diff --git a/.checkpatch.conf b/.checkpatch.conf index accee08b149e5..a6d9a31f11d09 100644 --- a/.checkpatch.conf +++ b/.checkpatch.conf @@ -5,7 +5,6 @@ --min-conf-desc-length=1 --typedefsfile=scripts/checkpatch/typedefsfile ---ignore BRACES --ignore PRINTK_WITHOUT_KERN_LEVEL --ignore SPLIT_STRING --ignore VOLATILE diff --git a/.clang-format b/.clang-format index 6cc25296b7d53..940f22994b8f7 100644 --- a/.clang-format +++ b/.clang-format @@ -111,3 +111,4 @@ WhitespaceSensitiveMacros: - LISTIFY - STRINGIFY - Z_STRINGIFY + - DT_FOREACH_PROP_ELEM_SEP diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 709a2b9cf9412..ba2dedb99e499 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -12,8 +12,7 @@ At this time, with the latest release of v4.0, the supported versions are: - v4.0: Current release - - v3.7: Current LTS - - v3.6: Prior release + - v3.7: Prior release and Current LTS - v2.7: Prior LTS ## Reporting process diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000000..a880296ea6d58 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: "ci: github: " + labels: [] + groups: + actions-deps: + patterns: + - "*" diff --git a/.github/workflows/assigner.yml b/.github/workflows/assigner.yml index 6e4e01c8ea1b6..be3696c4d3055 100644 --- a/.github/workflows/assigner.yml +++ b/.github/workflows/assigner.yml @@ -24,8 +24,7 @@ jobs: steps: - name: Install Python dependencies run: | - sudo pip3 install -U setuptools wheel pip - pip3 install -U PyGithub>=1.55 west + pip install -U PyGithub>=1.55 west - name: Check out source code uses: actions/checkout@v4 diff --git a/.github/workflows/backport_issue_check.yml b/.github/workflows/backport_issue_check.yml index ecaaf352827b4..2d2c4fda6a8b8 100644 --- a/.github/workflows/backport_issue_check.yml +++ b/.github/workflows/backport_issue_check.yml @@ -25,8 +25,7 @@ jobs: - name: Install Python dependencies run: | - sudo pip3 install -U setuptools wheel pip - pip3 install -U pygithub + pip install -U pygithub - name: Run backport issue checker env: diff --git a/.github/workflows/bsim-tests-publish.yaml b/.github/workflows/bsim-tests-publish.yaml index 72608b36b247e..5a4fbc0b39fff 100644 --- a/.github/workflows/bsim-tests-publish.yaml +++ b/.github/workflows/bsim-tests-publish.yaml @@ -13,7 +13,7 @@ jobs: steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@v8 with: run_id: ${{ github.event.workflow_run.id }} diff --git a/.github/workflows/bsim-tests.yaml b/.github/workflows/bsim-tests.yaml index 4739f99e68b19..66d47c68a1c24 100644 --- a/.github/workflows/bsim-tests.yaml +++ b/.github/workflows/bsim-tests.yaml @@ -12,12 +12,13 @@ on: - "dts/*/nordic/**" - "tests/bluetooth/common/testlib/**" - "samples/bluetooth/**" - - "boards/posix/**" - - "soc/posix/**" + - "boards/native/**" + - "soc/native/**" - "arch/posix/**" - "include/zephyr/arch/posix/**" - "scripts/native_simulator/**" - "samples/net/sockets/echo_*/**" + - "modules/hal_nordic/**" - "modules/mbedtls/**" - "modules/openthread/**" - "subsys/net/l2/openthread/**" @@ -77,6 +78,7 @@ jobs: git config --global user.email "bot@zephyrproject.org" git config --global user.name "Zephyr Bot" rm -fr ".git/rebase-apply" + rm -fr ".git/rebase-merge" git rebase origin/${BASE_REF} git clean -f -d git log --pretty=oneline | head -n 10 @@ -96,8 +98,8 @@ jobs: .github/workflows/bsim-tests.yaml .github/workflows/bsim-tests-publish.yaml west.yml - boards/posix/ - soc/posix/ + boards/native/ + soc/native/ arch/posix/ include/zephyr/arch/posix/ scripts/native_simulator/ @@ -105,6 +107,7 @@ jobs: boards/nordic/nrf5*/*dt* dts/*/nordic/ modules/mbedtls/** + modules/hal_nordic/** - name: Check if Bluethooth files changed uses: tj-actions/changed-files@v45 @@ -169,7 +172,7 @@ jobs: - name: Merge Test Results run: | - pip3 install junitparser junit2html + pip install junitparser junit2html junitparser merge --glob "./bsim_*/*bsim_results.*.xml" "./twister-out/twister.xml" junit.xml junit2html junit.xml junit.html diff --git a/.github/workflows/bug_snapshot.yaml b/.github/workflows/bug_snapshot.yaml index b4f9022bf2802..f10dc718b6eb2 100644 --- a/.github/workflows/bug_snapshot.yaml +++ b/.github/workflows/bug_snapshot.yaml @@ -25,8 +25,7 @@ jobs: - name: Install Python dependencies run: | - sudo pip3 install -U setuptools wheel pip - pip3 install -U pygithub + pip install -U pygithub - name: Snapshot bugs env: diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml deleted file mode 100644 index 0d97ecc8abcad..0000000000000 --- a/.github/workflows/clang.yaml +++ /dev/null @@ -1,165 +0,0 @@ -name: Build with Clang/LLVM - -on: pull_request_target - -concurrency: - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} - cancel-in-progress: true - -jobs: - clang-build: - if: github.repository_owner == 'zephyrproject-rtos' - runs-on: - group: zephyr-runner-v2-linux-x64-4xlarge - container: - image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.27.4.20241026 - options: '--entrypoint /bin/bash' - strategy: - fail-fast: false - matrix: - platform: ["native_sim"] - env: - CCACHE_DIR: /node-cache/ccache-zephyr - CCACHE_REMOTE_STORAGE: "redis://cache-*.keydb-cache.svc.cluster.local|shards=1,2,3" - CCACHE_REMOTE_ONLY: "true" - LLVM_TOOLCHAIN_PATH: /usr/lib/llvm-16 - COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} - BASE_REF: ${{ github.base_ref }} - outputs: - report_needed: ${{ steps.twister.outputs.report_needed }} - steps: - - name: Apply container owner mismatch workaround - run: | - # FIXME: The owner UID of the GITHUB_WORKSPACE directory may not - # match the container user UID because of the way GitHub - # Actions runner is implemented. Remove this workaround when - # GitHub comes up with a fundamental fix for this problem. - git config --global --add safe.directory ${GITHUB_WORKSPACE} - - - name: Print cloud service information - run: | - echo "ZEPHYR_RUNNER_CLOUD_PROVIDER = ${ZEPHYR_RUNNER_CLOUD_PROVIDER}" - echo "ZEPHYR_RUNNER_CLOUD_NODE = ${ZEPHYR_RUNNER_CLOUD_NODE}" - echo "ZEPHYR_RUNNER_CLOUD_POD = ${ZEPHYR_RUNNER_CLOUD_POD}" - - - name: Clone cached Zephyr repository - continue-on-error: true - run: | - git clone --shared /repo-cache/zephyrproject/zephyr . - git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - persist-credentials: false - - - name: Environment Setup - run: | - echo "$HOME/.local/bin" >> $GITHUB_PATH - git config --global user.email "bot@zephyrproject.org" - git config --global user.name "Zephyr Bot" - rm -fr ".git/rebase-apply" - git rebase origin/${BASE_REF} - git clean -f -d - git log --pretty=oneline | head -n 10 - west init -l . || true - west config --global update.narrow true - west config manifest.group-filter -- +ci,+optional - # In some cases modules are left in a state where they can't be - # updated (i.e. when we cancel a job and the builder is killed), - # So first retry to update, if that does not work, remove all modules - # and start over. (Workaround until we implement more robust module - # west caching). - west update --path-cache /repo-cache/zephyrproject 2>&1 1> west.log || west update --path-cache /repo-cache/zephyrproject 2>&1 1> west2.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /repo-cache/zephyrproject) - - echo "ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-$( cat SDK_VERSION )" >> $GITHUB_ENV - - - name: Check Environment - run: | - cmake --version - ${LLVM_TOOLCHAIN_PATH}/bin/clang --version - gcc --version - ls -la - - - name: Set up ccache - run: | - mkdir -p ${CCACHE_DIR} - ccache -M 10G - ccache -p - ccache -z -s -vv - - - name: Update BabbleSim to manifest revision - run: | - export BSIM_VERSION=$( west list bsim -f {revision} ) - echo "Manifest points to bsim sha $BSIM_VERSION" - cd /opt/bsim_west/bsim - git fetch -n origin ${BSIM_VERSION} - git -c advice.detachedHead=false checkout ${BSIM_VERSION} - west update - make everything -s -j 8 - - - name: Run Tests with Twister - id: twister - run: | - export ZEPHYR_BASE=${PWD} - export ZEPHYR_TOOLCHAIN_VARIANT=llvm - - # check if we need to run a full twister or not based on files changed - python3 ./scripts/ci/test_plan.py --no-detailed-test-id --platform ${{ matrix.platform }} -c origin/${BASE_REF}.. - - # We can limit scope to just what has changed - if [ -s testplan.json ]; then - echo "report_needed=1" >> $GITHUB_OUTPUT - # Full twister but with options based on changes - ./scripts/twister --no-detailed-test-id --force-color --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 - else - # if nothing is run, skip reporting step - echo "report_needed=0" >> $GITHUB_OUTPUT - fi - - - name: Print ccache stats - if: always() - run: | - ccache -s -vv - - - name: Upload Unit Test Results - if: always() && steps.twister.outputs.report_needed != 0 - uses: actions/upload-artifact@v4 - with: - name: Unit Test Results (Subset ${{ matrix.platform }}) - path: twister-out/twister.xml - - clang-build-results: - name: "Publish Unit Tests Results" - needs: clang-build - runs-on: ubuntu-22.04 - if: (success() || failure() ) && needs.clang-build.outputs.report_needed != 0 - steps: - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - name: Merge Test Results - run: | - pip3 install junitparser junit2html - junitparser merge artifacts/*/twister.xml junit.xml - junit2html junit.xml junit-clang.html - - - name: Upload Unit Test Results in HTML - if: always() - uses: actions/upload-artifact@v4 - with: - name: HTML Unit Test Results - if-no-files-found: ignore - path: | - junit-clang.html - - - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@v2 - if: always() - with: - check_name: Unit Test Results - files: "**/twister.xml" - comment_mode: off diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index f22fa7a75820b..5707610ae87b9 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -101,7 +101,7 @@ jobs: export ZEPHYR_BASE=${PWD} export ZEPHYR_TOOLCHAIN_VARIANT=zephyr mkdir -p coverage/reports - pip3 install gcovr==6.0 + pip install gcovr==6.0 ./scripts/twister -E ${{matrix.normalized}}-testplan.json ls -la ./scripts/twister \ @@ -182,7 +182,7 @@ jobs: - name: Merge coverage files run: | pushd ./coverage/reports - pip3 install gcovr==6.0 + pip install gcovr==6.0 gcovr ${{ steps.get-coverage-files.outputs.mergefiles }} --merge-mode-functions=separate --json merged.json gcovr ${{ steps.get-coverage-files.outputs.mergefiles }} --merge-mode-functions=separate --cobertura merged.xml popd @@ -220,7 +220,7 @@ jobs: - name: Upload coverage to Codecov if: always() - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: env_vars: OS,PYTHON fail_ci_if_error: false diff --git a/.github/workflows/coding_guidelines.yml b/.github/workflows/coding_guidelines.yml index 97d2301a9e3c9..81c20b372d9a7 100644 --- a/.github/workflows/coding_guidelines.yml +++ b/.github/workflows/coding_guidelines.yml @@ -21,16 +21,15 @@ jobs: - name: Install python dependencies run: | - pip3 install unidiff - pip3 install wheel - pip3 install sh + pip install unidiff + pip install sh - name: Install Packages run: | sudo apt-get update sudo apt-get install coccinelle - - name: Run Coding Guildeines Checks + - name: Run Coding Guidelines Checks continue-on-error: true id: coding_guidelines env: @@ -40,6 +39,8 @@ jobs: git config --global user.email "actions@zephyrproject.org" git config --global user.name "Github Actions" git remote -v + rm -fr ".git/rebase-apply" + rm -fr ".git/rebase-merge" git rebase origin/${BASE_REF} git clean -f -d source zephyr-env.sh diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index ecd874dd4869b..1875de7cb7e8e 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -33,6 +33,8 @@ jobs: # Ensure there's no merge commits in the PR [[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ (echo "::error ::Merge commits not allowed, rebase instead";false) + rm -fr ".git/rebase-apply" + rm -fr ".git/rebase-merge" git rebase origin/${BASE_REF} git clean -f -d # debug @@ -51,10 +53,8 @@ jobs: - name: Install python dependencies run: | - pip3 install setuptools - pip3 install wheel - pip3 install -r scripts/requirements-compliance.txt - pip3 install west + pip install -r scripts/requirements-compliance.txt + pip install west - name: west setup run: | @@ -82,7 +82,7 @@ jobs: git log --pretty=oneline | head -n 10 # Increase rename limit to allow for large PRs git config diff.renameLimit 10000 - ./scripts/ci/check_compliance.py --annotate -e KconfigBasic -e ClangFormat \ + ./scripts/ci/check_compliance.py --annotate -e KconfigBasic -e SysbuildKconfigBasic -e ClangFormat \ -c origin/${BASE_REF}.. - name: upload-results diff --git a/.github/workflows/daily_test_version.yml b/.github/workflows/daily_test_version.yml index 1886b4a8c805d..3a43ac643008d 100644 --- a/.github/workflows/daily_test_version.yml +++ b/.github/workflows/daily_test_version.yml @@ -25,7 +25,7 @@ jobs: - name: install-pip run: | - pip3 install gitpython + pip install gitpython - name: checkout uses: actions/checkout@v4 diff --git a/.github/workflows/devicetree_checks.yml b/.github/workflows/devicetree_checks.yml index 558e41c4bc1f1..345eb5b7db08e 100644 --- a/.github/workflows/devicetree_checks.yml +++ b/.github/workflows/devicetree_checks.yml @@ -62,8 +62,7 @@ jobs: ${{ runner.os }}-pip-${{ matrix.python-version }} - name: install python dependencies run: | - pip3 install wheel - pip3 install pytest pyyaml tox + pip install pytest pyyaml tox - name: run tox working-directory: scripts/dts/python-devicetree run: | diff --git a/.github/workflows/do_not_merge.yml b/.github/workflows/do_not_merge.yml index b6954e288c922..8d90efa981de0 100644 --- a/.github/workflows/do_not_merge.yml +++ b/.github/workflows/do_not_merge.yml @@ -6,14 +6,15 @@ on: jobs: do-not-merge: - if: ${{ contains(github.event.*.labels.*.name, 'DNM') || - contains(github.event.*.labels.*.name, 'TSC') || - contains(github.event.*.labels.*.name, 'Architecture Review') || - contains(github.event.*.labels.*.name, 'dev-review') }} name: Prevent Merging runs-on: ubuntu-22.04 steps: - name: Check for label + if: ${{ contains(github.event.*.labels.*.name, 'DNM') || + contains(github.event.*.labels.*.name, 'DNM (manifest)') || + contains(github.event.*.labels.*.name, 'TSC') || + contains(github.event.*.labels.*.name, 'Architecture Review') || + contains(github.event.*.labels.*.name, 'dev-review') }} run: | echo "Pull request is labeled as 'DNM', 'TSC', 'Architecture Review' or 'dev-review'." echo "This workflow fails so that the pull request cannot be merged." diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 7564d163f81d5..d263c1c80b6e2 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -94,6 +94,8 @@ jobs: run: | git config --global user.email "actions@zephyrproject.org" git config --global user.name "Github Actions" + rm -fr ".git/rebase-apply" + rm -fr ".git/rebase-merge" git rebase origin/${BASE_REF} git clean -f -d git log --graph --oneline HEAD...${PR_HEAD} @@ -106,11 +108,10 @@ jobs: - name: install-pip run: | - sudo pip3 install -U setuptools wheel pip - pip3 install -r doc/requirements.txt - pip3 install west==${WEST_VERSION} - pip3 install cmake==${CMAKE_VERSION} - pip3 install coverxygen + pip install -r doc/requirements.txt + pip install west==${WEST_VERSION} + pip install cmake==${CMAKE_VERSION} + pip install coverxygen - name: west setup run: | @@ -144,7 +145,7 @@ jobs: - name: compress-docs run: | - tar --use-compress-program="xz -T0" -cf html-output.tar.xz --directory=doc/_build html + tar --use-compress-program="xz -T0" -cf html-output.tar.xz --exclude html/_sources --exclude html/doxygen/xml --directory=doc/_build html tar --use-compress-program="xz -T0" -cf api-output.tar.xz --directory=doc/_build html/doxygen/html tar --use-compress-program="xz -T0" -cf api-coverage.tar.xz coverage-report @@ -221,10 +222,9 @@ jobs: - name: install-pip run: | - pip3 install -U setuptools wheel pip - pip3 install -r doc/requirements.txt - pip3 install west==${WEST_VERSION} - pip3 install cmake==${CMAKE_VERSION} + pip install -r doc/requirements.txt + pip install west==${WEST_VERSION} + pip install cmake==${CMAKE_VERSION} - name: west setup run: | diff --git a/.github/workflows/doc-publish-pr.yml b/.github/workflows/doc-publish-pr.yml index 786bd14aed277..d75bcad785616 100644 --- a/.github/workflows/doc-publish-pr.yml +++ b/.github/workflows/doc-publish-pr.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Download artifacts id: download-artifacts - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@v8 with: workflow: doc-build.yml run_id: ${{ github.event.workflow_run.id }} diff --git a/.github/workflows/doc-publish.yml b/.github/workflows/doc-publish.yml index 51c451c75ea3d..89349ed669730 100644 --- a/.github/workflows/doc-publish.yml +++ b/.github/workflows/doc-publish.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@v8 with: workflow: doc-build.yml run_id: ${{ github.event.workflow_run.id }} diff --git a/.github/workflows/footprint-tracking.yml b/.github/workflows/footprint-tracking.yml index 93eae63e954de..78f761cb545c4 100644 --- a/.github/workflows/footprint-tracking.yml +++ b/.github/workflows/footprint-tracking.yml @@ -58,7 +58,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y python3-venv - sudo pip3 install -U setuptools wheel pip gitpython + pip install -U gitpython - name: checkout uses: actions/checkout@v4 @@ -94,7 +94,7 @@ jobs: run: | python3 -m venv .venv . .venv/bin/activate - pip3 install awscli + pip install awscli aws s3 sync --quiet footprint_data/ s3://testing.zephyrproject.org/footprint_data/ - name: Transform Footprint data to Twister JSON reports @@ -113,7 +113,7 @@ jobs: ELASTICSEARCH_INDEX: ${{ vars.FOOTPRINT_TRACKING_INDEX }} run: | shopt -s globstar - pip3 install -U elasticsearch + pip install -U elasticsearch run_date=`date --iso-8601=minutes` python3 ./scripts/ci/upload_test_results_es.py -r ${run_date} \ --flatten footprint \ diff --git a/.github/workflows/hello_world_multiplatform.yaml b/.github/workflows/hello_world_multiplatform.yaml index 605cc2a903b69..f267688b1f0a5 100644 --- a/.github/workflows/hello_world_multiplatform.yaml +++ b/.github/workflows/hello_world_multiplatform.yaml @@ -12,8 +12,7 @@ on: - v*-branch - collab-* paths: - - 'scripts/build/**' - - 'scripts/requirements*.txt' + - 'scripts/**' - '.github/workflows/hello_world_multiplatform.yaml' - 'SDK_VERSION' @@ -45,6 +44,8 @@ jobs: run: | git config --global user.email "actions@zephyrproject.org" git config --global user.name "Github Actions" + rm -fr ".git/rebase-apply" + rm -fr ".git/rebase-merge" git rebase origin/${BASE_REF} git clean -f -d git log --graph --oneline HEAD...${PR_HEAD} @@ -69,7 +70,7 @@ jobs: elif [ "${{ runner.os }}" = "Windows" ]; then EXTRA_TWISTER_FLAGS="-P native_sim --short-build-path -O/tmp/twister-out" fi - ./scripts/twister --force-color --inline-logs -T samples/hello_world -T samples/cpp/hello_world -v $EXTRA_TWISTER_FLAGS + ./scripts/twister --runtime-artifact-cleanup --force-color --inline-logs -T samples/hello_world -T samples/cpp/hello_world -v $EXTRA_TWISTER_FLAGS - name: Upload artifacts if: failure() diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 538f06a1d5da6..8cfd17695afc5 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -20,13 +20,13 @@ jobs: BASE_REF: ${{ github.base_ref }} working-directory: zephyrproject/zephyr run: | - pip3 install west + pip install west git config --global user.email "you@example.com" git config --global user.name "Your Name" west init -l . || true - name: Manifest - uses: zephyrproject-rtos/action-manifest@v1.5.0 + uses: zephyrproject-rtos/action-manifest@v1.7.0 with: github-token: ${{ secrets.ZB_GITHUB_TOKEN }} manifest-path: 'west.yml' @@ -36,4 +36,4 @@ jobs: label-prefix: 'manifest-' verbosity-level: '1' labels: 'manifest' - dnm-labels: 'DNM' + dnm-labels: 'DNM (manifest)' diff --git a/.github/workflows/pylib_tests.yml b/.github/workflows/pylib_tests.yml index 2beb6c16956fe..bf9d828921224 100644 --- a/.github/workflows/pylib_tests.yml +++ b/.github/workflows/pylib_tests.yml @@ -44,7 +44,7 @@ jobs: ${{ runner.os }}-pip-${{ matrix.python-version }} - name: install-packages run: | - pip3 install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt + pip install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt - name: Run pytest for build_helpers env: ZEPHYR_BASE: ./ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 002485b9d8074..c7e71324c1d25 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: echo "TRIMMED_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT - name: REUSE Compliance Check - uses: fsfe/reuse-action@v4 + uses: fsfe/reuse-action@v5 with: args: spdx -o zephyr-${{ steps.get_version.outputs.VERSION }}.spdx diff --git a/.github/workflows/scripts_tests.yml b/.github/workflows/scripts_tests.yml index 183f3eb474be0..06e12ada528cb 100644 --- a/.github/workflows/scripts_tests.yml +++ b/.github/workflows/scripts_tests.yml @@ -42,6 +42,8 @@ jobs: run: | git config --global user.email "actions@zephyrproject.org" git config --global user.name "Github Actions" + rm -fr ".git/rebase-apply" + rm -fr ".git/rebase-merge" git rebase origin/${BASE_REF} git clean -f -d git log --graph --oneline HEAD...${PR_HEAD} @@ -62,7 +64,7 @@ jobs: - name: install-packages run: | - pip3 install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt + pip install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt - name: Run pytest env: diff --git a/.github/workflows/stats_merged_prs.yml b/.github/workflows/stats_merged_prs.yml index cd874b65b1ac8..0f86958e47b7b 100644 --- a/.github/workflows/stats_merged_prs.yml +++ b/.github/workflows/stats_merged_prs.yml @@ -20,5 +20,5 @@ jobs: ELASTICSEARCH_SERVER: "https://elasticsearch.zephyrproject.io:443" PR_STAT_ES_INDEX: ${{ vars.PR_STAT_ES_INDEX }} run: | - pip3 install pygithub elasticsearch + pip install pygithub elasticsearch python3 ./scripts/ci/stats/merged_prs.py --pull-request ${{ github.event.pull_request.number }} --repo ${{ github.repository }} diff --git a/.github/workflows/twister-prep.yaml b/.github/workflows/twister-prep.yaml index 4c8b03a5418b6..a179c5d38ba31 100644 --- a/.github/workflows/twister-prep.yaml +++ b/.github/workflows/twister-prep.yaml @@ -28,10 +28,10 @@ jobs: env: MATRIX_SIZE: 10 PUSH_MATRIX_SIZE: 20 - DAILY_MATRIX_SIZE: 80 + WEEKLY_MATRIX_SIZE: 200 BSIM_OUT_PATH: /opt/bsim/ BSIM_COMPONENTS_PATH: /opt/bsim/components - TESTS_PER_BUILDER: 700 + TESTS_PER_BUILDER: 900 COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} BASE_REF: ${{ github.base_ref }} steps: @@ -67,6 +67,7 @@ jobs: git config --global user.email "bot@zephyrproject.org" git config --global user.name "Zephyr Bot" rm -fr ".git/rebase-apply" + rm -fr ".git/rebase-merge" git rebase origin/${BASE_REF} git clean -f -d git log --pretty=oneline | head -n 10 @@ -115,10 +116,10 @@ jobs: env: MATRIX_SIZE: 10 PUSH_MATRIX_SIZE: 20 - DAILY_MATRIX_SIZE: 80 + WEEKLY_MATRIX_SIZE: 200 BSIM_OUT_PATH: /opt/bsim/ BSIM_COMPONENTS_PATH: /opt/bsim/components - TESTS_PER_BUILDER: 700 + TESTS_PER_BUILDER: 900 COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} BASE_REF: ${{ github.base_ref }} steps: @@ -135,8 +136,8 @@ jobs: subset="[$(seq -s',' 1 ${PUSH_MATRIX_SIZE})]" size=${MATRIX_SIZE} elif [ "${{github.event_name}}" = "schedule" -a "${{github.repository}}" = "zephyrproject-rtos/zephyr" ]; then - subset="[$(seq -s',' 1 ${DAILY_MATRIX_SIZE})]" - size=${DAILY_MATRIX_SIZE} + subset="[$(seq -s',' 1 ${WEEKLY_MATRIX_SIZE})]" + size=${WEEKLY_MATRIX_SIZE} else size=0 fi diff --git a/.github/workflows/twister-publish.yaml b/.github/workflows/twister-publish.yaml index f59a3edca3dbf..77078f8fdbcb3 100644 --- a/.github/workflows/twister-publish.yaml +++ b/.github/workflows/twister-publish.yaml @@ -27,7 +27,7 @@ jobs: - name: Download Artifacts id: download-artifacts - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@v8 with: path: artifacts workflow: twister.yml @@ -37,7 +37,7 @@ jobs: - name: Upload to elasticsearch if: steps.download-artifacts.outputs.found_artifact == 'true' run: | - pip3 install elasticsearch + pip install elasticsearch # set run date on upload to get consistent and unified data across the matrix. run_date=`date --iso-8601=minutes` if [ "${{github.event.workflow_run.event}}" = "push" ]; then diff --git a/.github/workflows/twister.yaml b/.github/workflows/twister.yaml index e660979b92d69..8a605cc6ce6ef 100644 --- a/.github/workflows/twister.yaml +++ b/.github/workflows/twister.yaml @@ -12,8 +12,8 @@ on: - v*-branch - collab-* schedule: - # Run at 03:00 UTC on every Sunday - - cron: '0 3 * * 0' + # Run at 17:00 UTC on every Saturday + - cron: '0 17 * * 6' concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} @@ -50,6 +50,7 @@ jobs: PUSH_OPTIONS: ' --clobber-output -M --show-footprint --report-filtered' COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} BASE_REF: ${{ github.base_ref }} + LLVM_TOOLCHAIN_PATH: /usr/lib/llvm-16 steps: - name: Print cloud service information run: | @@ -84,6 +85,7 @@ jobs: git config --global user.email "bot@zephyrproject.org" git config --global user.name "Zephyr Builder" rm -fr ".git/rebase-apply" + rm -fr ".git/rebase-merge" git rebase origin/${BASE_REF} git clean -f -d git log --pretty=oneline | head -n 10 @@ -137,8 +139,7 @@ jobs: if [ "${{matrix.subset}}" = "1" ]; then ./scripts/zephyr_module.py --twister-out module_tests.args if [ -s module_tests.args ]; then - # FIXME: workaround for modules with invalid test data - ./scripts/twister +module_tests.args --outdir module_tests ${TWISTER_COMMON} ${PUSH_OPTIONS} --integration + ./scripts/twister +module_tests.args --outdir module_tests ${TWISTER_COMMON} ${PUSH_OPTIONS} fi fi @@ -159,7 +160,7 @@ jobs: fi - if: github.event_name == 'schedule' - name: Run Tests with Twister (Daily) + name: Run Tests with Twister (Weekly) id: run_twister_sched run: | export ZEPHYR_BASE=${PWD} @@ -197,7 +198,7 @@ jobs: timestamp="$(date)" version="$(git describe --abbrev=12 --always)" echo -e "# Generated at $timestamp ($version)\n" > $FREEZE_FILE - pip3 freeze | tee -a $FREEZE_FILE + pip freeze | tee -a $FREEZE_FILE - if: matrix.subset == 1 && github.event_name == 'push' name: Upload the list of Python packages @@ -216,6 +217,14 @@ jobs: if: success() || failure() steps: + - name: Check out source code + if: needs.twister-build.result == 'failure' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + persist-credentials: false + - name: Download Artifacts uses: actions/download-artifact@v4 with: @@ -223,18 +232,19 @@ jobs: - name: Merge Test Results run: | - pip3 install junitparser junit2html + pip install junitparser junit2html junitparser merge artifacts/*/*/twister.xml junit.xml junit2html junit.xml junit.html - - name: Upload Unit Test Results in HTML + - name: Upload Unit Test Results if: always() uses: actions/upload-artifact@v4 with: - name: HTML Unit Test Results + name: Unit Test Results if-no-files-found: ignore path: | junit.html + junit.xml - name: Publish Unit Test Results uses: EnricoMi/publish-unit-test-result-action@v2 @@ -242,6 +252,25 @@ jobs: check_name: Unit Test Results files: "**/twister.xml" comment_mode: off + + - name: Analyze Twister Reports + if: needs.twister-build.result == 'failure' + run: | + ./scripts/ci/twister_report_analyzer.py artifacts/*/*/twister.json --long-summary --platforms --output-md errors.md + if [[ -s "errors.md" ]]; then + echo '### Error Summary! 🚀' >> $GITHUB_STEP_SUMMARY + cat errors.md >> $GITHUB_STEP_SUMMARY + fi + + - name: Upload Twister Analysis Results + if: needs.twister-build.result == 'failure' + uses: actions/upload-artifact@v4 + with: + name: Twister Analysis Results + if-no-files-found: ignore + path: | + twister_report_summary.json + twister-status-check: if: always() name: "Check Twister Status" diff --git a/.github/workflows/twister_tests.yml b/.github/workflows/twister_tests.yml index bcd2abac556eb..66409bce8763c 100644 --- a/.github/workflows/twister_tests.yml +++ b/.github/workflows/twister_tests.yml @@ -51,7 +51,7 @@ jobs: ${{ runner.os }}-pip-${{ matrix.python-version }} - name: install-packages run: | - pip3 install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt -r scripts/requirements-run-test.txt + pip install -r scripts/requirements-base.txt -r scripts/requirements-build-test.txt -r scripts/requirements-run-test.txt - name: Run pytest for twisterlib env: ZEPHYR_BASE: ./ diff --git a/.github/workflows/west_cmds.yml b/.github/workflows/west_cmds.yml index d7b671bc7e7f1..dc75c7578cc64 100644 --- a/.github/workflows/west_cmds.yml +++ b/.github/workflows/west_cmds.yml @@ -65,8 +65,7 @@ jobs: ${{ runner.os }}-pip-${{ matrix.python-version }} - name: install pytest run: | - pip3 install wheel - pip3 install pytest west pyelftools canopen natsort progress mypy intelhex psutil ply pyserial anytree + pip install pytest west pyelftools canopen natsort progress mypy intelhex psutil ply pyserial anytree junitparser - name: run pytest-win if: runner.os == 'Windows' run: | diff --git a/.gitignore b/.gitignore index b545443db310f..aab3981f52fcb 100644 --- a/.gitignore +++ b/.gitignore @@ -104,5 +104,8 @@ Nits.txt Pylint.txt Ruff.txt SphinxLint.txt +SysbuildKconfig.txt +SysbuildKconfigBasic.txt +SysbuildKconfigBasicNoModules.txt TextEncoding.txt YAMLLint.txt diff --git a/.mailmap b/.mailmap index 050d05cce9f0e..27cc2a560e3b1 100644 --- a/.mailmap +++ b/.mailmap @@ -1,14 +1,14 @@ Alexandr Kolosov Alexandre d'Alton -Amir Kaplan -Anas Nashif +Amir Kaplan +Anas Nashif Andrzej Kuroś Anthony Smigielski Armand Ciejak Aska Wu -Bit Pathe +Bit Pathe Bjarki Arge Andreasen -Carles Cufi +Carles Cufi chao an Charles E. Youse Chen Xingyu @@ -16,32 +16,32 @@ Christoph Schnetzler Christoph Schramm Christopher Friedt Christopher Friedt -Chuck Jordan +Chuck Jordan Chunlin Han David B. Kinder David Komel David Leach -Dirk Brandewie -Douglas Su +Dirk Brandewie +Douglas Su Enjia Mai -Enjia Mai -Evan Couzens +Enjia Mai +Evan Couzens Evgeniy Paltsev Evgeniy Paltsev -Felipe Neves +Felipe Neves Findlay Feng Flavio Arieta Netto Francois Ramu -Gerardo Aceves +Gerardo Aceves Gregory Shue Gregory Shue HaiLong Yang James Johnson Jarno Lämsä Jędrzej Ciupis -Jeremie Garcia +Jeremie Garcia Jim Benjamin Luther -Johan Kruger +Johan Kruger Johann Fischer Jørgen Kvalvaag Juan Manuel Cruz Alcaraz @@ -51,11 +51,11 @@ Jun Li Justin Watson Kamil Sroka Katarzyna Giądła -Keren Siman-Tov +Keren Siman-Tov Krzysztof Chruściński -Kuo-Lang Tseng -Lei Liu -Leona Cook +Kuo-Lang Tseng +Lei Liu +Leona Cook Leona Cook Lixin Guo Łukasz Mazur @@ -72,14 +72,14 @@ MartĂ­ BolĂ­var MartĂ­ BolĂ­var MartĂ­ BolĂ­var MartĂ­ BolĂ­var -Martin Jäger <17674105+martinjaeger@users.noreply.github.com> +Martin Jäger <17674105+martinjaeger@users.noreply.github.com> Mateusz Hołenko Michael Rosen Michal Narajowski -Mike Hirst +Mike Hirst Ming Shao Mohan Kumar Kumar -Naga Raja Rao Tulasi +Naga Raja Rao Tulasi Navin Sankar Velliangiri NingX Zhao Nishikant Nayak @@ -100,21 +100,23 @@ Radosław Koppel Raja D. Singh Ricardo Salveti Ricardo Salveti -Ruud Derwig +Ruud Derwig Saku Rautio Scott Worley Sean Nyekjaer Sean Nyekjaer Sharron Liu Shilpashree L C -Shuang He +Shuang He Sigvart Hovland StĂŠphane D'Alu Stine Åkredalen -Thomas Heeley +Thomas Heeley Tim Sørensen Tim Sørensen -Vinayak Kariappa Chettimada +Vinayak Kariappa Chettimada +Vinayak Kariappa Chettimada +Vinayak Kariappa Chettimada Xiaorui Hu Yannis Damigos Yonattan Louise diff --git a/.ruff-excludes.toml b/.ruff-excludes.toml index 06ac9c38e6316..269a0c9fcf171 100644 --- a/.ruff-excludes.toml +++ b/.ruff-excludes.toml @@ -439,9 +439,7 @@ "E701", # https://docs.astral.sh/ruff/rules/multiple-statements-on-one-line-colon "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports "SIM201", # https://docs.astral.sh/ruff/rules/negate-equal-op - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation "UP007", # https://docs.astral.sh/ruff/rules/non-pep604-annotation - "UP032", # https://docs.astral.sh/ruff/rules/f-string "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import "UP037", # https://docs.astral.sh/ruff/rules/quoted-annotation ] @@ -452,10 +450,8 @@ "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports "SIM102", # https://docs.astral.sh/ruff/rules/collapsible-if "SIM118", # https://docs.astral.sh/ruff/rules/in-dict-keys - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation "UP007", # https://docs.astral.sh/ruff/rules/non-pep604-annotation "UP015", # https://docs.astral.sh/ruff/rules/redundant-open-modes - "UP032", # https://docs.astral.sh/ruff/rules/f-string "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import "UP037", # https://docs.astral.sh/ruff/rules/quoted-annotation ] diff --git a/CMakeLists.txt b/CMakeLists.txt index 65cf26ff75e63..cd141c12dea6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -174,7 +174,17 @@ endif() # @Intent: Set compiler flags to detect general stack overflows across all functions if(CONFIG_STACK_CANARIES) - zephyr_compile_options($) + zephyr_compile_options("$<$:$>") + zephyr_compile_options("$<$:$>") +elseif(CONFIG_STACK_CANARIES_STRONG) + zephyr_compile_options("$<$:$>") + zephyr_compile_options("$<$:$>") +elseif(CONFIG_STACK_CANARIES_ALL) + zephyr_compile_options("$<$:$>") + zephyr_compile_options("$<$:$>") +elseif(CONFIG_STACK_CANARIES_EXPLICIT) + zephyr_compile_options("$<$:$>") + zephyr_compile_options("$<$:$>") endif() # @Intent: Obtain compiler optimizations flags and store in variables @@ -221,7 +231,8 @@ SOC_* symbol.") endif() # Apply the final optimization flag(s) -zephyr_compile_options(${OPTIMIZATION_FLAG}) +zephyr_compile_options($<$:${OPTIMIZATION_FLAG}>) +zephyr_compile_options($<$:${OPTIMIZATION_FLAG}>) if(CONFIG_LTO) zephyr_compile_options($) @@ -309,7 +320,9 @@ if(CONFIG_CODING_GUIDELINE_CHECK) endif() # @Intent: Set compiler specific macro inclusion of AUTOCONF_H -zephyr_compile_options("SHELL: $ ${AUTOCONF_H}") +zephyr_compile_options("SHELL: $<$:$ ${AUTOCONF_H}>") +zephyr_compile_options("SHELL: $<$:$ ${AUTOCONF_H}>") +zephyr_compile_options("SHELL: $<$:$ ${AUTOCONF_H}>") if(CONFIG_COMPILER_FREESTANDING) # @Intent: Set compiler specific flag for bare metal freestanding option @@ -354,7 +367,9 @@ zephyr_compile_options($<$:$ # @Intent: Enforce standard integer type correspondence to match Zephyr usage. # (must be after compiler specific flags) if(CONFIG_ENFORCE_ZEPHYR_STDINT) - zephyr_compile_options("SHELL: $ ${ZEPHYR_BASE}/include/zephyr/toolchain/zephyr_stdint.h") + zephyr_compile_options("SHELL:$<$:$ ${ZEPHYR_BASE}/include/zephyr/toolchain/zephyr_stdint.h>") + zephyr_compile_options("SHELL:$<$:$ ${ZEPHYR_BASE}/include/zephyr/toolchain/zephyr_stdint.h>") + zephyr_compile_options("SHELL:$<$:$ ${ZEPHYR_BASE}/include/zephyr/toolchain/zephyr_stdint.h>") endif() # Common toolchain-agnostic assembly flags @@ -842,7 +857,12 @@ if(CONFIG_LEGACY_GENERATED_INCLUDE_PATH) ${CMAKE_CURRENT_BINARY_DIR}/include/generated/syscall_list.h) endif() -add_custom_command(OUTPUT include/generated/zephyr/syscall_dispatch.c ${syscall_list_h} +add_custom_command( + OUTPUT + include/generated/zephyr/syscall_dispatch.c + include/generated/zephyr/syscall_exports_llext.c + syscall_weakdefs_llext.c + ${syscall_list_h} # Also, some files are written to include/generated/zephyr/syscalls/ COMMAND ${PYTHON_EXECUTABLE} @@ -850,7 +870,8 @@ add_custom_command(OUTPUT include/generated/zephyr/syscall_dispatch.c ${syscall_ --json-file ${syscalls_json} # Read this file --base-output include/generated/zephyr/syscalls # Write to this dir --syscall-dispatch include/generated/zephyr/syscall_dispatch.c # Write this file - --syscall-export-llext include/generated/zephyr/syscall_export_llext.c + --syscall-exports-llext include/generated/zephyr/syscall_exports_llext.c + --syscall-weakdefs-llext syscall_weakdefs_llext.c # compiled in CMake library 'syscall_weakdefs' --syscall-list ${syscall_list_h} $<$:--gen-mrsh-files> ${SYSCALL_LONG_REGISTERS_ARG} @@ -1009,6 +1030,16 @@ else() set(NO_WHOLE_ARCHIVE_LIBS kernel) endif() +if(CONFIG_LLEXT) + # LLEXT exports symbols for all syscalls, including unimplemented ones. + # Weak definitions for these must be added at the end of the link order + # to avoid shadowing actual implementations. + add_library(syscall_weakdefs syscall_weakdefs_llext.c) + add_dependencies(syscall_weakdefs zephyr_generated_headers) + target_link_libraries(syscall_weakdefs zephyr_interface) + list(APPEND NO_WHOLE_ARCHIVE_LIBS syscall_weakdefs) +endif() + get_property(OUTPUT_FORMAT GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT) if (CONFIG_CODE_DATA_RELOCATION) @@ -1087,10 +1118,10 @@ set_ifndef( TOPT "${COMPILER_TOPT}") set_ifndef( TOPT -Wl,-T) # Use this if the compiler driver doesn't set a value if(CONFIG_HAVE_CUSTOM_LINKER_SCRIPT) - set(LINKER_SCRIPT ${APPLICATION_SOURCE_DIR}/${CONFIG_CUSTOM_LINKER_SCRIPT}) + string(CONFIGURE ${APPLICATION_SOURCE_DIR}/${CONFIG_CUSTOM_LINKER_SCRIPT} LINKER_SCRIPT) if(NOT EXISTS ${LINKER_SCRIPT}) - set(LINKER_SCRIPT ${CONFIG_CUSTOM_LINKER_SCRIPT}) - assert_exists(CONFIG_CUSTOM_LINKER_SCRIPT) + string(CONFIGURE ${CONFIG_CUSTOM_LINKER_SCRIPT} LINKER_SCRIPT) + assert_exists(LINKER_SCRIPT) endif() elseif(DEFINED BOARD_LINKER_SCRIPT) set(LINKER_SCRIPT ${BOARD_LINKER_SCRIPT}) @@ -1968,7 +1999,6 @@ if (CONFIG_LLEXT AND CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) --elf-file ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} --slid-listing ${PROJECT_BINARY_DIR}/slid_listing.txt ) - endif() if(NOT CMAKE_C_COMPILER_ID STREQUAL "ARMClang") @@ -2199,51 +2229,57 @@ if((CMAKE_BUILD_TYPE IN_LIST build_types) AND (NOT NO_BUILD_TYPE_WARNING)) endif() # Extension Development Kit (EDK) generation. -set(llext_edk_file ${PROJECT_BINARY_DIR}/${CONFIG_LLEXT_EDK_NAME}.tar.xz) +if(CONFIG_LLEXT_EDK) + if(CONFIG_LLEXT_EDK_FORMAT_TAR_XZ) + set(llext_edk_extension "tar.xz") + elseif(CONFIG_LLEXT_EDK_FORMAT_TAR_ZSTD) + set(llext_edk_extension "tar.Z") + elseif(CONFIG_LLEXT_EDK_FORMAT_ZIP) + set(llext_edk_extension "zip") + else() + message(FATAL_ERROR "Unsupported LLEXT_EDK_FORMAT choice") + endif() + set(llext_edk_file ${PROJECT_BINARY_DIR}/${CONFIG_LLEXT_EDK_NAME}.${llext_edk_extension}) -# TODO maybe generate flags for C CXX ASM -zephyr_get_compile_definitions_for_lang(C zephyr_defs) -zephyr_get_compile_options_for_lang(C zephyr_flags) + # TODO maybe generate flags for C CXX ASM + zephyr_get_compile_definitions_for_lang(C zephyr_defs) + zephyr_get_compile_options_for_lang(C zephyr_flags) -# Filter out non LLEXT and LLEXT_EDK flags - and add required ones -llext_filter_zephyr_flags(LLEXT_REMOVE_FLAGS ${zephyr_flags} llext_filt_flags) -llext_filter_zephyr_flags(LLEXT_EDK_REMOVE_FLAGS ${llext_filt_flags} llext_filt_flags) + # Filter out non LLEXT and LLEXT_EDK flags - and add required ones + llext_filter_zephyr_flags(LLEXT_REMOVE_FLAGS ${zephyr_flags} llext_filt_flags) + llext_filter_zephyr_flags(LLEXT_EDK_REMOVE_FLAGS ${llext_filt_flags} llext_filt_flags) -set(llext_edk_cflags ${zephyr_defs} -DLL_EXTENSION_BUILD) -list(APPEND llext_edk_cflags ${llext_filt_flags}) -list(APPEND llext_edk_cflags ${LLEXT_APPEND_FLAGS}) -list(APPEND llext_edk_cflags ${LLEXT_EDK_APPEND_FLAGS}) + set(llext_edk_cflags ${zephyr_defs} -DLL_EXTENSION_BUILD) + list(APPEND llext_edk_cflags ${llext_filt_flags}) + list(APPEND llext_edk_cflags ${LLEXT_APPEND_FLAGS}) + list(APPEND llext_edk_cflags ${LLEXT_EDK_APPEND_FLAGS}) -add_custom_command( + build_info(llext-edk file PATH ${llext_edk_file}) + build_info(llext-edk cflags VALUE ${llext_edk_cflags}) + build_info(llext-edk include-dirs VALUE "$") + + add_custom_command( OUTPUT ${llext_edk_file} # Regenerate syscalls in case CONFIG_LLEXT_EDK_USERSPACE_ONLY COMMAND ${CMAKE_COMMAND} - -E make_directory edk/include/generated/zephyr + -E make_directory edk/include/generated/zephyr COMMAND - ${PYTHON_EXECUTABLE} - ${ZEPHYR_BASE}/scripts/build/gen_syscalls.py - --json-file ${syscalls_json} # Read this file - --base-output edk/include/generated/zephyr/syscalls # Write to this dir - --syscall-dispatch edk/include/generated/zephyr/syscall_dispatch.c # Write this file - --syscall-list ${edk_syscall_list_h} - $<$:--userspace-only> - ${SYSCALL_LONG_REGISTERS_ARG} - ${SYSCALL_SPLIT_TIMEOUT_ARG} + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/build/gen_syscalls.py + --json-file ${syscalls_json} # Read this file + --base-output edk/include/generated/zephyr/syscalls # Write to this dir + --syscall-dispatch edk/include/generated/zephyr/syscall_dispatch.c # Write this file + --syscall-list ${edk_syscall_list_h} + $<$:--userspace-only> + ${SYSCALL_LONG_REGISTERS_ARG} + ${SYSCALL_SPLIT_TIMEOUT_ARG} COMMAND ${CMAKE_COMMAND} - -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} - -DAPPLICATION_SOURCE_DIR=${APPLICATION_SOURCE_DIR} - -DINTERFACE_INCLUDE_DIRECTORIES="$" - -Dllext_edk_file=${llext_edk_file} - -Dllext_edk_cflags="${llext_edk_cflags}" - -Dllext_edk_name=${CONFIG_LLEXT_EDK_NAME} - -DWEST_TOPDIR=${WEST_TOPDIR} - -DZEPHYR_BASE=${ZEPHYR_BASE} - -DCONFIG_LLEXT_EDK_USERSPACE_ONLY=${CONFIG_LLEXT_EDK_USERSPACE_ONLY} -P ${ZEPHYR_BASE}/cmake/llext-edk.cmake - DEPENDS ${logical_target_for_zephyr_elf} + DEPENDS ${logical_target_for_zephyr_elf} build_info_yaml_saved COMMAND_EXPAND_LISTS -) -add_custom_target(llext-edk DEPENDS ${llext_edk_file}) + ) + add_custom_target(llext-edk DEPENDS ${llext_edk_file}) +endif() # @Intent: Set compiler specific flags for standard C/C++ includes # Done at the very end, so any other system includes which may @@ -2264,9 +2300,8 @@ add_subdirectory_ifdef( toolchain_linker_finalize() -yaml_context(EXISTS NAME build_info result) -if(result) - build_info(zephyr version VALUE ${PROJECT_VERSION_STR}) - build_info(zephyr zephyr-base VALUE ${ZEPHYR_BASE}) - yaml_save(NAME build_info) -endif() +# export build information +build_info(zephyr version VALUE ${PROJECT_VERSION_STR}) +build_info(zephyr zephyr-base VALUE ${ZEPHYR_BASE}) + +yaml_save(NAME build_info) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index bf202081e7065..2d8031260ced6 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -793,7 +793,8 @@ config BUILD_OUTPUT_UF2_FAMILY_ID default "0xada52840" if SOC_NRF52840_QIAA default "0x4fb2d5bd" if SOC_SERIES_IMXRT10XX || SOC_SERIES_IMXRT11XX default "0x2abc77ec" if SOC_SERIES_LPC55XXX - default "0xe48bff56" if SOC_SERIES_RP2XXX + default "0xe48bff56" if SOC_SERIES_RP2040 + default "0xe48bff57" if SOC_SERIES_RP2350 default "0x68ed2b88" if SOC_SERIES_SAMD21 default "0x55114460" if SOC_SERIES_SAMD51 default "0x647824b6" if SOC_SERIES_STM32F0X diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 5badb24d1eefa..97684e4a80b04 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -126,6 +126,20 @@ ACPI: tests: - acpi +Antmicro platforms: + status: maintained + maintainers: + - fkokosinski + - tgorochowik + collaborators: + - kgugala + files: + - boards/antmicro/ + - soc/antmicro/ + - dts/arm/antmicro/ + labels: + - "platform: Antmicro" + ARC arch: status: maintained maintainers: @@ -148,10 +162,19 @@ ARC arch: tests: - arch.arc +Arduino Platforms: + status: maintained + maintainers: + - pillo79 + collaborators: + - facchinm + files: + - boards/arduino/ + ARM arch: status: maintained maintainers: - - ithinuel + - wearyzen collaborators: - microbuilder - carlocaione @@ -159,6 +182,7 @@ ARM arch: - MaureenHelm - stephanosio - bbolen + - ithinuel files: - arch/arm/ - arch/arm/core/offsets/ @@ -179,6 +203,9 @@ ARM64 arch: - npitre - povergoing - sgrrzhf + - wearyzen + - ithinuel + - JiafeiPan files: - arch/arm64/ - include/zephyr/arch/arm64/ @@ -194,6 +221,8 @@ ARM64 arch: ARM Platforms: status: maintained maintainers: + - wearyzen + collaborators: - ithinuel files: - boards/arm/mps*/ @@ -313,6 +342,7 @@ Bluetooth HCI: - sjanc - theob-pro - HoZHel + - cvinayak files: - include/zephyr/drivers/bluetooth/ - include/zephyr/drivers/bluetooth.h @@ -326,14 +356,13 @@ Bluetooth HCI: tests: - bluetooth -Bluetooth controller: +Bluetooth Controller: status: maintained maintainers: - cvinayak collaborators: - carlescufi - thoh-ot - - kruithofa - ppryga - mtpr-ot - wopu-ot @@ -365,6 +394,7 @@ Bluetooth Host: - sjanc - Thalley - theob-pro + - cvinayak files: - doc/connectivity/bluetooth/ - include/zephyr/bluetooth/ @@ -397,13 +427,13 @@ Bluetooth Host: - doc/connectivity/bluetooth/shell/audio/ - samples/bluetooth/bap*/ - samples/bluetooth/cap*/ + - samples/bluetooth/ccp*/ - samples/bluetooth/hap*/ - samples/bluetooth/hci_*/ - samples/bluetooth/pbp*/ - samples/bluetooth/tmap*/ - samples/bluetooth/iso_*/ - samples/bluetooth/mesh*/ - - subsys/bluetooth/Kconfig.iso - subsys/bluetooth/host/iso.c - subsys/bluetooth/host/iso_internal.h - subsys/bluetooth/host/shell/iso.c @@ -462,7 +492,6 @@ Bluetooth Audio: - sjanc - asbjornsabo - fredrikdanebjer - - kruithofa - larsgk - pin-zephyr - niym-ot @@ -481,6 +510,7 @@ Bluetooth Audio: - doc/connectivity/bluetooth/shell/audio/ - samples/bluetooth/bap*/ - samples/bluetooth/cap*/ + - samples/bluetooth/ccp*/ - samples/bluetooth/hap*/ - samples/bluetooth/pbp*/ - samples/bluetooth/tmap*/ @@ -496,6 +526,9 @@ Bluetooth Classic: - lylezhu2012 collaborators: - jhedberg + - MarkWangChinese + - gzh-terry + - makeshi files: - doc/connectivity/bluetooth/shell/classic/a2dp.rst - subsys/bluetooth/common/ @@ -513,13 +546,12 @@ Bluetooth ISO: - Thalley collaborators: - jhedberg - - kruithofa - rugeGerritsen + - cvinayak files: - include/zephyr/bluetooth/iso.h - doc/connectivity/bluetooth/shell/host/iso.rst - samples/bluetooth/iso_*/ - - subsys/bluetooth/Kconfig.iso - subsys/bluetooth/host/iso.c - subsys/bluetooth/host/iso_internal.h - subsys/bluetooth/host/shell/iso.c @@ -884,14 +916,16 @@ DFU: - dfu Devicetree: - status: odd fixes + status: maintained + maintainers: + - mbolivar collaborators: - decsny - galak - rruuaanng files-regex: - - dts/bindings/.*zephyr.* - - dts/bindings/[^,]+$ + - ^dts/bindings/.*zephyr.* + - ^dts/bindings/[^,]+$ files: - scripts/dts/ - dts/common/ @@ -1227,6 +1261,8 @@ Release Notes: status: maintained maintainers: - ceolin + collaborators: + - valeriosetti files: - drivers/crypto/ - dts/bindings/crypto/ @@ -1386,6 +1422,7 @@ Release Notes: - decsny - lmajewski - pdgendt + - maass-hamburg files: - drivers/ethernet/ - include/zephyr/dt-bindings/ethernet/ @@ -1487,6 +1524,7 @@ Release Notes: files: - doc/hardware/peripherals/gnss.rst - drivers/gnss/ + - include/zephyr/data/navigation.h - include/zephyr/drivers/gnss.h - include/zephyr/drivers/gnss/ - dts/bindings/gnss/ @@ -1613,6 +1651,9 @@ Release Notes: status: maintained maintainers: - carlocaione + collaborators: + - wearyzen + - ithinuel files: - include/zephyr/drivers/mbox.h - drivers/mbox/ @@ -1642,6 +1683,7 @@ Release Notes: status: odd fixes collaborators: - decsny + - maass-hamburg files: - doc/hardware/peripherals/mdio.rst - drivers/mdio/ @@ -1757,8 +1799,6 @@ Release Notes: maintainers: - Mani-Sadhasivam - simonguinot - collaborators: - - bbilas files: - drivers/led/ - include/zephyr/drivers/led/ @@ -1779,7 +1819,6 @@ Release Notes: maintainers: - simonguinot collaborators: - - mbolivar-ampere - soburi - thedjnK files: @@ -2029,6 +2068,7 @@ Release Notes: - tristan-google - ubieda - jeppenodgaard + - asemjonovs files: - drivers/sensor/ - include/zephyr/drivers/sensor.h @@ -2093,6 +2133,7 @@ Release Notes: - include/zephyr/drivers/stepper.h - dts/bindings/stepper/ - doc/hardware/peripherals/stepper.rst + - samples/drivers/stepper/ - tests/drivers/build_all/stepper/ labels: - "area: Stepper" @@ -2416,7 +2457,8 @@ JSON Web Token: - sir-branch files: - subsys/jwt/ - - include/zephyr/data/ + - include/zephyr/data/json.h + - include/zephyr/data/jwt.h - lib/utils/json.c - tests/subsys/jwt/ - tests/lib/json/ @@ -2817,14 +2859,17 @@ Networking: - doc/connectivity/networking/api/ieee802154.rst - doc/connectivity/networking/api/ptp.rst - doc/connectivity/networking/api/wifi.rst + - doc/connectivity/networking/api/http*.rst - include/zephyr/net/gptp.h - include/zephyr/net/ieee802154*.h - include/zephyr/net/ptp.h - include/zephyr/net/wifi*.h - include/zephyr/net/buf.h - include/zephyr/net/dhcpv4*.h + - include/zephyr/net/http/ - samples/net/gptp/ - samples/net/sockets/coap_*/ + - samples/net/sockets/*http*/ - samples/net/lwm2m_client/ - samples/net/wifi/ - samples/net/dhcpv4_client/ @@ -2833,12 +2878,14 @@ Networking: - subsys/net/l2/wifi/ - subsys/net/lib/coap/ - subsys/net/lib/config/ieee802154* + - subsys/net/lib/http/ - subsys/net/lib/lwm2m/ - subsys/net/lib/ptp/ - subsys/net/lib/tls_credentials/ - subsys/net/lib/dhcpv4/ - tests/net/dhcpv4/ - tests/net/ieee802154/ + - tests/net/lib/http*/ - tests/net/wifi/ labels: - "area: Networking" @@ -3027,7 +3074,7 @@ Networking: collaborators: - pdgendt - canisLupus1313 - - mariuszpos + - kkasperczyk-no - edmont - maciejbaczmanski files: @@ -3060,6 +3107,25 @@ Networking: tests: - net.wifi +"Networking: HTTP": + status: maintained + maintainers: + - jukkar + - rlubos + collaborators: + - mrodgers-witekio + files: + - doc/connectivity/networking/api/http*.rst + - include/zephyr/net/http/ + - subsys/net/lib/http/ + - samples/net/sockets/*http*/ + - tests/net/lib/http*/ + labels: + - "area: Networking" + - "area: HTTP" + tests: + - net.http + NIOS-2 arch: status: maintained maintainers: @@ -3101,6 +3167,9 @@ Open AMP: status: maintained maintainers: - carlocaione + collaborators: + - uLipe + - iuliana-prodan files: - lib/open-amp/ - samples/subsys/ipc/openamp/ @@ -3296,7 +3365,7 @@ Settings: - subsys/settings/ - tests/subsys/settings/ - samples/subsys/settings/ - - doc/services/settings/ + - doc/services/storage/settings/ labels: - "area: Settings" tests: @@ -3384,6 +3453,7 @@ ADI Platforms: collaborators: - ozersa - ttmut + - yasinustunerg - galak - microbuilder files: @@ -3513,6 +3583,8 @@ Raspberry Pi Pico Platforms: - soburi collaborators: - yonsch + - threeeights + - ajf58 files: - boards/raspberrypi/ - boards/adafruit/kb2040/ @@ -3530,9 +3602,10 @@ Silabs Platforms: status: maintained maintainers: - jhedberg + - asmellby collaborators: - jerome-pouiller - - asmellby + - Martinhoff-maker files: - soc/silabs/ - boards/silabs/ @@ -3667,11 +3740,10 @@ NXP Drivers: - dleach02 - mmahadevan108 collaborators: - - danieldegrasse - decsny - manuargue - dbaluta - - MarkWangChinese + - Raymond0225 files-regex: - ^drivers/.*nxp.* - ^drivers/.*mcux.* @@ -3689,24 +3761,53 @@ NXP Drivers: - include/zephyr/dt-bindings/inputmux/ - include/zephyr/dt-bindings/rdc/ - include/zephyr/drivers/*/*nxp* + - include/zephyr/drivers/*/*nxp*/ - include/zephyr/drivers/*/*mcux* - arch/arm/core/mpu/nxp_mpu.c - dts/bindings/*/nxp* + files-exclude: + - drivers/wifi/ + - drivers/bluetooth/ + - drivers/usb/ files-regex-exclude: - .*s32.* labels: - "platform: NXP Drivers" description: NXP Drivers +NXP Wireless: + status: maintained + maintainers: + - dleach02 + collaborators: + - MaochenWang1 + - axelnxp + files: + - drivers/wifi/nxp/ + - drivers/bluetooth/hci/*nxp* + - drivers/ieee802154/ieee802154_kw41z.c + labels: + - "platform: NXP Drivers" + +NXP MCUX USB: + status: maintained + maintainers: + - mmahadevan108 + - MarkWangChinese + files: + - drivers/usb/*/*mcux* + - boards/nxp/usb_kw24d512/ + labels: + - "platform: NXP Drivers" + description: NXP MCUX USB shim drivers + NXP Platforms (MCU): status: maintained maintainers: - dleach02 - mmahadevan108 collaborators: - - danieldegrasse - DerekSnell - - yvanderv - EmilioCBen - decsny - butok @@ -3715,8 +3816,11 @@ NXP Platforms (MCU): - boards/nxp/frdm*/ - boards/nxp/lpcxpress*/ - boards/nxp/twr_*/ - - boards/nxp/vmu*/ - boards/nxp/*rw*/ + - boards/nxp/hexiwear/ + - boards/nxp/common/ + - boards/nxp/* + - soc/nxp/common/ - soc/nxp/imxrt/ - soc/nxp/kinetis/ - soc/nxp/lpc/ @@ -3737,13 +3841,9 @@ NXP Platforms (S32): maintainers: - manuargue collaborators: - - PetervdPerk-NXP - - bperseghetti - Dat-NguyenDuy files: - - boards/nxp/s32*/ - - boards/nxp/mr_canhubk3/ - - boards/nxp/ucans32k1sic/ + - boards/nxp/*s32*/ - boards/common/*nxp_s32* - soc/nxp/s32/ - drivers/*/*nxp_s32* @@ -3766,13 +3866,12 @@ NXP Platforms (MPU): - dleach02 - dbaluta - iuliana-prodan - - danieldegrasse - - yvanderv files: - dts/arm64/nxp/ - dts/arm/nxp/nxp_imx* - soc/nxp/imx/ - soc/nxp/layerscape/ + - boards/nxp/ls1046ardb/ files-regex: - boards/nxp/m?imx[^(rt)].*/ labels: @@ -3792,6 +3891,19 @@ NXP Platforms (Xtensa): - "platform: NXP Xtensa" description: NXP Xtensa platforms +NXP Platforms (Robotics Products): + status: maintained + maintainers: + - bperseghetti + - PetervdPerk-NXP + files: + - boards/nxp/vmu*/ + - boards/nxp/rddrone_fmuk66/ + - boards/nxp/mr_canhubk3/ + labels: + - "platform: NXP" + description: NXP Robotics Module Platform Products + Microchip MEC Platforms: status: maintained maintainers: @@ -3806,7 +3918,8 @@ Microchip MEC Platforms: - drivers/*/*mchp*.c - tests/boards/mec15xxevb_assy6853/ - tests/boards/mec172xevb_assy6906/ - - dts/bindings/*/microchip,* + - dts/bindings/*/microchip,mec* + - dts/bindings/*/microchip,xec* labels: - "platform: Microchip MEC" @@ -3880,6 +3993,19 @@ OpenTitan Platforms: description: >- OpenTitan boards, SOCs, dts files and related drivers. +Realtek EC Platforms: + status: maintained + maintainers: + - JasonLin-RealTek + files: + - boards/realtek/ + - drivers/*/*rts5912* + - dts/bindings/*/*rts5912* + - dts/arm/realtek/ec/ + - soc/realtek/ec/ + labels: + - "platform: Realtek EC" + Renesas SmartBond Platforms: status: maintained maintainers: @@ -3927,13 +4053,19 @@ Renesas RZ Platforms: status: maintained maintainers: - tgorochowik + collaborators: + - binhnguyen2434 + - nhutnguyenkc files: - - boards/renesas/rzt2m_*/ + - boards/renesas/rz*/ - drivers/*/*rzt2m* + - drivers/*/*renesas_rz* - drivers/pinctrl/renesas/rz/ - dts/arm/renesas/rz/ - dts/bindings/*/*rzt2m* + - dts/bindings/*/*renesas,rz* - soc/renesas/rzt2m/ + - soc/renesas/rz/ labels: - "platforms: Renesas RZ" description: >- @@ -3973,6 +4105,7 @@ STM32 Platforms: - GeorgeCGV - marwaiehm-st - mathieuchopstm + - djiatsaf-st files: - boards/st/ - drivers/*/*stm32*.c @@ -3983,11 +4116,48 @@ STM32 Platforms: - dts/bindings/*/*stm32* - soc/st/stm32/ - samples/boards/st/ + files-exclude: + - boards/st/*wb*/ + - drivers/bluetooth/hci/*stm32*.c + - soc/st/stm32/stm32wb*/ labels: - "platform: STM32" description: >- - STM32 SOCs, dts files and related drivers. ST nucleo, disco and eval - boards. + STM32 SOCs, dts files and related drivers. ST development boards. + +STM32 Wireless Platforms: + status: maintained + maintainers: + - erwango + collaborators: + - asm5878 + - HoZHel + - benothmn-st + - mathieuchopstm + files: + - boards/shields/x_nucleo_bnrg2a1/ + - boards/shields/x_nucleo_idb05a1/ + - boards/shields/x_nucleo_wb05kn1/ + - boards/st/*wb*/ + - drivers/bluetooth/hci/*stm32*.c + - drivers/bluetooth/hci/hci_spi_st.c + - soc/st/stm32/stm32wb*/ + labels: + - "platform: STM32" + description: >- + STM32WB SOCs, dts files and related drivers. STM32WB development boards + and ST bluetooth shields. + +Enclustra Platforms: + status: maintained + maintainers: + - fkokosinski + collaborators: + - tgorochowik + files: + - boards/enclustra/ + labels: + - "platform: Enclustra" Espressif Platforms: status: maintained @@ -4064,6 +4234,8 @@ TI K3 Platforms: - dnltz files: - boards/ti/*am62*/ + - drivers/*/*davinci* + - drivers/*/*omap* - drivers/*/*ti_k3* - dts/bindings/*/ti,k3* - soc/ti/k3/ @@ -4173,14 +4345,26 @@ Secure storage: - tomi-font files: - subsys/secure_storage/ + - include/zephyr/psa/ - samples/psa/ - - doc/services/secure_storage.rst + - doc/services/storage/secure_storage/index.rst - tests/subsys/secure_storage/ labels: - "area: Secure storage" tests: - psa.secure_storage +Sensry Platforms: + status: maintained + maintainers: + - tswaehn + files: + - boards/sensry/ + files-regex: + - .*sy1xx.* + labels: + - "platform: sensry" + Storage: status: odd fixes files: @@ -4312,6 +4496,18 @@ TDK Sensors: labels: - "area: Toolchains" +"Toolchain IAR": + status: maintained + maintainers: + - RobinKastberg + files: + - cmake/*/iar/ + - include/zephyr/toolchain/iar.h + - include/zephyr/toolchain/iar/* + - lib/libc/iar/* + labels: + - "area: Toolchains" + "Toolchain oneApi": status: maintained maintainers: @@ -4434,12 +4630,13 @@ VFS: - filesystem West: - status: odd fixes + status: maintained + maintainers: + - pdgendt collaborators: - - mbolivar-ampere + - mbolivar - carlescufi - swinslow - - pdgendt files: - scripts/west-commands.yml - scripts/west_commands/ @@ -4606,6 +4803,17 @@ West: labels: - "area: CMSIS-NN" +"West project: cmsis_6": + status: maintained + maintainers: + - wearyzen + collaborators: + - tomi-font + - ithinuel + files: [] + labels: + - "area: CMSIS_6" + "West project: edtt": status: maintained maintainers: @@ -4633,6 +4841,7 @@ West: collaborators: - ozersa - ttmut + - yasinustunerg files: [] labels: - "platform: ADI" @@ -4696,6 +4905,9 @@ West: status: maintained maintainers: - kristofer-jonsson-arm + - wearyzen + collaborators: + - ithinuel files: - drivers/misc/ethos_u/ - modules/hal_ethos_u/ @@ -4768,7 +4980,7 @@ West: - dleach02 - mmahadevan108 collaborators: - - danieldegrasse + - decsny - manuargue - PetervdPerk-NXP - bperseghetti @@ -4819,6 +5031,8 @@ West: - soburi collaborators: - yonsch + - threeeights + - ajf58 files: - modules/hal_rpi_pico/ labels: @@ -4828,13 +5042,14 @@ West: status: maintained maintainers: - jhedberg + - asmellby collaborators: - jerome-pouiller - - asmellby - sateeshkotapati - yonsch - mnkp - rettichschnidi + - Martinhoff-maker files: - modules/hal_silabs/ labels: @@ -4857,11 +5072,25 @@ West: - FRASTM - gautierg-st - marwaiehm-st + - asm5878 + - HoZHel + - benothmn-st files: - modules/Kconfig.stm32 labels: - "platform: STM32" +"West project: hal_tdk": + status: maintained + maintainers: + - afontaine-invn + collaborators: + - rbuisson-invn + - gjabouley-invn + - sriccardi-invn + files: + - modules/hal_tdk/Kconfig + "West project: hal_telink": status: maintained maintainers: @@ -4926,6 +5155,18 @@ West: labels: - "area: Rust" +"West project: libmctp": + status: maintained + maintainers: + - teburd + collaborators: + - nashif + - inteljiangwe1 + files: + - samples/modules/mctp/ + labels: + - "area: MCTP" + "West project: libmetal": status: odd fixes collaborators: @@ -4972,6 +5213,7 @@ West: collaborators: - brgl - pdgendt + - uLipe files: - modules/lvgl/ - tests/lib/gui/lvgl/ @@ -4995,9 +5237,10 @@ West: - d3zd3z - ceolin collaborators: - - ithinuel + - wearyzen - valeriosetti - tomi-font + - ithinuel files: - modules/mbedtls/ - tests/crypto/mbedtls/ @@ -5081,6 +5324,8 @@ West: status: odd fixes collaborators: - carlocaione + - uLipe + - iuliana-prodan files: - modules/Kconfig.open-amp labels: @@ -5183,9 +5428,10 @@ West: - d3zd3z collaborators: - Vge0rge - - ithinuel + - wearyzen - valeriosetti - tomi-font + - ithinuel files: - modules/trusted-firmware-m/ - samples/tfm_integration/ @@ -5202,6 +5448,7 @@ West: - d3zd3z collaborators: - Vge0rge + - wearyzen - ithinuel files: [] labels: @@ -5214,6 +5461,7 @@ West: - sgrrzhf collaborators: - carlocaione + - wearyzen - ithinuel files: - modules/trusted-firmware-a/ @@ -5226,6 +5474,7 @@ West: - d3zd3z collaborators: - Vge0rge + - wearyzen - ithinuel files: [] labels: @@ -5389,6 +5638,15 @@ Random: labels: - "area: Random" +Peregrine Platforms: + status: maintained + maintainers: + - nandojve + files: + - boards/peregrine/ + labels: + - "platform: Peregrine" + # This area is to be converted to a subarea Testing with Renode: status: odd fixes @@ -5430,6 +5688,7 @@ zbus: - cmake/llext-edk.cmake - samples/subsys/llext/ - include/zephyr/llext/ + - tests/misc/llext-edk/ - tests/subsys/llext/ - subsys/llext/ - doc/services/llext/ diff --git a/VERSION b/VERSION index b170abf44be15..c0e33f9145119 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 4 -VERSION_MINOR = 0 -PATCHLEVEL = 99 +VERSION_MINOR = 1 +PATCHLEVEL = 0 VERSION_TWEAK = 0 -EXTRAVERSION = +EXTRAVERSION = rc1 diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index fa00c3722e6be..d44ca272b11c8 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -262,7 +262,7 @@ config ARC_CURRENT_THREAD_USE_NO_TLS RGF_NUM_BANKS the parameter is disabled by-default because banks syncronization requires significant time, and it slows down performance. ARCMWDT works with tls pointer in different way then GCC. Optimized access to - TLS pointer via arch_current_thread() does not provide significant advantages + TLS pointer via the _current symbol does not provide significant advantages in case of MetaWare. config GEN_ISR_TABLES diff --git a/arch/arc/core/fault.c b/arch/arc/core/fault.c index a6c8410e63357..adbd6da12bbc7 100644 --- a/arch/arc/core/fault.c +++ b/arch/arc/core/fault.c @@ -55,7 +55,7 @@ static bool z_check_thread_stack_fail(const uint32_t fault_addr, uint32_t sp) { #if defined(CONFIG_MULTITHREADING) uint32_t guard_end, guard_start; - const struct k_thread *thread = arch_current_thread(); + const struct k_thread *thread = _current; if (!thread) { /* TODO: Under what circumstances could we get here ? */ @@ -346,7 +346,7 @@ static void dump_exception_info(uint32_t vector, uint32_t cause, uint32_t parame * invokes the user provided routine k_sys_fatal_error_handler() which is * responsible for implementing the error handling policy. */ -void _Fault(struct arch_esf *esf, uint32_t old_sp) +void z_arc_fault(struct arch_esf *esf, uint32_t old_sp) { uint32_t vector, cause, parameter; uint32_t exc_addr = z_arc_v2_aux_reg_read(_ARC_V2_EFA); diff --git a/arch/arc/core/fault_s.S b/arch/arc/core/fault_s.S index d89f3fe6a8208..69fb03082a5f0 100644 --- a/arch/arc/core/fault_s.S +++ b/arch/arc/core/fault_s.S @@ -19,7 +19,7 @@ #include #include -GTEXT(_Fault) +GTEXT(z_arc_fault) GTEXT(__reset) GTEXT(__memory_error) GTEXT(__instruction_error) @@ -99,11 +99,11 @@ _exc_entry: _save_exc_regs_into_stack - /* sp is parameter of _Fault */ + /* sp is parameter of z_arc_fault */ MOVR r0, sp /* ilink is the thread's original sp */ MOVR r1, ilink - jl _Fault + jl z_arc_fault _exc_return: /* the exception cause must be fixed in exception handler when exception returns diff --git a/arch/arc/core/irq_offload.c b/arch/arc/core/irq_offload.c index f24a3e7dd8a5b..d1a3f900ca3f0 100644 --- a/arch/arc/core/irq_offload.c +++ b/arch/arc/core/irq_offload.c @@ -49,8 +49,8 @@ void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) __asm__ volatile("sync"); - /* If arch_current_thread() was aborted in the offload routine, we shouldn't be here */ - __ASSERT_NO_MSG((arch_current_thread()->base.thread_state & _THREAD_DEAD) == 0); + /* If _current was aborted in the offload routine, we shouldn't be here */ + __ASSERT_NO_MSG((_current->base.thread_state & _THREAD_DEAD) == 0); } /* need to be executed on every core in the system */ diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index cb5352bc47547..4b1d836103eed 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -210,7 +210,7 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, #ifdef CONFIG_MULTITHREADING void *z_arch_get_next_switch_handle(struct k_thread **old_thread) { - *old_thread = arch_current_thread(); + *old_thread = _current; return z_get_next_switch_handle(NULL); } @@ -227,16 +227,16 @@ void *z_arch_get_next_switch_handle(struct k_thread **old_thread) FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3) { - setup_stack_vars(arch_current_thread()); + setup_stack_vars(_current); /* possible optimizaiton: no need to load mem domain anymore */ /* need to lock cpu here ? */ - configure_mpu_thread(arch_current_thread()); + configure_mpu_thread(_current); z_arc_userspace_enter(user_entry, p1, p2, p3, - (uint32_t)arch_current_thread()->stack_info.start, - (arch_current_thread()->stack_info.size - - arch_current_thread()->stack_info.delta), arch_current_thread()); + (uint32_t)_current->stack_info.start, + (_current->stack_info.size - + _current->stack_info.delta), _current); CODE_UNREACHABLE; } #endif @@ -336,7 +336,7 @@ int arc_vpx_lock(k_timeout_t timeout) id = _current_cpu->id; #if (CONFIG_MP_MAX_NUM_CPUS > 1) && defined(CONFIG_SCHED_CPU_MASK) - __ASSERT(!arch_is_in_isr() && (arch_current_thread()->base.cpu_mask == BIT(id)), ""); + __ASSERT(!arch_is_in_isr() && (_current->base.cpu_mask == BIT(id)), ""); #endif k_spin_unlock(&lock, key); @@ -355,7 +355,7 @@ void arc_vpx_unlock(void) key = k_spin_lock(&lock); #if (CONFIG_MP_MAX_NUM_CPUS > 1) && defined(CONFIG_SCHED_CPU_MASK) - __ASSERT(!arch_is_in_isr() && (arch_current_thread()->base.cpu_mask == BIT(id)), ""); + __ASSERT(!arch_is_in_isr() && (_current->base.cpu_mask == BIT(id)), ""); #endif id = _current_cpu->id; k_spin_unlock(&lock, key); diff --git a/arch/arc/core/tls.c b/arch/arc/core/tls.c index 9585b228926c2..3cf7d45cab913 100644 --- a/arch/arc/core/tls.c +++ b/arch/arc/core/tls.c @@ -29,7 +29,7 @@ size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) void *_Preserve_flags _mwget_tls(void) { - return (void *)(arch_current_thread()->tls); + return (void *)(_current->tls); } #else diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c28cf8d29f9a4..3ce78334cb62d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -155,12 +155,12 @@ config CPU_HAS_ARM_MPU This option is enabled when the CPU has a Memory Protection Unit (MPU) in ARM flavor. -config CPU_HAS_NXP_MPU +config CPU_HAS_NXP_SYSMPU bool select CPU_HAS_MPU help - This option is enabled when the CPU has a Memory Protection Unit (MPU) - in NXP flavor. + This option is enabled when the CPU has an NXP System Memory Protection + Unit (SYSMPU). config CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS bool "Custom fixed SoC MPU region definition" diff --git a/arch/arm/core/cortex_a_r/CMakeLists.txt b/arch/arm/core/cortex_a_r/CMakeLists.txt index d4e18a614f0ab..7d18e0e610d86 100644 --- a/arch/arm/core/cortex_a_r/CMakeLists.txt +++ b/arch/arm/core/cortex_a_r/CMakeLists.txt @@ -24,4 +24,4 @@ zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE __aeabi_read_tp.S) zephyr_library_sources_ifdef(CONFIG_ARCH_CACHE cache.c) zephyr_library_sources_ifdef(CONFIG_USE_SWITCH switch.S) -zephyr_library_sources_ifndef(CONFIG_USE_SWITCH swap.c swap_helper.S exc_exit.S) +zephyr_library_sources_ifndef(CONFIG_USE_SWITCH swap_helper.S exc_exit.S) diff --git a/arch/arm/core/cortex_a_r/exc.S b/arch/arm/core/cortex_a_r/exc.S index 78414fcd0a193..ecf7bab57f091 100644 --- a/arch/arm/core/cortex_a_r/exc.S +++ b/arch/arm/core/cortex_a_r/exc.S @@ -237,6 +237,28 @@ SECTION_SUBSEC_FUNC(TEXT, __exc, z_arm_data_abort) b z_arm_exc_exit #else + +GTEXT(z_arm_cortex_ar_exit_exc) +SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_cortex_ar_exit_exc) + + /* Note: + * This function is expected to be *always* called with + * processor mode set to MODE_SYS. + */ + + /* decrement exception depth */ + get_cpu r2 + ldrb r1, [r2, #_cpu_offset_to_exc_depth] + sub r1, r1, #1 + strb r1, [r2, #_cpu_offset_to_exc_depth] + + /* + * Restore r0-r3, r12, lr, lr_und and spsr_und from the exception stack + * and return to the current thread. + */ + pop {r0-r3, r12, lr} + rfeia sp! + /** * @brief Undefined instruction exception handler * diff --git a/arch/arm/core/cortex_a_r/fault.c b/arch/arm/core/cortex_a_r/fault.c index 5e3d38a66b45d..daf1d2345ca06 100644 --- a/arch/arm/core/cortex_a_r/fault.c +++ b/arch/arm/core/cortex_a_r/fault.c @@ -178,7 +178,7 @@ bool z_arm_fault_undef_instruction_fp(void) * context because it is about to be overwritten. */ if (((_current_cpu->nested == 2) - && (arch_current_thread()->base.user_options & K_FP_REGS)) + && (_current->base.user_options & K_FP_REGS)) || ((_current_cpu->nested > 2) && (spill_esf->undefined & FPEXC_EN))) { /* @@ -196,7 +196,7 @@ bool z_arm_fault_undef_instruction_fp(void) * means that a thread that uses the VFP does not have to, * but should, set K_FP_REGS on thread creation. */ - arch_current_thread()->base.user_options |= K_FP_REGS; + _current->base.user_options |= K_FP_REGS; } return false; diff --git a/arch/arm/core/cortex_a_r/swap.c b/arch/arm/core/cortex_a_r/swap.c deleted file mode 100644 index cf123e8ed932a..0000000000000 --- a/arch/arm/core/cortex_a_r/swap.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2018 Linaro, Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include - -/* The 'key' actually represents the BASEPRI register - * prior to disabling interrupts via the BASEPRI mechanism. - * - * arch_swap() itself does not do much. - */ -int arch_swap(unsigned int key) -{ - /* store off key and return value */ - arch_current_thread()->arch.basepri = key; - arch_current_thread()->arch.swap_return_value = -EAGAIN; - - z_arm_cortex_r_svc(); - irq_unlock(key); - - /* Context switch is performed here. Returning implies the - * thread has been context-switched-in again. - */ - return arch_current_thread()->arch.swap_return_value; -} diff --git a/arch/arm/core/cortex_a_r/swap_helper.S b/arch/arm/core/cortex_a_r/swap_helper.S index 36dd9a9654806..a41e1ab5942fe 100644 --- a/arch/arm/core/cortex_a_r/swap_helper.S +++ b/arch/arm/core/cortex_a_r/swap_helper.S @@ -70,7 +70,7 @@ SECTION_FUNC(TEXT, z_arm_do_swap) #if defined(CONFIG_FPU_SHARING) ldrb r0, [r2, #_thread_offset_to_user_options] - tst r0, #K_FP_REGS /* arch_current_thread()->base.user_options & K_FP_REGS */ + tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ beq out_fp_inactive mov ip, #FPEXC_EN @@ -152,7 +152,7 @@ out_fp_inactive: #if defined(CONFIG_FPU_SHARING) ldrb r0, [r2, #_thread_offset_to_user_options] - tst r0, #K_FP_REGS /* arch_current_thread()->base.user_options & K_FP_REGS */ + tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ beq in_fp_inactive mov r3, #FPEXC_EN diff --git a/arch/arm/core/cortex_a_r/thread.c b/arch/arm/core/cortex_a_r/thread.c index 43be2d5069022..b3bd91ce5c11c 100644 --- a/arch/arm/core/cortex_a_r/thread.c +++ b/arch/arm/core/cortex_a_r/thread.c @@ -198,8 +198,8 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, { /* Set up privileged stack before entering user mode */ - arch_current_thread()->arch.priv_stack_start = - (uint32_t)z_priv_stack_find(arch_current_thread()->stack_obj); + _current->arch.priv_stack_start = + (uint32_t)z_priv_stack_find(_current->stack_obj); #if defined(CONFIG_MPU_STACK_GUARD) #if defined(CONFIG_THREAD_STACK_INFO) /* We're dropping to user mode which means the guard area is no @@ -208,13 +208,13 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, * which accounted for memory borrowed from the thread stack. */ #if FP_GUARD_EXTRA_SIZE > 0 - if ((arch_current_thread()->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { - arch_current_thread()->stack_info.start -= FP_GUARD_EXTRA_SIZE; - arch_current_thread()->stack_info.size += FP_GUARD_EXTRA_SIZE; + if ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { + _current->stack_info.start -= FP_GUARD_EXTRA_SIZE; + _current->stack_info.size += FP_GUARD_EXTRA_SIZE; } #endif /* FP_GUARD_EXTRA_SIZE */ - arch_current_thread()->stack_info.start -= MPU_GUARD_ALIGN_AND_SIZE; - arch_current_thread()->stack_info.size += MPU_GUARD_ALIGN_AND_SIZE; + _current->stack_info.start -= MPU_GUARD_ALIGN_AND_SIZE; + _current->stack_info.size += MPU_GUARD_ALIGN_AND_SIZE; #endif /* CONFIG_THREAD_STACK_INFO */ /* Stack guard area reserved at the bottom of the thread's @@ -222,23 +222,23 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, * buffer area accordingly. */ #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - arch_current_thread()->arch.priv_stack_start += - ((arch_current_thread()->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? + _current->arch.priv_stack_start += + ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; #else - arch_current_thread()->arch.priv_stack_start += MPU_GUARD_ALIGN_AND_SIZE; + _current->arch.priv_stack_start += MPU_GUARD_ALIGN_AND_SIZE; #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ #endif /* CONFIG_MPU_STACK_GUARD */ #if defined(CONFIG_CPU_AARCH32_CORTEX_R) - arch_current_thread()->arch.priv_stack_end = - arch_current_thread()->arch.priv_stack_start + CONFIG_PRIVILEGED_STACK_SIZE; + _current->arch.priv_stack_end = + _current->arch.priv_stack_start + CONFIG_PRIVILEGED_STACK_SIZE; #endif z_arm_userspace_enter(user_entry, p1, p2, p3, - (uint32_t)arch_current_thread()->stack_info.start, - arch_current_thread()->stack_info.size - - arch_current_thread()->stack_info.delta); + (uint32_t)_current->stack_info.start, + _current->stack_info.size - + _current->stack_info.delta); CODE_UNREACHABLE; } @@ -304,7 +304,7 @@ EXPORT_SYMBOL(z_arm_thread_is_in_user_mode); uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp) { #if defined(CONFIG_MULTITHREADING) - const struct k_thread *thread = arch_current_thread(); + const struct k_thread *thread = _current; if (thread == NULL) { return 0; @@ -314,7 +314,7 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp #if (defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)) && \ defined(CONFIG_MPU_STACK_GUARD) uint32_t guard_len = - ((arch_current_thread()->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? + ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; #else /* If MPU_STACK_GUARD is not enabled, the guard length is @@ -377,7 +377,7 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) int arch_float_disable(struct k_thread *thread) { - if (thread != arch_current_thread()) { + if (thread != _current) { return -EINVAL; } diff --git a/arch/arm/core/cortex_a_r/vector_table.S b/arch/arm/core/cortex_a_r/vector_table.S index e74b6a41c8d6b..d5d95272548fd 100644 --- a/arch/arm/core/cortex_a_r/vector_table.S +++ b/arch/arm/core/cortex_a_r/vector_table.S @@ -35,27 +35,3 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table) #else ldr pc,=z_irq_spurious #endif - - -#ifdef CONFIG_USE_SWITCH -GTEXT(z_arm_cortex_ar_exit_exc) -SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_cortex_ar_exit_exc) - - /* Note: - * This function is expected to be *always* called with - * processor mode set to MODE_SYS. - */ - - /* decrement exception depth */ - get_cpu r2 - ldrb r1, [r2, #_cpu_offset_to_exc_depth] - sub r1, r1, #1 - strb r1, [r2, #_cpu_offset_to_exc_depth] - - /* - * Restore r0-r3, r12, lr, lr_und and spsr_und from the exception stack - * and return to the current thread. - */ - pop {r0-r3, r12, lr} - rfeia sp! -#endif diff --git a/arch/arm/core/cortex_m/CMakeLists.txt b/arch/arm/core/cortex_m/CMakeLists.txt index b220e6c81e849..05723811929ab 100644 --- a/arch/arm/core/cortex_m/CMakeLists.txt +++ b/arch/arm/core/cortex_m/CMakeLists.txt @@ -11,7 +11,6 @@ zephyr_library_sources( scb.c thread_abort.c vector_table.S - swap.c swap_helper.S irq_manage.c prep_c.c diff --git a/arch/arm/core/cortex_m/cmse/arm_core_cmse.c b/arch/arm/core/cortex_m/cmse/arm_core_cmse.c index aac96472ecf4f..163a9d0cdd205 100644 --- a/arch/arm/core/cortex_m/cmse/arm_core_cmse.c +++ b/arch/arm/core/cortex_m/cmse/arm_core_cmse.c @@ -9,7 +9,7 @@ int arm_cmse_mpu_region_get(uint32_t addr) { - cmse_address_info_t addr_info = cmse_TT((void *)addr); + cmse_address_info_t addr_info = cmse_TT((void *)addr); if (addr_info.flags.mpu_region_valid) { return addr_info.flags.mpu_region; @@ -40,8 +40,7 @@ int arm_cmse_addr_readwrite_ok(uint32_t addr, int force_npriv) return arm_cmse_addr_read_write_ok(addr, force_npriv, 1); } -static int arm_cmse_addr_range_read_write_ok(uint32_t addr, uint32_t size, - int force_npriv, int rw) +static int arm_cmse_addr_range_read_write_ok(uint32_t addr, uint32_t size, int force_npriv, int rw) { int flags = 0; @@ -74,10 +73,10 @@ int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npr int arm_cmse_mpu_nonsecure_region_get(uint32_t addr) { - cmse_address_info_t addr_info = cmse_TTA((void *)addr); + cmse_address_info_t addr_info = cmse_TTA((void *)addr); if (addr_info.flags.mpu_region_valid) { - return addr_info.flags.mpu_region; + return addr_info.flags.mpu_region; } return -EINVAL; @@ -85,7 +84,7 @@ int arm_cmse_mpu_nonsecure_region_get(uint32_t addr) int arm_cmse_sau_region_get(uint32_t addr) { - cmse_address_info_t addr_info = cmse_TT((void *)addr); + cmse_address_info_t addr_info = cmse_TT((void *)addr); if (addr_info.flags.sau_region_valid) { return addr_info.flags.sau_region; @@ -96,7 +95,7 @@ int arm_cmse_sau_region_get(uint32_t addr) int arm_cmse_idau_region_get(uint32_t addr) { - cmse_address_info_t addr_info = cmse_TT((void *)addr); + cmse_address_info_t addr_info = cmse_TT((void *)addr); if (addr_info.flags.idau_region_valid) { return addr_info.flags.idau_region; @@ -107,13 +106,12 @@ int arm_cmse_idau_region_get(uint32_t addr) int arm_cmse_addr_is_secure(uint32_t addr) { - cmse_address_info_t addr_info = cmse_TT((void *)addr); + cmse_address_info_t addr_info = cmse_TT((void *)addr); return addr_info.flags.secure; } -static int arm_cmse_addr_nonsecure_read_write_ok(uint32_t addr, - int force_npriv, int rw) +static int arm_cmse_addr_nonsecure_read_write_ok(uint32_t addr, int force_npriv, int rw) { cmse_address_info_t addr_info; if (force_npriv) { @@ -122,8 +120,7 @@ static int arm_cmse_addr_nonsecure_read_write_ok(uint32_t addr, addr_info = cmse_TTA((void *)addr); } - return rw ? addr_info.flags.nonsecure_readwrite_ok : - addr_info.flags.nonsecure_read_ok; + return rw ? addr_info.flags.nonsecure_readwrite_ok : addr_info.flags.nonsecure_read_ok; } int arm_cmse_addr_nonsecure_read_ok(uint32_t addr, int force_npriv) @@ -137,7 +134,7 @@ int arm_cmse_addr_nonsecure_readwrite_ok(uint32_t addr, int force_npriv) } static int arm_cmse_addr_range_nonsecure_read_write_ok(uint32_t addr, uint32_t size, - int force_npriv, int rw) + int force_npriv, int rw) { int flags = CMSE_NONSECURE; @@ -156,18 +153,14 @@ static int arm_cmse_addr_range_nonsecure_read_write_ok(uint32_t addr, uint32_t s } } -int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, - int force_npriv) +int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, int force_npriv) { - return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size, - force_npriv, 0); + return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size, force_npriv, 0); } -int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, - int force_npriv) +int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv) { - return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size, - force_npriv, 1); + return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size, force_npriv, 1); } #endif /* CONFIG_ARM_SECURE_FIRMWARE */ diff --git a/arch/arm/core/cortex_m/coredump.c b/arch/arm/core/cortex_m/coredump.c index c688c91d9819d..ddb539c4e34ef 100644 --- a/arch/arm/core/cortex_m/coredump.c +++ b/arch/arm/core/cortex_m/coredump.c @@ -7,31 +7,31 @@ #include #include -#define ARCH_HDR_VER 2 +#define ARCH_HDR_VER 2 uint32_t z_arm_coredump_fault_sp; struct arm_arch_block { struct { - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r12; - uint32_t lr; - uint32_t pc; - uint32_t xpsr; - uint32_t sp; + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t xpsr; + uint32_t sp; /* callee registers - optionally collected in V2 */ - uint32_t r4; - uint32_t r5; - uint32_t r6; - uint32_t r7; - uint32_t r8; - uint32_t r9; - uint32_t r10; - uint32_t r11; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; } r; } __packed; @@ -76,12 +76,12 @@ void arch_coredump_info_dump(const struct arch_esf *esf) #if defined(CONFIG_EXTRA_EXCEPTION_INFO) if (esf->extra_info.callee) { - arch_blk.r.r4 = esf->extra_info.callee->v1; - arch_blk.r.r5 = esf->extra_info.callee->v2; - arch_blk.r.r6 = esf->extra_info.callee->v3; - arch_blk.r.r7 = esf->extra_info.callee->v4; - arch_blk.r.r8 = esf->extra_info.callee->v5; - arch_blk.r.r9 = esf->extra_info.callee->v6; + arch_blk.r.r4 = esf->extra_info.callee->v1; + arch_blk.r.r5 = esf->extra_info.callee->v2; + arch_blk.r.r6 = esf->extra_info.callee->v3; + arch_blk.r.r7 = esf->extra_info.callee->v4; + arch_blk.r.r8 = esf->extra_info.callee->v5; + arch_blk.r.r9 = esf->extra_info.callee->v6; arch_blk.r.r10 = esf->extra_info.callee->v7; arch_blk.r.r11 = esf->extra_info.callee->v8; } diff --git a/arch/arm/core/cortex_m/cpu_idle.c b/arch/arm/core/cortex_m/cpu_idle.c index 5f373a88c9d55..8b3c416940f83 100644 --- a/arch/arm/core/cortex_m/cpu_idle.c +++ b/arch/arm/core/cortex_m/cpu_idle.c @@ -30,27 +30,31 @@ void z_arm_cpu_idle_init(void) #if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE) #define ON_EXIT_IDLE_HOOK SOC_ON_EXIT_CPU_IDLE #else -#define ON_EXIT_IDLE_HOOK do {} while (false) +#define ON_EXIT_IDLE_HOOK \ + do { \ + } while (false) #endif #if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK) -#define SLEEP_IF_ALLOWED(wait_instr) do { \ - /* Skip the wait instr if on_enter_cpu_idle returns false */ \ - if (z_arm_on_enter_cpu_idle()) { \ - /* Wait for all memory transaction to complete */ \ - /* before entering low power state. */ \ - __DSB(); \ - wait_instr(); \ - /* Inline the macro provided by SoC-specific code */ \ - ON_EXIT_IDLE_HOOK; \ - } \ -} while (false) +#define SLEEP_IF_ALLOWED(wait_instr) \ + do { \ + /* Skip the wait instr if on_enter_cpu_idle returns false */ \ + if (z_arm_on_enter_cpu_idle()) { \ + /* Wait for all memory transaction to complete */ \ + /* before entering low power state. */ \ + __DSB(); \ + wait_instr(); \ + /* Inline the macro provided by SoC-specific code */ \ + ON_EXIT_IDLE_HOOK; \ + } \ + } while (false) #else -#define SLEEP_IF_ALLOWED(wait_instr) do { \ - __DSB(); \ - wait_instr(); \ - ON_EXIT_IDLE_HOOK; \ -} while (false) +#define SLEEP_IF_ALLOWED(wait_instr) \ + do { \ + __DSB(); \ + wait_instr(); \ + ON_EXIT_IDLE_HOOK; \ + } while (false) #endif #ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE diff --git a/arch/arm/core/cortex_m/debug.c b/arch/arm/core/cortex_m/debug.c index 61fb681453507..47141d913dd14 100644 --- a/arch/arm/core/cortex_m/debug.c +++ b/arch/arm/core/cortex_m/debug.c @@ -35,7 +35,7 @@ bool z_arm_debug_monitor_event_error_check(void) printk("Null-pointer exception?\n"); } __ASSERT((DWT->FUNCTION0 & DWT_FUNCTION_MATCHED_Msk) == 0, - "MATCHED flag should have been cleared on read."); + "MATCHED flag should have been cleared on read."); return true; } @@ -55,8 +55,8 @@ bool z_arm_debug_monitor_event_error_check(void) * so we add a build assert that catches it. */ BUILD_ASSERT(!(CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE & - (CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE - 1)), - "the size of the partition must be power of 2"); + (CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE - 1)), + "the size of the partition must be power of 2"); int z_arm_debug_enable_null_pointer_detection(void) { @@ -81,20 +81,12 @@ int z_arm_debug_enable_null_pointer_detection(void) DWT->COMP0 = 0; DWT->COMP1 = CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE - 1; - DWT->FUNCTION0 = - ((0x4 << DWT_FUNCTION_MATCH_Pos) & DWT_FUNCTION_MATCH_Msk) - | - ((0x1 << DWT_FUNCTION_ACTION_Pos) & DWT_FUNCTION_ACTION_Msk) - | - ((0x0 << DWT_FUNCTION_DATAVSIZE_Pos) & DWT_FUNCTION_DATAVSIZE_Msk) - ; - DWT->FUNCTION1 = - ((0x7 << DWT_FUNCTION_MATCH_Pos) & DWT_FUNCTION_MATCH_Msk) - | - ((0x1 << DWT_FUNCTION_ACTION_Pos) & DWT_FUNCTION_ACTION_Msk) - | - ((0x0 << DWT_FUNCTION_DATAVSIZE_Pos) & DWT_FUNCTION_DATAVSIZE_Msk) - ; + DWT->FUNCTION0 = ((0x4 << DWT_FUNCTION_MATCH_Pos) & DWT_FUNCTION_MATCH_Msk) | + ((0x1 << DWT_FUNCTION_ACTION_Pos) & DWT_FUNCTION_ACTION_Msk) | + ((0x0 << DWT_FUNCTION_DATAVSIZE_Pos) & DWT_FUNCTION_DATAVSIZE_Msk); + DWT->FUNCTION1 = ((0x7 << DWT_FUNCTION_MATCH_Pos) & DWT_FUNCTION_MATCH_Msk) | + ((0x1 << DWT_FUNCTION_ACTION_Pos) & DWT_FUNCTION_ACTION_Msk) | + ((0x0 << DWT_FUNCTION_DATAVSIZE_Pos) & DWT_FUNCTION_DATAVSIZE_Msk); #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* ASSERT that we have the comparator needed for the implementation */ @@ -106,13 +98,10 @@ int z_arm_debug_enable_null_pointer_detection(void) /* Use comparator 0, R/W access check */ DWT->COMP0 = 0; - DWT->FUNCTION0 = (0x7 << DWT_FUNCTION_FUNCTION_Pos) & - DWT_FUNCTION_FUNCTION_Msk; - + DWT->FUNCTION0 = (0x7 << DWT_FUNCTION_FUNCTION_Pos) & DWT_FUNCTION_FUNCTION_Msk; /* Set mask according to the desired size */ - DWT->MASK0 = 32 - __builtin_clzl( - CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE - 1); + DWT->MASK0 = 32 - __builtin_clzl(CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE - 1); #endif return 0; diff --git a/arch/arm/core/cortex_m/exc_exit.c b/arch/arm/core/cortex_m/exc_exit.c index 450b397236164..a919fd8bbd7df 100644 --- a/arch/arm/core/cortex_m/exc_exit.c +++ b/arch/arm/core/cortex_m/exc_exit.c @@ -55,13 +55,8 @@ FUNC_ALIAS(z_arm_exc_exit, z_arm_int_exit, void); Z_GENERIC_SECTION(.text._HandlerModeExit) void z_arm_exc_exit(void) { #ifdef CONFIG_PREEMPT_ENABLED - /* If thread is preemptible */ - if (_kernel.cpus->current->base.prio >= 0) { - /* and cached thread is not current thread */ - if (_kernel.ready_q.cache != _kernel.cpus->current) { - /* trigger a context switch */ - SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; - } + if (_kernel.ready_q.cache != _kernel.cpus->current) { + SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; } #endif /* CONFIG_PREEMPT_ENABLED */ diff --git a/arch/arm/core/cortex_m/fault.c b/arch/arm/core/cortex_m/fault.c index 604801a6414d9..27ce260dad535 100644 --- a/arch/arm/core/cortex_m/fault.c +++ b/arch/arm/core/cortex_m/fault.c @@ -22,7 +22,7 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #if defined(CONFIG_PRINTK) || defined(CONFIG_LOG) -#define PR_EXC(...) LOG_ERR(__VA_ARGS__) +#define PR_EXC(...) LOG_ERR(__VA_ARGS__) #define STORE_xFAR(reg_var, reg) uint32_t reg_var = (uint32_t)reg #else #define PR_EXC(...) @@ -35,9 +35,9 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #define PR_FAULT_INFO(...) #endif -#if defined(CONFIG_ARM_MPU) && defined(CONFIG_CPU_HAS_NXP_MPU) -#define EMN(edr) (((edr) & SYSMPU_EDR_EMN_MASK) >> SYSMPU_EDR_EMN_SHIFT) -#define EACD(edr) (((edr) & SYSMPU_EDR_EACD_MASK) >> SYSMPU_EDR_EACD_SHIFT) +#if defined(CONFIG_ARM_MPU) && defined(CONFIG_CPU_HAS_NXP_SYSMPU) +#define EMN(edr) (((edr) & SYSMPU_EDR_EMN_MASK) >> SYSMPU_EDR_EMN_SHIFT) +#define EACD(edr) (((edr) & SYSMPU_EDR_EACD_MASK) >> SYSMPU_EDR_EACD_SHIFT) #endif /* Integrity signature for an ARMv8-M implementation */ @@ -54,15 +54,12 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* helpers to access memory/bus/usage faults */ -#define SCB_CFSR_MEMFAULTSR \ - (uint32_t)((SCB->CFSR & SCB_CFSR_MEMFAULTSR_Msk) \ - >> SCB_CFSR_MEMFAULTSR_Pos) -#define SCB_CFSR_BUSFAULTSR \ - (uint32_t)((SCB->CFSR & SCB_CFSR_BUSFAULTSR_Msk) \ - >> SCB_CFSR_BUSFAULTSR_Pos) -#define SCB_CFSR_USGFAULTSR \ - (uint32_t)((SCB->CFSR & SCB_CFSR_USGFAULTSR_Msk) \ - >> SCB_CFSR_USGFAULTSR_Pos) +#define SCB_CFSR_MEMFAULTSR \ + (uint32_t)((SCB->CFSR & SCB_CFSR_MEMFAULTSR_Msk) >> SCB_CFSR_MEMFAULTSR_Pos) +#define SCB_CFSR_BUSFAULTSR \ + (uint32_t)((SCB->CFSR & SCB_CFSR_BUSFAULTSR_Msk) >> SCB_CFSR_BUSFAULTSR_Pos) +#define SCB_CFSR_USGFAULTSR \ + (uint32_t)((SCB->CFSR & SCB_CFSR_USGFAULTSR_Msk) >> SCB_CFSR_USGFAULTSR_Pos) #endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */ /** @@ -103,8 +100,8 @@ static void fault_show(const struct arch_esf *esf, int fault) PR_EXC("Fault! EXC #%d", fault); #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - PR_EXC("MMFSR: 0x%x, BFSR: 0x%x, UFSR: 0x%x", SCB_CFSR_MEMFAULTSR, - SCB_CFSR_BUSFAULTSR, SCB_CFSR_USGFAULTSR); + PR_EXC("MMFSR: 0x%x, BFSR: 0x%x, UFSR: 0x%x", SCB_CFSR_MEMFAULTSR, SCB_CFSR_BUSFAULTSR, + SCB_CFSR_USGFAULTSR); #if defined(CONFIG_ARM_SECURE_FIRMWARE) PR_EXC("SFSR: 0x%x", SAU->SFSR); #endif /* CONFIG_ARM_SECURE_FIRMWARE */ @@ -127,9 +124,7 @@ static void fault_show(const struct arch_esf *esf, int fault) #ifdef CONFIG_USERSPACE Z_EXC_DECLARE(z_arm_user_string_nlen); -static const struct z_exc_handle exceptions[] = { - Z_EXC_HANDLE(z_arm_user_string_nlen) -}; +static const struct z_exc_handle exceptions[] = {Z_EXC_HANDLE(z_arm_user_string_nlen)}; #endif /* Perform an assessment whether an MPU fault shall be @@ -146,12 +141,12 @@ static bool memory_fault_recoverable(struct arch_esf *esf, bool synchronous) uint32_t end = (uint32_t)exceptions[i].end & ~0x1U; #if defined(CONFIG_NULL_POINTER_EXCEPTION_DETECTION_DWT) - /* Non-synchronous exceptions (e.g. DebugMonitor) may have - * allowed PC to continue to the next instruction. - */ - end += (synchronous) ? 0x0 : 0x4; + /* Non-synchronous exceptions (e.g. DebugMonitor) may have + * allowed PC to continue to the next instruction. + */ + end += (synchronous) ? 0x0 : 0x4; #else - ARG_UNUSED(synchronous); + ARG_UNUSED(synchronous); #endif if (esf->basic.pc >= start && esf->basic.pc < end) { esf->basic.pc = (uint32_t)(exceptions[i].fixup); @@ -168,8 +163,7 @@ static bool memory_fault_recoverable(struct arch_esf *esf, bool synchronous) #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) #if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) -uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, - const uint32_t psp); +uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp); #endif /* CONFIG_MPU_STACK_GUARD || defined(CONFIG_USERSPACE) */ /** @@ -180,8 +174,7 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, * * @return error code to identify the fatal error reason */ -static uint32_t mem_manage_fault(struct arch_esf *esf, int from_hard_fault, - bool *recoverable) +static uint32_t mem_manage_fault(struct arch_esf *esf, int from_hard_fault, bool *recoverable) { uint32_t reason = K_ERR_ARM_MEM_GENERIC; uint32_t mmfar = -EINVAL; @@ -191,7 +184,7 @@ static uint32_t mem_manage_fault(struct arch_esf *esf, int from_hard_fault, if ((SCB->CFSR & SCB_CFSR_MSTKERR_Msk) != 0) { reason = K_ERR_ARM_MEM_STACKING; PR_FAULT_INFO(" Stacking error (context area might be" - " not valid)"); + " not valid)"); } if ((SCB->CFSR & SCB_CFSR_MUNSTKERR_Msk) != 0) { reason = K_ERR_ARM_MEM_UNSTACKING; @@ -226,8 +219,7 @@ static uint32_t mem_manage_fault(struct arch_esf *esf, int from_hard_fault, #if defined(CONFIG_ARMV7_M_ARMV8_M_FP) if ((SCB->CFSR & SCB_CFSR_MLSPERR_Msk) != 0) { reason = K_ERR_ARM_MEM_FP_LAZY_STATE_PRESERVATION; - PR_FAULT_INFO( - " Floating-point lazy state preservation error"); + PR_FAULT_INFO(" Floating-point lazy state preservation error"); } #endif /* CONFIG_ARMV7_M_ARMV8_M_FP */ @@ -244,8 +236,7 @@ static uint32_t mem_manage_fault(struct arch_esf *esf, int from_hard_fault, * Data Access Violation errors may or may not be caused by * thread stack overflows. */ - if ((SCB->CFSR & SCB_CFSR_MSTKERR_Msk) || - (SCB->CFSR & SCB_CFSR_DACCVIOL_Msk)) { + if ((SCB->CFSR & SCB_CFSR_MSTKERR_Msk) || (SCB->CFSR & SCB_CFSR_DACCVIOL_Msk)) { #if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) /* MemManage Faults are always banked between security * states. Therefore, we can safely assume the fault @@ -265,8 +256,8 @@ static uint32_t mem_manage_fault(struct arch_esf *esf, int from_hard_fault, * handle the case of 'mmfar' holding the -EINVAL value. */ if (SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) { - uint32_t min_stack_ptr = z_check_thread_stack_fail(mmfar, - ((uint32_t) &esf[0])); + uint32_t min_stack_ptr = + z_check_thread_stack_fail(mmfar, ((uint32_t)&esf[0])); if (min_stack_ptr) { /* When MemManage Stacking Error has occurred, @@ -299,14 +290,14 @@ static uint32_t mem_manage_fault(struct arch_esf *esf, int from_hard_fault, reason = K_ERR_STACK_CHK_FAIL; } else { __ASSERT(!(SCB->CFSR & SCB_CFSR_MSTKERR_Msk), - "Stacking error not a stack fail\n"); + "Stacking error not a stack fail\n"); } } #else - (void)mmfar; - __ASSERT(!(SCB->CFSR & SCB_CFSR_MSTKERR_Msk), - "Stacking or Data Access Violation error " - "without stack guard, user-mode or null-pointer detection\n"); + (void)mmfar; + __ASSERT(!(SCB->CFSR & SCB_CFSR_MSTKERR_Msk), + "Stacking or Data Access Violation error " + "without stack guard, user-mode or null-pointer detection\n"); #endif /* CONFIG_MPU_STACK_GUARD || CONFIG_USERSPACE */ } @@ -392,7 +383,7 @@ static int bus_fault(struct arch_esf *esf, int from_hard_fault, bool *recoverabl } #endif /* !defined(CONFIG_ARMV7_M_ARMV8_M_FP) */ -#if defined(CONFIG_ARM_MPU) && defined(CONFIG_CPU_HAS_NXP_MPU) +#if defined(CONFIG_ARM_MPU) && defined(CONFIG_CPU_HAS_NXP_SYSMPU) uint32_t sperr = SYSMPU->CESR & SYSMPU_CESR_SPERR_MASK; uint32_t mask = BIT(31); int i; @@ -408,13 +399,10 @@ static int bus_fault(struct arch_esf *esf, int from_hard_fault, bool *recoverabl PR_FAULT_INFO(" NXP MPU error, port %d", i); PR_FAULT_INFO(" Mode: %s, %s Address: 0x%x", - edr & BIT(2) ? "Supervisor" : "User", - edr & BIT(1) ? "Data" : "Instruction", - ear); - PR_FAULT_INFO( - " Type: %s, Master: %d, Regions: 0x%x", - edr & BIT(0) ? "Write" : "Read", - EMN(edr), EACD(edr)); + edr & BIT(2) ? "Supervisor" : "User", + edr & BIT(1) ? "Data" : "Instruction", ear); + PR_FAULT_INFO(" Type: %s, Master: %d, Regions: 0x%x", + edr & BIT(0) ? "Write" : "Read", EMN(edr), EACD(edr)); /* When stack protection is enabled, we need to assess * if the memory violation error is a stack corruption. @@ -427,7 +415,7 @@ static int bus_fault(struct arch_esf *esf, int from_hard_fault, bool *recoverabl /* Note: we can assume the fault originated * from the same security state for ARM * platforms implementing the NXP MPU - * (CONFIG_CPU_HAS_NXP_MPU=y). + * (CONFIG_CPU_HAS_NXP_SYSMPU=y). * * As we only assess thread stack corruption, * we only process the error further, if the @@ -437,8 +425,7 @@ static int bus_fault(struct arch_esf *esf, int from_hard_fault, bool *recoverabl */ if (SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) { uint32_t min_stack_ptr = - z_check_thread_stack_fail(ear, - ((uint32_t) &esf[0])); + z_check_thread_stack_fail(ear, ((uint32_t)&esf[0])); if (min_stack_ptr) { /* When BusFault Stacking Error @@ -468,22 +455,20 @@ static int bus_fault(struct arch_esf *esf, int from_hard_fault, bool *recoverabl */ __set_PSP(min_stack_ptr); - reason = - K_ERR_STACK_CHK_FAIL; + reason = K_ERR_STACK_CHK_FAIL; break; } } #else (void)ear; __ASSERT(0, - "Stacking error without stack guard" - "or User-mode support"); + "Stacking error without stack guard or User-mode support"); #endif /* CONFIG_MPU_STACK_GUARD || CONFIG_USERSPACE */ } } SYSMPU->CESR &= ~sperr; } -#endif /* defined(CONFIG_ARM_MPU) && defined(CONFIG_CPU_HAS_NXP_MPU) */ +#endif /* defined(CONFIG_ARM_MPU) && defined(CONFIG_CPU_HAS_NXP_SYSMPU) */ /* clear BFSR sticky bits */ SCB->CFSR |= SCB_CFSR_BUSFAULTSR_Msk; @@ -617,8 +602,7 @@ static void debug_monitor(struct arch_esf *esf, bool *recoverable) { *recoverable = false; - PR_FAULT_INFO( - "***** Debug monitor exception *****"); + PR_FAULT_INFO("***** Debug monitor exception *****"); #if defined(CONFIG_NULL_POINTER_EXCEPTION_DETECTION_DWT) if (!z_arm_debug_monitor_event_error_check()) { @@ -675,7 +659,7 @@ static inline bool z_arm_is_synchronous_svc(struct arch_esf *esf) #endif /* ARMV6_M_ARMV8_M_BASELINE && !ARMV8_M_BASELINE */ if (((fault_insn & 0xff00) == _SVC_OPCODE) && - ((fault_insn & 0x00ff) == _SVC_CALL_RUNTIME_EXCEPT)) { + ((fault_insn & 0x00ff) == _SVC_CALL_RUNTIME_EXCEPT)) { return true; } #undef _SVC_OPCODE @@ -759,13 +743,11 @@ static uint32_t hard_fault(struct arch_esf *esf, bool *recoverable) reason = secure_fault(esf); #endif /* CONFIG_ARM_SECURE_FIRMWARE */ } else { - __ASSERT(0, - "Fault escalation without FSR info"); + __ASSERT(0, "Fault escalation without FSR info"); } } else { - __ASSERT(0, - "HardFault without HFSR info" - " Shall never occur"); + __ASSERT(0, "HardFault without HFSR info" + " Shall never occur"); } #else #error Unknown ARM architecture @@ -786,8 +768,7 @@ static void reserved_exception(const struct arch_esf *esf, int fault) ARG_UNUSED(esf); PR_FAULT_INFO("***** %s %d) *****", - fault < 16 ? "Reserved Exception (" : "Spurious interrupt (IRQ ", - fault - 16); + fault < 16 ? "Reserved Exception (" : "Spurious interrupt (IRQ ", fault - 16); } /* Handler function for ARM fault conditions. */ @@ -802,7 +783,7 @@ static uint32_t fault_handle(struct arch_esf *esf, int fault, bool *recoverable) reason = hard_fault(esf, recoverable); break; #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) - /* HardFault is raised for all fault conditions on ARMv6-M. */ + /* HardFault is raised for all fault conditions on ARMv6-M. */ #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) case 4: reason = mem_manage_fault(esf, 0, recoverable); @@ -860,7 +841,7 @@ static void secure_stack_dump(const struct arch_esf *secure_esf) uint32_t sec_ret_addr; #if defined(CONFIG_ARMV7_M_ARMV8_M_FP) if ((*top_of_sec_stack == INTEGRITY_SIGNATURE_STD) || - (*top_of_sec_stack == INTEGRITY_SIGNATURE_EXT)) { + (*top_of_sec_stack == INTEGRITY_SIGNATURE_EXT)) { #else if (*top_of_sec_stack == INTEGRITY_SIGNATURE) { #endif /* CONFIG_ARMV7_M_ARMV8_M_FP */ @@ -879,7 +860,6 @@ static void secure_stack_dump(const struct arch_esf *secure_esf) sec_ret_addr = *top_of_sec_stack; } PR_FAULT_INFO(" S instruction address: 0x%x", sec_ret_addr); - } #define SECURE_STACK_DUMP(esf) secure_stack_dump(esf) #else @@ -900,15 +880,14 @@ static void secure_stack_dump(const struct arch_esf *secure_esf) * @return ESF pointer on success, otherwise return NULL */ static inline struct arch_esf *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_return, - bool *nested_exc) + bool *nested_exc) { bool alternative_state_exc = false; struct arch_esf *ptr_esf = NULL; *nested_exc = false; - if ((exc_return & EXC_RETURN_INDICATOR_PREFIX) != - EXC_RETURN_INDICATOR_PREFIX) { + if ((exc_return & EXC_RETURN_INDICATOR_PREFIX) != EXC_RETURN_INDICATOR_PREFIX) { /* Invalid EXC_RETURN value. This is a fatal error. */ return NULL; } @@ -988,8 +967,7 @@ static inline struct arch_esf *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_ /* The processor has a single execution state. * We verify that the Thread mode is using PSP. */ - if ((exc_return & EXC_RETURN_MODE_THREAD) && - (!(exc_return & EXC_RETURN_SPSEL_PROCESS))) { + if ((exc_return & EXC_RETURN_MODE_THREAD) && (!(exc_return & EXC_RETURN_SPSEL_PROCESS))) { PR_EXC("SPSEL in thread mode does not indicate PSP"); return NULL; } @@ -998,7 +976,7 @@ static inline struct arch_esf *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_ if (!alternative_state_exc) { if (exc_return & EXC_RETURN_MODE_THREAD) { /* Returning to thread mode */ - ptr_esf = (struct arch_esf *)psp; + ptr_esf = (struct arch_esf *)psp; } else { /* Returning to handler mode */ @@ -1041,8 +1019,7 @@ static inline struct arch_esf *get_esf(uint32_t msp, uint32_t psp, uint32_t exc_ * @param callee_regs Callee-saved registers (R4-R11, PSP) * */ -void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, - _callee_saved_t *callee_regs) +void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, _callee_saved_t *callee_regs) { uint32_t reason = K_ERR_CPU_EXCEPTION; int fault = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk; @@ -1060,9 +1037,8 @@ void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, /* Retrieve the Exception Stack Frame (ESF) to be supplied * as argument to the remainder of the fault handling process. */ - esf = get_esf(msp, psp, exc_return, &nested_exc); - __ASSERT(esf != NULL, - "ESF could not be retrieved successfully. Shall never occur."); + esf = get_esf(msp, psp, exc_return, &nested_exc); + __ASSERT(esf != NULL, "ESF could not be retrieved successfully. Shall never occur."); z_arm_set_fault_sp(esf, exc_return); @@ -1080,11 +1056,8 @@ void z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, * so we only copy the fields before those. */ memcpy(&esf_copy, esf, offsetof(struct arch_esf, extra_info)); - esf_copy.extra_info = (struct __extra_esf_info) { - .callee = callee_regs, - .exc_return = exc_return, - .msp = msp - }; + esf_copy.extra_info = (struct __extra_esf_info){ + .callee = callee_regs, .exc_return = exc_return, .msp = msp}; #endif /* CONFIG_EXTRA_EXCEPTION_INFO */ /* Overwrite stacked IPSR to mark a nested exception, diff --git a/arch/arm/core/cortex_m/fpu.c b/arch/arm/core/cortex_m/fpu.c index a9c964d14d1a7..b937d725c2834 100644 --- a/arch/arm/core/cortex_m/fpu.c +++ b/arch/arm/core/cortex_m/fpu.c @@ -23,11 +23,10 @@ void z_arm_save_fp_context(struct fpu_ctx_full *buffer) if (CONTROL & CONTROL_FPCA_Msk) { /* Store caller-saved and callee-saved FP registers. */ - __asm__ volatile( - "vstmia %0, {s0-s15}\n" - "vstmia %1, {s16-s31}\n" - :: "r" (buffer->caller_saved), "r" (buffer->callee_saved) : - ); + __asm__ volatile("vstmia %0, {s0-s15}\n" + "vstmia %1, {s16-s31}\n" ::"r"(buffer->caller_saved), + "r"(buffer->callee_saved) + :); buffer->fpscr = __get_FPSCR(); buffer->ctx_saved = true; @@ -55,11 +54,10 @@ void z_arm_restore_fp_context(const struct fpu_ctx_full *buffer) /* Restore FP state. */ __set_FPSCR(buffer->fpscr); - __asm__ volatile( - "vldmia %0, {s0-s15}\n" - "vldmia %1, {s16-s31}\n" - :: "r" (buffer->caller_saved), "r" (buffer->callee_saved) : - ); + __asm__ volatile("vldmia %0, {s0-s15}\n" + "vldmia %1, {s16-s31}\n" ::"r"(buffer->caller_saved), + "r"(buffer->callee_saved) + :); } #endif } diff --git a/arch/arm/core/cortex_m/irq_manage.c b/arch/arm/core/cortex_m/irq_manage.c index cc62386e8acad..522ea4e89dd83 100644 --- a/arch/arm/core/cortex_m/irq_manage.c +++ b/arch/arm/core/cortex_m/irq_manage.c @@ -28,7 +28,7 @@ extern void z_arm_reserved(void); -#define NUM_IRQS_PER_REG 32 +#define NUM_IRQS_PER_REG 32 #define REG_FROM_IRQ(irq) (irq / NUM_IRQS_PER_REG) #define BIT_FROM_IRQ(irq) (irq % NUM_IRQS_PER_REG) @@ -87,8 +87,7 @@ void z_arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) */ __ASSERT(prio <= (BIT(NUM_IRQ_PRIO_BITS) - 1), "invalid priority %d for %d irq! values must be less than %lu\n", - prio - _IRQ_PRIO_OFFSET, irq, - BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET)); + prio - _IRQ_PRIO_OFFSET, irq, BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET)); NVIC_SetPriority((IRQn_Type)irq, prio); } @@ -141,7 +140,6 @@ void _arch_isr_direct_pm(void) #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ - } #endif @@ -165,8 +163,7 @@ void _arch_isr_direct_pm(void) * * @return The resulting target state of the given IRQ */ -irq_target_state_t irq_target_state_set(unsigned int irq, - irq_target_state_t irq_target_state) +irq_target_state_t irq_target_state_set(unsigned int irq, irq_target_state_t irq_target_state) { uint32_t result; @@ -217,7 +214,7 @@ int irq_target_state_is_secure(unsigned int irq) * - Bits corresponding to un-implemented interrupts are RES0, so writes * will be ignored. * -*/ + */ void irq_target_state_set_all_non_secure(void) { int i; @@ -241,8 +238,8 @@ void irq_target_state_set_all_non_secure(void) #ifdef CONFIG_DYNAMIC_INTERRUPTS #ifdef CONFIG_GEN_ISR_TABLES int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, - void (*routine)(const void *parameter), - const void *parameter, uint32_t flags) + void (*routine)(const void *parameter), const void *parameter, + uint32_t flags) { z_isr_install(irq, routine, parameter); z_arm_irq_priority_set(irq, priority, flags); diff --git a/arch/arm/core/cortex_m/pm_s2ram.S b/arch/arm/core/cortex_m/pm_s2ram.S index 1a4da5ce784f8..4b43fb8d74f91 100644 --- a/arch/arm/core/cortex_m/pm_s2ram.S +++ b/arch/arm/core/cortex_m/pm_s2ram.S @@ -193,6 +193,9 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend) * not successful (in r0 the return value). */ + /* Move return value of system_off to callee-saved register. */ + mov r4, r0 + /* * Reset the marking of suspend to RAM, return is ignored. */ @@ -200,7 +203,9 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_suspend) bl pm_s2ram_mark_check_and_clear mov lr, r1 - /* Move system_off back to r0 as return value */ + /* Move the stored return value of system_off back to r0, + * setting it as return value for this function. + */ mov r0, r4 POP_GPRS @@ -216,10 +221,10 @@ SECTION_FUNC(TEXT, arch_pm_s2ram_resume) bl pm_s2ram_mark_check_and_clear mov lr, r1 cmp r0, #0x1 - beq resume + beq .L_resume bx lr -resume: +.L_resume: /* * Restore the CPU context */ diff --git a/arch/arm/core/cortex_m/prep_c.c b/arch/arm/core/cortex_m/prep_c.c index 10f78c44a25ba..f6a22c3f0665f 100644 --- a/arch/arm/core/cortex_m/prep_c.c +++ b/arch/arm/core/cortex_m/prep_c.c @@ -37,17 +37,23 @@ #include #if defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) -Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) -void *_vector_table_pointer; +Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) void *_vector_table_pointer; #endif #ifdef CONFIG_CPU_CORTEX_M_HAS_VTOR #define VECTOR_ADDRESS ((uintptr_t)_vector_start) +/* In some Cortex-M3 implementations SCB_VTOR bit[29] is called the TBLBASE bit */ +#ifdef SCB_VTOR_TBLBASE_Msk +#define VTOR_MASK (SCB_VTOR_TBLBASE_Msk | SCB_VTOR_TBLOFF_Msk) +#else +#define VTOR_MASK SCB_VTOR_TBLOFF_Msk +#endif + static inline void relocate_vector_table(void) { - SCB->VTOR = VECTOR_ADDRESS & SCB_VTOR_TBLOFF_Msk; + SCB->VTOR = VECTOR_ADDRESS & VTOR_MASK; barrier_dsync_fence_full(); barrier_isync_fence_full(); } @@ -57,8 +63,8 @@ static inline void relocate_vector_table(void) void __weak relocate_vector_table(void) { -#if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ - !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) +#if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ + !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; (void)memcpy(VECTOR_ADDRESS, _vector_start, vector_size); #elif defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) @@ -93,7 +99,7 @@ static inline void z_arm_floating_point_init(void) #else /* Privileged access only */ SCB->CPACR |= CPACR_CP10_PRIV_ACCESS | CPACR_CP11_PRIV_ACCESS; -#endif /* CONFIG_USERSPACE */ +#endif /* CONFIG_USERSPACE */ /* * Upon reset, the FPU Context Control Register is 0xC0000000 * (both Automatic and Lazy state preservation is enabled). @@ -163,7 +169,7 @@ static inline void z_arm_floating_point_init(void) * * If CONFIG_INIT_ARCH_HW_AT_BOOT is set, CONTROL is cleared at reset. */ -#if (!defined(CONFIG_FPU) || !defined(CONFIG_FPU_SHARING)) && \ +#if (!defined(CONFIG_FPU) || !defined(CONFIG_FPU_SHARING)) && \ (!defined(CONFIG_INIT_ARCH_HW_AT_BOOT)) __set_CONTROL(__get_CONTROL() & (~(CONTROL_FPCA_Msk))); diff --git a/arch/arm/core/cortex_m/reset.S b/arch/arm/core/cortex_m/reset.S index bc75ccfceaaf4..742a3fe3d6500 100644 --- a/arch/arm/core/cortex_m/reset.S +++ b/arch/arm/core/cortex_m/reset.S @@ -68,13 +68,6 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,z_arm_reset) */ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) -#if defined(CONFIG_DEBUG_THREAD_INFO) - /* Clear z_sys_post_kernel flag for RTOS aware debuggers */ - movs.n r0, #0 - ldr r1, =z_sys_post_kernel - strb r0, [r1] -#endif /* CONFIG_DEBUG_THREAD_INFO */ - #if defined(CONFIG_INIT_ARCH_HW_AT_BOOT) /* Reset CONTROL register */ movs.n r0, #0 @@ -93,6 +86,18 @@ SECTION_SUBSEC_FUNC(TEXT,_reset_section,__start) bl arch_pm_s2ram_resume #endif /* CONFIG_PM_S2RAM */ + /* Note: Make sure that variables like z_sys_post_kernel + * are set after the call to arch_pm_s2ram_resume + * to avoid any issues with suspend/resume path. + * Refer issue #83660 for more details. + */ +#if defined(CONFIG_DEBUG_THREAD_INFO) + /* Clear z_sys_post_kernel flag for RTOS aware debuggers */ + movs.n r0, #0 + ldr r1, =z_sys_post_kernel + strb r0, [r1] +#endif /* CONFIG_DEBUG_THREAD_INFO */ + #if defined(CONFIG_SOC_RESET_HOOK) bl soc_reset_hook #endif diff --git a/arch/arm/core/cortex_m/scb.c b/arch/arm/core/cortex_m/scb.c index e3c35073ea310..957c66dcc9f50 100644 --- a/arch/arm/core/cortex_m/scb.c +++ b/arch/arm/core/cortex_m/scb.c @@ -23,7 +23,7 @@ #include #include -#if defined(CONFIG_CPU_HAS_NXP_MPU) +#if defined(CONFIG_CPU_HAS_NXP_SYSMPU) #include #endif @@ -55,14 +55,13 @@ void z_arm_clear_arm_mpu_config(void) { int i; - int num_regions = - ((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos); + int num_regions = ((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos); for (i = 0; i < num_regions; i++) { ARM_MPU_ClrRegion(i); } } -#elif CONFIG_CPU_HAS_NXP_MPU +#elif CONFIG_CPU_HAS_NXP_SYSMPU void z_arm_clear_arm_mpu_config(void) { int i; @@ -76,7 +75,7 @@ void z_arm_clear_arm_mpu_config(void) SYSMPU_RegionEnable(SYSMPU, i, false); } } -#endif /* CONFIG_CPU_HAS_NXP_MPU */ +#endif /* CONFIG_CPU_HAS_NXP_SYSMPU */ #endif /* CONFIG_ARM_MPU */ #if defined(CONFIG_INIT_ARCH_HW_AT_BOOT) @@ -90,7 +89,7 @@ void z_arm_clear_arm_mpu_config(void) */ void z_arm_init_arch_hw_at_boot(void) { - /* Disable interrupts */ + /* Disable interrupts */ __disable_irq(); #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) diff --git a/arch/arm/core/cortex_m/semihost.c b/arch/arm/core/cortex_m/semihost.c index 2a8c6d55a0515..dbf3e7ca94bec 100644 --- a/arch/arm/core/cortex_m/semihost.c +++ b/arch/arm/core/cortex_m/semihost.c @@ -9,11 +9,10 @@ long semihost_exec(enum semihost_instr instr, void *args) { - register unsigned int r0 __asm__ ("r0") = instr; - register void *r1 __asm__ ("r1") = args; - register int ret __asm__ ("r0"); + register unsigned int r0 __asm__("r0") = instr; + register void *r1 __asm__("r1") = args; + register int ret __asm__("r0"); - __asm__ __volatile__ ("bkpt 0xab" - : "=r" (ret) : "r" (r0), "r" (r1) : "memory"); + __asm__ __volatile__("bkpt 0xab" : "=r"(ret) : "r"(r0), "r"(r1) : "memory"); return ret; } diff --git a/arch/arm/core/cortex_m/swap.c b/arch/arm/core/cortex_m/swap.c deleted file mode 100644 index 72eade765596f..0000000000000 --- a/arch/arm/core/cortex_m/swap.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2018 Linaro, Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include - -/* The 'key' actually represents the BASEPRI register - * prior to disabling interrupts via the BASEPRI mechanism. - * - * arch_swap() itself does not do much. - * - * It simply stores the intlock key (the BASEPRI value) parameter into - * current->basepri, and then triggers a PendSV exception, which does - * the heavy lifting of context switching. - - * This is the only place we have to save BASEPRI since the other paths to - * z_arm_pendsv all come from handling an interrupt, which means we know the - * interrupts were not locked: in that case the BASEPRI value is 0. - * - * Given that arch_swap() is called to effect a cooperative context switch, - * only the caller-saved integer registers need to be saved in the thread of the - * outgoing thread. This is all performed by the hardware, which stores it in - * its exception stack frame, created when handling the z_arm_pendsv exception. - * - * On ARMv6-M, the intlock key is represented by the PRIMASK register, - * as BASEPRI is not available. - */ -int arch_swap(unsigned int key) -{ - /* store off key and return value */ - arch_current_thread()->arch.basepri = key; - arch_current_thread()->arch.swap_return_value = -EAGAIN; - - /* set pending bit to make sure we will take a PendSV exception */ - SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; - - /* clear mask or enable all irqs to take a pendsv */ - irq_unlock(0); - - /* Context switch is performed here. Returning implies the - * thread has been context-switched-in again. - */ - return arch_current_thread()->arch.swap_return_value; -} diff --git a/arch/arm/core/cortex_m/swap_helper.S b/arch/arm/core/cortex_m/swap_helper.S index 23a49cb87ef54..40f00fc005629 100644 --- a/arch/arm/core/cortex_m/swap_helper.S +++ b/arch/arm/core/cortex_m/swap_helper.S @@ -98,7 +98,7 @@ SECTION_FUNC(TEXT, z_arm_pendsv) #ifdef CONFIG_FPU_SHARING /* Assess whether switched-out thread had been using the FP registers. */ tst lr, #_EXC_RETURN_FTYPE_Msk - bne out_fp_endif + bne .L_out_fp_endif /* FP context active: set FP state and store callee-saved registers. * Note: if Lazy FP stacking is enabled, storing the callee-saved @@ -108,7 +108,7 @@ SECTION_FUNC(TEXT, z_arm_pendsv) add r0, r2, #_thread_offset_to_preempt_float vstmia r0, {s16-s31} -out_fp_endif: +.L_out_fp_endif: /* At this point FPCCR.LSPACT is guaranteed to be cleared, * regardless of whether the thread has an active FP context. */ @@ -159,9 +159,13 @@ out_fp_endif: #if defined(CONFIG_THREAD_LOCAL_STORAGE) /* Grab the TLS pointer */ +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) ldr r4, =_thread_offset_to_tls adds r4, r2, r4 ldr r0, [r4] +#else + ldr r0, [r2, #_thread_offset_to_tls] +#endif /* For Cortex-M, store TLS pointer in a global variable, * as it lacks the process ID or thread ID register @@ -204,9 +208,9 @@ out_fp_endif: * were enabled before irq_lock was called. */ cmp r0, #0 - bne _thread_irq_disabled + bne .L_thread_irq_disabled cpsie i -_thread_irq_disabled: +.L_thread_irq_disabled: #if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) /* Re-program dynamic memory map */ @@ -259,7 +263,7 @@ _thread_irq_disabled: #ifdef CONFIG_FPU_SHARING /* Assess whether switched-in thread had been using the FP registers. */ tst lr, #_EXC_RETURN_FTYPE_Msk - beq in_fp_active + beq .L_in_fp_active /* FP context inactive for swapped-in thread: * - reset FPSCR to 0 * - set EXC_RETURN.F_Type (prevents FP frame un-stacking when returning @@ -267,9 +271,9 @@ _thread_irq_disabled: */ movs.n r3, #0 vmsr fpscr, r3 - b in_fp_endif + b .L_in_fp_endif -in_fp_active: +.L_in_fp_active: /* FP context active: * - clear EXC_RETURN.F_Type * - FPSCR and caller-saved registers will be restored automatically @@ -277,7 +281,7 @@ in_fp_active: */ add r0, r2, #_thread_offset_to_preempt_float vldmia r0, {s16-s31} -in_fp_endif: +.L_in_fp_endif: /* Clear CONTROL.FPCA that may have been set by FP instructions */ mrs r3, CONTROL bic r3, #_CONTROL_FPCA_Msk @@ -288,7 +292,7 @@ in_fp_endif: #if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) /* Re-program dynamic memory map */ push {r2,lr} - mov r0, r2 /* arch_current_thread() thread */ + mov r0, r2 /* _current thread */ bl z_arm_configure_dynamic_mpu_regions pop {r2,lr} #endif @@ -361,12 +365,12 @@ SECTION_FUNC(TEXT, z_arm_svc) movs r0, #_EXC_RETURN_SPSEL_Msk mov r1, lr tst r1, r0 - beq _stack_frame_msp + beq .L_stack_frame_msp mrs r0, PSP - bne _stack_frame_endif -_stack_frame_msp: + bne .L_stack_frame_endif +.L_stack_frame_msp: mrs r0, MSP -_stack_frame_endif: +.L_stack_frame_endif: #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) tst lr, #_EXC_RETURN_SPSEL_Msk /* did we come from thread mode ? */ ite eq /* if zero (equal), came from handler mode */ @@ -399,7 +403,7 @@ _stack_frame_endif: mrs r2, CONTROL cmp r1, #3 - beq _do_syscall + beq .L_do_syscall /* * check that we are privileged before invoking other SVCs @@ -411,12 +415,12 @@ _stack_frame_endif: #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) tst r2, #0x1 #endif - bne _oops + bne .L_oops #endif /* CONFIG_USERSPACE */ cmp r1, #2 - beq _oops + beq .L_oops #if defined(CONFIG_IRQ_OFFLOAD) push {r0, lr} @@ -434,7 +438,7 @@ _stack_frame_endif: #endif -_oops: +.L_oops: push {r0, lr} #if defined(CONFIG_EXTRA_EXCEPTION_INFO) #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) @@ -484,7 +488,7 @@ _oops: * r6 - call_id * r8 - saved link register */ -_do_syscall: +.L_do_syscall: #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) movs r3, #24 ldr r1, [r0, r3] /* grab address of PC from stack frame */ @@ -510,7 +514,7 @@ _do_syscall: /* The supplied syscall_id must be lower than the limit * (Requires unsigned integer comparison) */ - blo valid_syscall_id + blo .L_valid_syscall_id /* bad syscall id. Set arg1 to bad id and set call_id to SYSCALL_BAD */ str r6, [r0] @@ -518,7 +522,7 @@ _do_syscall: /* Bad syscalls treated as valid syscalls with ID K_SYSCALL_BAD. */ -valid_syscall_id: +.L_valid_syscall_id: ldr r0, =_kernel ldr r0, [r0, #_kernel_offset_to_current] #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) diff --git a/arch/arm/core/cortex_m/thread.c b/arch/arm/core/cortex_m/thread.c index 4013b63681157..f1fc2019d9c43 100644 --- a/arch/arm/core/cortex_m/thread.c +++ b/arch/arm/core/cortex_m/thread.c @@ -22,15 +22,14 @@ #include #if (MPU_GUARD_ALIGN_AND_SIZE_FLOAT > MPU_GUARD_ALIGN_AND_SIZE) -#define FP_GUARD_EXTRA_SIZE (MPU_GUARD_ALIGN_AND_SIZE_FLOAT - \ - MPU_GUARD_ALIGN_AND_SIZE) +#define FP_GUARD_EXTRA_SIZE (MPU_GUARD_ALIGN_AND_SIZE_FLOAT - MPU_GUARD_ALIGN_AND_SIZE) #else -#define FP_GUARD_EXTRA_SIZE 0 +#define FP_GUARD_EXTRA_SIZE 0 #endif #ifndef EXC_RETURN_FTYPE /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ -#define EXC_RETURN_FTYPE (0x00000010UL) +#define EXC_RETURN_FTYPE (0x00000010UL) #endif /* Default last octet of EXC_RETURN, for threads that have not run yet. @@ -58,9 +57,8 @@ K_THREAD_STACK_DECLARE(z_main_stack, CONFIG_MAIN_STACK_SIZE); * addresses, we have to unset it manually before storing it in the 'pc' field * of the ESF. */ -void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, - char *stack_ptr, k_thread_entry_t entry, - void *p1, void *p2, void *p3) +void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, char *stack_ptr, + k_thread_entry_t entry, void *p1, void *p2, void *p3) { struct __basic_sf *iframe; @@ -105,8 +103,7 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, iframe->a3 = (uint32_t)p2; iframe->a4 = (uint32_t)p3; - iframe->xpsr = - 0x01000000UL; /* clear all, thumb bit is 1, even if RO */ + iframe->xpsr = 0x01000000UL; /* clear all, thumb bit is 1, even if RO */ thread->callee_saved.psp = (uint32_t)iframe; thread->arch.basepri = 0; @@ -131,52 +128,42 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, */ } -#if defined(CONFIG_MPU_STACK_GUARD) && defined(CONFIG_FPU) \ - && defined(CONFIG_FPU_SHARING) +#if defined(CONFIG_MPU_STACK_GUARD) && defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) -static inline void z_arm_thread_stack_info_adjust(struct k_thread *thread, - bool use_large_guard) +static inline void z_arm_thread_stack_info_adjust(struct k_thread *thread, bool use_large_guard) { if (use_large_guard) { /* Switch to use a large MPU guard if not already. */ - if ((thread->arch.mode & - Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) == 0) { + if ((thread->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) == 0) { /* Default guard size is used. Update required. */ thread->arch.mode |= Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; #if defined(CONFIG_USERSPACE) if (thread->arch.priv_stack_start) { /* User thread */ - thread->arch.priv_stack_start += - FP_GUARD_EXTRA_SIZE; + thread->arch.priv_stack_start += FP_GUARD_EXTRA_SIZE; } else #endif /* CONFIG_USERSPACE */ { /* Privileged thread */ - thread->stack_info.start += - FP_GUARD_EXTRA_SIZE; - thread->stack_info.size -= - FP_GUARD_EXTRA_SIZE; + thread->stack_info.start += FP_GUARD_EXTRA_SIZE; + thread->stack_info.size -= FP_GUARD_EXTRA_SIZE; } } } else { /* Switch to use the default MPU guard size if not already. */ - if ((thread->arch.mode & - Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { + if ((thread->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { /* Large guard size is used. Update required. */ thread->arch.mode &= ~Z_ARM_MODE_MPU_GUARD_FLOAT_Msk; #if defined(CONFIG_USERSPACE) if (thread->arch.priv_stack_start) { /* User thread */ - thread->arch.priv_stack_start -= - FP_GUARD_EXTRA_SIZE; + thread->arch.priv_stack_start -= FP_GUARD_EXTRA_SIZE; } else #endif /* CONFIG_USERSPACE */ { /* Privileged thread */ - thread->stack_info.start -= - FP_GUARD_EXTRA_SIZE; - thread->stack_info.size += - FP_GUARD_EXTRA_SIZE; + thread->stack_info.start -= FP_GUARD_EXTRA_SIZE; + thread->stack_info.size += FP_GUARD_EXTRA_SIZE; } } } @@ -190,7 +177,7 @@ static inline void z_arm_thread_stack_info_adjust(struct k_thread *thread, uint32_t z_arm_mpu_stack_guard_and_fpu_adjust(struct k_thread *thread) { if (((thread->base.user_options & K_FP_REGS) != 0) || - ((thread->arch.mode_exc_return & EXC_RETURN_FTYPE) == 0)) { + ((thread->arch.mode_exc_return & EXC_RETURN_FTYPE) == 0)) { /* The thread has been pre-tagged (at creation or later) with * K_FP_REGS, i.e. it is expected to be using the FPU registers * (if not already). Activate lazy stacking and program a large @@ -226,13 +213,11 @@ uint32_t z_arm_mpu_stack_guard_and_fpu_adjust(struct k_thread *thread) #endif #ifdef CONFIG_USERSPACE -FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, - void *p1, void *p2, void *p3) +FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3) { /* Set up privileged stack before entering user mode */ - arch_current_thread()->arch.priv_stack_start = - (uint32_t)z_priv_stack_find(arch_current_thread()->stack_obj); + _current->arch.priv_stack_start = (uint32_t)z_priv_stack_find(_current->stack_obj); #if defined(CONFIG_MPU_STACK_GUARD) #if defined(CONFIG_THREAD_STACK_INFO) /* We're dropping to user mode which means the guard area is no @@ -241,13 +226,13 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, * which accounted for memory borrowed from the thread stack. */ #if FP_GUARD_EXTRA_SIZE > 0 - if ((arch_current_thread()->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { - arch_current_thread()->stack_info.start -= FP_GUARD_EXTRA_SIZE; - arch_current_thread()->stack_info.size += FP_GUARD_EXTRA_SIZE; + if ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) { + _current->stack_info.start -= FP_GUARD_EXTRA_SIZE; + _current->stack_info.size += FP_GUARD_EXTRA_SIZE; } #endif /* FP_GUARD_EXTRA_SIZE */ - arch_current_thread()->stack_info.start -= MPU_GUARD_ALIGN_AND_SIZE; - arch_current_thread()->stack_info.size += MPU_GUARD_ALIGN_AND_SIZE; + _current->stack_info.start -= MPU_GUARD_ALIGN_AND_SIZE; + _current->stack_info.size += MPU_GUARD_ALIGN_AND_SIZE; #endif /* CONFIG_THREAD_STACK_INFO */ /* Stack guard area reserved at the bottom of the thread's @@ -255,22 +240,20 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, * buffer area accordingly. */ #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) - arch_current_thread()->arch.priv_stack_start += - ((arch_current_thread()->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? - MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; + _current->arch.priv_stack_start += + ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) + ? MPU_GUARD_ALIGN_AND_SIZE_FLOAT + : MPU_GUARD_ALIGN_AND_SIZE; #else - arch_current_thread()->arch.priv_stack_start += MPU_GUARD_ALIGN_AND_SIZE; + _current->arch.priv_stack_start += MPU_GUARD_ALIGN_AND_SIZE; #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ #endif /* CONFIG_MPU_STACK_GUARD */ - z_arm_userspace_enter(user_entry, p1, p2, p3, - (uint32_t)arch_current_thread()->stack_info.start, - arch_current_thread()->stack_info.size - - arch_current_thread()->stack_info.delta); + z_arm_userspace_enter(user_entry, p1, p2, p3, (uint32_t)_current->stack_info.start, + _current->stack_info.size - _current->stack_info.delta); CODE_UNREACHABLE; } - bool z_arm_thread_is_in_user_mode(void) { uint32_t value; @@ -311,14 +294,12 @@ void configure_builtin_stack_guard(struct k_thread *thread) * than the default thread stack (ensured by design). */ uint32_t guard_start = - ((thread->arch.priv_stack_start) && - (__get_PSP() >= thread->arch.priv_stack_start)) ? - (uint32_t)thread->arch.priv_stack_start : - (uint32_t)thread->stack_obj; + ((thread->arch.priv_stack_start) && (__get_PSP() >= thread->arch.priv_stack_start)) + ? (uint32_t)thread->arch.priv_stack_start + : (uint32_t)thread->stack_obj; __ASSERT(thread->stack_info.start == ((uint32_t)thread->stack_obj), - "stack_info.start does not point to the start of the" - "thread allocated area."); + "stack_info.start does not point to the start of the thread allocated area."); #else uint32_t guard_start = thread->stack_info.start; #endif @@ -332,13 +313,11 @@ void configure_builtin_stack_guard(struct k_thread *thread) #if defined(CONFIG_MPU_STACK_GUARD) || defined(CONFIG_USERSPACE) -#define IS_MPU_GUARD_VIOLATION(guard_start, guard_len, fault_addr, stack_ptr) \ - ((fault_addr != -EINVAL) ? \ - ((fault_addr >= guard_start) && \ - (fault_addr < (guard_start + guard_len)) && \ - (stack_ptr < (guard_start + guard_len))) \ - : \ - (stack_ptr < (guard_start + guard_len))) +#define IS_MPU_GUARD_VIOLATION(guard_start, guard_len, fault_addr, stack_ptr) \ + ((fault_addr != -EINVAL) \ + ? ((fault_addr >= guard_start) && (fault_addr < (guard_start + guard_len)) && \ + (stack_ptr < (guard_start + guard_len))) \ + : (stack_ptr < (guard_start + guard_len))) /** * @brief Assess occurrence of current thread's stack corruption @@ -379,18 +358,17 @@ void configure_builtin_stack_guard(struct k_thread *thread) uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp) { #if defined(CONFIG_MULTITHREADING) - const struct k_thread *thread = arch_current_thread(); + const struct k_thread *thread = _current; if (thread == NULL) { return 0; } #endif -#if (defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)) && \ - defined(CONFIG_MPU_STACK_GUARD) - uint32_t guard_len = - ((arch_current_thread()->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) ? - MPU_GUARD_ALIGN_AND_SIZE_FLOAT : MPU_GUARD_ALIGN_AND_SIZE; +#if (defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)) && defined(CONFIG_MPU_STACK_GUARD) + uint32_t guard_len = ((_current->arch.mode & Z_ARM_MODE_MPU_GUARD_FLOAT_Msk) != 0) + ? MPU_GUARD_ALIGN_AND_SIZE_FLOAT + : MPU_GUARD_ALIGN_AND_SIZE; #else /* If MPU_STACK_GUARD is not enabled, the guard length is * effectively zero. Stack overflows may be detected only @@ -404,10 +382,8 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp /* User thread */ if (z_arm_thread_is_in_user_mode() == false) { /* User thread in privilege mode */ - if (IS_MPU_GUARD_VIOLATION( - thread->arch.priv_stack_start - guard_len, - guard_len, - fault_addr, psp)) { + if (IS_MPU_GUARD_VIOLATION(thread->arch.priv_stack_start - guard_len, + guard_len, fault_addr, psp)) { /* Thread's privilege stack corruption */ return thread->arch.priv_stack_start; } @@ -419,26 +395,21 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp } } else { /* Supervisor thread */ - if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - - guard_len, - guard_len, - fault_addr, psp)) { + if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - guard_len, guard_len, + fault_addr, psp)) { /* Supervisor thread stack corruption */ return thread->stack_info.start; } } #else /* CONFIG_USERSPACE */ #if defined(CONFIG_MULTITHREADING) - if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - guard_len, - guard_len, - fault_addr, psp)) { + if (IS_MPU_GUARD_VIOLATION(thread->stack_info.start - guard_len, guard_len, fault_addr, + psp)) { /* Thread stack corruption */ return thread->stack_info.start; } #else - if (IS_MPU_GUARD_VIOLATION((uint32_t)z_main_stack, - guard_len, - fault_addr, psp)) { + if (IS_MPU_GUARD_VIOLATION((uint32_t)z_main_stack, guard_len, fault_addr, psp)) { /* Thread stack corruption */ return (uint32_t)K_THREAD_STACK_BUFFER(z_main_stack); } @@ -452,7 +423,7 @@ uint32_t z_check_thread_stack_fail(const uint32_t fault_addr, const uint32_t psp #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) int arch_float_disable(struct k_thread *thread) { - if (thread != arch_current_thread()) { + if (thread != _current) { return -EINVAL; } @@ -522,7 +493,7 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, { z_arm_prepare_switch_to_main(); - arch_current_thread_set(main_thread); + z_current_thread_set(main_thread); #if defined(CONFIG_THREAD_LOCAL_STORAGE) /* On Cortex-M, TLS uses a global variable as pointer to @@ -572,23 +543,23 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, * When calling arch_irq_unlock_outlined, LR is lost which is fine since * we do not intend to return after calling z_thread_entry. */ - __asm__ volatile ( - "mov r4, %0\n" /* force _main to be stored in a register */ - "msr PSP, %1\n" /* __set_PSP(stack_ptr) */ - - "mov r0, #0\n" /* arch_irq_unlock(0) */ - "ldr r3, =arch_irq_unlock_outlined\n" - "blx r3\n" - - "mov r0, r4\n" /* z_thread_entry(_main, NULL, NULL, NULL) */ - "mov r1, #0\n" - "mov r2, #0\n" - "mov r3, #0\n" - "ldr r4, =z_thread_entry\n" - "bx r4\n" /* We don’t intend to return, so there is no need to link. */ - : - : "r" (_main), "r" (stack_ptr) - : "r0", "r1", "r2", "r3", "r4", "ip", "lr", "memory"); + __asm__ volatile("mov r4, %0\n" /* force _main to be stored in a register */ + "msr PSP, %1\n" /* __set_PSP(stack_ptr) */ + + "movs r0, #0\n" /* arch_irq_unlock(0) */ + "ldr r3, =arch_irq_unlock_outlined\n" + "blx r3\n" + + "mov r0, r4\n" /* z_thread_entry(_main, NULL, NULL, NULL) */ + "movs r1, #0\n" + "movs r2, #0\n" + "movs r3, #0\n" + "ldr r4, =z_thread_entry\n" + /* We don’t intend to return, so there is no need to link. */ + "bx r4\n" + : + : "r"(_main), "r"(stack_ptr) + : "r0", "r1", "r2", "r3", "r4", "ip", "lr", "memory"); CODE_UNREACHABLE; } @@ -597,7 +568,7 @@ __used void arch_irq_unlock_outlined(unsigned int key) { #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) __enable_fault_irq(); /* alters FAULTMASK */ - __enable_irq(); /* alters PRIMASK */ + __enable_irq(); /* alters PRIMASK */ #endif arch_irq_unlock(key); } @@ -609,14 +580,13 @@ __used unsigned int arch_irq_lock_outlined(void) #if !defined(CONFIG_MULTITHREADING) -FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( - k_thread_entry_t main_entry, void *p1, void *p2, void *p3) +FUNC_NORETURN void z_arm_switch_to_main_no_multithreading(k_thread_entry_t main_entry, void *p1, + void *p2, void *p3) { z_arm_prepare_switch_to_main(); /* Set PSP to the highest address of the main stack. */ - char *psp = K_THREAD_STACK_BUFFER(z_main_stack) + - K_THREAD_STACK_SIZEOF(z_main_stack); + char *psp = K_THREAD_STACK_BUFFER(z_main_stack) + K_THREAD_STACK_SIZEOF(z_main_stack); #if defined(CONFIG_BUILTIN_STACK_GUARD) char *psplim = (K_THREAD_STACK_BUFFER(z_main_stack)); @@ -636,31 +606,31 @@ FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( * with the thread entry process. */ - __asm__ volatile ( + __asm__ volatile( #ifdef CONFIG_BUILTIN_STACK_GUARD - "msr PSPLIM, %[_psplim]\n" /* __set_PSPLIM(_psplim) */ + "msr PSPLIM, %[_psplim]\n" /* __set_PSPLIM(_psplim) */ #endif - "msr PSP, %[_psp]\n" /* __set_PSP(psp) */ - "mov r0, #0\n" - "ldr r1, =arch_irq_unlock_outlined\n" - "blx r1\n" - - "mov r0, %[_p1]\n" - "mov r1, %[_p2]\n" - "mov r2, %[_p3]\n" - "blx %[_main_entry]\n" /* main_entry(p1, p2, p3) */ - - "ldr r0, =arch_irq_lock_outlined\n" - "blx r0\n" - "loop: b loop\n\t" /* while (true); */ - : - : [_p1]"r" (p1), [_p2]"r" (p2), [_p3]"r" (p3), - [_psp]"r" (psp), [_main_entry]"r" (main_entry) + "msr PSP, %[_psp]\n" /* __set_PSP(psp) */ + "movs r0, #0\n" + "ldr r1, =arch_irq_unlock_outlined\n" + "blx r1\n" + + "mov r0, %[_p1]\n" + "mov r1, %[_p2]\n" + "mov r2, %[_p3]\n" + "blx %[_main_entry]\n" /* main_entry(p1, p2, p3) */ + + "ldr r0, =arch_irq_lock_outlined\n" + "blx r0\n" + "loop: b loop\n\t" /* while (true); */ + : + : [_p1] "r"(p1), [_p2] "r"(p2), [_p3] "r"(p3), [_psp] "r"(psp), + [_main_entry] "r"(main_entry) #ifdef CONFIG_BUILTIN_STACK_GUARD - , [_psplim]"r" (psplim) + , + [_psplim] "r"(psplim) #endif - : "r0", "r1", "r2", "ip", "lr" - ); + : "r0", "r1", "r2", "ip", "lr"); CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ } diff --git a/arch/arm/core/cortex_m/thread_abort.c b/arch/arm/core/cortex_m/thread_abort.c index 235adeab0b9eb..99af867110705 100644 --- a/arch/arm/core/cortex_m/thread_abort.c +++ b/arch/arm/core/cortex_m/thread_abort.c @@ -27,7 +27,7 @@ void z_impl_k_thread_abort(k_tid_t thread) { SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_thread, abort, thread); - if (arch_current_thread() == thread) { + if (_current == thread) { if (arch_is_in_isr()) { /* ARM is unlike most arches in that this is true * even for non-peripheral interrupts, even though diff --git a/arch/arm/core/cortex_m/timing.c b/arch/arm/core/cortex_m/timing.c index 6cb157552ace2..2ce7f64552ba5 100644 --- a/arch/arm/core/cortex_m/timing.c +++ b/arch/arm/core/cortex_m/timing.c @@ -73,7 +73,6 @@ static inline uint64_t z_arm_dwt_freq_get(void) } while ((dcyc == 0) || (ddwt == 0)); dwt_frequency = (cyc_freq * ddwt) / dcyc; - } return dwt_frequency; #endif /* CONFIG_SOC_FAMILY_NORDIC_NRF */ @@ -100,8 +99,7 @@ timing_t arch_timing_counter_get(void) return (timing_t)z_arm_dwt_get_cycles(); } -uint64_t arch_timing_cycles_get(volatile timing_t *const start, - volatile timing_t *const end) +uint64_t arch_timing_cycles_get(volatile timing_t *const start, volatile timing_t *const end) { return ((uint32_t)*end - (uint32_t)*start); } diff --git a/arch/arm/core/cortex_m/tz/CMakeLists.txt b/arch/arm/core/cortex_m/tz/CMakeLists.txt index 19c67476e40ee..aac4f65161941 100644 --- a/arch/arm/core/cortex_m/tz/CMakeLists.txt +++ b/arch/arm/core/cortex_m/tz/CMakeLists.txt @@ -2,7 +2,10 @@ # '-mcmse' enables the generation of code for the Secure state of the ARMv8-M # Security Extensions. This option is required when building a Secure firmware. -zephyr_compile_options_ifdef(CONFIG_ARM_SECURE_FIRMWARE -mcmse) + +zephyr_compile_options_ifdef(CONFIG_ARM_SECURE_FIRMWARE $<$:$>) +zephyr_compile_options_ifdef(CONFIG_ARM_SECURE_FIRMWARE $<$:$>) +zephyr_compile_options_ifdef(CONFIG_ARM_SECURE_FIRMWARE $<$:$>) if(CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS) diff --git a/arch/arm/core/mmu/arm_mmu.c b/arch/arm/core/mmu/arm_mmu.c index f37b4354d4660..4b398eb2d16e8 100644 --- a/arch/arm/core/mmu/arm_mmu.c +++ b/arch/arm/core/mmu/arm_mmu.c @@ -304,13 +304,15 @@ static struct arm_mmu_perms_attrs arm_mmu_convert_attr_flags(uint32_t attrs) perms_attrs.cacheable = 0; perms_attrs.domain = ARM_MMU_DOMAIN_DEVICE; - if (attrs & MATTR_SHARED) { - perms_attrs.tex = 0; - perms_attrs.bufferable = 1; - } else { - perms_attrs.tex = 2; - perms_attrs.bufferable = 0; - } + /* + * ARM deprecates the marking of Device memory with a + * shareability attribute other than Outer Shareable + * or Shareable. This means ARM strongly recommends + * that Device memory is never assigned a shareability + * attribute of Non-shareable or Inner Shareable. + */ + perms_attrs.tex = 0; + perms_attrs.bufferable = 1; } else if (attrs & MT_NORMAL) { /* * TEX[2] is always 1. TEX[1:0] contain the outer cache attri- diff --git a/arch/arm/core/mpu/CMakeLists.txt b/arch/arm/core/mpu/CMakeLists.txt index 1df6561ee528d..69f23e5be88d2 100644 --- a/arch/arm/core/mpu/CMakeLists.txt +++ b/arch/arm/core/mpu/CMakeLists.txt @@ -4,11 +4,11 @@ zephyr_library() zephyr_library_sources( arm_core_mpu.c) zephyr_library_sources_ifdef(CONFIG_CPU_HAS_ARM_MPU arm_mpu.c) -zephyr_library_sources_ifdef(CONFIG_CPU_HAS_NXP_MPU nxp_mpu.c) +zephyr_library_sources_ifdef(CONFIG_CPU_HAS_NXP_SYSMPU nxp_mpu.c) if(CONFIG_CPU_CORTEX_M AND NOT CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS) zephyr_library_sources_ifdef(CONFIG_CPU_HAS_ARM_MPU arm_mpu_regions.c) - zephyr_library_sources_ifdef(CONFIG_CPU_HAS_NXP_MPU nxp_mpu_regions.c) + zephyr_library_sources_ifdef(CONFIG_CPU_HAS_NXP_SYSMPU nxp_mpu_regions.c) endif() if (CONFIG_CPU_AARCH32_CORTEX_R) diff --git a/arch/arm/core/mpu/Kconfig b/arch/arm/core/mpu/Kconfig index c6d1bdc7da05a..67baee979c9bd 100644 --- a/arch/arm/core/mpu/Kconfig +++ b/arch/arm/core/mpu/Kconfig @@ -5,50 +5,10 @@ if CPU_HAS_MPU -config ARM_MPU - bool "ARM MPU Support" - select MPU - select SRAM_REGION_PERMISSIONS - select THREAD_STACK_INFO - select ARCH_HAS_EXECUTABLE_PAGE_BIT - select MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT if !(CPU_HAS_NXP_MPU || ARMV8_M_BASELINE || ARMV8_M_MAINLINE || AARCH32_ARMV8_R) - select MPU_REQUIRES_NON_OVERLAPPING_REGIONS if CPU_HAS_ARM_MPU && (ARMV8_M_BASELINE || ARMV8_M_MAINLINE || AARCH32_ARMV8_R) - select MPU_GAP_FILLING if AARCH32_ARMV8_R - select ARCH_MEM_DOMAIN_SUPPORTS_ISOLATED_STACKS - select MEM_DOMAIN_ISOLATED_STACKS - help - MCU implements Memory Protection Unit. - - Notes: - The ARMv6-M and ARMv7-M MPU architecture requires a power-of-two - alignment of MPU region base address and size. - - The NXP MPU as well as the ARMv8-M MPU do not require MPU regions - to have power-of-two alignment for base address and region size. - - The ARMv8-M MPU requires the active MPU regions be non-overlapping. - As a result of this, the ARMv8-M MPU needs to fully partition the - memory map when programming dynamic memory regions (e.g. PRIV stack - guard, user thread stack, and application memory domains), if the - system requires PRIV access policy different from the access policy - of the ARMv8-M background memory map. The application developer may - enforce full PRIV (kernel) memory partition by enabling the - CONFIG_MPU_GAP_FILLING option. - By not enforcing full partition, MPU may leave part of kernel - SRAM area covered only by the default ARMv8-M memory map. This - is fine for User Mode, since the background ARM map does not - allow nPRIV access at all. However, since the background map - policy allows instruction fetches by privileged code, forcing - this Kconfig option off prevents the system from directly - triggering MemManage exceptions upon accidental attempts to - execute code from SRAM in XIP builds. - Since this does not compromise User Mode, we make the skipping - of full partitioning the default behavior for the ARMv8-M MPU - driver. - config ARM_MPU_REGION_MIN_ALIGN_AND_SIZE int default 256 if ARM_MPU && ARMV6_M_ARMV8_M_BASELINE && !ARMV8_M_BASELINE + default 128 if ARM_MPU && FPU_SHARING && MPU_STACK_GUARD default 64 if ARM_MPU && AARCH32_ARMV8_R default 32 if ARM_MPU default 4 diff --git a/arch/arm/core/mpu/arm_core_mpu_dev.h b/arch/arm/core/mpu/arm_core_mpu_dev.h index 254d6d9dda341..4e8fa648ad341 100644 --- a/arch/arm/core/mpu/arm_core_mpu_dev.h +++ b/arch/arm/core/mpu/arm_core_mpu_dev.h @@ -76,7 +76,7 @@ struct k_thread; */ #if (defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS) && \ defined(CONFIG_MPU_GAP_FILLING)) \ - || defined(CONFIG_CPU_HAS_NXP_MPU) + || defined(CONFIG_CPU_HAS_NXP_SYSMPU) /* * When dynamic regions may not be defined on top of statically * allocated memory regions, defining a region for a supervisor @@ -96,7 +96,7 @@ struct k_thread; * using a single MPU region. */ #define ARM_CORE_MPU_NUM_MPU_REGIONS_FOR_MPU_STACK_GUARD 1 -#endif /* CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS || CPU_HAS_NXP_MPU */ +#endif /* CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS || CPU_HAS_NXP_SYSMPU */ #endif /* CONFIG_USERSPACE */ diff --git a/arch/arm/core/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c index f121e57e39224..e66c02ec067fb 100644 --- a/arch/arm/core/mpu/arm_mpu.c +++ b/arch/arm/core/mpu/arm_mpu.c @@ -42,7 +42,8 @@ BUILD_ASSERT((DT_FOREACH_STATUS_OKAY_NODE_VARGS( (DT_REG_SIZE(node_id) >= CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE)) || #define DT_NULL_PAGE_DETECT_NODE_EXIST \ - (DT_FOREACH_STATUS_OKAY_NODE_VARGS(NULL_PAGE_DETECT_NODE_FINDER, zephyr_memory_attr) false) + (DT_FOREACH_STATUS_OKAY_VARGS(zephyr_memory_region, NULL_PAGE_DETECT_NODE_FINDER, \ + zephyr_memory_attr) false) /* * Global status variable holding the number of HW MPU region indices, which @@ -92,7 +93,7 @@ static int region_allocate_and_init(const uint8_t index, (reg).dt_addr, \ (reg).dt_size, \ _ATTR) - +#ifdef CONFIG_MEM_ATTR /* This internal function programs the MPU regions defined in the DT when using * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. */ @@ -157,7 +158,7 @@ static int mpu_configure_regions_from_dt(uint8_t *reg_index) return 0; } - +#endif /* CONFIG_MEM_ATTR */ /* This internal function programs an MPU region * of a given configuration at a given MPU index. */ @@ -458,13 +459,13 @@ int z_arm_mpu_init(void) /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; - +#ifdef CONFIG_MEM_ATTR /* DT-defined MPU regions. */ if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { __ASSERT(0, "Failed to allocate MPU regions from DT\n"); return -EINVAL; } - +#endif /* CONFIG_MEM_ATTR */ /* Clear all regions before enabling MPU */ for (int i = static_regions_num; i < get_num_regions(); i++) { mpu_clear_region(i); diff --git a/arch/arm/core/mpu/arm_mpu_regions.c b/arch/arm/core/mpu/arm_mpu_regions.c index 6af62f840782f..0bf7a219c27d7 100644 --- a/arch/arm/core/mpu/arm_mpu_regions.c +++ b/arch/arm/core/mpu/arm_mpu_regions.c @@ -10,6 +10,7 @@ #include static const struct arm_mpu_region mpu_regions[] = { +#ifdef CONFIG_XIP /* Region 0 */ MPU_REGION_ENTRY("FLASH_0", CONFIG_FLASH_BASE_ADDRESS, @@ -19,6 +20,8 @@ static const struct arm_mpu_region mpu_regions[] = { #else REGION_FLASH_ATTR(REGION_FLASH_SIZE)), #endif +#endif + /* Region 1 */ MPU_REGION_ENTRY("SRAM_0", CONFIG_SRAM_BASE_ADDRESS, diff --git a/arch/arm/core/mpu/nxp_mpu.c b/arch/arm/core/mpu/nxp_mpu.c index b0fe24c6bf617..ae893086901ce 100644 --- a/arch/arm/core/mpu/nxp_mpu.c +++ b/arch/arm/core/mpu/nxp_mpu.c @@ -151,7 +151,7 @@ static int region_allocate_and_init(const uint8_t index, .end = (reg).dt_addr + (reg).dt_size, \ .attr = _ATTR, \ } - +#ifdef CONFIG_MEM_ATTR /* This internal function programs the MPU regions defined in the DT when using * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. */ @@ -198,7 +198,7 @@ static int mpu_configure_regions_from_dt(uint8_t *reg_index) return 0; } - +#endif /* CONFIG_MEM_ATTR */ /** * This internal function is utilized by the MPU driver to combine a given * region attribute configuration and size and fill-in a driver-specific @@ -700,13 +700,13 @@ int z_arm_mpu_init(void) /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; - +#ifdef CONFIG_MEM_ATTR /* DT-defined MPU regions. */ if (mpu_configure_regions_from_dt(&static_regions_num) == -EINVAL) { __ASSERT(0, "Failed to allocate MPU regions from DT\n"); return -EINVAL; } - +#endif /* CONFIG_MEM_ATTR */ arm_core_mpu_enable(); return 0; diff --git a/arch/arm/core/tls.c b/arch/arm/core/tls.c index 9b731286c7da8..0dc21285a916d 100644 --- a/arch/arm/core/tls.c +++ b/arch/arm/core/tls.c @@ -40,8 +40,10 @@ size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) stack_ptr -= z_tls_data_size(); z_tls_copy(stack_ptr); +#ifndef __IAR_SYSTEMS_ICC__ /* Skip two pointers due to toolchain */ stack_ptr -= sizeof(uintptr_t) * 2; +#endif /* * Set thread TLS pointer which is used in diff --git a/arch/arm/include/cortex_a_r/kernel_arch_func.h b/arch/arm/include/cortex_a_r/kernel_arch_func.h index ecd467f3c91eb..7a100db07ddb1 100644 --- a/arch/arm/include/cortex_a_r/kernel_arch_func.h +++ b/arch/arm/include/cortex_a_r/kernel_arch_func.h @@ -37,6 +37,21 @@ static ALWAYS_INLINE void arch_kernel_init(void) #ifndef CONFIG_USE_SWITCH +static ALWAYS_INLINE int arch_swap(unsigned int key) +{ + /* store off key and return value */ + _current->arch.basepri = key; + _current->arch.swap_return_value = -EAGAIN; + + z_arm_cortex_r_svc(); + irq_unlock(key); + + /* Context switch is performed here. Returning implies the + * thread has been context-switched-in again. + */ + return _current->arch.swap_return_value; +} + static ALWAYS_INLINE void arch_thread_return_value_set(struct k_thread *thread, unsigned int value) { diff --git a/arch/arm/include/cortex_m/cmse.h b/arch/arm/include/cortex_m/cmse.h index ff5e5120d8d39..ca997220dbd16 100644 --- a/arch/arm/include/cortex_m/cmse.h +++ b/arch/arm/include/cortex_m/cmse.h @@ -139,7 +139,7 @@ int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npr * where typeof is used instead of __typeof__) */ #ifndef typeof -#define typeof __typeof__ +#define typeof __typeof__ #endif /** @@ -157,8 +157,7 @@ int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npr * * @return p_obj if object is readable, NULL otherwise. */ -#define ARM_CMSE_OBJECT_READ_OK(p_obj) \ - cmse_check_pointed_object(p_obj, CMSE_MPU_READ) +#define ARM_CMSE_OBJECT_READ_OK(p_obj) cmse_check_pointed_object(p_obj, CMSE_MPU_READ) /** * @brief Read accessibility of an object (nPRIV mode) @@ -175,7 +174,7 @@ int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npr * * @return p_obj if object is readable, NULL otherwise. */ -#define ARM_CMSE_OBJECT_UNPRIV_READ_OK(p_obj) \ +#define ARM_CMSE_OBJECT_UNPRIV_READ_OK(p_obj) \ cmse_check_pointed_object(p_obj, CMSE_MPU_UNPRIV | CMSE_MPU_READ) /** @@ -193,8 +192,7 @@ int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npr * * @return p_obj if object is Read and Writable, NULL otherwise. */ -#define ARM_CMSE_OBJECT_READWRITE_OK(p_obj) \ - cmse_check_pointed_object(p_obj, CMSE_MPU_READWRITE) +#define ARM_CMSE_OBJECT_READWRITE_OK(p_obj) cmse_check_pointed_object(p_obj, CMSE_MPU_READWRITE) /** * @brief Read and Write accessibility of an object (nPRIV mode) @@ -211,7 +209,7 @@ int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npr * * @return p_obj if object is Read and Writable, NULL otherwise. */ -#define ARM_CMSE_OBJECT_UNPRIV_READWRITE_OK(p_obj) \ +#define ARM_CMSE_OBJECT_UNPRIV_READWRITE_OK(p_obj) \ cmse_check_pointed_object(p_obj, CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE) #if defined(CONFIG_ARM_SECURE_FIRMWARE) @@ -231,7 +229,7 @@ int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npr * @param addr The address for which the MPU region is requested * * @return a valid MPU region number or -EINVAL - */ + */ int arm_cmse_mpu_nonsecure_region_get(uint32_t addr); /** @@ -249,7 +247,7 @@ int arm_cmse_mpu_nonsecure_region_get(uint32_t addr); * @param addr The address for which the SAU region is requested * * @return a valid SAU region number or -EINVAL - */ + */ int arm_cmse_sau_region_get(uint32_t addr); /** @@ -267,7 +265,7 @@ int arm_cmse_sau_region_get(uint32_t addr); * @param addr The address for which the IDAU region is requested * * @return a valid IDAU region number or -EINVAL - */ + */ int arm_cmse_idau_region_get(uint32_t addr); /** @@ -342,8 +340,7 @@ int arm_cmse_addr_nonsecure_readwrite_ok(uint32_t addr, int force_npriv); * * @return 1 if address range is readable, 0 otherwise. */ -int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, - int force_npriv); +int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, int force_npriv); /** * @brief Non-Secure Read and Write accessibility of an address range @@ -365,8 +362,7 @@ int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, * * @return 1 if address range is readable, 0 otherwise. */ -int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, - int force_npriv); +int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv); /** * @brief Non-Secure Read accessibility of an object @@ -383,7 +379,7 @@ int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, * * @return p_obj if object is readable from Non-Secure state, NULL otherwise. */ -#define ARM_CMSE_OBJECT_NONSECURE_READ_OK(p_obj) \ +#define ARM_CMSE_OBJECT_NONSECURE_READ_OK(p_obj) \ cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_READ) /** @@ -401,9 +397,8 @@ int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, * * @return p_obj if object is readable from Non-Secure state, NULL otherwise. */ -#define ARM_CMSE_OBJECT_NONSECURE_UNPRIV_READ_OK(p_obj) \ - cmse_check_pointed_object(p_obj, \ - CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READ) +#define ARM_CMSE_OBJECT_NONSECURE_UNPRIV_READ_OK(p_obj) \ + cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READ) /** * @brief Non-Secure Read and Write accessibility of an object @@ -420,7 +415,7 @@ int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, * * @return p_obj if object is Non-Secure Read and Writable, NULL otherwise. */ -#define ARM_CMSE_OBJECT_NONSECURE_READWRITE_OK(p_obj) \ +#define ARM_CMSE_OBJECT_NONSECURE_READWRITE_OK(p_obj) \ cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_READWRITE) /** @@ -438,9 +433,8 @@ int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, * * @return p_obj if object is Non-Secure Read and Writable, NULL otherwise. */ -#define ARM_CMSE_OBJECT_NON_SECURE_UNPRIV_READWRITE_OK(p_obj) \ - cmse_check_pointed_object(p_obj, \ - CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE) +#define ARM_CMSE_OBJECT_NON_SECURE_UNPRIV_READWRITE_OK(p_obj) \ + cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE) #endif /* CONFIG_ARM_SECURE_FIRMWARE */ diff --git a/arch/arm/include/cortex_m/dwt.h b/arch/arm/include/cortex_m/dwt.h index ed0df44dfde56..947b35dca92e8 100644 --- a/arch/arm/include/cortex_m/dwt.h +++ b/arch/arm/include/cortex_m/dwt.h @@ -64,7 +64,7 @@ static inline void dwt_access(bool ena) } } } -#else /* CONFIG_CPU_CORTEX_M7 */ +#else /* CONFIG_CPU_CORTEX_M7 */ ARG_UNUSED(ena); #endif /* CONFIG_CPU_CORTEX_M7 */ } @@ -103,9 +103,8 @@ static inline int z_arm_dwt_init_cycle_counter(void) /* Assert that the cycle counter is indeed implemented. * The field is called NOCYCCNT. So 1 means there is no cycle counter. */ - __ASSERT((DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk) == 0, - "DWT implements no cycle counter. " - "Cannot be used for cycle counting\n"); + __ASSERT((DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk) == 0, "DWT implements no cycle counter. " + "Cannot be used for cycle counting\n"); return 0; } @@ -148,7 +147,7 @@ static inline void z_arm_dwt_enable_debug_monitor(void) * assert that the CPU is in normal mode. */ __ASSERT((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) == 0, - "Cannot enable DBM when CPU is in Debug mode\n"); + "Cannot enable DBM when CPU is in Debug mode\n"); #if defined(CONFIG_ARMV8_M_SE) && !defined(CONFIG_ARM_NONSECURE_FIRMWARE) /* @@ -158,8 +157,7 @@ static inline void z_arm_dwt_enable_debug_monitor(void) * when enabling the DebugMonitor exception, assert that * it is not targeting the Non Secure domain. */ - __ASSERT((CoreDebug->DEMCR & DCB_DEMCR_SDME_Msk) != 0, - "DebugMonitor targets Non-Secure\n"); + __ASSERT((CoreDebug->DEMCR & DCB_DEMCR_SDME_Msk) != 0, "DebugMonitor targets Non-Secure\n"); #endif /* The DebugMonitor handler priority is set already diff --git a/arch/arm/include/cortex_m/exception.h b/arch/arm/include/cortex_m/exception.h index c021d59d76411..0800a16436f16 100644 --- a/arch/arm/include/cortex_m/exception.h +++ b/arch/arm/include/cortex_m/exception.h @@ -37,7 +37,7 @@ extern volatile irq_offload_routine_t offload_routine; /* Writes to the AIRCR must be accompanied by a write of the value 0x05FA * to the Vector Key field, otherwise the writes are ignored. */ -#define AIRCR_VECT_KEY_PERMIT_WRITE 0x05FAUL +#define AIRCR_VECT_KEY_PERMIT_WRITE 0x05FAUL /* Exception Return (EXC_RETURN) is provided in LR upon exception entry. * It is used to perform an exception return and to detect possible state @@ -47,45 +47,44 @@ extern volatile irq_offload_routine_t offload_routine; /* Prefix. Indicates that this is an EXC_RETURN value. * This field reads as 0b11111111. */ -#define EXC_RETURN_INDICATOR_PREFIX (0xFF << 24) +#define EXC_RETURN_INDICATOR_PREFIX (0xFF << 24) /* bit[0]: Exception Secure. The security domain the exception was taken to. */ -#define EXC_RETURN_EXCEPTION_SECURE_Pos 0 -#define EXC_RETURN_EXCEPTION_SECURE_Msk \ - BIT(EXC_RETURN_EXCEPTION_SECURE_Pos) +#define EXC_RETURN_EXCEPTION_SECURE_Pos 0 +#define EXC_RETURN_EXCEPTION_SECURE_Msk BIT(EXC_RETURN_EXCEPTION_SECURE_Pos) #define EXC_RETURN_EXCEPTION_SECURE_Non_Secure 0 -#define EXC_RETURN_EXCEPTION_SECURE_Secure EXC_RETURN_EXCEPTION_SECURE_Msk +#define EXC_RETURN_EXCEPTION_SECURE_Secure EXC_RETURN_EXCEPTION_SECURE_Msk /* bit[2]: Stack Pointer selection. */ -#define EXC_RETURN_SPSEL_Pos 2 -#define EXC_RETURN_SPSEL_Msk BIT(EXC_RETURN_SPSEL_Pos) -#define EXC_RETURN_SPSEL_MAIN 0 -#define EXC_RETURN_SPSEL_PROCESS EXC_RETURN_SPSEL_Msk +#define EXC_RETURN_SPSEL_Pos 2 +#define EXC_RETURN_SPSEL_Msk BIT(EXC_RETURN_SPSEL_Pos) +#define EXC_RETURN_SPSEL_MAIN 0 +#define EXC_RETURN_SPSEL_PROCESS EXC_RETURN_SPSEL_Msk /* bit[3]: Mode. Indicates the Mode that was stacked from. */ -#define EXC_RETURN_MODE_Pos 3 -#define EXC_RETURN_MODE_Msk BIT(EXC_RETURN_MODE_Pos) -#define EXC_RETURN_MODE_HANDLER 0 -#define EXC_RETURN_MODE_THREAD EXC_RETURN_MODE_Msk +#define EXC_RETURN_MODE_Pos 3 +#define EXC_RETURN_MODE_Msk BIT(EXC_RETURN_MODE_Pos) +#define EXC_RETURN_MODE_HANDLER 0 +#define EXC_RETURN_MODE_THREAD EXC_RETURN_MODE_Msk /* bit[4]: Stack frame type. Indicates whether the stack frame is a standard * integer only stack frame or an extended floating-point stack frame. */ -#define EXC_RETURN_STACK_FRAME_TYPE_Pos 4 -#define EXC_RETURN_STACK_FRAME_TYPE_Msk BIT(EXC_RETURN_STACK_FRAME_TYPE_Pos) -#define EXC_RETURN_STACK_FRAME_TYPE_EXTENDED 0 -#define EXC_RETURN_STACK_FRAME_TYPE_STANDARD EXC_RETURN_STACK_FRAME_TYPE_Msk +#define EXC_RETURN_STACK_FRAME_TYPE_Pos 4 +#define EXC_RETURN_STACK_FRAME_TYPE_Msk BIT(EXC_RETURN_STACK_FRAME_TYPE_Pos) +#define EXC_RETURN_STACK_FRAME_TYPE_EXTENDED 0 +#define EXC_RETURN_STACK_FRAME_TYPE_STANDARD EXC_RETURN_STACK_FRAME_TYPE_Msk /* bit[5]: Default callee register stacking. Indicates whether the default * stacking rules apply, or whether the callee registers are already on the * stack. */ -#define EXC_RETURN_CALLEE_STACK_Pos 5 -#define EXC_RETURN_CALLEE_STACK_Msk BIT(EXC_RETURN_CALLEE_STACK_Pos) -#define EXC_RETURN_CALLEE_STACK_SKIPPED 0 -#define EXC_RETURN_CALLEE_STACK_DEFAULT EXC_RETURN_CALLEE_STACK_Msk +#define EXC_RETURN_CALLEE_STACK_Pos 5 +#define EXC_RETURN_CALLEE_STACK_Msk BIT(EXC_RETURN_CALLEE_STACK_Pos) +#define EXC_RETURN_CALLEE_STACK_SKIPPED 0 +#define EXC_RETURN_CALLEE_STACK_DEFAULT EXC_RETURN_CALLEE_STACK_Msk /* bit[6]: Secure or Non-secure stack. Indicates whether a Secure or * Non-secure stack is used to restore stack frame on exception return. */ -#define EXC_RETURN_RETURN_STACK_Pos 6 -#define EXC_RETURN_RETURN_STACK_Msk BIT(EXC_RETURN_RETURN_STACK_Pos) -#define EXC_RETURN_RETURN_STACK_Non_Secure 0 -#define EXC_RETURN_RETURN_STACK_Secure EXC_RETURN_RETURN_STACK_Msk +#define EXC_RETURN_RETURN_STACK_Pos 6 +#define EXC_RETURN_RETURN_STACK_Msk BIT(EXC_RETURN_RETURN_STACK_Pos) +#define EXC_RETURN_RETURN_STACK_Non_Secure 0 +#define EXC_RETURN_RETURN_STACK_Secure EXC_RETURN_RETURN_STACK_Msk /* * The current executing vector is found in the IPSR register. All @@ -170,8 +169,8 @@ static ALWAYS_INLINE void z_arm_exc_setup(void) #endif /* CONFIG_ARM_SECURE_FIRMWARE */ /* Enable Usage, Mem, & Bus Faults */ - SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk | - SCB_SHCSR_BUSFAULTENA_Msk; + SCB->SHCSR |= + SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk; #if defined(CONFIG_ARM_SECURE_FIRMWARE) /* Enable Secure Fault */ SCB->SHCSR |= SCB_SHCSR_SECUREFAULTENA_Msk; @@ -180,25 +179,21 @@ static ALWAYS_INLINE void z_arm_exc_setup(void) #endif /* CONFIG_ARM_SECURE_FIRMWARE */ #endif /* CONFIG_CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS */ -#if defined(CONFIG_ARM_SECURE_FIRMWARE) && \ - !defined(CONFIG_ARM_SECURE_BUSFAULT_HARDFAULT_NMI) +#if defined(CONFIG_ARM_SECURE_FIRMWARE) && !defined(CONFIG_ARM_SECURE_BUSFAULT_HARDFAULT_NMI) /* Set NMI, Hard, and Bus Faults as Non-Secure. * NMI and Bus Faults targeting the Secure state will * escalate to a SecureFault or SecureHardFault. */ SCB->AIRCR = - (SCB->AIRCR & (~(SCB_AIRCR_VECTKEY_Msk))) - | SCB_AIRCR_BFHFNMINS_Msk - | ((AIRCR_VECT_KEY_PERMIT_WRITE << SCB_AIRCR_VECTKEY_Pos) & - SCB_AIRCR_VECTKEY_Msk); + (SCB->AIRCR & (~(SCB_AIRCR_VECTKEY_Msk))) | SCB_AIRCR_BFHFNMINS_Msk | + ((AIRCR_VECT_KEY_PERMIT_WRITE << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk); /* Note: Fault conditions that would generate a SecureFault * in a PE with the Main Extension instead generate a * SecureHardFault in a PE without the Main Extension. */ #endif /* ARM_SECURE_FIRMWARE && !ARM_SECURE_BUSFAULT_HARDFAULT_NMI */ -#if defined(CONFIG_CPU_CORTEX_M_HAS_SYSTICK) && \ - !defined(CONFIG_CORTEX_M_SYSTICK) +#if defined(CONFIG_CPU_CORTEX_M_HAS_SYSTICK) && !defined(CONFIG_CORTEX_M_SYSTICK) /* SoC implements SysTick, but the system does not use it * as driver for system timing. However, the SysTick IRQ is * always enabled, so we must ensure the interrupt priority @@ -208,7 +203,6 @@ static ALWAYS_INLINE void z_arm_exc_setup(void) */ NVIC_SetPriority(SysTick_IRQn, _EXC_IRQ_DEFAULT_PRIO); #endif /* CPU_CORTEX_M_HAS_SYSTICK && ! CORTEX_M_SYSTICK */ - } /** @@ -221,9 +215,7 @@ static ALWAYS_INLINE void z_arm_clear_faults(void) #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) /* Reset all faults */ - SCB->CFSR = SCB_CFSR_USGFAULTSR_Msk | - SCB_CFSR_MEMFAULTSR_Msk | - SCB_CFSR_BUSFAULTSR_Msk; + SCB->CFSR = SCB_CFSR_USGFAULTSR_Msk | SCB_CFSR_MEMFAULTSR_Msk | SCB_CFSR_BUSFAULTSR_Msk; /* Clear all Hard Faults - HFSR is write-one-to-clear */ SCB->HFSR = 0xffffffff; @@ -253,7 +245,7 @@ static ALWAYS_INLINE void z_arm_set_fault_sp(const struct arch_esf *esf, uint32_ * registers if necessary */ if ((exc_return & EXC_RETURN_STACK_FRAME_TYPE_STANDARD) == - EXC_RETURN_STACK_FRAME_TYPE_EXTENDED) { + EXC_RETURN_STACK_FRAME_TYPE_EXTENDED) { z_arm_coredump_fault_sp += sizeof(esf->fpu); } #endif /* CONFIG_FPU && CONFIG_FPU_SHARING */ diff --git a/arch/arm/include/cortex_m/kernel_arch_func.h b/arch/arm/include/cortex_m/kernel_arch_func.h index bb79e3941066d..5abe5870762cf 100644 --- a/arch/arm/include/cortex_m/kernel_arch_func.h +++ b/arch/arm/include/cortex_m/kernel_arch_func.h @@ -61,29 +61,42 @@ static ALWAYS_INLINE void arch_kernel_init(void) #endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } -static ALWAYS_INLINE void -arch_thread_return_value_set(struct k_thread *thread, unsigned int value) +static ALWAYS_INLINE void arch_thread_return_value_set(struct k_thread *thread, unsigned int value) { thread->arch.swap_return_value = value; } #if !defined(CONFIG_MULTITHREADING) -extern FUNC_NORETURN void z_arm_switch_to_main_no_multithreading( - k_thread_entry_t main_func, - void *p1, void *p2, void *p3); +extern FUNC_NORETURN void z_arm_switch_to_main_no_multithreading(k_thread_entry_t main_func, + void *p1, void *p2, void *p3); -#define ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING \ - z_arm_switch_to_main_no_multithreading +#define ARCH_SWITCH_TO_MAIN_NO_MULTITHREADING z_arm_switch_to_main_no_multithreading #endif /* !CONFIG_MULTITHREADING */ -extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, - void *p1, void *p2, void *p3, - uint32_t stack_end, - uint32_t stack_start); +extern FUNC_NORETURN void z_arm_userspace_enter(k_thread_entry_t user_entry, void *p1, void *p2, + void *p3, uint32_t stack_end, uint32_t stack_start); extern void z_arm_fatal_error(unsigned int reason, const struct arch_esf *esf); +static ALWAYS_INLINE int arch_swap(unsigned int key) +{ + /* store off key and return value */ + _current->arch.basepri = key; + _current->arch.swap_return_value = -EAGAIN; + + /* set pending bit to make sure we will take a PendSV exception */ + SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; + + /* clear mask or enable all irqs to take a pendsv */ + irq_unlock(0); + + /* Context switch is performed here. Returning implies the + * thread has been context-switched-in again. + */ + return _current->arch.swap_return_value; +} + #endif /* _ASMLANGUAGE */ #ifdef __cplusplus diff --git a/arch/arm/include/cortex_m/stack.h b/arch/arm/include/cortex_m/stack.h index feeaf719a88e0..6b534a3ea5b1a 100644 --- a/arch/arm/include/cortex_m/stack.h +++ b/arch/arm/include/cortex_m/stack.h @@ -26,8 +26,7 @@ extern "C" { #endif -K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS, - CONFIG_ISR_STACK_SIZE); +K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS, CONFIG_ISR_STACK_SIZE); /** * @@ -39,9 +38,8 @@ K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS, */ static ALWAYS_INLINE void z_arm_interrupt_stack_setup(void) { - uint32_t msp = - (uint32_t)(K_KERNEL_STACK_BUFFER(z_interrupt_stacks[0])) + - K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0]); + uint32_t msp = (uint32_t)(K_KERNEL_STACK_BUFFER(z_interrupt_stacks[0])) + + K_KERNEL_STACK_SIZEOF(z_interrupt_stacks[0]); __set_MSP(msp); #if defined(CONFIG_BUILTIN_STACK_GUARD) diff --git a/arch/arm/include/cortex_m/tz_ns.h b/arch/arm/include/cortex_m/tz_ns.h index 51ed5eb1ca9fe..dd6dcb4c22e56 100644 --- a/arch/arm/include/cortex_m/tz_ns.h +++ b/arch/arm/include/cortex_m/tz_ns.h @@ -46,24 +46,18 @@ * the functions have been called. This instruction must leave * r0-r3 unmodified. */ -#define __TZ_WRAP_FUNC_RAW(preface, name, postface, store_lr, load_lr) \ - __asm__ volatile( \ - ".global "#preface"; .type "#preface", %function"); \ - __asm__ volatile( \ - ".global "#name"; .type "#name", %function"); \ - __asm__ volatile( \ - ".global "#postface"; .type "#postface", %function"); \ - __asm__ volatile( \ - store_lr "\n\t" \ - "push {r0-r3}\n\t" \ - "bl " #preface "\n\t" \ - "pop {r0-r3}\n\t" \ - "bl " #name " \n\t" \ - "push {r0-r3}\n\t" \ - "bl " #postface "\n\t" \ - "pop {r0-r3}\n\t" \ - load_lr "\n\t" \ - ::); +#define __TZ_WRAP_FUNC_RAW(preface, name, postface, store_lr, load_lr) \ + __asm__ volatile(".global " #preface "; .type " #preface ", %function"); \ + __asm__ volatile(".global " #name "; .type " #name ", %function"); \ + __asm__ volatile(".global " #postface "; .type " #postface ", %function"); \ + __asm__ volatile(store_lr "\n\t" \ + "push {r0-r3}\n\t" \ + "bl " #preface "\n\t" \ + "pop {r0-r3}\n\t" \ + "bl " #name "\n\t" \ + "push {r0-r3}\n\t" \ + "bl " #postface "\n\t" \ + "pop {r0-r3}\n\t" load_lr "\n\t" ::); /** * @brief Macro for "sandwiching" a function call (@p name) in two other calls @@ -98,10 +92,8 @@ * * See @ref __TZ_WRAP_FUNC_RAW for more information. */ -#define __TZ_WRAP_FUNC(preface, name, postface) \ - __TZ_WRAP_FUNC_RAW(preface, name, postface, "push {r4, lr}", \ - "pop {r4, pc}") - +#define __TZ_WRAP_FUNC(preface, name, postface) \ + __TZ_WRAP_FUNC_RAW(preface, name, postface, "push {r4, lr}", "pop {r4, pc}") #ifdef CONFIG_ARM_FIRMWARE_USES_SECURE_ENTRY_FUNCS /** @@ -130,10 +122,10 @@ * @param ... The rest of the signature of the function. This must be the same * signature as the corresponding NS entry function. */ -#define TZ_THREAD_SAFE_NONSECURE_ENTRY_FUNC(name, ret, nsc_name, ...) \ - ret __attribute__((naked)) name(__VA_ARGS__) \ - { \ - __TZ_WRAP_FUNC(k_sched_lock, nsc_name, k_sched_unlock); \ +#define TZ_THREAD_SAFE_NONSECURE_ENTRY_FUNC(name, ret, nsc_name, ...) \ + ret __attribute__((naked)) name(__VA_ARGS__) \ + { \ + __TZ_WRAP_FUNC(k_sched_lock, nsc_name, k_sched_unlock); \ } #endif /* CONFIG_ARM_FIRMWARE_USES_SECURE_ENTRY_FUNCS */ diff --git a/arch/arm64/core/Kconfig b/arch/arm64/core/Kconfig index 29f2cb6105ba1..35a480a24fde6 100644 --- a/arch/arm64/core/Kconfig +++ b/arch/arm64/core/Kconfig @@ -143,17 +143,6 @@ config ARM64_SAFE_EXCEPTION_STACK used for user stack overflow checking, because kernel stack support the checking work. -config ARM64_ENABLE_FRAME_POINTER - bool - depends on OVERRIDE_FRAME_POINTER_DEFAULT && !OMIT_FRAME_POINTER - depends on !FRAME_POINTER - select DEPRECATED - help - Deprecated. Use CONFIG_FRAME_POINTER instead. - Hidden option to simplify access to OVERRIDE_FRAME_POINTER_DEFAULT - and OMIT_FRAME_POINTER. It is automatically enabled when the frame - pointer unwinding is enabled. - config ARM64_EXCEPTION_STACK_TRACE bool default y diff --git a/arch/arm64/core/cortex_r/Kconfig b/arch/arm64/core/cortex_r/Kconfig index 4135378951536..e7008cce5ef02 100644 --- a/arch/arm64/core/cortex_r/Kconfig +++ b/arch/arm64/core/cortex_r/Kconfig @@ -7,39 +7,6 @@ if CPU_HAS_MPU -config ARM_MPU - bool "ARM MPU Support" - select THREAD_STACK_INFO - select MPU - select SRAM_REGION_PERMISSIONS - select ARCH_MEM_DOMAIN_SYNCHRONOUS_API if USERSPACE - default y - help - MPU implements Memory Protection Unit. - - Notes: - The ARMv8-R MPU architecture requires a power-of-two alignment - of MPU region base address and size(64 bytes aligned). - - The ARMv8-R MPU requires the active MPU regions be non-overlapping. - As a result of this, the ARMv8-R MPU needs to fully partition the - memory map when programming dynamic memory regions (e.g. PRIV stack - guard, user thread stack, and application memory domains), if the - system requires PRIV access policy different from the access policy - of the ARMv8-R background memory map. The application developer may - enforce full PRIV (kernel) memory partition by enabling the - CONFIG_MPU_GAP_FILLING option. - By not enforcing full partition, MPU may leave part of kernel - SRAM area covered only by the default ARMv8-R memory map. This - is fine for User Mode, since the background ARM map does not - allow nPRIV access at all. However, since the background map - policy allows instruction fetches by privileged code, forcing - this Kconfig option off prevents the system from directly - triggering MemManage exceptions upon accidental attempts to - execute code from SRAM in XIP builds. - Since this does not compromise User Mode, we make the skipping - of full partitioning the default behavior for the ARMv8-R MPU - driver. config ARM_MPU_REGION_MIN_ALIGN_AND_SIZE int diff --git a/arch/arm64/core/cortex_r/arm_mpu.c b/arch/arm64/core/cortex_r/arm_mpu.c index 5bc9ecbf3e5ac..3053d90cb75f6 100644 --- a/arch/arm64/core/cortex_r/arm_mpu.c +++ b/arch/arm64/core/cortex_r/arm_mpu.c @@ -196,7 +196,7 @@ static ALWAYS_INLINE void region_init(const uint32_t index, .limit = (reg).dt_addr + (reg).dt_size, \ .attr = _ATTR, \ } - +#ifdef CONFIG_MEM_ATTR /* This internal function programs the MPU regions defined in the DT when using * the `zephyr,memory-attr = <( DT_MEM_ARM(...) )>` property. */ @@ -247,7 +247,7 @@ static int mpu_configure_regions_from_dt(uint8_t *reg_index) return 0; } - +#endif /* CONFIG_MEM_ATTR */ /* * @brief MPU default configuration * @@ -303,13 +303,13 @@ FUNC_NO_STACK_PROTECTOR void z_arm64_mm_init(bool is_primary_core) /* Update the number of programmed MPU regions. */ tmp_static_num = mpu_config.num_regions; - +#ifdef CONFIG_MEM_ATTR /* DT-defined MPU regions. */ if (mpu_configure_regions_from_dt(&tmp_static_num) == -EINVAL) { __ASSERT(0, "Failed to allocate MPU regions from DT\n"); return; } - +#endif arm_core_mpu_enable(); if (!is_primary_core) { @@ -727,7 +727,7 @@ static int configure_dynamic_mpu_regions(struct k_thread *thread) */ thread->arch.region_num = (uint8_t)region_num; - if (thread == arch_current_thread()) { + if (thread == _current) { ret = flush_dynamic_regions_to_mpu(dyn_regions, region_num); } @@ -795,7 +795,7 @@ int arch_mem_domain_thread_add(struct k_thread *thread) ret = configure_dynamic_mpu_regions(thread); #ifdef CONFIG_SMP - if (ret == 0 && thread != arch_current_thread()) { + if (ret == 0 && thread != _current) { /* the thread could be running on another CPU right now */ z_arm64_mem_cfg_ipi(); } @@ -810,7 +810,7 @@ int arch_mem_domain_thread_remove(struct k_thread *thread) ret = configure_dynamic_mpu_regions(thread); #ifdef CONFIG_SMP - if (ret == 0 && thread != arch_current_thread()) { + if (ret == 0 && thread != _current) { /* the thread could be running on another CPU right now */ z_arm64_mem_cfg_ipi(); } diff --git a/arch/arm64/core/fatal.c b/arch/arm64/core/fatal.c index 0e793ea18bbe3..7955b6f7d6d16 100644 --- a/arch/arm64/core/fatal.c +++ b/arch/arm64/core/fatal.c @@ -306,9 +306,8 @@ static bool z_arm64_stack_corruption_check(struct arch_esf *esf, uint64_t esr, u } } #ifdef CONFIG_USERSPACE - else if ((arch_current_thread()->base.user_options & K_USER) != 0 && - GET_ESR_EC(esr) == 0x24) { - sp_limit = (uint64_t)arch_current_thread()->stack_info.start; + else if ((_current->base.user_options & K_USER) != 0 && GET_ESR_EC(esr) == 0x24) { + sp_limit = (uint64_t)_current->stack_info.start; guard_start = sp_limit - Z_ARM64_STACK_GUARD_SIZE; sp = esf->sp; if (sp <= sp_limit || (guard_start <= far && far <= sp_limit)) { @@ -435,7 +434,7 @@ void z_arm64_do_kernel_oops(struct arch_esf *esf) * User mode is only allowed to induce oopses and stack check * failures via software-triggered system fatal exceptions. */ - if (((arch_current_thread()->base.user_options & K_USER) != 0) && + if (((_current->base.user_options & K_USER) != 0) && reason != K_ERR_STACK_CHK_FAIL) { reason = K_ERR_KERNEL_OOPS; } diff --git a/arch/arm64/core/fpu.c b/arch/arm64/core/fpu.c index 00abd59632a61..a585165b94339 100644 --- a/arch/arm64/core/fpu.c +++ b/arch/arm64/core/fpu.c @@ -36,7 +36,7 @@ static void DBG(char *msg, struct k_thread *th) strcpy(buf, "CPU# exc# "); buf[3] = '0' + _current_cpu->id; buf[8] = '0' + arch_exception_depth(); - strcat(buf, arch_current_thread()->name); + strcat(buf, _current->name); strcat(buf, ": "); strcat(buf, msg); strcat(buf, " "); @@ -125,7 +125,7 @@ static void flush_owned_fpu(struct k_thread *thread) * replace it, and this avoids a deadlock where * two CPUs want to pull each other's FPU context. */ - if (thread == arch_current_thread()) { + if (thread == _current) { arch_flush_local_fpu(); while (atomic_ptr_get(&_kernel.cpus[i].arch.fpu_owner) == thread) { barrier_dsync_fence_full(); @@ -260,15 +260,15 @@ void z_arm64_fpu_trap(struct arch_esf *esf) * Make sure the FPU context we need isn't live on another CPU. * The current CPU's FPU context is NULL at this point. */ - flush_owned_fpu(arch_current_thread()); + flush_owned_fpu(_current); #endif /* become new owner */ - atomic_ptr_set(&_current_cpu->arch.fpu_owner, arch_current_thread()); + atomic_ptr_set(&_current_cpu->arch.fpu_owner, _current); /* restore our content */ - z_arm64_fpu_restore(&arch_current_thread()->arch.saved_fp_context); - DBG("restore", arch_current_thread()); + z_arm64_fpu_restore(&_current->arch.saved_fp_context); + DBG("restore", _current); } /* @@ -287,7 +287,7 @@ static void fpu_access_update(unsigned int exc_update_level) if (arch_exception_depth() == exc_update_level) { /* We're about to execute non-exception code */ - if (atomic_ptr_get(&_current_cpu->arch.fpu_owner) == arch_current_thread()) { + if (atomic_ptr_get(&_current_cpu->arch.fpu_owner) == _current) { /* turn on FPU access */ write_cpacr_el1(cpacr | CPACR_EL1_FPEN_NOTRAP); } else { diff --git a/arch/arm64/core/mmu.c b/arch/arm64/core/mmu.c index ef199b2e7ab4d..a914916d605e7 100644 --- a/arch/arm64/core/mmu.c +++ b/arch/arm64/core/mmu.c @@ -1309,7 +1309,7 @@ int arch_mem_domain_thread_add(struct k_thread *thread) } thread->arch.ptables = domain_ptables; - if (thread == arch_current_thread()) { + if (thread == _current) { z_arm64_swap_ptables(thread); } else { #ifdef CONFIG_SMP diff --git a/arch/arm64/core/smp.c b/arch/arm64/core/smp.c index e1c3f64dbb95f..fd9d457ea7df5 100644 --- a/arch/arm64/core/smp.c +++ b/arch/arm64/core/smp.c @@ -240,7 +240,7 @@ void mem_cfg_ipi_handler(const void *unused) * This is a no-op if the page table is already the right one. * Lock irq to prevent the interrupt during mem region switch. */ - z_arm64_swap_mem_domains(arch_current_thread()); + z_arm64_swap_mem_domains(_current); arch_irq_unlock(key); } diff --git a/arch/arm64/core/thread.c b/arch/arm64/core/thread.c index f51e203555039..18f49945eda49 100644 --- a/arch/arm64/core/thread.c +++ b/arch/arm64/core/thread.c @@ -159,15 +159,15 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, uint64_t tmpreg; /* Map the thread stack */ - z_arm64_thread_mem_domains_init(arch_current_thread()); + z_arm64_thread_mem_domains_init(_current); /* Top of the user stack area */ - stack_el0 = Z_STACK_PTR_ALIGN(arch_current_thread()->stack_info.start + - arch_current_thread()->stack_info.size - - arch_current_thread()->stack_info.delta); + stack_el0 = Z_STACK_PTR_ALIGN(_current->stack_info.start + + _current->stack_info.size - + _current->stack_info.delta); /* Top of the privileged non-user-accessible part of the stack */ - stack_el1 = (uintptr_t)(arch_current_thread()->stack_obj + ARCH_THREAD_STACK_RESERVED); + stack_el1 = (uintptr_t)(_current->stack_obj + ARCH_THREAD_STACK_RESERVED); register void *x0 __asm__("x0") = user_entry; register void *x1 __asm__("x1") = p1; diff --git a/arch/arm64/core/xen/enlighten.c b/arch/arm64/core/xen/enlighten.c index 91bf014b76212..164947a09ffdc 100644 --- a/arch/arm64/core/xen/enlighten.c +++ b/arch/arm64/core/xen/enlighten.c @@ -42,7 +42,7 @@ static int xen_map_shared_info(const shared_info_t *shared_page) return HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); } -int xen_enlighten_init(void) +static int xen_enlighten_init(void) { int ret = 0; shared_info_t *info = (shared_info_t *) shared_info_buf; @@ -66,3 +66,5 @@ int xen_enlighten_init(void) return 0; } + +SYS_INIT(xen_enlighten_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/arch/arm64/include/kernel_arch_func.h b/arch/arm64/include/kernel_arch_func.h index c37ea6257a50d..f9a2ffb982116 100644 --- a/arch/arm64/include/kernel_arch_func.h +++ b/arch/arm64/include/kernel_arch_func.h @@ -30,13 +30,8 @@ extern "C" { #ifndef _ASMLANGUAGE -extern void xen_enlighten_init(void); - static ALWAYS_INLINE void arch_kernel_init(void) { -#ifdef CONFIG_XEN - xen_enlighten_init(); -#endif #ifdef CONFIG_SOC_PER_CORE_INIT_HOOK soc_per_core_init_hook(); diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index 48685151ab1bd..6f84bb9635123 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -27,8 +27,6 @@ zephyr_library_sources_ifdef( multilevel_irq.c ) -zephyr_library_sources_ifdef(CONFIG_LEGACY_MULTI_LEVEL_TABLE_GENERATION multilevel_irq_legacy.c) - zephyr_library_sources_ifdef(CONFIG_SHARED_INTERRUPTS shared_irq.c) if(NOT CONFIG_ARCH_HAS_TIMING_FUNCTIONS AND @@ -58,12 +56,21 @@ zephyr_linker_sources_ifdef(CONFIG_GEN_IRQ_VECTOR_TABLE ) if(CONFIG_GEN_ISR_TABLES) - zephyr_linker_section(NAME .intList VMA IDT_LIST LMA IDT_LIST NOINPUT PASS NOT LINKER_ZEPHYR_FINAL) - zephyr_linker_section_configure(SECTION .intList KEEP INPUT ".irq_info" FIRST) - zephyr_linker_section_configure(SECTION .intList KEEP INPUT ".intList") - - zephyr_linker_section_configure(SECTION /DISCARD/ KEEP INPUT ".irq_info" PASS LINKER_ZEPHYR_FINAL) - zephyr_linker_section_configure(SECTION /DISCARD/ KEEP INPUT ".intList" PASS LINKER_ZEPHYR_FINAL) + # IAR Toolchain is having problems with discarding .intList + # This will always keep .intList in a harmless location + # until we can implement a proper DISCARD. + if(ZEPHYR_TOOLCHAIN_VARIANT STREQUAL "iar") + zephyr_linker_section(NAME .intList GROUP RODATA_REGION NOINPUT) + zephyr_linker_section_configure(SECTION .intList KEEP INPUT ".irq_info" FIRST) + zephyr_linker_section_configure(SECTION .intList KEEP INPUT ".intList") + else() + zephyr_linker_section(NAME .intList VMA IDT_LIST LMA IDT_LIST NOINPUT PASS NOT LINKER_ZEPHYR_FINAL) + zephyr_linker_section_configure(SECTION .intList KEEP INPUT ".irq_info" FIRST) + zephyr_linker_section_configure(SECTION .intList KEEP INPUT ".intList") + + zephyr_linker_section_configure(SECTION /DISCARD/ KEEP INPUT ".irq_info" PASS LINKER_ZEPHYR_FINAL) + zephyr_linker_section_configure(SECTION /DISCARD/ KEEP INPUT ".intList" PASS LINKER_ZEPHYR_FINAL) + endif() endif() zephyr_linker_sources_ifdef(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT @@ -76,9 +83,8 @@ zephyr_linker_sources_ifdef(CONFIG_NOCACHE_MEMORY nocache.ld ) -# Only ARM, X86 and OPENISA_RV32M1_RISCV32 use ROM_START_OFFSET. -if (DEFINED CONFIG_ARM OR DEFINED CONFIG_X86 OR DEFINED CONFIG_ARM64 - OR DEFINED CONFIG_SOC_OPENISA_RV32M1) +# Only ARM, X86 and RISCV use ROM_START_OFFSET. +if (DEFINED CONFIG_ARM OR DEFINED CONFIG_X86 OR DEFINED CONFIG_ARM64 OR DEFINED CONFIG_RISCV) # Exclamation mark is printable character with lowest number in ASCII table. # We are sure that this file will be included as a first. zephyr_linker_sources(ROM_START SORT_KEY ! rom_start_address.ld) diff --git a/arch/common/Kconfig b/arch/common/Kconfig index 2dcf2f5791bff..1cc91d7c25b79 100644 --- a/arch/common/Kconfig +++ b/arch/common/Kconfig @@ -16,24 +16,53 @@ config SEMIHOST This option is compatible with hardware and with QEMU, through the (automatic) use of the -semihosting-config switch when invoking it. -config LEGACY_MULTI_LEVEL_TABLE_GENERATION - bool "Auto generates the multi-level interrupt LUT (deprecated)" - default y - select DEPRECATED - depends on MULTI_LEVEL_INTERRUPTS - depends on !PLIC - depends on !NXP_IRQSTEER - depends on !RV32M1_INTMUX - depends on !CAVS_ICTL - depends on !DW_ICTL_ACE - depends on !DW_ICTL - help - A make-shift Kconfig to continue generating the multi-level interrupt LUT - with the legacy way using DT macros. - config ISR_TABLE_SHELL bool "Shell command to dump the ISR tables" depends on GEN_SW_ISR_TABLE depends on SHELL help This option enables a shell command to dump the ISR tables. + + +config ARM_MPU + bool "ARM MPU Support" + select MPU + select SRAM_REGION_PERMISSIONS + select THREAD_STACK_INFO + select ARCH_HAS_EXECUTABLE_PAGE_BIT if (CPU_AARCH32_CORTEX_R || CPU_CORTEX_M) + select MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT if !(CPU_HAS_NXP_SYSMPU || ARMV8_M_BASELINE || ARMV8_M_MAINLINE || AARCH32_ARMV8_R) + select MPU_REQUIRES_NON_OVERLAPPING_REGIONS if CPU_HAS_ARM_MPU && (ARMV8_M_BASELINE || ARMV8_M_MAINLINE || AARCH32_ARMV8_R) + select MPU_GAP_FILLING if AARCH32_ARMV8_R + select ARCH_MEM_DOMAIN_SUPPORTS_ISOLATED_STACKS if (CPU_AARCH32_CORTEX_R || CPU_CORTEX_M) + select ARCH_MEM_DOMAIN_SYNCHRONOUS_API if USERSPACE && CPU_AARCH64_CORTEX_R + default y if CPU_AARCH64_CORTEX_R + depends on CPU_HAS_MPU + help + MCU implements Memory Protection Unit. + + Notes: + The ARMv6-M, ARMv7-M, and ARMv8-R MPU MPU architecture requires a power-of-two + alignment of MPU region base address and size. + + The NXP MPU as well as the ARMv8-M MPU do not require MPU regions + to have power-of-two alignment for base address and region size. + + The ARMv8-M and ARMv8-R MPU requires the active MPU regions be non-overlapping. + As a result of this, both respective MPUs needs to fully partition the + memory map when programming dynamic memory regions (e.g. PRIV stack + guard, user thread stack, and application memory domains), if the + system requires PRIV access policy different from the access policy + of the ARMv8-M or ARMv8-R background memory map. The application developer may + enforce full PRIV (kernel) memory partition by enabling the + MPU_GAP_FILLING option. + By not enforcing full partition, MPU may leave part of kernel + SRAM area covered only by the default ARMv8-M or ARMv8-R memory map. This + is fine for User Mode, since the background ARM map does not + allow nPRIV access at all. However, since the background map + policy allows instruction fetches by privileged code, forcing + this Kconfig option off prevents the system from directly + triggering MemManage exceptions upon accidental attempts to + execute code from SRAM in XIP builds. + Since this does not compromise User Mode, we make the skipping + of full partitioning the default behavior for the ARMv8-M and ARMv8-R MPU + driver. diff --git a/arch/common/multilevel_irq_legacy.c b/arch/common/multilevel_irq_legacy.c deleted file mode 100644 index dd4fe68b5ac45..0000000000000 --- a/arch/common/multilevel_irq_legacy.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2018 Intel Corporation. - * Copyright (c) 2024 Meta. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/** - * @file - * @brief This file houses the deprecated legacy macros-generated multi-level interrupt lookup - * table code, compiled when `CONFIG_LEGACY_MULTI_LEVEL_TABLE_GENERATION` is enabled. - */ - -/* - * Insert code if the node_id is an interrupt controller - */ -#define Z_IF_DT_IS_INTC(node_id, code) \ - IF_ENABLED(DT_NODE_HAS_PROP(node_id, interrupt_controller), (code)) - -/* - * Expands to node_id if its IRQN is equal to `_irq`, nothing otherwise - * This only works for `_irq` between 0 & 4095, see `IS_EQ` - */ -#define Z_IF_DT_INTC_IRQN_EQ(node_id, _irq) IF_ENABLED(IS_EQ(DT_IRQ(node_id, irq), _irq), (node_id)) - -/* - * Expands to node_id if it's an interrupt controller & its IRQN is `irq`, or nothing otherwise - */ -#define Z_DT_INTC_GET_IRQN(node_id, _irq) \ - Z_IF_DT_IS_INTC(node_id, Z_IF_DT_INTC_IRQN_EQ(node_id, _irq)) - -/** - * Loop through child of "/soc" and get root interrupt controllers with `_irq` as IRQN, - * this assumes only one device has the IRQN - * @param _irq irq number - * @return node_id(s) that has the `_irq` number, or empty if none of them has the `_irq` - */ -#define INTC_DT_IRQN_GET(_irq) \ - DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_PATH(soc), Z_DT_INTC_GET_IRQN, _irq) - -#define INIT_IRQ_PARENT_OFFSET_2ND(n, d, i, o) \ - IRQ_PARENT_ENTRY_DEFINE(intc_l2_##n, DEVICE_DT_GET_OR_NULL(d), i, o, 2) - -#define IRQ_INDEX_TO_OFFSET(i, base) (base + i * CONFIG_MAX_IRQ_PER_AGGREGATOR) - -#define CAT_2ND_LVL_LIST(i, base) \ - INIT_IRQ_PARENT_OFFSET_2ND(i, INTC_DT_IRQN_GET(CONFIG_2ND_LVL_INTR_0##i##_OFFSET), \ - CONFIG_2ND_LVL_INTR_0##i##_OFFSET, \ - IRQ_INDEX_TO_OFFSET(i, base)) - -LISTIFY(CONFIG_NUM_2ND_LEVEL_AGGREGATORS, CAT_2ND_LVL_LIST, (;), CONFIG_2ND_LVL_ISR_TBL_OFFSET); - -#ifdef CONFIG_3RD_LEVEL_INTERRUPTS - -BUILD_ASSERT((CONFIG_NUM_3RD_LEVEL_AGGREGATORS * CONFIG_MAX_IRQ_PER_AGGREGATOR) <= - BIT(CONFIG_3RD_LEVEL_INTERRUPT_BITS), - "L3 bits not enough to cover the number of L3 IRQs"); - -#define INIT_IRQ_PARENT_OFFSET_3RD(n, d, i, o) \ - IRQ_PARENT_ENTRY_DEFINE(intc_l3_##n, DEVICE_DT_GET_OR_NULL(d), i, o, 3) - -#define CAT_3RD_LVL_LIST(i, base) \ - INIT_IRQ_PARENT_OFFSET_3RD(i, INTC_DT_IRQN_GET(CONFIG_3RD_LVL_INTR_0##i##_OFFSET), \ - CONFIG_3RD_LVL_INTR_0##i##_OFFSET, \ - IRQ_INDEX_TO_OFFSET(i, base)) - -LISTIFY(CONFIG_NUM_3RD_LEVEL_AGGREGATORS, CAT_3RD_LVL_LIST, (;), CONFIG_3RD_LVL_ISR_TBL_OFFSET); - -#endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ diff --git a/arch/common/timing.c b/arch/common/timing.c index 8a4f65caa332a..642ba79659fa0 100644 --- a/arch/common/timing.c +++ b/arch/common/timing.c @@ -22,13 +22,21 @@ void arch_timing_stop(void) timing_t arch_timing_counter_get(void) { +#if CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER + return k_cycle_get_64(); +#else return k_cycle_get_32(); +#endif } uint64_t arch_timing_cycles_get(volatile timing_t *const start, volatile timing_t *const end) { +#if CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER return (*end - *start); +#else + return ((uint32_t)*end - (uint32_t)*start); +#endif } diff --git a/arch/mips/core/fatal.c b/arch/mips/core/fatal.c index a53e5bb0f5e6c..aee7a597d4d4d 100644 --- a/arch/mips/core/fatal.c +++ b/arch/mips/core/fatal.c @@ -84,7 +84,7 @@ static char *cause_str(unsigned long cause) } } -void _Fault(struct arch_esf *esf) +void z_mips_fault(struct arch_esf *esf) { unsigned long cause; diff --git a/arch/mips/core/isr.S b/arch/mips/core/isr.S index f2f2f34205364..1532d06fe5e1b 100644 --- a/arch/mips/core/isr.S +++ b/arch/mips/core/isr.S @@ -66,7 +66,7 @@ addi sp, sp, __struct_arch_esf_SIZEOF ; /* imports */ -GTEXT(_Fault) +GTEXT(z_mips_fault) GTEXT(_k_neg_eagain) GTEXT(z_thread_mark_switched_in) @@ -125,7 +125,7 @@ SECTION_FUNC(exception.other, _mips_interrupt) unhandled: move a0, sp - jal _Fault + jal z_mips_fault eret is_kernel_syscall: diff --git a/arch/mips/include/kernel_arch_func.h b/arch/mips/include/kernel_arch_func.h index 7c35d1bf864a3..63ed7a65cf265 100644 --- a/arch/mips/include/kernel_arch_func.h +++ b/arch/mips/include/kernel_arch_func.h @@ -47,6 +47,8 @@ static inline bool arch_is_in_isr(void) return _current_cpu->nested != 0U; } +int arch_swap(unsigned int key); + #ifdef CONFIG_IRQ_OFFLOAD void z_irq_do_offload(void); #endif diff --git a/arch/nios2/core/exception.S b/arch/nios2/core/exception.S index ab2d3463dd437..8dd7e0b9b9b8f 100644 --- a/arch/nios2/core/exception.S +++ b/arch/nios2/core/exception.S @@ -12,7 +12,7 @@ GTEXT(_exception) /* import */ -GTEXT(_Fault) +GTEXT(z_nios2_fault) GTEXT(arch_swap) #ifdef CONFIG_IRQ_OFFLOAD GTEXT(z_irq_do_offload) @@ -171,12 +171,12 @@ not_interrupt: _exception_enter_fault: /* If we get here, the exception wasn't in interrupt or an - * invocation of irq_oflload(). Let _Fault() handle it in + * invocation of irq_offload(). Let z_nios2_fault() handle it in * C domain */ mov r4, sp - call _Fault + call z_nios2_fault jmpi _exception_exit no_reschedule: diff --git a/arch/nios2/core/fatal.c b/arch/nios2/core/fatal.c index b531bb41e1789..3f34c1e8fc7ec 100644 --- a/arch/nios2/core/fatal.c +++ b/arch/nios2/core/fatal.c @@ -102,7 +102,7 @@ static char *cause_str(uint32_t cause_code) } #endif -FUNC_NORETURN void _Fault(const struct arch_esf *esf) +FUNC_NORETURN void z_nios2_fault(const struct arch_esf *esf) { #if defined(CONFIG_PRINTK) || defined(CONFIG_LOG) /* Unfortunately, completely unavailable on Nios II/e cores */ diff --git a/arch/nios2/core/timing.c b/arch/nios2/core/timing.c index 9deb469a07fcb..80ee73c6f069e 100644 --- a/arch/nios2/core/timing.c +++ b/arch/nios2/core/timing.c @@ -41,7 +41,13 @@ timing_t arch_timing_counter_get(void) uint64_t arch_timing_cycles_get(volatile timing_t *const start, volatile timing_t *const end) { - return (*end - *start); + timing_t start_ = *start; + timing_t end_ = *end; + + if (end_ >= start_) { + return (end_ - start_); + } + return (end_ + NIOS2_SUBTRACT_CLOCK_CYCLES(start_)); } uint64_t arch_timing_freq_get(void) diff --git a/arch/nios2/include/kernel_arch_func.h b/arch/nios2/include/kernel_arch_func.h index 464ba32a7a738..c325ea49b49b9 100644 --- a/arch/nios2/include/kernel_arch_func.h +++ b/arch/nios2/include/kernel_arch_func.h @@ -51,6 +51,8 @@ static inline bool arch_is_in_isr(void) return _kernel.cpus[0].nested != 0U; } +int arch_swap(unsigned int key); + #ifdef CONFIG_IRQ_OFFLOAD void z_irq_do_offload(void); #endif diff --git a/arch/posix/core/swap.c b/arch/posix/core/swap.c index 18d83cf78d6b6..cf13ab4d4d311 100644 --- a/arch/posix/core/swap.c +++ b/arch/posix/core/swap.c @@ -23,7 +23,7 @@ int arch_swap(unsigned int key) { /* - * struct k_thread * arch_current_thread() is the currently running thread + * struct k_thread * _current is the currently running thread * struct k_thread * _kernel.ready_q.cache contains the next thread to * run (cannot be NULL) * @@ -34,8 +34,8 @@ int arch_swap(unsigned int key) #if CONFIG_INSTRUMENT_THREAD_SWITCHING z_thread_mark_switched_out(); #endif - arch_current_thread()->callee_saved.key = key; - arch_current_thread()->callee_saved.retval = -EAGAIN; + _current->callee_saved.key = key; + _current->callee_saved.retval = -EAGAIN; /* retval may be modified with a call to * arch_thread_return_value_set() @@ -47,10 +47,10 @@ int arch_swap(unsigned int key) posix_thread_status_t *this_thread_ptr = (posix_thread_status_t *) - arch_current_thread()->callee_saved.thread_status; + _current->callee_saved.thread_status; - arch_current_thread_set(_kernel.ready_q.cache); + z_current_thread_set(_kernel.ready_q.cache); #if CONFIG_INSTRUMENT_THREAD_SWITCHING z_thread_mark_switched_in(); #endif @@ -66,9 +66,9 @@ int arch_swap(unsigned int key) /* When we continue, _kernel->current points back to this thread */ - irq_unlock(arch_current_thread()->callee_saved.key); + irq_unlock(_current->callee_saved.key); - return arch_current_thread()->callee_saved.retval; + return _current->callee_saved.retval; } @@ -94,7 +94,7 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, z_thread_mark_switched_out(); #endif - arch_current_thread_set(_kernel.ready_q.cache); + z_current_thread_set(_kernel.ready_q.cache); #ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING z_thread_mark_switched_in(); diff --git a/arch/posix/core/thread.c b/arch/posix/core/thread.c index 0a3f2eccd74b3..050d075fe570c 100644 --- a/arch/posix/core/thread.c +++ b/arch/posix/core/thread.c @@ -131,7 +131,7 @@ void z_impl_k_thread_abort(k_tid_t thread) key = irq_lock(); - if (arch_current_thread() == thread) { + if (_current == thread) { if (tstatus->aborted == 0) { /* LCOV_EXCL_BR_LINE */ tstatus->aborted = 1; } else { diff --git a/arch/posix/include/kernel_arch_func.h b/arch/posix/include/kernel_arch_func.h index 98289d5d7c68a..ceba8a8509340 100644 --- a/arch/posix/include/kernel_arch_func.h +++ b/arch/posix/include/kernel_arch_func.h @@ -42,6 +42,8 @@ static inline bool arch_is_in_isr(void) return _kernel.cpus[0].nested != 0U; } +int arch_swap(unsigned int key); + #endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_ARCH_POSIX_INCLUDE_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 5e3049433a9c4..72907a41fee41 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -38,7 +38,7 @@ config RISCV_CURRENT_VIA_GP select ARCH_HAS_CUSTOM_CURRENT_IMPL help Store the current thread's pointer into the global pointer (GP) register. - When is enabled, calls to `arch_current_thread()` & `k_sched_current_thread_query()` will + When is enabled, calls to `_current` & `k_sched_current_thread_query()` will be reduced to a single register read. endchoice # RISCV_GP_PURPOSE @@ -124,6 +124,11 @@ config RISCV_SOC_HAS_ISR_STACKING saved on the stack by the hardware, and the registers saved by the software macros. The structure must be called 'struct arch_esf'. + - SOC_ISR_STACKING_ESR_INIT: macro guarded by !_ASMLANGUAGE. + Some hardware stacked registers should be initialized on init + stack with proper values. This prevents from incorrect behavior + on entry context switch when initial stack is restored. + config RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING bool help @@ -215,9 +220,20 @@ config RISCV_HAS_PLIC config RISCV_HAS_CLIC bool depends on RISCV_PRIVILEGED + select RISCV_ALWAYS_SWITCH_THROUGH_ECALL if MULTITHREADING + select CLIC_SUPPORT_INTERRUPT_LEVEL if !NRFX_CLIC help Does the SOC provide support for a Core-Local Interrupt Controller (CLIC). +config CLIC_SUPPORT_INTERRUPT_LEVEL + bool + depends on RISCV_HAS_CLIC + help + For CLIC implementations with extended interrupt level, where + higher-numbered interrupt levels can preempt lower-numbered interrupt + levels. This option handles interrupt level in ISR to ensure proper + nested ISR exits. + config RISCV_SOC_EXCEPTION_FROM_IRQ bool help diff --git a/arch/riscv/Kconfig.isa b/arch/riscv/Kconfig.isa index 70599843c48b5..7ac915865d15a 100644 --- a/arch/riscv/Kconfig.isa +++ b/arch/riscv/Kconfig.isa @@ -33,6 +33,8 @@ config RISCV_ISA_EXT_M config RISCV_ISA_EXT_A bool + imply RISCV_ISA_EXT_ZAAMO + imply RISCV_ISA_EXT_ZLRSC help (A) - Standard Extension for Atomic Instructions @@ -111,6 +113,20 @@ config RISCV_ISA_EXT_ZIFENCEI provides explicit synchronization between writes to instruction memory and instruction fetches on the same hart. +config RISCV_ISA_EXT_ZAAMO + bool + help + (Zaamo) - Atomic memory operation subset of the A extension + + The Zaamo extension enables support for AMO*.W/D-style instructions. + +config RISCV_ISA_EXT_ZLRSC + bool + help + (Zlrsc) - Load-Reserved/Store-Conditional subset of the A extension + + The Zlrsc extension enables support for LR.W/D and SC.W/D-style instructions. + config RISCV_ISA_EXT_ZBA bool help diff --git a/arch/riscv/core/elf.c b/arch/riscv/core/elf.c index 4f981083b946b..e0630876dd4c6 100644 --- a/arch/riscv/core/elf.c +++ b/arch/riscv/core/elf.c @@ -43,6 +43,13 @@ LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL); static inline int riscv_relocation_fits(long long jump_target, long long max_distance, elf_word reloc_type) { + /* + * two's complement encoding + * e.g., [-128=0b10000000, 127=0b01111111] encodable with 8 bits + */ + if (jump_target < 0) { + max_distance++; + } if (llabs(jump_target) > max_distance) { LOG_ERR("%lld byte relocation is not possible for type %" PRIu64 " (max %lld)!", jump_target, (uint64_t)reloc_type, max_distance); diff --git a/arch/riscv/core/fatal.c b/arch/riscv/core/fatal.c index 8e0e55c8e8047..3bf4e57d874a1 100644 --- a/arch/riscv/core/fatal.c +++ b/arch/riscv/core/fatal.c @@ -158,23 +158,23 @@ static bool bad_stack_pointer(struct arch_esf *esf) uintptr_t sp = (uintptr_t)esf + sizeof(struct arch_esf); #ifdef CONFIG_USERSPACE - if (arch_current_thread()->arch.priv_stack_start != 0 && - sp >= arch_current_thread()->arch.priv_stack_start && - sp < arch_current_thread()->arch.priv_stack_start + Z_RISCV_STACK_GUARD_SIZE) { + if (_current->arch.priv_stack_start != 0 && + sp >= _current->arch.priv_stack_start && + sp < _current->arch.priv_stack_start + Z_RISCV_STACK_GUARD_SIZE) { return true; } - if (z_stack_is_user_capable(arch_current_thread()->stack_obj) && - sp >= arch_current_thread()->stack_info.start - K_THREAD_STACK_RESERVED && - sp < arch_current_thread()->stack_info.start - K_THREAD_STACK_RESERVED + if (z_stack_is_user_capable(_current->stack_obj) && + sp >= _current->stack_info.start - K_THREAD_STACK_RESERVED && + sp < _current->stack_info.start - K_THREAD_STACK_RESERVED + Z_RISCV_STACK_GUARD_SIZE) { return true; } #endif /* CONFIG_USERSPACE */ #if CONFIG_MULTITHREADING - if (sp >= arch_current_thread()->stack_info.start - K_KERNEL_STACK_RESERVED && - sp < arch_current_thread()->stack_info.start - K_KERNEL_STACK_RESERVED + if (sp >= _current->stack_info.start - K_KERNEL_STACK_RESERVED && + sp < _current->stack_info.start - K_KERNEL_STACK_RESERVED + Z_RISCV_STACK_GUARD_SIZE) { return true; } @@ -191,10 +191,10 @@ static bool bad_stack_pointer(struct arch_esf *esf) #ifdef CONFIG_USERSPACE if ((esf->mstatus & MSTATUS_MPP) == 0 && - (esf->sp < arch_current_thread()->stack_info.start || - esf->sp > arch_current_thread()->stack_info.start + - arch_current_thread()->stack_info.size - - arch_current_thread()->stack_info.delta)) { + (esf->sp < _current->stack_info.start || + esf->sp > _current->stack_info.start + + _current->stack_info.size - + _current->stack_info.delta)) { /* user stack pointer moved outside of its allowed stack */ return true; } @@ -203,7 +203,7 @@ static bool bad_stack_pointer(struct arch_esf *esf) return false; } -void _Fault(struct arch_esf *esf) +void z_riscv_fault(struct arch_esf *esf) { #ifdef CONFIG_USERSPACE /* @@ -246,9 +246,9 @@ FUNC_NORETURN void arch_syscall_oops(void *ssf_ptr) void z_impl_user_fault(unsigned int reason) { - struct arch_esf *oops_esf = arch_current_thread()->syscall_frame; + struct arch_esf *oops_esf = _current->syscall_frame; - if (((arch_current_thread()->base.user_options & K_USER) != 0) && + if (((_current->base.user_options & K_USER) != 0) && reason != K_ERR_STACK_CHK_FAIL) { reason = K_ERR_KERNEL_OOPS; } diff --git a/arch/riscv/core/fpu.c b/arch/riscv/core/fpu.c index bd648585c436d..318e97e0002a9 100644 --- a/arch/riscv/core/fpu.c +++ b/arch/riscv/core/fpu.c @@ -36,8 +36,8 @@ static void DBG(char *msg, struct k_thread *th) strcpy(buf, "CPU# exc# "); buf[3] = '0' + _current_cpu->id; - buf[8] = '0' + arch_current_thread()->arch.exception_depth; - strcat(buf, arch_current_thread()->name); + buf[8] = '0' + _current->arch.exception_depth; + strcat(buf, _current->name); strcat(buf, ": "); strcat(buf, msg); strcat(buf, " "); @@ -82,12 +82,12 @@ static void z_riscv_fpu_load(void) "must be called with FPU access disabled"); /* become new owner */ - atomic_ptr_set(&_current_cpu->arch.fpu_owner, arch_current_thread()); + atomic_ptr_set(&_current_cpu->arch.fpu_owner, _current); /* restore our content */ csr_set(mstatus, MSTATUS_FS_INIT); - z_riscv_fpu_restore(&arch_current_thread()->arch.saved_fp_context); - DBG("restore", arch_current_thread()); + z_riscv_fpu_restore(&_current->arch.saved_fp_context); + DBG("restore", _current); } /* @@ -168,7 +168,7 @@ static void flush_owned_fpu(struct k_thread *thread) * replace it, and this avoids a deadlock where * two CPUs want to pull each other's FPU context. */ - if (thread == arch_current_thread()) { + if (thread == _current) { z_riscv_fpu_disable(); arch_flush_local_fpu(); do { @@ -213,7 +213,7 @@ void z_riscv_fpu_trap(struct arch_esf *esf) /* save current owner's content if any */ arch_flush_local_fpu(); - if (arch_current_thread()->arch.exception_depth > 0) { + if (_current->arch.exception_depth > 0) { /* * We were already in exception when the FPU access trapped. * We give it access and prevent any further IRQ recursion @@ -233,7 +233,7 @@ void z_riscv_fpu_trap(struct arch_esf *esf) * Make sure the FPU context we need isn't live on another CPU. * The current CPU's FPU context is NULL at this point. */ - flush_owned_fpu(arch_current_thread()); + flush_owned_fpu(_current); #endif /* make it accessible and clean to the returning context */ @@ -256,13 +256,13 @@ static bool fpu_access_allowed(unsigned int exc_update_level) __ASSERT((csr_read(mstatus) & MSTATUS_IEN) == 0, "must be called with IRQs disabled"); - if (arch_current_thread()->arch.exception_depth == exc_update_level) { + if (_current->arch.exception_depth == exc_update_level) { /* We're about to execute non-exception code */ - if (_current_cpu->arch.fpu_owner == arch_current_thread()) { + if (_current_cpu->arch.fpu_owner == _current) { /* everything is already in place */ return true; } - if (arch_current_thread()->arch.fpu_recently_used) { + if (_current->arch.fpu_recently_used) { /* * Before this thread was context-switched out, * it made active use of the FPU, but someone else @@ -273,7 +273,7 @@ static bool fpu_access_allowed(unsigned int exc_update_level) z_riscv_fpu_disable(); arch_flush_local_fpu(); #ifdef CONFIG_SMP - flush_owned_fpu(arch_current_thread()); + flush_owned_fpu(_current); #endif z_riscv_fpu_load(); _current_cpu->arch.fpu_state = MSTATUS_FS_CLEAN; diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index 193f48208716c..dad96974dcc48 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -72,7 +72,7 @@ GDATA(_sw_isr_table) GTEXT(__soc_is_irq) #endif GTEXT(__soc_handle_irq) -GTEXT(_Fault) +GTEXT(z_riscv_fault) #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE GTEXT(__soc_save_context) GTEXT(__soc_restore_context) @@ -198,6 +198,12 @@ SECTION_FUNC(exception.entry, _isr_wrapper) sr s0, __struct_arch_esf_s0_OFFSET(sp) get_current_cpu s0 +#ifdef CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL + /* Save mcause register */ + csrr t0, mcause + sr t0, __struct_arch_esf_mcause_OFFSET(sp) +#endif /* CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL */ + /* Save MEPC register */ csrr t0, mepc sr t0, __struct_arch_esf_mepc_OFFSET(sp) @@ -299,7 +305,7 @@ is_fp: /* Process the FP trap and quickly return from exception */ mv a0, sp tail z_riscv_fpu_trap 2: -no_fp: /* increment arch_current_thread()->arch.exception_depth */ +no_fp: /* increment _current->arch.exception_depth */ lr t0, ___cpu_t_current_OFFSET(s0) lb t1, _thread_offset_to_exception_depth(t0) add t1, t1, 1 @@ -336,7 +342,7 @@ no_fp: /* increment arch_current_thread()->arch.exception_depth */ /* * If the exception is the result of an ECALL, check whether to - * perform a context-switch or an IRQ offload. Otherwise call _Fault + * perform a context-switch or an IRQ offload. Otherwise call z_riscv_fault * to report the exception. */ csrr t0, mcause @@ -375,15 +381,15 @@ no_fp: /* increment arch_current_thread()->arch.exception_depth */ #endif /* CONFIG_USERSPACE */ /* - * Call _Fault to handle exception. + * Call z_riscv_fault to handle exception. * Stack pointer is pointing to a struct_arch_esf structure, pass it - * to _Fault (via register a0). - * If _Fault shall return, set return address to + * to z_riscv_fault (via register a0). + * If z_riscv_fault shall return, set return address to * no_reschedule to restore stack. */ mv a0, sp la ra, no_reschedule - tail _Fault + tail z_riscv_fault is_kernel_syscall: /* @@ -726,7 +732,7 @@ no_reschedule: mv a0, sp call z_riscv_fpu_exit_exc - /* decrement arch_current_thread()->arch.exception_depth */ + /* decrement _current->arch.exception_depth */ lr t0, ___cpu_t_current_OFFSET(s0) lb t1, _thread_offset_to_exception_depth(t0) add t1, t1, -1 @@ -737,6 +743,13 @@ fp_trap_exit: /* Restore MEPC and MSTATUS registers */ lr t0, __struct_arch_esf_mepc_OFFSET(sp) lr t2, __struct_arch_esf_mstatus_OFFSET(sp) + +#ifdef CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL + /* Restore MCAUSE register for previous interrupt level. */ + lr t1, __struct_arch_esf_mcause_OFFSET(sp) + csrw mcause, t1 +#endif /* CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL */ + csrw mepc, t0 csrw mstatus, t2 diff --git a/arch/riscv/core/offsets/offsets.c b/arch/riscv/core/offsets/offsets.c index 99eba096824a3..c526ffbaed0d3 100644 --- a/arch/riscv/core/offsets/offsets.c +++ b/arch/riscv/core/offsets/offsets.c @@ -112,6 +112,10 @@ GEN_OFFSET_STRUCT(arch_esf, a7); GEN_OFFSET_STRUCT(arch_esf, mepc); GEN_OFFSET_STRUCT(arch_esf, mstatus); +#ifdef CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL +GEN_OFFSET_STRUCT(arch_esf, mcause); +#endif /* CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL */ + GEN_OFFSET_STRUCT(arch_esf, s0); #ifdef CONFIG_USERSPACE diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index fbbf7c55137ce..e29c8abd76d61 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -752,8 +752,8 @@ int arch_buffer_validate(const void *addr, size_t size, int write) int ret = -1; /* Check if this is on the stack */ - if (IS_WITHIN(start, size, arch_current_thread()->stack_info.start, - arch_current_thread()->stack_info.size)) { + if (IS_WITHIN(start, size, + _current->stack_info.start, _current->stack_info.size)) { return 0; } @@ -768,7 +768,7 @@ int arch_buffer_validate(const void *addr, size_t size, int write) } /* Look for a matching partition in our memory domain */ - struct k_mem_domain *domain = arch_current_thread()->mem_domain_info.mem_domain; + struct k_mem_domain *domain = _current->mem_domain_info.mem_domain; int p_idx, remaining_partitions; k_spinlock_key_t key = k_spin_lock(&z_mem_domain_lock); diff --git a/arch/riscv/core/stacktrace.c b/arch/riscv/core/stacktrace.c index 0dfe0a1963882..361e152f00ca3 100644 --- a/arch/riscv/core/stacktrace.c +++ b/arch/riscv/core/stacktrace.c @@ -108,7 +108,7 @@ static void walk_stackframe(riscv_stacktrace_cb cb, void *cookie, const struct k /* Unwind the provided exception stack frame */ fp = esf->s0; ra = esf->mepc; - } else if ((csf == NULL) || (csf == &arch_current_thread()->callee_saved)) { + } else if ((csf == NULL) || (csf == &_current->callee_saved)) { /* Unwind current thread (default case when nothing is provided ) */ fp = (uintptr_t)__builtin_frame_address(0); ra = (uintptr_t)walk_stackframe; @@ -181,7 +181,7 @@ static void walk_stackframe(riscv_stacktrace_cb cb, void *cookie, const struct k /* Unwind the provided exception stack frame */ sp = z_riscv_get_sp_before_exc(esf); ra = esf->mepc; - } else if ((csf == NULL) || (csf == &arch_current_thread()->callee_saved)) { + } else if ((csf == NULL) || (csf == &_current->callee_saved)) { /* Unwind current thread (default case when nothing is provided ) */ sp = current_stack_pointer; ra = (uintptr_t)walk_stackframe; @@ -215,10 +215,8 @@ void arch_stack_walk(stack_trace_callback_fn callback_fn, void *cookie, const struct k_thread *thread, const struct arch_esf *esf) { if (thread == NULL) { - /* In case `thread` is NULL, default that to `arch_current_thread()` - * and try to unwind - */ - thread = arch_current_thread(); + /* In case `thread` is NULL, default that to `_current` and try to unwind */ + thread = _current; } walk_stackframe((riscv_stacktrace_cb)callback_fn, cookie, thread, esf, in_stack_bound, @@ -282,8 +280,7 @@ void z_riscv_unwind_stack(const struct arch_esf *esf, const _callee_saved_t *csf int i = 0; LOG_ERR("call trace:"); - walk_stackframe(print_trace_address, &i, arch_current_thread(), esf, in_fatal_stack_bound, - csf); + walk_stackframe(print_trace_address, &i, _current, esf, in_fatal_stack_bound, csf); LOG_ERR(""); } #endif /* CONFIG_EXCEPTION_STACK_TRACE */ diff --git a/arch/riscv/core/thread.c b/arch/riscv/core/thread.c index 5c471034d2575..ab2cbfe003676 100644 --- a/arch/riscv/core/thread.c +++ b/arch/riscv/core/thread.c @@ -106,6 +106,15 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, stack_init->soc_context = soc_esf_init; #endif +#ifdef CONFIG_RISCV_SOC_HAS_ISR_STACKING + SOC_ISR_STACKING_ESR_INIT; +#endif + +#ifdef CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL + /* Clear the previous interrupt level. */ + stack_init->mcause = 0; +#endif + thread->callee_saved.sp = (unsigned long)stack_init; /* where to go when returning from z_riscv_switch() */ @@ -132,29 +141,28 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, /* Set up privileged stack */ #ifdef CONFIG_GEN_PRIV_STACKS - arch_current_thread()->arch.priv_stack_start = - (unsigned long)z_priv_stack_find(arch_current_thread()->stack_obj); + _current->arch.priv_stack_start = + (unsigned long)z_priv_stack_find(_current->stack_obj); /* remove the stack guard from the main stack */ - arch_current_thread()->stack_info.start -= K_THREAD_STACK_RESERVED; - arch_current_thread()->stack_info.size += K_THREAD_STACK_RESERVED; + _current->stack_info.start -= K_THREAD_STACK_RESERVED; + _current->stack_info.size += K_THREAD_STACK_RESERVED; #else - arch_current_thread()->arch.priv_stack_start = - (unsigned long)arch_current_thread()->stack_obj; + _current->arch.priv_stack_start = (unsigned long)_current->stack_obj; #endif /* CONFIG_GEN_PRIV_STACKS */ - top_of_priv_stack = Z_STACK_PTR_ALIGN(arch_current_thread()->arch.priv_stack_start + + top_of_priv_stack = Z_STACK_PTR_ALIGN(_current->arch.priv_stack_start + K_KERNEL_STACK_RESERVED + CONFIG_PRIVILEGED_STACK_SIZE); #ifdef CONFIG_INIT_STACKS /* Initialize the privileged stack */ - (void)memset((void *)arch_current_thread()->arch.priv_stack_start, 0xaa, + (void)memset((void *)_current->arch.priv_stack_start, 0xaa, Z_STACK_PTR_ALIGN(K_KERNEL_STACK_RESERVED + CONFIG_PRIVILEGED_STACK_SIZE)); #endif /* CONFIG_INIT_STACKS */ top_of_user_stack = Z_STACK_PTR_ALIGN( - arch_current_thread()->stack_info.start + - arch_current_thread()->stack_info.size - - arch_current_thread()->stack_info.delta); + _current->stack_info.start + + _current->stack_info.size - + _current->stack_info.delta); status = csr_read(mstatus); @@ -170,12 +178,12 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, #ifdef CONFIG_PMP_STACK_GUARD /* reconfigure as the kernel mode stack will be different */ - z_riscv_pmp_stackguard_prepare(arch_current_thread()); + z_riscv_pmp_stackguard_prepare(_current); #endif /* Set up Physical Memory Protection */ - z_riscv_pmp_usermode_prepare(arch_current_thread()); - z_riscv_pmp_usermode_enable(arch_current_thread()); + z_riscv_pmp_usermode_prepare(_current); + z_riscv_pmp_usermode_enable(_current); /* preserve stack pointer for next exception entry */ arch_curr_cpu()->arch.user_exc_sp = top_of_priv_stack; diff --git a/arch/sparc/core/thread.c b/arch/sparc/core/thread.c index 8bdc4cd5500f6..e56d9f827c9de 100644 --- a/arch/sparc/core/thread.c +++ b/arch/sparc/core/thread.c @@ -61,7 +61,7 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, void *z_arch_get_next_switch_handle(struct k_thread **old_thread) { - *old_thread = arch_current_thread(); + *old_thread = _current; return z_get_next_switch_handle(*old_thread); } diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 46f32f927281f..c947c0afc1b83 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -43,7 +43,16 @@ config CPU_APOLLO_LAKE help This option signifies the use of a CPU from the Apollo Lake family. -config CPU_LAKEMONT +config CPU_LAKEMONT_VALUE + bool + select CPU_HAS_FPU + select ARCH_HAS_STACK_PROTECTION if X86_MMU + select ARCH_HAS_USERSPACE if X86_MMU + select CPU_HAS_DCACHE + help + This option signifies the use of a CPU from the Lakemont Value family. + +config CPU_LAKEMONT_PERF bool select CPU_HAS_FPU select ARCH_HAS_STACK_PROTECTION if X86_MMU @@ -55,7 +64,7 @@ config CPU_LAKEMONT select X86_CPU_HAS_SSSE3 select CPU_HAS_DCACHE help - This option signifies the use of a CPU from the Lakemont family. + This option signifies the use of a CPU from the Lakemont Performance family. # # Configuration common to both IA32 and Intel64 sub-architectures. diff --git a/arch/x86/core/fatal.c b/arch/x86/core/fatal.c index f3103861f366e..6511f531e3df6 100644 --- a/arch/x86/core/fatal.c +++ b/arch/x86/core/fatal.c @@ -49,7 +49,7 @@ bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, uint16_t cs) { uintptr_t start, end; - if (arch_current_thread() == NULL || arch_is_in_isr()) { + if (_current == NULL || arch_is_in_isr()) { /* We were servicing an interrupt or in early boot environment * and are supposed to be on the interrupt stack */ int cpu_id; @@ -64,7 +64,7 @@ bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, uint16_t cs) end = start + CONFIG_ISR_STACK_SIZE; #ifdef CONFIG_USERSPACE } else if ((cs & 0x3U) == 0U && - (arch_current_thread()->base.user_options & K_USER) != 0) { + (_current->base.user_options & K_USER) != 0) { /* The low two bits of the CS register is the privilege * level. It will be 0 in supervisor mode and 3 in user mode * corresponding to ring 0 / ring 3. @@ -72,14 +72,14 @@ bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, uint16_t cs) * If we get here, we must have been doing a syscall, check * privilege elevation stack bounds */ - start = arch_current_thread()->stack_info.start - CONFIG_PRIVILEGED_STACK_SIZE; - end = arch_current_thread()->stack_info.start; + start = _current->stack_info.start - CONFIG_PRIVILEGED_STACK_SIZE; + end = _current->stack_info.start; #endif /* CONFIG_USERSPACE */ } else { /* Normal thread operation, check its stack buffer */ - start = arch_current_thread()->stack_info.start; - end = Z_STACK_PTR_ALIGN(arch_current_thread()->stack_info.start + - arch_current_thread()->stack_info.size); + start = _current->stack_info.start; + end = Z_STACK_PTR_ALIGN(_current->stack_info.start + + _current->stack_info.size); } return (addr <= start) || (addr + size > end); @@ -97,7 +97,7 @@ bool z_x86_check_stack_bounds(uintptr_t addr, size_t size, uint16_t cs) __pinned_func bool z_x86_check_guard_page(uintptr_t addr) { - struct k_thread *thread = arch_current_thread(); + struct k_thread *thread = _current; uintptr_t start, end; /* Front guard size - before thread stack area */ @@ -233,7 +233,7 @@ static inline uintptr_t get_cr3(const struct arch_esf *esf) * switch when we took the exception via z_x86_trampoline_to_kernel */ if ((esf->cs & 0x3) != 0) { - return arch_current_thread()->arch.ptables; + return _current->arch.ptables; } #else ARG_UNUSED(esf); @@ -458,6 +458,7 @@ void z_x86_page_fault_handler(struct arch_esf *esf) * the page is present in the kernel's page tables and the * instruction will just be re-tried, producing another fault. */ + was_valid_access = true; if (was_user && !z_x86_kpti_is_access_ok(virt, get_ptables(esf))) { was_valid_access = false; diff --git a/arch/x86/core/ia32/float.c b/arch/x86/core/ia32/float.c index e4102d803324f..c89bf7accd5a1 100644 --- a/arch/x86/core/ia32/float.c +++ b/arch/x86/core/ia32/float.c @@ -207,7 +207,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options) /* Associate the new FP context with the specified thread */ - if (thread == arch_current_thread()) { + if (thread == _current) { /* * When enabling FP support for the current thread, just claim * ownership of the FPU and leave CR0[TS] unset. @@ -222,7 +222,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options) * of the FPU to them (unless we need it ourselves). */ - if ((arch_current_thread()->base.user_options & _FP_USER_MASK) == 0) { + if ((_current->base.user_options & _FP_USER_MASK) == 0) { /* * We are not FP-capable, so mark FPU as owned by the * thread we've just enabled FP support for, then @@ -278,7 +278,7 @@ int z_float_disable(struct k_thread *thread) thread->base.user_options &= ~_FP_USER_MASK; - if (thread == arch_current_thread()) { + if (thread == _current) { z_FpAccessDisable(); _kernel.current_fp = (struct k_thread *)0; } else { @@ -314,7 +314,7 @@ void _FpNotAvailableExcHandler(struct arch_esf *pEsf) /* Enable highest level of FP capability configured into the kernel */ - k_float_enable(arch_current_thread(), _FP_USER_MASK); + k_float_enable(_current, _FP_USER_MASK); } _EXCEPTION_CONNECT_NOCODE(_FpNotAvailableExcHandler, IV_DEVICE_NOT_AVAILABLE, 0); diff --git a/arch/x86/core/reboot_rst_cnt.c b/arch/x86/core/reboot_rst_cnt.c index e20b5b7ae3345..3eafcf9709c96 100644 --- a/arch/x86/core/reboot_rst_cnt.c +++ b/arch/x86/core/reboot_rst_cnt.c @@ -27,12 +27,22 @@ static inline void cold_reboot(void) sys_out8(reset_value, X86_RST_CNT_REG); } +static inline void warm_reboot(void) +{ + uint8_t reset_value = X86_RST_CNT_CPU_RST | X86_RST_CNT_SYS_RST; + + sys_out8(reset_value, X86_RST_CNT_REG); +} + void __weak sys_arch_reboot(int type) { switch (type) { case SYS_REBOOT_COLD: cold_reboot(); break; + case SYS_REBOOT_WARM: + warm_reboot(); + break; default: /* do nothing */ break; diff --git a/arch/x86/core/userspace.c b/arch/x86/core/userspace.c index fd38d22cb90b0..436bc18edb73d 100644 --- a/arch/x86/core/userspace.c +++ b/arch/x86/core/userspace.c @@ -132,9 +132,9 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, /* Transition will reset stack pointer to initial, discarding * any old context since this is a one-way operation */ - stack_end = Z_STACK_PTR_ALIGN(arch_current_thread()->stack_info.start + - arch_current_thread()->stack_info.size - - arch_current_thread()->stack_info.delta); + stack_end = Z_STACK_PTR_ALIGN(_current->stack_info.start + + _current->stack_info.size - + _current->stack_info.delta); #ifdef CONFIG_X86_64 /* x86_64 SysV ABI requires 16 byte stack alignment, which @@ -156,15 +156,15 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, * Note that this also needs to page in the reserved * portion of the stack (which is usually the page just * before the beginning of stack in - * arch_current_thread()->stack_info.start. + * _current->stack_info.start. */ uintptr_t stack_start; size_t stack_size; uintptr_t stack_aligned_start; size_t stack_aligned_size; - stack_start = POINTER_TO_UINT(arch_current_thread()->stack_obj); - stack_size = K_THREAD_STACK_LEN(arch_current_thread()->stack_info.size); + stack_start = POINTER_TO_UINT(_current->stack_obj); + stack_size = K_THREAD_STACK_LEN(_current->stack_info.size); #if defined(CONFIG_X86_STACK_PROTECTION) /* With hardware stack protection, the first page of stack @@ -182,7 +182,7 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, #endif z_x86_userspace_enter(user_entry, p1, p2, p3, stack_end, - arch_current_thread()->stack_info.start); + _current->stack_info.start); CODE_UNREACHABLE; } diff --git a/arch/x86/core/x86_mmu.c b/arch/x86/core/x86_mmu.c index fdda995b3b07f..e4188b8670f84 100644 --- a/arch/x86/core/x86_mmu.c +++ b/arch/x86/core/x86_mmu.c @@ -421,7 +421,7 @@ void z_x86_tlb_ipi(const void *arg) /* We might have been moved to another memory domain, so always invoke * z_x86_thread_page_tables_get() instead of using current CR3 value. */ - ptables_phys = k_mem_phys_addr(z_x86_thread_page_tables_get(arch_current_thread())); + ptables_phys = k_mem_phys_addr(z_x86_thread_page_tables_get(_current)); #endif /* * In the future, we can consider making this smarter, such as @@ -1440,7 +1440,7 @@ static inline void bcb_fence(void) __pinned_func int arch_buffer_validate(const void *addr, size_t size, int write) { - pentry_t *ptables = z_x86_thread_page_tables_get(arch_current_thread()); + pentry_t *ptables = z_x86_thread_page_tables_get(_current); uint8_t *virt; size_t aligned_size; int ret = 0; @@ -1958,7 +1958,7 @@ int arch_mem_domain_thread_add(struct k_thread *thread) * IPI takes care of this if the thread is currently running on some * other CPU. */ - if (thread == arch_current_thread() && thread->arch.ptables != z_x86_cr3_get()) { + if (thread == _current && thread->arch.ptables != z_x86_cr3_get()) { z_x86_cr3_set(thread->arch.ptables); } #endif /* CONFIG_X86_KPTI */ @@ -1980,9 +1980,8 @@ void z_x86_current_stack_perms(void) /* Clear any previous context in the stack buffer to prevent * unintentional data leakage. */ - (void)memset((void *)arch_current_thread()->stack_info.start, 0xAA, - arch_current_thread()->stack_info.size - - arch_current_thread()->stack_info.delta); + (void)memset((void *)_current->stack_info.start, 0xAA, + _current->stack_info.size - _current->stack_info.delta); /* Only now is it safe to grant access to the stack buffer since any * previous context has been erased. @@ -1992,13 +1991,13 @@ void z_x86_current_stack_perms(void) * This will grant stack and memory domain access if it wasn't set * already (in which case this returns very quickly). */ - z_x86_swap_update_common_page_table(arch_current_thread()); + z_x86_swap_update_common_page_table(_current); #else /* Memory domain access is already programmed into the page tables. * Need to enable access to this new user thread's stack buffer in * its domain-specific page tables. */ - set_stack_perms(arch_current_thread(), z_x86_thread_page_tables_get(arch_current_thread())); + set_stack_perms(_current, z_x86_thread_page_tables_get(_current)); #endif } #endif /* CONFIG_USERSPACE */ diff --git a/arch/x86/ia32.cmake b/arch/x86/ia32.cmake index 5bf5018a32a19..90546924af141 100644 --- a/arch/x86/ia32.cmake +++ b/arch/x86/ia32.cmake @@ -3,7 +3,10 @@ # Find out if we are optimizing for size get_target_property(zephyr_COMPILE_OPTIONS zephyr_interface INTERFACE_COMPILE_OPTIONS) -if ("-Os" IN_LIST zephyr_COMPILE_OPTIONS) +#Any -Os is (or may be) wraped in $ guards +list(FILTER zephyr_COMPILE_OPTIONS INCLUDE REGEX "-Os") +list(LENGTH zephyr_COMPILE_OPTIONS have_os) +if (${have_os} GREATER 0) zephyr_cc_option(-mpreferred-stack-boundary=2) else() zephyr_compile_definitions(PERF_OPT) diff --git a/arch/x86/include/ia32/kernel_arch_func.h b/arch/x86/include/ia32/kernel_arch_func.h index 878281c7ba896..686bc18989b7f 100644 --- a/arch/x86/include/ia32/kernel_arch_func.h +++ b/arch/x86/include/ia32/kernel_arch_func.h @@ -37,6 +37,8 @@ arch_thread_return_value_set(struct k_thread *thread, unsigned int value) extern void arch_cpu_atomic_idle(unsigned int key); +int arch_swap(unsigned int key); + /* ASM code to fiddle with registers to enable the MMU with PAE paging */ void z_x86_enable_paging(void); diff --git a/arch/x86/include/x86_mmu.h b/arch/x86/include/x86_mmu.h index ed6bb59b37cb4..1a733485e3748 100644 --- a/arch/x86/include/x86_mmu.h +++ b/arch/x86/include/x86_mmu.h @@ -139,7 +139,7 @@ extern uint8_t z_shared_kernel_page_start; /* Called from page fault handler. ptables here is the ptage tables for the * faulting user thread and not the current set of page tables */ -extern bool z_x86_kpti_is_access_ok(void *virt, pentry_t *ptables) +extern bool z_x86_kpti_is_access_ok(void *virt, pentry_t *ptables); #endif /* CONFIG_DEMAND_PAGING */ #endif /* CONFIG_X86_KPTI */ #endif /* CONFIG_USERSPACE */ diff --git a/arch/xtensa/core/elf.c b/arch/xtensa/core/elf.c index 0ce9885eed66c..17337f4a7bc6f 100644 --- a/arch/xtensa/core/elf.c +++ b/arch/xtensa/core/elf.c @@ -33,15 +33,31 @@ LOG_MODULE_DECLARE(llext, CONFIG_LLEXT_LOG_LEVEL); #define R_XTENSA_SLOT0_OP 20 static void xtensa_elf_relocate(struct llext_loader *ldr, struct llext *ext, - const elf_rela_t *rel, uint8_t *text, uintptr_t addr, + const elf_rela_t *rel, uintptr_t addr, uint8_t *loc, int type, uint32_t stb) { elf_word *got_entry = (elf_word *)loc; switch (type) { case R_XTENSA_RELATIVE: + ; /* Relocate a local symbol: Xtensa specific. Seems to only be used with PIC */ - *got_entry += (uintptr_t)text - addr; + unsigned int sh_ndx; + + for (sh_ndx = 0; sh_ndx < ext->sect_cnt; sh_ndx++) { + if (ext->sect_hdrs[sh_ndx].sh_addr <= *got_entry && + *got_entry < + ext->sect_hdrs[sh_ndx].sh_addr + ext->sect_hdrs[sh_ndx].sh_size) + break; + } + + if (sh_ndx == ext->sect_cnt) { + LOG_ERR("%#x not found in any of the sections", *got_entry); + return; + } + + *got_entry += (uintptr_t)llext_loaded_sect_ptr(ldr, ext, sh_ndx) - + ext->sect_hdrs[sh_ndx].sh_addr; break; case R_XTENSA_GLOB_DAT: case R_XTENSA_JMP_SLOT: @@ -113,42 +129,39 @@ static void xtensa_elf_relocate(struct llext_loader *ldr, struct llext *ext, * @brief Architecture specific function for STB_LOCAL ELF relocations */ void arch_elf_relocate_local(struct llext_loader *ldr, struct llext *ext, const elf_rela_t *rel, - const elf_sym_t *sym, size_t got_offset, + const elf_sym_t *sym, uint8_t *rel_addr, const struct llext_load_param *ldr_parm) { - uint8_t *text = ext->mem[LLEXT_MEM_TEXT]; - uint8_t *loc = text + got_offset; int type = ELF32_R_TYPE(rel->r_info); uintptr_t sh_addr; if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) { - elf_shdr_t *shdr = llext_peek(ldr, ldr->hdr.e_shoff + - sym->st_shndx * ldr->hdr.e_shentsize); + elf_shdr_t *shdr = ext->sect_hdrs + sym->st_shndx; + + /* shdr->sh_addr is NULL when not built for a specific address */ sh_addr = shdr->sh_addr && (!ldr_parm->section_detached || !ldr_parm->section_detached(shdr)) ? - shdr->sh_addr : (uintptr_t)llext_peek(ldr, shdr->sh_offset); + shdr->sh_addr : (uintptr_t)llext_loaded_sect_ptr(ldr, ext, sym->st_shndx); } else { sh_addr = ldr->sects[LLEXT_MEM_TEXT].sh_addr; } - xtensa_elf_relocate(ldr, ext, rel, text, sh_addr, loc, type, ELF_ST_BIND(sym->st_info)); + xtensa_elf_relocate(ldr, ext, rel, sh_addr, rel_addr, type, ELF_ST_BIND(sym->st_info)); } /** * @brief Architecture specific function for STB_GLOBAL ELF relocations */ void arch_elf_relocate_global(struct llext_loader *ldr, struct llext *ext, const elf_rela_t *rel, - const elf_sym_t *sym, size_t got_offset, const void *link_addr) + const elf_sym_t *sym, uint8_t *rel_addr, const void *link_addr) { - uint8_t *text = ext->mem[LLEXT_MEM_TEXT]; - elf_word *got_entry = (elf_word *)(text + got_offset); int type = ELF32_R_TYPE(rel->r_info); /* For global relocations we expect the initial value for R_XTENSA_RELATIVE to be zero */ - if (type == R_XTENSA_RELATIVE && *got_entry) { - LOG_WRN("global: non-zero relative value %#x", *got_entry); + if (type == R_XTENSA_RELATIVE && *(elf_word *)rel_addr) { + LOG_WRN("global: non-zero relative value %#x", *(elf_word *)rel_addr); } - xtensa_elf_relocate(ldr, ext, rel, text, (uintptr_t)link_addr, (uint8_t *)got_entry, type, + xtensa_elf_relocate(ldr, ext, rel, (uintptr_t)link_addr, rel_addr, type, ELF_ST_BIND(sym->st_info)); } diff --git a/arch/xtensa/core/fatal.c b/arch/xtensa/core/fatal.c index 5721f130446a1..41a7a8d14097b 100644 --- a/arch/xtensa/core/fatal.c +++ b/arch/xtensa/core/fatal.c @@ -140,7 +140,7 @@ FUNC_NORETURN void arch_syscall_oops(void *ssf) #ifdef CONFIG_USERSPACE void z_impl_xtensa_user_fault(unsigned int reason) { - if ((arch_current_thread()->base.user_options & K_USER) != 0) { + if ((_current->base.user_options & K_USER) != 0) { if ((reason != K_ERR_KERNEL_OOPS) && (reason != K_ERR_STACK_CHK_FAIL)) { reason = K_ERR_KERNEL_OOPS; diff --git a/arch/xtensa/core/prep_c.c b/arch/xtensa/core/prep_c.c index 990915c5a4610..6dbab69f50f5f 100644 --- a/arch/xtensa/core/prep_c.c +++ b/arch/xtensa/core/prep_c.c @@ -13,6 +13,13 @@ extern FUNC_NORETURN void z_cstart(void); /* defined by the SoC in case of CONFIG_SOC_HAS_RUNTIME_NUM_CPUS=y */ extern void soc_num_cpus_init(void); +/* Make sure the platform configuration matches what the toolchain + * thinks the hardware is doing. + */ +#ifdef CONFIG_DCACHE_LINE_SIZE +BUILD_ASSERT(CONFIG_DCACHE_LINE_SIZE == XCHAL_DCACHE_LINESIZE); +#endif + /** * * @brief Prepare to and run C code diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index b6c8e8fb7fd32..c02ecc64b0dbe 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -1086,7 +1086,7 @@ static int mem_buffer_validate(const void *addr, size_t size, int write, int rin int ret = 0; uint8_t *virt; size_t aligned_size; - const struct k_thread *thread = arch_current_thread(); + const struct k_thread *thread = _current; uint32_t *ptables = thread_page_tables_get(thread); /* addr/size arbitrary, fix this up into an aligned region */ diff --git a/arch/xtensa/core/thread.c b/arch/xtensa/core/thread.c index 5bc736a352f2f..f9b8179173d4e 100644 --- a/arch/xtensa/core/thread.c +++ b/arch/xtensa/core/thread.c @@ -156,7 +156,7 @@ int arch_float_enable(struct k_thread *thread, unsigned int options) FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, void *p1, void *p2, void *p3) { - struct k_thread *current = arch_current_thread(); + struct k_thread *current = _current; size_t stack_end; /* Transition will reset stack pointer to initial, discarding diff --git a/arch/xtensa/core/vector_handlers.c b/arch/xtensa/core/vector_handlers.c index f721e480a2c43..fa58b9c2133ad 100644 --- a/arch/xtensa/core/vector_handlers.c +++ b/arch/xtensa/core/vector_handlers.c @@ -34,7 +34,7 @@ extern char xtensa_arch_kernel_oops_epc[]; bool xtensa_is_outside_stack_bounds(uintptr_t addr, size_t sz, uint32_t ps) { uintptr_t start, end; - struct k_thread *thread = arch_current_thread(); + struct k_thread *thread = _current; bool was_in_isr, invalid; /* Without userspace, there is no privileged stack so the thread stack diff --git a/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts b/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts index 219b6f1f99862..70f83f398e756 100644 --- a/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts +++ b/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts @@ -15,7 +15,7 @@ model = "01space ESP32C3 0.42 OLED"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/01space/esp32c3_042_oled/esp32c3_042_oled.yaml b/boards/01space/esp32c3_042_oled/esp32c3_042_oled.yaml index 4f9e9c93778fb..579094df44390 100644 --- a/boards/01space/esp32c3_042_oled/esp32c3_042_oled.yaml +++ b/boards/01space/esp32c3_042_oled/esp32c3_042_oled.yaml @@ -11,8 +11,4 @@ supported: - spi - uart - watchdog -testing: - ignore_tags: - - net - - bluetooth vendor: 01space diff --git a/boards/01space/esp32c3_042_oled/esp32c3_042_oled_defconfig b/boards/01space/esp32c3_042_oled/esp32c3_042_oled_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/01space/esp32c3_042_oled/esp32c3_042_oled_defconfig +++ b/boards/01space/esp32c3_042_oled/esp32c3_042_oled_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/96boards/aerocore2/96b_aerocore2.dts b/boards/96boards/aerocore2/96b_aerocore2.dts index dd5f8d8a89592..028887cef16a1 100644 --- a/boards/96boards/aerocore2/96b_aerocore2.dts +++ b/boards/96boards/aerocore2/96b_aerocore2.dts @@ -179,7 +179,7 @@ zephyr_udc0: &usbotg_fs { pinctrl-0 = <&adc1_in10_pc0 &adc1_in11_pc1 &adc1_in12_pc2 &adc1_in13_pc3>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/96boards/aerocore2/96b_aerocore2.yaml b/boards/96boards/aerocore2/96b_aerocore2.yaml index 6e704190fddae..01b0b6502fc81 100644 --- a/boards/96boards/aerocore2/96b_aerocore2.yaml +++ b/boards/96boards/aerocore2/96b_aerocore2.yaml @@ -9,7 +9,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - pwm diff --git a/boards/96boards/argonkey/96b_argonkey.dts b/boards/96boards/argonkey/96b_argonkey.dts index a7c02dcb8816a..e19b022c26af7 100644 --- a/boards/96boards/argonkey/96b_argonkey.dts +++ b/boards/96boards/argonkey/96b_argonkey.dts @@ -71,7 +71,9 @@ div-m = <8>; mul-n = <192>; div-r = <3>; - status = "okay"; + div-q = <4>; + clocks = <&clk_hse>; + status = "okay"; /* 48MHz on PLLI2SQ */ }; &rcc { diff --git a/boards/96boards/argonkey/96b_argonkey.yaml b/boards/96boards/argonkey/96b_argonkey.yaml index c0e086b60f20b..272af0c82ff7e 100644 --- a/boards/96boards/argonkey/96b_argonkey.yaml +++ b/boards/96boards/argonkey/96b_argonkey.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/boards/96boards/avenger96/96b_avenger96.yaml b/boards/96boards/avenger96/96b_avenger96.yaml index ef14d1b879d98..83b5f6af34381 100644 --- a/boards/96boards/avenger96/96b_avenger96.yaml +++ b/boards/96boards/avenger96/96b_avenger96.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - shell diff --git a/boards/96boards/carbon/96b_carbon_nrf51822.yaml b/boards/96boards/carbon/96b_carbon_nrf51822.yaml index 135d5aa461bd8..daa4501a13f55 100644 --- a/boards/96boards/carbon/96b_carbon_nrf51822.yaml +++ b/boards/96boards/carbon/96b_carbon_nrf51822.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - ble vendor: seeed diff --git a/boards/96boards/carbon/96b_carbon_stm32f401xe.yaml b/boards/96boards/carbon/96b_carbon_stm32f401xe.yaml index 4b0c56dc5a489..a0254053ca311 100644 --- a/boards/96boards/carbon/96b_carbon_stm32f401xe.yaml +++ b/boards/96boards/carbon/96b_carbon_stm32f401xe.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - ble diff --git a/boards/96boards/meerkat96/96b_meerkat96_mcimx7d_m4.yaml b/boards/96boards/meerkat96/96b_meerkat96_mcimx7d_m4.yaml index 39f57323369cb..d214e696cadcb 100644 --- a/boards/96boards/meerkat96/96b_meerkat96_mcimx7d_m4.yaml +++ b/boards/96boards/meerkat96/96b_meerkat96_mcimx7d_m4.yaml @@ -13,7 +13,6 @@ flash: 32 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - shell diff --git a/boards/96boards/neonkey/96b_neonkey.yaml b/boards/96boards/neonkey/96b_neonkey.yaml index 614eca9d2491a..0afdd5a71810e 100644 --- a/boards/96boards/neonkey/96b_neonkey.yaml +++ b/boards/96boards/neonkey/96b_neonkey.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 512 supported: diff --git a/boards/96boards/nitrogen/96b_nitrogen.yaml b/boards/96boards/nitrogen/96b_nitrogen.yaml index 12b1f6c73e100..43875e92ed925 100644 --- a/boards/96boards/nitrogen/96b_nitrogen.yaml +++ b/boards/96boards/nitrogen/96b_nitrogen.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - ble - gpio diff --git a/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts b/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts index 80281ae098d3c..f20a91c6acaf5 100644 --- a/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts +++ b/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts @@ -75,7 +75,9 @@ div-m = <8>; mul-n = <192>; div-r = <3>; - status = "okay"; + div-q = <4>; + clocks = <&clk_hse>; + status = "okay"; /* 48MHz on PLLI2SQ */ }; &rcc { diff --git a/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.yaml b/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.yaml index 160bb802380c6..ae6db8a815965 100644 --- a/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.yaml +++ b/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio diff --git a/boards/Kconfig b/boards/Kconfig index 8f186b32caf4f..40e8e5006e129 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -128,6 +128,20 @@ config QEMU_EXTRA_FLAGS to setup devices, for example to allocate interface for Zephyr GDBstub over serial with `-serial tcp:127.0.0.1:5678,server` +config BOARD_REQUIRES_SERIAL_BACKEND_CDC_ACM + bool + help + Indicates that a board has no other capabilities than to use the CDC + ACM UART as a backend for logging or shell. + +config BOARD_SERIAL_BACKEND_CDC_ACM + bool "Board uses USB CDC ACM UART as serial backend" + depends on BOARD_REQUIRES_SERIAL_BACKEND_CDC_ACM + default y + help + USB stack and CDC ACM UART are configured and initialized at boot + time to be used as a backend for logging or shell. + # There might not be any board options, hence the optional source osource "$(KCONFIG_BOARD_DIR)/Kconfig" endmenu diff --git a/boards/aconno/acn52832/acn52832.yaml b/boards/aconno/acn52832/acn52832.yaml index 72e04b829f901..be2495a5a492a 100644 --- a/boards/aconno/acn52832/acn52832.yaml +++ b/boards/aconno/acn52832/acn52832.yaml @@ -5,6 +5,5 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 diff --git a/boards/actinius/icarus/actinius_icarus_nrf9160_1_4_0.yaml b/boards/actinius/icarus/actinius_icarus_nrf9160_1_4_0.yaml index 119745e52edeb..1dda7976354db 100644 --- a/boards/actinius/icarus/actinius_icarus_nrf9160_1_4_0.yaml +++ b/boards/actinius/icarus/actinius_icarus_nrf9160_1_4_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 256 diff --git a/boards/actinius/icarus/actinius_icarus_nrf9160_2_0_0.yaml b/boards/actinius/icarus/actinius_icarus_nrf9160_2_0_0.yaml index f017d9c6f3c35..2c09e3c40aac6 100644 --- a/boards/actinius/icarus/actinius_icarus_nrf9160_2_0_0.yaml +++ b/boards/actinius/icarus/actinius_icarus_nrf9160_2_0_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 256 diff --git a/boards/actinius/icarus/actinius_icarus_nrf9160_ns_1_4_0.yaml b/boards/actinius/icarus/actinius_icarus_nrf9160_ns_1_4_0.yaml index 0733824966130..fd25e54d37fe9 100644 --- a/boards/actinius/icarus/actinius_icarus_nrf9160_ns_1_4_0.yaml +++ b/boards/actinius/icarus/actinius_icarus_nrf9160_ns_1_4_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/actinius/icarus/actinius_icarus_nrf9160_ns_2_0_0.yaml b/boards/actinius/icarus/actinius_icarus_nrf9160_ns_2_0_0.yaml index a6a5ecc7738bb..3d6cdb5b10cfc 100644 --- a/boards/actinius/icarus/actinius_icarus_nrf9160_ns_2_0_0.yaml +++ b/boards/actinius/icarus/actinius_icarus_nrf9160_ns_2_0_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160.yaml b/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160.yaml index 8fd851899ba33..af041509705b6 100644 --- a/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160.yaml +++ b/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 256 diff --git a/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.yaml b/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.yaml index 89b21ece17002..a2d50d9dd2785 100644 --- a/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.yaml +++ b/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/actinius/icarus_som/actinius_icarus_som_nrf9160.yaml b/boards/actinius/icarus_som/actinius_icarus_som_nrf9160.yaml index 1eab502534061..1a6ac77ff8c11 100644 --- a/boards/actinius/icarus_som/actinius_icarus_som_nrf9160.yaml +++ b/boards/actinius/icarus_som/actinius_icarus_som_nrf9160.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 256 diff --git a/boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.yaml b/boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.yaml index 0a6968beec278..e49b377cab12e 100644 --- a/boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.yaml +++ b/boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160.yaml b/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160.yaml index 3b7d7377caa83..56eebadfab1d8 100644 --- a/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160.yaml +++ b/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 256 diff --git a/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.yaml b/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.yaml index b41972384ba05..cd0a90c222be4 100644 --- a/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.yaml +++ b/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/adafruit/feather_m0_basic_proto/adafruit_feather_m0_basic_proto.yaml b/boards/adafruit/feather_m0_basic_proto/adafruit_feather_m0_basic_proto.yaml index 859ae9feb17fc..e8777b1a070fb 100644 --- a/boards/adafruit/feather_m0_basic_proto/adafruit_feather_m0_basic_proto.yaml +++ b/boards/adafruit/feather_m0_basic_proto/adafruit_feather_m0_basic_proto.yaml @@ -7,5 +7,4 @@ flash: 232 toolchain: - zephyr - gnuarmemb - - xtools vendor: adafruit diff --git a/boards/adafruit/feather_m0_lora/adafruit_feather_m0_lora.yaml b/boards/adafruit/feather_m0_lora/adafruit_feather_m0_lora.yaml index de9b44f8820a7..a448a5e177bdd 100644 --- a/boards/adafruit/feather_m0_lora/adafruit_feather_m0_lora.yaml +++ b/boards/adafruit/feather_m0_lora/adafruit_feather_m0_lora.yaml @@ -7,5 +7,4 @@ flash: 232 toolchain: - zephyr - gnuarmemb - - xtools vendor: adafruit diff --git a/boards/adafruit/feather_m4_express/adafruit_feather_m4_express-pinctrl.dtsi b/boards/adafruit/feather_m4_express/adafruit_feather_m4_express-pinctrl.dtsi index 34ddd2b858cbf..a96cf644f4025 100644 --- a/boards/adafruit/feather_m4_express/adafruit_feather_m4_express-pinctrl.dtsi +++ b/boards/adafruit/feather_m4_express/adafruit_feather_m4_express-pinctrl.dtsi @@ -35,10 +35,10 @@ pinmux = ; }; }; - pwm1_default: pwm1_default { + + tc0_default: tc0_default { group1 { - pinmux = , - ; + pinmux = ; }; }; diff --git a/boards/adafruit/feather_m4_express/adafruit_feather_m4_express.dts b/boards/adafruit/feather_m4_express/adafruit_feather_m4_express.dts index 374123bae71b0..a77a3d2b7ae9d 100644 --- a/boards/adafruit/feather_m4_express/adafruit_feather_m4_express.dts +++ b/boards/adafruit/feather_m4_express/adafruit_feather_m4_express.dts @@ -25,6 +25,7 @@ aliases { led0 = &led0; pwm-0 = &tcc0; + pwm-1 = &tc0; }; leds { @@ -70,6 +71,17 @@ pinctrl-names = "default"; }; +&tc0 { + status = "okay"; + compatible = "atmel,sam0-tc-pwm"; + prescaler = <1024>; + #pwm-cells = <2>; + channels = <2>; + counter-size = <16>; + pinctrl-0 = <&tc0_default>; + pinctrl-names = "default"; +}; + zephyr_udc0: &usb0 { status = "okay"; pinctrl-0 = <&usb_dc_default>; diff --git a/boards/adafruit/feather_m4_express/adafruit_feather_m4_express.yaml b/boards/adafruit/feather_m4_express/adafruit_feather_m4_express.yaml index a8d50925d9fbd..654b2eb902abd 100644 --- a/boards/adafruit/feather_m4_express/adafruit_feather_m4_express.yaml +++ b/boards/adafruit/feather_m4_express/adafruit_feather_m4_express.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - dma - gpio diff --git a/boards/adafruit/feather_m4_express/support/openocd.cfg b/boards/adafruit/feather_m4_express/support/openocd.cfg index e17a3034afe67..9990cf9036ad1 100644 --- a/boards/adafruit/feather_m4_express/support/openocd.cfg +++ b/boards/adafruit/feather_m4_express/support/openocd.cfg @@ -7,7 +7,7 @@ source [find target/atsame5x.cfg] # TODO(http://openocd.zylin.com/#/c/5706/): lower the clock speed to workaround # an erase timeout. -adapter_khz 500 +adapter speed 500 reset_config srst_only $_TARGETNAME configure -event gdb-attach { diff --git a/boards/adafruit/feather_nrf52840/Kconfig.defconfig b/boards/adafruit/feather_nrf52840/Kconfig.defconfig index bf56a00eebbc1..f6351510d2f3c 100644 --- a/boards/adafruit/feather_nrf52840/Kconfig.defconfig +++ b/boards/adafruit/feather_nrf52840/Kconfig.defconfig @@ -6,4 +6,10 @@ if BOARD_ADAFRUIT_FEATHER_NRF52840 +if BOARD_ADAFRUIT_FEATHER_NRF52840_NRF52840_UF2 || BOARD_ADAFRUIT_FEATHER_NRF52840_NRF52840_SENSE_UF2 + +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" + +endif + endif # BOARD_ADAFRUIT_FEATHER_NRF52840 diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml index 761f378dcaa81..31369a0280cf1 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense.yaml b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense.yaml index e4a94b6bb36ca..236e5aafd0732 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense.yaml +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.dts b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.dts index 719577abc0d44..faafb8381feb4 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.dts +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.dts @@ -8,19 +8,12 @@ /dts-v1/; #include "adafruit_feather_nrf52840_common.dtsi" #include +#include <../boards/common/usb/cdc_acm_serial.dtsi> / { model = "Adafruit Feather nRF52840 Sense"; compatible = "adafruit,feather-nrf52840-sense-uf2"; - chosen { - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,uart-mcumgr = &cdc_acm_uart0; - zephyr,bt-mon-uart = &cdc_acm_uart0; - zephyr,bt-c2h-uart = &cdc_acm_uart0; - }; - leds { led0: led_0 { gpios = <&gpio1 9 0>; @@ -34,9 +27,3 @@ reg = <0x44>; }; }; - -zephyr_udc0: &usbd { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; -}; diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml index a5f095b336b01..3756dc3c2a44e 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2_defconfig b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2_defconfig index 18c22c337d08d..42f7298af555a 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2_defconfig +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_sense_uf2_defconfig @@ -17,11 +17,5 @@ CONFIG_UART_CONSOLE=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y -# Logger cannot use itself to log -CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y - -# Enable USB -CONFIG_USB_DEVICE_STACK=y - # Build UF2 by default, supported by the Adafruit nRF52 Bootloader CONFIG_BUILD_OUTPUT_UF2=y diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.dts b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.dts index bc4f67a993190..f4c30d6aec090 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.dts +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.dts @@ -7,28 +7,15 @@ /dts-v1/; #include "adafruit_feather_nrf52840_common.dtsi" #include +#include <../boards/common/usb/cdc_acm_serial.dtsi> / { model = "Adafruit Feather nRF52840 Express"; compatible = "adafruit,feather-nrf52840-uf2"; - chosen { - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,uart-mcumgr = &cdc_acm_uart0; - zephyr,bt-mon-uart = &cdc_acm_uart0; - zephyr,bt-c2h-uart = &cdc_acm_uart0; - }; - leds { led0: led_0 { gpios = <&gpio1 15 0>; }; }; }; - -zephyr_udc0: &usbd { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; -}; diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.yaml b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.yaml index ebb7a399f0ca4..c61e5ae36f93c 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.yaml +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2_defconfig b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2_defconfig index f6ec209764648..a40094157e3ff 100644 --- a/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2_defconfig +++ b/boards/adafruit/feather_nrf52840/adafruit_feather_nrf52840_nrf52840_uf2_defconfig @@ -13,11 +13,5 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Logger cannot use itself to log -CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y - -# Enable USB -CONFIG_USB_DEVICE_STACK=y - # Build UF2 by default, supported by the Adafruit nRF52 Bootloader CONFIG_BUILD_OUTPUT_UF2=y diff --git a/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.yaml b/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.yaml index 858b4fcf6dbdd..31454fe166060 100644 --- a/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.yaml +++ b/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/adafruit/itsybitsy/Kconfig b/boards/adafruit/itsybitsy/Kconfig deleted file mode 100644 index 8aa3368ffd68e..0000000000000 --- a/boards/adafruit/itsybitsy/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# Adafruit ItsyBitsy nRF52840 Express board configuration - -# Copyright (c) 2022 Embla Flatlandsmo -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_SERIAL_BACKEND_CDC_ACM - bool "USB CDC" - default y - depends on BOARD_ADAFRUIT_ITSYBITSY diff --git a/boards/adafruit/itsybitsy/Kconfig.defconfig b/boards/adafruit/itsybitsy/Kconfig.defconfig index 7f71d774acf44..02cbfc35fe2cb 100644 --- a/boards/adafruit/itsybitsy/Kconfig.defconfig +++ b/boards/adafruit/itsybitsy/Kconfig.defconfig @@ -5,46 +5,6 @@ if BOARD_ADAFRUIT_ITSYBITSY -if BOARD_SERIAL_BACKEND_CDC_ACM - -config USB_DEVICE_STACK - default y - -config USB_CDC_ACM - default SERIAL - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y if CONSOLE - -config SHELL_BACKEND_SERIAL_CHECK_DTR - default SHELL - depends on UART_LINE_CTRL - -config UART_LINE_CTRL - default SHELL - -config USB_DEVICE_REMOTE_WAKEUP - default n - -if LOG - -# Logger cannot use itself to log -config USB_CDC_ACM_LOG_LEVEL - default 0 - -# Set USB log level to error only -config USB_DEVICE_LOG_LEVEL - default 1 - -# Wait 1500ms at startup for logging -config LOG_PROCESS_THREAD_STARTUP_DELAY_MS - default 1500 - -endif # LOG - -endif # BOARD_SERIAL_BACKEND_CDC_ACM +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_ADAFRUIT_ITSYBITSY diff --git a/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.dts b/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.dts index ee74d88694007..a4ff029e93b96 100644 --- a/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.dts +++ b/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.dts @@ -16,11 +16,6 @@ compatible = "adafruit,itsybitsy-nrf52840"; chosen { - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,uart-mcumgr = &cdc_acm_uart0; - zephyr,bt-mon-uart = &cdc_acm_uart0; - zephyr,bt-c2h-uart = &cdc_acm_uart0; zephyr,ieee802154 = &ieee802154; }; @@ -155,8 +150,6 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; }; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml b/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml index 9bf0ea72176c3..79072d2d015f1 100644 --- a/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml +++ b/boards/adafruit/itsybitsy/adafruit_itsybitsy_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/adafruit/itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml b/boards/adafruit/itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml index 7de6fd7a3f210..6a39f7553b2d9 100644 --- a/boards/adafruit/itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml +++ b/boards/adafruit/itsybitsy_m4_express/adafruit_itsybitsy_m4_express.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - dma - gpio diff --git a/boards/adafruit/kb2040/adafruit_kb2040.dts b/boards/adafruit/kb2040/adafruit_kb2040.dts index c79794217b54c..d7de09cddac74 100644 --- a/boards/adafruit/kb2040/adafruit_kb2040.dts +++ b/boards/adafruit/kb2040/adafruit_kb2040.dts @@ -122,3 +122,7 @@ zephyr_udc0: &usbd { regulator-always-on; regulator-allowed-modes = ; }; + +&xosc { + startup-delay-multiplier = <64>; +}; diff --git a/boards/adafruit/kb2040/adafruit_kb2040.yaml b/boards/adafruit/kb2040/adafruit_kb2040.yaml index 40511a7763308..9fb4564482804 100644 --- a/boards/adafruit/kb2040/adafruit_kb2040.yaml +++ b/boards/adafruit/kb2040/adafruit_kb2040.yaml @@ -7,7 +7,6 @@ ram: 264 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio diff --git a/boards/adafruit/macropad_rp2040/Kconfig b/boards/adafruit/macropad_rp2040/Kconfig new file mode 100644 index 0000000000000..fcfac0d53f724 --- /dev/null +++ b/boards/adafruit/macropad_rp2040/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Benjamin CabĂŠ +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ADAFRUIT_MACROPAD_RP2040 + select RP2_FLASH_W25Q080 diff --git a/boards/adafruit/macropad_rp2040/Kconfig.adafruit_macropad_rp2040 b/boards/adafruit/macropad_rp2040/Kconfig.adafruit_macropad_rp2040 new file mode 100644 index 0000000000000..dfa06268eae42 --- /dev/null +++ b/boards/adafruit/macropad_rp2040/Kconfig.adafruit_macropad_rp2040 @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Benjamin CabĂŠ +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ADAFRUIT_MACROPAD_RP2040 + select SOC_RP2040 diff --git a/boards/adafruit/macropad_rp2040/Kconfig.defconfig b/boards/adafruit/macropad_rp2040/Kconfig.defconfig new file mode 100644 index 0000000000000..d9ef74ce3e089 --- /dev/null +++ b/boards/adafruit/macropad_rp2040/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Benjamin CabĂŠ +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ADAFRUIT_MACROPAD_RP2040 + +if I2C_DW + +config I2C_DW_CLOCK_SPEED + default 125 + +endif # I2C_DW + +config USB_SELF_POWERED + default n + +endif # BOARD_ADAFRUIT_MACROPAD_RP2040 diff --git a/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040-pinctrl.dtsi b/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040-pinctrl.dtsi new file mode 100644 index 0000000000000..1a1953adb0ffd --- /dev/null +++ b/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040-pinctrl.dtsi @@ -0,0 +1,49 @@ +#include + +&pinctrl { + uart1_default: uart1_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + + spi1_default: spi1_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + group3 { + pinmux = ; + }; + }; + + ws2812_pio1_default: ws2812_pio1_default { + ws2812 { + pinmux = ; + }; + }; + + pwm_ch0a_default: pwm_ch0a_default { + group1 { + pinmux = ; + }; + }; +}; diff --git a/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040.dts b/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040.dts new file mode 100644 index 0000000000000..6181fbdd94dad --- /dev/null +++ b/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040.dts @@ -0,0 +1,239 @@ +/dts-v1/; + +#include +#include "adafruit_macropad_rp2040-pinctrl.dtsi" +#include +#include +#include + + +/ { + model = "Adafruit MacroPad RP2040"; + compatible = "adafruit,macropad-rp2040"; + + chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &ssi; + zephyr,code-partition = &code_partition; + zephyr,display = &oled; + }; + + aliases { + watchdog0 = &wdt0; + led-strip = &ws2812; + led0 = &led0; + }; + + speaker_reg: speaker-reg { + compatible = "regulator-fixed"; + regulator-name = "Speaker"; + enable-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; + }; + + keys { + compatible = "gpio-keys"; + + key0: key_0 { + gpios = <&gpio0 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key1: key_1 { + gpios = <&gpio0 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key2: key_2 { + gpios = <&gpio0 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key3: key_3 { + gpios = <&gpio0 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key4: key_4 { + gpios = <&gpio0 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key5: key_5 { + gpios = <&gpio0 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key6: key_6 { + gpios = <&gpio0 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key7: key_7 { + gpios = <&gpio0 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key8: key_8 { + gpios = <&gpio0 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key9: key_9 { + gpios = <&gpio0 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key10: key_10 { + gpios = <&gpio0 11 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + key11: key_11 { + gpios = <&gpio0 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + encoder_button: encoder_button { + gpios = <&gpio0 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; + label = "LED 0"; + }; + }; + + encoder { + compatible = "gpio-qdec"; + gpios = <&gpio0 17 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>, + <&gpio0 18 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,axis = ; + steps-per-period = <4>; + sample-time-us = <2000>; + idle-timeout-ms = <200>; + }; + + stemma_connector: stemma_connector { + compatible = "stemma-qt-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 21 0>, + <1 0 &gpio0 20 0>; + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(8)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the bootloader. The partition + * size is 8MB minus the 0x100 bytes taken by the bootloader. + */ + code_partition: partition@100 { + label = "code-partition"; + reg = <0x100 (DT_SIZE_M(8) - 0x100)>; + read-only; + }; + }; +}; + +&uart1 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart1_default>; + pinctrl-names = "default"; +}; + +/* You need to disable uart1 to use i2c0 */ +&i2c0 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + +&spi1 { + status = "okay"; + pinctrl-0 = <&spi1_default>; + pinctrl-names = "default"; + cs-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; + + oled: ssd1306@0 { + compatible = "sinowealth,sh1106"; + reg = <0>; + spi-max-frequency = <10000000>; + width = <128>; + height = <64>; + segment-offset = <2>; + page-offset = <0>; + display-offset = <0>; + multiplex-ratio = <63>; + prechargep = <0x1F>; + segment-remap; + com-invdir; + inversion-on; + reset-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; + data-cmd-gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>; + ready-time-ms = <100>; /* SH1106G needs 100ms delay after init */ + }; +}; + +&gpio0 { + status = "okay"; +}; + +&pwm { + pinctrl-0 = <&pwm_ch0a_default>; + pinctrl-names = "default"; + divider-int-0 = <255>; +}; + +&wdt0 { + status = "okay"; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&pio1 { + status = "okay"; + + pio-ws2812 { + compatible = "worldsemi,ws2812-rpi_pico-pio"; + status = "okay"; + pinctrl-0 = <&ws2812_pio1_default>; + pinctrl-names = "default"; + bit-waveform = <3>, <3>, <4>; + + ws2812: ws2812 { + status = "okay"; + gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>; + chain-length = <12>; + color-mapping = ; + reset-delay = <280>; + frequency = <800000>; + }; + }; +}; diff --git a/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040.yaml b/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040.yaml new file mode 100644 index 0000000000000..2d0030dd519a3 --- /dev/null +++ b/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040.yaml @@ -0,0 +1,25 @@ +identifier: adafruit_macropad_rp2040 +name: Adafruit MacroPad RP2040 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 264 +flash: 8192 +supported: + - uart + - gpio + - i2c + - spi + - hwinfo + - watchdog + - pwm + - flash + - dma + - counter + - clock + - usbd + - display + - qdec + - led_strip diff --git a/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040_defconfig b/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040_defconfig new file mode 100644 index 0000000000000..2fb65b600220c --- /dev/null +++ b/boards/adafruit/macropad_rp2040/adafruit_macropad_rp2040_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Benjamin CabĂŠ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=125000000 +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y +CONFIG_USE_DT_CODE_PARTITION=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_RESET=y +CONFIG_CLOCK_CONTROL=y diff --git a/boards/adafruit/macropad_rp2040/board.cmake b/boards/adafruit/macropad_rp2040/board.cmake new file mode 100644 index 0000000000000..4103e36e63569 --- /dev/null +++ b/boards/adafruit/macropad_rp2040/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(uf2 "--board-id=RPI-RP2") + +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) diff --git a/boards/adafruit/macropad_rp2040/board.yml b/boards/adafruit/macropad_rp2040/board.yml new file mode 100644 index 0000000000000..3b0daf408e062 --- /dev/null +++ b/boards/adafruit/macropad_rp2040/board.yml @@ -0,0 +1,6 @@ +board: + name: adafruit_macropad_rp2040 + full_name: Adafruit MacroPad RP2040 + vendor: adafruit + socs: + - name: rp2040 diff --git a/boards/adafruit/macropad_rp2040/doc/adafruit_macropad_rp2040.webp b/boards/adafruit/macropad_rp2040/doc/adafruit_macropad_rp2040.webp new file mode 100644 index 0000000000000..86f128d85ab5e Binary files /dev/null and b/boards/adafruit/macropad_rp2040/doc/adafruit_macropad_rp2040.webp differ diff --git a/boards/adafruit/macropad_rp2040/doc/index.rst b/boards/adafruit/macropad_rp2040/doc/index.rst new file mode 100644 index 0000000000000..7f2e78418cd8e --- /dev/null +++ b/boards/adafruit/macropad_rp2040/doc/index.rst @@ -0,0 +1,116 @@ +.. zephyr:board:: adafruit_macropad_rp2040 + +Adafruit MacroPad RP2040 +######################## + +Overview +******** + +The Adafruit MacroPad RP2040 is a 3x4 mechanical keyboard development board featuring +the Raspberry Pi RP2040 microcontroller. It includes 12 mechanical key switches with +individual RGB NeoPixels, a rotary encoder with push button, a 128x64 OLED display, +and a small speaker for audio feedback. + +Hardware +******** + +- Dual core Cortex-M0+ at up to 133MHz +- 264KB of SRAM +- 8MB of QSPI flash memory +- 12 mechanical key switches (Cherry MX compatible) +- 12 RGB NeoPixel LEDs (one per key) +- 128x64 monochrome OLED display (SH1106) +- Rotary encoder with push button +- Small speaker with Class D amplifier +- STEMMA QT / Qwiic I2C connector +- USB Type-C connector +- Reset button +- 4x M3 mounting holes + +Supported Features +****************** + +The ``adafruit_macropad_rp2040`` board target supports the following hardware features: + +.. list-table:: + :header-rows: 1 + + * - Peripheral + - Kconfig option + - Devicetree compatible + * - NVIC + - N/A + - :dtcompatible:`arm,v6m-nvic` + * - UART + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart` + * - GPIO + - :kconfig:option:`CONFIG_GPIO` + - :dtcompatible:`raspberrypi,pico-gpio` + * - ADC + - :kconfig:option:`CONFIG_ADC` + - :dtcompatible:`raspberrypi,pico-adc` + * - I2C + - :kconfig:option:`CONFIG_I2C` + - :dtcompatible:`snps,designware-i2c` + * - SPI + - :kconfig:option:`CONFIG_SPI` + - :dtcompatible:`raspberrypi,pico-spi` + * - USB Device + - :kconfig:option:`CONFIG_USB_DEVICE_STACK` + - :dtcompatible:`raspberrypi,pico-usbd` + * - HWINFO + - :kconfig:option:`CONFIG_HWINFO` + - N/A + * - Watchdog Timer (WDT) + - :kconfig:option:`CONFIG_WATCHDOG` + - :dtcompatible:`raspberrypi,pico-watchdog` + * - PWM + - :kconfig:option:`CONFIG_PWM` + - :dtcompatible:`raspberrypi,pico-pwm` + * - Flash + - :kconfig:option:`CONFIG_FLASH` + - :dtcompatible:`raspberrypi,pico-flash-controller` + * - UART (PIO) + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart-pio` + * - Display + - :kconfig:option:`CONFIG_DISPLAY` + - :dtcompatible:`sinowealth,sh1106` + * - LED Strip (12 pixels) + - :kconfig:option:`CONFIG_LED_STRIP` + - :dtcompatible:`worldsemi,ws2812-rpi_pico-pio` + * - Rotary Encoder + - :kconfig:option:`CONFIG_INPUT` + - :dtcompatible:`gpio-qdec` + +Programming and Debugging +************************* + +Applications for the ``adafruit_macropad_rp2040`` board target can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Building and Flashing +********************* + +The MacroPad RP2040 has a built-in UF2 bootloader which can be entered by holding down the rotary +encoder button (BOOT) and, while continuing to hold it, pressing and releasing the reset button. +A "RPI-RP2" drive should appear on your host machine. + +Here is an example for building and flashing the :zephyr:code-sample:`blinky` sample application +using UF2. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: adafruit_macropad_rp2040 + :goals: build flash + :flash-args: --runner uf2 + +References +********** + +.. target-notes:: + +- `Adafruit MacroPad RP2040 Product Page `_ +- `Adafruit MacroPad RP2040 Learn Guide `_ diff --git a/boards/adafruit/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml b/boards/adafruit/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml index 0bfa59a6c1b62..0f6b58a4163c7 100644 --- a/boards/adafruit/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml +++ b/boards/adafruit/nrf52_adafruit_feather/nrf52_adafruit_feather.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/adafruit/qt_py_esp32s3/Kconfig b/boards/adafruit/qt_py_esp32s3/Kconfig new file mode 100644 index 0000000000000..eff6376782392 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Ian Wakely + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 4096 if BOARD_ADAFRUIT_QT_PY_ESP32S3_ESP32S3_PROCPU + default 256 if BOARD_ADAFRUIT_QT_PY_ESP32S3_ESP32S3_APPCPU diff --git a/boards/adafruit/qt_py_esp32s3/Kconfig.adafruit_qt_py_esp32s3 b/boards/adafruit/qt_py_esp32s3/Kconfig.adafruit_qt_py_esp32s3 new file mode 100644 index 0000000000000..9d5e991b572c5 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/Kconfig.adafruit_qt_py_esp32s3 @@ -0,0 +1,9 @@ +# Adafruit ESP32S3 board configuration + +# Copyright (c) 2024 Ian Wakely + +config BOARD_ADAFRUIT_QT_PY_ESP32S3 + select SOC_ESP32S3_WROOM_N8 if "$(BOARD_REVISION)" = "" + select SOC_ESP32S3_WROOM_N4R2 if "$(BOARD_REVISION)" = "psram" + select SOC_ESP32S3_PROCPU if BOARD_ADAFRUIT_QT_PY_ESP32S3_ESP32S3_PROCPU + select SOC_ESP32S3_APPCPU if BOARD_ADAFRUIT_QT_PY_ESP32S3_ESP32S3_APPCPU diff --git a/boards/adafruit/qt_py_esp32s3/Kconfig.sysbuild b/boards/adafruit/qt_py_esp32s3/Kconfig.sysbuild new file mode 100644 index 0000000000000..3a2d17ac5cfd0 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_NONE +endchoice diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3-pinctrl.dtsi b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3-pinctrl.dtsi new file mode 100644 index 0000000000000..8c59416d21bfb --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3-pinctrl.dtsi @@ -0,0 +1,67 @@ +/* + * Copyright 2022 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + spim2_default: spim2_default { + group1 { + pinmux = , + ; + }; + group2 { + pinmux = ; + output-low; + }; + }; + + spim3_ws2812_led: spim3_ws2812_led { + group1 { + pinmux = ; + output-low; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; + + i2c1_default: i2c1_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; + + twai_default: twai_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu.dts b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu.dts new file mode 100644 index 0000000000000..876a6d78fc68f --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Ian Wakely + */ + +/dts-v1/; + +#include +#include "adafruit_qt_py_esp32s3-pinctrl.dtsi" +#include + +/ { + model = "Adafruit QT Py ESP32S3 APPCPU"; + compatible = "espressif,esp32s3"; + + chosen { + zephyr,sram = &sram1; + zephyr,ipc_shm = &shm0; + zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; + }; +}; + +&trng0 { + status = "okay"; +}; + +&ipm0 { + status = "okay"; +}; diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu.yaml b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu.yaml new file mode 100644 index 0000000000000..70b5253574ce6 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu.yaml @@ -0,0 +1,27 @@ +identifier: adafruit_qt_py_esp32s3/esp32s3/appcpu +name: Adafruit QT Py ESP32S3 APPCPU +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - uart +testing: + ignore_tags: + - net + - bluetooth + - flash + - cpp + - posix + - watchdog + - logging + - kernel + - pm + - gpio + - crypto + - eeprom + - heap + - cmsis_rtos + - jwt + - zdsp +vendor: adafruit diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_defconfig b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_defconfig new file mode 100644 index 0000000000000..48546641cadd6 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_defconfig @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CLOCK_CONTROL=y diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_psram.overlay b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_psram.overlay new file mode 100644 index 0000000000000..ac1ec4af1b19c --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_psram.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Ian Wakely + */ + +/delete-node/ &flash0; + +/ { + model = "Adafruit QT Py ESP32S3 PSRAM APPCPU"; + + soc { + flash: flash-controller@60002000 { + compatible = "espressif,esp32-flash-controller"; + reg = <0x60002000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + /* 4MB flash */ + flash0: flash@0 { + compatible = "soc-nv-flash"; + erase-block-size = <4096>; + write-block-size = <4>; + reg = <0x0 DT_SIZE_M(4)>; + }; + }; + }; +}; + +/* 2MB psram */ +&psram0 { + reg = <0x3c000000 DT_SIZE_M(2)>; + status = "okay"; +}; + +#include diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_psram.yaml b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_psram.yaml new file mode 100644 index 0000000000000..4d3dba70d68ca --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_appcpu_psram.yaml @@ -0,0 +1,27 @@ +identifier: adafruit_qt_py_esp32s3@psram/esp32s3/appcpu +name: Adafruit QT Py ESP32S3 PSRAM APPCPU +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - uart +testing: + ignore_tags: + - net + - bluetooth + - flash + - cpp + - posix + - watchdog + - logging + - kernel + - pm + - gpio + - crypto + - eeprom + - heap + - cmsis_rtos + - jwt + - zdsp +vendor: adafruit diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu.dts b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu.dts new file mode 100644 index 0000000000000..ac757645e5b57 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu.dts @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2023 Seeed Studio inc. + * Copyright (c) 2024 Ian Wakely + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include "adafruit_qt_py_esp32s3-pinctrl.dtsi" +#include "seeed_xiao_connector.dtsi" +#include + +/ { + model = "Adafruit QT Py ESP32S3 PROCPU"; + compatible = "seeed,xiao-esp32s3"; + + chosen { + zephyr,sram = &sram1; + zephyr,console = &usb_serial; + zephyr,shell-uart = &usb_serial; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; + }; + + aliases { + i2c-0 = &i2c0; + watchdog0 = &wdt0; + led-strip = &led_strip; + sw0 = &button0; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "User button"; + zephyr,code = ; + }; + }; +}; + +&usb_serial { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + +&i2c1 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; +}; + +&trng0 { + status = "okay"; +}; + +&spi2 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-0 = <&spim2_default>; + pinctrl-names = "default"; +}; + +&spi3 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-0 = <&spim3_ws2812_led>; + pinctrl-names = "default"; + + line-idle-low; + + led_strip: ws2812@0 { + compatible = "worldsemi,ws2812-spi"; + + /* SPI */ + reg = <0>; /* ignored, but necessary for SPI bindings */ + spi-max-frequency = <6400000>; + + /* WS2812 */ + chain-length = <1>; + spi-cpha; + spi-one-frame = <0xf0>; /* 11110000: 625 ns high and 625 ns low */ + spi-zero-frame = <0xc0>; /* 11000000: 312.5 ns high and 937.5 ns low */ + color-mapping = ; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; + + /* + * Unlike some of the other Adafruit boards, the neopixel on this board has + * its positive side hooked up to a GPIO pin rather than a positive voltage + * rail to save on power. This will enable the LED on board initialization. + */ + neopixel-power-enable { + gpio-hog; + gpios = <6 GPIO_ACTIVE_HIGH>; + output-high; + }; +}; + +&wdt0 { + status = "okay"; +}; + +&twai { + pinctrl-0 = <&twai_default>; + pinctrl-names = "default"; +}; + +&timer0 { + status = "okay"; +}; + +&timer1 { + status = "okay"; +}; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu.yaml b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu.yaml new file mode 100644 index 0000000000000..b3d1cd326ebd9 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu.yaml @@ -0,0 +1,19 @@ +identifier: adafruit_qt_py_esp32s3/esp32s3/procpu +name: Adafruit QT Py ESP32S3 PROCPU +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - gpio + - uart + - i2c + - i2s + - spi + - can + - counter + - watchdog + - entropy + - pwm + - dma +vendor: adafruit diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_defconfig b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_defconfig new file mode 100644 index 0000000000000..187793c76e8cc --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_defconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_psram.overlay b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_psram.overlay new file mode 100644 index 0000000000000..5ab0be63c3ffb --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_psram.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Ian Wakely + */ + +/delete-node/ &flash0; + +/ { + model = "Adafruit QT Py ESP32S3 PSRAM PROCPU"; + + soc { + flash: flash-controller@60002000 { + compatible = "espressif,esp32-flash-controller"; + reg = <0x60002000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + /* 4MB flash */ + flash0: flash@0 { + compatible = "soc-nv-flash"; + erase-block-size = <4096>; + write-block-size = <4>; + reg = <0x0 DT_SIZE_M(4)>; + }; + }; + }; +}; + +/* 2MB psram */ +&psram0 { + reg = <0x3c000000 DT_SIZE_M(2)>; + status = "okay"; +}; + +#include diff --git a/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_psram.yaml b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_psram.yaml new file mode 100644 index 0000000000000..37e6a7f15d66f --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/adafruit_qt_py_esp32s3_procpu_psram.yaml @@ -0,0 +1,19 @@ +identifier: adafruit_qt_py_esp32s3@psram/esp32s3/procpu +name: Adafruit QT Py ESP32S3 PSRAM PROCPU +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - gpio + - uart + - i2c + - i2s + - spi + - can + - counter + - watchdog + - entropy + - pwm + - dma +vendor: adafruit diff --git a/boards/adafruit/qt_py_esp32s3/board.cmake b/boards/adafruit/qt_py_esp32s3/board.cmake new file mode 100644 index 0000000000000..2f04d1fe8861e --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adafruit/qt_py_esp32s3/board.yml b/boards/adafruit/qt_py_esp32s3/board.yml new file mode 100644 index 0000000000000..c9b26924f8c39 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/board.yml @@ -0,0 +1,12 @@ +board: + name: adafruit_qt_py_esp32s3 + full_name: QT Py ESP32-S3 + vendor: adafruit + socs: + - name: esp32s3 + revision: + format: "custom" + default: "" + revisions: + - name: "" + - name: "psram" diff --git a/boards/adafruit/qt_py_esp32s3/doc/img/adafruit_qt_py_esp32s3.webp b/boards/adafruit/qt_py_esp32s3/doc/img/adafruit_qt_py_esp32s3.webp new file mode 100644 index 0000000000000..43637d31a6fa4 Binary files /dev/null and b/boards/adafruit/qt_py_esp32s3/doc/img/adafruit_qt_py_esp32s3.webp differ diff --git a/boards/adafruit/qt_py_esp32s3/doc/index.rst b/boards/adafruit/qt_py_esp32s3/doc/index.rst new file mode 100644 index 0000000000000..1c1f6e04eeeca --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/doc/index.rst @@ -0,0 +1,291 @@ +.. zephyr:board:: adafruit_qt_py_esp32s3 + +Overview +******** + +An Adafruit based Xiao compatible board based on the ESP32-S3, which is great +for IoT projects and prototyping with new sensors. + +For more details see the `Adafruit QT Py ESP32S3`_ product page. + +Hardware +******** + +This board comes in 2 variants, both based on the ESP32-S3 with WiFi and BLE +support. The default variant supporting 8MB of flash with no PSRAM, while the +``psram`` variant supporting 4MB of flash with 2MB of PSRAM. Both boards have a +USB-C port for programming and debugging and is based on a standard XIAO 14 +pin pinout. + +In addition to the Xiao compatible pinout, it also has a RGB NeoPixel for +status and debugging, a reset button, and a button for entering the ROM +bootloader or user input. Like many other Adafruit boards, it has a +`SparkFun Qwiic`_-compatible `STEMMA QT`_ connector for the I2C bus so you +don't even need to solder. + +ESP32-S3 is a low-power MCU-based system on a chip (SoC) with integrated +2.4 GHz Wi-Fi and BluetoothÂŽ Low Energy (Bluetooth LE). It consists of +high-performance dual-core microprocessor (XtensaÂŽ 32-bit LX7), a low power +coprocessor, a Wi-Fi baseband, a Bluetooth LE baseband, RF module, and +numerous peripherals. + +Supported Features +================== + +Current Zephyr's Adafruit QT Py ESP32-S3 board supports the following features: + ++------------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++============+============+=====================================+ +| UART | on-chip | serial port | ++------------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++------------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++------------+------------+-------------------------------------+ +| USB-JTAG | on-chip | hardware interface | ++------------+------------+-------------------------------------+ +| SPI Master | on-chip | spi | ++------------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++------------+------------+-------------------------------------+ +| I2S | on-chip | i2s | ++------------+------------+-------------------------------------+ +| TWAI/CAN | on-chip | can | ++------------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++------------+------------+-------------------------------------+ +| Timers | on-chip | counter | ++------------+------------+-------------------------------------+ +| Watchdog | on-chip | watchdog | ++------------+------------+-------------------------------------+ +| TRNG | on-chip | entropy | ++------------+------------+-------------------------------------+ +| LEDC | on-chip | pwm | ++------------+------------+-------------------------------------+ +| MCPWM | on-chip | pwm | ++------------+------------+-------------------------------------+ +| PCNT | on-chip | qdec | ++------------+------------+-------------------------------------+ +| GDMA | on-chip | dma | ++------------+------------+-------------------------------------+ +| Wi-Fi | on-chip | | ++------------+------------+-------------------------------------+ +| Bluetooth | on-chip | | ++------------+------------+-------------------------------------+ + +Prerequisites +------------- + +Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the +command below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Building & Flashing +******************* + +Simple boot +=========== + +The board could be loaded using the single binary image, without 2nd stage +bootloader. It is the default option when building the application without +additional configuration. + +.. note:: + + Simple boot does not provide any security features nor OTA updates. + +MCUboot bootloader +================== + +User may choose to use MCUboot bootloader instead. In that case the bootloader +must be built (and flashed) at least once. + +There are two options to be used when building an application: + +1. Sysbuild +2. Manual build + +.. note:: + + User can select the MCUboot bootloader by adding the following line + to the board default configuration file. + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y + +Sysbuild +======== + +The sysbuild makes possible to build and flash all necessary images needed to +bootstrap the board with the ESP32 SoC. + +To build the sample application using sysbuild use the command: + +.. zephyr-app-commands:: + :tool: west + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3 + :goals: build + :west-args: --sysbuild + :compact: + +By default, the ESP32 sysbuild creates bootloader (MCUboot) and application +images. But it can be configured to create other kind of images. + +Build directory structure created by sysbuild is different from traditional +Zephyr build. Output is structured by the domain subdirectories: + +.. code-block:: + + build/ + ├── hello_world + │ └── zephyr + │ ├── zephyr.elf + │ └── zephyr.bin + ├── mcuboot + │ └── zephyr + │ ├── zephyr.elf + │ └── zephyr.bin + └── domains.yaml + +.. note:: + + With ``--sysbuild`` option the bootloader will be re-build and re-flash + every time the pristine build is used. + +For more information about the system build please read the :ref:`sysbuild` documentation. + +Manual build +============ + +During the development cycle, it is intended to build & flash as quickly possible. +For that reason, images can be built one at a time using traditional build. + +The instructions following are relevant for both manual build and sysbuild. +The only difference is the structure of the build directory. + +.. note:: + + Remember that bootloader (MCUboot) needs to be flash at least once. + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. tabs:: + + .. group-tab:: QT Py ESP32S3 + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3/esp32s3/procpu + :goals: build + + .. group-tab:: QT Py ESP32S3 with PSRAM + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3@psram/esp32s3/procpu + :goals: build + +The usual ``flash`` target will work with the ``adafruit_qt_py_esp32s3`` board +configuration. Here is an example for the :zephyr:code-sample:`hello_world` +application. + +.. tabs:: + + .. group-tab:: QT Py ESP32S3 + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3/esp32s3/procpu + :goals: flash + + .. group-tab:: QT Py ESP32S3 with PSRAM + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3@psram/esp32s3/procpu + :goals: flash + +Open the serial monitor using the following command: + +.. code-block:: shell + + west espressif monitor + +After the board has automatically reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! adafruit_qt_py_esp32s3/esp32s3/procpu + +Debugging +********* + +ESP32-S3 support on OpenOCD is available at `OpenOCD ESP32`_. + +ESP32-S3 has a built-in JTAG circuitry and can be debugged without any +additional chip. Only an USB cable connected to the D+/D- pins is necessary. + +Further documentation can be obtained from the SoC vendor +in `JTAG debugging for ESP32-S3`_. + +Here is an example for building the :zephyr:code-sample:`hello_world` application. + +.. tabs:: + + .. group-tab:: QT Py ESP32S3 + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3/esp32s3/procpu + :goals: debug + + .. group-tab:: QT Py ESP32S3 with PSRAM + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3@psram/esp32s3/procpu + :goals: debug + +You can debug an application in the usual way. Here is an example for +the :zephyr:code-sample:`hello_world` application. + +.. tabs:: + + .. group-tab:: QT Py ESP32S3 + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3/esp32s3/procpu + :goals: debug + + .. group-tab:: QT Py ESP32S3 with PSRAM + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: adafruit_qt_py_esp32s3@psram/esp32s3/procpu + :goals: debug + +References +********** + +.. target-notes:: + +.. _`Adafruit QT Py ESP32S3`: https://www.adafruit.com/product/5426 +.. _`Adafruit QT Py ESP32S3 - PSRAM`: https://www.adafruit.com/product/5700 +.. _`JTAG debugging for ESP32-S3`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/jtag-debugging/ +.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases +.. _`SparkFun Qwiic`: https://www.sparkfun.com/qwiic +.. _`STEMMA QT`: https://learn.adafruit.com/introducing-adafruit-stemma-qt diff --git a/boards/adafruit/qt_py_esp32s3/revision.cmake b/boards/adafruit/qt_py_esp32s3/revision.cmake new file mode 100644 index 0000000000000..26aeb65f775ef --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/revision.cmake @@ -0,0 +1,3 @@ +if(DEFINED BOARD_REVISION AND NOT BOARD_REVISION STREQUAL "psram") + message(FATAL_ERROR "Invalid board revision, ${BOARD_REVISION}, valid revisions are: (for non-PSRAM version), psram") +endif() diff --git a/boards/adafruit/qt_py_esp32s3/seeed_xiao_connector.dtsi b/boards/adafruit/qt_py_esp32s3/seeed_xiao_connector.dtsi new file mode 100644 index 0000000000000..39880f7c942d8 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/seeed_xiao_connector.dtsi @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Ian Wakely + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + xiao_d: connector { + compatible = "seeed,xiao-gpio"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 18 0>, /* D0 */ + <1 0 &gpio0 17 0>, /* D1 */ + <2 0 &gpio0 9 0>, /* D2 */ + <3 0 &gpio0 8 0>, /* D3 */ + <4 0 &gpio0 7 0>, /* D4 */ + <5 0 &gpio0 6 0>, /* D5 */ + <6 0 &gpio0 5 0>, /* D6 */ + <7 0 &gpio0 16 0>, /* D7 */ + <8 0 &gpio1 4 0>, /* D8 */ + <9 0 &gpio1 5 0>, /* D9 */ + <10 0 &gpio1 3 0>; /* D10 */ + }; +}; + +xiao_spi: &spi2 {}; +xiao_i2c: &i2c0 {}; +xiao_serial: &uart0 {}; +xiao_adc: &adc0 {}; diff --git a/boards/adafruit/qt_py_esp32s3/support/openocd.cfg b/boards/adafruit/qt_py_esp32s3/support/openocd.cfg new file mode 100644 index 0000000000000..2f740b4a36ab1 --- /dev/null +++ b/boards/adafruit/qt_py_esp32s3/support/openocd.cfg @@ -0,0 +1,7 @@ +set ESP_RTOS none +set ESP32_ONLYCPU 1 + +# Source the JTAG interface configuration file +source [find interface/esp_usb_jtag.cfg] +# Source the ESP32-S3 configuration file +source [find target/esp32s3.cfg] diff --git a/boards/adafruit/qt_py_rp2040/adafruit_qt_py_rp2040.dts b/boards/adafruit/qt_py_rp2040/adafruit_qt_py_rp2040.dts index 94fca20837c2d..3f87e4188b228 100644 --- a/boards/adafruit/qt_py_rp2040/adafruit_qt_py_rp2040.dts +++ b/boards/adafruit/qt_py_rp2040/adafruit_qt_py_rp2040.dts @@ -152,3 +152,7 @@ zephyr_udc0: &usbd { regulator-always-on; regulator-allowed-modes = ; }; + +&xosc { + startup-delay-multiplier = <64>; +}; diff --git a/boards/adafruit/qt_py_rp2040/adafruit_qt_py_rp2040.yaml b/boards/adafruit/qt_py_rp2040/adafruit_qt_py_rp2040.yaml index 2348e9cec55c2..132cfe81087c5 100644 --- a/boards/adafruit/qt_py_rp2040/adafruit_qt_py_rp2040.yaml +++ b/boards/adafruit/qt_py_rp2040/adafruit_qt_py_rp2040.yaml @@ -7,7 +7,6 @@ ram: 264 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio diff --git a/boards/adafruit/trinket_m0/adafruit_trinket_m0.yaml b/boards/adafruit/trinket_m0/adafruit_trinket_m0.yaml index f1d21a5c63db7..cc4b9bc37389a 100644 --- a/boards/adafruit/trinket_m0/adafruit_trinket_m0.yaml +++ b/boards/adafruit/trinket_m0/adafruit_trinket_m0.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - counter diff --git a/boards/adi/ad_swiot1l_sl/Kconfig.ad_swiot1l_sl b/boards/adi/ad_swiot1l_sl/Kconfig.ad_swiot1l_sl new file mode 100644 index 0000000000000..b8b2e0fed8164 --- /dev/null +++ b/boards/adi/ad_swiot1l_sl/Kconfig.ad_swiot1l_sl @@ -0,0 +1,7 @@ +# AD-SWIOT1L-SL board configuration + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_AD_SWIOT1L_SL + select SOC_MAX32650 diff --git a/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl.dts b/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl.dts new file mode 100644 index 0000000000000..d46ad87c1cf9e --- /dev/null +++ b/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl.dts @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include + +/ { + model = "Analog Devices AD-SWIOT1L-SL"; + compatible = "adi,ad_swiot1l_sl"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led_1 { + gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + + led2: led_2 { + gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0_tx_p2_12 &uart0_rx_p2_11>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; diff --git a/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl.yaml b/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl.yaml new file mode 100644 index 0000000000000..495481a989db0 --- /dev/null +++ b/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl.yaml @@ -0,0 +1,13 @@ +identifier: ad_swiot1l_sl +name: ad_swiot1l_sl +vendor: adi +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - serial +ram: 1024 +flash: 3072 diff --git a/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl_defconfig b/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl_defconfig new file mode 100644 index 0000000000000..9428e5334a08f --- /dev/null +++ b/boards/adi/ad_swiot1l_sl/ad_swiot1l_sl_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/ad_swiot1l_sl/board.cmake b/boards/adi/ad_swiot1l_sl/board.cmake new file mode 100644 index 0000000000000..716d812146114 --- /dev/null +++ b/boards/adi/ad_swiot1l_sl/board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=MAX32650" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/ad_swiot1l_sl/board.yml b/boards/adi/ad_swiot1l_sl/board.yml new file mode 100644 index 0000000000000..f458ef3b9e896 --- /dev/null +++ b/boards/adi/ad_swiot1l_sl/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: ad_swiot1l_sl + full_name: AD-SWIOT1L-SL + vendor: adi + socs: + - name: max32650 diff --git a/boards/adi/ad_swiot1l_sl/doc/img/ad_swiot1l_sl.webp b/boards/adi/ad_swiot1l_sl/doc/img/ad_swiot1l_sl.webp new file mode 100644 index 0000000000000..6b734dc80b45a Binary files /dev/null and b/boards/adi/ad_swiot1l_sl/doc/img/ad_swiot1l_sl.webp differ diff --git a/boards/adi/ad_swiot1l_sl/doc/index.rst b/boards/adi/ad_swiot1l_sl/doc/index.rst new file mode 100644 index 0000000000000..47d1cbd66671b --- /dev/null +++ b/boards/adi/ad_swiot1l_sl/doc/index.rst @@ -0,0 +1,123 @@ +.. zephyr:board:: ad_swiot1l_sl + +Overview +******** +The AD-SWIOT1L-SL is a complete hardware and software platform for prototyping intelligent, +secure, network-capable field devices, with applications in factory automation, process +control, and intelligent buildings. + +The Zephyr port is running on the MAX32650 MCU. + +.. image:: img/ad_swiot1l_sl.webp + :align: center + :alt: AD-SWIOT1L-SL Front + +Hardware +******** + +- MAX32650 MCU: + + - Ultra-Efficient Microcontroller for Battery-Powered Applications + + - 120MHz Arm Cortex-M4 Processor with FPU + - SmartDMA Provides Background Memory Transfers with Programmable Data Processing + - 120MHz High-Speed and 50MHz Low-Power Oscillators + - 7.3728MHz Low-Power Oscillators + - 32.768kHz and RTC Clock (Requires External Crystal) + - 8kHz, Always-On, Ultra-Low-Power Oscillator + - 3MB Internal Flash, 1MB Internal SRAM + - 104ÎźW/MHz Executing from Cache at 1.1V + - Five Low-Power Modes: Active, Sleep, Background, Deep Sleep, and Backup + - 1.8V and 3.3V I/O with No Level Translators + + - Scalable Cached External Memory Interfaces: + + - 120MB/s HyperBus/Xccela DDR Interface + - SPIXF/SPIXR for External Flash/RAM Expansion + - 240Mbps SDHC/eMMC/SDIO/microSD Interface + + - Optimal Peripheral Mix Provides Platform Scalability + + - 16-Channel DMA + - Three SPI Master (60MHz)/Slave (48MHz) + - One QuadSPI Master (60MHz)/Slave (48MHz) + - Up to Three 4Mbaud UARTs with Flow Control + - Two 1MHz I2C Master/Slave + - I2S Slave + - Four-Channel, 7.8ksps, 10-Bit Delta-Sigma ADC + - USB 2.0 Hi-Speed Device Interface with PHY + - 16 Pulse Train Generators + - Six 32-Bit Timers with 8mA High Drive + - 1-WireÂŽ Master + + - Trust Protection Unit (TPU) for IP/Data Security + + - Modular Arithmetic Accelerator (MAA), True Random Number Generator (TRNG) + - Secure Nonvolatile Key Storage, SHA-256, AES-128/192/256 + - Memory Decryption Integrity Unit, Secure Boot ROM + +- External devices connected to the AD-SWIOT1L-SL: + + - On-Board HyperRAM + - On-Board QSPI Flash + - MAXQ1065 Ultralow Power Cryptographic Controller with ChipDNA + - ADIN1110 Robust, Industrial, Low Power 10BASE-T1L Ethernet MAC-PHY + - 2-Pin external power supply terminal block (24V DC) + - ADP1032 high performance, isolated micropower management unit (PMU) + - SWD 10-Pin Header + - On-Board 3.3V, 1.8V, and 1.1V voltage regulators + - AD74413R Quad-channel, Software Configurable I/O + - MAX14906 Quad-channel, Industrial Digital I/O + - Two general-purpose LEDs + +Supported Features +================== + +The ``ad_swiot1l_sl`` board supports the following interfaces: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ + +Programming and Debugging +************************* + +Flashing +======== +The MAX32650 MCU can be flashed by connecting an external debug probe to the +SWD port. SWD debug can be accessed through the Cortex 10-pin connector, J3. +Logic levels are fixed to VDDIO (1.8V). + +Once the debug probe is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. + +.. note:: + + This board uses OpenOCD as the default debug interface. You can also use + a Segger J-Link with Segger's native tooling by overriding the runner, + appending ``--runner jlink`` to your ``west`` command(s). The J-Link should + be connected to the standard 2*5 pin debug connector (J3) using an + appropriate adapter board and cable + +Debugging +========= +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `AD-SWIOT1L-SL web page`_ + +.. _AD-SWIOT1L-SL web page: + https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/AD-SWIOT1L-SL.html diff --git a/boards/adi/apard32690/apard32690_max32690_m4.yaml b/boards/adi/apard32690/apard32690_max32690_m4.yaml index bc040f86855f5..bf6486d175b38 100644 --- a/boards/adi/apard32690/apard32690_max32690_m4.yaml +++ b/boards/adi/apard32690/apard32690_max32690_m4.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_serial diff --git a/boards/adi/apard32690/board.cmake b/boards/adi/apard32690/board.cmake index 409b85f0bc14a..d388c9a7497e0 100644 --- a/boards/adi/apard32690/board.cmake +++ b/boards/adi/apard32690/board.cmake @@ -1,9 +1,8 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32690.cfg]") board_runner_args(jlink "--device=MAX32690" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/apard32690/doc/index.rst b/boards/adi/apard32690/doc/index.rst index 8223f2b88e981..edd879bd3ddc3 100644 --- a/boards/adi/apard32690/doc/index.rst +++ b/boards/adi/apard32690/doc/index.rst @@ -190,7 +190,8 @@ SWD port. SWD debug can be accessed through the Cortex 10-pin connector, P9. Logic levels are either 1.8V or 3.3V (based on P51 selection). Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: @@ -209,7 +210,7 @@ instead of ``west flash``. References ********** -- `AD-APARD32690-SL web page`_ +- `AD-APARD32690-SL solution center`_ -.. _AD-APARD32690-SL web page: - https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/ad-apard32690-sl.html +.. _AD-APARD32690-SL solution center: + https://developer.analog.com/solutions/max32690 diff --git a/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml b/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml index c7e9a79567ace..c7746597fa4e5 100644 --- a/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml +++ b/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 640 flash: 2048 supported: diff --git a/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml b/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml index bddea6e4a7618..c0c48cce543d9 100644 --- a/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml +++ b/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 640 flash: 2048 supported: diff --git a/boards/adi/max32650evkit/Kconfig.max32650evkit b/boards/adi/max32650evkit/Kconfig.max32650evkit new file mode 100644 index 0000000000000..accb9f0e0f31b --- /dev/null +++ b/boards/adi/max32650evkit/Kconfig.max32650evkit @@ -0,0 +1,7 @@ +# MAX32650EVKIT boards configuration + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX32650EVKIT + select SOC_MAX32650 diff --git a/boards/adi/max32650evkit/board.cmake b/boards/adi/max32650evkit/board.cmake new file mode 100644 index 0000000000000..716d812146114 --- /dev/null +++ b/boards/adi/max32650evkit/board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=MAX32650" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32650evkit/board.yml b/boards/adi/max32650evkit/board.yml new file mode 100644 index 0000000000000..24e70315fb5e4 --- /dev/null +++ b/boards/adi/max32650evkit/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max32650evkit + full_name: MAX32650EVKIT + vendor: adi + socs: + - name: max32650 diff --git a/boards/adi/max32650evkit/doc/img/max32650evkit.webp b/boards/adi/max32650evkit/doc/img/max32650evkit.webp new file mode 100644 index 0000000000000..1300e5e44b910 Binary files /dev/null and b/boards/adi/max32650evkit/doc/img/max32650evkit.webp differ diff --git a/boards/adi/max32650evkit/doc/index.rst b/boards/adi/max32650evkit/doc/index.rst new file mode 100644 index 0000000000000..9d5a6ccaff39e --- /dev/null +++ b/boards/adi/max32650evkit/doc/index.rst @@ -0,0 +1,119 @@ +.. zephyr:board:: max32650evkit + +Overview +******** +The MAX32650 evaluation kit (EV kit) provides a platform for evaluating the +capabilities of the MAX32650 ultra-low power memory-scalable microcontroller +designed specifically for high performance battery powered applications. + +The Zephyr port is running on the MAX32650 MCU. + +.. image:: img/max32650evkit.webp + :align: center + :alt: MAX32650 EVKIT Front + +Hardware +******** + +- MAX32650 MCU: + + - Ultra Efficient Microcontroller for Battery-Powered Applications + + - 120MHz Arm Cortex-M4 with FPU + - SmartDMA Provides Background Memory Transfers with Programmable Data Processing + - 120MHz High-Speed and 50MHz Low-Power Oscillators + - 7.3728MHz Low Power Oscillators + - 32.768kHz and RTC Clock (Requires External Crystal) + - 8kHz, Always-on, Ultra-Low-Power Oscillator + - 3MB Internal Flash, 1MB Internal SRAM + - 104ÂľW/MHz Executing from Cache at 1.1V + - Five Low-Power Modes: Active, Sleep, Background, Deep-Sleep, and Backup + - 1.8V and 3.3V I/O with No Level Translators + - Programming and Debugging + + - Scalable Cached External Memory Interfaces + + - 120MB/s HyperBus/Xccela DDR Interface + - SPIXF/SPIXR for External Flash/RAM Expansion + - 240Mbps SDHC/eMMC/SDIO/microSD Interface + + - Optimal Peripheral Mix Provides Platform Scalability + + - 16-Channel DMA + - Three SPI Master (60MHz)/Slave (48MHz) + - One QuadSPI Master (60MHz)/Slave (48MHz) + - Up to Three 4Mbaud UARTs with Flow Control + - Two 1MHz I2C Master/Slave + - I2S Slave + - Four-Channel, 7.8ksps, 10-bit Delta-Sigma ADC + - USB 2.0 Hi-Speed Device Interface with PHY + - 16 Pulse Train Generators + - Six 32-bit Timers with 8mA Hi-Drive + - 1-WireÂŽ Master + + - Trust Protection Unit (TPU) for IP/Data and Security + + - Modular Arithmetic Accelerator (MAA), True Random Number Generator (TRNG) + - Secure Nonvolatile Key Storage, SHA-256, AES-128/192/256 + - Memory Decryption Integrity Unit, Secure Boot ROM + +- External devices connected to the MAX32650EVKIT: + + - 3.5in 320 x 240 Color TFT Display + - 64MB HyperRAM + - 64MB XIP Flash + - 1MB XIP RAM + - USB 2.0 Micro B + - Two General-Purpose LEDs and Two GeneralPurpose Pushbutton Switches + +Supported Features +================== + +The ``max32650evkit`` board supports the following interfaces: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ + +Programming and Debugging +************************* + +Flashing +======== +The MAX32650 MCU can be flashed by connecting an external debug probe to the +SWD port. SWD debug can be accessed through the Cortex 10-pin connector, J3. +Logic levels are fixed to VDDIO (1.8V). + +Once the debug probe is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. + +.. note:: + + This board uses OpenOCD as the default debug interface. You can also use + a Segger J-Link with Segger's native tooling by overriding the runner, + appending ``--runner jlink`` to your ``west`` command(s). The J-Link should + be connected to the standard 2*5 pin debug connector (J3) using an + appropriate adapter board and cable + +Debugging +========= +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `MAX32650EVKIT web page`_ + +.. _MAX32650EVKIT web page: + https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650-evkit.html diff --git a/boards/adi/max32650evkit/max32650evkit.dts b/boards/adi/max32650evkit/max32650evkit.dts new file mode 100644 index 0000000000000..2292bfd8b8ac4 --- /dev/null +++ b/boards/adi/max32650evkit/max32650evkit.dts @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include + +/ { + model = "Analog Devices MAX32650EVKIT"; + compatible = "adi,max32650evkit"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led_1 { + gpios = <&gpio2 25 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + + led2: led_2 { + gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + pb1: pb1 { + gpios = <&gpio2 28 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + zephyr,code = ; + }; + + pb2: pb2 { + gpios = <&gpio2 30 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW3"; + zephyr,code = ; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0_tx_p2_12 &uart0_rx_p2_11>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; diff --git a/boards/adi/max32650evkit/max32650evkit.yaml b/boards/adi/max32650evkit/max32650evkit.yaml new file mode 100644 index 0000000000000..8e3ced3c43711 --- /dev/null +++ b/boards/adi/max32650evkit/max32650evkit.yaml @@ -0,0 +1,13 @@ +identifier: max32650evkit +name: max32650evkit +vendor: adi +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - serial +ram: 1024 +flash: 3072 diff --git a/boards/adi/max32650evkit/max32650evkit_defconfig b/boards/adi/max32650evkit/max32650evkit_defconfig new file mode 100644 index 0000000000000..9428e5334a08f --- /dev/null +++ b/boards/adi/max32650evkit/max32650evkit_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/max32650fthr/Kconfig.max32650fthr b/boards/adi/max32650fthr/Kconfig.max32650fthr new file mode 100644 index 0000000000000..cf8acafe85d82 --- /dev/null +++ b/boards/adi/max32650fthr/Kconfig.max32650fthr @@ -0,0 +1,7 @@ +# MAX32650FTHR board configuration + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX32650FTHR + select SOC_MAX32650 diff --git a/boards/adi/max32650fthr/board.cmake b/boards/adi/max32650fthr/board.cmake new file mode 100644 index 0000000000000..716d812146114 --- /dev/null +++ b/boards/adi/max32650fthr/board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=MAX32650" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32650fthr/board.yml b/boards/adi/max32650fthr/board.yml new file mode 100644 index 0000000000000..46dee2be23394 --- /dev/null +++ b/boards/adi/max32650fthr/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max32650fthr + full_name: MAX32650FTHR + vendor: adi + socs: + - name: max32650 diff --git a/boards/adi/max32650fthr/doc/img/max32650fthr.webp b/boards/adi/max32650fthr/doc/img/max32650fthr.webp new file mode 100644 index 0000000000000..065de009e8cfa Binary files /dev/null and b/boards/adi/max32650fthr/doc/img/max32650fthr.webp differ diff --git a/boards/adi/max32650fthr/doc/index.rst b/boards/adi/max32650fthr/doc/index.rst new file mode 100644 index 0000000000000..b9e71d4931766 --- /dev/null +++ b/boards/adi/max32650fthr/doc/index.rst @@ -0,0 +1,118 @@ +.. zephyr:board:: max32650fthr + +Overview +******** +The MAX32650FTHR evaluation kit provides a platform for evaluating the capabilities +of the MAX32650 ultra-low-power memory-scalable microcontroller designed specifically +for high-performance, battery-powered applications. + +The Zephyr port is running on the MAX32650 MCU. + +.. image:: img/max32650fthr.webp + :align: center + :alt: MAX32650 FTHR Front + +Hardware +******** + +- MAX32650 MCU: + + - Ultra Efficient Microcontroller for Battery-Powered Applications + + - 120MHz Arm Cortex-M4 with FPU + - SmartDMA Provides Background Memory Transfers with Programmable Data Processing + - 120MHz High-Speed and 50MHz Low-Power Oscillators + - 7.3728MHz Low Power Oscillators + - 32.768kHz and RTC Clock (Requires External Crystal) + - 8kHz, Always-on, Ultra-Low-Power Oscillator + - 3MB Internal Flash, 1MB Internal SRAM + - 104ÂľW/MHz Executing from Cache at 1.1V + - Five Low-Power Modes: Active, Sleep, Background, Deep-Sleep, and Backup + - 1.8V and 3.3V I/O with No Level Translators + - Programming and Debugging + + - Scalable Cached External Memory Interfaces + + - 120MB/s HyperBus/Xccela DDR Interface + - SPIXF/SPIXR for External Flash/RAM Expansion + - 240Mbps SDHC/eMMC/SDIO/microSD Interface + + - Optimal Peripheral Mix Provides Platform Scalability + + - 16-Channel DMA + - Three SPI Master (60MHz)/Slave (48MHz) + - One QuadSPI Master (60MHz)/Slave (48MHz) + - Up to Three 4Mbaud UARTs with Flow Control + - Two 1MHz I2C Master/Slave + - I2S Slave + - Four-Channel, 7.8ksps, 10-bit Delta-Sigma ADC + - USB 2.0 Hi-Speed Device Interface with PHY + - 16 Pulse Train Generators + - Six 32-bit Timers with 8mA Hi-Drive + - 1-WireÂŽ Master + + - Trust Protection Unit (TPU) for IP/Data and Security + + - Modular Arithmetic Accelerator (MAA), True Random Number Generator (TRNG) + - Secure Nonvolatile Key Storage, SHA-256, AES-128/192/256 + - Memory Decryption Integrity Unit, Secure Boot ROM + +- External devices connected to the MAX32650FTHR: + + - Battery Connector and Charging Circuit + - Micro-SD Card Interface + - USB 2.0 Full-Speed Device Interface + - MAX11261 6-Channel, 24-Bit, 16ksps, ADC + - AdafruitÂŽ Feather Board Compatible + +Supported Features +================== + +The ``max32650fthr`` board supports the following interfaces: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ + +Programming and Debugging +************************* + +Flashing +======== +The MAX32650 MCU can be flashed by connecting an external debug probe to the +SWD port. SWD debug can be accessed through the Cortex 10-pin connector, J5. +Logic levels are fixed to VDDIO (1.8V). + +Once the debug probe is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. + +.. note:: + + This board uses OpenOCD as the default debug interface. You can also use + a Segger J-Link with Segger's native tooling by overriding the runner, + appending ``--runner jlink`` to your ``west`` command(s). The J-Link should + be connected to the standard 2*5 pin debug connector (J5) using an + appropriate adapter board and cable + +Debugging +========= +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `MAX32650FTHR web page`_ + +.. _MAX32650FTHR web page: + https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650fthr.html diff --git a/boards/adi/max32650fthr/max32650fthr.dts b/boards/adi/max32650fthr/max32650fthr.dts new file mode 100644 index 0000000000000..b471e2523ce0f --- /dev/null +++ b/boards/adi/max32650fthr/max32650fthr.dts @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include + +/ { + model = "Analog Devices MAX32650FTHR"; + compatible = "adi,max32650fthr"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led_1 { + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + + led2: led_2 { + gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + pb1: pb1 { + gpios = <&gpio1 19 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + zephyr,code = ; + }; + + pb2: pb2 { + gpios = <&gpio1 21 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW3"; + zephyr,code = ; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0_tx_p2_12 &uart0_rx_p2_11>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; diff --git a/boards/adi/max32650fthr/max32650fthr.yaml b/boards/adi/max32650fthr/max32650fthr.yaml new file mode 100644 index 0000000000000..f967621e7020c --- /dev/null +++ b/boards/adi/max32650fthr/max32650fthr.yaml @@ -0,0 +1,13 @@ +identifier: max32650fthr +name: max32650fthr +vendor: adi +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - serial +ram: 1024 +flash: 3072 diff --git a/boards/adi/max32650fthr/max32650fthr_defconfig b/boards/adi/max32650fthr/max32650fthr_defconfig new file mode 100644 index 0000000000000..9428e5334a08f --- /dev/null +++ b/boards/adi/max32650fthr/max32650fthr_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/max32655evkit/board.cmake b/boards/adi/max32655evkit/board.cmake index 965de9e4de2aa..12e0bc56765e7 100644 --- a/boards/adi/max32655evkit/board.cmake +++ b/boards/adi/max32655evkit/board.cmake @@ -1,9 +1,8 @@ -# Copyright (c) 2023-2024 Analog Devices, Inc. +# Copyright (c) 2023-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32655.cfg]") board_runner_args(jlink "--device=MAX32655" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32655evkit/doc/index.rst b/boards/adi/max32655evkit/doc/index.rst index 649df3bde3773..1dce1fbad6ecc 100644 --- a/boards/adi/max32655evkit/doc/index.rst +++ b/boards/adi/max32655evkit/doc/index.rst @@ -169,7 +169,8 @@ SWD port. SWD debug can be accessed through the Cortex 10-pin connector, JH3. Logic levels are fixed to VDDIO (1.8V). Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: diff --git a/boards/adi/max32655evkit/max32655evkit_max32655_m4.dts b/boards/adi/max32655evkit/max32655evkit_max32655_m4.dts index a14953606ea19..ae822ce9db1a6 100644 --- a/boards/adi/max32655evkit/max32655evkit_max32655_m4.dts +++ b/boards/adi/max32655evkit/max32655evkit_max32655_m4.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Analog Devices, Inc. + * Copyright (c) 2023-2025 Analog Devices, Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +10,6 @@ #include #include #include -#include / { model = "Analog Devices MAX32655EVKIT"; @@ -133,3 +132,34 @@ &rtc_counter { status = "okay"; }; + +&spi0_mosi_p0_5 { + power-source = ; +}; + +&spi0_miso_p0_6 { + power-source = ; +}; + +&spi0_sck_p0_7 { + power-source = ; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi0_mosi_p0_5 &spi0_miso_p0_6 &spi0_sck_p0_7>; + pinctrl-names = "default"; + cs-gpios = <&gpio0 4 (GPIO_ACTIVE_LOW | MAX32_GPIO_VSEL_VDDIOH)>; + + spi0_cs0_flash: w25q128@0 { + compatible = "jedec,spi-nor"; + /* 134217728 bits = 16 Mbytes */ + size = <0x8000000>; + reg = <0>; + spi-max-frequency = <10000000>; + jedec-id = [ef 40 18]; + hold-gpios = <&gpio0 9 (GPIO_ACTIVE_LOW | MAX32_GPIO_VSEL_VDDIOH)>; + wp-gpios = <&gpio0 8 (GPIO_ACTIVE_HIGH | MAX32_GPIO_VSEL_VDDIOH)>; + status = "okay"; + }; +}; diff --git a/boards/adi/max32655evkit/max32655evkit_max32655_m4.yaml b/boards/adi/max32655evkit/max32655evkit_max32655_m4.yaml index f3a7fac43baa8..141223a8db19b 100644 --- a/boards/adi/max32655evkit/max32655evkit_max32655_m4.yaml +++ b/boards/adi/max32655evkit/max32655evkit_max32655_m4.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial diff --git a/boards/adi/max32655fthr/board.cmake b/boards/adi/max32655fthr/board.cmake index d2353452cbe3c..281834ae50af3 100644 --- a/boards/adi/max32655fthr/board.cmake +++ b/boards/adi/max32655fthr/board.cmake @@ -1,7 +1,5 @@ -# Copyright (c) 2023-2024 Analog Devices, Inc. +# Copyright (c) 2023-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32655.cfg]") - +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adi/max32655fthr/doc/index.rst b/boards/adi/max32655fthr/doc/index.rst index 839365066cc12..bc3f191c19b13 100644 --- a/boards/adi/max32655fthr/doc/index.rst +++ b/boards/adi/max32655fthr/doc/index.rst @@ -191,7 +191,8 @@ The MAX32625 microcontroller on the board is flashed with DAPLink firmware at th It allows debugging and flashing the MAX32655 Arm Core over USB. Once the USB cable is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. Debugging ========= diff --git a/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts b/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts index 2f82dc09022e9..7d09e56521725 100644 --- a/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts +++ b/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Analog Devices, Inc. + * Copyright (c) 2023-2025 Analog Devices, Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +10,6 @@ #include #include #include -#include / { model = "Analog Devices MAX32655FTHR"; @@ -162,3 +161,35 @@ &rtc_counter { status = "okay"; }; + +&spi0_mosi_p0_5 { + power-source = ; +}; + +&spi0_miso_p0_6 { + power-source = ; +}; + +&spi0_sck_p0_7 { + power-source = ; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi0_mosi_p0_5 &spi0_miso_p0_6 &spi0_sck_p0_7>; + pinctrl-names = "default"; + cs-gpios = <&gpio0 4 (GPIO_ACTIVE_LOW | MAX32_GPIO_VSEL_VDDIOH)>, + <&gpio0 11 (GPIO_ACTIVE_LOW | MAX32_GPIO_VSEL_VDDIOH)>; + + spi0_cs1_flash: w25q128jv@1 { + compatible = "jedec,spi-nor"; + /* 134217728 bits = 16 Mbytes */ + size = <0x8000000>; + reg = <1>; + spi-max-frequency = <10000000>; + jedec-id = [ef 70 18]; + hold-gpios = <&gpio0 9 (GPIO_ACTIVE_LOW | MAX32_GPIO_VSEL_VDDIOH)>; + wp-gpios = <&gpio0 8 (GPIO_ACTIVE_HIGH | MAX32_GPIO_VSEL_VDDIOH)>; + status = "okay"; + }; +}; diff --git a/boards/adi/max32655fthr/max32655fthr_max32655_m4.yaml b/boards/adi/max32655fthr/max32655fthr_max32655_m4.yaml index 37c8b01e02eb5..66c3d05382d18 100644 --- a/boards/adi/max32655fthr/max32655fthr_max32655_m4.yaml +++ b/boards/adi/max32655fthr/max32655fthr_max32655_m4.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial diff --git a/boards/adi/max32660evsys/Kconfig.max32660evsys b/boards/adi/max32660evsys/Kconfig.max32660evsys new file mode 100644 index 0000000000000..2e93639776153 --- /dev/null +++ b/boards/adi/max32660evsys/Kconfig.max32660evsys @@ -0,0 +1,7 @@ +# MAX32660EVSYS boards configuration + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX32660EVSYS + select SOC_MAX32660 diff --git a/boards/adi/max32660evsys/board.cmake b/boards/adi/max32660evsys/board.cmake new file mode 100644 index 0000000000000..617eecca8f8ea --- /dev/null +++ b/boards/adi/max32660evsys/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adi/max32660evsys/board.yml b/boards/adi/max32660evsys/board.yml new file mode 100644 index 0000000000000..5e7e264b04c83 --- /dev/null +++ b/boards/adi/max32660evsys/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max32660evsys + full_name: MAX32660EVSYS + vendor: adi + socs: + - name: max32660 diff --git a/boards/adi/max32660evsys/doc/img/max32660evsys.webp b/boards/adi/max32660evsys/doc/img/max32660evsys.webp new file mode 100644 index 0000000000000..b3043a033a249 Binary files /dev/null and b/boards/adi/max32660evsys/doc/img/max32660evsys.webp differ diff --git a/boards/adi/max32660evsys/doc/index.rst b/boards/adi/max32660evsys/doc/index.rst new file mode 100644 index 0000000000000..91919764c297f --- /dev/null +++ b/boards/adi/max32660evsys/doc/index.rst @@ -0,0 +1,123 @@ +.. zephyr:board:: max32660evsys + +Overview +******** +The MAX32660 evaluation system offers a compact development platform that +provides access to all the features of the MAX32660 in a tiny, easy to +use board. A MAX32625PICO-based debug adapter comes attached to the main +board. It can be snapped free when programming is complete. The debug +module supports an optional 10-pin ArmÂŽ CortexÂŽ debug connector for DAPLink +functionality. Combined measurements are 0.65in x 2.2in, while the main board +alone measures 0.65in x 0.95in. External connections terminate in a dual-row +header footprint compatible with both thru-hole and SMT applications. This +board provides a powerful processing subsystem in a very small space that +can be easily integrated into a variety of applications. + +The Zephyr port is running on the MAX32660 MCU. + +Hardware +******** + +- MAX32660 MCU: + + - High-Efficiency Microcontroller for Wearable Devices + + - Internal Oscillator Operates Up to 96MHz + - 256KB Flash Memory + - 96KB SRAM, Optionally Preserved in Lowest Power Backup Mode + - 16KB Instruction Cache + - Memory Protection Unit (MPU) + - Low 1.1V VCORE Supply Voltage + - 3.6V GPIO Operating Range + - Internal LDO Provides Operation from Single Supply + - Wide Operating Temperature: -40°C to +105°C + + - Power Management Maximizes Uptime for Battery Applications + + - 85ÂľA/MHz Active Executing from Flash + - 2ÂľA Full Memory Retention Power in Backup Mode at VDD = 1.8V + - 450nA Ultra-Low Power RTC at VDD=1.8V + - Internal 80kHz Ring Oscillator + + - Optimal Peripheral Mix Provides Platform Scalability + + - Up to 14 General-Purpose I/O Pins + - Up to Two SPI + - I2S + - Up to Two UARTs + - Up to Two I2C, 3.4Mbps High Speed + - Four-Channel Standard DMA Controller + - Three 32-Bit Timers + - Watchdog Timer + - CMOS-Level 32.768kHz RTC Output + +- Benefits and Features of MAX32660-EVSYS: + + - DIP Breakout Board + + - 100mil Pitch Dual Inline Pin Headers + - Breadboard Compatible + + - Integrated Peripherals + + - Red Indicator LED + - User Pushbutton + + - MAX32625PICO-Based Debug Adapter + + - CMSIS-DAP SWD Debugger + - Virtual UART Console + +Supported Features +================== + +The ``max32660evsys`` board supports the following interfaces: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ + +Programming and Debugging +************************* + +Flashing +======== + +An ArmÂŽ debug access port (DAP) provides an external interface for debugging during application +development. The DAP is a standard Arm CoreSightÂŽ serial wire debug port, uses a two-pin serial +interface (SWDCLK and SWDIO), and is accessed through 10-pin header (J4). + +Once the debug probe is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. + +.. note:: + + This board uses OpenOCD as the default debug interface. You can also use + a Segger J-Link with Segger's native tooling by overriding the runner, + appending ``--runner jlink`` to your ``west`` command(s). The J-Link should + be connected to the standard 2*5 pin debug connector (J3) using an + appropriate adapter board and cable. + +Debugging +========= + +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `MAX32660EVSYS web page`_ + +.. _MAX32660EVSYS web page: + https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32660-evsys.html diff --git a/boards/adi/max32660evsys/max32660evsys.dts b/boards/adi/max32660evsys/max32660evsys.dts new file mode 100644 index 0000000000000..f06645f94a1e8 --- /dev/null +++ b/boards/adi/max32660evsys/max32660evsys.dts @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include + +/ { + model = "Analog Devices MAX32660EVSYS"; + compatible = "adi,max32660evsys"; + + chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,sram = &sram2; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led_1 { + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + }; + +}; + +&uart1 { + pinctrl-0 = <&uart1_tx_p0_10 &uart1_rx_p0_11>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; diff --git a/boards/adi/max32660evsys/max32660evsys.yaml b/boards/adi/max32660evsys/max32660evsys.yaml new file mode 100644 index 0000000000000..da963ef091c68 --- /dev/null +++ b/boards/adi/max32660evsys/max32660evsys.yaml @@ -0,0 +1,13 @@ +identifier: max32660evsys +name: max32660evsys +vendor: adi +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - serial +ram: 96 +flash: 256 diff --git a/boards/adi/max32660evsys/max32660evsys_defconfig b/boards/adi/max32660evsys/max32660evsys_defconfig new file mode 100644 index 0000000000000..9428e5334a08f --- /dev/null +++ b/boards/adi/max32660evsys/max32660evsys_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/max32662evkit/board.cmake b/boards/adi/max32662evkit/board.cmake index 48ee0fa505f8a..66bc1b70c0c0b 100644 --- a/boards/adi/max32662evkit/board.cmake +++ b/boards/adi/max32662evkit/board.cmake @@ -1,9 +1,8 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32662.cfg]") board_runner_args(jlink "--device=MAX32662" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32662evkit/doc/index.rst b/boards/adi/max32662evkit/doc/index.rst index b343fb6ed99b8..249c6b4aeaf48 100644 --- a/boards/adi/max32662evkit/doc/index.rst +++ b/boards/adi/max32662evkit/doc/index.rst @@ -212,7 +212,8 @@ the UART1A port can also be accessed through J3. Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: diff --git a/boards/adi/max32662evkit/max32662evkit.yaml b/boards/adi/max32662evkit/max32662evkit.yaml index eebab96b6766d..9866e12e0dc71 100644 --- a/boards/adi/max32662evkit/max32662evkit.yaml +++ b/boards/adi/max32662evkit/max32662evkit.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - dma - gpio diff --git a/boards/adi/max32666evkit/board.cmake b/boards/adi/max32666evkit/board.cmake index 80033d85bdc65..024f4a0b7a7f7 100644 --- a/boards/adi/max32666evkit/board.cmake +++ b/boards/adi/max32666evkit/board.cmake @@ -1,9 +1,8 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32665.cfg]") board_runner_args(jlink "--device=MAX32666" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32666evkit/doc/index.rst b/boards/adi/max32666evkit/doc/index.rst index f71b1a69bb6f4..96b43693653f1 100644 --- a/boards/adi/max32666evkit/doc/index.rst +++ b/boards/adi/max32666evkit/doc/index.rst @@ -296,7 +296,8 @@ SWD port. SWD debug can be accessed through the Cortex 10-pin connector, J6. Logic levels are fixed to VDDIOH (1.8V or 3.3V). Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: diff --git a/boards/adi/max32666evkit/max32666evkit_max32666_cpu0.yaml b/boards/adi/max32666evkit/max32666evkit_max32666_cpu0.yaml index 7d5f86999702e..f43f703e89458 100644 --- a/boards/adi/max32666evkit/max32666evkit_max32666_cpu0.yaml +++ b/boards/adi/max32666evkit/max32666evkit_max32666_cpu0.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - dma - i2c diff --git a/boards/adi/max32666fthr/board.cmake b/boards/adi/max32666fthr/board.cmake index b2315d05907d7..e7077922b369f 100644 --- a/boards/adi/max32666fthr/board.cmake +++ b/boards/adi/max32666fthr/board.cmake @@ -1,9 +1,8 @@ -# Copyright (c) 2023-2024 Analog Devices, Inc. +# Copyright (c) 2023-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32665.cfg]") board_runner_args(jlink "--device=MAX32666" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32666fthr/doc/index.rst b/boards/adi/max32666fthr/doc/index.rst index 1cd8a999de1c5..c8bb9bf9ebc98 100644 --- a/boards/adi/max32666fthr/doc/index.rst +++ b/boards/adi/max32666fthr/doc/index.rst @@ -126,6 +126,8 @@ Below interfaces are supported by Zephyr on MAX32666FTHR. +-----------+------------+-------------------------------------+ | Flash | on-chip | flash | +-----------+------------+-------------------------------------+ +| SDHC | on-chip | sd host controller | ++-----------+------------+-------------------------------------+ Connections and IOs =================== @@ -216,7 +218,8 @@ SWD debug can be accessed through the Cortex 10-pin connector, JH2. Logic levels are fixed to VDDIO (1.8V). Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: diff --git a/boards/adi/max32666fthr/max32666fthr_max32666_cpu0.dts b/boards/adi/max32666fthr/max32666fthr_max32666_cpu0.dts index 02b45bda3db55..5aa45a1c5ce2a 100644 --- a/boards/adi/max32666fthr/max32666fthr_max32666_cpu0.dts +++ b/boards/adi/max32666fthr/max32666fthr_max32666_cpu0.dts @@ -55,6 +55,7 @@ led2 = &led3; sw0 = &pb1; watchdog0 = &wdt0; + sdhc0 = &sdhc0; }; /* Used for accessing other pins */ @@ -134,3 +135,56 @@ pinctrl-0 = <&owm_io_p0_12>; pinctrl-names = "default"; }; + +&sdhc0 { + pinctrl-0 = <&sdhc_dat3_p1_0 &sdhc_cmd_p1_1 &sdhc_dat0_p1_2 &sdhc_clk_p1_3 + &sdhc_dat1_p1_4 &sdhc_dat2_p1_5 &sdhc_wp_p1_6 &sdhc_cdn_p1_7>; + pinctrl-names = "default"; +}; + +&sdhc_dat3_p1_0 { + power-source = ; + drive-strength = <1>; +}; + +&sdhc_cmd_p1_1 { + power-source = ; + drive-strength = <1>; +}; + +&sdhc_dat0_p1_2 { + power-source = ; + drive-strength = <1>; +}; + +&sdhc_clk_p1_3 { + power-source = ; + drive-strength = <1>; +}; + +&sdhc_dat1_p1_4 { + power-source = ; + drive-strength = <1>; +}; + +&sdhc_dat2_p1_5 { + power-source = ; + drive-strength = <1>; +}; + +&sdhc_wp_p1_6 { + power-source = ; + drive-strength = <1>; +}; + +&sdhc_cdn_p1_7 { + power-source = ; + drive-strength = <1>; +}; + +&sdhc0 { + status = "okay"; + mmc { + status = "okay"; + }; +}; diff --git a/boards/adi/max32666fthr/max32666fthr_max32666_cpu0.yaml b/boards/adi/max32666fthr/max32666fthr_max32666_cpu0.yaml index c40294e0ae33c..9b924a56a6d0c 100644 --- a/boards/adi/max32666fthr/max32666fthr_max32666_cpu0.yaml +++ b/boards/adi/max32666fthr/max32666fthr_max32666_cpu0.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - dma - i2c @@ -21,5 +20,6 @@ supported: - pwm - w1 - flash + - sdhc ram: 560 flash: 1024 diff --git a/boards/adi/max32670evkit/board.cmake b/boards/adi/max32670evkit/board.cmake index fc69d3635f195..b370a18f9f338 100644 --- a/boards/adi/max32670evkit/board.cmake +++ b/boards/adi/max32670evkit/board.cmake @@ -1,7 +1,5 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32670.cfg]") - +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adi/max32670evkit/doc/index.rst b/boards/adi/max32670evkit/doc/index.rst index a5b10ef8d9ee1..3fefd9e4119b2 100644 --- a/boards/adi/max32670evkit/doc/index.rst +++ b/boards/adi/max32670evkit/doc/index.rst @@ -185,7 +185,8 @@ The MAX32670 EVKIT integrates a MAX32625PICO based debugger for DAPLink function Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. Debugging ========= diff --git a/boards/adi/max32670evkit/max32670evkit.yaml b/boards/adi/max32670evkit/max32670evkit.yaml index d040a09de49db..266d1584aaf53 100644 --- a/boards/adi/max32670evkit/max32670evkit.yaml +++ b/boards/adi/max32670evkit/max32670evkit.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial diff --git a/boards/adi/max32672evkit/board.cmake b/boards/adi/max32672evkit/board.cmake index 454ec897d2a69..76eb51547343e 100644 --- a/boards/adi/max32672evkit/board.cmake +++ b/boards/adi/max32672evkit/board.cmake @@ -1,9 +1,8 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32672.cfg]") board_runner_args(jlink "--device=MAX32672" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32672evkit/doc/index.rst b/boards/adi/max32672evkit/doc/index.rst index c706898a353e8..b4b63a8550a72 100644 --- a/boards/adi/max32672evkit/doc/index.rst +++ b/boards/adi/max32672evkit/doc/index.rst @@ -327,7 +327,8 @@ is supplied externally. Be sure to remove jumper JP15 (LDO_DUT_EN) to disconnect LDO if supplying VDD and VDDA externally. Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: diff --git a/boards/adi/max32672evkit/max32672evkit.yaml b/boards/adi/max32672evkit/max32672evkit.yaml index e6dae70435c80..a8c835774e54a 100644 --- a/boards/adi/max32672evkit/max32672evkit.yaml +++ b/boards/adi/max32672evkit/max32672evkit.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial diff --git a/boards/adi/max32672fthr/board.cmake b/boards/adi/max32672fthr/board.cmake index 815111de6b74e..b370a18f9f338 100644 --- a/boards/adi/max32672fthr/board.cmake +++ b/boards/adi/max32672fthr/board.cmake @@ -1,7 +1,5 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32672.cfg]") - +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adi/max32672fthr/doc/index.rst b/boards/adi/max32672fthr/doc/index.rst index 76033bf97ecf6..e4d387728f4e0 100644 --- a/boards/adi/max32672fthr/doc/index.rst +++ b/boards/adi/max32672fthr/doc/index.rst @@ -204,7 +204,8 @@ The MAX32625 microcontroller on the board is flashed with DAPLink firmware at th It allows debugging and flashing the MAX32672 Arm Core over USB. Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. Debugging ========= diff --git a/boards/adi/max32672fthr/max32672fthr.yaml b/boards/adi/max32672fthr/max32672fthr.yaml index f98839246c8b3..28bb5414e07c0 100644 --- a/boards/adi/max32672fthr/max32672fthr.yaml +++ b/boards/adi/max32672fthr/max32672fthr.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial diff --git a/boards/adi/max32675evkit/board.cmake b/boards/adi/max32675evkit/board.cmake index 42caa77e95b02..4d691b5106c4c 100644 --- a/boards/adi/max32675evkit/board.cmake +++ b/boards/adi/max32675evkit/board.cmake @@ -1,9 +1,8 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32675.cfg]") board_runner_args(jlink "--device=MAX32675" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32675evkit/doc/index.rst b/boards/adi/max32675evkit/doc/index.rst index a9de574eb21ee..4028d8bc8e43c 100644 --- a/boards/adi/max32675evkit/doc/index.rst +++ b/boards/adi/max32675evkit/doc/index.rst @@ -379,7 +379,8 @@ is supplied externally. Be sure to remove jumper JP15 (LDO_DUT_EN) to disconnect the 3.3V LDO if supplying VDD and VDDA externally. Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: diff --git a/boards/adi/max32675evkit/max32675evkit.yaml b/boards/adi/max32675evkit/max32675evkit.yaml index 023a35465f3ea..86bee190d2547 100644 --- a/boards/adi/max32675evkit/max32675evkit.yaml +++ b/boards/adi/max32675evkit/max32675evkit.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - dma - gpio diff --git a/boards/adi/max32680evkit/board.cmake b/boards/adi/max32680evkit/board.cmake index bd318bb200d32..b370a18f9f338 100644 --- a/boards/adi/max32680evkit/board.cmake +++ b/boards/adi/max32680evkit/board.cmake @@ -1,7 +1,5 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32680.cfg]") - +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adi/max32680evkit/doc/index.rst b/boards/adi/max32680evkit/doc/index.rst index 13c6d7d06b603..10def1215cb8f 100644 --- a/boards/adi/max32680evkit/doc/index.rst +++ b/boards/adi/max32680evkit/doc/index.rst @@ -327,7 +327,8 @@ SWD port. SWD debug can be accessed through the Cortex 10-pin connector, JH10. Logic levels are set to 1.8V (VDDIO_AUX). Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. Debugging ========= diff --git a/boards/adi/max32680evkit/max32680evkit_max32680_m4.yaml b/boards/adi/max32680evkit/max32680evkit_max32680_m4.yaml index 1fc90758f49e9..84f75d376d8a0 100644 --- a/boards/adi/max32680evkit/max32680evkit_max32680_m4.yaml +++ b/boards/adi/max32680evkit/max32680evkit_max32680_m4.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial diff --git a/boards/adi/max32690evkit/board.cmake b/boards/adi/max32690evkit/board.cmake index 443c84cc5e85a..1c5aa42735d2c 100644 --- a/boards/adi/max32690evkit/board.cmake +++ b/boards/adi/max32690evkit/board.cmake @@ -1,9 +1,8 @@ -# Copyright (c) 2023-2024 Analog Devices, Inc. +# Copyright (c) 2023-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32690.cfg]") board_runner_args(jlink "--device=MAX32690" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32690evkit/doc/index.rst b/boards/adi/max32690evkit/doc/index.rst index d976048dcb6de..ab484d1e32e81 100644 --- a/boards/adi/max32690evkit/doc/index.rst +++ b/boards/adi/max32690evkit/doc/index.rst @@ -284,7 +284,8 @@ SWD port. SWD debug can be accessed through the Cortex 10-pin connector, J3. Logic levels are fixed to VDDIO (1.8V). Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: @@ -303,7 +304,7 @@ instead of ``west flash``. References ********** -- `MAX32690EVKIT web page`_ +- `MAX32690EVKIT solution center`_ -.. _MAX32690EVKIT web page: - https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/MAX32690EVKIT.html +.. _MAX32690EVKIT solution center: + https://developer.analog.com/solutions/max32690 diff --git a/boards/adi/max32690evkit/max32690evkit_max32690_m4.yaml b/boards/adi/max32690evkit/max32690evkit_max32690_m4.yaml index b6a5a9a5d7a55..150225890e2a8 100644 --- a/boards/adi/max32690evkit/max32690evkit_max32690_m4.yaml +++ b/boards/adi/max32690evkit/max32690evkit_max32690_m4.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial diff --git a/boards/adi/max32690fthr/board.cmake b/boards/adi/max32690fthr/board.cmake index 443c84cc5e85a..43b3efb7b59f8 100644 --- a/boards/adi/max32690fthr/board.cmake +++ b/boards/adi/max32690fthr/board.cmake @@ -1,9 +1,8 @@ # Copyright (c) 2023-2024 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max32690.cfg]") board_runner_args(jlink "--device=MAX32690" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max32690fthr/doc/index.rst b/boards/adi/max32690fthr/doc/index.rst index fdce08e32e866..ad133537417d2 100644 --- a/boards/adi/max32690fthr/doc/index.rst +++ b/boards/adi/max32690fthr/doc/index.rst @@ -97,7 +97,8 @@ Logic levels are fixed to VDDIO (1.8V). Once the debug probe is connected to your host computer, then you can run the ``west flash`` command to write a firmware image into flash. Here is an example -for the :zephyr:code-sample:`hello_world` application. +for the :zephyr:code-sample:`hello_world` application. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. zephyr-app-commands:: :zephyr-app: samples/hello_world @@ -127,7 +128,7 @@ session. Here is an example for the :zephyr:code-sample:`hello_world` applicatio References ********** -- `MAX32690 product page`_ +- `MAX32690 solution center`_ -.. _MAX32690 product page: - https://www.analog.com/en/products/max32690.html +.. _MAX32690 solution center: + https://developer.analog.com/solutions/max32690 diff --git a/boards/adi/max32690fthr/max32690fthr_max32690_m4.yaml b/boards/adi/max32690fthr/max32690fthr_max32690_m4.yaml index d81738ee74244..7b802ab479525 100644 --- a/boards/adi/max32690fthr/max32690fthr_max32690_m4.yaml +++ b/boards/adi/max32690fthr/max32690fthr_max32690_m4.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial diff --git a/boards/adi/max78000evkit/Kconfig.max78000evkit b/boards/adi/max78000evkit/Kconfig.max78000evkit new file mode 100644 index 0000000000000..67f6980da06c2 --- /dev/null +++ b/boards/adi/max78000evkit/Kconfig.max78000evkit @@ -0,0 +1,7 @@ +# MAX78000EVKIT boards configuration + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX78000EVKIT + select SOC_MAX78000_M4 if BOARD_MAX78000EVKIT_MAX78000_M4 diff --git a/boards/adi/max78000evkit/board.cmake b/boards/adi/max78000evkit/board.cmake new file mode 100644 index 0000000000000..c4b66dade5a2b --- /dev/null +++ b/boards/adi/max78000evkit/board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=MAX78000" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max78000evkit/board.yml b/boards/adi/max78000evkit/board.yml new file mode 100644 index 0000000000000..d1b1e370036c9 --- /dev/null +++ b/boards/adi/max78000evkit/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max78000evkit + full_name: MAX78000EVKIT + vendor: adi + socs: + - name: max78000 diff --git a/boards/adi/max78000evkit/doc/img/max78000evkit_img1.webp b/boards/adi/max78000evkit/doc/img/max78000evkit_img1.webp new file mode 100644 index 0000000000000..691efe7cec770 Binary files /dev/null and b/boards/adi/max78000evkit/doc/img/max78000evkit_img1.webp differ diff --git a/boards/adi/max78000evkit/doc/index.rst b/boards/adi/max78000evkit/doc/index.rst new file mode 100644 index 0000000000000..fb9c2fc8bcd8a --- /dev/null +++ b/boards/adi/max78000evkit/doc/index.rst @@ -0,0 +1,309 @@ +.. zephyr:board:: max78000evkit + +Overview +******** +The MAX78000 evaluation kit (EV kit) provides a platform for leveraging the capabilities of the MAX78000 to build +new generations of artificial intelligence (AI) devices. Onboard hardware includes a digital microphone, a gyroscope/accelerometer, parallel camera module support +and a 3.5in touch-enabled color TFT display. A secondary display is driven by a power accumulator for tracking +device power consumption over time. Uncommitted GPIO as well as analog inputs are readily accessible through +0.1in pin headers. Primary system power as well as UART access is provided by a USB Micro-B connector. A USB +to SPI bridge provides rapid access to onboard memory, allowing large networks or images to load quickly + +The Zephyr port is running on the MAX78000 MCU. + +.. image:: img/max78000evkit_img1.webp + :align: center + :alt: MAX78000 EVKIT + +Hardware +******** + +- MAX78000 MCU: + + - Dual-Core, Low-Power Microcontroller + + - Arm Cortex-M4 Processor with FPU up to 100MHz + - 512KB Flash and 128KB SRAM + - Optimized Performance with 16KB Instruction Cache + - Optional Error Correction Code (ECC-SEC-DED) for SRAM + - 32-Bit RISC-V Coprocessor up to 60MHz + - Up to 52 General-Purpose I/O Pins + - 12-Bit Parallel Camera Interface + - One I2S Master/Slave for Digital Audio Interface + + - Neural Network Accelerator + + - Highly Optimized for Deep Convolutional Neural Networks + - 442k 8-Bit Weight Capacity with 1,2,4,8-Bit Weights + - Programmable Input Image Size up to 1024 x 1024 pixels + - Programmable Network Depth up to 64 Layers + - Programmable per Layer Network Channel Widths up to 1024 Channels + - 1 and 2 Dimensional Convolution Processing + - Streaming Mode + - Flexibility to Support Other Network Types, Including MLP and Recurrent Neural Networks + + - Power Management Maximizes Operating Time for Battery Applications + + - Integrated Single-Inductor Multiple-Output (SIMO) Switch-Mode Power Supply (SMPS) + - 2.0V to 3.6V SIMO Supply Voltage Range + - Dynamic Voltage Scaling Minimizes Active Core Power Consumption + - 22.2ÎźA/MHz While Loop Execution at 3.0V from Cache (CM4 Only) + - Selectable SRAM Retention in Low-Power Modes with Real-Time Clock (RTC) Enabled + + - Security and Integrity + + - Available Secure Boot + - AES 128/192/256 Hardware Acceleration Engine + - True Random Number Generator (TRNG) Seed Generator + +Supported Features +================== + +The ``max78000evkit/max78000/m4`` board target supports the following interfaces: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| TRNG | on-chip | entropy | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| DMA | on-chip | dma controller | ++-----------+------------+-------------------------------------+ +| Watchdog | on-chip | watchdog | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| Flash | on-chip | flash | ++-----------+------------+-------------------------------------+ +| Timer | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | real time clock | ++-----------+------------+-------------------------------------+ +| Timer | on-chip | counter | ++-----------+------------+-------------------------------------+ +| W1 | on-chip | one wire master | ++--------------------------------------------------------------+ + +Connections and IOs +=================== + ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| Name | Name | Settings | Description | ++===========+===================+===================+==============================================================================================+ +| JP1 | LED1 EN | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables auxiliary LED1 | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables auxiliary LED1 | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP2 | LED2 EN | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables auxiliary LED2 | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables auxiliary LED2 | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP3 | TRIG1 | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables power monitor event trigger 1 | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables power monitor event trigger 1 | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP4 | TRIG2 | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables power monitor event trigger 2 | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables power monitor event trigger 2 | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP5 | VREGI | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables 3V3 VREGI power | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables 3V3 VREGI power | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP6 | VREGIA | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables 3V3 VREGIA power | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables 3V3 VREGIA power | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP7 | CNN BOOST | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables 1V1 boost LDO power | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables 1V1 boost LDO power | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP8 | VDDA | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Internal SIMO powers VDDA | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | External LDO powers VDDA | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP9 | VDDIO | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Internal SIMO powers VDDIO | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | External LDO powers VDDIO | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP10 | VDDIOH | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | DUT LDO powers VDDIOH | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | AUX LDO powers VDDIOH | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP11 | VCOREB | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Internal SIMO powers VCOREB | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | External LDO powers VCOREB | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP12 | VCOREA | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Internal SIMO powers VCOREA | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | External LDO powers VCOREA | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP13 | VREGI PM BYPASS | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Bypasses power monitor shunt | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Enables power monitoring using power accumulator | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP14 | CNN 1V1 | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Connects 1V1 boost LDO to VCOREA | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables 1V1 boost LDO | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP15 | VCOREA PM BYPASS | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Bypasses power monitor shunt | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Enables power monitoring using power accumulator | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP16 | VCOREB PM BYPASS | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Bypasses power monitor shunt | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Enables power monitoring using power accumulator | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP17 | VREG_A PM BYPASS | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Bypasses power monitor shunt | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Enables power monitoring using power accumulator | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP18 | RESET EN | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables RV JTAG adapter to perform full system reset | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables system reset by RV JTAG adapter | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP19 | TFT BL | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables main TFT screen backlight | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables main TFT screen backlight | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP20 | I2S CLK SEL | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Onboard 12.288MHz oscillator drives I2S clock | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | External 1V8 CMOS LEVEL source drives I2S clock | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP21 | DUT I | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | DUT 3V3 total current monitor point | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Open to insert current meter | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JP22 | USB-SPI/CAM | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables USB-SPI bridge | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Enables camera | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JH1 | UART 0 EN | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2, 3-4 | | | Enables USB-UART0 bridge, software flow control | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | All Open | | | Disables USB-UART0 bridge, allows reuse of port pins | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ +| JH2 | UART 1 EN | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | |All installed | | | Enables USB-UART1 bridge | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | All Open | | | Disables USB-UART1 bridge, allows reuse of port pins | | +| | | +---------------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+-------------------+----------------------------------------------------------------------------------------------+ + +Programming and Debugging +************************* + +Flashing +======== + +The MAX78000 MCU can be flashed by connecting an external debug probe to the +SWD port. SWD debug can be accessed through the Cortex 10-pin connector, JH5. +Logic levels are fixed to VDDIO (1.8V). + +Once the debug probe is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. + +.. note:: + + This board uses OpenOCD as the default debug interface. You can also use + a Segger J-Link with Segger's native tooling by overriding the runner, + appending ``--runner jlink`` to your ``west`` command(s). The J-Link should + be connected to the standard 2*5 pin debug connector (JH5) using an + appropriate adapter board and cable. + +Debugging +========= + +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `MAX78000EVKIT web page`_ + +.. _MAX78000EVKIT web page: + https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max78000evkit.html diff --git a/boards/adi/max78000evkit/max78000evkit_max78000_m4.dts b/boards/adi/max78000evkit/max78000evkit_max78000_m4.dts new file mode 100644 index 0000000000000..44e888a24c95c --- /dev/null +++ b/boards/adi/max78000evkit/max78000evkit_max78000_m4.dts @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include + +/ { + model = "Analog Devices MAX78000EVKIT"; + compatible = "adi,max78000evkit"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram2; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led_1 { + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + + led2: led_2 { + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + pb1: pb1 { + gpios = <&gpio2 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + zephyr,code = ; + }; + + pb2: pb2 { + gpios = <&gpio2 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW3"; + zephyr,code = ; + }; + + pb_wakeup: pb_wakeup { + gpios = <&gpio3 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW + | MAX32_GPIO_VSEL_VDDIOH)>; + label = "Wakeup"; + zephyr,code = ; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + sw0 = &pb1; + sw1 = &pb2; + watchdog0 = &wdt0; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0a_tx_p0_1 &uart0a_rx_p0_0>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&clk_ibro { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + pinctrl-0 = <&i2c0_scl_p0_10 &i2c0_sda_p0_11>; + pinctrl-names = "default"; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi0_mosi_p0_5 &spi0_miso_p0_6 &spi0_sck_p0_7 &spi0_ss0_p0_4>; + pinctrl-names = "default"; +}; + +&dma0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&w1 { + pinctrl-0 = <&owm_io_p0_18 &owm_pe_p0_19>; + pinctrl-names = "default"; +}; diff --git a/boards/adi/max78000evkit/max78000evkit_max78000_m4.yaml b/boards/adi/max78000evkit/max78000evkit_max78000_m4.yaml new file mode 100644 index 0000000000000..5f7f522504112 --- /dev/null +++ b/boards/adi/max78000evkit/max78000evkit_max78000_m4.yaml @@ -0,0 +1,23 @@ +identifier: max78000evkit/max78000/m4 +name: max78000evkit m4 +vendor: adi +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - counter + - dma + - flash + - gpio + - i2c + - pwm + - serial + - spi + - trng + - w1 + - watchdog +ram: 128 +flash: 512 diff --git a/boards/adi/max78000evkit/max78000evkit_max78000_m4_defconfig b/boards/adi/max78000evkit/max78000evkit_max78000_m4_defconfig new file mode 100644 index 0000000000000..9428e5334a08f --- /dev/null +++ b/boards/adi/max78000evkit/max78000evkit_max78000_m4_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/max78000fthr/Kconfig.max78000fthr b/boards/adi/max78000fthr/Kconfig.max78000fthr new file mode 100644 index 0000000000000..07efd3aa4bee2 --- /dev/null +++ b/boards/adi/max78000fthr/Kconfig.max78000fthr @@ -0,0 +1,7 @@ +# MAX78000FTHR boards configuration + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAX78000FTHR + select SOC_MAX78000_M4 if BOARD_MAX78000FTHR_MAX78000_M4 diff --git a/boards/adi/max78000fthr/board.cmake b/boards/adi/max78000fthr/board.cmake new file mode 100644 index 0000000000000..617eecca8f8ea --- /dev/null +++ b/boards/adi/max78000fthr/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/adi/max78000fthr/board.yml b/boards/adi/max78000fthr/board.yml new file mode 100644 index 0000000000000..365e84d1ad898 --- /dev/null +++ b/boards/adi/max78000fthr/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: max78000fthr + full_name: MAX78000FTHR + vendor: adi + socs: + - name: max78000 diff --git a/boards/adi/max78000fthr/doc/img/max78000fthr_img1.webp b/boards/adi/max78000fthr/doc/img/max78000fthr_img1.webp new file mode 100644 index 0000000000000..57f08575845a3 Binary files /dev/null and b/boards/adi/max78000fthr/doc/img/max78000fthr_img1.webp differ diff --git a/boards/adi/max78000fthr/doc/index.rst b/boards/adi/max78000fthr/doc/index.rst new file mode 100644 index 0000000000000..fee925ffae88f --- /dev/null +++ b/boards/adi/max78000fthr/doc/index.rst @@ -0,0 +1,211 @@ +.. zephyr:board:: max78000fthr + +Overview +******** +The MAX78000FTHR is a rapid development platform to help engineers quickly implement ultra low-power, artificial +intelligence (AI) solutions using the MAX78000 ArmÂŽ CortexÂŽ-M4F processor with an integrated Convolutional Neural Network +accelerator. The board also includes the MAX20303 PMIC for battery and power management. The form factor is 0.9in x 2.6in +dual-row header footprint that is compatible with Adafruit Feather Wing peripheral expansion boards. The board includes a +variety of peripherals, such as a CMOS VGA image sensor, digital microphone, low-power stereo audio CODEC, 1MB QSPI +SRAM, micro SD card connector, RGB indicator LED, and pushbutton. The MAX78000FTHR provides a poweroptimized flexible +platform for quick proof-of-concepts and early software development to enhance time to market. + +The Zephyr port is running on the MAX78000 MCU. + +.. image:: img/max78000fthr_img1.webp + :align: center + :alt: MAX78000 FTHR + +Hardware +******** + +- MAX78000 MCU: + + - Dual-Core, Low-Power Microcontroller + + - Arm Cortex-M4 Processor with FPU up to 100MHz + - 512KB Flash and 128KB SRAM + - Optimized Performance with 16KB Instruction Cache + - Optional Error Correction Code (ECC-SEC-DED) for SRAM + - 32-Bit RISC-V Coprocessor up to 60MHz + - Up to 52 General-Purpose I/O Pins + - 12-Bit Parallel Camera Interface + - One I2S Master/Slave for Digital Audio Interface + + - Neural Network Accelerator + + - Highly Optimized for Deep Convolutional Neural Networks + - 442k 8-Bit Weight Capacity with 1,2,4,8-Bit Weights + - Programmable Input Image Size up to 1024 x 1024 pixels + - Programmable Network Depth up to 64 Layers + - Programmable per Layer Network Channel Widths up to 1024 Channels + - 1 and 2 Dimensional Convolution Processing + - Streaming Mode + - Flexibility to Support Other Network Types, Including MLP and Recurrent Neural Networks + + - Power Management Maximizes Operating Time for Battery Applications + + - Integrated Single-Inductor Multiple-Output (SIMO) Switch-Mode Power Supply (SMPS) + - 2.0V to 3.6V SIMO Supply Voltage Range + - Dynamic Voltage Scaling Minimizes Active Core Power Consumption + - 22.2ÎźA/MHz While Loop Execution at 3.0V from Cache (CM4 Only) + - Selectable SRAM Retention in Low-Power Modes with Real-Time Clock (RTC) Enabled + + - Security and Integrity + + - Available Secure Boot + - AES 128/192/256 Hardware Acceleration Engine + - True Random Number Generator (TRNG) Seed Generator + +Supported Features +================== + +The ``max78000fthr/max78000/m4`` board target supports the following interfaces: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock and reset control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| TRNG | on-chip | entropy | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| DMA | on-chip | dma controller | ++-----------+------------+-------------------------------------+ +| Watchdog | on-chip | watchdog | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| Flash | on-chip | flash | ++-----------+------------+-------------------------------------+ +| Timer | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | real time clock | ++-----------+------------+-------------------------------------+ +| Timer | on-chip | counter | ++-----------+------------+-------------------------------------+ +| W1 | on-chip | one wire master | ++--------------------------------------------------------------+ + +Connections and IOs +=================== + +J8 Pinout +********** + ++---------+----------+-------------------------------------------------------------------------------------------------+ +| Pin | Name | Description | ++=========+==========+=================================================================================================+ +| 1 | RST | Master Reset Signal | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 2 | 3V3 | 3.3V Output. Typically used to provide 3.3V to peripherals connected to the expansion headers. | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 3 | 1V8 | 1.8V Output. Typically used to provide 1.8V to peripherals connected to the expansion headers. | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 4 | GND | Ground | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 5 | P2_3 | GPIO or Analog Input (AIN3 channel). | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 6 | P2_4 | GPIO or Analog Input (AIN4 channel). | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 7 | P1_1 | GPIO or UART2 Tx signal | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 8 | P1_0 | GPIO or UART2 Rx signal | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 9 | MPC1 | GPIO controlled by PMIC through I2C interface. Open drain or push-pull programmable | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 10 | MPC2 | GPIO controlled by PMIC through I2C interface. Open drain or push-pull programmable | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 11 | P0_7 | GPIO or QSPI0 clock signal. Shared with SD card and on-board QSPI SRAM | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 12 | P0_5 | GPIO or QSPI0 MOSI signal. Shared with SD card and on-board QSPI SRAM | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 13 | P0_6 | GPIO or QSPI0 MISO signal. Shared with SD card and on-board QSPI SRAM | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 14 | P2_6 | GPIO or LPUART Rx signal | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 15 | P2_7 | GPIO or LPUART Tx signal | ++---------+----------+-------------------------------------------------------------------------------------------------+ +| 16 | GND | Ground | ++---------+----------+-------------------------------------------------------------------------------------------------+ + +J4 Pinout +********** + ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| Pin | Name | Description | ++=========+==========+===========================================================================================================+ +| 1 | SYS | SYS Switched Connection to the Battery. This is the primary system power supply and automatically | +| | | switches between the battery voltage and the USB supply when available. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 2 | PWR | Turns off the PMIC if shorted to Ground for 13 seconds. Hard power-down button. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 3 | VBUS | USB VBUS Signal. This can be used as a 5V supply when connected to USB. This pin can also be | +| | | used as an input to power the board. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 4 | P1_6 | GPIO | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 5 | MPC3 | GPIO controlled by PMIC through the I2C interface. Open drain or push-pull programmable. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 6 | P0_9 | GPIO or QSPI0 SDIO3 signal. Shared with SD card and on-board QSPI SRAM. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 7 | P0_8 | GPIO or QSPI0 SDIO2 signal. Shared with SD Card and on-board QSPI SRAM. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 8 | P0_11 | GPIO or QSPI0 slave select signal | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 9 | P0_19 | GPIO | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 10 | P3_1 | GPIO or Wake-up signal. This pin is 3.3V only. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 11 | P0_16 | GPIO or I2C1 SCL signal. An on-board level shifter allows selecting 1.8V or 3.3V operation through | +| | | R15 or R20 resistors. Do not populate both. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ +| 12 | P0_17 | GPIO or I2C1 SDA signal. An on-board level shifter allows selecting 1.8V or 3.3V operation through | +| | | R15 or R20 resistors. Do not populate both. | ++---------+----------+-----------------------------------------------------------------------------------------------------------+ + +Programming and Debugging +************************* + +Flashing +======== + +The MAX32625 microcontroller on the board is preprogrammed with DAPLink firmware. +It allows debugging and programming of the MAX78000 Arm core over USB. + +Once the debug probe is connected to your host computer, then you can simply run the +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. + +.. note:: + + This board uses OpenOCD as the default debug interface. You can also use + a Segger J-Link with Segger's native tooling by overriding the runner, + appending ``--runner jlink`` to your ``west`` command(s). The J-Link should + be connected to the standard 2*5 pin debug connector (JH5) using an + appropriate adapter board and cable. + +Debugging +========= + +Please refer to the `Flashing`_ section and run the ``west debug`` command +instead of ``west flash``. + +References +********** + +- `MAX78000FTHR web page`_ + +.. _MAX78000FTHR web page: + https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max78000fthr.html diff --git a/boards/adi/max78000fthr/max78000fthr_max78000_m4.dts b/boards/adi/max78000fthr/max78000fthr_max78000_m4.dts new file mode 100644 index 0000000000000..0c62d5e4e4e62 --- /dev/null +++ b/boards/adi/max78000fthr/max78000fthr_max78000_m4.dts @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include + +/ { + model = "Analog Devices MAX78000FTHR"; + compatible = "adi,max78000fthr"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram2; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led_1 { + gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + + led2: led_2 { + gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + + led3: led_3 { + gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + pb1: pb1 { + gpios = <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW1"; + zephyr,code = ; + }; + + pb2: pb2 { + gpios = <&gpio1 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + zephyr,code = ; + }; + }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led1; + led1 = &led2; + sw0 = &pb1; + sw1 = &pb2; + watchdog0 = &wdt0; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0a_tx_p0_1 &uart0a_rx_p0_0>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&clk_ipo { + status = "okay"; +}; + +&clk_ibro { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + pinctrl-0 = <&i2c0_scl_p0_10 &i2c0_sda_p0_11>; + pinctrl-names = "default"; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi0_mosi_p0_5 &spi0_miso_p0_6 &spi0_sck_p0_7 &spi0_ss0_p0_4>; + pinctrl-names = "default"; +}; + +&dma0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&w1 { + pinctrl-0 = <&owm_io_p0_6 &owm_pe_p0_7>; + pinctrl-names = "default"; +}; diff --git a/boards/adi/max78000fthr/max78000fthr_max78000_m4.yaml b/boards/adi/max78000fthr/max78000fthr_max78000_m4.yaml new file mode 100644 index 0000000000000..116fa9051c584 --- /dev/null +++ b/boards/adi/max78000fthr/max78000fthr_max78000_m4.yaml @@ -0,0 +1,23 @@ +identifier: max78000fthr/max78000/m4 +name: max78000fthr m4 +vendor: adi +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - counter + - dma + - flash + - gpio + - i2c + - pwm + - serial + - spi + - trng + - w1 + - watchdog +ram: 128 +flash: 512 diff --git a/boards/adi/max78000fthr/max78000fthr_max78000_m4_defconfig b/boards/adi/max78000fthr/max78000fthr_max78000_m4_defconfig new file mode 100644 index 0000000000000..9428e5334a08f --- /dev/null +++ b/boards/adi/max78000fthr/max78000fthr_max78000_m4_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/adi/max78002evkit/board.cmake b/boards/adi/max78002evkit/board.cmake index b7d321b2f84f0..42001337f5882 100644 --- a/boards/adi/max78002evkit/board.cmake +++ b/boards/adi/max78002evkit/board.cmake @@ -1,7 +1,8 @@ -# Copyright (c) 2024 Analog Devices, Inc. +# Copyright (c) 2024-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd --cmd-pre-init "source [find interface/cmsis-dap.cfg]") -board_runner_args(openocd --cmd-pre-init "source [find target/max78002.cfg]") +board_runner_args(jlink "--device=MAX78002" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/max78002evkit/doc/index.rst b/boards/adi/max78002evkit/doc/index.rst index a5bd4acf09bb0..9a9d11a930759 100644 --- a/boards/adi/max78002evkit/doc/index.rst +++ b/boards/adi/max78002evkit/doc/index.rst @@ -42,7 +42,7 @@ Hardware - MIPI Camera Serial Interface 2 (MIPI CSI-2) Controller V2.1 - Support for Two Data Lanes - 12-Bit Parallel Camera Interface - - I 2S Controller/Target for Digital Audio Interface + - I2S Controller/Target for Digital Audio Interface - Secure Digital Interface Supports SD 3.0/SDIO 3.0/eMMC 4.51 - Convolutional Neural Network (CNN) Accelerator @@ -71,51 +71,6 @@ Hardware - AES 128/192/256 Hardware Acceleration Engine - True Random Number Generator (TRNG) Seed Generator - - Ultra-Low-Power Wireless Microcontroller - - - Internal 100MHz Oscillator - - Flexible Low-Power Modes with 7.3728MHz System Clock Option - - 512KB Flash and 128KB SRAM (Optional ECC on One 32KB SRAM Bank) - - 16KB Instruction Cache - - - Bluetooth 5.2 LE Radio - - - Dedicated, Ultra-Low-Power, 32-Bit RISC-V Coprocessor to Offload Timing-Critical Bluetooth Processing - - Fully Open-Source Bluetooth 5.2 Stack Available - - Supports AoA, AoD, LE Audio, and Mesh - - High-Throughput (2Mbps) Mode - - Long-Range (125kbps and 500kbps) Modes - - Rx Sensitivity: -97.5dBm; Tx Power: +4.5dBm - - Single-Ended Antenna Connection (50Ί) - - - Power Management Maximizes Battery Life - - - 2.0V to 3.6V Supply Voltage Range - - Integrated SIMO Power Regulator - - Dynamic Voltage Scaling (DVS) - - 23.8ÎźA/MHz Active Current at 3.0V - - 4.4ÎźA at 3.0V Retention Current for 32KB - - Selectable SRAM Retention + RTC in Low-Power Modes - - - Multiple Peripherals for System Control - - - Up to Two High-Speed SPI Master/Slave - - Up to Three High-Speed I2C Master/Slave (3.4Mbps) - - Up to Four UART, One I2S Master/Slave - - Up to 8-Input, 10-Bit Sigma-Delta ADC 7.8ksps - - Up to Four Micro-Power Comparators - - Timers: Up to Two Four 32-Bit, Two LP, TwoWatchdog Timers - - 1-WireÂŽ Master - - Up to Four Pulse Train (PWM) Engines - - RTC with Wake-Up Timer - - Up to 52 GPIOs - - - Security and Integrity​ - - - Available Secure Boot - - TRNG Seed Generator - - AES 128/192/256 Hardware Acceleration Engine - - External devices connected to the MAX78002 EVKIT: - Color TFT Display @@ -165,99 +120,324 @@ The ``max78002evkit/max78002/m4`` board target supports the following interfaces Connections and IOs =================== -+-----------+-------------------+----------------------------------------------------------------------------------+ -| Name | Signal | Usage | -+===========+===================+==================================================================================+ -| JP1 | 3V3 MON | Normal operation in conjunction with JP3 jumpered 1-2 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP2 | 3V3 SW PM BYPASS | Power monitor shunts for main 3.3 V system power are bypassed | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP3 | CNN MON | Normal operation in conjunction with JP6 jumpered 1-2 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP4 | VCOREA PM BYPASS | Power monitor shunts for U4's share of VCOREA + CNN loads are bypassed | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP5 | VCOREB PM BYPASS | Power monitor shunts for VCOREB are bypassed | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP6 | VREGO_A PM BYPASS | Power monitor shunts for VREGO_A are bypassed | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP7 | VBAT | Enable/Disable 3V3 VBAT power | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP8 | VREGI | Enable/Disable 3V3 VREGI power | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP9 | VREGI/VBAT | Onboard 3V3_PM / external source at TP10 supplies VREGI/VBAT | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP10 | VDDIOH | Onboard 3V3_PM/3V3_SW supplies VDDIOH | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP11 | VDDA | VREGO_A_PM powers VDDA | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP12 | VDDIO | VREGO_A_PM powers VDDIO | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP13 | VCOREB | VREGO_B powers VCOREB | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP14 | VCOREA | VREGO_C ties to net VCOREA | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP15 | VREF | DUT ADC VREF is supplied by precision external reference | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP16 | I2C1 SDA | I2C1 DATA pull-up | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP17 | I2C1 SCL | I2C1 CLOCK pull-up | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP18 | TRIG1 | PWR accumulator trigger signal 1 ties to port 1.6 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP19 | TRIG2 | PWR accumulator trigger signal 2 ties to port 1.7 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP20 | UART0 EN | Connect/Disconnect USB-UART bridge to UART0 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP21 | I2C0_SDA | I2C0 DATA pull-up | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP22 | I2C0_SCL | I2C0 CLOCK pull-up | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP23 | UART1 EN | Connect/Disconnect USB-UART bridge to UART1 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP24 | EXT I2C0 EN | Enable/Disable QWIIC interface for I2C0 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP25 | PB1 PU | Enable/Disable 100kΊ pull-up for pushbutton mode, port 2.6 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP26 | PB2 PU | Enable/Disable 100kΊ pull-up for pushbutton mode, port 2.7 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP27 | I2C2 SDA | I2C2 DATA pull-up | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP28 | I2C2 SCL | I2C2 CLOCK pull-up | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP29 | VDDB | USB XCVR VDDB powered from VBUS / powered full time by system 3V3_PM | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP30 | EXT I2C2 EN | Enable/Disable QWIIC interface for I2C2 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP31 | L/R SEL | Select MIC ON R/L CH, I2S microphone data stream | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP32 | MIC-I2S I/O | External I2S/MIC data from I2S I/O / MIC header connected to I2S SDI | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP33 | MIC-I2S/CODEC | Onboard CODEC data / external I2S data from header connects to I2S SDI | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP34 | I2S VDD | Select 1.8V/3.3V for external MIC and DATA I2S interface | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP35 | I2C1 SDA | I2C1 DATA pull-up | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP36 | I2C1 SCL | I2C1 CLOCK pull-up | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP37 | I2S CK SEL | Select SMA connector J6 / onboard crystal oscillator for I2S master clock source | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP38 | DVP CAM PWR | Enable/Disable OVM7692 for DVP camera PWDN input | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP39 | SW CAM PWUP | Camera reset and power up under port pin control | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP40 | HW PWUP / SW PWUP | Camera will reset and power up as soon as 3.3V reaches a valid level | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP41 | CSI CAM I2C EN | Connect/Disconnect I2C1 to CSI camera Digilent P5C I2C | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP42 | TFT DC | TFT data/command select connects to port 2.2 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP43 | TFT CS | Select port 0.3 / port 1.7 to drive TFT CS | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP44 | LED1 EN | Enable/Disable LED1 | -+-----------+-------------------+----------------------------------------------------------------------------------+ -| JP45 | LED2 EN | Enable/Disable LED2 | -+-----------+-------------------+----------------------------------------------------------------------------------+ ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| Name | Name | Settings | Description | ++===========+===================+===============+==================================================================================================+ +| JP1 | 3V3 MON | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Normal operation in conjunction with JP3 jumpered 1-2 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Test access point for current measurement | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP2 | 3V3 SW PM BYPASS | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Power monitor shunts for main 3.3 V system power are bypassed | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Main 3.3V input routes through shunts for power accumulator measurements | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP3 | CNN MON | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Normal operation in conjunction with JP6 jumpered 1-2 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Test access point for current measurement of U4's share of VCOREA and CNN loads | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP4 | VCOREA PM BYPASS | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Power monitor shunts for U4's share of VCOREA + CNN loads are bypassed | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | VCOREA + CNN loads route through shunts for power accumulator | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP5 | VCOREB PM BYPASS | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Power monitor shunts for VCOREB are bypassed | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | VCOREB power routes through shunts for power accumulator | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP6 | VREGO_A PM BYPASS | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Power monitor shunts for VREGO_A are bypassed | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | VREGO_A power routes through shunts for power accumulator | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP7 | VBAT | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables 3V3 VBAT power | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables 3V3 VBAT power | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP8 | VREGI | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Enables 3V3 VREGI power | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Disables 3V3 VREGI power | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP9 | VREGI/VBAT | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-1 | | | Onboard 3V3_PM supplies VREGI/VBAT | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | External source at TP10 supplies VREGI/VBAT | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP10 | VDDIOH | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-1 | | | Onboard 3V3_PM supplies VDDIOH | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Onboard 3V3_SW supplies VDDIOH | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP11 | VDDA | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | VREGO_A_PM powers VDDA | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | VDDA may be powered using TP6 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP12 | VDDIO | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | VREGO_A_PM powers VDDIO | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | VDDIO may be powered using TP7 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP13 | VCOREB | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | VREGO_B powers VCOREB | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | VCOREB may be powered using TP8 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP14 | VCOREA | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | VREGO_C ties to net VCOREA | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Net VCOREA may be powered using TP9; JP17 may also be used as a current test point | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP15 | VREF | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | DUT ADC VREF is supplied by precision external reference | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | External ADC VREF disabled; ref voltage may be injected at JP18.1 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP16 | I2C1 SDA | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2C1 DATA pullup | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Close this jumper as needed to assure proper termination | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP17 | I2C1 SCL | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2C1 CLOCK pullup | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Close this jumper as needed to assure proper termination | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP18 | TRIG1 | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | PWR accumulator trigger signal 1 ties to port 1.6 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | TRIG1 is disabled, so DVP camera PCIF_D10 may be used instead | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP19 | TRIG2 | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | PWR accumulator trigger signal 2 ties to port 1.7 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | TRIG2 is disabled, so DVP camera PCIF_D11 may be used instead | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP20 | UART0 EN | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Closed | | | USB-UART bridge connected to DUT UART0 (RTS and CTS are supported) | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | USB-UART bridge disconnected from DUT UART0 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP21 | I2C0_SDA | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2C0 DATA pull-up | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Close this jumper as needed to assure proper termination | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP22 | I2C0_SCL | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2C0 CLOCK pull-up | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Close this jumper as needed to assure proper termination | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP23 | UART1 EN | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Closed | | | USB-UART bridge connected to DUT UART1 (no HW flow control) | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | USB-UART bridge disconnected from DUT UART1 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP24 | EXT I2C0 EN | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | QWIIC interface for I2C0 enabled by default | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Open this jumper to place the QWIIC level translator into a high-Z state | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP25 | PB1 PU | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | 100kΩ pull-up enabled for pushbutton mode, port 2.6 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Pull-up disabled, allowing port pin to be repurposed (this port shared with AIN6) | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP26 | PB2 PU | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | 100kΩ pull-up enabled for pushbutton mode, port 2.7 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Pull-up disabled, allowing port pin to be repurposed (this port shared with AIN7) | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP27 | I2C2 SDA | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2C2 DATA pull-up | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Close this jumper as needed to assure proper termination | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP28 | I2C2 SCL | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2C2 CLOCK pull-up | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Close this jumper as needed to assure proper termination | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP29 | VDDB | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-1 | | | DUT USB XCVR VDDB powered from VBUS regulated with dedicated 3.3V LDO | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | USB XCVR VDDB powered full time by system 3V3_PM | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP30 | EXT I2C2 EN | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | QWIIC interface for I2C2 enabled by default | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Open this jumper to place the QWIIC level translator into a high-Z state | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP31 | L/R SEL | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | MIC ON R CH, I2S microphone data stream | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | MIC ON L CH, I2S microphone data stream | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP32 | MIC-I2S I/O | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | External I2S data from I2S I/O header connected to I2S SDI. | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | External MIC data from I2S MIC header connected to I2S SDI | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP33 | MIC-I2S/CODEC | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Onboard CODEC data connects to I2S SDI | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | External I2S data (mic or slave I2S) from header connects to I2S SDI | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP34 | I2S VDD | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-1 | | | External MIC and DATA I2S interface headers run at 1.8V | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | External MIC and DATA I2S interface headers run at 3.3V | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP35 | I2C1 SDA | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2C1 DATA pull-up | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Close this jumper as needed to assure proper termination | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP36 | I2C1 SCL | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2C1 CLOCK pull-up | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Close this jumper as needed to assure proper termination | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP37 | I2S CK SEL | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | I2S master clock sourced from SMA connector J6 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | I2S master clock sourced from onboard crystal oscillator | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP38 | DVP CAM PWR | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-1 | | | Sets state of DVP camera PWDN input; default is OFF for OVM7692 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | Sets state of DVP camera PWDN input; 2-3 will power up OVM7692 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP39 | SW CAM PWUP | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Camera reset and power up under port pin control | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Digilent P5C camera powered down, JP39 can over ride this condition | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP40 | HW PWUP / SW PWUP | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | Camera will reset and power up as soon as 3.3V reaches a valid level | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Camera reset and power up under port pin control if JP39 is installed; else, camera off | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP41 | CSI CAM I2C EN | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | CSI camera Digilent P5C I2C connects to I2C1 for register setup | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Level translator and I2C PU are in high-Z state; I2C1 disconnected from P5C registers | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP42 | TFT DC | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | TFT data/command select connects to port 2.2 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Pull jumper if using AIN2 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP43 | TFT CS | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-1 | | | TFT CS driven by port 0.3, shared with UART0 RTS | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 2-3 | | | TFT CS driven by port 1.7, shared with DVP DATA 11 and TRIG2 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP44 | LED1 EN | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | LED0 illuminates when port 2.4 is high | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Pull jumper if using AIN4 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ +| JP45 | LED2 EN | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | 1-2 | | | LED1 illuminates when port 2.5 is high | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | Open | | | Pull jumper if using AIN5 | | +| | | +-----------+ | +-----------------------------------------------------------------------------------------+ | +| | | | | ++-----------+-------------------+---------------+--------------------------------------------------------------------------------------------------+ Programming and Debugging ************************* @@ -270,7 +450,8 @@ SWD port. SWD debug can be accessed through the Cortex 10-pin connector, JH8. Logic levels are fixed to VDDIO (1.8V). Once the debug probe is connected to your host computer, then you can simply run the -``west flash`` command to write a firmware image into flash. +``west flash`` command to write a firmware image into flash. To perform a full erase, +pass the ``--erase`` option when executing ``west flash``. .. note:: diff --git a/boards/adi/max78002evkit/max78002evkit_max78002_m4.dts b/boards/adi/max78002evkit/max78002evkit_max78002_m4.dts index 8b6df6c28c10a..6ba9ded8d4aa6 100644 --- a/boards/adi/max78002evkit/max78002evkit_max78002_m4.dts +++ b/boards/adi/max78002evkit/max78002evkit_max78002_m4.dts @@ -125,3 +125,7 @@ pinctrl-0 = <&owm_io_p0_6 &owm_pe_p0_7>; pinctrl-names = "default"; }; + +&rtc_counter { + status = "okay"; +}; diff --git a/boards/adi/max78002evkit/max78002evkit_max78002_m4.yaml b/boards/adi/max78002evkit/max78002evkit_max78002_m4.yaml index 4631e4e276b55..ffe89807e7add 100644 --- a/boards/adi/max78002evkit/max78002evkit_max78002_m4.yaml +++ b/boards/adi/max78002evkit/max78002evkit_max78002_m4.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - serial @@ -17,6 +16,7 @@ supported: - spi - adc - counter + - rtc_counter - pwm - w1 - flash diff --git a/boards/adi/sdp_k1/adi_sdp_k1.yaml b/boards/adi/sdp_k1/adi_sdp_k1.yaml index 800bedab7de41..b794e9be8f28c 100644 --- a/boards/adi/sdp_k1/adi_sdp_k1.yaml +++ b/boards/adi/sdp_k1/adi_sdp_k1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 384 flash: 2048 supported: diff --git a/boards/alientek/pandora_stm32l475/pandora_stm32l475.yaml b/boards/alientek/pandora_stm32l475/pandora_stm32l475.yaml index d0f6adfdbf8f1..8a1ac76277084 100644 --- a/boards/alientek/pandora_stm32l475/pandora_stm32l475.yaml +++ b/boards/alientek/pandora_stm32l475/pandora_stm32l475.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 512 supported: diff --git a/boards/ambiq/apollo3_evb/apollo3_evb.dts b/boards/ambiq/apollo3_evb/apollo3_evb.dts index e6ff4fcfd80a3..bea88a5c3b91b 100644 --- a/boards/ambiq/apollo3_evb/apollo3_evb.dts +++ b/boards/ambiq/apollo3_evb/apollo3_evb.dts @@ -2,6 +2,7 @@ #include #include "apollo3_evb-pinctrl.dtsi" +#include / { model = "Ambiq Apollo3 Blue evaluation board"; @@ -13,9 +14,11 @@ zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; zephyr,uart-pipe = &uart0; zephyr,flash-controller = &flash; zephyr,bt_hci = &bt_hci_apollo; + zephyr,code-partition = &slot0_partition; }; aliases { @@ -25,6 +28,9 @@ led2 = &led2; sw0 = &button0; sw1 = &button1; + bootloader-led0 = &led0; + mcuboot-led0 = &led0; + rtc = &rtc0; }; leds { @@ -56,14 +62,17 @@ button0: button_0 { gpios = <&gpio0_31 16 GPIO_ACTIVE_LOW>; label = "BTN0"; + zephyr,code = ; }; button1: button_1 { gpios = <&gpio0_31 18 GPIO_ACTIVE_LOW>; label = "BTN1"; + zephyr,code = ; }; button2: button_2 { gpios = <&gpio0_31 19 GPIO_ACTIVE_LOW>; label = "BTN2"; + zephyr,code = ; }; }; }; @@ -77,10 +86,28 @@ #address-cells = <1>; #size-cells = <1>; - /* Set 16KB of storage at the end of the 976KB of flash */ - storage_partition: partition@f0000 { + internal_boot_partition: partition@0 { + label = "internal_bootloader"; + reg = <0x00000000 0xc000>; + }; + + boot_partition: partition@c000 { + label = "mcuboot"; + reg = <0x0000c000 0xc000>; + }; + slot0_partition: partition@18000 { + label = "image-0"; + reg = <0x00018000 0x72000>; + }; + slot1_partition: partition@8a000 { + label = "image-1"; + reg = <0x0008a000 0x72000>; + }; + + /* Set 16KB of storage at the end of the 1024KB of flash */ + storage_partition: partition@fc000 { label = "storage"; - reg = <0x000f0000 0x4000>; + reg = <0x000fc000 0x4000>; }; }; }; @@ -113,7 +140,6 @@ }; &spi0 { - compatible = "ambiq,spi"; pinctrl-0 = <&spi0_default>; pinctrl-names = "default"; cs-gpios = <&gpio0_31 11 GPIO_ACTIVE_LOW>; @@ -122,7 +148,6 @@ }; &i2c3 { - compatible = "ambiq,i2c"; pinctrl-0 = <&i2c3_default>; pinctrl-names = "default"; clock-frequency = ; @@ -163,8 +188,12 @@ status = "okay"; }; +&rtc0 { + status = "okay"; + clock = "XTAL"; +}; + &adc0 { - compatible = "ambiq,adc"; pinctrl-0 = <&adc0_default>; pinctrl-names = "default"; status = "disabled"; diff --git a/boards/ambiq/apollo3p_evb/apollo3p_evb.dts b/boards/ambiq/apollo3p_evb/apollo3p_evb.dts index 4c95d29deb090..56b9ec15fec9f 100644 --- a/boards/ambiq/apollo3p_evb/apollo3p_evb.dts +++ b/boards/ambiq/apollo3p_evb/apollo3p_evb.dts @@ -2,6 +2,7 @@ #include #include "apollo3p_evb-pinctrl.dtsi" +#include / { model = "Ambiq Apollo3 Blue Plus evaluation board"; @@ -25,6 +26,7 @@ led2 = &led2; sw0 = &button0; sw1 = &button1; + rtc = &rtc0; }; leds { @@ -56,14 +58,17 @@ button0: button_0 { gpios = <&gpio0_31 16 GPIO_ACTIVE_LOW>; label = "BTN0"; + zephyr,code = ; }; button1: button_1 { gpios = <&gpio0_31 18 GPIO_ACTIVE_LOW>; label = "BTN1"; + zephyr,code = ; }; button2: button_2 { gpios = <&gpio0_31 19 GPIO_ACTIVE_LOW>; label = "BTN2"; + zephyr,code = ; }; }; }; @@ -113,7 +118,6 @@ }; &spi0 { - compatible = "ambiq,spi"; pinctrl-0 = <&spi0_default>; pinctrl-names = "default"; cs-gpios = <&gpio0_31 11 GPIO_ACTIVE_LOW>; @@ -122,7 +126,6 @@ }; &i2c3 { - compatible = "ambiq,i2c"; pinctrl-0 = <&i2c3_default>; pinctrl-names = "default"; clock-frequency = ; @@ -163,8 +166,12 @@ status = "okay"; }; +&rtc0 { + status = "okay"; + clock = "XTAL"; +}; + &adc0 { - compatible = "ambiq,adc"; pinctrl-0 = <&adc0_default>; pinctrl-names = "default"; status = "disabled"; diff --git a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts index 6b74681be2e76..1a94e0e25cadd 100644 --- a/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts +++ b/boards/ambiq/apollo4p_blue_kxr_evb/apollo4p_blue_kxr_evb.dts @@ -26,6 +26,7 @@ led2 = &led2; sw0 = &button0; sw1 = &button1; + rtc = &rtc0; }; leds { @@ -79,12 +80,16 @@ status = "okay"; }; +&rtc0 { + status = "okay"; + clock = "XTAL"; +}; + &wdt0 { status = "okay"; }; &i2c0 { - compatible = "ambiq,i2c"; pinctrl-0 = <&i2c0_default>; pinctrl-names = "default"; clock-frequency = ; @@ -94,7 +99,6 @@ }; &spi1 { - compatible = "ambiq,spi"; pinctrl-0 = <&spi1_default>; pinctrl-names = "default"; cs-gpios = <&gpio0_31 11 GPIO_ACTIVE_LOW>; diff --git a/boards/ambiq/apollo4p_evb/apollo4p_evb.dts b/boards/ambiq/apollo4p_evb/apollo4p_evb.dts index 2d65320f5ca0c..a37974d10b91e 100644 --- a/boards/ambiq/apollo4p_evb/apollo4p_evb.dts +++ b/boards/ambiq/apollo4p_evb/apollo4p_evb.dts @@ -76,7 +76,6 @@ }; &adc0 { -compatible = "ambiq,adc"; pinctrl-0 = <&adc0_default>; pinctrl-names = "default"; status = "okay"; @@ -96,7 +95,6 @@ compatible = "ambiq,adc"; }; &iom0_i2c { - compatible = "ambiq,i2c"; pinctrl-0 = <&i2c0_default>; pinctrl-names = "default"; clock-frequency = ; @@ -106,7 +104,6 @@ compatible = "ambiq,adc"; }; &iom1_spi { - compatible = "ambiq,spi"; pinctrl-0 = <&spi1_default>; pinctrl-names = "default"; cs-gpios = <&gpio0_31 11 GPIO_ACTIVE_LOW>; diff --git a/boards/antmicro/index.rst b/boards/antmicro/index.rst new file mode 100644 index 0000000000000..34beaee93d25d --- /dev/null +++ b/boards/antmicro/index.rst @@ -0,0 +1,10 @@ +.. _boards-antmicro: + +Antmicro +### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/antmicro/myra_sip_baseboard/Kconfig.defconfig b/boards/antmicro/myra_sip_baseboard/Kconfig.defconfig new file mode 100644 index 0000000000000..21533cc29e9a3 --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/Kconfig.defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_MYRA_SIP_BASEBOARD + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +endif # BOARD_MYRA_SIP_BASEBOARD diff --git a/boards/antmicro/myra_sip_baseboard/Kconfig.myra_sip_baseboard b/boards/antmicro/myra_sip_baseboard/Kconfig.myra_sip_baseboard new file mode 100644 index 0000000000000..5fce139d966a9 --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/Kconfig.myra_sip_baseboard @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MYRA_SIP_BASEBOARD + select SOC_MYRA diff --git a/boards/antmicro/myra_sip_baseboard/board.cmake b/boards/antmicro/myra_sip_baseboard/board.cmake new file mode 100644 index 0000000000000..7595428a879ee --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +set(SUPPORTED_EMU_PLATFORMS renode) +set(RENODE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/support/myra_sip_baseboard.resc) +set(RENODE_UART sysbus.lpuart1) + +board_runner_args(openocd "--config=${BOARD_DIR}/support/openocd_myra_sip_baseboard.cfg") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/antmicro/myra_sip_baseboard/board.yml b/boards/antmicro/myra_sip_baseboard/board.yml new file mode 100644 index 0000000000000..71575059420ed --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/board.yml @@ -0,0 +1,6 @@ +board: + name: myra_sip_baseboard + full_name: Myra SiP Baseboard + vendor: antmicro + socs: + - name: myra diff --git a/boards/antmicro/myra_sip_baseboard/doc/img/myra_sip_baseboard.webp b/boards/antmicro/myra_sip_baseboard/doc/img/myra_sip_baseboard.webp new file mode 100644 index 0000000000000..c521ce0c462a1 Binary files /dev/null and b/boards/antmicro/myra_sip_baseboard/doc/img/myra_sip_baseboard.webp differ diff --git a/boards/antmicro/myra_sip_baseboard/doc/index.rst b/boards/antmicro/myra_sip_baseboard/doc/index.rst new file mode 100644 index 0000000000000..ee33397e453de --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/doc/index.rst @@ -0,0 +1,260 @@ +.. zephyr:board:: myra_sip_baseboard + +Overview +******** + +The Myra SiP Baseboard features Antmicro's **Myra** SiP, which integrates the **STM32G491REI6** MCU, +128kB FRAM, and FTDI FT231XQ USB to UART converter. The board is equipped with temperature, +humidity, and pressure sensors, designed to help monitor conditions in server rooms. + +The sensors are placed on a separate island that is detachable from the main PCB and can be +installed directly in the required place. It provides local storage for data logging and a battery +backup for protection against data loss. The board can be used as a building block for PoC solutions +for monitoring environmental parameters. + +Key features include: + +- STM32G491REI6 MCU (Cortex-M4, 170 MHz) +- 128 KB Fujitsu FRAM +- FTDI FT231XQ USB to UART converter +- 50 mm x 26.5 mm PCB +- USB-C Connector for data and power +- SHT45 temperature + humidity sensor +- BME280 temperature + humidity + pressure sensor +- QWIIC connectors for peripheral expansion +- RTC with battery backup + +More information about the board can be found on `Antmicro's Open Hardware Portal `_. + +Hardware +******** + +Myra SiP provides the following hardware: + +- **STM32G491REI6 MCU**: + + - ARM Cortex-M4 CPU with FPU, up to 170 MHz + - Clock Sources: + + - 4 to 48 MHz external crystal oscillator (HSE) + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz RC (Âą1%) + - Internal low-power 32 kHz RC (Âą5%) + - 2 PLLs for system clock, USB, audio, ADC + - RTC: Real-time clock with hardware calendar, alarms, and calibration + - Timers: + + - 1x 32-bit timer and 2x 16-bit timers with up to 4x IC/OC/PWM or pulse counter and quadrature + (incremental) encoder input + - 3x 16-bit advanced motor control timers with up to 8x PWM channels, dead time generation, + emergency stop + - 1x 16-bit timer with 2x IC/OC, one OCN/PWM, dead time generation, emergency stop + - 2x watchdog timers (independent, window) + - 2x 16-bit basic timers + - SysTick timer + - 1x low-power timer + - I/Os: Up to 86 fast I/Os, most 5V tolerant + - Memory: + + - 512 KB Flash memory with ECC and PCROP protection + - 96 KB SRAM including 32 KB with hardware parity check + - Analog peripherals: + + - 3x 16-bit ADCs with up to 36 channels, hardware oversampling, and resolution up to 16-bit + - 4x 12-bit DAC channels + - 4x ultra-fast rail-to-rail analog comparators + - 4x operational amplifiers with built-in PGA + - Internal temperature sensor and voltage reference with support for three output voltages + (2.048 V, 2.5 V, 2.9 V) + - Communication Interfaces: + + - 2x FDCAN controllers supporting flexible data rate + - 3x I2C Fast Mode Plus (1 Mbit/s) with 20 mA current sink, SMBus/PMBus support + - 5x USART/UART (ISO 7816, LIN, IrDA, modem control) + - 1x LPUART + - 3x SPI interfaces (2x with multiplexed half-duplex I²S) + - 1x SAI (serial audio interface) + - USB 2.0 full-speed with LPM and BCD support + - IRTIM (infrared interface) + - USB Type-C™ / USB Power Delivery (UCPD) + - Other Peripherals: + + - 16-channel DMA controller + - True Random Number Generator (RNG) + - CRC calculation unit, 96-bit unique ID + - Development support: SWD, JTAG, Embedded Trace Macrocell™ + - ECOPACK2ÂŽ compliant packages + +- **128 KB Fujitsu MB85RS1MT FRAM**: Local storage for data logging, allowing non-volatile memory storage. + +- **FTDI FT231XQ USB to UART converter**: Provides a reliable USB to UART interface. + + +More information about STM32G491RE can be found here: + +- `STM32G491RE on www.st.com`_ + +Other board's peripherals: +-------------------------- + +- USB-C Connector: For data and power. +- SHT45 sensor: + + - Relative humidity accuracy: Âą1.0% RH + - Operating humidity range: 0-100% RH + - Temperature accuracy: Âą0.1°C + - Operating temperature range: -40°C to 125°C +- BME280 sensor: + + - Relative humidity accuracy: Âą3% RH + - Temperature accuracy: Âą1°C + - Pressure accuracy: Âą1 hPa + - Operating temperature range: -40°C to 85°C + - Pressure range: 300-1100 hPa +- QWIIC connectors: For easy peripheral expansion. + +Supported Features +------------------ + +The Zephyr ``myra_sip_baseboard`` board target supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; serial | +| | | port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| DAC | on-chip | dac controller | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| EEPROM | on-chip | eeprom | ++-----------+------------+-------------------------------------+ +| NVS | on-chip | nvs | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtc | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| die-temp | on-chip | die temperature sensor | ++-----------+------------+-------------------------------------+ +| FDCAN1 | on-chip | can controller | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | rtc | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported on this Zephyr port. + +Connections and IOs +------------------- + +Antmicro's Myra SiP Baseboard provides the following default pin mappings for peripherals: + +.. rst-class:: rst-columns + +- LPUART_1_TX : PA2 +- LPUART_1_RX : PA3 +- I2C_1_SCL : PB8 +- I2C_1_SDA : PB9 +- SPI_CS2 : PB2 +- SPI_CS3 : PA7 +- SPI_2_SCK : PB13 +- SPI_2_MISO : PB14 +- SPI_2_MOSI : PB15 +- PWM_2_CH1 : PA5 +- USER_PB : PC13 +- LD2 : PA5 +- ADC1_IN1 : PA0 +- DAC1_OUT1 : PA4 +- USB_MCU_N : PA11 +- USB_MCU_P : PA12 +- SWDIO-JMTS : PA13 +- SWCLK-JTCK : PA14 +- JTDI : PA15 +- JTDO : PB3 +- JTRST : PB4 +- FRAM_HOLD (ACTIVE LOW) : PB10 +- FRAM_WP (ACTIVE LOW) : PB11 +- FRAM_CS (ACTIVE LOW) : PB12 +- GPIO_PC10 : PC10 +- GPIO_PC11 : PC11 +- GPIO_PC12 : PC12 +- PF0_OSC : PF0 + +System Clock +------------ + +System clock can be driven by an internal or an external oscillator, as well as by the main PLL +clock. By default, system clock is driven by PLL clock at 170MHz (boost mode selected), which in +turn, is driven by the 8MHz high speed external oscillator (HSE). While the HSE oscillator is +capable of operating at frequencies up to 48 MHz by default, in this configuration, it is +specifically set to 8 MHz. + +Serial Port +----------- + +The Myra SiP Baseboard has 5 U(S)ARTs. The Zephyr console output is assigned to LPUART1. The default +settings are 115200 8N1. + +Programming and Debugging +************************* + +Applications for the ``myra_sip_baseboard`` board target can be built and flashed in the usual way (see :ref:`build_an_application` and :ref:`application_run` for more details). + +Flashing +******** + +This board has a USB-JTAG interface and can be used with OpenOCD. + +Connect the Myra SiP Baseboard to your host computer using the USB port, then build and flash +the application. Here is an example for :zephyr:code-sample:`hello_world`. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: myra_sip_baseboard + :goals: build flash + +Then run a serial host program to connect with the Myra SiP Baseboard, e.g. using picocom: + +.. code-block:: console + + $ picocom /dev/ttyUSB0 -b 115200 + +.. warning:: + The board has only one port that is used for both programming and the console. For this reason, it is + recommended to set ``CONFIG_BOOT_DELAY`` to an arbitrary value. This is especially important when + running twister tests on the device. You should then also use the ``--flash-before`` and + ``--device-flash-timeout=120`` options: + + .. code-block:: console + + $ scripts/twister --device-testing --device-serial /dev/ttyUSB0 --device-serial-baud 115200 -p myra_sip_baseboard --flash-before --device-flash-timeout=120 -v + +Debugging +********* + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: myra_sip_baseboard + :maybe-skip-config: + :goals: debug + +.. _STM32G491RE on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32g491re.html diff --git a/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard.dts b/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard.dts new file mode 100644 index 0000000000000..e2d011fddf01a --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard.dts @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2024 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + compatible = "antmicro,myra-sip-baseboard"; + model = "Myra SiP Baseboard"; + + chosen { + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,canbus = &fdcan1; + zephyr,code-partition = &slot0_partition; + }; + + leds: leds { + compatible = "gpio-leds"; + green_led: led_0 { + gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + green_pwm_led: green_pwm_led { + pwms = <&pwm2 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &green_led; + mcuboot-led0 = &green_led; + pwm-led0 = &green_pwm_led; + sw0 = &user_button; + watchdog0 = &iwdg; + volt-sensor0 = &vref; + volt-sensor1 = &vbat; + rtc = &rtc; + }; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + status = "okay"; +}; + +&pll { + div-m = <2>; + mul-n = <85>; + div-p = <7>; + div-q = <2>; + div-r = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&lpuart1 { + pinctrl-0 = <&lpuart1_tx_pa2 &lpuart1_rx_pa3>; + pinctrl-1 = <&analog_pa2 &analog_pa3>; + pinctrl-names = "default", "sleep"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + pinctrl-names = "default"; + status = "okay"; + + bme280@76 { + compatible = "bosch,bme280"; + reg = <0x76>; + }; + + sht4x@44 { + compatible = "sensirion,sht4x"; + repeatability = <2>; + reg = <0x44>; + }; +}; + +&timers2 { + status = "okay"; + + pwm2: pwm { + status = "okay"; + pinctrl-0 = <&tim2_ch1_pa5>; + pinctrl-names = "default"; + }; +}; + +stm32_lp_tick_source: &lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(34)>; + }; + slot0_partition: partition@8800 { + label = "image-0"; + reg = <0x00008800 DT_SIZE_K(240)>; + }; + slot1_partition: partition@44800 { + label = "image-1"; + reg = <0x00044800 DT_SIZE_K(234)>; + }; + /* Set 4Kb of storage at the end of the 512Kb of flash */ + storage_partition: partition@7f000 { + label = "storage"; + reg = <0x0007f000 DT_SIZE_K(4)>; + }; + }; +}; + +&iwdg { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in1_pa0>; + pinctrl-names = "default"; + st,adc-clock-source = "SYNC"; + st,adc-prescaler = <4>; + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&dac1 { + pinctrl-0 = <&dac1_out1_pa4>; + pinctrl-names = "default"; + status = "okay"; +}; + +&fdcan1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>, + <&rcc STM32_SRC_HSE FDCAN_SEL(0)>; + pinctrl-0 = <&fdcan1_rx_pa11 &fdcan1_tx_pa12>; + pinctrl-names = "default"; + status = "okay"; +}; + +&vref { + status = "okay"; +}; + +&vbat { + status = "okay"; +}; + +&timers6 { + status = "okay"; + st,prescaler = <1>; +}; + +&timers7 { + status = "okay"; + st,prescaler = <1>; +}; diff --git a/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard.yaml b/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard.yaml new file mode 100644 index 0000000000000..5979e67fd174c --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard.yaml @@ -0,0 +1,27 @@ +identifier: myra_sip_baseboard +name: Myra SiP Baseboard +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 128 +flash: 512 +supported: + - nvs + - pwm + - i2c + - gpio + - usb device + - spi + - watchdog + - dma + - can + - rtc + - sensors +testing: + timeout_multiplier: 3 + renode: + uart: sysbus.lpuart1 + resc: boards/antmicro/myra_sip_baseboard/support/myra_sip_baseboard.resc +vendor: antmicro diff --git a/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard_defconfig b/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard_defconfig new file mode 100644 index 0000000000000..163b6236b2315 --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/myra_sip_baseboard_defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/antmicro/myra_sip_baseboard/support/myra_sip_baseboard.repl b/boards/antmicro/myra_sip_baseboard/support/myra_sip_baseboard.repl new file mode 100644 index 0000000000000..7d0aab5169360 --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/support/myra_sip_baseboard.repl @@ -0,0 +1,87 @@ +flash0: Memory.MappedMemory @ sysbus 0x8000000 + size: 0x80000 + +sram0: Memory.MappedMemory @ sysbus 0x20000000 + size: 0x1c000 + +timers2: Timers.STM32_Timer @ sysbus <0x40000000, +0x400> + frequency: 10000000 + initialLimit: 0xffffffff + ->nvic0@28 + +timers6: Timers.STM32_Timer @ sysbus <0x40001000, +0x400> + frequency: 10000000 + initialLimit: 0xffffffff + ->nvic0@54 + +timers7: Timers.STM32_Timer @ sysbus <0x40001400, +0x400> + frequency: 10000000 + initialLimit: 0xffffffff + ->nvic0@55 + +clk_lse: Python.PythonPeripheral @ sysbus 0x40007000 + size: 0x4 + initable: true + filename: "scripts/pydev/rolling-bit.py" + +gpioa: GPIOPort.STM32_GPIOPort @ sysbus <0x48000000, +0x400> + +gpiob: GPIOPort.STM32_GPIOPort @ sysbus <0x48000400, +0x400> + +gpioc: GPIOPort.STM32_GPIOPort @ sysbus <0x48000800, +0x400> + +gpiod: GPIOPort.STM32_GPIOPort @ sysbus <0x48000c00, +0x400> + +gpioe: GPIOPort.STM32_GPIOPort @ sysbus <0x48001000, +0x400> + +gpiof: GPIOPort.STM32_GPIOPort @ sysbus <0x48001400, +0x400> + +gpiog: GPIOPort.STM32_GPIOPort @ sysbus <0x48001800, +0x400> + +greenled: Miscellaneous.LED @ gpioa 0x5 + +gpioa: + 5 -> greenled@0 + +nvic0: IRQControllers.NVIC @ { + sysbus new Bus.BusPointRegistration { address: 0xe000e000; cpu: cpu0 } +} + -> cpu0@0 + +cpu0: CPU.CortexM @ sysbus + cpuType: "cortex-m4f" + nvic: nvic0 + +i2c1: I2C.STM32F7_I2C @ sysbus 0x40005400 + EventInterrupt->nvic0@31 + ErrorInterrupt->nvic0@32 + +sht4x: I2C.SHT45 @ i2c1 0x44 + +adc1: Analog.STM32_ADC @ sysbus 0x50000000 + IRQ->nvic0@18 + +lpuart1: UART.STM32F7_USART @ sysbus 0x40008000 + frequency: 200000000 + lowPowerMode: true + IRQ->nvic0@91 + +rcc: Python.PythonPeripheral @ sysbus 0x40021000 + size: 0x400 + initable: true + filename: "scripts/pydev/flipflop.py" + +rng: Miscellaneous.STM32F4_RNG @ sysbus 0x50060800 + ->nvic0@90 + +rtc: Timers.STM32F4_RTC @ sysbus 0x40002800 + AlarmIRQ->nvic0@41 + +spi2: SPI.STM32SPI @ sysbus 0x40003800 + IRQ->nvic0@36 + +iwdg: Timers.STM32_IndependentWatchdog @ sysbus 0x40003000 + frequency: 32000 + +dwt: Miscellaneous.DWT @ sysbus 0xE0001000 + frequency: 72000000 diff --git a/boards/antmicro/myra_sip_baseboard/support/myra_sip_baseboard.resc b/boards/antmicro/myra_sip_baseboard/support/myra_sip_baseboard.resc new file mode 100644 index 0000000000000..2d794d7c7f535 --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/support/myra_sip_baseboard.resc @@ -0,0 +1,17 @@ +:name: Myra SiP Baseboard +:description: This script is prepared to run Zephyr on the Myra SiP Baseboard. + +$name?="Myra SiP Baseboard" + +using sysbus +mach create $name +machine LoadPlatformDescription $ORIGIN/myra_sip_baseboard.repl + +showAnalyzer lpuart1 + +macro reset +""" + sysbus LoadELF $elf + cpu0 VectorTableOffset `sysbus GetSymbolAddress "_vector_table"` +""" +runMacro $reset diff --git a/boards/antmicro/myra_sip_baseboard/support/openocd_myra_sip_baseboard.cfg b/boards/antmicro/myra_sip_baseboard/support/openocd_myra_sip_baseboard.cfg new file mode 100644 index 0000000000000..dc278051fc9fb --- /dev/null +++ b/boards/antmicro/myra_sip_baseboard/support/openocd_myra_sip_baseboard.cfg @@ -0,0 +1,13 @@ +adapter driver ft232r +adapter speed 1000 + +ft232r vid_pid 0x0403 0x6015 +ft232r tck_num RTS +ft232r tms_num DTR +ft232r tdi_num RI +ft232r tdo_num CTS +ft232r trst_num DSR +ft232r srst_num DCD + +ft232r restore_serial 0x0015 +source [find target/stm32g4x.cfg] diff --git a/boards/arduino/due/arduino_due.yaml b/boards/arduino/due/arduino_due.yaml index 21a71527ffea0..b8beeac60c925 100644 --- a/boards/arduino/due/arduino_due.yaml +++ b/boards/arduino/due/arduino_due.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 512 ram: 96 supported: diff --git a/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m4.yaml b/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m4.yaml index 3917682bd21c0..bdabab68a165d 100644 --- a/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m4.yaml +++ b/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m4.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 288 flash: 1024 supported: diff --git a/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.yaml b/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.yaml index b637d14017b44..285330d8b011c 100644 --- a/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.yaml +++ b/boards/arduino/giga_r1/arduino_giga_r1_stm32h747xx_m7.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 1024 supported: diff --git a/boards/arduino/mkrzero/arduino_mkrzero-pinctrl.dtsi b/boards/arduino/mkrzero/arduino_mkrzero-pinctrl.dtsi index df09f3aed8f61..f4eadc39c95a0 100644 --- a/boards/arduino/mkrzero/arduino_mkrzero-pinctrl.dtsi +++ b/boards/arduino/mkrzero/arduino_mkrzero-pinctrl.dtsi @@ -6,6 +6,18 @@ #include &pinctrl { + adc_default: adc_default { + group1 { + pinmux = , + , + , + , + , + , + ; + }; + }; + dac_default: dac_default { group1 { pinmux = ; @@ -18,6 +30,7 @@ ; }; }; + sercom1_spi_default: sercom1_spi_default { group1 { pinmux = , diff --git a/boards/arduino/mkrzero/arduino_mkrzero.dts b/boards/arduino/mkrzero/arduino_mkrzero.dts index a0f26d57fa0a6..6a30c3be9d799 100644 --- a/boards/arduino/mkrzero/arduino_mkrzero.dts +++ b/boards/arduino/mkrzero/arduino_mkrzero.dts @@ -106,6 +106,13 @@ pinctrl-names = "default"; }; +&adc { + status = "okay"; + + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; +}; + &dac0 { status = "okay"; diff --git a/boards/arduino/mkrzero/arduino_mkrzero.yaml b/boards/arduino/mkrzero/arduino_mkrzero.yaml index 9b695e8609751..ed631fb6262a7 100644 --- a/boards/arduino/mkrzero/arduino_mkrzero.yaml +++ b/boards/arduino/mkrzero/arduino_mkrzero.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - counter diff --git a/boards/arduino/nano_33_ble/arduino_nano_33_ble.yaml b/boards/arduino/nano_33_ble/arduino_nano_33_ble.yaml index 385d3bd1559cc..70e0d6999a96b 100644 --- a/boards/arduino/nano_33_ble/arduino_nano_33_ble.yaml +++ b/boards/arduino/nano_33_ble/arduino_nano_33_ble.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/arduino/nano_33_ble/arduino_nano_33_ble_nrf52840_sense.yaml b/boards/arduino/nano_33_ble/arduino_nano_33_ble_nrf52840_sense.yaml index 6a80eaecf4814..56f57856eef5b 100644 --- a/boards/arduino/nano_33_ble/arduino_nano_33_ble_nrf52840_sense.yaml +++ b/boards/arduino/nano_33_ble/arduino_nano_33_ble_nrf52840_sense.yaml @@ -1,11 +1,10 @@ -identifier: arduino_nano_33_ble//sense +identifier: arduino_nano_33_ble/nrf52840/sense name: Arduino Nano 33 BLE Sense type: mcu arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/arduino/nano_33_ble/arduino_nano_r3_connector.dtsi b/boards/arduino/nano_33_ble/arduino_nano_r3_connector.dtsi index 21a98b50407bc..af20cc6c755ad 100644 --- a/boards/arduino/nano_33_ble/arduino_nano_r3_connector.dtsi +++ b/boards/arduino/nano_33_ble/arduino_nano_r3_connector.dtsi @@ -16,8 +16,8 @@ <4 0 &gpio1 15 0>, /* D4 */ <5 0 &gpio1 13 0>, /* D5 */ <6 0 &gpio1 14 0>, /* D6 */ - <7 0 &gpio0 9 0>, /* D7 */ - <8 0 &gpio0 10 0>, /* D8 */ + <7 0 &gpio0 23 0>, /* D7 */ + <8 0 &gpio0 21 0>, /* D8 */ <9 0 &gpio0 27 0>, /* D9 */ <10 0 &gpio1 2 0>, /* D10 */ <11 0 &gpio1 1 0>, /* D11 / SPI-MOSI */ @@ -27,10 +27,10 @@ <15 0 &gpio0 5 0>, /* D15 / A1 */ <16 0 &gpio0 30 0>, /* D16 / A2 */ <17 0 &gpio0 29 0>, /* D17 / A3 */ - <18 0 &gpio0 14 0>, /* D18 / A4 / I2C-SDA */ - <19 0 &gpio0 15 0>, /* D19 / A5 / I2C-SCL */ + <18 0 &gpio0 31 0>, /* D18 / A4 / I2C-SDA */ + <19 0 &gpio0 2 0>, /* D19 / A5 / I2C-SCL */ <20 0 &gpio0 28 0>, /* D20 / A6 */ - <21 0 &gpio1 3 0>; /* D21 / A7 */ + <21 0 &gpio0 3 0>; /* D21 / A7 */ }; }; diff --git a/boards/arduino/nano_33_ble/board.c b/boards/arduino/nano_33_ble/board.c index 10fd95e74cca6..5f6b14645f1cb 100644 --- a/boards/arduino/nano_33_ble/board.c +++ b/boards/arduino/nano_33_ble/board.c @@ -29,7 +29,7 @@ static int board_init(void) return res; } - return gpio_pin_configure_dt(&user_led, GPIO_OUTPUT_INACTIVE); + return gpio_pin_configure_dt(&user_led, GPIO_OUTPUT_HIGH); } SYS_INIT(board_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/arduino/nano_33_iot/arduino_nano_33_iot-pinctrl.dtsi b/boards/arduino/nano_33_iot/arduino_nano_33_iot-pinctrl.dtsi index 73ac01e129638..438eaaf80b9aa 100644 --- a/boards/arduino/nano_33_iot/arduino_nano_33_iot-pinctrl.dtsi +++ b/boards/arduino/nano_33_iot/arduino_nano_33_iot-pinctrl.dtsi @@ -6,6 +6,18 @@ #include &pinctrl { + adc_default: adc_default { + group1 { + pinmux = , + , + , + , + , + , + ; + }; + }; + pwm_default: pwm_default { group1 { pinmux = ; diff --git a/boards/arduino/nano_33_iot/arduino_nano_33_iot.dts b/boards/arduino/nano_33_iot/arduino_nano_33_iot.dts index f5fc56c015fdc..7a8e3b7e745a6 100644 --- a/boards/arduino/nano_33_iot/arduino_nano_33_iot.dts +++ b/boards/arduino/nano_33_iot/arduino_nano_33_iot.dts @@ -48,6 +48,13 @@ clock-frequency = <48000000>; }; +&adc { + status = "okay"; + + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; +}; + &sercom1 { status = "okay"; compatible = "atmel,sam0-spi"; diff --git a/boards/arduino/nano_33_iot/arduino_nano_33_iot.yaml b/boards/arduino/nano_33_iot/arduino_nano_33_iot.yaml index f7ded1f523947..b75847ab3838c 100644 --- a/boards/arduino/nano_33_iot/arduino_nano_33_iot.yaml +++ b/boards/arduino/nano_33_iot/arduino_nano_33_iot.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - counter diff --git a/boards/arduino/nicla_sense_me/arduino_nicla_sense_me.yaml b/boards/arduino/nicla_sense_me/arduino_nicla_sense_me.yaml index 74e8cab3c6bbb..a138ec5596cab 100644 --- a/boards/arduino/nicla_sense_me/arduino_nicla_sense_me.yaml +++ b/boards/arduino/nicla_sense_me/arduino_nicla_sense_me.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m4.yaml b/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m4.yaml index 727622952e5cf..8b179806eb2fa 100644 --- a/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m4.yaml +++ b/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m4.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 288 flash: 1024 supported: diff --git a/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m7.yaml b/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m7.yaml index 006cd2b35b451..0310b5dce8909 100644 --- a/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m7.yaml +++ b/boards/arduino/nicla_vision/arduino_nicla_vision_stm32h747xx_m7.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 1024 supported: diff --git a/boards/arduino/opta/Kconfig.defconfig b/boards/arduino/opta/Kconfig.defconfig index 1a89b70db5c08..6199be7debe88 100644 --- a/boards/arduino/opta/Kconfig.defconfig +++ b/boards/arduino/opta/Kconfig.defconfig @@ -11,34 +11,10 @@ config NET_L2_ETHERNET endif # NETWORKING -if USB_DEVICE_STACK +if BOARD_ARDUINO_OPTA_STM32H747XX_M7 -config USB_DEVICE_PRODUCT - default "Arduino Opta" +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" -config USB_DEVICE_PID - default 0x0164 - -config USB_DEVICE_VID - default 0x35d1 - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y - -if LOG - -# Logger cannot use itself to log -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF -endchoice - -# Set USB log level to error only -choice USB_DEVICE_LOG_LEVEL_CHOICE - default USB_DEVICE_LOG_LEVEL_ERR -endchoice - -endif # LOG - -endif # USB_DEVICE_STACK +endif # BOARD_ARDUINO_OPTA_STM32H747XX_M7 endif # BOARD_ARDUINO_OPTA diff --git a/boards/arduino/opta/arduino_opta-common.dtsi b/boards/arduino/opta/arduino_opta-common.dtsi index 36a96cc421af6..cf276172889de 100644 --- a/boards/arduino/opta/arduino_opta-common.dtsi +++ b/boards/arduino/opta/arduino_opta-common.dtsi @@ -107,7 +107,7 @@ &adc1 { pinctrl-0 = <&adc1_inp0_pa0_c &adc1_inp6_pf12>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; vref-mv = <10000>; @@ -135,7 +135,7 @@ &adc2 { pinctrl-0 = <&adc2_inp9_pb0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; vref-mv = <10000>; @@ -154,7 +154,7 @@ &adc3 { pinctrl-0 = <&adc3_inp6_pf10 &adc3_inp7_pf8 &adc3_inp8_pf6 &adc3_inp9_pf4 &adc3_inp0_pc2_c>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; vref-mv = <10000>; diff --git a/boards/arduino/opta/arduino_opta_stm32h747xx_m4.yaml b/boards/arduino/opta/arduino_opta_stm32h747xx_m4.yaml index e7495a72ea144..c510be86b804b 100644 --- a/boards/arduino/opta/arduino_opta_stm32h747xx_m4.yaml +++ b/boards/arduino/opta/arduino_opta_stm32h747xx_m4.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 288 flash: 512 supported: diff --git a/boards/arduino/opta/arduino_opta_stm32h747xx_m7.dts b/boards/arduino/opta/arduino_opta_stm32h747xx_m7.dts index cc408d4daf207..d1b63e91e52cf 100644 --- a/boards/arduino/opta/arduino_opta_stm32h747xx_m7.dts +++ b/boards/arduino/opta/arduino_opta_stm32h747xx_m7.dts @@ -16,9 +16,6 @@ compatible = "arduino,opta-m7"; chosen { - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,cdc-acm-uart0 = &cdc_acm_uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; @@ -29,12 +26,10 @@ zephyr_udc0: &usbotg_fs { pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; pinctrl-names = "default"; status = "okay"; - - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; }; +#include <../boards/common/usb/cdc_acm_serial.dtsi> + &clk_hse { clock-frequency = ; hse-bypass; @@ -126,8 +121,3 @@ zephyr_udc0: &usbotg_fs { status = "okay"; }; }; - -/* Assign USB serial (ACM) to M7 to have a working console out of the box */ -&cdc_acm_uart0 { - status = "okay"; -}; diff --git a/boards/arduino/opta/arduino_opta_stm32h747xx_m7.yaml b/boards/arduino/opta/arduino_opta_stm32h747xx_m7.yaml index 5ce1e815a74bc..6169f1b336498 100644 --- a/boards/arduino/opta/arduino_opta_stm32h747xx_m7.yaml +++ b/boards/arduino/opta/arduino_opta_stm32h747xx_m7.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 768 supported: diff --git a/boards/arduino/opta/arduino_opta_stm32h747xx_m7_defconfig b/boards/arduino/opta/arduino_opta_stm32h747xx_m7_defconfig index 7440b2163e333..b57ac0d6f8e18 100644 --- a/boards/arduino/opta/arduino_opta_stm32h747xx_m7_defconfig +++ b/boards/arduino/opta/arduino_opta_stm32h747xx_m7_defconfig @@ -27,6 +27,3 @@ CONFIG_STM32H7_BOOT_M4_AT_INIT=n CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -# Enable USB Stack (needed for the console to work) -CONFIG_USB_DEVICE_STACK=y diff --git a/boards/arduino/portenta_h7/Kconfig.defconfig b/boards/arduino/portenta_h7/Kconfig.defconfig index 002ff75b5a551..3a59127ffa711 100644 --- a/boards/arduino/portenta_h7/Kconfig.defconfig +++ b/boards/arduino/portenta_h7/Kconfig.defconfig @@ -5,39 +5,30 @@ if BOARD_ARDUINO_PORTENTA_H7 if NETWORKING +config REGULATOR + default y + config NET_L2_ETHERNET default y endif # NETWORKING -if USB_DEVICE_STACK +if BOARD_ARDUINO_PORTENTA_H7_STM32H747XX_M7 -config USB_DEVICE_PRODUCT - default "Arduino SA Portenta H7" +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" -config USB_DEVICE_PID - default 0x035b +endif # BOARD_ARDUINO_PORTENTA_H7_STM32H747XX_M7 -config USB_DEVICE_VID - default 0x2341 - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y +endif # BOARD_ARDUINO_PORTENTA_H7 -if LOG +if BT -# Logger cannot use itself to log -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF +choice AIROC_PART + default CYW4343W endchoice -# Set USB log level to error only -choice USB_DEVICE_LOG_LEVEL_CHOICE - default USB_DEVICE_LOG_LEVEL_ERR +choice CYW4343W_MODULE + default CYW4343W_MURATA_1DX endchoice -endif # LOG - -endif # USB_DEVICE_STACK - -endif # BOARD_ARDUINO_PORTENTA_H7 +endif # BT diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7-common.dtsi b/boards/arduino/portenta_h7/arduino_portenta_h7-common.dtsi index e030d9d1cd056..bf6f3348c9309 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7-common.dtsi +++ b/boards/arduino/portenta_h7/arduino_portenta_h7-common.dtsi @@ -209,17 +209,32 @@ }; }; +&rng { + status = "okay"; +}; + &mac { pinctrl-0 = < ð_ref_clk_pa1 - ð_mdio_pa2 ð_crs_dv_pa7 - ð_mdc_pc1 ð_rxd0_pc4 ð_rxd1_pc5 ð_tx_en_pg11 ð_txd1_pg12 ð_txd0_pg13 >; pinctrl-names = "default"; + status = "okay"; +}; + +&mdio { + status = "okay"; + pinctrl-0 = <ð_mdio_pa2 ð_mdc_pc1>; + pinctrl-names = "default"; + + ethernet-phy@0 { + compatible = "ethernet-phy"; + reg = <0x00>; + status = "okay"; + }; }; zephyr_udc0: &usbotg_hs { @@ -243,7 +258,4 @@ zephyr_udc0: &usbotg_hs { <&rcc STM32_SRC_HSI48 USB_SEL(3)>; num-bidir-endpoints = < 4 >; status = "okay"; - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; }; diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.yaml b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.yaml index 352ae2b3cce89..445d14b78095e 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.yaml +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m4.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 288 flash: 1024 supported: diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts index 30b5b06db2720..001d8509059e2 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts @@ -8,6 +8,7 @@ #include #include #include "arduino_portenta_h7-common.dtsi" +#include <../boards/common/usb/cdc_acm_serial.dtsi> / { model = "Arduino Portenta H7 board"; @@ -15,12 +16,10 @@ /* HW resources are split between CM7 and CM4 */ chosen { - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,cdc-acm-uart0 = &cdc_acm_uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_uart; }; oscen: oscen { @@ -87,6 +86,54 @@ &i2c1 { status = "okay"; + + pf1550: pmic@8 { + status = "okay"; + reg = <0x8>; + compatible = "nxp,pf1550"; + + pmic_regulators: regulators { + status = "okay"; + compatible = "nxp,pf1550-regulator"; + pf1550_sw1: BUCK1 { + regulator-init-microvolt = <3000000>; + regulator-boot-on; + }; + pf1550_sw2: BUCK2 { + regulator-init-microvolt = <3300000>; + regulator-boot-on; + }; + pf1550_sw3: BUCK3 { + regulator-init-microvolt = <3300000>; + regulator-init-microamp = <2000000>; + regulator-boot-on; + }; + pf1550_ldo1: LDO1 { + regulator-init-microvolt = <1000000>; + regulator-boot-on; + }; + pf1550_ldo2: LDO2 { + regulator-init-microvolt = <1800000>; + regulator-boot-on; + }; + pf1550_ldo3: LDO3 { + regulator-init-microvolt = <1200000>; + regulator-boot-on; + }; + }; + + pmic_charger: charger { + status = "okay"; + compatible = "nxp,pf1550-charger"; + constant-charge-current-max-microamp = <100000>; + constant-charge-voltage-max-microvolt = <4200000>; + pf1550,int-gpios = <&gpiok 0 0>; + pf1550,led-behaviour = "manual-off"; + pf1550,system-voltage-min-threshold-microvolt = <3500000>; + pf1550,thermistor-monitoring-mode = "thermistor"; + pf1550,vbus-current-limit-microamp = <1500000>; + }; + }; }; /* Only one should be enabled */ @@ -98,10 +145,6 @@ status = "okay"; }; -&cdc_acm_uart0 { - status = "okay"; -}; - &flash0 { partitions { compatible = "fixed-partitions"; @@ -137,3 +180,24 @@ }; }; }; + +&uart7 { + pinctrl-0 = <&uart7_tx_pa15 &uart7_rx_pf6 + &uart7_cts_pf9 &uart7_rts_pf8>; + pinctrl-names = "default"; + current-speed = <115200>; + hw-flow-control; + status = "okay"; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + + murata-1dx { + compatible = "infineon,cyw43xxx-bt-hci"; + bt-reg-on-gpios = <&gpioj 12 GPIO_ACTIVE_HIGH>; + bt-host-wake-gpios = <&gpioj 13 GPIO_ACTIVE_HIGH>; + bt-dev-wake-gpios = <&gpioj 14 GPIO_ACTIVE_HIGH>; + }; + }; +}; diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.yaml b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.yaml index ee73966dbfeda..97a23152c59fa 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.yaml +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.yaml @@ -5,9 +5,15 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 1024 supported: - gpio + - netif:eth + - i2c + - spi + - qspi + - memc + - usb_cdc + - usb_device vendor: arduino diff --git a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig index 06d55f8db39ac..1260af5f054b6 100644 --- a/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig +++ b/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # Enable the internal SMPS regulator -CONFIG_POWER_SUPPLY_DIRECT_SMPS=y +CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO=y # Enable GPIO CONFIG_GPIO=y diff --git a/boards/arduino/portenta_h7/doc/index.rst b/boards/arduino/portenta_h7/doc/index.rst index 3ed69927f4fbd..2d1d167065e7a 100644 --- a/boards/arduino/portenta_h7/doc/index.rst +++ b/boards/arduino/portenta_h7/doc/index.rst @@ -65,6 +65,8 @@ The current Zephyr arduino_portenta_h7 board configuration supports the followin +-----------+------------+-------------------------------------+ | ETHERNET | on-board | eth | +-----------+------------+-------------------------------------+ +| RADIO | Murata 1DX | WiFi and Bluetooth module | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on Zephyr porting. @@ -74,6 +76,22 @@ is used; to enable the use of the external oscillator, manually specify the hardware revision at build time (see :ref:`application_board_version` for information on how to build for specific revisions of the board). +Applications that intend to use BLE must specify hardware revision at build time. + +Currently only BLE is supported on this board, WiFi is not supported. + +Fetch Binary Blobs +****************** + +The board Bluetooth/WiFi module requires fetching some binary blob files, to do +that run the command: + +.. code-block:: console + + west blobs fetch hal_infineon + +.. note:: Only Bluetooth functionality is currently supported. + Resources sharing ================= diff --git a/boards/arduino/uno_r4/arduino_uno_r4_minima.yaml b/boards/arduino/uno_r4/arduino_uno_r4_minima.yaml index 81f3a94866a7a..b106de02aa7a8 100644 --- a/boards/arduino/uno_r4/arduino_uno_r4_minima.yaml +++ b/boards/arduino/uno_r4/arduino_uno_r4_minima.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 supported: - gpio diff --git a/boards/arduino/uno_r4/arduino_uno_r4_wifi.yaml b/boards/arduino/uno_r4/arduino_uno_r4_wifi.yaml index bfe5bc8cdcdf3..30d3dfb89bc4e 100644 --- a/boards/arduino/uno_r4/arduino_uno_r4_wifi.yaml +++ b/boards/arduino/uno_r4/arduino_uno_r4_wifi.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 supported: - gpio diff --git a/boards/arduino/zero/arduino_zero-pinctrl.dtsi b/boards/arduino/zero/arduino_zero-pinctrl.dtsi index 52b04cd64a586..573e05ea0cdea 100644 --- a/boards/arduino/zero/arduino_zero-pinctrl.dtsi +++ b/boards/arduino/zero/arduino_zero-pinctrl.dtsi @@ -6,6 +6,17 @@ #include &pinctrl { + adc_default: adc_default { + group1 { + pinmux = , + , + , + , + , + ; + }; + }; + dac_default: dac_default { group1 { pinmux = ; diff --git a/boards/arduino/zero/arduino_zero.dts b/boards/arduino/zero/arduino_zero.dts index 841e7ab762021..1109ea58b8937 100644 --- a/boards/arduino/zero/arduino_zero.dts +++ b/boards/arduino/zero/arduino_zero.dts @@ -102,6 +102,13 @@ pinctrl-names = "default"; }; +&adc { + status = "okay"; + + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; +}; + &dac0 { status = "okay"; diff --git a/boards/arduino/zero/arduino_zero.yaml b/boards/arduino/zero/arduino_zero.yaml index 771199f1e8fa1..60e0772e289e4 100644 --- a/boards/arduino/zero/arduino_zero.yaml +++ b/boards/arduino/zero/arduino_zero.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - counter diff --git a/boards/arm/mps2/Kconfig b/boards/arm/mps2/Kconfig index 4beda641d532d..0170bebb4d9d9 100644 --- a/boards/arm/mps2/Kconfig +++ b/boards/arm/mps2/Kconfig @@ -1,6 +1,7 @@ # Copyright (c) 2017 Linaro Limited +# Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 config BOARD_MPS2 - select QEMU_TARGET select HAS_COVERAGE_SUPPORT + select QEMU_TARGET if BOARD_MPS2_AN385 || BOARD_MPS2_AN521_CPU0 || BOARD_MPS2_AN521_CPU0_NS || BOARD_MPS2_AN521_CPU1 diff --git a/boards/arm/mps2/Kconfig.defconfig b/boards/arm/mps2/Kconfig.defconfig index b14613b488081..367e09c2a9a17 100644 --- a/boards/arm/mps2/Kconfig.defconfig +++ b/boards/arm/mps2/Kconfig.defconfig @@ -1,7 +1,8 @@ # Copyright (c) 2017 Linaro Limited +# Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if BOARD_MPS2_AN385 +if BOARD_MPS2_AN383 || BOARD_MPS2_AN385 || BOARD_MPS2_AN386 || BOARD_MPS2_AN500 if SERIAL diff --git a/boards/arm/mps2/Kconfig.mps2 b/boards/arm/mps2/Kconfig.mps2 index 0731c5d285508..c350ffeb8cb27 100644 --- a/boards/arm/mps2/Kconfig.mps2 +++ b/boards/arm/mps2/Kconfig.mps2 @@ -1,8 +1,12 @@ # Copyright (c) 2017 Linaro Limited +# Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 config BOARD_MPS2 + select SOC_MPS2_AN383 if BOARD_MPS2_AN383 select SOC_MPS2_AN385 if BOARD_MPS2_AN385 + select SOC_MPS2_AN386 if BOARD_MPS2_AN386 + select SOC_MPS2_AN500 if BOARD_MPS2_AN500 select SOC_MPS2_AN521_CPU0 if BOARD_MPS2_AN521_CPU0 select SOC_MPS2_AN521_CPU0 if BOARD_MPS2_AN521_CPU0_NS select SOC_MPS2_AN521_CPU1 if BOARD_MPS2_AN521_CPU1 diff --git a/boards/arm/mps2/board.cmake b/boards/arm/mps2/board.cmake index 6f38d01281ba2..b52e1958cf4e2 100644 --- a/boards/arm/mps2/board.cmake +++ b/boards/arm/mps2/board.cmake @@ -1,8 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 - -set(SUPPORTED_EMU_PLATFORMS qemu) +# Copyright 2024 Arm Limited and/or its affiliates if(CONFIG_BOARD_MPS2_AN385) + set(SUPPORTED_EMU_PLATFORMS qemu armfvp) set(QEMU_CPU_TYPE_${ARCH} cortex-m3) set(QEMU_FLAGS_${ARCH} -cpu ${QEMU_CPU_TYPE_${ARCH}} @@ -10,7 +10,23 @@ if(CONFIG_BOARD_MPS2_AN385) -nographic -vga none ) + set(ARMFVP_BIN_NAME FVP_MPS2_Cortex-M3) +elseif(CONFIG_BOARD_MPS2_AN383) + set(SUPPORTED_EMU_PLATFORMS armfvp) + set(ARMFVP_BIN_NAME FVP_MPS2_Cortex-M0plus) + set(ARMFVP_FLAGS + -C armcortexm0plusct.NUM_MPU_REGION=8 + -C armcortexm0plusct.USER=1 + -C armcortexm0plusct.VTOR=1 + ) +elseif(CONFIG_BOARD_MPS2_AN386) + set(SUPPORTED_EMU_PLATFORMS armfvp) + set(ARMFVP_BIN_NAME FVP_MPS2_Cortex-M4) +elseif(CONFIG_BOARD_MPS2_AN500) + set(SUPPORTED_EMU_PLATFORMS armfvp) + set(ARMFVP_BIN_NAME FVP_MPS2_Cortex-M7) elseif(CONFIG_BOARD_MPS2_AN521_CPU0 OR CONFIG_BOARD_MPS2_AN521_CPU0_NS OR CONFIG_BOARD_MPS2_AN521_CPU1) + set(SUPPORTED_EMU_PLATFORMS qemu) set(QEMU_CPU_TYPE_${ARCH} cortex-m33) set(QEMU_FLAGS_${ARCH} -cpu ${QEMU_CPU_TYPE_${ARCH}} @@ -19,11 +35,7 @@ elseif(CONFIG_BOARD_MPS2_AN521_CPU0 OR CONFIG_BOARD_MPS2_AN521_CPU0_NS OR CONFIG -m 16 -vga none ) -endif() - -board_set_debugger_ifnset(qemu) -if(CONFIG_BOARD_MPS2_AN521_CPU0 OR CONFIG_BOARD_MPS2_AN521_CPU0_NS OR CONFIG_BOARD_MPS2_AN521_CPU1) # To enable a host tty switch between serial and pty # -chardev serial,path=/dev/ttyS0,id=hostS0 # pty is not available on Windows. @@ -44,3 +56,18 @@ if(CONFIG_BOARD_MPS2_AN521_CPU0 OR CONFIG_BOARD_MPS2_AN521_CPU0_NS OR CONFIG_BOA list(APPEND QEMU_EXTRA_FLAGS "-device;loader,file=${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}") endif() endif() + +board_set_debugger_ifnset(qemu) + +set(ARMFVP_FLAGS ${ARMFVP_FLAGS} +-C fvp_mps2.telnetterminal0.start_telnet=0 +-C fvp_mps2.telnetterminal1.start_telnet=0 +-C fvp_mps2.telnetterminal2.start_telnet=0 +-C fvp_mps2.UART0.out_file=- +-C fvp_mps2.UART0.unbuffered_output=1 +-C fvp_mps2.UART1.out_file=- +-C fvp_mps2.UART1.unbuffered_output=1 +-C fvp_mps2.UART2.out_file=- +-C fvp_mps2.UART2.unbuffered_output=1 +-C fvp_mps2.mps2_visualisation.disable-visualisation=1 +) diff --git a/boards/arm/mps2/board.yml b/boards/arm/mps2/board.yml index 779a8ed21cc7c..5548cd05b171d 100644 --- a/boards/arm/mps2/board.yml +++ b/boards/arm/mps2/board.yml @@ -3,7 +3,10 @@ board: full_name: V2M MPS2 vendor: arm socs: + - name: an383 - name: an385 + - name: an386 + - name: an500 - name: an521 variants: - name: ns diff --git a/boards/arm/mps2/doc/img/mps2_an521.jpg b/boards/arm/mps2/doc/img/mps2.jpg similarity index 100% rename from boards/arm/mps2/doc/img/mps2_an521.jpg rename to boards/arm/mps2/doc/img/mps2.jpg diff --git a/boards/arm/mps2/doc/img/mps2_an385.jpg b/boards/arm/mps2/doc/img/mps2_an385.jpg deleted file mode 100644 index 58e42290939f8..0000000000000 Binary files a/boards/arm/mps2/doc/img/mps2_an385.jpg and /dev/null differ diff --git a/boards/arm/mps2/doc/index.rst b/boards/arm/mps2/doc/index.rst new file mode 100644 index 0000000000000..b102b37fd8046 --- /dev/null +++ b/boards/arm/mps2/doc/index.rst @@ -0,0 +1,10 @@ +.. zephyr:board:: mps2 + +ARM Ltd. +######## + +.. toctree:: + :maxdepth: 1 + :glob: + + * diff --git a/boards/arm/mps2/doc/mps2_an385.rst b/boards/arm/mps2/doc/mps2_an385.rst deleted file mode 100644 index 79f01dc9c53e0..0000000000000 --- a/boards/arm/mps2/doc/mps2_an385.rst +++ /dev/null @@ -1,281 +0,0 @@ -.. _mps2_an385_board: - -ARM V2M MPS2 -############ - -Overview -******** - -The mps2/an385 board configuration is used by Zephyr applications that run on -the V2M MPS2 board. It provides support for the ARM Cortex-M3 (AN385) CPU and -the following devices: - -- Nested Vectored Interrupt Controller (NVIC) -- System Tick System Clock (SYSTICK) -- Cortex-M System Design Kit UART - -.. image:: img/mps2_an385.jpg - :align: center - :alt: ARM V2M MPS2 - -In addition to enabling actual hardware usage, this board configuration can -also use QEMU to emulate the AN385 platform running on the MPS2+. - -More information about the board can be found at the `V2M MPS2 Website`_. - -The Application Note AN385 can be found at `Application Note AN385`_. - -.. note:: - This board configuration makes no claims about its suitability for use - with actual MPS2 hardware systems using AN385, or any other hardware - system. It has been tested on actual hardware, but its primary purpose is - for use with QEMU and unit tests. - -Hardware -******** - -ARM V2M MPS2 provides the following hardware components: - -- ARM Cortex-M3 (AN385) -- ARM IoT Subsystem for Cortex-M -- Form factor: 140x120cm -- ZBTSRAM: 8MB single cycle SRAM, 16MB PSRAM -- Video: QSVGA touch screen panel, 4bit RGB VGA connector -- Audio: Audio Codec -- Debug: - - - ARM JTAG20 connector - - ARM parallel trace connector (MICTOR38) - - 20 pin Cortex debug connector - - 10 pin Cortex debug connector - - ILA connector for FPGA debug - -- Expansion - - - GPIO - - SPI - -.. note:: - 4 MB of flash memory (in ZBTSRAM 1, starting at address 0x00400000) and 4 MB of RAM - (in ZBTSRAM 2 & 3, starting at address 0x20000000) are available. - -Supported Features -================== - -The mps2/an385 board configuration supports the following hardware features: - -+-----------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+=====================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+-------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+-------------------------------------+ -| UART | on-chip | serial port-polling; | -| | | serial port-interrupt | -+-----------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+-------------------------------------+ -| WATCHDOG | on-chip | watchdog | -+-----------+------------+-------------------------------------+ -| TIMER | on-chip | counter | -+-----------+------------+-------------------------------------+ -| DUALTIMER | on-chip | counter | -+-----------+------------+-------------------------------------+ - -Other hardware features are not currently supported by the port. -See the `V2M MPS2 Website`_ for a complete list of V2M MPS2 board hardware -features. - -The default configuration can be found in -:zephyr_file:`boards/arm/mps2/mps2_an385_defconfig` - -Interrupt Controller -==================== - -MPS2 is a Cortex-M3 based SoC and has 15 fixed exceptions and 45 IRQs. - -A Cortex-M3/4-based board uses vectored exceptions. This means each exception -calls a handler directly from the vector table. - -Handlers are provided for exceptions 1-6, 11-12, and 14-15. The table here -identifies the handlers used for each exception. - -+------+------------+----------------+--------------------------+ -| Exc# | Name | Remarks | Used by Zephyr Kernel | -+======+============+================+==========================+ -| 1 | Reset | | system initialization | -+------+------------+----------------+--------------------------+ -| 2 | NMI | | system fatal error | -+------+------------+----------------+--------------------------+ -| 3 | Hard fault | | system fatal error | -+------+------------+----------------+--------------------------+ -| 4 | MemManage | MPU fault | system fatal error | -+------+------------+----------------+--------------------------+ -| 5 | Bus | | system fatal error | -+------+------------+----------------+--------------------------+ -| 6 | Usage | undefined | system fatal error | -| | fault | instruction, | | -| | | or switch | | -| | | attempt to ARM | | -| | | mode | | -+------+------------+----------------+--------------------------+ -| 11 | SVC | | system calls, kernel | -| | | | run-time exceptions, | -| | | | and IRQ offloading | -+------+------------+----------------+--------------------------+ -| 12 | Debug | | system fatal error | -| | monitor | | | -+------+------------+----------------+--------------------------+ -| 14 | PendSV | | context switch | -+------+------------+----------------+--------------------------+ -| 15 | SYSTICK | | system clock | -+------+------------+----------------+--------------------------+ - -Pin Mapping -=========== - -The ARM V2M MPS2 Board has 4 GPIO controllers. These controllers are responsible -for pin muxing, input/output, pull-up, etc. - -All GPIO controller pins are exposed via the following sequence of pin numbers: - -- Pins 0 - 15 are for GPIO 0 -- Pins 16 - 31 are for GPIO 1 -- Pins 32 - 47 are for GPIO 2 -- Pins 48 - 51 are for GPIO 3 - -Mapping from the ARM MPS2 Board pins to GPIO controllers: - -.. rst-class:: rst-columns - - - D0 : EXT_0 - - D1 : EXT_4 - - D2 : EXT_2 - - D3 : EXT_3 - - D4 : EXT_1 - - D5 : EXT_6 - - D6 : EXT_7 - - D7 : EXT_8 - - D8 : EXT_9 - - D9 : EXT_10 - - D10 : EXT_12 - - D11 : EXT_13 - - D12 : EXT_14 - - D13 : EXT_11 - - D14 : EXT_15 - - D15 : EXT_5 - - D16 : EXT_16 - - D17 : EXT_17 - - D18 : EXT_18 - - D19 : EXT_19 - - D20 : EXT_20 - - D21 : EXT_21 - - D22 : EXT_22 - - D23 : EXT_23 - - D24 : EXT_24 - - D25 : EXT_25 - - D26 : EXT_26 - - D27 : EXT_30 - - D28 : EXT_28 - - D29 : EXT_29 - - D30 : EXT_27 - - D31 : EXT_32 - - D32 : EXT_33 - - D33 : EXT_34 - - D34 : EXT_35 - - D35 : EXT_36 - - D36 : EXT_38 - - D37 : EXT_39 - - D38 : EXT_40 - - D39 : EXT_44 - - D40 : EXT_41 - - D41 : EXT_31 - - D42 : EXT_37 - - D43 : EXT_42 - - D44 : EXT_43 - - D45 : EXT_45 - - D46 : EXT_46 - - D47 : EXT_47 - - D48 : EXT_48 - - D49 : EXT_49 - - D50 : EXT_50 - - D51 : EXT_51 - -Peripheral Mapping: - -.. rst-class:: rst-columns - - - UART_3_RX : D0 - - UART_3_TX : D1 - - SPI_3_CS : D10 - - SPI_3_MOSI : D11 - - SPI_3_MISO : D12 - - SPI_3_SCLK : D13 - - I2C_3_SDA : D14 - - I2C_3_SCL : D15 - - UART_4_RX : D26 - - UART_4_TX : D30 - - SPI_4_CS : D36 - - SPI_4_MOSI : D37 - - SPI_4_MISO : D38 - - SPI_4_SCK : D39 - - I2C_4_SDA : D40 - - I2C_4_SCL : D41 - -For more details please refer to `MPS2 Technical Reference Manual (TRM)`_. - -System Clock -============ - -The V2M MPS2 main clock is 24 MHz. - -Serial Port -=========== - -The V2M MPS2 processor has five UARTs. Both the UARTs have only two wires for -RX/TX and no flow control (CTS/RTS) or FIFO. The Zephyr console output, by -default, is utilizing UART0. - -Programming and Debugging -************************* - -Flashing -======== - -V2M MPS2 provides: - -- A USB connection to the host computer, which exposes a Mass Storage and an - USB Serial Port. -- A Serial Flash device, which implements the USB flash disk file storage. -- A physical UART connection which is relayed over interface USB Serial port. - -Flashing an application to V2M MPS2 ------------------------------------ - -Here is an example for the :zephyr:code-sample:`hello_world` application. - -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: mps2/an385 - :goals: build - -Connect the V2M MPS2 to your host computer using the USB port and you should -see a USB connection which exposes a Mass Storage and a USB Serial Port. -Copy the generated zephyr.bin in the exposed drive. -Reset the board and you should be able to see on the corresponding Serial Port -the following message: - -.. code-block:: console - - Hello World! arm - - -.. _V2M MPS2 Website: - https://developer.mbed.org/platforms/ARM-MPS2/ - -.. _MPS2 Technical Reference Manual (TRM): - http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_05_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_05_en.pdf - -.. _Application Note AN385: - http://infocenter.arm.com/help/topic/com.arm.doc.dai0385c/DAI0385C_cortex_m3_on_v2m_mps2.pdf diff --git a/boards/arm/mps2/doc/mps2_an521.rst b/boards/arm/mps2/doc/mps2_an521.rst index 33a4f4d7ca6ef..067b4f286b0fe 100644 --- a/boards/arm/mps2/doc/mps2_an521.rst +++ b/boards/arm/mps2/doc/mps2_an521.rst @@ -15,7 +15,7 @@ CPU and the following devices: - Cortex-M System Design Kit GPIO - Cortex-M System Design Kit UART -.. image:: img/mps2_an521.jpg +.. image:: img/mps2.jpg :align: center :alt: ARM MPS2+ AN521 diff --git a/boards/arm/mps2/doc/mps2_armv6m.rst b/boards/arm/mps2/doc/mps2_armv6m.rst new file mode 100644 index 0000000000000..11666d3cf626d --- /dev/null +++ b/boards/arm/mps2/doc/mps2_armv6m.rst @@ -0,0 +1,281 @@ +.. _mps2_armv6m_board: + +ARM V2M MPS2 Armv6-m (AN383) +############################ + +Overview +******** + +Currently ``mps2/an383`` is the only mps2 Armv6-m based board target supported in Zephyr. +It provides support for the ARM Cortex-M0+ (AN383) CPU and the following devices: + +- Nested Vectored Interrupt Controller (NVIC) +- System Tick System Clock (SYSTICK) +- Cortex-M System Design Kit UART + +.. image:: img/mps2.jpg + :align: center + :alt: ARM V2M MPS2 + +In addition to enabling actual hardware usage, this board target can +also use `FVP`_. to emulate the AN383 platform running on the MPS2+. + +More information about the board can be found at the `V2M MPS2 Website`_. + +The Application Note AN383 can be found at `Application Note AN383`_. + +.. note:: + This board target makes no claims about its suitability for use + with actual MPS2 hardware systems using AN383, or any other hardware + system. It has been tested on FVP. + + +Hardware +******** + +ARM V2M MPS2 AN383 provides the following hardware components: + +- ARM Cortex-M0+ +- ARM IoT Subsystem for Cortex-M +- Form factor: 140x120cm +- ZBTSRAM: 8MB single cycle SRAM, 16MB PSRAM +- Video: QSVGA touch screen panel, 4bit RGB VGA connector +- Audio: Audio Codec +- Debug: + + - ARM JTAG20 connector + - ARM parallel trace connector (MICTOR38) + - 20 pin Cortex debug connector + - 10 pin Cortex debug connector + - ILA connector for FPGA debug + +- Expansion + + - GPIO + - SPI + +.. note:: + 4 MB of flash memory (in ZBTSRAM 1, starting at address 0x00400000) and 4 MB of RAM + (in ZBTSRAM 2 & 3, starting at address 0x20000000) are available. + +Supported Features +================== + +The ``mps2/an383`` board target supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ +| TIMER | on-chip | counter | ++-----------+------------+-------------------------------------+ +| DUALTIMER | on-chip | counter | ++-----------+------------+-------------------------------------+ + +Other hardware features are not currently supported by the port. +See the `V2M MPS2 Website`_ for a complete list of V2M MPS2 board hardware +features. + +The default configuration can be found in +:zephyr_file:`boards/arm/mps2/mps2_an383_defconfig` + +Interrupt Controller +==================== + +MPS2 is a Cortex-M0+ based SoC and has 6 fixed exceptions and 32 IRQs. + +A Cortex-M0+ board uses vectored exceptions. This means each exception +calls a handler directly from the vector table. + +Handlers are provided for exceptions 1-3, 11, and 14-15. The table here +MPS2 is a Cortex-M0+ based SoC and has 15 fixed exceptions and 45 IRQs. + ++------+------------+----------------+--------------------------+ +| Exc# | Name | Remarks | Used by Zephyr Kernel | ++======+============+================+==========================+ +| 1 | Reset | | system initialization | ++------+------------+----------------+--------------------------+ +| 2 | NMI | | system fatal error | ++------+------------+----------------+--------------------------+ +| 3 | Hard fault | | system fatal error | ++------+------------+----------------+--------------------------+ +| 11 | SVC | | system calls, kernel | +| | | | run-time exceptions, | +| | | | and IRQ offloading | ++------+------------+----------------+--------------------------+ +| 14 | PendSV | | context switch | ++------+------------+----------------+--------------------------+ +| 15 | SYSTICK | optional | system clock | ++------+------------+----------------+--------------------------+ + +Pin Mapping +=========== + +The ARM V2M MPS2 Board has 4 GPIO controllers. These controllers are responsible +for pin muxing, input/output, pull-up, etc. + +All GPIO controller pins are exposed via the following sequence of pin numbers: + +- Pins 0 - 15 are for GPIO 0 +- Pins 16 - 31 are for GPIO 1 +- Pins 32 - 47 are for GPIO 2 +- Pins 48 - 51 are for GPIO 3 + +Mapping from the ARM MPS2 Board pins to GPIO controllers: + +.. rst-class:: rst-columns + + - D0 : EXT_0 + - D1 : EXT_4 + - D2 : EXT_2 + - D3 : EXT_3 + - D4 : EXT_1 + - D5 : EXT_6 + - D6 : EXT_7 + - D7 : EXT_8 + - D8 : EXT_9 + - D9 : EXT_10 + - D10 : EXT_12 + - D11 : EXT_13 + - D12 : EXT_14 + - D13 : EXT_11 + - D14 : EXT_15 + - D15 : EXT_5 + - D16 : EXT_16 + - D17 : EXT_17 + - D18 : EXT_18 + - D19 : EXT_19 + - D20 : EXT_20 + - D21 : EXT_21 + - D22 : EXT_22 + - D23 : EXT_23 + - D24 : EXT_24 + - D25 : EXT_25 + - D26 : EXT_26 + - D27 : EXT_30 + - D28 : EXT_28 + - D29 : EXT_29 + - D30 : EXT_27 + - D31 : EXT_32 + - D32 : EXT_33 + - D33 : EXT_34 + - D34 : EXT_35 + - D35 : EXT_36 + - D36 : EXT_38 + - D37 : EXT_39 + - D38 : EXT_40 + - D39 : EXT_44 + - D40 : EXT_41 + - D41 : EXT_31 + - D42 : EXT_37 + - D43 : EXT_42 + - D44 : EXT_43 + - D45 : EXT_45 + - D46 : EXT_46 + - D47 : EXT_47 + - D48 : EXT_48 + - D49 : EXT_49 + - D50 : EXT_50 + - D51 : EXT_51 + +Peripheral Mapping: + +.. rst-class:: rst-columns + + - UART_3_RX : D0 + - UART_3_TX : D1 + - SPI_3_CS : D10 + - SPI_3_MOSI : D11 + - SPI_3_MISO : D12 + - SPI_3_SCLK : D13 + - I2C_3_SDA : D14 + - I2C_3_SCL : D15 + - UART_4_RX : D26 + - UART_4_TX : D30 + - SPI_4_CS : D36 + - SPI_4_MOSI : D37 + - SPI_4_MISO : D38 + - SPI_4_SCK : D39 + - I2C_4_SDA : D40 + - I2C_4_SCL : D41 + +For more details please refer to `MPS2 Technical Reference Manual (TRM)`_. + +System Clock +============ + +The V2M MPS2 main clock is 24 MHz. + +Serial Port +=========== + +The V2M MPS2 processor has five UARTs. Both the UARTs have only two wires for +RX/TX and no flow control (CTS/RTS) or FIFO. The Zephyr console output, by +default, is utilizing UART0. + +Programming and Debugging +************************* + +Flashing +======== + +V2M MPS2 provides: + +- A USB connection to the host computer, which exposes a Mass Storage and an + USB Serial Port. +- A Serial Flash device, which implements the USB flash disk file storage. +- A physical UART connection which is relayed over interface USB Serial port. + +Flashing an application to V2M MPS2 +----------------------------------- + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mps2/an383 + :goals: build + +Connect the V2M MPS2 to your host computer using the USB port and you should +see a USB connection which exposes a Mass Storage and a USB Serial Port. +Copy the generated zephyr.bin in the exposed drive. +Reset the board and you should be able to see on the corresponding Serial Port +the following message: + +.. code-block:: console + + Hello World! arm + +Running an applicatoin with FVP +------------------------------- + +Here is the same example for running with FVP. +Set the ``ARMFVP_BIN_PATH`` environemnt variable to the location of your FVP you have downloaded from `here `_ + +.. code-block:: console + + export ARMFVP_BIN_PATH=/home/../FVP_MPS2/ + +Then build with the same command you would use normally, and run with ``west build -t run_armfvp``. + +.. _V2M MPS2 Website: + https://developer.mbed.org/platforms/ARM-MPS2/ + +.. _MPS2 Technical Reference Manual (TRM): + https://developer.arm.com/documentation/100112/0200/ + +.. _Application Note AN383: + https://documentation-service.arm.com/static/5ed1051dca06a95ce53f88a1 + +.. _FVP: + https://developer.arm.com/downloads/view/FMFVP diff --git a/boards/arm/mps2/doc/mps2_armv7m.rst b/boards/arm/mps2/doc/mps2_armv7m.rst new file mode 100644 index 0000000000000..ab6fab5d2928d --- /dev/null +++ b/boards/arm/mps2/doc/mps2_armv7m.rst @@ -0,0 +1,308 @@ +.. _mps2_armv7m_board: + +ARM V2M MPS2 Armv7-m (AN385/AN386/AN500) +######################################## + +Overview +******** + +The ``mps2/an385``, ``mps2/an386``, and ``mps2/an500`` board targets are three of +the mps2 Armv7-m based board targets supported in Zephyr. This document +provides details about the support provided for these three Armv7-m mps2 board targets +(**AN385**, **AN386**, **AN500**) and the following devices: + +- Nested Vectored Interrupt Controller (NVIC) +- System Tick System Clock (SYSTICK) +- Cortex-M System Design Kit UART + +.. image:: img/mps2.jpg + :align: center + :alt: ARM V2M MPS2 + +In addition to enabling actual hardware usage, these board targets can +also use `FVP`_ to emulate the platforms running on the MPS2+. + +More information about the board can be found at the `V2M MPS2 Website`_. + +The application note for each of the board can be found as follows: + +- AN385 can be found at `Application Note AN385`_ +- AN386 can be found at `Application Note AN386`_ +- AN500 can be found at `Application Note AN500`_ + +AN385 is also supported to run with QEMU, and is set to run with QEMU by default. + +.. note:: + These board targets makes no claims about its suitability for use + with actual MPS2 hardware systems, or any other hardware + system. + +Hardware +******** + +ARM V2M MPS2 provides the following hardware components: + +- ARM Cortex-M Chip +- ARM IoT Subsystem for Cortex-M +- Form factor: 140x120cm +- ZBTSRAM: 8MB single cycle SRAM, 16MB PSRAM +- Video: QSVGA touch screen panel, 4bit RGB VGA connector +- Audio: Audio Codec +- Debug: + + - ARM JTAG20 connector + - ARM parallel trace connector (MICTOR38) + - 20 pin Cortex debug connector + - 10 pin Cortex debug connector + - ILA connector for FPGA debug + +- Expansion + + - GPIO + - SPI + +.. note:: + 4 MB of flash memory (in ZBTSRAM 1, starting at address 0x00400000) and 4 MB of RAM + (in ZBTSRAM 2 & 3, starting at address 0x20000000) are available. + +Supported Features +================== + +The ``mps2/an385``, ``mps2/an386``, and ``mps2/an500`` board targets support the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ +| TIMER | on-chip | counter | ++-----------+------------+-------------------------------------+ +| DUALTIMER | on-chip | counter | ++-----------+------------+-------------------------------------+ + +Other hardware features are not currently supported by the port. +See the `V2M MPS2 Website`_ for a complete list of V2M MPS2 board hardware +features. + +The default configuration can be found in +:zephyr_file:`boards/arm/mps2/mps2_an385_defconfig` +or similarly in ``mps2_anxxx_defconfig`` for the other applicable boards. + +Interrupt Controller +==================== + +MPS2 is a Cortex-M based SoC and has 15 fixed exceptions and 45 IRQs. + +A Cortex-M3/4/7-based board uses vectored exceptions. This means each exception +calls a handler directly from the vector table. + +Handlers are provided for exceptions 1-6, 11-12, and 14-15. The table here +identifies the handlers used for each exception. + ++------+------------+----------------+--------------------------+ +| Exc# | Name | Remarks | Used by Zephyr Kernel | ++======+============+================+==========================+ +| 1 | Reset | | system initialization | ++------+------------+----------------+--------------------------+ +| 2 | NMI | | system fatal error | ++------+------------+----------------+--------------------------+ +| 3 | Hard fault | | system fatal error | ++------+------------+----------------+--------------------------+ +| 4 | MemManage | MPU fault | system fatal error | ++------+------------+----------------+--------------------------+ +| 5 | Bus | | system fatal error | ++------+------------+----------------+--------------------------+ +| 6 | Usage | undefined | system fatal error | +| | fault | instruction, | | +| | | or switch | | +| | | attempt to ARM | | +| | | mode | | ++------+------------+----------------+--------------------------+ +| 11 | SVC | | system calls, kernel | +| | | | run-time exceptions, | +| | | | and IRQ offloading | ++------+------------+----------------+--------------------------+ +| 12 | Debug | | system fatal error | +| | monitor | | | ++------+------------+----------------+--------------------------+ +| 14 | PendSV | | context switch | ++------+------------+----------------+--------------------------+ +| 15 | SYSTICK | | system clock | ++------+------------+----------------+--------------------------+ + +Pin Mapping +=========== + +The ARM V2M MPS2 Board has 4 GPIO controllers. These controllers are responsible +for pin muxing, input/output, pull-up, etc. + +All GPIO controller pins are exposed via the following sequence of pin numbers: + +- Pins 0 - 15 are for GPIO 0 +- Pins 16 - 31 are for GPIO 1 +- Pins 32 - 47 are for GPIO 2 +- Pins 48 - 51 are for GPIO 3 + +Mapping from the ARM MPS2 Board pins to GPIO controllers: + +.. rst-class:: rst-columns + + - D0 : EXT_0 + - D1 : EXT_4 + - D2 : EXT_2 + - D3 : EXT_3 + - D4 : EXT_1 + - D5 : EXT_6 + - D6 : EXT_7 + - D7 : EXT_8 + - D8 : EXT_9 + - D9 : EXT_10 + - D10 : EXT_12 + - D11 : EXT_13 + - D12 : EXT_14 + - D13 : EXT_11 + - D14 : EXT_15 + - D15 : EXT_5 + - D16 : EXT_16 + - D17 : EXT_17 + - D18 : EXT_18 + - D19 : EXT_19 + - D20 : EXT_20 + - D21 : EXT_21 + - D22 : EXT_22 + - D23 : EXT_23 + - D24 : EXT_24 + - D25 : EXT_25 + - D26 : EXT_26 + - D27 : EXT_30 + - D28 : EXT_28 + - D29 : EXT_29 + - D30 : EXT_27 + - D31 : EXT_32 + - D32 : EXT_33 + - D33 : EXT_34 + - D34 : EXT_35 + - D35 : EXT_36 + - D36 : EXT_38 + - D37 : EXT_39 + - D38 : EXT_40 + - D39 : EXT_44 + - D40 : EXT_41 + - D41 : EXT_31 + - D42 : EXT_37 + - D43 : EXT_42 + - D44 : EXT_43 + - D45 : EXT_45 + - D46 : EXT_46 + - D47 : EXT_47 + - D48 : EXT_48 + - D49 : EXT_49 + - D50 : EXT_50 + - D51 : EXT_51 + +Peripheral Mapping: + +.. rst-class:: rst-columns + + - UART_3_RX : D0 + - UART_3_TX : D1 + - SPI_3_CS : D10 + - SPI_3_MOSI : D11 + - SPI_3_MISO : D12 + - SPI_3_SCLK : D13 + - I2C_3_SDA : D14 + - I2C_3_SCL : D15 + - UART_4_RX : D26 + - UART_4_TX : D30 + - SPI_4_CS : D36 + - SPI_4_MOSI : D37 + - SPI_4_MISO : D38 + - SPI_4_SCK : D39 + - I2C_4_SDA : D40 + - I2C_4_SCL : D41 + +For more details please refer to `MPS2 Technical Reference Manual (TRM)`_. + +System Clock +============ + +The V2M MPS2 main clock is 24 MHz. + +Serial Port +=========== + +The V2M MPS2 processor has five UARTs. Both the UARTs have only two wires for +RX/TX and no flow control (CTS/RTS) or FIFO. The Zephyr console output, by +default, is utilizing UART0. + +Programming and Debugging +************************* + +Flashing +======== + +V2M MPS2 provides: + +- A USB connection to the host computer, which exposes a Mass Storage and an + USB Serial Port. +- A Serial Flash device, which implements the USB flash disk file storage. +- A physical UART connection which is relayed over interface USB Serial port. + +Flashing an application to V2M MPS2 +----------------------------------- + +Here is an example for the :zephyr:code-sample:`hello_world` application with AN385. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mps2/an385 + :goals: build + +Connect the V2M MPS2 to your host computer using the USB port and you should +see a USB connection which exposes a Mass Storage and a USB Serial Port. +Copy the generated zephyr.bin in the exposed drive. +Reset the board and you should be able to see on the corresponding Serial Port +the following message: + +.. code-block:: console + + Hello World! arm + +Running an applicatoin with FVP +------------------------------- + +Here is the same example for running with FVP. +Set the ``ARMFVP_BIN_PATH`` environemnt variable to the location of your FVP you have downloaded from `here `_ + +.. code-block:: console + + export ARMFVP_BIN_PATH=/home/../FVP_MPS2/ + +Then build with the same command you would use normally, and run with ``west build -t run_armfvp``. + +.. _V2M MPS2 Website: + https://developer.mbed.org/platforms/ARM-MPS2/ + +.. _MPS2 Technical Reference Manual (TRM): + https://developer.arm.com/documentation/100112/0200/ + +.. _Application Note AN385: + https://documentation-service.arm.com/static/5ed107a5ca06a95ce53f89e3 + +.. _Application Note AN386: + https://documentation-service.arm.com/static/5ed1094dca06a95ce53f8a9f + +.. _Application Note AN500: + https://documentation-service.arm.com/static/5ed112fcca06a95ce53f8eb3 + +.. _FVP: + https://developer.arm.com/downloads/view/FMFVP diff --git a/boards/arm/mps2/mps2_an383.dts b/boards/arm/mps2/mps2_an383.dts new file mode 100644 index 0000000000000..ef21f37b3f7dc --- /dev/null +++ b/boards/arm/mps2/mps2_an383.dts @@ -0,0 +1,30 @@ +/* + * Copyright 2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include "mps2_base.dtsi" + +/* FVP does not support uart3 and uart4 */ +/* hence we delete them for AN383 in FVP */ +/delete-node/ &uart3; +/delete-node/ &uart4; + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m0+"; + reg = <0>; + }; + }; +}; diff --git a/boards/arm/mps2/mps2_an383.yaml b/boards/arm/mps2/mps2_an383.yaml new file mode 100644 index 0000000000000..249225737754a --- /dev/null +++ b/boards/arm/mps2/mps2_an383.yaml @@ -0,0 +1,18 @@ +identifier: mps2/an383 +name: ARM V2M MPS2-an383 +type: mcu +arch: arm +simulation: + - name: armfvp + exec: FVP_MPS2_Cortex-M0plus +toolchain: + - zephyr + - gnuarmemb +supported: + - counter + - netif:serial-net + - gpio + - watchdog +testing: + default: true +vendor: arm diff --git a/boards/arm/mps2/mps2_an383_defconfig b/boards/arm/mps2/mps2_an383_defconfig new file mode 100644 index 0000000000000..aaa7c33d63d46 --- /dev/null +++ b/boards/arm/mps2/mps2_an383_defconfig @@ -0,0 +1,20 @@ +# +# Copyright 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_RUNTIME_NMI=y + +# GPIOs +CONFIG_GPIO=y + +# Serial +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y + +CONFIG_ARM_MPU=y + +# 0x0 is a valid address, we cannot prevent access to that area +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y diff --git a/boards/arm/mps2/mps2_an385.dts b/boards/arm/mps2/mps2_an385.dts index d2db1cebed0a5..fd7279d203d43 100644 --- a/boards/arm/mps2/mps2_an385.dts +++ b/boards/arm/mps2/mps2_an385.dts @@ -1,58 +1,25 @@ -/* SPDX-License-Identifier: Apache-2.0 */ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2024 Arm Limited and/or its affiliates + */ /dts-v1/; #include #include #include +#include "mps2_base.dtsi" -/ { - compatible = "arm,mps2"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - led0 = &led_0; - led1 = &led_1; - sw0 = &user_button_0; - sw1 = &user_button_1; - watchdog0 = &wdog0; - }; - - chosen { - zephyr,console = &uart0; - zephyr,shell-uart = &uart0; - zephyr,uart-pipe = &uart1; - zephyr,sram = &sram0; - zephyr,flash = &flash0; - }; +/* + * FVP does not support uart3 and uart4 whilst QEMU does. + * So if using QEMU, you might want to comment out the following two lines + */ - leds { - compatible = "gpio-leds"; - led_0: led_0 { - gpios = <&gpio_led0 0>; - label = "USERLED0"; - }; - led_1: led_1 { - gpios = <&gpio_led0 1>; - label = "USERLED1"; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - user_button_0: button_0 { - label = "USERPB0"; - gpios = <&gpio_button 0>; - zephyr,code = ; - }; - user_button_1: button_1 { - label = "USERPB1"; - gpios = <&gpio_button 1>; - zephyr,code = ; - }; - }; +/delete-node/ &uart3; +/delete-node/ &uart4; +/ { cpus { #address-cells = <1>; #size-cells = <0>; @@ -62,223 +29,4 @@ reg = <0>; }; }; - - sram0: memory@20000000 { - compatible = "mmio-sram"; - reg = <0x20000000 0x400000>; - }; - - flash0: flash@0 { - compatible = "soc-nv-flash"; - reg = <0 0x400000>; - }; - - sim_flash_controller: sim_flash_controller { - compatible = "zephyr,sim-flash"; - - #address-cells = <1>; - #size-cells = <1>; - erase-value = <0x00>; - - flash_sim0: flash_sim@0 { - compatible = "soc-nv-flash"; - reg = <0x00000000 0x8000>; - - erase-block-size = <1024>; - write-block-size = <4>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - storage_partition: partition@0 { - label = "storage_partition"; - reg = <0x00000000 0x8000>; - }; - }; - }; - }; - - sysclk: system-clock { - compatible = "fixed-clock"; - clock-frequency = <25000000>; - #clock-cells = <0>; - }; - - soc { - timer0: timer@40000000 { - compatible = "arm,cmsdk-timer"; - reg = <0x40000000 0x1000>; - interrupts = <8 3>; - }; - - timer1: timer@40001000 { - compatible = "arm,cmsdk-timer"; - reg = <0x40001000 0x1000>; - interrupts = <9 3>; - }; - - dtimer0: dtimer@40002000 { - compatible = "arm,cmsdk-dtimer"; - reg = <0x40002000 0x1000>; - interrupts = <10 3>; - }; - - uart0: uart@40004000 { - compatible = "arm,cmsdk-uart"; - reg = <0x40004000 0x1000>; - interrupts = <1 3 0 3>; - interrupt-names = "tx", "rx"; - clocks = <&sysclk>; - current-speed = <115200>; - }; - - uart1: uart@40005000 { - compatible = "arm,cmsdk-uart"; - reg = <0x40005000 0x1000>; - interrupts = <3 3 2 3>; - interrupt-names = "tx", "rx"; - clocks = <&sysclk>; - current-speed = <115200>; - }; - - uart2: uart@40006000 { - compatible = "arm,cmsdk-uart"; - reg = <0x40006000 0x1000>; - interrupts = <5 3 4 3>; - interrupt-names = "tx", "rx"; - clocks = <&sysclk>; - current-speed = <115200>; - }; - - uart3: uart@40007000 { - compatible = "arm,cmsdk-uart"; - reg = <0x40007000 0x1000>; - interrupts = <19 3 18 3>; - interrupt-names = "tx", "rx"; - clocks = <&sysclk>; - current-speed = <115200>; - }; - - wdog0: wdog@40008000 { - compatible = "arm,cmsdk-watchdog"; - clocks = <&sysclk>; - reg = <0x40008000 0x1000>; - }; - - uart4: uart@40009000 { - compatible = "arm,cmsdk-uart"; - reg = <0x40009000 0x1000>; - interrupts = <21 3 20 3>; - interrupt-names = "tx", "rx"; - clocks = <&sysclk>; - current-speed = <115200>; - }; - - gpio0: gpio@40010000 { - compatible = "arm,cmsdk-gpio"; - reg = <0x40010000 0x1000>; - interrupts = <6 3>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpio1: gpio@40011000 { - compatible = "arm,cmsdk-gpio"; - reg = <0x40011000 0x1000>; - interrupts = <7 3>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpio2: gpio@40012000 { - compatible = "arm,cmsdk-gpio"; - reg = <0x40012000 0x1000>; - interrupts = <16 3>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpio3: gpio@40013000 { - compatible = "arm,cmsdk-gpio"; - reg = <0x40013000 0x1000>; - interrupts = <17 3>; - gpio-controller; - #gpio-cells = <2>; - }; - - eth0: eth@40200000 { - /* Linux has "smsc,lan9115" */ - compatible = "smsc,lan9220"; - /* Such a big size from memory map in AN385 */ - /* Actual reg range is ~0x200 */ - reg = <0x40200000 0x100000>; - interrupts = <13 3>; - }; - - i2c_touch: i2c@40022000 { - compatible = "arm,versatile-i2c"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x40022000 0x1000>; - }; - - i2c_audio_conf: i2c@40023000 { - compatible = "arm,versatile-i2c"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x40023000 0x1000>; - }; - - i2c_shield0: i2c@40029000 { - compatible = "arm,versatile-i2c"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x40029000 0x1000>; - }; - - i2c_shield1: i2c@4002a000 { - compatible = "arm,versatile-i2c"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x4002a000 0x1000>; - }; - - gpio_led0: mps2_fpgaio@40028000 { - compatible = "arm,mps2-fpgaio-gpio"; - - reg = <0x40028000 0x4>; - gpio-controller; - #gpio-cells = <1>; - ngpios = <2>; - }; - - gpio_button: mps2_fpgaio@40028008 { - compatible = "arm,mps2-fpgaio-gpio"; - - reg = <0x40028008 0x4>; - gpio-controller; - #gpio-cells = <1>; - ngpios = <2>; - }; - - gpio_misc: mps2_fpgaio@4002804c { - compatible = "arm,mps2-fpgaio-gpio"; - - reg = <0x4002804c 0x4>; - gpio-controller; - #gpio-cells = <1>; - ngpios = <10>; - }; - - }; -}; - -&nvic { - arm,num-irq-priority-bits = <3>; }; diff --git a/boards/arm/mps2/mps2_an385.yaml b/boards/arm/mps2/mps2_an385.yaml index bbd929892c5ca..ca7d2443c9383 100644 --- a/boards/arm/mps2/mps2_an385.yaml +++ b/boards/arm/mps2/mps2_an385.yaml @@ -4,10 +4,11 @@ type: mcu arch: arm simulation: - name: qemu + - name: armfvp + exec: FVP_MPS2_Cortex-M3 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - netif:serial-net @@ -16,3 +17,5 @@ supported: testing: default: true vendor: arm +ram: 4096 +flash: 4096 diff --git a/boards/arm/mps2/mps2_an386.dts b/boards/arm/mps2/mps2_an386.dts new file mode 100644 index 0000000000000..44aacd6cbc139 --- /dev/null +++ b/boards/arm/mps2/mps2_an386.dts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include "mps2_base.dtsi" + +/* FVP does not support uart3 and uart4 */ +/* hence we delete them for AN386 in FVP */ +/delete-node/ &uart3; +/delete-node/ &uart4; + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-m4f"; + reg = <0>; + }; + }; +}; diff --git a/boards/arm/mps2/mps2_an386.yaml b/boards/arm/mps2/mps2_an386.yaml new file mode 100644 index 0000000000000..f71e166e683d4 --- /dev/null +++ b/boards/arm/mps2/mps2_an386.yaml @@ -0,0 +1,19 @@ +identifier: mps2/an386 +name: ARM V2M MPS2-an386 +type: mcu +arch: arm +simulation: + - name: armfvp + exec: FVP_MPS2_Cortex-M4 +toolchain: + - zephyr + - gnuarmemb +supported: + - counter + - gpio + - watchdog +testing: + default: true + ignore_tags: + - net +vendor: arm diff --git a/boards/arm/mps2/mps2_an386_defconfig b/boards/arm/mps2/mps2_an386_defconfig new file mode 100644 index 0000000000000..723288edb5248 --- /dev/null +++ b/boards/arm/mps2/mps2_an386_defconfig @@ -0,0 +1,15 @@ +# +# Copyright 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_RUNTIME_NMI=y + +# GPIOs +CONFIG_GPIO=y + +# Serial +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y diff --git a/boards/arm/mps2/mps2_an500.dts b/boards/arm/mps2/mps2_an500.dts new file mode 100644 index 0000000000000..6cd48be45fcc4 --- /dev/null +++ b/boards/arm/mps2/mps2_an500.dts @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2024 Arm Limited and/or its affiliates */ +/dts-v1/; + +#include +#include +#include +#include "mps2_base.dtsi" + +/* FVP does not support uart3 and uart4 */ +/* hence we delete them for AN500 in FVP */ +/delete-node/ &uart3; +/delete-node/ &uart4; +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-m7"; + reg = <0>; + }; + }; +}; diff --git a/boards/arm/mps2/mps2_an500.yaml b/boards/arm/mps2/mps2_an500.yaml new file mode 100644 index 0000000000000..cc4c713d799f9 --- /dev/null +++ b/boards/arm/mps2/mps2_an500.yaml @@ -0,0 +1,19 @@ +identifier: mps2/an500 +name: ARM V2M MPS2-an500 +type: mcu +arch: arm +simulation: + - name: armfvp + exec: FVP_MPS2_Cortex-M7 +toolchain: + - zephyr + - gnuarmemb +supported: + - counter + - gpio + - watchdog +testing: + default: true + ignore_tags: + - net +vendor: arm diff --git a/boards/arm/mps2/mps2_an500_defconfig b/boards/arm/mps2/mps2_an500_defconfig new file mode 100644 index 0000000000000..723288edb5248 --- /dev/null +++ b/boards/arm/mps2/mps2_an500_defconfig @@ -0,0 +1,15 @@ +# +# Copyright 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_RUNTIME_NMI=y + +# GPIOs +CONFIG_GPIO=y + +# Serial +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y diff --git a/boards/arm/mps2/mps2_an521-common.dtsi b/boards/arm/mps2/mps2_an521-common.dtsi index 5b1959ff5fe38..acd2be8da72e6 100644 --- a/boards/arm/mps2/mps2_an521-common.dtsi +++ b/boards/arm/mps2/mps2_an521-common.dtsi @@ -156,7 +156,7 @@ i2c_shield1: i2c@20d000 { }; gpio_led0: mps2_fpgaio@302000 { - compatible = "arm,mps2-fpgaio-gpio"; + compatible = "arm,mmio32-gpio"; reg = <0x302000 0x4>; gpio-controller; @@ -165,16 +165,17 @@ gpio_led0: mps2_fpgaio@302000 { }; gpio_button: mps2_fpgaio@302008 { - compatible = "arm,mps2-fpgaio-gpio"; + compatible = "arm,mmio32-gpio"; reg = <0x302008 0x4>; gpio-controller; #gpio-cells = <1>; ngpios = <2>; + direction-input; }; gpio_misc: mps2_fpgaio@30204c { - compatible = "arm,mps2-fpgaio-gpio"; + compatible = "arm,mmio32-gpio"; reg = <0x30204c 0x4>; gpio-controller; diff --git a/boards/arm/mps2/mps2_an521_cpu0.yaml b/boards/arm/mps2/mps2_an521_cpu0.yaml index 68210b954b46f..e511285c190f4 100644 --- a/boards/arm/mps2/mps2_an521_cpu0.yaml +++ b/boards/arm/mps2/mps2_an521_cpu0.yaml @@ -10,13 +10,11 @@ simulation: toolchain: - gnuarmemb - zephyr - - xtools supported: - gpio testing: default: true ignore_tags: - - drivers - bluetooth - net - timer diff --git a/boards/arm/mps2/mps2_an521_cpu0_ns.yaml b/boards/arm/mps2/mps2_an521_cpu0_ns.yaml index c4a589c93967b..8f0a61596caa9 100644 --- a/boards/arm/mps2/mps2_an521_cpu0_ns.yaml +++ b/boards/arm/mps2/mps2_an521_cpu0_ns.yaml @@ -10,7 +10,6 @@ simulation: toolchain: - gnuarmemb - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/arm/mps2/mps2_an521_cpu1.yaml b/boards/arm/mps2/mps2_an521_cpu1.yaml index 3880d479d6ec6..5264acb61f4c2 100644 --- a/boards/arm/mps2/mps2_an521_cpu1.yaml +++ b/boards/arm/mps2/mps2_an521_cpu1.yaml @@ -10,7 +10,6 @@ simulation: toolchain: - gnuarmemb - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/arm/mps2/mps2_base.dtsi b/boards/arm/mps2/mps2_base.dtsi new file mode 100644 index 0000000000000..0733b6e342d86 --- /dev/null +++ b/boards/arm/mps2/mps2_base.dtsi @@ -0,0 +1,267 @@ +/* Copyright 2024 Arm Limited and/or its affiliates */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/ { + compatible = "arm,mps2"; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + led0 = &led_0; + led1 = &led_1; + sw0 = &user_button_0; + sw1 = &user_button_1; + watchdog0 = &wdog0; + }; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-pipe = &uart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &sim_flash_controller; + }; + + leds { + compatible = "gpio-leds"; + led_0: led_0 { + gpios = <&gpio_led0 0>; + label = "USERLED0"; + }; + + led_1: led_1 { + gpios = <&gpio_led0 1>; + label = "USERLED1"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_0: button_0 { + label = "USERPB0"; + gpios = <&gpio_button 0>; + zephyr,code = ; + }; + + user_button_1: button_1 { + label = "USERPB1"; + gpios = <&gpio_button 1>; + zephyr,code = ; + }; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x400000>; + }; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 0x400000>; + }; + + sim_flash_controller: sim_flash_controller { + compatible = "zephyr,sim-flash"; + #address-cells = <1>; + #size-cells = <1>; + erase-value = <0x00>; + + flash_sim0: flash_sim@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 0x8000>; + erase-block-size = <1024>; + write-block-size = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage_partition"; + reg = <0x00000000 0x8000>; + }; + }; + }; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + clock-frequency = <25000000>; + #clock-cells = <0>; + }; + + soc { + timer0: timer@40000000 { + compatible = "arm,cmsdk-timer"; + reg = <0x40000000 0x1000>; + interrupts = <8 3>; + }; + + timer1: timer@40001000 { + compatible = "arm,cmsdk-timer"; + reg = <0x40001000 0x1000>; + interrupts = <9 3>; + }; + + dtimer0: dtimer@40002000 { + compatible = "arm,cmsdk-dtimer"; + reg = <0x40002000 0x1000>; + interrupts = <10 3>; + }; + + uart0: uart@40004000 { + compatible = "arm,cmsdk-uart"; + reg = <0x40004000 0x1000>; + interrupts = <1 3 0 3>; + interrupt-names = "tx", "rx"; + clocks = <&sysclk>; + current-speed = <115200>; + }; + + uart1: uart@40005000 { + compatible = "arm,cmsdk-uart"; + reg = <0x40005000 0x1000>; + interrupts = <3 3 2 3>; + interrupt-names = "tx", "rx"; + clocks = <&sysclk>; + current-speed = <115200>; + }; + + uart2: uart@40006000 { + compatible = "arm,cmsdk-uart"; + reg = <0x40006000 0x1000>; + interrupts = <5 3 4 3>; + interrupt-names = "tx", "rx"; + clocks = <&sysclk>; + current-speed = <115200>; + }; + + uart3: uart@40007000 { + compatible = "arm,cmsdk-uart"; + reg = <0x40007000 0x1000>; + interrupts = <19 3 18 3>; + interrupt-names = "tx", "rx"; + clocks = <&sysclk>; + current-speed = <115200>; + }; + + wdog0: wdog@40008000 { + compatible = "arm,cmsdk-watchdog"; + clocks = <&sysclk>; + reg = <0x40008000 0x1000>; + }; + + uart4: uart@40009000 { + compatible = "arm,cmsdk-uart"; + reg = <0x40009000 0x1000>; + interrupts = <21 3 20 3>; + interrupt-names = "tx", "rx"; + clocks = <&sysclk>; + current-speed = <115200>; + }; + + gpio0: gpio@40010000 { + compatible = "arm,cmsdk-gpio"; + reg = <0x40010000 0x1000>; + interrupts = <6 3>; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio1: gpio@40011000 { + compatible = "arm,cmsdk-gpio"; + reg = <0x40011000 0x1000>; + interrupts = <7 3>; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio2: gpio@40012000 { + compatible = "arm,cmsdk-gpio"; + reg = <0x40012000 0x1000>; + interrupts = <16 3>; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio3: gpio@40013000 { + compatible = "arm,cmsdk-gpio"; + reg = <0x40013000 0x1000>; + interrupts = <17 3>; + gpio-controller; + #gpio-cells = <2>; + }; + + eth0: eth@40200000 { + /* Linux has "smsc,lan9115" */ + compatible = "smsc,lan9220"; + /* Such a big size from memory map in AN385 */ + /* Actual reg range is ~0x200 */ + reg = <0x40200000 0x100000>; + interrupts = <13 3>; + }; + + i2c_touch: i2c@40022000 { + compatible = "arm,versatile-i2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40022000 0x1000>; + }; + + i2c_audio_conf: i2c@40023000 { + compatible = "arm,versatile-i2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40023000 0x1000>; + }; + + i2c_shield0: i2c@40029000 { + compatible = "arm,versatile-i2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40029000 0x1000>; + }; + + i2c_shield1: i2c@4002a000 { + compatible = "arm,versatile-i2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4002a000 0x1000>; + }; + + gpio_led0: mps2_fpgaio@40028000 { + compatible = "arm,mmio32-gpio"; + reg = <0x40028000 0x4>; + gpio-controller; + #gpio-cells = <1>; + ngpios = <2>; + }; + + gpio_button: mps2_fpgaio@40028008 { + compatible = "arm,mmio32-gpio"; + reg = <0x40028008 0x4>; + gpio-controller; + #gpio-cells = <1>; + ngpios = <2>; + direction-input; + }; + + gpio_misc: mps2_fpgaio@4002804c { + compatible = "arm,mmio32-gpio"; + reg = <0x4002804c 0x4>; + gpio-controller; + #gpio-cells = <1>; + ngpios = <10>; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/boards/arm/mps3/mps3_common_soc_peripheral.dtsi b/boards/arm/mps3/mps3_common_soc_peripheral.dtsi index 6fd5c7acd4024..4fc90627eec4f 100644 --- a/boards/arm/mps3/mps3_common_soc_peripheral.dtsi +++ b/boards/arm/mps3/mps3_common_soc_peripheral.dtsi @@ -122,7 +122,7 @@ i2c_ddr4_eeprom: i2c@9208000 { }; gpio_led0: mps3_fpgaio@9302000 { - compatible = "arm,mps3-fpgaio-gpio"; + compatible = "arm,mmio32-gpio"; reg = <0x9302000 0x4>; gpio-controller; @@ -131,16 +131,17 @@ gpio_led0: mps3_fpgaio@9302000 { }; gpio_button: mps3_fpgaio@9302008 { - compatible = "arm,mps3-fpgaio-gpio"; + compatible = "arm,mmio32-gpio"; reg = <0x9302008 0x4>; gpio-controller; #gpio-cells = <1>; ngpios = <2>; + direction-input; }; gpio_misc: mps3_fpgaio@930204c { - compatible = "arm,mps3-fpgaio-gpio"; + compatible = "arm,mmio32-gpio"; reg = <0x930204c 0x4>; gpio-controller; diff --git a/boards/arm/mps3/mps3_corstone300_an547.yaml b/boards/arm/mps3/mps3_corstone300_an547.yaml index 87a7100ed37aa..27d74d8c571b6 100644 --- a/boards/arm/mps3/mps3_corstone300_an547.yaml +++ b/boards/arm/mps3/mps3_corstone300_an547.yaml @@ -17,7 +17,6 @@ simulation: toolchain: - gnuarmemb - zephyr - - xtools supported: - gpio testing: diff --git a/boards/arm/mps3/mps3_corstone300_an547_ns.yaml b/boards/arm/mps3/mps3_corstone300_an547_ns.yaml index 3efa3da5de6d4..15e47f38110ab 100644 --- a/boards/arm/mps3/mps3_corstone300_an547_ns.yaml +++ b/boards/arm/mps3/mps3_corstone300_an547_ns.yaml @@ -16,7 +16,6 @@ simulation: toolchain: - gnuarmemb - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/arm/mps3/mps3_corstone300_an552.yaml b/boards/arm/mps3/mps3_corstone300_an552.yaml index ecabe7150853d..8feba8f3d6cd3 100644 --- a/boards/arm/mps3/mps3_corstone300_an552.yaml +++ b/boards/arm/mps3/mps3_corstone300_an552.yaml @@ -10,7 +10,6 @@ flash: 512 toolchain: - gnuarmemb - zephyr - - xtools supported: - gpio testing: diff --git a/boards/arm/mps3/mps3_corstone300_an552_ns.yaml b/boards/arm/mps3/mps3_corstone300_an552_ns.yaml index b8a914a5725bd..229778378bd08 100644 --- a/boards/arm/mps3/mps3_corstone300_an552_ns.yaml +++ b/boards/arm/mps3/mps3_corstone300_an552_ns.yaml @@ -10,7 +10,6 @@ flash: 512 toolchain: - gnuarmemb - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/arm/mps3/mps3_corstone300_fvp.yaml b/boards/arm/mps3/mps3_corstone300_fvp.yaml index 3d850b7f4eaf5..0629af2dea980 100644 --- a/boards/arm/mps3/mps3_corstone300_fvp.yaml +++ b/boards/arm/mps3/mps3_corstone300_fvp.yaml @@ -13,12 +13,10 @@ simulation: toolchain: - gnuarmemb - zephyr - - xtools supported: - gpio testing: ignore_tags: - - drivers - bluetooth - net - timer diff --git a/boards/arm/mps3/mps3_corstone300_fvp_ns.yaml b/boards/arm/mps3/mps3_corstone300_fvp_ns.yaml index 0802a12943425..52de52a2a1b1b 100644 --- a/boards/arm/mps3/mps3_corstone300_fvp_ns.yaml +++ b/boards/arm/mps3/mps3_corstone300_fvp_ns.yaml @@ -7,12 +7,9 @@ type: mcu arch: arm ram: 2048 flash: 512 -# Related issue #81656 -twister: false toolchain: - gnuarmemb - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/arm/mps3/mps3_corstone310_an555.yaml b/boards/arm/mps3/mps3_corstone310_an555.yaml index 5bcd0fb19251b..5005c8c68430b 100644 --- a/boards/arm/mps3/mps3_corstone310_an555.yaml +++ b/boards/arm/mps3/mps3_corstone310_an555.yaml @@ -10,7 +10,6 @@ flash: 32 toolchain: - gnuarmemb - zephyr - - xtools supported: - gpio testing: diff --git a/boards/arm/mps3/mps3_corstone310_an555_ns.yaml b/boards/arm/mps3/mps3_corstone310_an555_ns.yaml index f6a1f444f396e..80423596e316c 100644 --- a/boards/arm/mps3/mps3_corstone310_an555_ns.yaml +++ b/boards/arm/mps3/mps3_corstone310_an555_ns.yaml @@ -10,7 +10,6 @@ flash: 32 toolchain: - gnuarmemb - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/arm/mps3/mps3_corstone310_fvp.yaml b/boards/arm/mps3/mps3_corstone310_fvp.yaml index ab6c8d7e561c6..be08cf95aca2b 100644 --- a/boards/arm/mps3/mps3_corstone310_fvp.yaml +++ b/boards/arm/mps3/mps3_corstone310_fvp.yaml @@ -13,7 +13,6 @@ simulation: toolchain: - gnuarmemb - zephyr - - xtools supported: - gpio testing: diff --git a/boards/arm/mps3/mps3_corstone310_fvp_ns.yaml b/boards/arm/mps3/mps3_corstone310_fvp_ns.yaml index 6a70eff7fb09d..307329bcf902b 100644 --- a/boards/arm/mps3/mps3_corstone310_fvp_ns.yaml +++ b/boards/arm/mps3/mps3_corstone310_fvp_ns.yaml @@ -10,7 +10,6 @@ flash: 32 toolchain: - gnuarmemb - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/arm/v2m_beetle/v2m_beetle.yaml b/boards/arm/v2m_beetle/v2m_beetle.yaml index ca1e17d2d8df2..3284abddb3693 100644 --- a/boards/arm/v2m_beetle/v2m_beetle.yaml +++ b/boards/arm/v2m_beetle/v2m_beetle.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter vendor: arm diff --git a/boards/arm/v2m_musca_b1/v2m_musca_b1.yaml b/boards/arm/v2m_musca_b1/v2m_musca_b1.yaml index 72be434271db6..51b0acbf3a473 100644 --- a/boards/arm/v2m_musca_b1/v2m_musca_b1.yaml +++ b/boards/arm/v2m_musca_b1/v2m_musca_b1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio vendor: arm diff --git a/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.yaml b/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.yaml index 8f8700b08853c..7d13a46149f55 100644 --- a/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.yaml +++ b/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 1663 vendor: arm diff --git a/boards/arm/v2m_musca_s1/v2m_musca_s1.yaml b/boards/arm/v2m_musca_s1/v2m_musca_s1.yaml index 7e99e0fc4eb47..2d35c16b3c347 100644 --- a/boards/arm/v2m_musca_s1/v2m_musca_s1.yaml +++ b/boards/arm/v2m_musca_s1/v2m_musca_s1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio vendor: arm diff --git a/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.yaml b/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.yaml index 090f6996c580b..747247dcc75b6 100644 --- a/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.yaml +++ b/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 511 vendor: arm diff --git a/boards/atmarktechno/degu_evk/Kconfig.defconfig b/boards/atmarktechno/degu_evk/Kconfig.defconfig index 286008a36ab97..12c29c90ee0ca 100644 --- a/boards/atmarktechno/degu_evk/Kconfig.defconfig +++ b/boards/atmarktechno/degu_evk/Kconfig.defconfig @@ -5,29 +5,6 @@ if BOARD_DEGU_EVK -if USB_DEVICE_STACK - -config USB_DEVICE_PRODUCT - default "Degu Evaluation Kit" - -config UART_INTERRUPT_DRIVEN - default y - -config UART_LINE_CTRL - default y - -endif # USB_DEVICE_STACK - -if LOG - -# Logger cannot use itself to log -config USB_CDC_ACM_LOG_LEVEL - default 0 - -# Set USB log level to error only -config USB_DEVICE_LOG_LEVEL - default 1 - -endif # LOG +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_DEGU_EVK diff --git a/boards/atmarktechno/degu_evk/degu_evk.dts b/boards/atmarktechno/degu_evk/degu_evk.dts index e9d579bd3674b..82c7b75ba7fd5 100644 --- a/boards/atmarktechno/degu_evk/degu_evk.dts +++ b/boards/atmarktechno/degu_evk/degu_evk.dts @@ -16,8 +16,6 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,console = °u_cdc_acm_uart; - zephyr,shell-uart = °u_cdc_acm_uart; zephyr,code-partition = &slot0_partition; zephyr,ieee802154 = &ieee802154; }; @@ -173,8 +171,6 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - degu_cdc_acm_uart: degu_cdc_acm_uart { - compatible = "zephyr,cdc-acm-uart"; - }; }; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/atmarktechno/degu_evk/degu_evk_defconfig b/boards/atmarktechno/degu_evk/degu_evk_defconfig index ceed266a40205..bd22e1dbfde5d 100644 --- a/boards/atmarktechno/degu_evk/degu_evk_defconfig +++ b/boards/atmarktechno/degu_evk/degu_evk_defconfig @@ -10,9 +10,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -# Enable USB (for CDC ACM console) -CONFIG_USB_DEVICE_STACK=y - # Additional board options CONFIG_GPIO=y diff --git a/boards/atmel/sam/sam4e_xpro/sam4e_xpro.yaml b/boards/atmel/sam/sam4e_xpro/sam4e_xpro.yaml index 561b06b8afe42..ef72c87ba7211 100644 --- a/boards/atmel/sam/sam4e_xpro/sam4e_xpro.yaml +++ b/boards/atmel/sam/sam4e_xpro/sam4e_xpro.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 1024 ram: 128 supported: diff --git a/boards/atmel/sam/sam4l_ek/sam4l_ek.yaml b/boards/atmel/sam/sam4l_ek/sam4l_ek.yaml index 3a8193e551509..3be5a297f0516 100644 --- a/boards/atmel/sam/sam4l_ek/sam4l_ek.yaml +++ b/boards/atmel/sam/sam4l_ek/sam4l_ek.yaml @@ -1,3 +1,6 @@ +# Copyright (c) 2020-2025, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + identifier: sam4l_ek name: SAM4L-EK type: mcu @@ -5,7 +8,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: @@ -17,4 +19,5 @@ supported: - spi - uart - usb_device + - watchdog vendor: atmel diff --git a/boards/atmel/sam/sam4l_ek/sam4l_ek_defconfig b/boards/atmel/sam/sam4l_ek/sam4l_ek_defconfig index 6c902f537d7c2..141c98be56597 100644 --- a/boards/atmel/sam/sam4l_ek/sam4l_ek_defconfig +++ b/boards/atmel/sam/sam4l_ek/sam4l_ek_defconfig @@ -1,7 +1,9 @@ +# Copyright (c) 2020-2025, Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y +CONFIG_WDT_DISABLE_AT_BOOT=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/atmel/sam/sam4s_xplained/doc/index.rst b/boards/atmel/sam/sam4s_xplained/doc/index.rst index 480411323bdda..792c407da8cdc 100644 --- a/boards/atmel/sam/sam4s_xplained/doc/index.rst +++ b/boards/atmel/sam/sam4s_xplained/doc/index.rst @@ -37,6 +37,8 @@ features: +-----------+------------+-------------------------------------+ | COUNTER | on-chip | counter | +-----------+------------+-------------------------------------+ +| DAC | on-chip | dac | ++-----------+------------+-------------------------------------+ | GPIO | on-chip | gpio | +-----------+------------+-------------------------------------+ | HWINFO | on-chip | Unique device serial number | diff --git a/boards/atmel/sam/sam4s_xplained/sam4s_xplained-pinctrl.dtsi b/boards/atmel/sam/sam4s_xplained/sam4s_xplained-pinctrl.dtsi index 703e04ca5e125..479755f1a79e2 100644 --- a/boards/atmel/sam/sam4s_xplained/sam4s_xplained-pinctrl.dtsi +++ b/boards/atmel/sam/sam4s_xplained/sam4s_xplained-pinctrl.dtsi @@ -29,18 +29,21 @@ ; }; }; + uart1_default: uart1_default { group1 { pinmux = , ; }; }; + usart1_default: usart1_default { group1 { pinmux = , ; }; }; + pwm0_default: pwm0_default { group1 { pinmux = , @@ -48,12 +51,21 @@ ; }; }; + adc0_default: adc0_default { group1 { pinmux = , ; }; }; + + dacc_default: dacc_default { + group1 { + pinmux = , + ; + }; + }; + smc_default: smc_default { group1 { pinmux = , diff --git a/boards/atmel/sam/sam4s_xplained/sam4s_xplained.dts b/boards/atmel/sam/sam4s_xplained/sam4s_xplained.dts index 2e06d08aaded9..eb777a75b1769 100644 --- a/boards/atmel/sam/sam4s_xplained/sam4s_xplained.dts +++ b/boards/atmel/sam/sam4s_xplained/sam4s_xplained.dts @@ -190,6 +190,13 @@ tracking-time = <2>; }; +&dacc { + status = "okay"; + + pinctrl-0 = <&dacc_default>; + pinctrl-names = "default"; +}; + &wdt { status = "okay"; }; diff --git a/boards/atmel/sam/sam4s_xplained/sam4s_xplained.yaml b/boards/atmel/sam/sam4s_xplained/sam4s_xplained.yaml index 0cc1a4f9debe0..857d299516473 100644 --- a/boards/atmel/sam/sam4s_xplained/sam4s_xplained.yaml +++ b/boards/atmel/sam/sam4s_xplained/sam4s_xplained.yaml @@ -5,12 +5,12 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 1024 ram: 128 supported: - adc - counter + - dac - gpio - hwinfo - memc diff --git a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21.dts b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21.dts index d96e5083d5b2d..9ca18e32927c0 100644 --- a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21.dts +++ b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21.dts @@ -8,7 +8,7 @@ /dts-v1/; -#include +#include #include "sam_e70_xplained-common.dtsi" / { diff --git a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21.yaml b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21.yaml index a9fb5a4704f9e..3cec4f7518236 100644 --- a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21.yaml +++ b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 2048 ram: 384 supported: diff --git a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21b.dts b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21b.dts index e65d9da332549..50bd89a5ed343 100644 --- a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21b.dts +++ b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21b.dts @@ -7,7 +7,7 @@ /dts-v1/; -#include +#include #include "sam_e70_xplained-common.dtsi" / { diff --git a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21b.yaml b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21b.yaml index 4adc2dc6dd3ae..7a70dbc58440a 100644 --- a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21b.yaml +++ b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained_same70q21b.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 2048 ram: 384 supported: diff --git a/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21.dts b/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21.dts index 9bdcadc794631..ed06c0752b032 100644 --- a/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21.dts +++ b/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21.dts @@ -8,7 +8,7 @@ /dts-v1/; -#include +#include #include "sam_v71_xult-common.dtsi" / { diff --git a/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21.yaml b/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21.yaml index 271565dac2443..c1873f6aaaeaa 100644 --- a/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21.yaml +++ b/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 2048 ram: 384 supported: diff --git a/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21b.dts b/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21b.dts index f6f7f5a03ebfd..313093defd842 100644 --- a/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21b.dts +++ b/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21b.dts @@ -7,7 +7,7 @@ /dts-v1/; -#include +#include #include "sam_v71_xult-common.dtsi" / { diff --git a/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21b.yaml b/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21b.yaml index 732d1de39e693..b0a226550c966 100644 --- a/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21b.yaml +++ b/boards/atmel/sam/sam_v71_xult/sam_v71_xult_samv71q21b.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 2048 ram: 384 supported: diff --git a/boards/atmel/sam0/samc21n_xpro/samc21n_xpro.dts b/boards/atmel/sam0/samc21n_xpro/samc21n_xpro.dts index 3827dc104d993..dc49e1016c309 100644 --- a/boards/atmel/sam0/samc21n_xpro/samc21n_xpro.dts +++ b/boards/atmel/sam0/samc21n_xpro/samc21n_xpro.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Kamil Serwus + # Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -82,6 +83,14 @@ pinctrl-names = "default"; }; +&rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; + + atmel,assigned-clocks = <&osc32kctrl 4>; +}; + &sercom0 { status = "okay"; compatible = "atmel,sam0-uart"; diff --git a/boards/atmel/sam0/samc21n_xpro/samc21n_xpro.yaml b/boards/atmel/sam0/samc21n_xpro/samc21n_xpro.yaml index 428d79e111064..3c32cfef32263 100644 --- a/boards/atmel/sam0/samc21n_xpro/samc21n_xpro.yaml +++ b/boards/atmel/sam0/samc21n_xpro/samc21n_xpro.yaml @@ -1,5 +1,5 @@ # Copyright (c) 2022 Kamil Serwus -# Copyright (c) 2024 Gerson Fernando Budke +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 identifier: samc21n_xpro name: SAM C21N Xplained Pro @@ -8,7 +8,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: @@ -18,6 +17,7 @@ supported: - gpio - i2c - pwm + - rtc - spi - uart vendor: atmel diff --git a/boards/atmel/sam0/samd20_xpro/samd20_xpro.dts b/boards/atmel/sam0/samd20_xpro/samd20_xpro.dts index 83f5df99c05a2..6e465087aefce 100644 --- a/boards/atmel/sam0/samd20_xpro/samd20_xpro.dts +++ b/boards/atmel/sam0/samd20_xpro/samd20_xpro.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Sean Nyekjaer + # Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -51,6 +52,12 @@ clock-frequency = ; }; +&rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; +}; + &sercom0 { status = "okay"; compatible = "atmel,sam0-spi"; diff --git a/boards/atmel/sam0/samd20_xpro/samd20_xpro.yaml b/boards/atmel/sam0/samd20_xpro/samd20_xpro.yaml index 548bd6c462a88..06077f79cd392 100644 --- a/boards/atmel/sam0/samd20_xpro/samd20_xpro.yaml +++ b/boards/atmel/sam0/samd20_xpro/samd20_xpro.yaml @@ -1,3 +1,6 @@ +# Copyright (c) 2024-2025 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + identifier: samd20_xpro name: SAM D20 Xplained Pro type: mcu @@ -5,14 +8,13 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: - - adc - flash - gpio - i2c + - rtc - spi - uart - watchdog diff --git a/boards/atmel/sam0/samd21_xpro/samd21_xpro.dts b/boards/atmel/sam0/samd21_xpro/samd21_xpro.dts index f390bc106de9a..72c0b815b8bb5 100644 --- a/boards/atmel/sam0/samd21_xpro/samd21_xpro.dts +++ b/boards/atmel/sam0/samd21_xpro/samd21_xpro.dts @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 Bryan O'Donoghue - * Copyright (c) 2024 Gerson Fernando Budke + # Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -71,6 +71,12 @@ pinctrl-names = "default"; }; +&rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; +}; + &sercom0 { status = "okay"; compatible = "atmel,sam0-uart"; diff --git a/boards/atmel/sam0/samd21_xpro/samd21_xpro.yaml b/boards/atmel/sam0/samd21_xpro/samd21_xpro.yaml index c41c94432857c..2ffa9435ca523 100644 --- a/boards/atmel/sam0/samd21_xpro/samd21_xpro.yaml +++ b/boards/atmel/sam0/samd21_xpro/samd21_xpro.yaml @@ -1,6 +1,7 @@ # Copyright (c) 2018 Bryan O'Donoghue -# Copyright (c) 2024 Gerson Fernando Budke +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 + identifier: samd21_xpro name: SAM D21 Xplained Pro type: mcu @@ -8,16 +9,15 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: - - adc - counter - dma - gpio - i2c - pwm + - rtc - spi - uart - usb_device diff --git a/boards/atmel/sam0/same54_xpro/same54_xpro.dts b/boards/atmel/sam0/same54_xpro/same54_xpro.dts index f8d957727cd4d..b6b9ff9d78dcb 100644 --- a/boards/atmel/sam0/same54_xpro/same54_xpro.dts +++ b/boards/atmel/sam0/same54_xpro/same54_xpro.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Benjamin Valentin + # Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -68,6 +69,14 @@ pinctrl-names = "default"; }; +&rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; + + atmel,assigned-clocks = <&osc32kctrl 4>; +}; + &sercom2 { status = "okay"; compatible = "atmel,sam0-uart"; diff --git a/boards/atmel/sam0/same54_xpro/same54_xpro.yaml b/boards/atmel/sam0/same54_xpro/same54_xpro.yaml index 1cddeeaf7ad9d..bd46418551fd9 100644 --- a/boards/atmel/sam0/same54_xpro/same54_xpro.yaml +++ b/boards/atmel/sam0/same54_xpro/same54_xpro.yaml @@ -1,5 +1,5 @@ # Copyright (c) 2019 Benjamin Valentin -# Copyright (c) 2024 Gerson Fernando Budke +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 identifier: same54_xpro name: SAM E54 Xplained Pro @@ -8,16 +8,17 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 1024 ram: 256 supported: - adc + - dma - flash - gpio - i2c - netif:eth - pwm + - rtc - spi - uart - usb_device diff --git a/boards/atmel/sam0/saml21_xpro/saml21_xpro.dts b/boards/atmel/sam0/saml21_xpro/saml21_xpro.dts index c0e0e43d666ba..f1a14ab071bef 100644 --- a/boards/atmel/sam0/saml21_xpro/saml21_xpro.dts +++ b/boards/atmel/sam0/saml21_xpro/saml21_xpro.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Argentum Systems Ltd. + # Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -71,6 +72,14 @@ pinctrl-names = "default"; }; +&rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; + + atmel,assigned-clocks = <&osc32kctrl 4>; +}; + &sercom0 { status = "okay"; compatible = "atmel,sam0-spi"; diff --git a/boards/atmel/sam0/saml21_xpro/saml21_xpro.yaml b/boards/atmel/sam0/saml21_xpro/saml21_xpro.yaml index be39f0dc5173e..9588bef980df5 100644 --- a/boards/atmel/sam0/saml21_xpro/saml21_xpro.yaml +++ b/boards/atmel/sam0/saml21_xpro/saml21_xpro.yaml @@ -1,5 +1,5 @@ # Copyright (c) 2021 Argentum Systems Ltd. -# Copyright (c) 2024 Gerson Fernando Budke +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 identifier: saml21_xpro name: SAM L21 Xplained Pro @@ -8,7 +8,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: @@ -18,6 +17,7 @@ supported: - gpio - i2c - pwm + - rtc - spi - uart - usb_device diff --git a/boards/atmel/sam0/samr21_xpro/samr21_xpro-pinctrl.dtsi b/boards/atmel/sam0/samr21_xpro/samr21_xpro-pinctrl.dtsi index de5b64f0f8cfd..81f7bce508abc 100644 --- a/boards/atmel/sam0/samr21_xpro/samr21_xpro-pinctrl.dtsi +++ b/boards/atmel/sam0/samr21_xpro/samr21_xpro-pinctrl.dtsi @@ -1,11 +1,17 @@ /* - * Copyright (c) 2022, Gerson Fernando Budke + * Copyright (c) 2022-2024, Gerson Fernando Budke * SPDX-License-Identifier: Apache-2.0 */ #include &pinctrl { + adc_default: adc_default { + group1 { + pinmux = ; + }; + }; + pwm_default: pwm_default { group1 { pinmux = ; diff --git a/boards/atmel/sam0/samr21_xpro/samr21_xpro.dts b/boards/atmel/sam0/samr21_xpro/samr21_xpro.dts index 01ed0e8826ce3..5b7514c26d872 100644 --- a/boards/atmel/sam0/samr21_xpro/samr21_xpro.dts +++ b/boards/atmel/sam0/samr21_xpro/samr21_xpro.dts @@ -1,6 +1,6 @@ /* * Copyright (c) 2019 Benjamin Valentin - * Copyright (c) 2019-2024 Gerson Fernando Budke + * Copyright (c) 2019-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -106,6 +106,12 @@ clock-frequency = <48000000>; }; +&adc { + status = "okay"; + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; +}; + &tcc0 { status = "okay"; compatible = "atmel,sam0-tcc-pwm"; @@ -116,6 +122,12 @@ pinctrl-names = "default"; }; +&rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; +}; + &sercom0 { status = "okay"; compatible = "atmel,sam0-uart"; diff --git a/boards/atmel/sam0/samr21_xpro/samr21_xpro.yaml b/boards/atmel/sam0/samr21_xpro/samr21_xpro.yaml index 25ce756d667c9..77e032878b2ed 100644 --- a/boards/atmel/sam0/samr21_xpro/samr21_xpro.yaml +++ b/boards/atmel/sam0/samr21_xpro/samr21_xpro.yaml @@ -1,6 +1,7 @@ # Copyright (c) 2019 Benjamin Valentin -# Copyright (c) 2019-2024 Gerson Fernando Budke +# Copyright (c) 2019-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 + identifier: samr21_xpro name: SAM R21 Xplained Pro type: mcu @@ -8,16 +9,17 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: - adc + - dma - flash - gpio - i2c - netif - pwm + - rtc - spi - uart - usb_device diff --git a/boards/atmel/sam0/samr34_xpro/pre_dt_board.cmake b/boards/atmel/sam0/samr34_xpro/pre_dt_board.cmake new file mode 100644 index 0000000000000..94f7f4e445901 --- /dev/null +++ b/boards/atmel/sam0/samr34_xpro/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via sercom so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/atmel/sam0/samr34_xpro/samr34_xpro.dts b/boards/atmel/sam0/samr34_xpro/samr34_xpro.dts index 964cd8af4dfc9..cb267d86dba15 100644 --- a/boards/atmel/sam0/samr34_xpro/samr34_xpro.dts +++ b/boards/atmel/sam0/samr34_xpro/samr34_xpro.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Argentum Systems Ltd. + # Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -71,6 +72,14 @@ pinctrl-names = "default"; }; +&rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; + + atmel,assigned-clocks = <&osc32kctrl 4>; +}; + &sercom0 { status = "okay"; compatible = "atmel,sam0-uart"; diff --git a/boards/atmel/sam0/samr34_xpro/samr34_xpro.yaml b/boards/atmel/sam0/samr34_xpro/samr34_xpro.yaml index 488fba3bb324e..c436517152605 100644 --- a/boards/atmel/sam0/samr34_xpro/samr34_xpro.yaml +++ b/boards/atmel/sam0/samr34_xpro/samr34_xpro.yaml @@ -1,5 +1,5 @@ # Copyright (c) 2021 Argentum Systems Ltd. -# Copyright (c) 2024 Gerson Fernando Budke +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 identifier: samr34_xpro name: SAM R34 Xplained Pro @@ -8,7 +8,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: @@ -18,6 +17,7 @@ supported: - gpio - i2c - pwm + - rtc - spi - uart - usb_device diff --git a/boards/bbc/microbit/bbc_microbit.yaml b/boards/bbc/microbit/bbc_microbit.yaml index cb1b12a7d3613..521c111f2b89b 100644 --- a/boards/bbc/microbit/bbc_microbit.yaml +++ b/boards/bbc/microbit/bbc_microbit.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 16 testing: ignore_tags: diff --git a/boards/bbc/microbit_v2/bbc_microbit_v2.yaml b/boards/bbc/microbit_v2/bbc_microbit_v2.yaml index 5eb925efff663..81928e2c1eda5 100644 --- a/boards/bbc/microbit_v2/bbc_microbit_v2.yaml +++ b/boards/bbc/microbit_v2/bbc_microbit_v2.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 testing: ignore_tags: diff --git a/boards/bcdevices/plt_demo_v2/blueclover_plt_demo_v2_nrf52832.yaml b/boards/bcdevices/plt_demo_v2/blueclover_plt_demo_v2_nrf52832.yaml index 6536b8a957f58..74fa69a1cba02 100644 --- a/boards/bcdevices/plt_demo_v2/blueclover_plt_demo_v2_nrf52832.yaml +++ b/boards/bcdevices/plt_demo_v2/blueclover_plt_demo_v2_nrf52832.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0-pinctrl.dtsi b/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0-pinctrl.dtsi index dfc744b72e4a1..9cf1363ba226f 100644 --- a/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0-pinctrl.dtsi +++ b/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0-pinctrl.dtsi @@ -18,4 +18,12 @@ /* 0x14 is address of padconfig register of p8.22 and 14 is mux mode */ pinmux = ; }; + i2c6_scl_default: i2c6_scl_default { + /* 0x1e0 is the address of padconfig register of p9.17 and 2 is mux mode */ + pinmux = ; + }; + i2c6_sda_default: i2c6_sda_default { + /* 0x1dc is the address of padconfig register of p9.18 and 2 is mux mode */ + pinmux = ; + }; }; diff --git a/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0.dts b/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0.dts index 8c4c8f0e8e4c9..804abfd95660a 100644 --- a/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0.dts +++ b/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0.dts @@ -45,6 +45,12 @@ }; }; +&i2c6 { + status = "okay"; + pinctrl-0 = <&i2c6_scl_default &i2c6_sda_default>; + pinctrl-names = "default"; +}; + &uart2 { status = "okay"; pinctrl-0 = <&uart2_tx_default &uart2_rx_default>; diff --git a/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0.yaml b/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0.yaml index 0adaeddf82f47..1bc51599e7776 100644 --- a/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0.yaml +++ b/boards/beagle/beaglebone_ai64/beaglebone_ai64_j721e_main_r5f0_0.yaml @@ -11,7 +11,7 @@ ram: 32 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart + - i2c vendor: beagle diff --git a/boards/beagle/beaglebone_ai64/doc/index.rst b/boards/beagle/beaglebone_ai64/doc/index.rst index d54775011dbd5..3e62a1ad54a7a 100644 --- a/boards/beagle/beaglebone_ai64/doc/index.rst +++ b/boards/beagle/beaglebone_ai64/doc/index.rst @@ -44,9 +44,11 @@ The board configuration supports, +-----------+------------+-----------------------+ | Interface | Controller | Driver/Component | +===========+============+=======================+ -| UART | on-chip | serial port-polling | +| UART | on-chip | serial port-polling, | | | | serial port-interrupt | +-----------+------------+-----------------------+ +| I2C | on-chip | i2c-polling | ++-----------+------------+-----------------------+ Other hardwares features are currently not supported. diff --git a/boards/beagle/beagleconnect_freedom/beagleconnect_freedom.yaml b/boards/beagle/beagleconnect_freedom/beagleconnect_freedom.yaml index cbe7f154814ee..989f7f8e2f093 100644 --- a/boards/beagle/beagleconnect_freedom/beagleconnect_freedom.yaml +++ b/boards/beagle/beagleconnect_freedom/beagleconnect_freedom.yaml @@ -7,7 +7,6 @@ flash: 704 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/beagle/beagleplay/beagleplay_cc1352p7.yaml b/boards/beagle/beagleplay/beagleplay_cc1352p7.yaml index 816b755471fa1..8a35e3700ed71 100644 --- a/boards/beagle/beagleplay/beagleplay_cc1352p7.yaml +++ b/boards/beagle/beagleplay/beagleplay_cc1352p7.yaml @@ -7,7 +7,6 @@ flash: 704 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - uart diff --git a/boards/beagle/beagley_ai/Kconfig.beagley_ai b/boards/beagle/beagley_ai/Kconfig.beagley_ai new file mode 100644 index 0000000000000..fb4ca252ea16f --- /dev/null +++ b/boards/beagle/beagley_ai/Kconfig.beagley_ai @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Andrew Davis +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BEAGLEY_AI + select SOC_J722S_MAIN_R5F0_0 if BOARD_BEAGLEY_AI_J722S_MAIN_R5F0_0 + select SOC_J722S_MCU_R5F0_0 if BOARD_BEAGLEY_AI_J722S_MCU_R5F0_0 diff --git a/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0-pinctrl.dtsi b/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0-pinctrl.dtsi new file mode 100644 index 0000000000000..0ffa8f9107357 --- /dev/null +++ b/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0-pinctrl.dtsi @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Andrew Davis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart1_rx_default: uart1_rx_default { + /* (C27) MCASP0_AFSR.UART1_RXD */ + pinmux = ; + }; + + uart1_tx_default: uart1_tx_default { + /* (F24) MCASP0_ACLKR.UART1_TXD */ + pinmux = ; + }; +}; diff --git a/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0.dts b/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0.dts new file mode 100644 index 0000000000000..5bf213b644453 --- /dev/null +++ b/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0.dts @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Andrew Davis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "beagley_ai_j722s_main_r5f0_0-pinctrl.dtsi" +#include + +/ { + model = "BeagleBoard.org BeagleY-AI"; + compatible = "beagle,beagley-ai"; + + chosen { + zephyr,sram = &atcm; + zephyr,console = &uart1; + }; + + cpus { + cpu@0 { + status = "okay"; + }; + }; + + ddr0: memory@a2000000 { + compatible = "mmio-sram"; + reg = <0xa2000000 DT_SIZE_M(1)>; + }; + + rsc_table: memory@a2100000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0xa2100000 DT_SIZE_M(1)>; + zephyr,memory-region = "RSC_TABLE"; + }; + + ddr1: memory@a2200000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0xa2200000 DT_SIZE_M(14)>; + zephyr,memory-region = "DRAM"; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-0 = <&uart1_tx_default &uart1_rx_default>; + pinctrl-names = "default"; + current-speed = <115200>; +}; + +&systick_timer { + status = "okay"; +}; diff --git a/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0.yaml b/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0.yaml new file mode 100644 index 0000000000000..40986711f15ed --- /dev/null +++ b/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Andrew Davis +# +# SPDX-License-Identifier: Apache-2.0 + +identifier: beagley_ai/j722s/main_r5f0_0 +name: BeagleY-AI MAIN domain R5F Core 0 +type: mcu +arch: arm +ram: 32 +toolchain: + - zephyr + - gnuarmemb +supported: + - uart +vendor: beagle diff --git a/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0_defconfig b/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0_defconfig new file mode 100644 index 0000000000000..a8cf44f32dbcb --- /dev/null +++ b/boards/beagle/beagley_ai/beagley_ai_j722s_main_r5f0_0_defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Andrew Davis +# +# SPDX-License-Identifier: Apache-2.0 + +# Zephyr Kernel Configuration +CONFIG_XIP=n + +# Serial Driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0-pinctrl.dtsi b/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0-pinctrl.dtsi new file mode 100644 index 0000000000000..0ffa8f9107357 --- /dev/null +++ b/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0-pinctrl.dtsi @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Andrew Davis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart1_rx_default: uart1_rx_default { + /* (C27) MCASP0_AFSR.UART1_RXD */ + pinmux = ; + }; + + uart1_tx_default: uart1_tx_default { + /* (F24) MCASP0_ACLKR.UART1_TXD */ + pinmux = ; + }; +}; diff --git a/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0.dts b/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0.dts new file mode 100644 index 0000000000000..e2957226a66e2 --- /dev/null +++ b/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0.dts @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Andrew Davis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "beagley_ai_j722s_mcu_r5f0_0-pinctrl.dtsi" +#include + +/ { + model = "BeagleBoard.org BeagleY-AI"; + compatible = "beagle,beagley-ai"; + + chosen { + zephyr,sram = &atcm; + zephyr,console = &uart1; + }; + + cpus { + cpu@0 { + status = "okay"; + }; + }; + + ddr0: memory@a1000000 { + compatible = "mmio-sram"; + reg = <0xa1000000 DT_SIZE_M(1)>; + }; + + rsc_table: memory@a1100000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0xa1100000 DT_SIZE_M(1)>; + zephyr,memory-region = "RSC_TABLE"; + }; + + ddr1: memory@a1200000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0xa1200000 DT_SIZE_M(14)>; + zephyr,memory-region = "DRAM"; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-0 = <&uart1_tx_default &uart1_rx_default>; + pinctrl-names = "default"; + current-speed = <115200>; +}; + +&systick_timer { + status = "okay"; +}; diff --git a/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0.yaml b/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0.yaml new file mode 100644 index 0000000000000..665814f9d53b8 --- /dev/null +++ b/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Andrew Davis +# +# SPDX-License-Identifier: Apache-2.0 + +identifier: beagley_ai/j722s/mcu_r5f0_0 +name: BeagleY-AI MCU domain R5F Core 0 +type: mcu +arch: arm +ram: 32 +toolchain: + - zephyr + - gnuarmemb +supported: + - uart +vendor: beagle diff --git a/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0_defconfig b/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0_defconfig new file mode 100644 index 0000000000000..a8cf44f32dbcb --- /dev/null +++ b/boards/beagle/beagley_ai/beagley_ai_j722s_mcu_r5f0_0_defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Andrew Davis +# +# SPDX-License-Identifier: Apache-2.0 + +# Zephyr Kernel Configuration +CONFIG_XIP=n + +# Serial Driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/beagle/beagley_ai/board.yml b/boards/beagle/beagley_ai/board.yml new file mode 100644 index 0000000000000..af83769160e47 --- /dev/null +++ b/boards/beagle/beagley_ai/board.yml @@ -0,0 +1,6 @@ +board: + name: beagley_ai + full_name: BeagleY-AI + vendor: beagle + socs: + - name: j722s diff --git a/boards/beagle/beagley_ai/doc/assets/beagley_ai.webp b/boards/beagle/beagley_ai/doc/assets/beagley_ai.webp new file mode 100644 index 0000000000000..f943829c7104d Binary files /dev/null and b/boards/beagle/beagley_ai/doc/assets/beagley_ai.webp differ diff --git a/boards/beagle/beagley_ai/doc/index.rst b/boards/beagle/beagley_ai/doc/index.rst new file mode 100644 index 0000000000000..6e1e6ca7e7eab --- /dev/null +++ b/boards/beagle/beagley_ai/doc/index.rst @@ -0,0 +1,134 @@ +.. zephyr:board:: beagley_ai + +Overview +******** + +BeagleY-AI is a computational platform powered by TI AM67A (J722S) SoC, which is +targeted for automotive applications. + +Hardware +******** +BeagleY-AI is powered by TI AM67A (J722S) SoC, which has two domains (Main, +MCU). This document gives overview of Zephyr running on both Cortex R5. + +L1 Memory System +---------------- +BeagleY-AI defaults to single-core mode for the R5 subsystem. Changes in that +will impact the L1 memory system configuration. + +* 32KB instruction cache +* 32KB data cache +* 64KB tightly-coupled memory (TCM) + * 32KB TCMA + * 32KB TCMB + +Region Address Translation +-------------------------- +The RAT module performs a region based address translation. It translates a +32-bit input address into a 36-bit output address. Any input transaction that +starts inside of a programmed region will have its address translated, if the +region is enabled. + +VIM Interrupt Controller +------------------------ +The VIM aggregates device interrupts and sends them to the R5F CPU(s). The VIM +module supports 512 interrupt inputs per R5F core. Each interrupt can be either +a level or a pulse (both active-high). The VIM has two interrupt outputs per core +IRQ and FIQ. + +Supported Features +****************** +The board configuration supports a console UART via the HAT header pins. Future +versions will also support a console over RPmsg. + ++-----------+------------+-----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=======================+ +| UART | on-chip | serial port-polling | +| | | serial port-interrupt | ++-----------+------------+-----------------------+ + +Other hardware features are currently not supported. + +The default configuration can be found in the defconfig file. + +Future configurations will add support for GPIO, I2C, SPI, etc. + +Running Zephyr +************** + +The AM67A does not have a separate flash for the R5 core. Because of this +an A53 core has to load the program for the R5 core to the right memory +address, set the PC and start the processor. +This can be done from Linux on the A53 core via remoteproc. + +This is the memory mapping from A53 to the memory usable by the R5. Note that +the R5 core always sees its local TCMA at address 0x00000000 and its TCMB0 +at address 0x41010000. + +The A53 Linux configuration allocates a region in DDR that is shared with +the R5. The amount of the allocation can be changed in the Linux device tree. +Note that BeagleY-AI has 4GB of DDR. + ++-------------------+---------------+--------------+--------+ +| Region | Addr from A53 | MAIN R5F | Size | ++===================+===============+==============+========+ +| ATCM | 0x0078400000 | 0x0000000000 | 32KB | ++-------------------+---------------+--------------+--------+ +| BTCM | 0x0078500000 | 0x0041010000 | 32KB | ++-------------------+---------------+--------------+--------+ +| DDR Shared Region | 0x00A2000000 | 0x00A2000000 | 16MB | ++-------------------+---------------+--------------+--------+ + ++-------------------+---------------+--------------+--------+ +| Region | Addr from A53 | MCU R5F | Size | ++===================+===============+==============+========+ +| ATCM | 0x0079000000 | 0x0000000000 | 32KB | ++-------------------+---------------+--------------+--------+ +| BTCM | 0x0079020000 | 0x0041010000 | 32KB | ++-------------------+---------------+--------------+--------+ +| DDR Shared Region | 0x00A1000000 | 0x00A1000000 | 16MB | ++-------------------+---------------+--------------+--------+ + +Steps to run the image +---------------------- +Here is an example for the :zephyr:code-sample:`hello_world` application +targeting the MAIN domain Cortex R5F on BeagleY-AI: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: beagley_ai/j722s/main_r5f0_0 + :goals: build + +For the MCU domain Cortex R5F on BeagleY-AI: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: beagley_ai/j722s/mcu_r5f0_0 + :goals: build + +To load the image: + +| Copy Zephyr image to the /lib/firmware/ directory. +| ``cp build/zephyr/zephyr.elf /lib/firmware/`` +| +| Ensure the Core is not running. +| ``echo stop > /dev/remoteproc/am67a-{main,mcu}-r5f0_0/state`` +| +| Configuring the image name to the remoteproc module. +| ``echo zephyr.elf > /dev/remoteproc/am67a-{main,mcu}-r5f0_0/firmware`` +| +| Once the image name is configured, send the start command. +| ``echo start > /dev/remoteproc/am67a-{main,mcu}-r5f0_0/state`` + +Console +------- +The Zephyr on BeagleY-AI Cortex-R5F uses UART 1 (HAT pins 8-TX, 10-RX) +as console. + +References +********** +* `BeagleY-AI Homepage `_ +* `AM67A TRM `_ +* `Pinout guide `_ +* `Documentation `_ diff --git a/boards/blues/swan_r5/Kconfig.defconfig b/boards/blues/swan_r5/Kconfig.defconfig index a9d7a1e00b1a2..44ddb9268d124 100644 --- a/boards/blues/swan_r5/Kconfig.defconfig +++ b/boards/blues/swan_r5/Kconfig.defconfig @@ -9,14 +9,4 @@ config SPI_STM32_INTERRUPT default y depends on SPI -if NETWORKING - -config USB_DEVICE_STACK - default y - -config USB_DEVICE_NETWORK_EEM - default y - -endif # NETWORKING - endif # BOARD_SWAN_R5 diff --git a/boards/blues/swan_r5/swan_r5.dts b/boards/blues/swan_r5/swan_r5.dts index 221ca274fdecf..42fb32022170f 100644 --- a/boards/blues/swan_r5/swan_r5.dts +++ b/boards/blues/swan_r5/swan_r5.dts @@ -195,7 +195,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in6_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/blues/swan_r5/swan_r5.yaml b/boards/blues/swan_r5/swan_r5.yaml index 5e0efea65406f..7f9791b19d272 100644 --- a/boards/blues/swan_r5/swan_r5.yaml +++ b/boards/blues/swan_r5/swan_r5.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - pwm - spi diff --git a/boards/circuitdojo/feather/circuitdojo_feather_nrf9160.yaml b/boards/circuitdojo/feather/circuitdojo_feather_nrf9160.yaml index ee93576b4af58..c3f8f1634d494 100644 --- a/boards/circuitdojo/feather/circuitdojo_feather_nrf9160.yaml +++ b/boards/circuitdojo/feather/circuitdojo_feather_nrf9160.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.yaml b/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.yaml index 582e28dbfc9bd..85c4c60194fc8 100644 --- a/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.yaml +++ b/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/common/ecpprog.board.cmake b/boards/common/ecpprog.board.cmake new file mode 100644 index 0000000000000..25aa5914f089a --- /dev/null +++ b/boards/common/ecpprog.board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2024 tinyVision.ai Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(ecpprog) +board_finalize_runner_args(ecpprog) diff --git a/boards/common/openocd-adi-max32.boards.cmake b/boards/common/openocd-adi-max32.boards.cmake new file mode 100644 index 0000000000000..2c65ce974e3ff --- /dev/null +++ b/boards/common/openocd-adi-max32.boards.cmake @@ -0,0 +1,41 @@ +# +# Copyright (c) 2025 Analog Devices, Inc +# +# SPDX-License-Identifier: Apache-2.0 + +# Default cmsis-dap, it will be overwritten below if requires +set(MAX32_INTERFACE_CFG "cmsis-dap.cfg") + +if(CONFIG_SOC_MAX32650) + set(MAX32_TARGET_CFG "max32650.cfg") +elseif(CONFIG_SOC_MAX32655_M4) + set(MAX32_TARGET_CFG "max32655.cfg") +elseif(CONFIG_SOC_MAX32660) + set(MAX32_TARGET_CFG "max32660.cfg") +elseif(CONFIG_SOC_MAX32662) + set(MAX32_TARGET_CFG "max32662.cfg") +elseif(CONFIG_SOC_MAX32666) + set(MAX32_TARGET_CFG "max32665.cfg") +elseif(CONFIG_SOC_MAX32670) + set(MAX32_TARGET_CFG "max32670.cfg") +elseif(CONFIG_SOC_MAX32672) + set(MAX32_TARGET_CFG "max32672.cfg") +elseif(CONFIG_SOC_MAX32675) + set(MAX32_TARGET_CFG "max32675.cfg") +elseif(CONFIG_SOC_MAX32680_M4) + set(MAX32_TARGET_CFG "max32680.cfg") +elseif(CONFIG_SOC_MAX32690_M4) + set(MAX32_TARGET_CFG "max32690.cfg") +elseif(CONFIG_SOC_MAX78000_M4) + set(MAX32_TARGET_CFG "max78000.cfg") +elseif(CONFIG_SOC_MAX78002_M4) + set(MAX32_TARGET_CFG "max78002.cfg") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${MAX32_INTERFACE_CFG}]") +board_runner_args(openocd --cmd-pre-init "source [find target/${MAX32_TARGET_CFG}]") + +if(CONFIG_SOC_FAMILY_MAX32_M4) + board_runner_args(openocd --cmd-pre-init "allow_low_pwr_dbg") + board_runner_args(openocd "--cmd-erase=max32xxx mass_erase 0") +endif() diff --git a/boards/common/openocd-stm32.board.cmake b/boards/common/openocd-stm32.board.cmake new file mode 100644 index 0000000000000..855411fa34b1d --- /dev/null +++ b/boards/common/openocd-stm32.board.cmake @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_SERIES_STM32L0X OR CONFIG_SOC_SERIES_STM32L1X) + board_runner_args(openocd "--cmd-erase=stm32l1x mass_erase 0") +elseif(CONFIG_SOC_SERIES_STM32L4X OR + CONFIG_SOC_SERIES_STM32L5X OR + CONFIG_SOC_SERIES_STM32U5X OR + CONFIG_SOC_SERIES_STM32WBX OR + CONFIG_SOC_SERIES_STM32G0X OR + CONFIG_SOC_SERIES_STM32G4X) + board_runner_args(openocd "--cmd-erase=stm32l4x mass_erase 0") +elseif(CONFIG_SOC_SERIES_STM32F0X OR + CONFIG_SOC_SERIES_STM32F1X OR + CONFIG_SOC_SERIES_STM32F3X) + board_runner_args(openocd "--cmd-erase=stm32f1x mass_erase 0") +elseif(CONFIG_SOC_SERIES_STM32F2X OR + CONFIG_SOC_SERIES_STM32F4X OR + CONFIG_SOC_SERIES_STM32F7X) + board_runner_args(openocd "--cmd-erase=stm32f2x mass_erase 0") +endif() diff --git a/boards/common/openocd.board.cmake b/boards/common/openocd.board.cmake index 14d32d4be2548..b1d09fe0a2dd9 100644 --- a/boards/common/openocd.board.cmake +++ b/boards/common/openocd.board.cmake @@ -20,3 +20,6 @@ board_finalize_runner_args(openocd --cmd-load "${OPENOCD_CMD_LOAD_DEFAULT}" --cmd-verify "${OPENOCD_CMD_VERIFY_DEFAULT}" ) + +# Manufacturer common options +include(${CMAKE_CURRENT_LIST_DIR}/openocd-stm32.board.cmake) diff --git a/boards/common/simics.board.cmake b/boards/common/simics.board.cmake index 792197a54ccca..49fe1bfb7cd05 100644 --- a/boards/common/simics.board.cmake +++ b/boards/common/simics.board.cmake @@ -1,5 +1,7 @@ -# Copyright (c) 2023 Intel Corporation +# Copyright (c) 2023-2024 Intel Corporation # # SPDX-License-Identifier: Apache-2.0 +set(SUPPORTED_EMU_PLATFORMS simics) + board_finalize_emu_args(simics) diff --git a/boards/common/usb/Kconfig.cdc_acm_serial.defconfig b/boards/common/usb/Kconfig.cdc_acm_serial.defconfig new file mode 100644 index 0000000000000..3a5661a98f413 --- /dev/null +++ b/boards/common/usb/Kconfig.cdc_acm_serial.defconfig @@ -0,0 +1,51 @@ +# Copyright (c) 2023-2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_REQUIRES_SERIAL_BACKEND_CDC_ACM + default y + +if BOARD_SERIAL_BACKEND_CDC_ACM + +config SERIAL + default y + +config CONSOLE + default y + +config UART_CONSOLE + default CONSOLE + +config SHELL_BACKEND_SERIAL_CHECK_DTR + default SHELL + depends on UART_LINE_CTRL + +config UART_LINE_CTRL + default SHELL + +config USB_DEVICE_STACK + default y + +config USB_DEVICE_INITIALIZE_AT_BOOT + default y if !MCUBOOT + +config USB_DEVICE_REMOTE_WAKEUP + default n + +if LOG + +choice USB_CDC_ACM_LOG_LEVEL_CHOICE + default USB_CDC_ACM_LOG_LEVEL_OFF +endchoice + +choice USB_DEVICE_LOG_LEVEL_CHOICE + default USB_DEVICE_LOG_LEVEL_OFF +endchoice + +# Wait 4000ms at startup for logging +config LOG_PROCESS_THREAD_STARTUP_DELAY_MS + default 4000 + +endif # LOG + +endif # BOARD_SERIAL_BACKEND_CDC_ACM diff --git a/boards/common/usb/cdc_acm_serial.dtsi b/boards/common/usb/cdc_acm_serial.dtsi new file mode 100644 index 0000000000000..14e702fa52524 --- /dev/null +++ b/boards/common/usb/cdc_acm_serial.dtsi @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,console = &board_cdc_acm_uart; + zephyr,shell-uart = &board_cdc_acm_uart; + zephyr,uart-mcumgr = &board_cdc_acm_uart; + zephyr,bt-mon-uart = &board_cdc_acm_uart; + zephyr,bt-c2h-uart = &board_cdc_acm_uart; + }; +}; + +&zephyr_udc0 { + board_cdc_acm_uart: board_cdc_acm_uart { + compatible = "zephyr,cdc-acm-uart"; + }; +}; diff --git a/boards/contextualelectronics/abc/contextualelectronics_abc.yaml b/boards/contextualelectronics/abc/contextualelectronics_abc.yaml index f96fa8c29bf6a..57f5b4f49bb70 100644 --- a/boards/contextualelectronics/abc/contextualelectronics_abc.yaml +++ b/boards/contextualelectronics/abc/contextualelectronics_abc.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_i2c - arduino_spi diff --git a/boards/croxel/croxel_cx1825/Kconfig.defconfig b/boards/croxel/croxel_cx1825/Kconfig.defconfig index 04fa79982b296..b6f6c5ef704ae 100644 --- a/boards/croxel/croxel_cx1825/Kconfig.defconfig +++ b/boards/croxel/croxel_cx1825/Kconfig.defconfig @@ -3,13 +3,6 @@ if BOARD_CROXEL_CX1825 -if LOG - -# Logger cannot use itself to log -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF -endchoice - -endif # LOG +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_CROXEL_CX1825 diff --git a/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840.dts b/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840.dts index 0aaa70158f822..0dd4d908fa789 100644 --- a/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840.dts +++ b/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840.dts @@ -17,8 +17,6 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; - zephyr,console = &cdc_acm_0; - zephyr,shell-uart = &cdc_acm_0; }; leds { @@ -130,12 +128,10 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - cdc_acm_0: cdc_acm_0 { - compatible = "zephyr,cdc-acm-uart"; - }; }; +#include <../boards/common/usb/cdc_acm_serial.dtsi> + &flash0 { partitions { diff --git a/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840.yaml b/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840.yaml index bc550fd4cc449..3eef0741d5afa 100644 --- a/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840.yaml +++ b/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - ble - counter diff --git a/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840_defconfig b/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840_defconfig index 8694d118b007a..6a76f262ed3fb 100644 --- a/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840_defconfig +++ b/boards/croxel/croxel_cx1825/croxel_cx1825_nrf52840_defconfig @@ -10,11 +10,6 @@ CONFIG_HW_STACK_PROTECTION=y # enable GPIO CONFIG_GPIO=y -# Assume we start console by default -CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y - -# Console over USB CDC-ACM -CONFIG_USB_DEVICE_STACK=y CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y diff --git a/boards/ct/ctcc/Kconfig b/boards/ct/ctcc/Kconfig deleted file mode 100644 index 3a7ec750888b5..0000000000000 --- a/boards/ct/ctcc/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# CTHINGS.CO Connectivity Card board configuration - -# Copyright (c) 2024 CTHINGS.CO -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_SERIAL_BACKEND_CDC_ACM - bool "USB CDC" - default y - depends on BOARD_CTCC_NRF52840 diff --git a/boards/ct/ctcc/Kconfig.ctcc b/boards/ct/ctcc/Kconfig.ctcc index bdda03b4c0a73..7434347751dcb 100644 --- a/boards/ct/ctcc/Kconfig.ctcc +++ b/boards/ct/ctcc/Kconfig.ctcc @@ -5,3 +5,4 @@ config BOARD_CTCC select SOC_NRF52840_QIAA if BOARD_CTCC_NRF52840 + select SOC_NRF9161_LACA if BOARD_CTCC_NRF9161 || BOARD_CTCC_NRF9161_NS diff --git a/boards/ct/ctcc/Kconfig.defconfig b/boards/ct/ctcc/Kconfig.defconfig index f7ec488427698..298f3d2fe2185 100644 --- a/boards/ct/ctcc/Kconfig.defconfig +++ b/boards/ct/ctcc/Kconfig.defconfig @@ -5,51 +5,27 @@ if BOARD_CTCC_NRF52840 -if BOARD_SERIAL_BACKEND_CDC_ACM +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" -config USB_DEVICE_STACK - default y - -config USB_CDC_ACM - default SERIAL - -config CONSOLE - default y - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y if !MCUBOOT && CONSOLE - -config USB_DEVICE_REMOTE_WAKEUP - default n - -if LOG - -# Turn off logging for USB CDC ACM -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF -endchoice - -# Turn off logging for USB Device -choice USB_DEVICE_LOG_LEVEL_CHOICE - default USB_DEVICE_LOG_LEVEL_OFF -endchoice +endif # BOARD_CTCC_NRF52840 -# Wait 5s at startup for logging -config LOG_PROCESS_THREAD_STARTUP_DELAY_MS - default 5000 +if BOARD_CTCC_NRF9161 || BOARD_CTCC_NRF9161_NS -endif # LOG +# Workaround for not being able to have commas in macro arguments. +# For explanation please see: boards/nordic/nrf9161dk/Kconfig.defconfig +DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition -if USB_DEVICE_STACK +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) + depends on BOARD_CTCC_NRF9161 && TRUSTED_EXECUTION_SECURE -config SERIAL - default y +if BOARD_CTCC_NRF9161_NS -endif # USB_DEVICE_STACK +config FLASH_LOAD_OFFSET + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) -endif # BOARD_SERIAL_BACKEND_CDC_ACM +config FLASH_LOAD_SIZE + default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) -endif # BOARD_CTCC_NRF52840 +endif # BOARD_CTCC_NRF9161_NS +endif # BOARD_CTCC_NRF9161 || BOARD_CTCC_NRF9161_NS diff --git a/boards/ct/ctcc/board.cmake b/boards/ct/ctcc/board.cmake index 3a315c29fbe8e..11d0511404b1a 100644 --- a/boards/ct/ctcc/board.cmake +++ b/boards/ct/ctcc/board.cmake @@ -1,6 +1,19 @@ # SPDX-License-Identifier: Apache-2.0 -board_runner_args(nrfjprog "--softreset") -board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") -include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) -include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +if(CONFIG_BOARD_CTCC_NRF52840) + board_runner_args(nrfjprog "--softreset") + board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") + include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) + include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +elseif(CONFIG_BOARD_CTCC_NRF9161 OR CONFIG_BOARD_CTCC_NRF9161_NS) + if(CONFIG_BOARD_CTCC_NRF9161_NS) + set(TFM_PUBLIC_KEY_FORMAT "full") + endif() + if(CONFIG_TFM_FLASH_MERGED_BINARY) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) + endif() + board_runner_args(nrfjprog "--softreset") + board_runner_args(pyocd "--target=nrf9161" "--frequency=4000000") + include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) + include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +endif() diff --git a/boards/ct/ctcc/board.yml b/boards/ct/ctcc/board.yml index b6212047d79f3..826b1846af5dc 100644 --- a/boards/ct/ctcc/board.yml +++ b/boards/ct/ctcc/board.yml @@ -1,5 +1,8 @@ board: name: ctcc - full_name: Connectivity Card nRF52840 + full_name: CTHINGS.CO Connectivity Card socs: - name: nrf52840 + - name: nrf9161 + variants: + - name: 'ns' diff --git a/boards/ct/ctcc/ctcc_nrf52840.dts b/boards/ct/ctcc/ctcc_nrf52840.dts index 13b88e1ee053a..f99cc540e9c6f 100644 --- a/boards/ct/ctcc/ctcc_nrf52840.dts +++ b/boards/ct/ctcc/ctcc_nrf52840.dts @@ -12,11 +12,6 @@ compatible = "ct,ctcc-nrf52840"; chosen { - zephyr,console = &cdc_acm_uart; - zephyr,shell-uart = &cdc_acm_uart; - zephyr,uart-mcumgr = &cdc_acm_uart; - zephyr,bt-mon-uart = &cdc_acm_uart; - zephyr,bt-c2h-uart = &cdc_acm_uart; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; @@ -69,6 +64,10 @@ }; }; +®0 { + status = "okay"; +}; + ®1 { regulator-initial-mode = ; }; @@ -88,8 +87,6 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - cdc_acm_uart: cdc_acm_uart { - compatible = "zephyr,cdc-acm-uart"; - }; }; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/ct/ctcc/ctcc_nrf52840.yaml b/boards/ct/ctcc/ctcc_nrf52840.yaml index 2151c146fb7f6..332273c3a4257 100644 --- a/boards/ct/ctcc/ctcc_nrf52840.yaml +++ b/boards/ct/ctcc/ctcc_nrf52840.yaml @@ -5,10 +5,10 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - ble - gpio - usb_device - watchdog + - counter vendor: ct diff --git a/boards/ct/ctcc/ctcc_nrf9161-pinctrl.dtsi b/boards/ct/ctcc/ctcc_nrf9161-pinctrl.dtsi new file mode 100644 index 0000000000000..c48b2987b85d0 --- /dev/null +++ b/boards/ct/ctcc/ctcc_nrf9161-pinctrl.dtsi @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 CTHINGS.CO + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + ; + }; + group2 { + psels = , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + uart1_default: uart1_default { + group1 { + psels = , + ; + }; + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + uart1_sleep: uart1_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + spi3_default: spi3_default { + group1 { + psels = , + , + ; + nordic,drive-mode = ; + }; + }; + + spi3_sleep: spi3_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; diff --git a/boards/ct/ctcc/ctcc_nrf9161.dts b/boards/ct/ctcc/ctcc_nrf9161.dts new file mode 100644 index 0000000000000..6f3d9af92c6c1 --- /dev/null +++ b/boards/ct/ctcc/ctcc_nrf9161.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 CTHINGS.CO + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "ctcc_nrf9161_common.dtsi" + +/ { + chosen { + zephyr,sram = &sram0_s; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,sram-secure-partition = &sram0_s; + zephyr,sram-non-secure-partition = &sram0_ns; + }; +}; diff --git a/boards/ct/ctcc/ctcc_nrf9161.yaml b/boards/ct/ctcc/ctcc_nrf9161.yaml new file mode 100644 index 0000000000000..3c3a63796e1cc --- /dev/null +++ b/boards/ct/ctcc/ctcc_nrf9161.yaml @@ -0,0 +1,14 @@ +identifier: ctcc/nrf9161 +name: CTHINGS.CO Connectivity Card nRF9161 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 88 +flash: 1024 +supported: + - gpio + - watchdog + - counter +vendor: ct diff --git a/boards/ct/ctcc/ctcc_nrf9161_common.dtsi b/boards/ct/ctcc/ctcc_nrf9161_common.dtsi new file mode 100644 index 0000000000000..92a2a757c55a2 --- /dev/null +++ b/boards/ct/ctcc/ctcc_nrf9161_common.dtsi @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 CTHINGS.CO + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ctcc_nrf9161-pinctrl.dtsi" +#include + +/ { + model = "CTHINGS.CO Connectivity Card nRF9161"; + compatible = "ct,ctcc-nrf9161"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + }; + + leds { + compatible = "gpio-leds"; + led1: led_1 { + gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + label = "LED 1"; + }; + led2: led_2 { + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + label = "LED 2"; + }; + }; + + aliases { + led0 = &led1; + led1 = &led2; + mcuboot-led0 = &led1; + bootloader-led0 = &led1; + watchdog0 = &wdt0; + spi-flash0 = &mx25r6435; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&spi3 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi3_default>; + pinctrl-1 = <&spi3_sleep>; + pinctrl-names = "default", "sleep"; + + mx25r6435: mx25r6435fm2il0@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; + spi-max-frequency = <10000000>; + size = ; + has-dpd; + dpd-wakeup-sequence = <30000>, <20>, <30000>; + jedec-id = [c2 25 38]; + }; +}; + +/* Include default memory partition configuration file */ +#include diff --git a/boards/ct/ctcc/ctcc_nrf9161_defconfig b/boards/ct/ctcc/ctcc_nrf9161_defconfig new file mode 100644 index 0000000000000..c486d8323821a --- /dev/null +++ b/boards/ct/ctcc/ctcc_nrf9161_defconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/ct/ctcc/ctcc_nrf9161_ns.dts b/boards/ct/ctcc/ctcc_nrf9161_ns.dts new file mode 100644 index 0000000000000..1c23b0b8410ce --- /dev/null +++ b/boards/ct/ctcc/ctcc_nrf9161_ns.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 CTHINGS.CO + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "ctcc_nrf9161_common.dtsi" + +/ { + chosen { + zephyr,flash = &flash0; + zephyr,sram = &sram0_ns; + zephyr,code-partition = &slot0_ns_partition; + }; +}; + +/* Disable UART1, because it is used by default in TF-M */ +&uart1 { + status = "disabled"; +}; diff --git a/boards/ct/ctcc/ctcc_nrf9161_ns.yaml b/boards/ct/ctcc/ctcc_nrf9161_ns.yaml new file mode 100644 index 0000000000000..1017ca1989b55 --- /dev/null +++ b/boards/ct/ctcc/ctcc_nrf9161_ns.yaml @@ -0,0 +1,13 @@ +identifier: ctcc/nrf9161/ns +name: CTHINGS.CO Connectivity Card nRF9161 Non Secure +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 128 +flash: 192 +supported: + - gpio + - watchdog +vendor: ct diff --git a/boards/ct/ctcc/ctcc_nrf9161_ns_defconfig b/boards/ct/ctcc/ctcc_nrf9161_ns_defconfig new file mode 100644 index 0000000000000..2a74dd56f4144 --- /dev/null +++ b/boards/ct/ctcc/ctcc_nrf9161_ns_defconfig @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# This board implies building Non-Secure firmware +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/ct/ctcc/doc/img/ctcc_nrf9161_mpcie.webp b/boards/ct/ctcc/doc/img/ctcc_nrf9161_mpcie.webp new file mode 100644 index 0000000000000..20785314c3d4d Binary files /dev/null and b/boards/ct/ctcc/doc/img/ctcc_nrf9161_mpcie.webp differ diff --git a/boards/ct/ctcc/doc/index.rst b/boards/ct/ctcc/doc/index.rst index 73b857b47dfa5..97780246a742c 100644 --- a/boards/ct/ctcc/doc/index.rst +++ b/boards/ct/ctcc/doc/index.rst @@ -3,19 +3,27 @@ Overview ******** -The Connectivity Card nRF52840 enables BLE and IEEE 802.15.4 connectivity -over mPCIe or M.2 using USB port with on-board nRF52840 SoC. +Connectivity Cards come with either M.2 or mPCIe form factor with various SoCs, enabling different +radio interfaces. -This board has following features: +* The Connectivity Card nRF52840 enables BLE and IEEE 802.15.4 over mPCIe or M.2 + using USB device with on-board nRF52840 SoC + +* The Connectivity Card nRF9161 enables LTE-M/NB-IoT and DECT NR+ over mPCIe or M.2 + using on-board USB-UART converter + +Connectivity Card has following features: * CLOCK * FLASH * :abbr:`GPIO (General Purpose Input Output)` * :abbr:`MPU (Memory Protection Unit)` * :abbr:`NVIC (Nested Vectored Interrupt Controller)` -* RADIO (Bluetooth Low Energy and 802.15.4) +* RADIO (Bluetooth Low Energy and 802.15.4) (only nRF52840) +* RADIO (LTE-M/NB-IoT and DECT NR+) (only nRF9161) * :abbr:`RTC (nRF RTC System Clock)` -* :abbr:`USB (Universal Serial Bus)` +* :abbr:`USB (Universal Serial Bus)` (only nRF52840) +* :abbr:`UARTE (Universal asynchronous receiver-transmitter with EasyDMA)` (only nRF9161) * :abbr:`WDT (Watchdog Timer)` .. figure:: img/ctcc_nrf52840_mpcie.webp @@ -30,13 +38,21 @@ This board has following features: ctcc/nrf52840 M.2 board +.. figure:: img/ctcc_nrf9161_mpcie.webp + :align: center + :alt: CTCC nRF9161 mPCIe + + ctcc/nrf9161 mPCIe board + More information about the board can be found at the -`ctcc_nrf52840 Website`_ and for SoC information: `Nordic Semiconductor Infocenter`_. +`Connectivity Cards Website`_ and for SoC information: `Nordic Semiconductor Infocenter`_. Hardware ******** -The ``ctcc/nrf52840`` board target has one external oscillator of the 32.768 kHz. +* The ``ctcc/nrf52840`` board target has one external oscillator of the 32.768 kHz. +* The ``ctcc/nrf9161`` board target has one external SPI NOR 64Mbit memory and one on-board USB-UART + converter (CP210X). Supported Features ================== @@ -67,22 +83,61 @@ hardware features: | WDT | on-chip | watchdog | +-----------+------------+----------------------+ +The ``ctcc/nrf9161`` board target supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| FLASH | external | spi | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| RADIO | on-chip | LTE-M/NB-IoT, | +| | | DECT NR\+ | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| SPU | on-chip | system protection | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + Connections and IOs =================== LED --- -Note that board does not have on-board LEDs, however it exposes +Note that boards do not have on-board LEDs, however they expose LED signals on mPCIe/M.2 pins. +nRF52840: + * LED1 = P0.23 * LED2 = P0.22 +nRF9161: + +* LED1 = P0.11 +* LED2 = P0.12 + Programming and Debugging ************************* -Applications for the ``ctcc/nrf52840`` board target can be +Applications for ``ctcc`` boards can be built in the usual way (see :ref:`build_an_application` for more details). Flashing @@ -91,7 +146,10 @@ Flashing The board supports the following programming options: 1. Using an external :ref:`debug probe ` -2. Using MCUboot with DFU support +2. Using `MCUboot`_ with MCUmgr support + +Below instructions are provided for ``ctcc/nrf52840``, to use ``nrf9161`` target, the USB device configs have +to be replaced with UART configurations. Option 1: Using an External Debug Probe --------------------------------------- @@ -114,58 +172,65 @@ logs on emulated USB port. :board: ctcc/nrf52840 :goals: build flash -Debugging -========= +Option 2: Using MCUboot with MCUmgr support +------------------------------------------- -The ``ctcc/nrf52840`` board target does not have an on-board J-Link debug IC, however -instructions from the :ref:`nordic_segger` page also apply to this board, -with the additional step of connecting an external debugger. +It is also possible to use the MCUboot bootloader with :ref:`mcu_mgr` support to flash +Zephyr applications. + +Install a MCUmgr-compatible tool from :ref:`supported list ` +and make sure MCUboot's ``imgtool`` is available for signing your binary +for MCUboot as described on :ref:`west-sign`. + +#. Compile MCUboot as a Zephyr application with ``MCUmgr`` support. -Option 2: Using MCUboot with DFU support ----------------------------------------- + .. tabs:: -It is also possible to use the MCUboot bootloader with DFU support to flash -Zephyr applications. You need to flash MCUboot with DFU support and fill in slot0 with -some application one-time using Option 1. Then you can re-flash an application using DFU utility -by loading images to slot1. Note, it's not possible to have only MCUboot and load directly -software to slot0 due to DFU implementation in Zephyr, which for present slot0 and slot1 in flash -map, it assumes only slot1 partition as writeable. + .. group-tab:: nRF52840 -Install ``dfu-util`` first and make sure MCUboot's ``imgtool`` is -available for signing your binary for MCUboot as described on :ref:`west-sign`. + To build the MCUboot: -Next, do the **one-time setup** to flash MCUboot with DFU support. -We'll assume you've cloned the `MCUboot`_ as a submodule when initializing -Zephyr repositories using :ref:`west` tool. + .. zephyr-app-commands:: + :app: mcuboot/boot/zephyr + :board: ctcc/nrf52840 + :build-dir: mcuboot + :goals: build -#. Compile MCUboot as a Zephyr application with DFU support. + .. group-tab:: nRF9161 - .. zephyr-app-commands:: - :app: mcuboot/boot/zephyr - :board: ctcc/nrf52840 - :build-dir: mcuboot - :goals: build - :gen-args: -DCONFIG_BOOT_USB_DFU_WAIT=y + To build the MCUboot: + + .. zephyr-app-commands:: + :app: mcuboot/boot/zephyr + :board: ctcc/nrf9161 + :build-dir: mcuboot + :goals: build #. Flash it onto the board as described in Option 1. -#. Flash other Zephyr application to fill in slot0 e.g: +#. Flash other Zephyr application over USB using :ref:`MCUmgr-compatible tool ` and reset target to boot into the image. + + .. tabs:: + + .. group-tab:: nRF52840 - .. zephyr-app-commands:: - :zephyr-app: samples/subsys/usb/dfu - :board: ctcc/nrf52840 - :build-dir: dfu - :goals: build - :gen-args: -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"path/to/mcuboot/boot/root-rsa-2048.pem\" + Build the blinky example with MCUboot support: -You can now flash a Zephyr application to the board using DFU util. -As an example we'll use the :zephyr:code-sample:`usb-cdc-acm-console` sample. + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: ctcc/nrf52840 + :goals: build + :gen-args: -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"path/to/mcuboot/boot/root-rsa-2048.pem\" - .. zephyr-app-commands:: - :zephyr-app: samples/subsys/usb/console - :board: ctcc/nrf52840 - :goals: build flash - :gen-args: -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"path/to/mcuboot/boot/root-rsa-2048.pem\" + .. group-tab:: nRF9161 + + Build the blinky example with MCUboot support: + + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: ctcc/nrf9161 + :goals: build + :gen-args: -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"path/to/mcuboot/boot/root-rsa-2048.pem\" .. note:: @@ -173,25 +238,26 @@ As an example we'll use the :zephyr:code-sample:`usb-cdc-acm-console` sample. directory. Providing certificate in build args produces signed binary automatically. Do not use this certificate in your production firmware! -#. Plug in ``ctcc/nrf52840`` card to mPCIe/M.2 slot or use mPCIe/M.2 adapter to USB - and plug such adapter to USB port. +Debugging +========= - You should see ``NordicSemiconductor MCUBOOT`` or ``NordicSemiconductor Zephyr DFU sample`` - (if you flashed ``dfu`` sample to slot0) device once plugging it into host - USB port. You can check that on Linux system by entering ``lsusb`` command. +These boards do not have an on-board J-Link debug IC, however +instructions from the :ref:`nordic_segger` page also apply to them, +with the additional step of connecting an external debugger. - To check if DFU device is visible you can enter ``sudo dfu-util -l`` command. Once the - device is visible you can flash Zephyr image using DFU util: ``sudo dfu-util --alt 1 --download build/zephyr/zephyr.signed.bin`` +To test flashed software, plug in ``ctcc`` card to mPCIe/M.2 slot or use mPCIe/M.2 adapter to USB and plug such adapter to USB port. + * For ``ctcc/nrf52840`` check on Linux system by entering ``lsusb`` command if the following device appears: ``NordicSemiconductor MCUBOOT`` or ``NordicSemiconductor USB-DEV`` (when booted into blinky example). + * For ``ctcc/nrf9161`` it's not possible to see a change in ``lsusb`` due to the on-board USB-UART converter. Intead, connect to the UART console using a terminal emulation program of your choice. References ********** .. target-notes:: -.. _ctcc_nrf52840 Website: +.. _Connectivity Cards Website: https://cthings.co/products/connectivity-cards .. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com .. _MCUboot: - https://github.com/JuulLabs-OSS/mcuboot + https://github.com/zephyrproject-rtos/mcuboot diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_0_0_0.yaml b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_0_0_0.yaml index 0ef2e8ae82358..562a016589cb6 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_0_0_0.yaml +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_0_0_0.yaml @@ -14,7 +14,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_spi diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_1_0_0.yaml b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_1_0_0.yaml index 032fc65cdf356..c4284bd0ef8a3 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_1_0_0.yaml +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_1_0_0.yaml @@ -14,7 +14,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_spi diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_defconfig b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_defconfig index fefeed4980f7a..16e024e3bcaf9 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_defconfig +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m0_defconfig @@ -7,7 +7,6 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_BUILD_OUTPUT_HEX=y # UART driver CONFIG_SERIAL=y diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_0_0_0.yaml b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_0_0_0.yaml index 1ca0aaa3a1133..ba6b4bbc74d69 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_0_0_0.yaml +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_0_0_0.yaml @@ -14,7 +14,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - gpio diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_1_0_0.yaml b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_1_0_0.yaml index cdfb09a694291..44697309a42af 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_1_0_0.yaml +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_1_0_0.yaml @@ -14,7 +14,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - gpio diff --git a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_defconfig b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_defconfig index fefeed4980f7a..16e024e3bcaf9 100644 --- a/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_defconfig +++ b/boards/cypress/cy8ckit_062_ble/cy8ckit_062_ble_cy8c6347_m4_defconfig @@ -7,7 +7,6 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_BUILD_OUTPUT_HEX=y # UART driver CONFIG_SERIAL=y diff --git a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0.yaml b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0.yaml index 4135437c52ae3..12d1dca31d55d 100644 --- a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0.yaml +++ b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0.yaml @@ -13,7 +13,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio vendor: cypress diff --git a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig index fd9d1d319abcf..d9ff32f44cc97 100644 --- a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig +++ b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig @@ -6,7 +6,6 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_BUILD_OUTPUT_HEX=y # UART driver CONFIG_SERIAL=y diff --git a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4.yaml b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4.yaml index e861d197140fd..2a5b4a1f78898 100644 --- a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4.yaml +++ b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4.yaml @@ -13,7 +13,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio vendor: cypress diff --git a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4_defconfig b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4_defconfig index fd9d1d319abcf..d9ff32f44cc97 100644 --- a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4_defconfig +++ b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m4_defconfig @@ -6,7 +6,6 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_BUILD_OUTPUT_HEX=y # UART driver CONFIG_SERIAL=y diff --git a/boards/deprecated.cmake b/boards/deprecated.cmake index 91e7e660d38b0..78a960ec2e4ae 100644 --- a/boards/deprecated.cmake +++ b/boards/deprecated.cmake @@ -25,3 +25,15 @@ set(mimx8mp_phyboard_pollux/mimx8ml8/m7_DEPRECATED set(mimx8mm_phyboard_polis/mimx8mm6/m4_DEPRECATED phyboard_polis/mimx8mm6/m4 ) +set(mimxrt1050_evk_DEPRECATED + mimxrt1050_evk/mimxrt1052/hyperflash +) +set(mimxrt1060_evk_DEPRECATED + mimxrt1060_evk/mimxrt1064/hyperflash +) +set(mimxrt1060_evk_DEPRECATED + mimxrt1060_evk/mimxrt1062/qspi +) +set(mimxrt1060_evkb_DEPRECATED + mimxrt1060_evk@B/mimxrt1062/qspi +) diff --git a/boards/digilent/arty_a7/arty_a7_designstart_fpga_cortex_m1.yaml b/boards/digilent/arty_a7/arty_a7_designstart_fpga_cortex_m1.yaml index 565ddbffdb88c..aaf3326b4a405 100644 --- a/boards/digilent/arty_a7/arty_a7_designstart_fpga_cortex_m1.yaml +++ b/boards/digilent/arty_a7/arty_a7_designstart_fpga_cortex_m1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 64 supported: diff --git a/boards/digilent/arty_a7/arty_a7_designstart_fpga_cortex_m3.yaml b/boards/digilent/arty_a7/arty_a7_designstart_fpga_cortex_m3.yaml index 416365ff29140..c4334d658f56f 100644 --- a/boards/digilent/arty_a7/arty_a7_designstart_fpga_cortex_m3.yaml +++ b/boards/digilent/arty_a7/arty_a7_designstart_fpga_cortex_m3.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 32 supported: diff --git a/boards/digilent/zybo/zybo.yaml b/boards/digilent/zybo/zybo.yaml index 573fb74f666a2..8f4e5f5b94ab9 100644 --- a/boards/digilent/zybo/zybo.yaml +++ b/boards/digilent/zybo/zybo.yaml @@ -8,7 +8,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 524288 supported: - gpio diff --git a/boards/dptechnics/walter/walter_esp32s3_appcpu.dts b/boards/dptechnics/walter/walter_esp32s3_appcpu.dts index 8135d20849095..e7e6ff46a86f2 100644 --- a/boards/dptechnics/walter/walter_esp32s3_appcpu.dts +++ b/boards/dptechnics/walter/walter_esp32s3_appcpu.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/dptechnics/walter/walter_esp32s3_appcpu_defconfig b/boards/dptechnics/walter/walter_esp32s3_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/dptechnics/walter/walter_esp32s3_appcpu_defconfig +++ b/boards/dptechnics/walter/walter_esp32s3_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/dptechnics/walter/walter_esp32s3_procpu.dts b/boards/dptechnics/walter/walter_esp32s3_procpu.dts index 310fa5d59df8b..8d864885e0f00 100644 --- a/boards/dptechnics/walter/walter_esp32s3_procpu.dts +++ b/boards/dptechnics/walter/walter_esp32s3_procpu.dts @@ -22,7 +22,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/dptechnics/walter/walter_esp32s3_procpu.yaml b/boards/dptechnics/walter/walter_esp32s3_procpu.yaml index 839c29069a703..a26fa60e26b0d 100644 --- a/boards/dptechnics/walter/walter_esp32s3_procpu.yaml +++ b/boards/dptechnics/walter/walter_esp32s3_procpu.yaml @@ -16,8 +16,4 @@ supported: - pwm - dma - input -testing: - ignore_tags: - - net - - bluetooth vendor: dptechnics diff --git a/boards/dptechnics/walter/walter_esp32s3_procpu_defconfig b/boards/dptechnics/walter/walter_esp32s3_procpu_defconfig index 59f3df7a866cb..36749d6444836 100644 --- a/boards/dptechnics/walter/walter_esp32s3_procpu_defconfig +++ b/boards/dptechnics/walter/walter_esp32s3_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/dragino/lsn50/dragino_lsn50.yaml b/boards/dragino/lsn50/dragino_lsn50.yaml index 52418c949a45b..cc4c19c5958eb 100644 --- a/boards/dragino/lsn50/dragino_lsn50.yaml +++ b/boards/dragino/lsn50/dragino_lsn50.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 flash: 192 testing: diff --git a/boards/dragino/nbsn95/dragino_nbsn95.yaml b/boards/dragino/nbsn95/dragino_nbsn95.yaml index f614987d58d9d..3128e7d2a043d 100644 --- a/boards/dragino/nbsn95/dragino_nbsn95.yaml +++ b/boards/dragino/nbsn95/dragino_nbsn95.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 flash: 192 testing: diff --git a/boards/ebyte/e73_tbb/ebyte_e73_tbb_nrf52832.yaml b/boards/ebyte/e73_tbb/ebyte_e73_tbb_nrf52832.yaml index 9311e76cff148..67853fd073d21 100644 --- a/boards/ebyte/e73_tbb/ebyte_e73_tbb_nrf52832.yaml +++ b/boards/ebyte/e73_tbb/ebyte_e73_tbb_nrf52832.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/electronut/nrf52840_blip/nrf52840_blip.yaml b/boards/electronut/nrf52840_blip/nrf52840_blip.yaml index 694c2c251b8d2..975f1b831edfb 100644 --- a/boards/electronut/nrf52840_blip/nrf52840_blip.yaml +++ b/boards/electronut/nrf52840_blip/nrf52840_blip.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - i2c diff --git a/boards/electronut/nrf52840_papyr/nrf52840_papyr.yaml b/boards/electronut/nrf52840_papyr/nrf52840_papyr.yaml index 446c5205f963e..1c743016802e8 100644 --- a/boards/electronut/nrf52840_papyr/nrf52840_papyr.yaml +++ b/boards/electronut/nrf52840_papyr/nrf52840_papyr.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/element14/warp7/warp7_mcimx7d_m4.yaml b/boards/element14/warp7/warp7_mcimx7d_m4.yaml index 96a7e7fbca84e..24bcdb296fb6b 100644 --- a/boards/element14/warp7/warp7_mcimx7d_m4.yaml +++ b/boards/element14/warp7/warp7_mcimx7d_m4.yaml @@ -13,7 +13,6 @@ flash: 32 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/enclustra/mercury_xu/mercury_xu.dts b/boards/enclustra/mercury_xu/mercury_xu.dts index df51ab470c579..c0abbec19a3ac 100644 --- a/boards/enclustra/mercury_xu/mercury_xu.dts +++ b/boards/enclustra/mercury_xu/mercury_xu.dts @@ -10,7 +10,7 @@ / { model = "Mercury XU"; - compatible = "xlnx,zynqmp"; + compatible = "enclustra,mercury_xu"; chosen { zephyr,console = &uart0; diff --git a/boards/enclustra/mercury_xu/mercury_xu.yaml b/boards/enclustra/mercury_xu/mercury_xu.yaml index df01c2b112a71..f2cc537a06c67 100644 --- a/boards/enclustra/mercury_xu/mercury_xu.yaml +++ b/boards/enclustra/mercury_xu/mercury_xu.yaml @@ -6,4 +6,4 @@ arch: arm toolchain: - zephyr - gnuarmemb -vendor: xlnx +vendor: enclustra diff --git a/boards/ene/kb1200_evb/kb1200_evb.yaml b/boards/ene/kb1200_evb/kb1200_evb.yaml index efa85b9c830e5..e381e7c6c6a28 100644 --- a/boards/ene/kb1200_evb/kb1200_evb.yaml +++ b/boards/ene/kb1200_evb/kb1200_evb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - uart diff --git a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_appcpu.dts b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_appcpu.dts index e86ffdb90bf79..c88ae757867fd 100644 --- a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_appcpu.dts +++ b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.dts b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.dts index fb3075c028e67..783a8f2a7f7bf 100644 --- a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.dts +++ b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.dts @@ -32,7 +32,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.yaml b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.yaml index 88e22e7b170e9..7bc3c8feb55f7 100644 --- a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.yaml +++ b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu.yaml @@ -18,8 +18,4 @@ supported: - counter - entropy - input -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu_defconfig b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu_defconfig index 3be2d9e39d558..172a46d10057f 100644 --- a/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu_defconfig +++ b/boards/espressif/esp32_devkitc_wroom/esp32_devkitc_wroom_procpu_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_appcpu.dts b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_appcpu.dts index 81078114c97ba..f6fb39576f2e5 100644 --- a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_appcpu.dts +++ b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_appcpu_defconfig b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_appcpu_defconfig +++ b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.dts b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.dts index df8e3c019fc5f..33f0f3f134b3a 100644 --- a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.dts +++ b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.dts @@ -9,7 +9,7 @@ #include "esp32_devkitc_wrover-pinctrl.dtsi" #include #include -#include +#include / { model = "Espressif ESP32-DevkitC WROVER-E PROCPU"; @@ -32,7 +32,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.yaml b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.yaml index a2089253a3c6b..62e40f71e9373 100644 --- a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.yaml +++ b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu.yaml @@ -18,8 +18,4 @@ supported: - counter - entropy - input -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu_defconfig b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu_defconfig index 3be2d9e39d558..172a46d10057f 100644 --- a/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu_defconfig +++ b/boards/espressif/esp32_devkitc_wrover/esp32_devkitc_wrover_procpu_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_appcpu.dts b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_appcpu.dts index 24b4fd8271fb9..c4a99a62ef96f 100644 --- a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_appcpu.dts +++ b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_appcpu_defconfig b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_appcpu_defconfig +++ b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.dts b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.dts index 61838ea748a2d..799c17ad84955 100644 --- a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.dts +++ b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.dts @@ -7,7 +7,7 @@ #include #include "esp32_ethernet_kit-pinctrl.dtsi" -#include +#include / { model = "Espressif ESP32-Ethernet-Kit PROCPU"; @@ -19,7 +19,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.yaml b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.yaml index ca098c1ef773d..fb3c3cdd704af 100644 --- a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.yaml +++ b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu.yaml @@ -10,8 +10,4 @@ supported: - uart - nvs - pwm -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu_defconfig b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu_defconfig index f029cac9e9e77..e192c240251c1 100644 --- a/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu_defconfig +++ b/boards/espressif/esp32_ethernet_kit/esp32_ethernet_kit_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.dts b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.dts index c009ccb0d0a5d..86326fcc077f0 100644 --- a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.dts +++ b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.dts @@ -16,7 +16,7 @@ compatible = "espressif,esp32c3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.yaml b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.yaml index 876ee78855375..f2b98e3e4ed67 100644 --- a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.yaml +++ b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc.yaml @@ -15,8 +15,4 @@ supported: - spi - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc_defconfig b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/espressif/esp32c3_devkitc/esp32c3_devkitc_defconfig +++ b/boards/espressif/esp32c3_devkitc/esp32c3_devkitc_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.dts b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.dts index 3cc7c5218dea2..25bd583daee3d 100644 --- a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.dts +++ b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.dts @@ -16,7 +16,7 @@ compatible = "espressif,esp32c3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.yaml b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.yaml index 49ba690a56348..38153891381d8 100644 --- a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.yaml +++ b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm.yaml @@ -16,8 +16,4 @@ supported: - spi - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm_defconfig b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/espressif/esp32c3_devkitm/esp32c3_devkitm_defconfig +++ b/boards/espressif/esp32c3_devkitm/esp32c3_devkitm_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32c3_rust/esp32c3_rust.dts b/boards/espressif/esp32c3_rust/esp32c3_rust.dts index 5d397f3e1c9c5..867fa84adcf63 100644 --- a/boards/espressif/esp32c3_rust/esp32c3_rust.dts +++ b/boards/espressif/esp32c3_rust/esp32c3_rust.dts @@ -17,7 +17,7 @@ compatible = "espressif,esp32c3_rust"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32c3_rust/esp32c3_rust.yaml b/boards/espressif/esp32c3_rust/esp32c3_rust.yaml index fedd0178f45d6..a82552337b42a 100644 --- a/boards/espressif/esp32c3_rust/esp32c3_rust.yaml +++ b/boards/espressif/esp32c3_rust/esp32c3_rust.yaml @@ -18,8 +18,4 @@ supported: - spi - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32c3_rust/esp32c3_rust_defconfig b/boards/espressif/esp32c3_rust/esp32c3_rust_defconfig index a0483fa8a08a0..147089fe70e6f 100644 --- a/boards/espressif/esp32c3_rust/esp32c3_rust_defconfig +++ b/boards/espressif/esp32c3_rust/esp32c3_rust_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32c6_devkitc/doc/index.rst b/boards/espressif/esp32c6_devkitc/doc/index.rst index 4ba1e0c7d949a..ab81b187d746a 100644 --- a/boards/espressif/esp32c6_devkitc/doc/index.rst +++ b/boards/espressif/esp32c6_devkitc/doc/index.rst @@ -99,10 +99,16 @@ Current Zephyr's ESP32-C6-DevKitC board supports the following features: +------------+------------+-------------------------------------+ | SPI Master | on-chip | spi | +------------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++------------+------------+-------------------------------------+ +| Timers | on-chip | counter | ++------------+------------+-------------------------------------+ | Watchdog | on-chip | watchdog | +------------+------------+-------------------------------------+ | LEDC | on-chip | pwm | +------------+------------+-------------------------------------+ +| MCPWM | on-chip | pwm | ++------------+------------+-------------------------------------+ | SPI DMA | on-chip | spi | +------------+------------+-------------------------------------+ | GDMA | on-chip | dma | @@ -111,6 +117,8 @@ Current Zephyr's ESP32-C6-DevKitC board supports the following features: +------------+------------+-------------------------------------+ | USB-CDC | on-chip | serial | +------------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++------------+------------+-------------------------------------+ | Wi-Fi | on-chip | | +------------+------------+-------------------------------------+ diff --git a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc-pinctrl.dtsi b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc-pinctrl.dtsi index a9cda93d22a35..5265d5ef97280 100644 --- a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc-pinctrl.dtsi +++ b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc-pinctrl.dtsi @@ -32,4 +32,14 @@ output-low; }; }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; }; diff --git a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.dts b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.dts index a00de99e2b52c..896ae30530cc9 100644 --- a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.dts +++ b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.dts @@ -16,7 +16,7 @@ compatible = "espressif,esp32c6"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sramhp; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; @@ -49,6 +49,13 @@ status = "okay"; }; +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + &spi2 { #address-cells = <1>; #size-cells = <0>; diff --git a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.yaml b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.yaml index e72471a02edd2..95385596d9de6 100644 --- a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.yaml +++ b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc.yaml @@ -6,14 +6,13 @@ arch: riscv toolchain: - zephyr supported: + - adc - gpio - watchdog - uart - dma + - pwm - spi + - counter - entropy -testing: - ignore_tags: - - net - - bluetooth - - tracing + - i2c diff --git a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_defconfig b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_defconfig index 6539bd42e5947..187793c76e8cc 100644 --- a/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_defconfig +++ b/boards/espressif/esp32c6_devkitc/esp32c6_devkitc_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.dts b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.dts index 9038cea4a1ec3..f60ce264843fb 100644 --- a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.dts +++ b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.dts @@ -23,7 +23,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.yaml b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.yaml index 482d8ad5ec2cb..44a6f971e3b74 100644 --- a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.yaml +++ b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc.yaml @@ -19,8 +19,4 @@ supported: - input - can - dma -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc_defconfig b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc_defconfig index f029cac9e9e77..e192c240251c1 100644 --- a/boards/espressif/esp32s2_devkitc/esp32s2_devkitc_defconfig +++ b/boards/espressif/esp32s2_devkitc/esp32s2_devkitc_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32s2_saola/esp32s2_saola.dts b/boards/espressif/esp32s2_saola/esp32s2_saola.dts index c97108951ab4d..88490f1d551c4 100644 --- a/boards/espressif/esp32s2_saola/esp32s2_saola.dts +++ b/boards/espressif/esp32s2_saola/esp32s2_saola.dts @@ -23,7 +23,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32s2_saola/esp32s2_saola.yaml b/boards/espressif/esp32s2_saola/esp32s2_saola.yaml index 1e1e391bb0e22..bebe2a293a8a8 100644 --- a/boards/espressif/esp32s2_saola/esp32s2_saola.yaml +++ b/boards/espressif/esp32s2_saola/esp32s2_saola.yaml @@ -17,8 +17,4 @@ supported: - counter - entropy - input -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32s2_saola/esp32s2_saola_defconfig b/boards/espressif/esp32s2_saola/esp32s2_saola_defconfig index 5476839e2ba63..e192c240251c1 100644 --- a/boards/espressif/esp32s2_saola/esp32s2_saola_defconfig +++ b/boards/espressif/esp32s2_saola/esp32s2_saola_defconfig @@ -1,8 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 - -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu.dts b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu.dts index f105a0f8658b2..bac7de229b331 100644 --- a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu.dts +++ b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu.dts @@ -14,7 +14,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu_defconfig b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu_defconfig +++ b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.dts b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.dts index 99810fa22c75c..48806ab5a4c71 100644 --- a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.dts +++ b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.dts @@ -21,7 +21,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.yaml b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.yaml index 2a5e48d464f5c..ae1de5034e7e4 100644 --- a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.yaml +++ b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu.yaml @@ -17,8 +17,4 @@ supported: - pwm - dma - input -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu_defconfig b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu_defconfig index d789bab1824a6..d8fbaa879257b 100644 --- a/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu_defconfig +++ b/boards/espressif/esp32s3_devkitc/esp32s3_devkitc_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_appcpu.dts b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_appcpu.dts index 4946139c8c6e6..08a9e005be31b 100644 --- a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_appcpu.dts +++ b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_appcpu.dts @@ -14,7 +14,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_appcpu_defconfig b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_appcpu_defconfig deleted file mode 100644 index 1ac2b1c55c9b7..0000000000000 --- a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_appcpu_defconfig +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_MAIN_STACK_SIZE=4096 diff --git a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.dts b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.dts index 7b758eedd4d44..89c5b8c164182 100644 --- a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.dts +++ b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.dts @@ -21,7 +21,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.yaml b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.yaml index 084f6f7539e4b..e153c2e9f8178 100644 --- a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.yaml +++ b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu.yaml @@ -18,8 +18,4 @@ supported: - dma - input - video -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu_defconfig b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu_defconfig index 92308aa841b2e..d8fbaa879257b 100644 --- a/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu_defconfig +++ b/boards/espressif/esp32s3_devkitm/esp32s3_devkitm_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=4096 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp32s3_eye/esp32s3_eye_appcpu.dts b/boards/espressif/esp32s3_eye/esp32s3_eye_appcpu.dts index cd14ce2ea4936..8e323c4e46361 100644 --- a/boards/espressif/esp32s3_eye/esp32s3_eye_appcpu.dts +++ b/boards/espressif/esp32s3_eye/esp32s3_eye_appcpu.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32s3_eye/esp32s3_eye_appcpu_defconfig b/boards/espressif/esp32s3_eye/esp32s3_eye_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/espressif/esp32s3_eye/esp32s3_eye_appcpu_defconfig +++ b/boards/espressif/esp32s3_eye/esp32s3_eye_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.dts b/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.dts index df053757ee4f5..1b2afa8b83af0 100644 --- a/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.dts +++ b/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.dts @@ -24,7 +24,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.yaml b/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.yaml index 089082c42e505..1159b63942b3b 100644 --- a/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.yaml +++ b/boards/espressif/esp32s3_eye/esp32s3_eye_procpu.yaml @@ -17,8 +17,4 @@ supported: - dma - input - video -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp32s3_eye/esp32s3_eye_procpu_defconfig b/boards/espressif/esp32s3_eye/esp32s3_eye_procpu_defconfig index 6c24dead95bf8..32d7051fab45c 100644 --- a/boards/espressif/esp32s3_eye/esp32s3_eye_procpu_defconfig +++ b/boards/espressif/esp32s3_eye/esp32s3_eye_procpu_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=4096 CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp8684_devkitm/doc/index.rst b/boards/espressif/esp8684_devkitm/doc/index.rst index 1b20435c586d0..79c7294615034 100644 --- a/boards/espressif/esp8684_devkitm/doc/index.rst +++ b/boards/espressif/esp8684_devkitm/doc/index.rst @@ -63,6 +63,8 @@ Current Zephyr's ESP8684-DevKitM board supports the following features: +------------+------------+-------------------------------------+ | Timers | on-chip | counter | +------------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++------------+------------+-------------------------------------+ | Wi-Fi | on-chip | | +------------+------------+-------------------------------------+ | LEDC | on-chip | pwm | diff --git a/boards/espressif/esp8684_devkitm/esp8684_devkitm.dts b/boards/espressif/esp8684_devkitm/esp8684_devkitm.dts index 0b52a3d2b86f1..a6a76ac4756bc 100644 --- a/boards/espressif/esp8684_devkitm/esp8684_devkitm.dts +++ b/boards/espressif/esp8684_devkitm/esp8684_devkitm.dts @@ -16,7 +16,7 @@ compatible = "espressif,esp32c2"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp8684_devkitm/esp8684_devkitm.yaml b/boards/espressif/esp8684_devkitm/esp8684_devkitm.yaml index e689bbfe6c13d..870622d948cb9 100644 --- a/boards/espressif/esp8684_devkitm/esp8684_devkitm.yaml +++ b/boards/espressif/esp8684_devkitm/esp8684_devkitm.yaml @@ -5,6 +5,7 @@ arch: riscv toolchain: - zephyr supported: + - adc - gpio - watchdog - uart @@ -12,8 +13,4 @@ supported: - entropy - pwm - spi -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp8684_devkitm/esp8684_devkitm_defconfig b/boards/espressif/esp8684_devkitm/esp8684_devkitm_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/espressif/esp8684_devkitm/esp8684_devkitm_defconfig +++ b/boards/espressif/esp8684_devkitm/esp8684_devkitm_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/espressif/esp_wrover_kit/esp_wrover_kit_appcpu.dts b/boards/espressif/esp_wrover_kit/esp_wrover_kit_appcpu.dts index 154857f15e911..903f48f308e43 100644 --- a/boards/espressif/esp_wrover_kit/esp_wrover_kit_appcpu.dts +++ b/boards/espressif/esp_wrover_kit/esp_wrover_kit_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/espressif/esp_wrover_kit/esp_wrover_kit_appcpu_defconfig b/boards/espressif/esp_wrover_kit/esp_wrover_kit_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/espressif/esp_wrover_kit/esp_wrover_kit_appcpu_defconfig +++ b/boards/espressif/esp_wrover_kit/esp_wrover_kit_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.dts b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.dts index 3d37df9d5a7d9..614bd1ec54f54 100644 --- a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.dts +++ b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.dts @@ -7,7 +7,7 @@ #include #include "esp_wrover_kit-pinctrl.dtsi" -#include +#include / { model = "Espressif ESP32-Wrover-Kit PROCPU"; @@ -30,7 +30,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.yaml b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.yaml index d316dd1b8d029..88bcdc3289b18 100644 --- a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.yaml +++ b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu.yaml @@ -17,8 +17,4 @@ supported: - spi - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu_defconfig b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu_defconfig index f029cac9e9e77..e192c240251c1 100644 --- a/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu_defconfig +++ b/boards/espressif/esp_wrover_kit/esp_wrover_kit_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/ezurio/bl5340_dvk/Kconfig.defconfig b/boards/ezurio/bl5340_dvk/Kconfig.defconfig index b71b51265b916..2f93c265e0a2d 100644 --- a/boards/ezurio/bl5340_dvk/Kconfig.defconfig +++ b/boards/ezurio/bl5340_dvk/Kconfig.defconfig @@ -72,9 +72,6 @@ config BT_HCI_VS # https://www.buydisplay.com/2-8-inch-tft-touch-shield-for-arduino-w-capacitive-touch-screen-module if DISPLAY -config INPUT_FT5336_INTERRUPT - default y - if LVGL config LV_Z_VDB_SIZE diff --git a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml index cf432d7ab6e24..5237c073ffa43 100644 --- a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml index 89d29c79e055e..9bbf93a52d274 100644 --- a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 192 flash: 192 diff --git a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_partition_conf.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_partition_conf.dtsi index 2fc651230f454..b85e3d03dc2d7 100644 --- a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_partition_conf.dtsi +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_partition_conf.dtsi @@ -57,5 +57,5 @@ reg = <0x20040000 0x30000>; }; -/* Include default shared RAM configuration file */ -#include +/* Include shared RAM configuration file */ +#include "bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi" diff --git a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml index ab6f60bdd3ab5..99e7ee5a37e2b 100644 --- a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_common.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_common.dtsi index 1f5fc0bb3405a..ce2e145d58753 100644 --- a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_common.dtsi +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpunet_common.dtsi @@ -63,5 +63,5 @@ }; }; -/* Include default shared RAM configuration file */ -#include +/* Include shared RAM configuration file */ +#include "bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi" diff --git a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi new file mode 100644 index 0000000000000..fbb059494c36b --- /dev/null +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_shared_sram_planning_conf.dtsi @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019 Nordic Semiconductor ASA + * Copyright (c) 2021 Laird Connectivity + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Default shared SRAM planning when building for BL5340 DVK. + * This file is included by both nRF5340 CPUAPP (Application MCU) + * and nRF5340 CPUNET (Network MCU). + * - 64 kB SRAM allocated as Shared memory (sram0_shared) + * - Region defined after the image SRAM of Application MCU + */ + +/ { + chosen { + /* shared memory reserved for the inter-processor communication */ + zephyr,ipc_shm = &sram0_shared; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_shared: memory@20070000 { + /* SRAM allocated to shared memory */ + reg = <0x20070000 0x10000>; + }; + }; +}; diff --git a/boards/ezurio/bl652_dvk/bl652_dvk.yaml b/boards/ezurio/bl652_dvk/bl652_dvk.yaml index a549fcfdd6698..4e1a290436661 100644 --- a/boards/ezurio/bl652_dvk/bl652_dvk.yaml +++ b/boards/ezurio/bl652_dvk/bl652_dvk.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/ezurio/bl653_dvk/bl653_dvk.yaml b/boards/ezurio/bl653_dvk/bl653_dvk.yaml index ee1b610f312b9..24a17bc8c777b 100644 --- a/boards/ezurio/bl653_dvk/bl653_dvk.yaml +++ b/boards/ezurio/bl653_dvk/bl653_dvk.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/ezurio/bl654_dvk/bl654_dvk.yaml b/boards/ezurio/bl654_dvk/bl654_dvk.yaml index c4d016d63b699..c43d8f4328aa9 100644 --- a/boards/ezurio/bl654_dvk/bl654_dvk.yaml +++ b/boards/ezurio/bl654_dvk/bl654_dvk.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.yaml b/boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.yaml index 6ecf919159136..d38960a6eedbd 100644 --- a/boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.yaml +++ b/boards/ezurio/bl654_dvk/bl654_dvk_nrf52840_pa.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/ezurio/bl654_sensor_board/bl654_sensor_board.yaml b/boards/ezurio/bl654_sensor_board/bl654_sensor_board.yaml index bcaafe5669ac5..0dce5bbbe46cd 100644 --- a/boards/ezurio/bl654_sensor_board/bl654_sensor_board.yaml +++ b/boards/ezurio/bl654_sensor_board/bl654_sensor_board.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/ezurio/bl654_usb/Kconfig b/boards/ezurio/bl654_usb/Kconfig deleted file mode 100644 index c9779a44da9bb..0000000000000 --- a/boards/ezurio/bl654_usb/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -# BL654 USB adapter board configuration - -# Copyright (c) 2021 Laird Connectivity -# SPDX-License-Identifier: Apache-2.0 - -config BL654_USB_SERIAL_BACKEND_CDCACM - bool "Use CDC ACM UART as backend for BL654 USB adapter" - default y if !USB_DEVICE_BLUETOOTH - help - Use CDC ACM UART as backend for console or shell. diff --git a/boards/ezurio/bl654_usb/Kconfig.defconfig b/boards/ezurio/bl654_usb/Kconfig.defconfig index 83f7c2a968a8e..7b1a677095066 100644 --- a/boards/ezurio/bl654_usb/Kconfig.defconfig +++ b/boards/ezurio/bl654_usb/Kconfig.defconfig @@ -25,32 +25,6 @@ config FLASH_LOAD_SIZE default 0xdf000 depends on !USE_DT_CODE_PARTITION -config USB_CDC_ACM - default n if USB_DEVICE_BLUETOOTH - -if BL654_USB_SERIAL_BACKEND_CDCACM - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y if !MCUBOOT - -config SHELL_BACKEND_SERIAL_CHECK_DTR - default SHELL - depends on UART_LINE_CTRL - -config UART_LINE_CTRL - default SHELL - -# Logger cannot use itself to log -config USB_CDC_ACM_LOG_LEVEL - default 0 - -# Set USB log level to error only -config USB_DEVICE_LOG_LEVEL - default 1 - -endif #BL654_USB_SERIAL_BACKEND_CDCACM +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_BL654_USB diff --git a/boards/ezurio/bl654_usb/bl654_usb.dts b/boards/ezurio/bl654_usb/bl654_usb.dts index a6f81f64e616b..6ce352bda6d1b 100644 --- a/boards/ezurio/bl654_usb/bl654_usb.dts +++ b/boards/ezurio/bl654_usb/bl654_usb.dts @@ -16,9 +16,6 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,console = &bl654_cdc_acm_uart; - zephyr,shell-uart = &bl654_cdc_acm_uart; - zephyr,bt-c2h-uart = &bl654_cdc_acm_uart; zephyr,code-partition = &slot0_partition; zephyr,ieee802154 = &ieee802154; }; @@ -118,8 +115,6 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - bl654_cdc_acm_uart: bl654_cdc_acm_uart { - compatible = "zephyr,cdc-acm-uart"; - }; }; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/ezurio/bl654_usb/bl654_usb.yaml b/boards/ezurio/bl654_usb/bl654_usb.yaml index 4bf396760cc64..a56efa328770d 100644 --- a/boards/ezurio/bl654_usb/bl654_usb.yaml +++ b/boards/ezurio/bl654_usb/bl654_usb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - usb_device - ble diff --git a/boards/ezurio/bl654_usb/bl654_usb_defconfig b/boards/ezurio/bl654_usb/bl654_usb_defconfig index ba7d61d55be66..053eb9dafdbae 100644 --- a/boards/ezurio/bl654_usb/bl654_usb_defconfig +++ b/boards/ezurio/bl654_usb/bl654_usb_defconfig @@ -13,9 +13,6 @@ CONFIG_CONSOLE=y # Enable GPIO CONFIG_GPIO=y -# Enable USB -CONFIG_USB_DEVICE_STACK=y - # 32KHz clock source CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_150PPM=y diff --git a/boards/ezurio/bl654_usb/doc/bl654_usb.rst b/boards/ezurio/bl654_usb/doc/bl654_usb.rst index 345331890ec16..33bf2a554dda3 100644 --- a/boards/ezurio/bl654_usb/doc/bl654_usb.rst +++ b/boards/ezurio/bl654_usb/doc/bl654_usb.rst @@ -106,8 +106,10 @@ The board supports programming using the built-in bootloader. The board is factory-programmed with a Ezurio variation of Nordic's open bootloader from Nordic's nRF5x SDK. With this option, you'll use Nordic's `nrfutil`_ program to create firmware packages supported by this -bootloader and flash them to the device. Make sure ``nrfutil`` is installed -before proceeding. These instructions were tested with version 6.1.0. +bootloader and flash them to the device. Before proceeding, make sure: + +* ``nrfutil`` is installed. +* The ``nrf5sdk-tools`` command is installed within ``nrfutil``. #. With the adapter plugged in, reset the board into the bootloader by pressing the RESET button. @@ -132,16 +134,19 @@ before proceeding. These instructions were tested with version 6.1.0. .. code-block:: console - nrfutil pkg generate --hw-version 52 --sd-req=0x00 \ - --application build/zephyr/zephyr.hex \ - --application-version 1 blinky.zip + nrfutil nrf5sdk-tools pkg generate \ + --hw-version 52 \ + --sd-req=0x00 \ + --application build/zephyr/zephyr.hex \ + --application-version 1 \ + blinky.zip #. Flash it onto the board. Note :file:`/dev/ttyACM0` is for Linux; it will be something like ``COMx`` on Windows, and something else on macOS. .. code-block:: console - nrfutil dfu usb-serial -pkg blinky.zip -p /dev/ttyACM0 + nrfutil nrf5sdk-tools dfu usb-serial -pkg blinky.zip -p /dev/ttyACM0 When this command exits, observe the blue LED on the board blinking. diff --git a/boards/ezurio/bt510/bt510.yaml b/boards/ezurio/bt510/bt510.yaml index 198b538eecd44..f13cd759f4277 100644 --- a/boards/ezurio/bt510/bt510.yaml +++ b/boards/ezurio/bt510/bt510.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/ezurio/bt610/bt610.yaml b/boards/ezurio/bt610/bt610.yaml index 5b96d98c5275e..c56ec75873614 100644 --- a/boards/ezurio/bt610/bt610.yaml +++ b/boards/ezurio/bt610/bt610.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/ezurio/mg100/mg100.yaml b/boards/ezurio/mg100/mg100.yaml index 54de18e63ee29..bbfd5f81bc714 100644 --- a/boards/ezurio/mg100/mg100.yaml +++ b/boards/ezurio/mg100/mg100.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.yaml b/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.yaml index 3d44a009e2d06..5888bc4febc62 100644 --- a/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.yaml +++ b/boards/ezurio/pinnacle_100_dvk/pinnacle_100_dvk.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/fanke/fk750m1_vbt6/Kconfig.fk750m1_vbt6 b/boards/fanke/fk750m1_vbt6/Kconfig.fk750m1_vbt6 new file mode 100644 index 0000000000000..7c73267ab61d9 --- /dev/null +++ b/boards/fanke/fk750m1_vbt6/Kconfig.fk750m1_vbt6 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 zack jiang <1125934312@qq.com> +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FK750M1_VBT6 + select SOC_STM32H750XX diff --git a/boards/fanke/fk750m1_vbt6/board.cmake b/boards/fanke/fk750m1_vbt6/board.cmake new file mode 100644 index 0000000000000..3932958fd1db8 --- /dev/null +++ b/boards/fanke/fk750m1_vbt6/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +board_runner_args(jlink "--device=STM32H750VB" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/fanke/fk750m1_vbt6/board.yml b/boards/fanke/fk750m1_vbt6/board.yml new file mode 100644 index 0000000000000..2aae1f00b7366 --- /dev/null +++ b/boards/fanke/fk750m1_vbt6/board.yml @@ -0,0 +1,6 @@ +board: + name: fk750m1_vbt6 + full_name: FK750M1-VBT6 + vendor: fanke + socs: + - name: stm32h750xx diff --git a/boards/fanke/fk750m1_vbt6/doc/img/fk750m1_vbt6.webp b/boards/fanke/fk750m1_vbt6/doc/img/fk750m1_vbt6.webp new file mode 100644 index 0000000000000..cc86302e95ad8 Binary files /dev/null and b/boards/fanke/fk750m1_vbt6/doc/img/fk750m1_vbt6.webp differ diff --git a/boards/fanke/fk750m1_vbt6/doc/index.rst b/boards/fanke/fk750m1_vbt6/doc/index.rst new file mode 100644 index 0000000000000..6a558bddc0873 --- /dev/null +++ b/boards/fanke/fk750m1_vbt6/doc/index.rst @@ -0,0 +1,157 @@ +.. zephyr:board:: fk750m1_vbt6 + +Overview +******** + +The FK750M1-VBT6 core board by FANKE Technology Co., Ltd. is an advanced microcontroller +platform based on the STMicroelectronics ArmÂŽ CortexÂŽ-M7 core STM32H750VBT6 microcontroller. +This board is an ideal solution for developers looking to create high-performance +applications, leveraging its robust capabilities and support for sophisticated display +and image processing technologies. + +The FK750M1-VBT6 is designed as a reference design for user application development before +transitioning to the final product, significantly simplifying the development process. +Its wide range of hardware features, including advanced display and image processing capabilities, +allowing for comprehensive evaluation and testing of peripherals and functionalities. + +Hardware +******** + +FK750M1-VBT6 provides the following hardware components: + +- STM32H750VB in LQFP100 package +- ARM 32-bit Cortex-M7 CPU with FPU +- 480 MHz max CPU frequency +- 128 KB Flash +- 1 MB SRAM: 192 Kbytes TCM RAM (64 Kbytes ITCM RAM + 128 Kbytes DTCM RAM), 864 Kbytes user SRAM, and 4 Kbytes SRAM in Backup domain +- Main clock: External 25MHz crystal oscillator. +- RTC: 32.768kHz crystal oscillator. +- high-resolution timers(2.1 ns max resolution, 1) +- 32-bit timers(2) +- 16-bit timers(17) +- 1 reset button, and 1 BOOT button +- 1 user LED +- External 64-Mbit QSPI (W25Q64) NOR Flash memory. +- USB OTG Full Speed and High Speed(1) +- 1 micro SD card +- 1 DCMI camera interface +- 1 SPI LCD interface +- SWD and serial port accessibility through a pin header +- Bring out 73 IO ports + +More information about STM32H750VB can be found here: + +- `STM32H750VB on www.st.com`_ + +Supported Features +================== + +The Zephyr ``fk750m1_vbt6`` board target supports the following hardware +features: + ++-------------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++=============+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-------------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-------------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++-------------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-------------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-------------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-------------+------------+-------------------------------------+ +| Backup SRAM | on-chip | Backup SRAM | ++-------------+------------+-------------------------------------+ +| SPI | on-chip | spi bus | ++-------------+------------+-------------------------------------+ +| QUADSPI | on-chip | quadspi | ++-------------+------------+-------------------------------------+ + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration per core can be found in +:zephyr_file:`boards/fanke/fk750m1_vbt6/fk750m1_vbt6_defconfig` + +Pin Mapping +=========== + +FK750M1-VBT6 board has 5 GPIO controllers. These controllers are responsible for pin muxing, +input/output, pull-up, etc. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +The FK750M1-VBT6 board is configured as follows + +- UART_1 TX/RX : PA9/PA10 (available on the header pins) +- User LED (blue) : PC13 +- SPI4 NCS/CLK/MOSI : PE11/PE12/PE14 (SPI LCD) +- QuadSPI NCS/CLK/IO0/IO1/IO2/IO3 : PB6/PB2/PD11/PD12/PE2/PD13 (NOR Flash) +- USB DM/DP : PA11/PA12 + +System Clock +============ + +The FK750M1-VBT6 System Clock could be driven by an internal or external oscillator, +as well as by the main PLL clock. By default the system clock is driven by the PLL clock at 480MHz, +driven by an 25MHz external crystal oscillator. + +Serial Port +=========== + +The Zephyr console output is assigned to UART1. The default communication settings are 115200 8N1. + +Programming and Debugging +************************* + +Applications for the ``fk750m1_vbt6`` board target can be built and flashed in the usual +way (see :ref:`build_an_application` and :ref:`application_run` for more details). + +Flashing +======== + +The FK750M1-VBT6 board does not include an on-board debugger. As a result, it requires +an external debugger, such as ST-Link, for programming and debugging purposes. + +The board provides header pins for the Serial Wire Debug (SWD) interface. + +Flashing an application to FK750M1-VBT6 +--------------------------------------- + +To begin, connect the ST-Link Debug Programmer to the FK750M1-VBT6 board using the SWD +interface. Next, connect the ST-Link to your host computer via a USB port. +Once this setup is complete, you can proceed to build and flash your application to the board + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: fk750m1_vbt6 + :goals: build flash + +Run a serial host program to connect with your board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 -b 115200 + +Then, press the RESET button, you should see the following message: + +.. code-block:: console + + Hello World! fk750m1_vbt6 + +Debugging +========= + +This current Zephyr port does not support debugging. + +References +********** + +.. target-notes:: +.. _STM32H750VB on www.st.com: https://www.st.com/en/microcontrollers/stm32h750vb.html diff --git a/boards/fanke/fk750m1_vbt6/fk750m1_vbt6.dts b/boards/fanke/fk750m1_vbt6/fk750m1_vbt6.dts new file mode 100644 index 0000000000000..a3351b7e8646c --- /dev/null +++ b/boards/fanke/fk750m1_vbt6/fk750m1_vbt6.dts @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2024 zack jiang <1125934312@qq.com> + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include +#include + +/ { + model = "FANKE FK750M1-VBT6 board"; + compatible = "fanke,fk750m1-vbt6"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,display = &st7789v_240x240; + }; + + leds { + compatible = "gpio-leds"; + user_led: led_0 { + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + label = "User LED"; + }; + }; + + aliases { + led0 = &user_led; + }; + + mipi_dbi_st7789v_240x240 { + compatible = "zephyr,mipi-dbi-spi"; + spi-dev = <&spi4>; + dc-gpios = <&gpioe 15 GPIO_ACTIVE_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + + st7789v_240x240: st7789v@0 { + compatible = "sitronix,st7789v"; + mipi-max-frequency = <20000000>; + reg = <0>; + width = <240>; + height = <240>; + x-offset = <0>; + y-offset = <0>; + vcom = <0x19>; + gctrl = <0x35>; + vrhs = <0x12>; + vdvs = <0x20>; + mdac = <0x00>; + gamma = <0x01>; + colmod = <0x05>; + lcm = <0x2c>; + porch-param = [0c 0c 00 33 33]; + cmd2en-param = [5a 69 02 01]; + pwctrl1-param = [a4 a1]; + pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23]; + nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23]; + ram-param = [00 F0]; + rgb-param = [CD 08 14]; + mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; + }; + }; +}; + +&clk_hsi48 { + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + status = "okay"; +}; + +&pll { + div-m = <5>; + mul-n = <192>; + div-p = <2>; + div-q = <4>; + div-r = <4>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&pll3 { + div-m = <5>; + mul-n = <192>; + div-p = <2>; + div-q = <20>; + div-r = <99>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + d1cpre = <1>; + hpre = <2>; + d1ppre = <2>; + d2ppre1 = <2>; + d2ppre2 = <2>; + d3ppre = <2>; +}; + +&quadspi { + pinctrl-0 = <&quadspi_bk1_io0_pd11 &quadspi_bk1_io1_pd12 + &quadspi_bk1_io2_pe2 &quadspi_bk1_io3_pd13 + &quadspi_clk_pb2 &quadspi_bk1_ncs_pb6>; + pinctrl-names = "default"; + status = "okay"; + + /* Winbond external flash */ + w25q64_qspi: qspi-nor-flash@90000000 { + compatible = "st,stm32-qspi-nor"; + reg = <0x90000000 DT_SIZE_M(64)>; /* 64 Mbits */ + qspi-max-frequency = <40000000>; + status = "okay"; + spi-bus-width = <4>; + writeoc = "PP_1_1_4"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + storage_partition: partition@0 { + label = "storage"; + reg = <0x00000000 DT_SIZE_M(64)>; + }; + }; + }; +}; + +&spi4 { + pinctrl-0 = <&spi4_sck_pe12 &spi4_mosi_pe14>; + cs-gpios = <&gpioe 11 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + status = "okay"; +}; + +&gpiod { + status = "okay"; + + lcd_led { + gpio-hog; + gpios = <15 GPIO_ACTIVE_HIGH>; + output-high; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&backup_sram { + status = "okay"; +}; + +&rng { + status = "okay"; +}; diff --git a/boards/fanke/fk750m1_vbt6/fk750m1_vbt6.yaml b/boards/fanke/fk750m1_vbt6/fk750m1_vbt6.yaml new file mode 100644 index 0000000000000..e436cc6dc0a2f --- /dev/null +++ b/boards/fanke/fk750m1_vbt6/fk750m1_vbt6.yaml @@ -0,0 +1,13 @@ +identifier: fk750m1_vbt6 +name: FANKE FK750M1-VBT6 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 1024 +flash: 128 +supported: + - uart + - gpio +vendor: fanke diff --git a/boards/fanke/fk750m1_vbt6/fk750m1_vbt6_defconfig b/boards/fanke/fk750m1_vbt6/fk750m1_vbt6_defconfig new file mode 100644 index 0000000000000..527b26b55e688 --- /dev/null +++ b/boards/fanke/fk750m1_vbt6/fk750m1_vbt6_defconfig @@ -0,0 +1,18 @@ +# Copyright (c) zack jiang <1125934312@qq.com> +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable UART +CONFIG_SERIAL=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y diff --git a/boards/fanke/fk750m1_vbt6/support/openocd.cfg b/boards/fanke/fk750m1_vbt6/support/openocd.cfg new file mode 100644 index 0000000000000..1db2475768a98 --- /dev/null +++ b/boards/fanke/fk750m1_vbt6/support/openocd.cfg @@ -0,0 +1,25 @@ +# Copyright (c) zack jiang <1125934312@qq.com> +# SPDX-License-Identifier: Apache-2.0 + +source [find interface/stlink-dap.cfg] +transport select "dapdirect_swd" + +set WORKAREASIZE 0x8000 + +set CHIPNAME STM32H750VB +set BOARDNAME FK750M1-VBT6 + +source [find target/stm32h7x.cfg] + +# Enable debug when in low power modes +set ENABLE_LOW_POWER 1 + +# Stop Watchdog counters when halt +set STOP_WATCHDOG 1 + +# Reset configuration +# use hardware reset, connect under reset +# connect_assert_srst needed if low power mode application running (WFI...) +reset_config srst_only srst_nogate connect_assert_srst +set CONNECT_UNDER_RESET 1 +set CORE_RESET 0 diff --git a/boards/fanke/fk7b0m1_vbt6/fk7b0m1_vbt6.yaml b/boards/fanke/fk7b0m1_vbt6/fk7b0m1_vbt6.yaml index f847d49f4506b..6012823f29c5a 100644 --- a/boards/fanke/fk7b0m1_vbt6/fk7b0m1_vbt6.yaml +++ b/boards/fanke/fk7b0m1_vbt6/fk7b0m1_vbt6.yaml @@ -1,11 +1,10 @@ identifier: fk7b0m1_vbt6 -name: FANKE FK7B0M1-VBT6 board +name: FANKE FK7B0M1-VBT6 type: mcu arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 1376 flash: 128 supported: diff --git a/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho.dts b/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho.dts index beee6810d62be..2b182b569cbe7 100644 --- a/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho.dts +++ b/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho.dts @@ -22,7 +22,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho.yaml b/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho.yaml index 0a227dc60212f..da3da1bdc3ace 100644 --- a/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho.yaml +++ b/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho.yaml @@ -14,6 +14,4 @@ supported: testing: ignore_tags: - heap - - net - - bluetooth vendor: franzininho diff --git a/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho_defconfig b/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho_defconfig index f566acd934021..e192c240251c1 100644 --- a/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho_defconfig +++ b/boards/franzininho/esp32s2_franzininho/esp32s2_franzininho_defconfig @@ -1,9 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 - - -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/gaisler/generic_leon3/generic_leon3.yaml b/boards/gaisler/generic_leon3/generic_leon3.yaml index 621306904617d..206eedbabc9d3 100644 --- a/boards/gaisler/generic_leon3/generic_leon3.yaml +++ b/boards/gaisler/generic_leon3/generic_leon3.yaml @@ -9,7 +9,6 @@ ram: 4096 flash: 2048 toolchain: - zephyr - - xtools supported: - netif testing: diff --git a/boards/gaisler/gr716a_mini/gr716a_mini.yaml b/boards/gaisler/gr716a_mini/gr716a_mini.yaml index 4d2743602c670..8625d54c09547 100644 --- a/boards/gaisler/gr716a_mini/gr716a_mini.yaml +++ b/boards/gaisler/gr716a_mini/gr716a_mini.yaml @@ -7,7 +7,6 @@ simulation: arch: sparc toolchain: - zephyr - - xtools supported: - netif - spi diff --git a/boards/gardena/sgrm/doc/index.rst b/boards/gardena/sgrm/doc/index.rst index e50554dc2bf60..40d05a9f4f340 100644 --- a/boards/gardena/sgrm/doc/index.rst +++ b/boards/gardena/sgrm/doc/index.rst @@ -5,7 +5,7 @@ Overview This is a SoM that is used as a radio module by the GARDENA smart gateway (manual_, `FOSS parts`_). -.. _manual: https://www.gardena.com/tdrdownload//pub000070911/doc000120830 +.. _manual: https://content.tdr.dss.husqvarnagroup.net/pub000094159/doc000240276 .. _FOSS parts: https://github.com/husqvarnagroup/smart-garden-gateway-public Hardware diff --git a/boards/gardena/sgrm/sgrm.yaml b/boards/gardena/sgrm/sgrm.yaml index fe14fefec889a..9488fca96fc5a 100644 --- a/boards/gardena/sgrm/sgrm.yaml +++ b/boards/gardena/sgrm/sgrm.yaml @@ -10,7 +10,6 @@ ram: 32 flash: 256 toolchain: - gnuarmemb - - xtools - zephyr supported: - dma diff --git a/boards/gd/gd32a503v_eval/gd32a503v_eval.yaml b/boards/gd/gd32a503v_eval/gd32a503v_eval.yaml index e2e2145d9afb1..3182b92a191be 100644 --- a/boards/gd/gd32a503v_eval/gd32a503v_eval.yaml +++ b/boards/gd/gd32a503v_eval/gd32a503v_eval.yaml @@ -10,7 +10,6 @@ flash: 384 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - counter diff --git a/boards/gd/gd32e103v_eval/gd32e103v_eval.yaml b/boards/gd/gd32e103v_eval/gd32e103v_eval.yaml index a5dd9ba759b68..203ef2d95e9e0 100644 --- a/boards/gd/gd32e103v_eval/gd32e103v_eval.yaml +++ b/boards/gd/gd32e103v_eval/gd32e103v_eval.yaml @@ -10,7 +10,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools supported: - dac - counter diff --git a/boards/gd/gd32e507v_start/gd32e507v_start.yaml b/boards/gd/gd32e507v_start/gd32e507v_start.yaml index 8a1b4e4b89b9c..3e216953ec877 100644 --- a/boards/gd/gd32e507v_start/gd32e507v_start.yaml +++ b/boards/gd/gd32e507v_start/gd32e507v_start.yaml @@ -10,7 +10,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - pwm - gpio diff --git a/boards/gd/gd32e507z_eval/gd32e507z_eval.yaml b/boards/gd/gd32e507z_eval/gd32e507z_eval.yaml index 594df3a5f8d3e..f4174207b84b0 100644 --- a/boards/gd/gd32e507z_eval/gd32e507z_eval.yaml +++ b/boards/gd/gd32e507z_eval/gd32e507z_eval.yaml @@ -10,7 +10,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - pwm - gpio diff --git a/boards/gd/gd32f350r_eval/gd32f350r_eval.yaml b/boards/gd/gd32f350r_eval/gd32f350r_eval.yaml index 17834719ff1fd..1133959c2f47f 100644 --- a/boards/gd/gd32f350r_eval/gd32f350r_eval.yaml +++ b/boards/gd/gd32f350r_eval/gd32f350r_eval.yaml @@ -10,7 +10,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools supported: - watchdog - dma diff --git a/boards/gd/gd32f403z_eval/gd32f403z_eval.yaml b/boards/gd/gd32f403z_eval/gd32f403z_eval.yaml index 1bec175723ae8..675d101ad3176 100644 --- a/boards/gd/gd32f403z_eval/gd32f403z_eval.yaml +++ b/boards/gd/gd32f403z_eval/gd32f403z_eval.yaml @@ -10,7 +10,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - pwm diff --git a/boards/gd/gd32f407v_start/gd32f407v_start.yaml b/boards/gd/gd32f407v_start/gd32f407v_start.yaml index e79982ef6e870..418a6be76e1a2 100644 --- a/boards/gd/gd32f407v_start/gd32f407v_start.yaml +++ b/boards/gd/gd32f407v_start/gd32f407v_start.yaml @@ -10,7 +10,6 @@ flash: 3072 toolchain: - zephyr - gnuarmemb - - xtools supported: - pwm - gpio diff --git a/boards/gd/gd32f450i_eval/gd32f450i_eval.yaml b/boards/gd/gd32f450i_eval/gd32f450i_eval.yaml index 88ac1c0f55898..c4e95480151c3 100644 --- a/boards/gd/gd32f450i_eval/gd32f450i_eval.yaml +++ b/boards/gd/gd32f450i_eval/gd32f450i_eval.yaml @@ -10,7 +10,6 @@ flash: 3072 toolchain: - zephyr - gnuarmemb - - xtools supported: - dac - pwm diff --git a/boards/gd/gd32f450v_start/gd32f450v_start.yaml b/boards/gd/gd32f450v_start/gd32f450v_start.yaml index 62cf201bcd225..ede877bb1564b 100644 --- a/boards/gd/gd32f450v_start/gd32f450v_start.yaml +++ b/boards/gd/gd32f450v_start/gd32f450v_start.yaml @@ -10,7 +10,6 @@ flash: 3072 toolchain: - zephyr - gnuarmemb - - xtools supported: - pwm - gpio diff --git a/boards/gd/gd32f450z_eval/gd32f450z_eval.yaml b/boards/gd/gd32f450z_eval/gd32f450z_eval.yaml index 3cc5f3594953e..b5d60e8d905d0 100644 --- a/boards/gd/gd32f450z_eval/gd32f450z_eval.yaml +++ b/boards/gd/gd32f450z_eval/gd32f450z_eval.yaml @@ -10,7 +10,6 @@ flash: 3072 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - dac diff --git a/boards/gd/gd32f470i_eval/gd32f470i_eval.yaml b/boards/gd/gd32f470i_eval/gd32f470i_eval.yaml index 9537f9aef3015..ba01d16286981 100644 --- a/boards/gd/gd32f470i_eval/gd32f470i_eval.yaml +++ b/boards/gd/gd32f470i_eval/gd32f470i_eval.yaml @@ -10,7 +10,6 @@ flash: 3072 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - dac diff --git a/boards/gd/gd32l233r_eval/gd32l233r_eval.yaml b/boards/gd/gd32l233r_eval/gd32l233r_eval.yaml index 04e38f9e46c9e..99aacaea2f547 100644 --- a/boards/gd/gd32l233r_eval/gd32l233r_eval.yaml +++ b/boards/gd/gd32l233r_eval/gd32l233r_eval.yaml @@ -10,5 +10,4 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools vendor: gd diff --git a/boards/google/dragonclaw/google_dragonclaw.yaml b/boards/google/dragonclaw/google_dragonclaw.yaml index bf535af2c1e63..584bcbd29a44e 100644 --- a/boards/google/dragonclaw/google_dragonclaw.yaml +++ b/boards/google/dragonclaw/google_dragonclaw.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 vendor: google diff --git a/boards/google/icetower/Kconfig.google_icetower b/boards/google/icetower/Kconfig.google_icetower new file mode 100644 index 0000000000000..b6f143710cb52 --- /dev/null +++ b/boards/google/icetower/Kconfig.google_icetower @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_GOOGLE_ICETOWER + select SOC_STM32H743XX diff --git a/boards/google/icetower/board.cmake b/boards/google/icetower/board.cmake new file mode 100644 index 0000000000000..51e47b13107d9 --- /dev/null +++ b/boards/google/icetower/board.cmake @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +# keep first +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +board_runner_args(jlink "--device=STM32H743VI" "--speed=4000") +board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) + +# keep first +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/google/icetower/board.yml b/boards/google/icetower/board.yml new file mode 100644 index 0000000000000..beaafd5d4e1c4 --- /dev/null +++ b/boards/google/icetower/board.yml @@ -0,0 +1,6 @@ +board: + name: google_icetower + full_name: Icetower Development Board + vendor: google + socs: + - name: stm32h743xx diff --git a/boards/google/icetower/doc/index.rst b/boards/google/icetower/doc/index.rst new file mode 100644 index 0000000000000..45ecb81be2dcd --- /dev/null +++ b/boards/google/icetower/doc/index.rst @@ -0,0 +1,47 @@ +.. zephyr:board:: google_icetower + +Overview +******** + +Google Icetower Development Board is a board created by Google for +fingerprint-related functionality development. + +Board has connectors for fingerprint sensors. Console is exposed over `ÎźServo`_ +connector. MCU can be flashed using ÎźServo or SWD. + +Hardware +******** + +- STM32H7A3VIT6 LQFP100 package + +Pin Mapping +=========== + +Default Zephyr Peripheral Mapping: +---------------------------------- +- USART_1 TX/RX : PA9/PA10 +- SPI_1 CS/CLK/MISO/MOSI : PA4/PA5/PA6/PA7 +- SPI_4 CS/CLK/MISO/MOSI : PE11/PE12/PE13/PE14 + +Programming and Debugging +************************* + +Build application as usual for the ``google_icetower`` board, and flash +using ÎźServo or an external J-Link connected to J4. If ÎźServo is used, please +follow the `Chromium EC Flashing Documentation`_. + +Debugging +========= + +Use SWD with a J-Link or ST-Link. Remember that SW2 must be set to CORESIGHT. + +References +********** + +.. target-notes:: + +.. _Chromium EC Flashing Documentation: + https://chromium.googlesource.com/chromiumos/platform/ec#Flashing-via-the-servo-debug-board + +.. _ÎźServo: + https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/master/docs/servo_micro.md diff --git a/boards/google/icetower/google_icetower.dts b/boards/google/icetower/google_icetower.dts new file mode 100644 index 0000000000000..fa549c7bbe0fd --- /dev/null +++ b/boards/google/icetower/google_icetower.dts @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +/ { + model = "Google Icetower development board"; + compatible = "google,icetower-fpmcu"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; +}; + +&clk_lsi { + /* LSI clock frequency is 32kHz */ + status = "okay"; +}; + +&clk_hsi { + status = "okay"; + hsi-div = <1>; + clock-frequency = ; +}; + +&rcc { + clocks = <&clk_hsi>; + clock-frequency = ; + d1cpre = <1>; + hpre = <1>; + d1ppre = <1>; + d2ppre1 = <1>; + d2ppre2 = <1>; + d3ppre = <1>; +}; + +/* USART1: Servo UART (console) */ +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +/* SPI1: communication with the AP */ +&spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + status = "okay"; +}; + +/* SPI4: communication with the fingerprint sensor */ +&spi4 { + pinctrl-0 = <&spi4_nss_pe11 &spi4_sck_pe12 + &spi4_miso_pe13 &spi4_mosi_pe14>; + pinctrl-names = "default"; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB4 0x00010000>, + <&rcc STM32_SRC_LSI RTC_SEL(2)>; + status = "okay"; + + backup_regs { + status = "okay"; + }; +}; diff --git a/boards/google/icetower/google_icetower.yaml b/boards/google/icetower/google_icetower.yaml new file mode 100644 index 0000000000000..b867fb6484608 --- /dev/null +++ b/boards/google/icetower/google_icetower.yaml @@ -0,0 +1,18 @@ +identifier: google_icetower +name: Google Icetower Development Board +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 1024 +flash: 2048 +vendor: google +supported: + - counter + - dma + - gpio + - i2c + - spi + - pwm + - rtc diff --git a/boards/google/icetower/google_icetower_defconfig b/boards/google/icetower/google_icetower_defconfig new file mode 100644 index 0000000000000..705c23fe4b902 --- /dev/null +++ b/boards/google/icetower/google_icetower_defconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Google Inc +# SPDX-License-Identifier: Apache-2.0 + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# GPIO Controller +CONFIG_GPIO=y + +# Enable MPU and HW stack protection +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/google/quincy/Kconfig.google_quincy b/boards/google/quincy/Kconfig.google_quincy new file mode 100644 index 0000000000000..5bf9347a8602e --- /dev/null +++ b/boards/google/quincy/Kconfig.google_quincy @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_GOOGLE_QUINCY + select SOC_NPCX9MFP diff --git a/boards/google/quincy/board.cmake b/boards/google/quincy/board.cmake new file mode 100644 index 0000000000000..85a7ea7b5f143 --- /dev/null +++ b/boards/google/quincy/board.cmake @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=Cortex-M4" "--speed=4000") +board_runner_args(openocd --cmd-load "npcx_write_image") +board_runner_args(openocd --cmd-verify "npcx_verify_image") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/google/quincy/board.yml b/boards/google/quincy/board.yml new file mode 100644 index 0000000000000..e0774ca8b8617 --- /dev/null +++ b/boards/google/quincy/board.yml @@ -0,0 +1,6 @@ +board: + name: google_quincy + full_name: Quincy + vendor: google + socs: + - name: npcx9mfp diff --git a/boards/google/quincy/doc/index.rst b/boards/google/quincy/doc/index.rst new file mode 100644 index 0000000000000..12dc09329ca49 --- /dev/null +++ b/boards/google/quincy/doc/index.rst @@ -0,0 +1,47 @@ +.. zephyr:board:: google_quincy + +Overview +******** + +Google Quincy is a board created for fingerprint-related functionality +development. + +The board has connectors for fingerprint sensors. A UART Console is exposed +over ÎźServo and USB connectors. The MCU can be flashed using ÎźServo or SWD. + +Hardware +******** + +- NPCX99FPA0BX VFBGA144 package + +Peripheral Mapping +=================== + +- UART_1 (CONSOLE) TX/RX : GPIO65/GPIO64 +- UART_2 (PROG) TX/RX : GPIO86/GPIO75 +- SPI_0 (SHI) CS/CLK/MISO/MOSI : GPIO53/GPIO55/GPIO47/GPIO46 +- SPI_1 (SPIP) CS/CLK/MISO/MOSI : GPIOA6/GPIOA1/GPIO95/GPIOA3 +- SPI_2 (GP) CS/CLK/MISO/MOSI : GPIO30/GPIO25/GPIO24/GPIO31 + +Programming and Debugging +************************* + +Build application as usual for the ``google_quincy`` board target, and flash +using ÎźServo or an external J-Link connected to J4. If ÎźServo is used, please +follow the `Chromium EC Flashing Documentation`_ and +`Chromium Servo Micro Documentation`_. + +Debugging +========= + +Use SWD with a J-Link. + +References +********** + +.. target-notes:: + +.. _Chromium EC Flashing Documentation: + https://chromium.googlesource.com/chromiumos/platform/ec#Flashing-via-the-servo-debug-board +.. _Chromium Servo Micro Documentation: + https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/master/docs/servo_micro.md diff --git a/boards/google/quincy/google_quincy.dts b/boards/google/quincy/google_quincy.dts new file mode 100644 index 0000000000000..7067cd4cf3195 --- /dev/null +++ b/boards/google/quincy/google_quincy.dts @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +/ { + model = "Google Quincy development board"; + compatible = "google,quincy-fpmcu"; + + chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &int_flash; + }; + + aliases { + /* For watchdog sample */ + watchdog0 = &twd0; + }; +}; + +/* UART1: Servo UART (console) */ +&uart1 { + /* Use UART1_SL2 ie. PIN64.65 */ + pinctrl-0 = <&uart1_2_sin_gp64 + &uart1_2_sout_gp65>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +/* UART2: AP UART (Host Commands and MKBP) */ +&uart2 { + pinctrl-0 = <&uart2_sin_gp75 + &uart2_sout_gp86>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +/* SHI0: communication with the AP */ +&shi0 { + status = "okay"; + pinctrl-0 = <&shi_gp46_47_53_55>; + pinctrl-names = "default"; +}; + +/* SPIP0: communication with the fingerprint sensor */ +&spip0 { + pinctrl-0 = <&spip_sclk_mosi_miso_gp95_gpa1_gpa3_gpa5_sl + &spip_sclk_mosi_miso_gp95_gpa1_gpa3_gpa5_no_spip_inv>; + cs-gpios = <&gpioa 6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/google/quincy/google_quincy.yaml b/boards/google/quincy/google_quincy.yaml new file mode 100644 index 0000000000000..5ec04710dfe1f --- /dev/null +++ b/boards/google/quincy/google_quincy.yaml @@ -0,0 +1,19 @@ +identifier: google_quincy +name: Google Quincy Development Board +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 512 +flash: 1024 +vendor: google +supported: + - clock + - gpio + - i2c + - pm + - pwm + - spi + - uart + - watchdog diff --git a/boards/google/quincy/google_quincy_defconfig b/boards/google/quincy/google_quincy_defconfig new file mode 100644 index 0000000000000..0b5fcc5649f0c --- /dev/null +++ b/boards/google/quincy/google_quincy_defconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2024 Google Inc +# SPDX-License-Identifier: Apache-2.0 + +# General Kernel Options +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=15000000 + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# GPIO Controller +CONFIG_GPIO=y + +# Clock Controller +CONFIG_CLOCK_CONTROL=y + +# Enable MPU and HW stack protection +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/google/twinkie_v2/google_twinkie_v2.dts b/boards/google/twinkie_v2/google_twinkie_v2.dts index 08e8fbaf5d257..eaffe70edf4f1 100644 --- a/boards/google/twinkie_v2/google_twinkie_v2.dts +++ b/boards/google/twinkie_v2/google_twinkie_v2.dts @@ -101,7 +101,7 @@ &adc1_in18_pc5 /* CSA_CC2 */ >; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; diff --git a/boards/google/twinkie_v2/google_twinkie_v2.yaml b/boards/google/twinkie_v2/google_twinkie_v2.yaml index bc9028b4e9a16..5509e5f407942 100644 --- a/boards/google/twinkie_v2/google_twinkie_v2.yaml +++ b/boards/google/twinkie_v2/google_twinkie_v2.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 144 flash: 512 testing: diff --git a/boards/hardkernel/odroid_go/odroid_go-flash_partition_table.dtsi b/boards/hardkernel/odroid_go/odroid_go-flash_partition_table.dtsi deleted file mode 100644 index bd0a69298c893..0000000000000 --- a/boards/hardkernel/odroid_go/odroid_go-flash_partition_table.dtsi +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2024 Yannis Damigos - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&flash0 { - status = "okay"; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* Reserve 60kB for the bootloader */ - boot_partition: partition@1000 { - label = "mcuboot"; - reg = <0x00001000 0x0000F000>; - read-only; - }; - - /* Reserve 2048kB for the application in slot 0 */ - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x00010000 0x00200000>; - }; - - /* Reserve 2048kB for the application in slot 1 */ - slot1_partition: partition@210000 { - label = "image-1"; - reg = <0x00210000 0x00200000>; - }; - - /* Reserve the remaining 12224kB for the storage partition */ - storage_partition: partition@410000 { - label = "storage"; - reg = <0x00410000 0x00BF0000>; - }; - }; -}; diff --git a/boards/hardkernel/odroid_go/odroid_go_appcpu.dts b/boards/hardkernel/odroid_go/odroid_go_appcpu.dts index 656272a24e869..3fe5151c7cec6 100644 --- a/boards/hardkernel/odroid_go/odroid_go_appcpu.dts +++ b/boards/hardkernel/odroid_go/odroid_go_appcpu.dts @@ -6,16 +6,18 @@ /dts-v1/; #include -#include "odroid_go-flash_partition_table.dtsi" +#include / { model = "ODROID-GO Game Kit APPCPU"; compatible = "hardkernel,odroid_go", "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/hardkernel/odroid_go/odroid_go_appcpu_defconfig b/boards/hardkernel/odroid_go/odroid_go_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/hardkernel/odroid_go/odroid_go_appcpu_defconfig +++ b/boards/hardkernel/odroid_go/odroid_go_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/hardkernel/odroid_go/odroid_go_procpu.dts b/boards/hardkernel/odroid_go/odroid_go_procpu.dts index 4553b7e338bd0..386627ff3583b 100644 --- a/boards/hardkernel/odroid_go/odroid_go_procpu.dts +++ b/boards/hardkernel/odroid_go/odroid_go_procpu.dts @@ -7,7 +7,7 @@ #include #include "odroid_go-pinctrl.dtsi" -#include "odroid_go-flash_partition_table.dtsi" +#include #include / { @@ -15,7 +15,7 @@ compatible = "hardkernel,odroid_go", "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/hardkernel/odroid_go/odroid_go_procpu.yaml b/boards/hardkernel/odroid_go/odroid_go_procpu.yaml index f2eafb526763f..0f9df7d05e530 100644 --- a/boards/hardkernel/odroid_go/odroid_go_procpu.yaml +++ b/boards/hardkernel/odroid_go/odroid_go_procpu.yaml @@ -11,8 +11,4 @@ supported: - watchdog - uart - nvs -testing: - ignore_tags: - - net - - bluetooth vendor: hardkernel diff --git a/boards/hardkernel/odroid_go/odroid_go_procpu_defconfig b/boards/hardkernel/odroid_go/odroid_go_procpu_defconfig index 1a0608e1def7c..c59a51342aa8a 100644 --- a/boards/hardkernel/odroid_go/odroid_go_procpu_defconfig +++ b/boards/hardkernel/odroid_go/odroid_go_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_appcpu.dts b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_appcpu.dts index 3cbdd5e3f478d..0363d711293de 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_appcpu.dts +++ b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_appcpu_defconfig b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_appcpu_defconfig +++ b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.dts b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.dts index 323947247b54e..c641e773e0725 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.dts +++ b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.dts @@ -51,7 +51,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.yaml b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.yaml index d516f1e1c5c89..67ff09aa3d593 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.yaml +++ b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu.yaml @@ -10,8 +10,4 @@ supported: - watchdog - uart - nvs -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu_defconfig b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu_defconfig index f029cac9e9e77..e192c240251c1 100644 --- a/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu_defconfig +++ b/boards/heltec/heltec_wifi_lora32_v2/heltec_wifi_lora32_v2_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_appcpu.dts b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_appcpu.dts index 0a32e1d562b01..6a8ca48d962d1 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_appcpu.dts +++ b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_appcpu.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_appcpu_defconfig b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_appcpu_defconfig +++ b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.dts b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.dts index e955d2b0654e7..9e02e3db483cc 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.dts +++ b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.dts @@ -68,7 +68,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.yaml b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.yaml index 91221f8616b16..0ed96e577a164 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.yaml +++ b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu.yaml @@ -16,8 +16,4 @@ supported: - pwm - dma - lora -testing: - ignore_tags: - - net - - bluetooth vendor: heltec diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu_defconfig b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu_defconfig index 2dfe1853d5cc9..c698c60763687 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu_defconfig +++ b/boards/heltec/heltec_wireless_stick_lite_v3/heltec_wireless_stick_lite_v3_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CLOCK_CONTROL=y CONFIG_CONSOLE=y CONFIG_GPIO=y diff --git a/boards/holyiot/yj16019/holyiot_yj16019.yaml b/boards/holyiot/yj16019/holyiot_yj16019.yaml index 573af0e86d3b8..f60d7b319a3e3 100644 --- a/boards/holyiot/yj16019/holyiot_yj16019.yaml +++ b/boards/holyiot/yj16019/holyiot_yj16019.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - ble - pwm diff --git a/boards/infineon/cy8ckit_062s2_ai/Kconfig.cy8ckit_062s2_ai b/boards/infineon/cy8ckit_062s2_ai/Kconfig.cy8ckit_062s2_ai new file mode 100644 index 0000000000000..a063f196cecf9 --- /dev/null +++ b/boards/infineon/cy8ckit_062s2_ai/Kconfig.cy8ckit_062s2_ai @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Arrow Electronics. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CY8CKIT_062S2_AI + select SOC_CY8C624ABZI_S2D44 diff --git a/boards/infineon/cy8ckit_062s2_ai/board.cmake b/boards/infineon/cy8ckit_062s2_ai/board.cmake new file mode 100644 index 0000000000000..48e33964ca5f4 --- /dev/null +++ b/boards/infineon/cy8ckit_062s2_ai/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +# During gdb session, by default connect to CM4 core. +board_runner_args(openocd "--gdb-init=disconnect") +board_runner_args(openocd "--gdb-init=target extended-remote :3334") +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + +board_runner_args(pyocd "--target=cy8c6xxa") +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/infineon/cy8ckit_062s2_ai/board.yml b/boards/infineon/cy8ckit_062s2_ai/board.yml new file mode 100644 index 0000000000000..1bd554cd550eb --- /dev/null +++ b/boards/infineon/cy8ckit_062s2_ai/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Arrow Electronics. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: cy8ckit_062s2_ai + full_name: PSOC 6 AI Evaluation Kit + vendor: infineon + socs: + - name: cy8c624abzi_s2d44 diff --git a/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts b/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts new file mode 100644 index 0000000000000..c3c5b1ee8405d --- /dev/null +++ b/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2024 Arrow Electronics. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "CY8CKIT-062S2-AI PSOC 6 AI Evaluation Kit"; + compatible = "infineon,cy8ckit_062s2_ai", "cypress,PSOC6"; + + chosen { + zephyr,console = &uart5; + zephyr,shell-uart = &uart5; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + aliases { + led0 = &user_led0; + sw0 = &user_bt; + watchdog0 = &watchdog0; + }; + + leds { + compatible = "gpio-leds"; + user_led0: led_0 { + label = "LED_0"; + gpios = <&gpio_prt5 3 GPIO_ACTIVE_HIGH>; + }; + user_led1: led_1 { + label = "LED_1"; + gpios = <&gpio_prt5 4 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_bt: button_0 { + label = "SW_0"; + gpios = <&gpio_prt5 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; +}; + +&fll0 { + status = "okay"; + clock-frequency = <100000000>; +}; + +&clk_hf0 { + clock-div = <1>; + clocks = <&fll0>; +}; + +/* CM4 core clock = 100MHz + * &fll clock-frequency / &clk_hf0 clock-div / &clk_fast clock-div = 100MHz / 1 / 1 = 100MHz + */ +&clk_fast { + clock-div = <1>; +}; + +/* CM0+ core clock = 50MHz + * &fll clock-frequency / &clk_hf0 clock-div / &clk_slow clock-div = 100MHz / 1 / 2 = 50MHz + */ +&clk_slow { + clock-div = <2>; +}; + +/* PERI core clock = 100MHz + * &fll clock-frequency / &clk_hf0 clock-div / &clk_peri clock-div = 100MHz / 1 / 1 = 100MHz + */ +&clk_peri { + clock-div = <1>; +}; + +&gpio_prt5 { + status = "okay"; +}; + +&gpio_prt10 { + status = "okay"; +}; + +/* UART connected to KitProg3 */ +uart5: &scb5 { + compatible = "infineon,cat1-uart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&p5_1_scb5_uart_tx &p5_0_scb5_uart_rx>; + pinctrl-names = "default"; +}; + +uart1: &scb1 { + compatible = "infineon,cat1-uart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&p10_0_scb1_uart_rx &p10_1_scb1_uart_tx>; + pinctrl-names = "default"; +}; + +&p5_1_scb5_uart_tx { + drive-push-pull; +}; + +&p5_0_scb5_uart_rx { + input-enable; +}; + +&p10_1_scb1_uart_tx { + drive-push-pull; +}; + +&p10_0_scb1_uart_rx { + input-enable; +}; + +&watchdog0 { + status = "okay"; +}; diff --git a/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.yaml b/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.yaml new file mode 100644 index 0000000000000..eef9a3a23886a --- /dev/null +++ b/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.yaml @@ -0,0 +1,13 @@ +identifier: cy8ckit_062s2_ai +name: CY8CKIT-062S2-AI PSOC 6 AI Evaluation Kit +type: mcu +arch: arm +ram: 1024 +flash: 2048 +toolchain: + - zephyr +supported: + - gpio + - uart + - watchdog +vendor: infineon diff --git a/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai_defconfig b/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai_defconfig new file mode 100644 index 0000000000000..105fb484e2869 --- /dev/null +++ b/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai_defconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Arrow Electronics. +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable GPIO driver +CONFIG_GPIO=y + +# Enable clock controller +CONFIG_CLOCK_CONTROL=y + +# Add catcm0p sleep images for CM0 Devices +CONFIG_SOC_PSOC6_CM0P_IMAGE_SLEEP=y diff --git a/boards/infineon/cy8ckit_062s2_ai/doc/img/cy8ckit_062s2_ai.webp b/boards/infineon/cy8ckit_062s2_ai/doc/img/cy8ckit_062s2_ai.webp new file mode 100644 index 0000000000000..56075d2e88444 Binary files /dev/null and b/boards/infineon/cy8ckit_062s2_ai/doc/img/cy8ckit_062s2_ai.webp differ diff --git a/boards/infineon/cy8ckit_062s2_ai/doc/index.rst b/boards/infineon/cy8ckit_062s2_ai/doc/index.rst new file mode 100644 index 0000000000000..8395bcd98ce6c --- /dev/null +++ b/boards/infineon/cy8ckit_062s2_ai/doc/index.rst @@ -0,0 +1,182 @@ +.. zephyr:board:: cy8ckit_062s2_ai + +Overview +******** + +The PSOC 6 AI Evaluation Kit (CY8CKIT-062S2-AI) is a cost effective and small development kit that +enables design and debug of PSOC 6 MCUs. +It includes a CY8C624ABZI-S2D44 MCU which is based on a 150-MHz Arm |reg| Cortex |reg|-M4 and +a 100-MHz Arm |reg| Cortex |reg|-M0+, with 2048 KB of on-chip Flash, 1024 KB of SRAM, +a Quad-SPI external memory interface, built-in hardware and software security features, +rich analog, digital, and communication peripherals. + +The board features an AIROC |reg| CYW43439 Wi-Fi & Bluetooth |reg| combo device, +a 512 MB NOR flash, an onboard programmer/debugger (KitProg3), USB host and device features, +two user LEDs, and one push button. + +Hardware +******** + +For more information about the CY8C624ABZI-S2D44 MCU SoC and CY8CKIT-062S2-AI board: + +- `CY8C624ABZI-S2D44 MCU SoC Website`_ +- `CY8C624ABZI-S2D44 MCU Datasheet`_ +- `CY8CKIT-062S2-AI Website`_ +- `CY8CKIT-062S2-AI User Guide`_ +- `CY8CKIT-062S2-AI Schematics`_ + +Supported Features +================== + +The ``cy8ckit_062s2_ai/cy8c624abzi_s2d44`` board target supports the following hardware features: + ++-----------+------------+-----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=======================+ +| NVIC | on-chip | nested vectored | +| | | interrupt controller | ++-----------+------------+-----------------------+ +| SYSTICK | on-chip | system clock | ++-----------+------------+-----------------------+ +| GPIO | on-chip | GPIO | ++-----------+------------+-----------------------+ +| PINCTRL | on-chip | pin control | ++-----------+------------+-----------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-----------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-----------------------+ + + +The default configuration can be found in the defconfig and dts files: + + - :zephyr_file:`boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai_defconfig` + - :zephyr_file:`boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts` + +System Clock +============ + +The PCY8C624ABZI-S2D44 MCU SoC is configured to use the internal IMO+FLL as a source for +the system clock. CM0+ works at 50MHz, CM4 - at 100MHz. Other sources for the +system clock are provided in the SoC, depending on your system requirements. + + +Fetch Binary Blobs +****************** + +The CY8CKIT-062S2-AI board requires fetch binary files (e.g CM0+ prebuilt images). + +To fetch Binary Blobs: + +.. code-block:: console + + west blobs fetch hal_infineon + + +Build blinking led sample +************************* + +Here is an example for building the :zephyr:code-sample:`blinky` sample application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: cy8ckit_062s2_ai/cy8c624abzi_s2d44 + :goals: build + +Programming and Debugging +************************* + +The CY8CKIT-062S2-AI board includes an onboard programmer/debugger (`KitProg3`_) +to provide debugging, flash programming, and serial communication over USB. +Flash and debug commands use OpenOCD and require a custom Infineon OpenOCD version, +that supports KitProg3, to be installed. + + +Infineon OpenOCD Installation +============================= + +Both the full `ModusToolbox`_ and the `ModusToolbox Programming Tools`_ packages include Infineon OpenOCD. +Installing either of these packages will also install Infineon OpenOCD. +If neither package is installed, a minimal installation can be done by downloading the `Infineon OpenOCD`_ release +for your system and manually extract the files to a location of your choice. + +.. note:: + + Linux requires device access rights to be set up for KitProg3. + This is handled automatically by the ModusToolbox and ModusToolbox Programming Tools installations. + When doing a minimal installation, this can be done manually by executing the script + ``openocd/udev_rules/install_rules.sh``. + +West Commands +============= + +The path to the installed Infineon OpenOCD executable must be available to the ``west`` tool commands. +There are multiple ways of doing this. +The example below uses a permanent CMake argument to set the CMake variable ``OPENOCD``. + + .. tabs:: + .. group-tab:: Windows + + .. code-block:: shell + + # Run west config once to set permanent CMake argument + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd.exe + + # Do a pristine build once after setting CMake argument + west build -b cy8ckit_062s2_ai/cy8c624abzi_s2d44 -p always samples/basic/blinky + + west flash + west debug + + .. group-tab:: Linux + + .. code-block:: shell + + # Run west config once to set permanent CMake argument + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd + + # Do a pristine build once after setting CMake argument + west build -b cy8ckit_062s2_ai/cy8c624abzi_s2d44 -p always samples/basic/blinky + + west flash + west debug + +Alternatively, pyOCD can also be used to flash the board using +the ``--runner`` (or ``-r``) option: + +.. code-block:: console + + $ west flash --runner pyocd + +References +********** + +.. target-notes:: + +.. _CY8C624ABZI-S2D44 MCU SoC Website: + https://www.infineon.com/cms/en/product/microcontroller/32-bit-psoc-arm-cortex-microcontroller/psoc-6-32-bit-arm-cortex-m4-mcu/psoc-62/psoc-62x8-62xa/cy8c624abzi-s2d44/ + +.. _CY8C624ABZI-S2D44 MCU Datasheet: + https://www.infineon.com/dgdl/Infineon-PSOC_6_MCU_CY8C62X8_CY8C62XA-DataSheet-v16_00-EN.pdf?fileId=8ac78c8c7d0d8da4017d0ee7d03a70b1 + +.. _CY8CKIT-062S2-AI Website: + https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-062s2-ai/?redirId=273839 + +.. _CY8CKIT-062S2-AI User Guide: + https://www.infineon.com/dgdl/Infineon-CY8CKIT_062S2_AI_KIT_GUIDE-UserManual-v01_00-EN.pdf?fileId=8ac78c8c90530b3a01906d4608842668 + +.. _CY8CKIT-062S2-AI Schematics: + https://www.infineon.com/dgdl/Infineon-CY8CKIT-062S2-AI_PSoC_6_AI_Evaluation_Board_Schematic-PCBDesignData-v01_00-EN.pdf?fileId=8ac78c8c8eeb092c018f0af9e109106f + +.. _ModusToolbox: + https://softwaretools.infineon.com/tools/com.ifx.tb.tool.modustoolbox + +.. _ModusToolbox Programming Tools: + https://softwaretools.infineon.com/tools/com.ifx.tb.tool.modustoolboxprogtools + +.. _Infineon OpenOCD: + https://github.com/Infineon/openocd/releases/latest + +.. _KitProg3: + https://github.com/Infineon/KitProg3 diff --git a/boards/infineon/cy8ckit_062s2_ai/support/openocd.cfg b/boards/infineon/cy8ckit_062s2_ai/support/openocd.cfg new file mode 100644 index 0000000000000..5b123bd203f48 --- /dev/null +++ b/boards/infineon/cy8ckit_062s2_ai/support/openocd.cfg @@ -0,0 +1,12 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port + set INTERFACE "cmsis-dap" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +source [find target/psoc6_2m.cfg] diff --git a/boards/infineon/cy8ckit_062s4/cy8ckit_062s4_defconfig b/boards/infineon/cy8ckit_062s4/cy8ckit_062s4_defconfig index d0909391c4505..80182936a00b9 100644 --- a/boards/infineon/cy8ckit_062s4/cy8ckit_062s4_defconfig +++ b/boards/infineon/cy8ckit_062s4/cy8ckit_062s4_defconfig @@ -5,7 +5,6 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y -CONFIG_BUILD_OUTPUT_HEX=y CONFIG_CORTEX_M_SYSTICK=y CONFIG_XIP=y diff --git a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml index 5eb55d4de6d30..7d4185c860ec7 100644 --- a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml +++ b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml @@ -24,5 +24,6 @@ supported: - i2c - thermistor - uart + - dma - timer vendor: infineon diff --git a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig index 221643eca2791..54183d73c1ccb 100644 --- a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig +++ b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w_defconfig @@ -5,8 +5,6 @@ # General configuration CONFIG_CORTEX_M_SYSTICK=y -CONFIG_BUILD_OUTPUT_HEX=y - CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y @@ -22,6 +20,3 @@ CONFIG_GPIO=y # Enable clock controller CONFIG_CLOCK_CONTROL=y - -# Main Stack Size -CONFIG_MAIN_STACK_SIZE=2048 diff --git a/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble_defconfig b/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble_defconfig index 7d0d29ea39cc9..51c814073a308 100644 --- a/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble_defconfig +++ b/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble_defconfig @@ -6,8 +6,6 @@ # General configuration CONFIG_CORTEX_M_SYSTICK=y -CONFIG_BUILD_OUTPUT_HEX=y - CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y @@ -24,8 +22,5 @@ CONFIG_GPIO=y # Enable clock controller CONFIG_CLOCK_CONTROL=y -# Main Stack Size -CONFIG_MAIN_STACK_SIZE=2048 - # Add catcm0p sleep images for CM0 Devices CONFIG_SOC_PSOC6_CM0P_IMAGE_SLEEP=y diff --git a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dts b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dts index 927b1f865f4bd..92a748d2ee1b7 100644 --- a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dts +++ b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dts @@ -38,6 +38,16 @@ uart2: &scb2 { pinctrl-0 = <&p3_3_scb2_uart_tx &p3_2_scb2_uart_rx &p3_1_scb2_uart_rts &p3_0_scb2_uart_cts>; pinctrl-names = "default"; + + dmas = <&dma0 8>, <&dma0 9>; + dma-names = "tx", "rx"; +}; + +&dma0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "infineon,cat1-dma"; + status = "okay"; }; &fll0 { diff --git a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml index 9d83de725c0f9..3244d698080f8 100644 --- a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml +++ b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml @@ -17,6 +17,7 @@ supported: - uart - clock_control - bluetooth + - adc - watchdog - spi - i2c diff --git a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02_defconfig b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02_defconfig index e50b5462babe1..c59deaae71c2b 100644 --- a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02_defconfig +++ b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02_defconfig @@ -4,9 +4,6 @@ # # General configuration -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_BUILD_OUTPUT_BIN=y - CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y @@ -23,8 +20,5 @@ CONFIG_GPIO=y # Enable clock controller CONFIG_CLOCK_CONTROL=y -# Main Stack Size -CONFIG_MAIN_STACK_SIZE=2048 - # Enable code/data relocation to move SMIF driver into RAM CONFIG_CODE_DATA_RELOCATION=y diff --git a/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.yaml b/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.yaml index fde3084c862a8..7733dd224e0d2 100644 --- a/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.yaml +++ b/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - dma diff --git a/boards/innblue/innblue21/innblue21_nrf9160.yaml b/boards/innblue/innblue21/innblue21_nrf9160.yaml index 5722ebcd8c9e0..e19348bd0fd30 100644 --- a/boards/innblue/innblue21/innblue21_nrf9160.yaml +++ b/boards/innblue/innblue21/innblue21_nrf9160.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/innblue/innblue21/innblue21_nrf9160_ns.yaml b/boards/innblue/innblue21/innblue21_nrf9160_ns.yaml index 17faee49190ec..dd1cef9b328ad 100644 --- a/boards/innblue/innblue21/innblue21_nrf9160_ns.yaml +++ b/boards/innblue/innblue21/innblue21_nrf9160_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/innblue/innblue22/innblue22_nrf9160.yaml b/boards/innblue/innblue22/innblue22_nrf9160.yaml index 9bad5763319f6..2fc3a3cb3d3bc 100644 --- a/boards/innblue/innblue22/innblue22_nrf9160.yaml +++ b/boards/innblue/innblue22/innblue22_nrf9160.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/innblue/innblue22/innblue22_nrf9160_ns.yaml b/boards/innblue/innblue22/innblue22_nrf9160_ns.yaml index 4542d90bad038..d81920f42ed10 100644 --- a/boards/innblue/innblue22/innblue22_nrf9160_ns.yaml +++ b/boards/innblue/innblue22/innblue22_nrf9160_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/intel/ish/board.cmake b/boards/intel/ish/board.cmake index aa4b8ad48aec2..a6329d3856628 100644 --- a/boards/intel/ish/board.cmake +++ b/boards/intel/ish/board.cmake @@ -1,9 +1,8 @@ +# Copyright (c) 2023-2024 Intel Corporation +# # SPDX-License-Identifier: Apache-2.0 -set(SUPPORTED_EMU_PLATFORMS simics) - if(CONFIG_BOARD_INTEL_ISH_5_8_0) - board_emu_args(simics "project=$ENV{SIMICS_PROJECT}") board_emu_args(simics "zephyr_elf=${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME}") board_emu_args(simics "zephyr_start_address=${CONFIG_SRAM_BASE_ADDRESS}") include(${ZEPHYR_BASE}/boards/common/simics.board.cmake) diff --git a/boards/intel/ish/intel_ish_5_8_0.yaml b/boards/intel/ish/intel_ish_5_8_0.yaml index 5713ed69ff894..34037b7744917 100644 --- a/boards/intel/ish/intel_ish_5_8_0.yaml +++ b/boards/intel/ish/intel_ish_5_8_0.yaml @@ -11,6 +11,7 @@ simulation: supported: - serial testing: + timeout_multiplier: 2 ignore_tags: - net - bluetooth diff --git a/boards/intel/niosv_g/niosv_g.dts b/boards/intel/niosv_g/niosv_g.dts index 4ebd9c9721a92..cbaf19ec02d43 100644 --- a/boards/intel/niosv_g/niosv_g.dts +++ b/boards/intel/niosv_g/niosv_g.dts @@ -27,7 +27,7 @@ }; &mtimer { - reg = <0x90000 0x10>; + reg = <0x90000 0x8 0x90008 0x8>; }; &uart0 { diff --git a/boards/intel/niosv_m/niosv_m.dts b/boards/intel/niosv_m/niosv_m.dts index 495594f72dc35..e32edc3c7c22c 100644 --- a/boards/intel/niosv_m/niosv_m.dts +++ b/boards/intel/niosv_m/niosv_m.dts @@ -27,7 +27,7 @@ }; &mtimer { - reg = <0x90000 0x10>; + reg = <0x90000 0x8 0x90008 0x8>; }; &uart0 { diff --git a/boards/khadas/edge2/Kconfig.khadas_edge2 b/boards/khadas/edge2/Kconfig.khadas_edge2 new file mode 100644 index 0000000000000..58dd61dfe79d8 --- /dev/null +++ b/boards/khadas/edge2/Kconfig.khadas_edge2 @@ -0,0 +1,5 @@ +# Copyright 2024 UniversitĂŠ Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_KHADAS_EDGE2 + select SOC_RK3588S diff --git a/boards/khadas/edge2/board.yml b/boards/khadas/edge2/board.yml new file mode 100644 index 0000000000000..93138f3a2bbbc --- /dev/null +++ b/boards/khadas/edge2/board.yml @@ -0,0 +1,6 @@ +board: + name: khadas_edge2 + full_name: Edge2 + vendor: khadas + socs: + - name: rk3588s diff --git a/boards/khadas/edge2/doc/index.rst b/boards/khadas/edge2/doc/index.rst new file mode 100644 index 0000000000000..337ff3aa24e50 --- /dev/null +++ b/boards/khadas/edge2/doc/index.rst @@ -0,0 +1,97 @@ +.. zephyr:board:: khadas_edge2 + +Overview +******** + +See `Product page`_ + +.. _Product page: https://www.khadas.com/edge2 + +Hardware +******** + +See `Hardware details`_ + +.. _Hardware details: https://docs.khadas.com/products/sbc/edge2/hardware/start + +Supported Features +================== + +The ``khadas_edge2`` board target supports the following +hardware features: + ++-----------+------------+--------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================================+ +| GIC-600 | on-chip | GICv3 interrupt controller | ++-----------+------------+--------------------------------------+ +| ARM TIMER | on-chip | System Clock | ++-----------+------------+--------------------------------------+ +| UART | on-chip | Synopsys DesignWare 8250 serial port | ++-----------+------------+--------------------------------------+ + +Other hardware features have not been enabled yet for this board. + +The default configuration can be found in (NON-SMP) +:zephyr_file:`boards/khadas/edge2/khadas_edge2_defconfig` + +There are multiple serial ports on the board: Zephyr is using +uart2 as serial console. + +Programming and Debugging +************************* + +Use the following configuration to run basic Zephyr applications and +kernel tests on Khadas Edge2 board. For example, with the :zephyr:code-sample:`hello_world`: + +1. Non-SMP mode + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :host-os: unix + :board: khadas_edge2 + :goals: build + +This will build an image with the hello world sample app. + +Build the zephyr image: + +.. code-block:: console + + mkimage -C none -A arm64 -O linux -a 0x10000000 -e 0x10000000 -d build/zephyr/zephyr.bin build/zephyr/zephyr.img + +Burn the image on the board (we choose to use Rockchip burning tool `rkdeveloptool `_, you will need a `SPL `_ which is provided by khadas: + +.. code-block:: console + + rkdeveloptool db rk3588_spl_loader_*; rkdeveloptool wl 0x100000 zephyr.img; rkdeveloptool rd + +The sector 0x100000 was chosen arbitrarily (far away from U-Boot image) + +Use U-Boot to load and run Zephyr: + +.. code-block:: console + + mmc read ${pxefile_addr_r} 0x100000 0x1000; bootm start ${pxefile_addr_r}; bootm loados; bootm go + +0x1000 is the size (in number of sectors) or your image. Increase it if needed. + +It will display the following console output: + +.. code-block:: console + + *** Booting Zephyr OS build XXXXXXXXXXXX *** + Hello World! khadas_edge2 + +Flashing +======== + +Zephyr image can be loaded in DDR memory at address 0x10000000 from SD Card, +EMMC, QSPI Flash or downloaded from network in uboot. + +References +========== + +`Edge2 Documentation`_ + +.. _Edge2 Documentation: https://docs.khadas.com/products/sbc/edge2/start diff --git a/boards/khadas/edge2/doc/khadas_edge2.jpg b/boards/khadas/edge2/doc/khadas_edge2.jpg new file mode 100644 index 0000000000000..68278e72a98f5 Binary files /dev/null and b/boards/khadas/edge2/doc/khadas_edge2.jpg differ diff --git a/boards/khadas/edge2/khadas_edge2.dts b/boards/khadas/edge2/khadas_edge2.dts new file mode 100644 index 0000000000000..021015213b731 --- /dev/null +++ b/boards/khadas/edge2/khadas_edge2.dts @@ -0,0 +1,33 @@ +/* + * Copyright 2024 UniversitĂŠ Gustave Eiffel + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "Khadas Edge2"; + compatible = "khadas,edge2"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart2; + zephyr,shell-uart = &uart2; + }; + + cpus { + /delete-node/ cpu@1; + /delete-node/ cpu@2; + /delete-node/ cpu@3; + /delete-node/ cpu@4; + /delete-node/ cpu@5; + /delete-node/ cpu@6; + /delete-node/ cpu@7; + }; +}; + +&uart2 { + status = "okay"; +}; diff --git a/boards/khadas/edge2/khadas_edge2.yaml b/boards/khadas/edge2/khadas_edge2.yaml new file mode 100644 index 0000000000000..c9ed4ad11b23a --- /dev/null +++ b/boards/khadas/edge2/khadas_edge2.yaml @@ -0,0 +1,9 @@ +identifier: khadas_edge2 +name: Khadas Edge2 (single core, non SMP) +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +ram: 8192 +vendor: khadas diff --git a/boards/khadas/edge2/khadas_edge2_defconfig b/boards/khadas/edge2/khadas_edge2_defconfig new file mode 100644 index 0000000000000..38b7f52812f9f --- /dev/null +++ b/boards/khadas/edge2/khadas_edge2_defconfig @@ -0,0 +1,17 @@ +# Copyright 2024 UniversitĂŠ Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +# Platform Configuration +CONFIG_ARM64_VA_BITS_40=y +CONFIG_ARM64_PA_BITS_40=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=24000000 +CONFIG_CACHE_MANAGEMENT=y +CONFIG_ARMV8_A_NS=y + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_appcpu.dts b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_appcpu.dts index 4717ca7fa628b..d9747997ed0e8 100644 --- a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_appcpu.dts +++ b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_appcpu.dts @@ -6,15 +6,18 @@ /dts-v1/; #include +#include / { model = "Kincony KC868_A32 APPCPU"; compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; @@ -25,42 +28,3 @@ &trng0 { status = "okay"; }; - -&flash0 { - status = "okay"; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* Reserve 60kB for the bootloader */ - boot_partition: partition@1000 { - label = "mcuboot"; - reg = <0x00001000 0x0000F000>; - read-only; - }; - - /* Reserve 1024kB for the application in slot 0 */ - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x00010000 0x00100000>; - }; - - /* Reserve 1024kB for the application in slot 1 */ - slot1_partition: partition@110000 { - label = "image-1"; - reg = <0x00110000 0x00100000>; - }; - - /* Reserve 256kB for the scratch partition */ - scratch_partition: partition@210000 { - label = "image-scratch"; - reg = <0x00210000 0x00040000>; - }; - - storage_partition: partition@250000 { - label = "storage"; - reg = <0x00250000 0x00006000>; - }; - }; -}; diff --git a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_appcpu_defconfig b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_appcpu_defconfig +++ b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.dts b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.dts index be7da2765efaf..5e7e337e7d83e 100644 --- a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.dts +++ b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.dts @@ -18,7 +18,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.yaml b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.yaml index 325c3794c29da..89cfbb2e3fced 100644 --- a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.yaml +++ b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu.yaml @@ -12,8 +12,4 @@ supported: - nvs - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: kincony diff --git a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu_defconfig b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu_defconfig index 071024ac98dba..7ed3d6b89a219 100644 --- a/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu_defconfig +++ b/boards/kincony/kincony_kc868_a32/kincony_kc868_a32_procpu_defconfig @@ -1,8 +1,6 @@ # Copyright (c) Bartosz Bilas # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32-pinctrl.dtsi b/boards/lilygo/ttgo_lora32/ttgo_lora32-pinctrl.dtsi index eaa3e9b422b51..b8140e4451a62 100644 --- a/boards/lilygo/ttgo_lora32/ttgo_lora32-pinctrl.dtsi +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32-pinctrl.dtsi @@ -41,6 +41,7 @@ output-high; }; }; + sdhc0_default: sdhc0_default { group1 { pinmux = ; diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.dts b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.dts index 431572891342c..a4c5d93acfb4f 100644 --- a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.dts +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu_defconfig b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu_defconfig +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts index 060278b50dc90..6ae0dbeb0152e 100644 --- a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts @@ -24,7 +24,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.yaml b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.yaml index d16b056dd1166..e59818cc3dcbc 100644 --- a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.yaml +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.yaml @@ -15,8 +15,4 @@ supported: - lora - nvs - sdhc -testing: - ignore_tags: - - net - - bluetooth vendor: lilygo diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu_defconfig b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu_defconfig index e18641b5d445b..8dcf3d7e54bc5 100644 --- a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu_defconfig +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/lilygo/ttgo_t7v1_5/board.yml b/boards/lilygo/ttgo_t7v1_5/board.yml index 0a3f719864642..5912db5520cbf 100644 --- a/boards/lilygo/ttgo_t7v1_5/board.yml +++ b/boards/lilygo/ttgo_t7v1_5/board.yml @@ -1,5 +1,6 @@ board: name: ttgo_t7v1_5 + full_name: TTGO T7 Mini32 V1.5 vendor: lilygo socs: - name: esp32 diff --git a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_appcpu.dts b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_appcpu.dts index 15fe31598cf9b..d61269a1d5282 100644 --- a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_appcpu.dts +++ b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_appcpu_defconfig b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_appcpu_defconfig +++ b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu.dts b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu.dts index 4fab0e2ae7216..735ba0a8c52d7 100644 --- a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu.dts +++ b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu.dts @@ -22,7 +22,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu.yaml b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu.yaml index f4d0e25cc59d2..25d43a615024d 100644 --- a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu.yaml +++ b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu.yaml @@ -1,5 +1,5 @@ -identifier: ttgo_lora32/esp32/procpu -name: TTGO LoRa32 PROCPU +identifier: ttgo_t7v1_5/esp32/procpu +name: TTGO T7 V1.5 PROCPU type: mcu arch: xtensa toolchain: @@ -12,10 +12,5 @@ supported: - uart - pinmux - display - - lora - nvs -testing: - ignore_tags: - - net - - bluetooth vendor: lilygo diff --git a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu_defconfig b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu_defconfig index f029cac9e9e77..e192c240251c1 100644 --- a/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu_defconfig +++ b/boards/lilygo/ttgo_t7v1_5/ttgo_t7v1_5_esp32_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/lilygo/ttgo_t8c3/ttgo_t8c3.dts b/boards/lilygo/ttgo_t8c3/ttgo_t8c3.dts index 3e2b0ab74fa1b..896fdfc3bbf13 100644 --- a/boards/lilygo/ttgo_t8c3/ttgo_t8c3.dts +++ b/boards/lilygo/ttgo_t8c3/ttgo_t8c3.dts @@ -21,7 +21,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/lilygo/ttgo_t8c3/ttgo_t8c3.yaml b/boards/lilygo/ttgo_t8c3/ttgo_t8c3.yaml index e2fc320098a43..e0d0ce24a3dd8 100644 --- a/boards/lilygo/ttgo_t8c3/ttgo_t8c3.yaml +++ b/boards/lilygo/ttgo_t8c3/ttgo_t8c3.yaml @@ -11,8 +11,4 @@ supported: - uart - watchdog - can -testing: - ignore_tags: - - net - - bluetooth vendor: lilygo diff --git a/boards/lilygo/ttgo_t8c3/ttgo_t8c3_defconfig b/boards/lilygo/ttgo_t8c3/ttgo_t8c3_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/lilygo/ttgo_t8c3/ttgo_t8c3_defconfig +++ b/boards/lilygo/ttgo_t8c3/ttgo_t8c3_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/lilygo/ttgo_t8s3/ttgo_t8s3_appcpu_defconfig b/boards/lilygo/ttgo_t8s3/ttgo_t8s3_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/lilygo/ttgo_t8s3/ttgo_t8s3_appcpu_defconfig +++ b/boards/lilygo/ttgo_t8s3/ttgo_t8s3_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/lilygo/ttgo_t8s3/ttgo_t8s3_procpu.yaml b/boards/lilygo/ttgo_t8s3/ttgo_t8s3_procpu.yaml index 32ab521a903b1..cc1b652145aa0 100644 --- a/boards/lilygo/ttgo_t8s3/ttgo_t8s3_procpu.yaml +++ b/boards/lilygo/ttgo_t8s3/ttgo_t8s3_procpu.yaml @@ -18,8 +18,4 @@ supported: - dma - input - video -testing: - ignore_tags: - - net - - bluetooth vendor: lilygo diff --git a/boards/lilygo/ttgo_t8s3/ttgo_t8s3_procpu_defconfig b/boards/lilygo/ttgo_t8s3/ttgo_t8s3_procpu_defconfig index 723de34c47136..d8fbaa879257b 100644 --- a/boards/lilygo/ttgo_t8s3/ttgo_t8s3_procpu_defconfig +++ b/boards/lilygo/ttgo_t8s3/ttgo_t8s3_procpu_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dts b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dts index cfdfd771d13ec..5f6aadc9ce128 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dts +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.dts @@ -10,7 +10,7 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.yaml b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.yaml index 5baefb918a28d..5ba64d712ddb2 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.yaml +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core.yaml @@ -15,8 +15,4 @@ supported: - spi - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: luatos diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_defconfig b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_defconfig +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb.dts b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb.dts index f7e99f9b776fb..b029ef42ed417 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb.dts +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb.dts @@ -10,7 +10,7 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb.yaml b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb.yaml index 7910c6ac8eeda..ca0982c4111d9 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb.yaml +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb.yaml @@ -15,8 +15,4 @@ supported: - spi - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: luatos diff --git a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb_defconfig b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb_defconfig +++ b/boards/luatos/esp32c3_luatos_core/esp32c3_luatos_core_esp32c3_usb_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu.dts b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu.dts index 642949948cf6c..e302416886aea 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu.dts +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_defconfig b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_defconfig +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_usb.dts b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_usb.dts index a5dc8a0379236..eee5d310b6956 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_usb.dts +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_usb.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_usb_defconfig b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_usb_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_usb_defconfig +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_appcpu_usb_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.dts b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.dts index 2a04d5680668a..0b7973b8810e6 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.dts +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.dts @@ -21,7 +21,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.yaml b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.yaml index 6d564843a1c32..369a2fc7b63a6 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.yaml +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu.yaml @@ -15,8 +15,4 @@ supported: - entropy - pwm - dma -testing: - ignore_tags: - - net - - bluetooth vendor: luatos diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_defconfig b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_defconfig index d789bab1824a6..d8fbaa879257b 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_defconfig +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.dts b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.dts index a4182a4ba80ae..0d7d8c6ae8a03 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.dts +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.dts @@ -21,7 +21,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.yaml b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.yaml index 7e160d6811716..fe4e1ad61dd29 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.yaml +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb.yaml @@ -15,8 +15,4 @@ supported: - entropy - pwm - dma -testing: - ignore_tags: - - net - - bluetooth vendor: luatos diff --git a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb_defconfig b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb_defconfig index d789bab1824a6..d8fbaa879257b 100644 --- a/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb_defconfig +++ b/boards/luatos/esp32s3_luatos_core/esp32s3_luatos_core_procpu_usb_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_appcpu.dts b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_appcpu.dts index e9fee52699534..3262496f254fe 100644 --- a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_appcpu.dts +++ b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_appcpu_defconfig b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_appcpu_defconfig +++ b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.dts b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.dts index 884fdf949ccf2..012c2b1f8fe7e 100644 --- a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.dts +++ b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.dts @@ -20,7 +20,7 @@ compatible = "m5stack,m5stack-atom-lite"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.yaml b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.yaml index 14462ac58f829..04b3ef187161d 100644 --- a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.yaml +++ b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu.yaml @@ -12,8 +12,4 @@ supported: - uart - pinmux - nvs -testing: - ignore_tags: - - net - - bluetooth vendor: m5stack diff --git a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu_defconfig b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu_defconfig index 0ec9d053667b1..c3c35f0cfe929 100644 --- a/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu_defconfig +++ b/boards/m5stack/m5stack_atom_lite/m5stack_atom_lite_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_GPIO=y CONFIG_CONSOLE=y diff --git a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_appcpu.dts b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_appcpu.dts index 83eb4941fe8e6..2bc18ec2048b5 100644 --- a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_appcpu.dts +++ b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_appcpu.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_appcpu_defconfig b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_appcpu_defconfig +++ b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.dts b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.dts index cf12d00387d56..ed96340740748 100644 --- a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.dts +++ b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.dts @@ -17,7 +17,7 @@ compatible = "m5stack,atoms3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.yaml b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.yaml index 082aa4e569925..8fe5983e19c9b 100644 --- a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.yaml +++ b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu.yaml @@ -14,8 +14,4 @@ supported: - pinmux - nvs - display -testing: - ignore_tags: - - net - - bluetooth vendor: m5stack diff --git a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu_defconfig b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu_defconfig index 88c69e52e8c2e..60b1ee000fca1 100644 --- a/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu_defconfig +++ b/boards/m5stack/m5stack_atoms3/m5stack_atoms3_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_GPIO=y CONFIG_REGULATOR=y # for LCD backlight diff --git a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_appcpu.dts b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_appcpu.dts index 0842908542a06..0385c9e39a39d 100644 --- a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_appcpu.dts +++ b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_appcpu.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_appcpu_defconfig b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_appcpu_defconfig +++ b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.dts b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.dts index e224b50376222..c5884a846a156 100644 --- a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.dts +++ b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.dts @@ -18,7 +18,7 @@ compatible = "m5stack,atoms3_lite"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.yaml b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.yaml index 996732bc3dd00..34420d21d60e4 100644 --- a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.yaml +++ b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu.yaml @@ -16,8 +16,4 @@ supported: - pinmux - nvs - dma -testing: - ignore_tags: - - net - - bluetooth vendor: m5stack diff --git a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu_defconfig b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu_defconfig index d789bab1824a6..d8fbaa879257b 100644 --- a/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu_defconfig +++ b/boards/m5stack/m5stack_atoms3_lite/m5stack_atoms3_lite_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/m5stack/m5stack_core2/Kconfig.defconfig b/boards/m5stack/m5stack_core2/Kconfig.defconfig index 155a3c1d39c66..c90a78870ba0e 100644 --- a/boards/m5stack/m5stack_core2/Kconfig.defconfig +++ b/boards/m5stack/m5stack_core2/Kconfig.defconfig @@ -23,9 +23,6 @@ config GPIO_AXP192_INIT_PRIORITY config REGULATOR_FIXED_INIT_PRIORITY default 75 -config INPUT_FT5336_INTERRUPT - default y if INPUT - config INPUT default y diff --git a/boards/m5stack/m5stack_core2/m5stack_core2_appcpu.dts b/boards/m5stack/m5stack_core2/m5stack_core2_appcpu.dts index 3a50334db2143..4f7258310b72b 100644 --- a/boards/m5stack/m5stack_core2/m5stack_core2_appcpu.dts +++ b/boards/m5stack/m5stack_core2/m5stack_core2_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/m5stack/m5stack_core2/m5stack_core2_appcpu_defconfig b/boards/m5stack/m5stack_core2/m5stack_core2_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/m5stack/m5stack_core2/m5stack_core2_appcpu_defconfig +++ b/boards/m5stack/m5stack_core2/m5stack_core2_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts b/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts index 4ee67d3d5c001..554e1885488e2 100644 --- a/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts +++ b/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts @@ -28,7 +28,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_core2/m5stack_core2_procpu.yaml b/boards/m5stack/m5stack_core2/m5stack_core2_procpu.yaml index 5a95351e16df3..5e7edaca6febb 100644 --- a/boards/m5stack/m5stack_core2/m5stack_core2_procpu.yaml +++ b/boards/m5stack/m5stack_core2/m5stack_core2_procpu.yaml @@ -13,8 +13,4 @@ supported: - uart - pinmux - nvs -testing: - ignore_tags: - - net - - bluetooth vendor: m5stack diff --git a/boards/m5stack/m5stack_core2/m5stack_core2_procpu_defconfig b/boards/m5stack/m5stack_core2/m5stack_core2_procpu_defconfig index 008eb0afc9e3b..22e46419ab62b 100644 --- a/boards/m5stack/m5stack_core2/m5stack_core2_procpu_defconfig +++ b/boards/m5stack/m5stack_core2/m5stack_core2_procpu_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ESP_HEAP_MEM_POOL_REGION_1_SIZE=0 CONFIG_GPIO=y diff --git a/boards/m5stack/m5stack_cores3/Kconfig.defconfig b/boards/m5stack/m5stack_cores3/Kconfig.defconfig new file mode 100644 index 0000000000000..fe718f3cf4afd --- /dev/null +++ b/boards/m5stack/m5stack_cores3/Kconfig.defconfig @@ -0,0 +1,11 @@ +# M5Stack CoreS3 board defconfig + +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_M5STACK_CORES3_ESP32S3_PROCPU || BOARD_M5STACK_CORES3_ESP32S3_PROCPU_SE + +config INPUT + default y + +endif # BOARD_M5STACK_CORES3_ESP32S3_PROCPU || BOARD_M5STACK_CORES3_ESP32S3_PROCPU_SE diff --git a/boards/m5stack/m5stack_cores3/m5stack_cores3_appcpu.dts b/boards/m5stack/m5stack_cores3/m5stack_cores3_appcpu.dts index 1dac83cc46dea..ff04bc68817eb 100644 --- a/boards/m5stack/m5stack_cores3/m5stack_cores3_appcpu.dts +++ b/boards/m5stack/m5stack_cores3/m5stack_cores3_appcpu.dts @@ -14,7 +14,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_cores3/m5stack_cores3_appcpu_defconfig b/boards/m5stack/m5stack_cores3/m5stack_cores3_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/m5stack/m5stack_cores3/m5stack_cores3_appcpu_defconfig +++ b/boards/m5stack/m5stack_cores3/m5stack_cores3_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_common.dtsi b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_common.dtsi index 474da0931435a..1f0bf306dfca1 100644 --- a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_common.dtsi +++ b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_common.dtsi @@ -12,12 +12,14 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; + zephyr,rtc = &bm8563_rtc; zephyr,bt-hci = &esp32_bt_hci; + zephyr,touch = &ft6336_touch; }; aliases { @@ -27,6 +29,13 @@ i2c-0 = &i2c0; i2c-1 = &i2c1; watchdog0 = &wdt0; + rtc = &bm8563_rtc; + sdhc0 = &sd0; + }; + + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <&ft6336_touch>; }; }; @@ -68,6 +77,34 @@ clock-frequency = ; pinctrl-0 = <&i2c0_default>; pinctrl-names = "default"; + + bm8563_rtc: bm8563@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + status = "okay"; + }; + + aw9523b: aw9523b@58 { + compatible = "awinic,aw9523b"; + reg = <0x58>; + status = "okay"; + + aw9523b_gpio: gpio { + compatible = "awinic,aw9523b-gpio"; + gpio-controller; + #gpio-cells = <2>; + port0-push-pull; + int-gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; + }; + }; + + ft6336_touch: ft5336@38 { + status = "okay"; + compatible = "focaltech,ft5336"; + reg = <0x38>; + int-gpios = <&aw9523b_gpio 10 GPIO_ACTIVE_LOW>; + reset-gpios = <&aw9523b_gpio 0 GPIO_ACTIVE_LOW>; + }; }; &i2c1 { @@ -84,6 +121,22 @@ status = "okay"; pinctrl-0 = <&spim2_default>; pinctrl-names = "default"; + clock-frequency = <20000000>; + cs-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>, /* LCD */ + <&gpio0 4 GPIO_ACTIVE_LOW>; /* TF-CARD */ + + sd0: sd@1 { + compatible = "zephyr,sdhc-spi-slot"; + reg = <1>; + status = "okay"; + spi-max-frequency = <20000000>; + mmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; + + }; }; &twai { diff --git a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_defconfig b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_defconfig index 6539bd42e5947..187793c76e8cc 100644 --- a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_defconfig +++ b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_se_defconfig b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_se_defconfig index 6539bd42e5947..187793c76e8cc 100644 --- a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_se_defconfig +++ b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_se_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_appcpu.dts b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_appcpu.dts index 3600c76bde9c4..f6af6a54e4218 100644 --- a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_appcpu.dts +++ b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_appcpu.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_appcpu_defconfig b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_appcpu_defconfig +++ b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.dts b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.dts index 2abacdd87ed41..f2733a5719548 100644 --- a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.dts +++ b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.dts @@ -19,7 +19,7 @@ compatible = "m5stack,stamps3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.yaml b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.yaml index 746a5d2916e7c..762db7cbd7670 100644 --- a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.yaml +++ b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu.yaml @@ -13,8 +13,4 @@ supported: - pwm - pinmux - nvs -testing: - ignore_tags: - - net - - bluetooth vendor: m5stack diff --git a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu_defconfig b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu_defconfig index 466f9999601c4..68d1fe58d2e43 100644 --- a/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu_defconfig +++ b/boards/m5stack/m5stack_stamps3/m5stack_stamps3_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_GPIO=y CONFIG_CONSOLE=y diff --git a/boards/m5stack/m5stickc_plus/m5stickc_plus_appcpu.dts b/boards/m5stack/m5stickc_plus/m5stickc_plus_appcpu.dts index e514c55744071..23e942449c127 100644 --- a/boards/m5stack/m5stickc_plus/m5stickc_plus_appcpu.dts +++ b/boards/m5stack/m5stickc_plus/m5stickc_plus_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/m5stack/m5stickc_plus/m5stickc_plus_appcpu_defconfig b/boards/m5stack/m5stickc_plus/m5stickc_plus_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/m5stack/m5stickc_plus/m5stickc_plus_appcpu_defconfig +++ b/boards/m5stack/m5stickc_plus/m5stickc_plus_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.dts b/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.dts index 3575639697311..6b1a2dd8ba216 100644 --- a/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.dts +++ b/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.dts @@ -28,7 +28,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.yaml b/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.yaml index 69741a72d8f51..25fc452b8a973 100644 --- a/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.yaml +++ b/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu.yaml @@ -14,8 +14,4 @@ supported: - nvs - regulator - display -testing: - ignore_tags: - - net - - bluetooth vendor: m5stack diff --git a/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu_defconfig b/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu_defconfig index 6b210f481bc0d..35626ba6fea36 100644 --- a/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu_defconfig +++ b/boards/m5stack/m5stickc_plus/m5stickc_plus_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/m5stack/stamp_c3/stamp_c3.dts b/boards/m5stack/stamp_c3/stamp_c3.dts index e4b97e5865016..cbd3a3fdd92dd 100644 --- a/boards/m5stack/stamp_c3/stamp_c3.dts +++ b/boards/m5stack/stamp_c3/stamp_c3.dts @@ -16,7 +16,7 @@ compatible = "m5stack,stamp_c3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/m5stack/stamp_c3/stamp_c3.yaml b/boards/m5stack/stamp_c3/stamp_c3.yaml index d196fd357c604..4b272b9e8e739 100644 --- a/boards/m5stack/stamp_c3/stamp_c3.yaml +++ b/boards/m5stack/stamp_c3/stamp_c3.yaml @@ -10,8 +10,4 @@ supported: - spi - uart - watchdog -testing: - ignore_tags: - - net - - bluetooth vendor: m5stack diff --git a/boards/m5stack/stamp_c3/stamp_c3_defconfig b/boards/m5stack/stamp_c3/stamp_c3_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/m5stack/stamp_c3/stamp_c3_defconfig +++ b/boards/m5stack/stamp_c3/stamp_c3_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/madmachine/mm_feather/mm_feather.yaml b/boards/madmachine/mm_feather/mm_feather.yaml index a8af021d856cc..a4541bc88a837 100644 --- a/boards/madmachine/mm_feather/mm_feather.yaml +++ b/boards/madmachine/mm_feather/mm_feather.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 8192 supported: diff --git a/boards/madmachine/mm_swiftio/mm_swiftio.yaml b/boards/madmachine/mm_swiftio/mm_swiftio.yaml index cc27cbe254085..dbd5b79b7b63d 100644 --- a/boards/madmachine/mm_swiftio/mm_swiftio.yaml +++ b/boards/madmachine/mm_swiftio/mm_swiftio.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 8192 supported: diff --git a/boards/makerbase/mks_canable_v20/mks_canable_v20.dts b/boards/makerbase/mks_canable_v20/mks_canable_v20.dts index b619d8b900cfb..2f2e54565f926 100644 --- a/boards/makerbase/mks_canable_v20/mks_canable_v20.dts +++ b/boards/makerbase/mks_canable_v20/mks_canable_v20.dts @@ -81,7 +81,7 @@ zephyr_udc0: &usb { &fdcan1 { pinctrl-0 = <&fdcan1_rx_pb8 &fdcan1_tx_pb9>; pinctrl-names = "default"; - clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00001000>, + clocks = <&rcc STM32_CLOCK(APB1, 25U)>, <&rcc STM32_SRC_PLL_Q FDCAN_SEL(1)>; status = "okay"; }; diff --git a/boards/makerdiary/nrf52832_mdk/nrf52832_mdk.yaml b/boards/makerdiary/nrf52832_mdk/nrf52832_mdk.yaml index 68b42cf5afa27..3218983ff3802 100644 --- a/boards/makerdiary/nrf52832_mdk/nrf52832_mdk.yaml +++ b/boards/makerdiary/nrf52832_mdk/nrf52832_mdk.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/makerdiary/nrf52840_mdk/nrf52840_mdk.yaml b/boards/makerdiary/nrf52840_mdk/nrf52840_mdk.yaml index c3be56dacaa3f..79d62b2bf329c 100644 --- a/boards/makerdiary/nrf52840_mdk/nrf52840_mdk.yaml +++ b/boards/makerdiary/nrf52840_mdk/nrf52840_mdk.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - usb_device - ble diff --git a/boards/makerdiary/nrf52840_mdk_usb_dongle/Kconfig.defconfig b/boards/makerdiary/nrf52840_mdk_usb_dongle/Kconfig.defconfig index ae93b1ed6df36..5c7419ff43c5a 100644 --- a/boards/makerdiary/nrf52840_mdk_usb_dongle/Kconfig.defconfig +++ b/boards/makerdiary/nrf52840_mdk_usb_dongle/Kconfig.defconfig @@ -23,12 +23,6 @@ config FLASH_LOAD_OFFSET default 0x1000 depends on BOARD_HAS_NRF5_BOOTLOADER && !USE_DT_CODE_PARTITION -if USB_DEVICE_STACK - -# Enable UART driver, needed for CDC ACM -config SERIAL - default y - -endif # USB_DEVICE_STACK +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_NRF52840_MDK_USB_DONGLE diff --git a/boards/makerdiary/nrf52840_mdk_usb_dongle/doc/index.rst b/boards/makerdiary/nrf52840_mdk_usb_dongle/doc/index.rst index ac4743c77488c..83b5621bee84b 100644 --- a/boards/makerdiary/nrf52840_mdk_usb_dongle/doc/index.rst +++ b/boards/makerdiary/nrf52840_mdk_usb_dongle/doc/index.rst @@ -3,24 +3,40 @@ Overview ******** -The nRF52840 MDK USB Dongle is a small and low-cost development platform enabled -by the nRF5240 multiprotocol SoC in a convenient USB dongle form factor. +The nRF52840 MDK USB Dongle is a small and low-cost development platform +enabled by the nRF52840 multiprotocol SoC in a convenient USB dongle +form factor. -The design features a programmable user button, RGB LED, up to 12 GPIOs and 2.4G -Chip antenna on board. It can be used as a low-cost -Bluetooth5/Tread/802.15.4/ANT/2.4GHz multiprotocol node or development -board. Alternatively the USB Dongle can be used as a Network Co-Processor(NCP) -with a simple connection to a PC or other USB enabled device. +Hardware +******** + +The design features: + +* Programmable user button +* RGB LED +* Up to 12 GPIOs +* 2.4 GHz chip antenna -See `nrf52840-mdk-usb-dongle website`_ for more information about the development -board and `nRF52840 website`_ for the official reference on the IC itself. +The USB Dongle can be used as: +* A low-cost Bluetooth 5/Thread/802.15.4/ANT/2.4GHz multiprotocol node +* A development board +* A Network Co-Processor (NCP) with a simple connection to a PC or other USB enabled device + +For more information: + +* See the `nrf52840-mdk-usb-dongle website`_ for details about the development board +* See the `nRF52840 website`_ for the official reference on the IC itself +* See the `nrf52840-mdk-usb-dongle pinout diagram`_ for details about the pin usage of the board References ********** + .. target-notes:: .. _nRF52840 website: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52840 .. _nrf52840-mdk-usb-dongle website: https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/ +.. _nrf52840-mdk-usb-dongle pinout diagram: + https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/assets/attachments/nrf52840-mdk-usb-dongle-pinout_v1_1.pdf diff --git a/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts b/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts index 763aebe86e79c..0c9dd6b449651 100644 --- a/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts +++ b/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.dts @@ -16,11 +16,6 @@ compatible = "nrf52840_mdk_usb_dongle"; chosen { - zephyr,console = &uart0; - zephyr,shell-uart = &uart0; - zephyr,uart-mcumgr = &uart0; - zephyr,bt-mon-uart = &uart0; - zephyr,bt-c2h-uart = &uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; @@ -128,3 +123,5 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; }; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml b/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml index e714e1cafb5ee..f0fa9668e557f 100644 --- a/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml +++ b/boards/makerdiary/nrf52840_mdk_usb_dongle/nrf52840_mdk_usb_dongle.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - usb_device - ble diff --git a/boards/mediatek/mt8186/afe-mt8186.dts b/boards/mediatek/mt8186/afe-mt8186.dts new file mode 100644 index 0000000000000..c4d16826b81d4 --- /dev/null +++ b/boards/mediatek/mt8186/afe-mt8186.dts @@ -0,0 +1,54 @@ + afe_dl1: afe_dl1 { + compatible = "mediatek,afe"; + afe_name = "DL1"; + dai_id = <0>; + downlink; + base = <0x11210050 0x11210054>; + cur = <0x11210058 0x1121005c>; + end = <0x11210060 0x11210064>; + fs = <0x1121004c 24 4>; + mono = <0x1121004c 8 1>; + enable = <0x11210010 4 1>; + hd = <0x1121004c 0 1>; + }; + + afe_dl2: afe_dl2 { + compatible = "mediatek,afe"; + afe_name = "DL2"; + dai_id = <1>; + downlink; + base = <0x1121006c 0x11210070>; + cur = <0x11210074 0x11210078>; + end = <0x1121007c 0x11210080>; + fs = <0x11210068 24 4>; + mono = <0x11210068 8 1>; + enable = <0x11210010 5 1>; + hd = <0x11210068 0 1>; + }; + + afe_ul1: afe_ul1 { + compatible = "mediatek,afe"; + afe_name = "UL1"; + dai_id = <2>; + base = <0x11210378 0x1121037c>; + cur = <0x11210380 0x11210384>; + end = <0x11210388 0x1121038c>; + fs = <0x11210374 24 4>; + mono = <0x11210374 8 1>; + quad_ch = <0x11210374 11 1>; + enable = <0x11210010 31 1>; + hd = <0x11210374 0 1>; + }; + + afe_ul2: afe_ul2 { + compatible = "mediatek,afe"; + afe_name = "UL2"; + dai_id = <3>; + base = <0x11210860 0x11210864>; + cur = <0x11210868 0x1121086c>; + end = <0x11210870 0x11210874>; + fs = <0x1121085c 24 4>; + mono = <0x1121085c 8 1>; + enable = <0x11210010 16 1>; + hd = <0x1121085c 0 1>; + }; diff --git a/boards/mediatek/mt8186/mt8186_adsp.dts b/boards/mediatek/mt8186/mt8186_adsp.dts index a04aac1ffbf75..23f637cff4b69 100644 --- a/boards/mediatek/mt8186/mt8186_adsp.dts +++ b/boards/mediatek/mt8186/mt8186_adsp.dts @@ -37,12 +37,12 @@ #interrupt-cells = <3>; }; - intc2: intc@10680010 { + intc2: intc@10680050 { compatible = "mediatek,adsp_intc"; interrupt-controller; #interrupt-cells = <3>; - reg = <0x10680010 4>; - status-reg = <0x10680050>; + reg = <0x10680050 4>; + status-reg = <0x10680010>; interrupts = <2 0 0>; mask = <0x3f>; interrupt-parent = <&core_intc>; diff --git a/boards/mediatek/mt8188/afe-mt8188.dts b/boards/mediatek/mt8188/afe-mt8188.dts new file mode 100644 index 0000000000000..41daf54f62c79 --- /dev/null +++ b/boards/mediatek/mt8188/afe-mt8188.dts @@ -0,0 +1,67 @@ + afe_dl2: afe_dl2 { + compatible = "mediatek,afe"; + afe_name = "DL2"; + dai_id = <0>; + downlink; + base = <0x00000000 0x10b11250>; + cur = <0x00000000 0x10b11254>; + end = <0x00000000 0x10b11258>; + fs = <0x10b115a0 10 5>; + enable = <0x10b11200 18 1>; + hd = <0x10b1125c 5 1>; + msb = <0x10b1192c 18 1>; + msb2 = <0x10b11930 18 1>; + agent_disable = <0x10b10014 18 1>; + ch_num = <0x10b1125c 0 5>; + }; + + afe_dl3: afe_dl3 { + compatible = "mediatek,afe"; + afe_name = "DL3"; + dai_id = <1>; + downlink; + base = <0x00000000 0x10b11260>; + cur = <0x00000000 0x10b11264>; + end = <0x00000000 0x10b11268>; + fs = <0x10b115a0 15 5>; + enable = <0x10b11200 19 1>; + hd = <0x10b1126c 5 1>; + msb = <0x10b1192c 19 1>; + msb2 = <0x10b11930 19 1>; + agent_disable = <0x10b10014 19 1>; + ch_num = <0x10b1126c 0 5>; + }; + + afe_ul4: afe_ul4 { + compatible = "mediatek,afe"; + afe_name = "UL4"; + dai_id = <2>; + base = <0x00000000 0x10b11330>; + cur = <0x00000000 0x10b11334>; + end = <0x00000000 0x10b11338>; + fs = <0x10b115a8 15 5>; + mono = <0x10b1133c 1 1>; + int_odd = <0x10b1133c 0 1>; + enable = <0x10b11200 4 1>; + hd = <0x10b1133c 5 1>; + msb = <0x10b1192c 3 1>; + msb2 = <0x10b11930 3 1>; + agent_disable = <0x10b10014 3 1>; + }; + + afe_ul5: afe_ul5 { + compatible = "mediatek,afe"; + afe_name = "UL5"; + dai_id = <3>; + base = <0x00000000 0x10b11340>; + cur = <0x00000000 0x10b11344>; + end = <0x00000000 0x10b11348>; + fs = <0x10b115a8 20 5>; + mono = <0x10b1134c 1 1>; + int_odd = <0x10b1134c 0 1>; + enable = <0x10b11200 5 1>; + hd = <0x10b1134c 5 1>; + msb = <0x10b1192c 4 1>; + msb2 = <0x10b11930 4 1>; + agent_disable = <0x10b10014 4 1>; + }; diff --git a/boards/mediatek/mt8188/mt8188_adsp.dts b/boards/mediatek/mt8188/mt8188_adsp.dts index 1796bb7f44785..5f676bf115857 100644 --- a/boards/mediatek/mt8188/mt8188_adsp.dts +++ b/boards/mediatek/mt8188/mt8188_adsp.dts @@ -38,12 +38,12 @@ #interrupt-cells = <3>; }; - intc2: intc@10b80010 { + intc2: intc@10b80050 { compatible = "mediatek,adsp_intc"; interrupt-controller; #interrupt-cells = <3>; - reg = <0x10b80010 4>; - status-reg = <0x10b80050>; + reg = <0x10b80050 4>; + status-reg = <0x10b80010>; interrupts = <2 0 0>; mask = <0x3f>; interrupt-parent = <&core_intc>; diff --git a/boards/mediatek/mt8195/afe-mt8195.dts b/boards/mediatek/mt8195/afe-mt8195.dts new file mode 100644 index 0000000000000..f51f1a783e362 --- /dev/null +++ b/boards/mediatek/mt8195/afe-mt8195.dts @@ -0,0 +1,65 @@ + afe_dl2: afe_dl2 { + compatible = "mediatek,afe"; + afe_name = "DL2"; + dai_id = <0>; + downlink; + base = <0x00000000 0x10891250>; + cur = <0x00000000 0x10891254>; + end = <0x00000000 0x10891258>; + fs = <0x108915a0 10 5>; + enable = <0x10891200 18 1>; + hd = <0x1089125c 5 1>; + msb = <0x1089192c 18 1>; + msb2 = <0x10891930 18 1>; + agent_disable = <0x10890014 18 1>; + ch_num = <0x1089125c 0 5>; + }; + + afe_dl3: afe_dl3 { + compatible = "mediatek,afe"; + afe_name = "DL3"; + dai_id = <1>; + downlink; + base = <0x00000000 0x10891260>; + cur = <0x00000000 0x10891264>; + end = <0x00000000 0x10891268>; + fs = <0x108915a0 15 5>; + enable = <0x10891200 19 1>; + hd = <0x1089126c 5 1>; + msb = <0x1089192c 19 1>; + msb2 = <0x10891930 19 1>; + agent_disable = <0x10890014 19 1>; + ch_num = <0x1089126c 0 5>; + }; + + afe_ul4: afe_ul4 { + compatible = "mediatek,afe"; + afe_name = "UL4"; + dai_id = <2>; + base = <0x00000000 0x10891330>; + cur = <0x00000000 0x10891334>; + end = <0x00000000 0x10891338>; + fs = <0x108915a8 15 5>; + mono = <0x1089133c 1 1>; + enable = <0x10891200 4 1>; + hd = <0x1089133c 5 1>; + msb = <0x1089192c 3 1>; + msb2 = <0x10891930 3 1>; + agent_disable = <0x10890014 3 1>; + }; + + afe_ul5: afe_ul5 { + compatible = "mediatek,afe"; + afe_name = "UL5"; + dai_id = <3>; + base = <0x00000000 0x10891340>; + cur = <0x00000000 0x10891344>; + end = <0x00000000 0x10891348>; + fs = <0x108915a8 20 5>; + mono = <0x1089134c 1 1>; + enable = <0x10891200 5 1>; + hd = <0x1089134c 5 1>; + msb = <0x1089192c 4 1>; + msb2 = <0x10891930 4 1>; + agent_disable = <0x10890014 4 1>; + }; diff --git a/boards/mediatek/mt8195/mt8195_adsp.dts b/boards/mediatek/mt8195/mt8195_adsp.dts index a21d81693fa39..533467460413f 100644 --- a/boards/mediatek/mt8195/mt8195_adsp.dts +++ b/boards/mediatek/mt8195/mt8195_adsp.dts @@ -18,7 +18,13 @@ dram0: memory@60000000 { device_type = "memory"; compatible = "mmio-sram"; - reg = <0x60000000 DT_SIZE_M(17)>; + reg = <0x60000000 DT_SIZE_K(13824)>; + }; + + dram1: memory@60e80000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x60e80000 DT_SIZE_K(2560)>; }; soc { @@ -28,9 +34,9 @@ cpuclk: cpuclk@10000000 { compatible = "mediatek,mt8195_cpuclk"; reg = <0x10000000 380>; - cg_reg = <0x10720180>; - pll_ctrl_reg = <0x1000c7e0>; - freqs_mhz = <26 370 540 720>; + cg-reg = <0x10720180>; + pll-ctrl-reg = <0x1000c7e0>; + freqs-mhz = <26 370 540 720>; }; core_intc: core_intc@0 { diff --git a/boards/mediatek/mt8196/afe-mt8196.dts b/boards/mediatek/mt8196/afe-mt8196.dts new file mode 100644 index 0000000000000..fba314a61e37d --- /dev/null +++ b/boards/mediatek/mt8196/afe-mt8196.dts @@ -0,0 +1,66 @@ + afe_dl1: afe_dl1 { + compatible = "mediatek,afe"; + afe_name = "DL1"; + dai_id = <1>; + downlink; + base = <0x1a114470 0x1a114474>; + cur = <0x1a114478 0x1a11447c>; + end = <0x1a114480 0x1a114484>; + fs = <0x1a114490 8 5>; + mono = <0x1a114490 4 1>; + enable = <0x1a114490 28 1>; + hd = <0x1a114490 0 1>; + }; + + afe_dl_24ch: afe_dl_24ch { + compatible = "mediatek,afe"; + afe_name = "DL_24CH"; + dai_id = <0>; + downlink; + base = <0x1a114620 0x1a114624>; + cur = <0x1a114628 0x1a11462c>; + end = <0x1a114630 0x1a114634>; + fs = <0x1a114640 8 5>; + enable = <0x1a114640 31 1>; + hd = <0x1a114640 0 1>; + ch_num = <0x1a114640 24 6>; + }; + + afe_ul0: afe_ul0 { + compatible = "mediatek,afe"; + afe_name = "UL0"; + dai_id = <2>; + base = <0x1a114d60 0x1a114d64>; + cur = <0x1a114d68 0x1a114d6c>; + end = <0x1a114d70 0x1a114d74>; + fs = <0x1a114d80 8 5>; + mono = <0x1a114d80 4 1>; + enable = <0x1a114d80 28 1>; + hd = <0x1a114d80 0 1>; + }; + + afe_ul1: afe_ul1 { + compatible = "mediatek,afe"; + afe_name = "UL1"; + dai_id = <3>; + base = <0x1a114d90 0x1a114d94>; + cur = <0x1a114d98 0x1a114d9c>; + end = <0x1a114da0 0x1a114da4>; + fs = <0x1a114db0 8 5>; + mono = <0x1a114db0 4 1>; + enable = <0x1a114db0 28 1>; + hd = <0x1a114db0 0 1>; + }; + + afe_ul2: afe_ul2 { + compatible = "mediatek,afe"; + afe_name = "UL2"; + dai_id = <4>; + base = <0x1a114dc0 0x1a114dc4>; + cur = <0x1a114dc8 0x1a114dcc>; + end = <0x1a114dd0 0x1a114dd4>; + fs = <0x1a114de0 8 5>; + mono = <0x1a114de0 4 1>; + enable = <0x1a114de0 28 1>; + hd = <0x1a114de0 0 1>; + }; diff --git a/boards/mediatek/mt8196/mt8196_adsp.dts b/boards/mediatek/mt8196/mt8196_adsp.dts index ea3bfdf4f98a2..f8bee05bbe427 100644 --- a/boards/mediatek/mt8196/mt8196_adsp.dts +++ b/boards/mediatek/mt8196/mt8196_adsp.dts @@ -21,10 +21,10 @@ reg = <0x90000000 DT_SIZE_M(6)>; }; - dram1: memory@90700000 { + dram1: memory@90800000 { device_type = "memory"; compatible = "mmio-sram"; - reg = <0x90700000 DT_SIZE_M(1)>; + reg = <0x90800000 DT_SIZE_M(1)>; }; soc { @@ -88,19 +88,23 @@ interrupts = <8 0 0>; }; - mbox0: mbox@1a360100 { + mbox0: mbox@1a350100 { compatible = "mediatek,mbox"; - reg = <0x1a360100 16>; + reg = <0x1a350100 16>; interrupt-parent = <&intc_g2>; interrupts = <6 0 0>; }; - mbox1: mbox@1a370100 { + mbox1: mbox@1a360100 { compatible = "mediatek,mbox"; - reg = <0x1a370100 16>; + reg = <0x1a360100 16>; interrupt-parent = <&intc_g2>; interrupts = <7 0 0>; }; + +/* Generated code for AFE devices */ +#include "afe-mt8196.dts" + }; /* soc */ chosen { }; diff --git a/boards/microchip/ev11l78a/ev11l78a.yaml b/boards/microchip/ev11l78a/ev11l78a.yaml index f9b2a1a53a2ed..88417ca90d951 100644 --- a/boards/microchip/ev11l78a/ev11l78a.yaml +++ b/boards/microchip/ev11l78a/ev11l78a.yaml @@ -7,7 +7,6 @@ flash: 64 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - gpio diff --git a/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts b/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts index 856069de406c9..c259a7a44cdcf 100644 --- a/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts +++ b/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts @@ -52,7 +52,7 @@ &i2c_smb_0 { status = "okay"; - port_sel = <0>; + port-sel = <0>; sda-gpios = ; scl-gpios = ; pinctrl-0 = < &i2c00_scl_gpio004 &i2c00_sda_gpio003 >; @@ -61,7 +61,7 @@ &i2c_smb_1 { status = "okay"; - port_sel = <1>; + port-sel = <1>; sda-gpios = ; scl-gpios = ; pinctrl-0 = < &i2c01_scl_gpio131 &i2c01_sda_gpio130 >; diff --git a/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts b/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts index 11daa0efbe373..161536c867def 100644 --- a/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts +++ b/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts @@ -80,7 +80,7 @@ &i2c_smb_0 { status = "okay"; - port_sel = <0>; + port-sel = <0>; sda-gpios = ; scl-gpios = ; pinctrl-0 = < &i2c00_scl_gpio004 &i2c00_sda_gpio003 >; @@ -89,7 +89,7 @@ &i2c_smb_1 { status = "okay"; - port_sel = <1>; + port-sel = <1>; sda-gpios = ; scl-gpios = ; pinctrl-0 = < &i2c01_scl_gpio131 &i2c01_sda_gpio130 >; @@ -114,7 +114,7 @@ &i2c_smb_2 { status = "okay"; - port_sel = <7>; + port-sel = <7>; sda-gpios = ; scl-gpios = ; pinctrl-0 = < &i2c07_scl_gpio013 &i2c07_sda_gpio012 >; diff --git a/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts b/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts index c0427d03d3ded..076e84eda6002 100644 --- a/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts +++ b/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts @@ -125,7 +125,7 @@ /* I2C */ &i2c_smb_0 { status = "okay"; - port_sel = <0>; + port-sel = <0>; pinctrl-0 = < &i2c00_scl_gpio004 &i2c00_sda_gpio003 >; pinctrl-names = "default"; @@ -145,7 +145,7 @@ &i2c_smb_1 { status = "okay"; - port_sel = <1>; + port-sel = <1>; pinctrl-0 = <&i2c01_scl_gpio131 &i2c01_sda_gpio130>; pinctrl-names = "default"; @@ -180,7 +180,7 @@ &i2c_smb_2 { status = "okay"; - port_sel = <7>; + port-sel = <7>; pinctrl-0 = <&i2c07_scl_gpio013 &i2c07_sda_gpio012>; pinctrl-names = "default"; }; diff --git a/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts b/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts index 94a08cd03f165..24d600dd04043 100644 --- a/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts +++ b/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts @@ -119,7 +119,7 @@ /* I2C */ &i2c_smb_0 { status = "okay"; - port_sel = <0>; + port-sel = <0>; pinctrl-0 = < &i2c00_scl_gpio004 &i2c00_sda_gpio003 >; pinctrl-names = "default"; @@ -139,7 +139,7 @@ &i2c_smb_1 { status = "okay"; - port_sel = <1>; + port-sel = <1>; pinctrl-0 = <&i2c01_scl_gpio131 &i2c01_sda_gpio130>; pinctrl-names = "default"; }; @@ -158,7 +158,7 @@ &i2c_smb_2 { status = "okay"; - port_sel = <7>; + port-sel = <7>; pinctrl-0 = <&i2c07_scl_gpio013 &i2c07_sda_gpio012>; pinctrl-names = "default"; }; diff --git a/boards/mikroe/clicker_2/mikroe_clicker_2.dts b/boards/mikroe/clicker_2/mikroe_clicker_2.dts index 74ec6b395bb4a..aba4652f126d9 100644 --- a/boards/mikroe/clicker_2/mikroe_clicker_2.dts +++ b/boards/mikroe/clicker_2/mikroe_clicker_2.dts @@ -146,7 +146,7 @@ zephyr_udc0: &usbotg_fs { status ="okay"; pinctrl-0 = <&adc1_in2_pa2 &adc1_in3_pa3>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; }; diff --git a/boards/mikroe/clicker_2/mikroe_clicker_2.yaml b/boards/mikroe/clicker_2/mikroe_clicker_2.yaml index b69a800360b93..1f7b0fe4f8281 100644 --- a/boards/mikroe/clicker_2/mikroe_clicker_2.yaml +++ b/boards/mikroe/clicker_2/mikroe_clicker_2.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 1024 supported: diff --git a/boards/mikroe/clicker_ra4m1/mikroe_clicker_ra4m1.dts b/boards/mikroe/clicker_ra4m1/mikroe_clicker_ra4m1.dts index cd71c38f14c02..5a626a783648d 100644 --- a/boards/mikroe/clicker_ra4m1/mikroe_clicker_ra4m1.dts +++ b/boards/mikroe/clicker_ra4m1/mikroe_clicker_ra4m1.dts @@ -42,6 +42,29 @@ }; }; + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &ioport0 0 0>, /* AN */ + <1 0 &ioport4 7 0>, /* RST */ + <2 0 &ioport1 3 0>, /* CS */ + <3 0 &ioport1 2 0>, /* SCK */ + <4 0 &ioport1 0 0>, /* MISO */ + <5 0 &ioport1 1 0>, /* MOSI */ + /* +3.3V */ + /* GND */ + <6 0 &ioport1 7 0>, /* PWM */ + <7 0 &ioport3 2 0>, /* INT */ + <8 0 &ioport4 10 0>, /* RX */ + <9 0 &ioport4 11 0>, /* TX */ + <10 0 &ioport2 5 0>, /* SCL */ + <11 0 &ioport2 6 0>; /* SDA */ + /* +5V */ + /* GND */ + }; + aliases { led0 = &ld1; led1 = &ld2; @@ -72,6 +95,18 @@ }; }; +&ioport0 { + status = "okay"; +}; + +&ioport1 { + status = "okay"; +}; + +&ioport2 { + status = "okay"; +}; + &ioport3 { status = "okay"; }; diff --git a/boards/mikroe/clicker_ra4m1/mikroe_clicker_ra4m1.yaml b/boards/mikroe/clicker_ra4m1/mikroe_clicker_ra4m1.yaml index 9cc16dc9c8df9..04a7c550fed34 100644 --- a/boards/mikroe/clicker_ra4m1/mikroe_clicker_ra4m1.yaml +++ b/boards/mikroe/clicker_ra4m1/mikroe_clicker_ra4m1.yaml @@ -6,7 +6,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 256 supported: diff --git a/boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml b/boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml index e83b864f1ab59..1ea71f99223be 100644 --- a/boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml +++ b/boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/mikroe/stm32_m4_clicker/Kconfig.defconfig b/boards/mikroe/stm32_m4_clicker/Kconfig.defconfig index 082d099f4b8e5..6caedb91cfcdc 100644 --- a/boards/mikroe/stm32_m4_clicker/Kconfig.defconfig +++ b/boards/mikroe/stm32_m4_clicker/Kconfig.defconfig @@ -3,22 +3,6 @@ if BOARD_MIKROE_STM32_M4_CLICKER -if USB_DEVICE_STACK - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y - -endif # USB_DEVICE_STACK - -if LOG - -# Logger cannot use itself to log -config USB_CDC_ACM_LOG_LEVEL - default 0 - -endif # LOG +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_MIKROE_STM32_M4_CLICKER diff --git a/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.dts b/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.dts index 648f0da08f1ef..b6225a2579fdd 100644 --- a/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.dts +++ b/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.dts @@ -14,8 +14,6 @@ compatible = "st,stm32f415rg"; chosen { - zephyr,console = &usb_cdc_acm_uart; - zephyr,shell-uart = &usb_cdc_acm_uart; zephyr,sram = &sram0; zephyr,flash = &flash0; }; @@ -126,12 +124,10 @@ zephyr_udc0: &usbotg_fs { pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; pinctrl-names = "default"; status = "okay"; - - usb_cdc_acm_uart: cdc_acm_uart { - compatible = "zephyr,cdc-acm-uart"; - }; }; +#include <../boards/common/usb/cdc_acm_serial.dtsi> + mikrobus_spi: &spi2 {}; mikrobus_serial: &usart3 {}; mikrobus_i2c: &i2c2 {}; diff --git a/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml b/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml index 96d16aa2d63d8..361df15777756 100644 --- a/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml +++ b/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker_defconfig b/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker_defconfig index f964f048f7711..549aff1e682df 100644 --- a/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker_defconfig +++ b/boards/mikroe/stm32_m4_clicker/mikroe_stm32_m4_clicker_defconfig @@ -16,6 +16,3 @@ CONFIG_GPIO=y # Enable Clocks CONFIG_CLOCK_CONTROL=y - -# Enable USB -CONFIG_USB_DEVICE_STACK=y diff --git a/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.yaml b/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.yaml index bcb0ab9aa2976..e67ec4da93079 100644 --- a/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.yaml +++ b/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - pwm diff --git a/boards/native/native_posix/irq_handler.c b/boards/native/native_posix/irq_handler.c index 69a1f131dcbf2..206bf319d4ad5 100644 --- a/boards/native/native_posix/irq_handler.c +++ b/boards/native/native_posix/irq_handler.c @@ -105,7 +105,7 @@ void posix_irq_handler(void) */ if (may_swap && (hw_irq_ctrl_get_cur_prio() == 256) - && (_kernel.ready_q.cache) && (_kernel.ready_q.cache != arch_current_thread())) { + && (_kernel.ready_q.cache) && (_kernel.ready_q.cache != _current)) { (void)z_swap_irqlock(irq_lock); } @@ -248,6 +248,11 @@ void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), */ void posix_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { + if (irq >= N_IRQS) { + posix_print_error_and_exit("Attempted to configure not existent interrupt %u\n", + irq); + return; + } hw_irq_ctrl_prio_set(irq, prio); } diff --git a/boards/native/native_sim/Kconfig.defconfig b/boards/native/native_sim/Kconfig.defconfig index 03f3811302f1c..c74a9fe041e34 100644 --- a/boards/native/native_sim/Kconfig.defconfig +++ b/boards/native/native_sim/Kconfig.defconfig @@ -32,14 +32,4 @@ config UART_CONSOLE endif # CONSOLE -# BT relies on PSA Crypto API to perform crypto operations. On this platform -# this is implemented by Mbed TLS which requires a (possibly true) random -# number generator to initialize properly. We enable ENTROPY_GENERATOR here -# instead of manually adding it to all samples/tests configuration files because -# it looks more compact and easier to maintain. -config ENTROPY_GENERATOR - bool - default y if BT - - endif # BOARD_NATIVE_SIM diff --git a/boards/native/native_sim/irq_handler.c b/boards/native/native_sim/irq_handler.c index c9a18f018639b..6eb250f8450bb 100644 --- a/boards/native/native_sim/irq_handler.c +++ b/boards/native/native_sim/irq_handler.c @@ -113,7 +113,7 @@ void posix_irq_handler(void) */ if (may_swap && (hw_irq_ctrl_get_cur_prio() == 256) - && (_kernel.ready_q.cache) && (_kernel.ready_q.cache != arch_current_thread())) { + && (_kernel.ready_q.cache) && (_kernel.ready_q.cache != _current)) { (void)z_swap_irqlock(irq_lock); } @@ -256,6 +256,11 @@ void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), */ void posix_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { + if (irq >= N_IRQS) { + posix_print_error_and_exit("Attempted to configure not existent interrupt %u\n", + irq); + return; + } hw_irq_ctrl_prio_set(irq, prio); } diff --git a/boards/native/nrf_bsim/Kconfig.defconfig b/boards/native/nrf_bsim/Kconfig.defconfig index ad0934392a6ba..393db8060ded6 100644 --- a/boards/native/nrf_bsim/Kconfig.defconfig +++ b/boards/native/nrf_bsim/Kconfig.defconfig @@ -54,19 +54,6 @@ config BT_HCI_IPC endif # BOARD_NRF5340BSIM_NRF5340_CPUAPP -if BOARD_NRF5340BSIM_NRF5340_CPUAPP || BOARD_NRF52_BSIM - -# BT relies on PSA Crypto API to perform crypto operations. On this platform -# this is implemented by Mbed TLS which requires a (possibly true) random -# number generator to initialize properly. We enable ENTROPY_GENERATOR here -# instead of manually adding it to all samples/tests configuration files because -# it looks more compact and easier to maintain. -config ENTROPY_GENERATOR - bool - default y if BT - -endif # BOARD_NRF5340BSIM_NRF5340_CPUAPP || BOARD_NRF52_BSIM - # The 15.4 driver Tx encryption is currently not functional with this # simulated board => we disable it by default. With this Openthread will normally # default to encrypt packets on its own. diff --git a/boards/native/nrf_bsim/doc/nrf52_bsim.rst b/boards/native/nrf_bsim/doc/nrf52_bsim.rst index 01bd2c9f88ef8..3c94c82b53426 100644 --- a/boards/native/nrf_bsim/doc/nrf52_bsim.rst +++ b/boards/native/nrf_bsim/doc/nrf52_bsim.rst @@ -171,6 +171,33 @@ Run them with ``-help`` for more information. You can find more information about how to run BabbleSim simulations in `this BabbleSim example `_. +Running an application using the console +======================================== + +Some applications require the use of a console to interact with the user. +These applications typically enable :kconfig:option:`CONFIG_CONSOLE_SUBSYS` and :kconfig:option:`CONFIG_CONSOLE_GETCHAR`. +The UART console is disabled by default for BabbleSim boards, to enable it simply add the snippet :ref:`snippet-uart-console`. + +.. code-block:: console + + west build -S serial-console [...] + +To view the output and interact with the application the user needs to connect a terminal to this pseudoterminal. + +.. code-block:: console + + # Automatically attach to the terminal + ./build/zephyr/zephyr.exe --uart_pty_attach + # Use a custom command to attach to the terminal, for example 'xterm -e screen %s &' + ./build/zephyr/zephyr.exe --uart_attach_cmd= + # Use a custom way to connect to the pseudoterminal + ./build/zephyr/zephyr.exe --uart_pty --uart_pty_wait + minicom -D /dev/pts/ + +The command line option ``--uart_list`` prints out the mapping between ``uart_id`` and the UART peripherals. +The overlay files describes which UART peripheral is being used as the console output. + +For more details about attaching to the UART output, refer to the output of the ``-help`` option of the executable. C library choice **************** diff --git a/boards/native/nrf_bsim/doc/nrf54l15bsim.rst b/boards/native/nrf_bsim/doc/nrf54l15bsim.rst index ae8b29d2aecff..3b5275455033c 100644 --- a/boards/native/nrf_bsim/doc/nrf54l15bsim.rst +++ b/boards/native/nrf_bsim/doc/nrf54l15bsim.rst @@ -40,6 +40,7 @@ This boards include models of some of the nRF54L15 SOC peripherals: * AAR (Accelerated Address Resolver) * CCM (AES CCM mode encryption) * CLOCK (Clock control) +* CRACEN (Crypto Accelerator Engine) * DPPI (Distributed Programmable Peripheral Interconnect) * ECB (AES electronic codebook mode encryption) * EGU (Event Generator Unit) @@ -49,7 +50,6 @@ This boards include models of some of the nRF54L15 SOC peripherals: * PPIB (PPI Bridge) * RADIO * RRAMC (Resistive RAM Controller) -* RTC (Real Time Counter) * TEMP (Temperature sensor) * TIMER * UARTE (UART with Easy DMA) diff --git a/boards/native/nrf_bsim/irq_handler.c b/boards/native/nrf_bsim/irq_handler.c index c794395fb9a73..74d0dc5889eec 100644 --- a/boards/native/nrf_bsim/irq_handler.c +++ b/boards/native/nrf_bsim/irq_handler.c @@ -135,7 +135,7 @@ void posix_irq_handler(void) if (may_swap && (hw_irq_ctrl_get_cur_prio(cpu_n) == 256) && (CPU_will_be_awaken_from_WFE == false) - && (_kernel.ready_q.cache) && (_kernel.ready_q.cache != arch_current_thread())) { + && (_kernel.ready_q.cache) && (_kernel.ready_q.cache != _current)) { z_swap_irqlock(irq_lock); } @@ -278,6 +278,11 @@ void posix_isr_declare(unsigned int irq_p, int flags, void isr_p(const void *), */ void posix_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { + if (irq >= NHW_INTCTRL_MAX_INTLINES) { + bs_trace_error_time_line("Attempted to configure not existent interrupt %u\n", + irq); + return; + } hw_irq_ctrl_prio_set(CONFIG_NATIVE_SIMULATOR_MCU_N, irq, prio); } diff --git a/boards/native/nrf_bsim/nrf52_bsim.dts b/boards/native/nrf_bsim/nrf52_bsim.dts index ad3ac181ae7d6..9b5b5ba378604 100644 --- a/boards/native/nrf_bsim/nrf52_bsim.dts +++ b/boards/native/nrf_bsim/nrf52_bsim.dts @@ -36,6 +36,7 @@ chosen { zephyr,ieee802154 = &ieee802154; zephyr,flash = &flash0; + zephyr,console = &uart0; /* UART used by the BT controller UART HCI driver by default: */ zephyr,bt-c2h-uart = &uart1; }; diff --git a/boards/native/nrf_bsim/nrf52_bsim_defconfig b/boards/native/nrf_bsim/nrf52_bsim_defconfig index 0559b64671296..38b42f7eb8896 100644 --- a/boards/native/nrf_bsim/nrf52_bsim_defconfig +++ b/boards/native/nrf_bsim/nrf52_bsim_defconfig @@ -3,4 +3,3 @@ CONFIG_CONSOLE=y CONFIG_NO_OPTIMIZATIONS=y -CONFIG_LOG_BACKEND_UART=n diff --git a/boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts b/boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts index 0273ee4d77681..bdcd47f9440b5 100644 --- a/boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts +++ b/boards/native/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts @@ -39,6 +39,7 @@ }; chosen { + zephyr,console = &uart0; zephyr,entropy = &rng_hci; zephyr,flash = &flash0; zephyr,bt-hci = &bt_hci_ipc0; diff --git a/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts b/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts index 8e53dfe09dc64..ca61290384bbd 100644 --- a/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts +++ b/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts @@ -15,6 +15,7 @@ compatible = "bsim,nrf54l15-bsim-nrf54l15-cpuapp", "bsim,nrf54"; chosen { + zephyr,console = &uart20; zephyr,entropy = &rng; zephyr,bt-c2h-uart = &uart20; zephyr,flash-controller = &rram_controller; @@ -22,14 +23,12 @@ }; /delete-node/ cpus; - /delete-node/ clocks; /delete-node/ sw-pwm; soc { /delete-node/ memory@20000000; /delete-node/ memory@2002f000; peripheral@50000000 { - /delete-node/ spi@4a000; /delete-node/ vpr@4c000; /delete-node/ mailbox@0; /delete-node/ interrupt-controller@f0000000; @@ -56,7 +55,7 @@ rng: rng { status = "okay"; - compatible = "zephyr,native-posix-rng"; + compatible = "nordic,nrf-cracen-ctrdrbg"; }; psa_rng: psa-rng { @@ -69,6 +68,8 @@ /* Channels 7-11 reserved for Zero Latency IRQs, 3-4 for FLPR */ child-owned-channels = <3 4 7 8 9 10 11>; status = "okay"; + /delete-property/ clocks; + /delete-property/ clock-names; }; &cpuapp_rram { @@ -83,8 +84,8 @@ }; }; -&uart00 { - /delete-property/ clocks; +&spi00 { + status = "disabled"; }; &uart20 { diff --git a/boards/nordic/nrf21540dk/nrf21540dk_nrf52840.yaml b/boards/nordic/nrf21540dk/nrf21540dk_nrf52840.yaml index b84c5371d877b..d097ead5541ad 100644 --- a/boards/nordic/nrf21540dk/nrf21540dk_nrf52840.yaml +++ b/boards/nordic/nrf21540dk/nrf21540dk_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/nordic/nrf51dk/nrf51dk_nrf51822.yaml b/boards/nordic/nrf51dk/nrf51dk_nrf51822.yaml index e3aab4cbf8545..801aa256adcc6 100644 --- a/boards/nordic/nrf51dk/nrf51dk_nrf51822.yaml +++ b/boards/nordic/nrf51dk/nrf51dk_nrf51822.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 256 supported: diff --git a/boards/nordic/nrf51dongle/nrf51dongle_nrf51822.yaml b/boards/nordic/nrf51dongle/nrf51dongle_nrf51822.yaml index 8622e018ba328..9f87b6282c7f8 100644 --- a/boards/nordic/nrf51dongle/nrf51dongle_nrf51822.yaml +++ b/boards/nordic/nrf51dongle/nrf51dongle_nrf51822.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 256 supported: diff --git a/boards/nordic/nrf52833dk/nrf52833dk_nrf52820.yaml b/boards/nordic/nrf52833dk/nrf52833dk_nrf52820.yaml index 62e323927982e..682b6a0c67c60 100644 --- a/boards/nordic/nrf52833dk/nrf52833dk_nrf52820.yaml +++ b/boards/nordic/nrf52833dk/nrf52833dk_nrf52820.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 256 supported: diff --git a/boards/nordic/nrf52833dk/nrf52833dk_nrf52833.yaml b/boards/nordic/nrf52833dk/nrf52833dk_nrf52833.yaml index 8ab244fd648b1..93d3744e2fe1e 100644 --- a/boards/nordic/nrf52833dk/nrf52833dk_nrf52833.yaml +++ b/boards/nordic/nrf52833dk/nrf52833dk_nrf52833.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/nordic/nrf52840dk/nrf52840dk_nrf52811.yaml b/boards/nordic/nrf52840dk/nrf52840dk_nrf52811.yaml index 4c06984e3de38..1316814cc616c 100644 --- a/boards/nordic/nrf52840dk/nrf52840dk_nrf52811.yaml +++ b/boards/nordic/nrf52840dk/nrf52840dk_nrf52811.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 24 flash: 192 supported: diff --git a/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.yaml b/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.yaml index 313a975e6d04f..d257234e73968 100644 --- a/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.yaml +++ b/boards/nordic/nrf52840dk/nrf52840dk_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/nordic/nrf52840dongle/Kconfig b/boards/nordic/nrf52840dongle/Kconfig index b1cb32d2251ef..c8698ad07011f 100644 --- a/boards/nordic/nrf52840dongle/Kconfig +++ b/boards/nordic/nrf52840dongle/Kconfig @@ -12,8 +12,4 @@ config BOARD_HAS_NRF5_BOOTLOADER If selected, applications are linked so that they can be loaded by Nordic nRF5 bootloader. -config BOARD_SERIAL_BACKEND_CDC_ACM - bool "USB CDC" - default y - endif # BOARD_NRF52840DONGLE diff --git a/boards/nordic/nrf52840dongle/Kconfig.defconfig b/boards/nordic/nrf52840dongle/Kconfig.defconfig index 0140f3f99d5f8..5bdbb6ce63bd5 100644 --- a/boards/nordic/nrf52840dongle/Kconfig.defconfig +++ b/boards/nordic/nrf52840dongle/Kconfig.defconfig @@ -22,59 +22,6 @@ config FLASH_LOAD_OFFSET default 0x1000 depends on BOARD_HAS_NRF5_BOOTLOADER && (MCUBOOT || !USE_DT_CODE_PARTITION) -if BOARD_SERIAL_BACKEND_CDC_ACM - -config USB_DEVICE_STACK - default y - -config USB_CDC_ACM - default SERIAL - -config CONSOLE - default y - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y if !MCUBOOT && CONSOLE - -config SHELL_BACKEND_SERIAL_CHECK_DTR - default SHELL - depends on UART_LINE_CTRL - -config UART_LINE_CTRL - default SHELL - -config USB_DEVICE_REMOTE_WAKEUP - default n - -if LOG - -# Logger cannot use itself to log -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF -endchoice - -# Set USB log level to error only -choice USB_DEVICE_LOG_LEVEL_CHOICE - default USB_DEVICE_LOG_LEVEL_ERR -endchoice - -# Wait 4000ms at startup for logging -config LOG_PROCESS_THREAD_STARTUP_DELAY_MS - default 4000 - -endif # LOG - -if USB_DEVICE_STACK - -# Enable UART driver, needed for CDC ACM -config SERIAL - default y - -endif # USB_DEVICE_STACK - -endif # BOARD_SERIAL_BACKEND_CDC_ACM +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_NRF52840DONGLE diff --git a/boards/nordic/nrf52840dongle/doc/index.rst b/boards/nordic/nrf52840dongle/doc/index.rst index 9aa6f74811f3e..db2e7d70de0bd 100644 --- a/boards/nordic/nrf52840dongle/doc/index.rst +++ b/boards/nordic/nrf52840dongle/doc/index.rst @@ -126,7 +126,10 @@ Option 1: Using the Built-In Bootloader Only The board is factory-programmed with Nordic's bootloader from Nordic's nRF5 SDK. With this option, you'll use Nordic's `nrfutil`_ program to create firmware packages supported by this bootloader and flash them to the -device. Make sure ``nrfutil`` is installed before proceeding. +device. Before proceeding make sure: + +* ``nrfutil`` is installed. +* The ``nrf5sdk-tools`` command is installed within ``nrfutil``. #. Reset the board into the Nordic bootloader by pressing the RESET button. @@ -151,16 +154,19 @@ device. Make sure ``nrfutil`` is installed before proceeding. .. code-block:: console - nrfutil pkg generate --hw-version 52 --sd-req=0x00 \ - --application build/zephyr/zephyr.hex \ - --application-version 1 blinky.zip + nrfutil nrf5sdk-tools pkg generate \ + --hw-version 52 \ + --sd-req=0x00 \ + --application build/zephyr/zephyr.hex \ + --application-version 1 \ + blinky.zip #. Flash it onto the board. Note :file:`/dev/ttyACM0` is for Linux; it will be something like ``COMx`` on Windows, and something else on macOS. .. code-block:: console - nrfutil dfu usb-serial -pkg blinky.zip -p /dev/ttyACM0 + nrfutil nrf5sdk-tools dfu usb-serial -pkg blinky.zip -p /dev/ttyACM0 When this command exits, observe the green LED on the board blinking, instead of the red LED used by the bootloader. @@ -198,16 +204,19 @@ to the zephyr repository on your computer. .. code-block:: console - nrfutil pkg generate --hw-version 52 --sd-req=0x00 \ - --application build/mcuboot/zephyr/zephyr.hex \ - --application-version 1 mcuboot.zip + nrfutil nrf5sdk-tools pkg generate \ + --hw-version 52 \ + --sd-req=0x00 \ + --application build/mcuboot/zephyr/zephyr.hex \ + --application-version 1 \ + mcuboot.zip #. Flash it onto the board. Note :file:`/dev/ttyACM0` is for Linux; it will be something like ``COMx`` on Windows, and something else on macOS. .. code-block:: console - nrfutil dfu usb-serial -pkg mcuboot.zip -p /dev/ttyACM0 + nrfutil nrf5sdk-tools dfu usb-serial -pkg mcuboot.zip -p /dev/ttyACM0 You can now flash a Zephyr application to the board using MCUboot's serial recovery mode. We'll use the :zephyr:code-sample:`smp-svr` sample since it's ready to be @@ -341,7 +350,7 @@ References .. _Nordic Semiconductor USB DFU: https://docs.nordicsemi.com/bundle/sdk_nrf5_v17.1.0/page/sdk_app_serial_dfu_bootloader.html .. _nrfutil: - https://github.com/NordicSemiconductor/pc-nrfutil + https://www.nordicsemi.com/Products/Development-tools/nrf-util .. _MCUboot: https://github.com/JuulLabs-OSS/mcuboot .. _mcumgr: diff --git a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.dts b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.dts index 655ef346a6522..1f1de703adee9 100644 --- a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.dts +++ b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.dts @@ -15,11 +15,6 @@ compatible = "nordic,nrf52840-dongle-nrf52840"; chosen { - zephyr,console = &cdc_acm_uart; - zephyr,shell-uart = &cdc_acm_uart; - zephyr,uart-mcumgr = &cdc_acm_uart; - zephyr,bt-mon-uart = &cdc_acm_uart; - zephyr,bt-c2h-uart = &cdc_acm_uart; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; @@ -188,8 +183,6 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - cdc_acm_uart: cdc_acm_uart { - compatible = "zephyr,cdc-acm-uart"; - }; }; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml index e5410c74c7111..7eb89aa894b48 100644 --- a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml +++ b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/nordic/nrf52dk/nrf52dk_nrf52805.yaml b/boards/nordic/nrf52dk/nrf52dk_nrf52805.yaml index 86d3e44b8eff7..29f13ebf8871d 100644 --- a/boards/nordic/nrf52dk/nrf52dk_nrf52805.yaml +++ b/boards/nordic/nrf52dk/nrf52dk_nrf52805.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/nordic/nrf52dk/nrf52dk_nrf52810.yaml b/boards/nordic/nrf52dk/nrf52dk_nrf52810.yaml index 46cc9adbac6b4..d92f22d7d1872 100644 --- a/boards/nordic/nrf52dk/nrf52dk_nrf52810.yaml +++ b/boards/nordic/nrf52dk/nrf52dk_nrf52810.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/nordic/nrf52dk/nrf52dk_nrf52832.yaml b/boards/nordic/nrf52dk/nrf52dk_nrf52832.yaml index f50bb91ba040e..b2b9939a55322 100644 --- a/boards/nordic/nrf52dk/nrf52dk_nrf52832.yaml +++ b/boards/nordic/nrf52dk/nrf52dk_nrf52832.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/nordic/nrf5340_audio_dk/Kconfig.defconfig b/boards/nordic/nrf5340_audio_dk/Kconfig.defconfig index 543afadd4f224..7084af10d6bf0 100644 --- a/boards/nordic/nrf5340_audio_dk/Kconfig.defconfig +++ b/boards/nordic/nrf5340_audio_dk/Kconfig.defconfig @@ -53,19 +53,6 @@ config FLASH_LOAD_SIZE endif # BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP_NS -if BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP - -# BT relies on PSA Crypto API to perform crypto operations. On this platform -# this is implemented by Mbed TLS which requires a (possibly true) random -# number generator to initialize properly. We enable ENTROPY_GENERATOR here -# instead of manually adding it to all samples/tests configuration files because -# it looks more compact and easier to maintain. -config ENTROPY_GENERATOR - bool - default y if BT - -endif # BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP - config BT_HCI_IPC default y if BT diff --git a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp.yaml b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp.yaml index 8d8e378179577..b2b5d48b04114 100644 --- a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp.yaml +++ b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml index 28a295758911b..efa82f669a00e 100644 --- a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml +++ b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 192 flash: 192 diff --git a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpunet.yaml b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpunet.yaml index 35e0ba7ca2875..bf828e5309489 100644 --- a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpunet.yaml +++ b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpunet.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/nordic/nrf5340dk/Kconfig.defconfig b/boards/nordic/nrf5340dk/Kconfig.defconfig index 67747c688adab..b6186d4e07452 100644 --- a/boards/nordic/nrf5340dk/Kconfig.defconfig +++ b/boards/nordic/nrf5340dk/Kconfig.defconfig @@ -43,19 +43,6 @@ config SRAM_SIZE endif # BOARD_NRF5340DK_NRF5340_CPUAPP && TRUSTED_EXECUTION_SECURE -if BOARD_NRF5340DK_NRF5340_CPUAPP - -# BT relies on PSA Crypto API to perform crypto operations. On this platform -# this is implemented by Mbed TLS which requires a (possibly true) random -# number generator to initialize properly. We enable ENTROPY_GENERATOR here -# instead of manually adding it to all samples/tests configuration files because -# it looks more compact and easier to maintain. -config ENTROPY_GENERATOR - bool - default y if BT - -endif # BOARD_NRF5340DK_NRF5340_CPUAPP - if BOARD_NRF5340DK_NRF5340_CPUAPP_NS config FLASH_LOAD_OFFSET diff --git a/boards/nordic/nrf5340dk/board.cmake b/boards/nordic/nrf5340dk/board.cmake index 2a3f3cb43e449..306f1d7e4fbd5 100644 --- a/boards/nordic/nrf5340dk/board.cmake +++ b/boards/nordic/nrf5340dk/board.cmake @@ -5,7 +5,7 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP_NS) endif() if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP_NS) -board_runner_args(jlink "--device=nrf5340_xxaa_app" "--speed=4000") + board_runner_args(jlink "--device=nrf5340_xxaa_app" "--speed=4000") endif() if(CONFIG_TFM_FLASH_MERGED_BINARY) @@ -13,7 +13,7 @@ if(CONFIG_TFM_FLASH_MERGED_BINARY) endif() if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET) -board_runner_args(jlink "--device=nrf5340_xxaa_net" "--speed=4000") + board_runner_args(jlink "--device=nrf5340_xxaa_net" "--speed=4000") endif() include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp.yaml b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp.yaml index 50ed473387143..914353ffaceb3 100644 --- a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp.yaml +++ b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp.yaml @@ -4,11 +4,14 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 supported: + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi - gpio - i2c - i2s diff --git a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.yaml b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.yaml index 4c366d2f363f5..eaf2b54853106 100644 --- a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.yaml +++ b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.yaml @@ -4,11 +4,14 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 192 flash: 192 supported: + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi - i2c - pwm - watchdog @@ -18,3 +21,4 @@ supported: - gpio - spi vendor: nordic +sysbuild: true diff --git a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpunet.yaml b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpunet.yaml index a55a7879fc015..90fd8786513e7 100644 --- a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpunet.yaml +++ b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpunet.yaml @@ -4,11 +4,11 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 supported: + - arduino_gpio - watchdog - gpio vendor: nordic diff --git a/boards/nordic/nrf54h20dk/bicr.json b/boards/nordic/nrf54h20dk/bicr.json new file mode 100644 index 0000000000000..9937860052bd8 --- /dev/null +++ b/boards/nordic/nrf54h20dk/bicr.json @@ -0,0 +1,32 @@ +{ + "power": { + "scheme": "VDDH_2V1_5V5" + }, + "ioPortPower": { + "p1Supply": "EXTERNAL_1V8", + "p2Supply": "EXTERNAL_1V8", + "p6Supply": "EXTERNAL_1V8", + "p7Supply": "EXTERNAL_1V8", + "p9Supply": "EXTERNAL_FULL" + }, + "ioPortImpedance": { + "p6ImpedanceOhms": 50, + "p7ImpedanceOhms": 50 + }, + "lfosc": { + "source": "LFXO", + "lfxo": { + "mode": "CRYSTAL", + "accuracyPPM": 20, + "startupTimeMs": 600, + "builtInLoadCapacitancePf": 15, + "builtInLoadCapacitors": true + } + }, + "hfxo": { + "mode": "CRYSTAL", + "startupTimeUs": 850, + "builtInLoadCapacitors": true, + "builtInLoadCapacitancePf": 14 + } +} diff --git a/boards/nordic/nrf54h20dk/board.cmake b/boards/nordic/nrf54h20dk/board.cmake index 0c8376c1714e1..80963356dc989 100644 --- a/boards/nordic/nrf54h20dk/board.cmake +++ b/boards/nordic/nrf54h20dk/board.cmake @@ -12,3 +12,14 @@ if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR CONFIG_BOARD_NRF54H20DK_NRF54H20_C board_runner_args(jlink "--device=CORTEX-M33" "--speed=4000" "--tool-opt=-jlinkscriptfile ${JLINKSCRIPTFILE}") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) endif() + +if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUFLPR) + if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR) + set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpuppr.JLinkScript) + else() + set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpuflpr.JLinkScript) + endif() + + board_runner_args(jlink "--device=RISC-V" "--speed=4000" "-if SW" "--tool-opt=-jlinkscriptfile ${JLINKSCRIPTFILE}") + include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +endif() diff --git a/boards/nordic/nrf54h20dk/doc/index.rst b/boards/nordic/nrf54h20dk/doc/index.rst index c8e95e3987555..43a92673e39e9 100644 --- a/boards/nordic/nrf54h20dk/doc/index.rst +++ b/boards/nordic/nrf54h20dk/doc/index.rst @@ -126,6 +126,10 @@ Push buttons Programming and Debugging ************************* +.. note:: + When first using the nRF54H20 DK, you must program the `nRF54H20 SoC binaries`_ on the development kit. + To do so, follow the bring up steps instructions on the `Getting started with the nRF54H20 DK`_ documentation. + Applications for all targets can be built and flashed the usual way. See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. Debugging is for now limited to the application and radio @@ -163,3 +167,9 @@ your board. The button and LED definitions can be found in .. _nRF Util: https://www.nordicsemi.com/Products/Development-tools/nrf-util + +.. _Getting started with the nRF54H20 DK: + https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf54h/ug_nrf54h20_gs.html + +.. _nRF54H20 SoC binaries: + https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/releases_and_maturity/abi_compatibility.html diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi index 595307aec8c81..b0cb997de9477 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi @@ -11,13 +11,11 @@ &hfxo { status = "okay"; accuracy-ppm = <30>; - startup-time-us = <850>; - mode = "crystal"; }; &lfxo { status = "okay"; - accuracy-ppm = <20>; - startup-time-us = <600000>; - mode = "crystal"; }; + +/* Get a node label for wi-fi spi to use in shield files */ +wifi_spi: &spi130 {}; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi index 79ac2c6b7ad7c..9b574a18ec52c 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi @@ -98,4 +98,19 @@ low-power-enable; }; }; + + /omit-if-no-ref/ grtc_default: grtc_default { + group1 { + psels = , + ; + }; + }; + + /omit-if-no-ref/ grtc_sleep: grtc_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; }; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml index a64f8cf6398b1..943b2fb828a1c 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml @@ -7,7 +7,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 256 diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml index 568f6fcc18e9c..de557fcc2cdbb 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml @@ -7,7 +7,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 192 diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript index 28010addbf154..b1b968573991f 100644 --- a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript @@ -1,260 +1,12 @@ -// Constants specific to the application core __constant U32 _CPUCONF_ADDR = 0x52011000; -__constant U32 _PROCESSOR_ID = 2; -__constant U32 _DOMAIN_ID = 2; -__constant U32 _NUM_OTHER_PROCESSORS = 1; -const U32 _OTHER_PROCESSOR_IDS[1] = {3}; - -// Debug Halting Control and Status Register -__constant U32 _DHCSR_ADDR = 0xE000EDF0; -__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); -__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); -__constant U32 _DHCSR_C_HALT = (1 << 1); - -// Debug Exception and Monitor Control Register -__constant U32 _DEMCR_ADDR = 0xE000EDFC; -__constant U32 _DEMCR_VC_CORERESET = (1 << 0); -__constant U32 _DEMCR_TRCENA = (1 << 24); - -// CPU wait enable register __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C; -// CTRL-AP -__constant U32 _CTRLAP_ID = 4; -__constant U32 _CTRLAP_READY_BANK = 0; -__constant U32 _CTRLAP_READY_OFFSET = 1; -__constant U32 _CTRLAP_READY = 0; -__constant U32 _CTRLAP_MAILBOX_BANK = 1; -__constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0; -__constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1; -__constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2; -__constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3; -__constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0; -__constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1; -__constant int _CTRLAP_TIMEOUT_MS = 500; - -// ADAC transaction buffers -static U32 _adacTx[20]; -static U32 _adacRx[20]; - -// Failed to send to the CTRL-AP MAILBOX -__constant int _ERR_TX = -1; -// Failed to receive from the CTRL-AP MAILBOX -__constant int _ERR_RX = -2; -// ADAC command returned an error -__constant int _ERR_REPLY = -3; - -// Wait for an AP register read to return the expected value. -int _WaitForDataStatus(U32 regOffset, int expectedStatus) -{ - int status; - int ret; - int start; - int elapsed; - - status = 0; - start = JLINK_GetTime(); - elapsed = 0; - - do { - ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status); - elapsed = JLINK_GetTime() - start; - } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS)); - - if (ret < 0) { - return ret; - } - - return status; -} - -// Continuously read from the CTRL-AP MAILBOX until there is no more pending data. -void _DrainMailbox(void) -{ - int ret; - int status; - int data; - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - } -} - -// Perform an ADAC transaction by: -// * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS -// readiness before each write. -// * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before -// each read. -// -// The message to send is read from _adacTx and the reply is written to _adacRx. -// Optionally checks if a single data word is returned and returns an error if it is non-zero. -// -// Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP. -int _DoAdacTransaction(int checkReplyStatus) -{ - int numWords; - int ret; - int data; - int i; - - i = 0; - numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET, - _CTRLAP_MAILBOX_NO_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ", - ret); - return _ERR_TX; - } - - ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]); - if (ret < 0) { - JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret); - return _ERR_TX; - } - - i += 1; - } - - i = 0; - numWords = 2; // Minimum message length - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, - _CTRLAP_MAILBOX_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - if (ret < 0) { - JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - if (i == 1) { - // Update total length based on the message length field - numWords = 2 + (data >> 2); - } - - _adacRx[i] = data; - i += 1; - } - - if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) { - JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]); - return _ERR_REPLY; - } - - return 0; -} - -int ResetTarget(void) +int SetupTarget(void) { - int err; - U32 adacMajorVersion; - U32 i; - - // Select CTRL-AP bank 0, used for the READY register - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4)); - - // Wait for the READY register to indicate that the AP can be used. - err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY); - if (err < 0) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err); - return -1; - } - - // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4)); - - // Extract any pre-existing data from the mailbox in case there was previously - // an aborted transaction. - _DrainMailbox(); - - // Read the ADAC version - _adacTx[0] = 0xA3000000; // Command VERSION - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // Type 0 (ADAC version) - err = _DoAdacTransaction(0); - if (err < 0) { - return -1; - } - - adacMajorVersion = (_adacRx[2] >> 24) & 0xff; - JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion); - - if (adacMajorVersion >= 2) { - // There is a very small chance that this command fails if the domain reset itself - // at the exact same time the command was issued. Therefore we retry a few times. - i = 0; - while (i < 3) { - // Reset non-essential domains - _adacTx[0] = 0xA30A0000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // (reserved) - err = _DoAdacTransaction(1); - if (err >= 0) { - break; - } else if (err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - - // Start the core in halted mode - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - - // Start other cores normally (will fail silently if no firmware is present) - i = 0; - while (i < _NUM_OTHER_PROCESSORS) { - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000 | - (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags - err = _DoAdacTransaction(0); - if (err < 0 && err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - } else { - // Reset single domain via legacy implementation - _adacTx[0] = 0xA3030000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - } - - // Halt the CPU - JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); - - // Set vector catch on reset (to halt the CPU immediately after reset) - JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + JLINK_TARGET_Halt(); // Disable CPU wait JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); - // Clear vector catch stuff - JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); - return 0; } diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuflpr.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuflpr.JLinkScript new file mode 100644 index 0000000000000..10b83259fdd50 --- /dev/null +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuflpr.JLinkScript @@ -0,0 +1,9 @@ +int InitTarget(void) { + // Base address where DMI registers can be found in the APB address space + JLINK_ExecCommand("CORESIGHT_SetCoreBaseAddr = 0x5F8D4400"); + + // Use AP[x] to communicate with the RISC-V, flpr = APP + JLINK_ExecCommand("CORESIGHT_SetIndexAHBAPToUse = 0"); + + return 0; +} diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuppr.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuppr.JLinkScript new file mode 100644 index 0000000000000..127981a45c368 --- /dev/null +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuppr.JLinkScript @@ -0,0 +1,9 @@ +int InitTarget(void) { + // Base address where DMI registers can be found in the APB address space + JLINK_ExecCommand("CORESIGHT_SetCoreBaseAddr = 0x5F908400"); + + // Use AP[x] to communicate with the RISC-V, ppr = APP + JLINK_ExecCommand("CORESIGHT_SetIndexAHBAPToUse = 0"); + + return 0; +} diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript index 5c2065307ff56..e1861ae8c972a 100644 --- a/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript @@ -1,159 +1,6 @@ -// Constants specific to the radio core __constant U32 _CPUCONF_ADDR = 0x53011000; -__constant U32 _PROCESSOR_ID = 3; -__constant U32 _DOMAIN_ID = 3; -__constant U32 _NUM_OTHER_PROCESSORS = 1; -const U32 _OTHER_PROCESSOR_IDS[1] = {2}; - -// Debug Halting Control and Status Register -__constant U32 _DHCSR_ADDR = 0xE000EDF0; -__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); -__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); -__constant U32 _DHCSR_C_HALT = (1 << 1); - -// Debug Exception and Monitor Control Register -__constant U32 _DEMCR_ADDR = 0xE000EDFC; -__constant U32 _DEMCR_VC_CORERESET = (1 << 0); -__constant U32 _DEMCR_TRCENA = (1 << 24); - -// CPU wait enable register __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C; -// CTRL-AP -__constant U32 _CTRLAP_ID = 4; -__constant U32 _CTRLAP_READY_BANK = 0; -__constant U32 _CTRLAP_READY_OFFSET = 1; -__constant U32 _CTRLAP_READY = 0; -__constant U32 _CTRLAP_MAILBOX_BANK = 1; -__constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0; -__constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1; -__constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2; -__constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3; -__constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0; -__constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1; -__constant int _CTRLAP_TIMEOUT_MS = 500; - -// ADAC transaction buffers -static U32 _adacTx[20]; -static U32 _adacRx[20]; - -// Failed to send to the CTRL-AP MAILBOX -__constant int _ERR_TX = -1; -// Failed to receive from the CTRL-AP MAILBOX -__constant int _ERR_RX = -2; -// ADAC command returned an error -__constant int _ERR_REPLY = -3; - -// Wait for an AP register read to return the expected value. -int _WaitForDataStatus(U32 regOffset, int expectedStatus) -{ - int status; - int ret; - int start; - int elapsed; - - status = 0; - start = JLINK_GetTime(); - elapsed = 0; - - do { - ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status); - elapsed = JLINK_GetTime() - start; - } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS)); - - if (ret < 0) { - return ret; - } - - return status; -} - -// Continuously read from the CTRL-AP MAILBOX until there is no more pending data. -void _DrainMailbox(void) -{ - int ret; - int status; - int data; - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - } -} - -// Perform an ADAC transaction by: -// * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS -// readiness before each write. -// * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before -// each read. -// -// The message to send is read from _adacTx and the reply is written to _adacRx. -// Optionally checks if a single data word is returned and returns an error if it is non-zero. -// -// Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP. -int _DoAdacTransaction(int checkReplyStatus) -{ - int numWords; - int ret; - int data; - int i; - - i = 0; - numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET, - _CTRLAP_MAILBOX_NO_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ", - ret); - return _ERR_TX; - } - - ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]); - if (ret < 0) { - JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret); - return _ERR_TX; - } - - i += 1; - } - - i = 0; - numWords = 2; // Minimum message length - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, - _CTRLAP_MAILBOX_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - if (ret < 0) { - JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - if (i == 1) { - // Update total length based on the message length field - numWords = 2 + (data >> 2); - } - - _adacRx[i] = data; - i += 1; - } - - if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) { - JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]); - return _ERR_REPLY; - } - - return 0; -} - int ConfigTargetSettings(void) { JLINK_ExecCommand("CORESIGHT_AddAP = Index=1 Type=AHB-AP"); @@ -162,107 +9,12 @@ int ConfigTargetSettings(void) return 0; } -int ResetTarget(void) +int SetupTarget(void) { - int err; - U32 adacMajorVersion; - U32 i; - - // Select CTRL-AP bank 0, used for the READY register - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4)); - - // Wait for the READY register to indicate that the AP can be used. - err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY); - if (err < 0) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err); - return -1; - } - - // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4)); - - // Extract any pre-existing data from the mailbox in case there was previously - // an aborted transaction. - _DrainMailbox(); - - // Read the ADAC version - _adacTx[0] = 0xA3000000; // Command VERSION - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // Type 0 (ADAC version) - err = _DoAdacTransaction(0); - if (err < 0) { - return -1; - } - - adacMajorVersion = (_adacRx[2] >> 24) & 0xff; - JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion); - - if (adacMajorVersion >= 2) { - // There is a very small chance that this command fails if the domain reset itself - // at the exact same time the command was issued. Therefore we retry a few times. - i = 0; - while (i < 3) { - // Reset non-essential domains - _adacTx[0] = 0xA30A0000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // (reserved) - err = _DoAdacTransaction(1); - if (err >= 0) { - break; - } else if (err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - - // Start the core in halted mode - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - - // Start other cores normally (will fail silently if no firmware is present) - i = 0; - while (i < _NUM_OTHER_PROCESSORS) { - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000 | - (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags - err = _DoAdacTransaction(0); - if (err < 0 && err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - } else { - // Reset single domain via legacy implementation - _adacTx[0] = 0xA3030000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - } - - // Halt the CPU - JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); - - // Set vector catch on reset (to halt the CPU immediately after reset) - JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + JLINK_TARGET_Halt(); // Disable CPU wait JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); - // Clear vector catch stuff - JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); - return 0; } diff --git a/boards/nordic/nrf54l09pdk/Kconfig.defconfig b/boards/nordic/nrf54l09pdk/Kconfig.defconfig new file mode 100644 index 0000000000000..44589c9b35b75 --- /dev/null +++ b/boards/nordic/nrf54l09pdk/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF54L09PDK_NRF54L09_CPUAPP + +config BT_CTLR + default BT + +config ROM_START_OFFSET + default 0x800 if BOOTLOADER_MCUBOOT + +config SOC_NRF54LX_SKIP_GLITCHDETECTOR_DISABLE + default y + +endif # BOARD_NRF54L09PDK_NRF54L09_CPUAPP diff --git a/boards/nordic/nrf54l09pdk/Kconfig.nrf54l09pdk b/boards/nordic/nrf54l09pdk/Kconfig.nrf54l09pdk new file mode 100644 index 0000000000000..bc6aa67628183 --- /dev/null +++ b/boards/nordic/nrf54l09pdk/Kconfig.nrf54l09pdk @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF54L09PDK + select SOC_NRF54L09_ENGA_CPUAPP if BOARD_NRF54L09PDK_NRF54L09_CPUAPP diff --git a/boards/nordic/nrf54l09pdk/board.cmake b/boards/nordic/nrf54l09pdk/board.cmake new file mode 100644 index 0000000000000..5d36ac00a3e72 --- /dev/null +++ b/boards/nordic/nrf54l09pdk/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=cortex-m33" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nordic/nrf54l09pdk/board.yml b/boards/nordic/nrf54l09pdk/board.yml new file mode 100644 index 0000000000000..b35f4c1fafe2a --- /dev/null +++ b/boards/nordic/nrf54l09pdk/board.yml @@ -0,0 +1,6 @@ +board: + name: nrf54l09pdk + full_name: nRF54L09 PDK + vendor: nordic + socs: + - name: nrf54l09 diff --git a/boards/nordic/nrf54l09pdk/doc/index.rst b/boards/nordic/nrf54l09pdk/doc/index.rst new file mode 100644 index 0000000000000..77169e8e52b57 --- /dev/null +++ b/boards/nordic/nrf54l09pdk/doc/index.rst @@ -0,0 +1,90 @@ +.. zephyr:board:: nrf54l09pdk + +nRF54L09 PDK +############ + +Overview +******** + +.. note:: + + All software for the nRF54L09 SoC is experimental and hardware availability + is restricted to the participants in the limited sampling program. + +The nRF54L09 Preview Development Kit hardware provides +support for the Nordic Semiconductor nRF54L09 Arm Cortex-M33 CPU and +the following devices: + +* CLOCK +* RRAM +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`GRTC (Global real-time counter)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter)` + +Hardware +******** + +nRF54L09 PDK has two crystal oscillators: + +* High-frequency 32 MHz crystal oscillator (HFXO) +* Low-frequency 32.768 kHz crystal oscillator (LFXO) + +The crystal oscillators can be configured to use either +internal or external capacitors. + +Supported Features +================== + +The ``nrf54l09pdk/nrf54l09/cpuapp`` board target supports the following hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| RRAM | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| GRTC | on-chip | system clock | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. + +Programming and Debugging +************************* + +Applications for the ``nrf54l09pdk/nrf54l09/cpuapp`` board target can be +built, flashed, and debugged in the usual way. See +:ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +Flashing +======== + +As an example, this section shows how to build and flash the :zephyr:code-sample:`hello_world` +application. + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. + +To build and program the sample to the nRF54L09 PDK, complete the following steps: + +First, connect the nRF54L09 PDK to you computer using the IMCU USB port on the PDK. +Next, build the sample by running the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nrf54l09pdk/nrf54l09/cpuapp + :goals: build flash + +Testing the LEDs and buttons in the nRF54L09 PDK +************************************************ + +Test the nRF54L09 PDK with a :zephyr:code-sample:`blinky` sample. diff --git a/boards/nordic/nrf54l09pdk/nrf54l09_cpuapp_common.dtsi b/boards/nordic/nrf54l09pdk/nrf54l09_cpuapp_common.dtsi new file mode 100644 index 0000000000000..0bdab1b8851dd --- /dev/null +++ b/boards/nordic/nrf54l09pdk/nrf54l09_cpuapp_common.dtsi @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* This file is common to the secure and non-secure domain */ + +#include +#include "nrf54l09pdk_nrf54l09-common.dtsi" + +/ { + chosen { + zephyr,console = &uart20; + zephyr,shell-uart = &uart20; + zephyr,uart-mcumgr = &uart20; + zephyr,bt-mon-uart = &uart20; + zephyr,bt-c2h-uart = &uart20; + zephyr,flash-controller = &rram_controller; + zephyr,flash = &cpuapp_rram; + zephyr,bt-hci = &bt_hci_controller; + zephyr,ieee802154 = &ieee802154; + }; +}; + +&cpuapp_sram { + status = "okay"; +}; + +&hfpll { + /* For now use 64 MHz clock for CPU and fast peripherals. */ + clock-frequency = ; +}; + +&lfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <15500>; +}; + +&hfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <15000>; +}; + +&grtc { + owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11>; + /* Channels 7-11 reserved for Zero Latency IRQs, 3-4 for FLPR */ + child-owned-channels = <3 4 7 8 9 10 11>; + status = "okay"; +}; + +&cpuapp_rram { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(64)>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 DT_SIZE_K(212)>; + }; + slot0_ns_partition: partition@45000 { + label = "image-0-nonsecure"; + reg = <0x45000 DT_SIZE_K(212)>; + }; + slot1_partition: partition@7a000 { + label = "image-1"; + reg = <0x7a000 DT_SIZE_K(212)>; + }; + slot1_ns_partition: partition@af000 { + label = "image-1-nonsecure"; + reg = <0xaf000 DT_SIZE_K(212)>; + }; + storage_partition: partition@e4000 { + label = "storage"; + reg = <0xe4000 DT_SIZE_K(36)>; + }; + }; +}; + +&uart20 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpiote30 { + status = "okay"; +}; + +&radio { + status = "okay"; +}; + +&temp { + status = "okay"; +}; + +&clock { + status = "okay"; +}; + +&bt_hci_controller { + status = "okay"; +}; + +&ieee802154 { + status = "okay"; +}; diff --git a/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09-common.dtsi b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09-common.dtsi new file mode 100644 index 0000000000000..769b776aa1f9e --- /dev/null +++ b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09-common.dtsi @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf54l09pdk_nrf54l09-pinctrl.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + led1: led_1 { + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio1 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 0"; + zephyr,code = ; + }; + button1: button_1 { + gpios = <&gpio1 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + button2: button_2 { + gpios = <&gpio1 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + zephyr,code = ; + }; + button3: button_3 { + gpios = <&gpio0 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + watchdog0 = &wdt31; + }; +}; + +&uart20 { + current-speed = <115200>; + pinctrl-0 = <&uart20_default>; + pinctrl-1 = <&uart20_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09-pinctrl.dtsi b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09-pinctrl.dtsi new file mode 100644 index 0000000000000..83aa91d8a34a1 --- /dev/null +++ b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09-pinctrl.dtsi @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + /omit-if-no-ref/ uart20_default: uart20_default { + group1 { + psels = ; + }; + group2 { + psels = ; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ uart20_sleep: uart20_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; diff --git a/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp.dts b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp.dts new file mode 100644 index 0000000000000..7281f237b66ae --- /dev/null +++ b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "nrf54l09_cpuapp_common.dtsi" + +/ { + compatible = "nordic,nrf54l09pdk_nrf54l09-cpuapp"; + model = "Nordic nRF54L09 PDK nRF54L09 Application MCU"; + + chosen { + zephyr,code-partition = &slot0_partition; + zephyr,sram = &cpuapp_sram; + }; +}; diff --git a/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp.yaml b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp.yaml new file mode 100644 index 0000000000000..76e072b60618b --- /dev/null +++ b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54l09pdk/nrf54l09/cpuapp +name: nRF54L09-PDK-nRF54L09-Application +type: mcu +arch: arm +toolchain: + - gnuarmemb + - zephyr +sysbuild: true +ram: 192 +flash: 200 +supported: + - counter + - gpio diff --git a/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp_defconfig b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp_defconfig new file mode 100644 index 0000000000000..02796a1361ef9 --- /dev/null +++ b/boards/nordic/nrf54l09pdk/nrf54l09pdk_nrf54l09_cpuapp_defconfig @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# MPU-based null-pointer dereferencing detection cannot +# be applied as the (0x0 - 0x400) is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable Cache +CONFIG_CACHE_MANAGEMENT=y +CONFIG_EXTERNAL_CACHE=y + +# Start SYSCOUNTER on driver init +CONFIG_NRF_GRTC_START_SYSCOUNTER=y diff --git a/boards/nordic/nrf54l15dk/board.cmake b/boards/nordic/nrf54l15dk/board.cmake index c69f8460c0a58..6f615c5350513 100644 --- a/boards/nordic/nrf54l15dk/board.cmake +++ b/boards/nordic/nrf54l15dk/board.cmake @@ -1,12 +1,11 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(CONFIG_SOC_NRF54L05_CPUAPP OR CONFIG_SOC_NRF54L10_CPUAPP OR - CONFIG_SOC_NRF54L15_CPUAPP) - board_runner_args(jlink "--device=cortex-m33" "--speed=4000") -elseif(CONFIG_SOC_NRF54L05_CPUFLPR OR CONFIG_SOC_NRF54L10_CPUFLPR OR - CONFIG_SOC_NRF54L15_CPUFLPR) - board_runner_args(jlink "--speed=4000") +if(CONFIG_SOC_NRF54L05_CPUAPP OR CONFIG_SOC_NRF54L10_CPUAPP OR CONFIG_SOC_NRF54L15_CPUAPP) + board_runner_args(jlink "--device=nRF54L15_M33" "--speed=4000") +elseif(CONFIG_SOC_NRF54L05_CPUFLPR OR CONFIG_SOC_NRF54L10_CPUFLPR OR CONFIG_SOC_NRF54L15_CPUFLPR) + set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54l_05_10_15_cpuflpr.JLinkScript) + board_runner_args(jlink "--device=RISC-V" "--speed=4000" "-if SW" "--tool-opt=-jlinkscriptfile ${JLINKSCRIPTFILE}") endif() include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) diff --git a/boards/nordic/nrf54l15dk/doc/index.rst b/boards/nordic/nrf54l15dk/doc/index.rst index e4ad1e8ad09c9..6d0617746af3a 100644 --- a/boards/nordic/nrf54l15dk/doc/index.rst +++ b/boards/nordic/nrf54l15dk/doc/index.rst @@ -100,8 +100,12 @@ Applications for the ``nrf54l15dk/nrf54l15/cpuflpr`` board target need to be built as multicore configuration with code snippet called ``vpr_launcher`` for the application core. -Enter the following command to compile ``hello_world`` for the FLPR core:: - west build -p -b nrf54l15dk/nrf54l15/cpuflpr --sysbuild -- -DSB_VPR_LAUNCHER=y +Enter the following command to compile ``hello_world`` for the FLPR core: + +.. code-block:: console + + west build -p -b nrf54l15dk/nrf54l15/cpuflpr --sysbuild -- -DSB_VPR_LAUNCHER=y + Flashing ======== diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_common.dtsi b/boards/nordic/nrf54l15dk/nrf54l15dk_common.dtsi index 33cfebb55d6e6..6a40af0ee95d7 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_common.dtsi +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_common.dtsi @@ -98,3 +98,6 @@ pinctrl-1 = <&pwm20_sleep>; pinctrl-names = "default", "sleep"; }; + +/* Get a node label for wi-fi spi to use in shield files */ +wifi_spi: &spi22 {}; diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l05_cpuapp.yaml b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l05_cpuapp.yaml index 0c451b19a2efd..2a41fbf2ca10d 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l05_cpuapp.yaml +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l05_cpuapp.yaml @@ -7,7 +7,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 96 diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.yaml b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.yaml index 63afb059b9361..d56468281ac4a 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.yaml +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.yaml @@ -7,7 +7,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 192 diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.yaml b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.yaml index a3ddb5db1c608..a8c4fe549072c 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.yaml +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.yaml @@ -7,7 +7,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 188 diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi index 0b6e2056a82e1..6b7457a2818d7 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi @@ -77,4 +77,19 @@ low-power-enable; }; }; + + /omit-if-no-ref/ grtc_default: grtc_default { + group1 { + psels = , + ; + }; + }; + + /omit-if-no-ref/ grtc_sleep: grtc_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; }; diff --git a/boards/nordic/nrf54l15dk/support/nrf54l_05_10_15_cpuflpr.JLinkScript b/boards/nordic/nrf54l15dk/support/nrf54l_05_10_15_cpuflpr.JLinkScript new file mode 100644 index 0000000000000..1cf94ee52a4d0 --- /dev/null +++ b/boards/nordic/nrf54l15dk/support/nrf54l_05_10_15_cpuflpr.JLinkScript @@ -0,0 +1,5 @@ +int InitTarget(void) { + // Base address where DMI registers can be found in the APB address space + JLINK_ExecCommand("CORESIGHT_SetCoreBaseAddr = 0x5004C400"); + return 0; +} diff --git a/boards/nordic/nrf54l20pdk/Kconfig.defconfig b/boards/nordic/nrf54l20pdk/Kconfig.defconfig index f6987b800879a..406a65c882699 100644 --- a/boards/nordic/nrf54l20pdk/Kconfig.defconfig +++ b/boards/nordic/nrf54l20pdk/Kconfig.defconfig @@ -6,9 +6,6 @@ if BOARD_NRF54L20PDK_NRF54L20_CPUAPP config ROM_START_OFFSET default 0x800 if BOOTLOADER_MCUBOOT -config SOC_NRF54LX_SKIP_CLOCK_CONFIG - default y - config SOC_NRF54LX_SKIP_GLITCHDETECTOR_DISABLE default y diff --git a/boards/nordic/nrf54l20pdk/nrf54l20_cpuapp_common.dtsi b/boards/nordic/nrf54l20pdk/nrf54l20_cpuapp_common.dtsi index cdf6d62a30a7b..0d3c1fe98e999 100644 --- a/boards/nordic/nrf54l20pdk/nrf54l20_cpuapp_common.dtsi +++ b/boards/nordic/nrf54l20pdk/nrf54l20_cpuapp_common.dtsi @@ -27,6 +27,11 @@ status = "okay"; }; +&hfpll { + /* For now use 64 MHz clock for CPU and fast peripherals. */ + clock-frequency = ; +}; + &lfxo { load-capacitors = "internal"; load-capacitance-femtofarad = <15500>; diff --git a/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20-common.dtsi b/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20-common.dtsi index c188cd39e93da..35a434cda4b44 100644 --- a/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20-common.dtsi +++ b/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20-common.dtsi @@ -27,6 +27,19 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + /* + * PWM signal can be exposed on GPIO pin only within same domain. + * There is only one domain which contains both PWM and GPIO: + * PWM20/21/22 and GPIO Port P1/P3. + * Only LEDs connected to P1/P3 can work with PWM, for example LED1. + */ + pwm_led1: pwm_led_1 { + pwms = <&pwm20 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + buttons { compatible = "gpio-keys"; button0: button_0 { @@ -56,6 +69,7 @@ led1 = &led1; led2 = &led2; led3 = &led3; + pwm-led0 = &pwm_led1; sw0 = &button0; sw1 = &button1; sw2 = &button2; @@ -70,3 +84,10 @@ pinctrl-1 = <&uart20_sleep>; pinctrl-names = "default", "sleep"; }; + +&pwm20 { + status = "okay"; + pinctrl-0 = <&pwm20_default>; + pinctrl-1 = <&pwm20_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20-pinctrl.dtsi b/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20-pinctrl.dtsi index 83aa91d8a34a1..7dc2b77ae8336 100644 --- a/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20-pinctrl.dtsi +++ b/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20-pinctrl.dtsi @@ -21,4 +21,17 @@ low-power-enable; }; }; + + /omit-if-no-ref/ pwm20_default: pwm20_default { + group1 { + psels = ; + }; + }; + + /omit-if-no-ref/ pwm20_sleep: pwm20_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; }; diff --git a/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20_cpuapp.yaml b/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20_cpuapp.yaml index d11ea0d869fff..54ca6dd528f1a 100644 --- a/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20_cpuapp.yaml +++ b/boards/nordic/nrf54l20pdk/nrf54l20pdk_nrf54l20_cpuapp.yaml @@ -7,11 +7,14 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 512 flash: 449 supported: + - adc - counter - gpio + - i2c + - pwm + - watchdog diff --git a/boards/nordic/nrf7002dk/board.cmake b/boards/nordic/nrf7002dk/board.cmake index 3832c0d20c13d..51730b54e6f68 100644 --- a/boards/nordic/nrf7002dk/board.cmake +++ b/boards/nordic/nrf7002dk/board.cmake @@ -1,12 +1,9 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if(CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP OR - CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP_NRF7001) +if(CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP_NRF7001) board_runner_args(jlink "--device=nrf5340_xxaa_app" "--speed=4000") -endif() - -if(CONFIG_BOARD_NRF7002DK_NRF5340_CPUNET) +elseif(CONFIG_BOARD_NRF7002DK_NRF5340_CPUNET) board_runner_args(jlink "--device=nrf5340_xxaa_net" "--speed=4000") endif() diff --git a/boards/nordic/nrf7002dk/nrf5340_cpuapp_common.dtsi b/boards/nordic/nrf7002dk/nrf5340_cpuapp_common.dtsi index cff6e54fd5d7d..8a54d6da416c6 100644 --- a/boards/nordic/nrf7002dk/nrf5340_cpuapp_common.dtsi +++ b/boards/nordic/nrf7002dk/nrf5340_cpuapp_common.dtsi @@ -111,6 +111,15 @@ mcuboot-led0 = &led0; watchdog0 = &wdt0; }; + + nrf_radio_coex: coex { + status = "okay"; + compatible = "nordic,nrf7002-coex"; + req-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; + status0-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; + grant-gpios = <&gpio0 24 (GPIO_PULL_DOWN | GPIO_ACTIVE_LOW)>; + swctrl1-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; + }; }; &vregmain { diff --git a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp.yaml b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp.yaml index 9a6c653144247..707ab18abbc80 100644 --- a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp.yaml +++ b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 @@ -17,4 +16,5 @@ supported: - usbd - usb_device - netif:openthread + - netif:wifi vendor: nordic diff --git a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp_defconfig b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp_defconfig index c486d8323821a..49f3e03e2632d 100644 --- a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp_defconfig +++ b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp_defconfig @@ -18,3 +18,10 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y + +# Enable RNG +CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y +CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y + +# ISN needs CS-Rand which isn't supported upstream for nRF boards +CONFIG_NET_TCP_ISN_RFC6528=n diff --git a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp_nrf7001.yaml b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp_nrf7001.yaml index e74ba0628aba5..2607f08300434 100644 --- a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp_nrf7001.yaml +++ b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpuapp_nrf7001.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpunet.yaml b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpunet.yaml index f04ef6cee84ca..febd55d7fe332 100644 --- a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpunet.yaml +++ b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpunet.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/nordic/nrf9131ek/board.cmake b/boards/nordic/nrf9131ek/board.cmake index 8293a428b4013..d67464ff5ae36 100644 --- a/boards/nordic/nrf9131ek/board.cmake +++ b/boards/nordic/nrf9131ek/board.cmake @@ -8,7 +8,6 @@ if(CONFIG_TFM_FLASH_MERGED_BINARY) set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) endif() -# TODO: change to nRF9131_xxAA when such device is available in JLink -board_runner_args(jlink "--device=nRF9160_xxAA" "--speed=4000") +board_runner_args(jlink "--device=nRF9131_xxCA" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131.yaml b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131.yaml index 8cb2adc385f0f..22212b9a29c3d 100644 --- a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131.yaml +++ b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 1024 diff --git a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.yaml b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.yaml index c6e312066bf48..82aa310fe2cc8 100644 --- a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.yaml +++ b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 212 diff --git a/boards/nordic/nrf9151dk/board.cmake b/boards/nordic/nrf9151dk/board.cmake index a3126c941d982..dc898e054b4f2 100644 --- a/boards/nordic/nrf9151dk/board.cmake +++ b/boards/nordic/nrf9151dk/board.cmake @@ -8,7 +8,6 @@ if(CONFIG_TFM_FLASH_MERGED_BINARY) set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) endif() -# TODO: change to nRF9151_xxAA when such device is available in JLink -board_runner_args(jlink "--device=nRF9160_xxAA" "--speed=4000") +board_runner_args(jlink "--device=nRF9151_xxCA" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151.yaml b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151.yaml index aa4473d49ea36..733592265978b 100644 --- a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151.yaml +++ b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 1024 diff --git a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.yaml b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.yaml index 97e78ff373638..7ab511f711628 100644 --- a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.yaml +++ b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_0_14_0.yaml b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_0_14_0.yaml index 71e5bc2d0b398..1a33e5c9240a9 100644 --- a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_0_14_0.yaml +++ b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_0_14_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 1024 diff --git a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_0_7_0.yaml b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_0_7_0.yaml index 52a05c854556b..89fc6aac34a2e 100644 --- a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_0_7_0.yaml +++ b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_0_7_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 1024 diff --git a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns_0_14_0.yaml b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns_0_14_0.yaml index d610095afafe9..a16b89b7b64ee 100644 --- a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns_0_14_0.yaml +++ b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns_0_14_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 @@ -19,3 +18,4 @@ supported: - netif:modem - gpio vendor: nordic +sysbuild: true diff --git a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns_0_7_0.yaml b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns_0_7_0.yaml index 0faa84b38c948..ea5b804b2ce52 100644 --- a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns_0_7_0.yaml +++ b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns_0_7_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 @@ -19,3 +18,4 @@ supported: - netif:modem - gpio vendor: nordic +sysbuild: true diff --git a/boards/nordic/nrf9161dk/board.cmake b/boards/nordic/nrf9161dk/board.cmake index 883208b783260..6581b63965897 100644 --- a/boards/nordic/nrf9161dk/board.cmake +++ b/boards/nordic/nrf9161dk/board.cmake @@ -8,7 +8,6 @@ if(CONFIG_TFM_FLASH_MERGED_BINARY) set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) endif() -# TODO: change to nRF9161_xxAA when such device is available in JLink -board_runner_args(jlink "--device=nRF9160_xxAA" "--speed=4000") +board_runner_args(jlink "--device=nRF9161_xxCA" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_0_7_0.yaml b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_0_7_0.yaml index 9d9f07dc48b85..930b3a3ddd91b 100644 --- a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_0_7_0.yaml +++ b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_0_7_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 1024 diff --git a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_0_9_0.yaml b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_0_9_0.yaml index 55e021d3f681f..fad5afb0c8c2e 100644 --- a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_0_9_0.yaml +++ b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_0_9_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 88 flash: 1024 diff --git a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns_0_7_0.yaml b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns_0_7_0.yaml index c8224cafae41c..4d4a07965d6bc 100644 --- a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns_0_7_0.yaml +++ b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns_0_7_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns_0_9_0.yaml b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns_0_9_0.yaml index 13cf209bc2d06..f08145b5cbcb7 100644 --- a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns_0_9_0.yaml +++ b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns_0_9_0.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl.dtsi b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl.dtsi index 48067a7052c33..4cae3ba580ffc 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl.dtsi +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl.dtsi @@ -60,13 +60,6 @@ }; }; - /omit-if-no-ref/ can120_default: can120_default { - group1 { - psels = , - ; - }; - }; - /omit-if-no-ref/ pwm130_default: pwm130_default { group1 { psels = ; diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts index a380ac7473aad..11760974a11aa 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts @@ -27,7 +27,6 @@ zephyr,ieee802154 = &cpuapp_ieee802154; zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; - zephyr,canbus = &can120; }; aliases { @@ -275,16 +274,6 @@ zephyr_udc0: &usbhs { status = "okay"; }; -&canpll { - status = "okay"; -}; - -&can120 { - status = "okay"; - pinctrl-0 = <&can120_default>; - pinctrl-names = "default"; -}; - &pwm130 { status = "okay"; pinctrl-0 = <&pwm130_default>; diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.yaml b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.yaml index 9c2aff88052d1..d4bc799100dd2 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.yaml +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.yaml @@ -7,14 +7,12 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 512 flash: 1024 supported: - adc - - can - counter - gpio - i2c diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad.yaml b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad.yaml index 543a7377c1d3f..59ed708713fe4 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad.yaml +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad.yaml @@ -7,7 +7,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr sysbuild: true ram: 32 diff --git a/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript b/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript index 5791a7bed9b12..b1b968573991f 100644 --- a/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript +++ b/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript @@ -1,260 +1,12 @@ -// Constants specific to the application core __constant U32 _CPUCONF_ADDR = 0x52011000; -__constant U32 _PROCESSOR_ID = 2; -__constant U32 _DOMAIN_ID = 2; -__constant U32 _NUM_OTHER_PROCESSORS = 2; -const U32 _OTHER_PROCESSOR_IDS[2] = {4, 3}; - -// Debug Halting Control and Status Register -__constant U32 _DHCSR_ADDR = 0xE000EDF0; -__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); -__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); -__constant U32 _DHCSR_C_HALT = (1 << 1); - -// Debug Exception and Monitor Control Register -__constant U32 _DEMCR_ADDR = 0xE000EDFC; -__constant U32 _DEMCR_VC_CORERESET = (1 << 0); -__constant U32 _DEMCR_TRCENA = (1 << 24); - -// CPU wait enable register __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C; -// CTRL-AP -__constant U32 _CTRLAP_ID = 4; -__constant U32 _CTRLAP_READY_BANK = 0; -__constant U32 _CTRLAP_READY_OFFSET = 1; -__constant U32 _CTRLAP_READY = 0; -__constant U32 _CTRLAP_MAILBOX_BANK = 1; -__constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0; -__constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1; -__constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2; -__constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3; -__constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0; -__constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1; -__constant int _CTRLAP_TIMEOUT_MS = 500; - -// ADAC transaction buffers -static U32 _adacTx[20]; -static U32 _adacRx[20]; - -// Failed to send to the CTRL-AP MAILBOX -__constant int _ERR_TX = -1; -// Failed to receive from the CTRL-AP MAILBOX -__constant int _ERR_RX = -2; -// ADAC command returned an error -__constant int _ERR_REPLY = -3; - -// Wait for an AP register read to return the expected value. -int _WaitForDataStatus(U32 regOffset, int expectedStatus) -{ - int status; - int ret; - int start; - int elapsed; - - status = 0; - start = JLINK_GetTime(); - elapsed = 0; - - do { - ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status); - elapsed = JLINK_GetTime() - start; - } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS)); - - if (ret < 0) { - return ret; - } - - return status; -} - -// Continuously read from the CTRL-AP MAILBOX until there is no more pending data. -void _DrainMailbox(void) -{ - int ret; - int status; - int data; - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - } -} - -// Perform an ADAC transaction by: -// * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS -// readiness before each write. -// * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before -// each read. -// -// The message to send is read from _adacTx and the reply is written to _adacRx. -// Optionally checks if a single data word is returned and returns an error if it is non-zero. -// -// Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP. -int _DoAdacTransaction(int checkReplyStatus) -{ - int numWords; - int ret; - int data; - int i; - - i = 0; - numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET, - _CTRLAP_MAILBOX_NO_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ", - ret); - return _ERR_TX; - } - - ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]); - if (ret < 0) { - JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret); - return _ERR_TX; - } - - i += 1; - } - - i = 0; - numWords = 2; // Minimum message length - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, - _CTRLAP_MAILBOX_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - if (ret < 0) { - JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - if (i == 1) { - // Update total length based on the message length field - numWords = 2 + (data >> 2); - } - - _adacRx[i] = data; - i += 1; - } - - if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) { - JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]); - return _ERR_REPLY; - } - - return 0; -} - -int ResetTarget(void) +int SetupTarget(void) { - int err; - U32 adacMajorVersion; - U32 i; - - // Select CTRL-AP bank 0, used for the READY register - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4)); - - // Wait for the READY register to indicate that the AP can be used. - err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY); - if (err < 0) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err); - return -1; - } - - // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4)); - - // Extract any pre-existing data from the mailbox in case there was previously - // an aborted transaction. - _DrainMailbox(); - - // Read the ADAC version - _adacTx[0] = 0xA3000000; // Command VERSION - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // Type 0 (ADAC version) - err = _DoAdacTransaction(0); - if (err < 0) { - return -1; - } - - adacMajorVersion = (_adacRx[2] >> 24) & 0xff; - JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion); - - if (adacMajorVersion >= 2) { - // There is a very small chance that this command fails if the domain reset itself - // at the exact same time the command was issued. Therefore we retry a few times. - i = 0; - while (i < 3) { - // Reset non-essential domains - _adacTx[0] = 0xA30A0000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // (reserved) - err = _DoAdacTransaction(1); - if (err >= 0) { - break; - } else if (err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - - // Start the core in halted mode - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - - // Start other cores normally (will fail silently if no firmware is present) - i = 0; - while (i < _NUM_OTHER_PROCESSORS) { - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000 | - (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags - err = _DoAdacTransaction(0); - if (err < 0 && err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - } else { - // Reset single domain via legacy implementation - _adacTx[0] = 0xA3030000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - } - - // Halt the CPU - JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); - - // Set vector catch on reset (to halt the CPU immediately after reset) - JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + JLINK_TARGET_Halt(); // Disable CPU wait JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); - // Clear vector catch stuff - JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); - return 0; } diff --git a/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript b/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript index 02b84dcc970a3..e1861ae8c972a 100644 --- a/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript +++ b/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript @@ -1,159 +1,6 @@ -// Constants specific to the radio core __constant U32 _CPUCONF_ADDR = 0x53011000; -__constant U32 _PROCESSOR_ID = 3; -__constant U32 _DOMAIN_ID = 3; -__constant U32 _NUM_OTHER_PROCESSORS = 2; -const U32 _OTHER_PROCESSOR_IDS[2] = {4, 2}; - -// Debug Halting Control and Status Register -__constant U32 _DHCSR_ADDR = 0xE000EDF0; -__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); -__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); -__constant U32 _DHCSR_C_HALT = (1 << 1); - -// Debug Exception and Monitor Control Register -__constant U32 _DEMCR_ADDR = 0xE000EDFC; -__constant U32 _DEMCR_VC_CORERESET = (1 << 0); -__constant U32 _DEMCR_TRCENA = (1 << 24); - -// CPU wait enable register __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C; -// CTRL-AP -__constant U32 _CTRLAP_ID = 4; -__constant U32 _CTRLAP_READY_BANK = 0; -__constant U32 _CTRLAP_READY_OFFSET = 1; -__constant U32 _CTRLAP_READY = 0; -__constant U32 _CTRLAP_MAILBOX_BANK = 1; -__constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0; -__constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1; -__constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2; -__constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3; -__constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0; -__constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1; -__constant int _CTRLAP_TIMEOUT_MS = 500; - -// ADAC transaction buffers -static U32 _adacTx[20]; -static U32 _adacRx[20]; - -// Failed to send to the CTRL-AP MAILBOX -__constant int _ERR_TX = -1; -// Failed to receive from the CTRL-AP MAILBOX -__constant int _ERR_RX = -2; -// ADAC command returned an error -__constant int _ERR_REPLY = -3; - -// Wait for an AP register read to return the expected value. -int _WaitForDataStatus(U32 regOffset, int expectedStatus) -{ - int status; - int ret; - int start; - int elapsed; - - status = 0; - start = JLINK_GetTime(); - elapsed = 0; - - do { - ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status); - elapsed = JLINK_GetTime() - start; - } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS)); - - if (ret < 0) { - return ret; - } - - return status; -} - -// Continuously read from the CTRL-AP MAILBOX until there is no more pending data. -void _DrainMailbox(void) -{ - int ret; - int status; - int data; - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - } -} - -// Perform an ADAC transaction by: -// * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS -// readiness before each write. -// * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before -// each read. -// -// The message to send is read from _adacTx and the reply is written to _adacRx. -// Optionally checks if a single data word is returned and returns an error if it is non-zero. -// -// Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP. -int _DoAdacTransaction(int checkReplyStatus) -{ - int numWords; - int ret; - int data; - int i; - - i = 0; - numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET, - _CTRLAP_MAILBOX_NO_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ", - ret); - return _ERR_TX; - } - - ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]); - if (ret < 0) { - JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret); - return _ERR_TX; - } - - i += 1; - } - - i = 0; - numWords = 2; // Minimum message length - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, - _CTRLAP_MAILBOX_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - if (ret < 0) { - JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - if (i == 1) { - // Update total length based on the message length field - numWords = 2 + (data >> 2); - } - - _adacRx[i] = data; - i += 1; - } - - if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) { - JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]); - return _ERR_REPLY; - } - - return 0; -} - int ConfigTargetSettings(void) { JLINK_ExecCommand("CORESIGHT_AddAP = Index=1 Type=AHB-AP"); @@ -162,107 +9,12 @@ int ConfigTargetSettings(void) return 0; } -int ResetTarget(void) +int SetupTarget(void) { - int err; - U32 adacMajorVersion; - U32 i; - - // Select CTRL-AP bank 0, used for the READY register - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4)); - - // Wait for the READY register to indicate that the AP can be used. - err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY); - if (err < 0) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err); - return -1; - } - - // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4)); - - // Extract any pre-existing data from the mailbox in case there was previously - // an aborted transaction. - _DrainMailbox(); - - // Read the ADAC version - _adacTx[0] = 0xA3000000; // Command VERSION - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // Type 0 (ADAC version) - err = _DoAdacTransaction(0); - if (err < 0) { - return -1; - } - - adacMajorVersion = (_adacRx[2] >> 24) & 0xff; - JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion); - - if (adacMajorVersion >= 2) { - // There is a very small chance that this command fails if the domain reset itself - // at the exact same time the command was issued. Therefore we retry a few times. - i = 0; - while (i < 3) { - // Reset non-essential domains - _adacTx[0] = 0xA30A0000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // (reserved) - err = _DoAdacTransaction(1); - if (err >= 0) { - break; - } else if (err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - - // Start the core in halted mode - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - - // Start other cores normally (will fail silently if no firmware is present) - i = 0; - while (i < _NUM_OTHER_PROCESSORS) { - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000 | - (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags - err = _DoAdacTransaction(0); - if (err < 0 && err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - } else { - // Reset single domain via legacy implementation - _adacTx[0] = 0xA3030000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - } - - // Halt the CPU - JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); - - // Set vector catch on reset (to halt the CPU immediately after reset) - JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + JLINK_TARGET_Halt(); // Disable CPU wait JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); - // Clear vector catch stuff - JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); - return 0; } diff --git a/boards/nordic/thingy52/thingy52_nrf52832.yaml b/boards/nordic/thingy52/thingy52_nrf52832.yaml index a49aeaba6ce45..80b97596bdea2 100644 --- a/boards/nordic/thingy52/thingy52_nrf52832.yaml +++ b/boards/nordic/thingy52/thingy52_nrf52832.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/nordic/thingy53/Kconfig b/boards/nordic/thingy53/Kconfig index 01b2ee7dfcff0..a6781f63b0e24 100644 --- a/boards/nordic/thingy53/Kconfig +++ b/boards/nordic/thingy53/Kconfig @@ -11,10 +11,6 @@ config THINGY53_INIT_PRIORITY if BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS -config BOARD_SERIAL_BACKEND_CDC_ACM - bool "USB CDC" - default y - config DOMAIN_CPUNET_BOARD string default "thingy53/nrf5340/cpunet" diff --git a/boards/nordic/thingy53/Kconfig.defconfig b/boards/nordic/thingy53/Kconfig.defconfig index 885318feb7e92..d149d360f8595 100644 --- a/boards/nordic/thingy53/Kconfig.defconfig +++ b/boards/nordic/thingy53/Kconfig.defconfig @@ -79,58 +79,7 @@ config REGULATOR endif # !TRUSTED_EXECUTION_SECURE -if BOARD_SERIAL_BACKEND_CDC_ACM - -config USB_DEVICE_PRODUCT - default "Thingy:53 Application" - -config USB_DEVICE_VID - default 0x1915 - -config USB_DEVICE_PID - default 0x530C - -config USB_DEVICE_STACK - default y - -config USB_CDC_ACM - default y - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y if !MCUBOOT - -config SHELL_BACKEND_SERIAL_CHECK_DTR - default SHELL - depends on UART_LINE_CTRL - -config UART_LINE_CTRL - default SHELL - -config USB_DEVICE_REMOTE_WAKEUP - default n - -if LOG - -# Logger cannot use itself to log -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF -endchoice - -# Set USB log level to error only -choice USB_DEVICE_LOG_LEVEL_CHOICE - default USB_DEVICE_LOG_LEVEL_ERR -endchoice - -# Wait 4000ms at startup for logging -config LOG_PROCESS_THREAD_STARTUP_DELAY_MS - default 4000 - -endif # LOG - -endif # BOARD_SERIAL_BACKEND_CDC_ACM +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS diff --git a/boards/nordic/thingy53/thingy53_nrf5340_common.dtsi b/boards/nordic/thingy53/thingy53_nrf5340_common.dtsi index 12b7cf6c13bb6..72471a0c95edd 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_common.dtsi +++ b/boards/nordic/thingy53/thingy53_nrf5340_common.dtsi @@ -9,11 +9,6 @@ / { chosen { - zephyr,console = &cdc_acm_uart; - zephyr,shell-uart = &cdc_acm_uart; - zephyr,uart-mcumgr = &cdc_acm_uart; - zephyr,bt-mon-uart = &cdc_acm_uart; - zephyr,bt-c2h-uart = &cdc_acm_uart; zephyr,bt-hci-ipc = &ipc0; zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; @@ -316,10 +311,6 @@ edge_connector_spi: &spi4 { zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - cdc_acm_uart: cdc_acm_uart { - compatible = "zephyr,cdc-acm-uart"; - }; }; /* Include default memory partition configuration file */ diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.dts b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.dts index 41d287c8ebab9..9f3d7d46674c2 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.dts +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include "thingy53_nrf5340_common.dtsi" +#include <../boards/common/usb/cdc_acm_serial.dtsi> / { model = "Nordic Thingy53 NRF5340 Application"; diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml index bc3d8de14b639..c5b5c71d3d62c 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts index 1ac7536fb007b..8a754664325ba 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include "thingy53_nrf5340_common.dtsi" +#include <../boards/common/usb/cdc_acm_serial.dtsi> / { model = "Nordic Thingy53 NRF5340 Application"; diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml index a48325cb57f63..8d9787515e6a0 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 192 flash: 192 diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpunet.yaml b/boards/nordic/thingy53/thingy53_nrf5340_cpunet.yaml index c039c5ad9f445..42d7dd6ac1443 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpunet.yaml +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpunet.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/norik/octopus_io_board/doc/index.rst b/boards/norik/octopus_io_board/doc/index.rst index bf520d05d8ad3..088a3b936d38f 100644 --- a/boards/norik/octopus_io_board/doc/index.rst +++ b/boards/norik/octopus_io_board/doc/index.rst @@ -142,5 +142,5 @@ References .. target-notes:: -.. _Octopus IO-Board Product Page: https://www.norik.com/2024/09/16/octopus-io-board/ +.. _Octopus IO-Board Product Page: https://www.norik.com/octopus-io-board/ .. _Octopus IO-Board Documentation: https://www.norik.com/wp-content/uploads/2024/09/Octopus_IO-Board_Datasheet.pdf diff --git a/boards/norik/octopus_io_board/octopus_io_board_nrf9160.yaml b/boards/norik/octopus_io_board/octopus_io_board_nrf9160.yaml index e91c1da14b57d..d066558c2c991 100644 --- a/boards/norik/octopus_io_board/octopus_io_board_nrf9160.yaml +++ b/boards/norik/octopus_io_board/octopus_io_board_nrf9160.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.yaml b/boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.yaml index 675c316f6c28c..6d541fb1b3eed 100644 --- a/boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.yaml +++ b/boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.yaml @@ -7,7 +7,6 @@ flash: 192 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/norik/octopus_som/doc/index.rst b/boards/norik/octopus_som/doc/index.rst index 9949344233c60..1d3790a04d701 100644 --- a/boards/norik/octopus_som/doc/index.rst +++ b/boards/norik/octopus_som/doc/index.rst @@ -121,5 +121,5 @@ References .. target-notes:: -.. _Octopus SoM Product Page: https://www.norik.com/2024/09/16/octopus-som/ +.. _Octopus SoM Product Page: https://www.norik.com/octopus-som/ .. _Octopus SoM Documentation: https://www.norik.com/wp-content/uploads/2024/09/Octopus_SoM_Datasheet.pdf diff --git a/boards/norik/octopus_som/octopus_som_nrf9160.yaml b/boards/norik/octopus_som/octopus_som_nrf9160.yaml index 44a13234b8afa..f4eafba8e6bd0 100644 --- a/boards/norik/octopus_som/octopus_som_nrf9160.yaml +++ b/boards/norik/octopus_som/octopus_som_nrf9160.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/norik/octopus_som/octopus_som_nrf9160_ns.yaml b/boards/norik/octopus_som/octopus_som_nrf9160_ns.yaml index 85bb40d75ab19..dd306bb662191 100644 --- a/boards/norik/octopus_som/octopus_som_nrf9160_ns.yaml +++ b/boards/norik/octopus_som/octopus_som_nrf9160_ns.yaml @@ -7,7 +7,6 @@ flash: 192 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/nuvoton/numaker_m2l31ki/numaker_m2l31ki.yaml b/boards/nuvoton/numaker_m2l31ki/numaker_m2l31ki.yaml index 3ed0f87a06cf0..e553c0c800ece 100644 --- a/boards/nuvoton/numaker_m2l31ki/numaker_m2l31ki.yaml +++ b/boards/nuvoton/numaker_m2l31ki/numaker_m2l31ki.yaml @@ -8,7 +8,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 168 flash: 512 supported: diff --git a/boards/nuvoton/numaker_pfm_m467/numaker_pfm_m467.yaml b/boards/nuvoton/numaker_pfm_m467/numaker_pfm_m467.yaml index a7e26960ae6a5..3f709b8447d92 100644 --- a/boards/nuvoton/numaker_pfm_m467/numaker_pfm_m467.yaml +++ b/boards/nuvoton/numaker_pfm_m467/numaker_pfm_m467.yaml @@ -8,7 +8,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 1024 supported: diff --git a/boards/nuvoton/numaker_pfm_m487/numaker_pfm_m487.yaml b/boards/nuvoton/numaker_pfm_m487/numaker_pfm_m487.yaml index 396f6780698e7..0c747394be294 100644 --- a/boards/nuvoton/numaker_pfm_m487/numaker_pfm_m487.yaml +++ b/boards/nuvoton/numaker_pfm_m487/numaker_pfm_m487.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 160 flash: 512 vendor: nuvoton diff --git a/boards/nxp/frdm_k22f/frdm_k22f.dts b/boards/nxp/frdm_k22f/frdm_k22f.dts index 3a927b3de6d2d..69439718a36de 100644 --- a/boards/nxp/frdm_k22f/frdm_k22f.dts +++ b/boards/nxp/frdm_k22f/frdm_k22f.dts @@ -153,7 +153,7 @@ arduino_spi: &spi0 { &ftm0 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm0_default>; pinctrl-names = "default"; diff --git a/boards/nxp/frdm_k64f/frdm_k64f.dts b/boards/nxp/frdm_k64f/frdm_k64f.dts index 9cb864ccf3897..100dd6e69dc99 100644 --- a/boards/nxp/frdm_k64f/frdm_k64f.dts +++ b/boards/nxp/frdm_k64f/frdm_k64f.dts @@ -172,7 +172,7 @@ arduino_spi: &spi0 { &ftm0 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm0_default>; pinctrl-names = "default"; @@ -181,7 +181,7 @@ arduino_spi: &spi0 { &ftm3 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm3_default>; pinctrl-names = "default"; diff --git a/boards/nxp/frdm_k64f/frdm_k64f.yaml b/boards/nxp/frdm_k64f/frdm_k64f.yaml index 578ac4edd0d9b..11cff339ce93a 100644 --- a/boards/nxp/frdm_k64f/frdm_k64f.yaml +++ b/boards/nxp/frdm_k64f/frdm_k64f.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/nxp/frdm_k64f/support/pyocd.yaml b/boards/nxp/frdm_k64f/support/pyocd.yaml new file mode 100644 index 0000000000000..ded7208f43cb6 --- /dev/null +++ b/boards/nxp/frdm_k64f/support/pyocd.yaml @@ -0,0 +1,2 @@ +connect_mode: 'under-reset' +reset_type: 'hw' diff --git a/boards/nxp/frdm_k82f/frdm_k82f.dts b/boards/nxp/frdm_k82f/frdm_k82f.dts index a221b53e24d6b..d28c32e512751 100644 --- a/boards/nxp/frdm_k82f/frdm_k82f.dts +++ b/boards/nxp/frdm_k82f/frdm_k82f.dts @@ -206,7 +206,7 @@ &ftm3 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm3_default>; pinctrl-names = "default"; diff --git a/boards/nxp/frdm_k82f/frdm_k82f.yaml b/boards/nxp/frdm_k82f/frdm_k82f.yaml index 2a4c29652cbbc..1ca2c1ed3eb45 100644 --- a/boards/nxp/frdm_k82f/frdm_k82f.yaml +++ b/boards/nxp/frdm_k82f/frdm_k82f.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 256 supported: diff --git a/boards/nxp/frdm_ke15z/frdm_ke15z.yaml b/boards/nxp/frdm_ke15z/frdm_ke15z.yaml index bb9212fc7b55d..c7296fc12ea37 100644 --- a/boards/nxp/frdm_ke15z/frdm_ke15z.yaml +++ b/boards/nxp/frdm_ke15z/frdm_ke15z.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 24 supported: diff --git a/boards/nxp/frdm_ke17z/frdm_ke17z.dts b/boards/nxp/frdm_ke17z/frdm_ke17z.dts index 9b5e3aaa4b8ad..08590e6ee66e7 100644 --- a/boards/nxp/frdm_ke17z/frdm_ke17z.dts +++ b/boards/nxp/frdm_ke17z/frdm_ke17z.dts @@ -126,7 +126,7 @@ &ftm2 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; clocks = <&scg KINETIS_SCG_SIRC_CLK>; prescaler = <128>; diff --git a/boards/nxp/frdm_ke17z/frdm_ke17z.yaml b/boards/nxp/frdm_ke17z/frdm_ke17z.yaml index 17ccc33e8713a..cf4b8c2b0be24 100644 --- a/boards/nxp/frdm_ke17z/frdm_ke17z.yaml +++ b/boards/nxp/frdm_ke17z/frdm_ke17z.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - counter diff --git a/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts b/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts index 05c050bfdf1fc..c4c42776e2964 100644 --- a/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts +++ b/boards/nxp/frdm_ke17z512/frdm_ke17z512.dts @@ -143,7 +143,7 @@ &ftm2 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; clocks = <&scg KINETIS_SCG_SIRC_CLK>; prescaler = <128>; diff --git a/boards/nxp/frdm_ke17z512/frdm_ke17z512.yaml b/boards/nxp/frdm_ke17z512/frdm_ke17z512.yaml index 3b9dae0fa6b36..9f19b417ed39b 100644 --- a/boards/nxp/frdm_ke17z512/frdm_ke17z512.yaml +++ b/boards/nxp/frdm_ke17z512/frdm_ke17z512.yaml @@ -13,7 +13,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/nxp/frdm_kl25z/frdm_kl25z.yaml b/boards/nxp/frdm_kl25z/frdm_kl25z.yaml index 79c0082e156a7..de25dbba93749 100644 --- a/boards/nxp/frdm_kl25z/frdm_kl25z.yaml +++ b/boards/nxp/frdm_kl25z/frdm_kl25z.yaml @@ -7,7 +7,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/nxp/frdm_kw41z/frdm_kw41z.yaml b/boards/nxp/frdm_kw41z/frdm_kw41z.yaml index 9855726bc16a5..1697439dffbd3 100644 --- a/boards/nxp/frdm_kw41z/frdm_kw41z.yaml +++ b/boards/nxp/frdm_kw41z/frdm_kw41z.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/nxp/frdm_mcxa156/Kconfig.defconfig b/boards/nxp/frdm_mcxa156/Kconfig.defconfig new file mode 100644 index 0000000000000..117b55f95e843 --- /dev/null +++ b/boards/nxp/frdm_mcxa156/Kconfig.defconfig @@ -0,0 +1,15 @@ +# FRDM-MCXA156 board + +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_FRDM_MCXA156 + +if BOOTLOADER_MCUBOOT +choice MCUBOOT_BOOTLOADER_MODE + # Board only supports MCUBoot via "upgrade only" method: + default MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY +endchoice +endif #BOOTLOADER_MCUBOOT + +endif # BOARD_FRDM_MCXA156 diff --git a/boards/nxp/frdm_mcxa156/Kconfig.sysbuild b/boards/nxp/frdm_mcxa156/Kconfig.sysbuild new file mode 100644 index 0000000000000..4625c7d2929d2 --- /dev/null +++ b/boards/nxp/frdm_mcxa156/Kconfig.sysbuild @@ -0,0 +1,6 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice diff --git a/boards/nxp/frdm_mcxa156/board.c b/boards/nxp/frdm_mcxa156/board.c index 26e42979ed86c..6c2da318025f8 100644 --- a/boards/nxp/frdm_mcxa156/board.c +++ b/boards/nxp/frdm_mcxa156/board.c @@ -116,6 +116,36 @@ static int frdm_mcxa156_init(void) CLOCK_AttachClk(kFRO12M_to_LPUART0); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart1)) + CLOCK_SetClockDiv(kCLOCK_DivLPUART1, 1u); + CLOCK_AttachClk(kFRO12M_to_LPUART1); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer0)) + CLOCK_SetClockDiv(kCLOCK_DivCTIMER0, 1u); + CLOCK_AttachClk(kFRO_HF_to_CTIMER0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer1)) + CLOCK_SetClockDiv(kCLOCK_DivCTIMER1, 1u); + CLOCK_AttachClk(kFRO_HF_to_CTIMER1); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer2)) + CLOCK_SetClockDiv(kCLOCK_DivCTIMER2, 1u); + CLOCK_AttachClk(kFRO_HF_to_CTIMER2); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer3)) + CLOCK_SetClockDiv(kCLOCK_DivCTIMER3, 1u); + CLOCK_AttachClk(kFRO_HF_to_CTIMER3); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ctimer4)) + CLOCK_SetClockDiv(kCLOCK_DivCTIMER4, 1u); + CLOCK_AttachClk(kFRO_HF_to_CTIMER4); +#endif + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dac0)) SPC_EnableActiveModeAnalogModules(SPC0, kSPC_controlDac0); CLOCK_SetClockDiv(kCLOCK_DivDAC0, 1u); @@ -124,6 +154,88 @@ static int frdm_mcxa156_init(void) CLOCK_EnableClock(kCLOCK_GateDAC0); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcan0)) + CLOCK_SetClockDiv(kCLOCK_DivFLEXCAN0, 1U); + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); + CLOCK_AttachClk(kFRO_HF_DIV_to_FLEXCAN0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexio0)) + CLOCK_SetClockDiv(kCLOCK_DivFLEXIO0, 1u); + CLOCK_AttachClk(kFRO_HF_to_FLEXIO0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpadc0)) + CLOCK_SetClockDiv(kCLOCK_DivADC0, 1u); + CLOCK_AttachClk(kFRO12M_to_ADC0); + + CLOCK_EnableClock(kCLOCK_GateADC0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpcmp0)) + CLOCK_AttachClk(kFRO12M_to_CMP0); + CLOCK_SetClockDiv(kCLOCK_DivCMP0_FUNC, 1U); + SPC_EnableActiveModeAnalogModules(SPC0, (kSPC_controlCmp0 | kSPC_controlCmp0Dac)); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c0)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C0, 1u); + CLOCK_AttachClk(kFRO12M_to_LPI2C0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c1)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C1, 1u); + CLOCK_AttachClk(kFRO12M_to_LPI2C1); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c2)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C2, 1u); + CLOCK_AttachClk(kFRO12M_to_LPI2C2); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c3)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C3, 1u); + CLOCK_AttachClk(kFRO12M_to_LPI2C3); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi0)) + CLOCK_SetClockDiv(kCLOCK_DivLPSPI0, 1u); + CLOCK_AttachClk(kFRO12M_to_LPSPI0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi1)) + CLOCK_SetClockDiv(kCLOCK_DivLPSPI1, 1u); + CLOCK_AttachClk(kFRO12M_to_LPSPI1); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lptmr0)) + +/* + * Clock Select Decides what input source the lptmr will clock from + * + * 0 <- Reserved + * 1 <- 16K FRO + * 2 <- Reserved + * 3 <- Combination of clocks configured in MRCC_LPTMR0_CLKSEL[MUX] field + */ +#if DT_PROP(DT_NODELABEL(lptmr0), clk_source) == 0x1 + CLOCK_SetupFRO16KClocking(kCLKE_16K_SYSTEM | kCLKE_16K_COREMAIN); +#elif DT_PROP(DT_NODELABEL(lptmr0), clk_source) == 0x3 + CLOCK_SetClockDiv(kCLOCK_DivLPTMR0, 1u); + CLOCK_AttachClk(kFRO12M_to_LPTMR0); +#endif /* DT_PROP(DT_NODELABEL(lptmr0), clk_source) */ + +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb)) + RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); + CLOCK_EnableUsbfsClock(); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(wwdt0)) + CLOCK_SetClockDiv(kCLOCK_DivWWDT0, 1u); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; diff --git a/boards/nxp/frdm_mcxa156/doc/index.rst b/boards/nxp/frdm_mcxa156/doc/index.rst index 75d115fc627cd..8ca81d53e7921 100644 --- a/boards/nxp/frdm_mcxa156/doc/index.rst +++ b/boards/nxp/frdm_mcxa156/doc/index.rst @@ -4,11 +4,11 @@ Overview ******** FRDM-MCXA156 are compact and scalable development boards for rapid prototyping of -MCX A15X MCUs. They offer industry standard headers for easy access to the -MCUs I/Os, integrated open-standard serial interfaces, external flash memory and -an on-board MCU-Link debugger. MCX N Series are high-performance, low-power -microcontrollers with intelligent peripherals and accelerators providing multi-tasking -capabilities and performance efficiency. +MCX A144/5/6 A154/5/6 MCUs. They offer industry standard headers for easy access +to the MCU's I/Os, integrated open-standard serial interfaces, external flash +memory and an on-board MCU-Link debugger. Additional tools like our Expansion +Board Hub for add-on boards and the Application Code Hub for software examples +are available through the MCUXpresso Developer Experience. Hardware ******** @@ -16,8 +16,8 @@ Hardware - MCX-A156 Arm Cortex-M33 microcontroller running at 96 MHz - 1MB dual-bank on chip Flash - 128 KB RAM -- USB high-speed (Host/Device) with on-chip HS PHY. HS USB Type-C connectors -- 2x FlexCAN with FD, 2x I3Cs, 2x SAI +- USB full-speed with on-chip FS PHY. USB Type-C connectors +- 1x FlexCAN with FD, 1x I3Cs - On-board MCU-Link debugger with CMSIS-DAP - Arduino Header, FlexIO/LCD Header, SmartDMA/Camera Header, mikroBUS @@ -54,10 +54,35 @@ The FRDM-MCXA156 board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | FLASH | on-chip | soc flash | +-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| CTIMER | on-chip | counter | ++-----------+------------+-------------------------------------+ | DAC | on-chip | dac | +-----------+------------+-------------------------------------+ +| DMA | on-chip | dma | ++-----------+------------+-------------------------------------+ +| FLEXCAN | on-chip | CAN | ++-----------+------------+-------------------------------------+ +| FLEXIO | on-chip | flexio | ++-----------+------------+-------------------------------------+ +| DISPLAY | on-chip | flexio; MIPI-DBI. Tested with | +| | | :ref:`lcd_par_s035` | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| LPCMP | on-chip | sensor(comparator) | ++-----------+------------+-------------------------------------+ +| LPSPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| LPTMR | on-chip | counter | ++-----------+------------+-------------------------------------+ | PWM | on-chip | pwm | +-----------+------------+-------------------------------------+ +| USB | on-chip | USB device | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ Targets available ================== diff --git a/boards/nxp/frdm_mcxa156/frdm_mcxa156-pinctrl.dtsi b/boards/nxp/frdm_mcxa156/frdm_mcxa156-pinctrl.dtsi index 73a8a4a79cb1d..1ab107e4f4c3b 100644 --- a/boards/nxp/frdm_mcxa156/frdm_mcxa156-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxa156/frdm_mcxa156-pinctrl.dtsi @@ -16,6 +16,15 @@ input-enable; }; }; + pinmux_lpuart1: pinmux_lpuart1 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + input-enable; + }; + }; pinmux_dac0: pinmux_dac0 { group0 { pinmux = ; @@ -23,6 +32,55 @@ slew-rate = "fast"; }; }; + pinmux_flexcan0: pinmux_flexcan0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; + pinmux_flexio_lcd: pinmux_flexio_lcd { + group0 { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + group1 { + pinmux = ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + bias-pull-up; + }; + group2 { + pinmux = ; + slew-rate = "slow"; + drive-strength = "low"; + input-enable; + bias-pull-up; + }; + }; pinmux_flexpwm0_pwm0: pinmux_flexpwm0_pwm0 { group0 { pinmux = , @@ -31,4 +89,64 @@ drive-strength = "low"; }; }; + pinmux_lpadc0: pinmux_lpadc0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + }; + }; + pinmux_lpcmp0: pinmux_lpcmp0 { + group0 { + pinmux = ; + drive-strength = "low"; + slew-rate = "fast"; + bias-pull-up; + }; + }; + pinmux_lpi2c0: pinmux_lpi2c0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + bias-pull-up; + drive-open-drain; + }; + }; + pinmux_lpi2c2: pinmux_lpi2c2 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + bias-pull-up; + drive-open-drain; + }; + }; + pinmux_lpi2c3: pinmux_lpi2c3 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + bias-pull-up; + drive-open-drain; + }; + }; + pinmux_lpspi0: pinmux_lpspi0 { + group0 { + pinmux = , + , + , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; }; diff --git a/boards/nxp/frdm_mcxa156/frdm_mcxa156.dts b/boards/nxp/frdm_mcxa156/frdm_mcxa156.dts index 9407ba1a23515..8d8c07fe7ceb2 100644 --- a/boards/nxp/frdm_mcxa156/frdm_mcxa156.dts +++ b/boards/nxp/frdm_mcxa156/frdm_mcxa156.dts @@ -21,14 +21,19 @@ sw0 = &user_button_2; sw1 = &user_button_3; pwm-0 = &flexpwm0_pwm0; + mcuboot-button0 = &user_button_2; + watchdog0 = &wwdt0; }; chosen { zephyr,sram = &sram0; zephyr,flash = &flash; zephyr,flash-controller = &fmu; + zephyr,code-partition = &slot0_partition; zephyr,console = &lpuart0; zephyr,shell-uart = &lpuart0; + zephyr,uart-mcumgr = &lpuart0; + zephyr,canbus = &flexcan0; }; leds { @@ -61,6 +66,18 @@ }; }; + /* + * This node describes the GPIO pins of the LCD-PAR-S035 panel 8080 interface. + */ + nxp_lcd_8080_connector: lcd-8080-connector { + compatible = "nxp,lcd-8080"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <9 0 &gpio2 15 0>, /* Pin 9, LCD touch INT */ + <10 0 &gpio3 22 0>, /* Pin 10, LCD backlight control */ + <11 0 &gpio3 0 0>; /* Pin 11, LCD and touch reset */ + }; }; &gpio0 { @@ -90,14 +107,129 @@ pinctrl-names = "default"; }; +&lpuart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart1>; + pinctrl-names = "default"; +}; + +&ctimer0 { + status = "okay"; +}; + &dac0 { status = "okay"; pinctrl-0 = <&pinmux_dac0>; pinctrl-names = "default"; }; +&edma0 { + status = "okay"; +}; + +&flexcan0 { + status = "okay"; + pinctrl-0 = <&pinmux_flexcan0>; + pinctrl-names = "default"; +}; + +&flexio0 { + status = "okay"; +}; + +nxp_8080_touch_panel_i2c: &lpi2c2 { + pinctrl-0 = <&pinmux_lpi2c2>; + pinctrl-names = "default"; +}; + +zephyr_mipi_dbi_parallel: &flexio0_lcd { + /* DMA channels 0, muxed to FlexIO TX */ + dmas = <&edma0 0 71>; + dma-names = "tx"; + shifters-count = <4>; + timers-count = <1>; + enwr-pin = <31>; + rd-pin = <28>; + data-pin-start = <0>; + reset-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>; + rs-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pinmux_flexio_lcd>; + pinctrl-names = "default"; +}; + &flexpwm0_pwm0 { status = "okay"; pinctrl-0 = <&pinmux_flexpwm0_pwm0>; pinctrl-names = "default"; }; + +&lpadc0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpadc0>; + pinctrl-names = "default"; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; +}; + +&lpi2c0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpi2c0>; + pinctrl-names = "default"; +}; + +&lpi2c3 { + status = "okay"; + pinctrl-0 = <&pinmux_lpi2c3>; + pinctrl-names = "default"; +}; + +&lpspi0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpspi0>; + pinctrl-names = "default"; +}; + +&lptmr0 { + status = "okay"; +}; + +zephyr_udc0: &usb { + status = "okay"; + num-bidir-endpoints = <8>; +}; + +&wwdt0 { + status = "okay"; +}; + +&flash { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + read-only; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(424)>; + }; + slot1_partition: partition@7a000 { + label = "image-1"; + reg = <0x0007a000 DT_SIZE_K(424)>; + }; + storage_partition: partition@e4000 { + label = "storage"; + reg = <0x000e4000 DT_SIZE_K(112)>; + }; + }; +}; diff --git a/boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml b/boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml index abad7e82254de..24b7f6d8c7e8c 100644 --- a/boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml +++ b/boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml @@ -13,10 +13,18 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: + - adc - flash - gpio + - can + - counter - dac + - dma + - i2c - pwm + - spi + - usb_device + - usbd + - watchdog vendor: nxp diff --git a/boards/nxp/frdm_mcxa156/frdm_mcxa156_defconfig b/boards/nxp/frdm_mcxa156/frdm_mcxa156_defconfig index 8a733179c9f04..393d38123660c 100644 --- a/boards/nxp/frdm_mcxa156/frdm_mcxa156_defconfig +++ b/boards/nxp/frdm_mcxa156/frdm_mcxa156_defconfig @@ -9,3 +9,4 @@ CONFIG_UART_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_GPIO=y +CONFIG_LPADC_DO_OFFSET_CALIBRATION=y diff --git a/boards/nxp/frdm_mcxc242/doc/index.rst b/boards/nxp/frdm_mcxc242/doc/index.rst index 447cebd8dfa8b..ceaa1cc8af58f 100644 --- a/boards/nxp/frdm_mcxc242/doc/index.rst +++ b/boards/nxp/frdm_mcxc242/doc/index.rst @@ -101,6 +101,10 @@ PORTB/GPIOB, PORTC/GPIOC, PORTD/GPIOD, and PORTE/GPIOE) for the FRDM-MCXC242 boa +-------+-------------+---------------------------+ | PTA2 | LPUART0_TX | UART Console | +-------+-------------+---------------------------+ +| PTE1 | LPUART1_RX | UART | ++-------+-------------+---------------------------+ +| PTE0 | LPUART1_TX | UART | ++-------+-------------+---------------------------+ | PTA20 | RESET | RESET Button SW1 | +-------+-------------+---------------------------+ | PTC1 | GPIO | User button SW2 | diff --git a/boards/nxp/frdm_mcxc242/frdm_mcxc242-pinctrl.dtsi b/boards/nxp/frdm_mcxc242/frdm_mcxc242-pinctrl.dtsi index 2e8908e954e32..2bcb42359a9be 100644 --- a/boards/nxp/frdm_mcxc242/frdm_mcxc242-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxc242/frdm_mcxc242-pinctrl.dtsi @@ -16,6 +16,14 @@ slew-rate = "slow"; }; }; + pinmux_lpuart1: pinmux_lpuart1 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; pinmux_uart2: pinmux_uart2 { group0 { pinmux = , diff --git a/boards/nxp/frdm_mcxc242/frdm_mcxc242.dts b/boards/nxp/frdm_mcxc242/frdm_mcxc242.dts index 7c4a9da500447..20564d40a2583 100644 --- a/boards/nxp/frdm_mcxc242/frdm_mcxc242.dts +++ b/boards/nxp/frdm_mcxc242/frdm_mcxc242.dts @@ -122,6 +122,13 @@ pinctrl-names = "default"; }; +&lpuart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart1>; + pinctrl-names = "default"; +}; + &uart2 { status = "disabled"; current-speed = <115200>; diff --git a/boards/nxp/frdm_mcxc242/frdm_mcxc242.yaml b/boards/nxp/frdm_mcxc242/frdm_mcxc242.yaml index 778d84284956b..a8e920ea89d4b 100644 --- a/boards/nxp/frdm_mcxc242/frdm_mcxc242.yaml +++ b/boards/nxp/frdm_mcxc242/frdm_mcxc242.yaml @@ -13,7 +13,6 @@ flash: 64 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - counter diff --git a/boards/nxp/frdm_mcxc444/doc/index.rst b/boards/nxp/frdm_mcxc444/doc/index.rst index da09d23a25a95..891fdce5c86f6 100644 --- a/boards/nxp/frdm_mcxc444/doc/index.rst +++ b/boards/nxp/frdm_mcxc444/doc/index.rst @@ -55,12 +55,20 @@ The ``frdm_mcxc444`` board target supports the following hardware features: +-----------+------------+-------------------------------------+ | FLASH | on-chip | soc flash | +-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ | LPTMR | on-chip | counter | +-----------+------------+-------------------------------------+ | PIT | on-chip | counter | +-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ | RTC | on-chip | counter | +-----------+------------+-------------------------------------+ +| USB | on-chip | USB device | ++-----------+------------+-------------------------------------+ Targets available diff --git a/boards/nxp/frdm_mcxc444/frdm_mcxc444-pinctrl.dtsi b/boards/nxp/frdm_mcxc444/frdm_mcxc444-pinctrl.dtsi index 87552988ff852..328ce758ba43f 100644 --- a/boards/nxp/frdm_mcxc444/frdm_mcxc444-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxc444/frdm_mcxc444-pinctrl.dtsi @@ -8,6 +8,23 @@ #include &pinctrl { + pinmux_adc0: pinmux_adc0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; + pinmux_i2c0: pinmux_i2c0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + drive-open-drain; + slew-rate = "fast"; + }; + }; pinmux_lpuart0: pinmux_lpuart0 { group0 { pinmux = , @@ -24,4 +41,13 @@ slew-rate = "slow"; }; }; + pinmux_tpm0: pinmux_tpm0 { + group0 { + pinmux = , + , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; }; diff --git a/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts b/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts index c39e6543f135f..3fc85d9607552 100644 --- a/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts +++ b/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts @@ -17,9 +17,17 @@ aliases { led0 = &red_led; led1 = &green_led; - led2 = &red_led; + led2 = &blue_led; + pwm-led0 = &red_pwm_led; + pwm-led1 = &green_pwm_led; + pwm-led2 = &blue_pwm_led; + red-pwm-led = &red_pwm_led; + green-pwm-led = &green_pwm_led; + blue-pwm-led = &blue_pwm_led; sw0 = &user_button_2; sw1 = &user_button_3; + accel0 = &fxls8974; + pwm-0 = &tpm0; }; chosen { @@ -36,7 +44,7 @@ label = "Red LED"; }; green_led: led_1 { - gpios = <&gpiob 5 GPIO_ACTIVE_LOW>; + gpios = <&gpiod 5 GPIO_ACTIVE_LOW>; label = "Green LED"; }; blue_led: led_2 { @@ -45,6 +53,23 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + red_pwm_led: pwm_led_0 { + pwms = <&tpm0 4 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "PWM Red LED"; + }; + green_pwm_led: pwm_led_1 { + pwms = <&tpm0 5 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "PWM Green LED"; + }; + blue_pwm_led: pwm_led_2 { + pwms = <&tpm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "PWM Blue LED"; + }; + }; + gpio_keys { compatible = "gpio-keys"; user_button_2: button_2 { @@ -86,10 +111,33 @@ status = "okay"; }; +&gpiod { + status = "okay"; +}; + &gpioe { status = "okay"; }; +&adc0 { + status = "okay"; + pinctrl-0 = <&pinmux_adc0>; + pinctrl-names = "default"; +}; + +i2c0: &i2c0 { + status = "okay"; + pinctrl-0 = <&pinmux_i2c0>; + pinctrl-names = "default"; + + fxls8974: fxls8974@18 { + status = "okay"; + compatible = "nxp,fxls8974"; + reg = <0x18>; + int1-gpios = <&gpiod 1 GPIO_ACTIVE_LOW>; + }; +}; + &lpuart0 { status = "okay"; current-speed = <115200>; @@ -123,3 +171,15 @@ &pit0_channel1 { status = "okay"; }; + +&tpm0 { + status = "okay"; + pinctrl-0 = <&pinmux_tpm0>; + pinctrl-names = "default"; + clocks = <&sim KINETIS_SIM_OSCERCLK 0x103C 24>; +}; + +zephyr_udc0: &usb { + status = "okay"; + num-bidir-endpoints = <8>; +}; diff --git a/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml b/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml index 2b8e598fca671..201eacecb179c 100644 --- a/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml +++ b/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml @@ -13,12 +13,16 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: + - adc - counter - flash - gpio + - i2c - uart + - pwm + - usb_device + - usbd testing: ignore_tags: - net diff --git a/boards/nxp/frdm_mcxn236/board.c b/boards/nxp/frdm_mcxn236/board.c index fd9ce02abb78f..0f26f85724246 100644 --- a/boards/nxp/frdm_mcxn236/board.c +++ b/boards/nxp/frdm_mcxn236/board.c @@ -293,6 +293,12 @@ static int frdm_mcxn236_init(void) #endif /* DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lptmr0)) */ +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(i3c1)) + CLOCK_SetClkDiv(kCLOCK_DivI3c1FClk, DT_PROP(DT_NODELABEL(i3c1), clk_divider)); + /* Attach PLL0 clock to I3C, 150MHz / 6 = 25MHz. */ + CLOCK_AttachClk(kPLL0_to_I3C1FCLK); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; diff --git a/boards/nxp/frdm_mcxn236/board.cmake b/boards/nxp/frdm_mcxn236/board.cmake index 705a6443526d8..da7dfb17a86bd 100644 --- a/boards/nxp/frdm_mcxn236/board.cmake +++ b/boards/nxp/frdm_mcxn236/board.cmake @@ -6,16 +6,6 @@ board_runner_args(jlink "--device=MCXN236" "--reset-after-load") board_runner_args(linkserver "--device=MCXN236:FRDM-MCXN236") -board_runner_args(linkserver "--core=cm33_core0") -board_runner_args(linkserver "--override=/device/memory/1/flash-driver=MCXNxxx_S.cfx") -board_runner_args(linkserver "--override=/device/memory/1/location=0x10000000") -# Linkserver v1.4.85 and earlier do not include the secure regions in the -# MCXN236 memory map, so we add them here -board_runner_args(linkserver "--override=/device/memory/-=\{\"location\":\"0x30000000\",\ - \"size\":\"0x00040000\",\"type\":\"RAM\"\}") -# Define region for peripherals -board_runner_args(linkserver "--override=/device/memory/-=\{\"location\":\"0x50000000\",\ - \"size\":\"0x00140000\",\"type\":\"RAM\"\}") # Pyocd support added with the NXP.MCXN236_DFP.17.0.0.pack CMSIS Pack board_runner_args(pyocd "--target=mcxn236") diff --git a/boards/nxp/frdm_mcxn236/doc/index.rst b/boards/nxp/frdm_mcxn236/doc/index.rst index 58606df9f0196..48052ad4e56e3 100644 --- a/boards/nxp/frdm_mcxn236/doc/index.rst +++ b/boards/nxp/frdm_mcxn236/doc/index.rst @@ -55,6 +55,8 @@ The FRDM-MCXN236 board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | I2C | on-chip | i2c | +-----------+------------+-------------------------------------+ +| I3C | on-chip | i3c | ++-----------+------------+-------------------------------------+ | CLOCK | on-chip | clock_control | +-----------+------------+-------------------------------------+ | FLASH | on-chip | soc flash | @@ -80,6 +82,8 @@ The FRDM-MCXN236 board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | MRT | on-chip | counter | +-----------+------------+-------------------------------------+ +| RTC | on-chip | rtc | ++-----------+------------+-------------------------------------+ Targets available ================== diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236-pinctrl.dtsi b/boards/nxp/frdm_mcxn236/frdm_mcxn236-pinctrl.dtsi index e8c0907b87d25..19a06b8453fed 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236-pinctrl.dtsi @@ -120,6 +120,23 @@ }; }; + pinmux_i3c1: pinmux_i3c1 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + bias-pull-up; + }; + group1 { + pinmux = ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; + pinmux_flexio_lcd: pinmux_flexio_lcd { group0 { pinmux = , diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts index 5c1d345cb3d07..01e64e970851c 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts @@ -27,6 +27,7 @@ aliases{ watchdog0 = &wwdt0; pwm-0 = &flexpwm1_pwm0; + rtc = &rtc; }; }; @@ -135,6 +136,10 @@ zephyr_udc0: &usb1 { status = "okay"; }; +&i3c1 { + status = "okay"; +}; + &flexio0 { status = "okay"; }; @@ -146,3 +151,7 @@ zephyr_udc0: &usb1 { &mrt0_channel0 { status = "okay"; }; + +&rtc { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dtsi b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dtsi index 51dadf4673c4d..26515a7879755 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dtsi +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dtsi @@ -168,3 +168,11 @@ zephyr_mipi_dbi_parallel: &flexio0_lcd { pinctrl-0 = <&pinmux_flexio_lcd>; pinctrl-names = "default"; }; + +&i3c1 { + pinctrl-0 = <&pinmux_i3c1>; + pinctrl-names = "default"; +}; + +p3t1755dp_ard_i3c_interface: &i3c1 {}; +p3t1755dp_ard_i2c_interface: &flexcomm5_lpi2c5 {}; diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml b/boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml index e90378baba1f9..2453534b31815 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml @@ -13,7 +13,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - can @@ -22,6 +21,7 @@ supported: - flash - gpio - i2c + - i3c - pwm - regulator - spi diff --git a/boards/nxp/frdm_mcxn947/board.c b/boards/nxp/frdm_mcxn947/board.c index e16cf6f6e5cb3..fafaf3e406824 100644 --- a/boards/nxp/frdm_mcxn947/board.c +++ b/boards/nxp/frdm_mcxn947/board.c @@ -16,6 +16,10 @@ #define BOARD_USB_PHY_D_CAL (0x04U) #define BOARD_USB_PHY_TXCAL45DP (0x07U) #define BOARD_USB_PHY_TXCAL45DM (0x07U) + +usb_phy_config_struct_t usbPhyConfig = { + BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM, +}; #endif /* Board xtal frequency in Hz */ @@ -127,21 +131,18 @@ static int frdm_mcxn947_init(void) CLOCK_SetupExtClocking(BOARD_XTAL0_CLK_HZ); -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcan0)) - /* Set up PLL1 for 80 MHz FlexCAN clock */ - const pll_setup_t pll1Setup = { - .pllctrl = SCG_SPLLCTRL_SOURCE(1U) | SCG_SPLLCTRL_SELI(27U) | - SCG_SPLLCTRL_SELP(13U), - .pllndiv = SCG_SPLLNDIV_NDIV(3U), - .pllpdiv = SCG_SPLLPDIV_PDIV(1U), - .pllmdiv = SCG_SPLLMDIV_MDIV(10U), - .pllRate = 80000000U - }; +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai0)) || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai1)) + /* < Set up PLL1 */ + const pll_setup_t pll1_Setup = { + .pllctrl = SCG_SPLLCTRL_SOURCE(1U) | SCG_SPLLCTRL_SELI(3U) | + SCG_SPLLCTRL_SELP(1U), + .pllndiv = SCG_SPLLNDIV_NDIV(25U), + .pllpdiv = SCG_SPLLPDIV_PDIV(10U), + .pllmdiv = SCG_SPLLMDIV_MDIV(256U), + .pllRate = 24576000U}; /* Configure PLL1 to the desired values */ - CLOCK_SetPLL1Freq(&pll1Setup); - /* PLL1 Monitor is disabled */ - CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); + CLOCK_SetPLL1Freq(&pll1_Setup); /* Set PLL1 CLK0 divider to value 1 */ CLOCK_SetClkDiv(kCLOCK_DivPLL1Clk0, 1U); #endif @@ -246,7 +247,7 @@ static int frdm_mcxn947_init(void) #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcan0)) CLOCK_SetClkDiv(kCLOCK_DivFlexcan0Clk, 1U); - CLOCK_AttachClk(kPLL1_CLK0_to_FLEXCAN0); + CLOCK_AttachClk(kFRO_HF_to_FLEXCAN0); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usdhc0)) @@ -284,11 +285,7 @@ static int frdm_mcxn947_init(void) CLOCK_AttachClk(kFRO_HF_to_ADC0); #endif -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb1)) && CONFIG_USB_DC_NXP_EHCI - usb_phy_config_struct_t usbPhyConfig = { - BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM, - }; - +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb1)) && (CONFIG_USB_DC_NXP_EHCI || CONFIG_UDC_NXP_EHCI) SPC0->ACTIVE_VDELAY = 0x0500; /* Change the power DCDC to 1.8v (By default, DCDC is 1.8V), CORELDO to 1.1v (By default, * CORELDO is 1.0V) @@ -323,8 +320,10 @@ static int frdm_mcxn947_init(void) CLOCK_EnableClock(kCLOCK_UsbHsPhy); CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, BOARD_XTAL0_CLK_HZ); CLOCK_EnableUsbhsClock(); +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb1)) && CONFIG_USB_DC_NXP_EHCI USB_EhciPhyInit(kUSB_ControllerEhci0, BOARD_XTAL0_CLK_HZ, &usbPhyConfig); #endif +#endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpcmp0)) CLOCK_SetClkDiv(kCLOCK_DivCmp0FClk, 1U); @@ -381,6 +380,18 @@ static int frdm_mcxn947_init(void) CLOCK_AttachClk(kFRO_HF_to_SCT); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai0)) + CLOCK_SetClkDiv(kCLOCK_DivSai0Clk, 1u); + CLOCK_AttachClk(kPLL1_CLK0_to_SAI0); + CLOCK_EnableClock(kCLOCK_Sai0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sai1)) + CLOCK_SetClkDiv(kCLOCK_DivSai1Clk, 1u); + CLOCK_AttachClk(kPLL1_CLK0_to_SAI1); + CLOCK_EnableClock(kCLOCK_Sai1); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; diff --git a/boards/nxp/frdm_mcxn947/board.cmake b/boards/nxp/frdm_mcxn947/board.cmake index fa5862e5e008f..f26f08890bfbe 100644 --- a/boards/nxp/frdm_mcxn947/board.cmake +++ b/boards/nxp/frdm_mcxn947/board.cmake @@ -4,10 +4,14 @@ # SPDX-License-Identifier: Apache-2.0 # -if(CONFIG_SOC_MCXN947_CPU0) +if(CONFIG_SOC_MCXN947_CPU0 OR CONFIG_SECOND_CORE_MCUX) board_runner_args(jlink "--device=MCXN947_M33_0" "--reset-after-load") board_runner_args(linkserver "--device=MCXN947:FRDM-MCXN947") - board_runner_args(linkserver "--core=cm33_core0") + if(CONFIG_SECOND_CORE_MCUX) + board_runner_args(linkserver "--core=all") + else() + board_runner_args(linkserver "--core=cm33_core0") + endif() board_runner_args(linkserver "--override=/device/memory/1/flash-driver=MCXN9xx_S.cfx") board_runner_args(linkserver "--override=/device/memory/1/location=0x10000000") # Linkserver v1.4.85 and earlier do not include the secure regions in the @@ -19,8 +23,10 @@ if(CONFIG_SOC_MCXN947_CPU0) # Define region for peripherals board_runner_args(linkserver "--override=/device/memory/-=\{\"location\":\"0x50000000\",\ \"size\":\"0x00140000\",\"type\":\"RAM\"\}") -else() - message(FATAL_ERROR "Support for cpu1 not available yet") +elseif(CONFIG_SOC_MCXN947_CPU1) + board_runner_args(jlink "--device=MCXN947_M33_1" "--reset-after-load") + board_runner_args(linkserver "--device=MCXN947:FRDM-MCXN947") + board_runner_args(linkserver "--core=cm33_core1") endif() # Pyocd support added with the NXP.MCXN947_DFP.17.0.0.pack CMSIS Pack diff --git a/boards/nxp/frdm_mcxn947/doc/index.rst b/boards/nxp/frdm_mcxn947/doc/index.rst index 6b5008a20551f..83406f023bca0 100644 --- a/boards/nxp/frdm_mcxn947/doc/index.rst +++ b/boards/nxp/frdm_mcxn947/doc/index.rst @@ -85,6 +85,8 @@ The FRDM-MCXN947 board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | ADC | on-chip | adc | +-----------+------------+-------------------------------------+ +| HWINFO | on-chip | Unique device serial number | ++-----------+------------+-------------------------------------+ | USBHS | on-chip | USB device | +-----------+------------+-------------------------------------+ | LPCMP | on-chip | sensor(comparator) | @@ -95,20 +97,53 @@ The FRDM-MCXN947 board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | FLEXIO | on-chip | flexio | +-----------+------------+-------------------------------------+ +| SAI | on-chip | i2s | ++-----------+------------+-------------------------------------+ | DISPLAY | on-chip | flexio; MIPI-DBI. Tested with | | | | :ref:`lcd_par_s035` | +-----------+------------+-------------------------------------+ | MRT | on-chip | counter | +-----------+------------+-------------------------------------+ +Dual Core samples +***************** + ++-----------+-------------------+----------------------+ +| Core | Boot Address | Comment | ++===========+===================+======================+ +| CPU0 | 0x10000000[1856K] | primary core flash | ++-----------+-------------------+----------------------+ +| CPU1 | 0x101d0000[192K] | secondary core flash | ++-----------+-------------------+----------------------+ + ++----------+------------------+-----------------------+ +| Memory | Address[Size] | Comment | ++==========+==================+=======================+ +| srama | 0x20000000[320k] | CPU0 ram | ++----------+------------------+-----------------------+ +| sramg | 0x20050000[64k] | CPU1 ram | ++----------+------------------+-----------------------+ +| sramh | 0x20060000[32k] | Shared memory | ++----------+------------------+-----------------------+ + Targets available ================== The default configuration file :zephyr_file:`boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_defconfig` -only enables the first core. +only enables the first core. CPU0 is the only target that can run standalone. + +CPU1 does not work without CPU0 enabling it. + +To enable CPU1, create System Build application project and enable the +second core with config :kconfig:option:`CONFIG_SECOND_CORE_MCUX`. -Other hardware features are not currently supported by the port. +Please have a look at some already enabled samples: + +- :zephyr_file:`samples/subsys/ipc/ipc_service/static_vrings` +- :zephyr_file:`samples/subsys/ipc/openamp` +- :zephyr_file:`samples/drivers/mbox` +- :zephyr_file:`samples/drivers/mbox_data` Connections and IOs =================== @@ -119,9 +154,13 @@ can be used to configure the functionality of a pin. +------------+-----------------+----------------------------+ | Name | Function | Usage | +============+=================+============================+ -| P0_PIO1_8 | UART | UART RX | +| P0_PIO1_8 | UART | UART RX cpu0 | ++------------+-----------------+----------------------------+ +| P1_PIO1_9 | UART | UART TX cpu0 | ++------------+-----------------+----------------------------+ +| P4_PIO4_3 | UART | UART RX cpu1 | +------------+-----------------+----------------------------+ -| P1_PIO1_9 | UART | UART TX | +| P4_PIO4_2 | UART | UART TX cpu1 | +------------+-----------------+----------------------------+ System Clock @@ -204,6 +243,25 @@ see the following message in the terminal: *** Booting Zephyr OS build v3.6.0-479-g91faa20c6741 *** Hello World! frdm_mcxn947/mcxn947/cpu0 +Building a dual-core image +-------------------------- + +The dual-core samples are run using ``frdm_mcxn947/mcxn947/cpu0`` target. + +Images built for ``frdm_mcxn947/mcxn947/cpu1`` will be loaded from flash +and executed on the second core when :kconfig:option:`CONFIG_SECOND_CORE_MCUX` is selected. + +For an example of building for both cores with System Build, see +:zephyr_file:`samples/subsys/ipc/ipc_service/static_vrings` + +Here is an example for the :zephyr:code-sample:`mbox_data` application. + +.. zephyr-app-commands:: + :app: zephyr/samples/drivers/mbox_data + :board: frdm_mcxn947/mcxn947/cpu0 + :goals: flash + :west-args: --sysbuild + Flashing to QSPI ================ @@ -259,6 +317,14 @@ should see the following message in the terminal: *** Booting Zephyr OS build v3.6.0-479-g91faa20c6741 *** Hello World! frdm_mcxn947/mcxn947/cpu0 +Debugging a dual-core image +--------------------------- + +For dual core builds, the secondary core should be placed into a loop, +then a debugger can be attached. +As a reference please see (`AN13264`_, section 4.2.3 for more information). +The reference is for the RT1170 but similar technique can be also used here. + Troubleshooting =============== @@ -285,3 +351,6 @@ Troubleshooting .. _FRDM-MCXN947 Schematics: https://www.nxp.com/webapp/Download?colCode=90818-MCXN947SH + +.. _AN13264: + https://www.nxp.com/docs/en/application-note/AN13264.pdf diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi index ce4995b6d1cd4..83b496c635d26 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947-pinctrl.dtsi @@ -92,6 +92,31 @@ }; }; + pinmux_sai1: pinmux_sai1 { + group0 { + pinmux = , + , + , + , + , + ; + drive-strength = "high"; + slew-rate = "fast"; + input-enable; + }; + }; + + pinmux_sai0: pinmux_sai0 { + group0 { + pinmux = , + , + ; + drive-strength = "high"; + slew-rate = "fast"; + input-enable; + }; + }; + pinmux_enet_qos: pinmux_enet_qos { mdio_group { pinmux = , diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi index 574f20aecaf9a..3ebc13c0e9a99 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi @@ -132,12 +132,27 @@ nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 { status = "okay"; }; +&sram { + sramg: memory@20050000 { + compatible = "mmio-sram"; + reg = <0x20050000 DT_SIZE_K(64)>; + }; + sramh: memory@20060000 { + compatible = "mmio-sram"; + reg = <0x20060000 DT_SIZE_K(32)>; + }; +}; + &flash { partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; + /* + * Partition sizes must be aligned + * to the flash memory sector size of 8KB. + */ boot_partition: partition@0 { label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(80)>; @@ -183,15 +198,6 @@ nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 { cs-setup-time = <3>; data-valid-time = <2>; column-space = <0>; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - storage_partition: partition@0 { - label = "storage"; - reg = <0x0 DT_SIZE_M(8)>; - }; - }; }; }; @@ -200,6 +206,16 @@ nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 { pinctrl-names = "default"; }; +&sai1 { + pinctrl-0 = <&pinmux_sai1>; + pinctrl-names = "default"; +}; + +&sai0 { + pinctrl-0 = <&pinmux_sai0>; + pinctrl-names = "default"; +}; + &enet { pinctrl-0 = <&pinmux_enet_qos>; pinctrl-names = "default"; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi index 3a1a565c89911..d74efb27ac64e 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi @@ -27,6 +27,7 @@ zephyr,console = &flexcomm4_lpuart4; zephyr,shell-uart = &flexcomm4_lpuart4; zephyr,canbus = &flexcan0; + zephyr,code-cpu1-partition = &slot1_partition; }; aliases{ @@ -51,6 +52,10 @@ reg = <0x20000000 DT_SIZE_K(320)>; }; +&mbox { + status = "okay"; +}; + &gpio4 { status = "okay"; }; @@ -129,6 +134,15 @@ &w25q64jvssiq { status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + storage_partition: partition@0 { + label = "storage"; + reg = <0x0 DT_SIZE_M(8)>; + }; + }; }; &dac0 { @@ -182,6 +196,14 @@ zephyr_udc0: &usb1 { status = "okay"; + phy-handle = <&usbphy1>; +}; + +&usbphy1 { + status = "okay"; + tx-d-cal = <4>; + tx-cal-45-dp-ohms = <7>; + tx-cal-45-dm-ohms = <7>; }; &lpcmp0 { @@ -211,3 +233,10 @@ zephyr_udc0: &usb1 { &sc_timer { status = "okay"; }; + +&sai1 { + status = "okay"; +}; +&sai0 { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml index 8578e55b9310f..2b1b3bdf58ea6 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml @@ -13,7 +13,6 @@ flash: 2048 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - can @@ -23,6 +22,7 @@ supported: - flash - gpio - i2c + - i2s - i3c - pwm - regulator diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml index 15648a75da57e..6b3e876ffb9c8 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml @@ -13,7 +13,6 @@ flash: 8192 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - can diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.dts b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.dts new file mode 100644 index 0000000000000..78fc22c12a713 --- /dev/null +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.dts @@ -0,0 +1,72 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_mcxn947.dtsi" + +/ { + model = "NXP FRDM_N94 board"; + compatible = "nxp,mcxn947", "nxp,mcx"; + + cpus { + /delete-node/ cpu@0; + }; + + chosen { + zephyr,sram = &sramg; + zephyr,flash = &flash; + zephyr,flash-controller = &fmu; + zephyr,code-partition = &slot1_partition; + zephyr,console = &flexcomm2_lpuart2; + zephyr,shell-uart = &flexcomm2_lpuart2; + }; +}; + +&flexcomm2 { + status = "okay"; +}; + +&flexcomm2_lpuart2 { + status = "okay"; +}; + +&mbox { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&green_led { + status = "okay"; +}; + +&red_led { + status = "okay"; +}; + +&user_button_2 { + status = "okay"; +}; + +&edma0 { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.yaml new file mode 100644 index 0000000000000..62335a40f84ac --- /dev/null +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.yaml @@ -0,0 +1,19 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: frdm_mcxn947/mcxn947/cpu1 +name: NXP FRDM MCXN947 (CPU1) +type: mcu +arch: arm +ram: 64 +flash: 200 +toolchain: + - zephyr + - gnuarmemb +supported: + - dma + - gpio +vendor: nxp diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1_defconfig b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1_defconfig new file mode 100644 index 0000000000000..97c8634658057 --- /dev/null +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1_defconfig @@ -0,0 +1,13 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GPIO=y + +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/nxp/frdm_mcxw71/board.cmake b/boards/nxp/frdm_mcxw71/board.cmake index 27c59c8d3582a..ba8d5b735de93 100644 --- a/boards/nxp/frdm_mcxw71/board.cmake +++ b/boards/nxp/frdm_mcxw71/board.cmake @@ -1,6 +1,8 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 +board_runner_args(linkserver "--device=MCXW716CxxxA:FRDM-MCXW71") board_runner_args(jlink "--device=mcxw716" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/frdm_mcxw71/doc/index.rst b/boards/nxp/frdm_mcxw71/doc/index.rst index c5a16d8e1a3f3..7cb755020f26a 100644 --- a/boards/nxp/frdm_mcxw71/doc/index.rst +++ b/boards/nxp/frdm_mcxw71/doc/index.rst @@ -60,6 +60,8 @@ The ``frdm_mcxw71`` board target in Zephyr currently supports the following feat +-----------+------------+-------------------------------------+ | LPTMR | on-chip | counter | +-----------+------------+-------------------------------------+ +| RTC | on-chip | counter | ++-----------+------------+-------------------------------------+ | BLE | on-chip | Bluetooth | +-----------+------------+-------------------------------------+ | FLEXCAN | on-chip | can | @@ -68,6 +70,10 @@ The ``frdm_mcxw71`` board target in Zephyr currently supports the following feat +-----------+------------+-------------------------------------+ | LPADC | on-chip | adc | +-----------+------------+-------------------------------------+ +| ELE | on-chip | entropy | ++-----------+------------+-------------------------------------+ +| PHY | on-chip | ieee802154 | ++-----------+------------+-------------------------------------+ Fetch Binary Blobs ****************** @@ -91,6 +97,16 @@ Configuring a Debug Probe A debug probe is used for both flashing and debugging the board. This board is configured by default to use the MCU-Link CMSIS-DAP Onboard Debug Probe. +Using LinkServer +---------------- + +Linkserver is the default runner for this board, and supports the factory +default MCU-Link firmware. Follow the instructions in +:ref:`mcu-link-cmsis-onboard-debug-probe` to reprogram the default MCU-Link +firmware. This only needs to be done if the default onboard debug circuit +firmware was changed. To put the board in ``DFU mode`` to program the firmware, +short jumper J5. + Using J-Link ------------ @@ -118,8 +134,26 @@ Connect a USB cable from your PC to J10, and use the serial terminal of your cho - Parity: None - Stop bits: 1 -Flashing -======== +Application Building +==================== + +Openthread applications +----------------------- + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_server + :board: frdm_mcxw71 + :goals: build + :gen-args: -DEXTRA_CONF_FILE=overlay-ot.conf + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_client + :board: frdm_mcxw71 + :goals: build + :gen-args: -DEXTRA_CONF_FILE=overlay-ot.conf + +Application Flashing +==================== Here is an example for the :zephyr:code-sample:`hello_world` application. @@ -154,15 +188,17 @@ should see the following message in the terminal: *** Booting Zephyr OS build v3.7.0-xxx-xxxx *** Hello World! frdm_mcxw71/mcxw716c -Bluetooth -========= +NBU Flashing +============ BLE functionality requires to fetch binary blobs, so make sure to follow the ``Fetch Binary Blobs`` section first. Two images must be written to the board: one for the host (CM33) and one for the NBU (CM3). -- To flash the application (CM33) refer to the ``Flashing`` section above. -- To flash the NBU, follow the instructions below: + +- To flash the application (CM33) refer to the ``Application Flashing`` section above. + +- To flash the ``NBU Flashing``, follow the instructions below: * Install ``blhost`` from NXP's website. This is the tool that will allow you to flash the NBU. * Enter ISP mode. To boot the MCU in ISP mode, follow these steps: @@ -172,17 +208,39 @@ Two images must be written to the board: one for the host (CM33) and one for the - Reconnect any external power supply, if needed. * Use the following command to flash NBU file: -.. code-block:: console +.. tabs:: + + .. group-tab:: BLE NBU - Windows + + .. code-block:: console + :caption: Flash BLE only NBU on Windows + + blhost.exe -p COMxx -- receive-sb-file mcxw71_nbu_ble.sb3 + + .. group-tab:: BLE NBU - Linux + + .. code-block:: console + :caption: Flash BLE only NBU on Linux + + ./blhost -p /dev/ttyxx -- receive-sb-file mcxw71_nbu_ble.sb3 + + .. group-tab:: DYN NBU - Windows + + .. code-block:: console + :caption: Flash Dynamic NBU (BLE + 15.4) on Windows + + blhost.exe -p COMxx -- receive-sb-file mcxw71_nbu_ble_15_4_dyn.sb3 + + .. group-tab:: DYN NBU - Linux - # On Windows - blhost.exe -p COMxx -- receive-sb-file mcxw71_nbu_ble.sb3 + .. code-block:: console + :caption: Flash Dynamic NBU (BLE + 15.4) on Linux - # On Linux - ./blhost -p /dev/ttyxx -- receive-sb-file mcxw71_nbu_ble.sb3 + ./blhost -p /dev/ttyxx -- receive-sb-file mcxw71_nbu_ble_15_4_dyn.sb3 Please consider changing ``COMxx`` on Windows or ``ttyxx`` on Linux to the serial port used by your board. -The NBU file can be found in : ``/modules/hal/nxp/zephyr/blobs/mcxw71/mcxw71_nbu_ble.sb3`` +The NBU files can be found in : ``/modules/hal/nxp/zephyr/blobs/mcxw71/`` folder. For more details: diff --git a/boards/nxp/frdm_mcxw71/frdm_mcxw71-pinctrl.dtsi b/boards/nxp/frdm_mcxw71/frdm_mcxw71-pinctrl.dtsi index 29e41f6926e20..e1b876ee0b094 100644 --- a/boards/nxp/frdm_mcxw71/frdm_mcxw71-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxw71/frdm_mcxw71-pinctrl.dtsi @@ -32,6 +32,16 @@ }; }; + pinmux_lpi2c0: pinmux_lpi2c0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + drive-open-drain; + }; + }; + pinmux_lpi2c1: pinmux_lpi2c1 { group0 { pinmux = , @@ -45,7 +55,9 @@ pinmux_lpspi1: pinmux_lpspi1 { group0 { pinmux = , - ; + , + , + ; slew-rate = "fast"; drive-strength = "low"; }; diff --git a/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts b/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts index 4e7d1b31b4135..bfde56f818066 100644 --- a/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts +++ b/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts @@ -7,12 +7,14 @@ #include #include "frdm_mcxw71-pinctrl.dtsi" +#include / { model = "NXP FRDM-MCXW71 board"; aliases { led0 = &blue_led; + sw0 = &user_button_0; blue-pwm-led = &blue_pwm_led; green-pwm-led = &green_pwm_led; red-pwm-led = &red_pwm_led; @@ -27,6 +29,7 @@ zephyr,shell-uart = &lpuart1; zephyr,uart-pipe = &lpuart0; zephyr,canbus = &flexcan0; + zephyr,uart-mcumgr = &lpuart0; }; user_led { @@ -48,6 +51,16 @@ pwms = <&tpm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; }; }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_0: button_0 { + label = "User SW2"; + gpios = <&gpioc 6 GPIO_ACTIVE_LOW>; + zephyr,code = ; + status = "okay"; + }; + }; }; &vref { @@ -82,6 +95,28 @@ status = "okay"; pinctrl-0 = <&pinmux_lpspi1>; pinctrl-names = "default"; + pcs-sck-delay = <5>; + sck-pcs-delay = <5>; + transfer-delay = <125>; + + mx25r6435fm2il0: flash@0 { + compatible = "jedec,spi-nor"; + jedec-id = [c2 28 17]; + reg = <0>; + /* only wp-gpio on default board configuration, + * there is a reset gpio line but the line is + * DNP by default on the board (R4 on schematic) + */ + wp-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>; + size = ; + has-dpd; + dpd-wakeup-sequence = <30000 20 35000>; + t-enter-dpd = <10000>; + /* this is the default (reset) mode for this flash */ + mxicy,mx25r-power-mode = "low-power"; + /* 8 MHz for low power mode */ + spi-max-frequency = <8000000>; + }; }; &flash { @@ -89,21 +124,20 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. + */ boot_partition: partition@0 { reg = <0x0 DT_SIZE_K(64)>; }; - slot0_partition: partition@10000 { - reg = <0x10000 DT_SIZE_K(416)>; + reg = <0x10000 (DT_SIZE_K(416) + DT_SIZE_K(16))>; }; - - slot1_partition: partition@78000 { - reg = <0x78000 DT_SIZE_K(416)>; + slot1_partition: partition@7C000 { + reg = <0x7C000 DT_SIZE_K(416)>; }; - - storage_partition: partition@e0000 { - reg = <0xe0000 DT_SIZE_K(128)>; + storage_partition: partition@E4000 { + reg = <0xE4000 DT_SIZE_K(112)>; }; }; }; @@ -137,3 +171,12 @@ pinctrl-names = "default"; status = "okay"; }; + +&nbu { + status = "okay"; + wakeup-source; +}; + +&rtc { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml b/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml index 54cbe67d97218..24b5be8c10f1a 100644 --- a/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml +++ b/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - can diff --git a/boards/nxp/frdm_mcxw72/Kconfig.frdm_mcxw72 b/boards/nxp/frdm_mcxw72/Kconfig.frdm_mcxw72 new file mode 100644 index 0000000000000..0d5844ca6b69a --- /dev/null +++ b/boards/nxp/frdm_mcxw72/Kconfig.frdm_mcxw72 @@ -0,0 +1,6 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_MCXW72 + select SOC_MCXW727C_CPU0 if BOARD_FRDM_MCXW72_MCXW727C_CPU0 + select SOC_PART_NUMBER_MCXW727CMFTA diff --git a/boards/nxp/frdm_mcxw72/board.cmake b/boards/nxp/frdm_mcxw72/board.cmake new file mode 100644 index 0000000000000..6282eec263b61 --- /dev/null +++ b/boards/nxp/frdm_mcxw72/board.cmake @@ -0,0 +1,8 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(linkserver "--device=MCXW727C:MCX-W72-EVK") +board_runner_args(jlink "--device=MCXW727" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/frdm_mcxw72/board.yml b/boards/nxp/frdm_mcxw72/board.yml new file mode 100644 index 0000000000000..f00b612574913 --- /dev/null +++ b/boards/nxp/frdm_mcxw72/board.yml @@ -0,0 +1,6 @@ +board: + name: frdm_mcxw72 + full_name: FRDM-MCXW72 + vendor: nxp + socs: + - name: mcxw727c diff --git a/boards/nxp/frdm_mcxw72/doc/frdm_mcxw72.webp b/boards/nxp/frdm_mcxw72/doc/frdm_mcxw72.webp new file mode 100644 index 0000000000000..993086e1c1a89 Binary files /dev/null and b/boards/nxp/frdm_mcxw72/doc/frdm_mcxw72.webp differ diff --git a/boards/nxp/frdm_mcxw72/doc/index.rst b/boards/nxp/frdm_mcxw72/doc/index.rst new file mode 100644 index 0000000000000..ad4cfc0530038 --- /dev/null +++ b/boards/nxp/frdm_mcxw72/doc/index.rst @@ -0,0 +1,158 @@ +.. zephyr:board:: frdm_mcxw72 + +Overview +******** + +The FRDM-MCXW72 + +The MCX W72x family features a 96 MHz ArmÂŽ CortexÂŽ-M33 core coupled with a +multiprotocol radio subsystem supporting Matter, Thread, Zigbee and +Bluetooth LE. The independent radio subsystem, with a dedicated core and +memory, offloads the main CPU, preserving it for the primary application and +allowing firmware updates to support future wireless standards. + +Hardware +******** + +- MCXW72 Arm Cortex-M33 microcontroller running up to 96 MHz +- 2MB on-chip Flash memory unit +- 256 KB TCM RAM +- On-board MCU-Link debugger with CMSIS-DAP + +For more information about the MCXW72 SoC and FRDM-MCXW72 board, see: + +- `MCXW72 SoC Website`_ +- `FRDM-MCXW72 Website`_ + +Supported Features +================== + +The ``frdm_mcxw72`` board target in Zephyr currently supports the following features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinctrl | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| LPUART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| TPM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| LPTMR | on-chip | counter | ++-----------+------------+-------------------------------------+ +| LPSPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| FLEXCAN | on-chip | can | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ + +Programming and Debugging +************************* + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Debug Probe +========================= + +A debug probe is used for both flashing and debugging the board. This board is +configured by default to use the MCU-Link CMSIS-DAP Onboard Debug Probe. + +Using LinkServer +---------------- + +Linkserver is the default runner for this board, and supports the factory +default MCU-Link firmware. Follow the instructions in +:ref:`mcu-link-cmsis-onboard-debug-probe` to reprogram the default MCU-Link +firmware. This only needs to be done if the default onboard debug circuit +firmware was changed. To put the board in ``DFU mode`` to program the firmware, +short jumper JP5. + +Using J-Link +------------ + +There are two options. The onboard debug circuit can be updated with Segger +J-Link firmware by following the instructions in +:ref:`mcu-link-jlink-onboard-debug-probe`. +To be able to program the firmware, you need to put the board in ``DFU mode`` +by shortening the jumper JP5. +The second option is to attach a :ref:`jlink-external-debug-probe` to the +10-pin SWD connector (J12) of the board. +For both options use the ``-r jlink`` option with west to use the jlink runner. + +.. code-block:: console + + west flash -r jlink + +Configuring a Console +===================== + +Connect a USB cable from your PC to J14, and use the serial terminal of your choice +(minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing +======== + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_mcxw72/mcxw727c/cpu0 + :goals: flash + +Open a serial terminal, reset the board (press the RESET button), and you should +see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v3.7.0-xxx-xxxx *** + Hello World! frdm_mcxw72/mcxw727c/cpu0 + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_mcxw72/mcxw727c/cpu0 + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v3.7.0-xxx-xxxx *** + Hello World! frdm_mcxw72/mcxw727c/cpu0 + +Troubleshooting +=============== + +.. include:: ../../common/segger-ecc-systemview.rst + :start-after: segger-ecc-systemview + +References +********** + +.. target-notes:: + +.. _MCXW72 SoC Website: + https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/mcx-arm-cortex-m/mcx-w-series-microcontrollers/mcx-w72x-secure-and-ultra-low-power-mcus-for-matter-thread-zigbee-and-bluetooth-le:MCX-W72X + +.. _FRDM-MCXW72 Website: diff --git a/boards/nxp/frdm_mcxw72/frdm_mcxw72-pinctrl.dtsi b/boards/nxp/frdm_mcxw72/frdm_mcxw72-pinctrl.dtsi new file mode 100644 index 0000000000000..81d37051ec686 --- /dev/null +++ b/boards/nxp/frdm_mcxw72/frdm_mcxw72-pinctrl.dtsi @@ -0,0 +1,80 @@ +/* + * Copyright 2024 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + pinmux_lpuart0: pinmux_lpuart0 { + group0 { + pinmux = , ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart1: pinmux_lpuart1 { + group0 { + pinmux = , ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_tpm0: pinmux_tpm0 { + group0 { + pinmux = , , + , ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_lpspi1: pinmux_lpspi1 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + }; + }; + + pinmux_flexcan: pinmux_flexcan { + group0 { + pinmux = , ; + slew-rate = "slow"; + drive-strength = "low"; + }; + }; + + pinmux_lpadc0: pinmux_lpadc0 { + group0 { + pinmux = , + , + ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_lpi2c0: pinmux_lpi2c0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + drive-open-drain; + }; + }; + + pinmux_lpi2c1: pinmux_lpi2c1 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + drive-open-drain; + }; + }; +}; diff --git a/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.dts b/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.dts new file mode 100644 index 0000000000000..914e0f9dfd64d --- /dev/null +++ b/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.dts @@ -0,0 +1,136 @@ +/* + * Copyright 2024 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_mcxw72-pinctrl.dtsi" + +/ { + model = "NXP FRDM-MCXW72 board"; + + aliases { + led0 = &blue_led; + blue-pwm-led = &blue_pwm_led; + green-pwm-led = &green_pwm_led; + red-pwm-led = &red_pwm_led; + }; + + chosen { + zephyr,flash = &flash; + zephyr,flash-controller = &fmu; + zephyr,code-partition = &code_partition; + zephyr,sram = &stcm0; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + zephyr,uart-pipe = &lpuart0; + zephyr,canbus = &flexcan0; + }; + + user_led { + compatible = "gpio-leds"; + blue_led: led { + gpios = <&gpioc 1 GPIO_ACTIVE_HIGH>; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + blue_pwm_led: pwm_led_0 { + pwms = <&tpm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + green_pwm_led: pwm_led_1 { + pwms = <&tpm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + red_pwm_led: pwm_led_2 { + pwms = <&tpm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + }; +}; + +&gpioa { + status = "okay"; +}; + + +&gpioc { + status = "okay"; +}; + +&lpuart0 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&pinmux_lpuart0>; + pinctrl-names = "default"; +}; + +&lpuart1 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&pinmux_lpuart1>; + pinctrl-names = "default"; +}; + +&flash { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + code_partition: partition@0 { + reg = <0x0 DT_SIZE_K(67)>; + }; + + storage_partition: partition@10c00 { + reg = <0x10c00 DT_SIZE_K(1981)>; + }; + }; +}; + +&fmu { + status = "okay"; +}; + +&tpm0 { + status = "okay"; + pinctrl-0 = <&pinmux_tpm0>; + pinctrl-names = "default"; +}; + +&lptmr0 { + status = "okay"; +}; + +&lpspi1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpspi1>; + pinctrl-names = "default"; +}; + +&flexcan0 { + status = "okay"; + pinctrl-0 = <&pinmux_flexcan>; + pinctrl-names = "default"; + + can-transceiver { + max-bitrate = <5000000>; + }; +}; + +&vref { + status = "okay"; +}; + +&adc0 { + pinctrl-0 = <&pinmux_lpadc0>; + pinctrl-names = "default"; + status = "okay"; +}; + +&lpi2c1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpi2c1>; + pinctrl-names = "default"; +}; diff --git a/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.yaml b/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.yaml new file mode 100644 index 0000000000000..b41068a1c998d --- /dev/null +++ b/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.yaml @@ -0,0 +1,19 @@ +identifier: frdm_mcxw72/mcxw727c/cpu0 +name: NXP FRDM_MCXW72 +type: mcu +arch: arm +ram: 264 +flash: 2048 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - can + - counter + - gpio + - i2c + - pinctrl + - pwm + - spi + - uart diff --git a/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0_defconfig b/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0_defconfig new file mode 100644 index 0000000000000..19a6063f6775e --- /dev/null +++ b/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0_defconfig @@ -0,0 +1,12 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_ARM_MPU=y +CONFIG_TRUSTED_EXECUTION_SECURE=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/nxp/frdm_rw612/doc/index.rst b/boards/nxp/frdm_rw612/doc/index.rst index c07d5b49878c7..1bd6b5191a573 100644 --- a/boards/nxp/frdm_rw612/doc/index.rst +++ b/boards/nxp/frdm_rw612/doc/index.rst @@ -36,8 +36,6 @@ Supported Features +-----------+------------+-----------------------------------+ | USART | on-chip | serial | +-----------+------------+-----------------------------------+ -| BLE | on-chip | Bluetooth | -+-----------+------------+-----------------------------------+ | DMA | on-chip | dma | +-----------+------------+-----------------------------------+ | SPI | on-chip | spi | @@ -69,6 +67,8 @@ Supported Features +-----------+------------+-----------------------------------+ | ENET | on-chip | ethernet | +-----------+------------+-----------------------------------+ +| Wi-Fi | on-chip | Wi-Fi | ++-----------+------------+-----------------------------------+ The default configuration can be found in the defconfig file: @@ -76,16 +76,6 @@ The default configuration can be found in the defconfig file: Other hardware features are not currently supported -Fetch Binary Blobs -****************** - -To support Bluetooth, frdm_rw612 requires fetching binary blobs, which can be -achieved by running the following command: - -.. code-block:: console - - west blobs fetch hal_nxp - Programming and Debugging ************************* @@ -147,6 +137,34 @@ should see the following message in the terminal: ***** Booting Zephyr OS zephyr-v3.6.0 ***** Hello World! frdm_rw612 +SRAM Bus Access Partitioning +**************************** + +RW612 supports shared access of the SRAM from both the code bus and data bus. +The bus used to access the SRAM is determined using two separate memory mapped address spaces. +The application can configure the partitioning of the SRAM access regions by a devicetree overlay. +For example, below is part of an overlay to change the whole SRAM to be used for data. + +.. code-block:: devicetree + + &sram_data { + reg = <0x0 DT_SIZE_K(1216)>; + }; + + +Wireless Connectivity Support +***************************** + +Fetch Binary Blobs +================== + +To support Bluetooth or Wi-Fi, frdm_rw612 requires fetching binary blobs, which can be +achieved by running the following command: + +.. code-block:: console + + west blobs fetch hal_nxp + Bluetooth ========= @@ -157,8 +175,18 @@ frdm_rw612 platform supports the monolithic feature. The required binary blob ``/modules/hal/nxp/zephyr/blobs/rw61x_sb_ble_a2.bin`` will be linked with the application image directly, forming one single monolithic image. +Wi-Fi +===== + +Wi-Fi functionality requires to fetch binary blobs, so make sure to follow +the ``Fetch Binary Blobs`` section first. + +frdm_rw612 platform supports the monolithic feature. The required binary blob +``/modules/hal/nxp/zephyr/blobs/rw61x_sb_wifi_a2.bin`` will be linked +with the application image directly, forming one single monolithic image. + Resources -========= +********* .. _RW612 Website: https://www.nxp.com/products/wireless-connectivity/wi-fi-plus-bluetooth-plus-802-15-4/wireless-mcu-with-integrated-tri-radiobr1x1-wi-fi-6-plus-bluetooth-low-energy-5-3-802-15-4:RW612 diff --git a/boards/nxp/frdm_rw612/frdm_rw612.dts b/boards/nxp/frdm_rw612/frdm_rw612.dts index af0aac2372a2e..39a58571779bc 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612.dts +++ b/boards/nxp/frdm_rw612/frdm_rw612.dts @@ -7,219 +7,4 @@ /dts-v1/; #include -#include "frdm_rw612-pinctrl.dtsi" - -/ { - model = "nxp,frdm_rw612"; - - aliases { - led0 = &green_led; - watchdog0 = &wwdt; - usart-0 = &flexcomm3; - i2c-0 = &flexcomm2; - pwm-0 = &sctimer; - }; - - chosen { - zephyr,sram = &sram_data; - zephyr,flash = &w25q512jvfiq; - zephyr,console = &flexcomm3; - zephyr,shell-uart = &flexcomm3; - }; - - leds { - compatible = "gpio-leds"; - green_led: led_1 { - gpios = <&hsgpio0 12 0>; - }; - }; -}; - -&flexcomm3 { - compatible = "nxp,lpc-usart"; - status = "okay"; - current-speed = <115200>; - pinctrl-0 = <&pinmux_flexcomm3_usart>; - pinctrl-names = "default"; -}; - -&flexcomm0 { - compatible = "nxp,lpc-usart"; - status = "disabled"; - current-speed = <115200>; - pinctrl-0 = <&pinmux_flexcomm0_usart>; - pinctrl-names = "default"; -}; - -&hsgpio0 { - status = "okay"; -}; - -&flexspi { - status = "okay"; - ahb-bufferable; - ahb-prefetch; - ahb-cacheable; - ahb-read-addr-opt; - ahb-boundary = "1024"; - rx-clock-source = <1>; - rx-clock-source-b = <1>; - /* Winbond external flash */ - w25q512jvfiq: w25q512jvfiq@0 { - compatible = "nxp,imx-flexspi-nor"; - reg = <0>; - size = ; - status = "okay"; - erase-block-size = <4096>; - write-block-size = <1>; - spi-max-frequency = <104000000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 DT_SIZE_K(128)>; - }; - /* The MCUBoot swap-move algorithm uses the last 2 sectors - * of the primary slot0 for swap status and move. - */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(2 * 4))>; - }; - slot1_partition: partition@323000 { - label = "image-1"; - reg = <0x00323000 DT_SIZE_M(3)>; - }; - storage_partition: partition@623000 { - label = "storage"; - reg = <0x00623000 (DT_SIZE_M(58) - DT_SIZE_K(136))>; - }; - }; - }; - aps6404l: aps6404l@2 { - compatible = "nxp,imx-flexspi-aps6404l"; - /* APS6404L is 8MB, 64MBit pSRAM */ - size = ; - reg = <2>; - spi-max-frequency = <109000000>; - /* PSRAM cannot be enabled while board is in default XIP - * configuration, as it will conflict with flash chip. - */ - status = "disabled"; - cs-interval-unit = <1>; - cs-interval = <2>; - cs-hold-time = <3>; - cs-setup-time = <3>; - data-valid-time = <6>; - column-space = <0>; - ahb-write-wait-unit = <2>; - ahb-write-wait-interval = <0>; - }; -}; - -&hci { - status = "okay"; - wakeup-source; -}; - -&enet_mac { - status = "okay"; - pinctrl-0 = <&pinmux_enet>; - pinctrl-names = "default"; - phy-handle = <&phy>; - zephyr,random-mac-address; - phy-connection-type = "rmii"; -}; - -&enet_mdio { - status = "okay"; - pinctrl-0 = <&pinmux_mdio>; - pinctrl-names = "default"; - phy: phy@2 { - compatible = "microchip,ksz8081"; - reg = <2>; - status = "okay"; - reset-gpios = <&hsgpio1 23 GPIO_ACTIVE_HIGH>; - int-gpios = <&hsgpio0 21 GPIO_ACTIVE_HIGH>; - microchip,interface-type = "rmii"; - }; -}; - -&wwdt { - status = "okay"; -}; - -&dma0 { - status = "okay"; -}; - -&mrt0_channel0 { - status = "okay"; -}; - -&ctimer0 { - status = "okay"; -}; - -&pmu { - reset-causes-en = , - , - ; -}; - -/* OS Timer is the wakeup source for PM mode 2 */ -&os_timer { - status = "okay"; - wakeup-source; -}; - -&systick { - status = "disabled"; -}; - -&adc0 { - status = "okay"; -}; - -&dac0 { - status = "okay"; -}; - -&sctimer { - status = "okay"; - pinctrl-0 = <&pinmux_pwm0>; - pinctrl-names = "default"; -}; - -zephyr_udc0: &usb_otg { - status = "okay"; -}; - -/* - * the default resistors on the board breaks out the MOSI/MISO - * pins to the nets labelled "UART" which go to J1 2 and 4, - * but we are using it for spi mosi and miso here. - * SCK is on J2 6 as labelled. - */ -&flexcomm1 { - compatible = "nxp,lpc-spi"; - pinctrl-0 = <&pinmux_flexcomm1_spi>; - pinctrl-names = "default"; - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; -}; - -arduino_i2c: &flexcomm2 { - compatible = "nxp,lpc-i2c"; - status = "okay"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pinmux_flexcomm2_i2c>; - pinctrl-names = "default"; -}; +#include "frdm_rw612_common.dtsi" diff --git a/boards/nxp/frdm_rw612/frdm_rw612.yaml b/boards/nxp/frdm_rw612/frdm_rw612.yaml index 0ad00472dc293..6ec0eb9bd5172 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612.yaml +++ b/boards/nxp/frdm_rw612/frdm_rw612.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 960 flash: 65536 supported: diff --git a/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi b/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi new file mode 100644 index 0000000000000..0989d83ea3802 --- /dev/null +++ b/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi @@ -0,0 +1,230 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "frdm_rw612-pinctrl.dtsi" + +/ { + model = "nxp,frdm_rw612"; + + aliases { + led0 = &green_led; + watchdog0 = &wwdt; + usart-0 = &flexcomm3; + i2c-0 = &flexcomm2; + pwm-0 = &sctimer; + }; + + chosen { + zephyr,sram = &sram_data; + zephyr,flash = &w25q512jvfiq; + zephyr,console = &flexcomm3; + zephyr,shell-uart = &flexcomm3; + zephyr,flash-controller = &w25q512jvfiq; + zephyr,code-partition = &slot0_partition; + zephyr,uart-mcumgr = &flexcomm3; + }; + + leds { + compatible = "gpio-leds"; + green_led: led_1 { + gpios = <&hsgpio0 12 0>; + }; + }; +}; + +&flexcomm3 { + compatible = "nxp,lpc-usart"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm3_usart>; + pinctrl-names = "default"; +}; + +&flexcomm0 { + compatible = "nxp,lpc-usart"; + status = "disabled"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_usart>; + pinctrl-names = "default"; +}; + +&hsgpio0 { + status = "okay"; +}; + +&flexspi { + status = "okay"; + ahb-bufferable; + ahb-prefetch; + ahb-cacheable; + ahb-read-addr-opt; + ahb-boundary = "1024"; + rx-clock-source = <1>; + rx-clock-source-b = <1>; + /* Winbond external flash */ + w25q512jvfiq: w25q512jvfiq@0 { + compatible = "nxp,imx-flexspi-nor"; + reg = <0>; + size = ; + status = "okay"; + erase-block-size = <4096>; + write-block-size = <1>; + spi-max-frequency = <104000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(128)>; + }; + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. + */ + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(2 * 4))>; + }; + slot1_partition: partition@323000 { + label = "image-1"; + reg = <0x00323000 DT_SIZE_M(3)>; + }; + storage_partition: partition@623000 { + label = "storage"; + reg = <0x00623000 (DT_SIZE_M(58) - DT_SIZE_K(136))>; + }; + }; + }; + aps6404l: aps6404l@2 { + compatible = "nxp,imx-flexspi-aps6404l"; + /* APS6404L is 8MB, 64MBit pSRAM */ + size = ; + reg = <2>; + spi-max-frequency = <109000000>; + /* PSRAM cannot be enabled while board is in default XIP + * configuration, as it will conflict with flash chip. + */ + status = "disabled"; + cs-interval-unit = <1>; + cs-interval = <2>; + cs-hold-time = <3>; + cs-setup-time = <3>; + data-valid-time = <6>; + column-space = <0>; + ahb-write-wait-unit = <2>; + ahb-write-wait-interval = <0>; + }; +}; + +&hci { + status = "okay"; + wakeup-source; +}; + +&enet_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + phy-handle = <&phy>; + zephyr,random-mac-address; + phy-connection-type = "rmii"; +}; + +&enet_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_mdio>; + pinctrl-names = "default"; + phy: phy@2 { + compatible = "microchip,ksz8081"; + reg = <2>; + status = "okay"; + reset-gpios = <&hsgpio1 23 GPIO_ACTIVE_HIGH>; + int-gpios = <&hsgpio0 21 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; + }; +}; + +&wwdt { + status = "okay"; +}; + +&dma0 { + status = "okay"; +}; + +&mrt0_channel0 { + status = "okay"; +}; + +&ctimer0 { + status = "okay"; +}; + +&pmu { + reset-causes-en = , + , + ; +}; + +/* OS Timer is the wakeup source for PM mode 2 */ +&os_timer { + status = "okay"; + wakeup-source; +}; + +&systick { + status = "disabled"; +}; + +&adc0 { + status = "okay"; +}; + +&dac0 { + status = "okay"; +}; + +&sctimer { + status = "okay"; + pinctrl-0 = <&pinmux_pwm0>; + pinctrl-names = "default"; +}; + +&nbu { + status = "okay"; + wakeup-source; +}; + +zephyr_udc0: &usb_otg { + status = "okay"; +}; + +/* + * the default resistors on the board breaks out the MOSI/MISO + * pins to the nets labelled "UART" which go to J1 2 and 4, + * but we are using it for spi mosi and miso here. + * SCK is on J2 6 as labelled. + */ +&flexcomm1 { + compatible = "nxp,lpc-spi"; + pinctrl-0 = <&pinmux_flexcomm1_spi>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; +}; + +arduino_i2c: &flexcomm2 { + compatible = "nxp,lpc-i2c"; + status = "okay"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pinmux_flexcomm2_i2c>; + pinctrl-names = "default"; +}; diff --git a/boards/nxp/hexiwear/hexiwear_mk64f12.dts b/boards/nxp/hexiwear/hexiwear_mk64f12.dts index f41b3410c2c83..b70479153d4ef 100644 --- a/boards/nxp/hexiwear/hexiwear_mk64f12.dts +++ b/boards/nxp/hexiwear/hexiwear_mk64f12.dts @@ -103,7 +103,7 @@ &ftm3 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm3_default>; pinctrl-names = "default"; diff --git a/boards/nxp/hexiwear/hexiwear_mk64f12.yaml b/boards/nxp/hexiwear/hexiwear_mk64f12.yaml index ecf1aa1b8aaab..f545c591d96f8 100644 --- a/boards/nxp/hexiwear/hexiwear_mk64f12.yaml +++ b/boards/nxp/hexiwear/hexiwear_mk64f12.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/nxp/hexiwear/hexiwear_mkw40z4.yaml b/boards/nxp/hexiwear/hexiwear_mkw40z4.yaml index af4d8d5220d1f..e0e49ea82e99b 100644 --- a/boards/nxp/hexiwear/hexiwear_mkw40z4.yaml +++ b/boards/nxp/hexiwear/hexiwear_mkw40z4.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/nxp/imx8mm_evk/doc/index.rst b/boards/nxp/imx8mm_evk/doc/index.rst index 6984f06a8e6db..f234d8feef94a 100644 --- a/boards/nxp/imx8mm_evk/doc/index.rst +++ b/boards/nxp/imx8mm_evk/doc/index.rst @@ -64,6 +64,10 @@ features: +-----------+------------+-------------------------------------+ | ENET | on-chip | ethernet port | +-----------+------------+-------------------------------------+ +| GPIO | on-chip | GPIO ports | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | I2C bus | ++-----------+------------+-------------------------------------+ The Zephyr imx8mm_evk board for Cortex-M4 supports the following hardware features: diff --git a/boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi b/boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi index 9dff995dd9d79..b3f7251becc20 100644 --- a/boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi +++ b/boards/nxp/imx8mm_evk/imx8mm_evk-pinctrl.dtsi @@ -63,4 +63,16 @@ drive-strength = "x6"; }; }; + + pinmux_i2c3: pinmux_i2c3 { + group0 { + pinmux = <&iomuxc_i2c3_scl_i2c_scl_i2c3_scl>, + <&iomuxc_i2c3_sda_i2c_sda_i2c3_sda>; + bias-pull-up; + input-schmitt-enable; + slew-rate = "slow"; + drive-strength = "x4"; + input-enable; + }; + }; }; diff --git a/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_a53.dts b/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_a53.dts index 13213ee010c64..4f1d71902af22 100644 --- a/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_a53.dts +++ b/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_a53.dts @@ -6,6 +6,8 @@ /dts-v1/; +#include +#include #include #include "imx8mm_evk-pinctrl.dtsi" @@ -67,3 +69,23 @@ pinctrl-names = "default"; status = "okay"; }; + +&gpio1 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; + pinctrl-0 = <&pinmux_i2c3>; + pinctrl-names = "default"; + clock-frequency = ; + + gpio_exp1: pca6416@20 { + compatible = "nxp,pca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + interrupt-gpios = <&gpio1 12 (GPIO_ACTIVE_LOW|GPIO_PULL_UP)>; + status = "okay"; + }; +}; diff --git a/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_a53.yaml b/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_a53.yaml index 4132df2e1f6fd..4b60037a0a6b0 100644 --- a/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_a53.yaml +++ b/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_a53.yaml @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -15,6 +15,8 @@ ram: 1024 supported: - uart - net + - gpio + - i2c testing: ignore_tags: - bluetooth diff --git a/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_m4.yaml b/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_m4.yaml index 9ae6cadff5ddb..44c9ea57cdeca 100644 --- a/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_m4.yaml +++ b/boards/nxp/imx8mm_evk/imx8mm_evk_mimx8mm6_m4.yaml @@ -14,7 +14,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/nxp/imx8mn_evk/doc/index.rst b/boards/nxp/imx8mn_evk/doc/index.rst index 265c30be41c13..e488a9a887689 100644 --- a/boards/nxp/imx8mn_evk/doc/index.rst +++ b/boards/nxp/imx8mn_evk/doc/index.rst @@ -64,6 +64,10 @@ features: +-----------+------------+-------------------------------------+ | ENET | on-chip | ethernet port | +-----------+------------+-------------------------------------+ +| GPIO | on-chip | GPIO ports | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | I2C bus | ++-----------+------------+-------------------------------------+ Devices ======== diff --git a/boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi b/boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi index 23326b53f8f42..edc00e207a52e 100644 --- a/boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi +++ b/boards/nxp/imx8mn_evk/imx8mn_evk-pinctrl.dtsi @@ -63,4 +63,16 @@ drive-strength = "x6"; }; }; + + pinmux_i2c3: pinmux_i2c3 { + group0 { + pinmux = <&iomuxc_i2c3_scl_i2c_scl_i2c3_scl>, + <&iomuxc_i2c3_sda_i2c_sda_i2c3_sda>; + bias-pull-up; + input-schmitt-enable; + slew-rate = "slow"; + drive-strength = "x4"; + input-enable; + }; + }; }; diff --git a/boards/nxp/imx8mn_evk/imx8mn_evk_mimx8mn6_a53.dts b/boards/nxp/imx8mn_evk/imx8mn_evk_mimx8mn6_a53.dts index 60ab0ae04ed8e..e1b3d4ec286b9 100644 --- a/boards/nxp/imx8mn_evk/imx8mn_evk_mimx8mn6_a53.dts +++ b/boards/nxp/imx8mn_evk/imx8mn_evk_mimx8mn6_a53.dts @@ -6,6 +6,8 @@ /dts-v1/; +#include +#include #include #include "imx8mn_evk-pinctrl.dtsi" @@ -67,3 +69,23 @@ pinctrl-names = "default"; status = "okay"; }; + +&gpio1 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; + pinctrl-0 = <&pinmux_i2c3>; + pinctrl-names = "default"; + clock-frequency = ; + + gpio_exp1: pca6416@20 { + compatible = "nxp,pca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + interrupt-gpios = <&gpio1 12 (GPIO_ACTIVE_LOW|GPIO_PULL_UP)>; + status = "okay"; + }; +}; diff --git a/boards/nxp/imx8mn_evk/imx8mn_evk_mimx8mn6_a53.yaml b/boards/nxp/imx8mn_evk/imx8mn_evk_mimx8mn6_a53.yaml index a4a5dd0b50a6c..7d50419b06a51 100644 --- a/boards/nxp/imx8mn_evk/imx8mn_evk_mimx8mn6_a53.yaml +++ b/boards/nxp/imx8mn_evk/imx8mn_evk_mimx8mn6_a53.yaml @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -15,6 +15,8 @@ ram: 1024 supported: - uart - net + - gpio + - i2c testing: ignore_tags: - bluetooth diff --git a/boards/nxp/imx8mp_evk/doc/index.rst b/boards/nxp/imx8mp_evk/doc/index.rst index 7afafb3359356..935647045d423 100644 --- a/boards/nxp/imx8mp_evk/doc/index.rst +++ b/boards/nxp/imx8mp_evk/doc/index.rst @@ -62,6 +62,10 @@ features: +-----------+------------+-------------------------------------+ | ENET | on-chip | ethernet port | +-----------+------------+-------------------------------------+ +| GPIO | on-chip | GPIO ports | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | I2C bus | ++-----------+------------+-------------------------------------+ The Zephyr mimx8mp_evk_m7 board configuration supports the following hardware features: diff --git a/boards/nxp/imx8mp_evk/imx8mp_evk-pinctrl.dtsi b/boards/nxp/imx8mp_evk/imx8mp_evk-pinctrl.dtsi index f88555b13e276..dd9346bc19cdc 100644 --- a/boards/nxp/imx8mp_evk/imx8mp_evk-pinctrl.dtsi +++ b/boards/nxp/imx8mp_evk/imx8mp_evk-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 NXP + * Copyright 2022-2025 NXP * SPDX-License-Identifier: Apache-2.0 * */ @@ -7,6 +7,34 @@ #include &pinctrl { + sai3_default: sai3_default { + group0 { + pinmux = <&iomuxc_sai3_txfs_sai_tx_sync_sai3_tx_sync>, + <&iomuxc_sai3_txc_sai_tx_bclk_sai3_tx_bclk>, + <&iomuxc_sai3_rxd_sai_rx_data_sai3_rx_data0>, + <&iomuxc_sai3_txd_sai_tx_data_sai3_tx_data0>, + <&iomuxc_sai3_mclk_sai_mclk_sai3_mclk>; + bias-pull-up; + slew-rate = "fast"; + drive-strength = "x6"; + input-schmitt-enable; + }; + }; + + pdm_default: pdm_default { + group0 { + pinmux = <&iomuxc_sai5_rxc_pdm_clk_pdm_clk>, + <&iomuxc_sai5_rxd0_pdm_bit_stream_pdm_bit_stream0>, + <&iomuxc_sai5_rxd1_pdm_bit_stream_pdm_bit_stream1>, + <&iomuxc_sai5_rxd2_pdm_bit_stream_pdm_bit_stream2>, + <&iomuxc_sai5_rxd3_pdm_bit_stream_pdm_bit_stream3>; + bias-pull-up; + slew-rate = "fast"; + drive-strength = "x6"; + input-schmitt-enable; + }; + }; + uart2_default: uart2_default { group0 { pinmux = <&iomuxc_uart2_rxd_uart_rx_uart2_rx>, @@ -66,4 +94,16 @@ drive-strength = "x1"; }; }; + + pinmux_i2c3: pinmux_i2c3 { + group0 { + pinmux = <&iomuxc_i2c3_scl_i2c_scl_i2c3_scl>, + <&iomuxc_i2c3_sda_i2c_sda_i2c3_sda>; + bias-pull-up; + input-schmitt-enable; + slew-rate = "slow"; + drive-strength = "x4"; + input-enable; + }; + }; }; diff --git a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_a53.dts b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_a53.dts index c50173e3f3a73..01dd37b68c2cc 100644 --- a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_a53.dts +++ b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_a53.dts @@ -1,11 +1,13 @@ /* - * Copyright 2021-2024 NXP + * Copyright 2021-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ /dts-v1/; +#include +#include #include #include "imx8mp_evk-pinctrl.dtsi" @@ -69,3 +71,23 @@ pinctrl-0 = <&uart4_default>; pinctrl-names = "default"; }; + +&i2c3 { + status = "okay"; + pinctrl-0 = <&pinmux_i2c3>; + pinctrl-names = "default"; + clock-frequency = ; + + gpio_exp1: pca6416@20 { + compatible = "nxp,pca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + interrupt-gpios = <&gpio1 12 (GPIO_ACTIVE_LOW|GPIO_PULL_UP)>; + status = "okay"; + }; +}; + +&gpio1 { + status = "okay"; +}; diff --git a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_a53.yaml b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_a53.yaml index dff021eab7e95..bbacbcfd9fd0b 100644 --- a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_a53.yaml +++ b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_a53.yaml @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -15,6 +15,8 @@ ram: 1024 supported: - uart - net + - gpio + - i2c testing: ignore_tags: - bluetooth diff --git a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_adsp.dts b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_adsp.dts index dc8c0ab48a581..bf84ad41c5fea 100644 --- a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_adsp.dts +++ b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_adsp.dts @@ -1,5 +1,5 @@ /* - * Copyright 2021, 2023, 2024 NXP + * Copyright 2021, 2023-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,7 @@ /dts-v1/; #include -#include +#include "imx8mp_evk-pinctrl.dtsi" / { model = "NXP i.MX 8MPLUS Audio DSP"; @@ -21,16 +21,14 @@ }; }; -&pinctrl { - uart4_default: uart4_default { - group0 { - pinmux = <&iomuxc_uart4_rxd_uart_rx_uart4_rx>, - <&iomuxc_uart4_txd_uart_tx_uart4_tx>; - bias-pull-up; - slew-rate = "slow"; - drive-strength = "x1"; - }; - }; +&micfil { + pinctrl-0 = <&pdm_default>; + pinctrl-names = "default"; +}; + +&sai3 { + pinctrl-0 = <&sai3_default>; + pinctrl-names = "default"; }; &uart4 { diff --git a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_m7.yaml b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_m7.yaml index 799c88b4fb3be..bd9c5588ac20a 100644 --- a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_m7.yaml +++ b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_m7.yaml @@ -13,7 +13,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_m7_ddr.yaml b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_m7_ddr.yaml index f76568a30d745..9f841e668b25c 100644 --- a/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_m7_ddr.yaml +++ b/boards/nxp/imx8mp_evk/imx8mp_evk_mimx8ml8_m7_ddr.yaml @@ -13,7 +13,6 @@ flash: 2048 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/nxp/imx8mq_evk/imx8mq_evk_mimx8mq6_m4.yaml b/boards/nxp/imx8mq_evk/imx8mq_evk_mimx8mq6_m4.yaml index acb8e15d8a503..69d3f77231fbc 100644 --- a/boards/nxp/imx8mq_evk/imx8mq_evk_mimx8mq6_m4.yaml +++ b/boards/nxp/imx8mq_evk/imx8mq_evk_mimx8mq6_m4.yaml @@ -13,7 +13,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/nxp/imx8qm_mek/imx8qm_mek_mimx8qm6_adsp.dts b/boards/nxp/imx8qm_mek/imx8qm_mek_mimx8qm6_adsp.dts index 9eddb9385b07f..81daabb579f57 100644 --- a/boards/nxp/imx8qm_mek/imx8qm_mek_mimx8qm6_adsp.dts +++ b/boards/nxp/imx8qm_mek/imx8qm_mek_mimx8qm6_adsp.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include +#include #include "imx8qm_mek_mimx8qm6_adsp-pinctrl.dtsi" / { diff --git a/boards/nxp/imx8qxp_mek/imx8qxp_mek_mimx8qx6_adsp.dts b/boards/nxp/imx8qxp_mek/imx8qxp_mek_mimx8qx6_adsp.dts index f7b1d061d1a12..460ca19029c2a 100644 --- a/boards/nxp/imx8qxp_mek/imx8qxp_mek_mimx8qx6_adsp.dts +++ b/boards/nxp/imx8qxp_mek/imx8qxp_mek_mimx8qx6_adsp.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include +#include #include "imx8qxp_mek_mimx8qx6_adsp-pinctrl.dtsi" / { @@ -31,7 +31,3 @@ pinctrl-0 = <&sai1_default>; pinctrl-names = "default"; }; - -&irqsteer { - reg = <0x51080000 DT_SIZE_K(64)>; -}; diff --git a/boards/nxp/imx91_evk/Kconfig.imx91_evk b/boards/nxp/imx91_evk/Kconfig.imx91_evk new file mode 100644 index 0000000000000..6bfc897688e8d --- /dev/null +++ b/boards/nxp/imx91_evk/Kconfig.imx91_evk @@ -0,0 +1,6 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_IMX91_EVK + select SOC_MIMX9131 + select SOC_PART_NUMBER_MIMX9131CVVXJ diff --git a/boards/nxp/imx91_evk/board.yml b/boards/nxp/imx91_evk/board.yml new file mode 100644 index 0000000000000..8912c7df530d2 --- /dev/null +++ b/boards/nxp/imx91_evk/board.yml @@ -0,0 +1,6 @@ +board: + name: imx91_evk + full_name: i.MX91 EVK + vendor: nxp + socs: + - name: mimx9131 diff --git a/boards/nxp/imx91_evk/doc/index.rst b/boards/nxp/imx91_evk/doc/index.rst new file mode 100644 index 0000000000000..a292670b80e9b --- /dev/null +++ b/boards/nxp/imx91_evk/doc/index.rst @@ -0,0 +1,128 @@ +.. zephyr:board:: imx91_evk + +Overview +******** + +The i.MX 91 Evaluation Kit (MCIMX91-EVK board) is a platform designed +to display the most commonly used features of the i.MX 91 applications +processor. The MCIMX91-EVK board is an entry-level development board +with a small and low-cost package. The board can be used by developers +to get familiar with the processor before investing a large amount of +resources in more specific designs. + +The i.MX 91 applications processor features an Arm Cortex-A55 core +that can operate at speeds of up to 1.4 GHz. + +- Board features: + + - RAM: 2GB LPDDR4 + - Storage: + + - SanDisk 16GB eMMC5.1 + - microSD Socket + - Wireless: + + - Murata Type-2EL (SDIO+UART+SPI) module. It is based on NXP IW612 SoC, + which supports dual-band (2.4 GHz /5 GHz) 1x1 Wi-Fi 6, Bluetooth 5.2, + and 802.15.4 + - USB: + + - Two USB 2.0 Type C connectors + - Ethernet: + + - ENET: 10/100/1000 Mbit/s RGMII Ethernet connected with external PHY + RTL8211 + - ENET_QoS: 10/100/1000 Mbit/s RGMII Ethernet supporting TSN connected + with external PHY RTL8211 + - PCIe: + + - One M.2/NGFF Key E mini card 75-pin connector + - Connectors: + + - 40-Pin Dual Row Header + - LEDs: + + - 1x Power status LED + - 2x UART LED + - Debug: + + - JTAG 20-pin connector + - MicroUSB for UART debug + + +Supported Features +================== + +The ``imx91_evk`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| GIC-v3 | on-chip | interrupt controller | ++-----------+------------+-------------------------------------+ +| ARM TIMER | on-chip | system clock | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++-----------+------------+-------------------------------------+ + +Devices +======== +System Clock +------------ + +This board configuration uses a system clock frequency of 24 MHz. +Cortex-A55 Core runs up to 1.4 GHz. + +Serial Port +----------- + +This board configuration uses a single serial communication channel with the +CPU's UART1 for A55 core. + +Programming and Debugging +******************************* + +U-Boot "go" command is used to load and kick Zephyr to Cortex-A55 Core. + +Copy the compiled ``zephyr.bin`` to the first FAT partition of the SD card and +plug the SD card into the board. Power it up and stop the u-boot execution at +prompt. + +Use U-Boot to load and kick zephyr.bin to Cortex-A55 Core: + +.. code-block:: console + + fatload mmc 1:1 0x80000000 zephyr.bin; dcache flush; icache flush; go 0x80000000 + +Use this configuration to run basic Zephyr applications and kernel tests, +for example, with the :zephyr:code-sample:`synchronization` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: imx91_evk/mimx9131 + :goals: build + +This will build an image with the synchronization sample app, boot it and +display the following console output: + +.. code-block:: console + + *** Booting Zephyr OS build v4.0.0-3277-g69f43115c9a8 *** + thread_a: Hello World from cpu 0 on imx91_evk! + thread_b: Hello World from cpu 0 on imx91_evk! + thread_a: Hello World from cpu 0 on imx91_evk! + thread_b: Hello World from cpu 0 on imx91_evk! + +References +========== + +More information can refer to NXP official website: +`NXP website`_. + +.. _NXP website: + https://www.nxp.com/products/i.MX91 diff --git a/boards/nxp/imx91_evk/imx91_evk-pinctrl.dtsi b/boards/nxp/imx91_evk/imx91_evk-pinctrl.dtsi new file mode 100644 index 0000000000000..94d9f0f7f91c1 --- /dev/null +++ b/boards/nxp/imx91_evk/imx91_evk-pinctrl.dtsi @@ -0,0 +1,29 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +&pinctrl { + uart1_default: uart1_default { + group0 { + pinmux = <&iomuxc1_uart1_rxd_lpuart_rx_lpuart1_rx>, + <&iomuxc1_uart1_txd_lpuart_tx_lpuart1_tx>; + bias-pull-up; + slew-rate = "slightly_fast"; + drive-strength = "x5"; + }; + }; + + uart2_default: uart2_default { + group0 { + pinmux = <&iomuxc1_uart2_rxd_lpuart_rx_lpuart2_rx>, + <&iomuxc1_uart2_txd_lpuart_tx_lpuart2_tx>; + bias-pull-up; + slew-rate = "slightly_fast"; + drive-strength = "x5"; + }; + }; +}; diff --git a/boards/nxp/imx91_evk/imx91_evk_mimx9131.dts b/boards/nxp/imx91_evk/imx91_evk_mimx9131.dts new file mode 100644 index 0000000000000..6b4f464375b08 --- /dev/null +++ b/boards/nxp/imx91_evk/imx91_evk_mimx9131.dts @@ -0,0 +1,34 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "imx91_evk-pinctrl.dtsi" + +/ { + model = "NXP i.MX91 A55"; + compatible = "fsl,mimx91"; + + chosen { + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + /* sram node actually locates at DDR DRAM */ + zephyr,sram = &dram; + }; + + dram: memory@80000000 { + reg = <0x80000000 DT_SIZE_M(1)>; + }; + +}; + +&lpuart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-names = "default"; +}; diff --git a/boards/nxp/imx91_evk/imx91_evk_mimx9131.yaml b/boards/nxp/imx91_evk/imx91_evk_mimx9131.yaml new file mode 100644 index 0000000000000..4302f9566b4d7 --- /dev/null +++ b/boards/nxp/imx91_evk/imx91_evk_mimx9131.yaml @@ -0,0 +1,17 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: imx91_evk/mimx9131 +name: NXP i.MX91 EVK +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +ram: 1024 +supported: + - uart +vendor: nxp diff --git a/boards/nxp/imx91_evk/imx91_evk_mimx9131_defconfig b/boards/nxp/imx91_evk/imx91_evk_mimx9131_defconfig new file mode 100644 index 0000000000000..830456d006d27 --- /dev/null +++ b/boards/nxp/imx91_evk/imx91_evk_mimx9131_defconfig @@ -0,0 +1,30 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +# ARM Options +CONFIG_AARCH64_IMAGE_HEADER=y +CONFIG_ARMV8_A_NS=y + +# MMU Options +# Increase the value when encounter the assert on the MAX_XLAT_TABLES +CONFIG_MAX_XLAT_TABLES=24 + +# Cache Options +CONFIG_CACHE_MANAGEMENT=y +CONFIG_DCACHE_LINE_SIZE_DETECT=y +CONFIG_ICACHE_LINE_SIZE_DETECT=y + +# Zephyr Kernel Configuration +CONFIG_XIP=n + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_CLOCK_CONTROL=y diff --git a/boards/nxp/imx93_evk/Kconfig.imx93_evk b/boards/nxp/imx93_evk/Kconfig.imx93_evk index 412da581ac647..3dec8b2b8baa3 100644 --- a/boards/nxp/imx93_evk/Kconfig.imx93_evk +++ b/boards/nxp/imx93_evk/Kconfig.imx93_evk @@ -3,5 +3,5 @@ config BOARD_IMX93_EVK select SOC_MIMX9352_A55 if BOARD_IMX93_EVK_MIMX9352_A55 - select SOC_MIMX9352_M33 if BOARD_IMX93_EVK_MIMX9352_M33 + select SOC_MIMX9352_M33 if BOARD_IMX93_EVK_MIMX9352_M33 || BOARD_IMX93_EVK_MIMX9352_M33_DDR select SOC_PART_NUMBER_MIMX9352DVVXM diff --git a/boards/nxp/imx93_evk/board.yml b/boards/nxp/imx93_evk/board.yml index 008156c5fa567..f85fa29a0c310 100644 --- a/boards/nxp/imx93_evk/board.yml +++ b/boards/nxp/imx93_evk/board.yml @@ -4,3 +4,6 @@ board: vendor: nxp socs: - name: mimx9352 + variants: + - name: ddr + cpucluster: m33 diff --git a/boards/nxp/imx93_evk/doc/index.rst b/boards/nxp/imx93_evk/doc/index.rst index 88744045727fb..d410cd5dd2600 100644 --- a/boards/nxp/imx93_evk/doc/index.rst +++ b/boards/nxp/imx93_evk/doc/index.rst @@ -240,10 +240,26 @@ prompt. Use U-Boot to load and kick zephyr.bin to Cortex-M33 Core: +Boot with code from TCM +======================= + .. code-block:: console load mmc 1:1 0x80000000 zephyr.bin;cp.b 0x80000000 0x201e0000 0x30000;bootaux 0x1ffe0000 0 +Boot with code from DDR +======================= + +.. code-block:: console + + load mmc 1:1 0x84000000 zephyr.bin;dcache flush;bootaux 0x84000000 0 + +Note: Cortex M33 need execute permission to run code from DDR memory. In order +to enable this, `imx-atf`_ can to be modified in "plat/imx/imx93/trdc_config.h". + +.. _imx-atf: + https://github.com/nxp-imx/imx-atf + Use this configuration to run basic Zephyr applications and kernel tests, for example, with the :zephyr:code-sample:`synchronization` sample: diff --git a/boards/nxp/imx93_evk/dts/imx93_evk_mimx9352_exp_btn.overlay b/boards/nxp/imx93_evk/dts/imx93_evk_mimx9352_exp_btn.overlay index a2aea33b1f633..7ebb35dd483d1 100644 --- a/boards/nxp/imx93_evk/dts/imx93_evk_mimx9352_exp_btn.overlay +++ b/boards/nxp/imx93_evk/dts/imx93_evk_mimx9352_exp_btn.overlay @@ -23,11 +23,13 @@ btn_1: btn_1{ label = "BTN1"; gpios = <&gpio_exp1 5 GPIO_ACTIVE_LOW>; + zephyr,code = ; }; btn_2: btn_2{ label = "BTN2"; gpios = <&gpio_exp1 6 GPIO_ACTIVE_LOW>; + zephyr,code = ; }; }; }; diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_a55.dts b/boards/nxp/imx93_evk/imx93_evk_mimx9352_a55.dts index 389a3cfab0ef1..67272c846b5fd 100644 --- a/boards/nxp/imx93_evk/imx93_evk_mimx9352_a55.dts +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_a55.dts @@ -8,6 +8,7 @@ #include #include "imx93_evk-pinctrl.dtsi" +#include / { model = "NXP i.MX93 A55"; @@ -59,11 +60,13 @@ btn_1: btn_1{ label = "BTN1"; gpios = <&gpio2 23 GPIO_ACTIVE_LOW>; + zephyr,code = ; }; btn_2: btn_2{ label = "BTN2"; gpios = <&gpio2 24 GPIO_ACTIVE_LOW>; + zephyr,code = ; }; }; diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts index 5c75e10ccc9fc..e8db0b549295d 100644 --- a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts @@ -8,6 +8,7 @@ #include #include "imx93_evk-pinctrl.dtsi" +#include / { model = "NXP i.MX93 EVK board"; @@ -50,11 +51,13 @@ btn_1: btn_1{ label = "BTN1"; gpios = <&gpio2 23 GPIO_ACTIVE_LOW>; + zephyr,code = ; }; btn_2: btn_2{ label = "BTN2"; gpios = <&gpio2 24 GPIO_ACTIVE_LOW>; + zephyr,code = ; }; }; }; diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr.dts b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr.dts new file mode 100644 index 0000000000000..7c690afd3f384 --- /dev/null +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr.dts @@ -0,0 +1,23 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "imx93_evk_mimx9352_m33.dts" + +/ { + model = "NXP i.MX93 EVK board DDR variant"; + + chosen { + zephyr,sram = &ddr; + /delete-property/ zephyr,flash; + }; + + ddr: memory@84000000 { + device_type = "memory"; + reg = <0x84000000 DT_SIZE_M(4)>; + }; +}; diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr.yaml b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr.yaml new file mode 100644 index 0000000000000..a322cb1ed7cf6 --- /dev/null +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr.yaml @@ -0,0 +1,16 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +identifier: imx93_evk/mimx9352/m33/ddr +name: NXP i.MX93 EVK M33 DDR +type: mcu +arch: arm +toolchain: + - zephyr + - cross-compile +ram: 4096 +flash: 0 +supported: + - gpio + - uart +vendor: nxp diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr_defconfig b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr_defconfig new file mode 100644 index 0000000000000..75cc33576826e --- /dev/null +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33_ddr_defconfig @@ -0,0 +1,9 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CLOCK_CONTROL=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y +CONFIG_XIP=n diff --git a/boards/nxp/imx95_evk/doc/index.rst b/boards/nxp/imx95_evk/doc/index.rst index 1acf8cc536f5d..71762c3ed5e6f 100644 --- a/boards/nxp/imx95_evk/doc/index.rst +++ b/boards/nxp/imx95_evk/doc/index.rst @@ -92,6 +92,8 @@ The Zephyr ``imx95_evk/mimx9596/m7`` board target supports the following hardwar +-----------+------------+-------------------------------------+ | TPM | on-chip | tpm | +-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ The Zephyr ``imx95_evk/mimx9596/a55`` and ``imx95_evk/mimx9596/a55/smp`` board targets support the following hardware features: @@ -109,6 +111,8 @@ the following hardware features: +-----------+------------+-------------------------------------+ | UART | on-chip | serial port | +-----------+------------+-------------------------------------+ +| TPM | on-chip | tpm | ++-----------+------------+-------------------------------------+ System Clock ------------ @@ -131,6 +135,12 @@ oscilloscope. Channel 2 signal routed to resistance R881. Channel 3 signal routed to resistance R882. +SPI +--- + +The EVK board need to be reworked to solder R1217/R1218/R1219/R1220 with 0R resistances. +SPI1 on J35 is enabled for M7. + Programming and Debugging (A55) ******************************* diff --git a/boards/nxp/imx95_evk/imx95_evk-pinctrl.dtsi b/boards/nxp/imx95_evk/imx95_evk-pinctrl.dtsi index fecd72a46f1a5..5d2811389708e 100644 --- a/boards/nxp/imx95_evk/imx95_evk-pinctrl.dtsi +++ b/boards/nxp/imx95_evk/imx95_evk-pinctrl.dtsi @@ -28,6 +28,18 @@ }; }; + lpspi1_default: lpspi1_default { + group0 { + pinmux = <&iomuxc_sai1_txfs_lpspi_pcs_lpspi1_pcs0>, + <&iomuxc_sai1_txd0_lpspi_sck_lpspi1_sck>, + <&iomuxc_sai1_txc_lpspi_sin_lpspi1_sin>, + <&iomuxc_sai1_rxd0_lpspi_sout_lpspi1_sout>; + bias-pull-down; + slew-rate = "slightly_fast"; + drive-strength = "x4"; + }; + }; + lpuart1_default: lpuart1_default { group0 { pinmux = <&iomuxc_uart1_rxd_lpuart_rx_lpuart1_rx>, diff --git a/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.yaml b/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.yaml index c1183ca216ac5..410193135e807 100644 --- a/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.yaml +++ b/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.yaml @@ -14,4 +14,5 @@ toolchain: ram: 1024 supported: - uart + - counter vendor: nxp diff --git a/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55_smp.yaml b/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55_smp.yaml index 210f5f3278ac7..33f570bd53ade 100644 --- a/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55_smp.yaml +++ b/boards/nxp/imx95_evk/imx95_evk_mimx9596_a55_smp.yaml @@ -15,4 +15,5 @@ ram: 1024 supported: - smp - uart + - counter vendor: nxp diff --git a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts index ebc22540f8eef..f2c74a1278649 100644 --- a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts +++ b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts @@ -35,6 +35,12 @@ status = "okay"; }; +&lpspi1 { + pinctrl-0 = <&lpspi1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + &lpuart3 { status = "okay"; current-speed = <115200>; diff --git a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.yaml b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.yaml index 23fab0caeabb8..428cf60cb088c 100644 --- a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.yaml +++ b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.yaml @@ -13,9 +13,9 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - i2c - pwm + - spi vendor: nxp diff --git a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7_ddr.yaml b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7_ddr.yaml index b1f0b22dfc9f8..8a1674b8bd9e1 100644 --- a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7_ddr.yaml +++ b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7_ddr.yaml @@ -12,7 +12,6 @@ ram: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart vendor: nxp diff --git a/boards/nxp/lpcxpresso51u68/lpcxpresso51u68.yaml b/boards/nxp/lpcxpresso51u68/lpcxpresso51u68.yaml index 1c7a0644a10d4..91fbd6f992a1f 100644 --- a/boards/nxp/lpcxpresso51u68/lpcxpresso51u68.yaml +++ b/boards/nxp/lpcxpresso51u68/lpcxpresso51u68.yaml @@ -13,7 +13,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml index 8f99d4bbd9db9..8294367fcbd02 100644 --- a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml +++ b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml @@ -14,7 +14,6 @@ testing: ignore_tags: - net toolchain: - - xtools - zephyr - gnuarmemb vendor: nxp diff --git a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml index f2ed30e6976ff..f1f13fb5cdae6 100644 --- a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml +++ b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml @@ -13,7 +13,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_i2c - arduino_spi diff --git a/boards/nxp/lpcxpresso55s06/lpcxpresso55s06.yaml b/boards/nxp/lpcxpresso55s06/lpcxpresso55s06.yaml index f6cbb2e4e6e43..958a493b81a67 100644 --- a/boards/nxp/lpcxpresso55s06/lpcxpresso55s06.yaml +++ b/boards/nxp/lpcxpresso55s06/lpcxpresso55s06.yaml @@ -12,7 +12,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - can - flash diff --git a/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.dts b/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.dts index 9a19e69aed7fc..0baeb3e629322 100644 --- a/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.dts +++ b/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.dts @@ -26,7 +26,7 @@ zephyr_udc0: &usbhs { status = "okay"; - phy_handle = <&usbphy1>; + phy-handle = <&usbphy1>; }; &usbphy1 { diff --git a/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml b/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml index 8b930b43ae5f5..797e5a680f0ea 100644 --- a/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml +++ b/boards/nxp/lpcxpresso55s16/lpcxpresso55s16.yaml @@ -13,7 +13,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/nxp/lpcxpresso55s28/lpcxpresso55s28.yaml b/boards/nxp/lpcxpresso55s28/lpcxpresso55s28.yaml index 898d75c9c2737..5f98a3ebeb3eb 100644 --- a/boards/nxp/lpcxpresso55s28/lpcxpresso55s28.yaml +++ b/boards/nxp/lpcxpresso55s28/lpcxpresso55s28.yaml @@ -13,7 +13,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml index aec2ca1f6ac97..660145eaf23af 100644 --- a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml +++ b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml @@ -13,7 +13,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - can diff --git a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0.dts b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0.dts index e87cb04fc7996..b966c8545e647 100644 --- a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0.dts +++ b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0.dts @@ -152,7 +152,7 @@ zephyr_udc0: &usbhs { status = "okay"; - phy_handle = <&usbphy1>; + phy-handle = <&usbphy1>; }; &usbphy1 { diff --git a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0.yaml b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0.yaml index bd616045798e7..cec1ec0332a2b 100644 --- a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0.yaml +++ b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0.yaml @@ -13,7 +13,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml index 5d76704ba7b54..2b3541c40f62b 100644 --- a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml +++ b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml @@ -13,7 +13,6 @@ flash: 96 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_spi diff --git a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu1.yaml b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu1.yaml index 4d6f1c70ab8e8..1576a30e5daa5 100644 --- a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu1.yaml +++ b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu1.yaml @@ -13,7 +13,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio vendor: nxp diff --git a/boards/nxp/mcxw72_evk/Kconfig.mcxw72_evk b/boards/nxp/mcxw72_evk/Kconfig.mcxw72_evk new file mode 100644 index 0000000000000..8b851a30e8067 --- /dev/null +++ b/boards/nxp/mcxw72_evk/Kconfig.mcxw72_evk @@ -0,0 +1,6 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MCXW72_EVK + select SOC_MCXW727C_CPU0 if BOARD_MCXW72_EVK_MCXW727C_CPU0 + select SOC_PART_NUMBER_MCXW727CMFTA diff --git a/boards/nxp/mcxw72_evk/board.cmake b/boards/nxp/mcxw72_evk/board.cmake new file mode 100644 index 0000000000000..6282eec263b61 --- /dev/null +++ b/boards/nxp/mcxw72_evk/board.cmake @@ -0,0 +1,8 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(linkserver "--device=MCXW727C:MCX-W72-EVK") +board_runner_args(jlink "--device=MCXW727" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/mcxw72_evk/board.yml b/boards/nxp/mcxw72_evk/board.yml new file mode 100644 index 0000000000000..d63ad4b623ea7 --- /dev/null +++ b/boards/nxp/mcxw72_evk/board.yml @@ -0,0 +1,6 @@ +board: + name: mcxw72_evk + full_name: MCXW72-EVK + vendor: nxp + socs: + - name: mcxw727c diff --git a/boards/nxp/mcxw72_evk/doc/index.rst b/boards/nxp/mcxw72_evk/doc/index.rst new file mode 100644 index 0000000000000..d15433e2d5eae --- /dev/null +++ b/boards/nxp/mcxw72_evk/doc/index.rst @@ -0,0 +1,183 @@ +.. zephyr:board:: mcxw72_evk + +Overview +******** + +The MCXW72-EVK + +The MCX W72x family features a 96 MHz ArmÂŽ CortexÂŽ-M33 core coupled with a +multiprotocol radio subsystem supporting Matter, Thread, Zigbee and +Bluetooth LE. The independent radio subsystem, with a dedicated core and +memory, offloads the main CPU, preserving it for the primary application and +allowing firmware updates to support future wireless standards. + +Hardware +******** + +- MCXW72 Arm Cortex-M33 microcontroller running up to 96 MHz +- 2MB on-chip Flash memory unit +- 256 KB TCM RAM +- On-board MCU-Link debugger with CMSIS-DAP + +For more information about the MCXW72 SoC and MCXW72-EVK board, see: + +- `MCXW72 SoC Website`_ +- `MCXW72-EVK Website`_ + +Supported Features +================== + +The ``mcxw72_evk`` board in Zephyr currently supports the following features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinctrl | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| LPUART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| TPM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| LPTMR | on-chip | counter | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| FLEXCAN | on-chip | can | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ + +Fetch Binary Blobs +****************** + +To support Bluetooth, mcxw72_evk requires fetching binary blobs, which can be +achieved by running the following command: + +.. code-block:: console + + west blobs fetch hal_nxp + +Programming and Debugging +************************* + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Debug Probe +========================= + +A debug probe is used for both flashing and debugging the board. This board is +configured by default to use the MCU-Link CMSIS-DAP Onboard Debug Probe. + +Using LinkServer +---------------- + +Linkserver is the default runner for this board, and supports the factory +default MCU-Link firmware. Follow the instructions in +:ref:`mcu-link-cmsis-onboard-debug-probe` to reprogram the default MCU-Link +firmware. This only needs to be done if the default onboard debug circuit +firmware was changed. To put the board in ``DFU mode`` to program the firmware, +short jumper JP20. + +Using J-Link +------------ + +There are two options. The onboard debug circuit can be updated with Segger +J-Link firmware by following the instructions in +:ref:`mcu-link-jlink-onboard-debug-probe`. +To be able to program the firmware, you need to put the board in ``DFU mode`` +by shortening the jumper JP20. +The second option is to attach a :ref:`jlink-external-debug-probe` to the +10-pin SWD connector (J16) of the board. +For both options use the ``-r jlink`` option with west to use the jlink runner. + +.. code-block:: console + + west flash -r jlink + +Configuring a Console +===================== + +Connect a USB cable from your PC to J14, and use the serial terminal of your choice +(minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing +======== + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mcxw72_evk/mcxw727c/cpu0 + :goals: flash + +Open a serial terminal, reset the board (press the RESET button), and you should +see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v3.7.0-xxx-xxxx *** + Hello World! mcxw72_evk/mcxw727c/cpu0 + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mcxw72_evk/mcxw727c/cpu0 + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v3.7.0-xxx-xxxx *** + Hello World! mcxw72_evk/mcxw727c/cpu0 + +Bluetooth +========= + +BLE functionality requires to fetch binary blobs, so make sure to follow +the ``Fetch Binary Blobs`` section first. + +Two images must be written to the board: one for the host (CM33 core0) and one for the NBU (CM33 core1). +- To flash the application (CM33) refer to the ``Flashing`` section above. +- To flash the NBU, follow the instructions below: + +.. code-block:: console + + JLinkExe -device MCXW727C_CORE1 -if SWD -speed 4000 -autoconnect 1 + J-Link>loadbin 0x0 + +Troubleshooting +=============== + +.. include:: ../../common/segger-ecc-systemview.rst + :start-after: segger-ecc-systemview + +References +********** + +.. target-notes:: + +.. _MCXW72 SoC Website: + https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/mcx-arm-cortex-m/mcx-w-series-microcontrollers/mcx-w72x-secure-and-ultra-low-power-mcus-for-matter-thread-zigbee-and-bluetooth-le:MCX-W72X + +.. _MCXW72-EVK Website: diff --git a/boards/nxp/mcxw72_evk/doc/mcxw72_evk.webp b/boards/nxp/mcxw72_evk/doc/mcxw72_evk.webp new file mode 100644 index 0000000000000..cfa1e64703715 Binary files /dev/null and b/boards/nxp/mcxw72_evk/doc/mcxw72_evk.webp differ diff --git a/boards/nxp/mcxw72_evk/mcxw72_evk-pinctrl.dtsi b/boards/nxp/mcxw72_evk/mcxw72_evk-pinctrl.dtsi new file mode 100644 index 0000000000000..08289d5e5c3ae --- /dev/null +++ b/boards/nxp/mcxw72_evk/mcxw72_evk-pinctrl.dtsi @@ -0,0 +1,82 @@ +/* + * Copyright 2024 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + pinmux_lpuart0: pinmux_lpuart0 { + group0 { + pinmux = , ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart1: pinmux_lpuart1 { + group0 { + pinmux = , ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_tpm0: pinmux_tpm0 { + group0 { + pinmux = , , + , ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_lpspi1: pinmux_lpspi1 { + group0 { + pinmux = , + , + , + ; + slew-rate = "fast"; + drive-strength = "low"; + }; + }; + + pinmux_flexcan: pinmux_flexcan { + group0 { + pinmux = , ; + slew-rate = "slow"; + drive-strength = "low"; + }; + }; + + pinmux_lpadc0: pinmux_lpadc0 { + group0 { + pinmux = , + , + ; + drive-strength = "low"; + slew-rate = "fast"; + }; + }; + + pinmux_lpi2c0: pinmux_lpi2c0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + drive-open-drain; + }; + }; + + pinmux_lpi2c1: pinmux_lpi2c1 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + drive-open-drain; + }; + }; +}; diff --git a/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.dts b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.dts new file mode 100644 index 0000000000000..9ca8151c29522 --- /dev/null +++ b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.dts @@ -0,0 +1,140 @@ +/* + * Copyright 2024 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "mcxw72_evk-pinctrl.dtsi" + +/ { + model = "NXP MCXW72-EVK board"; + + aliases { + led0 = &blue_led; + blue-pwm-led = &blue_pwm_led; + green-pwm-led = &green_pwm_led; + red-pwm-led = &red_pwm_led; + }; + + chosen { + zephyr,flash = &flash; + zephyr,flash-controller = &fmu; + zephyr,code-partition = &code_partition; + zephyr,sram = &stcm0; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + zephyr,uart-pipe = &lpuart0; + zephyr,canbus = &flexcan0; + }; + + user_led { + compatible = "gpio-leds"; + blue_led: led { + gpios = <&gpioc 1 GPIO_ACTIVE_HIGH>; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + blue_pwm_led: pwm_led_0 { + pwms = <&tpm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + green_pwm_led: pwm_led_1 { + pwms = <&tpm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + red_pwm_led: pwm_led_2 { + pwms = <&tpm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + }; +}; + +&gpioa { + status = "okay"; +}; + + +&gpioc { + status = "okay"; +}; + +&lpuart0 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&pinmux_lpuart0>; + pinctrl-names = "default"; +}; + +&lpuart1 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&pinmux_lpuart1>; + pinctrl-names = "default"; +}; + +&flash { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + code_partition: partition@0 { + reg = <0x0 DT_SIZE_K(67)>; + }; + + storage_partition: partition@10c00 { + reg = <0x10c00 DT_SIZE_K(1981)>; + }; + }; +}; + +&fmu { + status = "okay"; +}; + +&tpm0 { + status = "okay"; + pinctrl-0 = <&pinmux_tpm0>; + pinctrl-names = "default"; +}; + +&lptmr0 { + status = "okay"; +}; + +&lpspi1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpspi1>; + pinctrl-names = "default"; +}; + +&flexcan0 { + status = "okay"; + pinctrl-0 = <&pinmux_flexcan>; + pinctrl-names = "default"; + + can-transceiver { + max-bitrate = <5000000>; + }; +}; + +&vref { + status = "okay"; +}; + +&adc0 { + pinctrl-0 = <&pinmux_lpadc0>; + pinctrl-names = "default"; + status = "okay"; +}; + +&lpi2c1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpi2c1>; + pinctrl-names = "default"; +}; + +&rtc { + status = "okay"; +}; diff --git a/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml new file mode 100644 index 0000000000000..f3f9a54cf1da3 --- /dev/null +++ b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml @@ -0,0 +1,19 @@ +identifier: mcxw72_evk/mcxw727c/cpu0 +name: NXP MCXW72_EVK +type: mcu +arch: arm +ram: 264 +flash: 2048 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - can + - counter + - gpio + - i2c + - pinctrl + - pwm + - spi + - uart diff --git a/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0_defconfig b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0_defconfig new file mode 100644 index 0000000000000..19a6063f6775e --- /dev/null +++ b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0_defconfig @@ -0,0 +1,12 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_ARM_MPU=y +CONFIG_TRUSTED_EXECUTION_SECURE=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/nxp/mimxrt1010_evk/mimxrt1010_evk.yaml b/boards/nxp/mimxrt1010_evk/mimxrt1010_evk.yaml index f9c8719a8dedf..b205958cf29b2 100644 --- a/boards/nxp/mimxrt1010_evk/mimxrt1010_evk.yaml +++ b/boards/nxp/mimxrt1010_evk/mimxrt1010_evk.yaml @@ -12,7 +12,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 16384 supported: diff --git a/boards/nxp/mimxrt1015_evk/mimxrt1015_evk.yaml b/boards/nxp/mimxrt1015_evk/mimxrt1015_evk.yaml index 80afd63da22b7..8f6d9713bc65d 100644 --- a/boards/nxp/mimxrt1015_evk/mimxrt1015_evk.yaml +++ b/boards/nxp/mimxrt1015_evk/mimxrt1015_evk.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 16384 supported: diff --git a/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.yaml b/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.yaml index 88c5629fa0c9f..886968e1c76a4 100644 --- a/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.yaml +++ b/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 8192 supported: diff --git a/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.yaml b/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.yaml index 67fad31a54d8d..4d2bfe65864d0 100644 --- a/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.yaml +++ b/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 4096 supported: diff --git a/boards/nxp/mimxrt1040_evk/doc/index.rst b/boards/nxp/mimxrt1040_evk/doc/index.rst index 8f9f4edf8da21..8ec0834b47b24 100644 --- a/boards/nxp/mimxrt1040_evk/doc/index.rst +++ b/boards/nxp/mimxrt1040_evk/doc/index.rst @@ -89,36 +89,37 @@ NXP prioritizes enabling the superset board with NXP's Full Platform Support for Zephyr. Therefore, the mimxrt1064_evk board may have additional features already supported, which can also be re-used on this mimxrt1040_evk board: -+-----------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+=====================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+-------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+-------------------------------------+ -| UART | on-chip | serial port-polling; | -| | | serial port-interrupt | -+-----------+------------+-------------------------------------+ -| PWM | on-chip | pwm | -+-----------+------------+-------------------------------------+ -| ADC | on-chip | adc | -+-----------+------------+-------------------------------------+ -| SPI | on-chip | spi | -+-----------+------------+-------------------------------------+ -| DMA | on-chip | dma | -+-----------+------------+-------------------------------------+ -| I2C | on-chip | i2c | -+-----------+------------+-------------------------------------+ -| GPT | on-chip | gpt | -+-----------+------------+-------------------------------------+ -| DISPLAY | on-chip | eLCDIF. Tested with | -| | | :ref:`rk043fn02h_ct`, and | -| | | :ref:`rk043fn66hs_ctg` shields | -+-----------+------------+-------------------------------------+ -| UART | NXP NW61x | M.2 WIFI/BT module | -+-----------+------------+-------------------------------------+ ++-----------+------------+-------------------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=================================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------------------+ +| DMA | on-chip | dma | ++-----------+------------+-------------------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------------------+ +| GPT | on-chip | gpt | ++-----------+------------+-------------------------------------------------+ +| DISPLAY | on-chip | eLCDIF. Tested with | +| | | :ref:`rk043fn02h_ct`, and | +| | | :ref:`rk043fn66hs_ctg` shields | ++-----------+------------+-------------------------------------------------+ +| UART | NXP IW61x | M.2 WIFI/BT module | +| | | (select :kconfig:option:`CONFIG_BT_NXP_NW612`) | ++-----------+------------+-------------------------------------------------+ The default configuration can be found in :zephyr_file:`boards/nxp/mimxrt1040_evk/mimxrt1040_evk_defconfig` diff --git a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml index 3d5aeefadcd52..b4cf62676db28 100644 --- a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml +++ b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 8192 supported: diff --git a/boards/nxp/mimxrt1050_evk/Kconfig.defconfig b/boards/nxp/mimxrt1050_evk/Kconfig.defconfig index 5660385019582..90fc7a76598f5 100644 --- a/boards/nxp/mimxrt1050_evk/Kconfig.defconfig +++ b/boards/nxp/mimxrt1050_evk/Kconfig.defconfig @@ -10,6 +10,7 @@ config DEVICE_CONFIGURATION_DATA config NXP_IMX_EXTERNAL_SDRAM default y + if NETWORKING config NET_L2_ETHERNET diff --git a/boards/nxp/mimxrt1050_evk/board.cmake b/boards/nxp/mimxrt1050_evk/board.cmake index c53e6474ca1bc..321eeee813445 100644 --- a/boards/nxp/mimxrt1050_evk/board.cmake +++ b/boards/nxp/mimxrt1050_evk/board.cmake @@ -3,10 +3,17 @@ # # SPDX-License-Identifier: Apache-2.0 # + +if(NOT ("${BOARD_QUALIFIERS}" MATCHES "qspi" + OR "${BOARD_QUALIFIERS}" MATCHES "hyperflash")) + message(FATAL_ERROR "Please specify a board flash variant for the mimxrt1050_evk:\n" + "mimxrt1050_evk/mimxrt1052/qspi or mimxrt1050_evk/mimxrt1052/hyperflash\n") +endif() + board_runner_args(jlink "--device=MCIMXRT1052") board_runner_args(linkserver "--device=MIMXRT1052xxxxB:EVKB-IMXRT1050") -if("${BOARD_REVISION}" STREQUAL "qspi") +if("${BOARD_QUALIFIERS}" MATCHES "qspi") board_runner_args(jlink "--loader=BankAddr=0x60000000&Loader=QSPI") board_runner_args(pyocd "--target=mimxrt1050_quadspi") board_runner_args(linkserver "--override=/device/memory/3/flash-driver=MIMXRT1050_SFDP_QSPI.cfx") diff --git a/boards/nxp/mimxrt1050_evk/board.yml b/boards/nxp/mimxrt1050_evk/board.yml index 48b8680e4b5cd..0d06dbd8d1a5b 100644 --- a/boards/nxp/mimxrt1050_evk/board.yml +++ b/boards/nxp/mimxrt1050_evk/board.yml @@ -4,9 +4,6 @@ board: vendor: nxp socs: - name: mimxrt1052 - revision: - format: "custom" - default: "hyperflash" - revisions: - - name: "hyperflash" - - name: "qspi" + variants: + - name: hyperflash + - name: qspi diff --git a/boards/nxp/mimxrt1050_evk/doc/index.rst b/boards/nxp/mimxrt1050_evk/doc/index.rst index 71e4fd4b96722..379498dd33b68 100644 --- a/boards/nxp/mimxrt1050_evk/doc/index.rst +++ b/boards/nxp/mimxrt1050_evk/doc/index.rst @@ -138,7 +138,7 @@ already supported, which can also be re-used on this mimxrt1050_evk board: +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/nxp/mimxrt1050_evk/mimxrt1050_evk_defconfig` +:zephyr_file:`boards/nxp/mimxrt1050_evk/mimxrt1050_evk_hyperflash_defconfig` Other hardware features are not currently supported by the port. @@ -298,6 +298,17 @@ The RT1050 SoC has two USB OTG (USBOTG) controllers that supports both device and host functions through its micro USB connectors. Only USB device function is supported in Zephyr at the moment. +Board Targets +************* + +This board has two variants that can be targeted, +depending on which flash to set as ``zephyr,flash``: + +* ``mimxrt1050_evk/mimxrt1052/hyperflash`` is the default variant for the out of box + setup of the board using hyperflash. +* ``mimxrt1050_evk/mimxrt1052/qspi`` is for a board that has been reworked to use the + qspi flash instead of hyperflash. + Programming and Debugging ************************* @@ -364,7 +375,7 @@ Here is an example for the :zephyr:code-sample:`hello_world` application. .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: mimxrt1050_evk + :board: mimxrt1050_evk//hyperflash :goals: flash Open a serial terminal, reset the board (press the SW4 button), and you should @@ -373,7 +384,7 @@ see the following message in the terminal: .. code-block:: console ***** Booting Zephyr OS v1.14.0-rc1 ***** - Hello World! mimxrt1050_evk + Hello World! mimxrt1050_evk//hyperflash Debugging ========= @@ -382,7 +393,7 @@ Here is an example for the :zephyr:code-sample:`hello_world` application. .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: mimxrt1050_evk + :board: mimxrt1050_evk//hyperflash :goals: debug Open a serial terminal, step through the application in your debugger, and you @@ -391,7 +402,7 @@ should see the following message in the terminal: .. code-block:: console ***** Booting Zephyr OS v1.14.0-rc1 ***** - Hello World! mimxrt1050_evk + Hello World! mimxrt1050_evk//hyperflash Troubleshooting =============== diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dts b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dts deleted file mode 100644 index 3879b04cb506a..0000000000000 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dts +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2017, NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; - -#include -#include "mimxrt1050_evk-pinctrl.dtsi" -#include - -/ { - model = "NXP MIMXRT1050-EVK board"; - compatible = "nxp,mimxrt1052"; - - aliases { - led0 = &green_led; - sw0 = &user_button; - watchdog0 = &wdog0; - magn0 = &fxos8700; - accel0 = &fxos8700; - sdhc0 = &usdhc1; - mcuboot-button0 = &user_button; - }; - - chosen { - zephyr,sram = &sdram0; - zephyr,itcm = &itcm; - zephyr,dtcm = &dtcm; - zephyr,uart-mcumgr = &lpuart1; - zephyr,console = &lpuart1; - zephyr,shell-uart = &lpuart1; - }; - - sdram0: memory@80000000 { - /* Micron MT48LC16M16A2B4-6AIT:G */ - device_type = "memory"; - reg = <0x80000000 DT_SIZE_M(32)>; - }; - - /* - * This node describes the GPIO pins of the parallel FPC interface, - * This interface is standard to several NXP EVKs, and is used with - * several parallel LCD displays (available as zephyr shields) - */ - nxp_parallel_lcd_connector: parallel-connector { - compatible = "nxp,parallel-lcd-connector"; - #gpio-cells = <2>; - gpio-map-mask = <0xffffffff 0xffffffc0>; - gpio-map-pass-thru = <0 0x3f>; - gpio-map = <0 0 &gpio2 31 0>; /* Pin 1, BL+ */ - }; - - /* - * This node describes the GPIO pins of the I2C display FPC interface, - * This interface is standard to several NXP EVKs, and is used with - * several parallel LCD displays (available as zephyr shields) - */ - nxp_i2c_touch_fpc: i2c-touch-connector { - compatible = "nxp,i2c-tsc-fpc"; - #gpio-cells = <2>; - gpio-map-mask = <0xffffffff 0xffffffc0>; - gpio-map-pass-thru = <0 0x3f>; - gpio-map = <1 0 &gpio1 2 0>, /* Pin 2, LCD touch RST */ - <2 0 &gpio1 11 0>; /* Pin 3, LCD touch INT */ - }; - - leds { - compatible = "gpio-leds"; - green_led: led_0 { - gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; - label = "User LD1"; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - user_button: button_0 { - label = "User SW8"; - gpios = <&gpio5 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - zephyr,code = ; - }; - }; - - arduino_header: connector { - compatible = "arduino-header-r3"; - #gpio-cells = <2>; - gpio-map-mask = <0xffffffff 0xffffffc0>; - gpio-map-pass-thru = <0 0x3f>; - gpio-map = <0 0 &gpio1 26 0>, /* A0 */ - <1 0 &gpio1 27 0>, /* A1 */ - <2 0 &gpio1 20 0>, /* A2 */ - <3 0 &gpio1 21 0>, /* A3 */ - <4 0 &gpio1 17 0>, /* A4 */ - <5 0 &gpio1 16 0>, /* A5 */ - <6 0 &gpio1 23 0>, /* D0 */ - <7 0 &gpio1 22 0>, /* D1 */ - <8 0 &gpio1 11 0>, /* D2 */ - <9 0 &gpio1 24 0>, /* D3 */ - <10 0 &gpio1 9 0>, /* D4 */ - <11 0 &gpio1 10 0>, /* D5 */ - <12 0 &gpio1 18 0>, /* D6 */ - <13 0 &gpio1 19 0>, /* D7 */ - <14 0 &gpio1 3 0>, /* D8 */ - <15 0 &gpio1 2 0>, /* D9 */ - <16 0 &gpio3 13 0>, /* D10 */ - <17 0 &gpio3 14 0>, /* D11 */ - <18 0 &gpio3 15 0>, /* D12 */ - <19 0 &gpio3 12 0>, /* D13 */ - <20 0 &gpio1 1 0>, /* D14 */ - <21 0 &gpio1 0 0>; /* D15 */ - }; -}; - -arduino_serial: &lpuart3 { - pinctrl-0 = <&pinmux_lpuart3>; - pinctrl-1 = <&pinmux_lpuart3_sleep>; - pinctrl-names = "default", "sleep"; -}; - -&adc1 { - status = "okay"; - pinctrl-0 = <&pinmux_adc1>; - pinctrl-names = "default"; -}; - -nxp_touch_i2c: &lpi2c1 {}; - -zephyr_lcdif: &lcdif { - pinctrl-0 = <&pinmux_lcdif>; - pinctrl-names = "default"; -}; - -&lpi2c1 { - status = "okay"; - pinctrl-0 = <&pinmux_lpi2c1>; - pinctrl-names = "default"; - - fxos8700: fxos8700@1f { - compatible = "nxp,fxos8700"; - reg = <0x1f>; - - /* Two zero ohm resistors (R263 and R264) isolate sensor - * interrupt gpios from the soc and are unpopulated by default. - * Note that if you populate them, they conflict with LCD and - * Ethernet interrupt gpios. - */ - int1-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; - int2-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; - }; -}; - -&lpuart1 { - status = "okay"; - current-speed = <115200>; - pinctrl-0 = <&pinmux_lpuart1>; - pinctrl-1 = <&pinmux_lpuart1_sleep>; - pinctrl-names = "default", "sleep"; -}; - -&lpspi1 { - status = "okay"; - /* DMA channels 0 and 1, muxed to LPSPI1 RX and TX */ - dmas = <&edma0 0 13>, <&edma0 1 14>; - dma-names = "rx", "tx"; - pinctrl-0 = <&pinmux_lpspi1>; - pinctrl-names = "default"; -}; - -&lpspi3 { - status = "okay"; - /* DMA channels 2 and 3, muxed to LPSPI3 RX and TX */ - dmas = <&edma0 2 15>, <&edma0 3 16>; - dma-names = "rx", "tx"; - pinctrl-0 = <&pinmux_lpspi3>; - pinctrl-names = "default"; -}; - -&enet_mac { - status = "okay"; - pinctrl-0 = <&pinmux_enet>; - pinctrl-names = "default"; - phy-handle = <&phy>; - zephyr,random-mac-address; - phy-connection-type = "rmii"; -}; - -&enet_mdio { - status = "okay"; - pinctrl-0 = <&pinmux_enet_mdio>; - pinctrl-names = "default"; - phy: phy@0 { - compatible = "microchip,ksz8081"; - reg = <0>; - status = "okay"; - reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; - int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; - microchip,interface-type = "rmii"; - }; -}; - -&enet_ptp_clock { - status = "okay"; - pinctrl-0 = <&pinmux_ptp>; - pinctrl-names = "default"; -}; - -zephyr_udc0: &usb1 { - status = "okay"; -}; - -&usdhc1 { - status = "okay"; - pwr-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; - cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pinmux_usdhc1>; - pinctrl-1 = <&pinmux_usdhc1_slow>; - pinctrl-2 = <&pinmux_usdhc1_med>; - pinctrl-3 = <&pinmux_usdhc1_fast>; - pinctrl-names = "default", "slow", "med", "fast"; - sdmmc { - compatible = "zephyr,sdmmc-disk"; - disk-name = "SD"; - status = "okay"; - }; -}; - -&wdog0 { - status = "okay"; -}; - -&edma0 { - status = "okay"; -}; - -&pxp { - status = "okay"; -}; - -/* GPT and Systick are enabled. If power management is enabled, the GPT - * timer will be used instead of systick, as allows the core clock to - * be gated. - */ -&gpt_hw_timer { - status = "okay"; -}; - -&systick { - status = "okay"; -}; diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dtsi b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dtsi new file mode 100644 index 0000000000000..4fdca2496d330 --- /dev/null +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dtsi @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2017, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "mimxrt1050_evk-pinctrl.dtsi" +#include + +/ { + model = "NXP MIMXRT1050-EVK board"; + compatible = "nxp,mimxrt1052"; + + aliases { + led0 = &green_led; + sw0 = &user_button; + watchdog0 = &wdog0; + magn0 = &fxos8700; + accel0 = &fxos8700; + sdhc0 = &usdhc1; + mcuboot-button0 = &user_button; + }; + + chosen { + zephyr,sram = &sdram0; + zephyr,itcm = &itcm; + zephyr,dtcm = &dtcm; + zephyr,uart-mcumgr = &lpuart1; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + }; + + sdram0: memory@80000000 { + /* Micron MT48LC16M16A2B4-6AIT:G */ + device_type = "memory"; + reg = <0x80000000 DT_SIZE_M(32)>; + }; + + /* + * This node describes the GPIO pins of the parallel FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_parallel_lcd_connector: parallel-connector { + compatible = "nxp,parallel-lcd-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio2 31 0>; /* Pin 1, BL+ */ + }; + + /* + * This node describes the GPIO pins of the I2C display FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_i2c_touch_fpc: i2c-touch-connector { + compatible = "nxp,i2c-tsc-fpc"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <1 0 &gpio1 2 0>, /* Pin 2, LCD touch RST */ + <2 0 &gpio1 11 0>; /* Pin 3, LCD touch INT */ + }; + + leds { + compatible = "gpio-leds"; + green_led: led_0 { + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + label = "User LD1"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button_0 { + label = "User SW8"; + gpios = <&gpio5 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio1 26 0>, /* A0 */ + <1 0 &gpio1 27 0>, /* A1 */ + <2 0 &gpio1 20 0>, /* A2 */ + <3 0 &gpio1 21 0>, /* A3 */ + <4 0 &gpio1 17 0>, /* A4 */ + <5 0 &gpio1 16 0>, /* A5 */ + <6 0 &gpio1 23 0>, /* D0 */ + <7 0 &gpio1 22 0>, /* D1 */ + <8 0 &gpio1 11 0>, /* D2 */ + <9 0 &gpio1 24 0>, /* D3 */ + <10 0 &gpio1 9 0>, /* D4 */ + <11 0 &gpio1 10 0>, /* D5 */ + <12 0 &gpio1 18 0>, /* D6 */ + <13 0 &gpio1 19 0>, /* D7 */ + <14 0 &gpio1 3 0>, /* D8 */ + <15 0 &gpio1 2 0>, /* D9 */ + <16 0 &gpio3 13 0>, /* D10 */ + <17 0 &gpio3 14 0>, /* D11 */ + <18 0 &gpio3 15 0>, /* D12 */ + <19 0 &gpio3 12 0>, /* D13 */ + <20 0 &gpio1 1 0>, /* D14 */ + <21 0 &gpio1 0 0>; /* D15 */ + }; +}; + +arduino_serial: &lpuart3 { + pinctrl-0 = <&pinmux_lpuart3>; + pinctrl-1 = <&pinmux_lpuart3_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&adc1 { + status = "okay"; + pinctrl-0 = <&pinmux_adc1>; + pinctrl-names = "default"; +}; + +nxp_touch_i2c: &lpi2c1 {}; + +zephyr_lcdif: &lcdif { + pinctrl-0 = <&pinmux_lcdif>; + pinctrl-names = "default"; +}; + +&lpi2c1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpi2c1>; + pinctrl-names = "default"; + + fxos8700: fxos8700@1f { + compatible = "nxp,fxos8700"; + reg = <0x1f>; + + /* Two zero ohm resistors (R263 and R264) isolate sensor + * interrupt gpios from the soc and are unpopulated by default. + * Note that if you populate them, they conflict with LCD and + * Ethernet interrupt gpios. + */ + int1-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + int2-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + }; +}; + +&lpuart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart1>; + pinctrl-1 = <&pinmux_lpuart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&lpspi1 { + status = "okay"; + /* DMA channels 0 and 1, muxed to LPSPI1 RX and TX */ + dmas = <&edma0 0 13>, <&edma0 1 14>; + dma-names = "rx", "tx"; + pinctrl-0 = <&pinmux_lpspi1>; + pinctrl-names = "default"; + tristate-output; +}; + +&lpspi3 { + status = "okay"; + /* DMA channels 2 and 3, muxed to LPSPI3 RX and TX */ + dmas = <&edma0 2 15>, <&edma0 3 16>; + dma-names = "rx", "tx"; + pinctrl-0 = <&pinmux_lpspi3>; + pinctrl-names = "default"; +}; + +&enet_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + phy-handle = <&phy>; + zephyr,random-mac-address; + phy-connection-type = "rmii"; +}; + +&enet_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_enet_mdio>; + pinctrl-names = "default"; + phy: phy@0 { + compatible = "microchip,ksz8081"; + reg = <0>; + status = "okay"; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; + }; +}; + +&enet_ptp_clock { + status = "okay"; + pinctrl-0 = <&pinmux_ptp>; + pinctrl-names = "default"; +}; + +zephyr_udc0: &usb1 { + status = "okay"; +}; + +&usdhc1 { + status = "okay"; + pwr-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&pinmux_usdhc1>; + pinctrl-1 = <&pinmux_usdhc1_slow>; + pinctrl-2 = <&pinmux_usdhc1_med>; + pinctrl-3 = <&pinmux_usdhc1_fast>; + pinctrl-names = "default", "slow", "med", "fast"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; + +&wdog0 { + status = "okay"; +}; + +&edma0 { + status = "okay"; +}; + +&pxp { + status = "okay"; +}; + +/* GPT and Systick are enabled. If power management is enabled, the GPT + * timer will be used instead of systick, as allows the core clock to + * be gated. + */ +&gpt_hw_timer { + status = "okay"; +}; + +&systick { + status = "okay"; +}; diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_defconfig b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_hyperflash_defconfig similarity index 100% rename from boards/nxp/mimxrt1050_evk/mimxrt1050_evk_defconfig rename to boards/nxp/mimxrt1050_evk/mimxrt1050_evk_hyperflash_defconfig diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.dts b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.dts new file mode 100644 index 0000000000000..e0aa389326aa4 --- /dev/null +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.dts @@ -0,0 +1,72 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mimxrt1050_evk.dtsi" + +/ { + chosen { + zephyr,flash-controller = &s26ks512s0; + zephyr,flash = &s26ks512s0; + zephyr,code-partition = &slot0_partition; + }; +}; + +&flexspi { + status = "okay"; + ahb-prefetch; + ahb-read-addr-opt; + pinctrl-0 = <&pinmux_flexspi1>; + pinctrl-names = "default"; + ahb-bufferable; + ahb-cacheable; + sck-differential-clock; + combination-mode; + rx-clock-source = <3>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(64)>; + s26ks512s0: s26ks512s@0 { + compatible = "nxp,imx-flexspi-hyperflash"; + size = ; + reg = <0>; + spi-max-frequency = <166000000>; + word-addressable; + cs-interval-unit = <1>; + cs-interval = <2>; + cs-hold-time = <0>; + cs-setup-time = <3>; + data-valid-time = <1>; + column-space = <3>; + ahb-write-wait-unit = <2>; + ahb-write-wait-interval = <20>; + status = "okay"; + erase-block-size = ; + write-block-size = <16>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(256)>; + }; + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. + */ + slot0_partition: partition@40000 { + label = "image-0"; + reg = <0x00040000 (DT_SIZE_M(3) + DT_SIZE_K(512))>; + }; + slot1_partition: partition@3C0000 { + label = "image-1"; + reg = <0x003C0000 DT_SIZE_M(3)>; + }; + storage_partition: partition@6C0000 { + label = "storage"; + reg = <0x006C0000 (DT_SIZE_M(58) - DT_SIZE_K(768))>; + }; + }; + }; +}; diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.overlay b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.overlay deleted file mode 100644 index 346aaca819f8c..0000000000000 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.overlay +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2024 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - chosen { - zephyr,flash-controller = &s26ks512s0; - zephyr,flash = &s26ks512s0; - zephyr,code-partition = &slot0_partition; - }; -}; - -&flexspi { - status = "okay"; - ahb-prefetch; - ahb-read-addr-opt; - pinctrl-0 = <&pinmux_flexspi1>; - pinctrl-names = "default"; - ahb-bufferable; - ahb-cacheable; - sck-differential-clock; - combination-mode; - rx-clock-source = <3>; - reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(64)>; - s26ks512s0: s26ks512s@0 { - compatible = "nxp,imx-flexspi-hyperflash"; - size = ; - reg = <0>; - spi-max-frequency = <166000000>; - word-addressable; - cs-interval-unit = <1>; - cs-interval = <2>; - cs-hold-time = <0>; - cs-setup-time = <3>; - data-valid-time = <1>; - column-space = <3>; - ahb-write-wait-unit = <2>; - ahb-write-wait-interval = <20>; - status = "okay"; - erase-block-size = ; - write-block-size = <16>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 DT_SIZE_K(256)>; - }; - /* The MCUBoot swap-move algorithm uses the last 2 sectors - * of the primary slot0 for swap status and move. - */ - slot0_partition: partition@40000 { - label = "image-0"; - reg = <0x00040000 (DT_SIZE_M(3) + DT_SIZE_K(512))>; - }; - slot1_partition: partition@3C0000 { - label = "image-1"; - reg = <0x003C0000 DT_SIZE_M(3)>; - }; - storage_partition: partition@6C0000 { - label = "storage"; - reg = <0x006C0000 (DT_SIZE_M(58) - DT_SIZE_K(768))>; - }; - }; - }; -}; diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.yaml b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.yaml index 73b20bcead3f4..4a097f4e441d4 100644 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.yaml +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_hyperflash.yaml @@ -4,14 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 # -identifier: mimxrt1050_evk +identifier: mimxrt1050_evk/mimxrt1052/hyperflash name: NXP MIMXRT1050-EVK type: mcu arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 65536 supported: diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.dts b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.dts new file mode 100644 index 0000000000000..ca5a924d282df --- /dev/null +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.dts @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mimxrt1050_evk.dtsi" + +/ { + chosen { + zephyr,flash-controller = &is25wp064; + zephyr,flash = &is25wp064; + zephyr,code-partition = &slot0_partition; + }; +}; + +&flexspi { + status = "okay"; + ahb-prefetch; + ahb-read-addr-opt; + rx-clock-source = <1>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; + is25wp064: is25wp064@0 { + compatible = "nxp,imx-flexspi-nor"; + size = <67108864>; + reg = <0>; + spi-max-frequency = <104000000>; + status = "okay"; + jedec-id = [9d 70 17]; + erase-block-size = <4096>; + write-block-size = <1>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(128)>; + }; + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. + */ + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(8))>; + }; + slot1_partition: partition@322000 { + label = "image-1"; + reg = <0x00322000 DT_SIZE_M(3)>; + }; + storage_partition: partition@622000 { + label = "storage"; + reg = <0x00622000 (DT_SIZE_M(2) - DT_SIZE_K(136))>; + }; + }; + }; +}; diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.overlay b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.overlay deleted file mode 100644 index 4930433268aac..0000000000000 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.overlay +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2017, NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - chosen { - zephyr,flash-controller = &is25wp064; - zephyr,flash = &is25wp064; - zephyr,code-partition = &slot0_partition; - }; -}; - -&flexspi { - status = "okay"; - ahb-prefetch; - ahb-read-addr-opt; - rx-clock-source = <1>; - reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; - is25wp064: is25wp064@0 { - compatible = "nxp,imx-flexspi-nor"; - size = <67108864>; - reg = <0>; - spi-max-frequency = <104000000>; - status = "okay"; - jedec-id = [9d 70 17]; - erase-block-size = <4096>; - write-block-size = <1>; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 DT_SIZE_K(128)>; - }; - /* The MCUBoot swap-move algorithm uses the last 2 sectors - * of the primary slot0 for swap status and move. - */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(8))>; - }; - slot1_partition: partition@322000 { - label = "image-1"; - reg = <0x00322000 DT_SIZE_M(3)>; - }; - storage_partition: partition@622000 { - label = "storage"; - reg = <0x00622000 (DT_SIZE_M(2) - DT_SIZE_K(136))>; - }; - }; - }; -}; diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml index 7f1f557d9da16..62b065a0658e2 100644 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml @@ -4,14 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 # -identifier: mimxrt1050_evk@qspi +identifier: mimxrt1050_evk/mimxrt1052/qspi name: NXP MIMXRT1050-EVK-QSPI type: mcu arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 8192 supported: diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi_defconfig b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi_defconfig new file mode 100644 index 0000000000000..a9e39fa1d739f --- /dev/null +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi_defconfig @@ -0,0 +1,12 @@ +# +# Copyright (c) 2017, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/nxp/mimxrt1050_evk/revision.cmake b/boards/nxp/mimxrt1050_evk/revision.cmake deleted file mode 100644 index 3e6f006a735b5..0000000000000 --- a/boards/nxp/mimxrt1050_evk/revision.cmake +++ /dev/null @@ -1,7 +0,0 @@ -if (NOT DEFINED BOARD_REVISION) - set(BOARD_REVISION "hyperflash") -else () - if (NOT (BOARD_REVISION STREQUAL "hyperflash") AND NOT (BOARD_REVISION STREQUAL "qspi")) - message(FATAL_ERROR "Invalid board revision, ${BOARD_REVISION}, valid revisions are: hyperflash, qspi") - endif() -endif() diff --git a/boards/nxp/mimxrt1060_evk/CMakeLists.txt b/boards/nxp/mimxrt1060_evk/CMakeLists.txt index 29c2d6f9068a6..29263b8b55596 100644 --- a/boards/nxp/mimxrt1060_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1060_evk/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2018-2022 NXP +# Copyright 2018-2022, 2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -12,7 +12,7 @@ endif() if(CONFIG_NXP_IMXRT_BOOT_HEADER) zephyr_library() - if(CONFIG_BOARD_MIMXRT1060_EVKB) + if((${BOARD_REVISION} STREQUAL "B") OR (${BOARD_REVISION} STREQUAL "C")) set(FLASH_CONF evkbmimxrt1060_flexspi_nor_config.c) set(BOARD_NAME evkbmimxrt1060) elseif(CONFIG_DT_HAS_NXP_IMX_FLEXSPI_NOR_ENABLED) diff --git a/boards/nxp/mimxrt1060_evk/Kconfig.defconfig b/boards/nxp/mimxrt1060_evk/Kconfig.defconfig index 899e8b3ffe0f2..bc06c96f7b80a 100644 --- a/boards/nxp/mimxrt1060_evk/Kconfig.defconfig +++ b/boards/nxp/mimxrt1060_evk/Kconfig.defconfig @@ -3,7 +3,7 @@ # Copyright 2018,2023 NXP # SPDX-License-Identifier: Apache-2.0 -if BOARD_MIMXRT1060_EVK || BOARD_MIMXRT1060_EVKB +if BOARD_MIMXRT1060_EVK config DEVICE_CONFIGURATION_DATA default y @@ -25,4 +25,4 @@ endif # ETH_MCUX endif # NETWORKING -endif # BOARD_MIMXRT1060_EVK || BOARD_MIMXRT1060_EVKB +endif # BOARD_MIMXRT1060_EVK diff --git a/boards/nxp/mimxrt1060_evk/Kconfig.mimxrt1060_evkb b/boards/nxp/mimxrt1060_evk/Kconfig.mimxrt1060_evkb deleted file mode 100644 index d2f59c8c9cfa9..0000000000000 --- a/boards/nxp/mimxrt1060_evk/Kconfig.mimxrt1060_evkb +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright 2024 NXP -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_MIMXRT1060_EVKB - select SOC_PART_NUMBER_MIMXRT1062DVL6A diff --git a/boards/nxp/mimxrt1060_evk/board.cmake b/boards/nxp/mimxrt1060_evk/board.cmake index 722afd541f712..9fe7e3718eab7 100644 --- a/boards/nxp/mimxrt1060_evk/board.cmake +++ b/boards/nxp/mimxrt1060_evk/board.cmake @@ -4,13 +4,26 @@ # SPDX-License-Identifier: Apache-2.0 # +if(NOT ("${BOARD_QUALIFIERS}" MATCHES "qspi" + OR "${BOARD_QUALIFIERS}" MATCHES "hyperflash")) + message(FATAL_ERROR "Please specify a board flash variant for the mimxrt1060_evk:\n" + "mimxrt1060_evk/mimxrt1062/qspi or mimxrt1060_evk/mimxrt1062/hyperflash\n") +endif() + board_runner_args(pyocd "--target=mimxrt1060") board_runner_args(jlink "--device=MIMXRT1062xxx6A") + +if ("${BOARD_REVISION}" STREQUAL "B") +board_runner_args(linkserver "--device=MIMXRT1062xxxxB:MIMXRT1060-EVKB") +elseif ("${BOARD_REVISION}" STREQUAL "C") +board_runner_args(linkserver "--device=MIMXRT1062xxxxB:MIMXRT1060-EVKC") +else() board_runner_args(linkserver "--device=MIMXRT1062xxxxA:EVK-MIMXRT1060") +endif() -if (("${BOARD_REVISION}" STREQUAL "qspi") OR CONFIG_BOARD_MIMXRT1060_EVKB) +if(("${BOARD_QUALIFIERS}" MATCHES "qspi") OR ("${BOARD_REVISION}" STREQUAL "B") OR ("${BOARD_REVISION}" STREQUAL "C")) board_runner_args(jlink "--loader=BankAddr=0x60000000&Loader=QSPI") -elseif ("${BOARD_REVISION}" STREQUAL "hyperflash") +elseif ("${BOARD_QUALIFIERS}" MATCHES "hyperflash") board_runner_args(jlink "--loader=BankAddr=0x60000000&Loader=HyperFlash") endif() diff --git a/boards/nxp/mimxrt1060_evk/board.yml b/boards/nxp/mimxrt1060_evk/board.yml index 8039cf65e4234..6ea1376ab869c 100644 --- a/boards/nxp/mimxrt1060_evk/board.yml +++ b/boards/nxp/mimxrt1060_evk/board.yml @@ -2,16 +2,15 @@ boards: - name: mimxrt1060_evk full_name: MIMXRT1060-EVK vendor: nxp - revision: - format: "custom" - default: "qspi" - revisions: - - name: "qspi" - - name: "hyperflash" - socs: - - name: mimxrt1062 - - name: mimxrt1060_evkb - full_name: MIMXRT1060-EVKB - vendor: nxp socs: - name: mimxrt1062 + variants: + - name: "qspi" + - name: "hyperflash" + revision: + format: "letter" + default: "C" + revisions: + - name: "A" + - name: "B" + - name: "C" diff --git a/boards/nxp/mimxrt1060_evk/doc/index.rst b/boards/nxp/mimxrt1060_evk/doc/index.rst index a28a059ae2b90..372aaea085e56 100644 --- a/boards/nxp/mimxrt1060_evk/doc/index.rst +++ b/boards/nxp/mimxrt1060_evk/doc/index.rst @@ -150,7 +150,7 @@ already supported, which can also be re-used on this mimxrt1060_evk board: +-----------+------------+-------------------------------------+ The default configuration can be found in -:zephyr_file:`boards/nxp/mimxrt1060_evk/mimxrt1060_evk_defconfig` +:zephyr_file:`boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_defconfig` Other hardware features are not currently supported by the port. @@ -316,6 +316,39 @@ The MIMXRT1060 SoC has eight UARTs. ``LPUART1`` is configured for the console, ``LPUART3`` for the Bluetooth Host Controller Interface (BT HCI), and the remaining are not used. +Board Revisions and Targets +*************************** + +There are three revisions of this board. + +Rev A: + +* Initial version + +Rev B: + +* adds the M.2 connector for Wi-Fi/BLE +* adds audio expansion connector J23 +* USER LED1 changed to GPIO1 pin 8 + +Rev C: + +* Replaces audio codec WM8960(EOL) to WM8962 +* Replaces 32.768 KHz oscillator from ASH7K-32.768KHz-T(EOL)to ASH7KW-32.768KHZ-L-T +* Replaces motion sensor from FXOS8700CQ(EOL) to FXLS8974CFR3 +* Re-assigns Bluetooth Audio PCM with dedicated I2S2 +* Re-assigns Bluetooth interface UART_CTS, UART_RTS to hardware PIN + +This board has two variants that can be targeted, +depending on which flash to set as ``zephyr,flash``: + +* ``mimxrt1060_evk/mimxrt1062/qspi`` is the default variant for the out of box + setup of the board using the qspi flash. +* ``mimxrt1060_evk/mimxrt1062/hyperflash`` is for a board that has been reworked to use the + hyperflash instead of the qspi flash. +* This board also has two revisions, the EVKA and EVKB. EVKA is the default target for this board. + To target EVKB, the board target string would become ``mimxrt1060_evk@B//qspi``, for example. + Programming and Debugging ************************* @@ -374,10 +407,28 @@ Flashing Here is an example for the :zephyr:code-sample:`hello_world` application. -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: mimxrt1060_evk - :goals: flash +.. tabs:: + + .. group-tab:: i.MX RT1060 Rev A + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt1060_evk@A//qspi + :goals: flash + + .. group-tab:: i.MX RT1060 Rev B + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt1060_evk@B//qspi + :goals: flash + + .. group-tab:: i.MX RT1060 Rev C (default) + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt1060_evk@C//qspi + :goals: flash Open a serial terminal, reset the board (press the SW9 button), and you should see the following message in the terminal: @@ -385,17 +436,36 @@ see the following message in the terminal: .. code-block:: console ***** Booting Zephyr OS v1.14.0-rc1 ***** - Hello World! mimxrt1060_evk + Hello World! mimxrt1060_evk//qspi Debugging ========= Here is an example for the :zephyr:code-sample:`hello_world` application. -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: mimxrt1060_evk - :goals: debug +.. tabs:: + + .. group-tab:: i.MX RT1060 Rev A + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt1060_evk@A//qspi + :goals: debug + + .. group-tab:: i.MX RT1060 Rev B + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt1060_evk@B//qspi + :goals: debug + + .. group-tab:: i.MX RT1060 Rev C (default) + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt1060_evk@C//qspi + :goals: debug + Open a serial terminal, step through the application in your debugger, and you should see the following message in the terminal: @@ -403,7 +473,7 @@ should see the following message in the terminal: .. code-block:: console ***** Booting Zephyr OS v1.14.0-rc1 ***** - Hello World! mimxrt1060_evk + Hello World! mimxrt1060_evk//qspi Troubleshooting =============== diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts deleted file mode 100644 index 84dbaac3ae4a9..0000000000000 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dts +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright 2018,2024 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; - -#include -#include "mimxrt1060_evk-pinctrl.dtsi" -#include - -/ { - model = "NXP MIMXRT1060-EVK board"; - compatible = "nxp,mimxrt1062"; - - aliases { - led0 = &green_led; - pwm-led0 = &green_pwm_led; - sw0 = &user_button; - watchdog0 = &wdog0; - sdhc0 = &usdhc1; - mcuboot-button0 = &user_button; - }; - - chosen { - zephyr,sram = &sdram0; - zephyr,itcm = &itcm; - zephyr,dtcm = &dtcm; - zephyr,uart-mcumgr = &lpuart1; - zephyr,console = &lpuart1; - zephyr,shell-uart = &lpuart1; - zephyr,canbus = &flexcan3; - }; - - sdram0: memory@80000000 { - /* Micron MT48LC16M16A2B4-6AIT:G */ - device_type = "memory"; - reg = <0x80000000 DT_SIZE_M(32)>; - }; - - /* - * This node describes the GPIO pins of the parallel FPC interface, - * This interface is standard to several NXP EVKs, and is used with - * several parallel LCD displays (available as zephyr shields) - */ - nxp_parallel_lcd_connector: parallel-connector { - compatible = "nxp,parallel-lcd-connector"; - #gpio-cells = <2>; - gpio-map-mask = <0xffffffff 0xffffffc0>; - gpio-map-pass-thru = <0 0x3f>; - gpio-map = <0 0 &gpio2 31 0>; /* Pin 1, BL+ */ - }; - - /* - * This node describes the GPIO pins of the I2C display FPC interface, - * This interface is standard to several NXP EVKs, and is used with - * several parallel LCD displays (available as zephyr shields) - */ - nxp_i2c_touch_fpc: i2c-touch-connector { - compatible = "nxp,i2c-tsc-fpc"; - #gpio-cells = <2>; - gpio-map-mask = <0xffffffff 0xffffffc0>; - gpio-map-pass-thru = <0 0x3f>; - gpio-map = <1 0 &gpio1 2 0>, /* Pin 2, LCD touch RST */ - <2 0 &gpio1 11 0>; /* Pin 3, LCD touch INT */ - }; - - leds { - compatible = "gpio-leds"; - green_led: led-1 { - gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; - label = "User LED1"; - }; - }; - - pwmleds { - compatible = "pwm-leds"; - green_pwm_led: green_pwm_led { - pwms = <&flexpwm2_pwm3 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - user_button: button-1 { - label = "User SW8"; - gpios = <&gpio5 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - zephyr,code = ; - }; - }; - - arduino_header: connector { - compatible = "arduino-header-r3"; - #gpio-cells = <2>; - gpio-map-mask = <0xffffffff 0xffffffc0>; - gpio-map-pass-thru = <0 0x3f>; - gpio-map = <0 0 &gpio1 26 0>, /* A0 */ - <1 0 &gpio1 27 0>, /* A1 */ - <2 0 &gpio1 20 0>, /* A2 */ - <3 0 &gpio1 21 0>, /* A3 */ - <4 0 &gpio1 17 0>, /* A4 */ - <5 0 &gpio1 16 0>, /* A5 */ - <6 0 &gpio1 23 0>, /* D0 */ - <7 0 &gpio1 22 0>, /* D1 */ - <8 0 &gpio1 11 0>, /* D2 */ - <9 0 &gpio1 24 0>, /* D3 */ - <10 0 &gpio1 9 0>, /* D4 */ - <11 0 &gpio1 10 0>, /* D5 */ - <12 0 &gpio1 18 0>, /* D6 */ - <13 0 &gpio1 19 0>, /* D7 */ - <14 0 &gpio1 3 0>, /* D8 */ - <15 0 &gpio1 2 0>, /* D9 */ - <16 0 &gpio3 13 0>, /* D10 */ - <17 0 &gpio3 14 0>, /* D11 */ - <18 0 &gpio3 15 0>, /* D12 */ - <19 0 &gpio3 12 0>, /* D13 */ - <20 0 &gpio1 17 0>, /* D14 */ - <21 0 &gpio1 16 0>; /* D15 */ - }; -}; - -arduino_serial: &lpuart3 { - pinctrl-0 = <&pinmux_lpuart3>; - pinctrl-1 = <&pinmux_lpuart3_flow_control>; - pinctrl-2 = <&pinmux_lpuart3_sleep>; - pinctrl-names = "default", "flowcontrol", "sleep"; -}; - -zephyr_lcdif: &lcdif { - pinctrl-0 = <&pinmux_lcdif>; - pinctrl-names = "default"; -}; - -nxp_touch_i2c: &lpi2c1 {}; - -arduino_i2c: &lpi2c1 { - status = "okay"; - pinctrl-0 = <&pinmux_lpi2c1>; - pinctrl-names = "default"; -}; - -&lpuart1 { - status = "okay"; - current-speed = <115200>; - pinctrl-0 = <&pinmux_lpuart1>; - pinctrl-1 = <&pinmux_lpuart1_sleep>; - pinctrl-names = "default", "sleep"; -}; - -&enet_mac { - status = "okay"; - pinctrl-0 = <&pinmux_enet>; - pinctrl-names = "default"; - phy-handle = <&phy>; - zephyr,random-mac-address; - phy-connection-type = "rmii"; -}; - -&enet_mdio { - status = "okay"; - pinctrl-0 = <&pinmux_enet_mdio>; - pinctrl-names = "default"; - phy: phy@0 { - compatible = "microchip,ksz8081"; - reg = <0>; - status = "okay"; - reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; - int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; - microchip,interface-type = "rmii"; - }; -}; - -&enet_ptp_clock { - status = "okay"; - pinctrl-0 = <&pinmux_ptp>; - pinctrl-names = "default"; -}; - -&adc1 { - status = "okay"; - pinctrl-0 = <&pinmux_adc1>; - pinctrl-names = "default"; -}; - -zephyr_udc0: &usb1 { - status = "okay"; - phy_handle = <&usbphy1>; -}; - -&usbphy1 { - status = "okay"; - tx-d-cal = <12>; - tx-cal-45-dp-ohms = <6>; - tx-cal-45-dm-ohms = <6>; -}; - -&csi { - pinctrl-0 = <&pinmux_csi>; - pinctrl-names = "default"; -}; - -&flexpwm2_pwm3 { - status = "okay"; - pinctrl-0 = <&pinmux_flexpwm2_3>; - pinctrl-names = "default"; -}; - -&flexpwm1_pwm0 { - pinctrl-0 = <&pinmux_flexpwm1_0>; - pinctrl-names = "default"; -}; - -&flexpwm1_pwm3 { - pinctrl-0 = <&pinmux_flexpwm1>; - pinctrl-names = "default"; -}; - -&usdhc1 { - status = "okay"; - power-delay-ms = <1000>; - pwr-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; - cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; - status = "okay"; - pinctrl-0 = <&pinmux_usdhc1>; - pinctrl-1 = <&pinmux_usdhc1_slow>; - pinctrl-2 = <&pinmux_usdhc1_med>; - pinctrl-3 = <&pinmux_usdhc1_fast>; - pinctrl-names = "default", "slow", "med", "fast"; - sdmmc { - compatible = "zephyr,sdmmc-disk"; - disk-name = "SD"; - status = "okay"; - }; -}; - -&edma0 { - status = "okay"; -}; - -&flexcan3 { - status = "okay"; - pinctrl-0 = <&pinmux_flexcan3>; - pinctrl-names = "default"; - - can-transceiver { - max-bitrate = <5000000>; - }; -}; - -&wdog0 { - status = "okay"; -}; - -arduino_spi: &lpspi1 { - status = "okay"; - /* DMA channels 0 and 1, muxed to LPSPI1 RX and TX */ - dmas = <&edma0 0 13>, <&edma0 1 14>; - dma-names = "rx", "tx"; - pinctrl-0 = <&pinmux_lpspi1>; - pinctrl-names = "default"; -}; - -&lpspi3 { - status = "okay"; - /* DMA channels 2 and 3, muxed to LPSPI3 RX and TX */ - dmas = <&edma0 2 15>, <&edma0 3 16>; - dma-names = "rx", "tx"; - pinctrl-0 = <&pinmux_lpspi3>; - pinctrl-names = "default"; - -}; - -&sai1 { - status = "okay"; - pinctrl-0 = <&pinmux_sai1>; - pinctrl-names = "default"; -}; - -/* GPT and Systick are enabled. If power management is enabled, the GPT - * timer will be used instead of systick, as allows the core clock to - * be gated. - */ -&gpt_hw_timer { - status = "okay"; -}; - -&systick { - status = "okay"; -}; - -&iomuxcgpr { - status = "okay"; -}; - -&itm { - pinctrl-0 = <&pinmux_swo>; - pinctrl-names = "default"; -}; - -&pxp { - status = "okay"; -}; - -&pit0 { - status = "okay"; -}; - -dvp_fpc24_i2c: &lpi2c1 {}; - -dvp_fpc24_interface: &csi {}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dtsi b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dtsi new file mode 100644 index 0000000000000..e8d4716aab7ce --- /dev/null +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dtsi @@ -0,0 +1,311 @@ +/* + * Copyright 2018,2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "mimxrt1060_evk-pinctrl.dtsi" +#include + +/ { + model = "NXP MIMXRT1060-EVK board"; + compatible = "nxp,mimxrt1062"; + + aliases { + led0 = &green_led; + pwm-led0 = &green_pwm_led; + sw0 = &user_button; + watchdog0 = &wdog0; + sdhc0 = &usdhc1; + mcuboot-button0 = &user_button; + }; + + chosen { + zephyr,sram = &sdram0; + zephyr,itcm = &itcm; + zephyr,dtcm = &dtcm; + zephyr,uart-mcumgr = &lpuart1; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + zephyr,canbus = &flexcan3; + }; + + sdram0: memory@80000000 { + /* Micron MT48LC16M16A2B4-6AIT:G */ + device_type = "memory"; + reg = <0x80000000 DT_SIZE_M(32)>; + }; + + /* + * This node describes the GPIO pins of the parallel FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_parallel_lcd_connector: parallel-connector { + compatible = "nxp,parallel-lcd-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio2 31 0>; /* Pin 1, BL+ */ + }; + + /* + * This node describes the GPIO pins of the I2C display FPC interface, + * This interface is standard to several NXP EVKs, and is used with + * several parallel LCD displays (available as zephyr shields) + */ + nxp_i2c_touch_fpc: i2c-touch-connector { + compatible = "nxp,i2c-tsc-fpc"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <1 0 &gpio1 2 0>, /* Pin 2, LCD touch RST */ + <2 0 &gpio1 11 0>; /* Pin 3, LCD touch INT */ + }; + + leds { + compatible = "gpio-leds"; + green_led: led-1 { + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + label = "User LED1"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + green_pwm_led: green_pwm_led { + pwms = <&flexpwm2_pwm3 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button-1 { + label = "User SW8"; + gpios = <&gpio5 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio1 26 0>, /* A0 */ + <1 0 &gpio1 27 0>, /* A1 */ + <2 0 &gpio1 20 0>, /* A2 */ + <3 0 &gpio1 21 0>, /* A3 */ + <4 0 &gpio1 17 0>, /* A4 */ + <5 0 &gpio1 16 0>, /* A5 */ + <6 0 &gpio1 23 0>, /* D0 */ + <7 0 &gpio1 22 0>, /* D1 */ + <8 0 &gpio1 11 0>, /* D2 */ + <9 0 &gpio1 24 0>, /* D3 */ + <10 0 &gpio1 9 0>, /* D4 */ + <11 0 &gpio1 10 0>, /* D5 */ + <12 0 &gpio1 18 0>, /* D6 */ + <13 0 &gpio1 19 0>, /* D7 */ + <14 0 &gpio1 3 0>, /* D8 */ + <15 0 &gpio1 2 0>, /* D9 */ + <16 0 &gpio3 13 0>, /* D10 */ + <17 0 &gpio3 14 0>, /* D11 */ + <18 0 &gpio3 15 0>, /* D12 */ + <19 0 &gpio3 12 0>, /* D13 */ + <20 0 &gpio1 17 0>, /* D14 */ + <21 0 &gpio1 16 0>; /* D15 */ + }; +}; + +arduino_serial: &lpuart3 { + pinctrl-0 = <&pinmux_lpuart3>; + pinctrl-1 = <&pinmux_lpuart3_flow_control>; + pinctrl-2 = <&pinmux_lpuart3_sleep>; + pinctrl-names = "default", "flowcontrol", "sleep"; +}; + +zephyr_lcdif: &lcdif { + pinctrl-0 = <&pinmux_lcdif>; + pinctrl-names = "default"; +}; + +nxp_touch_i2c: &lpi2c1 {}; + +arduino_i2c: &lpi2c1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpi2c1>; + pinctrl-names = "default"; +}; + +&lpuart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart1>; + pinctrl-1 = <&pinmux_lpuart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&enet_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + phy-handle = <&phy>; + zephyr,random-mac-address; + phy-connection-type = "rmii"; +}; + +&enet_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_enet_mdio>; + pinctrl-names = "default"; + phy: phy@0 { + compatible = "microchip,ksz8081"; + reg = <0>; + status = "okay"; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + microchip,interface-type = "rmii"; + }; +}; + +&enet_ptp_clock { + status = "okay"; + pinctrl-0 = <&pinmux_ptp>; + pinctrl-names = "default"; +}; + +&adc1 { + status = "okay"; + pinctrl-0 = <&pinmux_adc1>; + pinctrl-names = "default"; +}; + +zephyr_udc0: &usb1 { + status = "okay"; + phy-handle = <&usbphy1>; +}; + +&usbphy1 { + status = "okay"; + tx-d-cal = <12>; + tx-cal-45-dp-ohms = <6>; + tx-cal-45-dm-ohms = <6>; +}; + +&csi { + pinctrl-0 = <&pinmux_csi>; + pinctrl-names = "default"; +}; + +&flexpwm2_pwm3 { + status = "okay"; + pinctrl-0 = <&pinmux_flexpwm2_3>; + pinctrl-names = "default"; +}; + +&flexpwm1_pwm0 { + pinctrl-0 = <&pinmux_flexpwm1_0>; + pinctrl-names = "default"; +}; + +&flexpwm1_pwm3 { + pinctrl-0 = <&pinmux_flexpwm1>; + pinctrl-names = "default"; +}; + +&usdhc1 { + status = "okay"; + power-delay-ms = <1000>; + pwr-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + status = "okay"; + pinctrl-0 = <&pinmux_usdhc1>; + pinctrl-1 = <&pinmux_usdhc1_slow>; + pinctrl-2 = <&pinmux_usdhc1_med>; + pinctrl-3 = <&pinmux_usdhc1_fast>; + pinctrl-names = "default", "slow", "med", "fast"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; + +&edma0 { + status = "okay"; +}; + +&flexcan3 { + status = "okay"; + pinctrl-0 = <&pinmux_flexcan3>; + pinctrl-names = "default"; + + can-transceiver { + max-bitrate = <5000000>; + }; +}; + +&wdog0 { + status = "okay"; +}; + +arduino_spi: &lpspi1 { + status = "okay"; + /* DMA channels 0 and 1, muxed to LPSPI1 RX and TX */ + dmas = <&edma0 0 13>, <&edma0 1 14>; + dma-names = "rx", "tx"; + pinctrl-0 = <&pinmux_lpspi1>; + pinctrl-names = "default"; +}; + +&lpspi3 { + status = "okay"; + /* DMA channels 2 and 3, muxed to LPSPI3 RX and TX */ + dmas = <&edma0 2 15>, <&edma0 3 16>; + dma-names = "rx", "tx"; + pinctrl-0 = <&pinmux_lpspi3>; + pinctrl-names = "default"; + +}; + +&sai1 { + status = "okay"; + pinctrl-0 = <&pinmux_sai1>; + pinctrl-names = "default"; +}; + +/* GPT and Systick are enabled. If power management is enabled, the GPT + * timer will be used instead of systick, as allows the core clock to + * be gated. + */ +&gpt_hw_timer { + status = "okay"; +}; + +&systick { + status = "okay"; +}; + +&iomuxcgpr { + status = "okay"; +}; + +&itm { + pinctrl-0 = <&pinmux_swo>; + pinctrl-names = "default"; +}; + +&pxp { + status = "okay"; +}; + +&pit0 { + status = "okay"; +}; + +dvp_fpc24_i2c: &lpi2c1 {}; + +dvp_fpc24_interface: &csi {}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evkb_defconfig b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_B_defconfig similarity index 100% rename from boards/nxp/mimxrt1060_evk/mimxrt1060_evkb_defconfig rename to boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_B_defconfig diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.dts b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.dts new file mode 100644 index 0000000000000..125f0fecd185a --- /dev/null +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.dts @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mimxrt1060_evk.dtsi" + +/ { + chosen { + zephyr,flash-controller = &s26ks512s0; + zephyr,flash = &s26ks512s0; + zephyr,code-partition = &slot0_partition; + }; +}; + +&flexspi { + status = "okay"; + ahb-prefetch; + ahb-read-addr-opt; + ahb-bufferable; + ahb-cacheable; + sck-differential-clock; + combination-mode; + rx-clock-source = <3>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(64)>; + s26ks512s0: s26ks512s@0 { + compatible = "nxp,imx-flexspi-hyperflash"; + size = ; + reg = <0>; + spi-max-frequency = <166000000>; + word-addressable; + cs-interval-unit = <1>; + cs-interval = <2>; + cs-hold-time = <0>; + cs-setup-time = <3>; + data-valid-time = <1>; + column-space = <3>; + ahb-write-wait-unit = <2>; + ahb-write-wait-interval = <20>; + status = "okay"; + erase-block-size = ; + write-block-size = <16>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(256)>; + }; + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. + */ + slot0_partition: partition@40000 { + label = "image-0"; + reg = <0x00040000 (DT_SIZE_M(3) + DT_SIZE_K(512))>; + }; + slot1_partition: partition@3C0000 { + label = "image-1"; + reg = <0x003C0000 DT_SIZE_M(3)>; + }; + storage_partition: partition@6C0000 { + label = "storage"; + reg = <0x006C0000 (DT_SIZE_M(58) - DT_SIZE_K(768))>; + }; + }; + }; +}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.overlay b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.overlay deleted file mode 100644 index 0a3bb58d33d7d..0000000000000 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.overlay +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2018, NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - chosen { - zephyr,flash-controller = &s26ks512s0; - zephyr,flash = &s26ks512s0; - zephyr,code-partition = &slot0_partition; - }; -}; - -&flexspi { - status = "okay"; - ahb-prefetch; - ahb-read-addr-opt; - ahb-bufferable; - ahb-cacheable; - sck-differential-clock; - combination-mode; - rx-clock-source = <3>; - reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(64)>; - s26ks512s0: s26ks512s@0 { - compatible = "nxp,imx-flexspi-hyperflash"; - size = ; - reg = <0>; - spi-max-frequency = <166000000>; - word-addressable; - cs-interval-unit = <1>; - cs-interval = <2>; - cs-hold-time = <0>; - cs-setup-time = <3>; - data-valid-time = <1>; - column-space = <3>; - ahb-write-wait-unit = <2>; - ahb-write-wait-interval = <20>; - status = "okay"; - erase-block-size = ; - write-block-size = <16>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 DT_SIZE_K(256)>; - }; - /* The MCUBoot swap-move algorithm uses the last 2 sectors - * of the primary slot0 for swap status and move. - */ - slot0_partition: partition@40000 { - label = "image-0"; - reg = <0x00040000 (DT_SIZE_M(3) + DT_SIZE_K(512))>; - }; - slot1_partition: partition@3C0000 { - label = "image-1"; - reg = <0x003C0000 DT_SIZE_M(3)>; - }; - storage_partition: partition@6C0000 { - label = "storage"; - reg = <0x006C0000 (DT_SIZE_M(58) - DT_SIZE_K(768))>; - }; - }; - }; -}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml index 4dce0660162a2..688e5c8f576e3 100644 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml @@ -4,14 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 # -identifier: mimxrt1060_evk@hyperflash +identifier: mimxrt1060_evk/mimxrt1062/hyperflash name: NXP MIMXRT1060-EVK-HYPERFLASH type: mcu arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 65536 supported: diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_defconfig b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash_defconfig similarity index 100% rename from boards/nxp/mimxrt1060_evk/mimxrt1060_evk_defconfig rename to boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash_defconfig diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.dts b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.dts new file mode 100644 index 0000000000000..1e2876fc45d93 --- /dev/null +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.dts @@ -0,0 +1,60 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mimxrt1060_evk.dtsi" + +/ { + chosen { + zephyr,flash-controller = &is25wp064; + zephyr,flash = &is25wp064; + zephyr,code-partition = &slot0_partition; + }; +}; + +&flexspi { + status = "okay"; + pinctrl-0 = <&pinmux_flexspi1>; + pinctrl-names = "default"; + ahb-prefetch; + ahb-read-addr-opt; + rx-clock-source = <1>; + reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; + is25wp064: is25wp064@0 { + compatible = "nxp,imx-flexspi-nor"; + size = <67108864>; + reg = <0>; + spi-max-frequency = <104000000>; + status = "okay"; + jedec-id = [9d 70 17]; + erase-block-size = <4096>; + write-block-size = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(128)>; + }; + /* The MCUBoot swap-move algorithm uses the last 2 sectors + * of the primary slot0 for swap status and move. + */ + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(8))>; + }; + slot1_partition: partition@322000 { + label = "image-1"; + reg = <0x00322000 DT_SIZE_M(3)>; + }; + storage_partition: partition@622000 { + label = "storage"; + reg = <0x00622000 (DT_SIZE_M(2) - DT_SIZE_K(136))>; + }; + }; + }; +}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.overlay b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.overlay deleted file mode 100644 index c76c2b020c68f..0000000000000 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.overlay +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2024 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - chosen { - zephyr,flash-controller = &is25wp064; - zephyr,flash = &is25wp064; - zephyr,code-partition = &slot0_partition; - }; -}; - -&flexspi { - status = "okay"; - pinctrl-0 = <&pinmux_flexspi1>; - pinctrl-names = "default"; - ahb-prefetch; - ahb-read-addr-opt; - rx-clock-source = <1>; - reg = <0x402a8000 0x4000>, <0x60000000 DT_SIZE_M(8)>; - is25wp064: is25wp064@0 { - compatible = "nxp,imx-flexspi-nor"; - size = <67108864>; - reg = <0>; - spi-max-frequency = <104000000>; - status = "okay"; - jedec-id = [9d 70 17]; - erase-block-size = <4096>; - write-block-size = <1>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 DT_SIZE_K(128)>; - }; - /* The MCUBoot swap-move algorithm uses the last 2 sectors - * of the primary slot0 for swap status and move. - */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x00020000 (DT_SIZE_M(3) + DT_SIZE_K(8))>; - }; - slot1_partition: partition@322000 { - label = "image-1"; - reg = <0x00322000 DT_SIZE_M(3)>; - }; - storage_partition: partition@622000 { - label = "storage"; - reg = <0x00622000 (DT_SIZE_M(2) - DT_SIZE_K(136))>; - }; - }; - }; -}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.yaml b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.yaml index 13cbee4e4e8ca..56f608d3a6759 100644 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.yaml +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi.yaml @@ -4,14 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 # -identifier: mimxrt1060_evk +identifier: mimxrt1060_evk@A/mimxrt1062/qspi name: NXP MIMXRT1060-EVK type: mcu arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 8192 supported: diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_B.overlay b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_B.overlay new file mode 100644 index 0000000000000..284679eaa9f28 --- /dev/null +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_B.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, Whisper.ai + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* FLEXPWM not routed to LED on this EVK */ +&flexpwm2_pwm3 { + status = "disabled"; +}; + +&green_led { + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + label = "User LED1"; +}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_B.yaml b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_B.yaml new file mode 100644 index 0000000000000..c32eb2fdcf1b4 --- /dev/null +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_B.yaml @@ -0,0 +1,33 @@ +# +# Copyright (c) 2022, Whisper.ai +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: mimxrt1060_evk@B/mimxrt1062/qspi +name: NXP MIMXRT1060-EVKB +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 32768 +flash: 8192 +supported: + - adc + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi + - can + - counter + - display + - dma + - gpio + - i2c + - netif:eth + - sdhc + - spi + - usbd + - watchdog +vendor: nxp diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_C.overlay b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_C.overlay new file mode 100644 index 0000000000000..284679eaa9f28 --- /dev/null +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_C.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, Whisper.ai + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* FLEXPWM not routed to LED on this EVK */ +&flexpwm2_pwm3 { + status = "disabled"; +}; + +&green_led { + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + label = "User LED1"; +}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_C.yaml b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_C.yaml new file mode 100644 index 0000000000000..2a1c331164722 --- /dev/null +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_C.yaml @@ -0,0 +1,33 @@ +# +# Copyright (c) 2022, Whisper.ai +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: mimxrt1060_evk@C/mimxrt1062/qspi +name: NXP MIMXRT1060-EVKC +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 32768 +flash: 8192 +supported: + - adc + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi + - can + - counter + - display + - dma + - gpio + - i2c + - netif:eth + - sdhc + - spi + - usbd + - watchdog +vendor: nxp diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_defconfig b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_defconfig new file mode 100644 index 0000000000000..29f9a37ea90d5 --- /dev/null +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_qspi_defconfig @@ -0,0 +1,12 @@ +# +# Copyright (c) 2018, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evkb.dts b/boards/nxp/mimxrt1060_evk/mimxrt1060_evkb.dts deleted file mode 100644 index 905d32d89aa41..0000000000000 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evkb.dts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2022, Whisper.ai - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "mimxrt1060_evk.dts" -#include "mimxrt1060_evk_mimxrt1062_qspi.overlay" - -/* FLEXPWM not routed to LED on this EVK */ -&flexpwm2_pwm3 { - status = "disabled"; -}; - -&green_led { - gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; - label = "User LED1"; -}; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evkb.yaml b/boards/nxp/mimxrt1060_evk/mimxrt1060_evkb.yaml deleted file mode 100644 index 3f9306c1e0362..0000000000000 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evkb.yaml +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2022, Whisper.ai -# -# SPDX-License-Identifier: Apache-2.0 -# - -identifier: mimxrt1060_evkb -name: NXP MIMXRT1060-EVKB -type: mcu -arch: arm -toolchain: - - zephyr - - gnuarmemb - - xtools -ram: 32768 -flash: 8192 -supported: - - arduino_gpio - - arduino_i2c - - arduino_serial - - arduino_spi - - counter - - display - - gpio - - i2c - - netif:eth - - sdhc - - spi - - usb_device - - dma - - can - - watchdog - - adc -vendor: nxp diff --git a/boards/nxp/mimxrt1060_evk/revision.cmake b/boards/nxp/mimxrt1060_evk/revision.cmake deleted file mode 100644 index 97a3da96ea490..0000000000000 --- a/boards/nxp/mimxrt1060_evk/revision.cmake +++ /dev/null @@ -1,9 +0,0 @@ -if (NOT DEFINED BOARD_REVISION) - set(BOARD_REVISION "qspi") -else () - if (NOT (BOARD_REVISION STREQUAL "hyperflash") AND NOT (BOARD_REVISION STREQUAL "qspi")) - message(FATAL_ERROR "Invalid board revision, ${BOARD_REVISION}, valid revisions are: hyperflash, qspi") - elseif (BOARD_REVISION STREQUAL "hyperflash" AND CONFIG_BOARD_MIMXRT1060_EVKB) - message(FATAL_ERROR "hyperflash not supported on RT1060 EVKB") - endif() -endif() diff --git a/boards/nxp/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml b/boards/nxp/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml index 9e4a523d944d8..d0a6c75480ad4 100644 --- a/boards/nxp/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml +++ b/boards/nxp/mimxrt1062_fmurt6/mimxrt1062_fmurt6.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 768 flash: 65536 supported: diff --git a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts index 8d9f2437d6a80..004c280362c0c 100644 --- a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts @@ -304,6 +304,7 @@ zephyr_udc0: &usb1 { /* DMA channels 0 and 1, muxed to LPSPI1 RX and TX */ dmas = <&edma0 0 13>, <&edma0 1 14>; dma-names = "rx", "tx"; + tristate-output; pinctrl-0 = <&pinmux_lpspi1>; pinctrl-names = "default"; }; diff --git a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.yaml b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.yaml index eab16e277e597..deec4f1d66dfb 100644 --- a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.yaml +++ b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32768 flash: 4096 supported: diff --git a/boards/nxp/mimxrt1160_evk/doc/index.rst b/boards/nxp/mimxrt1160_evk/doc/index.rst index c37185fb6e5ad..b0d513ec8bde5 100644 --- a/boards/nxp/mimxrt1160_evk/doc/index.rst +++ b/boards/nxp/mimxrt1160_evk/doc/index.rst @@ -265,6 +265,25 @@ however the :ref:`pyocd-debug-host-tools` do not yet support programming the external flashes on this board so you must reconfigure the board for one of the following debug probes instead. +Launching Images Targeting M4 Core +================================== +If building targeting the M4 core, the M7 core must first run code to launch +the M4 image, by copying it into the ``ocram`` region then kicking off the M4 +core. When building using sysbuild targeting the M4 core, a minimal "launcher" +image will be built and flashed to the M7 core, which loads and kicks off +the M4 core. Therefore when developing an application intended to run +standalone on the M4 core, it is recommended to build with sysbuild, like +so: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt1160_evk/mimxrt1166/cm4 + :west-args: --sysbuild + :goals: flash + +If desired, this behavior can be disabled by building with +``-DSB_CONFIG_SECOND_CORE_MCUX_LAUNCHER=n`` + Using J-Link ------------ diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts index a92f93feb8d9a..475a166e78723 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts @@ -20,7 +20,7 @@ * sram region is changed and DMA is in use, you will * encounter issues! */ - zephyr,sram = &sram1; + zephyr,sram = &ocram; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; zephyr,flash-controller = &is25wp128; diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml index b265336cb241a..445f170f57302 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 128 supported: diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml index b9780a9574683..d803d9332e385 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 16384 supported: diff --git a/boards/nxp/mimxrt1170_evk/board.yml b/boards/nxp/mimxrt1170_evk/board.yml index 4a6a25318b01e..fce50aef20b3a 100644 --- a/boards/nxp/mimxrt1170_evk/board.yml +++ b/boards/nxp/mimxrt1170_evk/board.yml @@ -6,7 +6,7 @@ board: - name: mimxrt1176 revision: format: "letter" - default: "A" + default: "B" revisions: - name: "A" - name: "B" diff --git a/boards/nxp/mimxrt1170_evk/doc/index.rst b/boards/nxp/mimxrt1170_evk/doc/index.rst index 05fda1a60c7ee..549ef41b1088c 100644 --- a/boards/nxp/mimxrt1170_evk/doc/index.rst +++ b/boards/nxp/mimxrt1170_evk/doc/index.rst @@ -107,67 +107,68 @@ this board with new support for Zephyr features. Note that this table covers two boards: the RT1170 EVK (``mimxrt1170_evk//cm7/cm4``), and RT1170 EVKB (``mimxrt1170_evk@B//cm7/cm4``) -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| Interface | Controller | Driver/Component | RT1170 EVK | RT1170 EVKB | -+===========+============+=====================================+=================+=================+ -| NVIC | on-chip | nested vector interrupt controller | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| SYSTICK | on-chip | systick | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| GPIO | on-chip | gpio | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| COUNTER | on-chip | gpt | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| TIMER | on-chip | gpt | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| CAN | on-chip | flexcan | Supported (M7) | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| SPI | on-chip | spi | Supported (M7) | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| I2C | on-chip | i2c | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| PWM | on-chip | pwm | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| ADC | on-chip | adc | Supported (M7) | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| UART | on-chip | serial port-polling; | Supported | Supported | -| | | serial port-interrupt; | | | -| | | serial port-async | | | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| DMA | on-chip | dma | Supported | Supported | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| WATCHDOG | on-chip | watchdog | Supported (M7) | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| ENET | on-chip | ethernet - 10/100M | Supported (M7) | No support | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| ENET1G | on-chip | ethernet - 10/100/1000M | Supported (M7) | No support | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| SAI | on-chip | i2s | Supported | No support | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| USB | on-chip | USB Device | Supported (M7) | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| HWINFO | on-chip | Unique device serial number | Supported (M7) | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| DISPLAY | on-chip | eLCDIF; MIPI-DSI. Tested with | Supported (M7) | Supported (M7) | -| | | :ref:`rk055hdmipi4m`, | | | -| | | :ref:`rk055hdmipi4ma0`, | | | -| | | and :ref:`g1120b0mipi` shields | | | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| ACMP | on-chip | sensor | Supported | No support | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| CAAM RNG | on-chip | entropy | Supported (M7) | No support | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| FLEXSPI | on-chip | flash programming | Supported (M7) | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| SDHC | on-chip | SD host controller | Supported (M7) | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| PIT | on-chip | pit | Supported (M7) | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| VIDEO | on-chip | CSI; MIPI CSI-2 Rx. Tested with | Supported (M7) | Supported (M7) | -| | | :ref:`nxp_btb44_ov5640` shield | | | -+-----------+------------+-------------------------------------+-----------------+-----------------+ -| UART | NXP NW61x | M.2 WIFI/BT module | Unsupported | Supported (M7) | -+-----------+------------+-------------------------------------+-----------------+-----------------+ ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| Interface | Controller | Driver/Component | RT1170 EVK | RT1170 EVKB | ++===========+============+================================================+=================+=================+ +| NVIC | on-chip | nested vector interrupt controller | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| SYSTICK | on-chip | systick | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| GPIO | on-chip | gpio | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| COUNTER | on-chip | gpt | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| TIMER | on-chip | gpt | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| CAN | on-chip | flexcan | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| SPI | on-chip | spi | Supported (M7) | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| I2C | on-chip | i2c | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| PWM | on-chip | pwm | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| ADC | on-chip | adc | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| UART | on-chip | serial port-polling; | Supported | Supported | +| | | serial port-interrupt; | | | +| | | serial port-async | | | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| DMA | on-chip | dma | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| WATCHDOG | on-chip | watchdog | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| ENET | on-chip | ethernet - 10/100M | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| ENET1G | on-chip | ethernet - 10/100/1000M | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| SAI | on-chip | i2s | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| USB | on-chip | USB Device | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| HWINFO | on-chip | Unique device serial number | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| DISPLAY | on-chip | eLCDIF; MIPI-DSI. Tested with | Supported (M7) | Supported (M7) | +| | | :ref:`rk055hdmipi4m`, | | | +| | | :ref:`rk055hdmipi4ma0`, | | | +| | | and :ref:`g1120b0mipi` shields | | | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| ACMP | on-chip | sensor | Supported | Supported | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| CAAM RNG | on-chip | entropy | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| FLEXSPI | on-chip | flash programming | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| SDHC | on-chip | SD host controller | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| PIT | on-chip | pit | Supported (M7) | Supported (M7) | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| VIDEO | on-chip | CSI; MIPI CSI-2 Rx. Tested with | Supported (M7) | Supported (M7) | +| | | :ref:`nxp_btb44_ov5640` shield | | | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ +| UART | NXP IW61x | M.2 WIFI/BT module | Unsupported | Supported (M7) | +| | | (select :kconfig:option:`CONFIG_BT_NXP_NW612`) | | | ++-----------+------------+------------------------------------------------+-----------------+-----------------+ The default configuration can be found in the defconfig files: :zephyr_file:`boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_defconfig` @@ -331,6 +332,25 @@ The secondary core can be debugged normally in single core builds secondary core should be placed into a loop, then a debugger can be attached (see `AN13264`_, section 4.2.3 for more information) +Launching Images Targeting M4 Core +================================== +If building targeting the M4 core, the M7 core must first run code to launch +the M4 image, by copying it into the ``ocram`` region then kicking off the M4 +core. When building using sysbuild targeting the M4 core, a minimal "launcher" +image will be built and flashed to the M7 core, which loads and kicks off +the M4 core. Therefore when developing an application intended to run +standalone on the M4 core, it is recommended to build with sysbuild, like +so: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt1170_evk/mimxrt1176/cm4 + :west-args: --sysbuild + :goals: flash + +If desired, this behavior can be disabled by building with +``-DSB_CONFIG_SECOND_CORE_MCUX_LAUNCHER=n`` + Configuring a Debug Probe ========================= diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.dts b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.dts index cbef2377dab1f..5cd416c9c7372 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.dts +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.dts @@ -25,7 +25,7 @@ zephyr,shell-uart = &lpuart1; zephyr,canbus = &flexcan2; zephyr,flash-controller = &is25wp128; - zephyr,flash = &sram0; + zephyr,flash = &ocram; nxp,m4-partition = &slot1_partition; zephyr,ipc = &mailbox_b; }; diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml index 08bbfa3e6b93b..dd213e258bfff 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml @@ -4,14 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 # -identifier: mimxrt1170_evk/mimxrt1176/cm4 +identifier: mimxrt1170_evk@A/mimxrt1176/cm4 name: NXP MIMXRT1170-EVK CM4 type: mcu arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 128 supported: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml index 061366570f26e..e967a26465dd2 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 128 supported: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.dts b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.dts index 7e2a6c182fb7c..6d4a76fe26095 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.dts +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.dts @@ -150,7 +150,7 @@ nxp_mipi_i2c: &lpi2c5 { zephyr_udc0: &usb1 { status = "okay"; - phy_handle = <&usbphy1>; + phy-handle = <&usbphy1>; }; &usbphy1 { diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml index bf2f139da1072..976b0e71f124d 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml @@ -4,14 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 # -identifier: mimxrt1170_evk/mimxrt1176/cm7 +identifier: mimxrt1170_evk@A/mimxrt1176/cm7 name: NXP MIMXRT1170-EVK CM7 type: mcu arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 16384 supported: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml index 9935c53c7d098..6765cf82f2557 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml @@ -1,5 +1,5 @@ # -# Copyright 2023 NXP +# Copyright 2023, 2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 65536 flash: 65536 supported: @@ -24,8 +23,10 @@ supported: - hwinfo - i2c - mipi_dsi + - netif:eth + - pwm - spi - - usb_device + - usbd - video - watchdog vendor: nxp diff --git a/boards/nxp/mimxrt1180_evk/Kconfig.defconfig b/boards/nxp/mimxrt1180_evk/Kconfig.defconfig index a71be9a7729ae..47c1f2f826265 100644 --- a/boards/nxp/mimxrt1180_evk/Kconfig.defconfig +++ b/boards/nxp/mimxrt1180_evk/Kconfig.defconfig @@ -1,6 +1,6 @@ # MIMXRT1180-EVK board -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 if BOARD_MIMXRT1180_EVK @@ -14,4 +14,20 @@ config NXP_IMX_EXTERNAL_HYPERRAM config BOARD_EARLY_INIT_HOOK default y + +if SECOND_CORE_MCUX && BOARD_MIMXRT1180_EVK_MIMXRT1189_CM7 + +config BUILD_OUTPUT_INFO_HEADER + default y + +DT_CHOSEN_IMAGE_M7 = nxp,m7-partition + +# Adjust the offset of the output image if building for RT18xx SOC +config BUILD_OUTPUT_ADJUST_LMA + default "($(dt_chosen_reg_addr_hex,$(DT_CHOSEN_IMAGE_M7)) + \ + $(dt_node_reg_addr_hex,/soc/spi@425e0000,1)) - \ + $(dt_node_reg_addr_hex,/soc/itcm@0)" + +endif + endif # BOARD_MIMXRT1180_EVK diff --git a/boards/nxp/mimxrt1180_evk/board.c b/boards/nxp/mimxrt1180_evk/board.c index 6ecd6a868b06a..976f3dfcfda59 100644 --- a/boards/nxp/mimxrt1180_evk/board.c +++ b/boards/nxp/mimxrt1180_evk/board.c @@ -12,11 +12,17 @@ void board_early_init_hook(void) { #if defined(CONFIG_ETH_NXP_IMX_NETC) && (DT_CHILD_NUM_STATUS_OKAY(DT_NODELABEL(netc)) != 0) /* RMII mode */ + BLK_CTRL_WAKEUPMIX->NETC_LINK_CFG[0] = BLK_CTRL_WAKEUPMIX_NETC_LINK_CFG_MII_PROT(1); BLK_CTRL_WAKEUPMIX->NETC_LINK_CFG[4] = BLK_CTRL_WAKEUPMIX_NETC_LINK_CFG_MII_PROT(1); + /* RGMII mode */ + BLK_CTRL_WAKEUPMIX->NETC_LINK_CFG[1] = BLK_CTRL_WAKEUPMIX_NETC_LINK_CFG_MII_PROT(2); + BLK_CTRL_WAKEUPMIX->NETC_LINK_CFG[2] = BLK_CTRL_WAKEUPMIX_NETC_LINK_CFG_MII_PROT(2); + BLK_CTRL_WAKEUPMIX->NETC_LINK_CFG[3] = BLK_CTRL_WAKEUPMIX_NETC_LINK_CFG_MII_PROT(2); /* Output reference clock for RMII */ BLK_CTRL_WAKEUPMIX->NETC_PORT_MISC_CFG |= - BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_PORT4_RMII_REF_CLK_DIR_MASK; + BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_PORT4_RMII_REF_CLK_DIR_MASK | + BLK_CTRL_WAKEUPMIX_NETC_PORT_MISC_CFG_PORT0_RMII_REF_CLK_DIR_MASK; /* Unlock the IERB. It will warm reset whole NETC. */ NETC_PRIV->NETCRR &= ~NETC_PRIV_NETCRR_LOCK_MASK; diff --git a/boards/nxp/mimxrt1180_evk/board.cmake b/boards/nxp/mimxrt1180_evk/board.cmake index 36f76d8315373..b0659abddc905 100644 --- a/boards/nxp/mimxrt1180_evk/board.cmake +++ b/boards/nxp/mimxrt1180_evk/board.cmake @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -9,7 +9,7 @@ set(RT1180_BOARD_DIR # Note1: Suggest developers use Secure Provisioning Tool(SPT) to download RT1180 image # SPT can be downloaded on NXP web: https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-secure-provisioning-tool:MCUXPRESSO-SECURE-PROVISIONING # Details about the usage of SPT on MIMXRT1180-EVK board can be referred on chapter 7 of getting start with Mcuxpresso SDK for MIMXRT1180-EVK doc in SDK package. -if(CONFIG_SOC_MIMXRT1189_CM33) +if(CONFIG_SOC_MIMXRT1189_CM33 OR CONFIG_SECOND_CORE_MCUX) board_runner_args(linkserver "--device=MIMXRT1189xxxxx:MIMXRT1180-EVK") board_runner_args(jlink "--device=MIMXRT1189xxx8_M33" "--reset-after-load" "--tool-opt=-jlinkscriptfile ${RT1180_BOARD_DIR}/jlinkscript/evkmimxrt1180_cm33.jlinkscript") elseif(CONFIG_SOC_MIMXRT1189_CM7) @@ -19,5 +19,5 @@ board_runner_args(linkserver "--core=cm7") board_runner_args(jlink "--device=MIMXRT1189xxx8_M7" "--speed=4000" "--no-reset" "--tool-opt=-jlinkscriptfile ${RT1180_BOARD_DIR}/jlinkscript/evkmimxrt1180_cm7.jlinkscript" "--tool-opt=-ir") endif() -include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/mimxrt1180_evk/doc/index.rst b/boards/nxp/mimxrt1180_evk/doc/index.rst index 012cb9407ada5..27f46447ca621 100644 --- a/boards/nxp/mimxrt1180_evk/doc/index.rst +++ b/boards/nxp/mimxrt1180_evk/doc/index.rst @@ -106,7 +106,7 @@ configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | ADC | on-chip | adc | +-----------+------------+-------------------------------------+ -| NETC | on-chip | ethernet, mdio | +| NETC | on-chip | dsa, ethernet, mdio | +-----------+------------+-------------------------------------+ | CAN | on-chip | can | +-----------+------------+-------------------------------------+ @@ -116,6 +116,22 @@ configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | PWM | on-chip | pwm | +-----------+------------+-------------------------------------+ +| PWM | on-chip | tpm | ++-----------+------------+-------------------------------------+ +| I3C | on-chip | i3c | ++-----------+------------+-------------------------------------+ +| DMA | on-chip | dma | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| RTWDOG | on-chip | rtwdog | ++-----------+------------+-------------------------------------+ +| HWINFO | on-chip | Unique device serial number | ++-----------+------------+-------------------------------------+ +| USB | on-chip | USB device | ++-----------+------------+-------------------------------------+ +| SDHC | on-chip | SD host controller | ++-----------+------------+-------------------------------------+ The default configuration can be found in the defconfig file: :zephyr_file:`boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33_defconfig` @@ -135,10 +151,25 @@ The MIMXRT1180 SoC has six pairs of pinmux/gpio controllers. +---------------+-----------------+---------------------------+ | GPIO_AD_27 | GPIO | LED | +---------------+-----------------+---------------------------+ -| GPIO_AON_08 | LPUART1_TX | UART Console | +| GPIO_AON_08 | LPUART1_TX | UART Console M33 core | ++---------------+-----------------+---------------------------+ +| GPIO_AON_09 | LPUART1_RX | UART Console M33 core | ++---------------+---------------------------------------------+ +| GPIO_AON_19 | LPUART12_TX | UART Console M7 core | +---------------+-----------------+---------------------------+ -| GPIO_AON_09 | LPUART1_RX | UART Console | +| GPIO_AON_20 | LPUART12_RX | UART Console M7 core | +---------------+-----------------+---------------------------+ +| GPIO_SD_B1_00 | SPI1_CS0 | spi | ++---------------+---------------------------------------------+ +| GPIO_SD_B1_01 | SPI1_CLK | spi | ++---------------+---------------------------------------------+ +| GPIO_SD_B1_02 | SPI1_SDO | spi | ++---------------+---------------------------------------------+ +| GPIO_SD_B1_03 | SPI1_SDI | spi | ++---------------+-----------------+---------------------------+ + +UART for M7 core is connected to USB-to-UART J60 connector. +Or user can use open JP7 Jumper to enable second UART on MCU LINK J53 connector. System Clock ============ @@ -150,13 +181,41 @@ running at 792MHz Serial Port =========== -The MIMXRT1180 SoC has 12 UARTs. One is configured for the console and the -remaining are not used. +The MIMXRT1180 SoC has 12 UARTs. LPUART1 is configured for the CM33 console, the LPUART12 is +configured for the CM7 console core and the remaining are not used. Ethernet ======== -NETC driver supports to manage the Physical Station Interface (PSI). +NETC Ethernet driver supports to manage the Physical Station Interface (PSI). +NETC DSA driver supports to manage switch ports. Current DSA support is with +limitation that only switch function is available without management via +DSA master port. DSA master port support is TODO work. + +.. code-block:: none + + +--------+ +--------+ + | ENETC1 | | ENETC0 | + | | | | + | Pseudo | | 1G | + | MAC | | MAC | + +--------+ +--------+ + | zero copy interface | + +-------------- +--------+----------------+ | + | | Pseudo | | | + | | MAC | | | + | | | | | + | | Port 4 | | | + | +--------+ | | + | SWITCH CORE | | + +--------+ +--------+ +--------+ +--------+ | + | Port 0 | | Port 1 | | Port 2 | | Port 3 | | + | | | | | | | | | + | 1G | | 1G | | 1G | | 1G | | + | MAC | | MAC | | MAC | | MAC | | + +--------+-+--------+-+--------+-+--------+ | + | | | | | + NETC External Interfaces (4 switch ports, 1 end-point port) Programming and Debugging ************************* @@ -167,18 +226,19 @@ Build and flash applications as usual (see :ref:`build_an_application` and Configuring a Debug Probe ========================= +LinkServer is the default runner for this board. A debug probe is used for both flashing and debugging the board. This board is -configured by default to use the :ref:`mcu-link-cmsis-onboard-debug-probe`, -however the :ref:`pyocd-debug-host-tools` do not yet support programming the -external flashes on this board so you must reconfigure the board for one of the -following debug probes instead. +configured by default to use the :ref:`mcu-link-cmsis-onboard-debug-probe`. +The :ref:`pyocd-debug-host-tools` do not yet support programming the +external flashes on this board. Use one of the other supported debug probes +below. .. _Using J-Link RT1180: Using J-Link ------------ -Please ensure used JLINK above V7.94g and jumper JP5 installed if using +Please ensure to use a version of JLINK above V7.94g and jumper JP5 is installed if using external jlink plus on J37 as debugger. When debugging cm33 core, need to ensure the SW5 on "0100" mode. @@ -196,12 +256,22 @@ EVK. Using Linkserver ---------------- -Please ensure used linkserver above V1.5.30 and jumper JP5 uninstalled. +Please ensure to use a version of Linkserver above V1.5.30 and jumper JP5 is uninstalled (default setting). When debugging cm33 core, need to ensure the SW5 on "0100" mode. When debugging cm7 core, need to ensure the SW5 on "0001" mode. (Only support run cm7 image when debugging due to default boot core on board is cm33 core) +Dual Core samples Debugging +*************************** + +When debugging dual core samples, need to ensure the SW5 on "0100" mode. +The CM33 core is responsible for copying and starting the CM7. +To debug the CM7 it is useful to put infinite while loop either in reset vector or +into main function and attach via debugger to CM7 core. + +CM7 core can be started again only after reset, so after flashing ensure to reset board. + Configuring a Console ===================== diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk-pinctrl.dtsi b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk-pinctrl.dtsi index 29687171a5073..a0ee4993f68b9 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk-pinctrl.dtsi +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * SPDX-License-Identifier: Apache-2.0 * */ @@ -17,6 +17,88 @@ }; }; + eth0_default: eth0_default { + group1 { + pinmux = <&iomuxc_gpio_emc_b2_05_eth0_tx_data0>, + <&iomuxc_gpio_emc_b2_06_eth0_tx_data1>, + <&iomuxc_gpio_emc_b2_07_eth0_tx_en>, + <&iomuxc_gpio_emc_b2_09_eth0_rx_data0>, + <&iomuxc_gpio_emc_b2_10_eth0_rx_data1>, + <&iomuxc_gpio_emc_b2_11_eth0_rx_en>, + <&iomuxc_gpio_emc_b2_12_eth0_rx_er>; + bias-pull-down; + slew-rate = "fast"; + drive-strength = "high"; + }; + group2 { + pinmux = <&iomuxc_gpio_emc_b2_08_eth0_tx_clk>; + input-enable; + bias-pull-down; + slew-rate = "fast"; + drive-strength = "high"; + }; + }; + + eth1_default: eth1_default { + group1 { + pinmux = <&iomuxc_gpio_b1_00_eth1_tx_data0>, + <&iomuxc_gpio_b1_01_eth1_tx_data1>, + <&iomuxc_gpio_b1_02_eth1_tx_en>, + <&iomuxc_gpio_b1_03_eth1_tx_clk >, + <&iomuxc_gpio_b1_04_eth1_rx_data0>, + <&iomuxc_gpio_b1_05_eth1_rx_data1>, + <&iomuxc_gpio_b1_06_eth1_rx_en>, + <&iomuxc_gpio_b1_07_eth1_tx_data2>, + <&iomuxc_gpio_b1_08_eth1_tx_data3>, + <&iomuxc_gpio_b1_09_eth1_rx_data2>, + <&iomuxc_gpio_b1_10_eth1_rx_data3>, + <&iomuxc_gpio_b1_11_eth1_rx_clk>; + bias-pull-down; + slew-rate = "fast"; + drive-strength = "high"; + }; + }; + + eth2_default: eth2_default { + group1 { + pinmux = <&iomuxc_gpio_emc_b1_13_eth2_rx_en>, + <&iomuxc_gpio_emc_b1_16_eth2_rx_data0>, + <&iomuxc_gpio_emc_b1_17_eth2_rx_data1>, + <&iomuxc_gpio_emc_b1_21_eth2_rx_clk>, + <&iomuxc_gpio_emc_b1_22_eth2_rx_data2>, + <&iomuxc_gpio_emc_b1_23_eth2_rx_data3>, + <&iomuxc_gpio_emc_b1_24_eth2_tx_data3>, + <&iomuxc_gpio_emc_b1_25_eth2_tx_data2>, + <&iomuxc_gpio_emc_b1_26_eth2_tx_data1>, + <&iomuxc_gpio_emc_b1_27_eth2_tx_data0>, + <&iomuxc_gpio_emc_b1_28_eth2_tx_en>, + <&iomuxc_gpio_emc_b1_29_eth2_tx_clk>; + bias-pull-down; + slew-rate = "fast"; + drive-strength = "high"; + }; + }; + + eth3_default: eth3_default { + group1 { + pinmux = <&iomuxc_gpio_emc_b1_00_eth3_tx_data3>, + <&iomuxc_gpio_emc_b1_01_eth3_tx_data2>, + <&iomuxc_gpio_emc_b1_02_eth3_rx_clk>, + <&iomuxc_gpio_emc_b1_03_eth3_rx_data3>, + <&iomuxc_gpio_emc_b1_04_eth3_rx_data2>, + <&iomuxc_gpio_emc_b1_05_eth3_tx_data0>, + <&iomuxc_gpio_emc_b1_06_eth3_tx_data1>, + <&iomuxc_gpio_emc_b1_07_eth3_tx_en>, + <&iomuxc_gpio_emc_b1_08_eth3_tx_clk>, + <&iomuxc_gpio_emc_b1_09_eth3_rx_data0>, + <&iomuxc_gpio_emc_b1_10_eth3_rx_data1>, + <&iomuxc_gpio_emc_b1_11_eth3_rx_en>; + bias-pull-down; + slew-rate = "fast"; + drive-strength = "high"; + }; + }; + eth4_default: eth4_default { group1 { pinmux = <&iomuxc_gpio_emc_b2_13_eth4_tx_data0>, @@ -73,6 +155,52 @@ }; }; + pinmux_lpuart12: pinmux_lpuart12 { + group0 { + pinmux = <&iomuxc_aon_gpio_aon_20_lpuart12_rxd>, + <&iomuxc_aon_gpio_aon_19_lpuart12_txd>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart12_sleep: pinmux_lpuart12_sleep { + group0 { + pinmux = <&iomuxc_aon_gpio_aon_20_lpuart12_rxd>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + group1 { + pinmux = <&iomuxc_aon_gpio_aon_19_lpuart12_txd>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart3: pinmux_lpuart3 { + group0 { + pinmux = <&iomuxc_gpio_ad_14_lpuart3_rxd>, + <&iomuxc_gpio_ad_13_lpuart3_txd>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart3_sleep: pinmux_lpuart3_sleep { + group0 { + pinmux = <&iomuxc_gpio_ad_14_gpio4_io14>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + group1 { + pinmux = <&iomuxc_gpio_ad_13_lpuart3_txd>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + /* Connected to FXLS8974 */ pinmux_lpi2c2: pinmux_lpi2c2 { group0 { @@ -137,4 +265,86 @@ slew-rate = "fast"; }; }; + + pinmux_tpm5: pinmux_tpm5 { + group0 { + pinmux = <&iomuxc_gpio_b1_00_tpm5_ch0>; + drive-strength = "normal"; + slew-rate = "slow"; + }; + }; + + pinmux_i3c2: pinmux_i3c2 { + group0 { + pinmux = <&iomuxc_gpio_ad_18_i3c2_scl>, + <&iomuxc_gpio_ad_19_i3c2_sda>; + drive-strength = "normal"; + drive-open-drain; + slew-rate = "fast"; + input-enable; + }; + + group1 { + pinmux = <&iomuxc_gpio_ad_17_i3c2_pur>; + slew-rate = "fast"; + drive-strength = "high"; + }; + }; + + pinmux_usdhc1: pinmux_usdhc1 { + group0 { + pinmux = <&iomuxc_gpio_sd_b1_00_usdhc1_cmd>, + <&iomuxc_gpio_sd_b1_01_usdhc1_clk>, + <&iomuxc_gpio_sd_b1_02_usdhc1_data0>, + <&iomuxc_gpio_sd_b1_03_usdhc1_data1>, + <&iomuxc_gpio_sd_b1_04_usdhc1_data2>, + <&iomuxc_gpio_sd_b1_05_usdhc1_data3>; + bias-pull-up; + input-enable; + }; + group1 { + pinmux = <&iomuxc_gpio_ad_34_usdhc1_vselect>, + <&iomuxc_gpio_ad_15_gpio4_io15>; + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + }; + group2 { + pinmux = <&iomuxc_gpio_ad_14_gpio4_io14>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + }; + + /* removes pull on dat3 for card detect */ + pinmux_usdhc1_dat3_nopull: pinmux_usdhc1_dat3_nopull { + group0 { + pinmux = <&iomuxc_gpio_sd_b1_05_usdhc1_data3>; + bias-disable; + input-enable; + }; + group1 { + pinmux = <&iomuxc_gpio_sd_b1_00_usdhc1_cmd>, + <&iomuxc_gpio_sd_b1_01_usdhc1_clk>, + <&iomuxc_gpio_sd_b1_02_usdhc1_data0>, + <&iomuxc_gpio_sd_b1_03_usdhc1_data1>, + <&iomuxc_gpio_sd_b1_04_usdhc1_data2>; + bias-pull-up; + input-enable; + }; + group2 { + pinmux = <&iomuxc_gpio_ad_34_usdhc1_vselect>, + <&iomuxc_gpio_ad_15_gpio4_io15>; + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + }; + group3 { + pinmux = <&iomuxc_gpio_ad_14_gpio4_io14>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + }; }; diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk.dtsi b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk.dtsi index 3f71d74a762b5..8da2b53518594 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk.dtsi +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ led0 = &green_led; sw0 = &user_button; pwm-led0 = &green_pwm_led; + sdhc0 = &usdhc1; }; leds { @@ -19,7 +20,7 @@ green_led: led-1 { gpios = <&gpio4 27 GPIO_ACTIVE_HIGH>; label = "User LED D6"; - }; + }; }; gpio_keys { @@ -39,6 +40,102 @@ }; }; +&emdio { + pinctrl-0 = <&emdio_default>; + pinctrl-names = "default"; + status = "okay"; + + phy0: phy@2 { + compatible = "ethernet-phy"; + reg = <0x2>; + status = "okay"; + }; + + phy1: phy@5 { + compatible = "realtek,rtl8211f"; + reg = <0x5>; + status = "okay"; + }; + + phy2: phy@4 { + compatible = "realtek,rtl8211f"; + reg = <0x4>; + status = "okay"; + }; + + phy3: phy@7 { + compatible = "realtek,rtl8211f"; + reg = <0x7>; + status = "okay"; + }; + + phy4: phy@3 { + compatible = "ethernet-phy"; + reg = <0x3>; + status = "okay"; + }; +}; + +&enetc_psi0 { + local-mac-address = [00 00 00 01 02 00]; + pinctrl-0 = <ð4_default>; + pinctrl-names = "default"; + phy-handle = <&phy4>; + status = "okay"; +}; + +/* Internal port */ +&enetc_psi1 { + local-mac-address = [00 00 00 01 03 00]; + status = "okay"; +}; + +&switch { + status = "okay"; +}; + +&switch_port0 { + local-mac-address = [00 00 00 01 04 00]; + pinctrl-0 = <ð0_default>; + pinctrl-names = "default"; + phy-handle = <&phy0>; + phy-connection-type = "rmii"; + status = "okay"; +}; + +&switch_port1 { + local-mac-address = [00 00 00 01 05 00]; + pinctrl-0 = <ð1_default>; + pinctrl-names = "default"; + phy-handle = <&phy1>; + phy-connection-type = "rgmii"; + status = "okay"; +}; + +&switch_port2 { + local-mac-address = [00 00 00 01 06 00]; + pinctrl-0 = <ð2_default>; + pinctrl-names = "default"; + phy-handle = <&phy2>; + phy-connection-type = "rgmii"; + status = "okay"; +}; + +&switch_port3 { + local-mac-address = [00 00 00 01 07 00]; + pinctrl-0 = <ð3_default>; + pinctrl-names = "default"; + phy-handle = <&phy3>; + phy-connection-type = "rgmii"; + status = "okay"; +}; + +/* Internal port */ +&switch_port4 { + local-mac-address = [00 00 00 01 06 00]; + status = "okay"; +}; + &lpuart1 { status = "okay"; current-speed = <115200>; @@ -47,6 +144,20 @@ pinctrl-names = "default", "sleep"; }; +&lpuart12 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart12>; + pinctrl-1 = <&pinmux_lpuart12_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&lpuart3 { + pinctrl-0 = <&pinmux_lpuart3>; + pinctrl-1 = <&pinmux_lpuart3_sleep>; + pinctrl-names = "default", "sleep"; +}; + &user_button { status = "okay"; }; @@ -139,3 +250,38 @@ pinctrl-0 = <&pinmux_flexpwm2>; pinctrl-names = "default"; }; + +&tpm5 { + pinctrl-0 = <&pinmux_tpm5>; + pinctrl-names = "default"; +}; + +&i3c2 { + pinctrl-0 = <&pinmux_i3c2>; + pinctrl-names = "default"; +}; + +p3t1755dp_ard_i3c_interface: &i3c2 {}; +p3t1755dp_ard_i2c_interface: &lpi2c2 {}; + +&lpspi3 { + dmas = <&edma4 1 13>, <&edma4 2 12>; + dma-names = "rx", "tx"; + pinctrl-0 = <&pinmux_lpspi3>; + pinctrl-names = "default"; +}; + +&usdhc1 { + status = "okay"; + detect-dat3; + no-1-8-v; + pwr-gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&pinmux_usdhc1>; + pinctrl-1 = <&pinmux_usdhc1_dat3_nopull>; + pinctrl-names = "default", "nopull"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts index 331f85b5bf8fa..8143c05525816 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.dts @@ -19,8 +19,10 @@ zephyr,itcm = &itcm; zephyr,flash-controller = &w25q128jw; zephyr,flash = &w25q128jw; + zephyr,code-partition = &slot0_partition; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; + zephyr,uart-mcumgr = &lpuart1; zephyr,canbus = &flexcan3; }; @@ -31,26 +33,6 @@ }; }; -&emdio { - pinctrl-0 = <&emdio_default>; - pinctrl-names = "default"; - status = "okay"; - - phy4: phy@3 { - compatible = "ethernet-phy"; - reg = <0x3>; - status = "okay"; - }; -}; - -&enetc_psi0 { - local-mac-address = [00 00 00 01 02 00]; - pinctrl-0 = <ð4_default>; - pinctrl-names = "default"; - phy-handle = <&phy4>; - status = "okay"; -}; - &lpuart1 { status = "okay"; current-speed = <115200>; @@ -75,3 +57,31 @@ &lptmr1 { status = "okay"; }; + +&i3c2 { + status = "okay"; +}; + +&lpspi3 { + status = "okay"; +}; + +&edma3 { + status = "okay"; +}; + +&edma4 { + status = "okay"; +}; + +zephyr_udc0: &usb1 { + status = "okay"; + phy-handle = <&usbphy1>; +}; + +&usbphy1 { + status = "okay"; + tx-d-cal = <7>; + tx-cal-45-dp-ohms = <6>; + tx-cal-45-dm-ohms = <6>; +}; diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml index 93268aa528606..e291f38a9fac3 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 16384 supported: @@ -24,4 +23,10 @@ supported: - netif:eth - pwm - uart + - i3c + - dma + - spi + - watchdog + - usb_device + - sdhc vendor: nxp diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts index 84c2245eae911..81bd3a2124753 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.dts @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,15 +15,24 @@ chosen { zephyr,sram = &dtcm; + zephyr,dtcm = &dtcm; + zephyr,itcm = &itcm; zephyr,flash-controller = &w25q128jw; zephyr,flash = &itcm; - zephyr,console = &lpuart1; - zephyr,shell-uart = &lpuart1; + zephyr,console = &lpuart12; + zephyr,shell-uart = &lpuart12; zephyr,canbus = &flexcan3; + nxp,m7-partition = &slot1_partition; + }; + + hyperram0: memory@04000000 { + /* Winbond W957A8MFYA5K */ + device_type = "memory"; + reg = <0x04000000 DT_SIZE_M(8)>; }; }; -&lpuart1 { +&lpuart12 { status = "okay"; current-speed = <115200>; }; @@ -47,3 +56,31 @@ &lptmr1 { status = "okay"; }; + +&i3c2 { + status = "okay"; +}; + +&lpspi3 { + status = "okay"; +}; + +&edma3 { + status = "okay"; +}; + +&edma4 { + status = "okay"; +}; + +zephyr_udc0: &usb1 { + status = "okay"; + phy-handle = <&usbphy1>; +}; + +&usbphy1 { + status = "okay"; + tx-d-cal = <7>; + tx-cal-45-dp-ohms = <6>; + tx-cal-45-dm-ohms = <6>; +}; diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml index 87f1467207a87..a733aad8b7df6 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 256 supported: @@ -23,4 +22,8 @@ supported: - i2c - pwm - uart + - i3c + - dma + - spi + - sdhc vendor: nxp diff --git a/boards/nxp/mimxrt595_evk/CMakeLists.txt b/boards/nxp/mimxrt595_evk/CMakeLists.txt index f7db55d9430ff..79cb85e066495 100644 --- a/boards/nxp/mimxrt595_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt595_evk/CMakeLists.txt @@ -28,5 +28,5 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) endif() # Add custom linker section to relocate framebuffers to PSRAM -zephyr_linker_sources_ifdef(CONFIG_LV_Z_VBD_CUSTOM_SECTION +zephyr_linker_sources_ifdef(CONFIG_LV_Z_VDB_CUSTOM_SECTION SECTIONS dc_ram.ld) diff --git a/boards/nxp/mimxrt595_evk/board.c b/boards/nxp/mimxrt595_evk/board.c index 8db60fdcb6b07..ecb6cbcd129c4 100644 --- a/boards/nxp/mimxrt595_evk/board.c +++ b/boards/nxp/mimxrt595_evk/board.c @@ -5,6 +5,7 @@ #include #include "fsl_power.h" +#include "fsl_inputmux.h" #include #include "board.h" @@ -306,6 +307,52 @@ static int mimxrt595_evk_init(void) #endif /* CONFIG_I2S_TEST_SEPARATE_DEVICES */ #endif /* CONFIG_I2S */ + /* Configure the DMA requests in the INPUTMUX */ + INPUTMUX_Init(INPUTMUX); +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dma0)) + /* Enable the DMA requests with only 1 mux option. The other request + * choices should be configured for the application + */ + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm11RxToDmac0Ch32RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm11TxToDmac0Ch33RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm12RxToDmac0Ch34RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm12TxToDmac0Ch35RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm16RxToDmac0Ch28RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm16TxToDmac0Ch29RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_I3c1RxToDmac0Ch30RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_I3c1TxToDmac0Ch31RequestEna, true); +#endif /* dma0 */ + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dma1)) + /* Enable the DMA requests with only 1 mux option. The other request + * choices should be configured for the application + */ + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm11RxToDmac1Ch32RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm11TxToDmac1Ch33RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm12RxToDmac1Ch34RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm12TxToDmac1Ch35RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm16RxToDmac1Ch28RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_Flexcomm16TxToDmac1Ch29RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_I3c1RxToDmac1Ch30RequestEna, true); + INPUTMUX_EnableSignal(INPUTMUX, + kINPUTMUX_I3c1TxToDmac1Ch31RequestEna, true); +#endif /* dma1 */ + INPUTMUX_Deinit(INPUTMUX); #ifdef CONFIG_REBOOT /* @@ -344,7 +391,7 @@ static int mimxrt595_evk_init(void) } -#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION +#ifdef CONFIG_LV_Z_VDB_CUSTOM_SECTION extern char __flexspi2_start[]; extern char __flexspi2_end[]; @@ -358,14 +405,14 @@ static int init_psram_framebufs(void) return 0; } -#endif /* CONFIG_LV_Z_VBD_CUSTOM_SECTION */ +#endif /* CONFIG_LV_Z_VDB_CUSTOM_SECTION */ #if CONFIG_REGULATOR /* PMIC setup is dependent on the regulator API */ SYS_INIT(board_config_pmic, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY); #endif -#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION +#ifdef CONFIG_LV_Z_VDB_CUSTOM_SECTION /* Framebuffers should be setup after PSRAM is initialized but before * Graphics framework init */ diff --git a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.yaml b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.yaml index a2e8406c02baa..65739236386ea 100644 --- a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.yaml +++ b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 4608 flash: 65536 supported: diff --git a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts index bc091a2abf424..a92f00d270063 100644 --- a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts +++ b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts @@ -359,7 +359,7 @@ i2s1: &flexcomm3 { zephyr_udc0: &usbhs { status = "okay"; - phy_handle = <&usbphy>; + phy-handle = <&usbphy>; }; &usbphy { diff --git a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.yaml b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.yaml index 75124a8e7da51..8e861a3a3e570 100644 --- a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.yaml +++ b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 4608 flash: 65536 supported: diff --git a/boards/nxp/mimxrt700_evk/CMakeLists.txt b/boards/nxp/mimxrt700_evk/CMakeLists.txt new file mode 100644 index 0000000000000..e13f3a2679630 --- /dev/null +++ b/boards/nxp/mimxrt700_evk/CMakeLists.txt @@ -0,0 +1,28 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +if(CONFIG_BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU0 OR CONFIG_BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU1) + zephyr_library() + zephyr_library_sources(board.c) +endif() + +if(CONFIG_NXP_IMXRT_BOOT_HEADER) + if(NOT ((DEFINED CONFIG_BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU0) + OR (DEFINED CONFIG_BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU1))) + message(WARNING "It appears you are using the board definition for " + "the MIMXRT7xx-EVK, but targeting a custom board. You may need to " + "update your flash configuration block data") + endif() + # Include flash configuration block for RT7xx EVK from NXP's HAL. + # This configuration block may need modification if another flash chip is + # used on your custom board. See NXP AN13304 for more information. + zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) + zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) + set(RT7XX_BOARD_DIR + "${ZEPHYR_HAL_NXP_MODULE_DIR}/mcux/mcux-sdk/boards/mimxrt700evk") + zephyr_library_sources(${RT7XX_BOARD_DIR}/flash_config/flash_config.c) + zephyr_library_include_directories(${RT7XX_BOARD_DIR}/flash_config) +endif() diff --git a/boards/nxp/mimxrt700_evk/Kconfig.mimxrt700_evk b/boards/nxp/mimxrt700_evk/Kconfig.mimxrt700_evk new file mode 100644 index 0000000000000..af33cfc734b4e --- /dev/null +++ b/boards/nxp/mimxrt700_evk/Kconfig.mimxrt700_evk @@ -0,0 +1,7 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MIMXRT700_EVK + select SOC_MIMXRT798S_CM33_CPU0 if BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU0 + select SOC_MIMXRT798S_CM33_CPU1 if BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU1 + select SOC_PART_NUMBER_MIMXRT798SGFOA diff --git a/boards/nxp/mimxrt700_evk/board.c b/boards/nxp/mimxrt700_evk/board.c new file mode 100644 index 0000000000000..43e029b32e2ff --- /dev/null +++ b/boards/nxp/mimxrt700_evk/board.c @@ -0,0 +1,489 @@ +/* + * Copyright 2024-2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "fsl_power.h" +#include "fsl_clock.h" +#include +#include + +/*!< System oscillator settling time in us */ +#define SYSOSC_SETTLING_US 220U +/*!< xtal frequency in Hz */ +#define XTAL_SYS_CLK_HZ 24000000U + +#if CONFIG_SOC_MIMXRT798S_CM33_CPU0 +#define SYSCON_BASE DT_REG_ADDR(DT_NODELABEL(syscon0)) +#define EN_NUM 4 +#elif CONFIG_SOC_MIMXRT798S_CM33_CPU1 +#define SYSCON_BASE DT_REG_ADDR(DT_NODELABEL(syscon1)) +#define EN_NUM 2 +#endif + +#define EDMA_EN_OFFSET 0x420 +#define EDMA_EN_REG(instance, idx) ((uint32_t *)((uint32_t)(SYSCON_BASE) + \ + (EDMA_EN_OFFSET) + 0x10U * (instance) + 4U * (idx))) + +#define SET_UP_FLEXCOMM_CLOCK(x) \ + do { \ + CLOCK_AttachClk(kFCCLK0_to_FLEXCOMM##x); \ + RESET_ClearPeripheralReset(kFC##x##_RST_SHIFT_RSTn); \ + CLOCK_EnableClock(kCLOCK_LPFlexComm##x); \ + } while (0) + +#ifdef CONFIG_SOC_MIMXRT798S_CM33_CPU0 +#define SET_UP_CTIMER_CLOCK(x) \ + do { \ + CLOCK_AttachClk(kFRO0_DIV1_to_CTIMER##x); \ + CLOCK_SetClkDiv(kCLOCK_DivCtimer##x##Clk, 1U); \ + } while (0) +#elif CONFIG_SOC_MIMXRT798S_CM33_CPU1 +#define SET_UP_CTIMER_CLOCK(x) \ + do { \ + CLOCK_AttachClk(kFRO2_DIV1_to_CTIMER##x); \ + CLOCK_SetClkDiv(kCLOCK_DivCtimer##x##Clk, 1U); \ + } while (0) +#endif + +const clock_main_pll_config_t g_mainPllConfig_clock_init = { + .main_pll_src = kCLOCK_MainPllOscClk, /* OSC clock */ + .numerator = 0, /* Numerator of the SYSPLL0 fractional loop divider is 0 */ + .denominator = 1, /* Denominator of the SYSPLL0 fractional loop divider is 1 */ + .main_pll_mult = kCLOCK_MainPllMult22 /* Divide by 22 */ +}; + +const clock_audio_pll_config_t g_audioPllConfig_clock_init = { + .audio_pll_src = kCLOCK_AudioPllOscClk, /* OSC clock */ + .numerator = 5040, /* Numerator of the Audio PLL fractional loop divider is 0 */ + .denominator = 27000, /* Denominator of the Audio PLL fractional loop divider is 1 */ + .audio_pll_mult = kCLOCK_AudioPllMult22, /* Divide by 22 */ + .enableVcoOut = true}; + +static void BOARD_InitAHBSC(void); +#if CONFIG_DT_HAS_NXP_MCUX_EDMA_ENABLED +static void edma_enable_all_request(uint8_t instance); +#endif + +void board_early_init_hook(void) +{ +#if CONFIG_SOC_MIMXRT798S_CM33_CPU0 + const clock_fro_config_t froAutotrimCfg = { + .targetFreq = 300000000U, + .range = 50U, + .trim1DelayUs = 15U, + .trim2DelayUs = 15U, + .refDiv = 1U, + .enableInt = 0U, + .coarseTrimEn = true, + }; + + POWER_DisablePD(kPDRUNCFG_PD_LPOSC); + + /* Power up OSC */ + POWER_DisablePD(kPDRUNCFG_PD_SYSXTAL); + /* Enable system OSC */ + CLOCK_EnableSysOscClk(true, true, SYSOSC_SETTLING_US); + /* Sets external XTAL OSC freq */ + CLOCK_SetXtalFreq(XTAL_SYS_CLK_HZ); + + /* Make sure FRO1 is enabled. */ + POWER_DisablePD(kPDRUNCFG_PD_FRO1); + + /* Switch to FRO1 for safe configure. */ + CLOCK_AttachClk(kFRO1_DIV1_to_COMPUTE_BASE); + CLOCK_AttachClk(kCOMPUTE_BASE_to_COMPUTE_MAIN); + CLOCK_SetClkDiv(kCLOCK_DivCmptMainClk, 1U); + CLOCK_AttachClk(kFRO1_DIV1_to_RAM); + CLOCK_SetClkDiv(kCLOCK_DivComputeRamClk, 1U); + CLOCK_AttachClk(kFRO1_DIV1_to_COMMON_BASE); + CLOCK_AttachClk(kCOMMON_BASE_to_COMMON_VDDN); + CLOCK_SetClkDiv(kCLOCK_DivCommonVddnClk, 1U); + +#if CONFIG_FLASH_MCUX_XSPI_XIP + /* Change to common_base clock(Sourced by FRO1). */ + xspi_clock_safe_config(); +#endif + + /* Ungate all FRO clock. */ + POWER_DisablePD(kPDRUNCFG_GATE_FRO0); + /* Use close loop mode. */ + CLOCK_EnableFroClkFreqCloseLoop(FRO0, &froAutotrimCfg, kCLOCK_FroAllOutEn); + /* Enable FRO0 MAX clock for all domains.*/ + CLOCK_EnableFro0ClkForDomain(kCLOCK_AllDomainEnable); + + CLOCK_InitMainPll(&g_mainPllConfig_clock_init); + CLOCK_InitMainPfd(kCLOCK_Pfd0, 20U); /* 475 MHz */ + CLOCK_InitMainPfd(kCLOCK_Pfd1, 24U); /* 396 MHz */ + CLOCK_InitMainPfd(kCLOCK_Pfd2, 18U); /* 528 MHz */ + /* Main PLL kCLOCK_Pfd3 (528 * 18 / 19) = 500 MHz -need 2 div -> 250 MHz*/ + CLOCK_InitMainPfd(kCLOCK_Pfd3, 19U); + + CLOCK_EnableMainPllPfdClkForDomain(kCLOCK_Pfd0, kCLOCK_AllDomainEnable); + CLOCK_EnableMainPllPfdClkForDomain(kCLOCK_Pfd1, kCLOCK_AllDomainEnable); + CLOCK_EnableMainPllPfdClkForDomain(kCLOCK_Pfd2, kCLOCK_AllDomainEnable); + CLOCK_EnableMainPllPfdClkForDomain(kCLOCK_Pfd3, kCLOCK_AllDomainEnable); + + CLOCK_SetClkDiv(kCLOCK_DivCmptMainClk, 2U); + CLOCK_AttachClk(kMAIN_PLL_PFD0_to_COMPUTE_MAIN); /* Switch to PLL 237.5 MHz */ + + CLOCK_SetClkDiv(kCLOCK_DivMediaMainClk, 2U); + CLOCK_AttachClk(kMAIN_PLL_PFD0_to_MEDIA_MAIN); /* Switch to PLL 237.5 MHz */ + + CLOCK_SetClkDiv(kCLOCK_DivMediaVddnClk, 2U); + CLOCK_AttachClk(kMAIN_PLL_PFD0_to_MEDIA_VDDN); /* Switch to PLL 237.5 MHz */ + + CLOCK_SetClkDiv(kCLOCK_DivComputeRamClk, 2U); + CLOCK_AttachClk(kMAIN_PLL_PFD0_to_RAM); /* Switch to PLL 237.5 MHz */ + + CLOCK_SetClkDiv(kCLOCK_DivCommonVddnClk, 2U); + CLOCK_AttachClk(kMAIN_PLL_PFD3_to_COMMON_VDDN); /* Switch to 250MHZ */ + + /* Configure Audio PLL clock source. */ + CLOCK_InitAudioPll(&g_audioPllConfig_clock_init); /* 532.48MHZ */ + CLOCK_InitAudioPfd(kCLOCK_Pfd1, 24U); /* 399.36MHz */ + CLOCK_InitAudioPfd(kCLOCK_Pfd3, 26U); /* Enable Audio PLL PFD3 clock to 368.64MHZ */ + CLOCK_EnableAudioPllPfdClkForDomain(kCLOCK_Pfd1, kCLOCK_AllDomainEnable); + CLOCK_EnableAudioPllPfdClkForDomain(kCLOCK_Pfd3, kCLOCK_AllDomainEnable); + +#if CONFIG_FLASH_MCUX_XSPI_XIP + /* Call function xspi_setup_clock() to set user configured clock for XSPI. */ + xspi_setup_clock(XSPI0, 3U, 1U); /* Main PLL PDF1 DIV1. */ +#endif /* CONFIG_FLASH_MCUX_XSPI_XIP */ + +#elif CONFIG_SOC_MIMXRT798S_CM33_CPU1 + /* Power up OSC in case it's not enabled. */ + POWER_DisablePD(kPDRUNCFG_PD_SYSXTAL); + /* Enable system OSC */ + CLOCK_EnableSysOscClk(true, true, SYSOSC_SETTLING_US); + /* Sets external XTAL OSC freq */ + CLOCK_SetXtalFreq(XTAL_SYS_CLK_HZ); + + CLOCK_AttachClk(kFRO1_DIV3_to_SENSE_BASE); + CLOCK_SetClkDiv(kCLOCK_DivSenseMainClk, 1); + CLOCK_AttachClk(kSENSE_BASE_to_SENSE_MAIN); + + POWER_DisablePD(kPDRUNCFG_GATE_FRO2); + CLOCK_EnableFroClkFreq(FRO2, 300000000U, kCLOCK_FroAllOutEn); + + CLOCK_EnableFro2ClkForDomain(kCLOCK_AllDomainEnable); + + CLOCK_AttachClk(kFRO2_DIV3_to_SENSE_BASE); + CLOCK_SetClkDiv(kCLOCK_DivSenseMainClk, 1); + CLOCK_AttachClk(kSENSE_BASE_to_SENSE_MAIN); +#endif /* CONFIG_SOC_MIMXRT798S_CM33_CPU0 */ + + BOARD_InitAHBSC(); + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(edma0), okay) + CLOCK_EnableClock(kCLOCK_Dma0); + RESET_ClearPeripheralReset(kDMA0_RST_SHIFT_RSTn); + edma_enable_all_request(0); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(edma1), okay) + CLOCK_EnableClock(kCLOCK_Dma1); + RESET_ClearPeripheralReset(kDMA1_RST_SHIFT_RSTn); + edma_enable_all_request(1); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(iocon), okay) + RESET_ClearPeripheralReset(kIOPCTL0_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_Iopctl0); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(iocon1), okay) + RESET_ClearPeripheralReset(kIOPCTL1_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_Iopctl1); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(iocon2), okay) + RESET_ClearPeripheralReset(kIOPCTL2_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_Iopctl2); +#endif + +#ifdef CONFIG_BOARD_MIMXRT700_EVK_MIMXRT798S_CM33_CPU0 + CLOCK_AttachClk(kOSC_CLK_to_FCCLK0); + CLOCK_SetClkDiv(kCLOCK_DivFcclk0Clk, 1U); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm0), okay) + SET_UP_FLEXCOMM_CLOCK(0); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm1), okay) + SET_UP_FLEXCOMM_CLOCK(1); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm2), okay) + SET_UP_FLEXCOMM_CLOCK(2); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm3), okay) + SET_UP_FLEXCOMM_CLOCK(3); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm4), okay) + SET_UP_FLEXCOMM_CLOCK(4); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm5), okay) + SET_UP_FLEXCOMM_CLOCK(5); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm6), okay) + SET_UP_FLEXCOMM_CLOCK(6); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm7), okay) + SET_UP_FLEXCOMM_CLOCK(7); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm8), okay) + SET_UP_FLEXCOMM_CLOCK(8); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm9), okay) + SET_UP_FLEXCOMM_CLOCK(9); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm10), okay) + SET_UP_FLEXCOMM_CLOCK(10); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm11), okay) + SET_UP_FLEXCOMM_CLOCK(11); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm12), okay) + SET_UP_FLEXCOMM_CLOCK(12); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm13), okay) + SET_UP_FLEXCOMM_CLOCK(13); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi14), okay) + CLOCK_AttachClk(kFRO1_DIV1_to_LPSPI14); + CLOCK_SetClkDiv(kCLOCK_DivLpspi14Clk, 3U); + CLOCK_EnableClock(kCLOCK_LPSpi14); + RESET_ClearPeripheralReset(kLPSPI14_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpi2c15), okay) + CLOCK_EnableClock(kCLOCK_LPI2c15); + RESET_ClearPeripheralReset(kLPI2C15_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi16), okay) + CLOCK_AttachClk(kFRO0_DIV1_to_LPSPI16); + CLOCK_SetClkDiv(kCLOCK_DivLpspi16Clk, 1U); + CLOCK_EnableClock(kCLOCK_LPSpi16); + RESET_ClearPeripheralReset(kLPSPI16_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm17), okay) + CLOCK_AttachClk(kSENSE_BASE_to_FLEXCOMM17); + CLOCK_SetClkDiv(kCLOCK_DivLPFlexComm17Clk, 4U); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm18), okay) + CLOCK_AttachClk(kSENSE_BASE_to_FLEXCOMM18); + CLOCK_SetClkDiv(kCLOCK_DivLPFlexComm18Clk, 4U); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm19), okay) + CLOCK_AttachClk(kSENSE_BASE_to_FLEXCOMM19); + CLOCK_SetClkDiv(kCLOCK_DivLPFlexComm19Clk, 4U); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexcomm20), okay) + CLOCK_AttachClk(kSENSE_BASE_to_FLEXCOMM20); + CLOCK_SetClkDiv(kCLOCK_DivLPFlexComm20Clk, 4U); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(flexio), okay) + CLOCK_AttachClk(kFRO0_DIV1_to_FLEXIO); + CLOCK_SetClkDiv(kCLOCK_DivFlexioClk, 1U); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio0), okay) + CLOCK_EnableClock(kCLOCK_Gpio0); + RESET_ClearPeripheralReset(kGPIO0_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) + CLOCK_EnableClock(kCLOCK_Gpio1); + RESET_ClearPeripheralReset(kGPIO1_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio2), okay) + CLOCK_EnableClock(kCLOCK_Gpio2); + RESET_ClearPeripheralReset(kGPIO2_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio3), okay) + CLOCK_EnableClock(kCLOCK_Gpio3); + RESET_ClearPeripheralReset(kGPIO3_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio4), okay) + CLOCK_EnableClock(kCLOCK_Gpio4); + RESET_ClearPeripheralReset(kGPIO4_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio5), okay) + CLOCK_EnableClock(kCLOCK_Gpio5); + RESET_ClearPeripheralReset(kGPIO5_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio6), okay) + CLOCK_EnableClock(kCLOCK_Gpio6); + RESET_ClearPeripheralReset(kGPIO6_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio7), okay) + CLOCK_EnableClock(kCLOCK_Gpio7); + RESET_ClearPeripheralReset(kGPIO7_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio8), okay) + CLOCK_EnableClock(kCLOCK_Gpio8); + RESET_ClearPeripheralReset(kGPIO8_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio9), okay) + CLOCK_EnableClock(kCLOCK_Gpio9); + RESET_ClearPeripheralReset(kGPIO9_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio10), okay) + CLOCK_EnableClock(kCLOCK_Gpio10); + RESET_ClearPeripheralReset(kGPIO10_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer0), okay) + SET_UP_CTIMER_CLOCK(0); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer1), okay) + SET_UP_CTIMER_CLOCK(1); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer2), okay) + SET_UP_CTIMER_CLOCK(2); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer3), okay) + SET_UP_CTIMER_CLOCK(3); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer4), okay) + SET_UP_CTIMER_CLOCK(4); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer5), okay) + SET_UP_CTIMER_CLOCK(5); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer6), okay) + SET_UP_CTIMER_CLOCK(6); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ctimer7), okay) + SET_UP_CTIMER_CLOCK(7); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpadc0), okay) + CLOCK_AttachClk(kFRO1_DIV1_to_SENSE_MAIN); + CLOCK_AttachClk(kSENSE_BASE_to_ADC); + CLOCK_SetClkDiv(kCLOCK_DivAdcClk, 1U); +#endif + +#if (DT_NODE_HAS_STATUS(DT_NODELABEL(os_timer_cpu0), okay) || \ + DT_NODE_HAS_STATUS(DT_NODELABEL(os_timer_cpu1), okay)) + CLOCK_AttachClk(kLPOSC_to_OSTIMER); + CLOCK_SetClkDiv(kCLOCK_DivOstimerClk, 1U); +#endif +} + +static void GlikeyWriteEnable(GLIKEY_Type *base, uint8_t idx) +{ + (void)GLIKEY_SyncReset(base); + + (void)GLIKEY_StartEnable(base, idx); + (void)GLIKEY_ContinueEnable(base, GLIKEY_CODEWORD_STEP1); + (void)GLIKEY_ContinueEnable(base, GLIKEY_CODEWORD_STEP2); + (void)GLIKEY_ContinueEnable(base, GLIKEY_CODEWORD_STEP3); + (void)GLIKEY_ContinueEnable(base, GLIKEY_CODEWORD_STEP_EN); +} + +static void GlikeyClearConfig(GLIKEY_Type *base) +{ + (void)GLIKEY_SyncReset(base); +} + +/* Disable the secure check for AHBSC and enable periperhals/sram access for masters */ +static void BOARD_InitAHBSC(void) +{ +#if defined(CONFIG_SOC_MIMXRT798S_CM33_CPU0) + GlikeyWriteEnable(GLIKEY0, 1U); + AHBSC0->MISC_CTRL_DP_REG = 0x000086aa; + /* AHBSC0 MISC_CTRL_REG, disable Privilege & Secure checking. */ + AHBSC0->MISC_CTRL_REG = 0x000086aa; + + GlikeyWriteEnable(GLIKEY0, 7U); + /* Enable arbiter0 accessing SRAM */ + AHBSC0->COMPUTE_ARB0RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC0->SENSE_ARB0RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC0->MEDIA_ARB0RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC0->NPU_ARB0RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC0->HIFI4_ARB0RAM_ACCESS_ENABLE = 0x3FFFFFFF; +#endif + + GlikeyWriteEnable(GLIKEY1, 1U); + AHBSC3->MISC_CTRL_DP_REG = 0x000086aa; + /* AHBSC3 MISC_CTRL_REG, disable Privilege & Secure checking.*/ + AHBSC3->MISC_CTRL_REG = 0x000086aa; + + GlikeyWriteEnable(GLIKEY1, 9U); + /* Enable arbiter1 accessing SRAM */ + AHBSC3->COMPUTE_ARB1RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC3->SENSE_ARB1RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC3->MEDIA_ARB1RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC3->NPU_ARB1RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC3->HIFI4_ARB1RAM_ACCESS_ENABLE = 0x3FFFFFFF; + AHBSC3->HIFI1_ARB1RAM_ACCESS_ENABLE = 0x3FFFFFFF; + + GlikeyWriteEnable(GLIKEY1, 8U); + /* Access enable for COMPUTE domain masters to common APB peripherals.*/ + AHBSC3->COMPUTE_APB_PERIPHERAL_ACCESS_ENABLE = 0xffffffff; + AHBSC3->SENSE_APB_PERIPHERAL_ACCESS_ENABLE = 0xffffffff; + GlikeyWriteEnable(GLIKEY1, 7U); + AHBSC3->COMPUTE_AIPS_PERIPHERAL_ACCESS_ENABLE = 0xffffffff; + AHBSC3->SENSE_AIPS_PERIPHERAL_ACCESS_ENABLE = 0xffffffff; + + GlikeyWriteEnable(GLIKEY2, 1U); + /*Disable secure and secure privilege checking. */ + AHBSC4->MISC_CTRL_DP_REG = 0x000086aa; + AHBSC4->MISC_CTRL_REG = 0x000086aa; + +#if defined(CONFIG_SOC_MIMXRT798S_CM33_CPU0) + GlikeyClearConfig(GLIKEY0); +#endif + GlikeyClearConfig(GLIKEY1); + GlikeyClearConfig(GLIKEY2); +} + +#if CONFIG_DT_HAS_NXP_MCUX_EDMA_ENABLED +static void edma_enable_all_request(uint8_t instance) +{ + uint32_t *reg; + + for (uint8_t idx = 0; idx < EN_NUM; idx++) { + reg = EDMA_EN_REG(instance, idx); + *reg |= 0xFFFFFFFF; + } +} +#endif diff --git a/boards/nxp/mimxrt700_evk/board.cmake b/boards/nxp/mimxrt700_evk/board.cmake new file mode 100644 index 0000000000000..2ea53e1674115 --- /dev/null +++ b/boards/nxp/mimxrt700_evk/board.cmake @@ -0,0 +1,21 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +if(CONFIG_SOC_MIMXRT798S_CM33_CPU0) + board_runner_args(jlink "--device=MIMXRT798S_M33_0" "--reset-after-load") + board_runner_args(linkserver "--device=MIMXRT798S:MIMXRT700-EVK") + board_runner_args(linkserver "--override=/device/memory/4=") + board_runner_args(linkserver "--core=cm33_core0") +elseif(CONFIG_SOC_MIMXRT798S_CM33_CPU1) + board_runner_args(jlink "--device=MIMXRT798S_M33_1") + board_runner_args(linkserver "--device=MIMXRT798S:MIMXRT700-EVK") + board_runner_args(linkserver "--core=cm33_core1") +else() + message(FATAL_ERROR "Requested core is not supported") +endif() + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) diff --git a/boards/nxp/mimxrt700_evk/board.yml b/boards/nxp/mimxrt700_evk/board.yml new file mode 100644 index 0000000000000..e4aa90748f9a1 --- /dev/null +++ b/boards/nxp/mimxrt700_evk/board.yml @@ -0,0 +1,6 @@ +board: + name: mimxrt700_evk + full_name: MIMXRT700-EVK + vendor: nxp + socs: + - name: mimxrt798s diff --git a/boards/nxp/mimxrt700_evk/doc/index.rst b/boards/nxp/mimxrt700_evk/doc/index.rst new file mode 100644 index 0000000000000..52ace6399aefb --- /dev/null +++ b/boards/nxp/mimxrt700_evk/doc/index.rst @@ -0,0 +1,218 @@ +.. zephyr:board:: mimxrt700_evk + +Overview +******** + +The new i.MX RT700 CPU architecture is composed of a high-performance main compute subsystem, +a secondary “always-on” sense-compute subsystem and specialized coprocessors. + +The main compute subsystem uses a 325 MHz capable ArmÂŽ CortexÂŽ-M33 (CM33). +Similar to the i.MX RT600 crossover MCU, the i.MX RT700 includes a Cadence TensilicaÂŽ HiFi 4 DSP. +The HiFi 4 is a high performance DSP core based upon a Very Long Instruction Word (VLIW) architecture, +which is capable of processing up to eight 32x16 MACs per instruction cycle. It can be used for offloading +high-performance numerical tasks such as audio and image processing and supports both fixed-point and +floating-point operations. + +Hardware +******** + +- Main Compute Subsystem: + + - Arm Cortex-M33 up to 325 MHz + - HiFi 4 DSP up to 325 MHz + - eIQ Neutron NPU up to 325 MHz +- Sense Compute Subsystem: + + - Arm Cortex-M33 up to 250 MHz + - HiFi 1 DSP up to 250 MHz +- 7.5 MB on-chip SRAM +- Three xSPI interfaces for off-chip memory expansion, supporting up to 16b wide external memories up to 250 MHz DDR +- eUSB support with integrated PHY +- Two SD/eMMC memory card interfaces—one supporting eMMC 5.0 with HS400/DDR operation +- USB high-speed host/device controller with on-chip PHY +- A digital microphone interface supporting up to 8 channels +- Serial peripherals (UART/I²C/I3C/SPI/HSPI/SAI) +- 2.5D GPU with vector graphics acceleration and frame buffer compression +- EZH-V using RISC-V core with additional SIMD/DSP instructions +- Full openVG 1.1 support +- Up to 720p@60FPS from on-chip SRAM +- LCD Interface + MIPI DSI +- Integrated JPEG and PNG support +- CSI 8/10/16-bit parallel (via FlexIO) + +For more information about the MIMXRT798 SoC and MIMXRT700-EVK board, see +these references: + +- `i.MX RT700 Website`_ + +Supported Features +================== + +NXP considers the MIMXRT700-EVK as a superset board for the i.MX RT7xx +family of MCUs. This board is a focus for NXP's Full Platform Support for +Zephyr, to better enable the entire RT7xx family. NXP prioritizes enabling +this board with new support for Zephyr features. The ``mimxrt700_evk/mimxrt798s +/cm33_cpu0`` and ``mimxrt700_evk/mimxrt798s/cm33_cpu1`` board targets support +the hardware features below. + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| CTIMER | on-chip | counter | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| IOCON | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ +| MRT | on-chip | counter | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| OS_TIMER | on-chip | os timer | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: + + :zephyr_file:`boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0_defconfig` + :zephyr_file:`boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1_defconfig` + +Other hardware features are not currently supported by the port. + +Connections and IOs +=================== + +The MIMXRT798 SoC has IOCON registers, which can be used to configure the +functionality of a pin. + ++---------+-----------------+----------------------------+ +| Name | Function | Usage | ++=========+=================+============================+ +| PIO0_6 | I2C | I2C SDA | ++---------+-----------------+----------------------------+ +| PIO0_7 | I2C | I2C SCL | ++---------+-----------------+----------------------------+ +| PIO0_31 | UART0 | UART RX | ++---------+-----------------+----------------------------+ +| PIO1_0 | UART0 | UART TX | ++---------+-----------------+----------------------------+ +| PIO0_18 | GPIO | GREEN LED | ++---------+-----------------+----------------------------+ +| PIO0_9 | GPIO | SW5 | ++---------+-----------------+----------------------------+ +| PIO8_14 | UART19 | UART TX | ++---------+-----------------+----------------------------+ +| PIO8_15 | UART19 | UART RX | ++---------+-----------------+----------------------------+ +| PIO3_0 | SPI | SPI MOSI | ++---------+-----------------+----------------------------+ +| PIO3_1 | SPI | SPI SCK | ++---------+-----------------+----------------------------+ +| PIO3_2 | SPI | SPI MISO | ++---------+-----------------+----------------------------+ +| PIO3_3 | SPI | SPI SSEL | ++---------+-----------------+----------------------------+ + +System Clock +============ + +The MIMXRT700 EVK is configured to use the Systick +as a source for the system clock. + +Programming and Debugging +************************* + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Debug Probe +========================= + +A debug probe is used for both flashing and debugging the board. This board is +configured by default to use the MCU-Link CMSIS-DAP Onboard Debug Probe. + +.. tabs:: + .. group-tab:: LinkServer + + + 1. Install the :ref:`linkserver-debug-host-tools` and make sure they are in your search path. + 2. To put the board in ``DFU mode`` to program the firmware, short jumper J20. + 3. To update the debug firmware, please follow the instructions on `MIMXRT700-EVK Debug Firmware` + + .. group-tab:: JLink External + + + 1. Install the :ref:`jlink-debug-host-tools` and make sure they are in your search path. + + 2. To disconnect the SWD signals from onboard debug circuit, **short** jumpers JP18. + + 3. Connect the J-Link probe to J18 20-pin header. + + See :ref:`jlink-external-debug-probe` for more information. + +Configuring a Console +===================== + +Connect a USB cable from your PC to J54, and use the serial terminal of your choice +(minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing +======== + +Here is an example for the :zephyr:code-sample:`hello_world` application. This example uses the +:ref:`jlink-debug-host-tools` as default. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt700_evk/mimxrt798s/cm33_cpu0 + :goals: flash + +Open a serial terminal, reset the board (press the RESET button), and you should +see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS v3.7.0 *** + Hello World! mimxrt700_evk/mimxrt798s/cm33_cpu0 + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. This example uses the +:ref:`jlink-debug-host-tools` as default. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt700_evk/mimxrt798s/cm33_cpu0 + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS v3.7.0 *** + Hello World! mimxrt700_evk/mimxrt798s/cm33_cpu0 + +.. _i.MX RT700 Website: + https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/i-mx-rt-crossover-mcus/i-mx-rt700-crossover-mcu-with-arm-cortex-m33-npu-dsp-and-gpu-cores:i.MX-RT700 + +.. _MIMXRT700-EVK Debug Firmware: + https://www.nxp.com/docs/en/application-note/AN13206.pdf diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk-pinctrl.dtsi b/boards/nxp/mimxrt700_evk/mimxrt700_evk-pinctrl.dtsi new file mode 100644 index 0000000000000..ccf13860d3d5c --- /dev/null +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk-pinctrl.dtsi @@ -0,0 +1,78 @@ +/* + * Copyright 2024-2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + pinmux_flexcomm0_lpuart: pinmux_flexcomm0_lpuart { + group0 { + pinmux = ; + input-enable; + slew-rate = "normal"; + drive-strength = "normal"; + }; + group1 { + pinmux = ; + slew-rate = "normal"; + drive-strength = "normal"; + }; + }; + + pinmux_flexcomm8_i2c: pinmux_flexcomm8_i2c { + group0 { + pinmux = , + ; + bias-pull-up; + input-enable; + slew-rate = "normal"; + drive-strength = "high"; + drive-open-drain; + }; + }; + + pinmux_flexcomm19_lpuart: pinmux_flexcomm19_lpuart { + group0 { + pinmux = ; + input-enable; + slew-rate = "normal"; + drive-strength = "normal"; + }; + group1 { + pinmux = ; + slew-rate = "normal"; + drive-strength = "normal"; + }; + }; + + pinmux_lpspi14: pinmux_lpspi14 { + group0 { + pinmux = , + , + , + ; + slew-rate = "normal"; + drive-strength = "normal"; + input-enable; + }; + }; + + flexio_pwm_default: flexio_pwm_default { + group0 { + pinmux = ; + drive-strength = "normal"; + slew-rate = "slow"; + }; + }; + + pinmux_lpadc0: pinmux_lpadc0 { + group0 { + pinmux = , + ; + slew-rate = "normal"; + drive-strength = "normal"; + nxp,analog-mode; + }; + }; +}; diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts new file mode 100644 index 0000000000000..1e4e0ee72e3ce --- /dev/null +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts @@ -0,0 +1,150 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include "mimxrt700_evk-pinctrl.dtsi" + +/ { + model = "NXP MIMXRT700-EVK board"; + compatible = "nxp,mimxrt798s"; + + aliases { + led0 = &green_led; + led1 = &blue_led; + sw0 = &user_button_1; + sw1 = &user_button_2; + }; + + chosen { + zephyr,flash-controller = &mx25um51345g; + zephyr,flash = &mx25um51345g; + zephyr,sram = &sram0; + zephyr,console = &flexcomm0_lpuart0; + zephyr,shell-uart = &flexcomm0_lpuart0; + }; + + leds { + compatible = "gpio-leds"; + green_led: led_0 { + gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>; + label = "User LED_GREEN"; + }; + blue_led: led_1 { + gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; + label = "User LED_BLUE"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_1: button_0 { + label = "User SW5"; + gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + user_button_2: button_1 { + label = "User SW7"; + gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; +}; + +&ctimer0 { + status = "okay"; +}; + +&edma0 { + status = "okay"; +}; + +/* + * RT700-EVK board cm33_cpu0 uses OS timer as the kernel timer + * In case we need to switch to SYSTICK timer, then + * replace &os_timer with &systick + */ +&os_timer_cpu0 { + status = "okay"; + wakeup-source; +}; + +&flexcomm0{ + status = "okay"; +}; + +&flexcomm0_lpuart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm0_lpuart>; + pinctrl-names = "default"; +}; + +&lpspi14 { + status = "okay"; + /* DMA channels 0 and 1, muxed to LPSPI14 RX and TX */ + dmas = <&edma0 0 73>, <&edma0 1 74>; + dma-names = "rx", "tx"; + pinctrl-0 = <&pinmux_lpspi14>; + pinctrl-names = "default"; +}; + +&flexcomm8{ + status = "okay"; +}; + +&flexcomm8_lpi2c8 { + pinctrl-0 = <&pinmux_flexcomm8_i2c>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&green_led { + status = "okay"; +}; + +&lpadc0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpadc0>; + pinctrl-names = "default"; +}; + +&blue_led { + status = "okay"; +}; + +&mrt0_channel0 { + status = "okay"; +}; + +&xspi0 { + status = "okay"; + + mx25um51345g: mx25um51345g@0 { + compatible = "nxp,xspi-mx25um51345g"; + /* MX25UM51245G is 64MB, 512MBit flash part */ + size = ; + reg = <0>; + spi-max-frequency = <200000000>; + status = "okay"; + jedec-id = [c2 81 3a]; + erase-block-size = <4096>; + write-block-size = <2>; + }; +}; + +p3t1755dp_ard_i2c_interface: &flexcomm8_lpi2c8 {}; diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml new file mode 100644 index 0000000000000..74f4140992ee3 --- /dev/null +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml @@ -0,0 +1,23 @@ +# +# Copyright 2024-2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: mimxrt700_evk/mimxrt798s/cm33_cpu0 +name: NXP MIMXRT700-EVK (CM33_CPU0) +type: mcu +arch: arm +ram: 512 +flash: 65536 +toolchain: + - zephyr + - gnuarmemb +supported: + - counter + - gpio + - i2c + - uart + - spi + - adc +vendor: nxp diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0_defconfig b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0_defconfig new file mode 100644 index 0000000000000..9c7cb03806289 --- /dev/null +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0_defconfig @@ -0,0 +1,18 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GPIO=y + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_BOARD_EARLY_INIT_HOOK=y + +# Enable TrustZone-M +CONFIG_TRUSTED_EXECUTION_SECURE=y diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.dts b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.dts new file mode 100644 index 0000000000000..92ecdc41aafb0 --- /dev/null +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.dts @@ -0,0 +1,82 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include "mimxrt700_evk-pinctrl.dtsi" + +/ { + model = "NXP MIMXRT700-EVK board"; + compatible = "nxp,mimxrt798s"; + + aliases { + led0 = &red_led; + sw0 = &user_button_1; + }; + + chosen { + zephyr,flash = &sram_code; + zephyr,sram = &sram0; + zephyr,console = &flexcomm19_lpuart19; + zephyr,shell-uart = &flexcomm19_lpuart19; + }; + + leds { + compatible = "gpio-leds"; + red_led: led_0 { + status = "okay"; + gpios = <&gpio8 6 GPIO_ACTIVE_HIGH>; + label = "User LED_RED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_1: button_0 { + label = "User SW6"; + gpios = <&gpio8 5 (GPIO_ACTIVE_LOW)>; + zephyr,code = ; + status = "okay"; + }; + }; +}; + +&ctimer5 { + status = "okay"; +}; + +&lpadc0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpadc0>; + pinctrl-names = "default"; +}; + +/* + * RT700-EVK board cm33_cpu1 uses OS timer as the kernel timer + * In case we need to switch to SYSTICK timer, then + * replace &os_timer with &systick + */ +&os_timer_cpu1 { + status = "okay"; + wakeup-source; +}; + +&flexcomm19{ + status = "okay"; +}; + +&flexcomm19_lpuart19 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_flexcomm19_lpuart>; + pinctrl-names = "default"; +}; + +&gpio8 { + status = "okay"; +}; diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml new file mode 100644 index 0000000000000..38c45ae9027ed --- /dev/null +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml @@ -0,0 +1,21 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: mimxrt700_evk/mimxrt798s/cm33_cpu1 +name: NXP MIMXRT700-EVK (CM33_CPU1) +type: mcu +arch: arm +ram: 256 +flash: 512 +toolchain: + - zephyr + - gnuarmemb +supported: + - counter + - gpio + - uart + - adc +vendor: nxp diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1_defconfig b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1_defconfig new file mode 100644 index 0000000000000..a7a0f73244a15 --- /dev/null +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1_defconfig @@ -0,0 +1,19 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GPIO=y + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_BOARD_EARLY_INIT_HOOK=y + +# Enable TrustZone-M +CONFIG_TRUSTED_EXECUTION_SECURE=y +CONFIG_NXP_IMXRT_BOOT_HEADER=n diff --git a/boards/nxp/mr_canhubk3/mr_canhubk3.dts b/boards/nxp/mr_canhubk3/mr_canhubk3.dts index 6759aaf49fba8..c8df4985fbfd2 100644 --- a/boards/nxp/mr_canhubk3/mr_canhubk3.dts +++ b/boards/nxp/mr_canhubk3/mr_canhubk3.dts @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -344,6 +344,8 @@ readoc = "1-4-4"; writeoc = "1-4-4"; has-32k-erase; + max-program-buffer-size = <256>; + write-block-size = <1>; status = "okay"; partitions { @@ -499,7 +501,6 @@ emios0_bus_a { mode = "MCB_UP_COUNTER"; prescaler = <16>; - period = <1000>; status = "okay"; }; }; @@ -513,63 +514,43 @@ pwm_0 { channel = <0>; pwm-mode = "OPWFMB"; - period = <65535>; - duty-cycle = <0>; prescaler = <8>; - polarity = "ACTIVE_HIGH"; }; pwm_1 { channel = <1>; pwm-mode = "OPWFMB"; - period = <65535>; - duty-cycle = <0>; prescaler = <8>; - polarity = "ACTIVE_HIGH"; }; pwm_2 { channel = <2>; pwm-mode = "OPWFMB"; - period = <65535>; - duty-cycle = <0>; prescaler = <8>; - polarity = "ACTIVE_HIGH"; }; pwm_3 { channel = <3>; pwm-mode = "OPWFMB"; - period = <65535>; - duty-cycle = <0>; prescaler = <8>; - polarity = "ACTIVE_HIGH"; }; pwm_4 { channel = <4>; pwm-mode = "OPWFMB"; - period = <65535>; - duty-cycle = <0>; prescaler = <8>; - polarity = "ACTIVE_HIGH"; }; pwm_5 { channel = <5>; pwm-mode = "OPWFMB"; - period = <65535>; - duty-cycle = <0>; prescaler = <8>; - polarity = "ACTIVE_HIGH"; }; rgb_red { channel = <19>; master-bus = <&emios0_bus_a>; - duty-cycle = <0>; pwm-mode = "OPWMB"; - polarity = "ACTIVE_LOW"; }; }; }; @@ -586,14 +567,12 @@ emios1_bus_a { prescaler = <16>; mode = "MCB_UP_COUNTER"; - period = <1000>; status = "okay"; }; emios1_bus_f { prescaler = <16>; mode = "MCB_UP_COUNTER"; - period = <1000>; status = "okay"; }; }; @@ -606,17 +585,13 @@ rgb_green { channel = <10>; master-bus = <&emios1_bus_a>; - duty-cycle = <0>; pwm-mode = "OPWMB"; - polarity = "ACTIVE_LOW"; }; rgb_blue { channel = <5>; master-bus = <&emios1_bus_f>; - duty-cycle = <0>; pwm-mode = "OPWMB"; - polarity = "ACTIVE_LOW"; }; }; }; diff --git a/boards/nxp/rd_rw612_bga/Kconfig.defconfig b/boards/nxp/rd_rw612_bga/Kconfig.defconfig index 6f644448c7f91..a0a6022de038c 100644 --- a/boards/nxp/rd_rw612_bga/Kconfig.defconfig +++ b/boards/nxp/rd_rw612_bga/Kconfig.defconfig @@ -30,10 +30,6 @@ config LV_Z_FLUSH_THREAD endif # LVGL -# Enable interrupt support when using FT5336 driver -config INPUT_FT5336_INTERRUPT - default y if INPUT - if DT_HAS_NXP_ENET_MAC_ENABLED && NETWORKING config NET_L2_ETHERNET diff --git a/boards/nxp/rd_rw612_bga/doc/index.rst b/boards/nxp/rd_rw612_bga/doc/index.rst index c1ba78d3f64f0..340dcccbd01b2 100644 --- a/boards/nxp/rd_rw612_bga/doc/index.rst +++ b/boards/nxp/rd_rw612_bga/doc/index.rst @@ -73,6 +73,8 @@ Supported Features +-----------+------------+-----------------------------------+ | ENET | on-chip | ethernet | +-----------+------------+-----------------------------------+ +| Wi-Fi | on-chip | Wi-Fi | ++-----------+------------+-----------------------------------+ The default configuration can be found in the defconfig file: @@ -136,7 +138,7 @@ display sample can be built for the module like so: Fetch Binary Blobs ****************** -To support Bluetooth, rd_rw612_bga requires fetching binary blobs, which can be +To support Bluetooth or Wi-Fi, rd_rw612_bga requires fetching binary blobs, which can be achieved by running the following command: .. code-block:: console @@ -214,6 +216,16 @@ rd_rw612_bga platform supports the monolithic feature. The required binary blob ``/modules/hal/nxp/zephyr/blobs/rw61x_sb_ble_a2.bin`` will be linked with the application image directly, forming one single monolithic image. +Wi-Fi +***** + +Wi-Fi functionality requires to fetch binary blobs, so make sure to follow +the ``Fetch Binary Blobs`` section first. + +rd_rw612_bga platform supports the monolithic feature. The required binary blob +``/modules/hal/nxp/zephyr/blobs/rw61x_sb_wifi_a2.bin`` will be linked +with the application image directly, forming one single monolithic image. + Board variants ************** diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi b/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi index 21e7a1387d5ce..8d8bd71cd61ae 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi @@ -294,12 +294,12 @@ nxp_8080_touch_panel_i2c: &arduino_i2c { status = "disabled"; }; -&hci { +&pin1 { status = "okay"; - wakeup-source; + wakeup-level = "low"; }; -&pin1 { +&nbu { status = "okay"; - wakeup-level = "low"; + wakeup-source; }; diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml b/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml index 1971325463b6f..6f319e7215d88 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 960 flash: 65536 supported: diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml index 19d26ea8162f0..dbdff161607e5 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 960 flash: 65536 supported: diff --git a/boards/nxp/rddrone_fmuk66/rddrone_fmuk66.dts b/boards/nxp/rddrone_fmuk66/rddrone_fmuk66.dts index 127d6ffb72416..b2b3fefa4fed5 100644 --- a/boards/nxp/rddrone_fmuk66/rddrone_fmuk66.dts +++ b/boards/nxp/rddrone_fmuk66/rddrone_fmuk66.dts @@ -142,7 +142,7 @@ /* PWM header is powered by FlexTimer 0 for channels 1 to 4 */ &ftm0 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm0_default>; pinctrl-names = "default"; @@ -153,7 +153,7 @@ /* RGB LED powered by FlexTimer 3, and PWM headers for channel 5 and 6 */ &ftm3 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm3_default>; pinctrl-names = "default"; diff --git a/boards/nxp/s32z2xxdc2/doc/index.rst b/boards/nxp/s32z2xxdc2/doc/index.rst index 9cb0972bf8fc7..db6b713f47c24 100644 --- a/boards/nxp/s32z2xxdc2/doc/index.rst +++ b/boards/nxp/s32z2xxdc2/doc/index.rst @@ -60,6 +60,10 @@ The boards support the following hardware features: +-----------+------------+-------------------------------------+ | DSPI | on-chip | spi | +-----------+------------+-------------------------------------+ +| eMIOS | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| QSPI | on-chip | flash | ++-----------+------------+-------------------------------------+ Other hardware features are not currently supported by the port. @@ -170,6 +174,12 @@ EDMA The EDMA modules feature four EDMA3 instances: Instance 0 with 32 channels, and instances 1, 4, and 5, each with 16 channels. +External Flash +============== + +The on-board S26HS512T 512M-bit HyperFlash memory is connected to the QSPI controller +port A1. This board configuration selects it as the default flash controller. + Programming and Debugging ************************* diff --git a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270.dtsi b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270.dtsi index 65f04794ce3de..87befae0db2e7 100644 --- a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270.dtsi +++ b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270.dtsi @@ -5,6 +5,7 @@ */ #include "s32z2xxdc2_s32z270_pinctrl.dtsi" +#include &swt0 { status = "okay"; @@ -58,3 +59,69 @@ &sar_adc1 { vref-mv = <1800>; }; + +&qspi0 { + pinctrl-0 = <&qspi0_default>; + pinctrl-names = "default"; + data-rate = "DDR"; + column-space = <3>; + word-addressable; + hold-time-2x; + a-dll-freq-enable; + a-dll-ref-counter = <2>; + a-dll-resolution = <2>; + a-dll-coarse-delay = <2>; + a-dll-fine-delay = <2>; + a-dll-mode = "AUTO UPDATE"; + a-rx-clock-source = "EXTERNAL DQS"; + ahb-buffers-masters = <0 1 2 3>; + ahb-buffers-sizes = <256 256 256 256>; + ahb-buffers-all-masters; + status = "okay"; + + sfp_mdad { + compatible = "nxp,s32-qspi-sfp-mdad"; + + mdad_0: mdad_0 { + domain-id = <0>; + secure-attribute = ; + }; + }; + + sfp_frad { + compatible = "nxp,s32-qspi-sfp-frad"; + #address-cells = <1>; + #size-cells = <1>; + + frad_0: frad@0 { + reg = <0x0 DT_SIZE_M(512)>; + master-domain-acp-policy = ; + }; + }; + + s26hs512t: s26hs512t@0 { + compatible = "nxp,s32-qspi-hyperflash"; + reg = <0>; + jedec-id = [00 34 00 7b 00 1a 00 0f 00 90]; + device-id-word-addr = <0x800>; + size = ; + write-block-size = <2>; + read-latency-cycles = <16>; + max-program-buffer-size = <256>; + vcc-mv = <1800>; + drive-strength-ohm = <27>; + ppw-sectors-addr-mapping = "LOW"; + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0x0 0x10000>; + }; + }; + }; +}; diff --git a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_pinctrl.dtsi b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_pinctrl.dtsi index 05b92b089317a..7433ba00e40da 100644 --- a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_pinctrl.dtsi +++ b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_pinctrl.dtsi @@ -127,4 +127,25 @@ drive-open-drain; }; }; + + qspi0_default: qspi0_default { + group1 { + pinmux = , , + , , + , , + , , + ; + output-enable; + input-enable; + }; + group2 { + pinmux = , , + , ; + output-enable; + }; + group3 { + pinmux = ; + input-enable; + }; + }; }; diff --git a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0.dts b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0.dts index da6b964561420..e38e8b51792ea 100644 --- a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0.dts +++ b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0.dts @@ -16,6 +16,7 @@ zephyr,sram = &dram0; zephyr,flash = &cram0; zephyr,canbus = &canxl0; + zephyr,flash-controller = &s26hs512t; }; aliases { diff --git a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0.yaml b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0.yaml index 070c33e6bfd32..60b258ad5a166 100644 --- a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0.yaml +++ b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0.yaml @@ -19,4 +19,5 @@ supported: - adc - i2c - dma + - pwm vendor: nxp diff --git a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0_D.yaml b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0_D.yaml index 9d692144a76c2..c35cc47699bd0 100644 --- a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0_D.yaml +++ b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu0_D.yaml @@ -19,4 +19,5 @@ supported: - adc - i2c - dma + - pwm vendor: nxp diff --git a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1.dts b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1.dts index 286fd8d094c87..f8792f880f353 100644 --- a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1.dts +++ b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1.dts @@ -16,6 +16,7 @@ zephyr,sram = &dram1; zephyr,flash = &cram1; zephyr,canbus = &flexcan0; + zephyr,flash-controller = &s26hs512t; }; aliases { diff --git a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1.yaml b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1.yaml index 3de95effa8003..3d4f2062cc984 100644 --- a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1.yaml +++ b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1.yaml @@ -19,4 +19,5 @@ supported: - adc - i2c - dma + - pwm vendor: nxp diff --git a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1_D.yaml b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1_D.yaml index ef45138807eda..334d75319ca05 100644 --- a/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1_D.yaml +++ b/boards/nxp/s32z2xxdc2/s32z2xxdc2_s32z270_rtu1_D.yaml @@ -19,4 +19,5 @@ supported: - adc - i2c - dma + - pwm vendor: nxp diff --git a/boards/nxp/twr_ke18f/twr_ke18f.dts b/boards/nxp/twr_ke18f/twr_ke18f.dts index da98628956c6c..66e1059452113 100644 --- a/boards/nxp/twr_ke18f/twr_ke18f.dts +++ b/boards/nxp/twr_ke18f/twr_ke18f.dts @@ -224,7 +224,7 @@ &ftm0 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm0_default>; pinctrl-names = "default"; @@ -233,7 +233,7 @@ &ftm3 { status = "okay"; - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; #pwm-cells = <3>; pinctrl-0 = <&ftm3_default>; pinctrl-names = "default"; diff --git a/boards/nxp/twr_ke18f/twr_ke18f.yaml b/boards/nxp/twr_ke18f/twr_ke18f.yaml index 2ee4b9bef15db..33737e551adfd 100644 --- a/boards/nxp/twr_ke18f/twr_ke18f.yaml +++ b/boards/nxp/twr_ke18f/twr_ke18f.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 512 supported: diff --git a/boards/nxp/twr_kv58f220m/twr_kv58f220m.yaml b/boards/nxp/twr_kv58f220m/twr_kv58f220m.yaml index 453ce7d004cf1..fc0c8b521d792 100644 --- a/boards/nxp/twr_kv58f220m/twr_kv58f220m.yaml +++ b/boards/nxp/twr_kv58f220m/twr_kv58f220m.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/nxp/ucans32k1sic/ucans32k1sic.dts b/boards/nxp/ucans32k1sic/ucans32k1sic.dts index 4c1fdeb07328e..a22a3918c8ed9 100644 --- a/boards/nxp/ucans32k1sic/ucans32k1sic.dts +++ b/boards/nxp/ucans32k1sic/ucans32k1sic.dts @@ -150,7 +150,7 @@ }; &ftm0 { - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; pinctrl-0 = <&ftm0_default>; pinctrl-names = "default"; clock-source = "system"; @@ -160,7 +160,7 @@ }; &ftm1 { - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; pinctrl-0 = <&ftm1_default>; pinctrl-names = "default"; clock-source = "system"; @@ -170,7 +170,7 @@ }; &ftm2 { - compatible = "nxp,kinetis-ftm-pwm"; + compatible = "nxp,ftm-pwm"; pinctrl-0 = <&ftm2_default>; pinctrl-names = "default"; clock-source = "system"; diff --git a/boards/nxp/usb_kw24d512/usb_kw24d512.yaml b/boards/nxp/usb_kw24d512/usb_kw24d512.yaml index 1252d6418fcf7..4320277c68471 100644 --- a/boards/nxp/usb_kw24d512/usb_kw24d512.yaml +++ b/boards/nxp/usb_kw24d512/usb_kw24d512.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - flash - usb_device diff --git a/boards/nxp/vmu_rt1170/vmu_rt1170.yaml b/boards/nxp/vmu_rt1170/vmu_rt1170.yaml index 0ad33d74855f0..ffa04d5773d51 100644 --- a/boards/nxp/vmu_rt1170/vmu_rt1170.yaml +++ b/boards/nxp/vmu_rt1170/vmu_rt1170.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 65536 supported: diff --git a/boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_C.yaml b/boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_C.yaml index 5fdb67ec93323..7fc090013757b 100644 --- a/boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_C.yaml +++ b/boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_C.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 supported: diff --git a/boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_D.yaml b/boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_D.yaml index ead08879d1b7d..7d6af1766efe9 100644 --- a/boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_D.yaml +++ b/boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_D.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 supported: diff --git a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_appcpu.dts b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_appcpu.dts index e86ffdb90bf79..c88ae757867fd 100644 --- a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_appcpu.dts +++ b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.dts b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.dts index b080d47472d93..c39916c6de622 100644 --- a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.dts +++ b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.dts @@ -18,7 +18,7 @@ chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,bt-hci = &esp32_bt_hci; diff --git a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.yaml b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.yaml index c897a54621493..3084a2cf60c02 100644 --- a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.yaml +++ b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu.yaml @@ -13,8 +13,4 @@ supported: - spi - uart - watchdog -testing: - ignore_tags: - - net - - bluetooth vendor: olimex diff --git a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu_defconfig b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu_defconfig index f029cac9e9e77..e192c240251c1 100644 --- a/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu_defconfig +++ b/boards/olimex/olimex_esp32_evb/olimex_esp32_evb_procpu_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/olimex/olimexino_stm32/olimexino_stm32.yaml b/boards/olimex/olimexino_stm32/olimexino_stm32.yaml index 266ff00218497..fd3b52f986aad 100644 --- a/boards/olimex/olimexino_stm32/olimexino_stm32.yaml +++ b/boards/olimex/olimexino_stm32/olimexino_stm32.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 supported: - gpio diff --git a/boards/olimex/stm32_e407/olimex_stm32_e407.yaml b/boards/olimex/stm32_e407/olimex_stm32_e407.yaml index beefd5d2c8a76..8c68e307af6cb 100644 --- a/boards/olimex/stm32_e407/olimex_stm32_e407.yaml +++ b/boards/olimex/stm32_e407/olimex_stm32_e407.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/olimex/stm32_h103/olimex_stm32_h103.yaml b/boards/olimex/stm32_h103/olimex_stm32_h103.yaml index b863460fda49b..f1b406b1c6831 100644 --- a/boards/olimex/stm32_h103/olimex_stm32_h103.yaml +++ b/boards/olimex/stm32_h103/olimex_stm32_h103.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 flash: 128 supported: diff --git a/boards/olimex/stm32_h405/olimex_stm32_h405.yaml b/boards/olimex/stm32_h405/olimex_stm32_h405.yaml index 9930505236fc7..686345ce2acc9 100644 --- a/boards/olimex/stm32_h405/olimex_stm32_h405.yaml +++ b/boards/olimex/stm32_h405/olimex_stm32_h405.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/olimex/stm32_h407/olimex_stm32_h407.yaml b/boards/olimex/stm32_h407/olimex_stm32_h407.yaml index fea55c8a3d4ca..b7cdeeccf4d0d 100644 --- a/boards/olimex/stm32_h407/olimex_stm32_h407.yaml +++ b/boards/olimex/stm32_h407/olimex_stm32_h407.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/olimex/stm32_p405/olimex_stm32_p405.yaml b/boards/olimex/stm32_p405/olimex_stm32_p405.yaml index d3c23913f3538..67e408336ff02 100644 --- a/boards/olimex/stm32_p405/olimex_stm32_p405.yaml +++ b/boards/olimex/stm32_p405/olimex_stm32_p405.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/olimex/stm32_p405/olimex_stm32_p405_defconfig b/boards/olimex/stm32_p405/olimex_stm32_p405_defconfig index a6763abd156ba..51eadcb48096c 100644 --- a/boards/olimex/stm32_p405/olimex_stm32_p405_defconfig +++ b/boards/olimex/stm32_p405/olimex_stm32_p405_defconfig @@ -14,5 +14,3 @@ CONFIG_UART_CONSOLE=y # enable GPIO CONFIG_GPIO=y - -CONFIG_ENTROPY_GENERATOR=y diff --git a/boards/others/black_f407ve/black_f407ve.yaml b/boards/others/black_f407ve/black_f407ve.yaml index 3b37380ff48d4..849779180eb4c 100644 --- a/boards/others/black_f407ve/black_f407ve.yaml +++ b/boards/others/black_f407ve/black_f407ve.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 512 supported: diff --git a/boards/others/black_f407zg_pro/black_f407zg_pro.yaml b/boards/others/black_f407zg_pro/black_f407zg_pro.yaml index a686cf3a54c2f..5a720fbbdcd35 100644 --- a/boards/others/black_f407zg_pro/black_f407zg_pro.yaml +++ b/boards/others/black_f407zg_pro/black_f407zg_pro.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 1024 supported: diff --git a/boards/others/canbardo/Kconfig.canbardo b/boards/others/canbardo/Kconfig.canbardo new file mode 100644 index 0000000000000..dd82cb29466a9 --- /dev/null +++ b/boards/others/canbardo/Kconfig.canbardo @@ -0,0 +1,5 @@ +# Copyright (c) 2024-2025 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CANBARDO + select SOC_SAME70N20B diff --git a/boards/others/canbardo/board.cmake b/boards/others/canbardo/board.cmake new file mode 100644 index 0000000000000..470cf0a5322b8 --- /dev/null +++ b/boards/others/canbardo/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2024-2025 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=ATSAME70N20B") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/others/canbardo/board.yml b/boards/others/canbardo/board.yml new file mode 100644 index 0000000000000..096e332f8963b --- /dev/null +++ b/boards/others/canbardo/board.yml @@ -0,0 +1,6 @@ +board: + name: canbardo + full_name: CANbardo + vendor: others + socs: + - name: same70n20b diff --git a/boards/others/canbardo/canbardo-pinctrl.dtsi b/boards/others/canbardo/canbardo-pinctrl.dtsi new file mode 100644 index 0000000000000..18a4cb01c725c --- /dev/null +++ b/boards/others/canbardo/canbardo-pinctrl.dtsi @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024-2025 Henrik Brix Andersen + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart1_default: uart1_default { + group1 { + pinmux = , + ; + }; + }; + + can0_default: can0_default { + group1 { + pinmux = , + ; + }; + }; + + can1_default: can1_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/boards/others/canbardo/canbardo.dts b/boards/others/canbardo/canbardo.dts new file mode 100644 index 0000000000000..70da7b427bf14 --- /dev/null +++ b/boards/others/canbardo/canbardo.dts @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2024-2025 Henrik Brix Andersen + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include + +#include "canbardo-pinctrl.dtsi" + +/ { + model = "CANbardo board"; + compatible = "canbardo", "atmel,same70n20b", "atmel,same70b"; + + chosen { + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,canbus = &can0; + }; + + aliases { + led0 = &dfu_led; + sw0 = &sw; + mcuboot-led0 = &dfu_led; + mcuboot-button0 = &sw; + }; + + leds { + compatible = "gpio-leds"; + + dfu_led: dfu_led { + gpios = <&piod 9 GPIO_ACTIVE_LOW>; + label = "DFU LED"; + }; + + can_0_ledr: can_0_ledr { + gpios = <&piod 25 GPIO_ACTIVE_LOW>; + label = "CAN0 LED ERR"; + }; + + can_0_ledg: can_0_ledg { + gpios = <&piod 22 GPIO_ACTIVE_LOW>; + label = "CAN0 LED RDY"; + }; + + can_0_ledy: can_0_ledy { + gpios = <&piod 24 GPIO_ACTIVE_LOW>; + label = "CAN0 LED ACT"; + }; + + can_1_ledr: can_1_ledr { + gpios = <&piod 19 GPIO_ACTIVE_LOW>; + label = "CAN1 LED ERR"; + }; + + can_1_ledg: can_1_ledg { + gpios = <&piod 17 GPIO_ACTIVE_LOW>; + label = "CAN1 LED RDY"; + }; + + can_1_ledy: can_1_ledy { + gpios = <&piod 18 GPIO_ACTIVE_LOW>; + label = "CAN1 LED ACT"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + sw: sw { + label = "SW"; + gpios = <&piod 15 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + transceiver0: can-phy0 { + compatible = "microchip,mcp2558fd", "can-transceiver-gpio"; + enable-gpios = <&piod 26 GPIO_ACTIVE_LOW>; + max-bitrate = <8000000>; + #phy-cells = <0>; + }; + + transceiver1: can-phy1 { + compatible = "microchip,mcp2558fd", "can-transceiver-gpio"; + enable-gpios = <&piod 20 GPIO_ACTIVE_LOW>; + max-bitrate = <8000000>; + #phy-cells = <0>; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-names = "default"; +}; + +zephyr_udc0: &usbhs { + status = "okay"; +}; + +&can0 { + status = "okay"; + pinctrl-0 = <&can0_default>; + pinctrl-names = "default"; + phys = <&transceiver0>; +}; + +&can1 { + status = "okay"; + pinctrl-0 = <&can1_default>; + pinctrl-names = "default"; + phys = <&transceiver1>; +}; + +&wdt { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* First half of sector 0 */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(64)>; + read-only; + }; + + /* From sector 1 to sector 3 (included) */ + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 DT_SIZE_K(384)>; + }; + + /* From sector 4 to sector 6 (included) */ + slot1_partition: partition@80000 { + label = "image-1"; + reg = <0x00080000 DT_SIZE_K(384)>; + }; + + /* Sector 7 */ + storage_partition: partition@e0000 { + label = "storage"; + reg = <0x000e0000 DT_SIZE_K(128)>; + }; + }; +}; diff --git a/boards/others/canbardo/canbardo.yaml b/boards/others/canbardo/canbardo.yaml new file mode 100644 index 0000000000000..fab283bb5737c --- /dev/null +++ b/boards/others/canbardo/canbardo.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024-2025 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +identifier: canbardo/same70n20b +name: CANbardo +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +flash: 1024 +ram: 384 +supported: + - can + - gpio + - usb + - usb_device +vendor: others diff --git a/boards/others/canbardo/canbardo_defconfig b/boards/others/canbardo/canbardo_defconfig new file mode 100644 index 0000000000000..72c0c1bffffa7 --- /dev/null +++ b/boards/others/canbardo/canbardo_defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024-2025 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CACHE_MANAGEMENT=y +CONFIG_HW_STACK_PROTECTION=y + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y + +CONFIG_WDT_DISABLE_AT_BOOT=y diff --git a/boards/others/canbardo/doc/canbardo.webp b/boards/others/canbardo/doc/canbardo.webp new file mode 100644 index 0000000000000..48ec716406109 Binary files /dev/null and b/boards/others/canbardo/doc/canbardo.webp differ diff --git a/boards/others/canbardo/doc/index.rst b/boards/others/canbardo/doc/index.rst new file mode 100644 index 0000000000000..e0cccb91d9d2a --- /dev/null +++ b/boards/others/canbardo/doc/index.rst @@ -0,0 +1,67 @@ +.. zephyr:board:: canbardo + +Overview +******** + +CANbardo is an open hardware Universal Serial Bus (USB) to Controller Area Network (CAN) adapter +board. It is designed to be compatible with the open source :ref:`external_module_cannectivity`. + +Hardware +******** + +The CANbardo board is equipped with an Atmel SAME70N20B microcontroller and features an USB-C +connector (high-speed USB 2.0), two DB-9M connectors for CAN FD (up to 8 Mbit/s), a number of status +LEDs, and a push button. Schematics and component placement drawings are available in the `CANbardo +GitHub repository`_. + +Supported Features +================== + +The ``canbardo`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| USB | on-chip | USB | ++-----------+------------+-------------------------------------+ +| UART1 | on-chip | serial console | ++-----------+------------+-------------------------------------+ +| CAN0 | on-chip | CAN controller | ++-----------+------------+-------------------------------------+ +| CAN1 | on-chip | CAN controller | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: +:zephyr_file:`boards/others/canbardo/canbardo_defconfig`. + +Other hardware features are not currently supported by the port. + +System Clock +============ + +The SAME70N20B is driven by a 12 MHz crystal and configured to provide a system clock of 300 +MHz. The two CAN FD controllers have a core clock frequency of 80 MHz. + +Programming and Debugging +************************* + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: canbardo + :Goals: flash + +.. _CANbardo GitHub repository: + https://github.com/CANbardo/canbardo diff --git a/boards/others/esp32c3_supermini/Kconfig b/boards/others/esp32c3_supermini/Kconfig new file mode 100644 index 0000000000000..d7b9f494bc947 --- /dev/null +++ b/boards/others/esp32c3_supermini/Kconfig @@ -0,0 +1,8 @@ +# ESP32C3 supermini board configuration + +# Copyright (c) 2024 Arrel Neumiller +# SPDX-License-Identifier: Apache-2.0 + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 4096 diff --git a/boards/others/esp32c3_supermini/Kconfig.esp32c3_supermini b/boards/others/esp32c3_supermini/Kconfig.esp32c3_supermini new file mode 100644 index 0000000000000..3b1718b1480aa --- /dev/null +++ b/boards/others/esp32c3_supermini/Kconfig.esp32c3_supermini @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Arrel Neumiller +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ESP32C3_SUPERMINI + select SOC_ESP32C3_FH4 diff --git a/boards/others/esp32c3_supermini/Kconfig.sysbuild b/boards/others/esp32c3_supermini/Kconfig.sysbuild new file mode 100644 index 0000000000000..f4b8b8fb2beb1 --- /dev/null +++ b/boards/others/esp32c3_supermini/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Arrel Neumiller +# SPDX-License-Identifier: Apache-2.0 + +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_NONE +endchoice diff --git a/boards/others/esp32c3_supermini/board.cmake b/boards/others/esp32c3_supermini/board.cmake new file mode 100644 index 0000000000000..4c8b1b1822e71 --- /dev/null +++ b/boards/others/esp32c3_supermini/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Arrel Neumiller +# SPDX-License-Identifier: Apache-2.0 + +if(NOT "${OPENOCD}" MATCHES "^${ESPRESSIF_TOOLCHAIN_PATH}/.*") + set(OPENOCD OPENOCD-NOTFOUND) +endif() +find_program(OPENOCD openocd PATHS ${ESPRESSIF_TOOLCHAIN_PATH}/openocd-esp32/bin NO_DEFAULT_PATH) + +include(${ZEPHYR_BASE}/boards/common/esp32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/others/esp32c3_supermini/board.yml b/boards/others/esp32c3_supermini/board.yml new file mode 100644 index 0000000000000..ee28029260b20 --- /dev/null +++ b/boards/others/esp32c3_supermini/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Arrel Neumiller +# SPDX-License-Identifier: Apache-2.0 + +board: + name: esp32c3_supermini + full_name: ESP32-C3-SUPERMINI + vendor: others + socs: + - name: esp32c3 diff --git a/boards/others/esp32c3_supermini/doc/img/esp32c3_supermini.webp b/boards/others/esp32c3_supermini/doc/img/esp32c3_supermini.webp new file mode 100644 index 0000000000000..59e34716261dc Binary files /dev/null and b/boards/others/esp32c3_supermini/doc/img/esp32c3_supermini.webp differ diff --git a/boards/others/esp32c3_supermini/doc/index.rst b/boards/others/esp32c3_supermini/doc/index.rst new file mode 100644 index 0000000000000..7a7ff21dbd1e4 --- /dev/null +++ b/boards/others/esp32c3_supermini/doc/index.rst @@ -0,0 +1,249 @@ +.. zephyr:board:: esp32c3_supermini + +Overview +******** + +ESP32-C3-SUPERMINI is based on the ESP32-C3, a single-core Wi-Fi and Bluetooth 5 (LE) microcontroller SoC, +based on the open-source RISC-V architecture. This board also includes a Type-C USB Serial/JTAG port. +There may be multiple variations depending on the specific vendor. For more information a reasonbly well documented version of this board can be found at `ESP32-C3-SUPERMINI`_ + +Hardware +******** + +SoC Features: + +- IEEE 802.11 b/g/n-compliant +- Bluetooth 5, Bluetooth mesh +- 32-bit RISC-V single-core processor, up to 160MHz +- 384 KB ROM +- 400 KB SRAM (16 KB for cache) +- 8 KB SRAM in RTC +- 22 x programmable GPIOs +- 3 x SPI +- 2 x UART +- 1 x I2C +- 1 x I2S +- 2 x 54-bit general-purpose timers +- 3 x watchdog timers +- 1 x 52-bit system timer +- Remote Control Peripheral (RMT) +- LED PWM controller (LEDC) +- Full-speed USB Serial/JTAG controller +- General DMA controller (GDMA) +- 1 x TWAIÂŽ +- 2 x 12-bit SAR ADCs, up to 6 channels +- 1 x soc core temperature sensor + +For more information on the ESP32-C3 SOC, check the datasheet at `ESP32-C3 Datasheet`_ or the technical reference +manual at `ESP32-C3 Technical Reference Manual`_. + +Supported Features +================== + +Currently Zephyr's ``esp32c3_supermini`` board target supports the following features: + ++------------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++============+============+=====================================+ +| UART | on-chip | serial port | ++------------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++------------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++------------+------------+-------------------------------------+ +| USB-JTAG | on-chip | hardware interface | ++------------+------------+-------------------------------------+ +| SPI Master | on-chip | spi | ++------------+------------+-------------------------------------+ +| Timers | on-chip | counter | ++------------+------------+-------------------------------------+ +| Watchdog | on-chip | watchdog | ++------------+------------+-------------------------------------+ +| TRNG | on-chip | entropy | ++------------+------------+-------------------------------------+ +| LEDC | on-chip | pwm | ++------------+------------+-------------------------------------+ +| SPI DMA | on-chip | spi | ++------------+------------+-------------------------------------+ +| TWAI | on-chip | can | ++------------+------------+-------------------------------------+ +| USB-CDC | on-chip | serial | ++------------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++------------+------------+-------------------------------------+ +| Wi-Fi | on-chip | | ++------------+------------+-------------------------------------+ +| Bluetooth | on-chip | | ++------------+------------+-------------------------------------+ + +System requirements +******************* + +Prerequisites +============= + +Espressif HAL requires WiFi and Bluetooth binary blobs in order work. Run the command +below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_espressif + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Building & Flashing +******************* + +Simple boot +=========== + +The board could be loaded using the single binary image, without 2nd stage bootloader. +It is the default option when building the application without additional configuration. + +.. note:: + + Simple boot does not provide any security features nor OTA updates. + +MCUboot bootloader +================== + +User may choose to use MCUboot bootloader instead. In that case the bootloader +must be built (and flashed) at least once. + +There are two options to be used when building an application: + +1. Sysbuild +2. Manual build + +.. note:: + + User can select the MCUboot bootloader by adding the following line + to the board default configuration file. + + .. code:: cfg + + CONFIG_BOOTLOADER_MCUBOOT=y + +Sysbuild +======== + +The sysbuild makes possible to build and flash all necessary images needed to +bootstrap the board with the ESP32 SoC. + +To build the sample application using sysbuild use the command: + +.. zephyr-app-commands:: + :tool: west + :zephyr-app: samples/hello_world + :board: esp32c3_supermini + :goals: build + :west-args: --sysbuild + :compact: + +By default, the ESP32 sysbuild creates bootloader (MCUboot) and application +images. But it can be configured to create other kind of images. + +Build directory structure created by sysbuild is different from traditional +Zephyr build. Output is structured by the domain subdirectories: + +.. code-block:: + + build/ + ├── hello_world + │ └── zephyr + │ ├── zephyr.elf + │ └── zephyr.bin + ├── mcuboot + │ └── zephyr + │ ├── zephyr.elf + │ └── zephyr.bin + └── domains.yaml + +.. note:: + + With ``--sysbuild`` option the bootloader will be re-build and re-flash + every time the pristine build is used. + +For more information about the system build please read the :ref:`sysbuild` documentation. + +Manual build +============ + +During the development cycle, it is intended to build & flash as quickly possible. +For that reason, images can be built one at a time using traditional build. + +The instructions following are relevant for both manual build and sysbuild. +The only difference is the structure of the build directory. + +.. note:: + + Remember that bootloader (MCUboot) needs to be flash at least once. + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32c3_supermini + :goals: build + +The usual ``flash`` target will work with the ``esp32c3_supermini`` board +configuration. Here is an example for the :zephyr:code-sample:`hello_world` +application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32c3_supermini + :goals: flash + +Open the serial monitor using the following command: + +.. code-block:: shell + + west espressif monitor + +After the board has automatically reset and booted, you should see the following +message in the monitor: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! esp32c3_supermini + +Debugging +********* + +As with much custom hardware, the ESP32-C3 modules require patches to +OpenOCD that are not upstreamed yet. Espressif maintains their own fork of +the project. The custom OpenOCD can be obtained at `OpenOCD ESP32`_. + +The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the +``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` +parameter when building. + +Here is an example for building the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32c3_supermini + :goals: build flash + :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= + +You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: esp32c3_supermini + :goals: debug + +References +********** + +.. target-notes:: + +.. _`ESP32-C3-SUPERMINI`: https://www.nologo.tech/product/esp32/esp32c3SuperMini/esp32C3SuperMini.html +.. _`ESP32-C3 Datasheet`: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf +.. _`ESP32-C3 Technical Reference Manual`: https://espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf +.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases diff --git a/boards/others/esp32c3_supermini/esp32c3_supermini-pinctrl.dtsi b/boards/others/esp32c3_supermini/esp32c3_supermini-pinctrl.dtsi new file mode 100644 index 0000000000000..9ac04070866a9 --- /dev/null +++ b/boards/others/esp32c3_supermini/esp32c3_supermini-pinctrl.dtsi @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Arrel Neumiller + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + spim2_default: spim2_default { + group1 { + pinmux = , + , + ; + }; + group2 { + pinmux = ; + output-low; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; +}; diff --git a/boards/others/esp32c3_supermini/esp32c3_supermini.dts b/boards/others/esp32c3_supermini/esp32c3_supermini.dts new file mode 100644 index 0000000000000..30470c1a90fbd --- /dev/null +++ b/boards/others/esp32c3_supermini/esp32c3_supermini.dts @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Arrel Neumiller + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "esp32c3_supermini-pinctrl.dtsi" +#include +#include +#include + +/ { + model = "ESP32C3-SUPERMINI"; + compatible = "espressif,esp32c3_supermini"; + + chosen { + zephyr,sram = &sram1; + zephyr,console = &usb_serial; + zephyr,shell-uart = &usb_serial; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + aliases { + led0 = &blue_led_0; + sw0 = &user_button1; + i2c-0 = &i2c0; + watchdog0 = &wdt0; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button1: button_1 { + label = "User SW1"; + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + blue_led_0: led_0 { + gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; + label = "Blue LED 0"; + }; + }; + +}; + +&spi2 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-0 = <&spim2_default>; + pinctrl-names = "default"; + +}; + +&usb_serial { + status = "okay"; +}; + + +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + +&trng0 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&uart0 { + status = "disabled"; +}; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/others/esp32c3_supermini/esp32c3_supermini.yaml b/boards/others/esp32c3_supermini/esp32c3_supermini.yaml new file mode 100644 index 0000000000000..edc7252f583e0 --- /dev/null +++ b/boards/others/esp32c3_supermini/esp32c3_supermini.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Arrel Neumiller +# SPDX-License-Identifier: Apache-2.0 + +identifier: esp32c3_supermini +name: ESP32-C3-SUPERMINI +type: mcu +arch: riscv +toolchain: + - zephyr +supported: + - adc + - gpio + - i2c + - watchdog + - uart + - dma + - pwm + - spi + - counter + - entropy +vendor: others diff --git a/boards/others/esp32c3_supermini/esp32c3_supermini_defconfig b/boards/others/esp32c3_supermini/esp32c3_supermini_defconfig new file mode 100644 index 0000000000000..c5ef331aa760c --- /dev/null +++ b/boards/others/esp32c3_supermini/esp32c3_supermini_defconfig @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Arrel Neumiller +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/others/esp32c3_supermini/support/openocd.cfg b/boards/others/esp32c3_supermini/support/openocd.cfg new file mode 100644 index 0000000000000..7fa9d13624757 --- /dev/null +++ b/boards/others/esp32c3_supermini/support/openocd.cfg @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Arrel Neumiller +# SPDX-License-Identifier: Apache-2.0 + +set ESP_RTOS none + +# ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). +# Uncomment the line below to enable USB debugging. +#source [find interface/esp_usb_jtag.cfg] + +# Otherwise, use external JTAG programmer as ESP-Prog +source [find interface/ftdi/esp32_devkitj_v1.cfg] + +source [find target/esp32c3.cfg] +adapter speed 5000 diff --git a/boards/others/icev_wireless/icev_wireless.dts b/boards/others/icev_wireless/icev_wireless.dts index d044209cec48c..b91814c3b431a 100644 --- a/boards/others/icev_wireless/icev_wireless.dts +++ b/boards/others/icev_wireless/icev_wireless.dts @@ -16,7 +16,7 @@ compatible = "espressif,esp32c3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/others/icev_wireless/icev_wireless.yaml b/boards/others/icev_wireless/icev_wireless.yaml index 1850577054c3e..2ba46d2c763ee 100644 --- a/boards/others/icev_wireless/icev_wireless.yaml +++ b/boards/others/icev_wireless/icev_wireless.yaml @@ -4,8 +4,4 @@ type: mcu arch: riscv toolchain: - zephyr -testing: - ignore_tags: - - net - - bluetooth vendor: espressif diff --git a/boards/others/icev_wireless/icev_wireless_defconfig b/boards/others/icev_wireless/icev_wireless_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/others/icev_wireless/icev_wireless_defconfig +++ b/boards/others/icev_wireless/icev_wireless_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/others/promicro_nrf52840/Kconfig b/boards/others/promicro_nrf52840/Kconfig new file mode 100644 index 0000000000000..d49f34b3762a6 --- /dev/null +++ b/boards/others/promicro_nrf52840/Kconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2024 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_PROMICRO_NRF52840 + +config BOARD_HAS_NRF5_BOOTLOADER + bool "Board has nRF5 bootloader" + default y + help + If selected, applications are linked so that they can be loaded by Nordic + nRF5 bootloader. + +endif # BOARD_PROMICRO_NRF52840 diff --git a/boards/others/promicro_nrf52840/Kconfig.defconfig b/boards/others/promicro_nrf52840/Kconfig.defconfig new file mode 100644 index 0000000000000..85e9768bccc82 --- /dev/null +++ b/boards/others/promicro_nrf52840/Kconfig.defconfig @@ -0,0 +1,29 @@ +# Copyright (c) 2024 MASSDRIVER EI (massdriver.space) +# Copyright (c) 2018-2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_PROMICRO_NRF52840 + +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" + +# To let the nRF5 bootloader load an application, the application +# must be linked after Nordic MBR, that is factory-programmed on the board. + +# Nordic nRF5 bootloader exists outside of the partitions specified in the +# DTS file, so we manually override FLASH_LOAD_OFFSET to link the application +# correctly, after Nordic MBR. + +# When building MCUBoot, MCUBoot itself will select USE_DT_CODE_PARTITION +# which will make it link into the correct partition specified in DTS file, +# the offset is applied here so that the full partition size can be used when +# the bootloader Kconfig option has been disabled. + +config FLASH_LOAD_OFFSET + default 0x1000 + depends on BOARD_HAS_NRF5_BOOTLOADER && (MCUBOOT || !USE_DT_CODE_PARTITION) + +config BT_CTLR + default BT + +endif # BOARD_PROMICRO_NRF52840 diff --git a/boards/others/promicro_nrf52840/Kconfig.promicro_nrf52840 b/boards/others/promicro_nrf52840/Kconfig.promicro_nrf52840 new file mode 100644 index 0000000000000..ec026e8a7f73d --- /dev/null +++ b/boards/others/promicro_nrf52840/Kconfig.promicro_nrf52840 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PROMICRO_NRF52840 + select SOC_NRF52840_QIAA diff --git a/boards/others/promicro_nrf52840/board.cmake b/boards/others/promicro_nrf52840/board.cmake new file mode 100644 index 0000000000000..af0f4a93426b2 --- /dev/null +++ b/boards/others/promicro_nrf52840/board.cmake @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=nRF52840_xxAA" "--speed=4000") +board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") +if(CONFIG_BUILD_OUTPUT_UF2) + include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) +endif() +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/others/promicro_nrf52840/board.yml b/boards/others/promicro_nrf52840/board.yml new file mode 100644 index 0000000000000..dc4a01a47e438 --- /dev/null +++ b/boards/others/promicro_nrf52840/board.yml @@ -0,0 +1,8 @@ +board: + name: promicro_nrf52840 + full_name: Pro Micro nRF52840 + vendor: others + socs: + - name: nrf52840 + variants: + - name: uf2 diff --git a/boards/others/promicro_nrf52840/doc/img/others_promicro_nrf52840.webp b/boards/others/promicro_nrf52840/doc/img/others_promicro_nrf52840.webp new file mode 100644 index 0000000000000..9d81bdc271573 Binary files /dev/null and b/boards/others/promicro_nrf52840/doc/img/others_promicro_nrf52840.webp differ diff --git a/boards/others/promicro_nrf52840/doc/index.rst b/boards/others/promicro_nrf52840/doc/index.rst new file mode 100644 index 0000000000000..815b70a02c974 --- /dev/null +++ b/boards/others/promicro_nrf52840/doc/index.rst @@ -0,0 +1,181 @@ +.. zephyr:board:: promicro_nrf52840 + +More of a board type than a unique board, It is based on Nice!Nano. +Also referred to as Pro Micro, Promicro, SuperMini nRF52840 boards. + +Overview +******** + +The hardware provides support for the Nordic +Semiconductor nRF52840 ARM Cortex-M4F CPU and the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`RTC (nRF RTC System Clock)` +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UART (Universal asynchronous receiver-transmitter)` +* :abbr:`USB (Universal Serial Bus)` +* :abbr:`WDT (Watchdog Timer)` + +More information about the original board can be found at the +`Nice!Nano website`_. + +Information about clones can be found at `Clone Wiki`_. + +Pinout and Schematic are available in the `Nice!Nano Documentation`_ + + +Supported Features +================== + +The ``promicro_nrf52840/nrf52840`` board target supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RADIO | on-chip | Bluetooth, | +| | | ieee802154 | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| USB | on-chip | usb | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Connections and IOs +=================== + +LED +--- + +* LED0 = P0.15, can be any color. + +Programming and Debugging +************************* + +Applications for the ``promicro_nrf52840/nrf52840`` board target can be +built in the usual way (see :ref:`build_an_application` for more details). + +Flashing +======== + +The board is factory-programmed with Adafruit's UF2 booloader + +#. Reset the board into the bootloader by bridging ground and RST 2 times +quickly + + The status LED should start a fade pattern, signalling the bootloader is + running. + +#. Compile a Zephyr application; we'll use :zephyr:code-sample:`blinky`. + + .. zephyr-app-commands:: + :app: zephyr/samples/basic/blinky + :board: promicro_nrf52840/nrf52840/uf2 + :goals: build + +#. Flash it onto the board. You may need to mount the device. + + .. code-block:: console + + west flash + + When this command exits, observe the red LED on the board blinking, + + +Debugging +========= + +You may debug this board using the broken out pads on the back. +PyOCD and openOCD can be used to flash and debug this board. + +Recovery +======== + +In case of a error resulting in a board's bootloader becoming inaccessible, +it is possible to flash anything directly using openOCD: + +#. Setup OpenOCD correctly, here for WCH linkE in ARM mode: + + .. code-block:: console + + openocd -f interface/cmsis-dap.cfg -f target/nrf52.cfg + +Note interface and target folders are from openOCD's tcl folder. + +#. Connect to openOCD, for example with telnet or GDB: + + .. code-block:: console + + telnet localhost 4444 + + .. code-block:: console + + target extended-remote localhost:3333 + +#. Erase flash: + + .. code-block:: console + + reset halt + nrf5 mass_erase + +or + + .. code-block:: console + + mon reset halt + mon nrf5 mass_erase + +#. Flash Bootloader + + .. code-block:: console + + flash write_image erase nice_nano_bootloader-0.9.2_s140_6.1.1.hex + +or + + .. code-block:: console + + mon flash write_image erase nice_nano_bootloader-0.9.2_s140_6.1.1.hex + +References +********** + +.. target-notes:: + +.. _Nice!Nano website: + https://nicekeyboards.com/docs/nice-nano/ +.. _Clone Wiki: + https://github.com/joric/nrfmicro/wiki/Alternatives +.. _Nice!Nano Documentation: + https://nicekeyboards.com/docs/nice-nano/pinout-schematic diff --git a/boards/others/promicro_nrf52840/pre_dt_board.cmake b/boards/others/promicro_nrf52840/pre_dt_board.cmake new file mode 100644 index 0000000000000..3369c21d3af5b --- /dev/null +++ b/boards/others/promicro_nrf52840/pre_dt_board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2022 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - power@40000000 & clock@40000000 & bprot@40000000 +# - acl@4001e000 & flash-controller@4001e000 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840-pinctrl.dtsi b/boards/others/promicro_nrf52840/promicro_nrf52840-pinctrl.dtsi new file mode 100644 index 0000000000000..d4e61141803b0 --- /dev/null +++ b/boards/others/promicro_nrf52840/promicro_nrf52840-pinctrl.dtsi @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + i2c0_default: i2c0_default { + group1 { + psels = , + ; + }; + }; + + i2c0_sleep: i2c0_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + i2c1_default: i2c1_default { + group1 { + psels = , + ; + }; + }; + + i2c1_sleep: i2c1_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + spi2_default: spi2_default { + group1 { + psels = , + , + ; + }; + }; + + spi2_sleep: spi2_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + + pwm0_default: pwm0_default { + group1 { + psels = ; + }; + }; + + pwm0_sleep: pwm0_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; +}; diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840.yaml b/boards/others/promicro_nrf52840/promicro_nrf52840.yaml new file mode 100644 index 0000000000000..0f8ccd9b1a283 --- /dev/null +++ b/boards/others/promicro_nrf52840/promicro_nrf52840.yaml @@ -0,0 +1,19 @@ +identifier: promicro_nrf52840/nrf52840 +name: Pro Micro nRF52840 +type: mcu +arch: arm +ram: 256 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - usb_device + - ble + - pwm + - spi + - watchdog + - counter + - netif:openthread + - gpio diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840.dts b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840.dts new file mode 100644 index 0000000000000..3f68b9ababf77 --- /dev/null +++ b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840.dts @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "promicro_nrf52840_nrf52840_common.dts" +#include diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_common.dts b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_common.dts new file mode 100644 index 0000000000000..c8a8b77e62cf7 --- /dev/null +++ b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_common.dts @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2018-2023 Nordic Semiconductor ASA + * Copyright (c) 2017 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "promicro_nrf52840-pinctrl.dtsi" +#include + +/ { + model = "Pro Micro nRF52840"; + compatible = "others,promicro-nrf52840"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,ieee802154 = &ieee802154; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + red_pwm_led: led_pwm_0 { + pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "Red PWM LED"; + }; + }; + + aliases { + led0 = &led0; + pwm-led0 = &red_pwm_led; + red-pwm-led = &red_pwm_led; + bootloader-led0 = &led0; + mcuboot-led0 = &led0; + spi = &spi2; + watchdog0 = &wdt0; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&uicr { + nfct-pins-as-gpios; + gpio-as-nreset; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart0 { + compatible = "nordic,nrf-uarte"; + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + status = "okay"; + pinctrl-0 = <&i2c0_default>; + pinctrl-1 = <&i2c0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&i2c1 { + compatible = "nordic,nrf-twi"; + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-1 = <&i2c1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0_default>; + pinctrl-1 = <&pwm0_sleep>; + pinctrl-names = "default", "sleep"; +}; + + +&spi2 { + compatible = "nordic,nrf-spi"; + status = "okay"; + pinctrl-0 = <&spi2_default>; + pinctrl-1 = <&spi2_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&ieee802154 { + status = "okay"; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_defconfig b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_defconfig new file mode 100644 index 0000000000000..d0b5322cfeb49 --- /dev/null +++ b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_defconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable GPIO +CONFIG_GPIO=y + +# Board Kconfig.defconfig enables USB CDC ACM and should disable USB remote +# wakeup by default. It needs to be disabled here, because the USB nrfx +# driver always overwrites option from Kconfig mentioned above with the +# imply from CONFIG_USB_NRFX. +CONFIG_USB_DEVICE_REMOTE_WAKEUP=n diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.dts b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.dts new file mode 100644 index 0000000000000..d0c2ff473a6d7 --- /dev/null +++ b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.dts @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "promicro_nrf52840_nrf52840_common.dts" +#include diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.yaml b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.yaml new file mode 100644 index 0000000000000..7aa472b784d35 --- /dev/null +++ b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2.yaml @@ -0,0 +1,19 @@ +identifier: promicro_nrf52840/nrf52840/uf2 +name: Pro Micro nRF52840 +type: mcu +arch: arm +ram: 256 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - usb_device + - ble + - pwm + - spi + - watchdog + - counter + - netif:openthread + - gpio diff --git a/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2_defconfig b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2_defconfig new file mode 100644 index 0000000000000..51b5aae9f83e8 --- /dev/null +++ b/boards/others/promicro_nrf52840/promicro_nrf52840_nrf52840_uf2_defconfig @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable GPIO +CONFIG_GPIO=y + +# Board Kconfig.defconfig enables USB CDC ACM and should disable USB remote +# wakeup by default. It needs to be disabled here, because the USB nrfx +# driver always overwrites option from Kconfig mentioned above with the +# imply from CONFIG_USB_NRFX. +CONFIG_USB_DEVICE_REMOTE_WAKEUP=n + +# Build UF2 by default, supported by the Adafruit nRF52 Bootloader +CONFIG_BUILD_OUTPUT_UF2=y + +# UF2 Bootloader can use DT offset +CONFIG_BOARD_HAS_NRF5_BOOTLOADER=n +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/others/serpente/serpente.yaml b/boards/others/serpente/serpente.yaml index 7d3c1e68e58e5..438093aa07268 100644 --- a/boards/others/serpente/serpente.yaml +++ b/boards/others/serpente/serpente.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: diff --git a/boards/others/stm32_min_dev/twister.yaml b/boards/others/stm32_min_dev/twister.yaml index bcb30a9fdd0f0..19a0fa997230a 100644 --- a/boards/others/stm32_min_dev/twister.yaml +++ b/boards/others/stm32_min_dev/twister.yaml @@ -3,7 +3,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 supported: - i2c diff --git a/boards/others/stm32f030_demo/stm32f030_demo.yaml b/boards/others/stm32f030_demo/stm32f030_demo.yaml index 4a847323445d4..e327b7fb7694f 100644 --- a/boards/others/stm32f030_demo/stm32f030_demo.yaml +++ b/boards/others/stm32f030_demo/stm32f030_demo.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 4 flash: 16 supported: diff --git a/boards/others/stm32f103_mini/stm32f103_mini.yaml b/boards/others/stm32f103_mini/stm32f103_mini.yaml index 792145e6a1636..8478581eed9e8 100644 --- a/boards/others/stm32f103_mini/stm32f103_mini.yaml +++ b/boards/others/stm32f103_mini/stm32f103_mini.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 48 flash: 256 supported: diff --git a/boards/others/stm32f401_mini/stm32f401_mini.dts b/boards/others/stm32f401_mini/stm32f401_mini.dts index 8553bd8edf4b5..64c1da9af27f6 100644 --- a/boards/others/stm32f401_mini/stm32f401_mini.dts +++ b/boards/others/stm32f401_mini/stm32f401_mini.dts @@ -117,7 +117,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in1_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/others/stm32f401_mini/stm32f401_mini.yaml b/boards/others/stm32f401_mini/stm32f401_mini.yaml index ba3cdefd13881..a9570bc0ffbb0 100644 --- a/boards/others/stm32f401_mini/stm32f401_mini.yaml +++ b/boards/others/stm32f401_mini/stm32f401_mini.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - spi diff --git a/boards/panasonic/pan1770_evb/pan1770_evb.yaml b/boards/panasonic/pan1770_evb/pan1770_evb.yaml index 35ada5617cc54..a10c15ea3e10f 100644 --- a/boards/panasonic/pan1770_evb/pan1770_evb.yaml +++ b/boards/panasonic/pan1770_evb/pan1770_evb.yaml @@ -12,7 +12,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/panasonic/pan1780_evb/pan1780_evb.yaml b/boards/panasonic/pan1780_evb/pan1780_evb.yaml index 8833f01c3a233..65a29e5c75fc0 100644 --- a/boards/panasonic/pan1780_evb/pan1780_evb.yaml +++ b/boards/panasonic/pan1780_evb/pan1780_evb.yaml @@ -12,7 +12,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/panasonic/pan1781_evb/pan1781_evb.yaml b/boards/panasonic/pan1781_evb/pan1781_evb.yaml index 3061b639c54c7..5ba7fae607fa5 100644 --- a/boards/panasonic/pan1781_evb/pan1781_evb.yaml +++ b/boards/panasonic/pan1781_evb/pan1781_evb.yaml @@ -12,9 +12,7 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - - arduino_gpio - arduino_i2c - arduino_spi - ble diff --git a/boards/panasonic/pan1782_evb/pan1782_evb.yaml b/boards/panasonic/pan1782_evb/pan1782_evb.yaml index 9e896b97a566b..0574926ea72ee 100644 --- a/boards/panasonic/pan1782_evb/pan1782_evb.yaml +++ b/boards/panasonic/pan1782_evb/pan1782_evb.yaml @@ -12,10 +12,8 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - - arduino_gpio - arduino_i2c - arduino_spi - usb_device diff --git a/boards/panasonic/pan1783/pan1783_evb_nrf5340_cpuapp.yaml b/boards/panasonic/pan1783/pan1783_evb_nrf5340_cpuapp.yaml index 771055b508a31..4ed394738f000 100644 --- a/boards/panasonic/pan1783/pan1783_evb_nrf5340_cpuapp.yaml +++ b/boards/panasonic/pan1783/pan1783_evb_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/panasonic/pan1783/pan1783_evb_nrf5340_cpunet.yaml b/boards/panasonic/pan1783/pan1783_evb_nrf5340_cpunet.yaml index 510ceef5691b8..586252099df7f 100644 --- a/boards/panasonic/pan1783/pan1783_evb_nrf5340_cpunet.yaml +++ b/boards/panasonic/pan1783/pan1783_evb_nrf5340_cpunet.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/panasonic/pan1783/pan1783a_evb_nrf5340_cpuapp.yaml b/boards/panasonic/pan1783/pan1783a_evb_nrf5340_cpuapp.yaml index 3d9bea542288a..9f7fda71c414f 100644 --- a/boards/panasonic/pan1783/pan1783a_evb_nrf5340_cpuapp.yaml +++ b/boards/panasonic/pan1783/pan1783a_evb_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/panasonic/pan1783/pan1783a_evb_nrf5340_cpunet.yaml b/boards/panasonic/pan1783/pan1783a_evb_nrf5340_cpunet.yaml index 4904371041c7f..8a5ee9547e3b4 100644 --- a/boards/panasonic/pan1783/pan1783a_evb_nrf5340_cpunet.yaml +++ b/boards/panasonic/pan1783/pan1783a_evb_nrf5340_cpunet.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/panasonic/pan1783/pan1783a_pa_evb_nrf5340_cpuapp.yaml b/boards/panasonic/pan1783/pan1783a_pa_evb_nrf5340_cpuapp.yaml index d9936750286a2..8279d7aa7c64a 100644 --- a/boards/panasonic/pan1783/pan1783a_pa_evb_nrf5340_cpuapp.yaml +++ b/boards/panasonic/pan1783/pan1783a_pa_evb_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/panasonic/pan1783/pan1783a_pa_evb_nrf5340_cpunet.yaml b/boards/panasonic/pan1783/pan1783a_pa_evb_nrf5340_cpunet.yaml index 14ff8c16914dd..d49319f020d5f 100644 --- a/boards/panasonic/pan1783/pan1783a_pa_evb_nrf5340_cpunet.yaml +++ b/boards/panasonic/pan1783/pan1783a_pa_evb_nrf5340_cpunet.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/panasonic/panb511evb/Kconfig.defconfig b/boards/panasonic/panb511evb/Kconfig.defconfig new file mode 100644 index 0000000000000..03c84b8f538ee --- /dev/null +++ b/boards/panasonic/panb511evb/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_PANB511EVB_NRF54L15_CPUAPP + +config ROM_START_OFFSET + default 0x800 if BOOTLOADER_MCUBOOT + +endif # BOARD_PANB511EVB_NRF54L15_CPUAPP diff --git a/boards/panasonic/panb511evb/Kconfig.panb511evb b/boards/panasonic/panb511evb/Kconfig.panb511evb new file mode 100644 index 0000000000000..2454aba6270c1 --- /dev/null +++ b/boards/panasonic/panb511evb/Kconfig.panb511evb @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PANB511EVB + select SOC_NRF54L15_CPUAPP if BOARD_PANB511EVB_NRF54L15_CPUAPP + select SOC_NRF54L15_CPUFLPR if BOARD_PANB511EVB_NRF54L15_CPUFLPR || \ + BOARD_PANB511EVB_NRF54L15_CPUFLPR_XIP diff --git a/boards/panasonic/panb511evb/board.cmake b/boards/panasonic/panb511evb/board.cmake new file mode 100644 index 0000000000000..3138d0b04d779 --- /dev/null +++ b/boards/panasonic/panb511evb/board.cmake @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_NRF54L15_CPUAPP) + board_runner_args(jlink "--device=nRF54L15_M33" "--speed=4000") +elseif(CONFIG_SOC_NRF54L15_CPUFLPR) + set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54l15_cpuflpr.JLinkScript) + board_runner_args(jlink "--device=RISC-V" "--speed=4000" "-if SW" "--tool-opt=-jlinkscriptfile ${JLINKSCRIPTFILE}") +endif() + +include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/panasonic/panb511evb/board.yml b/boards/panasonic/panb511evb/board.yml new file mode 100644 index 0000000000000..a7e9a5901a4f5 --- /dev/null +++ b/boards/panasonic/panb511evb/board.yml @@ -0,0 +1,9 @@ +board: + name: panb511evb + full_name: PAN B511 Evaluation Board + vendor: panasonic + socs: + - name: nrf54l15 + variants: + - name: xip + cpucluster: cpuflpr diff --git a/boards/panasonic/panb511evb/doc/img/panb511evb.webp b/boards/panasonic/panb511evb/doc/img/panb511evb.webp new file mode 100644 index 0000000000000..51748e65c8df5 Binary files /dev/null and b/boards/panasonic/panb511evb/doc/img/panb511evb.webp differ diff --git a/boards/panasonic/panb511evb/doc/index.rst b/boards/panasonic/panb511evb/doc/index.rst new file mode 100644 index 0000000000000..934f55fc7a20c --- /dev/null +++ b/boards/panasonic/panb511evb/doc/index.rst @@ -0,0 +1,44 @@ +.. zephyr:board:: panb511evb + +Overview +******** + +The PAN B511 Evaluation Board (panb511evb) is a development tool +for the PAN B511 module which is based on the nRF54L15 chipset +from Nordic Semiconductor. + +More information about the PAN B511 Module Variants and Evaluation Board can be found +on the `product website`_. + +Usage +***** + +You can find the `panb511evb user guide`_ for the PAN B511 Evaluation Board in the +`Panasonic Wireless Connectivity Development Hub`_. + +The User Guide contains (amongst other things) detailed information about + +* pin mapping +* powering options +* breakout pin header interface +* current consumption measurement +* software development + +and other things. + +The schematics for the PANB511 Evaluation Boards are available in the +`download section PANB511`_ of the `Panasonic Wireless Connectivity Development Hub`_. + +Programming and Debugging +************************* + +Applications for the ``panb511evb/nrf54l15/cpuapp`` board target can +be built, flashed, and debugged in the usual way. See +:ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +.. target-notes:: +.. _product website: https://industry.panasonic.eu/products/devices/wireless-connectivity/bluetooth-low-energy-modules +.. _Panasonic Wireless Connectivity Development Hub: https://pideu.panasonic.de/development-hub/ +.. _panb511evb user guide: https://pideu.panasonic.de/development-hub/panb511/evaluation_board/user_guide/ +.. _download section PANB511: https://pideu.panasonic.de/development-hub/panb511/downloads/ diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15-pinctrl.dtsi b/boards/panasonic/panb511evb/panb511evb_nrf54l15-pinctrl.dtsi new file mode 100644 index 0000000000000..bc3a54459d978 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15-pinctrl.dtsi @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + /omit-if-no-ref/ uart20_default: uart20_default { + group1 { + psels = ; + }; + + group2 { + psels = ; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ uart20_sleep: uart20_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + /omit-if-no-ref/ uart30_default: uart30_default { + group1 { + psels = , + ; + }; + + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ uart30_sleep: uart30_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + /omit-if-no-ref/ spi00_default: spi00_default { + group1 { + psels = , + , + ; + }; + }; + + /omit-if-no-ref/ spi00_sleep: spi00_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + + /omit-if-no-ref/ pwm20_default: pwm20_default { + group1 { + psels = ; + }; + }; + + /omit-if-no-ref/ pwm20_sleep: pwm20_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; +}; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_common.dtsi b/boards/panasonic/panb511evb/panb511evb_nrf54l15_common.dtsi new file mode 100644 index 0000000000000..fc300f888b92a --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_common.dtsi @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "panb511evb_nrf54l15-pinctrl.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + + evb_led1: evb_led_1 { + gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + label = "LED1 on EVB"; + }; + + evb_led2: evb_led_2 { + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + label = "LED2 on EVB"; + }; + + evb_led3: evb_led_3 { + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + label = "LED3 on EVB"; + }; + + evb_led4: evb_led_4 { + gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; + label = "LED4 on EVB"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + /* + * PWM signal can be exposed on GPIO pin only within same domain. + * There is only one domain which contains both PWM and GPIO: + * PWM20/21/22 and GPIO Port P1. + * Only LEDs connected to P1 can work with PWM, for example LED1. + */ + pwm_evb_led1: pwm_evb_led_1 { + pwms = <&pwm20 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + buttons { + compatible = "gpio-keys"; + + evb_sw1: evb_sw_1 { + gpios = <&gpio1 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW1 on EVB"; + zephyr,code = ; + }; + + evb_sw2: evb_sw_2 { + gpios = <&gpio1 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2 on EVB"; + zephyr,code = ; + }; + + evb_sw3: evb_sw_3 { + gpios = <&gpio1 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW3 on EVB"; + zephyr,code = ; + }; + + evb_sw4: evb_sw_4 { + gpios = <&gpio1 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW4 on EVB"; + zephyr,code = ; + }; + }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio1 6 0>, /* AN */ + /* Not a GPIO*/ /* RST */ + <2 0 &gpio2 10 0>, /* CS */ + <3 0 &gpio2 6 0>, /* SCK */ + <4 0 &gpio2 9 0>, /* MISO */ + <5 0 &gpio2 8 0>, /* MOSI */ + /* +3.3V */ + /* GND */ + <6 0 &gpio1 15 0>, /* PWM */ + <7 0 &gpio2 7 0>, /* INT */ + <8 0 &gpio1 5 0>, /* RX */ + <9 0 &gpio1 4 0>, /* TX */ + <10 0 &gpio1 8 0>, /* SCL */ + <11 0 &gpio1 9 0>; /* SDA */ + /* +5V */ + /* GND */ + }; + + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio1 6 0>, /* A0 */ + <1 0 &gpio1 7 0>, /* A1 */ + <2 0 &gpio1 11 0>, /* A2 */ + <3 0 &gpio1 12 0>, /* A3 */ + <4 0 &gpio1 13 0>, /* A4 */ + <5 0 &gpio1 14 0>, /* A5 */ + <6 0 &gpio1 4 0>, /* D0 */ + <7 0 &gpio1 5 0>, /* D1 */ + <8 0 &gpio0 0 0>, /* D2 */ + <9 0 &gpio1 2 0>, /* D3 */ + <10 0 &gpio1 3 0>, /* D4 */ + <11 0 &gpio1 10 0>, /* D5 */ + <12 0 &gpio1 13 0>, /* D6 */ + <13 0 &gpio1 14 0>, /* D7 */ + <14 0 &gpio1 15 0>, /* D8 */ + <15 0 &gpio2 7 0>, /* D9 */ + <16 0 &gpio2 10 0>, /* D10 */ + <17 0 &gpio2 8 0>, /* D11 */ + <18 0 &gpio2 9 0>, /* D12 */ + <19 0 &gpio2 6 0>, /* D13 */ + <20 0 &gpio1 9 0>, /* D14 */ + <21 0 &gpio1 8 0>; /* D15 */ + }; + + arduino_adc: analog-connector { + compatible = "arduino,uno-adc"; + #io-channel-cells = <1>; + io-channel-map = <0 &adc 0>, /* A0 = P1.06 = AIN0 */ + <1 &adc 1>, /* A1 = P1.07 = AIN1 */ + <2 &adc 2>, /* A2 = P1.11 = AIN2 */ + <3 &adc 3>, /* A3 = P1.12 = AIN3 */ + <4 &adc 4>, /* A4 = P1.13 = AIN4 */ + <5 &adc 5>; /* A5 = P1.14 = AIN5 */ + }; + + aliases { + led0 = &evb_led1; + led1 = &evb_led2; + led2 = &evb_led3; + led3 = &evb_led4; + pwm-led0 = &pwm_evb_led1; + sw0 = &evb_sw1; + sw1 = &evb_sw2; + sw2 = &evb_sw3; + sw3 = &evb_sw4; + watchdog0 = &wdt31; + }; +}; + +&uart20 { + current-speed = <115200>; + pinctrl-0 = <&uart20_default>; + pinctrl-1 = <&uart20_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart30 { + current-speed = <115200>; + pinctrl-0 = <&uart30_default>; + pinctrl-1 = <&uart30_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pwm20 { + status = "okay"; + pinctrl-0 = <&pwm20_default>; + pinctrl-1 = <&pwm20_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.dts b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.dts new file mode 100644 index 0000000000000..c79847a3b57b0 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.dts @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "panb511evb_nrf54l15_cpuapp_common.dtsi" + +/ { + compatible = "panasonic-industrial-devices-europe-gmbh,panb511evb-cpuapp"; + model = "Panasonic PAN B511 EVB nRF54L15 Application MCU"; + + chosen { + zephyr,code-partition = &slot0_partition; + zephyr,sram = &cpuapp_sram; + }; +}; + +&cpuapp_rram { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 DT_SIZE_K(324)>; + }; + + slot0_ns_partition: partition@61000 { + label = "image-0-nonsecure"; + reg = <0x61000 DT_SIZE_K(324)>; + }; + + slot1_partition: partition@b2000 { + label = "image-1"; + reg = <0xb2000 DT_SIZE_K(324)>; + }; + + slot1_ns_partition: partition@103000 { + label = "image-1-nonsecure"; + reg = <0x103000 DT_SIZE_K(324)>; + }; + + /* 32k from 0x154000 to 0x15bfff reserved for TF-M partitions */ + storage_partition: partition@15c000 { + label = "storage"; + reg = <0x15c000 DT_SIZE_K(36)>; + }; + }; +}; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.yaml b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.yaml new file mode 100644 index 0000000000000..b30e5ffa106b4 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +identifier: panb511evb/nrf54l15/cpuapp +name: PANB511-EVB-nRF54l15-Application +type: mcu +arch: arm +toolchain: + - gnuarmemb + - zephyr +sysbuild: true +ram: 188 +flash: 324 +supported: + - adc + - counter + - gpio + - i2c + - pwm + - retained_mem + - spi + - watchdog + - i2s diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_common.dtsi b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_common.dtsi new file mode 100644 index 0000000000000..bf7922d8069eb --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_common.dtsi @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* This file is common to the secure and non-secure domain */ + +#include "panb511evb_nrf54l15_common.dtsi" + +/ { + chosen { + zephyr,console = &uart30; + zephyr,shell-uart = &uart30; + zephyr,uart-mcumgr = &uart30; + zephyr,bt-mon-uart = &uart30; + zephyr,bt-c2h-uart = &uart30; + zephyr,flash-controller = &rram_controller; + zephyr,flash = &cpuapp_rram; + zephyr,ieee802154 = &ieee802154; + }; +}; + +&cpuapp_sram { + status = "okay"; +}; + +&lfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <15500>; +}; + +&hfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <15000>; +}; + +®ulators { + status = "okay"; +}; + +&vregmain { + status = "okay"; + regulator-initial-mode = ; +}; + +&grtc { + owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11>; + /* Channels 7-11 reserved for Zero Latency IRQs, 3-4 for FLPR */ + child-owned-channels = <3 4 7 8 9 10 11>; + status = "okay"; +}; + +&uart30 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpiote30 { + status = "okay"; +}; + +&radio { + status = "okay"; +}; + +&ieee802154 { + status = "okay"; +}; + +&temp { + status = "okay"; +}; + +&clock { + status = "okay"; +}; + +&spi00 { + status = "okay"; + cs-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi00_default>; + pinctrl-1 = <&spi00_sleep>; + pinctrl-names = "default", "sleep"; + + mx25r64: mx25r6435f@0 { + compatible = "jedec,spi-nor"; + status = "okay"; + reg = <0>; + spi-max-frequency = <8000000>; + jedec-id = [c2 28 17]; + sfdp-bfp = [ + e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb + ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 + 10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 48 44 + 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff + ]; + size = <67108864>; + has-dpd; + t-enter-dpd = <10000>; + t-exit-dpd = <35000>; + }; +}; + +&adc { + status = "okay"; +}; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_defconfig b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_defconfig new file mode 100644 index 0000000000000..41648ab5b23b0 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuapp_defconfig @@ -0,0 +1,29 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# MPU-based null-pointer dereferencing detection cannot +# be applied as the (0x0 - 0x400) is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable Cache +CONFIG_CACHE_MANAGEMENT=y +CONFIG_EXTERNAL_CACHE=y + +# Start SYSCOUNTER on driver init +CONFIG_NRF_GRTC_START_SYSCOUNTER=y diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.dts b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.dts new file mode 100644 index 0000000000000..5a238b48a6ba1 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.dts @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "panb511evb_nrf54l15_common.dtsi" + +/ { + model = "Panasonic PAN B511 EVB nRF54L15 FLPR MCU"; + compatible = "panasonic-industrial-devices-europe-gmbh,panb511evb-cpuflpr"; + + chosen { + zephyr,console = &uart20; + zephyr,shell-uart = &uart20; + zephyr,code-partition = &cpuflpr_code_partition; + zephyr,flash = &cpuflpr_rram; + zephyr,sram = &cpuflpr_sram; + }; +}; + +&cpuflpr_sram { + status = "okay"; + /* Size must be increased due to booting from SRAM */ + reg = <0x20028000 DT_SIZE_K(96)>; + ranges = <0x0 0x20028000 0x18000>; +}; + +&cpuflpr_rram { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + cpuflpr_code_partition: partition@0 { + label = "image-0"; + reg = <0x0 DT_SIZE_K(96)>; + }; + }; +}; + +&grtc { + owned-channels = <3 4>; + status = "okay"; +}; + +&uart20 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpiote30 { + status = "okay"; +}; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.yaml b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.yaml new file mode 100644 index 0000000000000..481fcb00bd05d --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +identifier: panb511evb/nrf54l15/cpuflpr +name: PANB511-EVB-nRF54L15-Fast-Lightweight-Peripheral-Processor +type: mcu +arch: riscv +toolchain: + - zephyr +sysbuild: true +ram: 96 +flash: 96 +supported: + - counter + - gpio + - i2c + - spi + - watchdog diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_defconfig b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_defconfig new file mode 100644 index 0000000000000..35618b20a6e63 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_defconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +CONFIG_USE_DT_CODE_PARTITION=y + +# Execute from SRAM +CONFIG_XIP=n diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.dts b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.dts new file mode 100644 index 0000000000000..f14f44e097597 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.dts @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "panb511evb_nrf54l15_cpuflpr.dts" + +&cpuflpr_sram { + reg = <0x2002f000 DT_SIZE_K(68)>; + ranges = <0x0 0x2002f000 0x11000>; +}; diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.yaml b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.yaml new file mode 100644 index 0000000000000..e54c5a7b9fdd6 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +identifier: panb511evb/nrf54l15/cpuflpr/xip +name: PANB511-EVB-nRF54L15-Fast-Lightweight-Peripheral-Processor (RRAM XIP) +type: mcu +arch: riscv +toolchain: + - zephyr +sysbuild: true +ram: 68 +flash: 96 +supported: + - counter + - gpio + - i2c + - spi + - watchdog diff --git a/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip_defconfig b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip_defconfig new file mode 100644 index 0000000000000..8f75855af3cd4 --- /dev/null +++ b/boards/panasonic/panb511evb/panb511evb_nrf54l15_cpuflpr_xip_defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH +# SPDX-License-Identifier: Apache-2.0 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Execute from RRAM +CONFIG_XIP=y diff --git a/boards/panasonic/panb511evb/support/nrf54l15_cpuflpr.JLinkScript b/boards/panasonic/panb511evb/support/nrf54l15_cpuflpr.JLinkScript new file mode 100644 index 0000000000000..1cf94ee52a4d0 --- /dev/null +++ b/boards/panasonic/panb511evb/support/nrf54l15_cpuflpr.JLinkScript @@ -0,0 +1,5 @@ +int InitTarget(void) { + // Base address where DMI registers can be found in the APB address space + JLINK_ExecCommand("CORESIGHT_SetCoreBaseAddr = 0x5004C400"); + return 0; +} diff --git a/boards/particle/argon/particle_argon.yaml b/boards/particle/argon/particle_argon.yaml index 489b8c9dd1e97..8ec6c888b9218 100644 --- a/boards/particle/argon/particle_argon.yaml +++ b/boards/particle/argon/particle_argon.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - spi diff --git a/boards/particle/boron/particle_boron.yaml b/boards/particle/boron/particle_boron.yaml index bec2a0cbb0352..1e2835ac09d2b 100644 --- a/boards/particle/boron/particle_boron.yaml +++ b/boards/particle/boron/particle_boron.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - spi diff --git a/boards/particle/nrf51_blenano/nrf51_blenano.dts b/boards/particle/nrf51_blenano/nrf51_blenano.dts index f3e4dc8509c9e..8770c0b09ffdb 100644 --- a/boards/particle/nrf51_blenano/nrf51_blenano.dts +++ b/boards/particle/nrf51_blenano/nrf51_blenano.dts @@ -29,7 +29,7 @@ leds { compatible = "gpio-leds"; led0: led_0 { - gpios = <&gpio0 19 0>; + gpios = <&gpio0 19 GPIO_ACTIVE_LOW>; label = "LED"; }; }; diff --git a/boards/particle/nrf51_blenano/nrf51_blenano.yaml b/boards/particle/nrf51_blenano/nrf51_blenano.yaml index 97ddb9002abf8..4d4c9c96a2246 100644 --- a/boards/particle/nrf51_blenano/nrf51_blenano.yaml +++ b/boards/particle/nrf51_blenano/nrf51_blenano.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 16 supported: - ble diff --git a/boards/particle/nrf52_blenano2/nrf52_blenano2.yaml b/boards/particle/nrf52_blenano2/nrf52_blenano2.yaml index c3a0c8648bfa3..84f1dc668f814 100644 --- a/boards/particle/nrf52_blenano2/nrf52_blenano2.yaml +++ b/boards/particle/nrf52_blenano2/nrf52_blenano2.yaml @@ -5,6 +5,5 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 diff --git a/boards/particle/xenon/particle_xenon.yaml b/boards/particle/xenon/particle_xenon.yaml index 0aa6a4afa156c..0b21769654773 100644 --- a/boards/particle/xenon/particle_xenon.yaml +++ b/boards/particle/xenon/particle_xenon.yaml @@ -12,7 +12,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - spi diff --git a/boards/peregrine/index.rst b/boards/peregrine/index.rst new file mode 100644 index 0000000000000..a14270121da66 --- /dev/null +++ b/boards/peregrine/index.rst @@ -0,0 +1,10 @@ +.. _boards-peregrine: + +Peregrine +######### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/peregrine/sam4l_wm400_cape/Kconfig.defconfig b/boards/peregrine/sam4l_wm400_cape/Kconfig.defconfig new file mode 100644 index 0000000000000..1f95ae349d08f --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/Kconfig.defconfig @@ -0,0 +1,22 @@ +# Copyright (c) 2020-2025 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SAM4L_WM400_CAPE + +if NETWORKING + +config IEEE802154_RF2XX + default y + depends on IEEE802154 + +endif # NETWORKING + +# By default the board uses BOSSA bootloader and require that to zephyr relocate +# the code_partition. This should be disabled when using the whole flash without +# bootloader. +config USE_DT_CODE_PARTITION + default y + +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" + +endif # BOARD_SAM4L_WM400_CAPE diff --git a/boards/peregrine/sam4l_wm400_cape/Kconfig.sam4l_wm400_cape b/boards/peregrine/sam4l_wm400_cape/Kconfig.sam4l_wm400_cape new file mode 100644 index 0000000000000..44f81df5d32db --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/Kconfig.sam4l_wm400_cape @@ -0,0 +1,5 @@ +# Copyright (c) 2020-2025 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SAM4L_WM400_CAPE + select SOC_SAM4LC4B diff --git a/boards/peregrine/sam4l_wm400_cape/board.cmake b/boards/peregrine/sam4l_wm400_cape/board.cmake new file mode 100644 index 0000000000000..1b805dc8c9f9c --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/board.cmake @@ -0,0 +1,12 @@ +# Copyright (c) 2020-2025 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=atsam4lc4b") +board_runner_args(jlink "--speed=4000") +board_runner_args(jlink "--reset-after-load") +board_runner_args(jlink "-rtos GDBServer/RTOSPlugin_Zephyr") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +board_runner_args(bossac "--bossac-port=/dev/ttyACM0") +board_runner_args(bossac "--erase") +include(${ZEPHYR_BASE}/boards/common/bossac.board.cmake) diff --git a/boards/peregrine/sam4l_wm400_cape/board.yml b/boards/peregrine/sam4l_wm400_cape/board.yml new file mode 100644 index 0000000000000..ded0ab037ae97 --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/board.yml @@ -0,0 +1,6 @@ +board: + name: sam4l_wm400_cape + full_name: SAM4L WM-400 Cape Board + vendor: peregrine + socs: + - name: sam4lc4b diff --git a/boards/peregrine/sam4l_wm400_cape/doc/img/wm-400-pin-out.webp b/boards/peregrine/sam4l_wm400_cape/doc/img/wm-400-pin-out.webp new file mode 100644 index 0000000000000..28bfe30e3b424 Binary files /dev/null and b/boards/peregrine/sam4l_wm400_cape/doc/img/wm-400-pin-out.webp differ diff --git a/boards/peregrine/sam4l_wm400_cape/doc/index.rst b/boards/peregrine/sam4l_wm400_cape/doc/index.rst new file mode 100644 index 0000000000000..95ed6d6db5edd --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/doc/index.rst @@ -0,0 +1,153 @@ +.. zephyr:board:: sam4l_wm400_cape + +Overview +******** + +The SAM4L WM-400 Cape is a full featured design to enable IEEE 802.15.4 low +power nodes. It is a Beaglebone Black cape concept with an Atmel AT86RF233 +radio transceiver. User can develop Touch interface and have access to many +sensors and conectivity buses. + +Hardware +******** + +- ATSAM4LC4B ARM Cortex-M4 Processor +- 12 MHz crystal oscillator +- 32.768 kHz crystal oscillator +- 1 RS-232 interface +- 1 RS-485 full duplex interface +- Micro-AB USB OTG host/device +- 1 user touch button and One user pushbutton +- 4 user LEDs +- 1 AT86RF233 IEEE 802.15.4 transceiver +- 1 MPL115A2 I²C Barometric Pressure/Temperature Sensor +- 1 VCNL4010 Proximity/Light Sensor +- 1 CC2D33S Advanced Humidity Temperature Sensor +- 1 NCP18WF104J03RB NTC Temperature Sensor +- 1 TEMT6000X01 Ambient Light Sensor + +Supported Features +================== + +The ``sam4l_wm400_cape`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | counter | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| HWINFO | on-chip | Unique 120 bit serial number | ++-----------+------------+-------------------------------------+ +| RADIO | on-chip | ieee802154 | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| TRNG | on-chip | entropy | ++-----------+------------+-------------------------------------+ +| TWIM | on-chip | i2c master port-interrupt | ++-----------+------------+-------------------------------------+ +| USART | on-chip | serial port | ++-----------+------------+-------------------------------------+ +| USB | on-chip | USB device | ++-----------+------------+-------------------------------------+ + +Other hardware features are not currently supported by Zephyr. + +The default configuration can be found in the Kconfig +:zephyr_file:`boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape_defconfig`. + +Connections and IOs +=================== + +For detailed information see `SAM4L WM-400 Cape`_ Information. + +System Clock +============ + +The SAM4L MCU is configured to use the 12 MHz internal oscillator on the board +with the on-chip PLL to generate an 48 MHz system clock. + +Serial Port +=========== + +The ATSAM4LC4B MCU has 4 USARTs. One of the USARTs (USART3) is shared between +RS-232 and RS-485 interfaces. The default console terminal is available at +RS-232 onboard port or via USB device. + +Programming and Debugging +************************* + +The SAM4L WM-400 Cape board has a 10-pin header to connect to a Segger JLink. +Using the JLink is possible to program and debug the SAM4LC4B chip. The board +came with a SAM-BA bootloader that only can be used to flash the software. + +Flashing +======== + +#. For JLink instructions, see :ref:`jlink-debug-host-tools`. + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyACM0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyACM0 -o + + The -o option tells minicom not to send the modem initialization + string. Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +#. Connect the SAM4L WM-400 Cape board to your host computer using the + USB debug port. Then build and flash the :zephyr:code-sample:`hello_world` + application. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4l_wm400_cape + :goals: build flash + + You should see ``Hello World! sam4l_wm400_cape`` in your terminal. + +#. For SAM-BA bootloader instructions, see :ref:`atmel_sam_ba_bootloader`. + +#. Connect the SAM4L WM-400 Cape board to your host computer using the + USB debug port pressing the S1 button. Then build and flash the + :zephyr:code-sample:`hello_world` application. After programming the board + the application will start automatically. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4l_wm400_cape + :goals: build flash + :flash-args: -r bossac + + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: sam4l_wm400_cape + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _SAM4L WM-400 Cape: + https://gfbudke.wordpress.com/2014/04/30/modulo-wireless-ieee-802-15-4zigbee-wm-400-e-wm-400l-bbbs diff --git a/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape-pinctrl.dtsi b/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape-pinctrl.dtsi new file mode 100644 index 0000000000000..e1b81485b5bd2 --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape-pinctrl.dtsi @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022-2025 Gerson Fernando Budke + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + spi0_default: spi0_default { + group1 { + pinmux = , + , + , + , + ; + }; + }; + + twi1_default: twi1_default { + group1 { + pinmux = , + ; + }; + }; + + usart0_default: usart0_default { + group1 { + pinmux = , + ; + }; + }; + + usart0_hw_ctrl_flow: usart0_hw_ctrl_flow { + group1 { + pinmux = , + ; + bias-pull-up; + }; + + group2 { + pinmux = , + , + ; + }; + }; + + usart1_default: usart1_default { + group1 { + pinmux = , + ; + }; + }; + + usbc_default: usbc_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape.dts b/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape.dts new file mode 100644 index 0000000000000..5f1811003449d --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape.dts @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2020-2025 Gerson Fernando Budke + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "sam4l_wm400_cape-pinctrl.dtsi" +#include + +/ { + model = "Atmel SAM4L WM-400 Cape Board with an Atmel SAM4LC4B SoC"; + compatible = "peregrine,sam4l_wm400_cape", "atmel,sam4lc4b", "atmel,sam4l"; + + aliases { + i2c-0 = &twim1; + led0 = &red_mod_led; + led1 = &green_mod_led; + led2 = &blue_mod_led; + led3 = &red_cape_led; + sw0 = &sw0_dfu; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition= &code_partition; + }; + + leds { + compatible = "gpio-leds"; + + red_mod_led: led_0 { + gpios = <&gpioa 8 GPIO_ACTIVE_LOW>; + label = "LED_0"; + }; + + green_mod_led: led_1 { + gpios = <&gpiob 6 GPIO_ACTIVE_LOW>; + label = "LED_1"; + }; + + blue_mod_led: led_2 { + gpios = <&gpiob 7 GPIO_ACTIVE_LOW>; + label = "LED_2"; + }; + + red_cape_led: led_3 { + gpios = <&gpioa 24 GPIO_ACTIVE_LOW>; + label = "LED_3"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + sw0_dfu: button_1 { + gpios = <&gpiob 3 (GPIO_ACTIVE_LOW)>; + label = "SW0_DFU"; + zephyr,code = ; + }; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "sam-ba"; + reg = <0x000000000 0x00004000>; + }; + + code_partition: partition@4000 { + label = "image"; + reg = <0x00004000 0x0003c000>; + }; + }; +}; + +&spi0 { + status = "okay"; + + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + + cs-gpios = <&gpioa 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW) + &gpioa 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + + rf2xx@0 { + compatible = "atmel,rf2xx"; + reg = <0x0>; + spi-max-frequency = <6000000>; + irq-gpios = <&gpioa 20 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>; + slptr-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + at45db: at45db081d@1 { + compatible = "atmel,at45"; + reg = <1>; + spi-max-frequency = <8000000>; + jedec-id = [1f 25 00]; + size = <8388608>; + sector-size = <65536>; + block-size = <2048>; + page-size = <256>; + enter-dpd-delay = <3000>; + exit-dpd-delay = <35000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0x00000000 0x00100000>; + }; + }; + }; +}; + +&tc0 { + clk = <4>; + status = "okay"; +}; + +&twim1 { + status = "okay"; + + pinctrl-0 = <&twi1_default>; + pinctrl-names = "default"; + + std-clk-slew-lim = <0>; + std-clk-strength-low = "0.5"; + std-data-slew-lim = <0>; + std-data-strength-low = "0.5"; + + hs-clk-slew-lim = <0>; + hs-clk-strength-high = "0.5"; + hs-clk-strength-low = "0.5"; + hs-data-slew-lim = <0>; + hs-data-strength-low = "0.5"; + + hs-master-code = <0>; + + eeprom1: eeprom@57 { + compatible = "atmel,at24"; + reg = <0x57>; + size = <32768>; + pagesize = <64>; + address-width = <16>; + timeout = <5>; + }; +}; + +&usart0 { + status = "okay"; + current-speed = <115200>; + + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; +}; + +&usart1 { + status = "okay"; + current-speed = <115200>; + + pinctrl-0 = <&usart1_default>; + pinctrl-names = "default"; +}; + +zephyr_udc0: &usbc { + status = "okay"; + + pinctrl-0 = <&usbc_default>; + pinctrl-names = "default"; +}; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape.yaml b/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape.yaml new file mode 100644 index 0000000000000..ac9516c9431f0 --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2020-2025 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +identifier: sam4l_wm400_cape +name: SAM4L WM-400 Cape +type: mcu +arch: arm +flash: 256 +ram: 32 +toolchain: + - zephyr +supported: + - counter + - gpio + - entropy + - hwinfo + - i2c + - ieee802154 + - spi + - uart + - usart + - usb_device + - watchdog +vendor: peregrine diff --git a/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape_defconfig b/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape_defconfig new file mode 100644 index 0000000000000..623c83b1e0638 --- /dev/null +++ b/boards/peregrine/sam4l_wm400_cape/sam4l_wm400_cape_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2020-2025 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_WDT_DISABLE_AT_BOOT=y + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y diff --git a/boards/phytec/phyboard_electra/phyboard_electra_am6442_m4.dts b/boards/phytec/phyboard_electra/phyboard_electra_am6442_m4.dts index d19c5a62c923b..cc243d6243c55 100644 --- a/boards/phytec/phyboard_electra/phyboard_electra_am6442_m4.dts +++ b/boards/phytec/phyboard_electra/phyboard_electra_am6442_m4.dts @@ -17,7 +17,8 @@ zephyr,sram = &sram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram1 = &ddr0; + zephyr,ipc_shm = &ddr0; + zephyr,sram1 = &ddr1; }; aliases { @@ -31,9 +32,20 @@ }; }; - ddr0:memory@a4100000 { + ddr0: memory@a4000000 { + compatible = "mmio-sram"; + reg = <0xa4000000 DT_SIZE_M(1)>; + }; + + rsc_table: memory@a4100000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0xa4100000 DT_SIZE_K(4)>; + zephyr,memory-region = "RSC_TABLE"; + }; + + ddr1: memory@a4101000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0xa4101000 (DT_SIZE_M(15) - DT_SIZE_K(4))>; zephyr,memory-region = "DDR"; }; diff --git a/boards/phytec/phyboard_lyra/doc/phyboard_lyra_am62xx_a53.rst b/boards/phytec/phyboard_lyra/doc/phyboard_lyra_am62xx_a53.rst index 9b6d2f42a3d2a..b7d00a9764f45 100644 --- a/boards/phytec/phyboard_lyra/doc/phyboard_lyra_am62xx_a53.rst +++ b/boards/phytec/phyboard_lyra/doc/phyboard_lyra_am62xx_a53.rst @@ -45,6 +45,8 @@ features: +-----------+------------+-------------------------------------+ | UART | on-chip | serial port | +-----------+------------+-------------------------------------+ +| Mailbox | on-chip | IPC Mailbox | ++-----------+------------+-------------------------------------+ Devices ======== diff --git a/boards/phytec/phyboard_lyra/doc/phyboard_lyra_am62xx_m4.rst b/boards/phytec/phyboard_lyra/doc/phyboard_lyra_am62xx_m4.rst index d0f61264890f2..cf36efc4f5e10 100644 --- a/boards/phytec/phyboard_lyra/doc/phyboard_lyra_am62xx_m4.rst +++ b/boards/phytec/phyboard_lyra/doc/phyboard_lyra_am62xx_m4.rst @@ -56,6 +56,8 @@ The phyboard_lyra/am6234/m4 configuration supports the following hardware featur +-----------+------------+-------------------------------------+ | UART | on-chip | serial | +-----------+------------+-------------------------------------+ +| Mailbox | on-chip | IPC Mailbox | ++-----------+------------+-------------------------------------+ Other hardware features are not currently supported by the port. diff --git a/boards/phytec/phyboard_lyra/phyboard_lyra_am6234_m4.dts b/boards/phytec/phyboard_lyra/phyboard_lyra_am6234_m4.dts index 8112aeba41946..403277aea0670 100644 --- a/boards/phytec/phyboard_lyra/phyboard_lyra_am6234_m4.dts +++ b/boards/phytec/phyboard_lyra/phyboard_lyra_am6234_m4.dts @@ -17,7 +17,8 @@ zephyr,sram = &sram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram1 = &ddr0; + zephyr,ipc_shm = &ddr0; + zephyr,sram1 = &ddr1; }; aliases { @@ -31,9 +32,20 @@ }; }; - ddr0:memory@9CC00000{ + ddr0: memory@9cb00000 { + compatible = "mmio-sram"; + reg = <0x9cb00000 DT_SIZE_M(1)>; + }; + + rsc_table: memory@9cc00000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x9cc00000 DT_SIZE_K(4)>; + zephyr,memory-region = "RSC_TABLE"; + }; + + ddr1: memory@9cc01000 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x9CC00000 DT_SIZE_K(4)>; + reg = <0x9cc01000 (DT_SIZE_M(15) - DT_SIZE_K(4))>; zephyr,memory-region = "DDR"; }; diff --git a/boards/phytec/phyboard_polis/phyboard_polis_mimx8mm6_m4.yaml b/boards/phytec/phyboard_polis/phyboard_polis_mimx8mm6_m4.yaml index 5167e4d0aece5..23d07a25c9928 100644 --- a/boards/phytec/phyboard_polis/phyboard_polis_mimx8mm6_m4.yaml +++ b/boards/phytec/phyboard_polis/phyboard_polis_mimx8mm6_m4.yaml @@ -13,7 +13,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/phytec/phyboard_pollux/phyboard_pollux_mimx8ml8_m7.yaml b/boards/phytec/phyboard_pollux/phyboard_pollux_mimx8ml8_m7.yaml index 01084520792db..2af3d88b937a8 100644 --- a/boards/phytec/phyboard_pollux/phyboard_pollux_mimx8ml8_m7.yaml +++ b/boards/phytec/phyboard_pollux/phyboard_pollux_mimx8ml8_m7.yaml @@ -13,7 +13,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/phytec/reel_board/reel_board_1.yaml b/boards/phytec/reel_board/reel_board_1.yaml index b357f545511b1..c973f47cc79e3 100644 --- a/boards/phytec/reel_board/reel_board_1.yaml +++ b/boards/phytec/reel_board/reel_board_1.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - spi diff --git a/boards/phytec/reel_board/reel_board_nrf52840_2.yaml b/boards/phytec/reel_board/reel_board_nrf52840_2.yaml index e98f366b969e4..5852cf72161bc 100644 --- a/boards/phytec/reel_board/reel_board_nrf52840_2.yaml +++ b/boards/phytec/reel_board/reel_board_nrf52840_2.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - spi diff --git a/boards/pine64/pinetime_devkit0/pinetime_devkit0.yaml b/boards/pine64/pinetime_devkit0/pinetime_devkit0.yaml index 081daced8abac..c99eb8986f3bd 100644 --- a/boards/pine64/pinetime_devkit0/pinetime_devkit0.yaml +++ b/boards/pine64/pinetime_devkit0/pinetime_devkit0.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/pjrc/teensy4/doc/teensy40.jpg b/boards/pjrc/teensy4/doc/img/teensy40.jpg similarity index 100% rename from boards/pjrc/teensy4/doc/teensy40.jpg rename to boards/pjrc/teensy4/doc/img/teensy40.jpg diff --git a/boards/pjrc/teensy4/doc/teensy41.jpg b/boards/pjrc/teensy4/doc/img/teensy41.jpg similarity index 100% rename from boards/pjrc/teensy4/doc/teensy41.jpg rename to boards/pjrc/teensy4/doc/img/teensy41.jpg diff --git a/boards/pjrc/teensy4/doc/index.rst b/boards/pjrc/teensy4/doc/index.rst index 66aefe952c0a2..3517b1fb70fad 100644 --- a/boards/pjrc/teensy4/doc/index.rst +++ b/boards/pjrc/teensy4/doc/index.rst @@ -5,72 +5,100 @@ PJRC TEENSY 4 Overview ******** + The Teensy is a complete USB-based microcontroller development system, in a very small footprint, capable of implementing many types of projects. All programming is done via the USB port. +.. tabs:: + + .. group-tab:: Teensy 4.0 + + .. figure:: img/teensy40.jpg + :align: center + :alt: TEENSY40 -.. figure:: teensy40.jpg - :align: center - :alt: TEENSY40 + (Credit: https://www.pjrc.com) - TEENSY40 (Credit: https://www.pjrc.com) + .. group-tab:: Teensy 4.1 -.. figure:: teensy41.jpg - :align: center - :alt: TEENSY41 + .. figure:: img/teensy41.jpg + :align: center + :alt: TEENSY41 - TEENSY41 (Credit: https://www.pjrc.com) + (Credit: https://www.pjrc.com) Hardware ******** -Teensy 4.0: +.. tabs:: + + .. group-tab:: Teensy 4.0 + + - MIMXRT1062DVL6A MCU (600 MHz, 1024 KB on-chip memory) + - 16 Mbit QSPI Flash + - User LED + - USB 2.0 host connector + + See the `Teensy 4.0 Website`_ for a complete hardware description. -- MIMXRT1062DVL6A MCU (600 MHz, 1024 KB on-chip memory) -- 16 Mbit QSPI Flash -- LED -- USB 2.0 host connector + .. group-tab:: Teensy 4.1 -Teensy 4.1: + - MIMXRT1062DVJ6A MCU (600 MHz, 1024 KB on-chip memory) + - 64 Mbit QSPI Flash + - User LED + - USB 2.0 host connector + - USB 2.0 OTG connector + - 10/100 Mbit/s Ethernet transceiver + - TF socket for SD card -- MIMXRT1062DVJ6A MCU (600 MHz, 1024 KB on-chip memory) -- 64 Mbit QSPI Flash -- LED -- USB 2.0 host connector -- USB 2.0 OTG connector -- 10/100 Mbit/s Ethernet PHY -- TF socket for SD card + To connect an Ethernet cable, additional `Teensy 4.1 Ethernet Kit`_ is required. -See the `Teensy 4.0 Website`_ for a complete hardware description. + See the `Teensy 4.1 Website`_ for a complete hardware description. + +For more information, check the `i.MX RT1060 Datasheet`_. Supported Features ================== -The teensy40 board configuration supports the following hardware +The Teensy 4.0 board configuration supports the following hardware features: -+-----------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+=====================================+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+-------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+-------------------------------------+ -| I2C | on-chip | i2c | -+-----------+------------+-------------------------------------+ -| UART | on-chip | serial port-polling; | -| | | serial port-interrupt | -+-----------+------------+-------------------------------------+ -| USB | on-chip | USB device | -+-----------+------------+-------------------------------------+ - -The default configuration can be found in -:zephyr_file:`boards/pjrc/teensy4/teensy40_defconfig` - -The teensy41 board configuration supports additional hardware ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ +| I2S | on-chip | i2s | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI | on-chip | spi | ++-----------+------------+----------------------+ +| CAN | on-chip | can | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| USB | on-chip | usb | ++-----------+------------+----------------------+ +| TRNG | on-chip | entropy | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +The Teensy 4.1 board configuration supports additional hardware features: +-----------+------------+-------------------------------------+ @@ -81,10 +109,7 @@ features: | ENET | on-chip | ethernet | +-----------+------------+-------------------------------------+ -The default configuration can be found in -:zephyr_file:`boards/pjrc/teensy4/teensy41_defconfig` - -Other hardware features are not currently supported by the port. +Other hardware features have not been enabled yet for this board. Connections and IOs =================== @@ -204,23 +229,97 @@ Programming and Debugging Flashing ======== -Build applications as usual (see :ref:`build_an_application` for more details). -Flash hex-file with the documented tools: +Both the Teensy 4.0 and Teensy 4.1 ship with a dedicated bootloader chip, +which supports flashing using USB. This allows easy flashing of new images, +but does not support debugging the device. + +#. Build the Zephyr kernel and the :zephyr:code-sample:`blinky` sample application. + +.. tabs:: + + .. group-tab:: Teensy 4.0 + + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: teensy40 + :goals: build + :compact: -.. _Teensy flash tools: - https://www.pjrc.com/teensy/loader.html + .. group-tab:: Teensy 4.1 -Debugging -========= -Console output is mapped to teensy pins 0 (RX1) and 1 (TX1). Connect a usb-to-serial adapter -to use this serial console. Use the following settings with your serial terminal of choice (minicom, putty, -etc.): + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: teensy41 + :goals: build + :compact: -- Speed: 115200 -- Data: 8 bits -- Parity: None -- Stop bits: 1 +#. Connect the board to your host computer using USB. + +#. Tap the reset button to enter bootloader mode. + Red LED blinks. + +#. Flash the image. + +.. tabs:: + + .. group-tab:: Teensy 4.0 + + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: teensy40 + :goals: flash + :compact: + + .. group-tab:: Teensy 4.1 + + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: teensy41 + :goals: flash + :compact: + +#. You should see the orange LED blink. + +Configuring a Console +===================== + +.. tabs:: + + .. group-tab:: UART-Console + + By default console output is mapped to teensy pins 0 (RX1) and 1 (TX1). Connect a usb-to-serial adapter + to use this serial console. Use the following settings with your serial terminal of choice (minicom, putty, + etc.): + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + + .. group-tab:: USB-Console + + By mapping the console output to USB, a usb-to-serial adapter is no longer required. + Utilizing the :ref:`snippet-cdc-acm-console` and a config option will enable this feature. + + #. If application code doesn´t enable USB device support, this must be done via Kconfig option. + + .. code-block:: kconfig + + CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y + + #. Build application including the snippet. + + .. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :snippets: cdc-acm-console + :board: teensy41 + :goals: flash + :compact: + + #. After application startup a serial device named like + ``tty.usbmodem14203`` should appear on your host computer. + You can use e.g. ``Serial Monitor`` plugin for VScode to monitor. References ********** @@ -230,14 +329,11 @@ References .. _Teensy 4.0 Website: https://www.pjrc.com/store/teensy40.html -.. _Teensy Schematics: - https://www.pjrc.com/teensy/schematic.html +.. _Teensy 4.1 Website: + https://www.pjrc.com/store/teensy41.html -.. _i.MX RT1060 Website: - https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/i.mx-applications-processors/i.mx-rt-series/i.mx-rt1060-crossover-processor-with-arm-cortex-m7-core:i.MX-RT1060 +.. _Teensy 4.1 Ethernet Kit: + https://www.pjrc.com/store/ethernet_kit.html .. _i.MX RT1060 Datasheet: https://www.nxp.com/docs/en/nxp/data-sheets/IMXRT1060CEC.pdf - -.. _i.MX RT1060 Reference Manual: - https://www.nxp.com/webapp/Download?colCode=IMXRT1060RM diff --git a/boards/pjrc/teensy4/teensy40.yaml b/boards/pjrc/teensy4/teensy40.yaml index 11a7f0b284dac..a4908dc6abd3c 100644 --- a/boards/pjrc/teensy4/teensy40.yaml +++ b/boards/pjrc/teensy4/teensy40.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 768 flash: 2048 supported: diff --git a/boards/pjrc/teensy4/teensy41.yaml b/boards/pjrc/teensy4/teensy41.yaml index 18f320a2df614..659f6838ffa91 100644 --- a/boards/pjrc/teensy4/teensy41.yaml +++ b/boards/pjrc/teensy4/teensy41.yaml @@ -11,7 +11,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 768 flash: 8192 supported: diff --git a/boards/qemu/cortex_a53/qemu_cortex_a53.yaml b/boards/qemu/cortex_a53/qemu_cortex_a53.yaml index 509a461422fb2..9701dbf5f1f83 100644 --- a/boards/qemu/cortex_a53/qemu_cortex_a53.yaml +++ b/boards/qemu/cortex_a53/qemu_cortex_a53.yaml @@ -7,7 +7,8 @@ arch: arm64 toolchain: - zephyr - cross-compile -ram: 128 +ram: 131072 +flash: 65536 testing: default: true ignore_tags: diff --git a/boards/qemu/cortex_a9/qemu_cortex_a9.yaml b/boards/qemu/cortex_a9/qemu_cortex_a9.yaml index eb3e9ccc2c2c7..b1ed651c83076 100644 --- a/boards/qemu/cortex_a9/qemu_cortex_a9.yaml +++ b/boards/qemu/cortex_a9/qemu_cortex_a9.yaml @@ -14,7 +14,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - net - netif:eth diff --git a/boards/qemu/cortex_m0/qemu_cortex_m0.yaml b/boards/qemu/cortex_m0/qemu_cortex_m0.yaml index 5d6f166eeb740..02703d6f35c89 100644 --- a/boards/qemu/cortex_m0/qemu_cortex_m0.yaml +++ b/boards/qemu/cortex_m0/qemu_cortex_m0.yaml @@ -7,7 +7,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 16 flash: 256 testing: diff --git a/boards/qemu/cortex_m3/qemu_cortex_m3.yaml b/boards/qemu/cortex_m3/qemu_cortex_m3.yaml index 70f17485495a4..3d27987244a08 100644 --- a/boards/qemu/cortex_m3/qemu_cortex_m3.yaml +++ b/boards/qemu/cortex_m3/qemu_cortex_m3.yaml @@ -7,7 +7,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - netif:serial-net - gpio diff --git a/boards/qemu/cortex_r5/qemu_cortex_r5.yaml b/boards/qemu/cortex_r5/qemu_cortex_r5.yaml index 120c983fec2ea..392438c4e5d7e 100644 --- a/boards/qemu/cortex_r5/qemu_cortex_r5.yaml +++ b/boards/qemu/cortex_r5/qemu_cortex_r5.yaml @@ -7,7 +7,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 65536 flash: 32768 testing: diff --git a/boards/qemu/leon3/qemu_leon3.yaml b/boards/qemu/leon3/qemu_leon3.yaml index 9e21ec42bbb82..58a38e2fb0297 100644 --- a/boards/qemu/leon3/qemu_leon3.yaml +++ b/boards/qemu/leon3/qemu_leon3.yaml @@ -8,7 +8,6 @@ ram: 1048576 flash: 524288 toolchain: - zephyr - - xtools supported: - netif testing: diff --git a/boards/qemu/malta/qemu_malta.yaml b/boards/qemu/malta/qemu_malta.yaml index 836d037aabb3d..db1040b3d9a78 100644 --- a/boards/qemu/malta/qemu_malta.yaml +++ b/boards/qemu/malta/qemu_malta.yaml @@ -6,7 +6,6 @@ simulation: arch: mips toolchain: - zephyr - - xtools ram: 1024 flash: 512 testing: diff --git a/boards/qemu/malta/qemu_malta_qemu_malta_be.yaml b/boards/qemu/malta/qemu_malta_qemu_malta_be.yaml index a20cc223e853a..aba9aa3586410 100644 --- a/boards/qemu/malta/qemu_malta_qemu_malta_be.yaml +++ b/boards/qemu/malta/qemu_malta_qemu_malta_be.yaml @@ -6,7 +6,6 @@ simulation: arch: mips toolchain: - zephyr - - xtools ram: 1024 flash: 512 testing: diff --git a/boards/qemu/nios2/qemu_nios2.yaml b/boards/qemu/nios2/qemu_nios2.yaml index c0a3cf21644d5..816c280b5a024 100644 --- a/boards/qemu/nios2/qemu_nios2.yaml +++ b/boards/qemu/nios2/qemu_nios2.yaml @@ -8,7 +8,6 @@ ram: 128 flash: 128 toolchain: - zephyr - - xtools testing: default: true ignore_tags: diff --git a/boards/qemu/riscv32/qemu_riscv32.yaml b/boards/qemu/riscv32/qemu_riscv32.yaml index 6421fe744bdc4..8b0d348ee4f07 100644 --- a/boards/qemu/riscv32/qemu_riscv32.yaml +++ b/boards/qemu/riscv32/qemu_riscv32.yaml @@ -6,7 +6,6 @@ simulation: arch: riscv toolchain: - zephyr - - xtools supported: - netif testing: diff --git a/boards/qemu/riscv32/qemu_riscv32_qemu_virt_riscv32_smp.yaml b/boards/qemu/riscv32/qemu_riscv32_qemu_virt_riscv32_smp.yaml index 368fa750090fd..2ff24d2b59653 100644 --- a/boards/qemu/riscv32/qemu_riscv32_qemu_virt_riscv32_smp.yaml +++ b/boards/qemu/riscv32/qemu_riscv32_qemu_virt_riscv32_smp.yaml @@ -6,7 +6,6 @@ simulation: arch: riscv toolchain: - zephyr - - xtools supported: - netif - smp diff --git a/boards/qemu/riscv32_xip/qemu_riscv32_xip.yaml b/boards/qemu/riscv32_xip/qemu_riscv32_xip.yaml index 2e21c4acd2f6d..c2270c4236fcf 100644 --- a/boards/qemu/riscv32_xip/qemu_riscv32_xip.yaml +++ b/boards/qemu/riscv32_xip/qemu_riscv32_xip.yaml @@ -7,7 +7,6 @@ arch: riscv ram: 16 toolchain: - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/qemu/riscv32e/qemu_riscv32e.yaml b/boards/qemu/riscv32e/qemu_riscv32e.yaml index 8159d8c6292a8..475430c69d163 100644 --- a/boards/qemu/riscv32e/qemu_riscv32e.yaml +++ b/boards/qemu/riscv32e/qemu_riscv32e.yaml @@ -6,7 +6,6 @@ simulation: arch: riscv toolchain: - zephyr - - xtools supported: - netif testing: diff --git a/boards/qemu/x86/qemu_x86.yaml b/boards/qemu/x86/qemu_x86.yaml index 09ed538e457cd..5188e5253b2cf 100644 --- a/boards/qemu/x86/qemu_x86.yaml +++ b/boards/qemu/x86/qemu_x86.yaml @@ -7,7 +7,6 @@ arch: x86 ram: 3000 toolchain: - zephyr - - xtools - llvm supported: - pci diff --git a/boards/qemu/x86/qemu_x86_64.yaml b/boards/qemu/x86/qemu_x86_64.yaml index 5811211385b93..3fa3fd18a3cc4 100644 --- a/boards/qemu/x86/qemu_x86_64.yaml +++ b/boards/qemu/x86/qemu_x86_64.yaml @@ -4,7 +4,6 @@ type: qemu arch: x86 toolchain: - zephyr - - xtools simulation: - name: qemu supported: diff --git a/boards/qemu/x86/qemu_x86_64_atom_nokpti.yaml b/boards/qemu/x86/qemu_x86_64_atom_nokpti.yaml index 943ee9ae0b661..c776a903163f1 100644 --- a/boards/qemu/x86/qemu_x86_64_atom_nokpti.yaml +++ b/boards/qemu/x86/qemu_x86_64_atom_nokpti.yaml @@ -4,7 +4,6 @@ type: qemu arch: x86 toolchain: - zephyr - - xtools supported: - smp simulation: diff --git a/boards/qemu/x86/qemu_x86_atom_nokpti.yaml b/boards/qemu/x86/qemu_x86_atom_nokpti.yaml index 9620cfc0724a1..83a396d06db3b 100644 --- a/boards/qemu/x86/qemu_x86_atom_nokpti.yaml +++ b/boards/qemu/x86/qemu_x86_atom_nokpti.yaml @@ -6,7 +6,6 @@ simulation: - name: qemu toolchain: - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/qemu/x86/qemu_x86_atom_nommu.yaml b/boards/qemu/x86/qemu_x86_atom_nommu.yaml index e8fac2e2f5722..7e7042a1462cc 100644 --- a/boards/qemu/x86/qemu_x86_atom_nommu.yaml +++ b/boards/qemu/x86/qemu_x86_atom_nommu.yaml @@ -6,7 +6,6 @@ simulation: - name: qemu toolchain: - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/qemu/x86/qemu_x86_atom_nopae.yaml b/boards/qemu/x86/qemu_x86_atom_nopae.yaml index 5809fec52fa02..dfb264fb4743a 100644 --- a/boards/qemu/x86/qemu_x86_atom_nopae.yaml +++ b/boards/qemu/x86/qemu_x86_atom_nopae.yaml @@ -6,7 +6,6 @@ simulation: - name: qemu toolchain: - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/qemu/x86/qemu_x86_atom_virt.yaml b/boards/qemu/x86/qemu_x86_atom_virt.yaml index 782a28ac6882f..8794d17df9faa 100644 --- a/boards/qemu/x86/qemu_x86_atom_virt.yaml +++ b/boards/qemu/x86/qemu_x86_atom_virt.yaml @@ -6,7 +6,6 @@ simulation: - name: qemu toolchain: - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/qemu/x86/qemu_x86_atom_xip.yaml b/boards/qemu/x86/qemu_x86_atom_xip.yaml index ec2cfb9104e0b..6607c68681fe6 100644 --- a/boards/qemu/x86/qemu_x86_atom_xip.yaml +++ b/boards/qemu/x86/qemu_x86_atom_xip.yaml @@ -6,7 +6,6 @@ simulation: - name: qemu toolchain: - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/qemu/x86/qemu_x86_lakemont.yaml b/boards/qemu/x86/qemu_x86_lakemont.yaml index 7f153643b9e4d..3d6103d940424 100644 --- a/boards/qemu/x86/qemu_x86_lakemont.yaml +++ b/boards/qemu/x86/qemu_x86_lakemont.yaml @@ -6,7 +6,6 @@ simulation: arch: x86 toolchain: - zephyr - - xtools - llvm testing: default: true diff --git a/boards/qemu/x86/qemu_x86_tiny.yaml b/boards/qemu/x86/qemu_x86_tiny.yaml index c09f5b5137965..29197ecd6d867 100644 --- a/boards/qemu/x86/qemu_x86_tiny.yaml +++ b/boards/qemu/x86/qemu_x86_tiny.yaml @@ -6,7 +6,6 @@ simulation: - name: qemu toolchain: - zephyr - - xtools testing: default: true only_tags: diff --git a/boards/qemu/xtensa/Kconfig.defconfig b/boards/qemu/xtensa/Kconfig.defconfig index 081971b5e8108..1acc6ce8d4ecf 100644 --- a/boards/qemu/xtensa/Kconfig.defconfig +++ b/boards/qemu/xtensa/Kconfig.defconfig @@ -9,4 +9,9 @@ config BUILD_OUTPUT_BIN config IPM_CONSOLE_STACK_SIZE default 2048 if IPM_CONSOLE_RECEIVER +# Must match XCHAL_DCACHE_LINESIZE form core-isa.h +config DCACHE_LINE_SIZE + default 4 if BOARD_QEMU_XTENSA_SAMPLE_CONTROLLER32_MPU + default 32 + endif # BOARD_QEMU_XTENSA diff --git a/boards/qemu/xtensa/qemu_xtensa_dc233c.yaml b/boards/qemu/xtensa/qemu_xtensa_dc233c.yaml index c0fd17ab84c18..0a69c0347c7bd 100644 --- a/boards/qemu/xtensa/qemu_xtensa_dc233c.yaml +++ b/boards/qemu/xtensa/qemu_xtensa_dc233c.yaml @@ -6,10 +6,11 @@ simulation: arch: xtensa toolchain: - zephyr - - xtools testing: default: true ignore_tags: - net - bluetooth vendor: cdns +ram: 16384 +flash: 32768 diff --git a/boards/qemu/xtensa/qemu_xtensa_dc233c_mmu.yaml b/boards/qemu/xtensa/qemu_xtensa_dc233c_mmu.yaml index b9bbbd8969897..136ac569f9c99 100644 --- a/boards/qemu/xtensa/qemu_xtensa_dc233c_mmu.yaml +++ b/boards/qemu/xtensa/qemu_xtensa_dc233c_mmu.yaml @@ -6,7 +6,6 @@ simulation: arch: xtensa toolchain: - zephyr - - xtools testing: default: true ignore_tags: diff --git a/boards/qorvo/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml b/boards/qorvo/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml index 6503c5a3aae46..b394aee030725 100644 --- a/boards/qorvo/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml +++ b/boards/qorvo/decawave_dwm1001_dev/decawave_dwm1001_dev.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/qorvo/decawave_dwm3001cdk/Kconfig b/boards/qorvo/decawave_dwm3001cdk/Kconfig deleted file mode 100644 index b7e308ed70dce..0000000000000 --- a/boards/qorvo/decawave_dwm3001cdk/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# DecaWave DWM3001CDK board configuration - -# Copyright (c) 2024 The Zephyr Project Contributors -# # SPDX-License-Identifier: Apache-2.0 - -if BOARD_DECAWAVE_DWM3001CDK - -config BOARD_SERIAL_BACKEND_CDC_ACM - bool "Use USB CDC as serial console backend" - default y - -endif # BOARD_DECAWAVE_DWM3001CDK diff --git a/boards/qorvo/decawave_dwm3001cdk/Kconfig.defconfig b/boards/qorvo/decawave_dwm3001cdk/Kconfig.defconfig index e645316caaecb..c814a6c8994d0 100644 --- a/boards/qorvo/decawave_dwm3001cdk/Kconfig.defconfig +++ b/boards/qorvo/decawave_dwm3001cdk/Kconfig.defconfig @@ -8,60 +8,4 @@ if BOARD_DECAWAVE_DWM3001CDK config I2C default SENSOR -if BOARD_SERIAL_BACKEND_CDC_ACM - -config USB_DEVICE_STACK - default y - -config USB_CDC_ACM - default SERIAL - -config CONSOLE - default y - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y if !MCUBOOT && CONSOLE - -config SHELL_BACKEND_SERIAL_CHECK_DTR - default SHELL - depends on UART_LINE_CTRL - -config UART_LINE_CTRL - default y - -config USB_DEVICE_REMOTE_WAKEUP - default n - -if LOG - -# Logger cannot use itself to log -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF -endchoice - -# Set USB log level to error only -choice USB_DEVICE_LOG_LEVEL_CHOICE - default USB_DEVICE_LOG_LEVEL_ERR -endchoice - -endif # LOG - -if USB_DEVICE_STACK - -# Enable UART driver, needed for CDC ACM -config SERIAL - default y - -endif # USB_DEVICE_STACK - -endif # BOARD_SERIAL_BACKEND_CDC_ACM - -DT_CHOSEN_ZEPHYR_CONSOLE := zephyr,console - -config UART_CONSOLE - default y if $(dt_chosen_enabled,$(DT_CHOSEN_ZEPHYR_CONSOLE)) && CONSOLE - endif # BOARD_DECAWAVE_DWM3001CDK diff --git a/boards/qorvo/decawave_dwm3001cdk/board.yml b/boards/qorvo/decawave_dwm3001cdk/board.yml index e62aeef178990..a3a6a767b9c91 100644 --- a/boards/qorvo/decawave_dwm3001cdk/board.yml +++ b/boards/qorvo/decawave_dwm3001cdk/board.yml @@ -1,5 +1,6 @@ board: name: decawave_dwm3001cdk + full_name: Decawave DWM3001CDK vendor: qorvo socs: - name: nrf52833 diff --git a/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk-pinctrl.dtsi b/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk-pinctrl.dtsi index 4bbfe0554977b..b68c634870adc 100644 --- a/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk-pinctrl.dtsi +++ b/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk-pinctrl.dtsi @@ -4,6 +4,21 @@ */ &pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + i2c0_default: i2c0_default { group1 { psels = , diff --git a/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk.dts b/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk.dts index a616dbf2be711..88f85efbde578 100644 --- a/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk.dts +++ b/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk.dts @@ -14,11 +14,11 @@ compatible = "decawave,dwm3001"; chosen { - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,uart-mcumgr = &cdc_acm_uart0; - zephyr,bt-mon-uart = &cdc_acm_uart0; - zephyr,bt-c2h-uart = &cdc_acm_uart0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; @@ -84,6 +84,15 @@ status = "okay"; }; +&uart0 { + status = "okay"; + compatible = "nordic,nrf-uart"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + &gpio1 { status = "okay"; }; @@ -145,10 +154,6 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; }; ®1 { diff --git a/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk.yaml b/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk.yaml index 50fdad0ba878e..da6ecebeea314 100644 --- a/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk.yaml +++ b/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk.yaml @@ -8,7 +8,6 @@ vendor: decawave toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - usb_device diff --git a/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk_defconfig b/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk_defconfig index c115d16a9d051..7b06dae90852f 100644 --- a/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk_defconfig +++ b/boards/qorvo/decawave_dwm3001cdk/decawave_dwm3001cdk_defconfig @@ -8,3 +8,10 @@ CONFIG_HW_STACK_PROTECTION=y # Enable GPIO CONFIG_GPIO=y + +# Enable UART controller +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/qorvo/decawave_dwm3001cdk/doc/index.rst b/boards/qorvo/decawave_dwm3001cdk/doc/index.rst index 278699aa1b1c7..af592d110db37 100644 --- a/boards/qorvo/decawave_dwm3001cdk/doc/index.rst +++ b/boards/qorvo/decawave_dwm3001cdk/doc/index.rst @@ -1,7 +1,4 @@ -.. _decawave_dwm3001cdk: - -Decawave DWM3001CDK -################### +.. zephyr:board:: decawave_dwm3001cdk Overview ******** @@ -31,30 +28,24 @@ found in :ref:`nordic_segger_flashing`. Then build and flash applications as usual (see :ref:`build_an_application` and :ref:`application_run` for more details). -There are two USB ports, the one farthest from the DWM3001C is connected to the -J-Link debugger and the closer one is connected to the nRF52833, though you need -to use CDC ACM USB to get output over it - -Here is an example for the :zephyr:code-sample:`usb-cdc-acm` application. - -Connect to the bottom USB port, and flash the sample - -.. zephyr-app-commands:: - :zephyr-app: samples/subsys/usb/console - :board: decawave_dwm3001cdk - :goals: build flash - +Here is an example for the :zephyr:code-sample:`hello_world` application. -Then, connect the top USB port and open run your favorite terminal program to -listen for output. +Connect to the bottom micro-USB port labeled as J-Link and run your favorite +terminal program to listen for console output. .. code-block:: console $ minicom -D -b 115200 -Replace :code:`` with the port where the board nRF52 DK -can be found. For example, under Linux, :code:`/dev/ttyACM0`. +Replace :code:`` with the port where the DWM3001CDK board can be +found. For example, under Linux, :code:`/dev/ttyACM0`. + +Then build and flash the application in the usual way. +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: decawave_dwm3001cdk + :goals: build flash References ********** diff --git a/boards/quicklogic/qomu/qomu.yaml b/boards/quicklogic/qomu/qomu.yaml index 7e47a163ac9e0..ca9d4a7edc261 100644 --- a/boards/quicklogic/qomu/qomu.yaml +++ b/boards/quicklogic/qomu/qomu.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/quicklogic/quick_feather/quick_feather.yaml b/boards/quicklogic/quick_feather/quick_feather.yaml index 9342b75994ee3..29e067d1aa144 100644 --- a/boards/quicklogic/quick_feather/quick_feather.yaml +++ b/boards/quicklogic/quick_feather/quick_feather.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/rakwireless/rak11720/rak11720.dts b/boards/rakwireless/rak11720/rak11720.dts index 6ddbd5dd32393..828c676f0dd5f 100644 --- a/boards/rakwireless/rak11720/rak11720.dts +++ b/boards/rakwireless/rak11720/rak11720.dts @@ -8,6 +8,7 @@ #include #include #include "rak11720_apollo3-pinctrl.dtsi" +#include / { model = "RAKwireless RAK11720 WisBlock LPWAN Module"; @@ -19,9 +20,11 @@ zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; zephyr,uart-pipe = &uart0; zephyr,flash-controller = &flash; zephyr,bt_hci = &bt_hci_apollo; + zephyr,code-partition = &slot0_partition; }; aliases { @@ -29,6 +32,8 @@ led0 = &blue_led; led1 = &green_led; lora0 = &lora; + bootloader-led0 = &blue_led; + mcuboot-led0 = &blue_led; }; leds { @@ -53,10 +58,28 @@ #address-cells = <1>; #size-cells = <1>; - /* Set 16KB of storage at the end of the 976KB of flash */ - storage_partition: partition@f0000 { + internal_boot_partition: partition@0 { + label = "internal_bootloader"; + reg = <0x00000000 0xc000>; + }; + + boot_partition: partition@c000 { + label = "mcuboot"; + reg = <0x0000c000 0xc000>; + }; + slot0_partition: partition@18000 { + label = "image-0"; + reg = <0x00018000 0x72000>; + }; + slot1_partition: partition@8a000 { + label = "image-1"; + reg = <0x0008a000 0x72000>; + }; + + /* Set 16KB of storage at the end of the 1024KB of flash */ + storage_partition: partition@fc000 { label = "storage"; - reg = <0x000f0000 0x4000>; + reg = <0x000fc000 0x4000>; }; }; }; diff --git a/boards/rakwireless/rak3172/Kconfig.rak3172 b/boards/rakwireless/rak3172/Kconfig.rak3172 new file mode 100644 index 0000000000000..bdb0e9d6de1d6 --- /dev/null +++ b/boards/rakwireless/rak3172/Kconfig.rak3172 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Kenneth Lu +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RAK3172 + select SOC_STM32WLE5XX diff --git a/boards/rakwireless/rak3172/board.cmake b/boards/rakwireless/rak3172/board.cmake new file mode 100644 index 0000000000000..8d07af6287391 --- /dev/null +++ b/boards/rakwireless/rak3172/board.cmake @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Kenneth Lu +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(pyocd "--target=stm32wle5ccux") +board_runner_args(pyocd "--flash-opt=-O cmsis_dap.limit_packets=1") +board_runner_args(jlink "--device=STM32WLE5CC" "--speed=4000" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/rakwireless/rak3172/board.yml b/boards/rakwireless/rak3172/board.yml new file mode 100644 index 0000000000000..0e6400c3aeea4 --- /dev/null +++ b/boards/rakwireless/rak3172/board.yml @@ -0,0 +1,6 @@ +board: + name: rak3172 + full_name: RAK3172 + vendor: rakwireless + socs: + - name: stm32wle5xx diff --git a/boards/rakwireless/rak3172/doc/img/pinout.webp b/boards/rakwireless/rak3172/doc/img/pinout.webp new file mode 100644 index 0000000000000..038a4ba2a5ec7 Binary files /dev/null and b/boards/rakwireless/rak3172/doc/img/pinout.webp differ diff --git a/boards/rakwireless/rak3172/doc/img/rak3172.webp b/boards/rakwireless/rak3172/doc/img/rak3172.webp new file mode 100644 index 0000000000000..af4904399ed91 Binary files /dev/null and b/boards/rakwireless/rak3172/doc/img/rak3172.webp differ diff --git a/boards/rakwireless/rak3172/doc/index.rst b/boards/rakwireless/rak3172/doc/index.rst new file mode 100644 index 0000000000000..328dd433a8522 --- /dev/null +++ b/boards/rakwireless/rak3172/doc/index.rst @@ -0,0 +1,126 @@ +.. zephyr:board:: rak3172 + +Overview +******** + +RAK3172 is a WisDuo LPWAN module which integrating a STM32WLE5CC chip. +The breakout board has the RAK3172 as its core and with soldered to the +antenna connector. + +Hardware +******** + +The breakout board footprint allows RAK3172 stamp module pins to be transferred to 2.54 mm headers. +It is designed to easy access to the pins on the board and simplify the evaluation of the RAK3172 +module. + +- RAK3172 STM32WLE5CC Module with LPWAN single-core CortexÂŽ-M4 at 48 MHz +- 256-Kbyte Flash memory and 64-Kbyte SRAM +- RF transceiver LoRaÂŽ modulations +- Hardware encryption AES256-bit and a True random number generator +- SMA connectors for the LORA antenna +- I/O ports: + + - UART + - I2C + - SPI + - SWD + +.. image:: img/pinout.webp + :align: center + :alt: RAK3172-pinout + +For more information about the RAK3172 stamp module: + +- `WisDuo RAK3172 Website`_ +- `STM32WLE5CC on www.st.com`_ + +Supported Features +================== + +The ``rak3172`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| AES | on-chip | crypto | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | rtc | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| RADIO | on-chip | LoRa | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: +:zephyr_file:`boards/rakwireless/rak3172/rak3172_defconfig`. + +Programming and Debugging +========================= + +The RAK3172 board can be debugged and flashed with an external debug probe connected +to the SWD pins. +It can also be flashed via `pyOCD`_, but have to install an additional pack to support STM32WL. + +.. code-block:: console + + $ pyocd pack --update + $ pyocd pack --install stm32wl + +Flashing an application +----------------------- + +Connect the board to your host computer and build and flash an application. +The sample application :zephyr:code-sample:`hello_world` is used for this example. +Build the Zephyr kernel and application, then flash it to the device: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rak3172 + :goals: build flash + +Run a serial terminal to connect with your board. By default, ``usart1`` is +accessible via the USB to TTL converter. + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +.. code-block:: console + + Hello World! rak3172/stm32wle5xx + +References +********** + +.. target-notes:: + +.. _WisDuo RAK3172 Website: + https://docs.rakwireless.com/Product-Categories/WisDuo/RAK3172-Module/Overview/#product-description + +.. _STM32WLE5CC on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32wle5cc.html + +.. _pyOCD: + https://github.com/pyocd/pyOCD diff --git a/boards/rakwireless/rak3172/rak3172.dts b/boards/rakwireless/rak3172/rak3172.dts new file mode 100644 index 0000000000000..afd16df61c0b8 --- /dev/null +++ b/boards/rakwireless/rak3172/rak3172.dts @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2024 Kenneth Lu + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "RAKWireless RAK3172 WisDuo LPWAN Module with a STM32WLE5CC SoC"; + compatible = "stm32,rak3172_stm32wl"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + + blue_led: led_2 { + gpios = <&gpioa 1 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + + green_led: led_1 { + gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + }; + + aliases { + led0 = &green_led; + lora0 = &lora; + watchdog0 = &iwdg; + }; +}; + +&lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + +&pll { + div-m = <1>; + mul-n = <6>; + div-r = <2>; + div-q = <2>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + cpu1-prescaler = <1>; + ahb3-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pa12 &i2c2_sda_pa11>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>, + <&rcc STM32_SRC_LSI RTC_SEL(2)>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&clk_lse { + clock-frequency = <32768>; +}; + +&clk_hsi { + status = "okay"; +}; + +&subghzspi { + status = "okay"; + + lora: radio@0 { + status = "okay"; + tx-enable-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; /* FE_CTRL1 */ + rx-enable-gpios = <&gpiob 8 GPIO_ACTIVE_LOW>; /* FE_CTRL2 */ + power-amplifier-output = "rfo-lp"; + rfo-lp-max-power = <14>; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(32)>; + read-only; + }; + + slot0_partition: partition@8000 { + label = "image-0"; + reg = <0x00008000 DT_SIZE_K(108)>; + }; + + slot1_partition: partition@23000 { + label = "image-1"; + reg = <0x00023000 DT_SIZE_K(108)>; + }; + + storage_partition: partition@3e000 { + label = "storage"; + reg = <0x0003e000 DT_SIZE_K(8)>; + }; + }; +}; diff --git a/boards/rakwireless/rak3172/rak3172.yaml b/boards/rakwireless/rak3172/rak3172.yaml new file mode 100644 index 0000000000000..75017423ed671 --- /dev/null +++ b/boards/rakwireless/rak3172/rak3172.yaml @@ -0,0 +1,19 @@ +identifier: rak3172 +name: RAK3172 LoRa STM32WL +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 64 +flash: 256 +supported: + - counter + - gpio + - i2c + - nvs + - spi + - uart + - watchdog + - lora +vendor: rak diff --git a/boards/rakwireless/rak3172/rak3172_defconfig b/boards/rakwireless/rak3172/rak3172_defconfig new file mode 100644 index 0000000000000..a177820ad78bb --- /dev/null +++ b/boards/rakwireless/rak3172/rak3172_defconfig @@ -0,0 +1,18 @@ +# Enable UART driver +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable Clocks +CONFIG_CLOCK_CONTROL=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/rakwireless/rak4631/rak4631_nrf52840.dts b/boards/rakwireless/rak4631/rak4631_nrf52840.dts index de485c86bc1be..5c9b846edf6e6 100644 --- a/boards/rakwireless/rak4631/rak4631_nrf52840.dts +++ b/boards/rakwireless/rak4631/rak4631_nrf52840.dts @@ -56,6 +56,7 @@ &uicr { gpio-as-nreset; + nfct-pins-as-gpios; }; &gpiote { @@ -118,7 +119,6 @@ reg = <0>; reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; busy-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; - tx-enable-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; rx-enable-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; dio1-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; dio2-tx-enable; diff --git a/boards/rakwireless/rak4631/rak4631_nrf52840.yaml b/boards/rakwireless/rak4631/rak4631_nrf52840.yaml index f8b3e23582699..342b30b8f7fe8 100644 --- a/boards/rakwireless/rak4631/rak4631_nrf52840.yaml +++ b/boards/rakwireless/rak4631/rak4631_nrf52840.yaml @@ -7,7 +7,6 @@ ram: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/rakwireless/rak5010/rak5010_nrf52840.yaml b/boards/rakwireless/rak5010/rak5010_nrf52840.yaml index 2b947436b2620..41c9a3e378932 100644 --- a/boards/rakwireless/rak5010/rak5010_nrf52840.yaml +++ b/boards/rakwireless/rak5010/rak5010_nrf52840.yaml @@ -7,7 +7,6 @@ ram: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/raspberrypi/common/rpi_pico-led.dtsi b/boards/raspberrypi/common/rpi_pico-led.dtsi new file mode 100644 index 0000000000000..951e36260f200 --- /dev/null +++ b/boards/raspberrypi/common/rpi_pico-led.dtsi @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Pico and Pico 2 boards (but not Pico W) have a common LED placement. */ +/ { + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; + label = "LED"; + }; + }; + + pwm_leds { + compatible = "pwm-leds"; + status = "disabled"; + pwm_led0: pwm_led_0 { + pwms = <&pwm 9 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM_LED"; + }; + }; + + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + }; +}; diff --git a/boards/raspberrypi/common/rpi_pico-pinctrl-common.dtsi b/boards/raspberrypi/common/rpi_pico-pinctrl-common.dtsi new file mode 100644 index 0000000000000..66ccfd2089592 --- /dev/null +++ b/boards/raspberrypi/common/rpi_pico-pinctrl-common.dtsi @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Yonatan Schachter + * SPDX-License-Identifier: Apache-2.0 + */ + +/* The Pico and Pico 2 are pin compatible. */ +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , ; + input-enable; + input-schmitt-enable; + }; + }; + + i2c1_default: i2c1_default { + group1 { + pinmux = , ; + input-enable; + input-schmitt-enable; + }; + }; + + spi0_default: spi0_default { + group1 { + pinmux = , , ; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + + pwm_ch4b_default: pwm_ch4b_default { + group1 { + pinmux = ; + }; + }; + + adc_default: adc_default { + group1 { + pinmux = , , , ; + input-enable; + }; + }; +}; diff --git a/boards/raspberrypi/rpi_5/doc/index.rst b/boards/raspberrypi/rpi_5/doc/index.rst index ea3b3c4243a96..6285e425c252e 100644 --- a/boards/raspberrypi/rpi_5/doc/index.rst +++ b/boards/raspberrypi/rpi_5/doc/index.rst @@ -41,11 +41,17 @@ The Raspberry Pi 5 board configuration supports the following hardware features: - N/A - :dtcompatible:`arm,gic-v2` * - GPIO + - :kconfig:option:`CONFIG_GPIO` + - :dtcompatible:`raspberrypi,rp1-gpio` + * - GPIO (Internal) - :kconfig:option:`CONFIG_GPIO` - :dtcompatible:`brcm,brcmstb-gpio` * - UART - :kconfig:option:`CONFIG_SERIAL` - :dtcompatible:`arm,pl011` + * - PCIE + - :kconfig:option:`CONFIG_PCIE` + - :dtcompatible:`brcm,brcmstb-pcie` Not all hardware features are supported yet. See `Raspberry Pi hardware`_ for the complete list of hardware features. diff --git a/boards/raspberrypi/rpi_5/rpi_5.dts b/boards/raspberrypi/rpi_5/rpi_5.dts index 6fca0efd3d0c6..3f942d4e6f501 100644 --- a/boards/raspberrypi/rpi_5/rpi_5.dts +++ b/boards/raspberrypi/rpi_5/rpi_5.dts @@ -23,6 +23,7 @@ zephyr,sram = &sram0; zephyr,console = &uart10; zephyr,shell-uart = &uart10; + zephyr,pcie-controller = &pcie1; }; leds { @@ -43,3 +44,7 @@ status = "okay"; current-speed = <115200>; }; + +&gpio0_0 { + status = "okay"; +}; diff --git a/boards/raspberrypi/rpi_5/rpi_5_defconfig b/boards/raspberrypi/rpi_5/rpi_5_defconfig index bc0375e812034..55855307b4daa 100644 --- a/boards/raspberrypi/rpi_5/rpi_5_defconfig +++ b/boards/raspberrypi/rpi_5/rpi_5_defconfig @@ -8,3 +8,6 @@ CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME=y CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y + +CONFIG_PCIE=y +CONFIG_PCIE_CONTROLLER=y diff --git a/boards/raspberrypi/rpi_pico/Kconfig.defconfig b/boards/raspberrypi/rpi_pico/Kconfig.defconfig index d3a7429fedb45..71c4fd9c43f25 100644 --- a/boards/raspberrypi/rpi_pico/Kconfig.defconfig +++ b/boards/raspberrypi/rpi_pico/Kconfig.defconfig @@ -13,4 +13,15 @@ endif # I2C_DW config USB_SELF_POWERED default n +if BOARD_RPI_PICO_RP2040_W && WIFI_AIROC + +config MAIN_STACK_SIZE + default 4096 + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 16384 + +endif # BOARD_RPI_PICO_RP2040_W && WIFI_AIROC + endif # BOARD_RPI_PICO diff --git a/boards/raspberrypi/rpi_pico/doc/index.rst b/boards/raspberrypi/rpi_pico/doc/index.rst index 47ce4401f66bf..43937c50bd972 100644 --- a/boards/raspberrypi/rpi_pico/doc/index.rst +++ b/boards/raspberrypi/rpi_pico/doc/index.rst @@ -3,16 +3,20 @@ Overview ******** -The Raspberry Pi Pico and Pico W are small, low-cost, versatile boards from -Raspberry Pi. They are equipped with an RP2040 SoC, an on-board LED, -a USB connector, and an SWD interface. The Pico W additionally contains an -Infineon CYW43439 2.4 GHz Wi-Fi/Bluetooth module. The USB bootloader allows the -ability to flash without any adapter, in a drag-and-drop manner. +The `Raspberry Pi Pico`_ and Pico W are small, low-cost, versatile boards from +Raspberry Pi. They are equipped with an `RP2040 `_ SoC, an on-board LED, +a USB connector, and an SWD interface. + +The Pico W additionally contains an `Infineon CYW43439`_ 2.4 GHz Wi-Fi/Bluetooth module. + +The USB bootloader allows the ability to flash without any adapter, +in a drag-and-drop manner. It is also possible to flash and debug the boards with their SWD interface, using an external adapter. Hardware ******** + - Dual core Arm Cortex-M0+ processor running up to 133MHz - 264KB on-chip SRAM - 2MB on-board QSPI flash with XIP capabilities @@ -44,7 +48,7 @@ Hardware Supported Features ================== -The rpi_pico board configuration supports the following +The ``rpi_pico`` board configuration supports the following hardware features: .. list-table:: @@ -85,16 +89,12 @@ hardware features: - :dtcompatible:`raspberrypi,pico-pwm` * - Flash - :kconfig:option:`CONFIG_FLASH` - - :dtcompatible:`raspberrypi,pico-flash` + - :dtcompatible:`raspberrypi,pico-flash-controller` * - Clock controller - :kconfig:option:`CONFIG_CLOCK_CONTROL` - :dtcompatible:`raspberrypi,pico-clock-controller` - * - UART (PIO) - - :kconfig:option:`CONFIG_SERIAL` - - :dtcompatible:`raspberrypi,pico-uart-pio` - * - SPI (PIO) - - :kconfig:option:`CONFIG_SPI` - - :dtcompatible:`raspberrypi,pico-spi-pio` + +.. _rpi_pico_pin_mapping: Pin Mapping =========== @@ -131,7 +131,8 @@ Default Zephyr Peripheral Mapping: Programmable I/O (PIO) ********************** -The RP2040 SoC comes with two PIO periherals. These are two simple + +The RP2040 SoC comes with two PIO peripherals. These are two simple co-processors that are designed for I/O operations. The PIOs run a custom instruction set, generated from a custom assembly language. PIO programs are assembled using :command:`pioasm`, a tool provided by Raspberry Pi. @@ -150,17 +151,79 @@ combination of GPIO pins for an SPI bus, as well as allowing up to four independent SPI buses on a single board (using the two SPI devices as well as both PIO devices). +.. _rpi_pico_pio_based_features: + +PIO Based Features +================== + +Raspberry Pi Pico's PIO is a programmable chip that can implement a variety of peripherals. + +.. list-table:: + :header-rows: 1 + + * - Peripheral + - Kconfig option + - Devicetree compatible + * - UART (PIO) + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart-pio` + * - SPI (PIO) + - :kconfig:option:`CONFIG_SPI` + - :dtcompatible:`raspberrypi,pico-spi-pio` + * - WS2812 (PIO) + - :kconfig:option:`CONFIG_LED_STRIP` + - :dtcompatible:`worldsemi,ws2812-rpi_pico-pio` + Programming and Debugging ************************* +Applications for the ``rpi_pico`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +System requirements +=================== + +Prerequisites for the Pico W +---------------------------- + +Building for the Raspberry Pi Pico W requires the AIROC binary blobs +provided by Infineon. Run the command below to retrieve those files: + +.. code-block:: console + + west blobs fetch hal_infineon + +.. note:: + + It is recommended running the command above after :file:`west update`. + +Debug Probe and Host Tools +-------------------------- + +Several debugging tools support the Raspberry Pi Pico. +The `Raspberry Pi Debug Probe`_ is an easy-to-obtain CMSIS-DAP adapter +officially provided by the Raspberry Pi Foundation, +making it a convenient choice for debugging ``rpi_pico``. + +It can be used with + +- :ref:`openocd-debug-host-tools` +- :ref:`pyocd-debug-host-tools` + +OpenOCD is the default for ``rpi_pico``. + +- `SEGGER J-Link`_ +- `Black Magic Debug Probe `_ + +can also be used. +These are used with dedicated probes. + Flashing ======== -Using SEGGER JLink ------------------- - -You can Flash the rpi_pico with a SEGGER JLink debug probe as described in -:ref:`Building, Flashing and Debugging `. +The ``rpi_pico`` can flash with Zephyr's standard method. +See also :ref:`Building, Flashing and Debugging`. Here is an example of building and flashing the :zephyr:code-sample:`blinky` application. @@ -169,51 +232,42 @@ Here is an example of building and flashing the :zephyr:code-sample:`blinky` app :board: rpi_pico :goals: build -.. code-block:: bash +.. code-block:: console west flash --runner jlink -Using OpenOCD -------------- - -To use CMSIS-DAP, You must configure **udev**. -Create a file in /etc/udev.rules.d with any name, and write the line below. +.. _rpi_pico_flashing_using_openocd: -.. code-block:: bash - - ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", MODE="660", GROUP="plugdev", TAG+="uaccess" +Using OpenOCD +------------- -This example is valid for the case that the user joins to ``plugdev`` groups. +To use a debugging adapter such as the Raspberry Pi Debug Probe, +You must configure **udev**. Refer to :ref:`setting-udev-rules` for details. The Raspberry Pi Pico has an SWD interface that can be used to program -and debug the on board RP2040. This interface can be utilized by OpenOCD. -To use it with the RP2040, OpenOCD version 0.12.0 or later is needed. +and debug the onboard SoC. This interface can be used with OpenOCD. +To use it, OpenOCD version 0.12.0 or later is needed. If you are using a Debian based system (including RaspberryPi OS, Ubuntu. and more), using the `pico_setup.sh`_ script is a convenient way to set up the forked version of OpenOCD. -Depending on the interface used (such as JLink), you might need to -checkout to a branch that supports this interface, before proceeding. -Build and install OpenOCD as described in the README. - Here is an example of building and flashing the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky :board: rpi_pico :goals: build flash - :gen-args: -DOPENOCD=/usr/local/bin/openocd -DOPENOCD_DEFAULT_PATH=/usr/local/share/openocd/scripts -DRPI_PICO_DEBUG_ADAPTER=cmsis-dap + :gen-args: -DOPENOCD=/usr/local/bin/openocd -DRPI_PICO_DEBUG_ADAPTER=cmsis-dap -Set the environment variables **OPENOCD** to :file:`/usr/local/bin/openocd` -and **OPENOCD_DEFAULT_PATH** to :file:`/usr/local/share/openocd/scripts`. This should work +Set the CMake option **OPENOCD** to :file:`/usr/local/bin/openocd`. This should work with the OpenOCD that was installed with the default configuration. This configuration also works with an environment that is set up by the `pico_setup.sh`_ script. **RPI_PICO_DEBUG_ADAPTER** specifies what debug adapter is used for debugging. -If **RPI_PICO_DEBUG_ADAPTER** was not assigned, ``cmsis-dap`` is used by default. -The other supported adapters are ``raspberrypi-swd``, ``jlink`` and ``blackmagicprobe``. +If **RPI_PICO_DEBUG_ADAPTER** was not set, ``cmsis-dap`` is used by default. +The ``raspberrypi-swd`` and ``jlink`` are verified to work. How to connect ``cmsis-dap`` and ``raspberrypi-swd`` is described in `Getting Started with Raspberry Pi Pico`_. Any other SWD debug adapter maybe also work with this configuration. @@ -224,12 +278,7 @@ The value of **RPI_PICO_DEBUG_ADAPTER** is cached, so it can be omitted from **RPI_PICO_DEBUG_ADAPTER** is used in an argument to OpenOCD as ``"source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]"``. Thus, **RPI_PICO_DEBUG_ADAPTER** needs to be assigned the file name of the debug adapter. -You can also flash the board with the following -command that directly calls OpenOCD (assuming a SEGGER JLink adapter is used): - -.. code-block:: console - - $ openocd -f interface/jlink.cfg -c 'transport select swd' -f target/rp2040.cfg -c "adapter speed 2000" -c 'targets rp2040.core0' -c 'program path/to/zephyr.elf verify reset exit' +.. _rpi_pico_flashing_using_uf2: Using UF2 --------- @@ -243,59 +292,48 @@ UF2 file should be drag-and-dropped to the device, which will flash the Pico. Debugging ========= -The SWD interface can also be used to debug the board. To achieve this, you can -either use SEGGER JLink or OpenOCD. - -Using SEGGER JLink ------------------- - -Use a SEGGER JLink debug probe and follow the instruction in -:ref:`Building, Flashing and Debugging`. - - -Using OpenOCD -------------- - -Install OpenOCD as described for flashing the board. - -Here is an example for debugging the :zephyr:code-sample:`blinky` application. +Like flashing, debugging can also be performed using Zephyr's standard method +(see :ref:`application_run`). +The following sample demonstrates how to debug using OpenOCD and +the `Raspberry Pi Debug Probe`_. .. zephyr-app-commands:: :zephyr-app: samples/basic/blinky :board: rpi_pico :maybe-skip-config: :goals: debug - :gen-args: -DOPENOCD=/usr/local/bin/openocd -DOPENOCD_DEFAULT_PATH=/usr/local/share/openocd/scripts -DRPI_PICO_DEBUG_ADAPTER=raspberrypi-swd - -As with flashing, you can specify the debug adapter by specifying **RPI_PICO_DEBUG_ADAPTER** -at ``west build`` time. No needs to specify it at ``west debug`` time. + :gen-args: -DOPENOCD=/usr/local/bin/openocd -DRPI_PICO_DEBUG_ADAPTER=cmsis-dap -You can also debug with OpenOCD and gdb launching from command-line. -Run the following command: +The default debugging tool is ``openocd``. +If you use a different tool, specify it with the ``--runner``, +such as ``jlink``. -.. code-block:: console +If you use OpenOCD, see also the description about flashing :ref:`rpi_pico_flashing_using_uf2` +for more information. - $ openocd -f interface/jlink.cfg -c 'transport select swd' -f target/rp2040.cfg -c "adapter speed 2000" -c 'targets rp2040.core0' -On another terminal, run: - -.. code-block:: console - - $ gdb-multiarch +.. target-notes:: -Inside gdb, run: +.. _Raspberry Pi Pico: + https://www.raspberrypi.com/products/raspberry-pi-pico/ -.. code-block:: console +.. _RP2040 Datasheet: + https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf - (gdb) tar ext :3333 - (gdb) file path/to/zephyr.elf - -You can then start debugging the board. - -.. target-notes:: +.. _Infineon CYW43439: + https://www.infineon.com/cms/en/product/wireless-connectivity/airoc-wi-fi-plus-bluetooth-combos/wi-fi-4-802.11n/cyw43439/ .. _pico_setup.sh: https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh .. _Getting Started with Raspberry Pi Pico: - https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf + https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf + +.. _Raspberry Pi Debug Probe: + https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html + +.. _SEGGER J-Link: + https://www.segger.com/products/debug-probes/j-link/ + +.. _Black Magic Debug: + https://black-magic.org/ diff --git a/boards/raspberrypi/rpi_pico/rpi_pico-pinctrl.dtsi b/boards/raspberrypi/rpi_pico/rpi_pico-pinctrl.dtsi index 747b0d04e4095..5556638daa6d8 100644 --- a/boards/raspberrypi/rpi_pico/rpi_pico-pinctrl.dtsi +++ b/boards/raspberrypi/rpi_pico/rpi_pico-pinctrl.dtsi @@ -5,53 +5,4 @@ #include -&pinctrl { - uart0_default: uart0_default { - group1 { - pinmux = ; - }; - group2 { - pinmux = ; - input-enable; - }; - }; - - i2c0_default: i2c0_default { - group1 { - pinmux = , ; - input-enable; - input-schmitt-enable; - }; - }; - - i2c1_default: i2c1_default { - group1 { - pinmux = , ; - input-enable; - input-schmitt-enable; - }; - }; - - spi0_default: spi0_default { - group1 { - pinmux = , , ; - }; - group2 { - pinmux = ; - input-enable; - }; - }; - - pwm_ch4b_default: pwm_ch4b_default { - group1 { - pinmux = ; - }; - }; - - adc_default: adc_default { - group1 { - pinmux = , , , ; - input-enable; - }; - }; -}; +#include "../common/rpi_pico-pinctrl-common.dtsi" diff --git a/boards/raspberrypi/rpi_pico/rpi_pico.dts b/boards/raspberrypi/rpi_pico/rpi_pico.dts index 97d721024d749..807dc8e780053 100644 --- a/boards/raspberrypi/rpi_pico/rpi_pico.dts +++ b/boards/raspberrypi/rpi_pico/rpi_pico.dts @@ -7,27 +7,4 @@ /dts-v1/; #include "rpi_pico-common.dtsi" - -/ { - leds { - compatible = "gpio-leds"; - led0: led_0 { - gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; - label = "LED"; - }; - }; - - pwm_leds { - compatible = "pwm-leds"; - status = "disabled"; - pwm_led0: pwm_led_0 { - pwms = <&pwm 9 PWM_MSEC(20) PWM_POLARITY_NORMAL>; - label = "PWM_LED"; - }; - }; - - aliases { - led0 = &led0; - pwm-led0 = &pwm_led0; - }; -}; +#include "../common/rpi_pico-led.dtsi" diff --git a/boards/raspberrypi/rpi_pico/rpi_pico.yaml b/boards/raspberrypi/rpi_pico/rpi_pico.yaml index 80de519dad540..696d9971ab5f4 100644 --- a/boards/raspberrypi/rpi_pico/rpi_pico.yaml +++ b/boards/raspberrypi/rpi_pico/rpi_pico.yaml @@ -7,7 +7,6 @@ ram: 264 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio diff --git a/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.dts b/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.dts index ae01f15d69784..cba2142f7b575 100644 --- a/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.dts +++ b/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 Dave Rensberger - Beechwoods Software + * Copyright (c) 2024 Steve Boylan * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,3 +8,60 @@ /dts-v1/; #include "rpi_pico-common.dtsi" + +&pinctrl { + pio0_spi0_default: pio0_spi0_default { + /* gpio 25 is used for chip select, not assigned to the PIO */ + group1 { + pinmux = ; + }; + }; + + airoc_wifi_default: airoc_wifi_default { + /* Control of GPIO24 is done through the WiFi driver */ + group1 { + pinmux = ; + input-enable; + }; + }; + + airoc_wifi_host_wake: airoc_wifi_host_wake { + /* Assign GPIO24 to SIO (GPIO) for use as an interrupt source */ + group1 { + /* Lacking a specific SIO pin definition, use the RP2040_PINMUX macro */ + pinmux = ; + input-enable; + }; + }; +}; + +&pio0 { + status = "okay"; + + pio0_spi0: pio0_spi0 { + compatible = "raspberrypi,pico-spi-pio"; + clocks = < &clocks RPI_PICO_CLKID_CLK_SYS >; + #address-cells = <1>; + #size-cells = <0>; + cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + clk-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; + sio-gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pio0_spi0_default>; + pinctrl-names = "default"; + status = "okay"; + airoc-wifi@0 { + compatible = "infineon,airoc-wifi"; + reg = < 0 >; + wifi-reg-on-gpios = < &gpio0 23 GPIO_ACTIVE_HIGH >; + bus-select-gpios = < &gpio0 24 GPIO_ACTIVE_HIGH >; + wifi-host-wake-gpios = < &gpio0 24 GPIO_ACTIVE_HIGH >; + spi-max-frequency = < 10000000 >; + spi-half-duplex; + spi-data-irq-shared; + pinctrl-0 = <&airoc_wifi_default>; + pinctrl-1 = <&airoc_wifi_host_wake>; + pinctrl-names = "default", "host_wake"; + status = "okay"; + }; + }; +}; diff --git a/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.yaml b/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.yaml index 581645830a778..8ebdd370b0abd 100644 --- a/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.yaml +++ b/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.yaml @@ -7,7 +7,6 @@ ram: 264 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio diff --git a/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w_defconfig b/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w_defconfig index df003531af9c8..d1e96b968c5e8 100644 --- a/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w_defconfig +++ b/boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w_defconfig @@ -9,3 +9,6 @@ CONFIG_BUILD_OUTPUT_HEX=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_RESET=y CONFIG_CLOCK_CONTROL=y + +# Default networking configuration +CONFIG_CYW43439=y diff --git a/boards/raspberrypi/rpi_pico2/Kconfig.defconfig b/boards/raspberrypi/rpi_pico2/Kconfig.defconfig new file mode 100644 index 0000000000000..d122f3e4918aa --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RPI_PICO2 + +config USB_SELF_POWERED + default n + +endif # BOARD_RPI_PICO2 diff --git a/boards/raspberrypi/rpi_pico2/Kconfig.rpi_pico2 b/boards/raspberrypi/rpi_pico2/Kconfig.rpi_pico2 new file mode 100644 index 0000000000000..bcce97758fbe4 --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/Kconfig.rpi_pico2 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RPI_PICO2 + select SOC_RP2350A_M33 if BOARD_RPI_PICO2_RP2350A_M33 diff --git a/boards/raspberrypi/rpi_pico2/board.cmake b/boards/raspberrypi/rpi_pico2/board.cmake new file mode 100644 index 0000000000000..feae063129ac7 --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/board.cmake @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 + +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +board_runner_args(openocd --cmd-pre-init "source [find target/rp2350.cfg]") + +# The adapter speed is expected to be set by interface configuration. +# The Raspberry Pi's OpenOCD fork doesn't, so match their documentation at +# https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#debugging-with-swd +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 5000") + +board_runner_args(uf2 "--board-id=RP2350") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) diff --git a/boards/raspberrypi/rpi_pico2/board.yml b/boards/raspberrypi/rpi_pico2/board.yml new file mode 100644 index 0000000000000..2ab8ee599891e --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/board.yml @@ -0,0 +1,6 @@ +board: + name: rpi_pico2 + full_name: Raspberry Pi Pico 2 + vendor: raspberrypi + socs: + - name: rp2350a diff --git a/boards/raspberrypi/rpi_pico2/doc/img/rpi_pico2.webp b/boards/raspberrypi/rpi_pico2/doc/img/rpi_pico2.webp new file mode 100644 index 0000000000000..6a4895ba7b285 Binary files /dev/null and b/boards/raspberrypi/rpi_pico2/doc/img/rpi_pico2.webp differ diff --git a/boards/raspberrypi/rpi_pico2/doc/index.rst b/boards/raspberrypi/rpi_pico2/doc/index.rst new file mode 100644 index 0000000000000..1457a8b849e49 --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/doc/index.rst @@ -0,0 +1,93 @@ +.. zephyr:board:: rpi_pico2 + +Overview +******** + +The Raspberry Pi Pico 2 is the second-generation product in the Raspberry Pi +Pico family. From the `Raspberry Pi website `_ is referred to as Pico 2. + +There are many limitations of the board currently. Including but not limited to: +- The Zephyr build only supports configuring the RP2350A with the Cortex-M33 cores. +- As with the Pico 1, there's no support for running any code on the second core. + +Hardware +******** + +- Dual Cortex-M33 or Hazard3 processors at up to 150MHz +- 520KB of SRAM, and 4MB of on-board flash memory +- USB 1.1 with device and host support +- Low-power sleep and dormant modes +- Drag-and-drop programming using mass storage over USB +- 26 multi-function GPIO pins including 3 that can be used for ADC +- 2 SPI, 2 I2C, 2 UART, 3 12-bit 500ksps Analogue to Digital - Converter (ADC), 24 controllable PWM channels +- 2 Timer with 4 alarms, 1 AON Timer +- Temperature sensor +- 3 Programmable IO (PIO) blocks, 12 state machines total for custom peripheral support + + - Flexible, user-programmable high-speed IO + - Can emulate interfaces such as SD Card and VGA + +Supported Features +================== + +The ``rpi_pico2/rp2350a/m33`` board target supports the following +hardware features: + +.. list-table:: + :header-rows: 1 + + * - Peripheral + - Kconfig option + - Devicetree compatible + * - NVIC + - N/A + - :dtcompatible:`arm,v8m-nvic` + * - ADC + - :kconfig:option:`CONFIG_ADC` + - :dtcompatible:`raspberrypi,pico-adc` + * - Clock controller + - :kconfig:option:`CONFIG_CLOCK_CONTROL` + - :dtcompatible:`raspberrypi,pico-clock-controller` + * - Counter + - :kconfig:option:`CONFIG_COUNTER` + - :dtcompatible:`raspberrypi,pico-timer` + * - DMA + - :kconfig:option:`CONFIG_DMA` + - :dtcompatible:`raspberrypi,pico-dma` + * - GPIO + - :kconfig:option:`CONFIG_GPIO` + - :dtcompatible:`raspberrypi,pico-gpio` + * - HWINFO + - :kconfig:option:`CONFIG_HWINFO` + - N/A + * - I2C + - :kconfig:option:`CONFIG_I2C` + - :dtcompatible:`snps,designware-i2c` + * - PWM + - :kconfig:option:`CONFIG_PWM` + - :dtcompatible:`raspberrypi,pico-pwm` + * - SPI + - :kconfig:option:`CONFIG_SPI` + - :dtcompatible:`raspberrypi,pico-spi` + * - UART + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart` + * - UART (PIO) + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`raspberrypi,pico-uart-pio` + +Connections and IOs +=================== + +The default pin mapping is unchanged from the Pico 1 (see :ref:`rpi_pico_pin_mapping`). + +Programming and Debugging +************************* + +As with the Pico 1, the SWD interface can be used to program and debug the +device, e.g. using OpenOCD with the `Raspberry Pi Debug Probe `_ . + +References +********** + +.. target-notes:: diff --git a/boards/raspberrypi/rpi_pico2/rpi_pico2-pinctrl.dtsi b/boards/raspberrypi/rpi_pico2/rpi_pico2-pinctrl.dtsi new file mode 100644 index 0000000000000..a7841dc2da6ce --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/rpi_pico2-pinctrl.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024, Andrew Featherstone + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "../common/rpi_pico-pinctrl-common.dtsi" diff --git a/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi b/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi new file mode 100644 index 0000000000000..85cdb97e8457e --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +#include "rpi_pico2-pinctrl.dtsi" +#include "../common/rpi_pico-led.dtsi" + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,code-partition = &code_partition; + }; + + aliases { + watchdog0 = &wdt0; + }; + + pico_header: connector { + compatible = "raspberrypi,pico-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 0 0>, /* GP0 */ + <1 0 &gpio0 1 0>, /* GP1 */ + <2 0 &gpio0 2 0>, /* GP2 */ + <3 0 &gpio0 3 0>, /* GP3 */ + <4 0 &gpio0 4 0>, /* GP4 */ + <5 0 &gpio0 5 0>, /* GP5 */ + <6 0 &gpio0 6 0>, /* GP6 */ + <7 0 &gpio0 7 0>, /* GP7 */ + <8 0 &gpio0 8 0>, /* GP8 */ + <9 0 &gpio0 9 0>, /* GP9 */ + <10 0 &gpio0 10 0>, /* GP10 */ + <11 0 &gpio0 11 0>, /* GP11 */ + <12 0 &gpio0 12 0>, /* GP12 */ + <13 0 &gpio0 13 0>, /* GP13 */ + <14 0 &gpio0 14 0>, /* GP14 */ + <15 0 &gpio0 15 0>, /* GP15 */ + <16 0 &gpio0 16 0>, /* GP16 */ + <17 0 &gpio0 17 0>, /* GP17 */ + <18 0 &gpio0 18 0>, /* GP18 */ + <19 0 &gpio0 19 0>, /* GP19 */ + <20 0 &gpio0 20 0>, /* GP20 */ + <21 0 &gpio0 21 0>, /* GP21 */ + <22 0 &gpio0 22 0>, /* GP22 */ + <26 0 &gpio0 26 0>, /* GP26 */ + <27 0 &gpio0 27 0>, /* GP27 */ + <28 0 &gpio0 28 0>; /* GP28 */ + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(4)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for an image definition block. The block is much + * smaller than 256 bytes, but in practice the linker places the vector + * table at a much larger alignment offset. + */ + image_def: partition@0 { + label = "image_def"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the image definition block. + * The partition size is 4MB minus the 0x100 bytes taken by the + * image definition. + */ + code_partition: partition@100 { + label = "code-partition"; + reg = <0x100 (DT_SIZE_M(4) - 0x100)>; + read-only; + }; + }; +}; + +&uart0 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&gpio0 { + status = "okay"; +}; + +&spi0 { + clock-frequency = ; + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; +}; + +&i2c0 { + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + clock-frequency = ; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&adc { + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pwm { + pinctrl-0 = <&pwm_ch4b_default>; + pinctrl-names = "default"; + divider-int-0 = <255>; +}; + +&timer0 { + status = "okay"; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +pico_serial: &uart0 {}; diff --git a/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.dts b/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.dts new file mode 100644 index 0000000000000..f96491f44e2e5 --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +/* The build system assumes that there's a cpucluster-specific file. + * + * This file provides composition of the device tree: + * 1. The common features of the SoC + * 2. Core-specific configuration. + * 3. Board-specific configuration. + */ +#include +#include + +/* there's nothing specific to the Cortex-M33 cores vs the (not yet + * implemented) Hazard3 cores. + */ +#include "rpi_pico2.dtsi" diff --git a/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.yaml b/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.yaml new file mode 100644 index 0000000000000..810ab165f06e7 --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33.yaml @@ -0,0 +1,20 @@ +identifier: rpi_pico2/rp2350a/m33 +name: Raspberry Pi Pico 2 (Cortex-M33) +type: mcu +arch: arm +flash: 4096 +ram: 520 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock + - counter + - dma + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart diff --git a/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33_defconfig b/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33_defconfig new file mode 100644 index 0000000000000..8bd68e3511391 --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/rpi_pico2_rp2350a_m33_defconfig @@ -0,0 +1,14 @@ +# This configuration is orthogonal to whether the Cortex-M33 or Hazard3 cores +# are in use, but Zephyr does not support providing a qualifier-agnostic +# _defconfig file. +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=150000000 +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/raspberrypi/rpi_pico2/support/openocd.cfg b/boards/raspberrypi/rpi_pico2/support/openocd.cfg new file mode 100644 index 0000000000000..82666bb53314c --- /dev/null +++ b/boards/raspberrypi/rpi_pico2/support/openocd.cfg @@ -0,0 +1,11 @@ +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +# Checking and set 'adapter speed'. +# Set the adaptor speed, if unset, and given as an argument. +proc set_adapter_speed_if_not_set { speed } { + puts "checking adapter speed..." + if { [catch {adapter speed} ret] } { + adapter speed $speed + } +} diff --git a/boards/raytac/mdbt50q_db_33/raytac_mdbt50q_db_33_nrf52833.yaml b/boards/raytac/mdbt50q_db_33/raytac_mdbt50q_db_33_nrf52833.yaml index e0698628e71a5..fa8c20d016333 100644 --- a/boards/raytac/mdbt50q_db_33/raytac_mdbt50q_db_33_nrf52833.yaml +++ b/boards/raytac/mdbt50q_db_33/raytac_mdbt50q_db_33_nrf52833.yaml @@ -10,7 +10,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/raytac/mdbt50q_db_40/raytac_mdbt50q_db_40_nrf52840.yaml b/boards/raytac/mdbt50q_db_40/raytac_mdbt50q_db_40_nrf52840.yaml index cc99eab1a53a4..4a1e5fd20de73 100644 --- a/boards/raytac/mdbt50q_db_40/raytac_mdbt50q_db_40_nrf52840.yaml +++ b/boards/raytac/mdbt50q_db_40/raytac_mdbt50q_db_40_nrf52840.yaml @@ -12,7 +12,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp.yaml b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp.yaml index 44596dc8a5bc7..719c66ec644d6 100644 --- a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp.yaml +++ b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml index d77e8d5c8f0f9..6e0d66b0a41a9 100644 --- a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml +++ b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 192 flash: 192 diff --git a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpunet.yaml b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpunet.yaml index b6badb279f9a9..6bde25d200316 100644 --- a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpunet.yaml +++ b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpunet.yaml @@ -8,7 +8,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml index bd5763672682b..3151f2656856e 100644 --- a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml +++ b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 448 flash: 1024 diff --git a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml index e5340237e6a98..87aafde68e731 100644 --- a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml +++ b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 192 flash: 192 diff --git a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpunet.yaml b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpunet.yaml index eb5cac4d60941..c6684dff068ce 100644 --- a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpunet.yaml +++ b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpunet.yaml @@ -8,7 +8,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/realtek/index.rst b/boards/realtek/index.rst new file mode 100644 index 0000000000000..b15a0a3d34c3a --- /dev/null +++ b/boards/realtek/index.rst @@ -0,0 +1,10 @@ +.. _boards-realtek: + +Realtek +####### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/realtek/rts5912_evb/Kconfig.defconfig b/boards/realtek/rts5912_evb/Kconfig.defconfig new file mode 100644 index 0000000000000..21c1e3c65143f --- /dev/null +++ b/boards/realtek/rts5912_evb/Kconfig.defconfig @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# diff --git a/boards/realtek/rts5912_evb/Kconfig.rts5912_evb b/boards/realtek/rts5912_evb/Kconfig.rts5912_evb new file mode 100644 index 0000000000000..d9e479f42b9c1 --- /dev/null +++ b/boards/realtek/rts5912_evb/Kconfig.rts5912_evb @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config BOARD_RTS5912_EVB + select SOC_RTS5912 diff --git a/boards/realtek/rts5912_evb/board.cmake b/boards/realtek/rts5912_evb/board.cmake new file mode 100644 index 0000000000000..46c6d4bd1ffe4 --- /dev/null +++ b/boards/realtek/rts5912_evb/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/realtek/rts5912_evb/board.yml b/boards/realtek/rts5912_evb/board.yml new file mode 100644 index 0000000000000..8e0e6eb7ebdb9 --- /dev/null +++ b/boards/realtek/rts5912_evb/board.yml @@ -0,0 +1,6 @@ +board: + name: rts5912_evb + full_name: RTS5912 Evaluation Board + vendor: realtek + socs: + - name: rts5912 diff --git a/boards/realtek/rts5912_evb/doc/img/rts5912evb.webp b/boards/realtek/rts5912_evb/doc/img/rts5912evb.webp new file mode 100644 index 0000000000000..e8a7d96420af3 Binary files /dev/null and b/boards/realtek/rts5912_evb/doc/img/rts5912evb.webp differ diff --git a/boards/realtek/rts5912_evb/doc/index.rst b/boards/realtek/rts5912_evb/doc/index.rst new file mode 100644 index 0000000000000..b9832e19ab7b0 --- /dev/null +++ b/boards/realtek/rts5912_evb/doc/index.rst @@ -0,0 +1,85 @@ +.. zephyr:board:: rts5912_evb + +Overview +******** + +The RTS5912 EVB is a development platform to evaluate the Realtek RTS5912 embedded controller. + +Hardware +******** + +- Realtek-M300 Processor (compatible to Cortex-M33) +- Memory: + + - 384 KB SRAM + - 64 KB ROM + - 512 KB Flash(MCM) + - 256 B Battery SRAM +- PECI interface 3.1 +- FAN, PWM and TACHO pins +- 6x I2C instances +- eSPI header +- 1x PS/2 ports +- Keyboard interface headers + +For more information about the evb board please see `RTS5912_EVB_Schematics`_ and `RTS5912_DATASHEET`_ + +The board is powered through the +5V USB Type-C connector or adaptor. + +Supported Features +================== + +The ``rts5912_evb`` supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| PINCTRL | on-chip | pinctrl | ++-----------+------------+-------------------------------------+ +| SCCON | on-chip | clock_control | ++-----------+------------+-------------------------------------+ +| RTMR | on-chip | timer | ++-----------+------------+-------------------------------------+ + +Other hardware features are not currently supported by Zephyr. + +Programming and Debugging +************************* + +Building +======== + +#. Build :zephyr:code-sample:`hello_world` application as you would normally do. + +#. The file ``zephyr.rts5912.bin`` will be created if the build system can build successfully. + This binary image can be found under file "build/zephyr/". + +Flashing +======== + +#. Connect Dediprog into header ``J81`` and ``J82``. +#. Use Dediprog SF600 programmer to write the binary into the external flash ``U10`` at the address 0x0. +#. Power off the board. +#. Set the strap pin ``GPIO108`` to high and power on the board. + +Debugging +========= + +Using SWD or JTAG with ULINPRO. + +References +********** + +.. target-notes:: + +.. _RTS5912_EVB_Schematics: + https://github.com/JasonLin-RealTek/Realtek_EC/blob/main/RTS5912_EVB_Schematic_Ver%201.1_20240701_1407.pdf + +.. _RTS5912_DATASHEET: + https://github.com/JasonLin-RealTek/Realtek_EC/blob/main/RTS5912_datasheet_brief.pdf diff --git a/boards/realtek/rts5912_evb/rts5912_evb.dts b/boards/realtek/rts5912_evb/rts5912_evb.dts new file mode 100644 index 0000000000000..1e22d6c4ace82 --- /dev/null +++ b/boards/realtek/rts5912_evb/rts5912_evb.dts @@ -0,0 +1,36 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * + */ + +/dts-v1/; +#include +#include +#include +/ { + model = "Realtek RTS5912 Evaluation Board"; + compatible = "realtek,rts5912-evb"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,flash = &flash0; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; +}; + +&uart0_wrapper { + status = "okay"; + pinctrl-0 = <&uart_rx_gpio113 &uart_tx_gpio114>; + pinctrl-names = "default"; +}; + +&swj_port { + status = "okay"; +}; diff --git a/boards/realtek/rts5912_evb/rts5912_evb.yaml b/boards/realtek/rts5912_evb/rts5912_evb.yaml new file mode 100644 index 0000000000000..e81e170e7d622 --- /dev/null +++ b/boards/realtek/rts5912_evb/rts5912_evb.yaml @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +identifier: rts5912_evb +name: RTS5912-EVB +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 64 +flash: 320 +supported: + - gpio + - pinmux +vendor: realtek diff --git a/boards/realtek/rts5912_evb/rts5912_evb_defconfig b/boards/realtek/rts5912_evb/rts5912_evb_defconfig new file mode 100644 index 0000000000000..64454c374d597 --- /dev/null +++ b/boards/realtek/rts5912_evb/rts5912_evb_defconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +# Enable RTS5912 image tool +CONFIG_REALTEK_RTS5912_BOOTROM_HEADER=y + +# Serial Driver +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y diff --git a/boards/renesas/da14695_dk_usb/da14695_dk_usb.yaml b/boards/renesas/da14695_dk_usb/da14695_dk_usb.yaml index b85aee119b6cf..d6c2d7efa238f 100644 --- a/boards/renesas/da14695_dk_usb/da14695_dk_usb.yaml +++ b/boards/renesas/da14695_dk_usb/da14695_dk_usb.yaml @@ -6,7 +6,6 @@ ram: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - hwinfo diff --git a/boards/renesas/da1469x_dk_pro/Kconfig.defconfig b/boards/renesas/da1469x_dk_pro/Kconfig.defconfig index 496044aa9b625..3ca13893da157 100644 --- a/boards/renesas/da1469x_dk_pro/Kconfig.defconfig +++ b/boards/renesas/da1469x_dk_pro/Kconfig.defconfig @@ -29,9 +29,6 @@ endif # LVGL if INPUT -config INPUT_FT5336_INTERRUPT - default y - config LV_Z_POINTER_INPUT_MSGQ_COUNT default 70 diff --git a/boards/renesas/da1469x_dk_pro/da1469x_dk_pro.yaml b/boards/renesas/da1469x_dk_pro/da1469x_dk_pro.yaml index 1d988ecbf57ff..1c9a7e2885a1e 100644 --- a/boards/renesas/da1469x_dk_pro/da1469x_dk_pro.yaml +++ b/boards/renesas/da1469x_dk_pro/da1469x_dk_pro.yaml @@ -6,7 +6,6 @@ ram: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - counter diff --git a/boards/renesas/ek_ra2a1/doc/index.rst b/boards/renesas/ek_ra2a1/doc/index.rst index 365a9c2e04eff..95ac49e9fc7de 100644 --- a/boards/renesas/ek_ra2a1/doc/index.rst +++ b/boards/renesas/ek_ra2a1/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra2a1: - -RA2A1 Evaluation Kit -#################### +.. zephyr:board:: ek_ra2a1 Overview ******** @@ -31,12 +28,6 @@ Renesas RA2A1 Microcontroller Group has following features - Watchdog Timer - 49 Input/Output pins -.. figure:: ek_ra2a1.webp - :align: center - :alt: RA2A1 Evaluation Kit - - EK-RA2A1 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** @@ -82,6 +73,14 @@ hardware features: +-----------+------------+-------------------------------+ | COUNTER | on-chip | counter | +-----------+------------+-------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+-------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------+ +| DAC | on-chip | dac | ++-----------+------------+-------------------------------+ The default configuration can be found in :zephyr_file:`boards/renesas/ek_ra2a1/ek_ra2a1_defconfig` diff --git a/boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi b/boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi index 554b44803d6a5..690f5736c7596 100644 --- a/boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi +++ b/boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi @@ -26,4 +26,29 @@ ; }; }; + + pwm0_default: pwm0_default { + group1 { + /* GTIOC0A GTIOC0B */ + psels = , + ; + }; + }; + + iic0_default: iic0_default { + group1 { + /* SCL0 SDA0 */ + psels = , + ; + drive-strength = "medium"; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; }; diff --git a/boards/renesas/ek_ra2a1/ek_ra2a1.dts b/boards/renesas/ek_ra2a1/ek_ra2a1.dts index 1bb06419ca957..74b3fc3d57709 100644 --- a/boards/renesas/ek_ra2a1/ek_ra2a1.dts +++ b/boards/renesas/ek_ra2a1/ek_ra2a1.dts @@ -7,6 +7,7 @@ #include #include +#include #include "ek_ra2a1-pinctrl.dtsi" @@ -19,6 +20,7 @@ zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; }; leds { @@ -29,8 +31,18 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport2 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; }; }; @@ -69,3 +81,37 @@ &ioport1 { status = "okay"; }; + +&port_irq6 { + interrupts = <29 3>; + status = "okay"; +}; + +&pwm0 { + pinctrl-0 = <&pwm0_default>; + pinctrl-names = "default"; + interrupts = <28 1>, <31 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&iic0 { + pinctrl-0 = <&iic0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + interrupts = <0 1>, <1 1>, <2 1>, <3 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + status = "okay"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/renesas/ek_ra2a1/ek_ra2a1_defconfig b/boards/renesas/ek_ra2a1/ek_ra2a1_defconfig index 85bd6dcd4553d..15e3f1e271cf6 100644 --- a/boards/renesas/ek_ra2a1/ek_ra2a1_defconfig +++ b/boards/renesas/ek_ra2a1/ek_ra2a1_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 TOKITA Hiroshi # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/ek_ra2l1/Kconfig.ek_ra2l1 b/boards/renesas/ek_ra2l1/Kconfig.ek_ra2l1 new file mode 100644 index 0000000000000..53479a895c85a --- /dev/null +++ b/boards/renesas/ek_ra2l1/Kconfig.ek_ra2l1 @@ -0,0 +1,5 @@ +# Copyright (c) 2021-2024 MUNIC SA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_EK_RA2L1 + select SOC_R7FA2L1ABXXFP diff --git a/boards/renesas/ek_ra2l1/board.cmake b/boards/renesas/ek_ra2l1/board.cmake new file mode 100644 index 0000000000000..e39493b726b6a --- /dev/null +++ b/boards/renesas/ek_ra2l1/board.cmake @@ -0,0 +1,12 @@ +# Copyright (c) 2021-2024 MUNIC SA +# SPDX-License-Identifier: Apache-2.0 + +board_set_debugger_ifnset(jlink) +board_set_flasher_ifnset(jlink) + +board_runner_args(jlink "--device=r7fa2l1ab") +board_runner_args(pyocd "--target=r7fa2l1ab") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/renesas/ek_ra2l1/board.yml b/boards/renesas/ek_ra2l1/board.yml new file mode 100644 index 0000000000000..181a338410b97 --- /dev/null +++ b/boards/renesas/ek_ra2l1/board.yml @@ -0,0 +1,5 @@ +board: + name: ek_ra2l1 + vendor: renesas + socs: + - name: r7fa2l1abxxfp diff --git a/boards/renesas/ek_ra2l1/doc/ek_ra2l1.webp b/boards/renesas/ek_ra2l1/doc/ek_ra2l1.webp new file mode 100644 index 0000000000000..54da291633055 Binary files /dev/null and b/boards/renesas/ek_ra2l1/doc/ek_ra2l1.webp differ diff --git a/boards/renesas/ek_ra2l1/doc/index.rst b/boards/renesas/ek_ra2l1/doc/index.rst new file mode 100644 index 0000000000000..2d9686625c86f --- /dev/null +++ b/boards/renesas/ek_ra2l1/doc/index.rst @@ -0,0 +1,119 @@ +.. zephyr:board:: ek_ra2l1 + +Overview +******** + +The EK-RA2L1 is an evaluation kit for Renesas RA2L1 Microcontroller Group. + +Renesas RA2L1 Microcontroller Group has following features + +- 48MHz, Arm Cortex-M23 core +- 256kB or 128kB Code Flash, 8kB Data Flash, 32kB SRAM (divided on 2 equal areas + with- and without- ECC support) +- SCI x 5 +- SPI x 2 +- I2C x 2 +- CAN x 1 +- 12-bit A/D Converter +- 12-bit D/A Converter +- Low-Power Analog Comparator x 2 +- Temperature Sensor +- General PWM Timer 32-bit x 4 +- General PWM Timer 16-bit x 6 +- Low Power Asynchronous General-Purpose Timer x 2 +- Watchdog Timer (WDT) +- Independent Watchdog Timer (IWDT) +- up to 85 Input/Output pins (depends on the package type) + +Hardware +******** + +EK-RA2L1 has following features. + +- Native pin access through 1 x 40-pin and 3 x 20-pin male headers +- MCU current measurement points for precision current consumption measurement +- Multiple clock sources – Low-precision clocks are available internal to the MCU. + Additionally, MCU oscillator and sub-clock oscillator crystals, + 20.000 MHz and 32,768 Hz, are provided for precision +- SEGGER J-Link on-board programmer and debugger +- Two Digilent Pmod (SPI and UART) +- Three user LEDs (red, blue, green) +- Power LED (white) indicating availability of regulated power +- Debug LED (yellow) indicating the debug connection +- Two user buttons +- One reset button + +Supported Features +================== + +The Renesas ``ek_ra2l1`` board supports the following +hardware features: + ++-----------+------------+-------------------------------+ +| Interface | Controller | Driver/components | ++===========+============+===============================+ +| NVIC | on-chip | arch/arm | ++-----------+------------+-------------------------------+ +| PINCTRL | on-chip | pinctrl | ++-----------+------------+-------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------+ +| UART | on-chip | uart | ++-----------+------------+-------------------------------+ + +The default configuration can be found in +:zephyr_file:`boards/renesas/ek_ra2l1/ek_ra2l1_defconfig` + +Programming and debugging +************************* + +Building & Flashing +=================== + +You can build and flash an application with onboard J-Link debug adapter. +:ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for building and flashing the :zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: ek_ra2l1 + :goals: build flash + + +Debugging +========= + +Debugging also can be done with onboard J-Link debug adapter. +The following command is debugging the :zephyr:code-sample:`blinky` application. +Also, see the instructions specific to the debug server that you use. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: ek_ra2l1 + :maybe-skip-config: + :goals: debug + +Or you can use Segger Ozone (`Segger Ozone Download`_) for a visual debug interface + +Once downloaded and installed, open Segger Ozone and configure the debug project +like so: + +* Target Device: R7FA2L1AB +* Target Interface: SWD +* Target Interface Speed: 4 MHz +* Host Interface: USB +* Program File: + + +References +********** + +.. EK-RA2L1 Web site: + https://www.renesas.com/us/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra2l1-evaluation-kit-ra2l1-mcu-group + +.. _Segger Ozone Download: + https://www.segger.com/downloads/jlink#Ozone diff --git a/boards/renesas/ek_ra2l1/ek_ra2l1-pinctrl.dtsi b/boards/renesas/ek_ra2l1/ek_ra2l1-pinctrl.dtsi new file mode 100644 index 0000000000000..851d8543beea0 --- /dev/null +++ b/boards/renesas/ek_ra2l1/ek_ra2l1-pinctrl.dtsi @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci0_default: sci0_default { + group1 { + /* tx rx */ + psels = , + ; + }; + }; +}; diff --git a/boards/renesas/ek_ra2l1/ek_ra2l1.dts b/boards/renesas/ek_ra2l1/ek_ra2l1.dts new file mode 100644 index 0000000000000..1341b7cf7d375 --- /dev/null +++ b/boards/renesas/ek_ra2l1/ek_ra2l1.dts @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2021-2024 MUNIC SA + * Copyright (c) 2024 Renesas Electronics Corporation + * + * DTS for Renesas EK-RA2L1 eval. board + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include + +#include +#include "ek_ra2l1-pinctrl.dtsi" + +/ { + model = "Renesas EK-RA2L1"; + compatible = "renesas,r7fa2l1abxxfp", "renesas,ra2l1"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led1 { + gpios = <&ioport5 3 GPIO_ACTIVE_HIGH>; + label = "LED1"; + }; + }; + + aliases { + led0 = &led1; + }; +}; + +&ioport5 { + status = "okay"; +}; + +&sci0 { + pinctrl-0 = <&sci0_default>; + pinctrl-names = "default"; + status = "okay"; + + uart0: uart { + current-speed = <115200>; + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra2l1/ek_ra2l1.yaml b/boards/renesas/ek_ra2l1/ek_ra2l1.yaml new file mode 100644 index 0000000000000..bac07516f2c64 --- /dev/null +++ b/boards/renesas/ek_ra2l1/ek_ra2l1.yaml @@ -0,0 +1,16 @@ +identifier: ek_ra2l1 +name: Renesas EK-RA2L1 +type: mcu +arch: arm +ram: 32 +flash: 256 +toolchain: + - zephyr + - gnuarmemb +supported: + - flash +vendor: renesas +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/renesas/ek_ra2l1/ek_ra2l1_defconfig b/boards/renesas/ek_ra2l1/ek_ra2l1_defconfig new file mode 100644 index 0000000000000..9c7ccf6a625cb --- /dev/null +++ b/boards/renesas/ek_ra2l1/ek_ra2l1_defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2021-2024 MUNIC SA +# Copyright (c) 2024-2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Enable Console +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_CONSOLE=y +CONFIG_CONSOLE=y diff --git a/boards/renesas/ek_ra4e2/doc/index.rst b/boards/renesas/ek_ra4e2/doc/index.rst index cc2eb04af0d96..effa168b5ad79 100644 --- a/boards/renesas/ek_ra4e2/doc/index.rst +++ b/boards/renesas/ek_ra4e2/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra4e2: - -RA4E2 Evaluation Kit -#################### +.. zephyr:board:: ek_ra4e2 Overview ******** @@ -16,6 +13,7 @@ The MCU in this series incorporates a high-performance Arm CortexÂŽ-M33 core run 100 MHz with the following features: **MCU Native Pin Access** + - R7FA4E2B93CFM MCU (referred to as RA MCU) - 100 MHz, ArmÂŽ CortexÂŽ-M33 core - 128 kB Code Flash, 40 kB SRAM @@ -23,10 +21,11 @@ The MCU in this series incorporates a high-performance Arm CortexÂŽ-M33 core run - Native pin access through 2 x 14-pin and 1 x 40-pin male headers - MCU current measurement points for precision current consumption measurement - Multiple clock sources - RA MCU oscillator and sub-clock oscillator crystals, providing precision -20.000 MHz and 32,768 Hz reference clock. Additional low-precision clocks are available internal to the -RA MCU + 20.000 MHz and 32,768 Hz reference clock. Additional low-precision clocks are available internal to the + RA MCU **System Control and Ecosystem Access** + - USB Full Speed Device (micro-AB connector) - Three 5 V input sources @@ -61,15 +60,9 @@ RA MCU - CAN FD (3-pin header) -.. figure:: ek_ra4e2.webp - :align: center - :alt: RA4E2 Evaluation Kit - - EK-RA4E2 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detail Hardware feature for the RA4E2 MCU group can be found at `RA4E2 Group User's Manual Hardware`_ +Detailed hardware features for the RA4E2 MCU group can be found at `RA4E2 Group User's Manual Hardware`_ .. figure:: ra4e2_block_diagram.webp :width: 442px @@ -78,12 +71,12 @@ Detail Hardware feature for the RA4E2 MCU group can be found at `RA4E2 Group Use RA4E2 Block diagram (Credit: Renesas Electronics Corporation) -Detail Hardware feature for the EK-RA4E2 MCU can be found at `EK-RA4E2 - User's Manual`_ +Detailed hardware features for the EK-RA4E2 MCU can be found at `EK-RA4E2 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA4E2 board: +The below features are currently supported on Zephyr for EK-RA4E2 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -100,6 +93,16 @@ The below features are currently supported on Zephyr OS for EK-RA4E2 board: +-----------+------------+----------------------+ | SPI | on-chip | spi | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -119,11 +122,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA4E2 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA4E2 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra4e2/ek_ra4e2-pinctrl.dtsi b/boards/renesas/ek_ra4e2/ek_ra4e2-pinctrl.dtsi index 9c808d53a5285..29ce6c5c3025c 100644 --- a/boards/renesas/ek_ra4e2/ek_ra4e2-pinctrl.dtsi +++ b/boards/renesas/ek_ra4e2/ek_ra4e2-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -21,4 +21,37 @@ ; }; }; + + canfd0_default: canfd0_default { + group1 { + /* CRX0 CTX0 */ + psels = , + ; + drive-strength = "high"; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; }; diff --git a/boards/renesas/ek_ra4e2/ek_ra4e2.dts b/boards/renesas/ek_ra4e2/ek_ra4e2.dts index b99fafa457c76..30c17db435969 100644 --- a/boards/renesas/ek_ra4e2/ek_ra4e2.dts +++ b/boards/renesas/ek_ra4e2/ek_ra4e2.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra4e2-pinctrl.dtsi" / { @@ -15,9 +17,12 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,canbus = &canfd0; + zephyr,entropy = &trng; }; leds { @@ -36,8 +41,31 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport3 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; + }; + + transceiver0: can-phy0 { + compatible = "nxp,tja1043t", "can-transceiver-gpio"; + standby-gpios = <&ioport4 0 GPIO_ACTIVE_LOW>; + max-bitrate = <5000000>; + #phy-cells = <0>; }; }; @@ -69,6 +97,10 @@ }; }; +&ioport0 { + status = "okay"; +}; + &ioport1 { status = "okay"; }; @@ -82,3 +114,76 @@ pinctrl-names = "default"; status = "okay"; }; + +&ioport4 { + status = "okay"; +}; + +&canfdclk { + clocks = <&pll>; + div = <8>; + status = "okay"; +}; + +&canfd_global { + status = "okay"; + canfd0 { + pinctrl-0 = <&canfd0_default>; + pinctrl-names = "default"; + phys = <&transceiver0>; + rx-max-filters = <16>; + status = "okay"; + }; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&ioport3 { + status = "okay"; +}; + +&port_irq9 { + interrupts = <4 12>; + status = "okay"; +}; + +&port_irq10 { + interrupts = <5 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + divider = ; + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(4)>; + }; + }; +}; diff --git a/boards/renesas/ek_ra4e2/ek_ra4e2_defconfig b/boards/renesas/ek_ra4e2/ek_ra4e2_defconfig index 93569c968fce1..770a30fc47db0 100644 --- a/boards/renesas/ek_ra4e2/ek_ra4e2_defconfig +++ b/boards/renesas/ek_ra4e2/ek_ra4e2_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=100000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_CONSOLE=y CONFIG_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/ek_ra4l1/Kconfig.ek_ra4l1 b/boards/renesas/ek_ra4l1/Kconfig.ek_ra4l1 new file mode 100644 index 0000000000000..136246af8c750 --- /dev/null +++ b/boards/renesas/ek_ra4l1/Kconfig.ek_ra4l1 @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_EK_RA4L1 + select SOC_R7FA4L1BD4CFP diff --git a/boards/renesas/ek_ra4l1/board.cmake b/boards/renesas/ek_ra4l1/board.cmake new file mode 100644 index 0000000000000..ede2ff300bbcc --- /dev/null +++ b/boards/renesas/ek_ra4l1/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=R7FA4L1BD") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/renesas/ek_ra4l1/board.yml b/boards/renesas/ek_ra4l1/board.yml new file mode 100644 index 0000000000000..d2e6b1bf6cbf7 --- /dev/null +++ b/boards/renesas/ek_ra4l1/board.yml @@ -0,0 +1,6 @@ +board: + name: ek_ra4l1 + full_name: RA4L1 Evaluation Kit + vendor: renesas + socs: + - name: r7fa4l1bd4cfp diff --git a/boards/renesas/ek_ra4l1/doc/ek_ra4l1.webp b/boards/renesas/ek_ra4l1/doc/ek_ra4l1.webp new file mode 100644 index 0000000000000..219105795b04a Binary files /dev/null and b/boards/renesas/ek_ra4l1/doc/ek_ra4l1.webp differ diff --git a/boards/renesas/ek_ra4l1/doc/index.rst b/boards/renesas/ek_ra4l1/doc/index.rst new file mode 100644 index 0000000000000..067d2bdb8adee --- /dev/null +++ b/boards/renesas/ek_ra4l1/doc/index.rst @@ -0,0 +1,148 @@ +.. zephyr:board:: ek_ra4l1 + +Overview +******** + +The Renesas RA4L1 group of 32-bit microcontrollers (MCUs) uses the high-performance Arm +CortexÂŽ-M33 core. Share a common set of Renesas peripherals to facilitate design scalability +and efficient platform-based product development. + +The MCU in this series incorporates a high-performance Arm CortexÂŽ-M33 core running up to +80 MHz with the following features: + +**MCU Native Pin Access** + +- R7FA4L1BD4CFP MCU (referred to as RA MCU) +- 80 MHz, ArmÂŽ CortexÂŽ-M33 core +- 512 KB Code Flash, 64 KB SRAM +- 100-pin LQFP package + +**System Control and Ecosystem Access** + +- USB Full Speed Host and Device (USB-C connector) +- Three 5 V input sources + + - USB (Debug, Full Speed) + - External power supply (using surface mount clamp test points and power input vias) + +- Three Debug modes + + - Debug on-board (SWD) + - Debug in (SWD) + - Debug out (SWD, SW0 and JTAG) + +- User LEDs and buttons + + - Three User LEDs (red, blue, green) + - Power LED (white) indicating availability of regulated power + - Debug LED (yellow) indicating the debug connection + - Two User buttons + - One Reset button + +- Five most popular ecosystems expansions + + - 1 Seeed GroveÂŽ system (I3C) connector + - 1 Seeed GroveÂŽ system (I2C/Analog) connector + - 2 Digilent PmodTM (SPI, UART and I2C) connectors + - ArduinoTM (Uno R3) connector + - MikroElektronikaTM mikroBUS connector + +- MCU boot configuration jumper + +**Special Feature Access** + +- 256 Mb (32 MB) External QUAD-SPI Flash +- CAN FD (3-pin header) +- Segment LCD Board Interface (50-pin header) + +Hardware +******** + +Detailed hardware features can be found at: + +- RA4L1 MCU: `RA4L1 Group User's Manual Hardware`_ +- EK-RA4L1 board: `EK-RA4L1 - User's Manual`_ + +Debug on-board: + + - Connector Used: USB-C (J10) + ++----------------+------+------+--------------------+------+--------------------------------------+ +| Debug Modes | J6 | J6-A | J8 | J9 | J29 | ++================+======+======+====================+======+======================================+ +| Debug on-board | Open | Open | Jumper on pins 1-2 | Open | Jumpers on pins 1-2, 3-4, 5-6, 7-8 | ++----------------+------+------+--------------------+------+--------------------------------------+ + +Supported Features +================== + +The below features are currently supported on Zephyr for the ``ek_ra4l1`` board: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| SPI | on-chip | spi | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock control | ++-----------+------------+----------------------+ +| CAN | on-chip | canfd | ++-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ + +Other hardware features are currently not supported by the port. + +Programming and Debugging +************************* + +Applications for the ``ek_ra4l1`` board configuration can be +built, flashed, and debugged in the usual way. See +:ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +Flashing +======== + +Program can be flashed to EK-RA4L1 via the on-board SEGGER J-Link debugger. +SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ + +To flash the program to board + +1. Connect to J-Link OB via USB port to host PC + +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA4L1 - User's Manual`_ + +3. Execute west command + + .. code-block:: console + + west flash -r jlink + +References +********** +- `EK-RA4L1 Website`_ +- `RA4L1 MCU group Website`_ + +.. _EK-RA4L1 Website: + https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra4l1-evaluation-kit-ra4l1-mcu-group + +.. _RA4L1 MCU group Website: + https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra4l1-80mhz-arm-cortex-m33-based-low-power-mcu-trustzone-segment-lcd-controller-and-advanced-security + +.. _EK-RA4L1 - User's Manual: + https://www.renesas.com/en/document/mat/ek-ra4l1-v1-users-manual?r=25570359 + +.. _RA4L1 Group User's Manual Hardware: + https://www.renesas.com/en/document/mah/ra4l1-group-users-manual-hardware?r=25568281 diff --git a/boards/renesas/ek_ra4l1/ek_ra4l1-pinctrl.dtsi b/boards/renesas/ek_ra4l1/ek_ra4l1-pinctrl.dtsi new file mode 100644 index 0000000000000..c967c97b44269 --- /dev/null +++ b/boards/renesas/ek_ra4l1/ek_ra4l1-pinctrl.dtsi @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci5_default: sci5_default { + group1 { + /* tx rx */ + psels = , + ; + }; + }; + + spi0_default: spi0_default { + group1 { + /* MISO MOSI RSPCK SSL */ + psels = , + , + , + ; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + iic0_default: iic0_default { + group1 { + /* SCL0 SDA0 */ + psels = , + ; + drive-strength = "medium"; + }; + }; + + canfd0_default: canfd0_default { + group1 { + /* CRX0 CTX0 */ + psels = , + ; + drive-strength = "high"; + }; + }; +}; diff --git a/boards/renesas/ek_ra4l1/ek_ra4l1.dts b/boards/renesas/ek_ra4l1/ek_ra4l1.dts new file mode 100644 index 0000000000000..a85a694c12a02 --- /dev/null +++ b/boards/renesas/ek_ra4l1/ek_ra4l1.dts @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include "ek_ra4l1-pinctrl.dtsi" + +/ { + model = "Renesas EK-RA4L1"; + compatible = "renesas,ra4l1", "renesas,ra"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; + zephyr,flash = &flash0; + zephyr,console = &uart5; + zephyr,shell-uart = &uart5; + zephyr,canbus = &canfd0; + }; + + leds { + compatible = "gpio-leds"; + + led1: led1 { + gpios = <&ioport6 9 GPIO_ACTIVE_HIGH>; + label = "LED1"; + }; + + led2: led2 { + gpios = <&ioport6 10 GPIO_ACTIVE_HIGH>; + label = "LED2"; + }; + + led3: led3 { + gpios = <&ioport6 1 GPIO_ACTIVE_HIGH>; + label = "LED3"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: s1 { + gpios = <&ioport0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + + button1: s2 { + gpios = <&ioport0 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led1; + sw0 = &button0; + sw1 = &button1; + }; + + transceiver0: can-phy0 { + compatible = "microchip,mcp2562fd", "can-transceiver-gpio"; + standby-gpios = <&ioport1 6 GPIO_ACTIVE_LOW>; + max-bitrate = <5000000>; + #phy-cells = <0>; + }; +}; + +&xtal { + clock-frequency = ; + mosel = <0>; + #clock-cells = <0>; + status = "okay"; +}; + +&subclk { + status = "okay"; +}; + +&pll { + clocks = <&xtal>; + div = <1>; + mul = <10 0>; + status = "okay"; +}; + +&canfdclk { + clocks = <&pll>; + div = <2>; + status = "okay"; +}; + +&sci5 { + pinctrl-0 = <&sci5_default>; + pinctrl-names = "default"; + status = "okay"; + + uart5: uart { + current-speed = <115200>; + status = "okay"; + }; +}; + +&ioport0 { + status = "okay"; +}; + +&ioport1 { + status = "okay"; +}; + +&ioport4 { + status = "okay"; +}; + +&ioport5 { + status = "okay"; +}; + +&ioport6 { + status = "okay"; +}; + +&spi0 { + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&port_irq6 { + interrupts = <14 12>; + status = "okay"; +}; + +&port_irq7 { + interrupts = <15 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <8 1>, <9 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&iic0 { + pinctrl-0 = <&iic0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + interrupts = <10 1>, <11 1>, <12 1>, <13 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + status = "okay"; +}; + +&canfd_global { + status = "okay"; + + canfd0 { + pinctrl-0 = <&canfd0_default>; + pinctrl-names = "default"; + phys = <&transceiver0>; + rx-max-filters = <16>; + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra4l1/ek_ra4l1.yaml b/boards/renesas/ek_ra4l1/ek_ra4l1.yaml new file mode 100644 index 0000000000000..edcac7c0fa722 --- /dev/null +++ b/boards/renesas/ek_ra4l1/ek_ra4l1.yaml @@ -0,0 +1,12 @@ +identifier: ek_ra4l1 +name: Renesas EK-RA4L1 +type: mcu +arch: arm +ram: 64 +flash: 512 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - uart diff --git a/boards/renesas/ek_ra4l1/ek_ra4l1_defconfig b/boards/renesas/ek_ra4l1/ek_ra4l1_defconfig new file mode 100644 index 0000000000000..f26066de3e521 --- /dev/null +++ b/boards/renesas/ek_ra4l1/ek_ra4l1_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Enable Console +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_CONSOLE=y +CONFIG_CONSOLE=y diff --git a/boards/renesas/ek_ra4m1/Kconfig.ek_ra4m1 b/boards/renesas/ek_ra4m1/Kconfig.ek_ra4m1 new file mode 100644 index 0000000000000..9e52f5c7bde6c --- /dev/null +++ b/boards/renesas/ek_ra4m1/Kconfig.ek_ra4m1 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_EK_RA4M1 + select SOC_R7FA4M1AB3CFP diff --git a/boards/renesas/ek_ra4m1/board.cmake b/boards/renesas/ek_ra4m1/board.cmake new file mode 100644 index 0000000000000..8711194800bb7 --- /dev/null +++ b/boards/renesas/ek_ra4m1/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=R7FA4M1AB") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/renesas/ek_ra4m1/board.yml b/boards/renesas/ek_ra4m1/board.yml new file mode 100644 index 0000000000000..02926e4a43800 --- /dev/null +++ b/boards/renesas/ek_ra4m1/board.yml @@ -0,0 +1,6 @@ +board: + name: ek_ra4m1 + full_name: RA4M1 Evaluation Kit + vendor: renesas + socs: + - name: r7fa4m1ab3cfp diff --git a/boards/renesas/ek_ra4m1/doc/ek_ra4m1.webp b/boards/renesas/ek_ra4m1/doc/ek_ra4m1.webp new file mode 100644 index 0000000000000..510ee1689b0a7 Binary files /dev/null and b/boards/renesas/ek_ra4m1/doc/ek_ra4m1.webp differ diff --git a/boards/renesas/ek_ra4m1/doc/index.rst b/boards/renesas/ek_ra4m1/doc/index.rst new file mode 100644 index 0000000000000..be316702996a1 --- /dev/null +++ b/boards/renesas/ek_ra4m1/doc/index.rst @@ -0,0 +1,156 @@ +.. zephyr:board:: ek_ra4m1 + +Overview +******** + +The MCU integrates multiple series of software- and pin-compatible ArmÂŽ-based 32-bit +cores that share a common set of Renesas peripherals to facilitate design scalability +and efficient platform-based product development. +The MCU provides an optimal combination of low-power, high-performance Arm CortexÂŽ-M4 core +running up to 48 MHz with the following features: + +**Renesas RA4M1 Microcontroller Group** + +- R7FA4M1AB3CFP +- 100-pin LQFP package +- 48 MHz ArmÂŽ CortexÂŽ-M4 core with Floating Point Unit (FPU) +- 32 KB SRAM +- 256 KB code flash memory +- 8 KB data flash memory + +**Connectivity** + +- A Device USB connector for the Main MCU +- SEGGER J-LinkÂŽ On-Board (OB) interface for debugging and programming of the RA4M1 MCU. A + 10pin JTAG/SWD interface is also provided for connecting optional external debuggers and + programmers. +- Two PMOD connectors, allowing use of appropriate PMOD compliant peripheral plug-in modules for + rapid prototyping +- Pin headers for access to power and signals for the Main MCU + +**Multiple clock sources** + +- Main MCU oscillator crystals, providing precision 12.000 MHz and 32,768 Hz external reference + clocks +- Additional low-precision clocks are available internal to the Main MCU + +**General purpose I/O ports** + +- One jumper to allow measuring of Main MCU current +- Copper jumpers on PCB bottom side for configuration and access to selected MCU signals + +**Operating voltage** + +- External 5 V input through the Debug USB connector supplies the on-board power regulator to power + logic and interfaces on the board. External 5 V or 3.3 V may be also supplied through alternate + locations on the board. +- A two-color board status LED indicating availability of regulated power and connection status of the J-Link + interface. +- A red User LED, controlled by the Main MCU firmware +- A User Push-Button switch, User Capacitive Touch Button sensor, and an optional User Potentiometer, + all of which are controlled by the Main MCU firmware +- MCU reset push-button switch +- MCU boot configuration jumper + +Hardware +******** + +Detailed hardware features can be found at: + +- RA4M1 MCU: `RA4M1 Group User's Manual Hardware`_ +- EK-RA4M1 board: `EK-RA4M1 - User's Manual`_ + +Supported Features +================== + +The below features are currently supported on Zephyr for the ``ek_ra4m1`` board: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock control | ++-----------+------------+----------------------+ +| COUNTER | on-chip | counter | ++-----------+------------+----------------------+ +| SPI | on-chip | spi | ++-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ + +Other hardware features are currently not supported by the port. + +Programming and Debugging +************************* + +Applications for the ``ek_ra4m1`` board can be built, flashed, and debugged +in the usual way. See :ref:`build_an_application` and :ref:`application_run` +for more details on building and running. + +Flashing +======== + +Program can be flashed to EK-RA4M1 via the on-board SEGGER J-Link debugger. +SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ + +To flash the program to board + +1. Connect to J-Link OB via USB port to host PC + +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA4M1 - User's Manual`_ + +3. Execute west command + + .. code-block:: console + + west flash -r jlink + +Debugging +========= + +You can use Segger Ozone (`Segger Ozone Download`_) for a visual debug interface + +Once downloaded and installed, open Segger Ozone and configure the debug project +like so: + +* Target Device: R7FA4M1AB +* Target Interface: SWD +* Target Interface Speed: 4 MHz +* Host Interface: USB +* Program File: + +**Note:** It's verified that we can debug OK on Segger Ozone v3.30d so please use this or later +version of Segger Ozone + +References +********** +- `EK-RA4M1 Website`_ +- `RA4M1 MCU group Website`_ + +.. _EK-RA4M1 Website: + https://www.renesas.com/us/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra4m1-evaluation-kit-ra4m1-mcu-group + +.. _RA4M1 MCU group Website: + https://www.renesas.com/us/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra4m1-32-bit-microcontrollers-48mhz-arm-cortex-m4-and-lcd-controller-and-cap-touch-hmi + +.. _EK-RA4M1 - User's Manual: + https://www.renesas.com/us/en/document/mat/ek-ra4m1-v1-users-manual + +.. _RA4M1 Group User's Manual Hardware: + https://www.renesas.com/us/en/document/mah/renesas-ra4m1-group-users-manual-hardware?r=1054146 + +.. _Segger Ozone Download: + https://www.segger.com/downloads/jlink#Ozone diff --git a/boards/renesas/ek_ra4m1/ek_ra4m1-pinctrl.dtsi b/boards/renesas/ek_ra4m1/ek_ra4m1-pinctrl.dtsi new file mode 100644 index 0000000000000..5a701c3bda5eb --- /dev/null +++ b/boards/renesas/ek_ra4m1/ek_ra4m1-pinctrl.dtsi @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci1_default: sci1_default { + group1 { + /* tx rx */ + psels = , + ; + }; + }; + + spi1_default: spi1_default { + group1 { + /* MISO MOSI RSPCK SSL */ + psels = , + , + , + ; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + iic1_default: iic1_default { + group1 { + /* SCL1 SDA1 */ + psels = , + ; + drive-strength = "medium"; + }; + }; +}; diff --git a/boards/renesas/ek_ra4m1/ek_ra4m1.dts b/boards/renesas/ek_ra4m1/ek_ra4m1.dts new file mode 100644 index 0000000000000..903f660b1b4c8 --- /dev/null +++ b/boards/renesas/ek_ra4m1/ek_ra4m1.dts @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include "ek_ra4m1-pinctrl.dtsi" + +/ { + model = "Renesas EK-RA4M1"; + compatible = "renesas,ra4m1", "renesas,ra"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,entropy = &trng; + }; + + leds { + compatible = "gpio-leds"; + + led1: led1 { + gpios = <&ioport1 6 GPIO_ACTIVE_HIGH>; + label = "LED1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: s1 { + gpios = <&ioport1 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led1; + sw0 = &button0; + }; +}; + +&xtal { + clock-frequency = ; + mosel = <0>; + #clock-cells = <0>; + status = "okay"; +}; + +&subclk { + status = "okay"; +}; + +&pll { + clocks = <&xtal>; + div = <2>; + mul = <8 0>; + status = "okay"; +}; + +&sci1 { + pinctrl-0 = <&sci1_default>; + pinctrl-names = "default"; + status = "okay"; + + uart1: uart { + current-speed = <115200>; + status = "okay"; + }; +}; + +&ioport1 { + status = "okay"; +}; + +&ioport2 { + status = "okay"; +}; + +&ioport4 { + status = "okay"; +}; + +&spi1 { + pinctrl-0 = <&spi1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&port_irq0 { + interrupts = <27 12>; + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <8 1>, <9 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&iic1 { + pinctrl-0 = <&iic1_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + interrupts = <10 1>, <11 1>, <12 1>, <13 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + status = "okay"; +}; diff --git a/boards/renesas/ek_ra4m1/ek_ra4m1.yaml b/boards/renesas/ek_ra4m1/ek_ra4m1.yaml new file mode 100644 index 0000000000000..022f56df18d3b --- /dev/null +++ b/boards/renesas/ek_ra4m1/ek_ra4m1.yaml @@ -0,0 +1,12 @@ +identifier: ek_ra4m1 +name: Renesas EK-RA4M1 +type: mcu +arch: arm +ram: 32 +flash: 256 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - uart diff --git a/boards/renesas/ek_ra4m1/ek_ra4m1_defconfig b/boards/renesas/ek_ra4m1/ek_ra4m1_defconfig new file mode 100644 index 0000000000000..770a30fc47db0 --- /dev/null +++ b/boards/renesas/ek_ra4m1/ek_ra4m1_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Enable Console +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_CONSOLE=y +CONFIG_CONSOLE=y diff --git a/boards/renesas/ek_ra4m2/doc/index.rst b/boards/renesas/ek_ra4m2/doc/index.rst index c3c5583bf3682..bdea3c5e2f85d 100644 --- a/boards/renesas/ek_ra4m2/doc/index.rst +++ b/boards/renesas/ek_ra4m2/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra4m2: - -RA4M2 Evaluation Kit -#################### +.. zephyr:board:: ek_ra4m2 Overview ******** @@ -17,17 +14,19 @@ The MCU in this series incorporates a high-performance Arm CortexÂŽ-M33 core run 100 MHz with the following features: **Renesas RA4M2 Microcontroller Group** + - R7FA4M2AD3CFP - 100-pin LQFP package - 100 MHz ArmÂŽ CortexÂŽ-M33 core - 512 kB Code Flash, 128 KB SRAM - Native pin access through 4 x 28-pin male headers - MCU current measurement points for precision current consumption measurement -- Multiple clock sources - RA MCU oscillator and sub-clock oscillator crystals, providing -precision 24.000 MHz and 32,768 Hz reference clock. Additional low-precision clocks are -available internal to the RA MCU +- Multiple clock sources - RA MCU oscillator and sub-clock oscillator crystals, providing + precision 24.000 MHz and 32,768 Hz reference clock. Additional low-precision clocks are + available internal to the RA MCU **System Control and Ecosystem Access** + - USB Full Speed Host and Device (micro AB connector) - Three 5 V input sources @@ -59,17 +58,12 @@ available internal to the RA MCU - MCU boot configuration jumper **Special Feature Access** -- 32 MB (256 Mb) External Quad-SPI Flash -.. figure:: ek_ra4m2.webp - :align: center - :alt: RA4M2 Evaluation Kit - - EK-RA4M2 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) +- 32 MB (256 Mb) External Quad-SPI Flash Hardware ******** -Detail Hardware feature for the RA4M2 MCU group can be found at `RA4M2 Group User's Manual Hardware`_ +Detailed hardware features for the RA4M2 MCU group can be found at `RA4M2 Group User's Manual Hardware`_ .. figure:: ra4m2_block_diagram.webp :width: 442px @@ -78,12 +72,12 @@ Detail Hardware feature for the RA4M2 MCU group can be found at `RA4M2 Group Use RA4M2 Block diagram (Credit: Renesas Electronics Corporation) -Detail Hardware feature for the EK-RA4M2 MCU can be found at `EK-RA4M2 - User's Manual`_ +Detailed hardware features for the EK-RA4M2 MCU can be found at `EK-RA4M2 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA4M2 board: +The below features are currently supported on Zephyr for EK-RA4M2 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -102,6 +96,20 @@ The below features are currently supported on Zephyr OS for EK-RA4M2 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -121,11 +129,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA4M2 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA4M2 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra4m2/ek_ra4m2-pinctrl.dtsi b/boards/renesas/ek_ra4m2/ek_ra4m2-pinctrl.dtsi index a4c832c6e9e4b..97e386641c8ec 100644 --- a/boards/renesas/ek_ra4m2/ek_ra4m2-pinctrl.dtsi +++ b/boards/renesas/ek_ra4m2/ek_ra4m2-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -21,4 +21,45 @@ ; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + iic0_default: iic0_default { + group1 { + /* SCL0 SDA0 */ + psels = , + ; + drive-strength = "medium"; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USB_VBUS */ + psels = ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra4m2/ek_ra4m2.dts b/boards/renesas/ek_ra4m2/ek_ra4m2.dts index aa75e8a795cad..b0800e68de02c 100644 --- a/boards/renesas/ek_ra4m2/ek_ra4m2.dts +++ b/boards/renesas/ek_ra4m2/ek_ra4m2.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra4m2-pinctrl.dtsi" / { @@ -15,9 +17,11 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; }; leds { @@ -36,8 +40,24 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport0 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; }; }; @@ -59,6 +79,19 @@ status = "okay"; }; +&pll2 { + clocks = <&xtal>; + div = <2>; + mul = <20 0>; + status = "okay"; +}; + +&uclk { + clocks = <&pll2>; + div = <5>; + status = "okay"; +}; + &sci0 { pinctrl-0 = <&sci0_default>; pinctrl-names = "default"; @@ -69,6 +102,10 @@ }; }; +&ioport0 { + status = "okay"; +}; + &ioport4 { status = "okay"; }; @@ -78,3 +115,71 @@ pinctrl-names = "default"; status = "okay"; }; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq10 { + interrupts = <41 12>; + status = "okay"; +}; + +&port_irq11 { + interrupts = <42 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&iic0 { + pinctrl-0 = <&iic0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + interrupts = <87 1>, <88 1>, <89 1>, <90 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(8)>; + }; + }; +}; + +&trng { + status = "okay"; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra4m2/ek_ra4m2.yaml b/boards/renesas/ek_ra4m2/ek_ra4m2.yaml index d61c6bf05fe82..a32c36021c478 100644 --- a/boards/renesas/ek_ra4m2/ek_ra4m2.yaml +++ b/boards/renesas/ek_ra4m2/ek_ra4m2.yaml @@ -10,3 +10,5 @@ toolchain: supported: - gpio - uart + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra4m2/ek_ra4m2_defconfig b/boards/renesas/ek_ra4m2/ek_ra4m2_defconfig index 93569c968fce1..770a30fc47db0 100644 --- a/boards/renesas/ek_ra4m2/ek_ra4m2_defconfig +++ b/boards/renesas/ek_ra4m2/ek_ra4m2_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=100000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_CONSOLE=y CONFIG_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/ek_ra4m3/doc/index.rst b/boards/renesas/ek_ra4m3/doc/index.rst index 5ff3b755654d9..aa843d9311f5f 100644 --- a/boards/renesas/ek_ra4m3/doc/index.rst +++ b/boards/renesas/ek_ra4m3/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra4m3: - -RA4M3 Evaluation Kit -#################### +.. zephyr:board:: ek_ra4m3 Overview ******** @@ -18,6 +15,7 @@ The MCU in this series incorporates a high-performance Arm CortexÂŽ-M33 core run 100 MHz with the following features: **MCU Native Pin Access** + - R7FA4M3AF3CFB - 100-pin LQFP package - 100 MHz ArmÂŽ CortexÂŽ-M33 core @@ -26,24 +24,23 @@ The MCU in this series incorporates a high-performance Arm CortexÂŽ-M33 core run - Native pin access through 4 x 40-pin male headers - MCU and USB current measurement points for precision current consumption measurement - Multiple clock sources - RA MCU oscillator and sub-clock oscillator crystals, providing precision -24.000 MHz and 32,768 Hz reference clock. Additional low-precision clocks are available internal to the -RA MCU + 24.000 MHz and 32,768 Hz reference clock. Additional low-precision clocks are available internal to the + RA MCU **System Control and Ecosystem Access** + - USB Full Speed Host and Device (micro AB connector) -- Three 5 V input sources +- Three 5 V input sources - USB (Debug, Full Speed) - External power supply (using surface mount clamp test points and power input vias) - Three Debug modes - +- Three Debug modes - Debug on-board (SWD) - Debug in (ETM, SWD, and JTAG) - Debug out (SWD) - User LEDs and buttons - +- User LEDs and buttons - Three User LEDs (red, blue, green) - Power LED (white) indicating availability of regulated power - Debug LED (yellow) indicating the debug connection @@ -51,7 +48,6 @@ RA MCU - One Reset button - Five most popular ecosystems expansions - - 2 Seeed GroveÂŽ system (I2C/Analog) connectors - SparkFunÂŽ QwiicÂŽ connector - 2 Digilent PmodTM (SPI and UART) connectors @@ -63,15 +59,9 @@ RA MCU **Special Feature Access** - 32 MB (256 Mb) External Quad-SPI Flash -.. figure:: ek_ra4m3.webp - :align: center - :alt: RA4M3 Evaluation Kit - - EK-RA4M3 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detail Hardware feature for the RA4M3 MCU group can be found at `RA4M3 Group User's Manual Hardware`_ +Detailed hardware features for the RA4M3 MCU group can be found at `RA4M3 Group User's Manual Hardware`_ .. figure:: ra4m3_block_diagram.webp :width: 442px @@ -80,12 +70,12 @@ Detail Hardware feature for the RA4M3 MCU group can be found at `RA4M3 Group Use RA4M3 Block diagram (Credit: Renesas Electronics Corporation) -Detail Hardware feature for the EK-RA4M3 MCU can be found at `EK-RA4M3 - User's Manual`_ +Detailed hardware features for the EK-RA4M3 MCU can be found at `EK-RA4M3 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA4M3 board: +The below features are currently supported on Zephyr for EK-RA4M3 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -104,6 +94,20 @@ The below features are currently supported on Zephyr OS for EK-RA4M3 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. diff --git a/boards/renesas/ek_ra4m3/ek_ra4m3-pinctrl.dtsi b/boards/renesas/ek_ra4m3/ek_ra4m3-pinctrl.dtsi index 408f6e610b5a5..0b574b13c5ffb 100644 --- a/boards/renesas/ek_ra4m3/ek_ra4m3-pinctrl.dtsi +++ b/boards/renesas/ek_ra4m3/ek_ra4m3-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -21,4 +21,45 @@ ; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + iic0_default: iic0_default { + group1 { + /* SCL0 SDA0 */ + psels = , + ; + drive-strength = "medium"; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USB_VBUS */ + psels = ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra4m3/ek_ra4m3.dts b/boards/renesas/ek_ra4m3/ek_ra4m3.dts index cdcb10ca08db4..903c9997c9ae8 100644 --- a/boards/renesas/ek_ra4m3/ek_ra4m3.dts +++ b/boards/renesas/ek_ra4m3/ek_ra4m3.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra4m3-pinctrl.dtsi" / { @@ -15,9 +17,11 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; }; leds { @@ -36,8 +40,24 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport0 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; }; }; @@ -59,6 +79,19 @@ status = "okay"; }; +&pll2 { + clocks = <&xtal>; + div = <3>; + mul = <24 0>; + status = "okay"; +}; + +&uclk { + clocks = <&pll2>; + div = <4>; + status = "okay"; +}; + &sci0 { pinctrl-0 = <&sci0_default>; pinctrl-names = "default"; @@ -69,6 +102,10 @@ }; }; +&ioport0 { + status = "okay"; +}; + &ioport4 { status = "okay"; }; @@ -78,3 +115,71 @@ pinctrl-names = "default"; status = "okay"; }; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq10 { + interrupts = <41 12>; + status = "okay"; +}; + +&port_irq11 { + interrupts = <42 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&iic0 { + pinctrl-0 = <&iic0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + interrupts = <87 1>, <88 1>, <89 1>, <90 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(8)>; + }; + }; +}; + +&trng { + status = "okay"; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra4m3/ek_ra4m3.yaml b/boards/renesas/ek_ra4m3/ek_ra4m3.yaml index e05b8e804da78..6abc856677445 100644 --- a/boards/renesas/ek_ra4m3/ek_ra4m3.yaml +++ b/boards/renesas/ek_ra4m3/ek_ra4m3.yaml @@ -10,3 +10,5 @@ toolchain: supported: - gpio - uart + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra4m3/ek_ra4m3_defconfig b/boards/renesas/ek_ra4m3/ek_ra4m3_defconfig index 93569c968fce1..770a30fc47db0 100644 --- a/boards/renesas/ek_ra4m3/ek_ra4m3_defconfig +++ b/boards/renesas/ek_ra4m3/ek_ra4m3_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=100000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_CONSOLE=y CONFIG_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/ek_ra4w1/doc/index.rst b/boards/renesas/ek_ra4w1/doc/index.rst index 097b1b4448a3c..b763331a7f92c 100644 --- a/boards/renesas/ek_ra4w1/doc/index.rst +++ b/boards/renesas/ek_ra4w1/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra4w1: - -RA4W1 Evaluation Kit -#################### +.. zephyr:board:: ek_ra4w1 Overview ******** @@ -14,54 +11,56 @@ excellent reception performance. RA4W1 is geared towards IoT application requiri embedded RAM and low power consumption. **MCU Native Pin Access** + - R7FA4W1AD2CNG - QFN-56 package - On-chip memory: 512-KB ROM, 96-KB RAM, 8-KB data flash memory **Power-supply voltage** + - USB connector: 5-V input - Power-supply IC: 5-V input, 3.3-V output - External power-supply header*1: 3.3-V input, 2 pins x 1 **Main clock** + - Crystal oscillator (surface-mount technology (SMT)) for the main system clock - Crystal oscillator or ceramic resonator (lead type) for the main system clock **Sub-clock** + - Crystal oscillator (SMT) for the sub-clock **Bluetooth Low Energy** + - Bluetooth Low Energy (BLE) circuit x1 - Range of frequency: 2402 to 2480 MHz - Maximum transmission output power: 4 dBm (in 4-dBm output mode) - Output variation: +2 dB **Push switches** + - Reset switch x 1 - User switch x 1 **LED** + - Power indicator: green x 1 - User: green x 2 - ACT LED: green x 1 -**Conetivity** +**Connectivity** + - Connector for an on-board emulator: USB Micro-B - Connector for a USB serial-conversion interface: USB Micro-B - Pmod™ connector: Angle type, 12 pins - Arduino™ UNO connectors -- Emulator reset switch - -.. figure:: ek_ra4w1.webp - :align: center - :alt: RA4W1 Evaluation Kit - - EK-RA4W1 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) +- Emulator reset switch: DIP switch x 1 Hardware ******** -Detail Hardware feature for the RA4W1 MCU group can be found at `RA4W1 Group User's Manual Hardware`_ +Detailed Hardware features for the RA4W1 MCU group can be found at `RA4W1 Group User's Manual Hardware`_ .. figure:: ra4w1_block_diagram.webp :width: 442px @@ -70,12 +69,12 @@ Detail Hardware feature for the RA4W1 MCU group can be found at `RA4W1 Group Use RA4W1 Block diagram (Credit: Renesas Electronics Corporation) -Detail Hardware feature for the EK-RA4W1 MCU can be found at `EK-RA4W1 - User's Manual`_ +Detailed Hardware features for the EK-RA4W1 MCU can be found at `EK-RA4W1 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA4W1 board: +The below features are currently supported on Zephyr for EK-RA4W1 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -94,6 +93,14 @@ The below features are currently supported on Zephyr OS for EK-RA4W1 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -113,11 +120,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA4W1 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA4W1 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra4w1/ek_ra4w1-pinctrl.dtsi b/boards/renesas/ek_ra4w1/ek_ra4w1-pinctrl.dtsi index cfcc3fc541048..f0b48f12f95ba 100644 --- a/boards/renesas/ek_ra4w1/ek_ra4w1-pinctrl.dtsi +++ b/boards/renesas/ek_ra4w1/ek_ra4w1-pinctrl.dtsi @@ -21,4 +21,29 @@ ; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + iic0_default: iic0_default { + group1 { + /* SCL0 SDA0 */ + psels = , + ; + drive-strength = "medium"; + }; + }; }; diff --git a/boards/renesas/ek_ra4w1/ek_ra4w1.dts b/boards/renesas/ek_ra4w1/ek_ra4w1.dts index 2ba85852e9b30..75637a7f0237b 100644 --- a/boards/renesas/ek_ra4w1/ek_ra4w1.dts +++ b/boards/renesas/ek_ra4w1/ek_ra4w1.dts @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra4w1-pinctrl.dtsi" / { @@ -18,6 +20,7 @@ zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; }; leds { @@ -33,8 +36,18 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport4 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; }; }; @@ -65,3 +78,37 @@ pinctrl-names = "default"; status = "okay"; }; + +&trng { + status = "okay"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&port_irq4 { + interrupts = <27 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <8 1>, <9 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&iic0 { + pinctrl-0 = <&iic0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + interrupts = <10 1>, <11 1>, <12 1>, <13 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + status = "okay"; +}; diff --git a/boards/renesas/ek_ra4w1/ek_ra4w1_defconfig b/boards/renesas/ek_ra4w1/ek_ra4w1_defconfig index 631c90786a6b0..770a30fc47db0 100644 --- a/boards/renesas/ek_ra4w1/ek_ra4w1_defconfig +++ b/boards/renesas/ek_ra4w1/ek_ra4w1_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_CONSOLE=y CONFIG_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/ek_ra6e2/doc/index.rst b/boards/renesas/ek_ra6e2/doc/index.rst index 4dce24edaf05b..15a9d7c43050b 100644 --- a/boards/renesas/ek_ra6e2/doc/index.rst +++ b/boards/renesas/ek_ra6e2/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra6e2: - -RA6E2 Evaluation Kit -#################### +.. zephyr:board:: ek_ra6e2 Overview ******** @@ -61,15 +58,9 @@ The key features of the EK-RA6E2 board are categorized in three groups as follow - 16 Mb (128 Mb) External Quad-SPI Flash - CAN (3-pin header) -.. figure:: ek_ra6e2.webp - :align: center - :alt: RA6E2 Evaluation Kit - - EK-RA6E2 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detailed hardware feature for the RA6E2 MCU group can be found at `RA6E2 Group User's Manual Hardware`_ +Detailed hardware features for the RA6E2 MCU group can be found at `RA6E2 Group User's Manual Hardware`_ .. figure:: ra6e2_block_diagram.webp :width: 442px @@ -78,12 +69,12 @@ Detailed hardware feature for the RA6E2 MCU group can be found at `RA6E2 Group U RA6E2 Block diagram (Credit: Renesas Electronics Corporation) -Detailed hardware feature for the EK-RA6E2 MCU can be found at `EK-RA6E2 - User's Manual`_ +Detailed hardware features for the EK-RA6E2 MCU can be found at `EK-RA6E2 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA6E2 board: +The below features are currently supported on Zephyr for EK-RA6E2 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -100,6 +91,16 @@ The below features are currently supported on Zephyr OS for EK-RA6E2 board: +-----------+------------+----------------------+ | SPI | on-chip | spi | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -119,11 +120,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6E2 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6E2 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra6e2/ek_ra6e2-pinctrl.dtsi b/boards/renesas/ek_ra6e2/ek_ra6e2-pinctrl.dtsi index 5c47dd207044d..f8065c394f96d 100644 --- a/boards/renesas/ek_ra6e2/ek_ra6e2-pinctrl.dtsi +++ b/boards/renesas/ek_ra6e2/ek_ra6e2-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -21,4 +21,37 @@ ; }; }; + + canfd0_default: canfd0_default { + group1 { + /* CRX0 CTX0 */ + psels = , + ; + drive-strength = "high"; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; }; diff --git a/boards/renesas/ek_ra6e2/ek_ra6e2.dts b/boards/renesas/ek_ra6e2/ek_ra6e2.dts index a19f1ab5ff8e4..f6fc4abe0680b 100644 --- a/boards/renesas/ek_ra6e2/ek_ra6e2.dts +++ b/boards/renesas/ek_ra6e2/ek_ra6e2.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra6e2-pinctrl.dtsi" @@ -16,9 +18,12 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,canbus = &canfd0; + zephyr,entropy = &trng; }; leds { @@ -37,8 +42,24 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport3 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; }; }; @@ -52,6 +73,10 @@ }; }; +&ioport0 { + status = "okay"; +}; + &ioport1 { status = "okay"; }; @@ -66,26 +91,12 @@ status = "okay"; }; -&ioport4 { +&ioport3 { status = "okay"; }; -&flash0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "application"; - reg = <0x00000000 DT_SIZE_K(128)>; - }; - - storage_partition: partition@20000 { - label = "storage"; - reg = <0x20000 DT_SIZE_K(128)>; - }; - }; +&ioport4 { + status = "okay"; }; &xtal { @@ -105,3 +116,71 @@ mul = <10 0>; status = "okay"; }; + +&canfdclk { + clocks = <&pll>; + div = <8>; + status = "okay"; +}; + +&canfd_global { + status = "okay"; + canfd0 { + pinctrl-0 = <&canfd0_default>; + pinctrl-names = "default"; + rx-max-filters = <16>; + status = "okay"; + + can-transceiver { + max-bitrate = <5000000>; + }; + }; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq9 { + interrupts = <4 12>; + status = "okay"; +}; + +&port_irq10 { + interrupts = <5 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + divider = ; + status = "okay"; +}; + +&trng { + status ="okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(4)>; + }; + }; +}; diff --git a/boards/renesas/ek_ra6e2/ek_ra6e2_defconfig b/boards/renesas/ek_ra6e2/ek_ra6e2_defconfig index 882cf699d986f..770a30fc47db0 100644 --- a/boards/renesas/ek_ra6e2/ek_ra6e2_defconfig +++ b/boards/renesas/ek_ra6e2/ek_ra6e2_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_CONSOLE=y CONFIG_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/ek_ra6m1/doc/index.rst b/boards/renesas/ek_ra6m1/doc/index.rst index 9436486539dad..941d55d089e88 100644 --- a/boards/renesas/ek_ra6m1/doc/index.rst +++ b/boards/renesas/ek_ra6m1/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra6m1: - -RA6M1 Evaluation Kit -#################### +.. zephyr:board:: ek_ra6m1 Overview ******** @@ -17,6 +14,7 @@ low power consumption. The key features of the EK-RA6M1 board are categorized in three groups as follow: **MCU Native Pin Access** + - R7FA6M1AD3CFP - 100-pin LQFP package - 120 MHz ArmÂŽ CortexÂŽ-M4 core with Floating Point Unit (FPU) @@ -25,47 +23,42 @@ The key features of the EK-RA6M1 board are categorized in three groups as follow - 8 KB data flash memory **Connectivity** + - A Device USB connector for the Main MCU - S124 MCU-based SEGGER J-LinkÂŽ On-Board interface for debugging and programming of the -RA6M1 MCU. A 10-pin JTAG/SWD interface is also provided for connecting optional external -debuggers and programmers. + RA6M1 MCU. A 10-pin JTAG/SWD interface is also provided for connecting optional external + debuggers and programmers. - Two PMOD connectors, allowing use of appropriate PMOD compliant peripheral plug-in modules for -rapid prototyping + rapid prototyping. - Pin headers for access to power and signals for the Main MCU **Multiple clock sources** + - Main MCU oscillator crystals, providing precision 12.000 MHz and 32,768 Hz external reference -clocks + clocks - Additional low-precision clocks are available internal to the Main MCU **General purpose I/O ports** + - One jumper to allow measuring of Main MCU current - Copper jumpers on PCB bottom side for configuration and access to selected MCU signals + **Operating voltage** + - External 5 V input through the Debug USB connector supplies the on-board power regulator to power -logic and interfaces on the board. External 5 V or 3.3 V may be also supplied through alternate -locations on the board. + logic and interfaces on the board. External 5 V or 3.3 V may be also supplied through alternate + locations on the board. - A two-color board status LED indicating availability of regulated power and connection status of the J-Link -interface. + interface. - A red User LED, controlled by the Main MCU firmware - A User Push-Button switch, User Capacitive Touch Button sensor, and an optional User Potentiometer, -all of which are controlled by the Main MCU firmware + all of which are controlled by the Main MCU firmware - MCU reset push-button switch - MCU boot configuration jumper -**Special Feature Access** - -- USB Full Speed Debug and Device (micro-AB connector) - -.. figure:: ek_ra6m1.webp - :align: center - :alt: RA6M1 Evaluation Kit - - EK-RA6M1 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detailed hardware feature for the RA6M1 MCU group can be found at `RA6M1 Group User's Manual Hardware`_ +Detailed hardware features for the RA6M1 MCU group can be found at `RA6M1 Group User's Manual Hardware`_ .. figure:: ra6m1_block_diagram.webp :width: 442px @@ -74,12 +67,12 @@ Detailed hardware feature for the RA6M1 MCU group can be found at `RA6M1 Group U RA6M1 Block diagram (Credit: Renesas Electronics Corporation) -Detailed hardware feature for the EK-RA6M1 MCU can be found at `EK-RA6M1 - User's Manual`_ +Detailed hardware features for the EK-RA6M1 MCU can be found at `EK-RA6M1 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA6M1 board: +The below features are currently supported on Zephyr for EK-RA6M1 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -100,6 +93,16 @@ The below features are currently supported on Zephyr OS for EK-RA6M1 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -119,11 +122,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M1 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M1 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra6m1/ek_ra6m1-pinctrl.dtsi b/boards/renesas/ek_ra6m1/ek_ra6m1-pinctrl.dtsi index cb5eb69d6b484..87e76e218caea 100644 --- a/boards/renesas/ek_ra6m1/ek_ra6m1-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m1/ek_ra6m1-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -30,4 +30,36 @@ ; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USB_VBUS */ + psels = ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra6m1/ek_ra6m1.dts b/boards/renesas/ek_ra6m1/ek_ra6m1.dts index e21d57280f748..c89506b825312 100644 --- a/boards/renesas/ek_ra6m1/ek_ra6m1.dts +++ b/boards/renesas/ek_ra6m1/ek_ra6m1.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra6m1-pinctrl.dtsi" @@ -16,9 +18,11 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart8; zephyr,shell-uart = &uart8; + zephyr,entropy = &trng; }; leds { @@ -29,8 +33,18 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport4 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; }; }; @@ -65,6 +79,10 @@ status = "okay"; }; +&ioport4 { + status = "okay"; +}; + &xtal { clock-frequency = ; mosel = <0>; @@ -82,3 +100,61 @@ mul = <20 0>; status = "okay"; }; + +&trng { + status ="okay"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq8 { + interrupts = <41 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(8)>; + }; + }; +}; + +&uclk { + clocks = <&pll>; + div = <5>; + status = "okay"; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra6m1/ek_ra6m1.yaml b/boards/renesas/ek_ra6m1/ek_ra6m1.yaml index 92e8d569db224..5d23e1841edea 100644 --- a/boards/renesas/ek_ra6m1/ek_ra6m1.yaml +++ b/boards/renesas/ek_ra6m1/ek_ra6m1.yaml @@ -10,3 +10,5 @@ toolchain: supported: - gpio - uart + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra6m1/ek_ra6m1_defconfig b/boards/renesas/ek_ra6m1/ek_ra6m1_defconfig index fb0bf97d8885b..35ed0307b9aa5 100644 --- a/boards/renesas/ek_ra6m1/ek_ra6m1_defconfig +++ b/boards/renesas/ek_ra6m1/ek_ra6m1_defconfig @@ -1,14 +1,9 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 - # Enable GPIO CONFIG_GPIO=y -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y - # Enable Console CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/renesas/ek_ra6m2/doc/index.rst b/boards/renesas/ek_ra6m2/doc/index.rst index 59fb6c4d356a0..c7c6a16579f75 100644 --- a/boards/renesas/ek_ra6m2/doc/index.rst +++ b/boards/renesas/ek_ra6m2/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra6m2: - -RA6M2 Evaluation Kit -#################### +.. zephyr:board:: ek_ra6m2 Overview ******** @@ -51,15 +48,9 @@ The key features of the EK-RA6M2 board are categorized in three groups as follow - USB Full Speed Host and Device (micro-AB connector) -.. figure:: ek_ra6m2.webp - :align: center - :alt: RA6M2 Evaluation Kit - - EK-RA6M2 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detailed hardware feature for the RA6M2 MCU group can be found at `RA6M2 Group User's Manual Hardware`_ +Detailed hardware features for the RA6M2 MCU group can be found at `RA6M2 Group User's Manual Hardware`_ .. figure:: ra6m2_block_diagram.webp :width: 871px @@ -68,12 +59,12 @@ Detailed hardware feature for the RA6M2 MCU group can be found at `RA6M2 Group U RA6M2 Block diagram (Credit: Renesas Electronics Corporation) -Detailed hardware feature for the EK-RA6M2 MCU can be found at `EK-RA6M2 - User's Manual`_ +Detailed hardware features for the EK-RA6M2 MCU can be found at `EK-RA6M2 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA6M2 board: +The below features are currently supported on Zephyr for EK-RA6M2 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -94,6 +85,16 @@ The below features are currently supported on Zephyr OS for EK-RA6M2 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. diff --git a/boards/renesas/ek_ra6m2/ek_ra6m2-pinctrl.dtsi b/boards/renesas/ek_ra6m2/ek_ra6m2-pinctrl.dtsi index 45dd5625022e9..85a43362ea8c7 100644 --- a/boards/renesas/ek_ra6m2/ek_ra6m2-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m2/ek_ra6m2-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -30,4 +30,36 @@ ; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USB_VBUS */ + psels = ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra6m2/ek_ra6m2.dts b/boards/renesas/ek_ra6m2/ek_ra6m2.dts index d1fca9242e473..5fcd07f5ad50a 100644 --- a/boards/renesas/ek_ra6m2/ek_ra6m2.dts +++ b/boards/renesas/ek_ra6m2/ek_ra6m2.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra6m2-pinctrl.dtsi" @@ -16,9 +18,11 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart7; zephyr,shell-uart = &uart7; + zephyr,entropy = &trng; }; leds { @@ -29,8 +33,18 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport1 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; }; }; @@ -82,3 +96,61 @@ mul = <20 0>; status = "okay"; }; + +&trng { + status ="okay"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq0 { + interrupts = <41 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(32)>; + }; + }; +}; + +&uclk { + clocks = <&pll>; + div = <5>; + status = "okay"; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra6m2/ek_ra6m2.yaml b/boards/renesas/ek_ra6m2/ek_ra6m2.yaml index 3f3c049c5e563..8ddf34e307c86 100644 --- a/boards/renesas/ek_ra6m2/ek_ra6m2.yaml +++ b/boards/renesas/ek_ra6m2/ek_ra6m2.yaml @@ -9,3 +9,5 @@ toolchain: - gnuarmemb supported: - gpio + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra6m2/ek_ra6m2_defconfig b/boards/renesas/ek_ra6m2/ek_ra6m2_defconfig index fb0bf97d8885b..35ed0307b9aa5 100644 --- a/boards/renesas/ek_ra6m2/ek_ra6m2_defconfig +++ b/boards/renesas/ek_ra6m2/ek_ra6m2_defconfig @@ -1,14 +1,9 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 - # Enable GPIO CONFIG_GPIO=y -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y - # Enable Console CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/renesas/ek_ra6m3/doc/index.rst b/boards/renesas/ek_ra6m3/doc/index.rst index fed1a53207dad..1a898dc3a2756 100644 --- a/boards/renesas/ek_ra6m3/doc/index.rst +++ b/boards/renesas/ek_ra6m3/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra6m3: - -RA6M3 Evaluation Kit -#################### +.. zephyr:board:: ek_ra6m3 Overview ******** @@ -59,15 +56,9 @@ The key features of the EK-RA6M3 board are categorized in three groups as follow - USB High Speed Host and Device (micro-AB connector) - 32 Mb (256 Mb) External Quad-SPI Flash -.. figure:: ek_ra6m3.webp - :align: center - :alt: RA6M3 Evaluation Kit - - EK-RA6M3 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detailed hardware feature for the RA6M3 MCU group can be found at `RA6M3 Group User's Manual Hardware`_ +Detailed hardware features for the RA6M3 MCU group can be found at `RA6M3 Group User's Manual Hardware`_ .. figure:: ra6m3_block_diagram.webp :width: 442px @@ -76,12 +67,12 @@ Detailed hardware feature for the RA6M3 MCU group can be found at `RA6M3 Group U RA6M3 Block diagram (Credit: Renesas Electronics Corporation) -Detail hardware feature for the EK-RA6M3 MCU can be found at `EK-RA6M3 - User's Manual`_ +Detailed hardware features for the EK-RA6M3 MCU can be found at `EK-RA6M3 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA6M3 board: +The below features are currently supported on Zephyr for EK-RA6M3 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -102,6 +93,18 @@ The below features are currently supported on Zephyr OS for EK-RA6M3 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| USBHS | on-chip | udc | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -121,11 +124,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M3 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M3 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra6m3/ek_ra6m3-pinctrl.dtsi b/boards/renesas/ek_ra6m3/ek_ra6m3-pinctrl.dtsi index d1efcc91ba427..525b985659d8a 100644 --- a/boards/renesas/ek_ra6m3/ek_ra6m3-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m3/ek_ra6m3-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -30,4 +30,43 @@ ; }; }; + + usbhs_default: usbhs_default { + group1 { + psels = ; /* VBUS */ + drive-strength = "high"; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USB_VBUS */ + psels = ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra6m3/ek_ra6m3.dts b/boards/renesas/ek_ra6m3/ek_ra6m3.dts index 96b9bac56305e..6876f280e4e40 100644 --- a/boards/renesas/ek_ra6m3/ek_ra6m3.dts +++ b/boards/renesas/ek_ra6m3/ek_ra6m3.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra6m3-pinctrl.dtsi" @@ -18,7 +20,9 @@ zephyr,sram = &sram0; zephyr,console = &uart8; zephyr,shell-uart = &uart8; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; + zephyr,entropy = &trng; }; leds { @@ -37,8 +41,24 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; }; }; @@ -48,6 +68,10 @@ status = "okay"; }; +&ioport0 { + status = "okay"; +}; + &ioport1 { status = "okay"; }; @@ -94,3 +118,76 @@ mul = <20 0>; status = "okay"; }; + +&trng { + status ="okay"; +}; + +&uclk { + clocks = <&pll>; + div = <5>; + status = "okay"; +}; + +&usbhs { + pinctrl-0 = <&usbhs_default>; + pinctrl-names = "default"; + maximum-speed = "high-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; + +&usbhs_phy { + phys-clock-src = "xtal"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq12 { + interrupts = <41 12>; + status = "okay"; +}; + +&port_irq13 { + interrupts = <42 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(64)>; + }; + }; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; +}; diff --git a/boards/renesas/ek_ra6m3/ek_ra6m3.yaml b/boards/renesas/ek_ra6m3/ek_ra6m3.yaml index 50cc8737e921f..16aa58a8f5c6d 100644 --- a/boards/renesas/ek_ra6m3/ek_ra6m3.yaml +++ b/boards/renesas/ek_ra6m3/ek_ra6m3.yaml @@ -9,3 +9,5 @@ toolchain: - gnuarmemb supported: - gpio + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra6m3/ek_ra6m3_defconfig b/boards/renesas/ek_ra6m3/ek_ra6m3_defconfig index 914980bc08c8c..791f9faca4092 100644 --- a/boards/renesas/ek_ra6m3/ek_ra6m3_defconfig +++ b/boards/renesas/ek_ra6m3/ek_ra6m3_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/ek_ra6m4/doc/index.rst b/boards/renesas/ek_ra6m4/doc/index.rst index 1232b815e8709..6e65ebeeed79a 100644 --- a/boards/renesas/ek_ra6m4/doc/index.rst +++ b/boards/renesas/ek_ra6m4/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra6m4: - -RA6M4 Evaluation Kit -#################### +.. zephyr:board:: ek_ra6m4 Overview ******** @@ -64,15 +61,9 @@ The key features of the EK-RA6M4 board are categorized in three groups as follow - 32 Mb (256 Mb) External Quad-SPI Flash - 64 Mb (512 Mb) External Octo-SPI Flash -.. figure:: ek_ra6m4.webp - :align: center - :alt: RA6M4 Evaluation Kit - - EK-RA6M4 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detailed hardware feature for the RA6M4 MCU group can be found at `RA6M4 Group User's Manual Hardware`_ +Detailed hardware features for the RA6M4 MCU group can be found at `RA6M4 Group User's Manual Hardware`_ .. figure:: ra6m4_block_diagram.webp :width: 442px @@ -81,12 +72,12 @@ Detailed hardware feature for the RA6M4 MCU group can be found at `RA6M4 Group U RA6M4 Block diagram (Credit: Renesas Electronics Corporation) -Detailed hardware feature for the EK-RA6M4 MCU can be found at `EK-RA6M4 - User's Manual`_ +Detailed hardware features for the EK-RA6M4 MCU can be found at `EK-RA6M4 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA6M4 board: +The below features are currently supported on Zephyr for EK-RA6M4 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -107,6 +98,18 @@ The below features are currently supported on Zephyr OS for EK-RA6M4 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -126,11 +129,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M4 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M4 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi b/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi index 5519f92f74f9d..86e7a2506f813 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -30,4 +30,36 @@ ; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USB_VBUS */ + psels = ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4.dts b/boards/renesas/ek_ra6m4/ek_ra6m4.dts index 2f3b9eb3acd22..3eda814aa1bda 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4.dts +++ b/boards/renesas/ek_ra6m4/ek_ra6m4.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra6m4-pinctrl.dtsi" @@ -16,9 +18,11 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; }; leds { @@ -37,8 +41,24 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport0 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; }; }; @@ -69,6 +89,10 @@ status = "okay"; }; +&ioport0 { + status = "okay"; +}; + &ioport4 { status = "okay"; }; @@ -91,8 +115,78 @@ status = "okay"; }; +&pll2 { + clocks = <&hoco>; + div = <2>; + mul = <24 0>; + status = "okay"; +}; + &pclka { clocks = <&pll>; div = <2>; status = "okay"; }; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq10 { + interrupts = <41 12>; + status = "okay"; +}; + +&port_irq11 { + interrupts = <42 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(8)>; + }; + }; +}; + +&trng { + status = "okay"; +}; + +&uclk { + clocks = <&pll2>; + div = <5>; + status = "okay"; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4.yaml b/boards/renesas/ek_ra6m4/ek_ra6m4.yaml index d9488b99e8129..6f6f324f20253 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4.yaml +++ b/boards/renesas/ek_ra6m4/ek_ra6m4.yaml @@ -9,3 +9,5 @@ toolchain: - gnuarmemb supported: - gpio + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4_defconfig b/boards/renesas/ek_ra6m4/ek_ra6m4_defconfig index 7d9405d620489..791f9faca4092 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4_defconfig +++ b/boards/renesas/ek_ra6m4/ek_ra6m4_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/ek_ra6m5/doc/index.rst b/boards/renesas/ek_ra6m5/doc/index.rst index 6c8a708dc09d4..5e3dd4b2683a4 100644 --- a/boards/renesas/ek_ra6m5/doc/index.rst +++ b/boards/renesas/ek_ra6m5/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra6m5: - -RA6M5 Evaluation Kit -#################### +.. zephyr:board:: ek_ra6m5 Overview ******** @@ -62,15 +59,9 @@ The key features of the EK-RA6M5 board are categorized in three groups as follow - 64 Mb (512 Mb) External Octo-SPI Flash - CAN (3-pin header) -.. figure:: ek_ra6m5.webp - :align: center - :alt: RA6M5 Evaluation Kit - - EK-RA6M5 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detailed hardware feature for the RA6M5 MCU group can be found at `RA6M5 Group User's Manual Hardware`_ +Detailed hardware features for the RA6M5 MCU group can be found at `RA6M5 Group User's Manual Hardware`_ .. figure:: ra6m5_block_diagram.webp :width: 442px @@ -79,12 +70,12 @@ Detailed hardware feature for the RA6M5 MCU group can be found at `RA6M5 Group U RA6M5 Block diagram (Credit: Renesas Electronics Corporation) -Detailed hardware feature for the EK-RA6M5 MCU can be found at `EK-RA6M5 - User's Manual`_ +Detailed hardware features for the EK-RA6M5 MCU can be found at `EK-RA6M5 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA6M5 board: +The below features are currently supported on Zephyr for EK-RA6M5 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -105,6 +96,20 @@ The below features are currently supported on Zephyr OS for EK-RA6M5 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| USBHS | on-chip | udc | ++-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -124,11 +129,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M5 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA6M5 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi b/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi index 5519f92f74f9d..b279f0540ad1b 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -30,4 +30,43 @@ ; }; }; + + usbhs_default: usbhs_default { + group1 { + psels = ; /* USBHS-VBUS */ + drive-strength = "high"; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USB_VBUS */ + psels = ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5.dts b/boards/renesas/ek_ra6m5/ek_ra6m5.dts index 7abc7292c0c6e..929765d4f9b3d 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5.dts +++ b/boards/renesas/ek_ra6m5/ek_ra6m5.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "ek_ra6m5-pinctrl.dtsi" @@ -16,9 +18,11 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; }; leds { @@ -37,8 +41,24 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport0 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; }; }; @@ -90,3 +110,83 @@ mul = <25 0>; status = "okay"; }; + +&pll2 { + clocks = <&xtal>; + div = <2>; + mul = <20 0>; + status = "okay"; +}; + +&uclk { + clocks = <&pll2>; + div = <5>; + status = "okay"; +}; + +&usbhs { + pinctrl-0 = <&usbhs_default>; + pinctrl-names = "default"; + maximum-speed = "high-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; + +&usbhs_phy { + phys-clock-src = "xtal"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq9 { + interrupts = <41 12>; + status = "okay"; +}; + +&port_irq10 { + interrupts = <42 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(8)>; + }; + }; +}; + +&trng { + status = "okay"; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; +}; diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5.yaml b/boards/renesas/ek_ra6m5/ek_ra6m5.yaml index 2f65bfb229d83..4ce78217fd2f7 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5.yaml +++ b/boards/renesas/ek_ra6m5/ek_ra6m5.yaml @@ -9,3 +9,5 @@ toolchain: - gnuarmemb supported: - gpio + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5_defconfig b/boards/renesas/ek_ra6m5/ek_ra6m5_defconfig index 6a9a032666e9a..35ed0307b9aa5 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5_defconfig +++ b/boards/renesas/ek_ra6m5/ek_ra6m5_defconfig @@ -1,14 +1,9 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 - # Enable GPIO CONFIG_GPIO=y -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y - # Enable Console CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/renesas/ek_ra8d1/CMakeLists.txt b/boards/renesas/ek_ra8d1/CMakeLists.txt new file mode 100644 index 0000000000000..86d1cedc6f4b5 --- /dev/null +++ b/boards/renesas/ek_ra8d1/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_linker_sources_ifdef(CONFIG_MEMC + SECTIONS sdram.ld) diff --git a/boards/renesas/ek_ra8d1/Kconfig.defconfig b/boards/renesas/ek_ra8d1/Kconfig.defconfig index d99c0d945ba15..db92a2bd46118 100644 --- a/boards/renesas/ek_ra8d1/Kconfig.defconfig +++ b/boards/renesas/ek_ra8d1/Kconfig.defconfig @@ -10,4 +10,18 @@ config NET_L2_ETHERNET endif # NETWORKING +if SHIELD_RTKMIPILCDB00000BE + +config MEMC + default y + +if LVGL + +config LV_Z_VDB_CUSTOM_SECTION + default y + +endif # LVGL + +endif # SHIELD_RTKMIPILCDB00000BE + endif # BOARD_EK_RA8D1 diff --git a/boards/renesas/ek_ra8d1/doc/index.rst b/boards/renesas/ek_ra8d1/doc/index.rst index bed54638bd279..c1275bd196df9 100644 --- a/boards/renesas/ek_ra8d1/doc/index.rst +++ b/boards/renesas/ek_ra8d1/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra8d1: - -RA8D1 Evaluation Kit -#################### +.. zephyr:board:: ek_ra8d1 Overview ******** @@ -61,15 +58,9 @@ The key features of the EK-RA8D1 board are categorized in three groups as follow - 512 Mb (64 MB) External Octo-SPI Flash (present in the MCU Native Pin Access area of the EK-RA8D1 board) - CAN FD (3-pin header) -.. figure:: ek_ra8d1.jpg - :align: center - :alt: RA8D1 Evaluation Kit - - EK-RA8D1 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detail Hardware feature for the RA8D1 MCU group can be found at `RA8D1 Group User's Manual Hardware`_ +Detailed Hardware features for the RA8D1 MCU group can be found at `RA8D1 Group User's Manual Hardware`_ .. figure:: ra8d1_block_diagram.png :width: 442px @@ -78,44 +69,59 @@ Detail Hardware feature for the RA8D1 MCU group can be found at `RA8D1 Group Use RA8D1 Block diagram (Credit: Renesas Electronics Corporation) -Detail Hardware feature for the EK-RA8D1 MCU can be found at `EK-RA8D1 - User's Manual`_ +Detailed Hardware features for the EK-RA8D1 MCU can be found at `EK-RA8D1 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA8D1 board: - -+--------------+------------+------------------+ -| Interface | Controller | Driver/Component | -+==============+============+==================+ -| GPIO | on-chip | gpio | -+--------------+------------+------------------+ -| MPU | on-chip | arch/arm | -+--------------+------------+------------------+ -| NVIC | on-chip | arch/arm | -+--------------+------------+------------------+ -| UART | on-chip | serial | -+--------------+------------+------------------+ -| CLOCK | on-chip | clock control | -+--------------+------------+------------------+ -| ENTROPY | on-chip | entropy | -+--------------+------------+------------------+ -| SPI | on-chip | spi | -+--------------+------------+------------------+ -| FLASH | on-chip | flash | -+--------------+------------+------------------+ -| PWM | on-chip | pwm | -+--------------+------------+------------------+ -| COUNTER | on-chip | counter | -+--------------+------------+------------------+ -| CAN | on-chip | canfd | -+--------------+------------+------------------+ -| I2C | on-chip | i2c | -+--------------+------------+------------------+ -| ETHERNET | on-chip | ethernet | -+--------------+------------+------------------+ - -**Note:** for using Ethernet on RA8D1 board please set switch SW1 as following configuration: +The below features are currently supported on Zephyr for EK-RA8D1 board: + ++--------------+------------+-----------------------------------+ +| Interface | Controller | Driver/Component | ++==============+============+===================================+ +| GPIO | on-chip | gpio | ++--------------+------------+-----------------------------------+ +| MPU | on-chip | arch/arm | ++--------------+------------+-----------------------------------+ +| NVIC | on-chip | arch/arm | ++--------------+------------+-----------------------------------+ +| UART | on-chip | serial | ++--------------+------------+-----------------------------------+ +| CLOCK | on-chip | clock control | ++--------------+------------+-----------------------------------+ +| ENTROPY | on-chip | entropy | ++--------------+------------+-----------------------------------+ +| SPI | on-chip | spi | ++--------------+------------+-----------------------------------+ +| FLASH | on-chip | flash | ++--------------+------------+-----------------------------------+ +| PWM | on-chip | pwm | ++--------------+------------+-----------------------------------+ +| COUNTER | on-chip | counter | ++--------------+------------+-----------------------------------+ +| CAN | on-chip | canfd | ++--------------+------------+-----------------------------------+ +| I2C | on-chip | i2c | ++--------------+------------+-----------------------------------+ +| USBHS | on-chip | udc | ++--------------+------------+-----------------------------------+ +| USBFS | on-chip | udc | ++--------------+------------+-----------------------------------+ +| DISPLAY | on-chip | LCDIF; MIPI-DSI. Tested with | +| | | :ref:`rtkmipilcdb00000be` shields | ++--------------+------------+-----------------------------------+ +| ETHERNET | on-chip | ethernet | ++--------------+------------+-----------------------------------+ +| ADC | on-chip | adc | ++--------------+------------+-----------------------------------+ +| SDHC | on-chip | sdhc | ++--------------+------------+-----------------------------------+ +| DAC | on-chip | dac | ++--------------+------------+-----------------------------------+ + +**Note:** + +- For using Ethernet on RA8D1 board please set switch SW1 as following configuration: +-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ | SW1-1 PMOD1 | SW1-2 TRACE | SW1-3 CAMERA | SW1-4 ETHA | SW1-5 ETHB | SW1-6 GLCD | SW1-7 SDRAM | SW1-8 I3C | @@ -123,6 +129,14 @@ The below features are currently supported on Zephyr OS for EK-RA8D1 board: | OFF | OFF | OFF | OFF | ON | OFF | OFF | OFF | +-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ +- For using SDHC channel 1 on RA8D1 board please set switch SW1 as following configuration: + ++-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ +| SW1-1 PMOD1 | SW1-2 TRACE | SW1-3 CAMERA | SW1-4 ETHA | SW1-5 ETHB | SW1-6 GLCD | SW1-7 SDRAM | SW1-8 I3C | ++-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ +| OFF | OFF | OFF | OFF | OFF | OFF | OFF | OFF | ++-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ + **CAUTION:** Do not enable SW1-4 and SW1-5 together Other hardware features are currently not supported by the port. @@ -146,11 +160,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA8D1 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA8D1 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi b/boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi index a96d4d225f211..4ae1dcec244a2 100644 --- a/boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi +++ b/boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,7 @@ }; }; - spi0_default: spi0_default { + spi1_default: spi1_default { group1 { /* MISO MOSI RSPCK SSL */ psels = , @@ -70,4 +70,213 @@ drive-strength = "high"; }; }; + + usbhs_default: usbhs_default { + group1 { + psels = ; /* USBHS-VBUS */ + drive-strength = "high"; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + sdram_default: sdram_default{ + group1 { + /* SDRAM_DQM1 */ + psels = , + /* SDRAM_CKE */ + , + /* SDRAM_WE */ + , + /* SDRAM_CS */ + , + /* SDRAM_A0 */ + , + /* SDRAM_A1 */ + , + /* SDRAM_A2 */ + , + /* SDRAM_A3 */ + , + /* SDRAM_A4 */ + , + /* SDRAM_A5 */ + , + /* SDRAM_A6 */ + , + /* SDRAM_A7 */ + , + /* SDRAM_A8 */ + , + /* SDRAM_A9 */ + , + /* SDRAM_A10 */ + , + /* SDRAM_A11 */ + , + /* SDRAM_A12 */ + , + /* SDRAM_D0 */ + , + /* SDRAM_D1 */ + , + /* SDRAM_D2 */ + , + /* SDRAM_D3 */ + , + /* SDRAM_D4 */ + , + /* SDRAM_D5 */ + , + /* SDRAM_D6 */ + , + /* SDRAM_D8 */ + , + /* SDRAM_D9 */ + , + /* SDRAM_D10 */ + , + /* SDRAM_D11 */ + , + /* SDRAM_D12 */ + , + /* SDRAM_D13 */ + , + /* SDRAM_D14 */ + , + /* SDRAM_BA0 */ + , + /* SDRAM_BA1 */ + , + /* SDRAM_RAS */ + , + /* SDRAM_CAS */ + , + /* SDRAM_SDCLK */ + ; + drive-strength = "high"; + }; + + group2 { + /* SDRAM_SDCLK */ + psels = ; + drive-strength = "highspeed-high"; + }; + + group3 { + /* SDRAM_D7 */ + psels = , + /* SDRAM_D15 */ + , + /* SDRAM_DQM0 */ + ; + }; + }; + + glcdc_default: glcdc_default { + group1 { + /* LCDC_TCON0 */ + psels = , + /* LCDC_TCON1 */ + , + /* LCDC_TCON2 */ + , + /* LCDC_TCON3 */ + , + /* LCDC_DATA00 */ + , + /* LCDC_DATA01 */ + , + /* LCDC_DATA02 */ + , + /* LCDC_DATA03 */ + , + /* LCDC_DATA04 */ + , + /* LCDC_DATA05 */ + , + /* LCDC_DATA06 */ + , + /* LCDC_DATA07 */ + , + /* LCDC_DATA08 */ + , + /* LCDC_DATA09 */ + , + /* LCDC_DATA10 */ + , + /* LCDC_DATA11 */ + , + /* LCDC_DATA12 */ + , + /* LCDC_DATA13 */ + , + /* LCDC_DATA14 */ + , + /* LCDC_DATA15 */ + , + /* LCDC_DATA16 */ + , + /* LCDC_DATA17 */ + , + /* LCDC_DATA18 */ + , + /* LCDC_DATA19 */ + , + /* LCDC_DATA20 */ + , + /* LCDC_DATA21 */ + , + /* LCDC_DATA22 */ + , + /* LCDC_DATA23 */ + , + /* LCDC_CLK */ + , + /* LCDC_EXTCLK */ + ; + }; + }; + + /* NOTE: pins conflict with ether_default */ + sdhc1_default: sdhc1_default { + group1 { + psels = , /* SDCD */ + , /* SDCMD */ + , /* SDDATA0 */ + , /* SDDATA1 */ + , /* SDDATA2 */ + , /* SDDATA3 */ + ; /* SDWP */ + drive-strength = "high"; + }; + group2 { + psels = ; /* SDCLK */ + drive-strength = "highspeed-high"; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USBP USBN */ + psels = , + , + ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra8d1/ek_ra8d1.dts b/boards/renesas/ek_ra8d1/ek_ra8d1.dts index 6ef2af8b46bd4..d7fe352b1763d 100644 --- a/boards/renesas/ek_ra8d1/ek_ra8d1.dts +++ b/boards/renesas/ek_ra8d1/ek_ra8d1.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,10 @@ #include #include - +#include +#include +#include +#include #include "ek_ra8d1-pinctrl.dtsi" / { @@ -40,8 +43,45 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + + sdram1: sdram@68000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + device_type = "memory"; + reg = <0x68000000 DT_SIZE_M(64)>; /* 512 Mbits */ + zephyr,memory-region = "SDRAM"; + status = "okay"; + }; + + renesas_mipi_connector: mipi-connector { + compatible = "renesas,ra-gpio-mipi-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <14 0 &ioport5 11 0>, /* IIC_SDA */ + <15 0 &ioport4 4 0>, /* DISP_BLEN */ + <16 0 &ioport5 12 0>, /* IIC_SCL */ + <17 0 &ioport5 10 0>, /* DISP_INT */ + <18 0 &ioporta 1 0>; /* DISP_RST */ + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; + mipi-dsi = &mipi_dsi; }; }; @@ -63,6 +103,8 @@ }; pllq { + div = <4>; + freq = ; status = "okay"; }; @@ -71,7 +113,6 @@ }; }; - &sciclk { clocks = <&pllp>; div = <4>; @@ -79,11 +120,27 @@ }; &canfdclk { + clocks = <&pllp>; + div = <6>; + status = "okay"; +}; + +&lcdclk { clocks = <&pll>; + div = <2>; + status = "okay"; +}; + +&uclk { + clocks = <&pllq>; div = <5>; status = "okay"; }; +&ioport0 { + status = "okay"; +}; + &ioport1 { status = "okay"; }; @@ -92,14 +149,16 @@ status = "okay"; }; +&ioport5 { + status = "okay"; +}; + &ioport6 { status = "okay"; }; -&sci0 { - /* sci0 and spi0 cannot be enabled together */ - pinctrl-0 = <&sci9_default>; - pinctrl-names = "default"; +&ioporta { + status = "okay"; }; &sci9 { @@ -116,8 +175,8 @@ status = "okay"; }; -&spi0 { - pinctrl-0 = <&spi0_default>; +&spi1 { + pinctrl-0 = <&spi1_default>; pinctrl-names = "default"; status = "okay"; }; @@ -178,3 +237,79 @@ status = "okay"; }; }; + +&usbhs { + pinctrl-0 = <&usbhs_default>; + pinctrl-names = "default"; + maximum-speed = "high-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; + +&usbhs_phy { + phys-clock-src = "xtal"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq12 { + interrupts = <88 12>; + status = "okay"; +}; + +&port_irq13 { + interrupts = <89 12>; + status = "okay"; +}; + +&sdram { + pinctrl-0 = <&sdram_default>; + pinctrl-names = "default"; + status = "okay"; + auto-refresh-interval = ; + auto-refresh-count = ; + precharge-cycle-count = ; + multiplex-addr-shift = "10-bit"; + edian-mode = "little-endian"; + continuous-access; + bus-width = "16-bit"; + bank@0 { + reg = <0>; + renesas,ra-sdram-timing = ; + }; +}; + +zephyr_lcdif: &lcdif { + pinctrl-0 = <&glcdc_default>; + pinctrl-names = "default"; +}; + +zephyr_mipi_dsi: &mipi_dsi {}; + +renesas_mipi_i2c: &iic1{}; + +pmod_sd_shield: &sdhc1 {}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; +}; diff --git a/boards/renesas/ek_ra8d1/ek_ra8d1.yaml b/boards/renesas/ek_ra8d1/ek_ra8d1.yaml index 2432f8ed657c6..49272cd4c480a 100644 --- a/boards/renesas/ek_ra8d1/ek_ra8d1.yaml +++ b/boards/renesas/ek_ra8d1/ek_ra8d1.yaml @@ -10,3 +10,5 @@ toolchain: supported: - gpio - uart + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra8d1/ek_ra8d1_defconfig b/boards/renesas/ek_ra8d1/ek_ra8d1_defconfig index 1f67b94e7c110..35ed0307b9aa5 100644 --- a/boards/renesas/ek_ra8d1/ek_ra8d1_defconfig +++ b/boards/renesas/ek_ra8d1/ek_ra8d1_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=480000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_CONSOLE=y -CONFIG_CLOCK_CONTROL=y - -CONFIG_BUILD_OUTPUT_HEX=y diff --git a/boards/renesas/ek_ra8d1/sdram.ld b/boards/renesas/ek_ra8d1/sdram.ld new file mode 100644 index 0000000000000..5855e663d0951 --- /dev/null +++ b/boards/renesas/ek_ra8d1/sdram.ld @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(sdram1), okay) + +SECTION_DATA_PROLOGUE(.sdram,(NOLOAD),) +{ + __SDRAM_Start = .; + KEEP(*(.sdram*)) +#ifdef CONFIG_LVGL + KEEP(*(.lvgl_buf*)) +#endif + __SDRAM_End = .; +} GROUP_LINK_IN(SDRAM) + +#endif diff --git a/boards/renesas/ek_ra8m1/doc/index.rst b/boards/renesas/ek_ra8m1/doc/index.rst index d62ed9c3937ed..3dd8bf440c4c5 100644 --- a/boards/renesas/ek_ra8m1/doc/index.rst +++ b/boards/renesas/ek_ra8m1/doc/index.rst @@ -1,7 +1,4 @@ -.. _ek_ra8m1: - -RA8M1 Evaluation Kit -#################### +.. zephyr:board:: ek_ra8m1 Overview ******** @@ -61,15 +58,9 @@ The key features of the EK-RA8M1 board are categorized in three groups as follow - 512 Mb (64 MB) External Octo-SPI Flash (present in the MCU Native Pin Access area of the EK-RA8M1 board) - CAN FD (3-pin header) -.. figure:: ek_ra8m1.jpg - :align: center - :alt: RA8M1 Evaluation Kit - - EK-RA8M1 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detail Hardware feature for the RA8M1 MCU group can be found at `RA8M1 Group User's Manual Hardware`_ +Detailed Hardware features for the RA8M1 MCU group can be found at `RA8M1 Group User's Manual Hardware`_ .. figure:: ra8m1_block_diagram.jpg :width: 442px @@ -78,12 +69,12 @@ Detail Hardware feature for the RA8M1 MCU group can be found at `RA8M1 Group Use RA8M1 Block diagram (Credit: Renesas Electronics Corporation) -Detail Hardware feature for the EK-RA8M1 MCU can be found at `EK-RA8M1 - User's Manual`_ +Detailed Hardware features for the EK-RA8M1 MCU can be found at `EK-RA8M1 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for EK-RA8M1 board: +The below features are currently supported on Zephyr for EK-RA8M1 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -112,10 +103,23 @@ The below features are currently supported on Zephyr OS for EK-RA8M1 board: +-----------+------------+----------------------+ | CAN | on-chip | canfd | +-----------+------------+----------------------+ +| USBHS | on-chip | udc | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ | ETHERNET | on-chip | ethernet | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| SDHC | on-chip | sdhc | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ + +**Note:** -**Note:** For using Ethernet module on EK-RA8M1, remove jumper J61 to enable Ethernet B +- For using Ethernet module on EK-RA8M1, remove jumper J61 to enable Ethernet B +- For using SDHC driver on EK-RA8M1, remove jumper J61 to use with channel 0 Other hardware features are currently not supported by the port. @@ -138,11 +142,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA8M1 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `EK-RA8M1 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi b/boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi index cac279265a133..cdb7b3f9c9337 100644 --- a/boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi +++ b/boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -68,6 +68,14 @@ }; }; + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + spi1_default: spi1_default { group1 { /* MISO MOSI RSPCK SSL*/ @@ -114,4 +122,38 @@ drive-strength = "high"; }; }; + + usbhs_default: usbhs_default { + group1 { + psels = ; /* VBUS */ + drive-strength = "high"; + }; + }; + + sdhc0_default: sdhc0_default { + group1 { + psels = , /* SDCD */ + , /* SDCMD */ + , /* SDDATA0 */ + , /* SDDATA1 */ + , /* SDDATA2 */ + , /* SDDATA3 */ + ; /* SDWP */ + drive-strength = "high"; + }; + group2 { + psels = ; /* SDCLK */ + drive-strength = "highspeed-high"; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USBP USBN */ + psels = , + , + ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra8m1/ek_ra8m1.dts b/boards/renesas/ek_ra8m1/ek_ra8m1.dts index daeeaff22778d..e3fb1d54568fd 100644 --- a/boards/renesas/ek_ra8m1/ek_ra8m1.dts +++ b/boards/renesas/ek_ra8m1/ek_ra8m1.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include #include #include +#include #include "ek_ra8m1-pinctrl.dtsi" / { @@ -93,8 +94,24 @@ <7 0 &ioport8 11 0>; /* IO8 */ }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + button1: s2 { + gpios = <&ioport0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 2"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; + sw1 = &button1; }; transceiver0: can-phy0 { @@ -123,6 +140,8 @@ }; pllq { + div = <4>; + freq = ; status = "okay"; }; @@ -139,7 +158,13 @@ }; &canfdclk { - clocks = <&pll>; + clocks = <&pllp>; + div = <6>; + status = "okay"; +}; + +&uclk { + clocks = <&pllq>; div = <5>; status = "okay"; }; @@ -238,6 +263,13 @@ mikrobus_serial: &uart3 {}; status = "okay"; pinctrl-0 = <&adc0_default>; pinctrl-names = "default"; + average-count = <4>; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; }; &trng { @@ -305,3 +337,35 @@ pmod_header: &pmod1_header {}; status = "okay"; }; }; + +&usbhs { + pinctrl-0 = <&usbhs_default>; + pinctrl-names = "default"; + maximum-speed = "high-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; + +&usbhs_phy { + phys-clock-src = "xtal"; +}; + +&port_irq12 { + interrupts = <88 12>; + status = "okay"; +}; + +&port_irq13 { + interrupts = <89 12>; + status = "okay"; +}; + +pmod_sd_shield: &sdhc0 {}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; +}; diff --git a/boards/renesas/ek_ra8m1/ek_ra8m1.yaml b/boards/renesas/ek_ra8m1/ek_ra8m1.yaml index 28c7aa4296b7b..8e3881a1a2d5d 100644 --- a/boards/renesas/ek_ra8m1/ek_ra8m1.yaml +++ b/boards/renesas/ek_ra8m1/ek_ra8m1.yaml @@ -10,3 +10,5 @@ toolchain: supported: - gpio - uart + - usbd +vendor: renesas diff --git a/boards/renesas/ek_ra8m1/ek_ra8m1_defconfig b/boards/renesas/ek_ra8m1/ek_ra8m1_defconfig index d20f50324687f..35ed0307b9aa5 100644 --- a/boards/renesas/ek_ra8m1/ek_ra8m1_defconfig +++ b/boards/renesas/ek_ra8m1/ek_ra8m1_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=480000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/fpb_ra4e1/Kconfig.fpb_ra4e1 b/boards/renesas/fpb_ra4e1/Kconfig.fpb_ra4e1 new file mode 100644 index 0000000000000..0f57b0aedb911 --- /dev/null +++ b/boards/renesas/fpb_ra4e1/Kconfig.fpb_ra4e1 @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FPB_RA4E1 + select SOC_R7FA4E10D2CFM diff --git a/boards/renesas/fpb_ra4e1/board.cmake b/boards/renesas/fpb_ra4e1/board.cmake new file mode 100644 index 0000000000000..590f06a574311 --- /dev/null +++ b/boards/renesas/fpb_ra4e1/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=R7FA4E10D") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/renesas/fpb_ra4e1/board.yml b/boards/renesas/fpb_ra4e1/board.yml new file mode 100644 index 0000000000000..49c5b77196d7e --- /dev/null +++ b/boards/renesas/fpb_ra4e1/board.yml @@ -0,0 +1,6 @@ +board: + name: fpb_ra4e1 + full_name: RA4E1 Fast Prototyping Board + vendor: renesas + socs: + - name: r7fa4e10d2cfm diff --git a/boards/renesas/fpb_ra4e1/doc/fpb_ra4e1.webp b/boards/renesas/fpb_ra4e1/doc/fpb_ra4e1.webp new file mode 100644 index 0000000000000..3a09486138587 Binary files /dev/null and b/boards/renesas/fpb_ra4e1/doc/fpb_ra4e1.webp differ diff --git a/boards/renesas/fpb_ra4e1/doc/index.rst b/boards/renesas/fpb_ra4e1/doc/index.rst new file mode 100644 index 0000000000000..5f5898f595655 --- /dev/null +++ b/boards/renesas/fpb_ra4e1/doc/index.rst @@ -0,0 +1,155 @@ +.. zephyr:board:: fpb_ra4e1 + +Overview +******** + +The Renesas RA4E1 Group delivers up to 100 MHz of CPU performance using an ArmÂŽ CortexÂŽ-M33 core +with 512 KB code flash memory, 8 KB of data flash memory, and 128 KB of SRAM. RA4E1 MCUs +offer leading-performance. The RA4E1 Group offers a wide set of peripherals, including +USB 2.0 Full-Speed, Quad SPI, and advanced analog. + +The MCU in this series incorporates a high-performance Arm CortexÂŽ-M33 core running up to +100 MHz with the following features: + +**MCU Native Pin Access** + +- R7FA4E10D2CFM MCU (referred to as RA MCU) +- 100 MHz, ArmÂŽ CortexÂŽ-M33 core +- 512 KB Code Flash, 8 KB Data Flash, 128 KB SRAM +- 64 pins, LQFP package +- Native pin access through 2 x 50-pin male headers (not fitted) +- MCU current measurement point for precision current consumption measurement +- Multiple clock sources - Low-precision (~1%) clocks are available internal to the RA MCU. + RA MCU oscillator and sub-clock oscillator crystals, providing precision 24.000 MHz (not fitted) + and 32,768 Hz reference clocks are also available + +**System Control and Ecosystem Access** + +- Two 5 V input sources + + - USB (Debug, Full Speed) + - External power supply (using 2-pin header) (not fitted) + +- Built-in SEGGER J-Link Emulator On-Board programmer/debugger (SWD) + +- User LEDs and buttons + + - Two User LEDs (green) + - Power LED (green) (not fitted) indicating availability of regulated power + - Debug/power LED (yellow) indicating power and the debug connection + - One User button + - One Reset button + +- Two popular ecosystem expansions + + - Two Digilent PmodTM (SPI, UART) connectors (not fitted) + - ArduinoTM (Uno R3) connectors + +- MCU boot configuration jumper (not fitted) + +Hardware +******** + +Detailed hardware features can be found at: + +- RA4E1 MCU: `RA4E1 Group User's Manual Hardware`_ +- FPB-RA4E1 board: `FPB-RA4E1 - User's Manual`_ + +Supported Features +================== + +The below features are currently supported on Zephyr for the ``fpb_ra4e1`` board: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock control | ++-----------+------------+----------------------+ +| SPI | on-chip | spi | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| COUNTER | on-chip | counter | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ + +Other hardware features are currently not supported by the port. + +Programming and Debugging +************************* + +Applications for the ``fpb_ra4e1`` board can be +built, flashed, and debugged in the usual way. See +:ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +Flashing +======== + +Program can be flashed to FPB-RA4E1 via the on-board SEGGER J-Link debugger. +SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ + +To flash the program to board + +1. Connect to J-Link OB via USB port to host PC + +2. Make sure J-Link OB jumper is in default configuration as describe in `FPB-RA4E1 - User's Manual`_ + +3. Execute west command + + .. code-block:: console + + west flash -r jlink + +Debugging +========= + +You can use Segger Ozone (`Segger Ozone Download`_) for a visual debug interface + +Once downloaded and installed, open Segger Ozone and configure the debug project +like so: + +* Target Device: R7FA4E10D +* Target Interface: SWD +* Target Interface Speed: 4 MHz +* Host Interface: USB +* Program File: + +**Note:** It's verified that we can debug OK on Segger Ozone v3.30d so please use this or later +version of Segger Ozone + +References +********** + +- `FPB-RA4E1 Website`_ +- `RA4E1 MCU group Website`_ + +.. _FPB-RA4E1 Website: + https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/fpb-ra4e1-fast-prototyping-board-ra4e1-mcu-group + +.. _RA4E1 MCU group Website: + https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra4e1-100mhz-arm-cortex-m33-entry-line-balanced-low-power-consumption-optimized-feature-integration + +.. _FPB-RA4E1 - User's Manual: + https://www.renesas.com/en/document/mat/fpb-ra4e1-users-manual + +.. _RA4E1 Group User's Manual Hardware: + https://www.renesas.com/en/document/mah/ra4e1-group-users-manual-hardware + +.. _Segger Ozone Download: + https://www.segger.com/downloads/jlink#Ozone diff --git a/boards/renesas/fpb_ra4e1/fpb_ra4e1-pinctrl.dtsi b/boards/renesas/fpb_ra4e1/fpb_ra4e1-pinctrl.dtsi new file mode 100644 index 0000000000000..9607fc321d670 --- /dev/null +++ b/boards/renesas/fpb_ra4e1/fpb_ra4e1-pinctrl.dtsi @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci0_default: sci0_default { + group1 { + /* tx rx */ + psels = , + ; + }; + }; + + iic0_default: iic0_default { + group1 { + /* SCL0 SDA0 */ + psels = , + ; + drive-strength = "medium"; + }; + }; + + spi0_default: spi0_default { + group1 { + /* MISO MOSI RSPCK SSL */ + psels = , + , + , + ; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; +}; diff --git a/boards/renesas/fpb_ra4e1/fpb_ra4e1.dts b/boards/renesas/fpb_ra4e1/fpb_ra4e1.dts new file mode 100644 index 0000000000000..76cc3779bb356 --- /dev/null +++ b/boards/renesas/fpb_ra4e1/fpb_ra4e1.dts @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include "fpb_ra4e1-pinctrl.dtsi" + +/ { + model = "Renesas FPB-RA4E1"; + compatible = "renesas,ra4e1", "renesas,ra"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; + }; + + leds { + compatible = "gpio-leds"; + + led1: led1 { + gpios = <&ioport4 8 GPIO_ACTIVE_HIGH>; + label = "LED1"; + }; + + led2: led2 { + gpios = <&ioport4 7 GPIO_ACTIVE_HIGH>; + label = "LED2"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: s1 { + gpios = <&ioport2 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led1; + sw0 = &button0; + }; +}; + +&subclk { + status = "okay"; +}; + +&pll { + clocks = <&hoco>; + div = <2>; + mul = <20 0>; + status = "okay"; +}; + +&sci0 { + pinctrl-0 = <&sci0_default>; + pinctrl-names = "default"; + status = "okay"; + + uart0: uart { + current-speed = <115200>; + status = "okay"; + }; +}; + +&ioport0 { + status = "okay"; +}; + +&ioport1 { + status = "okay"; +}; + +&ioport2 { + status = "okay"; +}; + +&ioport3 { + status = "okay"; +}; + +&ioport4 { + status = "okay"; +}; + +&spi0 { + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&iic0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <91 1>, <92 1>, <93 1>, <94 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + clock-frequency = ; + pinctrl-0 = <&iic0_default>; + pinctrl-names = "default"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&port_irq1 { + interrupts = <41 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(8)>; + }; + }; +}; diff --git a/boards/renesas/fpb_ra4e1/fpb_ra4e1.yaml b/boards/renesas/fpb_ra4e1/fpb_ra4e1.yaml new file mode 100644 index 0000000000000..596ec974006b1 --- /dev/null +++ b/boards/renesas/fpb_ra4e1/fpb_ra4e1.yaml @@ -0,0 +1,12 @@ +identifier: fpb_ra4e1 +name: Renesas FPB-RA4E1 +type: mcu +arch: arm +ram: 128 +flash: 512 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - uart diff --git a/boards/renesas/fpb_ra4e1/fpb_ra4e1_defconfig b/boards/renesas/fpb_ra4e1/fpb_ra4e1_defconfig new file mode 100644 index 0000000000000..f26066de3e521 --- /dev/null +++ b/boards/renesas/fpb_ra4e1/fpb_ra4e1_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Enable Console +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_CONSOLE=y +CONFIG_CONSOLE=y diff --git a/boards/renesas/fpb_ra6e1/doc/index.rst b/boards/renesas/fpb_ra6e1/doc/index.rst index 9d8e73b921955..416d412f910b4 100644 --- a/boards/renesas/fpb_ra6e1/doc/index.rst +++ b/boards/renesas/fpb_ra6e1/doc/index.rst @@ -1,7 +1,4 @@ -.. _fpb_ra6e1: - -RA6E1 Fast Prototyping Board -############################ +.. zephyr:board:: fpb_ra6e1 Overview ******** @@ -46,15 +43,9 @@ The key features of the FPB-RA6E1 board are categorized in three groups as follo - MCU boot configuration jumper -.. figure:: fpb_ra6e1.webp - :align: center - :alt: RA6E1 Fast Prototyping Board - - FPB-RA6E1 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detailed hardware feature for the RA6E1 MCU group can be found at `RA6E1 Group User's Manual Hardware`_ +Detailed hardware features for the RA6E1 MCU group can be found at `RA6E1 Group User's Manual Hardware`_ .. figure:: ra6e1_block_diagram.webp :width: 442px @@ -63,12 +54,12 @@ Detailed hardware feature for the RA6E1 MCU group can be found at `RA6E1 Group U RA6E1 Block diagram (Credit: Renesas Electronics Corporation) -Detailed hardware feature for the FPB-RA6E1 MCU can be found at `FPB-RA6E1 - User's Manual`_ +Detailed hardware features for the FPB-RA6E1 MCU can be found at `FPB-RA6E1 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for FPB-RA6E1 board: +The below features are currently supported on Zephyr for FPB-RA6E1 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -89,6 +80,14 @@ The below features are currently supported on Zephyr OS for FPB-RA6E1 board: +-----------+------------+----------------------+ | COUNTER | on-chip | counter | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -108,11 +107,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `FPB-RA6E1 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `FPB-RA6E1 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/fpb_ra6e1/fpb_ra6e1-pinctrl.dtsi b/boards/renesas/fpb_ra6e1/fpb_ra6e1-pinctrl.dtsi index 90253c6b4c463..1b86818f001d1 100644 --- a/boards/renesas/fpb_ra6e1/fpb_ra6e1-pinctrl.dtsi +++ b/boards/renesas/fpb_ra6e1/fpb_ra6e1-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -30,4 +30,28 @@ ; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; }; diff --git a/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts b/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts index fefb2651d0787..5af5b73c63188 100644 --- a/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts +++ b/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "fpb_ra6e1-pinctrl.dtsi" @@ -16,9 +18,11 @@ chosen { zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; }; leds { @@ -33,8 +37,18 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport2 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; + sw0 = &button0; }; }; @@ -65,6 +79,10 @@ status = "okay"; }; +&ioport2 { + status = "okay"; +}; + &ioport4 { status = "okay"; }; @@ -80,20 +98,44 @@ status = "okay"; }; -&flash0 { +&flash1 { partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { - label = "application"; - reg = <0x00000000 DT_SIZE_K(512)>; - }; - - storage_partition: partition@80000 { + storage_partition: partition@0 { label = "storage"; - reg = <0x80000 DT_SIZE_K(512)>; + reg = <0X0 DT_SIZE_K(8)>; }; }; }; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq1 { + interrupts = <41 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + status = "okay"; +}; + +&trng { + status = "okay"; +}; diff --git a/boards/renesas/fpb_ra6e1/fpb_ra6e1_defconfig b/boards/renesas/fpb_ra6e1/fpb_ra6e1_defconfig index 4fd3e749468fa..770a30fc47db0 100644 --- a/boards/renesas/fpb_ra6e1/fpb_ra6e1_defconfig +++ b/boards/renesas/fpb_ra6e1/fpb_ra6e1_defconfig @@ -1,17 +1,11 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 - # Enable GPIO CONFIG_GPIO=y -CONFIG_BUILD_OUTPUT_HEX=y - # Enable Console CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_CONSOLE=y CONFIG_CONSOLE=y - -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/fpb_ra6e2/doc/index.rst b/boards/renesas/fpb_ra6e2/doc/index.rst index e7aeb268852e2..94d311a829c16 100644 --- a/boards/renesas/fpb_ra6e2/doc/index.rst +++ b/boards/renesas/fpb_ra6e2/doc/index.rst @@ -1,7 +1,4 @@ -.. _fpb_ra6e2: - -RA6E2 Fast Prototyping Board -############################ +.. zephyr:board:: fpb_ra6e2 Overview ******** @@ -50,15 +47,9 @@ The key features of the FPB-RA6E2 board are categorized in three groups as follo - MCU boot configuration jumper -.. figure:: fpb_ra6e2.webp - :align: center - :alt: RA6E2 Fast Prototyping Board - - FPB-RA6E2 Board Functional Area Definitions (Credit: Renesas Electronics Corporation) - Hardware ******** -Detailed hardware feature for the RA6E2 MCU group can be found at `RA6E2 Group User's Manual Hardware`_ +Detailed hardware features for the RA6E2 MCU group can be found at `RA6E2 Group User's Manual Hardware`_ .. figure:: ra6e2_block_diagram.webp :width: 442px @@ -67,12 +58,12 @@ Detailed hardware feature for the RA6E2 MCU group can be found at `RA6E2 Group U RA6E2 Block diagram (Credit: Renesas Electronics Corporation) -Detailed hardware feature for the FPB-RA6E2 MCU can be found at `FPB-RA6E2 - User's Manual`_ +Detailed hardware features for the FPB-RA6E2 MCU can be found at `FPB-RA6E2 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for FPB-RA6E2 board: +The below features are currently supported on Zephyr for FPB-RA6E2 board: +-----------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -87,6 +78,16 @@ The below features are currently supported on Zephyr OS for FPB-RA6E2 board: +-----------+------------+----------------------+ | SPI | on-chip | spi | +-----------+------------+----------------------+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| DAC | on-chip | dac | ++-----------+------------+----------------------+ Other hardware features are currently not supported by the port. @@ -106,11 +107,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `FPB-RA6E2 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `FPB-RA6E2 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/fpb_ra6e2/fpb_ra6e2-pinctrl.dtsi b/boards/renesas/fpb_ra6e2/fpb_ra6e2-pinctrl.dtsi index 5c47dd207044d..746d405e4c2ec 100644 --- a/boards/renesas/fpb_ra6e2/fpb_ra6e2-pinctrl.dtsi +++ b/boards/renesas/fpb_ra6e2/fpb_ra6e2-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -21,4 +21,28 @@ ; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + pwm1_default: pwm1_default { + group1 { + /* GTIOC1A GTIOC1B */ + psels = , + ; + }; + }; }; diff --git a/boards/renesas/fpb_ra6e2/fpb_ra6e2.dts b/boards/renesas/fpb_ra6e2/fpb_ra6e2.dts index 2ca322be83565..8ec8b80251c4f 100644 --- a/boards/renesas/fpb_ra6e2/fpb_ra6e2.dts +++ b/boards/renesas/fpb_ra6e2/fpb_ra6e2.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include #include +#include +#include #include "fpb_ra6e2-pinctrl.dtsi" @@ -19,6 +21,7 @@ zephyr,flash = &flash0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; + zephyr,entropy = &trng; }; leds { @@ -33,9 +36,19 @@ }; }; + buttons { + compatible = "gpio-keys"; + button0: s1 { + gpios = <&ioport3 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; led1 = &led2; + sw0 = &button0; }; }; @@ -59,20 +72,19 @@ status = "okay"; }; +&ioport3 { + status = "okay"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { - label = "application"; - reg = <0x00000000 DT_SIZE_K(128)>; - }; - - storage_partition: partition@20000 { + storage_partition: partition@0 { label = "storage"; - reg = <0x20000 DT_SIZE_K(128)>; + reg = <0X0 DT_SIZE_K(4)>; }; }; }; @@ -87,3 +99,33 @@ mul = <10 0>; status = "okay"; }; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq9 { + interrupts = <41 12>; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; + interrupts = <63 1>, <64 1>; + interrupt-names = "gtioca", "overflow"; + divider = ; + status = "okay"; +}; + +&trng { + status ="okay"; +}; diff --git a/boards/renesas/fpb_ra6e2/fpb_ra6e2_defconfig b/boards/renesas/fpb_ra6e2/fpb_ra6e2_defconfig index 882cf699d986f..770a30fc47db0 100644 --- a/boards/renesas/fpb_ra6e2/fpb_ra6e2_defconfig +++ b/boards/renesas/fpb_ra6e2/fpb_ra6e2_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,6 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_CONSOLE=y CONFIG_CONSOLE=y - -CONFIG_BUILD_OUTPUT_HEX=y -CONFIG_CLOCK_CONTROL=y diff --git a/boards/renesas/mck_ra8t1/board.yml b/boards/renesas/mck_ra8t1/board.yml index b7897016bbe15..dcd1bd718409e 100644 --- a/boards/renesas/mck_ra8t1/board.yml +++ b/boards/renesas/mck_ra8t1/board.yml @@ -1,6 +1,6 @@ board: name: mck_ra8t1 - full_name: RA8T1 Evaluation Kit + full_name: RA8T1 Motor Control Kit vendor: renesas socs: - name: r7fa8t1ahecbd diff --git a/boards/renesas/mck_ra8t1/doc/index.rst b/boards/renesas/mck_ra8t1/doc/index.rst index 999767e0bc2b8..c9b4f6d09a64b 100644 --- a/boards/renesas/mck_ra8t1/doc/index.rst +++ b/boards/renesas/mck_ra8t1/doc/index.rst @@ -1,7 +1,4 @@ -.. _mcb_ra8t1: - -RA8T1 Evaluation Kit -#################### +.. zephyr:board:: mck_ra8t1 Overview ******** @@ -20,7 +17,7 @@ MCK-RA8T1 kit includes the items below: .. figure:: mck_ra8t1_product_contents.jpg :align: center - :alt: RA8T1 Evaluation Kit + :alt: RA8T1 Motor Control Kit MCK-RA8T1 product contents (Credit: Renesas Electronics Corporation) @@ -54,12 +51,6 @@ The specifications of the CPU board are shown below: - Ethrnet connector - microSD card connector -.. figure:: mck_ra8t1.jpg - :align: center - :alt: RA8T1 Evaluation Kit - - CPU Board Layout (Credit: Renesas Electronics Corporation) - **Onboard debugger** This product has the onboard debugger circuit, J-Link On-Board (hereinafter called “J-Link-OB”). You can @@ -67,7 +58,7 @@ write a program (firmware) of RA8T1 with it. Hardware ******** -Detail Hardware feature for the RA8T1 MCU group can be found at `RA8T1 Group User's Manual Hardware`_ +Detailed Hardware features for the RA8T1 MCU group can be found at `RA8T1 Group User's Manual Hardware`_ .. figure:: ra8t1_block_diagram.png :width: 442px @@ -76,12 +67,12 @@ Detail Hardware feature for the RA8T1 MCU group can be found at `RA8T1 Group Use RA8T1 Block diagram (Credit: Renesas Electronics Corporation) -Detail Hardware feature for the MCB-RA8T1 board can be found at `MCB-RA8T1 - User's Manual`_ +Detailed Hardware features for the MCB-RA8T1 board can be found at `MCB-RA8T1 - User's Manual`_ Supported Features ================== -The below features are currently supported on Zephyr OS for MCB-RA8T1 board: +The below features are currently supported on Zephyr for MCB-RA8T1 board: +--------------+------------+----------------------+ | Interface | Controller | Driver/Component | @@ -112,6 +103,16 @@ The below features are currently supported on Zephyr OS for MCB-RA8T1 board: +--------------+------------+----------------------+ | ETHERNET | on-chip | ethernet | +--------------+------------+----------------------+ +| ADC | on-chip | adc | ++--------------+------------+----------------------+ +| SDHC | on-chip | sdhc | ++--------------+------------+----------------------+ +| DAC | on-chip | dac | ++--------------+------------+----------------------+ +| USBFS | on-chip | udc | ++--------------+------------+----------------------+ + +**Note:** For using SDHC module on EK-RA8M1, Connect microSD Card to microSD Socket (CN12) Other hardware features are currently not supported by the port. @@ -134,11 +135,11 @@ SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ To flash the program to board - 1. Connect to J-Link OB via USB port to host PC +1. Connect to J-Link OB via USB port to host PC - 2. Make sure J-Link OB jumper is in default configuration as describe in `MCB-RA8T1 - User's Manual`_ +2. Make sure J-Link OB jumper is in default configuration as describe in `MCB-RA8T1 - User's Manual`_ - 3. Execute west command +3. Execute west command .. code-block:: console diff --git a/boards/renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi b/boards/renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi index 2f13bbbf4c242..1ceb15c547e87 100644 --- a/boards/renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi +++ b/boards/renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -70,4 +70,47 @@ drive-strength = "high"; }; }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + sdhc0_default: sdhc0_default { + group1 { + psels = , /* SDCD */ + , /* SDCMD */ + , /* SDDATA0 */ + , /* SDDATA1 */ + , /* SDDATA2 */ + , /* SDDATA3 */ + ; /* SDWP */ + drive-strength = "high"; + }; + group2 { + psels = ; /* SDCLK */ + drive-strength = "highspeed-high"; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USBP USBN */ + psels = , + , + ; + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/mck_ra8t1/mck_ra8t1.dts b/boards/renesas/mck_ra8t1/mck_ra8t1.dts index a0e4387e60c17..b16ecd8a7edfc 100644 --- a/boards/renesas/mck_ra8t1/mck_ra8t1.dts +++ b/boards/renesas/mck_ra8t1/mck_ra8t1.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,7 @@ #include #include - +#include #include "mck_ra8t1-pinctrl.dtsi" / { @@ -46,6 +46,7 @@ aliases { led0 = &led1; + sdhc0 = &sdhc0; }; }; @@ -67,6 +68,8 @@ }; pllq { + div = <4>; + freq = ; status = "okay"; }; @@ -82,11 +85,21 @@ }; &canfdclk { - clocks = <&pll>; + clocks = <&pllp>; + div = <6>; + status = "okay"; +}; + +&uclk { + clocks = <&pllq>; div = <5>; status = "okay"; }; +&ioport3 { + status = "okay"; +}; + &ioport6 { status = "okay"; }; @@ -171,3 +184,39 @@ status = "okay"; }; }; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + average-count = <4>; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&sdhc0 { + compatible = "renesas,ra-sdhc"; + pinctrl-0 = <&sdhc0_default>; + enable-gpios = <&ioport3 11 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + status = "okay"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; diff --git a/boards/renesas/mck_ra8t1/mck_ra8t1.yaml b/boards/renesas/mck_ra8t1/mck_ra8t1.yaml index 52ef233d98f82..f4a0d4e8af2ff 100644 --- a/boards/renesas/mck_ra8t1/mck_ra8t1.yaml +++ b/boards/renesas/mck_ra8t1/mck_ra8t1.yaml @@ -10,3 +10,5 @@ toolchain: supported: - gpio - uart + - usbd +vendor: renesas diff --git a/boards/renesas/mck_ra8t1/mck_ra8t1_defconfig b/boards/renesas/mck_ra8t1/mck_ra8t1_defconfig index 07c0ee5f1ca5a..35ed0307b9aa5 100644 --- a/boards/renesas/mck_ra8t1/mck_ra8t1_defconfig +++ b/boards/renesas/mck_ra8t1/mck_ra8t1_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=480000000 - # Enable GPIO CONFIG_GPIO=y @@ -11,7 +9,3 @@ CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_CONSOLE=y - -CONFIG_CLOCK_CONTROL=y - -CONFIG_BUILD_OUTPUT_HEX=y diff --git a/boards/renesas/rzg3s_smarc/Kconfig.rzg3s_smarc b/boards/renesas/rzg3s_smarc/Kconfig.rzg3s_smarc new file mode 100644 index 0000000000000..3a0abcb410b30 --- /dev/null +++ b/boards/renesas/rzg3s_smarc/Kconfig.rzg3s_smarc @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RZG3S_SMARC + select SOC_R9A08G045S33GBG diff --git a/boards/renesas/rzg3s_smarc/board.cmake b/boards/renesas/rzg3s_smarc/board.cmake new file mode 100644 index 0000000000000..1dbf0782ab0dc --- /dev/null +++ b/boards/renesas/rzg3s_smarc/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=R9A08G045S33_M33_0" "--speed=15000") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/renesas/rzg3s_smarc/board.yml b/boards/renesas/rzg3s_smarc/board.yml new file mode 100644 index 0000000000000..97f7d9ba24f32 --- /dev/null +++ b/boards/renesas/rzg3s_smarc/board.yml @@ -0,0 +1,6 @@ +board: + name: rzg3s_smarc + full_name: RZ/G3S SMARC Evaluation Board Kit + vendor: renesas + socs: + - name: r9a08g045s33gbg diff --git a/boards/renesas/rzg3s_smarc/doc/index.rst b/boards/renesas/rzg3s_smarc/doc/index.rst new file mode 100644 index 0000000000000..09bcec22e75d6 --- /dev/null +++ b/boards/renesas/rzg3s_smarc/doc/index.rst @@ -0,0 +1,266 @@ +.. zephyr:board:: rzg3s_smarc + +Overview +******** + +The Renesas RZ/G3S SMARC Evaluation Board Kit (RZ/G3S-EVKIT) consists of a SMARC v2.1 module board and a carrier board. + +* Device: RZ/G3S R9A08G045S33GBG + + * Cortex-A55 Single, Cortex-M33 x 2 + * BGA 359-pin, 14mmSq body, 0.5mm pitch + +* SMARC v2.1 Module Board Functions + + * LPDDR4 SDRAM: 1GB x 1pc + * QSPI flash memory: 128Mb x 1pc + * eMMC memory: 64GB x 1pc + * PMIC power supply RAA215300A2GNP#HA3 implemented + * microSD card x2 + * I3C connector + * JTAG connector + * ADC x8 channels + * Current monitor (USB Micro B) + +* Carrier Board Functions + + * Gigabit Ethernet x2 + * USB2.0 x2ch (OTG x1ch, Host x1ch) + * CAN-FD x2 + * microSD card x1 + * Mono speaker, Stereo headphone, Mic., and Aux.. + * PMOD x2 + * USB-Type C for power input + * PCIe Gen2 4-lane slot (G3S supports only 1-lane) + * M.2 Key E + * M.2 Key B and SIM card + * Coin cell battery holder (3.0V support) + +Hardware +******** + +The Renesas RZ/G3S MPU documentation can be found at `RZ/G3S Group Website`_ + +.. figure:: rzg3s_block_diagram.webp + :width: 600px + :align: center + :alt: RZ/G3S group feature + + RZ/G3S block diagram (Credit: Renesas Electronics Corporation) + +Supported Features +================== + +The ``rzg3s_smarc/r9a08g045s33gbg/cm33`` board target supports the ARM Cortex-M33 System Core without FPU +and the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | arch/arm | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | arch/arm | ++-----------+------------+-------------------------------------+ +| PINCTRL | on-chip | pinctrl | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| GTM | on-chip | counter | ++-----------+------------+-------------------------------------+ +| GPT | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| INTC | on-chip | external interrupt controller | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock control | ++-----------+------------+-------------------------------------+ + +Other hardware features are currently not supported by the port. + +Programming and Debugging +************************* + +RZ/G3S-EVKIT is designed to start different systems on different cores. +It uses Yocto as the build system to build Linux system and boot loaders +to run BL2 TF-A on Cortex-A55 System Core before starting Zephyr. The minimal steps are described below. + + 1. Follow ''2.2 Building Images'' of `SMARC EVK of RZ/G3S Linux Start-up Guide`_ to prepare the build environment. + + 2. Before build, add ``PLAT_M33_BOOT_SUPPORT=1`` to meta-renesas/meta-rzg3s/recipes-bsp/trusted-firmware-a/trusted-firmware-a.bbappend. + + .. code-block:: bash + :emphasize-lines: 6 + + require trusted-firmware-a.inc + COMPATIBLE_MACHINE_rzg3s = "(rzg3s-dev|smarc-rzg3s)" + PLATFORM_rzg3s-dev = "g3s" + EXTRA_FLAGS_rzg3s-dev = "BOARD=dev14_1_lpddr PLAT_SYSTEM_SUSPEND=vbat" + PLATFORM_smarc-rzg3s = "g3s" + EXTRA_FLAGS_smarc-rzg3s = "BOARD=smarc PLAT_SYSTEM_SUSPEND=vbat PLAT_M33_BOOT_SUPPORT=1" + + 3. Start the build: + + .. code-block:: bash + + MACHINE=smarc-rzg3s bitbake core-image-minimal + + The below necessary artifacts will be located in the build/tmp/deploy/images + + +---------------+-----------------------------+ + | Artifacts | File name | + +===============+=============================+ + | Boot loader | bl2_bp_spi-smarc-rzg3s.srec | + | | | + | | fip-smarc-rzg3s.srec | + +---------------+-----------------------------+ + | Flash Writer | FlashWriter-smarc-rzg3s.mot | + +---------------+-----------------------------+ + + 4. Follow ''4.2 Startup Procedure'' of `SMARC EVK of RZ/G3S Linux Start-up Guide`_ for power supply and board setting + at SCIF download (SW_MODE[1:4] = OFF, ON, OFF, ON) and Cortex-A55 cold boot (SW_CONFIG[1:6] = OFF, OFF, ON, OFF, OFF, OFF) + + 5. Follow ''4.3 Download Flash Writer to RAM'' of `SMARC EVK of RZ/G3S Linux Start-up Guide`_ to download Flash Writer to RAM + + 6. Follow ''4.4 Write the Bootloader'' of `SMARC EVK of RZ/G3S Linux Start-up Guide`_ to write the boot loader + to the target board by using Flash Writer. + +Applications for the ``rzg3s_smarc`` board can be built in the usual way as +documented in :ref:`build_an_application`. + +Console +======= + +The UART port for Cortex-M33 System Core can be accessed by connecting `Pmod USBUART `_ +to the upper side of ``PMOD1_3A``. + +Debugging +========= + +It is possible to load and execute a Zephyr application binary on +this board on the Cortex-M33 System Core from +the internal SRAM, using ``JLink`` debugger (:ref:`jlink-debug-host-tools`). + +.. note:: + + Currently it's required Renesas BL2 TF-A to be started on Cortex-A55 System Core + before starting Zephyr as it configures clocks and the Cortex-M33 System Core before starting it. + +Here is an example for building and debugging with the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rzg3s_smarc/r9a08g045s33gbg/cm33 + :goals: build debug + +Flashing +======== + +Zephyr application can be flashed to QSPI storage and then loaded by +Renesas BL2 TF-A running on the Cortex-A55 System Core and starting binary on the Cortex-M33 System Core. + +The Zephyr application binary has to be converted to Motorolla S-record `SREC`_ format +which is generated automatically in Zephyr application build directory with the extension ``s19``. + +.. _SREC: https://en.wikipedia.org/wiki/SREC_(file_format) + +.. _Flashing on QSPI: + +Flashing on QSPI using Flash Writer +--------------------------------------- + +Zephyr binary has to be converted to **srec** format. + +* Download and start **Flash Writer** as described in ''4.3 Download Flash Writer to RAM'' of `SMARC EVK of RZ/G3S Linux Start-up Guide`_ +* Use **XLS2** command to flash Zephyr binary +* Input when asked: + +.. code-block:: console + + ===== Please Input Program Top Address ============ + Please Input : H'23000 + ===== Please Input Qspi Save Address === + Please Input : H'200000 + +* Then send Zephyr **s19** file from terminal (use ''ascii'' mode) +* Reboot the board in the **QSPI Boot Mode** + +.. code-block:: console + + -- Load Program to SRAM --------------- + + Flash writer for RZ/G3S Series V0.60 Jan.26,2023 + Product Code : RZ/G3S + >XLS2 + ===== Qspi writing of RZ/G2 Board Command ============= + Load Program to Spiflash + Writes to any of SPI address. + Program size & Qspi Save Address + ===== Please Input Program Top Address ============ + Please Input : H'23000 + + ===== Please Input Qspi Save Address === + Please Input : H'200000 + please send ! ('.' & CR stop load) + I Flash memory... + Erase Completed + Write to SPI Flash memory. + ======= Qspi Save Information ================= + SpiFlashMemory Stat Address : H'00200000 + SpiFlashMemory End Address : H'002098E6 + =========================================================== + +Flashing on QSPI using west +--------------------------- + +Before using ``flash`` command, the board must be set to Cortex-M33 cold boot (SW_CONFIG[1:6] = OFF, OFF, ON, OFF, OFF, ON). +After flashing, it must be set back to Cortex-A55 cold boot to run. + +The minimal version of SEGGER JLink SW which can perform flashing of QSPI memory is v7.96. + +**Note:** It's verified that we can perform flashing successfully with SEGGER JLink SW v7.98g so please use this or later +version. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rzg3s_smarc/r9a08g045s33gbg/cm33 + :goals: build flash + :compact: + +Troubleshooting +=============== + +Linux and Zephyr application should not share SoC HW resources otherwise it will cause HW corruption and unpredictable behavior. +Therefore, HW resources assigned to Zephyr application must be disabled in Linux. + +The below patch shows how to prevent Linux from configuring SCIF1 which is used by Zephyr. + +.. code-block:: diff + + diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi + index f01801b18e8a..d9f9a0a2bb08 100644 + --- a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi + +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi + @@ -347,7 +347,7 @@ &scif1 { + pinctrl-0 = <&scif1_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + - status = "okay"; + + status = "disabled"; + }; + #elif SPDIF_SEL == SW_ON + &spdif { + +References +********** + +.. target-notes:: + +.. _RZ/G3S Group Website: + https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rz-mpus/rzg3s-general-purpose-microprocessors-single-core-arm-cortex-a55-11-ghz-cpu-and-dual-core-cortex-m33-250 + +.. _RZG3S-EVKIT Website: + https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rz-mpus/rzg3s-evkit-evaluation-board-kit-rzg3s-mpu + +.. _SMARC EVK of RZ/G3S Linux Start-up Guide: + https://www.renesas.com/us/en/document/gde/smarc-evk-rzg3s-linux-start-guide-rev104 diff --git a/boards/renesas/rzg3s_smarc/doc/rzg3s_block_diagram.webp b/boards/renesas/rzg3s_smarc/doc/rzg3s_block_diagram.webp new file mode 100644 index 0000000000000..ae3022760bc49 Binary files /dev/null and b/boards/renesas/rzg3s_smarc/doc/rzg3s_block_diagram.webp differ diff --git a/boards/renesas/rzg3s_smarc/doc/rzg3s_smarc.webp b/boards/renesas/rzg3s_smarc/doc/rzg3s_smarc.webp new file mode 100644 index 0000000000000..1d81bb7a61556 Binary files /dev/null and b/boards/renesas/rzg3s_smarc/doc/rzg3s_smarc.webp differ diff --git a/boards/renesas/rzg3s_smarc/rzg3s_smarc-pinctrl.dtsi b/boards/renesas/rzg3s_smarc/rzg3s_smarc-pinctrl.dtsi new file mode 100644 index 0000000000000..72a243947cd1b --- /dev/null +++ b/boards/renesas/rzg3s_smarc/rzg3s_smarc-pinctrl.dtsi @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 EPAM Systems + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&pinctrl { + /omit-if-no-ref/ scif0_pins: scif0 { + scif0-pinmux { + pinmux = , /* TXD */ + ; /* RXD */ + }; + }; + + /omit-if-no-ref/ scif1_pins: scif1 { + scif1-pinmux { + pinmux = , /* TXD */ + ; /* RXD */ + }; + }; + + /omit-if-no-ref/ scif3_pins: scif3 { + scif3-pinmux { + pinmux = , /* TXD */ + ; /* RXD */ + }; + }; + + /omit-if-no-ref/ scif5_pins: scif5 { + scif5-pinmux { + pinmux = , /* RXD */ + ; /* TXD */ + }; + }; + + /omit-if-no-ref/ gpt0_pins: gpt0 { + gpt0-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; + + /omit-if-no-ref/ gpt3_pins: gpt3 { + gpt3-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; + + /omit-if-no-ref/ gpt6_pins: gpt6 { + gpt6-pinmux { + pinmux = ; /* GTIOCA */ + }; + }; +}; diff --git a/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33.dts b/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33.dts new file mode 100644 index 0000000000000..81210407ae4f4 --- /dev/null +++ b/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33.dts @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2024 EPAM Systems + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include +#include "rzg3s_smarc-pinctrl.dtsi" + +/ { + model = "Renesas RZ/G3S SMARC"; + compatible = "renesas,rzg3s-smarc"; + + chosen { + zephyr,sram = &sram_mcpu0; + zephyr,flash = &spi_flash; + zephyr,console = &scif1; + zephyr,shell-uart = &scif1; + }; + + aliases { + sw0 = &sw_1; + sw1 = &sw_2; + sw2 = &sw_3; + }; + + buttons { + compatible = "gpio-keys"; + + sw_1: button_1 { + gpios = <&gpio18 0 GPIO_ACTIVE_LOW>; + label = "SW1"; + zephyr,code = ; + }; + + sw_2: button_2 { + gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + label = "SW2"; + zephyr,code = ; + }; + + sw_3: button_3 { + gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; + label = "SW3"; + zephyr,code = ; + }; + }; + + ddr: memory@60000000 { + compatible ="zephyr,memory-region", "mmio-sram"; + reg = <0x60000000 DT_SIZE_M(16)>; + zephyr,memory-region = "DDR"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; + }; + + sram_mcpu0: memory@23000 { + compatible = "mmio-sram"; + reg = <0x23000 DT_SIZE_K(243)>; + }; + + /* + * This node is defined to enable west flash support. + * The base addr and size depends on ATF-F configuration, which is running on Cortex-A55 and + * loading Zephyr app from xSPI flash. + */ + spi_flash: memory@80200000 { + compatible = "mmio-sram"; + reg = <0x80200000 DT_SIZE_K(256)>; + }; + +}; + +&scif1 { + current-speed = <115200>; + pinctrl-0 = <&scif1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&gpio0{ + status = "okay"; +}; + +&gpio18{ + status = "okay"; +}; diff --git a/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33.yaml b/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33.yaml new file mode 100644 index 0000000000000..1d4a4eeeae13b --- /dev/null +++ b/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33.yaml @@ -0,0 +1,12 @@ +identifier: rzg3s_smarc/r9a08g045s33gbg/cm33 +name: Cortex-M33 for Renesas RZ/G3S SMARC +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - uart + - gpio + - counter + - pwm diff --git a/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33_defconfig b/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33_defconfig new file mode 100644 index 0000000000000..90a8ce521897f --- /dev/null +++ b/boards/renesas/rzg3s_smarc/rzg3s_smarc_r9a08g045s33gbg_cm33_defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 EPAM Systems +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_XIP=n + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/renesas/rzt2m_starterkit/rzt2m_starter_kit_renesas_rzt2m.dts b/boards/renesas/rzt2m_starterkit/rzt2m_starter_kit_renesas_rzt2m.dts index a34558ec0144c..717c21c0cdaba 100644 --- a/boards/renesas/rzt2m_starterkit/rzt2m_starter_kit_renesas_rzt2m.dts +++ b/boards/renesas/rzt2m_starterkit/rzt2m_starter_kit_renesas_rzt2m.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include / { model = "RZT/2M Starter Kit"; @@ -48,10 +49,12 @@ sw1: sw1 { label = "sw1"; gpios = <&gpio10 5 0>; + zephyr,code = ; }; sw2: sw2 { label = "sw2"; gpios = <&gpio16 3 0>; + zephyr,code = ; }; }; }; diff --git a/boards/renesas/voice_ra4e1/Kconfig.voice_ra4e1 b/boards/renesas/voice_ra4e1/Kconfig.voice_ra4e1 new file mode 100644 index 0000000000000..51239caf33140 --- /dev/null +++ b/boards/renesas/voice_ra4e1/Kconfig.voice_ra4e1 @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_VOICE_RA4E1 + select SOC_R7FA4E10D2CNE diff --git a/boards/renesas/voice_ra4e1/board.cmake b/boards/renesas/voice_ra4e1/board.cmake new file mode 100644 index 0000000000000..590f06a574311 --- /dev/null +++ b/boards/renesas/voice_ra4e1/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=R7FA4E10D") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/renesas/voice_ra4e1/board.yml b/boards/renesas/voice_ra4e1/board.yml new file mode 100644 index 0000000000000..2d675896174e8 --- /dev/null +++ b/boards/renesas/voice_ra4e1/board.yml @@ -0,0 +1,6 @@ +board: + name: voice_ra4e1 + full_name: RA4E1 Voice User Reference Kit + vendor: renesas + socs: + - name: r7fa4e10d2cne diff --git a/boards/renesas/voice_ra4e1/doc/index.rst b/boards/renesas/voice_ra4e1/doc/index.rst new file mode 100644 index 0000000000000..2d737a3378941 --- /dev/null +++ b/boards/renesas/voice_ra4e1/doc/index.rst @@ -0,0 +1,143 @@ +.. zephyr:board:: voice_ra4e1 + +Overview +******** + +VOICE-RA4E1 is an edge voice recognition evaluation kit designed to be used by Ecosystem Partners, +Application Engineers, Field Application Engineers, and for Business Development opportunities. The +primary purpose is to evaluate the functionality of projects developed by Ecosystem Partners, and to +facilitate the development of additional partner projects. The kit design to use the RA4E1 MCU with QFN +48pin package as the core logic device, with QSPI flash, OPAMP and power devices chosen from the +Renesas product portfolio. + +The MCU in this series incorporates a high-performance Arm CortexÂŽ-M33 core running up to +100 MHz with the following features: + +**MCU Native Pin Access** + +- R7FA4E10D2CNE MCU (referred to as RA MCU) +- 100 MHz, ArmÂŽ CortexÂŽ-M33 core +- 512 KB Code Flash, 8 KB Data Flash, 128 KB SRAM +- 48 pins, LQFP package +- MCU current measurement point for precision current consumption measurement +- Multiple clock sources - Low-precision (~1%) clocks are available internal to the RA MCU. + +**Kit Peripheral Features** + +Following is a list of the specific features that have been implemented: + +- QSPI: One QSPI flash memory device, Dialog AT25SF641B-MHB-T, 64M-bit (8MB). +- PMOD: 1 Digilent PMOD connectors, supporting UART, SPI and I2C configurations. +- Microphones: 1 I2S MEMS digital microphones and 2 MEMS analog microphones, distance between + each pair of microphones is 50mm which is suitable for beamforming applications. +- Audio out: One stereo audio headphone jack supporting mono output on both channels. +- LEDs: Five LEDs, D2 (Red), D3 (Green) and D4 (Blue) configurable by user, D5 (Blue) as a 3.3V power + indicator, D8(Green) as a JLOB (J-LINK on board) indicator. +- Buttons: One RESET button (S2), and one USER button (S1). +- Debug: J-Link On-Board debug interface, supporting JTAG or SWD debug port. +- USB: Micro USB-B (J6) for power input and J-Link On-Board function, USB-C (J1) for power input and + RA4E1 USB Full Speed port as a USB device. +- Form Factor: 7.5 x 6 cm + +Hardware +******** + +Detailed hardware features can be found at: + +- RA4E1 MCU: `RA4E1 Group User's Manual Hardware`_ +- VOICE-RA4E1 board: `VOICE-RA4E1 - Engineering Manual`_ + +Supported Features +================== + +The below features are currently supported on Zephyr for the ``voice_ra4e1`` board: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock control | ++-----------+------------+----------------------+ +| COUNTER | on-chip | counter | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| ENTROPY | on-chip | entropy | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| USBFS | on-chip | udc | ++-----------+------------+----------------------+ + +Other hardware features are currently not supported by the port. + +Programming and Debugging +************************* + +Applications for the ``voice_ra4e1`` board can be +built, flashed, and debugged in the usual way. See +:ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +Flashing +======== + +Program can be flashed to VOICE-RA4E1 via the on-board SEGGER J-Link debugger. +SEGGER J-link's drivers are avaialbe at https://www.segger.com/downloads/jlink/ + +To flash the program to board + +1. Connect to J-Link OB via USB port to host PC + +2. Make sure J-Link OB jumper is in default configuration as describe in `VOICE-RA4E1 - Engineering Manual`_ + +3. Execute west command + + .. code-block:: console + + west flash -r jlink + +Debugging +========= + +You can use Segger Ozone (`Segger Ozone Download`_) for a visual debug interface + +Once downloaded and installed, open Segger Ozone and configure the debug project +like so: + +* Target Device: R7FA4E10D +* Target Interface: SWD +* Target Interface Speed: 4 MHz +* Host Interface: USB +* Program File: + +**Note:** It's verified that we can debug OK on Segger Ozone v3.30d so please use this or later +version of Segger Ozone + +References +********** + +- `VOICE-RA4E1 Website`_ +- `RA4E1 MCU group Website`_ + +.. _VOICE-RA4E1 Website: + https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/tw001-vuia4e1pocz-ra4e1-voice-user-reference-kit + +.. _RA4E1 MCU group Website: + https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra4e1-100mhz-arm-cortex-m33-entry-line-balanced-low-power-consumption-optimized-feature-integration + +.. _VOICE-RA4E1 - Engineering Manual: + https://www.renesas.com/en/document/mat/voice-ra4e1-engineering-manual + +.. _RA4E1 Group User's Manual Hardware: + https://www.renesas.com/en/document/mah/ra4e1-group-users-manual-hardware + +.. _Segger Ozone Download: + https://www.segger.com/downloads/jlink#Ozone diff --git a/boards/renesas/voice_ra4e1/doc/voice_ra4e1.webp b/boards/renesas/voice_ra4e1/doc/voice_ra4e1.webp new file mode 100644 index 0000000000000..efed12efb2cd6 Binary files /dev/null and b/boards/renesas/voice_ra4e1/doc/voice_ra4e1.webp differ diff --git a/boards/renesas/voice_ra4e1/voice_ra4e1-pinctrl.dtsi b/boards/renesas/voice_ra4e1/voice_ra4e1-pinctrl.dtsi new file mode 100644 index 0000000000000..48093d9a49495 --- /dev/null +++ b/boards/renesas/voice_ra4e1/voice_ra4e1-pinctrl.dtsi @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci3_default: sci3_default { + group1 { + /* tx rx */ + psels = , + ; + }; + }; + + usbfs_default: usbfs_default { + group1 { + /* USB_VBUS */ + psels = ; + drive-strength = "high"; + }; + }; +}; diff --git a/boards/renesas/voice_ra4e1/voice_ra4e1.dts b/boards/renesas/voice_ra4e1/voice_ra4e1.dts new file mode 100644 index 0000000000000..9c756b0d6459f --- /dev/null +++ b/boards/renesas/voice_ra4e1/voice_ra4e1.dts @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include "voice_ra4e1-pinctrl.dtsi" + +/ { + model = "Renesas VOICE-RA4E1"; + compatible = "renesas,ra4e1", "renesas,ra"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash-controller = &flash1; + zephyr,flash = &flash0; + zephyr,console = &uart3; + zephyr,shell-uart = &uart3; + zephyr,entropy = &trng; + }; + + leds { + compatible = "gpio-leds"; + + led1: led1 { + gpios = <&ioport5 0 GPIO_ACTIVE_HIGH>; + label = "LED1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: s1 { + gpios = <&ioport4 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button switch 1"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led1; + sw0 = &button0; + }; +}; + +&subclk { + status = "okay"; +}; + +&pll { + clocks = <&hoco>; + div = <2>; + mul = <20 0>; + status = "okay"; +}; + +&pll2 { + clocks = <&hoco>; + div = <2>; + mul = <24 0>; + status = "okay"; +}; + +&uclk { + clocks = <&pll2>; + div = <5>; + status = "okay"; +}; + +&sci3 { + interrupts = <16 1>, <17 1>, <18 1>, <19 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + pinctrl-0 = <&sci3_default>; + pinctrl-names = "default"; + status = "okay"; + + uart3: uart { + current-speed = <115200>; + status = "okay"; + }; +}; + +&ioport1 { + status = "okay"; +}; + +&ioport2 { + status = "okay"; +}; + +&ioport4 { + status = "okay"; +}; + +&ioport5 { + status = "okay"; +}; + +&port_irq4 { + interrupts = <41 12>; + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(8)>; + }; + }; +}; + +&usbfs { + pinctrl-0 = <&usbfs_default>; + pinctrl-names = "default"; + maximum-speed = "full-speed"; + status = "okay"; + zephyr_udc0: udc { + status = "okay"; + }; +}; diff --git a/boards/renesas/voice_ra4e1/voice_ra4e1.yaml b/boards/renesas/voice_ra4e1/voice_ra4e1.yaml new file mode 100644 index 0000000000000..f6051167fff09 --- /dev/null +++ b/boards/renesas/voice_ra4e1/voice_ra4e1.yaml @@ -0,0 +1,14 @@ +identifier: voice_ra4e1 +name: Renesas VOICE-RA4E1 +type: mcu +arch: arm +ram: 128 +flash: 512 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - uart + - usbd +vendor: renesas diff --git a/boards/renesas/voice_ra4e1/voice_ra4e1_defconfig b/boards/renesas/voice_ra4e1/voice_ra4e1_defconfig new file mode 100644 index 0000000000000..f26066de3e521 --- /dev/null +++ b/boards/renesas/voice_ra4e1/voice_ra4e1_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Enable Console +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_CONSOLE=y +CONFIG_CONSOLE=y diff --git a/boards/ronoth/lodev/ronoth_lodev.dts b/boards/ronoth/lodev/ronoth_lodev.dts index 024e71a721066..315f58fa2c601 100644 --- a/boards/ronoth/lodev/ronoth_lodev.dts +++ b/boards/ronoth/lodev/ronoth_lodev.dts @@ -163,7 +163,7 @@ &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/ronoth/lodev/ronoth_lodev.yaml b/boards/ronoth/lodev/ronoth_lodev.yaml index ca715a9ed551d..495f9ff9c6754 100644 --- a/boards/ronoth/lodev/ronoth_lodev.yaml +++ b/boards/ronoth/lodev/ronoth_lodev.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 flash: 192 supported: diff --git a/boards/ruuvi/ruuvitag/ruuvi_ruuvitag.yaml b/boards/ruuvi/ruuvitag/ruuvi_ruuvitag.yaml index 151e614cbfb55..3331bd1790524 100644 --- a/boards/ruuvi/ruuvitag/ruuvi_ruuvitag.yaml +++ b/boards/ruuvi/ruuvitag/ruuvi_ruuvitag.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/seagate/legend/legend_stm32f070xb_25hdd.yaml b/boards/seagate/legend/legend_stm32f070xb_25hdd.yaml index e94bd6e2faa01..04853f50efdf8 100644 --- a/boards/seagate/legend/legend_stm32f070xb_25hdd.yaml +++ b/boards/seagate/legend/legend_stm32f070xb_25hdd.yaml @@ -7,7 +7,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/seagate/legend/legend_stm32f070xb_25ssd.yaml b/boards/seagate/legend/legend_stm32f070xb_25ssd.yaml index b1aa3766f7728..52f80c477016f 100644 --- a/boards/seagate/legend/legend_stm32f070xb_25ssd.yaml +++ b/boards/seagate/legend/legend_stm32f070xb_25ssd.yaml @@ -7,7 +7,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/seagate/legend/legend_stm32f070xb_35.yaml b/boards/seagate/legend/legend_stm32f070xb_35.yaml index 851fb36a8b41a..098487e913fff 100644 --- a/boards/seagate/legend/legend_stm32f070xb_35.yaml +++ b/boards/seagate/legend/legend_stm32f070xb_35.yaml @@ -7,7 +7,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/seco/stm32f3_seco_d23/stm32f3_seco_d23.yaml b/boards/seco/stm32f3_seco_d23/stm32f3_seco_d23.yaml index 469523eadc248..e1c2b9fe64ab3 100644 --- a/boards/seco/stm32f3_seco_d23/stm32f3_seco_d23.yaml +++ b/boards/seco/stm32f3_seco_d23/stm32f3_seco_d23.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 40 supported: - gpio diff --git a/boards/seeed/lora_e5_dev_board/lora_e5_dev_board.dts b/boards/seeed/lora_e5_dev_board/lora_e5_dev_board.dts index 64ea2f84726da..f3df8911ee805 100644 --- a/boards/seeed/lora_e5_dev_board/lora_e5_dev_board.dts +++ b/boards/seeed/lora_e5_dev_board/lora_e5_dev_board.dts @@ -157,7 +157,7 @@ stm32_lp_tick_source: &lptim1 { &adc1 { pinctrl-0 = <&adc_in2_pb3>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/seeed/lora_e5_dev_board/lora_e5_dev_board.yaml b/boards/seeed/lora_e5_dev_board/lora_e5_dev_board.yaml index dede51f812526..7b630ff169660 100644 --- a/boards/seeed/lora_e5_dev_board/lora_e5_dev_board.yaml +++ b/boards/seeed/lora_e5_dev_board/lora_e5_dev_board.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 supported: diff --git a/boards/seeed/lora_e5_mini/lora_e5_mini.yaml b/boards/seeed/lora_e5_mini/lora_e5_mini.yaml index 72a8018b0e319..3b1b998b6c7bf 100644 --- a/boards/seeed/lora_e5_mini/lora_e5_mini.yaml +++ b/boards/seeed/lora_e5_mini/lora_e5_mini.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 supported: diff --git a/boards/seeed/seeeduino_xiao/seeeduino_xiao.yaml b/boards/seeed/seeeduino_xiao/seeeduino_xiao.yaml index 4330f0a754ad0..fec73550e3fd2 100644 --- a/boards/seeed/seeeduino_xiao/seeeduino_xiao.yaml +++ b/boards/seeed/seeeduino_xiao/seeeduino_xiao.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools flash: 256 ram: 32 supported: @@ -18,4 +17,9 @@ supported: - uart - usb_device - watchdog + - xiao_adc + - xiao_gpio + - xiao_i2c + - xiao_serial + - xiao_spi vendor: seeed diff --git a/boards/seeed/wio_terminal/Kconfig.defconfig b/boards/seeed/wio_terminal/Kconfig.defconfig index 47e610c12cd9f..3ff8b29601596 100644 --- a/boards/seeed/wio_terminal/Kconfig.defconfig +++ b/boards/seeed/wio_terminal/Kconfig.defconfig @@ -5,3 +5,5 @@ configdefault LV_COLOR_16_SWAP default y if LVGL + +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" diff --git a/boards/seeed/wio_terminal/wio_terminal.dts b/boards/seeed/wio_terminal/wio_terminal.dts index 27d24604f44cc..c04feb0b14a79 100644 --- a/boards/seeed/wio_terminal/wio_terminal.dts +++ b/boards/seeed/wio_terminal/wio_terminal.dts @@ -18,8 +18,6 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,console = &wio_terminal_console; - zephyr,shell-uart = &wio_terminal_console; zephyr,code-partition = &code_partition; zephyr,display = &ili9341; }; @@ -300,8 +298,6 @@ zephyr_udc0: &usb0 { status = "okay"; pinctrl-0 = <&usb_dc_default>; pinctrl-names = "default"; - - wio_terminal_console: wio_terminal_console { - compatible = "zephyr,cdc-acm-uart"; - }; }; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/seeed/wio_terminal/wio_terminal.yaml b/boards/seeed/wio_terminal/wio_terminal.yaml index 66a97ebefc01c..a5445ae3cd036 100644 --- a/boards/seeed/wio_terminal/wio_terminal.yaml +++ b/boards/seeed/wio_terminal/wio_terminal.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - counter diff --git a/boards/seeed/wio_terminal/wio_terminal_defconfig b/boards/seeed/wio_terminal/wio_terminal_defconfig index 20852ef411e9e..e44adbcbb676e 100644 --- a/boards/seeed/wio_terminal/wio_terminal_defconfig +++ b/boards/seeed/wio_terminal/wio_terminal_defconfig @@ -14,16 +14,3 @@ CONFIG_REGULATOR=y CONFIG_BOOTLOADER_BOSSA=y CONFIG_BOOTLOADER_BOSSA_ADAFRUIT_UF2=y CONFIG_BUILD_OUTPUT_UF2=y - -# Console over USB CDC-ACM -CONFIG_SERIAL=y -CONFIG_CONSOLE=y -CONFIG_UART_CONSOLE=y -CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y -CONFIG_USB_DEVICE_VID=0x2886 -CONFIG_USB_DEVICE_PID=0x802D -CONFIG_USB_DEVICE_MANUFACTURER="Seeed Studio" -CONFIG_USB_DEVICE_PRODUCT="Wio Terminal" -CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y diff --git a/boards/seeed/xiao_ble/Kconfig.defconfig b/boards/seeed/xiao_ble/Kconfig.defconfig index d5c4e1ee51c70..3bc7ae6721fc4 100644 --- a/boards/seeed/xiao_ble/Kconfig.defconfig +++ b/boards/seeed/xiao_ble/Kconfig.defconfig @@ -5,14 +5,6 @@ if BOARD_XIAO_BLE -if USB_DEVICE_STACK - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y - -endif # USB_DEVICE_STACK +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_XIAO_BLE diff --git a/boards/seeed/xiao_ble/xiao_ble.yaml b/boards/seeed/xiao_ble/xiao_ble.yaml index 3351b8f609e4d..a6482108e38d7 100644 --- a/boards/seeed/xiao_ble/xiao_ble.yaml +++ b/boards/seeed/xiao_ble/xiao_ble.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble @@ -20,4 +19,9 @@ supported: - usb_device - watchdog - netif:openthread + - xiao_adc + - xiao_gpio + - xiao_i2c + - xiao_serial + - xiao_spi vendor: seeed diff --git a/boards/seeed/xiao_ble/xiao_ble_common.dtsi b/boards/seeed/xiao_ble/xiao_ble_common.dtsi index b8f4f259c1023..7b87b6db76f8e 100644 --- a/boards/seeed/xiao_ble/xiao_ble_common.dtsi +++ b/boards/seeed/xiao_ble/xiao_ble_common.dtsi @@ -12,11 +12,6 @@ / { chosen { - zephyr,console = &usb_cdc_acm_uart; - zephyr,shell-uart = &usb_cdc_acm_uart; - zephyr,uart-mcumgr = &usb_cdc_acm_uart; - zephyr,bt-mon-uart = &usb_cdc_acm_uart; - zephyr,bt-c2h-uart = &usb_cdc_acm_uart; zephyr,ieee802154 = &ieee802154; }; @@ -146,8 +141,6 @@ zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; - - usb_cdc_acm_uart: cdc-acm-uart { - compatible = "zephyr,cdc-acm-uart"; - }; }; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/seeed/xiao_ble/xiao_ble_defconfig b/boards/seeed/xiao_ble/xiao_ble_defconfig index 84eb3e97f22a5..725c581b36486 100644 --- a/boards/seeed/xiao_ble/xiao_ble_defconfig +++ b/boards/seeed/xiao_ble/xiao_ble_defconfig @@ -15,12 +15,6 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y -# Logger cannot use itself to log -CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y - -# Enable USB -CONFIG_USB_DEVICE_STACK=y - # Build UF2 by default, supported by the Adafruit nRF52 Bootloader CONFIG_BUILD_OUTPUT_UF2=y CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml b/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml index 9de9481776ab7..9275e38f7f69f 100644 --- a/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml +++ b/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble @@ -20,4 +19,9 @@ supported: - usb_device - watchdog - netif:openthread + - xiao_adc + - xiao_gpio + - xiao_i2c + - xiao_serial + - xiao_spi vendor: seeed diff --git a/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense_defconfig b/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense_defconfig index 027dd93e73b28..37b63403a6df6 100644 --- a/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense_defconfig +++ b/boards/seeed/xiao_ble/xiao_ble_nrf52840_sense_defconfig @@ -15,12 +15,6 @@ CONFIG_SERIAL=y # Enable console CONFIG_CONSOLE=y -# Logger cannot use itself to log -CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y - -# Enable USB -CONFIG_USB_DEVICE_STACK=y - # Build UF2 by default, supported by the Adafruit nRF52 Bootloader CONFIG_BUILD_OUTPUT_UF2=y CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/seeed/xiao_esp32c3/xiao_esp32c3.dts b/boards/seeed/xiao_esp32c3/xiao_esp32c3.dts index 5786e33c0ad68..606ec381f82c5 100644 --- a/boards/seeed/xiao_esp32c3/xiao_esp32c3.dts +++ b/boards/seeed/xiao_esp32c3/xiao_esp32c3.dts @@ -16,7 +16,7 @@ compatible = "seeed,xiao-esp32c3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/seeed/xiao_esp32c3/xiao_esp32c3.yaml b/boards/seeed/xiao_esp32c3/xiao_esp32c3.yaml index 1d762f6f2b216..2cb67d19dca07 100644 --- a/boards/seeed/xiao_esp32c3/xiao_esp32c3.yaml +++ b/boards/seeed/xiao_esp32c3/xiao_esp32c3.yaml @@ -11,8 +11,9 @@ supported: - uart - watchdog - can -testing: - ignore_tags: - - net - - bluetooth + - xiao_adc + - xiao_gpio + - xiao_i2c + - xiao_serial + - xiao_spi vendor: seeed diff --git a/boards/seeed/xiao_esp32c3/xiao_esp32c3_defconfig b/boards/seeed/xiao_esp32c3/xiao_esp32c3_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/seeed/xiao_esp32c3/xiao_esp32c3_defconfig +++ b/boards/seeed/xiao_esp32c3/xiao_esp32c3_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/seeed/xiao_esp32c6/doc/index.rst b/boards/seeed/xiao_esp32c6/doc/index.rst index 123869ae84bf5..5e6865c5b0219 100644 --- a/boards/seeed/xiao_esp32c6/doc/index.rst +++ b/boards/seeed/xiao_esp32c6/doc/index.rst @@ -36,6 +36,8 @@ The Zephyr ``xiao_esp32c6`` board target supports the following hardware feature +------------+------------+-------------------------------------+ | SPI Master | on-chip | spi | +------------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++------------+------------+-------------------------------------+ | Watchdog | on-chip | watchdog | +------------+------------+-------------------------------------+ | LEDC | on-chip | pwm | diff --git a/boards/seeed/xiao_esp32c6/seeed_xiao_connector.dtsi b/boards/seeed/xiao_esp32c6/seeed_xiao_connector.dtsi index 9fcac7e7b674e..cf4b71f87344f 100644 --- a/boards/seeed/xiao_esp32c6/seeed_xiao_connector.dtsi +++ b/boards/seeed/xiao_esp32c6/seeed_xiao_connector.dtsi @@ -24,5 +24,6 @@ }; }; +xiao_i2c: &i2c0 {}; xiao_spi: &spi2 {}; xiao_serial: &uart0 {}; diff --git a/boards/seeed/xiao_esp32c6/xiao_esp32c6-pinctrl.dtsi b/boards/seeed/xiao_esp32c6/xiao_esp32c6-pinctrl.dtsi index 061a21eb2c00a..424a405157850 100644 --- a/boards/seeed/xiao_esp32c6/xiao_esp32c6-pinctrl.dtsi +++ b/boards/seeed/xiao_esp32c6/xiao_esp32c6-pinctrl.dtsi @@ -31,4 +31,14 @@ output-low; }; }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; }; diff --git a/boards/seeed/xiao_esp32c6/xiao_esp32c6.dts b/boards/seeed/xiao_esp32c6/xiao_esp32c6.dts index 0e46e01c655a7..d155f5aa20141 100644 --- a/boards/seeed/xiao_esp32c6/xiao_esp32c6.dts +++ b/boards/seeed/xiao_esp32c6/xiao_esp32c6.dts @@ -17,7 +17,7 @@ compatible = "seeed,xiao-esp32c6"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sramhp; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; @@ -55,6 +55,13 @@ status = "okay"; }; +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + &spi2 { #address-cells = <1>; #size-cells = <0>; diff --git a/boards/seeed/xiao_esp32c6/xiao_esp32c6.yaml b/boards/seeed/xiao_esp32c6/xiao_esp32c6.yaml index c626ac548700c..2f0a60ea7a7ed 100644 --- a/boards/seeed/xiao_esp32c6/xiao_esp32c6.yaml +++ b/boards/seeed/xiao_esp32c6/xiao_esp32c6.yaml @@ -11,9 +11,12 @@ supported: - dma - spi - entropy + - i2c + - xiao_gpio + - xiao_i2c + - xiao_serial + - xiao_spi testing: ignore_tags: - - net - - bluetooth - tracing vendor: seeed diff --git a/boards/seeed/xiao_esp32c6/xiao_esp32c6_defconfig b/boards/seeed/xiao_esp32c6/xiao_esp32c6_defconfig index 6539bd42e5947..187793c76e8cc 100644 --- a/boards/seeed/xiao_esp32c6/xiao_esp32c6_defconfig +++ b/boards/seeed/xiao_esp32c6/xiao_esp32c6_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_appcpu.dts b/boards/seeed/xiao_esp32s3/xiao_esp32s3_appcpu.dts index 851abb50b5ae5..42962e9f0df9a 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_appcpu.dts +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_appcpu.dts @@ -13,7 +13,7 @@ compatible = "espressif,esp32s3"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_appcpu_defconfig b/boards/seeed/xiao_esp32s3/xiao_esp32s3_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_appcpu_defconfig +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu.yaml b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu.yaml index d438611cb3373..b8cfc2dfb74c9 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu.yaml +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu.yaml @@ -15,8 +15,9 @@ supported: - entropy - pwm - dma -testing: - ignore_tags: - - net - - bluetooth + - xiao_adc + - xiao_gpio + - xiao_i2c + - xiao_serial + - xiao_spi vendor: seeed diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_common.dtsi b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_common.dtsi index f8e4906f88c6b..79860b2644701 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_common.dtsi +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_common.dtsi @@ -12,7 +12,7 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &usb_serial; zephyr,shell-uart = &usb_serial; zephyr,flash = &flash0; diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_defconfig b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_defconfig index 6539bd42e5947..187793c76e8cc 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_defconfig +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.yaml b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.yaml index 91521bcd7d633..183703652824a 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.yaml +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.yaml @@ -15,8 +15,9 @@ supported: - entropy - pwm - dma -testing: - ignore_tags: - - net - - bluetooth + - xiao_adc + - xiao_gpio + - xiao_i2c + - xiao_serial + - xiao_spi vendor: seeed diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense_defconfig b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense_defconfig index 6539bd42e5947..187793c76e8cc 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense_defconfig +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/seeed/xiao_rp2040/xiao_rp2040.dts b/boards/seeed/xiao_rp2040/xiao_rp2040.dts index 728af5e28b4f6..c0f96c5fdabf6 100644 --- a/boards/seeed/xiao_rp2040/xiao_rp2040.dts +++ b/boards/seeed/xiao_rp2040/xiao_rp2040.dts @@ -78,6 +78,18 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the bootloader. The partition + * size is 2MB minus the 0x100 bytes taken by the bootloader. + */ code_partition: partition@100 { label = "code"; reg = <0x100 (DT_SIZE_M(2) - 0x100)>; @@ -167,3 +179,7 @@ zephyr_udc0: &usbd { regulator-always-on; regulator-allowed-modes = ; }; + +&xosc { + startup-delay-multiplier = <64>; +}; diff --git a/boards/seeed/xiao_rp2040/xiao_rp2040.yaml b/boards/seeed/xiao_rp2040/xiao_rp2040.yaml index b2852757aa3af..c91e45a1e2c97 100644 --- a/boards/seeed/xiao_rp2040/xiao_rp2040.yaml +++ b/boards/seeed/xiao_rp2040/xiao_rp2040.yaml @@ -3,11 +3,10 @@ name: XIAO RP2040 type: mcu arch: arm flash: 2048 -ram: 256 +ram: 264 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio @@ -21,4 +20,8 @@ supported: - dma - counter - clock + - xiao_gpio + - xiao_i2c + - xiao_serial + - xiao_spi vendor: seeed diff --git a/boards/segger/ip_k66f/ip_k66f.yaml b/boards/segger/ip_k66f/ip_k66f.yaml index ef2de5f4467e6..0ce51cd967d55 100644 --- a/boards/segger/ip_k66f/ip_k66f.yaml +++ b/boards/segger/ip_k66f/ip_k66f.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/segger/trb_stm32f407/segger_trb_stm32f407.yaml b/boards/segger/trb_stm32f407/segger_trb_stm32f407.yaml index 911c37648026c..c88382807b054 100644 --- a/boards/segger/trb_stm32f407/segger_trb_stm32f407.yaml +++ b/boards/segger/trb_stm32f407/segger_trb_stm32f407.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 512 supported: diff --git a/boards/sensry/ganymed_bob/ganymed_bob_sy120-pinctrl.dtsi b/boards/sensry/ganymed_bob/ganymed_bob_sy120-pinctrl.dtsi new file mode 100644 index 0000000000000..eda591f7ef826 --- /dev/null +++ b/boards/sensry/ganymed_bob/ganymed_bob_sy120-pinctrl.dtsi @@ -0,0 +1,146 @@ +/* Copyright (c) 2024 sensry.io */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +&pinctrl { + + /* UART0 */ + /omit-if-no-ref/ uart0_tx: uart0_tx { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_rx: uart0_rx { + pinmux = ; + input-enable; + }; + + /* UART1 */ + /omit-if-no-ref/ uart1_tx: uart1_tx { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rx: uart1_rx { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ uart1_cts: uart1_cts { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rts: uart1_rts { + pinmux = ; + input-enable; + bias-pull-up; + }; + + /* UART2 */ + /omit-if-no-ref/ uart2_tx: uart2_tx { + pinmux = ; + }; + + /omit-if-no-ref/ uart2_rx: uart2_rx { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ uart2_cts: uart2_cts { + pinmux = ; + }; + + /omit-if-no-ref/ uart2_rts: uart2_rts { + pinmux = ; + input-enable; + bias-pull-up; + }; + + /* MDIO */ + /omit-if-no-ref/ mdio_io: mdio_io { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ mdio_clk: mdio_clk { + pinmux = ; + }; + + /* RGMII */ + /omit-if-no-ref/ rgmii_rx_ctl: rgmii_rx_ctl { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ rgmii_rx_clk: rgmii_rx_clk { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ rgmii_tx_ctl: rgmii_tx_ctl { + pinmux = ; + }; + + /omit-if-no-ref/ rgmii_tx_clk: rgmii_tx_clk { + pinmux = ; + }; + + /omit-if-no-ref/ rgmii_txd0: rgmii_txd0 { + pinmux = ; + }; + + /omit-if-no-ref/ rgmii_txd1: rgmii_txd1 { + pinmux = ; + }; + + /omit-if-no-ref/ rgmii_txd2: rgmii_txd2 { + pinmux = ; + }; + + /omit-if-no-ref/ rgmii_txd3: rgmii_txd3 { + pinmux = ; + }; + + /omit-if-no-ref/ rgmii_rxd0: rgmii_rxd0 { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ rgmii_rxd1: rgmii_rxd1 { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ rgmii_rxd2: rgmii_rxd2 { + pinmux = ; + input-enable; + }; + + /omit-if-no-ref/ rgmii_rxd3: rgmii_rxd3 { + pinmux = ; + input-enable; + }; +}; + + +&uart0 { + pinctrl-0 = <&uart0_tx &uart0_rx>; + pinctrl-names = "default"; +}; + +&uart1 { + pinctrl-0 = <&uart1_tx &uart1_rx &uart1_cts &uart1_rts>; + pinctrl-names = "default"; +}; + +&uart2 { + pinctrl-0 = <&uart2_tx &uart2_rx &uart2_cts &uart2_rts>; + pinctrl-names = "default"; +}; + +ð0 { + pinctrl-0 = <&rgmii_rx_ctl &rgmii_rx_clk + &rgmii_tx_ctl &rgmii_tx_clk + &rgmii_txd0 &rgmii_txd1 &rgmii_txd2 &rgmii_txd3 + &rgmii_rxd0 &rgmii_rxd1 &rgmii_rxd2 &rgmii_rxd3>; + pinctrl-names = "default"; +}; diff --git a/boards/sensry/ganymed_bob/ganymed_bob_sy120_gbm.dts b/boards/sensry/ganymed_bob/ganymed_bob_sy120_gbm.dts index f0c4e8c30bf23..04993ff48f3f0 100644 --- a/boards/sensry/ganymed_bob/ganymed_bob_sy120_gbm.dts +++ b/boards/sensry/ganymed_bob/ganymed_bob_sy120_gbm.dts @@ -3,7 +3,10 @@ /dts-v1/; +#include + #include +#include "ganymed_bob_sy120-pinctrl.dtsi" / { @@ -15,3 +18,26 @@ }; }; + +&mdio0 { + status = "okay"; + + pinctrl-0 = <&mdio_clk &mdio_io>; + pinctrl-names = "default"; + + pyh0: phy@0 { + compatible = "microchip,vsc8541"; + reg = <0x0>; + status = "okay"; + + reset-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + + microchip,interface-type = "rgmii"; + }; +}; + +ð0 { + status = "okay"; + + phy-handle = <&pyh0>; +}; diff --git a/boards/sensry/ganymed_bob/ganymed_bob_sy120_gen1.dts b/boards/sensry/ganymed_bob/ganymed_bob_sy120_gen1.dts index f0c4e8c30bf23..04993ff48f3f0 100644 --- a/boards/sensry/ganymed_bob/ganymed_bob_sy120_gen1.dts +++ b/boards/sensry/ganymed_bob/ganymed_bob_sy120_gen1.dts @@ -3,7 +3,10 @@ /dts-v1/; +#include + #include +#include "ganymed_bob_sy120-pinctrl.dtsi" / { @@ -15,3 +18,26 @@ }; }; + +&mdio0 { + status = "okay"; + + pinctrl-0 = <&mdio_clk &mdio_io>; + pinctrl-names = "default"; + + pyh0: phy@0 { + compatible = "microchip,vsc8541"; + reg = <0x0>; + status = "okay"; + + reset-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + + microchip,interface-type = "rgmii"; + }; +}; + +ð0 { + status = "okay"; + + phy-handle = <&pyh0>; +}; diff --git a/boards/shields/abrobot_esp32c3_oled/Kconfig.shield b/boards/shields/abrobot_esp32c3_oled/Kconfig.shield new file mode 100644 index 0000000000000..61ddd0836b588 --- /dev/null +++ b/boards/shields/abrobot_esp32c3_oled/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Rick Cai +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_SH1106_72X40 + def_bool $(shields_list_contains,sh1106_72x40) diff --git a/boards/shields/abrobot_esp32c3_oled/abrobot_sh1106_72x40.overlay b/boards/shields/abrobot_esp32c3_oled/abrobot_sh1106_72x40.overlay new file mode 100644 index 0000000000000..7160e706c87f8 --- /dev/null +++ b/boards/shields/abrobot_esp32c3_oled/abrobot_sh1106_72x40.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Rick Cai + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,display = &abrobot_72x40; + }; +}; + +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + + abrobot_72x40: ssd1306@3c { + compatible = "sinowealth,sh1106"; + reg = <0x3c>; + width = <72>; + height = <40>; + segment-offset = <30>; + page-offset = <0>; + display-offset = <0xC>; + multiplex-ratio = <0x27>; + prechargep = <0x22>; + ready-time-ms = <10>; + segment-remap; + com-invdir; + use-internal-iref; + }; +}; diff --git a/boards/shields/abrobot_esp32c3_oled/doc/abrobot_esp32c3_oled.webp b/boards/shields/abrobot_esp32c3_oled/doc/abrobot_esp32c3_oled.webp new file mode 100644 index 0000000000000..b9961f50675b0 Binary files /dev/null and b/boards/shields/abrobot_esp32c3_oled/doc/abrobot_esp32c3_oled.webp differ diff --git a/boards/shields/abrobot_esp32c3_oled/doc/index.rst b/boards/shields/abrobot_esp32c3_oled/doc/index.rst new file mode 100644 index 0000000000000..2c887814e1736 --- /dev/null +++ b/boards/shields/abrobot_esp32c3_oled/doc/index.rst @@ -0,0 +1,31 @@ +.. _abrobot_esp32c3oled_shield: + +Abrobot ESP32 C3 OLED Shield +############################ + +Overview +******** + +.. figure:: abrobot_esp32c3_oled.webp + :align: center + :alt: Abrobot ESP32 C3 OLED Shield + +Abrobot esp32c3 oled only works with sh1106_compatible display driver. It does not support 1306 display driver commands. +Its screen resolution is 72x40. +Its screen start position is 30, 12. + +Requirements +************ + +This shield can only be used with esp32c3_042_oled board. + +Programming +*********** + +Set ``-b esp32c3_042_oled --shield abrobot_sh1106_72x40`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/display + :board: esp32c3_042_oled + :shield: abrobot_sh1106_72x40 + :goals: build diff --git a/boards/shields/adafruit_2_8_tft_touch_v2/Kconfig.defconfig b/boards/shields/adafruit_2_8_tft_touch_v2/Kconfig.defconfig index eb44e86b27141..07dcda05e0563 100644 --- a/boards/shields/adafruit_2_8_tft_touch_v2/Kconfig.defconfig +++ b/boards/shields/adafruit_2_8_tft_touch_v2/Kconfig.defconfig @@ -5,14 +5,6 @@ if SHIELD_ADAFRUIT_2_8_TFT_TOUCH_V2 || SHIELD_ADAFRUIT_2_8_TFT_TOUCH_V2_NANO if DISPLAY -if INPUT - -# NOTE: Enable if IRQ line is available (requires to solder jumper) -config INPUT_FT5336_INTERRUPT - default n - -endif # INPUT - if LVGL config LV_Z_VDB_SIZE diff --git a/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.defconfig b/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.defconfig index 38e54dbec887b..17653ad01426f 100644 --- a/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.defconfig +++ b/boards/shields/buydisplay_2_8_tft_touch_arduino/Kconfig.defconfig @@ -5,14 +5,6 @@ if SHIELD_BUYDISPLAY_2_8_TFT_TOUCH_ARDUINO if DISPLAY -if INPUT - -# NOTE: Enable if IRQ line is available (requires to solder jumper) -config INPUT_FT5336_INTERRUPT - default n - -endif # INPUT - if LVGL config LV_Z_VDB_SIZE diff --git a/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.defconfig b/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.defconfig index 1e95dee988eaa..08024b830a793 100644 --- a/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.defconfig +++ b/boards/shields/buydisplay_3_5_tft_touch_arduino/Kconfig.defconfig @@ -5,14 +5,6 @@ if SHIELD_BUYDISPLAY_3_5_TFT_TOUCH_ARDUINO if DISPLAY -if INPUT - -# NOTE: Enable if IRQ line is available (requires to solder jumper) -config INPUT_FT5336_INTERRUPT - default n - -endif # INPUT - if LVGL config LV_Z_VDB_SIZE diff --git a/boards/shields/ftdi_vm800c/ftdi_vm800c.overlay b/boards/shields/ftdi_vm800c/ftdi_vm800c.overlay index 479ac193f25d2..faa68a2a43e72 100644 --- a/boards/shields/ftdi_vm800c/ftdi_vm800c.overlay +++ b/boards/shields/ftdi_vm800c/ftdi_vm800c.overlay @@ -19,7 +19,7 @@ irq-gpios = <&arduino_header 8 GPIO_ACTIVE_LOW>; pclk = <5>; - pclk_pol = <1>; + pclk-pol = <1>; cspread = <1>; swizzle = <0>; vsize = <272>; diff --git a/boards/shields/g1120b0mipi/Kconfig.defconfig b/boards/shields/g1120b0mipi/Kconfig.defconfig index 5a6971aeef38f..dd96ec88e06c2 100644 --- a/boards/shields/g1120b0mipi/Kconfig.defconfig +++ b/boards/shields/g1120b0mipi/Kconfig.defconfig @@ -8,9 +8,6 @@ if LVGL config INPUT default y -config INPUT_FT5336_INTERRUPT - default y - if MIPI_DSI_MCUX_2L # Enable color swap in driver diff --git a/boards/shields/lcd_par_s035/boards/rd_rw612_bga.overlay b/boards/shields/lcd_par_s035/boards/rd_rw612_bga.overlay index 3633336931089..d8d217460b421 100644 --- a/boards/shields/lcd_par_s035/boards/rd_rw612_bga.overlay +++ b/boards/shields/lcd_par_s035/boards/rd_rw612_bga.overlay @@ -84,6 +84,8 @@ * software */ rgb-is-inverted; + /* Enable TE synchronization, using the rising edge */ + te-mode = "MIPI_DBI_TE_RISING_EDGE"; }; &lcdic { @@ -94,4 +96,6 @@ nxp,write-inactive-cycles = <1>; /* Raise the timer0 ratio to enable longer reset delay */ nxp,timer0-ratio = <15>; + /* Lower timer1 ratio to enable shorter TE delay */ + nxp,timer1-ratio = <0>; }; diff --git a/boards/shields/mikroe_eth3_click/Kconfig.defconfig b/boards/shields/mikroe_eth3_click/Kconfig.defconfig new file mode 100644 index 0000000000000..970f0fc910ac2 --- /dev/null +++ b/boards/shields/mikroe_eth3_click/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Mario Paja +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_MIKROE_ETH3_CLICK + +if NETWORKING + +# LAN9250 is L2 chip slave on SPI +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # SHIELD_MIKROE_ETH3_CLICK diff --git a/boards/shields/mikroe_eth3_click/Kconfig.shield b/boards/shields/mikroe_eth3_click/Kconfig.shield new file mode 100644 index 0000000000000..56f8d6893aaf4 --- /dev/null +++ b/boards/shields/mikroe_eth3_click/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Mario Paja +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_MIKROE_ETH3_CLICK + def_bool $(shields_list_contains,mikroe_eth3_click) diff --git a/boards/shields/mikroe_eth3_click/doc/eth3_click.webp b/boards/shields/mikroe_eth3_click/doc/eth3_click.webp new file mode 100644 index 0000000000000..243ec81fec333 Binary files /dev/null and b/boards/shields/mikroe_eth3_click/doc/eth3_click.webp differ diff --git a/boards/shields/mikroe_eth3_click/doc/index.rst b/boards/shields/mikroe_eth3_click/doc/index.rst new file mode 100644 index 0000000000000..10f9669762fbc --- /dev/null +++ b/boards/shields/mikroe_eth3_click/doc/index.rst @@ -0,0 +1,67 @@ +.. _mikroe_eth3_click: + +MikroElektronika ETH 3 Click +############################ + +Overview +******** + +ETH 3 Click is an accessory board in mikroBus™ form factor. It features `LAN9250`_, +a 10/100Mbps BASE-T stand alone Ethernet Controller with an on-board MAC & PHY, +16Kbyte FIFO Buffer and SPI serial interface. +More information at `ETH 3 Click Shield website`_. + +.. figure:: eth3_click.webp + :align: center + :alt: MikroElektronika ETH 3 Click + + MikroElektronika ETH 3 Click (Credit: MikroElektronika) + +Pins Assignment of the Eth Click Shield +======================================= + ++-----------------------+---------------------------------------------+ +| Shield Connector Pin | Function | ++=======================+=============================================+ +| RST# | Ethernet Controller's Reset | ++-----------------------+---------------------------------------------+ +| CS# | SPI's Chip Select | ++-----------------------+---------------------------------------------+ +| SCK | SPI's ClocK | ++-----------------------+---------------------------------------------+ +| SDO | SPI's Slave Data Output (MISO) | ++-----------------------+---------------------------------------------+ +| SDI | SPI's Slave Data Input (MISO) | ++-----------------------+---------------------------------------------+ +| INT | Ethernet Controller's Interrupt Output | ++-----------------------+---------------------------------------------+ + + +Requirements +************ + +This shield can only be used with a board which provides a configuration +for Mikro-BUS connectors and defines node aliases for SPI and GPIO interfaces +(see :ref:`shields` for more details). + +Programming +*********** + +Set ``--shield mikroe_eth3_click`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/dhcpv4_client + :board: mikroe_stm32_m4_clicker + :shield: mikroe_eth3_click + :goals: build + +References +********** + +.. target-notes:: + +.. _ETH 3 Click Shield website: + https://www.mikroe.com/eth-3-click + +.. _LAN9250: + https://www.microchip.com/en-us/product/lan9250 diff --git a/boards/shields/mikroe_eth3_click/mikroe_eth3_click.overlay b/boards/shields/mikroe_eth3_click/mikroe_eth3_click.overlay new file mode 100644 index 0000000000000..6c1bc35cf8369 --- /dev/null +++ b/boards/shields/mikroe_eth3_click/mikroe_eth3_click.overlay @@ -0,0 +1,15 @@ +/* Copyright (c) 2024 Mario Paja + * SPDX-License-Identifier: Apache-2.0 + */ + +&mikrobus_spi { + status = "okay"; + + eth3_click_mikroe_eth3_click: eth3_click@0 { + compatible = "microchip,lan9250"; + reg = <0x0>; + local-mac-address = [00 00 00 01 02 03]; + spi-max-frequency = <30000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; /* INT */ + }; +}; diff --git a/boards/shields/mikroe_weather_click/Kconfig.shield b/boards/shields/mikroe_weather_click/Kconfig.shield index 9c73ce779a27f..be548a7ce8c2f 100644 --- a/boards/shields/mikroe_weather_click/Kconfig.shield +++ b/boards/shields/mikroe_weather_click/Kconfig.shield @@ -1,5 +1,8 @@ # Copyright (c) 2024 Common Ground Electronics # SPDX-License-Identifier: Apache-2.0 -config SHIELD_MIKROE_WEATHER_CLICK - def_bool $(shields_list_contains,mikroe_weather_click) +config SHIELD_MIKROE_WEATHER_CLICK_I2C + def_bool $(shields_list_contains,mikroe_weather_click_i2c) + +config SHIELD_MIKROE_WEATHER_CLICK_SPI + def_bool $(shields_list_contains,mikroe_weather_click_spi) diff --git a/boards/shields/mikroe_weather_click/doc/index.rst b/boards/shields/mikroe_weather_click/doc/index.rst index 3042ff87521a3..80143d80117f5 100644 --- a/boards/shields/mikroe_weather_click/doc/index.rst +++ b/boards/shields/mikroe_weather_click/doc/index.rst @@ -21,8 +21,15 @@ Requirements This shield can only be used with a board that provides a mikroBUS |trade| socket and defines a ``mikrobus_i2c`` node label for the mikroBUS |trade| I2C +interface or a ``mikrobus_spi`` node label for the mikroBUS |trade| SPI interface (see :ref:`shields` for more details). +.. note:: + + By default the Weather Click is configured to use the I2C interface. In + order to use the SPI interface the jumper settings must be changed. See + the `Weather Click Schematic`_ for further details. + For more information about the BME280 and the Weather Click, see the following documentation: @@ -34,13 +41,14 @@ documentation: Programming *********** -Set ``--shield mikroe_weather_click`` when you invoke ``west build``. For +Set ``--shield mikroe_weather_click_i2c`` or +``--shield mikroe_weather_click_spi`` when you invoke ``west build``. For example: .. zephyr-app-commands:: :zephyr-app: samples/sensor/bme280 :board: lpcxpresso55s16 - :shield: mikroe_weather_click + :shield: [mikroe_weather_click_i2c | mikroe_weather_click_spi] :goals: build .. _Weather Click: diff --git a/boards/shields/mikroe_weather_click/mikroe_weather_click.overlay b/boards/shields/mikroe_weather_click/mikroe_weather_click_i2c.overlay similarity index 100% rename from boards/shields/mikroe_weather_click/mikroe_weather_click.overlay rename to boards/shields/mikroe_weather_click/mikroe_weather_click_i2c.overlay diff --git a/boards/shields/mikroe_weather_click/mikroe_weather_click_spi.overlay b/boards/shields/mikroe_weather_click/mikroe_weather_click_spi.overlay new file mode 100644 index 0000000000000..7cf667244f4a5 --- /dev/null +++ b/boards/shields/mikroe_weather_click/mikroe_weather_click_spi.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Ian Morris + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&mikrobus_spi { + status = "okay"; + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + bme280_mikroe_weather_click: bme280@0 { + status = "okay"; + compatible = "bosch,bme280"; + spi-max-frequency = <1000000>; + reg = <0>; + }; +}; diff --git a/boards/shields/nrf7002eb/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/boards/shields/nrf7002eb/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 0000000000000..89e3d5c4c9a27 --- /dev/null +++ b/boards/shields/nrf7002eb/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Only GPIOs 1..11 are supported for PORT1 in nRF54H20DK board, for now + * remove this as Wi-Fi SR co-existence is not yet supported on this board. + * The external SR RF switch may not even be present on this board. + */ +&nrf70 { + /delete-property/ srrf-switch-gpios; +}; diff --git a/boards/shields/p3t1755dp_ard_i2c/Kconfig.shield b/boards/shields/p3t1755dp_ard_i2c/Kconfig.shield new file mode 100644 index 0000000000000..0cdc75a34bebb --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i2c/Kconfig.shield @@ -0,0 +1,8 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SHIELD_P3T1755DP_ARD_I3C + def_bool $(shields_list_contains,p3t1755dp_ard_i3c) diff --git a/boards/shields/p3t1755dp_ard_i2c/boards/frdm_mcxn236.overlay b/boards/shields/p3t1755dp_ard_i2c/boards/frdm_mcxn236.overlay new file mode 100644 index 0000000000000..22ec2f7453cc0 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i2c/boards/frdm_mcxn236.overlay @@ -0,0 +1,14 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&i3c1 { + status = "disabled"; +}; + +&flexcomm5_lpi2c5 { + status = "okay"; + clock-frequency = ; +}; diff --git a/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..5a997072e2471 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,14 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&i3c2 { + status = "disabled"; +}; + +&lpi2c2 { + status = "okay"; + clock-frequency = ; +}; diff --git a/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay new file mode 100644 index 0000000000000..5a997072e2471 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -0,0 +1,14 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&i3c2 { + status = "disabled"; +}; + +&lpi2c2 { + status = "okay"; + clock-frequency = ; +}; diff --git a/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay b/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay new file mode 100644 index 0000000000000..9198366967eed --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i2c/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay @@ -0,0 +1,10 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&flexcomm8_lpi2c8 { + status = "okay"; + clock-frequency = ; +}; diff --git a/boards/shields/p3t1755dp_ard_i2c/doc/index.rst b/boards/shields/p3t1755dp_ard_i2c/doc/index.rst new file mode 100644 index 0000000000000..866ecfd6dd5f3 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i2c/doc/index.rst @@ -0,0 +1,59 @@ +.. _p3t1755dp_ard_i2c_shield: + +P3T1755DP ArduinoÂŽ Shield Evaluation Board +########################################## + +Overview +******** + +P3T1755DP is a Âą0.5 °C accurate temperature-to-digital converter +with a -40 °C to 125 °C range. + +.. figure:: p3t1755dp_ard.webp + :align: center + :alt: P3T1755DP ARD + +Requirements +************ + +The temperature register always stores a 12 bit two's complement data, +giving a temperature resolution of 0.0625 °C. P3T1755DP can be configured +for different operation conditions: continuous conversion, one-shot mode +or shutdown mode. The device supports 2-wire serial I3C (up to 12.5 MHz) +and I²C (up to 3.4 MHz) as communication interface. + +For more information about P3T1755DP-ARD see these NXP documents: + +- `Getting Started with the P3T1755DP-ARD Evaluation Board`_ +- `P3T1755DP-ARD Evaluation Board User Manual`_ + +Hardware Connection +******************* +- Shield board p3t1755dp_ard in I3C mode + J10, J11, J12 3-5, the i3c addr is 0x4800000236152a0090 + JP2, Jp3 1-2 + I3C is from J13 + The VDD from arduino is 3v3 JP1 2-3 + +- Shield board p3t1755dp_ard in I2C mode + J10, J11, J12 3-5, the i2c addr is 0x48 + JP2, Jp3 2-3 + The I2C is from Arduino J5 pin9(SCL_ARD) pin10(SDA_ARD) + The VDD from arduino is 3v3 JP1 2-3 + +Programming +*********** + +Set ``--shield p3t1755dp_ard_i3c`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/thermometer + :board: mimxrt1180_evk/mimxrt1189/cm33 + :shield: p3t1755dp_ard_i3c + :goals: build + +.. _Getting Started with the P3T1755DP-ARD Evaluation Board: + https://www.nxp.com/document/guide/getting-started-with-the-p3t1755dp-ard-evaluation-board:GS-P3T1755DP-ARD + +.. _P3T1755DP-ARD Evaluation Board User Manual: + https://www.nxp.com/docs/en/user-manual/UM11834.pdf diff --git a/boards/shields/p3t1755dp_ard_i2c/doc/p3t1755dp_ard.webp b/boards/shields/p3t1755dp_ard_i2c/doc/p3t1755dp_ard.webp new file mode 100644 index 0000000000000..3c8dd30c617d0 Binary files /dev/null and b/boards/shields/p3t1755dp_ard_i2c/doc/p3t1755dp_ard.webp differ diff --git a/boards/shields/p3t1755dp_ard_i2c/p3t1755dp_ard_i2c.overlay b/boards/shields/p3t1755dp_ard_i2c/p3t1755dp_ard_i2c.overlay new file mode 100644 index 0000000000000..b4f74314dd994 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i2c/p3t1755dp_ard_i2c.overlay @@ -0,0 +1,21 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + ambient-temp0 = &p3t1755_i2c; + }; +}; + +&p3t1755dp_ard_i2c_interface { + status = "okay"; + p3t1755_i2c: p3t1755@48 { + compatible = "nxp,p3t1755"; + reg = <0x48>; + oneshot-mode; + status = "okay"; + }; +}; diff --git a/boards/shields/p3t1755dp_ard_i3c/Kconfig.shield b/boards/shields/p3t1755dp_ard_i3c/Kconfig.shield new file mode 100644 index 0000000000000..0cdc75a34bebb --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i3c/Kconfig.shield @@ -0,0 +1,8 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SHIELD_P3T1755DP_ARD_I3C + def_bool $(shields_list_contains,p3t1755dp_ard_i3c) diff --git a/boards/shields/p3t1755dp_ard_i3c/boards/frdm_mcxn236.overlay b/boards/shields/p3t1755dp_ard_i3c/boards/frdm_mcxn236.overlay new file mode 100644 index 0000000000000..115b33818b156 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i3c/boards/frdm_mcxn236.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * The p3t1755 shield board is plugged into the arduino interface on + * the FRDM-MCXN236 board, and the J13 on the shield board is connected + * to the J9 on the MCXN236 referred below. + * J13-1 -> J9-3; J13-2 -> J9-4; + * J13-3 -> J9-1; J13-4 -> J9-22; + */ + +#include + +&flexcomm5_lpi2c5 { + status = "disabled"; +}; + +&i3c1 { + status = "okay"; + + i2c-scl-hz = ; + i3c-scl-hz = ; + i3c-od-scl-hz = ; +}; diff --git a/boards/shields/p3t1755dp_ard_i3c/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/boards/shields/p3t1755dp_ard_i3c/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..a0e26da50f425 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i3c/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * The p3t1755 shield board is plugged into the arduino interface on + * the MIMXRT1180-EVK board, and the J13 on the shield board is connected + * to the J50 on the RT1180 referred below. + * J13-1 -> J50-1; J13-2 -> J50-2; + * J13-3 -> J50-3; J13-4 -> J50-4; + */ + +#include + +&lpi2c2 { + status = "disabled"; +}; + +&i3c2 { + status = "okay"; + + i2c-scl-hz = ; + i3c-scl-hz = ; + i3c-od-scl-hz = ; +}; diff --git a/boards/shields/p3t1755dp_ard_i3c/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/boards/shields/p3t1755dp_ard_i3c/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay new file mode 100644 index 0000000000000..a0e26da50f425 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i3c/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * The p3t1755 shield board is plugged into the arduino interface on + * the MIMXRT1180-EVK board, and the J13 on the shield board is connected + * to the J50 on the RT1180 referred below. + * J13-1 -> J50-1; J13-2 -> J50-2; + * J13-3 -> J50-3; J13-4 -> J50-4; + */ + +#include + +&lpi2c2 { + status = "disabled"; +}; + +&i3c2 { + status = "okay"; + + i2c-scl-hz = ; + i3c-scl-hz = ; + i3c-od-scl-hz = ; +}; diff --git a/boards/shields/p3t1755dp_ard_i3c/doc/index.rst b/boards/shields/p3t1755dp_ard_i3c/doc/index.rst new file mode 100644 index 0000000000000..ff76ea334109f --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i3c/doc/index.rst @@ -0,0 +1,59 @@ +.. _p3t1755dp_ard_i3c_shield: + +P3T1755DP ArduinoÂŽ Shield Evaluation Board +########################################## + +Overview +******** + +P3T1755DP is a Âą0.5 °C accurate temperature-to-digital converter +with a -40 °C to 125 °C range. + +.. figure:: p3t1755dp_ard.webp + :align: center + :alt: P3T1755DP ARD + +Requirements +************ + +The temperature register always stores a 12 bit two's complement data, +giving a temperature resolution of 0.0625 °C. P3T1755DP can be configured +for different operation conditions: continuous conversion, one-shot mode +or shutdown mode. The device supports 2-wire serial I3C (up to 12.5 MHz) +and I²C (up to 3.4 MHz) as communication interface. + +For more information about P3T1755DP-ARD see these NXP documents: + +- `Getting Started with the P3T1755DP-ARD Evaluation Board`_ +- `P3T1755DP-ARD Evaluation Board User Manual`_ + +Hardware Connection +******************* +- Shield board p3t1755dp_ard in I3C mode + J10, J11, J12 3-5, the i3c addr is 0x4800000236152a0090 + JP2, Jp3 1-2 + I3C is from J13 + The VDD from arduino is 3v3 JP1 2-3 + +- Shield board p3t1755dp_ard in I2C mode + J10, J11, J12 3-5, the i2c addr is 0x48 + JP2, Jp3 2-3 + The I2C is from Arduino J5 pin9(SCL_ARD) pin10(SDA_ARD) + The VDD from arduino is 3v3 JP1 2-3 + +Programming +*********** + +Set ``--shield p3t1755dp_ard_i3c`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/thermometer + :board: mimxrt1180_evk/mimxrt1189/cm33 + :shield: p3t1755dp_ard_i3c + :goals: build + +.. _Getting Started with the P3T1755DP-ARD Evaluation Board: + https://www.nxp.com/document/guide/getting-started-with-the-p3t1755dp-ard-evaluation-board:GS-P3T1755DP-ARD + +.. _P3T1755DP-ARD Evaluation Board User Manual: + https://www.nxp.com/docs/en/user-manual/UM11834.pdf diff --git a/boards/shields/p3t1755dp_ard_i3c/doc/p3t1755dp_ard.webp b/boards/shields/p3t1755dp_ard_i3c/doc/p3t1755dp_ard.webp new file mode 100644 index 0000000000000..3c8dd30c617d0 Binary files /dev/null and b/boards/shields/p3t1755dp_ard_i3c/doc/p3t1755dp_ard.webp differ diff --git a/boards/shields/p3t1755dp_ard_i3c/p3t1755dp_ard_i3c.overlay b/boards/shields/p3t1755dp_ard_i3c/p3t1755dp_ard_i3c.overlay new file mode 100644 index 0000000000000..572368f952387 --- /dev/null +++ b/boards/shields/p3t1755dp_ard_i3c/p3t1755dp_ard_i3c.overlay @@ -0,0 +1,20 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + ambient-temp0 = &p3t1755_i3c; + }; +}; + +&p3t1755dp_ard_i3c_interface { + status = "okay"; + p3t1755_i3c: p3t1755@4800000236152a0090 { + compatible = "nxp,p3t1755"; + reg = <0x48 0x0236 0x152a0090>; + status = "okay"; + }; +}; diff --git a/boards/shields/pmod_sd/Kconfig.shield b/boards/shields/pmod_sd/Kconfig.shield new file mode 100644 index 0000000000000..8da50ac822494 --- /dev/null +++ b/boards/shields/pmod_sd/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_PMOD_SD + def_bool $(shields_list_contains,pmod_sd) diff --git a/boards/shields/pmod_sd/boards/ek_ra8d1.overlay b/boards/shields/pmod_sd/boards/ek_ra8d1.overlay new file mode 100644 index 0000000000000..65f155cf28da3 --- /dev/null +++ b/boards/shields/pmod_sd/boards/ek_ra8d1.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&pmod_sd_shield { + interrupt-names = "accs", "card", "dma-req"; + interrupts = <60 12>, <61 12>, <62 12>; + pinctrl-0 = <&sdhc1_default>; +}; diff --git a/boards/shields/pmod_sd/doc/index.rst b/boards/shields/pmod_sd/doc/index.rst new file mode 100644 index 0000000000000..eaf051f4c0803 --- /dev/null +++ b/boards/shields/pmod_sd/doc/index.rst @@ -0,0 +1,54 @@ +.. _pmod_sd: + +Digilent Pmod SD +################ + +Overview +******** + +The Digilent Pmod SD (Revision B) allows system boards to read from and write to SD cards. + +Features +******** + +- Full-sized SD card slot +- Store and access large amounts of date from your system board +- No limitation on file system or memory size of SD card used +- 1-bit and 4-bit communication +- 12-pin Pmod port with SPI interface + +Programming +*********** + +Set ``--shield pmod_sd`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: tests/drivers/disk/disk_access + :board: ek_ra8m1 + :shield: pmod_sd + :goals: build + +Pinout +====== + +.. figure:: pmod_sd_pins.webp + :align: center + :alt: PMOD SD Pinout + + PMOD SD Pinout (Credit: Digilent) + +References +********** + +- `Pmod SD product page`_ +- `Pmod SD reference manual`_ +- `Pmod SD schematic`_ + +.. _Pmod SD product page: + https://digilent.com/shop/pmod-sd-full-sized-sd-card-slot/ + +.. _Pmod SD reference manual: + https://digilent.com/reference/pmod/pmodsd/reference-manual + +.. _Pmod SD schematic: + https://digilent.com/reference/_media/reference/pmod/pmodsd/pmodsd_sch.pdf diff --git a/boards/shields/pmod_sd/doc/pmod_sd_pins.webp b/boards/shields/pmod_sd/doc/pmod_sd_pins.webp new file mode 100644 index 0000000000000..3be8baedb1e00 Binary files /dev/null and b/boards/shields/pmod_sd/doc/pmod_sd_pins.webp differ diff --git a/boards/shields/pmod_sd/pmod_sd.overlay b/boards/shields/pmod_sd/pmod_sd.overlay new file mode 100644 index 0000000000000..6bf8d7675c04f --- /dev/null +++ b/boards/shields/pmod_sd/pmod_sd.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &pmod_sd_shield; + }; +}; + +&pmod_sd_shield { + pinctrl-0 = <&sdhc0_default>; + pinctrl-names = "default"; + status = "okay"; + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; diff --git a/boards/shields/renesas_us159_da14531evz/Kconfig.shield b/boards/shields/renesas_us159_da14531evz/Kconfig.shield new file mode 100644 index 0000000000000..85cea91bb85c7 --- /dev/null +++ b/boards/shields/renesas_us159_da14531evz/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_RENESAS_US159_DA14531EVZ + def_bool $(shields_list_contains,renesas_us159_da14531evz) diff --git a/boards/shields/renesas_us159_da14531evz/boards/ek_ra8m1.overlay b/boards/shields/renesas_us159_da14531evz/boards/ek_ra8m1.overlay new file mode 100644 index 0000000000000..d17555e4f7918 --- /dev/null +++ b/boards/shields/renesas_us159_da14531evz/boards/ek_ra8m1.overlay @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci0_default: sci0_default { + group1 { + /* tx */ + psels = ; + drive-strength = "medium"; + }; + group2 { + /* rx, rts, cts */ + psels = , + , + ; + }; + }; +}; + +&sci0 { + pinctrl-0 = <&sci0_default>; + pinctrl-names = "default"; + status = "okay"; + uart0: uart { + current-speed = <115200>; + hw-flow-control; + status = "okay"; + }; +}; diff --git a/boards/shields/renesas_us159_da14531evz/doc/da14531-hci-hw-flow-binary.webp b/boards/shields/renesas_us159_da14531evz/doc/da14531-hci-hw-flow-binary.webp new file mode 100644 index 0000000000000..0bbf133565239 Binary files /dev/null and b/boards/shields/renesas_us159_da14531evz/doc/da14531-hci-hw-flow-binary.webp differ diff --git a/boards/shields/renesas_us159_da14531evz/doc/index.rst b/boards/shields/renesas_us159_da14531evz/doc/index.rst new file mode 100644 index 0000000000000..1b302e4ac149d --- /dev/null +++ b/boards/shields/renesas_us159_da14531evz/doc/index.rst @@ -0,0 +1,79 @@ +.. _renesas_us159_da14531evz_shield: + +Renesas DA14531 Pmod Board +########################## + +Overview +******** + +The Renesas US159 DA14531EVZ carries a `DA14531MOD`_ Bluetooth LE module +in a `Digilent Pmod`_ |trade| form factor. + +.. figure:: us159-da14531evz-pmod.webp + :align: center + :alt: Renesas US159 DA14531EVZ Pmod + + Renesas US159 DA14531EVZ Pmod (Credit: Renesas Electronics) + +Requirements +************ + +This shield can only be used with a board that provides a Pmod |trade| +socket and defines the ``pmod_serial`` node label (see :ref:`shields` for +more details). + +The DA14531 Module contained on the shield must be programmed with a binary +file that supports the HCI interface over UART, with hardware flow control +enabled. + +The `Renesas SmartBond Flash Programmer`_ tool can be used to download a +suitable binary and then program it into the DA14531 via the SWD header +present on the Pmod board. Once the tool has been installed, open it and +press the "Search Online" button. The required binary file can be selected +for download as follows: + +.. figure:: da14531-hci-hw-flow-binary.webp + :align: center + :alt: DA14531 HCI Binary File Selection + + Selecting the DA14531 HCI Binary File for Download + +Press the "Program" button to program the binary file into the DA14531 Module. + +For more information about interfacing to the DA14531 and the US159 DA14531EVZ +Pmod, see the following documentation: + +- `DA14531MOD Datasheet`_ +- `US159 DA14531EVZ Pmod`_ + +Programming +*********** + +Set ``--shield renesas_us159_da14531evz`` when you invoke ``west build``. For +example: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/beacon + :board: ek_ra8m1 + :shield: renesas_us159_da14531evz + :goals: build + +References +********** + +.. target-notes:: + +.. _DA14531MOD: + https://www.renesas.com/us/en/products/wireless-connectivity/bluetooth-low-energy/da14531mod-smartbond-tiny-bluetooth-low-energy-module + +.. _Digilent Pmod: + https://digilent.com/reference/pmod/start + +.. _Renesas SmartBond Flash Programmer: + https://www.renesas.com/us/en/software-tool/smartbond-flash-programmer + +.. _DA14531MOD Datasheet: + https://www.renesas.com/us/en/document/dst/da14531-module-datasheet?r=1601921 + +.. _US159 DA14531EVZ Pmod: + https://www.renesas.com/en/products/wireless-connectivity/bluetooth-low-energy/us159-da14531evz-low-power-bluetooth-pmod-board-renesas-quickconnect-iot diff --git a/boards/shields/renesas_us159_da14531evz/doc/us159-da14531evz-pmod.webp b/boards/shields/renesas_us159_da14531evz/doc/us159-da14531evz-pmod.webp new file mode 100644 index 0000000000000..cb3cb2f42d695 Binary files /dev/null and b/boards/shields/renesas_us159_da14531evz/doc/us159-da14531evz-pmod.webp differ diff --git a/boards/shields/renesas_us159_da14531evz/renesas_us159_da14531evz.overlay b/boards/shields/renesas_us159_da14531evz/renesas_us159_da14531evz.overlay new file mode 100644 index 0000000000000..e943e75dc0365 --- /dev/null +++ b/boards/shields/renesas_us159_da14531evz/renesas_us159_da14531evz.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,bt-hci = &bt_hci_uart; + }; +}; + +&pmod_serial { + status = "okay"; + + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; + status = "okay"; + + da1453x { + compatible = "renesas,bt-hci-da1453x"; + status = "okay"; + reset-gpios = <&pmod_header 5 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/boards/shields/rk043fn02h_ct/Kconfig.defconfig b/boards/shields/rk043fn02h_ct/Kconfig.defconfig index f2b199d916968..65edfb50c7a50 100644 --- a/boards/shields/rk043fn02h_ct/Kconfig.defconfig +++ b/boards/shields/rk043fn02h_ct/Kconfig.defconfig @@ -8,9 +8,6 @@ if LVGL config INPUT default y -config INPUT_FT5336_INTERRUPT - default y - # LVGL should allocate buffers equal to size of display config LV_Z_VDB_SIZE default 100 diff --git a/boards/shields/rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/boards/shields/rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf index bf60c87c6934c..000b59e0b43ce 100644 --- a/boards/shields/rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf +++ b/boards/shields/rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -6,7 +6,7 @@ # Use external framebuffer memory CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM=y -CONFIG_LV_Z_VBD_CUSTOM_SECTION=y +CONFIG_LV_Z_VDB_CUSTOM_SECTION=y # Use FlexSPI2 for framebuffer (pSRAM is present on this bus) CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR=0x38400000 # M33 core and LCDIF both access FlexSPI2 through the same cache, diff --git a/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_mimxrt595s_cm33.conf index bf60c87c6934c..000b59e0b43ce 100644 --- a/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_mimxrt595s_cm33.conf +++ b/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -6,7 +6,7 @@ # Use external framebuffer memory CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM=y -CONFIG_LV_Z_VBD_CUSTOM_SECTION=y +CONFIG_LV_Z_VDB_CUSTOM_SECTION=y # Use FlexSPI2 for framebuffer (pSRAM is present on this bus) CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR=0x38400000 # M33 core and LCDIF both access FlexSPI2 through the same cache, diff --git a/boards/shields/rtkmipilcdb00000be/Kconfig.defconfig b/boards/shields/rtkmipilcdb00000be/Kconfig.defconfig new file mode 100644 index 0000000000000..749284f97fb65 --- /dev/null +++ b/boards/shields/rtkmipilcdb00000be/Kconfig.defconfig @@ -0,0 +1,57 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_RTKMIPILCDB00000BE +if DISPLAY + +# Enable MIPI DSI, as this display controller requires it. + +config MIPI_DSI + default y + +endif # DISPLAY + +if LVGL + +# Configure LVGL to use touchscreen with input API + +config INPUT + default y + +if INPUT + +# GT911 driver drives reset pin low, GT911 and ILI9806E_DSI driver share a reset line, +# so it needs to initialize before the display_ili9806e_dsi driver but after the MIPI DSI driver + +config INPUT_INIT_PRIORITY + default 89 + +endif # INPUT + +# LVGL should allocate buffers equal to size of display +config LV_Z_VDB_SIZE + default 100 + +# Enable double buffering +config LV_Z_DOUBLE_VDB + default y + +# Force full refresh. This prevents memory copy associated with partial +# display refreshes, which is not necessary for the GLCDC driver +config LV_Z_FULL_REFRESH + default y + +config LV_Z_BITS_PER_PIXEL + default 32 + +# Use offloaded render thread +config LV_Z_FLUSH_THREAD + default y + +choice LV_COLOR_DEPTH + default LV_COLOR_DEPTH_32 +endchoice + +endif # LVGL + +endif # SHIELD_RTKMIPILCDB00000BE diff --git a/boards/shields/rtkmipilcdb00000be/Kconfig.shield b/boards/shields/rtkmipilcdb00000be/Kconfig.shield new file mode 100644 index 0000000000000..0081d3f9819e1 --- /dev/null +++ b/boards/shields/rtkmipilcdb00000be/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_RTKMIPILCDB00000BE + def_bool $(shields_list_contains,rtkmipilcdb00000be) diff --git a/boards/shields/rtkmipilcdb00000be/boards/ek_ra8d1.conf b/boards/shields/rtkmipilcdb00000be/boards/ek_ra8d1.conf new file mode 100644 index 0000000000000..0ac7b7ace6abc --- /dev/null +++ b/boards/shields/rtkmipilcdb00000be/boards/ek_ra8d1.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LV_Z_FLUSH_THREAD=n +CONFIG_LV_Z_BITS_PER_PIXEL=16 +CONFIG_LV_COLOR_DEPTH_16=y diff --git a/boards/shields/rtkmipilcdb00000be/boards/ek_ra8d1.overlay b/boards/shields/rtkmipilcdb00000be/boards/ek_ra8d1.overlay new file mode 100644 index 0000000000000..4bab6b914dcd1 --- /dev/null +++ b/boards/shields/rtkmipilcdb00000be/boards/ek_ra8d1.overlay @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + iic1_default: iic1_default { + group1 { + /* SCL1 SDA1 */ + psels = , + ; + drive-strength = "medium"; + }; + }; +}; + +&iic1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + pinctrl-0 = <&iic1_default>; + pinctrl-names = "default"; +}; + +&zephyr_lcdif { + input-pixel-format = ; +}; diff --git a/boards/shields/rtkmipilcdb00000be/doc/index.rst b/boards/shields/rtkmipilcdb00000be/doc/index.rst new file mode 100644 index 0000000000000..4e77512e6d5ac --- /dev/null +++ b/boards/shields/rtkmipilcdb00000be/doc/index.rst @@ -0,0 +1,61 @@ +.. _rtkmipilcdb00000be: + +RTKMIPILCDB00000BE MIPI Display +############################### + +Overview +******** + +The Focus LCDs RTKMIPILCDB00000BE MIPI Display is a 4.5 inch TFT 480x854 pixels +capacitive touch panel, and a backlight unit. + +This display uses a 26 pin connector header. + +Pins Assignment of the Renesas RTKMIPILCDB00000BE MIPI Display +============================================================== + ++-----------------------+------------------------+ +| Connector Pin | Function | ++=======================+========================+ +| 14 | Touch ctrl I2C SDA | ++-----------------------+------------------------+ +| 15 | Display backlight enable| ++-----------------------+------------------------+ +| 16 | Touch ctrl I2C SCL | ++-----------------------+------------------------+ +| 17 | External interrupt | ++-----------------------+------------------------+ +| 18 | Display reset | ++-----------------------+------------------------+ + +Hardware Requirements: +********************** + +Supported Renesas RA boards: EK-RA8D1 +- 1 x RA Board +- 1 x Micro USB cable + +Hardware Configuration: +*********************** + +The MIPI Graphics Expansion Port (J58) connects the EK-RA8D1 board to the MIPI Graphics Expansion Board +supplied as part of the kit. + +Set the configuration switches (SW1) as below to avoid potential failures. + +-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ + | SW1-1 PMOD1 | SW1-2 TRACE | SW1-3 CAMERA | SW1-4 ETHA | SW1-5 ETHB | SW1-6 GLCD | SW1-7 SDRAM | SW1-8 I3C | + +-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ + | OFF | OFF | OFF | OFF | OFF | ON | ON | OFF | + +-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ + +Programming +*********** + +Set ``--shield=rtkmipilcdb00000be`` when you invoke ``west build``. For +example: + +.. zephyr-app-commands:: + :zephyr-app: tests/drivers/display/display_read_write + :board: ek_ra8d1 + :shield: rtkmipilcdb00000be + :goals: build diff --git a/boards/shields/rtkmipilcdb00000be/rtkmipilcdb00000be.overlay b/boards/shields/rtkmipilcdb00000be/rtkmipilcdb00000be.overlay new file mode 100644 index 0000000000000..1902a9cb55b74 --- /dev/null +++ b/boards/shields/rtkmipilcdb00000be/rtkmipilcdb00000be.overlay @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/{ + chosen { + zephyr,display = &zephyr_lcdif; + }; + + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <>911_rtkmipilcdb00000be>; + }; +}; + +&renesas_mipi_i2c { + status = "okay"; + gt911_rtkmipilcdb00000be: gt911-rtkmipilcdb00000be@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + irq-gpios = <&renesas_mipi_connector 17 GPIO_ACTIVE_HIGH>; + reset-gpios = <&renesas_mipi_connector 18 GPIO_ACTIVE_LOW>; + }; +}; + +&zephyr_mipi_dsi { + status = "okay"; + ili9806e: ili9806e@0 { + status = "okay"; + compatible = "ilitek,ili9806e-dsi"; + reg = <0x0>; + height = <854>; + width = <480>; + data-lanes = <2>; + pixel-format = ; + }; +}; + +&zephyr_lcdif { + status = "okay"; + width = <480>; + height = <854>; + input-pixel-format = ; + output-pixel-format = ; + display-timings { + compatible = "zephyr,panel-timing"; + hsync-len = <2>; + hback-porch = <5>; + vsync-len = <3>; + vback-porch = <20>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + hfront-porch = <72>; + vfront-porch = <17>; + }; + backlight-gpios = <&renesas_mipi_connector 15 GPIO_ACTIVE_HIGH>; +}; diff --git a/boards/shields/semtech_sx1276mb1mas/doc/index.rst b/boards/shields/semtech_sx1276mb1mas/doc/index.rst index d4b7d07c45417..ef72a16d3245b 100644 --- a/boards/shields/semtech_sx1276mb1mas/doc/index.rst +++ b/boards/shields/semtech_sx1276mb1mas/doc/index.rst @@ -58,7 +58,7 @@ Arduino connectors and defines node aliases for SPI and GPIO interfaces (see Programming *********** -Set ``--shield semtech_sx1271mb1mas`` when you invoke ``west build``. For +Set ``--shield semtech_sx1276mb1mas`` when you invoke ``west build``. For example: .. zephyr-app-commands:: diff --git a/boards/shields/sparkfun_carrier_asset_tracker/Kconfig.defconfig b/boards/shields/sparkfun_carrier_asset_tracker/Kconfig.defconfig deleted file mode 100644 index da44e62a05f1c..0000000000000 --- a/boards/shields/sparkfun_carrier_asset_tracker/Kconfig.defconfig +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2024 JerĂłnimo AgullĂł -# SPDX-License-Identifier: Apache-2.0 - -if SHIELD_SPARKFUN_CARRIER_ASSET_TRACKER - -config SERIAL - default y - -config UART_INTERRUPT_DRIVEN - default y - -config UART_ASYNC_API - default y - -config I2C - default y - -config SPI - default y - -endif # SHIELD_SPARKFUN_CARRIER_ASSET_TRACKER diff --git a/boards/shields/ssd1306/ssd1306_128x64_spi.overlay b/boards/shields/ssd1306/ssd1306_128x64_spi.overlay index 7aabf73b2ee60..ad9301086f1a1 100644 --- a/boards/shields/ssd1306/ssd1306_128x64_spi.overlay +++ b/boards/shields/ssd1306/ssd1306_128x64_spi.overlay @@ -26,7 +26,7 @@ segment-remap; com-invdir; prechargep = <0x22>; - data_cmd-gpios = <&arduino_header 15 0>; + data-cmd-gpios = <&arduino_header 15 0>; /* reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; */ }; }; diff --git a/boards/shields/st_b_cams_omv_mb1683/Kconfig.shield b/boards/shields/st_b_cams_omv_mb1683/Kconfig.shield new file mode 100644 index 0000000000000..48bd6cd82492a --- /dev/null +++ b/boards/shields/st_b_cams_omv_mb1683/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Charles Dias +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ST_B_CAMS_OMV_MB1683 + def_bool $(shields_list_contains,st_b_cams_omv_mb1683) diff --git a/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7b3i_dk.overlay b/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7b3i_dk.overlay new file mode 100644 index 0000000000000..c6e629d23425b --- /dev/null +++ b/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7b3i_dk.overlay @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Charles Dias + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +&st_cam_i2c { + pinctrl-0 = <&i2c4_scl_pd12 &i2c4_sda_pd13>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&st_cam_dvp { + pinctrl-0 = <&dcmi_hsync_pa4 &dcmi_pixclk_pa6 &dcmi_vsync_pb7 + &dcmi_d0_pc6 &dcmi_d1_pc7 &dcmi_d2_pg10 &dcmi_d3_pc9 + &dcmi_d4_pc11 &dcmi_d5_pd3 &dcmi_d6_pb8 &dcmi_d7_pb9>; + pinctrl-names = "default"; + + dmas = <&dma1 0 75 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | + STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | + STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; +}; + +&dma1 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; diff --git a/boards/shields/st_b_cams_omv_mb1683/doc/index.rst b/boards/shields/st_b_cams_omv_mb1683/doc/index.rst new file mode 100644 index 0000000000000..754fbf2c9b7cb --- /dev/null +++ b/boards/shields/st_b_cams_omv_mb1683/doc/index.rst @@ -0,0 +1,153 @@ +.. _st_b_cams_omv_mb1683: + +ST B-CAMS-OMV-MB1683 +#################### + +Overview +******** + +The camera module bundle (B-CAMS-OMV) provides extension connectors +for the MB1379 STMicroelectronics camera module daughterboard or +third-party modules like OpenMV and Waveshare modules. It can be used +with the STM32 boards featuring a 1 x 30 pin ZIF connector for the +connection of multiple cameras to implement computer vision on STM32 +microcontrollers easily. + +The camera module bundle is compatible with all STM32 Discovery kits and +Evaluation boards featuring a ZIF connector, such as the STM32H747I-DISCO, +STM32H7B3I-DK, and 32L4R9IDISCOVERY Discovery kits. + +.. figure:: st_b_cams_omv.webp + :width: 600px + :align: center + :alt: B-CAMS-OMV-MB1683 + + B-CAMS-OMV MB1683 Image (Credit: STMicroelectronics.) + +The camera signals go into the shield from one of the supported input +connectors (CN1, CN2, CN4), and out of the shield towards Zephyr through +the output 30-pin ZIF connector CN5. + +Refer to the `User manual`_ for the pinout of CN1 and CN2. + +Waveshare camera board connector CN4 (camera input) +*************************************************** + ++------------+-----------------+------------+--------------+ +| Pin number | Description | Pin number | Description | ++============+=================+============+==============+ +| 1 | GND | 2 | VCAM | ++------------+-----------------+------------+--------------+ +| 3 | I2C_SDA | 4 | I2C_SCL | ++------------+-----------------+------------+--------------+ +| 5 | DCMI_HSYNC | 6 | DCMI_VSYNC | ++------------+-----------------+------------+--------------+ +| 7 | Camera_CLK | 8 | DCMI_PIXCLK | ++------------+-----------------+------------+--------------+ +| 9 | DCMI_D6 | 10 | DCMI_D7 | ++------------+-----------------+------------+--------------+ +| 11 | DCMI_D4 | 12 | DCMI_D5 | ++------------+-----------------+------------+--------------+ +| 13 | DCMI_D2 | 14 | DCMI_D3 | ++------------+-----------------+------------+--------------+ +| 15 | DCMI_D0 | 16 | DCMI_D1 | ++------------+-----------------+------------+--------------+ +| 17 | PWR_EN / LED1 | 18 | RESET# | ++------------+-----------------+------------+--------------+ + +ZIF connector CN5 (camera output) +********************************* + ++------------+-----------------+ +| Pin number | Description | ++============+=================+ +| 1 | 3V3 | ++------------+-----------------+ +| 2 | GND | ++------------+-----------------+ +| 3 | I2C_SCL | ++------------+-----------------+ +| 4 | I2C_SDA | ++------------+-----------------+ +| 5 | RESET# | ++------------+-----------------+ +| 6 | PWR_EN / LED1 | ++------------+-----------------+ +| 7 | SHUTTER | ++------------+-----------------+ +| 8 | GND | ++------------+-----------------+ +| 9 | PULLDOWN / LED2 | ++------------+-----------------+ +| 10 | Camera_CLK | ++------------+-----------------+ +| 11 | 3V3 | ++------------+-----------------+ +| 12 | DCMI_VSYNC | ++------------+-----------------+ +| 13 | 5V (RSU) | ++------------+-----------------+ +| 14 | DCMI_HSYNC | ++------------+-----------------+ +| 15 | GND | ++------------+-----------------+ +| 16 | DCMI_PIXCK | ++------------+-----------------+ +| 17 | GND | ++------------+-----------------+ +| 18 | SPI_MISO | ++------------+-----------------+ +| 19 | SPI_CS | ++------------+-----------------+ +| 20 | DCMI_D7 | ++------------+-----------------+ +| 21 | DCMI_D6 | ++------------+-----------------+ +| 22 | DCMI_D5 | ++------------+-----------------+ +| 23 | DCMI_D4 | ++------------+-----------------+ +| 24 | DCMI_D3 | ++------------+-----------------+ +| 25 | DCMI_D2 | ++------------+-----------------+ +| 26 | DCMI_D1 | ++------------+-----------------+ +| 27 | DCMI_D0 | ++------------+-----------------+ +| 28 | SPI_MOSI | ++------------+-----------------+ +| 29 | SPI_CLK | ++------------+-----------------+ +| 30 | GND | ++------------+-----------------+ + +Requirements +************ + +The camera module bundle is compatible with all STM32 Discovery kits and +Evaluation boards featuring a ZIF connector, such as the STM32H747I-DISCO, +STM32H7B3I-DK, and 32L4R9IDISCOVERY Discovery kits. + +Usage +***** + +The shield can be used in any application by setting ``SHIELD`` to +``_st_b_cams_omv_mb1683`` and adding the necessary device tree properties. + +Set ``--shield "st_b_cams_omv_mb1683"`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/video/capture_to_lvgl + :board: stm32h7b3i_dk + :shield: st_b_cams_omv_mb1683 + :goals: build + +References +********** + +- `Product page `_ + +- `Databrief `_ + +- `User manual `_ diff --git a/boards/shields/st_b_cams_omv_mb1683/doc/st_b_cams_omv.webp b/boards/shields/st_b_cams_omv_mb1683/doc/st_b_cams_omv.webp new file mode 100644 index 0000000000000..2060d43b2e421 Binary files /dev/null and b/boards/shields/st_b_cams_omv_mb1683/doc/st_b_cams_omv.webp differ diff --git a/boards/shields/st_b_cams_omv_mb1683/st_b_cams_omv_mb1683.overlay b/boards/shields/st_b_cams_omv_mb1683/st_b_cams_omv_mb1683.overlay new file mode 100644 index 0000000000000..0ffb5669dadfe --- /dev/null +++ b/boards/shields/st_b_cams_omv_mb1683/st_b_cams_omv_mb1683.overlay @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Charles Dias + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +/ { + chosen { + zephyr,camera = &st_cam_dvp; + }; +}; + +&st_cam_i2c { + + ov5640: ov5640@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + status = "okay"; + reset-gpios = <&dmci_camera_connector 5 GPIO_ACTIVE_LOW>; + powerdown-gpios = <&dmci_camera_connector 6 GPIO_ACTIVE_HIGH>; + + port { + ov5640_ep_out: endpoint { + remote-endpoint-label = "dcmi_ep_in"; + bus-type = ; + }; + }; + }; +}; + +&st_cam_dvp { + status = "okay"; + sensor = <&ov5640>; + + bus-width = <8>; + hsync-active = <0>; + vsync-active = <0>; + pixelclk-active = <1>; + capture-rate = <1>; + + port { + dcmi_ep_in: endpoint { + remote-endpoint-label = "ov5640_ep_out"; + }; + }; +}; diff --git a/boards/shields/st_b_lcd40_dsi1_mb1166/boards/stm32h747i_disco_stm32h747xx_m7.defconfig b/boards/shields/st_b_lcd40_dsi1_mb1166/boards/stm32h747i_disco_stm32h747xx_m7.defconfig index 8a363e39a71b0..f7cdddf0944bb 100644 --- a/boards/shields/st_b_lcd40_dsi1_mb1166/boards/stm32h747i_disco_stm32h747xx_m7.defconfig +++ b/boards/shields/st_b_lcd40_dsi1_mb1166/boards/stm32h747i_disco_stm32h747xx_m7.defconfig @@ -11,7 +11,7 @@ config STM32_LTDC_FB_NUM config LV_Z_DOUBLE_VDB default y -config LV_Z_VBD_CUSTOM_SECTION +config LV_Z_VDB_CUSTOM_SECTION default y config LV_Z_FULL_REFRESH diff --git a/boards/shields/x_nucleo_iks02a1/boards/nucleo_f411re.overlay b/boards/shields/x_nucleo_iks02a1/boards/nucleo_f411re.overlay index 1591debc93746..e57bf8cafd9f7 100644 --- a/boards/shields/x_nucleo_iks02a1/boards/nucleo_f411re.overlay +++ b/boards/shields/x_nucleo_iks02a1/boards/nucleo_f411re.overlay @@ -5,9 +5,12 @@ */ &plli2s { + div-m = <8>; mul-n = <192>; div-r = <3>; - status = "okay"; + div-q = <4>; + clocks = <&clk_hse>; + status = "okay"; /* 48MHz on PLLI2SQ */ }; &dma2 { diff --git a/boards/shields/x_nucleo_iks4a1/x_nucleo_iks4a1.overlay b/boards/shields/x_nucleo_iks4a1/x_nucleo_iks4a1.overlay index 3cda8324777d0..eaa60be0f4dae 100644 --- a/boards/shields/x_nucleo_iks4a1/x_nucleo_iks4a1.overlay +++ b/boards/shields/x_nucleo_iks4a1/x_nucleo_iks4a1.overlay @@ -9,6 +9,7 @@ magn0 = &lis2mdl_1e_x_nucleo_iks4a1; accel0 = &lsm6dso16is_6a_x_nucleo_iks4a1; accel1 = &lsm6dsv16x_6b_x_nucleo_iks4a1; + accel2 = &lis2duxs12_1e_x_nucleo_iks4a1; press0 = &lps22df_5d_x_nucleo_iks4a1; }; }; @@ -45,4 +46,11 @@ drdy-pulsed; drdy-gpios = <&arduino_header 12 GPIO_ACTIVE_HIGH>; /* D6 (PB10) */ }; + + lis2duxs12_1e_x_nucleo_iks4a1: lis2duxs12@19 { + compatible = "st,lis2duxs12"; + reg = <0x19>; + int1-gpios = <&arduino_header 3 GPIO_ACTIVE_HIGH>; /* A3 */ + }; + }; diff --git a/boards/silabs/dev_kits/sim3u1xx_dk/sim3u1xx_dk.yaml b/boards/silabs/dev_kits/sim3u1xx_dk/sim3u1xx_dk.yaml index 13a20e8a73665..0617a1a05fa42 100644 --- a/boards/silabs/dev_kits/sim3u1xx_dk/sim3u1xx_dk.yaml +++ b/boards/silabs/dev_kits/sim3u1xx_dk/sim3u1xx_dk.yaml @@ -10,7 +10,6 @@ ram: 32 flash: 256 toolchain: - gnuarmemb - - xtools - zephyr supported: - crypto diff --git a/boards/silabs/dev_kits/sltb004a/doc/index.rst b/boards/silabs/dev_kits/sltb004a/doc/index.rst index 13b0ddc47c6fe..14795756afc37 100644 --- a/boards/silabs/dev_kits/sltb004a/doc/index.rst +++ b/boards/silabs/dev_kits/sltb004a/doc/index.rst @@ -142,7 +142,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -199,6 +199,3 @@ the following message: .. _J-Link: https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/dev_kits/sltb004a/sltb004a.dts b/boards/silabs/dev_kits/sltb004a/sltb004a.dts index 5252b0b6a48f0..10ecd3c946f72 100644 --- a/boards/silabs/dev_kits/sltb004a/sltb004a.dts +++ b/boards/silabs/dev_kits/sltb004a/sltb004a.dts @@ -81,7 +81,7 @@ }; &usart2 { - compatible = "silabs,gecko-spi-usart"; + compatible = "silabs,usart-spi"; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/silabs/dev_kits/sltb004a/sltb004a.yaml b/boards/silabs/dev_kits/sltb004a/sltb004a.yaml index c1e842247f6f4..5eb52c7e024a1 100644 --- a/boards/silabs/dev_kits/sltb004a/sltb004a.yaml +++ b/boards/silabs/dev_kits/sltb004a/sltb004a.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/silabs/dev_kits/sltb009a/doc/index.rst b/boards/silabs/dev_kits/sltb009a/doc/index.rst index 1e0489dbad3ff..8be84aefc6036 100644 --- a/boards/silabs/dev_kits/sltb009a/doc/index.rst +++ b/boards/silabs/dev_kits/sltb009a/doc/index.rst @@ -101,7 +101,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -152,6 +152,3 @@ terminal session: .. _J-Link: https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/dev_kits/sltb010a/Kconfig.defconfig b/boards/silabs/dev_kits/sltb010a/Kconfig.defconfig index 047c526aad245..fac4f17b12e8e 100644 --- a/boards/silabs/dev_kits/sltb010a/Kconfig.defconfig +++ b/boards/silabs/dev_kits/sltb010a/Kconfig.defconfig @@ -1,12 +1,6 @@ # Copyright (c) 2023 Antmicro # SPDX-License-Identifier: Apache-2.0 -config CMU_HFXO_FREQ - default 38400000 - -config CMU_LFXO_FREQ - default 32768 - if SOC_GECKO_USE_RAIL config FPU @@ -26,9 +20,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT config REGULATOR diff --git a/boards/silabs/dev_kits/sltb010a/doc/index.rst b/boards/silabs/dev_kits/sltb010a/doc/index.rst index f1ed44facb40e..eb7dcfb24a040 100644 --- a/boards/silabs/dev_kits/sltb010a/doc/index.rst +++ b/boards/silabs/dev_kits/sltb010a/doc/index.rst @@ -63,6 +63,8 @@ The sltb010a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | UART | on-chip | serial | +-----------+------------+-------------------------------------+ +| DMA | on-chip | ldma | ++-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | watchdog | +-----------+------------+-------------------------------------+ | TRNG | on-chip | true random number generator | diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a.dts b/boards/silabs/dev_kits/sltb010a/sltb010a.dts index 994a75007ee02..520d9837d74cd 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a.dts +++ b/boards/silabs/dev_kits/sltb010a/sltb010a.dts @@ -105,6 +105,10 @@ enable-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; }; +&radio { + pa-voltage-mv = <1800>; +}; + &bt_hci_silabs { status = "okay"; }; diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml b/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml index 4de8c502a07ba..fd679198dc93b 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml @@ -7,13 +7,13 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - bluetooth - counter - gpio - uart - i2c + - dma - spi - clock_control vendor: silabs diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml b/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml index 2024a279aeb22..fbd9f8c972445 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml @@ -7,12 +7,12 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - bluetooth - counter - gpio - uart - i2c + - dma - spi vendor: silabs diff --git a/boards/silabs/dev_kits/xg24_dk2601b/Kconfig.defconfig b/boards/silabs/dev_kits/xg24_dk2601b/Kconfig.defconfig index c25c07667bdb2..13cb5b0c77c49 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/Kconfig.defconfig +++ b/boards/silabs/dev_kits/xg24_dk2601b/Kconfig.defconfig @@ -3,16 +3,6 @@ if BOARD_XG24_DK2601B -config CMU_HFXO_FREQ - default 40000000 - -config CMU_LFXO_FREQ - default 32768 - -config FLASH_BASE_ADDRESS - hex - default 0x08000000 - if SOC_GECKO_USE_RAIL config FPU @@ -31,9 +21,6 @@ config COMMON_LIBC_MALLOC_ARENA_SIZE config MAIN_STACK_SIZE default 2304 -config BT_SEND_ECC_EMULATION - default y - if SHELL config SHELL_STACK_SIZE diff --git a/boards/silabs/dev_kits/xg24_dk2601b/doc/index.rst b/boards/silabs/dev_kits/xg24_dk2601b/doc/index.rst index 214ce3b00bcf4..769692c66fe2e 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/doc/index.rst +++ b/boards/silabs/dev_kits/xg24_dk2601b/doc/index.rst @@ -17,7 +17,7 @@ Hardware - Transmit power: up to +20 dBm - Operation frequency: 2.4 GHz - Crystals for LFXO (32.768 kHz) and HFXO (38.4 MHz). -- On board sensors: +- On board devices: - Silicon Labs Si7021 relative humidity & temperature sensor - Silicon Labs Si7210 hall effect sensor @@ -25,6 +25,7 @@ Hardware - TDK InvenSense ICM-20689 6-axis inertial measurement sensor - Vishay VEML6035 ambient light sensor - Bosch BMP384 pressure sensor with internal temperature sensor + - MX25R3235F 32 Mbit SPI data flash For more information about the EFR32MG24 SoC and BRD2601B board, refer to these documents: @@ -39,31 +40,37 @@ Supported Features The board configuration supports the following hardware features: -+-----------+------------+-------------------------------------+ -| Interface | Controller | Driver/Component | -+===========+============+=====================================+ -| MPU | on-chip | memory protection unit | -+-----------+------------+-------------------------------------+ -| NVIC | on-chip | nested vector interrupt controller | -+-----------+------------+-------------------------------------+ -| SYSTICK | on-chip | systick | -+-----------+------------+-------------------------------------+ -| COUNTER | on-chip | stimer | -+-----------+------------+-------------------------------------+ -| FLASH | on-chip | flash memory | -+-----------+------------+-------------------------------------+ -| GPIO | on-chip | gpio | -+-----------+------------+-------------------------------------+ -| UART | on-chip | serial | -+-----------+------------+-------------------------------------+ -| TRNG | on-chip | semailbox | -+-----------+------------+-------------------------------------+ -| WATCHDOG | on-chip | watchdog | -+-----------+------------+-------------------------------------+ -| I2C(M/S) | on-chip | i2c | -+-----------+------------+-------------------------------------+ -| RADIO | on-chip | bluetooth | -+-----------+------------+-------------------------------------+ ++-----------+------------+------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+------------------------------------+ +| SYSRTC | on-chip | counter, timer | ++-----------+------------+------------------------------------+ +| MSC | on-chip | flash memory | ++-----------+------------+------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+------------------------------------+ +| EUSART | on-chip | serial, spi | ++-----------+------------+------------------------------------+ +| USART | on-chip | serial, spi | ++-----------+------------+------------------------------------+ +| LDMA | on-chip | dma | ++-----------+------------+------------------------------------+ +| SE | on-chip | entropy | ++-----------+------------+------------------------------------+ +| WDOG | on-chip | watchdog | ++-----------+------------+------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+------------------------------------+ +| RADIO | on-chip | bluetooth | ++-----------+------------+------------------------------------+ +| ACMP | on-chip | comparator | ++-----------+------------+------------------------------------+ Other hardware features are currently not supported by the port. @@ -71,23 +78,37 @@ Connections and IOs =================== In the following table, the column **Name** contains Pin names. For example, PA2 -means Pin number 2 on PORTA, as used in the board's datasheets and manuals. - -+-------+-------------+-------------------------------------+ -| Name | Function | Usage | -+=======+=============+=====================================+ -| PA4 | GPIO | LED0 | -+-------+-------------+-------------------------------------+ -| PB0 | GPIO | LED1 | -+-------+-------------+-------------------------------------+ -| PB2 | GPIO | Push Button 0 | -+-------+-------------+-------------------------------------+ -| PB3 | GPIO | Push Button 1 | -+-------+-------------+-------------------------------------+ -| PA5 | USART0_TX | UART Console VCOM_TX US0_TX | -+-------+-------------+-------------------------------------+ -| PA6 | USART0_RX | UART Console VCOM_RX US0_RX | -+-------+-------------+-------------------------------------+ +means Pin number 2 on Port A, as used in the board's datasheets and manuals. + ++------+--------------+---------------------+ +| Name | Function | Usage | ++======+==============+=====================+ +| PA4 | GPIO | LED0 | ++------+--------------+---------------------+ +| PB0 | GPIO | LED1 | ++------+--------------+---------------------+ +| PD2 | GPIO | LED2 | ++------+--------------+---------------------+ +| PB2 | GPIO | Push Button 0 | ++------+--------------+---------------------+ +| PB3 | GPIO | Push Button 1 | ++------+--------------+---------------------+ +| PA5 | USART0_TX | UART Console | ++------+--------------+---------------------+ +| PA6 | USART0_RX | UART Console | ++------+--------------+---------------------+ +| PC3 | EUSART1_TX | SPI bus: flash, IMU | ++------+--------------+---------------------+ +| PC2 | EUSART1_RX | SPI bus: flash, IMU | ++------+--------------+---------------------+ +| PC1 | EUSART1_SCLK | SPI bus: flash, IMU | ++------+--------------+---------------------+ +| PC0 | EUSART1_CS | SPI bus: flash | ++------+--------------+---------------------+ +| PC4 | I2C0_SCL | I2C bus | ++------+--------------+---------------------+ +| PC5 | I2C0_SDA | I2C bus | ++------+--------------+---------------------+ The default configuration can be found in :zephyr_file:`boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b_defconfig` @@ -109,7 +130,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -169,6 +190,3 @@ this example. .. _BRD2601B User Guide: https://www.silabs.com/documents/public/user-guides/ug524-brd2601b-user-guide.pdf - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b-pinctrl.dtsi b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b-pinctrl.dtsi index 30aaa4655ba94..9f49a09574495 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b-pinctrl.dtsi +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b-pinctrl.dtsi @@ -20,6 +20,19 @@ }; }; + eusart1_default: eusart1_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + i2c0_default: i2c0_default { group0 { pins = , ; diff --git a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts index 0859df1b3d4d0..0e5713ce9777a 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts @@ -124,6 +124,29 @@ status = "okay"; }; +&eusart1 { + compatible = "silabs,eusart-spi"; + pinctrl-0 = <&eusart1_default>; + pinctrl-names = "default"; + cs-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>; + clock-frequency = <4000000>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + mx25r32: mx25r3235f@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <80000000>; + size = <0x2000000>; + jedec-id = [c2 28 16]; + has-dpd; + dpd-wakeup-sequence = <30000 20 35000>; + mxicy,mx25r-power-mode = "low-power"; + zephyr,pm-device-runtime-auto; + }; +}; + &i2c0 { pinctrl-0 = <&i2c0_default>; pinctrl-names = "default"; @@ -230,6 +253,10 @@ status = "okay"; }; +&radio { + pa-voltage-mv = <1800>; +}; + &bt_hci_silabs { status = "okay"; }; diff --git a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml index 8bfaf749e3291..1682cc6038b67 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml @@ -12,10 +12,12 @@ supported: - counter - gpio - uart + - dma - watchdog - clock_control + - comparator + - adc testing: ignore_tags: - pm - - hwinfo vendor: silabs diff --git a/boards/silabs/dev_kits/xg24_ek2703a/CMakeLists.txt b/boards/silabs/dev_kits/xg24_ek2703a/CMakeLists.txt new file mode 100644 index 0000000000000..2e35c87b81db6 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Norik Systems +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(board.c) diff --git a/boards/silabs/dev_kits/xg24_ek2703a/Kconfig b/boards/silabs/dev_kits/xg24_ek2703a/Kconfig new file mode 100644 index 0000000000000..bcc3f461f6e03 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/Kconfig @@ -0,0 +1,16 @@ +# EFR32XG24 EK2703A board + +# Copyright (c) 2022, Silicon Labs +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_XG24_EK2703A + +config BOARD_XG24_EK2703A + select GPIO + select BOARD_LATE_INIT_HOOK + +module = BOARD_EFR32MG24 +module-str = Board Control +source "subsys/logging/Kconfig.template.log_config" + +endif # BOARD_XG24_EK2703A diff --git a/boards/silabs/dev_kits/xg24_ek2703a/Kconfig.defconfig b/boards/silabs/dev_kits/xg24_ek2703a/Kconfig.defconfig new file mode 100644 index 0000000000000..53290acffd071 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/Kconfig.defconfig @@ -0,0 +1,26 @@ +# Copyright (c) 2021, Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_XG24_EK2703A + +config CMU_HFXO_FREQ + default 39000000 + +config CMU_LFXO_FREQ + default 32768 + +if SOC_GECKO_USE_RAIL + +config FPU + default y + +endif # SOC_GECKO_USE_RAIL + +if BT + +config COMMON_LIBC_MALLOC_ARENA_SIZE + default 8192 + +endif # BT + +endif # BOARD_XG24_EK2703A diff --git a/boards/silabs/dev_kits/xg24_ek2703a/Kconfig.xg24_ek2703a b/boards/silabs/dev_kits/xg24_ek2703a/Kconfig.xg24_ek2703a new file mode 100644 index 0000000000000..275ebeb1f6a85 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/Kconfig.xg24_ek2703a @@ -0,0 +1,5 @@ +# Copyright (c) 2021, Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_XG24_EK2703A + select SOC_PART_NUMBER_EFR32MG24B210F1536IM48 diff --git a/boards/silabs/dev_kits/xg24_ek2703a/board.c b/boards/silabs/dev_kits/xg24_ek2703a/board.c new file mode 100644 index 0000000000000..2ffc7aa210db7 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/board.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(efr32xg24_ek2703a, CONFIG_BOARD_EFR32MG24_LOG_LEVEL); + +void board_late_init_hook(void) +{ + int ret; + + static struct gpio_dt_spec wake_up_gpio_dev = + GPIO_DT_SPEC_GET(DT_NODELABEL(wake_up_trigger), gpios); + + if (!gpio_is_ready_dt(&wake_up_gpio_dev)) { + LOG_ERR("Wake-up GPIO device was not found!\n"); + } + ret = gpio_pin_configure_dt(&wake_up_gpio_dev, GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_ERR("Failed to configure wake-up GPIO!\n"); + } +} diff --git a/boards/silabs/dev_kits/xg24_ek2703a/board.cmake b/boards/silabs/dev_kits/xg24_ek2703a/board.cmake new file mode 100644 index 0000000000000..a39d499a6c2f0 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32MG24BxxxF1536" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +board_runner_args(silabs_commander "--device=EFR32MG24B210F1536IM48") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) diff --git a/boards/silabs/dev_kits/xg24_ek2703a/board.yml b/boards/silabs/dev_kits/xg24_ek2703a/board.yml new file mode 100644 index 0000000000000..7327014ed54b3 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/board.yml @@ -0,0 +1,6 @@ +board: + name: xg24_ek2703a + full_name: EFR32xG24 Explorer Kit (xG24-EK2703A) + vendor: silabs + socs: + - name: efr32mg24b210f1536im48 diff --git a/boards/silabs/dev_kits/xg24_ek2703a/doc/index.rst b/boards/silabs/dev_kits/xg24_ek2703a/doc/index.rst new file mode 100644 index 0000000000000..5161fa1455dde --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/doc/index.rst @@ -0,0 +1,165 @@ +.. zephyr:board:: xg24_ek2703a + +Overview +******** + +The EFR32xG24 Explorer Kit (xG24-EK2703A) contains +a Wireless System-On-Chip from the EFR32MG24 family built on an +ARM CortexÂŽ-M33 processor with excellent low power capabilities. + +Hardware +******** + +- EFR32MG24B210F1536IM48-B Mighty Gecko SoC +- CPU core: ARM CortexÂŽ-M33 with FPU +- Flash memory: 1536 kB +- RAM: 256 kB +- Transmit power: up to +10 dBm +- Operation frequency: 2.4 GHz +- Crystals for LFXO (32.768 kHz) and HFXO (39 MHz). + +For more information about the EFR32MG24 SoC and BRD2703A board, refer to these +documents: + +- `EFR32MG24 Website`_ +- `EFR32MG24 Datasheet`_ +- `EFR32xG24 Reference Manual`_ +- `BRD2703A User Guide`_ + +Supported Features +================== + +The ``xg24_ek2703a`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | stimer | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| TRNG | on-chip | semailbox | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ +| I2C(M/S) | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| RADIO | on-chip | bluetooth | ++-----------+------------+-------------------------------------+ +| ACMP | on-chip | comparator | ++-----------+------------+-------------------------------------+ + +Other hardware features are currently not supported by the port. + +Connections and IOs +=================== + +In the following table, the column **Name** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + ++-------+-------------+-------------------------------------+ +| Name | Function | Usage | ++=======+=============+=====================================+ +| PA4 | GPIO | LED0 | ++-------+-------------+-------------------------------------+ +| PA7 | GPIO | LED1 | ++-------+-------------+-------------------------------------+ +| PB2 | GPIO | Push Button 0 | ++-------+-------------+-------------------------------------+ +| PB3 | GPIO | Push Button 1 | ++-------+-------------+-------------------------------------+ +| PA5 | USART0_TX | UART Console VCOM_TX US0_TX | ++-------+-------------+-------------------------------------+ +| PA6 | USART0_RX | UART Console VCOM_RX US0_RX | ++-------+-------------+-------------------------------------+ + +The default configuration can be found in +:zephyr_file:`boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a_defconfig` + +System Clock +============ + +The EFR32MG24 SoC is configured to use the 39 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32MG24 SoC has one USART and two EUSARTs. +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +.. note:: + Before using the kit the first time, you should update the J-Link firmware + in Simplicity Studio. + +Flashing +======== + +The sample application :zephyr:code-sample:`hello_world` is used for this example. +Build the Zephyr kernel and application: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: xg24_ek2703a + :goals: build + +Connect the xg24_ek2703a to your host computer using the USB port and you +should see a USB connection. + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you'll see the following message on the corresponding serial port +terminal session: + +.. code-block:: console + + Hello World! xg24_ek2703a + +Bluetooth +========= + +To use the BLE function, run the command below to retrieve necessary binary +blobs from the SiLabs HAL repository. + +.. code-block:: console + + west blobs fetch hal_silabs + +Then build the Zephyr kernel and a Bluetooth sample with the following +command. The :zephyr:code-sample:`bluetooth_observer` sample application is used in +this example. + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/observer + :board: xg24_ek2703a + :goals: build + +.. _EFR32MG24 Website: + https://www.silabs.com/wireless/zigbee/efr32mg24-series-2-socs# + +.. _EFR32MG24 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32mg24-datasheet.pdf + +.. _EFR32xG24 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg24-rm.pdf + +.. _BRD2703A User Guide: + https://www.silabs.com/documents/public/user-guides/ug533-xg24-ek2703a.pdf diff --git a/boards/silabs/dev_kits/xg24_ek2703a/dts/bindings/silabs,gecko-wake-up-trigger.yaml b/boards/silabs/dev_kits/xg24_ek2703a/dts/bindings/silabs,gecko-wake-up-trigger.yaml new file mode 100644 index 0000000000000..ba8892f2ce0b2 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/dts/bindings/silabs,gecko-wake-up-trigger.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2022, Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: GPIO Wake Up Trigger for EFR32MG24 + +compatible: "silabs,gecko-wake-up-trigger" + +include: base.yaml + +properties: + gpios: + type: phandle-array + required: true + description: | + GPIO used as wake up trigger from EM4 sleep diff --git a/boards/silabs/dev_kits/xg24_ek2703a/pre_dt_board.cmake b/boards/silabs/dev_kits/xg24_ek2703a/pre_dt_board.cmake new file mode 100644 index 0000000000000..beb76b85552d1 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi new file mode 100644 index 0000000000000..30aaa4655ba94 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + usart0_default: usart0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + i2c0_default: i2c0_default { + group0 { + pins = , ; + drive-open-drain; + bias-pull-up; + }; + }; +}; diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts new file mode 100644 index 0000000000000..a4bf9f857e5f4 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2020 TriaGnoSys GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include "xg24_ek2703a-pinctrl.dtsi" + +/ { + model = "Silicon Labs BRD2703A (xG24 Explorer Kit)"; + compatible = "silabs,xg24_ek2703a", "silabs,efr32mg24"; + + chosen { + zephyr,console = &usart0; + zephyr,shell-uart = &usart0; + zephyr,uart-pipe = &usart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_silabs; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + watchdog0 = &wdog0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpioa 4 GPIO_ACTIVE_LOW>; + }; + led1: led_1 { + gpios = <&gpioa 7 GPIO_ACTIVE_LOW>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpiob 2 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + button1: button_1 { + gpios = <&gpiob 3 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + wake_up_trigger: gpio-wake-up { + compatible = "silabs,gecko-wake-up-trigger"; + gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + }; +}; + +&cpu0 { + clock-frequency = <78000000>; +}; + +&hfxo { + status = "okay"; + ctune = <140>; + precision = <50>; +}; + +&lfxo { + status = "okay"; + ctune = <63>; + precision = <50>; +}; + +&hfrcodpll { + clock-frequency = ; + clocks = <&hfxo>; + dpll-n = <3839>; + dpll-m = <1919>; + dpll-edge = "fall"; + dpll-lock = "phase"; + dpll-autorecover; +}; + +&em23grpaclk { + clocks = <&lfxo>; +}; + +&em4grpaclk { + clocks = <&lfxo>; +}; + +&sysrtcclk { + clocks = <&lfxo>; +}; + +&wdog0clk { + clocks = <&lfxo>; +}; + +&wdog1clk { + clocks = <&lfxo>; +}; + +&usart0 { + current-speed = <115200>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&gpio { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&wdog0 { + status = "okay"; +}; + +&se { + status = "okay"; +}; + +&dcdc { + status = "okay"; + regulator-boot-on; + regulator-initial-mode = ; + silabs,pfmx-peak-current-milliamp = <120>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 48 kB for the bootloader */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 0x0000c000>; + read-only; + }; + + /* Reserve 464 kB for the application in slot 0 */ + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 0x00074000>; + }; + + /* Reserve 464 kB for the application in slot 1 */ + slot1_partition: partition@80000 { + label = "image-1"; + reg = <0x00080000 0x00074000>; + }; + + /* Reserve 32 kB for the scratch partition */ + scratch_partition: partition@f4000 { + label = "image-scratch"; + reg = <0x000f4000 0x00008000>; + }; + + /* Set 528Kb of storage at the end of the 1024Kb of flash */ + storage_partition: partition@fc000 { + label = "storage"; + reg = <0x000fc000 0x00084000>; + }; + }; +}; + +&adc0 { + status = "okay"; +}; + +&sysrtc0 { + status = "okay"; +}; + +&bt_hci_silabs { + status = "okay"; +}; diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml new file mode 100644 index 0000000000000..9a0285d442378 --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml @@ -0,0 +1,21 @@ +identifier: xg24_ek2703a +name: EFR32xG24 Explorer Kit (xG24-EK2703A, BRD2703A) +type: mcu +arch: arm +ram: 256 +flash: 1536 +toolchain: + - zephyr + - gnuarmemb +supported: + - bluetooth + - counter + - gpio + - uart + - watchdog + - clock_control + - comparator +testing: + ignore_tags: + - pm +vendor: silabs diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a_defconfig b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a_defconfig new file mode 100644 index 0000000000000..ea3fbea0c139f --- /dev/null +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a_defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2022 Silicon Labs +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_REGULATOR=y +CONFIG_SOC_GECKO_EMU_DCDC=y +CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y diff --git a/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.defconfig b/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.defconfig index 047c526aad245..fac4f17b12e8e 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.defconfig +++ b/boards/silabs/dev_kits/xg27_dk2602a/Kconfig.defconfig @@ -1,12 +1,6 @@ # Copyright (c) 2023 Antmicro # SPDX-License-Identifier: Apache-2.0 -config CMU_HFXO_FREQ - default 38400000 - -config CMU_LFXO_FREQ - default 32768 - if SOC_GECKO_USE_RAIL config FPU @@ -26,9 +20,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT config REGULATOR diff --git a/boards/silabs/dev_kits/xg27_dk2602a/doc/index.rst b/boards/silabs/dev_kits/xg27_dk2602a/doc/index.rst index cd739beeaedf3..19123e7bf0af4 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/doc/index.rst +++ b/boards/silabs/dev_kits/xg27_dk2602a/doc/index.rst @@ -47,6 +47,10 @@ The xg27_dk2602a board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | UART | on-chip | serial | +-----------+------------+-------------------------------------+ +| DMA | on-chip | ldma | ++-----------+------------+-------------------------------------+ +| ACMP | on-chip | comparator | ++-----------+------------+-------------------------------------+ Flashing ======== diff --git a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts index f201a09e86a8f..7bd14874e9b89 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts @@ -127,6 +127,10 @@ gpios = <&gpiob 3 GPIO_ACTIVE_LOW>; }; +&radio { + pa-voltage-mv = <1800>; +}; + &bt_hci_silabs { status = "okay"; }; diff --git a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml index b725374398e3f..8f8bfd19fb278 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml @@ -7,11 +7,13 @@ flash: 768 toolchain: - zephyr - gnuarmemb - - xtools supported: - bluetooth - counter - gpio - uart + - dma - clock_control + - comparator + - adc vendor: silabs diff --git a/boards/silabs/radio_boards/common/efr32-series1-common.dtsi b/boards/silabs/radio_boards/common/efr32-series1-common.dtsi index 72e771c1b28b9..1a235e498af05 100644 --- a/boards/silabs/radio_boards/common/efr32-series1-common.dtsi +++ b/boards/silabs/radio_boards/common/efr32-series1-common.dtsi @@ -64,7 +64,7 @@ }; &usart1 { - compatible = "silabs,gecko-spi-usart"; + compatible = "silabs,usart-spi"; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/Kconfig.siwx917_rb4338a b/boards/silabs/radio_boards/siwx917_rb4338a/Kconfig.siwx917_rb4338a new file mode 100644 index 0000000000000..a27803e5014ea --- /dev/null +++ b/boards/silabs/radio_boards/siwx917_rb4338a/Kconfig.siwx917_rb4338a @@ -0,0 +1,5 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SIWX917_RB4338A + select SOC_PART_NUMBER_SIWG917M111MGTBA diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/board.cmake b/boards/silabs/radio_boards/siwx917_rb4338a/board.cmake new file mode 100644 index 0000000000000..7b487f2cec89c --- /dev/null +++ b/boards/silabs/radio_boards/siwx917_rb4338a/board.cmake @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(silabs_commander "--device=SiWG917M111GTBA" "--file-type=bin" + "--file=${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}.rps") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) + +# It is not possible to load/flash a firmware using JLink, but it is possible to +# debug a firmware with: +# west attach -r jlink +# Once started, it should be possible to reset the device with "monitor reset" +board_runner_args(jlink "--device=Si917" "--speed=10000") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/board.yml b/boards/silabs/radio_boards/siwx917_rb4338a/board.yml new file mode 100644 index 0000000000000..bf757c06ce34d --- /dev/null +++ b/boards/silabs/radio_boards/siwx917_rb4338a/board.yml @@ -0,0 +1,6 @@ +board: + name: siwx917_rb4338a + full_name: SiWx917 Wi-Fi 6 and Bluetooth LE SoC 8 MB Flash Radio Board (SLWRB4338A) + vendor: silabs + socs: + - name: siwg917m111mgtba diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/doc/index.rst b/boards/silabs/radio_boards/siwx917_rb4338a/doc/index.rst new file mode 100644 index 0000000000000..dd6e4bf8bbb27 --- /dev/null +++ b/boards/silabs/radio_boards/siwx917_rb4338a/doc/index.rst @@ -0,0 +1,116 @@ +.. zephyr:board:: siwx917_rb4338a + + +Overview +******** + +The SiWx917-RB4338A (aka BRD4338A) radio board provides support for the Silicon +Labs SiWG917 SoC. This board cannot be used stand-alone and requires a a +`Wireless Pro Kit`_ Mainboard (Si-MB4002A aka BRD4002A), for power, debug +options etc. + +This board might be sold as a part of the `SiWx917-PK6031A`_ bundle ("SiWx917 +Wi-Fi 6 and Bluetooth LE 8 MB Flash Pro Kit"), which includes the BRD4002A +Mainboard in addition of the BRD4338A. + +SiWG917 is an ultra-low power SoC that includes hardware support for Single-Band +Wi-Fi 6 + Bluetooth LE 5.4, Matter... + +Hardware +******** + +For more information about the SiWG917 SoC and BRD4338A board, refer to these +documents: + +- `SiWG917 Website`_ +- `SiWG917 Datasheet`_ +- `SiWG917 Reference Manual`_ +- `BRD4338A Website`_ +- `BRD4338A User Guide`_ + + +Supported Features +================== + +The ``siwx917_rb4338a`` board supports the following hardware features: + ++-----------+------------+------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+========================+ +| CMU | on-chip | clock control | ++-----------+------------+------------------------+ +| MPU | on-chip | memory protection unit | ++-----------+------------+------------------------+ +| NVIC | on-chip | interrupt controller | ++-----------+------------+------------------------+ +| UART | on-chip | serial | ++-----------+------------+------------------------+ + +Programming and Debugging +************************* + +Flashing +======== + +Applications for the ``siwx917_rb4338a`` board can be built in the usual +way. The flash method requires on `Simplicity Commander`_ installed on the host. + +Then, connect the BRD4002A board with a mounted BRD4338A radio module to your +host computer using the USB port. + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: siwx917_rb4338a + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! siwx917_rb4338a + + +Debugging +========= + +Debuggning relies on JLink tool. JLink is not able to flash the firmware. So +debug session has to be done in two steps. ``west flash`` will flahs the +firmware using Simplicity Commander. Then ``west attach`` will use JLink to +attach to the board. The Zephyr image may has already booted when user runs +``west attach``. User may execute ``monitor reset`` in the gdb prompt to reset +the board. + + + +.. _SiWx917-PK6031A: + https://www.silabs.com/development-tools/wireless/wi-fi/siwx917-pk6031a-wifi-6-bluetooth-le-soc-pro-kit + +.. _Wireless Pro Kit: + https://www.silabs.com/development-tools/wireless/wireless-pro-kit-mainboard + +.. _BRD4338A Website: + https://www.silabs.com/development-tools/wireless/wi-fi/siwx917-rb4338a-wifi-6-bluetooth-le-soc-radio-board + +.. _BRD4338A User Guide: + https://www.silabs.com/documents/public/user-guides/ug562-brd4338a-user-guide.pdf + +.. _SiWG917 Website: + https://www.silabs.com/wireless/wi-fi/siwx917-wireless-socs + +.. _SiWG917 Datasheet: + https://www.silabs.com/documents/public/data-sheets/siw917x-datasheet.pdf + +.. _SiWG917 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/siw917x-family-rm.pdf + +.. _Simplicity Commander: + https://www.silabs.com/developer-tools/simplicity-studio/simplicity-commander diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/doc/siwx917_rb4338a.webp b/boards/silabs/radio_boards/siwx917_rb4338a/doc/siwx917_rb4338a.webp new file mode 100644 index 0000000000000..80bb6f8a3467b Binary files /dev/null and b/boards/silabs/radio_boards/siwx917_rb4338a/doc/siwx917_rb4338a.webp differ diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.dts b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.dts new file mode 100644 index 0000000000000..f650297426c32 --- /dev/null +++ b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.dts @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include +#include + +/ { + model = "Silicon Labs BRD4338A (SiWG917 Radio Board)"; + compatible = "silabs,x917_rb4338a", "silabs,siwg917"; + + chosen { + zephyr,sram = &sram0; + zephyr,code-partition = &code_partition; + zephyr,console = &ulpuart; + zephyr,shell-uart = &ulpuart; + zephyr,bt-hci = &bt_hci0; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + dht0 = &si7021; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&ulpgpio 2 GPIO_ACTIVE_HIGH>; + }; + + led1: led_1 { + gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&uulpgpio 2 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + + button1: button_1 { + gpios = <&gpioa 11 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; +}; + +&pinctrl0 { + ulpuart_default: ulpuart_default { + out { + pinmux = ; + }; + in { + pinmux = ; + }; + }; + + ulpi2c_default: ulpi2c_default { + group { + pinmux = , ; + }; + }; +}; + +&ulpuart { + status = "okay"; + pinctrl-0 = <&ulpuart_default>; + pinctrl-names = "default"; +}; + +&ulpi2c { + status = "okay"; + pinctrl-0 = <&ulpi2c_default>; + pinctrl-names = "default"; + clock-frequency = ; + + si7021: si7021@40 { + compatible = "silabs,si7006"; + reg = <0x40>; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + code_partition: partition@0 { + label = "code_partition"; + reg = <0x0000000 DT_SIZE_K(2048-8)>; + }; + }; +}; + +&bt_hci0 { + status = "okay"; +}; + +&wifi0 { + status = "okay"; +}; diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml new file mode 100644 index 0000000000000..12dd348c93c42 --- /dev/null +++ b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml @@ -0,0 +1,18 @@ +identifier: siwx917_rb4338a +name: SiWx917 Wi-Fi 6 and Bluetooth LE 8MB Flash Radio Board (SLWRB4338A, BRD4338A) +type: mcu +arch: arm +ram: 191 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb +supported: + - bluetooth + - dma + - entropy + - flash + - gpio + - i2c + - wifi +vendor: silabs diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a_defconfig b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a_defconfig new file mode 100644 index 0000000000000..afc7028e3b04a --- /dev/null +++ b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a_defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=180000000 +CONFIG_USE_DT_CODE_PARTITION=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_CLOCK_CONTROL=y diff --git a/boards/silabs/radio_boards/slwrb4104a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4104a/Kconfig.defconfig index da53255b60360..35290c1e5641d 100644 --- a/boards/silabs/radio_boards/slwrb4104a/Kconfig.defconfig +++ b/boards/silabs/radio_boards/slwrb4104a/Kconfig.defconfig @@ -10,10 +10,6 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -config FLASH_BASE_ADDRESS - hex - default 0x0 - config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO @@ -37,9 +33,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT endif # BOARD_SLWRB4104A diff --git a/boards/silabs/radio_boards/slwrb4104a/board.yml b/boards/silabs/radio_boards/slwrb4104a/board.yml index d1122ace33140..65e82240b973e 100644 --- a/boards/silabs/radio_boards/slwrb4104a/board.yml +++ b/boards/silabs/radio_boards/slwrb4104a/board.yml @@ -1,5 +1,6 @@ -boards: - - name: slwrb4104a - full_name: EFR32BG13 2.4 GHz 10 dBm (SLWRB4104A) - socs: - - name: efr32bg13p632f512gm48 +board: + name: slwrb4104a + full_name: EFR32BG13 2.4 GHz 10 dBm (SLWRB4104A) + vendor: silabs + socs: + - name: efr32bg13p632f512gm48 diff --git a/boards/silabs/radio_boards/slwrb4104a/slwrb4104a.yaml b/boards/silabs/radio_boards/slwrb4104a/slwrb4104a.yaml index a407f847f6f77..56a9c32bd4707 100644 --- a/boards/silabs/radio_boards/slwrb4104a/slwrb4104a.yaml +++ b/boards/silabs/radio_boards/slwrb4104a/slwrb4104a.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/silabs/radio_boards/slwrb4161a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4161a/Kconfig.defconfig index e7bfc1885bcb1..a9577b3eac532 100644 --- a/boards/silabs/radio_boards/slwrb4161a/Kconfig.defconfig +++ b/boards/silabs/radio_boards/slwrb4161a/Kconfig.defconfig @@ -10,10 +10,6 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -config FLASH_BASE_ADDRESS - hex - default 0x0 - config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO @@ -37,9 +33,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT endif # BOARD_SLWRB4161A diff --git a/boards/silabs/radio_boards/slwrb4161a/board.yml b/boards/silabs/radio_boards/slwrb4161a/board.yml index fd0c68e48b2a9..4d5fa40b8be30 100644 --- a/boards/silabs/radio_boards/slwrb4161a/board.yml +++ b/boards/silabs/radio_boards/slwrb4161a/board.yml @@ -1,5 +1,6 @@ -boards: - - name: slwrb4161a - full_name: EFR32MG12 2.4 GHz 19 dBm (SLWRB4161A) - socs: - - name: efr32mg12p432f1024gl125 +board: + name: slwrb4161a + full_name: EFR32MG12 2.4 GHz 19 dBm (SLWRB4161A) + vendor: silabs + socs: + - name: efr32mg12p432f1024gl125 diff --git a/boards/silabs/radio_boards/slwrb4161a/slwrb4161a.dts b/boards/silabs/radio_boards/slwrb4161a/slwrb4161a.dts index 9078789829046..2e978e83f4a1d 100644 --- a/boards/silabs/radio_boards/slwrb4161a/slwrb4161a.dts +++ b/boards/silabs/radio_boards/slwrb4161a/slwrb4161a.dts @@ -69,7 +69,7 @@ }; &usart2 { - compatible = "silabs,gecko-spi-usart"; + compatible = "silabs,usart-spi"; #address-cells = <1>; #size-cells = <0>; pinctrl-0 = <&usart2_default>; diff --git a/boards/silabs/radio_boards/slwrb4170a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4170a/Kconfig.defconfig index 34103dcc64132..47f7d487a2526 100644 --- a/boards/silabs/radio_boards/slwrb4170a/Kconfig.defconfig +++ b/boards/silabs/radio_boards/slwrb4170a/Kconfig.defconfig @@ -10,10 +10,6 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -config FLASH_BASE_ADDRESS - hex - default 0x0 - config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO @@ -37,9 +33,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT endif # BOARD_SLWRB4170A diff --git a/boards/silabs/radio_boards/slwrb4170a/board.yml b/boards/silabs/radio_boards/slwrb4170a/board.yml index 5d9fd340d3e0b..63a0445c9bb7f 100644 --- a/boards/silabs/radio_boards/slwrb4170a/board.yml +++ b/boards/silabs/radio_boards/slwrb4170a/board.yml @@ -1,5 +1,6 @@ -boards: - - name: slwrb4170a - full_name: EFR32MG12 2400/868-915 MHz 19 dBm Dual Band (SLWRB4170A) - socs: - - name: efr32mg12p433f1024gm68 +board: + name: slwrb4170a + full_name: EFR32MG12 2400/868-915 MHz 19 dBm Dual Band (SLWRB4170A) + vendor: silabs + socs: + - name: efr32mg12p433f1024gm68 diff --git a/boards/silabs/radio_boards/slwrb4180a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4180a/Kconfig.defconfig index 12d90d4165837..859089bbdffca 100644 --- a/boards/silabs/radio_boards/slwrb4180a/Kconfig.defconfig +++ b/boards/silabs/radio_boards/slwrb4180a/Kconfig.defconfig @@ -4,16 +4,6 @@ if BOARD_SLWRB4180A -config CMU_HFXO_FREQ - default 38400000 - -config CMU_LFXO_FREQ - default 32768 - -config FLASH_BASE_ADDRESS - hex - default 0x0 - config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO @@ -37,9 +27,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT endif # BOARD_SLWRB4180A diff --git a/boards/silabs/radio_boards/slwrb4180a/board.yml b/boards/silabs/radio_boards/slwrb4180a/board.yml index f77ecb3f65b19..d5f3955ba86aa 100644 --- a/boards/silabs/radio_boards/slwrb4180a/board.yml +++ b/boards/silabs/radio_boards/slwrb4180a/board.yml @@ -1,5 +1,6 @@ -boards: - - name: slwrb4180a - full_name: EFR32xG21 2.4 GHz 20 dBm (SLWRB4180A) - socs: - - name: efr32mg21a020f1024im32 +board: + name: slwrb4180a + full_name: EFR32xG21 2.4 GHz 20 dBm (SLWRB4180A) + vendor: silabs + socs: + - name: efr32mg21a020f1024im32 diff --git a/boards/silabs/radio_boards/slwrb4180a/doc/index.rst b/boards/silabs/radio_boards/slwrb4180a/doc/index.rst index 4bdaf37630919..d49a5770e4c5b 100644 --- a/boards/silabs/radio_boards/slwrb4180a/doc/index.rst +++ b/boards/silabs/radio_boards/slwrb4180a/doc/index.rst @@ -56,6 +56,8 @@ The board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | I2C | on-chip | i2c port-polling | +-----------+------------+-------------------------------------+ +| DMA | on-chip | ldma | ++-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | watchdog | +-----------+------------+-------------------------------------+ diff --git a/boards/silabs/radio_boards/slwrb4180a/slwrb4180a.yaml b/boards/silabs/radio_boards/slwrb4180a/slwrb4180a.yaml index 66ff5e7920f88..b359407b9299d 100644 --- a/boards/silabs/radio_boards/slwrb4180a/slwrb4180a.yaml +++ b/boards/silabs/radio_boards/slwrb4180a/slwrb4180a.yaml @@ -7,12 +7,12 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio - nvs - uart + - dma - watchdog testing: ignore_tags: diff --git a/boards/silabs/radio_boards/slwrb4250b/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4250b/Kconfig.defconfig index 812500d7c5cf5..3ac04f0f67124 100644 --- a/boards/silabs/radio_boards/slwrb4250b/Kconfig.defconfig +++ b/boards/silabs/radio_boards/slwrb4250b/Kconfig.defconfig @@ -10,10 +10,6 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -config FLASH_BASE_ADDRESS - hex - default 0x0 - config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO @@ -37,9 +33,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT endif # BOARD_SLWRB4250B diff --git a/boards/silabs/radio_boards/slwrb4250b/board.yml b/boards/silabs/radio_boards/slwrb4250b/board.yml index 052b39f83c308..63de8182fbd55 100644 --- a/boards/silabs/radio_boards/slwrb4250b/board.yml +++ b/boards/silabs/radio_boards/slwrb4250b/board.yml @@ -1,5 +1,6 @@ -boards: - - name: slwrb4250b - full_name: EFR32FG1 2400/868 MHz 13 dBm Dual Band (SLWRB4250B) - socs: - - name: efr32fg1p133f256gm48 +board: + name: slwrb4250b + full_name: EFR32FG1 2400/868 MHz 13 dBm Dual Band (SLWRB4250B) + vendor: silabs + socs: + - name: efr32fg1p133f256gm48 diff --git a/boards/silabs/radio_boards/slwrb4250b/slwrb4250b.yaml b/boards/silabs/radio_boards/slwrb4250b/slwrb4250b.yaml index 699eaf13971d3..0d89f5be4b3df 100644 --- a/boards/silabs/radio_boards/slwrb4250b/slwrb4250b.yaml +++ b/boards/silabs/radio_boards/slwrb4250b/slwrb4250b.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/silabs/radio_boards/slwrb4255a/Kconfig.defconfig b/boards/silabs/radio_boards/slwrb4255a/Kconfig.defconfig index 08070b2f94bab..ffc370954f58e 100644 --- a/boards/silabs/radio_boards/slwrb4255a/Kconfig.defconfig +++ b/boards/silabs/radio_boards/slwrb4255a/Kconfig.defconfig @@ -10,10 +10,6 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -config FLASH_BASE_ADDRESS - hex - default 0x0 - config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO @@ -37,9 +33,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT endif # BOARD_SLWRB4255A diff --git a/boards/silabs/radio_boards/slwrb4255a/board.yml b/boards/silabs/radio_boards/slwrb4255a/board.yml index 841a0858e13f4..b6740ec96859b 100644 --- a/boards/silabs/radio_boards/slwrb4255a/board.yml +++ b/boards/silabs/radio_boards/slwrb4255a/board.yml @@ -1,5 +1,6 @@ -boards: - - name: slwrb4255a - full_name: EFR32FG13 2400/915 MHz 19 dBm Dual Band (SLWRB4255A) - socs: - - name: efr32fg13p233f512gm48 +board: + name: slwrb4255a + full_name: EFR32FG13 2400/915 MHz 19 dBm Dual Band (SLWRB4255A) + vendor: silabs + socs: + - name: efr32fg13p233f512gm48 diff --git a/boards/silabs/radio_boards/slwrb4255a/slwrb4255a.yaml b/boards/silabs/radio_boards/slwrb4255a/slwrb4255a.yaml index 2e5a295ff8e07..116d7acbaf2e1 100644 --- a/boards/silabs/radio_boards/slwrb4255a/slwrb4255a.yaml +++ b/boards/silabs/radio_boards/slwrb4255a/slwrb4255a.yaml @@ -7,7 +7,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/silabs/radio_boards/slwrb4321a/doc/index.rst b/boards/silabs/radio_boards/slwrb4321a/doc/index.rst index 85237f7286ad0..ccd82c5387e3c 100644 --- a/boards/silabs/radio_boards/slwrb4321a/doc/index.rst +++ b/boards/silabs/radio_boards/slwrb4321a/doc/index.rst @@ -112,7 +112,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -172,6 +172,3 @@ terminal session: .. _J-Link: https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.dts b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.dts index a778fbfb18011..e9122db2ab712 100644 --- a/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.dts +++ b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.dts @@ -125,19 +125,19 @@ /* PHY management pins */ location-mdio = ; - location-phy_mdc = ; - location-phy_mdio = ; + location-phy-mdc = ; + location-phy-mdio = ; /* RMII interface pins */ location-rmii = ; - location-rmii_refclk = ; - location-rmii_crs_dv = ; - location-rmii_txd0 = ; - location-rmii_txd1 = ; - location-rmii_tx_en = ; - location-rmii_rxd0 = ; - location-rmii_rxd1 = ; - location-rmii_rx_er = ; + location-rmii-refclk = ; + location-rmii-crs-dv = ; + location-rmii-txd0 = ; + location-rmii-txd1 = ; + location-rmii-tx-en = ; + location-rmii-rxd0 = ; + location-rmii-rxd1 = ; + location-rmii-rx-er = ; status = "okay"; }; diff --git a/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.yaml b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.yaml index b6f05256c98a6..1ddec312c05c0 100644 --- a/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.yaml +++ b/boards/silabs/radio_boards/slwrb4321a/slwrb4321a.yaml @@ -7,7 +7,6 @@ flash: 2048 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - i2c diff --git a/boards/silabs/radio_boards/xg23_rb4210a/Kconfig.defconfig b/boards/silabs/radio_boards/xg23_rb4210a/Kconfig.defconfig new file mode 100644 index 0000000000000..74411aa5622a3 --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/Kconfig.defconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Yishai Jaffe +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_XG23_RB4210A + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if SOC_GECKO_USE_RAIL + +config FPU + default y + +endif # SOC_GECKO_USE_RAIL + +endif # BOARD_XG23_RB4210A diff --git a/boards/silabs/radio_boards/xg23_rb4210a/Kconfig.xg23_rb4210a b/boards/silabs/radio_boards/xg23_rb4210a/Kconfig.xg23_rb4210a new file mode 100644 index 0000000000000..cec62787ad5a3 --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/Kconfig.xg23_rb4210a @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Yishai Jaffe +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_XG23_RB4210A + select SOC_PART_NUMBER_EFR32ZG23B020F512IM48 diff --git a/boards/silabs/radio_boards/xg23_rb4210a/board.cmake b/boards/silabs/radio_boards/xg23_rb4210a/board.cmake new file mode 100644 index 0000000000000..7cbad4e887b54 --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/board.cmake @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32ZG23BxxxF512") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +board_runner_args(openocd) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + +board_runner_args(silabs_commander "--device=EFR32ZG23B020F512IM48") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) diff --git a/boards/silabs/radio_boards/xg23_rb4210a/board.yml b/boards/silabs/radio_boards/xg23_rb4210a/board.yml new file mode 100644 index 0000000000000..42d6b9ff707dd --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/board.yml @@ -0,0 +1,6 @@ +board: + name: xg23_rb4210a + full_name: EFR32xG23 868-915 MHz 20 dBm (xG23-RB4210A) + vendor: silabs + socs: + - name: efr32zg23b020f512im48 diff --git a/boards/silabs/radio_boards/xg23_rb4210a/doc/efr32zg23-xg23-rb4210a.jpg b/boards/silabs/radio_boards/xg23_rb4210a/doc/efr32zg23-xg23-rb4210a.jpg new file mode 100644 index 0000000000000..904a9ae03ac71 Binary files /dev/null and b/boards/silabs/radio_boards/xg23_rb4210a/doc/efr32zg23-xg23-rb4210a.jpg differ diff --git a/boards/silabs/radio_boards/xg23_rb4210a/doc/index.rst b/boards/silabs/radio_boards/xg23_rb4210a/doc/index.rst new file mode 100644 index 0000000000000..b3642243e64af --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/doc/index.rst @@ -0,0 +1,174 @@ +.. zephyr:board:: xg23_rb4210a + +Overview +******** + +The EFR32ZG23 Radio Board is the radio board delivered with +`xG23-PK6068A Website`_. It contains a Wireless System-On-Chip from the +EFR32ZG23 family built on an ARM CortexÂŽ-M33 processor with excellent low +power capabilities. + +The BRD4210A a.k.a. xG23-RB4210A radio board plugs into the Wireless Pro Kit +Mainboard BRD4002A and is supported as one of :ref:`silabs_radio_boards`. + +Hardware +******** + +- EFR32ZG23B020F512IM48 SoC +- CPU core: ARM CortexÂŽ-M33 with FPU +- Flash memory: 512 kB +- RAM: 64 kB +- Transmit power: up to +20 dBm +- Operation frequency: 868-915 MHz +- Crystals for LFXO (32.768 kHz) and HFXO (39 MHz). +- Silicon Labs Si7021 relative humidity and temperature sensor +- Low-power 128x128 pixel Memory LCD +- Macronix ultra low power 8-Mbit SPI flash (MX25R8035F) + +For more information about the EFR32ZG23 SoC and BRD4210A board, refer to these +documents: + +- `EFR32ZG23 Website`_ +- `EFR32ZG23 Datasheet`_ +- `EFR32xG23 Reference Manual`_ +- `xG23-PK6068A Website`_ +- `BRD4210A User Guide`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | stimer | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| DMA | on-chip | ldma | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| TRNG | on-chip | semailbox | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ +| ACMP | on-chip | comparator | ++-----------+------------+-------------------------------------+ + +Other hardware features are currently not supported by the port. + +Connections and IOs +=================== + +In the following table, the column **Name** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + ++-------+-------------+-------------------------------------+ +| Name | Function | Usage | ++=======+=============+=====================================+ +| PA8 | EUSART0_TX | UART Console TX | ++-------+-------------+-------------------------------------+ +| PA9 | EUSART0_RX | UART Console RX | ++-------+-------------+-------------------------------------+ +| PB0 | GPIO | Board Controller Enable | ++-------+-------------+-------------------------------------+ +| PB1 | GPIO | Push Button 0 | ++-------+-------------+-------------------------------------+ +| PB2 | GPIO | LED0 | ++-------+-------------+-------------------------------------+ +| PB3 | GPIO | Push Button 1 | ++-------+-------------+-------------------------------------+ +| PC1 | EUSART1_TX | Display/Flash SPI MOSI | ++-------+-------------+-------------------------------------+ +| PC2 | EUSART1_RX | Flash SPI MISO | ++-------+-------------+-------------------------------------+ +| PC3 | EUSART1_CLK | Display/Flash SPI Clock | ++-------+-------------+-------------------------------------+ +| PC4 | GPIO | Flash SPI Chip Select | ++-------+-------------+-------------------------------------+ +| PC5 | I2C0_SCL | Si7021 I2C Clock | ++-------+-------------+-------------------------------------+ +| PC6 | GPIO | Display COM Inversion | ++-------+-------------+-------------------------------------+ +| PC7 | I2C0_SDA | Si7021 I2C Data | ++-------+-------------+-------------------------------------+ +| PC8 | GPIO | Display SPI Chip Select | ++-------+-------------+-------------------------------------+ +| PC9 | GPIO | Display/Si7021 Enable | ++-------+-------------+-------------------------------------+ +| PD3 | GPIO | LED1 | ++-------+-------------+-------------------------------------+ + +The default configuration can be found in +:zephyr_file:`boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a_defconfig` + +System Clock +============ + +The EFR32ZG23 SoC is configured to use the 39 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32ZG23 SoC has one USART and three EUSARTs. +USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Flashing +======== + +Connect the BRD4002A board with a mounted BRD4210A radio module to your host +computer using the USB port. + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: xg23_rb4210a + :goals: flash + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! xg23_rb4210a/efr32zg23b020f512im48 + + +.. _xG23-PK6068A Website: + https://www.silabs.com/development-tools/wireless/efr32xg23-pro-kit-20-dbm + +.. _BRD4210A User Guide: + https://www.silabs.com/documents/public/user-guides/ug507-brd4210a-user-guide.pdf + +.. _EFR32ZG23 Website: + https://www.silabs.com/wireless/z-wave/800-series-modem-soc + +.. _EFR32ZG23 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32zg23-datasheet.pdf + +.. _EFR32xG23 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg23-rm.pdf diff --git a/boards/silabs/radio_boards/xg23_rb4210a/pre_dt_board.cmake b/boards/silabs/radio_boards/xg23_rb4210a/pre_dt_board.cmake new file mode 100644 index 0000000000000..beb76b85552d1 --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/radio_boards/xg23_rb4210a/support/openocd.cfg b/boards/silabs/radio_boards/xg23_rb4210a/support/openocd.cfg new file mode 100644 index 0000000000000..38409eb70ad79 --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/support/openocd.cfg @@ -0,0 +1,25 @@ +if {[info exists env(OPENOCD_INTERFACE)]} { + set INTERFACE $env(OPENOCD_INTERFACE) +} else { + # By default connect over Debug USB port using the J-Link interface + set INTERFACE "jlink" +} + +source [find interface/$INTERFACE.cfg] + +transport select swd + +set CHIPNAME efr32 + +source [find target/efm32.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a-pinctrl.dtsi b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a-pinctrl.dtsi new file mode 100644 index 0000000000000..c899c0558f8c0 --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a-pinctrl.dtsi @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Yishai Jaffe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + eusart0_default: eusart0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + eusart1_default: eusart1_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + i2c0_default: i2c0_default { + group0 { + pins = , ; + drive-open-drain; + bias-pull-up; + }; + }; +}; diff --git a/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.dts b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.dts new file mode 100644 index 0000000000000..5dc8423e32f6b --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.dts @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2024 Yishai Jaffe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include "xg23_rb4210a-pinctrl.dtsi" + +/ { + model = "Silicon Labs BRD4210A"; + compatible = "silabs,xg23_rb4210a", "silabs,efr32zg23"; + + chosen { + zephyr,console = &eusart0; + zephyr,shell-uart = &eusart0; + zephyr,uart-pipe = &eusart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,display = &ls0xx_ls013b7dh03; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + watchdog0 = &wdog0; + dht0 = &si7021; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpiob 2 GPIO_ACTIVE_HIGH>; + label = "LED 0"; + }; + led1: led_1 { + gpios = <&gpiod 3 GPIO_ACTIVE_HIGH>; + label = "LED 1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpiob 1 GPIO_ACTIVE_LOW>; + label = "User Push Button 0"; + zephyr,code = ; + }; + button1: button_1 { + gpios = <&gpiob 3 GPIO_ACTIVE_LOW>; + label = "User Push Button 1"; + zephyr,code = ; + }; + }; + + sensor_disp_enable: sensor_disp_enable { + compatible = "regulator-fixed"; + regulator-name = "sensor_disp_enable"; + enable-gpios = <&gpioc 9 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&cpu0 { + clock-frequency = <78000000>; +}; + +&pstate_em3 { + status = "disabled"; +}; + +&hfxo { + status = "okay"; + ctune = <106>; + precision = <50>; +}; + +&lfxo { + status = "okay"; + ctune = <38>; + precision = <50>; +}; + +&hfrcodpll { + clock-frequency = ; + clocks = <&hfxo>; + dpll-n = <3839>; + dpll-m = <1919>; + dpll-edge = "fall"; + dpll-lock = "phase"; + dpll-autorecover; +}; + +&em23grpaclk { + clocks = <&lfxo>; +}; + +&em4grpaclk { + clocks = <&lfxo>; +}; + +&sysrtcclk { + clocks = <&lfxo>; +}; + +&wdog0clk { + clocks = <&lfxo>; +}; + +&wdog1clk { + clocks = <&lfxo>; +}; + +&eusart0 { + compatible = "silabs,eusart-uart"; + current-speed = <115200>; + pinctrl-0 = <&eusart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&eusart1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&eusart1_default>; + pinctrl-names = "default"; + cs-gpios = <&gpioc 8 GPIO_ACTIVE_HIGH>, <&gpioc 4 GPIO_ACTIVE_LOW>; + + ls0xx_ls013b7dh03: ls0xx@0 { + compatible = "sharp,ls0xx"; + spi-max-frequency = ; + reg = <0>; + width = <128>; + height = <128>; + extcomin-gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>; + extcomin-frequency = <60>; + disp-en-gpios = <&gpioc 9 GPIO_ACTIVE_HIGH>; + }; + + mx25r80: mx25r8035f@1 { + compatible = "jedec,spi-nor"; + reg = <1>; + spi-max-frequency = ; + size = ; + jedec-id = [c2 28 14]; + has-dpd; + dpd-wakeup-sequence = <30000 20 35000>; + t-enter-dpd = <0>; + mxicy,mx25r-power-mode = "low-power"; + }; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "okay"; + + si7021: si7021@40 { + compatible = "silabs,si7006"; + reg = <0x40>; + vin-supply = <&sensor_disp_enable>; + status = "okay"; + }; +}; + +&gpio { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; + + board-controller-enable { + gpio-hog; + gpios = <0 GPIO_ACTIVE_HIGH>; + output-high; + }; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&wdog0 { + status = "okay"; +}; + +&sysrtc0 { + status = "okay"; +}; + +&se { + status = "okay"; +}; + +&dcdc { + status = "okay"; + regulator-boot-on; + regulator-initial-mode = ; + silabs,pfmx-peak-current-milliamp = <80>; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 48 kB for the bootloader */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(48)>; + read-only; + }; + + /* Reserve 208 kB for the application in slot 0 */ + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 DT_SIZE_K(208)>; + }; + + /* Reserve 208 kB for the application in slot 1 */ + slot1_partition: partition@40000 { + label = "image-1"; + reg = <0x00040000 DT_SIZE_K(208)>; + }; + + /* Reserve 32 kB for the scratch partition */ + scratch_partition: partition@74000 { + label = "image-scratch"; + reg = <0x00074000 DT_SIZE_K(32)>; + }; + + /* Set 16 kB of storage at the end of the 1536 kB of flash */ + storage_partition: partition@7c000 { + label = "storage"; + reg = <0x0007c000 DT_SIZE_K(16)>; + }; + }; +}; diff --git a/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.yaml b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.yaml new file mode 100644 index 0000000000000..1a95532a64fec --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.yaml @@ -0,0 +1,27 @@ +identifier: xg23_rb4210a +name: EFR32xG23 868-915 MHz 20 dBm Radio Board (xG23-RB4210A, BRD4210A) +type: mcu +arch: arm +ram: 64 +flash: 512 +toolchain: + - zephyr + - gnuarmemb +supported: + - clock_control + - counter + - entropy + - flash + - gpio + - i2c + - led + - pinctrl + - spi + - uart + - dma + - watchdog + - comparator +testing: + ignore_tags: + - pm +vendor: silabs diff --git a/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a_defconfig b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a_defconfig new file mode 100644 index 0000000000000..d937f7c3052ba --- /dev/null +++ b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a_defconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_SOC_GECKO_EMU_DCDC=y +CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y diff --git a/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.defconfig b/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.defconfig index 2e8ea4fdeae89..da434eb55ed0c 100644 --- a/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.defconfig +++ b/boards/silabs/radio_boards/xg24_rb4187c/Kconfig.defconfig @@ -4,16 +4,6 @@ if BOARD_XG24_RB4187C -config CMU_HFXO_FREQ - default 39000000 - -config CMU_LFXO_FREQ - default 32768 - -config FLASH_BASE_ADDRESS - hex - default 0x08000000 - config LOG_BACKEND_SWO_FREQ_HZ default 875000 depends on LOG_BACKEND_SWO @@ -37,9 +27,6 @@ config MAIN_STACK_SIZE default 3072 if PM default 2304 -config BT_SEND_ECC_EMULATION - default y - endif # BT endif # BOARD_XG24_RB4187C diff --git a/boards/silabs/radio_boards/xg24_rb4187c/board.yml b/boards/silabs/radio_boards/xg24_rb4187c/board.yml index 3645714223754..d4254a0c42de7 100644 --- a/boards/silabs/radio_boards/xg24_rb4187c/board.yml +++ b/boards/silabs/radio_boards/xg24_rb4187c/board.yml @@ -1,5 +1,6 @@ -boards: - - name: xg24_rb4187c - full_name: EFR32xG24 2.4 GHz 20 dBm (xG24-RB4187C) - socs: - - name: efr32mg24b220f1536im48 +board: + name: xg24_rb4187c + full_name: EFR32xG24 2.4 GHz 20 dBm (xG24-RB4187C) + vendor: silabs + socs: + - name: efr32mg24b220f1536im48 diff --git a/boards/silabs/radio_boards/xg24_rb4187c/doc/index.rst b/boards/silabs/radio_boards/xg24_rb4187c/doc/index.rst index 82804d3e93f29..ac1dfc1f9a2a7 100644 --- a/boards/silabs/radio_boards/xg24_rb4187c/doc/index.rst +++ b/boards/silabs/radio_boards/xg24_rb4187c/doc/index.rst @@ -53,12 +53,16 @@ The board configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | UART | on-chip | serial | +-----------+------------+-------------------------------------+ +| DMA | on-chip | ldma | ++-----------+------------+-------------------------------------+ | I2C | on-chip | i2c | +-----------+------------+-------------------------------------+ | TRNG | on-chip | semailbox | +-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | watchdog | +-----------+------------+-------------------------------------+ +| ACMP | on-chip | comparator | ++-----------+------------+-------------------------------------+ Other hardware features are currently not supported by the port. diff --git a/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml index 3b08119e53742..705f74253c93d 100644 --- a/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml +++ b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml @@ -7,14 +7,14 @@ flash: 1536 toolchain: - zephyr - gnuarmemb - - xtools supported: - bluetooth - gpio - uart + - dma - watchdog + - comparator testing: ignore_tags: - pm - - hwinfo vendor: silabs diff --git a/boards/silabs/radio_boards/xg29_rb4412a/Kconfig.defconfig b/boards/silabs/radio_boards/xg29_rb4412a/Kconfig.defconfig new file mode 100644 index 0000000000000..6004474fc86f6 --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/Kconfig.defconfig @@ -0,0 +1,31 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_XG29_RB4412A + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +if SOC_GECKO_USE_RAIL + +config FPU + default y + +endif # SOC_GECKO_USE_RAIL + +if BT + +config FPU + default y + +config COMMON_LIBC_MALLOC_ARENA_SIZE + default 8192 + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif # BOARD_XG29_RB4412A diff --git a/boards/silabs/radio_boards/xg29_rb4412a/Kconfig.xg29_rb4412a b/boards/silabs/radio_boards/xg29_rb4412a/Kconfig.xg29_rb4412a new file mode 100644 index 0000000000000..a7c877e51b65c --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/Kconfig.xg29_rb4412a @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_XG29_RB4412A + select SOC_PART_NUMBER_EFR32MG29B140F1024IM40 diff --git a/boards/silabs/radio_boards/xg29_rb4412a/board.cmake b/boards/silabs/radio_boards/xg29_rb4412a/board.cmake new file mode 100644 index 0000000000000..f44b8f013fb70 --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32MG29BxxxF1024") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +board_runner_args(silabs_commander "--device=EFR32MG29B140F1024IM40") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) diff --git a/boards/silabs/radio_boards/xg29_rb4412a/board.yml b/boards/silabs/radio_boards/xg29_rb4412a/board.yml new file mode 100644 index 0000000000000..994b5891f0ac5 --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/board.yml @@ -0,0 +1,6 @@ +board: + name: xg29_rb4412a + full_name: EFR32xG29 2.4 GHz 8 dBm Buck (xG29-RB4412A) + vendor: silabs + socs: + - name: efr32mg29b140f1024im40 diff --git a/boards/silabs/radio_boards/xg29_rb4412a/doc/index.rst b/boards/silabs/radio_boards/xg29_rb4412a/doc/index.rst new file mode 100644 index 0000000000000..85d017f32ffb5 --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/doc/index.rst @@ -0,0 +1,114 @@ +.. zephyr:board:: xg29_rb4412a + +Overview +******** + +The xG24-RB4412A radio board provides support for the Silicon Labs EFR32MG29 SoC. + +Hardware +******** + +- EFR32MG29B140F1024IM40 SoC +- CPU core: ARM CortexÂŽ-M33 with FPU +- Flash memory: 1024 kB +- RAM: 256 kB +- Transmit power: up to +8 dBm +- Operation frequency: 2.4 GHz +- Crystal oscillators for LFXO (32.768 kHz) and HFXO (38.4 MHz) + +Supported Features +================== + +The ``xg29_rb4412a`` board target supports the following hardware features: + ++-----------+------------+------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+========================+ +| CMU | on-chip | clock control | ++-----------+------------+------------------------+ +| MSC | on-chip | flash | ++-----------+------------+------------------------+ +| GPIO | on-chip | gpio, pin control | ++-----------+------------+------------------------+ +| RTCC | on-chip | system clock, counter | ++-----------+------------+------------------------+ +| MPU | on-chip | memory protection unit | ++-----------+------------+------------------------+ +| NVIC | on-chip | interrupt controller | ++-----------+------------+------------------------+ +| USART | on-chip | serial, spi | ++-----------+------------+------------------------+ +| EUSART | on-chip | serial, spi | ++-----------+------------+------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+------------------------+ +| LDMA | on-chip | dma | ++-----------+------------+------------------------+ +| WDOG | on-chip | watchdog | ++-----------+------------+------------------------+ +| SE | on-chip | entropy | ++-----------+------------+------------------------+ +| RADIO | on-chip | bluetooth | ++-----------+------------+------------------------+ +| ACMP | on-chip | comparator | ++-----------+------------+------------------------+ + +Programming and Debugging +************************* + +Applications for the ``xg29_rb4412a`` board target can be built, flashed, and debugged in the +usual way. See :ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +Flashing +======== + +As an example, this section shows how to build and flash the :zephyr:code-sample:`hello_world` +application. + +To build and program the sample to the xG24-RB4412A, complete the following steps: + +First, plug the xG24-RB4412A to a compatible mainboard and connect the mainboard to your computer +using the USB port on the left side. +Next, build and flash the sample by running the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: xg29_rb4412a + :goals: build flash + +``west flash`` will by default use SEGGER JLink. Make sure that the JLinkExe binary is available on +the PATH. Alternatively, use ``west flash -r silabs_commander`` to use Simplicity Commander to flash. +In this case, make sure that the commander binary is available on PATH. + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should see the following message in the terminal: + +.. code-block:: console + + Hello World! xg29_rb4412a + +Bluetooth +========= + +To use the BLE function, run the command below to retrieve necessary binary +blobs from the SiLabs HAL repository. + +.. code-block:: console + + west blobs fetch hal_silabs + +Then build the Zephyr kernel and a Bluetooth sample with the following +command. The :zephyr:code-sample:`bluetooth_observer` sample application is used in +this example. + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/observer + :board: xg29_rb4412a + :goals: build diff --git a/boards/silabs/radio_boards/xg29_rb4412a/pre_dt_board.cmake b/boards/silabs/radio_boards/xg29_rb4412a/pre_dt_board.cmake new file mode 100644 index 0000000000000..66dcd771b3e83 --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart/eusart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a-pinctrl.dtsi b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a-pinctrl.dtsi new file mode 100644 index 0000000000000..1acb655711189 --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a-pinctrl.dtsi @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + usart1_default: usart1_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + eusart1_default: eusart1_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + i2c0_default: i2c0_default { + group0 { + pins = , ; + drive-open-drain; + bias-pull-up; + }; + }; +}; diff --git a/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.dts b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.dts new file mode 100644 index 0000000000000..c96235a5082e7 --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.dts @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include "xg29_rb4412a-pinctrl.dtsi" + +/ { + model = "Silicon Labs xG29-RB4412A"; + compatible = "silabs,xg29_rb4412a", "silabs,efr32mg29"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,uart-pipe = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &bt_hci_silabs; + zephyr,display = &ls013b7dh03; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &button0; + sw1 = &button1; + watchdog0 = &wdog0; + spi-flash0 = &mx25r80; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; + label = "LED 0"; + }; + + led1: led_1 { + gpios = <&gpiob 1 GPIO_ACTIVE_LOW>; + label = "LED 1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; + label = "User Push Button 0"; + zephyr,code = ; + }; + + button1: button_1 { + gpios = <&gpiob 1 GPIO_ACTIVE_LOW>; + label = "User Push Button 1"; + zephyr,code = ; + }; + }; + + display_enable: sensor_enable: gpio_switch_0 { + compatible = "regulator-fixed"; + regulator-name = "sensor_enable"; + enable-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>; + }; +}; + +&cpu0 { + clock-frequency = <76800000>; +}; + +&hfxo { + status = "okay"; + ctune = <140>; + precision = <50>; +}; + +&lfxo { + status = "okay"; + ctune = <63>; + precision = <50>; +}; + +&hfrcodpll { + clock-frequency = ; + clocks = <&hfxo>; + dpll-n = <3839>; + dpll-m = <1919>; + dpll-edge = "fall"; + dpll-lock = "phase"; + dpll-autorecover; +}; + +&em23grpaclk { + clocks = <&lfxo>; +}; + +&em4grpaclk { + clocks = <&lfxo>; +}; + +&rtccclk { + clocks = <&lfxo>; +}; + +&wdog0clk { + clocks = <&lfxo>; +}; + +&usart1 { + current-speed = <115200>; + pinctrl-0 = <&usart1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "okay"; + + si7021: si7021@40 { + compatible = "silabs,si7006"; + reg = <0x40>; + status = "okay"; + }; +}; + +&eusart1 { + pinctrl-0 = <&eusart1_default>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + cs-gpios = <&gpioa 4 GPIO_ACTIVE_LOW>, <&gpioc 6 GPIO_ACTIVE_HIGH>; + + mx25r80: mx25r8035f@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = ; + size = <0x800000>; + jedec-id = [c2 28 14]; + has-dpd; + dpd-wakeup-sequence = <30000 20 35000>; + t-enter-dpd = <0>; + mxicy,mx25r-power-mode = "low-power"; + }; + + ls013b7dh03: ls0xx@1 { + compatible = "sharp,ls0xx"; + spi-max-frequency = ; + reg = <1>; + width = <128>; + height = <128>; + extcomin-gpios = <&gpiod 2 GPIO_ACTIVE_HIGH>; + extcomin-frequency = <60>; + }; +}; + +&gpio { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; + + vcom-enable { + gpio-hog; + gpios = <4 GPIO_ACTIVE_HIGH>; + output-high; + }; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&wdog0 { + status = "okay"; +}; + +&rtcc0 { + status = "okay"; +}; + +&se { + status = "okay"; +}; + +&dcdc { + status = "okay"; + regulator-boot-on; + regulator-initial-mode = ; +}; + +&radio { + pa-voltage-mv = <1800>; +}; + +&bt_hci_silabs { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(48)>; + }; + + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 DT_SIZE_K(472)>; + }; + + slot1_partition: partition@82000 { + label = "image-1"; + reg = <0x00082000 DT_SIZE_K(472)>; + }; + + storage_partition: partition@F8000 { + label = "storage"; + reg = <0x000F8000 DT_SIZE_K(32)>; + }; + }; +}; diff --git a/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.yaml b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.yaml new file mode 100644 index 0000000000000..c829c215fa9b1 --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.yaml @@ -0,0 +1,20 @@ +identifier: xg29_rb4412a +name: EFR32xG29 2.4 GHz 8 dBm Buck Radio Board (xG29-RB4412A, BRD4412A) +type: mcu +arch: arm +ram: 256 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb +supported: + - bluetooth + - gpio + - uart + - dma + - watchdog + - comparator +testing: + ignore_tags: + - pm +vendor: silabs diff --git a/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a_defconfig b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a_defconfig new file mode 100644 index 0000000000000..e70f8f5c5197d --- /dev/null +++ b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a_defconfig @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y diff --git a/boards/silabs/starter_kits/efm32wg_stk3800/doc/index.rst b/boards/silabs/starter_kits/efm32wg_stk3800/doc/index.rst index d78df5eaaf1c0..e8f4b9e432a03 100644 --- a/boards/silabs/starter_kits/efm32wg_stk3800/doc/index.rst +++ b/boards/silabs/starter_kits/efm32wg_stk3800/doc/index.rst @@ -99,7 +99,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -162,6 +162,3 @@ the following message: .. _J-Link: https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.yaml b/boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.yaml index 46f0a60822a69..2c55d747297fb 100644 --- a/boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.yaml +++ b/boards/silabs/starter_kits/efm32wg_stk3800/efm32wg_stk3800.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - nvs diff --git a/boards/silabs/starter_kits/slstk3400a/Kconfig.defconfig b/boards/silabs/starter_kits/slstk3400a/Kconfig.defconfig index 7c867fdd8e4e5..4839c7bf7cbce 100644 --- a/boards/silabs/starter_kits/slstk3400a/Kconfig.defconfig +++ b/boards/silabs/starter_kits/slstk3400a/Kconfig.defconfig @@ -9,4 +9,15 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 +# Kernel Options due to Low Memory (8k) + +configdefault MAIN_STACK_SIZE + default 640 + +configdefault IDLE_STACK_SIZE + default 200 + +configdefault ISR_STACK_SIZE + default 512 + endif # BOARD_SLSTK3400A diff --git a/boards/silabs/starter_kits/slstk3400a/doc/index.rst b/boards/silabs/starter_kits/slstk3400a/doc/index.rst index f3e3f6314c564..9178651500801 100644 --- a/boards/silabs/starter_kits/slstk3400a/doc/index.rst +++ b/boards/silabs/starter_kits/slstk3400a/doc/index.rst @@ -100,7 +100,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -162,6 +162,3 @@ Reset the board and you will see this message written to the serial port: .. _J-Link: https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/starter_kits/slstk3400a/slstk3400a.yaml b/boards/silabs/starter_kits/slstk3400a/slstk3400a.yaml index e3bb4628be03e..28438025a425d 100644 --- a/boards/silabs/starter_kits/slstk3400a/slstk3400a.yaml +++ b/boards/silabs/starter_kits/slstk3400a/slstk3400a.yaml @@ -7,7 +7,6 @@ flash: 64 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - nvs diff --git a/boards/silabs/starter_kits/slstk3400a/slstk3400a_defconfig b/boards/silabs/starter_kits/slstk3400a/slstk3400a_defconfig index 957fedcc584da..48429f2f899f5 100644 --- a/boards/silabs/starter_kits/slstk3400a/slstk3400a_defconfig +++ b/boards/silabs/starter_kits/slstk3400a/slstk3400a_defconfig @@ -6,8 +6,3 @@ CONFIG_SERIAL=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=24000000 CONFIG_CMU_HFCLK_HFXO=y - -# Kernel Options due to Low Memory (8k) -CONFIG_MAIN_STACK_SIZE=640 -CONFIG_IDLE_STACK_SIZE=200 -CONFIG_ISR_STACK_SIZE=512 diff --git a/boards/silabs/starter_kits/slstk3401a/doc/index.rst b/boards/silabs/starter_kits/slstk3401a/doc/index.rst index 0508a5894757b..8e5fa5fb1eeec 100644 --- a/boards/silabs/starter_kits/slstk3401a/doc/index.rst +++ b/boards/silabs/starter_kits/slstk3401a/doc/index.rst @@ -111,7 +111,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -174,6 +174,3 @@ terminal session: .. _J-Link: https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/starter_kits/slstk3401a/slstk3401a.yaml b/boards/silabs/starter_kits/slstk3401a/slstk3401a.yaml index a7de8915c225b..6de92764e9161 100644 --- a/boards/silabs/starter_kits/slstk3401a/slstk3401a.yaml +++ b/boards/silabs/starter_kits/slstk3401a/slstk3401a.yaml @@ -7,7 +7,6 @@ flash: 256 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - gpio diff --git a/boards/silabs/starter_kits/slstk3402a/doc/index.rst b/boards/silabs/starter_kits/slstk3402a/doc/index.rst index f0dbd560fb396..3470e9e670157 100644 --- a/boards/silabs/starter_kits/slstk3402a/doc/index.rst +++ b/boards/silabs/starter_kits/slstk3402a/doc/index.rst @@ -134,7 +134,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -200,6 +200,3 @@ terminal session: .. _J-Link: https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.yaml b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.yaml index 552699ed84a6c..5230f2a6a8226 100644 --- a/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.yaml +++ b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32jg12b500f1024gl125.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - gpio diff --git a/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.yaml b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.yaml index 8274823adfa2b..60aee6d99e11c 100644 --- a/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.yaml +++ b/boards/silabs/starter_kits/slstk3402a/slstk3402a_efm32pg12b500f1024gl125.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - gpio diff --git a/boards/silabs/starter_kits/slstk3701a/doc/index.rst b/boards/silabs/starter_kits/slstk3701a/doc/index.rst index fcde5ddd21876..d63c3f3844b3d 100644 --- a/boards/silabs/starter_kits/slstk3701a/doc/index.rst +++ b/boards/silabs/starter_kits/slstk3701a/doc/index.rst @@ -123,7 +123,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -186,6 +186,3 @@ terminal session: .. _J-Link: https://www.segger.com/jlink-debug-probes.html - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/silabs/starter_kits/slstk3701a/slstk3701a.dts b/boards/silabs/starter_kits/slstk3701a/slstk3701a.dts index 331a21637180a..64a656bb723fb 100644 --- a/boards/silabs/starter_kits/slstk3701a/slstk3701a.dts +++ b/boards/silabs/starter_kits/slstk3701a/slstk3701a.dts @@ -156,19 +156,19 @@ /* PHY management pins */ location-mdio = ; - location-phy_mdc = ; - location-phy_mdio = ; + location-phy-mdc = ; + location-phy-mdio = ; /* RMII interface pins */ location-rmii = ; - location-rmii_refclk = ; - location-rmii_crs_dv = ; - location-rmii_txd0 = ; - location-rmii_txd1 = ; - location-rmii_tx_en = ; - location-rmii_rxd0 = ; - location-rmii_rxd1 = ; - location-rmii_rx_er = ; + location-rmii-refclk = ; + location-rmii-crs-dv = ; + location-rmii-txd0 = ; + location-rmii-txd1 = ; + location-rmii-tx-en = ; + location-rmii-rxd0 = ; + location-rmii-rxd1 = ; + location-rmii-rx-er = ; status = "okay"; }; diff --git a/boards/silabs/starter_kits/slstk3701a/slstk3701a.yaml b/boards/silabs/starter_kits/slstk3701a/slstk3701a.yaml index 2c9a0d812cdd4..9ee9e8746ad0e 100644 --- a/boards/silabs/starter_kits/slstk3701a/slstk3701a.yaml +++ b/boards/silabs/starter_kits/slstk3701a/slstk3701a.yaml @@ -7,7 +7,6 @@ flash: 2048 toolchain: - zephyr - gnuarmemb - - xtools supported: - i2c - gpio diff --git a/boards/sipeed/longan_nano/longan_nano.yaml b/boards/sipeed/longan_nano/longan_nano.yaml index aebc7291fb85c..2289d7ad3b47b 100644 --- a/boards/sipeed/longan_nano/longan_nano.yaml +++ b/boards/sipeed/longan_nano/longan_nano.yaml @@ -4,7 +4,6 @@ type: mcu arch: riscv toolchain: - zephyr - - xtools flash: 128 ram: 32 supported: diff --git a/boards/sipeed/longan_nano/longan_nano_gd32vf103_lite.yaml b/boards/sipeed/longan_nano/longan_nano_gd32vf103_lite.yaml index 27636b6d47ec6..f12b097090214 100644 --- a/boards/sipeed/longan_nano/longan_nano_gd32vf103_lite.yaml +++ b/boards/sipeed/longan_nano/longan_nano_gd32vf103_lite.yaml @@ -4,7 +4,6 @@ type: mcu arch: riscv toolchain: - zephyr - - xtools flash: 64 ram: 20 supported: diff --git a/boards/snps/em_starterkit/em_starterkit_emsk_em11d.yaml b/boards/snps/em_starterkit/em_starterkit_emsk_em11d.yaml index 3189656c78f7a..65ec248abf2a1 100644 --- a/boards/snps/em_starterkit/em_starterkit_emsk_em11d.yaml +++ b/boards/snps/em_starterkit/em_starterkit_emsk_em11d.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools supported: - i2c - spi diff --git a/boards/snps/em_starterkit/em_starterkit_emsk_em7d.yaml b/boards/snps/em_starterkit/em_starterkit_emsk_em7d.yaml index fe2276e2d738f..9a37326ce9bbe 100644 --- a/boards/snps/em_starterkit/em_starterkit_emsk_em7d.yaml +++ b/boards/snps/em_starterkit/em_starterkit_emsk_em7d.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools supported: - i2c - spi diff --git a/boards/snps/em_starterkit/em_starterkit_emsk_em7d_2_2.yaml b/boards/snps/em_starterkit/em_starterkit_emsk_em7d_2_2.yaml index 29f4404ca9517..9baa05d0cf96a 100644 --- a/boards/snps/em_starterkit/em_starterkit_emsk_em7d_2_2.yaml +++ b/boards/snps/em_starterkit/em_starterkit_emsk_em7d_2_2.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools supported: - i2c - spi diff --git a/boards/snps/em_starterkit/em_starterkit_emsk_em9d.yaml b/boards/snps/em_starterkit/em_starterkit_emsk_em9d.yaml index 34b10ca6d7b27..e60017820fdba 100644 --- a/boards/snps/em_starterkit/em_starterkit_emsk_em9d.yaml +++ b/boards/snps/em_starterkit/em_starterkit_emsk_em9d.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools supported: - i2c - spi diff --git a/boards/snps/em_starterkit/em_starterkit_r23.dtsi b/boards/snps/em_starterkit/em_starterkit_r23.dtsi index ef93abcfd46d3..16236f315b7e3 100644 --- a/boards/snps/em_starterkit/em_starterkit_r23.dtsi +++ b/boards/snps/em_starterkit/em_starterkit_r23.dtsi @@ -34,9 +34,9 @@ compatible = "snps,creg-gpio"; reg = <0xf0000014 0x4>; ngpios = <6>; - bit_per_gpio = <1>; - off_val = <0>; - on_val = <1>; + bit-per-gpio = <1>; + off-val = <0>; + on-val = <1>; gpio-controller; #gpio-cells = <2>; diff --git a/boards/snps/emsdp/emsdp_emsdp_em11d.yaml b/boards/snps/emsdp/emsdp_emsdp_em11d.yaml index b9c1868a133a0..1f30455891d6a 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em11d.yaml +++ b/boards/snps/emsdp/emsdp_emsdp_em11d.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools ram: 128 supported: - spi diff --git a/boards/snps/emsdp/emsdp_emsdp_em11d_defconfig b/boards/snps/emsdp/emsdp_emsdp_em11d_defconfig index aa1c99186616d..1cbd8610dbb15 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em11d_defconfig +++ b/boards/snps/emsdp/emsdp_emsdp_em11d_defconfig @@ -12,4 +12,3 @@ CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_ARC_MPU_ENABLE=y CONFIG_GPIO=y CONFIG_SPI=y -CONFIG_PINCTRL=y diff --git a/boards/snps/emsdp/emsdp_emsdp_em4.yaml b/boards/snps/emsdp/emsdp_emsdp_em4.yaml index 96f05b3251ff0..12549b4017625 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em4.yaml +++ b/boards/snps/emsdp/emsdp_emsdp_em4.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools ram: 128 testing: ignore_tags: diff --git a/boards/snps/emsdp/emsdp_emsdp_em5d.yaml b/boards/snps/emsdp/emsdp_emsdp_em5d.yaml index 91f3c1d1c4e56..dfc2b08779320 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em5d.yaml +++ b/boards/snps/emsdp/emsdp_emsdp_em5d.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools ram: 128 testing: ignore_tags: diff --git a/boards/snps/emsdp/emsdp_emsdp_em6.yaml b/boards/snps/emsdp/emsdp_emsdp_em6.yaml index 0c74c5b7c2144..643d08876a1e3 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em6.yaml +++ b/boards/snps/emsdp/emsdp_emsdp_em6.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools ram: 128 supported: - spi diff --git a/boards/snps/emsdp/emsdp_emsdp_em7d.yaml b/boards/snps/emsdp/emsdp_emsdp_em7d.yaml index 94dfbdd2af055..6ec11b101c2c1 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em7d.yaml +++ b/boards/snps/emsdp/emsdp_emsdp_em7d.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools ram: 128 testing: ignore_tags: diff --git a/boards/snps/emsdp/emsdp_emsdp_em7d_esp.yaml b/boards/snps/emsdp/emsdp_emsdp_em7d_esp.yaml index fcbc5e24c74cd..f0126cc2b4c73 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em7d_esp.yaml +++ b/boards/snps/emsdp/emsdp_emsdp_em7d_esp.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools ram: 128 supported: - spi diff --git a/boards/snps/emsdp/emsdp_emsdp_em9d.yaml b/boards/snps/emsdp/emsdp_emsdp_em9d.yaml index e22e8d3709214..8a7e40aa827e8 100644 --- a/boards/snps/emsdp/emsdp_emsdp_em9d.yaml +++ b/boards/snps/emsdp/emsdp_emsdp_em9d.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools ram: 128 supported: - spi diff --git a/boards/snps/hsdk/hsdk.yaml b/boards/snps/hsdk/hsdk.yaml index 3547f1a313bf2..7a63a47ee6796 100644 --- a/boards/snps/hsdk/hsdk.yaml +++ b/boards/snps/hsdk/hsdk.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools - arcmwdt supported: - smp diff --git a/boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml b/boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml index 24c50b0b91828..b4bd8f19f5d3a 100644 --- a/boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml +++ b/boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools - arcmwdt supported: - smp diff --git a/boards/snps/hsdk4xd/hsdk4xd.yaml b/boards/snps/hsdk4xd/hsdk4xd.yaml index 798d7be5f2b8e..8cc50a8db6b6c 100644 --- a/boards/snps/hsdk4xd/hsdk4xd.yaml +++ b/boards/snps/hsdk4xd/hsdk4xd.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools - arcmwdt supported: - smp diff --git a/boards/snps/iotdk/iotdk.yaml b/boards/snps/iotdk/iotdk.yaml index 5ec9fdc8d15cf..9de77e5c1a716 100644 --- a/boards/snps/iotdk/iotdk.yaml +++ b/boards/snps/iotdk/iotdk.yaml @@ -5,7 +5,6 @@ arch: arc toolchain: - zephyr - cross-compile - - xtools ram: 128 testing: ignore_tags: diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22.dts b/boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22.dts index 4b52355589a46..ef9791ff0d766 100644 --- a/boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22.dts +++ b/boards/snps/nsim/arc_classic/nsim_nsim_em7d_v22.dts @@ -6,6 +6,9 @@ /dts-v1/; +#define ICCM_SIZE DT_SIZE_K(256) +#define DCCM_SIZE DT_SIZE_K(128) + #include "nsim_em.dtsi" / { diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_sem.dts b/boards/snps/nsim/arc_classic/nsim_nsim_sem.dts index de118195e3efe..807d54ba6981b 100644 --- a/boards/snps/nsim/arc_classic/nsim_nsim_sem.dts +++ b/boards/snps/nsim/arc_classic/nsim_nsim_sem.dts @@ -4,27 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ - /dts-v1/; +#define ICCM_SIZE DT_SIZE_K(256) +#define DCCM_SIZE DT_SIZE_K(256) + #include "nsim_em-sec.dtsi" / { - - model = "nsim_sem"; + model = "snps,nsim_sem"; compatible = "snps,nsim_sem"; - - iccm0: iccm@0 { - compatible = "arc,iccm"; - reg = <0x0 0x40000>; - }; - - dccm0: dccm@80000000 { - compatible = "arc,dccm"; - reg = <0x80000000 0x40000>; - }; - - chosen { - zephyr,sram = &dccm0; - }; }; diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_sem.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_sem.yaml index 53631e7d5fbd2..cc114d849af60 100644 --- a/boards/snps/nsim/arc_classic/nsim_nsim_sem.yaml +++ b/boards/snps/nsim/arc_classic/nsim_nsim_sem.yaml @@ -1,5 +1,5 @@ identifier: nsim/nsim_sem -name: SEM Nsim simulator +name: SEM nSIM simulator type: sim arch: arc simulation: diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard.dts b/boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard.dts index 4b1c02279c70c..a5d01055853e5 100644 --- a/boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard.dts +++ b/boards/snps/nsim/arc_classic/nsim_nsim_sem_mpu_stack_guard.dts @@ -6,9 +6,12 @@ /dts-v1/; +#define ICCM_SIZE DT_SIZE_K(512) +#define DCCM_SIZE DT_SIZE_K(512) + #include "nsim_em-sec.dtsi" / { - model = "snps,nsim_sem_mpu_stack_guard"; - compatible = "snps,nsim_sem_mpu_stack_guard.dts"; + model = "snps,nsim_sem"; + compatible = "snps,nsim_sem"; }; diff --git a/boards/snps/nsim/arc_classic/support/mdb_em7d_v22.args b/boards/snps/nsim/arc_classic/support/mdb_em7d_v22.args index ea1fa9efbfe8e..e827823df823f 100644 --- a/boards/snps/nsim/arc_classic/support/mdb_em7d_v22.args +++ b/boards/snps/nsim/arc_classic/support/mdb_em7d_v22.args @@ -38,10 +38,10 @@ -dcache_feature=2 -icache=16384,32,2,a -icache_feature=2 - -dccm_size=0x80000 + -dccm_size=0x20000 -dccm_base=0x80000000 -dccm_interleave - -iccm0_size=0x80000 + -iccm0_size=0x40000 -iccm0_base=0x00000000 -Xpct_counters=8 -dmac diff --git a/boards/snps/nsim/arc_classic/support/mdb_hs.args b/boards/snps/nsim/arc_classic/support/mdb_hs.args index b53cdd6922107..9b513b6000e01 100644 --- a/boards/snps/nsim/arc_classic/support/mdb_hs.args +++ b/boards/snps/nsim/arc_classic/support/mdb_hs.args @@ -34,11 +34,11 @@ -dcache_mem_cycles=2 -icache=65536,64,4,a -icache_feature=2 - -dccm_size=0x40000 + -dccm_size=0x100000 -dccm_base=0x80000000 -dccm_mem_cycles=2 - -iccm0_size=0x40000 - -iccm0_base=0x70000000 + -iccm0_size=0x100000 + -iccm0_base=0x00000000 -mpuv3 -mpu_regions=16 -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 diff --git a/boards/snps/nsim/arc_classic/support/mdb_hs_hostlink.args b/boards/snps/nsim/arc_classic/support/mdb_hs_hostlink.args index 322ab33998aab..2676357f3d05d 100644 --- a/boards/snps/nsim/arc_classic/support/mdb_hs_hostlink.args +++ b/boards/snps/nsim/arc_classic/support/mdb_hs_hostlink.args @@ -34,11 +34,11 @@ -dcache_mem_cycles=2 -icache=65536,64,4,a -icache_feature=2 - -dccm_size=0x40000 + -dccm_size=0x100000 -dccm_base=0x80000000 -dccm_mem_cycles=2 - -iccm0_size=0x40000 - -iccm0_base=0x70000000 + -iccm0_size=0x100000 + -iccm0_base=0x00000000 -mpuv3 -mpu_regions=16 -noprofile diff --git a/boards/snps/nsim/arc_classic/support/mdb_hs_mpuv6.args b/boards/snps/nsim/arc_classic/support/mdb_hs_mpuv6.args index 5f7a5a98e692a..64c68a917cd21 100644 --- a/boards/snps/nsim/arc_classic/support/mdb_hs_mpuv6.args +++ b/boards/snps/nsim/arc_classic/support/mdb_hs_mpuv6.args @@ -39,7 +39,7 @@ -dccm_size=0x100000 -dccm_base=0x80000000 -dccm_mem_cycles=2 - -iccm0_size=0x40000 - -iccm0_base=0x70000000 + -iccm0_size=0x100000 + -iccm0_base=0x00000000 -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 -noprofile diff --git a/boards/snps/nsim/arc_classic/support/nsim_hs.props b/boards/snps/nsim/arc_classic/support/nsim_hs.props index 56eb627e67038..6482a379a0d4a 100644 --- a/boards/snps/nsim/arc_classic/support/nsim_hs.props +++ b/boards/snps/nsim/arc_classic/support/nsim_hs.props @@ -41,8 +41,8 @@ dccm_size=0x100000 dccm_base=0x80000000 nsim_isa_dccm_mem_cycles=2 - iccm0_size=0x40000 - iccm0_base=0x70000000 + iccm0_size=0x100000 + iccm0_base=0x00000000 mpu_regions=16 mpu_version=3 nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 diff --git a/boards/snps/nsim/arc_classic/support/nsim_hs_hostlink.props b/boards/snps/nsim/arc_classic/support/nsim_hs_hostlink.props index 9c96ba18083e5..c1afff58cf269 100644 --- a/boards/snps/nsim/arc_classic/support/nsim_hs_hostlink.props +++ b/boards/snps/nsim/arc_classic/support/nsim_hs_hostlink.props @@ -41,7 +41,7 @@ dccm_size=0x100000 dccm_base=0x80000000 nsim_isa_dccm_mem_cycles=2 - iccm0_size=0x40000 - iccm0_base=0x70000000 + iccm0_size=0x100000 + iccm0_base=0x00000000 mpu_regions=16 mpu_version=3 diff --git a/boards/snps/nsim/arc_classic/support/nsim_hs_mpuv6.props b/boards/snps/nsim/arc_classic/support/nsim_hs_mpuv6.props index 9556ec1105e0f..faa3b7f4163ed 100644 --- a/boards/snps/nsim/arc_classic/support/nsim_hs_mpuv6.props +++ b/boards/snps/nsim/arc_classic/support/nsim_hs_mpuv6.props @@ -43,6 +43,6 @@ dccm_size=0x100000 dccm_base=0x80000000 nsim_isa_dccm_mem_cycles=2 - iccm0_size=0x40000 - iccm0_base=0x70000000 + iccm0_size=0x100000 + iccm0_base=0x00000000 nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 diff --git a/boards/snps/nsim/arc_v/rmx1xx.dtsi b/boards/snps/nsim/arc_v/rmx1xx.dtsi index 9480922e2176d..5cd969114a723 100644 --- a/boards/snps/nsim/arc_v/rmx1xx.dtsi +++ b/boards/snps/nsim/arc_v/rmx1xx.dtsi @@ -37,6 +37,13 @@ interrupt-names = "soft0", "timer0"; }; + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&cpu0_intc 7>; + reg = <0x200bff8 0x8 0x2004000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + uart0: serial@10000000{ compatible = "ns16550", "snps,dw-apb-uart"; reg = <0x10000000 0x400>; diff --git a/boards/sparkfun/micromod/micromod_nrf52840.yaml b/boards/sparkfun/micromod/micromod_nrf52840.yaml index 520d9607d5ebc..d1cc5c241b5b7 100644 --- a/boards/sparkfun/micromod/micromod_nrf52840.yaml +++ b/boards/sparkfun/micromod/micromod_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - ble - gpio diff --git a/boards/sparkfun/nrf52_sparkfun/nrf52_sparkfun.yaml b/boards/sparkfun/nrf52_sparkfun/nrf52_sparkfun.yaml index a377d06007381..76b50d5879a55 100644 --- a/boards/sparkfun/nrf52_sparkfun/nrf52_sparkfun.yaml +++ b/boards/sparkfun/nrf52_sparkfun/nrf52_sparkfun.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 vendor: sparkfun diff --git a/boards/sparkfun/pro_micro_rp2040/doc/index.rst b/boards/sparkfun/pro_micro_rp2040/doc/index.rst index f538a04b1ce37..6932147e862f8 100644 --- a/boards/sparkfun/pro_micro_rp2040/doc/index.rst +++ b/boards/sparkfun/pro_micro_rp2040/doc/index.rst @@ -103,8 +103,8 @@ Default Zephyr Peripheral Mapping: - I2C1_SDA : P2 - I2C1_SCL : P3 - SPI0_RX : P20 -- SPI0_SCK : P18 -- SPI0_TX : P19 +- SPI0_SCK : P22 +- SPI0_TX : P23 Programming and Debugging ************************* diff --git a/boards/sparkfun/pro_micro_rp2040/sparkfun_pro_micro_rp2040-pinctrl.dtsi b/boards/sparkfun/pro_micro_rp2040/sparkfun_pro_micro_rp2040-pinctrl.dtsi index b2386014d6f71..072770e1339a8 100644 --- a/boards/sparkfun/pro_micro_rp2040/sparkfun_pro_micro_rp2040-pinctrl.dtsi +++ b/boards/sparkfun/pro_micro_rp2040/sparkfun_pro_micro_rp2040-pinctrl.dtsi @@ -29,14 +29,14 @@ spi0_default: spi0_default { group1 { - pinmux = ; + pinmux = ; }; group2 { pinmux = ; input-enable; }; group3 { - pinmux = ; + pinmux = ; }; }; diff --git a/boards/sparkfun/pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml b/boards/sparkfun/pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml index a2a8932d78fc5..d7e2587d89d4f 100644 --- a/boards/sparkfun/pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml +++ b/boards/sparkfun/pro_micro_rp2040/sparkfun_pro_micro_rp2040.yaml @@ -7,7 +7,6 @@ ram: 264 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio diff --git a/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160.yaml b/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160.yaml index f9d59872c1490..07bf5bd58c1c4 100644 --- a/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160.yaml +++ b/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 64 flash: 256 diff --git a/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.yaml b/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.yaml index 6fbb1dfb13a7b..2ea6bea8e7b4d 100644 --- a/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.yaml +++ b/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.yaml @@ -4,7 +4,6 @@ type: mcu arch: arm toolchain: - gnuarmemb - - xtools - zephyr ram: 128 flash: 192 diff --git a/boards/sparkfun/thing_plus_matter_mgm240p/Kconfig.defconfig b/boards/sparkfun/thing_plus_matter_mgm240p/Kconfig.defconfig index 9c21ba54457c1..1f5a3c940df1d 100644 --- a/boards/sparkfun/thing_plus_matter_mgm240p/Kconfig.defconfig +++ b/boards/sparkfun/thing_plus_matter_mgm240p/Kconfig.defconfig @@ -12,10 +12,6 @@ config CMU_HFXO_FREQ config CMU_LFXO_FREQ default 32768 -config FLASH_BASE_ADDRESS - hex - default 0x08000000 - if SOC_GECKO_USE_RAIL config FPU diff --git a/boards/sparkfun/thing_plus_matter_mgm240p/doc/index.rst b/boards/sparkfun/thing_plus_matter_mgm240p/doc/index.rst index 2a3961884bf6b..bd91534fc793a 100644 --- a/boards/sparkfun/thing_plus_matter_mgm240p/doc/index.rst +++ b/boards/sparkfun/thing_plus_matter_mgm240p/doc/index.rst @@ -100,7 +100,7 @@ Programming and Debugging .. note:: Before using the kit the first time, you should update the J-Link firmware - from `J-Link-Downloads`_ + in Simplicity Studio. Flashing ======== @@ -163,6 +163,3 @@ this example. .. _MGM240P Schematics: https://cdn.sparkfun.com/assets/0/f/8/4/9/Thing_Plus_MGM240P.pdf - -.. _J-Link-Downloads: - https://www.segger.com/downloads/jlink diff --git a/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.dts b/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.dts index 05db65eb18783..e24f97961a563 100644 --- a/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.dts +++ b/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.dts @@ -73,7 +73,7 @@ }; &eusart1 { - compatible = "silabs,gecko-spi-eusart"; + compatible = "silabs,eusart-spi"; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.yaml b/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.yaml index 392fbb38fb97b..928cf3ac06056 100644 --- a/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.yaml +++ b/boards/sparkfun/thing_plus_matter_mgm240p/sparkfun_thing_plus_matter_mgm240p.yaml @@ -7,7 +7,6 @@ flash: 1536 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/st/b_g474e_dpow1/b_g474e_dpow1.dts b/boards/st/b_g474e_dpow1/b_g474e_dpow1.dts index 1eb84827718ec..3c20afabc64cb 100644 --- a/boards/st/b_g474e_dpow1/b_g474e_dpow1.dts +++ b/boards/st/b_g474e_dpow1/b_g474e_dpow1.dts @@ -134,7 +134,7 @@ stm32_lp_tick_source: &lptim1 { &adc2 { pinctrl-0 = <&adc2_in8_pc2>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; diff --git a/boards/st/b_g474e_dpow1/b_g474e_dpow1.yaml b/boards/st/b_g474e_dpow1/b_g474e_dpow1.yaml index ff6b032e815b8..d014e0a9ed7f9 100644 --- a/boards/st/b_g474e_dpow1/b_g474e_dpow1.yaml +++ b/boards/st/b_g474e_dpow1/b_g474e_dpow1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 512 supported: diff --git a/boards/st/b_l072z_lrwan1/b_l072z_lrwan1.yaml b/boards/st/b_l072z_lrwan1/b_l072z_lrwan1.yaml index eef460836cb5a..e94ba64e891ad 100644 --- a/boards/st/b_l072z_lrwan1/b_l072z_lrwan1.yaml +++ b/boards/st/b_l072z_lrwan1/b_l072z_lrwan1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 flash: 192 testing: diff --git a/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.dts b/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.dts index d7f5adab5bebc..da6bcc44c6a70 100644 --- a/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.dts +++ b/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.dts @@ -239,7 +239,7 @@ zephyr_udc0: &usbotg_fs { &octospim_p1_io2_pe14 &octospim_p1_io3_pe15>; pinctrl-names = "default"; - dmas = <&dma1 0 40 0x480>; /* request 40 for OCTOSPI1 */ + dmas = <&dma1 0 40 STM32_DMA_PERIPH_RX>; /* request 40 for OCTOSPI1 */ dma-names = "tx_rx"; status = "okay"; diff --git a/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml b/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml index d0928a8aa1dc2..daaa2bd2f40a9 100644 --- a/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml +++ b/boards/st/b_l4s5i_iot01a/b_l4s5i_iot01a.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 2048 supported: diff --git a/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi b/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi index c8d5ca4b790ff..39a42c9934aaa 100644 --- a/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi +++ b/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi @@ -223,7 +223,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in15_pb0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -231,7 +231,7 @@ zephyr_udc0: &usbotg_fs { &adc4 { pinctrl-0 = <&adc4_in19_pb1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/b_u585i_iot02a/b_u585i_iot02a.yaml b/boards/st/b_u585i_iot02a/b_u585i_iot02a.yaml index 48f1064731cec..621e455720497 100644 --- a/boards/st/b_u585i_iot02a/b_u585i_iot02a.yaml +++ b/boards/st/b_u585i_iot02a/b_u585i_iot02a.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 786 flash: 2048 supported: diff --git a/boards/st/b_u585i_iot02a/b_u585i_iot02a_stm32u585xx_ns.yaml b/boards/st/b_u585i_iot02a/b_u585i_iot02a_stm32u585xx_ns.yaml index 662c6f1884807..f3b9d44684c8e 100644 --- a/boards/st/b_u585i_iot02a/b_u585i_iot02a_stm32u585xx_ns.yaml +++ b/boards/st/b_u585i_iot02a/b_u585i_iot02a_stm32u585xx_ns.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 786 flash: 512 vendor: st diff --git a/boards/st/b_u585i_iot02a/pre_dt_board.cmake b/boards/st/b_u585i_iot02a/pre_dt_board.cmake deleted file mode 100644 index 812d18cdf6c53..0000000000000 --- a/boards/st/b_u585i_iot02a/pre_dt_board.cmake +++ /dev/null @@ -1,3 +0,0 @@ - -# SPI is implemented via octospi so node name isn't spi@... -list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/st/common/scripts/board_power_reset.sh b/boards/st/common/scripts/board_power_reset.sh new file mode 100755 index 0000000000000..47227f7de054b --- /dev/null +++ b/boards/st/common/scripts/board_power_reset.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2025 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 + +STM32_Programmer_CLI -c port=swd mode=UR --power off index=0 --power on index=0 > /dev/null + +sleep 1 diff --git a/boards/st/disco_l475_iot1/disco_l475_iot1.dts b/boards/st/disco_l475_iot1/disco_l475_iot1.dts index 33e6d973cf89c..6ffb695012402 100644 --- a/boards/st/disco_l475_iot1/disco_l475_iot1.dts +++ b/boards/st/disco_l475_iot1/disco_l475_iot1.dts @@ -293,7 +293,7 @@ zephyr_udc0: &usbotg_fs { pinctrl-0 = <&adc1_in3_pc2 &adc1_in4_pc3 &adc1_in13_pc4 &adc1_in14_pc5>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/disco_l475_iot1/disco_l475_iot1.yaml b/boards/st/disco_l475_iot1/disco_l475_iot1.yaml index 83d7b66b0cb56..801856fa3b010 100644 --- a/boards/st/disco_l475_iot1/disco_l475_iot1.yaml +++ b/boards/st/disco_l475_iot1/disco_l475_iot1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/st/nucleo_c031c6/nucleo_c031c6.dts b/boards/st/nucleo_c031c6/nucleo_c031c6.dts index 404c1cb296256..e14cf23512183 100644 --- a/boards/st/nucleo_c031c6/nucleo_c031c6.dts +++ b/boards/st/nucleo_c031c6/nucleo_c031c6.dts @@ -117,7 +117,7 @@ &adc1 { pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1 &adc1_in4_pa4>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_c031c6/nucleo_c031c6.yaml b/boards/st/nucleo_c031c6/nucleo_c031c6.yaml index 7f311f93c489a..713f5118a330a 100644 --- a/boards/st/nucleo_c031c6/nucleo_c031c6.yaml +++ b/boards/st/nucleo_c031c6/nucleo_c031c6.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - counter diff --git a/boards/st/nucleo_c071rb/Kconfig.nucleo_c071rb b/boards/st/nucleo_c071rb/Kconfig.nucleo_c071rb new file mode 100644 index 0000000000000..b0c7abff956be --- /dev/null +++ b/boards/st/nucleo_c071rb/Kconfig.nucleo_c071rb @@ -0,0 +1,5 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_C071RB + select SOC_STM32C071XX diff --git a/boards/st/nucleo_c071rb/arduino_r3_connector.dtsi b/boards/st/nucleo_c071rb/arduino_r3_connector.dtsi new file mode 100644 index 0000000000000..5d62471e418aa --- /dev/null +++ b/boards/st/nucleo_c071rb/arduino_r3_connector.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 0 0>, /* A0 */ + <1 0 &gpioa 1 0>, /* A1 */ + <2 0 &gpioa 4 0>, /* A2 */ + <3 0 &gpiob 0 0>, /* A3 */ + <4 0 &gpioc 4 0>, /* A4 */ + <5 0 &gpioc 5 0>, /* A5 */ + <6 0 &gpiob 7 0>, /* D0 */ + <7 0 &gpiob 6 0>, /* D1 */ + <8 0 &gpioa 10 0>, /* D2 */ + <9 0 &gpioc 7 0>, /* D3 */ + <10 0 &gpiob 5 0>, /* D4 */ + <11 0 &gpiob 4 0>, /* D5 */ + <12 0 &gpioc 8 0>, /* D6 */ + <13 0 &gpioa 8 0>, /* D7 */ + <14 0 &gpioa 9 0>, /* D8 */ + <15 0 &gpiob 3 0>, /* D9 */ + <16 0 &gpioa 15 0>, /* D10 */ + <17 0 &gpioa 7 0>, /* D11 */ + <18 0 &gpioa 6 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 8 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c1 {}; +arduino_spi: &spi1 {}; +arduino_serial: &usart1 {}; diff --git a/boards/st/nucleo_c071rb/board.cmake b/boards/st/nucleo_c071rb/board.cmake new file mode 100644 index 0000000000000..716846e4923c4 --- /dev/null +++ b/boards/st/nucleo_c071rb/board.cmake @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +# keep first +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") + +# keep first +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/st/nucleo_c071rb/board.yml b/boards/st/nucleo_c071rb/board.yml new file mode 100644 index 0000000000000..af125dd1154a0 --- /dev/null +++ b/boards/st/nucleo_c071rb/board.yml @@ -0,0 +1,6 @@ +board: + name: nucleo_c071rb + full_name: Nucleo C071RB + vendor: st + socs: + - name: stm32c071xx diff --git a/boards/st/nucleo_c071rb/doc/img/nucleo_c071rb.webp b/boards/st/nucleo_c071rb/doc/img/nucleo_c071rb.webp new file mode 100644 index 0000000000000..2cd802b7a59b6 Binary files /dev/null and b/boards/st/nucleo_c071rb/doc/img/nucleo_c071rb.webp differ diff --git a/boards/st/nucleo_c071rb/doc/index.rst b/boards/st/nucleo_c071rb/doc/index.rst new file mode 100644 index 0000000000000..7d4637c82a534 --- /dev/null +++ b/boards/st/nucleo_c071rb/doc/index.rst @@ -0,0 +1,163 @@ +.. zephyr:board:: nucleo_c071rb + +Overview +******** +The STM32 Nucleo-64 development board with STM32C071RB MCU, supports Arduino and ST morpho connectivity. + +The STM32 Nucleo board provides an affordable, and flexible way for users to try out new concepts, +and build prototypes with the STM32 microcontroller, choosing from the various +combinations of performance, power consumption and features. + +The STM32 Nucleo board integrates the ST-LINK/V2-1 debugger and programmer. + +The STM32 Nucleo board comes with the STM32 comprehensive software HAL library together +with various packaged software examples. + +.. image:: img/nucleo_c071rb.webp + :align: center + :alt: Nucleo C071RB + +More information about the board can be found at the `Nucleo C071RB website`_. + +Hardware +******** +Nucleo C071RB provides the following hardware components: + +- STM32 microcontroller in 64-pin package featuring 128 Kbytes of Flash memory + and 24 Kbytes of SRAM. +- Extension resource: + + - Arduino* Uno V3 connectivity + +- On-board ST-LINK/V2-1 debugger/programmer with SWD connector: + +- Flexible board power supply: + + - USB VBUS or external source (3.3V, 5V, 7 - 12V) + - Current consumption measurement (IDD) + +- Four LEDs: + + - USB communication (LD1), USB power fault LED (LD2), power LED (LD3), + user LED (LD4) + +- Two push-button: USER and RESET + +- USB re-enumeration capability. Three different interfaces supported on USB: + + - Virtual COM port + - Mass storage + - Debug port + +More information about STM32C071RB can be found here: +`STM32C0x1 reference manual`_ + +Supported Features +================== + +The Zephyr ``nucleo_c071rb`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | counter | ++-----------+------------+-------------------------------------+ +| IWDG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| WWDG | on-chip | window watchdog | ++-----------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | ADC Controller | ++-----------+------------+-------------------------------------+ +| die-temp | on-chip | die temperature sensor | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| DMA | on-chip | Direct Memory Access | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | rtc | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported in this Zephyr port. + +The default configuration can be found in +:zephyr_file:`boards/st/nucleo_c071rb/nucleo_c071rb_defconfig` + +Connections and IOs +=================== + +Each of the GPIO pins can be configured by software as output (push-pull or open-drain), as +input (with or without pull-up or pull-down), or as peripheral alternate function. Most of the +GPIO pins are shared with digital or analog alternate functions. All GPIOs are high current +capable except for analog inputs. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- I2C1 SCL/SDA : PB8/PB9 (Arduino I2C) +- LD1 : PA5 +- LD2 : PC9 +- SPI1 NSS/SCK/MISO/MOSI : PA4/PA5/PA11/PA12 (Arduino SPI) +- UART_2 TX/RX : PA2/PA3 (ST-Link Virtual Port Com) +- USER_PB : PC13 + + +For more details please refer to `STM32 Nucleo-64 board User Manual`_. + +Programming and Debugging +************************* + +Nucleo C071RB board includes an ST-LINK/V2-1 embedded debug tool interface. + +Applications for the ``nucleo_c071rb`` board can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +The board is configured to be flashed using west `STM32CubeProgrammer`_ runner, +so its :ref:`installation ` is required. + +Flashing an application to Nucleo C071RB +---------------------------------------- + +Here is an example for the :zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_c071rb + :goals: build flash + +You will see the LED blinking every second. + +References +********** + +.. target-notes:: + +.. _Nucleo C071RB website: + https://www.st.com/en/evaluation-tools/nucleo-c071rb.html + +.. _STM32C0x1 reference manual: + https://www.st.com/resource/en/reference_manual/rm0490-stm32c0x1-advanced-armbased-64bit-mcus-stmicroelectronics.pdf + +.. _STM32 Nucleo-64 board User Manual: + https://www.st.com/resource/en/user_manual/um2953-stm32c0-nucleo64-board-mb1717-stmicroelectronics.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/nucleo_c071rb/nucleo_c071rb.dts b/boards/st/nucleo_c071rb/nucleo_c071rb.dts new file mode 100644 index 0000000000000..3d4bcd0a12e46 --- /dev/null +++ b/boards/st/nucleo_c071rb/nucleo_c071rb.dts @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "arduino_r3_connector.dtsi" +#include + +/ { + model = "STMicroelectronics STM32C071RB-NUCLEO board"; + compatible = "st,stm32c071rb-nucleo"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds: leds { + compatible = "gpio-leds"; + green_led_1: led_1 { + gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + + blue_led: led_2 { + gpios = <&gpioc 9 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + green_pwm_led: green_pwm_led { + pwms = <&pwm1 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "user button"; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + status = "okay"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &green_led_1; + led1 = &blue_led; + pwm-led0 = &green_pwm_led; + sw0 = &user_button; + watchdog0 = &iwdg; + die-temp0 = &die_temp; + volt-sensor0 = &vref; + }; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&rcc { + clocks = <&clk_hse>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <1>; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&timers1 { + st,prescaler = <10000>; + status = "okay"; + + pwm1: pwm { + pinctrl-0 = <&tim1_ch1_pa5>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pa7 &i2c2_sda_pa6>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pb0 &spi1_sck_pb3 + &spi1_miso_pb4 &spi1_mosi_pb5>; + pinctrl-names = "default"; + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1 &adc1_in4_pa4>; + pinctrl-names = "default"; + st,adc-clock-source = "ASYNC"; + clocks = <&rcc STM32_CLOCK(APB1_2, 20U)>, + <&rcc STM32_SRC_HSI ADC_SEL(2)>; + st,adc-prescaler = <4>; + status = "okay"; + vref-mv = <3300>; +}; + +&die_temp { + status = "okay"; +}; + +&vref { + status = "okay"; +}; + +&dma1 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; diff --git a/boards/st/nucleo_c071rb/nucleo_c071rb.yaml b/boards/st/nucleo_c071rb/nucleo_c071rb.yaml new file mode 100644 index 0000000000000..50ca9ed00ee24 --- /dev/null +++ b/boards/st/nucleo_c071rb/nucleo_c071rb.yaml @@ -0,0 +1,21 @@ +identifier: nucleo_c071rb +name: ST Nucleo C071RB +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - arduino_gpio + - counter + - dma + - gpio + - i2c + - pwm + - rtc + - spi + - watchdog +ram: 24 +flash: 128 +vendor: st diff --git a/boards/st/nucleo_c071rb/nucleo_c071rb_defconfig b/boards/st/nucleo_c071rb/nucleo_c071rb_defconfig new file mode 100644 index 0000000000000..c60dfffbc3b86 --- /dev/null +++ b/boards/st/nucleo_c071rb/nucleo_c071rb_defconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# GPIO Controller +CONFIG_GPIO=y diff --git a/boards/st/nucleo_f030r8/doc/index.rst b/boards/st/nucleo_f030r8/doc/index.rst index 34abf6f6cb08a..4796c939ecc9a 100644 --- a/boards/st/nucleo_f030r8/doc/index.rst +++ b/boards/st/nucleo_f030r8/doc/index.rst @@ -29,7 +29,6 @@ Nucleo F030R8 provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -50,11 +49,6 @@ Nucleo F030R8 provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32F030R8 can be found here: diff --git a/boards/st/nucleo_f030r8/nucleo_f030r8.dts b/boards/st/nucleo_f030r8/nucleo_f030r8.dts index 3e346fc20c7ff..398c3ded4bafd 100644 --- a/boards/st/nucleo_f030r8/nucleo_f030r8.dts +++ b/boards/st/nucleo_f030r8/nucleo_f030r8.dts @@ -118,7 +118,7 @@ &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_f030r8/nucleo_f030r8_1.yaml b/boards/st/nucleo_f030r8/nucleo_f030r8_1.yaml index 814f2a7fc1b4e..94e7443c404ec 100644 --- a/boards/st/nucleo_f030r8/nucleo_f030r8_1.yaml +++ b/boards/st/nucleo_f030r8/nucleo_f030r8_1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 8 flash: 64 supported: diff --git a/boards/st/nucleo_f030r8/nucleo_f030r8_2.yaml b/boards/st/nucleo_f030r8/nucleo_f030r8_2.yaml index 0cdc0e8ee9d2e..6bff733424ef8 100644 --- a/boards/st/nucleo_f030r8/nucleo_f030r8_2.yaml +++ b/boards/st/nucleo_f030r8/nucleo_f030r8_2.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 8 flash: 64 supported: diff --git a/boards/st/nucleo_f031k6/nucleo_f031k6.dts b/boards/st/nucleo_f031k6/nucleo_f031k6.dts index 0b5f9a04161c7..496699450875e 100644 --- a/boards/st/nucleo_f031k6/nucleo_f031k6.dts +++ b/boards/st/nucleo_f031k6/nucleo_f031k6.dts @@ -103,7 +103,7 @@ &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_f031k6/nucleo_f031k6.yaml b/boards/st/nucleo_f031k6/nucleo_f031k6.yaml index 9b04bd973bfcb..289875df5b1ec 100644 --- a/boards/st/nucleo_f031k6/nucleo_f031k6.yaml +++ b/boards/st/nucleo_f031k6/nucleo_f031k6.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 4 flash: 32 supported: diff --git a/boards/st/nucleo_f042k6/nucleo_f042k6.dts b/boards/st/nucleo_f042k6/nucleo_f042k6.dts index 74d700c9c1dc0..0f8a31e35b4da 100644 --- a/boards/st/nucleo_f042k6/nucleo_f042k6.dts +++ b/boards/st/nucleo_f042k6/nucleo_f042k6.dts @@ -99,7 +99,7 @@ &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_f042k6/nucleo_f042k6.yaml b/boards/st/nucleo_f042k6/nucleo_f042k6.yaml index a86f5dddaeb12..826ce0b046d23 100644 --- a/boards/st/nucleo_f042k6/nucleo_f042k6.yaml +++ b/boards/st/nucleo_f042k6/nucleo_f042k6.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 6 flash: 32 supported: diff --git a/boards/st/nucleo_f070rb/doc/index.rst b/boards/st/nucleo_f070rb/doc/index.rst index c198fe28f6e20..989decfd3f06a 100644 --- a/boards/st/nucleo_f070rb/doc/index.rst +++ b/boards/st/nucleo_f070rb/doc/index.rst @@ -29,7 +29,6 @@ Nucleo F070RB provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -50,11 +49,6 @@ Nucleo F070RB provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32F070RB can be found in the `STM32F070 reference manual`_ . diff --git a/boards/st/nucleo_f070rb/nucleo_f070rb.dts b/boards/st/nucleo_f070rb/nucleo_f070rb.dts index c504dad4de50c..8c0b43d71c8b8 100644 --- a/boards/st/nucleo_f070rb/nucleo_f070rb.dts +++ b/boards/st/nucleo_f070rb/nucleo_f070rb.dts @@ -121,7 +121,7 @@ &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_f070rb/nucleo_f070rb.yaml b/boards/st/nucleo_f070rb/nucleo_f070rb.yaml index 5ed0d28dd3d54..4745c18339982 100644 --- a/boards/st/nucleo_f070rb/nucleo_f070rb.yaml +++ b/boards/st/nucleo_f070rb/nucleo_f070rb.yaml @@ -7,7 +7,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/st/nucleo_f072rb/Kconfig.defconfig b/boards/st/nucleo_f072rb/Kconfig.defconfig new file mode 100644 index 0000000000000..1031692291f91 --- /dev/null +++ b/boards/st/nucleo_f072rb/Kconfig.defconfig @@ -0,0 +1,12 @@ +# NUCLEO_F072RB board configuration + +# Copyright (c) 2025 Alex Fabre +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NUCLEO_F072RB + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +endif # BOARD_NUCLEO_F072RB diff --git a/boards/st/nucleo_f072rb/Kconfig.nucleo_f072rb b/boards/st/nucleo_f072rb/Kconfig.nucleo_f072rb new file mode 100644 index 0000000000000..165ba6c290297 --- /dev/null +++ b/boards/st/nucleo_f072rb/Kconfig.nucleo_f072rb @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Alex Fabre +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_F072RB + select SOC_STM32F072XB diff --git a/boards/st/nucleo_f072rb/arduino_r3_connector.dtsi b/boards/st/nucleo_f072rb/arduino_r3_connector.dtsi new file mode 100644 index 0000000000000..6ed2b49ad15f0 --- /dev/null +++ b/boards/st/nucleo_f072rb/arduino_r3_connector.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Alex Fabre + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 0 0>, /* A0 */ + <1 0 &gpioa 1 0>, /* A1 */ + <2 0 &gpioa 4 0>, /* A2 */ + <3 0 &gpiob 0 0>, /* A3 */ + <4 0 &gpioc 1 0>, /* A4 */ + <5 0 &gpioc 0 0>, /* A5 */ + <6 0 &gpioa 3 0>, /* D0 */ + <7 0 &gpioa 2 0>, /* D1 */ + <8 0 &gpioa 10 0>, /* D2 */ + <9 0 &gpiob 3 0>, /* D3 */ + <10 0 &gpiob 5 0>, /* D4 */ + <11 0 &gpiob 4 0>, /* D5 */ + <12 0 &gpiob 10 0>, /* D6 */ + <13 0 &gpioa 8 0>, /* D7 */ + <14 0 &gpioa 9 0>, /* D8 */ + <15 0 &gpioc 7 0>, /* D9 */ + <16 0 &gpiob 6 0>, /* D10 */ + <17 0 &gpioa 7 0>, /* D11 */ + <18 0 &gpioa 6 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 8 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c1 {}; +arduino_spi: &spi1 {}; diff --git a/boards/st/nucleo_f072rb/board.cmake b/boards/st/nucleo_f072rb/board.cmake new file mode 100644 index 0000000000000..136bd345f6afa --- /dev/null +++ b/boards/st/nucleo_f072rb/board.cmake @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +# keep first +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +board_runner_args(jlink "--device=STM32F072RB" "--speed=4000") + +# keep first +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/st/nucleo_f072rb/board.yml b/boards/st/nucleo_f072rb/board.yml new file mode 100644 index 0000000000000..96a4c251439d8 --- /dev/null +++ b/boards/st/nucleo_f072rb/board.yml @@ -0,0 +1,6 @@ +board: + name: nucleo_f072rb + full_name: Nucleo F072RB + vendor: st + socs: + - name: stm32f072xb diff --git a/boards/st/nucleo_f072rb/doc/img/nucleo_f072rb.webp b/boards/st/nucleo_f072rb/doc/img/nucleo_f072rb.webp new file mode 100644 index 0000000000000..36ee2ce83aabd Binary files /dev/null and b/boards/st/nucleo_f072rb/doc/img/nucleo_f072rb.webp differ diff --git a/boards/st/nucleo_f072rb/doc/img/nucleo_f072rb_connectors.webp b/boards/st/nucleo_f072rb/doc/img/nucleo_f072rb_connectors.webp new file mode 100644 index 0000000000000..db83da75dabf3 Binary files /dev/null and b/boards/st/nucleo_f072rb/doc/img/nucleo_f072rb_connectors.webp differ diff --git a/boards/st/nucleo_f072rb/doc/index.rst b/boards/st/nucleo_f072rb/doc/index.rst new file mode 100644 index 0000000000000..154497de01493 --- /dev/null +++ b/boards/st/nucleo_f072rb/doc/index.rst @@ -0,0 +1,181 @@ +.. zephyr:board:: nucleo_f072rb + +Overview +******** +The STM32 Nucleo-64 development board with STM32F072RB MCU, supports Arduino and ST morpho connectivity. + +The STM32 Nucleo board provides an affordable, and flexible way for users to try out new concepts, +and build prototypes with the STM32 microcontroller, choosing from the various +combinations of performance, power consumption, and features. + +The Arduino* Uno V3 connectivity support and the ST morpho headers allow easy functionality +expansion of the STM32 Nucleo open development platform with a wide choice of +specialized shields. + +The STM32 Nucleo board integrates the ST-LINK/V2-1 debugger and programmer. + +The STM32 Nucleo board comes with the STM32 comprehensive software HAL library together +with various packaged software examples. + +More information about the board can be found at the `Nucleo F072RB website`_. + +Hardware +******** +Nucleo F072RB provides the following hardware components: + +- STM32 microcontroller in QFP64 package +- Two types of extension resources: + + - Arduino* Uno V3 connectivity + - ST morpho extension pin headers for full access to all STM32 I/Os + +- On-board ST-LINK/V2-1 debugger/programmer with SWD connector: + + - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 + +- Flexible board power supply: + + - USB VBUS or external source (3.3V, 5V, 7 - 12V) + - Power management access point + +- Three LEDs: + + - USB communication (LD1), user LED (LD2), power LED (LD3) + +- Two push-buttons: USER and RESET +- USB re-enumeration capability. Three different interfaces supported on USB: + + - Virtual COM port + - Mass storage + - Debug port + +More information about STM32F072RB can be found in +the `STM32F072 reference manual`_ . + + +Supported Features +================== + +The Zephyr ``nucleo_f072rb`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c controller | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | SPI controller | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | rtc | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported in this Zephyr port. + +The default configuration can be found in +:zephyr_file:`boards/st/nucleo_f072rb/nucleo_f072rb_defconfig` + +Connections and IOs +=================== + +Each of the GPIO pins can be configured by software as output (push-pull or open-drain), as +input (with or without pull-up or pull-down), or as peripheral alternate function. Most of the +GPIO pins are shared with digital or analog alternate functions. All GPIOs are high current +capable except for analog inputs. + +Board connectors: +----------------- +.. image:: img/nucleo_f072rb_connectors.webp + :align: center + :alt: Nucleo F072RB connectors + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- UART_1 TX/RX : PA9/PA10 +- UART_2 TX/RX : PA2/PA3 (ST-Link Virtual COM Port) +- I2C1 SCL/SDA : PB8/PB9 (Arduino I2C) +- I2C2 SCL/SDA : PB10/PB11 +- SPI1 NSS/SCK/MISO/MOSI : PB6/PA5/PA6/PA7 (Arduino SPI) +- SPI2 SCK/MISO/MOSI : PB13/PB14/PB15 +- USER_PB : PC13 +- LD1 : PA5 + +For more details please refer to `STM32 Nucleo-64 board User Manual`_. + +Programming and Debugging +************************* + +Nucleo F072RB board includes an ST-LINK/V2-1 embedded debug tool interface. + +Applications for the ``nucleo_f072rb`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +The board is configured to be flashed using west `STM32CubeProgrammer`_ runner, +so its :ref:`installation ` is required. + +Alternatively, OpenOCD or JLink can also be used to flash the board using +the ``--runner`` (or ``-r``) option: + +.. code-block:: console + + $ west flash --runner openocd + $ west flash --runner jlink + +Flashing an application to Nucleo F072RB +---------------------------------------- + +Here is an example for the :zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_f072rb + :goals: build flash + +You will see the LED blinking every second. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_f072rb + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _Nucleo F072RB website: + https://www.st.com/en/evaluation-tools/nucleo-f072rb.html + +.. _STM32F072 reference manual: + https://www.st.com/resource/en/reference_manual/dm00031936.pdf + +.. _STM32 Nucleo-64 board User Manual: + https://www.st.com/resource/en/user_manual/dm00105823.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/nucleo_f072rb/nucleo_f072rb.dts b/boards/st/nucleo_f072rb/nucleo_f072rb.dts new file mode 100644 index 0000000000000..207639f73b1a2 --- /dev/null +++ b/boards/st/nucleo_f072rb/nucleo_f072rb.dts @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025 Alex Fabre + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "arduino_r3_connector.dtsi" +#include "st_morpho_connector.dtsi" +#include + +/ { + model = "STMicroelectronics NUCLEO-F072RB board"; + compatible = "st,stm32f072rb-nucleo"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds: leds { + compatible = "gpio-leds"; + green_led_2: led_2 { + gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &green_led_2; + sw0 = &user_button; + watchdog0 = &iwdg; + die-temp0 = &die_temp; + volt-sensor0 = &vref; + }; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hse { + hse-bypass; + clock-frequency = ; /* STLink 8MHz clock */ + status = "okay"; +}; + +&pll { + clocks = <&clk_hse>; + prediv = <1>; + mul = <6>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <2>; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>; + pinctrl-names = "default"; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc_in0_pa0>; + pinctrl-names = "default"; + st,adc-clock-source = "SYNC"; + st,adc-prescaler = <4>; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x10000000>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&vref { + status = "okay"; +}; diff --git a/boards/st/nucleo_f072rb/nucleo_f072rb.yaml b/boards/st/nucleo_f072rb/nucleo_f072rb.yaml new file mode 100644 index 0000000000000..0a46f541b9115 --- /dev/null +++ b/boards/st/nucleo_f072rb/nucleo_f072rb.yaml @@ -0,0 +1,24 @@ +identifier: nucleo_f072rb +name: ST Nucleo F072RB +type: mcu +arch: arm +ram: 16 +flash: 128 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - arduino_gpio + - arduino_i2c + - arduino_spi + - gpio + - i2c + - spi + - watchdog + - rtc +testing: + ignore_tags: + - net + - bluetooth +vendor: st diff --git a/boards/st/nucleo_f072rb/nucleo_f072rb_defconfig b/boards/st/nucleo_f072rb/nucleo_f072rb_defconfig new file mode 100644 index 0000000000000..c60dfffbc3b86 --- /dev/null +++ b/boards/st/nucleo_f072rb/nucleo_f072rb_defconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# GPIO Controller +CONFIG_GPIO=y diff --git a/boards/st/nucleo_f072rb/st_morpho_connector.dtsi b/boards/st/nucleo_f072rb/st_morpho_connector.dtsi new file mode 100644 index 0000000000000..397f3192dacb8 --- /dev/null +++ b/boards/st/nucleo_f072rb/st_morpho_connector.dtsi @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Alex Fabre + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + st_morpho_header: st-morpho-header { + compatible = "st-morpho-header"; + #gpio-cells = <2>; + gpio-map-mask = ; + gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , /* SB49=ON */ + , /* SB48=ON */ + , + , /* SB55=ON */ + , + , /* SB54=ON */ + , + , + , + , /* SB56=ON, SB46=OFF */ + , + , /* SB51=ON, SB52=OFF */ + , + , + , + , + , + , + , + , /* SB42=ON, SB29=OFF */ + , + , /* SB41=ON, SB24=OFF */ + , + , /* SB40=ON, SB20=OFF */ + , + , + , + , + , + , + , + , + , + , /* SB25=ON, SB36=OFF */ + , + , /* SB28=ON, SB39=OFF */ + , + , /* SB35=ON, SB44=OFF */ + , + , + , + , + , + , + ; + }; +}; diff --git a/boards/st/nucleo_f072rb/support/openocd.cfg b/boards/st/nucleo_f072rb/support/openocd.cfg new file mode 100644 index 0000000000000..f0d0b22a310bb --- /dev/null +++ b/boards/st/nucleo_f072rb/support/openocd.cfg @@ -0,0 +1,12 @@ +source [find board/st_nucleo_f0.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/st/nucleo_f091rc/doc/index.rst b/boards/st/nucleo_f091rc/doc/index.rst index 60181533aff9d..1773bc8132394 100644 --- a/boards/st/nucleo_f091rc/doc/index.rst +++ b/boards/st/nucleo_f091rc/doc/index.rst @@ -29,7 +29,6 @@ Nucleo F091RC provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -50,11 +49,6 @@ Nucleo F091RC provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32F091RC can be found in the `STM32F091 reference manual`_ diff --git a/boards/st/nucleo_f091rc/nucleo_f091rc.dts b/boards/st/nucleo_f091rc/nucleo_f091rc.dts index b24435909182a..cb9348240ca14 100644 --- a/boards/st/nucleo_f091rc/nucleo_f091rc.dts +++ b/boards/st/nucleo_f091rc/nucleo_f091rc.dts @@ -159,7 +159,7 @@ &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_f091rc/nucleo_f091rc.yaml b/boards/st/nucleo_f091rc/nucleo_f091rc.yaml index d0ac388b263a6..f8840d08c9679 100644 --- a/boards/st/nucleo_f091rc/nucleo_f091rc.yaml +++ b/boards/st/nucleo_f091rc/nucleo_f091rc.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 256 supported: diff --git a/boards/st/nucleo_f103rb/doc/index.rst b/boards/st/nucleo_f103rb/doc/index.rst index 662fd3ac3cc87..0bb6f042c43b0 100644 --- a/boards/st/nucleo_f103rb/doc/index.rst +++ b/boards/st/nucleo_f103rb/doc/index.rst @@ -29,7 +29,6 @@ Nucleo F103RB provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -50,11 +49,6 @@ Nucleo F103RB provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32F103RB can be found here: diff --git a/boards/st/nucleo_f103rb/nucleo_f103rb.yaml b/boards/st/nucleo_f103rb/nucleo_f103rb.yaml index e231aa5e1d264..507c2a01f27da 100644 --- a/boards/st/nucleo_f103rb/nucleo_f103rb.yaml +++ b/boards/st/nucleo_f103rb/nucleo_f103rb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 flash: 128 supported: diff --git a/boards/st/nucleo_f207zg/nucleo_f207zg.dts b/boards/st/nucleo_f207zg/nucleo_f207zg.dts index 4f3e8cafde3aa..724bf9456cc3b 100644 --- a/boards/st/nucleo_f207zg/nucleo_f207zg.dts +++ b/boards/st/nucleo_f207zg/nucleo_f207zg.dts @@ -164,7 +164,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f207zg/nucleo_f207zg.yaml b/boards/st/nucleo_f207zg/nucleo_f207zg.yaml index 681cc571c0e8e..127305024fe3d 100644 --- a/boards/st/nucleo_f207zg/nucleo_f207zg.yaml +++ b/boards/st/nucleo_f207zg/nucleo_f207zg.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/st/nucleo_f302r8/nucleo_f302r8.dts b/boards/st/nucleo_f302r8/nucleo_f302r8.dts index cb46e89563a6d..ea85df6c96d11 100644 --- a/boards/st/nucleo_f302r8/nucleo_f302r8.dts +++ b/boards/st/nucleo_f302r8/nucleo_f302r8.dts @@ -124,7 +124,7 @@ &adc1 { pinctrl-0 = <&adc1_in1_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f302r8/nucleo_f302r8.yaml b/boards/st/nucleo_f302r8/nucleo_f302r8.yaml index a5e3758b6a68a..b0607440979cb 100644 --- a/boards/st/nucleo_f302r8/nucleo_f302r8.yaml +++ b/boards/st/nucleo_f302r8/nucleo_f302r8.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 16 flash: 64 supported: diff --git a/boards/st/nucleo_f303k8/nucleo_f303k8.dts b/boards/st/nucleo_f303k8/nucleo_f303k8.dts index efdf58a848fbe..c4f39c8411384 100644 --- a/boards/st/nucleo_f303k8/nucleo_f303k8.dts +++ b/boards/st/nucleo_f303k8/nucleo_f303k8.dts @@ -100,7 +100,7 @@ &adc1 { pinctrl-0 = <&adc1_in1_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f303k8/nucleo_f303k8.yaml b/boards/st/nucleo_f303k8/nucleo_f303k8.yaml index 3442ef50d0d5d..848b83324c1dd 100644 --- a/boards/st/nucleo_f303k8/nucleo_f303k8.yaml +++ b/boards/st/nucleo_f303k8/nucleo_f303k8.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 12 flash: 64 supported: diff --git a/boards/st/nucleo_f303re/nucleo_f303re.yaml b/boards/st/nucleo_f303re/nucleo_f303re.yaml index 525a83f252a01..c8453732df609 100644 --- a/boards/st/nucleo_f303re/nucleo_f303re.yaml +++ b/boards/st/nucleo_f303re/nucleo_f303re.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 80 flash: 512 supported: diff --git a/boards/st/nucleo_f334r8/doc/index.rst b/boards/st/nucleo_f334r8/doc/index.rst index 385f4e05094ee..d5e633e97d8a2 100644 --- a/boards/st/nucleo_f334r8/doc/index.rst +++ b/boards/st/nucleo_f334r8/doc/index.rst @@ -30,7 +30,6 @@ Nucleo F334R8 provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -51,11 +50,6 @@ Nucleo F334R8 provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32F334R8 can be found in the `STM32F334 reference manual`_ diff --git a/boards/st/nucleo_f334r8/nucleo_f334r8.yaml b/boards/st/nucleo_f334r8/nucleo_f334r8.yaml index a4533b015a0d8..542686905bbc6 100644 --- a/boards/st/nucleo_f334r8/nucleo_f334r8.yaml +++ b/boards/st/nucleo_f334r8/nucleo_f334r8.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 12 flash: 64 testing: diff --git a/boards/st/nucleo_f401re/nucleo_f401re.dts b/boards/st/nucleo_f401re/nucleo_f401re.dts index fbfdc59bea00b..b73ea3f69ef47 100644 --- a/boards/st/nucleo_f401re/nucleo_f401re.dts +++ b/boards/st/nucleo_f401re/nucleo_f401re.dts @@ -180,7 +180,7 @@ &adc1 { pinctrl-0 = <&adc1_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f401re/nucleo_f401re.yaml b/boards/st/nucleo_f401re/nucleo_f401re.yaml index 457c4295196ce..08af2b481d7c5 100644 --- a/boards/st/nucleo_f401re/nucleo_f401re.yaml +++ b/boards/st/nucleo_f401re/nucleo_f401re.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/st/nucleo_f410rb/nucleo_f410rb.yaml b/boards/st/nucleo_f410rb/nucleo_f410rb.yaml index 81eef793cddea..6bbba048f606c 100644 --- a/boards/st/nucleo_f410rb/nucleo_f410rb.yaml +++ b/boards/st/nucleo_f410rb/nucleo_f410rb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/st/nucleo_f411re/nucleo_f411re.yaml b/boards/st/nucleo_f411re/nucleo_f411re.yaml index 90a57f9372083..c86e6cca3e046 100644 --- a/boards/st/nucleo_f411re/nucleo_f411re.yaml +++ b/boards/st/nucleo_f411re/nucleo_f411re.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/st/nucleo_f412zg/Kconfig.defconfig b/boards/st/nucleo_f412zg/Kconfig.defconfig deleted file mode 100644 index a2c9ec558818c..0000000000000 --- a/boards/st/nucleo_f412zg/Kconfig.defconfig +++ /dev/null @@ -1,18 +0,0 @@ -# NUCLEO-144 F412ZG board configuration - -# Copyright (c) 2017 Florian Vaussard, HEIG-VD -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_NUCLEO_F412ZG - -if NETWORKING - -config USB_DEVICE_STACK - default y - -config USB_DEVICE_NETWORK_ECM - default y - -endif # NETWORKING - -endif # BOARD_NUCLEO_F412ZG diff --git a/boards/st/nucleo_f412zg/nucleo_f412zg.yaml b/boards/st/nucleo_f412zg/nucleo_f412zg.yaml index 10fd21fc7051d..8164af0e6a6f0 100644 --- a/boards/st/nucleo_f412zg/nucleo_f412zg.yaml +++ b/boards/st/nucleo_f412zg/nucleo_f412zg.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/boards/st/nucleo_f413zh/Kconfig.defconfig b/boards/st/nucleo_f413zh/Kconfig.defconfig deleted file mode 100644 index 34fb8d5696157..0000000000000 --- a/boards/st/nucleo_f413zh/Kconfig.defconfig +++ /dev/null @@ -1,18 +0,0 @@ -# NUCLEO-144 F413ZH board configuration - -# Copyright (c) 2017 Florian Vaussard, HEIG-VD -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_NUCLEO_F413ZH - -if NETWORKING - -config USB_DEVICE_STACK - default y - -config USB_DEVICE_NETWORK_ECM - default y - -endif # NETWORKING - -endif # BOARD_NUCLEO_F413ZH diff --git a/boards/st/nucleo_f413zh/nucleo_f413zh.yaml b/boards/st/nucleo_f413zh/nucleo_f413zh.yaml index 4a8dda323d2f6..e9471e007eabf 100644 --- a/boards/st/nucleo_f413zh/nucleo_f413zh.yaml +++ b/boards/st/nucleo_f413zh/nucleo_f413zh.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 320 flash: 1536 supported: diff --git a/boards/st/nucleo_f429zi/nucleo_f429zi.dts b/boards/st/nucleo_f429zi/nucleo_f429zi.dts index 29a36b1155573..d05081ed8396f 100644 --- a/boards/st/nucleo_f429zi/nucleo_f429zi.dts +++ b/boards/st/nucleo_f429zi/nucleo_f429zi.dts @@ -90,7 +90,7 @@ &adc1 { pinctrl-0 = <&adc1_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f429zi/nucleo_f429zi.yaml b/boards/st/nucleo_f429zi/nucleo_f429zi.yaml index bec17951950bc..71b0fcbe4be21 100644 --- a/boards/st/nucleo_f429zi/nucleo_f429zi.yaml +++ b/boards/st/nucleo_f429zi/nucleo_f429zi.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 2048 supported: diff --git a/boards/st/nucleo_f446re/nucleo_f446re.yaml b/boards/st/nucleo_f446re/nucleo_f446re.yaml index 9d45982d995d8..b7e2d714cf40d 100644 --- a/boards/st/nucleo_f446re/nucleo_f446re.yaml +++ b/boards/st/nucleo_f446re/nucleo_f446re.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/st/nucleo_f446ze/nucleo_f446ze.dts b/boards/st/nucleo_f446ze/nucleo_f446ze.dts index 5eaad0ca83db5..df262a6f73ef3 100644 --- a/boards/st/nucleo_f446ze/nucleo_f446ze.dts +++ b/boards/st/nucleo_f446ze/nucleo_f446ze.dts @@ -87,7 +87,7 @@ &adc1 { pinctrl-0 = <&adc1_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f446ze/nucleo_f446ze.yaml b/boards/st/nucleo_f446ze/nucleo_f446ze.yaml index cf62cdd7712d4..73e4252613f21 100644 --- a/boards/st/nucleo_f446ze/nucleo_f446ze.yaml +++ b/boards/st/nucleo_f446ze/nucleo_f446ze.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/st/nucleo_f722ze/nucleo_f722ze.dts b/boards/st/nucleo_f722ze/nucleo_f722ze.dts index 988a1204a9fdd..00faeae1dbc2e 100644 --- a/boards/st/nucleo_f722ze/nucleo_f722ze.dts +++ b/boards/st/nucleo_f722ze/nucleo_f722ze.dts @@ -102,7 +102,7 @@ &adc1 { pinctrl-0 = <&adc1_in3_pa3 &adc1_in10_pc0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f722ze/nucleo_f722ze.yaml b/boards/st/nucleo_f722ze/nucleo_f722ze.yaml index 4286f55eca9a1..4af91c9e44b6e 100644 --- a/boards/st/nucleo_f722ze/nucleo_f722ze.yaml +++ b/boards/st/nucleo_f722ze/nucleo_f722ze.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/st/nucleo_f746zg/nucleo_f746zg.dts b/boards/st/nucleo_f746zg/nucleo_f746zg.dts index 90c4b4409a0eb..65416d66d529c 100644 --- a/boards/st/nucleo_f746zg/nucleo_f746zg.dts +++ b/boards/st/nucleo_f746zg/nucleo_f746zg.dts @@ -176,7 +176,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f746zg/nucleo_f746zg.yaml b/boards/st/nucleo_f746zg/nucleo_f746zg.yaml index ce8b0322fcd3e..affa0ccc2dfb4 100644 --- a/boards/st/nucleo_f746zg/nucleo_f746zg.yaml +++ b/boards/st/nucleo_f746zg/nucleo_f746zg.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/boards/st/nucleo_f756zg/nucleo_f756zg.yaml b/boards/st/nucleo_f756zg/nucleo_f756zg.yaml index 4b12d824b3beb..8b572e86c470e 100644 --- a/boards/st/nucleo_f756zg/nucleo_f756zg.yaml +++ b/boards/st/nucleo_f756zg/nucleo_f756zg.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/boards/st/nucleo_f767zi/nucleo_f767zi.dts b/boards/st/nucleo_f767zi/nucleo_f767zi.dts index 4125f4e6bde13..c7a113fdfcf56 100644 --- a/boards/st/nucleo_f767zi/nucleo_f767zi.dts +++ b/boards/st/nucleo_f767zi/nucleo_f767zi.dts @@ -171,7 +171,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/nucleo_f767zi/nucleo_f767zi.yaml b/boards/st/nucleo_f767zi/nucleo_f767zi.yaml index 1ca2d19993fb7..d23ca5a333691 100644 --- a/boards/st/nucleo_f767zi/nucleo_f767zi.yaml +++ b/boards/st/nucleo_f767zi/nucleo_f767zi.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 2048 supported: diff --git a/boards/st/nucleo_g031k8/nucleo_g031k8.yaml b/boards/st/nucleo_g031k8/nucleo_g031k8.yaml index 34ea35189abd4..afc7f150c30ea 100644 --- a/boards/st/nucleo_g031k8/nucleo_g031k8.yaml +++ b/boards/st/nucleo_g031k8/nucleo_g031k8.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/st/nucleo_g070rb/doc/index.rst b/boards/st/nucleo_g070rb/doc/index.rst index f15d559403ca9..2dc826765aca0 100644 --- a/boards/st/nucleo_g070rb/doc/index.rst +++ b/boards/st/nucleo_g070rb/doc/index.rst @@ -33,7 +33,6 @@ Nucleo G070RB provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -54,11 +53,6 @@ Nucleo G070RB provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32G070RB can be found here: diff --git a/boards/st/nucleo_g070rb/nucleo_g070rb.dts b/boards/st/nucleo_g070rb/nucleo_g070rb.dts index d0491570d1dee..bfbcfbc27f2e2 100644 --- a/boards/st/nucleo_g070rb/nucleo_g070rb.dts +++ b/boards/st/nucleo_g070rb/nucleo_g070rb.dts @@ -139,7 +139,7 @@ &adc1 { pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; vref-mv = <3300>; diff --git a/boards/st/nucleo_g070rb/nucleo_g070rb.yaml b/boards/st/nucleo_g070rb/nucleo_g070rb.yaml index 6cac29d4db124..7aae67d18d22e 100644 --- a/boards/st/nucleo_g070rb/nucleo_g070rb.yaml +++ b/boards/st/nucleo_g070rb/nucleo_g070rb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 36 flash: 128 supported: diff --git a/boards/st/nucleo_g070rb/st_morpho_connector.dtsi b/boards/st/nucleo_g070rb/st_morpho_connector.dtsi index e3c04c7ecb087..30d474478f69a 100644 --- a/boards/st/nucleo_g070rb/st_morpho_connector.dtsi +++ b/boards/st/nucleo_g070rb/st_morpho_connector.dtsi @@ -17,9 +17,9 @@ , , , - , - , - , + , + , + , , , , diff --git a/boards/st/nucleo_g071rb/doc/index.rst b/boards/st/nucleo_g071rb/doc/index.rst index 0ab38d78118ec..b7f778ac2c4f0 100644 --- a/boards/st/nucleo_g071rb/doc/index.rst +++ b/boards/st/nucleo_g071rb/doc/index.rst @@ -33,7 +33,6 @@ Nucleo G071RB provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -54,11 +53,6 @@ Nucleo G071RB provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32G071RB can be found here: diff --git a/boards/st/nucleo_g071rb/nucleo_g071rb.dts b/boards/st/nucleo_g071rb/nucleo_g071rb.dts index 553feebd2e959..902c30dc43acd 100644 --- a/boards/st/nucleo_g071rb/nucleo_g071rb.dts +++ b/boards/st/nucleo_g071rb/nucleo_g071rb.dts @@ -147,7 +147,7 @@ <&rcc STM32_SRC_SYSCLK ADC_SEL(0)>; pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; vref-mv = <3300>; diff --git a/boards/st/nucleo_g071rb/nucleo_g071rb.yaml b/boards/st/nucleo_g071rb/nucleo_g071rb.yaml index 8caf70832cded..756d570914f29 100644 --- a/boards/st/nucleo_g071rb/nucleo_g071rb.yaml +++ b/boards/st/nucleo_g071rb/nucleo_g071rb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 36 flash: 128 supported: diff --git a/boards/st/nucleo_g071rb/st_morpho_connector.dtsi b/boards/st/nucleo_g071rb/st_morpho_connector.dtsi index e3c04c7ecb087..30d474478f69a 100644 --- a/boards/st/nucleo_g071rb/st_morpho_connector.dtsi +++ b/boards/st/nucleo_g071rb/st_morpho_connector.dtsi @@ -17,9 +17,9 @@ , , , - , - , - , + , + , + , , , , diff --git a/boards/st/nucleo_g0b1re/nucleo_g0b1re.dts b/boards/st/nucleo_g0b1re/nucleo_g0b1re.dts index d86d7c6ae8eea..75ee749e603e4 100644 --- a/boards/st/nucleo_g0b1re/nucleo_g0b1re.dts +++ b/boards/st/nucleo_g0b1re/nucleo_g0b1re.dts @@ -163,7 +163,7 @@ zephyr_udc0: &usb { &adc1 { pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_g0b1re/nucleo_g0b1re.yaml b/boards/st/nucleo_g0b1re/nucleo_g0b1re.yaml index f08da37e7609f..629da4c0df687 100644 --- a/boards/st/nucleo_g0b1re/nucleo_g0b1re.yaml +++ b/boards/st/nucleo_g0b1re/nucleo_g0b1re.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 144 flash: 512 supported: diff --git a/boards/st/nucleo_g0b1re/st_morpho_connector.dtsi b/boards/st/nucleo_g0b1re/st_morpho_connector.dtsi index e3c04c7ecb087..30d474478f69a 100644 --- a/boards/st/nucleo_g0b1re/st_morpho_connector.dtsi +++ b/boards/st/nucleo_g0b1re/st_morpho_connector.dtsi @@ -17,9 +17,9 @@ , , , - , - , - , + , + , + , , , , diff --git a/boards/st/nucleo_g431kb/nucleo_g431kb.yaml b/boards/st/nucleo_g431kb/nucleo_g431kb.yaml index eb396a45f570c..833a279f73f25 100644 --- a/boards/st/nucleo_g431kb/nucleo_g431kb.yaml +++ b/boards/st/nucleo_g431kb/nucleo_g431kb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 128 supported: diff --git a/boards/st/nucleo_g431rb/nucleo_g431rb.yaml b/boards/st/nucleo_g431rb/nucleo_g431rb.yaml index 71ca5707ac58b..7d1ffe6364ace 100644 --- a/boards/st/nucleo_g431rb/nucleo_g431rb.yaml +++ b/boards/st/nucleo_g431rb/nucleo_g431rb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 128 supported: diff --git a/boards/st/nucleo_g474re/nucleo_g474re.dts b/boards/st/nucleo_g474re/nucleo_g474re.dts index a91ec3ccb6034..a315266113127 100644 --- a/boards/st/nucleo_g474re/nucleo_g474re.dts +++ b/boards/st/nucleo_g474re/nucleo_g474re.dts @@ -203,7 +203,7 @@ stm32_lp_tick_source: &lptim1 { &adc1 { pinctrl-0 = <&adc1_in1_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_g474re/nucleo_g474re.yaml b/boards/st/nucleo_g474re/nucleo_g474re.yaml index 26c4254294ffe..77cb58a31b0e2 100644 --- a/boards/st/nucleo_g474re/nucleo_g474re.yaml +++ b/boards/st/nucleo_g474re/nucleo_g474re.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 512 supported: diff --git a/boards/st/nucleo_h533re/nucleo_h533re.dts b/boards/st/nucleo_h533re/nucleo_h533re.dts index 66fade7dcd2ab..7ca0c23ddea3f 100644 --- a/boards/st/nucleo_h533re/nucleo_h533re.dts +++ b/boards/st/nucleo_h533re/nucleo_h533re.dts @@ -132,7 +132,7 @@ <&rcc STM32_SRC_HCLK ADCDAC_SEL(0)>; pinctrl-0 = <&adc1_inp0_pa0>; /* Arduino A0 */ pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <8>; status = "okay"; }; diff --git a/boards/st/nucleo_h563zi/doc/index.rst b/boards/st/nucleo_h563zi/doc/index.rst index c53d2f267cf36..da88685959cf3 100644 --- a/boards/st/nucleo_h563zi/doc/index.rst +++ b/boards/st/nucleo_h563zi/doc/index.rst @@ -167,6 +167,8 @@ The Zephyr nucleo_h563zi board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | I2C | on-chip | i2c bus | +-----------+------------+-------------------------------------+ +| I3C | on-chip | i3c bus | ++-----------+------------+-------------------------------------+ | UART | on-chip | serial port-polling; | | | | serial port-interrupt | +-----------+------------+-------------------------------------+ @@ -222,6 +224,7 @@ Default Zephyr Peripheral Mapping: - SPI1 SCK/MISO/MOSI/CS: PA5/PG9/PB5/PD14 - UART3 TX/RX : PD8/PD9 (VCP) - USER_PB : PC13 +- I3C1: PD12(SCL) & PD13(SDA) System Clock ------------ diff --git a/boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi b/boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi index 246e93926ccba..5c5cecdf40720 100644 --- a/boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi +++ b/boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi @@ -78,6 +78,13 @@ status = "okay"; }; +&i3c1 { + pinctrl-0 = <&i3c1_scl_pd12 &i3c1_sda_pd13>; + pinctrl-names = "default"; + i3c-scl-hz = <12500000>; + status = "okay"; +}; + &rcc { clocks = <&pll>; clock-frequency = ; @@ -149,7 +156,7 @@ <&rcc STM32_SRC_HCLK ADCDAC_SEL(0)>; pinctrl-0 = <&adc1_inp3_pa6 &adc1_inp15_pa3>; /* Zio A0, Zio D35 */ pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <6>; status = "okay"; }; diff --git a/boards/st/nucleo_h563zi/nucleo_h563zi.yaml b/boards/st/nucleo_h563zi/nucleo_h563zi.yaml index dbaa88e7de6d5..d8db97fe4a3cc 100644 --- a/boards/st/nucleo_h563zi/nucleo_h563zi.yaml +++ b/boards/st/nucleo_h563zi/nucleo_h563zi.yaml @@ -25,4 +25,5 @@ supported: - usb_device - rtc - i2c + - i3c vendor: st diff --git a/boards/st/nucleo_h723zg/Kconfig.defconfig b/boards/st/nucleo_h723zg/Kconfig.defconfig index d6d1af51e767b..b65c015d77747 100644 --- a/boards/st/nucleo_h723zg/Kconfig.defconfig +++ b/boards/st/nucleo_h723zg/Kconfig.defconfig @@ -12,8 +12,4 @@ config NET_L2_ETHERNET endif # NETWORKING -config USB_DC_HAS_HS_SUPPORT - default y - depends on USB_DC_STM32 - endif # BOARD_NUCLEO_H723ZG diff --git a/boards/st/nucleo_h723zg/nucleo_h723zg.yaml b/boards/st/nucleo_h723zg/nucleo_h723zg.yaml index 66161b5b9ff70..9ad2b83ba52c6 100644 --- a/boards/st/nucleo_h723zg/nucleo_h723zg.yaml +++ b/boards/st/nucleo_h723zg/nucleo_h723zg.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 372 flash: 1024 supported: diff --git a/boards/st/nucleo_h743zi/nucleo_h743zi.dts b/boards/st/nucleo_h743zi/nucleo_h743zi.dts index cc7122b593567..cd47bf9794c0b 100644 --- a/boards/st/nucleo_h743zi/nucleo_h743zi.dts +++ b/boards/st/nucleo_h743zi/nucleo_h743zi.dts @@ -150,7 +150,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_inp15_pa3>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -162,7 +162,7 @@ zephyr_udc0: &usbotg_fs { &adc3 { pinctrl-0 = <&adc3_inp5_pf3>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_h743zi/nucleo_h743zi.yaml b/boards/st/nucleo_h743zi/nucleo_h743zi.yaml index 8a315b337f5df..e76eb486524a0 100644 --- a/boards/st/nucleo_h743zi/nucleo_h743zi.yaml +++ b/boards/st/nucleo_h743zi/nucleo_h743zi.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 2048 supported: diff --git a/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m4.yaml b/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m4.yaml index b17c6d7963bc1..0cfd777c0c37c 100644 --- a/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m4.yaml +++ b/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m4.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 288 flash: 1024 supported: diff --git a/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m7.dts b/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m7.dts index b9ddb37cb7962..c79712968e1bc 100644 --- a/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m7.dts +++ b/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m7.dts @@ -26,6 +26,7 @@ zephyr,dtcm = &dtcm; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,canbus = &fdcan1; }; pwmleds { diff --git a/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m7.yaml b/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m7.yaml index 259cd29438b66..d11a42ae21156 100644 --- a/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m7.yaml +++ b/boards/st/nucleo_h745zi_q/nucleo_h745zi_q_stm32h745xx_m7.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 1024 supported: diff --git a/boards/st/nucleo_h753zi/nucleo_h753zi.dts b/boards/st/nucleo_h753zi/nucleo_h753zi.dts index d4217cfae580f..83ee70c171de7 100644 --- a/boards/st/nucleo_h753zi/nucleo_h753zi.dts +++ b/boards/st/nucleo_h753zi/nucleo_h753zi.dts @@ -147,7 +147,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_inp15_pa3>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_h753zi/nucleo_h753zi.yaml b/boards/st/nucleo_h753zi/nucleo_h753zi.yaml index 7bca456c26e66..9574f9fe75ef3 100644 --- a/boards/st/nucleo_h753zi/nucleo_h753zi.yaml +++ b/boards/st/nucleo_h753zi/nucleo_h753zi.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 2048 supported: diff --git a/boards/st/nucleo_h7a3zi_q/nucleo_h7a3zi_q.dts b/boards/st/nucleo_h7a3zi_q/nucleo_h7a3zi_q.dts index 410bd0b690425..71ee9ccf017b5 100644 --- a/boards/st/nucleo_h7a3zi_q/nucleo_h7a3zi_q.dts +++ b/boards/st/nucleo_h7a3zi_q/nucleo_h7a3zi_q.dts @@ -116,7 +116,7 @@ &adc1 { pinctrl-0 = <&adc1_inp15_pa3>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml b/boards/st/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml index 65cd30b3e0b92..34a554f3b7a78 100644 --- a/boards/st/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml +++ b/boards/st/nucleo_h7a3zi_q/nucleo_h7a3zi_q.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 1280 flash: 2048 supported: diff --git a/boards/st/nucleo_h7s3l8/Kconfig.defconfig b/boards/st/nucleo_h7s3l8/Kconfig.defconfig new file mode 100644 index 0000000000000..fdb5f99d840cf --- /dev/null +++ b/boards/st/nucleo_h7s3l8/Kconfig.defconfig @@ -0,0 +1,16 @@ +# STM32H7S3L8 NUCLEO board configuration +# +# Copyright (c) 2024 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NUCLEO_H7S3L8 + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # BOARD_NUCLEO_H7S3L8 diff --git a/boards/st/nucleo_h7s3l8/Kconfig.nucleo_h7s3l8 b/boards/st/nucleo_h7s3l8/Kconfig.nucleo_h7s3l8 new file mode 100644 index 0000000000000..ef9af59919b8d --- /dev/null +++ b/boards/st/nucleo_h7s3l8/Kconfig.nucleo_h7s3l8 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_H7S3L8 + select SOC_STM32H7S3XX diff --git a/boards/st/nucleo_h7s3l8/arduino_r3_connector.dtsi b/boards/st/nucleo_h7s3l8/arduino_r3_connector.dtsi new file mode 100644 index 0000000000000..13e390200fd43 --- /dev/null +++ b/boards/st/nucleo_h7s3l8/arduino_r3_connector.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 3 0>, /* A0 */ + <1 0 &gpioc 0 0>, /* A1 */ + <2 0 &gpioc 3 0>, /* A2 */ + <3 0 &gpioc 4 0>, /* A3 */ + <4 0 &gpioc 5 0>, /* A4 */ + <5 0 &gpiof 11 0>, /* A5 */ + <6 0 &gpioa 10 0>, /* D0 */ + <7 0 &gpiob 14 0>, /* D1 */ + <8 0 &gpiof 15 0>, /* D2 */ + <9 0 &gpioe 13 0>, /* D3 */ + <10 0 &gpiof 3 0>, /* D4 */ + <11 0 &gpioe 11 0>, /* D5 */ + <12 0 &gpioe 9 0>, /* D6 */ + <13 0 &gpiof 4 0>, /* D7 */ + <14 0 &gpiof 5 0>, /* D8 */ + <15 0 &gpiod 15 0>, /* D9 */ + <16 0 &gpiod 14 0>, /* D10 */ + <17 0 &gpiob 5 0>, /* D11 */ + <18 0 &gpioa 6 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 9 0>, /* D14 */ + <21 0 &gpiob 8 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c1 {}; +arduino_spi: &spi1 {}; +arduino_serial: &usart1 {}; diff --git a/boards/st/nucleo_h7s3l8/board.cmake b/boards/st/nucleo_h7s3l8/board.cmake new file mode 100644 index 0000000000000..6c18b45b35edc --- /dev/null +++ b/boards/st/nucleo_h7s3l8/board.cmake @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +# keep first +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") + +board_runner_args(openocd --target-handle=_CHIPNAME.cpu0) + +# keep first +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/st/nucleo_h7s3l8/board.yml b/boards/st/nucleo_h7s3l8/board.yml new file mode 100644 index 0000000000000..6d71cded43f10 --- /dev/null +++ b/boards/st/nucleo_h7s3l8/board.yml @@ -0,0 +1,6 @@ +board: + name: nucleo_h7s3l8 + full_name: Nucleo H7S3L8 + vendor: st + socs: + - name: stm32h7s3xx diff --git a/boards/st/nucleo_h7s3l8/doc/img/nucleo_h7s3l8.webp b/boards/st/nucleo_h7s3l8/doc/img/nucleo_h7s3l8.webp new file mode 100644 index 0000000000000..af2535e26b253 Binary files /dev/null and b/boards/st/nucleo_h7s3l8/doc/img/nucleo_h7s3l8.webp differ diff --git a/boards/st/nucleo_h7s3l8/doc/index.rst b/boards/st/nucleo_h7s3l8/doc/index.rst new file mode 100644 index 0000000000000..4d24bb9afe50d --- /dev/null +++ b/boards/st/nucleo_h7s3l8/doc/index.rst @@ -0,0 +1,316 @@ +.. zephyr:board:: nucleo_h7s3l8 + +Overview +******** + +The STM32 Nucleo-144 board provides an affordable and flexible way for users +to try out new concepts and build prototypes by choosing from the various combinations +of performance and power consumption features, provided by the STM32 microcontroller. + +The ST Zio connector, which extends the ARDUINOÂŽ Uno V3 connectivity, and +the ST morpho headers provide an easy means of expanding the functionality of the Nucleo +open development platform with a wide choice of specialized shields. +The STM32 Nucleo-144 board does not require any separate probe as it integrates +the ST-LINK V3 debugger/programmer. + +The STM32 Nucleo-144 board comes with the STM32 comprehensive free software +libraries and examples available with the STM32Cube MCU Package. + +Key Features + +- STM32 microcontroller with 64Kbytes of flash and 620Kbytes of RAM in TFBGA225 package +- Ethernet compliant with IEEE-802.3-2002 +- USB USB Device only, USB OTG full speed, or SNK/UFP (full-speed or high-speed mode) +- 3 user LEDs +- 2 user and reset push-buttons +- 32.768 kHz crystal oscillator +- Board connectors: + + - USB with Micro-AB or USB Type-CÂŽ + - Ethernet RJ45 + - MIPI20 compatible connector with trace signals + +- Flexible power-supply options: ST-LINK USB VBUS or external sources +- External or internal SMPS to generate Vcore logic supply +- On-board ST-LINK/V3 debugger/programmer with USB re-enumeration +- capability: mass storage, virtual COM port and debug port + +More information about the board can be found at the `Nucleo H7S3L8 website`_. + +Hardware +******** + +Nucleo H7S3L8 provides the following hardware components: + +The STM32H7S7xx devices are a high-performance microcontrollers family (STM32H7 +Series) based on the high-performance Arm |reg| Cortex |reg|-M7 32-bit RISC core. +They operate at a frequency of up to 500 MHz. + +- Core: ARM |reg| 32-bit Cortex |reg| -M7 CPU with TrustZone |reg| and FPU. +- Performance benchmark: + + - 1284 DMPIS/MHz (Dhrystone 2.1) + +- Security + + - Arm |reg| TrustZone |reg| with ARMv8-M mainline security extension + - Up to 8 configurable SAU regions + - TrustZone |reg| aware and securable peripherals + - Flexible lifecycle scheme with secure debug authentication + - Preconfigured immutable root of trust (ST-iROT) + - SFI (secure firmware installation) + - Secure data storage with hardware unique key (HUK) + - Secure firmware upgrade support with TF-M + - 2x AES coprocessors including one with DPA resistance + - Public key accelerator, DPA resistant + - On-the-fly decryption of Octo-SPI external memories + - HASH hardware accelerator + - True random number generator, NIST SP800-90B compliant + - 96-bit unique ID + - Active tampers + - True Random Number Generator (RNG) NIST SP800-90B compliant + +- Clock management: + + - 24 MHz crystal oscillator (HSE) + - 32768 Hz crystal oscillator for RTC (LSE) + - Internal 64 MHz (HSI) trimmable by software + - Internal low-power 32 kHz RC (LSI)( |plusminus| 5%) + - Internal 4 MHz oscillator (CSI), trimmable by software + - Internal 48 MHz (HSI48) with recovery system + - 3 PLLs for system clock, USB, audio, ADC + +- Power management + + - Embedded regulator (LDO) with three configurable range output to supply the digital circuitry + + +- RTC with HW calendar, alarms and calibration +- Up to 152 fast I/Os, most 5 V-tolerant, up to 10 I/Os with independent supply down to 1.08 V +- Up to 16 timers and 2 watchdogs + + - 16x 16-bit + - 4x 32-bit timers with up to 4 IC/OC/PWM or pulse counter and quadrature (incremental) encoder input + - 5x 16-bit low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - 1x SysTick timer + +- Memories + + - Up to 64KB Flash, 2 banks read-while-write + - 1 Kbyte OTP (one-time programmable) + - 640 KB of SRAM including 64 KB with hardware parity check and 320 Kbytes with flexible ECC + - 4 Kbytes of backup SRAM available in the lowest power modes + - Flexible external memory controller with up to 16-bit data bus: SRAM, PSRAM, FRAM, SDRAM/LPSDR SDRAM, NOR/NAND memories + - 2x OCTOSPI memory interface with on-the-fly decryption and support for serial PSRAM/NAND/NOR, Hyper RAM/Flash frame formats + - 1x HEXASPI memory interface with on-the-fly decryption and support for serial PSRAM/NAND/NOR, Hyper RAM/Flash frame formats + - 2x SD/SDIO/MMC interfaces + +- Rich analog peripherals (independent supply) + + - 2x 12-bit ADC with up to 5 MSPS in 12-bit + - 1x Digital temperature sensor + +- 35x communication interfaces + + - 1x USB Type-C / USB power-delivery controller + - 1x USB OTG full-speed with PHY + - 1x USB OTG high-speed with PHY + - 3x I2C FM+ interfaces (SMBus/PMBus) + - 1x I3C interface + - 7x U(S)ARTS (ISO7816 interface, LIN, IrDA, modem control) + - 2x LP UART + - 6x SPIs including 3 muxed with full-duplex I2S + - 2x SAI + - 2x FDCAN + - 2x SD/SDIO/MMC interface + - 2x 16 channel DMA controllers + - 1x 8- to 16- bit camera interface + - 1x HDMI-CEC + - 1x Ethernel MAC interface with DMA controller + - 1x 16-bit parallel slave synchronous-interface + - 1x SPDIF-IN interface + - 1x MDIO slave interface + +- CORDIC for trigonometric functions acceleration +- FMAC (filter mathematical accelerator) +- CRC calculation unit +- Development support: serial wire debug (SWD), JTAG, Embedded Trace Macrocell |trade| + + + +More information about STM32H7S3 can be found here: + +- `STM32H7S3L8 on www.st.com`_ +- `STM32H7Sx reference manual`_ + + +Supported Features +================== + +The Zephyr ``nucleo_h7s3l8`` board target supports the following hardware +features: + ++-------------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++=============+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-------------+------------+-------------------------------------+ +| UART | on-chip | serial port | ++-------------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-------------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-------------+------------+-------------------------------------+ +| RTC | on-chip | counter | ++-------------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-------------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-------------+------------+-------------------------------------+ +| PWM | on-chip | pwm | ++-------------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-------------+------------+-------------------------------------+ +| Backup SRAM | on-chip | Backup SRAM | ++-------------+------------+-------------------------------------+ +| RTC | on-chip | rtc | ++-------------+------------+-------------------------------------+ + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration can be found in the defconfig files: +:zephyr_file:`boards/st/nucleo_h7s3l8/nucleo_h7s3l8_defconfig` + +For more details please refer to `STM32H7R/S Nucleo-144 board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +The Nucleo H7S3L8 board features a ST Zio connector (extended Arduino Uno V3) +and a ST morpho connector. Board is configured as follows: + +- UART_3 TX/RX : PD8/PD9 (ST-Link Virtual Port Com) +- USER_PB : PC13 +- LD1 : PD10 +- LD2 : PD13 +- LD3 : PB7 +- I2C : PB8, PB9 +- SPI1 NSS/SCK/MISO/MOSI : PD14PA5/PA6/PB5 (Arduino SPI) + +System Clock +------------ + +Nucleo H7S3L8 System Clock could be driven by an internal or external +oscillator, as well as the main PLL clock. By default, the System clock is +driven by the PLL clock at 600MHz, driven by an 24MHz high-speed external clock. + +Serial Port +----------- + +Nucleo H7S3L8 board has 4 UARTs and 3 USARTs plus one LowPower UART. The Zephyr console +output is assigned to UART3. Default settings are 115200 8N1. + +Backup SRAM +----------- + +In order to test backup SRAM you may want to disconnect VBAT from VDD. You can +do it by removing ``SB13`` jumper on the back side of the board. + +Programming and Debugging +************************* + +Nucleo H7S3L8 board includes an ST-LINK/V3 embedded debug tool interface. + +.. note:: + + Check if your ST-LINK V3 has newest FW version. It can be done with `STM32CubeProgrammer`_ + +Flashing +======== + +The board is configured to be flashed using west `STM32CubeProgrammer`_ runner, +so its :ref:`installation ` is required. + +Alternatively, OpenOCD or JLink can also be used to flash the board using +the ``--runner`` (or ``-r``) option: + +.. code-block:: console + + $ west flash --runner openocd + +Flashing an application to Nucleo H7S3L8 +---------------------------------------- + +First, connect the NUCLEO-H7S3L8 to your host computer using +the USB port to prepare it for flashing. Then build and flash your application. + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +Run a serial host program to connect with your NUCLEO-H7S3L8 board. + +.. code-block:: console + + $ minicom -b 115200 -D /dev/ttyACM0 + +or use screen: + +.. code-block:: console + + $ screen /dev/ttyACM0 115200 + +Build and flash the application: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_h7s3l8 + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + $ Hello World! nucleo_h7s3l8 + +Blinky example can also be used: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: nucleo_h7s3l8 + :goals: build flash + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_h7s3l8 + :maybe-skip-config: + :goals: debug + +.. _Nucleo H7S3L8 website: + https://www.st.com/en/evaluation-tools/nucleo-h7s3l8.html + +.. _STM32H7R/S Nucleo-144 board User Manual: + https://www.st.com/resource/en/user_manual/um3276-stm32h7rx7sx-nucleo144-board-mb1737-stmicroelectronics.pdf + +.. _STM32H7S3L8 on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32h7s3l8.html + +.. _STM32H7Sx reference manual: + https://www.st.com/resource/en/reference_manual/rm0477-stm32h7rx7sx-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _OpenOCD installing Debug Version: + https://github.com/zephyrproject-rtos/openocd + +.. _OpenOCD installing with ST-LINK V3 support: + https://mbd.kleier.net/integrating-st-link-v3.html + +.. _STM32CubeIDE: + https://www.st.com/en/development-tools/stm32cubeide.html + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/nucleo_h7s3l8/nucleo_h7s3l8.dts b/boards/st/nucleo_h7s3l8/nucleo_h7s3l8.dts new file mode 100644 index 0000000000000..e5d817bea578d --- /dev/null +++ b/boards/st/nucleo_h7s3l8/nucleo_h7s3l8.dts @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "arduino_r3_connector.dtsi" +#include + +/ { + model = "STMicroelectronics STM32H7S3L8-NUCLEO board"; + compatible = "st,stm32h7s3l8-nucleo"; + + chosen { + zephyr,console = &usart3; + zephyr,shell-uart = &usart3; + zephyr,dtcm = &dtcm; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds: leds { + compatible = "gpio-leds"; + green_led: led_1 { + gpios = <&gpiod 10 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + yellow_led: led_2 { + gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + red_led: led_3 { + gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>; + label = "User LD3"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button: button_0 { + label = "User"; + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &green_led; + led1 = &yellow_led; + led2 = &red_led; + sw0 = &user_button; + watchdog0 = &iwdg; + }; +}; + +&clk_lsi { + status = "disabled"; +}; + +&clk_hsi48 { + status = "disabled"; +}; + +&clk_hse { + clock-frequency = ; + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&pll { + div-m = <12>; + mul-n = <200>; + div-p = <2>; + div-q = <2>; + div-r = <2>; + div-s = <2>; + div-t = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + dcpre = <1>; + hpre = <1>; + ppre1 = <2>; + ppre2 = <2>; + ppre4 = <2>; + ppre5 = <2>; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pb14 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart3 { + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&wwdg { + status = "okay"; +}; + +&adc1 { + pinctrl-0 = <&adc1_inp15_pa3>; /* Arduino A0 */ + pinctrl-names = "default"; + st,adc-clock-source = "SYNC"; + st,adc-prescaler = <4>; + status = "okay"; +}; + +&spi1 { + status = "okay"; + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pb5>; + pinctrl-names = "default"; + cs-gpios = <&gpiod 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; diff --git a/boards/st/nucleo_h7s3l8/nucleo_h7s3l8.yaml b/boards/st/nucleo_h7s3l8/nucleo_h7s3l8.yaml new file mode 100644 index 0000000000000..f7b72a70d9237 --- /dev/null +++ b/boards/st/nucleo_h7s3l8/nucleo_h7s3l8.yaml @@ -0,0 +1,15 @@ +identifier: nucleo_h7s3l8 +name: ST Nucleo H7S3L8 nucleo +type: mcu +arch: arm +toolchain: + - zephyr +ram: 640 +flash: 64 +supported: + - gpio + - uart + - watchdog + - entropy + - adc +vendor: st diff --git a/boards/st/nucleo_h7s3l8/nucleo_h7s3l8_defconfig b/boards/st/nucleo_h7s3l8/nucleo_h7s3l8_defconfig new file mode 100644 index 0000000000000..3ed77fa885c1e --- /dev/null +++ b/boards/st/nucleo_h7s3l8/nucleo_h7s3l8_defconfig @@ -0,0 +1,21 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +# Disable SMPS +CONFIG_POWER_SUPPLY_DIRECT_SMPS=n + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y diff --git a/boards/st/nucleo_h7s3l8/support/openocd.cfg b/boards/st/nucleo_h7s3l8/support/openocd.cfg new file mode 100644 index 0000000000000..af84952d31d21 --- /dev/null +++ b/boards/st/nucleo_h7s3l8/support/openocd.cfg @@ -0,0 +1,42 @@ + +source [find interface/stlink-dap.cfg] +transport select "dapdirect_swd" + +set WORKAREASIZE 0x8000 +set CHIPNAME STM32H7S3XX +set BOARDNAME NUCLEO-H7S3L8 + +# Enable debug when in low power modes +set ENABLE_LOW_POWER 1 + +# Stop Watchdog counters when halt +set STOP_WATCHDOG 1 + +# Reset configuration +# use hardware reset, connect under reset +# connect_assert_srst needed if low power mode application running (WFI...) +# reset_config srst_only srst_nogate connect_assert_srst + +#set CONNECT_UNDER_RESET 1 +#set CORE_RESET 0 + +source [find target/stm32h7rx.cfg] + + +$_CHIPNAME.cpu0 configure -event gdb-attach { + echo "Debugger attaching: halting execution" + gdb_breakpoint_override hard +} + +$_CHIPNAME.cpu0 configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +# Due to the use of connect_assert_srst, running gdb requires +# to reset halt just after openocd init. +rename init old_init +proc init {} { + old_init + reset halt +} diff --git a/boards/st/nucleo_l011k4/doc/index.rst b/boards/st/nucleo_l011k4/doc/index.rst index cb8ad43e2ab56..0b61e27b1a961 100644 --- a/boards/st/nucleo_l011k4/doc/index.rst +++ b/boards/st/nucleo_l011k4/doc/index.rst @@ -28,7 +28,6 @@ Nucleo L011K4 provides the following hardware components: - Arduino* Nano V3 connectivity -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -49,11 +48,6 @@ Nucleo L011K4 provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32L011K4 can be found in the `STM32L0x1 reference manual`_ diff --git a/boards/st/nucleo_l011k4/nucleo_l011k4.yaml b/boards/st/nucleo_l011k4/nucleo_l011k4.yaml index 482dc095abb2f..83661ba2eedee 100644 --- a/boards/st/nucleo_l011k4/nucleo_l011k4.yaml +++ b/boards/st/nucleo_l011k4/nucleo_l011k4.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/st/nucleo_l031k6/nucleo_l031k6.yaml b/boards/st/nucleo_l031k6/nucleo_l031k6.yaml index e3ce901c4ee12..f6b155460cc64 100644 --- a/boards/st/nucleo_l031k6/nucleo_l031k6.yaml +++ b/boards/st/nucleo_l031k6/nucleo_l031k6.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/st/nucleo_l053r8/doc/index.rst b/boards/st/nucleo_l053r8/doc/index.rst index 755520a2bfbf9..39d2669ce6d50 100644 --- a/boards/st/nucleo_l053r8/doc/index.rst +++ b/boards/st/nucleo_l053r8/doc/index.rst @@ -29,7 +29,6 @@ Nucleo L053R8 provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -50,11 +49,6 @@ Nucleo L053R8 provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32L053R8 can be found in the `STM32L0x3 reference manual`_ diff --git a/boards/st/nucleo_l053r8/nucleo_l053r8.yaml b/boards/st/nucleo_l053r8/nucleo_l053r8.yaml index 384d529491302..d6e40a30c6259 100644 --- a/boards/st/nucleo_l053r8/nucleo_l053r8.yaml +++ b/boards/st/nucleo_l053r8/nucleo_l053r8.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/st/nucleo_l073rz/doc/index.rst b/boards/st/nucleo_l073rz/doc/index.rst index 401290d90dec0..e6e5f669adb78 100644 --- a/boards/st/nucleo_l073rz/doc/index.rst +++ b/boards/st/nucleo_l073rz/doc/index.rst @@ -29,7 +29,6 @@ Nucleo L073RZ provides the following hardware components: - Arduino* Uno V3 connectivity - ST morpho extension pin headers for full access to all STM32 I/Os -- ARM* mbed* - On-board ST-LINK/V2-1 debugger/programmer with SWD connector: - Selection-mode switch to use the kit as a standalone ST-LINK/V2-1 @@ -50,11 +49,6 @@ Nucleo L073RZ provides the following hardware components: - Mass storage - Debug port -- Support of wide choice of Integrated Development Environments (IDEs) including: - - - IAR - - ARM Keil - - GCC-based IDEs More information about STM32L073RZ can be found in the `STM32L0x3 reference manual`_ diff --git a/boards/st/nucleo_l073rz/nucleo_l073rz.dts b/boards/st/nucleo_l073rz/nucleo_l073rz.dts index eefd8d428e7e2..11db6940d18c7 100644 --- a/boards/st/nucleo_l073rz/nucleo_l073rz.dts +++ b/boards/st/nucleo_l073rz/nucleo_l073rz.dts @@ -140,7 +140,7 @@ stm32_lp_tick_source: &lptim1 { &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_l073rz/nucleo_l073rz.yaml b/boards/st/nucleo_l073rz/nucleo_l073rz.yaml index 2a2ffde92bd78..a5cd4360123ac 100644 --- a/boards/st/nucleo_l073rz/nucleo_l073rz.yaml +++ b/boards/st/nucleo_l073rz/nucleo_l073rz.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 20 flash: 192 supported: diff --git a/boards/st/nucleo_l152re/nucleo_l152re.dts b/boards/st/nucleo_l152re/nucleo_l152re.dts index afcccc8dd01db..d1278873fd88d 100644 --- a/boards/st/nucleo_l152re/nucleo_l152re.dts +++ b/boards/st/nucleo_l152re/nucleo_l152re.dts @@ -124,7 +124,7 @@ &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_l412rb_p/nucleo_l412rb_p.dts b/boards/st/nucleo_l412rb_p/nucleo_l412rb_p.dts index 070260451f395..0ffe454564587 100644 --- a/boards/st/nucleo_l412rb_p/nucleo_l412rb_p.dts +++ b/boards/st/nucleo_l412rb_p/nucleo_l412rb_p.dts @@ -117,7 +117,7 @@ &adc1 { pinctrl-0 = <&adc1_in5_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_l412rb_p/nucleo_l412rb_p.yaml b/boards/st/nucleo_l412rb_p/nucleo_l412rb_p.yaml index 8c663aae01279..c2b8c3822eec2 100644 --- a/boards/st/nucleo_l412rb_p/nucleo_l412rb_p.yaml +++ b/boards/st/nucleo_l412rb_p/nucleo_l412rb_p.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 40 flash: 64 supported: diff --git a/boards/st/nucleo_l432kc/nucleo_l432kc.yaml b/boards/st/nucleo_l432kc/nucleo_l432kc.yaml index 345fcb7e44fa0..dbcb3c7e661b4 100644 --- a/boards/st/nucleo_l432kc/nucleo_l432kc.yaml +++ b/boards/st/nucleo_l432kc/nucleo_l432kc.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 supported: diff --git a/boards/st/nucleo_l433rc_p/nucleo_l433rc_p.yaml b/boards/st/nucleo_l433rc_p/nucleo_l433rc_p.yaml index ee3a41bce02b4..e4f61f712d85b 100644 --- a/boards/st/nucleo_l433rc_p/nucleo_l433rc_p.yaml +++ b/boards/st/nucleo_l433rc_p/nucleo_l433rc_p.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 supported: diff --git a/boards/st/nucleo_l452re/nucleo_l452re.yaml b/boards/st/nucleo_l452re/nucleo_l452re.yaml index 0b3aa645bf495..7cea2149cade5 100644 --- a/boards/st/nucleo_l452re/nucleo_l452re.yaml +++ b/boards/st/nucleo_l452re/nucleo_l452re.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 160 flash: 512 supported: diff --git a/boards/st/nucleo_l452re/nucleo_l452re_common.dtsi b/boards/st/nucleo_l452re/nucleo_l452re_common.dtsi index 8f0d76d9a8651..8db389d90740f 100644 --- a/boards/st/nucleo_l452re/nucleo_l452re_common.dtsi +++ b/boards/st/nucleo_l452re/nucleo_l452re_common.dtsi @@ -121,7 +121,7 @@ */ storage_partition: partition@7c000 { label = "storage"; - reg = <0x0007c000 0x00008000>; + reg = <0x0007c000 0x00004000>; }; }; }; diff --git a/boards/st/nucleo_l452re/nucleo_l452re_stm32l452xx_p.yaml b/boards/st/nucleo_l452re/nucleo_l452re_stm32l452xx_p.yaml index 86e8a58034f76..d4df5c29212bc 100644 --- a/boards/st/nucleo_l452re/nucleo_l452re_stm32l452xx_p.yaml +++ b/boards/st/nucleo_l452re/nucleo_l452re_stm32l452xx_p.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 160 flash: 512 supported: diff --git a/boards/st/nucleo_l476rg/nucleo_l476rg.dts b/boards/st/nucleo_l476rg/nucleo_l476rg.dts index 573c121dfd1a1..ecc5ea5cf7af2 100644 --- a/boards/st/nucleo_l476rg/nucleo_l476rg.dts +++ b/boards/st/nucleo_l476rg/nucleo_l476rg.dts @@ -167,7 +167,7 @@ stm32_lp_tick_source: &lptim1 { &adc1 { pinctrl-0 = <&adc1_in1_pc0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_l476rg/nucleo_l476rg.yaml b/boards/st/nucleo_l476rg/nucleo_l476rg.yaml index d0330751a753b..97821682ab21b 100644 --- a/boards/st/nucleo_l476rg/nucleo_l476rg.yaml +++ b/boards/st/nucleo_l476rg/nucleo_l476rg.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c diff --git a/boards/st/nucleo_l4r5zi/Kconfig.defconfig b/boards/st/nucleo_l4r5zi/Kconfig.defconfig index 31b375e87d2d9..57e21974c165e 100644 --- a/boards/st/nucleo_l4r5zi/Kconfig.defconfig +++ b/boards/st/nucleo_l4r5zi/Kconfig.defconfig @@ -9,14 +9,4 @@ config SPI_STM32_INTERRUPT default y depends on SPI -if NETWORKING - -config USB_DEVICE_STACK - default y - -config USB_DEVICE_NETWORK_EEM - default y - -endif # NETWORKING - endif # BOARD_NUCLEO_L4R5ZI diff --git a/boards/st/nucleo_l4r5zi/nucleo_l4r5zi.dts b/boards/st/nucleo_l4r5zi/nucleo_l4r5zi.dts index 690e4bea360ab..ad1586e43828c 100644 --- a/boards/st/nucleo_l4r5zi/nucleo_l4r5zi.dts +++ b/boards/st/nucleo_l4r5zi/nucleo_l4r5zi.dts @@ -65,6 +65,7 @@ led2 = &red_led_0; sw0 = &user_button; pwm-led0 = &red_pwm_led; + die-temp0 = &die_temp; volt-sensor0 = &vref; volt-sensor1 = &vbat; }; @@ -206,11 +207,15 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in1_pc0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; +&die_temp { + status = "okay"; +}; + &vref { status = "okay"; }; diff --git a/boards/st/nucleo_l4r5zi/nucleo_l4r5zi.yaml b/boards/st/nucleo_l4r5zi/nucleo_l4r5zi.yaml index 5bfd9f26be616..577c8c02b782b 100644 --- a/boards/st/nucleo_l4r5zi/nucleo_l4r5zi.yaml +++ b/boards/st/nucleo_l4r5zi/nucleo_l4r5zi.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_i2c - arduino_gpio diff --git a/boards/st/nucleo_l552ze_q/nucleo_l552ze_q-common.dtsi b/boards/st/nucleo_l552ze_q/nucleo_l552ze_q-common.dtsi index 1e86234718837..e0faedcc8e71d 100644 --- a/boards/st/nucleo_l552ze_q/nucleo_l552ze_q-common.dtsi +++ b/boards/st/nucleo_l552ze_q/nucleo_l552ze_q-common.dtsi @@ -82,7 +82,7 @@ &adc1 { pinctrl-0 = <&adc1_in1_pc0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_n657x0_q/Kconfig.nucleo_n657x0_q b/boards/st/nucleo_n657x0_q/Kconfig.nucleo_n657x0_q new file mode 100644 index 0000000000000..a1c2528a4709e --- /dev/null +++ b/boards/st/nucleo_n657x0_q/Kconfig.nucleo_n657x0_q @@ -0,0 +1,7 @@ +# STM32N657X0_Q Nucleo board configuration + +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_N657X0_Q + select SOC_STM32N657XX diff --git a/boards/st/nucleo_n657x0_q/arduino_r3_connector.dtsi b/boards/st/nucleo_n657x0_q/arduino_r3_connector.dtsi new file mode 100644 index 0000000000000..3d452c84a643a --- /dev/null +++ b/boards/st/nucleo_n657x0_q/arduino_r3_connector.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 8 0>, /* A0 */ + <1 0 &gpioa 9 0>, /* A1 */ + <2 0 &gpioa 10 0>, /* A2 */ + <3 0 &gpioa 12 0>, /* A3 */ + <4 0 &gpiof 3 0>, /* A4 */ + <5 0 &gpiog 15 0>, /* A5 */ + <6 0 &gpiod 9 0>, /* D0 */ + <7 0 &gpiod 8 0>, /* D1 */ + <8 0 &gpiod 0 0>, /* D2 */ + <9 0 &gpioe 9 0>, /* D3 */ + <10 0 &gpioe 0 0>, /* D4 */ + <11 0 &gpioe 10 0>, /* D5 */ + <12 0 &gpiod 5 0>, /* D6 */ + <13 0 &gpioe 11 0>, /* D7 */ + <14 0 &gpiod 12 0>, /* D8 */ + <15 0 &gpiod 7 0>, /* D9 */ + <16 0 &gpioa 3 0>, /* D10 */ + <17 0 &gpiog 2 0>, /* D11 */ + <18 0 &gpiog 1 0>, /* D12 */ + <19 0 &gpioe 15 0>, /* D13 */ + <20 0 &gpioc 1 0>, /* D14 */ + <21 0 &gpioh 9 0>; /* D15 */ + }; +}; + +arduino_serial: &usart3 {}; +arduino_i2c: &i2c1 {}; +arduino_spi: &spi5 {}; diff --git a/boards/st/nucleo_n657x0_q/board.cmake b/boards/st/nucleo_n657x0_q/board.cmake new file mode 100644 index 0000000000000..a469036845ca0 --- /dev/null +++ b/boards/st/nucleo_n657x0_q/board.cmake @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 STMicroelectronics + +if(CONFIG_STM32N6_BOOT_SERIAL) + board_runner_args(stm32cubeprogrammer "--port=usb1") + board_runner_args(stm32cubeprogrammer "--download-modifiers=0x1") + board_runner_args(stm32cubeprogrammer "--start-modifiers=noack") +else() + board_runner_args(stm32cubeprogrammer "--port=swd") + board_runner_args(stm32cubeprogrammer "--tool-opt= mode=HOTPLUG ap=1") + board_runner_args(stm32cubeprogrammer "--extload=MX25UM51245G_STM32N6570-NUCLEO.stldr") + board_runner_args(stm32cubeprogrammer "--download-address=0x70000000") +endif() + +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) diff --git a/boards/st/nucleo_n657x0_q/board.yml b/boards/st/nucleo_n657x0_q/board.yml new file mode 100644 index 0000000000000..4261dec1e7bd9 --- /dev/null +++ b/boards/st/nucleo_n657x0_q/board.yml @@ -0,0 +1,8 @@ +board: + name: nucleo_n657x0_q + full_name: Nucleo N657X0-Q + vendor: st + socs: + - name: stm32n657xx + variants: + - name: sb diff --git a/boards/st/nucleo_n657x0_q/doc/img/nucleo_n657x0_q.webp b/boards/st/nucleo_n657x0_q/doc/img/nucleo_n657x0_q.webp new file mode 100644 index 0000000000000..c6d918de66d9c Binary files /dev/null and b/boards/st/nucleo_n657x0_q/doc/img/nucleo_n657x0_q.webp differ diff --git a/boards/st/nucleo_n657x0_q/doc/index.rst b/boards/st/nucleo_n657x0_q/doc/index.rst new file mode 100644 index 0000000000000..2638f9b35e477 --- /dev/null +++ b/boards/st/nucleo_n657x0_q/doc/index.rst @@ -0,0 +1,276 @@ +.. zephyr:board:: nucleo_n657x0_q + +Overview +******** + +The NUCLEO-N657X0-Q board provides an affordable and flexible way for users to try out +new concepts and build prototypes by choosing from the various combinations of performance +and power consumption features, provided by the STM32 microcontroller. For the compatible boards, +the internal or external SMPS significantly reduces power consumption in Run mode. + +The ST Zio connector, which extends the ARDUINOÂŽ Uno V3 connectivity, and the ST morpho headers +provide an easy means of expanding the functionality of the Nucleo open development platform with +a wide choice of specialized shields. + +The NUCLEO-N657X0-Q board does not require any separate probe as it integrates the ST-LINK +debugger/programmer. + +The STM32 Nucleo-144 board comes with the STM32 comprehensive free software libraries and +examples available with the STM32Cube MCU Package. + +Hardware +******** + +- Common features: + + - STM32 microcontroller in an LQFP144, TFBGA225, or VFBGA264 package + - 3 user LEDs + - 1 user push-button and 1 reset push-button + - 32.768 kHz crystal oscillator + - Board connectors: + + - SWD + - ST morpho expansion connector + + - Flexible power-supply options: ST-LINK USB VBUS, USB connector, or external sources + +- Features specific to some of the boards (refer to the ordering information section + of the data brief for details); + + - External or internal SMPS to generate Vcore logic supply + - Ethernet compliant with IEEE-802.3-2002 + - USB Device only, USB OTG full speed, or SNK/UFP (full-speed or high-speed mode) + - Board connectors: + + - ARDUINOÂŽ Uno V3 connector or ST Zio expansion connector including ARDUINOÂŽ Uno V3 + - Camera module FPC + - MIPI20 compatible connector with trace signals + - USB with Micro-AB or USB Type-CÂŽ + - Ethernet RJ45 + + - On-board ST-LINK (STLINK/V2-1, STLINK-V3E, or STLINK-V3EC) debugger/programmer with + USB re-enumeration capability: mass storage, Virtual COM port, and debug port + +For more details, please refer to: + +* `NUCLEO-N657X0-Q website`_ +* `STM32N657X0 on www.st.com`_ +* `STM32N657 reference manual`_ + +Supported Features +================== + +The Zephyr ``nucleo_n657x0_q`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| CAN/CANFD | on-chip | canbus | ++-----------+------------+-------------------------------------+ +| DMA | on-chip | Direct Memory Access Controller | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ + + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration can be found in the defconfig file: +:zephyr_file:`boards/st/nucleo_n657x0_q/nucleo_n657x0_q_defconfig` + + +Connections and IOs +=================== + +NUCLEO-N657X0-Q Board has 12 GPIO controllers. These controllers are responsible +for pin muxing, input/output, pull-up, etc. + +For more details please refer to `NUCLEO-N657X0-Q User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- ADC1_INP10 : PA9 +- ADC1_INP11 : PA10 +- FDCAN1_TX : PH2 +- FDCAN1_RX : PD0 +- I2C1_SCL : PH9 +- I2C1_SDA : PC1 +- I2C4_SCL : PE13 +- I2C4_SDA : PE14 +- LD1 : PO1 +- LD2 : PG10 +- SPI5_SCK : PE15 +- SPI5_MOSI : PG2 +- SPI5_MISO : PG1 +- SPI5_NSS : PA3 +- USART_1_TX : PE5 +- USART_1_RX : PE6 +- USART_3_TX : PD8 +- USART_3_RX : PD9 + +System Clock +------------ + +NUCLEO-N657X0-Q System Clock could be driven by internal or external oscillator, +as well as main PLL clock. By default System clock is driven by PLL clock at +400MHz, driven by 64MHz high speed internal oscillator. + +Serial Port +----------- + +NUCLEO-N657X0-Q board has 10 U(S)ARTs. The Zephyr console output is assigned to +USART1. Default settings are 115200 8N1. + +Programming and Debugging +************************* + +NUCLEO-N657X0-Q board includes an ST-LINK/V3 embedded debug tool interface. +This probe allows to flash and debug the board using various tools. + + + +Flashing or loading +=================== + +The board is configured to be programmed using west `STM32CubeProgrammer`_ runner, +so its :ref:`installation ` is needed. +Version 2.18.0 or later of `STM32CubeProgrammer`_ is required. + +To program the board, there are two options: + +- Program the firmware in external flash. At boot, it will then be loaded on RAM + and executed from there. +- Optionally, it can also be taken advantage from the serial boot interface provided + by the boot ROM. In that case, firmware is directly loaded in RAM and executed from + there. It is not retained. + +Programming an application to NUCLEO-N657X0-Q +--------------------------------------------- + +Here is an example to build and run :zephyr:code-sample:`hello_world` application. + +First, connect the NUCLEO-N657X0-Q to your host computer using the ST-Link USB port. + + .. tabs:: + + .. group-tab:: ST-Link + + Build and flash an application using ``nucleo_n657x0_q`` target. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_n657x0_q + :goals: build flash + +.. note:: + For flashing, before powering the board, set the boot pins in the following configuration: + + * BOOT0: 0 + * BOOT1: 1 + + After flashing, to run the application, set the boot pins in the following configuration: + + * BOOT1: 0 + + Power off and on the board again. + + Run a serial host program to connect to your board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + + .. group-tab:: Serial Boot Loader (USB) + + Additionally, connect the NUCLEO-N657X0-Q to your host computer using the USB port. + In this configuration, ST-Link is used to power the board and for serial communication + over the Virtual COM Port. + + .. note:: + Before powering the board, set the boot pins in the following configuration: + + * BOOT0: 1 + * BOOT1: 0 + + Build and load an application using ``nucleo_n657x0_q/stm32n657xx/sb`` target (you + can also use the shortened form: ``nucleo_n657x0_q//sb``) + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_n657x0_q + :goals: build flash + + +Run a serial host program to connect to your board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +You should see the following message on the console: + +.. code-block:: console + + Hello World! nucleo_n657x0_q/stm32n657xx + + +Debugging +========= + +For now debugging is only available through STM32CubeIDE: + +* Go to File > Import and select C/C++ > STM32 Cortex-M Executable. +* In Executable field, browse to your /build/zephyr/zephyr.elf. +* In MCU field, select STM32N657X0HxQ. +* Click on Finish. +* Finally, click on Debug to start the debugging session. + +.. note:: + For debugging, before powering on the board, set the boot pins in the following configuration: + + * BOOT0: 0 + * BOOT1: 1 + + +Running tests with twister +========================== + +Due to the BOOT switches manipulation required when flashing the board using ``nucleo_n657x0_q`` +board target, it is only possible to run twister tests campaign on ``nucleo_n657x0_q/stm32n657xx/sb`` +board target which doesn't require BOOT pins changes to load and execute binaries. +To do so, it is advised to use Twister's hardware map feature with the following settings: + +.. code-block:: yaml + + - platform: nucleo_n657x0_q/stm32n657xx/sb + product: BOOT-SERIAL + pre_script: /boards/st/common/scripts/board_power_reset.sh + runner: stm32cubeprogrammer + +.. _NUCLEO-N657X0-Q website: + https://www.st.com/en/evaluation-tools/nucleo-n657x0-q.html + +.. _NUCLEO-N657X0-Q User Manual: + https://www.st.com/resource/en/user_manual/um3417-stm32n6-nucleo144-board-mb1940-stmicroelectronics.pdf +.. _STM32N657X0 on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32n657x0.html + +.. _STM32N657 reference manual: + https://www.st.com/resource/en/reference_manual/rm0486-stm32n647657xx-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q.dts b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q.dts new file mode 100644 index 0000000000000..1e6d99ed6324d --- /dev/null +++ b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q.dts @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "nucleo_n657x0_q_common.dtsi" + +/ { + model = "STMicroelectronics STM32N657X0-Q-NUCLEO board"; + compatible = "st,stm32n657x0-q-nucleo"; +}; diff --git a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi new file mode 100644 index 0000000000000..e28d61131bb63 --- /dev/null +++ b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "arduino_r3_connector.dtsi" + +/ { + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &axisram2; + zephyr,canbus = &fdcan1; + }; + + leds: leds { + compatible = "gpio-leds"; + + green_led: led_1 { + gpios = <&gpiog 0 GPIO_ACTIVE_HIGH>; + label = "User LD6"; + }; + + blue_led: led_2 { + gpios = <&gpiog 8 GPIO_ACTIVE_HIGH>; + label = "User LD7"; + }; + + red_led: led_3 { + gpios = <&gpiog 10 GPIO_ACTIVE_HIGH>; + label = "User LD5"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button: button_0 { + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + label = "User SB1"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &green_led; + led1 = &blue_led; + led2 = &red_led; + sw0 = &user_button; + }; +}; + +&clk_hsi { + hsi-div = <1>; + status = "okay"; +}; + +&pll1 { + clocks = <&clk_hsi>; + div-m = <4>; + mul-n = <75>; + div-p1 = <1>; + div-p2 = <1>; + status = "okay"; +}; + +&ic1 { + pll-src = <1>; + ic-div = <2>; + status = "okay"; +}; + +&ic2 { + pll-src = <1>; + ic-div = <3>; + status = "okay"; +}; + +&ic6 { + pll-src = <1>; + ic-div = <2>; + status = "okay"; +}; + +&ic11 { + pll-src = <1>; + ic-div = <3>; + status = "okay"; +}; + +&perck { + clocks = <&rcc STM32_SRC_HSI PER_SEL(0)>; + status = "okay"; +}; + +&cpusw { + clocks = <&rcc STM32_SRC_IC1 CPU_SEL(3)>; + clock-frequency = ; + status = "okay"; +}; + +&rcc { + /* ic2, ic6 & ic11 must all be enabled to set ic2 as SYSCLK */ + clocks = <&ic2>; + clock-frequency = ; + ahb-prescaler = <2>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb4-prescaler = <1>; + apb5-prescaler = <1>; +}; + +&adc1 { + clocks = <&rcc STM32_CLOCK(AHB1, 5)>, + <&rcc STM32_SRC_CKPER ADC12_SEL(1)>; + pinctrl-0 = <&adc1_inp10_pa9 &adc1_inp11_pa10>; /* Arduino A1 & A2 */ + pinctrl-names = "default"; + vref-mv = <1800>; + status = "okay"; +}; + +&fdcan1 { + clocks = <&rcc STM32_CLOCK(APB1_2, 8)>, + <&rcc STM32_SRC_CKPER FDCAN_SEL(1)>; + pinctrl-0 = <&fdcan1_rx_pd0 &fdcan1_tx_ph2>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + clocks = <&rcc STM32_CLOCK(APB1, 21)>, + <&rcc STM32_SRC_CKPER I2C1_SEL(1)>; + pinctrl-0 = <&i2c1_scl_ph9 &i2c1_sda_pc1>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; + +&i2c4 { + clocks = <&rcc STM32_CLOCK(APB4, 7)>, + <&rcc STM32_SRC_CKPER I2C4_SEL(1)>; + pinctrl-0 = <&i2c4_scl_pe13 &i2c4_sda_pe14>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; + +&spi5 { + clocks = <&rcc STM32_CLOCK(APB2, 20)>, + <&rcc STM32_SRC_CKPER SPI5_SEL(1)>; + pinctrl-0 = <&spi5_nss_pa3 &spi5_sck_pe15 &spi5_miso_pg1 &spi5_mosi_pg2>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usart1 { + clocks = <&rcc STM32_CLOCK(APB2, 4)>, + <&rcc STM32_SRC_CKPER USART1_SEL(1)>; + pinctrl-0 = <&usart1_tx_pe5 &usart1_rx_pe6>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart3 { + clocks = <&rcc STM32_CLOCK(APB1, 18)>, + <&rcc STM32_SRC_CKPER USART3_SEL(1)>; + pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; diff --git a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_defconfig b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_defconfig new file mode 100644 index 0000000000000..01abfa9c0b7ff --- /dev/null +++ b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 STMicroelectronics + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# No internal Flash +CONFIG_XIP=n diff --git a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_stm32n657xx_sb.dts b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_stm32n657xx_sb.dts new file mode 100644 index 0000000000000..e7d5f34730438 --- /dev/null +++ b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_stm32n657xx_sb.dts @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "nucleo_n657x0_q_common.dtsi" + +/ { + model = "STMicroelectronics STM32N657X0-Q-NUCLEO board"; + compatible = "st,stm32n657x0-q-nucleo-sb"; +}; diff --git a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_stm32n657xx_sb_defconfig b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_stm32n657xx_sb_defconfig new file mode 100644 index 0000000000000..33b0f281a2f84 --- /dev/null +++ b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_stm32n657xx_sb_defconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 STMicroelectronics + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# No internal Flash +CONFIG_XIP=n + +# Use serial boot (USB) +CONFIG_STM32N6_BOOT_SERIAL=y diff --git a/boards/st/nucleo_n657x0_q/twister.yaml b/boards/st/nucleo_n657x0_q/twister.yaml new file mode 100644 index 0000000000000..b1316a29fcf3d --- /dev/null +++ b/boards/st/nucleo_n657x0_q/twister.yaml @@ -0,0 +1,24 @@ +name: ST Nucleo N657X0-Q +type: mcu +arch: arm +ram: 1024 +flash: 1024 +supported: + - arduino_i2c + - arduino_serial + - arduino_spi + - adc + - can + - dma + - i2c + - gpio + - spi + - uart +vendor: st +variants: + nucleo_n657x0_q/stm32n657xx: + twister: false + nucleo_n657x0_q/stm32n657xx/sb: + toolchain: + - zephyr + - gnuarmemb diff --git a/boards/st/nucleo_u031r8/nucleo_u031r8.dts b/boards/st/nucleo_u031r8/nucleo_u031r8.dts index 46e29de3bfef9..d82570718ddb8 100644 --- a/boards/st/nucleo_u031r8/nucleo_u031r8.dts +++ b/boards/st/nucleo_u031r8/nucleo_u031r8.dts @@ -105,7 +105,7 @@ &adc1 { pinctrl-0 = <&adc1_in0_pc0 &adc1_in1_pc1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; vref-mv = <3300>; diff --git a/boards/st/nucleo_u083rc/doc/index.rst b/boards/st/nucleo_u083rc/doc/index.rst index 09db38710c615..7cd2f5db57807 100644 --- a/boards/st/nucleo_u083rc/doc/index.rst +++ b/boards/st/nucleo_u083rc/doc/index.rst @@ -49,6 +49,8 @@ They operate at a frequency of up to 56 MHz. - 4 ÂľA wake-up from Stop mode - 52 ÂľA/MHz Run mode - Brownout reset + - SPI (3) + - DMA Controller (2) - Core: @@ -98,6 +100,7 @@ They operate at a frequency of up to 56 MHz. - Candidate for Arm |reg| PSA level 1 and SESIP level 3 certifications - 5 passive anti-tamper pins - 96-bit unique ID + - True Random Number Generator (RNG) NIST SP800-90B compliant - Up to 10 timers, 2 watchdogs and RTC: @@ -106,6 +109,8 @@ They operate at a frequency of up to 56 MHz. 2x watchdogs, SysTick timer - RTC with hardware calendar, alarms and calibration +- 3 low-power 16-bit timers (available in Stop mode). + - Up to 20 communication peripherals: - 1 USB 2.0 full-speed crystal-less solution with LPM and BCD @@ -145,6 +150,8 @@ The Zephyr nucleo_u083rc board configuration supports the following hardware fea | UART | on-chip | serial port-polling; | | | | serial port-interrupt | +-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ | ADC | on-chip | adc | +-----------+------------+-------------------------------------+ | DAC | on-chip | DAC Controller | @@ -153,6 +160,20 @@ The Zephyr nucleo_u083rc board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | PWM | on-chip | pwm | +-----------+------------+-------------------------------------+ +| RTC | on-chip | Real Time Clock | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| USB | on-chip | USB full-speed host/device bus | ++-----------+------------+-------------------------------------+ +| DMA | on-chip | Direct Memory Access Controller | ++-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ +| AES | on-chip | crypto | ++-----------+------------+-------------------------------------+ +| LPTIM | on-chip | Low Power Timer | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. diff --git a/boards/st/nucleo_u083rc/nucleo_u083rc.dts b/boards/st/nucleo_u083rc/nucleo_u083rc.dts index dc3493fa13ada..cfe5e1495621f 100644 --- a/boards/st/nucleo_u083rc/nucleo_u083rc.dts +++ b/boards/st/nucleo_u083rc/nucleo_u083rc.dts @@ -44,6 +44,7 @@ aliases { led0 = &green_led_1; sw0 = &user_button; + watchdog0 = &iwdg; }; }; @@ -61,10 +62,26 @@ status = "okay"; }; +&iwdg { + status = "okay"; +}; + &clk_hsi { status = "okay"; }; +&clk_hsi48 { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + &pll { div-m = <1>; mul-n = <6>; @@ -95,17 +112,10 @@ clock-frequency = ; }; -&i2c2 { - pinctrl-0 = <&i2c2_scl_pa7 &i2c2_sda_pa6>; - pinctrl-names = "default"; - status = "okay"; - clock-frequency = ; -}; - &adc1 { pinctrl-0 = <&adc1_in0_pc0 &adc1_in1_pc1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00100000>, <&rcc STM32_SRC_HSI ADC_SEL(2)>; st,adc-prescaler = <4>; @@ -134,3 +144,48 @@ status = "okay"; }; }; + +stm32_lp_tick_source: &lptim1 { + clocks = <&rcc STM32_CLOCK(APB1, 31U)>, + <&rcc STM32_SRC_LSI LPTIM1_SEL(1)>; + status = "okay"; +}; + +&spi1{ + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + cs-gpios = <&gpioa 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + pinctrl-names = "default"; + status = "okay"; +}; + +&dma1 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; + +&rng { + clocks = <&rcc STM32_CLOCK(AHB1, 18U)>, + <&rcc STM32_SRC_HSI48 CLK48_SEL(1)>; + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +zephyr_udc0: &usb { + clocks = <&rcc STM32_CLOCK(APB1, 13U)>, + <&rcc STM32_SRC_HSI48 CLK48_SEL(1)>; + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; + pinctrl-names = "default"; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK(APB1, 10U)>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; diff --git a/boards/st/nucleo_u083rc/nucleo_u083rc.yaml b/boards/st/nucleo_u083rc/nucleo_u083rc.yaml index c4ddc5071c097..8f2e316ba2727 100644 --- a/boards/st/nucleo_u083rc/nucleo_u083rc.yaml +++ b/boards/st/nucleo_u083rc/nucleo_u083rc.yaml @@ -5,14 +5,20 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc + - aes - arduino_gpio - dac + - dma - gpio - i2c + - lptim - pwm + - rng + - rtc + - spi - usart + - usb ram: 40 flash: 256 diff --git a/boards/st/nucleo_u575zi_q/nucleo_u575zi_q-common.dtsi b/boards/st/nucleo_u575zi_q/nucleo_u575zi_q-common.dtsi index 0d66260badd23..171aa4126586a 100644 --- a/boards/st/nucleo_u575zi_q/nucleo_u575zi_q-common.dtsi +++ b/boards/st/nucleo_u575zi_q/nucleo_u575zi_q-common.dtsi @@ -129,7 +129,7 @@ &adc1 { pinctrl-0 = <&adc1_in1_pc0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -137,7 +137,7 @@ &adc4 { pinctrl-0 = <&adc4_in18_pb0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_u5a5zj_q/doc/index.rst b/boards/st/nucleo_u5a5zj_q/doc/index.rst index ea919c4f10ee7..794a2351d825a 100644 --- a/boards/st/nucleo_u5a5zj_q/doc/index.rst +++ b/boards/st/nucleo_u5a5zj_q/doc/index.rst @@ -204,6 +204,8 @@ The Zephyr nucleo_u5a5zj_q board configuration supports the following hardware f +-----------+------------+-------------------------------------+ | RTC | on-chip | rtc | +-----------+------------+-------------------------------------+ +| USB | on-chip | USB 2.0 HS | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -245,13 +247,15 @@ Default Zephyr Peripheral Mapping: - UART_2_TX : PD5 - UART_2_RX : PD6 - USER_PB : PC13 +- USB_DM : PA11 +- USB_DP : PA12 System Clock ------------ Nucleo U5A5ZJ Q System Clock could be driven by internal or external oscillator, as well as main PLL clock. By default System clock is driven by PLL clock at -160MHz, driven by 4MHz medium speed internal oscillator. +160MHz, driven by the 16MHz high speed oscillator. Serial Port ----------- @@ -259,13 +263,18 @@ Serial Port Nucleo U5A5ZJ Q board has 6 U(S)ARTs. The Zephyr console output is assigned to USART1. Default settings are 115200 8N1. - Backup SRAM ----------- In order to test backup SRAM you may want to disconnect VBAT from VDD. You can do it by removing ``SB50`` jumper on the back side of the board. +Using USB +--------- + +USB 2.0 high speed (HS) operation requires the HSE clock source to be populated +and enabled. The Nucleo U5A5ZJ-Q includes the 16MHz oscillator and required +jumper settings. Programming and Debugging ************************* diff --git a/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q-common.dtsi b/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q-common.dtsi index ecc9e862c990f..45d7c817ec600 100644 --- a/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q-common.dtsi +++ b/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q-common.dtsi @@ -55,22 +55,23 @@ status = "okay"; }; -&clk_lse { +/* This board has a 16MHz crystal attached */ +&clk_hse { + clock-frequency = ; status = "okay"; }; -&clk_msis { +&clk_lse { status = "okay"; - msi-range = <4>; - msi-pll-mode; }; &pll1 { - div-m = <1>; - mul-n = <80>; - div-q = <2>; - div-r = <2>; - clocks = <&clk_msis>; + /* HSE 16MHz source, outputting 160MHz to sysclk and apbclk */ + div-m = <4>; /* input divisor */ + mul-n = <80>; /* VCO multiplication factor */ + div-q = <2>; /* system clock divisor */ + div-r = <2>; /* peripheral clock divisor */ + clocks = <&clk_hse>; status = "okay"; }; @@ -127,7 +128,7 @@ &adc1 { pinctrl-0 = <&adc1_in1_pc0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -135,7 +136,7 @@ &adc4 { pinctrl-0 = <&adc4_in18_pb0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts b/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts index a9907afe61429..e34b10024ab05 100644 --- a/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts +++ b/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q.dts @@ -74,3 +74,9 @@ &gpdma1 { status = "okay"; }; + +zephyr_udc0: &usbotg_hs { + pinctrl-0 = <&usb_otg_hs_dm_pa11 &usb_otg_hs_dp_pa12>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml b/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml index cd93708041410..57c0712ffedb1 100644 --- a/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml +++ b/boards/st/nucleo_u5a5zj_q/nucleo_u5a5zj_q.yaml @@ -21,5 +21,6 @@ supported: - backup_sram - dma - rtc + - usb_device ram: 2450 flash: 4096 diff --git a/boards/st/nucleo_wb05kz/doc/index.rst b/boards/st/nucleo_wb05kz/doc/index.rst index 0c004e5995298..8b5c9a7e54114 100644 --- a/boards/st/nucleo_wb05kz/doc/index.rst +++ b/boards/st/nucleo_wb05kz/doc/index.rst @@ -52,6 +52,8 @@ The Zephyr ``nucleo_wb05kz`` board target supports the following hardware featur +-----------+------------+-------------------------------------+ | ADC | on-chip | adc | +-----------+------------+-------------------------------------+ +| TIMER | on-chip | counter, pwm | ++-----------+------------+-------------------------------------+ | RADIO | on-chip | Bluetooth Low Energy | +-----------+------------+-------------------------------------+ diff --git a/boards/st/nucleo_wb05kz/nucleo_wb05kz.dts b/boards/st/nucleo_wb05kz/nucleo_wb05kz.dts index 88f37c00186e4..93b98e86fded3 100644 --- a/boards/st/nucleo_wb05kz/nucleo_wb05kz.dts +++ b/boards/st/nucleo_wb05kz/nucleo_wb05kz.dts @@ -39,6 +39,14 @@ }; }; + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "okay"; + pwm_red_led_1: pwm_led_1 { + pwms = <&pwm2 3 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + gpio_keys { compatible = "gpio-keys"; user_button_1: button_0 { @@ -62,6 +70,7 @@ led0 = &blue_led_1; led1 = &green_led_1; led2 = &red_led_1; + pwm-led0 = &pwm_red_led_1; sw0 = &user_button_1; sw1 = &user_button_2; sw2 = &user_button_3; @@ -122,6 +131,19 @@ <&rcc STM32_SRC_SYSCLK SPI3_I2S3_SEL(3)>; }; + +&timers2 { + status = "okay"; + st,prescaler = <10000>; + + pwm2: pwm { + /* PWM on red_led_1 */ + pinctrl-0 = <&tim2_ch3_pb2>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/boards/st/nucleo_wb05kz/nucleo_wb05kz.yaml b/boards/st/nucleo_wb05kz/nucleo_wb05kz.yaml index cf931e9bd3756..57ede119efe7a 100644 --- a/boards/st/nucleo_wb05kz/nucleo_wb05kz.yaml +++ b/boards/st/nucleo_wb05kz/nucleo_wb05kz.yaml @@ -5,16 +5,17 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 24 flash: 192 supported: - adc - arduino_i2c - arduino_spi + - counter - dma - gpio - i2c + - pwm - spi - bluetooth vendor: st diff --git a/boards/st/nucleo_wb07cc/Kconfig.nucleo_wb07cc b/boards/st/nucleo_wb07cc/Kconfig.nucleo_wb07cc new file mode 100644 index 0000000000000..662643aeea74b --- /dev/null +++ b/boards/st/nucleo_wb07cc/Kconfig.nucleo_wb07cc @@ -0,0 +1,5 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NUCLEO_WB07CC + select SOC_STM32WB07XX diff --git a/boards/st/nucleo_wb07cc/arduino_r3_connector.dtsi b/boards/st/nucleo_wb07cc/arduino_r3_connector.dtsi new file mode 100644 index 0000000000000..75cb81bccfe23 --- /dev/null +++ b/boards/st/nucleo_wb07cc/arduino_r3_connector.dtsi @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + + /* Some pins are not connected to the Arduino + * connector in default hardware configuration. + * Only the connected pins are provided here. + */ + gpio-map = <0 0 &gpiob 3 0>, /* A0 */ + <1 0 &gpiob 1 0>, /* A1 */ + <2 0 &gpioa 15 0>, /* A2 */ + <3 0 &gpioa 12 0>, /* A3 */ + <4 0 &gpioa 14 0>, /* A4 */ + <5 0 &gpioa 13 0>, /* A5 */ + /* D0 - N/C (PA8 via SB9) */ + /* D1 - N/C (PA9 via SB7) */ + <8 0 &gpiob 15 0>, /* D2 */ + /* D3 - N/C (PA0 via SB3) */ + <10 0 &gpiob 11 0>, /* D4 */ + <11 0 &gpiob 14 0>, /* D5 */ + <12 0 &gpioa 11 0>, /* D6 */ + <13 0 &gpiob 10 0>, /* D7 */ + <14 0 &gpiob 8 0>, /* D8 */ + <15 0 &gpioa 1 0>, /* D9 */ + <16 0 &gpioa 4 0>, /* D10 */ + <17 0 &gpioa 6 0>, /* D11 */ + <18 0 &gpioa 7 0>, /* D12 */ + <19 0 &gpioa 5 0>, /* D13 */ + <20 0 &gpiob 7 0>, /* D14 */ + <21 0 &gpiob 6 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c2 {}; +arduino_serial: &usart1 {}; +arduino_spi: &spi2 {}; diff --git a/boards/st/nucleo_wb07cc/board.cmake b/boards/st/nucleo_wb07cc/board.cmake new file mode 100644 index 0000000000000..f70ab15a58669 --- /dev/null +++ b/boards/st/nucleo_wb07cc/board.cmake @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# keep first +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=sw" "--start-address=0x10040000") + +# keep first +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/st/nucleo_wb07cc/board.yml b/boards/st/nucleo_wb07cc/board.yml new file mode 100644 index 0000000000000..fefbe534fc69e --- /dev/null +++ b/boards/st/nucleo_wb07cc/board.yml @@ -0,0 +1,6 @@ +board: + name: nucleo_wb07cc + full_name: Nucleo WB07CC + vendor: st + socs: + - name: stm32wb07 diff --git a/boards/st/nucleo_wb07cc/doc/img/nucleo_wb07cc.webp b/boards/st/nucleo_wb07cc/doc/img/nucleo_wb07cc.webp new file mode 100644 index 0000000000000..93cefa87db046 Binary files /dev/null and b/boards/st/nucleo_wb07cc/doc/img/nucleo_wb07cc.webp differ diff --git a/boards/st/nucleo_wb07cc/doc/index.rst b/boards/st/nucleo_wb07cc/doc/index.rst new file mode 100644 index 0000000000000..15a2cfc2fe406 --- /dev/null +++ b/boards/st/nucleo_wb07cc/doc/index.rst @@ -0,0 +1,166 @@ +.. zephyr:board:: nucleo_wb07cc + +Overview +******** + +The Nucleo WB07CC board is a Bluetooth |reg| Low Energy wireless and ultra-low-power +board featuring an ARM Cortex |reg|-M0+ based STM32WB07CCV MCU, embedding a +powerful and ultra-low-power radio compliant with the Bluetooth |reg| Low Energy +SIG specification v5.4. + +More information about the board can be found on the `Nucleo WB07CC webpage`_. + +Hardware +******** + +Nucleo WB07CC provides the following hardware components: + +- STM32WB07CCV in VFQFPN32 package +- ARM |reg| 32-bit Cortex |reg|-M0+ CPU +- 64 MHz maximal CPU frequency +- 256 KB Flash +- 64 KB SRAM + +More information about STM32WB07CCV can be found here: + +- `WB07CC on www.st.com`_ +- `STM32WB07 reference manual`_ + + +Supported Features +================== + +The Zephyr ``nucleo_wb07cc`` board target supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | internal flash memory | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| TIMER | on-chip | counter, pwm | ++-----------+------------+-------------------------------------+ +| RADIO | on-chip | Bluetooth Low Energy | ++-----------+------------+-------------------------------------+ + + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration can be found in the defconfig file: +:zephyr_file:`boards/st/nucleo_wb07cc/nucleo_wb07cc_defconfig` + +Bluetooth support +----------------- + +BLE support is enabled; however, to build a Zephyr sample using this board, +the Bluetooth controller library must be fetched into Zephyr as a binary blob. + +To fetch the binary blobs: + +.. code-block:: console + + $ west blobs fetch hal_stm32 + +Connections and IOs +=================== + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- USART1 TX/RX : PA9/PA8 (ST-Link Virtual COM Port) +- BUTTON (B1) : PA0 +- BUTTON (B2) : PB5 +- BUTTON (B3) : PB9 +- LED (LD1/BLUE) : PB0 +- LED (LD2/GREEN) : PB4 +- LED (LD3/RED) : PB2 + +For more details, please refer to the `Nucleo WB07CC board User Manual`_. + +Programming and Debugging +************************* + +Nucleo WB07CC board includes an ST-LINK-V3EC embedded debug tool interface. + +Applications for the ``nucleo_wb07cc`` board target can be built and flashed +in the usual way (see :ref:`build_an_application` and :ref:`application_run` +for more details). + +Flashing +======== + +The board is configured to be flashed using the west `STM32CubeProgrammer`_ runner, +so :ref:`it must be installed ` beforehand. + +Alternatively, OpenOCD can also be used to flash the board using the +``--runner`` (or ``-r``) option: + +.. code-block:: console + + $ west flash --runner openocd + +Flashing an application to Nucleo WB07CC +---------------------------------------- + +Connect the Nucleo WB07CC to your host computer using the USB port, +then run a serial host program to connect with your Nucleo board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +Now build and flash an application. Here is an example for +:zephyr:code-sample:`hello_world`. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_wb07cc + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! nucleo_wb07cc/stm32wb07 + + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nucleo_wb07cc + :maybe-skip-config: + :goals: debug + +.. _`Nucleo WB07CC webpage`: + https://www.st.com/en/evaluation-tools/nucleo-wb07cc.html + +.. _`WB07CC on www.st.com`: + https://www.st.com/en/microcontrollers-microprocessors/stm32wb07cc.html + +.. _`STM32WB07 reference manual`: + https://www.st.com/resource/en/reference_manual/rm0530--stm32wb07xc-and-stm32wb06xc-ultralow-power-wireless-32bit-mcus-armbased-cortexm0-with-bluetooth-low-energy-and-24-ghz-radio-solution-stmicroelectronics.pdf + +.. _`Nucleo WB07CC board User Manual`: + https://www.st.com/resource/en/user_manual/um3344-stm32wb07-nucleo64-board-mb1801-and-mb2119-stmicroelectronics.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/nucleo_wb07cc/nucleo_wb07cc.dts b/boards/st/nucleo_wb07cc/nucleo_wb07cc.dts new file mode 100644 index 0000000000000..4b53c858e9237 --- /dev/null +++ b/boards/st/nucleo_wb07cc/nucleo_wb07cc.dts @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +#include "arduino_r3_connector.dtsi" + +/ { + model = "STMicroelectronics STM32WB07CC-NUCLEO board"; + compatible = "st,stm32wb07cc-nucleo"; + + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,bt-c2h-uart = &usart1; + }; + + leds: leds { + compatible ="gpio-leds"; + blue_led_1: led_0 { + gpios = <&gpiob 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + green_led_1: led_1 { + gpios = <&gpiob 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + red_led_1: led_2 { + gpios = <&gpiob 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + }; + }; + + pwmleds: pwmleds { + compatible = "pwm-leds"; + pwm_red_led_1: pwm_red_led_1 { + pwms = <&pwm1 3 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + user_button_1: button_0 { + label = "SW1"; + gpios = <&gpioa 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + user_button_2: button_1 { + label = "SW2"; + gpios = <&gpiob 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + user_button_3: button_2 { + label = "SW3"; + gpios = <&gpiob 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &blue_led_1; + led1 = &green_led_1; + led2 = &red_led_1; + pwm-led0 = &pwm_red_led_1; + sw0 = &user_button_1; + sw1 = &user_button_2; + sw2 = &user_button_3; + }; +}; + +&pwrc { + smps-mode = "RUN"; + smps-bom = <3>; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hse { + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&pll { + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + clksys-prescaler = <1>; + slow-clock = <&clk_lse>; +}; + +&bt_hci_wb0 { + status = "okay"; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa8>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb6 &i2c2_sda_pb7>; + pinctrl-names = "default"; + status = "okay"; +}; + +&spi2 { + pinctrl-0 = <&spi2_nss_pa4 &spi2_sck_pa5 &spi2_miso_pa7 &spi2_mosi_pa6>; + pinctrl-names = "default"; + status = "okay"; + /* Select 32MHz clock for SPI2 */ + clocks = <&rcc STM32_CLOCK(APB1, 12)>, + <&rcc STM32_SRC_SYSCLK SPI2_I2S2_SEL(1)>; +}; + +&timers1 { + status = "okay"; + st,prescaler = <10000>; + + pwm1: pwm { + status = "okay"; + pinctrl-0 = <&tim1_ch3_pb2>; + pinctrl-names = "default"; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + /* Set aside 16KB of storage at the end of 256KB flash */ + storage_partition: partition@3c000 { + label = "storage"; + reg = <0x0003c000 DT_SIZE_K(16)>; + }; + }; +}; diff --git a/boards/st/nucleo_wb07cc/nucleo_wb07cc.yaml b/boards/st/nucleo_wb07cc/nucleo_wb07cc.yaml new file mode 100644 index 0000000000000..452e43da855b5 --- /dev/null +++ b/boards/st/nucleo_wb07cc/nucleo_wb07cc.yaml @@ -0,0 +1,21 @@ +identifier: nucleo_wb07cc +name: ST Nucleo WB07CC +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 64 +flash: 256 +supported: + - adc + - arduino_i2c + - arduino_spi + - counter + - dma + - gpio + - i2c + - pwm + - spi + - bluetooth +vendor: st diff --git a/boards/st/nucleo_wb07cc/nucleo_wb07cc_defconfig b/boards/st/nucleo_wb07cc/nucleo_wb07cc_defconfig new file mode 100644 index 0000000000000..0a45ef65e1153 --- /dev/null +++ b/boards/st/nucleo_wb07cc/nucleo_wb07cc_defconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/st/nucleo_wb07cc/support/openocd.cfg b/boards/st/nucleo_wb07cc/support/openocd.cfg new file mode 100644 index 0000000000000..6d294443fcfac --- /dev/null +++ b/boards/st/nucleo_wb07cc/support/openocd.cfg @@ -0,0 +1,5 @@ +source [find interface/stlink-dap.cfg] + +transport select "dapdirect_swd" + +source [find target/stm32wb0x.cfg] diff --git a/boards/st/nucleo_wb09ke/doc/index.rst b/boards/st/nucleo_wb09ke/doc/index.rst index bab52ff1ba732..b48869175f442 100644 --- a/boards/st/nucleo_wb09ke/doc/index.rst +++ b/boards/st/nucleo_wb09ke/doc/index.rst @@ -52,6 +52,8 @@ The Zephyr ``nucleo_wb09ke`` board target supports the following hardware featur +-----------+------------+-------------------------------------+ | ADC | on-chip | adc | +-----------+------------+-------------------------------------+ +| TIMER | on-chip | counter, pwm | ++-----------+------------+-------------------------------------+ | RADIO | on-chip | Bluetooth Low Energy | +-----------+------------+-------------------------------------+ diff --git a/boards/st/nucleo_wb09ke/nucleo_wb09ke.dts b/boards/st/nucleo_wb09ke/nucleo_wb09ke.dts index 1b8826ed88442..15cde545c18cc 100644 --- a/boards/st/nucleo_wb09ke/nucleo_wb09ke.dts +++ b/boards/st/nucleo_wb09ke/nucleo_wb09ke.dts @@ -39,6 +39,14 @@ }; }; + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "okay"; + pwm_red_led_1: pwm_led_1 { + pwms = <&pwm2 3 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + gpio_keys { compatible = "gpio-keys"; user_button_1: button_0 { @@ -62,6 +70,7 @@ led0 = &blue_led_1; led1 = &green_led_1; led2 = &red_led_1; + pwm-led0 = &pwm_red_led_1; sw0 = &user_button_1; sw1 = &user_button_2; sw2 = &user_button_3; @@ -122,6 +131,18 @@ <&rcc STM32_SRC_SYSCLK SPI3_I2S3_SEL(3)>; }; +&timers2 { + status = "okay"; + st,prescaler = <10000>; + + pwm2: pwm { + /* PWM on red_led_1 */ + pinctrl-0 = <&tim2_ch3_pb2>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/boards/st/nucleo_wb09ke/nucleo_wb09ke.yaml b/boards/st/nucleo_wb09ke/nucleo_wb09ke.yaml index 20c4a33cfec0b..fde311bd0f5ce 100644 --- a/boards/st/nucleo_wb09ke/nucleo_wb09ke.yaml +++ b/boards/st/nucleo_wb09ke/nucleo_wb09ke.yaml @@ -5,16 +5,17 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: - adc - arduino_i2c - arduino_spi + - counter - dma - gpio - i2c + - pwm - spi - bluetooth vendor: st diff --git a/boards/st/nucleo_wb55rg/nucleo_wb55rg.dts b/boards/st/nucleo_wb55rg/nucleo_wb55rg.dts index f1a0d055aa87f..d58d2ebde26c3 100644 --- a/boards/st/nucleo_wb55rg/nucleo_wb55rg.dts +++ b/boards/st/nucleo_wb55rg/nucleo_wb55rg.dts @@ -181,7 +181,7 @@ &adc1 { pinctrl-0 = <&adc1_in3_pc2 &adc1_in5_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_wb55rg/nucleo_wb55rg.yaml b/boards/st/nucleo_wb55rg/nucleo_wb55rg.yaml index c99ca8712b438..f4e2a417dca90 100644 --- a/boards/st/nucleo_wb55rg/nucleo_wb55rg.yaml +++ b/boards/st/nucleo_wb55rg/nucleo_wb55rg.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 808 supported: diff --git a/boards/st/nucleo_wba52cg/nucleo_wba52cg.dts b/boards/st/nucleo_wba52cg/nucleo_wba52cg.dts index 0c08acc0bfe6c..08b81dba0dc49 100644 --- a/boards/st/nucleo_wba52cg/nucleo_wba52cg.dts +++ b/boards/st/nucleo_wba52cg/nucleo_wba52cg.dts @@ -125,7 +125,7 @@ &adc4 { pinctrl-0 = <&adc4_in8_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts b/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts index d527eea704303..908e2cec593c7 100644 --- a/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts +++ b/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts @@ -43,6 +43,14 @@ }; }; + pwmleds: pwmleds { + compatible = "pwm-leds"; + + green_pwm_led: green_pwm_led { + pwms = <&pwm3 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + gpio_keys { compatible = "gpio-keys"; user_button_1: button_0 { @@ -66,6 +74,7 @@ led0 = &blue_led_1; led1 = &green_led_2; led2 = &red_led_3; + pwm-led0 = &green_pwm_led; sw0 = &user_button_1; sw1 = &user_button_2; sw2 = &user_button_3; @@ -123,6 +132,16 @@ status = "okay"; }; +&usart2 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00020000>, + <&rcc STM32_SRC_HSI16 USART2_SEL(2)>; + pinctrl-0 = <&usart2_tx_pa12 &usart2_rx_pb8>; + pinctrl-1 = <&analog_pa12 &analog_pb8>; + pinctrl-names = "default", "sleep"; + current-speed = <115200>; + status = "okay"; +}; + &lpuart1 { pinctrl-0 = <&lpuart1_tx_pb5 &lpuart1_rx_pa10>; pinctrl-names = "default"; @@ -147,7 +166,7 @@ &adc4 { pinctrl-0 = <&adc4_in8_pa1 &adc4_in9_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -156,6 +175,17 @@ status = "okay"; }; +&timers3 { + st,prescaler = <10000>; + status = "okay"; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&tim3_ch2_pa9>; + pinctrl-names = "default"; + }; +}; + stm32_lp_tick_source: &lptim1 { clocks = <&rcc STM32_CLOCK_BUS_APB7 0x00000800>, <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; diff --git a/boards/st/nucleo_wba55cg/support/openocd.cfg b/boards/st/nucleo_wba55cg/support/openocd.cfg index 1715e7d026e4c..1c3a152323982 100644 --- a/boards/st/nucleo_wba55cg/support/openocd.cfg +++ b/boards/st/nucleo_wba55cg/support/openocd.cfg @@ -19,6 +19,6 @@ set CLOCK_FREQ 8000 # Reset configuration # use hardware reset, connect under reset # connect_assert_srst needed if low power mode application running (WFI...) -reset_config srst_only srst_nogate +reset_config srst_nogate source [find target/stm32wbax.cfg] diff --git a/boards/st/nucleo_wl55jc/doc/nucleo_wl55jc.rst b/boards/st/nucleo_wl55jc/doc/nucleo_wl55jc.rst index 72f7147c5b6eb..8ec97fbc184e3 100644 --- a/boards/st/nucleo_wl55jc/doc/nucleo_wl55jc.rst +++ b/boards/st/nucleo_wl55jc/doc/nucleo_wl55jc.rst @@ -33,8 +33,6 @@ power consumption, and features. mass storage, Virtual COM port, and debug port - Comprehensive free software libraries and examples available with the STM32CubeWL MCU Package -- Support of a wide choice of Integrated Development Environments (IDEs) - including IAR Embedded WorkbenchÂŽ, MDK-ARM, and STM32CubeIDE - Suitable for rapid prototyping of end nodes based on LoRaWAN, Sigfox, wM-Bus, and many other proprietary protocols - Fully open hardware platform diff --git a/boards/st/nucleo_wl55jc/nucleo_wl55jc.dts b/boards/st/nucleo_wl55jc/nucleo_wl55jc.dts index 98fcc7057aef3..1fa0c4d9fdb6f 100644 --- a/boards/st/nucleo_wl55jc/nucleo_wl55jc.dts +++ b/boards/st/nucleo_wl55jc/nucleo_wl55jc.dts @@ -149,7 +149,7 @@ stm32_lp_tick_source: &lptim1 { &adc1 { pinctrl-0 = <&adc_in5_pb1 &adc_in0_pb13>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/nucleo_wl55jc/nucleo_wl55jc.yaml b/boards/st/nucleo_wl55jc/nucleo_wl55jc.yaml index 4eb53ef3324fb..a0ab9a6f62132 100644 --- a/boards/st/nucleo_wl55jc/nucleo_wl55jc.yaml +++ b/boards/st/nucleo_wl55jc/nucleo_wl55jc.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 supported: diff --git a/boards/st/sensortile_box/sensortile_box.yaml b/boards/st/sensortile_box/sensortile_box.yaml index aaa655bf84cdd..47c80ae069c46 100644 --- a/boards/st/sensortile_box/sensortile_box.yaml +++ b/boards/st/sensortile_box/sensortile_box.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - pwm - spi diff --git a/boards/st/sensortile_box_pro/Kconfig b/boards/st/sensortile_box_pro/Kconfig deleted file mode 100644 index d8dc05c44f6a6..0000000000000 --- a/boards/st/sensortile_box_pro/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SENSORTILE_BOX_PRO board configuration - -# Copyright (c) 2024 STMicroelectronics -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_SENSORTILE_BOX_PRO - -config BOARD_SERIAL_BACKEND_CDC_ACM - bool "Use USB CDC as serial console backend" - default y - -endif # BOARD_SENSORTILE_BOX_PRO diff --git a/boards/st/sensortile_box_pro/Kconfig.defconfig b/boards/st/sensortile_box_pro/Kconfig.defconfig index fffa4f419f8b1..a357839f6c4b2 100644 --- a/boards/st/sensortile_box_pro/Kconfig.defconfig +++ b/boards/st/sensortile_box_pro/Kconfig.defconfig @@ -20,50 +20,6 @@ config SPI_STM32_INTERRUPT default y depends on SPI -if BOARD_SERIAL_BACKEND_CDC_ACM - -config USB_DEVICE_STACK - default y - -config USB_CDC_ACM - default SERIAL - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y if CONSOLE - -config SHELL_BACKEND_SERIAL_CHECK_DTR - default SHELL - depends on UART_LINE_CTRL - -config UART_LINE_CTRL - default SHELL - -config USB_DEVICE_REMOTE_WAKEUP - default n - -config USB_DEVICE_VID - default 0x0483 - -config USB_DEVICE_PID - default 0x5740 - -config USB_DEVICE_PRODUCT - default "Zephyr CDC SensorTile.box PRO" - -if LOG - -# Logger cannot use itself to log -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF -endchoice - -endif # LOG - -endif # BOARD_SERIAL_BACKEND_CDC_ACM - -DT_CHOSEN_ZEPHYR_CONSOLE := zephyr,console - -config UART_CONSOLE - default y if $(dt_chosen_enabled,$(DT_CHOSEN_ZEPHYR_CONSOLE)) && CONSOLE +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_SENSORTILE_BOX_PRO diff --git a/boards/st/sensortile_box_pro/doc/index.rst b/boards/st/sensortile_box_pro/doc/index.rst index 1487518e68689..528e6762a8758 100644 --- a/boards/st/sensortile_box_pro/doc/index.rst +++ b/boards/st/sensortile_box_pro/doc/index.rst @@ -221,24 +221,7 @@ Console There are two possible options for Zephyr console output: -- through USB as USB CDC/ACM class. This is the default case present in the board dts file - and is enabled by :kconfig:option:`CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM`. - -.. code-block:: dts - :caption: boards/st/sensortile_box_pro/sensortile_box_pro.dts - - / { - chosen { - zephyr,console = &cdc_acm_uart0; - }; - }; - - &zephyr_udc0 { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; - }; - +- through common CDC ACM UART backend configuration for all boards - through UART4 which is available on SWD connector (JP2). In this case a JTAG adapter can be used to connect SensorTile.box PRO and have both SWD and console lines available. diff --git a/boards/st/sensortile_box_pro/sensortile_box_pro.dts b/boards/st/sensortile_box_pro/sensortile_box_pro.dts index 7014fd86a7e53..85f01ab2a08b9 100644 --- a/boards/st/sensortile_box_pro/sensortile_box_pro.dts +++ b/boards/st/sensortile_box_pro/sensortile_box_pro.dts @@ -14,9 +14,6 @@ compatible = "st,sensortile-box-pro"; chosen { - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,bt-c2h-uart = &cdc_acm_uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; @@ -269,16 +266,14 @@ zephyr_udc0: &usbotg_fs { pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; pinctrl-names = "default"; status = "okay"; - - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; }; +#include <../boards/common/usb/cdc_acm_serial.dtsi> + &adc1 { pinctrl-0 = <&adc1_in15_pb0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -286,7 +281,7 @@ zephyr_udc0: &usbotg_fs { &adc4 { pinctrl-0 = <&adc4_in19_pb1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/sensortile_box_pro/sensortile_box_pro.yaml b/boards/st/sensortile_box_pro/sensortile_box_pro.yaml index 14624c77f7d3b..2151012aa8c59 100644 --- a/boards/st/sensortile_box_pro/sensortile_box_pro.yaml +++ b/boards/st/sensortile_box_pro/sensortile_box_pro.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - pwm - spi diff --git a/boards/st/st25dv_mb1283_disco/st25dv_mb1283_disco.yaml b/boards/st/st25dv_mb1283_disco/st25dv_mb1283_disco.yaml index b4dcf17f82872..899824a3a10c6 100644 --- a/boards/st/st25dv_mb1283_disco/st25dv_mb1283_disco.yaml +++ b/boards/st/st25dv_mb1283_disco/st25dv_mb1283_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 1024 supported: diff --git a/boards/st/steval_fcu001v1/steval_fcu001v1.yaml b/boards/st/steval_fcu001v1/steval_fcu001v1.yaml index 64ac751a2fc6e..3c90be5ed1828 100644 --- a/boards/st/steval_fcu001v1/steval_fcu001v1.yaml +++ b/boards/st/steval_fcu001v1/steval_fcu001v1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - pwm diff --git a/boards/st/steval_stwinbx1/Kconfig b/boards/st/steval_stwinbx1/Kconfig deleted file mode 100644 index 520aea81d168a..0000000000000 --- a/boards/st/steval_stwinbx1/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# STEVAL_STWINBX1 Development kit board configuration - -# Copyright (c) 2024 STMicroelectronics -# SPDX-License-Identifier: Apache-2.0 - -if BOARD_STEVAL_STWINBX1 - -config BOARD_SERIAL_BACKEND_CDC_ACM - bool "Use USB CDC as serial console backend" - default y - -endif # BOARD_STEVAL_STWINBX1 diff --git a/boards/st/steval_stwinbx1/Kconfig.defconfig b/boards/st/steval_stwinbx1/Kconfig.defconfig index 35256e0c2ada7..3d72efbe742f8 100644 --- a/boards/st/steval_stwinbx1/Kconfig.defconfig +++ b/boards/st/steval_stwinbx1/Kconfig.defconfig @@ -20,50 +20,6 @@ config SPI_STM32_INTERRUPT default y depends on SPI -if BOARD_SERIAL_BACKEND_CDC_ACM - -config USB_DEVICE_STACK - default y - -config USB_CDC_ACM - default SERIAL - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y if CONSOLE - -config SHELL_BACKEND_SERIAL_CHECK_DTR - default SHELL - depends on UART_LINE_CTRL - -config UART_LINE_CTRL - default SHELL - -config USB_DEVICE_REMOTE_WAKEUP - default n - -config USB_DEVICE_VID - default 0x0483 - -config USB_DEVICE_PID - default 0x5740 - -config USB_DEVICE_PRODUCT - default "Zephyr CDC STEval-STWinbx1" - -if LOG - -# Logger cannot use itself to log -choice USB_CDC_ACM_LOG_LEVEL_CHOICE - default USB_CDC_ACM_LOG_LEVEL_OFF -endchoice - -endif # LOG - -endif # BOARD_SERIAL_BACKEND_CDC_ACM - -DT_CHOSEN_ZEPHYR_CONSOLE := zephyr,console - -config UART_CONSOLE - default y if $(dt_chosen_enabled,$(DT_CHOSEN_ZEPHYR_CONSOLE)) && CONSOLE +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_STEVAL_STWINBX1 diff --git a/boards/st/steval_stwinbx1/doc/index.rst b/boards/st/steval_stwinbx1/doc/index.rst index 474127e8bcca1..8ef4c10dccaf0 100644 --- a/boards/st/steval_stwinbx1/doc/index.rst +++ b/boards/st/steval_stwinbx1/doc/index.rst @@ -230,23 +230,7 @@ Console There are two possible options for Zephyr console output: -- through USB as USB CDC/ACM class. This is the default case present in the board dts file - and is enabled by :kconfig:option:`CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM`. - -.. code-block:: dts - :caption: boards/st/steval_stwinbx1/steval_stwinbx1.dts - - / { - chosen { - zephyr,console = &cdc_acm_uart0; - }; - }; - - &zephyr_udc0 { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; - }; +- through common CDC ACM UART backend configuration for all boards - through USART2 which is available on SWD connector (CN4). In this case a JTAG adapter can be used to connect STEVAL-STWINBX1 and have both SWD and console lines available. diff --git a/boards/st/steval_stwinbx1/steval_stwinbx1.dts b/boards/st/steval_stwinbx1/steval_stwinbx1.dts index 1ca613ff12d23..c9ef1b4299bc4 100644 --- a/boards/st/steval_stwinbx1/steval_stwinbx1.dts +++ b/boards/st/steval_stwinbx1/steval_stwinbx1.dts @@ -14,9 +14,6 @@ compatible = "st,steval_stwinbx1"; chosen { - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; @@ -250,16 +247,14 @@ zephyr_udc0: &usbotg_fs { pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; pinctrl-names = "default"; status = "okay"; - - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; }; +#include <../boards/common/usb/cdc_acm_serial.dtsi> + &adc1 { pinctrl-0 = <&adc1_in1_pc0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; vref-mv = <2750>; status = "okay"; @@ -268,7 +263,7 @@ zephyr_udc0: &usbotg_fs { &adc4 { pinctrl-0 = <&adc4_in3_pc2>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <4>; vref-mv = <2750>; status = "okay"; diff --git a/boards/st/stm3210c_eval/stm3210c_eval.yaml b/boards/st/stm3210c_eval/stm3210c_eval.yaml index ae64ea9fe4702..05f966831caaf 100644 --- a/boards/st/stm3210c_eval/stm3210c_eval.yaml +++ b/boards/st/stm3210c_eval/stm3210c_eval.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 supported: diff --git a/boards/st/stm32373c_eval/stm32373c_eval.yaml b/boards/st/stm32373c_eval/stm32373c_eval.yaml index 6d06bffe95170..f2b59ecd75091 100644 --- a/boards/st/stm32373c_eval/stm32373c_eval.yaml +++ b/boards/st/stm32373c_eval/stm32373c_eval.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 supported: - watchdog diff --git a/boards/st/stm32c0116_dk/stm32c0116_dk.dts b/boards/st/stm32c0116_dk/stm32c0116_dk.dts index 79b4db1fa2583..1e388a0a28109 100644 --- a/boards/st/stm32c0116_dk/stm32c0116_dk.dts +++ b/boards/st/stm32c0116_dk/stm32c0116_dk.dts @@ -141,7 +141,7 @@ &adc1 { pinctrl-0 = <&adc1_in8_pa8>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; diff --git a/boards/st/stm32f072_eval/stm32f072_eval.yaml b/boards/st/stm32f072_eval/stm32f072_eval.yaml index b6655a0172202..72b089f67cb96 100644 --- a/boards/st/stm32f072_eval/stm32f072_eval.yaml +++ b/boards/st/stm32f072_eval/stm32f072_eval.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 16 flash: 128 supported: diff --git a/boards/st/stm32f072b_disco/stm32f072b_disco.yaml b/boards/st/stm32f072b_disco/stm32f072b_disco.yaml index 186d733ca7d68..2824e497ae7cf 100644 --- a/boards/st/stm32f072b_disco/stm32f072b_disco.yaml +++ b/boards/st/stm32f072b_disco/stm32f072b_disco.yaml @@ -7,7 +7,6 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/st/stm32f0_disco/stm32f0_disco.yaml b/boards/st/stm32f0_disco/stm32f0_disco.yaml index 53954e2a4ed11..0f3518142953a 100644 --- a/boards/st/stm32f0_disco/stm32f0_disco.yaml +++ b/boards/st/stm32f0_disco/stm32f0_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 8 supported: - watchdog diff --git a/boards/st/stm32f3_disco/stm32f3_disco.dts b/boards/st/stm32f3_disco/stm32f3_disco.dts index 44a66f038be73..01fbad2721fd1 100644 --- a/boards/st/stm32f3_disco/stm32f3_disco.dts +++ b/boards/st/stm32f3_disco/stm32f3_disco.dts @@ -219,7 +219,7 @@ zephyr_udc0: &usb { &adc1 { pinctrl-0 = <&adc1_in1_pa0>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/st/stm32f3_disco/stm32f3_disco_B.yaml b/boards/st/stm32f3_disco/stm32f3_disco_B.yaml index ebdbe230d20dc..b92695027c2d2 100644 --- a/boards/st/stm32f3_disco/stm32f3_disco_B.yaml +++ b/boards/st/stm32f3_disco/stm32f3_disco_B.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 40 supported: - gpio diff --git a/boards/st/stm32f3_disco/stm32f3_disco_stm32f303xc_E.yaml b/boards/st/stm32f3_disco/stm32f3_disco_stm32f303xc_E.yaml index 9a58627880cdd..dfb2f094e2820 100644 --- a/boards/st/stm32f3_disco/stm32f3_disco_stm32f303xc_E.yaml +++ b/boards/st/stm32f3_disco/stm32f3_disco_stm32f303xc_E.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 40 supported: - gpio diff --git a/boards/st/stm32f411e_disco/stm32f411e_disco.dts b/boards/st/stm32f411e_disco/stm32f411e_disco.dts index 197df98212d30..1f501e05ae03f 100644 --- a/boards/st/stm32f411e_disco/stm32f411e_disco.dts +++ b/boards/st/stm32f411e_disco/stm32f411e_disco.dts @@ -81,6 +81,9 @@ accel0 = &lsm303agr_accel; mcuboot-button0 = &user_button; mcuboot-led0 = &orange_led_3; + die-temp0 = &die_temp; + volt-sensor0 = &vref; + volt-sensor1 = &vbat; }; }; @@ -193,3 +196,20 @@ zephyr_udc0: &usbotg_fs { }; }; }; + +&adc1 { + st,adc-prescaler = <2>; + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&vref { + status = "okay"; +}; + +&vbat { + status = "okay"; +}; diff --git a/boards/st/stm32f411e_disco/stm32f411e_disco_stm32f411xe_B.yaml b/boards/st/stm32f411e_disco/stm32f411e_disco_stm32f411xe_B.yaml index 480b81537b678..61c203105e9c8 100644 --- a/boards/st/stm32f411e_disco/stm32f411e_disco_stm32f411xe_B.yaml +++ b/boards/st/stm32f411e_disco/stm32f411e_disco_stm32f411xe_B.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter vendor: st diff --git a/boards/st/stm32f411e_disco/stm32f411e_disco_stm32f411xe_D.yaml b/boards/st/stm32f411e_disco/stm32f411e_disco_stm32f411xe_D.yaml index 725a9fd46bd09..5591f060a938f 100644 --- a/boards/st/stm32f411e_disco/stm32f411e_disco_stm32f411xe_D.yaml +++ b/boards/st/stm32f411e_disco/stm32f411e_disco_stm32f411xe_D.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter vendor: st diff --git a/boards/st/stm32f412g_disco/doc/index.rst b/boards/st/stm32f412g_disco/doc/index.rst index 7dab509efecc1..db8674826c22c 100644 --- a/boards/st/stm32f412g_disco/doc/index.rst +++ b/boards/st/stm32f412g_disco/doc/index.rst @@ -41,7 +41,7 @@ More information about the board can be found at the `32F412GDISCOVERY website`_ Hardware ******** -STM32F469I-DISCO Discovery kit provides the following hardware components: +STM32F412G-DISCO Discovery kit provides the following hardware components: - STM32F412ZGT6 in LQFP144 package - ARM |reg| 32-bit Cortex |reg| -M4 CPU with FPU diff --git a/boards/st/stm32f412g_disco/stm32f412g_disco.yaml b/boards/st/stm32f412g_disco/stm32f412g_disco.yaml index 5bf836929ba69..41b728a9526bf 100644 --- a/boards/st/stm32f412g_disco/stm32f412g_disco.yaml +++ b/boards/st/stm32f412g_disco/stm32f412g_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_serial diff --git a/boards/st/stm32f413h_disco/Kconfig.stm32f413h_disco b/boards/st/stm32f413h_disco/Kconfig.stm32f413h_disco new file mode 100644 index 0000000000000..0dc50d88be036 --- /dev/null +++ b/boards/st/stm32f413h_disco/Kconfig.stm32f413h_disco @@ -0,0 +1,5 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_STM32F413H_DISCO + select SOC_STM32F413XX diff --git a/boards/st/stm32f413h_disco/arduino_r3_connector.dtsi b/boards/st/stm32f413h_disco/arduino_r3_connector.dtsi new file mode 100644 index 0000000000000..1a5a2bc468ce9 --- /dev/null +++ b/boards/st/stm32f413h_disco/arduino_r3_connector.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioc 0 0>, /* A0 */ + <1 0 &gpioa 1 0>, /* A1 */ + <2 0 &gpioa 2 0>, /* A2 */ + <3 0 &gpioa 5 0>, /* A3 */ + <4 0 &gpiob 1 0>, /* A4 */ + <5 0 &gpioc 4 0>, /* A5 */ + <6 0 &gpiof 6 0>, /* D0 */ + <7 0 &gpiof 7 0>, /* D1 */ + <8 0 &gpiog 13 0>, /* D2 */ + <9 0 &gpiof 10 0>, /* D3 */ + <10 0 &gpiob 6 0>, /* D4 */ + <11 0 &gpioe 6 0>, /* D5 */ + <12 0 &gpiob 0 0>, /* D6 */ + <13 0 &gpioc 13 0>, /* D7 */ + <14 0 &gpioa 4 0>, /* D8 */ + <15 0 &gpiob 8 0>, /* D9 */ + <16 0 &gpioa 15 0>, /* D10 */ + <17 0 &gpiob 5 0>, /* D11 */ + <18 0 &gpiob 4 0>, /* D12 */ + <19 0 &gpiob 12 0>, /* D13 */ + <20 0 &gpiob 11 0>, /* D14 */ + <21 0 &gpiob 10 0>; /* D15 */ + }; +}; + +arduino_i2c: &i2c2 {}; +arduino_spi: &spi3 {}; +arduino_serial: &uart7 {}; diff --git a/boards/st/stm32f413h_disco/board.cmake b/boards/st/stm32f413h_disco/board.cmake new file mode 100644 index 0000000000000..800b779a42dbc --- /dev/null +++ b/boards/st/stm32f413h_disco/board.cmake @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +# keep first +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +board_runner_args(jlink "--device=STM32F413ZH" "--speed=4000") + +# keep first +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/st/stm32f413h_disco/board.yml b/boards/st/stm32f413h_disco/board.yml new file mode 100644 index 0000000000000..e29d47b57be9b --- /dev/null +++ b/boards/st/stm32f413h_disco/board.yml @@ -0,0 +1,6 @@ +board: + name: stm32f413h_disco + full_name: STM32F413H Discovery + vendor: st + socs: + - name: stm32f413xx diff --git a/boards/st/stm32f413h_disco/doc/img/stm32F413H_DiscoveryKit.webp b/boards/st/stm32f413h_disco/doc/img/stm32F413H_DiscoveryKit.webp new file mode 100644 index 0000000000000..93785299b0ba0 Binary files /dev/null and b/boards/st/stm32f413h_disco/doc/img/stm32F413H_DiscoveryKit.webp differ diff --git a/boards/st/stm32f413h_disco/doc/index.rst b/boards/st/stm32f413h_disco/doc/index.rst new file mode 100644 index 0000000000000..49ce176da6514 --- /dev/null +++ b/boards/st/stm32f413h_disco/doc/index.rst @@ -0,0 +1,206 @@ +.. zephyr:board:: stm32f413h_disco + +Overview +******** + +The STM32F413H-DISCO Discovery kit features an ARM Cortex-M4 based STM32F413ZH MCU +with a wide range of connectivity support and configurations. Here are +some highlights of the STM32F413H-DISCO board: + + +- STM32F413ZHT6 microcontroller featuring 1.5 Mbyte of Flash memory and 320 Kbytes of RAM in an LQFP144 package +- On-board ST-LINK/V2-1 SWD debugger supporting USB re-enumeration capability: + + - USB virtual COM port + - mass storage + - debug port + +- 1.54 inch 240x240 pixel TFT color LCD with parallel interface and capacitive touchscreen +- I2S Audio CODEC, with a stereo headset jack, including analog microphone input and a loudspeaker output +- Stereo digital MEMS microphones +- MicroSD card connector extension +- I2C extension connector +- 128 Mbit Quad-SPI Nor Flash +- 8 Mbit 16-bit wide PSRAM +- Reset and User buttons +- Two color user LEDs. +- USB OTG FS with Micro-AB connector +- Four power supply options: + + - ST-LINK/V2-1 USB connector + - User USB FS connector + - VIN from Arduino* connectors + - + 5 V from Arduino* connectors + +- Two power supplies for MCU: 2.0 V and 3.3 V +- Compatible with Arduino(tm) Uno revision 3 connectors +- Extension connector for direct access to various features of STM32F413ZHT6 MCU +- Comprehensive free software including a variety of examples, part of STM32Cube package + +More information about the board can be found at the `32F413HDISCOVERY website`_. + +Hardware +******** + +STM32F413H-DISCO Discovery kit provides the following hardware components: + +- STM32F413ZHT6 in LQFP144 package +- ARM |reg| 32-bit Cortex |reg| -M4 CPU with FPU +- 100 MHz max CPU frequency +- VDD from 1.7 V to 3.6 V +- 1.5 MB Flash +- 320 KB SRAM +- GPIO with external interrupt capability +- LCD parallel interface, 8080/6800 modes +- 1x12-bit ADC with 16 channels +- RTC +- Advanced-control Timer +- General Purpose Timers (12) +- Watchdog Timers (2) +- USART/UART (10) +- I2C (4) +- SPI (5) +- SDIO +- SAI +- 3xCAN +- USB OTG 2.0 Full-speed +- CRC calculation unit +- True random number generator +- DMA Controller + +More information about STM32F413ZH can be found here: + - `STM32F413ZH on www.st.com`_ + - `STM32F413 reference manual`_ + +Supported Features +================== + +The Zephyr STM32F413H-DISCO board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ + +Other hardware features are not yet supported by Zephyr. + +The default configuration can be found in +:zephyr_file:`boards/st/stm32f413h_disco/stm32f413h_disco_defconfig` + + +Pin Mapping +=========== + +STM32F413H-DISCO Discovery kit has 8 GPIO controllers. These controllers are responsible for pin muxing, +input/output, pull-up, etc. + +For more details please refer to `32F413HDISCOVERY board User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- +- UART_6_TX : PG14 +- UART_6_RX : PG9 +- LD1 : PE3 +- LD2 : PC5 + +System Clock +============ + +STM32F413H-DISCO System Clock could be driven by internal or external oscillator, +as well as main PLL clock. By default System clock is driven by PLL clock at 100MHz, +that is driven by the internal oscillator. + +Serial Port +=========== + +The STM32F413H-DISCO Discovery kit has up to 10 UARTs. The Zephyr console output is assigned to UART6. +Default settings are 115200 8N1. + + +Programming and Debugging +************************* + +STM32F413H-DISCO Discovery kit includes an ST-LINK/V2 embedded debug tool interface. + +Applications for the STM32F413H-DISCO board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Flashing +======== + +The board is configured to be flashed using west `STM32CubeProgrammer`_ runner, +so its :ref:`installation ` is required. + +Alternatively, OpenOCD or JLink can also be used to flash the board using +the ``--runner`` (or ``-r``) option: + +.. code-block:: console + + $ west flash --runner openocd + $ west flash --runner jlink + +Flashing an application to STM32F413H-DISCO +------------------------------------------- + +Connect the STM32F413H-DISCO Discovery kit to your host computer using +the USB port, then run a serial host program to connect with your +board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +Then build and flash an application. Here is an example for the +:zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32f413h_disco + :goals: build flash + +You should see the following message on the console: + +.. code-block:: console + + Hello World! stm32f413h_disco/stm32f413xx + + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32f413h_disco + :maybe-skip-config: + :goals: debug + +.. _32F413HDISCOVERY website: + https://www.st.com/en/evaluation-tools/32f413hdiscovery.html + +.. _32F413HDISCOVERY board User Manual: + https://www.st.com/resource/en/user_manual/um2135-discovery-kit-with-stm32f413zh-mcu-stmicroelectronics.pdf + +.. _STM32F413ZH on www.st.com: + https://www.st.com/en/microcontrollers/stm32f413zh.html + +.. _STM32F413 reference manual: + https://www.st.com/resource/en/reference_manual/rm0430-stm32f413423-advanced-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/stm32f413h_disco/stm32f413h_disco.dts b/boards/st/stm32f413h_disco/stm32f413h_disco.dts new file mode 100644 index 0000000000000..72315d784e239 --- /dev/null +++ b/boards/st/stm32f413h_disco/stm32f413h_disco.dts @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "arduino_r3_connector.dtsi" +#include + +/ { + model = "STMicroelectronics STM32F413H-DISCO board"; + compatible = "st,stm32f413h-disco"; + + chosen { + zephyr,console = &usart6; + zephyr,shell-uart = &usart6; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + green_led_1: led_1 { + gpios = <&gpioc 5 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + red_led_2: led_2 { + gpios = <&gpioe 3 GPIO_ACTIVE_HIGH>; + label = "User LD4"; + }; + }; + + aliases { + led0 = &green_led_1; + led1 = &red_led_2; + + }; +}; + +&clk_lsi { + status = "okay"; +}; + +&clk_hse { + hse-bypass; + clock-frequency = ; /* STLink 8MHz clock */ + status = "okay"; +}; + +&pll { + div-m = <4>; + mul-n = <100>; + div-p = <2>; + div-q = <8>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <2>; + apb2-prescaler = <1>; +}; + +&usart6 { + pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&uart7 { + pinctrl-0 = <&uart7_tx_pf7 &uart7_rx_pf6>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; + +&spi3 { + pinctrl-0 = <&spi3_nss_pa15 &spi3_sck_pb12 + &spi3_miso_pb4 &spi3_mosi_pb5>; + pinctrl-names = "default"; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x10000000>, + <&rcc STM32_SRC_LSI RTC_SEL(2)>; + status = "okay"; +}; diff --git a/boards/st/stm32f413h_disco/stm32f413h_disco.yaml b/boards/st/stm32f413h_disco/stm32f413h_disco.yaml new file mode 100644 index 0000000000000..6fd4f5eb33181 --- /dev/null +++ b/boards/st/stm32f413h_disco/stm32f413h_disco.yaml @@ -0,0 +1,13 @@ +identifier: stm32f413h_disco +name: ST STM32F413H Discovery +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - arduino_gpio + - arduino_serial + - arduino_i2c + - arduino_spi +vendor: st diff --git a/boards/st/stm32f413h_disco/stm32f413h_disco_defconfig b/boards/st/stm32f413h_disco/stm32f413h_disco_defconfig new file mode 100644 index 0000000000000..2ae252482c91b --- /dev/null +++ b/boards/st/stm32f413h_disco/stm32f413h_disco_defconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +CONFIG_SERIAL=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO ports A, B, C, D, E, F, G, H +CONFIG_GPIO=y diff --git a/boards/st/stm32f413h_disco/support/openocd.cfg b/boards/st/stm32f413h_disco/support/openocd.cfg new file mode 100644 index 0000000000000..837f0cd29589f --- /dev/null +++ b/boards/st/stm32f413h_disco/support/openocd.cfg @@ -0,0 +1,12 @@ +source [find board/stm32f4discovery.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/boards/st/stm32f429i_disc1/stm32f429i_disc1.yaml b/boards/st/stm32f429i_disc1/stm32f429i_disc1.yaml index 5d4b25c83122a..10fbd8485d46c 100644 --- a/boards/st/stm32f429i_disc1/stm32f429i_disc1.yaml +++ b/boards/st/stm32f429i_disc1/stm32f429i_disc1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 2048 supported: diff --git a/boards/st/stm32f469i_disco/stm32f469i_disco.yaml b/boards/st/stm32f469i_disco/stm32f469i_disco.yaml index fef17c354b84f..32f51672d4617 100644 --- a/boards/st/stm32f469i_disco/stm32f469i_disco.yaml +++ b/boards/st/stm32f469i_disco/stm32f469i_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 320 flash: 2048 supported: diff --git a/boards/st/stm32f4_disco/doc/index.rst b/boards/st/stm32f4_disco/doc/index.rst index f21b1cdc01407..b0106f4a6621a 100644 --- a/boards/st/stm32f4_disco/doc/index.rst +++ b/boards/st/stm32f4_disco/doc/index.rst @@ -89,6 +89,12 @@ The Zephyr stm32f4_disco board configuration supports the following hardware fea +-----------+------------+-------------------------------------+ | CAN | on-chip | CAN controller | +-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c controller | ++-----------+------------+-------------------------------------+ +| I2S | on-chip | i2s controller | ++-----------+------------+-------------------------------------+ +| AUDIO | on-board | audio codec on CS43L22 via I2S3 | ++-----------+------------+-------------------------------------+ .. note:: CAN feature requires CAN transceiver, such as `SK Pang CAN breakout board`_. Zephyr default configuration uses CAN_2 exclusively, as simultaneous use @@ -113,8 +119,6 @@ Default Zephyr Peripheral Mapping: .. rst-class:: rst-columns -- UART_1_TX : PB6 -- UART_1_RX : PB7 - UART_2_TX : PA2 - UART_2_RX : PA3 - USER_PB : PA0 @@ -124,10 +128,14 @@ Default Zephyr Peripheral Mapping: - LD6 : PD15 - USB DM : PA11 - USB DP : PA12 -- CAN1_RX : PB8 -- CAN1_TX : PB9 - CAN2_RX : PB5 - CAN2_TX : PB13 +- I2C1_SDA : PB9 +- I2C1_SCL : PB6 +- I2S3_MCK : PC7 +- I2S3_CK : PC10 +- I2S3_SD : PC12 +- I2S3_WS : PA4 System Clock ============ diff --git a/boards/st/stm32f4_disco/stm32f4_disco.dts b/boards/st/stm32f4_disco/stm32f4_disco.dts index fdc52ed97842c..10404e49103cd 100644 --- a/boards/st/stm32f4_disco/stm32f4_disco.dts +++ b/boards/st/stm32f4_disco/stm32f4_disco.dts @@ -77,16 +77,12 @@ led2 = &red_led_5; led3 = &blue_led_6; sw0 = &user_button; + die-temp0 = &die_temp; + volt-sensor0 = &vref; + volt-sensor1 = &vbat; }; }; -&usart1 { - pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; - pinctrl-names = "default"; - current-speed = <115200>; - status = "okay"; -}; - &clk_lsi { status = "okay"; }; @@ -156,14 +152,64 @@ zephyr_udc0: &usbotg_fs { status = "okay"; }; -&can1 { - pinctrl-0 = <&can1_rx_pb8 &can1_tx_pb9>; +&can2 { + pinctrl-0 = <&can2_rx_pb5 &can2_tx_pb13>; pinctrl-names = "default"; - status = "disabled"; + status = "okay"; }; -&can2 { - pinctrl-0 = <&can2_rx_pb5 &can2_tx_pb13>; +&adc1 { + st,adc-prescaler = <2>; + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&vref { + status = "okay"; +}; + +&vbat { + status = "okay"; +}; + +&dma1 { + status = "okay"; +}; + +&plli2s { + /* Minimize audio clock error (with i2s mck-enabled) for all of: + * - 22.05kHz / 16b, 24b or 32b + * - 44.1kHz / 16b, 24b or 32b + * - 88.2kHz / 16b or 24b + * Note: because the PLLI2S is dependent on the main PLL, the latter + * should not be changed without checking impact on PLLI2S + */ + mul-n = <271>; + div-r = <2>; + status = "okay"; +}; + +&i2s3 { + mck-enabled; + pinctrl-0 = <&i2s3_ws_pa4 &i2s3_ck_pc10 &i2s3_sd_pc12 &i2s3_mck_pc7>; + pinctrl-names = "default"; + clocks = <&rcc STM32_CLOCK(APB1, 15U)>, + <&rcc STM32_SRC_PLLI2S_R I2S_SEL(0)>; + status = "okay"; +}; + +&i2c1 { + clock-frequency = ; + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb9>; pinctrl-names = "default"; status = "okay"; + + audio_codec: cs43l22@4a { + compatible = "cirrus,cs43l22"; + reg = <0x4a>; + reset-gpios = <&gpiod 4 0>; + }; }; diff --git a/boards/st/stm32f4_disco/stm32f4_disco.yaml b/boards/st/stm32f4_disco/stm32f4_disco.yaml index b3cca00ab7b0f..89bc800480467 100644 --- a/boards/st/stm32f4_disco/stm32f4_disco.yaml +++ b/boards/st/stm32f4_disco/stm32f4_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/st/stm32f723e_disco/stm32f723e_disco.yaml b/boards/st/stm32f723e_disco/stm32f723e_disco.yaml index 1908ae26279a7..61334096389db 100644 --- a/boards/st/stm32f723e_disco/stm32f723e_disco.yaml +++ b/boards/st/stm32f723e_disco/stm32f723e_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 512 supported: diff --git a/boards/st/stm32f746g_disco/Kconfig.defconfig b/boards/st/stm32f746g_disco/Kconfig.defconfig index e617f92308bd7..a3b98a61c92c3 100644 --- a/boards/st/stm32f746g_disco/Kconfig.defconfig +++ b/boards/st/stm32f746g_disco/Kconfig.defconfig @@ -24,13 +24,6 @@ config MEMC endif # DISPLAY -if INPUT - -config INPUT_FT5336_INTERRUPT - default y - -endif # INPUT - config DISK_DRIVER_SDMMC default y if DISK_DRIVERS diff --git a/boards/st/stm32f746g_disco/stm32f746g_disco.yaml b/boards/st/stm32f746g_disco/stm32f746g_disco.yaml index 7d58f2b1f2b90..adab2d743f041 100644 --- a/boards/st/stm32f746g_disco/stm32f746g_disco.yaml +++ b/boards/st/stm32f746g_disco/stm32f746g_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/boards/st/stm32f7508_dk/Kconfig.defconfig b/boards/st/stm32f7508_dk/Kconfig.defconfig index c43b749d79b91..1123e29477734 100644 --- a/boards/st/stm32f7508_dk/Kconfig.defconfig +++ b/boards/st/stm32f7508_dk/Kconfig.defconfig @@ -24,13 +24,6 @@ endif # DISPLAY config INPUT default y if LVGL -if INPUT - -config INPUT_FT5336_INTERRUPT - default y - -endif # INPUT - config DISK_DRIVER_SDMMC default y if DISK_DRIVERS diff --git a/boards/st/stm32f7508_dk/stm32f7508_dk.yaml b/boards/st/stm32f7508_dk/stm32f7508_dk.yaml index 9415c4660d1c7..28ff27942f5c3 100644 --- a/boards/st/stm32f7508_dk/stm32f7508_dk.yaml +++ b/boards/st/stm32f7508_dk/stm32f7508_dk.yaml @@ -8,7 +8,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 320 flash: 64 supported: diff --git a/boards/st/stm32f769i_disco/stm32f769i_disco.dts b/boards/st/stm32f769i_disco/stm32f769i_disco.dts index 94dd6f6bb22c9..bae733080165c 100644 --- a/boards/st/stm32f769i_disco/stm32f769i_disco.dts +++ b/boards/st/stm32f769i_disco/stm32f769i_disco.dts @@ -52,10 +52,6 @@ gpios = <&gpioa 12 GPIO_ACTIVE_HIGH>; label = "User LD3"; }; - red_led_4:led_4 { - gpios = <&gpiod 4 GPIO_ACTIVE_HIGH>; - label = "User LD4"; - }; }; gpio_keys { @@ -76,7 +72,6 @@ led0 = &red_led_1; led1 = &green_led_2; led2 = &green_led_3; - led3 = &red_led_4; sw0 = &user_button; }; diff --git a/boards/st/stm32f769i_disco/stm32f769i_disco.yaml b/boards/st/stm32f769i_disco/stm32f769i_disco.yaml index 69f06949e2a97..1f3c62f4c8d3b 100644 --- a/boards/st/stm32f769i_disco/stm32f769i_disco.yaml +++ b/boards/st/stm32f769i_disco/stm32f769i_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 384 flash: 2048 supported: diff --git a/boards/st/stm32g0316_disco/stm32g0316_disco.yaml b/boards/st/stm32g0316_disco/stm32g0316_disco.yaml index 3b6cb215ce435..0e55776456044 100644 --- a/boards/st/stm32g0316_disco/stm32g0316_disco.yaml +++ b/boards/st/stm32g0316_disco/stm32g0316_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 8 flash: 32 supported: diff --git a/boards/st/stm32g071b_disco/stm32g071b_disco.yaml b/boards/st/stm32g071b_disco/stm32g071b_disco.yaml index 817860f27ac06..439412af8295d 100644 --- a/boards/st/stm32g071b_disco/stm32g071b_disco.yaml +++ b/boards/st/stm32g071b_disco/stm32g071b_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 36 flash: 128 supported: diff --git a/boards/st/stm32g081b_eval/stm32g081b_eval.dts b/boards/st/stm32g081b_eval/stm32g081b_eval.dts index fa29e8147d0dc..103e745cfe024 100644 --- a/boards/st/stm32g081b_eval/stm32g081b_eval.dts +++ b/boards/st/stm32g081b_eval/stm32g081b_eval.dts @@ -131,7 +131,7 @@ &adc1 { pinctrl-0 = <&adc1_in3_pa3 &adc1_in9_pb1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; diff --git a/boards/st/stm32g081b_eval/stm32g081b_eval.yaml b/boards/st/stm32g081b_eval/stm32g081b_eval.yaml index 313faf236a87f..13efbbc72f365 100644 --- a/boards/st/stm32g081b_eval/stm32g081b_eval.yaml +++ b/boards/st/stm32g081b_eval/stm32g081b_eval.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 128 supported: diff --git a/boards/st/stm32h573i_dk/stm32h573i_dk.dts b/boards/st/stm32h573i_dk/stm32h573i_dk.dts index fcc109526287c..97664d80ebab6 100644 --- a/boards/st/stm32h573i_dk/stm32h573i_dk.dts +++ b/boards/st/stm32h573i_dk/stm32h573i_dk.dts @@ -241,7 +241,7 @@ <&rcc STM32_SRC_HCLK ADCDAC_SEL(0)>; pinctrl-0 = <&adc1_inp6_pf12>; /* Arduino A5 */ pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <6>; status = "okay"; }; diff --git a/boards/st/stm32h735g_disco/stm32h735g_disco.dts b/boards/st/stm32h735g_disco/stm32h735g_disco.dts index af351902869a4..0dc2d17f93da9 100644 --- a/boards/st/stm32h735g_disco/stm32h735g_disco.dts +++ b/boards/st/stm32h735g_disco/stm32h735g_disco.dts @@ -124,7 +124,7 @@ &adc1 { pinctrl-0 = <&adc1_inp0_pa0_c>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/stm32h735g_disco/stm32h735g_disco.yaml b/boards/st/stm32h735g_disco/stm32h735g_disco.yaml index cf0bbb425bad1..37e3671d9bcc7 100644 --- a/boards/st/stm32h735g_disco/stm32h735g_disco.yaml +++ b/boards/st/stm32h735g_disco/stm32h735g_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 368 flash: 1024 supported: diff --git a/boards/st/stm32h747i_disco/CMakeLists.txt b/boards/st/stm32h747i_disco/CMakeLists.txt index 2f480bd7966c4..7601729738961 100644 --- a/boards/st/stm32h747i_disco/CMakeLists.txt +++ b/boards/st/stm32h747i_disco/CMakeLists.txt @@ -5,5 +5,5 @@ # # Add custom linker section to relocate framebuffers to PSRAM -zephyr_linker_sources_ifdef(CONFIG_LV_Z_VBD_CUSTOM_SECTION +zephyr_linker_sources_ifdef(CONFIG_LV_Z_VDB_CUSTOM_SECTION SECTIONS dc_ram.ld) diff --git a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m4.yaml b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m4.yaml index 2a544e167013a..553524ff898e1 100644 --- a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m4.yaml +++ b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m4.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 288 flash: 1024 supported: diff --git a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.yaml b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.yaml index d566de9a4cad7..a7ff5d4a4bd39 100644 --- a/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.yaml +++ b/boards/st/stm32h747i_disco/stm32h747i_disco_stm32h747xx_m7.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 1024 supported: diff --git a/boards/st/stm32h750b_dk/stm32h750b_dk.dts b/boards/st/stm32h750b_dk/stm32h750b_dk.dts index 711a2ba7eee40..34a82721b0258 100644 --- a/boards/st/stm32h750b_dk/stm32h750b_dk.dts +++ b/boards/st/stm32h750b_dk/stm32h750b_dk.dts @@ -21,6 +21,7 @@ zephyr,flash = &flash0; zephyr,flash-controller = &mt25ql512ab1; zephyr,display = <dc; + zephyr,code-partition = &slot0_partition; }; sdram2: sdram@d0000000 { @@ -78,6 +79,19 @@ status = "okay"; }; +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + /* Flash has 128KB sector size */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(128)>; + }; + }; +}; + <dc { pinctrl-0 = <<dc_r0_pi15 <dc_r1_pj0 <dc_r2_pj1 <dc_r3_ph9 <dc_r4_pj3 <dc_r5_pj4 <dc_r6_pj5 <dc_r7_pj6 @@ -165,6 +179,8 @@ dual-flash; status = "okay"; + /* Sector erase 64KB uniform granularity */ + /* Subsector erase 4KB, 32KB granularity */ mt25ql512ab1: qspi-nor-flash-1@90000000 { compatible = "st,stm32-qspi-nor"; reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */ @@ -178,8 +194,19 @@ #address-cells = <1>; #size-cells = <1>; - partition@0 { - reg = <0x0 DT_SIZE_M(64)>; + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x00000000 DT_SIZE_K(2048)>; + }; + + slot1_partition: partition@200000 { + label = "image-1"; + reg = <0x00200000 DT_SIZE_K(2048)>; + }; + + storage_partition: partition@400000 { + label = "storage"; + reg = <0x00400000 DT_SIZE_K(128)>; }; }; }; @@ -239,7 +266,7 @@ }; &adc3 { - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/stm32h750b_dk/stm32h750b_dk.yaml b/boards/st/stm32h750b_dk/stm32h750b_dk.yaml index da7d087b0605c..24751cc5c13fc 100644 --- a/boards/st/stm32h750b_dk/stm32h750b_dk.yaml +++ b/boards/st/stm32h750b_dk/stm32h750b_dk.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 1024 flash: 128 supported: diff --git a/boards/st/stm32h7b3i_dk/CMakeLists.txt b/boards/st/stm32h7b3i_dk/CMakeLists.txt index 6edbccee55cdc..67def763643c7 100644 --- a/boards/st/stm32h7b3i_dk/CMakeLists.txt +++ b/boards/st/stm32h7b3i_dk/CMakeLists.txt @@ -5,5 +5,5 @@ # # Add custom linker section to relocate framebuffers to PSRAM -zephyr_linker_sources_ifdef(CONFIG_LV_Z_VBD_CUSTOM_SECTION +zephyr_linker_sources_ifdef(CONFIG_LV_Z_VDB_CUSTOM_SECTION SECTIONS dc_ram.ld) diff --git a/boards/st/stm32h7b3i_dk/Kconfig.defconfig b/boards/st/stm32h7b3i_dk/Kconfig.defconfig index 863570e555a1b..766cff03a3e81 100644 --- a/boards/st/stm32h7b3i_dk/Kconfig.defconfig +++ b/boards/st/stm32h7b3i_dk/Kconfig.defconfig @@ -9,9 +9,6 @@ if BOARD_STM32H7B3I_DK config INPUT default y if LVGL -config INPUT_FT5336_INTERRUPT - default y if INPUT_FT5336 - # MEMC needs to be enabled in order to store # display buffer to external SDRAM connected to FMC config MEMC @@ -22,12 +19,9 @@ if LVGL config CACHE_MANAGEMENT default y -config LV_USE_GPU_STM32_DMA2D +config LV_USE_DRAW_DMA2D default y -config LV_GPU_DMA2D_CMSIS_INCLUDE - default "stm32h7xx.h" - config STM32_LTDC_FB_NUM default 2 @@ -40,7 +34,7 @@ config LV_Z_DOUBLE_VDB config LV_Z_FULL_REFRESH default y -config LV_Z_VBD_CUSTOM_SECTION +config LV_Z_VDB_CUSTOM_SECTION default y config LV_Z_FLUSH_THREAD diff --git a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts index 7e4fe7f9c2d7f..23d71b056441a 100644 --- a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts +++ b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts @@ -75,6 +75,28 @@ #phy-cells = <0>; }; + dmci_camera_connector: connector_dcmi_camera { + compatible = "st,stm32-dcmi-camera-fpu-330zh"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <3 0 &gpiod 12 0>, /* I2C4_SCL */ + <4 0 &gpiod 13 0>, /* I2C4_SDA */ + <5 0 &gpioa 0 0>, /* RESET# */ + <6 0 &gpioa 7 0>, /* PWDN_EN */ + <12 0 &gpiob 7 0>, /* DCMI_VSYNC */ + <14 0 &gpioa 4 0>, /* DCMI_HSYNC */ + <16 0 &gpioa 6 0>, /* DCMI_PIXCK */ + <20 0 &gpiob 9 0>, /* DCMI_D7 */ + <21 0 &gpiob 8 0>, /* DCMI_D6 */ + <22 0 &gpiod 3 0>, /* DCMI_D5 */ + <23 0 &gpioc 11 0>, /* DCMI_D4 */ + <24 0 &gpioc 9 0>, /* DCMI_D3 */ + <25 0 &gpiog 10 0>, /* DCMI_D2 */ + <26 0 &gpioc 7 0>, /* DCMI_D1 */ + <27 0 &gpioc 6 0>; /* DCMI_D0 */ + }; + aliases { led0 = &blue_led; led1 = &red_led; @@ -278,3 +300,7 @@ }; }; }; + +st_cam_i2c: &i2c4 {}; + +st_cam_dvp: &dcmi {}; diff --git a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.yaml b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.yaml index 3779381d564bf..3c0cf307770b0 100644 --- a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.yaml +++ b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 1376 flash: 2048 supported: diff --git a/boards/st/stm32h7s78_dk/doc/index.rst b/boards/st/stm32h7s78_dk/doc/index.rst index 430b3d9dd0edc..a6f8455dc6d00 100644 --- a/boards/st/stm32h7s78_dk/doc/index.rst +++ b/boards/st/stm32h7s78_dk/doc/index.rst @@ -172,6 +172,8 @@ hardware features: +-----------+------------+-------------------------------------+ | SPI | on-chip | spi bus | +-----------+------------+-------------------------------------+ +| USB | on-chip | usb | ++-----------+------------+-------------------------------------+ Other hardware features are not yet supported on this Zephyr port. @@ -215,6 +217,7 @@ Default Zephyr Peripheral Mapping: - LD3 (red) : PM2 - LD4 (blue) : PM3 - ADC1 channel 6 input : PF12 +- USB OTG FS DM/DP : PM12/PM11 System Clock ------------ @@ -229,6 +232,11 @@ Serial Port STM32H7S78-DK Discovery board has 2 U(S)ARTs. The Zephyr console output is assigned to USART4. Default settings are 115200 8N1. +USB +--- + +STM32H7S78-DK Discovery board has 2 USB Type-C connectors. Currently, only +USB port2 (FS) is supported. Programming and Debugging ************************* diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk.dts b/boards/st/stm32h7s78_dk/stm32h7s78_dk.dts index 6cd70cbe60d07..5cfbbb449b85a 100644 --- a/boards/st/stm32h7s78_dk/stm32h7s78_dk.dts +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk.dts @@ -148,7 +148,7 @@ &adc1 { pinctrl-0 = <&adc1_inp6_pf12>; /* Arduino A3 */ pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -156,7 +156,7 @@ &adc2 { pinctrl-0 = <&adc2_inp2_pf13>; /* Arduino A4 */ pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -184,3 +184,11 @@ &vbat { status = "okay"; }; + +usb2: &usbotg_fs { + pinctrl-0 = <&usb_otg_fs_dm_pm12 &usb_otg_fs_dp_pm11>; + pinctrl-names = "default"; + status = "okay"; +}; + +zephyr_udc0: &usb2 {}; diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk.yaml b/boards/st/stm32h7s78_dk/stm32h7s78_dk.yaml index e48895cbce1bb..7e14a410259ff 100644 --- a/boards/st/stm32h7s78_dk/stm32h7s78_dk.yaml +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk.yaml @@ -13,4 +13,6 @@ supported: - watchdog - entropy - adc + - usb_device + - usbd vendor: st diff --git a/boards/st/stm32l1_disco/stm32l152c_disco.yaml b/boards/st/stm32l1_disco/stm32l152c_disco.yaml index 9ada265eed0c9..738f23ea4bdae 100644 --- a/boards/st/stm32l1_disco/stm32l152c_disco.yaml +++ b/boards/st/stm32l1_disco/stm32l152c_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 256 supported: diff --git a/boards/st/stm32l1_disco/stm32l1_disco.yaml b/boards/st/stm32l1_disco/stm32l1_disco.yaml index ac536ecacbb15..b5d4711295d48 100644 --- a/boards/st/stm32l1_disco/stm32l1_disco.yaml +++ b/boards/st/stm32l1_disco/stm32l1_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 16 flash: 128 supported: diff --git a/boards/st/stm32l476g_disco/stm32l476g_disco.yaml b/boards/st/stm32l476g_disco/stm32l476g_disco.yaml index 671e173851978..49f5036c9c7e2 100644 --- a/boards/st/stm32l476g_disco/stm32l476g_disco.yaml +++ b/boards/st/stm32l476g_disco/stm32l476g_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 96 flash: 1024 supported: diff --git a/boards/st/stm32l496g_disco/stm32l496g_disco.dts b/boards/st/stm32l496g_disco/stm32l496g_disco.dts index a6d1e876f4e81..4a942a5ab066c 100644 --- a/boards/st/stm32l496g_disco/stm32l496g_disco.dts +++ b/boards/st/stm32l496g_disco/stm32l496g_disco.dts @@ -164,7 +164,7 @@ &adc1 { pinctrl-0 = < &adc1_in2_pc1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; @@ -194,7 +194,7 @@ zephyr_udc0: &usbotg_fs { &quadspi_bk1_ncs_pb11 &quadspi_clk_pa3>; pinctrl-names = "default"; - dmas = <&dma2 7 3 0x480>; /* channel 7 request 3 on DMA2 */ + dmas = <&dma2 7 3 STM32_DMA_PERIPH_RX>; /* channel 7 request 3 on DMA2 */ dma-names = "tx_rx"; flash-id = <1>; diff --git a/boards/st/stm32l496g_disco/stm32l496g_disco.yaml b/boards/st/stm32l496g_disco/stm32l496g_disco.yaml index e6b153cb0e492..70656aa4da2d1 100644 --- a/boards/st/stm32l496g_disco/stm32l496g_disco.yaml +++ b/boards/st/stm32l496g_disco/stm32l496g_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.dts b/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.dts index 49737c68c8f56..2e6175dd171e0 100644 --- a/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.dts +++ b/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.dts @@ -22,7 +22,10 @@ leds { compatible = "gpio-leds"; - /* N.B. LD1 (orange) is not wired to MCU */ + orange_led: led_1 { + gpios = <&mfx 0 GPIO_ACTIVE_LOW>; + label = "User LD1"; + }; green_led: led_2 { gpios = <&gpioh 4 GPIO_ACTIVE_LOW>; label = "User LD2"; @@ -36,11 +39,36 @@ gpios = <&gpioc 13 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; zephyr,code = ; }; + joy_up: joystick_up { + label = "joystick up"; + gpios = <&mfx 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + zephyr,code = ; + }; + joy_down: joystick_down { + label = "joystick down"; + gpios = <&mfx 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + zephyr,code = ; + }; + joy_right: joystick_right { + label = "joystick right"; + gpios = <&mfx 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + zephyr,code = ; + }; + joy_left: joystick_left { + label = "joystick left"; + gpios = <&mfx 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + zephyr,code = ; + }; }; aliases { led0 = &green_led; + led1 = &orange_led; sw0 = &joy_sel; + sw1 = &joy_up; + sw2 = &joy_down; + sw3 = &joy_right; + sw4 = &joy_left; die-temp0 = &die_temp; volt-sensor0 = &vref; volt-sensor1 = &vbat; @@ -155,6 +183,15 @@ pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pg13>; pinctrl-names = "default"; clock-frequency = ; + + mfx: gpio@42 { + compatible = "st,mfxstm32l152"; + reg = <0x42>; + ngpios = <24>; + int-gpios = <&gpioi 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; + gpio-controller; + #gpio-cells = <2>; + }; }; &i2c3 { @@ -190,7 +227,7 @@ pinctrl-0 = <&adc1_in5_pa0 &adc1_in12_pa7 &adc1_in15_pb0 &adc1_in4_pc3 &adc1_in13_pc4>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <1>; }; diff --git a/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.yaml b/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.yaml index 3b4ef674d8413..8f8b558ed9f54 100644 --- a/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.yaml +++ b/boards/st/stm32l4r9i_disco/stm32l4r9i_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 192 flash: 2048 vendor: st diff --git a/boards/st/stm32l562e_dk/Kconfig.defconfig b/boards/st/stm32l562e_dk/Kconfig.defconfig index 7547fd3eb9c34..154a875da56cc 100644 --- a/boards/st/stm32l562e_dk/Kconfig.defconfig +++ b/boards/st/stm32l562e_dk/Kconfig.defconfig @@ -42,4 +42,14 @@ config COMMON_LIBC_MALLOC_ARENA_SIZE endif # BUILD_WITH_TFM +config INPUT + default y if LVGL + +if INPUT + +config INPUT_FT5336_INTERRUPT + default y + +endif # INPUT + endif # BOARD_STM32L562E_DK diff --git a/boards/st/stm32l562e_dk/doc/index.rst b/boards/st/stm32l562e_dk/doc/index.rst index 02109d0a5f7c8..4e15997193655 100644 --- a/boards/st/stm32l562e_dk/doc/index.rst +++ b/boards/st/stm32l562e_dk/doc/index.rst @@ -153,6 +153,9 @@ hardware features: +-----------+------------+-------------------------------------+ | DAC | on-chip | DAC Controller | +-----------+------------+-------------------------------------+ +| DISPLAY | on-chip | TFT LCD screen with st7789v driver | +| | | and touch panel with ft5336 driver | ++-----------+------------+-------------------------------------+ | DMA | on-chip | Direct Memory Access | +-----------+------------+-------------------------------------+ | GPIO | on-chip | gpio | @@ -273,6 +276,16 @@ Serial Port STM32L562E-DK Discovery board has 6 U(S)ARTs. The Zephyr console output is assigned to USART1. Default settings are 115200 8N1. +TFT LCD screen and touch panel +------------------------------ + +The TFT LCD screen and touch panel are supported for the STM32L562E-DK Discovery board. +They can be tested using :zephyr:code-sample:`lvgl` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/display/lvgl + :board: stm32l562e_dk + :goals: build Programming and Debugging ************************* diff --git a/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi b/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi index cf09783fc2322..47c678db786e5 100644 --- a/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi +++ b/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi @@ -42,6 +42,12 @@ chosen { zephyr,bt-hci = &hci_spi; }; + + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <&ft5336>; + invert-y; + }; }; &fmc { @@ -177,6 +183,13 @@ stm32_lp_tick_source: &lptim1 { reg = <0x6a>; irq-gpios = <&gpiof 3 GPIO_ACTIVE_HIGH>; }; + + ft5336: ft5336@38 { + compatible = "focaltech,ft5336"; + reg = <0x38>; + int-gpios = <&gpiof 1 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; + }; }; &rng { @@ -277,7 +290,7 @@ stm32_lp_tick_source: &lptim1 { &adc1 { pinctrl-0 = <&adc1_in13_pc4>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/stm32mp157c_dk2/stm32mp157c_dk2.yaml b/boards/st/stm32mp157c_dk2/stm32mp157c_dk2.yaml index 91a4aa38fe075..5fcd4f79ce2b9 100644 --- a/boards/st/stm32mp157c_dk2/stm32mp157c_dk2.yaml +++ b/boards/st/stm32mp157c_dk2/stm32mp157c_dk2.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_i2c - arduino_gpio diff --git a/boards/st/stm32n6570_dk/Kconfig.stm32n6570_dk b/boards/st/stm32n6570_dk/Kconfig.stm32n6570_dk new file mode 100644 index 0000000000000..667266938964b --- /dev/null +++ b/boards/st/stm32n6570_dk/Kconfig.stm32n6570_dk @@ -0,0 +1,5 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_STM32N6570_DK + select SOC_STM32N657XX diff --git a/boards/st/stm32n6570_dk/arduino_r3_connector.dtsi b/boards/st/stm32n6570_dk/arduino_r3_connector.dtsi new file mode 100644 index 0000000000000..b3309965278e5 --- /dev/null +++ b/boards/st/stm32n6570_dk/arduino_r3_connector.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + arduino_header: connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpioa 5 0>, /* A0 */ + <1 0 &gpioa 9 0>, /* A1 */ + <2 0 &gpioa 10 0>, /* A2 */ + <3 0 &gpioa 12 0>, /* A3 */ + <4 0 &gpiof 3 0>, /* A4 */ + <5 0 &gpiob 10 0>, /* A5 */ + <6 0 &gpiof 6 0>, /* D0 */ + <7 0 &gpiod 5 0>, /* D1 */ + <8 0 &gpiod 0 0>, /* D2 */ + <9 0 &gpioe 9 0>, /* D3 */ + <10 0 &gpioh 5 0>, /* D4 */ + <11 0 &gpioe 10 0>, /* D5 */ + <12 0 &gpioe 13 0>, /* D6 */ + <13 0 &gpiod 6 0>, /* D7 */ + <14 0 &gpioe 7 0>, /* D8 */ + <15 0 &gpioe 14 0>, /* D9 */ + <16 0 &gpioa 3 0>, /* D10 */ + <17 0 &gpiog 2 0>, /* D11 */ + <18 0 &gpioh 8 0>, /* D12 */ + <19 0 &gpioe 15 0>, /* D13 */ + <20 0 &gpioc 1 0>, /* D14 */ + <21 0 &gpioh 9 0>; /* D15 */ + }; +}; + +arduino_serial: &usart2 {}; +arduino_i2c: &i2c1 {}; +arduino_spi: &spi5 {}; diff --git a/boards/st/stm32n6570_dk/board.cmake b/boards/st/stm32n6570_dk/board.cmake new file mode 100644 index 0000000000000..becac84524af7 --- /dev/null +++ b/boards/st/stm32n6570_dk/board.cmake @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 STMicroelectronics + +if(CONFIG_STM32N6_BOOT_SERIAL) + board_runner_args(stm32cubeprogrammer "--port=usb1") + board_runner_args(stm32cubeprogrammer "--download-modifiers=0x1") + board_runner_args(stm32cubeprogrammer "--start-modifiers=noack") +else() + board_runner_args(stm32cubeprogrammer "--port=swd") + board_runner_args(stm32cubeprogrammer "--tool-opt= mode=HOTPLUG ap=1") + board_runner_args(stm32cubeprogrammer "--extload=MX66UW1G45G_STM32N6570-DK.stldr") + board_runner_args(stm32cubeprogrammer "--download-address=0x70000000") +endif() + +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) diff --git a/boards/st/stm32n6570_dk/board.yml b/boards/st/stm32n6570_dk/board.yml new file mode 100644 index 0000000000000..2bdf8abd80e26 --- /dev/null +++ b/boards/st/stm32n6570_dk/board.yml @@ -0,0 +1,8 @@ +board: + name: stm32n6570_dk + full_name: STM32N6570-DK + vendor: st + socs: + - name: stm32n657xx + variants: + - name: sb diff --git a/boards/st/stm32n6570_dk/doc/img/stm32n6570_dk.webp b/boards/st/stm32n6570_dk/doc/img/stm32n6570_dk.webp new file mode 100644 index 0000000000000..a6788dc33283e Binary files /dev/null and b/boards/st/stm32n6570_dk/doc/img/stm32n6570_dk.webp differ diff --git a/boards/st/stm32n6570_dk/doc/index.rst b/boards/st/stm32n6570_dk/doc/index.rst new file mode 100644 index 0000000000000..9b84e5883858f --- /dev/null +++ b/boards/st/stm32n6570_dk/doc/index.rst @@ -0,0 +1,280 @@ +.. zephyr:board:: stm32n6570_dk + +Overview +******** + +The STM32N6570_DK Discovery kit is a complete demonstration and development platform +for the ArmÂŽ Cortex®‑M55 core‑based STM32N657X0H3Q microcontroller. + +The STM32N6570_DK Discovery kit includes a full range of hardware features that help +the user evaluate many peripherals, such as USB Type-CÂŽ, Octo‑SPI flash memory and +Hexadeca‑SPI PSRAM devices, Ethernet, camera module, LCD, microSD™, audio codec, +digital microphones, ADC, flexible extension connectors, and user button. +The four flexible extension connectors feature easy and unlimited expansion capabilities +for specific applications such as wireless connectivity, analog applications, and sensors. + +The STM32N657X0H3Q microcontroller features one USB 2.0 high‑speed/full‑speed +Device/Host/OTG controller, one USB 2.0 high‑speed/full‑speed Device/Host/OTG controller +with UCPD (USB Type-CÂŽ Power Delivery), one Ethernet with TSN (time-sensitive networking), +four I2Cs, two I3Cs, six SPIs (of which four I2S‑capable), two SAIs, with four DMIC support, +five USARTs, five UARTs (ISO78916 interface, LIN, IrDA, up to 12.5 Mbit/s), one LPUART, +two SDMMCs (MMC version 4.0, CE-ATA version 1.0, and SD version 1.0.1), three CAN FD +with TTCAN capability, JTAG and SWD debugging support, and Embedded Trace Macrocell™ (ETM). + +The STM32N6570_DK Discovery kit integrates an STLINK-V3EC embedded in-circuit debugger and +programmer for the STM32 MCU, with a USB Virtual COM port bridge and the comprehensive MCU Package. + +Hardware +******** + +- STM32N657X0H3Q ArmÂŽ Cortex®‑M55‑based microcontroller featuring ST Neural-ART Accelerator, + H264 encoder, NeoChrom 2.5D GPU, and 4.2 Mbytes of contiguous SRAM, in a VFBGA264 package +- 5" LCD module with capacitive touch panel +- USB Type-CÂŽ with USB 2.0 HS interface, dual‑role‑power (DRP) +- USB Type-A with USB 2.0 HS interface, host, 0.5 A max +- 1‑Gbit Ethernet with TSN (time-sensitive networking) compliant with IEEE‑802.3‑2002 +- SAI audio codec +- One MEMS digital microphone +- 1‑Gbit Octo‑SPI flash memory +- 256-Mbit Hexadeca‑SPI PSRAM +- Two user LEDs +- User, tamper, and reset push-buttons +- Board connectors: + + - USB Type-CÂŽ + - USB Type-A + - Ethernet RJ45 + - Camera module + - microSD™ card + - LCD + - Stereo headset jack including analog microphone input + - Audio MEMS daughterboard expansion connector + - ARDUINOÂŽ Uno R3 expansion connector + - STMod+ expansion connector + +- On-board STLINK-V3EC debugger/programmer with USB re-enumeration capability: + Virtual COM port, and debug port + +For more details, please refer to: + +* `STM32N6570_DK website`_ +* `STM32N657X0 on www.st.com`_ +* `STM32N657 reference manual`_ + +Supported Features +================== + +The Zephyr ``stm32n6570_dk`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| ADC | on-chip | adc | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| CAN/CANFD | on-chip | canbus | ++-----------+------------+-------------------------------------+ +| DMA | on-chip | Direct Memory Access Controller | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ + + +Other hardware features are not yet supported on this Zephyr port. + +The default configuration can be found in the defconfig file: +:zephyr_file:`boards/st/stm32n6570_dk/stm32n6570_dk_defconfig` + + +Connections and IOs +=================== + +STM32N6570_DK Board has 12 GPIO controllers. These controllers are responsible +for pin muxing, input/output, pull-up, etc. + +For more details please refer to `STM32N6570_DK User Manual`_. + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- ADC1_INP10 : PA9 +- ADC1_INP11 : PA10 +- FDCAN1_TX : PH2 +- FDCAN1_RX : PD0 +- I2C1_SCL : PH9 +- I2C1_SDA : PC1 +- I2C4_SCL : PE13 +- I2C4_SDA : PE14 +- LD1 : PO1 +- LD2 : PG10 +- SPI5_SCK : PE15 +- SPI5_MOSI : PG2 +- SPI5_MISO : PH8 +- SPI5_NSS : PA3 +- USART_1_TX : PE5 +- USART_1_RX : PE6 +- USART_2_TX : PD5 +- USART_2_RX : PF6 + +System Clock +------------ + +STM32N6570_DK System Clock could be driven by internal or external oscillator, +as well as main PLL clock. By default System clock is driven by PLL clock at +400MHz, driven by 64MHz high speed internal oscillator. + +Serial Port +----------- + +STM32N6570_DK board has 10 U(S)ARTs. The Zephyr console output is assigned to +USART1. Default settings are 115200 8N1. + +Programming and Debugging +************************* + +STM32N6570_DK board includes an ST-LINK/V3 embedded debug tool interface. +This probe allows to flash and debug the board using various tools. + + +Flashing or loading +=================== + +The board is configured to be programmed using west `STM32CubeProgrammer`_ runner, +so its :ref:`installation ` is needed. +Version 2.18.0 or later of `STM32CubeProgrammer`_ is required. + +To program the board, there are two options: + +- Program the firmware in external flash. At boot, it will then be loaded on RAM + and executed from there. +- Optionally, it can also be taken advantage from the serial boot interface provided + by the boot ROM. In that case, firmware is directly loaded in RAM and executed from + there. It is not retained. + +Programming an application to STM32N6570_DK +------------------------------------------- + +Here is an example to build and run :zephyr:code-sample:`hello_world` application. + +First, connect the STM32N6570_DK to your host computer using the ST-Link USB port. + + .. tabs:: + + .. group-tab:: ST-Link + + Build and flash an application using ``stm32n6570_dk`` target. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32n6570_dk + :goals: build flash + + .. note:: + For flashing, before powering the board, set the boot pins in the following configuration: + + * BOOT0: 0 + * BOOT1: 1 + + After flashing, to run the application, set the boot pins in the following configuration: + + * BOOT1: 0 + + Power off and on the board again. + + Run a serial host program to connect to your board: + + .. code-block:: console + + $ minicom -D /dev/ttyACM0 + + .. group-tab:: Serial Boot Loader (USB) + + Additionally, connect the STM32N6570_DK to your host computer using the USB port. + In this configuration, ST-Link is used to power the board and for serial communication + over the Virtual COM Port. + + .. note:: + Before powering the board, set the boot pins in the following configuration: + + * BOOT0: 1 + * BOOT1: 0 + + Build and load an application using ``stm32n6570_dk/stm32n657xx/sb`` target (you + can also use the shortened form: ``stm32n6570_dk//sb``) + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32n6570_dk//sb + :goals: build flash + + +Run a serial host program to connect with your Disco board: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +You should see the following message on the console: + +.. code-block:: console + + Hello World! stm32n6570_dk/stm32n657xx + + +Debugging +========= + +For now debugging is only available through STM32CubeIDE: + +* Go to File > Import and select C/C++ > STM32 Cortex-M Executable. +* In Executable field, browse to your /build/zephyr/zephyr.elf. +* In MCU field, select STM32N657X0HxQ. +* Click on Finish. +* Finally, click on Debug to start the debugging session. + +.. note:: + For debugging, before powering on the board, set the boot pins in the following configuration: + + * BOOT0: 0 + * BOOT1: 1 + + +Running tests with twister +========================== + +Due to the BOOT switches manipulation required when flashing the board using ``stm32n6570_dk`` +board target, it is only possible to run twister tests campaign on ``stm32n6570_dk/stm32n657xx/sb`` +board target which doesn't require BOOT pins changes to load and execute binaries. +To do so, it is advised to use Twister's hardware map feature with the following settings: + +.. code-block:: yaml + + - platform: stm32n6570_dk/stm32n657xx/sb + product: BOOT-SERIAL + pre_script: /boards/st/common/scripts/board_power_reset.sh + runner: stm32cubeprogrammer + +.. _STM32N6570_DK website: + https://www.st.com/en/evaluation-tools/stm32n6570-dk.html + +.. _STM32N6570_DK User Manual: + https://www.st.com/resource/en/user_manual/um3300-discovery-kit-with-stm32n657x0-mcu-stmicroelectronics.pdf + +.. _STM32N657X0 on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32n657x0.html + +.. _STM32N657 reference manual: + https://www.st.com/resource/en/reference_manual/rm0486-stm32n647657xx-armbased-32bit-mcus-stmicroelectronics.pdf + +.. _STM32CubeProgrammer: + https://www.st.com/en/development-tools/stm32cubeprog.html diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk.dts b/boards/st/stm32n6570_dk/stm32n6570_dk.dts new file mode 100644 index 0000000000000..82bb8b72dde72 --- /dev/null +++ b/boards/st/stm32n6570_dk/stm32n6570_dk.dts @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "stm32n6570_dk_common.dtsi" + +/ { + model = "STMicroelectronics STM32N6570 Discovery Kit board"; + compatible = "st,stm32n6570-dk"; +}; diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi new file mode 100644 index 0000000000000..2f1ca7720f764 --- /dev/null +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "arduino_r3_connector.dtsi" +#include + +/ { + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &axisram2; + zephyr,canbus = &fdcan1; + }; + + aliases { + led0 = &green_led_1; + }; + + leds: leds { + compatible = "gpio-leds"; + + green_led_1: led_1 { + gpios = <&gpioo 1 GPIO_ACTIVE_HIGH>; + label = "User LD1"; + }; + + red_led_1: led_2 { + gpios = <&gpiog 10 GPIO_ACTIVE_HIGH>; + label = "User LD2"; + }; + }; +}; + +&clk_hsi { + hsi-div = <1>; + status = "okay"; +}; + +&pll1 { + clocks = <&clk_hsi>; + div-m = <4>; + mul-n = <75>; + div-p1 = <1>; + div-p2 = <1>; + status = "okay"; +}; + +&ic1 { + pll-src = <1>; + ic-div = <2>; + status = "okay"; +}; + +&ic2 { + pll-src = <1>; + ic-div = <3>; + status = "okay"; +}; + +&ic6 { + pll-src = <1>; + ic-div = <2>; + status = "okay"; +}; + +&ic11 { + pll-src = <1>; + ic-div = <3>; + status = "okay"; +}; + +&perck { + clocks = <&rcc STM32_SRC_HSI PER_SEL(0)>; + status = "okay"; +}; + +&cpusw { + clocks = <&rcc STM32_SRC_IC1 CPU_SEL(3)>; + clock-frequency = ; + status = "okay"; +}; + +&rcc { + /* ic2, ic6 & ic11 must all be enabled to set ic2 as SYSCLK */ + clocks = <&ic2>; + clock-frequency = ; + ahb-prescaler = <2>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb4-prescaler = <1>; + apb5-prescaler = <1>; +}; + +&adc1 { + clocks = <&rcc STM32_CLOCK(AHB1, 5)>, + <&rcc STM32_SRC_CKPER ADC12_SEL(1)>; + pinctrl-0 = <&adc1_inp10_pa9 &adc1_inp11_pa10>; /* Arduino A1 & A2 */ + pinctrl-names = "default"; + vref-mv = <1800>; + status = "okay"; +}; + +&fdcan1 { + clocks = <&rcc STM32_CLOCK(APB1_2, 8)>, + <&rcc STM32_SRC_CKPER FDCAN_SEL(1)>; + pinctrl-0 = <&fdcan1_rx_pd0 &fdcan1_tx_ph2>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + clocks = <&rcc STM32_CLOCK(APB1, 21)>, + <&rcc STM32_SRC_CKPER I2C1_SEL(1)>; + pinctrl-0 = <&i2c1_scl_ph9 &i2c1_sda_pc1>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; + +&i2c4 { + clocks = <&rcc STM32_CLOCK(APB4, 7)>, + <&rcc STM32_SRC_CKPER I2C4_SEL(1)>; + pinctrl-0 = <&i2c4_scl_pe13 &i2c4_sda_pe14>; + pinctrl-names = "default"; + clock-frequency = ; + status = "okay"; +}; + +&spi5 { + clocks = <&rcc STM32_CLOCK(APB2, 20)>, + <&rcc STM32_SRC_CKPER SPI5_SEL(1)>; + pinctrl-0 = <&spi5_nss_pa3 &spi5_sck_pe15 &spi5_miso_ph8 &spi5_mosi_pg2>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usart1 { + clocks = <&rcc STM32_CLOCK(APB2, 4)>, + <&rcc STM32_SRC_CKPER USART1_SEL(1)>; + pinctrl-0 = <&usart1_tx_pe5 &usart1_rx_pe6>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&usart2 { + clocks = <&rcc STM32_CLOCK(APB1, 17)>, + <&rcc STM32_SRC_CKPER USART2_SEL(1)>; + pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pf6>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_defconfig b/boards/st/stm32n6570_dk/stm32n6570_dk_defconfig new file mode 100644 index 0000000000000..01abfa9c0b7ff --- /dev/null +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_defconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 STMicroelectronics + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# No internal Flash +CONFIG_XIP=n diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_stm32n657xx_sb.dts b/boards/st/stm32n6570_dk/stm32n6570_dk_stm32n657xx_sb.dts new file mode 100644 index 0000000000000..967209c2fcc43 --- /dev/null +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_stm32n657xx_sb.dts @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "stm32n6570_dk_common.dtsi" + +/ { + model = "STMicroelectronics STM32N6570 Discovery Kit board"; + compatible = "st,stm32n6570-dk-serial-boot"; +}; diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_stm32n657xx_sb_defconfig b/boards/st/stm32n6570_dk/stm32n6570_dk_stm32n657xx_sb_defconfig new file mode 100644 index 0000000000000..33b0f281a2f84 --- /dev/null +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_stm32n657xx_sb_defconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 STMicroelectronics + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# No internal Flash +CONFIG_XIP=n + +# Use serial boot (USB) +CONFIG_STM32N6_BOOT_SERIAL=y diff --git a/boards/st/stm32n6570_dk/twister.yaml b/boards/st/stm32n6570_dk/twister.yaml new file mode 100644 index 0000000000000..f5501069a4364 --- /dev/null +++ b/boards/st/stm32n6570_dk/twister.yaml @@ -0,0 +1,24 @@ +name: STM32N6570 Discovery Kit +type: mcu +arch: arm +ram: 1024 +flash: 1024 +vendor: st +supported: + - arduino_i2c + - arduino_serial + - arduino_spi + - adc + - can + - dma + - i2c + - gpio + - spi + - uart +variants: + stm32n6570_dk/stm32n657xx: + twister: false + stm32n6570_dk/stm32n657xx/sb: + toolchain: + - zephyr + - gnuarmemb diff --git a/boards/st/stm32u083c_dk/arduino_r3_connector.dtsi b/boards/st/stm32u083c_dk/arduino_r3_connector.dtsi index 297fd9b7f1830..f2b85867b89ec 100644 --- a/boards/st/stm32u083c_dk/arduino_r3_connector.dtsi +++ b/boards/st/stm32u083c_dk/arduino_r3_connector.dtsi @@ -36,3 +36,4 @@ }; arduino_serial: &usart2 {}; +arduino_i2c: &i2c1 {}; diff --git a/boards/st/stm32u083c_dk/stm32u083c_dk.dts b/boards/st/stm32u083c_dk/stm32u083c_dk.dts index 6bf36bc3c87a4..4f340422d5152 100644 --- a/boards/st/stm32u083c_dk/stm32u083c_dk.dts +++ b/boards/st/stm32u083c_dk/stm32u083c_dk.dts @@ -75,7 +75,7 @@ &adc1 { pinctrl-0 = <&adc1_in0_pc0 &adc1_in1_pc1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00100000>, <&rcc STM32_SRC_HSI ADC_SEL(2)>; st,adc-prescaler = <4>; diff --git a/boards/st/stm32u083c_dk/stm32u083c_dk.yaml b/boards/st/stm32u083c_dk/stm32u083c_dk.yaml index 56767fa5f5dc4..5d1b0f4f6b100 100644 --- a/boards/st/stm32u083c_dk/stm32u083c_dk.yaml +++ b/boards/st/stm32u083c_dk/stm32u083c_dk.yaml @@ -5,10 +5,11 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio + - arduino_serial + - arduino_i2c - dac - gpio - i2c diff --git a/boards/st/stm32u5a9j_dk/stm32u5a9j_dk.dts b/boards/st/stm32u5a9j_dk/stm32u5a9j_dk.dts index f8dbb7f8d1817..5696253f93cfa 100644 --- a/boards/st/stm32u5a9j_dk/stm32u5a9j_dk.dts +++ b/boards/st/stm32u5a9j_dk/stm32u5a9j_dk.dts @@ -204,7 +204,7 @@ uart0: &usart3 { &adc1 { pinctrl-0 = <&adc1_in5_pa0 &adc1_in14_pc5>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <1>; status = "okay"; @@ -231,7 +231,7 @@ uart0: &usart3 { &adc4 { pinctrl-0 = <&adc4_in5_pf14>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "ASYNC"; st,adc-prescaler = <1>; status = "okay"; diff --git a/boards/st/stm32vl_disco/stm32vl_disco.yaml b/boards/st/stm32vl_disco/stm32vl_disco.yaml index 5e37731dfcc5c..0167ec3e79763 100644 --- a/boards/st/stm32vl_disco/stm32vl_disco.yaml +++ b/boards/st/stm32vl_disco/stm32vl_disco.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 8 flash: 128 supported: diff --git a/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.dts b/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.dts index e11ec3f0f20bd..7395329ca23c4 100644 --- a/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.dts +++ b/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.dts @@ -111,7 +111,7 @@ &adc1 { pinctrl-0 = <&adc1_in3_pc2>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.yaml b/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.yaml index a90491d13aa88..aa2472a2343da 100644 --- a/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.yaml +++ b/boards/st/stm32wb5mm_dk/stm32wb5mm_dk.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 876 supported: diff --git a/boards/st/stm32wb5mmg/stm32wb5mmg.dts b/boards/st/stm32wb5mmg/stm32wb5mmg.dts index d494b7024dc7c..29f7de3130278 100644 --- a/boards/st/stm32wb5mmg/stm32wb5mmg.dts +++ b/boards/st/stm32wb5mmg/stm32wb5mmg.dts @@ -69,7 +69,7 @@ &adc1 { pinctrl-0 = <&adc1_in3_pc2>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/st/stm32wb5mmg/stm32wb5mmg.yaml b/boards/st/stm32wb5mmg/stm32wb5mmg.yaml index 2e3667f18d549..5b9de8b09c7d2 100644 --- a/boards/st/stm32wb5mmg/stm32wb5mmg.yaml +++ b/boards/st/stm32wb5mmg/stm32wb5mmg.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/boards/tdk/robokit1/Kconfig.defconfig b/boards/tdk/robokit1/Kconfig.defconfig new file mode 100644 index 0000000000000..7dccfa805bf33 --- /dev/null +++ b/boards/tdk/robokit1/Kconfig.defconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ROBOKIT1 + +config ADC_ADS7052_INIT_PRIORITY + default 60 + depends on ADC_ADS7052 + +config SENSOR_INIT_PRIORITY + default 60 + depends on SENSOR + +config EEPROM_INIT_PRIORITY + default 60 + depends on EEPROM + +endif # BOARD_ROBOKIT1 diff --git a/boards/tdk/robokit1/robokit1.dts b/boards/tdk/robokit1/robokit1.dts index 46d160b20741f..7564ccfb5f6ef 100644 --- a/boards/tdk/robokit1/robokit1.dts +++ b/boards/tdk/robokit1/robokit1.dts @@ -7,7 +7,7 @@ /dts-v1/; -#include +#include #include "robokit1-common.dtsi" diff --git a/boards/tdk/robokit1/robokit1.yaml b/boards/tdk/robokit1/robokit1.yaml index 8cbd19f73a6f0..1f71210c029ce 100644 --- a/boards/tdk/robokit1/robokit1.yaml +++ b/boards/tdk/robokit1/robokit1.yaml @@ -7,7 +7,6 @@ ram: 384 toolchain: - zephyr - gnuarmemb - - xtools supported: - can - dma diff --git a/boards/technexion/pico_pi/pico_pi_mcimx7d_m4.yaml b/boards/technexion/pico_pi/pico_pi_mcimx7d_m4.yaml index 7baa570c54882..231a61b748d7d 100644 --- a/boards/technexion/pico_pi/pico_pi_mcimx7d_m4.yaml +++ b/boards/technexion/pico_pi/pico_pi_mcimx7d_m4.yaml @@ -13,7 +13,6 @@ flash: 32 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/ti/cc1352p1_launchxl/cc1352p1_launchxl.yaml b/boards/ti/cc1352p1_launchxl/cc1352p1_launchxl.yaml index 57e62c2ddecb3..eeebe7e033642 100644 --- a/boards/ti/cc1352p1_launchxl/cc1352p1_launchxl.yaml +++ b/boards/ti/cc1352p1_launchxl/cc1352p1_launchxl.yaml @@ -7,7 +7,6 @@ flash: 352 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/ti/cc1352p1_launchxl/cc1352p1_launchxl_defconfig b/boards/ti/cc1352p1_launchxl/cc1352p1_launchxl_defconfig index 42ca455ed3302..4e65416ca5373 100644 --- a/boards/ti/cc1352p1_launchxl/cc1352p1_launchxl_defconfig +++ b/boards/ti/cc1352p1_launchxl/cc1352p1_launchxl_defconfig @@ -16,7 +16,6 @@ CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_PIN=15 CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y -CONFIG_PINCTRL=y CONFIG_GPIO=y CONFIG_SERIAL=y diff --git a/boards/ti/cc1352p7_launchpad/cc1352p7_lp.yaml b/boards/ti/cc1352p7_launchpad/cc1352p7_lp.yaml index fe3a834ebcf48..8d438b75ed167 100644 --- a/boards/ti/cc1352p7_launchpad/cc1352p7_lp.yaml +++ b/boards/ti/cc1352p7_launchpad/cc1352p7_lp.yaml @@ -7,11 +7,11 @@ flash: 704 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c - spi - watchdog - hwinfo + - netif:openthread vendor: ti diff --git a/boards/ti/cc1352p7_launchpad/support/openocd.cfg b/boards/ti/cc1352p7_launchpad/support/openocd.cfg index 8be969b1819bd..e66d88411047d 100644 --- a/boards/ti/cc1352p7_launchpad/support/openocd.cfg +++ b/boards/ti/cc1352p7_launchpad/support/openocd.cfg @@ -1 +1,7 @@ +# Serial could be found using the following command: +# lsusb -d 0451:bef3 -v | grep -i iserial +if { [info exists _ZEPHYR_BOARD_SERIAL] } { + adapter serial $_ZEPHYR_BOARD_SERIAL +} + source [find board/ti_cc26x2x7_launchpad.cfg] diff --git a/boards/ti/cc1352r1_launchxl/cc1352r1_launchxl.yaml b/boards/ti/cc1352r1_launchxl/cc1352r1_launchxl.yaml index 7c37a90289324..ce8bfb6127f8f 100644 --- a/boards/ti/cc1352r1_launchxl/cc1352r1_launchxl.yaml +++ b/boards/ti/cc1352r1_launchxl/cc1352r1_launchxl.yaml @@ -7,7 +7,6 @@ flash: 352 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/ti/cc1352r1_launchxl/cc1352r1_launchxl_defconfig b/boards/ti/cc1352r1_launchxl/cc1352r1_launchxl_defconfig index 872843de16d29..3977a366b5210 100644 --- a/boards/ti/cc1352r1_launchxl/cc1352r1_launchxl_defconfig +++ b/boards/ti/cc1352r1_launchxl/cc1352r1_launchxl_defconfig @@ -14,7 +14,6 @@ CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_PIN=15 CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y -CONFIG_PINCTRL=y CONFIG_GPIO=y CONFIG_SERIAL=y diff --git a/boards/ti/cc1352r_sensortag/cc1352r_sensortag.yaml b/boards/ti/cc1352r_sensortag/cc1352r_sensortag.yaml index ab974002e384a..dc07fa49190e1 100644 --- a/boards/ti/cc1352r_sensortag/cc1352r_sensortag.yaml +++ b/boards/ti/cc1352r_sensortag/cc1352r_sensortag.yaml @@ -7,7 +7,6 @@ flash: 352 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/ti/cc1352r_sensortag/cc1352r_sensortag_defconfig b/boards/ti/cc1352r_sensortag/cc1352r_sensortag_defconfig index 2cddbd5af73e2..84b07413d0c8d 100644 --- a/boards/ti/cc1352r_sensortag/cc1352r_sensortag_defconfig +++ b/boards/ti/cc1352r_sensortag/cc1352r_sensortag_defconfig @@ -13,7 +13,6 @@ CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_PIN=15 CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y -CONFIG_PINCTRL=y CONFIG_GPIO=y CONFIG_SERIAL=y diff --git a/boards/ti/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml b/boards/ti/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml index 1c2bd9d88764f..7ae41f0cc032b 100644 --- a/boards/ti/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml +++ b/boards/ti/cc26x2r1_launchxl/cc26x2r1_launchxl.yaml @@ -7,7 +7,6 @@ flash: 352 toolchain: - zephyr - gnuarmemb - - xtools supported: - gpio - i2c diff --git a/boards/ti/cc26x2r1_launchxl/cc26x2r1_launchxl_defconfig b/boards/ti/cc26x2r1_launchxl/cc26x2r1_launchxl_defconfig index d10e7a152e52d..f4aa8c3c54159 100644 --- a/boards/ti/cc26x2r1_launchxl/cc26x2r1_launchxl_defconfig +++ b/boards/ti/cc26x2r1_launchxl/cc26x2r1_launchxl_defconfig @@ -14,7 +14,6 @@ CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_PIN=13 CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y -CONFIG_PINCTRL=y CONFIG_GPIO=y CONFIG_SERIAL=y diff --git a/boards/ti/cc3220sf_launchxl/cc3220sf_launchxl.yaml b/boards/ti/cc3220sf_launchxl/cc3220sf_launchxl.yaml index 2158d5ec45339..09b7343c4b3af 100644 --- a/boards/ti/cc3220sf_launchxl/cc3220sf_launchxl.yaml +++ b/boards/ti/cc3220sf_launchxl/cc3220sf_launchxl.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - netif:wifi - i2c diff --git a/boards/ti/cc3235sf_launchxl/cc3235sf_launchxl.yaml b/boards/ti/cc3235sf_launchxl/cc3235sf_launchxl.yaml index 4761555359aeb..7f7e3a9cab3ac 100644 --- a/boards/ti/cc3235sf_launchxl/cc3235sf_launchxl.yaml +++ b/boards/ti/cc3235sf_launchxl/cc3235sf_launchxl.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - netif:wifi - i2c diff --git a/boards/ti/lp_em_cc2340r5/Kconfig.lp_em_cc2340r5 b/boards/ti/lp_em_cc2340r5/Kconfig.lp_em_cc2340r5 new file mode 100644 index 0000000000000..fbc90c7ebc8ae --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/Kconfig.lp_em_cc2340r5 @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LP_EM_CC2340R5 + select SOC_CC2340R5 diff --git a/boards/ti/lp_em_cc2340r5/board.yml b/boards/ti/lp_em_cc2340r5/board.yml new file mode 100644 index 0000000000000..b698c52df8567 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/board.yml @@ -0,0 +1,6 @@ +board: + name: lp_em_cc2340r5 + full_name: CC2340R5 LaunchPad + vendor: ti + socs: + - name: cc2340r5 diff --git a/boards/ti/lp_em_cc2340r5/boosterpack_connector.dtsi b/boards/ti/lp_em_cc2340r5/boosterpack_connector.dtsi new file mode 100644 index 0000000000000..f330b8c1e8233 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/boosterpack_connector.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + boosterpack_header: connector { + compatible = "ti,boosterpack-header"; + #gpio-cells = <2>; + gpio-map = <3 0 &gpio0 22 0>, + <4 0 &gpio0 20 0>, + <7 0 &gpio0 18 0>, + <8 0 &gpio0 3 0>, + <9 0 &gpio0 24 0>, + <10 0 &gpio0 0 0>, + + <12 0 &gpio0 9 0>, + <13 0 &gpio0 10 0>, + <14 0 &gpio0 12 0>, + <15 0 &gpio0 13 0>, + <17 0 &gpio0 19 0>, + <18 0 &gpio0 11 0>, + + <23 0 &gpio0 23 0>, + <24 0 &gpio0 25 0>, + <25 0 &gpio0 1 0>, + <26 0 &gpio0 2 0>, + <27 0 &gpio0 5 0>, + <28 0 &gpio0 7 0>, + + <36 0 &gpio0 8 0>, + <37 0 &gpio0 21 0>, + <38 0 &gpio0 6 0>, + <39 0 &gpio0 14 0>, + <40 0 &gpio0 15 0>; + }; +}; diff --git a/boards/ti/lp_em_cc2340r5/doc/img/lp_em_cc2340r5.webp b/boards/ti/lp_em_cc2340r5/doc/img/lp_em_cc2340r5.webp new file mode 100644 index 0000000000000..df225cf6154ef Binary files /dev/null and b/boards/ti/lp_em_cc2340r5/doc/img/lp_em_cc2340r5.webp differ diff --git a/boards/ti/lp_em_cc2340r5/doc/index.rst b/boards/ti/lp_em_cc2340r5/doc/index.rst new file mode 100644 index 0000000000000..f6b2077db1bef --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/doc/index.rst @@ -0,0 +1,119 @@ +.. zephyr:board:: lp_em_cc2340r5 + +Overview +******** + +The Texas Instruments CC2340R5 LaunchPad |trade| (LP_EM_CC2340R5) is a +development kit for the SimpleLink |trade| multi-Standard CC2340R5 wireless MCU. + +See the `TI CC2340R5 LaunchPad Product Page`_ for details. + +Hardware +******** + +The CC2340R5 LaunchPad |trade| development kit features the CC2340R5 wireless MCU. +The board is equipped with two LEDs, two push buttons and BoosterPack connectors +for expansion. + +The CC2340R5 wireless MCU has a 48 MHz Arm |reg| Cortex |reg|-M0+ SoC and an +integrated 2.4 GHz transceiver supporting multiple protocols including Bluetooth +|reg| Low Energy and IEEE |reg| 802.15.4. + +See the `TI CC2340R5 Product Page`_ for additional details. + +Supported Features +================== + +The ``lp_em_cc2340r5`` board supports the following hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+----------------------+ +| UART | on-chip | serial port | ++-----------+------------+----------------------+ +| SYSTIM | on-chip | system timer | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. + +Connections and IOs +=================== + +All I/O signals are accessible from the BoosterPack connectors. Pin function +aligns with the LaunchPad standard. + ++-------+-----------+---------------------+ +| Pin | Function | Usage | ++=======+===========+=====================+ +| DIO0 | GPIO | | ++-------+-----------+---------------------+ +| DIO1 | ANALOG_IO | A4 | ++-------+-----------+---------------------+ +| DIO2 | ANALOG_IO | A3 | ++-------+-----------+---------------------+ +| DIO5 | ANALOG_IO | A5 | ++-------+-----------+---------------------+ +| DIO6 | SPI_CSN | SPI CS | ++-------+-----------+---------------------+ +| DIO7 | ANALOG_IO | A0 | ++-------+-----------+---------------------+ +| DIO8 | GPIO | | ++-------+-----------+---------------------+ +| DIO9 | GPIO | Button 2 | ++-------+-----------+---------------------+ +| DIO10 | GPIO | Button 1 | ++-------+-----------+---------------------+ +| DIO11 | SPI_CSN | SPI CS | ++-------+-----------+---------------------+ +| DIO12 | SPI_POCI | SPI POCI | ++-------+-----------+---------------------+ +| DIO13 | SPI_PICO | SPI_PICO | ++-------+-----------+---------------------+ +| DIO14 | GPIO | Red LED | ++-------+-----------+---------------------+ +| DIO15 | GPIO | Green LED | ++-------+-----------+---------------------+ +| DIO18 | SPI_CLK | SPI CLK | ++-------+-----------+---------------------+ +| DIO19 | GPIO | | ++-------+-----------+---------------------+ +| DIO20 | UART0_TX | UART TX | ++-------+-----------+---------------------+ +| DIO21 | GPIO | | ++-------+-----------+---------------------+ +| DIO22 | UART0_RX | UART RX | ++-------+-----------+---------------------+ +| DIO23 | ANALOG_IO | A8 | ++-------+-----------+---------------------+ +| DIO24 | ANALOG_IO | A7 | ++-------+-----------+---------------------+ + +Programming and Debugging +************************* + +The LP_EM_CC2340R5 requires an external debug probe such as the LP-XDS110 or +LP-XDS110ET. + +Currently there is no debug support in Zephyr for the LP_EM_CC2340R5, and the +built binaries for this target must be flashed/debugged using either Uniflash +or Code Composer Studio. + +References +********** + +CC2340R5 LaunchPad Quick Start Guide: + https://www.ti.com/lit/pdf/swru588 + +.. _TI CC2340R5 LaunchPad Product Page: + https://www.ti.com/tool/LP-EM-CC2340R5 + +.. _TI CC2340R5 Product Page: + https://www.ti.com/product/CC2340R5 diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5-pinctrl.dtsi b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5-pinctrl.dtsi new file mode 100644 index 0000000000000..1d929cfa6acaa --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5-pinctrl.dtsi @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* UART0 */ + uart0_tx_default: uart0_tx_default { + pinmux = <20 DIO20_UART0_TXD>; + bias-disable; + }; + uart0_rx_default: uart0_rx_default { + pinmux = <22 DIO22_UART0_RXD>; + bias-disable; + input-enable; + }; +}; diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts new file mode 100644 index 0000000000000..64d3e15020750 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "boosterpack_connector.dtsi" +#include "lp_em_cc2340r5-pinctrl.dtsi" +#include +#include + +/ { + model = "LP_EM_CC2340R5"; + compatible = "ti,lp_em_cc2340r5"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &btn0; + sw1 = &btn1; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + + led1: led_1 { + gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + }; + + keys { + compatible = "gpio-keys"; + + btn0: btn_0 { + gpios = <&gpio0 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "Button 1"; + zephyr,code = ; + }; + + btn1: btn_1 { + gpios = <&gpio0 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "Button 2"; + zephyr,code = ; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_rx_default &uart0_tx_default>; + pinctrl-names = "default"; +}; diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.yaml b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.yaml new file mode 100644 index 0000000000000..29cda9cc23990 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.yaml @@ -0,0 +1,13 @@ +identifier: lp_em_cc2340r5 +name: TI SimpleLink CC2340R5 LaunchPad +type: mcu +arch: arm +ram: 80 +flash: 512 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - uart +vendor: ti diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5_defconfig b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5_defconfig new file mode 100644 index 0000000000000..7f9b629c25f38 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5_defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y +CONFIG_SERIAL=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/ti/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml b/boards/ti/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml index c60f1b65de8d4..ac50b615de775 100644 --- a/boards/ti/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml +++ b/boards/ti/msp_exp432p401r_launchxl/msp_exp432p401r_launchxl.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 256 vendor: ti diff --git a/boards/ti/sk_am62/doc/index.rst b/boards/ti/sk_am62/doc/index.rst index 5e6cab8439f7e..a56f4cc2c0d4c 100644 --- a/boards/ti/sk_am62/doc/index.rst +++ b/boards/ti/sk_am62/doc/index.rst @@ -46,6 +46,8 @@ The sk_am62 configuration supports the following hardware features: +-----------+------------+-------------------------------------+ | UART | on-chip | serial | +-----------+------------+-------------------------------------+ +| Mailbox | on-chip | IPC Mailbox | ++-----------+------------+-------------------------------------+ Other hardware features are not currently supported by the port. diff --git a/boards/ti/sk_am62/sk_am62_am6234_m4.dts b/boards/ti/sk_am62/sk_am62_am6234_m4.dts index 0c3ea26e033e6..85688607d5d7a 100644 --- a/boards/ti/sk_am62/sk_am62_am6234_m4.dts +++ b/boards/ti/sk_am62/sk_am62_am6234_m4.dts @@ -16,7 +16,8 @@ zephyr,sram = &sram0; zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram1 = &ddr0; + zephyr,ipc_shm = &ddr0; + zephyr,sram1 = &ddr1; }; cpus { @@ -26,9 +27,20 @@ }; }; - ddr0:memory@9CC00000{ + ddr0: memory@9cb00000 { + compatible = "mmio-sram"; + reg = <0x9cb00000 DT_SIZE_M(1)>; + }; + + rsc_table: memory@9cc00000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x9cc00000 DT_SIZE_K(4)>; + zephyr,memory-region = "RSC_TABLE"; + }; + + ddr1: memory@9cc01000 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x9CC00000 DT_SIZE_K(4)>; + reg = <0x9cc01000 (DT_SIZE_M(15) - DT_SIZE_K(4))>; zephyr,memory-region = "DDR"; }; }; diff --git a/boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4.yaml b/boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4.yaml index d28eccc9d2b8c..616be08775c1e 100644 --- a/boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4.yaml +++ b/boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4.yaml @@ -13,7 +13,6 @@ flash: 32 toolchain: - zephyr - gnuarmemb - - xtools testing: ignore_tags: - net diff --git a/boards/toradex/verdin_imx8mm/Kconfig.defconfig b/boards/toradex/verdin_imx8mm/Kconfig.defconfig new file mode 100644 index 0000000000000..331e26b4b0b9d --- /dev/null +++ b/boards/toradex/verdin_imx8mm/Kconfig.defconfig @@ -0,0 +1,15 @@ +# VERDIN_IMX8MM board defconfig +# +# Copyright (c) 2024, Toradex +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_VERDIN_IMX8MM + +if !XIP +config FLASH_SIZE + default 0 +config FLASH_BASE_ADDRESS + default 0 +endif + +endif # BOARD_VERDIN_IMX8MM diff --git a/boards/toradex/verdin_imx8mm/Kconfig.verdin_imx8mm b/boards/toradex/verdin_imx8mm/Kconfig.verdin_imx8mm new file mode 100644 index 0000000000000..52de27de01d5b --- /dev/null +++ b/boards/toradex/verdin_imx8mm/Kconfig.verdin_imx8mm @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Toradex +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_VERDIN_IMX8MM + select SOC_PART_NUMBER_MIMX8MM6DVTLZ + select SOC_MIMX8MM6_M4 if BOARD_VERDIN_IMX8MM_MIMX8MM6_M4 diff --git a/boards/toradex/verdin_imx8mm/board.cmake b/boards/toradex/verdin_imx8mm/board.cmake new file mode 100644 index 0000000000000..ae521ff4962c9 --- /dev/null +++ b/boards/toradex/verdin_imx8mm/board.cmake @@ -0,0 +1,11 @@ +# +# Copyright (c) 2024, Toradex +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_set_debugger_ifnset(jlink) +board_set_flasher_ifnset(jlink) + +board_runner_args(jlink "--device=MIMX8MD6_M4") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/toradex/verdin_imx8mm/board.yml b/boards/toradex/verdin_imx8mm/board.yml new file mode 100644 index 0000000000000..0426a516da064 --- /dev/null +++ b/boards/toradex/verdin_imx8mm/board.yml @@ -0,0 +1,6 @@ +board: + name: verdin_imx8mm + full_name: Verdin iMX8M Mini + vendor: toradex + socs: + - name: mimx8mm6 diff --git a/boards/toradex/verdin_imx8mm/doc/img/verdin_imx8mm_m4.webp b/boards/toradex/verdin_imx8mm/doc/img/verdin_imx8mm_m4.webp new file mode 100644 index 0000000000000..87a26a21b1141 Binary files /dev/null and b/boards/toradex/verdin_imx8mm/doc/img/verdin_imx8mm_m4.webp differ diff --git a/boards/toradex/verdin_imx8mm/doc/index.rst b/boards/toradex/verdin_imx8mm/doc/index.rst new file mode 100644 index 0000000000000..112596322bcaf --- /dev/null +++ b/boards/toradex/verdin_imx8mm/doc/index.rst @@ -0,0 +1,261 @@ +.. zephyr:board:: verdin_imx8mm + +Overview +******** + +The Verdin iMX8M Mini is a System on Module based on the NXPÂŽ i.MX 8M Mini family of +embedded System on Chips (SoCs). The i.MX 8M Mini family consists of the i.MX 8M Mini Quad, +i.MX 8M Mini QuadLite, i.MX 8M Mini Dual, i.MX 8M Mini DualLite, i.MX 8M Mini Solo, and i.MX +8M Mini SoloLite. The top-tier i.MX 8M Mini Quad features four Cortex-A53 cores as the main +processor cluster. The cores provide complete 64-bit Armv8-A support while maintaining seamless +backwards compatibility with 32-bit Armv7-A software. The main cores run at up to 1.8 GHz for +commercial graded products and 1.6 GHz for industrial temperature range products. + +In addition to the main CPU complex, the i.MX 8M Mini features a Cortex-M4F processor which +peaks up to 400 MHz. This processor is independent of the main complex and features its own +dedicated interfaces while still being able to access the regular interfaces. This heterogeneous +multicore system allows for the running of additional real-time operating systems on the M4 cores +for time- and security-critical tasks. + +- Board features: + + - RAM: 1GB - 2GB (LPDDR4) + - Storage: + + - 4GB - 17GB eMMC + - 2KB I²C EEPROM + - Wireless: + + - WiFi Dual-band 802.11 ac/a/b/g/n 2.4/5 GHz + - Bluetooth 5/BLE + - USB: + + - 1x USB2.0 Host + - 1x USB2.0 OTG + - Ethernet Gigabit + - Interfaces: + + - MIPI DSI 1x4 Data Lanes + - PCIe Gen 2 + - MIPI CSI-2 + - SPI + - QSPI + - UART + - I²C + - I²S + - SD/SDIO/MMC + - GPIOs + - CAN + - ADC + - S/PDIF + - Debug + + - JTAG 10-pin connector + +More information about the board can be found at the +`Toradex website`_. + +Supported Features +================== + +The Zephyr ``verdin_imx8mm/mimx8mm6/m4`` board target supports the following hardware +features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | GPIO output | +| | | GPIO input | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: +:zephyr_file:`boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4_defconfig`. + +It is recommended to disable peripherals used by the M4 core on the Linux host. + +Other hardware features are not currently supported by the port. + +Connections and IOs +=================== + +UART: + +Zephyr is configured to use the UART4 by default, which is connected to the FTDI +USB converter on most Toradex carrier boards. + +This is also the UART connected to WiFi/BT chip in modules that have the WiFi/BT +chip. Therefore, if UART4 is used, WiFI/BT will not work properly. + +If the WiFi/BT is needed, then another UART should be used for Zephyr (UART2 for +example). You can change the UART by changing the ``zephyr,console`` and +``zephyr,shell-uart`` in the :zephyr_file:`boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.dts` file. + ++---------------+-----------------+---------------------------+ +| Board Name | SoC Name | Usage | ++===============+=================+===========================+ +| UART_1 | UART2 | General purpose UART | ++---------------+-----------------+---------------------------+ +| UART_2 | UART3 | General purpose UART | ++---------------+-----------------+---------------------------+ +| UART_3 | UART1 | Cortex-A53 debug UART | ++---------------+-----------------+---------------------------+ +| UART_4 | UART4 | Cortex-M4 debug UART | ++---------------+-----------------+---------------------------+ + +GPIO: + +All the GPIO banks are enabled in the :zephyr_file:`dts/arm/nxp/nxp_imx8m_m4.dtsi`. + +LED: + +There is no LED in the module itself, this is dependent on the carrier board that +is being used with the module. The device tree is configured to use the GPIO3_IO1, +which can be connected to the LED of the Verdin Development Board or changed in the +:zephyr_file:`boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.dts` if needed. + +System Clock +============ + +The M4 Core is configured to run at a 400 MHz clock speed. + +Programming and Debugging +************************* + +The i.MX8MM doesn't have QSPI flash for the M4 and it needs +to be started by the A53 core. The A53 core is responsible to load the M4 binary +application into the RAM, putting the M4 in reset, setting the M4 Program Counter and +Stack Pointer, and get the M4 out of reset. The A53 can perform these steps at the +bootloader level or after the Linux system has booted via RemoteProc. + +The M4 can use up to 3 different RAMs. These are the memory mapping for A53 and M4: + ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| Region | Cortex-A53 | Cortex-M4 (System Bus) | Cortex-M4 (Code Bus) | Size | ++============+=========================+========================+=======================+======================+ +| OCRAM | 0x00900000-0x0093FFFF | 0x20200000-0x2023FFFF | 0x00900000-0x0093FFFF | 256KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| TCMU | 0x00800000-0x0081FFFF | 0x20000000-0x2001FFFF | | 128KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| TCML | 0x007E0000-0x007FFFFF | | 0x1FFE0000-0x1FFFFFFF | 128KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ +| OCRAM_S | 0x00180000-0x00187FFF | 0x20180000-0x20187FFF | 0x00180000-0x00187FFF | 32KB | ++------------+-------------------------+------------------------+-----------------------+----------------------+ + +For more information about memory mapping see the +`i.MX 8M Applications Processor Reference Manual`_ (section 2.1.2 and 2.1.3) + +At compilation time you have to choose which RAM will be used. This +configuration is done in the file :zephyr_file:`boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.dts` +with "zephyr,flash" (when CONFIG_XIP=y) and "zephyr,sram" properties. +The available configurations are: + +.. code-block:: none + + "zephyr,flash" + - &tcml_code + - &ocram_code + - &ocram_s_code + + "zephyr,sram" + - &tcmu_sys + - &ocram_sys + - &ocram_s_sys + +Starting the Cortex-M4 via U-Boot +================================= + +Load and run Zephyr on M4 from A53 using u-boot by copying the compiled +``zephyr.bin`` to the eMMC (can be the FAT or EXT4 partition). You can do it +by using a USB stick or through the ethernet with the scp command, for example. +Power it up and stop at the u-boot prompt. + +Load the M4 binary onto the desired memory and start its execution using: + +.. code-block:: console + + fatload mmc 0:1 ${loadaddr} zephyr.bin + cp.b ${loadaddr} 0x7e0000 + bootaux 0x7e0000 + +Or if the binary is on the ext4 partition: + +.. code-block:: console + + ext4load mmc 0:2 ${loadaddr} /path/to/zephyr.bin + cp.b ${loadaddr} 0x7e0000 + bootaux 0x7e0000 + +If you are using `TorizonCore`_ OS, then you should use partition 1: + +.. code-block:: console + + ext4load mmc 0:1 ${loadaddr} /path/to/zephyr.bin + cp.b ${loadaddr} 0x7e0000 + bootaux 0x7e0000 + +Starting the Cortex-M4 via RemoteProc +===================================== + +Copy the ``zepyhr.elf`` to ``/lib/firmware`` on the target. + +.. note:: + In order to use remoteproc you have to add ``imx8mm-verdin_hmp_overlay.dtbo`` at + the end of the line in the ``/boot/overlays.txt``, then reboot the target. If + you are using `TorizonCore`_, then this file is located at + ``/boot/ostree/torizon-/dtb/overlays.txt``. + +To load and start a firmware use these commands: + +.. code-block:: console + + verdin-imx8mm:~# echo zepyhr.elf > /sys/class/remoteproc/remoteproc0/firmware + verdin-imx8mm:~# echo start > /sys/class/remoteproc/remoteproc0/state + [ 94.714498] remoteproc remoteproc0: powering up imx-rproc + [ 94.720481] remoteproc remoteproc0: Booting fw image zephyr.elf, size 473172 + [ 94.727713] remoteproc remoteproc0: No resource table in elf + [ 94.733615] remoteproc remoteproc0: remote processor imx-rproc is now up + +The M4-Core is now started up and running. You can see the output from Zephyr +on UART4. + +Debugging +========= + +MIMX8MM EVK board can be debugged by connecting an external JLink +JTAG debugger to the J902 debug connector and to the PC. Then +the application can be debugged using the usual way. + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: verdin_imx8mm/mimx8mm6/m4 + :goals: debug + +Open a serial terminal, step through the application in your debugger, and you +should see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v3.4.0-1251-g43c549305bdb *** + Hello World! verdin_imx8mm_m4 + +.. _Toradex website: + https://developer.toradex.com/hardware/verdin-som-family/modules/verdin-imx8m-mini/ + +.. _i.MX 8M Applications Processor Reference Manual: + https://www.nxp.com/webapp/Download?colCode=IMX8MMRM + +.. _TorizonCore: + https://developer.toradex.com/torizon/ diff --git a/boards/toradex/verdin_imx8mm/verdin_imx8mm-pinctrl.dtsi b/boards/toradex/verdin_imx8mm/verdin_imx8mm-pinctrl.dtsi new file mode 100644 index 0000000000000..ed92bc9f03897 --- /dev/null +++ b/boards/toradex/verdin_imx8mm/verdin_imx8mm-pinctrl.dtsi @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Toradex + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart4_default: uart4_default { + group0 { + pinmux = <&iomuxc_uart4_rxd_uart_rx_uart4_rx>, + <&iomuxc_uart4_txd_uart_tx_uart4_tx>; + slew-rate = "fast"; + drive-strength = "x6"; + }; + }; + + uart3_default: uart3_default { + group0 { + pinmux = <&iomuxc_uart3_rxd_uart_rx_uart3_rx>, + <&iomuxc_uart3_txd_uart_tx_uart3_tx>; + slew-rate = "fast"; + drive-strength = "x6"; + }; + }; + + uart2_default: uart2_default { + group0 { + pinmux = <&iomuxc_sai3_rxd_uart_cts_b_uart2_rts_b>, + <&iomuxc_sai3_rxd_uart_rts_b_uart2_rts_b>, + <&iomuxc_sai3_txfs_uart_tx_uart2_rx>, + <&iomuxc_sai3_txc_uart_rx_uart2_tx>; + slew-rate = "fast"; + drive-strength = "x6"; + }; + }; + + uart1_default: uart1_default { + group0 { + pinmux = <&iomuxc_sai2_rxfs_uart_rx_uart1_tx>, + <&iomuxc_sai2_rxc_uart_rx_uart1_rx>, + <&iomuxc_sai2_rxd0_uart_rts_b_uart1_rts_b>, + <&iomuxc_sai2_txfs_uart_cts_b_uart1_cts_b>; + slew-rate = "fast"; + drive-strength = "x6"; + }; + }; +}; diff --git a/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.dts b/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.dts new file mode 100644 index 0000000000000..e1b0f61a1ccf0 --- /dev/null +++ b/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.dts @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024, Toradex + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "verdin_imx8mm-pinctrl.dtsi" + +/ { + model = "Toradex Verdin iMX8M Mini"; + compatible = "nxp,verdin_imx8mm"; + + aliases { + uart-1 = &uart1; + uart-2 = &uart2; + uart-3 = &uart3; + uart-4 = &uart4; + led0 = &led_0; + }; + + chosen { + zephyr,flash = &tcml_code; + zephyr,sram = &tcmu_sys; + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + }; + + leds { + compatible = "gpio-leds"; + + led_0: led_0 { + gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&gpio3 { + status = "okay"; +}; + +&mailbox0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_default>; + current-speed = <115200>; + status = "disabled"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_default>; + current-speed = <115200>; + status = "disabled"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_default>; + current-speed = <115200>; + status = "disabled"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_default>; + current-speed = <115200>; + status = "okay"; +}; diff --git a/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.yaml b/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.yaml new file mode 100644 index 0000000000000..b002b13dd5445 --- /dev/null +++ b/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4.yaml @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Toradex +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: verdin_imx8mm/mimx8mm6/m4 +name: Toradex Verdin iMX8M Mini +type: mcu +arch: arm +ram: 128 +flash: 128 +toolchain: + - zephyr + - gnuarmemb +testing: + ignore_tags: + - net + - bluetooth +vendor: toradex diff --git a/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4_defconfig b/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4_defconfig new file mode 100644 index 0000000000000..0978045d488d0 --- /dev/null +++ b/boards/toradex/verdin_imx8mm/verdin_imx8mm_mimx8mm6_m4_defconfig @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 Toradex +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CLOCK_CONTROL=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_XIP=y +CONFIG_GPIO=y diff --git a/boards/toradex/verdin_imx8mp/verdin_imx8mp_mimx8ml8_m7.yaml b/boards/toradex/verdin_imx8mp/verdin_imx8mp_mimx8ml8_m7.yaml index e4e77056bc0fc..cd1e458f6842d 100644 --- a/boards/toradex/verdin_imx8mp/verdin_imx8mp_mimx8ml8_m7.yaml +++ b/boards/toradex/verdin_imx8mp/verdin_imx8mp_mimx8ml8_m7.yaml @@ -13,6 +13,5 @@ flash: 128 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart diff --git a/boards/toradex/verdin_imx8mp/verdin_imx8mp_mimx8ml8_m7_ddr.yaml b/boards/toradex/verdin_imx8mp/verdin_imx8mp_mimx8ml8_m7_ddr.yaml index 979dbfa498d24..5ba25e228c812 100644 --- a/boards/toradex/verdin_imx8mp/verdin_imx8mp_mimx8ml8_m7_ddr.yaml +++ b/boards/toradex/verdin_imx8mp/verdin_imx8mp_mimx8ml8_m7_ddr.yaml @@ -13,6 +13,5 @@ flash: 2048 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart diff --git a/boards/u-blox/ubx_bmd300eval/ubx_bmd300eval_nrf52832.yaml b/boards/u-blox/ubx_bmd300eval/ubx_bmd300eval_nrf52832.yaml index 910642809d6cc..9f77ebe06892d 100644 --- a/boards/u-blox/ubx_bmd300eval/ubx_bmd300eval_nrf52832.yaml +++ b/boards/u-blox/ubx_bmd300eval/ubx_bmd300eval_nrf52832.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/u-blox/ubx_bmd330eval/ubx_bmd330eval.yaml b/boards/u-blox/ubx_bmd330eval/ubx_bmd330eval.yaml index 50d337f1c35b3..5b7c00f0cc066 100644 --- a/boards/u-blox/ubx_bmd330eval/ubx_bmd330eval.yaml +++ b/boards/u-blox/ubx_bmd330eval/ubx_bmd330eval.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 24 flash: 192 supported: diff --git a/boards/u-blox/ubx_bmd340eval/ubx_bmd340eval_nrf52840.yaml b/boards/u-blox/ubx_bmd340eval/ubx_bmd340eval_nrf52840.yaml index eeca79d1e5e43..cacac6dc2b33b 100644 --- a/boards/u-blox/ubx_bmd340eval/ubx_bmd340eval_nrf52840.yaml +++ b/boards/u-blox/ubx_bmd340eval/ubx_bmd340eval_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/u-blox/ubx_bmd345eval/ubx_bmd345eval_nrf52840.yaml b/boards/u-blox/ubx_bmd345eval/ubx_bmd345eval_nrf52840.yaml index f79940dbbbdf0..ca5ec5224640f 100644 --- a/boards/u-blox/ubx_bmd345eval/ubx_bmd345eval_nrf52840.yaml +++ b/boards/u-blox/ubx_bmd345eval/ubx_bmd345eval_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_i2c diff --git a/boards/u-blox/ubx_bmd360eval/ubx_bmd360eval_nrf52811.yaml b/boards/u-blox/ubx_bmd360eval/ubx_bmd360eval_nrf52811.yaml index 4df9c1172f013..96820eeef2b4f 100644 --- a/boards/u-blox/ubx_bmd360eval/ubx_bmd360eval_nrf52811.yaml +++ b/boards/u-blox/ubx_bmd360eval/ubx_bmd360eval_nrf52811.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 24 flash: 192 supported: diff --git a/boards/u-blox/ubx_bmd380eval/ubx_bmd380eval_nrf52840.yaml b/boards/u-blox/ubx_bmd380eval/ubx_bmd380eval_nrf52840.yaml index a794a4cac05ec..31e23654cef5c 100644 --- a/boards/u-blox/ubx_bmd380eval/ubx_bmd380eval_nrf52840.yaml +++ b/boards/u-blox/ubx_bmd380eval/ubx_bmd380eval_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/u-blox/ubx_evkannab1/ubx_evkannab1_nrf52832.yaml b/boards/u-blox/ubx_evkannab1/ubx_evkannab1_nrf52832.yaml index 54af92298d8f5..2e3748675c155 100644 --- a/boards/u-blox/ubx_evkannab1/ubx_evkannab1_nrf52832.yaml +++ b/boards/u-blox/ubx_evkannab1/ubx_evkannab1_nrf52832.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/u-blox/ubx_evkninab1/ubx_evkninab1_nrf52832.yaml b/boards/u-blox/ubx_evkninab1/ubx_evkninab1_nrf52832.yaml index 286e66b97cbad..f1ea3c44ad563 100644 --- a/boards/u-blox/ubx_evkninab1/ubx_evkninab1_nrf52832.yaml +++ b/boards/u-blox/ubx_evkninab1/ubx_evkninab1_nrf52832.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/u-blox/ubx_evkninab3/ubx_evkninab3_nrf52840.yaml b/boards/u-blox/ubx_evkninab3/ubx_evkninab3_nrf52840.yaml index 6e01ef035e8ee..8aad52f8b229f 100644 --- a/boards/u-blox/ubx_evkninab3/ubx_evkninab3_nrf52840.yaml +++ b/boards/u-blox/ubx_evkninab3/ubx_evkninab3_nrf52840.yaml @@ -7,7 +7,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/u-blox/ubx_evkninab4/ubx_evkninab4_nrf52833.yaml b/boards/u-blox/ubx_evkninab4/ubx_evkninab4_nrf52833.yaml index f7f8cb355a93d..a89676bfefa3d 100644 --- a/boards/u-blox/ubx_evkninab4/ubx_evkninab4_nrf52833.yaml +++ b/boards/u-blox/ubx_evkninab4/ubx_evkninab4_nrf52833.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - arduino_gpio diff --git a/boards/udoo/udoo_neo_full/udoo_neo_full_mcimx6x_m4.yaml b/boards/udoo/udoo_neo_full/udoo_neo_full_mcimx6x_m4.yaml index 4fdd64933092a..6a1ee179451e4 100644 --- a/boards/udoo/udoo_neo_full/udoo_neo_full_mcimx6x_m4.yaml +++ b/boards/udoo/udoo_neo_full/udoo_neo_full_mcimx6x_m4.yaml @@ -13,7 +13,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - gpio diff --git a/boards/vcc-gnd/yd_esp32/yd_esp32_appcpu.dts b/boards/vcc-gnd/yd_esp32/yd_esp32_appcpu.dts index 15f7a6a25d84f..3514cbabbd3e1 100644 --- a/boards/vcc-gnd/yd_esp32/yd_esp32_appcpu.dts +++ b/boards/vcc-gnd/yd_esp32/yd_esp32_appcpu.dts @@ -13,9 +13,11 @@ compatible = "espressif,esp32"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; }; }; diff --git a/boards/vcc-gnd/yd_esp32/yd_esp32_appcpu_defconfig b/boards/vcc-gnd/yd_esp32/yd_esp32_appcpu_defconfig index 9abf2ff0430ab..48546641cadd6 100644 --- a/boards/vcc-gnd/yd_esp32/yd_esp32_appcpu_defconfig +++ b/boards/vcc-gnd/yd_esp32/yd_esp32_appcpu_defconfig @@ -1,4 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.dts b/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.dts index 489580a3e25ea..119e18f222ff5 100644 --- a/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.dts +++ b/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.dts @@ -31,7 +31,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.yaml b/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.yaml index 7e8e17cf71f08..99ac539076883 100644 --- a/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.yaml +++ b/boards/vcc-gnd/yd_esp32/yd_esp32_procpu.yaml @@ -17,8 +17,4 @@ supported: - spi - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: vcc-gnd diff --git a/boards/vcc-gnd/yd_esp32/yd_esp32_procpu_defconfig b/boards/vcc-gnd/yd_esp32/yd_esp32_procpu_defconfig index 4fc7d44e0852a..19979ff26adef 100644 --- a/boards/vcc-gnd/yd_esp32/yd_esp32_procpu_defconfig +++ b/boards/vcc-gnd/yd_esp32/yd_esp32_procpu_defconfig @@ -1,8 +1,6 @@ # Copyright (c) 2023 Julio Cesar # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/vcc-gnd/yd_stm32h750vb/yd_stm32h750vb.yaml b/boards/vcc-gnd/yd_stm32h750vb/yd_stm32h750vb.yaml index 0ce537a1bd4c1..fc7d992e2af4d 100644 --- a/boards/vcc-gnd/yd_stm32h750vb/yd_stm32h750vb.yaml +++ b/boards/vcc-gnd/yd_stm32h750vb/yd_stm32h750vb.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 1024 flash: 128 supported: diff --git a/boards/vngiotlab/nrf51_vbluno51/nrf51_vbluno51.yaml b/boards/vngiotlab/nrf51_vbluno51/nrf51_vbluno51.yaml index 7e8cb981eee9c..f389f34e77d07 100644 --- a/boards/vngiotlab/nrf51_vbluno51/nrf51_vbluno51.yaml +++ b/boards/vngiotlab/nrf51_vbluno51/nrf51_vbluno51.yaml @@ -5,5 +5,4 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 diff --git a/boards/vngiotlab/nrf52_vbluno52/nrf52_vbluno52.yaml b/boards/vngiotlab/nrf52_vbluno52/nrf52_vbluno52.yaml index dd9971acc314f..408109bcd5fd4 100644 --- a/boards/vngiotlab/nrf52_vbluno52/nrf52_vbluno52.yaml +++ b/boards/vngiotlab/nrf52_vbluno52/nrf52_vbluno52.yaml @@ -5,6 +5,5 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_appcpu.dts b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_appcpu.dts index 949f7a79a3244..e0b45b9ee0a2a 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_appcpu.dts +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_appcpu.dts @@ -5,14 +5,14 @@ /dts-v1/; #include -#include +#include / { model = "ESP32-S3-Touch-LCD-1.28 APPCPU"; compatible = "waveshare,esp32-s3-touch-lcd-1.28"; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &ipm0; zephyr,flash = &flash0; diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_appcpu_defconfig b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_appcpu_defconfig index 15e93d6bf4ad9..6a13f9c9e3928 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_appcpu_defconfig +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_appcpu_defconfig @@ -1,5 +1,4 @@ # Copyright (c) 2024 Joel Guittet # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_CLOCK_CONTROL=y diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.dts b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.dts index 18e8e900813ac..1204ed87bbdc5 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.dts +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.dts @@ -9,7 +9,7 @@ #include #include #include -#include +#include / { model = "ESP32-S3-Touch-LCD-1.28 PROCPU"; @@ -25,7 +25,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; @@ -74,7 +74,7 @@ compatible = "galaxycore,gc9x01x"; reg = <0>; mipi-max-frequency = <100000000>; - pixel-format = ; + pixel-format = ; display-inversion; width = <240>; height = <240>; diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.yaml b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.yaml index 5c81ff792a320..a2ae32d60f659 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.yaml +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu.yaml @@ -15,8 +15,4 @@ supported: - pinmux - nvs - display -testing: - ignore_tags: - - net - - bluetooth vendor: waveshare diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu_defconfig b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu_defconfig index 50c7db47465d8..a763fa8944dbc 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu_defconfig +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/esp32s3_touch_lcd_1_28_esp32s3_procpu_defconfig @@ -1,7 +1,6 @@ # Copyright (c) 2024 Joel Guittet # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 CONFIG_GPIO=y CONFIG_REGULATOR=y CONFIG_CONSOLE=y diff --git a/boards/waveshare/nrf51_ble400/nrf51_ble400.yaml b/boards/waveshare/nrf51_ble400/nrf51_ble400.yaml index 93c73fcd84fbf..681d32ac53254 100644 --- a/boards/waveshare/nrf51_ble400/nrf51_ble400.yaml +++ b/boards/waveshare/nrf51_ble400/nrf51_ble400.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 supported: - ble diff --git a/boards/waveshare/open103z/waveshare_open103z.yaml b/boards/waveshare/open103z/waveshare_open103z.yaml index c4df844c6825f..ae64dca74f77d 100644 --- a/boards/waveshare/open103z/waveshare_open103z.yaml +++ b/boards/waveshare/open103z/waveshare_open103z.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 64 flash: 512 supported: diff --git a/boards/waveshare/rp2040_zero/rp2040_zero.dts b/boards/waveshare/rp2040_zero/rp2040_zero.dts index 9d582a970549f..6e593f9a5ab43 100644 --- a/boards/waveshare/rp2040_zero/rp2040_zero.dts +++ b/boards/waveshare/rp2040_zero/rp2040_zero.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include +#include #include "rp2040_zero-pinctrl.dtsi" #include #include @@ -28,7 +28,7 @@ }; &flash0 { - reg = <0x10000000 DT_SIZE_M(16)>; + reg = <0x10000000 DT_SIZE_M(2)>; partitions { compatible = "fixed-partitions"; @@ -44,11 +44,11 @@ /* * Usable flash. Starts at 0x100, after the bootloader. The partition - * size is 16MB minus the 0x100 bytes taken by the bootloader. + * size is 2MB minus the 0x100 bytes taken by the bootloader. */ code_partition: partition@100 { label = "code-partition"; - reg = <0x100 (DT_SIZE_M(16) - 0x100)>; + reg = <0x100 (DT_SIZE_M(2) - 0x100)>; read-only; }; }; diff --git a/boards/waveshare/rp2040_zero/rp2040_zero.yaml b/boards/waveshare/rp2040_zero/rp2040_zero.yaml index b93e332f7d815..409dd03975fdc 100644 --- a/boards/waveshare/rp2040_zero/rp2040_zero.yaml +++ b/boards/waveshare/rp2040_zero/rp2040_zero.yaml @@ -2,12 +2,11 @@ identifier: rp2040_zero name: Waveshare RP2040-Zero type: mcu arch: arm -flash: 16384 +flash: 2048 ram: 264 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio diff --git a/boards/wch/ch32v003evt/board.cmake b/boards/wch/ch32v003evt/board.cmake index 1e0edfa18791e..41ee69473bf2e 100644 --- a/boards/wch/ch32v003evt/board.cmake +++ b/boards/wch/ch32v003evt/board.cmake @@ -1,8 +1,8 @@ # Copyright (c) 2024 Michael Hope # SPDX-License-Identifier: Apache-2.0 -board_runner_args(openocd "--use-elf" "--cmd-reset-halt" "halt") -include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) - board_runner_args(minichlink) include(${ZEPHYR_BASE}/boards/common/minichlink.board.cmake) + +board_runner_args(openocd "--use-elf" "--cmd-reset-halt" "halt") +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/wch/ch32v003evt/ch32v003evt.dts b/boards/wch/ch32v003evt/ch32v003evt.dts index d702b6d43d065..482c14045b06e 100644 --- a/boards/wch/ch32v003evt/ch32v003evt.dts +++ b/boards/wch/ch32v003evt/ch32v003evt.dts @@ -5,7 +5,7 @@ /dts-v1/; -#include +#include #include "ch32v003evt-pinctrl.dtsi" / { diff --git a/boards/we/oceanus1ev/Kconfig.defconfig b/boards/we/oceanus1ev/Kconfig.defconfig new file mode 100644 index 0000000000000..d644612b5e6f9 --- /dev/null +++ b/boards/we/oceanus1ev/Kconfig.defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_WE_OCEANUS1EV + +if LORA + +config MAIN_STACK_SIZE + default 2048 + +endif # LORA + +endif # BOARD_WE_OCEANUS1EV diff --git a/boards/we/oceanus1ev/Kconfig.we_oceanus1ev b/boards/we/oceanus1ev/Kconfig.we_oceanus1ev new file mode 100644 index 0000000000000..67f92ed7cdc1d --- /dev/null +++ b/boards/we/oceanus1ev/Kconfig.we_oceanus1ev @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_WE_OCEANUS1EV + select SOC_STM32WLE5XX diff --git a/boards/we/oceanus1ev/board.cmake b/boards/we/oceanus1ev/board.cmake new file mode 100644 index 0000000000000..4cba054c8a52e --- /dev/null +++ b/boards/we/oceanus1ev/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=STM32WLE5CC" "--speed=4000" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/we/oceanus1ev/board.yml b/boards/we/oceanus1ev/board.yml new file mode 100644 index 0000000000000..35c0780bdda90 --- /dev/null +++ b/boards/we/oceanus1ev/board.yml @@ -0,0 +1,12 @@ +board: + name: we_oceanus1ev + full_name: Oceanus-I EV + vendor: we + revision: + format: "major.minor.patch" + default: "1.1.0" + exact: true + revisions: + - name: "1.1.0" + socs: + - name: stm32wle5xx diff --git a/boards/we/oceanus1ev/doc/img/we_oceanus1ev.webp b/boards/we/oceanus1ev/doc/img/we_oceanus1ev.webp new file mode 100644 index 0000000000000..92eade76cdb8c Binary files /dev/null and b/boards/we/oceanus1ev/doc/img/we_oceanus1ev.webp differ diff --git a/boards/we/oceanus1ev/doc/index.rst b/boards/we/oceanus1ev/doc/index.rst new file mode 100644 index 0000000000000..1ccb459e328e3 --- /dev/null +++ b/boards/we/oceanus1ev/doc/index.rst @@ -0,0 +1,105 @@ +.. zephyr:board:: we_oceanus1ev + +Overview +******** + +The we_oceanus1ev board is an evaluation board of the `Oceanus-I`_ radio module. +It provides support for the `STM32WLE5CC`_ ARM CPU and +the following devices: + +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* RADIO (LoRa) +* :abbr:`RTC (STM32 RTC System Clock)` +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UART (Universal asynchronous receiver-transmitter)` +* :abbr:`WDT (Watchdog Timer)` + +Hardware +******** + +The board has below hardware features: + +- `Oceanus-I`_, 256KB Flash, 64KB RAM with external antenna +- 1 FTDI chip (USB to UART) converter +- 1 I2C WE sensor EV-Boards connector +- 1 SPI WE sensor EV-Boards connector +- 2 application LEDs +- 1 application, and 1 reset push-button + +Supported Features +================== + +The ``we_oceanus1ev`` board supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| RADIO | on-chip | LoRa | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Programming and Debugging +************************* + +Applications for the ``we_oceanus1ev`` board can be built the +usual way (see :ref:`build_an_application`). + +The board debugged and flashed with an external debug probe connected +to the SWD pins, current native support is for the JLink debug probe. + +Flashing +======== + +Connect the board to your host computer and build and flash an application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: we_oceanus1ev + :goals: build flash + +Run a serial terminal to connect with your board. By default, ``lpuart1`` is +accessible via the on-board FTDI USB to UART converter. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`blinky` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: we_oceanus1ev + :maybe-skip-config: + :goals: debug + +References +********** + +.. target-notes:: + +.. _`Oceanus-I`: https://www.we-online.com/katalog/de/OCEANUS-I +.. _`STM32WLE5CC`: https://www.st.com/en/microcontrollers-microprocessors/stm32wle5cc.html diff --git a/boards/we/oceanus1ev/we_oceanus1ev.dts b/boards/we/oceanus1ev/we_oceanus1ev.dts new file mode 100644 index 0000000000000..a861c63d0e4e5 --- /dev/null +++ b/boards/we/oceanus1ev/we_oceanus1ev.dts @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "Oceanus-I EV"; + compatible = "we,oceanus1ev"; + + chosen { + zephyr,console = &lpuart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + + yellow_led: led_1 { + gpios = <&gpioa 7 GPIO_ACTIVE_HIGH>; + label = "LED_1"; + }; + + blue_led: led_2 { + gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>; + label = "LED_2"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + wake_up_button: button_0 { + label = "/WAKE_UP"; + gpios = <&gpioa 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &yellow_led; + led1 = &blue_led; + sw0 = &wake_up_button; + lora0 = &lora; + watchdog0 = &iwdg; + }; +}; + +stm32_lp_tick_source: &lptim1 { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x80000000>, + <&rcc STM32_SRC_LSE LPTIM1_SEL(3)>; + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + +&pll { + div-m = <1>; + mul-n = <6>; + div-r = <2>; + div-q = <2>; + clocks = <&clk_hsi>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + cpu1-prescaler = <1>; + ahb3-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&lpuart1 { + pinctrl-0 = <&lpuart1_tx_pa2 &lpuart1_rx_pa3>; + pinctrl-names = "default"; + current-speed = <9600>; + status = "okay"; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb7>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pb3 &spi1_miso_pb4 &spi1_mosi_pb5>; + pinctrl-names = "default"; + cs-gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>, + <&rcc STM32_SRC_LSE RTC_SEL(2)>; + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(32)>; + read-only; + }; + slot0_partition: partition@8000 { + label = "image-0"; + reg = <0x00008000 DT_SIZE_K(108)>; + }; + slot1_partition: partition@23000 { + label = "image-1"; + reg = <0x00023000 DT_SIZE_K(108)>; + }; + storage_partition: partition@3e000 { + label = "storage"; + reg = <0x0003e000 DT_SIZE_K(8)>; + }; + }; +}; diff --git a/boards/we/oceanus1ev/we_oceanus1ev_1_1_0.yaml b/boards/we/oceanus1ev/we_oceanus1ev_1_1_0.yaml new file mode 100644 index 0000000000000..600d75ac2bc87 --- /dev/null +++ b/boards/we/oceanus1ev/we_oceanus1ev_1_1_0.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +identifier: we_oceanus1ev@1.1.0 +name: Oceanus-I EV (rev 1.1) +type: mcu +arch: arm +toolchain: + - zephyr +ram: 64 +flash: 256 +supported: + - counter + - gpio + - i2c + - nvs + - spi + - uart + - watchdog + - lora +vendor: we diff --git a/boards/we/oceanus1ev/we_oceanus1ev_defconfig b/boards/we/oceanus1ev/we_oceanus1ev_defconfig new file mode 100644 index 0000000000000..dddce979cc9dc --- /dev/null +++ b/boards/we/oceanus1ev/we_oceanus1ev_defconfig @@ -0,0 +1,15 @@ +# Enable UART driver +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/we/ophelia1ev/we_ophelia1ev_nrf52805.yaml b/boards/we/ophelia1ev/we_ophelia1ev_nrf52805.yaml index 5b55a854a0d99..6b47fe26a5b0d 100644 --- a/boards/we/ophelia1ev/we_ophelia1ev_nrf52805.yaml +++ b/boards/we/ophelia1ev/we_ophelia1ev_nrf52805.yaml @@ -10,7 +10,6 @@ flash: 192 toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - i2c diff --git a/boards/we/orthosie1ev/we_orthosie1ev.yaml b/boards/we/orthosie1ev/we_orthosie1ev.yaml index 82e60eadc3247..0033d15834306 100644 --- a/boards/we/orthosie1ev/we_orthosie1ev.yaml +++ b/boards/we/orthosie1ev/we_orthosie1ev.yaml @@ -16,8 +16,4 @@ supported: - spi - counter - entropy -testing: - ignore_tags: - - net - - bluetooth vendor: we diff --git a/boards/we/orthosie1ev/we_orthosie1ev_defconfig b/boards/we/orthosie1ev/we_orthosie1ev_defconfig index ef633ce56a18e..187793c76e8cc 100644 --- a/boards/we/orthosie1ev/we_orthosie1ev_defconfig +++ b/boards/we/orthosie1ev/we_orthosie1ev_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/we/proteus2ev/we_proteus2ev_nrf52832.yaml b/boards/we/proteus2ev/we_proteus2ev_nrf52832.yaml index e30510176d0db..ca37439689f65 100644 --- a/boards/we/proteus2ev/we_proteus2ev_nrf52832.yaml +++ b/boards/we/proteus2ev/we_proteus2ev_nrf52832.yaml @@ -10,7 +10,6 @@ flash: 512 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - gpio diff --git a/boards/we/proteus3ev/we_proteus3ev_nrf52840.yaml b/boards/we/proteus3ev/we_proteus3ev_nrf52840.yaml index 5a771ca28b386..2467fb4279591 100644 --- a/boards/we/proteus3ev/we_proteus3ev_nrf52840.yaml +++ b/boards/we/proteus3ev/we_proteus3ev_nrf52840.yaml @@ -10,7 +10,6 @@ flash: 1024 toolchain: - zephyr - gnuarmemb - - xtools supported: - adc - ble diff --git a/boards/weact/blackpill_f401cc/blackpill_f401cc.dts b/boards/weact/blackpill_f401cc/blackpill_f401cc.dts index 1fdecac970423..07d48c5497c38 100644 --- a/boards/weact/blackpill_f401cc/blackpill_f401cc.dts +++ b/boards/weact/blackpill_f401cc/blackpill_f401cc.dts @@ -125,7 +125,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in1_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/weact/blackpill_f401cc/blackpill_f401cc.yaml b/boards/weact/blackpill_f401cc/blackpill_f401cc.yaml index b8f88615acda9..fafe8e0bd8c32 100644 --- a/boards/weact/blackpill_f401cc/blackpill_f401cc.yaml +++ b/boards/weact/blackpill_f401cc/blackpill_f401cc.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - spi diff --git a/boards/weact/blackpill_f401ce/blackpill_f401ce.dts b/boards/weact/blackpill_f401ce/blackpill_f401ce.dts index d670a32701983..04d490d0f79c4 100644 --- a/boards/weact/blackpill_f401ce/blackpill_f401ce.dts +++ b/boards/weact/blackpill_f401ce/blackpill_f401ce.dts @@ -125,7 +125,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in1_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/weact/blackpill_f401ce/blackpill_f401ce.yaml b/boards/weact/blackpill_f401ce/blackpill_f401ce.yaml index 5f44db28d397d..7881fc6071a73 100644 --- a/boards/weact/blackpill_f401ce/blackpill_f401ce.yaml +++ b/boards/weact/blackpill_f401ce/blackpill_f401ce.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - spi diff --git a/boards/weact/blackpill_f411ce/blackpill_f411ce.dts b/boards/weact/blackpill_f411ce/blackpill_f411ce.dts index d53bfa5f021f5..5acd309cbc9f8 100644 --- a/boards/weact/blackpill_f411ce/blackpill_f411ce.dts +++ b/boards/weact/blackpill_f411ce/blackpill_f411ce.dts @@ -126,7 +126,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_in1_pa1>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <2>; status = "okay"; }; diff --git a/boards/weact/blackpill_f411ce/blackpill_f411ce.yaml b/boards/weact/blackpill_f411ce/blackpill_f411ce.yaml index f93ce7397cde9..95a2abe993644 100644 --- a/boards/weact/blackpill_f411ce/blackpill_f411ce.yaml +++ b/boards/weact/blackpill_f411ce/blackpill_f411ce.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools supported: - counter - spi diff --git a/boards/weact/mini_stm32h743/Kconfig.defconfig b/boards/weact/mini_stm32h743/Kconfig.defconfig index bcc31baaf59fa..3ebe575aff615 100644 --- a/boards/weact/mini_stm32h743/Kconfig.defconfig +++ b/boards/weact/mini_stm32h743/Kconfig.defconfig @@ -22,14 +22,6 @@ endif # LVGL endif # DISPLAY -if USB_DEVICE_STACK - -config UART_CONSOLE - default CONSOLE - -config USB_DEVICE_INITIALIZE_AT_BOOT - default y - -endif # USB_DEVICE_STACK +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" endif # BOARD_MINI_STM32H743 diff --git a/boards/weact/mini_stm32h743/mini_stm32h743.dts b/boards/weact/mini_stm32h743/mini_stm32h743.dts index 5a63ca0f5bede..abec39683d407 100644 --- a/boards/weact/mini_stm32h743/mini_stm32h743.dts +++ b/boards/weact/mini_stm32h743/mini_stm32h743.dts @@ -15,8 +15,6 @@ compatible = "weact,mini-stm32h743"; chosen { - zephyr,console = &usb_cdc_acm_uart; - zephyr,shell-uart = &usb_cdc_acm_uart; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,display = &st7735r_160x80; @@ -155,12 +153,10 @@ zephyr_udc0: &usbotg_fs { pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; pinctrl-names = "default"; status = "okay"; - - usb_cdc_acm_uart: cdc_acm_uart { - compatible = "zephyr,cdc-acm-uart"; - }; }; +#include <../boards/common/usb/cdc_acm_serial.dtsi> + &quadspi { pinctrl-names = "default"; pinctrl-0 = <&quadspi_clk_pb2 &quadspi_bk1_ncs_pb6 diff --git a/boards/weact/mini_stm32h743/mini_stm32h743.yaml b/boards/weact/mini_stm32h743/mini_stm32h743.yaml index 10edcbb5ed2a0..7e24ed909c945 100644 --- a/boards/weact/mini_stm32h743/mini_stm32h743.yaml +++ b/boards/weact/mini_stm32h743/mini_stm32h743.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 2048 supported: diff --git a/boards/weact/mini_stm32h743/mini_stm32h743_defconfig b/boards/weact/mini_stm32h743/mini_stm32h743_defconfig index 809e85276c9bb..7feee60d01cce 100644 --- a/boards/weact/mini_stm32h743/mini_stm32h743_defconfig +++ b/boards/weact/mini_stm32h743/mini_stm32h743_defconfig @@ -15,9 +15,3 @@ CONFIG_CONSOLE=y # Enable GPIO CONFIG_GPIO=y - -# Logger cannot use itself to log -CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y - -# Enable USB -CONFIG_USB_DEVICE_STACK=y diff --git a/boards/weact/mini_stm32h7b0/mini_stm32h7b0.yaml b/boards/weact/mini_stm32h7b0/mini_stm32h7b0.yaml index d9904423aa660..6dfd11a35bc94 100644 --- a/boards/weact/mini_stm32h7b0/mini_stm32h7b0.yaml +++ b/boards/weact/mini_stm32h7b0/mini_stm32h7b0.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 2048 supported: diff --git a/boards/weact/stm32f405_core/weact_stm32f405_core.yaml b/boards/weact/stm32f405_core/weact_stm32f405_core.yaml index e1f98a41ce4b0..c1854ca57f740 100644 --- a/boards/weact/stm32f405_core/weact_stm32f405_core.yaml +++ b/boards/weact/stm32f405_core/weact_stm32f405_core.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 128 flash: 1024 supported: diff --git a/boards/weact/stm32g431_core/weact_stm32g431_core.dts b/boards/weact/stm32g431_core/weact_stm32g431_core.dts index ca6dfcf656935..1038536369f83 100644 --- a/boards/weact/stm32g431_core/weact_stm32g431_core.dts +++ b/boards/weact/stm32g431_core/weact_stm32g431_core.dts @@ -154,7 +154,7 @@ stm32_lp_tick_source: &lptim1 { &adc2 { pinctrl-0 = <&adc2_in12_pb2>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; #address-cells = <1>; diff --git a/boards/weact/stm32g431_core/weact_stm32g431_core.yaml b/boards/weact/stm32g431_core/weact_stm32g431_core.yaml index 91886ad0ea51a..5392afdbd4b16 100644 --- a/boards/weact/stm32g431_core/weact_stm32g431_core.yaml +++ b/boards/weact/stm32g431_core/weact_stm32g431_core.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 32 flash: 128 supported: diff --git a/boards/weact/stm32h5_core/Kconfig.weact_stm32h5_core b/boards/weact/stm32h5_core/Kconfig.weact_stm32h5_core new file mode 100644 index 0000000000000..999012b1955ed --- /dev/null +++ b/boards/weact/stm32h5_core/Kconfig.weact_stm32h5_core @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Kacper Brzostowski +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_WEACT_STM32H5_CORE + select SOC_STM32H562XX diff --git a/boards/weact/stm32h5_core/board.cmake b/boards/weact/stm32h5_core/board.cmake new file mode 100644 index 0000000000000..2288b4765efc8 --- /dev/null +++ b/boards/weact/stm32h5_core/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Kacper Brzostowski +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(dfu-util "--pid=0483:df11" "--alt=0" "--dfuse") + +# Keep first +include(${ZEPHYR_BASE}/boards/common/dfu-util.board.cmake) diff --git a/boards/weact/stm32h5_core/board.yml b/boards/weact/stm32h5_core/board.yml new file mode 100644 index 0000000000000..ad89ef703655f --- /dev/null +++ b/boards/weact/stm32h5_core/board.yml @@ -0,0 +1,6 @@ +board: + name: weact_stm32h5_core + full_name: STM32H5 Core Board + vendor: weact + socs: + - name: stm32h562xx diff --git a/boards/weact/stm32h5_core/doc/index.rst b/boards/weact/stm32h5_core/doc/index.rst new file mode 100644 index 0000000000000..a128d4b358b6d --- /dev/null +++ b/boards/weact/stm32h5_core/doc/index.rst @@ -0,0 +1,230 @@ +.. zephyr:board:: weact_stm32h5_core + +Overview +******** + +The ``weact_stm32h5_core`` board is a compact development board equipped with +an STM32H562RGT6 microcontroller. It features basic set of peripherals: +user LED and button, microSD |trade| card slot, and combined SWD & UART header. + +Key Features + +- STM32 microcontroller in LQFP64 package +- USB OTG or full-speed device +- 1 user LED +- User, boot, and reset push-buttons +- 32.768 kHz and 8MHz HSE crystal oscillators +- Board connectors: + + - microSD |trade| card + - USB Type-C Connector + - SWD & UART header for external debugger + - 2x 30-pin GPIO connector + +More information about the board can be found on the `WeAct GitHub`_. + +Hardware +******** + +The ``weact_stm32h5_core`` board provides the following hardware components: + + - STM32H562RGT6 in LQFP64 package + - ARM 32-bit Cortex-M33 CPU with FPU + - CORDIC for trigonometric functions acceleration + - FMAC (filter mathematical accelerator) + - CRC calculation unit + - 240 MHz max CPU frequency + - VDD from 1.71 V to 3.6 V + - 1MB Flash, 2 banks read-while-write + - 640kB SRAM + - 4 Kbytes of backup SRAM available in the lowest power modes + - 2x watchdogs + - 2x SysTick timer + - 32-bit timers (2) + - 16-bit advanced motor control timers (2) + - 16-bit low power timers (6) + - 16-bit timers (10) + - 1x USB Type-C / USB power-delivery controller + - 1x USB 2.0 full-speed host and device + - 4x I2C FM+ interfaces (SMBus/PMBus) + - 1x I3C interface + - 12x U(S)ARTS (ISO7816 interface, LIN, IrDA, modem control) + - 1x LP UART + - 6x SPIs including 3 muxed with full-duplex I2S + - 2x SAI + - 1x FDCAN + - Flexible external memory controller with up to 16-bit data bus: SRAM, PSRAM, FRAM, SDRAM/LPSDR SDRAM, NOR/NAND memories + - 1x OCTOSPI memory interface with on-the-fly decryption and support for serial PSRAM/NAND/NOR, Hyper RAM/Flash frame formats + - 1x SD/SDIO/MMC interfaces + - 1x HDMI-CEC + - 2x 12-bit ADC with up to 5 MSPS in 12-bit + - 1x 12-bit D/A with 2 channels + - 1x Digital temperature sensor + +More information about STM32H562RG can be found here: + +- `STM32H562RG on www.st.com`_ +- `STM32H562 reference manual`_ + +Supported Features +================== + +The Zephyr ``weact_stm32h5_core`` board supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| CAN/CANFD | on-chip | CAN | ++-----------+------------+-------------------------------------+ +| CLOCK | on-chip | reset and clock control | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+-------------------------------------+ +| RNG | on-chip | True Random number generator | ++-----------+------------+-------------------------------------+ +| RTC | on-chip | Real Time Clock | ++-----------+------------+-------------------------------------+ +| SPI | on-chip | spi bus | ++-----------+------------+-------------------------------------+ +| I2C | on-chip | i2c bus | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial port-polling; | +| | | serial port-interrupt | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | independent watchdog | ++-----------+------------+-------------------------------------+ +| USB | on-chip | USB full-speed host/device bus | ++-----------+------------+-------------------------------------+ +| SDMMC | on-chip | disk access | ++-----------+------------+-------------------------------------+ + +Other hardware features have not been enabled yet for this board. + +The default configuration per core can be found in the defconfig file: +:zephyr_file:`boards/weact/stm32h5_core/weact_stm32h5_core_defconfig` + +Pin Mapping +=========== + +Default Zephyr Peripheral Mapping: +---------------------------------- + +The ``weact_stm32h5_core`` board is configured as follows + +- USER_LED : PB2 +- USER_PB : PC13 +- SDMMC1 CLK/DCMD/CD/D0/D1/D2/D3 : PC12/PD2/PD4/PC8/PC9/PC10/PC11 (microSD card) +- USB DM/DP : PA11/PA12 (USB CDC ACM) +- UART on debug header : RX/TX - pA10/PA9 + +System Clock +============ + +The STM32H562RG System Clock can be driven by an internal or external oscillator, +as well as by the main PLL clock. By default, the System clock is driven +by the PLL clock at 240MHz. PLL clock is fed by a 8MHz external clock. + +Serial Port (USB CDC ACM) +========================= + +The Zephyr console output is assigned to the USB CDC ACM virtual serial port. +Virtual COM port interface. Default communication settings are 115200 8N1. + +Programming and Debugging +************************* + +The ``weact_stm32h5_core`` board facilitates firmware flashing via the USB DFU +bootloader. This method simplifies the process of updating images, although +it doesn't provide debugging capabilities. However, the board provides header +pins for the Serial Wire Debug (SWD) interface, which can be used to connect +an external debugger, such as ST-Link. + +Flashing +======== + +To activate the bootloader, follow these steps: + +1. Press and hold the BOOT0 key. +2. While still holding the BOOT0 key, press and release the RESET key. +3. Wait for 0.5 seconds, then release the BOOT0 key. + +Upon successful execution of these steps, the device will transition into +bootloader mode and present itself as a USB DFU Mode device. You can program +the device using the west tool or the STM32CubeProgrammer. + +Flashing an application to ``weact_stm32h5_core`` +------------------------------------------------- + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +First, put the board in bootloader mode as described above. Then build and flash +the application in the usual way. Just add ``CONFIG_BOOT_DELAY=5000`` to the +configuration, so that USB CDC ACM is initialized before any text is printed, +as below: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: weact_stm32h5_core + :goals: build flash + :gen-args: -DCONFIG_BOOT_DELAY=5000 + +Run a serial host program to connect with your board: + +.. code-block:: console + + $ minicom -D -b 115200 + +Then, press the RESET button, you should see the following message after few seconds: + +.. code-block:: console + + Hello World! weact_stm32h5_core + +Replace :code:`` with the port where the board can be found. +For example, under Linux, :code:`/dev/ttyACM0`. + +Debugging +--------- + +This current Zephyr port does not support debugging. + +Testing the LEDs in the ``weact_stm32h5_core`` +********************************************** + +There is a sample that allows to test that LED on the board are working +properly with Zephyr: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: weact_stm32h5_core + :goals: build flash + :gen-args: -DCONFIG_BOOT_DELAY=5000 + +You can build and flash the examples to make sure Zephyr is running correctly on +your board. The LED definitions can be found in +:zephyr_file:`boards/weact/stm32h5_core/weact_stm32h5_core.dts`. + +Testing shell over USB in the ``weact_stm32h5_core`` +**************************************************** + +There is a sample that allows to test shell interface over USB CDC ACM interface +with Zephyr: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/shell/shell_module + :board: weact_stm32h5_core + :goals: build flash + :gen-args: -DCONFIG_BOOT_DELAY=5000 + +.. _WeAct GitHub: + https://github.com/WeActStudio/WeActStudio.STM32H5_64Pin_CoreBoard + +.. _STM32H562RG on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32h562rg.html + +.. _STM32H562 reference manual: + https://www.st.com/resource/en/reference_manual/rm0481-stm32h52333xx-stm32h56263xx-and-stm32h573xx-armbased-32bit-mcus-stmicroelectronics.pdf diff --git a/boards/weact/stm32h5_core/weact_stm32h5_core.dts b/boards/weact/stm32h5_core/weact_stm32h5_core.dts new file mode 100644 index 0000000000000..1d39eea4c2018 --- /dev/null +++ b/boards/weact/stm32h5_core/weact_stm32h5_core.dts @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2025 Kacper Brzostowski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "WeAct Studio STM32H5 Core Board"; + compatible = "weact,stm32h5-core"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,code-partition = &slot0_partition; + zephyr,sram = &sram1; + zephyr,flash = &flash0; + }; + + aliases { + led0 = &led_0; + sw0 = &button_0; + watchdog0 = &iwdg; + }; + + leds { + compatible = "gpio-leds"; + + led_0: led0 { + gpios = <&gpiob 2 GPIO_ACTIVE_HIGH>; + label = "User LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + button_0: button0 { + label = "User Button"; + gpios = <&gpioc 13 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + zephyr,code = ; + }; + }; +}; + +&sdmmc1 { + pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9 + &sdmmc1_d2_pc10 &sdmmc1_d3_pc11 + &sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>; + cd-gpios = <&gpioa 8 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + cd-gpios = <&gpioa 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + status = "okay"; +}; + +&clk_lsi { + status = "okay"; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&clk_hse { + status = "okay"; + clock-frequency = ; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + ahb-prescaler = <1>; + apb1-prescaler = <2>; + apb2-prescaler = <1>; + apb3-prescaler = <2>; +}; + +&pll { + div-m = <2>; + mul-n = <120>; + div-p = <2>; + div-q = <3>; + div-r = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB3 0x00200000>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + +stm32_lp_tick_source: &lptim4 { + clocks = <&rcc STM32_CLOCK_BUS_APB3 0x2000>, + <&rcc STM32_SRC_LSI LPTIM4_SEL(4)>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&usart1 { + status = "okay"; + pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; + pinctrl-names = "default"; + current-speed = <115200>; +}; + +&rng { + status = "okay"; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + cs-gpios = <&gpioa 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + status = "okay"; +}; + +&fdcan1 { + pinctrl-0 = <&fdcan1_rx_pb8 &fdcan1_tx_pb7>; + pinctrl-names = "default"; + clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>, + <&rcc STM32_SRC_PLL1_Q FDCAN_SEL(1)>; + clk-divider = <2>; + status = "okay"; +}; + +zephyr_udc0: &usb { + pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; + pinctrl-names = "default"; + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(448)>; + }; + + slot1_partition: partition@80000 { + label = "image-1"; + reg = <0x00080000 DT_SIZE_K(448)>; + }; + + storage_partition: partition@f0000 { + label = "storage"; + reg = <0x000f0000 DT_SIZE_K(64)>; + }; + }; +}; diff --git a/boards/weact/stm32h5_core/weact_stm32h5_core.yaml b/boards/weact/stm32h5_core/weact_stm32h5_core.yaml new file mode 100644 index 0000000000000..942b2f55025bb --- /dev/null +++ b/boards/weact/stm32h5_core/weact_stm32h5_core.yaml @@ -0,0 +1,20 @@ +identifier: weact_stm32h5_core +name: WeAct Studio STM32H5 Core Board +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 640 +flash: 1024 +supported: + - gpio + - can + - uart + - entropy + - spi + - usb_device + - rtc + - watchdog +vendor: weact diff --git a/boards/weact/stm32h5_core/weact_stm32h5_core_defconfig b/boards/weact/stm32h5_core/weact_stm32h5_core_defconfig new file mode 100644 index 0000000000000..4b8a61df364a4 --- /dev/null +++ b/boards/weact/stm32h5_core/weact_stm32h5_core_defconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Kacper Brzostowski +# SPDX-License-Identifier: Apache-2.0 + +# Enable uart driver +CONFIG_SERIAL=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Enable GPIO +CONFIG_GPIO=y diff --git a/boards/weact/usb2canfdv1/usb2canfdv1.yaml b/boards/weact/usb2canfdv1/usb2canfdv1.yaml index 8fb61f88e14cf..34d66235b1439 100644 --- a/boards/weact/usb2canfdv1/usb2canfdv1.yaml +++ b/boards/weact/usb2canfdv1/usb2canfdv1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 144 flash: 128 supported: diff --git a/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini.dts b/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini.dts index 66761886e55de..058cce83a2b22 100644 --- a/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini.dts +++ b/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini.dts @@ -22,7 +22,7 @@ }; chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,flash = &flash0; diff --git a/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini.yaml b/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini.yaml index 763b8c838f492..fcc4d03a44f9c 100644 --- a/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini.yaml +++ b/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini.yaml @@ -10,6 +10,5 @@ supported: - uart testing: ignore_tags: - - net - bluetooth vendor: wemos diff --git a/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini_defconfig b/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini_defconfig index f029cac9e9e77..e192c240251c1 100644 --- a/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini_defconfig +++ b/boards/wemos/esp32s2_lolin_mini/esp32s2_lolin_mini_defconfig @@ -1,7 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_CONSOLE=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y diff --git a/boards/witte/linum/linum.dts b/boards/witte/linum/linum.dts index d4846f3e1c7d7..fe2280ec11726 100644 --- a/boards/witte/linum/linum.dts +++ b/boards/witte/linum/linum.dts @@ -203,7 +203,7 @@ zephyr_udc0: &usbotg_fs { &adc1 { pinctrl-0 = <&adc1_inp15_pa3>; pinctrl-names = "default"; - st,adc-clock-source = ; + st,adc-clock-source = "SYNC"; st,adc-prescaler = <4>; status = "okay"; }; diff --git a/boards/witte/linum/linum.yaml b/boards/witte/linum/linum.yaml index 3242d570583ac..6b2e6b1b1c79b 100644 --- a/boards/witte/linum/linum.yaml +++ b/boards/witte/linum/linum.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 512 flash: 2048 supported: diff --git a/boards/wiznet/w5500_evb_pico/w5500_evb_pico.yaml b/boards/wiznet/w5500_evb_pico/w5500_evb_pico.yaml index 85246c0ef1ddf..aaa9c3637efba 100644 --- a/boards/wiznet/w5500_evb_pico/w5500_evb_pico.yaml +++ b/boards/wiznet/w5500_evb_pico/w5500_evb_pico.yaml @@ -7,7 +7,6 @@ ram: 264 toolchain: - zephyr - gnuarmemb - - xtools supported: - uart - gpio diff --git a/boards/xen/xenvm/Kconfig.defconfig b/boards/xen/xenvm/Kconfig.defconfig index 965dc9cda33bd..66ef1066e4c63 100644 --- a/boards/xen/xenvm/Kconfig.defconfig +++ b/boards/xen/xenvm/Kconfig.defconfig @@ -7,6 +7,6 @@ config BUILD_OUTPUT_BIN default y config HEAP_MEM_POOL_SIZE - default 16384 if BOARD_XENVM_XENVM + default 16384 endif # BOARD_XENVM diff --git a/boards/xen/xenvm/xenvm_xenvm_gicv3_defconfig b/boards/xen/xenvm/xenvm_xenvm_gicv3_defconfig new file mode 100644 index 0000000000000..2115f9175bd2a --- /dev/null +++ b/boards/xen/xenvm/xenvm_xenvm_gicv3_defconfig @@ -0,0 +1,13 @@ +# Enable UART driver +CONFIG_SERIAL=y + +CONFIG_MAX_XLAT_TABLES=24 + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable logging subsys +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=n +CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME=y diff --git a/cmake/bintools/bintools_template.cmake b/cmake/bintools/bintools_template.cmake index 6fa63080dd921..6617fd7780800 100644 --- a/cmake/bintools/bintools_template.cmake +++ b/cmake/bintools/bintools_template.cmake @@ -66,6 +66,7 @@ # elfconvert_flag_final : Flags that must always be applied last at the elfconvert command # elfconvert_flag_strip_all : Flag that is used for stripping all symbols when converting # elfconvert_flag_strip_debug : Flag that is used to strip debug symbols when converting +# elfconvert_flag_strip_unneeded: Flag that is used to strip all unreferenced symbols when converting # elfconvert_flag_compress_debug_sections: Flag that is used to compress debug sections when converting # elfconvert_flag_intarget : Flag for specifying target used for infile # elfconvert_flag_outtarget : Flag for specifying target to use for converted file. @@ -142,6 +143,8 @@ set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_COMMAND} -E ech set_property(TARGET bintools PROPERTY elfconvert_formats "") set_property(TARGET bintools PROPERTY elfconvert_flag "") set_property(TARGET bintools PROPERTY elfconvert_flag_final "") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_unneeded "") set_property(TARGET bintools PROPERTY elfconvert_flag_compress_debug_sections "") set_property(TARGET bintools PROPERTY elfconvert_flag_outtarget "") set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "") diff --git a/cmake/bintools/gnu/target_bintools.cmake b/cmake/bintools/gnu/target_bintools.cmake index 0fa06ea7c32f0..6bbe8f8a3cf05 100644 --- a/cmake/bintools/gnu/target_bintools.cmake +++ b/cmake/bintools/gnu/target_bintools.cmake @@ -7,6 +7,7 @@ # elfconvert_flag_final : empty # elfconvert_flag_strip_all : -S # elfconvert_flag_strip_debug : -g +# elfconvert_flag_strip_unneeded: --strip-unneeded # elfconvert_flag_compress_debug_sections: --compress-debug-sections # elfconvert_flag_intarget : --input-target= # elfconvert_flag_outtarget : --output-target= @@ -34,6 +35,7 @@ set_property(TARGET bintools PROPERTY elfconvert_flag_final "") set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-S") set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "-g") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_unneeded "--strip-unneeded") set_property(TARGET bintools PROPERTY elfconvert_flag_compress_debug_sections "--compress-debug-sections") diff --git a/cmake/bintools/iar/target.cmake b/cmake/bintools/iar/target.cmake new file mode 100644 index 0000000000000..0ea594503cc36 --- /dev/null +++ b/cmake/bintools/iar/target.cmake @@ -0,0 +1,44 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +# Configures binary tools as GNU binutils +include(extensions) + +# Specifically choose arm-zephyr-eabi from the zephyr sdk for objcopy and friends + +if("${IAR_TOOLCHAIN_VARIANT}" STREQUAL "iccarm") + set(IAR_ZEPHYR_HOME ${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin) + set(IAR_GNU_PREFIX arm-zephyr-eabi-) +else() + message(ERROR "IAR_TOOLCHAIN_VARIANT not set") +endif() +find_program(CMAKE_OBJCOPY ${IAR_GNU_PREFIX}objcopy PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_OBJDUMP ${IAR_GNU_PREFIX}objdump PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_AS ${IAR_GNU_PREFIX}as PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_AR ${IAR_GNU_PREFIX}ar PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_RANLIB ${IAR_GNU_PREFIX}ranlib PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_READELF ${IAR_GNU_PREFIX}readelf PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_NM ${IAR_GNU_PREFIX}nm PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_STRIP ${IAR_GNU_PREFIX}strip PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_GDB ${IAR_GNU_PREFIX}gdb-py PATHS ${IAR_ZEPHYR_HOME} NO_DEFAULT_PATH) + +if(CMAKE_GDB) + execute_process( + COMMAND ${CMAKE_GDB} --configuration + RESULTS_VARIABLE GDB_CFG_ERR + OUTPUT_QUIET + ERROR_QUIET + ) +endif() + +if(NOT CMAKE_GDB OR GDB_CFG_ERR) + find_program(CMAKE_GDB_NO_PY ${CROSS_COMPILE}gdb PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + + if(CMAKE_GDB_NO_PY) + set(CMAKE_GDB ${CMAKE_GDB_NO_PY} CACHE FILEPATH "Path to a program." FORCE) + endif() +endif() + +# Include bin tool properties +include(${ZEPHYR_BASE}/cmake/bintools/iar/target_bintools.cmake) diff --git a/cmake/bintools/iar/target_bintools.cmake b/cmake/bintools/iar/target_bintools.cmake new file mode 100644 index 0000000000000..087bd518df136 --- /dev/null +++ b/cmake/bintools/iar/target_bintools.cmake @@ -0,0 +1,135 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 +# +# - elfconvert : Name of command for elf file conversion. +# In this implementation `objcopy` is used +# elfconvert_formats : Formats supported: ihex, srec, binary +# elfconvert_flag : empty +# elfconvert_flag_final : empty +# elfconvert_flag_strip_all : -S +# elfconvert_flag_strip_debug : -g +# elfconvert_flag_intarget : --input-target= +# elfconvert_flag_outtarget : --output-target= +# elfconvert_flag_section_remove: --remove-section= +# elfconvert_flag_section_only : --only-section= +# elfconvert_flag_section_rename: --rename-section; +# elfconvert_flag_gapfill : --gap-fill; +# Note: The ';' will be transformed into an +# empty space when executed +# elfconvert_flag_srec_len : --srec-len= +# elfconvert_flag_infile : empty, objcopy doesn't take arguments for filenames +# elfconvert_flag_outfile : empty, objcopy doesn't take arguments for filenames +# + +# elfconvert to use for transforming an elf file into another format, +# such as intel hex, s-rec, binary, etc. +set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_OBJCOPY}) + +# List of format the tool supports for converting, for example, +# GNU tools uses objectcopy, which supports the following: ihex, srec, binary +set_property(TARGET bintools PROPERTY elfconvert_formats ihex srec binary) + +set_property(TARGET bintools PROPERTY elfconvert_flag "") +set_property(TARGET bintools PROPERTY elfconvert_flag_final "") + +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-S") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "-g") + +set_property(TARGET bintools PROPERTY elfconvert_flag_intarget "--input-target=") +set_property(TARGET bintools PROPERTY elfconvert_flag_outtarget "--output-target=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "--remove-section=") +set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "--only-section=") +set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "--rename-section;") + +set_property(TARGET bintools PROPERTY elfconvert_flag_lma_adjust "--change-section-lma;") + +# Note, placing a ';' at the end results in the following param to be a list, +# and hence space separated. +# Thus the command line argument becomes: +# `--gap-file ` instead of `--gap-fill` (The latter would result in an error) +set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "--gap-fill;") +set_property(TARGET bintools PROPERTY elfconvert_flag_srec_len "--srec-len=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_infile "") +set_property(TARGET bintools PROPERTY elfconvert_flag_outfile "") + +# +# - disassembly : Name of command for disassembly of files +# In this implementation `objdump` is used +# disassembly_flag : -d +# disassembly_flag_final : empty +# disassembly_flag_inline_source : -S +# disassembly_flag_all : -SDz +# disassembly_flag_infile : empty, objdump doesn't take arguments for filenames +# disassembly_flag_outfile : '>', objdump doesn't take arguments for output file, but result is printed to standard out, and is redirected. + +set_property(TARGET bintools PROPERTY disassembly_command ${CMAKE_OBJDUMP}) +set_property(TARGET bintools PROPERTY disassembly_flag -d) +set_property(TARGET bintools PROPERTY disassembly_flag_final "") +set_property(TARGET bintools PROPERTY disassembly_flag_inline_source -S) +set_property(TARGET bintools PROPERTY disassembly_flag_all -SDz) + +set_property(TARGET bintools PROPERTY disassembly_flag_infile "") +set_property(TARGET bintools PROPERTY disassembly_flag_outfile ">;" ) + +# +# - strip: Name of command for stripping symbols +# In this implementation `strip` is used +# strip_flag : empty +# strip_flag_final : empty +# strip_flag_all : --strip-all +# strip_flag_debug : --strip-debug +# strip_flag_dwo : --strip-dwo +# strip_flag_infile : empty, strip doesn't take arguments for input file +# strip_flag_outfile : -o + +# This is using strip from bintools. +set_property(TARGET bintools PROPERTY strip_command ${CMAKE_STRIP}) + +# Any flag the strip command requires for processing +set_property(TARGET bintools PROPERTY strip_flag "") +set_property(TARGET bintools PROPERTY strip_flag_final "") + +set_property(TARGET bintools PROPERTY strip_flag_all --strip-all) +set_property(TARGET bintools PROPERTY strip_flag_debug --strip-debug) +set_property(TARGET bintools PROPERTY strip_flag_dwo --strip-dwo) +set_property(TARGET bintools PROPERTY strip_flag_remove_section -R ) + +set_property(TARGET bintools PROPERTY strip_flag_infile "") +set_property(TARGET bintools PROPERTY strip_flag_outfile -o ) + +# +# - readelf : Name of command for reading elf files. +# In this implementation `readelf` is used +# readelf_flag : empty +# readelf_flag_final : empty +# readelf_flag_headers : -e +# readelf_flag_infile : empty, readelf doesn't take arguments for filenames +# readelf_flag_outfile : '>', readelf doesn't take arguments for output +# file, but result is printed to standard out, and +# is redirected. + +# This is using readelf from bintools. +set_property(TARGET bintools PROPERTY readelf_command ${CMAKE_READELF}) + +set_property(TARGET bintools PROPERTY readelf_flag "") +set_property(TARGET bintools PROPERTY readelf_flag_final "") +set_property(TARGET bintools PROPERTY readelf_flag_headers -e) + +set_property(TARGET bintools PROPERTY readelf_flag_infile "") +set_property(TARGET bintools PROPERTY readelf_flag_outfile ">;" ) + +# Example on how to support dwarfdump instead of readelf +#set_property(TARGET bintools PROPERTY readelf_command dwarfdump) +#set_property(TARGET bintools PROPERTY readelf_flag "") +#set_property(TARGET bintools PROPERTY readelf_flag_headers -E) +#set_property(TARGET bintools PROPERTY readelf_flag_infile "") +#set_property(TARGET bintools PROPERTY readelf_flag_outfile "-O file=" ) + +set_property(TARGET bintools PROPERTY symbols_command ${CMAKE_NM}) +set_property(TARGET bintools PROPERTY symbols_flag "") +set_property(TARGET bintools PROPERTY symbols_final "") +set_property(TARGET bintools PROPERTY symbols_infile "") +set_property(TARGET bintools PROPERTY symbols_outfile ">;" ) diff --git a/cmake/bintools/llvm/target_bintools.cmake b/cmake/bintools/llvm/target_bintools.cmake index f310d57bf2b2b..9d8edc46de96d 100644 --- a/cmake/bintools/llvm/target_bintools.cmake +++ b/cmake/bintools/llvm/target_bintools.cmake @@ -7,6 +7,7 @@ # elfconvert_flag_final : empty # elfconvert_flag_strip_all : -S # elfconvert_flag_strip_debug : -g +# elfconvert_flag_strip_unneeded: --strip-unneeded # elfconvert_flag_compress_debug_sections: --compress-debug-sections # elfconvert_flag_intarget : --input-target= # elfconvert_flag_outtarget : --output-target= @@ -34,6 +35,7 @@ set_property(TARGET bintools PROPERTY elfconvert_flag_final "") set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-S") set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "-g") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_unneeded "--strip-unneeded") set_property(TARGET bintools PROPERTY elfconvert_flag_compress_debug_sections "--compress-debug-sections") @@ -44,6 +46,8 @@ set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "--remove-s set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "--only-section=") set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "--rename-section;") +set_property(TARGET bintools PROPERTY elfconvert_flag_lma_adjust "--change-section-lma;") + # llvm-objcopy doesn't support gap fill argument. set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "") set_property(TARGET bintools PROPERTY elfconvert_flag_srec_len "--srec-len=") diff --git a/cmake/compiler/arcmwdt/compiler_flags.cmake b/cmake/compiler/arcmwdt/compiler_flags.cmake index 6b334c1fe84da..7234afc0c8030 100644 --- a/cmake/compiler/arcmwdt/compiler_flags.cmake +++ b/cmake/compiler/arcmwdt/compiler_flags.cmake @@ -167,7 +167,9 @@ set_compiler_property(PROPERTY imacros -imacros) # Security canaries. #no support of -mstack-protector-guard=global" -set_compiler_property(PROPERTY security_canaries -fstack-protector-all) +set_compiler_property(PROPERTY security_canaries -fstack-protector) +set_compiler_property(PROPERTY security_canaries_strong -fstack-protector-strong) +set_compiler_property(PROPERTY security_canaries_all -fstack-protector-all) #no support of _FORTIFY_SOURCE" set_compiler_property(PROPERTY security_fortify_compile_time) diff --git a/cmake/compiler/clang/compiler_flags.cmake b/cmake/compiler/clang/compiler_flags.cmake index a64150eb58c61..8715150e5a6f3 100644 --- a/cmake/compiler/clang/compiler_flags.cmake +++ b/cmake/compiler/clang/compiler_flags.cmake @@ -102,19 +102,13 @@ check_set_compiler_property(APPEND PROPERTY warning_dw_3 check_set_compiler_property(PROPERTY warning_extended #FIXME: need to fix all of those -Wno-sometimes-uninitialized - -Wno-shift-overflow - -Wno-missing-braces -Wno-self-assign -Wno-address-of-packed-member -Wno-unused-function -Wno-initializer-overrides -Wno-section - -Wno-unknown-warning-option -Wno-unused-variable - -Wno-format-invalid-specifier -Wno-gnu - # comparison of unsigned expression < 0 is always false - -Wno-tautological-compare ) set_compiler_property(PROPERTY warning_error_coding_guideline diff --git a/cmake/compiler/compiler_flags_template.cmake b/cmake/compiler/compiler_flags_template.cmake index 5a4386f49beb7..bea8027bb0f43 100644 --- a/cmake/compiler/compiler_flags_template.cmake +++ b/cmake/compiler/compiler_flags_template.cmake @@ -92,6 +92,9 @@ set_compiler_property(PROPERTY coverage) # Security canaries flags. set_compiler_property(PROPERTY security_canaries) +set_compiler_property(PROPERTY security_canaries_strong) +set_compiler_property(PROPERTY security_canaries_all) +set_compiler_property(PROPERTY security_canaries_explicit) set_compiler_property(PROPERTY security_fortify_compile_time) set_compiler_property(PROPERTY security_fortify_run_time) @@ -122,6 +125,9 @@ set_property(TARGET compiler-cpp PROPERTY no_threadsafe_statics) # Required ASM flags when compiling set_property(TARGET asm PROPERTY required) +# GCC compiler flags for imacros. The specific header must be appended by user. +set_property(TARGET asm PROPERTY imacros) + # Compiler flag for disabling pointer arithmetic warnings set_compiler_property(PROPERTY warning_no_pointer_arithmetic) @@ -143,3 +149,11 @@ set_compiler_property(PROPERTY no_builtin_malloc) # Compiler flag for defining specs. Used only by gcc, other compilers may keep # this undefined. set_compiler_property(PROPERTY specs) + +# Compiler flag for defining preinclude files. +set_compiler_property(PROPERTY include_file) + +# Compiler flag for trustzone +set_compiler_property(PROPERTY cmse) + +set_property(TARGET asm PROPERTY cmse) diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake index 5d348a2aacc2d..3ff29a4b30cfe 100644 --- a/cmake/compiler/gcc/compiler_flags.cmake +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -121,7 +121,7 @@ if (NOT CONFIG_NEWLIB_LIBC AND set_compiler_property(APPEND PROPERTY nostdinc_include ${NOSTDINC}) endif() -set_compiler_property(PROPERTY no_printf_return_value -fno-printf-return-value) +check_set_compiler_property(PROPERTY no_printf_return_value -fno-printf-return-value) set_property(TARGET compiler-cpp PROPERTY nostdincxx "-nostdinc++") @@ -167,13 +167,22 @@ set_property(TARGET compiler-cpp PROPERTY no_rtti "-fno-rtti") set_compiler_property(PROPERTY coverage -fprofile-arcs -ftest-coverage -fno-inline) # Security canaries. -set_compiler_property(PROPERTY security_canaries -fstack-protector-all) +set_compiler_property(PROPERTY security_canaries -fstack-protector) +set_compiler_property(PROPERTY security_canaries_strong -fstack-protector-strong) +set_compiler_property(PROPERTY security_canaries_all -fstack-protector-all) +set_compiler_property(PROPERTY security_canaries_explicit -fstack-protector-explicit) # Only a valid option with GCC 7.x and above, so let's do check and set. if(CONFIG_STACK_CANARIES_TLS) check_set_compiler_property(APPEND PROPERTY security_canaries -mstack-protector-guard=tls) + check_set_compiler_property(APPEND PROPERTY security_canaries_strong -mstack-protector-guard=tls) + check_set_compiler_property(APPEND PROPERTY security_canaries_all -mstack-protector-guard=tls) + check_set_compiler_property(APPEND PROPERTY security_canaries_explicit -mstack-protector-guard=tls) else() check_set_compiler_property(APPEND PROPERTY security_canaries -mstack-protector-guard=global) + check_set_compiler_property(APPEND PROPERTY security_canaries_global -mstack-protector-guard=global) + check_set_compiler_property(APPEND PROPERTY security_canaries_all -mstack-protector-guard=global) + check_set_compiler_property(APPEND PROPERTY security_canaries_explicit -mstack-protector-guard=global) endif() @@ -222,10 +231,11 @@ set_property(TARGET compiler-cpp PROPERTY no_threadsafe_statics "-fno-threadsafe # Required ASM flags when using gcc set_property(TARGET asm PROPERTY required "-xassembler-with-cpp") +# GCC compiler flags for imacros. The specific header must be appended by user. +set_property(TARGET asm PROPERTY imacros "-imacros") + # gcc flag for colourful diagnostic messages -if (NOT COMPILER STREQUAL "xcc") -set_compiler_property(PROPERTY diagnostic -fdiagnostics-color=always) -endif() +check_set_compiler_property(PROPERTY diagnostic -fdiagnostics-color=always) # Compiler flag for disabling pointer arithmetic warnings set_compiler_property(PROPERTY warning_no_pointer_arithmetic "-Wno-pointer-arith") @@ -244,3 +254,9 @@ set_compiler_property(PROPERTY no_builtin -fno-builtin) set_compiler_property(PROPERTY no_builtin_malloc -fno-builtin-malloc) set_compiler_property(PROPERTY specs -specs=) + +set_compiler_property(PROPERTY include_file -include) + +set_compiler_property(PROPERTY cmse -mcmse) + +set_property(TARGET asm PROPERTY cmse -mcmse) diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake index 7e8ffc4817337..f2f6a96e369bf 100644 --- a/cmake/compiler/gcc/target.cmake +++ b/cmake/compiler/gcc/target.cmake @@ -42,7 +42,8 @@ execute_process( OUTPUT_VARIABLE temp_compiler_version ) -if("${temp_compiler_version}" VERSION_GREATER_EQUAL 13.1.0) +if("${temp_compiler_version}" VERSION_LESS 4.3.0 OR + "${temp_compiler_version}" VERSION_GREATER_EQUAL 13.1.0) set(fix_header_file include/limits.h) else() set(fix_header_file include-fixed/limits.h) diff --git a/cmake/compiler/gcc/target_arc.cmake b/cmake/compiler/gcc/target_arc.cmake index d306fe1550f10..7d580e81e8f75 100644 --- a/cmake/compiler/gcc/target_arc.cmake +++ b/cmake/compiler/gcc/target_arc.cmake @@ -15,9 +15,12 @@ set(LLEXT_REMOVE_FLAGS -fno-pie -ffunction-sections -fdata-sections - -g.* -Os ) +set(LLEXT_APPEND_FLAGS + -mcpu=${GCC_ARC_TUNED_CPU} # Force compiler and linker match +) + list(APPEND TOOLCHAIN_C_FLAGS -mcpu=${GCC_ARC_TUNED_CPU}) list(APPEND TOOLCHAIN_LD_FLAGS -mcpu=${GCC_ARC_TUNED_CPU}) diff --git a/cmake/compiler/gcc/target_arm.cmake b/cmake/compiler/gcc/target_arm.cmake index 72b6cc036010d..7d46a4e9572fc 100644 --- a/cmake/compiler/gcc/target_arm.cmake +++ b/cmake/compiler/gcc/target_arm.cmake @@ -54,7 +54,6 @@ set(LLEXT_REMOVE_FLAGS -fno-pie -ffunction-sections -fdata-sections - -g.* -Os ) @@ -67,8 +66,9 @@ set(LLEXT_APPEND_FLAGS list(APPEND LLEXT_EDK_REMOVE_FLAGS --sysroot=.* -fmacro-prefix-map=.* - ) + -g.* +) list(APPEND LLEXT_EDK_APPEND_FLAGS -nodefaultlibs - ) +) diff --git a/cmake/compiler/gcc/target_arm64.cmake b/cmake/compiler/gcc/target_arm64.cmake index 2674cac50cc8e..2bc16e61bc1f0 100644 --- a/cmake/compiler/gcc/target_arm64.cmake +++ b/cmake/compiler/gcc/target_arm64.cmake @@ -22,13 +22,13 @@ set(LLEXT_REMOVE_FLAGS -fno-pie -ffunction-sections -fdata-sections - -g.* -Os ) list(APPEND LLEXT_EDK_REMOVE_FLAGS --sysroot=.* -fmacro-prefix-map=.* + -g.* ) list(APPEND LLEXT_EDK_APPEND_FLAGS diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index a297a772886c2..74d12d04c7975 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -53,6 +53,18 @@ if(CONFIG_RISCV_ISA_EXT_ZIFENCEI) string(CONCAT riscv_march ${riscv_march} "_zifencei") endif() +# Check whether we already imply Zaamo/Zlrsc by selecting the A extension; if not - check them +# individually and enable them as needed +if(NOT CONFIG_RISCV_ISA_EXT_A) + if(CONFIG_RISCV_ISA_EXT_ZAAMO) + string(CONCAT riscv_march ${riscv_march} "_zaamo") + endif() + + if(CONFIG_RISCV_ISA_EXT_ZLRSC) + string(CONCAT riscv_march ${riscv_march} "_zlrsc") + endif() +endif() + if(CONFIG_RISCV_ISA_EXT_ZBA) string(CONCAT riscv_march ${riscv_march} "_zba") endif() @@ -90,4 +102,4 @@ set(LLEXT_APPEND_FLAGS -mabi=${riscv_mabi} -march=${riscv_march} -mno-relax -) \ No newline at end of file +) diff --git a/cmake/compiler/gcc/target_xtensa.cmake b/cmake/compiler/gcc/target_xtensa.cmake index 0b398023f67bd..abe0c7be703cc 100644 --- a/cmake/compiler/gcc/target_xtensa.cmake +++ b/cmake/compiler/gcc/target_xtensa.cmake @@ -5,7 +5,6 @@ set(LLEXT_REMOVE_FLAGS -ffunction-sections -fdata-sections - -g.* -Os -mcpu=.* ) diff --git a/cmake/compiler/iar/compiler_flags.cmake b/cmake/compiler/iar/compiler_flags.cmake new file mode 100644 index 0000000000000..49cd7bfd33ea2 --- /dev/null +++ b/cmake/compiler/iar/compiler_flags.cmake @@ -0,0 +1,178 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +# Compiler options for the IAR C/C++ Compiler for Arm + +##################################################### +# This section covers flags related to optimization # +##################################################### +set_compiler_property(PROPERTY no_optimization -On) + +set_compiler_property(PROPERTY optimization_debug -Ol) + +set_compiler_property(PROPERTY optimization_speed -Ohs) + +set_compiler_property(PROPERTY optimization_size -Ohz) + +set_compiler_property(PROPERTY optimization_size_aggressive -Ohz) + +####################################################### +# This section covers flags related to warning levels # +####################################################### + +# Property for standard warning base in Zephyr, this will always be set when +# compiling. +set_compiler_property(PROPERTY warning_base + --diag_error=Pe223 # function "xxx" declared implicitly + --diag_warning=Pe054 # too few arguments in invocation of macro + --diag_warning=Pe144 # a value of type "void *" cannot be used to initialize an entity of type [...] "void (*)(struct onoff_manager *, int)" + --diag_warning=Pe167 # argument of type "void *" is incompatible with [...] "void (*)(void *, void *, void *)" + --diag_suppress=Pe1675 # unrecognized GCC pragma + --diag_suppress=Pe111 # statement is unreachable + --diag_suppress=Pe1143 # arithmetic on pointer to void or function type + --diag_suppress=Pe068) # integer conversion resulted in a change of sign) + + +set(IAR_WARNING_DW_1 + --diag_suppress=Pe188 # enumerated type mixed with another type + --diag_suppress=Pe128 # loop is not reachable + --diag_suppress=Pe550 # variable "res" was set but never used + --diag_suppress=Pe546 # transfer of control bypasses initialization + --diag_suppress=Pe186) # pointless comparison of unsigned integer with zero + +set(IAR_WARNING_DW2 + --diag_suppress=Pe1097 # unknown attribute + --diag_suppress=Pe381 # extra ";" ignored + --diag_suppress=Pa082 # undefined behavior: the order of volatile accesses is undefined + --diag_suppress=Pa084 # pointless integer comparison, the result is always false + --diag_suppress=Pe185 # dynamic initialization in unreachable code ) + --diag_suppress=Pe167 # argument of type "onoff_notify_fn" is incompatible with... + --diag_suppress=Pe144 # a value of type "void *" cannot be used to initialize... + --diag_suppress=Pe177 # function "xxx" was declared but never referenced + --diag_suppress=Pe513) # a value of type "void *" cannot be assigned to an entity of type "int (*)(int)" + +set(IAR_WARNING_DW3) + +set_compiler_property(PROPERTY warning_dw_1 + ${IAR_WARNING_DW_3} + ${IAR_WARNING_DW_2} + ${IAR_WARNING_DW_1}) + +set_compiler_property(PROPERTY warning_dw_2 + ${IAR_WARNING_DW3} + ${IAR_WARNING_DW2}) + +# no suppressions +set_compiler_property(PROPERTY warning_dw_3 ${IAR_WARNING_DW3}) + +# Extended warning set supported by the compiler +set_compiler_property(PROPERTY warning_extended) + +# Compiler property that will issue error if a declaration does not specify a type +set_compiler_property(PROPERTY warning_error_implicit_int) + +# Compiler flags to use when compiling according to MISRA +set_compiler_property(PROPERTY warning_error_misra_sane) + +set_property(TARGET compiler PROPERTY warnings_as_errors --warnings_are_errors) + +########################################################################### +# This section covers flags related to C or C++ standards / standard libs # +########################################################################### + +# Compiler flags for C standard. The specific standard must be appended by user. +# For example, gcc specifies this as: set_compiler_property(PROPERTY cstd -std=) +# TC-WG: the `cstd99` is used regardless of this flag being useful for iccarm +# This flag will make it a symbol. Works for C,CXX,ASM +# Since ICCARM does not use C standard flags, we just make them a defined symbol +# instead +set_compiler_property(PROPERTY cstd -D__IAR_CSTD_) + +# Compiler flags for disabling C standard include and instead specify include +# dirs in nostdinc_include to use. +set_compiler_property(PROPERTY nostdinc) +set_compiler_property(PROPERTY nostdinc_include) + +# Compiler flags for disabling C++ standard include. +set_compiler_property(TARGET compiler-cpp PROPERTY nostdincxx) + +# Required C++ flags when compiling C++ code +set_property(TARGET compiler-cpp PROPERTY required --c++) + +# Compiler flags to use for specific C++ dialects +set_property(TARGET compiler-cpp PROPERTY dialect_cpp98) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp11) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp14) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp17 --libc++) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp2a --libc++) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp20 --libc++) +set_property(TARGET compiler-cpp PROPERTY dialect_cpp2b --libc++) + +# Flag for disabling strict aliasing rule in C and C++ +set_compiler_property(PROPERTY no_strict_aliasing) + +# Flag for disabling exceptions in C++ +set_property(TARGET compiler-cpp PROPERTY no_exceptions --no_exceptions) + +# Flag for disabling rtti in C++ +set_property(TARGET compiler-cpp PROPERTY no_rtti --no_rtti) + +################################################### +# This section covers all remaining C / C++ flags # +################################################### + +# Flags for coverage generation +set_compiler_property(PROPERTY coverage) + +# Security canaries flags. +set_compiler_property(PROPERTY security_canaries --stack_protection) +set_compiler_property(PROPERTY security_canaries_strong --stack_protection) +set_compiler_property(PROPERTY security_canaries_all --security_canaries_all_is_not_supported) +set_compiler_property(PROPERTY security_canaries_explicit --security_canaries_explicit_is_not_supported) + +if(CONFIG_STACK_CANARIES_TLS) + check_set_compiler_property(APPEND PROPERTY security_canaries --stack_protector_guard=tls) + check_set_compiler_property(APPEND PROPERTY security_canaries_strong --stack_protector_guard=tls) + check_set_compiler_property(APPEND PROPERTY security_canaries_all --stack_protector_guard=tls) + check_set_compiler_property(APPEND PROPERTY security_canaries_explicit --stack_protector_guard=tls) +endif() + +set_compiler_property(PROPERTY security_fortify) + +# Flag for a hosted (no-freestanding) application +set_compiler_property(PROPERTY hosted) + +# gcc flag for a freestanding application +set_compiler_property(PROPERTY freestanding) + +# Flag to include debugging symbol in compilation +set_property(TARGET compiler PROPERTY debug --debug) +set_property(TARGET compiler-cpp PROPERTY debug --debug) +set_property(TARGET asm PROPERTY debug -gdwarf-4) + +set_compiler_property(PROPERTY no_common) + +# Flags for imacros. The specific header must be appended by user. +set_property(TARGET compiler PROPERTY imacros --preinclude) +set_property(TARGET compiler-cpp PROPERTY imacros --preinclude) +set_property(TARGET asm PROPERTY imacros -imacros) + +# Compiler flag for turning off thread-safe initialization of local statics +set_property(TARGET compiler-cpp PROPERTY no_threadsafe_statics) + +# Required ASM flags when compiling +set_property(TARGET asm PROPERTY required) + +# Compiler flag for disabling pointer arithmetic warnings +set_compiler_property(PROPERTY warning_no_pointer_arithmetic) + +# Compiler flags for disabling position independent code / executable +set_compiler_property(PROPERTY no_position_independent) + +# Compiler flag for defining preinclude files. +set_compiler_property(PROPERTY include_file --preinclude) + +set_compiler_property(PROPERTY cmse --cmse) + +set_property(TARGET asm PROPERTY cmse -mcmse) diff --git a/cmake/compiler/iar/generic.cmake b/cmake/compiler/iar/generic.cmake new file mode 100644 index 0000000000000..5d46412770d77 --- /dev/null +++ b/cmake/compiler/iar/generic.cmake @@ -0,0 +1,15 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +if(NOT CMAKE_DTS_PREPROCESSOR) + find_program(CMAKE_DTS_PREPROCESSOR arm-zephyr-eabi-gcc PATHS ${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin NO_DEFAULT_PATH) +endif() + +if(NOT CMAKE_DTS_PREPROCESSOR) + message(FATAL_ERROR "Zephyr was unable to find \`arm-zephyr-eabi-gcc\` for DTS preprocessing") +endif() + +if(CMAKE_C_COMPILER STREQUAL CMAKE_C_COMPILER-NOTFOUND) + message(FATAL_ERROR "Zephyr was unable to find the IAR toolchain. Was the environment misconfigured?") +endif() diff --git a/cmake/compiler/iar/iccarm-cpu.cmake b/cmake/compiler/iar/iccarm-cpu.cmake new file mode 100644 index 0000000000000..70eee9240b654 --- /dev/null +++ b/cmake/compiler/iar/iccarm-cpu.cmake @@ -0,0 +1,89 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +# Determines what argument to give to --cpu= based on the +# KConfig'uration and sets this to ICCARM_CPU + +if("${ARCH}" STREQUAL "arm") + if(CONFIG_CPU_CORTEX_M0) + set(ICCARM_CPU Cortex-M0) + elseif(CONFIG_CPU_CORTEX_M0PLUS) + set(ICCARM_CPU Cortex-M0+) + elseif(CONFIG_CPU_CORTEX_M1) + set(ICCARM_CPU Cortex-M1) + elseif(CONFIG_CPU_CORTEX_M3) + set(ICCARM_CPU Cortex-M3) + elseif(CONFIG_CPU_CORTEX_M4) + set(ICCARM_CPU Cortex-M4) + elseif(CONFIG_CPU_CORTEX_M7) + set(ICCARM_CPU Cortex-M7) + elseif(CONFIG_CPU_CORTEX_M23) + set(ICCARM_CPU Cortex-M23) + elseif(CONFIG_CPU_CORTEX_M33) + if(CONFIG_ARMV8_M_DSP) + set(ICCARM_CPU Cortex-M33) + else() + set(ICCARM_CPU Cortex-M33.no_dsp) + endif() + elseif(CONFIG_CPU_CORTEX_M55) + if(CONFIG_ARMV8_1_M_MVEF) + set(ICCARM_CPU Cortex-M55) + elseif(CONFIG_ARMV8_1_M_MVEI) + set(ICCARM_CPU Cortex-M55.no_mve) + elseif(CONFIG_ARMV8_M_DSP) + set(ICCARM_CPU Cortex-M55.no_mve) + else() + set(ICCARM_CPU Cortex-M55.no_dsp) + endif() + elseif(CONFIG_CPU_CORTEX_R4) + if(CONFIG_FPU AND CONFIG_CPU_HAS_VFP) + set(ICCARM_CPU Cortex-R4F) + else() + set(ICCARM_CPU Cortex-R4) + endif() + elseif(CONFIG_CPU_CORTEX_R5) + set(ICCARM_CPU Cortex-R5) + if(CONFIG_FPU AND CONFIG_CPU_HAS_VFP) + if(NOT CONFIG_VFP_FEATURE_DOUBLE_PRECISION) + set(ICCARM_CPU ${ICCARM_CPU}+fp.sp) + endif() + else() + set(ICCARM_CPU ${ICCARM_CPU}+fp.dp) + endif() + elseif(CONFIG_CPU_CORTEX_R7) + set(ICCARM_CPU Cortex-R7) + if(CONFIG_FPU AND CONFIG_CPU_HAS_VFP) + if(NOT CONFIG_VFP_FEATURE_DOUBLE_PRECISION) + set(ICCARM_CPU ${ICCARM_CPU}+fp.sp) + endif() + else() + set(ICCARM_CPU ${ICCARM_CPU}+fp.dp) + endif() + elseif(CONFIG_CPU_CORTEX_R52) + set(ICCARM_CPU Cortex-R52) + if(CONFIG_FPU AND CONFIG_CPU_HAS_VFP) + if(NOT CONFIG_VFP_FEATURE_DOUBLE_PRECISION) + set(ICCARM_CPU ${ICCARM_CPU}+fp.sp) + endif() + endif() + elseif(CONFIG_CPU_CORTEX_A9) + set(ICCARM_CPU Cortex-A9) + else() + message(FATAL_ERROR "Expected CONFIG_CPU_CORTEX_x to be defined") + endif() +elseif("${ARCH}" STREQUAL "arm64") + if(CONFIG_CPU_CORTEX_A53) + set(ICCARM_CPU Cortex-A53) + elseif(CONFIG_CPU_CORTEX_A55) + set(ICCARM_CPU Cortex-A55) + elseif(CONFIG_CPU_CORTEX_A76) + set(ICCARM_CPU cortex-a76) + elseif(CONFIG_CPU_CORTEX_A76_A55) + set(ICCARM_CPU cortex-a76) + elseif(CONFIG_CPU_CORTEX_A72) + set(ICCARM_CPU Cortex-A72) + elseif(CONFIG_CPU_CORTEX_R82) + set(ICCARM_CPU Cortex-R82) + endif() +endif() diff --git a/cmake/compiler/iar/iccarm-fpu.cmake b/cmake/compiler/iar/iccarm-fpu.cmake new file mode 100644 index 0000000000000..2435d77254bf8 --- /dev/null +++ b/cmake/compiler/iar/iccarm-fpu.cmake @@ -0,0 +1,53 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +# Determines what argument to give to --fpu= based on the +# KConfiguration and sets this to ICCARM_FPU + +if(CONFIG_FPU) + + # 32-bit + if("${ARCH}" STREQUAL "arm") + if(CONFIG_CPU_AARCH32_CORTEX_R) + if(CONFIG_CPU_CORTEX_R4 OR CONFIG_CPU_CORTEX_R5) # VFPv3 + if(CONFIG_VFP_FEATURE_DOUBLE_PRECISION) + set(ICCARM_FPU VFPv3_D16) + elseif(CONFIG_VFP_FEATURE_SINGLE_PRECISION) + set(ICCARM_FPU VFPv3-SP) + endif() + if(CONFIG_VFP_FEATURE_HALF_PRECISION) + set(ICCARM_FPU ${ICCARM_FPU}_Fp16) + endif() + elseif(CONFIG_CPU_CORTEX_R52) + if(CONFIG_VFP_FEATURE_DOUBLE_PRECISION) + set(ICCARM_FPU VFPv5_D16) + elseif(CONFIG_VFP_FEATURE_SINGLE_PRECISION) + set(ICCARM_FPU VFPv5-SP) + endif() + endif() + elseif(CONFIG_CPU_CORTEX_M) + # Defines a mapping from ICCARM_CPU to FPU + if(CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION) + set(PRECISION_TOKEN _D16) + else() + set(PRECISION_TOKEN -SP) + endif() + + set(FPU_FOR_Cortex-M4 FPv4${PRECISION_TOKEN}) + set(FPU_FOR_Cortex-M7 FPv5${PRECISION_TOKEN}) + set(FPU_FOR_Cortex-M33 FPv5${PRECISION_TOKEN}) + set(FPU_FOR_Cortex-M33.no_dsp FPv5${PRECISION_TOKEN}) + set(FPU_FOR_Cortex-M55 auto) + set(FPU_FOR_Cortex-M55.no_mve auto) + # We don't have this one? + set(FPU_FOR_Cortex-M55.no_dsp auto) + + set(ICCARM_FPU ${FPU_FOR_${ICCARM_CPU}}) + endif() + # 64-bit + else() + set(ICCARM_FPU none) + endif() + +endif() #CONFIG_FPU diff --git a/cmake/compiler/iar/target.cmake b/cmake/compiler/iar/target.cmake new file mode 100644 index 0000000000000..e6c89c875c43e --- /dev/null +++ b/cmake/compiler/iar/target.cmake @@ -0,0 +1,144 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +# Avoids running the linker during try_compile() +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +set(NO_BUILD_TYPE_WARNING 1) +set(CMAKE_NOT_USING_CONFIG_FLAGS 1) + +find_program(CMAKE_C_COMPILER + NAMES ${IAR_COMPILER} + PATHS ${TOOLCHAIN_HOME} + PATH_SUFFIXES bin + NO_DEFAULT_PATH + REQUIRED ) + +message(STATUS "Found C Compiler ${CMAKE_C_COMPILER}") + +find_program(CMAKE_CXX_COMPILER + NAMES ${IAR_COMPILER} + PATHS ${TOOLCHAIN_HOME} + PATH_SUFFIXES bin + NO_DEFAULT_PATH + REQUIRED ) + +find_program(CMAKE_AR + NAMES iarchive + PATHS ${TOOLCHAIN_HOME} + PATH_SUFFIXES bin + NO_DEFAULT_PATH + REQUIRED ) + +set(CMAKE_ASM_COMPILER) +if("${IAR_TOOLCHAIN_VARIANT}" STREQUAL "iccarm") + find_program(CMAKE_ASM_COMPILER + arm-zephyr-eabi-gcc + PATHS ${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin + NO_DEFAULT_PATH ) +else() + find_program(CMAKE_ASM_COMPILER + riscv64-zephyr-elf-gcc + PATHS ${ZEPHYR_SDK_INSTALL_DIR}/riscv64-zephyr-elf/bin + NO_DEFAULT_PATH ) +endif() + +message(STATUS "Found assembler ${CMAKE_ASM_COMPILER}") + +set(ICC_BASE ${ZEPHYR_BASE}/cmake/compiler/iar) + + +if("${IAR_TOOLCHAIN_VARIANT}" STREQUAL "iccarm") + # Used for settings correct cpu/fpu option for gnu assembler + include(${ZEPHYR_BASE}/cmake/gcc-m-cpu.cmake) + include(${ZEPHYR_BASE}/cmake/gcc-m-fpu.cmake) + + # Map KConfig option to icc cpu/fpu + include(${ICC_BASE}/iccarm-cpu.cmake) + include(${ICC_BASE}/iccarm-fpu.cmake) +endif() + +set(IAR_COMMON_FLAGS) +# Minimal C compiler flags + +list(APPEND IAR_COMMON_FLAGS + "SHELL: --preinclude" + "${ZEPHYR_BASE}/include/zephyr/toolchain/iar/iar_missing_defs.h" + # Enable both IAR and GNU extensions + -e + --language gnu + --do_explicit_init_in_named_sections + --macro_positions_in_diagnostics + --no_wrap_diagnostics +) + +if("${IAR_TOOLCHAIN_VARIANT}" STREQUAL "iccarm") + list(APPEND IAR_COMMON_FLAGS + --endian=little + --cpu=${ICCARM_CPU} + -DRTT_USE_ASM=0 #WA for VAAK-232 + --diag_suppress=Ta184 # Using zero sized arrays except for as last member of a struct is discouraged and dereferencing elements in such an array has undefined behavior + ) +endif() + +# Minimal ASM compiler flags +if("${IAR_TOOLCHAIN_VARIANT}" STREQUAL "iccarm") + list(APPEND IAR_ASM_FLAGS + -mcpu=${GCC_M_CPU} + -mabi=aapcs + -DRTT_USE_ASM=0 #WA for VAAK-232 + ) +endif() + +# IAR needs Dwarf 4 output +list(APPEND IAR_ASM_FLAGS -gdwarf-4) + +if(DEFINED CONFIG_ARM_SECURE_FIRMWARE) + list(APPEND IAR_COMMON_FLAGS --cmse) + list(APPEND IAR_ASM_FLAGS -mcmse) +endif() + +# 64-bit +if("${IAR_TOOLCHAIN_VARIANT}" STREQUAL "iccarm") + if(CONFIG_ARM64) + list(APPEND IAR_COMMON_FLAGS --abi=lp64) + list(APPEND TOOLCHAIN_LD_FLAGS --abi=lp64) + # 32-bit + else() + list(APPEND IAR_COMMON_FLAGS --aeabi) + if(CONFIG_COMPILER_ISA_THUMB2) + list(APPEND IAR_COMMON_FLAGS --thumb) + list(APPEND IAR_ASM_FLAGS -mthumb) + endif() + + if(CONFIG_FPU) + list(APPEND IAR_COMMON_FLAGS --fpu=${ICCARM_FPU}) + list(APPEND IAR_ASM_FLAGS -mfpu=${GCC_M_FPU}) + endif() + endif() +endif() + +if("${IAR_TOOLCHAIN_VARIANT}" STREQUAL "iccarm") + if(CONFIG_IAR_LIBC) + # Zephyr requires AEABI portability to ensure correct functioning of the C + # library, for example error numbers, errno.h. + list(APPEND IAR_COMMON_FLAGS -D__AEABI_PORTABILITY_LEVEL=1) + endif() +endif() + +if(CONFIG_IAR_LIBC) + message(STATUS "IAR C library used") + # Zephyr uses the type FILE for normal LIBC while IAR + # only has it for full LIBC support, so always choose + # full libc when using IAR C libraries. + list(APPEND IAR_COMMON_FLAGS --dlib_config full) +endif() + +foreach(F ${IAR_COMMON_FLAGS}) + list(APPEND TOOLCHAIN_C_FLAGS $<$:${F}>) + list(APPEND TOOLCHAIN_C_FLAGS $<$:${F}>) +endforeach() + +foreach(F ${IAR_ASM_FLAGS}) + list(APPEND TOOLCHAIN_C_FLAGS $<$:${F}>) +endforeach() diff --git a/cmake/compiler/xt-clang/target.cmake b/cmake/compiler/xt-clang/target.cmake index 978bc7c7860f4..73cf348a1fd58 100644 --- a/cmake/compiler/xt-clang/target.cmake +++ b/cmake/compiler/xt-clang/target.cmake @@ -7,7 +7,6 @@ include(${ZEPHYR_BASE}/cmake/compiler/xcc/target.cmake) set(LLEXT_REMOVE_FLAGS -ffunction-sections -fdata-sections - -g.* -Os -mcpu=.* ) diff --git a/cmake/emu/simics.cmake b/cmake/emu/simics.cmake index dee1305a1f175..f20c09f052a77 100644 --- a/cmake/emu/simics.cmake +++ b/cmake/emu/simics.cmake @@ -1,30 +1,42 @@ -# Copyright (c) 2023 Intel Corporation +# Copyright (c) 2023-2024 Intel Corporation # # SPDX-License-Identifier: Apache-2.0 find_program( SIMICS NAMES simics + NO_DEFAULT_PATH + PATHS ENV SIMICS_PROJECT + # Search exactly for the project's autogenerated 'trampoline' script. ) -zephyr_get(SIMICS_SCRIPT_PATH SYSBUILD GLOBAL) -if(SIMICS_SCRIPT_PATH) - set(SIMICS_SCRIPT ${SIMICS_SCRIPT_PATH}) +if(SIMICS STREQUAL SIMICS-NOTFOUND) + message(WARNING "Simics simulator environment is not found at SIMICS_PROJECT:'${SIMICS_PROJECT}'") else() - set(SIMICS_SCRIPT ${BOARD_DIR}/support/${BOARD}.simics) -endif() + message(STATUS "Found Simics: ${SIMICS}") -get_property(SIMICS_ARGS GLOBAL PROPERTY "BOARD_EMU_ARGS_simics") + zephyr_get(SIMICS_SCRIPT_PATH SYSBUILD GLOBAL) + if(SIMICS_SCRIPT_PATH) + set(SIMICS_SCRIPT ${SIMICS_SCRIPT_PATH}) + else() + set(SIMICS_SCRIPT ${BOARD_DIR}/support/${BOARD}.simics) + endif() -add_custom_target(run_simics - COMMAND - ${SIMICS} - -no-gui - -no-win - ${SIMICS_SCRIPT} - ${SIMICS_ARGS} - -e run - WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} - DEPENDS ${logical_target_for_zephyr_elf} - USES_TERMINAL - ) + get_property(SIMICS_ARGS GLOBAL PROPERTY "BOARD_EMU_ARGS_simics") + + add_custom_target(run_simics + COMMAND + ${SIMICS} + -no-gui + --no-win + --batch-mode + ${SIMICS_SCRIPT} + ${SIMICS_ARGS} + $ENV{SIMICS_EXTRA_ARGS} + -e run + WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} + DEPENDS ${logical_target_for_zephyr_elf} + USES_TERMINAL + ) + +endif() diff --git a/cmake/hex.cmake b/cmake/hex.cmake deleted file mode 100644 index f5eb586f7bd47..0000000000000 --- a/cmake/hex.cmake +++ /dev/null @@ -1,64 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -# This code was deprecated after Zephyr v3.5.0 -message(DEPRECATION "The to_hex() and from_hex() functions are deprecated. Please " - "use CMake's math(... OUTPUT_FORMAT ) instead.") - -# from https://gist.github.com/korzo89/71a6de0f388f7cf8b349101b0134060c -function(from_hex HEX DEC) - string(SUBSTRING "${HEX}" 2 -1 HEX) - string(TOUPPER "${HEX}" HEX) - set(_res 0) - string(LENGTH "${HEX}" _strlen) - - while(_strlen GREATER 0) - math(EXPR _res "${_res} * 16") - string(SUBSTRING "${HEX}" 0 1 NIBBLE) - string(SUBSTRING "${HEX}" 1 -1 HEX) - if(NIBBLE STREQUAL "A") - math(EXPR _res "${_res} + 10") - elseif(NIBBLE STREQUAL "B") - math(EXPR _res "${_res} + 11") - elseif(NIBBLE STREQUAL "C") - math(EXPR _res "${_res} + 12") - elseif(NIBBLE STREQUAL "D") - math(EXPR _res "${_res} + 13") - elseif(NIBBLE STREQUAL "E") - math(EXPR _res "${_res} + 14") - elseif(NIBBLE STREQUAL "F") - math(EXPR _res "${_res} + 15") - else() - math(EXPR _res "${_res} + ${NIBBLE}") - endif() - - string(LENGTH "${HEX}" _strlen) - endwhile() - - set(${DEC} ${_res} PARENT_SCOPE) -endfunction() - -function(to_hex DEC HEX) - if(DEC EQUAL 0) - set(${HEX} "0x0" PARENT_SCOPE) - return() - endif() - while(DEC GREATER 0) - math(EXPR _val "${DEC} % 16") - math(EXPR DEC "${DEC} / 16") - if(_val EQUAL 10) - set(_val "A") - elseif(_val EQUAL 11) - set(_val "B") - elseif(_val EQUAL 12) - set(_val "C") - elseif(_val EQUAL 13) - set(_val "D") - elseif(_val EQUAL 14) - set(_val "E") - elseif(_val EQUAL 15) - set(_val "F") - endif() - set(_res "${_val}${_res}") - endwhile() - set(${HEX} "0x${_res}" PARENT_SCOPE) -endfunction() diff --git a/cmake/linker/iar/config_file_script.cmake b/cmake/linker/iar/config_file_script.cmake new file mode 100644 index 0000000000000..be11bbac8a38a --- /dev/null +++ b/cmake/linker/iar/config_file_script.cmake @@ -0,0 +1,922 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.17) + +set(SORT_TYPE_NAME Lexical) + +set_property(GLOBAL PROPERTY ILINK_REGION_SYMBOL_ICF) + +# This function post process the region for easier use. +# +# Tasks: +# - Symbol translation using a steering file is configured. +function(process_region) + cmake_parse_arguments(REGION "" "OBJECT" "" ${ARGN}) + + process_region_common(${ARGN}) + + get_property(empty GLOBAL PROPERTY ${REGION_OBJECT}_EMPTY) + if(NOT empty) + # For scatter files we move any system symbols into first non-empty load section. + get_parent(OBJECT ${REGION_OBJECT} PARENT parent TYPE SYSTEM) + get_property(symbols GLOBAL PROPERTY ${parent}_SYMBOLS) + set_property(GLOBAL APPEND PROPERTY ${REGION_OBJECT}_SYMBOLS ${symbols}) + set_property(GLOBAL PROPERTY ${parent}_SYMBOLS) + endif() + + get_property(sections GLOBAL PROPERTY ${REGION_OBJECT}_SECTION_LIST_ORDERED) + foreach(section ${sections}) + + get_property(name GLOBAL PROPERTY ${section}_NAME) + get_property(name_clean GLOBAL PROPERTY ${section}_NAME_CLEAN) + get_property(noinput GLOBAL PROPERTY ${section}_NOINPUT) + get_property(type GLOBAL PROPERTY ${section}_TYPE) + get_property(nosymbols GLOBAL PROPERTY ${section}_NOSYMBOLS) + + if(NOT nosymbols) + if(${name} STREQUAL .ramfunc) + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name_clean}_load_start + EXPR "@ADDR(.ramfunc_init)@" + ) + else() + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name_clean}_load_start + EXPR "@LOADADDR(${name_clean})@" + ) + endif() + endif() + + get_property(indicies GLOBAL PROPERTY ${section}_SETTINGS_INDICIES) + list(LENGTH indicies length) + foreach(idx ${indicies}) + set(steering_postfixes Base Limit) + get_property(symbols GLOBAL PROPERTY ${section}_SETTING_${idx}_SYMBOLS) + get_property(sort GLOBAL PROPERTY ${section}_SETTING_${idx}_SORT) + get_property(offset GLOBAL PROPERTY ${section}_SETTING_${idx}_OFFSET) + if(DEFINED offset AND NOT offset EQUAL 0 ) + # Same behavior as in section_to_string + elseif(DEFINED offset AND offset STREQUAL 0 ) + # Same behavior as in section_to_string + elseif(sort) + # Treated by labels in the icf or image symbols. + elseif(DEFINED symbols AND ${length} EQUAL 1 AND noinput) + endif() + endforeach() + + # Symbols translation here. + + get_property(symbol_val GLOBAL PROPERTY SYMBOL_TABLE___${name_clean}_end) + + if("${symbol_val}" STREQUAL "${name_clean}") + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name_clean}_size + EXPR "@SIZE(${name_clean})@" + ) + else() + # These seem to be thing that can't be transformed to $$Length + set_property(GLOBAL APPEND PROPERTY ILINK_REGION_SYMBOL_ICF + "define image symbol __${name_clean}_size = (__${symbol_val} - ADDR(${name_clean}))") + endif() + set(ZI) + + if(${name_clean} STREQUAL last_ram_section) + # A trick to add the symbol for the nxp devices + # _flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start; + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL _flash_used + EXPR "(@LOADADDR(last_section)@ + @SIZE(last_section)@ - @__rom_region_start@)" + ) + endif() + + if(${name_clean} STREQUAL rom_start) + # The below two symbols is meant to make aliases to the _vector_table symbol. + list(GET symbols 0 symbol_start) + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __Vectors + EXPR "@ADDR(${symbol_start})@" + ) + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __vector_table + EXPR "@ADDR(${symbol_start})@" + ) + endif() + + endforeach() + + get_property(groups GLOBAL PROPERTY ${REGION_OBJECT}_GROUP_LIST_ORDERED) + foreach(group ${groups}) + get_property(name GLOBAL PROPERTY ${group}_NAME) + string(TOLOWER ${name} name) + + get_property(group_type GLOBAL PROPERTY ${group}_OBJ_TYPE) + get_property(parent GLOBAL PROPERTY ${group}_PARENT) + get_property(parent_type GLOBAL PROPERTY ${parent}_OBJ_TYPE) + # Need to find the init manually group or parent + if(${parent_type} STREQUAL GROUP) + get_property(vma GLOBAL PROPERTY ${parent}_VMA) + get_property(lma GLOBAL PROPERTY ${parent}_LMA) + else() + get_property(vma GLOBAL PROPERTY ${group}_VMA) + get_property(lma GLOBAL PROPERTY ${group}_LMA) + endif() + + get_objects(LIST sections OBJECT ${group} TYPE SECTION) + list(GET sections 0 section) + get_property(first_section_name GLOBAL PROPERTY ${section}_NAME_CLEAN) + list(POP_BACK sections section) + get_property(last_section_name GLOBAL PROPERTY ${section}_NAME_CLEAN) + + if(DEFINED vma AND DEFINED lma) + # Something to init + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name}_load_start + EXPR "@ADDR(${first_section_name}_init)@" + ) + else() + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name}_load_start + EXPR "@LOADADDR(${first_section_name})@" + ) + endif() + + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name}_start + EXPR "@ADDR(${first_section_name})@" + ) + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name}_end + EXPR "@END(${last_section_name})@" + ) + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name}_size + EXPR "(@(__${name}_end)@ - @(__${name}_start)@)" + ) + + endforeach() + + get_property(symbols GLOBAL PROPERTY ${REGION_OBJECT}_SYMBOLS) + foreach(symbol ${symbols}) + get_property(name GLOBAL PROPERTY ${symbol}_NAME) + get_property(expr GLOBAL PROPERTY ${symbol}_EXPR) + if(NOT DEFINED expr) + create_symbol(OBJECT ${REGION_OBJECT} SYMBOL __${name}_size + EXPR "@(ADDR(${name})@" + ) + endif() + endforeach() + + # This is only a trick to get the memories + set(groups) + get_objects(LIST groups OBJECT ${REGION_OBJECT} TYPE GROUP) + foreach(group ${groups}) + get_property(group_type GLOBAL PROPERTY ${group}_OBJ_TYPE) + get_property(parent GLOBAL PROPERTY ${group}_PARENT) + get_property(parent_type GLOBAL PROPERTY ${parent}_OBJ_TYPE) + + if(${group_type} STREQUAL GROUP) + get_property(group_name GLOBAL PROPERTY ${group}_NAME) + get_property(group_lma GLOBAL PROPERTY ${group}_LMA) + if(${group_name} STREQUAL ROM_REGION) + set_property(GLOBAL PROPERTY ILINK_ROM_REGION_NAME ${group_lma}) + endif() + endif() + + if(${parent_type} STREQUAL GROUP) + get_property(vma GLOBAL PROPERTY ${parent}_VMA) + get_property(lma GLOBAL PROPERTY ${parent}_LMA) + + set_property(GLOBAL PROPERTY ${group}_VMA ${vma}) + set_property(GLOBAL PROPERTY ${group}_LMA ${lma}) + endif() + endforeach() + +endfunction() + +# +# String functions - start +# + +function(system_to_string) + cmake_parse_arguments(STRING "" "OBJECT;STRING" "" ${ARGN}) + + get_property(name GLOBAL PROPERTY ${STRING_OBJECT}_NAME) + get_property(regions GLOBAL PROPERTY ${STRING_OBJECT}_REGIONS) + get_property(format GLOBAL PROPERTY ${STRING_OBJECT}_FORMAT) + + # Ilink specials + # set(${STRING_STRING} "build for rom;\n") + set(${STRING_STRING} "build for ram;\n") + if("${format}" MATCHES "aarch64") + set(${STRING_STRING} "${${STRING_STRING}}define memory mem with size = 16E;\n") + else() + set(${STRING_STRING} "${${STRING_STRING}}define memory mem with size = 4G;\n") + endif() + + foreach(region ${regions}) + get_property(name GLOBAL PROPERTY ${region}_NAME) + get_property(address GLOBAL PROPERTY ${region}_ADDRESS) + get_property(flags GLOBAL PROPERTY ${region}_FLAGS) + get_property(size GLOBAL PROPERTY ${region}_SIZE) + + if(DEFINED flags) + if(${flags} STREQUAL rx) + set(flags " rom") + elseif(${flags} STREQUAL ro) + set(flags " rom") + elseif(${flags} STREQUAL wx) + set(flags " ram") + elseif(${flags} STREQUAL rw) + set(flags " ram") + endif() + endif() + + if(${name} STREQUAL IDT_LIST) + # Need to use a untyped region for IDT_LIST + set(flags "") + endif() + + if(DEFINED address) + set(start "${address}") + endif() + + if(DEFINED size) + set(size "${size}") + endif() + # define rom region FLASH = mem:[from 0x0 size 0x40000]; + set(memory_region "define${flags} region ${name} = mem:[from ${start} size ${size}];") + + set(${STRING_STRING} "${${STRING_STRING}}${memory_region}\n") + set(flags) + endforeach() + + set(${STRING_STRING} "${${STRING_STRING}}\n\n") + set_property(GLOBAL PROPERTY ILINK_SYMBOL_ICF) + + set(${STRING_STRING} "${${STRING_STRING}}\n") + foreach(region ${regions}) + get_property(empty GLOBAL PROPERTY ${region}_EMPTY) + if(NOT empty) + get_property(name GLOBAL PROPERTY ${region}_NAME) + set(ILINK_CURRENT_NAME ${name}) + to_string(OBJECT ${region} STRING ${STRING_STRING}) + set(ILINK_CURRENT_NAME) + endif() + endforeach() + set(${STRING_STRING} "${${STRING_STRING}}\n") + + get_property(symbols_icf GLOBAL PROPERTY ILINK_SYMBOL_ICF) + foreach(image_symbol ${symbols_icf}) + set(${STRING_STRING} "${${STRING_STRING}}define image symbol ${image_symbol};\n") + endforeach() + + get_property(symbols_icf GLOBAL PROPERTY ILINK_REGION_SYMBOL_ICF) + set(${STRING_STRING} "${${STRING_STRING}}\n") + foreach(image_symbol ${symbols_icf}) + set(${STRING_STRING} "${${STRING_STRING}}${image_symbol};\n") + endforeach() + + if(IAR_LIBC) + set(${STRING_STRING} "${${STRING_STRING}}if (K_HEAP_MEM_POOL_SIZE>0)\n{\n") + set(${STRING_STRING} "${${STRING_STRING}} define block HEAP with alignment=8 { symbol kheap__system_heap };\n") + set(${STRING_STRING} "${${STRING_STRING}}}\nelse\n{\n") + set(${STRING_STRING} "${${STRING_STRING}} define block HEAP with alignment=8, expanding size { };\n") + set(${STRING_STRING} "${${STRING_STRING}}}\n") + set(${STRING_STRING} "${${STRING_STRING}}\"DLib heap\": place in RAM { block HEAP };\n") +# set(${STRING_STRING} "${${STRING_STRING}}define exported symbol HEAP$$Base=kheap__system_heap;\n") +# set(${STRING_STRING} "${${STRING_STRING}}define exported symbol HEAP$$Limit=END(kheap__system_heap);\n") + endif() + + set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE) +endfunction() + +function(group_to_string) + cmake_parse_arguments(STRING "" "OBJECT;STRING" "" ${ARGN}) + + get_property(type GLOBAL PROPERTY ${STRING_OBJECT}_OBJ_TYPE) + if(${type} STREQUAL REGION) + get_property(name GLOBAL PROPERTY ${STRING_OBJECT}_NAME) + get_property(address GLOBAL PROPERTY ${STRING_OBJECT}_ADDRESS) + get_property(size GLOBAL PROPERTY ${STRING_OBJECT}_SIZE) + + get_property(empty GLOBAL PROPERTY ${STRING_OBJECT}_EMPTY) + if(empty) + return() + endif() + + else() + get_property(else_name GLOBAL PROPERTY ${STRING_OBJECT}_NAME) + get_property(else_symbol GLOBAL PROPERTY ${STRING_OBJECT}_SYMBOL) + string(TOLOWER ${else_name} else_name) + + get_objects(LIST sections OBJECT ${STRING_OBJECT} TYPE SECTION) + list(GET sections 0 section) + get_property(first_section_name GLOBAL PROPERTY ${section}_NAME) + + endif() + + if(${type} STREQUAL GROUP) + get_property(group_name GLOBAL PROPERTY ${STRING_OBJECT}_NAME) + get_property(group_address GLOBAL PROPERTY ${STRING_OBJECT}_ADDRESS) + get_property(group_vma GLOBAL PROPERTY ${STRING_OBJECT}_VMA) + get_property(group_lma GLOBAL PROPERTY ${STRING_OBJECT}_LMA) + endif() + + get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_SECTIONS_FIXED) + foreach(section ${sections}) + to_string(OBJECT ${section} STRING ${STRING_STRING}) + get_property(name GLOBAL PROPERTY ${section}_NAME) + get_property(name_clean GLOBAL PROPERTY ${section}_NAME_CLEAN) + set(${STRING_STRING} "${${STRING_STRING}}\"${name}\": place at address mem:${address} { block ${name_clean} };\n") + endforeach() + + get_property(groups GLOBAL PROPERTY ${STRING_OBJECT}_GROUPS) + foreach(group ${groups}) + to_string(OBJECT ${group} STRING ${STRING_STRING}) + endforeach() + + get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_SECTIONS) + foreach(section ${sections}) + to_string(OBJECT ${section} STRING ${STRING_STRING}) + + get_property(name GLOBAL PROPERTY ${section}_NAME) + + get_property(name_clean GLOBAL PROPERTY ${section}_NAME_CLEAN) + + get_property(parent GLOBAL PROPERTY ${section}_PARENT) + # This is only a trick to get the memories + get_property(parent_type GLOBAL PROPERTY ${parent}_OBJ_TYPE) + if(${parent_type} STREQUAL GROUP) + get_property(vma GLOBAL PROPERTY ${parent}_VMA) + get_property(lma GLOBAL PROPERTY ${parent}_LMA) + endif() + + if(DEFINED vma) + set(ILINK_CURRENT_NAME ${vma}) + elseif(DEFINED lma) + set(ILINK_CURRENT_NAME ${lma}) + else() + # message(FATAL_ERROR "Need either vma or lma") + endif() + + set(${STRING_STRING} "${${STRING_STRING}}\"${name}\": place in ${ILINK_CURRENT_NAME} { block ${name_clean} };\n") + if(DEFINED vma AND DEFINED lma) + set(${STRING_STRING} "${${STRING_STRING}}\"${name}_init\": place in ${lma} { block ${name_clean}_init };\n") + endif() + + endforeach() + + get_parent(OBJECT ${STRING_OBJECT} PARENT parent TYPE SYSTEM) + get_property(regions GLOBAL PROPERTY ${parent}_REGIONS) + list(REMOVE_ITEM regions ${STRING_OBJECT}) + + foreach(region ${regions}) + get_property(vma GLOBAL PROPERTY ${region}_NAME) + get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_SECTIONS_FIXED) + + foreach(section ${sections}) + to_string(OBJECT ${section} STRING ${STRING_STRING}) + endforeach() + + get_property(groups GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_GROUPS) + foreach(group ${groups}) + to_string(OBJECT ${group} STRING ${STRING_STRING}) + endforeach() + + get_property(sections GLOBAL PROPERTY ${STRING_OBJECT}_${vma}_SECTIONS) + foreach(section ${sections}) + to_string(OBJECT ${section} STRING ${STRING_STRING}) + get_property(name GLOBAL PROPERTY ${section}_NAME) + string(REGEX REPLACE "^[\.]" "" name_clean "${name}") + string(REPLACE "." "_" name_clean "${name_clean}") + set(${STRING_STRING} "${${STRING_STRING}}\"${name}\": place in ${vma} { block ${name_clean} };\n") + + # Insert 'do not initialize' here + get_property(current_sections GLOBAL PROPERTY ILINK_CURRENT_SECTIONS) + if(${name} STREQUAL .bss) + if(DEFINED current_sections) + set(${STRING_STRING} "${${STRING_STRING}}do not initialize\n") + set(${STRING_STRING} "${${STRING_STRING}}{\n") + foreach(section ${current_sections}) + set(${STRING_STRING} "${${STRING_STRING}} ${section},\n") + endforeach() + set(${STRING_STRING} "${${STRING_STRING}}};\n") + set(current_sections) + set_property(GLOBAL PROPERTY ILINK_CURRENT_SECTIONS) + endif() + endif() + + if(${name_clean} STREQUAL last_ram_section) + get_property(group_name_lma GLOBAL PROPERTY ILINK_ROM_REGION_NAME) + set(${STRING_STRING} "${${STRING_STRING}}\n") + if(${CONFIG_LINKER_LAST_SECTION_ID}) + set(${STRING_STRING} "${${STRING_STRING}}define section last_section_id { udata32 ${CONFIG_LINKER_LAST_SECTION_ID_PATTERN}; };\n") + set(${STRING_STRING} "${${STRING_STRING}}define block last_section with fixed order { section last_section_id };\n") + else() + set(${STRING_STRING} "${${STRING_STRING}}define block last_section with fixed order { };\n") + endif() + # Not really the right place, we want the last used flash bytes not end of the world! + # set(${STRING_STRING} "${${STRING_STRING}}\".last_section\": place at end of ${group_name_lma} { block last_section };\n") + set(${STRING_STRING} "${${STRING_STRING}}\".last_section\": place in ${group_name_lma} { block last_section };\n") + set(${STRING_STRING} "${${STRING_STRING}}keep { block last_section };\n") + endif() + + endforeach() + endforeach() + + get_property(symbols GLOBAL PROPERTY ${STRING_OBJECT}_SYMBOLS) + set(${STRING_STRING} "${${STRING_STRING}}\n") + foreach(symbol ${symbols}) + to_string(OBJECT ${symbol} STRING ${STRING_STRING}) + endforeach() + + set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE) +endfunction() + + +function(section_to_string) + cmake_parse_arguments(STRING "" "SECTION;STRING" "" ${ARGN}) + + get_property(name GLOBAL PROPERTY ${STRING_SECTION}_NAME) + get_property(address GLOBAL PROPERTY ${STRING_SECTION}_ADDRESS) + get_property(type GLOBAL PROPERTY ${STRING_SECTION}_TYPE) + get_property(align GLOBAL PROPERTY ${STRING_SECTION}_ALIGN) + get_property(subalign GLOBAL PROPERTY ${STRING_SECTION}_SUBALIGN) + get_property(endalign GLOBAL PROPERTY ${STRING_SECTION}_ENDALIGN) + get_property(vma GLOBAL PROPERTY ${STRING_SECTION}_VMA) + get_property(lma GLOBAL PROPERTY ${STRING_SECTION}_LMA) + get_property(noinput GLOBAL PROPERTY ${STRING_SECTION}_NOINPUT) + get_property(noinit GLOBAL PROPERTY ${STRING_SECTION}_NOINIT) + + get_property(nosymbols GLOBAL PROPERTY ${STRING_SECTION}_NOSYMBOLS) + get_property(start_syms GLOBAL PROPERTY ${STRING_SECTION}_START_SYMBOLS) + get_property(end_syms GLOBAL PROPERTY ${STRING_SECTION}_END_SYMBOLS) + + get_property(parent GLOBAL PROPERTY ${STRING_SECTION}_PARENT) + + get_property(parent_type GLOBAL PROPERTY ${parent}_OBJ_TYPE) + if(${parent_type} STREQUAL GROUP) + get_property(group_parent_vma GLOBAL PROPERTY ${parent}_VMA) + get_property(group_parent_lma GLOBAL PROPERTY ${parent}_LMA) + if(NOT DEFINED vma) + get_property(vma GLOBAL PROPERTY ${parent}_VMA) + endif() + if(NOT DEFINED lma) + get_property(lma GLOBAL PROPERTY ${parent}_LMA) + endif() + endif() + + if(DEFINED group_parent_vma AND DEFINED group_parent_lma) + # Something to init + set(part "rw ") + else() + set(part) + endif() + + + set_property(GLOBAL PROPERTY ILINK_CURRENT_SECTIONS) + + string(REGEX REPLACE "^[\.]" "" name_clean "${name}") + string(REPLACE "." "_" name_clean "${name_clean}") + + # WA for 'Error[Lc036]: no block or place matches the pattern "ro data section .tdata_init"' + if("${name_clean}" STREQUAL "tdata") + set(TEMP "${TEMP}define block ${name_clean}_init { ro section .tdata_init };\n") + set(TEMP "${TEMP}\"${name_clean}_init\": place in ${ILINK_CURRENT_NAME} { block ${name_clean}_init };\n\n") + endif() + + get_property(indicies GLOBAL PROPERTY ${STRING_SECTION}_SETTINGS_INDICIES) + # ZIP_LISTS partner + get_property(next_indicies GLOBAL PROPERTY ${STRING_SECTION}_SETTINGS_INDICIES) + list(POP_FRONT next_indicies first_index) + + set(first_index_section) + set(first_index_section_name) + if(DEFINED first_index) + # Handle case where the first section has an offset + get_property(first_index_offset + GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${first_index}_OFFSET) + get_property(keep GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${first_index}_KEEP) + if(DEFINED keep) + set(root "root ") + else() + set(root) + endif() + if(DEFINED first_index_offset AND NOT first_index_offset EQUAL 0 ) + set(first_index_section_name "${name_clean}_${first_index}_offset") + set(first_index_section + "define ${root}section ${first_index_section_name} {};") + else() + set(first_index) + endif() + endif() + + foreach(start_symbol ${start_syms}) + set_property(GLOBAL APPEND PROPERTY ILINK_SYMBOL_ICF "${start_symbol} = ADDR(${name_clean})") + endforeach() + foreach(end_symbol ${end_syms}) + set_property(GLOBAL APPEND PROPERTY ILINK_SYMBOL_ICF "${end_symbol} = END(${name_clean})") + endforeach() + + if(NOT nosymbols) + if("${name_clean}" STREQUAL "tdata") + set_property(GLOBAL APPEND PROPERTY ILINK_SYMBOL_ICF "__${name_clean}_start = (__iar_tls$$INIT_DATA$$Base)") + set_property(GLOBAL APPEND PROPERTY ILINK_SYMBOL_ICF "__${name_clean}_end = (__iar_tls$$INIT_DATA$$Limit)") + else() + set_property(GLOBAL APPEND PROPERTY ILINK_SYMBOL_ICF "__${name_clean}_start = ADDR(${name_clean})") + set_property(GLOBAL APPEND PROPERTY ILINK_SYMBOL_ICF "__${name_clean}_end = END(${name_clean})") + endif() + endif() + + # Add keep to the sections that have 'KEEP:TRUE' + foreach(idx ${indicies}) + get_property(keep GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_KEEP) + get_property(input GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_INPUT) + foreach(setting ${input}) + if(keep) + # keep { section .abc* }; + set(TEMP "${TEMP}keep { section ${setting} };\n") + endif() + endforeach() + endforeach() + + if(DEFINED first_index_section) + set(TEMP "${TEMP}${first_index_section}\n") + endif() + + set(TEMP "${TEMP}define block ${name_clean} with fixed order") + + if(align) + set(TEMP "${TEMP}, alignment=${align}") + elseif(subalign) + set(TEMP "${TEMP}, alignment = ${subalign}") + elseif(part) + set(TEMP "${TEMP}, alignment = input") + else() + set(TEMP "${TEMP}, alignment=4") + endif() + if(endalign) + set(TEMP "${TEMP}, end alignment=${endalign}") + endif() + + set(TEMP "${TEMP}\n{") + + # foreach(start_symbol ${start_syms}) + # set(TEMP "${TEMP}\n section ${start_symbol},") + # set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section ${start_symbol}") + # endforeach() + + # if(NOT nosymbols) + # set(TEMP "${TEMP}\n section __${name_clean}_start,") + # set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section __${name_clean}_start") + # endif() + + list(GET indicies -1 last_index) + list(LENGTH indicies length) + + if(NOT noinput) + + set(TEMP "${TEMP}\n block ${name_clean}_winput") + if(align) + list(APPEND block_attr "alignment = ${align}") + elseif(subalign) + list(APPEND block_attr "alignment = ${subalign}") + elseif(part) + # list(APPEND block_attr "alignment = input") + else() + list(APPEND block_attr "alignment=4") + endif() + list(APPEND block_attr "fixed order") + + list(JOIN block_attr ", " block_attr_str) + if(block_attr_str) + set(TEMP "${TEMP} with ${block_attr_str}") + endif() + set(block_attr) + set(block_attr_str) + + set(TEMP "${TEMP} { ${part}section ${name}, ${part}section ${name}.* }") + if(${length} GREATER 0) + set(TEMP "${TEMP},") + endif() + set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section ${name}") + set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section ${name}.*") + endif() + + foreach(idx idx_next IN ZIP_LISTS indicies next_indicies) + get_property(align GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_ALIGN) + get_property(any GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_ANY) + get_property(first GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_FIRST) + get_property(keep GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_KEEP) + get_property(sort GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_SORT) + get_property(flags GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_FLAGS) + get_property(input GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_INPUT) + get_property(symbols GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_SYMBOLS) + # Get the next offset and use that as this ones size! + get_property(offset GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx_next}_OFFSET) + + if(DEFINED symbols) + list(LENGTH symbols symbols_count) + if(${symbols_count} GREATER 0) + list(GET symbols 0 symbol_start) + endif() + if(${symbols_count} GREATER 1) + list(GET symbols 1 symbol_end) + endif() + endif() + + if(DEFINED symbol_start) + # set(TEMP "${TEMP}\n section ${symbol_start},") + # set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section ${symbol_start}") + set_property(GLOBAL APPEND PROPERTY ILINK_SYMBOL_ICF "${symbol_start} = ADDR(${name_clean}_${idx})") + endif() + + if(DEFINED first_index AND first_index EQUAL ${idx}) + # Create the offset + set(TEMP "${TEMP}\n block ${first_index_section_name}") + list(APPEND block_attr "size = ${first_index_offset}") + if(sort) + if(${sort} STREQUAL NAME) + list(APPEND block_attr "alphabetical order") + endif() + endif() + if(align) + list(APPEND block_attr "alignment = ${align}") + elseif(subalign) + list(APPEND block_attr "alignment = ${subalign}") + elseif(part) + # list(APPEND block_attr "alignment = input") + else() + list(APPEND block_attr "alignment=4") + endif() + list(APPEND block_attr "fixed order") + + list(JOIN block_attr ", " block_attr_str) + if(block_attr_str) + set(TEMP "${TEMP} with ${block_attr_str}") + endif() + set(block_attr) + set(block_attr_str) + + set(TEMP "${TEMP} { section ${first_index_section_name} },\n") + endif() + + # block init_100 with alphabetical order { section .z_init_EARLY?_} + set(TEMP "${TEMP}\n block ${name_clean}_${idx}") + if(DEFINED offset AND NOT offset EQUAL 0 ) + list(APPEND block_attr "size = ${offset}") + elseif(DEFINED offset AND offset STREQUAL 0 ) + # Do nothing + endif() + if(sort) + if(${sort} STREQUAL NAME) + list(APPEND block_attr "alphabetical order") + endif() + endif() + if(align) + list(APPEND block_attr "alignment = ${align}") + elseif(subalign) + list(APPEND block_attr "alignment = ${subalign}") + elseif(part) + # list(APPEND block_attr "alignment = input") + else() + list(APPEND block_attr "alignment=4") + endif() + + # LD + # There are two ways to include more than one section: + # + # *(.text .rdata) + # *(.text) *(.rdata) + # + # The difference between these is the order in which + # the `.text' and `.rdata' input sections will appear in the output section. + # In the first example, they will be intermingled, + # appearing in the same order as they are found in the linker input. + # In the second example, all `.text' input sections will appear first, + # followed by all `.rdata' input sections. + # + # ILINK solved by adding 'fixed order' + if(NOT sort AND NOT first) + list(APPEND block_attr "fixed order") + endif() + + list(JOIN block_attr ", " block_attr_str) + if(block_attr_str) + set(TEMP "${TEMP} with ${block_attr_str}") + endif() + set(block_attr) + set(block_attr_str) + + if(empty) + set(TEMP "${TEMP}\n {") + set(empty FALSE) + endif() + + list(GET input -1 last_input) + + set(TEMP "${TEMP} {") + if(NOT DEFINED input AND NOT any) + set(TEMP "${TEMP} }") + endif() + + foreach(setting ${input}) + if(first) + set(TEMP "${TEMP} first") + set(first "") + endif() + + set(section_type "") + + # build for ram, no section_type + # if("${lma}" STREQUAL "${vma}") + # # if("${vma}" STREQUAL "") + # set(section_type "") + # # else() + # # set(section_type " readwrite") + # # endif() + # elseif(NOT "${vma}" STREQUAL "") + # set(section_type " readwrite") + # elseif(NOT "${lma}" STREQUAL "") + # set(section_type " readonly") + # else() + # message(FATAL_ERROR "How to handle this? lma=${lma} vma=${vma}") + # endif() + + set(TEMP "${TEMP}${section_type} ${part}section ${setting}") + set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section ${setting}") + set(section_type "") + + if("${setting}" STREQUAL "${last_input}") + set(TEMP "${TEMP} }") + else() + set(TEMP "${TEMP}, ") + endif() + + # set(TEMP "${TEMP}\n *.o(${setting})") + endforeach() + + if(any) + if(NOT flags) + message(FATAL_ERROR ".ANY requires flags to be set.") + endif() + set(ANY_FLAG "") + foreach(flag ${flags}) + # if("${flag}" STREQUAL +RO OR "${flag}" STREQUAL +XO) + # set(ANY_FLAG "readonly") + # # elseif("${flag}" STREQUAL +RW) + # # set(ANY_FLAG "readwrite") + # else + if("${flag}" STREQUAL +ZI) + set(ANY_FLAG "zeroinit") + set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "${ANY_FLAG}") + endif() + endforeach() + set(TEMP "${TEMP} ${ANY_FLAG} }") + endif() + + if(DEFINED symbol_end) + # set(TEMP "${TEMP},\n section ${symbol_end}") + # set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section ${symbol_end}") + set_property(GLOBAL APPEND PROPERTY ILINK_SYMBOL_ICF "${symbol_end} = END(${name_clean}_${idx})") + endif() + if(${length} GREATER 0) + if(NOT "${idx}" STREQUAL "${last_index}") + set(TEMP "${TEMP},") + elseif() + endif() + endif() + + set(symbol_start) + set(symbol_end) + endforeach() + set(next_indicies) + + set(last_index) + set(last_input) + set(TEMP "${TEMP}") + + # if(NOT nosymbols) + # set(TEMP "${TEMP},\n section __${name_clean}_end") + # set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section __${name_clean}_end") + # endif() + + # foreach(end_symbol ${end_syms}) + # set(TEMP "${TEMP},\n section ${end_symbol}") + # set_property(GLOBAL APPEND PROPERTY ILINK_CURRENT_SECTIONS "section ${end_symbol}") + # endforeach() + + set(TEMP "${TEMP}\n};") + + get_property(type GLOBAL PROPERTY ${parent}_OBJ_TYPE) + if(${type} STREQUAL REGION) + get_property(name GLOBAL PROPERTY ${parent}_NAME) + get_property(address GLOBAL PROPERTY ${parent}_ADDRESS) + get_property(size GLOBAL PROPERTY ${parent}_SIZE) + + endif() + + get_property(current_sections GLOBAL PROPERTY ILINK_CURRENT_SECTIONS) + + if(DEFINED group_parent_vma AND DEFINED group_parent_lma) + if(DEFINED current_sections) + # "${TEMP}" is there too keep the ';' else it will be a list + string(REGEX REPLACE "(block[ \t\r\n]+)([^ \t\r\n]+)" "\\1\\2_init" INIT_TEMP "${TEMP}") + string(REGEX REPLACE "(rw)([ \t\r\n]+)(section[ \t\r\n]+)([^ \t\r\n,]+)" "\\1\\2\\3\\4_init" INIT_TEMP "${INIT_TEMP}") + string(REGEX REPLACE "(rw)([ \t\r\n]+)(section[ \t\r\n]+)" "ro\\2\\3" INIT_TEMP "${INIT_TEMP}") + string(REGEX REPLACE "alphabetical order, " "" INIT_TEMP "${INIT_TEMP}") + string(REGEX REPLACE "{ readwrite }" "{ }" INIT_TEMP "${INIT_TEMP}") + + set(TEMP "${TEMP}\n${INIT_TEMP}\n") + set(TEMP "${TEMP}\ninitialize manually with copy friendly\n") + set(TEMP "${TEMP}{\n") + foreach(section ${current_sections}) + set(TEMP "${TEMP} ${section},\n") + endforeach() + set(TEMP "${TEMP}};") + set(current_sections) + + endif() + endif() + + set(${STRING_STRING} "${${STRING_STRING}}\n${TEMP}\n" PARENT_SCOPE) +endfunction() + +function(symbol_to_string) + cmake_parse_arguments(STRING "" "SYMBOL;STRING" "" ${ARGN}) + + get_property(name GLOBAL PROPERTY ${STRING_SYMBOL}_NAME) + get_property(expr GLOBAL PROPERTY ${STRING_SYMBOL}_EXPR) + get_property(size GLOBAL PROPERTY ${STRING_SYMBOL}_SIZE) + get_property(symbol GLOBAL PROPERTY ${STRING_SYMBOL}_SYMBOL) + get_property(subalign GLOBAL PROPERTY ${STRING_SYMBOL}_SUBALIGN) + + string(REPLACE "\\" "" expr "${expr}") + string(REGEX MATCHALL "@([^@]*)@" match_res ${expr}) + + foreach(match ${match_res}) + string(REPLACE "@" "" match ${match}) + get_property(symbol_val GLOBAL PROPERTY SYMBOL_TABLE_${match}) + string(REPLACE "@${match}@" "${match}" expr ${expr}) + endforeach() + + list(LENGTH match_res match_res_count) + + if(match_res_count) + if(${match_res_count} GREATER 1) + set(${STRING_STRING} + "${${STRING_STRING}}define image symbol ${symbol} = ${expr};\n" + ) + else() + if((expr MATCHES "Base|Limit|Length") OR (expr MATCHES "ADDR\\(|END\\(|SIZE\\(")) + # Anything like $$Base/$$Limit/$$Length should be an image symbol + if( "${symbol}" STREQUAL "__tdata_size") + # This will handle the alignment of the TBSS block + set(${STRING_STRING} + "${${STRING_STRING}}define image symbol ${symbol}=(__iar_tls$$INIT_DATA$$Limit-__iar_tls$$INIT_DATA$$Base);\n" + ) + elseif( "${symbol}" STREQUAL "__tbss_size") + # This will handle the alignment of the TBSS block by + # pre-padding bytes + set(${STRING_STRING} + "${${STRING_STRING}}define image symbol ${symbol}=((tbss$$Limit-__iar_tls$$DATA$$Base)-(__iar_tls$$INIT_DATA$$Limit-__iar_tls$$INIT_DATA$$Base));\n" + ) + else() + set(${STRING_STRING} + "${${STRING_STRING}}define image symbol ${symbol} = ${expr};\n" + ) + endif() + else() + list(GET match_res 0 match) + string(REPLACE "@" "" match ${match}) + get_property(symbol_val GLOBAL PROPERTY SYMBOL_TABLE_${match}) + if(symbol_val) + set(${STRING_STRING} + "${${STRING_STRING}}define image symbol ${symbol} = ${expr};\n" + ) + else() + # Treatmen of "zephyr_linker_symbol(SYMBOL z_arm_platform_init EXPR "@SystemInit@")" + set_property(GLOBAL APPEND PROPERTY SYMBOL_STEERING_FILE + "--redirect ${symbol}=${expr}\n" + ) + endif() + endif() + endif() + else() + # Handle things like ADDR(.ramfunc) + if(${expr} MATCHES "^[A-Za-z]?ADDR\\(.+\\)") + # string(REGEX REPLACE "^[A-Za-z]?ADDR\\((.+)\\)" "(\\1$$Base)" expr ${expr}) + set(${STRING_STRING} + "${${STRING_STRING}}define image symbol ${symbol} = ${expr};\n" + ) + else() + set(${STRING_STRING} + "${${STRING_STRING}}define exported symbol ${symbol} = ${expr};\n" + ) + endif() + endif() + + set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE) +endfunction() + +include(${CMAKE_CURRENT_LIST_DIR}/../linker_script_common.cmake) + +if(DEFINED STEERING_FILE) + get_property(steering_content GLOBAL PROPERTY SYMBOL_STEERING_FILE) + file(WRITE ${STEERING_FILE} "/* AUTO-GENERATED - Do not modify\n") + file(APPEND ${STEERING_FILE} " * AUTO-GENERATED - All changes will be lost\n") + file(APPEND ${STEERING_FILE} " */\n") + + file(APPEND ${STEERING_FILE} ${steering_content}) +endif() diff --git a/cmake/linker/iar/linker_flags.cmake b/cmake/linker/iar/linker_flags.cmake new file mode 100644 index 0000000000000..f65925ff8a894 --- /dev/null +++ b/cmake/linker/iar/linker_flags.cmake @@ -0,0 +1,14 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +# Override the default CMake's IAR ILINK linker signature + +string(APPEND CMAKE_C_LINK_FLAGS --no-wrap-diagnostics ) + +foreach(lang C CXX ASM) + set(commands "--log modules,libraries,initialization,redirects,sections") + set(CMAKE_${lang}_LINK_EXECUTABLE + " ${commands} -o ") + set(commands) +endforeach() diff --git a/cmake/linker/iar/target.cmake b/cmake/linker/iar/target.cmake new file mode 100644 index 0000000000000..f2326b60491aa --- /dev/null +++ b/cmake/linker/iar/target.cmake @@ -0,0 +1,135 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start") +find_program(CMAKE_LINKER + NAMES ${CROSS_COMPILE}${IAR_LINKER} + PATHS ${TOOLCHAIN_HOME} + PATH_SUFFIXES bin + NO_DEFAULT_PATH +) + +add_custom_target(${IAR_LINKER}) +set(ILINK_THUMB_CALLS_WARNING_SUPPRESSED) +set(IAR_LIB_USED) +function(toolchain_ld_force_undefined_symbols "") +# foreach(symbol ${ARGN}) +# zephyr_link_libraries(--place_holder=${symbol}) +# endforeach() +endfunction() + +# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time +macro(configure_linker_script linker_script_gen linker_pass_define) + set(extra_dependencies ${ARGN}) + set(STEERING_FILE "${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}.xcl") + set(STEERING_FILE_ARG "-DSTEERING_FILE=${STEERING_FILE}") + set(cmake_linker_script_settings + ${PROJECT_BINARY_DIR}/include/generated/ld_script_settings_${linker_pass_define}.cmake + ) + if("${linker_pass_define}" STREQUAL "LINKER_ZEPHYR_PREBUILT") + set(ILINK_THUMB_CALLS_WARNING_SUPPRESSED "--diag_suppress=Lt056") + else() + set(ILINK_THUMB_CALLS_WARNING_SUPPRESSED "") + endif() + if(CONFIG_IAR_LIBC OR CONFIG_IAR_LIBCPP) + set(IAR_LIB_USED "-DIAR_LIBC=1") + else() + set(IAR_LIB_USED "") + endif() + + file(GENERATE OUTPUT ${cmake_linker_script_settings} CONTENT + "set(FORMAT \"$\" CACHE INTERNAL \"\")\n + set(ENTRY \"$\" CACHE INTERNAL \"\")\n + set(MEMORY_REGIONS \"$\" CACHE INTERNAL \"\")\n + set(GROUPS \"$\" CACHE INTERNAL \"\")\n + set(SECTIONS \"$\" CACHE INTERNAL \"\")\n + set(SECTION_SETTINGS \"$\" CACHE INTERNAL \"\")\n + set(SYMBOLS \"$\" CACHE INTERNAL \"\")\n + " + ) + add_custom_command( + OUTPUT ${linker_script_gen} + ${STEERING_FILE} + DEPENDS + ${extra_dependencies} + ${DEVICE_API_LD_TARGET} + COMMAND ${CMAKE_COMMAND} + -C ${DEVICE_API_LINKER_SECTIONS_CMAKE} + -C ${cmake_linker_script_settings} + -DPASS="${linker_pass_define}" + ${STEERING_FILE_ARG} + -DCONFIG_LINKER_LAST_SECTION_ID=${CONFIG_LINKER_LAST_SECTION_ID} + -DCONFIG_LINKER_LAST_SECTION_ID_PATTERN=${CONFIG_LINKER_LAST_SECTION_ID_PATTERN} + -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen} + ${IAR_LIB_USED} + -P ${ZEPHYR_BASE}/cmake/linker/iar/config_file_script.cmake + ) + +endmacro() + +function(toolchain_ld_link_elf) + cmake_parse_arguments( + TOOLCHAIN_LD_LINK_ELF # prefix of output variables + "" # list of names of the boolean arguments + "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments + "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments + ${ARGN} # input args to parse + ) + + foreach(lib ${ZEPHYR_LIBS_PROPERTY}) + list(APPEND ZEPHYR_LIBS_OBJECTS $) + list(APPEND ZEPHYR_LIBS_OBJECTS $) + endforeach() + + set(ILINK_SEMIHOSTING) + set(ILINK_BUFFERED_WRITE) + if(${CONFIG_IAR_SEMIHOSTING}) + set(ILINK_SEMIHOSTING "--semihosting") + endif() + if(${CONFIG_IAR_BUFFERED_WRITE}) + set(ILINK_BUFFERED_WRITE "--redirect __write=__write_buffered") + endif() + + set(ILINK_XCL "-f ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}.xcl") + + set(ILINK_TLS_LIBRARY) + if(${CONFIG_THREAD_LOCAL_STORAGE}) + set(ILINK_TLS_LIBRARY "--threaded_lib=manual") + endif() + + set(ILINK_TZONE_LIBRARY) + # if(${CONFIG_IAR_LIBC}) + # set(ILINK_TZONE_LIBRARY "--timezone_lib") + # endif() + + target_link_libraries( + ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} + ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} + --config=${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} + ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} + --map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} + --log_file=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}.log + + ${ZEPHYR_LIBS_OBJECTS} + kernel + $ + --entry=$ + + ${ILINK_SEMIHOSTING} + ${ILINK_BUFFERED_WRITE} + ${ILINK_TLS_LIBRARY} + ${ILINK_TZONE_LIBRARY} + ${ILINK_THUMB_CALLS_WARNING_SUPPRESSED} + # Do not remove symbols + #--no_remove + ${ILINK_XCL} + + ${TOOLCHAIN_LIBS_OBJECTS} + + ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} + ) +endfunction(toolchain_ld_link_elf) + +include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake) +include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake) diff --git a/cmake/linker_script/common/common-ram.cmake b/cmake/linker_script/common/common-ram.cmake index 5d2f9d18430d6..37b0e86faf1d1 100644 --- a/cmake/linker_script/common/common-ram.cmake +++ b/cmake/linker_script/common/common-ram.cmake @@ -97,14 +97,6 @@ endif() #endif() # -if(CONFIG_ZTEST) - zephyr_iterable_section(NAME ztest_suite_node GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) - zephyr_iterable_section(NAME ztest_suite_stats GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) - zephyr_iterable_section(NAME ztest_unit_test GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) - zephyr_iterable_section(NAME ztest_test_rule GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) - zephyr_iterable_section(NAME ztest_expected_result_entry GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) -endif() - if(CONFIG_ZBUS) zephyr_iterable_section(NAME zbus_channel_observation_mask GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 1) endif() diff --git a/cmake/linker_script/common/common-rom.cmake b/cmake/linker_script/common/common-rom.cmake index 868e9f382d93c..85a258996b4e9 100644 --- a/cmake/linker_script/common/common-rom.cmake +++ b/cmake/linker_script/common/common-rom.cmake @@ -91,6 +91,10 @@ zephyr_linker_section_configure( KEEP SORT NAME ) +if(CONFIG_NETWORKING) + zephyr_iterable_section(NAME net_l3_register KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) +endif() + if(CONFIG_NET_SOCKETS) zephyr_iterable_section(NAME net_socket_register KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) endif() @@ -234,6 +238,13 @@ if(CONFIG_USBD_MSC_CLASS) zephyr_iterable_section(NAME usbd_msc_lun KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) endif() +if(CONFIG_ZTEST) + zephyr_iterable_section(NAME ztest_expected_result_entry KVMA RAM_REGION GROUP RODATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) + zephyr_iterable_section(NAME ztest_suite_node KVMA RAM_REGION GROUP RODATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) + zephyr_iterable_section(NAME ztest_unit_test KVMA RAM_REGION GROUP RODATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) + zephyr_iterable_section(NAME ztest_test_rule KVMA RAM_REGION GROUP RODATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) +endif() + if(CONFIG_ZBUS) zephyr_iterable_section(NAME zbus_channel KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) zephyr_iterable_section(NAME zbus_observer KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) diff --git a/cmake/llext-edk.cmake b/cmake/llext-edk.cmake index e78498c784525..e4add3ebb2186 100644 --- a/cmake/llext-edk.cmake +++ b/cmake/llext-edk.cmake @@ -11,32 +11,23 @@ # directories (build/zephyr, zephyr base, west top dir and application source # dir), to avoid leaking any information about the host system. # -# The following arguments are expected: -# - llext_edk_name: Name of the extension, used to name the tarball and the -# install directory variable for Makefile. -# - INTERFACE_INCLUDE_DIRECTORIES: List of include directories to copy headers -# from. It should simply be the INTERFACE_INCLUDE_DIRECTORIES property of the -# zephyr_interface target. -# - llext_edk_file: Output file name for the tarball. -# - llext_edk_cflags: Flags to be used for source compile commands. -# - ZEPHYR_BASE: Path to the zephyr base directory. -# - WEST_TOPDIR: Path to the west top directory. -# - APPLICATION_SOURCE_DIR: Path to the application source directory. -# - PROJECT_BINARY_DIR: Path to the project binary build directory. -# - CONFIG_LLEXT_EDK_USERSPACE_ONLY: Whether to copy syscall headers from the -# edk directory. This is necessary when building an extension that only -# supports userspace, as the syscall headers are regenerated in the edk -# directory. +# The script expects a build_info.yml file in the project binary directory. +# This file should contain the following entries: +# - cmake application source-dir +# - cmake llext-edk cflags +# - cmake llext-edk file +# - cmake llext-edk include-dirs +# - west topdir cmake_minimum_required(VERSION 3.20.0) -if (CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) - message(FATAL_ERROR - "The LLEXT EDK is not compatible with CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID.") -endif() +# initialize the same paths as the main CMakeLists.txt for consistency +set(PROJECT_BINARY_DIR ${CMAKE_BINARY_DIR}) +set(ZEPHYR_BASE ${CMAKE_CURRENT_LIST_DIR}/../) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules") -set(llext_edk ${PROJECT_BINARY_DIR}/${llext_edk_name}) -set(llext_edk_inc ${llext_edk}/include) +include(extensions) +include(yaml) # Usage: # relative_dir( ) @@ -89,12 +80,92 @@ function(relative_dir dir relative_out bindir_out) endif() endfunction() +# Usage: +# edk_escape( ) +# +# Escape problematic characters in the string and store the result in +# . The escaping is done to make the string suitable for . +function(edk_escape target str_in str_out) + string(REPLACE "\\" "\\\\" str_escaped "${str_in}") + string(REPLACE "\"" "\\\"" str_escaped "${str_escaped}") + set(${str_out} "${str_escaped}" PARENT_SCOPE) +endfunction() + +# Usage: +# edk_write_header() +# +# Initialize the file associated with and write its header. +function(edk_write_header target) + file(WRITE ${edk_file_${target}} "") +endfunction() + +# Usage: +# edk_write_comment( ) +# +# Write to the file associated with the string as a comment. +function(edk_write_comment target text) + file(APPEND ${edk_file_${target}} "\n# ${text}\n") +endfunction() + +# Usage: +# edk_write_var( ) +# +# Write to the file associated with an entry where is +# assigned the value . +function(edk_write_var target var_name var_value) + if(target STREQUAL "CMAKE") + # CMake: export assignments of the form: + # + # set(var "value1;value2;...") + # + set(DASHIMACROS "-imacros\${CMAKE_CURRENT_LIST_DIR}/") + set(DASHI "-I\${CMAKE_CURRENT_LIST_DIR}/") + edk_escape(${target} "${var_value}" var_value) + string(CONFIGURE "${var_value}" exp_var_value @ONLY) + # The list is otherwise exported verbatim, surrounded by quotes. + file(APPEND ${edk_file_${target}} "set(${var_name} \"${exp_var_value}\")\n") + elseif(target STREQUAL "MAKEFILE") + # Makefile: export assignments of the form: + # + # var = "value1" "value2" ... + # + set(DASHIMACROS "-imacros\$(${install_dir_var})/") + set(DASHI "-I\$(${install_dir_var})/") + edk_escape(${target} "${var_value}" var_value) + string(CONFIGURE "${var_value}" exp_var_value @ONLY) + # Each element of the list is wrapped in quotes and is separated by a space. + list(JOIN exp_var_value "\" \"" exp_var_value_str) + file(APPEND ${edk_file_${target}} "${var_name} = \"${exp_var_value_str}\"\n") + endif() +endfunction() + + + +# read in computed build configuration +import_kconfig(CONFIG ${PROJECT_BINARY_DIR}/.config) + +if (CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) + message(FATAL_ERROR + "The LLEXT EDK is not compatible with CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID.") +endif() + +set(build_info_file ${PROJECT_BINARY_DIR}/../build_info.yml) +yaml_load(FILE ${build_info_file} NAME build_info) + +yaml_get(llext_edk_cflags NAME build_info KEY cmake llext-edk cflags) +yaml_get(llext_edk_file NAME build_info KEY cmake llext-edk file) +yaml_get(INTERFACE_INCLUDE_DIRECTORIES NAME build_info KEY cmake llext-edk include-dirs) +yaml_get(APPLICATION_SOURCE_DIR NAME build_info KEY cmake application source-dir) +yaml_get(WEST_TOPDIR NAME build_info KEY west topdir) + +set(llext_edk_name ${CONFIG_LLEXT_EDK_NAME}) +set(llext_edk ${PROJECT_BINARY_DIR}/${llext_edk_name}) +set(llext_edk_inc ${llext_edk}/include) + string(REGEX REPLACE "[^a-zA-Z0-9]" "_" llext_edk_name_sane ${llext_edk_name}) string(TOUPPER ${llext_edk_name_sane} llext_edk_name_sane) set(install_dir_var "${llext_edk_name_sane}_INSTALL_DIR") -separate_arguments(llext_edk_cflags NATIVE_COMMAND ${llext_edk_cflags}) - set(make_relative FALSE) foreach(flag ${llext_edk_cflags}) if (flag STREQUAL "-imacros") @@ -106,11 +177,9 @@ foreach(flag ${llext_edk_cflags}) relative_dir(${parent} dest bindir) cmake_path(RELATIVE_PATH dest BASE_DIRECTORY ${llext_edk} OUTPUT_VARIABLE dest_rel) if(bindir) - list(APPEND imacros_gen_make "-imacros\$(${install_dir_var})/${dest_rel}/${name}") - list(APPEND imacros_gen_cmake "-imacros\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}/${name}") + list(APPEND imacros_gen "@DASHIMACROS@${dest_rel}/${name}") else() - list(APPEND imacros_make "-imacros\$(${install_dir_var})/${dest_rel}/${name}") - list(APPEND imacros_cmake "-imacros\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}/${name}") + list(APPEND imacros "@DASHIMACROS@${dest_rel}/${name}") endif() else() list(APPEND new_cflags ${flag}) @@ -118,12 +187,10 @@ foreach(flag ${llext_edk_cflags}) endforeach() set(llext_edk_cflags ${new_cflags}) -list(APPEND base_flags_make ${llext_edk_cflags} ${imacros_make}) -list(APPEND base_flags_cmake ${llext_edk_cflags} ${imacros_cmake}) +list(APPEND base_flags ${llext_edk_cflags} ${imacros}) -separate_arguments(include_dirs NATIVE_COMMAND ${INTERFACE_INCLUDE_DIRECTORIES}) file(MAKE_DIRECTORY ${llext_edk_inc}) -foreach(dir ${include_dirs}) +foreach(dir ${INTERFACE_INCLUDE_DIRECTORIES}) if (NOT EXISTS ${dir}) continue() endif() @@ -137,61 +204,55 @@ foreach(dir ${include_dirs}) cmake_path(RELATIVE_PATH dest BASE_DIRECTORY ${llext_edk} OUTPUT_VARIABLE dest_rel) if(bindir) - list(APPEND inc_gen_flags_make "-I\$(${install_dir_var})/${dest_rel}") - list(APPEND inc_gen_flags_cmake "-I\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}") + list(APPEND gen_inc_flags "@DASHI@${dest_rel}") else() - list(APPEND inc_flags_make "-I\$(${install_dir_var})/${dest_rel}") - list(APPEND inc_flags_cmake "-I\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}") + list(APPEND inc_flags "@DASHI@${dest_rel}") endif() - list(APPEND all_inc_flags_make "-I\$(${install_dir_var})/${dest_rel}") - list(APPEND all_inc_flags_cmake "-I\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}") + list(APPEND all_inc_flags "@DASHI@${dest_rel}") endforeach() +list(APPEND all_flags ${base_flags} ${imacros_gen} ${all_inc_flags}) + if(CONFIG_LLEXT_EDK_USERSPACE_ONLY) # Copy syscall headers from edk directory, as they were regenerated there. file(COPY ${PROJECT_BINARY_DIR}/edk/include/generated/ DESTINATION ${llext_edk_inc}/zephyr/include/generated) endif() -# Generate flags for Makefile -list(APPEND all_flags_make ${base_flags_make} ${imacros_gen_make} ${all_inc_flags_make}) -list(JOIN all_flags_make " " all_flags_str) -file(WRITE ${llext_edk}/Makefile.cflags "LLEXT_CFLAGS = ${all_flags_str}") - -list(JOIN all_inc_flags_make " " all_inc_flags_str) -file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_ALL_INCLUDE_CFLAGS = ${all_inc_flags_str}") - -list(JOIN inc_flags_make " " inc_flags_str) -file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_INCLUDE_CFLAGS = ${inc_flags_str}") - -list(JOIN inc_gen_flags_make " " inc_gen_flags_str) -file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_GENERATED_INCLUDE_CFLAGS = ${inc_gen_flags_str}") - -list(JOIN base_flags_make " " base_flags_str) -file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_BASE_CFLAGS = ${base_flags_str}") - -list(JOIN imacros_gen_make " " imacros_gen_str) -file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_GENERATED_IMACROS_CFLAGS = ${imacros_gen_str}") - -# Generate flags for CMake -list(APPEND all_flags_cmake ${base_flags_cmake} ${imacros_gen_cmake} ${all_inc_flags_cmake}) -file(WRITE ${llext_edk}/cmake.cflags "set(LLEXT_CFLAGS ${all_flags_cmake})") - -file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_ALL_INCLUDE_CFLAGS ${all_inc_flags_cmake})") +# +# Generate the EDK flags files +# -file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_INCLUDE_CFLAGS ${inc_flags_cmake})") +set(edk_targets MAKEFILE CMAKE) +set(edk_file_MAKEFILE ${llext_edk}/Makefile.cflags) +set(edk_file_CMAKE ${llext_edk}/cmake.cflags) -file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_GENERATED_INCLUDE_CFLAGS ${inc_gen_flags_cmake})") +foreach(target ${edk_targets}) + edk_write_header(${target}) -file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_BASE_CFLAGS ${base_flags_cmake})") + edk_write_comment(${target} "Compile flags") + edk_write_var(${target} "LLEXT_CFLAGS" "${all_flags}") + edk_write_var(${target} "LLEXT_ALL_INCLUDE_CFLAGS" "${all_inc_flags}") + edk_write_var(${target} "LLEXT_INCLUDE_CFLAGS" "${inc_flags}") + edk_write_var(${target} "LLEXT_GENERATED_INCLUDE_CFLAGS" "${gen_inc_flags}") + edk_write_var(${target} "LLEXT_BASE_CFLAGS" "${base_flags}") + edk_write_var(${target} "LLEXT_GENERATED_IMACROS_CFLAGS" "${imacros_gen}") +endforeach() -file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_GENERATED_IMACROS_CFLAGS ${imacros_gen_cmake})") +if(CONFIG_LLEXT_EDK_FORMAT_TAR_XZ) + set(llext_edk_format FORMAT gnutar COMPRESSION XZ) +elseif(CONFIG_LLEXT_EDK_FORMAT_TAR_ZSTD) + set(llext_edk_format FORMAT gnutar COMPRESSION Zstd) +elseif(CONFIG_LLEXT_EDK_FORMAT_ZIP) + set(llext_edk_format FORMAT zip) +else() + message(FATAL_ERROR "Unsupported LLEXT_EDK_FORMAT choice") +endif() # Generate the tarball file(ARCHIVE_CREATE OUTPUT ${llext_edk_file} PATHS ${llext_edk} - FORMAT gnutar - COMPRESSION XZ + ${llext_edk_format} ) file(REMOVE_RECURSE ${llext_edk}) diff --git a/cmake/mcuboot.cmake b/cmake/mcuboot.cmake index b6ab9dd503401..2767af807c124 100644 --- a/cmake/mcuboot.cmake +++ b/cmake/mcuboot.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2023 Nordic Semiconductor ASA +# Copyright (c) 2020-2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 # This file includes extra build system logic that is enabled when @@ -52,23 +52,8 @@ function(zephyr_mcuboot_tasks) endif() endforeach() - # Find imgtool. Even though west is installed, imgtool might not be. - # The user may also have a custom manifest which doesn't include - # MCUboot. - # - # Therefore, go with an explicitly installed imgtool first, falling - # back on mcuboot/scripts/imgtool.py. - if(IMGTOOL) - set(imgtool_path "${IMGTOOL}") - elseif(DEFINED ZEPHYR_MCUBOOT_MODULE_DIR) - set(IMGTOOL_PY "${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts/imgtool.py") - if(EXISTS "${IMGTOOL_PY}") - set(imgtool_path "${IMGTOOL_PY}") - endif() - endif() - # No imgtool, no signed binaries. - if(NOT DEFINED imgtool_path) + if(NOT DEFINED IMGTOOL) message(FATAL_ERROR "Can't sign images for MCUboot: can't find imgtool. To fix, install imgtool with pip3, or add the mcuboot repository to the west manifest and ensure it has a scripts/imgtool.py file.") return() endif() @@ -94,7 +79,7 @@ function(zephyr_mcuboot_tasks) endif() # Basic 'imgtool sign' command with known image information. - set(imgtool_sign ${PYTHON_EXECUTABLE} ${imgtool_path} sign + set(imgtool_sign ${PYTHON_EXECUTABLE} ${IMGTOOL} sign --version ${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION} --header-size ${CONFIG_ROM_START_OFFSET} --slot-size ${slot_size}) @@ -198,8 +183,18 @@ function(zephyr_mcuboot_tasks) set(BYPRODUCT_KERNEL_SIGNED_HEX_NAME "${output}.signed.hex" CACHE FILEPATH "Signed kernel hex file" FORCE ) - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND - ${imgtool_sign} ${imgtool_args} ${output}.hex ${output}.signed.hex) + + if(NOT "${keyfile_enc}" STREQUAL "") + # When encryption is enabled, set the encrypted bit when signing the image but do not + # encrypt the data, this means that when the image is moved out of the primary into the + # secondary, it will be encrypted rather than being in unencrypted + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${imgtool_sign} ${imgtool_args} --encrypt "${keyfile_enc}" --clear + ${output}.hex ${output}.signed.hex) + else() + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${imgtool_sign} ${imgtool_args} ${output}.hex ${output}.signed.hex) + endif() if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE) list(APPEND byproducts ${output}.signed.confirmed.hex) diff --git a/cmake/modules/FindDeprecated.cmake b/cmake/modules/FindDeprecated.cmake index df0b6a3df51bf..8030c75953173 100644 --- a/cmake/modules/FindDeprecated.cmake +++ b/cmake/modules/FindDeprecated.cmake @@ -53,16 +53,6 @@ if("CROSS_COMPILE" IN_LIST Deprecated_FIND_COMPONENTS) endif() endif() -if("XTOOLS" IN_LIST Deprecated_FIND_COMPONENTS) - list(REMOVE_ITEM Deprecated_FIND_COMPONENTS XTOOLS) - # This code was deprecated after Zephyr v3.3.0 - # When removing support for `xtools`, remember to also remove: - # cmake/toolchain/xtools (folder with files) - # doc/develop/toolchains/crosstool_ng.rst and update the index.rst file. - message(DEPRECATION "XTOOLS toolchain variant is deprecated. " - "Please set ZEPHYR_TOOLCHAIN_VARIANT to 'zephyr'") -endif() - if("SPARSE" IN_LIST Deprecated_FIND_COMPONENTS) list(REMOVE_ITEM Deprecated_FIND_COMPONENTS SPARSE) # This code was deprecated after Zephyr v3.2.0 diff --git a/cmake/modules/FindGnuLd.cmake b/cmake/modules/FindGnuLd.cmake index 9ee42cc82fe2f..937218ecc1bf3 100644 --- a/cmake/modules/FindGnuLd.cmake +++ b/cmake/modules/FindGnuLd.cmake @@ -87,10 +87,11 @@ if(GNULD_LINKER) # - "GNU ld (GNU Binutils for Ubuntu) 2.34" # - "GNU ld (Zephyr SDK 0.15.2) 2.38" # - "GNU ld (Gentoo 2.39 p5) 2.39.0" + # - "GNU ld version 2.17.50.0.9 20070103" string(REGEX MATCH - "GNU ld \\(.+\\) ([0-9]+[.][0-9]+[.]?[0-9]*).*" + "GNU ld (\\(.+\\)|version) ([0-9]+[.][0-9]+[.]?[0-9]*).*" out_var ${gnuld_version_output}) - set(GNULD_VERSION_STRING ${CMAKE_MATCH_1} CACHE STRING "GNU ld version" FORCE) + set(GNULD_VERSION_STRING ${CMAKE_MATCH_2} CACHE STRING "GNU ld version" FORCE) endif() endif() diff --git a/cmake/modules/FindHostTools.cmake b/cmake/modules/FindHostTools.cmake index 1dfce4d3d4a12..f0954a26b7505 100644 --- a/cmake/modules/FindHostTools.cmake +++ b/cmake/modules/FindHostTools.cmake @@ -61,9 +61,16 @@ find_program(OPENOCD openocd) # bossac is an optional dependency find_program(BOSSAC bossac) -# imgtool is an optional dependency (the build may also fall back to scripts/imgtool.py -# in the mcuboot repository if that's present in some cases) -find_program(IMGTOOL imgtool) +# imgtool is an optional dependency (prefer the version that is in the mcuboot repository, if +# present and a user has not specified a different version) +zephyr_get(IMGTOOL SYSBUILD LOCAL) +find_program(IMGTOOL imgtool.py HINTS ${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts/ NAMES imgtool NAMES_PER_DIR) + +# winpty is an optional dependency +find_program(PTY_INTERFACE winpty) +if("${PTY_INTERFACE}" STREQUAL "PTY_INTERFACE-NOTFOUND") + set(PTY_INTERFACE "") +endif() # Default to the host system's toolchain if we are targeting a host based target if((${BOARD_DIR} MATCHES "boards\/native") OR ("${ARCH}" STREQUAL "posix") diff --git a/cmake/modules/boards.cmake b/cmake/modules/boards.cmake index 2b78845482a23..3f086dca94809 100644 --- a/cmake/modules/boards.cmake +++ b/cmake/modules/boards.cmake @@ -357,3 +357,4 @@ build_info(board name VALUE ${BOARD}) string(REGEX REPLACE "^/" "" qualifiers "${BOARD_QUALIFIERS}") build_info(board qualifiers VALUE ${qualifiers}) build_info(board revision VALUE ${BOARD_REVISION}) +build_info(board path PATH ${BOARD_DIRECTORIES}) diff --git a/cmake/modules/configuration_files.cmake b/cmake/modules/configuration_files.cmake index ff7a172445c38..fe1ff3bf16fa4 100644 --- a/cmake/modules/configuration_files.cmake +++ b/cmake/modules/configuration_files.cmake @@ -47,10 +47,6 @@ else() if(${CONF_FILE_LENGTH} EQUAL 1) get_filename_component(CONF_FILE_NAME ${CONF_FILE} NAME) if(${CONF_FILE_NAME} MATCHES "prj_(.*).conf") - set(CONF_FILE_BUILD_TYPE ${CMAKE_MATCH_1}) - zephyr_file(CONF_FILES ${APPLICATION_CONFIG_DIR}/boards KCONF CONF_FILE - BUILD ${CONF_FILE_BUILD_TYPE} - ) set(CONF_FILE_FORCE_CACHE FORCE) endif() endif() diff --git a/cmake/modules/dts.cmake b/cmake/modules/dts.cmake index 737e083aa5720..08ed8db083d2c 100644 --- a/cmake/modules/dts.cmake +++ b/cmake/modules/dts.cmake @@ -327,8 +327,7 @@ execute_process( COMMAND_ERROR_IS_FATAL ANY ) zephyr_file_copy(${DEVICETREE_GENERATED_H}.new ${DEVICETREE_GENERATED_H} ONLY_IF_DIFFERENT) -file(REMOVE ${ZEPHYR_DTS}.new ${DEVICETREE_GENERATED_H}.new) -message(STATUS "Generated zephyr.dts: ${ZEPHYR_DTS}") +file(REMOVE ${DEVICETREE_GENERATED_H}.new) message(STATUS "Generated devicetree_generated.h: ${DEVICETREE_GENERATED_H}") # diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index ab1f6f59cda13..51726a3b7ec04 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -336,6 +336,12 @@ function(process_flags lang input output) foreach(flag ${${input}}) set(is_compile_lang_generator_expression 0) + # SHELL is used to avoid de-duplication, but when process flags + # then this tag must be removed to return real compile/linker flags. + if(flag MATCHES "^SHELL:[ ]*(.*)") + separate_arguments(flag UNIX_COMMAND ${CMAKE_MATCH_1}) + endif() + foreach(l ${languages}) if(flag MATCHES ":([^>]+)>") set(updated_flag ${CMAKE_MATCH_1}) @@ -356,11 +362,6 @@ function(process_flags lang input output) endforeach() if(NOT is_compile_lang_generator_expression) - # SHELL is used to avoid de-duplication, but when process flags - # then this tag must be removed to return real compile/linker flags. - if(flag MATCHES "SHELL:[ ]*(.*)") - separate_arguments(flag UNIX_COMMAND ${CMAKE_MATCH_1}) - endif() # Flags may be placed inside generator expression, therefore any flag # which is not already a generator expression must have commas converted. if(NOT flag MATCHES "\\\$<.*>") @@ -1452,7 +1453,7 @@ endmacro() # - PHDR [program_header]: add program header. Used on Xtensa platforms. function(zephyr_code_relocate) set(options NOCOPY NOKEEP) - set(single_args LIBRARY LOCATION PHDR) + set(single_args LIBRARY LOCATION PHDR FILTER) set(multi_args FILES) cmake_parse_arguments(CODE_REL "${options}" "${single_args}" "${multi_args}" ${ARGN}) @@ -1521,7 +1522,7 @@ function(zephyr_code_relocate) if(CODE_REL_PHDR) set(CODE_REL_LOCATION "${CODE_REL_LOCATION}\ :${CODE_REL_PHDR}") endif() - # We use the "|" character to separate code relocation directives, instead of + # Each code relocation directive is placed on an independent line, instead of # using set_property(APPEND) to produce a ";"-separated CMake list. This way, # each directive can embed multiple CMake lists, representing flags and files, # the latter of which can come from generator expressions. @@ -1529,7 +1530,7 @@ function(zephyr_code_relocate) PROPERTY INTERFACE_SOURCES) set_property(TARGET code_data_relocation_target PROPERTY INTERFACE_SOURCES - "${code_rel_str}|${CODE_REL_LOCATION}:${flag_list}:${file_list}") + "${code_rel_str}\n${CODE_REL_LOCATION}:${flag_list}:${file_list},${CODE_REL_FILTER}") endfunction() # Usage: @@ -1602,8 +1603,6 @@ endfunction() # - Build string with cpuset removed in addition # - Build string with soc removed in addition # -# If BUILD is supplied, then build type will be appended to each entry in the -# list above. # If REVISION is supplied or obtained as system wide setting a build string # with the sanitized revision string will be added in addition to the # non-revisioned entry for each entry. @@ -1614,12 +1613,10 @@ endfunction() # [SHORT ] # [BOARD_QUALIFIERS ] # [BOARD_REVISION ] -# [BUILD ] # [MERGE [REVERSE]] # ) # zephyr_build_string( # BOARD_QUALIFIERS -# [BUILD ] # [MERGE [REVERSE]] # ) # @@ -1627,18 +1624,17 @@ endfunction() # SHORT : Output variable where the shortened build string will be returned. # BOARD : Board name to use when creating the build string. # BOARD_REVISION : Board revision to use when creating the build string. -# BUILD : Build type to use when creating the build string. # MERGE: Return a list of build strings instead of a single build string. # REVERSE: Reverse the list before returning it. # # Examples # calling -# zephyr_build_string(build_string BOARD alpha BUILD debug) -# will return the string `alpha_debug` in `build_string` parameter. +# zephyr_build_string(build_string BOARD alpha) +# will return the string `alpha` in `build_string` parameter. # # calling -# zephyr_build_string(build_string BOARD alpha BOARD_REVISION 1.0.0 BUILD debug) -# will return the string `alpha_1_0_0_debug` in `build_string` parameter. +# zephyr_build_string(build_string BOARD alpha BOARD_REVISION 1.0.0) +# will return the string `alpha_1_0_0` in `build_string` parameter. # # calling # zephyr_build_string(build_string BOARD alpha BOARD_QUALIFIERS /soc/bar) @@ -1661,7 +1657,7 @@ endfunction() # function(zephyr_build_string outvar) set(options MERGE REVERSE) - set(single_args BOARD BOARD_QUALIFIERS BOARD_REVISION BUILD SHORT) + set(single_args BOARD BOARD_QUALIFIERS BOARD_REVISION SHORT) cmake_parse_arguments(BUILD_STR "${options}" "${single_args}" "" ${ARGN}) if(BUILD_STR_UNPARSED_ARGUMENTS) @@ -1695,10 +1691,10 @@ function(zephyr_build_string outvar) string(REPLACE "/" ";" str_segment_list "${BUILD_STR_BOARD_QUALIFIERS}") string(REPLACE "." "_" revision_string "${BUILD_STR_BOARD_REVISION}") - string(JOIN "_" ${outvar} ${BUILD_STR_BOARD} ${str_segment_list} ${revision_string} ${BUILD_STR_BUILD}) + string(JOIN "_" ${outvar} ${BUILD_STR_BOARD} ${str_segment_list} ${revision_string}) if(BUILD_STR_MERGE) - string(JOIN "_" variant_string ${BUILD_STR_BOARD} ${str_segment_list} ${BUILD_STR_BUILD}) + string(JOIN "_" variant_string ${BUILD_STR_BOARD} ${str_segment_list}) if(NOT "${variant_string}" IN_LIST ${outvar}) list(APPEND ${outvar} "${variant_string}") @@ -1714,10 +1710,10 @@ function(zephyr_build_string outvar) string(REGEX REPLACE "^/[^/]*(.*)" "\\1" shortened_qualifiers "${BOARD_QUALIFIERS}") string(REPLACE "/" ";" str_short_segment_list "${shortened_qualifiers}") string(JOIN "_" ${BUILD_STR_SHORT} - ${BUILD_STR_BOARD} ${str_short_segment_list} ${revision_string} ${BUILD_STR_BUILD} + ${BUILD_STR_BOARD} ${str_short_segment_list} ${revision_string} ) if(BUILD_STR_MERGE) - string(JOIN "_" variant_string ${BUILD_STR_BOARD} ${str_short_segment_list} ${BUILD_STR_BUILD}) + string(JOIN "_" variant_string ${BUILD_STR_BOARD} ${str_short_segment_list}) if(NOT "${variant_string}" IN_LIST ${BUILD_STR_SHORT}) list(APPEND ${BUILD_STR_SHORT} "${variant_string}") @@ -2663,7 +2659,7 @@ endfunction() # Usage: # zephyr_file(CONF_FILES [DTS ] [KCONF ] # [BOARD [BOARD_REVISION ] | NAMES ...] -# [BUILD ] [SUFFIX ] [REQUIRED] +# [SUFFIX ] [REQUIRED] # ) # # CONF_FILES : Find all configuration files in the list of paths and @@ -2690,10 +2686,6 @@ endfunction() # DTS : List to append DTS overlay files in to # KCONF : List to append Kconfig fragment files in to # DEFCONF : List to append _defconfig files in to -# BUILD : Build type to include for search. -# For example: -# BUILD debug, will look for _debug.conf -# and _debug.overlay, instead of .conf # SUFFIX : Suffix name to check for instead of the default name # but with a fallback to the default name if not found. # For example: @@ -2713,7 +2705,7 @@ Please provide one of following: APPLICATION_ROOT, CONF_FILES") set(single_args APPLICATION_ROOT BASE_DIR) elseif(${ARGV0} STREQUAL CONF_FILES) set(options QUALIFIERS REQUIRED) - set(single_args BOARD BOARD_REVISION BOARD_QUALIFIERS DTS KCONF DEFCONFIG BUILD SUFFIX) + set(single_args BOARD BOARD_REVISION BOARD_QUALIFIERS DTS KCONF DEFCONFIG SUFFIX) set(multi_args CONF_FILES NAMES) endif() @@ -2792,13 +2784,11 @@ Relative paths are only allowed with `-D${ARGV1}=`") BOARD ${ZFILE_BOARD} BOARD_REVISION ${ZFILE_BOARD_REVISION} BOARD_QUALIFIERS ${ZFILE_BOARD_QUALIFIERS} - BUILD ${ZFILE_BUILD} MERGE REVERSE ) else() zephyr_build_string(filename_list BOARD_QUALIFIERS ${ZFILE_BOARD_QUALIFIERS} - BUILD ${ZFILE_BUILD} MERGE REVERSE ) endif() @@ -2834,10 +2824,6 @@ Relative paths are only allowed with `-D${ARGV1}=`") list(APPEND found_dts_files ${test_file_0}) list(APPEND found_dts_files ${test_file_1}) - if(DEFINED ZFILE_BUILD) - set(deprecated_file_found y) - endif() - if(ZFILE_NAMES) break() endif() @@ -2885,10 +2871,6 @@ Relative paths are only allowed with `-D${ARGV1}=`") list(APPEND found_conf_files ${test_file_0}) list(APPEND found_conf_files ${test_file_1}) - if(DEFINED ZFILE_BUILD) - set(deprecated_file_found y) - endif() - if(ZFILE_NAMES) break() endif() @@ -2926,11 +2908,6 @@ Relative paths are only allowed with `-D${ARGV1}=`") ) endif() - if(deprecated_file_found) - message(DEPRECATION "prj_.conf was deprecated after Zephyr 3.5," - " you should switch to using -DFILE_SUFFIX instead") - endif() - if(ZFILE_DEFCONFIG) set(found_defconf_files) foreach(path ${ZFILE_CONF_FILES}) @@ -3251,8 +3228,9 @@ function(zephyr_get variable) set(sysbuild_global_${var}) endif() - if(TARGET snippets_scope) - get_property(snippets_${var} TARGET snippets_scope PROPERTY ${var}) + zephyr_scope_exists(scope_defined snippets) + if(scope_defined) + zephyr_get_scoped(snippets_${var} snippets ${var}) endif() endforeach() @@ -3317,11 +3295,54 @@ endfunction(zephyr_get variable) # : Name of new scope. # function(zephyr_create_scope scope) - if(TARGET ${scope}_scope) + zephyr_scope_exists(scope_defined ${scope}) + if(scope_defined) message(FATAL_ERROR "zephyr_create_scope(${scope}) already exists.") endif() - add_custom_target(${scope}_scope) + set_property(GLOBAL PROPERTY scope:${scope} TRUE) +endfunction() + +# Usage: +# zephyr_scope_exists( ) +# +# Check if exists. +# +# : Variable to set with result. +# TRUE if scope exists, FALSE otherwise. +# : Name of scope. +# +function(zephyr_scope_exists result scope) + get_property(scope_defined GLOBAL PROPERTY scope:${scope}) + if(scope_defined) + set(${result} TRUE PARENT_SCOPE) + else() + set(${result} FALSE PARENT_SCOPE) + endif() +endfunction() + +# Usage: +# zephyr_get_scoped( ) +# +# Get the current value of in a specific , as defined by a +# previous zephyr_set() call. The value will be stored in the var. +# +# : Variable to store the value in +# : Scope for the variable look up +# : Name to look up in the specific scope +# +function(zephyr_get_scoped output scope var) + zephyr_scope_exists(scope_defined ${scope}) + if(NOT scope_defined) + message(FATAL_ERROR "zephyr_get_scoped(): scope ${scope} doesn't exists.") + endif() + + get_property(value GLOBAL PROPERTY ${scope}_scope:${var}) + if(DEFINED value) + set(${output} "${value}" PARENT_SCOPE) + else() + unset(${output} PARENT_SCOPE) + endif() endfunction() # Usage: @@ -3342,7 +3363,8 @@ function(zephyr_set variable) zephyr_check_arguments_required_all(zephyr_set SET_VAR SCOPE) - if(NOT TARGET ${SET_VAR_SCOPE}_scope) + zephyr_scope_exists(scope_defined ${SET_VAR_SCOPE}) + if(NOT scope_defined) message(FATAL_ERROR "zephyr_set(... SCOPE ${SET_VAR_SCOPE}) doesn't exists.") endif() @@ -3350,8 +3372,8 @@ function(zephyr_set variable) set(property_args APPEND) endif() - set_property(TARGET ${SET_VAR_SCOPE}_scope ${property_args} - PROPERTY ${variable} ${SET_VAR_UNPARSED_ARGUMENTS} + set_property(GLOBAL ${property_args} PROPERTY + ${SET_VAR_SCOPE}_scope:${variable} ${SET_VAR_UNPARSED_ARGUMENTS} ) endfunction() @@ -3658,11 +3680,11 @@ function(topological_sort) endfunction() # Usage: -# build_info(... VALUE ... ) -# build_info(... PATH ... ) +# build_info(... VALUE ...) +# build_info(... PATH ...) # -# This function populates updates the build_info.yml info file with exchangable build information -# related to the current build. +# This function populates the build_info.yml info file with exchangable build +# information related to the current build. # # Example: # build_info(devicetree files VALUE file1.dts file2.dts file3.dts) @@ -3692,6 +3714,14 @@ function(build_info) message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}(...) missing a required argument: VALUE or PATH") endif() + string(GENEX_STRIP "${arg_list}" arg_list_no_genexes) + if (NOT "${arg_list}" STREQUAL "${arg_list_no_genexes}") + if (convert_path) + message(FATAL_ERROR "build_info: generator expressions unsupported on PATH entries") + endif() + set(genex_flag GENEX) + endif() + yaml_context(EXISTS NAME build_info result) if(NOT result) yaml_load(FILE ${ZEPHYR_BASE}/scripts/schemas/build-schema.yml NAME build_info_schema) @@ -3734,7 +3764,7 @@ function(build_info) endif() endif() - yaml_set(NAME build_info KEY cmake ${keys} ${type} "${values}") + yaml_set(NAME build_info KEY cmake ${keys} ${type} "${values}" ${genex_flag}) endfunction() ######################################################## @@ -5157,7 +5187,11 @@ function(zephyr_iterable_section) endif() if(SECTION_NUMERIC) - set(INPUT "._${SECTION_NAME}.static.*_?_*;._${SECTION_NAME}.static.*_??_*") + set(INPUT "._${SECTION_NAME}.static.*_?_*;" + "._${SECTION_NAME}.static.*_??_*;" + "._${SECTION_NAME}.static.*_???_*;" + "._${SECTION_NAME}.static.*_????_*;" + "._${SECTION_NAME}.static.*_?????_*") else() set(INPUT "._${SECTION_NAME}.static.*") endif() @@ -5591,7 +5625,7 @@ function(add_llext_target target_name) if(CONFIG_LLEXT_TYPE_ELF_OBJECT) # Create an object library to compile the source file - add_library(${llext_lib_target} OBJECT ${source_files}) + add_library(${llext_lib_target} EXCLUDE_FROM_ALL OBJECT ${source_files}) set(llext_lib_output $) elseif(CONFIG_LLEXT_TYPE_ELF_RELOCATABLE) @@ -5607,6 +5641,7 @@ function(add_llext_target target_name) target_link_options(${llext_lib_target} PRIVATE $) set_target_properties(${llext_lib_target} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/llext SUFFIX ${CMAKE_C_OUTPUT_EXTENSION}) set(llext_lib_output $) @@ -5618,7 +5653,10 @@ function(add_llext_target target_name) elseif(CONFIG_LLEXT_TYPE_ELF_SHAREDLIB) # Create a shared library - add_library(${llext_lib_target} SHARED ${source_files}) + add_library(${llext_lib_target} EXCLUDE_FROM_ALL SHARED ${source_files}) + set_target_properties(${llext_lib_target} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/llext + ) set(llext_lib_output $) # Add the llext flags to the linking step as well @@ -5647,11 +5685,14 @@ function(add_llext_target target_name) zephyr_generated_headers ) + # Make sure the intermediate output directory exists. + file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/llext) + # Set up an intermediate processing step between compilation and packaging # to be used to support POST_BUILD commands on targets that do not use a # dynamic library. set(llext_proc_target ${target_name}_llext_proc) - set(llext_pkg_input ${PROJECT_BINARY_DIR}/${target_name}.llext.pkg_input) + set(llext_pkg_input ${PROJECT_BINARY_DIR}/llext/${target_name}_debug.elf) add_custom_target(${llext_proc_target} DEPENDS ${llext_pkg_input}) set_property(TARGET ${llext_proc_target} PROPERTY has_post_build_cmds 0) @@ -5684,49 +5725,19 @@ function(add_llext_target target_name) set(slid_inject_cmd ${CMAKE_COMMAND} -E true) endif() - # Type-specific packaging of the built binary file into an .llext file - if(CONFIG_LLEXT_TYPE_ELF_OBJECT) - - # No packaging required, simply copy the object file - add_custom_command( - OUTPUT ${llext_pkg_output} - COMMAND ${CMAKE_COMMAND} -E copy ${llext_pkg_input} ${llext_pkg_output} - COMMAND ${slid_inject_cmd} - DEPENDS ${llext_proc_target} ${llext_pkg_input} - ) - - elseif(CONFIG_LLEXT_TYPE_ELF_RELOCATABLE) - - # Need to remove just some sections from the relocatable object - # (using strip in this case would remove _all_ symbols) - add_custom_command( - OUTPUT ${llext_pkg_output} - COMMAND $ - $ - $.xt.* - $${llext_pkg_input} - $${llext_pkg_output} - $ - COMMAND ${slid_inject_cmd} - DEPENDS ${llext_proc_target} ${llext_pkg_input} - ) - - elseif(CONFIG_LLEXT_TYPE_ELF_SHAREDLIB) - - # Need to strip the shared library of some sections - add_custom_command( - OUTPUT ${llext_pkg_output} - COMMAND $ - $ - $.xt.* - $${llext_pkg_input} - $${llext_pkg_output} - $ - COMMAND ${slid_inject_cmd} - DEPENDS ${llext_proc_target} ${llext_pkg_input} - ) - - endif() + # Remove sections that are unused by the llext loader + add_custom_command( + OUTPUT ${llext_pkg_output} + COMMAND $ + $ + $ + $.xt.* + $${llext_pkg_input} + $${llext_pkg_output} + $ + COMMAND ${slid_inject_cmd} + DEPENDS ${llext_proc_target} ${llext_pkg_input} + ) # Add user-visible target and dependency, and fill in properties get_filename_component(output_name ${llext_pkg_output} NAME) @@ -5784,7 +5795,7 @@ function(add_llext_command) # ARM uses an object file representation so there is no link step. if(CONFIG_ARM AND LLEXT_PRE_BUILD) message(FATAL_ERROR - "add_llext_command: PRE_BUILD not supported on this arch") + "add_llext_command: PRE_BUILD not supported on this arch") endif() # Determine the build step and the target to attach the command to @@ -5871,7 +5882,7 @@ endfunction() # depending on the exact use of the function in script mode. # # Current Zephyr CMake scripts which includes `extensions.cmake` in script mode -# are: package_helper.cmake, verify-toolchain.cmake +# are: package_helper.cmake, verify-toolchain.cmake, llext-edk.cmake # if(CMAKE_SCRIPT_MODE_FILE) @@ -5886,16 +5897,11 @@ if(CMAKE_SCRIPT_MODE_FILE) # This silence the error: 'set_target_properties command is not scriptable' endfunction() - function(zephyr_set variable) - # This silence the error: zephyr_set(... SCOPE ) doesn't exists. - endfunction() - # Build info creates a custom target for handling of build info. # build_info is not needed in script mode but still called by Zephyr CMake # modules. Therefore disable build_info(...) in when including # extensions.cmake in script mode. function(build_info) - # This silence the error: 'YAML context 'build_info' does not exist.' - # 'Remember to create a YAML context' + # This silence the error: 'Unknown CMake command "yaml_context"' endfunction() endif() diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 02bebbe085199..af8c1e33fa7b9 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -226,6 +226,7 @@ foreach(kconfig_target "SHIELD_AS_LIST=${SHIELD_AS_LIST_ESCAPED}" DTS_POST_CPP=${DTS_POST_CPP} DTS_ROOT_BINDINGS=${DTS_ROOT_BINDINGS} + ${PTY_INTERFACE} ${PYTHON_EXECUTABLE} ${EXTRA_KCONFIG_TARGET_COMMAND_FOR_${kconfig_target}} ${KCONFIG_ROOT} diff --git a/cmake/modules/root.cmake b/cmake/modules/root.cmake index e14b853831f29..696de94fe7684 100644 --- a/cmake/modules/root.cmake +++ b/cmake/modules/root.cmake @@ -28,6 +28,7 @@ zephyr_get(BOARD_ROOT MERGE SYSBUILD GLOBAL) zephyr_get(SOC_ROOT MERGE SYSBUILD GLOBAL) zephyr_get(ARCH_ROOT MERGE SYSBUILD GLOBAL) zephyr_get(SCA_ROOT MERGE SYSBUILD GLOBAL) +zephyr_get(SNIPPET_ROOT MERGE SYSBUILD GLOBAL) # Convert paths to absolute, relative from APPLICATION_SOURCE_DIR zephyr_file(APPLICATION_ROOT MODULE_EXT_ROOT) @@ -35,6 +36,7 @@ zephyr_file(APPLICATION_ROOT BOARD_ROOT) zephyr_file(APPLICATION_ROOT SOC_ROOT) zephyr_file(APPLICATION_ROOT ARCH_ROOT) zephyr_file(APPLICATION_ROOT SCA_ROOT) +zephyr_file(APPLICATION_ROOT SNIPPET_ROOT) if(unittest IN_LIST Zephyr_FIND_COMPONENTS) # Zephyr used in unittest mode, use dedicated unittest root. diff --git a/cmake/modules/snippets.cmake b/cmake/modules/snippets.cmake index 550d236a2f4ad..b897067667eff 100644 --- a/cmake/modules/snippets.cmake +++ b/cmake/modules/snippets.cmake @@ -45,19 +45,23 @@ zephyr_check_cache(SNIPPET WATCH) function(zephyr_process_snippets) set(snippets_py ${ZEPHYR_BASE}/scripts/snippets.py) set(snippets_generated ${CMAKE_BINARY_DIR}/zephyr/snippets_generated.cmake) + set_ifndef(SNIPPET_NAMESPACE SNIPPET) + set_ifndef(SNIPPET_PYTHON_EXTRA_ARGS "") + set_ifndef(SNIPPET_APP_DIR "${APPLICATION_SOURCE_DIR}") # Set SNIPPET_AS_LIST, removing snippets_generated.cmake if we are # running cmake again and snippets are no longer requested. - if (NOT DEFINED SNIPPET) + if(NOT DEFINED SNIPPET) set(SNIPPET_AS_LIST "" PARENT_SCOPE) file(REMOVE ${snippets_generated}) else() - string(REPLACE " " ";" SNIPPET_AS_LIST "${SNIPPET}") + string(REPLACE " " ";" SNIPPET_AS_LIST "${${SNIPPET_NAMESPACE}}") set(SNIPPET_AS_LIST "${SNIPPET_AS_LIST}" PARENT_SCOPE) endif() # Set SNIPPET_ROOT. - list(APPEND SNIPPET_ROOT ${APPLICATION_SOURCE_DIR}) + zephyr_get(SNIPPET_ROOT MERGE SYSBUILD GLOBAL) + list(APPEND SNIPPET_ROOT ${SNIPPET_APP_DIR}) list(APPEND SNIPPET_ROOT ${ZEPHYR_BASE}) unset(real_snippet_root) foreach(snippet_dir ${SNIPPET_ROOT}) @@ -85,11 +89,25 @@ function(zephyr_process_snippets) ${snippet_root_args} ${requested_snippet_args} --cmake-out ${snippets_generated} + ${SNIPPET_PYTHON_EXTRA_ARGS} OUTPUT_VARIABLE output ERROR_VARIABLE output RESULT_VARIABLE ret) if(${ret}) - message(FATAL_ERROR "${output}") + list(JOIN SNIPPET_ROOT "\n " snippet_root_paths) + set(snippet_root_paths "\n ${snippet_root_paths}") + + if(SYSBUILD) + zephyr_get(SYSBUILD_NAME SYSBUILD GLOBAL) + set(extra_output "Snippet roots for image ${SYSBUILD_NAME}:${snippet_root_paths}\n" + "Note that snippets will be applied to all images unless prefixed with the image name " + "e.g. `-D${SYSBUILD_NAME}_SNIPPET=...`, local snippet roots for one image are not set " + "for other images in a build") + else() + set(extra_output "Snippet roots for application:${snippet_root_paths}") + endif() + + message(FATAL_ERROR "${output}" ${extra_output}) endif() include(${snippets_generated}) diff --git a/cmake/modules/unittest.cmake b/cmake/modules/unittest.cmake index 6565e89aec53a..aa3247661c549 100644 --- a/cmake/modules/unittest.cmake +++ b/cmake/modules/unittest.cmake @@ -112,6 +112,7 @@ target_compile_options(test_interface INTERFACE ${EXTRA_CFLAGS_AS_LIST} $<$:${EXTRA_CXXFLAGS_AS_LIST}> $<$:${EXTRA_AFLAGS_AS_LIST}> + -Wno-format-zero-length ) target_link_options(testbinary PRIVATE @@ -130,6 +131,10 @@ if(CONFIG_COVERAGE) target_link_libraries(testbinary PRIVATE $) endif() +if (CONFIG_COMPILER_WARNINGS_AS_ERRORS) + target_compile_options(test_interface INTERFACE $) +endif() + if(LIBS) message(FATAL_ERROR "This variable is not supported, see SOURCES instead") endif() @@ -157,6 +162,13 @@ if(VALGRIND_PROGRAM) ) endif() +add_custom_target(run + COMMAND + $ + DEPENDS testbinary + WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} + ) + add_custom_target(run-test COMMAND ${VALGRIND} ${VALGRIND_FLAGS} diff --git a/cmake/modules/version.cmake b/cmake/modules/version.cmake index d35b3be062332..b3a9a3c937b1b 100644 --- a/cmake/modules/version.cmake +++ b/cmake/modules/version.cmake @@ -63,7 +63,7 @@ foreach(type file IN ZIP_LISTS VERSION_TYPE VERSION_FILE) string(REGEX MATCH "VERSION_TWEAK = ([0-9]*)" _ ${ver}) set(${type}_VERSION_TWEAK ${CMAKE_MATCH_1}) - string(REGEX MATCH "EXTRAVERSION = ([a-z0-9]*)" _ ${ver}) + string(REGEX MATCH "EXTRAVERSION = ([a-z0-9\.\-]*)" _ ${ver}) set(${type}_VERSION_EXTRA ${CMAKE_MATCH_1}) # Validate all version fields fit in a single byte diff --git a/cmake/modules/yaml.cmake b/cmake/modules/yaml.cmake index 50d6c7cc74622..ec12a04bec5f8 100644 --- a/cmake/modules/yaml.cmake +++ b/cmake/modules/yaml.cmake @@ -19,6 +19,13 @@ # - foo2 # - foo3 # +# Support for list of maps, like: +# foo: +# - bar: val1 +# baz: val1 +# - bar: val2 +# baz: val2 +# # All of above can be combined, for example like: # foo: # bar: baz @@ -28,14 +35,6 @@ # - beta # - gamma # fred: thud -# -# Support for list of objects are currently experimental and not guranteed to work. -# For example: -# foo: -# - bar: val1 -# baz: val1 -# - bar: val2 -# baz: val2 include_guard(GLOBAL) @@ -72,6 +71,98 @@ function(internal_yaml_context_free) endif() endfunction() +# Internal helper function to provide the correct initializer for a list in the +# JSON content. +function(internal_yaml_list_initializer var genex) + if(genex) + set(${var} "\"@YAML-LIST@\"" PARENT_SCOPE) + else() + set(${var} "[]" PARENT_SCOPE) + endif() +endfunction() + +# Internal helper function to append items to a list in the JSON content. +# Unassigned arguments are the values to be appended. +function(internal_yaml_list_append var genex key) + set(json_content "${${var}}") + string(JSON subjson GET "${json_content}" ${key}) + if(genex) + # new lists are stored in CMake string format, but those imported via + # yaml_load() are proper JSON arrays. When an append is requested, those + # must be converted back to a CMake list. + string(JSON type TYPE "${json_content}" ${key}) + if(type STREQUAL ARRAY) + string(JSON arraylength LENGTH "${subjson}") + internal_yaml_list_initializer(subjson TRUE) + if(${arraylength} GREATER 0) + math(EXPR arraystop "${arraylength} - 1") + list(GET ARG_YAML_LIST 0 entry_0) + if(entry_0 STREQUAL MAP) + message(FATAL_ERROR "${function}(GENEX ${argument} ) is not valid at this position.\n" + "Syntax is 'LIST MAP \"key1: value1.1, ...\" MAP \"key1: value1.2, ...\"" + ) + endif() + + foreach(i RANGE 0 ${arraystop}) + string(JSON item GET "${json_content}" ${key} ${i}) + list(APPEND subjson ${item}) + endforeach() + endif() + endif() + list(APPEND subjson ${ARGN}) + string(JSON json_content SET "${json_content}" ${key} "\"${subjson}\"") + else() + # lists are stored as JSON arrays + string(JSON index LENGTH "${subjson}") + list(LENGTH ARGN length) + if(NOT length EQUAL 0) + list(GET ARG_YAML_LIST 0 entry_0) + if(entry_0 STREQUAL MAP) + math(EXPR length "${length} / 2") + math(EXPR stop "${index} + ${length} - 1") + foreach(i RANGE ${index} ${stop}) + list(POP_FRONT ARG_YAML_LIST argument) + if(NOT argument STREQUAL MAP) + message(FATAL_ERROR "yaml_set(${argument} ) is not valid at this position.\n" + "Syntax is 'LIST MAP \"key1: value1.1, ...\" MAP \"key1: value1.2, ...\"" + ) + endif() + list(POP_FRONT ARG_YAML_LIST map_value) + string(REGEX REPLACE "([^\\])," "\\1;" pair_list "${map_value}") + set(qouted_map_value) + foreach(pair ${pair_list}) + if(NOT pair MATCHES "[^ ]*:[^ ]*") + message(FATAL_ERROR "yaml_set(MAP ${map_value} ) is malformed.\n" + "Syntax is 'LIST MAP \"key1: value1.1, ...\" MAP \"key1: value1.2, ...\"\n" + "If value contains comma ',' then ensure the value field is properly qouted " + "and escaped" + ) + endif() + string(REGEX MATCH "^[^:]*" map_key "${pair}") + string(REGEX REPLACE "^${map_key}:[ ]*" "" value "${pair}") + string(STRIP "${map_key}" map_key) + if(value MATCHES "," AND NOT (value MATCHES "\\\\," AND value MATCHES "'.*'")) + message(FATAL_ERROR "value: ${value} is not properly quoted") + endif() + string(REGEX REPLACE "\\\\," "," value "${value}") + list(APPEND qouted_map_value "\"${map_key}\": \"${value}\"") + endforeach() + list(JOIN qouted_map_value "," qouted_map_value) + string(JSON json_content SET "${json_content}" ${key} ${i} "{${qouted_map_value}}") + endforeach() + else() + math(EXPR stop "${index} + ${length} - 1") + list(GET ARG_YAML_LIST 0 entry_0) + foreach(i RANGE ${index} ${stop}) + list(POP_FRONT ARGN value) + string(JSON json_content SET "${json_content}" ${key} ${i} "\"${value}\"") + endforeach() + endif() + endif() + endif() + set(${var} "${json_content}" PARENT_SCOPE) +endfunction() + # Usage # yaml_context(EXISTS NAME ) # @@ -93,7 +184,8 @@ function(yaml_context) ) endif() - if(TARGET ${ARG_YAML_NAME}_scope) + zephyr_scope_exists(scope_defined ${ARG_YAML_NAME}) + if(scope_defined) list(POP_FRONT ARG_YAML_UNPARSED_ARGUMENTS out-var) set(${out-var} TRUE PARENT_SCOPE) else() @@ -124,6 +216,7 @@ function(yaml_create) if(DEFINED ARG_YAML_FILE) zephyr_set(FILE ${ARG_YAML_FILE} SCOPE ${ARG_YAML_NAME}) endif() + zephyr_set(GENEX FALSE SCOPE ${ARG_YAML_NAME}) zephyr_set(JSON "{}" SCOPE ${ARG_YAML_NAME}) endfunction() @@ -148,7 +241,7 @@ function(yaml_load) zephyr_set(FILE ${ARG_YAML_FILE} SCOPE ${ARG_YAML_NAME}) execute_process(COMMAND ${PYTHON_EXECUTABLE} -c - "import json; import yaml; print(json.dumps(yaml.safe_load(open('${ARG_YAML_FILE}'))))" + "import json; import yaml; print(json.dumps(yaml.safe_load(open('${ARG_YAML_FILE}')) or {}))" OUTPUT_VARIABLE json_load_out ERROR_VARIABLE json_load_error RESULT_VARIABLE json_load_result @@ -160,6 +253,7 @@ function(yaml_load) ) endif() + zephyr_set(GENEX FALSE SCOPE ${ARG_YAML_NAME}) zephyr_set(JSON "${json_load_out}" SCOPE ${ARG_YAML_NAME}) endfunction() @@ -183,7 +277,7 @@ function(yaml_get out_var) zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME KEY) internal_yaml_context_required(NAME ${ARG_YAML_NAME}) - get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON) + zephyr_get_scoped(json_content ${ARG_YAML_NAME} JSON) # We specify error variable to avoid a fatal error. # If key is not found, then type becomes '-NOTFOUND' and value handling is done below. @@ -224,7 +318,7 @@ function(yaml_length out_var) zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME KEY) internal_yaml_context_required(NAME ${ARG_YAML_NAME}) - get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON) + zephyr_get_scoped(json_content ${ARG_YAML_NAME} JSON) string(JSON type ERROR_VARIABLE error TYPE "${json_content}" ${ARG_YAML_KEY}) if(type STREQUAL ARRAY) @@ -240,8 +334,9 @@ function(yaml_length out_var) endfunction() # Usage: -# yaml_set(NAME KEY ... VALUE ) -# yaml_set(NAME KEY ... [APPEND] LIST ...) +# yaml_set(NAME KEY ... [GENEX] VALUE ) +# yaml_set(NAME KEY ... [APPEND] [GENEX] LIST ...) +# yaml_set(NAME KEY ... [APPEND] LIST MAP MAP MAP ...) # # Set a value or a list of values to given key. # @@ -251,18 +346,46 @@ endfunction() # NAME : Name of the YAML context. # KEY ... : Name of key. # VALUE : New value for the key. -# List : New list of values for the key. +# LIST : New list of values for the key. # APPEND : Append the list of values to the list of values for the key. +# GENEX : The value(s) contain generator expressions. When using this +# option, also see the notes in the yaml_save() function. +# MAP : Map, with key-value pairs where key-value is separated by ':', +# and pairs separated by ','. +# Format example: ": , : , ..." +# MAP can be given multiple times to separate maps when adding them to a list. +# LIST MAP cannot be used with GENEX. +# +# Note: if a map value contains commas, ',', then the value string must be quoted in +# single quotes and commas must be double escaped, like this: 'A \\,string' # function(yaml_set) - cmake_parse_arguments(ARG_YAML "APPEND" "NAME;VALUE" "KEY;LIST" ${ARGN}) + cmake_parse_arguments(ARG_YAML "APPEND;GENEX" "NAME;VALUE" "KEY;LIST" ${ARGN}) zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME KEY) zephyr_check_arguments_required_allow_empty(${CMAKE_CURRENT_FUNCTION} ARG_YAML VALUE LIST) zephyr_check_arguments_exclusive(${CMAKE_CURRENT_FUNCTION} ARG_YAML VALUE LIST) internal_yaml_context_required(NAME ${ARG_YAML_NAME}) - get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON) + if(ARG_YAML_GENEX) + zephyr_set(GENEX TRUE SCOPE ${ARG_YAML_NAME}) + endif() + + if(DEFINED ARG_YAML_LIST + OR LIST IN_LIST ARG_YAML_KEYWORDS_MISSING_VALUES) + set(key_is_list TRUE) + endif() + + if(ARG_YAML_APPEND AND NOT key_is_list) + message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}(APPEND ...) can only be used with argument: LIST") + endif() + + if(ARG_YAML_GENEX AND MAP IN_LIST ARG_YAML_LIST) + message(FATAL_ERROR "${function}(GENEX ...) cannot be used with argument: LIST MAP") + endif() + + zephyr_get_scoped(json_content ${ARG_YAML_NAME} JSON) + zephyr_get_scoped(genex ${ARG_YAML_NAME} GENEX) set(yaml_key_undefined ${ARG_YAML_KEY}) foreach(k ${yaml_key_undefined}) @@ -280,8 +403,8 @@ function(yaml_set) list(REVERSE yaml_key_undefined) if(NOT "${yaml_key_undefined}" STREQUAL "") - if(ARG_YAML_APPEND) - set(json_string "[]") + if(key_is_list) + internal_yaml_list_initializer(json_string ${genex}) else() set(json_string "\"\"") endif() @@ -294,21 +417,12 @@ function(yaml_set) ) endif() - if(DEFINED ARG_YAML_LIST OR LIST IN_LIST ARG_YAML_KEYWORDS_MISSING_VALUES) + if(key_is_list) if(NOT ARG_YAML_APPEND) - string(JSON json_content SET "${json_content}" ${ARG_YAML_KEY} "[]") - endif() - - string(JSON subjson GET "${json_content}" ${ARG_YAML_KEY}) - string(JSON index LENGTH "${subjson}") - list(LENGTH ARG_YAML_LIST length) - math(EXPR stop "${index} + ${length} - 1") - if(NOT length EQUAL 0) - foreach(i RANGE ${index} ${stop}) - list(POP_FRONT ARG_YAML_LIST value) - string(JSON json_content SET "${json_content}" ${ARG_YAML_KEY} ${i} "\"${value}\"") - endforeach() + internal_yaml_list_initializer(json_string ${genex}) + string(JSON json_content SET "${json_content}" ${ARG_YAML_KEY} "${json_string}") endif() + internal_yaml_list_append(json_content ${genex} "${ARG_YAML_KEY}" ${ARG_YAML_LIST}) else() string(JSON json_content SET "${json_content}" ${ARG_YAML_KEY} "\"${ARG_YAML_VALUE}\"") endif() @@ -335,7 +449,7 @@ function(yaml_remove) zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME KEY) internal_yaml_context_required(NAME ${ARG_YAML_NAME}) - get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON) + zephyr_get_scoped(json_content ${ARG_YAML_NAME} JSON) string(JSON json_content REMOVE "${json_content}" ${ARG_YAML_KEY}) zephyr_set(JSON "${json_content}" SCOPE ${ARG_YAML_NAME}) @@ -344,8 +458,12 @@ endfunction() # Usage: # yaml_save(NAME [FILE ]) # -# Write the YAML context to the file which were given with the earlier -# 'yaml_load()' or 'yaml_create()' call. +# Write the YAML context to , or the one given with the earlier +# 'yaml_load()' or 'yaml_create()' call. This will be performed immediately if +# the context does not use generator expressions; otherwise, keys that include +# a generator expression will initially be written as comments, and the full +# contents will be available at build time. Build steps that depend on the file +# being complete must depend on the '_yaml_saved' target. # # NAME : Name of the YAML context # FILE : Path to file to write the context. @@ -359,26 +477,69 @@ function(yaml_save) zephyr_check_arguments_required(${CMAKE_CURRENT_FUNCTION} ARG_YAML NAME) internal_yaml_context_required(NAME ${ARG_YAML_NAME}) - get_target_property(yaml_file ${ARG_YAML_NAME}_scope FILE) + zephyr_get_scoped(yaml_file ${ARG_YAML_NAME} FILE) if(NOT yaml_file) zephyr_check_arguments_required(${CMAKE_CURRENT_FUNCTION} ARG_YAML FILE) endif() - - get_property(json_content TARGET ${ARG_YAML_NAME}_scope PROPERTY JSON) - to_yaml("${json_content}" 0 yaml_out) - if(DEFINED ARG_YAML_FILE) set(yaml_file ${ARG_YAML_FILE}) else() - get_property(yaml_file TARGET ${ARG_YAML_NAME}_scope PROPERTY FILE) + zephyr_get_scoped(yaml_file ${ARG_YAML_NAME} FILE) endif() + + zephyr_get_scoped(genex ${ARG_YAML_NAME} GENEX) + zephyr_get_scoped(json_content ${ARG_YAML_NAME} JSON) + to_yaml("${json_content}" 0 yaml_out ${genex}) + if(EXISTS ${yaml_file}) FILE(RENAME ${yaml_file} ${yaml_file}.bak) endif() FILE(WRITE ${yaml_file} "${yaml_out}") + + set(save_target ${ARG_YAML_NAME}_yaml_saved) + if (NOT TARGET ${save_target}) + # Create a target for the completion of the YAML save operation. + # This will be a dummy unless genexes are used. + add_custom_target(${save_target} ALL DEPENDS ${yaml_file}) + set_target_properties(${save_target} PROPERTIES + genex_save_count 0 + temp_files "" + ) + endif() + + if (genex) + get_property(genex_save_count TARGET ${save_target} PROPERTY genex_save_count) + if (${genex_save_count} EQUAL 0) + # First yaml_save() for this context with genexes enabled + add_custom_command( + OUTPUT ${yaml_file} + DEPENDS $ + COMMAND ${CMAKE_COMMAND} + -DJSON_FILE="$" + -DYAML_FILE="${yaml_file}" + -DTEMP_FILES="$" + -P ${ZEPHYR_BASE}/cmake/yaml-filter.cmake + ) + endif() + + math(EXPR genex_save_count "${genex_save_count} + 1") + set_property(TARGET ${save_target} PROPERTY genex_save_count ${genex_save_count}) + + cmake_path(SET yaml_path "${yaml_file}") + cmake_path(GET yaml_path STEM yaml_file_no_ext) + set(json_file ${yaml_file_no_ext}_${genex_save_count}.json) + set_property(TARGET ${save_target} PROPERTY json_file ${json_file}) + + # comment this to keep the temporary JSON files + set_property(TARGET ${save_target} APPEND PROPERTY temp_files ${json_file}) + + FILE(GENERATE OUTPUT ${json_file} + CONTENT "${json_content}" + ) + endif() endfunction() -function(to_yaml json level yaml) +function(to_yaml json level yaml genex) if(level GREATER 0) math(EXPR level_dec "${level} - 1") set(indent_${level} "${indent_${level_dec}} ") @@ -397,10 +558,12 @@ function(to_yaml json level yaml) string(JSON type TYPE "${json}" ${member}) string(JSON subjson GET "${json}" ${member}) if(type STREQUAL OBJECT) + # JSON object -> YAML dictionary set(${yaml} "${${yaml}}${indent_${level}}${member}:\n") math(EXPR sublevel "${level} + 1") - to_yaml("${subjson}" ${sublevel} ${yaml}) + to_yaml("${subjson}" ${sublevel} ${yaml} ${genex}) elseif(type STREQUAL ARRAY) + # JSON array -> YAML list set(${yaml} "${${yaml}}${indent_${level}}${member}:") string(JSON arraylength LENGTH "${subjson}") if(${arraylength} LESS 1) @@ -410,10 +573,47 @@ function(to_yaml json level yaml) math(EXPR arraystop "${arraylength} - 1") foreach(i RANGE 0 ${arraystop}) string(JSON item GET "${json}" ${member} ${i}) - set(${yaml} "${${yaml}}${indent_${level}} - ${item}\n") + # Check the length of item. Only OBJECT and ARRAY may have length, so a length at this + # level means `to_yaml()` should be called recursively. + string(JSON length ERROR_VARIABLE ignore LENGTH "${item}") + if(length) + set(non_indent_yaml) + to_yaml("${item}" 0 non_indent_yaml FALSE) + string(REGEX REPLACE "\n$" "" non_indent_yaml "${non_indent_yaml}") + string(REPLACE "\n" "\n${indent_${level}} " indent_yaml "${non_indent_yaml}") + set(${yaml} "${${yaml}}${indent_${level}} - ${indent_yaml}\n") + else() + set(${yaml} "${${yaml}}${indent_${level}} - ${item}\n") + endif() endforeach() endif() + elseif(type STREQUAL STRING) + # JSON string maps to multiple YAML types: + # - with unexpanded generator expressions: save as YAML comment + # - if it matches the special prefix: convert to YAML list + # - otherwise: save as YAML scalar + if (subjson MATCHES "\\$<.*>" AND ${genex}) + # Yet unexpanded generator expression: save as comment + string(SUBSTRING ${indent_${level}} 1 -1 short_indent) + set(${yaml} "${${yaml}}#${short_indent}${member}: ${subjson}\n") + elseif(subjson MATCHES "^@YAML-LIST@") + # List-as-string: convert to list + set(${yaml} "${${yaml}}${indent_${level}}${member}:") + list(POP_FRONT subjson) + if(subjson STREQUAL "") + set(${yaml} "${${yaml}} []\n") + else() + set(${yaml} "${${yaml}}\n") + foreach(item ${subjson}) + set(${yaml} "${${yaml}}${indent_${level}} - ${item}\n") + endforeach() + endif() + else() + # Raw strings: save as is + set(${yaml} "${${yaml}}${indent_${level}}${member}: ${subjson}\n") + endif() else() + # Other JSON data type -> YAML scalar, as-is set(${yaml} "${${yaml}}${indent_${level}}${member}: ${subjson}\n") endif() endforeach() diff --git a/cmake/reports/CMakeLists.txt b/cmake/reports/CMakeLists.txt index 96cba730788ea..c9d2783db3fad 100644 --- a/cmake/reports/CMakeLists.txt +++ b/cmake/reports/CMakeLists.txt @@ -29,7 +29,7 @@ foreach(report ram_report rom_report footprint) ) endforeach() -if (CONFIG_BUILD_WITH_TFM) +if(CONFIG_BUILD_WITH_TFM) foreach(report ram_report rom_report footprint) add_custom_target( tfm_${report} @@ -40,6 +40,7 @@ if (CONFIG_BUILD_WITH_TFM) -o ${CMAKE_BINARY_DIR} ${workspace_arg} -d ${report_depth} + --json tfm_${report}.json ${flag_for_${report}} DEPENDS tfm USES_TERMINAL @@ -48,22 +49,23 @@ if (CONFIG_BUILD_WITH_TFM) endforeach() endif() -if (CONFIG_TFM_BL2) +if(CONFIG_TFM_BL2) foreach(report ram_report rom_report footprint) - add_custom_target( - bl2_${report} - ${PYTHON_EXECUTABLE} - ${ZEPHYR_BASE}/scripts/footprint/size_report - -k $ - -z ${ZEPHYR_BASE} - -o ${CMAKE_BINARY_DIR} - ${workspace_arg} - -d ${report_depth} - ${flag_for_${report}} - DEPENDS tfm - USES_TERMINAL - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) + add_custom_target( + bl2_${report} + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/footprint/size_report + -k $ + -z ${ZEPHYR_BASE} + -o ${CMAKE_BINARY_DIR} + ${workspace_arg} + -d ${report_depth} + --json bl2_${report}.json + ${flag_for_${report}} + DEPENDS tfm + USES_TERMINAL + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) endforeach() endif() diff --git a/cmake/sca/polyspace/polyspace-print-console.py b/cmake/sca/polyspace/polyspace-print-console.py new file mode 100755 index 0000000000000..352fed1bdb3f3 --- /dev/null +++ b/cmake/sca/polyspace/polyspace-print-console.py @@ -0,0 +1,85 @@ +#!/usr/bin/python3 +""" +Print Polyspace results on terminal, for easy review. +Copyright (C) 2020-2024 The MathWorks, Inc. +""" + +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import os +import sys +from collections import Counter + + +def _parse_findings(filename: str, ignore_metrics=True): + """Parse CSV file""" + csv_sep = '\t' # Polyspace default separator + + def consume_header(oneline): + parts = oneline.split(csv_sep) + header.extend([p.strip() for p in parts]) + + def consume_data(oneline): + columns = oneline.split(csv_sep) + return dict(zip(header, columns, strict=True)) + + findings = [] + header = [] + with open(filename, encoding="latin-1") as fp: + for lno, line in enumerate(fp): + if lno == 0: + consume_header(line.rstrip()) + else: + onefind = consume_data(line.rstrip()) + if onefind and (not ignore_metrics or onefind.get('Family', '') != 'Code Metric'): + findings.append(onefind) + # -- + return findings + + +def print_sorted(mydict, maxlines=0): + """Print a dict sorted by value, largest first""" + + for lno, cnt_and_fil in enumerate( + sorted(((cnt, fil) for fil, cnt in mydict.items()), reverse=True), start=1 + ): + print(f" {cnt_and_fil[0]} issues in {cnt_and_fil[1]}") + if lno >= maxlines and maxlines != 0: + break + + +def main(argv): + # 1. command line arguments as required by your script + parser = argparse.ArgumentParser(description='Print results to console', allow_abbrev=False) + parser.add_argument('file', type=str, help='output file from polyspace-results-export') + parser.add_argument('--details', action='store_true', help='print details') + args = parser.parse_args() + + # 2. parsing the Polyspace files -> report + findings = _parse_findings(args.file) + print("-= Polyspace Static Code Analysis results =-") + + # 3. print details + if args.details: + for f in findings: + print( + f"{f.get('File', 'unknown file')}:" + + f"{f.get('Line', '?')}:" + + f"{f.get('Col', '?')}: " + + f"{f.get('Family', '')} {f.get('Check', 'Defect')}" + ) + + # 3. summary by category and file + print("By type:") + family = Counter([f.get('Family', 'Defect') for f in findings]) + print_sorted(family) + print("Top 10 files:") + files = Counter([os.path.basename(f.get('File', 'Unknown')) for f in findings]) + print_sorted(files, 10) + print(f"SCA found {len(findings)} issues in total") + return 0 + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/cmake/sca/polyspace/sca.cmake b/cmake/sca/polyspace/sca.cmake new file mode 100644 index 0000000000000..e9a73d71fda8f --- /dev/null +++ b/cmake/sca/polyspace/sca.cmake @@ -0,0 +1,142 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024, The MathWorks, Inc. + +include(boards) +include(git) +include(extensions) +include(west) + +# find Polyspace, stop if missing +find_program(POLYSPACE_CONFIGURE_EXE NAMES polyspace-configure) +if(NOT POLYSPACE_CONFIGURE_EXE) + message(FATAL_ERROR "Polyspace not found. For install instructions, see https://mathworks.com/help/bugfinder/install") +else() + cmake_path(GET POLYSPACE_CONFIGURE_EXE PARENT_PATH POLYSPACE_BIN) + message(STATUS "Found SCA: Polyspace (${POLYSPACE_BIN})") +endif() +find_program(POLYSPACE_RESULTS_EXE NAMES polyspace-results-export REQUIRED) + + +# Get Polyspace specific variables +zephyr_get(POLYSPACE_ONLY_APP) +zephyr_get(POLYSPACE_CONFIGURE_OPTIONS) +zephyr_get(POLYSPACE_MODE) +zephyr_get(POLYSPACE_OPTIONS) +zephyr_get(POLYSPACE_OPTIONS_FILE) +zephyr_get(POLYSPACE_PROG_NAME) +zephyr_get(POLYSPACE_PROG_VERSION) +message(TRACE "POLYSPACE_OPTIONS is ${POLYSPACE_OPTIONS}") + + +# Get path and name of user application +zephyr_get(APPLICATION_SOURCE_DIR) +cmake_path(GET APPLICATION_SOURCE_DIR FILENAME APPLICATION_NAME) +message(TRACE "APPLICATION_SOURCE_DIR is ${APPLICATION_SOURCE_DIR}") +message(TRACE "APPLICATION_NAME is ${APPLICATION_NAME}") + + +# process options +if(POLYSPACE_ONLY_APP) + set(POLYSPACE_CONFIGURE_OPTIONS ${POLYSPACE_CONFIGURE_OPTIONS} -include-sources ${APPLICATION_SOURCE_DIR}/**) + message(WARNING "SCA only analyzes application code") +endif() +if(POLYSPACE_MODE STREQUAL "prove") + message(NOTICE "POLYSPACE in proof mode") + find_program(POLYSPACE_EXE NAMES polyspace-code-prover-server polyspace-code-prover) +else() + message(NOTICE "POLYSPACE in bugfinding mode") + find_program(POLYSPACE_EXE NAMES polyspace-bug-finder-server polyspace-bug-finder) +endif() +if(NOT POLYSPACE_PROG_NAME) + set(POLYSPACE_PROG_NAME "zephyr-${BOARD}-${APPLICATION_NAME}") +endif() +message(TRACE "POLYSPACE_PROG_NAME is ${POLYSPACE_PROG_NAME}") +if(POLYSPACE_OPTIONS_FILE) + message(TRACE "POLYSPACE_OPTIONS_FILE is ${POLYSPACE_OPTIONS_FILE}") + set(POLYSPACE_OPTIONS_FILE -options-file ${POLYSPACE_OPTIONS_FILE}) +endif() +if(POLYSPACE_PROG_VERSION) + set(POLYSPACE_PROG_VERSION -verif-version '${POLYSPACE_PROG_VERSION}') +else() + git_describe(${APPLICATION_SOURCE_DIR} app_version) + if(app_version) + set(POLYSPACE_PROG_VERSION -verif-version '${app_version}') + endif() +endif() +message(TRACE "POLYSPACE_PROG_VERSION is ${POLYSPACE_PROG_VERSION}") + +# tell Polyspace about Zephyr specials +set(POLYSPACE_OPTIONS_ZEPHYR -options-file ${CMAKE_CURRENT_LIST_DIR}/zephyr.psopts) + +# Polyspace requires the compile_commands.json as input +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Create results directory +set(POLYSPACE_RESULTS_DIR ${CMAKE_BINARY_DIR}/sca/polyspace) +set(POLYSPACE_RESULTS_FILE ${POLYSPACE_RESULTS_DIR}/results.csv) +file(MAKE_DIRECTORY ${POLYSPACE_RESULTS_DIR}) +message(TRACE "POLYSPACE_RESULTS_DIR is ${POLYSPACE_RESULTS_DIR}") +set(POLYSPACE_OPTIONS_FILE_BASE ${POLYSPACE_RESULTS_DIR}/polyspace.psopts) + + +##################### +# mandatory targets # +##################### + +add_custom_target(polyspace_configure ALL + COMMAND ${POLYSPACE_CONFIGURE_EXE} + -allow-overwrite + -silent + -prog ${POLYSPACE_PROG_NAME} + -compilation-database ${CMAKE_BINARY_DIR}/compile_commands.json + -output-options-file ${POLYSPACE_OPTIONS_FILE_BASE} + ${POLYSPACE_CONFIGURE_OPTIONS} + VERBATIM + DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json + BYPRODUCTS ${POLYSPACE_OPTIONS_FILE_BASE} + USES_TERMINAL + COMMAND_EXPAND_LISTS +) + +add_custom_target(polyspace-analyze ALL + COMMAND ${POLYSPACE_EXE} + -results-dir ${POLYSPACE_RESULTS_DIR} + -options-file ${POLYSPACE_OPTIONS_FILE_BASE} + ${POLYSPACE_PROG_VERSION} + ${POLYSPACE_OPTIONS_ZEPHYR} + ${POLYSPACE_OPTIONS_FILE} + ${POLYSPACE_OPTIONS} + || ${CMAKE_COMMAND} -E true # allow to continue processing results + DEPENDS ${POLYSPACE_OPTIONS_FILE_BASE} + USES_TERMINAL + COMMAND_EXPAND_LISTS +) + +add_custom_target(polyspace-results ALL + COMMAND ${POLYSPACE_RESULTS_EXE} + -results-dir ${POLYSPACE_RESULTS_DIR} + -output-name ${POLYSPACE_RESULTS_FILE} + -format csv + || ${CMAKE_COMMAND} -E true # allow to continue processing results + VERBATIM + USES_TERMINAL + COMMAND_EXPAND_LISTS +) + +add_dependencies(polyspace-results polyspace-analyze) + + +##################### +# summarize results # +##################### + +add_custom_command(TARGET polyspace-results POST_BUILD + COMMAND ${CMAKE_CURRENT_LIST_DIR}/polyspace-print-console.py + ${POLYSPACE_RESULTS_FILE} + COMMAND + ${CMAKE_COMMAND} -E cmake_echo_color --cyan --bold + "SCA results are here: ${POLYSPACE_RESULTS_DIR}" + VERBATIM + USES_TERMINAL +) diff --git a/cmake/sca/polyspace/zephyr.psopts b/cmake/sca/polyspace/zephyr.psopts new file mode 100644 index 0000000000000..5888849b58cc5 --- /dev/null +++ b/cmake/sca/polyspace/zephyr.psopts @@ -0,0 +1,3 @@ +# tweaks specifically for Zephyr +-D__thread= +-enable-concurrency-detection diff --git a/cmake/toolchain/iar/Kconfig b/cmake/toolchain/iar/Kconfig new file mode 100644 index 0000000000000..056fa5d499f4d --- /dev/null +++ b/cmake/toolchain/iar/Kconfig @@ -0,0 +1,40 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +config LD_LINKER_SCRIPT_SUPPORTED + default n + +choice LINKER_SCRIPT + default CMAKE_LINKER_GENERATOR +endchoice + +menu "IAR library options" + +config IAR_SEMIHOSTING + bool "Use the IAR semihosting implementation." + depends on IAR_LIBC + help + Use the semihosting implementation in the IAR library + instead of the Zephyr implementation. + +config IAR_BUFFERED_WRITE + bool "Use buffered write" + depends on IAR_SEMIHOSTING + help + Instead of printing one character at a time + this option uses a buffer to print a line + at a time instead, increasing speed of printout. + +endmenu + +config TOOLCHAIN_IAR_SUPPORTS_THREAD_LOCAL_STORAGE + def_bool y + select TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE + +# Should we set this? It doesn't seem to be used +# We support most but don't set __GNUC__ +# +config TOOLCHAIN_IAR_SUPPORTS_GNU_EXTENSIONS + def_bool y + select TOOLCHAIN_SUPPORTS_GNU_EXTENSIONS diff --git a/cmake/toolchain/iar/Kconfig.defconfig b/cmake/toolchain/iar/Kconfig.defconfig new file mode 100644 index 0000000000000..506e81b87ba9a --- /dev/null +++ b/cmake/toolchain/iar/Kconfig.defconfig @@ -0,0 +1,53 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + + +config MISRA_SANE + default y + +config PICOLIBC_SUPPORTED + default n + +config TOOLCHAIN_HAS_BUILTIN_FFS + default n + +config FP16 + default y + +config IAR_LIBC_SUPPORTED + default y + +config COMPILER_FREESTANDING + default y + +config CBPRINTF_LIBC_SUBSTS + default y + +# IAR has slightly different types +config ENFORCE_ZEPHYR_STDINT + default n + +# IAR uses a little bit more stack than GCC +config TEST_EXTRA_STACK_SIZE + default 64 + +# ICCARM does not support relaxation +config LINKER_USE_NO_RELAX + default y + +# ICCARM support C17 with some additional features from C23 +config REQUIRES_STD_C17 + default y + +config CODING_GUIDELINE_CHECK + default n + help + Not applicable to ICCARM + +config TC_PROVIDES_POSIX_C_LANG_SUPPORT_R + default n + +# ICCARM does not support +config COMMON_LIBC_THRD + default n diff --git a/cmake/toolchain/iar/generic.cmake b/cmake/toolchain/iar/generic.cmake new file mode 100644 index 0000000000000..645ba19ecb989 --- /dev/null +++ b/cmake/toolchain/iar/generic.cmake @@ -0,0 +1,46 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_get(IAR_TOOLCHAIN_PATH) +assert(IAR_TOOLCHAIN_PATH "IAR_TOOLCHAIN_PATH is not set") + +set(IAR_TOOLCHAIN_VARIANT none) +if(NOT EXISTS ${IAR_TOOLCHAIN_PATH}) + message(FATAL_ERROR "Nothing found at IAR_TOOLCHAIN_PATH: '${IAR_TOOLCHAIN_PATH}'") +endif() + +if(EXISTS ${IAR_TOOLCHAIN_PATH}/bin/iccarm) + message(STATUS "Found toolchain: IAR C/C++ Compiler for Arm (${IAR_TOOLCHAIN_PATH})") + set(IAR_COMPILER iccarm) + set(IAR_LINKER ilinkarm) +elseif(EXISTS ${IAR_TOOLCHAIN_PATH}/bin/iccarm.exe) + message(STATUS "Found toolchain: IAR C/C++ Compiler for Arm (${IAR_TOOLCHAIN_PATH})") + set(IAR_COMPILER iccarm) + set(IAR_LINKER ilinkarm) +endif() + +set(IAR_TOOLCHAIN_VARIANT ${IAR_COMPILER}) + +# iar relies on Zephyr SDK for the use of C preprocessor (devicetree) and objcopy +find_package(Zephyr-sdk 0.16 REQUIRED) +message(STATUS "Found Zephyr SDK at ${ZEPHYR_SDK_INSTALL_DIR}") + +set(TOOLCHAIN_HOME ${IAR_TOOLCHAIN_PATH}) + +# Handling to be improved in Zephyr SDK, to avoid overriding ZEPHYR_TOOLCHAIN_VARIANT by +# find_package(Zephyr-sdk) if it's already set +set(ZEPHYR_TOOLCHAIN_VARIANT iar) + +set(COMPILER iar) +set(LINKER iar) +set(BINTOOLS iar) + +if("${IAR_TOOLCHAIN_VARIANT}" STREQUAL "iccarm") + set(SYSROOT_TARGET arm) +else() + set(SYSROOT_TARGET riscv) +endif() +set(CROSS_COMPILE ${TOOLCHAIN_HOME}/bin/) + +set(TOOLCHAIN_HAS_NEWLIB OFF CACHE BOOL "True if toolchain supports NewLib") diff --git a/cmake/toolchain/iar/target.cmake b/cmake/toolchain/iar/target.cmake new file mode 100644 index 0000000000000..b11635894a639 --- /dev/null +++ b/cmake/toolchain/iar/target.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2025 IAR Systems AB +# +# SPDX-License-Identifier: Apache-2.0 + +# Intentionally left blank. diff --git a/cmake/toolchain/xtools/Kconfig b/cmake/toolchain/xtools/Kconfig deleted file mode 100644 index c96baacbcc7d1..0000000000000 --- a/cmake/toolchain/xtools/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright © 2022 Keith Packard -# SPDX-License-Identifier: Apache-2.0 - -config TOOLCHAIN_XTOOLS_SUPPORTS_THREAD_LOCAL_STORAGE - def_bool y - select TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE - -config NEWLIB_LIBC_SUPPORTED - def_bool y - help - Crosstools is assumed to support newlib for C and C++ development. diff --git a/cmake/toolchain/xtools/generic.cmake b/cmake/toolchain/xtools/generic.cmake deleted file mode 100644 index be0075adede91..0000000000000 --- a/cmake/toolchain/xtools/generic.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -find_package(Deprecated COMPONENTS XTOOLS) - -zephyr_get(XTOOLS_TOOLCHAIN_PATH) -assert( XTOOLS_TOOLCHAIN_PATH "XTOOLS_TOOLCHAIN_PATH is not set") - -set(TOOLCHAIN_HOME ${XTOOLS_TOOLCHAIN_PATH}) - -set(COMPILER gcc) -set(LINKER ld) -set(BINTOOLS gnu) - -# Choose one of the toolchains in 'TOOLCHAIN_HOME' at random to use as -# a 'generic' toolchain until we know for sure which toolchain we -# should use. Note that we can't use ARCH to distinguish between -# toolchains because choosing between iamcu and non-iamcu is dependent -# on Kconfig, not ARCH. -if("${ARCH}" STREQUAL "xtensa") - file(GLOB toolchain_paths ${TOOLCHAIN_HOME}/xtensa/*/*) -else() - file(GLOB toolchain_paths ${TOOLCHAIN_HOME}/*) -endif() -list(REMOVE_ITEM toolchain_paths ${TOOLCHAIN_HOME}/sources) -list(GET toolchain_paths 0 some_toolchain_path) - -get_filename_component(some_toolchain_root "${some_toolchain_path}" DIRECTORY) -get_filename_component(some_toolchain "${some_toolchain_path}" NAME) - -set(CROSS_COMPILE_TARGET ${some_toolchain}) - -set(SYSROOT_TARGET ${CROSS_COMPILE_TARGET}) - -set(CROSS_COMPILE ${some_toolchain_root}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) -set(SYSROOT_DIR ${some_toolchain_root}/${SYSROOT_TARGET}/${SYSROOT_TARGET}) -set(TOOLCHAIN_HAS_NEWLIB ON CACHE BOOL "True if toolchain supports newlib") - -unset(some_toolchain_root) -unset(some_toolchain) - -message(STATUS "Found toolchain: xtools (${XTOOLS_TOOLCHAIN_PATH})") diff --git a/cmake/toolchain/xtools/target.cmake b/cmake/toolchain/xtools/target.cmake deleted file mode 100644 index fab28b7463cd2..0000000000000 --- a/cmake/toolchain/xtools/target.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -set(CROSS_COMPILE_TARGET_arm arm-zephyr-eabi) -set(CROSS_COMPILE_TARGET_arm64 aarch64-zephyr-elf) -set(CROSS_COMPILE_TARGET_nios2 nios2-zephyr-elf) -set(CROSS_COMPILE_TARGET_riscv riscv64-zephyr-elf) -set(CROSS_COMPILE_TARGET_mips mipsel-zephyr-elf) -set(CROSS_COMPILE_TARGET_xtensa xtensa-zephyr-elf) -set(CROSS_COMPILE_TARGET_arc arc-zephyr-elf) -set(CROSS_COMPILE_TARGET_x86 x86_64-zephyr-elf) -set(CROSS_COMPILE_TARGET_sparc sparc-zephyr-elf) - -set(CROSS_COMPILE_TARGET ${CROSS_COMPILE_TARGET_${ARCH}}) -set(SYSROOT_TARGET ${CROSS_COMPILE_TARGET}) - -if("${ARCH}" STREQUAL "xtensa") - set(SYSROOT_DIR ${TOOLCHAIN_HOME}/xtensa/${SOC_NAME}/${SYSROOT_TARGET}) - set(CROSS_COMPILE ${TOOLCHAIN_HOME}/xtensa/${SOC_NAME}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) -else() - set(SYSROOT_DIR ${TOOLCHAIN_HOME}/${SYSROOT_TARGET}/${SYSROOT_TARGET}) - set(CROSS_COMPILE ${TOOLCHAIN_HOME}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) -endif() - -if("${ARCH}" STREQUAL "x86") - if(CONFIG_X86_64) - list(APPEND TOOLCHAIN_C_FLAGS -m64) - list(APPEND TOOLCHAIN_LD_FLAGS -m64) - else() - list(APPEND TOOLCHAIN_C_FLAGS -m32) - list(APPEND TOOLCHAIN_LD_FLAGS -m32) - endif() -endif() diff --git a/cmake/yaml-filter.cmake b/cmake/yaml-filter.cmake new file mode 100644 index 0000000000000..c7733be6485f0 --- /dev/null +++ b/cmake/yaml-filter.cmake @@ -0,0 +1,35 @@ +# Copyright (c) 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +# Simple second stage filter for YAML generation, used when generator +# expressions have been used for some of the data and the conversion to +# YAML needs to happen after cmake has completed processing. +# +# This scripts expects as input: +# - JSON_FILE: the name of the input file, in JSON format, that contains +# the expanded generator expressions. +# - YAML_FILE: the name of the final output YAML file. +# - TEMP_FILES: a list of temporary files that need to be removed after +# the conversion is done. +# +# This script loads the Zephyr yaml module and reuses its `to_yaml()` +# function to convert the fully expanded JSON content to YAML, taking +# into account the special format that was used to store lists. +# Temporary files are then removed. + +cmake_minimum_required(VERSION 3.20.0) + +set(ZEPHYR_BASE ${CMAKE_CURRENT_LIST_DIR}/../) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules") +include(yaml) + +file(READ ${JSON_FILE} json_content) +to_yaml("${json_content}" 0 yaml_out TRUE) +file(WRITE ${YAML_FILE} "${yaml_out}") + +# Remove unused temporary files. JSON_FILE needs to be kept, or the +# build system will complain there is no rule to rebuild it +list(REMOVE_ITEM TEMP_FILES ${JSON_FILE}) +foreach(file ${TEMP_FILES}) + file(REMOVE ${file}) +endforeach() diff --git a/doc/LICENSING.rst b/doc/LICENSING.rst index a16750cd3c3f9..d2674a7b3276b 100644 --- a/doc/LICENSING.rst +++ b/doc/LICENSING.rst @@ -10,42 +10,109 @@ are not covered by the `Apache 2.0 License`_. In some places there is no LICENSE file or way to put a LICENSE file there, so we describe the licensing in this document. +Continuous Integration Scripts +------------------------------ + +* *Origin:* Linux Kernel +* *Licensing:* `GPLv2 License`_ +* *Impact:* These files are used in Continuous Integration (CI) and never linked into the firmware. +* *Files:* + + * :zephyr_file:`scripts/checkpatch.pl` + * :zephyr_file:`scripts/checkstack.pl` + * :zephyr_file:`scripts/spelling.txt` + +Coccinelle Scripts +------------------ + + * *Origin:* Coccinelle + * *Licensing:* `GPLv2 License`_ + * *Impact:* These files are used by `Coccinelle`_, a tool for transforming C-code, and never linked + into the firmware. + * *Files:* + + * :zephyr_file:`scripts/coccicheck` + * :zephyr_file:`scripts/coccinelle/array_size.cocci` + * :zephyr_file:`scripts/coccinelle/deref_null.cocci` + * :zephyr_file:`scripts/coccinelle/deref_null.cocci` + * :zephyr_file:`scripts/coccinelle/deref_null.cocci` + * :zephyr_file:`scripts/coccinelle/mini_lock.cocci` + * :zephyr_file:`scripts/coccinelle/mini_lock.cocci` + * :zephyr_file:`scripts/coccinelle/mini_lock.cocci` + * :zephyr_file:`scripts/coccinelle/noderef.cocci` + * :zephyr_file:`scripts/coccinelle/noderef.cocci` + * :zephyr_file:`scripts/coccinelle/returnvar.cocci` + * :zephyr_file:`scripts/coccinelle/semicolon.cocci` + +GCOV Coverage Header File +------------------------- + +* *Origin:* GCC, the GNU Compiler Collection +* *Licensing:* `GPLv2 License`_ with Runtime Library Exception +* *Impact:* This file is only linked into the firmware if :kconfig:option:`CONFIG_COVERAGE_GCOV` is + enabled. +* *Files:* + + * :zephyr_file:`subsys/testsuite/coverage/coverage.h` + +ENE KB1200_EVB Board OpenOCD Configuration +------------------------------------------ + +* *Licensing:* `GPLv2 License`_ +* *Impact:* This file is used by `OpenOCD`_ when programming and debugging the :ref:`ene_kb1200_evb` + board. It is never linked into the firmware. +* *Files:* + + * :zephyr_file:`boards/ene/kb1200_evb/support/openocd.cfg` + +Thread-Metric RTOS Test Suite Source Files +------------------------------------------ + +* *Origin:* ThreadX +* *Licensing:* `MIT License`_ +* *Impact:* These files are only linked into the Thread-Metric RTOS Test Suite test firmware. +* *Files:* + + * :zephyr_file:`tests/benchmarks/thread_metric/thread_metric_readme.txt` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_api.h` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_basic_processing_test.c` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_cooperative_scheduling_test.c` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_interrupt_preemption_processing_test.c` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_interrupt_processing_test.c` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_memory_allocation_test.c` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_message_processing_test.c` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_porting_layer.h` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_porting_layer_zephyr.c` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_preemptive_scheduling_test.c` + * :zephyr_file:`tests/benchmarks/thread_metric/src/tm_synchronization_processing_test.c` + +OpenThread Spinel HDLC RCP Host Interface Files +----------------------------------------------- + +* *Origin:* OpenThread +* *Licensing:* `BSD-3-clause`_ +* *Impact:* These files are only linked into the firmware if :kconfig:option:`CONFIG_HDLC_RCP_IF` is + enabled. +* *Files*: + + * :zephyr_file:`modules/openthread/platform/hdlc_interface.hpp` + * :zephyr_file:`modules/openthread/platform/radio_spinel.cpp` + * :zephyr_file:`modules/openthread/platform/hdlc_interface.cpp` + .. _Apache 2.0 License: https://github.com/zephyrproject-rtos/zephyr/blob/main/LICENSE .. _GPLv2 License: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/COPYING -*scripts/{checkpatch.pl,checkstack.pl,spelling.txt}* - *Origin:* Linux Kernel - - *Licensing:* `GPLv2 License`_ - -*scripts/{coccicheck,coccinelle/array_size.cocci,coccinelle/deref_null.cocci,coccinelle/deref_null.cocci,coccinelle/deref_null.cocci,coccinelle/mini_lock.cocci,coccinelle/mini_lock.cocci,coccinelle/mini_lock.cocci,coccinelle/noderef.cocci,coccinelle/noderef.cocci,coccinelle/returnvar.cocci,coccinelle/semicolon.cocci}* - *Origin:* Coccinelle - - *Licensing:* `GPLv2 License`_ - -*subsys/testsuite/coverage/coverage.h* - *Origin:* GCC, the GNU Compiler Collection - - *Licensing:* `GPLv2 License`_ with Runtime Library Exception - -*boards/ene/kb1200_evb/support/openocd.cfg* - *Licensing:* `GPLv2 License`_ - .. _MIT License: https://opensource.org/licenses/MIT -*tests/benchmarks/thread_metric/{thread_metric_readme.txt,src/\*}* - *Origin:* ThreadX - - *Licensing:* `MIT License`_ - .. _BSD-3-clause: https://opensource.org/license/bsd-3-clause -*modules/openthread/platform/{hdlc_interface.cpp,hdlc_interface.hpp,radio_spinel.cpp}* - *Origin:* OpenThread +.. _Coccinelle: + https://coccinelle.gitlabpages.inria.fr/website/ - *Licensing:* `BSD-3-clause`_ +.. _OpenOCD: + https://openocd.org diff --git a/doc/_extensions/zephyr/api_overview.py b/doc/_extensions/zephyr/api_overview.py index 3d56e5eaee4fb..028a4ce9df048 100644 --- a/doc/_extensions/zephyr/api_overview.py +++ b/doc/_extensions/zephyr/api_overview.py @@ -1,16 +1,38 @@ # Copyright (c) 2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +import os from pathlib import Path from typing import Any import doxmlparser from docutils import nodes from doxmlparser.compound import DoxCompoundKind -from sphinx.application import Sphinx from sphinx.util.docutils import SphinxDirective +def get_group(innergroup, all_groups): + try: + return [ + group + for group in all_groups + if group.get_compounddef()[0].get_id() == innergroup.get_refid() + ][0] + except IndexError as e: + raise Exception(f"Unexpected group {innergroup.get_refid()}") from e + + +def parse_xml_dir(dir_name): + groups = [] + root = doxmlparser.index.parse(Path(dir_name) / "index.xml", True) + for compound in root.get_compound(): + if compound.get_kind() == DoxCompoundKind.GROUP: + file_name = Path(dir_name) / f"{compound.get_refid()}.xml" + groups.append(doxmlparser.compound.parse(file_name, True)) + + return groups + + class ApiOverview(SphinxDirective): """ This is a Zephyr directive to generate a table containing an overview @@ -21,156 +43,117 @@ class ApiOverview(SphinxDirective): Configuration options: - api_overview_doxygen_xml_dir: Doxygen xml output directory - api_overview_doxygen_base_url: Doxygen base html directory + api_overview_doxygen_out_dir: Doxygen output directory """ def run(self): - return [self.env.api_overview_table] - + groups = parse_xml_dir(self.config.api_overview_doxygen_out_dir + "/xml") -def get_group(innergroup, all_groups): - try: - return [ - g - for g in all_groups - if g.get_compounddef()[0].get_id() == innergroup.get_refid() - ][0] - except IndexError as e: - raise Exception(f"Unexpected group {innergroup.get_refid()}") from e + inners = [group.get_compounddef()[0].get_innergroup() for group in groups] + inner_ids = [i.get_refid() for inner in inners for i in inner] + toplevel = [ + group for group in groups if group.get_compounddef()[0].get_id() not in inner_ids + ] + return [self.generate_table(toplevel, groups)] -def visit_group(app, group, all_groups, rows, indent=0): - version = since = "" - github_uri = "https://github.com/zephyrproject-rtos/zephyr/releases/tag/" - cdef = group.get_compounddef()[0] - - ssects = [ - s for p in cdef.get_detaileddescription().get_para() for s in p.get_simplesect() - ] - for sect in ssects: - if sect.get_kind() == "since": - since = sect.get_para()[0].get_valueOf_() - elif sect.get_kind() == "version": - version = sect.get_para()[0].get_valueOf_() - - if since: - since_url = nodes.inline() - reference = nodes.reference( - text=f"v{since.strip()}.0", refuri=f"{github_uri}/v{since.strip()}.0" - ) - reference.attributes["internal"] = True - since_url += reference - else: - since_url = nodes.Text("") + def generate_table(self, toplevel, groups): + table = nodes.table() + tgroup = nodes.tgroup() - url_base = Path(app.config.api_overview_doxygen_base_url) - url = url_base / f"{cdef.get_id()}.html" + thead = nodes.thead() + thead_row = nodes.row() + for header_name in ["API", "Version", "Available in Zephyr Since"]: + colspec = nodes.colspec() + tgroup += colspec - title = cdef.get_title() + entry = nodes.entry() + entry += nodes.Text(header_name) + thead_row += entry + thead += thead_row + tgroup += thead - row_node = nodes.row() + rows = [] + tbody = nodes.tbody() + for t in toplevel: + self.visit_group(t, groups, rows) + tbody.extend(rows) + tgroup += tbody - # Next entry will contain the spacer and the link with API name - entry = nodes.entry() - span = nodes.Text("".join(["\U000000A0"] * indent)) - entry += span + table += tgroup - # API name with link - inline = nodes.inline() - reference = nodes.reference(text=title, refuri=str(url)) - reference.attributes["internal"] = True - inline += reference - entry += inline - row_node += entry + return table - version_node = nodes.Text(version) - # Finally, add version and since - for cell in [version_node, since_url]: - entry = nodes.entry() - entry += cell - row_node += entry - rows.append(row_node) + def visit_group(self, group, all_groups, rows, indent=0): + version = since = "" + github_uri = self.config.api_overview_base_url + "/releases/tag/" + cdef = group.get_compounddef()[0] - for innergroup in cdef.get_innergroup(): - visit_group( - app, get_group(innergroup, all_groups), all_groups, rows, indent + 6 + ssects = [ + s for p in cdef.get_detaileddescription().get_para() for s in p.get_simplesect() + ] + for sect in ssects: + if sect.get_kind() == "since": + since = sect.get_para()[0].get_valueOf_() + elif sect.get_kind() == "version": + version = sect.get_para()[0].get_valueOf_() + + if since: + since_url = nodes.inline() + reference = nodes.reference( + text=f"v{since.strip()}.0", refuri=f"{github_uri}/v{since.strip()}.0" + ) + reference.attributes["internal"] = True + since_url += reference + else: + since_url = nodes.Text("") + + url_base = Path(self.config.api_overview_doxygen_out_dir + "/html") + abs_url = url_base / f"{cdef.get_id()}.html" + doc_dir = os.path.dirname(self.get_source_info()[0]) + doc_dest = os.path.join( + self.env.app.outdir, + os.path.relpath(doc_dir, self.env.app.srcdir), ) + url = os.path.relpath(abs_url, doc_dest) + title = cdef.get_title() -def parse_xml_dir(dir_name): - groups = [] - root = doxmlparser.index.parse(Path(dir_name) / "index.xml", True) - for compound in root.get_compound(): - if compound.get_kind() == DoxCompoundKind.GROUP: - file_name = Path(dir_name) / f"{compound.get_refid()}.xml" - groups.append(doxmlparser.compound.parse(file_name, True)) - - return groups - + row_node = nodes.row() -def generate_table(app, toplevel, groups): - table = nodes.table() - tgroup = nodes.tgroup() + # Next entry will contain the spacer and the link with API name + entry = nodes.entry() + span = nodes.Text("".join(["\U000000A0"] * indent)) + entry += span - thead = nodes.thead() - thead_row = nodes.row() - for header_name in ["API", "Version", "Available in Zephyr Since"]: - colspec = nodes.colspec() - tgroup += colspec + # API name with link + inline = nodes.inline() + reference = nodes.reference(text=title, refuri=str(url)) + reference.attributes["internal"] = True + inline += reference + entry += inline + row_node += entry - entry = nodes.entry() - entry += nodes.Text(header_name) - thead_row += entry - thead += thead_row - tgroup += thead - - rows = [] - tbody = nodes.tbody() - for t in toplevel: - visit_group(app, t, groups, rows) - tbody.extend(rows) - tgroup += tbody - - table += tgroup - - return table - - -def sync_contents(app: Sphinx) -> None: - if app.config.doxyrunner_outdir: - doxygen_out_dir = Path(app.config.doxyrunner_outdir) - else: - doxygen_out_dir = Path(app.outdir) / "_doxygen" - - if not app.env.doxygen_input_changed: - return - - doxygen_xml_dir = doxygen_out_dir / "xml" - groups = parse_xml_dir(doxygen_xml_dir) - - toplevel = [ - g - for g in groups - if g.get_compounddef()[0].get_id() - not in [ - i.get_refid() - for h in [j.get_compounddef()[0].get_innergroup() for j in groups] - for i in h - ] - ] + version_node = nodes.Text(version) + # Finally, add version and since + for cell in [version_node, since_url]: + entry = nodes.entry() + entry += cell + row_node += entry + rows.append(row_node) - app.builder.env.api_overview_table = generate_table(app, toplevel, groups) + for innergroup in cdef.get_innergroup(): + self.visit_group( + get_group(innergroup, all_groups), all_groups, rows, indent + 6 + ) def setup(app) -> dict[str, Any]: - app.add_config_value("api_overview_doxygen_xml_dir", "html/doxygen/xml", "env") - app.add_config_value("api_overview_doxygen_base_url", "../../doxygen/html", "env") + app.add_config_value("api_overview_doxygen_out_dir", "", "env") + app.add_config_value("api_overview_base_url", "", "env") app.add_directive("api-overview-table", ApiOverview) - app.connect("builder-inited", sync_contents) - return { "version": "0.1", "parallel_read_safe": True, diff --git a/doc/_extensions/zephyr/domain/__init__.py b/doc/_extensions/zephyr/domain/__init__.py index b598ef3a3e552..5cdb7213ca931 100644 --- a/doc/_extensions/zephyr/domain/__init__.py +++ b/doc/_extensions/zephyr/domain/__init__.py @@ -268,6 +268,21 @@ def convert_node(self, node): field += field_body field_list += field + gh_link = gh_link_get_url(self.app, self.env.docname) + gh_link_button = nodes.raw( + "", + f""" + + """, + format="html", + ) + sidebar += gh_link_button + # Move the sibling nodes under the new section new_section.extend(siblings_to_move) @@ -836,7 +851,7 @@ def resolve_xref(self, env, fromdocname, builder, type, target, node, contnode): else: return - if elem: + if elem and "docname" in elem: if not node.get("refexplicit"): contnode = [nodes.Text(elem["name"] if type != "board" else elem["full_name"])] diff --git a/doc/_extensions/zephyr/doxybridge.py b/doc/_extensions/zephyr/doxybridge.py index fe0074b65da77..6b640fa8822e6 100644 --- a/doc/_extensions/zephyr/doxybridge.py +++ b/doc/_extensions/zephyr/doxybridge.py @@ -10,6 +10,7 @@ import doxmlparser from docutils import nodes +from docutils.parsers.rst import directives from doxmlparser.compound import DoxCompoundKind, DoxMemberKind from sphinx import addnodes from sphinx.application import Sphinx @@ -34,6 +35,9 @@ class DoxygenGroupDirective(SphinxDirective): has_content = False required_arguments = 1 optional_arguments = 0 + option_spec = { + "project": directives.unchanged, + } def run(self): @@ -48,6 +52,7 @@ def run(self): reftype="group", reftarget=self.arguments[0], refwarn=True, + project=self.options.get("project") ) group_xref += nodes.Text(self.arguments[0]) title_signode += group_xref @@ -73,28 +78,40 @@ def run(self, **kwargs: Any) -> None: if reftype in ("member", "data"): reftype = "var" - entry = self.app.env.doxybridge_cache.get(reftype) - if not entry: - continue + found_name = None + found_id = None + for name in self.app.config.doxybridge_projects: + entry = self.app.env.doxybridge_cache[name].get(reftype) + if not entry: + continue - reftarget = node.get("reftarget").replace(".", "::").rstrip("()") - id = entry.get(reftarget) - if not id: - if reftype == "func": - # macros are sometimes referenced as functions, so try that - id = self.app.env.doxybridge_cache.get("macro").get(reftarget) - if not id: + reftarget = node.get("reftarget").replace(".", "::").rstrip("()") + id = entry.get(reftarget) + if not id: + if reftype == "func": + # macros are sometimes referenced as functions, so try that + id = self.app.env.doxybridge_cache[name].get("macro").get(reftarget) + if not id: + continue + else: continue - else: - continue + + found_name = name + found_id = id + break + + if not found_name or not found_id: + continue if reftype in ("struct", "union", "group"): doxygen_target = f"{id}.html" else: - split = id.split("_") + split = found_id.split("_") doxygen_target = f"{'_'.join(split[:-1])}.html#{split[-1][1:]}" - doxygen_target = str(self.app.config.doxybridge_dir) + "/html/" + doxygen_target + doxygen_target = ( + str(self.app.config.doxybridge_projects[found_name]) + "/html/" + doxygen_target + ) doc_dir = os.path.dirname(self.document.get("source")) doc_dest = os.path.join( @@ -109,7 +126,7 @@ def run(self, **kwargs: Any) -> None: if reftype == "group": refnode["classes"].append("doxygroup") - title = self.app.env.doxybridge_group_titles.get(reftarget, "group") + title = self.app.env.doxybridge_group_titles[found_name].get(reftarget, "group") refnode[0] = nodes.Text(title) node.replace_self([refnode]) @@ -178,7 +195,7 @@ def parse_compound(inDirName, baseName) -> dict: return cache, group_titles -def parse_index(app: Sphinx, inDirName): +def parse_index(app: Sphinx, name, inDirName): rootObj = doxmlparser.index.parse(inDirName + "/index.xml", True) compounds = rootObj.get_compound() @@ -190,33 +207,40 @@ def parse_index(app: Sphinx, inDirName): for future in concurrent.futures.as_completed(futures): cache, group_titles = future.result() for kind, data in cache.items(): - app.env.doxybridge_cache.setdefault(kind, {}).update(data) - app.env.doxybridge_group_titles.update(group_titles) + app.env.doxybridge_cache[name].setdefault(kind, {}).update(data) + app.env.doxybridge_group_titles[name].update(group_titles) def doxygen_parse(app: Sphinx) -> None: - if not app.env.doxygen_input_changed: - return - - app.env.doxybridge_cache = { - "macro": {}, - "var": {}, - "type": {}, - "enum": {}, - "enumerator": {}, - "func": {}, - "union": {}, - "struct": {}, - "group": {}, - } + if not hasattr(app.env, "doxybridge_cache"): + app.env.doxybridge_cache = dict() + + if not hasattr(app.env, "doxybridge_group_titles"): + app.env.doxybridge_group_titles = dict() + + for project, path in app.config.doxybridge_projects.items(): + if project in app.env.doxygen_input_changed and not app.env.doxygen_input_changed[project]: + return + + app.env.doxybridge_cache[project] = { + "macro": {}, + "var": {}, + "type": {}, + "enum": {}, + "enumerator": {}, + "func": {}, + "union": {}, + "struct": {}, + "group": {}, + } - app.env.doxybridge_group_titles = {} + app.env.doxybridge_group_titles[project] = dict() - parse_index(app, str(app.config.doxybridge_dir / "xml")) + parse_index(app, project, str(path / "xml")) def setup(app: Sphinx) -> dict[str, Any]: - app.add_config_value("doxybridge_dir", None, "env") + app.add_config_value("doxybridge_projects", None, "env") app.add_directive("doxygengroup", DoxygenGroupDirective) diff --git a/doc/_extensions/zephyr/doxyrunner.py b/doc/_extensions/zephyr/doxyrunner.py index bdbc0daba6efe..45621175ad3b7 100644 --- a/doc/_extensions/zephyr/doxyrunner.py +++ b/doc/_extensions/zephyr/doxyrunner.py @@ -28,17 +28,19 @@ ===================== - ``doxyrunner_doxygen``: Path to the Doxygen binary. -- ``doxyrunner_doxyfile``: Path to Doxyfile. -- ``doxyrunner_outdir``: Doxygen build output directory (inserted to - ``OUTPUT_DIRECTORY``) -- ``doxyrunner_outdir_var``: Variable representing the Doxygen build output - directory, as used by ``OUTPUT_DIRECTORY``. This can be useful if other - Doxygen variables reference to the output directory. -- ``doxyrunner_fmt``: Flag to indicate if Doxyfile should be formatted. -- ``doxyrunner_fmt_vars``: Format variables dictionary (name: value). -- ``doxyrunner_fmt_pattern``: Format pattern. - ``doxyrunner_silent``: If Doxygen output should be logged or not. Note that this option may not have any effect if ``QUIET`` is set to ``YES``. +- ``doxyrunner_projects``: Dictionary specifying projects, keys being project + name and values a dictionary with the following keys: + + - ``doxyfile``: Path to Doxyfile. + - ``outdir``: Doxygen build output directory (inserted to ``OUTPUT_DIRECTORY``) + - ``outdir_var``: Variable representing the Doxygen build output directory, + as used by ``OUTPUT_DIRECTORY``. This can be useful if other Doxygen + variables reference to the output directory. + - ``fmt``: Flag to indicate if Doxyfile should be formatted. + - ``fmt_vars``: Format variables dictionary (name: value). + - ``fmt_pattern``: Format pattern. """ import filecmp @@ -193,7 +195,7 @@ def process_doxyfile( return content -def doxygen_input_has_changed(env: BuildEnvironment, doxyfile: str) -> bool: +def doxygen_input_has_changed(env: BuildEnvironment, name, doxyfile: str) -> bool: """Check if Doxygen input files have changed. Args: @@ -224,12 +226,15 @@ def doxygen_input_has_changed(env: BuildEnvironment, doxyfile: str) -> bool: for p_file in path.glob("**/" + pattern): cache.add(hash_file(p_file)) + if not hasattr(env, "doxyrunner_cache"): + env.doxyrunner_cache = dict() + # check if any file has changed - if hasattr(env, "doxyrunner_cache") and env.doxyrunner_cache == cache: + if env.doxyrunner_cache.get(name) == cache: return False # store current state - env.doxyrunner_cache = cache + env.doxyrunner_cache[name] = cache return True @@ -341,53 +346,52 @@ def doxygen_build(app: Sphinx) -> None: app: Sphinx application instance. """ - if app.config.doxyrunner_outdir: - outdir = Path(app.config.doxyrunner_outdir) - else: - outdir = Path(app.outdir) / "_doxygen" - - outdir.mkdir(exist_ok=True) - tmp_outdir = outdir / "tmp" - - logger.info("Preparing Doxyfile...") - doxyfile = process_doxyfile( - app.config.doxyrunner_doxyfile, - tmp_outdir, - app.config.doxyrunner_silent, - app.config.doxyrunner_fmt, - app.config.doxyrunner_fmt_pattern, - app.config.doxyrunner_fmt_vars, - app.config.doxyrunner_outdir_var, - ) + for name, config in app.config.doxyrunner_projects.items(): + if config.get("outdir"): + outdir = Path(config["outdir"]) + else: + outdir = Path(app.outdir) / "_doxygen" / name - logger.info("Checking if Doxygen needs to be run...") - app.env.doxygen_input_changed = doxygen_input_has_changed(app.env, doxyfile) - if not app.env.doxygen_input_changed: - logger.info("Doxygen build will be skipped (no changes)!") - return - - logger.info("Running Doxygen...") - run_doxygen( - app.config.doxyrunner_doxygen, - doxyfile, - app.config.doxyrunner_silent, - ) + outdir.mkdir(exist_ok=True) + tmp_outdir = outdir / "tmp" + + logger.info("Preparing Doxyfile...") + doxyfile = process_doxyfile( + config["doxyfile"], + tmp_outdir, + app.config.doxyrunner_silent, + config.get("fmt", False), + config.get("fmt_pattern", "@{}@"), + config.get("fmt_vars", {}), + config.get("outdir_var"), + ) + + logger.info(f"Checking if Doxygen needs to be run for {name}...") + if not hasattr(app.env, "doxygen_input_changed"): + app.env.doxygen_input_changed = dict() + + app.env.doxygen_input_changed[name] = doxygen_input_has_changed(app.env, name, doxyfile) + if not app.env.doxygen_input_changed[name]: + logger.info(f"Doxygen build for {name} will be skipped (no changes)!") + return + + logger.info(f"Running Doxygen for {name}...") + run_doxygen( + app.config.doxyrunner_doxygen, + doxyfile, + app.config.doxyrunner_silent, + ) - logger.info("Syncing Doxygen output...") - sync_doxygen(doxyfile, tmp_outdir, outdir) + logger.info(f"Syncing Doxygen output for {name}...") + sync_doxygen(doxyfile, tmp_outdir, outdir) - shutil.rmtree(tmp_outdir) + shutil.rmtree(tmp_outdir) def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value("doxyrunner_doxygen", "doxygen", "env") - app.add_config_value("doxyrunner_doxyfile", None, "env") - app.add_config_value("doxyrunner_outdir", None, "env") - app.add_config_value("doxyrunner_outdir_var", None, "env") - app.add_config_value("doxyrunner_fmt", False, "env") - app.add_config_value("doxyrunner_fmt_vars", {}, "env") - app.add_config_value("doxyrunner_fmt_pattern", "@{}@", "env") app.add_config_value("doxyrunner_silent", True, "") + app.add_config_value("doxyrunner_projects", {}, "") app.connect("builder-inited", doxygen_build) diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index 67998cd4382f0..a2774faa1cdfd 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -211,6 +211,8 @@ def git_info_filter(app: Sphinx, pagename) -> tuple[str, str] | None: .decode("utf-8") .strip() ) + if not date_and_sha1: # added but not committed + return None date, sha1 = date_and_sha1.split(" ", 1) date_object = datetime.fromtimestamp(int(date)) last_update_fmt = app.config.html_last_updated_fmt diff --git a/doc/_extensions/zephyr/kconfig/__init__.py b/doc/_extensions/zephyr/kconfig/__init__.py index fe037d1c894a3..13ebd0b7d01a1 100644 --- a/doc/_extensions/zephyr/kconfig/__init__.py +++ b/doc/_extensions/zephyr/kconfig/__init__.py @@ -26,6 +26,10 @@ - kconfig_ext_paths: A list of base paths where to search for external modules Kconfig files when they use ``kconfig-ext: True``. The extension will look for ${BASE_PATH}/modules/${MODULE_NAME}/Kconfig. +- kconfig_gh_link_base_url: The base URL for the GitHub links. This is used to + generate links to the Kconfig files on GitHub. +- kconfig_zephyr_version: The Zephyr version. This is used to generate links to + the Kconfig files on GitHub. """ import argparse @@ -152,11 +156,18 @@ def kconfig_load(app: Sphinx) -> tuple[kconfiglib.Kconfig, dict[str, str]]: if not build_conf: continue + # Module Kconfig file has already been specified + if f"ZEPHYR_{name_var}_KCONFIG" in os.environ: + continue + if build_conf.get("kconfig"): kconfig = Path(module.project) / build_conf["kconfig"] os.environ[f"ZEPHYR_{name_var}_KCONFIG"] = str(kconfig) elif build_conf.get("kconfig-ext"): for path in app.config.kconfig_ext_paths: + # Assume that the kconfig file exists at this path. + # Technically the cmake variable can be constructed arbitarily + # by "{ext_path}/modules/modules.cmake" kconfig = Path(path) / "modules" / name / "Kconfig" if kconfig.exists(): os.environ[f"ZEPHYR_{name_var}_KCONFIG"] = str(kconfig) @@ -429,8 +440,14 @@ def kconfig_build_resources(app: Sphinx) -> None: kconfig_db_file = outdir / "kconfig.json" + kconfig_db = { + "gh_base_url": app.config.kconfig_gh_link_base_url, + "zephyr_version": app.config.kconfig_zephyr_version, + "symbols": db, + } + with open(kconfig_db_file, "w") as f: - json.dump(db, f) + json.dump(kconfig_db, f) app.config.html_extra_path.append(kconfig_db_file.as_posix()) app.config.html_static_path.append(RESOURCES_DIR.as_posix()) @@ -461,6 +478,8 @@ def kconfig_install( def setup(app: Sphinx): app.add_config_value("kconfig_generate_db", False, "env") app.add_config_value("kconfig_ext_paths", [], "env") + app.add_config_value("kconfig_gh_link_base_url", "", "") + app.add_config_value("kconfig_zephyr_version", "", "") app.add_node( KconfigSearchNode, diff --git a/doc/_extensions/zephyr/kconfig/static/kconfig.mjs b/doc/_extensions/zephyr/kconfig/static/kconfig.mjs index 6c94845a1079e..f76bf8baa92d8 100644 --- a/doc/_extensions/zephyr/kconfig/static/kconfig.mjs +++ b/doc/_extensions/zephyr/kconfig/static/kconfig.mjs @@ -5,6 +5,8 @@ const DB_FILE = 'kconfig.json'; const RESULTS_PER_PAGE_OPTIONS = [10, 25, 50]; +let zephyr_gh_base_url; +let zephyr_version; /* search state */ let db; @@ -57,13 +59,38 @@ function showProgress(message) { p.appendChild(pText); } +/** + * Generate a GitHub link for a given file path in the Zephyr repository. + * @param {string} path - The file path in the repository. + * @param {number} [line] - Optional line number to link to. + * @param {string} [mode=blob] - The mode (blob or edit). Defaults to 'blob'. + * @param {string} [revision=main] - The branch, tag, or commit hash. Defaults to 'main'. + * @returns {string} - The generated GitHub URL. + */ +function getGithubLink(path, line, mode = "blob", revision = "main") { + let url = [ + zephyr_gh_base_url, + mode, + revision, + path + ].join("/"); + + if (line !== undefined){ + url += `#L${line}`; + } + + return url; +} + + /** * Render a Kconfig literal property. * @param {Element} parent Parent element. * @param {String} title Title. - * @param {String} content Content. + * @param {Element} contentElement Content Element. */ -function renderKconfigPropLiteral(parent, title, content) { +function renderKconfigPropLiteralElement(parent, title, contentElement) +{ const term = document.createElement('dt'); parent.appendChild(term); @@ -81,8 +108,18 @@ function renderKconfigPropLiteral(parent, title, content) { literal.className = 'pre'; code.appendChild(literal); - const literalText = document.createTextNode(content); - literal.appendChild(literalText); + literal.appendChild(contentElement); +} + +/** + * Render a Kconfig literal property. + * @param {Element} parent Parent element. + * @param {String} title Title. + * @param {String} content Content. + */ +function renderKconfigPropLiteral(parent, title, content) { + const contentElement = document.createTextNode(content); + renderKconfigPropLiteralElement(parent, title, contentElement); } /** @@ -268,7 +305,17 @@ function renderKconfigEntry(entry) { renderKconfigPropList(props, 'Implied by', entry.implied_by, true); renderKconfigPropList(props, 'Ranges', entry.ranges, false); renderKconfigPropList(props, 'Choices', entry.choices, false); - renderKconfigPropLiteral(props, 'Location', `${entry.filename}:${entry.linenr}`); + + /* symbol location with permalink */ + const locationPermalink = document.createElement('a'); + locationPermalink.href = getGithubLink(entry.filename, entry.linenr, "blob", zephyr_version); + + const locationElement = document.createTextNode(`${entry.filename}:${entry.linenr}`); + locationElement.class = "pre"; + locationPermalink.appendChild(locationElement); + + renderKconfigPropLiteralElement(props, 'Location', locationPermalink); + renderKconfigPropLiteral(props, 'Menu path', entry.menupath); return container; @@ -483,7 +530,9 @@ function setupKconfigSearch() { fetch(DB_FILE) .then(response => response.json()) .then(json => { - db = json; + db = json["symbols"]; + zephyr_gh_base_url = json["gh_base_url"]; + zephyr_version = json["zephyr_version"]; results.replaceChildren(); diff --git a/doc/_scripts/gen_devicetree_rest.py b/doc/_scripts/gen_devicetree_rest.py index ed5694675068e..9a28b591f29f6 100644 --- a/doc/_scripts/gen_devicetree_rest.py +++ b/doc/_scripts/gen_devicetree_rest.py @@ -162,7 +162,7 @@ def init_vnd2ref_target(self): def main(): args = parse_args() setup_logging(args.verbose) - bindings = load_bindings(args.dts_roots, args.dts_folders) + bindings = load_bindings(args.dts_roots, args.dts_folders, args.dts_files) base_binding = load_base_binding() driver_sources = load_driver_sources() vnd_lookup = VndLookup(args.vendor_prefixes, bindings) @@ -182,6 +182,8 @@ def parse_args(): be set in DTS_ROOTS''') parser.add_argument('--dts-folder', dest='dts_folders', action='append', default=[], help='additional DTS folders containing binding files') + parser.add_argument('--dts-file', dest='dts_files', action='append', default=[], + help='additional individual DTS binding files') parser.add_argument('--turbo-mode', action='store_true', help='Enable turbo mode (dummy references)') parser.add_argument('out_dir', help='output files are generated here') @@ -198,7 +200,7 @@ def setup_logging(verbose): logging.basicConfig(format='%(filename)s:%(levelname)s: %(message)s', level=log_level) -def load_bindings(dts_roots, dts_folders): +def load_bindings(dts_roots, dts_folders, dts_files): # Get a list of edtlib.Binding objects from searching 'dts_roots'. if not dts_roots: @@ -213,6 +215,7 @@ def load_bindings(dts_roots, dts_folders): for folders in dts_folders: binding_files.extend(glob.glob(f'{folders}/*.yml', recursive=False)) binding_files.extend(glob.glob(f'{folders}/*.yaml', recursive=False)) + binding_files.extend(dts_files) bindings = edtlib.bindings_from_paths(binding_files, ignore_errors=True) diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index 87d54e5032eca..14bc2504a4971 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -210,7 +210,7 @@ ('reference/peripherals/uart', 'hardware/peripherals/uart'), ('reference/peripherals/video', 'hardware/peripherals/video'), ('reference/pm/index', 'services/pm/api/index'), - ('reference/settings/index', 'services/settings/index'), + ('reference/settings/index', 'services/storage/settings/index'), ('reference/shell/index', 'services/shell/index'), ('reference/storage/fcb/fcb', 'services/storage/fcb/fcb'), ('reference/storage/index', 'services/storage/index'), @@ -308,5 +308,7 @@ ('samples/subsys/video/video', 'samples/drivers/video/video'), ('services/crypto/tinycrypt', 'services/crypto/psa_crypto'), ('services/portability/posix', 'services/portability/posix/index'), + ('services/secure_storage', 'services/storage/secure_storage/index'), + ('services/settings/index', 'services/storage/settings/index'), # zephyr-keep-sorted-stop ] diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 1bc107e11c249..586450fc64962 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -1128,6 +1128,10 @@ li>a.code-sample-link.reference.internal.current { } } +.sidebar.board-overview { + color: var(--admonition-note-color); +} + .sidebar.board-overview .sidebar-title { font-family: var(--header-font-family); background: var(--admonition-note-title-background-color); @@ -1137,10 +1141,6 @@ li>a.code-sample-link.reference.internal.current { text-align: center; } -.sidebar.board-overview * { - color: var(--admonition-note-color); -} - .sidebar.board-overview figure { padding: 1rem; margin-bottom: -1rem; @@ -1175,3 +1175,17 @@ li>a.code-sample-link.reference.internal.current { .sidebar.board-overview dl.field-list>dd code { font-size: 0.9em; } + +.sidebar.board-overview #board-github-link { + text-align: center; + margin-bottom: 1em; + font-size: 0.9em; +} + +.sidebar.board-overview #board-github-link a { + display: inline-block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width:80%; +} diff --git a/doc/build/cmake/index.rst b/doc/build/cmake/index.rst index ee9bde7206ff8..2b180eaa5d95e 100644 --- a/doc/build/cmake/index.rst +++ b/doc/build/cmake/index.rst @@ -43,6 +43,9 @@ source file :file:`src/main.c`, behavior that we surely do not want. The ``PUBLIC`` keyword could however be useful when modifying the include paths of a target library. +When introducing build system code using CMake or adding new CMake files, +please follow the style guidelines outlined :ref:`here `. + Build and Configuration Phases ============================== diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index 189c3a3dadfa6..f604f29d9e077 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -104,9 +104,10 @@ does not apply to macros which take cell names as arguments. For-each macros =============== -There is currently only one "generic" for-each macro, -:c:macro:`DT_FOREACH_CHILD`, which allows iterating over the children of a -devicetree node. +The :c:macro:`DT_FOREACH_ANCESTOR` macro allows iterating over the ancestor node +of a devicetree node. +Additionally, the :c:macro:`DT_FOREACH_CHILD` macro allows iterating over the +children of a devicetree node. There are special-purpose for-each macros, like :c:macro:`DT_INST_FOREACH_STATUS_OKAY`, but these require ``DT_DRV_COMPAT`` to diff --git a/doc/build/dts/phandles.rst b/doc/build/dts/phandles.rst index 65d8a16d7e189..a3760864f55fa 100644 --- a/doc/build/dts/phandles.rst +++ b/doc/build/dts/phandles.rst @@ -324,7 +324,7 @@ specifier space ``foo``. For example: pwms: type: phandle-array -The ``dmas`` property's specifier space is "dma". The ``pwm`` property's +The ``dmas`` property's specifier space is "dma". The ``pwms`` property's specifier space is ``pwm``. Special case: GPIO diff --git a/doc/build/dts/zephyr-user-node.rst b/doc/build/dts/zephyr-user-node.rst index 9cd0226eb9a90..f2fcea6f94b16 100644 --- a/doc/build/dts/zephyr-user-node.rst +++ b/doc/build/dts/zephyr-user-node.rst @@ -79,19 +79,16 @@ device pointers like this: const struct device *my_device = DEVICE_DT_GET(DT_PROP(ZEPHYR_USER_NODE, handle)); - #define PHANDLE_TO_DEVICE(node_id, prop, idx) \ - DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)), - /* * Same thing as: * * ... *my_devices[] = { * DEVICE_DT_GET(DT_NODELABEL(gpio0)), - * DEVICE_DT_GET(DT_NODELABEL(gpio1)), + * DEVICE_DT_GET(DT_NODELABEL(gpio1)) * }; */ const struct device *my_devices[] = { - DT_FOREACH_PROP_ELEM(ZEPHYR_USER_NODE, handles, PHANDLE_TO_DEVICE) + DT_FOREACH_PROP_ELEM_SEP(ZEPHYR_USER_NODE, handles, DEVICE_DT_GET_BY_IDX, (,)) }; GPIOs diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 3a70d90da8219..ad62d86eb3d43 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -149,13 +149,6 @@ used. 3. From the CMake variable cache - Furthermore if ``CONF_FILE`` is set as single configuration file of the - form :file:`prj_.conf` and if file - :file:`boards/_.conf` exists in same folder as file - :file:`prj_.conf`, the result of merging :file:`prj_.conf` and - :file:`boards/_.conf` is used - note that this feature is - deprecated, :ref:`application-file-suffixes` should be used instead. - #. Otherwise, if :file:`boards/.conf` exists in the application configuration directory, the result of merging it with :file:`prj.conf` is used. diff --git a/doc/build/kconfig/tips.rst b/doc/build/kconfig/tips.rst index d79c5d122d78b..1225d84914781 100644 --- a/doc/build/kconfig/tips.rst +++ b/doc/build/kconfig/tips.rst @@ -876,31 +876,10 @@ For a Kconfig symbol that enables a driver/subsystem FOO, consider having just usually be clear in the context of an option that can be toggled on/off, and makes things consistent. +Style +===== -Header comments and other nits -============================== - -A few formatting nits, to help keep things consistent: - -- Use this format for any header comments at the top of ``Kconfig`` files: - - .. code-block:: none - - # - (Blank line) - # Copyright (c) 2019 ... - # SPDX-License-Identifier: - (Blank line) - (Kconfig definitions) - -- Format comments as ``# Comment`` rather than ``#Comment`` - -- Put a blank line before/after each top-level ``if`` and ``endif`` - -- Use a single tab for each indentation - -- Indent help text with two extra spaces - +See :ref:`coding_style` for style guidelines. Lesser-known/used Kconfig features ********************************** diff --git a/doc/build/snippets/writing.rst b/doc/build/snippets/writing.rst index 87ed6448f03e6..7f0fb4a04716e 100644 --- a/doc/build/snippets/writing.rst +++ b/doc/build/snippets/writing.rst @@ -31,6 +31,15 @@ this: EXTRA_DTC_OVERLAY_FILE: foo.overlay EXTRA_CONF_FILE: foo.conf +In addition, snippets can also be applied to sysbuild configuration like so: + +.. code-block:: yaml + + name: foo + append: + SB_EXTRA_CONF_FILE: sb.conf + EXTRA_CONF_FILE: app.conf + Namespacing *********** @@ -156,6 +165,20 @@ This :file:`snippet.yml` adds :file:`foo.conf` to the build: The path to :file:`foo.conf` is relative to the directory containing :file:`snippet.yml`. +Sysbuild ``.conf`` files +************************ + +This :file:`snippet.yml` adds :file:`foo.conf` to the sysbuild configuration: + +.. code-block:: yaml + + name: foo + append: + SB_EXTRA_CONF_FILE: foo.conf + +The path to :file:`foo.conf` is relative to the directory containing +:file:`snippet.yml`. + ``DTS_EXTRA_CPPFLAGS`` ********************** diff --git a/doc/build/version/index.rst b/doc/build/version/index.rst index 1725e1a66463f..bd5f205aed237 100644 --- a/doc/build/version/index.rst +++ b/doc/build/version/index.rst @@ -39,19 +39,19 @@ field to a single byte (note that there may be further restrictions depending up is used for, e.g. bootloaders might only support some of these fields or might place limits on the maximum values of fields): -+---------------+----------------------------------------+ -| Field | Data type | -+---------------+----------------------------------------+ -| VERSION_MAJOR | Numerical (0-255) | -+---------------+----------------------------------------+ -| VERSION_MINOR | Numerical (0-255) | -+---------------+----------------------------------------+ -| PATCHLEVEL | Numerical (0-255) | -+---------------+----------------------------------------+ -| VERSION_TWEAK | Numerical (0-255) | -+---------------+----------------------------------------+ -| EXTRAVERSION | Alphanumerical (Lowercase a-z and 0-9) | -+---------------+----------------------------------------+ ++---------------+-------------------------------------------------------+ +| Field | Data type | ++---------------+-------------------------------------------------------+ +| VERSION_MAJOR | Numerical (0-255) | ++---------------+-------------------------------------------------------+ +| VERSION_MINOR | Numerical (0-255) | ++---------------+-------------------------------------------------------+ +| PATCHLEVEL | Numerical (0-255) | ++---------------+-------------------------------------------------------+ +| VERSION_TWEAK | Numerical (0-255) | ++---------------+-------------------------------------------------------+ +| EXTRAVERSION | Alphanumerical (Lowercase a-z and 0-9) and "." or "-" | ++---------------+-------------------------------------------------------+ When an application is configured using CMake, the version file will be automatically processed, and will be checked automatically each time the version is changed, so CMake does not need to be @@ -65,7 +65,7 @@ For the sections below, examples are provided for the following :file:`VERSION` VERSION_MINOR = 2 PATCHLEVEL = 3 VERSION_TWEAK = 4 - EXTRAVERSION = unstable + EXTRAVERSION = unstable.5 Use in code =========== @@ -74,120 +74,120 @@ To use the version information in application code, the version file must be inc fields can be freely used. The include file name is :file:`app_version.h` (no path is needed), the following defines are available: -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| Define | Type | Field(s) | Example | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APPVERSION | Numerical | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | -| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | -| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | -| | | ``VERSION_TWEAK`` | | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_NUMBER | Numerical | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | -| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | -| | | ``PATCHLEVEL`` | | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_TWEAK | Numerical | ``VERSION_TWEAK`` | 4 | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3-unstable" | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION`` |br| | | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_EXTENDED_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3-unstable+4" | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION`` |br| | | -| | | ``VERSION_TWEAK`` |br| | | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_TWEAK_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3+4" | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``VERSION_TWEAK`` |br| | | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_BUILD_VERSION | String (unquoted) | None (value of ``git describe --abbrev=12 --always`` | v3.3.0-18-g2c85d9224fca | -| | | from application repository) | | -+-----------------------------+-------------------+------------------------------------------------------+-------------------------+ ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| Define | Type | Field(s) | Example | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APPVERSION | Numerical | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | +| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | +| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | +| | | ``VERSION_TWEAK`` | | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_VERSION_NUMBER | Numerical | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | +| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | +| | | ``PATCHLEVEL`` | | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_TWEAK | Numerical | ``VERSION_TWEAK`` | 4 | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_VERSION_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3-unstable.5" | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` |br| | | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_VERSION_EXTENDED_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3-unstable.5+4" | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` |br| | | +| | | ``VERSION_TWEAK`` |br| | | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_VERSION_TWEAK_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3+4" | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``VERSION_TWEAK`` |br| | | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ +| APP_BUILD_VERSION | String (unquoted) | None (value of ``git describe --abbrev=12 --always`` | v3.3.0-18-g2c85d9224fca | +| | | from application repository) | | ++-----------------------------+-------------------+------------------------------------------------------+---------------------------+ Use in Kconfig ============== The following variables are available for usage in Kconfig files: -+--------------------------------+-----------+--------------------------+------------------+ -| Variable | Type | Field(s) | Example | -+--------------------------------+-----------+--------------------------+------------------+ -| $(VERSION_MAJOR) | Numerical | ``VERSION_MAJOR`` | 1 | -+--------------------------------+-----------+--------------------------+------------------+ -| $(VERSION_MINOR) | Numerical | ``VERSION_MINOR`` | 2 | -+--------------------------------+-----------+--------------------------+------------------+ -| $(PATCHLEVEL) | Numerical | ``PATCHLEVEL`` | 3 | -+--------------------------------+-----------+--------------------------+------------------+ -| $(VERSION_TWEAK) | Numerical | ``VERSION_TWEAK`` | 4 | -+--------------------------------+-----------+--------------------------+------------------+ -| $(APPVERSION) | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION`` | | -+--------------------------------+-----------+--------------------------+------------------+ -| $(APP_VERSION_EXTENDED_STRING) | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable+4 | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION``, |br| | | -| | | ``VERSION_TWEAK`` | | -+--------------------------------+-----------+--------------------------+------------------+ -| $(APP_VERSION_TWEAK_STRING) | String | ``VERSION_MAJOR``, |br| | 1.2.3+4 | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``VERSION_TWEAK`` | | -+--------------------------------+-----------+--------------------------+------------------+ ++--------------------------------+-----------+--------------------------+--------------------+ +| Variable | Type | Field(s) | Example | ++--------------------------------+-----------+--------------------------+--------------------+ +| $(VERSION_MAJOR) | Numerical | ``VERSION_MAJOR`` | 1 | ++--------------------------------+-----------+--------------------------+--------------------+ +| $(VERSION_MINOR) | Numerical | ``VERSION_MINOR`` | 2 | ++--------------------------------+-----------+--------------------------+--------------------+ +| $(PATCHLEVEL) | Numerical | ``PATCHLEVEL`` | 3 | ++--------------------------------+-----------+--------------------------+--------------------+ +| $(VERSION_TWEAK) | Numerical | ``VERSION_TWEAK`` | 4 | ++--------------------------------+-----------+--------------------------+--------------------+ +| $(APPVERSION) | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable.5 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` | | ++--------------------------------+-----------+--------------------------+--------------------+ +| $(APP_VERSION_EXTENDED_STRING) | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable.5+4 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION``, |br| | | +| | | ``VERSION_TWEAK`` | | ++--------------------------------+-----------+--------------------------+--------------------+ +| $(APP_VERSION_TWEAK_STRING) | String | ``VERSION_MAJOR``, |br| | 1.2.3+4 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``VERSION_TWEAK`` | | ++--------------------------------+-----------+--------------------------+--------------------+ Use in CMake ============ The following variable are available for usage in CMake files: -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| Variable | Type | Field(s) | Example | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APPVERSION | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | -| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | -| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | -| | | ``VERSION_TWEAK`` | | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APP_VERSION_NUMBER | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | -| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | -| | | ``PATCHLEVEL`` | | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APP_VERSION_TWEAK | Numerical | ``VERSION_TWEAK`` | 4 | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APP_VERSION_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION`` | | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APP_VERSION_EXTENDED_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable+4 | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION``, |br| | | -| | | ``VERSION_TWEAK`` | | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ -| APP_VERSION_TWEAK_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3+4 | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``VERSION_TWEAK`` | | -+-----------------------------+-----------------+---------------------------------------------------+------------------+ ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| Variable | Type | Field(s) | Example | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APPVERSION | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | +| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | +| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | +| | | ``VERSION_TWEAK`` | | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APP_VERSION_NUMBER | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | +| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | +| | | ``PATCHLEVEL`` | | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APP_VERSION_TWEAK | Numerical | ``VERSION_TWEAK`` | 4 | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APP_VERSION_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable.5 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` | | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APP_VERSION_EXTENDED_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable.5+4 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION``, |br| | | +| | | ``VERSION_TWEAK`` | | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ +| APP_VERSION_TWEAK_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3+4 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``VERSION_TWEAK`` | | ++-----------------------------+-----------------+---------------------------------------------------+--------------------+ Use in MCUboot-supported applications ===================================== diff --git a/doc/conf.py b/doc/conf.py index 479fd358ee70f..a9646be01e596 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -35,7 +35,7 @@ # -- Project -------------------------------------------------------------- project = "Zephyr Project" -copyright = "2015-2024 Zephyr Project members and individual contributors" +copyright = "2015-2025 Zephyr Project members and individual contributors" author = "The Zephyr Project Contributors" # parse version from 'VERSION' file @@ -198,8 +198,6 @@ ("latest", "/"), ("4.0.0", "/4.0.0/"), ("3.7.0 (LTS)", "/3.7.0/"), - ("3.6.0", "/3.6.0/"), - ("2.7.6 (LTS)", "/2.7.6/"), ), "display_gh_links": True, "reference_links": { @@ -247,15 +245,22 @@ # -- Options for zephyr.doxyrunner plugin --------------------------------- doxyrunner_doxygen = os.environ.get("DOXYGEN_EXECUTABLE", "doxygen") -doxyrunner_doxyfile = ZEPHYR_BASE / "doc" / "zephyr.doxyfile.in" -doxyrunner_outdir = ZEPHYR_BUILD / "doxygen" -doxyrunner_fmt = True -doxyrunner_fmt_vars = {"ZEPHYR_BASE": str(ZEPHYR_BASE), "ZEPHYR_VERSION": version} -doxyrunner_outdir_var = "DOXY_OUT" +doxyrunner_projects = { + "zephyr": { + "doxyfile": ZEPHYR_BASE / "doc" / "zephyr.doxyfile.in", + "outdir": ZEPHYR_BUILD / "doxygen", + "fmt": True, + "fmt_vars": { + "ZEPHYR_BASE": str(ZEPHYR_BASE), + "ZEPHYR_VERSION": version, + }, + "outdir_var": "DOXY_OUT", + }, +} # -- Options for zephyr.doxybridge plugin --------------------------------- -doxybridge_dir = doxyrunner_outdir +doxybridge_projects = {"zephyr": doxyrunner_projects["zephyr"]["outdir"]} # -- Options for html_redirect plugin ------------------------------------- @@ -293,6 +298,8 @@ kconfig_generate_db = True kconfig_ext_paths = [ZEPHYR_BASE] +kconfig_gh_link_base_url = "https://github.com/zephyrproject-rtos/zephyr" +kconfig_zephyr_version = f"v{version}" if is_release else "main" # -- Options for zephyr.external_content ---------------------------------- @@ -357,7 +364,8 @@ # -- Options for zephyr.api_overview -------------------------------------- -api_overview_doxygen_base_url = "../../doxygen/html" +api_overview_doxygen_out_dir = str(doxyrunner_projects["zephyr"]["outdir"]) +api_overview_base_url = "https://github.com/zephyrproject-rtos/zephyr" def setup(app): # theme customizations diff --git a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst index 1156f2a4e89e9..f2a15814e3f35 100644 --- a/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst +++ b/doc/connectivity/bluetooth/api/audio/bluetooth-le-audio-arch.rst @@ -294,6 +294,7 @@ GAF and the top layer profiles gave been implemented in Zephyr with the followin cluster=true; label="CCP"; style=solid; + CCP_H [label="ccp.h"]; TBS_H [label="tbs.h"]; } } @@ -331,6 +332,7 @@ GAF and the top layer profiles gave been implemented in Zephyr with the followin CAP_H -> MCS_H; CAP_H -> MCC_H; CAP_H -> MP_H; + CAP_H -> CCP_H; CAP_H -> TBS_H; CAP_H -> BAP_H; CAP_H -> BAP_PRESET_H; @@ -341,6 +343,7 @@ GAF and the top layer profiles gave been implemented in Zephyr with the followin CSIP_H -> MCS_H; CSIP_H -> MCC_H; CSIP_H -> MP_H; + CSIP_H -> CCP_H; CSIP_H -> TBS_H; CSIP_H -> BAP_H; CSIP_H -> BAP_PRESET_H; @@ -719,12 +722,12 @@ Bluetooth Audio Stack. | | | | | - Shell Module | | | | | | | - BSIM test | | +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ - | CCP | Call Control Server | 1.0 | 3.0 | - Feature complete | - API refactor | - | | | | | - Shell Module | - Sample Application | + | CCP | Call Control Server | 1.0 | 3.0 | - Feature complete | - API refactor (in progress) | + | | | | | - Shell Module | - Sample Application (in progress) | | | | | | - BSIM test | | | +-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ - | | Call Control Client | 1.0 | 3.0 | - Feature complete | - API refactor | - | | | | | - Shell Module | - Sample Application | + | | Call Control Client | 1.0 | 3.0 | - Feature complete | - API refactor (in progress) | + | | | | | - Shell Module | - Sample Application (in progress) | | | | | | - BSIM test | | +--------+-------------------------------+---------+------------------+-----------------------+--------------------------------------------------+ | MCP | Media Control Server | 1.0 | 3.0 | - Feature complete | - API refactor | @@ -1235,10 +1238,10 @@ The LE audio channel on Discord Zephyr has a specific Discord channel for LE Audio development, which is open to all. Find it here at https://discordapp.com/channels/720317445772017664/1207326649591271434 or simply -search for "ble-audio" from within Discord. -Since the ``#ble-audio`` channel is open for all, +search for "bt-audio" from within Discord. +Since the ``#bt-audio`` channel is open for all, we cannot discuss any specifications that are in development in that channel. -For discussions that require a Bluetooth SIG membership we refer to the ``#bluetooth-sig`` +For discussions that require a Bluetooth SIG membership we refer to the ``#bt-sig`` Discord channel found at https://discordapp.com/channels/720317445772017664/869172014018097162. Zephyr weekly meetings diff --git a/doc/connectivity/bluetooth/api/hci.txt b/doc/connectivity/bluetooth/api/hci.txt index ee75f0799f9f0..2ad17bfae5eb0 100644 --- a/doc/connectivity/bluetooth/api/hci.txt +++ b/doc/connectivity/bluetooth/api/hci.txt @@ -805,7 +805,7 @@ event shall be generated. Zephyr Write Tx Power Level (per Role/Connection) Command ========================================================= -This command dynamically modifies BLE Tx power level given a handle and a +This command dynamically modifies Bluetooth Tx power level given a handle and a handle type (advertiser, scanner, connection). +--------------------------+-------+--------------------+--------------------+ @@ -818,8 +818,8 @@ handle type (advertiser, scanner, connection). | | | | Selected_Tx_Power | +--------------------------+-------+--------------------+--------------------+ -The Tx power of the BLE radio interface is modified for any low-level link by -the controller with a high degree of flexibility. The BLE link whose power is +The Tx power of the Bluetooth radio interface is modified for any low-level link by +the controller with a high degree of flexibility. The Bluetooth link whose power is set is identified based on a handle type (advertiser, scanner, connection) and handle pair. @@ -927,10 +927,10 @@ event shall be generated. Zephyr Read Tx Power Level (per Role/Connection) Command ======================================================== -This command reads the BLE Tx power level. In contrast to the standardized HCI +This command reads the Bluetooth Tx power level. In contrast to the standardized HCI command, i.e. Read_Transmit_Power_Level, which returns the transmitted power level only for a specified connection handle, this command operates for both -connected and unconnected states. It gets the BLE Tx power level for any given +connected and unconnected states. It gets the Bluetooth Tx power level for any given handle type (advertiser, scanner, connection) and handle. +--------------------------+-------+--------------------+--------------------+ @@ -943,7 +943,7 @@ handle type (advertiser, scanner, connection) and handle. | | | | Tx_Power_Level | +--------------------------+-------+--------------------+--------------------+ -The Tx power of the BLE radio interface used for a low-level link identified +The Tx power of the Bluetooth radio interface used for a low-level link identified by a pair of Handle_Type and Handle is retrieved from the controller. The role/state defining input parameter is the Handle_Type, whereas its diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index 926754ab0f022..959872ae9b9fe 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -212,9 +212,10 @@ re-provisioned. The complete list of available options is defined in :c:enum:`bt provisioning. In this case, the device stays provisioned and the new composition data takes place after re-provisioning using the Remote Provisioning models. :c:enumerator:`BT_MESH_DFU_EFFECT_UNPROV` - This effect is chosen if the composition data in the new firmware changes, the device doesn't + This effect is chosen if the composition data in the new firmware changes, the device does not support the remote provisioning, and the new composition data takes effect after applying the - firmware. + firmware. The effect can also be chosen, if it is necessary to unprovision the device for + application-specific reasons. When the Target node receives the Firmware Update Firmware Metadata Check message, the Firmware Update Server model calls the :c:member:`bt_mesh_dfu_srv_cb.check` callback, the application can diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index 87678a1630ad9..a76bdd17b5bb4 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -1071,12 +1071,13 @@ The :ref:`bluetooth_mesh_blob_cli` can be added to the mesh shell by enabling th * ``Addr``: Unicast address of the Target node's BLOB Transfer Server model. -``mesh models blob cli bounds []`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``mesh models blob cli caps [ []]`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Get the total boundary parameters of all Target nodes. + Retrieve transfer capabilities for Target nodes. * ``Group``: Optional group address to use when communicating with Target nodes. If omitted, the BLOB Transfer Client will address each Target node individually. + * ``TimeoutBase``: Optional time to wait for responses from Target nodes, in 10-second increments. ``mesh models blob cli tx [ []]`` @@ -1170,6 +1171,27 @@ receiving any BLOB data, but the implementation in the mesh shell will discard t Get a list of all BLOB Transfer Server model instances on the node. +Binary Large Object (BLOB) Transfer flash stream +------------------------------------------------ +BLOB flash stream configuration can be added to the mesh shell by enabling the +:kconfig:option:`CONFIG_BT_MESH_SHELL_BLOB_IO_FLASH` option. By default, the shell uses a +dummy BLOB stream. This option allows the user to specify which area in the flash to use. +See :ref:`flash_map_api` for information on how to obtain related parameters. + +``mesh models blob flash-stream-set []`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Set the BLOB stream to a specified area. + + * ``AreaID``: Flash area ID to write/read the BLOB to/from. + * ``Offset``: Optional offset into the flash area to place the BLOB at (in bytes). + +``mesh models blob flash-stream-unset`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Set the BLOB stream back to the dummy stream. + + Firmware Update Client model ---------------------------- @@ -1471,9 +1493,9 @@ commands, a Firmware Distribution Server must be instantiated by the application DFU metadata ------------ -The DFU metadata commands allow generating metadata that can be used by a Target node to check the -firmware before accepting it. The commands are enabled through the -:kconfig:option:`CONFIG_BT_MESH_DFU_METADATA` configuration option. +The DFU metadata shell commands allow generating metadata that can be used by a Target node to +check the firmware before accepting it. The commands are enabled through the +:kconfig:option:`CONFIG_BT_MESH_SHELL_DFU_METADATA` configuration option. ``mesh models dfu metadata comp-clear`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/connectivity/bluetooth/bluetooth-arch.rst b/doc/connectivity/bluetooth/bluetooth-arch.rst index eeb2f5bbd6d5f..1ae6ce9ff4dca 100644 --- a/doc/connectivity/bluetooth/bluetooth-arch.rst +++ b/doc/connectivity/bluetooth/bluetooth-arch.rst @@ -10,15 +10,14 @@ This page describes the software architecture of Zephyr's Bluetooth protocol stack. .. note:: - Zephyr supports mainly Bluetooth Low Energy (BLE), the low-power + Zephyr supports mainly Bluetooth Low Energy (LE), the low-power version of the Bluetooth specification. Zephyr also has limited support - for portions of the BR/EDR Host. Throughout this architecture document we - use BLE interchangeably for Bluetooth except when noted. + for portions of the BR/EDR Host. .. _bluetooth-layers: -BLE Layers -========== +Bluetooth LE Layers +=================== There are 3 main layers that together constitute a full Bluetooth Low Energy protocol stack: @@ -62,7 +61,7 @@ following configurations are commonly used: * **Single-chip configuration**: In this configuration, a single microcontroller implements all three layers and the application itself. This can also be called a - system-on-chip (SoC) implementation. In this case the BLE Host and the BLE + system-on-chip (SoC) implementation. In this case the Bluetooth Host and the Bluetooth Controller communicate directly through function calls and queues in RAM. The Bluetooth specification does not specify how HCI is implemented in this single-chip configuration and so how HCI commands, events, and data flows between @@ -75,11 +74,11 @@ following configurations are commonly used: configuration. This configuration allows for a wider variety of combinations of Hosts when using the Zephyr OS as a Controller. Since HCI ensures interoperability among Host and Controller implementations, including of course - Zephyr's very own BLE Host and Controller, users of the Zephyr Controller can + Zephyr's very own Bluetooth Host and Controller, users of the Zephyr Controller can choose to use whatever Host running on any platform they prefer. For example, - the host can be the Linux BLE Host stack (BlueZ) running on any processor + the host can be the Linux Bluetooth Host stack (BlueZ) running on any processor capable of supporting Linux. The Host processor may of course also run Zephyr - and the Zephyr OS BLE Host. Conversely, combining an IC running the Zephyr + and the Zephyr OS Bluetooth Host. Conversely, combining an IC running the Zephyr Host with an external Controller that does not run Zephyr is also supported. .. _bluetooth-build-types: @@ -88,12 +87,12 @@ Build Types =========== The Zephyr software stack as an RTOS is highly configurable, and in particular, -the BLE subsystem can be configured in multiple ways during the build process to +the Bluetooth subsystem can be configured in multiple ways during the build process to include only the features and layers that are required to reduce RAM and ROM footprint as well as power consumption. Here's a short list of the different -BLE-enabled builds that can be produced from the Zephyr project codebase: +Bluetooth-enabled builds that can be produced from the Zephyr project codebase: -* **Controller-only build**: When built as a BLE Controller, Zephyr includes +* **Controller-only build**: When built as a Bluetooth Controller, Zephyr includes the Link Layer and a special application. This application is different depending on the physical transport chosen for HCI: @@ -114,7 +113,7 @@ BLE-enabled builds that can be produced from the Zephyr project codebase: corresponding device tree node is enabled. * **Host-only build**: A Zephyr OS Host build will contain the Application and - the BLE Host, along with an HCI driver (UART or SPI) to interface with an + the Bluetooth Host, along with an HCI driver (UART or SPI) to interface with an external Controller chip. A build of this type sets the following Kconfig option values: @@ -143,12 +142,12 @@ BLE-enabled builds that can be produced from the Zephyr project codebase: used for Controller-only builds can be built as Combined The picture below shows the SoC or single-chip configuration when using a Zephyr -combined build (a build that includes both a BLE Host and a Controller in the +combined build (a build that includes both a Bluetooth Host and a Controller in the same firmware image that is programmed onto the chip): .. figure:: img/ble_cfg_single.png :align: center - :alt: BLE Combined build on a single chip + :alt: Bluetooth Combined build on a single chip A Combined build on a Single-Chip configuration @@ -157,25 +156,25 @@ combinations are possible, some of which are depicted below: .. figure:: img/ble_cfg_dual.png :align: center - :alt: BLE dual-chip configuration builds + :alt: Bluetooth dual-chip configuration builds Host-only and Controller-only builds on dual-chip configurations When using a Zephyr Host (left side of image), two instances of Zephyr OS must be built with different configurations, yielding two separate images that must be programmed into each of the chips respectively. The Host build image -contains the application, the BLE Host and the selected HCI driver (UART or +contains the application, the Bluetooth Host and the selected HCI driver (UART or SPI), while the Controller build runs either the :zephyr:code-sample:`bluetooth_hci_uart`, or the :zephyr:code-sample:`bluetooth_hci_spi` app to provide an interface to -the BLE Controller. +the Bluetooth Controller. This configuration is not limited to using a Zephyr OS Host, as the right side of the image shows. One can indeed take one of the many existing GNU/Linux -distributions, most of which include Linux's own BLE Host (BlueZ), to connect it +distributions, most of which include Linux's own Bluetooth Host (BlueZ), to connect it via UART or USB to one or more instances of the Zephyr OS Controller build. BlueZ as a Host supports multiple Controllers simultaneously for applications -that require more than one BLE radio operating at the same time but sharing the +that require more than one Bluetooth radio operating at the same time but sharing the same Host stack. Source tree layout diff --git a/doc/connectivity/bluetooth/bluetooth-dev.rst b/doc/connectivity/bluetooth/bluetooth-dev.rst index afefaf45a7e55..999eb8f3d4168 100644 --- a/doc/connectivity/bluetooth/bluetooth-dev.rst +++ b/doc/connectivity/bluetooth/bluetooth-dev.rst @@ -139,7 +139,7 @@ Simulated nRF5x with BabbleSim The :ref:`nrf52_bsim ` and :ref:`nrf5340bsim ` boards, are simulated target boards which emulate the necessary peripherals of a nRF52/53 SOC to be able to develop -and test BLE applications. +and test Bluetooth LE applications. These boards, use: * `BabbleSim`_ to simulate the nRF5x modem and the radio environment. diff --git a/doc/connectivity/bluetooth/bluetooth-le-host.rst b/doc/connectivity/bluetooth/bluetooth-le-host.rst index 26665ada3c312..53dc7d420c42a 100644 --- a/doc/connectivity/bluetooth/bluetooth-le-host.rst +++ b/doc/connectivity/bluetooth/bluetooth-le-host.rst @@ -21,7 +21,7 @@ host, and vice-versa. Perhaps the most important block above the HCI handling is the Generic Access Profile (GAP). GAP simplifies Bluetooth LE access by defining -four distinct roles of BLE usage: +four distinct roles of Bluetooth usage: * Connection-oriented roles @@ -31,9 +31,9 @@ four distinct roles of BLE usage: * Connection-less roles - * Broadcaster (sending out BLE advertisements, e.g. a smart beacon) + * Broadcaster (sending out Bluetooth LE advertisements, e.g. a smart beacon) - * Observer (scanning for BLE advertisements) + * Observer (scanning for Bluetooth LE advertisements) Each role comes with its own build-time configuration option: :kconfig:option:`CONFIG_BT_PERIPHERAL`, :kconfig:option:`CONFIG_BT_CENTRAL`, @@ -49,7 +49,7 @@ section. Peripheral role =============== -Most Zephyr-based BLE devices will most likely be peripheral-role +Most Zephyr-based Bluetooth LE devices will most likely be peripheral-role devices. This means that they perform connectable advertising and expose one or more GATT services. After registering services using the :c:func:`bt_gatt_service_register` API the application will typically diff --git a/doc/connectivity/bluetooth/bluetooth-shell.rst b/doc/connectivity/bluetooth/bluetooth-shell.rst index 1cfa5d8054689..95fda5c2f61d9 100644 --- a/doc/connectivity/bluetooth/bluetooth-shell.rst +++ b/doc/connectivity/bluetooth/bluetooth-shell.rst @@ -19,6 +19,7 @@ For specific Bluetooth functionality see also the following shell documentation shell/audio/csip.rst shell/audio/gmap.rst shell/audio/mcp.rst + shell/audio/tbs.rst shell/audio/tmap.rst shell/audio/pbp.rst shell/classic/a2dp.rst diff --git a/doc/connectivity/bluetooth/bluetooth-tools.rst b/doc/connectivity/bluetooth/bluetooth-tools.rst index 6e194adaa88de..3d8c314a3f909 100644 --- a/doc/connectivity/bluetooth/bluetooth-tools.rst +++ b/doc/connectivity/bluetooth/bluetooth-tools.rst @@ -40,7 +40,7 @@ Using BlueZ with Zephyr *********************** The Linux Bluetooth Protocol Stack, BlueZ, comes with a very useful set of -tools that can be used to debug and interact with Zephyr's BLE Host and +tools that can be used to debug and interact with Zephyr's Bluetooth Host and Controller. In order to benefit from these tools you will need to make sure that you are running a recent version of the Linux Kernel and BlueZ: @@ -62,7 +62,7 @@ You can then find :file:`btattach`, :file:`btmgt` and :file:`btproxy` in the :file:`tools/` folder and :file:`btmon` in the :file:`monitor/` folder. You'll need to enable BlueZ's experimental features so you can access its -most recent BLE functionality. Do this by editing the file +most recent Bluetooth functionality. Do this by editing the file :file:`/lib/systemd/system/bluetooth.service` and making sure to include the :literal:`-E` option in the daemon's execution start line: @@ -160,11 +160,11 @@ building and running a sample: $ sudo ./build/zephyr/zephyr.exe --bt-dev=hci0 -Using a Zephyr-based BLE Controller -=================================== +Using a Zephyr-based Bluetooth Controller +========================================= Depending on which hardware you have available, you can choose between two -transports when building a single-mode, Zephyr-based BLE Controller: +transports when building a single-mode, Zephyr-based Bluetooth Controller: * UART: Use the :zephyr:code-sample:`bluetooth_hci_uart` sample and follow the instructions in :ref:`bluetooth-hci-uart-qemu-posix`. @@ -309,7 +309,7 @@ peripheral samples such as :zephyr:code-sample:`ble_peripheral_hr` or Using Zephyr-based Controllers with BlueZ ***************************************** -If you want to test a Zephyr-powered BLE Controller using BlueZ's Bluetooth +If you want to test a Zephyr-powered Bluetooth Controller using BlueZ's Bluetooth Host, you will need a few tools described in the :ref:`bluetooth_bluez` section. Once you have installed the tools you can then use them to interact with your Zephyr-based controller: diff --git a/doc/connectivity/bluetooth/features.rst b/doc/connectivity/bluetooth/features.rst index b51678ed7d7a6..ed94b10035561 100644 --- a/doc/connectivity/bluetooth/features.rst +++ b/doc/connectivity/bluetooth/features.rst @@ -8,10 +8,10 @@ Supported features :depth: 2 Since its inception, Zephyr has had a strong focus on Bluetooth and, in -particular, on Bluetooth Low Energy (BLE). Through the contributions of +particular, on Bluetooth Low Energy (LE). Through the contributions of several companies and individuals involved in existing open source implementations of the Bluetooth specification (Linux's BlueZ) as well as the -design and development of BLE radio hardware, the protocol stack in Zephyr has +design and development of Bluetooth LE radio hardware, the protocol stack in Zephyr has grown to be mature and feature-rich, as can be seen in the section below. * Bluetooth v5.3 compliant @@ -41,7 +41,7 @@ grown to be mature and feature-rich, as can be seen in the section below. * All v5.3 specification features supported (except a few minor items) * Concurrent multi-protocol support ready * Intelligent scheduling of roles to minimize overlap - * Portable design to any open BLE radio, currently supports Nordic + * Portable design to any open Bluetooth LE radio, currently supports Nordic Semiconductor nRF52x and nRF53x SoC Series, as well as proprietary radios * Supports little and big endian architectures, and abstracts the hard real-time specifics so that they can be encapsulated in a hardware-specific diff --git a/doc/connectivity/bluetooth/shell/audio/cap.rst b/doc/connectivity/bluetooth/shell/audio/cap.rst index 9a9c520e3fd8d..f7b34930d6248 100644 --- a/doc/connectivity/bluetooth/shell/audio/cap.rst +++ b/doc/connectivity/bluetooth/shell/audio/cap.rst @@ -271,6 +271,7 @@ the optionally included CSIS instance by calling (:code:`cap_commander discover` [] [] [] broadcast_reception_stop : Stop broadcast reception + distribute_broadcast_code : Distribute broadcast code Before being able to perform any stream operation, the device must also perform the @@ -460,3 +461,21 @@ Starting and stopping broadcast reception uart:~$ cap_commander broadcast_reception_stop 0 Stopping broadcast reception on 1 connection(s) Broadcast reception stop completed + +Distributing the broadcast code +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: console + + uart:~$ bt connect + Connected: + uart:~$ bap_init + uart:~$ cap_commander discover + discovery completed with CSIS + uart:~$ bap_broadcast_assistant discover + BASS discover done with 1 recv states + uart:~$ cap_commander broadcast_reception_start 0 4 + Starting broadcast reception on 1 connection(s) + Broadcast reception start completed + uart:~$ cap_commander distribute_broadcast_code 0 "BroadcastCode" + Distribute broadcast code completed diff --git a/doc/connectivity/bluetooth/shell/audio/ccp.rst b/doc/connectivity/bluetooth/shell/audio/ccp.rst index 9d5c17c4e7c9c..0fbf3ed2181df 100644 --- a/doc/connectivity/bluetooth/shell/audio/ccp.rst +++ b/doc/connectivity/bluetooth/shell/audio/ccp.rst @@ -1,208 +1,24 @@ Bluetooth: Call Control Profile Shell ##################################### -This document describes how to run the call control functionality, both as -a client and as a (telephone bearer service (TBS)) server. Note that in the -examples below, some lines of debug have been removed to make this shorter -and provide a better overview. +Call Control Server +******************* +The Call Control Server is a role that typically resides on devices that can make calls, +including calls from apps such as Skype, e.g. (smart)phones and PCs, +which are typically GAP Central devices. -Telephone Bearer Service Client -******************************* - -The telephone bearer service client will typically exist on a resource -restricted device, such as headphones, but may also exist on e.g. phones or -laptops. The call control client will also thus typically be the advertiser. -The client can control the states of calls on a server using the call control -point. - -It is necessary to have :kconfig:option:`CONFIG_BT_TBS_CLIENT_LOG_LEVEL_DBG` -enabled for using the client interactively. - -Using the telephone bearer service client -========================================= - -When the Bluetooth stack has been initialized (:code:`bt init`), -and a device has been connected, the telephone bearer service client can -discover TBS on the connected device calling :code:`tbs_client discover`, which -will start a discovery for the TBS UUIDs and store the handles, and optionally -subscribe to all notifications (default is to subscribe to all). - -Since a server may have multiple TBS instances, most of the tbs_client commands -will take an index (starting from 0) as input. Joining calls require at least 2 -call IDs, and all call indexes shall be on the same TBS instance. - -A server will also have a GTBS instance, which is an abstraction layer for all -the telephone bearers on the server. If the server has both GTBS and TBS, -the client may subscribe and use either when sending requests if -:code:`BT_TBS_CLIENT_GTBS` is enabled. - -.. code-block:: console - - tbs_client --help - tbs_client - Bluetooth TBS_CLIENT shell commands - Subcommands: - discover :Discover TBS [subscribe] - set_signal_reporting_interval :Set the signal reporting interval - [<{instance_index, gtbs}>] - originate :Originate a call [<{instance_index, gtbs}>] - - terminate :terminate a call [<{instance_index, gtbs}>] - - accept :Accept a call [<{instance_index, gtbs}>] - hold :Place a call on hold [<{instance_index, - gtbs}>] - retrieve :Retrieve a held call [<{instance_index, - gtbs}>] - read_provider_name :Read the bearer name [<{instance_index, - gtbs}>] - read_bearer_uci :Read the bearer UCI [<{instance_index, gtbs}>] - read_technology :Read the bearer technology [<{instance_index, - gtbs}>] - read_uri_list :Read the bearer's supported URI list - [<{instance_index, gtbs}>] - read_signal_strength :Read the bearer signal strength - [<{instance_index, gtbs}>] - read_signal_interval :Read the bearer signal strength reporting - interval [<{instance_index, gtbs}>] - read_current_calls :Read the current calls [<{instance_index, - gtbs}>] - read_ccid :Read the CCID [<{instance_index, gtbs}>] - read_status_flags :Read the in feature and status value - [<{instance_index, gtbs}>] - read_uri :Read the incoming call target URI - [<{instance_index, gtbs}>] - read_call_state :Read the call state [<{instance_index, gtbs}>] - read_remote_uri :Read the incoming remote URI - [<{instance_index, gtbs}>] - read_friendly_name :Read the friendly name of an incoming call - [<{instance_index, gtbs}>] - read_optional_opcodes :Read the optional opcodes [<{instance_index, - gtbs}>] - - -In the following examples, notifications from GTBS is ignored, unless otherwise -specified. - -Example usage -============= - -Setup ------ - -.. code-block:: console - - uart:~$ bt init - uart:~$ bt advertise on - Advertising started - -When connected --------------- - -Placing a call: - -.. code-block:: console - - uart:~$ tbs_client discover - bt_tbs_client.primary_discover_func: Discover complete, found 1 instances (GTBS found) - bt_tbs_client.discover_func: Setup complete for 1 / 1 TBS - bt_tbs_client.discover_func: Setup complete GTBS - uart:~$ tbs_client originate 0 tel:123 - bt_tbs_client.notify_handler: Index 0 - bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the dialing state with URI tel:123 - bt_tbs_client.call_cp_notify_handler: Status: success for the originate opcode for call 0x00 - bt_tbs_client.notify_handler: Index 0 - bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the alerting state with URI tel:123 - - bt_tbs_client.notify_handler: Index 0 - bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the active state with URI tel:123 - -Placing a call on GTBS: - -.. code-block:: console - - uart:~$ tbs_client originate 0 tel:123 - bt_tbs_client.notify_handler: Index 0 - bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the dialing state with URI tel:123 - bt_tbs_client.call_cp_notify_handler: Status: success for the originate opcode for call 0x00 - bt_tbs_client.notify_handler: Index 0 - bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the alerting state with URI tel:123 - - bt_tbs_client.notify_handler: Index 0 - bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the active state with URI tel:123 - -It is necessary to set an outgoing caller ID before placing a call. - -Accepting incoming call from peer device: - -.. code-block:: console - - bt_tbs_client.incoming_uri_notify_handler: tel:123 - bt_tbs_client.in_call_notify_handler: tel:456 - bt_tbs_client.friendly_name_notify_handler: Peter - bt_tbs_client.current_calls_notify_handler: Call 0x05 is in the incoming state with URI tel:456 - uart:~$ tbs_client accept 0 5 - bt_tbs_client.call_cp_callback_handler: Status: success for the accept opcode for call 0x05 - bt_tbs_client.current_calls_notify_handler: Call 0x05 is in the active state with URI tel - - -Terminate call: +Using the Call Control Server +============================= +The Server can be controlled locally, or by a remote device (when in a call). For +example a remote device may initiate a call to the server, +or the Server may initiate a call to remote device, without a client. .. code-block:: console - uart:~$ tbs_client terminate 0 5 - bt_tbs_client.termination_reason_notify_handler: ID 0x05, reason 0x06 - bt_tbs_client.call_cp_notify_handler: Status: success for the terminate opcode for call 0x05 - bt_tbs_client.current_calls_notify_handler: - -Telephone Bearer Service (TBS) -****************************** -The telephone bearer service is a service that typically resides on devices that -can make calls, including calls from apps such as Skype, e.g. (smart)phones and -PCs. - -It is necessary to have :kconfig:option:`CONFIG_BT_TBS_LOG_LEVEL_DBG` enabled -for using the TBS server interactively. - -Using the telephone bearer service -================================== -TBS can be controlled locally, or by a remote device (when in a call). For -example a remote device may initiate a call to the device with the TBS server, -or the TBS server may initiate a call to remote device, without a TBS_CLIENT client. -The TBS implementation is capable of fully controlling any call. -Omitting an index for commands where a :code:`` can be supplied, defaults to the -GTBS bearer. - -.. code-block:: console - - tbs --help - tbs - Bluetooth TBS shell commands + ccp_call_control_server --help + ccp_call_control_server - Bluetooth CCP Call Control Server shell commands Subcommands: - init :Initialize TBS - authorize :Authorize the current connection - accept :Accept call - terminate :Terminate call - hold :Hold call - retrieve :Retrieve call - originate :Originate call [] - join :Join calls [ [ [...]]] - incoming :Simulate incoming remote call [<{instance_index, - gtbs}>] - - remote_answer :Simulate remote answer outgoing call - remote_retrieve :Simulate remote retrieve - remote_terminate :Simulate remote terminate - remote_hold :Simulate remote hold - set_bearer_provider_name :Set the bearer provider name [<{instance_index, - gtbs}>] - set_bearer_technology :Set the bearer technology [<{instance_index, - gtbs}>] - set_bearer_signal_strength :Set the bearer signal strength [<{instance_index, - gtbs}>] - set_status_flags :Set the bearer feature and status value - [<{instance_index, gtbs}>] - set_uri_scheme :Set the URI prefix list - print_calls :Output all calls in the debug log + init : Initialize CCP Call Control Server Example Usage ============= @@ -213,26 +29,32 @@ Setup .. code-block:: console uart:~$ bt init + uart:~$ ccp_call_control_server init + Registered GTBS bearer + Registered bearer[1] uart:~$ bt connect xx:xx:xx:xx:xx:xx public -When connected --------------- +Call Control Client +******************* +The Call Control Client is a role that typically resides on resource constrained devices such as +earbuds or headsets. -Answering a call for a peer device originated by a client: +Using the Call Control Client +============================= +The Client can control a remote CCP server device. +For example a remote device may have an incoming call that can be accepted by the Client. .. code-block:: console - bt_tbs.write_call_cp: Index 0: Processing the originate opcode - bt_tbs.originate_call: New call with call index 1 - bt_tbs.write_call_cp: Index 0: Processed the originate opcode with status success for call index 1 - uart:~$ tbs remote_answer 1 - TBS succeeded for call_id: 1 + uart:~$ ccp_call_control_client --help + ccp_call_control_client - Bluetooth CCP Call Control Client shell commands + Subcommands: + discover : Discover GTBS and TBS on remote device -Incoming call from a peer device, accepted by client: +Example Usage when connected +============================ .. code-block:: console - uart:~$ tbs incoming 0 tel:123 tel:456 Peter - TBS succeeded for call_id: 4 - bt_tbs.bt_tbs_remote_incoming: New call with call index 4 - bt_tbs.write_call_cp: Index 0: Processed the accept opcode with status success for call index 4 + uart:~$ ccp_call_control_client discover + Discovery completed with GTBS and 1 TBS bearers diff --git a/doc/connectivity/bluetooth/shell/audio/tbs.rst b/doc/connectivity/bluetooth/shell/audio/tbs.rst new file mode 100644 index 0000000000000..e4eb3efebf346 --- /dev/null +++ b/doc/connectivity/bluetooth/shell/audio/tbs.rst @@ -0,0 +1,237 @@ +Bluetooth: Telephone Bearer Service Shell +######################################### + +This document describes how to run the call control functionality, both as +a client and as a (telephone bearer service (TBS)) server. Note that in the +examples below, some lines of debug have been removed to make this shorter +and provide a better overview. + +Telephone Bearer Service Client +******************************* + +The telephone bearer service client will typically exist on a resource +restricted device, such as headphones, but may also exist on e.g. phones or +laptops. The call control client will also thus typically be the advertiser. +The client can control the states of calls on a server using the call control +point. + +It is necessary to have :kconfig:option:`CONFIG_BT_TBS_CLIENT_LOG_LEVEL_DBG` +enabled for using the client interactively. + +Using the telephone bearer service client +========================================= + +When the Bluetooth stack has been initialized (:code:`bt init`), +and a device has been connected, the telephone bearer service client can +discover TBS on the connected device calling :code:`tbs_client discover`, which +will start a discovery for the TBS UUIDs and store the handles, and optionally +subscribe to all notifications (default is to subscribe to all). + +Since a server may have multiple TBS instances, most of the tbs_client commands +will take an index (starting from 0) as input. Joining calls require at least 2 +call IDs, and all call indexes shall be on the same TBS instance. + +A server will also have a GTBS instance, which is an abstraction layer for all +the telephone bearers on the server. If the server has both GTBS and TBS, +the client may subscribe and use either when sending requests if +:code:`BT_TBS_CLIENT_GTBS` is enabled. + +.. code-block:: console + + tbs_client --help + tbs_client - Bluetooth TBS_CLIENT shell commands + Subcommands: + discover :Discover TBS [subscribe] + set_signal_reporting_interval :Set the signal reporting interval + [<{instance_index, gtbs}>] + originate :Originate a call [<{instance_index, gtbs}>] + + terminate :terminate a call [<{instance_index, gtbs}>] + + accept :Accept a call [<{instance_index, gtbs}>] + hold :Place a call on hold [<{instance_index, + gtbs}>] + retrieve :Retrieve a held call [<{instance_index, + gtbs}>] + read_provider_name :Read the bearer name [<{instance_index, + gtbs}>] + read_bearer_uci :Read the bearer UCI [<{instance_index, gtbs}>] + read_technology :Read the bearer technology [<{instance_index, + gtbs}>] + read_uri_list :Read the bearer's supported URI list + [<{instance_index, gtbs}>] + read_signal_strength :Read the bearer signal strength + [<{instance_index, gtbs}>] + read_signal_interval :Read the bearer signal strength reporting + interval [<{instance_index, gtbs}>] + read_current_calls :Read the current calls [<{instance_index, + gtbs}>] + read_ccid :Read the CCID [<{instance_index, gtbs}>] + read_status_flags :Read the in feature and status value + [<{instance_index, gtbs}>] + read_uri :Read the incoming call target URI + [<{instance_index, gtbs}>] + read_call_state :Read the call state [<{instance_index, gtbs}>] + read_remote_uri :Read the incoming remote URI + [<{instance_index, gtbs}>] + read_friendly_name :Read the friendly name of an incoming call + [<{instance_index, gtbs}>] + read_optional_opcodes :Read the optional opcodes [<{instance_index, + gtbs}>] + + +In the following examples, notifications from GTBS are ignored, unless otherwise specified. + +Example usage +============= + +Setup +----- + +.. code-block:: console + + uart:~$ bt init + uart:~$ bt advertise on + Advertising started + +When connected +-------------- + +Placing a call: + +.. code-block:: console + + uart:~$ tbs_client discover + bt_tbs_client.primary_discover_func: Discover complete, found 1 instances (GTBS found) + bt_tbs_client.discover_func: Setup complete for 1 / 1 TBS + bt_tbs_client.discover_func: Setup complete GTBS + uart:~$ tbs_client originate 0 tel:123 + bt_tbs_client.notify_handler: Index 0 + bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the dialing state with URI tel:123 + bt_tbs_client.call_cp_notify_handler: Status: success for the originate opcode for call 0x00 + bt_tbs_client.notify_handler: Index 0 + bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the alerting state with URI tel:123 + + bt_tbs_client.notify_handler: Index 0 + bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the active state with URI tel:123 + +Placing a call on GTBS: + +.. code-block:: console + + uart:~$ tbs_client originate 0 tel:123 + bt_tbs_client.notify_handler: Index 0 + bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the dialing state with URI tel:123 + bt_tbs_client.call_cp_notify_handler: Status: success for the originate opcode for call 0x00 + bt_tbs_client.notify_handler: Index 0 + bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the alerting state with URI tel:123 + + bt_tbs_client.notify_handler: Index 0 + bt_tbs_client.current_calls_notify_handler: Call 0x01 is in the active state with URI tel:123 + +It is necessary to set an outgoing caller ID before placing a call. + +Accepting incoming call from peer device: + +.. code-block:: console + + bt_tbs_client.incoming_uri_notify_handler: tel:123 + bt_tbs_client.in_call_notify_handler: tel:456 + bt_tbs_client.friendly_name_notify_handler: Peter + bt_tbs_client.current_calls_notify_handler: Call 0x05 is in the incoming state with URI tel:456 + uart:~$ tbs_client accept 0 5 + bt_tbs_client.call_cp_callback_handler: Status: success for the accept opcode for call 0x05 + bt_tbs_client.current_calls_notify_handler: Call 0x05 is in the active state with URI tel + + +Terminate call: + +.. code-block:: console + + uart:~$ tbs_client terminate 0 5 + bt_tbs_client.termination_reason_notify_handler: ID 0x05, reason 0x06 + bt_tbs_client.call_cp_notify_handler: Status: success for the terminate opcode for call 0x05 + bt_tbs_client.current_calls_notify_handler: + +Telephone Bearer Service (TBS) +****************************** +The telephone bearer service is a service that typically resides on devices that +can make calls, including calls from apps such as Skype, e.g. (smart)phones and +PCs. + +It is necessary to have :kconfig:option:`CONFIG_BT_TBS_LOG_LEVEL_DBG` enabled +for using the TBS server interactively. + +Using the telephone bearer service +================================== +TBS can be controlled locally, or by a remote device (when in a call). For +example a remote device may initiate a call to the device with the TBS server, +or the TBS server may initiate a call to remote device, without a TBS_CLIENT client. +The TBS implementation is capable of fully controlling any call. +Omitting an index for commands where a :code:`` can be supplied, defaults to the +GTBS bearer. + +.. code-block:: console + + tbs --help + tbs - Bluetooth TBS shell commands + Subcommands: + init :Initialize TBS + authorize :Authorize the current connection + accept :Accept call + terminate :Terminate call + hold :Hold call + retrieve :Retrieve call + originate :Originate call [] + join :Join calls [ [ [...]]] + incoming :Simulate incoming remote call [<{instance_index, + gtbs}>] + + remote_answer :Simulate remote answer outgoing call + remote_retrieve :Simulate remote retrieve + remote_terminate :Simulate remote terminate + remote_hold :Simulate remote hold + set_bearer_provider_name :Set the bearer provider name [<{instance_index, + gtbs}>] + set_bearer_technology :Set the bearer technology [<{instance_index, + gtbs}>] + set_bearer_signal_strength :Set the bearer signal strength [<{instance_index, + gtbs}>] + set_status_flags :Set the bearer feature and status value + [<{instance_index, gtbs}>] + set_uri_scheme :Set the URI prefix list + print_calls :Output all calls in the debug log + +Example Usage +============= + +Setup +----- + +.. code-block:: console + + uart:~$ bt init + uart:~$ bt connect xx:xx:xx:xx:xx:xx public + +When connected +-------------- + +Answering a call for a peer device originated by a client: + +.. code-block:: console + + bt_tbs.write_call_cp: Index 0: Processing the originate opcode + bt_tbs.originate_call: New call with call index 1 + bt_tbs.write_call_cp: Index 0: Processed the originate opcode with status success for call index 1 + uart:~$ tbs remote_answer 1 + TBS succeeded for call_id: 1 + +Incoming call from a peer device, accepted by client: + +.. code-block:: console + + uart:~$ tbs incoming 0 tel:123 tel:456 Peter + TBS succeeded for call_id: 4 + bt_tbs.bt_tbs_remote_incoming: New call with call index 4 + bt_tbs.write_call_cp: Index 0: Processed the accept opcode with status success for call index 4 diff --git a/doc/connectivity/bluetooth/shell/classic/a2dp.rst b/doc/connectivity/bluetooth/shell/classic/a2dp.rst index 2895b41b23349..503214445ce75 100644 --- a/doc/connectivity/bluetooth/shell/classic/a2dp.rst +++ b/doc/connectivity/bluetooth/shell/classic/a2dp.rst @@ -14,6 +14,8 @@ Here is a example connecting two devices: * Source or Sink establish the stream. using :code:`a2dp establish`. * Source or Sink start the media. using :code:`a2dp start`. * Source test the media sending. using :code:`a2dp send_media` to send one test packet data. + * Source or Sink suspend the media. using :code:`a2dp suspend`. + * Source or Sink release the media. using :code:`a2dp release`. .. tabs:: @@ -58,6 +60,12 @@ Here is a example connecting two devices: uart:~$ a2dp send_media frames num: 1, data length: 160 data: 1, 2, 3, 4, 5, 6 ...... + uart:~$ a2dp suspend + success to suspend + stream suspended + uart:~$ a2dp release + success to release + stream released .. group-tab:: Device B (Audio Sink Side) @@ -74,7 +82,6 @@ Here is a example connecting two devices: a2dp connected receive requesting config and accept - SBC configure success sample rate 44100Hz stream configured @@ -86,4 +93,10 @@ Here is a example connecting two devices: received, num of frames: 1, data length: 160 data: 1, 2, 3, 4, 5, 6 ...... + + receive requesting suspend and accept + stream suspended + + receive requesting release and accept + stream released ... diff --git a/doc/connectivity/networking/api/coap_server.rst b/doc/connectivity/networking/api/coap_server.rst index 04498098818f9..9fb29a7ffda44 100644 --- a/doc/connectivity/networking/api/coap_server.rst +++ b/doc/connectivity/networking/api/coap_server.rst @@ -173,7 +173,7 @@ of CoAP services. An example using a temperature sensor can look like: coap_append_option_int(&response, COAP_OPTION_CONTENT_FORMAT, COAP_CONTENT_FORMAT_TEXT_PLAIN); - /* Get the sensor date */ + /* Get the sensor data */ sensor_sample_fetch_chan(dev, SENSOR_CHAN_AMBIENT_TEMP); sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &value); temp = sensor_value_to_double(&value); diff --git a/doc/connectivity/networking/api/http_server.rst b/doc/connectivity/networking/api/http_server.rst index 9514e5ab8f712..2a357a35a0790 100644 --- a/doc/connectivity/networking/api/http_server.rst +++ b/doc/connectivity/networking/api/http_server.rst @@ -29,6 +29,12 @@ Currently, the following resource types are supported: * Static resources - content defined compile-time, cannot be modified at runtime (:c:enumerator:`HTTP_RESOURCE_TYPE_STATIC`). +* Static file system resources - the path at which the filesystem is mounted, + and the URL at which the filesystem is made available are fixed at build time, + but the content within the filesystem can be changed dynamically. This means that + the files can be created, modified or deleted by some other code outside the HTTP + server (:c:enumerator:`HTTP_RESOURCE_TYPE_STATIC_FS`). + * Dynamic resources - content provided at runtime by respective application callback (:c:enumerator:`HTTP_RESOURCE_TYPE_DYNAMIC`). @@ -101,7 +107,7 @@ macro: static uint16_t http_service_port = 80; - HTTP_SERVICE_DEFINE(my_service, "0.0.0.0", &http_service_port, 1, 10, NULL); + HTTP_SERVICE_DEFINE(my_service, "0.0.0.0", &http_service_port, 1, 10, NULL, NULL); Alternatively, an HTTPS service can be defined with :c:macro:`HTTPS_SERVICE_DEFINE`: @@ -119,7 +125,43 @@ Alternatively, an HTTPS service can be defined with }; HTTPS_SERVICE_DEFINE(my_service, "0.0.0.0", &https_service_port, 1, 10, - NULL, sec_tag_list, sizeof(sec_tag_list)); + NULL, NULL, sec_tag_list, sizeof(sec_tag_list)); + +The ``_res_fallback`` parameter can be used when defining an HTTP/HTTPS service to +specify a fallback resource which will be used if no other resource matches the +URL. This can be used for example to serve an index page for all unknown paths +(useful for a single-page app which handles routing in the frontend), or for a +customised 404 response. + +.. code-block:: c + + static int default_handler(struct http_client_ctx *client, enum http_data_status status, + const struct http_request_ctx *request_ctx, + struct http_response_ctx *response_ctx, void *user_data) + { + static const char response_404[] = "Oops, page not found!"; + + if (status == HTTP_SERVER_DATA_FINAL) { + response_ctx->status = 404; + response_ctx->body = response_404; + response_ctx->body_len = sizeof(response_404) - 1; + response_ctx->final_chunk = true; + } + + return 0; + } + + static struct http_resource_detail_dynamic default_detail = { + .common = { + .type = HTTP_RESOURCE_TYPE_DYNAMIC, + .bitmask_of_supported_http_methods = BIT(HTTP_GET), + }, + .cb = default_handler, + .user_data = NULL, + }; + + /* Register a fallback resource to handle any unknown path */ + HTTP_SERVICE_DEFINE(my_service, "0.0.0.0", &http_service_port, 1, 10, NULL, &default_detail); .. note:: @@ -190,7 +232,8 @@ where ``src/index.html`` is the location of the webpage to be compressed. Static filesystem resources =========================== -Static filesystem resource content is defined build-time and is immutable. The following +Static filesystem resource content is defined build-time and is immutable. Note that only +``GET`` operation is supported, user is not able to upload files to the filesystem. The following example shows how the path can be defined as a static resource in the application: .. code-block:: c @@ -342,7 +385,7 @@ release it when done. static int ws_socket; static uint8_t ws_recv_buffer[1024]; - int ws_setup(int sock, void *user_data) + int ws_setup(int sock, struct http_request_ctx *request_ctx, void *user_data) { ws_socket = sock; return 0; diff --git a/doc/connectivity/networking/api/thread.rst b/doc/connectivity/networking/api/thread.rst index 155b794d7c1fd..35b5aa07d04a5 100644 --- a/doc/connectivity/networking/api/thread.rst +++ b/doc/connectivity/networking/api/thread.rst @@ -41,6 +41,9 @@ support in these samples, build them with ``overlay-ot.conf`` overlay config fil See :zephyr:code-sample:`sockets-echo-server` and :zephyr:code-sample:`sockets-echo-client` samples for details. +Zephyr also provides an :zephyr:code-sample:`openthread-shell`, which is useful for +testing and debugging Thread and its underlying IEEE 802.15.4 drivers. + Thread related APIs ******************* diff --git a/doc/connectivity/networking/api/wifi.rst b/doc/connectivity/networking/api/wifi.rst index 45c7b88592c9c..7f322bf248674 100644 --- a/doc/connectivity/networking/api/wifi.rst +++ b/doc/connectivity/networking/api/wifi.rst @@ -25,6 +25,11 @@ Currently, two types of Wi-Fi drivers are supported: * Networking or socket offloaded drivers * Native L2 Ethernet drivers +Wi-Fi PSA crypto supported build +******************************** + +To enable PSA crypto API supported Wi-Fi build, the :kconfig:option:`CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT` and the :kconfig:option:`CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA` need to be set. + Wi-Fi Enterprise test: X.509 Certificate header generation ********************************************************** diff --git a/doc/connectivity/usb/device/usb_device.rst b/doc/connectivity/usb/device/usb_device.rst index f1230e073d42b..1e4111f0eee51 100644 --- a/doc/connectivity/usb/device/usb_device.rst +++ b/doc/connectivity/usb/device/usb_device.rst @@ -27,9 +27,9 @@ over time. It provides the following functionalities: .. note:: It is planned to deprecate all APIs listed in :ref:`usb_api` and the - functions that depend on them between Zephyr v4.0.0 and v4.1.0, and remove - them in v4.3.0. The new USB device support, represented by the APIs in - :ref:`usb_device_next_api`, will become the default in Zephyr v4.1.0. + functions that depend on them between Zephyr v4.1.0 and v4.2.0, and remove + them in v4.4.0. The new USB device support, represented by the APIs in + :ref:`usb_device_next_api`, will become the default in Zephyr v4.2.0. Supported USB classes ********************* @@ -170,7 +170,7 @@ CDC ACM UART as backend for a subsystem or application: * ``zephyr,bt-c2h-uart`` used in Bluetooth, for example see :zephyr:code-sample:`bluetooth_hci_uart` * ``zephyr,ot-uart`` used in OpenThread, - for example see :zephyr:code-sample:`coprocessor` + for example see :zephyr:code-sample:`openthread-coprocessor` * ``zephyr,shell-uart`` used by shell for serial backend, for example see :zephyr_file:`samples/subsys/shell/shell_module` * ``zephyr,uart-mcumgr`` used by :zephyr:code-sample:`smp-svr` sample @@ -510,7 +510,7 @@ prevent you from implementing a hardware-clone firmware. Instead, if possible, the host driver implementation should be fixed to use values from the interface and endpoint descriptor. -Testing over USPIP in native_sim +Testing over USBIP in native_sim ******************************** A virtual USB controller implemented through USBIP might be used to test the USB @@ -596,7 +596,7 @@ The following Product IDs are currently used: +----------------------------------------------------+--------+ | :zephyr:code-sample:`bluetooth_hci_usb` | 0x000B | +----------------------------------------------------+--------+ -| :zephyr:code-sample:`bluetooth_hci_usb_h4` | 0x000C | +| Reserved (previously: bluetooth_hci_usb_h4) | 0x000C | +----------------------------------------------------+--------+ | Reserved (previously: wpan-usb) | 0x000D | +----------------------------------------------------+--------+ diff --git a/doc/connectivity/usb/device_next/api/index.rst b/doc/connectivity/usb/device_next/api/index.rst index 2606582066404..8b5c3d730e4a5 100644 --- a/doc/connectivity/usb/device_next/api/index.rst +++ b/doc/connectivity/usb/device_next/api/index.rst @@ -11,3 +11,5 @@ New USB device support APIs usbd_hid_device.rst uac2_device.rst usbd_msc_device.rst + usbd_midi2.rst + usbd_dfu.rst diff --git a/doc/connectivity/usb/device_next/api/usbd_dfu.rst b/doc/connectivity/usb/device_next/api/usbd_dfu.rst new file mode 100644 index 0000000000000..4059fca099f1a --- /dev/null +++ b/doc/connectivity/usb/device_next/api/usbd_dfu.rst @@ -0,0 +1,11 @@ +.. _usbd_dfu: + +USB DFU device API +################## + +USB DFU device specific API defined in :zephyr_file:`include/zephyr/usb/class/usbd_dfu.h`. + +API Reference +************* + +.. doxygengroup:: usbd_dfu diff --git a/doc/connectivity/usb/device_next/api/usbd_midi2.rst b/doc/connectivity/usb/device_next/api/usbd_midi2.rst new file mode 100644 index 0000000000000..d774f538961c1 --- /dev/null +++ b/doc/connectivity/usb/device_next/api/usbd_midi2.rst @@ -0,0 +1,12 @@ +.. _usbd_midi2: + +MIDI 2.0 Class device API +######################### + +USB MIDI 2.0 device specific API defined in :zephyr_file:`include/zephyr/usb/class/usbd_midi2.h`. + +API Reference +************* + +.. doxygengroup:: usbd_midi2 +.. doxygengroup:: midi_ump diff --git a/doc/connectivity/usb/host/usbip.rst b/doc/connectivity/usb/host/usbip.rst new file mode 100644 index 0000000000000..5c6495406ccc1 --- /dev/null +++ b/doc/connectivity/usb/host/usbip.rst @@ -0,0 +1,79 @@ +.. _usbip: + +USB/IP protocol support +####################### + +Overview +******** + +New USB support includes initial support for the USB/IP protocol. It is still +under development and is currently limited to supporting only one device +connected to the host controller being exported. + +USB/IP uses TCP/IP. Both of the underlying connectivity stacks, USB and +networking, require significant memory resources, which must be considered when +choosing a platform. + +In the USB/IP protocol, a server exports the USB devices and a client imports +them. USB/IP support in the Zephyr RTOS implements server functionality and +exports a device connected to a host controller on a device running the Zephyr +RTOS. A client, typically running the Linux kernel, imports this device. The +USB/IP protocol is described in `USB/IP protocol documentation`_. + +To use USB/IP support, make sure the required modules are loaded on the client side. + +.. code-block:: console + + modprobe vhci_hcd + modprobe usbip-core + modprobe usbip-host + +On the client side, you will also need the **usbip** user tool. It can be installed +using your Linux distribution's package management system or built from Linux +kernel sources. + +There are a few basic commands for everyday use. To list exported USB devices, +run the following command: + +.. code-block:: console + + $ usbip list -r 192.0.2.1 + Exportable USB devices + ====================== + - 192.0.2.1 + 1-1: NordicSemiconductor : unknown product (2fe3:0001) + : /sys/bus/usb/devices/usb1/1-1 + : Miscellaneous Device / ? / Interface Association (ef/02/01) + : 0 - Communications / Abstract (modem) / None (02/02/00) + : 1 - CDC Data / Unused / unknown protocol (0a/00/00) + +To attach an exported device with busid 1-1: + +.. code-block:: console + + $ sudo usbip attach -r 192.0.2.1 -b 1-1 + +To detach an exported device on port 0: + +.. code-block:: console + + $ sudo usbip detach -p 0 + +USB/IP with native_sim +********************** + +The preferred method to develop with USB/IP support enabled is to use +:ref:`native_sim `. Use on real hardware is not really tested yet. +USB/IP requires a network connection, see :ref:`networking_with_native_sim` +for how to set up the interface on the client side. + +Building and running a sample with USB/IP requires extensive configuration, +you can use usbip-native-sim snippet to configure host and USB/IP support. + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/usb/cdc_acm + :board: native_sim/native/64 + :gen-args: -DSNIPPET=usbip-native-sim -DEXTRA_DTC_OVERLAY_FILE=app.overlay + :goals: build + +.. _USB/IP protocol documentation: https://www.kernel.org/doc/html/latest/usb/usbip_protocol.html diff --git a/doc/connectivity/usb/index.rst b/doc/connectivity/usb/index.rst index b24bcb9954b43..74d880ed83907 100644 --- a/doc/connectivity/usb/index.rst +++ b/doc/connectivity/usb/index.rst @@ -19,6 +19,7 @@ USB device_next/usb_device.rst device_next/api/index.rst host/api/index.rst + host/usbip.rst **USB Power Delivery support** diff --git a/doc/contribute/coding_guidelines/index.rst b/doc/contribute/coding_guidelines/index.rst index 3c74ee2a3244e..131a7f31b1c16 100644 --- a/doc/contribute/coding_guidelines/index.rst +++ b/doc/contribute/coding_guidelines/index.rst @@ -3,42 +3,6 @@ Coding Guidelines ################# -The project TSC and the Safety Committee of the project agreed to implement -a staged and incremental approach for complying with a set of coding rules (AKA -Coding Guidelines) to improve quality and consistency of the code base. Below -are the agreed upon stages: - -Stage I (COMPLETED) - Coding guideline rules are available to be followed and referenced, - but not enforced. Rules are not yet enforced in CI and pull-requests cannot be - blocked by reviewers/approvers due to violations. - -Stage II - Begin enforcement on a limited scope of the code base. Initially, this would be - the safety certification scope. For rules easily applied across codebase, we - should not limit compliance to initial scope. This step requires tooling, - CI setup and an enforcement strategy. - -Stage III - Revisit the coding guideline rules and based on experience from previous - stages, refine/iterate on selected rules. - -Stage IV - Expand enforcement to the wider codebase. Exceptions may be granted on some - areas of the codebase with a proper justification. Exception would require - TSC approval. - -.. note:: - - Coding guideline rules may be removed/changed at any time by filing a - GH issue/RFC. - -.. important:: - - **Current stage:** - The prerequisites for entering **Stage II** are currently being looked at: - The tooling is in evaluation, CI setup and `enforcement strategy - `__ is being worked on. Main rules ********** @@ -1111,385 +1075,344 @@ Additional rules Rule A.1: Conditional Compilation ================================= - Severity --------- - -Required + Required Description ------------ - -Do not conditionally compile function declarations in header files. Do not -conditionally compile structure declarations in header files. You may -conditionally exclude fields within structure definitions to avoid wasting -memory when the feature they support is not enabled. + Do not conditionally compile function declarations in header files. Do not + conditionally compile structure declarations in header files. You may + conditionally exclude fields within structure definitions to avoid wasting + memory when the feature they support is not enabled. Rationale ---------- - -Excluding declarations from the header based on compile-time options may prevent -their documentation from being generated. Their absence also prevents use of -``if (IS_ENABLED(CONFIG_FOO)) {}`` as an alternative to preprocessor -conditionals when the code path should change based on the selected options. + Excluding declarations from the header based on compile-time options may prevent + their documentation from being generated. Their absence also prevents use of + ``if (IS_ENABLED(CONFIG_FOO)) {}`` as an alternative to preprocessor + conditionals when the code path should change based on the selected options. .. _coding_guideline_inclusive_language: Rule A.2: Inclusive Language ============================ - Severity --------- - -Required + Required Description ------------ + Do not introduce new usage of offensive terms listed below. This rule applies + but is not limited to source code, comments, documentation, and branch names. + Replacement terms may vary by area or subsystem, but should aim to follow + updated industry standards when possible. -Do not introduce new usage of offensive terms listed below. This rule applies -but is not limited to source code, comments, documentation, and branch names. -Replacement terms may vary by area or subsystem, but should aim to follow -updated industry standards when possible. + Exceptions are allowed for maintaining existing implementations or adding new + implementations of industry standard specifications governed externally to the + Zephyr Project. -Exceptions are allowed for maintaining existing implementations or adding new -implementations of industry standard specifications governed externally to the -Zephyr Project. + Existing usage is recommended to change as soon as updated industry standard + specifications become available or new terms are publicly announced by the + governing body, or immediately if no specifications apply. -Existing usage is recommended to change as soon as updated industry standard -specifications become available or new terms are publicly announced by the -governing body, or immediately if no specifications apply. + .. list-table:: + :header-rows: 1 -.. list-table:: - :header-rows: 1 + * - Offensive Terms + - Recommended Replacements - * - Offensive Terms - - Recommended Replacements + * - ``{master,leader} / slave`` + - - ``{primary,main} / {secondary,replica}`` + - ``{initiator,requester} / {target,responder}`` + - ``{controller,host} / {device,worker,proxy,target}`` + - ``director / performer`` + - ``central / peripheral`` - * - ``{master,leader} / slave`` - - - ``{primary,main} / {secondary,replica}`` - - ``{initiator,requester} / {target,responder}`` - - ``{controller,host} / {device,worker,proxy,target}`` - - ``director / performer`` - - ``central / peripheral`` + * - ``blacklist / whitelist`` + - * ``denylist / allowlist`` + * ``blocklist / allowlist`` + * ``rejectlist / acceptlist`` - * - ``blacklist / whitelist`` - - * ``denylist / allowlist`` - * ``blocklist / allowlist`` - * ``rejectlist / acceptlist`` - - * - ``grandfather policy`` - - * ``legacy`` - - * - ``sanity`` - - * ``coherence`` - * ``confidence`` + * - ``grandfather policy`` + - * ``legacy`` + * - ``sanity`` + - * ``coherence`` + * ``confidence`` Rationale ---------- - -Offensive terms do not create an inclusive community environment and therefore -violate the Zephyr Project `Code of Conduct`_. This coding rule was inspired by -a similar rule in `Linux`_. + Offensive terms do not create an inclusive community environment and therefore + violate the Zephyr Project `Code of Conduct`_. This coding rule was inspired by + a similar rule in `Linux`_. -.. _Code of Conduct: https://github.com/zephyrproject-rtos/zephyr/blob/main/CODE_OF_CONDUCT.md -.. _Linux: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=49decddd39e5f6132ccd7d9fdc3d7c470b0061bb + .. _Code of Conduct: https://github.com/zephyrproject-rtos/zephyr/blob/main/CODE_OF_CONDUCT.md + .. _Linux: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=49decddd39e5f6132ccd7d9fdc3d7c470b0061bb Status ------- - -Related GitHub Issues and Pull Requests are tagged with the `Inclusive Language Label`_. - -.. list-table:: - :header-rows: 1 - - * - Area - - Selected Replacements - - Status - - * - :ref:`Bluetooth ` - - See `Bluetooth Appropriate Language Mapping Tables`_ - - - - * - CAN - - This `CAN in Automation Inclusive Language news post`_ has a list of general - recommendations. See `CAN in Automation Inclusive Language`_ for terms to - be used in specification document updates. - - - - * - eSPI - - * ``master / slave`` => ``controller / target`` - - Refer to `eSPI Specification`_ for new terminology - - * - gPTP - - * ``master / slave`` => TBD - - + Related GitHub Issues and Pull Requests are tagged with the `Inclusive Language Label`_. + + .. list-table:: + :header-rows: 1 + + * - Area + - Selected Replacements + - Status + + * - :ref:`Bluetooth ` + - See `Bluetooth Appropriate Language Mapping Tables`_ + - + + * - CAN + - This `CAN in Automation Inclusive Language news post`_ has a list of general + recommendations. See `CAN in Automation Inclusive Language`_ for terms to + be used in specification document updates. + - + + * - eSPI + - * ``master / slave`` => ``controller / target`` + - Refer to `eSPI Specification`_ for new terminology + + * - gPTP + - * ``master / slave`` => TBD + - + + * - :ref:`i2c_api` + - * ``master / slave`` => TBD + - NXP publishes the `I2C Specification`_ and has selected ``controller / + target`` as replacement terms, but the timing to publish an announcement + or new specification is TBD. Zephyr will update I2C when replacement + terminology is confirmed by a public announcement or updated + specification. + + See :github:`Zephyr issue 27033 <27033>`. + + * - :ref:`i2s_api` + - * ``master / slave`` => TBD + - + + * - SMP/AMP + - * ``master / slave`` => TBD + - + + * - :ref:`spi_api` + - * ``master / slave`` => ``controller / peripheral`` + * ``MOSI / MISO / SS`` => ``SDO / SDI / CS`` + - The Open Source Hardware Association has selected these replacement + terms. See `OSHWA Resolution to Redefine SPI Signal Names`_ + + * - :ref:`twister_script` + - * ``platform_whitelist`` => ``platform_allow`` + * ``sanitycheck`` => ``twister`` + - + + .. _Inclusive Language Label: https://github.com/zephyrproject-rtos/zephyr/issues?q=label%3A%22Inclusive+Language%22 + .. _I2C Specification: https://www.nxp.com/docs/en/user-guide/UM10204.pdf + .. _Bluetooth Appropriate Language Mapping Tables: https://specificationrefs.bluetooth.com/language-mapping/Appropriate_Language_Mapping_Table.pdf + .. _OSHWA Resolution to Redefine SPI Signal Names: https://www.oshwa.org/a-resolution-to-redefine-spi-signal-names/ + .. _CAN in Automation Inclusive Language news post: https://www.can-cia.org/news/archive/view/?tx_news_pi1%5Bnews%5D=699&tx_news_pi1%5Bday%5D=6&tx_news_pi1%5Bmonth%5D=12&tx_news_pi1%5Byear%5D=2020&cHash=784e79eb438141179386cf7c29ed9438 + .. _CAN in Automation Inclusive Language: https://can-newsletter.org/canopen/categories/ + .. _eSPI Specification: https://downloadmirror.intel.com/27055/327432%20espi_base_specification%20R1-5.pdf - * - :ref:`i2c_api` - - * ``master / slave`` => TBD - - NXP publishes the `I2C Specification`_ and has selected ``controller / - target`` as replacement terms, but the timing to publish an announcement - or new specification is TBD. Zephyr will update I2C when replacement - terminology is confirmed by a public announcement or updated - specification. - - See :github:`Zephyr issue 27033 <27033>`. - - * - :ref:`i2s_api` - - * ``master / slave`` => TBD - - - - * - SMP/AMP - - * ``master / slave`` => TBD - - - - * - :ref:`spi_api` - - * ``master / slave`` => ``controller / peripheral`` - * ``MOSI / MISO / SS`` => ``SDO / SDI / CS`` - - The Open Source Hardware Association has selected these replacement - terms. See `OSHWA Resolution to Redefine SPI Signal Names`_ - - * - :ref:`twister_script` - - * ``platform_whitelist`` => ``platform_allow`` - * ``sanitycheck`` => ``twister`` - - - -.. _Inclusive Language Label: https://github.com/zephyrproject-rtos/zephyr/issues?q=label%3A%22Inclusive+Language%22 -.. _I2C Specification: https://www.nxp.com/docs/en/user-guide/UM10204.pdf -.. _Bluetooth Appropriate Language Mapping Tables: https://specificationrefs.bluetooth.com/language-mapping/Appropriate_Language_Mapping_Table.pdf -.. _OSHWA Resolution to Redefine SPI Signal Names: https://www.oshwa.org/a-resolution-to-redefine-spi-signal-names/ -.. _CAN in Automation Inclusive Language news post: https://www.can-cia.org/news/archive/view/?tx_news_pi1%5Bnews%5D=699&tx_news_pi1%5Bday%5D=6&tx_news_pi1%5Bmonth%5D=12&tx_news_pi1%5Byear%5D=2020&cHash=784e79eb438141179386cf7c29ed9438 -.. _CAN in Automation Inclusive Language: https://can-newsletter.org/canopen/categories/ -.. _eSPI Specification: https://downloadmirror.intel.com/27055/327432%20espi_base_specification%20R1-5.pdf +.. _coding_guideline_libc_usage_restrictions_in_zephyr_kernel: Rule A.3: Macro name collisions =============================== - Severity --------- - -Required + Required Description ------------ - -Macros with commonly used names such as ``MIN``, ``MAX``, ``ARRAY_SIZE``, must -not be modified or protected to avoid name collisions with other -implementations. In particular, they must not be prefixed to place them in a -Zephyr-specific namespace, re-defined using ``#undef``, or conditionally -excluded from compilation using ``#ifndef``. Instead, if a conflict arises with -an existing definition originating from a :ref:`module `, the module's -code itself needs to be modified (ideally upstream, alternatively via a change -in Zephyr's own fork). -This rule applies to Zephyr as a project in general, regardless of the time of -introduction of the macro or its current name in the tree. If a macro name is -commonly used in several other well-known open source projects then the -implementation in Zephyr should use that name. While there is a subjective and -non-measurable component to what "commonly used" means, the ultimate goal is -to offer users familiar macros. -Finally, this rule applies to inter-module name collisions as well: in that case -both modules, prior to their inclusion, should be modified to use -module-specific versions of the macro name that collides. + Macros with commonly used names such as ``MIN``, ``MAX``, ``ARRAY_SIZE``, must not be modified or + protected to avoid name collisions with other implementations. In particular, they must not be + prefixed to place them in a Zephyr-specific namespace, re-defined using ``#undef``, or + conditionally excluded from compilation using ``#ifndef``. Instead, if a conflict arises with an + existing definition originating from a :ref:`module `, the module's code itself needs to + be modified (ideally upstream, alternatively via a change in Zephyr's own fork). + + This rule applies to Zephyr as a project in general, regardless of the time of introduction of the + macro or its current name in the tree. If a macro name is commonly used in several other well-known + open source projects then the implementation in Zephyr should use that name. While there is a + subjective and non-measurable component to what "commonly used" means, the ultimate goal is to offer + users familiar macros. + + Finally, this rule applies to inter-module name collisions as well: in that case both modules, prior + to their inclusion, should be modified to use module-specific versions of the macro name that + collides. Rationale ---------- - -Zephyr is an RTOS that comes with additional functionality and dependencies in -the form of modules. Those modules are typically independent projects that may -use macro names that can conflict with other modules or with Zephyr itself. -Since, in the context of this documentation, Zephyr is considered the central or -main project, it should implement the non-namespaced versions of the -macros. Given that Zephyr uses a fork of the corresponding upstream for each -module, it is always possible to patch the macro implementation in each module -to avoid collisions. - -.. _coding_guideline_libc_usage_restrictions_in_zephyr_kernel: + Zephyr is an RTOS that comes with additional functionality and dependencies in the form of modules. + Those modules are typically independent projects that may use macro names that can conflict with + other modules or with Zephyr itself. Since, in the context of this documentation, Zephyr is + considered the central or main project, it should implement the non-namespaced versions of the + macros. Given that Zephyr uses a fork of the corresponding upstream for each module, it is always + possible to patch the macro implementation in each module to avoid collisions. Rule A.4: C Standard Library Usage Restrictions in Zephyr Kernel ================================================================ - Severity --------- - -Required + Required Description ------------ - -The use of the C standard library functions and macros in the Zephyr kernel -shall be limited to the following functions and macros from the ISO/IEC -9899:2011 standard, also known as C11, and their extensions: - -.. csv-table:: List of allowed libc functions and macros in the Zephyr kernel - :header: Function,Source - :widths: auto - - abort(),ISO/IEC 9899:2011 - abs(),ISO/IEC 9899:2011 - aligned_alloc(),ISO/IEC 9899:2011 - assert(),ISO/IEC 9899:2011 - atoi(),ISO/IEC 9899:2011 - bsearch(),ISO/IEC 9899:2011 - calloc(),ISO/IEC 9899:2011 - exit(),ISO/IEC 9899:2011 - fprintf(),ISO/IEC 9899:2011 - fputc(),ISO/IEC 9899:2011 - fputs(),ISO/IEC 9899:2011 - free(),ISO/IEC 9899:2011 - fwrite(),ISO/IEC 9899:2011 - gmtime(),ISO/IEC 9899:2011 - isalnum(),ISO/IEC 9899:2011 - isalpha(),ISO/IEC 9899:2011 - iscntrl(),ISO/IEC 9899:2011 - isdigit(),ISO/IEC 9899:2011 - isgraph(),ISO/IEC 9899:2011 - isprint(),ISO/IEC 9899:2011 - isspace(),ISO/IEC 9899:2011 - isupper(),ISO/IEC 9899:2011 - isxdigit(),ISO/IEC 9899:2011 - labs(),ISO/IEC 9899:2011 - llabs(),ISO/IEC 9899:2011 - malloc(),ISO/IEC 9899:2011 - memchr(),ISO/IEC 9899:2011 - memcmp(),ISO/IEC 9899:2011 - memcpy(),ISO/IEC 9899:2011 - memmove(),ISO/IEC 9899:2011 - memset(),ISO/IEC 9899:2011 - perror(),ISO/IEC 9899:2011 - printf(),ISO/IEC 9899:2011 - putc(),ISO/IEC 9899:2011 - putchar(),ISO/IEC 9899:2011 - puts(),ISO/IEC 9899:2011 - qsort(),ISO/IEC 9899:2011 - rand(),ISO/IEC 9899:2011 - realloc(),ISO/IEC 9899:2011 - snprintf(),ISO/IEC 9899:2011 - sprintf(),ISO/IEC 9899:2011 - sqrt(),ISO/IEC 9899:2011 - sqrtf(),ISO/IEC 9899:2011 - srand(),ISO/IEC 9899:2011 - strcat(),ISO/IEC 9899:2011 - strchr(),ISO/IEC 9899:2011 - strcmp(),ISO/IEC 9899:2011 - strcpy(),ISO/IEC 9899:2011 - strcspn(),ISO/IEC 9899:2011 - strerror(),ISO/IEC 9899:2011 - strlen(),ISO/IEC 9899:2011 - strncat(),ISO/IEC 9899:2011 - strncmp(),ISO/IEC 9899:2011 - strncpy(),ISO/IEC 9899:2011 - `strnlen()`_,POSIX.1-2008 - strrchr(),ISO/IEC 9899:2011 - strspn(),ISO/IEC 9899:2011 - strstr(),ISO/IEC 9899:2011 - strtol(),ISO/IEC 9899:2011 - strtoll(),ISO/IEC 9899:2011 - strtoul(),ISO/IEC 9899:2011 - strtoull(),ISO/IEC 9899:2011 - time(),ISO/IEC 9899:2011 - tolower(),ISO/IEC 9899:2011 - toupper(),ISO/IEC 9899:2011 - vfprintf(),ISO/IEC 9899:2011 - vprintf(),ISO/IEC 9899:2011 - vsnprintf(),ISO/IEC 9899:2011 - vsprintf(),ISO/IEC 9899:2011 - -All of the functions listed above must be implemented by the -:ref:`minimal libc ` to ensure that the Zephyr kernel can -build with the minimal libc. - -In addition, any functions from the above list that are not part of the -ISO/IEC 9899:2011 standard must be implemented by the -:ref:`common libc ` to ensure their availability across -multiple C standard libraries. - -Introducing new C standard library functions to the Zephyr kernel is allowed -with justification given that the above requirements are satisfied. - -Note that the use of the functions listed above are subject to secure and safe -coding practices and it should not be assumed that their use in the Zephyr -kernel is unconditionally permitted by being listed in this rule. - -The "Zephyr kernel" in this context consists of the following components: - -* Kernel (:file:`kernel`) -* OS Library (:file:`lib/os`) -* Architecture Port (:file:`arch`) -* Logging Subsystem (:file:`subsys/logging`) + The use of the C standard library functions and macros in the Zephyr kernel + shall be limited to the following functions and macros from the ISO/IEC + 9899:2011 standard, also known as C11, and their extensions: + + .. csv-table:: List of allowed libc functions and macros in the Zephyr kernel + :header: Function,Source + :widths: auto + + abort(),ISO/IEC 9899:2011 + abs(),ISO/IEC 9899:2011 + aligned_alloc(),ISO/IEC 9899:2011 + assert(),ISO/IEC 9899:2011 + atoi(),ISO/IEC 9899:2011 + bsearch(),ISO/IEC 9899:2011 + calloc(),ISO/IEC 9899:2011 + exit(),ISO/IEC 9899:2011 + fprintf(),ISO/IEC 9899:2011 + fputc(),ISO/IEC 9899:2011 + fputs(),ISO/IEC 9899:2011 + free(),ISO/IEC 9899:2011 + fwrite(),ISO/IEC 9899:2011 + gmtime(),ISO/IEC 9899:2011 + isalnum(),ISO/IEC 9899:2011 + isalpha(),ISO/IEC 9899:2011 + iscntrl(),ISO/IEC 9899:2011 + isdigit(),ISO/IEC 9899:2011 + isgraph(),ISO/IEC 9899:2011 + isprint(),ISO/IEC 9899:2011 + isspace(),ISO/IEC 9899:2011 + isupper(),ISO/IEC 9899:2011 + isxdigit(),ISO/IEC 9899:2011 + labs(),ISO/IEC 9899:2011 + llabs(),ISO/IEC 9899:2011 + malloc(),ISO/IEC 9899:2011 + memchr(),ISO/IEC 9899:2011 + memcmp(),ISO/IEC 9899:2011 + memcpy(),ISO/IEC 9899:2011 + memmove(),ISO/IEC 9899:2011 + memset(),ISO/IEC 9899:2011 + perror(),ISO/IEC 9899:2011 + printf(),ISO/IEC 9899:2011 + putc(),ISO/IEC 9899:2011 + putchar(),ISO/IEC 9899:2011 + puts(),ISO/IEC 9899:2011 + qsort(),ISO/IEC 9899:2011 + rand(),ISO/IEC 9899:2011 + realloc(),ISO/IEC 9899:2011 + snprintf(),ISO/IEC 9899:2011 + sprintf(),ISO/IEC 9899:2011 + sqrt(),ISO/IEC 9899:2011 + sqrtf(),ISO/IEC 9899:2011 + srand(),ISO/IEC 9899:2011 + strcat(),ISO/IEC 9899:2011 + strchr(),ISO/IEC 9899:2011 + strcmp(),ISO/IEC 9899:2011 + strcpy(),ISO/IEC 9899:2011 + strcspn(),ISO/IEC 9899:2011 + strerror(),ISO/IEC 9899:2011 + strlen(),ISO/IEC 9899:2011 + strncat(),ISO/IEC 9899:2011 + strncmp(),ISO/IEC 9899:2011 + strncpy(),ISO/IEC 9899:2011 + `strnlen()`_,POSIX.1-2008 + strrchr(),ISO/IEC 9899:2011 + strspn(),ISO/IEC 9899:2011 + strstr(),ISO/IEC 9899:2011 + strtol(),ISO/IEC 9899:2011 + strtoll(),ISO/IEC 9899:2011 + strtoul(),ISO/IEC 9899:2011 + strtoull(),ISO/IEC 9899:2011 + time(),ISO/IEC 9899:2011 + tolower(),ISO/IEC 9899:2011 + toupper(),ISO/IEC 9899:2011 + vfprintf(),ISO/IEC 9899:2011 + vprintf(),ISO/IEC 9899:2011 + vsnprintf(),ISO/IEC 9899:2011 + vsprintf(),ISO/IEC 9899:2011 + + All of the functions listed above must be implemented by the + :ref:`minimal libc ` to ensure that the Zephyr kernel can + build with the minimal libc. + + In addition, any functions from the above list that are not part of the + ISO/IEC 9899:2011 standard must be implemented by the + :ref:`common libc ` to ensure their availability across + multiple C standard libraries. + + Introducing new C standard library functions to the Zephyr kernel is allowed + with justification given that the above requirements are satisfied. + + Note that the use of the functions listed above are subject to secure and safe + coding practices and it should not be assumed that their use in the Zephyr + kernel is unconditionally permitted by being listed in this rule. + + The "Zephyr kernel" in this context consists of the following components: + + * Kernel (:file:`kernel`) + * OS Library (:file:`lib/os`) + * Architecture Port (:file:`arch`) + * Logging Subsystem (:file:`subsys/logging`) Rationale ---------- - -Zephyr kernel must be able to build with the -:ref:`minimal libc `, a limited C standard library -implementation that is part of the Zephyr RTOS and maintained by the Zephyr -Project, to allow self-contained testing and verification of the kernel and -core OS services. + Zephyr kernel must be able to build with the + :ref:`minimal libc `, a limited C standard library + implementation that is part of the Zephyr RTOS and maintained by the Zephyr + Project, to allow self-contained testing and verification of the kernel and + core OS services. -In order to ensure that the Zephyr kernel can build with the minimal libc, it -is necessary to restrict the use of the C standard library functions and macros -in the Zephyr kernel to the functions and macros that are available as part of -the minimal libc. + In order to ensure that the Zephyr kernel can build with the minimal libc, it + is necessary to restrict the use of the C standard library functions and macros + in the Zephyr kernel to the functions and macros that are available as part of + the minimal libc. Rule A.5: C Standard Library Usage Restrictions in Zephyr Codebase ================================================================== - Severity --------- - -Required + Required Description ------------ - -The use of the C standard library functions and macros in the Zephyr codebase -shall be limited to the functions, excluding the Annex K "Bounds-checking -interfaces", from the ISO/IEC 9899:2011 standard, also known as C11, unless -exempted by this rule. - -The "Zephyr codebase" in this context refers to all embedded source code files committed -to the `main Zephyr repository`_, except the Zephyr kernel as defined by the -:ref:`coding_guideline_libc_usage_restrictions_in_zephyr_kernel`. -With embedded source code we refer to code which is meant to be executed in embedded -targets, and therefore excludes host tooling, and code specific for the -:ref:`native ` test targets. - -The following non-ISO 9899:2011, hereinafter referred to as non-standard, -functions and macros are exempt from this rule and allowed to be used in the -Zephyr codebase: - -.. csv-table:: List of allowed non-standard libc functions - :header: Function,Source - :widths: auto - - `gmtime_r()`_,POSIX.1-2001 - `strnlen()`_,POSIX.1-2008 - `strtok_r()`_,POSIX.1-2001 - -All non-standard functions and macros listed above must be implemented by the -:ref:`common libc ` in order to make sure that these -functions can be made available when using a C standard library that does not -implement these functions. - -Adding a new non-standard function from common C standard libraries to the -above list is allowed with justification, given that the above requirement is -satisfied. However, when there exists a standard function that is functionally -equivalent, the standard function shall be used. + The use of the C standard library functions and macros in the Zephyr codebase + shall be limited to the functions, excluding the Annex K "Bounds-checking + interfaces", from the ISO/IEC 9899:2011 standard, also known as C11, unless + exempted by this rule. + + The "Zephyr codebase" in this context refers to all embedded source code files committed + to the `main Zephyr repository`_, except the Zephyr kernel as defined by the + :ref:`coding_guideline_libc_usage_restrictions_in_zephyr_kernel`. + With embedded source code we refer to code which is meant to be executed in embedded + targets, and therefore excludes host tooling, and code specific for the + :ref:`native ` test targets. + + The following non-ISO 9899:2011, hereinafter referred to as non-standard, + functions and macros are exempt from this rule and allowed to be used in the + Zephyr codebase: + + .. csv-table:: List of allowed non-standard libc functions + :header: Function,Source + :widths: auto + + `gmtime_r()`_,POSIX.1-2001 + `strnlen()`_,POSIX.1-2008 + `strtok_r()`_,POSIX.1-2001 + + All non-standard functions and macros listed above must be implemented by the + :ref:`common libc ` in order to make sure that these + functions can be made available when using a C standard library that does not + implement these functions. + + Adding a new non-standard function from common C standard libraries to the + above list is allowed with justification, given that the above requirement is + satisfied. However, when there exists a standard function that is functionally + equivalent, the standard function shall be used. Rationale ---------- - -Some C standard libraries, such as Newlib and Picolibc, include additional -functions and macros that are defined by the standards and de-facto standards -that extend the ISO C standard (e.g. POSIX, Linux). - -The ISO/IEC 9899:2011 standard does not require C compiler toolchains to -include the support for these non-standard functions, and therefore using -these functions can lead to compatibility issues with the third-party -toolchains that come with their own C standard libraries. - -.. _main Zephyr repository: https://github.com/zephyrproject-rtos/zephyr -.. _gmtime_r(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/gmtime_r.html -.. _strnlen(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/strlen.html -.. _strtok_r(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html + Some C standard libraries, such as Newlib and Picolibc, include additional + functions and macros that are defined by the standards and de-facto standards + that extend the ISO C standard (e.g. POSIX, Linux). + + The ISO/IEC 9899:2011 standard does not require C compiler toolchains to + include the support for these non-standard functions, and therefore using + these functions can lead to compatibility issues with the third-party + toolchains that come with their own C standard libraries. + + .. _main Zephyr repository: https://github.com/zephyrproject-rtos/zephyr + .. _gmtime_r(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/gmtime_r.html + .. _strnlen(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/strlen.html + .. _strtok_r(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html diff --git a/doc/contribute/contributor_expectations.rst b/doc/contribute/contributor_expectations.rst index c6152914e5a1c..8c650a4726895 100644 --- a/doc/contribute/contributor_expectations.rst +++ b/doc/contribute/contributor_expectations.rst @@ -87,26 +87,78 @@ Changes which require an RFC proposal include: Maintainers have the discretion to request that contributors create an RFC for PRs that are too large or complicated. +.. _pr_requirements: + PR Requirements *************** - Each commit in the PR must provide a commit message following the :ref:`commit-guidelines`. +- No fixup or merge commits are allowed, see :ref:`Contribution workflow` for + more information. + - The PR description must include a summary of the changes and their rationales. - All files in the PR must comply with :ref:`Licensing Requirements`. -- Follow the Zephyr :ref:`coding_style` and :ref:`coding_guidelines`. +- The code must follow the Zephyr :ref:`coding_style` and :ref:`coding_guidelines`. -- PRs must pass all CI checks. This is a requirement to merge the PR. +- The PR must pass all CI checks, as described in :ref:`merge_criteria`. Contributors may mark a PR as draft and explicitly request reviewers to provide early feedback, even with failing CI checks. -- When breaking a PR into multiple commits, each commit must build cleanly. The - CI system does not enforce this policy, so it is the PR author's - responsibility to verify. +- Commits in a pull request should represent clear, logical units of change that are easy to review + and maintain bisectability. The following guidelines expand on this principle: + + 1. Distinct, Logical Units of Change + + Each commit should correspond to a self-contained, meaningful change. For example, adding a + feature, fixing a bug, or refactoring existing code should be separate commits. Avoid mixing + different types of changes (e.g., feature implementation and unrelated refactoring) in the same + commit. + + 2. Retain Bisectability + + Every commit in the pull request must build successfully and pass all relevant tests. This + ensures that git bisect can be used effectively to identify the specific commit that introduced + a bug or issue. + + 3. Squash Intermediary or Non-Final Development History + + During development, commits may include intermediary changes (e.g., partial implementations, + temporary files, or debugging code). These should be squashed or rewritten before submitting the + pull request. Remove non-final artifacts, such as: + + * Temporary renaming of files that are later renamed again. + * Code that was rewritten or significantly changed in later commits. + + 4. Ensure Clean History Before Submission + + Use interactive rebasing (git rebase -i) to clean up the commit history before submitting the + pull request. This helps in: + + * Squashing small, incomplete commits into a single cohesive commit. + * Ensuring that each commit remains bisectable. + * Maintaining proper attribution of authorship while improving clarity. + + 5. Renaming and Code Rewrites + + If files or code are renamed or rewritten in later commits during development, squash or rewrite + earlier commits to reflect the final structure. This ensures that: + + * The history remains clean and easy to follow. + * Bisectability is preserved by eliminating redundant renaming or partial rewrites. + + 6. Attribution of Authorship + + While cleaning up the commit history, ensure that authorship attribution remains accurate. + + 7. Readable and Reviewable History + + The final commit history should be easy to understand for future maintainers. Logical units of + change should be grouped into commits that tell a clear, coherent story of the work done. - When major new functionality is added, tests for the new functionality shall be added to the automated test suite. All API functions should have test cases @@ -133,6 +185,13 @@ PR Requirements - Changes to APIs must increment the API version number according to the API version rules. +- Documentation must be added and/or updated to reflect the changes in the code + introduced by the PR. The documentation changes must use the proper + terminology as present in the existing pages, and must be written in American + English. If you include images as part of the documentation, those must follow + the rules in :ref:`doc_images`. Please refer to :ref:`doc_guidelines` for + additional information. + - PRs must also satisfy all :ref:`merge_criteria` before a member of the release engineering team merges the PR into the zephyr tree. @@ -163,7 +222,7 @@ Workflow Suggestions That Help Reviewers .. |git range-diff| replace:: ``git range-diff`` .. _`git range-diff`: https://git-scm.com/docs/git-range-diff -PR Review Escalation +Getting PRs Reviewed ==================== The Zephyr community is a diverse group of individuals, with different levels of @@ -179,8 +238,8 @@ following this process: #. For PRs that have otherwise stalled, the Zephyr Dev Meeting pings the Assignee and any reviewers that have left comments on the PR. -Contributors may escalate PRs outside of the Zephyr Dev Meeting triage process -as follows: +Contributors may request PRs to be reviewed outside of the Zephyr Dev Meeting +triage process as follows: - After 1 week of inactivity, ping the Assignee or reviewers on the PR by adding a comment to the PR. @@ -195,7 +254,7 @@ as follows: help on Discord or send an email to the `Zephyr devel mailing list`_. Note that for new PRs, contributors should generally wait for at least one -Zephyr Dev Meeting before escalating the PR themselves. +Zephyr Dev Meeting before making a request themselves. .. _Zephyr devel mailing list: https://lists.zephyrproject.org/g/devel @@ -259,62 +318,3 @@ the steps below: .. _Architecture Project: https://github.com/zephyrproject-rtos/zephyr/projects/18 .. _Architecture Working Group: https://github.com/zephyrproject-rtos/zephyr/wiki/Architecture-Working-Group - - -.. _reviewer-expectations: - -Reviewer Expectations -********************* - -- Be respectful when commenting on PRs. Refer to the Zephyr `Code of Conduct`_ - for more details. - -- The Zephyr Project recognizes that reviewers and maintainers have limited - bandwidth. As a reviewer, prioritize review requests in the following order: - - #. PRs related to items in the `Zephyr Release Plan`_ or those targeting - the next release during the stabilization period (after RC1). - #. PRs where the reviewer has requested blocking changes. - #. PRs assigned to the reviewer as the area maintainer. - #. All other PRs. - -- Reviewers shall strive to advance the PR to a mergeable state with their - feedback and engagement with the PR author. - -- Try to provide feedback on the entire PR in one shot. This provides the - contributor an opportunity to address all comments in the next PR update. - -- Partial reviews are permitted, but the reviewer must add a comment indicating - what portion of the PR they reviewed. Examples of useful partial reviews - include: - - - Domain specific reviews (e.g. Devicetree). - - Code style changes that impact the readability of the PR. - - Reviewing commits separately when the requested changes cascade into the - later commits. - -- Avoid increasing scope of the PR by requesting new features, especially when - there is a corresponding :ref:`RFC ` associated with the PR. Instead, - reviewers should add suggestions as a comment to the :ref:`RFC `. This - also encourages more collaboration as it is easier for multiple contributors - to work on a feature once the minimum implementation has merged. - -- When using the "Request Changes" option, mark trivial, non-functional, - requests as "Non-blocking" in the comment. Reviewers should approve PRs once - only non-blocking changes remain. The PR author has discretion as to whether - they address all non-blocking comments. PR authors should acknowledge every - review comment in some way, even if it's just with an emoticon. - -- Reviewers shall be *clear* and *concise* what changes they are requesting when the - "Request Changes" option is used. Requested changes shall be in the scope of - the PR in question and following the contribution and style guidelines of the - project. - -- Reviewers shall not close a PR due to technical or structural disagreement. - If requested changes cannot be resolved within the review process, the - :ref:`pr_technical_escalation` path shall be used for any potential resolution - path, which may include closing the PR. - -.. _Code of Conduct: https://github.com/zephyrproject-rtos/zephyr/blob/main/CODE_OF_CONDUCT.md - -.. _Zephyr Release Plan: https://github.com/orgs/zephyrproject-rtos/projects/13 diff --git a/doc/contribute/documentation/generation.rst b/doc/contribute/documentation/generation.rst index 8c5675333231d..7c88ccd1beb29 100644 --- a/doc/contribute/documentation/generation.rst +++ b/doc/contribute/documentation/generation.rst @@ -188,9 +188,9 @@ folder, here are the commands to generate the html content locally: .. code-block:: console # On Linux/macOS - cd ~/zephyr/doc + cd ~/zephyrproject/zephyr/doc # On Windows - cd %userprofile%\zephyr\doc + cd %userprofile%\zephyrproject\zephyr\doc # Use cmake to configure a Ninja-based build system: cmake -GNinja -B_build . @@ -234,7 +234,7 @@ build the documentation directly from there: .. code-block:: console - cd ~/zephyr/doc + cd ~/zephyrproject/zephyr/doc # To generate HTML output make html @@ -255,7 +255,7 @@ To enable this mode, set the following option when invoking cmake:: or invoke make with the following target:: - cd ~/zephyr/doc + cd ~/zephyrproject/zephyr/doc # To generate HTML output without detailed Kconfig make html-fast diff --git a/doc/contribute/documentation/guidelines.rst b/doc/contribute/documentation/guidelines.rst index 468b8cecede58..8cba07080cc03 100644 --- a/doc/contribute/documentation/guidelines.rst +++ b/doc/contribute/documentation/guidelines.rst @@ -700,6 +700,8 @@ Cross-referencing C documentation Visual Elements *************** +.. _doc_images: + Images ====== @@ -928,15 +930,7 @@ Cross-referencing files in the Zephyr tree ========================================== Special roles are available to reference files in the Zephyr tree. For example, referencing this -very file can be done using the :rst:role:`zephyr_file` role, like this:: - - Check out :zephyr_file:`doc/contribute/documentation/guidelines.rst` for more information. - -This would render as: - - Check out :zephyr_file:`doc/contribute/documentation/guidelines.rst` for more information. - -You may use the :rst:role:`zephyr_raw` role instead if you want to reference the "raw" content. +very file can be done using the :rst:role:`zephyr_file` role. .. rst:role:: zephyr_file @@ -948,6 +942,8 @@ You may use the :rst:role:`zephyr_raw` role instead if you want to reference the Check out :zephyr_file:`doc/contribute/documentation/guidelines.rst` for more information. +You may use the :rst:role:`zephyr_raw` role instead if you want to reference the "raw" content. + .. rst:role:: zephyr_raw This role is used to reference the raw content of a file in the Zephyr tree. For example:: @@ -1006,6 +1002,15 @@ Doxygen API documentation .. doxygengroup:: can_interface + + .. rubric:: Options + + .. rst:directive:option:: project + :type: project name (optional) + + Associated Doxygen project. This can be useful when multiple Doxygen + projects are configured. + .. rst:role:: c:group This role is used to reference a Doxygen group in the Zephyr tree. In the HTML documentation, diff --git a/doc/contribute/guidelines.rst b/doc/contribute/guidelines.rst index 998681a2e8fc5..eac7185850592 100644 --- a/doc/contribute/guidelines.rst +++ b/doc/contribute/guidelines.rst @@ -12,6 +12,34 @@ This document explains how to participate in project conversations, log bugs and enhancement requests, and submit patches to the project so your patch will be accepted quickly in the codebase. + +Prerequisites +************* + +.. _Zephyr Project website: https://zephyrproject.org + +As a contributor, you'll want to be familiar with the Zephyr project, how to +configure, install, and use it as explained in the `Zephyr Project website`_ +and how to set up your development environment as introduced in the Zephyr +:ref:`getting_started`. + +You should be familiar with common developer tools such as Git and CMake, and +platforms such as GitHub. + +If you haven't already done so, you'll need to create a (free) GitHub account +on https://github.com and have Git tools available on your development system. + +.. note:: + The Zephyr development workflow supports all 3 major operating systems + (Linux, macOS, and Windows) but some of the tools used in the sections below + are only available on Linux and macOS. On Windows, instead of running these + tools yourself, you will need to rely on the Continuous Integration (CI) + service using Github Actions, which runs automatically on GitHub when you submit + your Pull Request (PR). You can see any failure results in the workflow + details link near the end of the PR conversation list. See + `Continuous Integration`_ for more information + + .. _licensing_requirements: Licensing @@ -156,54 +184,6 @@ Additional requirements: - If you are altering an existing commit created by someone else, you must add your Signed-off-by: line without removing the existing one. -- If you forget to add the Signed-off-by: line, you can add it to your previous - commit by running ``git commit --amend -s``. - -- If you've pushed your changes to GitHub already you'll need to force push - your branch after this with ``git push -f``. - -Notes -===== - -Any contributions made as part of submitted pull requests are considered free -for the Project to use. Developers are permitted to cherry-pick patches that -are included in pull requests submitted by other contributors. It is expected -that - -* the content of the patches will not be substantially modified, -* the cherry-picked commits or portions of a commit shall preserve the original - sign-off messages and the author identity. - -:ref:`modifying_contributions` describes additional recommended policies -around working with contributions submitted by other developers. - - -Prerequisites -************* - -.. _Zephyr Project website: https://zephyrproject.org - -As a contributor, you'll want to be familiar with the Zephyr project, how to -configure, install, and use it as explained in the `Zephyr Project website`_ -and how to set up your development environment as introduced in the Zephyr -:ref:`getting_started`. - -You should be familiar with common developer tools such as Git and CMake, and -platforms such as GitHub. - -If you haven't already done so, you'll need to create a (free) GitHub account -on https://github.com and have Git tools available on your development system. - -.. note:: - The Zephyr development workflow supports all 3 major operating systems - (Linux, macOS, and Windows) but some of the tools used in the sections below - are only available on Linux and macOS. On Windows, instead of running these - tools yourself, you will need to rely on the Continuous Integration (CI) - service using Github Actions, which runs automatically on GitHub when you submit - your Pull Request (PR). You can see any failure results in the workflow - details link near the end of the PR conversation list. See - `Continuous Integration`_ for more information - .. _source_tree_v2: Source Tree Structure @@ -390,11 +370,6 @@ this: You need to change text in square brackets (``[like this]``) above to fit your commit. -Examples and more details follow. - -Example -------- - Here is an example of a good commit message. .. code-block:: none @@ -531,99 +506,6 @@ reference manuals, etc. Link: https://github.com/zephyrproject-rtos/zephyr/issues/ -.. _coding_style: - -Coding Style -============ - -.. _Linux kernel coding style: - https://kernel.org/doc/html/latest/process/coding-style.html - -In general, follow the `Linux kernel coding style`_, with the following -exceptions: - -* The line length is 100 columns or fewer. In the documentation, longer lines - for URL references are an allowed exception. -* Add braces to every ``if``, ``else``, ``do``, ``while``, ``for`` and - ``switch`` body, even for single-line code blocks. Use the ``--ignore BRACES`` - flag to make *checkpatch* stop complaining. -* Use spaces instead of tabs to align comments after declarations, as needed. -* Use C89-style single line comments, ``/* */``. The C99-style single line - comment, ``//``, is not allowed. -* Use ``/** */`` for doxygen comments that need to appear in the documentation. -* Avoid using binary literals (constants starting with ``0b``). -* Avoid using non-ASCII symbols in code, unless it significantly improves - clarity, avoid emojis in any case. - -Use these coding guidelines to ensure that your development complies with the -project's style and naming conventions. - -The Linux kernel GPL-licensed tool ``checkpatch`` is used to check -coding style conformity. - -.. note:: - checkpatch does not currently run on Windows. - -Checkpatch is available in the scripts directory. To invoke it when committing -code, make the file *$ZEPHYR_BASE/.git/hooks/pre-commit* executable and edit -it to contain: - -.. code-block:: bash - - #!/bin/sh - set -e exec - exec git diff --cached | ${ZEPHYR_BASE}/scripts/checkpatch.pl - - -Instead of running checkpatch at each commit, you may prefer to run it only -before pushing on zephyr repo. To do this, make the file -*$ZEPHYR_BASE/.git/hooks/pre-push* executable and edit it to contain: - -.. code-block:: bash - - #!/bin/sh - remote="$1" - url="$2" - - z40=0000000000000000000000000000000000000000 - - echo "Run push hook" - - while read local_ref local_sha remote_ref remote_sha - do - args="$remote $url $local_ref $local_sha $remote_ref $remote_sha" - exec ${ZEPHYR_BASE}/scripts/series-push-hook.sh $args - done - - exit 0 - -If you want to override checkpatch verdict and push you branch despite reported -issues, you can add option --no-verify to the git push command. - -A more complete alternative to this is using :ref:`check_compliance_py` script. - -clang-format ------------- - -The `clang-format tool `_ can -be helpful to quickly reformat large amounts of new source code to our -`Coding Style`_ standards together with the ``.clang-format`` configuration file -provided in the repository. ``clang-format`` is well integrated into most -editors, but you can also run it manually like this: - -.. code-block:: bash - - clang-format -i my_source_file.c - -``clang-format`` is part of LLVM, which can be downloaded from the project -`releases page `_. Note that if -you are a Linux user, ``clang-format`` will likely be available as a package in -your distribution repositories. - -When there are differences between the `Coding Style`_ guidelines and the -formatting generated by code formatting tools, the `Coding Style`_ guidelines -take precedence. If there is ambiguity between formatting tools and the -guidelines, maintainers may decide which style should be adopted. - .. _Continuous Integration: Continuous Integration (CI) @@ -954,30 +836,6 @@ attention needed and it will be ready for merge sooner than later: sure you click the "Re-request review" button on the GitHub UI to notify those who asked for the changes - -Submitting Proposals -==================== - -You can request a new feature or submit a proposal by submitting an issue to -our GitHub Repository. -If you would like to implement a new feature, please submit an issue with a -proposal (RFC) for your work first, to be sure that we can use it. Please -consider what kind of change it is: - -* For a Major Feature, first open an issue and outline your proposal so that it - can be discussed. This will also allow us to better coordinate our efforts, - prevent duplication of work, and help you to craft the change so that it is - successfully accepted into the project. Providing the following information - will increase the chances of your issue being dealt with quickly: - - * Overview of the Proposal - * Motivation for or Use Case - * Design Details - * Alternatives - * Test Strategy - -* Small Features can be crafted and directly submitted as a Pull Request. - Identifying Contribution Origin =============================== diff --git a/doc/contribute/index.rst b/doc/contribute/index.rst index 19f872226a5ac..a6c2998a81855 100644 --- a/doc/contribute/index.rst +++ b/doc/contribute/index.rst @@ -15,9 +15,13 @@ General Guidelines :hidden: guidelines.rst + contributor_expectations.rst + reviewer_expectations.rst coding_guidelines/index.rst + style/index.rst proposals_and_rfcs.rst - contributor_expectations.rst + modifying_contributions.rst + :ref:`contribute_guidelines` Learn about the overall process and guidelines for contributing to the Zephyr project. @@ -30,17 +34,26 @@ General Guidelines This document is another mandatory read that describes the expected behavior of *all* contributors to the project. +:ref:`reviewer-expectations` + This document is another mandatory read that describes the expected behavior when revieweing + contributions to the project. + :ref:`coding_guidelines` Code contributions are expected to follow a set of coding guidelines to ensure consistency and readability across the code base. - This page describes these guidelines and introduces important considerations regarding the use of - :ref:`inclusive language `. +:ref:`coding_style` + Code contributions are expected to follow a set of style guidelines to ensure consistency and + readability across the code base. :ref:`rfcs` Learn when and how to submit RFCs (Request for Comments) for new features and changes to the project. +:ref:`modifying_contributions` + Guidelines for modifying contributions made by other developers and how to deal with stale pull + requests. + Documentation ============= @@ -88,16 +101,6 @@ Dealing with external components in binary form, this page describes the process and guidelines for :ref:`contributing binary blobs ` to the project. -Zephyr Contributor Badge -======================== - -When your first contribution to the Zephyr project gets merged, you'll become eligible to claim your -Zephyr Contributor Badge. This digital badge can be displayed on your website, blog, social media -profile, etc. It will allow you to showcase your involvement in the Zephyr project and help raise -its awareness. - -You may apply for your Contributor Badge by filling out the `Zephyr Contributor Badge form`_. - Need help along the way? ======================== @@ -107,4 +110,3 @@ You may join our Discord_ channel or use the `Developer Mailing List`_. .. _Discord: https://chat.zephyrproject.org .. _Developer Mailing List: https://lists.zephyrproject.org/g/devel -.. _Zephyr Contributor Badge form: https://forms.gle/oCw9iAPLhUsHTapc8 diff --git a/doc/project/modifying_contributions.rst b/doc/contribute/modifying_contributions.rst similarity index 100% rename from doc/project/modifying_contributions.rst rename to doc/contribute/modifying_contributions.rst diff --git a/doc/contribute/proposals_and_rfcs.rst b/doc/contribute/proposals_and_rfcs.rst index 8b76b44a09658..d87647e07448f 100644 --- a/doc/contribute/proposals_and_rfcs.rst +++ b/doc/contribute/proposals_and_rfcs.rst @@ -33,8 +33,22 @@ feature as it is being designed, and incorporate important constraints into the design while it's easier to change, before the design has been fully implemented. -Some changes do not require an RFC: +For a Major Feature, first open an issue and outline your proposal so that it +can be discussed. This will also allow us to better coordinate our efforts, +prevent duplication of work, and help you to craft the change so that it is +successfully accepted into the project. Providing the following information +will increase the chances of your issue being dealt with quickly: + * Overview of the Proposal + * Motivation for or Use Case + * Design Details + * Alternatives + * Test Strategy + +Some changes or contributions do not require an RFC, the rationale and details +of the changes should however be part of the pull-request: + +- Small enhancements and modifications to existing and established subsystems. - Rephrasing, reorganizing or refactoring - Addition or removal of warnings - Addition of new boards, SoCs or drivers to existing subsystems diff --git a/doc/contribute/reviewer_expectations.rst b/doc/contribute/reviewer_expectations.rst new file mode 100644 index 0000000000000..b22ea7b9ea72e --- /dev/null +++ b/doc/contribute/reviewer_expectations.rst @@ -0,0 +1,74 @@ +.. _reviewer-expectations: + +Reviewer Expectations +##################### + +- Be respectful when commenting on PRs. Refer to the Zephyr `Code of Conduct`_ + for more details. + +- The Zephyr Project recognizes that reviewers and maintainers have limited + bandwidth. As a reviewer, prioritize review requests in the following order: + + #. PRs related to items in the `Zephyr Release Plan`_ or those targeting + the next release during the stabilization period (after RC1). + #. PRs where the reviewer has requested blocking changes. + #. PRs assigned to the reviewer as the area maintainer. + #. All other PRs. + +- Reviewers shall strive to advance the PR to a mergeable state with their + feedback and engagement with the PR author. + +- Try to provide feedback on the entire PR in one shot. This provides the + contributor an opportunity to address all comments in the next PR update. + +- Partial reviews are permitted, but the reviewer must add a comment indicating + what portion of the PR they reviewed. Examples of useful partial reviews + include: + + - Domain specific reviews (e.g. Devicetree). + - Code style changes that impact the readability of the PR. + - Reviewing commits separately when the requested changes cascade into the + later commits. + +- Avoid increasing scope of the PR by requesting new features, especially when + there is a corresponding :ref:`RFC ` associated with the PR. Instead, + reviewers should add suggestions as a comment to the :ref:`RFC `. This + also encourages more collaboration as it is easier for multiple contributors + to work on a feature once the minimum implementation has merged. + +- When using the "Request Changes" option, mark trivial, non-functional, + requests as "Non-blocking" in the comment. Reviewers should approve PRs once + only non-blocking changes remain. The PR author has discretion as to whether + they address all non-blocking comments. PR authors should acknowledge every + review comment in some way, even if it's just with an emoticon. + +- Style changes that the reviewer disagrees with but that are not documented as + part of the project can be pointed out as non-blocking, but cannot constitute + a reason for a request for changes. The reviewer can optionally correct any + potential inconsistencies in the tree, document the new guidelines or rules, + and then enforce them as part of the review. + +- Whenever requesting style related changes, reviewers should be able to point + out the corresponding guideline, rule or rationale in the project's + documentation. This does not apply to certain types of requests for changes, + notably those specific to the changes being submitted (e.g. the use of a + particular data structure or the choice of locking primitives). + +- Reviewers shall be *clear* about what changes they are requesting when the + "Request Changes" option is used. Requested changes shall be in the scope of + the PR in question and following the contribution and style guidelines of the + project. Furthermore, reviewers must be able to point back to the exact issues + in the PR that triggered a request for changes. + +- Reviewers should not request changes for issues which are automatically + caught by CI, as this causes the pull request to remain blocked even after CI + failures have been addressed and may unnecessarily delay it from being merged. + +- Reviewers shall not close a PR due to technical or structural disagreement. + If requested changes cannot be resolved within the review process, the + :ref:`pr_technical_escalation` path shall be used for any potential resolution + path, which may include closing the PR. + +.. _Code of Conduct: https://github.com/zephyrproject-rtos/zephyr/blob/main/CODE_OF_CONDUCT.md + +.. _Zephyr Release Plan: https://github.com/orgs/zephyrproject-rtos/projects/13 diff --git a/doc/contribute/style/cmake.rst b/doc/contribute/style/cmake.rst new file mode 100644 index 0000000000000..0fff427341618 --- /dev/null +++ b/doc/contribute/style/cmake.rst @@ -0,0 +1,139 @@ +:orphan: + +.. _cmake-style: + +CMake Style Guidelines +###################### + +General Formatting +****************** + +- **Indentation**: Use **2 spaces** for indentation. Avoid tabs to ensure + consistency across different environments. +- **Line Length**: Limit line length to **100 characters** where possible. +- **Empty Lines**: Use empty lines to separate logically distinct sections + within a CMake file. +- **No Space Before Opening Brackets**: Do not add a space between a command + and the opening parenthesis. + Use ``if(...)`` instead of ``if (...)``. + + .. code-block:: cmake + + # Good: + if(ENABLE_TESTS) + add_subdirectory(tests) + endif() + + # Bad: + if (ENABLE_TESTS) + add_subdirectory(tests) + endif() + +Commands and Syntax +******************* + +- **Lowercase Commands**: Always use **lowercase** CMake commands (e.g., + ``add_executable``, ``find_package``). This improves readability and + consistency. + + .. code-block:: cmake + + # Good: + add_library(my_lib STATIC src/my_lib.cpp) + + # Bad: + ADD_LIBRARY(my_lib STATIC src/my_lib.cpp) + +- **One File Argument per Line**: Break the file arguments across multiple + lines to make it easier to scan and identify each source file or item. + + .. code-block:: cmake + + # Good: + target_sources(my_target PRIVATE + src/file1.cpp + src/file2.cpp + ) + + # Bad: + target_sources(my_target PRIVATE src/file1.cpp src/file2.cpp) + +Variable Naming +*************** + +- **Use Uppercase for Cache Variables or variables shared across CMake files**: + When defining cache variables using ``option`` or ``set(... CACHE ...)``, use + **UPPERCASE names**. + + .. code-block:: cmake + + option(ENABLE_TESTS "Enable test suite" ON) + set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard version") + +- **Use Lowercase for Local Variables**: For local variables within CMake + files, use **lowercase** or **snake_case**. + + .. code-block:: cmake + + set(output_dir "${CMAKE_BINARY_DIR}/output") + +- **Consistent Prefixing**: Use consistent prefixes for variables to avoid name + conflicts, especially in large projects. + + .. code-block:: cmake + + set(MYPROJECT_SRC_DIR "${CMAKE_SOURCE_DIR}/src") + +Quoting +******* + +- **Quote Strings and Variables**: Always quote string literals and variables + to prevent unintended behavior, especially when dealing with paths or + arguments that may contain spaces. + + .. code-block:: cmake + + # Good: + set(my_path "${CMAKE_SOURCE_DIR}/include") + + # Bad: + set(my_path ${CMAKE_SOURCE_DIR}/include) + +- **Do Not Quote Boolean Values**: For boolean values (``ON``, ``OFF``, + ``TRUE``, ``FALSE``), avoid quoting them. + + .. code-block:: cmake + + option(BUILD_SHARED_LIBS "Build shared libraries" OFF) + +Avoid Hardcoding Paths +********************** + +- Use CMake variables (``CMAKE_SOURCE_DIR``, ``CMAKE_BINARY_DIR``, + ``CMAKE_CURRENT_SOURCE_DIR``) instead of hardcoding paths. + + .. code-block:: cmake + + set(output_dir "${CMAKE_BINARY_DIR}/bin") + +Conditional Logic +***************** + +- Use ``if``, ``elseif``, and ``else`` with proper indentation, and close with + ``endif()``. + + .. code-block:: cmake + + if(ENABLE_TESTS) + add_subdirectory(tests) + endif() + +Documentation +************* + +- Use comments to document complex logic in the CMake files. + + .. code-block:: cmake + + # Find LlvmLld components required for building with llvm + find_package(LlvmLld 14.0.0 REQUIRED) diff --git a/doc/contribute/style/code.rst b/doc/contribute/style/code.rst new file mode 100644 index 0000000000000..59a363ee50949 --- /dev/null +++ b/doc/contribute/style/code.rst @@ -0,0 +1,38 @@ +.. _general_code_style: + +C Code and General Style Guidelines +################################### + +Coding style is enforced on any new or modified code, but contributors are +not expected to correct the style on existing code that they are not +modifying. + +For style aspects where the guidelines don't offer explicit guidance or +permit multiple valid ways to express something, contributors should follow +the style of existing code in the tree, with higher importance given to +"nearby" code (first look at the function, then the same file, then +subsystem, etc). + +In general, follow the `Linux kernel coding style`_, with the following +exceptions and clarifications: + +* Use `snake case`_ for code and variables. +* The line length is 100 columns or fewer. In the documentation, longer lines + for URL references are an allowed exception. +* Add braces to every ``if``, ``else``, ``do``, ``while``, ``for`` and + ``switch`` body, even for single-line code blocks. +* Use spaces instead of tabs to align comments after declarations, as needed. +* Use C89-style single line comments, ``/* */``. The C99-style single line + comment, ``//``, is not allowed. +* Use ``/** */`` for doxygen comments that need to appear in the documentation. +* Avoid using binary literals (constants starting with ``0b``). +* Avoid using non-ASCII symbols in code, unless it significantly improves + clarity, avoid emojis in any case. +* Use proper capitalization of nouns in code comments (e.g. ``UART`` and not + ``uart``, ``CMake`` and not ``cmake``). + +.. _Linux kernel coding style: + https://kernel.org/doc/html/latest/process/coding-style.html + +.. _snake case: + https://en.wikipedia.org/wiki/Snake_case diff --git a/doc/contribute/style/devicetree.rst b/doc/contribute/style/devicetree.rst new file mode 100644 index 0000000000000..36746770754fa --- /dev/null +++ b/doc/contribute/style/devicetree.rst @@ -0,0 +1,13 @@ +.. _devicetree_style: + +Devicetree Style Guidelines +########################### + + * Indent with tabs. + * Follow the Devicetree specification conventions and rules. + * Use dashes (``-``) as word separators for node and property names. + * Use underscores (``_``) as word separators in node labels. + * Leave a single space on each side of the equal sign (``=``) in property + definitions. + * Don't insert empty lines before a dedenting ``};``. + * Insert a single empty line to separate nodes at the same hierarchy level. diff --git a/doc/contribute/style/index.rst b/doc/contribute/style/index.rst new file mode 100644 index 0000000000000..d0ff1814d4cb0 --- /dev/null +++ b/doc/contribute/style/index.rst @@ -0,0 +1,87 @@ +.. _coding_style: + + +Coding Style Guidelines +####################### + +.. toctree:: + :maxdepth: 1 + + code.rst + cmake.rst + devicetree.rst + kconfig.rst + + +Style Tools +*********** + +Checkpatch +========== + +The Linux kernel GPL-licensed tool ``checkpatch`` is used to check +coding style conformity. + +.. note:: + checkpatch does not currently run on Windows. + +Checkpatch is available in the scripts directory. To invoke it when committing +code, make the file *$ZEPHYR_BASE/.git/hooks/pre-commit* executable and edit +it to contain: + +.. code-block:: bash + + #!/bin/sh + set -e exec + exec git diff --cached | ${ZEPHYR_BASE}/scripts/checkpatch.pl - + +Instead of running checkpatch at each commit, you may prefer to run it only +before pushing on zephyr repo. To do this, make the file +*$ZEPHYR_BASE/.git/hooks/pre-push* executable and edit it to contain: + +.. code-block:: bash + + #!/bin/sh + remote="$1" + url="$2" + + z40=0000000000000000000000000000000000000000 + + echo "Run push hook" + + while read local_ref local_sha remote_ref remote_sha + do + args="$remote $url $local_ref $local_sha $remote_ref $remote_sha" + exec ${ZEPHYR_BASE}/scripts/series-push-hook.sh $args + done + + exit 0 + +If you want to override checkpatch verdict and push you branch despite reported +issues, you can add option --no-verify to the git push command. + +A different way for running ``checkpatch`` is by using :ref:`check_compliance_py` +script, which does additional style and compliance related checks. + +clang-format +============ + +The `clang-format tool `_ can +be helpful to quickly reformat large amounts of new source code to our +`Coding Style Guidelines`_ standards together with the ``.clang-format`` configuration file +provided in the repository. ``clang-format`` is well integrated into most +editors, but you can also run it manually like this: + +.. code-block:: bash + + clang-format -i my_source_file.c + +``clang-format`` is part of LLVM, which can be downloaded from the project +`releases page `_. Note that if +you are a Linux user, ``clang-format`` will likely be available as a package in +your distribution repositories. + +When there are differences between the `Coding Style Guidelines`_ guidelines and the +formatting generated by code formatting tools, the `Coding Style Guidelines`_ guidelines +take precedence. If there is ambiguity between formatting tools and the +guidelines, maintainers may decide which style should be adopted. diff --git a/doc/contribute/style/kconfig.rst b/doc/contribute/style/kconfig.rst new file mode 100644 index 0000000000000..f73165e28d4e5 --- /dev/null +++ b/doc/contribute/style/kconfig.rst @@ -0,0 +1,14 @@ +.. _kconfig_style: + +Kconfig Style Guidelines +######################## + + * Line length of 100 columns or fewer. + * Indent with tabs, except for ``help`` entry text which should be placed at + one tab plus two extra spaces. + * Leave a single empty line between option declarations. + * Use Statements like ``select`` carefully, see + :ref:`kconfig_tips_and_tricks` for more information. + * Format comments as ``# Comment`` rather than ``#Comment`` + * Insert an empty line before/after each top-level ``if`` and ``endif`` + statement. diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index fa787d5640ebc..f89d45b11b214 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -722,12 +722,6 @@ Given the following example project layout: * If this is build with ``FILE_SUFFIX`` set to ``mouse`` for ``qemu_cortex_m3`` then ``prj_mouse.conf`` will be used and ``boards/qemu_cortex_m3_mouse.overlay`` will be used. -.. note:: - - When ``CONF_FILE`` is set in the form of ``prj_X.conf`` then the ``X`` will be used as the - build type. If this is combined with ``FILE_SUFFIX`` then the file suffix option will take - priority over the build type. - Application-Specific Code ************************* diff --git a/doc/develop/beyond-GSG.rst b/doc/develop/beyond-GSG.rst index ab0a1aba84fef..fe7e646e9e858 100644 --- a/doc/develop/beyond-GSG.rst +++ b/doc/develop/beyond-GSG.rst @@ -136,6 +136,8 @@ Keeping Zephyr updated To update the Zephyr project source code, you need to get the latest changes via ``git``. Afterwards, run ``west update`` as mentioned in the previous paragraph. +Additionally, in the case of updated or added Python dependencies, running +``west packages pip --install`` will make sure these are up-to-date. .. code-block:: console @@ -143,6 +145,7 @@ the previous paragraph. cd zephyrproject/zephyr git pull west update + west packages pip --install Export Zephyr CMake package *************************** diff --git a/doc/develop/flash_debug/host-tools.rst b/doc/develop/flash_debug/host-tools.rst index 85cf6a826dc03..e0788734091ff 100644 --- a/doc/develop/flash_debug/host-tools.rst +++ b/doc/develop/flash_debug/host-tools.rst @@ -28,7 +28,14 @@ The typical command to flash the board is: .. code-block:: console - west flash [ -r bossac ] [ -p /dev/ttyX ] + west flash [ -r bossac ] [ -p /dev/ttyX ] [ --erase ] + +.. note:: + + By default, flashing with bossac will only erase the flash pages containing + the flashed application, leaving other pages untouched. Should you wish to + erase the entire flash of the target when flashing, pass the ``--erase`` + parameter when flashing. Flash configuration for devices: diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index a79b3489acc6c..f2bee3943cd93 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -95,6 +95,11 @@ The current minimum required version for the main dependencies are: python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \ make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 + .. note:: + + Due to the unavailability of ``gcc-multilib`` and ``g++-multilib`` on AArch64 + (ARM64) systems, you may need to remove them from the list of packages to install. + #. Verify the versions of the main dependencies installed on your system by entering: .. code-block:: bash @@ -207,8 +212,10 @@ Get Zephyr and install Python dependencies ****************************************** Next, clone Zephyr and its :ref:`modules ` into a new :ref:`west -` workspace named :file:`zephyrproject`. You'll also install Zephyr's -additional Python dependencies in a `Python virtual environment`_. +` workspace. In the following instructions the name :file:`zephyrproject` +is used for the workspace, however in practice its name and location can be freely +chosen. You'll also install Zephyr's additional Python dependencies in a +`Python virtual environment`_. .. _Python virtual environment: https://docs.python.org/3/library/venv.html diff --git a/doc/develop/modules.rst b/doc/develop/modules.rst index ff8f3781d45fb..352edfb963fd5 100644 --- a/doc/develop/modules.rst +++ b/doc/develop/modules.rst @@ -1050,6 +1050,25 @@ requirement files in the ``scripts`` directory of the module. - scripts/requirements-build.txt - scripts/requirements-doc.txt + +.. _modules-runners: + +External Runners +================ + +If a module has out of tree boards that require custom :ref:`runners `, +then it can add a list to its ``zephyr/module.yml`` file, for example: + + +.. code-block:: yaml + + runners: + - file: scripts/my-runner.py + + +Each file entry is imported when executing ``west flash`` or ``west debug`` and +subclasses of the ``ZephyrBinaryRunner`` are registered for use. + Module Inclusion ================ diff --git a/doc/develop/sca/index.rst b/doc/develop/sca/index.rst index 37c30827d27c0..8269b0be4835c 100644 --- a/doc/develop/sca/index.rst +++ b/doc/develop/sca/index.rst @@ -66,3 +66,4 @@ The following is a list of SCA tools natively supported by Zephyr build system. gcc cpptest eclair + polyspace diff --git a/doc/develop/sca/polyspace.rst b/doc/develop/sca/polyspace.rst new file mode 100644 index 0000000000000..438472027fc1f --- /dev/null +++ b/doc/develop/sca/polyspace.rst @@ -0,0 +1,93 @@ +.. _polyspace: + +Polyspace support +################# + +`Polyspace® `__ is +a commercial static code analysis tool from MathWorks, which is certified +for use in highest safety contexts. It can check compliance to coding +guidelines like MISRA C and CERT C, find CWEs, detect bugs and calculate +code complexity metrics. Optionally, it can run a formal proof to verify +the absence of run-time errors like array out of bounds access, overflows, +race conditions and more, and thus help achieving memory safety. + +Installing +********** + +The Polyspace tools must be installed and made available in the +operating system's or container's PATH variable. Specifically, the path +``/polyspace/bin`` must be on the list. + +For installation instructions, see +`here `__. +To use formal verification (proving the *absence* of defects), you +additionally need to install +`this `__. + +A license file must be available +in the installation folder. To request a trial license, visit `this +page `__. + +Running +******* + +The code analysis can be triggered through the ``west`` command by +appending the option ``-DZEPHYR_SCA_VARIANT=polyspace`` to the build, +for example: + +.. code-block:: shell + + west build -b qemu_x86 samples/hello_world -- -DZEPHYR_SCA_VARIANT=polyspace + +Reviewing results +***************** + +The identified issues are summarized at the end of the build and printed +in the console window, along with the path of the folder containing +detailed results. + +For an efficient review, the folder should be opened in the +`Polyspace user interface `__ +or `uploaded to the web interface `__ +and reviewed there. + +For programmatic access of the results, e.g., in the CI pipeline, the +individual issues are also described in a CSV file in the results folder. + +Configuration +************* + +By default, Polyspace scans for typical programming defects on all C and C++ sources. +The following options are available to customize the default behavior: + +.. list-table:: + :widths: 20 40 30 + :header-rows: 1 + + * - Option + - Effect + - Example + * - ``POLYSPACE_ONLY_APP`` + - If set, only user code is analyzed and Zephyr sources are ignored. + - ``-DPOLYSPACE_ONLY_APP=1`` + * - ``POLYSPACE_OPTIONS`` + - Provide additional command line flags, e.g., for selection of coding + rules. Separate the options and their values by semicolon. For a list + of options, see `here `__. + - ``-DPOLYSPACE_OPTIONS="-misra3;mandatory-required;-checkers;all"`` + * - ``POLYSPACE_OPTIONS_FILE`` + - Command line flags can also be provided in a text file, line by + line. Provide the absolute path to the file. + - ``-DPOLYSPACE_OPTIONS_FILE=/workdir/zephyr/myoptions.txt`` + * - ``POLYSPACE_MODE`` + - Switch between bugfinding and proving mode. Default is bugfinding. + See `here `__ for more details. + - ``-DPOLYSPACE_MODE=prove`` + * - ``POLYSPACE_PROG_NAME`` + - Override the name of the analyzed application. Default is board + and application name. + - ``-DPOLYSPACE_PROG_NAME=myapp`` + * - ``POLYSPACE_PROG_VERSION`` + - Override the version of the analyzed application. Default is taken + from git-describe. + - ``-DPOLYSPACE_PROG_VERSION=v1.0b-28f023`` diff --git a/doc/develop/test/bsim.rst b/doc/develop/test/bsim.rst index 0bdc7d0fecc19..d5484df51b558 100644 --- a/doc/develop/test/bsim.rst +++ b/doc/develop/test/bsim.rst @@ -7,11 +7,11 @@ BabbleSim and Zephyr ******************** In the Zephyr project we use the `Babblesim`_ simulator to test some of the Zephyr radio protocols, -including the BLE stack, 802.15.4, and some of the networking stack. +including the Bluetooth LE stack, 802.15.4, and some of the networking stack. BabbleSim_ is a physical layer simulator, which in combination with the Zephyr :ref:`bsim boards` -can be used to simulate a network of BLE and 15.4 devices. +can be used to simulate a network of Bluetooth LE and 15.4 devices. When we build Zephyr targeting a :ref:`bsim board` we produce a Linux executable, which includes the application, Zephyr OS, and models of the HW. diff --git a/doc/develop/test/coverage.rst b/doc/develop/test/coverage.rst index 5c86adda1b325..1811990b273d5 100644 --- a/doc/develop/test/coverage.rst +++ b/doc/develop/test/coverage.rst @@ -60,34 +60,42 @@ These steps will produce an HTML coverage report for a single application. .. code-block:: console - ninja -Cbuild run | tee log.log + $ ninja -Cbuild run | tee log.log or .. code-block:: console - ninja -Cbuild run | tee log.log + $ ninja -Cbuild run | tee log.log #. Generate the gcov ``.gcda`` and ``.gcno`` files from the log file that was - saved:: + saved: + + .. code-block:: console $ python3 scripts/gen_gcov_files.py -i log.log #. Find the gcov binary placed in the SDK. You will need to pass the path to the gcov binary for the appropriate architecture when you later invoke - ``gcovr``:: + ``gcovr``: + + .. code-block:: console $ find $ZEPHYR_SDK_INSTALL_DIR -iregex ".*gcov" -#. Create an output directory for the reports:: +#. Create an output directory for the reports: + + .. code-block:: console $ mkdir -p gcov_report -#. Run ``gcovr`` to get the reports:: +#. Run ``gcovr`` to get the reports: + + .. code-block:: console $ gcovr -r $ZEPHYR_BASE . --html -o gcov_report/coverage.html --html-details --gcov-executable -.. _coverage_posix: + .. _coverage_posix: Coverage reports using the POSIX architecture ********************************************* @@ -117,8 +125,8 @@ You may postprocess these with your preferred tools. For example: $ ./build/zephyr/zephyr.exe # Press Ctrl+C to exit - lcov --capture --directory ./ --output-file lcov.info -q --rc lcov_branch_coverage=1 - genhtml lcov.info --output-directory lcov_html -q --ignore-errors source --branch-coverage --highlight --legend + $ lcov --capture --directory ./ --output-file lcov.info -q --rc lcov_branch_coverage=1 + $ genhtml lcov.info --output-directory lcov_html -q --ignore-errors source --branch-coverage --highlight --legend .. note:: @@ -134,11 +142,15 @@ Zephyr's :ref:`twister script ` can automatically generate a coverage report from the tests which were executed. You just need to invoke it with the ``--coverage`` command line option. -For example, you may invoke:: +For example, you may invoke: + +.. code-block:: console $ twister --coverage -p qemu_x86 -T tests/kernel -or:: +or: + +.. code-block:: console $ twister --coverage -p native_sim -T tests/bluetooth @@ -148,13 +160,36 @@ the coverage data collected by ``gcovr`` tool in ``twister-out/coverage.json``. Other reports might be chosen with ``--coverage-tool`` and ``--coverage-formats`` command line options. +To generate code coverage report including Zephyr sources as well as your application +code outside of Zephyr repository (see :ref:`Application Types `) +call Twister from your project directory with ``--coverage-basedir $ZEPHYR_BASE`` +command line option, for example: + +.. code-block:: console + + $ $ZEPHYR_BASE/scripts/twister --coverage -p native_sim --coverage_basedir $ZEPHYR_BASE -T your_project_dir + +.. note:: + + By default, Twister calls ``gcovr`` tool which filters source files assuming real paths + are everywhere with `all symlinks resolved `_, so when your development + environment has directories with symlinks then, to avoid incomplete ``gcovr`` reports, + either your :ref:`ZEPHYR_BASE ` should contain a real path, + or ``lcov`` tool used instead of ``gcovr`` with additional Twister command line + option ``--coverage-tool lcov``. + The process differs for unit tests, which are built with the host -toolchain and require a different board:: +toolchain and require a different board: - $ twister --coverage -p unit_testing -T tests/unit +.. code-block:: console + + $ twister --coverage -p unit_testing -T tests/unit which produces a report in the same location as non-unit testing. +.. _gcovr_symlinks: + https://github.com/gcovr/gcovr/blob/main/doc/source/guide/filters.rst#filters-for-symlinks + .. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index 9bf95c030989a..88137a6917472 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -219,6 +219,8 @@ Shell .. automethod:: wait_for_prompt + .. automethod:: get_filtered_output + Examples of pytest tests in the Zephyr project ********************************************** diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index a3893e5da6a97..42f09ef020eee 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -116,7 +116,6 @@ required for best test coverage for this specific board: toolchain: - zephyr - gnuarmemb - - xtools supported: - arduino_gpio - arduino_i2c @@ -261,8 +260,7 @@ A Test Suite is a collection of Test Cases which are intended to be used to test a software program to ensure it meets certain requirements. The Test Cases in a Test Suite are either related or meant to be executed together. -The name of each Test Scenario needs to be unique in the context of the overall -test application and has to follow basic rules: +Test Scenario, Test Suite, and Test Case names must follow to these basic rules: #. The format of the Test Scenario identifier shall be a string without any spaces or special characters (allowed characters: alphanumeric and [\_=]) consisting @@ -272,7 +270,8 @@ test application and has to follow basic rules: subsection names delimited with a dot (``.``). For example, a test scenario that covers semaphores in the kernel shall start with ``kernel.semaphore``. -#. All Test Scenario identifiers within a ``testcase.yaml`` file need to be unique. +#. All Test Scenario identifiers within a Test Configuration (``testcase.yaml`` file) + need to be unique. For example a ``testcase.yaml`` file covering semaphores in the kernel can have: * ``kernel.semaphore``: For general semaphore tests @@ -295,6 +294,18 @@ test application and has to follow basic rules: Test Case name, for example: ``debug.coredump.logging_backend``. +The ``--no-detailed-test-id`` command line option modifies the above rules in this way: + +#. A Test Suite name has only ```` component. + Its Application Project path can be found in ``twister.json`` report as ``path:`` property. + +#. With short Test Suite names in this mode, all corresponding Test Scenario names + must be unique for the Twister execution scope. + +#. **Ztest** Test Case names have only Ztest components ``.``. + Its parent Test Suite name equals to the corresponding Test Scenario identifier. + + The following is an example test configuration with a few options that are explained in this document. @@ -478,6 +489,40 @@ integration_platforms: platform_allow if the goal is to limit scope due to timing or resource constraints. +integration_toolchains: + This option expands the scope to all the listed toolchains variants and + adds another vector of testing where desired. By default, test + configurations are generated based on the toolchain configured in the environment: + + test scenario -> platforms1 -> toolchain1 + test scenario -> platforms2 -> toolchain1 + + + When a platform supports multiple toolchains that are available during the + twister run, it is possible to expand the test configurations to include + additional tests for each toolchain. For example, if a platform supports + toolchains ``toolchain1`` and ``toolchain2``, and the test scenario + includes: + + .. code-block:: yaml + + integration_toolchains: + - toolchain1 + - toolchain2 + + the following configurations are generated: + + test scenario -> platforms1 -> toolchain1 + test scenario -> platforms1 -> toolchain2 + test scenario -> platforms2 -> toolchain1 + test scenario -> platforms2 -> toolchain2 + + + .. note:: + + This functionality is evaluated always and is not limited to the + ``--integration`` option. + platform_exclude: Set of platforms that this test scenario should not run on. @@ -514,30 +559,10 @@ harness: - pytest - gtest - robot + - ctest + - shell - Harnesses ``ztest``, ``gtest`` and ``console`` are based on parsing of the - output and matching certain phrases. ``ztest`` and ``gtest`` harnesses look - for pass/fail/etc. frames defined in those frameworks. Use ``gtest`` - harness if you've already got tests written in the gTest framework and do - not wish to update them to zTest. The ``console`` harness tells Twister to - parse a test's text output for a regex defined in the test's YAML file. - The ``robot`` harness is used to execute Robot Framework test suites - in the Renode simulation framework. - - Some widely used harnesses that are not supported yet: - - - keyboard - - net - - bluetooth - - Harness ``bsim`` is implemented in limited way - it helps only to copy the - final executable (``zephyr.exe``) from build directory to BabbleSim's - ``bin`` directory (``${BSIM_OUT_PATH}/bin``). This action is useful to allow - BabbleSim's tests to directly run after. By default, the executable file - name is (with dots and slashes replaced by underscores): - ``bs___``. - This name can be overridden with the ``bsim_exe_name`` option in - ``harness_config`` section. + See :ref:`twister_harnesses` for more information. platform_key: Often a test needs to only be built and run once to qualify as passing. @@ -566,71 +591,6 @@ harness_config: what features it supports. This option will enable the test to run on only those platforms that fulfill this external dependency. - The following options are currently supported: - - type: (required) - Depends on the regex string to be matched - - regex: (required) - Strings with regular expressions to match with the test's output - to confirm the test runs as expected. - - ordered: (default False) - Check the regular expression strings in orderly or randomly fashion - - record: (optional) - regex: (required) - The regular expression with named subgroups to match data fields - at the test's output lines where the test provides some custom data - for further analysis. These records will be written into the build - directory ``recording.csv`` file as well as ``recording`` property - of the test suite object in ``twister.json``. - - For example, to extract three data fields ``metric``, ``cycles``, - ``nanoseconds``: - - .. code-block:: yaml - - record: - regex: "(?P.*):(?P.*) cycles, (?P.*) ns" - - as_json: (optional) - Data fields, extracted by the regular expression into named subgroups, - which will be additionally parsed as JSON encoded strings and written - into ``twister.json`` as nested ``recording`` object properties. - The corresponding ``recording.csv`` columns will contain strings as-is. - - Using this option, a test log can convey layered data structures - passed from the test image for further analysis with summary results, - traces, statistics, etc. - - For example, this configuration: - - .. code-block:: yaml - - record: - regex: "RECORD:(?P.*):DATA:(?P.*)" - as_json: [metrics] - - when matched to a test log string: - - .. code-block:: none - - RECORD:jitter_drift:DATA:{"rollovers":0, "mean_us":1000.0} - - will be reported in ``twister.json`` as: - - .. code-block:: json - - "recording":[ - { - "type":"jitter_drift", - "metrics":{ - "rollovers":0, - "mean_us":1000.0 - } - } - ] fixture: Specify a test scenario dependency on an external device(e.g., sensor), @@ -643,94 +603,6 @@ harness_config: Only one fixture can be defined per test scenario and the fixture name has to be unique across all tests in the test suite. -.. _pytest_root: - - pytest_root: (default pytest) - Specify a list of pytest directories, files or subtests that need to be - executed when a test scenario begins to run. The default pytest directory is - ``pytest``. After the pytest run is finished, Twister will check if - the test scenario passed or failed according to the pytest report. - As an example, a list of valid pytest roots is presented below: - - .. code-block:: yaml - - harness_config: - pytest_root: - - "pytest/test_shell_help.py" - - "../shell/pytest/test_shell.py" - - "/tmp/test_shell.py" - - "~/tmp/test_shell.py" - - "$ZEPHYR_BASE/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py" - - "pytest/test_shell_help.py::test_shell2_sample" # select pytest subtest - - "pytest/test_shell_help.py::test_shell2_sample[param_a]" # select pytest parametrized subtest - -.. _pytest_args: - - pytest_args: (default empty) - Specify a list of additional arguments to pass to ``pytest`` e.g.: - ``pytest_args: [‘-k=test_method’, ‘--log-level=DEBUG’]``. Note that - ``--pytest-args`` can be passed multiple times to pass several arguments - to the pytest. - -.. _pytest_dut_scope: - - pytest_dut_scope: (default function) - The scope for which ``dut`` and ``shell`` pytest fixtures are shared. - If the scope is set to ``function``, DUT is launched for every test case - in python script. For ``session`` scope, DUT is launched only once. - - robot_testsuite: (default empty) - Specify one or more paths to a file containing a Robot Framework test suite to be run. - - robot_option: (default empty) - One or more options to be send to robotframework. - - bsim_exe_name: - If provided, the executable filename when copying to BabbleSim's bin - directory, will be ``bs__`` instead of the - default based on the test path and scenario name. - - The following is an example yaml file with a few harness_config options. - - .. code-block:: yaml - - sample: - name: HTS221 Temperature and Humidity Monitor - common: - tags: sensor - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "Temperature:(.*)C" - - "Relative Humidity:(.*)%" - fixture: i2c_hts221 - tests: - test: - tags: sensors - depends_on: i2c - - The following is an example yaml file with pytest harness_config options, - default pytest_root name "pytest" will be used if pytest_root not specified. - please refer the examples in samples/subsys/testsuite/pytest/. - - .. code-block:: yaml - - common: - harness: pytest - tests: - pytest.example.directories: - harness_config: - pytest_root: - - pytest_dir1 - - $ENV_VAR/samples/test/pytest_dir2 - pytest.example.files_and_subtests: - harness_config: - pytest_root: - - pytest/test_file_1.py - - test_file_2.py::test_A - - test_file_2.py::test_B[param_a] The following is an example yaml file with robot harness_config options. @@ -878,6 +750,283 @@ line break instead of white spaces. Most everyday users will run with no arguments. +.. _twister_harnesses: + +Harnesses +********* + +Harnesses ``ztest``, ``gtest`` and ``console`` are based on parsing of the +output and matching certain phrases. ``ztest`` and ``gtest`` harnesses look +for pass/fail/etc. frames defined in those frameworks. + +Some widely used harnesses that are not supported yet: + +- keyboard +- net +- bluetooth + +The following is an example yaml file with a few harness_config options. + +.. code-block:: yaml + + sample: + name: HTS221 Temperature and Humidity Monitor + common: + tags: sensor + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "Temperature:(.*)C" + - "Relative Humidity:(.*)%" + fixture: i2c_hts221 + tests: + test: + tags: sensors + depends_on: i2c + +Ctest +===== + +ctest_args: (default empty) + Specify a list of additional arguments to pass to ``ctest`` e.g.: + ``ctest_args: [‘--repeat until-pass:5’]``. Note that + ``--ctest-args`` can be passed multiple times to pass several arguments + to the ctest. + + +Gtest +===== + +Use ``gtest`` harness if you've already got tests written in the gTest +framework and do not wish to update them to zTest. + +Pytest +====== + +The :ref:`pytest harness ` is used to execute pytest +test suites in the Zephyr test. The following options apply to the pytest harness: + +.. _pytest_root: + +pytest_root: (default pytest) + Specify a list of pytest directories, files or subtests that need to be + executed when a test scenario begins to run. The default pytest directory is + ``pytest``. After the pytest run is finished, Twister will check if + the test scenario passed or failed according to the pytest report. + As an example, a list of valid pytest roots is presented below: + + .. code-block:: yaml + + harness_config: + pytest_root: + - "pytest/test_shell_help.py" + - "../shell/pytest/test_shell.py" + - "/tmp/test_shell.py" + - "~/tmp/test_shell.py" + - "$ZEPHYR_BASE/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py" + - "pytest/test_shell_help.py::test_shell2_sample" # select pytest subtest + - "pytest/test_shell_help.py::test_shell2_sample[param_a]" # select pytest parametrized subtest + +.. _pytest_args: + +pytest_args: (default empty) + Specify a list of additional arguments to pass to ``pytest`` e.g.: + ``pytest_args: [‘-k=test_method’, ‘--log-level=DEBUG’]``. Note that + ``--pytest-args`` can be passed multiple times to pass several arguments + to the pytest. + +.. _pytest_dut_scope: + +pytest_dut_scope: (default function) + The scope for which ``dut`` and ``shell`` pytest fixtures are shared. + If the scope is set to ``function``, DUT is launched for every test case + in python script. For ``session`` scope, DUT is launched only once. + + + The following is an example yaml file with pytest harness_config options, + default pytest_root name "pytest" will be used if pytest_root not specified. + please refer the examples in samples/subsys/testsuite/pytest/. + + .. code-block:: yaml + + common: + harness: pytest + tests: + pytest.example.directories: + harness_config: + pytest_root: + - pytest_dir1 + - $ENV_VAR/samples/test/pytest_dir2 + pytest.example.files_and_subtests: + harness_config: + pytest_root: + - pytest/test_file_1.py + - test_file_2.py::test_A + - test_file_2.py::test_B[param_a] + +Console +======= + +The ``console`` harness tells Twister to parse a test's text output for a +regex defined in the test's YAML file. + +The following options are currently supported: + +type: (required) + Depends on the regex string to be matched + +regex: (required) + Strings with regular expressions to match with the test's output + to confirm the test runs as expected. + +ordered: (default False) + Check the regular expression strings in orderly or randomly fashion + +record: (optional) + regex: (required) + Regular expressions with named subgroups to match data fields found + in the test instance's output lines where it provides some custom data + for further analysis. These records will be written into the build + directory ``recording.csv`` file as well as ``recording`` property + of the test suite object in ``twister.json``. + + With several regular expressions given, each of them will be applied + to each output line producing either several different records from + the same output line, or different records from different lines, + or similar records from different lines. + + The .CSV file will have as many columns as there are fields detected + in all records; missing values are filled by empty strings. + + For example, to extract three data fields ``metric``, ``cycles``, + ``nanoseconds``: + + .. code-block:: yaml + + record: + regex: + - "(?P.*):(?P.*) cycles, (?P.*) ns" + + merge: (default False) + Allows to keep only one record in a test instance with all the data + fields extracted by the regular expressions. Fields with the same name + will be put into lists ordered as their appearance in recordings. + It is possible for such multi value fields to have different number + of values depending on the regex rules and the test's output. + + as_json: (optional) + Data fields, extracted by the regular expressions into named subgroups, + which will be additionally parsed as JSON encoded strings and written + into ``twister.json`` as nested ``recording`` object properties. + The corresponding ``recording.csv`` columns will contain JSON strings + as-is. + + Using this option, a test log can convey layered data structures + passed from the test image for further analysis with summary results, + traces, statistics, etc. + + For example, this configuration: + + .. code-block:: yaml + + record: + regex: "RECORD:(?P.*):DATA:(?P.*)" + as_json: [metrics] + + when matched to a test log string: + + .. code-block:: none + + RECORD:jitter_drift:DATA:{"rollovers":0, "mean_us":1000.0} + + will be reported in ``twister.json`` as: + + .. code-block:: json + + "recording":[ + { + "type":"jitter_drift", + "metrics":{ + "rollovers":0, + "mean_us":1000.0 + } + } + ] + +Robot +===== + +The ``robot`` harness is used to execute Robot Framework test suites +in the Renode simulation framework. + +robot_testsuite: (default empty) + Specify one or more paths to a file containing a Robot Framework test suite to be run. + +robot_option: (default empty) + One or more options to be send to robotframework. + +Bsim +==== + +Harness ``bsim`` is implemented in limited way - it helps only to copy the +final executable (``zephyr.exe``) from build directory to BabbleSim's +``bin`` directory (``${BSIM_OUT_PATH}/bin``). + +This action is useful to allow BabbleSim's tests to directly run after. +By default, the executable file name is (with dots and slashes +replaced by underscores): ``bs___``. +This name can be overridden with the ``bsim_exe_name`` option in +``harness_config`` section. + +bsim_exe_name: + If provided, the executable filename when copying to BabbleSim's bin + directory, will be ``bs__`` instead of the + default based on the test path and scenario name. + +Shell +===== + +The shell harness is used to execute shell commands and parse the output and utilizes the pytest +framework and the pytest harness of twister. + +The following options apply to the shell harness: + +shell_commands: (default empty) + Specify a list of shell commands to be executed and their expected output. + For example: + + .. code-block:: yaml + + harness_config: + shell_commands: + - command: "kernel cycles" + expected: "cycles: .* hw cycles" + - command: "kernel version" + expected: "Zephyr version .*" + - command: "kernel sleep 100" + + + If expected output is not provided, the command will be executed and the output + will be logged. + +shell_commands_file: (default empty) + Specify a file containing test parameters to be used in the test. + The file should contain a list of commands and their expected output. For example: + + .. code-block:: yaml + + - command: "mpu mtest 1" + expected: "The value is: 0x.*" + - command: "mpu mtest 2" + expected: "The value is: 0x.*" + + + If no file is specified, the shell harness will use the default file + ``test_shell.yml`` in the test directory. + ``shell_commands`` will take precedence over ``shell_commands_file``. + Selecting platform scope ************************ diff --git a/doc/develop/toolchains/crosstool_ng.rst b/doc/develop/toolchains/crosstool_ng.rst deleted file mode 100644 index dc51b9b36fc7e..0000000000000 --- a/doc/develop/toolchains/crosstool_ng.rst +++ /dev/null @@ -1,49 +0,0 @@ -.. _toolchain_xtools: - -Crosstool-NG (Deprecated) -######################### - -.. warning:: - - ``xtools`` toolchain variant is deprecated. The - :ref:`cross-compile toolchain variant ` should be used - when using a custom toolchain built with Crosstool-NG. - -You can build toolchains from source code using crosstool-NG. - -#. Follow the steps on the crosstool-NG website to `prepare your host - `_. - -#. Follow the `Zephyr SDK with Crosstool NG instructions - `_ to - build your toolchain. Repeat as necessary to build toolchains for multiple - target architectures. - - You will need to clone the ``sdk-ng`` repo and run the following command: - - .. code-block:: console - - ./go.sh - - .. note:: - - Currently, only i586 and Arm toolchain builds are verified. - -#. :ref:`Set these environment variables `: - - - Set :envvar:`ZEPHYR_TOOLCHAIN_VARIANT` to ``xtools``. - - Set :envvar:`XTOOLS_TOOLCHAIN_PATH` to the toolchain build directory. - -#. To check that you have set these variables correctly in your current - environment, follow these example shell sessions (the - :envvar:`XTOOLS_TOOLCHAIN_PATH` values may be different on your system): - - .. code-block:: console - - # Linux, macOS: - $ echo $ZEPHYR_TOOLCHAIN_VARIANT - xtools - $ echo $XTOOLS_TOOLCHAIN_PATH - /Volumes/CrossToolNGNew/build/output/ - -.. _crosstool-ng site: http://crosstool-ng.org diff --git a/doc/develop/toolchains/iar_arm_toolchain.rst b/doc/develop/toolchains/iar_arm_toolchain.rst new file mode 100644 index 0000000000000..8b854dd20da74 --- /dev/null +++ b/doc/develop/toolchains/iar_arm_toolchain.rst @@ -0,0 +1,60 @@ +IAR Arm Toolchain +################# + +#. Download and install a release of `IAR Arm Toolchain`_ (EWARM/CXARM) on your host. + +.. note:: + As of now, a Development version of the IAR build tools for Arm is required to work with Zephyr. + It is distributed to selected partners and customers for evaluation. If you are interested in being + part of this program, please send a request to the IAR FAE team at fae.emea@iar.com. + +#. Make sure you have :ref:`Zephyr SDK ` installed on your host. + +.. note:: + A Zephyr SDK is used as a source of tools like device tree compiler (DTC), QEMU, etc… Even though + IAR Arm toolchain is used for Zephyr RTOS build, still the GNU preprocessor & GNU objcopy might + be used for some steps like device tree preprocessing and .bin file generation. + +#. :ref:`Set these environment variables `: + + - Set :envvar:`ZEPHYR_TOOLCHAIN_VARIANT` to ``iar``. + - Set :envvar:`IAR_TOOLCHAIN_PATH` to the toolchain installation directory. + +#. The IAR Toolchain needs the :envvar:`IAR_LMS_BEARER_TOKEN` environment + variable to be set to a valid ``license bearer token``. + +For example: + + .. code-block:: bash + + # Linux (default installation path): + export IAR_TOOLCHAIN_PATH=/opt/iarsystems/bxarm/arm + export ZEPHYR_TOOLCHAIN_VARIANT=iar + export IAR_LMS_BEARER_TOKEN="" + + .. code-block:: batch + + # Windows: + set IAR_TOOLCHAIN_PATH=c:\\arm + set ZEPHYR_TOOLCHAIN_VARIANT=iar + set IAR_LMS_BEARER_TOKEN="" + +.. note:: + + The IAR Toolchain uses ``ilink`` for linking. This is incompatible with Zephyr’s + linker script template, which works with GNU ld. Zephyr’s IAR Arm Toolchain depends on + Zephyr’s CMake linker script generator, which supports generating icf-files. + Basic icf-file support is in place, but there are still areas which are not fully + supported by the CMake linker script generator. + +.. note:: + + The IAR Toolchain uses the GNU Assembler which is distributed with the Zephyr SDK + for ``.S-files``. + +.. note:: + + Some Zephyr subsystems or modules may also contain C or assembly code that relies + on GNU intrinsics and have not yet been updated to work fully with ``iar``. + +.. _IAR Arm Toolchain: https://www.iar.com/products/architectures/arm/ diff --git a/doc/develop/toolchains/index.rst b/doc/develop/toolchains/index.rst index 4310e22f19a00..e085a1fbe1c3c 100644 --- a/doc/develop/toolchains/index.rst +++ b/doc/develop/toolchains/index.rst @@ -14,9 +14,9 @@ Guides on how to set up toolchains for Zephyr development. cadence_xcc.rst designware_arc_mwdt.rst gnu_arm_embedded.rst + iar_arm_toolchain.rst intel_oneapi_toolkit.rst - crosstool_ng.rst host.rst other_x_compilers.rst custom_cmake.rst diff --git a/doc/develop/tools/clion.rst b/doc/develop/tools/clion.rst index d72e2ed28d6a2..a9e7104526f11 100644 --- a/doc/develop/tools/clion.rst +++ b/doc/develop/tools/clion.rst @@ -3,6 +3,15 @@ CLion ##### +.. note:: + + This guide describes how to set up, build, and debug Zephyr's sample application in CLion, using + the IDE's CMake integration. This approach is no longer optimal. + + CLion now features `native Zephyr West integration`_ which provides an easier and more intuitive + way to open, build, and run/debug Zephyr projects. This guide will be updated soon, but is still + valid if you prefer to use CMake. + CLion_ is a cross-platform C/C++ IDE that supports multi-threaded RTOS debugging. This guide describes the process of setting up, building, and debugging Zephyr's @@ -200,6 +209,7 @@ Start debugging Refer to `CLion web help`_ for detailed description of the IDE debug capabilities. +.. _native Zephyr West integration: https://www.jetbrains.com/help/clion/zephyr.html .. _CLion: https://www.jetbrains.com/clion/ .. _Download CLion: https://www.jetbrains.com/clion/download .. _Project security: https://www.jetbrains.com/help/clion/project-security.html#projects_security diff --git a/doc/develop/west/build-flash-debug.rst b/doc/develop/west/build-flash-debug.rst index c45a4551843e9..2b7dd3ecd3ba6 100644 --- a/doc/develop/west/build-flash-debug.rst +++ b/doc/develop/west/build-flash-debug.rst @@ -779,6 +779,19 @@ To view all available options Renode supports, use:: west simulate --runner=renode --renode-help +Out of tree runners +******************* + +:ref:`Zephyr modules ` can have external runners discovered by adding python +files in their :ref:`module.yml `. Create an external runner class by +inheriting from ``ZephyrBinaryRunner`` and implement all abstract methods. + +.. note:: + + Support for custom out-of-tree runners makes the ``runners.core`` module part of + the public API and backwards incompatible changes need to undergo the + :ref:`deprecation process `. + Hacking ******* @@ -786,11 +799,6 @@ This section documents the ``runners.core`` module used by the flash and debug commands. This is the core abstraction used to implement support for these features. -.. warning:: - - These APIs are provided for reference, but they are more "shared code" used - to implement multiple extension commands than a stable API. - Developers can add support for new ways to flash and debug Zephyr programs by implementing additional runners. To get this support into upstream Zephyr, the runner should be added into a new or existing ``runners`` module, and imported diff --git a/doc/develop/west/workspaces.rst b/doc/develop/west/workspaces.rst index 5c182658df92e..d3dadc2b369d9 100644 --- a/doc/develop/west/workspaces.rst +++ b/doc/develop/west/workspaces.rst @@ -321,3 +321,25 @@ v2.5.0 and its modules, then add the ``app1`` and ``app2`` projects: You can also do this "by hand" by copy/pasting :file:`zephyr/west.yml` as shown :ref:`above ` for the T2 topology, with the same caveats. + +.. _workspace-as-git-repo: + +Not supported: workspace topdir as .git repository +************************************************** + +Some users have asked for support making the workspace :ref:`topdir +` a git repository, like this example: + +.. code-block:: none + + my-workspace/ # workspace topdir + ├── .git/ # puts the entire workspace in a git repository + ├── .west/ # marks the location of the topdir + └── [ ... other projects ...] + +This is **not** an officially supported topology. As a design decision, west +assumes that the workspace topdir itself is not a git repository. + +You may be able to make something like this "work" for yourself and your own +goals. However, future versions of west might contain changes which can "break" +your setup. diff --git a/doc/hardware/arch/arm-scmi.rst b/doc/hardware/arch/arm-scmi.rst index 65dad1bffce65..c4ffcf8229f1f 100644 --- a/doc/hardware/arch/arm-scmi.rst +++ b/doc/hardware/arch/arm-scmi.rst @@ -135,10 +135,22 @@ Protocols Currently, Zephyr has support for the following standard protocols: + #. **Power domain management** #. **Clock management** #. **Pin Control** +Power domain management +*********************** + +This protocol is intended for management of power states of power domains. +This is done via a set of functions implementing various commands, for +example, ``POWER_STATE_GET`` and ``POWER_STATE_SET``. + +.. note:: + This driver is vendor-agnostic. As such, it may be used on any + system that uses SCMI for power domain management operations. + Clock management protocol ************************* diff --git a/doc/hardware/arch/arm_cortex_m.rst b/doc/hardware/arch/arm_cortex_m.rst index 7e68398c9ccb0..7eef8e7f2f5d1 100644 --- a/doc/hardware/arch/arm_cortex_m.rst +++ b/doc/hardware/arch/arm_cortex_m.rst @@ -422,6 +422,8 @@ MPU stack guards detection mechanism; users may override this setting by manually enabling :kconfig:option:`CONFIG_MPU_STACK_GUARD` in these scenarios. +.. _arm_cortex_m_mpu_considerations: + Memory map and MPU considerations ================================= @@ -469,18 +471,19 @@ For example, to define a new non-cacheable memory region in devicetree: }; This will automatically create a new MPU entry in with the correct name, base, -size and attributes gathered directly from the devicetree. +size and attributes gathered directly from the devicetree. See :ref:`cache_guide` +and :ref:`mem_mgmt_api` for more details. Static MPU regions ------------------ Additional *static* MPU regions may be programmed once during system boot. These regions -are required to enable certain features +are required to enable certain features. See :ref:`cache_guide` for more details. * a RX region to allow execution from SRAM, when :kconfig:option:`CONFIG_ARCH_HAS_RAMFUNC_SUPPORT` is enabled and users have defined functions to execute from SRAM. * a RX region for relocating text sections to SRAM, when :kconfig:option:`CONFIG_CODE_DATA_RELOCATION_SRAM` is enabled -* a no-cache region to allow for a none-cacheable SRAM area, when :kconfig:option:`CONFIG_NOCACHE_MEMORY` is enabled +* a ``nocache`` region to allow for a non-cacheable SRAM area, when :kconfig:option:`CONFIG_NOCACHE_MEMORY` is enabled * a possibly unprivileged RW region for GCOV code coverage accounting area, when :kconfig:option:`CONFIG_COVERAGE_GCOV` is enabled * a no-access region to implement null pointer dereference detection, when :kconfig:option:`CONFIG_NULL_POINTER_EXCEPTION_DETECTION_MPU` is enabled diff --git a/doc/hardware/arch/risc-v.rst b/doc/hardware/arch/risc-v.rst index 1484781f6586b..473b614b44b20 100644 --- a/doc/hardware/arch/risc-v.rst +++ b/doc/hardware/arch/risc-v.rst @@ -32,6 +32,8 @@ combinations. SMP support *********** -SMP is supported on RISC-V, but currently only on Qemu platforms. In -order to test the SMP support, one can use ``qemu_riscv32_smp`` or -``qemu_riscv64_smp`` boards. +SMP is supported on RISC-V for both QEMU-virtualized and hardware-based +platforms. In order to test the SMP support, one can use +:zephyr:board:`qemu_riscv32` or :zephyr:board:`qemu_riscv64` for QEMU-based +platforms, or :zephyr:board:`beaglev_fire` or :zephyr:board:`mpfs_icicle` for +hardware-based platforms. diff --git a/doc/hardware/cache/guide.rst b/doc/hardware/cache/guide.rst new file mode 100644 index 0000000000000..e2a8391895d12 --- /dev/null +++ b/doc/hardware/cache/guide.rst @@ -0,0 +1,183 @@ +.. _cache_guide: + +Caching Basics +############## + +This section discusses the basics of cache coherency and under what situations a +user needs to explicitly deal with caching. For more detailed info on Zephyr's +caching tools, see :ref:`cache_config` for Zephyr Kconfig options or +:ref:`cache_api` for the API reference. This section primarily focuses on the +data cache though there is typically also an instruction cache for systems with +cache support. + +.. note:: + + The information here assumes that the architecture-specific MPU support is + enabled. See the architecture-specific documentation for details. + +.. note:: + + While cache coherence can be a concern for data shared between SMP cores, Zephyr + in general ensures that memory will be seen in a coherent state from multiple + cores. Most applications will only need to use the cache APIs for interaction + with external hardware like DMA controllers or foreign CPUs running a + different OS image. For more information on cache coherence between SMP cores, + see :kconfig:option:`CONFIG_KERNEL_COHERENCE`. + +When dealing with memory shared between a processor core and other bus masters, +cache coherency needs to be considered. Typically processor caches exist as +close to each processor core as possible to maximize performance gain. Because +of this, data moved into and out of memory by DMA engines will be stale in the +processor's cache, resulting in what appears to be corrupt data. If you are +moving data using DMA and the processor doesn't see the data you expect, cache +coherency may be the issue. + +There are multiple approaches to ensuring that the data seen by the processor +core and peripherals is coherent. The simplest is just to disable caching, but +this defeats the purpose of having a hardware cache in the first place and +results in a significant performance hit. Many architectures provide methods for +disabling caching for only a portion of memory. This can be useful when cache +coherence is more important than performance, such as when using DMA with SPI. +Finally, there is the option to flush or invalidate the cache for regions of +memory at runtime. + +Globally Disabling the Data Cache +--------------------------------- + +As mentioned above, globally disabling data caching can have a significant +performance impact but can be useful for debugging. + +Requirements: + +* :kconfig:option:`CONFIG_DCACHE`: DCACHE control enabled in Zephyr. + +* :kconfig:option:`CONFIG_CACHE_MANAGEMENT`: cache API enabled. + +* Call :c:func:`sys_cache_data_disable()` to globally disable the data cache. + +Disabling Caching for a Memory Region +------------------------------------- + +Disabling caching for only a portion of memory can be a good performance +compromise if performance on the uncached memory is not critical to the +application. This is a good option if the application requires many small +unrelated buffers that are smaller than a cache line. + +Requirements: + +* :kconfig:option:`CONFIG_DCACHE`: DCACHE control enabled in Zephyr. + +* :kconfig:option:`CONFIG_MEM_ATTR`: enable the ``mem-attr`` library for + handling memory attributes in the device tree. + +* Annotate your device tree according to :ref:`mem_mgmt_api`. + +Assuming the MPU driver is enabled, it will configure the specified regions +according to the memory attributes specified during kernel initialization. When +using a dedicated uncached region of memory, the linker needs to be instructed +to place buffers into that region. This can be accomplished by specifying the +memory region explicitly using ``Z_GENERIC_SECTION``: + +.. code-block:: c + + /* SRAM4 marked as uncached in device tree */ + uint8_t buffer[BUF_SIZE] Z_GENERIC_SECTION("SRAM4"); + +.. note:: + + Configuring a distinct memory region with separate caching rules requires the + use of an MPU region which may be a limited resource on some architectures. + MPU regions may be needed by other memory protection features such as + :ref:`userspace `, :ref:`stack protection `, + or :ref:`memory domains`. + +Automatically Disabling Caching by Variable +------------------------------------------- + +Zephyr has the ability to automatically define an uncached region in memory and +allocate variables to it using ``__nocache``. Any variables marked with this +attribute will be placed in a special ``nocache`` linker region in memory. This +region will be configured as uncached by the MPU driver during initialization. +This is a simpler option than explicitly declaring a region of memory uncached +but provides less control over the placement of these variables, as the linker +may allocate this region anywhere in RAM. + +Requirements: + +* :kconfig:option:`CONFIG_DCACHE`: DCACHE control enabled in Zephyr. + +* :kconfig:option:`CONFIG_NOCACHE_MEMORY`: enable allocation of the ``nocache`` + linker region and configure it as uncached. + +* Add the ``__nocache`` attribute at the end of any uncached buffer definition: + +.. code-block:: c + + uint8_t buffer[BUF_SIZE] __nocache; + +.. note:: + + See note above regarding possible limitations on MPU regions. The ``nocache`` + region is still a distinct MPU region even though it is automatically created + by Zephyr instead of being explicitly defined by the user. + +Runtime Cache Control +--------------------- + +The most performant but most complex option is to control data caching at +runtime. The two most relevant cache operations in this case are **flushing** +and **invalidating**. Both of these operations operate on the smallest unit of +cacheable memory, the cache line. Data cache lines are typically 16 to 128 +bytes. See :kconfig:option:`CONFIG_DCACHE_LINE_SIZE`. Cache line sizes are +typically fixed in hardware and not configurable, but Zephyr does need to know +the size of cache lines in order to correctly and efficiently manage the cache. +If the buffers in question are smaller than the data cache line size, it may be +more efficient to place them in an uncached region, as unrelated data packed +into the same cache line may be destroyed when invalidating. + +Flushing the cache involves writing all modified cache lines in a specified +region back to shared memory. Flush the cache associated with a buffer after the +processor has written to it and before a remote bus master reads from that +region. + +.. note:: + + Some architectures support a cache configuration called **write-through** + caching in which data writes from the processor core propagate through to + shared memory. While this solves the cache coherence problem for CPU writes, + it also results in more traffic to main memory which may result in performance + degradation. + +Invalidating the cache works similarly but in the other direction. It marks +cache lines in the specified region as stale, ensuring that the cache line will +be refreshed from main memory when the processor next reads from the specified +region. Invalidate the data cache of a buffer that a peripheral has written to +before reading from that region. + +In some cases, the same buffer may be reused for e.g. DMA reads and DMA writes. +In that case it is possible to first flush the cache associated with a buffer +and then invalidate it, ensuring that the cache will be refreshed the next time +the processor reads from the buffer. + +Requirements: + +* :kconfig:option:`CONFIG_DCACHE`: DCACHE control enabled in Zephyr. + +* :kconfig:option:`CONFIG_CACHE_MANAGEMENT`: cache API enabled. + +* Call :c:func:`sys_cache_data_flush_range()` to flush a memory region. + +* Call :c:func:`sys_cache_data_invd_range()` to invalidate a memory region. + +* Call :c:func:`sys_cache_data_flush_and_invd_range()` to flush and invalidate. + +Alignment +--------- + +As mentioned in :c:func:`sys_cache_data_invd_range()` and associated functions, +buffers should be aligned to the cache line size. This can be accomplished by +using ``__aligned``: + +.. code-block:: c + + uint8_t buffer[BUF_SIZE] __aligned(CONFIG_DCACHE_LINE_SIZE); diff --git a/doc/hardware/cache/index.rst b/doc/hardware/cache/index.rst index 7f5fd5045e0d3..9e1ab1890ef7b 100644 --- a/doc/hardware/cache/index.rst +++ b/doc/hardware/cache/index.rst @@ -1,9 +1,9 @@ -.. _cache-guide: +.. _cache_config: -Cache Interface -############### +Cache Control Configuration +########################### -This is a high-level guide to cache interface and Kconfig options related to +This is a high-level guide to Zephyr's cache interface and Kconfig options related to cache controllers. See :ref:`cache_api` for API reference material. Zephyr has different Kconfig options to control how the cache controller is @@ -15,12 +15,14 @@ implemented and controlled. instruction cache. The cache controller can be in the core or can be an external cache controller for which a driver is provided. - These options have the goal to document an available feature and should be - set whether we plan to support and use the caches in Zephyr or not. + These options have the goal to document an available hardware feature and + should be set whether we plan to support and use the cache control in Zephyr + or not. * :kconfig:option:`CONFIG_DCACHE` / :kconfig:option:`CONFIG_ICACHE`: these options must be selected when support for data or instruction cache is - present and working in zephyr. + present and working in zephyr. Note that if these options are disabled, + caching may still be enabled depending on the hardware defaults. All the code paths related to cache control must be conditionally enabled depending on these symbols. When the symbol is set the cache is considered @@ -39,6 +41,15 @@ implemented and controlled. implemented in the architectural code or in an external cache controller driver. +* :kconfig:option:`CONFIG_MEM_ATTR`: this option allows the user to + specify (using :ref:`memory region attributes`) a fixed region + in memory that will have caching disabled once the kernel has initialized. + +* :kconfig:option:`CONFIG_NOCACHE_MEMORY`: this option allows the user to + specify individual global variables as uncached using ``__nocache``. This will + instruct the linker to place any marked variables into a special ``nocache`` + region in memory and the MPU driver will configure that region as uncached. + * :kconfig:option:`CONFIG_ARCH_CACHE`/:kconfig:option:`CONFIG_EXTERNAL_CACHE`: mutually exclusive options for :kconfig:option:`CACHE_TYPE` used to define whether the cache operations are implemented at arch level or using an @@ -54,6 +65,6 @@ implemented and controlled. .. _cache_api: Cache API -********* +######### .. doxygengroup:: cache_interface diff --git a/doc/hardware/index.rst b/doc/hardware/index.rst index 72e9cc5fd0561..72697d09e72d9 100644 --- a/doc/hardware/index.rst +++ b/doc/hardware/index.rst @@ -8,6 +8,7 @@ Hardware Support arch/index.rst barriers/index.rst + cache/guide.rst cache/index.rst emulator/index.rst emulator/bus_emulators.rst diff --git a/doc/hardware/peripherals/dma.rst b/doc/hardware/peripherals/dma.rst index f2b998aaeda94..575c42cde6473 100644 --- a/doc/hardware/peripherals/dma.rst +++ b/doc/hardware/peripherals/dma.rst @@ -14,6 +14,10 @@ peripheral interactions, and features. The API in effect provides a union of all functionality drivers have needed in the tree. It can still be a good abstraction, with care, for peripheral devices for vendors where the DMA IP might be very similar but have slight variances. +The DMA drivers in general do not handle cache coherency; this is left up to the developer as +requirements vary dramatically depending on the application. See :ref:`cache_guide` for an +overview of cache management in Zephyr. + Driver Implementation Expectations ********************************** diff --git a/doc/hardware/peripherals/sensor/triggers.rst b/doc/hardware/peripherals/sensor/triggers.rst index 6dd7870103225..c4a5c9536a2cc 100644 --- a/doc/hardware/peripherals/sensor/triggers.rst +++ b/doc/hardware/peripherals/sensor/triggers.rst @@ -5,7 +5,7 @@ Sensor Triggers :dfn:`Triggers`, enumerated in :c:enum:`sensor_trigger_type`, are sensor generated events. Typically sensors allow setting up these events to cause -digital line signaling for easy capture by a micro controller. The events can +digital line signaling for easy capture by a microcontroller. The events can then commonly be inspected by reading registers to determine which event caused the digital line signaling to occur. diff --git a/doc/hardware/peripherals/stepper.rst b/doc/hardware/peripherals/stepper.rst index 8dce76c5d5541..0754b35b5cc86 100644 --- a/doc/hardware/peripherals/stepper.rst +++ b/doc/hardware/peripherals/stepper.rst @@ -12,16 +12,15 @@ Configure Stepper Driver and :c:func:`stepper_get_micro_step_res`. - Configure **reference position** in microsteps using :c:func:`stepper_set_reference_position` and :c:func:`stepper_get_actual_position`. -- Set **max velocity** in micro-steps per second using :c:func:`stepper_set_max_velocity` +- Set **step interval** in nanoseconds between steps using :c:func:`stepper_set_microstep_interval` - **Enable** the stepper driver using :c:func:`stepper_enable`. Control Stepper =============== -- **Move by** +/- micro-steps also known as **relative movement** using :c:func:`stepper_move`. -- **Move to** a specific position also known as **absolute movement** - using :c:func:`stepper_set_target_position`. -- Run continuously with a **constant velocity** in a specific direction until +- **Move by** +/- micro-steps also known as **relative movement** using :c:func:`stepper_move_by`. +- **Move to** a specific position also known as **absolute movement** using :c:func:`stepper_move_to`. +- Run continuously with a **constant step interval** in a specific direction until a stop is detected using :c:func:`stepper_run`. - Check if the stepper is **moving** using :c:func:`stepper_is_moving`. - Register an **event callback** using :c:func:`stepper_set_event_callback`. @@ -38,7 +37,7 @@ be used in a boards devicetree to configure a stepper driver to its initial stat See examples in: - :dtcompatible:`zephyr,gpio-stepper` -- :dtcompatible:`adi,tmc5041` +- :dtcompatible:`adi,tmc50xx` Discord ======= diff --git a/doc/hardware/porting/board_porting.rst b/doc/hardware/porting/board_porting.rst index b1b6141d7af4f..8140c7a367b2a 100644 --- a/doc/hardware/porting/board_porting.rst +++ b/doc/hardware/porting/board_porting.rst @@ -281,7 +281,7 @@ The mandatory files are: #. :file:`plank_.dts`: a hardware description in :ref:`devicetree ` format. This declares your SoC, connectors, and any other hardware components such as LEDs, buttons, sensors, or - communication peripherals (USB, BLE controller, etc). + communication peripherals (USB, Bluetooth controller, etc). #. :file:`Kconfig.plank`: the base software configuration for selecting SoC and other board and SoC related settings. Kconfig settings outside of the board @@ -649,6 +649,15 @@ while porting. - If available, configure and enable a serial output for the console using the ``zephyr,console`` chosen node in the devicetree. + Development boards with a built-in debug adapter or USB-to-UART adapter should + by default configure and use the UART controller connected to that adapter. + For boards like :ref:`nRF52840 Dongle `, that do not + have a debug adapter, but a USB device controller, there is a common + :zephyr_file:`Kconfig file ` + that must be included in the board's Kconfig.defconfig file and + :zephyr_file:`devicetree file ` + that must be included if the board's devicetree, if the board want to use the + CDC ACM UART as the default backend for logging and shell. - If your board supports networking, configure a default interface. diff --git a/doc/index.rst b/doc/index.rst index aa4918c583b98..9d5a30c3d7f82 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -39,13 +39,6 @@ documentation for a specific version of Zephyr.

Set up Zephyr, build & run a sample application

-
  • - - -

    Contribution Guidelines

    -
    -

    How to submit patches and contribute to Zephyr

    -
  • @@ -53,6 +46,13 @@ documentation for a specific version of Zephyr.

    Explore samples and demos for various boards

  • +
  • + + +

    Supported Boards

    +
    +

    List of supported boards and platforms

    +
  • @@ -67,13 +67,6 @@ documentation for a specific version of Zephyr.

    Security processes and guidelines

  • -
  • - - -

    Supported Boards

    -
    -

    List of supported boards and platforms

    -
  • @@ -81,6 +74,13 @@ documentation for a specific version of Zephyr.

    OS Services and usage guides

  • +
  • + + +

    Contribution Guidelines

    +
    +

    How to submit patches and contribute to Zephyr

    +
  • For information about the changes and additions for past releases, please diff --git a/doc/kernel/code-relocation.rst b/doc/kernel/code-relocation.rst index aea6e11793d4b..c3b8aced76ecc 100644 --- a/doc/kernel/code-relocation.rst +++ b/doc/kernel/code-relocation.rst @@ -14,15 +14,23 @@ This script provides a robust way to re-order the memory contents without actually having to modify the code. In simple terms this script will do the job of ``__attribute__((section("name")))`` for a bunch of files together. +A regular expression filter can be used to select only the required sections to be relocated. + Details ******* -The memory region and file are given to the :ref:`gen_relocate_app.py` script in the form of a string. +The memory region and file are given to the :ref:`gen_relocate_app.py` script +through a file where each line specifies a list of files to be placed in the +given region. + +An example of such a file is: + + .. code-block:: none -An example of such a string is: -``SRAM2:/home/xyz/zephyr/samples/hello_world/src/main.c,SRAM1:/home/xyz/zephyr/samples/hello_world/src/main2.c`` + SRAM2:/home/xyz/zephyr/samples/hello_world/src/main.c, + SRAM1:/home/xyz/zephyr/samples/hello_world/src/main2.c, This script is invoked with the following parameters: -``python3 gen_relocate_app.py -i input_string -o generated_linker -c generated_code`` +``python3 gen_relocate_app.py -i input_file -o generated_linker -c generated_code`` Kconfig :kconfig:option:`CONFIG_CODE_DATA_RELOCATION` option, when enabled in ``prj.conf``, will invoke the script and do the required relocation. @@ -97,6 +105,24 @@ This section shows additional configuration options that can be set in zephyr_code_relocate(FILES ${sources} LOCATION SRAM) zephyr_code_relocate(FILES $ LOCATION SRAM) +Section Filtering +================= + +By default, all sections of the specified files will be relocated. If +``FILTER`` is used, a regular expression is provided to select only +the sections to be relocated. + +The regular expression applies to sections names which can be used to +select the file's symbols when this one has been built with +``-ffunction-sections`` and ``-fdata-sections`` which is the case by +default. + + .. code-block:: none + + zephyr_code_relocate(FILES src/file1.c FILTER ".*\\.func1|.*\\.func2" LOCATION SRAM2_TEXT) + +The example above will only relocate ``func1()`` and ``func2()`` of file ``src/file1.c`` + NOKEEP flag =========== diff --git a/doc/kernel/services/data_passing/message_queues.rst b/doc/kernel/services/data_passing/message_queues.rst index afa333104844a..18c8cf34eba45 100644 --- a/doc/kernel/services/data_passing/message_queues.rst +++ b/doc/kernel/services/data_passing/message_queues.rst @@ -108,6 +108,7 @@ The following code builds on the example above, and uses the message queue to pass data items from a producing thread to one or more consuming threads. If the message queue fills up because the consumers can't keep up, the producing thread throws away all existing data so the newer data can be saved. +Note that this api will trigger reschedule. .. code-block:: c diff --git a/doc/kernel/services/data_passing/pipes.rst b/doc/kernel/services/data_passing/pipes.rst index b3130687db5da..2a8c1ed0bd072 100644 --- a/doc/kernel/services/data_passing/pipes.rst +++ b/doc/kernel/services/data_passing/pipes.rst @@ -4,8 +4,8 @@ Pipes ##### A :dfn:`pipe` is a kernel object that allows a thread to send a byte stream -to another thread. Pipes can be used to synchronously transfer chunks of data -in whole or in part. +to another thread. Pipes enable efficient inter-thread communication and can +be used to synchronously transfer chunks of data in whole or in part. .. contents:: :local: @@ -14,192 +14,179 @@ in whole or in part. Concepts ******** -The pipe can be configured with a ring buffer which holds data that has been -sent but not yet received; alternatively, the pipe may have no ring buffer. - -Any number of pipes can be defined (limited only by available RAM). Each pipe is -referenced by its memory address. +Any number of pipes can be defined, limited only by available RAM. Each pipe +is referenced by its memory address. A pipe has the following key property: -* A **size** that indicates the size of the pipe's ring buffer. Note that a +* A **size** that indicates the capacity of the pipe's ring buffer. Note that a size of zero defines a pipe with no ring buffer. -A pipe must be initialized before it can be used. The pipe is initially empty. - -Data is synchronously **sent** either in whole or in part to a pipe by a -thread. If the specified minimum number of bytes can not be immediately -satisfied, then the operation will either fail immediately or attempt to send -as many bytes as possible and then pend in the hope that the send can be -completed later. Accepted data is either copied to the pipe's ring buffer -or directly to the waiting reader(s). - -Data is synchronously **received** from a pipe by a thread. If the specified -minimum number of bytes can not be immediately satisfied, then the operation -will either fail immediately or attempt to receive as many bytes as possible -and then pend in the hope that the receive can be completed later. Accepted -data is either copied from the pipe's ring buffer or directly from the -waiting sender(s). - -Data may also be **flushed** from a pipe by a thread. Flushing can be performed -either on the entire pipe or on only its ring buffer. Flushing the entire pipe -is equivalent to reading all the information in the ring buffer **and** waiting -to be written into a giant temporary buffer which is then discarded. Flushing -the ring buffer is equivalent to reading **only** the data in the ring buffer -into a temporary buffer which is then discarded. Flushing the ring buffer does -not guarantee that the ring buffer will stay empty; flushing it may allow a -pended writer to fill the ring buffer. - -.. note:: - Flushing does not in practice allocate or use additional buffers. - -.. note:: - The kernel does allow for an ISR to flush a pipe from an ISR. It also - allows it to send/receive data to/from one provided it does not attempt - to wait for space/data. +A pipe must be initialized before it can be used. When initialized, the pipe +is empty. + +Threads interact with the pipe as follows: + +- **Writing**: Data is synchronously written, either in whole or in part, to + a pipe by a thread. Accepted data is either copied directly to the waiting + reader(s) or to the pipe's ring buffer. If the ring buffer is full or simply + absent, the operation blocks until sufficient space becomes available or + the specified timeout expires. + +- **Reading**: Data is synchronously read, either in whole or in part, from a + pipe by a thread. Accepted data is either copied from the pipe's ring buffer + or directly from the waiting sender(s). If the ring buffer is empty or simply + absent, the operation blocks until data becomes available or the specified + timeout expires. + +- **Resetting**: A thread can reset a pipe, which resets its internal state and + ends all pending read and write operations with an error code. + +Pipes are well-suited for scenarios like producer-consumer patterns or +streaming data between threads. Implementation ************** -A pipe is defined using a variable of type :c:struct:`k_pipe` and an -optional character buffer of type ``unsigned char``. It must then be -initialized by calling :c:func:`k_pipe_init`. - -The following code defines and initializes an empty pipe that has a ring -buffer capable of holding 100 bytes and is aligned to a 4-byte boundary. +A pipe is defined using a variable of type :c:struct:`k_pipe` and a +byte buffer. The pipe must then be initialized by calling :c:func:`k_pipe_init`. +The following code defines and initializes an empty pipe with a ring buffer +capable of holding 100 bytes, aligned to a 4-byte boundary: .. code-block:: c - unsigned char __aligned(4) my_ring_buffer[100]; + uint8_t __aligned(4) my_ring_buffer[100]; struct k_pipe my_pipe; k_pipe_init(&my_pipe, my_ring_buffer, sizeof(my_ring_buffer)); -Alternatively, a pipe can be defined and initialized at compile time by -calling :c:macro:`K_PIPE_DEFINE`. - -The following code has the same effect as the code segment above. Observe -that macro defines both the pipe and its ring buffer. +Alternatively, a pipe can be defined and initialized at compile time using +the :c:macro:`K_PIPE_DEFINE` macro, which defines both the pipe and its +ring buffer: .. code-block:: c K_PIPE_DEFINE(my_pipe, 100, 4); +This has the same effect as the code above. + +When no ring buffer is used, the buffer pointer argument should be NULL and +the size argument should be 0. + Writing to a Pipe ================= -Data is added to a pipe by calling :c:func:`k_pipe_put`. +Data is added to a pipe by calling :c:func:`k_pipe_write`. -The following code builds on the example above, and uses the pipe to pass -data from a producing thread to one or more consuming threads. If the pipe's -ring buffer fills up because the consumers can't keep up, the producing thread -waits for a specified amount of time. +The following example demonstrates using a pipe to send data from a producer +thread to one or more consumer threads. If the pipe's ring buffer fills up, +the producer thread waits for a specified amount of time. .. code-block:: c - struct message_header { - ... - }; - - void producer_thread(void) - { - unsigned char *data; - size_t total_size; - size_t bytes_written; - int rc; - ... - - while (1) { - /* Craft message to send in the pipe */ - data = ...; - total_size = ...; - - /* send data to the consumers */ - rc = k_pipe_put(&my_pipe, data, total_size, &bytes_written, - sizeof(struct message_header), K_NO_WAIT); - - if (rc < 0) { - /* Incomplete message header sent */ - ... - } else if (bytes_written < total_size) { - /* Some of the data was sent */ - ... - } else { - /* All data sent */ - ... - } - } - } + struct message_header { + size_t num_data_bytes; /* Example field */ + ... + }; + + void producer_thread(void) + { + int rc; + uint8_t *data; + size_t total_size; + size_t bytes_written; + + while (1) { + /* Craft message to send in the pipe */ + make_message(data, &total_size); + bytes_written = 0; + + /* Write data to the pipe, handling partial writes */ + while (bytes_written < total_size) { + rc = k_pipe_write(&my_pipe, &data[bytes_written], total_size - bytes_written, K_NO_WAIT); + + if (rc < 0) { + /* Error occurred */ + ... + break; + } else { + /* Partial or full write succeeded; adjust for next iteration */ + bytes_written += rc; + } + } + + /* Reset bytes_written for the next message */ + bytes_written = 0; + ... + } + } Reading from a Pipe =================== -Data is read from the pipe by calling :c:func:`k_pipe_get`. - -The following code builds on the example above, and uses the pipe to -process data items generated by one or more producing threads. - -.. code-block:: c - - void consumer_thread(void) - { - unsigned char buffer[120]; - size_t bytes_read; - struct message_header *header = (struct message_header *)buffer; - - while (1) { - rc = k_pipe_get(&my_pipe, buffer, sizeof(buffer), &bytes_read, - sizeof(*header), K_MSEC(100)); - - if ((rc < 0) || (bytes_read < sizeof (*header))) { - /* Incomplete message header received */ - ... - } else if (header->num_data_bytes + sizeof(*header) > bytes_read) { - /* Only some data was received */ - ... - } else { - /* All data was received */ - ... - } - } - } - -Use a pipe to send streams of data between threads. - -.. note:: - A pipe can be used to transfer long streams of data if desired. However - it is often preferable to send pointers to large data items to avoid - copying the data. - -Flushing a Pipe's Buffer -======================== +Data is retrieved from the pipe by calling :c:func:`k_pipe_read`. -Data is flushed from the pipe's ring buffer by calling -:c:func:`k_pipe_buffer_flush`. - -The following code builds on the examples above, and flushes the pipe's -buffer. +The following example builds on the producer thread example above. It shows +a consumer thread that processes data generated by the producer. .. code-block:: c - void monitor_thread(void) - { - while (1) { - ... - /* Pipe buffer contains stale data. Flush it. */ - k_pipe_buffer_flush(&my_pipe); - ... - } - } - -Flushing a Pipe -=============== - -All data in the pipe is flushed by calling :c:func:`k_pipe_flush`. - -The following code builds on the examples above, and flushes all the -data in the pipe. + struct message_header { + size_t num_data_bytes; /* Example field */ + ... + }; + + void consumer_thread(void) + { + int rc; + uint8_t buffer[128]; + size_t bytes_read = 0; + struct message_header *header = (struct message_header *)buffer; + + while (1) { + /* Step 1: Read the message header */ + bytes_read = 0; + read_header: + while (bytes_read < sizeof(*header)) { + rc = k_pipe_read(&my_pipe, &buffer[bytes_read], sizeof(*header) - bytes_read, &bytes_read, K_NO_WAIT); + + if (rc < 0) { + /* Error occurred */ + ... + goto read_header; + } + + /* Adjust for partial reads */ + bytes_read += rc; + } + + /* Step 2: Read the message body */ + bytes_read = 0; + while (bytes_read < header->num_data_bytes) { + rc = k_pipe_read(&my_pipe, &buffer[sizeof(*header) + bytes_read], header->num_data_bytes - bytes_read, K_NO_WAIT); + + if (rc < 0) { + /* Error occurred */ + ... + goto read_header; + } + + /* Adjust for partial reads */ + bytes_read += rc; + } + /* Successfully received the complete message */ + } + } + +Resetting a Pipe +================ + +The pipe can be reset by calling :c:func:`k_pipe_reset`. Resetting a pipe +resets its internal state and ends all pending operations with an error code. + +The following example demonstrates resetting a pipe in response to a critical +error: .. code-block:: c @@ -207,31 +194,21 @@ data in the pipe. { while (1) { ... - /* Critical error detected. Flush the entire pipe to reset it. */ - k_pipe_flush(&my_pipe); + /* Critical error detected: reset the entire pipe to reset it. */ + k_pipe_reset(&my_pipe); ... } } - -Suggested uses +Suggested Uses ************** -Use a pipe to send streams of data between threads. - -.. note:: - A pipe can be used to transfer long streams of data if desired. However it - is often preferable to send pointers to large data items to avoid copying - the data. Copying large data items will negatively impact interrupt latency - as a spinlock is held while copying that data. - - -Configuration Options -********************* - -Related configuration options: +Pipes are useful for sending streams of data between threads. Typical +applications include: -* :kconfig:option:`CONFIG_PIPES` +- Implementing producer-consumer patterns. +- Streaming logs or packets between threads. +- Handling variable-length message passing in real-time systems. API Reference ************* diff --git a/doc/kernel/services/smp/smp.rst b/doc/kernel/services/smp/smp.rst index e570958fce23e..615676494f822 100644 --- a/doc/kernel/services/smp/smp.rst +++ b/doc/kernel/services/smp/smp.rst @@ -276,7 +276,7 @@ Per-CPU data ============ Many elements of the core kernel data need to be implemented for each -CPU in SMP mode. For example, the ``arch_current_thread()`` thread pointer obviously +CPU in SMP mode. For example, the ``_current`` thread pointer obviously needs to reflect what is running locally, there are many threads running concurrently. Likewise a kernel-provided interrupt stack needs to be created and assigned for each physical CPU, as does the diff --git a/doc/kernel/services/threads/priorities.svg b/doc/kernel/services/threads/priorities.svg index 2e9a85d4ad51b..00475e6e9826f 100644 --- a/doc/kernel/services/threads/priorities.svg +++ b/doc/kernel/services/threads/priorities.svg @@ -1,4 +1,4 @@ - + -
    0
    0
    - CONFIG_NUM_COOP_PRIORITIES
    - CONFIG_NUM_COOP_PRIORITIES
    cooperative threads
    cooperative threads
    preemptible threads
    preemptible threads
    CONFIG_NUM_PREEMPT_PRIORITIES - 1
    CONFIG_NUM_PREEMPT_PRIORITIES - 1
    -1
    -1
    Higher priority
    Higher priority
    Lower priority
    Lower priority
    1
    1
    2
    2
    - 2
    - 2
    Idle thread (cooperative)
    Idle thread (cooperative)
    Idle thread (preemptible)
    Idle thread (preemptible)
    Text is not SVG - cannot display
    \ No newline at end of file +
    0
    0
    - CONFIG_NUM_COOP_PRIORITIES
    - CONFIG_NUM_COOP_PRIORITIES
    cooperative threads
    cooperative threads
    preemptible threads
    preemptible threads
    CONFIG_NUM_PREEMPT_PRIORITIES - 1
    CONFIG_NUM_PREEMPT_PRIORITIES - 1
    -1
    -1
    Higher priority
    Higher priority
    Lower priority
    Lower priority
    1
    1
    - 2
    - 2
    Idle thread
    Idle thread
    Text is not SVG - cannot display
    \ No newline at end of file diff --git a/doc/kernel/services/threads/system_threads.rst b/doc/kernel/services/threads/system_threads.rst index 74da3c0a033c9..b46ab4d3c83ca 100644 --- a/doc/kernel/services/threads/system_threads.rst +++ b/doc/kernel/services/threads/system_threads.rst @@ -35,9 +35,6 @@ The kernel spawns the following system threads: and never terminates. The idle thread always uses the lowest configured thread priority. - If this makes it a cooperative thread, the idle thread repeatedly - yields the CPU to allow the application's other threads to run when - they need to. The idle thread is an essential thread, which means a fatal system error is raised if the thread aborts. diff --git a/doc/kernel/usermode/memory_domain.rst b/doc/kernel/usermode/memory_domain.rst index f830cc981b91b..9b9f31f64ed11 100644 --- a/doc/kernel/usermode/memory_domain.rst +++ b/doc/kernel/usermode/memory_domain.rst @@ -28,7 +28,8 @@ contain the following: have an MPU region configuring it. It is strongly recommended to use this to maximize the number of available MPU regions for the end user. On ARMv7-M/ARMv8-M this is called the System Address Map, other CPUs may - have similar capabilities. + have similar capabilities. See :ref:`mem_mgmt_api` for information on + how to annotate the system map in the device tree. - A read-only, executable region or regions for program text and ro-data, that is accessible to user mode. This could be further sub-divided into a diff --git a/doc/project/dev_env_and_tools.rst b/doc/project/dev_env_and_tools.rst index 2095192d4d579..9485d1520506a 100644 --- a/doc/project/dev_env_and_tools.rst +++ b/doc/project/dev_env_and_tools.rst @@ -65,55 +65,45 @@ Categories/Labels ----------------- Hotfix -++++++ + Any change that is a fix to an issue that blocks developers from doing their + daily work, for example CI breakage, Test breakage, Minor documentation fixes + that impact the user experience. -Any change that is a fix to an issue that blocks developers from doing their -daily work, for example CI breakage, Test breakage, Minor documentation fixes -that impact the user experience. - -Such fixes can be merged at any time after they have passed CI checks. Depending -on the fix, severity, and availability of someone to review them (other than the -author) they can be merged with justification without review by one of the -project owners. + Such fixes can be merged at any time after they have passed CI checks. Depending + on the fix, severity, and availability of someone to review them (other than the + author) they can be merged with justification without review by one of the + project owners. Trivial -+++++++ - -Trivial changes are those that appear obvious enough and do not require maintainer or code-owner -involvement. Such changes should not change the logic or the design of a -subsystem or component. For example a trivial change can be: + Trivial changes are those that appear obvious enough and do not require maintainer or code-owner + involvement. Such changes should not change the logic or the design of a + subsystem or component. For example a trivial change can be: -- Documentation changes -- Configuration changes -- Minor Build System tweaks -- Minor optimization to code logic without changing the logic -- Test changes and fixes -- Sample modifications to support additional configuration or boards etc. + - Documentation changes + - Configuration changes + - Minor Build System tweaks + - Minor optimization to code logic without changing the logic + - Test changes and fixes + - Sample modifications to support additional configuration or boards etc. Maintainer -+++++++++++ - -Any changes that touch the logic or the original design of a subsystem or -component will need to be reviewed by the code owner or the designated subsystem -maintainer. If the code changes is initiated by a contributor or developer other -than the owner the pull request needs to be assigned to the code owner who will -have to drive the pull request to a mergeable state by giving feedback to the -author and asking for more reviews from other developers. + Any changes that touch the logic or the original design of a subsystem or + component will need to be reviewed by the code owner or the designated subsystem + maintainer. If the code changes is initiated by a contributor or developer other + than the owner the pull request needs to be assigned to the code owner who will + have to drive the pull request to a mergeable state by giving feedback to the + author and asking for more reviews from other developers. Security -+++++++++++ - -Changes that appear to have an impact to the overall security of the system need -to be reviewed by a security expert from the security working group. + Changes that appear to have an impact to the overall security of the system need + to be reviewed by a security expert from the security working group. TSC and Working Groups -++++++++++++++++++++++ - -Changes that introduce new features or functionality or change the way the -overall system works need to be reviewed by the TSC or the responsible Working -Group. For example for :ref:`breaking API changes `, the -proposal needs to be presented in the Architecture meeting so that the relevant -stakeholders are made aware of the change. + Changes that introduce new features or functionality or change the way the + overall system works need to be reviewed by the TSC or the responsible Working + Group. For example for :ref:`breaking API changes `, the + proposal needs to be presented in the Architecture meeting so that the relevant + stakeholders are made aware of the change. A Pull-Request should have an Assignee ======================================= diff --git a/doc/project/index.rst b/doc/project/index.rst index dda70ca575f22..84ade4c32fa89 100644 --- a/doc/project/index.rst +++ b/doc/project/index.rst @@ -13,7 +13,6 @@ Project and Governance release_process proposals code_flow - modifying_contributions.rst dev_env_and_tools issues communication diff --git a/doc/project/project_roles.rst b/doc/project/project_roles.rst index 02760af95f0ab..bccf3bc2c4c7c 100644 --- a/doc/project/project_roles.rst +++ b/doc/project/project_roles.rst @@ -71,6 +71,16 @@ Contributor change requests or approval on pull requests are not counted with respect to accepting and merging a pull request. However, Contributors comments and requested changes should still be considered by the pull request author. +Zephyr Contributor Badge +++++++++++++++++++++++++ + +When your first contribution to the Zephyr project gets merged, you'll become eligible to claim your +Zephyr Contributor Badge. This digital badge can be displayed on your website, blog, social media +profile, etc. It will allow you to showcase your involvement in the Zephyr project and help raise +its awareness. + +You may apply for your Contributor Badge by filling out the `Zephyr Contributor Badge form`_. + .. _collaborator: Collaborator @@ -350,6 +360,7 @@ Release Activity Merge Criteria ++++++++++++++ +* All :ref:`pr_requirements` must be met. * Minimal of 2 approvals, including an approval by the designated assignee. * Pull requests should be reviewed by at least a maintainer or collaborator of each affected area; Unless the changes to a given area are considered trivial @@ -402,3 +413,6 @@ Merge Criteria * Coding Guidelines * Static Analysis (Coverity) * Documentation coverage (APIs) + + +.. _Zephyr Contributor Badge form: https://forms.gle/oCw9iAPLhUsHTapc8 diff --git a/doc/releases/eol_releases.rst b/doc/releases/eol_releases.rst index f16f74a87aa73..f539ca5e65622 100644 --- a/doc/releases/eol_releases.rst +++ b/doc/releases/eol_releases.rst @@ -19,7 +19,7 @@ Release Notes release-notes-1.? release-notes-1.* release-notes-2.[0-6] - release-notes-3.[0-5] + release-notes-3.[0-6] .. _eol_releases_migration_guides: diff --git a/doc/releases/index.rst b/doc/releases/index.rst index f5e143d02308c..e068ae493513c 100644 --- a/doc/releases/index.rst +++ b/doc/releases/index.rst @@ -58,12 +58,8 @@ Supported Releases +-----------------+----------------+---------------+ | Release | Release date | EOL | +=================+================+===============+ -| `Zephyr 2.7.6`_ | 2024-03-01 | 2025-01-26 | -+-----------------+----------------+---------------+ | `Zephyr 3.7.0`_ | 2024-07-26 | 2027-01-26 | +-----------------+----------------+---------------+ -| `Zephyr 3.6.0`_ | 2024-02-23 | 2024-11-29 | -+-----------------+----------------+---------------+ | `Zephyr 4.0.0`_ | 2024-11-15 | 2025-07-18 | +-----------------+----------------+---------------+ @@ -83,8 +79,7 @@ needs to be changed are to be detailed in the release's migration guide. :glob: :reversed: - release-notes-2.7 - release-notes-3.[6-7] + release-notes-3.7 release-notes-4.[0-1] Migration Guides @@ -133,7 +128,5 @@ Release notes and migration guides for end-of-life releases of Zephyr RTOS can b .. _`GitHub repository`: https://github.com/zephyrproject-rtos/zephyr .. _`GitHub tagged releases`: https://github.com/zephyrproject-rtos/zephyr/tags -.. _`Zephyr 2.7.6`: https://docs.zephyrproject.org/2.7.6/ -.. _`Zephyr 3.6.0`: https://docs.zephyrproject.org/3.6.0/ .. _`Zephyr 3.7.0`: https://docs.zephyrproject.org/3.7.0/ .. _`Zephyr 4.0.0`: https://docs.zephyrproject.org/4.0.0/ diff --git a/doc/releases/migration-guide-4.1.rst b/doc/releases/migration-guide-4.1.rst index 61f3d0f34c52e..836d20d79b579 100644 --- a/doc/releases/migration-guide-4.1.rst +++ b/doc/releases/migration-guide-4.1.rst @@ -1,5 +1,10 @@ :orphan: +.. + See + https://docs.zephyrproject.org/latest/releases/index.html#migration-guides + for details of what is supposed to go into this document. + .. _migration_4.1: Migration guide to Zephyr v4.1.0 (Working Draft) @@ -18,12 +23,84 @@ the :ref:`release notes`. Build System ************ +* Support for the build type feature which was deprecated in Zephyr 3.6 has been removed, + :ref:`application-file-suffixes`/:ref:`sysbuild_file_suffixes` has replaced this. + +* Sysbuild + + * The Kconfig ``SB_CONFIG_MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH`` has been deprecated and replaced + with ``SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE``, applications should be updated to select this + new symbol if they were selecting the old symbol. + +BOSSA Runner +============ + +The ``bossac`` runner has been changed to no longer do a full erase by default when flashing. To +perform a full erase, pass the ``--erase`` option when executing ``west flash``. + Kernel ****** +Security +******** + +* New options for stack canaries have been added, providing users with finer control over stack + protection. With this change, :kconfig:option:`CONFIG_STACK_CANARIES` no longer enables the + compiler option ``-fstack-protector-all``. Users who wish to use this option must now enable + :kconfig:option:`CONFIG_STACK_CANARIES_ALL`. + Boards ****** +* Shield ``mikroe_weather_click`` now supports both I2C and SPI interfaces. Users should select + the required configuration by using ``mikroe_weather_click_i2c`` or ``mikroe_weather_click_spi`` + instead of ``mikroe_weather_click``. + +* All nRF52-based boards will now default to soft (system) reset + instead of pin reset when flashing with ``west flash``. If you want to keep + using pin reset on the nRF52 family of ICs you can use ``west flash --pinreset``. + +* Erasing the external memory when programming a new firmware image with ``west + flash`` on the nRF52 and nRF53 series now always correctly honors the + ``--erase`` flag (and its absence) both when using the ``nrfjprog`` and + ``nrfutil`` backends. Prior to this release, the ``nrjfprog`` backend would + always erase only the sectors of the external flash used by the new firmware, + and the ``nrfutil`` one would always erase the whole external flash. + +* CAN1 and USART1 have been disabled on the ``stm32f4_disco``, because of + conflicting pinctrl on I2C1, which is now used to control the audio codec + connected to the audio jack output. + +Devicetree +********** + +* The :dtcompatible:`microchip,cap1203` driver has changed its compatible to + :dtcompatible:`microchip,cap12xx` and has been updated to support multiple + channels. + The number of available channels is derived from the length of the devicetree + array property ``input-codes``. + The :kconfig:option:`CONFIG_INPUT_CAP1203_POLL` has been removed: + If the devicetree property ``int-gpios`` is present, interrupt mode is used + otherwise, polling is used. + The :kconfig:option:`CONFIG_INPUT_CAP1203_PERIOD` has been replaced with + the devicetree property ``poll-interval-ms``. + In interrupt mode, the devicetree property ``repeat`` is supported. + +Raspberry Pi +============ + +* ``CONFIG_SOC_SERIES_RP2XXX`` is renamed to :kconfig:option:`CONFIG_SOC_SERIES_RP2040`. + +STM32 +===== + +* MCO clock source and prescaler are now exclusively configured by the DTS + as it was introduced earlier. + The Kconfig method for configuration is now removed. + +* ADC properties ``st,adc-sequencer`` and ``st,adc-clock-source`` now uses + string values instead of integer values. + Modules ******* @@ -54,24 +131,42 @@ LVGL :kconfig:option:`CONFIG_LV_Z_FLUSH_THREAD_PRIORITY` and its value is now interpreted as an absolute priority instead of a cooperative one. +* The config option :kconfig:option:`CONFIG_LV_Z_VBD_CUSTOM_SECTION` is now called + :kconfig:option:`CONFIG_LV_Z_VDB_CUSTOM_SECTION`. + Device Drivers and Devicetree ***************************** -* Device driver APIs are placed into iterable sections (:github:`71773`) to allow for runtime - checking. See :ref:`device_driver_api` for more details. +* Device driver APIs are placed into iterable sections (:github:`71773` and :github:`82102`) to + allow for runtime checking. See :ref:`device_driver_api` for more details. The :c:macro:`DEVICE_API()` macro should be used by out-of-tree driver implementations for - the following driver classes: - - * :c:struct:`adc_driver_api` + all the upstream driver classes. ADC === * Renamed the ``compatible`` from ``nxp,kinetis-adc12`` to :dtcompatible:`nxp,adc12`. +Clock +===== +* Renamed the devicetree property ``freqs_mhz`` to ``freqs-mhz``. +* Renamed the devicetree property ``cg_reg`` to ``cg-reg``. +* Renamed the devicetree property ``pll_ctrl_reg`` to ``pll-ctrl-reg``. + +Counter +======= + +* Renamed the devicetree property ``primary_source`` to ``primary-source``. +* Renamed the devicetree property ``secondary_source`` to ``secondary-source``. +* Renamed the devicetree property ``filter_count`` to ``filter-count``. +* Renamed the devicetree property ``filter_period`` to ``filter-period``. + Controller Area Network (CAN) ============================= +* Renamed the :dtcompatible:`infineon,xmc4xxx-can-node` devicetree property ``clock_div8`` to + ``clock-div8`` (:github:`83782`). + Display ======= @@ -97,6 +192,14 @@ Display ... }; +* Renamed the devicetree propertys ``pclk_pol`` and ``data_cmd-gpios`` + to ``pclk-pol`` and ``data-cmd-gpios``. + +DAC +=== + +* Renamed the devicetree properties ``voltage_reference`` and ``power_down_mode`` + to ``voltage-reference`` and ``power-down-mode``. Enhanced Serial Peripheral Interface (eSPI) =========================================== @@ -110,23 +213,97 @@ Entropy processor needs to get random data before BT is fully enabled. (:github:`79931`) +Ethernet +======== + +* Silabs gecko ethernet changes: + + * Renamed the devicetree property ``location-phy_mdc`` to ``location-phy-mdc``. + * Renamed the devicetree property ``location-phy_mdio`` to ``location-phy-mdio``. + * Renamed the devicetree property ``location-rmii_refclk`` to ``location-phy-refclk``. + * Renamed the devicetree property ``location-rmii_crs_dv`` to ``location-phy-crs-dv``. + * Renamed the devicetree property ``location-rmii_txd0`` to ``location-phy-txd0``. + * Renamed the devicetree property ``location-rmii_txd1`` to ``location-phy-txd1``. + * Renamed the devicetree property ``location-rmii_tx_en`` to ``location-phy-tx-en``. + * Renamed the devicetree property ``location-rmii_rxd0`` to ``location-phy-rxd0``. + * Renamed the devicetree property ``location-rmii_rxd1`` to ``location-phy-rxd1``. + * Renamed the devicetree property ``location-rmii_rx_er`` to ``location-phy-rx-er``. + * Renamed the devicetree property ``location-phy_pwr_enable`` to ``location-phy-pwr-enable``. + * Renamed the devicetree property ``location-phy_reset`` to ``location-phy-reset``. + * Renamed the devicetree property ``location-phy_interrupt`` to ``location-phy-interrupt``. + GNSS ==== +GPIO +==== + +* Renamed the device tree property ``pin_mask`` to ``pin-mask``. +* Renamed the device tree property ``pinmux_mask`` to ``pinmux-mask``. +* Renamed the device tree property ``vbatts_pins`` to ``vbatts-pins``. +* Renamed the device tree property ``bit_per_gpio`` to ``bit-per-gpio``. +* Renamed the device tree property ``off_val`` to ``off-val``. +* Renamed the device tree property ``on_val`` to ``on-val``. +* Renamed the ``compatible`` from ``ti,ads114s0x-gpio`` to :dtcompatible:`ti,ads1x4s0x-gpio`. + +HWSPINLOCK +========== + +* Renamed the DeviceTree property ``num_locks`` to ``num-locks``. + I2C === * Renamed the ``compatible`` from ``nxp,imx-lpi2c`` to :dtcompatible:`nxp,lpi2c`. +* Renamed the device tree property ``port_sel`` to ``port-sel```. + +I2S +=== + +* Renamed the device tree property from ``fifo_depth`` to ``fifo-depth``. Input ===== +LED +=== + +* Renamed the device tree property ``max_curr_opt`` to ``max-curr-opt``.` + +PWM +=== + +* Renamed the ``compatible`` from ``renesas,ra8-pwm`` to :dtcompatible:`renesas,ra-pwm`. + Interrupt Controller ==================== LED Strip ========= +Misc +==== + +* All the functions in the ft8xx driver take an additional ``const struct *device`` parameter + to allow for multiple instances of the driver. + + The exception to this is the functions and macros defined in the + :zephyr_file:`include/zephyr/drivers/misc/ft8xx/ft8xx_reference_api.h` file, which translate the + API to a single-instance model, compatible with the API defined in the FT8xx programming guide. + These functions have not been modified. + +* The :c:func:`ft8xx_register_int` function now takes an additional ``void *user_data`` parameter + to allow user-defined data to be passed to the interrupt handler. + Additionally, the signature of the ft8xx interrupt handler has changed to include the + ``void *user_data`` parameter. + +MMU/MPU +======= + +* Renamed the ``compatible`` from ``nxp,kinetis-mpu`` to :dtcompatible:`nxp,sysmpu` and added + its corresponding binding. +* Renamed the Kconfig option ``CPU_HAS_NXP_MPU`` to :kconfig:option:`CPU_HAS_NXP_SYSMPU`. + Pin Control =========== @@ -157,27 +334,141 @@ Pin Control }; +PWM +=== + +* Renamed the ``compatible`` from ``nxp,kinetis-ftm-pwm`` to :dtcompatible:`nxp,ftm-pwm`. + +SDHC +==== + +* Renamed the device tree property from ``power_delay_ms`` to ``power-delay-ms``` +* Renamed the device tree property from ``max_current_330`` to ``max-current-330`` + Sensors ======= + * The :dtcompatible:`we,wsen-pads` driver has been renamed to + :dtcompatible:`we,wsen-pads-2511020213301`. + The Device Tree can be configured as follows: + + .. code-block:: devicetree + + &i2c0 { + pads:pads-2511020213301@5d { + compatible = "we,wsen-pads-2511020213301"; + reg = <0x5d>; + odr = < 10 >; + interrupt-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + }; + }; + + * The :dtcompatible:`we,wsen-pdus` driver has been renamed to + :dtcompatible:`we,wsen-pdus-25131308XXXXX`. + The Device Tree can be configured as follows: + + .. code-block:: devicetree + + &i2c0 { + pdus:pdus-25131308XXXXX@78 { + compatible = "we,wsen-pdus-25131308XXXXX"; + reg = < 0x78 >; + sensor-type = < 4 >; + }; + }; + + * The :dtcompatible:`we,wsen-tids` driver has been renamed to + :dtcompatible:`we,wsen-tids-2521020222501`. + The Device Tree can be configured as follows: + + .. code-block:: devicetree + + &i2c0 { + tids:tids-2521020222501@3F { + compatible = "we,wsen-tids-2521020222501"; + reg = < 0x3F >; + odr = < 25 >; + interrupt-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + }; + }; + + * The :dtcompatible:`invensense,icp10125` driver has been renamed to + :dtcompatible:`invensense,icp101xx`. + The Device Tree can be configured as follows: + + .. code-block:: devicetree + + &i2c0 { + icp101xx:icp101xx@63 { + compatible = "invensense,icp101xx"; + reg = <0x63>; + }; + }; + Serial ====== +* Renamed the ``compatible`` from ``nxp,kinetis-lpuart`` to :dtcompatible:`nxp,lpuart`. +* Silabs Usart driver has been split for Series 2 :dtcompatible:`silabs,usart-uart` + and Series 0/1 ``silabs,gecko-usart`` + Stepper ======= * Renamed the ``compatible`` from ``zephyr,gpio-steppers`` to :dtcompatible:`zephyr,gpio-stepper`. * Renamed the ``stepper_set_actual_position`` function to :c:func:`stepper_set_reference_position`. * Renamed the ``stepper_enable_constant_velocity_mode`` function to :c:func:`stepper_run`. + The function does not take a velocity parameter anymore. Set the desired speed using the + :c:func:`stepper_set_microstep_interval` function beforehand. + * Renamed the ``stepper_move`` function to :c:func:`stepper_move_by`. + * Renamed the ``stepper_set_target_position`` function to :c:func:`stepper_move_to`. + * Renamed the ``stepper_set_max_velocity`` function to :c:func:`stepper_set_microstep_interval`. + The function now takes the step interval in nanoseconds. This allows for a more precise control. + * Deprecating setting max velocity via :c:func:`stepper_run`. + * The :kconfig:option:`STEPPER_ADI_TMC_RAMP_GEN` is now deprecated and is replaced with the new + :kconfig:option:`STEPPER_ADI_TMC50XX_RAMP_GEN` option. + * Renamed tmc5041 stepper driver to tmc50xx. + * To control the velocity for :dtcompatible:`adi,tmc50xx` stepper driver, use + :c:func:`tmc50xx_stepper_set_max_velocity` or :c:func:`tmc50xx_stepper_set_ramp`. + * Renamed the DeviceTree property ``en_spreadcycle`` to ``en-spreadcycle``. + * Renamed the DeviceTree property ``i_scale_analog`` to ``i-scale-analog``. + * Renamed the DeviceTree property ``index_optw`` to ``index-otpw``. + * Renamed the DeviceTree property ``ĂŹndex_step`` to ``index-step``. + * Renamed the DeviceTree property ``internal_rsense`` to ``internal-rsense``. + * Renamed the DeviceTree property ``lock_gconf`` to ``lock-gconf``. + * Renamed the DeviceTree property ``mstep_reg_select`` to ``mstep-reg-select``. + * Renamed the DeviceTree property ``pdn_disable`` to ``pdn-disable``. + * Renamed the DeviceTree property ``poscmp_enable`` to ``poscmp-enable``. + * Renamed the DeviceTree property ``test_mode`` to ``test-mode``. SPI === * Renamed the ``compatible`` from ``nxp,imx-lpspi`` to :dtcompatible:`nxp,lpspi`. +* Renamed the ``compatible`` from ``nxp,kinetis-dspi`` to :dtcompatible:`nxp,dspi`. +* Renamed the ``compatible`` from ``silabs,gecko-spi-usart`` to :dtcompatible:`silabs,usart-spi`. +* Renamed the ``compatible`` from ``silabs,gecko-spi-eusart`` to :dtcompatible:`silabs,eusart-spi`. Regulator ========= +RTC +=== + +* Renamed the ``compatible`` from ``nxp,kinetis-rtc`` to :dtcompatible:`nxp,rtc`. + +Timer +===== + +* Renamed the ``compatible`` from ``nxp,kinetis-ftm`` to :dtcompatible:`nxp,ftm` and relocate it + under ``dts/bindings/timer``. +* Renamed the device tree property from ``ticks_us`` to ``ticks-us``. + +USB +=== + +* Renamed the devicetree property names ``phy_handle`` to ``phy-handle``. + Video ===== @@ -188,11 +479,31 @@ Video The new ``video-controls.h`` source now contains description of each control ID to help disambiguating. +* The ``video_pix_fmt_bpp()`` function was returning a byte count, this got replaced by + ``video_bits_per_pixel()`` which return a bit count. For instance, invocations such as + ``pitch = width * video_pix_fmt_bpp(pixfmt)`` needs to be replaced by an equivalent + ``pitch = width * video_bits_per_pixel(pixfmt) / BITS_PER_BYTE``. + +* The :c:func:`video_buffer_alloc` and :c:func:`video_buffer_aligned_alloc` functions in the + video API now take an additional timeout parameter. + +* The :c:func:`video_stream_start` and :c:func:`video_stream_stop` driver APIs are now merged + into the new :c:func:`video_set_stream` driver API. The user APIs are however unchanged to + keep backward compatibility with downstream applications. + Watchdog ======== +Wi-Fi +===== + * Renamed the ``compatible`` from ``nxp,kinetis-wdog32`` to :dtcompatible:`nxp,wdog32`. +* The config options :kconfig:option:`CONFIG_NXP_WIFI_BUILD_ONLY_MODE` and + :kconfig:option:`CONFIG_NRF_WIFI_BUILD_ONLY_MODE` are now unified under + :kconfig:option:`CONFIG_BUILD_ONLY_NO_BLOBS` making it a common entry point + for any vendor to enable builds without blobs. + Bluetooth ********* @@ -213,6 +524,21 @@ Bluetooth Mesh set as deprecated. Default option for platforms that do not support TF-M is :kconfig:option:`CONFIG_BT_MESH_USES_MBEDTLS_PSA`. +* Mesh key representations are not backward compatible if images are built with TinyCrypt and + crypto libraries based on the PSA API. Mesh no longer stores the key values for those crypto + libraries. The crypto library stores the keys in the internal trusted storage. + If a provisioned device is going to update its image that was built with + the :kconfig:option:`CONFIG_BT_MESH_USES_TINYCRYPT` Kconfig option set on an image + that was built with :kconfig:option:`CONFIG_BT_MESH_USES_MBEDTLS_PSA` or + :kconfig:option:`CONFIG_BT_MESH_USES_TFM_PSA` without erasing the persistent area, + it should be unprovisioned first and reprovisioned after update again. + If the image is changed over Mesh DFU, use :c:enumerator:`BT_MESH_DFU_EFFECT_UNPROV`. + +* Mesh explicitly depends on the Secure Storage subsystem if storing into + non-volatile memory (:kconfig:option:`CONFIG_BT_SETTINGS`) is enabled and + Mbed TLS library (:kconfig:option:`CONFIG_BT_MESH_USES_MBEDTLS_PSA`) is used. + Applications should be built with :kconfig:option:`CONFIG_SECURE_STORAGE` enabled. + Bluetooth Audio =============== @@ -229,6 +555,16 @@ Bluetooth Audio * :kconfig:option:`CONFIG_BT_PAC_SNK` * :kconfig:option:`CONFIG_BT_PAC_SRC` +* PACS have been changed to support dynamic, runtime configuration. This means that PACS now has + to be registered with :c:func:`bt_pacs_register` before it can be used. In addition, + :c:func:`bt_pacs_register` also have to be called before :c:func:`bt_ascs_register` can be + be called. All Kconfig options still remain. Runtime configuration cannot override a disabled + Kconfig option. (:github:`83730`) + +* Several services and service client (AICS, ASCS, CSIP, HAS, MCS, PACS, TBS, VCP and VOCS) now + depend on :kconfig:option:`CONFIG_BT_SMP` and may need to be explicitly enabled. + (:github:`84994``) + Bluetooth Classic ================= @@ -252,9 +588,22 @@ Bluetooth Host makes a device vulnerable for downgrade attacks. If an application still needs to use LE legacy pairing, it should disable :kconfig:option:`CONFIG_BT_SMP_SC_PAIR_ONLY` manually. +* The prompt for :kconfig:option:`CONFIG_BT_ECC` has been removed, since it only offers an internal + API, meaning internal users should explicitly select it in their respective Kconfig options. + Bluetooth Crypto ================ +Bluetooth Services +================== + +* The :kconfig:option:`CONFIG_BT_DIS_MODEL` and :kconfig:option:`CONFIG_BT_DIS_MANUF` have been + deprecated. Application developers should now use the + :kconfig:option:`CONFIG_BT_DIS_MODEL_NUMBER_STR` and + :kconfig:option:`CONFIG_BT_DIS_MANUF_NAME_STR` Kconfig options to set the string values in the + Model Number String and Manufacturer Name String characteristics that are part of the Device + Information Service (DIS). + Networking ********** @@ -275,27 +624,69 @@ Networking rather than directly in the :c:struct:`http_client_ctx` to correctly handle concurrent requests on different HTTP/2 streams. +* The HTTP server public API function signature for the :c:type:`http_resource_websocket_cb_t` has + changed, a :c:struct:`http_request_ctx` parameter has been added. The application may use this to + access the request headers of the HTTP upgrade request, which may be useful in deciding whether + to accept or reject a websocket connection. + +* An additional ``_res_fallback`` parameter has been added to the :c:macro:`HTTP_SERVICE_DEFINE` + and :c:macro:`HTTPS_SERVICE_DEFINE` macros, allowing a fallback resource to be served if no other + resources match the requested path. To retain the existing behaviour, ``NULL`` can be passed as the + additional parameter. + +* The :kconfig:option:`CONFIG_NET_L2_OPENTHREAD` symbol no longer implies the + :kconfig:option:`CONFIG_NVS` Kconfig option. Platforms using OpenThread must explicitly enable + either the :kconfig:option:`CONFIG_NVS` or :kconfig:option:`CONFIG_ZMS` Kconfig option. + +* ``CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO`` was deprecated in favour of + :kconfig:option:`CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO` to avoid naming ambiguity. + Other Subsystems **************** Flash map ========= +Filesystem +========== + +* The EXT2 Kconfig symbol ``CONFIG_MAX_FILES`` has been renamed to + :kconfig:option:`CONFIG_EXT2_MAX_FILES`. + hawkBit ======= +* The Kconfig symbols :kconfig:option:`CONFIG_SMF` and + :kconfig:option:`CONFIG_SMF_ANCESTOR_SUPPORT` are now required to be enabled to use the + hawkBit subsystem. + MCUmgr ====== +* The Kconfig :kconfig:option:`CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH` has been + deprecated and replaced with :kconfig:option:`CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_USING_MOVE`, + applications should be updated to select this new symbol if they were selecting the old symbol. + Modem ===== -Architectures -************* +LoRa +==== + +* The function :c:func:`lora_recv_async` and callback ``lora_recv_cb`` now include an + additional ``user_data`` parameter, which is a void pointer. This parameter can be used to reference + any user-defined data structure. To maintain the current behavior, set this parameter to ``NULL``. -* Common +Stream Flash +============ - * ``_current`` is deprecated, used :c:func:`arch_current_thread` instead. +* The function :c:func:`stream_flash_init` no longer does auto-detection of device size + when ``size`` parameter is set to 0 and will return error in such case. User is now + required to explicitly provide device size. Issue :github:`71042` provides rationale + for the change. + +Architectures +************* * native/POSIX diff --git a/doc/releases/migration-guide-4.2.rst b/doc/releases/migration-guide-4.2.rst new file mode 100644 index 0000000000000..70cf72e0b037e --- /dev/null +++ b/doc/releases/migration-guide-4.2.rst @@ -0,0 +1,48 @@ +:orphan: + +.. + See + https://docs.zephyrproject.org/latest/releases/index.html#migration-guides + for details of what is supposed to go into this document. + +.. _migration_4.2: + +Migration guide to Zephyr v4.2.0 (Working Draft) +################################################ + +This document describes the changes required when migrating your application from Zephyr v4.1.0 to +Zephyr v4.2.0. + +Any other changes (not directly related to migrating applications) can be found in +the :ref:`release notes`. + +.. contents:: + :local: + :depth: 2 + +Build System +************ + +Kernel +****** + +Boards +****** + +Device Drivers and Devicetree +***************************** + +Bluetooth +********* + +Networking +********** + +Other subsystems +**************** + +Modules +******* + +Architectures +************* diff --git a/doc/releases/release-notes-3.3.rst b/doc/releases/release-notes-3.3.rst index 9867ff7cdeae1..c752ff01cbd8b 100644 --- a/doc/releases/release-notes-3.3.rst +++ b/doc/releases/release-notes-3.3.rst @@ -186,7 +186,7 @@ Removed APIs in this release Deprecated in this release ========================== -* :ref:`xtools toolchain variant ` is now deprecated. When using a +* ``xtools`` toolchain variant is now deprecated. When using a custom toolchain built with Crosstool-NG, the :ref:`cross-compile toolchain variant ` should be used instead. diff --git a/doc/releases/release-notes-3.7.rst b/doc/releases/release-notes-3.7.rst index 30749ad038076..b32219c2ff789 100644 --- a/doc/releases/release-notes-3.7.rst +++ b/doc/releases/release-notes-3.7.rst @@ -413,7 +413,7 @@ Boards & SoC Support * Added support for :zephyr:board:`Seeed Studio XIAO RP2040 board `: ``xiao_rp2040``. * Added support for :zephyr:board:`Mikroe RA4M1 Clicker board `: ``mikroe_clicker_ra4m1``. * Added support for :ref:`Arduino UNO R4 WiFi board `: ``arduino_uno_r4_wifi``. - * Added support for :ref:`Renesas EK-RA8M1 board `: ``ek_ra8m1``. + * Added support for :zephyr:board:`Renesas EK-RA8M1 board `: ``ek_ra8m1``. * Added support for :zephyr:board:`ST Nucleo H533RE `: ``nucleo_h533re``. * Added support for :zephyr:board:`ST STM32C0116-DK Discovery Kit `: ``stm32c0116_dk``. * Added support for :zephyr:board:`ST STM32H745I Discovery `: ``stm32h745i_disco``. diff --git a/doc/releases/release-notes-4.0.rst b/doc/releases/release-notes-4.0.rst index 8b9ede8f11eba..4dcf628ea722e 100644 --- a/doc/releases/release-notes-4.0.rst +++ b/doc/releases/release-notes-4.0.rst @@ -303,21 +303,21 @@ Boards & SoC Support * :zephyr:board:`NXP i.MX95 EVK ` (``imx95_evk``) * :zephyr:board:`NXP MIMXRT1180-EVK ` (``mimxrt1180_evk``) * :ref:`PHYTEC phyBOARD-Nash i.MX93 ` (``phyboard_nash``) - * :ref:`Renesas RA2A1 Evaluation Kit ` (``ek_ra2a1``) - * :ref:`Renesas RA4E2 Evaluation Kit ` (``ek_ra4e2``) - * :ref:`Renesas RA4M2 Evaluation Kit ` (``ek_ra4m2``) - * :ref:`Renesas RA4M3 Evaluation Kit ` (``ek_ra4m3``) - * :ref:`Renesas RA4W1 Evaluation Kit ` (``ek_ra4w1``) - * :ref:`Renesas RA6E2 Evaluation Kit ` (``ek_ra6e2``) - * :ref:`Renesas RA6M1 Evaluation Kit ` (``ek_ra6m1``) - * :ref:`Renesas RA6M2 Evaluation Kit ` (``ek_ra6m2``) - * :ref:`Renesas RA6M3 Evaluation Kit ` (``ek_ra6m3``) - * :ref:`Renesas RA6M4 Evaluation Kit ` (``ek_ra6m4``) - * :ref:`Renesas RA6M5 Evaluation Kit ` (``ek_ra6m5``) - * :ref:`Renesas RA8D1 Evaluation Kit ` (``ek_ra8d1``) - * :ref:`Renesas RA6E1 Fast Prototyping Board ` (``fpb_ra6e1``) - * :ref:`Renesas RA6E2 Fast Prototyping Board ` (``fpb_ra6e2``) - * :ref:`Renesas RA8T1 Evaluation Kit ` (``mck_ra8t1``) + * :zephyr:board:`Renesas RA2A1 Evaluation Kit ` (``ek_ra2a1``) + * :zephyr:board:`Renesas RA4E2 Evaluation Kit ` (``ek_ra4e2``) + * :zephyr:board:`Renesas RA4M2 Evaluation Kit ` (``ek_ra4m2``) + * :zephyr:board:`Renesas RA4M3 Evaluation Kit ` (``ek_ra4m3``) + * :zephyr:board:`Renesas RA4W1 Evaluation Kit ` (``ek_ra4w1``) + * :zephyr:board:`Renesas RA6E2 Evaluation Kit ` (``ek_ra6e2``) + * :zephyr:board:`Renesas RA6M1 Evaluation Kit ` (``ek_ra6m1``) + * :zephyr:board:`Renesas RA6M2 Evaluation Kit ` (``ek_ra6m2``) + * :zephyr:board:`Renesas RA6M3 Evaluation Kit ` (``ek_ra6m3``) + * :zephyr:board:`Renesas RA6M4 Evaluation Kit ` (``ek_ra6m4``) + * :zephyr:board:`Renesas RA6M5 Evaluation Kit ` (``ek_ra6m5``) + * :zephyr:board:`Renesas RA8D1 Evaluation Kit ` (``ek_ra8d1``) + * :zephyr:board:`Renesas RA6E1 Fast Prototyping Board ` (``fpb_ra6e1``) + * :zephyr:board:`Renesas RA6E2 Fast Prototyping Board ` (``fpb_ra6e2``) + * :zephyr:board:`Renesas RA8T1 Motor Control Kit ` (``mck_ra8t1``) * :zephyr:board:`Renode Cortex-R8 Virtual ` (``cortex_r8_virtual``) * :zephyr:board:`Seeed XIAO ESP32-S3 Sense Variant `: ``xiao_esp32s3``. * :ref:`sensry.io Ganymed Break-Out-Board (BOB) ` (``ganymed_bob``) diff --git a/doc/releases/release-notes-4.1.rst b/doc/releases/release-notes-4.1.rst index 9b0810b0a1a07..08c121a09e15a 100644 --- a/doc/releases/release-notes-4.1.rst +++ b/doc/releases/release-notes-4.1.rst @@ -1,5 +1,29 @@ :orphan: +.. + What goes here: removed/deprecated apis, new boards, new drivers, notable + features. If you feel like something new can be useful to a user, put it + under "Other Enhancements" in the first paragraph, if you feel like something + is worth mentioning in the project media (release blog post, release + livestream) put it under "Major enhancement". +.. + If you are describing a feature or functionality, consider adding it to the + actual project documentation rather than the release notes, so that the + information does not get lost in time. +.. + No list of bugfixes, minor changes, those are already in the git log, this is + not a changelog. +.. + Does the entry have a link that contains the details? Just add the link, if + you think it needs more details, put them in the content that shows up on the + link. +.. + Are you thinking about generating this? Don't put anything at all. +.. + Does the thing require the user to change their application? Put it on the + migration guide instead. (TODO: move the removed APIs section in the + migration guide) + .. _zephyr_4.1: Zephyr 4.1.0 (Working Draft) @@ -24,357 +48,767 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html API Changes *********** -Removed APIs in this release -============================ +Removed APIs and options +======================== + +* The legacy Bluetooth HCI driver API has been removed. It has been replaced + by a :c:group:`new API` that follows the normal Zephyr driver + model. + +* The ``CAN_MAX_STD_ID`` (replaced by :c:macro:`CAN_STD_ID_MASK`) and + ``CAN_MAX_EXT_ID`` (replaced by :c:macro:`CAN_EXT_ID_MASK`) CAN API macros + have been removed. + +* The ``can_get_min_bitrate()`` (replaced by :c:func:`can_get_bitrate_min`) + and ``can_get_max_bitrate()`` (replaced by :c:func:`can_get_bitrate_max`) + CAN API functions have been removed. + +* The ``can_calc_prescaler()`` CAN API function has been removed. + +* The :kconfig:option:`CONFIG_NET_SOCKETS_POSIX_NAMES` option has been + removed. It was a legacy option and was used to allow user to call BSD + socket API while not enabling POSIX API. This removal means that in order + to use POSIX API socket calls, one needs to enable the + :kconfig:option:`CONFIG_POSIX_API` option. If the application does not want + or is not able to enable that option, then the socket API calls need to be + prefixed by a ``zsock_`` string. + +* Removed ``video_pix_fmt_bpp()`` function that was returning a *byte* count + and only supported 8-bit depth to :c:func:`video_bits_per_pixel()` returning + the *bit* count and supporting any color depth. + +* The ``video_stream_start()`` and ``video_stream_stop()`` driver APIs have been + replaced by ``video_set_stream()``. - * The deprecated Bluetooth HCI driver API has been removed. It has been replaced by a - :c:group:`new API` that follows the normal Zephyr driver model. - * The deprecated ``CAN_MAX_STD_ID`` (replaced by :c:macro:`CAN_STD_ID_MASK`) and ``CAN_MAX_EXT_ID`` - (replaced by :c:macro:`CAN_EXT_ID_MASK`) CAN API macros have been removed. - * The deprecated ``can_get_min_bitrate()`` (replaced by :c:func:`can_get_bitrate_min`) and - ``can_get_max_bitrate()`` (replaced by :c:func:`can_get_bitrate_max`) CAN API functions have been - removed. - * The deprecated ``can_calc_prescaler()`` CAN API function has been removed. +* :kconfig:option:`CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO` -Deprecated in this release -========================== +* The :kconfig:option:`CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE` option has been removed + after being deprecated in favor of :kconfig:option:`CONFIG_PM_DEVICE_SYSTEM_MANAGED`. -* Deprecated the :c:func:`bt_le_set_auto_conn` API function. Application developers can achieve +* The ``z_pm_save_idle_exit()`` PM API function has been removed. + + +Deprecated APIs and options +=========================== + +* the :c:func:`bt_le_set_auto_conn` API function. Application developers can achieve the same functionality in their application code by reconnecting to the peer when the :c:member:`bt_conn_cb.disconnected` callback is invoked. -Architectures -************* +* :kconfig:option:`CONFIG_NATIVE_APPLICATION` has been deprecated. -* Common +* Deprecated the :c:func:`stream_flash_erase_page` from Stream Flash API. The same functionality + can be achieved using :c:func:`flash_area_erase` or :c:func:`flash_erase`. Nevertheless + erasing of a device, while stream flash is supposed to do so, as configured, will result in + data lost from stream flash. There are only two situations where device should be erased + directly: - * Introduced :kconfig:option:`CONFIG_ARCH_HAS_CUSTOM_CURRENT_IMPL`, which can be selected when - an architecture implemented and enabled its own :c:func:`arch_current_thread` and - :c:func:`arch_current_thread_set` functions for faster retrieval of the current CPU's thread - pointer. When enabled, ``_current`` variable will be routed to the - :c:func:`arch_current_thread` (:github:`80716`). + 1. when Stream Flash is not configured to do erase on its own + 2. when erase is used for removal of a data prior or after Stream Flash uses the designated area. -* ARC +* For the native_sim target :kconfig:option:`CONFIG_NATIVE_SIM_NATIVE_POSIX_COMPAT` has been + switched to ``n`` by default, and this option has been deprecated. -* ARM +* :kconfig:option:`CONFIG_BT_BUF_ACL_RX_COUNT` -* ARM64 +* All HWMv1 board name aliases which were added as deprecated in v3.7 are now removed + (:github:`82247`). -* RISC-V +* The TinyCrypt library has been deprecated as the upstream version is no longer maintained. + PSA Crypto API is now the recommended cryptographic library for Zephyr. - * Implements :c:func:`arch_current_thread_set` & :c:func:`arch_current_thread`, which can be enabled - by :kconfig:option:`CONFIG_RISCV_CURRENT_VIA_GP` (:github:`80716`). +* The :kconfig:option:`CONFIG_BT_DIS_MODEL` and :kconfig:option:`CONFIG_BT_DIS_MANUF` have been + deprecated. Application developers can achieve the same configuration by using the new + :kconfig:option:`CONFIG_BT_DIS_MODEL_NUMBER_STR` and + :kconfig:option:`CONFIG_BT_DIS_MANUF_NAME_STR` Kconfig options. -* Xtensa +New APIs and options +==================== -* native/POSIX +.. + Link to new APIs here, in a group if you think it's necessary, no need to get + fancy just list the link, that should contain the documentation. If you feel + like you need to add more details, add them in the API documentation code + instead. - * :kconfig:option:`CONFIG_NATIVE_APPLICATION` has been deprecated. - * For the native_sim target :kconfig:option:`CONFIG_NATIVE_SIM_NATIVE_POSIX_COMPAT` has been - switched to ``n`` by default, and this option has been deprecated. +* Architectures -Kernel -****** + * :kconfig:option:`CONFIG_ARCH_HAS_CUSTOM_CURRENT_IMPL` + * :kconfig:option:`CONFIG_RISCV_CURRENT_VIA_GP` -Bluetooth -********* +* Bluetooth -* Audio + * Audio -* Host + * :c:func:`bt_bap_broadcast_source_register_cb` + * :c:func:`bt_bap_broadcast_source_unregister_cb` + * :c:func:`bt_cap_commander_distribute_broadcast_code` + * ``bt_ccp`` API (in progress) + * :c:func:`bt_pacs_register` + * :c:func:`bt_pacs_unregister` - * :kconfig:option:`CONFIG_BT_BUF_ACL_RX_COUNT` has been deprecated and - :kconfig:option:`CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA` has been added. + * Host -* HCI Drivers + * :c:func:`bt_conn_is_type` -Boards & SoC Support -******************** + * Mesh -* Added support for these SoC series: + * :c:member:`bt_mesh_health_cli::update` callback can be used to periodically update the message + published by the Health Client. -* Made these changes in other SoC series: + * Services -* Added support for these boards: + * The :kconfig:option:`CONFIG_BT_DIS_MODEL_NUMBER` and + :kconfig:option:`CONFIG_BT_DIS_MANUF_NAME` Kconfig options can be used to control the + presence of the Model Number String and Manufacturer Name String characteristics inside + the Device Information Service (DIS). The :kconfig:option:`CONFIG_BT_DIS_MODEL_NUMBER_STR` + and :kconfig:option:`CONFIG_BT_DIS_MANUF_NAME_STR` Kconfig options are now used to set the + string values in these characteristics. They replace the functionality of the deprecated + :kconfig:option:`CONFIG_BT_DIS_MODEL` and :kconfig:option:`CONFIG_BT_DIS_MANUF` Kconfigs. -* Made these board changes: +* Build system - * All HWMv1 board name aliases which were added as deprecated in v3.7 are now removed - (:github:`82247`). - * Enabled USB on NXP ``frdm_mcxn236`` + * Sysbuild -* Added support for the following shields: + * The newly introduced MCUboot swap using offset mode can be selected from sysbuild by using + ``SB_CONFIG_MCUBOOT_MODE_SWAP_USING_OFFSET``, this mode is experimental. -Build system and Infrastructure -******************************* +* Crypto -* Space-separated lists support has been removed from Twister configuration - files. This feature was deprecated a long time ago. Projects that do still use - them can use the :zephyr_file:`scripts/utils/twister_to_list.py` script to - automatically migrate Twister configuration files. + * :kconfig:option:`CONFIG_MBEDTLS_PSA_STATIC_KEY_SLOTS` + * :kconfig:option:`CONFIG_MBEDTLS_PSA_KEY_SLOT_COUNT` -Drivers and Sensors -******************* +* Management -* ADC + * hawkBit -* Battery + * The hawkBit subsystem now uses the State Machine Framework internally. + * :kconfig:option:`CONFIG_HAWKBIT_TENANT` + * :kconfig:option:`CONFIG_HAWKBIT_EVENT_CALLBACKS` + * :kconfig:option:`CONFIG_HAWKBIT_SAVE_PROGRESS` -* CAN + * MCUmgr -* Charger + * Image management :c:macro:`MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED` now has image data field + :c:struct:`img_mgmt_image_confirmed`. -* Clock control +* MCUboot -* Counter + * Signed hex files where an encryption key Kconfig is set now have the encrypted flag set in + the image header. -* DAC +* Video -* Disk + * :c:func:`video_set_stream()` driver API has replaced :c:func:`video_stream_start()` and + :c:func:`video_stream_stop()` driver APIs. -* Display +* Other - * Added flag ``frame_incomplete`` to ``display_write`` that indicates whether a write is the last - write of the frame, allowing display drivers to implement double buffering / tearing enable - signal handling (:github:`81250`) - * Added ``frame_incomplete`` handling to SDL display driver (:dtcompatible:`zephyr,sdl-dc`) - (:github:`81250`) - * Added transparency support to SDL display driver (:dtcompatible:`zephyr,sdl-dc`) (:github:`81184`) + * :kconfig:option:`CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA` + * :c:macro:`DT_ANY_INST_HAS_BOOL_STATUS_OKAY` + * :c:struct:`led_dt_spec` + * :kconfig:option:`CONFIG_STEP_DIR_STEPPER` -* Ethernet +New Boards +********** +.. + You may update this list as you contribute a new board during the release cycle, in order to make + it visible to people who might be looking at the working draft of the release notes. However, note + that this list will be recomputed at the time of the release, so you don't *have* to update it. + In any case, just link the board, further details go in the board description. -* Flash +* Adafruit Industries, LLC -* FPGA + * :zephyr:board:`adafruit_feather_m4_express` (``adafruit_feather_m4_express``) + * :zephyr:board:`adafruit_macropad_rp2040` (``adafruit_macropad_rp2040``) + * :zephyr:board:`adafruit_qt_py_esp32s3` (``adafruit_qt_py_esp32s3``) - * Extracted from :dtcompatible:`lattice,ice40-fpga` the compatible and driver for - :dtcompatible:`lattice,ice40-fpga-bitbang`. This replaces the original ``load_mode`` property from - the binding, which selected either the SPI or GPIO bitbang load mode. +* Advanced Micro Devices (AMD), Inc. -* GNSS + * :zephyr:board:`acp_6_0_adsp` (``acp_6_0_adsp``) -* GPIO +* Analog Devices, Inc. -* Hardware info + * :zephyr:board:`ad_swiot1l_sl` (``ad_swiot1l_sl``) + * :zephyr:board:`max32650evkit` (``max32650evkit``) + * :zephyr:board:`max32650fthr` (``max32650fthr``) + * :zephyr:board:`max32660evsys` (``max32660evsys``) + * :zephyr:board:`max78000evkit` (``max78000evkit``) + * :zephyr:board:`max78000fthr` (``max78000fthr``) + * :zephyr:board:`max78002evkit` (``max78002evkit``) -* I2C +* Antmicro -* I2S + * :zephyr:board:`myra_sip_baseboard` (``myra_sip_baseboard``) -* I3C +* BeagleBoard.org Foundation -* Input + * :zephyr:board:`beagley_ai` (``beagley_ai``) -* LED +* FANKE Technology Co., Ltd. - * Added a new set of devicetree based LED APIs, see :c:struct:`led_dt_spec`. - * lp5569: added use of auto-increment functionality. - * lp5569: implemented ``write_channels`` api. - * lp5569: demonstrate ``led_write_channels`` in the sample. + * :zephyr:board:`fk750m1_vbt6` (``fk750m1_vbt6``) -* LED Strip +* Google, Inc. -* LoRa + * :zephyr:board:`google_icetower` (``google_icetower``) + * :zephyr:board:`google_quincy` (``google_quincy``) -* Mailbox +* Infineon Technologies -* MDIO + * :zephyr:board:`cy8ckit_062s2_ai` (``cy8ckit_062s2_ai``) -* MFD +* Khadas -* Modem + * :zephyr:board:`khadas_edge2` (``khadas_edge2``) -* MIPI-DBI +* Lilygo Shenzhen Xinyuan Electronic Technology Co., Ltd -* MSPI + * :zephyr:board:`ttgo_t7v1_5` (``ttgo_t7v1_5``) + * :zephyr:board:`ttgo_t8s3` (``ttgo_t8s3``) -* Pin control +* M5Stack - * Added new driver for Silabs Series 2 (:dtcompatible:`silabs,dbus-pinctrl`). + * :zephyr:board:`m5stack_cores3` (``m5stack_cores3``) -* PWM +* Makerbase Co., Ltd. -* Regulators + * :zephyr:board:`mks_canable_v20` (``mks_canable_v20``) -* Reset +* MediaTek Inc. -* RTC + * MT8186 (``mt8186``) + * MT8188 (``mt8188``) + * MT8196 (``mt8196``) -* RTIO +* NXP Semiconductors -* SDHC + * :zephyr:board:`frdm_mcxw72` (``frdm_mcxw72``) + * :zephyr:board:`imx91_evk` (``imx91_evk``) + * :zephyr:board:`mcxw72_evk` (``mcxw72_evk``) + * :zephyr:board:`mimxrt700_evk` (``mimxrt700_evk``) -* Sensors +* Nordic Semiconductor -* Serial + * :zephyr:board:`nrf54l09pdk` (``nrf54l09pdk``) -* SPI +* Norik Systems -* USB + * :zephyr:board:`octopus_io_board` (``octopus_io_board``) + * :zephyr:board:`octopus_som` (``octopus_som``) -* Video +* Panasonic Corporation - * Changed :file:`include/zephyr/drivers/video-controls.h` to have control IDs (CIDs) matching - those present in the Linux kernel. + * :zephyr:board:`panb511evb` (``panb511evb``) -* Watchdog +* Peregrine Consultoria e Servicos -* Wi-Fi + * :zephyr:board:`sam4l_wm400_cape` (``sam4l_wm400_cape``) -Networking -********** +* Qorvo, Inc. -* ARP: + * :zephyr:board:`decawave_dwm3001cdk` (``decawave_dwm3001cdk``) -* CoAP: +* RAKwireless Technology Limited -* Connection manager: + * :zephyr:board:`rak3172` (``rak3172``) -* DHCPv4: +* Raspberry Pi Foundation -* DHCPv6: + * :zephyr:board:`rpi_pico2` (``rpi_pico2``) -* DNS/mDNS/LLMNR: +* Realtek Semiconductor Corp. -* gPTP/PTP: + * :zephyr:board:`rts5912_evb` (``rts5912_evb``) -* HTTP: +* Renesas Electronics Corporation -* IPSP: + * :zephyr:board:`ek_ra4l1` (``ek_ra4l1``) + * :zephyr:board:`ek_ra4m1` (``ek_ra4m1``) + * :zephyr:board:`fpb_ra4e1` (``fpb_ra4e1``) + * :zephyr:board:`rzg3s_smarc` (``rzg3s_smarc``) + * :zephyr:board:`voice_ra4e1` (``voice_ra4e1``) -* IPv4: +* STMicroelectronics -* IPv6: + * :zephyr:board:`nucleo_c071rb` (``nucleo_c071rb``) + * :zephyr:board:`nucleo_f072rb` (``nucleo_f072rb``) + * :zephyr:board:`nucleo_h7s3l8` (``nucleo_h7s3l8``) + * :zephyr:board:`nucleo_n657x0_q` (``nucleo_n657x0_q``) + * :zephyr:board:`nucleo_wb07cc` (``nucleo_wb07cc``) + * :zephyr:board:`stm32f413h_disco` (``stm32f413h_disco``) + * :zephyr:board:`stm32n6570_dk` (``stm32n6570_dk``) -* LwM2M: +* Seeed Technology Co., Ltd -* Misc: + * :zephyr:board:`xiao_esp32c6` (``xiao_esp32c6``) -* MQTT: +* Shenzhen Fuyuansheng Electronic Technology Co., Ltd. -* Network Interface: + * :zephyr:board:`ucan` (``ucan``) -* OpenThread +* Silicon Laboratories -* PPP + * :zephyr:board:`siwx917_rb4338a` (``siwx917_rb4338a``) + * :zephyr:board:`xg23_rb4210a` (``xg23_rb4210a``) + * :zephyr:board:`xg24_ek2703a` (``xg24_ek2703a``) + * :zephyr:board:`xg29_rb4412a` (``xg29_rb4412a``) -* Shell: +* Texas Instruments -* Sockets: + * :zephyr:board:`lp_em_cc2340r5` (``lp_em_cc2340r5``) - * The deprecated :kconfig:option:`CONFIG_NET_SOCKETS_POSIX_NAMES` option has been removed. - It was a legacy option and was used to allow user to call BSD socket API while not enabling POSIX API. - This removal means that in order to use POSIX API socket calls, one needs to enable the - :kconfig:option:`CONFIG_POSIX_API` option. - If the application does not want or is not able to enable that option, then the socket API - calls need to be prefixed by a ``zsock_`` string. +* Toradex AG -* Syslog: + * :zephyr:board:`verdin_imx8mm` (``verdin_imx8mm``) -* TCP: +* Waveshare Electronics -* Websocket: + * :zephyr:board:`rp2040_zero` (``rp2040_zero``) -* Wi-Fi: +* WeAct Studio -* zperf: + * :zephyr:board:`mini_stm32h7b0` (``mini_stm32h7b0``) + * :zephyr:board:`weact_stm32h5_core` (``weact_stm32h5_core``) -USB -*** +* WinChipHead -Devicetree -********** + * :zephyr:board:`ch32v003evt` (``ch32v003evt``) -* Added :c:macro:`DT_ANY_INST_HAS_BOOL_STATUS_OKAY`. +* WĂźrth Elektronik GmbH. -Kconfig -******* + * :zephyr:board:`we_oceanus1ev` (``we_oceanus1ev``) + * :zephyr:board:`we_orthosie1ev` (``we_orthosie1ev``) -Libraries / Subsystems -********************** +* others -* Debug + * :zephyr:board:`canbardo` (``canbardo``) + * :zephyr:board:`candlelight` (``candlelight``) + * :zephyr:board:`candlelightfd` (``candlelightfd``) + * :zephyr:board:`esp32c3_supermini` (``esp32c3_supermini``) + * :zephyr:board:`promicro_nrf52840` (``promicro_nrf52840``) -* Demand Paging +New Drivers +*********** +.. + Same as above for boards, this will also be recomputed at the time of the release. + Just link the driver, further details go in the binding description -* Formatted output +* :abbr:`ADC (Analog to Digital Converter)` -* Management + * :dtcompatible:`adi,ad4114-adc` + * :dtcompatible:`adi,ad7124-adc` + * :dtcompatible:`st,stm32n6-adc` + * :dtcompatible:`ti,ads114s06` + * :dtcompatible:`ti,ads124s06` + * :dtcompatible:`ti,ads124s08` + * :dtcompatible:`ti,ads131m02` + * :dtcompatible:`ti,tla2022` + * :dtcompatible:`ti,tla2024` -* Logging +* ARM architecture -* Modem modules + * :dtcompatible:`nxp,nbu` -* Power management +* Audio -* Crypto + * :dtcompatible:`cirrus,cs43l22` + * :dtcompatible:`intel,adsp-mic-privacy` + +* Bluetooth + + * :dtcompatible:`renesas,bt-hci-da1453x` + * :dtcompatible:`silabs,siwx91x-bt-hci` + * :dtcompatible:`st,hci-stm32wb0` + +* Charger + + * :dtcompatible:`nxp,pf1550-charger` + +* Clock control + + * :dtcompatible:`atmel,sam0-gclk` + * :dtcompatible:`atmel,sam0-mclk` + * :dtcompatible:`atmel,sam0-osc32kctrl` + * :dtcompatible:`nordic,nrf-hsfll-global` + * :dtcompatible:`nuvoton,npcm-pcc` + * :dtcompatible:`realtek,rts5912-sccon` + * :dtcompatible:`st,stm32n6-cpu-clock-mux` + * :dtcompatible:`st,stm32n6-hse-clock` + * :dtcompatible:`st,stm32n6-ic-clock-mux` + * :dtcompatible:`st,stm32n6-pll-clock` + * :dtcompatible:`st,stm32n6-rcc` + * :dtcompatible:`wch,ch32v00x-hse-clock` + * :dtcompatible:`wch,ch32v00x-hsi-clock` + * :dtcompatible:`wch,ch32v00x-pll-clock` + * :dtcompatible:`wch,rcc` + +* Comparator + + * :dtcompatible:`silabs,acmp` + +* Counter + + * :dtcompatible:`adi,max32-rtc-counter` + * :dtcompatible:`renesas,rz-gtm-counter` + +* CPU + + * :dtcompatible:`wch,qingke-v2` + +* :abbr:`DAC (Digital to Analog Converter)` + + * :dtcompatible:`adi,max22017-dac` + * :dtcompatible:`renesas,ra-dac` + * :dtcompatible:`renesas,ra-dac-global` + +* :abbr:`DAI (Digital Audio Interface)` + + * :dtcompatible:`mediatek,afe` + * :dtcompatible:`nxp,dai-micfil` + +* Display + + * :dtcompatible:`ilitek,ili9806e-dsi` + * :dtcompatible:`renesas,ra-glcdc` + * :dtcompatible:`solomon,ssd1309fb` + +* :abbr:`DMA (Direct Memory Access)` + + * :dtcompatible:`infineon,cat1-dma` + * :dtcompatible:`nxp,sdma` + * :dtcompatible:`silabs,ldma` + * :dtcompatible:`silabs,siwx91x-dma` + * :dtcompatible:`xlnx,axi-dma-1.00.a` + * :dtcompatible:`xlnx,eth-dma` + +* :abbr:`DSA (Distributed Switch Architecture)` + + * :dtcompatible:`nxp,netc-switch` - * The Kconfig symbol :kconfig:option:`CONFIG_MBEDTLS_PSA_STATIC_KEY_SLOTS` was - added to allow Mbed TLS to use statically allocated buffers to store key material - in its PSA Crypto core instead of heap-allocated ones. This can help reduce - (or remove, if no other component makes use of it) heap memory requirements - from the final application. +* :abbr:`EEPROM (Electrically Erasable Programmable Read-Only Memory)` - * The Kconfig symbol :kconfig:option:`CONFIG_MBEDTLS_PSA_KEY_SLOT_COUNT` was - added to allow selecting the number of key slots available in the Mbed TLS - implementation of the PSA Crypto core. It defaults to 16. Since each - slot consumes RAM memory even if unused, this value can be tweaked in order - to minimize RAM usage. + * :dtcompatible:`fujitsu,mb85rsxx` -* CMSIS-NN +* Ethernet + + * :dtcompatible:`davicom,dm8806-phy` + * :dtcompatible:`microchip,lan9250` + * :dtcompatible:`microchip,t1s-phy` + * :dtcompatible:`microchip,vsc8541` + * :dtcompatible:`renesas,ra-ethernet` + * :dtcompatible:`sensry,sy1xx-mac` + +* Firmware + + * :dtcompatible:`arm,scmi-power` + +* Flash controller + + * :dtcompatible:`silabs,siwx91x-flash-controller` + * :dtcompatible:`ti,cc23x0-flash-controller` + +* :abbr:`FPGA (Field Programmable Gate Array)` + + * :dtcompatible:`lattice,ice40-fpga-base` + * :dtcompatible:`lattice,ice40-fpga-bitbang` + +* :abbr:`GPIO (General Purpose Input/Output)` + + * :dtcompatible:`adi,max22017-gpio` + * :dtcompatible:`adi,max22190-gpio` + * :dtcompatible:`awinic,aw9523b-gpio` + * :dtcompatible:`ite,it8801-gpio` + * :dtcompatible:`microchip,mec5-gpio` + * :dtcompatible:`nordic,npm2100-gpio` + * :dtcompatible:`nxp,pca6416` + * :dtcompatible:`raspberrypi,rp1-gpio` + * :dtcompatible:`realtek,rts5912-gpio` + * :dtcompatible:`renesas,ra-gpio-mipi-header` + * :dtcompatible:`renesas,rz-gpio` + * :dtcompatible:`renesas,rz-gpio-int` + * :dtcompatible:`sensry,sy1xx-gpio` + * :dtcompatible:`silabs,siwx91x-gpio` + * :dtcompatible:`silabs,siwx91x-gpio-port` + * :dtcompatible:`silabs,siwx91x-gpio-uulp` + * :dtcompatible:`st,dcmi-camera-fpu-330zh` + * :dtcompatible:`st,mfxstm32l152` + * :dtcompatible:`stemma-qt-connector` + * :dtcompatible:`ti,cc23x0-gpio` + * :dtcompatible:`wch,gpio` + +* IEEE 802.15.4 HDLC RCP interface + + * :dtcompatible:`nxp,hdlc-rcp-if` + * :dtcompatible:`uart,hdlc-rcp-if` + +* :abbr:`I2C (Inter-Integrated Circuit)` + + * :dtcompatible:`nxp,ii2c` + * :dtcompatible:`ti,omap-i2c` + * :dtcompatible:`ti,tca9544a` + +* :abbr:`I3C (Improved Inter-Integrated Circuit)` + + * :dtcompatible:`snps,designware-i3c` + * :dtcompatible:`st,stm32-i3c` + +* IEEE 802.15.4 + + * :dtcompatible:`nxp,mcxw-ieee802154` + +* Input + + * :dtcompatible:`cypress,cy8cmbr3xxx` + * :dtcompatible:`ite,it8801-kbd` + * :dtcompatible:`microchip,cap12xx` + * :dtcompatible:`nintendo,nunchuk` + +* Interrupt controller + + * :dtcompatible:`renesas,rz-ext-irq` + * :dtcompatible:`wch,pfic` + +* Mailbox + + * :dtcompatible:`linaro,ivshmem-mbox` + * :dtcompatible:`ti,omap-mailbox` + +* :abbr:`MDIO (Management Data Input/Output)` + + * :dtcompatible:`microchip,lan865x-mdio` + * :dtcompatible:`renesas,ra-mdio` + * :dtcompatible:`sensry,sy1xx-mdio` + +* Memory controller + + * :dtcompatible:`renesas,ra-sdram` + +* :abbr:`MFD (Multi-Function Device)` + + * :dtcompatible:`adi,max22017` + * :dtcompatible:`awinic,aw9523b` + * :dtcompatible:`ite,it8801-altctrl` + * :dtcompatible:`ite,it8801-mfd` + * :dtcompatible:`ite,it8801-mfd-map` + * :dtcompatible:`maxim,ds3231-mfd` + * :dtcompatible:`nordic,npm2100` + * :dtcompatible:`nxp,pf1550` -* FPGA +* :abbr:`MIPI DSI (Mobile Industry Processor Interface Display Serial Interface)` -* Random + * :dtcompatible:`renesas,ra-mipi-dsi` -* SD +* Miscellaneous -* State Machine Framework + * :dtcompatible:`nordic,nrf-bicr` + * :dtcompatible:`nordic,nrf-ppib` + * :dtcompatible:`renesas,ra-external-interrupt` -* Storage +* :abbr:`MMU / MPU (Memory Management Unit / Memory Protection Unit)` -* Task Watchdog + * :dtcompatible:`nxp,sysmpu` -* POSIX API +* :abbr:`MTD (Memory Technology Device)` -* LoRa/LoRaWAN + * :dtcompatible:`nxp,s32-qspi-hyperflash` + * :dtcompatible:`nxp,xspi-mx25um51345g` + * :dtcompatible:`ti,cc23x0-ccfg-flash` -* ZBus +* Networking -HALs -**** + * :dtcompatible:`silabs,series2-radio` -* Nordic +* :abbr:`PCIe (Peripheral Component Interconnect Express)` -* STM32 + * :dtcompatible:`brcm,brcmstb-pcie` -* ADI +* PHY -* Espressif + * :dtcompatible:`renesas,ra-usbphyc` + * :dtcompatible:`st,stm32u5-otghs-phy` -MCUboot -******* +* Pin control + + * :dtcompatible:`realtek,rts5912-pinctrl` + * :dtcompatible:`renesas,rzg-pinctrl` + * :dtcompatible:`sensry,sy1xx-pinctrl` + * :dtcompatible:`silabs,dbus-pinctrl` + * :dtcompatible:`silabs,siwx91x-pinctrl` + * :dtcompatible:`ti,cc23x0-pinctrl` + * :dtcompatible:`wch,afio` + +* :abbr:`PWM (Pulse Width Modulation)` + + * :dtcompatible:`atmel,sam0-tc-pwm` + * :dtcompatible:`ite,it8801-pwm` + * :dtcompatible:`renesas,rz-gpt-pwm` + * :dtcompatible:`zephyr,fake-pwm` + +* Quad SPI + + * :dtcompatible:`nxp,s32-qspi-sfp-frad` + * :dtcompatible:`nxp,s32-qspi-sfp-mdad` + +* Regulator + + * :dtcompatible:`nordic,npm2100-regulator` + * :dtcompatible:`nxp,pf1550-regulator` + +* :abbr:`RNG (Random Number Generator)` + + * :dtcompatible:`nordic,nrf-cracen-ctrdrbg` + * :dtcompatible:`nxp,ele-trng` + * :dtcompatible:`renesas,ra-sce5-rng` + * :dtcompatible:`renesas,ra-sce7-rng` + * :dtcompatible:`renesas,ra-sce9-rng` + * :dtcompatible:`renesas,ra-trng` + * :dtcompatible:`sensry,sy1xx-trng` + * :dtcompatible:`silabs,siwx91x-rng` + * :dtcompatible:`st,stm32-rng-noirq` + +* :abbr:`RTC (Real Time Clock)` + + * :dtcompatible:`epson,rx8130ce-rtc` + * :dtcompatible:`maxim,ds1337` + * :dtcompatible:`maxim,ds3231-rtc` + * :dtcompatible:`microcrystal,rv8803` + * :dtcompatible:`ti,bq32002` + +* SDHC + + * :dtcompatible:`renesas,ra-sdhc` + +* Sensors + + * :dtcompatible:`adi,adxl366` + * :dtcompatible:`hc-sr04` + * :dtcompatible:`invensense,icm42370p` + * :dtcompatible:`invensense,icm42670s` + * :dtcompatible:`invensense,icp101xx` + * :dtcompatible:`maxim,ds3231-sensor` + * :dtcompatible:`melexis,mlx90394` + * :dtcompatible:`nordic,npm2100-vbat` + * :dtcompatible:`phosense,xbr818` + * :dtcompatible:`renesas,hs400x` + * :dtcompatible:`sensirion,scd40` + * :dtcompatible:`sensirion,scd41` + * :dtcompatible:`sensirion,sts4x` + * :dtcompatible:`st,lis2duxs12` + * :dtcompatible:`st,lsm6dsv16x` + * :dtcompatible:`ti,tmag3001` + * :dtcompatible:`ti,tmp435` + * :dtcompatible:`we,wsen-pads-2511020213301` + * :dtcompatible:`we,wsen-pdus-25131308XXXXX` + * :dtcompatible:`we,wsen-tids-2521020222501` + +* Serial controller + + * :dtcompatible:`microchip,mec5-uart` + * :dtcompatible:`realtek,rts5912-uart` + * :dtcompatible:`renesas,rz-scif-uart` + * :dtcompatible:`silabs,eusart-uart` + * :dtcompatible:`silabs,usart-uart` + * :dtcompatible:`ti,cc23x0-uart` + * :dtcompatible:`wch,usart` + +* :abbr:`SPI (Serial Peripheral Interface)` + + * :dtcompatible:`ite,it8xxx2-spi` + * :dtcompatible:`nxp,lpspi` + * :dtcompatible:`nxp,xspi` + * :dtcompatible:`renesas,ra-spi` + +* Stepper + + * :dtcompatible:`adi,tmc2209` + * :dtcompatible:`ti,drv8424` + +* :abbr:`TCPC (USB Type-C Port Controller)` + + * :dtcompatible:`richtek,rt1715` + +* Timer + + * :dtcompatible:`mediatek,ostimer64` + * :dtcompatible:`realtek,rts5912-rtmr` + * :dtcompatible:`realtek,rts5912-slwtimer` + * :dtcompatible:`renesas,rz-gpt` + * :dtcompatible:`renesas,rz-gtm` + * :dtcompatible:`riscv,machine-timer` + * :dtcompatible:`ti,cc23x0-systim-timer` + * :dtcompatible:`wch,systick` + +* USB + + * :dtcompatible:`ambiq,usb` + * :dtcompatible:`renesas,ra-udc` + * :dtcompatible:`renesas,ra-usbfs` + * :dtcompatible:`renesas,ra-usbhs` + * :dtcompatible:`zephyr,midi2-device` + +* Video + + * :dtcompatible:`zephyr,video-emul-imager` + * :dtcompatible:`zephyr,video-emul-rx` -OSDP -**** +* Watchdog + + * :dtcompatible:`atmel,sam4l-watchdog` + * :dtcompatible:`nordic,npm2100-wdt` + * :dtcompatible:`nxp,rtwdog` -Trusted Firmware-M -****************** +* Wi-Fi -LVGL -**** + * :dtcompatible:`infineon,airoc-wifi` + * :dtcompatible:`silabs,siwx91x-wifi` -* Added ``frame_incomplete`` support to indicate whether a write is the last - write of the frame (:github:`81250`) +New Samples +*********** -Tests and Samples -***************** +.. + Same as above for boards and drivers, this will also be recomputed at the time of the release. + Just link the sample, further details go in the sample documentation itself. + +* :zephyr:code-sample:`6dof_motion_drdy` +* :zephyr:code-sample:`ble_cs` +* :zephyr:code-sample:`bluetooth_ccp_call_control_client` +* :zephyr:code-sample:`bluetooth_ccp_call_control_server` +* :zephyr:code-sample:`coresight_stm_sample` +* :zephyr:code-sample:`dfu-next` +* :zephyr:code-sample:`i2c-rtio-loopback` +* :zephyr:code-sample:`lvgl-screen-transparency` +* :zephyr:code-sample:`mctp_endpoint_sample` +* :zephyr:code-sample:`mctp_host_sample` +* :zephyr:code-sample:`openthread-shell` +* :zephyr:code-sample:`ot-coap` +* :zephyr:code-sample:`rtc` +* :zephyr:code-sample:`sensor_batch_processing` +* :zephyr:code-sample:`sensor_clock` +* :zephyr:code-sample:`stream_fifo` +* :zephyr:code-sample:`tdk_apex` +* :zephyr:code-sample:`tmc50xx` +* :zephyr:code-sample:`uart` +* :zephyr:code-sample:`usb-midi2-device` +* :zephyr:code-sample:`usbd-cdc-acm-console` +* :zephyr:code-sample:`webusb-next` + +Other notable changes +********************* + +.. + Any more descriptive subsystem or driver changes. Do you really want to write + a paragraph or is it enough to link to the api/driver/Kconfig/board page above? -* Fixed incorrect alpha values in :zephyr_file:`samples/drivers/display`. (:github:`81184`) -* Added :zephyr_file:`samples/modules/lvgl/screen_transparency`. (:github:`81184`) +* Space-separated lists support has been removed from Twister configuration + files. This feature was deprecated a long time ago. Projects that do still use + them can use the :zephyr_file:`scripts/utils/twister_to_list.py` script to + automatically migrate Twister configuration files. -Issue Related Items -******************* +* Test case names for Ztest now include the Ztest suite name, meaning the resulting identifier has + three sections and looks like: ``..``. + These extended identifiers are used in log output, twister.json and testplan.json, + as well as for ``--sub-test`` command line parameters. -Known Issues -============ +* The ``--no-detailed-test-id`` command line option can be used to shorten the test case name + by excluding the test scenario name prefix which is the same as the parent test suite id. diff --git a/doc/releases/release-notes-4.2.rst b/doc/releases/release-notes-4.2.rst new file mode 100644 index 0000000000000..08b9bac37090e --- /dev/null +++ b/doc/releases/release-notes-4.2.rst @@ -0,0 +1,94 @@ +:orphan: + +.. + What goes here: removed/deprecated apis, new boards, new drivers, notable + features. If you feel like something new can be useful to a user, put it + under "Other Enhancements" in the first paragraph, if you feel like something + is worth mentioning in the project media (release blog post, release + livestream) put it under "Major enhancement". +.. + If you are describing a feature or functionality, consider adding it to the + actual project documentation rather than the release notes, so that the + information does not get lost in time. +.. + No list of bugfixes, minor changes, those are already in the git log, this is + not a changelog. +.. + Does the entry have a link that contains the details? Just add the link, if + you think it needs more details, put them in the content that shows up on the + link. +.. + Are you thinking about generating this? Don't put anything at all. +.. + Does the thing require the user to change their application? Put it on the + migration guide instead. (TODO: move the removed APIs section in the + migration guide) + +.. _zephyr_4.2: + +Zephyr 4.2.0 (Working Draft) +############################ + +We are pleased to announce the release of Zephyr version 4.2.0. + +Major enhancements with this release include: + +An overview of the changes required or recommended when migrating your application from Zephyr +v4.1.0 to Zephyr v4.2.0 can be found in the separate :ref:`migration guide`. + +The following sections provide detailed lists of changes by component. + +Security Vulnerability Related +****************************** +The following CVEs are addressed by this release: + +More detailed information can be found in: +https://docs.zephyrproject.org/latest/security/vulnerabilities.html + +API Changes +*********** + +Removed APIs and options +======================== + +Deprecated APIs and options +=========================== + +New APIs and options +==================== + +.. + Link to new APIs here, in a group if you think it's necessary, no need to get + fancy just list the link, that should contain the documentation. If you feel + like you need to add more details, add them in the API documentation code + instead. + +New Boards +********** + +.. + You may update this list as you contribute a new board during the release cycle, in order to make + it visible to people who might be looking at the working draft of the release notes. However, note + that this list will be recomputed at the time of the release, so you don't *have* to update it. + In any case, just link the board, further details go in the board description. + +New Drivers +*********** + +.. + Same as above for boards, this will also be recomputed at the time of the release. + Just link the driver, further details go in the binding description + +New Samples +*********** + +.. + Same as above for boards and drivers, this will also be recomputed at the time of the release. + Just link the sample, further details go in the sample documentation itself. + +Other notable changes +********************* + +.. + Any more descriptive subsystem or driver changes. Do you really want to write + a paragraph or is it enough to link to the api/driver/Kconfig/board page above? diff --git a/doc/requirements.txt b/doc/requirements.txt index cb202de2f50a4..b5a5d3065408a 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -4,7 +4,7 @@ sphinx sphinx_rtd_theme~=3.0 sphinx-tabs sphinxcontrib-svg2pdfconverter -pygments>=2.9 +pygments>=2.9,!=2.19.0 sphinx-notfound-page sphinx-copybutton sphinx-togglebutton diff --git a/doc/safety/safety_overview.rst b/doc/safety/safety_overview.rst index d3e907f340d66..16106582a3983 100644 --- a/doc/safety/safety_overview.rst +++ b/doc/safety/safety_overview.rst @@ -147,6 +147,46 @@ system. Also the **IEC 61508 standard** sets a pre-condition and recommendation towards the use of coding standards / guidelines to reduce likelihood of errors. +The project TSC and the Safety Committee of the project agreed to implement +a staged and incremental approach for complying with a set of coding rules (AKA +Coding Guidelines) to improve quality and consistency of the code base. Below +are the agreed upon stages: + +Stage I (COMPLETED) + Coding guideline rules are available to be followed and referenced, + but not enforced. Rules are not yet enforced in CI and pull-requests cannot be + blocked by reviewers/approvers due to violations. + +Stage II + Reviewers/approvers can block pull-requests due to violations of the coding guidelines + in pull-requests across the codebase. + + Begin enforcement on a limited scope of the code base. Initially, this would be + the safety certification scope. For rules easily applied across codebase, we + should not limit compliance to initial scope. This step requires tooling, + CI setup and an enforcement strategy. + +Stage III + Revisit the coding guideline rules and based on experience from previous + stages, refine/iterate on selected rules. + +Stage IV + Expand enforcement to the wider codebase. Exceptions may be granted on some + areas of the codebase with a proper justification. Exception would require + TSC approval. + +.. note:: + + Coding guideline rules may be removed/changed at any time by filing a + GH issue/RFC. + +.. important:: + + **Current stage:** + The prerequisites to complete **Stage II** are currently being looked at: + The tooling is in evaluation, CI setup and `enforcement strategy + `__ is being worked on. + Requirements and requirements tracing ------------------------------------- diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index da3b353d9893f..550a66da217a9 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1599,8 +1599,8 @@ This has been fixed in main for v3.6.0 :cve:`2024-3077` ---------------- -Bluetooth: Integer underflow in gatt_find_info_rsp. A malicious BLE -device can crash BLE victim device by sending malformed gatt packet. +Bluetooth: Integer underflow in gatt_find_info_rsp. A malicious Bluetooth LE +device can crash Bluetooth LE victim device by sending malformed gatt packet. - `Zephyr project bug tracker GHSA-gmfv-4vfh-2mh8 `_ @@ -1615,8 +1615,8 @@ This has been fixed in main for v3.7.0 Bluetooth: DoS caused by null pointer dereference. -A malicious BLE device can send a specific order of packet -sequence to cause a DoS attack on the victim BLE device. +A malicious Bluetooth LE device can send a specific order of packet +sequence to cause a DoS attack on the victim Bluetooth LE device. - `Zephyr project bug tracker GHSA-jmr9-xw2v-5vf4 `_ @@ -1788,12 +1788,36 @@ This has been fixed in main for v3.7.0 :cve:`2024-8798` ---------------- -Under embargo until 2024-11-22 +Bluetooth: classic: avdtp: missing buffer length check + +- `Zephyr project bug tracker GHSA-r7pm-f93f-f7fp + `_ + +This has been fixed in main for v4.0.0 + +- `PR 77969 fix for main + `_ + +- `PR 78409 fix for 3.7 + `_ :cve:`2024-10395` ----------------- -Under embargo until 2025-01-23 +net: lib: http_server: Buffer Under-read + +No proper validation of the length of user input in +http_server_get_content_type_from_extension could cause a +segmentation fault or crash by causing memory to be read +outside of the bounds of the buffer. + +- `Zephyr project bug tracker GHSA-hfww-j92m-x8fv + `_ + +This has been fixed in main for v4.0.0 + +- `PR 80396 fix for main + `_ :cve:`2024-11263` ----------------- diff --git a/doc/services/debugging/thread-analyzer.rst b/doc/services/debugging/thread-analyzer.rst index 2b41099df028a..57e433ff176c4 100644 --- a/doc/services/debugging/thread-analyzer.rst +++ b/doc/services/debugging/thread-analyzer.rst @@ -67,19 +67,25 @@ Configuration ************* Configure this module using the following options. -* ``THREAD_ANALYZER``: enable the module. -* ``THREAD_ANALYZER_USE_PRINTK``: use printk for thread statistics. -* ``THREAD_ANALYZER_USE_LOG``: use the logger for thread statistics. -* ``THREAD_ANALYZER_AUTO``: run the thread analyzer automatically. - You do not need to add any code to the application when using this option. -* ``THREAD_ANALYZER_AUTO_INTERVAL``: the time for which the module sleeps - between consecutive printing of thread analysis in automatic mode. -* ``THREAD_ANALYZER_AUTO_STACK_SIZE``: the stack for thread analyzer - automatic thread. -* ``THREAD_NAME``: enable this option in the kernel to print the name of the - thread instead of its ID. -* ``THREAD_RUNTIME_STATS``: enable this option to print thread runtime data such - as utilization (This options is automatically selected by THREAD_ANALYZER). +:kconfig:option:`CONFIG_THREAD_ANALYZER` + Enable the module. +:kconfig:option:`CONFIG_THREAD_ANALYZER_USE_PRINTK` + Use printk for thread statistics. +:kconfig:option:`CONFIG_THREAD_ANALYZER_USE_LOG` + Use the logger for thread statistics. +:kconfig:option:`CONFIG_THREAD_ANALYZER_AUTO` + Run the thread analyzer automatically. + You do not need to add any code to the application when using this option. +:kconfig:option:`CONFIG_THREAD_ANALYZER_AUTO_INTERVAL` + The time for which the module sleeps between consecutive printing of thread analysis in automatic + mode. +:kconfig:option:`CONFIG_THREAD_ANALYZER_AUTO_STACK_SIZE` + The stack for thread analyzer automatic thread. +:kconfig:option:`CONFIG_THREAD_NAME` + Print the name of the thread instead of its ID. +:kconfig:option:`CONFIG_THREAD_RUNTIME_STATS` + Print thread runtime data such as utilization. + This options is automatically selected by :kconfig:option:`CONFIG_THREAD_ANALYZER`. API documentation ***************** diff --git a/doc/services/device_mgmt/mcumgr.rst b/doc/services/device_mgmt/mcumgr.rst index b554d6777f17e..a91bd86e46fa8 100644 --- a/doc/services/device_mgmt/mcumgr.rst +++ b/doc/services/device_mgmt/mcumgr.rst @@ -19,7 +19,7 @@ The following management operations are available: over the following transports: -* BLE (Bluetooth Low Energy) +* Bluetooth Low Energy (LE) * Serial (UART) * UDP over IP @@ -32,7 +32,7 @@ The management subsystem is located in :zephyr_file:`subsys/mgmt/` inside of the Zephyr tree. Additionally, there is a :zephyr:code-sample:`sample ` server that provides -management functionality over BLE and serial. +management functionality over Bluetooth LE and serial. .. _mcumgr_tools_libraries: diff --git a/doc/services/device_mgmt/ota.rst b/doc/services/device_mgmt/ota.rst index 4548ce8b02860..911be1d1ba76a 100644 --- a/doc/services/device_mgmt/ota.rst +++ b/doc/services/device_mgmt/ota.rst @@ -62,7 +62,7 @@ SMP Server ========== A Simple Management Protocol (SMP) server can be used to update firmware via -Bluetooth Low Energy (BLE) or UDP. :ref:`mcu_mgr` is used to send a signed +Bluetooth Low Energy (LE) or UDP. :ref:`mcu_mgr` is used to send a signed firmware binary to the remote device where it is verified by MCUboot before the upgrade occurs. diff --git a/doc/services/device_mgmt/smp_transport.rst b/doc/services/device_mgmt/smp_transport.rst index 644ef7c484ee0..a6a00fed9f34b 100644 --- a/doc/services/device_mgmt/smp_transport.rst +++ b/doc/services/device_mgmt/smp_transport.rst @@ -8,10 +8,10 @@ side SMP transports. .. _mcumgr_smp_transport_ble: -BLE (Bluetooth Low Energy) -************************** +Bluetooth Low Energy (LE) +************************* -MCUmgr Clients need to use following BLE Characteristics, when implementing +MCUmgr Clients need to use following Bluetooth Characteristics, when implementing SMP client: - **Service UUID**: ``8D53DC1D-1DB7-4CD3-868B-8A527460AA84`` diff --git a/doc/services/file_system/index.rst b/doc/services/file_system/index.rst index 3c038847916e5..b04cb950ff616 100644 --- a/doc/services/file_system/index.rst +++ b/doc/services/file_system/index.rst @@ -51,11 +51,11 @@ Samples for the VFS are mainly supplied in ``samples/subsys/fs``, although vario VFS usage are provided as important functionalities in samples for different subsystems. Here is the list of samples worth looking at: -- ``samples/subsys/fs/fat_fs`` is an example of FAT file system usage with SDHC media; -- ``samples/subsys/shell/fs`` is an example of Shell fs subsystem, using internal flash partition - formatted to LittleFS; -- ``samples/subsys/usb/mass/`` example of USB Mass Storage device that uses FAT FS driver with RAM - or SPI connected FLASH, or LittleFS in flash, depending on the sample configuration. +- :zephyr:code-sample:`fs` is an example of FAT file system usage with SDHC media; +- :zephyr:code-sample:`shell-fs` is an example of Shell fs subsystem, using internal flash partition + formatted to LittleFS; +- :zephyr:code-sample:`usb-mass` example of USB Mass Storage device that uses FAT FS driver with RAM + or SPI connected FLASH, or LittleFS in flash, depending on the sample configuration. API Reference ************* diff --git a/doc/services/index.rst b/doc/services/index.rst index d1c456151a299..69050cb784fc5 100644 --- a/doc/services/index.rst +++ b/doc/services/index.rst @@ -29,10 +29,8 @@ OS Services portability/index.rst poweroff.rst profiling/index.rst - secure_storage.rst shell/index.rst serialization/index.rst - settings/index.rst smf/index.rst storage/index.rst sensing/index.rst diff --git a/doc/services/ipc/ipc_service/backends/ipc_service_icmsg.rst b/doc/services/ipc/ipc_service/backends/ipc_service_icmsg.rst index 251a332027a44..369929a876f50 100644 --- a/doc/services/ipc/ipc_service/backends/ipc_service_icmsg.rst +++ b/doc/services/ipc/ipc_service/backends/ipc_service_icmsg.rst @@ -83,8 +83,7 @@ connected through the IPC instance: memory. #. It then sends a signal to the other domain or CPU, informing that the data has been written. Sending the signal to the other domain or CPU is repeated - with timeout specified by - :kconfig:option:`CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS` option. + with timeout. #. When the signal from the other domain or CPU is received, the magic number is read from ``rx-region``. If it is correct, the bonding process is finished and the backend informs the application by calling diff --git a/doc/services/llext/api.rst b/doc/services/llext/api.rst index b3d8d64152b00..c4227ca2d8a42 100644 --- a/doc/services/llext/api.rst +++ b/doc/services/llext/api.rst @@ -6,3 +6,5 @@ API Reference .. doxygengroup:: llext_symbols .. doxygengroup:: llext_loader_apis + +.. doxygengroup:: llext_inspect_apis diff --git a/doc/services/llext/debug.rst b/doc/services/llext/debug.rst new file mode 100644 index 0000000000000..2389c078dc993 --- /dev/null +++ b/doc/services/llext/debug.rst @@ -0,0 +1,359 @@ +.. _llext_debug: + +Debugging extensions +#################### + +Debugging extensions is a complex task. Since the extension code is by +definition not built with the Zephyr application, the final Zephyr ELF file +does not contain the symbols for extension code. Furthermore, the extension is +dynamically relocated by :c:func:`llext_load` at runtime, so even if the +symbols were available, it would be impossible for the debugger to know the +final locations of the symbols in the extension code. + +Setting up the debugger session properly in this case requires a few manual +steps. The following sections will provide some tips on how to do it with the +Zephyr SDK and the debug features provided by ``west``, but the instructions +can be adapted to any GDB-based debugging environment. + +Extension debugging process +=========================== + +1. Make sure the project is set up to display the verbose LLEXT debug output + (:kconfig:option:`CONFIG_LOG` and :kconfig:option:`CONFIG_LLEXT_LOG_LEVEL_DBG` + are set). + +2. Build the Zephyr application and the extensions. + + For each target ``name`` included in the current build, two files will be + generated into the ``llext`` subdirectory of the build root: + + ``name_ext_debug.elf`` + + An intermediate ELF file with full debugging information. + + ``name.llext`` + + The final extension binary, stripped to the essential data required for + loading into the Zephyr application. + + Other files may be present, depending on the target architecture and the + build configuration. + +3. Start a debugging session of the main Zephyr application. This is described + in the :ref:`Debugging ` section of the documentation; on + supported boards it is as easy as running ``west debug``, perhaps with some + additional arguments. + +4. Set a breakpoint just after the :c:func:`llext_load` function in your code + and let it run. This will load the extension into memory and relocate it. + The output logs will contain a line with ``gdb add-symbol-file flags:``, + followed by lines all starting with ``-s``. + +5. Type this command in the GDB console to load this extension's symbols: + + .. code-block:: + + add-symbol-file + + where ```` is the full path of the ELF file with debug + information identified in step 2, and ```` is a space + separated list of all the ``-s`` lines collected from the log in the + previous step. + +6. The extension symbols are now available to the debugger. You can set + breakpoints, inspect variables, and step through the code as usual. + +Steps 4-6 can be repeated for every extension that is loaded by the +application, if there are several. + +Symbol lookup issues +==================== + +.. warning:: + + It is almost certain that the loaded symbols will be shadowed by others in + the main application; for example, they may be located inside the memory + area of the ELF buffer or the LLEXT heap. + + In this case GDB chooses the first known symbol and therefore associates the + addresses to some ``elf_buffer+0x123`` instead of an expected ``ext_fn``. + This further confuses its high-level operations like source stepping or + inspecting locals, since they are meaningless in that context. + +Two possible solutions to this problem are discussed in the following +paragraphs. + +Discard all Zephyr symbols +-------------------------- + +The simplest option is to drop all the Zephyr application symbols from GDB by +invoking ``add-symbol-file`` with no arguments, before step 5. This will +however focus the debugging session to the llext only, as all information about +the Zephyr application will be lost. For example, the debugger may not be able to +properly follow stack traces outside the extension code. + +It is possible to use the same technique multiple times in the same session to +switch between the main and extension symbol tables as required, but it rapidly +becomes cumbersome. + +Edit the ELF file +----------------- + +This alternative is more complex but allows for a more seamless debugging +experience. The idea is to edit the main Zephyr ELF file to remove information +about the symbols that overlap with the extension that is to be debugged, so +that when the extension symbols are loaded, GDB will not have any ambiguity. +This can be done by using ``objcopy`` with the ``-N `` option. + +Identifying the offending symbols is however an iterative trial-and-error +procedure, as there can be many different layers; for example, the ELF buffer +may be itself contained in a symbol for the data segment. Fortunately, this +knowledge can then be used several times as the list is unlikely to change for +a given project. + +Example debugging session +========================= + +This example demonstrates how to debug the ``detached_fn`` extension in the +``tests/subsys/llext`` project (specifically, the ``writable`` case), on an +emulated ``mps2/an385`` board which is based on an ARM Cortex-M3. + +.. note:: + + The logs below have been obtained using Zephyr version 4.1 and the Zephyr + SDK version 0.17.0. However, the exact addresses may still vary between + runs even when using the same versions. Adjust the commands below to + match the results of your own session. + +The following command will build the project and start the emulator in +debugging mode: + +.. code-block:: + :caption: Terminal 1 (build, QEMU emulator, GDB server) + + zephyr$ west build -p -b mps2/an385 tests/subsys/llext/ -T llext.writable -t debugserver_qemu + -- west build: generating a build system + [...] + -- west build: running target debugserver_qemu + [...] + [186/187] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: cortex-m3 + +On a separate terminal, set ``ZEPHYR_SDK_INSTALL_DIR`` to the directory for the +Zephyr SDK on your installation, then start the GDB client for the target: + +.. code-block:: + :caption: Terminal 2 (GDB client) + + zephyr$ export LLEXT_SDK_INSTALL_DIR=/opt/zephyr-sdk-0.17.0 + zephyr$ ${LLEXT_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb build/zephyr/zephyr.elf + GNU gdb (Zephyr SDK 0.17.0) 12.1 + [...] + Reading symbols from build/zephyr/zephyr.elf... + (gdb) + +Connect, set a breakpoint on the ``llext_load`` function and run until it +finishes: + +.. code-block:: + :caption: Terminal 2 (GDB client) + + (gdb) target extended-remote :1234 + Remote debugging using :1234 + z_arm_reset () at zephyr/arch/arm/core/cortex_m/reset.S:124 + 124 movs.n r0, #_EXC_IRQ_DEFAULT_PRIO + (gdb) break llext_load + Breakpoint 1 at 0x236c: file zephyr/subsys/llext/llext.c, line 168. + (gdb) continue + Continuing. + + Breakpoint 1, llext_load (ldr=ldr@entry=0x2000bef0 , + name=name@entry=0x9d98 "test_detached", + ext=ext@entry=0x2000abb8 , + ldr_parm=ldr_parm@entry=0x2000bee8 ) + at zephyr/subsys/llext/llext.c:168 + 168 *ext = llext_by_name(name); + (gdb) finish + Run till exit from #0 llext_load ([...]) + at zephyr/subsys/llext/llext.c:168 + llext_test_detached () at zephyr/tests/subsys/llext/src/test_llext.c:481 + 481 zassert_ok(res, "load should succeed"); + +The first terminal will have printed lots of debugging information related to +the extension loading. Find the section with the addresses: + +.. code-block:: + :caption: Terminal 1 (build, QEMU emulator, GDB server) + + [...] + D: Allocate and copy regions... + [...] + D: gdb add-symbol-file flags: + D: -s .text 0x20000034 + D: -s .data 0x200000b4 + D: -s .bss 0x2000c2e0 + D: -s .rodata 0x200000b8 + D: -s .detach 0x200001d0 + D: Counting exported symbols... + [...] + +Use these addresses to load the symbols into GDB: + +.. code-block:: + :caption: Terminal 2 (GDB client) + + (gdb) add-symbol-file build/llext/detached_fn_ext_debug.elf -s .text 0x20000034 -s .data 0x200000b4 -s .bss 0x2000c2e0 -s .rodata 0x200000b8 -s .detach 0x200001d0 + add symbol table from file "build/llext/detached_fn_ext_debug.elf" at + .text_addr = 0x20000034 + .data_addr = 0x200000b4 + .bss_addr = 0x2000c2e0 + .rodata_addr = 0x200000b8 + .detach_addr = 0x200001d0 + (y or n) y + Reading symbols from build/llext/detached_fn_ext_debug.elf... + (gdb) break detached_entry + Breakpoint 2 at 0x200001d0 (2 locations) + (gdb) continue + Continuing. + + Breakpoint 2, 0x200001d0 in test_detached_ext () + (gdb) backtrace + #0 0x200001d0 in test_detached_ext () + #1 0x200000ac in test_detached_ext () + #2 0x00000706 in llext_test_detached () at zephyr/tests/subsys/llext/src/test_llext.c:496 + #3 0x00001a36 in run_test_functions (suite=0x92bc , data=0x0 , test=0x92d8 ) at zephyr/subsys/testsuite/ztest/src/ztest.c:328 + #4 test_cb (a=0x92bc , b=0x92d8 , c=0x0 ) at zephyr/subsys/testsuite/ztest/src/ztest.c:662 + #5 0x00000e96 in z_thread_entry (entry=0x1a05 , p1=0x92bc , p2=0x92d8 , p3=0x0 ) at zephyr/lib/os/thread_entry.c:48 + #6 0x00000000 in ?? () + +The symbol associated with the breakpoint location and the last stack frames +mistakenly reference the ELF buffer in the Zephyr application instead of the +extension symbols. Note that GDB however knows both: + +.. code-block:: + :caption: Terminal 2 (GDB client) + + (gdb) info sym 0x200001d0 + test_detached_ext + 464 in section datas of zephyr/build/zephyr/zephyr.elf + detached_entry in section .detach of zephyr/build/llext/detached_fn_ext_debug.elf + (gdb) info sym 0x200000ac + test_detached_ext + 172 in section datas of zephyr/build/zephyr/zephyr.elf + test_entry + 8 in section .text of zephyr/build/llext/detached_fn_ext_debug.elf + +It is also impossible to inspect the variables in the extension or step through +code properly: + +.. code-block:: + :caption: Terminal 2 (GDB client) + + (gdb) print bss_cnt + No symbol "bss_cnt" in current context. + (gdb) print data_cnt + No symbol "data_cnt" in current context. + (gdb) next + Single stepping until exit from function test_detached_ext, + which has no line number information. + + Breakpoint 2, 0x200001ea in test_detached_ext () + (gdb) + +Discarding symbols +------------------ + +Discarding the Zephyr symbols and only focusing on the extension restores full +debugging functionality at the cost of losing the global context (note the +backtrace stops outside the extension): + +.. code-block:: + :caption: Terminal 2 (GDB client) + + (gdb) symbol-file + Discard symbol table from `zephyr/build/zephyr/zephyr.elf'? (y or n) y + Error in re-setting breakpoint 1: No symbol table is loaded. Use the "file" command. + No symbol file now. + (gdb) add-symbol-file build/llext/detached_fn_ext_debug.elf -s .text 0x20000034 -s .data 0x200000b4 -s .bss 0x2000c2e0 -s .rodata 0x200000b8 -s .detach 0x200001d0 + add symbol table from file "build/llext/detached_fn_ext_debug.elf" at + .text_addr = 0x20000034 + .data_addr = 0x200000b4 + .bss_addr = 0x2000c2e0 + .rodata_addr = 0x200000b8 + .detach_addr = 0x200001d0 + (y or n) y + Reading symbols from build/llext/detached_fn_ext_debug.elf... + (gdb) backtrace + #0 detached_entry () at zephyr/tests/subsys/llext/src/detached_fn_ext.c:18 + #1 0x200000ac in test_entry () at zephyr/tests/subsys/llext/src/detached_fn_ext.c:26 + #2 0x00000706 in ?? () + Backtrace stopped: previous frame identical to this frame (corrupt stack?) + (gdb) next + 19 zassert_true(data_cnt < 0); + (gdb) print bss_cnt + $1 = 1 + (gdb) print data_cnt + $2 = -2 + (gdb) + + +Editing the ELF file +-------------------- + +In this alternative approach, the patches to the Zephyr ELF file must be +performed after building the Zephyr binary and starting the emulator on +Terminal 1, but before starting the GDB client on Terminal 2. + +The above debugging session already identified ``test_detached_ext``, the char +array that holds the ELF file, as an offending symbol, so that will be removed +in a first pass. Performing the same steps multiple times, ``__data_start`` and +``__data_region_start`` can also be found to overlap the memory area of +interest. + +The following commands will remove all of these from the Zephyr ELF file, then +start a debugging session on the modified file: + +.. code-block:: + :caption: Terminal 2 (GDB client) + + zephyr$ export LLEXT_SDK_INSTALL_DIR=/opt/zephyr-sdk-0.17.0 + zephyr$ ${LLEXT_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-objcopy -N test_detached_ext -N __data_start -N __data_region_start build/zephyr/zephyr.elf build/zephyr/zephyr-edit.elf + zephyr$ ${LLEXT_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb build/zephyr/zephyr-edit.elf + GNU gdb (Zephyr SDK 0.17.0) 12.1 + [...] + Reading symbols from build/zephyr/zephyr-edit.elf... + (gdb) + +The same steps used in the previous run can be performed again to attach to the +GDB server and load both the extension and its debug symbols. This time, however, +the result is rather different: + + * the ``break`` command includes line number information; + + * the output from ``backtrace`` contains functions from both the extension and + the Zephyr application; + + * the local variables can be properly inspected. + +.. code-block:: + :caption: Terminal 2 (GDB client) + + (gdb) add-symbol-file build/llext/detached_fn_ext_debug.elf [...] + [...] + Reading symbols from build/llext/detached_fn_ext_debug.elf... + (gdb) break detached_entry + Breakpoint 2 at 0x200001d6: file zephyr/tests/subsys/llext/src/detached_fn_ext.c, line 17. + (gdb) continue + Continuing. + + Breakpoint 2, detached_entry () at zephyr/tests/subsys/llext/src/detached_fn_ext.c:17 + 17 printk("bss %u @ %p\n", bss_cnt++, &bss_cnt); + (gdb) backtrace + #0 detached_entry () at zephyr/tests/subsys/llext/src/detached_fn_ext.c:17 + #1 0x200000ac in test_entry () at zephyr/tests/subsys/llext/src/detached_fn_ext.c:26 + #2 0x00000706 in llext_test_detached () at zephyr/tests/subsys/llext/src/test_llext.c:496 + #3 0x00001a36 in run_test_functions (suite=0x92bc , data=0x0 , test=0x92d8 ) at zephyr/subsys/testsuite/ztest/src/ztest.c:328 + #4 test_cb (a=0x92bc , b=0x92d8 , c=0x0 ) at zephyr/subsys/testsuite/ztest/src/ztest.c:662 + #5 0x00000e96 in z_thread_entry (entry=0x1a05 , p1=0x92bc , p2=0x92d8 , p3=0x0 ) at zephyr/lib/os/thread_entry.c:48 + #6 0x00000000 in ?? () + (gdb) print bss_cnt + $1 = 0 + (gdb) print data_cnt + $2 = -3 + (gdb) diff --git a/doc/services/llext/index.rst b/doc/services/llext/index.rst index ebae211d16db0..13bfe78316b21 100644 --- a/doc/services/llext/index.rst +++ b/doc/services/llext/index.rst @@ -16,9 +16,12 @@ and introspected to some degree, as well as unloaded when no longer needed. config build load + debug api .. note:: The LLEXT subsystem requires architecture-specific support. It is currently available only on RISC-V, ARM, ARM64, ARC (experimental) and Xtensa cores. + Harvard architecture cores that separate code and data paths and have no + common memory are not supported. diff --git a/doc/services/llext/load.rst b/doc/services/llext/load.rst index 78fc897b87d43..939f278185d8c 100644 --- a/doc/services/llext/load.rst +++ b/doc/services/llext/load.rst @@ -60,6 +60,10 @@ The returned ``void *`` can then be cast to the appropriate type and used. A wrapper for calling a function with no arguments is provided in :c:func:`llext_call_fn`. +Advanced users that need direct access to areas of the newly loaded extension +may want to refer to :c:func:`llext_get_section_info` and other LLEXT +inspection APIs. + Cleaning up after use ===================== @@ -94,13 +98,7 @@ If any of this happens, the following tips may help understand the issue: the issue. * Use a debugger to inspect the memory and registers to try to understand what - is happening. - - .. note:: - When using GDB, the ``add_symbol_file`` command may be used to load the - debugging information and symbols from the ELF file. Make sure to specify - the proper offset (usually the start of the ``.text`` section, reported - as ``region 0`` in the debug logs.) + is happening. See :ref:`Debugging extensions ` for more details. If the issue persists, please open an issue in the GitHub repository, including all the above information. diff --git a/doc/services/mem_mgmt/index.rst b/doc/services/mem_mgmt/index.rst index 86d36b3961ce3..bcdef9fc3cb43 100644 --- a/doc/services/mem_mgmt/index.rst +++ b/doc/services/mem_mgmt/index.rst @@ -45,7 +45,9 @@ regions out of devicetree defined memory regions, for example: }; See :zephyr_file:`include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h` and -:ref:`arm_cortex_m_developer_guide` for more details about MPU usage. +:ref:`arm_cortex_m_mpu_considerations` in the :ref:`arm_cortex_m_developer_guide` +for more details about MPU usage. Also see :ref:`cache_guide` for details on how +Zephyr handles caching. The conventional and recommended way to deal and manage with memory regions marked with attributes is by using the provided ``mem-attr`` helper library by @@ -61,7 +63,10 @@ and act on regions and attributes (see next section for more details). actual setting for the memory to be set. The user, code or subsystem willing to use this information to do some work (for example creating an MPU region out of the property) must use either the provided ``mem-attr`` library or - the usual devicetree helpers to perform the required work / setting. + the usual devicetree helpers to perform the required work / setting. Note, + however, that for some architectures (such as ARM and ARM64) the MPU driver + uses this information to properly initialize caching at boot. See + :kconfig:option:`CONFIG_ARM_MPU`, :kconfig:option:`CONFIG_RISCV_PMP`, etc. A test for the ``mem-attr`` library and its usage is provided in ``tests/subsys/mem_mgmt/mem_attr/``. diff --git a/doc/services/portability/posix/aep/index.rst b/doc/services/portability/posix/aep/index.rst index 50f96b4c12338..2eed8163c44e7 100644 --- a/doc/services/portability/posix/aep/index.rst +++ b/doc/services/portability/posix/aep/index.rst @@ -63,7 +63,7 @@ The *Minimal Realtime System Profile* (PSE51) includes all of the :ref:`_POSIX_MEMLOCK `, 200809L, :kconfig:option:`CONFIG_POSIX_MEMLOCK` :ref:`†` :ref:`_POSIX_MEMLOCK_RANGE `, 200809L, :kconfig:option:`CONFIG_POSIX_MEMLOCK_RANGE` :ref:`_POSIX_MONOTONIC_CLOCK `, 200809L, :kconfig:option:`CONFIG_POSIX_MONOTONIC_CLOCK` - :ref:`_POSIX_SHARED_MEMORY_OBJECTS `, 200809L, :kconfig:option:`CONFIG_POSIX_SHARED_MEMORY_OBJECTS` + :ref:`_POSIX_SHARED_MEMORY_OBJECTS `, 200809L, :kconfig:option:`CONFIG_POSIX_SHARED_MEMORY_OBJECTS` :ref:`_POSIX_SYNCHRONIZED_IO `, 200809L, :kconfig:option:`CONFIG_POSIX_SYNCHRONIZED_IO` :ref:`_POSIX_THREAD_ATTR_STACKADDR`, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_ATTR_STACKADDR` :ref:`_POSIX_THREAD_ATTR_STACKSIZE`, 200809L, :kconfig:option:`CONFIG_POSIX_THREAD_ATTR_STACKSIZE` diff --git a/doc/services/portability/posix/conformance/index.rst b/doc/services/portability/posix/conformance/index.rst index e809ae08401f8..5581fbaa2bf78 100644 --- a/doc/services/portability/posix/conformance/index.rst +++ b/doc/services/portability/posix/conformance/index.rst @@ -77,7 +77,7 @@ POSIX System Interfaces _POSIX_PRIORITIZED_IO, -1, :ref:`_POSIX_PRIORITY_SCHEDULING`, 200809L, :kconfig:option:`CONFIG_POSIX_PRIORITY_SCHEDULING` :ref:`_POSIX_RAW_SOCKETS`, 200809L, :kconfig:option:`CONFIG_POSIX_RAW_SOCKETS` - :ref:`_POSIX_SHARED_MEMORY_OBJECTS `, 200809L, :kconfig:option:`CONFIG_POSIX_SHARED_MEMORY_OBJECTS` + :ref:`_POSIX_SHARED_MEMORY_OBJECTS `, 200809L, :kconfig:option:`CONFIG_POSIX_SHARED_MEMORY_OBJECTS` _POSIX_SPAWN, -1, :ref:`†` _POSIX_SPORADIC_SERVER, -1, :ref:`†` :ref:`_POSIX_SYNCHRONIZED_IO `, 200809L, :kconfig:option:`CONFIG_POSIX_SYNCHRONIZED_IO` @@ -95,7 +95,7 @@ POSIX System Interfaces _POSIX_TRACE_LOG, -1, _POSIX_TYPED_MEMORY_OBJECTS, -1, _XOPEN_CRYPT, -1, - _XOPEN_REALTIME, -1, + :ref:`_XOPEN_REALTIME `, 700, :kconfig:option:`CONFIG_XSI_REALTIME` _XOPEN_REALTIME_THREADS, -1, :ref:`_XOPEN_STREAMS`, 200809L, :kconfig:option:`CONFIG_XOPEN_STREAMS` _XOPEN_UNIX, -1, diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index e1e2b930cc803..87a21fe7147c7 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -641,6 +641,24 @@ Enable this option group with :kconfig:option:`CONFIG_POSIX_TIMERS`. timer_getoverrun(),yes timer_settime(),yes +.. _posix_option_group_xsi_realtime: + +XSI_REALTIME +++++++++++++ + +The ``XSI_REALTIME`` option group indicates that the :ref:`_POSIX_FSYNC`, +:ref:`_POSIX_MEMLOCK`, +:ref:`_POSIX_MEMLOCK_RANGE`, +:ref:`_POSIX_MESSAGE_PASSING`, +:ref:`_POSIX_PRIORITY_SCHEDULING`, +:ref:`_POSIX_SHARED_MEMORY_OBJECTS`, and +:ref:`_POSIX_SYNCHRONIZED_IO` options are enabled. + +Enable this option group with :kconfig:option:`CONFIG_XSI_REALTIME`. + +When this option group is enabled, the ``_XOPEN_REALTIME`` feature test macro will be defined to a +value other than -1. + .. _posix_option_group_xsi_system_logging: XSI_SYSTEM_LOGGING @@ -866,8 +884,12 @@ Enable this option with :kconfig:option:`CONFIG_POSIX_READER_WRITER_LOCKS`. pthread_rwlockattr_init(),yes pthread_rwlockattr_setpshared(),yes +.. + this link is "deprecated" - mainly left here so that older links still work .. _posix_shared_memory_objects: +.. _posix_option_shared_memory_objects: + _POSIX_SHARED_MEMORY_OBJECTS ++++++++++++++++++++++++++++ diff --git a/doc/services/retention/index.rst b/doc/services/retention/index.rst index 1f6de06eae2fe..7316fb0a5b690 100644 --- a/doc/services/retention/index.rst +++ b/doc/services/retention/index.rst @@ -114,8 +114,8 @@ using: #include #include + const struct device *retention0 = DEVICE_DT_GET(DT_NODELABEL(retention0)); const struct device *retention1 = DEVICE_DT_GET(DT_NODELABEL(retention1)); - const struct device *retention2 = DEVICE_DT_GET(DT_NODELABEL(retention2)); When the write function is called, the magic header and checksum (if enabled) will be set on the area, and it will be marked as valid from that point diff --git a/doc/services/secure_storage.rst b/doc/services/secure_storage.rst deleted file mode 100644 index 5f7b90943b6fd..0000000000000 --- a/doc/services/secure_storage.rst +++ /dev/null @@ -1,119 +0,0 @@ -.. _secure_storage: - -Secure storage -############## - -| The secure storage subsystem provides an implementation of the functions defined in the - `Platform Security Architecture (PSA) Secure Storage API `_. -| It can be enabled on :term:`board targets` - that don't already have an implementation of the API. - -Overview -******** - -The secure storage subsystem makes the PSA Secure Storage API available on all board targets with -non-volatile memory support. -As such, it provides an implementation of the API on those that don't already have one, ensuring -functional support for the API. -Board targets with :ref:`tfm` enabled (ending in ``/ns``), for instance, -cannot enable the subsystem because TF-M already provides an implementation of the API. - -| In addition to providing functional support for the API, depending on - device-specific security features and the configuration, the subsystem - may secure the data stored via the PSA Secure Storage API at rest. -| Keep in mind, however, that it's preferable to use a secure processing environment like TF-M when - possible because it's able to provide more security due to isolation guarantees. - -Limitations -*********** - -The secure storage subsystem's implementation of the PSA Secure Storage API: - -* does not aim at full compliance with the specification. - - | Its foremost goal is functional support for the API on all board targets. - | See below for important ways the implementation deviates from the specification. - -* does not guarantee that the data it stores will be secure at rest in all cases. - - This depends on device-specific security features and the configuration. - -* does not yet provide an implementation of the Protected Storage (PS) API as of this writing. - - Instead, the PS API directly calls into the Internal Trusted Storage (ITS) API - (unless a `custom implementation <#whole-api>`_ of the PS API is provided). - -Below are some ways the implementation deviates from the specification -and an explanation why. This is not an exhaustive list. - -* The data stored in the ITS is by default encrypted and authenticated (Against ``1.`` in - `3.2. Internal Trusted Storage requirements `_.) - - | The specification considers the storage underlying the ITS to be - ``implicitly confidential and protected from replay`` - (`2.4. The Internal Trusted Storage API `_) - because ``most embedded microprocessors (MCU) have on-chip flash storage that can be made - inaccessible except to software running on the MCU`` - (`2.2. Technical Background `_). - | This is not the case on all MCUs. Thus, additional protection is provided to the stored data. - - However, this does not guarantee that the data stored will be secure at rest in all cases, - because this depends on device-specific security features and the configuration. - It requires a random entropy source and especially a secure encryption key provider - (:kconfig:option:`CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER`). - - In addition, the data stored in the ITS is not protected against replay attacks, - because this requires storage that is protected by hardware. - -* The data stored via the PSA Secure Storage API is not protected from direct - read/write by software or debugging. (Against ``2.`` and ``10.`` in - `3.2. Internal Trusted Storage requirements `_.) - - It is only secured at rest. Protecting it at runtime as well - requires specific hardware mechanisms to support this. - -Configuration -************* - -To configure the implementation of the PSA Secure Storage API provided by Zephyr, have a look at the -``CONFIG_SECURE_STORAGE_.*`` Kconfig options. They are defined in the various Kconfig files found -under ``subsys/secure_storage/``. - -Customization -************* - -Custom implementations can also replace those of Zephyr at different levels -if the functionality provided by the existing implementations isn't enough. - -Whole API -========= - -If you already have an implementation of the whole ITS or PS API and want to make use of it, you -can do so by enabling the following Kconfig option and implementing the relevant functions: - -* :kconfig:option:`CONFIG_SECURE_STORAGE_ITS_IMPLEMENTATION_CUSTOM`, for the ITS API. -* :kconfig:option:`CONFIG_SECURE_STORAGE_PS_IMPLEMENTATION_CUSTOM`, for the PS API. - -ITS API -======= - -Zephyr's implementation of the ITS API -(:kconfig:option:`CONFIG_SECURE_STORAGE_ITS_IMPLEMENTATION_ZEPHYR`) -makes use of the ITS transform and store modules, which can be configured and customized separately. -Have a look at the ``CONFIG_SECURE_STORAGE_ITS_(STORE|TRANSFORM)_.*_CUSTOM`` -Kconfig options to see the different customization possibilities. - -It's especially recommended to implement a custom encryption key provider -(:kconfig:option:`CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER_CUSTOM`) -that is more secure than the available options, if possible. - -Samples -******* - -* :zephyr:code-sample:`persistent_key` -* :zephyr:code-sample:`psa_its` - -PSA Secure Storage API reference -******************************** - -.. doxygengroup:: psa_secure_storage diff --git a/doc/services/serialization/nanopb.rst b/doc/services/serialization/nanopb.rst index 79525600ac8f2..9c996af7c729a 100644 --- a/doc/services/serialization/nanopb.rst +++ b/doc/services/serialization/nanopb.rst @@ -45,6 +45,7 @@ Additionally, Nanopb is an optional module and needs to be added explicitly to t west config manifest.project-filter -- +nanopb west update + west packages pip --install Configuration ************* diff --git a/doc/services/shell/images/putty_rtt.png b/doc/services/shell/images/putty_rtt.png new file mode 100644 index 0000000000000..c459ee4104bde Binary files /dev/null and b/doc/services/shell/images/putty_rtt.png differ diff --git a/doc/services/shell/index.rst b/doc/services/shell/index.rst index 8327031e197df..d1aa82dc7a3d0 100644 --- a/doc/services/shell/index.rst +++ b/doc/services/shell/index.rst @@ -122,6 +122,30 @@ To configure Segger RTT backend, add the following configurations to your build: Details on additional configuration settings are captured in: :zephyr_file:`samples/subsys/shell/shell_module/prj_minimal_rtt.conf`. +.. _shell_rtt_putty: + +Using PuTTY +----------- + +Use following procedure: + +* Open debug session and continue running the application. + + .. code-block:: none + + west attach + +* Open ``PuTTY``. Use telnet port 19021 and specific Terminal configuration. Set ``Local echo`` + to ``Force off`` and ``Local line editing`` to ``Force off`` (see image below). + + +.. image:: images/putty_rtt.png + :align: center + :alt: RTT PuTTY terminal configuration. + +* Now you should have a network connection to RTT that will let you enter input + to the shell. + Connecting to Segger RTT via TCP (on macOS, for example) -------------------------------------------------------- @@ -143,7 +167,9 @@ procedure: nc localhost 19021 * Now you should have a network connection to RTT that will let you enter input - to the shell. + to the shell. However, contrary to `PuTTY `_ some features like + ``Tab`` completion do not work. + Commands ******** diff --git a/doc/services/storage/index.rst b/doc/services/storage/index.rst index f6e069ecf2ab1..0fe31e8edccb8 100644 --- a/doc/services/storage/index.rst +++ b/doc/services/storage/index.rst @@ -12,3 +12,5 @@ Storage flash_map/flash_map.rst fcb/fcb.rst stream/stream_flash.rst + secure_storage/index.rst + settings/index.rst diff --git a/doc/services/storage/secure_storage/index.rst b/doc/services/storage/secure_storage/index.rst new file mode 100644 index 0000000000000..83eb7aa4dace2 --- /dev/null +++ b/doc/services/storage/secure_storage/index.rst @@ -0,0 +1,119 @@ +.. _secure_storage: + +Secure Storage +############## + +| The secure storage subsystem provides an implementation of the functions defined in the + `Platform Security Architecture (PSA) Secure Storage API `_. +| It can be enabled on :term:`board targets` + that don't already have an implementation of the API. + +Overview +******** + +The secure storage subsystem makes the PSA Secure Storage API available on all board targets with +non-volatile memory support. +As such, it provides an implementation of the API on those that don't already have one, ensuring +functional support for the API. +Board targets with :ref:`tfm` enabled (ending in ``/ns``), for instance, +cannot enable the subsystem because TF-M already provides an implementation of the API. + +| In addition to providing functional support for the API, depending on + device-specific security features and the configuration, the subsystem + may secure the data stored via the PSA Secure Storage API at rest. +| Keep in mind, however, that it's preferable to use a secure processing environment like TF-M when + possible because it's able to provide more security due to isolation guarantees. + +Limitations +*********** + +The secure storage subsystem's implementation of the PSA Secure Storage API: + +* does not aim at full compliance with the specification. + + | Its foremost goal is functional support for the API on all board targets. + | See below for important ways the implementation deviates from the specification. + +* does not guarantee that the data it stores will be secure at rest in all cases. + + This depends on device-specific security features and the configuration. + +* does not yet provide an implementation of the Protected Storage (PS) API as of this writing. + + Instead, the PS API directly calls into the Internal Trusted Storage (ITS) API + (unless a `custom implementation <#whole-api>`_ of the PS API is provided). + +Below are some ways the implementation deviates from the specification +and an explanation why. This is not an exhaustive list. + +* The data stored in the ITS is by default encrypted and authenticated (Against ``1.`` in + `3.2. Internal Trusted Storage requirements `_.) + + | The specification considers the storage underlying the ITS to be + ``implicitly confidential and protected from replay`` + (`2.4. The Internal Trusted Storage API `_) + because ``most embedded microprocessors (MCU) have on-chip flash storage that can be made + inaccessible except to software running on the MCU`` + (`2.2. Technical Background `_). + | This is not the case on all MCUs. Thus, additional protection is provided to the stored data. + + However, this does not guarantee that the data stored will be secure at rest in all cases, + because this depends on device-specific security features and the configuration. + It requires a random entropy source and especially a secure encryption key provider + (:kconfig:option:`CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER`). + + In addition, the data stored in the ITS is not protected against replay attacks, + because this requires storage that is protected by hardware. + +* The data stored via the PSA Secure Storage API is not protected from direct + read/write by software or debugging. (Against ``2.`` and ``10.`` in + `3.2. Internal Trusted Storage requirements `_.) + + It is only secured at rest. Protecting it at runtime as well + requires specific hardware mechanisms to support this. + +Configuration +************* + +To configure the implementation of the PSA Secure Storage API provided by Zephyr, have a look at the +``CONFIG_SECURE_STORAGE_.*`` Kconfig options. They are defined in the various Kconfig files found +under ``subsys/secure_storage/``. + +Customization +************* + +Custom implementations can also replace those of Zephyr at different levels +if the functionality provided by the existing implementations isn't enough. + +Whole API +========= + +If you already have an implementation of the whole ITS or PS API and want to make use of it, you +can do so by enabling the following Kconfig option and implementing the relevant functions: + +* :kconfig:option:`CONFIG_SECURE_STORAGE_ITS_IMPLEMENTATION_CUSTOM`, for the ITS API. +* :kconfig:option:`CONFIG_SECURE_STORAGE_PS_IMPLEMENTATION_CUSTOM`, for the PS API. + +ITS API +======= + +Zephyr's implementation of the ITS API +(:kconfig:option:`CONFIG_SECURE_STORAGE_ITS_IMPLEMENTATION_ZEPHYR`) +makes use of the ITS transform and store modules, which can be configured and customized separately. +Have a look at the ``CONFIG_SECURE_STORAGE_ITS_(STORE|TRANSFORM)_.*_CUSTOM`` +Kconfig options to see the different customization possibilities. + +It's especially recommended to implement a custom encryption key provider +(:kconfig:option:`CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER_CUSTOM`) +that is more secure than the available options, if possible. + +Samples +******* + +* :zephyr:code-sample:`persistent_key` +* :zephyr:code-sample:`psa_its` + +PSA Secure Storage API reference +******************************** + +.. doxygengroup:: psa_secure_storage diff --git a/doc/services/settings/index.rst b/doc/services/storage/settings/index.rst similarity index 100% rename from doc/services/settings/index.rst rename to doc/services/storage/settings/index.rst diff --git a/doc/services/tracing/index.rst b/doc/services/tracing/index.rst index 45ee08c14328b..61ac2e790ea0c 100644 --- a/doc/services/tracing/index.rst +++ b/doc/services/tracing/index.rst @@ -41,7 +41,7 @@ also provides one generic named tracing function for convenience purposes, as well as to demonstrate how tracing frameworks could be extended. Users can generate a custom trace event by calling -:c:func:`sys_tracing_named_event`, which takes an event name as well as two +:c:func:`sys_trace_named_event`, which takes an event name as well as two arbitrary 4 byte arguments. Tracing backends may truncate the provided event name if it is too long for the serialization format they support. diff --git a/doc/services/zbus/index.rst b/doc/services/zbus/index.rst index 1cc053ce75d7d..0473d7157083a 100644 --- a/doc/services/zbus/index.rst +++ b/doc/services/zbus/index.rst @@ -636,6 +636,34 @@ the defined channels and observers. ZBUS_CHAN_DECLARE(acc_chan, version_chan); +Unique channel identifiers +-------------------------- + +To simplify integrations with external entities, it is possible to assign a unique numeric identifier +to a channel. Users can then retrieve the channel reference by using the identifier with +:c:func:`zbus_chan_from_id`, rather than needing to obtain the reference at compile time with +:c:macro:`ZBUS_CHAN_DECLARE`. Channels using this feature are declared with +:c:func:`ZBUS_CHAN_DEFINE_WITH_ID`. + +.. code-block:: c + + ZBUS_CHAN_DEFINE_WITH_ID(control_chan, /* Name */ + 0x12345678, /* Unique channel identifier */ + struct control_msg, /* Message type */ + control_validator, /* Validator */ + &message_count, /* User data */ + ZBUS_OBSERVERS_EMPTY, /* observers */ + ZBUS_MSG_INIT(.move = 0) /* Initial value */ + ); + + static void channel_retrieve(void) + { + const struct zbus_channel *chan = zbus_chan_from_id(0x12345678); + + ... + } + + Iterating over channels and observers ===================================== diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 2536e2011710c..a4975dbe249c9 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -53,6 +53,7 @@ add_subdirectory_ifdef(CONFIG_I2S i2s) add_subdirectory_ifdef(CONFIG_I3C i3c) add_subdirectory_ifdef(CONFIG_IEEE802154 ieee802154) add_subdirectory_ifdef(CONFIG_INPUT input) +add_subdirectory_ifdef(CONFIG_INTEL_ADSP_MIC_PRIVACY audio/mic_privacy/intel) add_subdirectory_ifdef(CONFIG_IPM ipm) add_subdirectory_ifdef(CONFIG_KSCAN kscan) add_subdirectory_ifdef(CONFIG_LED led) diff --git a/drivers/Kconfig b/drivers/Kconfig index 65f097f2acc97..4819d5059dfbe 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -8,6 +8,7 @@ menu "Device Drivers" # zephyr-keep-sorted-start source "drivers/adc/Kconfig" source "drivers/audio/Kconfig" +source "drivers/audio/mic_privacy/intel/Kconfig.mic_privacy" source "drivers/auxdisplay/Kconfig" source "drivers/bbram/Kconfig" source "drivers/bluetooth/Kconfig" diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index 0877adc5b3d95..5770e9eb3cc8d 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -34,7 +34,8 @@ zephyr_library_sources_ifdef(CONFIG_ADC_GD32 adc_gd32.c) zephyr_library_sources_ifdef(CONFIG_ADC_ADS1112 adc_ads1112.c) zephyr_library_sources_ifdef(CONFIG_ADC_ADS1119 adc_ads1119.c) zephyr_library_sources_ifdef(CONFIG_ADC_ADS7052 adc_ads7052.c) -zephyr_library_sources_ifdef(CONFIG_ADC_ADS114S0X adc_ads114s0x.c) +zephyr_library_sources_ifdef(CONFIG_ADC_ADS1X4S0X adc_ads1x4s0x.c) +zephyr_library_sources_ifdef(CONFIG_ADC_ADS131M02 adc_ads131m02.c) zephyr_library_sources_ifdef(CONFIG_ADC_RPI_PICO adc_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_ADC_XMC4XXX adc_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_ADC_ESP32 adc_esp32.c) @@ -43,7 +44,7 @@ zephyr_library_sources_ifdef(CONFIG_ADC_GECKO_IADC iadc_gecko.c) zephyr_library_sources_ifdef(CONFIG_ADC_INFINEON_CAT1 adc_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_ADC_SMARTBOND_GPADC adc_smartbond_gpadc.c) zephyr_library_sources_ifdef(CONFIG_ADC_SMARTBOND_SDADC adc_smartbond_sdadc.c) -zephyr_library_sources_ifdef(CONFIG_ADC_TLA2021 adc_tla2021.c) +zephyr_library_sources_ifdef(CONFIG_ADC_TLA202X adc_tla202x.c) zephyr_library_sources_ifdef(CONFIG_ADC_NXP_S32_ADC_SAR adc_nxp_s32_adc_sar.c) zephyr_library_sources_ifdef(CONFIG_ADC_MAX1125X adc_max1125x.c) zephyr_library_sources_ifdef(CONFIG_ADC_MAX11102_17 adc_max11102_17.c) @@ -55,3 +56,5 @@ zephyr_library_sources_ifdef(CONFIG_ADC_MCUX_GAU adc_mcux_gau_adc.c) zephyr_library_sources_ifdef(CONFIG_ADC_AMBIQ adc_ambiq.c) zephyr_library_sources_ifdef(CONFIG_ADC_RENESAS_RA adc_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_ADC_MAX32 adc_max32.c) +zephyr_library_sources_ifdef(CONFIG_ADC_AD4114 adc_ad4114.c) +zephyr_library_sources_ifdef(CONFIG_ADC_AD7124 adc_ad7124.c) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index 1e26de71e760f..0266c7f2a8d45 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -100,7 +100,9 @@ source "drivers/adc/Kconfig.ads1119" source "drivers/adc/Kconfig.ads7052" -source "drivers/adc/Kconfig.ads114s0x" +source "drivers/adc/Kconfig.ads1x4s0x" + +source "drivers/adc/Kconfig.ads131m02" source "drivers/adc/Kconfig.rpi_pico" @@ -112,7 +114,7 @@ source "drivers/adc/Kconfig.ifx_cat1" source "drivers/adc/Kconfig.smartbond" -source "drivers/adc/Kconfig.tla2021" +source "drivers/adc/Kconfig.tla202x" source "drivers/adc/Kconfig.nxp_s32" @@ -134,4 +136,8 @@ source "drivers/adc/Kconfig.renesas_ra" source "drivers/adc/Kconfig.max32" +source "drivers/adc/Kconfig.ad4114" + +source "drivers/adc/Kconfig.ad7124" + endif # ADC diff --git a/drivers/adc/Kconfig.ad4114 b/drivers/adc/Kconfig.ad4114 new file mode 100644 index 0000000000000..3f57d23d1ac0a --- /dev/null +++ b/drivers/adc/Kconfig.ad4114 @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Grinn +# SPDX-License-Identifier: Apache-2.0 + +config ADC_AD4114 + bool "AD4114 ADC driver" + default y + depends on DT_HAS_ADI_AD4114_ADC_ENABLED + select SPI + help + Enable the AD4114 ADC driver. + +config ADC_AD4114_ACQUISITION_THREAD_STACK_SIZE + int "Stack size for the ADC data acquisition thread" + depends on ADC_AD4114 + default 512 + help + Size of the stack used for the internal data acquisition + thread. + +config ADC_AD4114_ACQUISITION_THREAD_PRIO + int "Priority for the ADC data acquisition thread" + depends on ADC_AD4114 + default 0 + help + Priority level for the internal ADC data acquisition thread. diff --git a/drivers/adc/Kconfig.ad7124 b/drivers/adc/Kconfig.ad7124 new file mode 100644 index 0000000000000..6344f5c337231 --- /dev/null +++ b/drivers/adc/Kconfig.ad7124 @@ -0,0 +1,25 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config ADC_AD7124 + bool "ADI AD7124 Analog-to-Digital Converter" + default y + depends on DT_HAS_ADI_AD7124_ADC_ENABLED + select SPI + select CRC + select ADC_CONFIGURABLE_INPUTS + help + Enable the ad7124 adc + +config ADI_AD7124_ADC_ACQUISITION_THREAD_INIT_PRIO + int "ADC data acquisition thread priority" + default 0 + depends on ADC_AD7124 && ADC_ASYNC + +config ADI_AD7124_ADC_ACQUISITION_THREAD_STACK_SIZE + int "Stack size for the ADC data acquisition thread" + default 400 + depends on ADC_AD7124 && ADC_ASYNC + help + Size of the stack used for the internal data acquisition + thread. diff --git a/drivers/adc/Kconfig.ads114s0x b/drivers/adc/Kconfig.ads114s0x deleted file mode 100644 index 45191bb92eabd..0000000000000 --- a/drivers/adc/Kconfig.ads114s0x +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2023 SILA Embedded Solutions GmbH -# -# SPDX-License-Identifier: Apache-2.0 - -menuconfig ADC_ADS114S0X - bool "Texas instruments ADS114S0x" - default y - depends on DT_HAS_TI_ADS114S08_ENABLED - select SPI - select ADC_CONFIGURABLE_INPUTS - select ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN - select ADC_CONFIGURABLE_VBIAS_PIN - help - Enable the driver implementation for the ADS114S0X family - -config ADC_ADS114S0X_ASYNC_THREAD_INIT_PRIO - int "ADC ADS114S0x async thread priority" - default 0 - depends on ADC_ADS114S0X - -config ADC_ADS114S0X_ACQUISITION_THREAD_STACK_SIZE - int "Stack size for the ADC data acquisition thread" - default 400 - depends on ADC_ADS114S0X - help - Size of the stack used for the internal data acquisition - thread. - -config ADC_ADS114S0X_GPIO - bool "GPIO support" - default n - depends on GPIO && ADC_ADS114S0X - help - Enable GPIO child device support in the ADS114S0x ADC driver. - - The GPIO functionality is handled by the ADS114S0x GPIO - driver. - -config ADC_ADS114S0X_WAIT_FOR_COMPLETION_TIMEOUT_MS - int "Timeout for wait for completion of a read in ms" - default 1000 - depends on ADC_ADS114S0X - help - This is the wait time in ms until a read is completed. diff --git a/drivers/adc/Kconfig.ads131m02 b/drivers/adc/Kconfig.ads131m02 new file mode 100644 index 0000000000000..23e44f4d53f59 --- /dev/null +++ b/drivers/adc/Kconfig.ads131m02 @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Linumiz +# +# SPDX-License-Identifier: Apache-2.0 + +config ADC_ADS131M02 + bool "Texas instruments ADS131M02" + default y + depends on DT_HAS_TI_ADS131M02_ENABLED + select ADC_CONFIGURABLE_INPUTS + select SPI + select GPIO + help + Enable the driver for ADS131M02 ADC. diff --git a/drivers/adc/Kconfig.ads1x4s0x b/drivers/adc/Kconfig.ads1x4s0x new file mode 100644 index 0000000000000..ecf38cf2de7fb --- /dev/null +++ b/drivers/adc/Kconfig.ads1x4s0x @@ -0,0 +1,45 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# +# SPDX-License-Identifier: Apache-2.0 + +menuconfig ADC_ADS1X4S0X + bool "Texas instruments ADS1X4S0X" + default y + depends on DT_HAS_TI_ADS114S06_ENABLED || DT_HAS_TI_ADS114S08_ENABLED \ + || DT_HAS_TI_ADS124S06_ENABLED || DT_HAS_TI_ADS124S08_ENABLED + select SPI + select ADC_CONFIGURABLE_INPUTS + select ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN + select ADC_CONFIGURABLE_VBIAS_PIN + help + Enable the driver implementation for the ADS1X4S0X family + +config ADC_ADS1X4S0X_ASYNC_THREAD_INIT_PRIO + int "ADC ADS1X4S0X async thread priority" + default 0 + depends on ADC_ADS1X4S0X + +config ADC_ADS1X4S0X_ACQUISITION_THREAD_STACK_SIZE + int "Stack size for the ADC data acquisition thread" + default 400 + depends on ADC_ADS1X4S0X + help + Size of the stack used for the internal data acquisition + thread. + +config ADC_ADS1X4S0X_GPIO + bool "GPIO support" + default n + depends on GPIO && ADC_ADS1X4S0X + help + Enable GPIO child device support in the ADS1X4S0X ADC driver. + + The GPIO functionality is handled by the ADS1X4S0X GPIO + driver. + +config ADC_ADS1X4S0X_WAIT_FOR_COMPLETION_TIMEOUT_MS + int "Timeout for wait for completion of a read in ms" + default 1000 + depends on ADC_ADS1X4S0X + help + This is the wait time in ms until a read is completed. diff --git a/drivers/adc/Kconfig.mcux b/drivers/adc/Kconfig.mcux index 16c6aaf7723ab..1ed2bf75a6bf4 100644 --- a/drivers/adc/Kconfig.mcux +++ b/drivers/adc/Kconfig.mcux @@ -37,11 +37,13 @@ config ADC_MCUX_LPADC help Enable the MCUX LPADC driver. +if ADC_MCUX_12B1MSPS_SAR || ADC_MCUX_LPADC config ADC_MCUX_ETC bool "MCUX ADC ETC driver" depends on HAS_MCUX_ADC_ETC help Enable the MCUX ADC ETC driver. +endif config ADC_MCUX_GAU bool "MCUX GAU ADC driver" diff --git a/drivers/adc/Kconfig.tla2021 b/drivers/adc/Kconfig.tla2021 deleted file mode 100644 index 5f9aa4c60c014..0000000000000 --- a/drivers/adc/Kconfig.tla2021 +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2023 Caspar Friedrich -# SPDX-License-Identifier: Apache-2.0 - -config ADC_TLA2021 - bool "Texas Instruments TLA2021 Low-Power ADC" - default y - depends on DT_HAS_TI_TLA2021_ENABLED - select I2C - help - TLA202x Cost-Optimized, Ultra-Small, 12-Bit, System-Monitoring ADCs - -if ADC_TLA2021 - -config ADC_TLA2021_INIT_PRIORITY - int "Priority for the driver initialization" - default 80 - help - Fine tune the priority for the driver initialization. Make sure it's - higher (-> lower priority) than I2C_INIT_PRIORITY. - -if ADC_ASYNC - -config ADC_TLA2021_ACQUISITION_THREAD_PRIORITY - int "Priority for the data acquisition thread" - default 0 - help - Execution priority for the internal data acquisition thread. - -config ADC_TLA2021_ACQUISITION_THREAD_STACK_SIZE - int "Stack size for the data acquisition thread" - default 512 - help - Stack size for the internal data acquisition thread. Requires room - for I2C operations. - -endif # ADC_ASYNC - -endif # ADC_TLA2021 diff --git a/drivers/adc/Kconfig.tla202x b/drivers/adc/Kconfig.tla202x new file mode 100644 index 0000000000000..89040f2033fbc --- /dev/null +++ b/drivers/adc/Kconfig.tla202x @@ -0,0 +1,41 @@ +# Copyright (c) 2023 Caspar Friedrich +# SPDX-License-Identifier: Apache-2.0 + +config ADC_TLA202X + bool "Texas Instruments TLA202x Low-Power ADC" + default y + depends on DT_HAS_TI_TLA2021_ENABLED \ + || DT_HAS_TI_TLA2022_ENABLED \ + || DT_HAS_TI_TLA2024_ENABLED + select I2C + select ADC_CONFIGURABLE_INPUTS if DT_HAS_TI_TLA2024_ENABLED + help + TLA202x Cost-Optimized, Ultra-Small, 12-Bit, System-Monitoring ADCs + +if ADC_TLA202X + +config ADC_TLA202X_INIT_PRIORITY + int "Priority for the driver initialization" + default 80 + help + Fine tune the priority for the driver initialization. Make sure it's + higher (-> lower priority) than I2C_INIT_PRIORITY. + +if ADC_ASYNC + +config ADC_TLA202X_ACQUISITION_THREAD_PRIORITY + int "Priority for the data acquisition thread" + default 0 + help + Execution priority for the internal data acquisition thread. + +config ADC_TLA202X_ACQUISITION_THREAD_STACK_SIZE + int "Stack size for the data acquisition thread" + default 512 + help + Stack size for the internal data acquisition thread. Requires room + for I2C operations. + +endif # ADC_ASYNC + +endif # ADC_TLA202X diff --git a/drivers/adc/adc_ad4114.c b/drivers/adc/adc_ad4114.c new file mode 100644 index 0000000000000..7623b22761b14 --- /dev/null +++ b/drivers/adc/adc_ad4114.c @@ -0,0 +1,452 @@ +/* + * Copyright (c) 2024 Pierrick Curt + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADC_CONTEXT_USES_KERNEL_TIMER +#include "adc_context.h" + +LOG_MODULE_REGISTER(ADC_AD4114, CONFIG_ADC_LOG_LEVEL); + +#define DT_DRV_COMPAT adi_ad4114_adc + +#define AD4114_CMD_READ 0x40 +#define AD4114_CMD_WRITE 0x0 +#define AD4114_CHAN_NUMBER 16 +#define AD4114_ADC_RESOLUTION 24U + +enum ad4114_reg { + AD4114_STATUS_REG = 0x00, + AD4114_MODE_REG = 0x01, + AD4114_IFMODE_REG = 0x02, + AD4114_REGCHECK = 0x03, + AD4114_DATA_REG = 0x04, + AD4114_GPIOCON_REG = 0x06, + AD4114_ID_REG = 0x07, + AD4114_CHANNEL_0_REG = 0x10, + AD4114_CHANNEL_1_REG = 0x11, + AD4114_CHANNEL_2_REG = 0x12, + AD4114_CHANNEL_3_REG = 0x13, + AD4114_CHANNEL_4_REG = 0x14, + AD4114_CHANNEL_5_REG = 0x15, + AD4114_CHANNEL_6_REG = 0x16, + AD4114_CHANNEL_7_REG = 0x17, + AD4114_CHANNEL_8_REG = 0x18, + AD4114_CHANNEL_9_REG = 0x19, + AD4114_CHANNEL_10_REG = 0x1A, + AD4114_CHANNEL_11_REG = 0x1B, + AD4114_CHANNEL_12_REG = 0x1C, + AD4114_CHANNEL_13_REG = 0x1D, + AD4114_CHANNEL_14_REG = 0x1E, + AD4114_CHANNEL_15_REG = 0x1F, + AD4114_SETUPCON0_REG = 0x20, + AD4114_SETUPCON1_REG = 0x21, + AD4114_SETUPCON2_REG = 0x22, + AD4114_SETUPCON3_REG = 0x23, + AD4114_SETUPCON4_REG = 0x24, + AD4114_SETUPCON5_REG = 0x25, + AD4114_SETUPCON6_REG = 0x26, + AD4114_SETUPCON7_REG = 0x27, + AD4114_FILTCON0_REG = 0x28, + AD4114_FILTCON1_REG = 0x29, + AD4114_FILTCON2_REG = 0x2A, + AD4114_FILTCON3_REG = 0x2B, + AD4114_FILTCON4_REG = 0x2C, + AD4114_FILTCON5_REG = 0x2D, + AD4114_FILTCON6_REG = 0x2E, + AD4114_FILTCON7_REG = 0x2F, + AD4114_OFFSET0_REG = 0x30, + AD4114_OFFSET1_REG = 0x31, + AD4114_OFFSET2_REG = 0x32, + AD4114_OFFSET3_REG = 0x33, + AD4114_OFFSET4_REG = 0x34, + AD4114_OFFSET5_REG = 0x35, + AD4114_OFFSET6_REG = 0x36, + AD4114_OFFSET7_REG = 0x37, + AD4114_GAIN0_REG = 0x38, + AD4114_GAIN1_REG = 0x39, + AD4114_GAIN2_REG = 0x3A, + AD4114_GAIN3_REG = 0x3B, + AD4114_GAIN4_REG = 0x3C, + AD4114_GAIN5_REG = 0x3D, + AD4114_GAIN6_REG = 0x3E, + AD4114_GAIN7_REG = 0x3F, +}; + +struct adc_ad4114_config { + struct spi_dt_spec spi; + uint16_t resolution; + uint16_t map_input[AD4114_CHAN_NUMBER]; +}; + +struct adc_ad4114_data { + struct adc_context ctx; + const struct device *dev; + struct k_thread thread; + struct k_sem sem; + uint16_t channels; + uint16_t channels_cfg; + uint32_t *buffer; + uint32_t *repeat_buffer; + + K_KERNEL_STACK_MEMBER(stack, CONFIG_ADC_AD4114_ACQUISITION_THREAD_STACK_SIZE); +}; + +static int ad4114_write_reg(const struct device *dev, enum ad4114_reg reg_addr, uint8_t *buffer, + size_t reg_size) +{ + int ret; + const struct adc_ad4114_config *config = dev->config; + uint8_t buffer_tx[5] = {0}; /* One byte command, max 4 bytes data */ + + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + + buffer_tx[0] = AD4114_CMD_WRITE | reg_addr; + + if (reg_size > 4) { + LOG_ERR("Invalid size, max data write size is 4"); + return -ENOMEM; + } + /* Fill the data */ + for (uint8_t index = 0; index < reg_size; index++) { + buffer_tx[1 + index] = buffer[index]; + } + + ret = spi_write_dt(&config->spi, &tx); + if (ret != 0) { + LOG_ERR("%s: error writing register 0x%X (%d)", dev->name, reg_addr, ret); + return ret; + } + + return ret; +} + +static int ad4114_read_reg(const struct device *dev, enum ad4114_reg reg_addr, uint8_t *buffer, + size_t reg_size) +{ + int ret; + const struct adc_ad4114_config *config = dev->config; + + uint8_t buffer_tx[6] = {0}; + uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)] = {0xFF}; + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }}; + const struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = ARRAY_SIZE(buffer_rx), + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf), + }; + buffer_tx[0] = AD4114_CMD_READ | reg_addr; + + ret = spi_transceive_dt(&config->spi, &tx, &rx); + if (ret != 0) { + LOG_ERR("%s: error reading register 0x%X (%d)", dev->name, reg_addr, ret); + return ret; + } + + /* Copy received data in output buffer */ + for (uint8_t index = 0; index < reg_size; index++) { + buffer[index] = buffer_rx[index + 1]; + } + + return ret; +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct adc_ad4114_data *data = CONTAINER_OF(ctx, struct adc_ad4114_data, ctx); + + data->channels = ctx->sequence.channels; + data->repeat_buffer = data->buffer; + + k_sem_give(&data->sem); +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) +{ + struct adc_ad4114_data *data = CONTAINER_OF(ctx, struct adc_ad4114_data, ctx); + + if (repeat_sampling) { + data->buffer = data->repeat_buffer; + } +} + +static int adc_ad4114x_validate_buffer_size(const struct device *dev, + const struct adc_sequence *sequence) +{ + uint8_t channels; + size_t needed; + + channels = POPCOUNT(sequence->channels); + needed = channels * sizeof(uint32_t); + + if (sequence->buffer_size < needed) { + return -ENOMEM; + } + + return 0; +} + +static int adc_ad4114_start_read(const struct device *dev, const struct adc_sequence *sequence) +{ + struct adc_ad4114_data *data = dev->data; + const struct adc_ad4114_config *config = dev->config; + int ret; + uint8_t write_reg[2]; + uint8_t status; + + ret = adc_ad4114x_validate_buffer_size(dev, sequence); + if (ret < 0) { + LOG_ERR("insufficient buffer size"); + return ret; + } + + data->channels_cfg = sequence->channels; + for (uint32_t i = 0U; i < AD4114_CHAN_NUMBER; i++) { + if ((BIT(i) & sequence->channels) != 0) { + write_reg[0] = 0x80 | (uint8_t)((config->map_input[i] >> 8) & 0xFF); + write_reg[1] = (uint8_t)(config->map_input[i] & 0xFF); + LOG_DBG("Enable channel %d with mapping %X %X, raw %X", i, write_reg[0], + write_reg[1], config->map_input[i]); + ad4114_write_reg(dev, AD4114_CHANNEL_0_REG + i, write_reg, 2); + } else { + LOG_DBG("Disable channel %d", i); + write_reg[0] = 0x0; + write_reg[1] = 0x0; + ad4114_write_reg(dev, AD4114_CHANNEL_0_REG + i, write_reg, 2); + } + } + + /* Configure the buffer */ + data->buffer = sequence->buffer; + + while ((status & 0x80) != 0x80) { + /* Wait for acquiistion start */ + ad4114_read_reg(dev, AD4114_STATUS_REG, &status, 1); + /* Wait 10us between two status read */ + k_usleep(10); + } + + adc_context_start_read(&data->ctx, sequence); + + return adc_context_wait_for_completion(&data->ctx); +} + +static void adc_ad4114_acquisition_thread(struct adc_ad4114_data *data) +{ + uint8_t value[4] = {0}; + uint32_t buffer_values[AD4114_CHAN_NUMBER]; + bool is_ended = false; + + while (true) { + k_sem_take(&data->sem, K_FOREVER); + + while (data->channels != 0) { + ad4114_read_reg(data->dev, AD4114_DATA_REG, value, 4); + /* Check the read channel */ + if ((value[3] & 0xF0) != 0) { + LOG_DBG("Error read on : %X ", value[3]); + } else { + LOG_DBG("Success read on %d: value %X ", value[3], + (value[2] << 16 | value[1] << 8 | value[0])); + /* success read, store it */ + buffer_values[value[3]] = + (value[0] << 16 | value[1] << 8 | value[2]); + WRITE_BIT(data->channels, value[3], 0); + /* Disable the channel after read success */ + uint8_t write_reg[2] = {0}; + + ad4114_write_reg(data->dev, AD4114_CHANNEL_0_REG + value[3], + write_reg, 2); + } + if (data->channels == 0) { + is_ended = true; + } + /* Wait before next status ready check: the minimal acquisition time for a + * channel is 100us. So wait 10us betwen each check to avoid to use CPU for + * nothing. + */ + k_usleep(10); + } + + if (is_ended) { + is_ended = false; + for (uint8_t i = 0U; i < AD4114_CHAN_NUMBER; i++) { + if ((BIT(i) & data->channels_cfg) != 0) { + *data->buffer++ = buffer_values[i]; + LOG_DBG("Read channel %d value : %X ", i, + buffer_values[i]); + } + } + adc_context_on_sampling_done(&data->ctx, data->dev); + } + /* Wait 1ms before checking if a new sequence acquisition is asked */ + k_usleep(1000); + } +} + +static int adc_ad4114_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + + /* Todo in the futur we can manage here : + * filters + * gain + * offsets + * special configuration : we can update map_input here to override the device + * tree setup + */ + if (channel_cfg->channel_id >= AD4114_CHAN_NUMBER) { + LOG_ERR("invalid channel id %d", channel_cfg->channel_id); + return -EINVAL; + } + return 0; +} + +static int adc_ad4114_read_async(const struct device *dev, const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + struct adc_ad4114_data *data = dev->data; + int ret; + + adc_context_lock(&data->ctx, async ? true : false, async); + ret = adc_ad4114_start_read(dev, sequence); + adc_context_release(&data->ctx, ret); + + return ret; +} + +static int adc_ad4114_read(const struct device *dev, const struct adc_sequence *sequence) +{ + return adc_ad4114_read_async(dev, sequence, NULL); +} + +static int adc_ad4114_init(const struct device *dev) +{ + int err; + const struct adc_ad4114_config *config = dev->config; + struct adc_ad4114_data *data = dev->data; + uint8_t id[2] = {0}; + uint8_t gain[3]; + uint8_t write_reg[2]; + uint8_t status = 0; + k_tid_t tid; + + data->dev = dev; + k_sem_init(&data->sem, 0, 1); + adc_context_init(&data->ctx); + + if (!spi_is_ready_dt(&config->spi)) { + LOG_ERR("spi bus %s not ready", config->spi.bus->name); + return -ENODEV; + } + + ad4114_read_reg(dev, AD4114_ID_REG, id, 2); + /* Check that this is the expected ID : 0x30DX, where x is don’t care */ + if ((((id[0] << 8) | id[1]) & 0xFFF0) != 0x30D0) { + LOG_ERR("Read wrong ID register 0x%X 0x%X", id[0], id[1]); + return -EIO; + } + + ad4114_read_reg(dev, AD4114_STATUS_REG, &status, 1); + LOG_INF("Found AD4114 with status %d", status); + + /* Configure gain to 0x400000 */ + gain[0] = 0x40; + gain[1] = 0x00; + gain[2] = 0x00; + ad4114_write_reg(dev, AD4114_GAIN0_REG, gain, 3); + ad4114_write_reg(dev, AD4114_GAIN1_REG, gain, 3); + + /* Bit 6: DATA_STAT = 1 */ + write_reg[0] = 0x0; + write_reg[1] = 0x40; + ad4114_write_reg(dev, AD4114_IFMODE_REG, write_reg, 2); + + /* Bit 12: BI_UNIPOLARx = 0 + * Bit 9:8 INBUFx = 11 + */ + write_reg[0] = 0x3; + write_reg[1] = 0x0; + ad4114_write_reg(dev, AD4114_SETUPCON0_REG, write_reg, 2); + + /* Bit 12: BI_UNIPOLARx = 1 + * Bit 9:8 INBUFx = 11 + */ + write_reg[0] = 0x13; + write_reg[1] = 0x0; + ad4114_write_reg(dev, AD4114_SETUPCON1_REG, write_reg, 2); + + /* Bit 15: REF_EN = 1 + * Bit 3:2: CLOCKSEL = 11 + */ + write_reg[0] = 0x80; + write_reg[1] = 0xC; + ad4114_write_reg(dev, AD4114_MODE_REG, write_reg, 2); + + tid = k_thread_create(&data->thread, data->stack, K_KERNEL_STACK_SIZEOF(data->stack), + (k_thread_entry_t)adc_ad4114_acquisition_thread, data, NULL, NULL, + CONFIG_ADC_AD4114_ACQUISITION_THREAD_PRIO, 0, K_NO_WAIT); + + if (IS_ENABLED(CONFIG_THREAD_NAME)) { + err = k_thread_name_set(tid, "adc_ad4114"); + if (err < 0) { + return err; + } + } + + adc_context_unlock_unconditionally(&data->ctx); + return 0; +} + +static DEVICE_API(adc, adc_ad4114_api) = { + .channel_setup = adc_ad4114_channel_setup, + .read = adc_ad4114_read, +}; + +#define FILL_MAP_INPUTS(node_id, prop, idx) \ + { \ + .key_index = DT_NODE_CHILD_IDX(node_id), \ + .press_mv = DT_PROP_BY_IDX(node_id, prop, idx), \ + } + +#define ADC_AD4114_DEVICE(inst) \ + static struct adc_ad4114_data adc_ad4114_data_##inst; \ + static const struct adc_ad4114_config adc_ad4114_config_##inst = { \ + .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \ + .resolution = AD4114_ADC_RESOLUTION, \ + .map_input = DT_INST_PROP(inst, map_inputs), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, adc_ad4114_init, NULL, &adc_ad4114_data_##inst, \ + &adc_ad4114_config_##inst, POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ + &adc_ad4114_api) \ + BUILD_ASSERT(DT_INST_PROP_LEN(inst, map_inputs) == AD4114_CHAN_NUMBER); + +DT_INST_FOREACH_STATUS_OKAY(ADC_AD4114_DEVICE) diff --git a/drivers/adc/adc_ad7124.c b/drivers/adc/adc_ad7124.c new file mode 100644 index 0000000000000..ea1a507f2cd36 --- /dev/null +++ b/drivers/adc/adc_ad7124.c @@ -0,0 +1,1377 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_ad7124_adc + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(adc_ad7124, CONFIG_ADC_LOG_LEVEL); + +#define ADC_CONTEXT_USES_KERNEL_TIMER +#include "adc_context.h" + +#define AD7124_MAX_RETURNED_DATA_SIZE 6 +#define AD7124_ADC_VREF_MV 2500U +#define AD7124_RESOLUTION 24 +#define AD7124_SPI_RDY_POLL_CNT 10000 + +/* Maximum number of channels */ +#define AD7124_MAX_CHANNELS 16 +/* Total Number of Setups */ +#define AD7124_MAX_SETUPS 8 + +/* AD7124-4 Standard Device ID */ +#define AD7124_4_STD_ID 0x04 +/* AD7124-4 B Grade Device ID */ +#define AD7124_4_B_GRADE_ID 0x06 +/* Device ID for the re-designed die in the AD7124-4 standard part and B-grade */ +#define AD7124_4_NEW_ID 0x07 + +/* AD7124-8 Standard Device ID */ +#define AD7124_8_STD_ID 0x14 +/* AD7124-8 B and W Grade Device ID */ +#define AD7124_8_B_W_GRADE_ID 0x16 +/* Device ID for the re-designed die in the AD7124-8 standard part, B-grade and W-grade */ +#define AD7124_8_NEW_ID 0x17 + +/* ODR */ +#define ADC_ODR_DEFAULT_VALUE 0xA /* 10SPS */ +#define ADC_ODR_MIN_VALUE 0xA /* 10SPS */ +#define ADC_ODR_LOW_POWER_MAX 0x960 /* 2400SPS */ +#define ADC_ODR_MID_POWER_MAX 0x12C0 /* 4800SPS */ +#define ADC_ODR_HIGH_POWER_MAX 0x4B00 /* 19200SPS */ + +#define ADC_ODR_SEL_BITS_MAX 0x7FF +#define ADC_ODR_SEL_BITS_MIN 0x1 + +/* AD7124 registers */ +#define AD7124_STATUS 0x00 +#define AD7124_ADC_CONTROL 0x01 +#define AD7124_DATA 0x02 +#define AD7124_ID 0x05 +#define AD7124_ERROR 0x06 +#define AD7124_ERROR_EN 0x07 +#define AD7124_CHANNEL(x) (0x09 + (x)) +#define AD7124_CONFIG(x) (0x19 + (x)) +#define AD7124_FILTER(x) (0x21 + (x)) + +/* Configuration Registers 0-7 bits */ +#define AD7124_CFG_REG_BIPOLAR BIT(11) +#define AD7124_CFG_REG_REF_BUFP BIT(8) +#define AD7124_CFG_REG_REF_BUFM BIT(7) +#define AD7124_CFG_REG_AIN_BUFP BIT(6) +#define AD7124_CFG_REG_AINN_BUFM BIT(5) + +#define AD7124_REF_BUF_MSK GENMASK(8, 7) +#define AD7124_AIN_BUF_MSK GENMASK(6, 5) +#define AD7124_SETUP_CONF_REG_REF_SEL_MSK GENMASK(4, 3) +#define AD7124_SETUP_CONF_PGA_MSK GENMASK(2, 0) +#define AD7124_ALL_BUF_MSK GENMASK(8, 0) + +#define AD7124_SETUP_CONFIGURATION_MASK (AD7124_CFG_REG_BIPOLAR | AD7124_ALL_BUF_MSK) + +/* ADC_Control Register bits */ +#define AD7124_ADC_CTRL_REG_DATA_STATUS BIT(10) +#define AD7124_ADC_CTRL_REG_REF_EN BIT(8) + +/* CRC */ +#define AD7124_CRC8_POLYNOMIAL_REPRESENTATION 0x07 /* x8 + x2 + x + 1 */ + +/* Communication Register bits */ +#define AD7124_COMM_REG_WEN (0 << 7) +#define AD7124_COMM_REG_WR (0 << 6) +#define AD7124_COMM_REG_RD BIT(6) +#define AD7124_COMM_REG_RA(x) ((x) & 0x3F) + +/* Filter register bits */ +#define AD7124_FILTER_CONF_REG_FILTER_MSK GENMASK(23, 21) +#define AD7124_FILTER_FS_MSK GENMASK(10, 0) + +/* Channel register bits */ +#define AD7124_CH_MAP_REG_CH_ENABLE BIT(15) +#define AD7124_CHMAP_REG_SETUP_SEL_MSK GENMASK(14, 12) +#define AD7124_CHMAP_REG_AINPOS_MSK GENMASK(9, 5) +#define AD7124_CHMAP_REG_AINNEG_MSK GENMASK(4, 0) + +/* Status register bits */ +#define AD7124_STATUS_REG_RDY BIT(7) +#define AD7124_STATUS_REG_POR_FLAG BIT(4) +#define AD7124_STATUS_REG_CH_ACTIVE(x) ((x) & 0xF) + +/* Error_En register bits */ +#define AD7124_ERREN_REG_SPI_IGNORE_ERR_EN BIT(6) +#define AD7124_ERREN_REG_SPI_CRC_ERR_EN BIT(2) + +/* ADC control register bits */ +#define AD7124_POWER_MODE_MSK GENMASK(7, 6) +#define AD7124_ADC_CTRL_REG_MODE_MSK GENMASK(5, 2) + +/* Error register bits */ +#define AD7124_ERR_REG_SPI_IGNORE_ERR BIT(6) + +enum ad7124_register_lengths { + AD7124_STATUS_REG_LEN = 1, + AD7124_ADC_CONTROL_REG_LEN = 2, + AD7124_DATA_REG_LEN = 3, + AD7124_ID_REG_LEN = 1, + AD7124_ERROR_REG_LEN = 3, + AD7124_ERROR_EN_REG_LEN = 3, + AD7124_CHANNEL_REG_LEN = 2, + AD7124_CONFIG_REG_LEN = 2, + AD7124_FILTER_REG_LEN = 3, +}; + +enum ad7124_mode { + AD7124_CONTINUOUS, + AD7124_SINGLE, + AD7124_STANDBY, + AD7124_POWER_DOWN, + AD7124_IDLE, + AD7124_IN_ZERO_SCALE_OFF, + AD7124_IN_FULL_SCALE_GAIN, + AD7124_SYS_ZERO_SCALE_OFF, + AD7124_SYS_ZERO_SCALE_GAIN, +}; + +enum ad7124_power_mode { + AD7124_LOW_POWER_MODE, + AD7124_MID_POWER_MODE, + AD7124_HIGH_POWER_MODE +}; + +enum adc_ad7124_master_clk_freq_hz { + AD7124_LOW_POWER_CLK = 76800, + AD7124_MID_POWER_CLK = 153600, + AD7124_HIGH_POWER_CLK = 614400, +}; + +enum ad7124_device_type { + ID_AD7124_4, + ID_AD7124_8 +}; + +struct ad7124_control_status { + uint16_t value; + bool is_read; +}; + +enum ad7124_reference_source { + /* External Reference REFIN1+/-*/ + EXTERNAL_REFIN1, + /* External Reference REFIN2+/-*/ + EXTERNAL_REFIN2, + /* Internal 2.5V Reference */ + INTERNAL_REF, + /* AVDD - AVSS */ + AVDD_AVSS, +}; + +enum ad7124_gain { + AD7124_GAIN_1, + AD7124_GAIN_2, + AD7124_GAIN_4, + AD7124_GAIN_8, + AD7124_GAIN_16, + AD7124_GAIN_32, + AD7124_GAIN_64, + AD7124_GAIN_128 +}; + +enum ad7124_filter_type { + AD7124_FILTER_SINC4, + AD7124_FILTER_SINC3 = 2U, +}; + +struct ad7124_config_props { + enum ad7124_reference_source refsel; + enum ad7124_gain pga_bits; + enum ad7124_filter_type filter_type; + uint16_t odr_sel_bits; + bool bipolar; + bool inbuf_enable; + bool refbuf_enable; +}; + +struct ad7124_channel_config { + struct ad7124_config_props props; + uint8_t cfg_slot; + bool live_cfg; +}; + +struct adc_ad7124_config { + struct spi_dt_spec bus; + uint16_t filter_type_mask; + uint16_t bipolar_mask; + uint16_t inbuf_enable_mask; + uint16_t refbuf_enable_mask; + enum ad7124_mode adc_mode; + enum ad7124_power_mode power_mode; + enum ad7124_device_type active_device; + uint8_t resolution; + bool ref_en; +}; + +struct adc_ad7124_data { + const struct device *dev; + struct adc_context ctx; + struct ad7124_control_status adc_control_status; + struct ad7124_channel_config channel_setup_cfg[AD7124_MAX_CHANNELS]; + uint8_t setup_cfg_slots; + struct k_sem acquire_signal; + uint16_t channels; + uint32_t *buffer; + uint32_t *repeat_buffer; + bool crc_enable; + bool spi_ready; +#if CONFIG_ADC_ASYNC + struct k_thread thread; + + K_KERNEL_STACK_MEMBER(stack, CONFIG_ADI_AD7124_ADC_ACQUISITION_THREAD_STACK_SIZE); +#endif /* CONFIG_ADC_ASYNC */ +}; + +static int adc_ad7124_read_reg(const struct device *dev, uint32_t reg, + enum ad7124_register_lengths len, uint32_t *val); + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) +{ + struct adc_ad7124_data *data = CONTAINER_OF(ctx, struct adc_ad7124_data, ctx); + + if (repeat_sampling) { + data->buffer = data->repeat_buffer; + } +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct adc_ad7124_data *data = CONTAINER_OF(ctx, struct adc_ad7124_data, ctx); + + data->repeat_buffer = data->buffer; + k_sem_give(&data->acquire_signal); +} + +static int adc_ad7124_acq_time_to_odr(const struct device *dev, uint16_t acq_time, uint16_t *odr) +{ + const struct adc_ad7124_config *config = dev->config; + uint16_t acquisition_time_value = ADC_ACQ_TIME_VALUE(acq_time); + uint16_t acquisition_time_unit = ADC_ACQ_TIME_UNIT(acq_time); + + /* The AD7124 uses samples per seconds units with the lowest being 10SPS + * regardless of the selected power mode and with acquisition_time only + * having 14b for time, this will not fit within here for microsecond units. + * Use Tick units and allow the user to specify the ODR directly. + */ + + if (acq_time == ADC_ACQ_TIME_DEFAULT) { + *odr = ADC_ODR_DEFAULT_VALUE; + return 0; + } + + if (acquisition_time_unit != ADC_ACQ_TIME_TICKS) { + LOG_ERR("%s: invalid acquisition time %i", dev->name, acquisition_time_value); + return -EINVAL; + } + + if (acquisition_time_value < ADC_ODR_MIN_VALUE) { + LOG_ERR("%s: invalid acquisition time %i", dev->name, acquisition_time_value); + return -EINVAL; + } else if (config->power_mode == AD7124_HIGH_POWER_MODE && + acquisition_time_value > ADC_ODR_HIGH_POWER_MAX) { + LOG_ERR("%s: invalid acquisition time %i", dev->name, acquisition_time_value); + return -EINVAL; + } else if (config->power_mode == AD7124_MID_POWER_MODE && + acquisition_time_value > ADC_ODR_MID_POWER_MAX) { + LOG_ERR("%s: invalid acquisition time %i", dev->name, acquisition_time_value); + return -EINVAL; + } else if (config->power_mode == AD7124_LOW_POWER_MODE && + acquisition_time_value > ADC_ODR_LOW_POWER_MAX) { + LOG_ERR("%s: invalid acquisition time %i", dev->name, acquisition_time_value); + return -EINVAL; + } + + *odr = acquisition_time_value; + + return 0; +} + +static uint16_t adc_ad7124_odr_to_fs(const struct device *dev, int16_t odr) +{ + const struct adc_ad7124_config *config = dev->config; + uint16_t odr_sel_bits; + uint32_t master_clk_freq; + + switch (config->power_mode) { + case AD7124_HIGH_POWER_MODE: + master_clk_freq = AD7124_HIGH_POWER_CLK; + break; + case AD7124_MID_POWER_MODE: + master_clk_freq = AD7124_MID_POWER_CLK; + break; + case AD7124_LOW_POWER_MODE: + master_clk_freq = AD7124_LOW_POWER_CLK; + break; + default: + LOG_ERR("Invalid power mode (%u)", config->power_mode); + return -EINVAL; + } + + odr_sel_bits = DIV_ROUND_CLOSEST(master_clk_freq, odr * 32); + + if (odr_sel_bits < ADC_ODR_SEL_BITS_MIN) { + odr_sel_bits = ADC_ODR_SEL_BITS_MIN; + } else if (odr_sel_bits > ADC_ODR_SEL_BITS_MAX) { + odr_sel_bits = ADC_ODR_SEL_BITS_MAX; + } + + return odr_sel_bits; +} + +static int adc_ad7124_create_new_cfg(const struct device *dev, const struct adc_channel_cfg *cfg, + struct ad7124_channel_config *new_cfg) +{ + const struct adc_ad7124_config *config = dev->config; + uint16_t odr; + enum ad7124_reference_source ref_source; + enum ad7124_gain gain; + int ret; + + if (cfg->channel_id >= AD7124_MAX_CHANNELS) { + LOG_ERR("Invalid channel (%u)", cfg->channel_id); + return -EINVAL; + } + + switch (cfg->reference) { + case ADC_REF_INTERNAL: + ref_source = INTERNAL_REF; + break; + case ADC_REF_EXTERNAL0: + ref_source = EXTERNAL_REFIN1; + break; + case ADC_REF_EXTERNAL1: + ref_source = EXTERNAL_REFIN2; + break; + case ADC_REF_VDD_1: + ref_source = AVDD_AVSS; + break; + default: + LOG_ERR("Invalid reference source (%u)", cfg->reference); + return -EINVAL; + } + + new_cfg->props.refsel = ref_source; + + switch (cfg->gain) { + case ADC_GAIN_1: + gain = AD7124_GAIN_1; + break; + case ADC_GAIN_2: + gain = AD7124_GAIN_2; + break; + case ADC_GAIN_4: + gain = AD7124_GAIN_4; + break; + case ADC_GAIN_8: + gain = AD7124_GAIN_8; + break; + case ADC_GAIN_16: + gain = AD7124_GAIN_16; + break; + case ADC_GAIN_32: + gain = AD7124_GAIN_32; + break; + case ADC_GAIN_64: + gain = AD7124_GAIN_64; + break; + case ADC_GAIN_128: + gain = AD7124_GAIN_128; + break; + default: + LOG_ERR("Invalid gain value (%u)", cfg->gain); + return -EINVAL; + } + + new_cfg->props.pga_bits = gain; + + ret = adc_ad7124_acq_time_to_odr(dev, cfg->acquisition_time, &odr); + if (ret) { + return ret; + } + + if (config->filter_type_mask & BIT(cfg->channel_id)) { + new_cfg->props.filter_type = AD7124_FILTER_SINC3; + } else { + new_cfg->props.filter_type = AD7124_FILTER_SINC4; + } + + new_cfg->props.odr_sel_bits = adc_ad7124_odr_to_fs(dev, odr); + new_cfg->props.bipolar = config->bipolar_mask & BIT(cfg->channel_id); + new_cfg->props.inbuf_enable = config->inbuf_enable_mask & BIT(cfg->channel_id); + new_cfg->props.refbuf_enable = config->refbuf_enable_mask & BIT(cfg->channel_id); + + return 0; +} + +static int adc_ad7124_find_new_slot(const struct device *dev) +{ + struct adc_ad7124_data *data = dev->data; + uint8_t slot = data->setup_cfg_slots; + + int cnt = 0; + + while (slot) { + if ((slot & 0x1) == 0) { + return cnt; + } + slot >>= 1; + cnt++; + } + + if (cnt == AD7124_MAX_SETUPS) { + return -1; + } + + return cnt; +} + +static int adc_ad7124_find_similar_configuration(const struct device *dev, + const struct ad7124_channel_config *cfg, + int channel_id) +{ + struct adc_ad7124_data *data = dev->data; + int similar_channel_index = -1; + + for (int i = 0; i < AD7124_MAX_CHANNELS; i++) { + if (!data->channel_setup_cfg[i].live_cfg && i == channel_id) { + continue; + } + + if (memcmp(&cfg->props, &data->channel_setup_cfg[i].props, + sizeof(struct ad7124_config_props)) == 0) { + similar_channel_index = i; + break; + } + } + + return similar_channel_index; +} + +static int adc_ad7124_wait_for_spi_ready(const struct device *dev) +{ + int ret = 0; + uint32_t read_val = 0; + bool ready = false; + uint16_t spi_ready_try_count = AD7124_SPI_RDY_POLL_CNT; + + while (!ready && --spi_ready_try_count) { + ret = adc_ad7124_read_reg(dev, AD7124_ERROR, AD7124_ERROR_REG_LEN, &read_val); + if (ret) { + return ret; + } + + ready = (read_val & AD7124_ERR_REG_SPI_IGNORE_ERR) == 0; + } + + if (!spi_ready_try_count) { + return -ETIMEDOUT; + } + + return 0; +} + +static int adc_ad7124_read_reg(const struct device *dev, uint32_t reg, + enum ad7124_register_lengths len, uint32_t *val) +{ + const struct adc_ad7124_config *config = dev->config; + struct adc_ad7124_data *data = dev->data; + const struct spi_dt_spec *spec = &config->bus; + + int ret; + uint32_t cntrl_value = 0; + uint8_t add_status_length = 0; + uint8_t buffer_tx[AD7124_MAX_RETURNED_DATA_SIZE] = {0}; + uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)]; + uint8_t crc_check; + + if (reg != AD7124_ERROR && data->spi_ready) { + ret = adc_ad7124_wait_for_spi_ready(dev); + if (ret) { + return ret; + } + } + + if (reg == AD7124_DATA) { + + if (data->adc_control_status.is_read) { + cntrl_value = data->adc_control_status.value; + } else { + ret = adc_ad7124_read_reg(dev, AD7124_ADC_CONTROL, + AD7124_ADC_CONTROL_REG_LEN, &cntrl_value); + if (ret) { + return ret; + } + } + + if (cntrl_value & AD7124_ADC_CTRL_REG_DATA_STATUS) { + add_status_length = 1; + } + } + + struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = 1, + }}; + struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = ((data->crc_enable) ? len + 1 : len) + 1 + add_status_length, + }}; + const struct spi_buf_set tx = {.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)}; + const struct spi_buf_set rx = {.buffers = rx_buf, .count = ARRAY_SIZE(rx_buf)}; + + buffer_tx[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | AD7124_COMM_REG_RA(reg); + + ret = spi_transceive_dt(spec, &tx, &rx); + if (ret) { + return ret; + } + + if (data->crc_enable) { + buffer_rx[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | AD7124_COMM_REG_RA(reg); + + crc_check = crc8(buffer_rx, len + 2 + add_status_length, + AD7124_CRC8_POLYNOMIAL_REPRESENTATION, 0, false); + if (crc_check) { + return -EBADMSG; + } + } + + switch (len) { + case 1: + *val = buffer_rx[1]; + break; + case 2: + *val = sys_get_be16(&buffer_rx[1]); + break; + case 3: + *val = sys_get_be24(&buffer_rx[1]); + break; + default: + return -EINVAL; + } + + if (reg == AD7124_ADC_CONTROL) { + data->adc_control_status.value = *val; + data->adc_control_status.is_read = true; + } + + return 0; +} + +static int adc_ad7124_write_reg(const struct device *dev, uint32_t reg, + enum ad7124_register_lengths len, uint32_t val) +{ + const struct adc_ad7124_config *config = dev->config; + struct adc_ad7124_data *data = dev->data; + const struct spi_dt_spec *spec = &config->bus; + + int ret; + uint8_t buffer_tx[AD7124_MAX_RETURNED_DATA_SIZE] = {0}; + uint8_t crc; + + if (data->spi_ready) { + ret = adc_ad7124_wait_for_spi_ready(dev); + if (ret) { + return ret; + } + } + + buffer_tx[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_WR | AD7124_COMM_REG_RA(reg); + + switch (len) { + case 1: + buffer_tx[1] = val; + break; + case 2: + sys_put_be16(val, &buffer_tx[1]); + break; + case 3: + sys_put_be24(val, &buffer_tx[1]); + break; + default: + return -EINVAL; + } + + if (data->crc_enable) { + crc = crc8(buffer_tx, len + 1, AD7124_CRC8_POLYNOMIAL_REPRESENTATION, 0, false); + buffer_tx[len + 1] = crc; + } + + struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ((data->crc_enable) ? len + 1 : len) + 1, + }}; + + const struct spi_buf_set tx = {.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)}; + + ret = spi_transceive_dt(spec, &tx, NULL); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_reg_write_msk(const struct device *dev, uint32_t reg, + enum ad7124_register_lengths len, uint32_t data, uint32_t mask) +{ + int ret; + uint32_t reg_data; + + ret = adc_ad7124_read_reg(dev, reg, len, ®_data); + if (ret) { + return ret; + } + + reg_data &= ~mask; + reg_data |= data; + + ret = adc_ad7124_write_reg(dev, reg, len, reg_data); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_setup_cfg(const struct device *dev, const struct ad7124_channel_config *cfg) +{ + const struct adc_ad7124_config *config = dev->config; + int ret; + int configuration_setup = 0; + int configuration_mask = 0; + int ref_internal = 0; + + if (cfg->props.bipolar) { + configuration_setup |= AD7124_CFG_REG_BIPOLAR; + } + + if (cfg->props.inbuf_enable) { + configuration_setup |= AD7124_CFG_REG_AIN_BUFP | AD7124_CFG_REG_AINN_BUFM; + } + + if (cfg->props.refbuf_enable) { + configuration_setup |= AD7124_CFG_REG_REF_BUFP | AD7124_CFG_REG_REF_BUFM; + } + + configuration_setup |= FIELD_PREP(AD7124_SETUP_CONF_REG_REF_SEL_MSK, cfg->props.refsel); + configuration_setup |= FIELD_PREP(AD7124_SETUP_CONF_PGA_MSK, cfg->props.pga_bits); + configuration_mask |= AD7124_SETUP_CONFIGURATION_MASK; + + ret = adc_ad7124_reg_write_msk(dev, AD7124_CONFIG(cfg->cfg_slot), AD7124_CONFIG_REG_LEN, + configuration_setup, configuration_mask); + if (ret) { + return ret; + } + + if (config->ref_en) { + ref_internal = AD7124_ADC_CTRL_REG_REF_EN; + } + + if (cfg->props.refsel == INTERNAL_REF) { + ret = adc_ad7124_reg_write_msk(dev, AD7124_ADC_CONTROL, AD7124_ADC_CONTROL_REG_LEN, + ref_internal, AD7124_ADC_CTRL_REG_REF_EN); + if (ret) { + return ret; + } + } + + return 0; +} + +static int adc_ad7124_filter_cfg(const struct device *dev, const struct ad7124_channel_config *cfg) +{ + int filter_setup = 0; + int filter_mask = 0; + int ret; + + filter_setup = FIELD_PREP(AD7124_FILTER_CONF_REG_FILTER_MSK, cfg->props.filter_type) | + FIELD_PREP(AD7124_FILTER_FS_MSK, cfg->props.odr_sel_bits); + filter_mask = AD7124_FILTER_CONF_REG_FILTER_MSK | AD7124_FILTER_FS_MSK; + + /* Set filter type and odr*/ + ret = adc_ad7124_reg_write_msk(dev, AD7124_FILTER(cfg->cfg_slot), AD7124_FILTER_REG_LEN, + filter_setup, filter_mask); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_connect_analog_input(const struct device *dev, uint8_t chn_num, uint8_t ainp, + uint8_t ainm) +{ + int ret; + + ret = adc_ad7124_reg_write_msk(dev, AD7124_CHANNEL(chn_num), AD7124_CHANNEL_REG_LEN, + FIELD_PREP(AD7124_CHMAP_REG_AINPOS_MSK, ainp), + AD7124_CHMAP_REG_AINPOS_MSK); + if (ret) { + return ret; + } + + ret = adc_ad7124_reg_write_msk(dev, AD7124_CHANNEL(chn_num), AD7124_CHANNEL_REG_LEN, + FIELD_PREP(AD7124_CHMAP_REG_AINNEG_MSK, ainm), + AD7124_CHMAP_REG_AINNEG_MSK); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_set_channel_status(const struct device *dev, uint8_t chn_num, + bool channel_status) +{ + int ret; + uint16_t status; + + if (channel_status) { + status = AD7124_CH_MAP_REG_CH_ENABLE; + } else { + status = 0x0U; + } + + ret = adc_ad7124_reg_write_msk(dev, AD7124_CHANNEL(chn_num), AD7124_CHANNEL_REG_LEN, status, + AD7124_CH_MAP_REG_CH_ENABLE); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_channel_cfg(const struct device *dev, const struct adc_channel_cfg *cfg) +{ + struct adc_ad7124_data *data = dev->data; + int ret; + + ret = adc_ad7124_connect_analog_input(dev, cfg->channel_id, cfg->input_positive, + cfg->input_negative); + if (ret) { + return ret; + } + + /* Assign setup */ + ret = adc_ad7124_reg_write_msk( + dev, AD7124_CHANNEL(cfg->channel_id), AD7124_CHANNEL_REG_LEN, + FIELD_PREP(AD7124_CHMAP_REG_SETUP_SEL_MSK, + data->channel_setup_cfg[cfg->channel_id].cfg_slot), + AD7124_CHMAP_REG_SETUP_SEL_MSK); + if (ret) { + return ret; + } + + ret = adc_ad7124_set_channel_status(dev, cfg->channel_id, true); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_channel_setup(const struct device *dev, const struct adc_channel_cfg *cfg) +{ + struct adc_ad7124_data *data = dev->data; + struct ad7124_channel_config new_cfg; + int new_slot; + int ret; + int similar_channel_index; + + data->channel_setup_cfg[cfg->channel_id].live_cfg = false; + + ret = adc_ad7124_create_new_cfg(dev, cfg, &new_cfg); + if (ret) { + return ret; + } + + /* AD7124 supports only 8 different configurations for 16 channels*/ + new_slot = adc_ad7124_find_new_slot(dev); + + if (new_slot == -1) { + similar_channel_index = + adc_ad7124_find_similar_configuration(dev, &new_cfg, cfg->channel_id); + if (similar_channel_index == -1) { + return -EINVAL; + } + new_cfg.cfg_slot = data->channel_setup_cfg[similar_channel_index].cfg_slot; + } else { + new_cfg.cfg_slot = new_slot; + WRITE_BIT(data->setup_cfg_slots, new_slot, true); + } + + new_cfg.live_cfg = true; + + memcpy(&data->channel_setup_cfg[cfg->channel_id], &new_cfg, + sizeof(struct ad7124_channel_config)); + + /* Setup the channel configuration */ + ret = adc_ad7124_setup_cfg(dev, &data->channel_setup_cfg[cfg->channel_id]); + if (ret) { + LOG_ERR("Error setting up configuration"); + return ret; + } + + /* Setup the filter configuration */ + ret = adc_ad7124_filter_cfg(dev, &data->channel_setup_cfg[cfg->channel_id]); + if (ret) { + LOG_ERR("Error setting up filter"); + return ret; + } + + /* Setup the channel */ + ret = adc_ad7124_channel_cfg(dev, cfg); + if (ret) { + LOG_ERR("Error setting up channel"); + return ret; + } + + WRITE_BIT(data->channels, cfg->channel_id, true); + + return 0; +} + +int adc_ad7124_wait_to_power_up(const struct device *dev) +{ + int ret = 0; + uint32_t read_val = 0; + bool powered_on = false; + uint16_t spi_ready_try_count = AD7124_SPI_RDY_POLL_CNT; + + while (!powered_on && --spi_ready_try_count) { + + ret = adc_ad7124_read_reg(dev, AD7124_STATUS, AD7124_STATUS_REG_LEN, &read_val); + if (ret) { + return ret; + } + + powered_on = (read_val & AD7124_STATUS_REG_POR_FLAG) == 0; + } + + if (!spi_ready_try_count) { + return -ETIMEDOUT; + } + + return 0; +} + +int adc_ad7124_reset(const struct device *dev) +{ + const struct adc_ad7124_config *config = dev->config; + const struct spi_dt_spec *spec = &config->bus; + + int ret; + uint8_t buffer_tx[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }}; + + const struct spi_buf_set tx = {.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)}; + + ret = spi_transceive_dt(spec, &tx, NULL); + if (ret) { + return ret; + } + + ret = adc_ad7124_wait_to_power_up(dev); + if (ret) { + return ret; + } + + return ret; +} + +static int adc_ad7124_update_crc(const struct device *dev) +{ + struct adc_ad7124_data *data = dev->data; + + int ret = 0; + uint32_t reg_temp = 0; + + ret = adc_ad7124_read_reg(dev, AD7124_ERROR_EN, AD7124_ERROR_EN_REG_LEN, ®_temp); + if (ret) { + return ret; + } + + if (reg_temp & AD7124_ERREN_REG_SPI_CRC_ERR_EN) { + data->crc_enable = true; + } else { + data->crc_enable = false; + } + + return 0; +} + +static int adc_ad7124_update_spi_check_ready(const struct device *dev) +{ + struct adc_ad7124_data *data = dev->data; + + int ret = 0; + uint32_t reg_temp = 0; + + ret = adc_ad7124_read_reg(dev, AD7124_ERROR_EN, AD7124_ERROR_EN_REG_LEN, ®_temp); + if (ret) { + return ret; + } + + if (reg_temp & AD7124_ERREN_REG_SPI_IGNORE_ERR_EN) { + data->spi_ready = true; + } else { + data->spi_ready = false; + } + + return 0; +} + +static int adc_ad7124_check_chip_id(const struct device *dev) +{ + const struct adc_ad7124_config *config = dev->config; + uint32_t reg_temp = 0; + int ret; + + ret = adc_ad7124_read_reg(dev, AD7124_ID, AD7124_ID_REG_LEN, ®_temp); + if (ret) { + return ret; + } + + if (config->active_device == ID_AD7124_4) { + switch (reg_temp) { + case AD7124_4_STD_ID: + case AD7124_4_B_GRADE_ID: + case AD7124_4_NEW_ID: + break; + + default: + return -ENODEV; + } + } else if (config->active_device == ID_AD7124_8) { + switch (reg_temp) { + case AD7124_8_STD_ID: + case AD7124_8_B_W_GRADE_ID: + case AD7124_8_NEW_ID: + break; + + default: + return -ENODEV; + } + } else { + return -ENODEV; + } + + return 0; +} + +static int adc_ad7124_set_adc_mode(const struct device *dev, enum ad7124_mode adc_mode) +{ + int ret; + + ret = adc_ad7124_reg_write_msk(dev, AD7124_ADC_CONTROL, AD7124_ADC_CONTROL_REG_LEN, + FIELD_PREP(AD7124_ADC_CTRL_REG_MODE_MSK, adc_mode), + AD7124_ADC_CTRL_REG_MODE_MSK); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_set_power_mode(const struct device *dev, enum ad7124_power_mode power_mode) +{ + int ret; + + ret = adc_ad7124_reg_write_msk(dev, AD7124_ADC_CONTROL, AD7124_ADC_CONTROL_REG_LEN, + FIELD_PREP(AD7124_POWER_MODE_MSK, power_mode), + AD7124_POWER_MODE_MSK); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_setup(const struct device *dev) +{ + const struct adc_ad7124_config *config = dev->config; + int ret; + + /* Reset the device interface */ + ret = adc_ad7124_reset(dev); + if (ret) { + return ret; + } + + /* Get CRC State */ + ret = adc_ad7124_update_crc(dev); + if (ret) { + return ret; + } + + ret = adc_ad7124_update_spi_check_ready(dev); + if (ret) { + return ret; + } + + /* Check the device ID */ + ret = adc_ad7124_check_chip_id(dev); + if (ret) { + return ret; + } + + /* Disable channel 0 */ + ret = adc_ad7124_set_channel_status(dev, 0, false); + if (ret) { + return ret; + } + + ret = adc_ad7124_set_adc_mode(dev, config->adc_mode); + if (ret) { + return ret; + } + + ret = adc_ad7124_set_power_mode(dev, config->power_mode); + if (ret) { + return ret; + } + + return 0; +} + +static int adc_ad7124_wait_for_conv_ready(const struct device *dev) +{ + int ret = 0; + uint32_t read_val = 0; + bool ready = false; + uint16_t spi_ready_try_count = AD7124_SPI_RDY_POLL_CNT; + + while (!ready && --spi_ready_try_count) { + + ret = adc_ad7124_read_reg(dev, AD7124_STATUS, AD7124_STATUS_REG_LEN, &read_val); + if (ret) { + return ret; + } + + ready = (read_val & AD7124_STATUS_REG_RDY) == 0; + } + + if (!spi_ready_try_count) { + return -ETIMEDOUT; + } + + return 0; +} + +static bool get_next_ch_idx(uint16_t ch_mask, uint16_t last_idx, uint16_t *new_idx) +{ + last_idx++; + if (last_idx >= AD7124_MAX_CHANNELS) { + return 0; + } + ch_mask >>= last_idx; + if (!ch_mask) { + *new_idx = -1; + return 0; + } + while (!(ch_mask & 1)) { + last_idx++; + ch_mask >>= 1; + } + *new_idx = last_idx; + + return 1; +} + +static int adc_ad7124_get_read_chan_id(const struct device *dev, uint16_t *chan_id) +{ + int ret; + uint32_t reg_temp; + + ret = adc_ad7124_read_reg(dev, AD7124_STATUS, AD7124_STATUS_REG_LEN, ®_temp); + if (ret) { + return ret; + } + + *chan_id = reg_temp & AD7124_STATUS_REG_CH_ACTIVE(0xF); + + return 0; +} + +static int adc_ad7124_perform_read(const struct device *dev) +{ + int ret; + struct adc_ad7124_data *data = dev->data; + uint16_t ch_idx = -1; + uint16_t prev_ch_idx = -1; + uint16_t adc_ch_id = 0; + bool status; + + k_sem_take(&data->acquire_signal, K_FOREVER); + + do { + prev_ch_idx = ch_idx; + + status = get_next_ch_idx(data->ctx.sequence.channels, ch_idx, &ch_idx); + if (!status) { + break; + } + + ret = adc_ad7124_wait_for_conv_ready(dev); + if (ret) { + LOG_ERR("waiting for conversion ready failed"); + adc_context_complete(&data->ctx, ret); + return ret; + } + + ret = adc_ad7124_read_reg(dev, AD7124_DATA, AD7124_DATA_REG_LEN, data->buffer); + if (ret) { + LOG_ERR("reading sample failed"); + adc_context_complete(&data->ctx, ret); + return ret; + } + + ret = adc_ad7124_get_read_chan_id(dev, &adc_ch_id); + if (ret) { + LOG_ERR("reading channel id failed"); + adc_context_complete(&data->ctx, ret); + return ret; + } + + if (ch_idx == adc_ch_id) { + data->buffer++; + } else { + ch_idx = prev_ch_idx; + } + + } while (true); + + adc_context_on_sampling_done(&data->ctx, dev); + + return ret; +} + +static int adc_ad7124_validate_sequence(const struct device *dev, + const struct adc_sequence *sequence) +{ + const struct adc_ad7124_config *config = dev->config; + struct adc_ad7124_data *data = dev->data; + const size_t channel_maximum = 8 * sizeof(sequence->channels); + uint32_t num_requested_channels; + size_t necessary; + + if (sequence->resolution != config->resolution) { + LOG_ERR("invalid resolution"); + return -EINVAL; + } + + if (!sequence->channels) { + LOG_ERR("no channel selected"); + return -EINVAL; + } + + if (sequence->oversampling) { + LOG_ERR("oversampling is not supported"); + return -EINVAL; + } + + num_requested_channels = POPCOUNT(sequence->channels); + necessary = num_requested_channels * sizeof(int32_t); + + if (sequence->options) { + necessary *= (1 + sequence->options->extra_samplings); + } + + if (sequence->buffer_size < necessary) { + LOG_ERR("buffer size %u is too small, need %u", sequence->buffer_size, necessary); + return -ENOMEM; + } + + for (size_t i = 0; i < channel_maximum; ++i) { + if ((BIT(i) & sequence->channels) == 0) { + continue; + } + + if ((BIT(i) & sequence->channels) && !(BIT(i) & data->channels)) { + LOG_ERR("Channel-%d not enabled", i); + return -EINVAL; + } + + if (i >= AD7124_MAX_CHANNELS) { + LOG_ERR("invalid channel selection"); + return -EINVAL; + } + } + + return 0; +} + +static int adc_ad7124_start_read(const struct device *dev, const struct adc_sequence *sequence, + bool wait) +{ + int result; + struct adc_ad7124_data *data = dev->data; + + result = adc_ad7124_validate_sequence(dev, sequence); + if (result != 0) { + LOG_ERR("sequence validation failed"); + return result; + } + + data->buffer = sequence->buffer; + + adc_context_start_read(&data->ctx, sequence); + + if (wait) { + result = adc_context_wait_for_completion(&data->ctx); + } + + return result; +} + +#if CONFIG_ADC_ASYNC +static int adc_ad7124_read_async(const struct device *dev, const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + int status; + struct adc_ad7124_data *data = dev->data; + + adc_context_lock(&data->ctx, true, async); + status = adc_ad7124_start_read(dev, sequence, true); + adc_context_release(&data->ctx, status); + + return status; +} + +static int adc_ad7124_read(const struct device *dev, const struct adc_sequence *sequence) +{ + int status; + struct adc_ad7124_data *data = dev->data; + + adc_context_lock(&data->ctx, false, NULL); + status = adc_ad7124_start_read(dev, sequence, true); + adc_context_release(&data->ctx, status); + + return status; +} + +#else +static int adc_ad7124_read(const struct device *dev, const struct adc_sequence *sequence) +{ + int status; + struct adc_ad7124_data *data = dev->data; + + adc_context_lock(&data->ctx, false, NULL); + + status = adc_ad7124_start_read(dev, sequence, false); + + while (status == 0 && k_sem_take(&data->ctx.sync, K_NO_WAIT) != 0) { + status = adc_ad7124_perform_read(dev); + } + + adc_context_release(&data->ctx, status); + + return status; +} +#endif + +#if CONFIG_ADC_ASYNC +static void adc_ad7124_acquisition_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; + + while (true) { + adc_ad7124_perform_read(dev); + } +} +#endif /* CONFIG_ADC_ASYNC */ + +static int adc_ad7124_init(const struct device *dev) +{ + const struct adc_ad7124_config *config = dev->config; + struct adc_ad7124_data *data = dev->data; + int ret; + + data->dev = dev; + + k_sem_init(&data->acquire_signal, 0, 1); + + if (!spi_is_ready_dt(&config->bus)) { + LOG_ERR("spi bus %s not ready", config->bus.bus->name); + return -ENODEV; + } + + ret = adc_ad7124_setup(dev); + if (ret) { + return ret; + } + +#if CONFIG_ADC_ASYNC + k_tid_t tid = k_thread_create( + &data->thread, data->stack, CONFIG_ADI_AD7124_ADC_ACQUISITION_THREAD_STACK_SIZE, + adc_ad7124_acquisition_thread, (void *)dev, NULL, NULL, + CONFIG_ADI_AD7124_ADC_ACQUISITION_THREAD_INIT_PRIO, 0, K_NO_WAIT); + k_thread_name_set(tid, "adc_ad7124"); +#endif /* CONFIG_ADC_ASYNC */ + + adc_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static DEVICE_API(adc, adc_ad7124_api) = { + .channel_setup = adc_ad7124_channel_setup, + .read = adc_ad7124_read, +#ifdef CONFIG_ADC_ASYNC + .read_async = adc_ad7124_read_async, +#endif + .ref_internal = AD7124_ADC_VREF_MV, +}; + +#define ADC_AD7124_INST_DEFINE(inst) \ + static const struct adc_ad7124_config adc_ad7124_config##inst = { \ + .bus = SPI_DT_SPEC_INST_GET( \ + inst, \ + SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), \ + .resolution = AD7124_RESOLUTION, \ + .filter_type_mask = DT_INST_PROP(inst, filter_type_mask), \ + .bipolar_mask = DT_INST_PROP(inst, bipolar_mask), \ + .inbuf_enable_mask = DT_INST_PROP(inst, inbuf_enable_mask), \ + .refbuf_enable_mask = DT_INST_PROP(inst, refbuf_enable_mask), \ + .adc_mode = DT_INST_PROP(inst, adc_mode), \ + .power_mode = DT_INST_PROP(inst, power_mode), \ + .active_device = DT_INST_PROP(inst, active_device), \ + .ref_en = DT_INST_PROP(inst, reference_enable), \ + }; \ + static struct adc_ad7124_data adc_ad7124_data##inst = { \ + ADC_CONTEXT_INIT_LOCK(adc_ad7124_data##inst, ctx), \ + ADC_CONTEXT_INIT_TIMER(adc_ad7124_data##inst, ctx), \ + ADC_CONTEXT_INIT_SYNC(adc_ad7124_data##inst, ctx), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, adc_ad7124_init, NULL, &adc_ad7124_data##inst, \ + &adc_ad7124_config##inst, POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ + &adc_ad7124_api); + +DT_INST_FOREACH_STATUS_OKAY(ADC_AD7124_INST_DEFINE) diff --git a/drivers/adc/adc_ads114s0x.c b/drivers/adc/adc_ads114s0x.c deleted file mode 100644 index 36e3eaefac4af..0000000000000 --- a/drivers/adc/adc_ads114s0x.c +++ /dev/null @@ -1,1508 +0,0 @@ -/* - * Copyright (c) 2023 SILA Embedded Solutions GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ADC_CONTEXT_USES_KERNEL_TIMER 1 -#define ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT \ - K_MSEC(CONFIG_ADC_ADS114S0X_WAIT_FOR_COMPLETION_TIMEOUT_MS) -#include "adc_context.h" - -LOG_MODULE_REGISTER(ads114s0x, CONFIG_ADC_LOG_LEVEL); - -#define ADS114S0X_CLK_FREQ_IN_KHZ 4096 -#define ADS114S0X_RESET_LOW_TIME_IN_CLOCK_CYCLES 4 -#define ADS114S0X_START_SYNC_PULSE_DURATION_IN_CLOCK_CYCLES 4 -#define ADS114S0X_SETUP_TIME_IN_CLOCK_CYCLES 32 -#define ADS114S0X_INPUT_SELECTION_AINCOM 12 -#define ADS114S0X_RESOLUTION 16 -#define ADS114S0X_REF_INTERNAL 2500 -#define ADS114S0X_GPIO_MAX 3 -#define ADS114S0X_POWER_ON_RESET_TIME_IN_US 2200 -#define ADS114S0X_VBIAS_PIN_MAX 7 -#define ADS114S0X_VBIAS_PIN_MIN 0 - -/* Not mentioned in the datasheet, but instead determined experimentally. */ -#define ADS114S0X_RESET_DELAY_TIME_SAFETY_MARGIN_IN_US 1000 -#define ADS114S0X_RESET_DELAY_TIME_IN_US \ - (4096 * 1000 / ADS114S0X_CLK_FREQ_IN_KHZ + ADS114S0X_RESET_DELAY_TIME_SAFETY_MARGIN_IN_US) - -#define ADS114S0X_RESET_LOW_TIME_IN_US \ - (ADS114S0X_RESET_LOW_TIME_IN_CLOCK_CYCLES * 1000 / ADS114S0X_CLK_FREQ_IN_KHZ) -#define ADS114S0X_START_SYNC_PULSE_DURATION_IN_US \ - (ADS114S0X_START_SYNC_PULSE_DURATION_IN_CLOCK_CYCLES * 1000 / ADS114S0X_CLK_FREQ_IN_KHZ) -#define ADS114S0X_SETUP_TIME_IN_US \ - (ADS114S0X_SETUP_TIME_IN_CLOCK_CYCLES * 1000 / ADS114S0X_CLK_FREQ_IN_KHZ) - -enum ads114s0x_command { - ADS114S0X_COMMAND_NOP = 0x00, - ADS114S0X_COMMAND_WAKEUP = 0x02, - ADS114S0X_COMMAND_POWERDOWN = 0x04, - ADS114S0X_COMMAND_RESET = 0x06, - ADS114S0X_COMMAND_START = 0x08, - ADS114S0X_COMMAND_STOP = 0x0A, - ADS114S0X_COMMAND_SYOCAL = 0x16, - ADS114S0X_COMMAND_SYGCAL = 0x17, - ADS114S0X_COMMAND_SFOCAL = 0x19, - ADS114S0X_COMMAND_RDATA = 0x12, - ADS114S0X_COMMAND_RREG = 0x20, - ADS114S0X_COMMAND_WREG = 0x40, -}; - -enum ads114s0x_register { - ADS114S0X_REGISTER_ID = 0x00, - ADS114S0X_REGISTER_STATUS = 0x01, - ADS114S0X_REGISTER_INPMUX = 0x02, - ADS114S0X_REGISTER_PGA = 0x03, - ADS114S0X_REGISTER_DATARATE = 0x04, - ADS114S0X_REGISTER_REF = 0x05, - ADS114S0X_REGISTER_IDACMAG = 0x06, - ADS114S0X_REGISTER_IDACMUX = 0x07, - ADS114S0X_REGISTER_VBIAS = 0x08, - ADS114S0X_REGISTER_SYS = 0x09, - ADS114S0X_REGISTER_OFCAL0 = 0x0B, - ADS114S0X_REGISTER_OFCAL1 = 0x0C, - ADS114S0X_REGISTER_FSCAL0 = 0x0E, - ADS114S0X_REGISTER_FSCAL1 = 0x0F, - ADS114S0X_REGISTER_GPIODAT = 0x10, - ADS114S0X_REGISTER_GPIOCON = 0x11, -}; - -#define ADS114S0X_REGISTER_GET_VALUE(value, pos, length) \ - FIELD_GET(GENMASK(pos + length - 1, pos), value) -#define ADS114S0X_REGISTER_SET_VALUE(target, value, pos, length) \ - target &= ~GENMASK(pos + length - 1, pos); \ - target |= FIELD_PREP(GENMASK(pos + length - 1, pos), value) - -#define ADS114S0X_REGISTER_ID_DEV_ID_LENGTH 3 -#define ADS114S0X_REGISTER_ID_DEV_ID_POS 0 -#define ADS114S0X_REGISTER_ID_DEV_ID_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_ID_DEV_ID_POS, \ - ADS114S0X_REGISTER_ID_DEV_ID_LENGTH) -#define ADS114S0X_REGISTER_ID_DEV_ID_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_ID_DEV_ID_POS, \ - ADS114S0X_REGISTER_ID_DEV_ID_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_POR_LENGTH 1 -#define ADS114S0X_REGISTER_STATUS_FL_POR_POS 7 -#define ADS114S0X_REGISTER_STATUS_FL_POR_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_POR_POS, \ - ADS114S0X_REGISTER_STATUS_FL_POR_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_POR_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_POR_POS, \ - ADS114S0X_REGISTER_STATUS_FL_POR_LENGTH) -#define ADS114S0X_REGISTER_STATUS_NOT_RDY_LENGTH 1 -#define ADS114S0X_REGISTER_STATUS_NOT_RDY_POS 6 -#define ADS114S0X_REGISTER_STATUS_NOT_RDY_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_NOT_RDY_POS, \ - ADS114S0X_REGISTER_STATUS_NOT_RDY_LENGTH) -#define ADS114S0X_REGISTER_STATUS_NOT_RDY_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_NOT_RDY_POS, \ - ADS114S0X_REGISTER_STATUS_NOT_RDY_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH 1 -#define ADS114S0X_REGISTER_STATUS_FL_P_RAILP_POS 5 -#define ADS114S0X_REGISTER_STATUS_FL_P_RAILP_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_P_RAILP_POS, \ - ADS114S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_P_RAILP_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_P_RAILP_POS, \ - ADS114S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH 1 -#define ADS114S0X_REGISTER_STATUS_FL_P_RAILN_POS 4 -#define ADS114S0X_REGISTER_STATUS_FL_P_RAILN_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_P_RAILN_POS, \ - ADS114S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_P_RAILN_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_P_RAILN_POS, \ - ADS114S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH 1 -#define ADS114S0X_REGISTER_STATUS_FL_N_RAILP_POS 3 -#define ADS114S0X_REGISTER_STATUS_FL_N_RAILP_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_N_RAILP_POS, \ - ADS114S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_N_RAILP_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_N_RAILP_POS, \ - ADS114S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH 1 -#define ADS114S0X_REGISTER_STATUS_FL_N_RAILN_POS 2 -#define ADS114S0X_REGISTER_STATUS_FL_N_RAILN_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_N_RAILN_POS, \ - ADS114S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_N_RAILN_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_N_RAILN_POS, \ - ADS114S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_REF_L1_LENGTH 1 -#define ADS114S0X_REGISTER_STATUS_FL_REF_L1_POS 1 -#define ADS114S0X_REGISTER_STATUS_FL_REF_L1_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_REF_L1_POS, \ - ADS114S0X_REGISTER_STATUS_FL_REF_L1_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_REF_L1_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_REF_L1_POS, \ - ADS114S0X_REGISTER_STATUS_FL_REF_L1_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_REF_L0_LENGTH 1 -#define ADS114S0X_REGISTER_STATUS_FL_REF_L0_POS 0 -#define ADS114S0X_REGISTER_STATUS_FL_REF_L0_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_STATUS_FL_REF_L0_POS, \ - ADS114S0X_REGISTER_STATUS_FL_REF_L0_LENGTH) -#define ADS114S0X_REGISTER_STATUS_FL_REF_L0_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_STATUS_FL_REF_L0_POS, \ - ADS114S0X_REGISTER_STATUS_FL_REF_L0_LENGTH) -#define ADS114S0X_REGISTER_INPMUX_MUXP_LENGTH 4 -#define ADS114S0X_REGISTER_INPMUX_MUXP_POS 4 -#define ADS114S0X_REGISTER_INPMUX_MUXP_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_INPMUX_MUXP_POS, \ - ADS114S0X_REGISTER_INPMUX_MUXP_LENGTH) -#define ADS114S0X_REGISTER_INPMUX_MUXP_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_INPMUX_MUXP_POS, \ - ADS114S0X_REGISTER_INPMUX_MUXP_LENGTH) -#define ADS114S0X_REGISTER_INPMUX_MUXN_LENGTH 4 -#define ADS114S0X_REGISTER_INPMUX_MUXN_POS 0 -#define ADS114S0X_REGISTER_INPMUX_MUXN_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_INPMUX_MUXN_POS, \ - ADS114S0X_REGISTER_INPMUX_MUXN_LENGTH) -#define ADS114S0X_REGISTER_INPMUX_MUXN_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_INPMUX_MUXN_POS, \ - ADS114S0X_REGISTER_INPMUX_MUXN_LENGTH) -#define ADS114S0X_REGISTER_PGA_DELAY_LENGTH 3 -#define ADS114S0X_REGISTER_PGA_DELAY_POS 5 -#define ADS114S0X_REGISTER_PGA_DELAY_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_PGA_DELAY_POS, \ - ADS114S0X_REGISTER_PGA_DELAY_LENGTH) -#define ADS114S0X_REGISTER_PGA_DELAY_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_PGA_DELAY_POS, \ - ADS114S0X_REGISTER_PGA_DELAY_LENGTH) -#define ADS114S0X_REGISTER_PGA_PGA_EN_LENGTH 2 -#define ADS114S0X_REGISTER_PGA_PGA_EN_POS 3 -#define ADS114S0X_REGISTER_PGA_PGA_EN_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_PGA_PGA_EN_POS, \ - ADS114S0X_REGISTER_PGA_PGA_EN_LENGTH) -#define ADS114S0X_REGISTER_PGA_PGA_EN_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_PGA_PGA_EN_POS, \ - ADS114S0X_REGISTER_PGA_PGA_EN_LENGTH) -#define ADS114S0X_REGISTER_PGA_GAIN_LENGTH 3 -#define ADS114S0X_REGISTER_PGA_GAIN_POS 0 -#define ADS114S0X_REGISTER_PGA_GAIN_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_PGA_GAIN_POS, \ - ADS114S0X_REGISTER_PGA_GAIN_LENGTH) -#define ADS114S0X_REGISTER_PGA_GAIN_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_PGA_GAIN_POS, \ - ADS114S0X_REGISTER_PGA_GAIN_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_G_CHOP_LENGTH 1 -#define ADS114S0X_REGISTER_DATARATE_G_CHOP_POS 7 -#define ADS114S0X_REGISTER_DATARATE_G_CHOP_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_G_CHOP_POS, \ - ADS114S0X_REGISTER_DATARATE_G_CHOP_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_G_CHOP_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_G_CHOP_POS, \ - ADS114S0X_REGISTER_DATARATE_G_CHOP_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_CLK_LENGTH 1 -#define ADS114S0X_REGISTER_DATARATE_CLK_POS 6 -#define ADS114S0X_REGISTER_DATARATE_CLK_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_CLK_POS, \ - ADS114S0X_REGISTER_DATARATE_CLK_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_CLK_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_CLK_POS, \ - ADS114S0X_REGISTER_DATARATE_CLK_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_MODE_LENGTH 1 -#define ADS114S0X_REGISTER_DATARATE_MODE_POS 5 -#define ADS114S0X_REGISTER_DATARATE_MODE_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_MODE_POS, \ - ADS114S0X_REGISTER_DATARATE_MODE_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_MODE_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_MODE_POS, \ - ADS114S0X_REGISTER_DATARATE_MODE_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_FILTER_LENGTH 1 -#define ADS114S0X_REGISTER_DATARATE_FILTER_POS 4 -#define ADS114S0X_REGISTER_DATARATE_FILTER_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_FILTER_POS, \ - ADS114S0X_REGISTER_DATARATE_FILTER_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_FILTER_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_FILTER_POS, \ - ADS114S0X_REGISTER_DATARATE_FILTER_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_DR_LENGTH 4 -#define ADS114S0X_REGISTER_DATARATE_DR_POS 0 -#define ADS114S0X_REGISTER_DATARATE_DR_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_DATARATE_DR_POS, \ - ADS114S0X_REGISTER_DATARATE_DR_LENGTH) -#define ADS114S0X_REGISTER_DATARATE_DR_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_DATARATE_DR_POS, \ - ADS114S0X_REGISTER_DATARATE_DR_LENGTH) -#define ADS114S0X_REGISTER_REF_FL_REF_EN_LENGTH 2 -#define ADS114S0X_REGISTER_REF_FL_REF_EN_POS 6 -#define ADS114S0X_REGISTER_REF_FL_REF_EN_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_FL_REF_EN_POS, \ - ADS114S0X_REGISTER_REF_FL_REF_EN_LENGTH) -#define ADS114S0X_REGISTER_REF_FL_REF_EN_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_FL_REF_EN_POS, \ - ADS114S0X_REGISTER_REF_FL_REF_EN_LENGTH) -#define ADS114S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH 1 -#define ADS114S0X_REGISTER_REF_NOT_REFP_BUF_POS 5 -#define ADS114S0X_REGISTER_REF_NOT_REFP_BUF_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_NOT_REFP_BUF_POS, \ - ADS114S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH) -#define ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_NOT_REFP_BUF_POS, \ - ADS114S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH) -#define ADS114S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH 1 -#define ADS114S0X_REGISTER_REF_NOT_REFN_BUF_POS 4 -#define ADS114S0X_REGISTER_REF_NOT_REFN_BUF_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_NOT_REFN_BUF_POS, \ - ADS114S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH) -#define ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_NOT_REFN_BUF_POS, \ - ADS114S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH) -#define ADS114S0X_REGISTER_REF_REFSEL_LENGTH 2 -#define ADS114S0X_REGISTER_REF_REFSEL_POS 2 -#define ADS114S0X_REGISTER_REF_REFSEL_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_REFSEL_POS, \ - ADS114S0X_REGISTER_REF_REFSEL_LENGTH) -#define ADS114S0X_REGISTER_REF_REFSEL_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_REFSEL_POS, \ - ADS114S0X_REGISTER_REF_REFSEL_LENGTH) -#define ADS114S0X_REGISTER_REF_REFCON_LENGTH 2 -#define ADS114S0X_REGISTER_REF_REFCON_POS 0 -#define ADS114S0X_REGISTER_REF_REFCON_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_REF_REFCON_POS, \ - ADS114S0X_REGISTER_REF_REFCON_LENGTH) -#define ADS114S0X_REGISTER_REF_REFCON_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_REF_REFCON_POS, \ - ADS114S0X_REGISTER_REF_REFCON_LENGTH) -#define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH 1 -#define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS 7 -#define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \ - ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH) -#define ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \ - ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH) -#define ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH 1 -#define ADS114S0X_REGISTER_IDACMAG_PSW_POS 6 -#define ADS114S0X_REGISTER_IDACMAG_PSW_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_PSW_POS, \ - ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH) -#define ADS114S0X_REGISTER_IDACMAG_PSW_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_PSW_POS, \ - ADS114S0X_REGISTER_IDACMAG_PSW_LENGTH) -#define ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH 4 -#define ADS114S0X_REGISTER_IDACMAG_IMAG_POS 0 -#define ADS114S0X_REGISTER_IDACMAG_IMAG_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMAG_IMAG_POS, \ - ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH) -#define ADS114S0X_REGISTER_IDACMAG_IMAG_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMAG_IMAG_POS, \ - ADS114S0X_REGISTER_IDACMAG_IMAG_LENGTH) -#define ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH 4 -#define ADS114S0X_REGISTER_IDACMUX_I2MUX_POS 4 -#define ADS114S0X_REGISTER_IDACMUX_I2MUX_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMUX_I2MUX_POS, \ - ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH) -#define ADS114S0X_REGISTER_IDACMUX_I2MUX_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMUX_I2MUX_POS, \ - ADS114S0X_REGISTER_IDACMUX_I2MUX_LENGTH) -#define ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH 4 -#define ADS114S0X_REGISTER_IDACMUX_I1MUX_POS 0 -#define ADS114S0X_REGISTER_IDACMUX_I1MUX_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_IDACMUX_I1MUX_POS, \ - ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH) -#define ADS114S0X_REGISTER_IDACMUX_I1MUX_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_IDACMUX_I1MUX_POS, \ - ADS114S0X_REGISTER_IDACMUX_I1MUX_LENGTH) -#define ADS114S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH 1 -#define ADS114S0X_REGISTER_VBIAS_VB_LEVEL_POS 7 -#define ADS114S0X_REGISTER_VBIAS_VB_LEVEL_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_VBIAS_VB_LEVEL_POS, \ - ADS114S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH) -#define ADS114S0X_REGISTER_VBIAS_VB_LEVEL_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_VBIAS_VB_LEVEL_POS, \ - ADS114S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH) -#define ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH 4 -#define ADS114S0X_REGISTER_GPIODAT_DIR_POS 4 -#define ADS114S0X_REGISTER_GPIODAT_DIR_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIODAT_DIR_POS, \ - ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH) -#define ADS114S0X_REGISTER_GPIODAT_DIR_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIODAT_DIR_POS, \ - ADS114S0X_REGISTER_GPIODAT_DIR_LENGTH) -#define ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH 4 -#define ADS114S0X_REGISTER_GPIODAT_DAT_POS 0 -#define ADS114S0X_REGISTER_GPIODAT_DAT_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIODAT_DAT_POS, \ - ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH) -#define ADS114S0X_REGISTER_GPIODAT_DAT_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIODAT_DAT_POS, \ - ADS114S0X_REGISTER_GPIODAT_DAT_LENGTH) -#define ADS114S0X_REGISTER_GPIOCON_CON_LENGTH 4 -#define ADS114S0X_REGISTER_GPIOCON_CON_POS 0 -#define ADS114S0X_REGISTER_GPIOCON_CON_GET(value) \ - ADS114S0X_REGISTER_GET_VALUE(value, ADS114S0X_REGISTER_GPIOCON_CON_POS, \ - ADS114S0X_REGISTER_GPIOCON_CON_LENGTH) -#define ADS114S0X_REGISTER_GPIOCON_CON_SET(target, value) \ - ADS114S0X_REGISTER_SET_VALUE(target, value, ADS114S0X_REGISTER_GPIOCON_CON_POS, \ - ADS114S0X_REGISTER_GPIOCON_CON_LENGTH) - -/* - * - AIN0 as positive input - * - AIN1 as negative input - */ -#define ADS114S0X_REGISTER_INPMUX_SET_DEFAULTS(target) \ - ADS114S0X_REGISTER_INPMUX_MUXP_SET(target, 0b0000); \ - ADS114S0X_REGISTER_INPMUX_MUXN_SET(target, 0b0001) -/* - * - disable reference monitor - * - enable positive reference buffer - * - disable negative reference buffer - * - use internal reference - * - enable internal voltage reference - */ -#define ADS114S0X_REGISTER_REF_SET_DEFAULTS(target) \ - ADS114S0X_REGISTER_REF_FL_REF_EN_SET(target, 0b00); \ - ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(target, 0b0); \ - ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(target, 0b1); \ - ADS114S0X_REGISTER_REF_REFSEL_SET(target, 0b10); \ - ADS114S0X_REGISTER_REF_REFCON_SET(target, 0b01) -/* - * - disable global chop - * - use internal oscillator - * - single shot conversion mode - * - low latency filter - * - 20 samples per second - */ -#define ADS114S0X_REGISTER_DATARATE_SET_DEFAULTS(target) \ - ADS114S0X_REGISTER_DATARATE_G_CHOP_SET(target, 0b0); \ - ADS114S0X_REGISTER_DATARATE_CLK_SET(target, 0b0); \ - ADS114S0X_REGISTER_DATARATE_MODE_SET(target, 0b1); \ - ADS114S0X_REGISTER_DATARATE_FILTER_SET(target, 0b1); \ - ADS114S0X_REGISTER_DATARATE_DR_SET(target, 0b0100) -/* - * - delay of 14*t_mod - * - disable gain - * - gain 1 - */ -#define ADS114S0X_REGISTER_PGA_SET_DEFAULTS(target) \ - ADS114S0X_REGISTER_PGA_DELAY_SET(target, 0b000); \ - ADS114S0X_REGISTER_PGA_PGA_EN_SET(target, 0b00); \ - ADS114S0X_REGISTER_PGA_GAIN_SET(target, 0b000) -/* - * - disable PGA output rail flag - * - low-side power switch - * - IDAC off - */ -#define ADS114S0X_REGISTER_IDACMAG_SET_DEFAULTS(target) \ - ADS114S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, 0b0); \ - ADS114S0X_REGISTER_IDACMAG_PSW_SET(target, 0b0); \ - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(target, 0b0000) -/* - * - disconnect IDAC1 - * - disconnect IDAC2 - */ -#define ADS114S0X_REGISTER_IDACMUX_SET_DEFAULTS(target) \ - ADS114S0X_REGISTER_IDACMUX_I1MUX_SET(target, 0b1111); \ - ADS114S0X_REGISTER_IDACMUX_I2MUX_SET(target, 0b1111) - -struct ads114s0x_config { - struct spi_dt_spec bus; -#if CONFIG_ADC_ASYNC - k_thread_stack_t *stack; -#endif - const struct gpio_dt_spec gpio_reset; - const struct gpio_dt_spec gpio_data_ready; - const struct gpio_dt_spec gpio_start_sync; - int idac_current; - uint8_t vbias_level; -}; - -struct ads114s0x_data { - struct adc_context ctx; -#if CONFIG_ADC_ASYNC - struct k_thread thread; -#endif /* CONFIG_ADC_ASYNC */ - struct gpio_callback callback_data_ready; - struct k_sem data_ready_signal; - struct k_sem acquire_signal; - int16_t *buffer; - int16_t *buffer_ptr; -#if CONFIG_ADC_ADS114S0X_GPIO - struct k_mutex gpio_lock; - uint8_t gpio_enabled; /* one bit per GPIO, 1 = enabled */ - uint8_t gpio_direction; /* one bit per GPIO, 1 = input */ - uint8_t gpio_value; /* one bit per GPIO, 1 = high */ -#endif /* CONFIG_ADC_ADS114S0X_GPIO */ -}; - -static void ads114s0x_data_ready_handler(const struct device *dev, struct gpio_callback *gpio_cb, - uint32_t pins) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pins); - - struct ads114s0x_data *data = - CONTAINER_OF(gpio_cb, struct ads114s0x_data, callback_data_ready); - - k_sem_give(&data->data_ready_signal); -} - -static int ads114s0x_read_register(const struct device *dev, - enum ads114s0x_register register_address, uint8_t *value) -{ - const struct ads114s0x_config *config = dev->config; - uint8_t buffer_tx[3]; - uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)]; - const struct spi_buf tx_buf[] = {{ - .buf = buffer_tx, - .len = ARRAY_SIZE(buffer_tx), - }}; - const struct spi_buf rx_buf[] = {{ - .buf = buffer_rx, - .len = ARRAY_SIZE(buffer_rx), - }}; - const struct spi_buf_set tx = { - .buffers = tx_buf, - .count = ARRAY_SIZE(tx_buf), - }; - const struct spi_buf_set rx = { - .buffers = rx_buf, - .count = ARRAY_SIZE(rx_buf), - }; - - buffer_tx[0] = ((uint8_t)ADS114S0X_COMMAND_RREG) | ((uint8_t)register_address); - /* read one register */ - buffer_tx[1] = 0x00; - - int result = spi_transceive_dt(&config->bus, &tx, &rx); - - if (result != 0) { - LOG_ERR("%s: spi_transceive failed with error %i", dev->name, result); - return result; - } - - *value = buffer_rx[2]; - LOG_DBG("%s: read from register 0x%02X value 0x%02X", dev->name, register_address, *value); - - return 0; -} - -static int ads114s0x_write_register(const struct device *dev, - enum ads114s0x_register register_address, uint8_t value) -{ - const struct ads114s0x_config *config = dev->config; - uint8_t buffer_tx[3]; - const struct spi_buf tx_buf[] = {{ - .buf = buffer_tx, - .len = ARRAY_SIZE(buffer_tx), - }}; - const struct spi_buf_set tx = { - .buffers = tx_buf, - .count = ARRAY_SIZE(tx_buf), - }; - - buffer_tx[0] = ((uint8_t)ADS114S0X_COMMAND_WREG) | ((uint8_t)register_address); - /* write one register */ - buffer_tx[1] = 0x00; - buffer_tx[2] = value; - - LOG_DBG("%s: writing to register 0x%02X value 0x%02X", dev->name, register_address, value); - int result = spi_write_dt(&config->bus, &tx); - - if (result != 0) { - LOG_ERR("%s: spi_write failed with error %i", dev->name, result); - return result; - } - - return 0; -} - -static int ads114s0x_write_multiple_registers(const struct device *dev, - enum ads114s0x_register *register_addresses, - uint8_t *values, size_t count) -{ - const struct ads114s0x_config *config = dev->config; - uint8_t buffer_tx[2]; - const struct spi_buf tx_buf[] = { - { - .buf = buffer_tx, - .len = ARRAY_SIZE(buffer_tx), - }, - { - .buf = values, - .len = count, - }, - }; - const struct spi_buf_set tx = { - .buffers = tx_buf, - .count = ARRAY_SIZE(tx_buf), - }; - - if (count == 0) { - LOG_WRN("%s: ignoring the command to write 0 registers", dev->name); - return -EINVAL; - } - - buffer_tx[0] = ((uint8_t)ADS114S0X_COMMAND_WREG) | ((uint8_t)register_addresses[0]); - buffer_tx[1] = count - 1; - - LOG_HEXDUMP_DBG(register_addresses, count, "writing to registers"); - LOG_HEXDUMP_DBG(values, count, "values"); - - /* ensure that the register addresses are in the correct order */ - for (size_t i = 1; i < count; ++i) { - __ASSERT(register_addresses[i - 1] + 1 == register_addresses[i], - "register addresses are not consecutive"); - } - - int result = spi_write_dt(&config->bus, &tx); - - if (result != 0) { - LOG_ERR("%s: spi_write failed with error %i", dev->name, result); - return result; - } - - return 0; -} - -static int ads114s0x_send_command(const struct device *dev, enum ads114s0x_command command) -{ - const struct ads114s0x_config *config = dev->config; - uint8_t buffer_tx[1]; - const struct spi_buf tx_buf[] = {{ - .buf = buffer_tx, - .len = ARRAY_SIZE(buffer_tx), - }}; - const struct spi_buf_set tx = { - .buffers = tx_buf, - .count = ARRAY_SIZE(tx_buf), - }; - - buffer_tx[0] = (uint8_t)command; - - LOG_DBG("%s: sending command 0x%02X", dev->name, command); - int result = spi_write_dt(&config->bus, &tx); - - if (result != 0) { - LOG_ERR("%s: spi_write failed with error %i", dev->name, result); - return result; - } - - return 0; -} - -static int ads114s0x_channel_setup(const struct device *dev, - const struct adc_channel_cfg *channel_cfg) -{ - const struct ads114s0x_config *config = dev->config; - uint8_t input_mux = 0; - uint8_t reference_control = 0; - uint8_t data_rate = 0; - uint8_t gain = 0; - uint8_t idac_magnitude = 0; - uint8_t idac_mux = 0; - uint8_t pin_selections[4]; - uint8_t vbias = 0; - size_t pin_selections_size; - int result; - enum ads114s0x_register register_addresses[7]; - uint8_t values[ARRAY_SIZE(register_addresses)]; - uint16_t acquisition_time_value = ADC_ACQ_TIME_VALUE(channel_cfg->acquisition_time); - uint16_t acquisition_time_unit = ADC_ACQ_TIME_UNIT(channel_cfg->acquisition_time); - - ADS114S0X_REGISTER_INPMUX_SET_DEFAULTS(gain); - ADS114S0X_REGISTER_REF_SET_DEFAULTS(reference_control); - ADS114S0X_REGISTER_DATARATE_SET_DEFAULTS(data_rate); - ADS114S0X_REGISTER_PGA_SET_DEFAULTS(gain); - ADS114S0X_REGISTER_IDACMAG_SET_DEFAULTS(idac_magnitude); - ADS114S0X_REGISTER_IDACMUX_SET_DEFAULTS(idac_mux); - - if (channel_cfg->channel_id != 0) { - LOG_ERR("%s: only one channel is supported", dev->name); - return -EINVAL; - } - - /* The ADS114 uses samples per seconds units with the lowest being 2.5SPS - * and with acquisition_time only having 14b for time, this will not fit - * within here for microsecond units. Use Tick units and allow the user to - * specify the ODR directly. - */ - if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT && - acquisition_time_unit != ADC_ACQ_TIME_TICKS) { - LOG_ERR("%s: invalid acquisition time %i", dev->name, - channel_cfg->acquisition_time); - return -EINVAL; - } - - if (channel_cfg->acquisition_time == ADC_ACQ_TIME_DEFAULT) { - ADS114S0X_REGISTER_DATARATE_DR_SET(data_rate, ADS114S0X_CONFIG_DR_20); - } else { - ADS114S0X_REGISTER_DATARATE_DR_SET(data_rate, acquisition_time_value); - } - - switch (channel_cfg->reference) { - case ADC_REF_INTERNAL: - /* disable negative reference buffer */ - ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b1); - /* disable positive reference buffer */ - ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b1); - /* use internal reference */ - ADS114S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b10); - break; - case ADC_REF_EXTERNAL0: - /* enable negative reference buffer */ - ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0); - /* enable positive reference buffer */ - ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0); - /* use external reference 0*/ - ADS114S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b00); - break; - case ADC_REF_EXTERNAL1: - /* enable negative reference buffer */ - ADS114S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0); - /* enable positive reference buffer */ - ADS114S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0); - /* use external reference 0*/ - ADS114S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b01); - break; - default: - LOG_ERR("%s: reference %i is not supported", dev->name, channel_cfg->reference); - return -EINVAL; - } - - if (channel_cfg->differential) { - LOG_DBG("%s: configuring channel for a differential measurement from the pins (p, " - "n) (%i, %i)", - dev->name, channel_cfg->input_positive, channel_cfg->input_negative); - if (channel_cfg->input_positive >= ADS114S0X_INPUT_SELECTION_AINCOM) { - LOG_ERR("%s: positive channel input %i is invalid", dev->name, - channel_cfg->input_positive); - return -EINVAL; - } - - if (channel_cfg->input_negative >= ADS114S0X_INPUT_SELECTION_AINCOM) { - LOG_ERR("%s: negative channel input %i is invalid", dev->name, - channel_cfg->input_negative); - return -EINVAL; - } - - if (channel_cfg->input_positive == channel_cfg->input_negative) { - LOG_ERR("%s: negative and positive channel inputs must be different", - dev->name); - return -EINVAL; - } - - ADS114S0X_REGISTER_INPMUX_MUXP_SET(input_mux, channel_cfg->input_positive); - ADS114S0X_REGISTER_INPMUX_MUXN_SET(input_mux, channel_cfg->input_negative); - pin_selections[0] = channel_cfg->input_positive; - pin_selections[1] = channel_cfg->input_negative; - } else { - LOG_DBG("%s: configuring channel for single ended measurement from input %i", - dev->name, channel_cfg->input_positive); - if (channel_cfg->input_positive >= ADS114S0X_INPUT_SELECTION_AINCOM) { - LOG_ERR("%s: channel input %i is invalid", dev->name, - channel_cfg->input_positive); - return -EINVAL; - } - - ADS114S0X_REGISTER_INPMUX_MUXP_SET(input_mux, channel_cfg->input_positive); - ADS114S0X_REGISTER_INPMUX_MUXN_SET(input_mux, ADS114S0X_INPUT_SELECTION_AINCOM); - pin_selections[0] = channel_cfg->input_positive; - pin_selections[1] = ADS114S0X_INPUT_SELECTION_AINCOM; - } - - switch (channel_cfg->gain) { - case ADC_GAIN_1: - /* set gain value */ - ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b000); - break; - case ADC_GAIN_2: - ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b001); - break; - case ADC_GAIN_4: - ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b010); - break; - case ADC_GAIN_8: - ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b011); - break; - case ADC_GAIN_16: - ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b100); - break; - case ADC_GAIN_32: - ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b101); - break; - case ADC_GAIN_64: - ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b110); - break; - case ADC_GAIN_128: - ADS114S0X_REGISTER_PGA_GAIN_SET(gain, 0b111); - break; - default: - LOG_ERR("%s: gain value %i not supported", dev->name, channel_cfg->gain); - return -EINVAL; - } - - if (channel_cfg->gain != ADC_GAIN_1) { - /* enable gain */ - ADS114S0X_REGISTER_PGA_PGA_EN_SET(gain, 0b01); - } - - switch (config->idac_current) { - case 0: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0000); - break; - case 10: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0001); - break; - case 50: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0010); - break; - case 100: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0011); - break; - case 250: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0100); - break; - case 500: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0101); - break; - case 750: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0110); - break; - case 1000: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0111); - break; - case 1500: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b1000); - break; - case 2000: - ADS114S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b1001); - break; - default: - LOG_ERR("%s: IDAC magnitude %i not supported", dev->name, config->idac_current); - return -EINVAL; - } - - if (channel_cfg->current_source_pin_set) { - LOG_DBG("%s: current source pin set to %i and %i", dev->name, - channel_cfg->current_source_pin[0], channel_cfg->current_source_pin[1]); - if (channel_cfg->current_source_pin[0] > 0b1111) { - LOG_ERR("%s: invalid selection %i for I1MUX", dev->name, - channel_cfg->current_source_pin[0]); - return -EINVAL; - } - - if (channel_cfg->current_source_pin[1] > 0b1111) { - LOG_ERR("%s: invalid selection %i for I2MUX", dev->name, - channel_cfg->current_source_pin[1]); - return -EINVAL; - } - - ADS114S0X_REGISTER_IDACMUX_I1MUX_SET(idac_mux, channel_cfg->current_source_pin[0]); - ADS114S0X_REGISTER_IDACMUX_I2MUX_SET(idac_mux, channel_cfg->current_source_pin[1]); - pin_selections[2] = channel_cfg->current_source_pin[0]; - pin_selections[3] = channel_cfg->current_source_pin[1]; - pin_selections_size = 4; - } else { - LOG_DBG("%s: current source pins not set", dev->name); - pin_selections_size = 2; - } - - for (size_t i = 0; i < pin_selections_size; ++i) { - if (pin_selections[i] > ADS114S0X_INPUT_SELECTION_AINCOM) { - continue; - } - - for (size_t j = i + 1; j < pin_selections_size; ++j) { - if (pin_selections[j] > ADS114S0X_INPUT_SELECTION_AINCOM) { - continue; - } - - if (pin_selections[i] == pin_selections[j]) { - LOG_ERR("%s: pins for inputs and current sources must be different", - dev->name); - return -EINVAL; - } - } - } - - ADS114S0X_REGISTER_VBIAS_VB_LEVEL_SET(vbias, config->vbias_level); - - if ((channel_cfg->vbias_pins & - ~GENMASK(ADS114S0X_VBIAS_PIN_MAX, ADS114S0X_VBIAS_PIN_MIN)) != 0) { - LOG_ERR("%s: invalid VBIAS pin selection 0x%08X", dev->name, - channel_cfg->vbias_pins); - return -EINVAL; - } - - vbias |= channel_cfg->vbias_pins; - - register_addresses[0] = ADS114S0X_REGISTER_INPMUX; - register_addresses[1] = ADS114S0X_REGISTER_PGA; - register_addresses[2] = ADS114S0X_REGISTER_DATARATE; - register_addresses[3] = ADS114S0X_REGISTER_REF; - register_addresses[4] = ADS114S0X_REGISTER_IDACMAG; - register_addresses[5] = ADS114S0X_REGISTER_IDACMUX; - register_addresses[6] = ADS114S0X_REGISTER_VBIAS; - BUILD_ASSERT(ARRAY_SIZE(register_addresses) == 7); - values[0] = input_mux; - values[1] = gain; - values[2] = data_rate; - values[3] = reference_control; - values[4] = idac_magnitude; - values[5] = idac_mux; - values[6] = vbias; - BUILD_ASSERT(ARRAY_SIZE(values) == 7); - - result = ads114s0x_write_multiple_registers(dev, register_addresses, values, - ARRAY_SIZE(values)); - - if (result != 0) { - LOG_ERR("%s: unable to configure registers", dev->name); - return result; - } - - return 0; -} - -static int ads114s0x_validate_buffer_size(const struct adc_sequence *sequence) -{ - size_t needed = sizeof(int16_t); - - if (sequence->options) { - needed *= (1 + sequence->options->extra_samplings); - } - - if (sequence->buffer_size < needed) { - return -ENOMEM; - } - - return 0; -} - -static int ads114s0x_validate_sequence(const struct device *dev, - const struct adc_sequence *sequence) -{ - if (sequence->resolution != ADS114S0X_RESOLUTION) { - LOG_ERR("%s: invalid resolution", dev->name); - return -EINVAL; - } - - if (sequence->channels != BIT(0)) { - LOG_ERR("%s: invalid channel", dev->name); - return -EINVAL; - } - - if (sequence->oversampling) { - LOG_ERR("%s: oversampling is not supported", dev->name); - return -EINVAL; - } - - return ads114s0x_validate_buffer_size(sequence); -} - -static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) -{ - struct ads114s0x_data *data = CONTAINER_OF(ctx, struct ads114s0x_data, ctx); - - if (repeat_sampling) { - data->buffer = data->buffer_ptr; - } -} - -static void adc_context_start_sampling(struct adc_context *ctx) -{ - struct ads114s0x_data *data = CONTAINER_OF(ctx, struct ads114s0x_data, ctx); - - data->buffer_ptr = data->buffer; - k_sem_give(&data->acquire_signal); -} - -static int ads114s0x_adc_start_read(const struct device *dev, const struct adc_sequence *sequence, - bool wait) -{ - int result; - struct ads114s0x_data *data = dev->data; - - result = ads114s0x_validate_sequence(dev, sequence); - - if (result != 0) { - LOG_ERR("%s: sequence validation failed", dev->name); - return result; - } - - data->buffer = sequence->buffer; - - adc_context_start_read(&data->ctx, sequence); - - if (wait) { - result = adc_context_wait_for_completion(&data->ctx); - } - - return result; -} - -static int ads114s0x_send_start_read(const struct device *dev) -{ - const struct ads114s0x_config *config = dev->config; - int result; - - if (config->gpio_start_sync.port == 0) { - result = ads114s0x_send_command(dev, ADS114S0X_COMMAND_START); - if (result != 0) { - LOG_ERR("%s: unable to send START/SYNC command", dev->name); - return result; - } - } else { - result = gpio_pin_set_dt(&config->gpio_start_sync, 1); - - if (result != 0) { - LOG_ERR("%s: unable to start ADC operation", dev->name); - return result; - } - - k_sleep(K_USEC(ADS114S0X_START_SYNC_PULSE_DURATION_IN_US + - ADS114S0X_SETUP_TIME_IN_US)); - - result = gpio_pin_set_dt(&config->gpio_start_sync, 0); - - if (result != 0) { - LOG_ERR("%s: unable to start ADC operation", dev->name); - return result; - } - } - - return 0; -} - -static int ads114s0x_wait_data_ready(const struct device *dev) -{ - struct ads114s0x_data *data = dev->data; - - return k_sem_take(&data->data_ready_signal, ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT); -} - -static int ads114s0x_read_sample(const struct device *dev, uint16_t *buffer) -{ - const struct ads114s0x_config *config = dev->config; - uint8_t buffer_tx[3]; - uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)]; - const struct spi_buf tx_buf[] = {{ - .buf = buffer_tx, - .len = ARRAY_SIZE(buffer_tx), - }}; - const struct spi_buf rx_buf[] = {{ - .buf = buffer_rx, - .len = ARRAY_SIZE(buffer_rx), - }}; - const struct spi_buf_set tx = { - .buffers = tx_buf, - .count = ARRAY_SIZE(tx_buf), - }; - const struct spi_buf_set rx = { - .buffers = rx_buf, - .count = ARRAY_SIZE(rx_buf), - }; - - buffer_tx[0] = (uint8_t)ADS114S0X_COMMAND_RDATA; - - int result = spi_transceive_dt(&config->bus, &tx, &rx); - - if (result != 0) { - LOG_ERR("%s: spi_transceive failed with error %i", dev->name, result); - return result; - } - - *buffer = sys_get_be16(buffer_rx + 1); - LOG_DBG("%s: read ADC sample %i", dev->name, *buffer); - - return 0; -} - -static int ads114s0x_adc_perform_read(const struct device *dev) -{ - int result; - struct ads114s0x_data *data = dev->data; - - k_sem_take(&data->acquire_signal, K_FOREVER); - k_sem_reset(&data->data_ready_signal); - - result = ads114s0x_send_start_read(dev); - if (result != 0) { - LOG_ERR("%s: unable to start ADC conversion", dev->name); - adc_context_complete(&data->ctx, result); - return result; - } - - result = ads114s0x_wait_data_ready(dev); - if (result != 0) { - LOG_ERR("%s: waiting for data to be ready failed", dev->name); - adc_context_complete(&data->ctx, result); - return result; - } - - result = ads114s0x_read_sample(dev, data->buffer); - if (result != 0) { - LOG_ERR("%s: reading sample failed", dev->name); - adc_context_complete(&data->ctx, result); - return result; - } - - data->buffer++; - - adc_context_on_sampling_done(&data->ctx, dev); - - return result; -} - -#if CONFIG_ADC_ASYNC -static int ads114s0x_adc_read_async(const struct device *dev, const struct adc_sequence *sequence, - struct k_poll_signal *async) -{ - int result; - struct ads114s0x_data *data = dev->data; - - adc_context_lock(&data->ctx, true, async); - result = ads114s0x_adc_start_read(dev, sequence, true); - adc_context_release(&data->ctx, result); - - return result; -} - -static int ads114s0x_read(const struct device *dev, const struct adc_sequence *sequence) -{ - int result; - struct ads114s0x_data *data = dev->data; - - adc_context_lock(&data->ctx, false, NULL); - result = ads114s0x_adc_start_read(dev, sequence, true); - adc_context_release(&data->ctx, result); - - return result; -} - -#else -static int ads114s0x_read(const struct device *dev, const struct adc_sequence *sequence) -{ - int result; - struct ads114s0x_data *data = dev->data; - - adc_context_lock(&data->ctx, false, NULL); - result = ads114s0x_adc_start_read(dev, sequence, false); - - while (result == 0 && k_sem_take(&data->ctx.sync, K_NO_WAIT) != 0) { - result = ads114s0x_adc_perform_read(dev); - } - - adc_context_release(&data->ctx, result); - return result; -} -#endif - -#if CONFIG_ADC_ASYNC -static void ads114s0x_acquisition_thread(void *p1, void *p2, void *p3) -{ - ARG_UNUSED(p2); - ARG_UNUSED(p3); - - const struct device *dev = p1; - while (true) { - ads114s0x_adc_perform_read(dev); - } -} -#endif - -#ifdef CONFIG_ADC_ADS114S0X_GPIO -static int ads114s0x_gpio_write_config(const struct device *dev) -{ - struct ads114s0x_data *data = dev->data; - enum ads114s0x_register register_addresses[2]; - uint8_t register_values[ARRAY_SIZE(register_addresses)]; - uint8_t gpio_dat = 0; - uint8_t gpio_con = 0; - - ADS114S0X_REGISTER_GPIOCON_CON_SET(gpio_con, data->gpio_enabled); - ADS114S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value); - ADS114S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction); - - register_values[0] = gpio_dat; - register_values[1] = gpio_con; - register_addresses[0] = ADS114S0X_REGISTER_GPIODAT; - register_addresses[1] = ADS114S0X_REGISTER_GPIOCON; - return ads114s0x_write_multiple_registers(dev, register_addresses, register_values, - ARRAY_SIZE(register_values)); -} - -static int ads114s0x_gpio_write_value(const struct device *dev) -{ - struct ads114s0x_data *data = dev->data; - uint8_t gpio_dat = 0; - - ADS114S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value); - ADS114S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction); - - return ads114s0x_write_register(dev, ADS114S0X_REGISTER_GPIODAT, gpio_dat); -} - -int ads114s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value) -{ - struct ads114s0x_data *data = dev->data; - int result = 0; - - if (pin > ADS114S0X_GPIO_MAX) { - LOG_ERR("%s: invalid pin %i", dev->name, pin); - return -EINVAL; - } - - k_mutex_lock(&data->gpio_lock, K_FOREVER); - - data->gpio_enabled |= BIT(pin); - data->gpio_direction &= ~BIT(pin); - - if (initial_value) { - data->gpio_value |= BIT(pin); - } else { - data->gpio_value &= ~BIT(pin); - } - - result = ads114s0x_gpio_write_config(dev); - - k_mutex_unlock(&data->gpio_lock); - - return result; -} - -int ads114s0x_gpio_set_input(const struct device *dev, uint8_t pin) -{ - struct ads114s0x_data *data = dev->data; - int result = 0; - - if (pin > ADS114S0X_GPIO_MAX) { - LOG_ERR("%s: invalid pin %i", dev->name, pin); - return -EINVAL; - } - - k_mutex_lock(&data->gpio_lock, K_FOREVER); - - data->gpio_enabled |= BIT(pin); - data->gpio_direction |= BIT(pin); - data->gpio_value &= ~BIT(pin); - - result = ads114s0x_gpio_write_config(dev); - - k_mutex_unlock(&data->gpio_lock); - - return result; -} - -int ads114s0x_gpio_deconfigure(const struct device *dev, uint8_t pin) -{ - struct ads114s0x_data *data = dev->data; - int result = 0; - - if (pin > ADS114S0X_GPIO_MAX) { - LOG_ERR("%s: invalid pin %i", dev->name, pin); - return -EINVAL; - } - - k_mutex_lock(&data->gpio_lock, K_FOREVER); - - data->gpio_enabled &= ~BIT(pin); - data->gpio_direction |= BIT(pin); - data->gpio_value &= ~BIT(pin); - - result = ads114s0x_gpio_write_config(dev); - - k_mutex_unlock(&data->gpio_lock); - - return result; -} - -int ads114s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin, bool value) -{ - struct ads114s0x_data *data = dev->data; - int result = 0; - - if (pin > ADS114S0X_GPIO_MAX) { - LOG_ERR("%s: invalid pin %i", dev->name, pin); - return -EINVAL; - } - - k_mutex_lock(&data->gpio_lock, K_FOREVER); - - if ((BIT(pin) & data->gpio_enabled) == 0) { - LOG_ERR("%s: gpio pin %i not configured", dev->name, pin); - result = -EINVAL; - } else if ((BIT(pin) & data->gpio_direction) != 0) { - LOG_ERR("%s: gpio pin %i not configured as output", dev->name, pin); - result = -EINVAL; - } else { - data->gpio_value |= BIT(pin); - - result = ads114s0x_gpio_write_value(dev); - } - - k_mutex_unlock(&data->gpio_lock); - - return result; -} - -int ads114s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin, bool *value) -{ - struct ads114s0x_data *data = dev->data; - int result = 0; - uint8_t gpio_dat; - - if (pin > ADS114S0X_GPIO_MAX) { - LOG_ERR("%s: invalid pin %i", dev->name, pin); - return -EINVAL; - } - - k_mutex_lock(&data->gpio_lock, K_FOREVER); - - if ((BIT(pin) & data->gpio_enabled) == 0) { - LOG_ERR("%s: gpio pin %i not configured", dev->name, pin); - result = -EINVAL; - } else if ((BIT(pin) & data->gpio_direction) == 0) { - LOG_ERR("%s: gpio pin %i not configured as input", dev->name, pin); - result = -EINVAL; - } else { - result = ads114s0x_read_register(dev, ADS114S0X_REGISTER_GPIODAT, &gpio_dat); - data->gpio_value = ADS114S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat); - *value = (BIT(pin) & data->gpio_value) != 0; - } - - k_mutex_unlock(&data->gpio_lock); - - return result; -} - -int ads114s0x_gpio_port_get_raw(const struct device *dev, gpio_port_value_t *value) -{ - struct ads114s0x_data *data = dev->data; - int result = 0; - uint8_t gpio_dat; - - k_mutex_lock(&data->gpio_lock, K_FOREVER); - - result = ads114s0x_read_register(dev, ADS114S0X_REGISTER_GPIODAT, &gpio_dat); - data->gpio_value = ADS114S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat); - *value = data->gpio_value; - - k_mutex_unlock(&data->gpio_lock); - - return result; -} - -int ads114s0x_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, - gpio_port_value_t value) -{ - struct ads114s0x_data *data = dev->data; - int result = 0; - - k_mutex_lock(&data->gpio_lock, K_FOREVER); - - data->gpio_value = ((data->gpio_value & ~mask) | (mask & value)) & data->gpio_enabled & - ~data->gpio_direction; - result = ads114s0x_gpio_write_value(dev); - - k_mutex_unlock(&data->gpio_lock); - - return result; -} - -int ads114s0x_gpio_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) -{ - struct ads114s0x_data *data = dev->data; - int result = 0; - - k_mutex_lock(&data->gpio_lock, K_FOREVER); - - data->gpio_value = (data->gpio_value ^ pins) & data->gpio_enabled & ~data->gpio_direction; - result = ads114s0x_gpio_write_value(dev); - - k_mutex_unlock(&data->gpio_lock); - - return result; -} - -#endif /* CONFIG_ADC_ADS114S0X_GPIO */ - -static int ads114s0x_init(const struct device *dev) -{ - uint8_t status = 0; - uint8_t reference_control = 0; - uint8_t reference_control_read; - int result; - const struct ads114s0x_config *config = dev->config; - struct ads114s0x_data *data = dev->data; - - adc_context_init(&data->ctx); - - k_sem_init(&data->data_ready_signal, 0, 1); - k_sem_init(&data->acquire_signal, 0, 1); - -#ifdef CONFIG_ADC_ADS114S0X_GPIO - k_mutex_init(&data->gpio_lock); -#endif /* CONFIG_ADC_ADS114S0X_GPIO */ - - if (!spi_is_ready_dt(&config->bus)) { - LOG_ERR("%s: SPI device is not ready", dev->name); - return -ENODEV; - } - - if (config->gpio_reset.port != NULL) { - result = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE); - if (result != 0) { - LOG_ERR("%s: failed to initialize GPIO for reset", dev->name); - return result; - } - } - - if (config->gpio_start_sync.port != NULL) { - result = gpio_pin_configure_dt(&config->gpio_start_sync, GPIO_OUTPUT_INACTIVE); - if (result != 0) { - LOG_ERR("%s: failed to initialize GPIO for start/sync", dev->name); - return result; - } - } - - result = gpio_pin_configure_dt(&config->gpio_data_ready, GPIO_INPUT); - if (result != 0) { - LOG_ERR("%s: failed to initialize GPIO for data ready", dev->name); - return result; - } - - result = gpio_pin_interrupt_configure_dt(&config->gpio_data_ready, GPIO_INT_EDGE_TO_ACTIVE); - if (result != 0) { - LOG_ERR("%s: failed to configure data ready interrupt", dev->name); - return -EIO; - } - - gpio_init_callback(&data->callback_data_ready, ads114s0x_data_ready_handler, - BIT(config->gpio_data_ready.pin)); - result = gpio_add_callback(config->gpio_data_ready.port, &data->callback_data_ready); - if (result != 0) { - LOG_ERR("%s: failed to add data ready callback", dev->name); - return -EIO; - } - -#if CONFIG_ADC_ASYNC - k_tid_t tid = k_thread_create(&data->thread, config->stack, - CONFIG_ADC_ADS114S0X_ACQUISITION_THREAD_STACK_SIZE, - ads114s0x_acquisition_thread, (void *)dev, NULL, NULL, - CONFIG_ADC_ADS114S0X_ASYNC_THREAD_INIT_PRIO, 0, K_NO_WAIT); - k_thread_name_set(tid, "adc_ads114s0x"); -#endif - - k_busy_wait(ADS114S0X_POWER_ON_RESET_TIME_IN_US); - - if (config->gpio_reset.port == NULL) { - result = ads114s0x_send_command(dev, ADS114S0X_COMMAND_RESET); - if (result != 0) { - LOG_ERR("%s: unable to send RESET command", dev->name); - return result; - } - } else { - k_busy_wait(ADS114S0X_RESET_LOW_TIME_IN_US); - gpio_pin_set_dt(&config->gpio_reset, 0); - } - - k_busy_wait(ADS114S0X_RESET_DELAY_TIME_IN_US); - - result = ads114s0x_read_register(dev, ADS114S0X_REGISTER_STATUS, &status); - if (result != 0) { - LOG_ERR("%s: unable to read status register", dev->name); - return result; - } - - if (ADS114S0X_REGISTER_STATUS_NOT_RDY_GET(status) == 0x01) { - LOG_ERR("%s: ADS114 is not yet ready", dev->name); - return -EBUSY; - } - - /* - * Activate internal voltage reference during initialization to - * avoid the necessary setup time for it to settle later on. - */ - ADS114S0X_REGISTER_REF_SET_DEFAULTS(reference_control); - - result = ads114s0x_write_register(dev, ADS114S0X_REGISTER_REF, reference_control); - if (result != 0) { - LOG_ERR("%s: unable to set default reference control values", dev->name); - return result; - } - - /* - * Ensure that the internal voltage reference is active. - */ - result = ads114s0x_read_register(dev, ADS114S0X_REGISTER_REF, &reference_control_read); - if (result != 0) { - LOG_ERR("%s: unable to read reference control values", dev->name); - return result; - } - - if (reference_control != reference_control_read) { - LOG_ERR("%s: reference control register is incorrect: 0x%02X", dev->name, - reference_control_read); - return -EIO; - } - -#ifdef CONFIG_ADC_ADS114S0X_GPIO - data->gpio_enabled = 0x00; - data->gpio_direction = 0x0F; - data->gpio_value = 0x00; - - result = ads114s0x_gpio_write_config(dev); - - if (result != 0) { - LOG_ERR("%s: unable to configure defaults for GPIOs", dev->name); - return result; - } -#endif - - adc_context_unlock_unconditionally(&data->ctx); - - return result; -} - -static DEVICE_API(adc, api) = { - .channel_setup = ads114s0x_channel_setup, - .read = ads114s0x_read, - .ref_internal = ADS114S0X_REF_INTERNAL, -#ifdef CONFIG_ADC_ASYNC - .read_async = ads114s0x_adc_read_async, -#endif -}; - -BUILD_ASSERT(CONFIG_ADC_INIT_PRIORITY > CONFIG_SPI_INIT_PRIORITY, - "CONFIG_ADC_INIT_PRIORITY must be higher than CONFIG_SPI_INIT_PRIORITY"); - -#define DT_DRV_COMPAT ti_ads114s08 - -#define ADC_ADS114S0X_INST_DEFINE(n) \ - IF_ENABLED( \ - CONFIG_ADC_ASYNC, \ - (static K_KERNEL_STACK_DEFINE( \ - thread_stack_##n, CONFIG_ADC_ADS114S0X_ACQUISITION_THREAD_STACK_SIZE);)) \ - static const struct ads114s0x_config config_##n = { \ - .bus = SPI_DT_SPEC_INST_GET( \ - n, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), \ - IF_ENABLED(CONFIG_ADC_ASYNC, (.stack = thread_stack_##n,)) \ - .gpio_reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \ - .gpio_data_ready = GPIO_DT_SPEC_INST_GET(n, drdy_gpios), \ - .gpio_start_sync = GPIO_DT_SPEC_INST_GET_OR(n, start_sync_gpios, {0}), \ - .idac_current = DT_INST_PROP(n, idac_current), \ - .vbias_level = DT_INST_PROP(n, vbias_level), \ - }; \ - static struct ads114s0x_data data_##n; \ - DEVICE_DT_INST_DEFINE(n, ads114s0x_init, NULL, &data_##n, &config_##n, POST_KERNEL, \ - CONFIG_ADC_INIT_PRIORITY, &api); - -DT_INST_FOREACH_STATUS_OKAY(ADC_ADS114S0X_INST_DEFINE); diff --git a/drivers/adc/adc_ads131m02.c b/drivers/adc/adc_ads131m02.c new file mode 100644 index 0000000000000..cde5aedda3658 --- /dev/null +++ b/drivers/adc/adc_ads131m02.c @@ -0,0 +1,733 @@ +/* + * Copyright (c) 2024 Linumiz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADC_CONTEXT_USES_KERNEL_TIMER +#include "adc_context.h" + +LOG_MODULE_REGISTER(ads131m02, CONFIG_ADC_LOG_LEVEL); + +#define ADS131M02_DEVICE_ID 0x22 + +/* Device settings Registers */ +#define ADS131M02_ID_REG 0x00 +#define ADS131M02_STATUS_REG 0x01 + +/* Global settings Registers */ +#define ADS131M02_MODE_REG 0x02 +#define ADS131M02_CLOCK_REG 0x03 +#define ADS131M02_GAIN_REG 0x04 +#define ADS131M02_CFG_REG 0x06 +#define ADS131M02_THRESH_MSB_REG 0x07 +#define ADS131M02_THRESH_LSB_REG 0x08 + +/* Channel 0 settings Registers */ +#define ADS131M02_CH0_CFG_REG 0x09 +#define ADS131M02_CH0_OCAL_MSB_REG 0x0A +#define ADS131M02_CH0_OCAL_LSB_REG 0x0B +#define ADS131M02_CH0_GCAL_MSB_REG 0x0C +#define ADS131M02_CH0_GCAL_LSB_REG 0x0D + +/* Channel 1 settings Registers */ +#define ADS131M02_CH1_CFG_REG 0x0E +#define ADS131M02_CH1_OCAL_MSB_REG 0x0F +#define ADS131M02_CH1_OCAL_LSB_REG 0x10 +#define ADS131M02_CH1_GCAL_MSB_REG 0x11 +#define ADS131M02_CH1_GCAL_LSB_REG 0x12 + +/* Register Map CRC Registers */ +#define ADS131M02_REGMAP_CRC_REG 0x3E + +#define ADC_CHANNEL_0 0 +#define ADC_CHANNEL_1 1 +#define ADS131M02_REF_INTERNAL 1200 +#define ADS131M02_RESOLUTION 24 + +/* ADS131M02 cmds */ +#define ADS131M02_NULL_CMD 0x0000 +#define ADS131M02_RESET_CMD 0x0011 +#define ADS131M02_STANDBY_CMD 0x0022 +#define ADS131M02_WAKEUP_CMD 0x0033 +#define ADS131M02_LOCK_CMD 0x0555 +#define ADS131M02_UNLOCK_CMD 0x0655 +#define ADS131M02_RREG_CMD 0xA000 +#define ADS131M02_WREG_CMD 0x6000 + +#define ADS131M02_RESET_RSP 0xFF22 + +#define ADS131M02_GAIN0_MASK GENMASK(2, 0) +#define ADS131M02_GAIN1_MASK GENMASK(6, 4) +#define ADS131M02_CHANNEL0_ENABLE BIT(8) +#define ADS131M02_CHANNEL1_ENABLE BIT(9) +#define ADS131M02_DRDY_CH0_MASK BIT(0) +#define ADS131M02_DRDY_CH1_MASK BIT(1) +#define ADS131M02_OSR_256_MASK BIT(2) +#define ADS131M02_OSR_512_MASK BIT(3) +#define ADS131M02_OSR_1024_MASK BIT(3) | BIT(2) +#define ADS131M02_OSR_2048_MASK BIT(4) +#define ADS131M02_OSR_4096_MASK BIT(4) | BIT(2) +#define ADS131M02_OSR_8192_MASK BIT(4) | BIT(3) +#define ADS131M02_OSR_16384_MASK BIT(4) | BIT(3) | BIT(2) +#define ADS131M02_GC_MODE_MASK BIT(8) +#define ADS131M02_GC_DELAY_MASK GENMASK(12, 9) +#define ADS131M02_PWR_HR BIT(1) | BIT(0) +#define ADS131M02_PWR_LP BIT(0) + +#define ADS131M02_DISABLE_ADC 0x000E +#define ADS131M02_RESET_DELAY 100 + +#define ADS131M02_GAIN_1 0 +#define ADS131M02_GAIN_2 1 +#define ADS131M02_GAIN_4 2 +#define ADS131M02_GAIN_8 3 +#define ADS131M02_GAIN_16 4 +#define ADS131M02_GAIN_32 5 +#define ADS131M02_GAIN_64 6 +#define ADS131M02_GAIN_128 7 + +#define ADS131M02_GET_GAIN(channel_id, gain) \ + FIELD_PREP(channel_id == 0 ? ADS131M02_GAIN0_MASK : \ + ADS131M02_GAIN1_MASK, gain) + +enum ads131m02_data_rate { + /* SPS */ + ADS131M02_DR_250, + ADS131M02_DR_500, + ADS131M02_DR_1k, + ADS131M02_DR_2k, + ADS131M02_DR_4k, + ADS131M02_DR_8k, + ADS131M02_DR_16k, + ADS131M02_DR_32k, +}; + +struct ads131m02_config { + const struct spi_dt_spec spi; + const struct gpio_dt_spec gpio_drdy; +}; + +struct ads131m02_data { + struct adc_context ctx; + struct k_sem acq_sem; + struct k_sem drdy_sem; + struct gpio_callback callback_drdy; + int32_t *buffer; + int32_t *buffer_ptr; +}; + +static inline int ads131m02_transceive(const struct device *dev, + uint8_t *send_buf, size_t send_buf_len, + uint8_t *recv_buf, size_t recv_buf_len) +{ + int ret; + const struct ads131m02_config *cfg = dev->config; + + struct spi_buf tx_buf = { + .buf = send_buf, + .len = send_buf_len, + }; + const struct spi_buf_set tx = { + .buffers = &tx_buf, + .count = 1 + }; + + struct spi_buf rx_buf = { + .buf = recv_buf, + .len = recv_buf_len, + }; + const struct spi_buf_set rx = { + .buffers = &rx_buf, + .count = 1, + }; + + ret = spi_transceive_dt(&cfg->spi, &tx, NULL); + if (ret != 0) { + return ret; + } + + return spi_read_dt(&cfg->spi, &rx); +} + +static int ads131m02_reg_read(const struct device *dev, uint16_t addr, + uint8_t *read_buf, size_t read_buf_len) +{ + uint16_t temp; + uint8_t tx_buf[3] = {0}; + + temp = (uint16_t)(ADS131M02_RREG_CMD | (addr << 7)); + sys_put_be16(temp, tx_buf); + + return ads131m02_transceive(dev, tx_buf, sizeof(tx_buf), + read_buf, read_buf_len); +} + +static int ads131m02_reg_write(const struct device *dev, uint16_t addr, + uint16_t write_data) +{ + uint16_t temp; + uint8_t tx_buf[6] = {0}; + uint8_t rx_buf[3] = {0}; + + temp = (uint16_t)(ADS131M02_WREG_CMD | (addr << 7)); + sys_put_be16(temp, tx_buf); + sys_put_be16(write_data, &tx_buf[3]); + + return ads131m02_transceive(dev, tx_buf, sizeof(tx_buf), + rx_buf, sizeof(rx_buf)); + +} + +static inline int ads131m02_configure_gain(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + uint16_t gain_cfg; + + switch (channel_cfg->gain) { + case ADC_GAIN_1: + gain_cfg = ADS131M02_GET_GAIN(channel_cfg->channel_id, + ADS131M02_GAIN_1); + break; + case ADC_GAIN_2: + gain_cfg = ADS131M02_GET_GAIN(channel_cfg->channel_id, + ADS131M02_GAIN_2); + break; + case ADC_GAIN_4: + gain_cfg = ADS131M02_GET_GAIN(channel_cfg->channel_id, + ADS131M02_GAIN_4); + break; + case ADC_GAIN_8: + gain_cfg = ADS131M02_GET_GAIN(channel_cfg->channel_id, + ADS131M02_GAIN_8); + break; + case ADC_GAIN_16: + gain_cfg = ADS131M02_GET_GAIN(channel_cfg->channel_id, + ADS131M02_GAIN_16); + break; + case ADC_GAIN_32: + gain_cfg = ADS131M02_GET_GAIN(channel_cfg->channel_id, + ADS131M02_GAIN_32); + break; + case ADC_GAIN_64: + gain_cfg = ADS131M02_GET_GAIN(channel_cfg->channel_id, + ADS131M02_GAIN_64); + break; + case ADC_GAIN_128: + gain_cfg = ADS131M02_GET_GAIN(channel_cfg->channel_id, + ADS131M02_GAIN_128); + break; + default: + return -EINVAL; + } + + return ads131m02_reg_write(dev, ADS131M02_GAIN_REG, gain_cfg); +} + +static inline int ads131m02_acquistion_time(uint16_t acq_time, uint16_t *enable) +{ + uint16_t acq_value = ADC_ACQ_TIME_VALUE(acq_time); + + if (acq_time == ADC_ACQ_TIME_DEFAULT) { + *enable |= ADS131M02_OSR_1024_MASK; + return 0; + } + + if (ADC_ACQ_TIME_UNIT(acq_time) != ADC_ACQ_TIME_TICKS) { + return -EINVAL; + } + + if (acq_time == ADC_ACQ_TIME_MAX) { + *enable |= ADS131M02_OSR_16384_MASK; + return 0; + } + + switch (acq_value) { + case ADS131M02_DR_250: + *enable |= ADS131M02_OSR_16384_MASK; + break; + case ADS131M02_DR_500: + *enable |= ADS131M02_OSR_8192_MASK; + break; + case ADS131M02_DR_1k: + *enable |= ADS131M02_OSR_4096_MASK; + break; + case ADS131M02_DR_2k: + *enable |= ADS131M02_OSR_2048_MASK; + break; + case ADS131M02_DR_4k: + *enable |= ADS131M02_OSR_1024_MASK; + break; + case ADS131M02_DR_8k: + *enable |= ADS131M02_OSR_512_MASK; + break; + case ADS131M02_DR_16k: + *enable |= ADS131M02_OSR_256_MASK; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ads131m02_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + int ret; + uint16_t enable; + uint8_t read_data[3] = {0}; + + ret = ads131m02_reg_read(dev, ADS131M02_CLOCK_REG, read_data, + sizeof(read_data)); + if (ret != 0) { + return ret; + } + + enable = sys_get_be16(read_data); + switch (channel_cfg->channel_id) { + case ADC_CHANNEL_0: + enable |= ADS131M02_CHANNEL0_ENABLE; + break; + case ADC_CHANNEL_1: + enable |= ADS131M02_CHANNEL1_ENABLE; + break; + default: + return -EINVAL; + } + + enable &= ~(ADS131M02_OSR_16384_MASK); + ret = ads131m02_acquistion_time(channel_cfg->acquisition_time, &enable); + if (ret < 0) { + return ret; + } + + return ads131m02_reg_write(dev, ADS131M02_CLOCK_REG, enable); +} + +static int ads131m02_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + int ret; + + if (channel_cfg->channel_id != 0 && channel_cfg->channel_id != 1) { + return -EINVAL; + } + + if (channel_cfg->reference != ADC_REF_INTERNAL) { + LOG_DBG("Unsupported Reference Voltage"); + return -ENOTSUP; + } + + if (!channel_cfg->differential) { + return -EINVAL; + } + + ret = ads131m02_configure_gain(dev, channel_cfg); + if (ret != 0) { + return ret; + } + + ret = ads131m02_setup(dev, channel_cfg); + if (ret != 0) { + return ret; + } + + return 0; +} + +static int ads131m02_validate_buffer_size(const struct adc_sequence *sequence) +{ + size_t needed = sizeof(int32_t); + + if (sequence->options) { + needed *= (1 + sequence->options->extra_samplings); + } + + if (sequence->buffer_size < needed) { + return -ENOMEM; + } + + return 0; +} + +static int ads131m02_validate_sequence(const struct adc_sequence *sequence) +{ + if (sequence->resolution != ADS131M02_RESOLUTION) { + return -EINVAL; + } + + if (sequence->channels != BIT(0) && sequence->channels != BIT(1)) { + LOG_ERR("invalid channel"); + return -EINVAL; + } + + if (sequence->oversampling) { + return -EINVAL; + } + + return ads131m02_validate_buffer_size(sequence); +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, + bool repeat_sampling) +{ + struct ads131m02_data *data = CONTAINER_OF(ctx, struct ads131m02_data, ctx); + + if (repeat_sampling) { + data->buffer = data->buffer_ptr; + } +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct ads131m02_data *data = CONTAINER_OF(ctx, struct ads131m02_data, ctx); + + data->buffer_ptr = data->buffer; + k_sem_give(&data->acq_sem); +} + +static int ads131m02_adc_start_read(const struct device *dev, + const struct adc_sequence *sequence, + bool wait) +{ + int ret; + struct ads131m02_data *data = dev->data; + + ret = ads131m02_validate_sequence(sequence); + if (ret != 0) { + LOG_ERR("sequence validation failed"); + return ret; + } + + data->buffer = sequence->buffer; + adc_context_start_read(&data->ctx, sequence); + if (wait) { + ret = adc_context_wait_for_completion(&data->ctx); + } + + return ret; +} + +static int ads131m02_wait_drdy(const struct device *dev) +{ + struct ads131m02_data *data = dev->data; + + return k_sem_take(&data->drdy_sem, + ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT); +} + +static int ads131m02_read_sample(const struct device *dev, + uint32_t channels, uint32_t *buffer) +{ + int ret; + uint16_t int_status; + uint8_t tx_buf[4] = {0}; + uint8_t rx_buf[12] = {0}; + + ret = ads131m02_transceive(dev, tx_buf, sizeof(tx_buf), + rx_buf, sizeof(rx_buf)); + if (ret != 0) { + return ret; + } + + int_status = sys_get_be16(&rx_buf[0]); + if ((int_status & ADS131M02_DRDY_CH0_MASK) && (channels & BIT(0))) { + *buffer = sys_get_be24(&rx_buf[3]); + } else if ((int_status & ADS131M02_DRDY_CH1_MASK) && + (channels & BIT(1))) { + *buffer = sys_get_be24(&rx_buf[6]); + } else { + LOG_INF("No ADC Data Available"); + } + + return 0; +} + +static int ads131m02_perform_read(const struct device *dev, + const struct adc_sequence *sequence) +{ + int ret; + struct ads131m02_data *data = dev->data; + + k_sem_take(&data->acq_sem, K_FOREVER); + k_sem_reset(&data->drdy_sem); + + ret = ads131m02_wait_drdy(dev); + if (ret != 0) { + goto error; + } + + ret = ads131m02_read_sample(dev, sequence->channels, data->buffer); + if (ret != 0) { + goto error; + } + + data->buffer++; + adc_context_on_sampling_done(&data->ctx, dev); + + return 0; +error: + adc_context_complete(&data->ctx, ret); + return ret; +} + +static int ads131m02_read(const struct device *dev, + const struct adc_sequence *seq) +{ + int ret; + struct ads131m02_data *data = dev->data; + + adc_context_lock(&data->ctx, false, NULL); + ret = ads131m02_adc_start_read(dev, seq, false); + + while (ret == 0 && k_sem_take(&data->ctx.sync, K_NO_WAIT) != 0) { + ret = ads131m02_perform_read(dev, seq); + } + + adc_context_release(&data->ctx, ret); + + return ret; +} + +static void ads131m02_data_ready_handler(const struct device *dev, + struct gpio_callback *gpio_cb, + uint32_t pins) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pins); + + struct ads131m02_data *data = CONTAINER_OF(gpio_cb, + struct ads131m02_data, callback_drdy); + + k_sem_give(&data->drdy_sem); +} + +static int ads131m02_configure_gpio(const struct device *dev) +{ + int ret; + const struct ads131m02_config *cfg = dev->config; + struct ads131m02_data *data = dev->data; + + ret = gpio_pin_configure_dt(&cfg->gpio_drdy, GPIO_INPUT); + if (ret != 0) { + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0) { + return ret; + } + + gpio_init_callback(&data->callback_drdy, ads131m02_data_ready_handler, + BIT(cfg->gpio_drdy.pin)); + + return gpio_add_callback(cfg->gpio_drdy.port, &data->callback_drdy); +} + +static int ads131m02_device_reset(const struct device *dev) +{ + int ret; + uint8_t tx_buf[12] = {0}; + uint8_t rx_buf[3] = {0}; + + sys_put_be16(ADS131M02_RESET_CMD, tx_buf); + ret = ads131m02_transceive(dev, tx_buf, sizeof(tx_buf), + rx_buf, sizeof(rx_buf)); + + if (ret != 0) { + return ret; + } + + if (sys_get_be16(rx_buf) != ADS131M02_RESET_RSP) { + return -EIO; + } + + k_msleep(ADS131M02_RESET_DELAY); + + return 0; +} + +#if defined CONFIG_PM_DEVICE +static int ads131m02_pm(const struct device *dev, uint16_t cmd) +{ + int ret; + uint8_t tx_buf[3] = {0}; + uint8_t rx_buf[3] = {0}; + + sys_put_be16(cmd, tx_buf); + ret = ads131m02_transceive(dev, tx_buf, sizeof(tx_buf), + rx_buf, sizeof(rx_buf)); + if (ret != 0) { + return ret; + } + + if (rx_buf[1] != cmd) { + return -EIO; + } + + return 0; +} + +static int ads131m02_pm_action(const struct device *dev, + enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_RESUME: + return ads131m02_pm(dev, ADS131M02_WAKEUP_CMD); + case PM_DEVICE_ACTION_SUSPEND: + return ads131m02_pm(dev, ADS131M02_STANDBY_CMD); + default: + return -EINVAL; + } +} +#endif /* CONFIG_PM_DEVICE */ + +int ads131m02_set_adc_mode(const struct device *dev, + enum ads131m02_adc_mode mode, + enum ads131m02_gc_delay gc_delay) +{ + uint16_t temp = 0; + + switch (mode) { + case ADS131M02_CONTINUOUS_MODE: + break; + case ADS131M02_GLOBAL_CHOP_MODE: + temp |= ADS131M02_GC_MODE_MASK; + temp |= FIELD_PREP(ADS131M02_GC_DELAY_MASK, gc_delay); + break; + default: + return -EINVAL; + } + + return ads131m02_reg_write(dev, ADS131M02_CFG_REG, temp); +} + +int ads131m02_set_power_mode(const struct device *dev, + enum ads131m02_adc_power_mode mode) +{ + int ret; + uint16_t temp; + uint8_t buf[3] = {0}; + + ret = ads131m02_reg_read(dev, ADS131M02_CLOCK_REG, buf, sizeof(buf)); + if (ret != 0) { + return ret; + } + + temp = sys_get_be16(buf); + temp &= ~(ADS131M02_PWR_HR); + + switch (mode) { + case ADS131M02_VLP: + break; + case ADS131M02_LP: + temp |= ADS131M02_PWR_LP; + break; + case ADS131M02_HR: + temp |= ADS131M02_PWR_HR; + break; + default: + return -EINVAL; + } + + return ads131m02_reg_write(dev, ADS131M02_CLOCK_REG, temp); +} + +static DEVICE_API(adc, ads131m02_api) = { + .channel_setup = ads131m02_channel_setup, + .read = ads131m02_read, + .ref_internal = ADS131M02_REF_INTERNAL, +}; + +static int ads131m02_init(const struct device *dev) +{ + int ret; + uint8_t buf[3] = {0}; + const struct ads131m02_config *cfg = dev->config; + struct ads131m02_data *data = dev->data; + + if (!spi_is_ready_dt(&cfg->spi)) { + LOG_ERR("ADS131M02 is not ready"); + return -ENODEV; + } + + adc_context_init(&data->ctx); + k_sem_init(&data->acq_sem, 0, 1); + k_sem_init(&data->drdy_sem, 0, 1); + + ret = ads131m02_configure_gpio(dev); + if (ret != 0) { + LOG_ERR("GPIO config failed %d", ret); + return ret; + } + + ret = ads131m02_reg_read(dev, ADS131M02_ID_REG, buf, sizeof(buf)); + if (ret != 0) { + return ret; + } + + if (buf[0] != ADS131M02_DEVICE_ID) { + LOG_ERR("Device ID mismatch %d", buf[0]); + return -ENODEV; + } + + ret = ads131m02_device_reset(dev); + if (ret != 0) { + LOG_WRN("Device is not reset"); + } + + /* By default, adc is configured, so disabling it */ + ret = ads131m02_reg_write(dev, ADS131M02_CLOCK_REG, + ADS131M02_DISABLE_ADC); + if (ret != 0) { + return ret; + } + + adc_context_unlock_unconditionally(&data->ctx); + +#if defined CONFIG_PM_DEVICE + ret = ads131m02_pm(dev, ADS131M02_STANDBY_CMD); + if (ret != 0) { + return ret; + } + + pm_device_init_suspended(dev); +#endif /* CONFIG_PM_DEVICE */ + + LOG_INF("ADS131M02 Initialised"); + + return 0; +} + +#define DT_DRV_COMPAT ti_ads131m02 + +#define ADC_ADS131M02_INST_DEFINE(n) \ + PM_DEVICE_DT_INST_DEFINE(n, ads131m02_pm_action); \ + static const struct ads131m02_config config_##n = { \ + .spi = SPI_DT_SPEC_INST_GET( \ + n, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | \ + SPI_WORD_SET(8), 0), \ + .gpio_drdy = GPIO_DT_SPEC_INST_GET(n, drdy_gpios), \ + }; \ + static struct ads131m02_data data_##n; \ + DEVICE_DT_INST_DEFINE(n, ads131m02_init, \ + PM_DEVICE_DT_INST_GET(n), \ + &data_##n, &config_##n, POST_KERNEL, \ + CONFIG_ADC_INIT_PRIORITY, &ads131m02_api); + +DT_INST_FOREACH_STATUS_OKAY(ADC_ADS131M02_INST_DEFINE) diff --git a/drivers/adc/adc_ads1x1x.c b/drivers/adc/adc_ads1x1x.c index f984de435b99b..594b275c10d83 100644 --- a/drivers/adc/adc_ads1x1x.c +++ b/drivers/adc/adc_ads1x1x.c @@ -26,7 +26,7 @@ LOG_MODULE_REGISTER(ADS1X1X, CONFIG_ADC_LOG_LEVEL); DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(ti_ads1015, alert_rdy_gpios) || \ DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(ti_ads1014, alert_rdy_gpios) -#define ADC_ADS1X1X_TRIGGER +#define ADC_ADS1X1X_TRIGGER 1 #endif diff --git a/drivers/adc/adc_ads1x4s0x.c b/drivers/adc/adc_ads1x4s0x.c new file mode 100644 index 0000000000000..f4d5f8687d912 --- /dev/null +++ b/drivers/adc/adc_ads1x4s0x.c @@ -0,0 +1,1631 @@ +/* + * Copyright (c) 2023 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADS1X4S0X_HAS_16_BIT_DEV \ + (DT_HAS_COMPAT_STATUS_OKAY(ti_ads114s06) || DT_HAS_COMPAT_STATUS_OKAY(ti_ads114s08)) +#define ADS1X4S0X_HAS_24_BIT_DEV \ + (DT_HAS_COMPAT_STATUS_OKAY(ti_ads124s06) || DT_HAS_COMPAT_STATUS_OKAY(ti_ads124s08)) + +#define ADC_CONTEXT_USES_KERNEL_TIMER 1 +#define ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT \ + K_MSEC(CONFIG_ADC_ADS1X4S0X_WAIT_FOR_COMPLETION_TIMEOUT_MS) +#include "adc_context.h" + +LOG_MODULE_REGISTER(ads1x4s0x, CONFIG_ADC_LOG_LEVEL); + +#define ADS1X4S0X_CLK_FREQ_IN_KHZ 4096 +#define ADS1X4S0X_RESET_LOW_TIME_IN_CLOCK_CYCLES 4 +#define ADS1X4S0X_START_SYNC_PULSE_DURATION_IN_CLOCK_CYCLES 4 +#define ADS1X4S0X_SETUP_TIME_IN_CLOCK_CYCLES 32 +#define ADS1X4S0X_INPUT_SELECTION_AINCOM 12 +#define ADS1X4S0X_REF_INTERNAL 2500 +#define ADS1X4S0X_GPIO_MAX 3 +#define ADS1X4S0X_POWER_ON_RESET_TIME_IN_US 2200 +#define ADS1X4S0X_VBIAS_PIN_MAX 7 +#define ADS1X4S0X_VBIAS_PIN_MIN 0 + +/* Not mentioned in the datasheet, but instead determined experimentally. */ +#define ADS1X4S0X_RESET_DELAY_TIME_SAFETY_MARGIN_IN_US 1000 +#define ADS1X4S0X_RESET_DELAY_TIME_IN_US \ + (4096 * 1000 / ADS1X4S0X_CLK_FREQ_IN_KHZ + ADS1X4S0X_RESET_DELAY_TIME_SAFETY_MARGIN_IN_US) + +#define ADS1X4S0X_RESET_LOW_TIME_IN_US \ + (ADS1X4S0X_RESET_LOW_TIME_IN_CLOCK_CYCLES * 1000 / ADS1X4S0X_CLK_FREQ_IN_KHZ) +#define ADS1X4S0X_START_SYNC_PULSE_DURATION_IN_US \ + (ADS1X4S0X_START_SYNC_PULSE_DURATION_IN_CLOCK_CYCLES * 1000 / ADS1X4S0X_CLK_FREQ_IN_KHZ) +#define ADS1X4S0X_SETUP_TIME_IN_US \ + (ADS1X4S0X_SETUP_TIME_IN_CLOCK_CYCLES * 1000 / ADS1X4S0X_CLK_FREQ_IN_KHZ) + +enum ads1x4s0x_command { + ADS1X4S0X_COMMAND_NOP = 0x00, + ADS1X4S0X_COMMAND_WAKEUP = 0x02, + ADS1X4S0X_COMMAND_POWERDOWN = 0x04, + ADS1X4S0X_COMMAND_RESET = 0x06, + ADS1X4S0X_COMMAND_START = 0x08, + ADS1X4S0X_COMMAND_STOP = 0x0A, + ADS1X4S0X_COMMAND_SYOCAL = 0x16, + ADS1X4S0X_COMMAND_SYGCAL = 0x17, + ADS1X4S0X_COMMAND_SFOCAL = 0x19, + ADS1X4S0X_COMMAND_RDATA = 0x12, + ADS1X4S0X_COMMAND_RREG = 0x20, + ADS1X4S0X_COMMAND_WREG = 0x40, +}; + +enum ads1x4s0x_register { + ADS1X4S0X_REGISTER_ID = 0x00, + ADS1X4S0X_REGISTER_STATUS = 0x01, + ADS1X4S0X_REGISTER_INPMUX = 0x02, + ADS1X4S0X_REGISTER_PGA = 0x03, + ADS1X4S0X_REGISTER_DATARATE = 0x04, + ADS1X4S0X_REGISTER_REF = 0x05, + ADS1X4S0X_REGISTER_IDACMAG = 0x06, + ADS1X4S0X_REGISTER_IDACMUX = 0x07, + ADS1X4S0X_REGISTER_VBIAS = 0x08, + ADS1X4S0X_REGISTER_SYS = 0x09, + ADS1X4S0X_REGISTER_GPIODAT = 0x10, + ADS1X4S0X_REGISTER_GPIOCON = 0x11, + ADS114S0X_REGISTER_OFCAL0 = 0x0B, + ADS114S0X_REGISTER_OFCAL1 = 0x0C, + ADS114S0X_REGISTER_FSCAL0 = 0x0E, + ADS114S0X_REGISTER_FSCAL1 = 0x0F, + ADS124S0X_REGISTER_OFCAL0 = 0x0A, + ADS124S0X_REGISTER_OFCAL1 = 0x0B, + ADS124S0X_REGISTER_OFCAL2 = 0x0C, + ADS124S0X_REGISTER_FSCAL0 = 0x0E, + ADS124S0X_REGISTER_FSCAL1 = 0x0F, + ADS124S0X_REGISTER_FSCAL2 = 0x0F, +}; + +#define ADS1X4S0X_REGISTER_GET_VALUE(value, pos, length) \ + FIELD_GET(GENMASK(pos + length - 1, pos), value) +#define ADS1X4S0X_REGISTER_SET_VALUE(target, value, pos, length) \ + target &= ~GENMASK(pos + length - 1, pos); \ + target |= FIELD_PREP(GENMASK(pos + length - 1, pos), value) + +#define ADS1X4S0X_REGISTER_ID_DEV_ID_LENGTH 3 +#define ADS1X4S0X_REGISTER_ID_DEV_ID_POS 0 +#define ADS1X4S0X_REGISTER_ID_DEV_ID_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_ID_DEV_ID_POS, \ + ADS1X4S0X_REGISTER_ID_DEV_ID_LENGTH) +#define ADS1X4S0X_REGISTER_ID_DEV_ID_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_ID_DEV_ID_POS, \ + ADS1X4S0X_REGISTER_ID_DEV_ID_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_POR_LENGTH 1 +#define ADS1X4S0X_REGISTER_STATUS_FL_POR_POS 7 +#define ADS1X4S0X_REGISTER_STATUS_FL_POR_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_POR_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_POR_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_POR_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_POR_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_POR_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_NOT_RDY_LENGTH 1 +#define ADS1X4S0X_REGISTER_STATUS_NOT_RDY_POS 6 +#define ADS1X4S0X_REGISTER_STATUS_NOT_RDY_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_NOT_RDY_POS, \ + ADS1X4S0X_REGISTER_STATUS_NOT_RDY_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_NOT_RDY_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_NOT_RDY_POS, \ + ADS1X4S0X_REGISTER_STATUS_NOT_RDY_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH 1 +#define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_POS 5 +#define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_P_RAILP_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH 1 +#define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_POS 4 +#define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_P_RAILN_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH 1 +#define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_POS 3 +#define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_N_RAILP_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH 1 +#define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_POS 2 +#define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_N_RAILN_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_LENGTH 1 +#define ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_POS 1 +#define ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_REF_L1_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_LENGTH 1 +#define ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_POS 0 +#define ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_LENGTH) +#define ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_POS, \ + ADS1X4S0X_REGISTER_STATUS_FL_REF_L0_LENGTH) +#define ADS1X4S0X_REGISTER_INPMUX_MUXP_LENGTH 4 +#define ADS1X4S0X_REGISTER_INPMUX_MUXP_POS 4 +#define ADS1X4S0X_REGISTER_INPMUX_MUXP_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_INPMUX_MUXP_POS, \ + ADS1X4S0X_REGISTER_INPMUX_MUXP_LENGTH) +#define ADS1X4S0X_REGISTER_INPMUX_MUXP_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_INPMUX_MUXP_POS, \ + ADS1X4S0X_REGISTER_INPMUX_MUXP_LENGTH) +#define ADS1X4S0X_REGISTER_INPMUX_MUXN_LENGTH 4 +#define ADS1X4S0X_REGISTER_INPMUX_MUXN_POS 0 +#define ADS1X4S0X_REGISTER_INPMUX_MUXN_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_INPMUX_MUXN_POS, \ + ADS1X4S0X_REGISTER_INPMUX_MUXN_LENGTH) +#define ADS1X4S0X_REGISTER_INPMUX_MUXN_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_INPMUX_MUXN_POS, \ + ADS1X4S0X_REGISTER_INPMUX_MUXN_LENGTH) +#define ADS1X4S0X_REGISTER_PGA_DELAY_LENGTH 3 +#define ADS1X4S0X_REGISTER_PGA_DELAY_POS 5 +#define ADS1X4S0X_REGISTER_PGA_DELAY_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_PGA_DELAY_POS, \ + ADS1X4S0X_REGISTER_PGA_DELAY_LENGTH) +#define ADS1X4S0X_REGISTER_PGA_DELAY_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_PGA_DELAY_POS, \ + ADS1X4S0X_REGISTER_PGA_DELAY_LENGTH) +#define ADS1X4S0X_REGISTER_PGA_PGA_EN_LENGTH 2 +#define ADS1X4S0X_REGISTER_PGA_PGA_EN_POS 3 +#define ADS1X4S0X_REGISTER_PGA_PGA_EN_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_PGA_PGA_EN_POS, \ + ADS1X4S0X_REGISTER_PGA_PGA_EN_LENGTH) +#define ADS1X4S0X_REGISTER_PGA_PGA_EN_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_PGA_PGA_EN_POS, \ + ADS1X4S0X_REGISTER_PGA_PGA_EN_LENGTH) +#define ADS1X4S0X_REGISTER_PGA_GAIN_LENGTH 3 +#define ADS1X4S0X_REGISTER_PGA_GAIN_POS 0 +#define ADS1X4S0X_REGISTER_PGA_GAIN_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_PGA_GAIN_POS, \ + ADS1X4S0X_REGISTER_PGA_GAIN_LENGTH) +#define ADS1X4S0X_REGISTER_PGA_GAIN_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_PGA_GAIN_POS, \ + ADS1X4S0X_REGISTER_PGA_GAIN_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_G_CHOP_LENGTH 1 +#define ADS1X4S0X_REGISTER_DATARATE_G_CHOP_POS 7 +#define ADS1X4S0X_REGISTER_DATARATE_G_CHOP_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_G_CHOP_POS, \ + ADS1X4S0X_REGISTER_DATARATE_G_CHOP_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_G_CHOP_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_G_CHOP_POS, \ + ADS1X4S0X_REGISTER_DATARATE_G_CHOP_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_CLK_LENGTH 1 +#define ADS1X4S0X_REGISTER_DATARATE_CLK_POS 6 +#define ADS1X4S0X_REGISTER_DATARATE_CLK_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_CLK_POS, \ + ADS1X4S0X_REGISTER_DATARATE_CLK_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_CLK_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_CLK_POS, \ + ADS1X4S0X_REGISTER_DATARATE_CLK_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_MODE_LENGTH 1 +#define ADS1X4S0X_REGISTER_DATARATE_MODE_POS 5 +#define ADS1X4S0X_REGISTER_DATARATE_MODE_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_MODE_POS, \ + ADS1X4S0X_REGISTER_DATARATE_MODE_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_MODE_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_MODE_POS, \ + ADS1X4S0X_REGISTER_DATARATE_MODE_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_FILTER_LENGTH 1 +#define ADS1X4S0X_REGISTER_DATARATE_FILTER_POS 4 +#define ADS1X4S0X_REGISTER_DATARATE_FILTER_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_FILTER_POS, \ + ADS1X4S0X_REGISTER_DATARATE_FILTER_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_FILTER_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_FILTER_POS, \ + ADS1X4S0X_REGISTER_DATARATE_FILTER_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_DR_LENGTH 4 +#define ADS1X4S0X_REGISTER_DATARATE_DR_POS 0 +#define ADS1X4S0X_REGISTER_DATARATE_DR_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_DATARATE_DR_POS, \ + ADS1X4S0X_REGISTER_DATARATE_DR_LENGTH) +#define ADS1X4S0X_REGISTER_DATARATE_DR_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_DATARATE_DR_POS, \ + ADS1X4S0X_REGISTER_DATARATE_DR_LENGTH) +#define ADS1X4S0X_REGISTER_REF_FL_REF_EN_LENGTH 2 +#define ADS1X4S0X_REGISTER_REF_FL_REF_EN_POS 6 +#define ADS1X4S0X_REGISTER_REF_FL_REF_EN_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_FL_REF_EN_POS, \ + ADS1X4S0X_REGISTER_REF_FL_REF_EN_LENGTH) +#define ADS1X4S0X_REGISTER_REF_FL_REF_EN_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_FL_REF_EN_POS, \ + ADS1X4S0X_REGISTER_REF_FL_REF_EN_LENGTH) +#define ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH 1 +#define ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_POS 5 +#define ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_POS, \ + ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH) +#define ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_POS, \ + ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_LENGTH) +#define ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH 1 +#define ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_POS 4 +#define ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_POS, \ + ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH) +#define ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_POS, \ + ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_LENGTH) +#define ADS1X4S0X_REGISTER_REF_REFSEL_LENGTH 2 +#define ADS1X4S0X_REGISTER_REF_REFSEL_POS 2 +#define ADS1X4S0X_REGISTER_REF_REFSEL_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_REFSEL_POS, \ + ADS1X4S0X_REGISTER_REF_REFSEL_LENGTH) +#define ADS1X4S0X_REGISTER_REF_REFSEL_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_REFSEL_POS, \ + ADS1X4S0X_REGISTER_REF_REFSEL_LENGTH) +#define ADS1X4S0X_REGISTER_REF_REFCON_LENGTH 2 +#define ADS1X4S0X_REGISTER_REF_REFCON_POS 0 +#define ADS1X4S0X_REGISTER_REF_REFCON_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_REF_REFCON_POS, \ + ADS1X4S0X_REGISTER_REF_REFCON_LENGTH) +#define ADS1X4S0X_REGISTER_REF_REFCON_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_REF_REFCON_POS, \ + ADS1X4S0X_REGISTER_REF_REFCON_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH 1 +#define ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS 7 +#define ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \ + ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_POS, \ + ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMAG_PSW_LENGTH 1 +#define ADS1X4S0X_REGISTER_IDACMAG_PSW_POS 6 +#define ADS1X4S0X_REGISTER_IDACMAG_PSW_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMAG_PSW_POS, \ + ADS1X4S0X_REGISTER_IDACMAG_PSW_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMAG_PSW_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMAG_PSW_POS, \ + ADS1X4S0X_REGISTER_IDACMAG_PSW_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMAG_IMAG_LENGTH 4 +#define ADS1X4S0X_REGISTER_IDACMAG_IMAG_POS 0 +#define ADS1X4S0X_REGISTER_IDACMAG_IMAG_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMAG_IMAG_POS, \ + ADS1X4S0X_REGISTER_IDACMAG_IMAG_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMAG_IMAG_POS, \ + ADS1X4S0X_REGISTER_IDACMAG_IMAG_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMUX_I2MUX_LENGTH 4 +#define ADS1X4S0X_REGISTER_IDACMUX_I2MUX_POS 4 +#define ADS1X4S0X_REGISTER_IDACMUX_I2MUX_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMUX_I2MUX_POS, \ + ADS1X4S0X_REGISTER_IDACMUX_I2MUX_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMUX_I2MUX_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMUX_I2MUX_POS, \ + ADS1X4S0X_REGISTER_IDACMUX_I2MUX_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMUX_I1MUX_LENGTH 4 +#define ADS1X4S0X_REGISTER_IDACMUX_I1MUX_POS 0 +#define ADS1X4S0X_REGISTER_IDACMUX_I1MUX_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_IDACMUX_I1MUX_POS, \ + ADS1X4S0X_REGISTER_IDACMUX_I1MUX_LENGTH) +#define ADS1X4S0X_REGISTER_IDACMUX_I1MUX_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_IDACMUX_I1MUX_POS, \ + ADS1X4S0X_REGISTER_IDACMUX_I1MUX_LENGTH) +#define ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH 1 +#define ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_POS 7 +#define ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_POS, \ + ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH) +#define ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_POS, \ + ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_LENGTH) +#define ADS1X4S0X_REGISTER_GPIODAT_DIR_LENGTH 4 +#define ADS1X4S0X_REGISTER_GPIODAT_DIR_POS 4 +#define ADS1X4S0X_REGISTER_GPIODAT_DIR_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_GPIODAT_DIR_POS, \ + ADS1X4S0X_REGISTER_GPIODAT_DIR_LENGTH) +#define ADS1X4S0X_REGISTER_GPIODAT_DIR_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_GPIODAT_DIR_POS, \ + ADS1X4S0X_REGISTER_GPIODAT_DIR_LENGTH) +#define ADS1X4S0X_REGISTER_GPIODAT_DAT_LENGTH 4 +#define ADS1X4S0X_REGISTER_GPIODAT_DAT_POS 0 +#define ADS1X4S0X_REGISTER_GPIODAT_DAT_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_GPIODAT_DAT_POS, \ + ADS1X4S0X_REGISTER_GPIODAT_DAT_LENGTH) +#define ADS1X4S0X_REGISTER_GPIODAT_DAT_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_GPIODAT_DAT_POS, \ + ADS1X4S0X_REGISTER_GPIODAT_DAT_LENGTH) +#define ADS1X4S0X_REGISTER_GPIOCON_CON_LENGTH 4 +#define ADS1X4S0X_REGISTER_GPIOCON_CON_POS 0 +#define ADS1X4S0X_REGISTER_GPIOCON_CON_GET(value) \ + ADS1X4S0X_REGISTER_GET_VALUE(value, ADS1X4S0X_REGISTER_GPIOCON_CON_POS, \ + ADS1X4S0X_REGISTER_GPIOCON_CON_LENGTH) +#define ADS1X4S0X_REGISTER_GPIOCON_CON_SET(target, value) \ + ADS1X4S0X_REGISTER_SET_VALUE(target, value, ADS1X4S0X_REGISTER_GPIOCON_CON_POS, \ + ADS1X4S0X_REGISTER_GPIOCON_CON_LENGTH) + +/* + * - AIN0 as positive input + * - AIN1 as negative input + */ +#define ADS1X4S0X_REGISTER_INPMUX_SET_DEFAULTS(target) \ + ADS1X4S0X_REGISTER_INPMUX_MUXP_SET(target, 0b0000); \ + ADS1X4S0X_REGISTER_INPMUX_MUXN_SET(target, 0b0001) +/* + * - disable reference monitor + * - enable positive reference buffer + * - disable negative reference buffer + * - use internal reference + * - enable internal voltage reference + */ +#define ADS1X4S0X_REGISTER_REF_SET_DEFAULTS(target) \ + ADS1X4S0X_REGISTER_REF_FL_REF_EN_SET(target, 0b00); \ + ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(target, 0b0); \ + ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(target, 0b1); \ + ADS1X4S0X_REGISTER_REF_REFSEL_SET(target, 0b10); \ + ADS1X4S0X_REGISTER_REF_REFCON_SET(target, 0b01) +/* + * - disable global chop + * - use internal oscillator + * - single shot conversion mode + * - low latency filter + * - 20 samples per second + */ +#define ADS1X4S0X_REGISTER_DATARATE_SET_DEFAULTS(target) \ + ADS1X4S0X_REGISTER_DATARATE_G_CHOP_SET(target, 0b0); \ + ADS1X4S0X_REGISTER_DATARATE_CLK_SET(target, 0b0); \ + ADS1X4S0X_REGISTER_DATARATE_MODE_SET(target, 0b1); \ + ADS1X4S0X_REGISTER_DATARATE_FILTER_SET(target, 0b1); \ + ADS1X4S0X_REGISTER_DATARATE_DR_SET(target, 0b0100) +/* + * - delay of 14*t_mod + * - disable gain + * - gain 1 + */ +#define ADS1X4S0X_REGISTER_PGA_SET_DEFAULTS(target) \ + ADS1X4S0X_REGISTER_PGA_DELAY_SET(target, 0b000); \ + ADS1X4S0X_REGISTER_PGA_PGA_EN_SET(target, 0b00); \ + ADS1X4S0X_REGISTER_PGA_GAIN_SET(target, 0b000) +/* + * - disable PGA output rail flag + * - low-side power switch + * - IDAC off + */ +#define ADS1X4S0X_REGISTER_IDACMAG_SET_DEFAULTS(target) \ + ADS1X4S0X_REGISTER_IDACMAG_FL_RAIL_EN_SET(target, 0b0); \ + ADS1X4S0X_REGISTER_IDACMAG_PSW_SET(target, 0b0); \ + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(target, 0b0000) +/* + * - disconnect IDAC1 + * - disconnect IDAC2 + */ +#define ADS1X4S0X_REGISTER_IDACMUX_SET_DEFAULTS(target) \ + ADS1X4S0X_REGISTER_IDACMUX_I1MUX_SET(target, 0b1111); \ + ADS1X4S0X_REGISTER_IDACMUX_I2MUX_SET(target, 0b1111) + +struct ads1x4s0x_config { + struct spi_dt_spec bus; +#if CONFIG_ADC_ASYNC + k_thread_stack_t *stack; +#endif + const struct gpio_dt_spec gpio_reset; + const struct gpio_dt_spec gpio_data_ready; + const struct gpio_dt_spec gpio_start_sync; + int idac_current; + uint8_t vbias_level; + uint8_t channels; + uint8_t resolution; +}; + +struct ads1x4s0x_data { + struct adc_context ctx; +#if CONFIG_ADC_ASYNC + struct k_thread thread; +#endif /* CONFIG_ADC_ASYNC */ + struct gpio_callback callback_data_ready; + struct k_sem data_ready_signal; + struct k_sem acquire_signal; + void *buffer; + void *buffer_ptr; +#if CONFIG_ADC_ADS1X4S0X_GPIO + struct k_mutex gpio_lock; + uint8_t gpio_enabled; /* one bit per GPIO, 1 = enabled */ + uint8_t gpio_direction; /* one bit per GPIO, 1 = input */ + uint8_t gpio_value; /* one bit per GPIO, 1 = high */ +#endif /* CONFIG_ADC_ADS1X4S0X_GPIO */ +}; + +static void ads1x4s0x_data_ready_handler(const struct device *dev, struct gpio_callback *gpio_cb, + uint32_t pins) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pins); + + struct ads1x4s0x_data *data = + CONTAINER_OF(gpio_cb, struct ads1x4s0x_data, callback_data_ready); + + k_sem_give(&data->data_ready_signal); +} + +static int ads1x4s0x_read_register(const struct device *dev, + enum ads1x4s0x_register register_address, uint8_t *value) +{ + const struct ads1x4s0x_config *config = dev->config; + uint8_t buffer_tx[3]; + uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)]; + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }}; + const struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = ARRAY_SIZE(buffer_rx), + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf), + }; + + buffer_tx[0] = ((uint8_t)ADS1X4S0X_COMMAND_RREG) | ((uint8_t)register_address); + /* read one register */ + buffer_tx[1] = 0x00; + + int result = spi_transceive_dt(&config->bus, &tx, &rx); + + if (result != 0) { + LOG_ERR("%s: spi_transceive failed with error %i", dev->name, result); + return result; + } + + *value = buffer_rx[2]; + LOG_DBG("%s: read from register 0x%02X value 0x%02X", dev->name, register_address, *value); + + return 0; +} + +static int ads1x4s0x_write_register(const struct device *dev, + enum ads1x4s0x_register register_address, uint8_t value) +{ + const struct ads1x4s0x_config *config = dev->config; + uint8_t buffer_tx[3]; + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + + buffer_tx[0] = ((uint8_t)ADS1X4S0X_COMMAND_WREG) | ((uint8_t)register_address); + /* write one register */ + buffer_tx[1] = 0x00; + buffer_tx[2] = value; + + LOG_DBG("%s: writing to register 0x%02X value 0x%02X", dev->name, register_address, value); + int result = spi_write_dt(&config->bus, &tx); + + if (result != 0) { + LOG_ERR("%s: spi_write failed with error %i", dev->name, result); + return result; + } + + return 0; +} + +static int ads1x4s0x_write_multiple_registers(const struct device *dev, + enum ads1x4s0x_register *register_addresses, + uint8_t *values, size_t count) +{ + const struct ads1x4s0x_config *config = dev->config; + uint8_t buffer_tx[2]; + const struct spi_buf tx_buf[] = { + { + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }, + { + .buf = values, + .len = count, + }, + }; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + + if (count == 0) { + LOG_WRN("%s: ignoring the command to write 0 registers", dev->name); + return -EINVAL; + } + + buffer_tx[0] = ((uint8_t)ADS1X4S0X_COMMAND_WREG) | ((uint8_t)register_addresses[0]); + buffer_tx[1] = count - 1; + + LOG_HEXDUMP_DBG(register_addresses, count, "writing to registers"); + LOG_HEXDUMP_DBG(values, count, "values"); + + /* ensure that the register addresses are in the correct order */ + for (size_t i = 1; i < count; ++i) { + __ASSERT(register_addresses[i - 1] + 1 == register_addresses[i], + "register addresses are not consecutive"); + } + + int result = spi_write_dt(&config->bus, &tx); + + if (result != 0) { + LOG_ERR("%s: spi_write failed with error %i", dev->name, result); + return result; + } + + return 0; +} + +static int ads1x4s0x_send_command(const struct device *dev, enum ads1x4s0x_command command) +{ + const struct ads1x4s0x_config *config = dev->config; + uint8_t buffer_tx[1]; + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = ARRAY_SIZE(buffer_tx), + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + + buffer_tx[0] = (uint8_t)command; + + LOG_DBG("%s: sending command 0x%02X", dev->name, command); + int result = spi_write_dt(&config->bus, &tx); + + if (result != 0) { + LOG_ERR("%s: spi_write failed with error %i", dev->name, result); + return result; + } + + return 0; +} + +static int ads1x4s0x_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + const struct ads1x4s0x_config *config = dev->config; + uint8_t input_mux = 0; + uint8_t reference_control = 0; + uint8_t data_rate = 0; + uint8_t gain = 0; + uint8_t idac_magnitude = 0; + uint8_t idac_mux = 0; + uint8_t pin_selections[4]; + uint8_t vbias = 0; + size_t pin_selections_size; + int result; + enum ads1x4s0x_register register_addresses[7]; + uint8_t values[ARRAY_SIZE(register_addresses)]; + uint16_t acquisition_time_value = ADC_ACQ_TIME_VALUE(channel_cfg->acquisition_time); + uint16_t acquisition_time_unit = ADC_ACQ_TIME_UNIT(channel_cfg->acquisition_time); + + ADS1X4S0X_REGISTER_INPMUX_SET_DEFAULTS(gain); + ADS1X4S0X_REGISTER_REF_SET_DEFAULTS(reference_control); + ADS1X4S0X_REGISTER_DATARATE_SET_DEFAULTS(data_rate); + ADS1X4S0X_REGISTER_PGA_SET_DEFAULTS(gain); + ADS1X4S0X_REGISTER_IDACMAG_SET_DEFAULTS(idac_magnitude); + ADS1X4S0X_REGISTER_IDACMUX_SET_DEFAULTS(idac_mux); + + if (channel_cfg->channel_id != 0) { + LOG_ERR("%s: only one channel is supported", dev->name); + return -EINVAL; + } + + /* The ADS114 uses samples per seconds units with the lowest being 2.5SPS + * and with acquisition_time only having 14b for time, this will not fit + * within here for microsecond units. Use Tick units and allow the user to + * specify the ODR directly. + */ + if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT && + acquisition_time_unit != ADC_ACQ_TIME_TICKS) { + LOG_ERR("%s: invalid acquisition time %i", dev->name, + channel_cfg->acquisition_time); + return -EINVAL; + } + + if (channel_cfg->acquisition_time == ADC_ACQ_TIME_DEFAULT) { + ADS1X4S0X_REGISTER_DATARATE_DR_SET(data_rate, ADS1X4S0X_CONFIG_DR_20); + } else { + ADS1X4S0X_REGISTER_DATARATE_DR_SET(data_rate, acquisition_time_value); + } + + switch (channel_cfg->reference) { + case ADC_REF_INTERNAL: + /* disable negative reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b1); + /* disable positive reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b1); + /* use internal reference */ + ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b10); + break; + case ADC_REF_EXTERNAL0: + /* enable negative reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0); + /* enable positive reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0); + /* use external reference 0*/ + ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b00); + break; + case ADC_REF_EXTERNAL1: + /* enable negative reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0); + /* enable positive reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0); + /* use external reference 0*/ + ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b01); + break; + default: + LOG_ERR("%s: reference %i is not supported", dev->name, channel_cfg->reference); + return -EINVAL; + } + + if (channel_cfg->differential) { + LOG_DBG("%s: configuring channel for a differential measurement from the pins (p, " + "n) (%i, %i)", + dev->name, channel_cfg->input_positive, channel_cfg->input_negative); + if (channel_cfg->input_positive >= config->channels && + channel_cfg->input_positive != ADS1X4S0X_INPUT_SELECTION_AINCOM) { + LOG_ERR("%s: positive channel input %i is invalid", dev->name, + channel_cfg->input_positive); + return -EINVAL; + } + + if (channel_cfg->input_negative >= config->channels && + channel_cfg->input_negative != ADS1X4S0X_INPUT_SELECTION_AINCOM) { + LOG_ERR("%s: negative channel input %i is invalid", dev->name, + channel_cfg->input_negative); + return -EINVAL; + } + + if (channel_cfg->input_positive == channel_cfg->input_negative) { + LOG_ERR("%s: negative and positive channel inputs must be different", + dev->name); + return -EINVAL; + } + + ADS1X4S0X_REGISTER_INPMUX_MUXP_SET(input_mux, channel_cfg->input_positive); + ADS1X4S0X_REGISTER_INPMUX_MUXN_SET(input_mux, channel_cfg->input_negative); + pin_selections[0] = channel_cfg->input_positive; + pin_selections[1] = channel_cfg->input_negative; + } else { + LOG_DBG("%s: configuring channel for single ended measurement from input %i", + dev->name, channel_cfg->input_positive); + if (channel_cfg->input_positive >= config->channels && + channel_cfg->input_positive != ADS1X4S0X_INPUT_SELECTION_AINCOM) { + LOG_ERR("%s: channel input %i is invalid", dev->name, + channel_cfg->input_positive); + return -EINVAL; + } + + ADS1X4S0X_REGISTER_INPMUX_MUXP_SET(input_mux, channel_cfg->input_positive); + ADS1X4S0X_REGISTER_INPMUX_MUXN_SET(input_mux, ADS1X4S0X_INPUT_SELECTION_AINCOM); + pin_selections[0] = channel_cfg->input_positive; + pin_selections[1] = ADS1X4S0X_INPUT_SELECTION_AINCOM; + } + + switch (channel_cfg->gain) { + case ADC_GAIN_1: + /* set gain value */ + ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b000); + break; + case ADC_GAIN_2: + ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b001); + break; + case ADC_GAIN_4: + ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b010); + break; + case ADC_GAIN_8: + ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b011); + break; + case ADC_GAIN_16: + ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b100); + break; + case ADC_GAIN_32: + ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b101); + break; + case ADC_GAIN_64: + ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b110); + break; + case ADC_GAIN_128: + ADS1X4S0X_REGISTER_PGA_GAIN_SET(gain, 0b111); + break; + default: + LOG_ERR("%s: gain value %i not supported", dev->name, channel_cfg->gain); + return -EINVAL; + } + + if (channel_cfg->gain != ADC_GAIN_1) { + /* enable gain */ + ADS1X4S0X_REGISTER_PGA_PGA_EN_SET(gain, 0b01); + } + + switch (config->idac_current) { + case 0: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0000); + break; + case 10: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0001); + break; + case 50: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0010); + break; + case 100: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0011); + break; + case 250: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0100); + break; + case 500: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0101); + break; + case 750: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0110); + break; + case 1000: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b0111); + break; + case 1500: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b1000); + break; + case 2000: + ADS1X4S0X_REGISTER_IDACMAG_IMAG_SET(idac_magnitude, 0b1001); + break; + default: + LOG_ERR("%s: IDAC magnitude %i not supported", dev->name, config->idac_current); + return -EINVAL; + } + + if (channel_cfg->current_source_pin_set) { + LOG_DBG("%s: current source pin set to %i and %i", dev->name, + channel_cfg->current_source_pin[0], channel_cfg->current_source_pin[1]); + if (channel_cfg->current_source_pin[0] > 0b1111) { + LOG_ERR("%s: invalid selection %i for I1MUX", dev->name, + channel_cfg->current_source_pin[0]); + return -EINVAL; + } + + if (channel_cfg->current_source_pin[1] > 0b1111) { + LOG_ERR("%s: invalid selection %i for I2MUX", dev->name, + channel_cfg->current_source_pin[1]); + return -EINVAL; + } + + ADS1X4S0X_REGISTER_IDACMUX_I1MUX_SET(idac_mux, channel_cfg->current_source_pin[0]); + ADS1X4S0X_REGISTER_IDACMUX_I2MUX_SET(idac_mux, channel_cfg->current_source_pin[1]); + pin_selections[2] = channel_cfg->current_source_pin[0]; + pin_selections[3] = channel_cfg->current_source_pin[1]; + pin_selections_size = 4; + } else { + LOG_DBG("%s: current source pins not set", dev->name); + pin_selections_size = 2; + } + + for (size_t i = 0; i < pin_selections_size; ++i) { + if (pin_selections[i] > ADS1X4S0X_INPUT_SELECTION_AINCOM) { + continue; + } + + for (size_t j = i + 1; j < pin_selections_size; ++j) { + if (pin_selections[j] > ADS1X4S0X_INPUT_SELECTION_AINCOM) { + continue; + } + + if (pin_selections[i] == pin_selections[j]) { + LOG_ERR("%s: pins for inputs and current sources must be different", + dev->name); + return -EINVAL; + } + } + } + + ADS1X4S0X_REGISTER_VBIAS_VB_LEVEL_SET(vbias, config->vbias_level); + + if ((channel_cfg->vbias_pins & + ~GENMASK(ADS1X4S0X_VBIAS_PIN_MAX, ADS1X4S0X_VBIAS_PIN_MIN)) != 0) { + LOG_ERR("%s: invalid VBIAS pin selection 0x%08X", dev->name, + channel_cfg->vbias_pins); + return -EINVAL; + } + + vbias |= channel_cfg->vbias_pins; + + register_addresses[0] = ADS1X4S0X_REGISTER_INPMUX; + register_addresses[1] = ADS1X4S0X_REGISTER_PGA; + register_addresses[2] = ADS1X4S0X_REGISTER_DATARATE; + register_addresses[3] = ADS1X4S0X_REGISTER_REF; + register_addresses[4] = ADS1X4S0X_REGISTER_IDACMAG; + register_addresses[5] = ADS1X4S0X_REGISTER_IDACMUX; + register_addresses[6] = ADS1X4S0X_REGISTER_VBIAS; + BUILD_ASSERT(ARRAY_SIZE(register_addresses) == 7); + values[0] = input_mux; + values[1] = gain; + values[2] = data_rate; + values[3] = reference_control; + values[4] = idac_magnitude; + values[5] = idac_mux; + values[6] = vbias; + BUILD_ASSERT(ARRAY_SIZE(values) == 7); + + result = ads1x4s0x_write_multiple_registers(dev, register_addresses, values, + ARRAY_SIZE(values)); + + if (result != 0) { + LOG_ERR("%s: unable to configure registers", dev->name); + return result; + } + + return 0; +} + +static int ads1x4s0x_validate_buffer_size(const struct device *dev, + const struct adc_sequence *sequence) +{ + const struct ads1x4s0x_config *config = dev->config; + size_t needed; + + needed = (config->resolution > 16) ? sizeof(int32_t) : sizeof(int16_t); + + if (sequence->options) { + needed *= (1 + sequence->options->extra_samplings); + } + + if (sequence->buffer_size < needed) { + return -ENOMEM; + } + + return 0; +} + +static int ads1x4s0x_validate_sequence(const struct device *dev, + const struct adc_sequence *sequence) +{ + const struct ads1x4s0x_config *config = dev->config; + + if (sequence->resolution != config->resolution) { + LOG_ERR("%s: invalid resolution", dev->name); + return -EINVAL; + } + + if (sequence->channels != BIT(0)) { + LOG_ERR("%s: invalid channel", dev->name); + return -EINVAL; + } + + if (sequence->oversampling) { + LOG_ERR("%s: oversampling is not supported", dev->name); + return -EINVAL; + } + + return ads1x4s0x_validate_buffer_size(dev, sequence); +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) +{ + struct ads1x4s0x_data *data = CONTAINER_OF(ctx, struct ads1x4s0x_data, ctx); + + if (repeat_sampling) { + data->buffer = data->buffer_ptr; + } +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct ads1x4s0x_data *data = CONTAINER_OF(ctx, struct ads1x4s0x_data, ctx); + + data->buffer_ptr = data->buffer; + k_sem_give(&data->acquire_signal); +} + +static int ads1x4s0x_adc_start_read(const struct device *dev, const struct adc_sequence *sequence, + bool wait) +{ + int result; + struct ads1x4s0x_data *data = dev->data; + + result = ads1x4s0x_validate_sequence(dev, sequence); + + if (result != 0) { + LOG_ERR("%s: sequence validation failed", dev->name); + return result; + } + + data->buffer = sequence->buffer; + + adc_context_start_read(&data->ctx, sequence); + + if (wait) { + result = adc_context_wait_for_completion(&data->ctx); + } + + return result; +} + +static int ads1x4s0x_send_start_read(const struct device *dev) +{ + const struct ads1x4s0x_config *config = dev->config; + int result; + + if (config->gpio_start_sync.port == 0) { + result = ads1x4s0x_send_command(dev, ADS1X4S0X_COMMAND_START); + if (result != 0) { + LOG_ERR("%s: unable to send START/SYNC command", dev->name); + return result; + } + } else { + result = gpio_pin_set_dt(&config->gpio_start_sync, 1); + + if (result != 0) { + LOG_ERR("%s: unable to start ADC operation", dev->name); + return result; + } + + k_sleep(K_USEC(ADS1X4S0X_START_SYNC_PULSE_DURATION_IN_US + + ADS1X4S0X_SETUP_TIME_IN_US)); + + result = gpio_pin_set_dt(&config->gpio_start_sync, 0); + + if (result != 0) { + LOG_ERR("%s: unable to start ADC operation", dev->name); + return result; + } + } + + return 0; +} + +static int ads1x4s0x_wait_data_ready(const struct device *dev) +{ + struct ads1x4s0x_data *data = dev->data; + + return k_sem_take(&data->data_ready_signal, ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT); +} + +#if ADS1X4S0X_HAS_16_BIT_DEV +static int ads1x4s0x_read_sample_16(const struct device *dev, int16_t *buffer) +{ + const struct ads1x4s0x_config *config = dev->config; + uint8_t buffer_tx[3]; + uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)]; + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = 3, + }}; + const struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = 3, + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf), + }; + + buffer_tx[0] = (uint8_t)ADS1X4S0X_COMMAND_RDATA; + + int result = spi_transceive_dt(&config->bus, &tx, &rx); + + if (result != 0) { + LOG_ERR("%s: spi_transceive failed with error %i", dev->name, result); + return result; + } + + *buffer = sys_get_be16(buffer_rx + 1); + LOG_DBG("%s: read ADC sample %i", dev->name, *buffer); + + return 0; +} +#endif + +#if ADS1X4S0X_HAS_24_BIT_DEV +static int ads1x4s0x_read_sample_24(const struct device *dev, int32_t *buffer) +{ + const struct ads1x4s0x_config *config = dev->config; + uint8_t buffer_tx[5] = {0}; + uint8_t buffer_rx[ARRAY_SIZE(buffer_tx)]; + const struct spi_buf tx_buf[] = {{ + .buf = buffer_tx, + .len = 4, + }}; + const struct spi_buf rx_buf[] = {{ + .buf = buffer_rx, + .len = 4, + }}; + const struct spi_buf_set tx = { + .buffers = tx_buf, + .count = ARRAY_SIZE(tx_buf), + }; + const struct spi_buf_set rx = { + .buffers = rx_buf, + .count = ARRAY_SIZE(rx_buf), + }; + + buffer_tx[0] = (uint8_t)ADS1X4S0X_COMMAND_RDATA; + + int result = spi_transceive_dt(&config->bus, &tx, &rx); + + if (result != 0) { + LOG_ERR("%s: spi_transceive failed with error %i", dev->name, result); + return result; + } + + *buffer = (int32_t)sys_get_be32(buffer_rx + 1) >> 8; + + LOG_DBG("%s: read ADC sample 0x%02X%02X%02X", dev->name, *(buffer_rx + 1), *(buffer_rx + 2), + *(buffer_rx + 3)); + + return 0; +} +#endif + +static int ads1x4s0x_adc_perform_read(const struct device *dev) +{ + int result; + const struct ads1x4s0x_config *config = dev->config; + struct ads1x4s0x_data *data = dev->data; + void *buffer = data->buffer; + + k_sem_take(&data->acquire_signal, K_FOREVER); + k_sem_reset(&data->data_ready_signal); + + result = ads1x4s0x_send_start_read(dev); + if (result != 0) { + LOG_ERR("%s: unable to start ADC conversion", dev->name); + adc_context_complete(&data->ctx, result); + return result; + } + + result = ads1x4s0x_wait_data_ready(dev); + if (result != 0) { + LOG_ERR("%s: waiting for data to be ready failed", dev->name); + adc_context_complete(&data->ctx, result); + return result; + } + +#if ADS1X4S0X_HAS_24_BIT_DEV + if (config->resolution == 24) { + result = ads1x4s0x_read_sample_24(dev, (int32_t *)data->buffer); + + if (result == 0) { + buffer = (int32_t *)buffer + 1; + adc_context_on_sampling_done(&data->ctx, dev); + return 0; + } + + } +#endif + +#if ADS1X4S0X_HAS_16_BIT_DEV + if (config->resolution == 16) { + result = ads1x4s0x_read_sample_16(dev, (int16_t *)data->buffer); + + if (result == 0) { + buffer = (int16_t *)buffer + 1; + adc_context_on_sampling_done(&data->ctx, dev); + return 0; + } + + } +#endif + + LOG_ERR("%s: reading sample failed", dev->name); + adc_context_complete(&data->ctx, result); + return result; +} + +#if CONFIG_ADC_ASYNC +static int ads1x4s0x_adc_read_async(const struct device *dev, const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + int result; + struct ads1x4s0x_data *data = dev->data; + + adc_context_lock(&data->ctx, true, async); + result = ads1x4s0x_adc_start_read(dev, sequence, true); + adc_context_release(&data->ctx, result); + + return result; +} + +static int ads1x4s0x_read(const struct device *dev, const struct adc_sequence *sequence) +{ + int result; + struct ads1x4s0x_data *data = dev->data; + + adc_context_lock(&data->ctx, false, NULL); + result = ads1x4s0x_adc_start_read(dev, sequence, true); + adc_context_release(&data->ctx, result); + + return result; +} + +#else +static int ads1x4s0x_read(const struct device *dev, const struct adc_sequence *sequence) +{ + int result; + struct ads1x4s0x_data *data = dev->data; + + adc_context_lock(&data->ctx, false, NULL); + result = ads1x4s0x_adc_start_read(dev, sequence, false); + + while (result == 0 && k_sem_take(&data->ctx.sync, K_NO_WAIT) != 0) { + result = ads1x4s0x_adc_perform_read(dev); + } + + adc_context_release(&data->ctx, result); + return result; +} +#endif + +#if CONFIG_ADC_ASYNC +static void ads1x4s0x_acquisition_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; + + while (true) { + ads1x4s0x_adc_perform_read(dev); + } +} +#endif + +#ifdef CONFIG_ADC_ADS1X4S0X_GPIO +static int ads1x4s0x_gpio_write_config(const struct device *dev) +{ + struct ads1x4s0x_data *data = dev->data; + enum ads1x4s0x_register register_addresses[2]; + uint8_t register_values[ARRAY_SIZE(register_addresses)]; + uint8_t gpio_dat = 0; + uint8_t gpio_con = 0; + + ADS1X4S0X_REGISTER_GPIOCON_CON_SET(gpio_con, data->gpio_enabled); + ADS1X4S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value); + ADS1X4S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction); + + register_values[0] = gpio_dat; + register_values[1] = gpio_con; + register_addresses[0] = ADS1X4S0X_REGISTER_GPIODAT; + register_addresses[1] = ADS1X4S0X_REGISTER_GPIOCON; + return ads1x4s0x_write_multiple_registers(dev, register_addresses, register_values, + ARRAY_SIZE(register_values)); +} + +static int ads1x4s0x_gpio_write_value(const struct device *dev) +{ + struct ads1x4s0x_data *data = dev->data; + uint8_t gpio_dat = 0; + + ADS1X4S0X_REGISTER_GPIODAT_DAT_SET(gpio_dat, data->gpio_value); + ADS1X4S0X_REGISTER_GPIODAT_DIR_SET(gpio_dat, data->gpio_direction); + + return ads1x4s0x_write_register(dev, ADS1X4S0X_REGISTER_GPIODAT, gpio_dat); +} + +int ads1x4s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value) +{ + struct ads1x4s0x_data *data = dev->data; + int result = 0; + + if (pin > ADS1X4S0X_GPIO_MAX) { + LOG_ERR("%s: invalid pin %i", dev->name, pin); + return -EINVAL; + } + + k_mutex_lock(&data->gpio_lock, K_FOREVER); + + data->gpio_enabled |= BIT(pin); + data->gpio_direction &= ~BIT(pin); + + if (initial_value) { + data->gpio_value |= BIT(pin); + } else { + data->gpio_value &= ~BIT(pin); + } + + result = ads1x4s0x_gpio_write_config(dev); + + k_mutex_unlock(&data->gpio_lock); + + return result; +} + +int ads1x4s0x_gpio_set_input(const struct device *dev, uint8_t pin) +{ + struct ads1x4s0x_data *data = dev->data; + int result = 0; + + if (pin > ADS1X4S0X_GPIO_MAX) { + LOG_ERR("%s: invalid pin %i", dev->name, pin); + return -EINVAL; + } + + k_mutex_lock(&data->gpio_lock, K_FOREVER); + + data->gpio_enabled |= BIT(pin); + data->gpio_direction |= BIT(pin); + data->gpio_value &= ~BIT(pin); + + result = ads1x4s0x_gpio_write_config(dev); + + k_mutex_unlock(&data->gpio_lock); + + return result; +} + +int ads1x4s0x_gpio_deconfigure(const struct device *dev, uint8_t pin) +{ + struct ads1x4s0x_data *data = dev->data; + int result = 0; + + if (pin > ADS1X4S0X_GPIO_MAX) { + LOG_ERR("%s: invalid pin %i", dev->name, pin); + return -EINVAL; + } + + k_mutex_lock(&data->gpio_lock, K_FOREVER); + + data->gpio_enabled &= ~BIT(pin); + data->gpio_direction |= BIT(pin); + data->gpio_value &= ~BIT(pin); + + result = ads1x4s0x_gpio_write_config(dev); + + k_mutex_unlock(&data->gpio_lock); + + return result; +} + +int ads1x4s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin, bool value) +{ + struct ads1x4s0x_data *data = dev->data; + int result = 0; + + if (pin > ADS1X4S0X_GPIO_MAX) { + LOG_ERR("%s: invalid pin %i", dev->name, pin); + return -EINVAL; + } + + k_mutex_lock(&data->gpio_lock, K_FOREVER); + + if ((BIT(pin) & data->gpio_enabled) == 0) { + LOG_ERR("%s: gpio pin %i not configured", dev->name, pin); + result = -EINVAL; + } else if ((BIT(pin) & data->gpio_direction) != 0) { + LOG_ERR("%s: gpio pin %i not configured as output", dev->name, pin); + result = -EINVAL; + } else { + data->gpio_value |= BIT(pin); + + result = ads1x4s0x_gpio_write_value(dev); + } + + k_mutex_unlock(&data->gpio_lock); + + return result; +} + +int ads1x4s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin, bool *value) +{ + struct ads1x4s0x_data *data = dev->data; + int result = 0; + uint8_t gpio_dat; + + if (pin > ADS1X4S0X_GPIO_MAX) { + LOG_ERR("%s: invalid pin %i", dev->name, pin); + return -EINVAL; + } + + k_mutex_lock(&data->gpio_lock, K_FOREVER); + + if ((BIT(pin) & data->gpio_enabled) == 0) { + LOG_ERR("%s: gpio pin %i not configured", dev->name, pin); + result = -EINVAL; + } else if ((BIT(pin) & data->gpio_direction) == 0) { + LOG_ERR("%s: gpio pin %i not configured as input", dev->name, pin); + result = -EINVAL; + } else { + result = ads1x4s0x_read_register(dev, ADS1X4S0X_REGISTER_GPIODAT, &gpio_dat); + data->gpio_value = ADS1X4S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat); + *value = (BIT(pin) & data->gpio_value) != 0; + } + + k_mutex_unlock(&data->gpio_lock); + + return result; +} + +int ads1x4s0x_gpio_port_get_raw(const struct device *dev, gpio_port_value_t *value) +{ + struct ads1x4s0x_data *data = dev->data; + int result = 0; + uint8_t gpio_dat; + + k_mutex_lock(&data->gpio_lock, K_FOREVER); + + result = ads1x4s0x_read_register(dev, ADS1X4S0X_REGISTER_GPIODAT, &gpio_dat); + data->gpio_value = ADS1X4S0X_REGISTER_GPIODAT_DAT_GET(gpio_dat); + *value = data->gpio_value; + + k_mutex_unlock(&data->gpio_lock); + + return result; +} + +int ads1x4s0x_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + struct ads1x4s0x_data *data = dev->data; + int result = 0; + + k_mutex_lock(&data->gpio_lock, K_FOREVER); + + data->gpio_value = ((data->gpio_value & ~mask) | (mask & value)) & data->gpio_enabled & + ~data->gpio_direction; + result = ads1x4s0x_gpio_write_value(dev); + + k_mutex_unlock(&data->gpio_lock); + + return result; +} + +int ads1x4s0x_gpio_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) +{ + struct ads1x4s0x_data *data = dev->data; + int result = 0; + + k_mutex_lock(&data->gpio_lock, K_FOREVER); + + data->gpio_value = (data->gpio_value ^ pins) & data->gpio_enabled & ~data->gpio_direction; + result = ads1x4s0x_gpio_write_value(dev); + + k_mutex_unlock(&data->gpio_lock); + + return result; +} + +#endif /* CONFIG_ADC_ADS1X4S0X_GPIO */ + +static int ads1x4s0x_init(const struct device *dev) +{ + uint8_t status = 0; + uint8_t reference_control = 0; + uint8_t reference_control_read; + int result; + const struct ads1x4s0x_config *config = dev->config; + struct ads1x4s0x_data *data = dev->data; + + adc_context_init(&data->ctx); + + k_sem_init(&data->data_ready_signal, 0, 1); + k_sem_init(&data->acquire_signal, 0, 1); + +#ifdef CONFIG_ADC_ADS1X4S0X_GPIO + k_mutex_init(&data->gpio_lock); +#endif /* CONFIG_ADC_ADS1X4S0X_GPIO */ + + if (!spi_is_ready_dt(&config->bus)) { + LOG_ERR("%s: SPI device is not ready", dev->name); + return -ENODEV; + } + + if (config->gpio_reset.port != NULL) { + result = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE); + if (result != 0) { + LOG_ERR("%s: failed to initialize GPIO for reset", dev->name); + return result; + } + } + + if (config->gpio_start_sync.port != NULL) { + result = gpio_pin_configure_dt(&config->gpio_start_sync, GPIO_OUTPUT_INACTIVE); + if (result != 0) { + LOG_ERR("%s: failed to initialize GPIO for start/sync", dev->name); + return result; + } + } + + result = gpio_pin_configure_dt(&config->gpio_data_ready, GPIO_INPUT); + if (result != 0) { + LOG_ERR("%s: failed to initialize GPIO for data ready", dev->name); + return result; + } + + result = gpio_pin_interrupt_configure_dt(&config->gpio_data_ready, GPIO_INT_EDGE_TO_ACTIVE); + if (result != 0) { + LOG_ERR("%s: failed to configure data ready interrupt", dev->name); + return -EIO; + } + + gpio_init_callback(&data->callback_data_ready, ads1x4s0x_data_ready_handler, + BIT(config->gpio_data_ready.pin)); + result = gpio_add_callback(config->gpio_data_ready.port, &data->callback_data_ready); + if (result != 0) { + LOG_ERR("%s: failed to add data ready callback", dev->name); + return -EIO; + } + +#if CONFIG_ADC_ASYNC + k_tid_t tid = k_thread_create(&data->thread, config->stack, + CONFIG_ADC_ADS1X4S0X_ACQUISITION_THREAD_STACK_SIZE, + ads1x4s0x_acquisition_thread, (void *)dev, NULL, NULL, + CONFIG_ADC_ADS1X4S0X_ASYNC_THREAD_INIT_PRIO, 0, K_NO_WAIT); + k_thread_name_set(tid, "adc_ads1x4s0x"); +#endif + + k_busy_wait(ADS1X4S0X_POWER_ON_RESET_TIME_IN_US); + + if (config->gpio_reset.port == NULL) { + result = ads1x4s0x_send_command(dev, ADS1X4S0X_COMMAND_RESET); + if (result != 0) { + LOG_ERR("%s: unable to send RESET command", dev->name); + return result; + } + } else { + k_busy_wait(ADS1X4S0X_RESET_LOW_TIME_IN_US); + gpio_pin_set_dt(&config->gpio_reset, 0); + } + + k_busy_wait(ADS1X4S0X_RESET_DELAY_TIME_IN_US); + + result = ads1x4s0x_read_register(dev, ADS1X4S0X_REGISTER_STATUS, &status); + if (result != 0) { + LOG_ERR("%s: unable to read status register", dev->name); + return result; + } + + if (ADS1X4S0X_REGISTER_STATUS_NOT_RDY_GET(status) == 0x01) { + LOG_ERR("%s: ADS114 is not yet ready", dev->name); + return -EBUSY; + } + + /* + * Activate internal voltage reference during initialization to + * avoid the necessary setup time for it to settle later on. + */ + ADS1X4S0X_REGISTER_REF_SET_DEFAULTS(reference_control); + + result = ads1x4s0x_write_register(dev, ADS1X4S0X_REGISTER_REF, reference_control); + if (result != 0) { + LOG_ERR("%s: unable to set default reference control values", dev->name); + return result; + } + + /* + * Ensure that the internal voltage reference is active. + */ + result = ads1x4s0x_read_register(dev, ADS1X4S0X_REGISTER_REF, &reference_control_read); + if (result != 0) { + LOG_ERR("%s: unable to read reference control values", dev->name); + return result; + } + + if (reference_control != reference_control_read) { + LOG_ERR("%s: reference control register is incorrect: 0x%02X", dev->name, + reference_control_read); + return -EIO; + } + +#ifdef CONFIG_ADC_ADS1X4S0X_GPIO + data->gpio_enabled = 0x00; + data->gpio_direction = 0x0F; + data->gpio_value = 0x00; + + result = ads1x4s0x_gpio_write_config(dev); + + if (result != 0) { + LOG_ERR("%s: unable to configure defaults for GPIOs", dev->name); + return result; + } +#endif + + adc_context_unlock_unconditionally(&data->ctx); + + return result; +} + +static DEVICE_API(adc, api) = { + .channel_setup = ads1x4s0x_channel_setup, + .read = ads1x4s0x_read, + .ref_internal = ADS1X4S0X_REF_INTERNAL, +#ifdef CONFIG_ADC_ASYNC + .read_async = ads1x4s0x_adc_read_async, +#endif +}; +BUILD_ASSERT(CONFIG_ADC_INIT_PRIORITY > CONFIG_SPI_INIT_PRIORITY, + "CONFIG_ADC_INIT_PRIORITY must be higher than CONFIG_SPI_INIT_PRIORITY"); + +#define ADC_ADS1X4S0X_INST_DEFINE(n, name, ch, res) \ + IF_ENABLED( \ + CONFIG_ADC_ASYNC, \ + (static K_KERNEL_STACK_DEFINE( \ + thread_stack_##name##_##n, \ + CONFIG_ADC_ADS1X4S0X_ACQUISITION_THREAD_STACK_SIZE);) \ + ) \ + static const struct ads1x4s0x_config config_##name##_##n = { \ + .bus = SPI_DT_SPEC_INST_GET( \ + n, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(8), 0), \ + IF_ENABLED(CONFIG_ADC_ASYNC, (.stack = thread_stack_##n,)) \ + .gpio_reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \ + .gpio_data_ready = GPIO_DT_SPEC_INST_GET(n, drdy_gpios), \ + .gpio_start_sync = GPIO_DT_SPEC_INST_GET_OR(n, start_sync_gpios, {0}), \ + .idac_current = DT_INST_PROP(n, idac_current), \ + .vbias_level = DT_INST_PROP(n, vbias_level), \ + .vbias_level = DT_INST_PROP(n, vbias_level), \ + .resolution = res, \ + .channels = ch, \ + }; \ + static struct ads1x4s0x_data data_##name##_##n; \ + DEVICE_DT_INST_DEFINE(n, ads1x4s0x_init, NULL, &data_##name##_##n, &config_##name##_##n, \ + POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, &api); + +/* + * ADS114S06: 16 bit, 6 channels + */ +#define DT_DRV_COMPAT ti_ads114s06 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +#define ADC_ADS114S06_INST_DEFINE(n) ADC_ADS1X4S0X_INST_DEFINE(n, ti_ads114s06, 6, 16) +DT_INST_FOREACH_STATUS_OKAY(ADC_ADS114S06_INST_DEFINE); +#endif + +/* + * ADS114S08: 16 bit, 12 channels + */ +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT ti_ads114s08 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +#define ADC_ADS114S08_INST_DEFINE(n) ADC_ADS1X4S0X_INST_DEFINE(n, ti_ads114s08, 12, 16) +DT_INST_FOREACH_STATUS_OKAY(ADC_ADS114S08_INST_DEFINE); +#endif + +/* + * ADS124S06: 24 bit, 6 channels + */ +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT ti_ads124s06 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +#define ADC_ADS124S06_INST_DEFINE(n) ADC_ADS1X4S0X_INST_DEFINE(n, ti_ads124s06, 6, 24) +DT_INST_FOREACH_STATUS_OKAY(ADC_ADS124S06_INST_DEFINE); +#endif + +/* + * ADS124S08: 24 bit, 12 channels + */ +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT ti_ads124s08 +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +#define ADC_ADS124S08_INST_DEFINE(n) ADC_ADS1X4S0X_INST_DEFINE(n, ti_ads124s08, 12, 24) +DT_INST_FOREACH_STATUS_OKAY(ADC_ADS124S08_INST_DEFINE); +#endif diff --git a/drivers/adc/adc_common.c b/drivers/adc/adc_common.c index cf6472718dec0..eed4ec4ead6c0 100644 --- a/drivers/adc/adc_common.c +++ b/drivers/adc/adc_common.c @@ -17,6 +17,7 @@ int adc_gain_invert(enum adc_gain gain, [ADC_GAIN_1_6] = {.mul = 6, .div = 1}, [ADC_GAIN_1_5] = {.mul = 5, .div = 1}, [ADC_GAIN_1_4] = {.mul = 4, .div = 1}, + [ADC_GAIN_2_7] = {.mul = 7, .div = 2}, [ADC_GAIN_1_3] = {.mul = 3, .div = 1}, [ADC_GAIN_2_5] = {.mul = 5, .div = 2}, [ADC_GAIN_1_2] = {.mul = 2, .div = 1}, diff --git a/drivers/adc/adc_emul.c b/drivers/adc/adc_emul.c index 8630516d8212b..a74fc011fa73e 100644 --- a/drivers/adc/adc_emul.c +++ b/drivers/adc/adc_emul.c @@ -31,6 +31,8 @@ typedef uint16_t adc_emul_res_t; enum adc_emul_input_source { ADC_EMUL_CONST_VALUE, ADC_EMUL_CUSTOM_FUNC, + ADC_EMUL_CONST_RAW_VALUE, + ADC_EMUL_CUSTOM_FUNC_RAW_VALUE, }; /** @@ -39,11 +41,11 @@ enum adc_emul_input_source { * This structure contains configuration of one channel of emulated ADC. */ struct adc_emul_chan_cfg { - /** Pointer to function used to obtain input mV */ + /** Pointer to function used to obtain input mV or raw input value */ adc_emul_value_func func; /** Pointer to data that are passed to @a func on call */ void *func_data; - /** Constant mV input value */ + /** Constant mV input value or raw input value */ uint32_t const_value; /** Gain used on output value */ enum adc_gain gain; @@ -127,8 +129,31 @@ int adc_emul_const_value_set(const struct device *dev, unsigned int chan, return 0; } -int adc_emul_value_func_set(const struct device *dev, unsigned int chan, - adc_emul_value_func func, void *func_data) +int adc_emul_const_raw_value_set(const struct device *dev, unsigned int chan, uint32_t raw_value) +{ + const struct adc_emul_config *config = dev->config; + struct adc_emul_data *data = dev->data; + struct adc_emul_chan_cfg *chan_cfg; + + if (chan >= config->num_channels) { + LOG_ERR("unsupported channel %d", chan); + return -EINVAL; + } + + chan_cfg = &data->chan_cfg[chan]; + + k_mutex_lock(&data->cfg_mtx, K_FOREVER); + + chan_cfg->input = ADC_EMUL_CONST_RAW_VALUE; + chan_cfg->const_value = raw_value; + + k_mutex_unlock(&data->cfg_mtx); + + return 0; +} + +int adc_emul_value_func_set(const struct device *dev, unsigned int chan, adc_emul_value_func func, + void *func_data) { const struct adc_emul_config *config = dev->config; struct adc_emul_data *data = dev->data; @@ -152,6 +177,31 @@ int adc_emul_value_func_set(const struct device *dev, unsigned int chan, return 0; } +int adc_emul_raw_value_func_set(const struct device *dev, unsigned int chan, + adc_emul_value_func func, void *func_data) +{ + const struct adc_emul_config *config = dev->config; + struct adc_emul_data *data = dev->data; + struct adc_emul_chan_cfg *chan_cfg; + + if (chan >= config->num_channels) { + LOG_ERR("unsupported channel %d", chan); + return -EINVAL; + } + + chan_cfg = &data->chan_cfg[chan]; + + k_mutex_lock(&data->cfg_mtx, K_FOREVER); + + chan_cfg->func = func; + chan_cfg->func_data = func_data; + chan_cfg->input = ADC_EMUL_CUSTOM_FUNC_RAW_VALUE; + + k_mutex_unlock(&data->cfg_mtx); + + return 0; +} + int adc_emul_ref_voltage_set(const struct device *dev, enum adc_reference ref, uint16_t value) { @@ -344,24 +394,34 @@ static int adc_emul_start_read(const struct device *dev, return adc_context_wait_for_completion(&data->ctx); } -static int adc_emul_read_async(const struct device *dev, +static int adc_emul_read_common(const struct device *dev, const struct adc_sequence *sequence, + bool is_async, struct k_poll_signal *async) { struct adc_emul_data *data = dev->data; int err; - adc_context_lock(&data->ctx, async ? true : false, async); + adc_context_lock(&data->ctx, is_async, async); err = adc_emul_start_read(dev, sequence); adc_context_release(&data->ctx, err); return err; } +#ifdef CONFIG_ADC_ASYNC +static int adc_emul_read_async(const struct device *dev, + const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + return adc_emul_read_common(dev, sequence, true, async); +} +#endif + static int adc_emul_read(const struct device *dev, const struct adc_sequence *sequence) { - return adc_emul_read_async(dev, sequence, NULL); + return adc_emul_read_common(dev, sequence, false, NULL); } static void adc_context_start_sampling(struct adc_context *ctx) @@ -426,6 +486,19 @@ static int adc_emul_get_chan_value(struct adc_emul_data *data, } break; + case ADC_EMUL_CONST_RAW_VALUE: + temp = chan_cfg->const_value; + goto check_bound_and_out; + + case ADC_EMUL_CUSTOM_FUNC_RAW_VALUE: + err = chan_cfg->func(data->dev, chan, chan_cfg->func_data, &input_mV); + if (err) { + LOG_ERR("failed to read channel %d (err %d)", chan, err); + goto out; + } + temp = input_mV; + goto check_bound_and_out; + default: LOG_ERR("unknown input source %d", chan_cfg->input); err = -EINVAL; @@ -444,6 +517,7 @@ static int adc_emul_get_chan_value(struct adc_emul_data *data, /* Calculate output value */ temp = (uint64_t)input_mV * data->res_mask / ref_v; +check_bound_and_out: /* If output value is greater than resolution, it has to be trimmed */ if (temp > data->res_mask) { temp = data->res_mask; diff --git a/drivers/adc/adc_ene_kb1200.c b/drivers/adc/adc_ene_kb1200.c index 3078d0b915d6e..9abae01f52ad3 100644 --- a/drivers/adc/adc_ene_kb1200.c +++ b/drivers/adc/adc_ene_kb1200.c @@ -11,10 +11,13 @@ #include #include #include +#include #define ADC_CONTEXT_USES_KERNEL_TIMER #include "adc_context.h" +LOG_MODULE_REGISTER(adc_ene_kb1200, CONFIG_ADC_LOG_LEVEL); + struct adc_kb1200_config { /* ADC Register base address */ struct adc_regs *adc; @@ -70,17 +73,17 @@ static int adc_kb1200_start_read(const struct device *dev, const struct adc_sequ int error = 0; if (!sequence->channels || (sequence->channels & ~BIT_MASK(ADC_MAX_CHAN))) { - printk("Invalid ADC channels.\n"); + LOG_ERR("Invalid ADC channels."); return -EINVAL; } /* Fixed 10 bit resolution of ene ADC */ if (sequence->resolution != ADC_RESOLUTION) { - printk("Unfixed 10 bit ADC resolution.\n"); + LOG_ERR("Unfixed 10 bit ADC resolution."); return -ENOTSUP; } /* Check sequence->buffer_size is enough */ if (!adc_kb1200_validate_buffer_size(sequence)) { - printk("ADC buffer size too small.\n"); + LOG_ERR("ADC buffer size too small."); return -ENOMEM; } @@ -107,7 +110,7 @@ static int adc_kb1200_start_read(const struct device *dev, const struct adc_sequ k_busy_wait(ADC_WAIT_TIME); count++; if (count >= ADC_WAIT_CNT) { - printk("ADC busy timeout...\n"); + LOG_ERR("ADC busy timeout..."); error = -EBUSY; break; } @@ -136,30 +139,30 @@ static int adc_kb1200_channel_setup(const struct device *dev, const struct adc_channel_cfg *channel_cfg) { if (channel_cfg->channel_id >= ADC_MAX_CHAN) { - printk("Invalid channel %d.\n", channel_cfg->channel_id); + LOG_ERR("Invalid channel %d.", channel_cfg->channel_id); return -EINVAL; } if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) { - printk("Unsupported channel acquisition time.\n"); + LOG_ERR("Unsupported channel acquisition time."); return -ENOTSUP; } if (channel_cfg->differential) { - printk("Differential channels are not supported.\n"); + LOG_ERR("Differential channels are not supported."); return -ENOTSUP; } if (channel_cfg->gain != ADC_GAIN_1) { - printk("Unsupported channel gain %d.\n", channel_cfg->gain); + LOG_ERR("Unsupported channel gain %d.", channel_cfg->gain); return -ENOTSUP; } if (channel_cfg->reference != ADC_REF_INTERNAL) { - printk("Unsupported channel reference.\n"); + LOG_ERR("Unsupported channel reference."); return -ENOTSUP; } - printk("ADC channel %d configured.\n", channel_cfg->channel_id); + LOG_DBG("ADC channel %d configured.", channel_cfg->channel_id); return 0; } @@ -199,7 +202,7 @@ static void adc_context_start_sampling(struct adc_context *ctx) data->repeat_buffer = data->buffer; config->adc->ADCCFG = (config->adc->ADCCFG & ~ADC_CHANNEL_BIT_MASK) | - (ctx->sequence.channels << ADC_CHANNEL_BIT_POS); + (ctx->sequence.channels << ADC_CHANNEL_BIT_POS); config->adc->ADCCFG |= ADC_FUNCTION_ENABLE; } @@ -231,7 +234,7 @@ static int adc_kb1200_init(const struct device *dev) /* Configure pin-mux for ADC device */ ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); if (ret < 0) { - printk("ADC pinctrl setup failed (%d).\n", ret); + LOG_ERR("ADC pinctrl setup failed (%d).", ret); return ret; } @@ -249,7 +252,7 @@ static int adc_kb1200_init(const struct device *dev) .adc = (struct adc_regs *)DT_INST_REG_ADDR(inst), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ }; \ - DEVICE_DT_INST_DEFINE(inst, &adc_kb1200_init, NULL, &adc_kb1200_data_##inst, \ + DEVICE_DT_INST_DEFINE(inst, adc_kb1200_init, NULL, &adc_kb1200_data_##inst, \ &adc_kb1200_config_##inst, PRE_KERNEL_1, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &adc_kb1200_api); diff --git a/drivers/adc/adc_esp32.c b/drivers/adc/adc_esp32.c index e6d43b0c7e7c4..d41795d2c4362 100644 --- a/drivers/adc/adc_esp32.c +++ b/drivers/adc/adc_esp32.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Espressif Systems (Shanghai) CO LTD + * Copyright (c) 2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,9 +8,11 @@ #include #include +#include #include #include -#include +#include +#include #include #include #include @@ -28,52 +30,40 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(adc_esp32, CONFIG_ADC_LOG_LEVEL); -#define ADC_RESOLUTION_MIN SOC_ADC_DIGI_MIN_BITWIDTH -#define ADC_RESOLUTION_MAX SOC_ADC_DIGI_MAX_BITWIDTH +#define ADC_RESOLUTION_MIN SOC_ADC_DIGI_MIN_BITWIDTH +#define ADC_RESOLUTION_MAX SOC_ADC_DIGI_MAX_BITWIDTH -#if CONFIG_SOC_SERIES_ESP32 -#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_VREF -/* Due to significant measurement discrepancy in higher voltage range, we - * clip the value instead of yet another correction. The IDF implementation - * for ESP32-S2 is doing it, so we copy that approach in Zephyr driver - */ -#define ADC_CLIP_MVOLT_12DB 2550 -#elif CONFIG_SOC_SERIES_ESP32S3 -#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP_FIT -#else -#define ADC_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP -#endif - -/* Validate if resolution in bits is within allowed values */ #define VALID_RESOLUTION(r) ((r) >= ADC_RESOLUTION_MIN && (r) <= ADC_RESOLUTION_MAX) -#define INVALID_RESOLUTION(r) (!VALID_RESOLUTION(r)) /* Default internal reference voltage */ #define ADC_ESP32_DEFAULT_VREF_INTERNAL (1100) -#define ADC_DMA_BUFFER_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED +#define ADC_DMA_BUFFER_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED struct adc_esp32_conf { + const struct device *clock_dev; + const clock_control_subsys_t clock_subsys; adc_unit_t unit; uint8_t channel_count; -#if defined(CONFIG_ADC_ESP32_DMA) const struct device *gpio_port; +#if defined(CONFIG_ADC_ESP32_DMA) const struct device *dma_dev; uint8_t dma_channel; #endif /* defined(CONFIG_ADC_ESP32_DMA) */ }; struct adc_esp32_data { + adc_oneshot_hal_ctx_t hal; adc_atten_t attenuation[SOC_ADC_MAX_CHANNEL_NUM]; uint8_t resolution[SOC_ADC_MAX_CHANNEL_NUM]; - esp_adc_cal_characteristics_t chars[SOC_ADC_MAX_CHANNEL_NUM]; + adc_cali_handle_t cal_handle[SOC_ADC_MAX_CHANNEL_NUM]; uint16_t meas_ref_internal; uint16_t *buffer; - bool calibrate; #if defined(CONFIG_ADC_ESP32_DMA) adc_hal_dma_ctx_t adc_hal_dma_ctx; uint8_t *dma_buffer; @@ -103,30 +93,6 @@ static inline int gain_to_atten(enum adc_gain gain, adc_atten_t *atten) return 0; } -#if !defined(CONFIG_ADC_ESP32_DMA) -/* Convert voltage by inverted attenuation to support zephyr gain values */ -static void atten_to_gain(adc_atten_t atten, uint32_t *val_mv) -{ - if (!val_mv) { - return; - } - switch (atten) { - case ADC_ATTEN_DB_2_5: - *val_mv = (*val_mv * 4) / 5; /* 1/ADC_GAIN_4_5 */ - break; - case ADC_ATTEN_DB_6: - *val_mv = *val_mv >> 1; /* 1/ADC_GAIN_1_2 */ - break; - case ADC_ATTEN_DB_12: - *val_mv = *val_mv / 4; /* 1/ADC_GAIN_1_4 */ - break; - case ADC_ATTEN_DB_0: /* 1/ADC_GAIN_1 */ - default: - break; - } -} -#endif /* !defined(CONFIG_ADC_ESP32_DMA) */ - static void adc_hw_calibration(adc_unit_t unit) { #if SOC_ADC_CALIBRATION_V1_SUPPORTED @@ -143,26 +109,6 @@ static void adc_hw_calibration(adc_unit_t unit) #endif /* SOC_ADC_CALIBRATION_V1_SUPPORTED */ } -static bool adc_calibration_init(const struct device *dev) -{ - switch (esp_adc_cal_check_efuse(ADC_CALI_SCHEME)) { - case ESP_ERR_NOT_SUPPORTED: - LOG_WRN("Skip software calibration - Not supported!"); - break; - case ESP_ERR_INVALID_VERSION: - LOG_WRN("Skip software calibration - Invalid version!"); - break; - case ESP_OK: - LOG_DBG("Software calibration possible"); - return true; - default: - LOG_ERR("Invalid arg"); - break; - } - - return false; -} - #if defined(CONFIG_ADC_ESP32_DMA) static void IRAM_ATTR adc_esp32_dma_conv_done(const struct device *dma_dev, void *user_data, @@ -180,7 +126,6 @@ static void IRAM_ATTR adc_esp32_dma_conv_done(const struct device *dma_dev, void static int adc_esp32_dma_start(const struct device *dev, uint8_t *buf, size_t len) { const struct adc_esp32_conf *conf = dev->config; - struct adc_esp32_data *data = dev->data; int err = 0; struct dma_config dma_cfg = {0}; @@ -243,13 +188,14 @@ static int adc_esp32_dma_stop(const struct device *dev) } static int adc_esp32_fill_digi_pattern(const struct device *dev, const struct adc_sequence *seq, - void *pattern_config, uint32_t *pattern_len, uint32_t *unit_attenuation) + void *pattern_config, uint32_t *pattern_len, + uint32_t *unit_attenuation) { const struct adc_esp32_conf *conf = dev->config; struct adc_esp32_data *data = dev->data; adc_digi_pattern_config_t *adc_digi_pattern_config = - (adc_digi_pattern_config_t *)pattern_config; + (adc_digi_pattern_config_t *)pattern_config; const uint32_t unit_atten_uninit = 999; uint32_t channel_mask = 1, channels_copy = seq->channels; @@ -300,7 +246,7 @@ static void adc_esp32_digi_start(const struct device *dev, void *pattern_config, #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_set_hw_calibration_code(conf->unit, unit_attenuation); -#endif /* SOC_ADC_CALIBRATION_V1_SUPPORTED */ +#endif /* SOC_ADC_CALIBRATION_V1_SUPPORTED */ #if SOC_ADC_ARBITER_SUPPORTED if (conf->unit == ADC_UNIT_2) { @@ -308,7 +254,7 @@ static void adc_esp32_digi_start(const struct device *dev, void *pattern_config, adc_hal_arbiter_config(&config); } -#endif /* SOC_ADC_ARBITER_SUPPORTED */ +#endif /* SOC_ADC_ARBITER_SUPPORTED */ adc_hal_digi_ctrlr_cfg_t adc_hal_digi_ctrlr_cfg; soc_module_clk_t clk_src = ADC_DIGI_CLK_SRC_DEFAULT; @@ -318,7 +264,7 @@ static void adc_esp32_digi_start(const struct device *dev, void *pattern_config, &clk_src_freq_hz); adc_hal_digi_ctrlr_cfg.conv_mode = - (conf->unit == ADC_UNIT_1)?ADC_CONV_SINGLE_UNIT_1:ADC_CONV_SINGLE_UNIT_2; + (conf->unit == ADC_UNIT_1) ? ADC_CONV_SINGLE_UNIT_1 : ADC_CONV_SINGLE_UNIT_2; adc_hal_digi_ctrlr_cfg.clk_src = clk_src; adc_hal_digi_ctrlr_cfg.clk_src_freq_hz = clk_src_freq_hz; adc_hal_digi_ctrlr_cfg.sample_freq_hz = sample_freq_hz; @@ -384,10 +330,7 @@ static int adc_esp32_wait_for_dma_conv_done(const struct device *dev) static int adc_esp32_read(const struct device *dev, const struct adc_sequence *seq) { - const struct adc_esp32_conf *conf = dev->config; struct adc_esp32_data *data = dev->data; - int reading; - uint32_t cal, cal_mv; uint8_t channel_id = find_lsb_set(seq->channels) - 1; @@ -417,7 +360,7 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s #endif /* !defined(CONFIG_ADC_ESP32_DMA) */ } - if (INVALID_RESOLUTION(seq->resolution)) { + if (!VALID_RESOLUTION(seq->resolution)) { LOG_ERR("unsupported resolution (%d)", seq->resolution); return -ENOTSUP; } @@ -430,55 +373,33 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s data->resolution[channel_id] = seq->resolution; -#if CONFIG_SOC_SERIES_ESP32C3 - /* NOTE: nothing to set on ESP32C3 SoC */ - if (conf->unit == ADC_UNIT_1) { - adc1_config_width(ADC_WIDTH_BIT_DEFAULT); - } -#else - adc_set_data_width(conf->unit, data->resolution[channel_id]); -#endif /* CONFIG_SOC_SERIES_ESP32C3 */ - #if !defined(CONFIG_ADC_ESP32_DMA) - /* Read raw value */ - if (conf->unit == ADC_UNIT_1) { - reading = adc1_get_raw(channel_id); - } - if (conf->unit == ADC_UNIT_2) { - if (adc2_get_raw(channel_id, ADC_WIDTH_BIT_DEFAULT, &reading)) { - LOG_ERR("Conversion timeout on '%s' channel %d", dev->name, channel_id); - return -ETIMEDOUT; - } - } - /* Calibration scheme is available */ - if (data->calibrate) { - data->chars[channel_id].bit_width = data->resolution[channel_id]; - /* Get corrected voltage output */ - cal = cal_mv = esp_adc_cal_raw_to_voltage(reading, &data->chars[channel_id]); + uint32_t acq_raw, acq_mv, result; -#if CONFIG_SOC_SERIES_ESP32 - if (data->attenuation[channel_id] == ADC_ATTEN_DB_12) { - if (cal > ADC_CLIP_MVOLT_12DB) { - cal = ADC_CLIP_MVOLT_12DB; - } - } -#endif /* CONFIG_SOC_SERIES_ESP32 */ + adc_oneshot_hal_setup(&data->hal, channel_id); - /* Fit according to selected attenuation */ - atten_to_gain(data->attenuation[channel_id], &cal); - if (data->meas_ref_internal > 0) { - cal = (cal << data->resolution[channel_id]) / data->meas_ref_internal; - } +#if SOC_ADC_CALIBRATION_V1_SUPPORTED + adc_set_hw_calibration_code(data->hal.unit, data->attenuation[channel_id]); +#endif /* SOC_ADC_CALIBRATION_V1_SUPPORTED */ + + adc_oneshot_hal_convert(&data->hal, &acq_raw); + + if (data->cal_handle[channel_id]) { + adc_cali_raw_to_voltage(data->cal_handle[channel_id], acq_raw, &acq_mv); + + LOG_DBG("ADC acquisition [unit: %u, chan: %u, acq_raw: %u, acq_mv: %u]", + data->hal.unit, channel_id, acq_raw, acq_mv); + + result = acq_mv; } else { - LOG_DBG("Using uncalibrated values!"); - /* Uncalibrated raw value */ - cal = reading; + LOG_WRN("ADC values are raw (uncalibrated)"); + result = acq_raw; } /* Store result */ - data->buffer = (uint16_t *) seq->buffer; - data->buffer[0] = cal; + data->buffer = (uint16_t *)seq->buffer; + data->buffer[0] = result; #else /* !defined(CONFIG_ADC_ESP32_DMA) */ @@ -486,15 +407,14 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s uint32_t adc_pattern_len, unit_attenuation; adc_digi_pattern_config_t adc_digi_pattern_config[SOC_ADC_MAX_CHANNEL_NUM]; - err = adc_esp32_fill_digi_pattern(dev, seq, &adc_digi_pattern_config, - &adc_pattern_len, &unit_attenuation); + err = adc_esp32_fill_digi_pattern(dev, seq, &adc_digi_pattern_config, &adc_pattern_len, + &unit_attenuation); if (err || adc_pattern_len == 0) { return -EINVAL; } const struct adc_sequence_options *options = seq->options; - uint32_t sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, - number_of_samplings = 1; + uint32_t sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, number_of_samplings = 1; if (options != NULL) { number_of_samplings = seq->buffer_size / (adc_pattern_len * sizeof(uint16_t)); @@ -509,7 +429,7 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s return -EINVAL; } - if (sample_freq_hz < SOC_ADC_SAMPLE_FREQ_THRES_LOW || + if (sample_freq_hz < SOC_ADC_SAMPLE_FREQ_THRES_LOW || sample_freq_hz > SOC_ADC_SAMPLE_FREQ_THRES_HIGH) { LOG_ERR("ADC sampling frequency out of range: %uHz", sample_freq_hz); return -EINVAL; @@ -517,7 +437,7 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s uint32_t number_of_adc_samples = number_of_samplings * adc_pattern_len; uint32_t number_of_adc_dma_data_bytes = - number_of_adc_samples * SOC_ADC_DIGI_DATA_BYTES_PER_CONV; + number_of_adc_samples * SOC_ADC_DIGI_DATA_BYTES_PER_CONV; if (number_of_adc_dma_data_bytes > ADC_DMA_BUFFER_SIZE) { LOG_ERR("dma buffer size insufficient to store a complete sequence!"); @@ -552,8 +472,7 @@ static int adc_esp32_read(const struct device *dev, const struct adc_sequence *s } #ifdef CONFIG_ADC_ASYNC -static int adc_esp32_read_async(const struct device *dev, - const struct adc_sequence *sequence, +static int adc_esp32_read_async(const struct device *dev, const struct adc_sequence *sequence, struct k_poll_signal *async) { (void)(dev); @@ -567,7 +486,8 @@ static int adc_esp32_read_async(const struct device *dev, static int adc_esp32_channel_setup(const struct device *dev, const struct adc_channel_cfg *cfg) { const struct adc_esp32_conf *conf = (const struct adc_esp32_conf *)dev->config; - struct adc_esp32_data *data = (struct adc_esp32_data *) dev->data; + struct adc_esp32_data *data = (struct adc_esp32_data *)dev->data; + adc_atten_t old_atten = data->attenuation[cfg->channel_id]; if (cfg->channel_id >= conf->channel_count) { LOG_ERR("Unsupported channel id '%d'", cfg->channel_id); @@ -594,33 +514,68 @@ static int adc_esp32_channel_setup(const struct device *dev, const struct adc_ch return -ENOTSUP; } - /* Prepare channel */ - if (conf->unit == ADC_UNIT_1) { - adc1_config_channel_atten(cfg->channel_id, data->attenuation[cfg->channel_id]); - } - if (conf->unit == ADC_UNIT_2) { - adc2_config_channel_atten(cfg->channel_id, data->attenuation[cfg->channel_id]); - } - - if (data->calibrate) { - esp_adc_cal_value_t cal = esp_adc_cal_characterize(conf->unit, - data->attenuation[cfg->channel_id], - data->resolution[cfg->channel_id], - data->meas_ref_internal, - &data->chars[cfg->channel_id]); - if (cal >= ESP_ADC_CAL_VAL_NOT_SUPPORTED) { - LOG_ERR("Calibration error or not supported"); - return -EIO; + adc_oneshot_hal_chan_cfg_t config = { + .atten = data->attenuation[cfg->channel_id], + .bitwidth = data->resolution[cfg->channel_id], + }; + + adc_oneshot_hal_channel_config(&data->hal, &config, cfg->channel_id); + + if ((data->cal_handle[cfg->channel_id] == NULL) || + (data->attenuation[cfg->channel_id] != old_atten)) { +#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED + adc_cali_curve_fitting_config_t cal_config = { + .unit_id = conf->unit, + .chan = cfg->channel_id, + .atten = data->attenuation[cfg->channel_id], + .bitwidth = data->resolution[cfg->channel_id], + }; + + LOG_DBG("Curve fitting calib [unit_id: %u, chan: %u, atten: %u, bitwidth: %u]", + conf->unit, cfg->channel_id, data->attenuation[cfg->channel_id], + data->resolution[cfg->channel_id]); + + if (data->cal_handle[cfg->channel_id] != NULL) { + /* delete pre-existing calib scheme */ + adc_cali_delete_scheme_curve_fitting(data->cal_handle[cfg->channel_id]); } - LOG_DBG("Using ADC calibration method %d", cal); + + adc_cali_create_scheme_curve_fitting(&cal_config, + &data->cal_handle[cfg->channel_id]); +#endif /* ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED */ + +#if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + adc_cali_line_fitting_config_t cal_config = { + .unit_id = conf->unit, + .atten = data->attenuation[cfg->channel_id], + .bitwidth = data->resolution[cfg->channel_id], +#if CONFIG_SOC_SERIES_ESP32 + .default_vref = data->meas_ref_internal +#endif + }; + + LOG_DBG("Line fitting calib [unit_id: %u, chan: %u, atten: %u, bitwidth: %u]", + conf->unit, cfg->channel_id, data->attenuation[cfg->channel_id], + data->resolution[cfg->channel_id]); + + if (data->cal_handle[cfg->channel_id] != NULL) { + /* delete pre-existing calib scheme */ + adc_cali_delete_scheme_line_fitting(data->cal_handle[cfg->channel_id]); + } + + adc_cali_create_scheme_line_fitting(&cal_config, + &data->cal_handle[cfg->channel_id]); +#endif /* ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED */ } #if defined(CONFIG_ADC_ESP32_DMA) - if (!SOC_ADC_DIG_SUPPORTED_UNIT(conf->unit)) { LOG_ERR("ADC2 dma mode is no longer supported, please use ADC1!"); return -EINVAL; } +#endif /* defined(CONFIG_ADC_ESP32_DMA) */ + + /* GPIO config for ADC mode */ int io_num = adc_channel_io_map[conf->unit][cfg->channel_id]; @@ -642,37 +597,50 @@ static int adc_esp32_channel_setup(const struct device *dev, const struct adc_ch return err; } -#endif /* defined(CONFIG_ADC_ESP32_DMA) */ - return 0; } static int adc_esp32_init(const struct device *dev) { - struct adc_esp32_data *data = (struct adc_esp32_data *) dev->data; - const struct adc_esp32_conf *conf = (struct adc_esp32_conf *) dev->config; - - adc_hw_calibration(conf->unit); + struct adc_esp32_data *data = (struct adc_esp32_data *)dev->data; + const struct adc_esp32_conf *conf = (struct adc_esp32_conf *)dev->config; + uint32_t clock_src_hz; -#if CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3 - if (conf->unit == ADC_UNIT_2) { - adc2_init_code_calibration(); +#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED + if (!device_is_ready(conf->clock_dev)) { + return -ENODEV; } -#endif /* CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3 */ -#if defined(CONFIG_ADC_ESP32_DMA) + clock_control_on(conf->clock_dev, conf->clock_subsys); +#endif + + esp_clk_tree_src_get_freq_hz(ADC_DIGI_CLK_SRC_DEFAULT, + ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_src_hz); + + adc_oneshot_hal_cfg_t config = { + .unit = conf->unit, + .work_mode = ADC_HAL_SINGLE_READ_MODE, + .clk_src = ADC_DIGI_CLK_SRC_DEFAULT, + .clk_src_freq_hz = clock_src_hz, + }; + + adc_oneshot_hal_init(&data->hal, &config); + + sar_periph_ctrl_adc_oneshot_power_acquire(); + if (!device_is_ready(conf->gpio_port)) { LOG_ERR("gpio0 port not ready"); return -ENODEV; } +#if defined(CONFIG_ADC_ESP32_DMA) + if (k_sem_init(&data->dma_conv_wait_lock, 0, 1)) { LOG_ERR("dma_conv_wait_lock initialization failed!"); return -EINVAL; } - data->adc_hal_dma_ctx.rx_desc = k_aligned_alloc(sizeof(uint32_t), - sizeof(dma_descriptor_t)); + data->adc_hal_dma_ctx.rx_desc = k_aligned_alloc(sizeof(uint32_t), sizeof(dma_descriptor_t)); if (!data->adc_hal_dma_ctx.rx_desc) { LOG_ERR("rx_desc allocation failed!"); return -ENOMEM; @@ -689,66 +657,64 @@ static int adc_esp32_init(const struct device *dev) #endif /* defined(CONFIG_ADC_ESP32_DMA) */ - for (uint8_t i = 0; i < ARRAY_SIZE(data->resolution); i++) { + for (uint8_t i = 0; i < SOC_ADC_MAX_CHANNEL_NUM; i++) { data->resolution[i] = ADC_RESOLUTION_MAX; - } - - for (uint8_t i = 0; i < ARRAY_SIZE(data->attenuation); i++) { data->attenuation[i] = ADC_ATTEN_DB_0; + data->cal_handle[i] = NULL; } /* Default reference voltage. This could be calibrated externaly */ data->meas_ref_internal = ADC_ESP32_DEFAULT_VREF_INTERNAL; - /* Check if calibration is possible */ - data->calibrate = adc_calibration_init(dev); + adc_hw_calibration(conf->unit); return 0; } static DEVICE_API(adc, api_esp32_driver_api) = { .channel_setup = adc_esp32_channel_setup, - .read = adc_esp32_read, + .read = adc_esp32_read, #ifdef CONFIG_ADC_ASYNC - .read_async = adc_esp32_read_async, + .read_async = adc_esp32_read_async, #endif /* CONFIG_ADC_ASYNC */ - .ref_internal = ADC_ESP32_DEFAULT_VREF_INTERNAL, + .ref_internal = ADC_ESP32_DEFAULT_VREF_INTERNAL, }; -#if defined(CONFIG_ADC_ESP32_DMA) +#define ADC_ESP32_CONF_GPIO_PORT_INIT .gpio_port = DEVICE_DT_GET(DT_NODELABEL(gpio0)), -#define ADC_ESP32_CONF_GPIO_PORT_INIT .gpio_port = DEVICE_DT_GET(DT_NODELABEL(gpio0)), +#if defined(CONFIG_ADC_ESP32_DMA) -#define ADC_ESP32_CONF_DMA_INIT(n) .dma_dev = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ +#define ADC_ESP32_CONF_DMA_INIT(n) \ + .dma_dev = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ (DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_IDX(n, 0))), \ - (NULL)), \ - .dma_channel = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ + (NULL)), \ + .dma_channel = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ (DT_INST_DMAS_CELL_BY_IDX(n, 0, channel)), \ (0xff)), #else -#define ADC_ESP32_CONF_GPIO_PORT_INIT #define ADC_ESP32_CONF_DMA_INIT(inst) #endif /* defined(CONFIG_ADC_ESP32_DMA) */ -#define ESP32_ADC_INIT(inst) \ - \ - static const struct adc_esp32_conf adc_esp32_conf_##inst = { \ - .unit = DT_PROP(DT_DRV_INST(inst), unit) - 1, \ - .channel_count = DT_PROP(DT_DRV_INST(inst), channel_count), \ - ADC_ESP32_CONF_GPIO_PORT_INIT \ - ADC_ESP32_CONF_DMA_INIT(inst) \ - }; \ - \ - static struct adc_esp32_data adc_esp32_data_##inst = { \ - }; \ - \ -DEVICE_DT_INST_DEFINE(inst, &adc_esp32_init, NULL, \ - &adc_esp32_data_##inst, \ - &adc_esp32_conf_##inst, \ - POST_KERNEL, \ - CONFIG_ADC_INIT_PRIORITY, \ - &api_esp32_driver_api); +#define ESP32_ADC_INIT(inst) \ + \ + static const struct adc_esp32_conf adc_esp32_conf_##inst = { \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(inst, offset), \ + .unit = DT_PROP(DT_DRV_INST(inst), unit) - 1, \ + .channel_count = DT_PROP(DT_DRV_INST(inst), channel_count), \ + ADC_ESP32_CONF_GPIO_PORT_INIT ADC_ESP32_CONF_DMA_INIT(inst)}; \ + \ + static struct adc_esp32_data adc_esp32_data_##inst = { \ + .hal = \ + { \ + .dev = (adc_oneshot_soc_handle_t)DT_INST_REG_ADDR(inst), \ + }, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &adc_esp32_init, NULL, &adc_esp32_data_##inst, \ + &adc_esp32_conf_##inst, POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ + &api_esp32_driver_api); DT_INST_FOREACH_STATUS_OKAY(ESP32_ADC_INIT) diff --git a/drivers/adc/adc_ifx_cat1.c b/drivers/adc/adc_ifx_cat1.c index e247ee96209fc..0df730d143385 100644 --- a/drivers/adc/adc_ifx_cat1.c +++ b/drivers/adc/adc_ifx_cat1.c @@ -22,9 +22,11 @@ LOG_MODULE_REGISTER(ifx_cat1_adc, CONFIG_ADC_LOG_LEVEL); #if defined(PASS_SARMUX_PADS0_PORT) - #define _ADCSAR_PORT PASS_SARMUX_PADS0_PORT +#define _ADC_PORT PASS_SARMUX_PADS0_PORT +#elif defined(ADCMIC_GPIO_ADC_IN0_PORT) +#define _ADC_PORT ADCMIC_GPIO_ADC_IN0_PORT #else - #error The selected device does not supported ADC +#error The selected device does not supported ADC #endif #define ADC_CAT1_EVENTS_MASK (CYHAL_ADC_EOS | CYHAL_ADC_ASYNC_READ_COMPLETE) @@ -33,15 +35,25 @@ LOG_MODULE_REGISTER(ifx_cat1_adc, CONFIG_ADC_LOG_LEVEL); #define ADC_CAT1_RESOLUTION (12u) #define ADC_CAT1_REF_INTERNAL_MV (1200u) +#if defined(CONFIG_SOC_FAMILY_INFINEON_CAT1B) +#define IFX_ADC_NUM_CHANNELS \ + ARRAY_SIZE(cyhal_pin_map_adcmic_gpio_adc_in) +#else +#define IFX_ADC_NUM_CHANNELS CY_SAR_SEQ_NUM_CHANNELS +#endif + struct ifx_cat1_adc_data { struct adc_context ctx; const struct device *dev; cyhal_adc_t adc_obj; - cyhal_adc_channel_t adc_chan_obj[CY_SAR_SEQ_NUM_CHANNELS]; + cyhal_adc_channel_t adc_chan_obj[IFX_ADC_NUM_CHANNELS]; uint16_t *buffer; uint16_t *repeat_buffer; uint32_t channels; uint32_t channels_mask; +#ifdef CONFIG_SOC_FAMILY_INFINEON_CAT1B + struct k_work adc_worker_thread; +#endif }; struct ifx_cat1_adc_config { @@ -74,13 +86,42 @@ static void _cyhal_adc_event_callback(void *callback_arg, cyhal_adc_event_t even LOG_DBG("%s ISR triggered.", dev->name); } +#ifdef CONFIG_SOC_FAMILY_INFINEON_CAT1B +static void ifx_cat1_adc_worker(struct k_work *adc_worker_thread) +{ + struct ifx_cat1_adc_data *data = + CONTAINER_OF(adc_worker_thread, struct ifx_cat1_adc_data, adc_worker_thread); + + uint32_t channels = data->channels; + int32_t result; + uint32_t channel_id; + + while (channels != 0) { + channel_id = find_lsb_set(channels) - 1; + channels &= ~BIT(channel_id); + + result = cyhal_adc_read(&data->adc_chan_obj[channel_id]); + /* Legacy API for BWC. Convert from signed to unsigned by adding 0x800 to + * convert the lowest signed 12-bit number to 0x0. + */ + *data->buffer = (uint16_t)(result + 0x800); + data->buffer++; + } + adc_context_on_sampling_done(&data->ctx, data->dev); +} +#endif + static void adc_context_start_sampling(struct adc_context *ctx) { struct ifx_cat1_adc_data *data = CONTAINER_OF(ctx, struct ifx_cat1_adc_data, ctx); data->repeat_buffer = data->buffer; +#if defined(CONFIG_SOC_FAMILY_INFINEON_CAT1B) + k_work_submit(&data->adc_worker_thread); +#else Cy_SAR_StartConvert(data->adc_obj.base, CY_SAR_START_CONVERT_SINGLE_SHOT); +#endif } static void adc_context_update_buffer_pointer(struct adc_context *ctx, @@ -99,10 +140,10 @@ static int ifx_cat1_adc_channel_setup(const struct device *dev, struct ifx_cat1_adc_data *data = dev->data; cy_rslt_t result; - cyhal_gpio_t vplus = CYHAL_GET_GPIO(_ADCSAR_PORT, channel_cfg->input_positive); - cyhal_gpio_t vminus = channel_cfg->differential ? - CYHAL_GET_GPIO(_ADCSAR_PORT, channel_cfg->input_negative) : - CYHAL_ADC_VNEG; + cyhal_gpio_t vplus = CYHAL_GET_GPIO(_ADC_PORT, channel_cfg->input_positive); + cyhal_gpio_t vminus = channel_cfg->differential + ? CYHAL_GET_GPIO(_ADC_PORT, channel_cfg->input_negative) + : CYHAL_ADC_VNEG; uint32_t acquisition_ns = ADC_CAT1_DEFAULT_ACQUISITION_NS; if (channel_cfg->reference != ADC_REF_INTERNAL) { @@ -158,7 +199,7 @@ static int validate_buffer_size(const struct adc_sequence *sequence) int active_channels = 0; int total_buffer_size; - for (int i = 0; i < CY_SAR_SEQ_NUM_CHANNELS; i++) { + for (int i = 0; i < IFX_ADC_NUM_CHANNELS; i++) { if (sequence->channels & BIT(i)) { active_channels++; } @@ -250,7 +291,7 @@ static int ifx_cat1_adc_init(const struct device *dev) data->dev = dev; /* Initialize ADC. The ADC block which can connect to the input pin is selected */ - result = cyhal_adc_init(&data->adc_obj, CYHAL_GET_GPIO(_ADCSAR_PORT, 0), NULL); + result = cyhal_adc_init(&data->adc_obj, CYHAL_GET_GPIO(_ADC_PORT, 0), NULL); if (result != CY_RSLT_SUCCESS) { LOG_ERR("ADC initialization failed. Error: 0x%08X\n", (unsigned int)result); return -EIO; @@ -274,23 +315,25 @@ static DEVICE_API(adc, adc_cat1_driver_api) = { #endif .ref_internal = ADC_CAT1_REF_INTERNAL_MV }; +#ifdef CONFIG_SOC_FAMILY_INFINEON_CAT1B +#define ADC_WORKER_THREAD_INIT() .adc_worker_thread = Z_WORK_INITIALIZER(ifx_cat1_adc_worker), +#else +#define ADC_WORKER_THREAD_INIT() +#endif /* Macros for ADC instance declaration */ -#define INFINEON_CAT1_ADC_INIT(n) \ - static struct ifx_cat1_adc_data ifx_cat1_adc_data##n = { \ - ADC_CONTEXT_INIT_TIMER(ifx_cat1_adc_data##n, ctx), \ - ADC_CONTEXT_INIT_LOCK(ifx_cat1_adc_data##n, ctx), \ - ADC_CONTEXT_INIT_SYNC(ifx_cat1_adc_data##n, ctx), \ - }; \ - \ - static const struct ifx_cat1_adc_config adc_cat1_cfg_##n = { \ - .irq_priority = DT_INST_IRQ(n, priority), \ - }; \ - \ - DEVICE_DT_INST_DEFINE(n, ifx_cat1_adc_init, \ - NULL, &ifx_cat1_adc_data##n, \ - &adc_cat1_cfg_##n, \ - POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ +#define INFINEON_CAT1_ADC_INIT(n) \ + static struct ifx_cat1_adc_data ifx_cat1_adc_data##n = { \ + ADC_CONTEXT_INIT_TIMER(ifx_cat1_adc_data##n, ctx), \ + ADC_CONTEXT_INIT_LOCK(ifx_cat1_adc_data##n, ctx), \ + ADC_CONTEXT_INIT_SYNC(ifx_cat1_adc_data##n, ctx), ADC_WORKER_THREAD_INIT()}; \ + \ + static const struct ifx_cat1_adc_config adc_cat1_cfg_##n = { \ + .irq_priority = DT_INST_IRQ(n, priority), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, ifx_cat1_adc_init, NULL, &ifx_cat1_adc_data##n, \ + &adc_cat1_cfg_##n, POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ &adc_cat1_driver_api); DT_INST_FOREACH_STATUS_OKAY(INFINEON_CAT1_ADC_INIT) diff --git a/drivers/adc/adc_mchp_xec.c b/drivers/adc/adc_mchp_xec.c index a3167b7479eeb..01ce587eea3cb 100644 --- a/drivers/adc/adc_mchp_xec.c +++ b/drivers/adc/adc_mchp_xec.c @@ -47,6 +47,8 @@ enum adc_pm_policy_state_flag { ADC_PM_POLICY_STATE_FLAG_COUNT, }; +#define XEC_ADC_MAX_HW_CHAN 16 +#define XEC_ADC_CFG_CHANNELS DT_INST_PROP(0, channels) struct adc_xec_regs { uint32_t control_reg; @@ -54,8 +56,8 @@ struct adc_xec_regs { uint32_t status_reg; uint32_t single_reg; uint32_t repeat_reg; - uint32_t channel_read_reg[8]; - uint32_t unused[18]; + uint32_t channel_read_reg[XEC_ADC_CFG_CHANNELS]; + uint32_t unused[10 + (XEC_ADC_MAX_HW_CHAN - XEC_ADC_CFG_CHANNELS)]; uint32_t config_reg; uint32_t vref_channel_reg; uint32_t vref_control_reg; @@ -139,7 +141,7 @@ static int adc_xec_channel_setup(const struct device *dev, return -EINVAL; } - if (channel_cfg->channel_id >= MCHP_ADC_MAX_CHAN) { + if (channel_cfg->channel_id >= XEC_ADC_CFG_CHANNELS) { return -EINVAL; } @@ -205,7 +207,7 @@ static int adc_xec_start_read(const struct device *dev, struct adc_xec_data * const data = dev->data; uint32_t sar_ctrl; - if (sequence->channels & ~BIT_MASK(MCHP_ADC_MAX_CHAN)) { + if (sequence->channels & ~BIT_MASK(XEC_ADC_CFG_CHANNELS)) { LOG_ERR("Incorrect channels, bitmask 0x%x", sequence->channels); return -EINVAL; } diff --git a/drivers/adc/adc_mcux_lpadc.c b/drivers/adc/adc_mcux_lpadc.c index 9b0fbd475f6c5..7804bdec94bd9 100644 --- a/drivers/adc/adc_mcux_lpadc.c +++ b/drivers/adc/adc_mcux_lpadc.c @@ -157,6 +157,8 @@ static int mcux_lpadc_channel_setup(const struct device *dev, return -EINVAL; } +#if !(defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && \ + (FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U)) if (channel_cfg->differential) { /* Channel pairs must match in differential mode */ if ((ADC_CMDL_ADCH(channel_cfg->input_positive)) != @@ -183,6 +185,7 @@ static int mcux_lpadc_channel_setup(const struct device *dev, } else { /* Default value for sampleChannelMode is SideA */ } +#endif #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE /* * The true scaling factor used by the LPADC is 30/64, instead of @@ -435,6 +438,8 @@ static void mcux_lpadc_isr(const struct device *dev) conv_mode = data->cmd_config[channel].sampleChannelMode; if (data->ctx.sequence.resolution < 15) { result = ((conv_result.convValue >> 3) & 0xFFF); +#if !(defined(FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS) && \ + (FSL_FEATURE_LPADC_HAS_B_SIDE_CHANNELS == 0U)) #if defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF if (conv_mode == kLPADC_SampleChannelDiffBothSideAB || conv_mode == kLPADC_SampleChannelDiffBothSideBA) { @@ -447,6 +452,7 @@ static void mcux_lpadc_isr(const struct device *dev) } } *data->buffer++ = result; +#endif } else { *data->buffer++ = conv_result.convValue; } diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index 279ba41265127..1418ae286f51d 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #define LOG_LEVEL CONFIG_ADC_LOG_LEVEL #include @@ -31,7 +33,7 @@ static const uint8_t saadc_psels[NRF_SAADC_AIN7 + 1] = { [NRF_SAADC_AIN6] = NRF_PIN_PORT_TO_PIN_NUMBER(6U, 1), [NRF_SAADC_AIN7] = NRF_PIN_PORT_TO_PIN_NUMBER(7U, 1), }; -#elif defined(CONFIG_SOC_NRF54L05) || defined(CONFIG_SOC_NRF54L10) || defined(CONFIG_SOC_NRF54L15) +#elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX) static const uint32_t saadc_psels[NRF_SAADC_DVDD + 1] = { [NRF_SAADC_AIN0] = NRF_PIN_PORT_TO_PIN_NUMBER(4U, 1), [NRF_SAADC_AIN1] = NRF_PIN_PORT_TO_PIN_NUMBER(5U, 1), @@ -168,6 +170,26 @@ static int adc_convert_acq_time(uint16_t acquisition_time, nrf_saadc_acqtime_t * return result; } +static int saadc_pm_hook(const struct device *dev, enum pm_device_action action) +{ + ARG_UNUSED(dev); + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + nrf_saadc_disable(NRF_SAADC); + return 0; + + case PM_DEVICE_ACTION_RESUME: + nrf_saadc_enable(NRF_SAADC); + return 0; + + default: + break; + } + + return -ENOTSUP; +} + /* Implementation of the ADC driver API function: adc_channel_setup. */ static int adc_nrfx_channel_setup(const struct device *dev, const struct adc_channel_cfg *channel_cfg) @@ -202,6 +224,11 @@ static int adc_nrfx_channel_setup(const struct device *dev, config.gain = NRF_SAADC_GAIN1_4; break; #endif +#if defined(SAADC_CH_CONFIG_GAIN_Gain2_7) + case ADC_GAIN_2_7: + config.gain = NRF_SAADC_GAIN2_7; + break; +#endif #if defined(SAADC_CH_CONFIG_GAIN_Gain1_3) || defined(SAADC_CH_CONFIG_GAIN_Gain2_6) case ADC_GAIN_1_3: config.gain = NRF_SAADC_GAIN1_3; @@ -315,7 +342,11 @@ static int adc_nrfx_channel_setup(const struct device *dev, static void adc_context_start_sampling(struct adc_context *ctx) { +#if defined(CONFIG_PM_DEVICE_RUNTIME) + pm_device_runtime_get(DEVICE_DT_INST_GET(0)); +#else nrf_saadc_enable(NRF_SAADC); +#endif if (ctx->sequence.calibrate) { nrf_saadc_task_trigger(NRF_SAADC, @@ -618,7 +649,12 @@ static void saadc_irq_handler(const struct device *dev) nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END); nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP); + +#if defined(CONFIG_PM_DEVICE_RUNTIME) + pm_device_runtime_put(DEVICE_DT_INST_GET(0)); +#else nrf_saadc_disable(NRF_SAADC); +#endif if (has_single_ended(&m_data.ctx.sequence)) { correct_single_ended(&m_data.ctx.sequence); @@ -658,7 +694,7 @@ static int init_saadc(const struct device *dev) adc_context_unlock_unconditionally(&m_data.ctx); - return 0; + return pm_device_driver_init(dev, saadc_pm_hook); } static DEVICE_API(adc, adc_nrfx_driver_api) = { @@ -667,7 +703,7 @@ static DEVICE_API(adc, adc_nrfx_driver_api) = { #ifdef CONFIG_ADC_ASYNC .read_async = adc_nrfx_read_async, #endif -#if defined(CONFIG_SOC_NRF54L05) || defined(CONFIG_SOC_NRF54L10) || defined(CONFIG_SOC_NRF54L15) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) .ref_internal = 900, #elif defined(CONFIG_NRF_PLATFORM_HALTIUM) .ref_internal = 1024, @@ -688,9 +724,10 @@ static DEVICE_API(adc, adc_nrfx_driver_api) = { #define SAADC_INIT(inst) \ BUILD_ASSERT((inst) == 0, \ "multiple instances not supported"); \ + PM_DEVICE_DT_INST_DEFINE(0, saadc_pm_hook, 1); \ DEVICE_DT_INST_DEFINE(0, \ init_saadc, \ - NULL, \ + PM_DEVICE_DT_INST_GET(0), \ NULL, \ NULL, \ POST_KERNEL, \ diff --git a/drivers/adc/adc_renesas_ra.c b/drivers/adc/adc_renesas_ra.c index 8c1225040edbc..9eadfc7a4278c 100644 --- a/drivers/adc/adc_renesas_ra.c +++ b/drivers/adc/adc_renesas_ra.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -21,6 +22,11 @@ LOG_MODULE_REGISTER(adc_ra, CONFIG_ADC_LOG_LEVEL); #include "adc_context.h" #define ADC_RA_MAX_RESOLUTION 12 +#define ADC_AVERAGE_1 ADC_ADD_OFF +#define ADC_AVERAGE_2 ADC_ADD_AVERAGE_TWO +#define ADC_AVERAGE_4 ADC_ADD_AVERAGE_FOUR +#define ADC_AVERAGE_8 ADC_ADD_AVERAGE_EIGHT +#define ADC_AVERAGE_16 ADC_ADD_AVERAGE_SIXTEEN void adc_scan_end_isr(void); @@ -32,6 +38,8 @@ void adc_scan_end_isr(void); struct adc_ra_config { /** Number of supported channels */ uint8_t num_channels; + /** Mask for channels existed in each board */ + uint32_t channel_available_mask; /** pinctrl configs */ const struct pinctrl_dev_config *pcfg; /** function pointer to irq setup */ @@ -76,10 +84,9 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann { fsp_err_t fsp_err = FSP_SUCCESS; struct adc_ra_data *data = dev->data; + const struct adc_ra_config *config = dev->config; - if (!((channel_cfg->channel_id >= 0 && channel_cfg->channel_id <= 2) || - (channel_cfg->channel_id >= 4 && channel_cfg->channel_id <= 8) || - (channel_cfg->channel_id >= 16 && channel_cfg->channel_id <= 19))) { + if (!((config->channel_available_mask & (1 << channel_cfg->channel_id)) != 0)) { LOG_ERR("unsupported channel id '%d'", channel_cfg->channel_id); return -ENOTSUP; } @@ -312,20 +319,6 @@ static int adc_ra_init(const struct device *dev) return 0; } -const adc_extended_cfg_t g_adc_cfg_extend = { - .add_average_count = ADC_ADD_OFF, - .clearing = ADC_CLEAR_AFTER_READ_ON, - .trigger_group_b = ADC_START_SOURCE_DISABLED, - .double_trigger_mode = ADC_DOUBLE_TRIGGER_DISABLED, - .adc_vref_control = ADC_VREF_CONTROL_VREFH, - .enable_adbuf = 0, - .window_a_irq = FSP_INVALID_VECTOR, - .window_a_ipl = (1), - .window_b_irq = FSP_INVALID_VECTOR, - .window_b_ipl = (BSP_IRQ_DISABLED), - .trigger = ADC_START_SOURCE_DISABLED, /* Use Software trigger */ -}; - #define IRQ_CONFIGURE_FUNC(idx) \ static void adc_ra_configure_func_##idx(void) \ { \ @@ -342,6 +335,19 @@ const adc_extended_cfg_t g_adc_cfg_extend = { #define ADC_RA_INIT(idx) \ IRQ_CONFIGURE_FUNC(idx) \ PINCTRL_DT_INST_DEFINE(idx); \ + static const adc_extended_cfg_t g_adc_cfg_extend_##idx = { \ + .add_average_count = UTIL_CAT(ADC_AVERAGE_, DT_INST_PROP(idx, average_count)), \ + .clearing = ADC_CLEAR_AFTER_READ_ON, \ + .trigger_group_b = ADC_START_SOURCE_DISABLED, \ + .double_trigger_mode = ADC_DOUBLE_TRIGGER_DISABLED, \ + .adc_vref_control = ADC_VREF_CONTROL_VREFH, \ + .enable_adbuf = 0, \ + .window_a_irq = FSP_INVALID_VECTOR, \ + .window_a_ipl = (1), \ + .window_b_irq = FSP_INVALID_VECTOR, \ + .window_b_ipl = (BSP_IRQ_DISABLED), \ + .trigger = ADC_START_SOURCE_DISABLED, \ + }; \ static DEVICE_API(adc, adc_ra_api_##idx) = { \ .channel_setup = adc_ra_channel_setup, \ .read = adc_ra_read, \ @@ -349,6 +355,7 @@ const adc_extended_cfg_t g_adc_cfg_extend = { IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \ static const struct adc_ra_config adc_ra_config_##idx = { \ .num_channels = DT_INST_PROP(idx, channel_count), \ + .channel_available_mask = DT_INST_PROP(idx, channel_available_mask), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ IRQ_CONFIGURE_DEFINE(idx), \ }; \ @@ -366,7 +373,7 @@ const adc_extended_cfg_t g_adc_cfg_extend = { .trigger = 0, \ .p_callback = NULL, \ .p_context = NULL, \ - .p_extend = &g_adc_cfg_extend, \ + .p_extend = &g_adc_cfg_extend_##idx, \ .scan_end_irq = DT_INST_IRQ_BY_NAME(idx, scanend, irq), \ .scan_end_ipl = DT_INST_IRQ_BY_NAME(idx, scanend, priority), \ .scan_end_b_irq = FSP_INVALID_VECTOR, \ @@ -377,7 +384,7 @@ const adc_extended_cfg_t g_adc_cfg_extend = { .scan_mask = 0, \ .scan_mask_group_b = 0, \ .priority_group_a = ADC_GROUP_A_PRIORITY_OFF, \ - .add_mask = 0, \ + .add_mask = UINT16_MAX, \ .sample_hold_mask = 0, \ .sample_hold_states = 24, \ .p_window_cfg = NULL, \ diff --git a/drivers/adc/adc_sam0.c b/drivers/adc/adc_sam0.c index 7cf31bc2ef54b..bc766b7278fe6 100644 --- a/drivers/adc/adc_sam0.c +++ b/drivers/adc/adc_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Derek Hageman + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +15,8 @@ #include LOG_MODULE_REGISTER(adc_sam0, CONFIG_ADC_LOG_LEVEL); +/* clang-format off */ + #define ADC_CONTEXT_USES_KERNEL_TIMER #include "adc_context.h" @@ -46,18 +49,12 @@ struct adc_sam0_data { struct adc_sam0_cfg { Adc *regs; const struct pinctrl_dev_config *pcfg; - -#ifdef MCLK + volatile uint32_t *mclk; uint32_t mclk_mask; - uint32_t gclk_mask; + uint32_t gclk_gen; uint16_t gclk_id; -#else - uint32_t gclk; -#endif - uint32_t freq; uint16_t prescaler; - void (*config_func)(const struct device *dev); }; @@ -180,7 +177,6 @@ static int adc_sam0_channel_setup(const struct device *dev, #endif } - uint32_t inputctrl = 0; switch (channel_cfg->gain) { @@ -258,7 +254,6 @@ static int adc_sam0_channel_setup(const struct device *dev, break; } - return 0; } @@ -328,6 +323,12 @@ static int start_read(const struct device *dev, } adc->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM(sequence->oversampling); + if (sequence->oversampling < 4) { + adc->AVGCTRL.reg |= ADC_AVGCTRL_ADJRES(sequence->oversampling); + } else { + adc->AVGCTRL.reg |= ADC_AVGCTRL_ADJRES(4); + } + /* AVGCTRL is not synchronized */ #ifdef CONFIG_SOC_SERIES_SAMD20 @@ -449,14 +450,15 @@ static int adc_sam0_init(const struct device *dev) Adc *const adc = cfg->regs; int retval; -#ifdef MCLK - GCLK->PCHCTRL[cfg->gclk_id].reg = cfg->gclk_mask | GCLK_PCHCTRL_CHEN; + *cfg->mclk |= cfg->mclk_mask; - MCLK_ADC |= cfg->mclk_mask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); #else - PM->APBCMASK.bit.ADC_ = 1; - - GCLK->CLKCTRL.reg = cfg->gclk | GCLK_CLKCTRL_CLKEN; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); @@ -515,81 +517,82 @@ static DEVICE_API(adc, adc_sam0_api) = { #ifdef MCLK -#define ADC_SAM0_CLOCK_CONTROL(n) \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_mask = UTIL_CAT(GCLK_PCHCTRL_GEN_GCLK, \ - DT_INST_PROP(n, gclk)), \ - .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch), \ - .prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \ - UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)), - -#define ADC_SAM0_CONFIGURE(n) \ -do { \ - const struct adc_sam0_cfg *const cfg = dev->config; \ - Adc * const adc = cfg->regs; \ - adc->CALIB.reg = ADC_SAM0_BIASCOMP(n) \ - | ADC_SAM0_BIASR2R(n) \ - | ADC_SAM0_BIASREFBUF(n); \ +#define ADC_SAM0_CONFIGURE(n) \ +do { \ + const struct adc_sam0_cfg *const cfg = dev->config; \ + Adc * const adc = cfg->regs; \ + adc->CALIB.reg = ADC_SAM0_BIASCOMP(n) \ + | ADC_SAM0_BIASR2R(n) \ + | ADC_SAM0_BIASREFBUF(n); \ } while (false) #else -#define ADC_SAM0_CLOCK_CONTROL(n) \ - .gclk = UTIL_CAT(GCLK_CLKCTRL_GEN_GCLK, DT_INST_PROP(n, gclk)) |\ - GCLK_CLKCTRL_ID_ADC, \ - .prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \ - UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)), - -#define ADC_SAM0_CONFIGURE(n) \ -do { \ - const struct adc_sam0_cfg *const cfg = dev->config; \ - Adc * const adc = cfg->regs; \ - /* Linearity is split across two words */ \ +#define ADC_SAM0_CONFIGURE(n) \ +do { \ + const struct adc_sam0_cfg *const cfg = dev->config; \ + Adc * const adc = cfg->regs; \ + /* Linearity is split across two words */ \ uint32_t lin = ((*(uint32_t *)ADC_FUSES_LINEARITY_0_ADDR) & \ - ADC_FUSES_LINEARITY_0_Msk) >> \ - ADC_FUSES_LINEARITY_0_Pos; \ - lin |= (((*(uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) & \ - ADC_FUSES_LINEARITY_1_Msk) >> \ - ADC_FUSES_LINEARITY_1_Pos) << 4; \ + ADC_FUSES_LINEARITY_0_Msk) >> \ + ADC_FUSES_LINEARITY_0_Pos; \ + lin |= (((*(uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) & \ + ADC_FUSES_LINEARITY_1_Msk) >> \ + ADC_FUSES_LINEARITY_1_Pos) << 4; \ uint32_t bias = ((*(uint32_t *)ADC_FUSES_BIASCAL_ADDR) & \ - ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; \ - adc->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | \ - ADC_CALIB_LINEARITY_CAL(lin); \ + ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; \ + adc->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | \ + ADC_CALIB_LINEARITY_CAL(lin); \ } while (false) #endif -#define ADC_SAM0_DEVICE(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static void adc_sam0_config_##n(const struct device *dev); \ - static const struct adc_sam0_cfg adc_sam_cfg_##n = { \ - .regs = (Adc *)DT_INST_REG_ADDR(n), \ - ADC_SAM0_CLOCK_CONTROL(n) \ - .freq = UTIL_CAT(UTIL_CAT(SOC_ATMEL_SAM0_GCLK, \ - DT_INST_PROP(n, gclk)), \ - _FREQ_HZ) / \ - DT_INST_PROP(n, prescaler), \ - .config_func = &adc_sam0_config_##n, \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - }; \ - static struct adc_sam0_data adc_sam_data_##n = { \ - ADC_CONTEXT_INIT_TIMER(adc_sam_data_##n, ctx), \ - ADC_CONTEXT_INIT_LOCK(adc_sam_data_##n, ctx), \ - ADC_CONTEXT_INIT_SYNC(adc_sam_data_##n, ctx), \ - }; \ - DEVICE_DT_INST_DEFINE(n, adc_sam0_init, NULL, \ - &adc_sam_data_##n, \ - &adc_sam_cfg_##n, POST_KERNEL, \ - CONFIG_ADC_INIT_PRIORITY, \ - &adc_sam0_api); \ - static void adc_sam0_config_##n(const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, resrdy, irq), \ - DT_INST_IRQ_BY_NAME(n, resrdy, priority), \ - adc_sam0_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQ_BY_NAME(n, resrdy, irq)); \ - ADC_SAM0_CONFIGURE(n); \ +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define ADC_SAM0_GCLK_FREQ(n) \ + UTIL_CAT(UTIL_CAT(SOC_ATMEL_SAM0_GCLK, \ + ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen)), \ + _FREQ_HZ) + +#define ADC_SAM0_FREQ(n) \ + .prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \ + UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)), \ + .freq = ADC_SAM0_GCLK_FREQ(n) / DT_INST_PROP(n, prescaler) + +#define ADC_SAM0_DEVICE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static void adc_sam0_config_##n(const struct device *dev); \ + static const struct adc_sam0_cfg adc_sam_cfg_##n = { \ + .regs = (Adc *)DT_INST_REG_ADDR(n), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ + ADC_SAM0_FREQ(n), \ + .config_func = &adc_sam0_config_##n, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + static struct adc_sam0_data adc_sam_data_##n = { \ + ADC_CONTEXT_INIT_TIMER(adc_sam_data_##n, ctx), \ + ADC_CONTEXT_INIT_LOCK(adc_sam_data_##n, ctx), \ + ADC_CONTEXT_INIT_SYNC(adc_sam_data_##n, ctx), \ + }; \ + DEVICE_DT_INST_DEFINE(n, adc_sam0_init, NULL, \ + &adc_sam_data_##n, \ + &adc_sam_cfg_##n, POST_KERNEL, \ + CONFIG_ADC_INIT_PRIORITY, \ + &adc_sam0_api); \ + static void adc_sam0_config_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, resrdy, irq), \ + DT_INST_IRQ_BY_NAME(n, resrdy, priority), \ + adc_sam0_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(n, resrdy, irq)); \ + ADC_SAM0_CONFIGURE(n); \ } DT_INST_FOREACH_STATUS_OKAY(ADC_SAM0_DEVICE) + +/* clang-format on */ diff --git a/drivers/adc/adc_shell.c b/drivers/adc/adc_shell.c index b3517f772d69c..6c3417ac1d673 100644 --- a/drivers/adc/adc_shell.c +++ b/drivers/adc/adc_shell.c @@ -75,6 +75,7 @@ static struct adc_hdl { uint8_t resolution; } adc_list[] = { /* zephyr-keep-sorted-start */ + DT_FOREACH_STATUS_OKAY(adi_ad4114_adc, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(adi_ad559x_adc, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(atmel_sam0_adc, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(atmel_sam_adc, ADC_HDL_LIST_ENTRY) @@ -104,6 +105,7 @@ static struct adc_hdl { DT_FOREACH_STATUS_OKAY(nuvoton_npcx_adc, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(nuvoton_numaker_adc, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(nxp_adc12, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(nxp_gau_adc, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(nxp_kinetis_adc16, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(nxp_lpc_lpadc, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(nxp_mcux_12b1msps_sar, ADC_HDL_LIST_ENTRY) @@ -139,6 +141,8 @@ static struct adc_hdl { DT_FOREACH_STATUS_OKAY(ti_lmp90099, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(ti_lmp90100, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(ti_tla2021, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(ti_tla2022, ADC_HDL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(ti_tla2024, ADC_HDL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(zephyr_adc_emul, ADC_HDL_LIST_ENTRY) /* zephyr-keep-sorted-stop */ }; diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 85f12aa7e4992..54a076c897d1a 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -23,7 +23,8 @@ #include #include #include -#if defined(CONFIG_SOC_SERIES_STM32U5X) +#if defined(CONFIG_SOC_SERIES_STM32N6X) || \ + defined(CONFIG_SOC_SERIES_STM32U5X) #include #endif /* CONFIG_SOC_SERIES_STM32U5X */ @@ -58,113 +59,88 @@ LOG_MODULE_REGISTER(adc_stm32); #include #endif /* CONFIG_NOCACHE_MEMORY */ + +/* Here are some redefinitions of ADC versions for better readability */ #if defined(CONFIG_SOC_SERIES_STM32F3X) #if defined(ADC1_V2_5) -/* ADC1_V2_5 is the ADC version for STM32F37x */ -#define STM32F3X_ADC_V2_5 +#define STM32F37X_ADC /* F37x */ #elif defined(ADC5_V1_1) -/* ADC5_V1_1 is the ADC version for other STM32F3x */ -#define STM32F3X_ADC_V1_1 -#endif -#endif +#define STM32F3XX_ADC /* Other F3xx */ +#endif /* ADC5_V1_1 */ +#elif defined(CONFIG_SOC_SERIES_STM32H7X) +#if defined(ADC_VER_V5_V90) +#define STM32H72X_ADC /* H72x and H73x */ +#elif defined(ADC_VER_V5_X) +#define STM32H74X_ADC /* H74x and H75x */ +#elif defined(ADC_VER_V5_3) +#define STM32H7AX_ADC /* H7Ax and H7Bx */ +#endif /* ADC_VER_V5_3 */ +#endif /* CONFIG_SOC_SERIES_STM32H7X */ + /* * Other ADC versions: - * ADC_VER_V5_V90 -> STM32H72x/H73x - * ADC_VER_V5_X -> STM32H74x/H75x && U5 - * ADC_VER_V5_3 -> STM32H7Ax/H7Bx * compat st_stm32f1_adc -> STM32F1, F37x (ADC1_V2_5) * compat st_stm32f4_adc -> STM32F2, F4, F7, L1 */ +/* Clock source values */ +#define SYNC 1 +#define ASYNC 2 + +/* Sequencer type */ +#define NOT_FULLY_CONFIGURABLE 0 +#define FULLY_CONFIGURABLE 1 + +/* Oversampler type */ +#define OVERSAMPLER_NONE 0 +#define OVERSAMPLER_MINIMAL 1 +#define OVERSAMPLER_EXTENDED 2 + #define ANY_NUM_COMMON_SAMPLING_TIME_CHANNELS_IS(value) \ (DT_INST_FOREACH_STATUS_OKAY_VARGS(IS_EQ_PROP_OR, \ num_sampling_time_common_channels,\ 0, value) 0) #define ANY_ADC_SEQUENCER_TYPE_IS(value) \ - (DT_INST_FOREACH_STATUS_OKAY_VARGS(IS_EQ_PROP_OR, \ + (DT_INST_FOREACH_STATUS_OKAY_VARGS(IS_EQ_STRING_PROP, \ st_adc_sequencer,\ - 0, value) 0) + value) 0) + +#define ANY_ADC_OVERSAMPLER_TYPE_IS(value) \ + (DT_INST_FOREACH_STATUS_OKAY_VARGS(IS_EQ_STRING_PROP, \ + st_adc_oversampler,\ + value) 0) #define IS_EQ_PROP_OR(inst, prop, default_value, compare_value) \ IS_EQ(DT_INST_PROP_OR(inst, prop, default_value), compare_value) || +#define IS_EQ_STRING_PROP(inst, prop, compare_value) \ + IS_EQ(DT_INST_STRING_UPPER_TOKEN(inst, prop), compare_value) || + /* reference voltage for the ADC */ #define STM32_ADC_VREF_MV DT_INST_PROP(0, vref_mv) #if ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) -#define RANK(n) LL_ADC_REG_RANK_##n -static const uint32_t table_rank[] = { - RANK(1), - RANK(2), - RANK(3), - RANK(4), - RANK(5), - RANK(6), - RANK(7), - RANK(8), - RANK(9), - RANK(10), - RANK(11), - RANK(12), - RANK(13), - RANK(14), - RANK(15), - RANK(16), -#if defined(LL_ADC_REG_RANK_17) - RANK(17), - RANK(18), - RANK(19), - RANK(20), - RANK(21), - RANK(22), - RANK(23), - RANK(24), - RANK(25), - RANK(26), - RANK(27), + #if defined(LL_ADC_REG_RANK_28) - RANK(28), -#endif /* LL_ADC_REG_RANK_28 */ -#endif /* LL_ADC_REG_RANK_17 */ -}; +#define MAX_RANK 28 +#elif defined(LL_ADC_REG_RANK_27) +#define MAX_RANK 27 +#else +#define MAX_RANK 16 +#endif -#define SEQ_LEN(n) LL_ADC_REG_SEQ_SCAN_ENABLE_##n##RANKS +#define RANK(i, _) _CONCAT_1(LL_ADC_REG_RANK_, UTIL_INC(i)) +static const uint32_t table_rank[] = { + LISTIFY(MAX_RANK, RANK, (,))}; + +#define SEQ_LEN(i, _) _CONCAT_2(LL_ADC_REG_SEQ_SCAN_ENABLE_, UTIL_INC(UTIL_INC(i)), RANKS) /* Length of this array signifies the maximum sequence length */ static const uint32_t table_seq_len[] = { LL_ADC_REG_SEQ_SCAN_DISABLE, - SEQ_LEN(2), - SEQ_LEN(3), - SEQ_LEN(4), - SEQ_LEN(5), - SEQ_LEN(6), - SEQ_LEN(7), - SEQ_LEN(8), - SEQ_LEN(9), - SEQ_LEN(10), - SEQ_LEN(11), - SEQ_LEN(12), - SEQ_LEN(13), - SEQ_LEN(14), - SEQ_LEN(15), - SEQ_LEN(16), -#if defined(LL_ADC_REG_SEQ_SCAN_ENABLE_17RANKS) - SEQ_LEN(17), - SEQ_LEN(18), - SEQ_LEN(19), - SEQ_LEN(20), - SEQ_LEN(21), - SEQ_LEN(22), - SEQ_LEN(23), - SEQ_LEN(24), - SEQ_LEN(25), - SEQ_LEN(26), - SEQ_LEN(27), -#if defined(LL_ADC_REG_SEQ_SCAN_ENABLE_28RANKS) - SEQ_LEN(28), -#endif /* LL_ADC_REG_SEQ_SCAN_ENABLE_28RANKS */ -#endif /* LL_ADC_REG_SEQ_SCAN_ENABLE_17RANKS */ + LISTIFY(UTIL_DEC(MAX_RANK), SEQ_LEN, (,)) }; + #endif /* ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) */ /* Number of different sampling time values */ @@ -182,11 +158,17 @@ struct stream { }; #endif /* CONFIG_ADC_STM32_DMA */ +#if defined(CONFIG_SOC_SERIES_STM32N6X) +typedef uint32_t adc_data_size_t; +#else +typedef uint16_t adc_data_size_t; +#endif + struct adc_stm32_data { struct adc_context ctx; const struct device *dev; - uint16_t *buffer; - uint16_t *repeat_buffer; + adc_data_size_t *buffer; + adc_data_size_t *repeat_buffer; uint8_t resolution; uint32_t channels; @@ -210,6 +192,7 @@ struct adc_stm32_cfg { const uint16_t sampling_time_table[STM32_NB_SAMPLING_TIME]; int8_t num_sampling_time_common_channels; int8_t sequencer_type; + int8_t oversampler_type; int8_t res_table_size; const uint32_t res_table[]; }; @@ -218,38 +201,18 @@ struct adc_stm32_cfg { static void adc_stm32_enable_dma_support(ADC_TypeDef *adc) { /* Allow ADC to create DMA request and set to one-shot mode as implemented in HAL drivers */ - -#if defined(CONFIG_SOC_SERIES_STM32H7X) - -#if defined(ADC_VER_V5_V90) - if (adc == ADC3) { - LL_ADC_REG_SetDMATransferMode(adc, LL_ADC3_REG_DMA_TRANSFER_LIMITED); - } else { - LL_ADC_REG_SetDataTransferMode(adc, LL_ADC_REG_DMA_TRANSFER_LIMITED); - } -#elif defined(ADC_VER_V5_X) +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) + LL_ADC_REG_SetDMATransfer(adc, LL_ADC_REG_DMA_TRANSFER_UNLIMITED); +#elif defined(CONFIG_SOC_SERIES_STM32H7X) || \ + defined(CONFIG_SOC_SERIES_STM32N6X) || \ + defined(CONFIG_SOC_SERIES_STM32U5X) + /* H72x ADC3 and U5 ADC4 are different from the rest, but this call works also for them, + * so no need to call their specific function + */ LL_ADC_REG_SetDataTransferMode(adc, LL_ADC_REG_DMA_TRANSFER_LIMITED); #else -#error "Unsupported ADC version" -#endif - -#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) /* defined(CONFIG_SOC_SERIES_STM32H7X) */ - -#error "The STM32F1 ADC + DMA is not yet supported" - -#elif defined(CONFIG_SOC_SERIES_STM32U5X) /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ - - if (adc == ADC4) { - LL_ADC_REG_SetDMATransfer(adc, LL_ADC_REG_DMA_TRANSFER_LIMITED_ADC4); - } else { - LL_ADC_REG_SetDataTransferMode(adc, LL_ADC_REG_DMA_TRANSFER_LIMITED); - } - -#else /* defined(CONFIG_SOC_SERIES_STM32U5X) */ - /* Default mechanism for other MCUs */ LL_ADC_REG_SetDMATransfer(adc, LL_ADC_REG_DMA_TRANSFER_LIMITED); - #endif } @@ -257,7 +220,7 @@ static int adc_stm32_dma_start(const struct device *dev, void *buffer, size_t channel_count) { const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; struct adc_stm32_data *data = dev->data; struct dma_block_config *blk_cfg; int ret; @@ -267,7 +230,7 @@ static int adc_stm32_dma_start(const struct device *dev, blk_cfg = &dma->dma_blk_cfg; /* prepare the block */ - blk_cfg->block_size = channel_count * sizeof(int16_t); + blk_cfg->block_size = channel_count * sizeof(adc_data_size_t); /* Source and destination */ blk_cfg->source_address = (uint32_t)LL_ADC_DMA_GetRegAddr(adc, LL_ADC_DMA_REG_REGULAR_DATA); @@ -342,7 +305,7 @@ static int check_buffer(const struct adc_sequence *sequence, { size_t needed_buffer_size; - needed_buffer_size = active_channels * sizeof(uint16_t); + needed_buffer_size = active_channels * sizeof(adc_data_size_t); if (sequence->options) { needed_buffer_size *= (1 + sequence->options->extra_samplings); @@ -414,7 +377,7 @@ static int adc_stm32_enable(ADC_TypeDef *adc) static void adc_stm32_start_conversion(const struct device *dev) { const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; LOG_DBG("Starting conversion"); @@ -515,13 +478,48 @@ static void adc_stm32_calibration_delay(const struct device *dev) } } +#if defined(CONFIG_SOC_SERIES_STM32N6X) +/* Number of ADC measurement during calibration procedure */ +#define ADC_CALIBRATION_STEPS (8U) + +static void adc_stm32_calibration_measure(ADC_TypeDef *adc, uint32_t *calibration_factor) +{ + uint32_t calib_step; + uint32_t calib_factor_avg = 0; + uint8_t done = 0; + + do { + for (calib_step = 0; calib_step < ADC_CALIBRATION_STEPS; calib_step++) { + LL_ADC_REG_StartConversion(adc); + while (LL_ADC_REG_IsConversionOngoing(adc) != 0UL) { + } + + calib_factor_avg += LL_ADC_REG_ReadConversionData32(adc); + } + + /* Compute the average data */ + calib_factor_avg /= ADC_CALIBRATION_STEPS; + + if ((calib_factor_avg == 0) && (LL_ADC_IsCalibrationOffsetEnabled(adc) == 0UL)) { + /* If average is 0 and offset is disabled + * set offset and repeat measurements + */ + LL_ADC_EnableCalibrationOffset(adc); + } else { + *calibration_factor = (uint32_t)(calib_factor_avg); + done = 1; + } + } while (done == 0); +} +#endif + static void adc_stm32_calibration_start(const struct device *dev) { const struct adc_stm32_cfg *config = (const struct adc_stm32_cfg *)dev->config; ADC_TypeDef *adc = config->base; -#if defined(STM32F3X_ADC_V1_1) || \ +#if defined(STM32F3XX_ADC) || \ defined(CONFIG_SOC_SERIES_STM32L4X) || \ defined(CONFIG_SOC_SERIES_STM32L5X) || \ defined(CONFIG_SOC_SERIES_STM32H5X) || \ @@ -563,6 +561,17 @@ static void adc_stm32_calibration_start(const struct device *dev) LL_ADC_StartCalibration(adc, LL_ADC_CALIB_OFFSET); #elif defined(CONFIG_SOC_SERIES_STM32H7X) LL_ADC_StartCalibration(adc, LL_ADC_CALIB_OFFSET, LL_ADC_SINGLE_ENDED); +#elif defined(CONFIG_SOC_SERIES_STM32N6X) + uint32_t calibration_factor; + /* Start ADC calibration */ + LL_ADC_StartCalibration(adc, LL_ADC_SINGLE_ENDED); + /* Disable additional offset before calibration start */ + LL_ADC_DisableCalibrationOffset(adc); + + adc_stm32_calibration_measure(adc, &calibration_factor); + + LL_ADC_SetCalibrationFactor(adc, LL_ADC_SINGLE_ENDED, calibration_factor); + LL_ADC_StopCalibration(adc); #endif /* Make sure ADCAL is cleared before returning for proper operations * on the ADC control register, for enabling the peripheral for example @@ -597,7 +606,8 @@ static int adc_stm32_calibrate(const struct device *dev) #endif /* CONFIG_SOC_SERIES_* */ #endif /* CONFIG_ADC_STM32_DMA */ -#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ + !defined(CONFIG_SOC_SERIES_STM32N6X) adc_stm32_disable(adc); adc_stm32_calibration_start(dev); adc_stm32_calibration_delay(dev); @@ -608,7 +618,8 @@ static int adc_stm32_calibrate(const struct device *dev) return err; } -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) || \ + defined(CONFIG_SOC_SERIES_STM32N6X) adc_stm32_calibration_delay(dev); adc_stm32_calibration_start(dev); #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ @@ -653,25 +664,19 @@ static int adc_stm32_calibrate(const struct device *dev) #define HAS_OVERSAMPLING -#define OVS_SHIFT(n) LL_ADC_OVS_SHIFT_RIGHT_##n +#if defined(LL_ADC_OVS_SHIFT_RIGHT_10) +#define MAX_OVS_SHIFT 10 +#else +#define MAX_OVS_SHIFT 8 +#endif + +#define OVS_SHIFT(i, _) _CONCAT_1(LL_ADC_OVS_SHIFT_RIGHT_, UTIL_INC(i)) static const uint32_t table_oversampling_shift[] = { LL_ADC_OVS_SHIFT_NONE, - OVS_SHIFT(1), - OVS_SHIFT(2), - OVS_SHIFT(3), - OVS_SHIFT(4), - OVS_SHIFT(5), - OVS_SHIFT(6), - OVS_SHIFT(7), - OVS_SHIFT(8), -#if defined(CONFIG_SOC_SERIES_STM32H7X) || \ - defined(CONFIG_SOC_SERIES_STM32U5X) - OVS_SHIFT(9), - OVS_SHIFT(10), -#endif + LISTIFY(MAX_OVS_SHIFT, OVS_SHIFT, (,)) }; -#ifdef LL_ADC_OVS_RATIO_2 +#if ANY_ADC_OVERSAMPLER_TYPE_IS(OVERSAMPLER_MINIMAL) #define OVS_RATIO(n) LL_ADC_OVS_RATIO_##n static const uint32_t table_oversampling_ratio[] = { 0, @@ -734,8 +739,11 @@ static void adc_stm32_oversampling_ratioshift(ADC_TypeDef *adc, uint32_t ratio, * ratio is directly the sequence->oversampling (a 2^n value) * shift is the corresponding LL_ADC_OVS_SHIFT_RIGHT_x constant */ -static int adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio) +static int adc_stm32_oversampling(const struct device *dev, uint8_t ratio) { + const struct adc_stm32_cfg *config = dev->config; + ADC_TypeDef *adc = config->base; + if (ratio == 0) { adc_stm32_oversampling_scope(adc, LL_ADC_OVS_DISABLE); return 0; @@ -748,33 +756,19 @@ static int adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio) uint32_t shift = table_oversampling_shift[ratio]; -#if defined(CONFIG_SOC_SERIES_STM32H7X) - /* Certain variants of the H7, such as STM32H72x/H73x has ADC3 - * as a separate entity and require special handling. - */ -#if defined(ADC_VER_V5_V90) - if (adc != ADC3) { - /* the LL function expects a value from 1 to 1024 */ - adc_stm32_oversampling_ratioshift(adc, 1 << ratio, shift); - } else { +#if ANY_ADC_OVERSAMPLER_TYPE_IS(OVERSAMPLER_MINIMAL) + if (config->oversampler_type == OVERSAMPLER_MINIMAL) { /* the LL function expects a value LL_ADC_OVS_RATIO_x */ adc_stm32_oversampling_ratioshift(adc, table_oversampling_ratio[ratio], shift); } -#else - /* the LL function expects a value from 1 to 1024 */ - adc_stm32_oversampling_ratioshift(adc, 1 << ratio, shift); -#endif /* defined(ADC_VER_V5_V90) */ -#elif defined(CONFIG_SOC_SERIES_STM32U5X) - if (adc != ADC4) { +#endif + +#if ANY_ADC_OVERSAMPLER_TYPE_IS(OVERSAMPLER_EXTENDED) + if (config->oversampler_type == OVERSAMPLER_EXTENDED) { /* the LL function expects a value from 1 to 1024 */ - adc_stm32_oversampling_ratioshift(adc, (1 << ratio), shift); - } else { - /* the LL function expects a value LL_ADC_OVS_RATIO_x */ - adc_stm32_oversampling_ratioshift(adc, table_oversampling_ratio[ratio], shift); + adc_stm32_oversampling_ratioshift(adc, 1 << ratio, shift); } -#else /* CONFIG_SOC_SERIES_STM32H7X */ - adc_stm32_oversampling_ratioshift(adc, table_oversampling_ratio[ratio], shift); -#endif /* CONFIG_SOC_SERIES_STM32H7X */ +#endif return 0; } @@ -786,17 +780,22 @@ static void dma_callback(const struct device *dev, void *user_data, { /* user_data directly holds the adc device */ struct adc_stm32_data *data = user_data; +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) /* Avoid unused variables */ const struct adc_stm32_cfg *config = data->dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; +#endif /* !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ LOG_DBG("dma callback"); if (channel == data->dma.channel) { #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) - if (LL_ADC_IsActiveFlag_OVR(adc) || (status >= 0)) { -#else - if (status >= 0) { + if (LL_ADC_IsActiveFlag_OVR(adc)) { + LL_ADC_ClearFlag_OVR(adc); + LOG_ERR("ADC overrun error occurred. Reduce clock source frequency, " + "increase prescaler value or increase sampling times."); + } #endif /* !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ + if (status >= 0) { data->samples_count = data->channel_count; data->buffer += data->channel_count; /* Stop the DMA engine, only to start it again when the callback returns @@ -805,9 +804,6 @@ static void dma_callback(const struct device *dev, void *user_data, * within adc_context_start_sampling */ dma_stop(data->dma.dma_dev, data->dma.channel); -#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) - LL_ADC_ClearFlag_OVR(adc); -#endif /* !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ /* No need to invalidate the cache because it's assumed that * the address is in a non-cacheable SRAM region. */ @@ -821,7 +817,7 @@ static void dma_callback(const struct device *dev, void *user_data, } else if (status < 0) { LOG_ERR("DMA sampling complete, but DMA reported error %d", status); data->dma_error = status; -#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) LL_ADC_REG_StopConversion(adc); #endif dma_stop(data->dma.dma_dev, data->dma.channel); @@ -835,7 +831,7 @@ static uint8_t get_reg_value(const struct device *dev, uint32_t reg, uint32_t shift, uint32_t mask) { const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; uintptr_t addr = (uintptr_t)adc + reg; @@ -846,7 +842,7 @@ static void set_reg_value(const struct device *dev, uint32_t reg, uint32_t shift, uint32_t mask, uint32_t value) { const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; uintptr_t addr = (uintptr_t)adc + reg; @@ -857,7 +853,7 @@ static int set_resolution(const struct device *dev, const struct adc_sequence *sequence) { const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; uint8_t res_reg_addr = 0xFF; uint8_t res_shift = 0; uint8_t res_mask = 0; @@ -909,7 +905,7 @@ static int set_sequencer(const struct device *dev) { const struct adc_stm32_cfg *config = dev->config; struct adc_stm32_data *data = dev->data; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; uint8_t channel_id; uint8_t channel_index = 0; @@ -929,7 +925,9 @@ static int set_sequencer(const struct device *dev) #if ANY_ADC_SEQUENCER_TYPE_IS(FULLY_CONFIGURABLE) if (config->sequencer_type == FULLY_CONFIGURABLE) { -#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32U5X) +#if defined(CONFIG_SOC_SERIES_STM32H7X) || \ + defined(CONFIG_SOC_SERIES_STM32N6X) || \ + defined(CONFIG_SOC_SERIES_STM32U5X) /* * Each channel in the sequence must be previously enabled in PCSEL. * This register controls the analog switch integrated in the IO level. @@ -974,7 +972,7 @@ static int start_read(const struct device *dev, { const struct adc_stm32_cfg *config = dev->config; struct adc_stm32_data *data = dev->data; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; int err; data->buffer = sequence->buffer; @@ -1020,7 +1018,7 @@ static int start_read(const struct device *dev, } #ifdef HAS_OVERSAMPLING - err = adc_stm32_oversampling(adc, sequence->oversampling); + err = adc_stm32_oversampling(dev, sequence->oversampling); if (err) { return err; } @@ -1082,7 +1080,7 @@ static void adc_context_start_sampling(struct adc_context *ctx) CONTAINER_OF(ctx, struct adc_stm32_data, ctx); const struct device *dev = data->dev; const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; /* Remove warning for some series */ ARG_UNUSED(adc); @@ -1118,6 +1116,14 @@ static void adc_stm32_isr(const struct device *dev) (const struct adc_stm32_cfg *)dev->config; ADC_TypeDef *adc = config->base; +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) + if (LL_ADC_IsActiveFlag_OVR(adc)) { + LL_ADC_ClearFlag_OVR(adc); + LOG_ERR("ADC overrun error occurred. Use DMA, reduce clock source frequency, " + "increase prescaler value or increase sampling times."); + } +#endif /* !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) */ + #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) if (LL_ADC_IsActiveFlag_EOS(adc) == 1) { #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) @@ -1148,7 +1154,7 @@ static void adc_context_on_complete(struct adc_context *ctx, int status) struct adc_stm32_data *data = CONTAINER_OF(ctx, struct adc_stm32_data, ctx); const struct adc_stm32_cfg *config = data->dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; ARG_UNUSED(status); @@ -1381,7 +1387,7 @@ static inline int adc_stm32_get_input_freq_prescaler(void) { int presc = 2; -#ifdef ADC_VER_V5_X +#ifdef STM32H74X_ADC /* For revision Y we have no prescaler of 2 */ if (LL_DBGMCU_GetRevisionID() <= 0x1003) { presc = 1; @@ -1485,7 +1491,7 @@ static int adc_stm32_set_clock(const struct device *dev) { const struct adc_stm32_cfg *config = dev->config; const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; int ret = 0; ARG_UNUSED(adc); /* Necessary to avoid warnings on some series */ @@ -1504,6 +1510,7 @@ static int adc_stm32_set_clock(const struct device *dev) } } +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source) #if defined(CONFIG_SOC_SERIES_STM32F0X) LL_ADC_SetClock(adc, config->clk_prescaler); #elif defined(ADC_STM32_HAS_INDIVIDUAL_CLOCKS) @@ -1514,7 +1521,7 @@ static int adc_stm32_set_clock(const struct device *dev) config->clk_prescaler); LL_ADC_SetClock(adc, LL_ADC_CLOCK_ASYNC); } -#elif !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) +#else LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc), config->clk_prescaler); @@ -1523,16 +1530,37 @@ static int adc_stm32_set_clock(const struct device *dev) ret = adc_stm32h7_setup_boost(config, adc, clk); #endif #endif +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source) */ return ret; } +static void adc_stm32_enable_analog_supply(void) +{ +#if defined(CONFIG_SOC_SERIES_STM32N6X) + LL_PWR_EnableVddADC(); +#elif defined(CONFIG_SOC_SERIES_STM32U5X) + LL_PWR_EnableVDDA(); +#endif /* CONFIG_SOC_SERIES_STM32U5X */ +} + +#ifdef CONFIG_PM_DEVICE +static void adc_stm32_disable_analog_supply(void) +{ +#if defined(CONFIG_SOC_SERIES_STM32N6X) + LL_PWR_DisableVddADC(); +#elif defined(CONFIG_SOC_SERIES_STM32U5X) + LL_PWR_DisableVDDA(); +#endif /* CONFIG_SOC_SERIES_STM32U5X */ +} +#endif + static int adc_stm32_init(const struct device *dev) { struct adc_stm32_data *data = dev->data; const struct adc_stm32_cfg *config = dev->config; const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; int err; ARG_UNUSED(adc); /* Necessary to avoid warnings on some series */ @@ -1572,10 +1600,7 @@ static int adc_stm32_init(const struct device *dev) return err; } -#if defined(CONFIG_SOC_SERIES_STM32U5X) - /* Enable the independent analog supply */ - LL_PWR_EnableVDDA(); -#endif /* CONFIG_SOC_SERIES_STM32U5X */ + adc_stm32_enable_analog_supply(); #ifdef CONFIG_ADC_STM32_DMA if ((data->dma.dma_dev != NULL) && @@ -1592,6 +1617,7 @@ static int adc_stm32_init(const struct device *dev) defined(CONFIG_SOC_SERIES_STM32H5X) || \ defined(CONFIG_SOC_SERIES_STM32H7X) || \ defined(CONFIG_SOC_SERIES_STM32H7RSX) || \ + defined(CONFIG_SOC_SERIES_STM32N6X) || \ defined(CONFIG_SOC_SERIES_STM32U5X) /* * L4, WB, G4, H5, H7 and U5 series STM32 needs to be awaken from deep sleep @@ -1607,12 +1633,13 @@ static int adc_stm32_init(const struct device *dev) */ #if !defined(CONFIG_SOC_SERIES_STM32F0X) && \ !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ - !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) + !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) && \ + !defined(CONFIG_SOC_SERIES_STM32N6X) LL_ADC_EnableInternalRegulator(adc); /* Wait for Internal regulator stabilisation * Some series have a dedicated status bit, others relie on a delay */ -#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(ADC_VER_V5_V90) +#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(STM32H72X_ADC) /* ADC3 on H72x/H73x doesn't have the LDORDY status bit */ if (adc == ADC3) { k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); @@ -1623,10 +1650,7 @@ static int adc_stm32_init(const struct device *dev) #elif defined(CONFIG_SOC_SERIES_STM32H7X) || \ defined(CONFIG_SOC_SERIES_STM32U5X) || \ defined(CONFIG_SOC_SERIES_STM32WBAX) - /* Don't use LL_ADC_IsActiveFlag_LDORDY since not present in U5 LL (1.5.0) - * (internal issue 185106) - */ - while ((READ_BIT(adc->ISR, LL_ADC_FLAG_LDORDY) != (LL_ADC_FLAG_LDORDY))) { + while (LL_ADC_IsActiveFlag_LDORDY(adc) == 0) { } #else k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); @@ -1651,7 +1675,7 @@ static int adc_stm32_init(const struct device *dev) static int adc_stm32_suspend_setup(const struct device *dev) { const struct adc_stm32_cfg *config = dev->config; - ADC_TypeDef *adc = (ADC_TypeDef *)config->base; + ADC_TypeDef *adc = config->base; const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); int err; @@ -1660,7 +1684,8 @@ static int adc_stm32_suspend_setup(const struct device *dev) #if !defined(CONFIG_SOC_SERIES_STM32F0X) && \ !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) && \ - !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) + !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_adc) && \ + !defined(CONFIG_SOC_SERIES_STM32N6X) /* Disable ADC internal voltage regulator */ LL_ADC_DisableInternalRegulator(adc); while (LL_ADC_IsInternalRegulatorEnabled(adc) == 1U) { @@ -1674,6 +1699,7 @@ static int adc_stm32_suspend_setup(const struct device *dev) defined(CONFIG_SOC_SERIES_STM32H5X) || \ defined(CONFIG_SOC_SERIES_STM32H7X) || \ defined(CONFIG_SOC_SERIES_STM32H7RSX) || \ + defined(CONFIG_SOC_SERIES_STM32N6X) || \ defined(CONFIG_SOC_SERIES_STM32U5X) /* * L4, WB, G4, H5, H7 and U5 series STM32 needs to be put into @@ -1683,10 +1709,7 @@ static int adc_stm32_suspend_setup(const struct device *dev) LL_ADC_EnableDeepPowerDown(adc); #endif -#if defined(CONFIG_SOC_SERIES_STM32U5X) - /* Disable the independent analog supply */ - LL_PWR_DisableVDDA(); -#endif /* CONFIG_SOC_SERIES_STM32U5X */ + adc_stm32_disable_analog_supply(); /* Stop device clock. Note: fixed clocks are not handled yet. */ err = clock_control_off(clk, (clock_control_subsys_t)&config->pclken[0]); @@ -1736,13 +1759,16 @@ static DEVICE_API(adc, api_stm32_driver_api) = { .ref_internal = STM32_ADC_VREF_MV, /* VREF is usually connected to VDD */ }; +/* Macros for ADC clock source and prescaler */ +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source) + #if defined(CONFIG_SOC_SERIES_STM32F0X) /* LL_ADC_CLOCK_ASYNC_DIV1 doesn't exist in F0 LL. Define it here. */ #define LL_ADC_CLOCK_ASYNC_DIV1 LL_ADC_CLOCK_ASYNC #endif /* st_prescaler property requires 2 elements : clock ASYNC/SYNC and DIV */ -#define ADC_STM32_CLOCK(x) DT_INST_PROP(x, st_adc_clock_source) +#define ADC_STM32_CLOCK(x) DT_INST_STRING_UPPER_TOKEN(x, st_adc_clock_source) #define ADC_STM32_DIV(x) DT_INST_PROP(x, st_adc_prescaler) /* Macro to set the prefix depending on the 1st element: check if it is SYNC or ASYNC */ @@ -1752,17 +1778,20 @@ static DEVICE_API(adc, api_stm32_driver_api) = { (LL_ADC_CLOCK_ASYNC_DIV)) /* Concat prefix (1st element) and DIV value (2nd element) of st,adc-prescaler */ -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) -#define ADC_STM32_DT_PRESC(x) 0 -#define ADC_STM32_CHECK_DT_CLOCK(x) -#else #define ADC_STM32_DT_PRESC(x) \ _CONCAT(ADC_STM32_CLOCK_PREFIX(x), ADC_STM32_DIV(x)) + /* Macro to check if the ADC instance clock setup is correct */ #define ADC_STM32_CHECK_DT_CLOCK(x) \ BUILD_ASSERT(IS_EQ(ADC_STM32_CLOCK(x), SYNC) || (DT_INST_NUM_CLOCKS(x) > 1), \ "ASYNC clock mode defined without ASYNC clock defined in device tree") -#endif + +#else /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source) */ + +#define ADC_STM32_DT_PRESC(x) 0 +#define ADC_STM32_CHECK_DT_CLOCK(x) + +#endif /* !DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source) */ #if defined(CONFIG_ADC_STM32_DMA) @@ -1921,7 +1950,8 @@ static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \ .pclk_len = DT_INST_NUM_CLOCKS(index), \ .clk_prescaler = ADC_STM32_DT_PRESC(index), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ - .sequencer_type = DT_INST_PROP(index, st_adc_sequencer), \ + .sequencer_type = DT_INST_STRING_UPPER_TOKEN(index, st_adc_sequencer), \ + .oversampler_type = DT_INST_STRING_UPPER_TOKEN(index, st_adc_oversampler), \ .sampling_time_table = DT_INST_PROP(index, sampling_times), \ .num_sampling_time_common_channels = \ DT_INST_PROP_OR(index, num_sampling_time_common_channels, 0),\ diff --git a/drivers/adc/adc_tla2021.c b/drivers/adc/adc_tla2021.c deleted file mode 100644 index c4bfb50082f2b..0000000000000 --- a/drivers/adc/adc_tla2021.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (c) 2023 Caspar Friedrich - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include -#include -#include -#include -#include - -#define ADC_CONTEXT_USES_KERNEL_TIMER - -/* - * This requires to be included _after_ `#define ADC_CONTEXT_USES_KERNEL_TIMER` - */ -#include "adc_context.h" - -#define DT_DRV_COMPAT ti_tla2021 - -LOG_MODULE_REGISTER(tla2021, CONFIG_ADC_LOG_LEVEL); - -#define ACQ_THREAD_PRIORITY CONFIG_ADC_TLA2021_ACQUISITION_THREAD_PRIORITY -#define ACQ_THREAD_STACK_SIZE CONFIG_ADC_TLA2021_ACQUISITION_THREAD_STACK_SIZE - -#define ADC_CHANNEL_msk BIT(0) -#define ADC_RESOLUTION 12 - -/* - * Conversion Data Register (RP = 00h) [reset = 0000h] - */ -#define REG_DATA 0x00 -#define REG_DATA_pos 4 - -/* - * Configuration Register (RP = 01h) [reset = 8583h] - */ -#define REG_CONFIG 0x01 -#define REG_CONFIG_DEFAULT 0x8583 -#define REG_CONFIG_DR_pos 5 -#define REG_CONFIG_MODE_pos 8 -#define REG_CONFIG_PGA_pos 9 /* TLA2022 and TLA2024 Only */ -#define REG_CONFIG_MUX_pos 12 /* TLA2024 Only */ -#define REG_CONFIG_OS_pos 15 -#define REG_CONFIG_OS_msk (BIT_MASK(1) << REG_CONFIG_OS_pos) - -typedef int16_t tla2021_reg_data_t; -typedef uint16_t tla2021_reg_config_t; - -struct tla2021_config { - const struct i2c_dt_spec bus; -}; - -struct tla2021_data { - const struct device *dev; - struct adc_context ctx; -#ifdef CONFIG_ADC_ASYNC - struct k_sem acq_lock; -#endif - tla2021_reg_data_t *buffer; - tla2021_reg_data_t *repeat_buffer; - - /* - * Shadow register - */ - tla2021_reg_config_t reg_config; -}; - -static int tla2021_read_register(const struct device *dev, uint8_t reg, uint16_t *value) -{ - int ret; - - const struct tla2021_config *config = dev->config; - uint8_t tmp[2]; - - ret = i2c_write_read_dt(&config->bus, ®, sizeof(reg), tmp, sizeof(tmp)); - if (ret) { - return ret; - } - - *value = sys_get_be16(tmp); - - return 0; -} - -static int tla2021_write_register(const struct device *dev, uint8_t reg, uint16_t value) -{ - int ret; - - const struct tla2021_config *config = dev->config; - uint8_t tmp[3] = {reg}; - - sys_put_be16(value, &tmp[1]); - - ret = i2c_write_dt(&config->bus, tmp, sizeof(tmp)); - if (ret) { - return ret; - } - - return 0; -} - -static int tla2021_channel_setup(const struct device *dev, const struct adc_channel_cfg *cfg) -{ - if (cfg->gain != ADC_GAIN_1) { - LOG_ERR("Invalid gain"); - return -EINVAL; - } - - if (cfg->reference != ADC_REF_INTERNAL) { - LOG_ERR("Invalid reference"); - return -EINVAL; - } - - if (cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) { - LOG_ERR("Invalid acquisition time"); - return -EINVAL; - } - - return 0; -} - -static int tla2021_start_read(const struct device *dev, const struct adc_sequence *seq) -{ - struct tla2021_data *data = dev->data; - - const size_t num_extra_samples = seq->options ? seq->options->extra_samplings : 0; - const size_t num_samples = (1 + num_extra_samples) * POPCOUNT(seq->channels); - - if (!(seq->channels & ADC_CHANNEL_msk)) { - LOG_ERR("Selected channel(s) not supported: %x", seq->channels); - return -EINVAL; - } - - if (seq->resolution != ADC_RESOLUTION) { - LOG_ERR("Selected resolution not supported: %d", seq->resolution); - return -EINVAL; - } - - if (seq->oversampling) { - LOG_ERR("Oversampling is not supported"); - return -EINVAL; - } - - if (seq->calibrate) { - LOG_ERR("Calibration is not supported"); - return -EINVAL; - } - - if (!seq->buffer) { - LOG_ERR("Buffer invalid"); - return -EINVAL; - } - - if (seq->buffer_size < (num_samples * sizeof(tla2021_reg_data_t))) { - LOG_ERR("buffer size too small"); - return -EINVAL; - } - - data->buffer = seq->buffer; - - adc_context_start_read(&data->ctx, seq); - - return adc_context_wait_for_completion(&data->ctx); -} - -static int tla2021_read_async(const struct device *dev, const struct adc_sequence *seq, - struct k_poll_signal *async) -{ - int ret; - - struct tla2021_data *data = dev->data; - - adc_context_lock(&data->ctx, async ? true : false, async); - ret = tla2021_start_read(dev, seq); - adc_context_release(&data->ctx, ret); - - return ret; -} - -static int tla2021_read(const struct device *dev, const struct adc_sequence *seq) -{ - return tla2021_read_async(dev, seq, NULL); -} - -static void tla2021_perform_read(const struct device *dev) -{ - struct tla2021_data *data = dev->data; - tla2021_reg_config_t reg; - tla2021_reg_data_t res; - int ret; - - /* - * Wait until sampling is done - */ - do { - ret = tla2021_read_register(dev, REG_CONFIG, ®); - if (ret < 0) { - adc_context_complete(&data->ctx, ret); - } - } while (!(reg & REG_CONFIG_OS_msk)); - - /* - * Read result - */ - ret = tla2021_read_register(dev, REG_DATA, &res); - if (ret) { - adc_context_complete(&data->ctx, ret); - } - - /* - * ADC data is stored in the upper 12 bits - */ - res >>= REG_DATA_pos; - *data->buffer++ = res; - - adc_context_on_sampling_done(&data->ctx, data->dev); -} - -static void adc_context_start_sampling(struct adc_context *ctx) -{ - int ret; - - struct tla2021_data *data = CONTAINER_OF(ctx, struct tla2021_data, ctx); - const struct device *dev = data->dev; - - tla2021_reg_config_t reg = data->reg_config; - - /* - * Start single-shot conversion - */ - WRITE_BIT(reg, REG_CONFIG_MODE_pos, 1); - WRITE_BIT(reg, REG_CONFIG_OS_pos, 1); - ret = tla2021_write_register(dev, REG_CONFIG, reg); - if (ret) { - LOG_WRN("Failed to start conversion"); - } - - data->repeat_buffer = data->buffer; - -#ifdef CONFIG_ADC_ASYNC - k_sem_give(&data->acq_lock); -#else - tla2021_perform_read(dev); -#endif -} - -static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) -{ - struct tla2021_data *data = CONTAINER_OF(ctx, struct tla2021_data, ctx); - - if (repeat_sampling) { - data->buffer = data->repeat_buffer; - } -} - -#ifdef CONFIG_ADC_ASYNC -static void tla2021_acq_thread_fn(void *p1, void *p2, void *p3) -{ - const struct device *dev = p1; - struct tla2021_data *data = dev->data; - - while (true) { - k_sem_take(&data->acq_lock, K_FOREVER); - - tla2021_perform_read(dev); - } -} -#endif - -static int tla2021_init(const struct device *dev) -{ - int ret; - - const struct tla2021_config *config = dev->config; - struct tla2021_data *data = dev->data; - - if (!i2c_is_ready_dt(&config->bus)) { - LOG_ERR("Bus not ready"); - return -EINVAL; - } - - ret = tla2021_write_register(dev, REG_CONFIG, data->reg_config); - if (ret) { - LOG_ERR("Device reset failed: %d", ret); - return ret; - } - - adc_context_unlock_unconditionally(&data->ctx); - - return 0; -} - -static DEVICE_API(adc, tla2021_driver_api) = { - .channel_setup = tla2021_channel_setup, - .read = tla2021_read, - .ref_internal = 4096, -#ifdef CONFIG_ADC_ASYNC - .read_async = tla2021_read_async, -#endif -}; - -#define TLA2021_THREAD_INIT(n) \ - K_THREAD_DEFINE(adc_tla2021_##n##_thread, ACQ_THREAD_STACK_SIZE, tla2021_acq_thread_fn, \ - DEVICE_DT_INST_GET(n), NULL, NULL, ACQ_THREAD_PRIORITY, 0, 0); - -#define TLA2021_INIT(n) \ - static const struct tla2021_config inst_##n##_config; \ - static struct tla2021_data inst_##n##_data; \ - IF_ENABLED(CONFIG_ADC_ASYNC, (TLA2021_THREAD_INIT(n))) \ - static const struct tla2021_config inst_##n##_config = { \ - .bus = I2C_DT_SPEC_INST_GET(n), \ - }; \ - static struct tla2021_data inst_##n##_data = { \ - .dev = DEVICE_DT_INST_GET(n), \ - ADC_CONTEXT_INIT_LOCK(inst_##n##_data, ctx), \ - ADC_CONTEXT_INIT_TIMER(inst_##n##_data, ctx), \ - ADC_CONTEXT_INIT_SYNC(inst_##n##_data, ctx), \ - .reg_config = REG_CONFIG_DEFAULT, \ - IF_ENABLED(CONFIG_ADC_ASYNC, \ - (.acq_lock = Z_SEM_INITIALIZER(inst_##n##_data.acq_lock, 0, 1),)) \ - }; \ - DEVICE_DT_INST_DEFINE(n, &tla2021_init, NULL, &inst_##n##_data, &inst_##n##_config, \ - POST_KERNEL, CONFIG_ADC_TLA2021_INIT_PRIORITY, &tla2021_driver_api); - -DT_INST_FOREACH_STATUS_OKAY(TLA2021_INIT) - -BUILD_ASSERT(CONFIG_I2C_INIT_PRIORITY < CONFIG_ADC_TLA2021_INIT_PRIORITY); diff --git a/drivers/adc/adc_tla202x.c b/drivers/adc/adc_tla202x.c new file mode 100644 index 0000000000000..fe3a2cc09d659 --- /dev/null +++ b/drivers/adc/adc_tla202x.c @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2023 Caspar Friedrich + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include +#include + +#define ADC_CONTEXT_USES_KERNEL_TIMER + +/* + * This requires to be included _after_ `#define ADC_CONTEXT_USES_KERNEL_TIMER` + */ +#include "adc_context.h" + +LOG_MODULE_REGISTER(tla2021, CONFIG_ADC_LOG_LEVEL); + +#define ACQ_THREAD_PRIORITY CONFIG_ADC_TLA202X_ACQUISITION_THREAD_PRIORITY +#define ACQ_THREAD_STACK_SIZE CONFIG_ADC_TLA202X_ACQUISITION_THREAD_STACK_SIZE + +#define MAX_CHANNELS 4 +#define ADC_RESOLUTION 12 + +#define WAKEUP_TIME_US 25 +#define CONVERSION_TIME_US 625 /* DR is 1600 SPS */ + +/* + * Conversion Data Register (RP = 00h) [reset = 0000h] + */ +#define REG_DATA 0x00 +#define REG_DATA_pos 4 + +/* + * Configuration Register (RP = 01h) [reset = 8583h] + */ +#define REG_CONFIG 0x01 +#define REG_CONFIG_DEFAULT 0x8583 +#define REG_CONFIG_DR_pos 5 +#define REG_CONFIG_MODE_pos 8 +#define REG_CONFIG_PGA_pos 9 /* TLA2024 Only */ +#define REG_CONFIG_PGA_msk GENMASK(11, 9) /* TLA2022 and TLA2024 Only */ +#define REG_CONFIG_MUX_pos 12 /* TLA2024 Only */ +#define REG_CONFIG_MUX_msk GENMASK(14, 12) /* TLA2024 Only */ +#define REG_CONFIG_OS_pos 15 +#define REG_CONFIG_OS_msk (BIT_MASK(1) << REG_CONFIG_OS_pos) + +enum { + MUX_DIFF_0_1 = 0, + MUX_DIFF_0_3 = 1, + MUX_DIFF_1_3 = 2, + MUX_DIFF_2_3 = 3, + MUX_SINGLE_0 = 4, + MUX_SINGLE_1 = 5, + MUX_SINGLE_2 = 6, + MUX_SINGLE_3 = 7, +}; + +enum { + /* Gain 1/3 */ + PGA_6144 = 0, + /* Gain 1/2 */ + PGA_4096 = 1, + /* Gain 1 (Default) */ + PGA_2048 = 2, + /* Gain 2 */ + PGA_1024 = 3, + /* Gain 4 */ + PGA_512 = 4, + /* Gain 8 */ + PGA_256 = 5 +}; + +typedef int16_t tla202x_reg_data_t; +typedef uint16_t tla202x_reg_config_t; + +struct tla202x_config { + const struct i2c_dt_spec bus; + bool has_pga; + uint8_t channel_count; +}; + +struct tla202x_data { + const struct device *dev; + struct adc_context ctx; +#ifdef CONFIG_ADC_ASYNC + struct k_sem acq_lock; +#endif + tla202x_reg_data_t *buffer; + tla202x_reg_data_t *repeat_buffer; + uint8_t channels; + + /* + * Shadow register + */ + tla202x_reg_config_t reg_config[MAX_CHANNELS]; +}; + +static int tla202x_read_register(const struct device *dev, uint8_t reg, uint16_t *value) +{ + int ret; + + const struct tla202x_config *config = dev->config; + uint8_t tmp[2]; + + ret = i2c_write_read_dt(&config->bus, ®, sizeof(reg), tmp, sizeof(tmp)); + if (ret) { + return ret; + } + + *value = sys_get_be16(tmp); + + return 0; +} + +static int tla202x_write_register(const struct device *dev, uint8_t reg, uint16_t value) +{ + int ret; + + const struct tla202x_config *config = dev->config; + uint8_t tmp[3] = {reg}; + + sys_put_be16(value, &tmp[1]); + + ret = i2c_write_dt(&config->bus, tmp, sizeof(tmp)); + if (ret) { + return ret; + } + + return 0; +} + +static int tla202x_channel_setup(const struct device *dev, const struct adc_channel_cfg *cfg) +{ + const struct tla202x_config *config = dev->config; + struct tla202x_data *data = dev->data; + + if (cfg->channel_id >= config->channel_count) { + LOG_ERR("invalid channel selection %u", cfg->channel_id); + return -EINVAL; + } + tla202x_reg_config_t *reg_config = &data->reg_config[cfg->channel_id]; + + if (config->has_pga) { + *reg_config &= ~REG_CONFIG_PGA_msk; + switch (cfg->gain) { + case ADC_GAIN_1_3: + *reg_config |= PGA_6144 << REG_CONFIG_PGA_pos; + break; + case ADC_GAIN_1_2: + *reg_config |= PGA_4096 << REG_CONFIG_PGA_pos; + break; + case ADC_GAIN_1: + *reg_config |= PGA_2048 << REG_CONFIG_PGA_pos; + break; + case ADC_GAIN_2: + *reg_config |= PGA_1024 << REG_CONFIG_PGA_pos; + break; + case ADC_GAIN_4: + *reg_config |= PGA_512 << REG_CONFIG_PGA_pos; + break; + case ADC_GAIN_8: + *reg_config |= PGA_256 << REG_CONFIG_PGA_pos; + break; + default: + LOG_ERR("Invalid gain"); + return -EINVAL; + } + } else { + if (cfg->gain != ADC_GAIN_1) { + LOG_ERR("Invalid gain"); + return -EINVAL; + } + } + + /* + * Only adc with more than one channels has a mux + */ +#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS) + if (config->channel_count > 1) { + *reg_config &= ~REG_CONFIG_MUX_msk; + + if (cfg->differential) { + if (cfg->input_positive == 0 && cfg->input_negative == 1) { + *reg_config |= MUX_DIFF_0_1 << REG_CONFIG_MUX_pos; + } else if (cfg->input_positive == 0 && cfg->input_negative == 3) { + *reg_config |= MUX_DIFF_0_3 << REG_CONFIG_MUX_pos; + } else if (cfg->input_positive == 1 && cfg->input_negative == 3) { + *reg_config |= MUX_DIFF_1_3 << REG_CONFIG_MUX_pos; + } else if (cfg->input_positive == 2 && cfg->input_negative == 3) { + *reg_config |= MUX_DIFF_2_3 << REG_CONFIG_MUX_pos; + } else { + LOG_ERR("Invalid channel config"); + return -EINVAL; + } + } else { + if (cfg->input_positive == 0) { + *reg_config |= MUX_SINGLE_0 << REG_CONFIG_MUX_pos; + } else if (cfg->input_positive == 1) { + *reg_config |= MUX_SINGLE_1 << REG_CONFIG_MUX_pos; + } else if (cfg->input_positive == 2) { + *reg_config |= MUX_SINGLE_2 << REG_CONFIG_MUX_pos; + } else if (cfg->input_positive == 3) { + *reg_config |= MUX_SINGLE_3 << REG_CONFIG_MUX_pos; + } else { + LOG_ERR("Invalid channel config"); + return -EINVAL; + } + } + } +#endif + + if (cfg->reference != ADC_REF_INTERNAL) { + LOG_ERR("Invalid reference"); + return -EINVAL; + } + + if (cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) { + LOG_ERR("Invalid acquisition time"); + return -EINVAL; + } + + return 0; +} + +static int tla202x_start_read(const struct device *dev, const struct adc_sequence *seq) +{ + struct tla202x_data *data = dev->data; + const struct tla202x_config *config = dev->config; + + const size_t num_extra_samples = seq->options ? seq->options->extra_samplings : 0; + const size_t num_samples = (1 + num_extra_samples) * POPCOUNT(seq->channels); + + if (find_msb_set(seq->channels) > config->channel_count) { + LOG_ERR("Selected channel(s) not supported: %x", seq->channels); + return -EINVAL; + } + + if (seq->resolution != ADC_RESOLUTION) { + LOG_ERR("Selected resolution not supported: %d", seq->resolution); + return -EINVAL; + } + + if (seq->oversampling) { + LOG_ERR("Oversampling is not supported"); + return -EINVAL; + } + + if (seq->calibrate) { + LOG_ERR("Calibration is not supported"); + return -EINVAL; + } + + if (!seq->buffer) { + LOG_ERR("Buffer invalid"); + return -EINVAL; + } + + if (seq->buffer_size < (num_samples * sizeof(tla202x_reg_data_t))) { + LOG_ERR("buffer size too small"); + return -EINVAL; + } + + data->buffer = seq->buffer; + + adc_context_start_read(&data->ctx, seq); + + return adc_context_wait_for_completion(&data->ctx); +} + +static int tla202x_read_async(const struct device *dev, const struct adc_sequence *seq, + struct k_poll_signal *async) +{ + int ret; + + struct tla202x_data *data = dev->data; + + adc_context_lock(&data->ctx, async ? true : false, async); + ret = tla202x_start_read(dev, seq); + adc_context_release(&data->ctx, ret); + + return ret; +} + +static int tla202x_read(const struct device *dev, const struct adc_sequence *seq) +{ + return tla202x_read_async(dev, seq, NULL); +} + +static void tla202x_perform_read(const struct device *dev) +{ + struct tla202x_data *data = dev->data; + tla202x_reg_config_t reg; + tla202x_reg_data_t res; + uint8_t ch; + int ret; + + while (data->channels) { + /* + * Select correct channel + */ + ch = find_lsb_set(data->channels) - 1; + reg = data->reg_config[ch]; + LOG_DBG("reg: %x", reg); + + /* + * Start single-shot conversion + */ + WRITE_BIT(reg, REG_CONFIG_MODE_pos, 1); + WRITE_BIT(reg, REG_CONFIG_OS_pos, 1); + ret = tla202x_write_register(dev, REG_CONFIG, reg); + if (ret) { + LOG_WRN("Failed to start conversion"); + } + + /* + * Wait until sampling is done + */ + k_usleep(WAKEUP_TIME_US + CONVERSION_TIME_US); + do { + k_yield(); + ret = tla202x_read_register(dev, REG_CONFIG, ®); + if (ret < 0) { + adc_context_complete(&data->ctx, ret); + } + } while (!(reg & REG_CONFIG_OS_msk)); + + /* + * Read result + */ + ret = tla202x_read_register(dev, REG_DATA, &res); + if (ret) { + adc_context_complete(&data->ctx, ret); + } + + /* + * ADC data is stored in the upper 12 bits + */ + res >>= REG_DATA_pos; + *data->buffer++ = res; + + LOG_DBG("read channel %d, result = %d", ch, res); + WRITE_BIT(data->channels, ch, 0); + } + + adc_context_on_sampling_done(&data->ctx, data->dev); +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct tla202x_data *data = CONTAINER_OF(ctx, struct tla202x_data, ctx); + const struct device *dev = data->dev; + + data->channels = ctx->sequence.channels; + data->repeat_buffer = data->buffer; + +#ifdef CONFIG_ADC_ASYNC + k_sem_give(&data->acq_lock); +#else + tla202x_perform_read(dev); +#endif +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) +{ + struct tla202x_data *data = CONTAINER_OF(ctx, struct tla202x_data, ctx); + + if (repeat_sampling) { + data->buffer = data->repeat_buffer; + } +} + +#ifdef CONFIG_ADC_ASYNC +static void tla202x_acq_thread_fn(void *p1, void *p2, void *p3) +{ + const struct device *dev = p1; + struct tla202x_data *data = dev->data; + + while (true) { + k_sem_take(&data->acq_lock, K_FOREVER); + + tla202x_perform_read(dev); + } +} +#endif + +static int tla202x_init(const struct device *dev) +{ + int ret; + + const struct tla202x_config *config = dev->config; + struct tla202x_data *data = dev->data; + + if (!i2c_is_ready_dt(&config->bus)) { + LOG_ERR("Bus not ready"); + return -EINVAL; + } + + for (uint8_t ch = 0; ch < MAX_CHANNELS; ch++) { + data->reg_config[ch] = REG_CONFIG_DEFAULT; + } + + ret = tla202x_write_register(dev, REG_CONFIG, data->reg_config[0]); + if (ret) { + LOG_ERR("Device reset failed: %d", ret); + return ret; + } + + adc_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static DEVICE_API(adc, tla202x_driver_api) = { + .channel_setup = tla202x_channel_setup, + .read = tla202x_read, + .ref_internal = 4096, +#ifdef CONFIG_ADC_ASYNC + .read_async = tla202x_read_async, +#endif +}; + +#define TLA202X_THREAD_INIT(t, n) \ + K_THREAD_DEFINE(adc_##t##_##n##_thread, ACQ_THREAD_STACK_SIZE, tla202x_acq_thread_fn, \ + DEVICE_DT_INST_GET(n), NULL, NULL, ACQ_THREAD_PRIORITY, 0, 0); + +#define TLA202X_INIT(n, t, pga, channels) \ + IF_ENABLED(CONFIG_ADC_ASYNC, (TLA202X_THREAD_INIT(t, n))) \ + static const struct tla202x_config inst_##t##_##n##_config = { \ + .bus = I2C_DT_SPEC_INST_GET(n), \ + .has_pga = pga, \ + .channel_count = channels, \ + }; \ + static struct tla202x_data inst_##t##_##n##_data = { \ + .dev = DEVICE_DT_INST_GET(n), \ + ADC_CONTEXT_INIT_LOCK(inst_##t##_##n##_data, ctx), \ + ADC_CONTEXT_INIT_TIMER(inst_##t##_##n##_data, ctx), \ + ADC_CONTEXT_INIT_SYNC(inst_##t##_##n##_data, ctx), \ + IF_ENABLED(CONFIG_ADC_ASYNC, \ + (.acq_lock = Z_SEM_INITIALIZER(inst_##t##_##n##_data.acq_lock, 0, 1),)) \ + }; \ + DEVICE_DT_INST_DEFINE(n, &tla202x_init, NULL, &inst_##t##_##n##_data, \ + &inst_##t##_##n##_config, POST_KERNEL, \ + CONFIG_ADC_TLA202X_INIT_PRIORITY, &tla202x_driver_api); + +#define DT_DRV_COMPAT ti_tla2021 +#define ADC_TLA2021_CHANNELS 1 +#define ADC_TLA2021_PGA false +DT_INST_FOREACH_STATUS_OKAY_VARGS(TLA202X_INIT, tla2021, ADC_TLA2021_PGA, ADC_TLA2021_CHANNELS) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT ti_tla2022 +#define ADC_TLA2022_CHANNELS 1 +#define ADC_TLA2022_PGA true +DT_INST_FOREACH_STATUS_OKAY_VARGS(TLA202X_INIT, tla2022, ADC_TLA2022_PGA, ADC_TLA2022_CHANNELS) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT ti_tla2024 +#define ADC_TLA2024_CHANNELS 4 +#define ADC_TLA2024_PGA true +DT_INST_FOREACH_STATUS_OKAY_VARGS(TLA202X_INIT, tla2024, ADC_TLA2024_PGA, ADC_TLA2024_CHANNELS) +#undef DT_DRV_COMPAT + +BUILD_ASSERT(CONFIG_I2C_INIT_PRIORITY < CONFIG_ADC_TLA202X_INIT_PRIORITY); diff --git a/drivers/adc/iadc_gecko.c b/drivers/adc/iadc_gecko.c index 3e76794d55ec8..5a6af0bafe059 100644 --- a/drivers/adc/iadc_gecko.c +++ b/drivers/adc/iadc_gecko.c @@ -7,9 +7,11 @@ #define DT_DRV_COMPAT silabs_gecko_iadc #include +#include +#include +#include #include -#include #define ADC_CONTEXT_USES_KERNEL_TIMER #include "adc_context.h" @@ -43,6 +45,9 @@ struct adc_gecko_data { struct adc_gecko_config { IADC_Config_t config; IADC_TypeDef *base; + const struct pinctrl_dev_config *pcfg; + const struct device *clock_dev; + const struct silabs_clock_control_cmu_config clock_cfg; void (*irq_cfg_func)(void); }; @@ -277,80 +282,6 @@ static int adc_gecko_read_async(const struct device *dev, } #endif -static void adc_gecko_gpio_busalloc_pos(IADC_PosInput_t input) -{ - uint32_t port = ((input << _IADC_SCAN_PINPOS_SHIFT) & - _IADC_SCAN_PORTPOS_MASK) >> _IADC_SCAN_PORTPOS_SHIFT; - uint32_t pin = ((input << _IADC_SCAN_PINPOS_SHIFT) & - _IADC_SCAN_PINPOS_MASK) >> _IADC_SCAN_PINPOS_SHIFT; - - switch (port) { - case _IADC_SCAN_PORTPOS_PORTA: - if (pin & 1) { - GPIO->ABUSALLOC |= GPIO_ABUSALLOC_AODD0_ADC0; - } else { - GPIO->ABUSALLOC |= GPIO_ABUSALLOC_AEVEN0_ADC0; - } - break; - - case _IADC_SCAN_PORTPOS_PORTB: - if (pin & 1) { - GPIO->BBUSALLOC |= GPIO_BBUSALLOC_BODD0_ADC0; - } else { - GPIO->BBUSALLOC |= GPIO_BBUSALLOC_BEVEN0_ADC0; - } - break; - - case _IADC_SCAN_PORTPOS_PORTC: - case _IADC_SCAN_PORTPOS_PORTD: - if (pin & 1) { - GPIO->CDBUSALLOC |= GPIO_CDBUSALLOC_CDODD0_ADC0; - } else { - GPIO->CDBUSALLOC |= GPIO_CDBUSALLOC_CDEVEN0_ADC0; - } - break; - - default: - } -} - -static void adc_gecko_gpio_busalloc_neg(IADC_NegInput_t input) -{ - uint32_t port = ((input << _IADC_SCAN_PINNEG_SHIFT) & - _IADC_SCAN_PORTNEG_MASK) >> _IADC_SCAN_PORTNEG_SHIFT; - uint32_t pin = ((input << _IADC_SCAN_PINNEG_SHIFT) & - _IADC_SCAN_PINNEG_MASK) >> _IADC_SCAN_PINNEG_SHIFT; - - switch (port) { - case _IADC_SCAN_PORTNEG_PORTA: - if (pin & 1) { - GPIO->ABUSALLOC |= GPIO_ABUSALLOC_AODD0_ADC0; - } else { - GPIO->ABUSALLOC |= GPIO_ABUSALLOC_AEVEN0_ADC0; - } - break; - - case _IADC_SCAN_PORTNEG_PORTB: - if (pin & 1) { - GPIO->BBUSALLOC |= GPIO_BBUSALLOC_BODD0_ADC0; - } else { - GPIO->BBUSALLOC |= GPIO_BBUSALLOC_BEVEN0_ADC0; - } - break; - - case _IADC_SCAN_PORTNEG_PORTC: - case _IADC_SCAN_PORTNEG_PORTD: - if (pin & 1) { - GPIO->CDBUSALLOC |= GPIO_CDBUSALLOC_CDODD0_ADC0; - } else { - GPIO->CDBUSALLOC |= GPIO_CDBUSALLOC_CDEVEN0_ADC0; - } - break; - - default: - } -} - static int adc_gecko_channel_setup(const struct device *dev, const struct adc_channel_cfg *channel_cfg) { @@ -424,10 +355,6 @@ static int adc_gecko_channel_setup(const struct device *dev, return -ENOTSUP; } - /* Setup GPIO xBUSALLOC registers if channel uses GPIO pin */ - adc_gecko_gpio_busalloc_pos(channel_config->input_positive); - adc_gecko_gpio_busalloc_neg(channel_config->input_negative); - channel_config->initialized = true; LOG_DBG("Channel setup succeeded!"); @@ -436,13 +363,19 @@ static int adc_gecko_channel_setup(const struct device *dev, static int adc_gecko_init(const struct device *dev) { + int err; const struct adc_gecko_config *config = dev->config; struct adc_gecko_data *data = dev->data; - CMU_ClockEnable(cmuClock_IADC0, true); + err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg); + if (err < 0) { + return err; + } - /* Select clock for IADC */ - CMU_ClockSelectSet(cmuClock_IADCCLK, cmuSelect_FSRCO); /* FSRCO - 20MHz */ + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0 && err != -ENOENT) { + return err; + } data->dev = dev; @@ -463,11 +396,15 @@ static DEVICE_API(adc, api_gecko_adc_driver_api) = { }; #define GECKO_IADC_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ \ static void adc_gecko_config_func_##n(void); \ \ const static struct adc_gecko_config adc_gecko_config_##n = { \ .base = (IADC_TypeDef *)DT_INST_REG_ADDR(n),\ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_cfg = SILABS_DT_INST_CLOCK_CFG(n), \ .irq_cfg_func = adc_gecko_config_func_##n, \ }; \ static struct adc_gecko_data adc_gecko_data_##n = { \ diff --git a/drivers/audio/CMakeLists.txt b/drivers/audio/CMakeLists.txt index 0396ae23e483f..92119d25defaa 100644 --- a/drivers/audio/CMakeLists.txt +++ b/drivers/audio/CMakeLists.txt @@ -10,3 +10,4 @@ zephyr_library_sources_ifdef(CONFIG_AUDIO_TAS6422DAC tas6422dac.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_SHELL codec_shell.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_DMIC_MCUX dmic_mcux.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_WM8904 wm8904.c) +zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_CS43L22 cs43l22.c) diff --git a/drivers/audio/Kconfig b/drivers/audio/Kconfig index 70d02b5320a21..ccc4a7375d4f3 100644 --- a/drivers/audio/Kconfig +++ b/drivers/audio/Kconfig @@ -35,6 +35,7 @@ module = AUDIO_CODEC module-str = audio codec source "subsys/logging/Kconfig.template.log_config" +source "drivers/audio/Kconfig.cs43l22" source "drivers/audio/Kconfig.tas6422dac" source "drivers/audio/Kconfig.tlv320dac" source "drivers/audio/Kconfig.wm8904" diff --git a/drivers/audio/Kconfig.cs43l22 b/drivers/audio/Kconfig.cs43l22 new file mode 100644 index 0000000000000..6fa65a451b943 --- /dev/null +++ b/drivers/audio/Kconfig.cs43l22 @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Titouan Christophe +# SPDX-License-Identifier: Apache-2.0 + +config AUDIO_CODEC_CS43L22 + bool "Cirrus CS43L22 driver" + default y + select I2C + depends on GPIO + depends on DT_HAS_CIRRUS_CS43L22_ENABLED + help + Enable the driver for the Cirrus CS43L22 low Power, stereo DAC + with headphone & speaker amplifiers diff --git a/drivers/audio/codec_shell.c b/drivers/audio/codec_shell.c index b5c3421bf265e..f63d4c90e5332 100644 --- a/drivers/audio/codec_shell.c +++ b/drivers/audio/codec_shell.c @@ -39,6 +39,8 @@ static const char *const codec_channel_name[] = { [AUDIO_CHANNEL_REAR_CENTER] = "rear_center", [AUDIO_CHANNEL_SIDE_LEFT] = "side_left", [AUDIO_CHANNEL_SIDE_RIGHT] = "side_right", + [AUDIO_CHANNEL_HEADPHONE_LEFT] = "headphone_left", + [AUDIO_CHANNEL_HEADPHONE_RIGHT] = "headphone_right", [AUDIO_CHANNEL_ALL] = "all", }; @@ -81,7 +83,7 @@ static int cmd_start(const struct shell *sh, size_t argc, char *argv[]) { const struct device *dev; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "Audio Codec device not found"); return -ENODEV; @@ -95,7 +97,7 @@ static int cmd_stop(const struct shell *sh, size_t argc, char *argv[]) { const struct device *dev; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "Audio Codec device not found"); return -ENODEV; @@ -114,7 +116,7 @@ static int cmd_set_prop(const struct shell *sh, size_t argc, char *argv[]) char *endptr; audio_property_value_t property_value; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "Audio Codec device not found"); return -ENODEV; @@ -159,7 +161,7 @@ static int cmd_apply_prop(const struct shell *sh, size_t argc, char *argv[]) { const struct device *dev; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "Audio Codec device not found"); return -ENODEV; diff --git a/drivers/audio/cs43l22.c b/drivers/audio/cs43l22.c new file mode 100644 index 0000000000000..0da2af130b498 --- /dev/null +++ b/drivers/audio/cs43l22.c @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2025 Titouan Christophe + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(cirrus_cs43l22); + +#define DT_DRV_COMPAT cirrus_cs43l22 + +/* + * See datasheet: https://statics.cirrus.com/pubs/proDatasheet/CS43L22_F2.pdf + */ + +/* (datasheet) 6. REGISTER QUICK REFERENCE */ +#define REG_ID 0x01 +#define REG_POWER_CTL_1 0x02 +#define REG_POWER_CTL_2 0x04 +#define REG_CLOCKING_CTL 0x05 +#define REG_INTERFACE_CTL_1 0x06 +#define REG_INTERFACE_CTL_2 0x07 +#define REG_PASSTHROUGH_A 0x08 +#define REG_PASSTHROUGH_B 0x09 +#define REG_ANALOG_ZC_AND_SR 0x0a +#define REG_PASSTHROUGH_GANG_CONTROL 0x0c +#define REG_PLAYBACK_CTL_1 0x0d +#define REG_MISC_CTL 0x0e +#define REG_PLAYBACK_CTL_2 0x0f +#define REG_PASSTHROUGH_A_VOL 0x14 +#define REG_PASSTHROUGH_B_VOL 0x15 +#define REG_PCMA_VOL 0x1a +#define REG_PCMB_VOL 0x1b +#define REG_BEEP_FREQ 0x1c +#define REG_BEEP_VOL 0x1d +#define REG_BEEP_TONE 0x1e +#define REG_TONE_CTL 0x1f +#define REG_MASTER_A_VOL 0x20 +#define REG_MASTER_B_VOL 0x21 +#define REG_HEADPHONES_A_VOL 0x22 +#define REG_HEADPHONES_B_VOL 0x23 +#define REG_SPEAKER_A_VOL 0x22 +#define REG_SPEAKER_B_VOL 0x23 +#define REG_LIMITER_CTL_1 0x27 +#define REG_LIMITER_CTL_2 0x28 +#define REG_STATUS 0x2e +#define REG_SPEAKER_STATUS 0x31 + +/* (datasheet) 7.5.4 DAC Interface Format */ +#define DAC_IF_FORMAT_LEFT_JUSTIFIED 0 +#define DAC_IF_FORMAT_I2S 1 +#define DAC_IF_FORMAT_RIGHT_JUSTIFIED 2 + +/* (datasheet) 7.5.5 Audio Word Length */ +#define WORDLEN_32 0 +#define WORDLEN_24 1 +#define WORDLEN_20 2 +#define WORDLEN_16 3 +#define WORDLEN_RIGHT_24 0 +#define WORDLEN_RIGHT_20 1 +#define WORDLEN_RIGHT_18 2 +#define WORDLEN_RIGHT_16 3 + +/* (datasheet) 7.12 Playback Control 2 */ +#define HEADPHONES_B_MUTE (1 << 7) +#define HEADPHONES_A_MUTE (1 << 6) +#define SPEAKER_B_MUTE (1 << 5) +#define SPEAKER_A_MUTE (1 << 4) + +#define cs43l22_write(_i2c, _reg, _value) \ + cs43l22_write_masked(_i2c, _reg, _value, 0xff) + +static inline int cs43l22_write_masked(const struct i2c_dt_spec *i2c, uint8_t reg, + uint8_t value, uint8_t mask) +{ + int ret; + uint8_t actual_value = 0; + + if (mask != 0xff) { + ret = i2c_burst_read_dt(i2c, reg, &actual_value, 1); + if (ret) { + LOG_ERR("Unable to get actual register value [%02X]", reg); + return ret; + } + } + actual_value = (actual_value & ~mask) | (value & mask); + + return i2c_burst_write_dt(i2c, reg, &actual_value, 1); +} + +#define cs43l22_soft_power_down(_i2c) cs43l22_write(_i2c, REG_POWER_CTL_1, 0x01) +#define cs43l22_soft_power_up(_i2c) cs43l22_write(_i2c, REG_POWER_CTL_1, 0x9e) + +struct cs43l22_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec reset_gpio; +}; + +static int cs43l22_configure(const struct device *dev, struct audio_codec_cfg *audiocfg) +{ + uint8_t format, wordlen; + const struct cs43l22_config *cfg = dev->config; + + if (audiocfg->dai_route != AUDIO_ROUTE_PLAYBACK) { + return -ENOTSUP; + } + + switch (audiocfg->dai_type) { + case AUDIO_DAI_TYPE_LEFT_JUSTIFIED: + format = DAC_IF_FORMAT_LEFT_JUSTIFIED; + break; + case AUDIO_DAI_TYPE_I2S: + format = DAC_IF_FORMAT_I2S; + break; + case AUDIO_DAI_TYPE_RIGHT_JUSTIFIED: + format = DAC_IF_FORMAT_RIGHT_JUSTIFIED; + break; + default: + return -ENOTSUP; + } + + if (format == DAC_IF_FORMAT_RIGHT_JUSTIFIED) { + switch (audiocfg->dai_cfg.i2s.word_size) { + case 16: + wordlen = WORDLEN_RIGHT_16; + break; + case 18: + wordlen = WORDLEN_RIGHT_18; + break; + case 20: + wordlen = WORDLEN_RIGHT_20; + break; + case 24: + wordlen = WORDLEN_RIGHT_24; + break; + default: + return -ENOTSUP; + } + } else { + switch (audiocfg->dai_cfg.i2s.word_size) { + case 16: + wordlen = WORDLEN_16; + break; + case 20: + wordlen = WORDLEN_20; + break; + case 24: + wordlen = WORDLEN_24; + break; + case 32: + wordlen = WORDLEN_32; + break; + default: + return -ENOTSUP; + } + } + + if (cs43l22_soft_power_down(&cfg->i2c)) { + return -EIO; + } + /* Set automatic clock detection */ + if (cs43l22_write(&cfg->i2c, REG_CLOCKING_CTL, (1 << 7))) { + return -EIO; + } + /* Set input audio format */ + if (cs43l22_write_masked(&cfg->i2c, REG_INTERFACE_CTL_1, (format << 2) | wordlen, 0xdf)) { + return -EIO; + } + if (cs43l22_soft_power_up(&cfg->i2c)) { + return -EIO; + } + return 0; +} + +static void cs43l22_start_output(const struct device *dev) +{ +} + +static void cs43l22_stop_output(const struct device *dev) +{ +} + +static int cs43l22_apply_properties(const struct device *dev) +{ + return 0; +} + +static inline int cs43l22_set_mute(const struct i2c_dt_spec *i2c, + audio_channel_t channel, bool mute) +{ + uint8_t chan_mute_mask = 0; + + switch (channel) { + case AUDIO_CHANNEL_ALL: + chan_mute_mask = HEADPHONES_A_MUTE + | HEADPHONES_B_MUTE + | SPEAKER_A_MUTE + | SPEAKER_B_MUTE; + break; + case AUDIO_CHANNEL_HEADPHONE_LEFT: + chan_mute_mask = HEADPHONES_A_MUTE; + break; + case AUDIO_CHANNEL_HEADPHONE_RIGHT: + chan_mute_mask = HEADPHONES_B_MUTE; + break; + case AUDIO_CHANNEL_FRONT_LEFT: + chan_mute_mask = SPEAKER_A_MUTE; + break; + case AUDIO_CHANNEL_FRONT_RIGHT: + chan_mute_mask = SPEAKER_B_MUTE; + break; + default: + return -ENOTSUP; + } + + return cs43l22_write_masked(i2c, REG_PLAYBACK_CTL_2, + mute * chan_mute_mask, chan_mute_mask); +} + +static inline int cs43l22_set_volume(const struct i2c_dt_spec *i2c, + audio_channel_t channel, int vol) +{ + uint8_t reg; + uint8_t volume_scaled = 65 + (191 * vol / 100); + + switch (channel) { + case AUDIO_CHANNEL_HEADPHONE_LEFT: + reg = REG_HEADPHONES_A_VOL; + break; + case AUDIO_CHANNEL_HEADPHONE_RIGHT: + reg = REG_HEADPHONES_B_VOL; + break; + case AUDIO_CHANNEL_FRONT_LEFT: + reg = REG_SPEAKER_A_VOL; + break; + case AUDIO_CHANNEL_FRONT_RIGHT: + reg = REG_SPEAKER_B_VOL; + break; + default: + return -ENOTSUP; + } + + return cs43l22_write(i2c, reg, volume_scaled); +} + +static int cs43l22_set_property(const struct device *dev, audio_property_t property, + audio_channel_t channel, audio_property_value_t val) +{ + const struct cs43l22_config *cfg = dev->config; + + switch (property) { + case AUDIO_PROPERTY_OUTPUT_MUTE: + return cs43l22_set_mute(&cfg->i2c, channel, val.mute); + case AUDIO_PROPERTY_OUTPUT_VOLUME: + return cs43l22_set_volume(&cfg->i2c, channel, val.vol); + default: + return -ENOTSUP; + } + +} + +static const struct audio_codec_api cs43l22_api = { + .configure = cs43l22_configure, + .start_output = cs43l22_start_output, + .stop_output = cs43l22_stop_output, + .set_property = cs43l22_set_property, + .apply_properties = cs43l22_apply_properties, +}; + +static int cs43l22_init(const struct device *dev) +{ + uint8_t regval; + const struct cs43l22_config *cfg = dev->config; + int ret; + + ret = gpio_pin_configure_dt(&cfg->reset_gpio, GPIO_OUTPUT_ACTIVE); + if (ret) { + return -EIO; + } + + ret = i2c_burst_read_dt(&cfg->i2c, REG_ID, ®val, 1); + if (ret) { + LOG_ERR("Unable to read device ID"); + return -ENODEV; + } + + if ((regval >> 3) != 0x1C) { + LOG_ERR("Wrong Chip ID"); + return -ENODEV; + } + + LOG_DBG("Found CS43L22 (chip=%02X, rev=%c%d)", + regval >> 3, 'A' + ((regval >> 1) & 3), regval & 1); + + return 0; +} + +#define CS43L22_INIT(inst) \ + static const struct cs43l22_config cs43l22_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .reset_gpio = GPIO_DT_SPEC_INST_GET(inst, reset_gpios), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, cs43l22_init, NULL, NULL, \ + &cs43l22_config_##inst, POST_KERNEL, \ + CONFIG_AUDIO_CODEC_INIT_PRIORITY, \ + &cs43l22_api); + +DT_INST_FOREACH_STATUS_OKAY(CS43L22_INIT) diff --git a/drivers/audio/dmic_nrfx_pdm.c b/drivers/audio/dmic_nrfx_pdm.c index 4ffd00f49099e..b7ea336b9f9d6 100644 --- a/drivers/audio/dmic_nrfx_pdm.c +++ b/drivers/audio/dmic_nrfx_pdm.c @@ -8,17 +8,25 @@ #include #include #include +#include #include #include #include LOG_MODULE_REGISTER(dmic_nrfx_pdm, CONFIG_AUDIO_DMIC_LOG_LEVEL); +#if CONFIG_SOC_SERIES_NRF54HX +#define DMIC_NRFX_CLOCK_FREQ 8*1000*1000UL +#else +#define DMIC_NRFX_CLOCK_FREQ 32*1000*1000UL +#endif + struct dmic_nrfx_pdm_drv_data { const nrfx_pdm_t *pdm; struct onoff_manager *clk_mgr; struct onoff_client clk_cli; struct k_mem_slab *mem_slab; + void *mem_slab_buffer; uint32_t block_size; struct k_msgq rx_queue; bool request_clock : 1; @@ -36,17 +44,25 @@ struct dmic_nrfx_pdm_drv_cfg { PCLK32M_HFXO, ACLK } clk_src; + void *mem_reg; }; -static void free_buffer(struct dmic_nrfx_pdm_drv_data *drv_data, void *buffer) +static void free_buffer(struct dmic_nrfx_pdm_drv_data *drv_data) +{ + k_mem_slab_free(drv_data->mem_slab, drv_data->mem_slab_buffer); + LOG_DBG("Freed buffer %p", drv_data->mem_slab_buffer); +} + +static void stop_pdm(struct dmic_nrfx_pdm_drv_data *drv_data) { - k_mem_slab_free(drv_data->mem_slab, buffer); - LOG_DBG("Freed buffer %p", buffer); + drv_data->stopping = true; + nrfx_pdm_stop(drv_data->pdm); } static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt) { struct dmic_nrfx_pdm_drv_data *drv_data = dev->data; + const struct dmic_nrfx_pdm_drv_cfg *drv_cfg = dev->config; int ret; bool stop = false; @@ -54,11 +70,18 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt) void *buffer; nrfx_err_t err; - ret = k_mem_slab_alloc(drv_data->mem_slab, &buffer, K_NO_WAIT); + ret = k_mem_slab_alloc(drv_data->mem_slab, &drv_data->mem_slab_buffer, K_NO_WAIT); if (ret < 0) { LOG_ERR("Failed to allocate buffer: %d", ret); stop = true; } else { + ret = dmm_buffer_in_prepare(drv_cfg->mem_reg, drv_data->mem_slab_buffer, + drv_data->block_size, &buffer); + if (ret < 0) { + LOG_ERR("Failed to prepare buffer: %d", ret); + stop_pdm(drv_data); + return; + } err = nrfx_pdm_buffer_set(drv_data->pdm, buffer, drv_data->block_size / 2); if (err != NRFX_SUCCESS) { LOG_ERR("Failed to set buffer: 0x%08x", err); @@ -69,7 +92,14 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt) if (drv_data->stopping) { if (evt->buffer_released) { - free_buffer(drv_data, evt->buffer_released); + ret = dmm_buffer_in_release(drv_cfg->mem_reg, drv_data->mem_slab_buffer, + drv_data->block_size, evt->buffer_released); + if (ret < 0) { + LOG_ERR("Failed to release buffer: %d", ret); + stop_pdm(drv_data); + return; + } + free_buffer(drv_data); } if (drv_data->active) { @@ -79,22 +109,26 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt) } } } else if (evt->buffer_released) { + ret = dmm_buffer_in_release(drv_cfg->mem_reg, drv_data->mem_slab_buffer, + drv_data->block_size, evt->buffer_released); + if (ret < 0) { + LOG_ERR("Failed to release buffer: %d", ret); + stop_pdm(drv_data); + return; + } ret = k_msgq_put(&drv_data->rx_queue, - &evt->buffer_released, + &drv_data->mem_slab_buffer, K_NO_WAIT); if (ret < 0) { LOG_ERR("No room in RX queue"); stop = true; - - free_buffer(drv_data, evt->buffer_released); + free_buffer(drv_data); } else { LOG_DBG("Queued buffer %p", evt->buffer_released); } } - if (stop) { - drv_data->stopping = true; - nrfx_pdm_stop(drv_data->pdm); + stop_pdm(drv_data); } } @@ -168,7 +202,7 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg, better_found = true; } #else - if (IS_ENABLED(CONFIG_SOC_SERIES_NRF53X)) { + if (IS_ENABLED(CONFIG_SOC_SERIES_NRF53X) || IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX)) { const uint32_t src_freq = (NRF_PDM_HAS_MCLKCONFIG && drv_cfg->clk_src == ACLK) /* The DMIC_NRFX_PDM_DEVICE() macro contains build @@ -180,9 +214,13 @@ static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg, * not defined (this expression will be eventually * optimized away then). */ + /* TODO : PS does not provide correct formula for nRF54H20 PDM_CLK. + * Assume that master clock source frequency is 8 MHz. Remove once + * correct formula is found. + */ ? DT_PROP_OR(DT_NODELABEL(clock), hfclkaudio_frequency, 0) - : 32*1000*1000UL; + : DMIC_NRFX_CLOCK_FREQ; uint32_t req_freq = req_rate * ratio; /* As specified in the nRF5340 PS: * @@ -562,6 +600,7 @@ static int dmic_nrfx_pdm_read(const struct device *dev, return ret; } +#if CONFIG_CLOCK_CONTROL_NRF static void init_clock_manager(const struct device *dev) { struct dmic_nrfx_pdm_drv_data *drv_data = dev->data; @@ -581,6 +620,7 @@ static void init_clock_manager(const struct device *dev) drv_data->clk_mgr = z_nrf_clock_control_get_onoff(subsys); __ASSERT_NO_MSG(drv_data->clk_mgr != NULL); } +#endif static const struct _dmic_ops dmic_ops = { .configure = dmic_nrfx_pdm_configure, @@ -609,7 +649,8 @@ static const struct _dmic_ops dmic_ops = { k_msgq_init(&dmic_nrfx_pdm_data##idx.rx_queue, \ (char *)rx_msgs##idx, sizeof(void *), \ ARRAY_SIZE(rx_msgs##idx)); \ - init_clock_manager(dev); \ + IF_ENABLED(CONFIG_CLOCK_CONTROL_NRF, \ + (init_clock_manager(dev);)) \ return 0; \ } \ static void event_handler##idx(const nrfx_pdm_evt_t *evt) \ @@ -624,6 +665,7 @@ static const struct _dmic_ops dmic_ops = { .nrfx_def_cfg.skip_psel_cfg = true, \ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(PDM(idx)), \ .clk_src = PDM_CLK_SRC(idx), \ + .mem_reg = DMM_DEV_TO_REG(PDM(idx)), \ }; \ BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || NRF_PDM_HAS_MCLKCONFIG, \ "Clock source ACLK is not available."); \ diff --git a/drivers/audio/mic_privacy/intel/CMakeLists.txt b/drivers/audio/mic_privacy/intel/CMakeLists.txt new file mode 100644 index 0000000000000..63f9d81bec9c5 --- /dev/null +++ b/drivers/audio/mic_privacy/intel/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_MIC_PRIVACY mic_privacy.c) diff --git a/drivers/audio/mic_privacy/intel/Kconfig.mic_privacy b/drivers/audio/mic_privacy/intel/Kconfig.mic_privacy new file mode 100644 index 0000000000000..aea9ed7b00dd1 --- /dev/null +++ b/drivers/audio/mic_privacy/intel/Kconfig.mic_privacy @@ -0,0 +1,11 @@ +# SOF Microphone Privacy configuration options + +# Copyright (c) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config INTEL_ADSP_MIC_PRIVACY + bool "MIC PRIVACY device driver support" + default y + depends on DT_HAS_INTEL_ADSP_MIC_PRIVACY_ENABLED + help + Enable MIC PRIVACY device driver diff --git a/drivers/audio/mic_privacy/intel/mic_privacy.c b/drivers/audio/mic_privacy/intel/mic_privacy.c new file mode 100644 index 0000000000000..1d2076e8bb619 --- /dev/null +++ b/drivers/audio/mic_privacy/intel/mic_privacy.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "mic_privacy_registers.h" +#include +#include +#include +#include +#include + +#define LOG_DOMAIN mic_priv_zephyr + +LOG_MODULE_REGISTER(LOG_DOMAIN); + +#define DT_DRV_COMPAT intel_adsp_mic_privacy + +#define DMICPVC_ADDRESS (DT_INST_REG_ADDR(0)) +#define DFMICPVCP_ADDRESS (DMICPVC_ADDRESS) +#define DFMICPVCS_ADDRESS (DMICPVC_ADDRESS + 0x0004) +#define DFFWMICPVCCS_ADDRESS (DMICPVC_ADDRESS + 0x0006) + +#define DMICVSSX_ADDRESS (0x16000) +#define DMICXLVSCTL_ADDRESS (DMICVSSX_ADDRESS + 0x0004) +#define DMICXPVCCS_ADDRESS (DMICVSSX_ADDRESS + 0x0010) + +static inline void ace_mic_priv_intc_unmask(void) +{ + ACE_DINT[0].ie[ACE_INTL_MIC_PRIV] = BIT(0); +} + +static inline void ace_dmic_intc_unmask(void) +{ + ACE_DINT[0].ie[ACE_INTL_DMIC] = BIT(0); +} + +static void mic_privacy_enable_fw_managed_irq(bool enable_irq, const void *fn) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DFFWMICPVCCS_ADDRESS); + if (enable_irq) { + pv_ccs.part.mdstschgie = 1; + } else { + pv_ccs.part.mdstschgie = 0; + } + sys_write16(pv_ccs.full, DFFWMICPVCCS_ADDRESS); + + if (enable_irq && !irq_is_enabled(DT_INST_IRQN(0))) { + + irq_connect_dynamic(DT_INST_IRQN(0), 0, + fn, + DEVICE_DT_INST_GET(0), 0); + + irq_enable(DT_INST_IRQN(0)); + ace_mic_priv_intc_unmask(); + } +} + +static void mic_privacy_clear_fw_managed_irq(void) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DFFWMICPVCCS_ADDRESS); + pv_ccs.part.mdstschg = 1; + sys_write16(pv_ccs.full, DFFWMICPVCCS_ADDRESS); +} + +static void mic_privacy_enable_dmic_irq(bool enable_irq, const void *fn) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DMICXPVCCS_ADDRESS); + if (enable_irq) { + pv_ccs.part.mdstschgie = 1; + } else { + pv_ccs.part.mdstschgie = 0; + } + sys_write16(pv_ccs.full, DMICXPVCCS_ADDRESS); + + if (enable_irq) { + irq_connect_dynamic(ACE_INTL_DMIC, 0, + fn, + NULL, 0); + irq_enable(ACE_INTL_DMIC); + ace_dmic_intc_unmask(); + } +} + +static bool mic_privacy_get_dmic_irq_status(void) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DMICXPVCCS_ADDRESS); + return pv_ccs.part.mdstschg; +} + +static void mic_privacy_clear_dmic_irq_status(void) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DMICXPVCCS_ADDRESS); + pv_ccs.part.mdstschg = 1; + sys_write16(pv_ccs.full, DMICXPVCCS_ADDRESS); +} + +static enum mic_privacy_policy mic_privacy_get_policy(void) +{ + union DFMICPVCP micpvcp; + + micpvcp.full = sys_read32(DFMICPVCP_ADDRESS); + + if (micpvcp.part.ddze == 2 && micpvcp.part.ddzpl == 1) { + return MIC_PRIVACY_HW_MANAGED; + } else if (micpvcp.part.ddze == 2 && micpvcp.part.ddzpl == 0) { + return MIC_PRIVACY_FW_MANAGED; + } else if (micpvcp.part.ddze == 3) { + return MIC_PRIVACY_FORCE_MIC_DISABLED; + } else { + return MIC_PRIVACY_DISABLED; + } +} + +static uint32_t mic_privacy_get_privacy_policy_register_raw_value(void) +{ + return sys_read32(DFMICPVCP_ADDRESS); +} + +static uint32_t mic_privacy_get_dma_data_zeroing_wait_time(void) +{ + union DFMICPVCP micpvcp; + + micpvcp.full = sys_read32(DFMICPVCP_ADDRESS); + return micpvcp.part.ddzwt; +} + +static uint32_t mic_privacy_get_dma_data_zeroing_link_select(void) +{ + union DFMICPVCP micpvcp; + + micpvcp.full = sys_read32(DFMICPVCP_ADDRESS); + return micpvcp.part.ddzls; +} + +static uint32_t mic_privacy_get_dmic_mic_disable_status(void) +{ + union DMICXPVCCS pvccs; + + pvccs.full = sys_read32(DMICXPVCCS_ADDRESS); + return pvccs.part.mdsts; +} + +static uint32_t mic_privacy_get_fw_managed_mic_disable_status(void) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DFFWMICPVCCS_ADDRESS); + return pv_ccs.part.mdsts; +} + +static void mic_privacy_set_fw_managed_mode(bool is_fw_managed_enabled) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DFFWMICPVCCS_ADDRESS); + if (is_fw_managed_enabled) { + pv_ccs.part.fmmd = 1; + } else { + pv_ccs.part.fmmd = 0; + } + sys_write16(pv_ccs.full, DFFWMICPVCCS_ADDRESS); +} + +static void mic_privacy_set_fw_mic_disable_status(bool fw_mic_disable_status) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DFFWMICPVCCS_ADDRESS); + if (fw_mic_disable_status) { + pv_ccs.part.fmdsts = 1; + } else { + pv_ccs.part.fmdsts = 0; + } + sys_write16(pv_ccs.full, DFFWMICPVCCS_ADDRESS); +} + +static uint32_t mic_privacy_get_fw_mic_disable_status(void) +{ + union DFFWMICPVCCS pv_ccs; + + pv_ccs.full = sys_read16(DFFWMICPVCCS_ADDRESS); + return pv_ccs.part.fmdsts; +} + +static int intel_adsp_mic_priv_init(const struct device *dev) +{ + return 0; +}; + +static const struct mic_privacy_api_funcs mic_privacy_ops = { + .enable_fw_managed_irq = mic_privacy_enable_fw_managed_irq, + .clear_fw_managed_irq = mic_privacy_clear_fw_managed_irq, + .enable_dmic_irq = mic_privacy_enable_dmic_irq, + .get_dmic_irq_status = mic_privacy_get_dmic_irq_status, + .clear_dmic_irq_status = mic_privacy_clear_dmic_irq_status, + .get_policy = mic_privacy_get_policy, + .get_privacy_policy_register_raw_value = mic_privacy_get_privacy_policy_register_raw_value, + .get_dma_data_zeroing_wait_time = mic_privacy_get_dma_data_zeroing_wait_time, + .get_dma_data_zeroing_link_select = mic_privacy_get_dma_data_zeroing_link_select, + .get_dmic_mic_disable_status = mic_privacy_get_dmic_mic_disable_status, + .get_fw_managed_mic_disable_status = mic_privacy_get_fw_managed_mic_disable_status, + .set_fw_managed_mode = mic_privacy_set_fw_managed_mode, + .set_fw_mic_disable_status = mic_privacy_set_fw_mic_disable_status, + .get_fw_mic_disable_status = mic_privacy_get_fw_mic_disable_status +}; + +#define INTEL_ADSP_MIC_PRIVACY_INIT(inst) \ + \ + static const struct intel_adsp_mic_priv_cfg intel_adsp_mic_priv##inst##_config = { \ + .base = DT_INST_REG_ADDR(inst), \ + .regblock_size = DT_INST_REG_SIZE(inst), \ + }; \ + \ + static struct intel_adsp_mic_priv_data intel_adsp_mic_priv##inst##_data = {}; \ + \ + DEVICE_DT_INST_DEFINE(inst, &intel_adsp_mic_priv_init, \ + NULL, \ + &intel_adsp_mic_priv##inst##_data, \ + &intel_adsp_mic_priv##inst##_config, POST_KERNEL, \ + 0, \ + &mic_privacy_ops); \ + \ + +DT_INST_FOREACH_STATUS_OKAY(INTEL_ADSP_MIC_PRIVACY_INIT) diff --git a/drivers/audio/mic_privacy/intel/mic_privacy_registers.h b/drivers/audio/mic_privacy/intel/mic_privacy_registers.h new file mode 100644 index 0000000000000..360c75004e0f9 --- /dev/null +++ b/drivers/audio/mic_privacy/intel/mic_privacy_registers.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __INTEL_DRIVER_MIC_PRIVACY_REGISTERS_H__ +#define __INTEL_DRIVER_MIC_PRIVACY_REGISTERS_H__ + +#include +#include +#include + +/** + * DFMICPVCP + * Microphone Privacy Policy + * + * Offset: 00h + * Block: DfMICPVC + * + * This register controls the microphone privacy DMA data zeroing feature HW policy. + */ +union DFMICPVCP { + uint32_t full; + struct { + /** + * DMA Data Zeroing Wait Time + * type: RW/L, rst: 0b, rst domain: PLTRST + * + * Indicates the time-out duration to wait before forcing the actual + * microphone privacy DMA data zeroing. Unit in number of RTC clocks. + * Valid and static when DDZE = 10. For DDZE = 0x or 11 case, time-out + * is not necessary as it will not be enabled or force mic disable statically. + * Locked when DDZPL = 1. + */ + uint32_t ddzwt : 16; + /** + * DMA Data Zeroing Enable + * type: RW/L, rst: 00b, rst domain: PLTRST + * + * Indicates the policy setting for HW to force the microphone privacy DMA data zeroing. + * 0x: Disabled + * 10: Enabled (mic disable dynamically depending on privacy signaling input) + * 11: Enabled (force mic disable statically) + * Locked when DDZPL = 1. + */ + uint32_t ddze : 2; + /** + * De-glitcher Enable + * type: RW/L, rst: 0b, rst domain: PLTRST + * + * De-glitcher enable for privacy signaling GPIO input running on resume clock domain. + * Locked when DDZPL = 1. + */ + uint32_t dge : 1; + /** + * DMA Data Zeroing Policy Lock + * type: RW/L, rst: 0b, rst domain: PLTRST + * + * When set to 1, it locks the privacy DMA data zeroing policy setting. + */ + uint32_t ddzpl : 1; + + /** + * DMA Data Zeroing Link Select + * type: RW/L, rst: 0b, rst domain: PLTRST + * + * Select 1 or more audio link to apply the microphone privacy DMA data zeroing. + * 1 bit per audio link. + * [6:0]: SoundWire link segment + * [7]: DMIC + * Valid and static when DDZE = 1. + * Locked when DDZPL = 1. + */ + uint32_t ddzls : 8; + /** + * Reserved (Preserved) + * type: RO, rst: 000 0000h, rst domain: nan + * + * SW must preserve the original value when writing. + */ + uint32_t rsvd31 : 4; + } part; +}; + +/** + * DFMICPVCS + * Microphone Privacy Status + * + * Offset: 04h + * Block: DfMICPVC + * + * This register reports the microphone privacy DMA data zeroing status. + */ +union DFMICPVCS { + uint16_t full; + struct { + /** + * Mic Disabled Indicator Output + * type: RO/V, rst: 0b, rst domain: nan + * + * Indicates the mic disabled status output to GPIO (i.e. the privacy + * indicator output). + */ + uint16_t mdio : 1; + /** + * Reserved (Zero) + * type: RO, rst: 0000h, rst domain: nan + * + * SW must use zeros for writes. + */ + uint16_t rsvd15 : 15; + } part; +}; + +/** + * DFFWMICPVCCS + * FW Microphone Privacy Control & Status + * + * Offset: 06h + * Block: DfMICPVC + * + * This register allows DSP FW to manage the mic privacy operation (if not locked by trusted host). + */ +union DFFWMICPVCCS { + uint16_t full; + struct { + /** + * Mic Disable Status Changed Interrupt Enabled + * type: RW, rst: 0b, rst domain: DSPLRST + * + * When set to 1, it allows MDSTSCHG bit to be propagated as mic privacy interrupt + * to the DSP Cores. + */ + uint16_t mdstschgie : 1; + /** + * FW Managed Mic Disable + * type: RW/L, rst: 0b, rst domain: DSPLRST + * + * When set to 1, it indicates FW will manage its own time-out, decide which related link + * DMA should zero out the data (through DGLISxCS.DDZ), and update the privacy signaling + * output (through FMDSTS). + * HW will NOT control any of the DMIC / SoundWire link level DMA data zeroing or privacy + * signaling output in this case. Locked when DfMICPVCCGP. DDZPL = 1. + */ + uint16_t fmmd : 1; + /** + * FW Mic Disable Status + * type: RW, rst: 0b, rst domain: DSPLRST + * + * When set to 1, it indicates FW has quiesced the mic input stream gracefully and + * instructs HW to set privacy indicator output (no dependency on privacy + * signaling input). Valid if FMMD = 1. + */ + uint16_t fmdsts : 1; + /** + * Reserved (Preserved) + * type: RO, rst: 00h, rst domain: nan + * + * SW must preserve the original value when writing. + */ + uint16_t rsvd7 : 5; + /** + * Mic Disable Status Changed + * type: RW/1C, rst: 0b, rst domain: DSPLRST + * + * Asserted when mic disable status has changed state (independent of MDSTSCHGIE setting), + * and trigger interrupt if enabled. + * + * Note: If MDSTS change again before the current MDSTSCHG is acknowledged by DSP FW, + * the bit will still remain set until cleared by DSP FW. + */ + uint16_t mdstschg : 1; + /** + * Mic Disable Status + * type: RO/V, rst: 0b, rst domain: nan + * + * Indicates the live mic disable status input from GPIO (if FMMD = 1). When asserted and + * the microphone privacy DMA data zeroing policy is enabled, FW will manage its + * own time-out and decide which related link DMA should zero out the data + * (DGLISxCS.DDZ = 1), followed by setting the mic privacy indicator output (FMDSTS = 1). + * When de-asserted, FW should remove the DMA data zeroing (DGLISxCS.DDZ = 0) and clear + * the privacy indicator output (FMDSTS = 0) as soon as possible. + */ + uint16_t mdsts : 1; + /** + * Reserved (Preserved) + * type: RO, rst: 00h, rst domain: nan + * + * SW must preserve the original value when writing. + */ + uint16_t rsvd15 : 6; + } part; +}; + +/** + * DMICXPVCCS + * Digital Microphone x Privacy Control & Status + * + * Offset: 10h + * Block: DMICVSSX_AON + * + * This register controls the status reporting structure of the microphone privacy DMA data + * zeroing feature. + */ +union DMICXPVCCS { + uint16_t full; + struct { + /** + * Mic Disable Status Changed Interrupt Enabled + * type: RW, rst: 0h, rst domain: FLR + * + * When set to 1, it allows MDSTSCHG bit to be propagated as DMIC + * / SoundWire interrupt to the DSP Cores / host CPU. + */ + uint16_t mdstschgie : 1; + /** + * Reserved + * type: RO, rst: 00h, rst domain: N/A + */ + uint16_t rsvd7 : 7; + /** + * Mic Disable Status Changed + * type: RW/1C, rst: 0h, rst domain: FLR + * + * Asserted when mic disable status has changed state (independent of MDSTSCHGIE + * setting), and trigger interrupt if enabled. + * Note: If MDSTS change again before the current MDSTSCHG is acknowledged by + * DSP FW / host SW, the bit will still remain set until cleared by + * DSP FW / host SW. + */ + uint16_t mdstschg: 1; + /** + * Mic Disable Status + * type: RO/V, rst: 0h, rst domain: N/A + * + * Indicates the live mic disable status input from GPIO + * (for the selected mic audio link per DFMICPVCP.DDZLS). + * When asserted and the microphone privacy DMA data zeroing policy is enabled, + * the timer will start counting and force the selected mic data to zero + * (after time-out). When de-asserted, + * it remove the DMA data zeroing immediately (including stopping the timer + * if it has not expired). + */ + uint16_t mdsts: 1; + /** + * Force Mic Disable + * type: RO/V, rst: 0h, rst domain: N/A + * + * Indicates the microphone endpoint + * (for the selected mic audio link per DFMICPVCP.DDZLS) + * is statically force mic disable by trusted agent and SW / FW should hide + * the endpoint from being exposed to OS. + */ + uint16_t fmdis: 1; + /** + * Reserved + * type: RO, rst: 00h, rst domain: N/A + */ + uint16_t rsvd15: 5; + } part; +}; +#endif /* __INTEL_DAI_DRIVER_MIC_PRIVACY_REGISTERS_H__ */ diff --git a/drivers/audio/wm8904.c b/drivers/audio/wm8904.c index 8cfe9db900aa7..29d71a220c30b 100644 --- a/drivers/audio/wm8904.c +++ b/drivers/audio/wm8904.c @@ -264,9 +264,9 @@ static int wm8904_in_update( static int wm8904_in_volume_config(const struct device *dev, audio_channel_t channel, int volume) { const uint16_t val = WM8904_REGVAL_IN_VOL(0, volume); - const uint16_t mask = WM8904_REGMASK_IN_MUTE; + const uint16_t mask = WM8904_REGMASK_IN_VOLUME; - return wm8904_in_update(dev, channel, val, mask); + return wm8904_in_update(dev, channel, mask, val); } static int wm8904_in_mute_config(const struct device *dev, audio_channel_t channel, bool mute) @@ -274,7 +274,7 @@ static int wm8904_in_mute_config(const struct device *dev, audio_channel_t chann const uint16_t val = WM8904_REGVAL_IN_VOL(mute, 0); const uint16_t mask = WM8904_REGMASK_IN_MUTE; - return wm8904_in_update(dev, channel, val, mask); + return wm8904_in_update(dev, channel, mask, val); } static int wm8904_route_input(const struct device *dev, audio_channel_t channel, uint32_t input) diff --git a/drivers/audio/wm8904.h b/drivers/audio/wm8904.h index da01fb00df1f7..1224ee7f84bc2 100644 --- a/drivers/audio/wm8904.h +++ b/drivers/audio/wm8904.h @@ -102,7 +102,7 @@ * [1:0] - x_MODE: Input mode */ #define WM8904_REGVAL_INSEL(cm, nin, pin, mode) \ - (((cm) & 0b1) << 6) | (((nin) & 0b11) << 4) + (((cm) & 0b1) << 6) | (((nin) & 0b11) << 4) | (((pin) & 0b11) << 2) #define WM8904_REGMASK_INSEL_CMENA 0b01000000 #define WM8904_REGMASK_INSEL_IP_SEL_N 0b00110000 #define WM8904_REGMASK_INSEL_IP_SEL_P 0b00001100 diff --git a/drivers/auxdisplay/auxdisplay_jhd1313.c b/drivers/auxdisplay/auxdisplay_jhd1313.c index 998a5976cb601..112b114ecfaa4 100644 --- a/drivers/auxdisplay/auxdisplay_jhd1313.c +++ b/drivers/auxdisplay/auxdisplay_jhd1313.c @@ -205,7 +205,7 @@ static int auxdisplay_jhd1313_backlight_set(const struct device *dev, uint8_t co const struct auxdisplay_jhd1313_config *config = dev->config; struct auxdisplay_jhd1313_data *data = dev->data; - if (colour > ARRAY_SIZE(colour_define)) { + if (colour >= ARRAY_SIZE(colour_define)) { LOG_WRN("Selected colour is too high a value"); return -EINVAL; } diff --git a/drivers/bbram/bbram_emul.c b/drivers/bbram/bbram_emul.c index 663e00a66f290..4c4493bc2df66 100644 --- a/drivers/bbram/bbram_emul.c +++ b/drivers/bbram/bbram_emul.c @@ -119,7 +119,7 @@ static int bbram_emul_write(const struct device *dev, size_t offset, size_t size return 0; } -static const struct bbram_driver_api bbram_emul_driver_api = { +static DEVICE_API(bbram, bbram_emul_driver_api) = { .check_invalid = bbram_emul_check_invalid, .check_standby_power = bbram_emul_check_standby_power, .check_power = bbram_emul_check_power, diff --git a/drivers/bbram/bbram_it8xxx2.c b/drivers/bbram/bbram_it8xxx2.c index 1110cf025ce46..7fb250b5e60f8 100644 --- a/drivers/bbram/bbram_it8xxx2.c +++ b/drivers/bbram/bbram_it8xxx2.c @@ -67,7 +67,7 @@ static int bbram_it8xxx2_size(const struct device *dev, size_t *size) return 0; } -static const struct bbram_driver_api bbram_it8xxx2_driver_api = { +static DEVICE_API(bbram, bbram_it8xxx2_driver_api) = { .read = bbram_it8xxx2_read, .write = bbram_it8xxx2_write, .get_size = bbram_it8xxx2_size, diff --git a/drivers/bbram/bbram_microchip_mcp7940n.c b/drivers/bbram/bbram_microchip_mcp7940n.c index ff5b7850576a6..1a6a7d14513e9 100644 --- a/drivers/bbram/bbram_microchip_mcp7940n.c +++ b/drivers/bbram/bbram_microchip_mcp7940n.c @@ -212,7 +212,7 @@ static int microchip_mcp7940n_bbram_write(const struct device *dev, size_t offse return rc; } -static const struct bbram_driver_api microchip_mcp7940n_bbram_api = { +static DEVICE_API(bbram, microchip_mcp7940n_bbram_api) = { .get_size = microchip_mcp7940n_bbram_size, .check_invalid = microchip_mcp7940n_bbram_is_invalid, .check_standby_power = microchip_mcp7940n_bbram_check_standby_power, diff --git a/drivers/bbram/bbram_npcx.c b/drivers/bbram/bbram_npcx.c index ceca04b1d8084..c40a577fabfce 100644 --- a/drivers/bbram/bbram_npcx.c +++ b/drivers/bbram/bbram_npcx.c @@ -90,7 +90,7 @@ static int bbram_npcx_write(const struct device *dev, size_t offset, size_t size return 0; } -static const struct bbram_driver_api bbram_npcx_driver_api = { +static DEVICE_API(bbram, bbram_npcx_driver_api) = { .check_invalid = bbram_npcx_check_invalid, .check_standby_power = bbram_npcx_check_standby_power, .check_power = bbram_npcx_check_power, diff --git a/drivers/bbram/bbram_shell.c b/drivers/bbram/bbram_shell.c index f04549d7470ae..c9024ce0c1b5a 100644 --- a/drivers/bbram/bbram_shell.c +++ b/drivers/bbram/bbram_shell.c @@ -61,7 +61,7 @@ static inline int parse_device(const struct shell *sh, size_t argc, char *argv[] return -EINVAL; } - *bbram_dev = device_get_binding(argv[1]); + *bbram_dev = shell_device_get_binding(argv[1]); if (!*bbram_dev) { shell_error(sh, "Given BBRAM device was not found"); return -ENODEV; diff --git a/drivers/bbram/bbram_stm32.c b/drivers/bbram/bbram_stm32.c index 26acf001a9aed..5eee680e07842 100644 --- a/drivers/bbram/bbram_stm32.c +++ b/drivers/bbram/bbram_stm32.c @@ -94,7 +94,7 @@ static int bbram_stm32_get_size(const struct device *dev, size_t *size) return 0; } -static const struct bbram_driver_api bbram_stm32_driver_api = { +static DEVICE_API(bbram, bbram_stm32_driver_api) = { .read = bbram_stm32_read, .write = bbram_stm32_write, .get_size = bbram_stm32_get_size, diff --git a/drivers/bbram/bbram_xec.c b/drivers/bbram/bbram_xec.c index 56a1cab2b9aa2..ef43ec848a611 100644 --- a/drivers/bbram/bbram_xec.c +++ b/drivers/bbram/bbram_xec.c @@ -72,7 +72,7 @@ static int bbram_xec_write(const struct device *dev, size_t offset, size_t size, return 0; } -static const struct bbram_driver_api bbram_xec_driver_api = { +static DEVICE_API(bbram, bbram_xec_driver_api) = { .check_invalid = bbram_xec_check_invalid, .get_size = bbram_xec_get_size, .read = bbram_xec_read, diff --git a/drivers/bluetooth/hci/CMakeLists.txt b/drivers/bluetooth/hci/CMakeLists.txt index ff734e08a66d2..845c7cd2aa2ec 100644 --- a/drivers/bluetooth/hci/CMakeLists.txt +++ b/drivers/bluetooth/hci/CMakeLists.txt @@ -1,9 +1,33 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_library_sources_ifdef(CONFIG_BT_ESP32 hci_esp32.c) +if (CONFIG_BUILD_ONLY_NO_BLOBS) + message(WARNING " + --------------------------------------------------------------------------- + Building only the Bluetooth driver without binary blobs and patches. + This is only for building (CI) purposes and will not work on a real device. + --------------------------------------------------------------------------- + ") +else() + if(CONFIG_DT_HAS_ESPRESSIF_ESP32_BT_HCI_ENABLED) zephyr_blobs_verify(MODULE hal_espressif REQUIRED) endif() + +if((CONFIG_DT_HAS_ST_HCI_STM32WBA_ENABLED) OR (CONFIG_DT_HAS_ST_HCI_STM32WB0_ENABLED)) + zephyr_blobs_verify(MODULE hal_stm32 REQUIRED) +endif() + +if(CONFIG_DT_HAS_SILABS_BT_HCI_EFR32_ENABLED) + zephyr_blobs_verify(MODULE hal_silabs REQUIRED) +endif() + +if(CONFIG_DT_HAS_INFINEON_CAT1_BLESS_HCI_ENABLED) + zephyr_blobs_verify(MODULE hal_infineon REQUIRED) +endif() + +endif() # CONFIG_BUILD_ONLY_NO_BLOBS + +zephyr_library_sources_ifdef(CONFIG_BT_ESP32 hci_esp32.c) zephyr_library_sources_ifdef(CONFIG_BT_H4 h4.c) zephyr_library_sources_ifdef(CONFIG_BT_H5 h5.c) zephyr_library_sources_ifdef(CONFIG_BT_HCI_IPC ipc.c) @@ -11,22 +35,13 @@ zephyr_library_sources_ifdef(CONFIG_BT_SPI_ZEPHYR spi.c) zephyr_library_sources_ifdef(CONFIG_BT_SPI_BLUENRG hci_spi_st.c) zephyr_library_sources_ifdef(CONFIG_BT_CYW43XX h4_ifx_cyw43xxx.c) zephyr_library_sources_ifdef(CONFIG_BT_CYW208XX hci_ifx_cyw208xx.c) - zephyr_library_sources_ifdef(CONFIG_BT_STM32_IPM ipm_stm32wb.c) zephyr_library_sources_ifdef(CONFIG_BT_STM32WBA hci_stm32wba.c) zephyr_library_sources_ifdef(CONFIG_BT_STM32WB0 hci_stm32wb0.c) -if((CONFIG_DT_HAS_ST_HCI_STM32WBA_ENABLED) OR (CONFIG_DT_HAS_ST_HCI_STM32WB0_ENABLED)) - zephyr_blobs_verify(MODULE hal_stm32 REQUIRED) -endif() zephyr_library_sources_ifdef(CONFIG_BT_USERCHAN userchan.c) zephyr_library_sources_ifdef(CONFIG_BT_SILABS_EFR32 hci_silabs_efr32.c) -if(CONFIG_DT_HAS_SILABS_BT_HCI_EFR32_ENABLED) - zephyr_blobs_verify(MODULE hal_silabs REQUIRED) -endif() +zephyr_library_sources_ifdef(CONFIG_BT_SILABS_SIWX91X hci_silabs_siwx91x.c) zephyr_library_sources_ifdef(CONFIG_BT_PSOC6_BLESS hci_ifx_psoc6_bless.c) -if(CONFIG_DT_HAS_INFINEON_CAT1_BLESS_HCI_ENABLED) - zephyr_blobs_verify(MODULE hal_infineon REQUIRED) -endif() zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUAPP nrf53_support.c) zephyr_library_sources_ifdef(CONFIG_BT_AMBIQ_HCI hci_ambiq.c apollox_blue.c) zephyr_library_sources_ifdef(CONFIG_BT_DA1453X hci_da1453x.c) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index fe78343c3667a..3ac7554347cc8 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -97,7 +97,7 @@ config BT_STM32WBA depends on DT_HAS_ST_HCI_STM32WBA_ENABLED depends on ZEPHYR_HAL_STM32_MODULE_BLOBS select HAS_STM32LIB - select BT_HCI_SET_PUBLIC_ADDR + select BT_HCI_SET_PUBLIC_ADDR if !BT_HCI_RAW help ST STM32WBA HCI Bluetooth interface @@ -116,20 +116,38 @@ config BT_STM32WB0 ST STM32WB0 HCI Bluetooth interface config BT_SILABS_EFR32 - bool + bool "Silabs EFR32 HCI driver" default y depends on DT_HAS_SILABS_BT_HCI_EFR32_ENABLED - depends on ZEPHYR_HAL_SILABS_MODULE_BLOBS + depends on ZEPHYR_HAL_SILABS_MODULE_BLOBS || BUILD_ONLY_NO_BLOBS depends on !PM || SOC_GECKO_PM_BACKEND_PMGR select SOC_GECKO_USE_RAIL - select ENTROPY_GENERATOR select MBEDTLS select MBEDTLS_PSA_CRYPTO_C select MBEDTLS_ENTROPY_C + select HAS_BT_CTLR + select BT_CTLR_PHY_UPDATE_SUPPORT + select BT_CTLR_PER_INIT_FEAT_XCHG_SUPPORT + select BT_CTLR_DATA_LEN_UPDATE_SUPPORT + select BT_CTLR_EXT_REJ_IND_SUPPORT + select BT_CTLR_CHAN_SEL_2_SUPPORT + select BT_CTLR_CONN_RSSI_SUPPORT + select BT_CTLR_ADV_EXT_SUPPORT help Use Silicon Labs binary Bluetooth library to connect to the controller. +source "drivers/bluetooth/hci/Kconfig.silabs" + +config BT_SILABS_SIWX91X + bool "Silabs SiWx91x Bluetooth interface" + default y + depends on DT_HAS_SILABS_SIWX91X_BT_HCI_ENABLED + select WISECONNECT_NETWORK_STACK + select ENTROPY_GENERATOR + help + Use Silicon Labs Wiseconnect 3.x Bluetooth library to connect to the controller. + config BT_USERCHAN bool depends on (BOARD_NATIVE_POSIX || BOARD_NATIVE_SIM) @@ -146,8 +164,8 @@ config BT_ESP32 bool default y depends on DT_HAS_ESPRESSIF_ESP32_BT_HCI_ENABLED - depends on ZEPHYR_HAL_ESPRESSIF_MODULE_BLOBS - select ENTROPY_GENERATOR + depends on ZEPHYR_HAL_ESPRESSIF_MODULE_BLOBS || BUILD_ONLY_NO_BLOBS + select HAS_BT_CTLR help Espressif HCI bluetooth interface @@ -287,18 +305,10 @@ config BT_DRV_RX_STACK_SIZE default BT_RX_STACK_SIZE if (BT_H4 || BT_HCI_RAW_H4) default BT_STM32_IPM_RX_STACK_SIZE if BT_STM32_IPM default HCI_NXP_RX_STACK_SIZE if HCI_NXP_RX_THREAD - default 256 + default 512 help Stack size for the HCI driver's RX thread. -config BT_SILABS_EFR32_BUFFER_MEMORY - int "Silicon Labs Bluetooth Library memory buffer size" - depends on BT_SILABS_EFR32 - default 6144 - help - Select the size of allocated memory buffer for the Silicon Labs - Bluetooth Library. - config BT_H4_NXP_CTLR bool "NXP Bluetooth Controller" select GPIO diff --git a/drivers/bluetooth/hci/Kconfig.esp32 b/drivers/bluetooth/hci/Kconfig.esp32 index ad7a53d5de36b..294b6a1cd84aa 100644 --- a/drivers/bluetooth/hci/Kconfig.esp32 +++ b/drivers/bluetooth/hci/Kconfig.esp32 @@ -2,16 +2,19 @@ if BT_ESP32 +config HEAP_MEM_POOL_ADD_SIZE_ESP_BT + int + default 25600 if ESP_BT_HEAP_SYSTEM + default 0 + help + Make sure there is a minimal heap available for BT driver. + choice ESP_BT_HEAP prompt "Bluetooth adapter heap in use" - default ESP_BT_HEAP_RUNTIME - - config ESP_BT_HEAP_RUNTIME - bool "Bluetooth adapter use ESP runtime heap" - depends on ESP_HEAP_RUNTIME + default ESP_BT_HEAP_SYSTEM config ESP_BT_HEAP_SYSTEM - bool "Bluetooth adapter use system heap" + bool "Bluetooth adapter use the kernel mempool heap (k_malloc)" endchoice # ESP_BT_HEAP diff --git a/drivers/bluetooth/hci/Kconfig.nxp b/drivers/bluetooth/hci/Kconfig.nxp index b91dfbbe488be..9eaea2849b033 100644 --- a/drivers/bluetooth/hci/Kconfig.nxp +++ b/drivers/bluetooth/hci/Kconfig.nxp @@ -48,7 +48,10 @@ endif if BT_NXP -config BT_DIS_MANUF +config BT_DIS_MANUF_NAME + default y + +config BT_DIS_MANUF_NAME_STR default "NXP" config BT_HCI_ACL_FLOW_CONTROL @@ -69,7 +72,7 @@ endif # BT_NXP if BT_H4_NXP_CTLR config BT_NXP_NW612 - bool "NXP IW612 Chipset" + bool "NW612 firmware for NXP IW612 Chipset" help NXP IW612 Chipset supports Wi-Fi? 802.11a/b/g/n/ac/ax + Bluetooth? 5.3 BR/EDR/LE + IEEE802.1.5.4 up to 601 Mbps data rate on Wi-Fi? and 2Mbps diff --git a/drivers/bluetooth/hci/Kconfig.silabs b/drivers/bluetooth/hci/Kconfig.silabs new file mode 100644 index 0000000000000..482131c51f794 --- /dev/null +++ b/drivers/bluetooth/hci/Kconfig.silabs @@ -0,0 +1,54 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# +# SPDX-License-Identifier: Apache-2.0 +menu "EFR32 Bluetooth Controller Configuration" + depends on BT_SILABS_EFR32 + +config BT_SILABS_EFR32_HCI_VS + bool "Silicon Labs vendor specific HCI extensions" + help + Enable Silicon Labs vendor specific HCI extensions. + +config BT_SILABS_EFR32_BUFFER_MEMORY + int "Memory buffer size" + default 6144 + help + Select the size of allocated memory buffer for the Silicon Labs + Bluetooth Library. If set too low the capacity of the link layer may + suffer. + +config BT_SILABS_EFR32_USER_ADVERTISERS + int "User advertisement sets" + default 1 + help + Amount of advertisement sets reserved for application. + +config BT_SILABS_EFR32_ACCEPT_LIST_SIZE + int "Accept list size" + default 1 + help + Accept list size. + +config BT_SILABS_EFR32_COMPLETED_PACKETS_THRESHOLD + int "Completed packet reporting threshold" + default 1 + help + Completed packet reporting threshold value. + +config BT_SILABS_EFR32_COMPLETED_PACKETS_TIMEOUT + int "Completed packet report event timeout" + default 3 + help + Completed packet report event timeout. + +config BT_SILABS_EFR32_ACCEPT_LINK_LAYER_STACK_SIZE + int "Link layer stack size" + default 1024 + help + Link layer stack size. + +config BT_SILABS_EFR32_LL_THREAD_PRIO + # Hidden option for Co-Operative Link Layer thread priority + def_int 0 + +endmenu diff --git a/drivers/bluetooth/hci/h4_ifx_cyw43xxx.c b/drivers/bluetooth/hci/h4_ifx_cyw43xxx.c index ae98a8e51e2d6..6bc563fb9f202 100644 --- a/drivers/bluetooth/hci/h4_ifx_cyw43xxx.c +++ b/drivers/bluetooth/hci/h4_ifx_cyw43xxx.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/bluetooth/hci/hci_da1453x.c b/drivers/bluetooth/hci/hci_da1453x.c index 668dd8aaa18f1..8e63e377cb718 100644 --- a/drivers/bluetooth/hci/hci_da1453x.c +++ b/drivers/bluetooth/hci/hci_da1453x.c @@ -41,7 +41,7 @@ int bt_hci_transport_setup(const struct device *h4) k_sleep(K_MSEC(DT_INST_PROP_OR(0, reset_assert_duration_ms, 0))); /* Release the DA1453x from reset */ - err = gpio_pin_set_dt(&bt_reset, 0); + err = gpio_pin_configure_dt(&bt_reset, GPIO_OUTPUT_INACTIVE); if (err) { return err; } diff --git a/drivers/bluetooth/hci/hci_nxp.c b/drivers/bluetooth/hci/hci_nxp.c index 366325539f03b..ad2dbfb9ec7a6 100644 --- a/drivers/bluetooth/hci/hci_nxp.c +++ b/drivers/bluetooth/hci/hci_nxp.c @@ -39,12 +39,6 @@ struct hci_data { #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL LOG_MODULE_REGISTER(bt_driver); -#define HCI_IRQ_N DT_INST_IRQ_BY_NAME(0, hci_int, irq) -#define HCI_IRQ_P DT_INST_IRQ_BY_NAME(0, hci_int, priority) -#if DT_INST_IRQ_HAS_NAME(0, wakeup_int) -#define HCI_WAKEUP_IRQ_N DT_INST_IRQ_BY_NAME(0, wakeup_int, irq) -#define HCI_WAKEUP_IRQ_P DT_INST_IRQ_BY_NAME(0, wakeup_int, priority) -#endif /* Vendor specific commands */ #define HCI_CMD_STORE_BT_CAL_DATA_OCF 0x61U #define HCI_CMD_STORE_BT_CAL_DATA_PARAM_LENGTH 32U @@ -81,9 +75,6 @@ LOG_MODULE_REGISTER(bt_driver); /* Public prototypes */ /* -------------------------------------------------------------------------- */ -extern int32_t ble_hci_handler(void); -extern int32_t ble_wakeup_done_handler(void); - /* -------------------------------------------------------------------------- */ /* Private functions */ /* -------------------------------------------------------------------------- */ @@ -546,18 +537,6 @@ static int bt_nxp_init(const struct device *dev) ARG_UNUSED(dev); - /* HCI Interrupt */ - IRQ_CONNECT(HCI_IRQ_N, HCI_IRQ_P, ble_hci_handler, 0, 0); - irq_enable(HCI_IRQ_N); -#if DT_INST_IRQ_HAS_NAME(0, wakeup_int) - /* Wake up done interrupt */ - IRQ_CONNECT(HCI_WAKEUP_IRQ_N, HCI_WAKEUP_IRQ_P, ble_wakeup_done_handler, 0, 0); - irq_enable(HCI_WAKEUP_IRQ_N); -#endif -#if (DT_INST_PROP(0, wakeup_source)) && CONFIG_PM - EnableDeepSleepIRQ(HCI_IRQ_N); -#endif - do { status = PLATFORM_InitBle(); if (status < 0) { diff --git a/drivers/bluetooth/hci/hci_silabs_efr32.c b/drivers/bluetooth/hci/hci_silabs_efr32.c index 49d69098db32f..c528b3b69103b 100644 --- a/drivers/bluetooth/hci/hci_silabs_efr32.c +++ b/drivers/bluetooth/hci/hci_silabs_efr32.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -21,27 +22,37 @@ struct hci_data { bt_hci_recv_t recv; }; -#define SL_BT_CONFIG_ACCEPT_LIST_SIZE 1 -#define SL_BT_CONFIG_MAX_CONNECTIONS 1 -#define SL_BT_CONFIG_USER_ADVERTISERS 1 -#define SL_BT_CONTROLLER_BUFFER_MEMORY CONFIG_BT_SILABS_EFR32_BUFFER_MEMORY -#define SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX CONFIG_BT_BUF_ACL_TX_COUNT -#define SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD 1 -#define SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT 3 -#define SL_BT_SILABS_LL_STACK_SIZE 1024 +#if defined(CONFIG_BT_MAX_CONN) +#define MAX_CONN CONFIG_BT_MAX_CONN +#else +#define MAX_CONN 0 +#endif + +#if defined(CONFIG_BT_CTLR_RL_SIZE) +#define CTLR_RL_SIZE CONFIG_BT_CTLR_RL_SIZE +#else +#define CTLR_RL_SIZE 0 +#endif -static K_KERNEL_STACK_DEFINE(slz_ll_stack, SL_BT_SILABS_LL_STACK_SIZE); +static K_KERNEL_STACK_DEFINE(slz_ll_stack, CONFIG_BT_SILABS_EFR32_ACCEPT_LINK_LAYER_STACK_SIZE); static struct k_thread slz_ll_thread; +static K_KERNEL_STACK_DEFINE(slz_rx_stack, CONFIG_BT_DRV_RX_STACK_SIZE); +static struct k_thread slz_rx_thread; + /* Semaphore for Link Layer */ K_SEM_DEFINE(slz_ll_sem, 0, 1); /* Events mask for Link Layer */ static atomic_t sli_btctrl_events; +/* FIFO for received HCI packets */ +static struct k_fifo slz_rx_fifo; + /* FIXME: these functions should come from the SiSDK headers! */ void BTLE_LL_EventRaise(uint32_t events); void BTLE_LL_Process(uint32_t events); +int16_t BTLE_LL_SetMaxPower(int16_t power); bool sli_pending_btctrl_events(void); RAIL_Handle_t BTLE_LL_GetRadioHandle(void); @@ -61,6 +72,82 @@ void rail_isr_installer(void) IRQ_CONNECT(AGC_IRQn, 0, AGC_IRQHandler, NULL, 0); } +static bool slz_is_evt_discardable(const struct bt_hci_evt_hdr *hdr, const uint8_t *params, + int16_t params_len) +{ + switch (hdr->evt) { + case BT_HCI_EVT_LE_META_EVENT: { + struct bt_hci_evt_le_meta_event *meta_evt = (void *)params; + + if (params_len < sizeof(*meta_evt)) { + return false; + } + params += sizeof(*meta_evt); + params_len -= sizeof(*meta_evt); + + switch (meta_evt->subevent) { + case BT_HCI_EVT_LE_ADVERTISING_REPORT: + return true; + case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT: { + struct bt_hci_evt_le_ext_advertising_report *evt = (void *)params; + + if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) { + return false; + } + + if (params_len < sizeof(*evt) + sizeof(*evt->adv_info)) { + return false; + } + + /* Never discard if the event could be part of a multi-part report event, + * because the missing part could confuse the BT host. + */ + return (evt->num_reports == 1) && + ((evt->adv_info[0].evt_type & BT_HCI_LE_ADV_EVT_TYPE_LEGACY) != 0); + } + default: + return false; + } + } + default: + return false; + } +} + +static struct net_buf *slz_bt_recv_evt(const uint8_t *data, const int16_t len) +{ + struct net_buf *buf; + bool discardable; + const struct bt_hci_evt_hdr *hdr = (void *)data; + const uint8_t *params = &data[sizeof(*hdr)]; + const int16_t params_len = len - sizeof(*hdr); + + if (len < sizeof(*hdr)) { + LOG_ERR("Event header is missing"); + return NULL; + } + + discardable = slz_is_evt_discardable(hdr, params, params_len); + buf = bt_buf_get_evt(hdr->evt, discardable, discardable ? K_NO_WAIT : K_FOREVER); + if (!buf) { + LOG_DBG("Discardable buffer pool full, ignoring event"); + return buf; + } + + net_buf_add_mem(buf, data, len); + + return buf; +} + +static struct net_buf *slz_bt_recv_acl(const uint8_t *data, const int16_t len) +{ + struct net_buf *buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER); + + net_buf_add_mem(buf, data, len); + + return buf; +} + /** * @brief Transmit HCI message using the currently used transport layer. * The HCI calls this function to transmit a full HCI message. @@ -70,33 +157,36 @@ void rail_isr_installer(void) */ uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len) { - const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); - struct hci_data *hci = dev->data; struct net_buf *buf; - uint8_t packet_type = data[0]; - uint8_t event_code; + uint8_t packet_type; LOG_HEXDUMP_DBG(data, len, "host packet data:"); + if (len < 1) { + LOG_ERR("HCI packet type is missing"); + return -EINVAL; + } + + packet_type = data[0]; /* drop packet type from the frame buffer - it is no longer needed */ - data = &data[1]; + data += 1; len -= 1; switch (packet_type) { case BT_HCI_H4_EVT: - event_code = data[0]; - buf = bt_buf_get_evt(event_code, false, K_FOREVER); + buf = slz_bt_recv_evt(data, len); break; case BT_HCI_H4_ACL: - buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER); + buf = slz_bt_recv_acl(data, len); break; default: LOG_ERR("Unknown HCI type: %d", packet_type); return -EINVAL; } - net_buf_add_mem(buf, data, len); - hci->recv(dev, buf); + if (buf) { + k_fifo_put(&slz_rx_fifo, buf); + } sl_btctrl_hci_transmit_complete(0); @@ -137,7 +227,7 @@ static int slz_bt_send(const struct device *dev, struct net_buf *buf) * or an HCI event to pass upstairs. The BTLE_LL_Process function call will * take care of all of them, and add HCI events to the HCI queue when applicable. */ -static void slz_thread_func(void *p1, void *p2, void *p3) +static void slz_ll_thread_func(void *p1, void *p2, void *p3) { ARG_UNUSED(p1); ARG_UNUSED(p2); @@ -152,17 +242,52 @@ static void slz_thread_func(void *p1, void *p2, void *p3) } } +static void slz_rx_thread_func(void *p1, void *p2, void *p3) +{ + const struct device *dev = p1; + struct hci_data *hci = dev->data; + + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + while (true) { + struct net_buf *buf = k_fifo_get(&slz_rx_fifo, K_FOREVER); + + hci->recv(dev, buf); + } +} + +static void slz_set_tx_power(int16_t max_power_dbm) +{ + const int16_t max_power_cbm = max_power_dbm * 10; + const int16_t actual_max_power_cbm = BTLE_LL_SetMaxPower(max_power_cbm); + const int16_t actual_max_power_dbm = DIV_ROUND_CLOSEST(actual_max_power_cbm, 10); + + if (actual_max_power_dbm != max_power_dbm) { + LOG_WRN("Unable to set max TX power to %d dBm, actual max is %d dBm", max_power_dbm, + actual_max_power_dbm); + } +} + static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv) { struct hci_data *hci = dev->data; int ret; - /* Start RX thread */ - k_thread_create(&slz_ll_thread, slz_ll_stack, - K_KERNEL_STACK_SIZEOF(slz_ll_stack), - slz_thread_func, NULL, NULL, NULL, - K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, - K_NO_WAIT); + BUILD_ASSERT(CONFIG_NUM_METAIRQ_PRIORITIES > 0, + "Config NUM_METAIRQ_PRIORITIES must be greater than 0"); + BUILD_ASSERT(CONFIG_BT_SILABS_EFR32_LL_THREAD_PRIO < CONFIG_NUM_METAIRQ_PRIORITIES, + "Config BT_SILABS_EFR32_LL_THREAD_PRIO must be a meta-IRQ priority"); + + k_fifo_init(&slz_rx_fifo); + + k_thread_create(&slz_ll_thread, slz_ll_stack, K_KERNEL_STACK_SIZEOF(slz_ll_stack), + slz_ll_thread_func, NULL, NULL, NULL, + K_PRIO_COOP(CONFIG_BT_SILABS_EFR32_LL_THREAD_PRIO), 0, K_NO_WAIT); + + k_thread_create(&slz_rx_thread, slz_rx_stack, K_KERNEL_STACK_SIZEOF(slz_rx_stack), + slz_rx_thread_func, (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); rail_isr_installer(); sl_rail_util_pa_init(); @@ -172,13 +297,18 @@ static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv) sl_btctrl_disable_coded_phy(); /* sl_btctrl_init_mem returns the number of memory buffers allocated */ - ret = sl_btctrl_init_mem(SL_BT_CONTROLLER_BUFFER_MEMORY); + ret = sl_btctrl_init_mem(CONFIG_BT_SILABS_EFR32_BUFFER_MEMORY); if (!ret) { LOG_ERR("Failed to allocate memory %d", ret); return -ENOMEM; } - sl_btctrl_configure_le_buffer_size(SL_BT_CONTROLLER_LE_BUFFER_SIZE_MAX); + sl_btctrl_configure_le_buffer_size(CONFIG_BT_BUF_ACL_TX_COUNT); + + if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) { + sl_btctrl_allocate_resolving_list_memory(CTLR_RL_SIZE); + sl_btctrl_init_privacy(); + } ret = sl_btctrl_init_ll(); if (ret) { @@ -186,24 +316,28 @@ static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv) goto deinit; } + slz_set_tx_power(CONFIG_BT_CTLR_TX_PWR_ANTENNA); + sl_btctrl_init_adv(); sl_btctrl_init_scan(); sl_btctrl_init_conn(); sl_btctrl_init_phy(); - sl_btctrl_init_adv_ext(); - sl_btctrl_init_scan_ext(); - ret = sl_btctrl_init_basic(SL_BT_CONFIG_MAX_CONNECTIONS, - SL_BT_CONFIG_USER_ADVERTISERS, - SL_BT_CONFIG_ACCEPT_LIST_SIZE); + if (IS_ENABLED(CONFIG_BT_EXT_ADV)) { + sl_btctrl_init_adv_ext(); + sl_btctrl_init_scan_ext(); + } + + ret = sl_btctrl_init_basic(MAX_CONN, CONFIG_BT_SILABS_EFR32_USER_ADVERTISERS + MAX_CONN, + CONFIG_BT_SILABS_EFR32_ACCEPT_LIST_SIZE); if (ret) { LOG_ERR("Failed to initialize the controller %d", ret); goto deinit; } sl_btctrl_configure_completed_packets_reporting( - SL_BT_CONTROLLER_COMPLETED_PACKETS_THRESHOLD, - SL_BT_CONTROLLER_COMPLETED_PACKETS_EVENTS_TIMEOUT); + CONFIG_BT_SILABS_EFR32_COMPLETED_PACKETS_THRESHOLD, + CONFIG_BT_SILABS_EFR32_COMPLETED_PACKETS_TIMEOUT); sl_bthci_init_upper(); sl_btctrl_hci_parser_init_default(); @@ -211,8 +345,11 @@ static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv) sl_btctrl_hci_parser_init_adv(); sl_btctrl_hci_parser_init_phy(); -#ifdef CONFIG_PM - { + if (IS_ENABLED(CONFIG_BT_SILABS_EFR32_HCI_VS)) { + sl_bthci_init_vs(); + } + + if (IS_ENABLED(CONFIG_PM)) { RAIL_ConfigSleep(BTLE_LL_GetRadioHandle(), RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED); RAIL_Status_t status = RAIL_InitPowerManager(); @@ -223,7 +360,10 @@ static int slz_bt_open(const struct device *dev, bt_hci_recv_t recv) goto deinit; } } -#endif + + if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) { + sl_btctrl_hci_parser_init_privacy(); + } hci->recv = recv; diff --git a/drivers/bluetooth/hci/hci_silabs_siwx91x.c b/drivers/bluetooth/hci/hci_silabs_siwx91x.c new file mode 100644 index 0000000000000..3d40a38208a6c --- /dev/null +++ b/drivers/bluetooth/hci/hci_silabs_siwx91x.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define DT_DRV_COMPAT silabs_siwx91x_bt_hci +#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL +#include +LOG_MODULE_REGISTER(bt_hci_driver_siwg917); + +#include "rsi_ble.h" + +static void siwx91x_bt_resp_rcvd(uint16_t status, rsi_ble_event_rcp_rcvd_info_t *resp_buf); + +struct hci_data { + bt_hci_recv_t recv; + rsi_data_packet_t rsi_data_packet; +}; + +static int siwx91x_bt_open(const struct device *dev, bt_hci_recv_t recv) +{ + struct hci_data *hci = dev->data; + int status = rsi_ble_enhanced_gap_extended_register_callbacks(RSI_BLE_ON_RCP_EVENT, + (void *)siwx91x_bt_resp_rcvd); + + if (!status) { + hci->recv = recv; + } + return status ? -EIO : 0; +} + +static int siwx91x_bt_send(const struct device *dev, struct net_buf *buf) +{ + struct hci_data *hci = dev->data; + int sc = -EOVERFLOW; + uint8_t packet_type = BT_HCI_H4_NONE; + + switch (bt_buf_get_type(buf)) { + case BT_BUF_ACL_OUT: + packet_type = BT_HCI_H4_ACL; + break; + case BT_BUF_CMD: + packet_type = BT_HCI_H4_CMD; + break; + default: + sc = -EINVAL; + break; + } + + if ((packet_type != BT_HCI_H4_NONE) && (buf->len < sizeof(hci->rsi_data_packet.data))) { + net_buf_push_u8(buf, packet_type); + memcpy(&hci->rsi_data_packet, buf->data, buf->len); + sc = rsi_bt_driver_send_cmd(RSI_BLE_REQ_HCI_RAW, &hci->rsi_data_packet, NULL); + /* TODO SILABS ZEPHYR Convert to errno. A common function from rsi/sl_status should + * be introduced + */ + if (sc) { + LOG_ERR("BT command send failure: %d", sc); + sc = -EIO; + } + } + net_buf_unref(buf); + return sc; +} + +static void siwx91x_bt_resp_rcvd(uint16_t status, rsi_ble_event_rcp_rcvd_info_t *resp_buf) +{ + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct hci_data *hci = dev->data; + uint8_t packet_type = BT_HCI_H4_NONE; + size_t len = 0; + struct net_buf *buf = NULL; + + /* TODO SILABS ZEPHYR This horror expression is from the WiseConnect from the HCI example... + * No workaround have been found until now. + */ + memcpy(&packet_type, (resp_buf->data - 12), 1); + switch (packet_type) { + case BT_HCI_H4_EVT: { + struct bt_hci_evt_hdr *hdr = (void *)resp_buf->data; + + len = hdr->len + sizeof(*hdr); + buf = bt_buf_get_evt(hdr->evt, false, K_FOREVER); + break; + } + case BT_HCI_H4_ACL: { + struct bt_hci_acl_hdr *hdr = (void *)resp_buf->data; + + len = hdr->len + sizeof(*hdr); + buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER); + break; + } + default: + LOG_ERR("Unknown/Unhandled HCI type: %d", packet_type); + break; + } + + if (buf && (len <= net_buf_tailroom(buf))) { + net_buf_add_mem(buf, resp_buf->data, len); + hci->recv(dev, buf); + } +} + +static DEVICE_API(bt_hci, siwx91x_api) = { + .open = siwx91x_bt_open, + .send = siwx91x_bt_send, +}; + +#define HCI_DEVICE_INIT(inst) \ + static struct hci_data hci_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &siwx91x_api) + +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 6ef1992923526..3ce62548ea01d 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -377,7 +377,7 @@ static int bt_spi_open(const struct device *dev, bt_hci_recv_t recv) struct bt_spi_data *hci = dev->data; int err; - /* Configure RST pin and hold BLE in Reset */ + /* Configure RST pin and hold Bluetooth LE in Reset */ err = gpio_pin_configure_dt(&rst_gpio, GPIO_OUTPUT_ACTIVE); if (err) { return err; @@ -403,7 +403,7 @@ static int bt_spi_open(const struct device *dev, bt_hci_recv_t recv) hci->recv = recv; - /* Take BLE out of reset */ + /* Take Bluetooth LE out of reset */ k_sleep(K_MSEC(DT_INST_PROP_OR(0, reset_assert_duration_ms, 0))); gpio_pin_set_dt(&rst_gpio, 0); @@ -413,6 +413,7 @@ static int bt_spi_open(const struct device *dev, bt_hci_recv_t recv) bt_spi_rx_thread, (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0, K_NO_WAIT); + k_thread_name_set(&spi_rx_thread_data, "bt_spi_rx_thread"); /* Device will let us know when it's ready */ k_sem_take(&sem_initialised, K_FOREVER); diff --git a/drivers/cache/CMakeLists.txt b/drivers/cache/CMakeLists.txt index a10d98ce68fee..74c3b983026f7 100644 --- a/drivers/cache/CMakeLists.txt +++ b/drivers/cache/CMakeLists.txt @@ -9,3 +9,4 @@ zephyr_library_sources_ifdef(CONFIG_CACHE_ASPEED cache_aspeed.c) zephyr_library_sources_ifdef(CONFIG_CACHE_ANDES cache_andes.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE cache_handlers.c) zephyr_library_sources_ifdef(CONFIG_CACHE_NRF_CACHE cache_nrf.c) +zephyr_library_sources_ifdef(CONFIG_CACHE_NXP_XCACHE cache_nxp_xcache.c) diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index be3fc2ce19365..8bae7f3520243 100644 --- a/drivers/cache/Kconfig +++ b/drivers/cache/Kconfig @@ -21,5 +21,6 @@ comment "Device Drivers" source "drivers/cache/Kconfig.aspeed" source "drivers/cache/Kconfig.nrf" source "drivers/cache/Kconfig.andes" +source "drivers/cache/Kconfig.nxp_xcache" endif # CACHE diff --git a/drivers/cache/Kconfig.andes b/drivers/cache/Kconfig.andes index 8c566ab24cd66..50b49d5c434d0 100644 --- a/drivers/cache/Kconfig.andes +++ b/drivers/cache/Kconfig.andes @@ -2,15 +2,11 @@ # # Copyright (c) 2024 ANDES Technology Inc. -DT_COMPAT_ANDESTECH_L2C := andestech,l2c - config CACHE_ANDES bool "ANDES external cache driver" default y depends on SOC_FAMILY_ANDES_V5 select CACHE_HAS_DRIVER - imply DCACHE_LINE_SIZE_DETECT - imply ICACHE_LINE_SIZE_DETECT help This option enables the CACHE driver for ANDES V5 series SOC. @@ -18,7 +14,7 @@ if CACHE_ANDES config L2C_INCLUSIVE_POLICY bool - depends on $(dt_compat_enabled,$(DT_COMPAT_ANDESTECH_L2C)) + depends on DT_HAS_ANDESTECH_L2C_ENABLED help When L2 cache is inclusive of L1, CPU only needs to perform operations on L2 cache, instead of on both L1 and L2 caches. diff --git a/drivers/cache/Kconfig.nxp_xcache b/drivers/cache/Kconfig.nxp_xcache new file mode 100644 index 0000000000000..f9844793e307f --- /dev/null +++ b/drivers/cache/Kconfig.nxp_xcache @@ -0,0 +1,10 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config CACHE_NXP_XCACHE + bool "NXP external cache driver for xcache controller" + default y + select CACHE_HAS_DRIVER + depends on HAS_MCUX_XCACHE + help + This option enables the XCACHE driver for NXP SOC's. diff --git a/drivers/cache/cache_andes.c b/drivers/cache/cache_andes.c index 8008013a86d60..4b8cd66b87dfa 100644 --- a/drivers/cache/cache_andes.c +++ b/drivers/cache/cache_andes.c @@ -60,6 +60,7 @@ struct cache_config { uint32_t data_line_size; uint32_t l2_cache_size; uint32_t l2_cache_inclusive; + bool is_cctl_supported; }; static struct cache_config cache_cfg; @@ -285,6 +286,10 @@ int cache_data_invd_all(void) { unsigned long ret = 0; + if (!cache_cfg.is_cctl_supported) { + return -ENOTSUP; + } + K_SPINLOCK(&lock) { if (cache_cfg.l2_cache_inclusive) { ret |= nds_l2_cache_all(K_CACHE_WB); @@ -304,6 +309,10 @@ int cache_data_invd_range(void *addr, size_t size) { unsigned long ret = 0; + if (!cache_cfg.is_cctl_supported) { + return -ENOTSUP; + } + K_SPINLOCK(&lock) { if (cache_cfg.l2_cache_inclusive) { ret |= nds_l2_cache_range(addr, size, K_CACHE_INVD); @@ -320,6 +329,10 @@ int cache_instr_invd_all(void) { unsigned long ret = 0; + if (!cache_cfg.is_cctl_supported) { + return -ENOTSUP; + } + if (IS_ENABLED(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1)) { return -ENOTSUP; } @@ -353,6 +366,10 @@ int cache_instr_invd_range(void *addr, size_t size) { unsigned long ret = 0; + if (!cache_cfg.is_cctl_supported) { + return -ENOTSUP; + } + if (IS_ENABLED(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1)) { ARG_UNUSED(addr); ARG_UNUSED(size); @@ -371,6 +388,10 @@ int cache_data_flush_all(void) { unsigned long ret = 0; + if (!cache_cfg.is_cctl_supported) { + return -ENOTSUP; + } + K_SPINLOCK(&lock) { if (cache_cfg.l2_cache_inclusive) { ret |= nds_l2_cache_all(K_CACHE_WB); @@ -387,6 +408,10 @@ int cache_data_flush_range(void *addr, size_t size) { unsigned long ret = 0; + if (!cache_cfg.is_cctl_supported) { + return -ENOTSUP; + } + K_SPINLOCK(&lock) { if (cache_cfg.l2_cache_inclusive) { ret |= nds_l2_cache_range(addr, size, K_CACHE_WB); @@ -403,6 +428,10 @@ int cache_data_flush_and_invd_all(void) { unsigned long ret = 0; + if (!cache_cfg.is_cctl_supported) { + return -ENOTSUP; + } + K_SPINLOCK(&lock) { if (cache_cfg.l2_cache_size) { if (cache_cfg.l2_cache_inclusive) { @@ -424,6 +453,10 @@ int cache_data_flush_and_invd_range(void *addr, size_t size) { unsigned long ret = 0; + if (!cache_cfg.is_cctl_supported) { + return -ENOTSUP; + } + K_SPINLOCK(&lock) { if (cache_cfg.l2_cache_size) { if (cache_cfg.l2_cache_inclusive) { @@ -503,7 +536,7 @@ static int andes_cache_init(void) cache_cfg.instr_line_size = CONFIG_ICACHE_LINE_SIZE; #elif DT_NODE_HAS_PROP(DT_PATH(cpus, cpu_0), i_cache_line_size) cache_cfg.instr_line_size = - DT_PROP(DT_PATH(cpus, cpu_0), "i_cache_line_size"); + DT_PROP(DT_PATH(cpus, cpu_0), i_cache_line_size); #else LOG_ERR("Please specific the i-cache-line-size " "CPU0 property of the DT"); @@ -527,15 +560,15 @@ static int andes_cache_init(void) cache_cfg.data_line_size = CONFIG_DCACHE_LINE_SIZE; #elif DT_NODE_HAS_PROP(DT_PATH(cpus, cpu_0), d_cache_line_size) cache_cfg.data_line_size = - DT_PROP(DT_PATH(cpus, cpu_0), "d_cache_line_size"); + DT_PROP(DT_PATH(cpus, cpu_0), d_cache_line_size); #else LOG_ERR("Please specific the d-cache-line-size " "CPU0 property of the DT"); #endif /* defined(CONFIG_DCACHE_LINE_SIZE_DETECT) */ } - if (!(csr_read(NDS_MMSC_CFG) & MMSC_CFG_CCTLCSR)) { - LOG_ERR("Platform doesn't support I/D cache operation"); + if (csr_read(NDS_MMSC_CFG) & MMSC_CFG_CCTLCSR) { + cache_cfg.is_cctl_supported = true; } if (csr_read(NDS_MMSC_CFG) & MMSC_CFG_VCCTL_2) { @@ -544,7 +577,7 @@ static int andes_cache_init(void) } } - cache_cfg.l2_cache_size = nds_l2_cache_init(); + cache_cfg.l2_cache_size = nds_l2_cache_init(cache_cfg.data_line_size); cache_cfg.l2_cache_inclusive = nds_l2_cache_is_inclusive(); return 0; diff --git a/drivers/cache/cache_andes_l2.h b/drivers/cache/cache_andes_l2.h index 962bf837fd8c6..fbf4144300715 100644 --- a/drivers/cache/cache_andes_l2.h +++ b/drivers/cache/cache_andes_l2.h @@ -54,6 +54,7 @@ struct nds_l2_cache_config { uint32_t status_offset; uint16_t status_shift; uint8_t version; + uint8_t line_size; }; static struct nds_l2_cache_config l2_cache_cfg; @@ -78,14 +79,16 @@ static ALWAYS_INLINE void nds_l2_cache_wait_status(uint8_t hart_id) static ALWAYS_INLINE int nds_l2_cache_all(int op) { - /* L2 cache fixed to 64 byte cache line size and 16 way */ - const unsigned long line_size = 64, ways = 16; - unsigned long sets, index, cmd; + unsigned long ways, sets, index, cmd; uint8_t hart_id; unsigned long status = csr_read(mstatus); if (!l2_cache_cfg.size) { return -ENOTSUP; + } else if (l2_cache_cfg.size >= 128 * 1024) { + ways = 16; + } else { + ways = 8; } if (csr_read(NDS_MMSC_CFG) & MMSC_CFG_VCCTL_2) { @@ -118,14 +121,14 @@ static ALWAYS_INLINE int nds_l2_cache_all(int op) /* Wait L2 CCTL Commands finished */ nds_l2_cache_wait_status(hart_id); } else { - sets = l2_cache_cfg.size / (ways * line_size); + sets = l2_cache_cfg.size / (ways * l2_cache_cfg.line_size); /* Invalidate all cache line by each way and each set */ for (int j = 0; j < ways; j++) { /* Index of way */ index = j << L2C_CCTLACC_WAY_SHIFT; for (int i = 0; i < sets; i++) { /* Index of set */ - index += line_size; + index += l2_cache_cfg.line_size; /* Invalidate each cache line */ sys_write32(index, L2C_CCTLACC(hart_id)); @@ -142,7 +145,6 @@ static ALWAYS_INLINE int nds_l2_cache_all(int op) static ALWAYS_INLINE int nds_l2_cache_range(void *addr, size_t size, int op) { - const unsigned long line_size = 64; unsigned long last_byte, align_addr, cmd; uint8_t hart_id; @@ -165,13 +167,13 @@ static ALWAYS_INLINE int nds_l2_cache_range(void *addr, size_t size, int op) } last_byte = (unsigned long)addr + size - 1; - align_addr = ROUND_DOWN(addr, line_size); + align_addr = ROUND_DOWN(addr, l2_cache_cfg.line_size); hart_id = arch_proc_id(); while (align_addr <= last_byte) { sys_write32(align_addr, L2C_CCTLACC(hart_id)); sys_write32(cmd, L2C_CCTLCMD(hart_id)); - align_addr += line_size; + align_addr += l2_cache_cfg.line_size; /* Wait L2 CCTL Commands finished */ nds_l2_cache_wait_status(hart_id); @@ -204,9 +206,10 @@ static ALWAYS_INLINE void nds_l2_cache_disable(void) } } -static ALWAYS_INLINE int nds_l2_cache_init(void) +static ALWAYS_INLINE int nds_l2_cache_init(uint8_t line_size) { - unsigned long line_size; + unsigned long size; + uint32_t l2c_ctrl; #if defined(CONFIG_SYSCON) #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(syscon), andestech_atcsmu100, okay) @@ -230,10 +233,10 @@ static ALWAYS_INLINE int nds_l2_cache_init(void) #endif /* andestech_atcsmu100 dts node status okay */ #endif /* defined(CONFIG_SYSCON) */ - uint32_t l2c_ctrl; + l2_cache_cfg.line_size = line_size; - line_size = (sys_read32(L2C_CONFIG) >> L2C_CONFIG_SIZE_SHIFT) & BIT_MASK(7); - l2_cache_cfg.size = line_size * 128 * 1024; + size = (sys_read32(L2C_CONFIG) >> L2C_CONFIG_SIZE_SHIFT) & BIT_MASK(7); + l2_cache_cfg.size = size * 128 * 1024; if (sys_read32(L2C_CONFIG) & L2C_CONFIG_MAP) { l2_cache_cfg.cmd_offset = 0x10; diff --git a/drivers/cache/cache_nxp_xcache.c b/drivers/cache/cache_nxp_xcache.c new file mode 100644 index 0000000000000..59dd7ce2af6be --- /dev/null +++ b/drivers/cache/cache_nxp_xcache.c @@ -0,0 +1,125 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(cache_nxp_xcache, CONFIG_CACHE_LOG_LEVEL); + +#if !defined(NXP_XCACHE_INSTR) +#define NXP_XCACHE_INSTR XCACHE_PC +#endif + +#if !defined(NXP_XCACHE_DATA) +#define NXP_XCACHE_DATA XCACHE_PS +#endif + +void cache_data_enable(void) +{ + XCACHE_EnableCache(NXP_XCACHE_DATA); +} + +void cache_data_disable(void) +{ + XCACHE_DisableCache(NXP_XCACHE_DATA); +} + +int cache_data_flush_all(void) +{ + XCACHE_CleanCache(NXP_XCACHE_DATA); + + return 0; +} + +int cache_data_invd_all(void) +{ + XCACHE_InvalidateCache(NXP_XCACHE_DATA); + + return 0; +} + +int cache_data_flush_and_invd_all(void) +{ + XCACHE_CleanInvalidateCache(NXP_XCACHE_DATA); + + return 0; +} + +int cache_data_flush_range(void *addr, size_t size) +{ + XCACHE_CleanCacheByRange((uint32_t)addr, size); + + return 0; +} + +int cache_data_invd_range(void *addr, size_t size) +{ + XCACHE_InvalidateCacheByRange((uint32_t)addr, size); + + return 0; +} + +int cache_data_flush_and_invd_range(void *addr, size_t size) +{ + XCACHE_CleanInvalidateCacheByRange((uint32_t)addr, size); + + return 0; +} + +void cache_instr_enable(void) +{ + XCACHE_EnableCache(NXP_XCACHE_INSTR); +} + +void cache_instr_disable(void) +{ + XCACHE_DisableCache(NXP_XCACHE_INSTR); +} + +int cache_instr_flush_all(void) +{ + XCACHE_CleanCache(NXP_XCACHE_INSTR); + + return 0; +} + +int cache_instr_invd_all(void) +{ + XCACHE_InvalidateCache(NXP_XCACHE_INSTR); + + return 0; +} + +int cache_instr_flush_and_invd_all(void) +{ + XCACHE_CleanInvalidateCache(NXP_XCACHE_INSTR); + + return 0; +} + +int cache_instr_flush_range(void *addr, size_t size) +{ + XCACHE_CleanCacheByRange((uint32_t)addr, size); + + return 0; +} + +int cache_instr_invd_range(void *addr, size_t size) +{ + XCACHE_InvalidateCacheByRange((uint32_t)addr, size); + + return 0; +} + +int cache_instr_flush_and_invd_range(void *addr, size_t size) +{ + XCACHE_CleanInvalidateCacheByRange((uint32_t)addr, size); + + return 0; +} diff --git a/drivers/can/CMakeLists.txt b/drivers/can/CMakeLists.txt index 1398309e91484..c84884df8b56f 100644 --- a/drivers/can/CMakeLists.txt +++ b/drivers/can/CMakeLists.txt @@ -3,33 +3,39 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/can.h) zephyr_library() -zephyr_sources_ifdef(CONFIG_CAN_MCUX_MCAN can_mcux_mcan.c) +# CAN subsystem common files +# zephyr-keep-sorted-start zephyr_library_sources_ifdef(CONFIG_CAN can_common.c) +zephyr_library_sources_ifdef(CONFIG_CAN_SHELL can_shell.c) +zephyr_library_sources_ifdef(CONFIG_USERSPACE can_handlers.c) +# zephyr-keep-sorted-stop + +# CAN subsystem driver files +# zephyr-keep-sorted-start +zephyr_library_sources_ifdef(CONFIG_CAN_ESP32_TWAI can_esp32_twai.c) zephyr_library_sources_ifdef(CONFIG_CAN_FAKE can_fake.c) +zephyr_library_sources_ifdef(CONFIG_CAN_KVASER_PCI can_kvaser_pci.c) zephyr_library_sources_ifdef(CONFIG_CAN_LOOPBACK can_loopback.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCAN can_mcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCP2515 can_mcp2515.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCP251XFD can_mcp251xfd.c) zephyr_library_sources_ifdef(CONFIG_CAN_MCUX_FLEXCAN can_mcux_flexcan.c) +zephyr_library_sources_ifdef(CONFIG_CAN_MCUX_MCAN can_mcux_mcan.c) +zephyr_library_sources_ifdef(CONFIG_CAN_NRF can_nrf.c) +zephyr_library_sources_ifdef(CONFIG_CAN_NUMAKER can_numaker.c) +zephyr_library_sources_ifdef(CONFIG_CAN_NXP_S32_CANXL can_nxp_s32_canxl.c) +zephyr_library_sources_ifdef(CONFIG_CAN_RCAR can_rcar.c) +zephyr_library_sources_ifdef(CONFIG_CAN_RENESAS_RA_CANFD can_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_CAN_SAM can_sam.c) zephyr_library_sources_ifdef(CONFIG_CAN_SAM0 can_sam0.c) +zephyr_library_sources_ifdef(CONFIG_CAN_SJA1000 can_sja1000.c) +zephyr_library_sources_ifdef(CONFIG_CAN_STM32H7_FDCAN can_stm32h7_fdcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_STM32_BXCAN can_stm32_bxcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_STM32_FDCAN can_stm32_fdcan.c) -zephyr_library_sources_ifdef(CONFIG_CAN_STM32H7_FDCAN can_stm32h7_fdcan.c) zephyr_library_sources_ifdef(CONFIG_CAN_TCAN4X5X can_tcan4x5x.c) -zephyr_library_sources_ifdef(CONFIG_CAN_RCAR can_rcar.c) -zephyr_library_sources_ifdef(CONFIG_CAN_NUMAKER can_numaker.c) zephyr_library_sources_ifdef(CONFIG_CAN_XMC4XXX can_xmc4xxx.c) -zephyr_library_sources_ifdef(CONFIG_CAN_SJA1000 can_sja1000.c) -zephyr_library_sources_ifdef(CONFIG_CAN_ESP32_TWAI can_esp32_twai.c) -zephyr_library_sources_ifdef(CONFIG_CAN_KVASER_PCI can_kvaser_pci.c) -zephyr_library_sources_ifdef(CONFIG_CAN_NRF can_nrf.c) -zephyr_library_sources_ifdef(CONFIG_CAN_RENESAS_RA_CANFD can_renesas_ra.c) - -zephyr_library_sources_ifdef(CONFIG_USERSPACE can_handlers.c) -zephyr_library_sources_ifdef(CONFIG_CAN_SHELL can_shell.c) -zephyr_library_sources_ifdef(CONFIG_CAN_NXP_S32_CANXL can_nxp_s32_canxl.c) +# zephyr-keep-sorted-stop if(CONFIG_CAN_NATIVE_LINUX) if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Linux) diff --git a/drivers/can/Kconfig.stm32 b/drivers/can/Kconfig.stm32 index 65da04a7225f3..7a9bfae3a731f 100644 --- a/drivers/can/Kconfig.stm32 +++ b/drivers/can/Kconfig.stm32 @@ -54,7 +54,6 @@ config CAN_STM32_FDCAN depends on DT_HAS_ST_STM32_FDCAN_ENABLED select CAN_MCAN select PINCTRL - select USE_STM32_LL_RCC if CAN_STM32_FDCAN @@ -82,4 +81,3 @@ config CAN_STM32H7_FDCAN depends on DT_HAS_ST_STM32H7_FDCAN_ENABLED select CAN_MCAN select PINCTRL - select USE_STM32_LL_RCC diff --git a/drivers/can/can_nrf.c b/drivers/can/can_nrf.c index b4e6dbd49be7a..c538291ecb407 100644 --- a/drivers/can/can_nrf.c +++ b/drivers/can/can_nrf.c @@ -13,9 +13,14 @@ #include #include #include +#include #include #include +#ifdef CONFIG_SOC_NRF54H20_GPD +#include +#endif + /* nRF CAN wrapper offsets */ #define CAN_TASKS_START offsetof(NRF_CAN_Type, TASKS_START) #define CAN_EVENTS_CORE_0 offsetof(NRF_CAN_Type, EVENTS_CORE[0]) @@ -27,7 +32,8 @@ struct can_nrf_config { uint32_t mcan; uint32_t mrba; uint32_t mram; - const struct device *clock; + const struct device *auxpll; + const struct device *hsfll; const struct pinctrl_dev_config *pcfg; void (*irq_configure)(void); uint16_t irq; @@ -54,7 +60,7 @@ static int can_nrf_get_core_clock(const struct device *dev, uint32_t *rate) const struct can_mcan_config *mcan_config = dev->config; const struct can_nrf_config *config = mcan_config->custom; - return clock_control_get_rate(config->clock, NULL, rate); + return clock_control_get_rate(config->auxpll, NULL, rate); } static DEVICE_API(can, can_nrf_api) = { @@ -131,17 +137,41 @@ static const struct can_mcan_ops can_mcan_nrf_ops = { .clear_mram = can_nrf_clear_mram, }; +static int configure_hsfll(const struct device *dev, bool on) +{ + const struct can_mcan_config *mcan_config = dev->config; + const struct can_nrf_config *config = mcan_config->custom; + struct nrf_clock_spec spec = { 0 }; + + /* If CAN is on, HSFLL frequency >= AUXPLL frequency */ + if (on) { + int ret; + + ret = clock_control_get_rate(dev, NULL, &spec.frequency); + if (ret < 0) { + return ret; + } + } + + return nrf_clock_control_request_sync(config->hsfll, &spec, K_FOREVER); +} + static int can_nrf_init(const struct device *dev) { const struct can_mcan_config *mcan_config = dev->config; const struct can_nrf_config *config = mcan_config->custom; int ret; - if (!device_is_ready(config->clock)) { + if (!device_is_ready(config->auxpll) || !device_is_ready(config->hsfll)) { return -ENODEV; } - ret = clock_control_on(config->clock, NULL); + ret = configure_hsfll(dev, true); + if (ret < 0) { + return ret; + } + + ret = clock_control_on(config->auxpll, NULL); if (ret < 0) { return ret; } @@ -151,11 +181,19 @@ static int can_nrf_init(const struct device *dev) return ret; } + sys_write32(0U, config->wrapper + CAN_EVENTS_CORE_0); sys_write32(0U, config->wrapper + CAN_EVENTS_CORE_1); sys_write32(CAN_INTEN_CORE0_Msk | CAN_INTEN_CORE1_Msk, config->wrapper + CAN_INTEN); sys_write32(1U, config->wrapper + CAN_TASKS_START); +#ifdef CONFIG_SOC_NRF54H20_GPD + ret = nrf_gpd_retain_pins_set(config->pcfg, false); + if (ret < 0) { + return ret; + } +#endif + config->irq_configure(); ret = can_mcan_configure_mram(dev, config->mrba, config->mram); @@ -186,8 +224,9 @@ static int can_nrf_init(const struct device *dev) .mcan = CAN_MCAN_DT_INST_MCAN_ADDR(n), \ .mrba = CAN_MCAN_DT_INST_MRBA(n), \ .mram = CAN_MCAN_DT_INST_MRAM_ADDR(n), \ - .clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .auxpll = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(n, auxpll)), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .hsfll = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(n, hsfll)), \ .irq = DT_INST_IRQN(n), \ .irq_configure = can_nrf_irq_configure##n, \ }; \ diff --git a/drivers/can/can_renesas_ra.c b/drivers/can/can_renesas_ra.c index 8a4239275e6e9..0d6c679dee418 100644 --- a/drivers/can/can_renesas_ra.c +++ b/drivers/can/can_renesas_ra.c @@ -88,7 +88,7 @@ LOG_MODULE_REGISTER(can_renesas_ra, CONFIG_CAN_LOG_LEVEL); #define CANFD_CFG_GLOBAL \ ((0U << R_CANFD_CFDGCFG_TPRI_Pos) | /* Transmission Priority: ID priority */ \ (0U << R_CANFD_CFDGCFG_DCE_Pos) | /* DLC check disabled */ \ - (1U << R_CANFD_CFDGCFG_DCS_Pos)) /* DLL Clock Select: CANFDCLK */ + (0U << R_CANFD_CFDGCFG_DCS_Pos)) /* DLL Clock Select: CANFDCLK */ /* * TX Message Buffer Interrupt Enable Configuration: refer to '34.2.43 CFDTMIEC : TX Message Buffer @@ -142,6 +142,8 @@ struct can_renesas_ra_global_cfg { const struct device *ram_clk; const struct clock_control_ra_subsys_cfg op_subsys; const struct clock_control_ra_subsys_cfg ram_subsys; + const unsigned int dll_min_freq; + const unsigned int dll_max_freq; }; struct can_renesas_ra_filter { @@ -902,19 +904,33 @@ static inline int can_renesas_module_clock_init(const struct device *dev) return ret; } + if (dll_rate < global_cfg->dll_min_freq || dll_rate > global_cfg->dll_max_freq) { + LOG_ERR("%s frequency is out of supported range: %d < %s freq < %d", + cfg->dll_clk->name, global_cfg->dll_min_freq, cfg->dll_clk->name, + global_cfg->dll_max_freq); + return -ENOTSUP; + } + /* Clock constraint: refer to '34.1.2 Clock restriction' - RA8M1 MCU group HWM */ /* * Operation clock rate must be at least 40Mhz in case CANFD mode. * Otherwise, it must be at least 32MHz. */ - if (IS_ENABLED(CONFIG_CAN_FD_MODE) ? op_rate < 40000000 : op_rate < 32000000) { + if (IS_ENABLED(CONFIG_CAN_FD_MODE) ? op_rate < MHZ(40) : op_rate < MHZ(32)) { + LOG_ERR("%s frequency should be at least %d", global_cfg->op_clk->name, + IS_ENABLED(CONFIG_CAN_FD_MODE) ? MHZ(40) : MHZ(32)); return -ENOTSUP; } + /* * (RAM clock rate / 2) >= DLL rate * (CANFD operation clock rate) >= DLL rate */ if ((ram_rate / 2) < dll_rate || op_rate < dll_rate) { + LOG_ERR("%s frequency should be less than half of %s and %s frequency should " + "be less than %s", + global_cfg->ram_clk->name, cfg->dll_clk->name, global_cfg->op_clk->name, + cfg->dll_clk->name); return -ENOTSUP; } @@ -998,12 +1014,10 @@ static DEVICE_API(can, can_renesas_ra_driver_api) = { R_ICU->IELSR_b[VECTOR_NUMBER_CAN_GLERR].IELS = ELC_EVENT_CAN_GLERR; \ R_ICU->IELSR_b[VECTOR_NUMBER_CAN_RXF].IELS = ELC_EVENT_CAN_RXF; \ IRQ_CONNECT(VECTOR_NUMBER_CAN_GLERR, \ - DT_IRQ_BY_NAME(DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), glerr, \ - priority), \ + DT_IRQ_BY_NAME(DT_INST(0, renesas_ra_canfd_global), glerr, priority), \ canfd_error_isr, NULL, 0); \ IRQ_CONNECT(VECTOR_NUMBER_CAN_RXF, \ - DT_IRQ_BY_NAME(DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), rxf, \ - priority), \ + DT_IRQ_BY_NAME(DT_INST(0, renesas_ra_canfd_global), rxf, priority), \ canfd_rx_fifo_isr, NULL, 0); \ irq_enable(VECTOR_NUMBER_CAN_RXF); \ irq_enable(VECTOR_NUMBER_CAN_GLERR); @@ -1012,30 +1026,26 @@ static canfd_global_cfg_t g_canfd_global_cfg = { .global_interrupts = CANFD_CFG_GLERR_IRQ, .global_config = CANFD_CFG_GLOBAL, .rx_mb_config = CANFD_CFG_RXMB, - .global_err_ipl = DT_IRQ_BY_NAME(DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), - glerr, priority), - .rx_fifo_ipl = DT_IRQ_BY_NAME(DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), rxf, - priority), + .global_err_ipl = DT_IRQ_BY_NAME(DT_INST(0, renesas_ra_canfd_global), glerr, priority), + .rx_fifo_ipl = DT_IRQ_BY_NAME(DT_INST(0, renesas_ra_canfd_global), rxf, priority), .rx_fifo_config = CANFD_CFG_RXFIFO, .common_fifo_config = CANFD_CFG_COMMONFIFO, }; static const struct can_renesas_ra_global_cfg g_can_renesas_ra_global_cfg = { - .op_clk = DEVICE_DT_GET(DT_CLOCKS_CTLR_BY_NAME( - DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), opclk)), - .ram_clk = DEVICE_DT_GET(DT_CLOCKS_CTLR_BY_NAME( - DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), ramclk)), - .op_subsys = {.mstp = DT_CLOCKS_CELL_BY_NAME( - DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), opclk, mstp), - .stop_bit = DT_CLOCKS_CELL_BY_NAME( - DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), opclk, - stop_bit)}, - .ram_subsys = {.mstp = DT_CLOCKS_CELL_BY_NAME( - DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), ramclk, - mstp), - .stop_bit = DT_CLOCKS_CELL_BY_NAME( - DT_COMPAT_GET_ANY_STATUS_OKAY(renesas_ra_canfd_global), ramclk, - stop_bit)}, + .op_clk = DEVICE_DT_GET(DT_CLOCKS_CTLR_BY_NAME(DT_INST(0, renesas_ra_canfd_global), opclk)), + .ram_clk = + DEVICE_DT_GET(DT_CLOCKS_CTLR_BY_NAME(DT_INST(0, renesas_ra_canfd_global), ramclk)), + .op_subsys = {.mstp = DT_CLOCKS_CELL_BY_NAME(DT_INST(0, renesas_ra_canfd_global), opclk, + mstp), + .stop_bit = DT_CLOCKS_CELL_BY_NAME(DT_INST(0, renesas_ra_canfd_global), opclk, + stop_bit)}, + .ram_subsys = {.mstp = DT_CLOCKS_CELL_BY_NAME(DT_INST(0, renesas_ra_canfd_global), ramclk, + mstp), + .stop_bit = DT_CLOCKS_CELL_BY_NAME(DT_INST(0, renesas_ra_canfd_global), + ramclk, stop_bit)}, + .dll_min_freq = DT_PROP_OR(DT_INST(0, renesas_ra_canfd_global), dll_min_freq, 0), + .dll_max_freq = DT_PROP_OR(DT_INST(0, renesas_ra_canfd_global), dll_max_freq, UINT_MAX), }; static int can_renesas_ra_global_init(const struct device *dev) diff --git a/drivers/can/can_sam0.c b/drivers/can/can_sam0.c index 74532748e2e03..4680fc63a7130 100644 --- a/drivers/can/can_sam0.c +++ b/drivers/can/can_sam0.c @@ -3,6 +3,7 @@ * Copyright (c) 2021 Alexander Wachter * Copyright (c) 2022 Kamil Serwus * Copyright (c) 2023 Sebastian Schlupp + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +18,8 @@ LOG_MODULE_REGISTER(can_sam0, CONFIG_CAN_LOG_LEVEL); +/* clang-format off */ + #define DT_DRV_COMPAT atmel_sam0_can struct can_sam0_config { @@ -26,7 +29,8 @@ struct can_sam0_config { const struct pinctrl_dev_config *pcfg; volatile uint32_t *mclk; uint32_t mclk_mask; - uint16_t gclk_core_id; + uint32_t gclk_gen; + uint16_t gclk_id; int divider; }; @@ -109,6 +113,11 @@ static int can_sam0_get_core_clock(const struct device *dev, uint32_t *rate) static void can_sam0_clock_enable(const struct can_sam0_config *cfg) { + *cfg->mclk |= cfg->mclk_mask; + + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); + /* Enable the GLCK7 with DIV*/ #if defined(CONFIG_SOC_SERIES_SAME51) || defined(CONFIG_SOC_SERIES_SAME54) /*DFFL has to be used as clock source for the ATSAME51/54 family of SoCs*/ @@ -121,13 +130,6 @@ static void can_sam0_clock_enable(const struct can_sam0_config *cfg) | GCLK_GENCTRL_DIV(cfg->divider) | GCLK_GENCTRL_GENEN; #endif - - /* Route channel */ - GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK7 - | GCLK_PCHCTRL_CHEN; - - /* Enable CAN clock in MCLK */ - *cfg->mclk |= cfg->mclk_mask; } static int can_sam0_init(const struct device *dev) @@ -204,6 +206,9 @@ static void config_can_##inst##_irq(void) \ irq_enable(DT_INST_IRQ_BY_NAME(inst, int0, irq)); \ } +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + #define CAN_SAM0_CFG_INST(inst) \ CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, can_sam0_cbs_##inst); \ CAN_MCAN_DT_INST_MRAM_DEFINE(inst, can_sam0_mram_##inst); \ @@ -211,9 +216,10 @@ static void config_can_##inst##_irq(void) \ static const struct can_sam0_config can_sam0_cfg_##inst = { \ .base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \ .mram = (mem_addr_t)POINTER_TO_UINT(&can_sam0_mram_##inst), \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \ - .gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \ .divider = DT_INST_PROP(inst, divider), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ .config_irq = config_can_##inst##_irq, \ @@ -243,3 +249,5 @@ static void config_can_##inst##_irq(void) \ CAN_SAM0_DEVICE_INST(inst) DT_INST_FOREACH_STATUS_OKAY(CAN_SAM0_INST) + +/* clang-format on */ diff --git a/drivers/can/can_shell.c b/drivers/can/can_shell.c index 26bd5d7f4f80a..eb257f027efe4 100644 --- a/drivers/can/can_shell.c +++ b/drivers/can/can_shell.c @@ -281,7 +281,7 @@ static void can_shell_print_extended_modes(const struct shell *sh, can_mode_t ca static int cmd_can_start(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); int err; if (!can_device_check(dev)) { @@ -302,7 +302,7 @@ static int cmd_can_start(const struct shell *sh, size_t argc, char **argv) static int cmd_can_stop(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); int err; if (!can_device_check(dev)) { @@ -323,7 +323,7 @@ static int cmd_can_stop(const struct shell *sh, size_t argc, char **argv) static int cmd_can_show(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); const struct device *phy; const struct can_timing *timing_min; const struct can_timing *timing_max; @@ -434,7 +434,7 @@ static int cmd_can_show(const struct shell *sh, size_t argc, char **argv) static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); struct can_timing timing = { 0 }; uint16_t sample_pnt; uint32_t bitrate; @@ -505,7 +505,7 @@ static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv) static int cmd_can_dbitrate_set(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); struct can_timing timing = { 0 }; uint16_t sample_pnt; uint32_t bitrate; @@ -614,7 +614,7 @@ static int can_shell_parse_timing(const struct shell *sh, size_t argc, char **ar static int cmd_can_timing_set(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); struct can_timing timing = { 0 }; int err; @@ -643,7 +643,7 @@ static int cmd_can_timing_set(const struct shell *sh, size_t argc, char **argv) static int cmd_can_dtiming_set(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); struct can_timing timing = { 0 }; int err; @@ -672,7 +672,7 @@ static int cmd_can_dtiming_set(const struct shell *sh, size_t argc, char **argv) static int cmd_can_mode_set(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); can_mode_t mode = CAN_MODE_NORMAL; can_mode_t raw; char *endptr; @@ -720,7 +720,7 @@ static int cmd_can_mode_set(const struct shell *sh, size_t argc, char **argv) static int cmd_can_send(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); static unsigned int frame_counter; unsigned int frame_no; struct can_frame frame = { 0 }; @@ -841,7 +841,7 @@ static int cmd_can_send(const struct shell *sh, size_t argc, char **argv) static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); struct can_filter filter; uint32_t id_mask; int argidx = 2; @@ -941,7 +941,7 @@ static int cmd_can_filter_add(const struct shell *sh, size_t argc, char **argv) static int cmd_can_filter_remove(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); int filter_id; char *endptr; @@ -965,7 +965,7 @@ static int cmd_can_filter_remove(const struct shell *sh, size_t argc, char **arg static int cmd_can_recover(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); k_timeout_t timeout = K_FOREVER; int millisec; char *endptr; @@ -1031,7 +1031,7 @@ static void cmd_can_mode(size_t idx, struct shell_static_entry *entry) static void cmd_can_device_name_mode(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, can_device_check); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/can/can_stm32_fdcan.c b/drivers/can/can_stm32_fdcan.c index 44605a3237a97..ebed4c6939b64 100644 --- a/drivers/can/can_stm32_fdcan.c +++ b/drivers/can/can_stm32_fdcan.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -403,13 +402,30 @@ static int can_stm32fd_clear_mram(const struct device *dev, uint16_t offset, siz static int can_stm32fd_get_core_clock(const struct device *dev, uint32_t *rate) { - const uint32_t rate_tmp = LL_RCC_GetFDCANClockFreq(LL_RCC_FDCAN_CLKSOURCE); + uint32_t rate_tmp; + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_stm32fd_config *stm32fd_cfg = mcan_cfg->custom; + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); ARG_UNUSED(dev); + if (!device_is_ready(clk)) { + return -ENODEV; + } - if (rate_tmp == LL_RCC_PERIPH_FREQUENCY_NO) { - LOG_ERR("Can't read core clock"); - return -EIO; + if (IS_ENABLED(STM32_CANFD_DOMAIN_CLOCK_SUPPORT) && (stm32fd_cfg->pclk_len > 1)) { + if (clock_control_get_rate(clk, + (clock_control_subsys_t) &stm32fd_cfg->pclken[1], + &rate_tmp) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclk[1])"); + return -EIO; + } + } else { + if (clock_control_get_rate(clk, + (clock_control_subsys_t) &stm32fd_cfg->pclken[0], + &rate_tmp) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclk[0])"); + return -EIO; + } } if (FDCAN_CONFIG->CKDIV == 0) { diff --git a/drivers/can/can_stm32h7_fdcan.c b/drivers/can/can_stm32h7_fdcan.c index 912358b14624b..9e3c5ceb055c2 100644 --- a/drivers/can/can_stm32h7_fdcan.c +++ b/drivers/can/can_stm32h7_fdcan.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -84,16 +83,33 @@ static int can_stm32h7_clear_mram(const struct device *dev, uint16_t offset, siz static int can_stm32h7_get_core_clock(const struct device *dev, uint32_t *rate) { - const uint32_t rate_tmp = LL_RCC_GetFDCANClockFreq(LL_RCC_FDCAN_CLKSOURCE); + uint32_t rate_tmp; + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_stm32h7_config *stm32h7_cfg = mcan_cfg->custom; + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); uint32_t cdiv; ARG_UNUSED(dev); - - if (rate_tmp == LL_RCC_PERIPH_FREQUENCY_NO) { - LOG_ERR("Can't read core clock"); - return -EIO; + if (!device_is_ready(clk)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; } + if (IS_ENABLED(STM32H7_FDCAN_DOMAIN_CLOCK_SUPPORT) && (stm32h7_cfg->pclk_len > 1)) { + if (clock_control_get_rate(clk, + (clock_control_subsys_t) &stm32h7_cfg->pclken[1], + &rate_tmp) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclk[1])"); + return -EIO; + } + } else { + if (clock_control_get_rate(clk, + (clock_control_subsys_t) &stm32h7_cfg->pclken[0], + &rate_tmp) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclk[0])"); + return -EIO; + } + } cdiv = FIELD_GET(FDCANCCU_CCFG_CDIV, FDCAN_CCU->CCFG); if (cdiv == 0U) { *rate = rate_tmp; diff --git a/drivers/can/can_tcan4x5x.c b/drivers/can/can_tcan4x5x.c index d92efa204550d..2abd0467a5ee3 100644 --- a/drivers/can/can_tcan4x5x.c +++ b/drivers/can/can_tcan4x5x.c @@ -508,8 +508,10 @@ static int tcan4x5x_wake(const struct device *dev) static int tcan4x5x_reset(const struct device *dev) { +#if TCAN4X5X_RST_GPIO_SUPPORT const struct can_mcan_config *mcan_config = dev->config; const struct tcan4x5x_config *tcan_config = mcan_config->custom; +#endif /* TCAN4X5X_RST_GPIO_SUPPORT */ int err; err = tcan4x5x_wake(dev); diff --git a/drivers/charger/CMakeLists.txt b/drivers/charger/CMakeLists.txt index 60b80b0ed25cd..fd4832eded35b 100644 --- a/drivers/charger/CMakeLists.txt +++ b/drivers/charger/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/charger.h) zephyr_library_sources_ifdef(CONFIG_CHARGER_BQ24190 charger_bq24190.c) zephyr_library_sources_ifdef(CONFIG_CHARGER_BQ25180 charger_bq25180.c) zephyr_library_sources_ifdef(CONFIG_CHARGER_MAX20335 charger_max20335.c) +zephyr_library_sources_ifdef(CONFIG_CHARGER_PF1550 charger_pf1550.c) zephyr_library_sources_ifdef(CONFIG_SBS_CHARGER sbs_charger.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE charger_handlers.c) zephyr_library_sources_ifdef(CONFIG_EMUL_SBS_CHARGER emul_sbs_charger.c) diff --git a/drivers/charger/Kconfig b/drivers/charger/Kconfig index 4e0b6b3c7a742..c6c68bdaba585 100644 --- a/drivers/charger/Kconfig +++ b/drivers/charger/Kconfig @@ -54,5 +54,6 @@ source "drivers/charger/Kconfig.sbs_charger" source "drivers/charger/Kconfig.bq24190" source "drivers/charger/Kconfig.bq25180" source "drivers/charger/Kconfig.max20335" +source "drivers/charger/Kconfig.pf1550" endif # CHARGER diff --git a/drivers/charger/Kconfig.pf1550 b/drivers/charger/Kconfig.pf1550 new file mode 100644 index 0000000000000..f81e0b085b91e --- /dev/null +++ b/drivers/charger/Kconfig.pf1550 @@ -0,0 +1,12 @@ +# Copyright 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +config CHARGER_PF1550 + bool "NXP PF1550 battery charger driver" + default y + depends on DT_HAS_NXP_PF1550_CHARGER_ENABLED + select GPIO + select I2C + select MFD + help + Enable the NXP PF1550 battery charger driver. diff --git a/drivers/charger/charger_bq24190.c b/drivers/charger/charger_bq24190.c index 58cae3b897ecc..b7672a8880703 100644 --- a/drivers/charger/charger_bq24190.c +++ b/drivers/charger/charger_bq24190.c @@ -433,6 +433,21 @@ static int bq24190_set_prop(const struct device *dev, charger_prop_t prop, } } +static int bq24190_charge_enable(const struct device *dev, const bool enable) +{ + const struct bq24190_config *const config = dev->config; + + if (config->ce_gpio.port != NULL) { + if (enable == true) { + return gpio_pin_set_dt(&config->ce_gpio, 1); + } else { + return gpio_pin_set_dt(&config->ce_gpio, 0); + } + } else { + return -ENOTSUP; + } +} + static int bq24190_init(const struct device *dev) { const struct bq24190_config *const config = dev->config; @@ -457,6 +472,19 @@ static int bq24190_init(const struct device *dev) return -ENODEV; } + if (config->ce_gpio.port != NULL) { + if (!gpio_is_ready_dt(&config->ce_gpio)) { + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->ce_gpio, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + } else { + LOG_DBG("Assuming charge enable pin is pulled low"); + } + ret = bq24190_register_reset(dev); if (ret) { return ret; @@ -473,12 +501,14 @@ static int bq24190_init(const struct device *dev) static DEVICE_API(charger, bq24190_driver_api) = { .get_property = bq24190_get_prop, .set_property = bq24190_set_prop, + .charge_enable = bq24190_charge_enable, }; #define BQ24190_INIT(inst) \ \ static const struct bq24190_config bq24190_config_##inst = { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .ce_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, ce_gpios, {}), \ }; \ \ static struct bq24190_data bq24190_data_##inst = { \ diff --git a/drivers/charger/charger_pf1550.c b/drivers/charger/charger_pf1550.c new file mode 100644 index 0000000000000..06ce4d3bc5c91 --- /dev/null +++ b/drivers/charger/charger_pf1550.c @@ -0,0 +1,691 @@ +/* + * Copyright 2024 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_pf1550_charger + +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(pf1550_charger, CONFIG_CHARGER_LOG_LEVEL); + +#define INT_ENABLE_DELAY K_MSEC(500) + +#define CHARGER_CHG_INT (0x80 + 0x00) +#define CHARGER_CHG_INT_MASK (0x80 + 0x02) +#define CHARGER_CHG_INT_OK (0x80 + 0x04) +#define CHARGER_VBUS_SNS (0x80 + 0x06) +#define CHARGER_CHG_SNS (0x80 + 0x07) +#define CHARGER_BATT_SNS (0x80 + 0x08) +#define CHARGER_CHG_OPER (0x80 + 0x09) +#define CHARGER_CHG_TMR (0x80 + 0x0A) +#define CHARGER_CHG_EOC_CNFG (0x80 + 0x0D) +#define CHARGER_CHG_CURR_CNFG (0x80 + 0x0E) +#define CHARGER_BATT_REG (0x80 + 0x0F) +#define CHARGER_BATFET_CNFG (0x80 + 0x11) +#define CHARGER_THM_REG_CNFG (0x80 + 0x12) +#define CHARGER_VBUS_INLIM_CNFG (0x80 + 0x14) +#define CHARGER_VBUS_LIN_DPM (0x80 + 0x15) +#define CHARGER_USB_PHY_LDO_CNFG (0x80 + 0x16) +#define CHARGER_DBNC_DELAY_TIME (0x80 + 0x18) +#define CHARGER_CHG_INT_CNFG (0x80 + 0x19) +#define CHARGER_THM_ADJ_SETTING (0x80 + 0x1A) +#define CHARGER_VBUS2SYS_CNFG (0x80 + 0x1B) +#define CHARGER_LED_PWM (0x80 + 0x1C) +#define CHARGER_FAULT_BATFET_CNFG (0x80 + 0x1D) +#define CHARGER_LED_CNFG (0x80 + 0x1E) +#define CHARGER_CHGR_KEY2 (0x80 + 0x1F) + +#define PF1550_BAT_IRQ BIT(2) +#define PF1550_CHG_IRQ BIT(3) +#define PF1550_VBUS_IRQ BIT(5) +#define PF1550_VBUS_DPM_IRQ BIT(5) +#define CHG_INT_ENABLE_ALL (0xFF) + +#define LED_PWM_LED_EN BIT(7) +#define LED_PWM_FULL_ON BIT(5) + +#define LED_CNFG_LED_CFG BIT(4) +#define LED_CNFG_LEDOVRD BIT(5) + +#define CHG_OPER_CHG_OPER_MASK GENMASK(1, 0) +#define CHG_CURR_CNFG_CHG_CC_MASK GENMASK(4, 0) +#define CHG_SNS_CHG_SNS_MASK GENMASK(3, 0) +#define VBUS_INLIM_CNFG_VBUS_INLIM_MASK GENMASK(7, 3) +#define BATT_REG_CHGCV_MASK GENMASK(5, 0) +#define BATT_REG_VSYSMIN_MASK GENMASK(7, 6) +#define THM_REG_CNFG_THM_CNFG_MASK GENMASK(1, 0) + +#define CHG_OPER_CHARGER_OFF_LINEAR_OFF 0 +#define CHG_OPER_CHARGER_OFF_LINEAR_ON 1 +#define CHG_OPER_CHARGER_ON_LINEAR_ON 2 + +enum charger_pf1550_therm_mode { + PF1550_THERM_MODE_DISABLED, + PF1550_THERM_MODE_THERMISTOR, + PF1550_THERM_MODE_JEITA_1, + PF1550_THERM_MODE_JEITA_2, + PF1550_THERM_MODE_UNKNOWN, +}; + +/* synced with YAML binding */ +enum charger_pf1550_led_behaviour { + PF1550_LED_ON_IN_CHARGING_FLASH_IN_FAULT, + PF1550_LED_FLASH_IN_CHARGING_ON_IN_FAULT, + PF1550_LED_MANUAL_OFF +}; + +struct charger_pf1550_led_config { + bool enabled; + bool manual; + enum charger_pf1550_led_behaviour behaviour; +}; + +struct charger_pf1550_config { + struct i2c_dt_spec bus; + struct gpio_dt_spec int_gpio; + char *therm_mon_mode; + uint32_t charge_current_ua; + uint32_t vbus_ilim_ua; + uint32_t charge_voltage_max_uv; + uint32_t vsys_min_uv; +}; + +struct charger_pf1550_data { + const struct device *dev; + struct gpio_callback gpio_cb; + struct k_work int_routine_work; + struct k_work_delayable int_enable_work; + enum charger_status charger_status; + enum charger_online charger_online; + charger_status_notifier_t charger_status_notifier; + charger_online_notifier_t charger_online_notifier; + bool charger_enabled; + uint32_t charge_current_ua; + uint32_t vbus_ilim_ua; + struct charger_pf1550_led_config *led_config; +}; + +static const struct linear_range charger_vbus_ilim_range[] = { + LINEAR_RANGE_INIT(10000, 5000, 0, 8), + LINEAR_RANGE_INIT(100000, 50000, 9, 10), + LINEAR_RANGE_INIT(200000, 100000, 11, 19), + LINEAR_RANGE_INIT(1500000, 0, 20, 20), +}; + +static const struct linear_range charger_fast_charge_ua_range[] = { + LINEAR_RANGE_INIT(100000, 50000, 0, 18), +}; + +static const struct linear_range charger_battery_termination_uv_range[] = { + LINEAR_RANGE_INIT(3500000, 20000, 8, 55), +}; + +static const struct linear_range charger_vsysmin_uv[] = { + LINEAR_RANGE_INIT(3500000, 0, 0, 0), + LINEAR_RANGE_INIT(3700000, 0, 1, 1), + LINEAR_RANGE_INIT(4300000, 0, 2, 2), +}; + +static int pf1550_get_charger_status(const struct device *dev, enum charger_status *status) +{ + enum chg_sns { + PF1550_CHARGER_PRECHARGE, + PF1550_FAST_CHARGE_CONSTANT_CURRENT, + PF1550_FAST_CHARGE_CONSTANT_VOLTAGE, + PF1550_END_OF_CHARGE, + PF1550_CHARGE_DONE, + PF1550_TIMER_FAULT = 6, + PF1550_THERMISTOR_SUSPEND, + PF1550_CHARGER_OFF_INVALID_INPUT, + PF1550_BATTERY_OVERVOLTAGE, + PF1550_BATTERY_OVERTEMPERATURE, + PF1550_CHARGER_OFF_LINEAR_MODE = 12, + }; + + const struct charger_pf1550_config *const config = dev->config; + uint8_t val; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, CHARGER_CHG_SNS, &val); + if (ret) { + return ret; + } + + val = FIELD_GET(CHG_SNS_CHG_SNS_MASK, val); + + if (val == PF1550_CHARGE_DONE) { + *status = CHARGER_STATUS_FULL; + } else if (val < PF1550_CHARGE_DONE) { + *status = CHARGER_STATUS_CHARGING; + } else { + *status = CHARGER_STATUS_NOT_CHARGING; + } + + return 0; +} + +static int pf1550_get_charger_online(const struct device *dev, enum charger_online *online) +{ + const struct charger_pf1550_config *const config = dev->config; + uint8_t val; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, CHARGER_CHG_OPER, &val); + if (ret) { + return ret; + } + + val = FIELD_GET(CHG_OPER_CHG_OPER_MASK, val); + + switch (val) { + case CHG_OPER_CHARGER_ON_LINEAR_ON: + *online = CHARGER_ONLINE_FIXED; + break; + default: + *online = CHARGER_ONLINE_OFFLINE; + break; + }; + + return 0; +} + +static int pf1550_set_constant_charge_current(const struct device *dev, uint32_t current_ua) +{ + const struct charger_pf1550_config *const config = dev->config; + uint16_t idx; + uint8_t val; + int ret; + + ret = linear_range_group_get_index(charger_fast_charge_ua_range, + ARRAY_SIZE(charger_fast_charge_ua_range), current_ua, + &idx); + if (ret < 0) { + return ret; + } + + val = FIELD_PREP(CHG_CURR_CNFG_CHG_CC_MASK, idx); + + return i2c_reg_update_byte_dt(&config->bus, CHARGER_CHG_CURR_CNFG, + CHG_CURR_CNFG_CHG_CC_MASK, val); +} + +static int pf1550_set_vbus_ilim(const struct device *dev, uint32_t current_ua) +{ + const struct charger_pf1550_config *const config = dev->config; + uint16_t idx; + uint8_t val; + int ret; + + ret = linear_range_group_get_index(charger_vbus_ilim_range, + ARRAY_SIZE(charger_vbus_ilim_range), current_ua, &idx); + if (ret < 0) { + return ret; + } + + val = FIELD_PREP(VBUS_INLIM_CNFG_VBUS_INLIM_MASK, idx); + + return i2c_reg_update_byte_dt(&config->bus, CHARGER_VBUS_INLIM_CNFG, + VBUS_INLIM_CNFG_VBUS_INLIM_MASK, val); +} + +static int pf1550_set_vsys_min(const struct device *dev, uint32_t voltage_uv) +{ + const struct charger_pf1550_config *const config = dev->config; + uint16_t idx; + uint8_t val; + int ret; + + ret = linear_range_group_get_index(charger_vsysmin_uv, ARRAY_SIZE(charger_vsysmin_uv), + voltage_uv, &idx); + if (ret < 0) { + return ret; + } + + val = FIELD_PREP(BATT_REG_VSYSMIN_MASK, idx); + + return i2c_reg_update_byte_dt(&config->bus, CHARGER_BATT_REG, BATT_REG_VSYSMIN_MASK, val); +} + +static int pf1550_set_charge_termination_uv(const struct device *dev, uint32_t voltage_uv) +{ + const struct charger_pf1550_config *const config = dev->config; + uint16_t idx; + uint8_t val; + int ret; + + ret = linear_range_group_get_index(charger_battery_termination_uv_range, + ARRAY_SIZE(charger_battery_termination_uv_range), + voltage_uv, &idx); + if (ret < 0) { + return ret; + } + + val = FIELD_PREP(BATT_REG_CHGCV_MASK, idx); + + return i2c_reg_update_byte_dt(&config->bus, CHARGER_BATT_REG, BATT_REG_CHGCV_MASK, val); +} + +static int pf1550_set_thermistor_mode(const struct device *dev, enum charger_pf1550_therm_mode mode) +{ + const struct charger_pf1550_config *const config = dev->config; + uint8_t val; + + val = FIELD_PREP(THM_REG_CNFG_THM_CNFG_MASK, mode); + + return i2c_reg_update_byte_dt(&config->bus, CHARGER_THM_REG_CNFG, + THM_REG_CNFG_THM_CNFG_MASK, val); +} + +static int pf1550_set_enabled(const struct device *dev, bool enable) +{ + struct charger_pf1550_data *data = dev->data; + const struct charger_pf1550_config *const config = dev->config; + + int ret = i2c_reg_update_byte_dt(&config->bus, CHARGER_CHG_OPER, CHG_OPER_CHG_OPER_MASK, + enable ? 2 : 0); + + if (ret == 0) { + data->charger_enabled = enable; + } + + return ret; +} + +static int pf1550_get_interrupt_source(const struct device *dev, uint8_t *int_a) +{ + const struct charger_pf1550_config *config = dev->config; + uint8_t buf = 0; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, CHARGER_CHG_INT, &buf); + + if (int_a) { + *int_a = buf; + } + return ret; +} + +static int pf1550_enable_interrupts(const struct device *dev) +{ + const struct charger_pf1550_config *config = dev->config; + int ret; + + ret = pf1550_get_interrupt_source(dev, NULL); + if (ret < 0) { + LOG_WRN("Failed to clear pending interrupts: %d", ret); + return ret; + } + + return i2c_reg_write_byte_dt(&config->bus, CHARGER_CHG_INT_MASK, CHG_INT_ENABLE_ALL); +} + +static int pf1550_led_config(const struct device *dev) +{ + struct charger_pf1550_data *data = dev->data; + const struct charger_pf1550_config *config = dev->config; + struct charger_pf1550_led_config *cfg = data->led_config; + int ret; + uint8_t val; + + cfg->enabled = true; + + if (cfg->behaviour == PF1550_LED_MANUAL_OFF) { + cfg->manual = true; + cfg->enabled = false; + } + + val = (cfg->enabled ? LED_PWM_LED_EN : 0) | LED_PWM_FULL_ON; + + ret = i2c_reg_write_byte_dt(&config->bus, CHARGER_LED_PWM, val); + if (ret < 0) { + return ret; + } + + val = (cfg->manual ? LED_CNFG_LEDOVRD : 0) | + (cfg->behaviour == PF1550_LED_FLASH_IN_CHARGING_ON_IN_FAULT ? + LED_CNFG_LED_CFG : 0); + + return i2c_reg_write_byte_dt(&config->bus, CHARGER_LED_CNFG, val); +} + +static int pf1550_init_properties(const struct device *dev) +{ + struct charger_pf1550_data *data = dev->data; + const struct charger_pf1550_config *config = dev->config; + int ret; + + data->charger_enabled = true; + data->charge_current_ua = config->charge_current_ua; + data->vbus_ilim_ua = config->vbus_ilim_ua; + + ret = pf1550_get_charger_status(dev, &data->charger_status); + if (ret < 0) { + LOG_ERR("Failed to read charger status: %d", ret); + return ret; + } + + ret = pf1550_get_charger_online(dev, &data->charger_online); + if (ret < 0) { + LOG_ERR("Failed to read charger online: %d", ret); + return ret; + } + + return 0; +} + +enum charger_pf1550_therm_mode pf1550_string_to_therm_mode(const char *mode_string) +{ + static const char *const modes[] = { + [PF1550_THERM_MODE_DISABLED] = "disabled", + [PF1550_THERM_MODE_THERMISTOR] = "thermistor", + [PF1550_THERM_MODE_JEITA_1] = "JEITA-1", + [PF1550_THERM_MODE_JEITA_2] = "JEITA-2", + }; + enum charger_pf1550_therm_mode i; + + for (i = PF1550_THERM_MODE_DISABLED; i < ARRAY_SIZE(modes); i++) { + if (strncmp(mode_string, modes[i], strlen(modes[i])) == 0) { + return i; + } + } + + return PF1550_THERM_MODE_UNKNOWN; +} + +static int pf1550_update_properties(const struct device *dev) +{ + struct charger_pf1550_data *data = dev->data; + const struct charger_pf1550_config *config = dev->config; + enum charger_pf1550_therm_mode therm_mode; + int ret; + + ret = pf1550_set_vbus_ilim(dev, config->vbus_ilim_ua); + if (ret < 0) { + LOG_ERR("Failed to set vbus current limit: %d", ret); + return ret; + } + + ret = pf1550_set_vsys_min(dev, config->vsys_min_uv); + if (ret < 0) { + LOG_ERR("Failed to set minimum system voltage threshold: %d", ret); + return ret; + } + + ret = pf1550_set_charge_termination_uv(dev, config->charge_voltage_max_uv); + if (ret < 0) { + LOG_ERR("Failed to set recharge threshold: %d", ret); + return ret; + } + + therm_mode = pf1550_string_to_therm_mode(config->therm_mon_mode); + ret = pf1550_set_thermistor_mode(dev, therm_mode); + if (ret < 0) { + LOG_ERR("Failed to set thermistor mode: %d", ret); + return ret; + } + + ret = pf1550_set_constant_charge_current(dev, data->charge_current_ua); + if (ret < 0) { + LOG_ERR("Failed to set charge voltage: %d", ret); + return ret; + } + + ret = pf1550_set_enabled(dev, data->charger_enabled); + if (ret < 0) { + LOG_ERR("Failed to set enabled: %d", ret); + return ret; + } + + ret = pf1550_led_config(dev); + if (ret < 0) { + LOG_ERR("Failed to configure led: %d", ret); + return ret; + } + + return 0; +} + +static int pf1550_get_prop(const struct device *dev, charger_prop_t prop, + union charger_propval *val) +{ + struct charger_pf1550_data *data = dev->data; + + switch (prop) { + case CHARGER_PROP_ONLINE: + val->online = data->charger_online; + return 0; + case CHARGER_PROP_STATUS: + val->status = data->charger_status; + return 0; + case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA: + val->const_charge_current_ua = data->charge_current_ua; + return 0; + default: + return -ENOTSUP; + } +} + +static int pf1550_set_prop(const struct device *dev, charger_prop_t prop, + const union charger_propval *val) +{ + struct charger_pf1550_data *data = dev->data; + int ret; + + switch (prop) { + case CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA: + ret = pf1550_set_constant_charge_current(dev, val->const_charge_current_ua); + if (ret == 0) { + data->charge_current_ua = val->const_charge_current_ua; + } + return ret; + case CHARGER_PROP_INPUT_REGULATION_CURRENT_UA: + ret = pf1550_set_vbus_ilim(dev, val->input_current_regulation_current_ua); + if (ret == 0) { + data->vbus_ilim_ua = val->input_current_regulation_current_ua; + } + return ret; + case CHARGER_PROP_STATUS_NOTIFICATION: + data->charger_status_notifier = val->status_notification; + return 0; + case CHARGER_PROP_ONLINE_NOTIFICATION: + data->charger_online_notifier = val->online_notification; + return 0; + default: + return -ENOTSUP; + } +} + +static int pf1550_enable_interrupt_pin(const struct device *dev, bool enabled) +{ + const struct charger_pf1550_config *const config = dev->config; + gpio_flags_t flags; + int ret; + + flags = enabled ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE; + + ret = gpio_pin_interrupt_configure_dt(&config->int_gpio, flags); + if (ret < 0) { + LOG_ERR("Could not %s interrupt GPIO callback: %d", enabled ? "enable" : "disable", + ret); + } + + return ret; +} + +static void pf1550_gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct charger_pf1550_data *data = CONTAINER_OF(cb, struct charger_pf1550_data, gpio_cb); + int ret; + + (void)pf1550_enable_interrupt_pin(data->dev, false); + + ret = k_work_submit(&data->int_routine_work); + if (ret < 0) { + LOG_WRN("Could not submit int work: %d", ret); + } +} + +static void pf1550_int_routine_work_handler(struct k_work *work) +{ + struct charger_pf1550_data *data = + CONTAINER_OF(work, struct charger_pf1550_data, int_routine_work); + uint8_t int_src; + int ret; + + ret = pf1550_get_interrupt_source(data->dev, &int_src); + if (ret < 0) { + LOG_WRN("Failed to read interrupt source: %d", ret); + return; + } + + LOG_DBG("Interrupt received: %x", int_src); + + ret = pf1550_get_charger_status(data->dev, &data->charger_status); + if (ret < 0) { + LOG_WRN("Failed to read charger status: %d", ret); + return; + } + + ret = pf1550_get_charger_online(data->dev, &data->charger_online); + if (ret < 0) { + LOG_WRN("Failed to read charger online %d", ret); + return; + } + + if (data->charger_status_notifier != NULL) { + data->charger_status_notifier(data->charger_status); + } + if (data->charger_online_notifier != NULL) { + data->charger_online_notifier(data->charger_online); + } + + if (data->charger_online != CHARGER_ONLINE_OFFLINE) { + (void)pf1550_update_properties(data->dev); + } + + ret = k_work_reschedule(&data->int_enable_work, INT_ENABLE_DELAY); + if (ret < 0) { + LOG_WRN("Could not reschedule int_enable_work: %d", ret); + } +} + +static void pf1550_int_enable_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct charger_pf1550_data *data = + CONTAINER_OF(dwork, struct charger_pf1550_data, int_enable_work); + + (void)pf1550_enable_interrupt_pin(data->dev, true); +} + +static int pf1550_configure_interrupt_pin(const struct device *dev) +{ + struct charger_pf1550_data *data = dev->data; + const struct charger_pf1550_config *config = dev->config; + int ret; + + ret = gpio_is_ready_dt(&config->int_gpio) ? 0 : -ENODEV; + if (ret < 0) { + LOG_ERR("Interrupt GPIO device not ready: %d", ret); + return ret; + } + + ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Could not configure interrupt GPIO: %d", ret); + return ret; + } + + gpio_init_callback(&data->gpio_cb, pf1550_gpio_callback, BIT(config->int_gpio.pin)); + ret = gpio_add_callback_dt(&config->int_gpio, &data->gpio_cb); + if (ret < 0) { + LOG_ERR("Could not add interrupt GPIO callback: %d", ret); + return ret; + } + + return 0; +} + +static int pf1550_init(const struct device *dev) +{ + struct charger_pf1550_data *data = dev->data; + const struct charger_pf1550_config *config = dev->config; + int ret; + + if (!i2c_is_ready_dt(&config->bus)) { + return -ENODEV; + } + + data->dev = dev; + + ret = pf1550_init_properties(dev); + if (ret < 0) { + return ret; + } + + k_work_init(&data->int_routine_work, pf1550_int_routine_work_handler); + k_work_init_delayable(&data->int_enable_work, pf1550_int_enable_work_handler); + + ret = pf1550_configure_interrupt_pin(dev); + if (ret < 0) { + return ret; + } + + ret = pf1550_enable_interrupt_pin(dev, true); + if (ret < 0) { + return ret; + } + + ret = pf1550_enable_interrupts(dev); + if (ret < 0) { + LOG_ERR("Failed to enable interrupts: %d", ret); + return ret; + } + + ret = pf1550_update_properties(dev); + if (ret < 0) { + LOG_ERR("Failed to setup charger: %d", ret); + return ret; + } + + return 0; +} + +static const struct charger_driver_api pf1550_driver_api = { + .get_property = pf1550_get_prop, + .set_property = pf1550_set_prop, + .charge_enable = pf1550_set_enabled, +}; + +#define PF1550_DEFINE(inst) \ + static struct charger_pf1550_led_config charger_pf1550_led_config_##inst = { \ + .behaviour = DT_INST_ENUM_IDX(inst, pf1550_led_behaviour), \ + }; \ + static struct charger_pf1550_data charger_pf1550_data_##inst = { \ + .led_config = &charger_pf1550_led_config_##inst, \ + }; \ + static const struct charger_pf1550_config charger_pf1550_config_##inst = { \ + .bus = I2C_DT_SPEC_GET(DT_INST_PARENT(inst)), \ + .int_gpio = GPIO_DT_SPEC_INST_GET(inst, pf1550_int_gpios), \ + .charge_current_ua = DT_INST_PROP(inst, constant_charge_current_max_microamp), \ + .vsys_min_uv = DT_INST_PROP(inst, pf1550_system_voltage_min_threshold_microvolt), \ + .therm_mon_mode = DT_INST_PROP(inst, pf1550_thermistor_monitoring_mode), \ + .vbus_ilim_ua = DT_INST_PROP(inst, pf1550_vbus_current_limit_microamp), \ + .charge_voltage_max_uv = \ + DT_INST_PROP(inst, constant_charge_voltage_max_microvolt), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &pf1550_init, NULL, &charger_pf1550_data_##inst, \ + &charger_pf1550_config_##inst, POST_KERNEL, \ + CONFIG_MFD_INIT_PRIORITY, &pf1550_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PF1550_DEFINE) diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index b17dc7b86c55b..1b8332cdc6f35 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -26,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_DRIVER_CALIBRATION nrf_clo zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RV32M1_PCC clock_control_rv32m1_pcc.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_INFINEON_CAT1 clock_control_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SAM clock_control_sam_pmc.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SILABS_SIWX91X clock_control_silabs_siwx91x.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SILABS_SERIES clock_control_silabs_series.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SI32_PLL clock_control_si32_pll.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SI32_AHB clock_control_si32_ahb.c) @@ -34,9 +35,12 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SMARTBOND clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NUMAKER_SCC clock_control_numaker_scc.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_S32 clock_control_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RENESAS_RA_CGC clock_control_renesas_ra_cgc.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RENESAS_RZ_CPG clock_control_renesas_rz_cpg.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AMBIQ clock_control_ambiq.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_PWM clock_control_pwm.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RPI_PICO clock_control_rpi_pico.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL clock_control_nrf2_global_hsfll.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RTS5912_SCCON clock_control_rts5912_sccon.c) if(CONFIG_CLOCK_CONTROL_NRF2) zephyr_library_sources(clock_control_nrf2_common.c) @@ -57,6 +61,8 @@ elseif(CONFIG_SOC_SERIES_STM32H7RSX) zephyr_library_sources(clock_stm32_ll_h7.c) elseif(CONFIG_SOC_SERIES_STM32H5X) zephyr_library_sources(clock_stm32_ll_h5.c) +elseif(CONFIG_SOC_SERIES_STM32N6X) + zephyr_library_sources(clock_stm32_ll_n6.c) elseif(CONFIG_SOC_SERIES_STM32U5X) zephyr_library_sources(clock_stm32_ll_u5.c) elseif(CONFIG_SOC_SERIES_STM32WB0X) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 040dab163c2b4..c4a0f83d6e154 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -56,6 +56,8 @@ source "drivers/clock_control/Kconfig.npcx" source "drivers/clock_control/Kconfig.rv32m1" +source "drivers/clock_control/Kconfig.rts5912" + source "drivers/clock_control/Kconfig.esp32" source "drivers/clock_control/Kconfig.litex" @@ -86,6 +88,8 @@ source "drivers/clock_control/Kconfig.agilex5" source "drivers/clock_control/Kconfig.renesas_ra_cgc" +source "drivers/clock_control/Kconfig.renesas_rz_cpg" + source "drivers/clock_control/Kconfig.max32" source "drivers/clock_control/Kconfig.ambiq" @@ -100,6 +104,8 @@ source "drivers/clock_control/Kconfig.arm_scmi" source "drivers/clock_control/Kconfig.silabs" +source "drivers/clock_control/Kconfig.siwx91x" + source "drivers/clock_control/Kconfig.wch_rcc" endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index f7b0de3db090d..80cdeb2d1adb1 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -179,12 +179,17 @@ config CLOCK_CONTROL_NRF2 depends on SOC_SERIES_NRF54HX && !RISCV_CORE_NORDIC_VPR select ONOFF select NRFS if HAS_NRFS - imply NRFS_LOCAL_DOMAIN_DVFS_SCALE_DOWN_AFTER_INIT if NRFS_DVFS_LOCAL_DOMAIN help Support for nRF clock control devices. if CLOCK_CONTROL_NRF2 +config CLOCK_CONTROL_NRF2_HSFLL_REQ_LOW_FREQ + bool "Local domain scale down after init" + default y if NRFS_DVFS_LOCAL_DOMAIN + help + Request the lowest operating point after DVFS initialization. + config CLOCK_CONTROL_NRF2_NRFS_DVFS_TIMEOUT_MS int "Timeout waiting for nrfs dvfs service callback in milliseconds" default 2000 @@ -193,4 +198,37 @@ config CLOCK_CONTROL_NRF2_NRFS_CLOCK_TIMEOUT_MS int "Timeout waiting for nrfs clock service callback in milliseconds" default 1000 +config CLOCK_CONTROL_NRF2_GLOBAL_HSFLL + bool "Clock control for global HSFLL" + depends on NRFS_GDFS_SERVICE_ENABLED + default y + +if CLOCK_CONTROL_NRF2_GLOBAL_HSFLL + +config CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_TIMEOUT_MS + int "Frequency request timeout in milliseconds" + default 10000 + +config CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_REQ_LOW_FREQ + bool "Request LOW frequency on init" + default y + help + The GDFS service will default to HIGH frequency until it receives + a lower frequency request. The NRF2 clock controller drivers + expect the clock to be initialized to their lowest frequency, so + we need to send a request on init to align GDFS with the NRF2 + clock controller driver. + + This initial request can be disabled to prevent a potentially + unnecessary HIGH -> LOW -> HIGH cycle given some module will + request a HIGH frequency on init anyway. + +config CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY + int "Init priority of global HSFLL device driver" + default 52 + help + Must be higher than NRFS backend + +endif # CLOCK_CONTROL_NRF2_GLOBAL_HSFLL + endif # CLOCK_CONTROL_NRF2 diff --git a/drivers/clock_control/Kconfig.renesas_rz_cpg b/drivers/clock_control/Kconfig.renesas_rz_cpg new file mode 100644 index 0000000000000..6d8e04cefce57 --- /dev/null +++ b/drivers/clock_control/Kconfig.renesas_rz_cpg @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_RENESAS_RZ_CPG + bool "Renesas RZ/G Clock Control Driver" + default y + depends on DT_HAS_RENESAS_RZ_CPG_ENABLED + select USE_RZ_FSP_CPG + help + Enable support for Renesas RZ CPG Clock Pulse Generator (CPG) driver. + The CPG driver supports only module's clocks. + The PLLs and core clocks are not configured by the CPG driver. diff --git a/drivers/clock_control/Kconfig.rts5912 b/drivers/clock_control/Kconfig.rts5912 new file mode 100644 index 0000000000000..2ad6374c8d2e7 --- /dev/null +++ b/drivers/clock_control/Kconfig.rts5912 @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config CLOCK_CONTROL_RTS5912_SCCON + bool "Realtek RTS5912 system clock controller driver" + depends on SOC_SERIES_RTS5912 + default y if DT_HAS_REALTEK_RTS5912_SCCON_ENABLED + help + Enable support for RTS5912 system clock controller driver diff --git a/drivers/clock_control/Kconfig.siwx91x b/drivers/clock_control/Kconfig.siwx91x new file mode 100644 index 0000000000000..0aa0fc240b853 --- /dev/null +++ b/drivers/clock_control/Kconfig.siwx91x @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_SILABS_SIWX91X + bool "SiWx91x clock control driver" + default y + depends on DT_HAS_SILABS_SIWX91X_CLOCK_ENABLED + help + Enable clock management on Silicon Labs SiWx91x chips. This driver + includes support for HP (High Performace), ULP (Ultra Low Power), and + ULP VBAT clocks. + + The original hardware allow to customize the various clocks offered for + every devices. This driver does not provide such customizations. It + just hardcodes sane default parameters for every devices. diff --git a/drivers/clock_control/Kconfig.stm32 b/drivers/clock_control/Kconfig.stm32 index e5c652b04092e..d99fa3b62eb29 100644 --- a/drivers/clock_control/Kconfig.stm32 +++ b/drivers/clock_control/Kconfig.stm32 @@ -10,7 +10,8 @@ menuconfig CLOCK_CONTROL_STM32_CUBE default y select USE_STM32_LL_UTILS select USE_STM32_LL_RCC if (SOC_SERIES_STM32MP1X || SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X) + SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X || \ + SOC_SERIES_STM32N6X) select RUNTIME_NMI if ($(dt_nodelabel_enabled,clk_hse) && \ $(dt_nodelabel_has_prop,clk_hse,css-enabled)) help @@ -97,310 +98,8 @@ config CLOCK_STM32_MCO bool default y depends on DT_HAS_ST_STM32_CLOCK_MCO_ENABLED || DT_HAS_ST_STM32F1_CLOCK_MCO_ENABLED - # Although deprecated, MCO configuration via Kconfig takes priority over Device Tree. - # Prevent DT-based MCO driver from compiling when Kconfig is used. - depends on CLOCK_STM32_MCO1_SRC_NOCLOCK && CLOCK_STM32_MCO2_SRC_NOCLOCK - -choice - prompt "STM32 MCO1 Clock Source" - default CLOCK_STM32_MCO1_SRC_NOCLOCK - -config CLOCK_STM32_MCO1_SRC_NOCLOCK - bool "NOCLOCK" - help - MCO1 output disabled, no clock on MCO1 - -config CLOCK_STM32_MCO1_SRC_EXT_HSE - bool "EXT_HSE" - depends on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE - select DEPRECATED - help - Use EXT_HSE as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_LSE - bool "LSE" - depends on SOC_SERIES_STM32F4X || \ - SOC_SERIES_STM32F7X || \ - SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X || \ - SOC_SERIES_STM32U5X - select DEPRECATED - help - Use LSE as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_HSE - bool "HSE" - depends on SOC_SERIES_STM32F1X || \ - SOC_SERIES_STM32F4X || \ - SOC_SERIES_STM32F7X || \ - SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X || \ - SOC_SERIES_STM32U5X - select DEPRECATED - help - Use HSE as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_LSI - bool "LSI" - depends on SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32U5X - select DEPRECATED - help - Use LSI as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_MSI - bool "MSI" - depends on SOC_SERIES_STM32L4X - select DEPRECATED - help - Use MSI as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_MSIK - bool "MSIK" - depends on SOC_SERIES_STM32U5X - select DEPRECATED - help - Use MSIK as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_MSIS - bool "MSIS" - depends on SOC_SERIES_STM32U5X - select DEPRECATED - help - Use MSIS as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_HSI - bool "HSI" - depends on SOC_SERIES_STM32F1X || \ - SOC_SERIES_STM32F4X || \ - SOC_SERIES_STM32F7X || \ - SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X - select DEPRECATED - help - Use HSI as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_HSI16 - bool "HSI16" - depends on SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32U5X - select DEPRECATED - help - Use HSI16 as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_HSI48 - bool "HSI48" - depends on SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X || \ - SOC_SERIES_STM32U5X - select DEPRECATED - help - Use HSI48 as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_PLLCLK - bool "PLLCLK" - depends on SOC_SERIES_STM32F4X || \ - SOC_SERIES_STM32F7X || \ - SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32U5X - select DEPRECATED - help - Use PLLCLK as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_PLLQCLK - bool "PLLQ" - depends on SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X - select DEPRECATED - help - Use PLLQ as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_PLLCLK_DIV2 - bool "PLLCLK_DIV2" - depends on SOC_SERIES_STM32F1X - select DEPRECATED - help - Use PLLCLK/2 as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_PLL2CLK - bool "PLL2CLK" - depends on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE - select DEPRECATED - help - Use PLL2CLK as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_PLLI2SCLK - bool "PLLI2SCLK" - depends on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE - select DEPRECATED - help - Use PLLI2SCLK as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_PLLI2SCLK_DIV2 - bool "PLLI2SCLK_DIV2" - depends on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE - select DEPRECATED - help - Use PLLI2SCLK/2 as source of MCO1 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO1_SRC_SYSCLK - bool "SYSCLK" - depends on SOC_SERIES_STM32F1X || \ - SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32U5X - select DEPRECATED - help - Use SYSCLK as source of MCO1 - This option is deprecated, please use devicetree instead. - -endchoice - -config CLOCK_STM32_MCO1_DIV - int "MCO1 prescaler" - depends on !CLOCK_STM32_MCO1_SRC_NOCLOCK && (\ - SOC_SERIES_STM32F4X || \ - SOC_SERIES_STM32F7X || \ - SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X || \ - SOC_SERIES_STM32U5X \ - ) - default 1 - range 1 5 if SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X - range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32H5X - range 1 16 if SOC_SERIES_STM32L4X || SOC_SERIES_STM32U5X - help - Prescaler for MCO1 output clock - This option is deprecated, please use devicetree instead. - -choice - prompt "STM32 MCO2 Clock Source" - default CLOCK_STM32_MCO2_SRC_NOCLOCK - -config CLOCK_STM32_MCO2_SRC_NOCLOCK - bool "NOCLOCK" - help - MCO2 output disabled, no clock on MCO2 - -config CLOCK_STM32_MCO2_SRC_SYSCLK - bool "SYSCLK" - depends on SOC_SERIES_STM32F4X || \ - SOC_SERIES_STM32F7X || \ - SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X - select DEPRECATED - help - Use SYSCLK as source of MCO2 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO2_SRC_PLLI2S - bool "PLLI2S" - depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X - select DEPRECATED - help - Use PLLI2S as source of MCO2 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO2_SRC_HSE - bool "HSE" - depends on SOC_SERIES_STM32F4X || \ - SOC_SERIES_STM32F7X || \ - SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X - select DEPRECATED - help - Use HSE as source of MCO2 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO2_SRC_LSI - bool "LSI" - depends on SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X - help - Use LSI as source of MCO2 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO2_SRC_CSI - bool "CSI" - depends on SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X - select DEPRECATED - help - Use CSI as source of MCO2 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO2_SRC_PLLCLK - bool "PLLCLK" - depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X - select DEPRECATED - help - Use PLLCLK as source of MCO2 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO2_SRC_PLLPCLK - bool "PLLPCLK" - depends on SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X - select DEPRECATED - help - Use PLLPCLK as source of MC02 - This option is deprecated, please use devicetree instead. - -config CLOCK_STM32_MCO2_SRC_PLL2PCLK - bool "PLL2PCLK" - depends on SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX || \ - SOC_SERIES_STM32H5X - select DEPRECATED - help - Use PLL2PCLK as source of MC02 - This option is deprecated, please use devicetree instead. - -endchoice - -config CLOCK_STM32_MCO2_DIV - int "MCO2 prescaler" - depends on !CLOCK_STM32_MCO2_SRC_NOCLOCK && (\ - SOC_SERIES_STM32F4X || \ - SOC_SERIES_STM32F7X || \ - SOC_SERIES_STM32H5X || \ - SOC_SERIES_STM32H7X || \ - SOC_SERIES_STM32H7RSX \ - ) - default 1 - range 1 5 if SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X - range 1 15 if SOC_SERIES_STM32H7X || SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32H5X help - Prescaler for MCO2 output clock + Allows to output various different clock sources onto the MCO pin + using a configurable prescaler. endif # CLOCK_CONTROL_STM32_CUBE diff --git a/drivers/clock_control/clock_control_agilex5.c b/drivers/clock_control/clock_control_agilex5.c index c3c88b625073a..938c18703e6e2 100644 --- a/drivers/clock_control/clock_control_agilex5.c +++ b/drivers/clock_control/clock_control_agilex5.c @@ -25,12 +25,8 @@ struct clock_control_data { static int clock_init(const struct device *dev) { - DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); - /* Initialize the low layer clock driver */ - clock_agilex5_ll_init(DEVICE_MMIO_GET(dev)); - - LOG_INF("Intel Agilex5 clock driver initialized!"); + LOG_DBG("Intel Agilex5 clock driver initialized!"); return 0; } @@ -54,13 +50,25 @@ static int clock_get_rate(const struct device *dev, clock_control_subsys_t sub_s break; case INTEL_SOCFPGA_CLOCK_MMC: - *rate = get_mmc_clk(); + *rate = get_sdmmc_clk(); break; case INTEL_SOCFPGA_CLOCK_TIMER: *rate = get_timer_clk(); break; + case INTEL_SOCFPGA_CLOCK_QSPI: + *rate = get_qspi_clk(); + break; + + case INTEL_SOCFPGA_CLOCK_I2C: + *rate = get_i2c_clk(); + break; + + case INTEL_SOCFPGA_CLOCK_I3C: + *rate = get_i3c_clk(); + break; + default: LOG_ERR("Clock ID %ld is not supported\n", (intptr_t)sub_system); return -ENOTSUP; diff --git a/drivers/clock_control/clock_control_agilex5_ll.c b/drivers/clock_control/clock_control_agilex5_ll.c index a730832330949..bde406cd44b2c 100644 --- a/drivers/clock_control/clock_control_agilex5_ll.c +++ b/drivers/clock_control/clock_control_agilex5_ll.c @@ -1,181 +1,254 @@ /* - * Copyright (c) 2022-2023, Intel Corporation. + * Copyright (c) 2022-2024, Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include #include +#include #include "clock_control_agilex5_ll.h" LOG_MODULE_REGISTER(clock_control_agilex5_ll, CONFIG_CLOCK_CONTROL_LOG_LEVEL); -/* Clock manager individual group base addresses. */ -struct clock_agilex5_ll_params { - mm_reg_t base_addr; - mm_reg_t mainpll_addr; - mm_reg_t peripll_addr; - mm_reg_t ctl_addr; -}; - -/* Clock manager low layer(ll) params object. */ -static struct clock_agilex5_ll_params clock_agilex5_ll; - -/* Initialize the clock ll with the given base address */ -void clock_agilex5_ll_init(mm_reg_t base_addr) -{ - /* Clock manager module base address. */ - clock_agilex5_ll.base_addr = base_addr; - - /* Clock manager main PLL base address. */ - clock_agilex5_ll.mainpll_addr = clock_agilex5_ll.base_addr + CLKMGR_MAINPLL_OFFSET; - - /* Clock manager peripheral PLL base address. */ - clock_agilex5_ll.peripll_addr = clock_agilex5_ll.base_addr + CLKMGR_PERPLL_OFFSET; - - /* Clock manager control module base address. */ - clock_agilex5_ll.ctl_addr = clock_agilex5_ll.base_addr + CLKMGR_INTEL_OFFSET; -} - /* Extract reference clock from platform clock source */ -static uint32_t get_ref_clk(uint32_t pllglob) +static uint32_t get_ref_clk(mm_reg_t pllglob_reg, mm_reg_t pllm_reg) { - uint32_t arefclkdiv, ref_clk; - uint32_t scr_reg; + uint32_t arefclkdiv = 0U; + uint32_t ref_clk = 0U; + uint32_t mdiv = 0U; + uint32_t pllglob_val = 0U; + uint32_t pllm_val = 0U; + + /* Read pllglob and pllm registers */ + pllglob_val = sys_read32(pllglob_reg); + pllm_val = sys_read32(pllm_reg); /* * Based on the clock source, read the values from System Manager boot * scratch registers. These values are filled by boot loader based on * hand-off data. */ - switch (CLKMGR_PSRC(pllglob)) { - case CLKMGR_PLLGLOB_PSRC_EOSC1: - scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1); - ref_clk = sys_read32(scr_reg); + switch (CLKCTRL_PSRC(pllglob_val)) { + case CLKCTRL_PLLGLOB_PSRC_EOSC1: + ref_clk = sys_read32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1)); break; - case CLKMGR_PLLGLOB_PSRC_INTOSC: - ref_clk = CLKMGR_INTOSC_HZ; + case CLKCTRL_PLLGLOB_PSRC_INTOSC: + ref_clk = CLKCTRL_INTOSC_HZ; break; - case CLKMGR_PLLGLOB_PSRC_F2S: - scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2); - ref_clk = sys_read32(scr_reg); + case CLKCTRL_PLLGLOB_PSRC_F2S: + ref_clk = sys_read32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2)); break; default: ref_clk = 0; - LOG_ERR("Invalid VCO input clock source"); + __ASSERT(0, "Invalid input clock source"); break; } - /* Reference clock divider, to get the effective reference clock. */ - arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob); + /* Get reference clock divider */ + arefclkdiv = CLKCTRL_PLLGLOB_AREFCLKDIV(pllglob_val); + __ASSERT(arefclkdiv != 0, "Reference clock divider is zero"); ref_clk /= arefclkdiv; + /* Feedback clock divider */ + mdiv = CLKCTRL_PLLM_MDIV(pllm_val); + ref_clk *= mdiv; + + LOG_DBG("%s: ref_clk %u\n", __func__, ref_clk); + return ref_clk; } /* Calculate clock frequency based on parameter */ -static uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc) +static uint32_t get_clk_freq(mm_reg_t psrc_reg, mm_reg_t mainpllc_reg, + mm_reg_t perpllc_reg) { - uint32_t clk_psrc, mdiv, ref_clk; - uint32_t pllm_reg, pllc_reg, pllc_div, pllglob_reg; + uint32_t clock_val = 0U; + uint32_t clk_psrc = 0U; + uint32_t pllcx_div = 0U; + + /* + * Select source for the active 5:1 clock selection when the PLL + * is not bypassed + */ + clk_psrc = sys_read32(psrc_reg); + switch (GET_CLKCTRL_CLKSRC(clk_psrc)) { + case CLKCTRL_CLKSRC_MAIN: + clock_val = get_ref_clk(CLKCTRL_MAINPLL(PLLGLOB), CLKCTRL_MAINPLL(PLLM)); + pllcx_div = (sys_read32(mainpllc_reg) & CLKCTRL_PLLCX_DIV_MSK); + __ASSERT(pllcx_div != 0, "Main PLLC clock divider is zero"); + clock_val /= pllcx_div; + break; + + case CLKCTRL_CLKSRC_PER: + clock_val = get_ref_clk(CLKCTRL_PERPLL(PLLGLOB), CLKCTRL_PERPLL(PLLM)); + pllcx_div = (sys_read32(perpllc_reg) & CLKCTRL_PLLCX_DIV_MSK); + __ASSERT(pllcx_div != 0, "Peripheral PLLC clock divider is zero"); + clock_val /= pllcx_div; + break; - clk_psrc = sys_read32(clock_agilex5_ll.mainpll_addr + psrc_reg); + case CLKCTRL_CLKSRC_OSC1: + clock_val = sys_read32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1)); + break; - switch (CLKMGR_PSRC(clk_psrc)) { - case CLKMGR_PSRC_MAIN: - pllm_reg = clock_agilex5_ll.mainpll_addr + CLKMGR_MAINPLL_PLLM; - pllc_reg = clock_agilex5_ll.mainpll_addr + main_pllc; - pllglob_reg = clock_agilex5_ll.mainpll_addr + CLKMGR_MAINPLL_PLLGLOB; + case CLKCTRL_CLKSRC_INTOSC: + clock_val = CLKCTRL_INTOSC_HZ; break; - case CLKMGR_PSRC_PER: - pllm_reg = clock_agilex5_ll.peripll_addr + CLKMGR_PERPLL_PLLM; - pllc_reg = clock_agilex5_ll.peripll_addr + per_pllc; - pllglob_reg = clock_agilex5_ll.peripll_addr + CLKMGR_PERPLL_PLLGLOB; + case CLKCTRL_CLKSRC_FPGA: + clock_val = sys_read32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2)); break; default: - return 0; + __ASSERT(0, "Invalid clock source select"); + break; } - ref_clk = get_ref_clk(sys_read32(pllglob_reg)); - mdiv = CLKMGR_PLLM_MDIV(sys_read32(pllm_reg)); - ref_clk *= mdiv; + LOG_DBG("%s: clock source %lu and its value %u\n", + __func__, GET_CLKCTRL_CLKSRC(clk_psrc), clock_val); - /* Clock slice divider ration in binary code. */ - pllc_div = CLKMGR_PLLC_DIV(sys_read32(pllc_reg)); + return clock_val; +} - return ref_clk / pllc_div; +/* Get L3 free clock */ +static uint32_t get_l3_main_free_clk(void) +{ + return get_clk_freq(CLKCTRL_MAINPLL(NOCCLK), + CLKCTRL_MAINPLL(PLLC3), + CLKCTRL_PERPLL(PLLC1)); } -/* Return L3 interconnect clock */ -uint32_t get_l3_clk(void) +/* Get L4 mp clock */ +static uint32_t get_l4_mp_clk(void) +{ + uint32_t l3_main_free_clk = get_l3_main_free_clk(); + uint32_t mainpll_nocdiv_l4mp = BIT(GET_CLKCTRL_MAINPLL_NOCDIV_L4MP( + sys_read32(CLKCTRL_MAINPLL(NOCDIV)))); + + uint32_t l4_mp_clk = (l3_main_free_clk / mainpll_nocdiv_l4mp); + + return l4_mp_clk; +} + +/* + * Get L4 sp clock. + * "l4_sp_clk" (100MHz) will be used for slow peripherals like UART, I2C, + * Timers ...etc. + */ +static uint32_t get_l4_sp_clk(void) { - uint32_t l3_clk; + uint32_t l3_main_free_clk = get_l3_main_free_clk(); + uint32_t mainpll_nocdiv_l4sp = BIT(GET_CLKCTRL_MAINPLL_NOCDIV_L4SP( + sys_read32(CLKCTRL_MAINPLL(NOCDIV)))); - l3_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1, CLKMGR_PERPLL_PLLC1); + uint32_t l4_sp_clk = (l3_main_free_clk / mainpll_nocdiv_l4sp); - return l3_clk; + return l4_sp_clk; } -/* Calculate clock frequency to be used for mpu */ +/* Get MPU clock */ uint32_t get_mpu_clk(void) { - uint32_t mpu_clk; + uint8_t cpu_id = arch_curr_cpu()->id; + uint32_t ctr_reg = 0U; + uint32_t clock_val = 0U; + + if (cpu_id > CLKCTRL_CPU_ID_CORE1) { + clock_val = get_clk_freq(CLKCTRL_CTLGRP(CORE23CTR), + CLKCTRL_MAINPLL(PLLC0), + CLKCTRL_PERPLL(PLLC0)); + } else { + clock_val = get_clk_freq(CLKCTRL_CTLGRP(CORE01CTR), + CLKCTRL_MAINPLL(PLLC1), + CLKCTRL_PERPLL(PLLC0)); + } + + switch (cpu_id) { + case CLKCTRL_CPU_ID_CORE0: + case CLKCTRL_CPU_ID_CORE1: + ctr_reg = CLKCTRL_CTLGRP(CORE01CTR); + break; - mpu_clk = get_clk_freq(CLKMGR_MAINPLL_MPUCLK, CLKMGR_MAINPLL_PLLC0, CLKMGR_PERPLL_PLLC0); + case CLKCTRL_CPU_ID_CORE2: + ctr_reg = CLKCTRL_CTLGRP(CORE2CTR); + break; + + case CLKCTRL_CPU_ID_CORE3: + ctr_reg = CLKCTRL_CTLGRP(CORE3CTR); + break; - return mpu_clk; + default: + break; + } + + /* Division setting for ping pong counter in clock slice */ + clock_val /= 1 + (sys_read32(ctr_reg) & CLKCTRL_PLLCX_DIV_MSK); + + return clock_val; } /* Calculate clock frequency to be used for watchdog timer */ uint32_t get_wdt_clk(void) { - uint32_t l4_sys_clk; + uint32_t l3_main_free_clk = get_l3_main_free_clk(); + uint32_t mainpll_nocdiv_l4sysfreeclk = BIT(GET_CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE( + sys_read32(CLKCTRL_MAINPLL(NOCDIV)))); + uint32_t l4_sys_free_clk = (l3_main_free_clk / mainpll_nocdiv_l4sysfreeclk); - l4_sys_clk = (get_l3_clk() >> 2); - - return l4_sys_clk; + return l4_sys_free_clk; } -/* Calculate clock frequency to be used for UART driver */ +/* Get clock frequency to be used for UART driver */ uint32_t get_uart_clk(void) { - uint32_t mainpll_nocdiv, l4_sp_clk; - - mainpll_nocdiv = sys_read32(clock_agilex5_ll.mainpll_addr + CLKMGR_MAINPLL_NOCDIV); - mainpll_nocdiv = CLKMGR_MAINPLL_L4SPDIV(mainpll_nocdiv); - - l4_sp_clk = (get_l3_clk() >> mainpll_nocdiv); - - return l4_sp_clk; + return get_l4_sp_clk(); } /* Calculate clock frequency to be used for SDMMC driver */ -uint32_t get_mmc_clk(void) +uint32_t get_sdmmc_clk(void) { - uint32_t sdmmc_ctr, mmc_clk; - - mmc_clk = get_clk_freq(CLKMGR_INTEL_SDMMCCTR, CLKMGR_MAINPLL_PLLC3, CLKMGR_PERPLL_PLLC3); - - sdmmc_ctr = sys_read32(clock_agilex5_ll.ctl_addr + CLKMGR_INTEL_SDMMCCTR); - sdmmc_ctr = CLKMGR_INTEL_SDMMC_CNT(sdmmc_ctr); - mmc_clk = ((mmc_clk / sdmmc_ctr) >> 2); + uint32_t l4_mp_clk = get_l4_mp_clk(); + uint32_t mainpll_nocdiv = sys_read32(CLKCTRL_MAINPLL(NOCDIV)); + uint32_t sdmmc_clk = l4_mp_clk / BIT(GET_CLKCTRL_MAINPLL_NOCDIV_SPHY(mainpll_nocdiv)); - return mmc_clk; + return sdmmc_clk; } /* Calculate clock frequency to be used for Timer driver */ uint32_t get_timer_clk(void) { - uint32_t l4_sys_clk; + return get_l4_sp_clk(); +} + +/* Calculate clock frequency to be used for QSPI driver */ +uint32_t get_qspi_clk(void) +{ + uint32_t scr_reg, ref_clk; - l4_sys_clk = (get_l3_clk() >> 2); + scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0); + ref_clk = sys_read32(scr_reg); - return l4_sys_clk; + /* + * In ATF, the qspi clock is divided by 1000 and loaded in scratch cold register 0 + * So in Zephyr, reverting back the clock frequency by multiplying by 1000. + */ + return (ref_clk * 1000); +} + +/* Calculate clock frequency to be used for I2C driver */ +uint32_t get_i2c_clk(void) +{ + return get_l4_sp_clk(); +} + +/* Calculate clock frequency to be used for I3C driver */ +uint32_t get_i3c_clk(void) +{ + return get_l4_mp_clk(); } diff --git a/drivers/clock_control/clock_control_agilex5_ll.h b/drivers/clock_control/clock_control_agilex5_ll.h index 57c44fd9be0af..fcccc7382bed8 100644 --- a/drivers/clock_control/clock_control_agilex5_ll.h +++ b/drivers/clock_control/clock_control_agilex5_ll.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023, Intel Corporation. + * Copyright (c) 2022-2024, Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,109 +8,176 @@ #define ZEPHYR_INCLUDE_DRIVERS_CLOCK_AGILEX5_LL_H_ #include +#include #include -/* Clock manager register offsets */ -#define CLKMGR_CTRL 0x00 -#define CLKMGR_STAT 0x04 -#define CLKMGR_INTRCLR 0x14 - -/* Clock manager main PLL group register offsets */ -#define CLKMGR_MAINPLL_OFFSET 0x24 -#define CLKMGR_MAINPLL_EN 0x00 -#define CLKMGR_MAINPLL_BYPASS 0x0C -#define CLKMGR_MAINPLL_MPUCLK 0x18 -#define CLKMGR_MAINPLL_BYPASSS 0x10 -#define CLKMGR_MAINPLL_NOCCLK 0x1C -#define CLKMGR_MAINPLL_NOCDIV 0x20 -#define CLKMGR_MAINPLL_PLLGLOB 0x24 -#define CLKMGR_MAINPLL_FDBCK 0x28 -#define CLKMGR_MAINPLL_MEM 0x2C -#define CLKMGR_MAINPLL_MEMSTAT 0x30 -#define CLKMGR_MAINPLL_VCOCALIB 0x34 -#define CLKMGR_MAINPLL_PLLC0 0x38 -#define CLKMGR_MAINPLL_PLLC1 0x3C -#define CLKMGR_MAINPLL_PLLC2 0x40 -#define CLKMGR_MAINPLL_PLLC3 0x44 -#define CLKMGR_MAINPLL_PLLM 0x48 -#define CLKMGR_MAINPLL_LOSTLOCK 0x54 - -/* Clock manager peripheral PLL group register offsets */ -#define CLKMGR_PERPLL_OFFSET 0x7C -#define CLKMGR_PERPLL_EN 0x00 -#define CLKMGR_PERPLL_BYPASS 0x0C -#define CLKMGR_PERPLL_BYPASSS 0x10 -#define CLKMGR_PERPLL_EMACCTL 0x18 -#define CLKMGR_PERPLL_GPIODIV 0x1C -#define CLKMGR_PERPLL_PLLGLOB 0x20 -#define CLKMGR_PERPLL_FDBCK 0x24 -#define CLKMGR_PERPLL_MEM 0x28 -#define CLKMGR_PERPLL_MEMSTAT 0x2C -#define CLKMGR_PERPLL_VCOCALIB 0x30 -#define CLKMGR_PERPLL_PLLC0 0x34 -#define CLKMGR_PERPLL_PLLC1 0x38 -#define CLKMGR_PERPLL_PLLC2 0x3C -#define CLKMGR_PERPLL_PLLC3 0x40 -#define CLKMGR_PERPLL_PLLM 0x44 -#define CLKMGR_PERPLL_LOSTLOCK 0x50 - -/* Clock manager control/intel group register offsets */ -#define CLKMGR_INTEL_OFFSET 0xD0 -#define CLKMGR_INTEL_JTAG 0x00 -#define CLKMGR_INTEL_EMACACTR 0x4 -#define CLKMGR_INTEL_EMACBCTR 0x8 -#define CLKMGR_INTEL_EMACPTPCTR 0x0C -#define CLKMGR_INTEL_GPIODBCTR 0x10 -#define CLKMGR_INTEL_SDMMCCTR 0x14 -#define CLKMGR_INTEL_S2FUSER0CTR 0x18 -#define CLKMGR_INTEL_S2FUSER1CTR 0x1C -#define CLKMGR_INTEL_PSIREFCTR 0x20 -#define CLKMGR_INTEL_EXTCNTRST 0x24 - -/* Clock manager macros */ -#define CLKMGR_CTRL_BOOTMODE_SET_MSK 0x00000001U -#define CLKMGR_STAT_BUSY_E_BUSY 0x1 -#define CLKMGR_STAT_BUSY(x) (((x) & 0x00000001U) >> 0) -#define CLKMGR_STAT_MAINPLLLOCKED(x) (((x) & 0x00000100U) >> 8) -#define CLKMGR_STAT_PERPLLLOCKED(x) (((x) & 0x00010000U) >> 16) -#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK 0x00000004U -#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK 0x00000008U -#define CLKMGR_MAINPLL_L4SPDIV(x) (((x) >> 16) & 0x3) -#define CLKMGR_INTOSC_HZ 460000000U +/* Clock control MMIO register base address */ +#define CLKCTRL_BASE_ADDR DT_REG_ADDR(DT_NODELABEL(clock)) + +/* Clock manager/control register offsets */ +#define CLKCTRL_OFFSET 0x00 +#define CLKCTRL_CTRL 0x00 +#define CLKCTRL_STAT 0x04 +#define CLKCTRL_TESTIOCTRL 0x08 +#define CLKCTRL_INTRGEN 0x0C +#define CLKCTRL_INTRMSK 0x10 +#define CLKCTRL_INTRCLR 0x14 +#define CLKCTRL_INTRSTS 0x18 +#define CLKCTRL_INTRSTK 0x1C +#define CLKCTRL_INTRRAW 0x20 + +#define CLKCTRL(x) (CLKCTRL_BASE_ADDR + CLKCTRL_##_reg) + +/* Clock manager/control main PLL group register offsets */ +#define CLKCTRL_MAINPLL_OFFSET 0x24 +#define CLKCTRL_MAINPLL_EN 0x00 +#define CLKCTRL_MAINPLL_ENS 0x04 +#define CLKCTRL_MAINPLL_ENR 0x08 +#define CLKCTRL_MAINPLL_BYPASS 0x0C +#define CLKCTRL_MAINPLL_BYPASSS 0x10 +#define CLKCTRL_MAINPLL_BYPASSR 0x14 +#define CLKCTRL_MAINPLL_NOCCLK 0x1C +#define CLKCTRL_MAINPLL_NOCDIV 0x20 +#define CLKCTRL_MAINPLL_PLLGLOB 0x24 +#define CLKCTRL_MAINPLL_FDBCK 0x28 +#define CLKCTRL_MAINPLL_MEM 0x2C +#define CLKCTRL_MAINPLL_MEMSTAT 0x30 +#define CLKCTRL_MAINPLL_VCOCALIB 0x34 +#define CLKCTRL_MAINPLL_PLLC0 0x38 +#define CLKCTRL_MAINPLL_PLLC1 0x3C +#define CLKCTRL_MAINPLL_PLLC2 0x40 +#define CLKCTRL_MAINPLL_PLLC3 0x44 +#define CLKCTRL_MAINPLL_PLLM 0x48 +#define CLKCTRL_MAINPLL_FHOP 0x4C +#define CLKCTRL_MAINPLL_SSC 0x50 +#define CLKCTRL_MAINPLL_LOSTLOCK 0x54 + +#define CLKCTRL_MAINPLL_BASE_ADDR (CLKCTRL_BASE_ADDR + CLKCTRL_MAINPLL_OFFSET) +#define CLKCTRL_MAINPLL(_reg) (CLKCTRL_MAINPLL_BASE_ADDR + CLKCTRL_MAINPLL_##_reg) + +/* Clock manager/control peripheral PLL group register offsets */ +#define CLKCTRL_PERPLL_OFFSET 0x7C +#define CLKCTRL_PERPLL_EN 0x00 +#define CLKCTRL_PERPLL_ENS 0x04 +#define CLKCTRL_PERPLL_ENR 0x08 +#define CLKCTRL_PERPLL_BYPASS 0x0C +#define CLKCTRL_PERPLL_BYPASSS 0x10 +#define CLKCTRL_PERPLL_BYPASSR 0x14 +#define CLKCTRL_PERPLL_EMACCTL 0x18 +#define CLKCTRL_PERPLL_GPIODIV 0x1C +#define CLKCTRL_PERPLL_PLLGLOB 0x20 +#define CLKCTRL_PERPLL_FDBCK 0x24 +#define CLKCTRL_PERPLL_MEM 0x28 +#define CLKCTRL_PERPLL_MEMSTAT 0x2C +#define CLKCTRL_PERPLL_VCOCALIB 0x30 +#define CLKCTRL_PERPLL_PLLC0 0x34 +#define CLKCTRL_PERPLL_PLLC1 0x38 +#define CLKCTRL_PERPLL_PLLC2 0x3C +#define CLKCTRL_PERPLL_PLLC3 0x40 +#define CLKCTRL_PERPLL_PLLM 0x44 +#define CLKCTRL_PERPLL_FHOP 0x48 +#define CLKCTRL_PERPLL_SSC 0x4C +#define CLKCTRL_PERPLL_LOSTLOCK 0x50 + +#define CLKCTRL_PERPLL_BASE_ADDR (CLKCTRL_BASE_ADDR + CLKCTRL_PERPLL_OFFSET) +#define CLKCTRL_PERPLL(_reg) (CLKCTRL_PERPLL_BASE_ADDR + CLKCTRL_PERPLL_##_reg) + +/* Clock manager/control controller group register offsets */ +#define CLKCTRL_CTLGRP_OFFSET 0xD0 +#define CLKCTRL_CTLGRP_JTAG 0x00 +#define CLKCTRL_CTLGRP_EMACACTR 0x04 +#define CLKCTRL_CTLGRP_EMACBCTR 0x08 +#define CLKCTRL_CTLGRP_EMACPTPCTR 0x0C +#define CLKCTRL_CTLGRP_GPIODBCTR 0x10 +#define CLKCTRL_CTLGRP_S2FUSER0CTR 0x18 +#define CLKCTRL_CTLGRP_S2FUSER1CTR 0x1C +#define CLKCTRL_CTLGRP_PSIREFCTR 0x20 +#define CLKCTRL_CTLGRP_EXTCNTRST 0x24 +#define CLKCTRL_CTLGRP_USB31CTR 0x28 +#define CLKCTRL_CTLGRP_DSUCTR 0x2C +#define CLKCTRL_CTLGRP_CORE01CTR 0x30 +#define CLKCTRL_CTLGRP_CORE23CTR 0x34 +#define CLKCTRL_CTLGRP_CORE2CTR 0x38 +#define CLKCTRL_CTLGRP_CORE3CTR 0x3C +#define CLKCTRL_CTLGRP_SRL_CON_PLLCTR 0x40 + +#define CLKCTRL_CTLGRP_BASE_ADDR (CLKCTRL_BASE_ADDR + CLKCTRL_CTLGRP_OFFSET) +#define CLKCTRL_CTLGRP(_reg) (CLKCTRL_CTLGRP_BASE_ADDR + CLKCTRL_CTLGRP_##_reg) + + +/* Clock manager/control macros */ +#define CLKCTRL_CTRL_BOOTMODE_SET_MSK 0x00000001U +#define CLKCTRL_STAT_BUSY_E_BUSY 0x1 +#define CLKCTRL_STAT_BUSY(x) (((x) & 0x00000001U) >> 0) +#define CLKCTRL_STAT_MAINPLLLOCKED(x) (((x) & 0x00000100U) >> 8) +#define CLKCTRL_STAT_PERPLLLOCKED(x) (((x) & 0x00010000U) >> 16) +#define CLKCTRL_INTRCLR_MAINLOCKLOST_SET_MSK 0x00000004U +#define CLKCTRL_INTRCLR_PERLOCKLOST_SET_MSK 0x00000008U +#define CLKCTRL_MAINPLL_L4SPDIV(x) (((x) >> 16) & 0x3) +#define CLKCTRL_INTOSC_HZ 460000000U + +#define CLKCTRL_CLKSRC_MASK GENMASK(18, 16) +#define CLKCTRL_CLKSRC_OFFSET 16 +#define CLKCTRL_CLKSRC_MAIN 0 +#define CLKCTRL_CLKSRC_PER 1 +#define CLKCTRL_CLKSRC_OSC1 2 +#define CLKCTRL_CLKSRC_INTOSC 3 +#define CLKCTRL_CLKSRC_FPGA 4 +#define CLKCTRL_PLLCX_DIV_MSK GENMASK(10, 0) +#define GET_CLKCTRL_CLKSRC(x) (((x) & CLKCTRL_CLKSRC_MASK) >> \ + CLKCTRL_CLKSRC_OFFSET) /* Shared Macros */ -#define CLKMGR_PSRC(x) (((x) & 0x00030000U) >> 16) -#define CLKMGR_PSRC_MAIN 0 -#define CLKMGR_PSRC_PER 1 +#define CLKCTRL_PSRC(x) (((x) & 0x00030000U) >> 16) +#define CLKCTRL_PSRC_MAIN 0 +#define CLKCTRL_PSRC_PER 1 -#define CLKMGR_PLLGLOB_PSRC_EOSC1 0x0 -#define CLKMGR_PLLGLOB_PSRC_INTOSC 0x1 -#define CLKMGR_PLLGLOB_PSRC_F2S 0x2 +#define CLKCTRL_PLLGLOB_PSRC_EOSC1 0x0 +#define CLKCTRL_PLLGLOB_PSRC_INTOSC 0x1 +#define CLKCTRL_PLLGLOB_PSRC_F2S 0x2 -#define CLKMGR_PLLM_MDIV(x) ((x) & 0x000003FFU) -#define CLKMGR_PLLGLOB_PD_SET_MSK 0x00000001U -#define CLKMGR_PLLGLOB_RST_SET_MSK 0x00000002U +#define CLKCTRL_PLLM_MDIV(x) ((x) & 0x000003FFU) +#define CLKCTRL_PLLGLOB_PD_SET_MSK 0x00000001U +#define CLKCTRL_PLLGLOB_RST_SET_MSK 0x00000002U -#define CLKMGR_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003F00) >> 8) -#define CLKMGR_PLLGLOB_AREFCLKDIV(x) (((x) & 0x00000F00) >> 8) -#define CLKMGR_PLLGLOB_DREFCLKDIV(x) (((x) & 0x00003000) >> 12) +#define CLKCTRL_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003F00) >> 8) +#define CLKCTRL_PLLGLOB_AREFCLKDIV(x) (((x) & 0x00000F00) >> 8) +#define CLKCTRL_PLLGLOB_DREFCLKDIV(x) (((x) & 0x00003000) >> 12) -#define CLKMGR_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003FF) -#define CLKMGR_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00FF0000) +#define CLKCTRL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003FF) +#define CLKCTRL_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00FF0000) -#define CLKMGR_CLR_LOSTLOCK_BYPASS 0x20000000U -#define CLKMGR_PLLC_DIV(x) ((x) & 0x7FF) -#define CLKMGR_INTEL_SDMMC_CNT(x) (((x) & 0x7FF) + 1) +#define CLKCTRL_CLR_LOSTLOCK_BYPASS 0x20000000U +#define CLKCTRL_PLLC_DIV(x) ((x) & 0x7FF) +#define CLKCTRL_CTRL_SDMMC_CNT(x) (((x) & 0x7FF) + 1) -/** - * @brief Initialize the low layer clock control driver - * - * @param base_addr : Clock control device MMIO base address - * - * @return void - */ -void clock_agilex5_ll_init(mm_reg_t base_addr); +#define CLKCTRL_CPU_ID_CORE0 0 +#define CLKCTRL_CPU_ID_CORE1 1 +#define CLKCTRL_CPU_ID_CORE2 2 +#define CLKCTRL_CPU_ID_CORE3 3 + + +#define CLKCTRL_MAINPLL_NOCDIV_L4MP_MASK GENMASK(5, 4) +#define CLKCTRL_MAINPLL_NOCDIV_L4MP_OFFSET 4 +#define GET_CLKCTRL_MAINPLL_NOCDIV_L4MP(x) (((x) & CLKCTRL_MAINPLL_NOCDIV_L4MP_MASK) >> \ + CLKCTRL_MAINPLL_NOCDIV_L4MP_OFFSET) + +#define CLKCTRL_MAINPLL_NOCDIV_L4SP_MASK GENMASK(7, 6) +#define CLKCTRL_MAINPLL_NOCDIV_L4SP_OFFSET 6 +#define GET_CLKCTRL_MAINPLL_NOCDIV_L4SP(x) (((x) & CLKCTRL_MAINPLL_NOCDIV_L4SP_MASK) >> \ + CLKCTRL_MAINPLL_NOCDIV_L4SP_OFFSET) + + +#define CLKCTRL_MAINPLL_NOCDIV_SPHY_MASK GENMASK(17, 16) +#define CLKCTRL_MAINPLL_NOCDIV_SPHY_OFFSET 16 +#define GET_CLKCTRL_MAINPLL_NOCDIV_SPHY(x) (((x) & CLKCTRL_MAINPLL_NOCDIV_SPHY_MASK) >> \ + CLKCTRL_MAINPLL_NOCDIV_SPHY_OFFSET) + +#define CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE_MASK GENMASK(3, 2) +#define CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE_OFFSET 2 +#define GET_CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE(x) (((x) & CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE_MASK) >> \ + CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE_OFFSET) /** * @brief Get MPU(Micro Processor Unit) clock value @@ -146,7 +213,7 @@ uint32_t get_uart_clk(void); * * @return returns MMC clock value */ -uint32_t get_mmc_clk(void); +uint32_t get_sdmmc_clk(void); /** * @brief Get Timer peripheral clock value @@ -157,4 +224,31 @@ uint32_t get_mmc_clk(void); */ uint32_t get_timer_clk(void); +/** + * @brief Get QSPI peripheral clock value + * + * @param void + * + * @return returns QSPI clock value + */ +uint32_t get_qspi_clk(void); + +/** + * @brief Get I2C peripheral clock value + * + * @param void + * + * @return returns I2C clock value + */ +uint32_t get_i2c_clk(void); + +/** + * @brief Get I3C peripheral clock value + * + * @param void + * + * @return returns I3C clock value + */ +uint32_t get_i3c_clk(void); + #endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_AGILEX5_LL_H_ */ diff --git a/drivers/clock_control/clock_control_esp32.c b/drivers/clock_control/clock_control_esp32.c index e9f556d812d16..902f186c10e57 100644 --- a/drivers/clock_control/clock_control_esp32.c +++ b/drivers/clock_control/clock_control_esp32.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2020 Mohamed ElShahawi. - * Copyright (c) 2021-2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2021-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -161,6 +161,7 @@ static void esp32_clock_perip_init(void) } } #else +#if !defined(CONFIG_SOC_ESP32_APPCPU) && !defined(CONFIG_SOC_ESP32S3_APPCPU) static void esp32_clock_perip_init(void) { uint32_t common_perip_clk; @@ -168,10 +169,6 @@ static void esp32_clock_perip_init(void) uint32_t wifi_bt_sdio_clk; #if !defined(CONFIG_SOC_SERIES_ESP32) uint32_t common_perip_clk1; -#endif - /* Avoid APPCPU to mess with the clocks. */ -#if defined(CONFIG_SOC_ESP32_APPCPU) || defined(CONFIG_SOC_ESP32S3_APPCPU) - return; #endif /* For reason that only reset CPU, do not disable the clocks * that have been enabled before reset. @@ -196,10 +193,10 @@ static void esp32_clock_perip_init(void) common_perip_clk = #if defined(CONFIG_SOC_SERIES_ESP32C2) SYSTEM_SPI2_CLK_EN | -#if ESP_CONSOLE_UART_NUM != 0 +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 SYSTEM_UART_CLK_EN | #endif -#if ESP_CONSOLE_UART_NUM != 1 +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 SYSTEM_UART1_CLK_EN | #endif SYSTEM_LEDC_CLK_EN | @@ -208,14 +205,14 @@ static void esp32_clock_perip_init(void) #elif (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) SYSTEM_WDG_CLK_EN | SYSTEM_I2S0_CLK_EN | -#if ESP_CONSOLE_UART_NUM != 0 +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 SYSTEM_UART_CLK_EN | #endif -#if ESP_CONSOLE_UART_NUM != 1 +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 SYSTEM_UART1_CLK_EN | #endif #if defined(CONFIG_SOC_SERIES_ESP32S3) -#if ESP_CONSOLE_UART_NUM != 2 +#if CONFIG_ESP_CONSOLE_UART_NUM != 2 SYSTEM_UART2_CLK_EN | #endif SYSTEM_USB_CLK_EN | @@ -316,23 +313,23 @@ static void esp32_clock_perip_init(void) common_perip_clk |= #if defined(CONFIG_SOC_SERIES_ESP32C2) SYSTEM_SPI2_CLK_EN | -#if ESP_CONSOLE_UART_NUM != 0 +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 SYSTEM_UART_CLK_EN | #endif -#if ESP_CONSOLE_UART_NUM != 1 +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 SYSTEM_UART1_CLK_EN | #endif SYSTEM_I2C_EXT0_CLK_EN; #elif (defined(CONFIG_SOC_SERIES_ESP32C3) || defined(CONFIG_SOC_SERIES_ESP32S3)) SYSTEM_I2S0_CLK_EN | -#if ESP_CONSOLE_UART_NUM != 0 +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 SYSTEM_UART_CLK_EN | #endif -#if ESP_CONSOLE_UART_NUM != 1 +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 SYSTEM_UART1_CLK_EN | #endif #if defined(CONFIG_SOC_SERIES_ESP32S3) -#if ESP_CONSOLE_UART_NUM != 2 +#if CONFIG_ESP_CONSOLE_UART_NUM != 2 SYSTEM_UART2_CLK_EN | #endif SYSTEM_USB_CLK_EN | @@ -357,15 +354,15 @@ static void esp32_clock_perip_init(void) DPORT_UHCI1_CLK_EN | DPORT_SPI3_CLK_EN | DPORT_I2C_EXT1_CLK_EN | -#if ESP_CONSOLE_UART_NUM != 0 +#if CONFIG_ESP_CONSOLE_UART_NUM != 0 DPORT_UART_CLK_EN | #endif -#if ESP_CONSOLE_UART_NUM != 1 +#if CONFIG_ESP_CONSOLE_UART_NUM != 1 DPORT_UART1_CLK_EN | #endif #if defined(CONFIG_SOC_SERIES_ESP32) DPORT_SPI_DMA_CLK_EN | -#if ESP_CONSOLE_UART_NUM != 2 +#if CONFIG_ESP_CONSOLE_UART_NUM != 2 DPORT_UART2_CLK_EN | #endif #endif /* CONFIG_SOC_SERIES_ESP32 */ @@ -487,6 +484,7 @@ static void esp32_clock_perip_init(void) #endif } #endif +#endif static enum clock_control_status clock_control_esp32_get_status(const struct device *dev, clock_control_subsys_t sys) @@ -639,7 +637,7 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf rtc_clk_cfg.xtal_freq = cpu_cfg->xtal_freq; rtc_clk_cfg.cpu_freq_mhz = cpu_cfg->cpu_freq; - esp_rom_uart_tx_wait_idle(ESP_CONSOLE_UART_NUM); + esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); #if defined(CONFIG_SOC_SERIES_ESP32C6) rtc_clk_modem_clock_domain_active_state_icg_map_preinit(); @@ -704,15 +702,15 @@ static int esp32_cpu_clock_configure(const struct esp32_cpu_clock_config *cpu_cf esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * rtc_clk_cfg.cpu_freq_mhz / old_config.freq_mhz); -#if !defined(ESP_CONSOLE_UART_NONE) +#if defined(CONFIG_ESP_CONSOLE_UART) #if !defined(CONFIG_SOC_SERIES_ESP32C2) && !defined(CONFIG_SOC_SERIES_ESP32C6) #if defined(CONFIG_MCUBOOT) && defined(ESP_ROM_UART_CLK_IS_XTAL) uint32_t uart_clock_src_hz = (uint32_t)rtc_clk_xtal_freq_get() * MHZ(1); #else uint32_t uart_clock_src_hz = esp_clk_apb_freq(); #endif - esp_rom_uart_set_clock_baudrate(ESP_CONSOLE_UART_NUM, uart_clock_src_hz, - ESP_CONSOLE_UART_BAUDRATE); + esp_rom_uart_set_clock_baudrate(CONFIG_ESP_CONSOLE_UART_NUM, uart_clock_src_hz, + CONFIG_ESP_CONSOLE_UART_BAUDRATE); #endif #endif return 0; @@ -782,6 +780,8 @@ static int clock_control_esp32_init(const struct device *dev) return ret; } + /* Prevent APPCPU from interfering with the clock setup */ +#if !defined(CONFIG_SOC_ESP32_APPCPU) && !defined(CONFIG_SOC_ESP32S3_APPCPU) rtc_clk_fast_src_set(cfg->rtc.rtc_fast_clock_src); ret = esp32_select_rtc_slow_clk(cfg->rtc.rtc_slow_clock_src); @@ -791,6 +791,7 @@ static int clock_control_esp32_init(const struct device *dev) } esp32_clock_perip_init(); +#endif return 0; } diff --git a/drivers/clock_control/clock_control_ifx_cat1.c b/drivers/clock_control/clock_control_ifx_cat1.c index 7ed8493131cfa..071eb0e9559d5 100644 --- a/drivers/clock_control/clock_control_ifx_cat1.c +++ b/drivers/clock_control/clock_control_ifx_cat1.c @@ -533,9 +533,16 @@ static int clock_control_infineon_cat1_init(const struct device *dev) clock_source_obj = _get_hal_obj_from_ord(GET_CLK_SOURCE_ORD(clk_hf3)); clock_div = DT_PROP(DT_NODELABEL(clk_hf3), clock_div); +#if defined(CONFIG_SOC_FAMILY_INFINEON_CAT1B) && \ + defined(CONFIG_USE_INFINEON_ADC) + Cy_SysClk_ClkHfSetSource(3, CY_SYSCLK_CLKHF_IN_CLKPATH1); + Cy_SysClk_ClkHfSetDivider(3, CY_SYSCLK_CLKHF_DIVIDE_BY_2); + Cy_SysClk_ClkHfEnable(3); +#else if (_configure_clk_hf(clock_obj, clock_source_obj, &CYHAL_CLOCK_HF[3], clock_div)) { return -EIO; } +#endif #endif /* Configure the HF[4] to source defined in tree device 'clk_hf4' node */ diff --git a/drivers/clock_control/clock_control_mcux_ccm.c b/drivers/clock_control/clock_control_mcux_ccm.c index fa00eb1819298..5ae8d71d979df 100644 --- a/drivers/clock_control/clock_control_mcux_ccm.c +++ b/drivers/clock_control/clock_control_mcux_ccm.c @@ -1,5 +1,5 @@ /* - * Copyright 2017,2024 NXP + * Copyright 2017, 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -81,6 +81,18 @@ static const clock_ip_name_t sai_clocks[] = { #endif #endif /* CONFIG_DAI_NXP_SAI */ +#if defined(CONFIG_I2C_NXP_II2C) +static const clock_ip_name_t i2c_clk_root[] = { + kCLOCK_RootI2c1, + kCLOCK_RootI2c2, + kCLOCK_RootI2c3, + kCLOCK_RootI2c4, +#ifdef CONFIG_SOC_MIMX8ML8 + kCLOCK_RootI2c5, + kCLOCK_RootI2c6, +#endif +}; +#endif static int mcux_ccm_on(const struct device *dev, clock_control_subsys_t sub_system) @@ -447,6 +459,31 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, (CLOCK_GetRootPostDivider(kCLOCK_RootEcspi3)); break; #endif /* CONFIG_SPI_MCUX_ECSPI */ + +#if defined(CONFIG_I2C_NXP_II2C) + case IMX_CCM_I2C1_CLK: + case IMX_CCM_I2C2_CLK: + case IMX_CCM_I2C3_CLK: + case IMX_CCM_I2C4_CLK: +#ifdef CONFIG_SOC_MIMX8ML8 + case IMX_CCM_I2C5_CLK: + case IMX_CCM_I2C6_CLK: +#endif + { + uint32_t instance = clock_name & IMX_CCM_INSTANCE_MASK; + uint32_t i2c_mux = CLOCK_GetRootMux(i2c_clk_root[instance]); + + if (i2c_mux == 0) { + *rate = MHZ(24); + } else if (i2c_mux == 1) { + *rate = CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / + (CLOCK_GetRootPreDivider(i2c_clk_root[instance])) / + (CLOCK_GetRootPostDivider(i2c_clk_root[instance])) / + 5; /* SYSTEM PLL1 DIV5 */ + } + + } break; +#endif } return 0; diff --git a/drivers/clock_control/clock_control_mcux_ccm_rev2.c b/drivers/clock_control/clock_control_mcux_ccm_rev2.c index f5829095cbf3c..dcca3f4eca96e 100644 --- a/drivers/clock_control/clock_control_mcux_ccm_rev2.c +++ b/drivers/clock_control/clock_control_mcux_ccm_rev2.c @@ -1,5 +1,5 @@ /* - * Copyright 2021,2024 NXP + * Copyright 2021,2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -74,11 +74,24 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, #endif #endif +#ifdef CONFIG_I3C_MCUX + case IMX_CCM_I3C1_CLK: + case IMX_CCM_I3C2_CLK: + clock_root = kCLOCK_Root_I3c1 + instance; + break; +#endif + #ifdef CONFIG_SPI_MCUX_LPSPI +#if defined(CONFIG_SOC_SERIES_IMXRT118X) + case IMX_CCM_LPSPI0102_CLK: + clock_root = kCLOCK_Root_Lpspi0102 + instance; + break; +#else case IMX_CCM_LPSPI1_CLK: clock_root = kCLOCK_Root_Lpspi1 + instance; break; -#endif +#endif /* CONFIG_SOC_SERIES_IMXRT118X */ +#endif /* CONFIG_SPI_MCUX_LPSPI */ #ifdef CONFIG_UART_MCUX_LPUART #if defined(CONFIG_SOC_SERIES_IMXRT118X) @@ -110,6 +123,15 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, break; #endif +#ifdef CONFIG_DMA_MCUX_EDMA_V4 + case IMX_CCM_EDMA3_CLK: + clock_root = kCLOCK_Root_M33; + break; + case IMX_CCM_EDMA4_CLK: + clock_root = kCLOCK_Root_Wakeup_Axi; + break; +#endif + #ifdef CONFIG_PWM_MCUX #if defined(CONFIG_SOC_SERIES_IMXRT118X) case IMX_CCM_PWM_CLK: @@ -178,11 +200,29 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, return 0; #endif -#ifdef CONFIG_COUNTER_MCUX_TPM +#if defined(CONFIG_COUNTER_MCUX_TPM) || defined(CONFIG_PWM_MCUX_TPM) +#if defined(CONFIG_SOC_SERIES_IMXRT118X) + case IMX_CCM_TPM_CLK: + switch (instance) { + case 0: + clock_root = kCLOCK_Root_Bus_Aon; + break; + case 1: + clock_root = kCLOCK_Root_Tpm2; + break; + case 2: + clock_root = kCLOCK_Root_Bus_Wakeup; + break; + default: + clock_root = (kCLOCK_Root_Tpm4 + instance - 3); + } + break; +#else case IMX_CCM_TPM_CLK: clock_root = kCLOCK_Root_Tpm1 + instance; break; #endif +#endif #ifdef CONFIG_MCUX_FLEXIO case IMX_CCM_FLEXIO1_CLK: @@ -247,7 +287,7 @@ static int mcux_ccm_get_subsys_rate(const struct device *dev, default: return -EINVAL; } -#ifdef CONFIG_SOC_MIMX9352 +#if defined(CONFIG_SOC_MIMX9352) || defined(CONFIG_SOC_MIMX9131) *rate = CLOCK_GetIpFreq(clock_root); #else *rate = CLOCK_GetRootClockFreq(clock_root); diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index 8f36225cb81d0..a9e27e731c43d 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -25,7 +25,7 @@ static int mcux_lpc_syscon_clock_control_on(const struct device *dev, #endif /* defined(CONFIG_CAN_MCUX_MCAN) */ #if defined(CONFIG_COUNTER_NXP_MRT) if ((uint32_t)sub_system == MCUX_MRT_CLK) { -#if defined(CONFIG_SOC_FAMILY_LPC) || defined(CONFIG_SOC_SERIES_RW6XX) ||\ +#if defined(CONFIG_SOC_FAMILY_LPC) || defined(CONFIG_SOC_SERIES_RW6XX) || \ defined(CONFIG_SOC_SERIES_MCXN) CLOCK_EnableClock(kCLOCK_Mrt); #elif defined(CONFIG_SOC_FAMILY_NXP_IMXRT) @@ -92,12 +92,18 @@ static int mcux_lpc_syscon_clock_control_on(const struct device *dev, #if defined(CONFIG_CAN_MCUX_FLEXCAN) switch ((uint32_t)sub_system) { +#if defined(CONFIG_SOC_SERIES_MCXA) + case MCUX_FLEXCAN0_CLK: + CLOCK_EnableClock(kCLOCK_GateFLEXCAN0); + break; +#else case MCUX_FLEXCAN0_CLK: CLOCK_EnableClock(kCLOCK_Flexcan0); break; case MCUX_FLEXCAN1_CLK: CLOCK_EnableClock(kCLOCK_Flexcan1); break; +#endif /* defined(CONFIG_SOC_SERIES_MCXA) */ default: break; } @@ -236,14 +242,65 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de *rate = CLOCK_GetLPFlexCommClkFreq(9); break; + case MCUX_FLEXCOMM10_CLK: + *rate = CLOCK_GetLPFlexCommClkFreq(10); + break; + + case MCUX_FLEXCOMM11_CLK: + *rate = CLOCK_GetLPFlexCommClkFreq(11); + break; + + case MCUX_FLEXCOMM12_CLK: + *rate = CLOCK_GetLPFlexCommClkFreq(12); + break; + + case MCUX_FLEXCOMM13_CLK: + *rate = CLOCK_GetLPFlexCommClkFreq(13); + break; + + case MCUX_FLEXCOMM17_CLK: + *rate = CLOCK_GetLPFlexCommClkFreq(17); + break; + + case MCUX_FLEXCOMM18_CLK: + *rate = CLOCK_GetLPFlexCommClkFreq(18); + break; + + case MCUX_FLEXCOMM19_CLK: + *rate = CLOCK_GetLPFlexCommClkFreq(19); + break; + + case MCUX_FLEXCOMM20_CLK: + *rate = CLOCK_GetLPFlexCommClkFreq(20); + break; +#endif + + /* On RT7xx, flexcomm14 and 16 only can be LPSPI, flexcomm15 only can be I2C. */ +#if defined(CONFIG_SOC_SERIES_IMXRT7XX) && defined(CONFIG_SOC_FAMILY_NXP_IMXRT) + case MCUX_LPSPI14_CLK: + *rate = CLOCK_GetLPSpiClkFreq(14); + break; + case MCUX_LPI2C15_CLK: + *rate = CLOCK_GetLPI2cClkFreq(15); + break; + case MCUX_LPSPI16_CLK: + *rate = CLOCK_GetLPSpiClkFreq(16); + break; #endif #if (defined(FSL_FEATURE_SOC_USDHC_COUNT) && FSL_FEATURE_SOC_USDHC_COUNT) -#if CONFIG_SOC_SERIES_MCXN +#if defined(CONFIG_SOC_SERIES_MCXN) case MCUX_USDHC1_CLK: *rate = CLOCK_GetUsdhcClkFreq(); break; +#elif defined(CONFIG_SOC_SERIES_IMXRT7XX) + case MCUX_USDHC1_CLK: + *rate = CLOCK_GetUsdhcClkFreq(0); + break; + case MCUX_USDHC2_CLK: + *rate = CLOCK_GetUsdhcClkFreq(1); + break; #else case MCUX_USDHC1_CLK: *rate = CLOCK_GetSdioClkFreq(0); @@ -283,6 +340,15 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de case MCUX_CTIMER4_CLK: *rate = CLOCK_GetCTimerClkFreq(4); break; + case MCUX_CTIMER5_CLK: + *rate = CLOCK_GetCTimerClkFreq(5); + break; + case MCUX_CTIMER6_CLK: + *rate = CLOCK_GetCTimerClkFreq(6); + break; + case MCUX_CTIMER7_CLK: + *rate = CLOCK_GetCTimerClkFreq(7); + break; #endif #if defined(CONFIG_COUNTER_NXP_MRT) @@ -355,6 +421,21 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de #endif #endif /* CONFIG_MEMC_MCUX_FLEXSPI */ +#if defined(CONFIG_I2S_MCUX_SAI) + case MCUX_SAI0_CLK: +#if (FSL_FEATURE_SOC_I2S_COUNT == 1) + *rate = CLOCK_GetSaiClkFreq(); +#else + *rate = CLOCK_GetSaiClkFreq(0); +#endif + break; +#if (FSL_FEATURE_SOC_I2S_COUNT == 2) + case MCUX_SAI1_CLK: + *rate = CLOCK_GetSaiClkFreq(1); + break; +#endif +#endif /* CONFIG_I2S_MCUX_SAI */ + #ifdef CONFIG_ETH_NXP_ENET_QOS case MCUX_ENET_QOS_CLK: *rate = CLOCK_GetFreq(kCLOCK_BusClk); @@ -391,12 +472,18 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de #endif /* CONFIG_ADC_MCUX_LPADC */ #if defined(CONFIG_CAN_MCUX_FLEXCAN) +#if defined(CONFIG_SOC_SERIES_MCXA) + case MCUX_FLEXCAN0_CLK: + *rate = CLOCK_GetFlexcanClkFreq(); + break; +#else case MCUX_FLEXCAN0_CLK: *rate = CLOCK_GetFlexcanClkFreq(0); break; case MCUX_FLEXCAN1_CLK: *rate = CLOCK_GetFlexcanClkFreq(1); break; +#endif /* defined(CONFIG_SOC_SERIES_MCXA) */ #endif /* defined(CONFIG_CAN_MCUX_FLEXCAN) */ #if defined(CONFIG_MCUX_FLEXIO) @@ -428,6 +515,42 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de *rate = CLOCK_GetLpuartClkFreq(4); break; #endif /* defined(CONFIG_UART_MCUX_LPUART) */ + +#if (defined(CONFIG_I2C_MCUX_LPI2C) && CONFIG_SOC_SERIES_MCXA) + case MCUX_LPI2C0_CLK: + *rate = CLOCK_GetLpi2cClkFreq(0); + break; + case MCUX_LPI2C1_CLK: + *rate = CLOCK_GetLpi2cClkFreq(1); + break; + case MCUX_LPI2C2_CLK: + *rate = CLOCK_GetLpi2cClkFreq(2); + break; + case MCUX_LPI2C3_CLK: + *rate = CLOCK_GetLpi2cClkFreq(3); + break; +#endif /* defined(CONFIG_I2C_MCUX_LPI2C) */ + +#if defined(CONFIG_DT_HAS_NXP_XSPI_ENABLED) + case MCUX_XSPI0_CLK: + *rate = CLOCK_GetXspiClkFreq(0); + break; + case MCUX_XSPI1_CLK: + *rate = CLOCK_GetXspiClkFreq(1); + break; + case MCUX_XSPI2_CLK: + *rate = CLOCK_GetXspiClkFreq(2); + break; +#endif /* defined(CONFIG_DT_HAS_NXP_XSPI_ENABLED) */ + +#if (defined(CONFIG_SPI_MCUX_LPSPI) && CONFIG_SOC_SERIES_MCXA) + case MCUX_LPSPI0_CLK: + *rate = CLOCK_GetLpspiClkFreq(0); + break; + case MCUX_LPSPI1_CLK: + *rate = CLOCK_GetLpspiClkFreq(1); + break; +#endif /* defined(CONFIG_SPI_MCUX_LPSPI) */ } return 0; diff --git a/drivers/clock_control/clock_control_npcx.c b/drivers/clock_control/clock_control_npcx.c index db6a844d57cca..e622b7cc9bc19 100644 --- a/drivers/clock_control/clock_control_npcx.c +++ b/drivers/clock_control/clock_control_npcx.c @@ -11,7 +11,7 @@ #include #include -LOG_MODULE_REGISTER(clock_control_npcx, LOG_LEVEL_ERR); +LOG_MODULE_REGISTER(clock_control_npcx, CONFIG_CLOCK_CONTROL_LOG_LEVEL); /* Driver config */ struct npcx_pcc_config { diff --git a/drivers/clock_control/clock_control_nrf.c b/drivers/clock_control/clock_control_nrf.c index 42eeeaad8b26f..03955d3fb7d3a 100644 --- a/drivers/clock_control/clock_control_nrf.c +++ b/drivers/clock_control/clock_control_nrf.c @@ -79,6 +79,10 @@ struct nrf_clock_control_config { static atomic_t hfclk_users; static uint64_t hf_start_tstamp; static uint64_t hf_stop_tstamp; +#if CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH +/* Client to request HFXO to synthesize low frequency clock. */ +static struct onoff_client lfsynth_cli; +#endif static struct nrf_clock_control_sub_data *get_sub_data(const struct device *dev, enum clock_control_nrf_type type) @@ -202,6 +206,12 @@ static void lfclk_start(void) anomaly_132_workaround(); } +#if CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH + sys_notify_init_spinwait(&lfsynth_cli.notify); + (void)onoff_request(z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF), + &lfsynth_cli); +#endif + nrfx_clock_lfclk_start(); } @@ -212,6 +222,11 @@ static void lfclk_stop(void) } nrfx_clock_lfclk_stop(); + +#if CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH + (void)onoff_cancel_or_release(z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF), + &lfsynth_cli); +#endif } static void hfclk_start(void) @@ -622,6 +637,16 @@ static void clock_event_handler(nrfx_clock_evt_type_t event) __ASSERT_NO_MSG(false); } break; + case NRFX_CLOCK_EVT_PLL_STARTED: +#if NRF_CLOCK_HAS_XO_TUNE + case NRFX_CLOCK_EVT_XO_TUNED: + case NRFX_CLOCK_EVT_XO_TUNE_ERROR: + case NRFX_CLOCK_EVT_XO_TUNE_FAILED: +#endif + { + /* unhandled event */ + break; + } default: __ASSERT_NO_MSG(0); break; diff --git a/drivers/clock_control/clock_control_nrf2_common.c b/drivers/clock_control/clock_control_nrf2_common.c index f3b21a5dd1fbe..da3b6b8686350 100644 --- a/drivers/clock_control/clock_control_nrf2_common.c +++ b/drivers/clock_control/clock_control_nrf2_common.c @@ -4,6 +4,8 @@ */ #include "clock_control_nrf2_common.h" +#include +#include #include LOG_MODULE_REGISTER(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); @@ -18,12 +20,21 @@ LOG_MODULE_REGISTER(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); (idx * sizeof(array[0])) - \ offsetof(type, array[0])) +#define BICR (NRF_BICR_Type *)DT_REG_ADDR(DT_NODELABEL(bicr)) + /* * Definition of `struct clock_config_generic`. * Used to access `clock_config_*` structures in a common way. */ STRUCT_CLOCK_CONFIG(generic, ONOFF_CNT_MAX); +/* Structure used for synchronous clock request. */ +struct sync_req { + struct onoff_client cli; + struct k_sem sem; + int res; +}; + static void update_config(struct clock_config_generic *cfg) { atomic_val_t prev_flags = atomic_or(&cfg->flags, FLAG_UPDATE_NEEDED); @@ -75,6 +86,40 @@ static inline uint8_t get_index_of_highest_bit(uint32_t value) return value ? (uint8_t)(31 - __builtin_clz(value)) : 0; } +int lfosc_get_accuracy(uint16_t *accuracy) +{ + switch (nrf_bicr_lfosc_accuracy_get(BICR)) { + case NRF_BICR_LFOSC_ACCURACY_500PPM: + *accuracy = 500U; + break; + case NRF_BICR_LFOSC_ACCURACY_250PPM: + *accuracy = 250U; + break; + case NRF_BICR_LFOSC_ACCURACY_150PPM: + *accuracy = 150U; + break; + case NRF_BICR_LFOSC_ACCURACY_100PPM: + *accuracy = 100U; + break; + case NRF_BICR_LFOSC_ACCURACY_75PPM: + *accuracy = 75U; + break; + case NRF_BICR_LFOSC_ACCURACY_50PPM: + *accuracy = 50U; + break; + case NRF_BICR_LFOSC_ACCURACY_30PPM: + *accuracy = 30U; + break; + case NRF_BICR_LFOSC_ACCURACY_20PPM: + *accuracy = 20U; + break; + default: + return -EINVAL; + } + + return 0; +} + int clock_config_init(void *clk_cfg, uint8_t onoff_cnt, k_work_handler_t update_work_handler) { struct clock_config_generic *cfg = clk_cfg; @@ -159,3 +204,40 @@ int api_nosys_on_off(const struct device *dev, clock_control_subsys_t sys) return -ENOSYS; } + +static void sync_cb(struct onoff_manager *mgr, struct onoff_client *cli, uint32_t state, int res) +{ + struct sync_req *req = CONTAINER_OF(cli, struct sync_req, cli); + + req->res = res; + k_sem_give(&req->sem); +} + +int nrf_clock_control_request_sync(const struct device *dev, + const struct nrf_clock_spec *spec, + k_timeout_t timeout) +{ + struct sync_req req = { + .sem = Z_SEM_INITIALIZER(req.sem, 0, 1) + }; + int err; + + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + sys_notify_init_callback(&req.cli.notify, sync_cb); + + err = nrf_clock_control_request(dev, spec, &req.cli); + if (err < 0) { + return err; + } + + err = k_sem_take(&req.sem, timeout); + if (err < 0) { + nrf_clock_control_cancel_or_release(dev, spec, &req.cli); + return err; + } + + return req.res; +} diff --git a/drivers/clock_control/clock_control_nrf2_common.h b/drivers/clock_control/clock_control_nrf2_common.h index 858698c38ea7e..1f08e5b090f87 100644 --- a/drivers/clock_control/clock_control_nrf2_common.h +++ b/drivers/clock_control/clock_control_nrf2_common.h @@ -36,6 +36,16 @@ struct clock_onoff { struct clock_onoff onoff[_onoff_cnt]; \ } +/** + * @brief Obtain LFOSC accuracy in ppm. + * + * @param[out] accuracy Accuracy in ppm. + * + * @retval 0 On success + * @retval -EINVAL If accuracy is not configured. + */ +int lfosc_get_accuracy(uint16_t *accuracy); + /** * @brief Initializes a clock configuration structure. * diff --git a/drivers/clock_control/clock_control_nrf2_fll16m.c b/drivers/clock_control/clock_control_nrf2_fll16m.c index 1637284b3226c..cbec791aa77c6 100644 --- a/drivers/clock_control/clock_control_nrf2_fll16m.c +++ b/drivers/clock_control/clock_control_nrf2_fll16m.c @@ -8,7 +8,9 @@ #include "clock_control_nrf2_common.h" #include #include + #include +#include #include LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); @@ -23,26 +25,17 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, #define FLL16M_MODE_BYPASS 2 #define FLL16M_MODE_DEFAULT FLL16M_MODE_OPEN_LOOP -#define FLL16M_LFXO_NODE DT_INST_PHANDLE_BY_NAME(0, clocks, lfxo) #define FLL16M_HFXO_NODE DT_INST_PHANDLE_BY_NAME(0, clocks, hfxo) -#define FLL16M_HAS_LFXO DT_NODE_HAS_STATUS_OKAY(FLL16M_LFXO_NODE) - -#define FLL16M_LFXO_ACCURACY DT_PROP(FLL16M_LFXO_NODE, accuracy_ppm) #define FLL16M_HFXO_ACCURACY DT_PROP(FLL16M_HFXO_NODE, accuracy_ppm) #define FLL16M_OPEN_LOOP_ACCURACY DT_INST_PROP(0, open_loop_accuracy_ppm) #define FLL16M_CLOSED_LOOP_BASE_ACCURACY DT_INST_PROP(0, closed_loop_base_accuracy_ppm) #define FLL16M_MAX_ACCURACY FLL16M_HFXO_ACCURACY -/* Closed-loop mode uses LFXO as source if present, HFXO otherwise */ -#if FLL16M_HAS_LFXO -#define FLL16M_CLOSED_LOOP_ACCURACY (FLL16M_CLOSED_LOOP_BASE_ACCURACY + FLL16M_LFXO_ACCURACY) -#else -#define FLL16M_CLOSED_LOOP_ACCURACY (FLL16M_CLOSED_LOOP_BASE_ACCURACY + FLL16M_HFXO_ACCURACY) -#endif +#define BICR (NRF_BICR_Type *)DT_REG_ADDR(DT_NODELABEL(bicr)) /* Clock options sorted from lowest to highest accuracy */ -static const struct clock_options { +static struct clock_options { uint16_t accuracy; uint8_t mode; } clock_options[] = { @@ -51,7 +44,6 @@ static const struct clock_options { .mode = FLL16M_MODE_OPEN_LOOP, }, { - .accuracy = FLL16M_CLOSED_LOOP_ACCURACY, .mode = FLL16M_MODE_CLOSED_LOOP, }, { @@ -233,6 +225,27 @@ static int api_get_rate_fll16m(const struct device *dev, static int fll16m_init(const struct device *dev) { struct fll16m_dev_data *dev_data = dev->data; + nrf_bicr_lfosc_mode_t lfosc_mode; + + clock_options[1].accuracy = FLL16M_CLOSED_LOOP_BASE_ACCURACY; + + /* Closed-loop mode uses LFXO as source if present, HFXO otherwise */ + lfosc_mode = nrf_bicr_lfosc_mode_get(BICR); + + if (lfosc_mode != NRF_BICR_LFOSC_MODE_UNCONFIGURED && + lfosc_mode != NRF_BICR_LFOSC_MODE_DISABLED) { + int ret; + uint16_t accuracy; + + ret = lfosc_get_accuracy(&accuracy); + if (ret < 0) { + return ret; + } + + clock_options[1].accuracy += accuracy; + } else { + clock_options[1].accuracy += FLL16M_HFXO_ACCURACY; + } return clock_config_init(&dev_data->clk_cfg, ARRAY_SIZE(dev_data->clk_cfg.onoff), diff --git a/drivers/clock_control/clock_control_nrf2_global_hsfll.c b/drivers/clock_control/clock_control_nrf2_global_hsfll.c new file mode 100644 index 0000000000000..69053c99ff2f4 --- /dev/null +++ b/drivers/clock_control/clock_control_nrf2_global_hsfll.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_hsfll_global + +#include "clock_control_nrf2_common.h" +#include +#include +#include + +#include +LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + +#define GLOBAL_HSFLL_CLOCK_FREQUENCIES \ + DT_INST_PROP(0, supported_clock_frequencies) + +#define GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(idx) \ + DT_INST_PROP_BY_IDX(0, supported_clock_frequencies, idx) + +#define GLOBAL_HSFLL_CLOCK_FREQUENCIES_SIZE \ + DT_INST_PROP_LEN(0, supported_clock_frequencies) + +#define GLOBAL_HSFLL_FREQ_REQ_TIMEOUT \ + K_MSEC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_TIMEOUT_MS) + +#define GLOBAL_HSFLL_INIT_LOW_REQ \ + CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_REQ_LOW_FREQ + +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_SIZE == 4); +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(0) == 64000000); +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(1) == 128000000); +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(2) == 256000000); +BUILD_ASSERT(GLOBAL_HSFLL_CLOCK_FREQUENCIES_IDX(3) == 320000000); +BUILD_ASSERT(GDFS_FREQ_COUNT == 4); +BUILD_ASSERT(GDFS_FREQ_HIGH == 0); +BUILD_ASSERT(GDFS_FREQ_MEDHIGH == 1); +BUILD_ASSERT(GDFS_FREQ_MEDLOW == 2); +BUILD_ASSERT(GDFS_FREQ_LOW == 3); + +struct global_hsfll_dev_config { + uint32_t clock_frequencies[GLOBAL_HSFLL_CLOCK_FREQUENCIES_SIZE]; +}; + +struct global_hsfll_dev_data { + STRUCT_CLOCK_CONFIG(global_hsfll, GLOBAL_HSFLL_CLOCK_FREQUENCIES_SIZE) clk_cfg; + const struct device *dev; + struct k_work evt_work; + nrfs_gdfs_evt_type_t evt; + struct k_work_delayable timeout_dwork; + +#if GLOBAL_HSFLL_INIT_LOW_REQ + struct k_sem evt_sem; +#endif /* GLOBAL_HSFLL_INIT_LOW_REQ */ +}; + +static uint32_t global_hsfll_get_max_clock_frequency(const struct device *dev) +{ + const struct global_hsfll_dev_config *dev_config = dev->config; + + return dev_config->clock_frequencies[ARRAY_SIZE(dev_config->clock_frequencies) - 1]; +} + +static struct onoff_manager *global_hsfll_find_mgr(const struct device *dev, + const struct nrf_clock_spec *spec) +{ + struct global_hsfll_dev_data *dev_data = dev->data; + const struct global_hsfll_dev_config *dev_config = dev->config; + uint32_t frequency; + + if (!spec) { + return &dev_data->clk_cfg.onoff[0].mgr; + } + + if (spec->accuracy || spec->precision) { + LOG_ERR("invalid specification of accuracy or precision"); + return NULL; + } + + frequency = spec->frequency == NRF_CLOCK_CONTROL_FREQUENCY_MAX + ? global_hsfll_get_max_clock_frequency(dev) + : spec->frequency; + + for (uint8_t i = 0; i < ARRAY_SIZE(dev_config->clock_frequencies); i++) { + if (dev_config->clock_frequencies[i] < frequency) { + continue; + } + + return &dev_data->clk_cfg.onoff[i].mgr; + } + + LOG_ERR("invalid frequency"); + return NULL; +} + +static int api_request_global_hsfll(const struct device *dev, + const struct nrf_clock_spec *spec, + struct onoff_client *cli) +{ + struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec); + + if (mgr) { + return onoff_request(mgr, cli); + } + + return -EINVAL; +} + +static int api_release_global_hsfll(const struct device *dev, + const struct nrf_clock_spec *spec) +{ + struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec); + + if (mgr) { + return onoff_release(mgr); + } + + return -EINVAL; +} + +static int api_cancel_or_release_global_hsfll(const struct device *dev, + const struct nrf_clock_spec *spec, + struct onoff_client *cli) +{ + struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec); + + if (mgr) { + return onoff_cancel_or_release(mgr, cli); + } + + return -EINVAL; +} + +static DEVICE_API(nrf_clock_control, driver_api) = { + .std_api = { + .on = api_nosys_on_off, + .off = api_nosys_on_off, + }, + .request = api_request_global_hsfll, + .release = api_release_global_hsfll, + .cancel_or_release = api_cancel_or_release_global_hsfll, +}; + +static enum gdfs_frequency_setting global_hsfll_freq_idx_to_nrfs_freq(const struct device *dev, + uint8_t freq_idx) +{ + const struct global_hsfll_dev_config *dev_config = dev->config; + + return ARRAY_SIZE(dev_config->clock_frequencies) - 1 - freq_idx; +} + +static const char *global_hsfll_gdfs_freq_to_str(enum gdfs_frequency_setting freq) +{ + switch (freq) { + case GDFS_FREQ_HIGH: + return "GDFS_FREQ_HIGH"; + case GDFS_FREQ_MEDHIGH: + return "GDFS_FREQ_MEDHIGH"; + case GDFS_FREQ_MEDLOW: + return "GDFS_FREQ_MEDLOW"; + case GDFS_FREQ_LOW: + return "GDFS_FREQ_LOW"; + default: + break; + } + + return "UNKNOWN"; +} + +static void global_hsfll_work_handler(struct k_work *work) +{ + struct global_hsfll_dev_data *dev_data = + CONTAINER_OF(work, struct global_hsfll_dev_data, clk_cfg.work); + const struct device *dev = dev_data->dev; + uint8_t freq_idx; + enum gdfs_frequency_setting target_freq; + nrfs_err_t err; + + freq_idx = clock_config_update_begin(work); + target_freq = global_hsfll_freq_idx_to_nrfs_freq(dev, freq_idx); + + LOG_DBG("requesting %s", global_hsfll_gdfs_freq_to_str(target_freq)); + err = nrfs_gdfs_request_freq(target_freq, dev_data); + if (err != NRFS_SUCCESS) { + clock_config_update_end(&dev_data->clk_cfg, -EIO); + return; + } + + k_work_schedule(&dev_data->timeout_dwork, GLOBAL_HSFLL_FREQ_REQ_TIMEOUT); +} + +static void global_hsfll_evt_handler(struct k_work *work) +{ + struct global_hsfll_dev_data *dev_data = + CONTAINER_OF(work, struct global_hsfll_dev_data, evt_work); + int rc; + + k_work_cancel_delayable(&dev_data->timeout_dwork); + rc = dev_data->evt == NRFS_GDFS_EVT_FREQ_CONFIRMED ? 0 : -EIO; + clock_config_update_end(&dev_data->clk_cfg, rc); +} + +#if GLOBAL_HSFLL_INIT_LOW_REQ +static void global_hfsll_nrfs_gdfs_init_evt_handler(nrfs_gdfs_evt_t const *p_evt, void *context) +{ + struct global_hsfll_dev_data *dev_data = context; + + dev_data->evt = p_evt->type; + k_sem_give(&dev_data->evt_sem); +} +#endif /* GLOBAL_HSFLL_INIT_LOW_REQ */ + +static void global_hfsll_nrfs_gdfs_evt_handler(nrfs_gdfs_evt_t const *p_evt, void *context) +{ + struct global_hsfll_dev_data *dev_data = context; + + if (k_work_is_pending(&dev_data->evt_work)) { + return; + } + + dev_data->evt = p_evt->type; + k_work_submit(&dev_data->evt_work); +} + +static void global_hsfll_timeout_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct global_hsfll_dev_data *dev_data = + CONTAINER_OF(dwork, struct global_hsfll_dev_data, timeout_dwork); + + clock_config_update_end(&dev_data->clk_cfg, -ETIMEDOUT); +} + +static int global_hfsll_init(const struct device *dev) +{ + struct global_hsfll_dev_data *dev_data = dev->data; + nrfs_err_t err; + int rc; + + k_work_init_delayable(&dev_data->timeout_dwork, global_hsfll_timeout_handler); + k_work_init(&dev_data->evt_work, global_hsfll_evt_handler); + +#if GLOBAL_HSFLL_INIT_LOW_REQ + k_sem_init(&dev_data->evt_sem, 0, 1); + + err = nrfs_gdfs_init(global_hfsll_nrfs_gdfs_init_evt_handler); + if (err != NRFS_SUCCESS) { + return -EIO; + } + + LOG_DBG("initial request %s", global_hsfll_gdfs_freq_to_str(GDFS_FREQ_LOW)); + err = nrfs_gdfs_request_freq(GDFS_FREQ_LOW, dev_data); + if (err != NRFS_SUCCESS) { + return -EIO; + } + + rc = k_sem_take(&dev_data->evt_sem, GLOBAL_HSFLL_FREQ_REQ_TIMEOUT); + if (rc) { + return -EIO; + } + + if (dev_data->evt != NRFS_GDFS_EVT_FREQ_CONFIRMED) { + return -EIO; + } + + nrfs_gdfs_uninit(); +#endif /* GLOBAL_HSFLL_INIT_LOW_REQ */ + + rc = clock_config_init(&dev_data->clk_cfg, + ARRAY_SIZE(dev_data->clk_cfg.onoff), + global_hsfll_work_handler); + if (rc < 0) { + return rc; + } + + err = nrfs_gdfs_init(global_hfsll_nrfs_gdfs_evt_handler); + if (err != NRFS_SUCCESS) { + return -EIO; + } + + return 0; +} + +static struct global_hsfll_dev_data driver_data = { + .dev = DEVICE_DT_INST_GET(0), +}; + +static const struct global_hsfll_dev_config driver_config = { + GLOBAL_HSFLL_CLOCK_FREQUENCIES +}; + +DEVICE_DT_INST_DEFINE( + 0, + global_hfsll_init, + NULL, + &driver_data, + &driver_config, + POST_KERNEL, + CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY, + &driver_api +); diff --git a/drivers/clock_control/clock_control_nrf2_hfxo.c b/drivers/clock_control/clock_control_nrf2_hfxo.c index c48f4d9bdb400..21d3d33f7e8d5 100644 --- a/drivers/clock_control/clock_control_nrf2_hfxo.c +++ b/drivers/clock_control/clock_control_nrf2_hfxo.c @@ -12,6 +12,7 @@ LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); #include +#include BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "multiple instances not supported"); @@ -21,14 +22,36 @@ struct dev_data_hfxo { onoff_notify_fn notify; struct k_timer timer; sys_snode_t hfxo_node; +#if defined(CONFIG_ZERO_LATENCY_IRQS) + uint16_t request_count; +#endif /* CONFIG_ZERO_LATENCY_IRQS */ + k_timeout_t start_up_time; }; struct dev_config_hfxo { uint32_t fixed_frequency; uint16_t fixed_accuracy; - k_timeout_t start_up_time; }; +#define BICR (NRF_BICR_Type *)DT_REG_ADDR(DT_NODELABEL(bicr)) + +#if defined(CONFIG_ZERO_LATENCY_IRQS) +static uint32_t full_irq_lock(void) +{ + uint32_t mcu_critical_state; + + mcu_critical_state = __get_PRIMASK(); + __disable_irq(); + + return mcu_critical_state; +} + +static void full_irq_unlock(uint32_t mcu_critical_state) +{ + __set_PRIMASK(mcu_critical_state); +} +#endif /* CONFIG_ZERO_LATENCY_IRQS */ + static void hfxo_start_up_timer_handler(struct k_timer *timer) { struct dev_data_hfxo *dev_data = @@ -48,33 +71,102 @@ static void hfxo_start_up_timer_handler(struct k_timer *timer) } } +static void start_hfxo(struct dev_data_hfxo *dev_data) +{ + nrf_lrcconf_event_clear(NRF_LRCCONF010, NRF_LRCCONF_EVENT_HFXOSTARTED); + soc_lrcconf_poweron_request(&dev_data->hfxo_node, NRF_LRCCONF_POWER_MAIN); + nrf_lrcconf_task_trigger(NRF_LRCCONF010, NRF_LRCCONF_TASK_REQHFXO); +} + +static void request_hfxo(struct dev_data_hfxo *dev_data) +{ +#if defined(CONFIG_ZERO_LATENCY_IRQS) + unsigned int key; + + key = full_irq_lock(); + if (dev_data->request_count == 0) { + start_hfxo(dev_data); + } + + dev_data->request_count++; + full_irq_unlock(key); +#else + start_hfxo(dev_data); +#endif /* CONFIG_ZERO_LATENCY_IRQS */ +} + +#if IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) +void nrf_clock_control_hfxo_request(void) +{ + const struct device *dev = DEVICE_DT_INST_GET(0); + struct dev_data_hfxo *dev_data = dev->data; + + request_hfxo(dev_data); +} +#endif /* CONFIG_ZERO_LATENCY_IRQS */ + static void onoff_start_hfxo(struct onoff_manager *mgr, onoff_notify_fn notify) { struct dev_data_hfxo *dev_data = CONTAINER_OF(mgr, struct dev_data_hfxo, mgr); - const struct device *dev = DEVICE_DT_INST_GET(0); - const struct dev_config_hfxo *dev_config = dev->config; dev_data->notify = notify; - - nrf_lrcconf_event_clear(NRF_LRCCONF010, NRF_LRCCONF_EVENT_HFXOSTARTED); - soc_lrcconf_poweron_request(&dev_data->hfxo_node, NRF_LRCCONF_POWER_MAIN); - nrf_lrcconf_task_trigger(NRF_LRCCONF010, NRF_LRCCONF_TASK_REQHFXO); + request_hfxo(dev_data); /* Due to a hardware issue, the HFXOSTARTED event is currently * unreliable. Hence the timer is used to simply wait the expected * start-up time. To be removed once the hardware is fixed. */ - k_timer_start(&dev_data->timer, dev_config->start_up_time, K_NO_WAIT); + k_timer_start(&dev_data->timer, dev_data->start_up_time, K_NO_WAIT); } +static void stop_hfxo(struct dev_data_hfxo *dev_data) +{ + nrf_lrcconf_task_trigger(NRF_LRCCONF010, NRF_LRCCONF_TASK_STOPREQHFXO); + soc_lrcconf_poweron_release(&dev_data->hfxo_node, NRF_LRCCONF_POWER_MAIN); +} + +static void release_hfxo(struct dev_data_hfxo *dev_data) +{ +#if IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) + unsigned int key; + + key = full_irq_lock(); + if (dev_data->request_count < 1) { + full_irq_unlock(key); + /* Misuse of the API, release without request? */ + __ASSERT_NO_MSG(false); + /* In case asserts are disabled early return due to no requests pending */ + return; + } + + dev_data->request_count--; + if (dev_data->request_count < 1) { + stop_hfxo(dev_data); + } + + full_irq_unlock(key); +#else + stop_hfxo(dev_data); +#endif /* CONFIG_ZERO_LATENCY_IRQS */ +} + +#if IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) +void nrf_clock_control_hfxo_release(void) +{ + const struct device *dev = DEVICE_DT_INST_GET(0); + struct dev_data_hfxo *dev_data = dev->data; + + release_hfxo(dev_data); +} +#endif /* IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) */ + static void onoff_stop_hfxo(struct onoff_manager *mgr, onoff_notify_fn notify) { struct dev_data_hfxo *dev_data = CONTAINER_OF(mgr, struct dev_data_hfxo, mgr); - nrf_lrcconf_task_trigger(NRF_LRCCONF010, NRF_LRCCONF_TASK_STOPREQHFXO); - soc_lrcconf_poweron_release(&dev_data->hfxo_node, NRF_LRCCONF_POWER_MAIN); + release_hfxo(dev_data); notify(mgr, 0); } @@ -159,6 +251,7 @@ static int init_hfxo(const struct device *dev) .start = onoff_start_hfxo, .stop = onoff_stop_hfxo }; + uint32_t start_up_time; int rc; rc = onoff_manager_init(&dev_data->mgr, &transitions); @@ -166,6 +259,13 @@ static int init_hfxo(const struct device *dev) return rc; } + start_up_time = nrf_bicr_hfxo_startup_time_us_get(BICR); + if (start_up_time == NRF_BICR_HFXO_STARTUP_TIME_UNCONFIGURED) { + return -EINVAL; + } + + dev_data->start_up_time = K_USEC(start_up_time); + k_timer_init(&dev_data->timer, hfxo_start_up_timer_handler, NULL); return 0; @@ -187,7 +287,6 @@ static struct dev_data_hfxo data_hfxo; static const struct dev_config_hfxo config_hfxo = { .fixed_frequency = DT_INST_PROP(0, clock_frequency), .fixed_accuracy = DT_INST_PROP(0, accuracy_ppm), - .start_up_time = K_USEC(DT_INST_PROP(0, startup_time_us)), }; DEVICE_DT_INST_DEFINE(0, init_hfxo, NULL, diff --git a/drivers/clock_control/clock_control_nrf2_hsfll.c b/drivers/clock_control/clock_control_nrf2_hsfll.c index 4025fc6720ab9..f67373070f1a4 100644 --- a/drivers/clock_control/clock_control_nrf2_hsfll.c +++ b/drivers/clock_control/clock_control_nrf2_hsfll.c @@ -3,12 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nordic_nrf_hsfll +#define DT_DRV_COMPAT nordic_nrf_hsfll_local #include "clock_control_nrf2_common.h" #include #include -#include #include LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); @@ -183,18 +182,6 @@ static int api_cancel_or_release_hsfll(const struct device *dev, #endif } -static int api_get_rate_hsfll(const struct device *dev, - clock_control_subsys_t sys, - uint32_t *rate) -{ - ARG_UNUSED(dev); - ARG_UNUSED(sys); - - *rate = nrf_hsfll_clkctrl_mult_get(NRF_HSFLL) * MHZ(16); - - return 0; -} - static int hsfll_init(const struct device *dev) { #ifdef CONFIG_NRFS_DVFS_LOCAL_DOMAIN @@ -221,7 +208,6 @@ static DEVICE_API(nrf_clock_control, hsfll_drv_api) = { .std_api = { .on = api_nosys_on_off, .off = api_nosys_on_off, - .get_rate = api_get_rate_hsfll, }, .request = api_request_hsfll, .release = api_release_hsfll, @@ -232,6 +218,21 @@ static DEVICE_API(nrf_clock_control, hsfll_drv_api) = { static struct hsfll_dev_data hsfll_data; #endif +#ifdef CONFIG_CLOCK_CONTROL_NRF2_HSFLL_REQ_LOW_FREQ +static int dvfs_low_init(void) +{ + static const k_timeout_t timeout = K_MSEC(CONFIG_CLOCK_CONTROL_NRF2_NRFS_DVFS_TIMEOUT_MS); + static const struct device *hsfll_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_NODELABEL(cpu))); + static const struct nrf_clock_spec clk_spec = { + .frequency = HSFLL_FREQ_LOW + }; + + return nrf_clock_control_request_sync(hsfll_dev, &clk_spec, timeout); +} + +SYS_INIT(dvfs_low_init, APPLICATION, 0); +#endif + DEVICE_DT_INST_DEFINE(0, hsfll_init, NULL, COND_CODE_1(CONFIG_NRFS_DVFS_LOCAL_DOMAIN, (&hsfll_data), diff --git a/drivers/clock_control/clock_control_nrf2_lfclk.c b/drivers/clock_control/clock_control_nrf2_lfclk.c index a4261c18f475f..2cbef9b8bf094 100644 --- a/drivers/clock_control/clock_control_nrf2_lfclk.c +++ b/drivers/clock_control/clock_control_nrf2_lfclk.c @@ -8,6 +8,7 @@ #include "clock_control_nrf2_common.h" #include #include +#include #include #include @@ -16,30 +17,25 @@ LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "multiple instances not supported"); -#define LFCLK_LFXO_NODE DT_INST_PHANDLE_BY_NAME(0, clocks, lfxo) #define LFCLK_HFXO_NODE DT_INST_PHANDLE_BY_NAME(0, clocks, hfxo) -#define LFCLK_HAS_LFXO DT_NODE_HAS_STATUS_OKAY(LFCLK_LFXO_NODE) - #define LFCLK_LFLPRC_ACCURACY DT_INST_PROP(0, lflprc_accuracy_ppm) #define LFCLK_LFRC_ACCURACY DT_INST_PROP(0, lfrc_accuracy_ppm) -#define LFCLK_LFXO_ACCURACY DT_PROP(LFCLK_LFXO_NODE, accuracy_ppm) #define LFCLK_HFXO_ACCURACY DT_PROP(LFCLK_HFXO_NODE, accuracy_ppm) -#if LFCLK_HAS_LFXO -#define LFCLK_MAX_ACCURACY LFCLK_LFXO_ACCURACY -#else -#define LFCLK_MAX_ACCURACY LFCLK_HFXO_ACCURACY -#endif +#define LFCLK_MAX_OPTS 5 +#define LFCLK_DEF_OPTS 3 #define NRFS_CLOCK_TIMEOUT K_MSEC(CONFIG_CLOCK_CONTROL_NRF2_NRFS_CLOCK_TIMEOUT_MS) +#define BICR (NRF_BICR_Type *)DT_REG_ADDR(DT_NODELABEL(bicr)) + /* Clock options sorted from lowest to highest accuracy/precision */ -static const struct clock_options { +static struct clock_options { uint16_t accuracy : 15; uint16_t precision : 1; nrfs_clock_src_t src; -} clock_options[] = { +} clock_options[LFCLK_MAX_OPTS] = { { .accuracy = LFCLK_LFLPRC_ACCURACY, .precision = 0, @@ -56,43 +52,13 @@ static const struct clock_options { .precision = 1, .src = NRFS_CLOCK_SRC_LFCLK_SYNTH, }, -#if LFCLK_HAS_LFXO -#if DT_ENUM_HAS_VALUE(LFCLK_LFXO_NODE, mode, crystal) - { - .accuracy = LFCLK_LFXO_ACCURACY, - .src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE, - }, - { - .accuracy = LFCLK_LFXO_ACCURACY, - .precision = 1, - .src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE_HP, - }, -#elif DT_ENUM_HAS_VALUE(LFCLK_LFXO_NODE, mode, external_sine) - { - .accuracy = LFCLK_LFXO_ACCURACY, - .precision = 0, - .src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE, - }, - { - .accuracy = LFCLK_LFXO_ACCURACY, - .precision = 1, - .src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE_HP, - }, -#elif DT_ENUM_HAS_VALUE(LFCLK_LFXO_NODE, mode, external_square) - { - .accuracy = LFCLK_LFXO_ACCURACY, - .precision = 0, - .src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SQUARE, - }, -#else -#error "unsupported LFXO mode" -#endif -#endif }; struct lfclk_dev_data { STRUCT_CLOCK_CONFIG(lfclk, ARRAY_SIZE(clock_options)) clk_cfg; struct k_timer timer; + uint16_t max_accuracy; + uint8_t clock_options_cnt; }; struct lfclk_dev_config { @@ -156,10 +122,10 @@ static struct onoff_manager *lfclk_find_mgr(const struct device *dev, } accuracy = spec->accuracy == NRF_CLOCK_CONTROL_ACCURACY_MAX - ? LFCLK_MAX_ACCURACY + ? dev_data->max_accuracy : spec->accuracy; - for (int i = 0; i < ARRAY_SIZE(clock_options); ++i) { + for (int i = 0; i < dev_data->clock_options_cnt; ++i) { if ((accuracy && accuracy < clock_options[i].accuracy) || spec->precision > clock_options[i].precision) { @@ -227,6 +193,7 @@ static int api_get_rate_lfclk(const struct device *dev, static int lfclk_init(const struct device *dev) { struct lfclk_dev_data *dev_data = dev->data; + nrf_bicr_lfosc_mode_t lfosc_mode; nrfs_err_t res; res = nrfs_clock_init(clock_evt_handler); @@ -234,6 +201,58 @@ static int lfclk_init(const struct device *dev) return -EIO; } + dev_data->clock_options_cnt = LFCLK_DEF_OPTS; + + lfosc_mode = nrf_bicr_lfosc_mode_get(BICR); + + if (lfosc_mode == NRF_BICR_LFOSC_MODE_UNCONFIGURED || + lfosc_mode == NRF_BICR_LFOSC_MODE_DISABLED) { + dev_data->max_accuracy = LFCLK_HFXO_ACCURACY; + } else { + int ret; + + ret = lfosc_get_accuracy(&dev_data->max_accuracy); + if (ret < 0) { + LOG_ERR("LFOSC enabled with invalid accuracy"); + return ret; + } + + switch (lfosc_mode) { + case NRF_BICR_LFOSC_MODE_CRYSTAL: + clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy; + clock_options[LFCLK_MAX_OPTS - 2].precision = 0; + clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE; + + clock_options[LFCLK_MAX_OPTS - 1].accuracy = dev_data->max_accuracy; + clock_options[LFCLK_MAX_OPTS - 1].precision = 1; + clock_options[LFCLK_MAX_OPTS - 1].src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE_HP; + + dev_data->clock_options_cnt += 2; + break; + case NRF_BICR_LFOSC_MODE_EXTSINE: + clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy; + clock_options[LFCLK_MAX_OPTS - 2].precision = 0; + clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE; + + clock_options[LFCLK_MAX_OPTS - 1].accuracy = dev_data->max_accuracy; + clock_options[LFCLK_MAX_OPTS - 1].precision = 1; + clock_options[LFCLK_MAX_OPTS - 1].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE_HP; + + dev_data->clock_options_cnt += 2; + break; + case NRF_BICR_LFOSC_MODE_EXTSQUARE: + clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy; + clock_options[LFCLK_MAX_OPTS - 2].precision = 0; + clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SQUARE; + + dev_data->clock_options_cnt += 1; + break; + default: + LOG_ERR("Unexpected LFOSC mode"); + return -EINVAL; + } + } + k_timer_init(&dev_data->timer, lfclk_update_timeout_handler, NULL); return clock_config_init(&dev_data->clk_cfg, diff --git a/drivers/clock_control/clock_control_renesas_ra_cgc.c b/drivers/clock_control/clock_control_renesas_ra_cgc.c index c58f090c903eb..5a35b721943af 100644 --- a/drivers/clock_control/clock_control_renesas_ra_cgc.c +++ b/drivers/clock_control/clock_control_renesas_ra_cgc.c @@ -23,6 +23,20 @@ static volatile uint32_t *mstp_regs[] = { static volatile uint32_t *mstp_regs[] = {}; #endif +#if !defined(CONFIG_PM) +/* If a CPU clock exists in the system, it will be the source for the CPU */ +#if BSP_FEATURE_CGC_HAS_CPUCLK +#define sys_clk DT_NODELABEL(cpuclk) +#else +#define sys_clk DT_NODELABEL(iclk) +#endif + +#define SYS_CLOCK_HZ (BSP_STARTUP_SOURCE_CLOCK_HZ / DT_PROP(sys_clk, div)) + +BUILD_ASSERT(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == SYS_CLOCK_HZ, + "CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC must match the configuration of the clock " + "supplying the CPU "); +#endif static int clock_control_renesas_ra_on(const struct device *dev, clock_control_subsys_t sys) { struct clock_control_ra_subsys_cfg *subsys_clk = (struct clock_control_ra_subsys_cfg *)sys; diff --git a/drivers/clock_control/clock_control_renesas_rz_cpg.c b/drivers/clock_control/clock_control_renesas_rz_cpg.c new file mode 100644 index 0000000000000..f220cc2e4d0aa --- /dev/null +++ b/drivers/clock_control/clock_control_renesas_rz_cpg.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define DT_DRV_COMPAT renesas_rz_cpg + +static int clock_control_renesas_rz_on(const struct device *dev, clock_control_subsys_t sys) +{ + if (!dev || !sys) { + return -EINVAL; + } + + uint32_t *clock_id = (uint32_t *)sys; + + uint32_t ip = (*clock_id & RZ_IP_MASK) >> RZ_IP_SHIFT; + uint32_t ch = (*clock_id & RZ_IP_CH_MASK) >> RZ_IP_CH_SHIFT; + + switch (ip) { + case RZ_IP_GTM: + R_BSP_MODULE_START(FSP_IP_GTM, ch); + break; + case RZ_IP_GPT: + R_BSP_MODULE_START(FSP_IP_GPT, ch); + break; + case RZ_IP_SCIF: + R_BSP_MODULE_START(FSP_IP_SCIF, ch); + break; + case RZ_IP_RIIC: + R_BSP_MODULE_START(FSP_IP_RIIC, ch); + break; + case RZ_IP_RSPI: + R_BSP_MODULE_START(FSP_IP_RSPI, ch); + break; + case RZ_IP_MHU: + R_BSP_MODULE_START(FSP_IP_MHU, ch); + break; + case RZ_IP_DMAC: + R_BSP_MODULE_START(FSP_IP_DMAC, ch); + break; + case RZ_IP_CANFD: + R_BSP_MODULE_START(FSP_IP_CANFD, ch); + break; + case RZ_IP_ADC: + R_BSP_MODULE_START(FSP_IP_ADC, ch); + break; + default: + return -EINVAL; /* Invalid FSP IP Module */ + } + + return 0; +} + +static int clock_control_renesas_rz_off(const struct device *dev, clock_control_subsys_t sys) +{ + if (!dev || !sys) { + return -EINVAL; + } + + uint32_t *clock_id = (uint32_t *)sys; + + uint32_t ip = (*clock_id & RZ_IP_MASK) >> RZ_IP_SHIFT; + uint32_t ch = (*clock_id & RZ_IP_CH_MASK) >> RZ_IP_CH_SHIFT; + + switch (ip) { + case RZ_IP_GTM: + R_BSP_MODULE_STOP(FSP_IP_GTM, ch); + break; + case RZ_IP_GPT: + R_BSP_MODULE_STOP(FSP_IP_GPT, ch); + break; + case RZ_IP_SCIF: + R_BSP_MODULE_STOP(FSP_IP_SCIF, ch); + break; + case RZ_IP_RIIC: + R_BSP_MODULE_STOP(FSP_IP_RIIC, ch); + break; + case RZ_IP_RSPI: + R_BSP_MODULE_STOP(FSP_IP_RSPI, ch); + break; + case RZ_IP_MHU: + R_BSP_MODULE_STOP(FSP_IP_MHU, ch); + break; + case RZ_IP_DMAC: + R_BSP_MODULE_STOP(FSP_IP_DMAC, ch); + break; + case RZ_IP_CANFD: + R_BSP_MODULE_STOP(FSP_IP_CANFD, ch); + break; + case RZ_IP_ADC: + R_BSP_MODULE_STOP(FSP_IP_ADC, ch); + break; + default: + return -EINVAL; /* Invalid */ + } + return 0; +} + +static int clock_control_renesas_rz_get_rate(const struct device *dev, clock_control_subsys_t sys, + uint32_t *rate) +{ + if (!dev || !sys || !rate) { + return -EINVAL; + } + + uint32_t *clock_id = (uint32_t *)sys; + + fsp_priv_clock_t clk_src = (*clock_id & RZ_CLOCK_MASK) >> RZ_CLOCK_SHIFT; + uint32_t clk_div = (*clock_id & RZ_CLOCK_DIV_MASK) >> RZ_CLOCK_DIV_SHIFT; + + uint32_t clk_hz = R_FSP_SystemClockHzGet(clk_src); + *rate = clk_hz / clk_div; + return 0; +} + +static DEVICE_API(clock_control, rz_clock_control_driver_api) = { + .on = clock_control_renesas_rz_on, + .off = clock_control_renesas_rz_off, + .get_rate = clock_control_renesas_rz_get_rate, +}; + +static int clock_control_rz_init(const struct device *dev) +{ + ARG_UNUSED(dev); + return 0; +} + +DEVICE_DT_INST_DEFINE(0, clock_control_rz_init, NULL, NULL, NULL, PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &rz_clock_control_driver_api); diff --git a/drivers/clock_control/clock_control_rpi_pico.c b/drivers/clock_control/clock_control_rpi_pico.c index 40d678017e4bb..02f2c867c31ed 100644 --- a/drivers/clock_control/clock_control_rpi_pico.c +++ b/drivers/clock_control/clock_control_rpi_pico.c @@ -10,7 +10,11 @@ #include #include #include -#include +#if defined(CONFIG_SOC_SERIES_RP2040) +#include +#else +#include +#endif #include #include @@ -18,6 +22,7 @@ #include #include #include +#include /* Undefine to prevent conflicts with header definitions */ #undef pll_sys @@ -77,6 +82,7 @@ #define CLOCK_FREQ_clk_gpout1 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_gpout1), clock_frequency) #define CLOCK_FREQ_clk_gpout2 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_gpout2), clock_frequency) #define CLOCK_FREQ_clk_gpout3 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_gpout3), clock_frequency) +#define CLOCK_FREQ_clk_hstx DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_hstx), clock_frequency) #define CLOCK_FREQ_clk_ref DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_ref), clock_frequency) #define CLOCK_FREQ_clk_sys DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_sys), clock_frequency) #define CLOCK_FREQ_clk_usb DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_usb), clock_frequency) @@ -102,9 +108,16 @@ #define AUXSRC_clk_sys CLK_SYS #define AUXSRC_clk_usb CLK_USB #define AUXSRC_clk_adc CLK_ADC -#define AUXSRC_clk_rtc CLK_RTC #define AUXSRC_clk_gpin0 CLKSRC_GPIN0 #define AUXSRC_clk_gpin1 CLKSRC_GPIN1 +#if defined(CONFIG_SOC_SERIES_RP2040) +#define AUXSRC_clk_rtc CLK_RTC +#else +#define AUXSRC_pll_usb_primary_ref_opcg CLKSRC_PLL_PLL_USB_PRIMARY_REF_OPCG +#define AUXSRC_lposc LPOSC_CLKSRC +#define AUXSRC_clk_hstx CLK_HSTX +#define AUXSRC_otp_clk2fc OTP_CLK2FC +#endif #define AUXSTEM_clk_gpout0 CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_VALUE_ #define AUXSTEM_clk_gpout1 CLOCKS_CLK_GPOUT1_CTRL_AUXSRC_VALUE_ @@ -114,8 +127,12 @@ #define AUXSTEM_clk_sys CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ #define AUXSTEM_clk_usb CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_ #define AUXSTEM_clk_adc CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_ -#define AUXSTEM_clk_rtc CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_ -#define AUXSTEM_clk_peri CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_ +#define AUXSTEM_clk_peri CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_ +#if defined(CONFIG_SOC_SERIES_RP2040) +#define AUXSTEM_clk_rtc CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_ +#else +#define AUXSTEM_clk_hstx CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_ +#endif #define TUPLE_ENTRY(n, p, i) \ { \ @@ -141,7 +158,9 @@ enum rpi_pico_clkid { rpi_pico_clkid_clk_peri = RPI_PICO_CLKID_CLK_PERI, rpi_pico_clkid_clk_usb = RPI_PICO_CLKID_CLK_USB, rpi_pico_clkid_clk_adc = RPI_PICO_CLKID_CLK_ADC, +#if defined(RPI_PICO_CLKID_CLK_RTC) rpi_pico_clkid_clk_rtc = RPI_PICO_CLKID_CLK_RTC, +#endif rpi_pico_clkid_pll_sys = RPI_PICO_CLKID_PLL_SYS, rpi_pico_clkid_pll_usb = RPI_PICO_CLKID_PLL_USB, rpi_pico_clkid_xosc = RPI_PICO_CLKID_XOSC, @@ -223,9 +242,11 @@ uint64_t rpi_pico_frequency_count(const struct device *dev, clock_control_subsys case rpi_pico_clkid_clk_adc: fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_ADC; break; +#if defined(CONFIG_SOC_SERIES_RP2040) case rpi_pico_clkid_clk_rtc: fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_RTC; break; +#endif case rpi_pico_clkid_pll_sys: fc0_id = CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY; break; @@ -284,10 +305,13 @@ static int rpi_pico_rosc_write(const struct device *dev, io_rw_32 *addr, uint32_ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum rpi_pico_clkid id) { const struct clock_control_rpi_pico_config *config = dev->config; - enum rpi_pico_clkid srcid = rpi_pico_clkid_none; + enum rpi_pico_clkid srcid; - if (id == rpi_pico_clkid_clk_gpout0 || id == rpi_pico_clkid_clk_gpout1 || - id == rpi_pico_clkid_clk_gpout2 || id == rpi_pico_clkid_clk_gpout3) { + switch (id) { + case rpi_pico_clkid_clk_gpout0: + case rpi_pico_clkid_clk_gpout1: + case rpi_pico_clkid_clk_gpout2: + case rpi_pico_clkid_clk_gpout3: { const static enum rpi_pico_clkid table[] = { rpi_pico_clkid_pll_sys, rpi_pico_clkid_gpin0, @@ -298,7 +322,9 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum rpi_pico_clkid_clk_sys, rpi_pico_clkid_clk_usb, rpi_pico_clkid_clk_adc, +#if defined(CONFIG_SOC_SERIES_RP2040) rpi_pico_clkid_clk_rtc, +#endif rpi_pico_clkid_clk_ref, }; @@ -306,7 +332,9 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB); srcid = table[aux]; - } else if (id == rpi_pico_clkid_clk_ref) { + break; + } + case rpi_pico_clkid_clk_ref: { const static enum rpi_pico_clkid table[] = { rpi_pico_clkid_pll_usb, rpi_pico_clkid_gpin0, @@ -324,7 +352,9 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum } else { srcid = table[aux]; } - } else if (id == rpi_pico_clkid_clk_sys) { + break; + } + case rpi_pico_clkid_clk_sys: { const static enum rpi_pico_clkid table[] = { rpi_pico_clkid_pll_sys, rpi_pico_clkid_pll_usb, @@ -343,7 +373,9 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum } else { srcid = table[aux]; } - } else if (id == rpi_pico_clkid_clk_peri) { + break; + } + case rpi_pico_clkid_clk_peri: { const static enum rpi_pico_clkid table[] = { rpi_pico_clkid_clk_sys, rpi_pico_clkid_pll_sys, @@ -358,8 +390,16 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB); srcid = table[aux]; - } else if (id == rpi_pico_clkid_clk_usb || id == rpi_pico_clkid_clk_adc || - id == rpi_pico_clkid_clk_rtc) { + break; + } + case rpi_pico_clkid_clk_usb: + case rpi_pico_clkid_clk_adc: +#if defined(RPI_PICO_CLKID_CLK_RTC) + case rpi_pico_clkid_clk_rtc: +#else + +#endif + { const static enum rpi_pico_clkid table[] = { rpi_pico_clkid_pll_usb, rpi_pico_clkid_pll_sys, @@ -373,8 +413,16 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB); srcid = table[aux]; - } else if (id == rpi_pico_clkid_pll_sys || id == rpi_pico_clkid_pll_usb) { + break; + } + case rpi_pico_clkid_pll_sys: + case rpi_pico_clkid_pll_usb: { srcid = rpi_pico_clkid_xosc; + break; + } + default: + srcid = rpi_pico_clkid_none; + break; } return srcid; @@ -396,7 +444,9 @@ static bool rpi_pico_is_clock_enabled(const struct device *dev, enum rpi_pico_cl } else if (id == rpi_pico_clkid_clk_usb || id == rpi_pico_clkid_clk_peri || id == rpi_pico_clkid_clk_adc || +#if defined(RPI_PICO_CLKID_CLK_RTC) id == rpi_pico_clkid_clk_rtc || +#endif id == rpi_pico_clkid_clk_gpout0 || id == rpi_pico_clkid_clk_gpout1 || id == rpi_pico_clkid_clk_gpout2 || @@ -444,7 +494,9 @@ static float rpi_pico_calc_clock_freq(const struct device *dev, enum rpi_pico_cl if (id == rpi_pico_clkid_clk_sys || id == rpi_pico_clkid_clk_usb || id == rpi_pico_clkid_clk_adc || +#if defined(RPI_PICO_CLKID_CLK_RTC) id == rpi_pico_clkid_clk_rtc || +#endif id == rpi_pico_clkid_clk_ref || id == rpi_pico_clkid_clk_gpout0 || id == rpi_pico_clkid_clk_gpout1 || @@ -595,6 +647,7 @@ void rpi_pico_clkid_tuple_reorder_by_dependencies(struct rpi_pico_clkid_tuple *t static int clock_control_rpi_pico_init(const struct device *dev) { + const uint32_t cycles_per_tick = CLOCK_FREQ_xosc / 1000000; const struct clock_control_rpi_pico_config *config = dev->config; struct clock_control_rpi_pico_data *data = dev->data; clocks_hw_t *clocks_regs = config->clocks_regs; @@ -611,13 +664,23 @@ static int clock_control_rpi_pico_init(const struct device *dev) RESETS_RESET_SYSCFG_BITS | RESETS_RESET_PLL_SYS_BITS)); unreset_block_wait(RESETS_RESET_BITS & - ~(RESETS_RESET_ADC_BITS | RESETS_RESET_RTC_BITS | + ~(RESETS_RESET_ADC_BITS | +#if defined(RESETS_RESET_RTC_BITS) + RESETS_RESET_RTC_BITS | +#endif +#if defined(RESETS_RESET_HSTX_BITS) + RESETS_RESET_HSTX_BITS | +#endif RESETS_RESET_SPI0_BITS | RESETS_RESET_SPI1_BITS | RESETS_RESET_UART0_BITS | RESETS_RESET_UART1_BITS | RESETS_RESET_USBCTRL_BITS)); /* Start tick in watchdog */ - watchdog_hw->tick = ((CLOCK_FREQ_xosc/1000000) | WATCHDOG_TICK_ENABLE_BITS); + watchdog_start_tick(cycles_per_tick); +#if defined(CONFIG_SOC_SERIES_RP2350) + tick_start(TICK_TIMER0, cycles_per_tick); + tick_start(TICK_TIMER1, cycles_per_tick); +#endif clocks_regs->resus.ctrl = 0; @@ -755,8 +818,10 @@ BUILD_ASSERT(SRC_CLOCK_FREQ(clk_usb) >= CLOCK_FREQ_clk_usb, "clk_usb: clock divider is out of range"); BUILD_ASSERT(SRC_CLOCK_FREQ(clk_adc) >= CLOCK_FREQ_clk_adc, "clk_adc: clock divider is out of range"); +#if defined(CONFIG_SOC_SERIES_RP2040) BUILD_ASSERT(SRC_CLOCK_FREQ(clk_rtc) >= CLOCK_FREQ_clk_rtc, "clk_rtc: clock divider is out of range"); +#endif BUILD_ASSERT(SRC_CLOCK_FREQ(clk_peri) >= CLOCK_FREQ_clk_peri, "clk_peri: clock divider is out of range"); @@ -838,12 +903,21 @@ static const struct clock_control_rpi_pico_config clock_control_rpi_pico_config .source_rate = SRC_CLOCK_FREQ(clk_adc), .rate = CLOCK_FREQ(clk_adc), }, +#if defined(RPI_PICO_CLKID_CLK_RTC) [RPI_PICO_CLKID_CLK_RTC] = { .source = 0, .aux_source = CLOCK_AUX_SOURCE(clk_rtc), .source_rate = SRC_CLOCK_FREQ(clk_rtc), .rate = CLOCK_FREQ(clk_rtc), }, +#elif defined(RPI_PICO_CLKID_CLK_HSTX) + [RPI_PICO_CLKID_CLK_HSTX] = { + .source = 0, + .aux_source = CLOCK_AUX_SOURCE(clk_hstx), + .source_rate = SRC_CLOCK_FREQ(clk_hstx), + .rate = CLOCK_FREQ(clk_hstx), + }, +#endif }, .plls_data = { [RPI_PICO_PLL_SYS] = { diff --git a/drivers/clock_control/clock_control_rts5912_sccon.c b/drivers/clock_control/clock_control_rts5912_sccon.c new file mode 100644 index 0000000000000..686c47a4904d7 --- /dev/null +++ b/drivers/clock_control/clock_control_rts5912_sccon.c @@ -0,0 +1,247 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#define DT_DRV_COMPAT realtek_rts5912_sccon + +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(sccon, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + +#define RC25M_FREQ DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, rc25m), clock_frequency) +#define PLL_FREQ DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll), clock_frequency) + +struct rts5912_sccon_config { + uint32_t reg_base; + uint8_t sysclk_src; + uint8_t sysclk_div; +}; + +static int rts5912_periph_clock_control(const struct device *dev, clock_control_subsys_t sub_system, + bool on_off) +{ + const struct rts5912_sccon_config *const config = dev->config; + struct rts5912_sccon_subsys *subsys = (struct rts5912_sccon_subsys *)sub_system; + + SYSTEM_Type *sys_reg = (SYSTEM_Type *)config->reg_base; + + uint32_t clk_grp = subsys->clk_grp; + uint32_t clk_idx = subsys->clk_idx; + + uint32_t module_idx; + + switch (clk_grp) { + case RTS5912_SCCON_I2C: + module_idx = (clk_idx - I2C0_CLKPWR) >> 2; + + if (on_off) { + sys_reg->I2CCLK |= BIT(clk_idx); + } else { + sys_reg->I2CCLK &= ~BIT(clk_idx); + } + + LOG_DBG("Turn I2C%d clock <%s>", module_idx, on_off ? "ON" : "OFF"); + break; + case RTS5912_SCCON_UART: + if (on_off) { + sys_reg->UARTCLK = BIT(clk_idx); + } else { + sys_reg->UARTCLK &= ~BIT(clk_idx); + } + + LOG_DBG("Turn UART0 clock <%s>", on_off ? "ON" : "OFF"); + break; + case RTS5912_SCCON_ADC: + if (on_off) { + sys_reg->ADCCLK = BIT(clk_idx); + } else { + sys_reg->ADCCLK &= ~BIT(clk_idx); + } + + LOG_DBG("Turn ADC clock <%s>", on_off ? "ON" : "OFF"); + break; + case RTS5912_SCCON_PERIPH_GRP0: + if (on_off) { + sys_reg->PERICLKPWR0 |= BIT(clk_idx); + } else { + sys_reg->PERICLKPWR0 &= ~BIT(clk_idx); + } + + LOG_DBG("Turn GRP0-%d clock <%s>", clk_idx, on_off ? "ON" : "OFF"); + break; + case RTS5912_SCCON_PERIPH_GRP1: + if (on_off) { + sys_reg->PERICLKPWR1 |= BIT(clk_idx); + } else { + sys_reg->PERICLKPWR1 &= ~BIT(clk_idx); + } + + LOG_DBG("Turn GRP1-%d clock <%s>", clk_idx, on_off ? "ON" : "OFF"); + break; + case RTS5912_SCCON_PERIPH_GRP2: + if (on_off) { + sys_reg->PERICLKPWR2 |= BIT(clk_idx); + } else { + sys_reg->PERICLKPWR2 &= ~BIT(clk_idx); + } + + LOG_DBG("Turn GRP2-%d clock <%s>", clk_idx, on_off ? "ON" : "OFF"); + break; + case RTS5912_SCCON_SYS: + LOG_ERR("Not support peripheral group #%d-%d", clk_grp, clk_idx); + return -ENOTSUP; + default: + LOG_ERR("Unknown peripheral group #%d", clk_grp); + return -EINVAL; + } + + return 0; +} + +static int rts5912_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) +{ + return rts5912_periph_clock_control(dev, sub_system, true); +} + +static int rts5912_clock_control_off(const struct device *dev, clock_control_subsys_t sub_system) +{ + return rts5912_periph_clock_control(dev, sub_system, false); +} + +static int rts5912_clock_control_get_rate(const struct device *dev, + clock_control_subsys_t sub_system, uint32_t *rate) +{ + const struct rts5912_sccon_config *const config = dev->config; + struct rts5912_sccon_subsys *subsys = (struct rts5912_sccon_subsys *)sub_system; + + SYSTEM_Type *sys_reg = (SYSTEM_Type *)config->reg_base; + + uint32_t clk_grp = subsys->clk_grp; + uint32_t clk_idx = subsys->clk_idx; + uint32_t module_idx; + + uint32_t offset; + uint32_t src, divide, freq = 0; + + switch (clk_grp) { + case RTS5912_SCCON_I2C: + module_idx = (clk_idx - I2C0_CLKPWR) >> 2; + + offset = (SYSTEM_I2CCLK_I2C1CLKSRC_Pos - SYSTEM_I2CCLK_I2C0CLKSRC_Pos) * module_idx; + src = ((sys_reg->I2CCLK >> offset) & SYSTEM_I2CCLK_I2C0CLKSRC_Msk) ? PLL_FREQ + : RC25M_FREQ; + + offset = SYSTEM_I2CCLK_I2C0CLKDIV_Pos; + offset += (SYSTEM_I2CCLK_I2C1CLKDIV_Pos - SYSTEM_I2CCLK_I2C0CLKDIV_Pos) * + module_idx; + divide = (sys_reg->I2CCLK >> offset) & SYSTEM_I2CCLK_I2C0CLKDIV_Msk; + + freq = src >> divide; + + LOG_DBG("I2C%d: src<%s> divide<%ld> freq<%d>", module_idx, + (src == PLL_FREQ) ? "PLL" : "RC25M", BIT(divide), freq); + break; + case RTS5912_SCCON_UART: + src = (sys_reg->UARTCLK & SYSTEM_UARTCLK_SRC_Msk) ? PLL_FREQ : RC25M_FREQ; + divide = (sys_reg->UARTCLK & SYSTEM_UARTCLK_DIV_Msk) >> SYSTEM_UARTCLK_DIV_Pos; + freq = src >> divide; + + LOG_DBG("UART0: src<%s> divide<%ld> freq<%d>", (src == PLL_FREQ) ? "PLL" : "RC25M", + BIT(divide), freq); + break; + case RTS5912_SCCON_ADC: + src = (sys_reg->ADCCLK & SYSTEM_ADCCLK_SRC_Msk) ? RC25M_FREQ : PLL_FREQ; + divide = (sys_reg->ADCCLK & SYSTEM_ADCCLK_DIV_Msk) >> SYSTEM_ADCCLK_DIV_Pos; + + switch (divide) { + case 0: + __fallthrough; + case 1: + __fallthrough; + case 2: + __fallthrough; + case 3: + divide += 1; + freq = src / divide; + break; + case 4: + freq = src / 6; + divide = 6; + break; + case 5: + freq = src / 8; + divide = 8; + break; + case 6: + freq = src / 12; + divide = 12; + break; + case 7: + freq = src / 16; + divide = 16; + break; + default: + return -EINVAL; + } + + LOG_DBG("ADC0: src<%s> divide<%d> freq<%d>", (src == PLL_FREQ) ? "PLL" : "RC25M", + divide, freq); + break; + case RTS5912_SCCON_SYS: + src = (sys_reg->SYSCLK & SYSTEM_SYSCLK_SRC_Msk) ? PLL_FREQ : RC25M_FREQ; + divide = (sys_reg->SYSCLK & SYSTEM_SYSCLK_DIV_Msk) ? 0x01ul : 0x00ul; + freq = src >> divide; + + LOG_DBG("System Clock: src<%s> divide<%d> freq<%d>", + (src == PLL_FREQ) ? "PLL" : "RC25M", divide, freq); + break; + case RTS5912_SCCON_PERIPH_GRP0: + __fallthrough; + case RTS5912_SCCON_PERIPH_GRP1: + __fallthrough; + case RTS5912_SCCON_PERIPH_GRP2: + LOG_ERR("Not support peripheral group #%d-%d", clk_grp, clk_idx); + return -ENOTSUP; + default: + LOG_ERR("Unknown peripheral group #%d", clk_grp); + return -EINVAL; + } + + *rate = freq; + return 0; +} + +static DEVICE_API(clock_control, rts5912_clock_control_api) = { + .on = rts5912_clock_control_on, + .off = rts5912_clock_control_off, + .get_rate = rts5912_clock_control_get_rate, +}; + +static int rts5912_clock_control_init(const struct device *dev) +{ + const struct rts5912_sccon_config *const config = dev->config; + SYSTEM_Type *sys_reg = (SYSTEM_Type *)config->reg_base; + + /* Setup system clock */ + sys_reg->SYSCLK = (config->sysclk_src << SYSTEM_SYSCLK_SRC_Pos) | + (config->sysclk_div << SYSTEM_SYSCLK_DIV_Pos); + + return 0; +} + +const struct rts5912_sccon_config rts5912_sccon_config = { + .reg_base = DT_INST_REG_ADDR_BY_IDX(0, 0), + .sysclk_src = 1, + .sysclk_div = 0, +}; + +DEVICE_DT_INST_DEFINE(0, &rts5912_clock_control_init, NULL, NULL, &rts5912_sccon_config, + PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &rts5912_clock_control_api); diff --git a/drivers/clock_control/clock_control_silabs_siwx91x.c b/drivers/clock_control/clock_control_silabs_siwx91x.c new file mode 100644 index 0000000000000..44f4b3909e64f --- /dev/null +++ b/drivers/clock_control/clock_control_silabs_siwx91x.c @@ -0,0 +1,186 @@ +/* Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + * + * Poor man driver for 917 clocks. 917 includes High Performace (HP) clock + * (@46000000), Ultra Lower Power (ULP) clock (@24041400) and ULP VBAT (@24048000) + * + */ +#include +#include +#include + +#include "rsi_power_save.h" +#include "rsi_rom_ulpss_clk.h" +#include "rsi_rom_clks.h" +#include "clock_update.h" +#include "sl_si91x_clock_manager.h" + +#define DT_DRV_COMPAT silabs_siwx91x_clock + +LOG_MODULE_REGISTER(siwx91x_clock, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + +struct siwx91x_clock_data { + uint32_t enable; +}; + +static int siwx91x_clock_on(const struct device *dev, clock_control_subsys_t sys) +{ + struct siwx91x_clock_data *data = dev->data; + uintptr_t clockid = (uintptr_t)sys; + + switch (clockid) { + case SIWX91X_CLK_ULP_UART: + RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_UART); + RSI_ULPSS_UlpUartClkConfig(ULPCLK, ENABLE_STATIC_CLK, + false, ULP_UART_ULP_MHZ_RC_CLK, 1); + break; + case SIWX91X_CLK_ULP_I2C: + RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_I2C); + RSI_ULPSS_PeripheralEnable(ULPCLK, ULP_I2C_CLK, ENABLE_STATIC_CLK); + break; + case SIWX91X_CLK_ULP_DMA: + RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_UDMA); + RSI_ULPSS_PeripheralEnable(ULPCLK, ULP_UDMA_CLK, ENABLE_STATIC_CLK); + break; + case SIWX91X_CLK_UART1: + RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); + /* RSI_CLK_UsartClkConfig() calls RSI_CLK_PeripheralClkEnable(); */ + RSI_CLK_UsartClkConfig(M4CLK, ENABLE_STATIC_CLK, 0, USART1, 0, 1); + break; + case SIWX91X_CLK_UART2: + RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); + /* RSI_CLK_UsartClkConfig() calls RSI_CLK_PeripheralClkEnable(); */ + RSI_CLK_UsartClkConfig(M4CLK, ENABLE_STATIC_CLK, 0, USART2, 0, 1); + break; + case SIWX91X_CLK_I2C0: + RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); + RSI_CLK_I2CClkConfig(M4CLK, true, 0); + break; + case SIWX91X_CLK_I2C1: + RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); + RSI_CLK_I2CClkConfig(M4CLK, true, 1); + break; + case SIWX91X_CLK_DMA0: + RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); + RSI_CLK_PeripheralClkEnable(M4CLK, UDMA_CLK, ENABLE_STATIC_CLK); + break; + default: + return -EINVAL; + } + data->enable |= BIT(clockid); + + return 0; +} + +static int siwx91x_clock_off(const struct device *dev, clock_control_subsys_t sys) +{ + struct siwx91x_clock_data *data = dev->data; + uintptr_t clockid = (uintptr_t)sys; + + switch (clockid) { + case SIWX91X_CLK_ULP_I2C: + RSI_ULPSS_PeripheralDisable(ULPCLK, ULP_I2C_CLK); + break; + case SIWX91X_CLK_ULP_DMA: + RSI_ULPSS_PeripheralDisable(ULPCLK, ULP_UDMA_CLK); + break; + case SIWX91X_CLK_UART1: + RSI_CLK_PeripheralClkDisable(M4CLK, USART1_CLK); + break; + case SIWX91X_CLK_UART2: + RSI_CLK_PeripheralClkDisable(M4CLK, USART2_CLK); + break; + case SIWX91X_CLK_DMA0: + RSI_CLK_PeripheralClkDisable(M4CLK, UDMA_CLK); + break; + case SIWX91X_CLK_ULP_UART: + case SIWX91X_CLK_I2C0: + case SIWX91X_CLK_I2C1: + /* Not supported */ + return 0; + default: + return -EINVAL; + } + + data->enable &= ~BIT(clockid); + return 0; +} + +static int siwx91x_clock_get_rate(const struct device *dev, clock_control_subsys_t sys, + uint32_t *rate) +{ + uintptr_t clockid = (uintptr_t)sys; + + switch (clockid) { + case SIWX91X_CLK_ULP_UART: + *rate = RSI_CLK_GetBaseClock(ULPSS_UART); + return 0; + case SIWX91X_CLK_UART1: + *rate = RSI_CLK_GetBaseClock(M4_USART0); + return 0; + case SIWX91X_CLK_UART2: + *rate = RSI_CLK_GetBaseClock(M4_UART1); + return 0; + default: + /* For now, no other driver need clock rate */ + return -EINVAL; + } +} + +static enum clock_control_status siwx91x_clock_get_status(const struct device *dev, + clock_control_subsys_t sys) +{ + struct siwx91x_clock_data *data = dev->data; + uintptr_t clockid = (uintptr_t)sys; + + if (data->enable & BIT(clockid)) { + return CLOCK_CONTROL_STATUS_ON; + } else { + return CLOCK_CONTROL_STATUS_OFF; + } +} + +static int siwx91x_clock_init(const struct device *dev) +{ + SystemCoreClockUpdate(); + + /* Use SoC PLL at configured frequency as core clock */ + sl_si91x_clock_manager_m4_set_core_clk(M4_SOCPLLCLK, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); + + /* Use interface PLL at configured frequency as peripheral clock */ + sl_si91x_clock_manager_set_pll_freq(INFT_PLL, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, + PLL_REF_CLK_VAL_XTAL); + + /* FIXME: Currently the clock consumer use clocks without power on them. + * This should be fixed in drivers. Meanwhile, get the list of required + * clocks using DT labels. + */ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ulpi2c), okay) + siwx91x_clock_on(dev, (clock_control_subsys_t)SIWX91X_CLK_ULP_I2C); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c0), okay) + siwx91x_clock_on(dev, (clock_control_subsys_t)SIWX91X_CLK_I2C0); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) + siwx91x_clock_on(dev, (clock_control_subsys_t)SIWX91X_CLK_I2C1); +#endif + + return 0; +} + +static DEVICE_API(clock_control, siwx91x_clock_api) = { + .on = siwx91x_clock_on, + .off = siwx91x_clock_off, + .get_rate = siwx91x_clock_get_rate, + .get_status = siwx91x_clock_get_status, +}; + +#define SIWX91X_CLOCK_INIT(p) \ + static struct siwx91x_clock_data siwx91x_clock_data_##p; \ + DEVICE_DT_INST_DEFINE(p, siwx91x_clock_init, NULL, &siwx91x_clock_data_##p, NULL, \ + PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, \ + &siwx91x_clock_api); + +DT_INST_FOREACH_STATUS_OKAY(SIWX91X_CLOCK_INIT) diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index adc451d7e8c51..a2cff13d5711d 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -17,7 +17,6 @@ #include #include #include "clock_stm32_ll_common.h" -#include "clock_stm32_ll_mco.h" #include "stm32_hsem.h" /* Macros to fill up prescaler values */ @@ -123,10 +122,8 @@ int enabled_clock(uint32_t src_clk) int r = 0; switch (src_clk) { -#if defined(STM32_SRC_SYSCLK) case STM32_SRC_SYSCLK: break; -#endif /* STM32_SRC_SYSCLK */ #if defined(STM32_SRC_PCLK) case STM32_SRC_PCLK: break; @@ -215,6 +212,13 @@ int enabled_clock(uint32_t src_clk) } break; #endif /* STM32_SRC_PLL_R */ +#if defined(STM32_SRC_PLLI2S_Q) + case STM32_SRC_PLLI2S_Q: + if (!IS_ENABLED(STM32_PLLI2S_Q_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_PLLI2S_Q */ #if defined(STM32_SRC_PLLI2S_R) case STM32_SRC_PLLI2S_R: if (!IS_ENABLED(STM32_PLLI2S_R_ENABLED)) { @@ -289,7 +293,6 @@ static inline int stm32_clock_control_configure(const struct device *dev, clock_control_subsys_t sub_system, void *data) { -#if defined(STM32_SRC_SYSCLK) /* At least one alt src clock available */ struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); int err; @@ -308,16 +311,14 @@ static inline int stm32_clock_control_configure(const struct device *dev, return 0; } - sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_MASK_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); - sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_VAL_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_MASK_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_VAL_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); return 0; -#else - /* No src clock available: Not supported */ - return -ENOTSUP; -#endif } static int stm32_clock_control_get_subsys_rate(const struct device *clock, @@ -389,11 +390,9 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, *rate = ahb3_clock; break; #endif -#if defined(STM32_SRC_SYSCLK) case STM32_SRC_SYSCLK: *rate = SystemCoreClock * STM32_CORE_PRESCALER; break; -#endif #if defined(STM32_SRC_PLLCLK) & defined(STM32_SYSCLK_SRC_PLL) case STM32_SRC_PLLCLK: if (get_pllout_frequency() == 0) { @@ -426,6 +425,14 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, STM32_PLL_R_DIVISOR); break; #endif +#if defined(STM32_SRC_PLLI2S_Q) & STM32_PLLI2S_Q_ENABLED & STM32_PLLI2S_ENABLED + case STM32_SRC_PLLI2S_Q: + *rate = get_pll_div_frequency(get_pllsrc_frequency(), + STM32_PLLI2S_M_DIVISOR, + STM32_PLLI2S_N_MULTIPLIER, + STM32_PLLI2S_Q_DIVISOR); + break; +#endif /* STM32_SRC_PLLI2S_Q */ #if defined(STM32_SRC_PLLI2S_R) & STM32_PLLI2S_ENABLED case STM32_SRC_PLLI2S_R: *rate = get_pll_div_frequency(get_pllsrc_frequency(), @@ -434,6 +441,7 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, STM32_PLLI2S_R_DIVISOR); break; #endif /* STM32_SRC_PLLI2S_R */ + /* PLLSAI1x not supported yet */ /* PLLSAI2x not supported yet */ #if defined(STM32_SRC_LSE) @@ -466,10 +474,20 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, *rate = STM32_HSI48_FREQ; break; #endif /* STM32_HSI48_ENABLED */ +#if defined(STM32_CK48_ENABLED) + case STM32_SRC_CK48: + *rate = get_ck48_frequency(); + break; +#endif /* STM32_CK48_ENABLED */ + default: return -ENOTSUP; } + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } @@ -544,7 +562,11 @@ static void set_up_plls(void) stm32_clock_switch_to_hsi(); LL_RCC_SetAHBPrescaler(ahb_prescaler(1)); } + /* Disable PLL */ LL_RCC_PLL_Disable(); + while (LL_RCC_PLL_IsReady() != 0U) { + /* Wait for PLL to be disabled */ + } #endif @@ -555,6 +577,9 @@ static void set_up_plls(void) * since PLL source can be PLL2. */ LL_RCC_PLL2_Disable(); + while (LL_RCC_PLL2_IsReady() != 0U) { + /* Wait for PLL2 to be disabled */ + } config_pll2(); @@ -870,9 +895,6 @@ int stm32_clock_control_init(const struct device *dev) LL_RCC_SetADCClockSource(adc34_prescaler(STM32_ADC34_PRESCALER)); #endif - /* configure MCO1/MCO2 based on Kconfig */ - stm32_clock_control_mco_init(); - return 0; } diff --git a/drivers/clock_control/clock_stm32_ll_common.h b/drivers/clock_control/clock_stm32_ll_common.h index e13fb34c2d3e1..1988bb06544c6 100644 --- a/drivers/clock_control/clock_stm32_ll_common.h +++ b/drivers/clock_control/clock_stm32_ll_common.h @@ -27,9 +27,18 @@ #define z_pllr(v) LL_RCC_PLLR_DIV_ ## v #define pllr(v) z_pllr(v) +#if defined(RCC_PLLI2SCFGR_PLLI2SM) +/* Some stm32F4 devices have a dedicated PLL I2S with M divider */ #define z_plli2s_m(v) LL_RCC_PLLI2SM_DIV_ ## v +#else +/* Some stm32F4 devices (typ. stm32F401) have a dedicated PLL I2S with PLL M divider */ +#define z_plli2s_m(v) LL_RCC_PLLM_DIV_ ## v +#endif /* RCC_PLLI2SCFGR_PLLI2SM */ #define plli2sm(v) z_plli2s_m(v) +#define z_plli2s_q(v) LL_RCC_PLLI2SQ_DIV_ ## v +#define plli2sq(v) z_plli2s_q(v) + #define z_plli2s_r(v) LL_RCC_PLLI2SR_DIV_ ## v #define plli2sr(v) z_plli2s_r(v) @@ -52,6 +61,10 @@ void config_enable_default_clocks(void); void config_regulator_voltage(uint32_t hclk_freq); int enabled_clock(uint32_t src_clk); +#if defined(STM32_CK48_ENABLED) +uint32_t get_ck48_frequency(void); +#endif + /* functions exported to the soc power.c */ int stm32_clock_control_init(const struct device *dev); void stm32_clock_control_standby_exit(void); diff --git a/drivers/clock_control/clock_stm32_ll_h5.c b/drivers/clock_control/clock_stm32_ll_h5.c index 221147a0b589e..486861a32fd09 100644 --- a/drivers/clock_control/clock_stm32_ll_h5.c +++ b/drivers/clock_control/clock_stm32_ll_h5.c @@ -18,7 +18,6 @@ #include #include #include -#include "clock_stm32_ll_mco.h" /* Macros to fill up prescaler values */ #define z_hsi_divider(v) LL_RCC_HSI_DIV_ ## v @@ -201,8 +200,9 @@ static inline int stm32_clock_control_configure(const struct device *dev, return err; } - sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_VAL_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_VAL_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); return 0; } @@ -343,6 +343,10 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, return -ENOTSUP; } + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } @@ -475,6 +479,10 @@ static int set_up_plls(void) LL_RCC_PLL1_SetN(STM32_PLL_N_MULTIPLIER); LL_RCC_PLL1FRACN_Disable(); + if (IS_ENABLED(STM32_PLL_FRACN_ENABLED)) { + LL_RCC_PLL1_SetFRACN(STM32_PLL_FRACN_VALUE); + LL_RCC_PLL1FRACN_Enable(); + } if (IS_ENABLED(STM32_PLL_P_ENABLED)) { LL_RCC_PLL1_SetP(STM32_PLL_P_DIVISOR); @@ -769,9 +777,6 @@ int stm32_clock_control_init(const struct device *dev) /* Update CMSIS variable */ SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; - /* configure MCO1/MCO2 based on Kconfig */ - stm32_clock_control_mco_init(); - return 0; } diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index d24863ee55834..49dd67ae848eb 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -16,7 +16,6 @@ #include #include #include -#include "clock_stm32_ll_mco.h" #include "stm32_hsem.h" @@ -110,7 +109,8 @@ defined(CONFIG_SOC_STM32H747XX_M7) || defined(CONFIG_SOC_STM32H747XX_M4) ||\ defined(CONFIG_SOC_STM32H750XX) ||\ defined(CONFIG_SOC_STM32H753XX) ||\ - defined(CONFIG_SOC_STM32H755XX_M7) || defined(CONFIG_SOC_STM32H755XX_M4) + defined(CONFIG_SOC_STM32H755XX_M7) || defined(CONFIG_SOC_STM32H755XX_M4) ||\ + defined(CONFIG_SOC_STM32H757XX_M7) || defined(CONFIG_SOC_STM32H757XX_M4) /* All h7 SoC with maximum 480MHz SYSCLK */ #define SYSCLK_FREQ_MAX 480000000UL #define AHB_FREQ_MAX 240000000UL @@ -448,10 +448,12 @@ static inline int stm32_clock_control_configure(const struct device *dev, z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); - sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_MASK_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); - sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_VAL_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_MASK_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_VAL_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); @@ -541,6 +543,11 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, *rate = STM32_LSI_FREQ; break; #endif /* STM32_LSI_ENABLED */ +#if defined(STM32_HSI_ENABLED) + case STM32_SRC_HSI_KER: + *rate = STM32_HSI_FREQ/STM32_HSI_DIVISOR; + break; +#endif /* STM32_HSI_ENABLED */ #if defined(STM32_HSI48_ENABLED) case STM32_SRC_HSI48: *rate = STM32_HSI48_FREQ; @@ -642,6 +649,10 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, return -ENOTSUP; } + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } @@ -1083,9 +1094,6 @@ int stm32_clock_control_init(const struct device *dev) #endif z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); - /* Configure MCO1/MCO2 based on Kconfig */ - stm32_clock_control_mco_init(); - /* Set up individual enabled clocks */ set_up_fixed_clock_sources(); diff --git a/drivers/clock_control/clock_stm32_ll_mco.h b/drivers/clock_control/clock_stm32_ll_mco.h deleted file mode 100644 index 22e2043329bcc..0000000000000 --- a/drivers/clock_control/clock_stm32_ll_mco.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2017-2022 Linaro Limited. - * Copyright (c) 2017 RnDity Sp. z o.o. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_ -#define ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_ - -#include - -#if CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_NOCLOCK -#elif CONFIG_CLOCK_STM32_MCO1_SRC_EXT_HSE - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_EXT_HSE -#elif CONFIG_CLOCK_STM32_MCO1_SRC_LSE - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_LSE -#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSE - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSE -#elif CONFIG_CLOCK_STM32_MCO1_SRC_LSI - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_LSI -#elif CONFIG_CLOCK_STM32_MCO1_SRC_MSI - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_MSI -#elif CONFIG_CLOCK_STM32_MCO1_SRC_MSIK - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_MSIK -#elif CONFIG_CLOCK_STM32_MCO1_SRC_MSIS - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_MSIS -#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI -#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI16 - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI -#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI48 - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI48 -#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLCLK - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLCLK -#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLQCLK - #if (CONFIG_SOC_SERIES_STM32G0X || CONFIG_SOC_SERIES_STM32WLX) - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLQCLK - #elif (CONFIG_SOC_SERIES_STM32H5X || \ - CONFIG_SOC_SERIES_STM32H7X || CONFIG_SOC_SERIES_STM32H7RSX) - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLL1QCLK - #else - #error "PLLQCLK is not a valid clock source on your SOC" - #endif -#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLCLK_DIV2 - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLCLK_DIV_2 -#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLL2CLK - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLL2CLK -#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLI2SCLK - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLI2SCLK -#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLI2SCLK_DIV2 - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLI2SCLK_DIV2 -#elif CONFIG_CLOCK_STM32_MCO1_SRC_SYSCLK - #define MCO1_SOURCE LL_RCC_MCO1SOURCE_SYSCLK -#endif - -#if CONFIG_CLOCK_STM32_MCO2_SRC_SYSCLK - #define MCO2_SOURCE LL_RCC_MCO2SOURCE_SYSCLK -#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLI2S - #define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLLI2S -#elif CONFIG_CLOCK_STM32_MCO2_SRC_HSE - #define MCO2_SOURCE LL_RCC_MCO2SOURCE_HSE -#elif CONFIG_CLOCK_STM32_MCO2_SRC_LSI - #define MCO2_SOURCE LL_RCC_MCO2SOURCE_LSI -#elif CONFIG_CLOCK_STM32_MCO2_SRC_CSI - #define MCO2_SOURCE LL_RCC_MCO2SOURCE_CSI -#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLCLK - #define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLLCLK -#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLPCLK - #define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLL1PCLK -#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLL2PCLK - #define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLL2PCLK -#endif - -#define fn_mco1_prescaler(v) LL_RCC_MCO1_DIV_ ## v -#define mco1_prescaler(v) fn_mco1_prescaler(v) - -#define fn_mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v -#define mco2_prescaler(v) fn_mco2_prescaler(v) - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * MCO configure doesn't active requested clock source, - * so please make sure the clock source was enabled. - */ -__unused -static inline void stm32_clock_control_mco_init(void) -{ -#ifndef CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK -#ifdef CONFIG_SOC_SERIES_STM32F1X - LL_RCC_ConfigMCO(MCO1_SOURCE); -#else - LL_RCC_ConfigMCO(MCO1_SOURCE, - mco1_prescaler(CONFIG_CLOCK_STM32_MCO1_DIV)); -#endif -#endif /* CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK */ - -#ifndef CONFIG_CLOCK_STM32_MCO2_SRC_NOCLOCK - LL_RCC_ConfigMCO(MCO2_SOURCE, - mco2_prescaler(CONFIG_CLOCK_STM32_MCO2_DIV)); -#endif /* CONFIG_CLOCK_STM32_MCO2_SRC_NOCLOCK */ -} - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_ */ diff --git a/drivers/clock_control/clock_stm32_ll_mp1.c b/drivers/clock_control/clock_stm32_ll_mp1.c index 598bd4f202e09..e87d4c94b7718 100644 --- a/drivers/clock_control/clock_stm32_ll_mp1.c +++ b/drivers/clock_control/clock_stm32_ll_mp1.c @@ -390,6 +390,11 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, default: return -ENOTSUP; } + + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } diff --git a/drivers/clock_control/clock_stm32_ll_n6.c b/drivers/clock_control/clock_stm32_ll_n6.c new file mode 100644 index 0000000000000..3a1a9538bfd91 --- /dev/null +++ b/drivers/clock_control/clock_stm32_ll_n6.c @@ -0,0 +1,952 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Macros to fill up prescaler values */ +#define z_ic_src_pll(v) LL_RCC_ICCLKSOURCE_PLL ## v +#define ic_src_pll(v) z_ic_src_pll(v) + +#define z_hsi_divider(v) LL_RCC_HSI_DIV_ ## v +#define hsi_divider(v) z_hsi_divider(v) + +#define z_ahb_prescaler(v) LL_RCC_AHB_DIV_ ## v +#define ahb_prescaler(v) z_ahb_prescaler(v) + +#define z_apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v +#define apb1_prescaler(v) z_apb1_prescaler(v) + +#define z_apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v +#define apb2_prescaler(v) z_apb2_prescaler(v) + +#define z_apb4_prescaler(v) LL_RCC_APB4_DIV_ ## v +#define apb4_prescaler(v) z_apb4_prescaler(v) + +#define z_apb5_prescaler(v) LL_RCC_APB5_DIV_ ## v +#define apb5_prescaler(v) z_apb5_prescaler(v) + +#define PLL1_ID 1 +#define PLL2_ID 2 +#define PLL3_ID 3 +#define PLL4_ID 4 + + +static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler) +{ + return clock / prescaler; +} + +__unused +/** @brief returns the pll source frequency of given pll_id */ +static uint32_t get_pllsrc_frequency(int pll_id) +{ + if ((IS_ENABLED(STM32_PLL_SRC_HSI) && pll_id == PLL1_ID) || + (IS_ENABLED(STM32_PLL2_SRC_HSI) && pll_id == PLL2_ID) || + (IS_ENABLED(STM32_PLL3_SRC_HSI) && pll_id == PLL3_ID) || + (IS_ENABLED(STM32_PLL4_SRC_HSI) && pll_id == PLL4_ID)) { + return STM32_HSI_FREQ; + } else if ((IS_ENABLED(STM32_PLL_SRC_HSE) && pll_id == PLL1_ID) || + (IS_ENABLED(STM32_PLL2_SRC_HSE) && pll_id == PLL2_ID) || + (IS_ENABLED(STM32_PLL3_SRC_HSE) && pll_id == PLL3_ID) || + (IS_ENABLED(STM32_PLL4_SRC_HSE) && pll_id == PLL4_ID)) { + return STM32_HSE_FREQ; + } + + __ASSERT(0, "No PLL Source configured"); + return 0; +} + +static uint32_t get_pllout_frequency(int pll_id) +{ + uint32_t pllsrc_freq = get_pllsrc_frequency(pll_id); + int pllm_div; + int plln_mul; + int pllout_div1; + int pllout_div2; + + switch (pll_id) { +#if defined(STM32_PLL1_ENABLED) + case PLL1_ID: + pllm_div = STM32_PLL1_M_DIVISOR; + plln_mul = STM32_PLL1_N_MULTIPLIER; + pllout_div1 = STM32_PLL1_P1_DIVISOR; + pllout_div2 = STM32_PLL1_P2_DIVISOR; + break; +#endif /* STM32_PLL1_ENABLED */ +#if defined(STM32_PLL2_ENABLED) + case PLL2_ID: + pllm_div = STM32_PLL2_M_DIVISOR; + plln_mul = STM32_PLL2_N_MULTIPLIER; + pllout_div1 = STM32_PLL2_P1_DIVISOR; + pllout_div2 = STM32_PLL2_P2_DIVISOR; + break; +#endif /* STM32_PLL2_ENABLED */ +#if defined(STM32_PLL3_ENABLED) + case PLL3_ID: + pllm_div = STM32_PLL3_M_DIVISOR; + plln_mul = STM32_PLL3_N_MULTIPLIER; + pllout_div1 = STM32_PLL3_P1_DIVISOR; + pllout_div2 = STM32_PLL3_P2_DIVISOR; + break; +#endif /* STM32_PLL3_ENABLED */ +#if defined(STM32_PLL4_ENABLED) + case PLL4_ID: + pllm_div = STM32_PLL4_M_DIVISOR; + plln_mul = STM32_PLL4_N_MULTIPLIER; + pllout_div1 = STM32_PLL4_P1_DIVISOR; + pllout_div2 = STM32_PLL4_P2_DIVISOR; + break; +#endif /* STM32_PLL4_ENABLED */ + default: + __ASSERT(0, "No PLL configured"); + return 0; + } + + __ASSERT_NO_MSG(pllm_div && pllout_div1 && pllout_div2); + + return (pllsrc_freq / pllm_div) * plln_mul / (pllout_div1 * pllout_div2); +} + +__unused uint32_t get_icout_frequency(uint32_t icsrc, int div) +{ + if (icsrc == LL_RCC_ICCLKSOURCE_PLL1) { + return get_pllout_frequency(PLL1_ID) / div; + } else if (icsrc == LL_RCC_ICCLKSOURCE_PLL2) { + return get_pllout_frequency(PLL2_ID) / div; + } else if (icsrc == LL_RCC_ICCLKSOURCE_PLL3) { + return get_pllout_frequency(PLL3_ID) / div; + } else if (icsrc == LL_RCC_ICCLKSOURCE_PLL4) { + return get_pllout_frequency(PLL4_ID) / div; + } + + __ASSERT(0, "No IC Source configured"); + return 0; +} + +static uint32_t get_sysclk_frequency(void) +{ +#if defined(STM32_SYSCLK_SRC_HSE) + return STM32_HSE_FREQ; +#elif defined(STM32_SYSCLK_SRC_HSI) + return STM32_HSI_FREQ; +#elif defined(STM32_SYSCLK_SRC_IC2) + return get_icout_frequency(LL_RCC_IC2_GetSource(), STM32_IC2_DIV); +#else + __ASSERT(0, "No SYSCLK Source configured"); + return 0; +#endif + +} + + +/** @brief Verifies clock is part of active clock configuration */ +static int enabled_clock(uint32_t src_clk) +{ + if ((src_clk == STM32_SRC_SYSCLK) || + ((src_clk == STM32_SRC_LSE) && IS_ENABLED(STM32_LSE_ENABLED)) || + ((src_clk == STM32_SRC_LSI) && IS_ENABLED(STM32_LSI_ENABLED)) || + ((src_clk == STM32_SRC_HSE) && IS_ENABLED(STM32_HSE_ENABLED)) || + ((src_clk == STM32_SRC_HSI) && IS_ENABLED(STM32_HSI_ENABLED)) || + ((src_clk == STM32_SRC_PLL1) && IS_ENABLED(STM32_PLL1_ENABLED)) || + ((src_clk == STM32_SRC_PLL2) && IS_ENABLED(STM32_PLL2_ENABLED)) || + ((src_clk == STM32_SRC_PLL3) && IS_ENABLED(STM32_PLL3_ENABLED)) || + ((src_clk == STM32_SRC_PLL4) && IS_ENABLED(STM32_PLL4_ENABLED)) || + ((src_clk == STM32_SRC_CKPER) && IS_ENABLED(STM32_CKPER_ENABLED)) || + ((src_clk == STM32_SRC_IC1) && IS_ENABLED(STM32_IC1_ENABLED)) || + ((src_clk == STM32_SRC_IC2) && IS_ENABLED(STM32_IC2_ENABLED)) || + ((src_clk == STM32_SRC_IC3) && IS_ENABLED(STM32_IC3_ENABLED)) || + ((src_clk == STM32_SRC_IC4) && IS_ENABLED(STM32_IC4_ENABLED)) || + ((src_clk == STM32_SRC_IC5) && IS_ENABLED(STM32_IC5_ENABLED)) || + ((src_clk == STM32_SRC_IC6) && IS_ENABLED(STM32_IC6_ENABLED)) || + ((src_clk == STM32_SRC_IC7) && IS_ENABLED(STM32_IC7_ENABLED)) || + ((src_clk == STM32_SRC_IC8) && IS_ENABLED(STM32_IC8_ENABLED)) || + ((src_clk == STM32_SRC_IC9) && IS_ENABLED(STM32_IC9_ENABLED)) || + ((src_clk == STM32_SRC_IC10) && IS_ENABLED(STM32_IC10_ENABLED)) || + ((src_clk == STM32_SRC_IC11) && IS_ENABLED(STM32_IC11_ENABLED)) || + ((src_clk == STM32_SRC_IC12) && IS_ENABLED(STM32_IC12_ENABLED)) || + ((src_clk == STM32_SRC_IC13) && IS_ENABLED(STM32_IC13_ENABLED)) || + ((src_clk == STM32_SRC_IC14) && IS_ENABLED(STM32_IC14_ENABLED)) || + ((src_clk == STM32_SRC_IC15) && IS_ENABLED(STM32_IC15_ENABLED)) || + ((src_clk == STM32_SRC_IC16) && IS_ENABLED(STM32_IC16_ENABLED)) || + ((src_clk == STM32_SRC_IC17) && IS_ENABLED(STM32_IC17_ENABLED)) || + ((src_clk == STM32_SRC_IC18) && IS_ENABLED(STM32_IC18_ENABLED)) || + ((src_clk == STM32_SRC_IC19) && IS_ENABLED(STM32_IC19_ENABLED)) || + ((src_clk == STM32_SRC_IC20) && IS_ENABLED(STM32_IC20_ENABLED))) { + return 0; + } + + return -ENOTSUP; +} + +static inline int stm32_clock_control_on(const struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + + ARG_UNUSED(dev); + + if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) { + /* Attempt to toggle a wrong periph clock bit */ + return -ENOTSUP; + } + + /* Set Run clock */ + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus, + pclken->enr); + + /* Set Low Power clock */ + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus + STM32_CLOCK_LP_BUS_SHIFT, + pclken->enr); + + return 0; +} + +static inline int stm32_clock_control_off(const struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + + ARG_UNUSED(dev); + + if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) { + /* Attempt to toggle a wrong periph clock bit */ + return -ENOTSUP; + } + + /* Clear Run clock */ + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus, + pclken->enr); + + /* Clear Low Power clock */ + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus + STM32_CLOCK_LP_BUS_SHIFT, + pclken->enr); + + return 0; +} + +static inline int stm32_clock_control_configure(const struct device *dev, + clock_control_subsys_t sub_system, + void *data) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + int err; + + ARG_UNUSED(dev); + ARG_UNUSED(data); + + err = enabled_clock(pclken->bus); + if (err < 0) { + /* Attempt to configure a src clock not available or not valid */ + return err; + } + + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_MASK_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_VAL_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); + + return 0; +} + +static int stm32_clock_control_get_subsys_rate(const struct device *dev, + clock_control_subsys_t sys, + uint32_t *rate) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)(sys); + + uint32_t sys_clock = get_sysclk_frequency(); + uint32_t ahb_clock = get_bus_clock(sys_clock, STM32_AHB_PRESCALER); + + ARG_UNUSED(dev); + + switch (pclken->bus) { + case STM32_SRC_SYSCLK: + *rate = get_sysclk_frequency(); + break; + case STM32_CLOCK_BUS_AHB1: + case STM32_CLOCK_BUS_AHB2: + case STM32_CLOCK_BUS_AHB3: + case STM32_CLOCK_BUS_AHB4: + case STM32_CLOCK_BUS_AHB5: + *rate = ahb_clock; + break; + case STM32_CLOCK_BUS_APB1: + case STM32_CLOCK_BUS_APB1_2: + *rate = get_bus_clock(ahb_clock, STM32_APB1_PRESCALER); + break; + case STM32_CLOCK_BUS_APB2: + *rate = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER); + break; + case STM32_CLOCK_BUS_APB4: + case STM32_CLOCK_BUS_APB4_2: + *rate = get_bus_clock(ahb_clock, STM32_APB4_PRESCALER); + break; + case STM32_CLOCK_BUS_APB5: + *rate = get_bus_clock(ahb_clock, STM32_APB5_PRESCALER); + break; +#if defined(STM32_LSE_ENABLED) + case STM32_SRC_LSE: + *rate = STM32_LSE_FREQ; + break; +#endif /* STM32_LSE_ENABLED */ +#if defined(STM32_LSI_ENABLED) + case STM32_SRC_LSI: + *rate = STM32_LSI_FREQ; + break; +#endif /* STM32_LSI_ENABLED */ +#if defined(STM32_HSE_ENABLED) + case STM32_SRC_HSE: + *rate = STM32_HSE_FREQ; + break; +#endif /* STM32_HSE_ENABLED */ +#if defined(STM32_HSI_ENABLED) + case STM32_SRC_HSI: + *rate = STM32_HSI_FREQ; + break; +#endif /* STM32_HSI_ENABLED */ + case STM32_SRC_PLL1: + *rate = get_pllout_frequency(PLL1_ID); + break; + case STM32_SRC_PLL2: + *rate = get_pllout_frequency(PLL2_ID); + break; + case STM32_SRC_PLL3: + *rate = get_pllout_frequency(PLL3_ID); + break; + case STM32_SRC_PLL4: + *rate = get_pllout_frequency(PLL4_ID); + break; +#if defined(STM32_CKPER_ENABLED) + case STM32_SRC_CKPER: + *rate = LL_RCC_GetCLKPClockFreq(LL_RCC_CLKP_CLKSOURCE); + break; +#endif /* STM32_CKPER_ENABLED */ +#if defined(STM32_IC1_ENABLED) + case STM32_SRC_IC1: + *rate = get_icout_frequency(LL_RCC_IC1_GetSource(), STM32_IC1_DIV); + break; +#endif /* STM32_IC1_ENABLED */ +#if defined(STM32_IC2_ENABLED) + case STM32_SRC_IC2: + *rate = get_icout_frequency(LL_RCC_IC2_GetSource(), STM32_IC2_DIV); + break; +#endif /* STM32_IC2_ENABLED */ +#if defined(STM32_IC3_ENABLED) + case STM32_SRC_IC3: + *rate = get_icout_frequency(LL_RCC_IC3_GetSource(), STM32_IC3_DIV); + break; +#endif /* STM32_IC3_ENABLED */ +#if defined(STM32_IC4_ENABLED) + case STM32_SRC_IC4: + *rate = get_icout_frequency(LL_RCC_IC4_GetSource(), STM32_IC4_DIV); + break; +#endif /* STM32_IC4_ENABLED */ +#if defined(STM32_IC5_ENABLED) + case STM32_SRC_IC5: + *rate = get_icout_frequency(LL_RCC_IC5_GetSource(), STM32_IC5_DIV); + break; +#endif /* STM32_IC5_ENABLED */ +#if defined(STM32_IC6_ENABLED) + case STM32_SRC_IC6: + *rate = get_icout_frequency(LL_RCC_IC6_GetSource(), STM32_IC6_DIV); + break; +#endif /* STM32_IC6_ENABLED */ +#if defined(STM32_IC7_ENABLED) + case STM32_SRC_IC7: + *rate = get_icout_frequency(LL_RCC_IC7_GetSource(), STM32_IC7_DIV); + break; +#endif /* STM32_IC7_ENABLED */ +#if defined(STM32_IC8_ENABLED) + case STM32_SRC_IC8: + *rate = get_icout_frequency(LL_RCC_IC8_GetSource(), STM32_IC8_DIV); + break; +#endif /* STM32_IC8_ENABLED */ +#if defined(STM32_IC9_ENABLED) + case STM32_SRC_IC9: + *rate = get_icout_frequency(LL_RCC_IC9_GetSource(), STM32_IC9_DIV); + break; +#endif /* STM32_IC9_ENABLED */ +#if defined(STM32_IC10_ENABLED) + case STM32_SRC_IC10: + *rate = get_icout_frequency(LL_RCC_IC10_GetSource(), STM32_IC10_DIV); + break; +#endif /* STM32_IC10_ENABLED */ +#if defined(STM32_IC11_ENABLED) + case STM32_SRC_IC11: + *rate = get_icout_frequency(LL_RCC_IC11_GetSource(), STM32_IC11_DIV); + break; +#endif /* STM32_IC11_ENABLED */ +#if defined(STM32_IC12_ENABLED) + case STM32_SRC_IC12: + *rate = get_icout_frequency(LL_RCC_IC12_GetSource(), STM32_IC12_DIV); + break; +#endif /* STM32_IC12_ENABLED */ +#if defined(STM32_IC13_ENABLED) + case STM32_SRC_IC13: + *rate = get_icout_frequency(LL_RCC_IC13_GetSource(), STM32_IC13_DIV); + break; +#endif /* STM32_IC13_ENABLED */ +#if defined(STM32_IC14_ENABLED) + case STM32_SRC_IC14: + *rate = get_icout_frequency(LL_RCC_IC14_GetSource(), STM32_IC14_DIV); + break; +#endif /* STM32_IC14_ENABLED */ +#if defined(STM32_IC15_ENABLED) + case STM32_SRC_IC15: + *rate = get_icout_frequency(LL_RCC_IC15_GetSource(), STM32_IC15_DIV); + break; +#endif /* STM32_IC15_ENABLED */ +#if defined(STM32_IC16_ENABLED) + case STM32_SRC_IC16: + *rate = get_icout_frequency(LL_RCC_IC16_GetSource(), STM32_IC16_DIV); + break; +#endif /* STM32_IC16_ENABLED */ +#if defined(STM32_IC17_ENABLED) + case STM32_SRC_IC17: + *rate = get_icout_frequency(LL_RCC_IC17_GetSource(), STM32_IC17_DIV); + break; +#endif /* STM32_IC17_ENABLED */ +#if defined(STM32_IC18_ENABLED) + case STM32_SRC_IC18: + *rate = get_icout_frequency(LL_RCC_IC18_GetSource(), STM32_IC18_DIV); + break; +#endif /* STM32_IC18_ENABLED */ +#if defined(STM32_IC19_ENABLED) + case STM32_SRC_IC19: + *rate = get_icout_frequency(LL_RCC_IC19_GetSource(), STM32_IC19_DIV); + break; +#endif /* STM32_IC19_ENABLED */ +#if defined(STM32_IC20_ENABLED) + case STM32_SRC_IC20: + *rate = get_icout_frequency(LL_RCC_IC20_GetSource(), STM32_IC20_DIV); + break; +#endif /* STM32_IC20_ENABLED */ + default: + return -ENOTSUP; + } + + if (pclken->div) { + *rate /= (pclken->div + 1); + } + + return 0; +} + +static DEVICE_API(clock_control, stm32_clock_control_api) = { + .on = stm32_clock_control_on, + .off = stm32_clock_control_off, + .get_rate = stm32_clock_control_get_subsys_rate, + .configure = stm32_clock_control_configure, +}; + +/* + * Unconditionally switch the system clock source to HSI. + */ +__unused +static void stm32_clock_switch_to_hsi(void) +{ + /* Enable HSI if not enabled */ + if (LL_RCC_HSI_IsReady() != 1) { + /* Enable HSI */ + LL_RCC_HSI_Enable(); + while (LL_RCC_HSI_IsReady() != 1) { + /* Wait for HSI ready */ + } + } + + /* Set HSI as SYSCLCK source */ + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI); + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) { + } + + LL_RCC_SetCpuClkSource(LL_RCC_CPU_CLKSOURCE_HSI); + while (LL_RCC_GetCpuClkSource() != LL_RCC_CPU_CLKSOURCE_STATUS_HSI) { + } +} + +static int set_up_ics(void) +{ +#if defined(STM32_IC1_ENABLED) + LL_RCC_IC1_SetSource(ic_src_pll(STM32_IC1_PLL_SRC)); + LL_RCC_IC1_SetDivider(STM32_IC1_DIV); + LL_RCC_IC1_Enable(); +#endif + +#if defined(STM32_IC2_ENABLED) + LL_RCC_IC2_SetSource(ic_src_pll(STM32_IC2_PLL_SRC)); + LL_RCC_IC2_SetDivider(STM32_IC2_DIV); + LL_RCC_IC2_Enable(); +#endif + +#if defined(STM32_IC3_ENABLED) + LL_RCC_IC3_SetSource(ic_src_pll(STM32_IC3_PLL_SRC)); + LL_RCC_IC3_SetDivider(STM32_IC3_DIV); + LL_RCC_IC3_Enable(); +#endif + +#if defined(STM32_IC4_ENABLED) + LL_RCC_IC4_SetSource(ic_src_pll(STM32_IC4_PLL_SRC)); + LL_RCC_IC4_SetDivider(STM32_IC4_DIV); + LL_RCC_IC4_Enable(); +#endif + +#if defined(STM32_IC5_ENABLED) + LL_RCC_IC5_SetSource(ic_src_pll(STM32_IC5_PLL_SRC)); + LL_RCC_IC5_SetDivider(STM32_IC5_DIV); + LL_RCC_IC5_Enable(); +#endif + +#if defined(STM32_IC6_ENABLED) + LL_RCC_IC6_SetSource(ic_src_pll(STM32_IC6_PLL_SRC)); + LL_RCC_IC6_SetDivider(STM32_IC6_DIV); + LL_RCC_IC6_Enable(); +#endif + +#if defined(STM32_IC7_ENABLED) + LL_RCC_IC7_SetSource(ic_src_pll(STM32_IC7_PLL_SRC)); + LL_RCC_IC7_SetDivider(STM32_IC7_DIV); + LL_RCC_IC7_Enable(); +#endif + +#if defined(STM32_IC8_ENABLED) + LL_RCC_IC8_SetSource(ic_src_pll(STM32_IC8_PLL_SRC)); + LL_RCC_IC8_SetDivider(STM32_IC8_DIV); + LL_RCC_IC8_Enable(); +#endif + +#if defined(STM32_IC9_ENABLED) + LL_RCC_IC9_SetSource(ic_src_pll(STM32_IC9_PLL_SRC)); + LL_RCC_IC9_SetDivider(STM32_IC9_DIV); + LL_RCC_IC9_Enable(); +#endif + +#if defined(STM32_IC10_ENABLED) + LL_RCC_IC10_SetSource(ic_src_pll(STM32_IC10_PLL_SRC)); + LL_RCC_IC10_SetDivider(STM32_IC10_DIV); + LL_RCC_IC10_Enable(); +#endif + +#if defined(STM32_IC11_ENABLED) + LL_RCC_IC11_SetSource(ic_src_pll(STM32_IC11_PLL_SRC)); + LL_RCC_IC11_SetDivider(STM32_IC11_DIV); + LL_RCC_IC11_Enable(); +#endif + +#if defined(STM32_IC12_ENABLED) + LL_RCC_IC12_SetSource(ic_src_pll(STM32_IC12_PLL_SRC)); + LL_RCC_IC12_SetDivider(STM32_IC12_DIV); + LL_RCC_IC12_Enable(); +#endif + +#if defined(STM32_IC13_ENABLED) + LL_RCC_IC13_SetSource(ic_src_pll(STM32_IC13_PLL_SRC)); + LL_RCC_IC13_SetDivider(STM32_IC13_DIV); + LL_RCC_IC13_Enable(); +#endif + +#if defined(STM32_IC14_ENABLED) + LL_RCC_IC14_SetSource(ic_src_pll(STM32_IC14_PLL_SRC)); + LL_RCC_IC14_SetDivider(STM32_IC14_DIV); + LL_RCC_IC14_Enable(); +#endif + +#if defined(STM32_IC15_ENABLED) + LL_RCC_IC15_SetSource(ic_src_pll(STM32_IC15_PLL_SRC)); + LL_RCC_IC15_SetDivider(STM32_IC15_DIV); + LL_RCC_IC15_Enable(); +#endif + +#if defined(STM32_IC16_ENABLED) + LL_RCC_IC16_SetSource(ic_src_pll(STM32_IC16_PLL_SRC)); + LL_RCC_IC16_SetDivider(STM32_IC16_DIV); + LL_RCC_IC16_Enable(); +#endif + +#if defined(STM32_IC17_ENABLED) + LL_RCC_IC17_SetSource(ic_src_pll(STM32_IC17_PLL_SRC)); + LL_RCC_IC17_SetDivider(STM32_IC17_DIV); + LL_RCC_IC17_Enable(); +#endif + +#if defined(STM32_IC18_ENABLED) + LL_RCC_IC18_SetSource(ic_src_pll(STM32_IC18_PLL_SRC)); + LL_RCC_IC18_SetDivider(STM32_IC18_DIV); + LL_RCC_IC18_Enable(); +#endif + +#if defined(STM32_IC19_ENABLED) + LL_RCC_IC19_SetSource(ic_src_pll(STM32_IC19_PLL_SRC)); + LL_RCC_IC19_SetDivider(STM32_IC19_DIV); + LL_RCC_IC19_Enable(); +#endif + +#if defined(STM32_IC20_ENABLED) + LL_RCC_IC20_SetSource(ic_src_pll(STM32_IC20_PLL_SRC)); + LL_RCC_IC20_SetDivider(STM32_IC20_DIV); + LL_RCC_IC20_Enable(); +#endif + + return 0; +} + +static int set_up_plls(void) +{ +#if defined(STM32_PLL1_ENABLED) + /* TODO: Do not switch systematically on HSI if not needed */ + stm32_clock_switch_to_hsi(); + + LL_RCC_PLL1_Disable(); + + /* Configure PLL source : Can be HSE, HSI, MSI */ + if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_HSE); + } else if (IS_ENABLED(STM32_PLL_SRC_MSI)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_MSI); + } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_HSI); + } else { + return -ENOTSUP; + } + + /* Disable PLL1 modulation spread-spectrum */ + LL_RCC_PLL1_DisableModulationSpreadSpectrum(); + + /* Disable bypass to use the PLL VCO */ + if (LL_RCC_PLL1_IsEnabledBypass()) { + LL_RCC_PLL1_DisableBypass(); + } + + /* Configure PLL */ + LL_RCC_PLL1_SetM(STM32_PLL1_M_DIVISOR); + LL_RCC_PLL1_SetN(STM32_PLL1_N_MULTIPLIER); + LL_RCC_PLL1_SetP1(STM32_PLL1_P1_DIVISOR); + LL_RCC_PLL1_SetP2(STM32_PLL1_P2_DIVISOR); + + /* Disable fractional mode */ + LL_RCC_PLL1_SetFRACN(0); + LL_RCC_PLL1_DisableFractionalModulationSpreadSpectrum(); + + LL_RCC_PLL1_AssertModulationSpreadSpectrumReset(); + + /* Enable post division */ + if (!LL_RCC_PLL1P_IsEnabled()) { + LL_RCC_PLL1P_Enable(); + } + + LL_RCC_PLL1_Enable(); + while (LL_RCC_PLL1_IsReady() != 1U) { + } +#endif /* STM32_PLL1_ENABLED */ + +#if defined(STM32_PLL2_ENABLED) + LL_RCC_PLL2_Disable(); + + /* Configure PLL source : Can be HSE, HSI, MSI */ + if (IS_ENABLED(STM32_PLL2_SRC_HSE)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL2_SetSource(LL_RCC_PLLSOURCE_HSE); + } else if (IS_ENABLED(STM32_PLL2_SRC_MSI)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL2_SetSource(LL_RCC_PLLSOURCE_MSI); + } else if (IS_ENABLED(STM32_PLL2_SRC_HSI)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL2_SetSource(LL_RCC_PLLSOURCE_HSI); + } else { + return -ENOTSUP; + } + + /* Disable PLL2 modulation spread-spectrum */ + LL_RCC_PLL2_DisableModulationSpreadSpectrum(); + + /* Disable bypass to use the PLL VCO */ + if (LL_RCC_PLL2_IsEnabledBypass()) { + LL_RCC_PLL2_DisableBypass(); + } + + /* Configure PLL */ + LL_RCC_PLL2_SetM(STM32_PLL2_M_DIVISOR); + LL_RCC_PLL2_SetN(STM32_PLL2_N_MULTIPLIER); + LL_RCC_PLL2_SetP1(STM32_PLL2_P1_DIVISOR); + LL_RCC_PLL2_SetP2(STM32_PLL2_P2_DIVISOR); + + /* Disable fractional mode */ + LL_RCC_PLL2_SetFRACN(0); + LL_RCC_PLL2_DisableFractionalModulationSpreadSpectrum(); + + LL_RCC_PLL2_AssertModulationSpreadSpectrumReset(); + + /* Enable post division */ + if (!LL_RCC_PLL2P_IsEnabled()) { + LL_RCC_PLL2P_Enable(); + } + + LL_RCC_PLL2_Enable(); + while (LL_RCC_PLL2_IsReady() != 1U) { + } +#endif + +#if defined(STM32_PLL3_ENABLED) + LL_RCC_PLL3_Disable(); + + /* Configure PLL source : Can be HSE, HSI, MSIS */ + if (IS_ENABLED(STM32_PLL3_SRC_HSE)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL3_SetSource(LL_RCC_PLLSOURCE_HSE); + } else if (IS_ENABLED(STM32_PLL3_SRC_MSI)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL3_SetSource(LL_RCC_PLLSOURCE_MSI); + } else if (IS_ENABLED(STM32_PLL3_SRC_HSI)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL3_SetSource(LL_RCC_PLLSOURCE_HSI); + } else { + return -ENOTSUP; + } + + /* Disable PLL3 modulation spread-spectrum */ + LL_RCC_PLL3_DisableModulationSpreadSpectrum(); + + /* Disable bypass to use the PLL VCO */ + if (LL_RCC_PLL3_IsEnabledBypass()) { + LL_RCC_PLL3_DisableBypass(); + } + + /* Configure PLL */ + LL_RCC_PLL3_SetM(STM32_PLL3_M_DIVISOR); + LL_RCC_PLL3_SetN(STM32_PLL3_N_MULTIPLIER); + LL_RCC_PLL3_SetP1(STM32_PLL3_P1_DIVISOR); + LL_RCC_PLL3_SetP2(STM32_PLL3_P2_DIVISOR); + + /* Disable fractional mode */ + LL_RCC_PLL3_SetFRACN(0); + LL_RCC_PLL3_DisableFractionalModulationSpreadSpectrum(); + + LL_RCC_PLL3_AssertModulationSpreadSpectrumReset(); + + /* Enable post division */ + if (!LL_RCC_PLL3P_IsEnabled()) { + LL_RCC_PLL3P_Enable(); + } + + LL_RCC_PLL3_Enable(); + while (LL_RCC_PLL3_IsReady() != 1U) { + } +#endif + +#if defined(STM32_PLL4_ENABLED) + LL_RCC_PLL4_Disable(); + + /* Configure PLL source : Can be HSE, HSI, MSIS */ + if (IS_ENABLED(STM32_PLL4_SRC_HSE)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL4_SetSource(LL_RCC_PLLSOURCE_HSE); + } else if (IS_ENABLED(STM32_PLL4_SRC_MSI)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL4_SetSource(LL_RCC_PLLSOURCE_MSI); + } else if (IS_ENABLED(STM32_PLL4_SRC_HSI)) { + /* Main PLL configuration and activation */ + LL_RCC_PLL4_SetSource(LL_RCC_PLLSOURCE_HSI); + } else { + return -ENOTSUP; + } + + /* Disable PLL4 modulation spread-spectrum */ + LL_RCC_PLL4_DisableModulationSpreadSpectrum(); + + /* Disable bypass to use the PLL VCO */ + if (LL_RCC_PLL4_IsEnabledBypass()) { + LL_RCC_PLL4_DisableBypass(); + } + + /* Configure PLL */ + LL_RCC_PLL4_SetM(STM32_PLL4_M_DIVISOR); + LL_RCC_PLL4_SetN(STM32_PLL4_N_MULTIPLIER); + LL_RCC_PLL4_SetP1(STM32_PLL4_P1_DIVISOR); + LL_RCC_PLL4_SetP2(STM32_PLL4_P2_DIVISOR); + + /* Disable fractional mode */ + LL_RCC_PLL4_SetFRACN(0); + LL_RCC_PLL4_DisableFractionalModulationSpreadSpectrum(); + + LL_RCC_PLL4_AssertModulationSpreadSpectrumReset(); + + /* Enable post division */ + if (!LL_RCC_PLL4P_IsEnabled()) { + LL_RCC_PLL4P_Enable(); + } + + LL_RCC_PLL4_Enable(); + while (LL_RCC_PLL4_IsReady() != 1U) { + } +#endif + + return 0; +} + +static void set_up_fixed_clock_sources(void) +{ + if (IS_ENABLED(STM32_HSE_ENABLED)) { + /* Check if need to enable HSE bypass feature or not */ + if (IS_ENABLED(STM32_HSE_BYPASS)) { + LL_RCC_HSE_EnableBypass(); + } else { + LL_RCC_HSE_DisableBypass(); + } + + if (IS_ENABLED(STM32_HSE_DIV2)) { + LL_RCC_HSE_SelectHSEDiv2AsDiv2Clock(); + } else { + LL_RCC_HSE_SelectHSEAsDiv2Clock(); + } + + /* Enable HSE */ + LL_RCC_HSE_Enable(); + while (LL_RCC_HSE_IsReady() != 1) { + /* Wait for HSE ready */ + } + } + + if (IS_ENABLED(STM32_HSI_ENABLED)) { + /* Enable HSI oscillator */ + LL_RCC_HSI_Enable(); + while (LL_RCC_HSI_IsReady() != 1) { + } + /* HSI divider configuration */ + LL_RCC_HSI_SetDivider(hsi_divider(STM32_HSI_DIVISOR)); + } + + if (IS_ENABLED(STM32_LSE_ENABLED)) { + /* Enable the power interface clock */ + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_PWR); + + if (!LL_PWR_IsEnabledBkUpAccess()) { + /* Enable write access to Backup domain */ + LL_PWR_EnableBkUpAccess(); + while (!LL_PWR_IsEnabledBkUpAccess()) { + /* Wait for Backup domain access */ + } + } + + /* Configure driving capability */ + LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_LSECFGR_LSEDRV_Pos); + + if (IS_ENABLED(STM32_LSE_BYPASS)) { + /* Configure LSE bypass */ + LL_RCC_LSE_EnableBypass(); + } + + /* Enable LSE Oscillator */ + LL_RCC_LSE_Enable(); + /* Wait for LSE ready */ + while (!LL_RCC_LSE_IsReady()) { + } + + LL_PWR_DisableBkUpAccess(); + } + + if (IS_ENABLED(STM32_LSI_ENABLED)) { + /* Enable LSI oscillator */ + LL_RCC_LSI_Enable(); + while (LL_RCC_LSI_IsReady() != 1) { + } + } +} + +int stm32_clock_control_init(const struct device *dev) +{ + int r = 0; + + ARG_UNUSED(dev); + + /* For now, enable clocks (including low_power ones) of all RAM */ + uint32_t all_ram = LL_MEM_AXISRAM1 | LL_MEM_AXISRAM2 | LL_MEM_AXISRAM3 | LL_MEM_AXISRAM4 | + LL_MEM_AXISRAM5 | LL_MEM_AXISRAM6 | LL_MEM_AHBSRAM1 | LL_MEM_AHBSRAM2 | + LL_MEM_BKPSRAM | LL_MEM_FLEXRAM | LL_MEM_CACHEAXIRAM | LL_MEM_VENCRAM; + LL_MEM_EnableClock(all_ram); + LL_MEM_EnableClockLowPower(all_ram); + + /* Set up individual enabled clocks */ + set_up_fixed_clock_sources(); + + /* Set up PLLs */ + r = set_up_plls(); + if (r < 0) { + return r; + } + + /* Preset the prescalers prior to chosing SYSCLK */ + /* Prevents APB clock to go over limits */ + /* Set buses (AHB, APB1, APB2, APB4 & APB5) prescalers */ + LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_AHB_PRESCALER)); + LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_APB1_PRESCALER)); + LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_APB2_PRESCALER)); + LL_RCC_SetAPB4Prescaler(apb4_prescaler(STM32_APB4_PRESCALER)); + LL_RCC_SetAPB5Prescaler(apb5_prescaler(STM32_APB5_PRESCALER)); + + if (IS_ENABLED(STM32_CKPER_ENABLED)) { + LL_MISC_EnableClock(LL_PER); + LL_MISC_EnableClockLowPower(LL_PER); + while (LL_MISC_IsEnabledClock(LL_PER) != 1) { + } + } + + /* Set up ICs */ + r = set_up_ics(); + if (r < 0) { + return r; + } + + /* Set up sys clock */ + if (IS_ENABLED(STM32_SYSCLK_SRC_HSE)) { + /* Set sysclk source to HSE */ + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE); + while (LL_RCC_GetSysClkSource() != + LL_RCC_SYS_CLKSOURCE_STATUS_HSE) { + } + } else if (IS_ENABLED(STM32_SYSCLK_SRC_HSI)) { + /* Set sysclk source to HSI */ + stm32_clock_switch_to_hsi(); + } else if (IS_ENABLED(STM32_SYSCLK_SRC_IC2)) { + /* Set sysclk source to IC2 */ + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_IC2_IC6_IC11); + while (LL_RCC_GetSysClkSource() != + LL_RCC_SYS_CLKSOURCE_STATUS_IC2_IC6_IC11) { + } + } else { + return -ENOTSUP; + } + + /* Update CMSIS variable */ + SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; + + return r; +} + +/** + * @brief RCC device, note that priority is intentionally set to 1 so + * that the device init runs just after SOC init + */ +DEVICE_DT_DEFINE(DT_NODELABEL(rcc), + &stm32_clock_control_init, + NULL, + NULL, NULL, + PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, + &stm32_clock_control_api); diff --git a/drivers/clock_control/clock_stm32_ll_u5.c b/drivers/clock_control/clock_stm32_ll_u5.c index 380f88f2da694..770c535209f78 100644 --- a/drivers/clock_control/clock_stm32_ll_u5.c +++ b/drivers/clock_control/clock_stm32_ll_u5.c @@ -17,7 +17,7 @@ #include #include #include -#include "clock_stm32_ll_mco.h" + /* Macros to fill up prescaler values */ #define z_ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v @@ -206,10 +206,12 @@ static inline int stm32_clock_control_configure(const struct device *dev, return err; } - sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_MASK_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); - sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_VAL_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_MASK_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_VAL_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); return 0; } @@ -357,6 +359,10 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, return -ENOTSUP; } + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } @@ -904,9 +910,6 @@ int stm32_clock_control_init(const struct device *dev) /* Update CMSIS variable */ SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; - /* configure MCO1/MCO2 based on Kconfig */ - stm32_clock_control_mco_init(); - return 0; } diff --git a/drivers/clock_control/clock_stm32_ll_wb0.c b/drivers/clock_control/clock_stm32_ll_wb0.c index 03082d60b3a49..82ae3c15abcc1 100644 --- a/drivers/clock_control/clock_stm32_ll_wb0.c +++ b/drivers/clock_control/clock_stm32_ll_wb0.c @@ -252,8 +252,8 @@ static inline int stm32_clock_control_configure(const struct device *dev, void *data) { struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system; - const uint32_t shift = STM32_CLOCK_SHIFT_GET(pclken->enr); - mem_addr_t reg = RCC_REG(STM32_CLOCK_REG_GET(pclken->enr)); + const uint32_t shift = STM32_DT_CLKSEL_SHIFT_GET(pclken->enr); + mem_addr_t reg = RCC_REG(STM32_DT_CLKSEL_REG_GET(pclken->enr)); int err; ARG_UNUSED(dev); @@ -265,16 +265,16 @@ static inline int stm32_clock_control_configure(const struct device *dev, return err; } - sys_clear_bits(reg, STM32_CLOCK_MASK_GET(pclken->enr) << shift); - sys_set_bits(reg, STM32_CLOCK_VAL_GET(pclken->enr) << shift); + sys_clear_bits(reg, STM32_DT_CLKSEL_MASK_GET(pclken->enr) << shift); + sys_set_bits(reg, STM32_DT_CLKSEL_VAL_GET(pclken->enr) << shift); return 0; } -static inline int get_apb0_periph_clkrate(uint32_t enr, uint32_t *rate, - uint32_t slow_clock, uint32_t sysclk, uint32_t clk_sys) +static inline int get_apb0_periph_clkrate(struct stm32_pclken *pclken, + uint32_t *rate, uint32_t slow_clock, uint32_t sysclk, uint32_t clk_sys) { - switch (enr) { + switch (pclken->enr) { /* Slow clock peripherals: RTC & IWDG */ case LL_APB0_GRP1_PERIPH_RTC: case LL_APB0_GRP1_PERIPH_WDG: @@ -305,13 +305,17 @@ static inline int get_apb0_periph_clkrate(uint32_t enr, uint32_t *rate, return -ENOTSUP; } + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } -static inline int get_apb1_periph_clkrate(uint32_t enr, uint32_t *rate, - uint32_t clk_sys) +static inline int get_apb1_periph_clkrate(struct stm32_pclken *pclken, + uint32_t *rate, uint32_t clk_sys) { - switch (enr) { + switch (pclken->enr) { #if defined(SPI1) case LL_APB1_GRP1_PERIPH_SPI1: *rate = clk_sys; @@ -387,6 +391,10 @@ static inline int get_apb1_periph_clkrate(uint32_t enr, uint32_t *rate, return -ENOTSUP; } + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } @@ -457,11 +465,10 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, *rate = clk_sys; break; case STM32_CLOCK_BUS_APB0: - return get_apb0_periph_clkrate(pclken->enr, rate, - slow_clock, sysclk, clk_sys); + return get_apb0_periph_clkrate(pclken, rate, slow_clock, + sysclk, clk_sys); case STM32_CLOCK_BUS_APB1: - return get_apb1_periph_clkrate(pclken->enr, rate, - clk_sys); + return get_apb1_periph_clkrate(pclken, rate, clk_sys); case STM32_SRC_SYSCLK: *rate = sysclk; break; @@ -494,6 +501,10 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, return -ENOTSUP; } + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } diff --git a/drivers/clock_control/clock_stm32_ll_wba.c b/drivers/clock_control/clock_stm32_ll_wba.c index 58b96ca38659e..4895d862b47ae 100644 --- a/drivers/clock_control/clock_stm32_ll_wba.c +++ b/drivers/clock_control/clock_stm32_ll_wba.c @@ -120,10 +120,12 @@ static inline int stm32_clock_control_configure(const struct device *dev, return err; } - sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_MASK_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); - sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr), - STM32_CLOCK_VAL_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr)); + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_MASK_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_VAL_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); return 0; #else @@ -271,6 +273,10 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, return -ENOTSUP; } + if (pclken->div) { + *rate /= (pclken->div + 1); + } + return 0; } diff --git a/drivers/clock_control/clock_stm32_mco.c b/drivers/clock_control/clock_stm32_mco.c index 0e8d6faec2661..1a524d74c59b2 100644 --- a/drivers/clock_control/clock_stm32_mco.c +++ b/drivers/clock_control/clock_stm32_mco.c @@ -41,24 +41,24 @@ static int stm32_mco_init(const struct device *dev) /* MCO source */ sys_clear_bits( - DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_MCO_CFGR_REG_GET(pclken->enr), - STM32_MCO_CFGR_MASK_GET(pclken->enr) << - STM32_MCO_CFGR_SHIFT_GET(pclken->enr)); + DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_MASK_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); sys_set_bits( - DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_MCO_CFGR_REG_GET(pclken->enr), - STM32_MCO_CFGR_VAL_GET(pclken->enr) << - STM32_MCO_CFGR_SHIFT_GET(pclken->enr)); + DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr), + STM32_DT_CLKSEL_VAL_GET(pclken->enr) << + STM32_DT_CLKSEL_SHIFT_GET(pclken->enr)); #if defined(HAS_PRESCALER) /* MCO prescaler */ sys_clear_bits( - DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_MCO_CFGR_REG_GET(config->prescaler), - STM32_MCO_CFGR_MASK_GET(config->prescaler) << - STM32_MCO_CFGR_SHIFT_GET(config->prescaler)); + DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(config->prescaler), + STM32_DT_CLKSEL_MASK_GET(config->prescaler) << + STM32_DT_CLKSEL_SHIFT_GET(config->prescaler)); sys_set_bits( - DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_MCO_CFGR_REG_GET(config->prescaler), - STM32_MCO_CFGR_VAL_GET(config->prescaler) << - STM32_MCO_CFGR_SHIFT_GET(config->prescaler)); + DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(config->prescaler), + STM32_DT_CLKSEL_VAL_GET(config->prescaler) << + STM32_DT_CLKSEL_SHIFT_GET(config->prescaler)); #endif return pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); diff --git a/drivers/clock_control/clock_stm32f2_f4_f7.c b/drivers/clock_control/clock_stm32f2_f4_f7.c index a10fede688704..c391d508b3026 100644 --- a/drivers/clock_control/clock_stm32f2_f4_f7.c +++ b/drivers/clock_control/clock_stm32f2_f4_f7.c @@ -50,6 +50,46 @@ uint32_t get_pllsrc_frequency(void) return 0; } +#if defined(STM32_CK48_ENABLED) +/** + * @brief calculate the CK48 frequency depending on its clock source + */ +__unused +uint32_t get_ck48_frequency(void) +{ + uint32_t source; + + if (LL_RCC_GetCK48MClockSource(LL_RCC_CK48M_CLKSOURCE) == + LL_RCC_CK48M_CLKSOURCE_PLL) { + /* Get the PLL48CK source : HSE or HSI */ + source = (LL_RCC_PLL_GetMainSource() == LL_RCC_PLLSOURCE_HSE) + ? HSE_VALUE + : HSI_VALUE; + /* Get the PLL48CK Q freq. No HAL macro for that */ + return __LL_RCC_CALC_PLLCLK_48M_FREQ(source, + LL_RCC_PLL_GetDivider(), + LL_RCC_PLL_GetN(), + LL_RCC_PLL_GetQ() + ); + } else if (LL_RCC_GetCK48MClockSource(LL_RCC_CK48M_CLKSOURCE) == + LL_RCC_CK48M_CLKSOURCE_PLLI2S) { + /* Get the PLL I2S source : HSE or HSI */ + source = (LL_RCC_PLLI2S_GetMainSource() == LL_RCC_PLLSOURCE_HSE) + ? HSE_VALUE + : HSI_VALUE; + /* Get the PLL I2S Q freq. No HAL macro for that */ + return __LL_RCC_CALC_PLLI2S_48M_FREQ(source, + LL_RCC_PLLI2S_GetDivider(), + LL_RCC_PLLI2S_GetN(), + LL_RCC_PLLI2S_GetQ() + ); + } + + __ASSERT(0, "Invalid source"); + return 0; +} +#endif + /** * @brief Set up pll configuration */ @@ -64,6 +104,14 @@ void config_pll_sysclock(void) STM32_PLL_N_MULTIPLIER, pllp(STM32_PLL_P_DIVISOR)); +#if STM32_PLL_Q_ENABLED + /* There is a Q divider on the PLL to configure the PLL48CK */ + LL_RCC_PLL_ConfigDomain_48M(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllq(STM32_PLL_Q_DIVISOR)); +#endif /* STM32_PLLI2S_Q_ENABLED */ + #if defined(CONFIG_SOC_SERIES_STM32F7X) /* Assuming we stay on Power Scale default value: Power Scale 1 */ if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC > 180000000) { @@ -104,17 +152,19 @@ void config_pll_sysclock(void) __unused void config_plli2s(void) { -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f4_plli2s_clock) LL_RCC_PLLI2S_ConfigDomain_I2S(get_pll_source(), - pllm(STM32_PLLI2S_M_DIVISOR), + plli2sm(STM32_PLLI2S_M_DIVISOR), STM32_PLLI2S_N_MULTIPLIER, plli2sr(STM32_PLLI2S_R_DIVISOR)); -#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32f412_plli2s_clock) - LL_RCC_PLL_ConfigDomain_I2S(get_pll_source(), + +#if STM32_PLLI2S_Q_ENABLED && \ + (defined(RCC_PLLI2SCFGR_PLLI2SQ) && !defined(RCC_DCKCFGR_PLLI2SDIVQ)) + /* There is a Q divider on the PLLI2S to configure the PLL48CK */ + LL_RCC_PLLI2S_ConfigDomain_48M(get_pll_source(), plli2sm(STM32_PLLI2S_M_DIVISOR), STM32_PLLI2S_N_MULTIPLIER, - plli2sr(STM32_PLLI2S_R_DIVISOR)); -#endif + plli2sq(STM32_PLLI2S_Q_DIVISOR)); +#endif /* STM32_PLLI2S_Q_ENABLED */ } #endif /* STM32_PLLI2S_ENABLED */ diff --git a/drivers/clock_control/nrf_clock_calibration.c b/drivers/clock_control/nrf_clock_calibration.c index bea799515e1aa..fc2ce4162aa47 100644 --- a/drivers/clock_control/nrf_clock_calibration.c +++ b/drivers/clock_control/nrf_clock_calibration.c @@ -294,3 +294,8 @@ int z_nrf_clock_calibration_skips_count(void) return total_skips_cnt; } + +bool z_nrf_clock_calibration_is_in_progress(void) +{ + return cal_process_in_progress ? true : false; +} diff --git a/drivers/comparator/CMakeLists.txt b/drivers/comparator/CMakeLists.txt index 43462d64288ac..cbfa301d580f3 100644 --- a/drivers/comparator/CMakeLists.txt +++ b/drivers/comparator/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/comparator.h) zephyr_library() zephyr_library_sources_ifdef(CONFIG_USERSPACE comparator_handlers.c) +zephyr_library_sources_ifdef(CONFIG_COMPARATOR_SILABS_ACMP comparator_silabs_acmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_FAKE_COMP comparator_fake_comp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_MCUX_ACMP comparator_mcux_acmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NRF_COMP comparator_nrf_comp.c) diff --git a/drivers/comparator/Kconfig b/drivers/comparator/Kconfig index 978adc0325173..79538a6cc2221 100644 --- a/drivers/comparator/Kconfig +++ b/drivers/comparator/Kconfig @@ -19,6 +19,7 @@ config COMPARATOR_INIT_PRIORITY Comparator device driver initialization priority. rsource "Kconfig.fake_comp" +rsource "Kconfig.silabs_acmp" rsource "Kconfig.mcux_acmp" rsource "Kconfig.nrf_comp" rsource "Kconfig.nrf_lpcomp" diff --git a/drivers/comparator/Kconfig.silabs_acmp b/drivers/comparator/Kconfig.silabs_acmp new file mode 100644 index 0000000000000..db684e91f9b39 --- /dev/null +++ b/drivers/comparator/Kconfig.silabs_acmp @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 +config COMPARATOR_SILABS_ACMP + bool "Silabs ACMP comparator driver" + default y + depends on DT_HAS_SILABS_ACMP_ENABLED + select PINCTRL + select SOC_SILABS_ACMP + help + Enable the comparator driver for the Analog Comparator hardware block + present on Silicon Labs devices. This block is commonly used to + monitor the power supply. diff --git a/drivers/comparator/comparator_shell.c b/drivers/comparator/comparator_shell.c index 8641faafcf011..2723e170cefa0 100644 --- a/drivers/comparator/comparator_shell.c +++ b/drivers/comparator/comparator_shell.c @@ -30,7 +30,7 @@ static int get_device_from_str(const struct shell *sh, const char *dev_str, const struct device **dev) { - *dev = device_get_binding(dev_str); + *dev = shell_device_get_binding(dev_str); if (*dev == NULL) { shell_error(sh, "%s not %s", dev_str, "found"); @@ -216,9 +216,9 @@ static int cmd_trigger_is_pending(const struct shell *sh, size_t argc, char **ar return 0; } -static bool device_is_comp_and_ready(const struct device *dev) +static bool device_is_comp(const struct device *dev) { - return device_is_ready(dev) && DEVICE_API_IS(comparator, dev); + return DEVICE_API_IS(comparator, dev); } static void dsub_set_trigger_lookup_1(size_t idx, struct shell_static_entry *entry) @@ -233,7 +233,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_set_trigger_1, dsub_set_trigger_lookup_1); static void dsub_set_trigger_lookup_0(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_filter(idx, device_is_comp_and_ready); + const struct device *dev = shell_device_filter(idx, device_is_comp); entry->syntax = dev != NULL ? dev->name : NULL; entry->handler = NULL; @@ -245,7 +245,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_set_trigger_0, dsub_set_trigger_lookup_0); static void dsub_device_lookup_0(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_filter(idx, device_is_comp_and_ready); + const struct device *dev = shell_device_filter(idx, device_is_comp); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/comparator/comparator_silabs_acmp.c b/drivers/comparator/comparator_silabs_acmp.c new file mode 100644 index 0000000000000..479472f790f0c --- /dev/null +++ b/drivers/comparator/comparator_silabs_acmp.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(silabs_acmp, CONFIG_COMPARATOR_LOG_LEVEL); + +#define DT_DRV_COMPAT silabs_acmp + +struct acmp_config { + ACMP_TypeDef *base; + const struct pinctrl_dev_config *pincfg; + const struct device *clock_dev; + const struct silabs_clock_control_cmu_config clock_cfg; + void (*irq_init)(void); + ACMP_Init_TypeDef init; + int input_negative; + int input_positive; +}; + +struct acmp_data { + uint32_t interrupt_mask; + comparator_callback_t callback; + void *user_data; +}; + +static int acmp_init(const struct device *dev) +{ + int err; + const struct acmp_config *config = dev->config; + + /* Enable ACMP Clock */ + err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg); + if (err < 0) { + return err; + } + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err < 0 && err != -ENOENT) { + LOG_ERR("failed to allocate silabs,analog-bus via pinctrl"); + return err; + } + + /* Initialize the ACMP */ + ACMP_Init(config->base, &config->init); + + /* Configure the ACMP Input Channels */ + ACMP_ChannelSet(config->base, config->input_negative, config->input_positive); + + /* Initialize the irq handler */ + config->irq_init(); + + return 0; +} + +static int acmp_get_output(const struct device *dev) +{ + const struct acmp_config *config = dev->config; + + return config->base->STATUS & ACMP_STATUS_ACMPOUT; +} + +static int acmp_set_trigger(const struct device *dev, enum comparator_trigger trigger) +{ + const struct acmp_config *config = dev->config; + struct acmp_data *data = dev->data; + + /* Disable ACMP trigger interrupts */ + ACMP_IntDisable(config->base, ACMP_IEN_RISE | ACMP_IEN_FALL); + + /* Clear ACMP trigger interrupt flags */ + ACMP_IntClear(config->base, ACMP_IEN_RISE | ACMP_IEN_FALL); + + switch (trigger) { + case COMPARATOR_TRIGGER_BOTH_EDGES: + data->interrupt_mask = ACMP_IEN_RISE | ACMP_IEN_FALL; + break; + case COMPARATOR_TRIGGER_RISING_EDGE: + data->interrupt_mask = ACMP_IEN_RISE; + break; + case COMPARATOR_TRIGGER_FALLING_EDGE: + data->interrupt_mask = ACMP_IEN_FALL; + break; + case COMPARATOR_TRIGGER_NONE: + data->interrupt_mask = 0; + break; + default: + return -EINVAL; + } + + /* Only enable interrupts when the trigger is not none and if a + * callback is set. + */ + if (data->interrupt_mask && data->callback != NULL) { + ACMP_IntEnable(config->base, data->interrupt_mask); + } + + return 0; +} + +static int acmp_set_trigger_callback(const struct device *dev, comparator_callback_t callback, + void *user_data) +{ + const struct acmp_config *config = dev->config; + struct acmp_data *data = dev->data; + + /* Disable ACMP trigger interrupts while setting callback */ + ACMP_IntDisable(config->base, ACMP_IEN_RISE | ACMP_IEN_FALL); + + data->callback = callback; + data->user_data = user_data; + + if (data->callback == NULL) { + return 0; + } + + /* Re-enable currently set ACMP trigger interrupts */ + if (data->interrupt_mask) { + ACMP_IntEnable(config->base, data->interrupt_mask); + } + + return 0; +} + +static int acmp_trigger_is_pending(const struct device *dev) +{ + const struct acmp_config *config = dev->config; + const struct acmp_data *data = dev->data; + + if (ACMP_IntGet(config->base) & data->interrupt_mask) { + ACMP_IntClear(config->base, data->interrupt_mask); + return 1; + } + + return 0; +} + +static void acmp_irq_handler(const struct device *dev) +{ + const struct acmp_config *config = dev->config; + struct acmp_data *data = dev->data; + + ACMP_IntClear(config->base, ACMP_IF_RISE | ACMP_IF_FALL); + + if (data->callback == NULL) { + return; + } + + data->callback(dev, data->user_data); +} + +static DEVICE_API(comparator, acmp_api) = { + .get_output = acmp_get_output, + .set_trigger = acmp_set_trigger, + .set_trigger_callback = acmp_set_trigger_callback, + .trigger_is_pending = acmp_trigger_is_pending, +}; + +#define ACMP_DEVICE(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + \ + static void acmp_irq_init##inst(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), acmp_irq_handler, \ + DEVICE_DT_INST_GET(inst), 0); \ + \ + irq_enable(DT_INST_IRQN(inst)); \ + } \ + \ + static struct acmp_data acmp_data##inst; \ + \ + static const struct acmp_config acmp_config##inst = { \ + .base = (ACMP_TypeDef *)DT_INST_REG_ADDR(inst), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \ + .clock_cfg = SILABS_DT_INST_CLOCK_CFG(inst), \ + .irq_init = acmp_irq_init##inst, \ + .init.biasProg = DT_INST_PROP(inst, bias), \ + .init.inputRange = DT_INST_ENUM_IDX(inst, input_range), \ + .init.accuracy = DT_INST_ENUM_IDX(inst, accuracy_mode), \ + .init.hysteresisLevel = DT_INST_ENUM_IDX(inst, hysteresis_mode), \ + .init.inactiveValue = false, \ + .init.vrefDiv = DT_INST_PROP(inst, vref_divider), \ + .init.enable = true, \ + .input_negative = DT_INST_PROP(inst, input_negative), \ + .input_positive = DT_INST_PROP(inst, input_positive), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, acmp_init, NULL, &acmp_data##inst, &acmp_config##inst, \ + POST_KERNEL, CONFIG_COMPARATOR_INIT_PRIORITY, &acmp_api); + +DT_INST_FOREACH_STATUS_OKAY(ACMP_DEVICE) diff --git a/drivers/console/Kconfig b/drivers/console/Kconfig index 2fd0111a9dd52..98ae6f7f84306 100644 --- a/drivers/console/Kconfig +++ b/drivers/console/Kconfig @@ -284,4 +284,20 @@ config WINSTREAM_CONSOLE See the WINSTREAM Kconfig help for more information. +config WINSTREAM_CONSOLE_STATIC + bool "Use static/linkable memory for the winstream console" + default y if !SOC_FAMILY_INTEL_ADSP + help + The winstream console can be configured to use simple linker + memory which can help avoid manual memory management at the + platform layer. The memory should be pointed to by the + symbol "_winstream_console_buf" and have size set by + CONFIG_WINSTREAM_CONSOLE_SIZE. + +config WINSTREAM_CONSOLE_STATIC_SIZE + int "Size of winstream console buffer" + default 32768 + help + Size of winstream console buffer, in bytes + endif # CONSOLE diff --git a/drivers/console/winstream_console.c b/drivers/console/winstream_console.c index 79794068ce81d..9a238326854d4 100644 --- a/drivers/console/winstream_console.c +++ b/drivers/console/winstream_console.c @@ -12,8 +12,10 @@ #include #include +#ifdef CONFIG_SOC_FAMILY_INTEL_ADSP #include #include +#endif struct k_spinlock trace_lock; @@ -58,19 +60,70 @@ static void winstream_console_hook_install(void) #endif } +/* This gets optionally defined by the platform layer as it needs (it + * might want to go in a special location to coordinate with linux + * userspace, etc...) + */ +extern char _winstream_console_buf[]; + +/* This descriptor with a 96-bit magic number gets linked into the + * binary when enabled so that external tooling can easily find it at + * runtime (e.g. by searching the binary image file, etc...) + */ +#define WINSTREAM_CONSOLE_MAGIC1 0xd06a5f74U +#define WINSTREAM_CONSOLE_MAGIC2 0x004fe279U +#define WINSTREAM_CONSOLE_MAGIC3 0xf9bdb8cdU + +struct winstream_console_desc { + uint32_t magic1; + uint32_t magic2; + uint32_t magic3; + uint32_t buf_addr; + uint32_t size; +}; + +static const __used struct winstream_console_desc wsdesc = { + .magic1 = WINSTREAM_CONSOLE_MAGIC1, + .magic2 = WINSTREAM_CONSOLE_MAGIC2, + .magic3 = WINSTREAM_CONSOLE_MAGIC3, + .buf_addr = (uint32_t) &_winstream_console_buf, + .size = CONFIG_WINSTREAM_CONSOLE_STATIC_SIZE, +}; static int winstream_console_init(void) { + void *buf = NULL; + size_t size = 0; + +#ifdef CONFIG_SOC_FAMILY_INTEL_ADSP + /* These have a SOC-specific "mem_window" device. FIXME: The + * type handling is backwards here. We shouldn't be grabbing + * an arbitrary DTS alias and assuming it's a mem_window at + * runtime, that's not safe. The mem_window init code (which + * is typesafe by construction) should be detecting that it's + * supposed to be the console and starting the console hook + * registration process. + */ const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); if (!device_is_ready(dev)) { return -ENODEV; } const struct mem_win_config *config = dev->config; - void *buf = - sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *)config->mem_base); + buf = sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *)config->mem_base); + size = config->size; +#endif + +#ifdef CONFIG_WINSTREAM_CONSOLE_STATIC + /* Dirty trick to prevent linker garbage collection */ + _winstream_console_buf[0] = ((volatile char*) &wsdesc)[0]; + + buf = &_winstream_console_buf; + size = CONFIG_WINSTREAM_CONSOLE_STATIC_SIZE; +#endif - winstream = sys_winstream_init(buf, config->size); + __ASSERT_NO_MSG(buf != NULL && size != 0); + winstream = sys_winstream_init(buf, size); winstream_console_hook_install(); return 0; diff --git a/drivers/counter/CMakeLists.txt b/drivers/counter/CMakeLists.txt index d406f7e2d625f..93a51369f572c 100644 --- a/drivers/counter/CMakeLists.txt +++ b/drivers/counter/CMakeLists.txt @@ -53,3 +53,4 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_TIMER_MAX32 counter_max32_ti zephyr_library_sources_ifdef(CONFIG_COUNTER_RTC_MAX32 counter_max32_rtc.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_NXP_MRT counter_nxp_mrt.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_RA_AGT counter_renesas_ra_agt.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_RENESAS_RZ_GTM counter_renesas_rz_gtm.c) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 32baf8255ce82..d9d1dcafcc5fa 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -104,4 +104,6 @@ source "drivers/counter/Kconfig.nxp_mrt" source "drivers/counter/Kconfig.renesas_ra" +source "drivers/counter/Kconfig.renesas_rz" + endif # COUNTER diff --git a/drivers/counter/Kconfig.mcux_rtc b/drivers/counter/Kconfig.mcux_rtc index 0ce5d0432f62e..7dc23d0a4f7ff 100644 --- a/drivers/counter/Kconfig.mcux_rtc +++ b/drivers/counter/Kconfig.mcux_rtc @@ -6,6 +6,6 @@ config COUNTER_MCUX_RTC bool "MCUX RTC driver" default y - depends on DT_HAS_NXP_KINETIS_RTC_ENABLED + depends on DT_HAS_NXP_RTC_ENABLED help - Enable support for mcux rtc driver. + Enable support for MCU RTC driver. diff --git a/drivers/counter/Kconfig.nrfx b/drivers/counter/Kconfig.nrfx index 321cf9de63479..775406a5198ca 100644 --- a/drivers/counter/Kconfig.nrfx +++ b/drivers/counter/Kconfig.nrfx @@ -9,6 +9,12 @@ config COUNTER_NRF_RTC def_bool y depends on DT_HAS_NORDIC_NRF_RTC_ENABLED +config COUNTER_NRFX_TIMER_USE_CLOCK_CONTROL + def_bool y + depends on $(dt_nodelabel_enabled,timer120) || \ + $(dt_nodelabel_enabled,timer121) + select CLOCK_CONTROL + # Internal flag which detects if PPI wrap feature is enabled for any instance config COUNTER_RTC_WITH_PPI_WRAP def_bool $(dt_nodelabel_bool_prop,rtc0,ppi-wrap) || \ diff --git a/drivers/counter/Kconfig.renesas_rz b/drivers/counter/Kconfig.renesas_rz new file mode 100644 index 0000000000000..4be934e33a9fe --- /dev/null +++ b/drivers/counter/Kconfig.renesas_rz @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config COUNTER_RENESAS_RZ_GTM + bool "Renesas RZ General Timer (GTM) Counter driver" + default y + depends on DT_HAS_RENESAS_RZ_GTM_COUNTER_ENABLED + select USE_RZ_FSP_GTM + help + Enable the counter driver for the Renesas RZ General Timer (GTM). diff --git a/drivers/counter/counter_esp32_tmr.c b/drivers/counter/counter_esp32_tmr.c index 275a42fa5fec0..3131b45a42b2c 100644 --- a/drivers/counter/counter_esp32_tmr.c +++ b/drivers/counter/counter_esp32_tmr.c @@ -1,33 +1,30 @@ /* - * Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT espressif_esp32_timer -/* Include esp-idf headers first to avoid redefining BIT() macro */ -#include -#include -#include +#include #include -#include #include #include -#include + #include -#include +#include #include -#if defined(CONFIG_SOC_SERIES_ESP32C2) || defined(CONFIG_SOC_SERIES_ESP32C3) +#if defined(CONFIG_RISCV) #include #else #include #endif #include #include + LOG_MODULE_REGISTER(esp32_counter, CONFIG_COUNTER_LOG_LEVEL); -#if defined(CONFIG_SOC_SERIES_ESP32C2) || defined(CONFIG_SOC_SERIES_ESP32C3) +#if defined(CONFIG_RISCV) #define ISR_HANDLER isr_handler_t #else #define ISR_HANDLER intr_handler_t @@ -47,6 +44,8 @@ struct timer_isr_func_t { struct counter_esp32_config { struct counter_config_info counter_info; timer_config_t config; + const struct device *clock_dev; + const clock_control_subsys_t clock_subsys; timer_group_t group; timer_idx_t index; int irq_source; @@ -57,31 +56,24 @@ struct counter_esp32_config { struct counter_esp32_data { struct counter_alarm_cfg alarm_cfg; uint32_t ticks; + uint32_t clock_src_hz; timer_hal_context_t hal_ctx; struct timer_isr_func_t timer_isr_fun; }; -static struct k_spinlock lock; - static int counter_esp32_init(const struct device *dev) { const struct counter_esp32_config *cfg = dev->config; struct counter_esp32_data *data = dev->data; - switch (cfg->group) { - case TIMER_GROUP_0: - periph_module_enable(PERIPH_TIMG0_MODULE); - break; -#if !defined(CONFIG_SOC_SERIES_ESP32C2) - case TIMER_GROUP_1: - periph_module_enable(PERIPH_TIMG1_MODULE); - break; -#endif - default: - return -ENOTSUP; + if (!device_is_ready(cfg->clock_dev)) { + return -ENODEV; } - k_spinlock_key_t key = k_spin_lock(&lock); + /* Return value is not checked below, as clock might have been already enabled + * by another timer of the same group. + */ + clock_control_on(cfg->clock_dev, cfg->clock_subsys); timer_hal_init(&data->hal_ctx, cfg->group, cfg->index); data->alarm_cfg.callback = NULL; @@ -90,6 +82,8 @@ static int counter_esp32_init(const struct device *dev) timer_ll_clear_intr_status(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id)); timer_ll_enable_auto_reload(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.auto_reload); + timer_ll_set_clock_source(data->hal_ctx.dev, data->hal_ctx.timer_id, + GPTIMER_CLK_SRC_DEFAULT); timer_ll_set_clock_prescale(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.divider); timer_ll_set_count_direction(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.counter_dir); @@ -97,7 +91,8 @@ static int counter_esp32_init(const struct device *dev) timer_ll_set_reload_value(data->hal_ctx.dev, data->hal_ctx.timer_id, 0); timer_ll_enable_counter(data->hal_ctx.dev, data->hal_ctx.timer_id, cfg->config.counter_en); - k_spin_unlock(&lock, key); + esp_clk_tree_src_get_freq_hz(GPTIMER_CLK_SRC_DEFAULT, + ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &data->clock_src_hz); int ret = esp_intr_alloc(cfg->irq_source, ESP_PRIO_TO_FLAGS(cfg->irq_priority) | @@ -114,10 +109,8 @@ static int counter_esp32_init(const struct device *dev) static int counter_esp32_start(const struct device *dev) { struct counter_esp32_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&lock); timer_ll_enable_counter(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_START); - k_spin_unlock(&lock, key); return 0; } @@ -125,10 +118,8 @@ static int counter_esp32_start(const struct device *dev) static int counter_esp32_stop(const struct device *dev) { struct counter_esp32_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&lock); timer_ll_enable_counter(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_PAUSE); - k_spin_unlock(&lock, key); return 0; } @@ -136,26 +127,20 @@ static int counter_esp32_stop(const struct device *dev) static int counter_esp32_get_value(const struct device *dev, uint32_t *ticks) { struct counter_esp32_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&lock); timer_ll_trigger_soft_capture(data->hal_ctx.dev, data->hal_ctx.timer_id); *ticks = (uint32_t)timer_ll_get_counter_value(data->hal_ctx.dev, data->hal_ctx.timer_id); - k_spin_unlock(&lock, key); - return 0; } static int counter_esp32_get_value_64(const struct device *dev, uint64_t *ticks) { struct counter_esp32_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&lock); timer_ll_trigger_soft_capture(data->hal_ctx.dev, data->hal_ctx.timer_id); *ticks = timer_ll_get_counter_value(data->hal_ctx.dev, data->hal_ctx.timer_id); - k_spin_unlock(&lock, key); - return 0; } @@ -168,8 +153,6 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id, counter_esp32_get_value(dev, &now); - k_spinlock_key_t key = k_spin_lock(&lock); - if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) { timer_ll_set_alarm_value(data->hal_ctx.dev, data->hal_ctx.timer_id, (now + alarm_cfg->ticks)); @@ -182,7 +165,6 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id, timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_ALARM_EN); data->alarm_cfg.callback = alarm_cfg->callback; data->alarm_cfg.user_data = alarm_cfg->user_data; - k_spin_unlock(&lock, key); return 0; } @@ -192,12 +174,9 @@ static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id) ARG_UNUSED(chan_id); struct counter_esp32_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&lock); - timer_ll_enable_intr(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id), false); timer_ll_enable_alarm(data->hal_ctx.dev, data->hal_ctx.timer_id, TIMER_ALARM_DIS); - k_spin_unlock(&lock, key); return 0; } @@ -227,6 +206,14 @@ static uint32_t counter_esp32_get_top_value(const struct device *dev) return config->counter_info.max_top_value; } +uint32_t counter_esp32_get_freq(const struct device *dev) +{ + const struct counter_esp32_config *config = dev->config; + struct counter_esp32_data *data = dev->data; + + return data->clock_src_hz / config->config.divider; +} + static DEVICE_API(counter, counter_api) = { .start = counter_esp32_start, .stop = counter_esp32_stop, @@ -237,6 +224,7 @@ static DEVICE_API(counter, counter_api) = { .set_top_value = counter_esp32_set_top_value, .get_pending_int = counter_esp32_get_pending_int, .get_top_value = counter_esp32_get_top_value, + .get_freq = counter_esp32_get_freq, }; static void counter_esp32_isr(void *arg) @@ -255,13 +243,6 @@ static void counter_esp32_isr(void *arg) timer_ll_clear_intr_status(data->hal_ctx.dev, TIMER_LL_EVENT_ALARM(data->hal_ctx.timer_id)); } -#if defined(CONFIG_SOC_SERIES_ESP32C2) -#define CLK_LL_PLL_40M_FREQ MHZ(40) -#define CLOCK_SOURCE_FREQ CLK_LL_PLL_40M_FREQ -#else -#define CLOCK_SOURCE_FREQ APB_CLK_FREQ -#endif - #define ESP32_COUNTER_GET_CLK_DIV(idx) \ (((DT_INST_PROP(idx, prescaler) & UINT16_MAX) < 2) \ ? 2 \ @@ -273,7 +254,6 @@ static void counter_esp32_isr(void *arg) \ static const struct counter_esp32_config counter_config_##idx = { \ .counter_info = {.max_top_value = UINT32_MAX, \ - .freq = (CLOCK_SOURCE_FREQ / ESP32_COUNTER_GET_CLK_DIV(idx)), \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ .config = \ @@ -285,6 +265,8 @@ static void counter_esp32_isr(void *arg) .auto_reload = TIMER_AUTORELOAD_DIS, \ .divider = ESP32_COUNTER_GET_CLK_DIV(idx), \ }, \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(idx, offset), \ .group = DT_INST_PROP(idx, group), \ .index = DT_INST_PROP(idx, index), \ .irq_source = DT_INST_IRQ_BY_IDX(idx, 0, irq), \ diff --git a/drivers/counter/counter_ll_stm32_timer.c b/drivers/counter/counter_ll_stm32_timer.c index dab9d4b167f5f..c7a6216ac6642 100644 --- a/drivers/counter/counter_ll_stm32_timer.c +++ b/drivers/counter/counter_ll_stm32_timer.c @@ -383,7 +383,10 @@ static int counter_stm32_get_tim_clk(const struct stm32_pclken *pclken, uint32_t return r; } -#if defined(CONFIG_SOC_SERIES_STM32H7X) +#if defined(CONFIG_SOC_SERIES_STM32WB0X) + /* Timers are clocked by SYSCLK on STM32WB0 */ + apb_psc = 1; +#elif defined(CONFIG_SOC_SERIES_STM32H7X) if (pclken->bus == STM32_CLOCK_BUS_APB1) { apb_psc = STM32_D2PPRE1; } else { diff --git a/drivers/counter/counter_max32_rtc.c b/drivers/counter/counter_max32_rtc.c index 74e5c86f3b66d..832a1394508cf 100644 --- a/drivers/counter/counter_max32_rtc.c +++ b/drivers/counter/counter_max32_rtc.c @@ -38,11 +38,6 @@ struct max32_rtc_config { static int api_start(const struct device *dev) { - /* Ensure that both sec and subsec are reset to 0 */ - while (MXC_RTC_Init(0, 0) == E_BUSY) { - ; - } - while (MXC_RTC_Start() == E_BUSY) { ; } diff --git a/drivers/counter/counter_mcux_gpt.c b/drivers/counter/counter_mcux_gpt.c index 3ea46c5b3a226..c0e714ea41dc1 100644 --- a/drivers/counter/counter_mcux_gpt.c +++ b/drivers/counter/counter_mcux_gpt.c @@ -28,6 +28,7 @@ struct mcux_gpt_config { const struct device *clock_dev; clock_control_subsys_t clock_subsys; clock_name_t clock_source; + void (*irq_config_func)(void); }; struct mcux_gpt_data { @@ -210,6 +211,8 @@ static int mcux_gpt_init(const struct device *dev) base = get_base(dev); GPT_Init(base, &gptConfig); + config->irq_config_func(); + return 0; } @@ -226,6 +229,7 @@ static DEVICE_API(counter, mcux_gpt_driver_api) = { #define GPT_DEVICE_INIT_MCUX(n) \ static struct mcux_gpt_data mcux_gpt_data_ ## n; \ + static void mcux_gpt_irq_config_ ## n(void); \ \ static const struct mcux_gpt_config mcux_gpt_config_ ## n = { \ DEVICE_MMIO_NAMED_ROM_INIT(gpt_mmio, DT_DRV_INST(n)), \ @@ -238,11 +242,11 @@ static DEVICE_API(counter, mcux_gpt_driver_api) = { .channels = 1, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ }, \ + .irq_config_func = mcux_gpt_irq_config_ ## n, \ }; \ \ - static int mcux_gpt_## n ##_init(const struct device *dev); \ DEVICE_DT_INST_DEFINE(n, \ - mcux_gpt_## n ##_init, \ + mcux_gpt_init, \ NULL, \ &mcux_gpt_data_ ## n, \ &mcux_gpt_config_ ## n, \ @@ -250,13 +254,12 @@ static DEVICE_API(counter, mcux_gpt_driver_api) = { CONFIG_COUNTER_INIT_PRIORITY, \ &mcux_gpt_driver_api); \ \ - static int mcux_gpt_## n ##_init(const struct device *dev) \ + static void mcux_gpt_irq_config_ ## n(void) \ { \ IRQ_CONNECT(DT_INST_IRQN(n), \ DT_INST_IRQ(n, priority), \ mcux_gpt_isr, DEVICE_DT_INST_GET(n), 0); \ irq_enable(DT_INST_IRQN(n)); \ - return mcux_gpt_init(dev); \ } \ DT_INST_FOREACH_STATUS_OKAY(GPT_DEVICE_INIT_MCUX) diff --git a/drivers/counter/counter_mcux_rtc.c b/drivers/counter/counter_mcux_rtc.c index cb11c476e7a26..eb0d964a96dd2 100644 --- a/drivers/counter/counter_mcux_rtc.c +++ b/drivers/counter/counter_mcux_rtc.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nxp_kinetis_rtc +#define DT_DRV_COMPAT nxp_rtc #include #include @@ -14,6 +14,16 @@ #include #include +/* + * FSL_FEATURE_* is defined with paranethesis + * which is not acceptable when using the IS_ENABLED() macro + */ +#if (defined(FSL_FEATURE_RTC_HAS_LPO_ADJUST) && FSL_FEATURE_RTC_HAS_LPO_ADJUST) +#define NXP_RTC_HAS_LPO_ADJUST 1 +#else +#define NXP_RTC_HAS_LPO_ADJUST 0 +#endif + LOG_MODULE_REGISTER(mcux_rtc, CONFIG_COUNTER_LOG_LEVEL); struct mcux_rtc_data { @@ -241,9 +251,10 @@ static int mcux_rtc_init(const struct device *dev) * "LPO": 1 */ BUILD_ASSERT((((DT_INST_ENUM_IDX(0, clock_source) == 1) && - FSL_FEATURE_RTC_HAS_LPO_ADJUST) || + NXP_RTC_HAS_LPO_ADJUST) || DT_INST_ENUM_IDX(0, clock_source) == 0), "Cannot choose the LPO clock for that instance of the RTC"); + #if (defined(FSL_FEATURE_RTC_HAS_LPO_ADJUST) && FSL_FEATURE_RTC_HAS_LPO_ADJUST) /* The RTC prescaler increments using the LPO 1 kHz clock * instead of the RTC clock diff --git a/drivers/counter/counter_mcux_tpm.c b/drivers/counter/counter_mcux_tpm.c index 51b0d95aec1f9..059b057ada2a1 100644 --- a/drivers/counter/counter_mcux_tpm.c +++ b/drivers/counter/counter_mcux_tpm.c @@ -28,6 +28,7 @@ struct mcux_tpm_config { tpm_clock_source_t tpm_clock_source; tpm_clock_prescale_t prescale; + void (*irq_config_func)(void); }; struct mcux_tpm_data { @@ -248,6 +249,8 @@ static int mcux_tpm_init(const struct device *dev) /* Set the modulo to max value. */ base->MOD = TPM_MAX_COUNTER_VALUE(base); + config->irq_config_func(); + return 0; } @@ -267,6 +270,7 @@ static DEVICE_API(counter, mcux_tpm_driver_api) = { #define TPM_DEVICE_INIT_MCUX(n) \ static struct mcux_tpm_data mcux_tpm_data_ ## n; \ + static void mcux_tpm_irq_config_ ## n(void); \ \ static const struct mcux_tpm_config mcux_tpm_config_ ## n = { \ DEVICE_MMIO_NAMED_ROM_INIT(tpm_mmio, DT_DRV_INST(n)), \ @@ -281,11 +285,11 @@ static DEVICE_API(counter, mcux_tpm_driver_api) = { .channels = 1, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ }, \ + .irq_config_func = mcux_tpm_irq_config_ ## n, \ }; \ \ - static int mcux_tpm_## n ##_init(const struct device *dev); \ DEVICE_DT_INST_DEFINE(n, \ - mcux_tpm_## n ##_init, \ + mcux_tpm_init, \ NULL, \ &mcux_tpm_data_ ## n, \ &mcux_tpm_config_ ## n, \ @@ -293,13 +297,12 @@ static DEVICE_API(counter, mcux_tpm_driver_api) = { CONFIG_COUNTER_INIT_PRIORITY, \ &mcux_tpm_driver_api); \ \ - static int mcux_tpm_## n ##_init(const struct device *dev) \ + static void mcux_tpm_irq_config_ ## n(void) \ { \ IRQ_CONNECT(DT_INST_IRQN(n), \ DT_INST_IRQ(n, priority), \ mcux_tpm_isr, DEVICE_DT_INST_GET(n), 0); \ irq_enable(DT_INST_IRQN(n)); \ - return mcux_tpm_init(dev); \ } \ DT_INST_FOREACH_STATUS_OKAY(TPM_DEVICE_INIT_MCUX) diff --git a/drivers/counter/counter_nrfx_timer.c b/drivers/counter/counter_nrfx_timer.c index ed67dbde06267..afbdb4ed1adac 100644 --- a/drivers/counter/counter_nrfx_timer.c +++ b/drivers/counter/counter_nrfx_timer.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ #include +#include +#include #include #include @@ -32,11 +34,32 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL); #define MAYBE_CONST_CONFIG const #endif +#ifdef CONFIG_SOC_NRF54H20_GPD +#include + +#define NRF_CLOCKS_INSTANCE_IS_FAST(node) \ + COND_CODE_1(DT_NODE_HAS_PROP(node, power_domains), \ + (IS_EQ(DT_PHA(node, power_domains, id), NRF_GPD_FAST_ACTIVE1)), \ + (0)) + +/* Macro must resolve to literal 0 or 1 */ +#define INSTANCE_IS_FAST(idx) NRF_CLOCKS_INSTANCE_IS_FAST(DT_DRV_INST(idx)) + +#define INSTANCE_IS_FAST_OR(idx) INSTANCE_IS_FAST(idx) || + +#if (DT_INST_FOREACH_STATUS_OKAY(INSTANCE_IS_FAST_OR) 0) +#define COUNTER_ANY_FAST 1 +#endif +#endif + struct counter_nrfx_data { counter_top_callback_t top_cb; void *top_user_data; uint32_t guard_period; atomic_t cc_int_pending; +#ifdef COUNTER_ANY_FAST + atomic_t active; +#endif }; struct counter_nrfx_ch_data { @@ -48,6 +71,10 @@ struct counter_nrfx_config { struct counter_config_info info; struct counter_nrfx_ch_data *ch_data; NRF_TIMER_Type *timer; +#ifdef COUNTER_ANY_FAST + const struct device *clk_dev; + struct nrf_clock_spec clk_spec; +#endif LOG_INSTANCE_PTR_DECLARE(log); }; @@ -61,6 +88,18 @@ static int start(const struct device *dev) { const struct counter_nrfx_config *config = dev->config; +#ifdef COUNTER_ANY_FAST + struct counter_nrfx_data *data = dev->data; + + if (config->clk_dev && atomic_cas(&data->active, 0, 1)) { + int err; + + err = nrf_clock_control_request_sync(config->clk_dev, &config->clk_spec, K_FOREVER); + if (err < 0) { + return err; + } + } +#endif nrf_timer_task_trigger(config->timer, NRF_TIMER_TASK_START); return 0; @@ -71,6 +110,18 @@ static int stop(const struct device *dev) const struct counter_nrfx_config *config = dev->config; nrf_timer_task_trigger(config->timer, NRF_TIMER_TASK_STOP); +#ifdef COUNTER_ANY_FAST + struct counter_nrfx_data *data = dev->data; + + if (config->clk_dev && atomic_cas(&data->active, 1, 0)) { + int err; + + err = nrf_clock_control_release(config->clk_dev, &config->clk_spec); + if (err < 0) { + return err; + } + } +#endif return 0; } @@ -403,6 +454,20 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { .set_guard_period = set_guard_period, }; +/* Get initialization level of an instance. Instances that requires clock control + * which is using nrfs (IPC) are initialized later. + */ +#define TIMER_INIT_LEVEL(idx) \ + COND_CODE_1(INSTANCE_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1)) + +/* Get initialization priority of an instance. Instances that requires clock control + * which is using nrfs (IPC) are initialized later. + */ +#define TIMER_INIT_PRIO(idx) \ + COND_CODE_1(INSTANCE_IS_FAST(idx), \ + (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \ + (CONFIG_COUNTER_INIT_PRIORITY)) + /* * Device instantiation is done with node labels due to HAL API * requirements. In particular, TIMERx_MAX_SIZE values from HALs @@ -419,14 +484,6 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { irq_handler, DEVICE_DT_INST_GET(idx), 0)) \ ) -#if !defined(CONFIG_SOC_SERIES_BSIM_NRFXX) -#define CHECK_MAX_FREQ(idx) \ - BUILD_ASSERT(DT_INST_PROP(idx, max_frequency) == \ - NRF_TIMER_BASE_FREQUENCY_GET((NRF_TIMER_Type *)DT_INST_REG_ADDR(idx))) -#else -#define CHECK_MAX_FREQ(idx) -#endif - #define COUNTER_NRFX_TIMER_DEVICE(idx) \ BUILD_ASSERT(DT_INST_PROP(idx, prescaler) <= \ TIMER_PRESCALER_PRESCALER_Msk, \ @@ -456,22 +513,29 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = { static MAYBE_CONST_CONFIG struct counter_nrfx_config nrfx_counter_##idx##_config = { \ .info = { \ .max_top_value = (uint32_t)BIT64_MASK(DT_INST_PROP(idx, max_bit_width)),\ - .freq = DT_INST_PROP(idx, max_frequency) / \ + .freq = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)) / \ BIT(DT_INST_PROP(idx, prescaler)), \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = CC_TO_ID(DT_INST_PROP(idx, cc_num)), \ }, \ .ch_data = counter##idx##_ch_data, \ .timer = (NRF_TIMER_Type *)DT_INST_REG_ADDR(idx), \ + IF_ENABLED(INSTANCE_IS_FAST(idx), \ + (.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_DRV_INST(idx))), \ + .clk_spec = { \ + .frequency = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)), \ + .accuracy = 0, \ + .precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT, \ + }, \ + )) \ LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx) \ }; \ - CHECK_MAX_FREQ(idx); \ DEVICE_DT_INST_DEFINE(idx, \ counter_##idx##_init, \ NULL, \ &counter_##idx##_data, \ &nrfx_counter_##idx##_config.info, \ - PRE_KERNEL_1, CONFIG_COUNTER_INIT_PRIORITY, \ + TIMER_INIT_LEVEL(idx), TIMER_INIT_PRIO(idx), \ &counter_nrfx_driver_api); DT_INST_FOREACH_STATUS_OKAY(COUNTER_NRFX_TIMER_DEVICE) diff --git a/drivers/counter/counter_renesas_rz_gtm.c b/drivers/counter/counter_renesas_rz_gtm.c new file mode 100644 index 0000000000000..836d213d776a2 --- /dev/null +++ b/drivers/counter/counter_renesas_rz_gtm.c @@ -0,0 +1,553 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rz_gtm_counter + +#include +#include +#include +#include + +#define RZ_GTM_TOP_VALUE UINT32_MAX + +#define counter_rz_gtm_clear_pending(irq) NVIC_ClearPendingIRQ(irq) +#define counter_rz_gtm_set_pending(irq) NVIC_SetPendingIRQ(irq) +#define counter_rz_gtm_is_pending(irq) NVIC_GetPendingIRQ(irq) + +struct counter_rz_gtm_config { + struct counter_config_info config_info; + const timer_api_t *fsp_api; + uint8_t irqn; +}; + +struct counter_rz_gtm_data { + timer_cfg_t *fsp_cfg; + gtm_instance_ctrl_t *fsp_ctrl; + /* top callback function */ + counter_top_callback_t top_cb; + /* alarm callback function */ + counter_alarm_callback_t alarm_cb; + void *user_data; + uint32_t clk_freq; + struct k_spinlock lock; + uint32_t guard_period; + uint32_t top_val; + bool is_started; + bool is_periodic; +}; + +static int counter_rz_gtm_get_value(const struct device *dev, uint32_t *ticks) +{ + const struct counter_rz_gtm_config *cfg = dev->config; + struct counter_rz_gtm_data *data = dev->data; + timer_status_t timer_status; + fsp_err_t err; + + err = cfg->fsp_api->statusGet(data->fsp_ctrl, &timer_status); + if (err != FSP_SUCCESS) { + return err; + } + uint32_t value = (uint32_t)timer_status.counter; + *ticks = value; + + return 0; +} + +static void counter_rz_gtm_irq_handler(timer_callback_args_t *p_args) +{ + const struct device *dev = p_args->p_context; + struct counter_rz_gtm_data *data = dev->data; + counter_alarm_callback_t alarm_callback = data->alarm_cb; + k_spinlock_key_t key; + + key = k_spin_lock(&data->lock); + + if (alarm_callback) { + uint32_t now; + + counter_rz_gtm_get_value(dev, &now); + data->alarm_cb = NULL; + alarm_callback(dev, 0, now, data->user_data); + } else if (data->top_cb) { + data->top_cb(dev, data->user_data); + } + + k_spin_unlock(&data->lock, key); +} + +static int counter_rz_gtm_init(const struct device *dev) +{ + struct counter_rz_gtm_data *data = dev->data; + const struct counter_rz_gtm_config *cfg = dev->config; + int err; + + data->top_val = data->fsp_cfg->period_counts; + + err = cfg->fsp_api->open(data->fsp_ctrl, data->fsp_cfg); + if (err != FSP_SUCCESS) { + return err; + } + return err; +} + +static void counter_rz_gtm_start_freerun(const struct device *dev) +{ + /* enable counter in free running mode */ + const struct counter_rz_gtm_config *cfg = dev->config; + struct counter_rz_gtm_data *data = dev->data; + + gtm_extended_cfg_t *fsp_cfg_extend = (gtm_extended_cfg_t *)data->fsp_cfg->p_extend; + + fsp_cfg_extend->gtm_mode = GTM_TIMER_MODE_FREERUN; + cfg->fsp_api->close(data->fsp_ctrl); + cfg->fsp_api->open(data->fsp_ctrl, data->fsp_cfg); + cfg->fsp_api->start(data->fsp_ctrl); +} + +static void counter_rz_gtm_start_interval(const struct device *dev) +{ + /* start timer in interval mode */ + const struct counter_rz_gtm_config *cfg = dev->config; + struct counter_rz_gtm_data *data = dev->data; + + gtm_extended_cfg_t *fsp_cfg_extend = (gtm_extended_cfg_t *)data->fsp_cfg->p_extend; + + fsp_cfg_extend->gtm_mode = GTM_TIMER_MODE_INTERVAL; + cfg->fsp_api->close(data->fsp_ctrl); + cfg->fsp_api->open(data->fsp_ctrl, data->fsp_cfg); + cfg->fsp_api->start(data->fsp_ctrl); +} + +static int counter_rz_gtm_start(const struct device *dev) +{ + const struct counter_rz_gtm_config *cfg = dev->config; + struct counter_rz_gtm_data *data = dev->data; + k_spinlock_key_t key; + + key = k_spin_lock(&data->lock); + + if (data->is_started) { + k_spin_unlock(&data->lock, key); + return -EALREADY; + } + + if (data->is_periodic) { + data->fsp_cfg->period_counts = data->top_val; + counter_rz_gtm_start_interval(dev); + } else { + counter_rz_gtm_start_freerun(dev); + } + + counter_rz_gtm_clear_pending(cfg->irqn); + data->is_started = true; + if (data->top_cb) { + irq_enable(cfg->irqn); + } + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int counter_rz_gtm_stop(const struct device *dev) +{ + const struct counter_rz_gtm_config *cfg = dev->config; + struct counter_rz_gtm_data *data = dev->data; + k_spinlock_key_t key; + + key = k_spin_lock(&data->lock); + + if (!data->is_started) { + k_spin_unlock(&data->lock, key); + return 0; + } + + fsp_err_t err = FSP_SUCCESS; + + /* Stop timer */ + err = cfg->fsp_api->stop(data->fsp_ctrl); + + /* dis irq */ + irq_disable(cfg->irqn); + counter_rz_gtm_clear_pending(cfg->irqn); + + data->top_cb = NULL; + data->alarm_cb = NULL; + data->user_data = NULL; + + data->is_started = false; + + k_spin_unlock(&data->lock, key); + + return err; +} + +static int counter_rz_gtm_set_alarm(const struct device *dev, uint8_t chan, + const struct counter_alarm_cfg *alarm_cfg) +{ + const struct counter_rz_gtm_config *cfg = dev->config; + struct counter_rz_gtm_data *data = dev->data; + + bool absolute = alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE; + uint32_t val = alarm_cfg->ticks; + k_spinlock_key_t key; + bool irq_on_late; + uint32_t max_rel_val; + uint32_t now, diff; + int err = 0; + + if (!alarm_cfg) { + return -EINVAL; + } + /* Alarm callback is mandatory */ + if (!alarm_cfg->callback) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + + if (!data->is_started) { + k_spin_unlock(&data->lock, key); + return -EINVAL; + } + + /** Alarm_cb need equal NULL before */ + if (data->alarm_cb) { + k_spin_unlock(&data->lock, key); + return -EBUSY; + } + + /** Timer is currently in interval mode*/ + if (data->is_periodic) { + /** return error because val exceeded the limit set alarm */ + if (val > data->fsp_cfg->period_counts) { + k_spin_unlock(&data->lock, key); + return -EINVAL; + } + + /* restore free running mode */ + irq_disable(cfg->irqn); + data->top_cb = NULL; + data->alarm_cb = alarm_cfg->callback; + data->user_data = NULL; + data->top_val = RZ_GTM_TOP_VALUE; + data->is_periodic = false; + + if (data->is_started) { + data->fsp_cfg->period_counts = data->top_val; + counter_rz_gtm_start_freerun(dev); + } + } + + counter_rz_gtm_get_value(dev, &now); + data->alarm_cb = alarm_cfg->callback; + data->user_data = alarm_cfg->user_data; + + if (absolute) { + max_rel_val = RZ_GTM_TOP_VALUE - data->guard_period; + irq_on_late = alarm_cfg->flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE; + } else { + /* If relative value is smaller than half of the counter range + * it is assumed that there is a risk of setting value too late + * and late detection algorithm must be applied. When late + * setting is detected, interrupt shall be triggered for + * immediate expiration of the timer. Detection is performed + * by limiting relative distance between CC and counter. + * + * Note that half of counter range is an arbitrary value. + */ + irq_on_late = val < (RZ_GTM_TOP_VALUE / 2U); + /* limit max to detect short relative being set too late. */ + max_rel_val = irq_on_late ? RZ_GTM_TOP_VALUE / 2U : RZ_GTM_TOP_VALUE; + val = (now + val) & RZ_GTM_TOP_VALUE; + } + + /** Set new period */ + data->fsp_cfg->period_counts = val; + err = cfg->fsp_api->periodSet(data->fsp_ctrl, data->fsp_cfg->period_counts); + if (err != FSP_SUCCESS) { + k_spin_unlock(&data->lock, key); + return err; + } + + uint32_t read_counter_again = 0; + + counter_rz_gtm_get_value(dev, &read_counter_again); + diff = ((val - 1U) - read_counter_again) & RZ_GTM_TOP_VALUE; + if (diff > max_rel_val) { + if (absolute) { + err = -ETIME; + } + + /* Interrupt is triggered always for relative alarm and + * for absolute depending on the flag. + */ + if (irq_on_late) { + irq_enable(cfg->irqn); + counter_rz_gtm_set_pending(cfg->irqn); + } else { + data->alarm_cb = NULL; + } + } else { + if (diff == 0) { + /* RELOAD value could be set just in time for interrupt + * trigger or too late. In any case time is interrupt + * should be triggered. No need to enable interrupt + * on TIMER just make sure interrupt is pending. + */ + irq_enable(cfg->irqn); + counter_rz_gtm_set_pending(cfg->irqn); + } else { + counter_rz_gtm_clear_pending(cfg->irqn); + irq_enable(cfg->irqn); + } + } + + k_spin_unlock(&data->lock, key); + + return err; +} + +static int counter_rz_gtm_cancel_alarm(const struct device *dev, uint8_t chan) +{ + const struct counter_rz_gtm_config *cfg = dev->config; + struct counter_rz_gtm_data *data = dev->data; + k_spinlock_key_t key; + + ARG_UNUSED(chan); + + key = k_spin_lock(&data->lock); + + if (!data->is_started) { + k_spin_unlock(&data->lock, key); + return -EINVAL; + } + + if (!data->alarm_cb) { + k_spin_unlock(&data->lock, key); + return 0; + } + + irq_disable(cfg->irqn); + counter_rz_gtm_clear_pending(cfg->irqn); + data->alarm_cb = NULL; + data->user_data = NULL; + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int counter_rz_gtm_set_top_value(const struct device *dev, + const struct counter_top_cfg *top_cfg) +{ + const struct counter_rz_gtm_config *cfg = dev->config; + struct counter_rz_gtm_data *data = dev->data; + k_spinlock_key_t key; + uint32_t cur_tick; + int ret = 0; + + if (!top_cfg) { + return -EINVAL; + } + + /** -EBUSY if any alarm is active */ + if (data->alarm_cb) { + return -EBUSY; + } + + key = k_spin_lock(&data->lock); + + if (!data->is_periodic && top_cfg->ticks == RZ_GTM_TOP_VALUE) { + goto exit_unlock; + } + + if (top_cfg->ticks == RZ_GTM_TOP_VALUE) { + /* restore free running mode */ + irq_disable(cfg->irqn); + counter_rz_gtm_clear_pending(cfg->irqn); + data->top_cb = NULL; + data->user_data = NULL; + data->top_val = RZ_GTM_TOP_VALUE; + data->is_periodic = false; + + if (data->is_started) { + counter_rz_gtm_start_freerun(dev); + counter_rz_gtm_clear_pending(cfg->irqn); + } + goto exit_unlock; + } + + data->top_cb = top_cfg->callback; + data->user_data = top_cfg->user_data; + data->top_val = top_cfg->ticks; + + if (!data->is_started) { + data->is_periodic = true; + goto exit_unlock; + } + + if (!data->is_periodic) { + /* switch to interval mode first time, restart timer */ + ret = cfg->fsp_api->stop(data->fsp_ctrl); + irq_disable(cfg->irqn); + data->is_periodic = true; + data->fsp_cfg->period_counts = data->top_val; + counter_rz_gtm_start_interval(dev); + + if (data->top_cb) { + counter_rz_gtm_clear_pending(cfg->irqn); + irq_enable(cfg->irqn); + } + goto exit_unlock; + } + + if (!data->top_cb) { + /* new top cfg is without callback - stop IRQs */ + irq_disable(cfg->irqn); + counter_rz_gtm_clear_pending(cfg->irqn); + } + /* timer already in interval mode - only change top value */ + data->fsp_cfg->period_counts = data->top_val; + cfg->fsp_api->periodSet(&data->fsp_ctrl, data->fsp_cfg->period_counts); + + /* check if counter reset is required */ + if (top_cfg->flags & COUNTER_TOP_CFG_DONT_RESET) { + /* Don't reset counter */ + counter_rz_gtm_get_value(dev, &cur_tick); + + if (cur_tick >= data->top_val) { + ret = -ETIME; + if (top_cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE) { + /* Reset counter if current is late */ + cfg->fsp_api->stop(data->fsp_ctrl); + cfg->fsp_api->start(data->fsp_ctrl); + } + } + } else { + /* reset counter */ + cfg->fsp_api->stop(data->fsp_ctrl); + cfg->fsp_api->start(data->fsp_ctrl); + } + +exit_unlock: + k_spin_unlock(&data->lock, key); + return ret; +} + +static uint32_t counter_rz_gtm_get_pending_int(const struct device *dev) +{ + const struct counter_rz_gtm_config *cfg = dev->config; + + /* There is no register to check TIMER peripheral to check for interrupt + * pending, check directly in NVIC. + */ + return counter_rz_gtm_is_pending(cfg->irqn); +} + +static uint32_t counter_rz_gtm_get_top_value(const struct device *dev) +{ + struct counter_rz_gtm_data *data = dev->data; + const struct counter_rz_gtm_config *cfg = dev->config; + uint32_t top_val = RZ_GTM_TOP_VALUE; + + if (data->is_periodic) { + timer_info_t info; + + cfg->fsp_api->infoGet(data->fsp_ctrl, &info); + top_val = info.period_counts; + } + + return top_val; +} +static uint32_t counter_rz_gtm_get_guard_period(const struct device *dev, uint32_t flags) +{ + struct counter_rz_gtm_data *data = dev->data; + + ARG_UNUSED(flags); + return data->guard_period; +} + +static int counter_rz_gtm_set_guard_period(const struct device *dev, uint32_t guard, uint32_t flags) +{ + struct counter_rz_gtm_data *data = dev->data; + + ARG_UNUSED(flags); + __ASSERT_NO_MSG(guard < counter_rz_gtm_get_top_value(dev)); + + data->guard_period = guard; + + return 0; +} + +static uint32_t counter_rz_gtm_get_freq(const struct device *dev) +{ + struct counter_rz_gtm_data *data = dev->data; + const struct counter_rz_gtm_config *cfg = dev->config; + timer_info_t info; + + cfg->fsp_api->infoGet(data->fsp_ctrl, &info); + + return info.clock_frequency; +} + +static DEVICE_API(counter, counter_rz_gtm_driver_api) = { + .start = counter_rz_gtm_start, + .stop = counter_rz_gtm_stop, + .get_value = counter_rz_gtm_get_value, + .set_alarm = counter_rz_gtm_set_alarm, + .cancel_alarm = counter_rz_gtm_cancel_alarm, + .set_top_value = counter_rz_gtm_set_top_value, + .get_pending_int = counter_rz_gtm_get_pending_int, + .get_top_value = counter_rz_gtm_get_top_value, + .get_guard_period = counter_rz_gtm_get_guard_period, + .set_guard_period = counter_rz_gtm_set_guard_period, + .get_freq = counter_rz_gtm_get_freq, +}; + +extern void gtm_int_isr(void); + +#define GTM(idx) DT_INST_PARENT(idx) + +#define COUNTER_RZG_GTM_INIT(inst) \ + static gtm_instance_ctrl_t g_timer##inst##_ctrl; \ + static gtm_extended_cfg_t g_timer##inst##_extend = { \ + .generate_interrupt_when_starts = GTM_GIWS_TYPE_DISABLED, \ + .gtm_mode = GTM_TIMER_MODE_FREERUN, \ + }; \ + static timer_cfg_t g_timer##inst##_cfg = { \ + .mode = TIMER_MODE_PERIODIC, \ + .period_counts = (uint32_t)RZ_GTM_TOP_VALUE, \ + .channel = DT_PROP(GTM(inst), channel), \ + .p_callback = counter_rz_gtm_irq_handler, \ + .p_context = DEVICE_DT_GET(DT_DRV_INST(inst)), \ + .p_extend = &g_timer##inst##_extend, \ + .cycle_end_ipl = DT_IRQ_BY_NAME(GTM(inst), overflow, priority), \ + .cycle_end_irq = DT_IRQ_BY_NAME(GTM(inst), overflow, irq), \ + }; \ + static const struct counter_rz_gtm_config counter_rz_gtm_config_##inst = { \ + .config_info = \ + { \ + .max_top_value = RZ_GTM_TOP_VALUE, \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = 1, \ + }, \ + .fsp_api = &g_timer_on_gtm, \ + .irqn = DT_IRQ_BY_NAME(GTM(inst), overflow, irq), \ + }; \ + static struct counter_rz_gtm_data counter_rz_gtm_data_##inst = { \ + .fsp_cfg = &g_timer##inst##_cfg, .fsp_ctrl = &g_timer##inst##_ctrl}; \ + static int counter_rz_gtm_init_##inst(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_IRQ_BY_NAME(GTM(inst), overflow, irq), \ + DT_IRQ_BY_NAME(GTM(inst), overflow, priority), gtm_int_isr, \ + DEVICE_DT_INST_GET(inst), 0); \ + return counter_rz_gtm_init(dev); \ + } \ + DEVICE_DT_INST_DEFINE(inst, counter_rz_gtm_init_##inst, NULL, &counter_rz_gtm_data_##inst, \ + &counter_rz_gtm_config_##inst, PRE_KERNEL_1, \ + CONFIG_COUNTER_INIT_PRIORITY, &counter_rz_gtm_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(COUNTER_RZG_GTM_INIT) diff --git a/drivers/counter/counter_rpi_pico_timer.c b/drivers/counter/counter_rpi_pico_timer.c index 6a5a90eadec06..ae07dc678a1c0 100644 --- a/drivers/counter/counter_rpi_pico_timer.c +++ b/drivers/counter/counter_rpi_pico_timer.c @@ -68,7 +68,9 @@ static uint32_t counter_rpi_pico_timer_get_top_value(const struct device *dev) static int counter_rpi_pico_timer_get_value(const struct device *dev, uint32_t *ticks) { - *ticks = time_us_32(); + const struct counter_rpi_pico_timer_config *config = dev->config; + + *ticks = timer_time_us_32(config->timer); return 0; } @@ -95,11 +97,11 @@ static int counter_rpi_pico_timer_set_alarm(const struct device *dev, uint8_t id chdata->callback = alarm_cfg->callback; chdata->user_data = alarm_cfg->user_data; - missed = hardware_alarm_set_target(id, alarm_at); + missed = timer_hardware_alarm_set_target(config->timer, id, alarm_at); if (missed) { if (alarm_cfg->flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE) { - hardware_alarm_force_irq(id); + timer_hardware_alarm_force_irq(config->timer, id); } chdata->callback = NULL; chdata->user_data = NULL; @@ -113,10 +115,11 @@ static int counter_rpi_pico_timer_cancel_alarm(const struct device *dev, uint8_t { struct counter_rpi_pico_timer_data *data = dev->data; struct counter_rpi_pico_timer_ch_data *chdata = &data->ch_data[id]; + const struct counter_rpi_pico_timer_config *config = dev->config; chdata->callback = NULL; chdata->user_data = NULL; - hardware_alarm_cancel(id); + timer_hardware_alarm_cancel(config->timer, id); return 0; } @@ -157,6 +160,7 @@ static int counter_rpi_pico_timer_set_guard_period(const struct device *dev, uin static void counter_rpi_pico_irq_handle(uint32_t ch, void *arg) { struct device *dev = arg; + const struct counter_rpi_pico_timer_config *config = dev->config; struct counter_rpi_pico_timer_data *data = dev->data; counter_alarm_callback_t cb = data->ch_data[ch].callback; void *user_data = data->ch_data[ch].user_data; @@ -164,7 +168,7 @@ static void counter_rpi_pico_irq_handle(uint32_t ch, void *arg) if (cb) { data->ch_data[ch].callback = NULL; data->ch_data[ch].user_data = NULL; - cb(dev, ch, time_us_32(), user_data); + cb(dev, ch, timer_time_us_32(config->timer), user_data); } } @@ -203,7 +207,8 @@ static DEVICE_API(counter, counter_rpi_pico_driver_api) = { #define RPI_PICO_TIMER_IRQ_ENABLE(node_id, name, idx) \ do { \ - hardware_alarm_set_callback(idx, counter_rpi_pico_irq_handle); \ + timer_hardware_alarm_set_callback((timer_hw_t *)DT_REG_ADDR(node_id), idx, \ + counter_rpi_pico_irq_handle); \ IRQ_CONNECT((DT_IRQ_BY_IDX(node_id, idx, irq)), \ (DT_IRQ_BY_IDX(node_id, idx, priority)), hardware_alarm_irq_handler, \ (DEVICE_DT_GET(node_id)), 0); \ diff --git a/drivers/counter/counter_sam0_tc32.c b/drivers/counter/counter_sam0_tc32.c index 2965fb5c5da48..4656000003b0c 100644 --- a/drivers/counter/counter_sam0_tc32.c +++ b/drivers/counter/counter_sam0_tc32.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Derek Hageman + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +16,8 @@ #include LOG_MODULE_REGISTER(counter_sam0_tc32, CONFIG_COUNTER_LOG_LEVEL); +/* clang-format off */ + struct counter_sam0_tc32_ch_data { counter_alarm_callback_t callback; void *user_data; @@ -31,16 +34,11 @@ struct counter_sam0_tc32_config { struct counter_config_info info; TcCount32 *regs; const struct pinctrl_dev_config *pcfg; -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; + uint32_t gclk_gen; uint16_t gclk_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif uint16_t prescaler; - void (*irq_config_func)(const struct device *dev); }; @@ -336,20 +334,15 @@ static int counter_sam0_tc32_initialize(const struct device *dev) TcCount32 *tc = cfg->regs; int retval; -#ifdef MCLK - /* Enable the GCLK */ - GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_GEN_GCLK0 | - GCLK_PCHCTRL_CHEN; - - /* Enable TC clock in MCLK */ *cfg->mclk |= cfg->mclk_mask; -#else - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - /* Enable clock in PM */ - PM->APBCMASK.reg |= cfg->pm_apbcmask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif /* @@ -403,60 +396,57 @@ static DEVICE_API(counter, counter_sam0_tc32_driver_api) = { }; -#ifdef MCLK -#define COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch), -#else -#define COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id), -#endif +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME -#define SAM0_TC32_PRESCALER(n) \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(n, prescaler), \ +#define SAM0_TC32_PRESCALER(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, prescaler), \ (DT_INST_PROP(n, prescaler)), (1)) -#define COUNTER_SAM0_TC32_DEVICE(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static void counter_sam0_tc32_config_##n(const struct device *dev); \ - static const struct counter_sam0_tc32_config \ - \ - counter_sam0_tc32_dev_config_##n = { \ - .info = { \ - .max_top_value = UINT32_MAX, \ - .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ - SAM0_TC32_PRESCALER(n), \ - .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ - .channels = 1 \ - }, \ - .regs = (TcCount32 *)DT_INST_REG_ADDR(n), \ - COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \ - .prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \ - SAM0_TC32_PRESCALER(n)), \ - .irq_config_func = &counter_sam0_tc32_config_##n, \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - }; \ - \ - static struct counter_sam0_tc32_data counter_sam0_tc32_dev_data_##n;\ - \ - DEVICE_DT_INST_DEFINE(n, \ - &counter_sam0_tc32_initialize, \ - NULL, \ - &counter_sam0_tc32_dev_data_##n, \ - &counter_sam0_tc32_dev_config_##n, \ - PRE_KERNEL_1, \ - CONFIG_COUNTER_INIT_PRIORITY, \ - &counter_sam0_tc32_driver_api); \ - \ - static void counter_sam0_tc32_config_##n(const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQN(n), \ - DT_INST_IRQ(n, priority), \ - counter_sam0_tc32_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQN(n)); \ +#define COUNTER_SAM0_TC32_DEVICE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static void counter_sam0_tc32_config_##n(const struct device *dev); \ + static const struct counter_sam0_tc32_config \ + \ + counter_sam0_tc32_dev_config_##n = { \ + .info = { \ + .max_top_value = UINT32_MAX, \ + .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ + SAM0_TC32_PRESCALER(n), \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = 1 \ + }, \ + .regs = (TcCount32 *)DT_INST_REG_ADDR(n), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ + .prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \ + SAM0_TC32_PRESCALER(n)), \ + .irq_config_func = &counter_sam0_tc32_config_##n, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + static struct counter_sam0_tc32_data counter_sam0_tc32_dev_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + &counter_sam0_tc32_initialize, \ + NULL, \ + &counter_sam0_tc32_dev_data_##n, \ + &counter_sam0_tc32_dev_config_##n, \ + PRE_KERNEL_1, \ + CONFIG_COUNTER_INIT_PRIORITY, \ + &counter_sam0_tc32_driver_api); \ + \ + static void counter_sam0_tc32_config_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + counter_sam0_tc32_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ } DT_INST_FOREACH_STATUS_OKAY(COUNTER_SAM0_TC32_DEVICE) + +/* clang-format on */ diff --git a/drivers/counter/counter_sam_tc.c b/drivers/counter/counter_sam_tc.c index c91d9081ab404..57ae3c6dd676a 100644 --- a/drivers/counter/counter_sam_tc.c +++ b/drivers/counter/counter_sam_tc.c @@ -74,14 +74,14 @@ struct counter_sam_dev_data { }; static const uint32_t sam_tc_input_freq_table[] = { -#if defined(CONFIG_SOC_SERIES_SAME70) || defined(CONFIG_SOC_SERIES_SAMV71) +#if defined(CONFIG_SOC_SERIES_SAMX7X) USEC_PER_SEC, SOC_ATMEL_SAM_MCK_FREQ_HZ / 8, SOC_ATMEL_SAM_MCK_FREQ_HZ / 32, SOC_ATMEL_SAM_MCK_FREQ_HZ / 128, 32768, #elif defined(CONFIG_SOC_SERIES_SAM4L) - USEC_PER_SEC, + 1024, SOC_ATMEL_SAM_MCK_FREQ_HZ / 2, SOC_ATMEL_SAM_MCK_FREQ_HZ / 8, SOC_ATMEL_SAM_MCK_FREQ_HZ / 32, @@ -319,7 +319,7 @@ static int counter_sam_initialize(const struct device *dev) /* Connect pins to the peripheral */ retval = pinctrl_apply_state(dev_cfg->pcfg, PINCTRL_STATE_DEFAULT); - if (retval < 0) { + if (retval < 0 && retval != -ENOENT) { return retval; } diff --git a/drivers/counter/counter_timer_shell.c b/drivers/counter/counter_timer_shell.c index 80aef168a91a4..d1e81e8a9fba0 100644 --- a/drivers/counter/counter_timer_shell.c +++ b/drivers/counter/counter_timer_shell.c @@ -42,7 +42,7 @@ static inline int parse_device(const struct shell *shctx, size_t argc, char *arg { ARG_UNUSED(argc); - *timer_dev = device_get_binding(argv[ARGV_DEV]); + *timer_dev = shell_device_get_binding(argv[ARGV_DEV]); if (*timer_dev == NULL) { shell_error(shctx, "Timer: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -197,10 +197,15 @@ static int cmd_timer_periodic(const struct shell *shctx, size_t argc, char **arg return 0; } +static bool device_is_counter(const struct device *dev) +{ + return DEVICE_API_IS(counter, dev); +} + /* Device name autocompletion support */ static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, "timer"); + const struct device *dev = shell_device_filter(idx, device_is_counter); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/counter/rtc_mcp7940n.c b/drivers/counter/rtc_mcp7940n.c index 783fd775f0b55..38ffd93463d9a 100644 --- a/drivers/counter/rtc_mcp7940n.c +++ b/drivers/counter/rtc_mcp7940n.c @@ -712,7 +712,7 @@ static int mcp7940n_init(const struct device *dev) gpio_init_callback(&data->int_callback, mcp7940n_init_cb, BIT(cfg->int_gpios.pin)); - gpio_add_callback(cfg->int_gpios.port, &data->int_callback); + (void)gpio_add_callback(cfg->int_gpios.port, &data->int_callback); /* Configure interrupt polarity */ if ((cfg->int_gpios.dt_flags & GPIO_ACTIVE_LOW) == GPIO_ACTIVE_LOW) { diff --git a/drivers/crypto/crypto_ataes132a.c b/drivers/crypto/crypto_ataes132a.c index 4696272fc5619..f7bbbc467d61a 100644 --- a/drivers/crypto/crypto_ataes132a.c +++ b/drivers/crypto/crypto_ataes132a.c @@ -353,7 +353,7 @@ int ataes132a_aes_ccm_decrypt(const struct device *dev, return -EINVAL; } - if (out_len < 2 || out_len > 33) { + if (!IN_RANGE(out_len, 2, 33)) { LOG_ERR("decrypt command response has invalid" " size %d", out_len); k_sem_give(&data->device_sem); @@ -394,7 +394,14 @@ int ataes132a_aes_ccm_encrypt(const struct device *dev, uint8_t buf_len; uint8_t out_len; uint8_t return_code; - uint8_t param_buffer[40]; + + const uint8_t key_id_len = 1; + const uint8_t buf_len_len = 1; + const uint8_t max_input_len = 32; + const uint8_t nonce_len = 12; + const uint8_t tag_len = 16; + + uint8_t param_buffer[key_id_len + buf_len_len + max_input_len + nonce_len + tag_len]; if (!aead_op) { LOG_ERR("Parameter cannot be null"); @@ -525,7 +532,7 @@ int ataes132a_aes_ccm_encrypt(const struct device *dev, return -EINVAL; } - if (out_len < 33 || out_len > 49) { + if (!IN_RANGE(out_len, 33, 49)) { LOG_ERR("encrypt command response has invalid" " size %d", out_len); k_sem_give(&data->device_sem); @@ -542,6 +549,7 @@ int ataes132a_aes_ccm_encrypt(const struct device *dev, if (aead_op->tag) { memcpy(aead_op->tag, param_buffer + 1, 16); } + memcpy(aead_op->pkt->out_buf, param_buffer + 17, out_len - 17U); if (mac_mode) { @@ -875,7 +883,7 @@ static const struct ataes132a_device_config ataes132a_config = { .i2c = I2C_DT_SPEC_INST_GET(0), }; -static struct crypto_driver_api crypto_enc_funcs = { +static DEVICE_API(crypto, crypto_enc_funcs) = { .cipher_begin_session = ataes132a_session_setup, .cipher_free_session = ataes132a_session_free, .cipher_async_callback_set = NULL, diff --git a/drivers/crypto/crypto_intel_sha.c b/drivers/crypto/crypto_intel_sha.c index c0722fa18ce17..54934f5949a4c 100644 --- a/drivers/crypto/crypto_intel_sha.c +++ b/drivers/crypto/crypto_intel_sha.c @@ -325,7 +325,7 @@ static int intel_sha_device_hw_caps(const struct device *dev) return (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS); } -static struct crypto_driver_api hash_enc_funcs = { +static DEVICE_API(crypto, hash_enc_funcs) = { .hash_begin_session = intel_sha_device_set_hash_type, .hash_free_session = intel_sha_device_free, .hash_async_callback_set = NULL, diff --git a/drivers/crypto/crypto_it8xxx2_sha.c b/drivers/crypto/crypto_it8xxx2_sha.c index 3fea42f217d28..5ce174ab237ee 100644 --- a/drivers/crypto/crypto_it8xxx2_sha.c +++ b/drivers/crypto/crypto_it8xxx2_sha.c @@ -215,7 +215,7 @@ static int it8xxx2_sha_init(const struct device *dev) return 0; } -static const struct crypto_driver_api it8xxx2_crypto_api = { +static DEVICE_API(crypto, it8xxx2_crypto_api) = { .hash_begin_session = it8xxx2_hash_begin_session, .hash_free_session = it8xxx2_hash_session_free, .query_hw_caps = it8xxx2_query_hw_caps, diff --git a/drivers/crypto/crypto_it8xxx2_sha_v2.c b/drivers/crypto/crypto_it8xxx2_sha_v2.c index 6da1cff4c2942..3098bf4b9b5e0 100644 --- a/drivers/crypto/crypto_it8xxx2_sha_v2.c +++ b/drivers/crypto/crypto_it8xxx2_sha_v2.c @@ -340,7 +340,7 @@ static int it8xxx2_sha_init(const struct device *dev) return 0; } -static const struct crypto_driver_api it8xxx2_crypto_api = { +static DEVICE_API(crypto, it8xxx2_crypto_api) = { .hash_begin_session = it8xxx2_hash_begin_session, .hash_free_session = it8xxx2_hash_session_free, .query_hw_caps = it8xxx2_query_hw_caps, diff --git a/drivers/crypto/crypto_mchp_xec_symcr.c b/drivers/crypto/crypto_mchp_xec_symcr.c index 6bcf4f17c854a..0845009802457 100644 --- a/drivers/crypto/crypto_mchp_xec_symcr.c +++ b/drivers/crypto/crypto_mchp_xec_symcr.c @@ -514,7 +514,7 @@ static int xec_symcr_init(const struct device *dev) return ret; } -static const struct crypto_driver_api xec_symcr_api = { +static DEVICE_API(crypto, xec_symcr_api) = { .query_hw_caps = xec_symcr_query_hw_caps, .hash_begin_session = xec_symcr_hash_session_begin, .hash_free_session = xec_symcr_hash_session_free, diff --git a/drivers/crypto/crypto_mcux_dcp.c b/drivers/crypto/crypto_mcux_dcp.c index 23232ed9b57cd..a415e108821a2 100644 --- a/drivers/crypto/crypto_mcux_dcp.c +++ b/drivers/crypto/crypto_mcux_dcp.c @@ -331,7 +331,7 @@ static int crypto_dcp_init(const struct device *dev) return 0; } -static const struct crypto_driver_api crypto_dcp_api = { +static DEVICE_API(crypto, crypto_dcp_api) = { .query_hw_caps = crypto_dcp_query_hw_caps, .cipher_begin_session = crypto_dcp_cipher_begin_session, .cipher_free_session = crypto_dcp_cipher_free_session, diff --git a/drivers/crypto/crypto_mtls_shim.c b/drivers/crypto/crypto_mtls_shim.c index 071b3593f338d..2031e7d7c987b 100644 --- a/drivers/crypto/crypto_mtls_shim.c +++ b/drivers/crypto/crypto_mtls_shim.c @@ -599,7 +599,7 @@ static int mtls_query_caps(const struct device *dev) return MTLS_SUPPORT; } -static struct crypto_driver_api mtls_crypto_funcs = { +static DEVICE_API(crypto, mtls_crypto_funcs) = { .cipher_begin_session = mtls_session_setup, .cipher_free_session = mtls_session_free, .cipher_async_callback_set = NULL, diff --git a/drivers/crypto/crypto_npcx_sha.c b/drivers/crypto/crypto_npcx_sha.c index 20c817f1cf903..65da0cb5dcf0f 100644 --- a/drivers/crypto/crypto_npcx_sha.c +++ b/drivers/crypto/crypto_npcx_sha.c @@ -202,7 +202,7 @@ static int npcx_hash_init(const struct device *dev) return 0; } -static const struct crypto_driver_api npcx_crypto_api = { +static DEVICE_API(crypto, npcx_crypto_api) = { .hash_begin_session = npcx_hash_session_setup, .hash_free_session = npcx_hash_session_free, .query_hw_caps = npcx_query_caps, diff --git a/drivers/crypto/crypto_nrf_ecb.c b/drivers/crypto/crypto_nrf_ecb.c index 9fa354738ae55..1ab06eacd34aa 100644 --- a/drivers/crypto/crypto_nrf_ecb.c +++ b/drivers/crypto/crypto_nrf_ecb.c @@ -132,7 +132,7 @@ static int nrf_ecb_session_free(const struct device *dev, return 0; } -static const struct crypto_driver_api crypto_enc_funcs = { +static DEVICE_API(crypto, crypto_enc_funcs) = { .cipher_begin_session = nrf_ecb_session_setup, .cipher_free_session = nrf_ecb_session_free, .cipher_async_callback_set = NULL, diff --git a/drivers/crypto/crypto_si32.c b/drivers/crypto/crypto_si32.c index e933852e7a5fa..2a4dbd11605ea 100644 --- a/drivers/crypto/crypto_si32.c +++ b/drivers/crypto/crypto_si32.c @@ -1194,7 +1194,7 @@ static int crypto_si32_free_session(const struct device *dev, struct cipher_ctx } /* AES only, no support for hashing */ -static const struct crypto_driver_api crypto_si32_api = { +static DEVICE_API(crypto, crypto_si32_api) = { .query_hw_caps = crypto_si32_query_hw_caps, .cipher_begin_session = crypto_si32_begin_session, .cipher_free_session = crypto_si32_free_session, diff --git a/drivers/crypto/crypto_smartbond.c b/drivers/crypto/crypto_smartbond.c index 9899f46dd33f5..1cff9f046c4bc 100644 --- a/drivers/crypto/crypto_smartbond.c +++ b/drivers/crypto/crypto_smartbond.c @@ -921,7 +921,7 @@ crypto_smartbond_hash_set_async_callback(const struct device *dev, hash_completi } #endif -static const struct crypto_driver_api crypto_smartbond_driver_api = { +static DEVICE_API(crypto, crypto_smartbond_driver_api) = { .cipher_begin_session = crypto_smartbond_cipher_begin_session, .cipher_free_session = crypto_smartbond_cipher_free_session, #if defined(CONFIG_CRYPTO_ASYNC) diff --git a/drivers/crypto/crypto_stm32.c b/drivers/crypto/crypto_stm32.c index bd7e05a2ddcdd..c453e3a0e6556 100644 --- a/drivers/crypto/crypto_stm32.c +++ b/drivers/crypto/crypto_stm32.c @@ -541,7 +541,7 @@ static int crypto_stm32_init(const struct device *dev) return 0; } -static struct crypto_driver_api crypto_enc_funcs = { +static DEVICE_API(crypto, crypto_enc_funcs) = { .cipher_begin_session = crypto_stm32_session_setup, .cipher_free_session = crypto_stm32_session_free, .cipher_async_callback_set = NULL, diff --git a/drivers/crypto/crypto_tc_shim.c b/drivers/crypto/crypto_tc_shim.c index 71616250be05e..7733a96f0708d 100644 --- a/drivers/crypto/crypto_tc_shim.c +++ b/drivers/crypto/crypto_tc_shim.c @@ -314,7 +314,7 @@ static int tc_shim_init(const struct device *dev) return 0; } -static struct crypto_driver_api crypto_enc_funcs = { +static DEVICE_API(crypto, crypto_enc_funcs) = { .cipher_begin_session = tc_session_setup, .cipher_free_session = tc_session_free, .cipher_async_callback_set = NULL, diff --git a/drivers/dac/CMakeLists.txt b/drivers/dac/CMakeLists.txt index eec91be800a21..2b2584daf4195 100644 --- a/drivers/dac/CMakeLists.txt +++ b/drivers/dac/CMakeLists.txt @@ -25,3 +25,5 @@ zephyr_library_sources_ifdef(CONFIG_DAC_AD569X dac_ad569x.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE dac_handlers.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_GAU dac_mcux_gau.c) zephyr_library_sources_ifdef(CONFIG_DAC_TEST dac_test.c) +zephyr_library_sources_ifdef(CONFIG_DAC_MAX22017 dac_max22017.c) +zephyr_library_sources_ifdef(CONFIG_DAC_RENESAS_RA dac_renesas_ra.c) diff --git a/drivers/dac/Kconfig b/drivers/dac/Kconfig index 26b17f1a31d57..36592ab983799 100644 --- a/drivers/dac/Kconfig +++ b/drivers/dac/Kconfig @@ -61,4 +61,8 @@ source "drivers/dac/Kconfig.ad569x" source "drivers/dac/Kconfig.test" +source "drivers/dac/Kconfig.max22017" + +source "drivers/dac/Kconfig.renesas_ra" + endif # DAC diff --git a/drivers/dac/Kconfig.max22017 b/drivers/dac/Kconfig.max22017 new file mode 100644 index 0000000000000..d7a46229f02bb --- /dev/null +++ b/drivers/dac/Kconfig.max22017 @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +config DAC_MAX22017 + bool "Analog Devices MAX22017 DAC" + default y + depends on DT_HAS_ADI_MAX22017_DAC_ENABLED + select MFD + help + Enable the driver for the Analog Devices MAX22017 DAC + +if DAC_MAX22017 + +config DAC_MAX22017_INIT_PRIORITY + int "Init priority" + default 80 + help + Analog Devices MAX22017 DAC device driver initialization priority. + +endif # DAC_MAX22017 diff --git a/drivers/dac/Kconfig.renesas_ra b/drivers/dac/Kconfig.renesas_ra new file mode 100644 index 0000000000000..40e9ce6812191 --- /dev/null +++ b/drivers/dac/Kconfig.renesas_ra @@ -0,0 +1,43 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config DAC_RENESAS_RA + bool "Renesas RA DAC" + default y + depends on DT_HAS_RENESAS_RA_DAC_ENABLED + select USE_RA_FSP_DAC + select PINCTRL + help + Enable Renesas RA DAC Driver. + +if DAC_RENESAS_RA +config DAC_RENESAS_RA_DA_AD_SYNCHRONIZE + bool "D/A A/D Synchronous Conversion" + help + - n: Do not synchronize DAC12 with ADC (unit 1) operation + (disable interference reduction between D/A and A/D conversion). + - y: Synchronize DAC12 with ADC (unit 1) operation + (enable interference reduction between D/A and A/D conversion). + +choice DAC_RENESAS_RA_DAVREFCR + prompt "D/A Reference Voltage" + depends on $(dt_nodelabel_bool_prop,dac_global,has-davrefcr) + default DAC_RENESAS_RA_DAVREFCR_AVCC0_AVSS0 + +config DAC_RENESAS_RA_DAVREFCR_NONE + bool "No reference voltage selected" + help + No reference voltage selected + +config DAC_RENESAS_RA_DAVREFCR_AVCC0_AVSS0 + bool "Using AVCC0/AVSS0 for reference voltage source" + help + AVCC0/AVSS0 selected + +config DAC_RENESAS_RA_DAVREFCR_VREFH_VREFL + bool "Using VREFH/VREFL for reference voltage source" + help + VREFH/VREFL selected + +endchoice #DAC_RENESAS_RA_DAVREFCR +endif # DAC_RENESAS_RA diff --git a/drivers/dac/dac_dacx3608.c b/drivers/dac/dac_dacx3608.c index e2218c6bcdfab..9e783622253e4 100644 --- a/drivers/dac/dac_dacx3608.c +++ b/drivers/dac/dac_dacx3608.c @@ -146,7 +146,8 @@ static int dacx3608_write_value(const struct device *dev, uint8_t channel, * Check if channel is initialized * If broadcast channel is used, check if any channel is initialized */ - if ((brdcast && !data->configured) || (!(data->configured & BIT(channel)))) { + if ((brdcast && !data->configured) || + (channel < DACX3608_MAX_CHANNEL && !(data->configured & BIT(channel)))) { LOG_ERR("Channel %d not initialized", channel); return -EINVAL; } diff --git a/drivers/dac/dac_max22017.c b/drivers/dac/dac_max22017.c new file mode 100644 index 0000000000000..a7c5f07dd3274 --- /dev/null +++ b/drivers/dac/dac_max22017.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include + +#define DT_DRV_COMPAT adi_max22017_dac +LOG_MODULE_REGISTER(dac_max22017, CONFIG_DAC_LOG_LEVEL); + +struct dac_adi_max22017_config { + const struct device *parent; + uint8_t resolution; + uint8_t nchannels; + const struct gpio_dt_spec gpio_ldac; + const struct gpio_dt_spec gpio_busy; + uint8_t latch_mode[MAX22017_MAX_CHANNEL]; + uint8_t polarity_mode[MAX22017_MAX_CHANNEL]; + uint8_t dac_mode[MAX22017_MAX_CHANNEL]; + uint8_t ovc_mode[MAX22017_MAX_CHANNEL]; + uint16_t timeout; +}; + +static int max22017_channel_setup(const struct device *dev, + const struct dac_channel_cfg *channel_cfg) +{ + int ret; + uint16_t ao_cnfg, gen_cnfg; + uint8_t chan = channel_cfg->channel_id; + const struct dac_adi_max22017_config *config = dev->config; + const struct device *parent = config->parent; + struct max22017_data *data = parent->data; + + if (chan > config->nchannels - 1) { + LOG_ERR("Unsupported channel %d", chan); + return -ENOTSUP; + } + + if (channel_cfg->resolution != config->resolution) { + LOG_ERR("Unsupported resolution %d", chan); + return -ENOTSUP; + } + + k_mutex_lock(&data->lock, K_FOREVER); + ret = max22017_reg_read(parent, MAX22017_AO_CNFG_OFF, &ao_cnfg); + if (ret) { + goto fail; + } + + ao_cnfg |= FIELD_PREP(MAX22017_AO_CNFG_AO_EN, BIT(chan)); + + if (!config->latch_mode[chan]) { + ao_cnfg |= FIELD_PREP(MAX22017_AO_CNFG_AO_LD_CNFG, BIT(chan)); + } + + if (config->polarity_mode[chan]) { + ao_cnfg |= FIELD_PREP(MAX22017_AO_CNFG_AO_UNI, BIT(chan)); + } + + if (config->dac_mode[chan]) { + ao_cnfg |= FIELD_PREP(MAX22017_AO_CNFG_AO_MODE, BIT(chan)); + } + + ret = max22017_reg_write(parent, MAX22017_AO_CNFG_OFF, ao_cnfg); + if (ret) { + goto fail; + } + + ret = max22017_reg_read(parent, MAX22017_GEN_CNFG_OFF, &gen_cnfg); + if (ret) { + goto fail; + } + + if (config->ovc_mode[chan]) { + gen_cnfg |= FIELD_PREP(MAX22017_GEN_CNFG_OVC_CNFG, BIT(chan)); + /* Over current shutdown mode */ + if (config->ovc_mode[chan] == 2) { + gen_cnfg |= FIELD_PREP(MAX22017_GEN_CNFG_OVC_SHDN_CNFG, BIT(chan)); + } + } + + ret = max22017_reg_write(parent, MAX22017_GEN_CNFG_OFF, gen_cnfg); +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static int max22017_write_value(const struct device *dev, uint8_t channel, uint32_t value) +{ + int ret; + uint16_t ao_sta; + const struct dac_adi_max22017_config *config = dev->config; + const struct device *parent = config->parent; + struct max22017_data *data = parent->data; + + if (channel > config->nchannels - 1) { + LOG_ERR("unsupported channel %d", channel); + return ENOTSUP; + } + + if (value >= (1 << config->resolution)) { + LOG_ERR("Value %d out of range", value); + return -EINVAL; + } + + k_mutex_lock(&data->lock, K_FOREVER); + if (config->gpio_busy.port) { + if (gpio_pin_get_dt(&config->gpio_busy)) { + ret = -EBUSY; + goto fail; + } + } else { + ret = max22017_reg_read(parent, MAX22017_AO_STA_OFF, &ao_sta); + if (ret) { + goto fail; + } + if (FIELD_GET(MAX22017_AO_STA_BUSY_STA, ao_sta)) { + ret = -EBUSY; + goto fail; + } + } + + ret = max22017_reg_write(parent, MAX22017_AO_DATA_CHn_OFF(channel), + FIELD_PREP(MAX22017_AO_DATA_CHn_AO_DATA_CH, value)); + if (ret) { + goto fail; + } + + if (config->latch_mode[channel]) { + if (config->gpio_ldac.port) { + gpio_pin_set_dt(&config->gpio_ldac, false); + k_sleep(K_USEC(MAX22017_LDAC_TOGGLE_TIME)); + gpio_pin_set_dt(&config->gpio_ldac, true); + } else { + ret = max22017_reg_write( + parent, MAX22017_AO_CMD_OFF, + FIELD_PREP(MAX22017_AO_CMD_AO_LD_CTRL, BIT(channel))); + } + } +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static int max22017_init(const struct device *dev) +{ + int ret; + uint16_t gen_cnfg = 0, gen_int_en = 0; + const struct dac_adi_max22017_config *config = dev->config; + const struct device *parent = config->parent; + struct max22017_data *data = config->parent->data; + + if (!device_is_ready(config->parent)) { + LOG_ERR("parent adi_max22017 MFD device '%s' not ready", config->parent->name); + return -EINVAL; + } + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(parent, MAX22017_GEN_CNFG_OFF, &gen_cnfg); + if (ret) { + goto fail; + } + + ret = max22017_reg_read(parent, MAX22017_GEN_INTEN_OFF, &gen_int_en); + if (ret) { + goto fail; + } + + if (config->timeout) { + gen_cnfg |= FIELD_PREP(MAX22017_GEN_CNFG_TMOUT_EN, 1) | + FIELD_PREP(MAX22017_GEN_CNFG_TMOUT_SEL, (config->timeout / 100) - 1); + gen_int_en |= FIELD_PREP(MAX22017_GEN_INTEN_TMOUT_INTEN, 1); + } + + ret = max22017_reg_write(parent, MAX22017_GEN_CNFG_OFF, gen_cnfg); + if (ret) { + goto fail; + } + + ret = max22017_reg_write(parent, MAX22017_GEN_INTEN_OFF, gen_int_en); + if (ret) { + goto fail; + } + + if (config->gpio_ldac.port) { + ret = gpio_pin_configure_dt(&config->gpio_ldac, GPIO_OUTPUT_ACTIVE); + if (ret) { + LOG_ERR("failed to initialize GPIO ldac pin"); + goto fail; + } + } + + if (config->gpio_busy.port) { + ret = gpio_pin_configure_dt(&config->gpio_busy, GPIO_INPUT); + if (ret) { + LOG_ERR("failed to initialize GPIO busy pin"); + goto fail; + } + } + +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static DEVICE_API(dac, max22017_driver_api) = { + .channel_setup = max22017_channel_setup, + .write_value = max22017_write_value, +}; + +#define DAC_MAX22017_DEVICE(id) \ + static const struct dac_adi_max22017_config dac_adi_max22017_config_##id = { \ + .parent = DEVICE_DT_GET(DT_INST_PARENT(id)), \ + .resolution = DT_INST_PROP_OR(id, resolution, 16), \ + .nchannels = DT_INST_PROP_OR(id, num_channels, 2), \ + .gpio_busy = GPIO_DT_SPEC_INST_GET_OR(id, busy_gpios, {0}), \ + .gpio_ldac = GPIO_DT_SPEC_INST_GET_OR(id, ldac_gpios, {0}), \ + .latch_mode = DT_INST_PROP_OR(id, latch_mode, {0}), \ + .polarity_mode = DT_INST_PROP_OR(id, polarity_mode, {0}), \ + .dac_mode = DT_INST_PROP_OR(id, dac_mode, {0}), \ + .ovc_mode = DT_INST_PROP_OR(id, overcurrent_mode, {0}), \ + .timeout = DT_INST_PROP_OR(id, timeout, 0), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(id, max22017_init, NULL, NULL, &dac_adi_max22017_config_##id, \ + POST_KERNEL, CONFIG_DAC_MAX22017_INIT_PRIORITY, \ + &max22017_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DAC_MAX22017_DEVICE); diff --git a/drivers/dac/dac_renesas_ra.c b/drivers/dac/dac_renesas_ra.c new file mode 100644 index 0000000000000..766facb14fb31 --- /dev/null +++ b/drivers/dac/dac_renesas_ra.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_dac + +#include +#include +#include +#include "r_dac_api.h" +#include "r_dac.h" + +LOG_MODULE_REGISTER(dac_renesas_ra, CONFIG_DAC_LOG_LEVEL); + +struct dac_renesas_ra_config { + const struct pinctrl_dev_config *pcfg; +}; + +struct dac_renesas_ra_data { + const struct device *dev; + dac_instance_ctrl_t dac; + struct st_dac_cfg f_config; +}; + +static int dac_renesas_ra_write_value(const struct device *dev, uint8_t channel, uint32_t value) +{ + struct dac_renesas_ra_data *data = dev->data; + fsp_err_t fsp_err; + + if (channel != 0) { + LOG_ERR("wrong channel id '%hhu'", channel); + return -ENOTSUP; + } + + fsp_err = R_DAC_Write(&data->dac, value); + if (FSP_SUCCESS != fsp_err) { + return -EIO; + } + + return 0; +} + +static int dac_renesas_ra_channel_setup(const struct device *dev, + const struct dac_channel_cfg *channel_cfg) +{ + struct dac_renesas_ra_data *data = dev->data; + dac_extended_cfg_t *config_extend = (dac_extended_cfg_t *)data->f_config.p_extend; + fsp_err_t fsp_err; + + if (channel_cfg->channel_id != 0) { + LOG_ERR("wrong channel id '%hhu'", channel_cfg->channel_id); + return -ENOTSUP; + } + + if (channel_cfg->resolution != 12) { + LOG_ERR("Resolution not supported"); + return -ENOTSUP; + } + + if (data->dac.channel_opened != 0) { + fsp_err = R_DAC_Close(&data->dac); + if (FSP_SUCCESS != fsp_err) { + return -EIO; + } + } + +#if DT_PROP(DT_PARENT(DT_DRV_INST(0)), has_output_amplifier) + config_extend->output_amplifier_enabled = channel_cfg->buffered; +#elif DT_PROP(DT_PARENT(DT_DRV_INST(0)), has_chargepump) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(moco)) + config_extend->enable_charge_pump = channel_cfg->buffered; +#else + if (channel_cfg->buffered) { + LOG_ERR("Requires MOCO clock enabled to support the buffer feature"); + return -ENOTSUP; + } +#endif +#else + if (channel_cfg->buffered) { + LOG_ERR("The MCU doesn't support the buffer feature"); + return -ENOTSUP; + } +#endif + +#if DT_PROP(DT_PARENT(DT_DRV_INST(0)), has_internal_output) + config_extend->internal_output_enabled = channel_cfg->internal; +#else + if (channel_cfg->internal) { + LOG_ERR("The MCU doesn't support the internal output feature"); + return -ENOTSUP; + } +#endif + + fsp_err = R_DAC_Open(&data->dac, &data->f_config); + if (FSP_SUCCESS != fsp_err) { + return -EIO; + } + + fsp_err = R_DAC_Start(&data->dac); + if (FSP_SUCCESS != fsp_err) { + return -EIO; + } + + return 0; +} + +static int dac_renesas_ra_init(const struct device *dev) +{ + const struct dac_renesas_ra_config *config = dev->config; + int ret; + + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + return 0; +} + +static DEVICE_API(dac, dac_renesas_ra_api) = { + .channel_setup = dac_renesas_ra_channel_setup, + .write_value = dac_renesas_ra_write_value, +}; + +#ifdef CONFIG_DAC_RENESAS_RA_DAVREFCR_AVCC0_AVSS0 +#define DAC_RENESAS_RA_DAVREFCR DAC_VREF_AVCC0_AVSS0 +#elif defined(CONFIG_DAC_RENESAS_RA_DAVREFCR_VREFH_VREFL) +#define DAC_RENESAS_RA_DAVREFCR DAC_VREF_VREFH_VREFL +#elif defined(CONFIG_DAC_RENESAS_RA_DAVREFCR_NONE) +#define DAC_RENESAS_RA_DAVREFCR DAC_VREF_NONE +#else +#define DAC_RENESAS_RA_DAVREFCR 0 +#endif + +#define DAC_RENESAS_RA_INIT(idx) \ + PINCTRL_DT_INST_DEFINE(idx); \ + static dac_extended_cfg_t g_dac_cfg_extend_##idx = { \ + .data_format = DAC_DATA_FORMAT_FLUSH_RIGHT, \ + .enable_charge_pump = true, \ + .output_amplifier_enabled = true, \ + .internal_output_enabled = false, \ + .ref_volt_sel = DAC_RENESAS_RA_DAVREFCR, \ + }; \ + static const struct dac_renesas_ra_config dac_renesas_ra_config_##idx = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + }; \ + static struct dac_renesas_ra_data dac_renesas_ra_data_##idx = { \ + .dev = DEVICE_DT_INST_GET(idx), \ + .f_config = \ + { \ + .channel = DT_INST_REG_ADDR(idx), \ + .ad_da_synchronized = \ + IS_ENABLED(CONFIG_DAC_RENESAS_RA_DA_AD_SYNCHRONIZE), \ + .p_extend = &g_dac_cfg_extend_##idx, \ + }, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, dac_renesas_ra_init, NULL, &dac_renesas_ra_data_##idx, \ + &dac_renesas_ra_config_##idx, POST_KERNEL, CONFIG_DAC_INIT_PRIORITY, \ + &dac_renesas_ra_api) + +DT_INST_FOREACH_STATUS_OKAY(DAC_RENESAS_RA_INIT); diff --git a/drivers/dac/dac_sam.c b/drivers/dac/dac_sam.c index 40cd7cadade12..c39d137dc5118 100644 --- a/drivers/dac/dac_sam.c +++ b/drivers/dac/dac_sam.c @@ -5,10 +5,6 @@ /** @file * @brief DAC driver for Atmel SAM MCU family. - * - * Remarks: - * Only SAME70, SAMV71 series devices are currently supported. Please submit a - * patch. */ #define DT_DRV_COMPAT atmel_sam_dac @@ -25,10 +21,6 @@ #include LOG_MODULE_REGISTER(dac_sam, CONFIG_DAC_LOG_LEVEL); -BUILD_ASSERT(IS_ENABLED(CONFIG_SOC_SERIES_SAME70) || - IS_ENABLED(CONFIG_SOC_SERIES_SAMV71), - "Only SAME70, SAMV71 series devices are currently supported."); - #define DAC_CHANNEL_NO 2 /* Device constant configuration parameters */ @@ -47,7 +39,11 @@ struct dac_channel { /* Device run time data */ struct dac_sam_dev_data { +#if defined(CONFIG_SOC_SERIES_SAMX7X) struct dac_channel dac_channels[DAC_CHANNEL_NO]; +#else + struct dac_channel dac_channel; +#endif }; static void dac_sam_isr(const struct device *dev) @@ -60,6 +56,7 @@ static void dac_sam_isr(const struct device *dev) /* Retrieve interrupt status */ int_stat = dac->DACC_ISR & dac->DACC_IMR; +#if defined(CONFIG_SOC_SERIES_SAMX7X) if ((int_stat & DACC_ISR_TXRDY0) != 0) { /* Disable Transmit Ready Interrupt */ dac->DACC_IDR = DACC_IDR_TXRDY0; @@ -70,6 +67,13 @@ static void dac_sam_isr(const struct device *dev) dac->DACC_IDR = DACC_IDR_TXRDY1; k_sem_give(&dev_data->dac_channels[1].sem); } +#else + if ((int_stat & DACC_ISR_TXRDY) != 0) { + /* Disable Transmit Ready Interrupt */ + dac->DACC_IDR = DACC_IDR_TXRDY; + k_sem_give(&dev_data->dac_channel.sem); + } +#endif } static int dac_sam_channel_setup(const struct device *dev, @@ -106,7 +110,11 @@ static int dac_sam_write_value(const struct device *dev, uint8_t channel, return -EINVAL; } +#if defined(CONFIG_SOC_SERIES_SAMX7X) if (dac->DACC_IMR & (DACC_IMR_TXRDY0 << channel)) { +#else + if (dac->DACC_IMR & DACC_IMR_TXRDY) { +#endif /* Attempting to send data on channel that's already in use */ return -EINVAL; } @@ -116,6 +124,7 @@ static int dac_sam_write_value(const struct device *dev, uint8_t channel, return -EINVAL; } +#if defined(CONFIG_SOC_SERIES_SAMX7X) k_sem_take(&dev_data->dac_channels[channel].sem, K_FOREVER); /* Trigger conversion */ @@ -123,6 +132,18 @@ static int dac_sam_write_value(const struct device *dev, uint8_t channel, /* Enable Transmit Ready Interrupt */ dac->DACC_IER = DACC_IER_TXRDY0 << channel; +#else + k_sem_take(&dev_data->dac_channel.sem, K_FOREVER); + + /* Select the channel */ + dac->DACC_MR = DACC_MR_USER_SEL(channel) | DACC_MR_ONE; + + /* Trigger conversion */ + dac->DACC_CDR = DACC_CDR_DATA(value); + + /* Enable Transmit Ready Interrupt */ + dac->DACC_IER = DACC_IER_TXRDY; +#endif return 0; } @@ -131,16 +152,22 @@ static int dac_sam_init(const struct device *dev) { const struct dac_sam_dev_cfg *const dev_cfg = dev->config; struct dac_sam_dev_data *const dev_data = dev->data; - Dacc *const dac = dev_cfg->regs; int retval; +#if defined(CONFIG_SOC_SERIES_SAMX7X) + Dacc *const dac = dev_cfg->regs; +#endif /* Configure interrupts */ dev_cfg->irq_config(); /* Initialize semaphores */ +#if defined(CONFIG_SOC_SERIES_SAMX7X) for (int i = 0; i < ARRAY_SIZE(dev_data->dac_channels); i++) { k_sem_init(&dev_data->dac_channels[i].sem, 1, 1); } +#else + k_sem_init(&dev_data->dac_channel.sem, 1, 1); +#endif /* Enable DAC clock in PMC */ (void)clock_control_on(SAM_DT_PMC_CONTROLLER, @@ -151,8 +178,10 @@ static int dac_sam_init(const struct device *dev) return retval; } +#if defined(CONFIG_SOC_SERIES_SAMX7X) /* Set Mode Register */ dac->DACC_MR = DACC_MR_PRESCALER(dev_cfg->prescaler); +#endif /* Enable module's IRQ */ irq_enable(dev_cfg->irq_id); diff --git a/drivers/dac/dac_sam0.c b/drivers/dac/dac_sam0.c index 02013ac9dcb72..dc307cfe98e9b 100644 --- a/drivers/dac/dac_sam0.c +++ b/drivers/dac/dac_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +15,8 @@ #include LOG_MODULE_REGISTER(dac_sam0, CONFIG_DAC_LOG_LEVEL); +/* clang-format off */ + /* * Maps between the DTS reference property names and register values. Note that * the ASF uses the 09/2015 names which differ from the 03/2020 datasheet. @@ -27,8 +30,10 @@ LOG_MODULE_REGISTER(dac_sam0, CONFIG_DAC_LOG_LEVEL); struct dac_sam0_cfg { Dac *regs; const struct pinctrl_dev_config *pcfg; - uint8_t pm_apbc_bit; - uint8_t gclk_clkctrl_id; + volatile uint32_t *mclk; + uint32_t mclk_mask; + uint32_t gclk_gen; + uint16_t gclk_id; uint8_t refsel; }; @@ -77,18 +82,22 @@ static int dac_sam0_init(const struct device *dev) Dac *regs = cfg->regs; int retval; - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; + *cfg->mclk |= cfg->mclk_mask; + +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); +#endif retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); if (retval < 0) { return retval; } - /* Enable the clock in PM */ - PM->APBCMASK.reg |= 1 << cfg->pm_apbc_bit; - /* Reset then configure the DAC */ regs->CTRLA.bit.SWRST = 1; while (regs->STATUS.bit.SYNCBUSY) { @@ -110,24 +119,30 @@ static DEVICE_API(dac, api_sam0_driver_api) = { .write_value = dac_sam0_write_value }; -#define SAM0_DAC_REFSEL(n) \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(n, reference), \ +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define SAM0_DAC_REFSEL(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, reference), \ (DT_INST_ENUM_IDX(n, reference)), (0)) -#define SAM0_DAC_INIT(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static const struct dac_sam0_cfg dac_sam0_cfg_##n = { \ - .regs = (Dac *)DT_INST_REG_ADDR(n), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .pm_apbc_bit = DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit), \ - .gclk_clkctrl_id = \ - DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id), \ - .refsel = UTIL_CAT(SAM0_DAC_REFSEL_, SAM0_DAC_REFSEL(n)), \ - }; \ - \ - DEVICE_DT_INST_DEFINE(n, &dac_sam0_init, NULL, NULL, \ - &dac_sam0_cfg_##n, POST_KERNEL, \ - CONFIG_DAC_INIT_PRIORITY, \ +#define SAM0_DAC_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static const struct dac_sam0_cfg dac_sam0_cfg_##n = { \ + .regs = (Dac *)DT_INST_REG_ADDR(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ + .refsel = UTIL_CAT(SAM0_DAC_REFSEL_, SAM0_DAC_REFSEL(n)), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, &dac_sam0_init, NULL, NULL, \ + &dac_sam0_cfg_##n, POST_KERNEL, \ + CONFIG_DAC_INIT_PRIORITY, \ &api_sam0_driver_api) DT_INST_FOREACH_STATUS_OKAY(SAM0_DAC_INIT); + +/* clang-format on */ diff --git a/drivers/dac/dac_shell.c b/drivers/dac/dac_shell.c index 11789f7153b3c..12260ad634acc 100644 --- a/drivers/dac/dac_shell.c +++ b/drivers/dac/dac_shell.c @@ -36,7 +36,7 @@ static int cmd_setup(const struct shell *sh, size_t argc, char **argv) int argidx; int err; - dac = device_get_binding(argv[args_indx.device]); + dac = shell_device_get_binding(argv[args_indx.device]); if (!dac) { shell_error(sh, "DAC device not found"); return -EINVAL; @@ -76,7 +76,7 @@ static int cmd_write_value(const struct shell *sh, size_t argc, char **argv) uint32_t value; int err; - dac = device_get_binding(argv[args_indx.device]); + dac = shell_device_get_binding(argv[args_indx.device]); if (!dac) { shell_error(sh, "DAC device not found"); return -EINVAL; @@ -94,14 +94,31 @@ static int cmd_write_value(const struct shell *sh, size_t argc, char **argv) return 0; } +static bool device_is_dac(const struct device *dev) +{ + return DEVICE_API_IS(dac, dev); +} + +static void device_name_get(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_filter(idx, device_is_dac); + + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; +} + +SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); + SHELL_STATIC_SUBCMD_SET_CREATE(dac_cmds, - SHELL_CMD_ARG(setup, NULL, + SHELL_CMD_ARG(setup, &dsub_device_name, "Setup DAC channel\n" "Usage: setup [-b] [-i]\n" "-b Enable output buffer\n" "-i Connect internally", cmd_setup, 4, 2), - SHELL_CMD_ARG(write_value, NULL, + SHELL_CMD_ARG(write_value, &dsub_device_name, "Write DAC value\n" "Usage: write ", cmd_write_value, 4, 0), diff --git a/drivers/dai/CMakeLists.txt b/drivers/dai/CMakeLists.txt index 506c2a54335bc..2196c11485f68 100644 --- a/drivers/dai/CMakeLists.txt +++ b/drivers/dai/CMakeLists.txt @@ -6,3 +6,4 @@ add_subdirectory_ifdef(CONFIG_DAI_INTEL_DMIC intel/dmic) add_subdirectory_ifdef(CONFIG_DAI_INTEL_HDA intel/hda) add_subdirectory_ifdef(CONFIG_DAI_NXP_SAI nxp/sai) add_subdirectory_ifdef(CONFIG_DAI_NXP_ESAI nxp/esai) +add_subdirectory_ifdef(CONFIG_DAI_NXP_MICFIL nxp/micfil) diff --git a/drivers/dai/Kconfig b/drivers/dai/Kconfig index 05877efd88eda..fc3972a989666 100644 --- a/drivers/dai/Kconfig +++ b/drivers/dai/Kconfig @@ -31,5 +31,6 @@ source "drivers/dai/intel/dmic/Kconfig.dmic" source "drivers/dai/intel/hda/Kconfig.hda" source "drivers/dai/nxp/sai/Kconfig.sai" source "drivers/dai/nxp/esai/Kconfig.esai" +source "drivers/dai/nxp/micfil/Kconfig.micfil" endif # DAI diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index 587a91957cff4..e1a93da91b46e 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -895,13 +895,8 @@ static int dai_dmic_initialize_device(const struct device *dev) dai_dmic_irq_handler, DEVICE_DT_INST_GET(0), 0); - if (pm_device_on_power_domain(dev)) { - pm_device_init_off(dev); - } else { - pm_device_init_suspended(dev); - } - return pm_device_runtime_enable(dev); + return pm_device_driver_init(dev, dmic_pm_action); }; diff --git a/drivers/dai/intel/hda/hda.c b/drivers/dai/intel/hda/hda.c index 45c803e59c1c3..c057466b5a6d2 100644 --- a/drivers/dai/intel/hda/hda.c +++ b/drivers/dai/intel/hda/hda.c @@ -8,7 +8,10 @@ #include #include #include +#include #include +#include +#include #include #define DT_DRV_COMPAT intel_hda_dai @@ -103,9 +106,35 @@ static int dai_hda_remove(const struct device *dev) return 0; } +static int hda_pm_action(const struct device *dev, enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + dai_hda_remove(dev); + break; + case PM_DEVICE_ACTION_RESUME: + dai_hda_probe(dev); + break; + case PM_DEVICE_ACTION_TURN_OFF: + case PM_DEVICE_ACTION_TURN_ON: + /* All device pm is handled during resume and suspend */ + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static int hda_init(const struct device *dev) +{ + LOG_DBG("%s", __func__); + return pm_device_driver_init(dev, hda_pm_action); +} + static DEVICE_API(dai, dai_intel_hda_api_funcs) = { - .probe = dai_hda_probe, - .remove = dai_hda_remove, + .probe = pm_device_runtime_get, + .remove = pm_device_runtime_put, .config_set = dai_hda_config_set, .config_get = dai_hda_config_get, .trigger = dai_hda_trigger, @@ -122,11 +151,14 @@ static DEVICE_API(dai, dai_intel_hda_api_funcs) = { \ }; \ \ + PM_DEVICE_DT_INST_DEFINE(n, hda_pm_action); \ + \ DEVICE_DT_INST_DEFINE(n, \ - NULL, NULL, \ + hda_init, PM_DEVICE_DT_INST_GET(n), \ &dai_intel_hda_data_##n, \ &dai_intel_hda_config_##n, \ - POST_KERNEL, 32, \ + POST_KERNEL, \ + CONFIG_DAI_INIT_PRIORITY, \ &dai_intel_hda_api_funcs); DT_INST_FOREACH_STATUS_OKAY(DAI_INTEL_HDA_DEVICE_INIT) diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index 879e520e4fc5f..bd0f6479fba80 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -743,7 +743,8 @@ static int dai_ssp_poll_for_register_delay(uint32_t reg, uint32_t mask, uint32_t val, uint64_t us) { if (!WAIT_FOR((sys_read32(reg) & mask) == val, us, k_busy_wait(1))) { - LOG_ERR("poll timeout reg %u mask %u val %u us %u", reg, mask, val, (uint32_t)us); + LOG_ERR("poll timeout reg[%#x]=%#x, waited for: mask %#x, val %#x, us %u", reg, + sys_read32(reg), mask, val, (uint32_t)us); return -EIO; } @@ -864,7 +865,7 @@ static void dai_ssp_program_channel_map(struct dai_intel_ssp *dp, /* Set upper slot number from configuration */ pcmsycm = pcmsycm | (dp->ssp_plat_data->params.tdm_slots - 1) << 4; - if (DAI_INTEL_SSP_IS_BIT_SET(cfg->link_config, 15)) { + if (IS_BIT_SET(cfg->link_config, 15)) { uint32_t reg_add = dai_ip_base(dp) + 0x1000 * ssp_index + PCMS0CM_OFFSET; /* Program HDA output stream parameters */ sys_write16((pcmsycm & 0xffff), reg_add); @@ -880,7 +881,7 @@ static void dai_ssp_program_channel_map(struct dai_intel_ssp *dp, uint16_t pcmsycm = cfg->link_config; uint8_t slot_count = 0; - if (DAI_INTEL_SSP_IS_BIT_SET(cfg->link_config, 15)) { + if (IS_BIT_SET(cfg->link_config, 15)) { if (blob30->version == SSP_BLOB_VER_3_0) { time_slot_map = blob30->i2s_ssp_config.ssmidytsa[cfg->tdm_slot_group]; @@ -1936,6 +1937,9 @@ static int dai_ssp_parse_tlv(struct dai_intel_ssp *dp, const uint8_t *aux_ptr, s struct ssp_intel_ext_ctl *ext; #if SSP_IP_VER >= SSP_IP_VER_1_5 struct ssp_intel_link_ctl *link; +#if SSP_IP_VER > SSP_IP_VER_1_5 + struct dai_intel_ssp_plat_data *ssp = dai_get_plat_data(dp); +#endif #endif for (i = 0; i < aux_len; i += hop) { @@ -1989,6 +1993,7 @@ static int dai_ssp_parse_tlv(struct dai_intel_ssp *dp, const uint8_t *aux_ptr, s I2CLCTL_MLCS(link->clock_source), dai_ip_base(dp) + I2SLCTL_OFFSET); #elif SSP_IP_VER > SSP_IP_VER_1_5 + ssp->link_clock = link->clock_source; sys_write32((sys_read32(dai_i2svss_base(dp) + I2SLCTL_OFFSET) & ~I2CLCTL_MLCS(0x7)) | I2CLCTL_MLCS(link->clock_source), @@ -2075,8 +2080,6 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp); const struct dai_intel_ipc4_ssp_config_ver_3_0 *regs = spec_config; uint32_t sscr1 = 0; - uint32_t sstsa = 0; - uint32_t ssrsa = 0; uint32_t ssc0 = regs->ssc0; sscr1 = regs->ssc1 & ~(SSCR1_RSVD21); @@ -2325,29 +2328,29 @@ static void dai_ssp_start(struct dai_intel_ssp *dp, int direction) /* enable DMA */ -#if SSP_IP_VER > SSP_IP_VER_2_0 if (direction == DAI_DIR_PLAYBACK) { + LOG_INF("SSP%d TX", dp->dai_index); +#if SSP_IP_VER > SSP_IP_VER_2_0 dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), SSMODyCS_TSRE, SSMODyCS_TSRE); dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), SSMODyCS_TXEN, SSMODyCS_TXEN); +#else + dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE, SSCR1_TSRE); + dai_ssp_update_bits(dp, SSTSA, SSTSA_TXEN, SSTSA_TXEN); +#endif } else { + LOG_INF("SSP%d RX", dp->dai_index); +#if SSP_IP_VER > SSP_IP_VER_2_0 dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), SSMIDyCS_RSRE, SSMIDyCS_RSRE); dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), SSMIDyCS_RXEN, SSMIDyCS_RXEN); - } #else - if (direction == DAI_DIR_PLAYBACK) { - LOG_INF("SSP%d TX", dp->dai_index); - dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE, SSCR1_TSRE); - dai_ssp_update_bits(dp, SSTSA, SSTSA_TXEN, SSTSA_TXEN); - } else { - LOG_INF("SSP%d RX", dp->dai_index); dai_ssp_update_bits(dp, SSCR1, SSCR1_RSRE, SSCR1_RSRE); dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, SSRSA_RXEN); - } #endif + } dp->state[direction] = DAI_STATE_RUNNING; @@ -2553,6 +2556,14 @@ static void ssp_acquire_ip(struct dai_intel_ssp *dp) /* Disable dynamic clock gating before touching any register */ dai_ssp_pm_runtime_dis_ssp_clk_gating(dp, ssp->ssp_index); + +#if SSP_IP_VER >= SSP_IP_VER_2_0 + /* Switch to selected clock source */ + sys_write32((sys_read32(dai_i2svss_base(dp) + I2SLCTL_OFFSET) & + ~I2CLCTL_MLCS(0x7)) | + I2CLCTL_MLCS(ssp->link_clock), + dai_i2svss_base(dp) + I2SLCTL_OFFSET); +#endif } } @@ -2578,6 +2589,14 @@ static void ssp_release_ip(struct dai_intel_ssp *dp) dai_ssp_post_stop(dp); +#if SSP_IP_VER >= SSP_IP_VER_2_0 + /* Restore default XTAL clock source */ + sys_write32((sys_read32(dai_i2svss_base(dp) + I2SLCTL_OFFSET) & + ~I2CLCTL_MLCS(0x7)) | + I2CLCTL_MLCS(DAI_INTEL_SSP_CLOCK_XTAL_OSCILLATOR), + dai_i2svss_base(dp) + I2SLCTL_OFFSET); +#endif + dai_ssp_pm_runtime_en_ssp_clk_gating(dp, ssp->ssp_index); dai_ssp_mclk_disable_unprepare(dp); @@ -2663,14 +2682,7 @@ static int dai_intel_ssp_init_device(const struct device *dev) static int ssp_init(const struct device *dev) { dai_intel_ssp_init_device(dev); - - if (pm_device_on_power_domain(dev)) { - pm_device_init_off(dev); - } else { - pm_device_init_suspended(dev); - } - - return pm_device_runtime_enable(dev); + return pm_device_driver_init(dev, ssp_pm_action); } static int dai_ssp_dma_control_set(const struct device *dev, diff --git a/drivers/dai/intel/ssp/ssp.h b/drivers/dai/intel/ssp/ssp.h index d85a95aa9a2f1..de0ba4ef9af63 100644 --- a/drivers/dai/intel/ssp/ssp.h +++ b/drivers/dai/intel/ssp/ssp.h @@ -39,7 +39,6 @@ (((x) & (1ULL << (b))) >> (b)) #define DAI_INTEL_SSP_GET_BITS(b_hi, b_lo, x) \ (((x) & MASK(b_hi, b_lo)) >> (b_lo)) -#define DAI_INTEL_SSP_IS_BIT_SET(reg, bit) (((reg >> bit) & (0x1)) != 0) /* ssp_freq array constants */ #define DAI_INTEL_SSP_NUM_FREQ 3 @@ -137,6 +136,7 @@ struct dai_intel_ssp_plat_data { #if SSP_IP_VER > SSP_IP_VER_1_5 uint32_t hdamlssp_base; uint32_t i2svss_base; + uint32_t link_clock; #endif int irq; const char *irq_name; diff --git a/drivers/dai/nxp/micfil/CMakeLists.txt b/drivers/dai/nxp/micfil/CMakeLists.txt new file mode 100644 index 0000000000000..50ea62e932795 --- /dev/null +++ b/drivers/dai/nxp/micfil/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(micfil.c) diff --git a/drivers/dai/nxp/micfil/Kconfig.micfil b/drivers/dai/nxp/micfil/Kconfig.micfil new file mode 100644 index 0000000000000..7e5e0cd8bebe6 --- /dev/null +++ b/drivers/dai/nxp/micfil/Kconfig.micfil @@ -0,0 +1,10 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config DAI_NXP_MICFIL + bool "NXP Pulse Density Modulation Microphone Interface (MICFIL) driver" + default y + depends on DT_HAS_NXP_DAI_MICFIL_ENABLED + select PINCTRL + help + Select this to enable NXP PDM MICFIL driver. diff --git a/drivers/dai/nxp/micfil/micfil.c b/drivers/dai/nxp/micfil/micfil.c new file mode 100644 index 0000000000000..364be9ac28a92 --- /dev/null +++ b/drivers/dai/nxp/micfil/micfil.c @@ -0,0 +1,209 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include + +#include "fsl_pdm.h" + +#define DT_DRV_COMPAT nxp_dai_micfil +LOG_MODULE_REGISTER(nxp_dai_micfil); + +#define MICFIL_CLK_ROOT 24576000 +#define MICFIL_OSR_DEFAULT 16 + +#define UINT_TO_MICFIL(x) ((PDM_Type *)(uintptr_t)(x)) + +#define MICFIL_FIFO_BASE(inst) \ + POINTER_TO_UINT(&(UINT_TO_MICFIL(DT_INST_REG_ADDR(inst))->DATACH[0])) + +#define MICFIL_DMA_HANDSHAKE(inst) \ + ((DT_INST_DMAS_CELL_BY_IDX(inst, 0, channel) & GENMASK(7, 0)) | \ + ((DT_INST_DMAS_CELL_BY_IDX(inst, 0, mux) << 8) & GENMASK(15, 8))) + +struct dai_nxp_micfil_data { + struct dai_config cfg; +}; + +struct dai_nxp_micfil_config { + PDM_Type *base; + const struct dai_properties *rx_props; + const struct pinctrl_dev_config *pincfg; +}; + +/* this needs to match SOF struct sof_ipc_dai_micfil_params */ +struct micfil_bespoke_config { + uint32_t pdm_rate; + uint32_t pdm_ch; +}; + +static void dai_nxp_micfil_trigger_start(const struct device *dev) +{ + const struct dai_nxp_micfil_config *cfg = dev->config; + + /* enable DMA requests */ + PDM_EnableDMA(cfg->base, true); + /* enable the module */ + PDM_Enable(cfg->base, true); +} + +static void dai_nxp_micfil_trigger_stop(const struct device *dev) +{ + const struct dai_nxp_micfil_config *cfg = dev->config; + + /* disable DMA requests */ + PDM_EnableDMA(cfg->base, false); + /* disable module */ + PDM_Enable(cfg->base, false); +} + +static const struct dai_properties +*dai_nxp_micfil_get_properties(const struct device *dev, enum dai_dir dir, int stream_id) +{ + const struct dai_nxp_micfil_config *cfg = dev->config; + + if (dir == DAI_DIR_RX) { + return cfg->rx_props; + } + + LOG_ERR("invalid direction %d", dir); + return NULL; +} + +static int dai_nxp_micfil_trigger(const struct device *dev, enum dai_dir dir, + enum dai_trigger_cmd cmd) +{ + if (dir != DAI_DIR_RX) { + LOG_ERR("invalid direction %d", dir); + return -EINVAL; + } + + switch (cmd) { + case DAI_TRIGGER_START: + dai_nxp_micfil_trigger_start(dev); + break; + case DAI_TRIGGER_STOP: + case DAI_TRIGGER_PAUSE: + dai_nxp_micfil_trigger_stop(dev); + break; + case DAI_TRIGGER_PRE_START: + case DAI_TRIGGER_COPY: + return 0; + default: + LOG_ERR("invalid trigger cmd %d", cmd); + return -EINVAL; + } + + return 0; +} + +static int dai_nxp_micfil_get_config(const struct device *dev, struct dai_config *cfg, + enum dai_dir dir) +{ + struct dai_nxp_micfil_data *micfil_data = dev->data; + + memcpy(cfg, &micfil_data->cfg, sizeof(*cfg)); + return 0; +} + +static int dai_nxp_micfil_set_config(const struct device *dev, + const struct dai_config *cfg, const void *bespoke_cfg) + +{ + const struct micfil_bespoke_config *bespoke = bespoke_cfg; + const struct dai_nxp_micfil_config *micfil_cfg = dev->config; + pdm_channel_config_t chan_config = { 0 }; + pdm_config_t global_config = { 0 }; + int ret, i; + + if (cfg->type != DAI_IMX_MICFIL) { + LOG_ERR("wrong DAI type: %d", cfg->type); + return -EINVAL; + } + + global_config.fifoWatermark = micfil_cfg->rx_props->fifo_depth - 1; + global_config.qualityMode = kPDM_QualityModeVeryLow0; + global_config.cicOverSampleRate = MICFIL_OSR_DEFAULT; + + PDM_Init(micfil_cfg->base, &global_config); + + for (i = 0; i < bespoke->pdm_ch; i++) { + chan_config.gain = kPDM_DfOutputGain2; + chan_config.cutOffFreq = kPDM_DcRemoverBypass; + PDM_SetChannelConfig(micfil_cfg->base, i, &chan_config); + } + + ret = PDM_SetSampleRateConfig(micfil_cfg->base, MICFIL_CLK_ROOT, bespoke->pdm_rate); + if (ret == kStatus_Fail) { + LOG_ERR("Failure to set samplerate config rate %d", bespoke->pdm_rate); + return -EINVAL; + } + + return 0; +} + +static int dai_nxp_micfil_probe(const struct device *dev) +{ + /* nothing do to here, but mandatory to exist */ + return 0; +} + +static int dai_nxp_micfil_remove(const struct device *dev) +{ + /* nothing do to here, but mandatory to exist */ + return 0; +} + +static DEVICE_API(dai, dai_nxp_micfil_ops) = { + .probe = dai_nxp_micfil_probe, + .remove = dai_nxp_micfil_remove, + .config_set = dai_nxp_micfil_set_config, + .config_get = dai_nxp_micfil_get_config, + .get_properties = dai_nxp_micfil_get_properties, + .trigger = dai_nxp_micfil_trigger, +}; + +static int micfil_init(const struct device *dev) +{ + const struct dai_nxp_micfil_config *cfg = dev->config; + int ret; + + /* pinctrl is optional so do not return an error if not defined */ + ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (ret < 0 && ret != -ENOENT) { + return ret; + } + + return 0; +} + +#define DAI_NXP_MICFIL_INIT(inst) \ +PINCTRL_DT_INST_DEFINE(inst); \ +static struct dai_nxp_micfil_data dai_nxp_micfil_data_##inst = { \ + .cfg.type = DAI_IMX_MICFIL, \ + .cfg.dai_index = DT_INST_PROP_OR(inst, dai_index, 0), \ +}; \ + \ +static const struct dai_properties micfil_rx_props_##inst = { \ + .fifo_address = MICFIL_FIFO_BASE(inst), \ + .fifo_depth = DT_INST_PROP(inst, fifo_depth), \ + .dma_hs_id = MICFIL_DMA_HANDSHAKE(inst), \ +}; \ + \ +static const struct dai_nxp_micfil_config dai_nxp_micfil_config_##inst = { \ + .base = UINT_TO_MICFIL(DT_INST_REG_ADDR(inst)), \ + .rx_props = &micfil_rx_props_##inst, \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ +}; \ + \ +DEVICE_DT_INST_DEFINE(inst, &micfil_init, NULL, \ + &dai_nxp_micfil_data_##inst, &dai_nxp_micfil_config_##inst, \ + POST_KERNEL, CONFIG_DAI_INIT_PRIORITY, \ + &dai_nxp_micfil_ops); \ + +DT_INST_FOREACH_STATUS_OKAY(DAI_NXP_MICFIL_INIT) diff --git a/drivers/disk/sdmmc_stm32.c b/drivers/disk/sdmmc_stm32.c index 114e7d6b467ab..b0f3503b6c71c 100644 --- a/drivers/disk/sdmmc_stm32.c +++ b/drivers/disk/sdmmc_stm32.c @@ -537,7 +537,7 @@ static const struct disk_operations stm32_sdmmc_ops = { }; static struct disk_info stm32_sdmmc_info = { - .name = "SD", + .name = DT_INST_PROP_OR(0, disk_name, "SD"), .ops = &stm32_sdmmc_ops, }; diff --git a/drivers/disk/sdmmc_subsys.c b/drivers/disk/sdmmc_subsys.c index 500471d4d659d..6fc8d7fd6e3fa 100644 --- a/drivers/disk/sdmmc_subsys.c +++ b/drivers/disk/sdmmc_subsys.c @@ -21,12 +21,13 @@ enum sd_status { struct sdmmc_config { const struct device *host_controller; + const char *name; }; struct sdmmc_data { struct sd_card card; enum sd_status status; - struct disk_info *disk_info; + struct disk_info disk_info; }; @@ -113,27 +114,24 @@ static const struct disk_operations sdmmc_disk_ops = { static int disk_sdmmc_init(const struct device *dev) { + const struct sdmmc_config *config = dev->config; struct sdmmc_data *data = dev->data; data->status = SD_UNINIT; + data->disk_info.name = config->name; + data->disk_info.ops = &sdmmc_disk_ops; + data->disk_info.dev = dev; - return disk_access_register(data->disk_info); + return disk_access_register(&data->disk_info); } #define DISK_ACCESS_SDMMC_INIT(n) \ static const struct sdmmc_config sdmmc_config_##n = { \ .host_controller = DEVICE_DT_GET(DT_INST_PARENT(n)), \ - }; \ - \ - static struct disk_info sdmmc_disk_##n = { \ .name = DT_INST_PROP(n, disk_name), \ - .ops = &sdmmc_disk_ops, \ - .dev = DEVICE_DT_INST_GET(n), \ }; \ \ - static struct sdmmc_data sdmmc_data_##n = { \ - .disk_info = &sdmmc_disk_##n, \ - }; \ + static struct sdmmc_data sdmmc_data_##n; \ \ DEVICE_DT_INST_DEFINE(n, \ &disk_sdmmc_init, \ diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index 1c8ad62b645e2..185e3a1b2b4bc 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -31,6 +31,8 @@ zephyr_library_sources_ifdef(CONFIG_GC9X01X display_gc9x01x.c) zephyr_library_sources_ifdef(CONFIG_LED_STRIP_MATRIX display_led_strip_matrix.c) zephyr_library_sources_ifdef(CONFIG_DISPLAY_RENESAS_LCDC display_renesas_lcdc.c) zephyr_library_sources_ifdef(CONFIG_NT35510 display_nt35510.c) +zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_GLCDC display_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_ILI9806E_DSI display_ili9806e_dsi.c) zephyr_library_sources_ifdef(CONFIG_MICROBIT_DISPLAY mb_display.c diff --git a/drivers/display/Kconfig b/drivers/display/Kconfig index 890eb36015c2d..593c34dc163ba 100644 --- a/drivers/display/Kconfig +++ b/drivers/display/Kconfig @@ -48,5 +48,7 @@ source "drivers/display/Kconfig.gc9x01x" source "drivers/display/Kconfig.led_strip_matrix" source "drivers/display/Kconfig.renesas_lcdc" source "drivers/display/Kconfig.nt35510" +source "drivers/display/Kconfig.renesas_ra" +source "drivers/display/Kconfig.ili9806e_dsi" endif # DISPLAY diff --git a/drivers/display/Kconfig.ili9806e_dsi b/drivers/display/Kconfig.ili9806e_dsi new file mode 100644 index 0000000000000..ea8f4ec32404c --- /dev/null +++ b/drivers/display/Kconfig.ili9806e_dsi @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config ILI9806E_DSI + bool "ILI9806E_DSI display driver" + default y + depends on DT_HAS_ILITEK_ILI9806E_DSI_ENABLED + select MIPI_DSI + help + Enable driver for ILI9806E_DSI display driver. + +if ILI9806E_DSI + +config DISPLAY_ILI9806E_DSI_INIT_PRIORITY + int "Initialization priority" + default 90 + help + ILI9806E_DSI display driver initialization priority. + +endif diff --git a/drivers/display/Kconfig.ili9xxx b/drivers/display/Kconfig.ili9xxx index d1710d176e918..f203e614d2027 100644 --- a/drivers/display/Kconfig.ili9xxx +++ b/drivers/display/Kconfig.ili9xxx @@ -12,13 +12,13 @@ config ILI9XXX config ILI9XXX_READ bool "Allow display_read API with ILI9XXX" + depends on ILI9XXX help Support display_read API with ILI9XXX controllers. This API is opt-in, because it adds code overhead and is not very performant due to the requirement to bitshift data read from the ILI9XXX. Note the API only supports RGB565 mode. - config ILI9340 bool "ILI9340 display driver" default y diff --git a/drivers/display/Kconfig.renesas_ra b/drivers/display/Kconfig.renesas_ra new file mode 100644 index 0000000000000..4eaaeb99196d3 --- /dev/null +++ b/drivers/display/Kconfig.renesas_ra @@ -0,0 +1,34 @@ +# Renesas RA Family + +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config RENESAS_RA_GLCDC + bool "Renesas display controller driver" + default y + depends on DT_HAS_RENESAS_RA_GLCDC_ENABLED + select USE_RA_FSP_DISPLAY + help + Enable Renesas display controller. + +if RENESAS_RA_GLCDC + +config RENESAS_RA_GLCDC_FB_NUM + int "Frame buffer number" + default 2 + range 0 2 + help + RENESAS RA GLCDC frame buffer number config: + - 0 frame buffer maintained by application, must write with full screen pixels. + - 1 single frame buffer in RENESAS RA GLCDC driver. + - 2 double frame buffer in RENESAS RA GLCDC driver. + +if LVGL + +# Force display buffers to be aligned to cache line size (64 bytes) +config LV_Z_VDB_ALIGN + default 64 + +endif # LVGL + +endif # RENESAS_RA_GLCDC diff --git a/drivers/display/Kconfig.ssd1306 b/drivers/display/Kconfig.ssd1306 index 413e32d8f334b..f067f572371d1 100644 --- a/drivers/display/Kconfig.ssd1306 +++ b/drivers/display/Kconfig.ssd1306 @@ -6,9 +6,11 @@ menuconfig SSD1306 bool "SSD1306 display driver" default y - depends on DT_HAS_SOLOMON_SSD1306FB_ENABLED || DT_HAS_SINOWEALTH_SH1106_ENABLED + depends on DT_HAS_SOLOMON_SSD1306FB_ENABLED || DT_HAS_SOLOMON_SSD1309FB_ENABLED || DT_HAS_SINOWEALTH_SH1106_ENABLED select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),i2c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309FB),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309FB),spi) select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),i2c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),spi) help diff --git a/drivers/display/display_dummy.c b/drivers/display/display_dummy.c index 2ba8c8c6c92d6..de9394b0ea759 100644 --- a/drivers/display/display_dummy.c +++ b/drivers/display/display_dummy.c @@ -38,7 +38,7 @@ static int dummy_display_write(const struct device *dev, const uint16_t x, { const struct dummy_display_config *config = dev->config; - __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT(desc->pitch <= config->width, "Pitch in descriptor is larger than screen size"); __ASSERT(desc->height <= config->height, diff --git a/drivers/display/display_gc9x01x.c b/drivers/display/display_gc9x01x.c index 35cedc9c21957..43ae97d00013f 100644 --- a/drivers/display/display_gc9x01x.c +++ b/drivers/display/display_gc9x01x.c @@ -518,7 +518,7 @@ static int gc9x01x_write(const struct device *dev, const uint16_t x, const uint1 __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT((desc->pitch * data->bytes_per_pixel * desc->height) <= desc->buf_size, - "Input buffer to small"); + "Input buffer too small"); LOG_DBG("Writing %dx%d (w,h) @ %dx%d (x,y)", desc->width, desc->height, x, y); ret = gc9x01x_set_mem_area(dev, x, y, desc->width, desc->height); diff --git a/drivers/display/display_ili9340.h b/drivers/display/display_ili9340.h index 50836b030181c..aaa0d2bfd210b 100644 --- a/drivers/display/display_ili9340.h +++ b/drivers/display/display_ili9340.h @@ -50,7 +50,7 @@ struct ili9340_regs { /* Initializer macro for ILI9340 registers. */ #define ILI9340_REGS_INIT(n) \ - static const struct ili9340_regs ili9xxx_regs_##n = { \ + static const struct ili9340_regs ili9340_regs_##n = { \ .gamset = DT_PROP(DT_INST(n, ilitek_ili9340), gamset), \ .frmctr1 = DT_PROP(DT_INST(n, ilitek_ili9340), frmctr1), \ .disctrl = DT_PROP(DT_INST(n, ilitek_ili9340), disctrl), \ diff --git a/drivers/display/display_ili9341.h b/drivers/display/display_ili9341.h index 5ffd60fc5cb99..b46f6ba9fb01e 100644 --- a/drivers/display/display_ili9341.h +++ b/drivers/display/display_ili9341.h @@ -121,7 +121,7 @@ struct ili9341_regs { "ili9341: Error length frame rate control (IFCTL) register"); \ BUILD_ASSERT(DT_PROP_LEN(DT_INST(n, ilitek_ili9341), etmod) == ILI9341_ETMOD_LEN, \ "ili9341: Error length entry Mode Set (ETMOD) register"); \ - static const struct ili9341_regs ili9xxx_regs_##n = { \ + static const struct ili9341_regs ili9341_regs_##n = { \ .gamset = DT_PROP(DT_INST(n, ilitek_ili9341), gamset), \ .ifmode = DT_PROP(DT_INST(n, ilitek_ili9341), ifmode), \ .frmctr1 = DT_PROP(DT_INST(n, ilitek_ili9341), frmctr1), \ diff --git a/drivers/display/display_ili9342c.h b/drivers/display/display_ili9342c.h index c5cc8fb5b9f13..d028248cff0ca 100644 --- a/drivers/display/display_ili9342c.h +++ b/drivers/display/display_ili9342c.h @@ -67,7 +67,7 @@ struct ili9342c_regs { /* Initializer macro for ILI9342C registers. */ #define ILI9342c_REGS_INIT(n) \ - static const struct ili9342c_regs ili9xxx_regs_##n = { \ + static const struct ili9342c_regs ili9342c_regs_##n = { \ .gamset = DT_PROP(DT_INST(n, ilitek_ili9342c), gamset), \ .ifmode = DT_PROP(DT_INST(n, ilitek_ili9342c), ifmode), \ .frmctr1 = DT_PROP(DT_INST(n, ilitek_ili9342c), frmctr1), \ diff --git a/drivers/display/display_ili9488.h b/drivers/display/display_ili9488.h index 8cb9f37b50739..93d8be2d830a3 100644 --- a/drivers/display/display_ili9488.h +++ b/drivers/display/display_ili9488.h @@ -44,7 +44,7 @@ struct ili9488_regs { /* Initializer macro for ILI9488 registers. */ #define ILI9488_REGS_INIT(n) \ - static const struct ili9488_regs ili9xxx_regs_##n = { \ + static const struct ili9488_regs ili9488_regs_##n = { \ .frmctr1 = DT_PROP(DT_INST(n, ilitek_ili9488), frmctr1), \ .disctrl = DT_PROP(DT_INST(n, ilitek_ili9488), disctrl), \ .pwctrl1 = DT_PROP(DT_INST(n, ilitek_ili9488), pwctrl1), \ diff --git a/drivers/display/display_ili9806e_dsi.c b/drivers/display/display_ili9806e_dsi.c new file mode 100644 index 0000000000000..ed54d413119a0 --- /dev/null +++ b/drivers/display/display_ili9806e_dsi.c @@ -0,0 +1,434 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ilitek_ili9806e_dsi + +#include +#include +#include +#include +#include +#include +#include "display_ili9806e_dsi.h" +LOG_MODULE_REGISTER(display_ili9806e_dsi, CONFIG_DISPLAY_LOG_LEVEL); + +#define ILITEK_ILI9806E_COLMOD_RGB565 0x50 +#define ILITEK_ILI9806E_COLMOD_RGB888 0x70 +struct ili9806e_config { + const struct device *mipi_dsi; + const struct gpio_dt_spec reset; + const struct gpio_dt_spec backlight; + enum display_pixel_format pixel_format; + uint8_t data_lanes; + uint16_t width; + uint16_t height; + uint8_t channel; +}; + +struct ili9806e_init_cmd { + uint8_t reg; + uint8_t cmd_len; + uint8_t cmd[5]; +} __packed; + +static const struct ili9806e_init_cmd init_cmds[] = { + /* Change to Page 1 CMD */ + {.reg = 0xff, .cmd_len = 5, .cmd = {0xFF, 0x98, 0x06, 0x04, 0x01}}, + /* Output SDA */ + {.reg = 0x08, .cmd_len = 1, .cmd = {0x10}}, + /* DE = 1 Active */ + {.reg = 0x21, .cmd_len = 1, .cmd = {0x01}}, + /* Resolution setting 480 X 800 */ + {.reg = 0x30, .cmd_len = 1, .cmd = {0x01}}, + /* Inversion setting */ + {.reg = 0x31, .cmd_len = 1, .cmd = {0x00}}, + /* BT 15 */ + {.reg = 0x40, .cmd_len = 1, .cmd = {0x14}}, + /* avdd +5.2v,avee-5.2v */ + {.reg = 0x41, .cmd_len = 1, .cmd = {0x33}}, + /* VGL=DDVDL+VCL-VCIP,VGH=2DDVDH-DDVDL */ + {.reg = 0x42, .cmd_len = 1, .cmd = {0x02}}, + /* Set VGH clamp level */ + {.reg = 0x43, .cmd_len = 1, .cmd = {0x09}}, + /* Set VGL clamp level */ + {.reg = 0x44, .cmd_len = 1, .cmd = {0x06}}, + /* Set VREG1 */ + {.reg = 0x50, .cmd_len = 1, .cmd = {0x70}}, + /* Set VREG2 */ + {.reg = 0x51, .cmd_len = 1, .cmd = {0x70}}, + /* Flicker MSB */ + {.reg = 0x52, .cmd_len = 1, .cmd = {0x00}}, + /* Flicker LSB */ + {.reg = 0x53, .cmd_len = 1, .cmd = {0x48}}, + /* Timing Adjust */ + {.reg = 0x60, .cmd_len = 1, .cmd = {0x07}}, + {.reg = 0x61, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x62, .cmd_len = 1, .cmd = {0x08}}, + {.reg = 0x63, .cmd_len = 1, .cmd = {0x00}}, + /* Positive Gamma Control 1 */ + {.reg = 0xa0, .cmd_len = 1, .cmd = {0x00}}, + /* Positive Gamma Control 2 */ + {.reg = 0xa1, .cmd_len = 1, .cmd = {0x03}}, + /* Positive Gamma Control 3 */ + {.reg = 0xa2, .cmd_len = 1, .cmd = {0x09}}, + /* Positive Gamma Control 4 */ + {.reg = 0xa3, .cmd_len = 1, .cmd = {0x0d}}, + /* Positive Gamma Control 5 */ + {.reg = 0xa4, .cmd_len = 1, .cmd = {0x06}}, + /* Positive Gamma Control 6 */ + {.reg = 0xa5, .cmd_len = 1, .cmd = {0x16}}, + /* Positive Gamma Control 7 */ + {.reg = 0xa6, .cmd_len = 1, .cmd = {0x09}}, + /* Positive Gamma Control 8 */ + {.reg = 0xa7, .cmd_len = 1, .cmd = {0x08}}, + /* Positive Gamma Control 9 */ + {.reg = 0xa8, .cmd_len = 1, .cmd = {0x03}}, + /* Positive Gamma Control 10 */ + {.reg = 0xa9, .cmd_len = 1, .cmd = {0x07}}, + /* Positive Gamma Control 11 */ + {.reg = 0xaa, .cmd_len = 1, .cmd = {0x06}}, + /* Positive Gamma Control 12 */ + {.reg = 0xab, .cmd_len = 1, .cmd = {0x05}}, + /* Positive Gamma Control 13 */ + {.reg = 0xac, .cmd_len = 1, .cmd = {0x0d}}, + /* Positive Gamma Control 14 */ + {.reg = 0xad, .cmd_len = 1, .cmd = {0x2c}}, + /* Positive Gamma Control 15 */ + {.reg = 0xae, .cmd_len = 1, .cmd = {0x26}}, + /* Positive Gamma Control 16 */ + {.reg = 0xaf, .cmd_len = 1, .cmd = {0x00}}, + /* Negative Gamma Correction 1 */ + {.reg = 0xc0, .cmd_len = 1, .cmd = {0x00}}, + /* Negative Gamma Correction 2 */ + {.reg = 0xc1, .cmd_len = 1, .cmd = {0x04}}, + /* Negative Gamma Correction 3 */ + {.reg = 0xc2, .cmd_len = 1, .cmd = {0x0b}}, + /* Negative Gamma Correction 4 */ + {.reg = 0xc3, .cmd_len = 1, .cmd = {0x0f}}, + /* Negative Gamma Correction 5 */ + {.reg = 0xc4, .cmd_len = 1, .cmd = {0x09}}, + /* Negative Gamma Correction 6 */ + {.reg = 0xc5, .cmd_len = 1, .cmd = {0x18}}, + /* Negative Gamma Correction 7 */ + {.reg = 0xc6, .cmd_len = 1, .cmd = {0x07}}, + /* Negative Gamma Correction 8 */ + {.reg = 0xc7, .cmd_len = 1, .cmd = {0x08}}, + /* Negative Gamma Correction 9 */ + {.reg = 0xc8, .cmd_len = 1, .cmd = {0x05}}, + /* Negative Gamma Correction 10 */ + {.reg = 0xc9, .cmd_len = 1, .cmd = {0x09}}, + /* Negative Gamma Correction 11 */ + {.reg = 0xca, .cmd_len = 1, .cmd = {0x07}}, + /* Negative Gamma Correction 12 */ + {.reg = 0xcb, .cmd_len = 1, .cmd = {0x05}}, + /* Negative Gamma Correction 13 */ + {.reg = 0xcc, .cmd_len = 1, .cmd = {0x0c}}, + /* Negative Gamma Correction 14 */ + {.reg = 0xcd, .cmd_len = 1, .cmd = {0x2d}}, + /* Negative Gamma Correction 15 */ + {.reg = 0xce, .cmd_len = 1, .cmd = {0x28}}, + /* Negative Gamma Correction 16 */ + {.reg = 0xcf, .cmd_len = 1, .cmd = {0x00}}, + + /* Change to Page 6 CMD for GIP timing */ + {.reg = 0xff, .cmd_len = 5, .cmd = {0xFF, 0x98, 0x06, 0x04, 0x06}}, + /* GIP Control 1 */ + {.reg = 0x00, .cmd_len = 1, .cmd = {0x21}}, + {.reg = 0x01, .cmd_len = 1, .cmd = {0x09}}, + {.reg = 0x02, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x03, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x04, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x05, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x06, .cmd_len = 1, .cmd = {0x80}}, + {.reg = 0x07, .cmd_len = 1, .cmd = {0x05}}, + {.reg = 0x08, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x09, .cmd_len = 1, .cmd = {0x80}}, + {.reg = 0x0a, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x0b, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x0c, .cmd_len = 1, .cmd = {0x0a}}, + {.reg = 0x0d, .cmd_len = 1, .cmd = {0x0a}}, + {.reg = 0x0e, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x0f, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x10, .cmd_len = 1, .cmd = {0xe0}}, + {.reg = 0x11, .cmd_len = 1, .cmd = {0xe4}}, + {.reg = 0x12, .cmd_len = 1, .cmd = {0x04}}, + {.reg = 0x13, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x14, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x15, .cmd_len = 1, .cmd = {0xc0}}, + {.reg = 0x16, .cmd_len = 1, .cmd = {0x08}}, + {.reg = 0x17, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x18, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x19, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1a, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1b, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1c, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1d, .cmd_len = 1, .cmd = {0x00}}, + /* GIP Control 2 */ + {.reg = 0x20, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x21, .cmd_len = 1, .cmd = {0x23}}, + {.reg = 0x22, .cmd_len = 1, .cmd = {0x45}}, + {.reg = 0x23, .cmd_len = 1, .cmd = {0x67}}, + {.reg = 0x24, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x25, .cmd_len = 1, .cmd = {0x23}}, + {.reg = 0x26, .cmd_len = 1, .cmd = {0x45}}, + {.reg = 0x27, .cmd_len = 1, .cmd = {0x67}}, + /* GIP Control 3 */ + {.reg = 0x30, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x31, .cmd_len = 1, .cmd = {0x11}}, + {.reg = 0x32, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x33, .cmd_len = 1, .cmd = {0xee}}, + {.reg = 0x34, .cmd_len = 1, .cmd = {0xff}}, + {.reg = 0x35, .cmd_len = 1, .cmd = {0xcb}}, + {.reg = 0x36, .cmd_len = 1, .cmd = {0xda}}, + {.reg = 0x37, .cmd_len = 1, .cmd = {0xad}}, + {.reg = 0x38, .cmd_len = 1, .cmd = {0xbc}}, + {.reg = 0x39, .cmd_len = 1, .cmd = {0x76}}, + {.reg = 0x3a, .cmd_len = 1, .cmd = {0x67}}, + {.reg = 0x3b, .cmd_len = 1, .cmd = {0x22}}, + {.reg = 0x3c, .cmd_len = 1, .cmd = {0x22}}, + {.reg = 0x3d, .cmd_len = 1, .cmd = {0x22}}, + {.reg = 0x3e, .cmd_len = 1, .cmd = {0x22}}, + {.reg = 0x3f, .cmd_len = 1, .cmd = {0x22}}, + {.reg = 0x40, .cmd_len = 1, .cmd = {0x22}}, + /* GOUT VGLO Control */ + {.reg = 0x53, .cmd_len = 1, .cmd = {0x10}}, + {.reg = 0x54, .cmd_len = 1, .cmd = {0x10}}, + /* Change to Page 7 CMD for Normal command */ + {.reg = 0xff, .cmd_len = 5, .cmd = {0xff, 0x98, 0x06, 0x04, 0x07}}, + /* VREG1/2OUT ENABLE */ + {.reg = 0x18, .cmd_len = 1, .cmd = {0x1d}}, + {.reg = 0x26, .cmd_len = 1, .cmd = {0xb2}}, + {.reg = 0x02, .cmd_len = 1, .cmd = {0x77}}, + {.reg = 0xe1, .cmd_len = 1, .cmd = {0x79}}, + {.reg = 0x17, .cmd_len = 1, .cmd = {0x22}}, + /* Change to Page 0 CMD for Normal command */ + {.reg = 0xff, .cmd_len = 5, .cmd = {0xff, 0x98, 0x06, 0x04, 0x00}}}; + +static int ili9806e_write_reg(const struct device *dev, uint8_t reg, const uint8_t *buf, size_t len) +{ + int ret; + const struct ili9806e_config *cfg = dev->config; + + ret = mipi_dsi_dcs_write(cfg->mipi_dsi, cfg->channel, reg, buf, len); + if (ret < 0) { + LOG_ERR("Failed writing reg: 0x%x result: (%d)", reg, ret); + return ret; + } + + return 0; +} + +static int ili9806e_write_reg_val(const struct device *dev, uint8_t reg, uint8_t value) +{ + return ili9806e_write_reg(dev, reg, &value, 1); +} + +static int ili9806e_write_sequence(const struct device *dev, const struct ili9806e_init_cmd *cmd, + uint8_t nr_cmds) +{ + int ret = 0; + + /* Loop through all commands as long as writes are successful */ + for (int i = 0; i < nr_cmds && ret == 0; i++) { + ret = ili9806e_write_reg(dev, cmd->reg, cmd->cmd, cmd->cmd_len); + if (ret < 0) { + LOG_ERR("Failed writing sequence: 0x%x result: (%d)", cmd->reg, ret); + return ret; + } + cmd++; + } + + return ret; +} + +static int ili9806e_config(const struct device *dev) +{ + const struct ili9806e_config *cfg = dev->config; + int ret; + + ret = ili9806e_write_sequence(dev, init_cmds, ARRAY_SIZE(init_cmds)); + if (ret < 0) { + return ret; + } + /* Add a delay, otherwise MADCTL not taken */ + k_msleep(120); + + /* Exit sleep mode */ + ret = ili9806e_write_reg(dev, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); + if (ret < 0) { + return ret; + } + + /* Wait for sleep out exit */ + k_msleep(5); + + /* Set color mode */ + ret = ili9806e_write_reg_val(dev, MIPI_DCS_SET_PIXEL_FORMAT, + cfg->pixel_format == PIXEL_FORMAT_RGB_565 + ? ILITEK_ILI9806E_COLMOD_RGB565 + : ILITEK_ILI9806E_COLMOD_RGB888); + if (ret < 0) { + return ret; + } + + /* Turn on display */ + ret = ili9806e_write_reg(dev, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); + return ret; +} + +static int ili9806e_blanking_on(const struct device *dev) +{ + const struct ili9806e_config *cfg = dev->config; + int ret; + + if (cfg->backlight.port != NULL) { + ret = gpio_pin_set_dt(&cfg->backlight, 0); + if (ret) { + LOG_ERR("Disable backlight failed! (%d)", ret); + return ret; + } + } + + return ili9806e_write_reg(dev, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); +} + +static int ili9806e_blanking_off(const struct device *dev) +{ + const struct ili9806e_config *cfg = dev->config; + int ret; + + if (cfg->backlight.port != NULL) { + ret = gpio_pin_set_dt(&cfg->backlight, 1); + if (ret) { + LOG_ERR("Enable backlight failed! (%d)", ret); + return ret; + } + } + + return ili9806e_write_reg(dev, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); +} + +static void ili9806e_get_capabilities(const struct device *dev, + struct display_capabilities *capabilities) +{ + const struct ili9806e_config *cfg = dev->config; + + memset(capabilities, 0, sizeof(struct display_capabilities)); + capabilities->x_resolution = cfg->width; + capabilities->y_resolution = cfg->height; + capabilities->supported_pixel_formats = cfg->pixel_format; + capabilities->current_pixel_format = cfg->pixel_format; +} + +static int ili9806e_pixel_format(const struct device *dev, + const enum display_pixel_format pixel_format) +{ + const struct ili9806e_config *config = dev->config; + + LOG_WRN("Pixel format change not implemented"); + if (pixel_format == config->pixel_format) { + return 0; + } + + return -ENOTSUP; +} + +static DEVICE_API(display, ili9806e_api) = { + .blanking_on = ili9806e_blanking_on, + .blanking_off = ili9806e_blanking_off, + .set_pixel_format = ili9806e_pixel_format, + .get_capabilities = ili9806e_get_capabilities, +}; + +static int ili9806e_init(const struct device *dev) +{ + const struct ili9806e_config *cfg = dev->config; + struct mipi_dsi_device mdev; + int ret; + + if (cfg->reset.port) { + if (!gpio_is_ready_dt(&cfg->reset)) { + LOG_ERR("Reset GPIO device is not ready!"); + return -ENODEV; + } + k_sleep(K_MSEC(1)); + + ret = gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Reset display failed! (%d)", ret); + return ret; + } + + ret = gpio_pin_set_dt(&cfg->reset, 0); + if (ret < 0) { + LOG_ERR("Reset display failed! (%d)", ret); + return ret; + } + k_sleep(K_MSEC(1)); + + ret = gpio_pin_set_dt(&cfg->reset, 1); + if (ret < 0) { + LOG_ERR("Enable display failed! (%d)", ret); + return ret; + } + k_sleep(K_MSEC(50)); + } + + /* attach to MIPI-DSI host */ + if (cfg->pixel_format == PIXEL_FORMAT_RGB_565) { + mdev.pixfmt = MIPI_DSI_PIXFMT_RGB565; + } else { + mdev.pixfmt = MIPI_DSI_PIXFMT_RGB888; + } + mdev.data_lanes = cfg->data_lanes; + mdev.mode_flags = MIPI_DSI_MODE_VIDEO; + mdev.timings.hactive = cfg->width; + mdev.timings.hbp = ILITEK_ILI9806E_HBP; + mdev.timings.hfp = ILITEK_ILI9806E_HFP; + mdev.timings.hsync = ILITEK_ILI9806E_HSYNC; + mdev.timings.vactive = cfg->height; + mdev.timings.vbp = ILITEK_ILI9806E_VBP; + mdev.timings.vfp = ILITEK_ILI9806E_VFP; + mdev.timings.vsync = ILITEK_ILI9806E_VSYNC; + + ret = mipi_dsi_attach(cfg->mipi_dsi, cfg->channel, &mdev); + if (ret < 0) { + LOG_ERR("Could not attach to MIPI-DSI host"); + return ret; + } + + if (cfg->backlight.port != NULL) { + ret = gpio_pin_configure_dt(&cfg->backlight, GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_ERR("Could not configure backlight GPIO (%d)", ret); + return ret; + } + } + + ret = ili9806e_config(dev); + if (ret) { + LOG_ERR("DSI init sequence failed! (%d)", ret); + return ret; + } + + return 0; +} + +#define ILITEK_ILI9806E_DEFINE(n) \ + static const struct ili9806e_config ili9806e_config_##n = { \ + .mipi_dsi = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \ + .backlight = GPIO_DT_SPEC_INST_GET_OR(n, bl_gpios, {0}), \ + .data_lanes = DT_INST_PROP_BY_IDX(n, data_lanes, 0), \ + .width = DT_INST_PROP(n, width), \ + .height = DT_INST_PROP(n, height), \ + .channel = DT_INST_REG_ADDR(n), \ + .pixel_format = DT_INST_PROP(n, pixel_format), \ + }; \ + DEVICE_DT_INST_DEFINE(n, &ili9806e_init, NULL, NULL, &ili9806e_config_##n, POST_KERNEL, \ + CONFIG_DISPLAY_ILI9806E_DSI_INIT_PRIORITY, &ili9806e_api); + +DT_INST_FOREACH_STATUS_OKAY(ILITEK_ILI9806E_DEFINE) diff --git a/drivers/display/display_ili9806e_dsi.h b/drivers/display/display_ili9806e_dsi.h new file mode 100644 index 0000000000000..bf3f0f198957f --- /dev/null +++ b/drivers/display/display_ili9806e_dsi.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_DISPLAY_ILITEK_ILI9806E_H_ +#define ZEPHYR_DRIVERS_DISPLAY_ILITEK_ILI9806E_H_ + +#define LCD_TIMINGS_NODE DT_CHILD(DT_NODELABEL(zephyr_lcdif), display_timings) + +#define LCD_HTIMMING_SYNC DT_PROP(LCD_TIMINGS_NODE, hsync_len) +#define LCD_HTIMMING_BACK_PORCH DT_PROP(LCD_TIMINGS_NODE, hback_porch) +#define LCD_HTIMMING_FRONT_PORCH DT_PROP(LCD_TIMINGS_NODE, hfront_porch) +#define LCD_HACTIVE_LINE DT_PROP(DT_NODELABEL(zephyr_lcdif), width) +#define LCD_HTIMMING_TOTAL_CYC \ + LCD_HACTIVE_LINE + LCD_HTIMMING_BACK_PORCH + LCD_HTIMMING_FRONT_PORCH + LCD_HTIMMING_SYNC + +#define LCD_VTIMMING_SYNC DT_PROP(LCD_TIMINGS_NODE, vsync_len) +#define LCD_VTIMMING_BACK_PORCH DT_PROP(LCD_TIMINGS_NODE, vback_porch) +#define LCD_VTIMMING_FRONT_PORCH DT_PROP(LCD_TIMINGS_NODE, vfront_porch) +#define LCD_VACTIVE_LINE DT_PROP(DT_NODELABEL(zephyr_lcdif), height) +#define LCD_VTIMMING_TOTAL_CYC \ + LCD_VACTIVE_LINE + LCD_VTIMMING_BACK_PORCH + LCD_VTIMMING_FRONT_PORCH + LCD_VTIMMING_SYNC + +#define ILITEK_ILI9806E_HSYNC LCD_HTIMMING_SYNC +#define ILITEK_ILI9806E_HBP LCD_HTIMMING_BACK_PORCH - LCD_HTIMMING_SYNC +#define ILITEK_ILI9806E_HFP \ + LCD_HTIMMING_TOTAL_CYC - LCD_HACTIVE_LINE - LCD_HTIMMING_BACK_PORCH - LCD_HTIMMING_SYNC + +#define ILITEK_ILI9806E_VSYNC LCD_VTIMMING_SYNC +#define ILITEK_ILI9806E_VBP LCD_VTIMMING_BACK_PORCH - LCD_VTIMMING_SYNC +#define ILITEK_ILI9806E_VFP \ + LCD_VTIMMING_TOTAL_CYC - LCD_VACTIVE_LINE - LCD_VTIMMING_BACK_PORCH - LCD_VTIMMING_SYNC + +#endif /* ZEPHYR_DRIVERS_DISPLAY_ILITEK_ILI9806E_H_ */ diff --git a/drivers/display/display_ili9xxx.c b/drivers/display/display_ili9xxx.c index e28ba65d1849b..fbe4f06aa1a1e 100644 --- a/drivers/display/display_ili9xxx.c +++ b/drivers/display/display_ili9xxx.c @@ -139,7 +139,7 @@ static int ili9xxx_write(const struct device *dev, const uint16_t x, __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT((desc->pitch * data->bytes_per_pixel * desc->height) <= desc->buf_size, - "Input buffer to small"); + "Input buffer too small"); LOG_DBG("Writing %dx%d (w,h) @ %dx%d (x,y)", desc->width, desc->height, x, y); @@ -207,7 +207,7 @@ static int ili9xxx_read(const struct device *dev, const uint16_t x, __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT((desc->pitch * data->bytes_per_pixel * desc->height) <= desc->buf_size, - "Output buffer to small"); + "Output buffer too small"); LOG_DBG("Reading %dx%d (w,h) @ %dx%d (x,y)", desc->width, desc->height, x, y); @@ -517,7 +517,7 @@ static const struct ili9xxx_quirks ili9488_quirks = { #define ILI9XXX_INIT(n, t) \ ILI##t##_REGS_INIT(n); \ \ - static const struct ili9xxx_config ili9xxx_config_##n = { \ + static const struct ili9xxx_config ili9##t##_config_##n = { \ .quirks = &ili##t##_quirks, \ .mipi_dev = DEVICE_DT_GET(DT_PARENT(INST_DT_ILI9XXX(n, t))), \ .dbi_config = { \ @@ -535,15 +535,15 @@ static const struct ili9xxx_quirks ili9488_quirks = { .x_resolution = ILI##t##_X_RES, \ .y_resolution = ILI##t##_Y_RES, \ .inversion = DT_PROP(INST_DT_ILI9XXX(n, t), display_inversion),\ - .regs = &ili9xxx_regs_##n, \ + .regs = &ili##t##_regs_##n, \ .regs_init_fn = ili##t##_regs_init, \ }; \ \ - static struct ili9xxx_data ili9xxx_data_##n; \ + static struct ili9xxx_data ili9##t##_data_##n; \ \ DEVICE_DT_DEFINE(INST_DT_ILI9XXX(n, t), ili9xxx_init, \ - NULL, &ili9xxx_data_##n, \ - &ili9xxx_config_##n, POST_KERNEL, \ + NULL, &ili9##t##_data_##n, \ + &ili9##t##_config_##n, POST_KERNEL, \ CONFIG_DISPLAY_INIT_PRIORITY, &ili9xxx_api) #define DT_INST_FOREACH_ILI9XXX_STATUS_OKAY(t) \ diff --git a/drivers/display/display_led_strip_matrix.c b/drivers/display/display_led_strip_matrix.c index d4e5be57c4a0a..f47521864d108 100644 --- a/drivers/display/display_led_strip_matrix.c +++ b/drivers/display/display_led_strip_matrix.c @@ -88,7 +88,7 @@ static struct led_rgb *pixel_address(const struct led_strip_matrix_config *confi static inline int check_descriptor(const struct led_strip_matrix_config *config, const uint16_t x, const uint16_t y, const struct display_buffer_descriptor *desc) { - __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT(desc->pitch <= config->width, "Pitch in descriptor is larger than screen size"); __ASSERT(desc->height <= config->height, "Height in descriptor is larger than screen size"); __ASSERT(x + desc->pitch <= config->width, diff --git a/drivers/display/display_max7219.c b/drivers/display/display_max7219.c index 2f3553c1eb8b2..9430cf3c5d080 100644 --- a/drivers/display/display_max7219.c +++ b/drivers/display/display_max7219.c @@ -151,8 +151,8 @@ static int max7219_write(const struct device *dev, const uint16_t x, const uint1 /* * MAX7219 only supports PIXEL_FORMAT_MONO01. 1 bit stands for 1 pixel. */ - __ASSERT((desc->pitch * desc->height) <= (desc->buf_size * 8U), "Input buffer to small"); - __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); + __ASSERT((desc->pitch * desc->height) <= (desc->buf_size * 8U), "Input buffer too small"); + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT(desc->pitch <= max_width, "Pitch in descriptor is larger than screen size"); __ASSERT(desc->height <= max_height, "Height in descriptor is larger than screen size"); __ASSERT(x + desc->pitch <= max_width, diff --git a/drivers/display/display_nrf_led_matrix.c b/drivers/display/display_nrf_led_matrix.c index 64068ea488f65..79ae6652807a7 100644 --- a/drivers/display/display_nrf_led_matrix.c +++ b/drivers/display/display_nrf_led_matrix.c @@ -339,7 +339,7 @@ static void timer_irq_handler(void *arg) const struct display_drv_config *dev_config = dev->config; uint8_t iteration = dev_data->iteration; uint8_t pixel_idx; - uint8_t row_idx; + uint8_t row_idx = 0; /* The timer is automagically stopped and cleared by shortcuts * on the same event (COMPARE0) that generates this interrupt. diff --git a/drivers/display/display_renesas_ra.c b/drivers/display/display_renesas_ra.c new file mode 100644 index 0000000000000..ea5cfdaec81c2 --- /dev/null +++ b/drivers/display/display_renesas_ra.c @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_glcdc + +#include "display_renesas_ra.h" +#include "r_glcdc.h" +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(display_renesas_ra, CONFIG_DISPLAY_LOG_LEVEL); + +void glcdc_line_detect_isr(void); +struct display_ra_config { + const struct pinctrl_dev_config *pincfg; + const struct gpio_dt_spec backlight_gpio; + const struct device *clock_dev; + struct clock_control_ra_subsys_cfg clock_glcdc_subsys; + uint16_t height; + uint16_t width; + uint32_t display_frame_size; + enum display_pixel_format pixel_format; + void (*irq_configure)(void); +}; + +struct display_ra_data { + glcdc_instance_ctrl_t display_ctrl; + display_cfg_t display_fsp_cfg; + uint8_t *p_base; + uint32_t frame_buffer_len; + const uint8_t *pend_buf; + const uint8_t *front_buf; + uint8_t pixel_size; + uint8_t *frame_buffer; + struct k_sem sem; +}; + +static void renesas_ra_glcdc_isr(const struct device *dev) +{ + struct display_ra_data *data = dev->data; + + glcdc_line_detect_isr(); + if (data->front_buf != data->pend_buf) { + data->front_buf = data->pend_buf; + k_sem_give(&data->sem); + } +} + +static int ra_display_write(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf) +{ + struct display_ra_data *data = dev->data; + const struct display_ra_config *config = dev->config; + uint8_t *dst = NULL; + const uint8_t *src = buf; + const uint8_t *l_pend_buf = NULL; + uint16_t row; + int err; + + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); + __ASSERT((desc->pitch * BYTE_PER_PIXEL * desc->height) <= desc->buf_size, + "Input buffer too small"); + + if (x == 0 && y == 0 && desc->height == DISPLAY_VSIZE && desc->width == DISPLAY_HSIZE && + desc->pitch == DISPLAY_HSIZE) { + l_pend_buf = buf; + } else { + if (CONFIG_RENESAS_RA_GLCDC_FB_NUM == 0) { + LOG_ERR("Partial write requires internal frame buffer"); + return -ENOTSUP; + } + dst = data->frame_buffer; + + if (CONFIG_RENESAS_RA_GLCDC_FB_NUM == 2) { + if (data->front_buf == data->frame_buffer) { + dst = data->frame_buffer + data->frame_buffer_len; + } + + memcpy(dst, data->front_buf, data->frame_buffer_len); + } + + l_pend_buf = dst; + + /* dst = pointer to upper left pixel of the rectangle + * to be updated in frame buffer. + */ + dst += (x * data->pixel_size); + dst += (y * config->width * data->pixel_size); + + for (row = 0; row < desc->height; row++) { + (void)memcpy(dst, src, desc->width * data->pixel_size); + dst += (config->width * data->pixel_size); + src += (desc->pitch * data->pixel_size); + } + } + + if (data->front_buf == l_pend_buf) { + return 0; + } + + k_sem_reset(&data->sem); + + data->pend_buf = l_pend_buf; + + err = R_GLCDC_BufferChange(&data->display_ctrl, (uint8_t *)data->pend_buf, + DISPLAY_FRAME_LAYER_1); + if (err) { + LOG_ERR("GLCDC buffer change failed"); + return -EIO; + } + + k_sem_take(&data->sem, K_FOREVER); + + return 0; +} + +static int ra_display_read(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, void *buf) +{ + struct display_ra_data *data = dev->data; + const struct display_ra_config *config = dev->config; + uint8_t *dst = buf; + const uint8_t *src = data->front_buf; + uint16_t row; + + /* src = pointer to upper left pixel of the rectangle to be read from frame buffer */ + src += (x * data->pixel_size); + src += (y * config->width * data->pixel_size); + + for (row = 0; row < desc->height; row++) { + (void)memcpy(dst, src, desc->width * data->pixel_size); + src += (config->width * data->pixel_size); + dst += (desc->pitch * data->pixel_size); + } + + return 0; +} + +static int ra_display_blanking_on(const struct device *dev) +{ + const struct display_ra_config *config = dev->config; + int err; + + if (config->backlight_gpio.port != NULL) { + err = gpio_pin_set_dt(&config->backlight_gpio, 0); + if (err) { + LOG_ERR("Disable backlight failed! (%d)", err); + return err; + } + } else { + return -ENOTSUP; + } + + return 0; +} + +static int ra_display_blanking_off(const struct device *dev) +{ + const struct display_ra_config *config = dev->config; + int err; + + if (config->backlight_gpio.port != NULL) { + err = gpio_pin_set_dt(&config->backlight_gpio, 1); + if (err) { + LOG_ERR("Enable backlight failed! (%d)", err); + return err; + } + } else { + return -ENOTSUP; + } + + return 0; +} + +static void ra_display_get_capabilities(const struct device *dev, + struct display_capabilities *capabilities) +{ + const struct display_ra_config *config = dev->config; + + memset(capabilities, 0, sizeof(struct display_capabilities)); + capabilities->x_resolution = config->width; + capabilities->y_resolution = config->height; + capabilities->current_orientation = DISPLAY_ORIENTATION_NORMAL; + capabilities->supported_pixel_formats = + PIXEL_FORMAT_RGB_888 | PIXEL_FORMAT_ARGB_8888 | PIXEL_FORMAT_RGB_565; + capabilities->current_pixel_format = (config->pixel_format == PIXEL_FORMAT_RGB_888) + ? PIXEL_FORMAT_ARGB_8888 + : config->pixel_format; +} + +static int ra_display_set_pixel_format(const struct device *dev, + const enum display_pixel_format pixel_format) +{ + const struct display_ra_config *config = dev->config; + + if (pixel_format == config->pixel_format) { + return 0; + } + LOG_ERR("Pixel format changes must be set in dts at build time."); + return -ENOTSUP; +} + +static DEVICE_API(display, display_api) = { + .blanking_on = ra_display_blanking_on, + .blanking_off = ra_display_blanking_off, + .get_capabilities = ra_display_get_capabilities, + .set_pixel_format = ra_display_set_pixel_format, + .write = ra_display_write, + .read = ra_display_read, +}; + +static int display_init(const struct device *dev) +{ + const struct display_ra_config *config = dev->config; + struct display_ra_data *data = dev->data; + int err; + +#if BSP_FEATURE_BSP_HAS_GRAPHICS_DOMAIN + + R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); + FSP_HARDWARE_REGISTER_WAIT( + (R_SYSTEM->PDCTRGD & (R_SYSTEM_PDCTRGD_PDCSF_Msk | R_SYSTEM_PDCTRGD_PDPGSF_Msk)), + R_SYSTEM_PDCTRGD_PDPGSF_Msk); + R_SYSTEM->PDCTRGD = 0; + FSP_HARDWARE_REGISTER_WAIT( + (R_SYSTEM->PDCTRGD & (R_SYSTEM_PDCTRGD_PDCSF_Msk | R_SYSTEM_PDCTRGD_PDPGSF_Msk)), + 0); + R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); + +#endif + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + LOG_ERR("pin function initial failed"); + return err; + } + k_sem_init(&data->sem, 0, 1); + + err = clock_control_on(config->clock_dev, + (clock_control_subsys_t)&config->clock_glcdc_subsys); + if (err) { + LOG_ERR("Enable GLCDC clock failed!"); + return err; + } + + err = R_GLCDC_Open(&data->display_ctrl, &data->display_fsp_cfg); + if (err) { + LOG_ERR("GLCDC open failed"); + return -EIO; + } + + err = gpio_pin_configure_dt(&config->backlight_gpio, GPIO_OUTPUT_ACTIVE); + if (err) { + LOG_ERR("config backlight gpio failed"); + return err; + } + + err = R_GLCDC_Start(&data->display_ctrl); + if (err) { + LOG_ERR("GLCDC start failed"); + return -EIO; + } + + config->irq_configure(); + + return 0; +} + +#define IRQ_CONFIGURE_FUNC(id) \ + static void glcdc_renesas_ra_configure_func_##id(void) \ + { \ + R_ICU->IELSR[DT_INST_IRQ_BY_NAME(id, line, irq)] = ELC_EVENT_GLCDC_LINE_DETECT; \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(id, line, irq), \ + DT_INST_IRQ_BY_NAME(id, line, priority), renesas_ra_glcdc_isr, \ + DEVICE_DT_INST_GET(id), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(id, line, irq)); \ + } + +#define IRQ_CONFIGURE_DEFINE(id) .irq_configure = glcdc_renesas_ra_configure_func_##id + +#define RENESAS_RA_FRAME_BUFFER_LEN(id) \ + (BYTE_PER_PIXEL * DT_INST_PROP(id, height) * DT_INST_PROP(id, width)) + +#define RENESAS_RA_DEVICE_INIT(id) \ + PINCTRL_DT_INST_DEFINE(id); \ + IRQ_CONFIGURE_FUNC(id) \ + Z_GENERIC_SECTION(".sdram") \ + static uint8_t __aligned(64) \ + fb_background##id[CONFIG_RENESAS_RA_GLCDC_FB_NUM * RENESAS_RA_FRAME_BUFFER_LEN(id)]; \ + static const glcdc_extended_cfg_t display_extend_cfg##id = { \ + .tcon_hsync = GLCDC_TCON_PIN_1, \ + .tcon_vsync = GLCDC_TCON_PIN_0, \ + .tcon_de = GLCDC_TCON_PIN_2, \ + .correction_proc_order = GLCDC_CORRECTION_PROC_ORDER_BRIGHTNESS_CONTRAST2GAMMA, \ + .clksrc = GLCDC_CLK_SRC_INTERNAL, \ + .clock_div_ratio = GLCDC_PANEL_CLK_DIVISOR_8, \ + .dithering_mode = GLCDC_DITHERING_MODE_TRUNCATE, \ + .dithering_pattern_A = GLCDC_DITHERING_PATTERN_11, \ + .dithering_pattern_B = GLCDC_DITHERING_PATTERN_11, \ + .dithering_pattern_C = GLCDC_DITHERING_PATTERN_11, \ + .dithering_pattern_D = GLCDC_DITHERING_PATTERN_11, \ + .phy_layer = NULL, \ + }; \ + static struct display_ra_data ra_data##id = { \ + .frame_buffer = fb_background##id, \ + .frame_buffer_len = RENESAS_RA_FRAME_BUFFER_LEN(id), \ + .front_buf = fb_background##id, \ + .pend_buf = fb_background##id, \ + .pixel_size = BYTE_PER_PIXEL, \ + .p_base = (uint8_t *)&fb_background##id, \ + .display_fsp_cfg = { \ + .input[0] = {.p_base = (uint32_t *)&fb_background##id, \ + .hsize = DISPLAY_HSIZE, \ + .vsize = DISPLAY_VSIZE, \ + .hstride = DISPLAY_BUFFER_STRIDE_PIXELS_INPUT0, \ + .format = \ + (INPUT_FORMAT_PIXEL == PANEL_PIXEL_FORMAT_RGB_565) \ + ? DISPLAY_IN_FORMAT_16BITS_RGB565 \ + : (INPUT_FORMAT_PIXEL == PANEL_PIXEL_FORMAT_RGB_888) \ + ? DISPLAY_IN_FORMAT_32BITS_RGB888 \ + : DISPLAY_IN_FORMAT_32BITS_ARGB8888, \ + .line_descending_enable = false, \ + .lines_repeat_enable = false, \ + .lines_repeat_times = 0}, \ + .input[1] = {.p_base = NULL, \ + .hsize = DISPLAY_HSIZE, \ + .vsize = DISPLAY_VSIZE, \ + .hstride = DISPLAY_BUFFER_STRIDE_PIXELS_INPUT1, \ + .format = DISPLAY_IN_FORMAT_16BITS_RGB565, \ + .line_descending_enable = false, \ + .lines_repeat_enable = false, \ + .lines_repeat_times = 0}, \ + .layer[0] = {.coordinate = {.x = 0, .y = 0}, \ + .bg_color = {.byte = {.a = LAYER_ALPHA, \ + .r = LAYER_RED, \ + .g = LAYER_GREEN, \ + .b = LAYER_BLUE}}, \ + .fade_control = DISPLAY_FADE_CONTROL_NONE, \ + .fade_speed = 0}, \ + .layer[1] = {.coordinate = {.x = 0, .y = 0}, \ + .bg_color = {.byte = {.a = LAYER_ALPHA, \ + .r = LAYER_RED, \ + .g = LAYER_GREEN, \ + .b = LAYER_BLUE}}, \ + .fade_control = DISPLAY_FADE_CONTROL_NONE, \ + .fade_speed = 0}, \ + .output = {.htiming = {.total_cyc = \ + DT_INST_PROP(id, width) + \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + hback_porch) + \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + hfront_porch) + \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + hsync_len), \ + .display_cyc = DT_INST_PROP(id, width), \ + .back_porch = \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + hback_porch), \ + .sync_width = \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + hsync_len), \ + .sync_polarity = \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + hsync_active)}, \ + .vtiming = {.total_cyc = \ + DT_INST_PROP(id, height) + \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + vback_porch) + \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + vfront_porch) + \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + vsync_len), \ + .display_cyc = DT_INST_PROP(id, height), \ + .back_porch = \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + vback_porch), \ + .sync_width = \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + vsync_len), \ + .sync_polarity = \ + DT_PROP(DT_INST_CHILD(id, display_timings), \ + vsync_active)}, \ + .format = (OUTPUT_FORMAT_PIXEL == PANEL_PIXEL_FORMAT_RGB_565) \ + ? DISPLAY_OUT_FORMAT_16BITS_RGB565 \ + : DISPLAY_OUT_FORMAT_24BITS_RGB888, \ + .endian = DISPLAY_ENDIAN_LITTLE, \ + .color_order = DISPLAY_COLOR_ORDER_RGB, \ + .data_enable_polarity = DISPLAY_SIGNAL_POLARITY_HIACTIVE, \ + .sync_edge = DISPLAY_SIGNAL_SYNC_EDGE_FALLING, \ + .bg_color = {.byte = {.a = OUTPUT_ALPHA, \ + .r = OUTPUT_RED, \ + .g = OUTPUT_GREEN, \ + .b = OUTPUT_BLUE}}, \ + .brightness = {.enable = false, \ + .r = OUTPUT_RED, \ + .g = OUTPUT_GREEN, \ + .b = OUTPUT_BLUE}, \ + .contrast = {.enable = false, \ + .r = OUTPUT_RED, \ + .g = OUTPUT_GREEN, \ + .b = OUTPUT_BLUE}, \ + .dithering_on = false}, \ + .p_callback = NULL, \ + .p_context = NULL, \ + .p_extend = (void *)(&display_extend_cfg##id), \ + .line_detect_ipl = BSP_IRQ_DISABLED, \ + .underflow_1_ipl = BSP_IRQ_DISABLED, \ + .underflow_2_ipl = BSP_IRQ_DISABLED}}; \ + static struct display_ra_config ra_config##id = { \ + IRQ_CONFIGURE_DEFINE(id), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \ + .backlight_gpio = GPIO_DT_SPEC_INST_GET(id, backlight_gpios), \ + .height = DT_INST_PROP(id, height), \ + .width = DT_INST_PROP(id, width), \ + .pixel_format = DT_INST_PROP(id, input_pixel_format), \ + .display_frame_size = \ + (DT_INST_PROP(id, width)) * (DT_INST_PROP(id, height)) * BYTE_PER_PIXEL, \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \ + .clock_glcdc_subsys = {.mstp = (uint32_t)DT_INST_CLOCKS_CELL_BY_IDX(id, 0, mstp), \ + .stop_bit = DT_INST_CLOCKS_CELL_BY_IDX(id, 0, stop_bit)}, \ + }; \ + DEVICE_DT_INST_DEFINE(id, &display_init, NULL, &ra_data##id, &ra_config##id, POST_KERNEL, \ + CONFIG_DISPLAY_INIT_PRIORITY, &display_api); + +DT_INST_FOREACH_STATUS_OKAY(RENESAS_RA_DEVICE_INIT) diff --git a/drivers/display/display_renesas_ra.h b/drivers/display/display_renesas_ra.h new file mode 100644 index 0000000000000..e3cddbcc3b7d1 --- /dev/null +++ b/drivers/display/display_renesas_ra.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_DISPLAY_RENESAS_RA_H_ +#define ZEPHYR_DRIVERS_DISPLAY_RENESAS_RA_H_ + +#include + +#define INPUT_FORMAT_PIXEL DT_INST_PROP(0, input_pixel_format) +#define OUTPUT_FORMAT_PIXEL DT_INST_PROP(0, output_pixel_format) + +#if (INPUT_FORMAT_PIXEL == PANEL_PIXEL_FORMAT_RGB_565) +#define BYTE_PER_PIXEL (2) +#define DISPLAY_BITS_PER_PIXEL_INPUT0 (16) +#elif (INPUT_FORMAT_PIXEL == PANEL_PIXEL_FORMAT_RGB_888) +#define BYTE_PER_PIXEL (4) +#define DISPLAY_BITS_PER_PIXEL_INPUT0 (32) +#elif (INPUT_FORMAT_PIXEL == PANEL_PIXEL_FORMAT_ARGB_8888) +#define BYTE_PER_PIXEL (4) +#define DISPLAY_BITS_PER_PIXEL_INPUT0 (32) +#endif + +#define DISPLAY_BITS_PER_PIXEL_INPUT1 (16) +#define DISPLAY_HSIZE DT_INST_PROP(0, width) +#define DISPLAY_VSIZE DT_INST_PROP(0, height) +#define DISPLAY_BUFFER_STRIDE_BYTES_INPUT0 \ + (((DISPLAY_HSIZE * DISPLAY_BITS_PER_PIXEL_INPUT0 + 0x1FF) >> 9) << 6) +#define DISPLAY_BUFFER_STRIDE_PIXELS_INPUT0 \ + ((DISPLAY_BUFFER_STRIDE_BYTES_INPUT0 * 8) / DISPLAY_BITS_PER_PIXEL_INPUT0) +#define DISPLAY_BUFFER_STRIDE_BYTES_INPUT1 \ + (((DISPLAY_HSIZE * DISPLAY_BITS_PER_PIXEL_INPUT1 + 0x1FF) >> 9) << 6) +#define DISPLAY_BUFFER_STRIDE_PIXELS_INPUT1 \ + ((DISPLAY_BUFFER_STRIDE_BYTES_INPUT1 * 8) / DISPLAY_BITS_PER_PIXEL_INPUT1) + +#define LAYER_GREEN (255) +#define LAYER_RED (255) +#define LAYER_BLUE (255) +#define LAYER_ALPHA (255) +#define OUTPUT_GREEN (0) +#define OUTPUT_RED (0) +#define OUTPUT_BLUE (0) +#define OUTPUT_ALPHA (255) +#define GLCDC_BRIGHTNESS_MAX (1023U) +#define BRIGHTNESS_MAX (255U) +#define GLCDC_CONTRAST_MAX (255U) + +#endif /* ZEPHYR_DRIVERS_DISPLAY_RENESAS_RA_H_ */ diff --git a/drivers/display/display_rm67162.c b/drivers/display/display_rm67162.c index a5bd43af7e65e..c4c9482dec850 100644 --- a/drivers/display/display_rm67162.c +++ b/drivers/display/display_rm67162.c @@ -334,7 +334,11 @@ static int rm67162_init(const struct device *dev) /* Init and install GPIO callback */ gpio_init_callback(&data->te_gpio_cb, rm67162_te_isr_handler, BIT(config->te_gpio.pin)); - gpio_add_callback(config->te_gpio.port, &data->te_gpio_cb); + ret = gpio_add_callback(config->te_gpio.port, &data->te_gpio_cb); + if (ret < 0) { + LOG_ERR("Could not add TE gpio callback"); + return ret; + } /* Setup te pin semaphore */ k_sem_init(&data->te_sem, 0, 1); @@ -350,7 +354,7 @@ static int rm67162_write_fb(const struct device *dev, bool first_write, const uint8_t *src, uint32_t len) { const struct rm67162_config *config = dev->config; - uint32_t wlen = 0; + ssize_t wlen; struct mipi_dsi_msg msg = {0}; /* Note- we need to set custom flags on the DCS message, @@ -368,7 +372,7 @@ static int rm67162_write_fb(const struct device *dev, bool first_write, msg.tx_buf = src; wlen = mipi_dsi_transfer(config->mipi_dsi, config->channel, &msg); if (wlen < 0) { - return wlen; + return (int)wlen; } /* Advance source pointer and decrement remaining */ src += wlen; @@ -522,21 +526,18 @@ static int rm67162_set_pixel_format(const struct device *dev, switch (pixel_format) { case PIXEL_FORMAT_RGB_565: data->pixel_format = MIPI_DSI_PIXFMT_RGB565; - return 0; + param = MIPI_DCS_PIXEL_FORMAT_16BIT; + data->bytes_per_pixel = 2; + break; case PIXEL_FORMAT_RGB_888: data->pixel_format = MIPI_DSI_PIXFMT_RGB888; - return 0; + param = MIPI_DCS_PIXEL_FORMAT_24BIT; + data->bytes_per_pixel = 3; + break; default: /* Other display formats not implemented */ return -ENOTSUP; } - if (data->pixel_format == MIPI_DSI_PIXFMT_RGB888) { - param = MIPI_DCS_PIXEL_FORMAT_24BIT; - data->bytes_per_pixel = 3; - } else if (data->pixel_format == MIPI_DSI_PIXFMT_RGB565) { - param = MIPI_DCS_PIXEL_FORMAT_16BIT; - data->bytes_per_pixel = 2; - } return mipi_dsi_dcs_write(config->mipi_dsi, config->channel, MIPI_DCS_SET_PIXEL_FORMAT, ¶m, 1); } diff --git a/drivers/display/display_sdl.c b/drivers/display/display_sdl.c index d3ac14aa7b750..bbae94c75e068 100644 --- a/drivers/display/display_sdl.c +++ b/drivers/display/display_sdl.c @@ -100,7 +100,7 @@ static void sdl_display_write_argb8888(void *disp_buf, const struct display_buffer_descriptor *desc, const void *buf) { __ASSERT((desc->pitch * 4U * desc->height) <= desc->buf_size, - "Input buffer to small"); + "Input buffer too small"); memcpy(disp_buf, buf, desc->pitch * 4U * desc->height); } @@ -114,7 +114,7 @@ static void sdl_display_write_rgb888(uint8_t *disp_buf, const uint8_t *byte_ptr; __ASSERT((desc->pitch * 3U * desc->height) <= desc->buf_size, - "Input buffer to small"); + "Input buffer too small"); for (h_idx = 0U; h_idx < desc->height; ++h_idx) { for (w_idx = 0U; w_idx < desc->width; ++w_idx) { @@ -139,7 +139,7 @@ static void sdl_display_write_rgb565(uint8_t *disp_buf, uint16_t rgb565; __ASSERT((desc->pitch * 2U * desc->height) <= desc->buf_size, - "Input buffer to small"); + "Input buffer too small"); for (h_idx = 0U; h_idx < desc->height; ++h_idx) { for (w_idx = 0U; w_idx < desc->width; ++w_idx) { @@ -164,7 +164,7 @@ static void sdl_display_write_bgr565(uint8_t *disp_buf, const uint16_t *pix_ptr; __ASSERT((desc->pitch * 2U * desc->height) <= desc->buf_size, - "Input buffer to small"); + "Input buffer too small"); for (h_idx = 0U; h_idx < desc->height; ++h_idx) { for (w_idx = 0U; w_idx < desc->width; ++w_idx) { @@ -192,7 +192,7 @@ static void sdl_display_write_mono(uint8_t *disp_buf, uint8_t *disp_buf_start; __ASSERT((desc->pitch * desc->height) <= (desc->buf_size * 8U), - "Input buffer to small"); + "Input buffer too small"); __ASSERT((desc->height % 8) == 0U, "Input buffer height not aligned per 8 pixels"); @@ -234,7 +234,7 @@ static int sdl_display_write(const struct device *dev, const uint16_t x, LOG_DBG("Writing %dx%d (w,h) bitmap @ %dx%d (x,y)", desc->width, desc->height, x, y); - __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT(desc->pitch <= config->width, "Pitch in descriptor is larger than screen size"); __ASSERT(desc->height <= config->height, diff --git a/drivers/display/display_st7789v.c b/drivers/display/display_st7789v.c index cc329e0c13461..084d48a3e549c 100644 --- a/drivers/display/display_st7789v.c +++ b/drivers/display/display_st7789v.c @@ -45,6 +45,7 @@ struct st7789v_config { uint8_t rgb_param[3]; uint16_t height; uint16_t width; + uint8_t ready_time_ms; }; struct st7789v_data { @@ -67,22 +68,29 @@ static void st7789v_set_lcd_margins(const struct device *dev, data->y_offset = y_offset; } -static void st7789v_transmit(const struct device *dev, uint8_t cmd, - uint8_t *tx_data, size_t tx_count) +static int st7789v_transmit(const struct device *dev, uint8_t cmd, + uint8_t *tx_data, size_t tx_count) { const struct st7789v_config *config = dev->config; - mipi_dbi_command_write(config->mipi_dbi, &config->dbi_config, cmd, - tx_data, tx_count); + return mipi_dbi_command_write(config->mipi_dbi, &config->dbi_config, + cmd, tx_data, tx_count); } -static void st7789v_exit_sleep(const struct device *dev) +static int st7789v_exit_sleep(const struct device *dev) { - st7789v_transmit(dev, ST7789V_CMD_SLEEP_OUT, NULL, 0); + int ret; + + ret = st7789v_transmit(dev, ST7789V_CMD_SLEEP_OUT, NULL, 0); + if (ret < 0) { + return ret; + } + k_sleep(K_MSEC(120)); + return ret; } -static void st7789v_reset_display(const struct device *dev) +static int st7789v_reset_display(const struct device *dev) { const struct st7789v_config *config = dev->config; int ret; @@ -93,26 +101,29 @@ static void st7789v_reset_display(const struct device *dev) ret = mipi_dbi_reset(config->mipi_dbi, 6); if (ret == -ENOTSUP) { /* Send software reset command */ - st7789v_transmit(dev, ST7789V_CMD_SW_RESET, NULL, 0); + ret = st7789v_transmit(dev, ST7789V_CMD_SW_RESET, NULL, 0); + if (ret < 0) { + return ret; + } k_sleep(K_MSEC(5)); } else { k_sleep(K_MSEC(20)); } + + return ret; } static int st7789v_blanking_on(const struct device *dev) { - st7789v_transmit(dev, ST7789V_CMD_DISP_OFF, NULL, 0); - return 0; + return st7789v_transmit(dev, ST7789V_CMD_DISP_OFF, NULL, 0); } static int st7789v_blanking_off(const struct device *dev) { - st7789v_transmit(dev, ST7789V_CMD_DISP_ON, NULL, 0); - return 0; + return st7789v_transmit(dev, ST7789V_CMD_DISP_ON, NULL, 0); } -static void st7789v_set_mem_area(const struct device *dev, const uint16_t x, +static int st7789v_set_mem_area(const struct device *dev, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h) { struct st7789v_data *data = dev->data; @@ -121,13 +132,18 @@ static void st7789v_set_mem_area(const struct device *dev, const uint16_t x, uint16_t ram_x = x + data->x_offset; uint16_t ram_y = y + data->y_offset; + int ret; + spi_data[0] = sys_cpu_to_be16(ram_x); spi_data[1] = sys_cpu_to_be16(ram_x + w - 1); - st7789v_transmit(dev, ST7789V_CMD_CASET, (uint8_t *)&spi_data[0], 4); + ret = st7789v_transmit(dev, ST7789V_CMD_CASET, (uint8_t *)&spi_data[0], 4); + if (ret < 0) { + return ret; + } spi_data[0] = sys_cpu_to_be16(ram_y); spi_data[1] = sys_cpu_to_be16(ram_y + h - 1); - st7789v_transmit(dev, ST7789V_CMD_RASET, (uint8_t *)&spi_data[0], 4); + return st7789v_transmit(dev, ST7789V_CMD_RASET, (uint8_t *)&spi_data[0], 4); } static int st7789v_write(const struct device *dev, @@ -142,14 +158,18 @@ static int st7789v_write(const struct device *dev, uint16_t nbr_of_writes; uint16_t write_h; enum display_pixel_format pixfmt; + int ret; - __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT((desc->pitch * ST7789V_PIXEL_SIZE * desc->height) <= desc->buf_size, - "Input buffer to small"); + "Input buffer too small"); LOG_DBG("Writing %dx%d (w,h) @ %dx%d (x,y)", desc->width, desc->height, x, y); - st7789v_set_mem_area(dev, x, y, desc->width, desc->height); + ret = st7789v_set_mem_area(dev, x, y, desc->width, desc->height); + if (ret < 0) { + return ret; + } if (desc->pitch > desc->width) { write_h = 1U; @@ -175,16 +195,22 @@ static int st7789v_write(const struct device *dev, mipi_desc.pitch = desc->width; /* Send RAMWR command */ - st7789v_transmit(dev, ST7789V_CMD_RAMWR, NULL, 0); + ret = st7789v_transmit(dev, ST7789V_CMD_RAMWR, NULL, 0); + if (ret < 0) { + return ret; + } for (uint16_t write_cnt = 0U; write_cnt < nbr_of_writes; ++write_cnt) { - mipi_dbi_write_display(config->mipi_dbi, &config->dbi_config, - write_data_start, &mipi_desc, pixfmt); + ret = mipi_dbi_write_display(config->mipi_dbi, &config->dbi_config, + write_data_start, &mipi_desc, pixfmt); + if (ret < 0) { + return ret; + } write_data_start += (desc->pitch * ST7789V_PIXEL_SIZE); } - return 0; + return ret; } static void st7789v_get_capabilities(const struct device *dev, @@ -235,121 +261,196 @@ static int st7789v_set_orientation(const struct device *dev, return -ENOTSUP; } -static void st7789v_lcd_init(const struct device *dev) +static int st7789v_lcd_init(const struct device *dev) { struct st7789v_data *data = dev->data; const struct st7789v_config *config = dev->config; uint8_t tmp; + int ret; st7789v_set_lcd_margins(dev, data->x_offset, data->y_offset); - st7789v_transmit(dev, ST7789V_CMD_CMD2EN, - (uint8_t *)config->cmd2en_param, - sizeof(config->cmd2en_param)); + ret = st7789v_transmit(dev, ST7789V_CMD_CMD2EN, + (uint8_t *)config->cmd2en_param, + sizeof(config->cmd2en_param)); + if (ret < 0) { + return ret; + } - st7789v_transmit(dev, ST7789V_CMD_PORCTRL, - (uint8_t *)config->porch_param, - sizeof(config->porch_param)); + ret = st7789v_transmit(dev, ST7789V_CMD_PORCTRL, + (uint8_t *)config->porch_param, + sizeof(config->porch_param)); + if (ret < 0) { + return ret; + } /* Digital Gamma Enable, default disabled */ tmp = 0x00; - st7789v_transmit(dev, ST7789V_CMD_DGMEN, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_DGMEN, &tmp, 1); + if (ret < 0) { + return ret; + } /* Frame Rate Control in Normal Mode, default value */ tmp = 0x0f; - st7789v_transmit(dev, ST7789V_CMD_FRCTRL2, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_FRCTRL2, &tmp, 1); + if (ret < 0) { + return ret; + } tmp = config->gctrl; - st7789v_transmit(dev, ST7789V_CMD_GCTRL, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_GCTRL, &tmp, 1); + if (ret < 0) { + return ret; + } tmp = config->vcom; - st7789v_transmit(dev, ST7789V_CMD_VCOMS, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_VCOMS, &tmp, 1); + if (ret < 0) { + return ret; + } if (config->vdv_vrh_enable) { tmp = 0x01; - st7789v_transmit(dev, ST7789V_CMD_VDVVRHEN, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_VDVVRHEN, &tmp, 1); + if (ret < 0) { + return ret; + } tmp = config->vrh_value; - st7789v_transmit(dev, ST7789V_CMD_VRH, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_VRH, &tmp, 1); + if (ret < 0) { + return ret; + } tmp = config->vdv_value; - st7789v_transmit(dev, ST7789V_CMD_VDS, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_VDS, &tmp, 1); + if (ret < 0) { + return ret; + } } - st7789v_transmit(dev, ST7789V_CMD_PWCTRL1, - (uint8_t *)config->pwctrl1_param, - sizeof(config->pwctrl1_param)); + ret = st7789v_transmit(dev, ST7789V_CMD_PWCTRL1, + (uint8_t *)config->pwctrl1_param, + sizeof(config->pwctrl1_param)); + if (ret < 0) { + return ret; + } /* Memory Data Access Control */ tmp = config->mdac; - st7789v_transmit(dev, ST7789V_CMD_MADCTL, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_MADCTL, &tmp, 1); + if (ret < 0) { + return ret; + } /* Interface Pixel Format */ tmp = config->colmod; - st7789v_transmit(dev, ST7789V_CMD_COLMOD, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_COLMOD, &tmp, 1); + if (ret < 0) { + return ret; + } tmp = config->lcm; - st7789v_transmit(dev, ST7789V_CMD_LCMCTRL, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_LCMCTRL, &tmp, 1); + if (ret < 0) { + return ret; + } tmp = config->gamma; - st7789v_transmit(dev, ST7789V_CMD_GAMSET, &tmp, 1); + ret = st7789v_transmit(dev, ST7789V_CMD_GAMSET, &tmp, 1); + if (ret < 0) { + return ret; + } if (config->inversion_on) { - st7789v_transmit(dev, ST7789V_CMD_INV_ON, NULL, 0); + ret = st7789v_transmit(dev, ST7789V_CMD_INV_ON, NULL, 0); } else { - st7789v_transmit(dev, ST7789V_CMD_INV_OFF, NULL, 0); + ret = st7789v_transmit(dev, ST7789V_CMD_INV_OFF, NULL, 0); + } + if (ret < 0) { + return ret; } - st7789v_transmit(dev, ST7789V_CMD_PVGAMCTRL, - (uint8_t *)config->pvgam_param, - sizeof(config->pvgam_param)); + ret = st7789v_transmit(dev, ST7789V_CMD_PVGAMCTRL, + (uint8_t *)config->pvgam_param, + sizeof(config->pvgam_param)); + if (ret < 0) { + return ret; + } - st7789v_transmit(dev, ST7789V_CMD_NVGAMCTRL, - (uint8_t *)config->nvgam_param, - sizeof(config->nvgam_param)); + ret = st7789v_transmit(dev, ST7789V_CMD_NVGAMCTRL, + (uint8_t *)config->nvgam_param, + sizeof(config->nvgam_param)); + if (ret < 0) { + return ret; + } - st7789v_transmit(dev, ST7789V_CMD_RAMCTRL, - (uint8_t *)config->ram_param, - sizeof(config->ram_param)); + ret = st7789v_transmit(dev, ST7789V_CMD_RAMCTRL, + (uint8_t *)config->ram_param, + sizeof(config->ram_param)); + if (ret < 0) { + return ret; + } - st7789v_transmit(dev, ST7789V_CMD_RGBCTRL, - (uint8_t *)config->rgb_param, - sizeof(config->rgb_param)); + ret = st7789v_transmit(dev, ST7789V_CMD_RGBCTRL, + (uint8_t *)config->rgb_param, + sizeof(config->rgb_param)); + return ret; } static int st7789v_init(const struct device *dev) { const struct st7789v_config *config = dev->config; + int ret; if (!device_is_ready(config->mipi_dbi)) { LOG_ERR("MIPI DBI device not ready"); return -ENODEV; } - st7789v_reset_display(dev); + k_sleep(K_TIMEOUT_ABS_MS(config->ready_time_ms)); - st7789v_blanking_on(dev); + ret = st7789v_reset_display(dev); + if (ret < 0) { + LOG_ERR("Failed to reset display (%d)", ret); + return ret; + } - st7789v_lcd_init(dev); + ret = st7789v_blanking_on(dev); + if (ret < 0) { + LOG_ERR("Failed to turn blanking on (%d)", ret); + return ret; + } - st7789v_exit_sleep(dev); + ret = st7789v_lcd_init(dev); + if (ret < 0) { + LOG_ERR("Failed to init display (%d)", ret); + return ret; + } - return 0; + ret = st7789v_exit_sleep(dev); + if (ret < 0) { + LOG_ERR("Failed to exit the sleep mode (%d)", ret); + return ret; + } + + return ret; } #ifdef CONFIG_PM_DEVICE static int st7789v_pm_action(const struct device *dev, enum pm_device_action action) { - int ret = 0; + int ret; switch (action) { case PM_DEVICE_ACTION_RESUME: - st7789v_exit_sleep(dev); + ret = st7789v_exit_sleep(dev); break; case PM_DEVICE_ACTION_SUSPEND: - st7789v_transmit(dev, ST7789V_CMD_SLEEP_IN, NULL, 0); + ret = st7789v_transmit(dev, ST7789V_CMD_SLEEP_IN, NULL, 0); break; default: ret = -ENOTSUP; @@ -398,6 +499,7 @@ static DEVICE_API(display, st7789v_api) = { .rgb_param = DT_INST_PROP(inst, rgb_param), \ .width = DT_INST_PROP(inst, width), \ .height = DT_INST_PROP(inst, height), \ + .ready_time_ms = DT_INST_PROP(inst, ready_time_ms), \ }; \ \ static struct st7789v_data st7789v_data_ ## inst = { \ diff --git a/drivers/display/display_st7796s.c b/drivers/display/display_st7796s.c index 32411d7a54de5..b10a894dccbdc 100644 --- a/drivers/display/display_st7796s.c +++ b/drivers/display/display_st7796s.c @@ -46,6 +46,8 @@ struct st7796s_config { uint8_t pgc[14]; /* Positive gamma control */ uint8_t ngc[14]; /* Negative gamma control */ uint8_t madctl; /* Memory data access control */ + uint8_t te_mode; /* Tearing enable mode */ + uint32_t te_delay; /* Tearing enable delay */ bool rgb_is_inverted; }; @@ -155,7 +157,7 @@ static int st7796s_write(const struct device *dev, { const struct st7796s_config *config = dev->config; int ret; - struct display_buffer_descriptor mipi_desc; + struct display_buffer_descriptor mipi_desc = {0}; enum display_pixel_format pixfmt; ret = st7796s_set_cursor(dev, x, y, desc->width, desc->height); @@ -164,6 +166,7 @@ static int st7796s_write(const struct device *dev, } mipi_desc.buf_size = desc->width * desc->height * ST7796S_PIXEL_SIZE; + mipi_desc.frame_incomplete = desc->frame_incomplete; ret = mipi_dbi_command_write(config->mipi_dbi, &config->dbi_config, ST7796S_CMD_RAMWR, @@ -282,6 +285,18 @@ static int st7796s_lcd_config(const struct device *dev) return ret; } + /* Attempt to enable TE signal */ + ret = mipi_dbi_configure_te(config->mipi_dbi, config->te_mode, + config->te_delay); + if (ret == 0) { + /* TE was enabled- send TEON, and enable vblank only */ + param = 0x0; /* Set TMEM bit to 0 */ + ret = st7796s_send_cmd(dev, ST7796S_CMD_TEON, ¶m, sizeof(param)); + if (ret < 0) { + return ret; + } + } + /* Lock display configuration */ param = ST7796S_LOCK_1; ret = st7796s_send_cmd(dev, ST7796S_CMD_CSCON, ¶m, sizeof(param)); @@ -385,6 +400,8 @@ static DEVICE_API(display, st7796s_api) = { .ngc = DT_INST_PROP(n, ngc), \ .madctl = DT_INST_PROP(n, madctl), \ .rgb_is_inverted = DT_INST_PROP(n, rgb_is_inverted), \ + .te_mode = MIPI_DBI_TE_MODE_DT_INST(n, te_mode), \ + .te_delay = DT_INST_PROP(n, te_delay), \ }; \ \ DEVICE_DT_INST_DEFINE(n, st7796s_init, \ diff --git a/drivers/display/display_st7796s.h b/drivers/display/display_st7796s.h index 7b0be000107a2..43e4e2e4b9c61 100644 --- a/drivers/display/display_st7796s.h +++ b/drivers/display/display_st7796s.h @@ -16,6 +16,7 @@ #define ST7796S_CMD_RAMWR 0x2C /* Memory write */ #define ST7796S_CMD_DISPOFF 0x28 /* Display off */ #define ST7796S_CMD_DISPON 0x29 /* Display on */ +#define ST7796S_CMD_TEON 0x35 /* Tearing effect on */ #define ST7796S_CMD_MADCTL 0x36 /* Memory data access control */ #define ST7796S_CMD_COLMOD 0x3A /* Interface pixel format */ #define ST7796S_CMD_FRMCTR1 0xB1 /* Frame rate control 1 (normal mode) */ diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 67acc839c6d24..8fe6a92931352 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -23,6 +23,8 @@ LOG_MODULE_REGISTER(ssd1306, CONFIG_DISPLAY_LOG_LEVEL); #define SSD1306_PANEL_VCOM_DESEL_LEVEL 0x20 #define SSD1306_PANEL_PUMP_VOLTAGE SSD1306_SET_PUMP_VOLTAGE_90 +#define SSD1306_PANEL_VCOM_DESEL_LEVEL_SSD1309 0x34 + #ifndef SSD1306_ADDRESSING_MODE #define SSD1306_ADDRESSING_MODE (SSD1306_SET_MEM_ADDRESSING_HORIZONTAL) #endif @@ -41,6 +43,7 @@ struct ssd1306_config { union ssd1306_bus bus; struct gpio_dt_spec data_cmd; struct gpio_dt_spec reset; + struct gpio_dt_spec supply; ssd1306_bus_ready_fn bus_ready; ssd1306_write_bus_fn write_bus; ssd1306_bus_name_fn bus_name; @@ -55,6 +58,7 @@ struct ssd1306_config { bool com_invdir; bool com_sequential; bool color_inversion; + bool ssd1309_compatible; bool sh1106_compatible; int ready_time_ms; bool use_internal_iref; @@ -65,6 +69,7 @@ struct ssd1306_data { }; #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309fb, i2c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sinowealth_sh1106, i2c)) static bool ssd1306_bus_ready_i2c(const struct device *dev) { @@ -92,6 +97,7 @@ static const char *ssd1306_bus_name_i2c(const struct device *dev) #endif #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, spi) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309fb, spi) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sinowealth_sh1106, spi)) static bool ssd1306_bus_ready_spi(const struct device *dev) { @@ -167,7 +173,8 @@ static inline int ssd1306_set_timing_setting(const struct device *dev) SSD1306_SET_CHARGE_PERIOD, config->prechargep, SSD1306_SET_VCOM_DESELECT_LEVEL, - SSD1306_PANEL_VCOM_DESEL_LEVEL}; + config->ssd1309_compatible ? SSD1306_PANEL_VCOM_DESEL_LEVEL_SSD1309 : + SSD1306_PANEL_VCOM_DESEL_LEVEL}; return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } @@ -220,19 +227,33 @@ static inline int ssd1306_set_iref_mode(const struct device *dev) static int ssd1306_resume(const struct device *dev) { + const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { SSD1306_DISPLAY_ON, }; + /* Turn on supply if pin connected */ + if (config->supply.port) { + gpio_pin_set_dt(&config->supply, 1); + k_sleep(K_MSEC(SSD1306_SUPPLY_DELAY)); + } + return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } static int ssd1306_suspend(const struct device *dev) { + const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { SSD1306_DISPLAY_OFF, }; + /* Turn off supply if pin connected */ + if (config->supply.port) { + gpio_pin_set_dt(&config->supply, 0); + k_sleep(K_MSEC(SSD1306_SUPPLY_DELAY)); + } + return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } @@ -306,7 +327,7 @@ static int ssd1306_write(const struct device *dev, const uint16_t x, const uint1 size_t buf_len; if (desc->pitch < desc->width) { - LOG_ERR("Pitch is smaller then width"); + LOG_ERR("Pitch is smaller than width"); return -1; } @@ -402,6 +423,11 @@ static int ssd1306_init_device(const struct device *dev) }; data->pf = config->color_inversion ? PIXEL_FORMAT_MONO10 : PIXEL_FORMAT_MONO01; + /* Turn on supply if pin connected */ + if (config->supply.port) { + gpio_pin_set_dt(&config->supply, 1); + k_sleep(K_MSEC(SSD1306_SUPPLY_DELAY)); + } /* Reset if pin connected */ if (config->reset.port) { @@ -428,12 +454,14 @@ static int ssd1306_init_device(const struct device *dev) return -EIO; } - if (ssd1306_set_charge_pump(dev)) { - return -EIO; - } + if (!config->ssd1309_compatible) { + if (ssd1306_set_charge_pump(dev)) { + return -EIO; + } - if (ssd1306_set_iref_mode(dev)) { - return -EIO; + if (ssd1306_set_iref_mode(dev)) { + return -EIO; + } } if (ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true)) { @@ -452,6 +480,7 @@ static int ssd1306_init_device(const struct device *dev) static int ssd1306_init(const struct device *dev) { const struct ssd1306_config *config = dev->config; + int ret; k_sleep(K_TIMEOUT_ABS_MS(config->ready_time_ms)); @@ -460,14 +489,28 @@ static int ssd1306_init(const struct device *dev) return -EINVAL; } - if (config->reset.port) { - int ret; + if (config->supply.port) { + ret = gpio_pin_configure_dt(&config->supply, + GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + if (!gpio_is_ready_dt(&config->supply)) { + LOG_ERR("Supply GPIO device not ready"); + return -ENODEV; + } + } + if (config->reset.port) { ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_INACTIVE); if (ret < 0) { return ret; } + if (!gpio_is_ready_dt(&config->reset)) { + LOG_ERR("Reset GPIO device not ready"); + return -ENODEV; + } } if (ssd1306_init_device(dev)) { @@ -506,6 +549,7 @@ static DEVICE_API(display, ssd1306_driver_api) = { static struct ssd1306_data data##node_id; \ static const struct ssd1306_config config##node_id = { \ .reset = GPIO_DT_SPEC_GET_OR(node_id, reset_gpios, {0}), \ + .supply = GPIO_DT_SPEC_GET_OR(node_id, supply_gpios, {0}), \ .height = DT_PROP(node_id, height), \ .width = DT_PROP(node_id, width), \ .segment_offset = DT_PROP(node_id, segment_offset), \ @@ -517,6 +561,7 @@ static DEVICE_API(display, ssd1306_driver_api) = { .com_sequential = DT_PROP(node_id, com_sequential), \ .prechargep = DT_PROP(node_id, prechargep), \ .color_inversion = DT_PROP(node_id, inversion_on), \ + .ssd1309_compatible = DT_NODE_HAS_COMPAT(node_id, solomon_ssd1309fb), \ .sh1106_compatible = DT_NODE_HAS_COMPAT(node_id, sinowealth_sh1106), \ .ready_time_ms = DT_PROP(node_id, ready_time_ms), \ .use_internal_iref = DT_PROP(node_id, use_internal_iref), \ @@ -528,4 +573,5 @@ static DEVICE_API(display, ssd1306_driver_api) = { POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1306_driver_api); DT_FOREACH_STATUS_OKAY(solomon_ssd1306fb, SSD1306_DEFINE) +DT_FOREACH_STATUS_OKAY(solomon_ssd1309fb, SSD1306_DEFINE) DT_FOREACH_STATUS_OKAY(sinowealth_sh1106, SSD1306_DEFINE) diff --git a/drivers/display/ssd1306_regs.h b/drivers/display/ssd1306_regs.h index c2982c1fae67f..87dc3b6ba5b42 100644 --- a/drivers/display/ssd1306_regs.h +++ b/drivers/display/ssd1306_regs.h @@ -118,5 +118,6 @@ /* time constants in ms */ #define SSD1306_RESET_DELAY 1 +#define SSD1306_SUPPLY_DELAY 20 #endif diff --git a/drivers/display/uc81xx.c b/drivers/display/uc81xx.c index a051575c165e3..11a89c3475a36 100644 --- a/drivers/display/uc81xx.c +++ b/drivers/display/uc81xx.c @@ -383,7 +383,7 @@ static int uc81xx_write(const struct device *dev, const uint16_t x, const uint16 buf_len = MIN(desc->buf_size, desc->height * desc->width / UC81XX_PIXELS_PER_BYTE); - __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller than width"); __ASSERT(buf != NULL, "Buffer is not available"); __ASSERT(buf_len != 0U, "Buffer of length zero"); __ASSERT(!(desc->width % UC81XX_PIXELS_PER_BYTE), diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 00b424a37b680..e9fee15f7921f 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -37,11 +37,15 @@ zephyr_library_sources_ifdef(CONFIG_MCUX_PXP dma_mcux_pxp.c) zephyr_library_sources_ifdef(CONFIG_DMA_MAX32 dma_max32.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_ANDES_ATCDMAC300 dma_andes_atcdmac300.c) +zephyr_library_sources_ifdef(CONFIG_DMA_INFINEON_CAT1 dma_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_DMA_SEDI dma_sedi.c) zephyr_library_sources_ifdef(CONFIG_DMA_SI32 dma_si32.c) +zephyr_library_sources_ifdef(CONFIG_DMA_SILABS_LDMA dma_silabs_ldma.c) +zephyr_library_sources_ifdef(CONFIG_DMA_SILABS_SIWX91X dma_silabs_siwx91x.c) zephyr_library_sources_ifdef(CONFIG_DMA_SMARTBOND dma_smartbond.c) zephyr_library_sources_ifdef(CONFIG_DMA_NXP_SOF_HOST_DMA dma_nxp_sof_host_dma.c) zephyr_library_sources_ifdef(CONFIG_DMA_EMUL dma_emul.c) zephyr_library_sources_ifdef(CONFIG_DMA_NXP_EDMA dma_nxp_edma.c) zephyr_library_sources_ifdef(CONFIG_DMA_DW_AXI dma_dw_axi.c) zephyr_library_sources_ifdef(CONFIG_DMA_XILINX_AXI_DMA dma_xilinx_axi_dma.c) +zephyr_library_sources_ifdef(CONFIG_DMA_NXP_SDMA dma_nxp_sdma.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 964727e61cd6b..0c86eda9be987 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -58,6 +58,8 @@ source "drivers/dma/Kconfig.xmc4xxx" source "drivers/dma/Kconfig.rpi_pico" +source "drivers/dma/Kconfig.ifx_cat1" + source "drivers/dma/Kconfig.intel_lpss" source "drivers/dma/Kconfig.mcux_pxp" @@ -72,6 +74,10 @@ source "drivers/dma/Kconfig.sedi" source "drivers/dma/Kconfig.si32" +source "drivers/dma/Kconfig.silabs" + +source "drivers/dma/Kconfig.siwx91x" + source "drivers/dma/Kconfig.smartbond" source "drivers/dma/Kconfig.nxp_sof_host_dma" @@ -83,4 +89,6 @@ source "drivers/dma/Kconfig.nxp_edma" source "drivers/dma/Kconfig.dw_axi_dmac" source "drivers/dma/Kconfig.xilinx_axi_dma" +source "drivers/dma/Kconfig.nxp_sdma" + endif # DMA diff --git a/drivers/dma/Kconfig.ifx_cat1 b/drivers/dma/Kconfig.ifx_cat1 new file mode 100644 index 0000000000000..18066589773e7 --- /dev/null +++ b/drivers/dma/Kconfig.ifx_cat1 @@ -0,0 +1,14 @@ +# Infineon CAT1 DMA configuration options + +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +config DMA_INFINEON_CAT1 + bool "Infineon CAT1 DMA driver" + default y + depends on DT_HAS_INFINEON_CAT1_DMA_ENABLED + select USE_INFINEON_DMA + help + This option enables the DMA driver for Infineon CAT1 family. diff --git a/drivers/dma/Kconfig.nxp_sdma b/drivers/dma/Kconfig.nxp_sdma new file mode 100644 index 0000000000000..e0c2af47243b6 --- /dev/null +++ b/drivers/dma/Kconfig.nxp_sdma @@ -0,0 +1,9 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config DMA_NXP_SDMA + bool "NXP SDMA driver" + default y + depends on DT_HAS_NXP_SDMA_ENABLED + help + Enable driver for NXP's SDMA IP. diff --git a/drivers/dma/Kconfig.silabs b/drivers/dma/Kconfig.silabs new file mode 100644 index 0000000000000..8b61f422854d7 --- /dev/null +++ b/drivers/dma/Kconfig.silabs @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Silicon-labs +# SPDX-License-Identifier: Apache-2.0 + +config DMA_SILABS_LDMA + bool "Silabs DMA driver" + default y + select SYS_MEM_BLOCKS + select SOC_GECKO_LDMA + depends on DT_HAS_SILABS_LDMA_ENABLED + help + Driver for Silabs DMA. + +if DMA_SILABS_LDMA + +config DMA_MAX_DESCRIPTOR + int "Max Number of block_config (LDMA_Descriptor)" + default 8 + help + Max Number of block_config (LDMA_Descriptor) + +endif diff --git a/drivers/dma/Kconfig.siwx91x b/drivers/dma/Kconfig.siwx91x new file mode 100644 index 0000000000000..b6e7520439151 --- /dev/null +++ b/drivers/dma/Kconfig.siwx91x @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config DMA_SILABS_SIWX91X + bool "Silabs SiWx91x DMA driver" + default y + depends on DT_HAS_SILABS_SIWX91X_DMA_ENABLED + help + Enable the High Power(HP)/Ultra Low Power(ULP) DMA driver for the Silabs SiWx91x SoC series. diff --git a/drivers/dma/Kconfig.stm32 b/drivers/dma/Kconfig.stm32 index 03af025f883c1..fe1fdee43da6c 100644 --- a/drivers/dma/Kconfig.stm32 +++ b/drivers/dma/Kconfig.stm32 @@ -56,7 +56,7 @@ config DMA_STM32_SHARED_IRQS default y depends on SOC_SERIES_STM32C0X || SOC_SERIES_STM32F0X || \ SOC_SERIES_STM32G0X || SOC_SERIES_STM32L0X || \ - SOC_SERIES_STM32WB0X + SOC_SERIES_STM32U0X || SOC_SERIES_STM32WB0X help Enable shared IRQ support on devices where channels share 1 IRQ. diff --git a/drivers/dma/Kconfig.xmc4xxx b/drivers/dma/Kconfig.xmc4xxx index a2cf0a2e211d9..dd5feb3163b9b 100644 --- a/drivers/dma/Kconfig.xmc4xxx +++ b/drivers/dma/Kconfig.xmc4xxx @@ -9,3 +9,11 @@ config DMA_XMC4XXX depends on DT_HAS_INFINEON_XMC4XXX_DMA_ENABLED help DMA driver for Infineon xmc4xxx series MCUs. + +config DMA_XMC4XXX_NUM_DESCRIPTORS + int "Max DMA descriptors in a linked list" + default 4 + depends on DMA_XMC4XXX + help + Maximum number of blocks in a DMA block transfer configuration. + Only supported by dma0 channels 0 and 1. diff --git a/drivers/dma/dma_andes_atcdmac300.c b/drivers/dma/dma_andes_atcdmac300.c index 8f67a3cacd901..e2856b4d25072 100644 --- a/drivers/dma/dma_andes_atcdmac300.c +++ b/drivers/dma/dma_andes_atcdmac300.c @@ -493,7 +493,7 @@ static int dma_atcdmac300_get_status(const struct device *dev, return 0; } -static const struct dma_driver_api dma_atcdmac300_api = { +static DEVICE_API(dma, dma_atcdmac300_api) = { .config = dma_atcdmac300_config, .reload = dma_atcdmac300_reload, .start = dma_atcdmac300_transfer_start, diff --git a/drivers/dma/dma_dw.c b/drivers/dma/dma_dw.c index 138f428049cd9..8545ed7dffcfa 100644 --- a/drivers/dma/dma_dw.c +++ b/drivers/dma/dma_dw.c @@ -48,7 +48,7 @@ static int dw_dma_init(const struct device *dev) return ret; } -static const struct dma_driver_api dw_dma_driver_api = { +static DEVICE_API(dma, dw_dma_driver_api) = { .config = dw_dma_config, .start = dw_dma_start, .stop = dw_dma_stop, diff --git a/drivers/dma/dma_dw_axi.c b/drivers/dma/dma_dw_axi.c index 917f7008876ac..a0df451ffef3e 100644 --- a/drivers/dma/dma_dw_axi.c +++ b/drivers/dma/dma_dw_axi.c @@ -851,7 +851,7 @@ static int dma_dw_axi_init(const struct device *dev) return 0; } -static const struct dma_driver_api dma_dw_axi_driver_api = { +static DEVICE_API(dma, dma_dw_axi_driver_api) = { .config = dma_dw_axi_config, .start = dma_dw_axi_start, .stop = dma_dw_axi_stop, diff --git a/drivers/dma/dma_emul.c b/drivers/dma/dma_emul.c index 60c3486bf36bc..6320d1c1620b7 100644 --- a/drivers/dma/dma_emul.c +++ b/drivers/dma/dma_emul.c @@ -70,11 +70,6 @@ static void dma_emul_work_handler(struct k_work *work); LOG_MODULE_REGISTER(dma_emul, CONFIG_DMA_LOG_LEVEL); -static inline bool dma_emul_xfer_is_error_status(int status) -{ - return status < 0; -} - static inline const char *const dma_emul_channel_state_to_string(enum dma_emul_channel_state state) { switch (state) { @@ -513,7 +508,7 @@ static bool dma_emul_chan_filter(const struct device *dev, int channel, void *fi return success; } -static const struct dma_driver_api dma_emul_driver_api = { +static DEVICE_API(dma, dma_emul_driver_api) = { .config = dma_emul_configure, .reload = dma_emul_reload, .start = dma_emul_start, diff --git a/drivers/dma/dma_esp32_gdma.c b/drivers/dma/dma_esp32_gdma.c index 7fb5da72b43b6..c7874a65ce807 100644 --- a/drivers/dma/dma_esp32_gdma.c +++ b/drivers/dma/dma_esp32_gdma.c @@ -605,7 +605,7 @@ static int dma_esp32_init(const struct device *dev) return 0; } -static const struct dma_driver_api dma_esp32_api = { +static DEVICE_API(dma, dma_esp32_api) = { .config = dma_esp32_config, .start = dma_esp32_start, .stop = dma_esp32_stop, diff --git a/drivers/dma/dma_gd32.c b/drivers/dma/dma_gd32.c index 1bea14bb32ad3..ec6fb51d4fb38 100644 --- a/drivers/dma/dma_gd32.c +++ b/drivers/dma/dma_gd32.c @@ -651,7 +651,7 @@ static void dma_gd32_isr(const struct device *dev) } } -static const struct dma_driver_api dma_gd32_driver_api = { +static DEVICE_API(dma, dma_gd32_driver_api) = { .config = dma_gd32_config, .reload = dma_gd32_reload, .start = dma_gd32_start, diff --git a/drivers/dma/dma_ifx_cat1.c b/drivers/dma/dma_ifx_cat1.c new file mode 100644 index 0000000000000..0c1aaf89ef671 --- /dev/null +++ b/drivers/dma/dma_ifx_cat1.c @@ -0,0 +1,749 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief DMA driver for Infineon CAT1 MCU family. + */ + +#define DT_DRV_COMPAT infineon_cat1_dma + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#if CYHAL_DRIVER_AVAILABLE_SYSPM && CONFIG_PM +#include "cyhal_syspm_impl.h" +#endif + +#include +LOG_MODULE_REGISTER(ifx_cat1_dma, CONFIG_DMA_LOG_LEVEL); + +#define CH_NUM 32 +#define DESCRIPTOR_POOL_SIZE CH_NUM + 5 /* TODO: add parameter to Kconfig */ +#define DMA_LOOP_X_COUNT_MAX CY_DMA_LOOP_COUNT_MAX +#define DMA_LOOP_Y_COUNT_MAX CY_DMA_LOOP_COUNT_MAX + +#if CONFIG_SOC_FAMILY_INFINEON_CAT1B +/* For CAT1B we must use SBUS instead CBUS when operate with + * flash area, so convert address from CBUS to SBUS + */ +#define IFX_CAT1B_FLASH_SBUS_ADDR (0x60000000) +#define IFX_CAT1B_FLASH_CBUS_ADDR (0x8000000) +#define IFX_CAT1_DMA_SRC_ADDR(v) \ + (void *)(((uint32_t)v & IFX_CAT1B_FLASH_CBUS_ADDR) \ + ? (IFX_CAT1B_FLASH_SBUS_ADDR + ((uint32_t)v - IFX_CAT1B_FLASH_CBUS_ADDR)) \ + : (uint32_t)v) +#else +#define IFX_CAT1_DMA_SRC_ADDR(v) ((void *)v) +#endif + +struct ifx_cat1_dma_channel { + uint32_t channel_direction: 3; + uint32_t error_callback_dis: 1; + + cy_stc_dma_descriptor_t *descr; + IRQn_Type irq; + + /* store config data from dma_config structure */ + dma_callback_t callback; + void *user_data; +}; + +struct ifx_cat1_dma_data { + struct dma_context ctx; + struct ifx_cat1_dma_channel *channels; + +#if CYHAL_DRIVER_AVAILABLE_SYSPM && CONFIG_PM + cyhal_syspm_callback_data_t syspm_callback_args; +#endif +}; + +struct ifx_cat1_dma_config { + uint8_t num_channels; + DW_Type *regs; + void (*irq_configure)(void); +}; + +/* Descriptors pool */ +K_MEM_SLAB_DEFINE_STATIC(ifx_cat1_dma_descriptors_pool_slab, sizeof(cy_stc_dma_descriptor_t), + DESCRIPTOR_POOL_SIZE, 4); + +static int32_t _get_hw_block_num(DW_Type *reg_addr) +{ +#if (CPUSS_DW0_PRESENT == 1) + if ((uint32_t)reg_addr == DW0_BASE) { + return 0; + } +#endif + +#if (CPUSS_DW1_PRESENT == 1) + if ((uint32_t)reg_addr == DW1_BASE) { + return 1; + } +#endif + return 0; +} + +static int _dma_alloc_descriptor(void **descr) +{ + int ret = k_mem_slab_alloc(&ifx_cat1_dma_descriptors_pool_slab, (void **)descr, K_NO_WAIT); + + if (!ret) { + memset(*descr, 0, sizeof(cy_stc_dma_descriptor_t)); + } + + return ret; +} + +void _dma_free_descriptor(cy_stc_dma_descriptor_t *descr) +{ + k_mem_slab_free(&ifx_cat1_dma_descriptors_pool_slab, descr); +} + +void _dma_free_linked_descriptors(cy_stc_dma_descriptor_t *descr) +{ + if (descr == NULL) { + return; + } + cy_stc_dma_descriptor_t *descr_to_remove = descr; + cy_stc_dma_descriptor_t *descr_to_remove_next = NULL; + + do { + descr_to_remove_next = (cy_stc_dma_descriptor_t *)descr_to_remove->nextPtr; + _dma_free_descriptor(descr_to_remove); + descr_to_remove = descr_to_remove_next; + + } while (descr_to_remove); +} + +int ifx_cat1_dma_ex_connect_digital(const struct device *dev, uint32_t channel, + cyhal_source_t source, cyhal_dma_input_t input) +{ + const struct ifx_cat1_dma_config *const cfg = dev->config; + + cyhal_dma_t dma_obj = { + .resource.type = CYHAL_RSC_DW, + .resource.block_num = _get_hw_block_num(cfg->regs), + .resource.channel_num = channel, + }; + + cy_rslt_t rslt = cyhal_dma_connect_digital(&dma_obj, source, input); + + return rslt ? -EIO : 0; +} + +int ifx_cat1_dma_ex_enable_output(const struct device *dev, uint32_t channel, + cyhal_dma_output_t output, cyhal_source_t *source) +{ + const struct ifx_cat1_dma_config *const cfg = dev->config; + + cyhal_dma_t dma_obj = { + .resource.type = CYHAL_RSC_DW, + .resource.block_num = _get_hw_block_num(cfg->regs), + .resource.channel_num = channel, + }; + + cy_rslt_t rslt = cyhal_dma_enable_output(&dma_obj, output, source); + + return rslt ? -EIO : 0; +} + +static cy_en_dma_data_size_t _convert_dma_data_size_z_to_pdl(struct dma_config *config) +{ + cy_en_dma_data_size_t pdl_dma_data_size = CY_DMA_BYTE; + + switch (config->source_data_size) { + case 1: + /* One byte */ + pdl_dma_data_size = CY_DMA_BYTE; + break; + case 2: + /* Half word (two bytes) */ + pdl_dma_data_size = CY_DMA_HALFWORD; + break; + case 4: + /* Full word (four bytes) */ + pdl_dma_data_size = CY_DMA_WORD; + break; + } + return pdl_dma_data_size; +} + +static int _convert_dma_xy_increment_z_to_pdl(uint32_t addr_adj) +{ + switch (addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + return 1; + + case DMA_ADDR_ADJ_DECREMENT: + return -1; + + case DMA_ADDR_ADJ_NO_CHANGE: + return 0; + + default: + return 0; + } +} + +static int _initialize_descriptor(cy_stc_dma_descriptor_t *descriptor, struct dma_config *config, + struct dma_block_config *block_config, uint32_t block_num, + uint32_t bytes, uint32_t offset) +{ + cy_en_dma_status_t dma_status; + cy_stc_dma_descriptor_config_t descriptor_config = {0u}; + + /* Retrigger descriptor immediately */ + descriptor_config.retrigger = CY_DMA_RETRIG_IM; + + /* Setup Interrupt Type */ + descriptor_config.interruptType = CY_DMA_DESCR_CHAIN; + + if (((offset + bytes) == block_config->block_size) && + (block_num + 1 == config->block_count)) { + descriptor_config.channelState = CY_DMA_CHANNEL_DISABLED; + } else { + descriptor_config.channelState = CY_DMA_CHANNEL_ENABLED; + } + + /* TODO: should be able to configure triggerInType/triggerOutType */ + descriptor_config.triggerOutType = CY_DMA_1ELEMENT; + + if (config->channel_direction == MEMORY_TO_MEMORY) { + descriptor_config.triggerInType = CY_DMA_DESCR_CHAIN; + } else { + descriptor_config.triggerInType = CY_DMA_1ELEMENT; + } + + /* Set data size byte / 2 bytes / word */ + descriptor_config.dataSize = _convert_dma_data_size_z_to_pdl(config); + + /* By default, transfer what the user set for dataSize. However, if transferring between + * memory and a peripheral, make sure the peripheral access is using words. + */ + descriptor_config.srcTransferSize = CY_DMA_TRANSFER_SIZE_DATA; + descriptor_config.dstTransferSize = CY_DMA_TRANSFER_SIZE_DATA; + + if (config->channel_direction == PERIPHERAL_TO_MEMORY) { + descriptor_config.srcTransferSize = CY_DMA_TRANSFER_SIZE_WORD; + } else if (config->channel_direction == MEMORY_TO_PERIPHERAL) { + descriptor_config.dstTransferSize = CY_DMA_TRANSFER_SIZE_WORD; + } + + /* Setup destination increment for X source loop */ + descriptor_config.srcXincrement = + _convert_dma_xy_increment_z_to_pdl(block_config->source_addr_adj); + + /* Setup destination increment for X destination loop */ + descriptor_config.dstXincrement = + _convert_dma_xy_increment_z_to_pdl(block_config->dest_addr_adj); + + /* Setup 1D/2D descriptor for each data block */ + if (bytes >= DMA_LOOP_X_COUNT_MAX) { + descriptor_config.descriptorType = CY_DMA_2D_TRANSFER; + descriptor_config.xCount = DMA_LOOP_X_COUNT_MAX; + descriptor_config.yCount = DIV_ROUND_UP(bytes, DMA_LOOP_X_COUNT_MAX); + descriptor_config.srcYincrement = + descriptor_config.srcXincrement * DMA_LOOP_X_COUNT_MAX; + descriptor_config.dstYincrement = + descriptor_config.dstXincrement * DMA_LOOP_X_COUNT_MAX; + } else { + descriptor_config.descriptorType = CY_DMA_1D_TRANSFER; + descriptor_config.xCount = bytes; + descriptor_config.yCount = 1; + descriptor_config.srcYincrement = 0; + descriptor_config.dstYincrement = 0; + } + + /* Set source and destination for descriptor */ + descriptor_config.srcAddress = IFX_CAT1_DMA_SRC_ADDR( + (block_config->source_address + (descriptor_config.srcXincrement ? offset : 0))); + descriptor_config.dstAddress = (void *)(block_config->dest_address + + (descriptor_config.dstXincrement ? offset : 0)); + + /* initialize descriptor */ + dma_status = Cy_DMA_Descriptor_Init(descriptor, &descriptor_config); + if (dma_status != CY_DMA_SUCCESS) { + return -EIO; + } + + return 0; +} + +/* Configure a channel v2 */ +static int ifx_cat1_dma_configure(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + bool use_dt_config = false; + cy_en_dma_status_t dma_status; + struct ifx_cat1_dma_data *data = dev->data; + const struct ifx_cat1_dma_config *const cfg = dev->config; + + cy_stc_dma_channel_config_t channel_config = {0u}; + cy_stc_dma_descriptor_t *descriptor = NULL; + cy_stc_dma_descriptor_t *prev_descriptor = NULL; + + if (channel >= cfg->num_channels) { + LOG_ERR("Unsupported channel"); + return -EINVAL; + } + + /* Support only the same data width for source and dest */ + if (config->dest_data_size != config->source_data_size) { + LOG_ERR("Source and dest data size differ."); + return -EINVAL; + } + + if ((config->dest_data_size != 1) && (config->dest_data_size != 2) && + (config->dest_data_size != 4)) { + LOG_ERR("dest_data_size must be 1, 2, or 4 (%" PRIu32 ")", config->dest_data_size); + return -EINVAL; + } + + if (config->complete_callback_en > 1) { + LOG_ERR("Callback on each block not implemented"); + return -ENOTSUP; + } + + data->channels[channel].callback = config->dma_callback; + data->channels[channel].user_data = config->user_data; + data->channels[channel].channel_direction = config->channel_direction; + data->channels[channel].error_callback_dis = config->error_callback_dis; + + /* Remove all allocated linked descriptors */ + _dma_free_linked_descriptors(data->channels[channel].descr); + data->channels[channel].descr = NULL; + + /* Lock and page in the channel configuration */ + uint32_t key = irq_lock(); + + struct dma_block_config *block_config = config->head_block; + + for (uint32_t i = 0u; i < config->block_count; i++) { + uint32_t block_pending_bytes = block_config->block_size; + uint32_t offset = 0; + + do { + /* Configure descriptors for one block */ + uint32_t bytes; + + /* allocate new descriptor */ + if (_dma_alloc_descriptor((void **)&descriptor)) { + LOG_ERR("Can't allocate new descriptor"); + return -EINVAL; + } + + if (data->channels[channel].descr == NULL) { + /* Store first descriptor in data structure */ + data->channels[channel].descr = descriptor; + } + + /* Mendotary chain descriptors in scope of one pack */ + if (prev_descriptor != NULL) { + Cy_DMA_Descriptor_SetNextDescriptor(prev_descriptor, descriptor); + } + + /* Calculate bytes, block_pending_bytes for 1D/2D descriptor */ + if (block_pending_bytes <= DMA_LOOP_X_COUNT_MAX) { + /* Calculate bytes for 1D descriptor */ + bytes = block_pending_bytes; + block_pending_bytes = 0; + } else { + /* Calculate bytes for 2D descriptor */ + if (block_pending_bytes > + (DMA_LOOP_X_COUNT_MAX * DMA_LOOP_Y_COUNT_MAX)) { + bytes = DMA_LOOP_X_COUNT_MAX * DMA_LOOP_Y_COUNT_MAX; + } else { + bytes = DMA_LOOP_Y_COUNT_MAX * + (block_pending_bytes / DMA_LOOP_Y_COUNT_MAX); + } + block_pending_bytes -= bytes; + } + + _initialize_descriptor(descriptor, config, block_config, + /* block_num */ i, bytes, offset); + offset += bytes; + prev_descriptor = descriptor; + + } while (block_pending_bytes > 0); + + block_config = block_config->next_block; + } + + /* Set a descriptor for the specified DMA channel */ + channel_config.descriptor = data->channels[channel].descr; + + /* Set a priority for the DMA channel */ + if (use_dt_config == false) { + Cy_DMA_Channel_SetPriority(cfg->regs, channel, config->channel_priority); + } + + /* Initialize channel */ + dma_status = Cy_DMA_Channel_Init(cfg->regs, channel, &channel_config); + if (dma_status != CY_DMA_SUCCESS) { + return -EIO; + } + + irq_unlock(key); + return 0; +} + +DW_Type *ifx_cat1_dma_get_regs(const struct device *dev) +{ + const struct ifx_cat1_dma_config *const cfg = dev->config; + + return cfg->regs; +} + +static int ifx_cat1_dma_start(const struct device *dev, uint32_t channel) +{ + const struct ifx_cat1_dma_config *const cfg = dev->config; + struct ifx_cat1_dma_data *data = dev->data; + + if (channel >= cfg->num_channels) { + LOG_ERR("Unsupported channel"); + return -EINVAL; + } + + /* Enable DMA interrupt source. */ + Cy_DMA_Channel_SetInterruptMask(cfg->regs, channel, CY_DMA_INTR_MASK); + + /* Enable the interrupt */ + irq_enable(data->channels[channel].irq); + + /* Enable DMA channel */ + Cy_DMA_Channel_Enable(cfg->regs, channel); + if ((data->channels[channel].channel_direction == MEMORY_TO_MEMORY) || + (data->channels[channel].channel_direction == MEMORY_TO_PERIPHERAL)) { + cyhal_dma_t dma_obj = { + .resource.type = CYHAL_RSC_DW, + .resource.block_num = _get_hw_block_num(cfg->regs), + .resource.channel_num = channel, + }; + (void)cyhal_dma_start_transfer(&dma_obj); + } + return 0; +} + +static int ifx_cat1_dma_stop(const struct device *dev, uint32_t channel) +{ + const struct ifx_cat1_dma_config *const cfg = dev->config; + + if (channel >= cfg->num_channels) { + LOG_ERR("Unsupported channel"); + return -EINVAL; + } + + /* Disable DMA channel */ + Cy_DMA_Channel_Disable(cfg->regs, channel); + + return 0; +} + +int ifx_cat1_dma_reload(const struct device *dev, uint32_t channel, uint32_t src, uint32_t dst, + size_t size) +{ + struct ifx_cat1_dma_data *data = dev->data; + const struct ifx_cat1_dma_config *const cfg = dev->config; + cy_stc_dma_descriptor_t *descriptor = data->channels[channel].descr; + + if (channel >= cfg->num_channels) { + LOG_ERR("Unsupported channel"); + return -EINVAL; + } + + /* Disable Channel */ + Cy_DMA_Channel_Disable(cfg->regs, channel); + + /* Update source/destination address for the specified descriptor */ + descriptor->src = (uint32_t)IFX_CAT1_DMA_SRC_ADDR(src); + descriptor->dst = dst; + + /* Initialize channel */ + Cy_DMA_Channel_Enable(cfg->regs, channel); + + return 0; +} + +uint32_t get_total_size(const struct device *dev, uint32_t channel) +{ + struct ifx_cat1_dma_data *data = dev->data; + uint32_t total_size = 0; + uint32_t x_size = 0; + uint32_t y_size = 0; + cy_stc_dma_descriptor_t *curr_descr = data->channels[channel].descr; + + while (curr_descr != NULL) { + x_size = Cy_DMA_Descriptor_GetXloopDataCount(curr_descr); + + if (CY_DMA_2D_TRANSFER == Cy_DMA_Descriptor_GetDescriptorType(curr_descr)) { + y_size = Cy_DMA_Descriptor_GetYloopDataCount(curr_descr); + } else { + y_size = 0; + } + + total_size += y_size != 0 ? x_size * y_size : x_size; + curr_descr = Cy_DMA_Descriptor_GetNextDescriptor(curr_descr); + } + + return total_size; +} + +uint32_t get_transferred_size(const struct device *dev, uint32_t channel) +{ + struct ifx_cat1_dma_data *data = dev->data; + const struct ifx_cat1_dma_config *const cfg = dev->config; + uint32_t transferred_data_size = 0; + uint32_t x_size = 0; + uint32_t y_size = 0; + + cy_stc_dma_descriptor_t *next_descr = data->channels[channel].descr; + cy_stc_dma_descriptor_t *curr_descr = + Cy_DMA_Channel_GetCurrentDescriptor(ifx_cat1_dma_get_regs(dev), channel); + + /* Calculates all processed descriptors */ + while ((next_descr != NULL) && (next_descr != curr_descr)) { + x_size = Cy_DMA_Descriptor_GetXloopDataCount(next_descr); + y_size = Cy_DMA_Descriptor_GetYloopDataCount(next_descr); + transferred_data_size += y_size != 0 ? x_size * y_size : x_size; + next_descr = Cy_DMA_Descriptor_GetNextDescriptor(next_descr); + } + + /* Calculates current descriptors (in progress) */ + transferred_data_size += + _FLD2VAL(DW_CH_STRUCT_CH_IDX_X_IDX, DW_CH_IDX(cfg->regs, channel)) + + (_FLD2VAL(DW_CH_STRUCT_CH_IDX_Y_IDX, DW_CH_IDX(cfg->regs, channel)) * + Cy_DMA_Descriptor_GetXloopDataCount(curr_descr)); + + return transferred_data_size; +} + +static int ifx_cat1_dma_get_status(const struct device *dev, uint32_t channel, + struct dma_status *stat) +{ + struct ifx_cat1_dma_data *data = dev->data; + const struct ifx_cat1_dma_config *const cfg = dev->config; + uint32_t pending_status = 0; + + if (channel >= cfg->num_channels) { + LOG_ERR("Unsupported channel"); + return -EINVAL; + } + + if (stat != NULL) { + /* Check is current DMA channel busy or idle */ +#if CONFIG_SOC_FAMILY_INFINEON_CAT1A + pending_status = DW_CH_STATUS(cfg->regs, channel) & + (1UL << DW_CH_STRUCT_V2_CH_STATUS_PENDING_Pos); +#elif CONFIG_SOC_FAMILY_INFINEON_CAT1B + pending_status = DW_CH_STATUS(cfg->regs, channel) & + (1UL << DW_CH_STRUCT_CH_STATUS_PENDING_Pos); +#endif + /* busy status info */ + stat->busy = pending_status ? true : false; + + if (data->channels[channel].descr != NULL) { + uint32_t total_transfer_size = get_total_size(dev, channel); + uint32_t transferred_size = get_transferred_size(dev, channel); + + stat->pending_length = total_transfer_size - transferred_size; + } else { + stat->pending_length = 0; + } + + /* direction info */ + stat->dir = data->channels[channel].channel_direction; + } + + return 0; +} + +#if CYHAL_DRIVER_AVAILABLE_SYSPM && CONFIG_PM + +static bool _cyhal_dma_dmac_pm_callback(cyhal_syspm_callback_state_t state, + cyhal_syspm_callback_mode_t mode, void *callback_arg) +{ + CY_UNUSED_PARAMETER(state); + bool block_transition = false; + struct ifx_cat1_dma_config *conf = (struct ifx_cat1_dma_config *)callback_arg; + uint8_t i; + + switch (mode) { + case CYHAL_SYSPM_CHECK_READY: + for (i = 0u; i < conf->num_channels; i++) { +#if CONFIG_SOC_FAMILY_INFINEON_CAT1A + block_transition |= DW_CH_STATUS(conf->regs, i) & + (1UL << DW_CH_STRUCT_V2_CH_STATUS_PENDING_Pos); +#elif CONFIG_SOC_FAMILY_INFINEON_CAT1B + block_transition |= DW_CH_STATUS(conf->regs, i) & + (1UL << DW_CH_STRUCT_CH_STATUS_PENDING_Pos); +#endif + } + break; + case CYHAL_SYSPM_CHECK_FAIL: + case CYHAL_SYSPM_AFTER_TRANSITION: + break; + default: + CY_ASSERT(false); + break; + } + + return !block_transition; +} +#endif + +static int ifx_cat1_dma_init(const struct device *dev) +{ + const struct ifx_cat1_dma_config *const cfg = dev->config; + +#if CYHAL_DRIVER_AVAILABLE_SYSPM && CONFIG_PM + struct ifx_cat1_dma_data *data = dev->data; + + _cyhal_syspm_register_peripheral_callback(&data->syspm_callback_args); +#endif + + /* Enable DMA block to start descriptor execution process */ + Cy_DMA_Enable(cfg->regs); + + /* Configure IRQ */ + cfg->irq_configure(); + + return 0; +} + +/* Handles DMA interrupts and dispatches to the individual channel */ +struct ifx_cat1_dma_irq_context { + const struct device *dev; + uint32_t channel; +}; + +static void ifx_cat1_dma_isr(struct ifx_cat1_dma_irq_context *irq_context) +{ + uint32_t channel = irq_context->channel; + struct ifx_cat1_dma_data *data = irq_context->dev->data; + const struct ifx_cat1_dma_config *cfg = irq_context->dev->config; + dma_callback_t callback = data->channels[channel].callback; + int status; + + /* Remove all allocated linked descriptors */ + _dma_free_linked_descriptors(data->channels[channel].descr); + data->channels[channel].descr = NULL; + + uint32_t intr_status = Cy_DMA_Channel_GetStatus(cfg->regs, channel); + + /* Clear all interrupts */ + Cy_DMA_Channel_ClearInterrupt(cfg->regs, channel); + + /* Get interrupt type and call users event callback if they have enabled that event */ + switch (intr_status) { + case CY_DMA_INTR_CAUSE_COMPLETION: + status = 0; + break; + case CY_DMA_INTR_CAUSE_DESCR_BUS_ERROR: /* Descriptor bus error */ + case CY_DMA_INTR_CAUSE_SRC_BUS_ERROR: /* Source bus error */ + case CY_DMA_INTR_CAUSE_DST_BUS_ERROR: /* Destination bus error */ + status = -EPERM; + break; + case CY_DMA_INTR_CAUSE_SRC_MISAL: /* Source address is not aligned */ + case CY_DMA_INTR_CAUSE_DST_MISAL: /* Destination address is not aligned */ + status = -EPERM; + break; + case CY_DMA_INTR_CAUSE_CURR_PTR_NULL: /* Current descr pointer is NULL */ + case CY_DMA_INTR_CAUSE_ACTIVE_CH_DISABLED: /* Active channel is disabled */ + default: + status = -EIO; + break; + } + + if ((callback != NULL && status == 0) || + (callback != NULL && data->channels[channel].error_callback_dis)) { + void *callback_arg = data->channels[channel].user_data; + + callback(irq_context->dev, callback_arg, channel, status); + } +} + +static DEVICE_API(dma, ifx_cat1_dma_api) = { + .config = ifx_cat1_dma_configure, + .start = ifx_cat1_dma_start, + .stop = ifx_cat1_dma_stop, + .reload = ifx_cat1_dma_reload, + .get_status = ifx_cat1_dma_get_status, +}; + +#define IRQ_CONFIGURE(n, inst) \ + static const struct ifx_cat1_dma_irq_context irq_context##inst##n = { \ + .dev = DEVICE_DT_INST_GET(inst), \ + .channel = n, \ + }; \ + \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, n, irq), DT_INST_IRQ_BY_IDX(inst, n, priority), \ + ifx_cat1_dma_isr, &irq_context##inst##n, 0); \ + \ + ifx_cat1_dma_channels##inst[n].irq = DT_INST_IRQ_BY_IDX(inst, n, irq); + +#define CONFIGURE_ALL_IRQS(inst, n) LISTIFY(n, IRQ_CONFIGURE, (), inst) + +#if CYHAL_DRIVER_AVAILABLE_SYSPM && CONFIG_PM +#define SYSPM_CALLBACK_ARGS(n) \ + .syspm_callback_args = { \ + .callback = &_cyhal_dma_dmac_pm_callback, \ + .states = (cyhal_syspm_callback_state_t)(CYHAL_SYSPM_CB_CPU_DEEPSLEEP | \ + CYHAL_SYSPM_CB_CPU_DEEPSLEEP_RAM | \ + CYHAL_SYSPM_CB_SYSTEM_HIBERNATE), \ + .next = NULL, \ + .args = (void *)&ifx_cat1_dma_config##n, \ + .ignore_modes = \ + (cyhal_syspm_callback_mode_t)(CYHAL_SYSPM_BEFORE_TRANSITION | \ + CYHAL_SYSPM_AFTER_DS_WFI_TRANSITION)}, +#else +#define SYSPM_CALLBACK_ARGS(n) +#endif + +#define INFINEON_CAT1_DMA_INIT(n) \ + \ + static void ifx_cat1_dma_irq_configure##n(void); \ + \ + \ + static struct ifx_cat1_dma_channel \ + ifx_cat1_dma_channels##n[DT_INST_PROP(n, dma_channels)]; \ + \ + static const struct ifx_cat1_dma_config ifx_cat1_dma_config##n = { \ + .num_channels = DT_INST_PROP(n, dma_channels), \ + .regs = (DW_Type *)DT_INST_REG_ADDR(n), \ + .irq_configure = ifx_cat1_dma_irq_configure##n, \ + }; \ + \ + ATOMIC_DEFINE(ifx_cat1_dma_##n, DT_INST_PROP(n, dma_channels)); \ + static __aligned(32) struct ifx_cat1_dma_data ifx_cat1_dma_data##n = { \ + .ctx = \ + { \ + .magic = DMA_MAGIC, \ + .atomic = ifx_cat1_dma_##n, \ + .dma_channels = DT_INST_PROP(n, dma_channels), \ + }, \ + .channels = ifx_cat1_dma_channels##n, \ + SYSPM_CALLBACK_ARGS(n)}; \ + \ + static void ifx_cat1_dma_irq_configure##n(void) \ + { \ + extern struct ifx_cat1_dma_channel ifx_cat1_dma_channels##n[]; \ + CONFIGURE_ALL_IRQS(n, DT_NUM_IRQS(DT_DRV_INST(n))); \ + } \ + \ + DEVICE_DT_INST_DEFINE(n, &ifx_cat1_dma_init, NULL, &ifx_cat1_dma_data##n, \ + &ifx_cat1_dma_config##n, PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, \ + &ifx_cat1_dma_api); + +DT_INST_FOREACH_STATUS_OKAY(INFINEON_CAT1_DMA_INIT) diff --git a/drivers/dma/dma_intel_adsp_gpdma.c b/drivers/dma/dma_intel_adsp_gpdma.c index bed6296adf8fd..02c8e635c3df5 100644 --- a/drivers/dma/dma_intel_adsp_gpdma.c +++ b/drivers/dma/dma_intel_adsp_gpdma.c @@ -440,38 +440,15 @@ static inline void ace_gpdma_intc_unmask(void) static inline void ace_gpdma_intc_unmask(void) {} #endif - -int intel_adsp_gpdma_init(const struct device *dev) -{ - struct dw_dma_dev_data *const dev_data = dev->data; - - /* Setup context and atomics for channels */ - dev_data->dma_ctx.magic = DMA_MAGIC; - dev_data->dma_ctx.dma_channels = DW_MAX_CHAN; - dev_data->dma_ctx.atomic = dev_data->channels_atomic; - - ace_gpdma_intc_unmask(); - -#if CONFIG_PM_DEVICE && CONFIG_SOC_SERIES_INTEL_ADSP_ACE - if (pm_device_on_power_domain(dev)) { - pm_device_init_off(dev); - } else { - pm_device_init_suspended(dev); - } - - return 0; -#else - return intel_adsp_gpdma_power_on(dev); -#endif -} -#ifdef CONFIG_PM_DEVICE static int gpdma_pm_action(const struct device *dev, enum pm_device_action action) { switch (action) { case PM_DEVICE_ACTION_RESUME: return intel_adsp_gpdma_power_on(dev); case PM_DEVICE_ACTION_SUSPEND: +#ifdef CONFIG_PM_DEVICE return intel_adsp_gpdma_power_off(dev); +#endif /* ON and OFF actions are used only by the power domain to change internal power status of * the device. OFF state mean that device and its power domain are disabled, SUSPEND mean * that device is power off but domain is already power on. @@ -485,9 +462,21 @@ static int gpdma_pm_action(const struct device *dev, enum pm_device_action actio return 0; } -#endif -static const struct dma_driver_api intel_adsp_gpdma_driver_api = { +int intel_adsp_gpdma_init(const struct device *dev) +{ + struct dw_dma_dev_data *const dev_data = dev->data; + + /* Setup context and atomics for channels */ + dev_data->dma_ctx.magic = DMA_MAGIC; + dev_data->dma_ctx.dma_channels = DW_MAX_CHAN; + dev_data->dma_ctx.atomic = dev_data->channels_atomic; + + ace_gpdma_intc_unmask(); + return pm_device_driver_init(dev, gpdma_pm_action); +} + +static DEVICE_API(dma, intel_adsp_gpdma_driver_api) = { .config = intel_adsp_gpdma_config, .reload = intel_adsp_gpdma_copy, .start = intel_adsp_gpdma_start, diff --git a/drivers/dma/dma_intel_adsp_hda.c b/drivers/dma/dma_intel_adsp_hda.c index 43653933a14e4..de2b5b1c827a5 100644 --- a/drivers/dma/dma_intel_adsp_hda.c +++ b/drivers/dma/dma_intel_adsp_hda.c @@ -383,6 +383,22 @@ static void intel_adsp_hda_channels_init(const struct device *dev) #endif } +int intel_adsp_hda_dma_pm_action(const struct device *dev, enum pm_device_action action) +{ + ARG_UNUSED(dev); + switch (action) { + case PM_DEVICE_ACTION_RESUME: + case PM_DEVICE_ACTION_SUSPEND: + case PM_DEVICE_ACTION_TURN_ON: + case PM_DEVICE_ACTION_TURN_OFF: + break; + default: + return -ENOTSUP; + } + + return 0; +} + int intel_adsp_hda_dma_init(const struct device *dev) { struct intel_adsp_hda_dma_data *data = dev->data; @@ -391,19 +407,8 @@ int intel_adsp_hda_dma_init(const struct device *dev) data->ctx.dma_channels = cfg->dma_channels; data->ctx.atomic = data->channels_atomic; data->ctx.magic = DMA_MAGIC; -#ifdef CONFIG_PM_DEVICE_RUNTIME - if (pm_device_on_power_domain(dev)) { - pm_device_init_off(dev); - } else { - intel_adsp_hda_channels_init(dev); - pm_device_init_suspended(dev); - } - - return pm_device_runtime_enable(dev); -#else intel_adsp_hda_channels_init(dev); - return 0; -#endif + return pm_device_driver_init(dev, intel_adsp_hda_dma_pm_action); } int intel_adsp_hda_dma_get_attribute(const struct device *dev, uint32_t type, uint32_t *value) @@ -430,25 +435,6 @@ int intel_adsp_hda_dma_get_attribute(const struct device *dev, uint32_t type, ui return 0; } -#ifdef CONFIG_PM_DEVICE -int intel_adsp_hda_dma_pm_action(const struct device *dev, enum pm_device_action action) -{ - switch (action) { - case PM_DEVICE_ACTION_RESUME: - intel_adsp_hda_channels_init(dev); - break; - case PM_DEVICE_ACTION_SUSPEND: - case PM_DEVICE_ACTION_TURN_ON: - case PM_DEVICE_ACTION_TURN_OFF: - break; - default: - return -ENOTSUP; - } - - return 0; -} -#endif - #define DEVICE_DT_GET_AND_COMMA(node_id) DEVICE_DT_GET(node_id), void intel_adsp_hda_dma_isr(void) diff --git a/drivers/dma/dma_intel_adsp_hda_host_in.c b/drivers/dma/dma_intel_adsp_hda_host_in.c index a6114b0540426..96695c0250789 100644 --- a/drivers/dma/dma_intel_adsp_hda_host_in.c +++ b/drivers/dma/dma_intel_adsp_hda_host_in.c @@ -10,7 +10,7 @@ #include #include "dma_intel_adsp_hda.h" -static const struct dma_driver_api intel_adsp_hda_dma_host_in_api = { +static DEVICE_API(dma, intel_adsp_hda_dma_host_in_api) = { .config = intel_adsp_hda_dma_host_in_config, .reload = intel_adsp_hda_dma_host_reload, .start = intel_adsp_hda_dma_start, diff --git a/drivers/dma/dma_intel_adsp_hda_host_out.c b/drivers/dma/dma_intel_adsp_hda_host_out.c index f06d177ed2963..2072e35d942e7 100644 --- a/drivers/dma/dma_intel_adsp_hda_host_out.c +++ b/drivers/dma/dma_intel_adsp_hda_host_out.c @@ -14,7 +14,7 @@ #include LOG_MODULE_REGISTER(dma_intel_adsp_hda_dma_host_out); -static const struct dma_driver_api intel_adsp_hda_dma_host_out_api = { +static DEVICE_API(dma, intel_adsp_hda_dma_host_out_api) = { .config = intel_adsp_hda_dma_host_out_config, .reload = intel_adsp_hda_dma_host_reload, .start = intel_adsp_hda_dma_start, diff --git a/drivers/dma/dma_intel_adsp_hda_link_in.c b/drivers/dma/dma_intel_adsp_hda_link_in.c index fc631d136f0c7..f6be51bfdd726 100644 --- a/drivers/dma/dma_intel_adsp_hda_link_in.c +++ b/drivers/dma/dma_intel_adsp_hda_link_in.c @@ -13,7 +13,7 @@ #include LOG_MODULE_REGISTER(dma_intel_adsp_hda_dma_link_in); -static const struct dma_driver_api intel_adsp_hda_dma_link_in_api = { +static DEVICE_API(dma, intel_adsp_hda_dma_link_in_api) = { .config = intel_adsp_hda_dma_link_in_config, .reload = intel_adsp_hda_dma_link_reload, .start = intel_adsp_hda_dma_start, diff --git a/drivers/dma/dma_intel_adsp_hda_link_out.c b/drivers/dma/dma_intel_adsp_hda_link_out.c index eefa50189f0ec..b3b5f1396d475 100644 --- a/drivers/dma/dma_intel_adsp_hda_link_out.c +++ b/drivers/dma/dma_intel_adsp_hda_link_out.c @@ -13,7 +13,7 @@ #include LOG_MODULE_REGISTER(dma_intel_adsp_hda_dma_link_out); -static const struct dma_driver_api intel_adsp_hda_dma_link_out_api = { +static DEVICE_API(dma, intel_adsp_hda_dma_link_out_api) = { .config = intel_adsp_hda_dma_link_out_config, .reload = intel_adsp_hda_dma_link_reload, .start = intel_adsp_hda_dma_start, diff --git a/drivers/dma/dma_intel_lpss.c b/drivers/dma/dma_intel_lpss.c index ad004fc1cf865..40553928b5325 100644 --- a/drivers/dma/dma_intel_lpss.c +++ b/drivers/dma/dma_intel_lpss.c @@ -129,7 +129,7 @@ void dma_intel_lpss_isr(const struct device *dev) dw_dma_isr(dev); } -static const struct dma_driver_api dma_intel_lpss_driver_api = { +static DEVICE_API(dma, dma_intel_lpss_driver_api) = { .config = dw_dma_config, .start = dw_dma_start, .reload = dma_intel_lpss_reload, diff --git a/drivers/dma/dma_iproc_pax_v1.c b/drivers/dma/dma_iproc_pax_v1.c index 9acfeabd37481..4073238da1675 100644 --- a/drivers/dma/dma_iproc_pax_v1.c +++ b/drivers/dma/dma_iproc_pax_v1.c @@ -965,7 +965,7 @@ static int dma_iproc_pax_transfer_stop(const struct device *dev, return 0; } -static const struct dma_driver_api pax_dma_driver_api = { +static DEVICE_API(dma, pax_dma_driver_api) = { .config = dma_iproc_pax_configure, .start = dma_iproc_pax_transfer_start, .stop = dma_iproc_pax_transfer_stop, diff --git a/drivers/dma/dma_iproc_pax_v2.c b/drivers/dma/dma_iproc_pax_v2.c index 556af62ae75e9..a3d7522a87ff2 100644 --- a/drivers/dma/dma_iproc_pax_v2.c +++ b/drivers/dma/dma_iproc_pax_v2.c @@ -1081,7 +1081,7 @@ static int dma_iproc_pax_transfer_stop(const struct device *dev, return 0; } -static const struct dma_driver_api pax_dma_driver_api = { +static DEVICE_API(dma, pax_dma_driver_api) = { .config = dma_iproc_pax_configure, .start = dma_iproc_pax_transfer_start, .stop = dma_iproc_pax_transfer_stop, diff --git a/drivers/dma/dma_max32.c b/drivers/dma/dma_max32.c index 100c14629bf18..79bbb7b95ed33 100644 --- a/drivers/dma/dma_max32.c +++ b/drivers/dma/dma_max32.c @@ -318,7 +318,7 @@ static int max32_dma_init(const struct device *dev) return 0; } -static const struct dma_driver_api max32_dma_driver_api = { +static DEVICE_API(dma, max32_dma_driver_api) = { .config = max32_dma_config, .reload = max32_dma_reload, .start = max32_dma_start, diff --git a/drivers/dma/dma_mchp_xec.c b/drivers/dma/dma_mchp_xec.c index 699aa5deef815..e54efd1526096 100644 --- a/drivers/dma/dma_mchp_xec.c +++ b/drivers/dma/dma_mchp_xec.c @@ -644,7 +644,7 @@ static bool dma_xec_chan_filter(const struct device *dev, int ch, void *filter_p } /* API - HW does not stupport suspend/resume */ -static const struct dma_driver_api dma_xec_api = { +static DEVICE_API(dma, dma_xec_api) = { .config = dma_xec_configure, .reload = dma_xec_reload, .start = dma_xec_start, diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index 5c9cbcf40df7a..ab818cd18ec50 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -91,7 +91,7 @@ struct dma_mcux_channel_transfer_edma_settings { /* These parameters are for cyclic mode only. * Next empty TCD idx which can be used for transfer */ - volatile int8_t write_idx; + volatile uint8_t write_idx; /* How many TCDs in TCD pool is emtpy(can be used to write transfer parameters) */ volatile uint8_t empty_tcds; }; @@ -277,6 +277,28 @@ static void dma_mcux_edma_error_irq_handler(const struct device *dev) } #endif +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(channels_shared_irq_mask) +static void dma_mcux_edma_multi_channels_irq_handler(const struct device *dev, uint32_t idx, + uint32_t *buf, uint32_t mask_width) +{ + uint32_t *num = &buf[mask_width * idx]; + uint32_t count = 0; + + for (int _i = 0; _i < mask_width; _i++) { + uint32_t value = (*num); + + while (value > 0) { + if ((value & 0x1) == 1) { + dma_mcux_edma_irq_handler(dev, count); + } + value = value >> 1; + count++; + } + num++; + } +} +#endif + /* Configure a channel */ static int dma_mcux_edma_configure(const struct device *dev, uint32_t channel, struct dma_config *config) @@ -613,6 +635,7 @@ static int dma_mcux_edma_reload(const struct device *dev, uint32_t channel, edma_tcd_t *tcd = NULL; edma_tcd_t *pre_tcd = NULL; uint32_t hw_id, sw_id; + uint8_t pre_idx; /* Lock the channel configuration */ const unsigned int key = irq_lock(); @@ -634,10 +657,14 @@ static int dma_mcux_edma_reload(const struct device *dev, uint32_t channel, /* Convert size into major loop count */ size = size / data->transfer_settings.dest_data_size; + /* Previous TCD index in circular list */ + pre_idx = data->transfer_settings.write_idx - 1; + if (pre_idx >= CONFIG_DMA_TCD_QUEUE_SIZE) + pre_idx = CONFIG_DMA_TCD_QUEUE_SIZE - 1; + /* Configure a TCD for the transfer */ tcd = &(DEV_CFG(dev)->tcdpool[channel][data->transfer_settings.write_idx]); - pre_tcd = &(DEV_CFG(dev)->tcdpool[channel][(data->transfer_settings.write_idx - 1) % - CONFIG_DMA_TCD_QUEUE_SIZE]); + pre_tcd = &(DEV_CFG(dev)->tcdpool[channel][pre_idx]); EDMA_TCD_SADDR(tcd, kEDMA_EDMA4Flag) = src; EDMA_TCD_DADDR(tcd, kEDMA_EDMA4Flag) = dst; @@ -799,7 +826,7 @@ static bool dma_mcux_edma_channel_filter(const struct device *dev, return true; } -static const struct dma_driver_api dma_mcux_edma_api = { +static DEVICE_API(dma, dma_mcux_edma_api) = { .reload = dma_mcux_edma_reload, .config = dma_mcux_edma_configure, .start = dma_mcux_edma_start, @@ -856,10 +883,22 @@ static int dma_mcux_edma_init(const struct device *dev) irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \ } +#define EDMA_CHANNELS_MASK(n) static uint32_t edma_channel_mask_##n[] = \ + DT_PROP(DT_DRV_INST(n), channels_shared_irq_mask); + +#define GET_EDMA_CHANNEL_SHARED_IRQ_MASK_WIDTH(n) \ + (DT_INST_PROP(n, dma_channels) / 32) + +#define EDMA_CHANNELS_SHARED_REGISTER_IN_IRQ(dev, idx, n) \ + dma_mcux_edma_multi_channels_irq_handler(dev, idx, edma_channel_mask_##n, \ + GET_EDMA_CHANNEL_SHARED_IRQ_MASK_WIDTH(n)); + #define DMA_MCUX_EDMA_IRQ_DEFINE(idx, n) \ static void dma_mcux_edma_##n##_irq_##idx(const struct device *dev) \ { \ - dma_mcux_edma_irq_handler(dev, idx); \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, channels_shared_irq_mask), \ + (EDMA_CHANNELS_SHARED_REGISTER_IN_IRQ(dev, idx, n)), \ + (dma_mcux_edma_irq_handler(dev, idx);)) \ \ IF_ENABLED(UTIL_BOOL(DT_INST_PROP(n, irq_shared_offset)), \ (dma_mcux_edma_irq_handler(dev, \ @@ -872,6 +911,8 @@ static int dma_mcux_edma_init(const struct device *dev) IRQ_CONFIG(n, idx, dma_mcux_edma_##n##_irq_##idx) #define DMA_MCUX_EDMA_CONFIG_FUNC(n) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(n, channels_shared_irq_mask), \ + (EDMA_CHANNELS_MASK(n))) \ LISTIFY(NUM_IRQS_WITHOUT_ERROR_IRQ(n), DMA_MCUX_EDMA_IRQ_DEFINE, (), n) \ static void dma_imx_config_func_##n(const struct device *dev) \ { \ diff --git a/drivers/dma/dma_mcux_lpc.c b/drivers/dma/dma_mcux_lpc.c index 3ef75ac11767a..fde97055284cf 100644 --- a/drivers/dma/dma_mcux_lpc.c +++ b/drivers/dma/dma_mcux_lpc.c @@ -854,7 +854,7 @@ static int dma_mcux_lpc_init(const struct device *dev) return 0; } -static const struct dma_driver_api dma_mcux_lpc_api = { +static DEVICE_API(dma, dma_mcux_lpc_api) = { .config = dma_mcux_lpc_configure, .start = dma_mcux_lpc_start, .stop = dma_mcux_lpc_stop, diff --git a/drivers/dma/dma_mcux_pxp.c b/drivers/dma/dma_mcux_pxp.c index 64f3154807c32..dadfa5c03cf56 100644 --- a/drivers/dma/dma_mcux_pxp.c +++ b/drivers/dma/dma_mcux_pxp.c @@ -183,7 +183,7 @@ static int dma_mcux_pxp_start(const struct device *dev, uint32_t channel) return 0; } -static const struct dma_driver_api dma_mcux_pxp_api = { +static DEVICE_API(dma, dma_mcux_pxp_api) = { .config = dma_mcux_pxp_configure, .start = dma_mcux_pxp_start, }; diff --git a/drivers/dma/dma_mcux_smartdma.c b/drivers/dma/dma_mcux_smartdma.c index 86663dd02e8b7..af7fb600be994 100644 --- a/drivers/dma/dma_mcux_smartdma.c +++ b/drivers/dma/dma_mcux_smartdma.c @@ -129,7 +129,7 @@ void dma_smartdma_install_fw(const struct device *dev, uint8_t *firmware, SMARTDMA_InstallFirmware((uint32_t)config->smartdma_progs, firmware, len); } -static const struct dma_driver_api dma_mcux_smartdma_api = { +static DEVICE_API(dma, dma_mcux_smartdma_api) = { .config = dma_mcux_smartdma_configure, .start = dma_mcux_smartdma_start, .stop = dma_mcux_smartdma_stop, diff --git a/drivers/dma/dma_nios2_msgdma.c b/drivers/dma/dma_nios2_msgdma.c index ccc7b1e58ad17..21b86d31c620f 100644 --- a/drivers/dma/dma_nios2_msgdma.c +++ b/drivers/dma/dma_nios2_msgdma.c @@ -197,7 +197,7 @@ static int nios2_msgdma_transfer_stop(const struct device *dev, return status; } -static const struct dma_driver_api nios2_msgdma_driver_api = { +static DEVICE_API(dma, nios2_msgdma_driver_api) = { .config = nios2_msgdma_config, .start = nios2_msgdma_transfer_start, .stop = nios2_msgdma_transfer_stop, diff --git a/drivers/dma/dma_nxp_edma.c b/drivers/dma/dma_nxp_edma.c index 7d4f6e8b44958..a9c134a37adc2 100644 --- a/drivers/dma/dma_nxp_edma.c +++ b/drivers/dma/dma_nxp_edma.c @@ -6,6 +6,8 @@ #include "dma_nxp_edma.h" +#define EDMA_ACTIVE_TIMEOUT 50 + /* TODO list: * 1) Support for requesting a specific channel. * 2) Support for checking if DMA transfer is pending when attempting config. (?) @@ -28,6 +30,11 @@ static void edma_isr(const void *parameter) cfg = chan->dev->config; data = chan->dev->data; + if (chan->state == CHAN_STATE_RELEASING || chan->state == CHAN_STATE_INIT) { + /* skip, not safe to access channel register space */ + return; + } + if (!EDMA_ChannelRegRead(data->hal_cfg, chan->id, EDMA_TCD_CH_INT)) { /* skip, interrupt was probably triggered by another channel */ return; @@ -270,11 +277,11 @@ static int edma_config(const struct device *dev, uint32_t chan_id, chan->cyclic_buffer = false; } - /* change channel's state to CONFIGURED */ - ret = channel_change_state(chan, CHAN_STATE_CONFIGURED); - if (ret < 0) { - LOG_ERR("failed to change channel %d state to CONFIGURED", chan_id); - return ret; + /* check if transition to CONFIGURED is allowed */ + if (!channel_allows_transition(chan, CHAN_STATE_CONFIGURED)) { + LOG_ERR("chan %d transition from %d to CONFIGURED not allowed", + chan_id, chan->state); + return -EPERM; } ret = get_transfer_type(dma_cfg->channel_direction, &transfer_type); @@ -335,6 +342,8 @@ static int edma_config(const struct device *dev, uint32_t chan_id, /* dump register status - for debugging purposes */ edma_dump_channel_registers(data, chan_id); + chan->state = CHAN_STATE_CONFIGURED; + return 0; } @@ -389,7 +398,6 @@ static int edma_suspend(const struct device *dev, uint32_t chan_id) struct edma_data *data; const struct edma_config *cfg; struct edma_channel *chan; - int ret; data = dev->data; cfg = dev->config; @@ -403,11 +411,11 @@ static int edma_suspend(const struct device *dev, uint32_t chan_id) edma_dump_channel_registers(data, chan_id); - /* change channel's state to SUSPENDED */ - ret = channel_change_state(chan, CHAN_STATE_SUSPENDED); - if (ret < 0) { - LOG_ERR("failed to change channel %d state to SUSPENDED", chan_id); - return ret; + /* check if transition to SUSPENDED is allowed */ + if (!channel_allows_transition(chan, CHAN_STATE_SUSPENDED)) { + LOG_ERR("chan %d transition from %d to SUSPENDED not allowed", + chan_id, chan->state); + return -EPERM; } LOG_DBG("suspending channel %u", chan_id); @@ -416,6 +424,8 @@ static int edma_suspend(const struct device *dev, uint32_t chan_id) EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR, 0, EDMA_TCD_CH_CSR_ERQ_MASK); + chan->state = CHAN_STATE_SUSPENDED; + return 0; } @@ -439,11 +449,11 @@ static int edma_stop(const struct device *dev, uint32_t chan_id) prev_state = chan->state; - /* change channel's state to STOPPED */ - ret = channel_change_state(chan, CHAN_STATE_STOPPED); - if (ret < 0) { - LOG_ERR("failed to change channel %d state to STOPPED", chan_id); - return ret; + /* check if transition to STOPPED is allowed */ + if (!channel_allows_transition(chan, CHAN_STATE_STOPPED)) { + LOG_ERR("chan %d transition from %d to STOPPED not allowed", + chan_id, chan->state); + return -EPERM; } LOG_DBG("stopping channel %u", chan_id); @@ -459,11 +469,8 @@ static int edma_stop(const struct device *dev, uint32_t chan_id) /* disable HW requests */ EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR, 0, EDMA_TCD_CH_CSR_ERQ_MASK); - out_release_channel: - irq_disable(chan->irq); - /* clear the channel MUX so that it can used by a different peripheral. * * note: because the channel is released during dma_stop() that means @@ -482,6 +489,8 @@ static int edma_stop(const struct device *dev, uint32_t chan_id) edma_dump_channel_registers(data, chan_id); + chan->state = CHAN_STATE_STOPPED; + return 0; } @@ -490,7 +499,6 @@ static int edma_start(const struct device *dev, uint32_t chan_id) struct edma_data *data; const struct edma_config *cfg; struct edma_channel *chan; - int ret; data = dev->data; cfg = dev->config; @@ -502,21 +510,21 @@ static int edma_start(const struct device *dev, uint32_t chan_id) return -EINVAL; } - /* change channel's state to STARTED */ - ret = channel_change_state(chan, CHAN_STATE_STARTED); - if (ret < 0) { - LOG_ERR("failed to change channel %d state to STARTED", chan_id); - return ret; + /* check if transition to STARTED is allowed */ + if (!channel_allows_transition(chan, CHAN_STATE_STARTED)) { + LOG_ERR("chan %d transition from %d to STARTED not allowed", + chan_id, chan->state); + return -EPERM; } LOG_DBG("starting channel %u", chan_id); - irq_enable(chan->irq); - /* enable HW requests */ EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR, EDMA_TCD_CH_CSR_ERQ_MASK, 0); + chan->state = CHAN_STATE_STARTED; + return 0; } @@ -577,22 +585,83 @@ static int edma_get_attribute(const struct device *dev, uint32_t type, uint32_t static bool edma_channel_filter(const struct device *dev, int chan_id, void *param) { - int *requested_channel; + struct edma_channel *chan; + int ret; if (!param) { return false; } - requested_channel = param; + if (*(int *)param != chan_id) { + return false; + } + + chan = lookup_channel(dev, chan_id); + if (!chan) { + return false; + } - if (*requested_channel == chan_id && lookup_channel(dev, chan_id)) { - return true; + if (chan->pd_dev) { + ret = pm_device_runtime_get(chan->pd_dev); + if (ret < 0) { + LOG_ERR("failed to PM get channel %d PD dev: %d", + chan_id, ret); + return false; + } + } + + irq_enable(chan->irq); + + return true; +} + +static void edma_channel_release(const struct device *dev, uint32_t chan_id) +{ + struct edma_channel *chan; + struct edma_data *data; + int ret; + + chan = lookup_channel(dev, chan_id); + if (!chan) { + return; + } + + data = dev->data; + + if (!channel_allows_transition(chan, CHAN_STATE_RELEASING)) { + LOG_ERR("chan %d transition from %d to RELEASING not allowed", + chan_id, chan->state); + return; + } + + /* channel needs to be INACTIVE before transitioning */ + if (!WAIT_FOR(!EDMA_CHAN_IS_ACTIVE(data, chan), + EDMA_ACTIVE_TIMEOUT, k_busy_wait(1))) { + LOG_ERR("timed out while waiting for chan %d to become inactive", + chan->id); + return; + } + + /* start the process of disabling IRQ and PD */ + chan->state = CHAN_STATE_RELEASING; + +#ifdef CONFIG_NXP_IRQSTEER + irq_disable(chan->irq); +#endif /* CONFIG_NXP_IRQSTEER */ + + if (chan->pd_dev) { + ret = pm_device_runtime_put(chan->pd_dev); + if (ret < 0) { + LOG_ERR("failed to PM put channel %d PD dev: %d", + chan_id, ret); + } } - return false; + /* done, proceed with next state */ + chan->state = CHAN_STATE_INIT; } -static const struct dma_driver_api edma_api = { +static DEVICE_API(dma, edma_api) = { .reload = edma_reload, .config = edma_config, .start = edma_start, @@ -602,6 +671,7 @@ static const struct dma_driver_api edma_api = { .get_status = edma_get_status, .get_attribute = edma_get_attribute, .chan_filter = edma_channel_filter, + .chan_release = edma_channel_release, }; static edma_config_t *edma_hal_cfg_get(const struct edma_config *cfg) diff --git a/drivers/dma/dma_nxp_edma.h b/drivers/dma/dma_nxp_edma.h index f45740d981d21..52f65a76938fe 100644 --- a/drivers/dma/dma_nxp_edma.h +++ b/drivers/dma/dma_nxp_edma.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "fsl_edma_soc_rev2.h" @@ -54,12 +56,18 @@ LOG_MODULE_REGISTER(nxp_edma); 0, edma_isr, \ &channels_##inst[idx], 0) +#define _EDMA_CHANNEL_PD_DEVICE_OR_NULL(idx, inst) \ + COND_CODE_1(CONFIG_PM_DEVICE_POWER_DOMAIN, \ + (DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE_BY_IDX(inst, power_domains, idx))), \ + (NULL)) + /* used to declare a struct edma_channel by the non-explicit macro suite */ #define _EDMA_CHANNEL_DECLARE(idx, inst) \ { \ .id = DT_INST_PROP_BY_IDX(inst, valid_channels, idx), \ .dev = DEVICE_DT_INST_GET(inst), \ .irq = DT_INST_IRQN_BY_IDX(inst, idx), \ + .pd_dev = _EDMA_CHANNEL_PD_DEVICE_OR_NULL(idx, inst), \ } /* used to declare a struct edma_channel by the explicit macro suite */ @@ -68,6 +76,7 @@ LOG_MODULE_REGISTER(nxp_edma); .id = idx, \ .dev = DEVICE_DT_INST_GET(inst), \ .irq = DT_INST_IRQN_BY_IDX(inst, idx), \ + .pd_dev = _EDMA_CHANNEL_PD_DEVICE_OR_NULL(idx, inst), \ } /* used to create an array of channel IDs via the valid-channels property */ @@ -160,6 +169,10 @@ LOG_MODULE_REGISTER(nxp_edma); edma_chan_cyclic_produce(chan, size) :\ edma_chan_cyclic_consume(chan, size)) +#define EDMA_CHAN_IS_ACTIVE(data, chan)\ + (EDMA_ChannelRegRead((data)->hal_cfg, (chan)->id, EDMA_TCD_CH_CSR) &\ + EDMA_TCD_CH_CSR_ACTIVE_MASK) + enum channel_type { CHAN_TYPE_CONSUMER = 0, CHAN_TYPE_PRODUCER, @@ -171,6 +184,7 @@ enum channel_state { CHAN_STATE_STARTED, CHAN_STATE_STOPPED, CHAN_STATE_SUSPENDED, + CHAN_STATE_RELEASING, }; struct edma_channel { @@ -178,6 +192,8 @@ struct edma_channel { uint32_t id; /* pointer to device representing the EDMA instance, used by edma_isr */ const struct device *dev; + /* channel power domain device */ + const struct device *pd_dev; /* current state of the channel */ enum channel_state state; /* type of the channel (PRODUCER/CONSUMER) - only applicable to cyclic @@ -221,52 +237,49 @@ struct edma_config { bool contiguous_channels; }; -static inline int channel_change_state(struct edma_channel *chan, - enum channel_state next) +static inline bool channel_allows_transition(struct edma_channel *chan, + enum channel_state next) { enum channel_state prev = chan->state; - LOG_DBG("attempting to change state from %d to %d for channel %d", prev, next, chan->id); - /* validate transition */ switch (prev) { case CHAN_STATE_INIT: if (next != CHAN_STATE_CONFIGURED) { - return -EPERM; + return false; } break; case CHAN_STATE_CONFIGURED: if (next != CHAN_STATE_STARTED && - next != CHAN_STATE_CONFIGURED) { - return -EPERM; + next != CHAN_STATE_CONFIGURED && + next != CHAN_STATE_RELEASING) { + return false; } break; case CHAN_STATE_STARTED: if (next != CHAN_STATE_STOPPED && next != CHAN_STATE_SUSPENDED) { - return -EPERM; + return false; } break; case CHAN_STATE_STOPPED: - if (next != CHAN_STATE_CONFIGURED) { - return -EPERM; + if (next != CHAN_STATE_CONFIGURED && + next != CHAN_STATE_RELEASING) { + return false; } break; case CHAN_STATE_SUSPENDED: if (next != CHAN_STATE_STARTED && next != CHAN_STATE_STOPPED) { - return -EPERM; + return false; } break; default: LOG_ERR("invalid channel previous state: %d", prev); - return -EINVAL; + return false; } - /* transition OK, proceed */ - chan->state = next; - - return 0; + return true; } static inline int get_transfer_type(enum dma_channel_direction dir, uint32_t *type) diff --git a/drivers/dma/dma_nxp_sdma.c b/drivers/dma/dma_nxp_sdma.c new file mode 100644 index 0000000000000..380a9411c9e36 --- /dev/null +++ b/drivers/dma/dma_nxp_sdma.c @@ -0,0 +1,484 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include "fsl_sdma.h" + +LOG_MODULE_REGISTER(nxp_sdma); + +#define DMA_NXP_SDMA_BD_COUNT 2 +#define DMA_NXP_SDMA_CHAN_DEFAULT_PRIO 4 + +#define DT_DRV_COMPAT nxp_sdma + +AT_NONCACHEABLE_SECTION_ALIGN(static sdma_context_data_t + sdma_contexts[FSL_FEATURE_SDMA_MODULE_CHANNEL], 4); + +struct sdma_dev_cfg { + SDMAARM_Type *base; + void (*irq_config)(void); +}; + +struct sdma_channel_data { + sdma_handle_t handle; + sdma_transfer_config_t transfer_cfg; + sdma_peripheral_t peripheral; + uint32_t direction; + uint32_t index; + const struct device *dev; + sdma_buffer_descriptor_t *bd_pool; /*pre-allocated list of BD used for transfer */ + uint32_t bd_count; /* number of bd */ + uint32_t capacity; /* total transfer capacity for this channel */ + struct dma_config *dma_cfg; + uint32_t event_source; /* DMA REQ number that trigger this channel */ + struct dma_status stat; + + void *arg; /* argument passed to user-defined DMA callback */ + dma_callback_t cb; /* user-defined callback for DMA transfer completion */ +}; + +struct sdma_dev_data { + struct dma_context dma_ctx; + atomic_t *channels_atomic; + struct sdma_channel_data chan[FSL_FEATURE_SDMA_MODULE_CHANNEL]; + sdma_buffer_descriptor_t bd_pool[FSL_FEATURE_SDMA_MODULE_CHANNEL][DMA_NXP_SDMA_BD_COUNT] + __aligned(64); +}; + +static int dma_nxp_sdma_init_stat(struct sdma_channel_data *chan_data) +{ + chan_data->stat.read_position = 0; + chan_data->stat.write_position = 0; + + switch (chan_data->direction) { + case MEMORY_TO_PERIPHERAL: + /* buffer is full */ + chan_data->stat.pending_length = chan_data->capacity; + chan_data->stat.free = 0; + break; + case PERIPHERAL_TO_MEMORY: + /* buffer is empty */ + chan_data->stat.pending_length = 0; + chan_data->stat.free = chan_data->capacity; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int dma_nxp_sdma_consume(struct sdma_channel_data *chan_data, uint32_t bytes) +{ + if (bytes > chan_data->stat.pending_length) + return -EINVAL; + + chan_data->stat.read_position += bytes; + chan_data->stat.read_position %= chan_data->capacity; + + if (chan_data->stat.read_position > chan_data->stat.write_position) + chan_data->stat.free = chan_data->stat.read_position - + chan_data->stat.write_position; + else + chan_data->stat.free = chan_data->capacity - + (chan_data->stat.write_position - chan_data->stat.read_position); + + chan_data->stat.pending_length = chan_data->capacity - chan_data->stat.free; + + return 0; +} + +static int dma_nxp_sdma_produce(struct sdma_channel_data *chan_data, uint32_t bytes) +{ + if (bytes > chan_data->stat.free) + return -EINVAL; + + chan_data->stat.write_position += bytes; + chan_data->stat.write_position %= chan_data->capacity; + + if (chan_data->stat.write_position > chan_data->stat.read_position) + chan_data->stat.pending_length = chan_data->stat.write_position - + chan_data->stat.read_position; + else + chan_data->stat.pending_length = chan_data->capacity - + (chan_data->stat.read_position - chan_data->stat.write_position); + + chan_data->stat.free = chan_data->capacity - chan_data->stat.pending_length; + + return 0; +} + +static void dma_nxp_sdma_isr(const void *data) +{ + uint32_t val; + uint32_t i = 1; + struct sdma_channel_data *chan_data; + struct device *dev = (struct device *)data; + struct sdma_dev_data *dev_data = dev->data; + const struct sdma_dev_cfg *dev_cfg = dev->config; + + /* Clear channel 0 */ + SDMA_ClearChannelInterruptStatus(dev_cfg->base, 1U); + + /* Ignore channel 0, is used only for download */ + val = SDMA_GetChannelInterruptStatus(dev_cfg->base) >> 1U; + while (val) { + if ((val & 0x1) != 0) { + chan_data = &dev_data->chan[i]; + SDMA_ClearChannelInterruptStatus(dev_cfg->base, 1 << i); + SDMA_HandleIRQ(&chan_data->handle); + + if (chan_data->cb) + chan_data->cb(chan_data->dev, chan_data->arg, i, DMA_STATUS_BLOCK); + } + i++; + val >>= 1; + } +} + +void sdma_set_transfer_type(struct dma_config *config, sdma_transfer_type_t *type) +{ + switch (config->channel_direction) { + case MEMORY_TO_MEMORY: + *type = kSDMA_MemoryToMemory; + break; + case MEMORY_TO_PERIPHERAL: + *type = kSDMA_MemoryToPeripheral; + break; + case PERIPHERAL_TO_MEMORY: + *type = kSDMA_PeripheralToMemory; + break; + case PERIPHERAL_TO_PERIPHERAL: + *type = kSDMA_PeripheralToPeripheral; + break; + default: + LOG_ERR("%s: channel direction not supported %d", __func__, + config->channel_direction); + return; + } + LOG_DBG("%s: dir %d type = %d", __func__, config->channel_direction, *type); +} + +int sdma_set_peripheral_type(struct dma_config *config, sdma_peripheral_t *type) +{ + switch (config->dma_slot) { + case kSDMA_PeripheralNormal_SP: + case kSDMA_PeripheralMultiFifoPDM: + *type = config->dma_slot; + break; + default: + return -EINVAL; + } + + return 0; +} + +void dma_nxp_sdma_callback(sdma_handle_t *handle, void *userData, bool TransferDone, + uint32_t bdIndex) +{ + const struct sdma_dev_cfg *dev_cfg; + struct sdma_channel_data *chan_data = userData; + sdma_buffer_descriptor_t *bd; + int xfer_size; + + dev_cfg = chan_data->dev->config; + + xfer_size = chan_data->capacity / chan_data->bd_count; + + switch (chan_data->direction) { + case MEMORY_TO_PERIPHERAL: + dma_nxp_sdma_consume(chan_data, xfer_size); + break; + case PERIPHERAL_TO_MEMORY: + dma_nxp_sdma_produce(chan_data, xfer_size); + break; + default: + break; + } + + bd = &chan_data->bd_pool[bdIndex]; + bd->status |= (uint8_t)kSDMA_BDStatusDone; + + SDMA_StartChannelSoftware(dev_cfg->base, chan_data->index); +} + +static int dma_nxp_sdma_channel_init(const struct device *dev, uint32_t channel) +{ + const struct sdma_dev_cfg *dev_cfg = dev->config; + struct sdma_dev_data *dev_data = dev->data; + struct sdma_channel_data *chan_data; + + chan_data = &dev_data->chan[channel]; + SDMA_CreateHandle(&chan_data->handle, dev_cfg->base, channel, &sdma_contexts[channel]); + + SDMA_SetCallback(&chan_data->handle, dma_nxp_sdma_callback, chan_data); + + return 0; +} + +static void dma_nxp_sdma_setup_bd(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + struct sdma_dev_data *dev_data = dev->data; + struct sdma_channel_data *chan_data; + sdma_buffer_descriptor_t *crt_bd; + struct dma_block_config *block_cfg; + int i; + + chan_data = &dev_data->chan[channel]; + + /* initialize bd pool */ + chan_data->bd_pool = &dev_data->bd_pool[channel][0]; + chan_data->bd_count = config->block_count; + + memset(chan_data->bd_pool, 0, sizeof(sdma_buffer_descriptor_t) * chan_data->bd_count); + SDMA_InstallBDMemory(&chan_data->handle, chan_data->bd_pool, chan_data->bd_count); + + crt_bd = chan_data->bd_pool; + block_cfg = config->head_block; + + for (i = 0; i < config->block_count; i++) { + bool is_last = false; + bool is_wrap = false; + + if (i == config->block_count - 1) { + is_last = true; + is_wrap = true; + } + + SDMA_ConfigBufferDescriptor(crt_bd, + block_cfg->source_address, block_cfg->dest_address, + config->source_data_size, block_cfg->block_size, + is_last, true, is_wrap, chan_data->transfer_cfg.type); + + chan_data->capacity += block_cfg->block_size; + block_cfg = block_cfg->next_block; + crt_bd++; + } +} + +static int dma_nxp_sdma_config(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + struct sdma_dev_data *dev_data = dev->data; + struct sdma_channel_data *chan_data; + struct dma_block_config *block_cfg; + int ret; + + if (channel >= FSL_FEATURE_SDMA_MODULE_CHANNEL) { + LOG_ERR("sdma_config() invalid channel %d", channel); + return -EINVAL; + } + + dma_nxp_sdma_channel_init(dev, channel); + + chan_data = &dev_data->chan[channel]; + chan_data->dev = dev; + chan_data->direction = config->channel_direction; + + chan_data->cb = config->dma_callback; + chan_data->arg = config->user_data; + + sdma_set_transfer_type(config, &chan_data->transfer_cfg.type); + + ret = sdma_set_peripheral_type(config, &chan_data->peripheral); + if (ret < 0) { + LOG_ERR("%s: failed to set peripheral type", __func__); + return ret; + } + + dma_nxp_sdma_setup_bd(dev, channel, config); + ret = dma_nxp_sdma_init_stat(chan_data); + if (ret < 0) { + LOG_ERR("%s: failed to init stat", __func__); + return ret; + } + + block_cfg = config->head_block; + + /* prepare first block for transfer ...*/ + SDMA_PrepareTransfer(&chan_data->transfer_cfg, + block_cfg->source_address, + block_cfg->dest_address, + config->source_data_size, config->dest_data_size, + /* watermark = */64, + block_cfg->block_size, chan_data->event_source, + chan_data->peripheral, chan_data->transfer_cfg.type); + + /*... and submit it to SDMA engine. + * Note that SDMA transfer is later manually started by the dma_nxp_sdma_start() + */ + chan_data->transfer_cfg.isEventIgnore = false; + chan_data->transfer_cfg.isSoftTriggerIgnore = false; + SDMA_SubmitTransfer(&chan_data->handle, &chan_data->transfer_cfg); + + return 0; +} + +static int dma_nxp_sdma_start(const struct device *dev, uint32_t channel) +{ + const struct sdma_dev_cfg *dev_cfg = dev->config; + struct sdma_dev_data *dev_data = dev->data; + struct sdma_channel_data *chan_data; + + if (channel >= FSL_FEATURE_SDMA_MODULE_CHANNEL) { + LOG_ERR("%s: invalid channel %d", __func__, channel); + return -EINVAL; + } + + chan_data = &dev_data->chan[channel]; + + SDMA_SetChannelPriority(dev_cfg->base, channel, DMA_NXP_SDMA_CHAN_DEFAULT_PRIO); + SDMA_StartChannelSoftware(dev_cfg->base, channel); + + return 0; +} + +static int dma_nxp_sdma_stop(const struct device *dev, uint32_t channel) +{ + struct sdma_dev_data *dev_data = dev->data; + struct sdma_channel_data *chan_data; + + if (channel >= FSL_FEATURE_SDMA_MODULE_CHANNEL) { + LOG_ERR("%s: invalid channel %d", __func__, channel); + return -EINVAL; + } + + chan_data = &dev_data->chan[channel]; + + SDMA_StopTransfer(&chan_data->handle); + return 0; +} + +static int dma_nxp_sdma_get_status(const struct device *dev, uint32_t channel, + struct dma_status *stat) +{ + struct sdma_dev_data *dev_data = dev->data; + struct sdma_channel_data *chan_data; + + chan_data = &dev_data->chan[channel]; + + stat->free = chan_data->stat.free; + stat->pending_length = chan_data->stat.pending_length; + + return 0; +} + +static int dma_nxp_sdma_reload(const struct device *dev, uint32_t channel, uint32_t src, + uint32_t dst, size_t size) +{ + struct sdma_dev_data *dev_data = dev->data; + struct sdma_channel_data *chan_data; + + chan_data = &dev_data->chan[channel]; + + if (!size) + return 0; + + if (chan_data->direction == MEMORY_TO_PERIPHERAL) + dma_nxp_sdma_produce(chan_data, size); + else + dma_nxp_sdma_consume(chan_data, size); + + return 0; +} + +static int dma_nxp_sdma_get_attribute(const struct device *dev, uint32_t type, uint32_t *val) +{ + switch (type) { + case DMA_ATTR_BUFFER_SIZE_ALIGNMENT: + *val = 4; + break; + case DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT: + *val = 128; /* should be dcache_align */ + break; + case DMA_ATTR_MAX_BLOCK_COUNT: + *val = DMA_NXP_SDMA_BD_COUNT; + break; + default: + LOG_ERR("invalid attribute type: %d", type); + return -EINVAL; + } + return 0; +} + +static bool sdma_channel_filter(const struct device *dev, int chan_id, void *param) +{ + struct sdma_dev_data *dev_data = dev->data; + + /* chan 0 is reserved for boot channel */ + if (chan_id == 0) + return false; + + if (chan_id >= FSL_FEATURE_SDMA_MODULE_CHANNEL) + return false; + + dev_data->chan[chan_id].event_source = *((int *)param); + dev_data->chan[chan_id].index = chan_id; + + return true; +} + +static DEVICE_API(dma, sdma_api) = { + .reload = dma_nxp_sdma_reload, + .config = dma_nxp_sdma_config, + .start = dma_nxp_sdma_start, + .stop = dma_nxp_sdma_stop, + .suspend = dma_nxp_sdma_stop, + .resume = dma_nxp_sdma_start, + .get_status = dma_nxp_sdma_get_status, + .get_attribute = dma_nxp_sdma_get_attribute, + .chan_filter = sdma_channel_filter, +}; + +static int dma_nxp_sdma_init(const struct device *dev) +{ + struct sdma_dev_data *data = dev->data; + const struct sdma_dev_cfg *cfg = dev->config; + sdma_config_t defconfig; + + data->dma_ctx.magic = DMA_MAGIC; + data->dma_ctx.dma_channels = FSL_FEATURE_SDMA_MODULE_CHANNEL; + data->dma_ctx.atomic = data->channels_atomic; + + SDMA_GetDefaultConfig(&defconfig); + defconfig.ratio = kSDMA_ARMClockFreq; + + SDMA_Init(cfg->base, &defconfig); + + /* configure interrupts */ + cfg->irq_config(); + + return 0; +} + +#define DMA_NXP_SDMA_INIT(inst) \ + static ATOMIC_DEFINE(dma_nxp_sdma_channels_atomic_##inst, \ + FSL_FEATURE_SDMA_MODULE_CHANNEL); \ + static struct sdma_dev_data sdma_data_##inst = { \ + .channels_atomic = dma_nxp_sdma_channels_atomic_##inst, \ + }; \ + static void dma_nxp_sdma_##inst_irq_config(void); \ + static const struct sdma_dev_cfg sdma_cfg_##inst = { \ + .base = (SDMAARM_Type *)DT_INST_REG_ADDR(inst), \ + .irq_config = dma_nxp_sdma_##inst_irq_config, \ + }; \ + static void dma_nxp_sdma_##inst_irq_config(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(inst), \ + DT_INST_IRQ_(inst, priority), \ + dma_nxp_sdma_isr, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQN(inst)); \ + } \ + DEVICE_DT_INST_DEFINE(inst, &dma_nxp_sdma_init, NULL, \ + &sdma_data_##inst, &sdma_cfg_##inst, \ + PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, \ + &sdma_api); \ + +DT_INST_FOREACH_STATUS_OKAY(DMA_NXP_SDMA_INIT); diff --git a/drivers/dma/dma_nxp_sof_host_dma.c b/drivers/dma/dma_nxp_sof_host_dma.c index baafd69551eca..065107f7003b9 100644 --- a/drivers/dma/dma_nxp_sof_host_dma.c +++ b/drivers/dma/dma_nxp_sof_host_dma.c @@ -271,7 +271,7 @@ static int sof_host_dma_get_attribute(const struct device *dev, uint32_t type, u return 0; } -static const struct dma_driver_api sof_host_dma_api = { +static DEVICE_API(dma, sof_host_dma_api) = { .reload = sof_host_dma_reload, .config = sof_host_dma_config, .start = sof_host_dma_start, diff --git a/drivers/dma/dma_pl330.c b/drivers/dma/dma_pl330.c index 5bc161c512196..844c4c7657215 100644 --- a/drivers/dma/dma_pl330.c +++ b/drivers/dma/dma_pl330.c @@ -565,7 +565,7 @@ static int dma_pl330_initialize(const struct device *dev) return 0; } -static const struct dma_driver_api pl330_driver_api = { +static DEVICE_API(dma, pl330_driver_api) = { .config = dma_pl330_configure, .start = dma_pl330_transfer_start, .stop = dma_pl330_transfer_stop, diff --git a/drivers/dma/dma_rpi_pico.c b/drivers/dma/dma_rpi_pico.c index 581116d1ebae8..9aa79de374895 100644 --- a/drivers/dma/dma_rpi_pico.c +++ b/drivers/dma/dma_rpi_pico.c @@ -10,7 +10,11 @@ #include #include #include -#include +#if defined(CONFIG_SOC_SERIES_RP2040) +#include +#elif defined(CONFIG_SOC_SERIES_RP2350) +#include +#endif #include @@ -332,7 +336,7 @@ static void dma_rpi_pico_isr(const struct device *dev) } } -static const struct dma_driver_api dma_rpi_pico_driver_api = { +static DEVICE_API(dma, dma_rpi_pico_driver_api) = { .config = dma_rpi_pico_config, .reload = dma_rpi_pico_reload, .start = dma_rpi_pico_start, diff --git a/drivers/dma/dma_sam0.c b/drivers/dma/dma_sam0.c index fde5a250e84ec..359162290c0b2 100644 --- a/drivers/dma/dma_sam0.c +++ b/drivers/dma/dma_sam0.c @@ -413,6 +413,15 @@ static int dma_sam0_init(const struct device *dev) PM->APBBMASK.bit.DMAC_ = 1; #endif + /* Reset the DMA controller */ + DMAC->CTRL.bit.DMAENABLE = 0; +#ifdef DMAC_CTRL_CRCENABLE + DMAC->CTRL.bit.CRCENABLE = 0; +#endif + DMAC->CTRL.bit.SWRST = 1; + while (DMAC->CTRL.bit.SWRST) { + } + /* Set up the descriptor and write back addresses */ DMA_REGS->BASEADDR.reg = (uintptr_t)&data->descriptors; DMA_REGS->WRBADDR.reg = (uintptr_t)&data->descriptors_wb; @@ -446,7 +455,7 @@ static int dma_sam0_init(const struct device *dev) static struct dma_sam0_data dmac_data; -static const struct dma_driver_api dma_sam0_api = { +static DEVICE_API(dma, dma_sam0_api) = { .config = dma_sam0_config, .start = dma_sam0_start, .stop = dma_sam0_stop, diff --git a/drivers/dma/dma_sam_xdmac.c b/drivers/dma/dma_sam_xdmac.c index 569085e5766cd..2deeeba817391 100644 --- a/drivers/dma/dma_sam_xdmac.c +++ b/drivers/dma/dma_sam_xdmac.c @@ -399,7 +399,7 @@ static int sam_xdmac_get_status(const struct device *dev, uint32_t channel, return 0; } -static const struct dma_driver_api sam_xdmac_driver_api = { +static DEVICE_API(dma, sam_xdmac_driver_api) = { .config = sam_xdmac_config, .reload = sam_xdmac_transfer_reload, .start = sam_xdmac_transfer_start, diff --git a/drivers/dma/dma_sedi.c b/drivers/dma/dma_sedi.c index 03f43e87580ae..14ee67af850df 100644 --- a/drivers/dma/dma_sedi.c +++ b/drivers/dma/dma_sedi.c @@ -350,11 +350,12 @@ static int dma_sedi_stop(const struct device *dev, uint32_t channel) return 0; } -static const struct dma_driver_api dma_funcs = { .config = dma_sedi_chan_config, - .start = dma_sedi_start, - .stop = dma_sedi_stop, - .reload = dma_sedi_reload, - .get_status = NULL +static DEVICE_API(dma, dma_funcs) = { + .config = dma_sedi_chan_config, + .start = dma_sedi_start, + .stop = dma_sedi_stop, + .reload = dma_sedi_reload, + .get_status = NULL, }; static int dma_sedi_init(const struct device *dev) @@ -375,7 +376,7 @@ static int dma_sedi_init(const struct device *dev) .chn_num = DT_INST_PROP(inst, dma_channels), \ .irq_config = dma_sedi_##inst##_irq_config \ }; \ - DEVICE_DT_DEFINE(DT_INST(inst, DT_DRV_COMPAT), &dma_sedi_init, \ + DEVICE_DT_INST_DEFINE(inst, &dma_sedi_init, \ NULL, &dma_sedi_dev_data_##inst, &dma_sedi_config_data_##inst, PRE_KERNEL_2, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, (void *)&dma_funcs); \ \ diff --git a/drivers/dma/dma_si32.c b/drivers/dma/dma_si32.c index f6b8a46f1177c..4463a19fc056d 100644 --- a/drivers/dma/dma_si32.c +++ b/drivers/dma/dma_si32.c @@ -417,7 +417,7 @@ static int dma_si32_stop(const struct device *dev, const uint32_t channel) return 0; } -static const struct dma_driver_api dma_si32_driver_api = { +static DEVICE_API(dma, dma_si32_driver_api) = { .config = dma_si32_config, .start = dma_si32_start, .stop = dma_si32_stop, diff --git a/drivers/dma/dma_silabs_ldma.c b/drivers/dma/dma_silabs_ldma.c new file mode 100644 index 0000000000000..5bd43c5dfd1f0 --- /dev/null +++ b/drivers/dma/dma_silabs_ldma.c @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "em_ldma.h" +#include "dmadrv.h" + +#define DT_DRV_COMPAT silabs_ldma + +#define DMA_IRQ_PRIORITY 3 + +LOG_MODULE_REGISTER(silabs_dma, CONFIG_DMA_LOG_LEVEL); + +struct dma_silabs_channel { + enum dma_channel_direction dir; + uint32_t complete_callback_en; + atomic_t busy; + void *user_data; + dma_callback_t cb; + LDMA_TransferCfg_t xfer_config; + LDMA_Descriptor_t *desc; +}; + +struct dma_silabs_config { + void (*config_irq)(const struct device *dev); + const struct device *clock_dev; +}; + +struct dma_silabs_data { + struct dma_context dma_ctx; + struct dma_silabs_channel *dma_chan_table; + struct sys_mem_blocks *dma_desc_pool; +}; + +static int dma_silabs_get_blocksize(uint32_t src_blen, uint32_t dst_blen, uint32_t src_dsize) +{ + const static struct { + int native; + int efr; + } ldma_blocksize_map[] = { + { 0x0001, ldmaCtrlBlockSizeUnit1 }, + { 0x0002, ldmaCtrlBlockSizeUnit2 }, + { 0x0003, ldmaCtrlBlockSizeUnit3 }, + { 0x0004, ldmaCtrlBlockSizeUnit4 }, + { 0x0006, ldmaCtrlBlockSizeUnit6 }, + { 0x0008, ldmaCtrlBlockSizeUnit8 }, + { 0x0010, ldmaCtrlBlockSizeUnit16 }, + { 0x0020, ldmaCtrlBlockSizeUnit32 }, + { 0x0040, ldmaCtrlBlockSizeUnit64 }, + { 0x0080, ldmaCtrlBlockSizeUnit128 }, + { 0x0100, ldmaCtrlBlockSizeUnit256 }, + { 0x0200, ldmaCtrlBlockSizeUnit512 }, + { 0x0400, ldmaCtrlBlockSizeUnit1024 } + }; + uint32_t arb_unit; + + if (src_blen != dst_blen) { + LOG_ERR("Source burst length (%u) and destination burst length(%u) must be equal", + src_blen, dst_blen); + return -ENOTSUP; + } + + if (src_blen % src_dsize) { + LOG_ERR("burst length (%u) and data size (%u) mismatch", src_blen, dst_blen); + return -EINVAL; + } + + arb_unit = src_blen / src_dsize; + + for (int i = 0; i < ARRAY_SIZE(ldma_blocksize_map); i++) { + if (ldma_blocksize_map[i].native == arb_unit) { + return ldma_blocksize_map[i].efr; + } + } + return -EINVAL; +} + +static int dma_silabs_block_to_descriptor(struct dma_config *config, + struct dma_silabs_channel *chan_conf, + struct dma_block_config *block, LDMA_Descriptor_t *desc) +{ + int ret, src_size, xfer_count; + + if (block->dest_scatter_count || block->source_gather_count || + block->source_gather_interval || block->dest_scatter_interval || + block->dest_reload_en || block->source_reload_en) { + return -ENOTSUP; + } + + if ((block->source_gather_en || block->dest_scatter_en) && config->block_count == 1) { + LOG_WRN("DMA scatter_gather enabled but there is only one descriptor " + "configured"); + } + + memset(desc, 0, sizeof(*desc)); + + if (config->channel_direction == MEMORY_TO_MEMORY) { + desc->xfer.structReq = 1; + } + + if (config->source_data_size != config->dest_data_size) { + LOG_ERR("Source data size(%u) and destination data size(%u) must be equal", + config->source_data_size, config->dest_data_size); + return -ENOTSUP; + } + + if (config->source_data_size < 1 || config->source_data_size > 4) { + return -ENOTSUP; + } + + src_size = config->source_data_size; + desc->xfer.size = LOG2(src_size); + + if (block->block_size % config->source_data_size) { + xfer_count = block->block_size / config->source_data_size; + } else { + xfer_count = block->block_size / config->source_data_size - 1; + } + + if (xfer_count > LDMA_DESCRIPTOR_MAX_XFER_SIZE) { + return -ENOTSUP; + } + + desc->xfer.xferCnt = xfer_count; + + /* Warning : High LDMA blockSize (high burst) mean a large transfer + * without LDMA controller re-arbitration. + */ + ret = dma_silabs_get_blocksize(config->source_burst_length, config->dest_burst_length, + config->source_data_size); + if (ret < 0) { + return ret; + } + + desc->xfer.blockSize = ret; + + /* if complete_callbacks_enabled, callback is called at then end of each descriptor + * in the list (block for zephyr) + */ + desc->xfer.doneIfs = config->complete_callback_en; + + if (config->channel_direction == PERIPHERAL_TO_MEMORY || + config->channel_direction == MEMORY_TO_PERIPHERAL) { + if (block->flow_control_mode) { + desc->xfer.reqMode = ldmaCtrlReqModeAll; + } else { + desc->xfer.reqMode = ldmaCtrlReqModeBlock; + } + } else { + desc->xfer.reqMode = ldmaCtrlReqModeAll; + } + + /* In silabs LDMA, increment sign is managed with the transfer configuration + * which is common for all descs of the channel. Zephyr DMA API allows + * to manage increment sign for each block desc which can't be done with + * silabs LDMA. If increment sign is different in 2 block desc, then an + * error is returned. + */ + if (block->source_addr_adj != DMA_ADDR_ADJ_NO_CHANGE && + block->source_addr_adj != chan_conf->xfer_config.ldmaCfgSrcIncSign) { + return -ENOTSUP; + } + + if (block->source_addr_adj == DMA_ADDR_ADJ_NO_CHANGE) { + desc->xfer.srcInc = ldmaCtrlSrcIncNone; + } else { + desc->xfer.srcInc = ldmaCtrlSrcIncOne; + } + + if (block->dest_addr_adj == DMA_ADDR_ADJ_NO_CHANGE) { + desc->xfer.dstInc = ldmaCtrlDstIncNone; + } else { + desc->xfer.dstInc = ldmaCtrlDstIncOne; + } + + desc->xfer.srcAddrMode = ldmaCtrlSrcAddrModeAbs; + desc->xfer.dstAddrMode = ldmaCtrlDstAddrModeAbs; + + if (block->source_address == 0) { + LOG_WRN("source_buffer address is null."); + } + if (block->dest_address == 0) { + LOG_WRN("dest_buffer address is null."); + } + + desc->xfer.srcAddr = block->source_address; + desc->xfer.dstAddr = block->dest_address; + + return 0; +} + +static int dma_silabs_release_descriptor(struct dma_silabs_data *data, LDMA_Descriptor_t *desc) +{ + LDMA_Descriptor_t *head_desc, *next_desc; + int ret; + + head_desc = desc; + while (desc) { + next_desc = LDMA_DESCRIPTOR_LINKABS_LINKADDR_TO_ADDR(desc->xfer.linkAddr); + ret = sys_mem_blocks_free(data->dma_desc_pool, 1, (void **)&desc); + if (ret) { + return ret; + } + desc = next_desc; + /* Protection against descriptor loop*/ + if (desc == head_desc) { + break; + } + } + + return 0; +} + +static int dma_silabs_configure_descriptor(struct dma_config *config, struct dma_silabs_data *data, + struct dma_silabs_channel *chan_conf) +{ + struct dma_block_config *head_block = config->head_block; + struct dma_block_config *block = config->head_block; + LDMA_Descriptor_t *desc, *prev_desc; + int ret; + + /* Descriptors configuration + * block refers to user configured block (dma_block_config structure from dma.h) + * desc refers to driver configured block (LDMA_Descriptor_t structure from silabs + * hal) + */ + prev_desc = NULL; + while (block) { + ret = sys_mem_blocks_alloc(data->dma_desc_pool, 1, (void **)&desc); + if (ret) { + goto err; + } + + ret = dma_silabs_block_to_descriptor(config, chan_conf, block, desc); + if (ret) { + goto err; + } + + if (!prev_desc) { + chan_conf->desc = desc; + } else { + prev_desc->xfer.linkAddr = LDMA_DESCRIPTOR_LINKABS_ADDR_TO_LINKADDR(desc); + prev_desc->xfer.linkMode = ldmaLinkModeAbs; + prev_desc->xfer.link = 1; + } + + prev_desc = desc; + block = block->next_block; + if (block == head_block) { + block = NULL; + prev_desc->xfer.linkAddr = + LDMA_DESCRIPTOR_LINKABS_ADDR_TO_LINKADDR(chan_conf->desc); + prev_desc->xfer.linkMode = ldmaLinkModeAbs; + prev_desc->xfer.link = 1; + } + } + + return 0; +err: + /* Free all eventually allocated descriptor */ + dma_silabs_release_descriptor(data, chan_conf->desc); + + return ret; +} + +static void dma_silabs_irq_handler(const struct device *dev, uint32_t id) +{ + const struct dma_silabs_data *data = dev->data; + struct dma_silabs_channel *chan; + int status; + uint32_t pending, chnum; + + pending = LDMA_IntGetEnabled(); + + for (chnum = 0; chnum < data->dma_ctx.dma_channels; chnum++) { + chan = &data->dma_chan_table[chnum]; + status = DMA_STATUS_COMPLETE; + + if (pending & LDMA_IF_ERROR) { + if (chan->cb) { + chan->cb(dev, chan->user_data, chnum, -EIO); + } + } else if (pending & BIT(chnum)) { + LDMA_IntClear(BIT(chnum)); + + /* Is it only an interrupt for the end of a descriptor and not a complete + * transfer. + */ + if (chan->complete_callback_en) { + status = DMA_STATUS_BLOCK; + } else { + atomic_clear(&chan->busy); + } + + /* + * In the case that the transfer is done but we have append a new + * descriptor, we need to manually load the next descriptor + */ + if (LDMA_TransferDone(chnum) && + LDMA->CH[chnum].LINK & _LDMA_CH_LINK_LINK_MASK) { + sys_clear_bit((mem_addr_t)&LDMA->CHDONE, chnum); + LDMA->LINKLOAD = BIT(chnum); + } + + if (chan->cb) { + chan->cb(dev, chan->user_data, chnum, status); + } + } + } +} + +static int dma_silabs_configure(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + struct dma_silabs_data *data = dev->data; + struct dma_silabs_channel *chan_conf = &data->dma_chan_table[channel]; + LDMA_TransferCfg_t *xfer_config = &chan_conf->xfer_config; + int ret; + + if (channel > data->dma_ctx.dma_channels) { + return -EINVAL; + } + + if (!config) { + return -EINVAL; + } + + if (atomic_get(&chan_conf->busy)) { + LOG_ERR("DMA channel %u is busy", channel); + return -EBUSY; + } + + /* Release previously owned descriptor for this channel*/ + ret = dma_silabs_release_descriptor(data, chan_conf->desc); + if (ret) { + return ret; + } + + if (config->dest_data_size != config->source_data_size) { + LOG_ERR("source and dest data size differ"); + return -ENOTSUP; + } + + if (config->source_handshake || config->dest_handshake || config->source_chaining_en || + config->dest_chaining_en || config->linked_channel) { + return -ENOTSUP; + } + + LDMA_StopTransfer(channel); + + chan_conf->user_data = config->user_data; + chan_conf->cb = config->dma_callback; + chan_conf->dir = config->channel_direction; + chan_conf->complete_callback_en = config->complete_callback_en; + + memset(xfer_config, 0, sizeof(*xfer_config)); + + switch (config->channel_direction) { + case MEMORY_TO_MEMORY: + break; + case PERIPHERAL_TO_MEMORY: + case MEMORY_TO_PERIPHERAL: + xfer_config->ldmaReqSel = SILABS_LDMA_SLOT_TO_REQSEL(config->dma_slot); + break; + case PERIPHERAL_TO_PERIPHERAL: + case HOST_TO_MEMORY: + case MEMORY_TO_HOST: + default: + return -ENOTSUP; + } + + /* Directly transform channel_priority into efr priority */ + if (config->channel_priority < ldmaCfgArbSlotsAs1 || + config->channel_priority > ldmaCfgArbSlotsAs8) { + return -EINVAL; + } + xfer_config->ldmaCfgArbSlots = config->channel_priority; + + switch (config->head_block->source_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + xfer_config->ldmaCfgSrcIncSign = ldmaCfgSrcIncSignPos; + break; + case DMA_ADDR_ADJ_DECREMENT: + xfer_config->ldmaCfgSrcIncSign = ldmaCfgSrcIncSignNeg; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + xfer_config->ldmaCfgSrcIncSign = ldmaCfgSrcIncSignPos; + break; + default: + LOG_ERR("Addr Adjustement error %d", config->head_block->source_addr_adj); + break; + } + + switch (config->head_block->dest_addr_adj) { + case DMA_ADDR_ADJ_INCREMENT: + xfer_config->ldmaCfgDstIncSign = ldmaCfgDstIncSignPos; + break; + case DMA_ADDR_ADJ_DECREMENT: + xfer_config->ldmaCfgDstIncSign = ldmaCfgDstIncSignNeg; + break; + case DMA_ADDR_ADJ_NO_CHANGE: + xfer_config->ldmaCfgDstIncSign = ldmaCfgDstIncSignPos; + break; + default: + break; + } + + ret = dma_silabs_configure_descriptor(config, data, chan_conf); + if (ret) { + return ret; + } + + atomic_set_bit(data->dma_ctx.atomic, channel); + + return 0; +} + +static int dma_silabs_start(const struct device *dev, uint32_t channel) +{ + const struct dma_silabs_data *data = dev->data; + struct dma_silabs_channel *chan = &data->dma_chan_table[channel]; + + if (channel > data->dma_ctx.dma_channels) { + return -EINVAL; + } + + atomic_inc(&chan->busy); + + LDMA_StartTransfer(channel, &chan->xfer_config, chan->desc); + + return 0; +} + +static int dma_silabs_stop(const struct device *dev, uint32_t channel) +{ + const struct dma_silabs_data *data = dev->data; + struct dma_silabs_channel *chan = &data->dma_chan_table[channel]; + + if (channel > data->dma_ctx.dma_channels) { + return -EINVAL; + } + + LDMA_StopTransfer(channel); + + atomic_clear(&chan->busy); + + LDMA_IntClear(BIT(channel)); + + return 0; +} + +static int dma_silabs_get_status(const struct device *dev, uint32_t channel, + struct dma_status *status) +{ + const struct dma_silabs_data *data = dev->data; + + if (channel > data->dma_ctx.dma_channels) { + return -EINVAL; + } + + if (!atomic_test_bit(data->dma_ctx.atomic, channel)) { + return -EINVAL; + } + + status->pending_length = LDMA_TransferRemainingCount(channel); + status->busy = data->dma_chan_table[channel].busy; + status->dir = data->dma_chan_table[channel].dir; + + return 0; +} + +bool dma_silabs_chan_filter(const struct device *dev, int channel, void *filter_param) +{ + ARG_UNUSED(dev); + ARG_UNUSED(filter_param); + return (DMADRV_AllocateChannelById(channel, 0) == ECODE_EMDRV_DMADRV_OK); +} + +void dma_silabs_chan_release(const struct device *dev, uint32_t channel) +{ + ARG_UNUSED(dev); + Ecode_t err = DMADRV_FreeChannel(channel); + + __ASSERT_NO_MSG(err == ECODE_EMDRV_DMADRV_OK); +} + +static int dma_silabs_init(const struct device *dev) +{ + const struct dma_silabs_config *config = dev->config; + + /* Clock is managed by em_ldma */ + DMADRV_Init(); + + /* LDMA_Init configure IRQ but we want IRQ to match with configured one in the dts*/ + config->config_irq(dev); + + return 0; +} + +static DEVICE_API(dma, dma_funcs) = { + .config = dma_silabs_configure, + .start = dma_silabs_start, + .stop = dma_silabs_stop, + .get_status = dma_silabs_get_status, + .chan_filter = dma_silabs_chan_filter, + .chan_release = dma_silabs_chan_release +}; + +int silabs_ldma_append_block(const struct device *dev, uint32_t channel, struct dma_config *config) +{ + const struct dma_silabs_data *data = dev->data; + struct dma_silabs_channel *chan_conf = &data->dma_chan_table[channel]; + struct dma_block_config *block_config = config->head_block; + LDMA_Descriptor_t *desc = data->dma_chan_table[channel].desc; + unsigned int key; + int ret; + + __ASSERT(!((uintptr_t)desc & ~_LDMA_CH_LINK_LINKADDR_MASK), + "DMA Descriptor is not 32 bits aligned"); + + if (channel > data->dma_ctx.dma_channels) { + return -EINVAL; + } + + if (!atomic_test_bit(data->dma_ctx.atomic, channel)) { + return -EINVAL; + } + + /* DMA Channel already have loaded a descriptor with a linkaddr + * so we can't append a new block just after the current transfer. + * You can't also append a descriptor list. + * This check is here to not use the function in a wrong way + */ + if (desc->xfer.linkAddr || config->head_block->next_block) { + return -EINVAL; + } + + /* A link is already set by a previous call to the function */ + if (sys_test_bit((mem_addr_t)&LDMA->CH[channel].LINK, _LDMA_CH_LINK_LINK_SHIFT)) { + return -EINVAL; + } + + ret = dma_silabs_block_to_descriptor(config, chan_conf, block_config, desc); + if (ret) { + return ret; + } + + key = irq_lock(); + if (!LDMA_TransferDone(channel)) { + /* + * It is voluntary to split this 2 lines in order to separate the write of the link + * addr and the write of the link bit. In this way, there is always a linkAddr when + * the link bit is set. + */ + sys_write32((uintptr_t)desc, (mem_addr_t)&LDMA->CH[channel].LINK); + sys_set_bit((mem_addr_t)&LDMA->CH[channel].LINK, _LDMA_CH_LINK_LINK_SHIFT); + irq_unlock(key); + + } else { + irq_unlock(key); + LDMA_StartTransfer(channel, &chan_conf->xfer_config, desc); + } + + return 0; +} + +#define SILABS_DMA_IRQ_CONNECT(n, inst) \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, n, irq), DT_INST_IRQ_BY_IDX(inst, n, priority), \ + dma_silabs_irq_handler, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(inst, n, irq)); + +#define CONFIGURE_ALL_IRQS(inst, n) LISTIFY(n, SILABS_DMA_IRQ_CONNECT, (), inst) + +#define DMA_SILABS_LDMA_INIT(inst) \ + \ + static void silabs_dma_irq_configure_##inst(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + CONFIGURE_ALL_IRQS(inst, DT_NUM_IRQS(DT_DRV_INST(inst))); \ + }; \ + \ + const struct dma_silabs_config dma_silabs_config_##inst = { \ + .config_irq = silabs_dma_irq_configure_##inst \ + }; \ + \ + static ATOMIC_DEFINE(dma_channels_atomic_##inst, DT_INST_PROP(inst, dma_channels)); \ + \ + static struct dma_silabs_channel \ + dma_silabs_channel_##inst[DT_INST_PROP(inst, dma_channels)]; \ + \ + SYS_MEM_BLOCKS_DEFINE_STATIC(desc_pool_##inst, sizeof(LDMA_Descriptor_t), \ + CONFIG_DMA_MAX_DESCRIPTOR, 4); \ + \ + static struct dma_silabs_data dma_silabs_data_##inst = { \ + .dma_ctx.magic = DMA_MAGIC, \ + .dma_ctx.dma_channels = DT_INST_PROP(inst, dma_channels), \ + .dma_ctx.atomic = dma_channels_atomic_##inst, \ + .dma_chan_table = dma_silabs_channel_##inst, \ + .dma_desc_pool = &desc_pool_##inst \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &dma_silabs_init, NULL, &dma_silabs_data_##inst, \ + &dma_silabs_config_##inst, PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, \ + &dma_funcs); + +DT_INST_FOREACH_STATUS_OKAY(DMA_SILABS_LDMA_INIT); diff --git a/drivers/dma/dma_silabs_siwx91x.c b/drivers/dma/dma_silabs_siwx91x.c new file mode 100644 index 0000000000000..1bcdfe05580c3 --- /dev/null +++ b/drivers/dma/dma_silabs_siwx91x.c @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "rsi_rom_udma_wrapper.h" +#include "rsi_udma.h" +#include "sl_status.h" + +#define DT_DRV_COMPAT silabs_siwx91x_dma +#define DMA_MAX_TRANSFER_COUNT 1024 +#define DMA_CH_PRIORITY_HIGH 1 +#define DMA_CH_PRIORITY_LOW 0 +#define VALID_BURST_LENGTH 0 +#define UDMA_ADDR_INC_NONE 0X03 + +LOG_MODULE_REGISTER(si91x_dma, CONFIG_DMA_LOG_LEVEL); + +struct dma_siwx91x_config { + UDMA0_Type *reg; /* UDMA register base address */ + uint8_t channels; /* UDMA channel count */ + uint8_t irq_number; /* IRQ number */ + RSI_UDMA_DESC_T *sram_desc_addr; /* SRAM Address for UDMA Descriptor Storage */ + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + void (*irq_configure)(void); /* IRQ configure function */ +}; + +struct dma_siwx91x_data { + UDMA_Channel_Info *chan_info; + dma_callback_t dma_callback; /* User callback */ + void *cb_data; /* User callback data */ + RSI_UDMA_DATACONTEXT_T dma_rom_buff; /* Buffer to store UDMA handle */ + /* related information */ +}; + +static inline int siwx91x_dma_is_peripheral_request(uint32_t dir) +{ + if (dir == MEMORY_TO_MEMORY) { + return 0; + } + if (dir == MEMORY_TO_PERIPHERAL || dir == PERIPHERAL_TO_MEMORY) { + return 1; + } + return -1; +} + +static inline int siwx91x_dma_data_width(uint32_t data_width) +{ + switch (data_width) { + case 1: + return SRC_SIZE_8; + case 2: + return SRC_SIZE_16; + case 4: + return SRC_SIZE_32; + default: + return -EINVAL; + } +} + +static inline int siwx91x_dma_burst_length(uint32_t blen) +{ + switch (blen / 8) { + case 1: + return VALID_BURST_LENGTH; /* 8-bit burst */ + default: + return -EINVAL; + } +} + +static inline int siwx91x_dma_addr_adjustment(uint32_t adjustment) +{ + switch (adjustment) { + case 0: + return 0; /* Addr Increment */ + case 2: + return UDMA_ADDR_INC_NONE; /* No Address increment */ + default: + return -EINVAL; + } +} + +static int dma_channel_config(const struct device *dev, RSI_UDMA_HANDLE_T udma_handle, + uint32_t channel, struct dma_config *config, + UDMA_Channel_Info *channel_info) +{ + const struct dma_siwx91x_config *cfg = dev->config; + UDMA_RESOURCES udma_resources = { + .reg = cfg->reg, + .udma_irq_num = cfg->irq_number, + /* SRAM address where UDMA descriptor is stored */ + .desc = cfg->sram_desc_addr, + }; + RSI_UDMA_CHA_CONFIG_DATA_T channel_control = { + .transferType = UDMA_MODE_BASIC, + }; + RSI_UDMA_CHA_CFG_T channel_config = {}; + int status; + + channel_config.channelPrioHigh = config->channel_priority; + if (siwx91x_dma_is_peripheral_request(config->channel_direction) < 0) { + return -EINVAL; + } + channel_config.periphReq = siwx91x_dma_is_peripheral_request(config->channel_direction); + channel_config.dmaCh = channel; + if (channel_config.periphReq) { + /* Arbitration power for peripheral<->memory transfers */ + channel_control.rPower = ARBSIZE_1; + } else { + /* Arbitration power for mem-mem transfers */ + channel_control.rPower = ARBSIZE_1024; + } + /* Obtain the number of transfers */ + config->head_block->block_size /= config->source_data_size; + if (config->head_block->block_size >= DMA_MAX_TRANSFER_COUNT) { + /* Maximum number of transfers is 1024 */ + channel_control.totalNumOfDMATrans = DMA_MAX_TRANSFER_COUNT - 1; + } else { + channel_control.totalNumOfDMATrans = config->head_block->block_size; + } + if (siwx91x_dma_data_width(config->source_data_size) < 0 || + siwx91x_dma_data_width(config->dest_data_size) < 0) { + return -EINVAL; + } + if (siwx91x_dma_burst_length(config->source_burst_length) < 0 || + siwx91x_dma_burst_length(config->dest_burst_length) < 0) { + return -EINVAL; + } + channel_control.srcSize = siwx91x_dma_data_width(config->source_data_size); + channel_control.dstSize = siwx91x_dma_data_width(config->dest_data_size); + if (siwx91x_dma_addr_adjustment(config->head_block->source_addr_adj) < 0 || + siwx91x_dma_addr_adjustment(config->head_block->dest_addr_adj) < 0) { + return -EINVAL; + } + if (siwx91x_dma_addr_adjustment(config->head_block->source_addr_adj) == 0) { + channel_control.srcInc = channel_control.srcSize; + } else { + channel_control.srcInc = UDMA_SRC_INC_NONE; + } + if (siwx91x_dma_addr_adjustment(config->head_block->dest_addr_adj) == 0) { + channel_control.dstInc = channel_control.dstSize; + } else { + channel_control.dstInc = UDMA_DST_INC_NONE; + } + status = UDMAx_ChannelConfigure(&udma_resources, (uint8_t)channel, + config->head_block->source_address, + config->head_block->dest_address, + config->head_block->block_size, channel_control, + &channel_config, NULL, channel_info, udma_handle); + if (status) { + return -EIO; + } + return 0; +} + +/* Function to configure UDMA channel for transfer */ +static int dma_siwx91x_configure(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + const struct dma_siwx91x_config *cfg = dev->config; + struct dma_siwx91x_data *data = dev->data; + void *udma_handle = &data->dma_rom_buff; + int status; + + /* Expecting a fixed channel number between 0-31 for dma0 and 0-11 for ulpdma */ + if (channel >= cfg->channels) { + return -EINVAL; + } + + /* Disable the channel before configuring */ + if (RSI_UDMA_ChannelDisable(udma_handle, channel) != 0) { + return -EIO; + } + + if (config->channel_priority != DMA_CH_PRIORITY_LOW && + config->channel_priority != DMA_CH_PRIORITY_HIGH) { + return -EINVAL; + } + + /* Configure dma channel for transfer */ + status = dma_channel_config(dev, udma_handle, channel, config, data->chan_info); + if (status) { + return status; + } + return 0; +} + +/* Function to reload UDMA channel for new transfer */ +static int dma_siwx91x_reload(const struct device *dev, uint32_t channel, uint32_t src, + uint32_t dst, size_t size) +{ + const struct dma_siwx91x_config *cfg = dev->config; + struct dma_siwx91x_data *data = dev->data; + void *udma_handle = &data->dma_rom_buff; + uint32_t desc_src_addr; + uint32_t desc_dst_addr; + uint32_t length; + RSI_UDMA_DESC_T *udma_table = cfg->sram_desc_addr; + + /* Expecting a fixed channel number between 0-31 for dma0 and 0-11 for ulpdma */ + if (channel >= cfg->channels) { + return -EINVAL; + } + + /* Disable the channel before reloading transfer */ + if (RSI_UDMA_ChannelDisable(udma_handle, channel) != 0) { + return -EIO; + } + + /* Update new channel info to dev->data structure */ + data->chan_info[channel].SrcAddr = src; + data->chan_info[channel].DestAddr = dst; + data->chan_info[channel].Size = size; + + /* Update new transfer size to dev->data structure */ + if (size >= DMA_MAX_TRANSFER_COUNT) { + data->chan_info[channel].Cnt = DMA_MAX_TRANSFER_COUNT - 1; + } else { + data->chan_info[channel].Cnt = size; + } + /* Program the DMA descriptors with new transfer data information. */ + if (udma_table[channel].vsUDMAChaConfigData1.srcInc != UDMA_SRC_INC_NONE) { + length = data->chan_info[channel].Cnt + << udma_table[channel].vsUDMAChaConfigData1.srcInc; + desc_src_addr = src + (length - 1); + udma_table[channel].pSrcEndAddr = (void *)desc_src_addr; + } + if (udma_table[channel].vsUDMAChaConfigData1.dstInc != UDMA_SRC_INC_NONE) { + length = data->chan_info[channel].Cnt + << udma_table[channel].vsUDMAChaConfigData1.dstInc; + desc_dst_addr = dst + (length - 1); + udma_table[channel].pDstEndAddr = (void *)desc_dst_addr; + } + udma_table[channel].vsUDMAChaConfigData1.totalNumOfDMATrans = data->chan_info[channel].Cnt; + udma_table[channel].vsUDMAChaConfigData1.transferType = UDMA_MODE_BASIC; + + return 0; +} + +/* Function to start a DMA transfer */ +static int dma_siwx91x_start(const struct device *dev, uint32_t channel) +{ + const struct dma_siwx91x_config *cfg = dev->config; + RSI_UDMA_DESC_T *udma_table = cfg->sram_desc_addr; + struct dma_siwx91x_data *data = dev->data; + void *udma_handle = &data->dma_rom_buff; + + /* Expecting a fixed channel number between 0-31 for dma0 and 0-11 for ulpdma */ + if (channel >= cfg->channels) { + return -EINVAL; + } + if (RSI_UDMA_ChannelEnable(udma_handle, channel) != 0) { + return -EINVAL; + } + + /* Check if the transfer type is memory-memory */ + if (udma_table[channel].vsUDMAChaConfigData1.srcInc != UDMA_SRC_INC_NONE && + udma_table[channel].vsUDMAChaConfigData1.dstInc != UDMA_DST_INC_NONE) { + /* Apply software trigger to start transfer */ + cfg->reg->CHNL_SW_REQUEST |= BIT(channel); + } + return 0; +} + +/* Function to stop a DMA transfer */ +static int dma_siwx91x_stop(const struct device *dev, uint32_t channel) +{ + const struct dma_siwx91x_config *cfg = dev->config; + struct dma_siwx91x_data *data = dev->data; + void *udma_handle = &data->dma_rom_buff; + + /* Expecting a fixed channel number between 0-31 for dma0 and 0-11 for ulpdma */ + if (channel >= cfg->channels) { + return -EINVAL; + } + if (RSI_UDMA_ChannelDisable(udma_handle, channel) != 0) { + return -EIO; + } + return 0; +} + +/* Function to fetch DMA channel status */ +static int dma_siwx91x_get_status(const struct device *dev, uint32_t channel, + struct dma_status *stat) +{ + const struct dma_siwx91x_config *cfg = dev->config; + RSI_UDMA_DESC_T *udma_table = cfg->sram_desc_addr; + + /* Expecting a fixed channel number between 0-31 for dma0 and 0-11 for ulpdma */ + if (channel >= cfg->channels) { + return -EINVAL; + } + /* Read the channel status register */ + if (cfg->reg->CHANNEL_STATUS_REG & BIT(channel)) { + stat->busy = 1; + } else { + stat->busy = 0; + } + + /* Obtain the transfer direction from channel descriptors */ + if (udma_table[channel].vsUDMAChaConfigData1.srcInc == UDMA_SRC_INC_NONE) { + stat->dir = PERIPHERAL_TO_MEMORY; + } else if (udma_table[channel].vsUDMAChaConfigData1.dstInc == UDMA_DST_INC_NONE) { + stat->dir = MEMORY_TO_PERIPHERAL; + } else { + stat->dir = MEMORY_TO_MEMORY; + } + return 0; +} + +/* Function to initialize DMA peripheral */ +static int dma_siwx91x_init(const struct device *dev) +{ + const struct dma_siwx91x_config *cfg = dev->config; + struct dma_siwx91x_data *data = dev->data; + void *udma_handle = NULL; + UDMA_RESOURCES udma_resources = { + .reg = cfg->reg, /* UDMA register base address */ + .udma_irq_num = cfg->irq_number, + .desc = cfg->sram_desc_addr, + }; + int ret; + + ret = clock_control_on(cfg->clock_dev, cfg->clock_subsys); + if (ret) { + return ret; + } + + udma_handle = UDMAx_Initialize(&udma_resources, udma_resources.desc, NULL, + (uint32_t *)&data->dma_rom_buff); + if (udma_handle != &data->dma_rom_buff) { + return -EINVAL; + } + + /* Connect the DMA interrupt */ + cfg->irq_configure(); + + if (UDMAx_DMAEnable(&udma_resources, udma_handle) != 0) { + return -EBUSY; + } + return 0; +} + +static void dma_siwx91x_isr(const struct device *dev) +{ + const struct dma_siwx91x_config *cfg = dev->config; + struct dma_siwx91x_data *data = dev->data; + UDMA_RESOURCES udma_resources = { + .reg = cfg->reg, + .udma_irq_num = cfg->irq_number, + .desc = cfg->sram_desc_addr, + }; + uint8_t channel; + + /* Disable the IRQ to prevent the ISR from being triggered by */ + /* interrupts from other DMA channels */ + irq_disable(cfg->irq_number); + channel = find_lsb_set(cfg->reg->UDMA_DONE_STATUS_REG); + /* Identify the interrupt channel */ + if (!channel || channel > cfg->channels) { + goto out; + } + /* find_lsb_set() returns 1 indexed value */ + channel -= 1; + if (data->chan_info[channel].Cnt == data->chan_info[channel].Size) { + if (data->dma_callback) { + /* Transfer complete, call user callback */ + data->dma_callback(dev, data->cb_data, channel, 0); + } + cfg->reg->UDMA_DONE_STATUS_REG = BIT(channel); + } else { + /* Call UDMA ROM IRQ handler. */ + ROMAPI_UDMA_WRAPPER_API->uDMAx_IRQHandler(&udma_resources, udma_resources.desc, + data->chan_info); + /* Is a Memory-to-memory Transfer */ + if (udma_resources.desc[channel].vsUDMAChaConfigData1.srcInc != UDMA_SRC_INC_NONE && + udma_resources.desc[channel].vsUDMAChaConfigData1.dstInc != UDMA_DST_INC_NONE) { + /* Set the software trigger bit for starting next transfer */ + cfg->reg->CHNL_SW_REQUEST |= BIT(channel); + } + } +out: + /* Enable the IRQ to restore interrupt functionality for other DMA channels */ + irq_enable(cfg->irq_number); +} + +/* Store the Si91x DMA APIs */ +static DEVICE_API(dma, siwx91x_dma_api) = { + .config = dma_siwx91x_configure, + .reload = dma_siwx91x_reload, + .start = dma_siwx91x_start, + .stop = dma_siwx91x_stop, + .get_status = dma_siwx91x_get_status, +}; + +#define SIWX91X_DMA_INIT(inst) \ + static UDMA_Channel_Info dma##inst##_channel_info[DT_INST_PROP(inst, dma_channels)]; \ + static struct dma_siwx91x_data dma##inst##_data = { \ + .chan_info = dma##inst##_channel_info, \ + }; \ + static void siwx91x_dma##inst##_irq_configure(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQ(inst, irq), DT_INST_IRQ(inst, priority), dma_siwx91x_isr, \ + DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQ(inst, irq)); \ + } \ + static const struct dma_siwx91x_config dma##inst##_cfg = { \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_PHA(inst, clocks, clkid), \ + .reg = (UDMA0_Type *)DT_INST_REG_ADDR(inst), \ + .channels = DT_INST_PROP(inst, dma_channels), \ + .irq_number = DT_INST_PROP_BY_IDX(inst, interrupts, 0), \ + .sram_desc_addr = (RSI_UDMA_DESC_T *)DT_INST_PROP(inst, silabs_sram_desc_addr), \ + .irq_configure = siwx91x_dma##inst##_irq_configure, \ + }; \ + DEVICE_DT_INST_DEFINE(inst, &dma_siwx91x_init, NULL, &dma##inst##_data, &dma##inst##_cfg, \ + PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, &siwx91x_dma_api); + +DT_INST_FOREACH_STATUS_OKAY(SIWX91X_DMA_INIT) diff --git a/drivers/dma/dma_smartbond.c b/drivers/dma/dma_smartbond.c index ced9580dbfe5c..b2eb956e26320 100644 --- a/drivers/dma/dma_smartbond.c +++ b/drivers/dma/dma_smartbond.c @@ -909,7 +909,7 @@ static bool dma_smartbond_chan_filter(const struct device *dev, int channel, voi return false; } -static struct dma_driver_api dma_smartbond_driver_api = { +static DEVICE_API(dma, dma_smartbond_driver_api) = { .config = dma_smartbond_config, .reload = dma_smartbond_reload, .start = dma_smartbond_start, diff --git a/drivers/dma/dma_stm32.c b/drivers/dma/dma_stm32.c index 8afc07792b55f..a50ba310a86d7 100644 --- a/drivers/dma/dma_stm32.c +++ b/drivers/dma/dma_stm32.c @@ -686,7 +686,7 @@ DMA_STM32_EXPORT_API int dma_stm32_get_status(const struct device *dev, return 0; } -static const struct dma_driver_api dma_funcs = { +static DEVICE_API(dma, dma_funcs) = { .reload = dma_stm32_reload, .config = dma_stm32_configure, .start = dma_stm32_start, diff --git a/drivers/dma/dma_stm32.h b/drivers/dma/dma_stm32.h index 553e09838d84d..54e7ac45524d8 100644 --- a/drivers/dma/dma_stm32.h +++ b/drivers/dma/dma_stm32.h @@ -52,7 +52,9 @@ uint32_t dma_stm32_slot_to_channel(uint32_t id); #endif typedef void (*dma_stm32_clear_flag_func)(DMA_TypeDef *DMAx); -#if !defined(CONFIG_SOC_SERIES_STM32G0X) +#if !defined(CONFIG_SOC_SERIES_STM32G0X) && \ + !defined(CONFIG_SOC_SERIES_STM32H7X) && \ + !defined(CONFIG_SOC_SERIES_STM32U0X) typedef uint32_t (*dma_stm32_check_flag_func)(DMA_TypeDef *DMAx); #else typedef uint32_t (*dma_stm32_check_flag_func)(const DMA_TypeDef *DMAx); diff --git a/drivers/dma/dma_stm32_bdma.c b/drivers/dma/dma_stm32_bdma.c index 1e814e8481543..7825a5520210f 100644 --- a/drivers/dma/dma_stm32_bdma.c +++ b/drivers/dma/dma_stm32_bdma.c @@ -849,7 +849,7 @@ BDMA_STM32_EXPORT_API int bdma_stm32_get_status(const struct device *dev, return 0; } -static const struct dma_driver_api dma_funcs = { +static DEVICE_API(dma, dma_funcs) = { .reload = bdma_stm32_reload, .config = bdma_stm32_configure, .start = bdma_stm32_start, diff --git a/drivers/dma/dma_stm32_bdma.h b/drivers/dma/dma_stm32_bdma.h index 090b03b1bfdf8..ea6ee145283bd 100644 --- a/drivers/dma/dma_stm32_bdma.h +++ b/drivers/dma/dma_stm32_bdma.h @@ -53,7 +53,7 @@ uint32_t bdma_stm32_slot_to_channel(uint32_t id); #endif typedef void (*bdma_stm32_clear_flag_func)(BDMA_TypeDef *DMAx); -typedef uint32_t (*bdma_stm32_check_flag_func)(BDMA_TypeDef *DMAx); +typedef uint32_t (*bdma_stm32_check_flag_func)(const BDMA_TypeDef *DMAx); bool bdma_stm32_is_gi_active(BDMA_TypeDef *DMAx, uint32_t id); void bdma_stm32_clear_gi(BDMA_TypeDef *DMAx, uint32_t id); diff --git a/drivers/dma/dma_stm32u5.c b/drivers/dma/dma_stm32u5.c index ca57ee8f36a90..d5b94d89af4ee 100644 --- a/drivers/dma/dma_stm32u5.c +++ b/drivers/dma/dma_stm32u5.c @@ -274,7 +274,9 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) stream->dma_callback(dev, stream->user_data, callback_arg, DMA_STATUS_BLOCK); } else if (stm32_dma_is_tc_irq_active(dma, id)) { /* Assuming not cyclic transfer */ - stream->busy = false; + if (stream->cyclic == false) { + stream->busy = false; + } /* Let HAL DMA handle flags on its own */ if (!stream->hal_override) { dma_stm32_clear_tc(dma, id); @@ -351,6 +353,13 @@ static int dma_stm32_configure(const struct device *dev, LL_DMA_InitTypeDef DMA_InitStruct; int ret; + /* Linked list Node and structure initialization */ + static LL_DMA_LinkNodeTypeDef Node_GPDMA_Channel; + LL_DMA_InitLinkedListTypeDef DMA_InitLinkedListStruct; + LL_DMA_InitNodeTypeDef NodeConfig; + + LL_DMA_ListStructInit(&DMA_InitLinkedListStruct); + LL_DMA_NodeStructInit(&NodeConfig); LL_DMA_StructInit(&DMA_InitStruct); /* Give channel from index 0 */ @@ -406,16 +415,6 @@ static int dma_stm32_configure(const struct device *dev, return -EINVAL; } - /* Continuous transfers are supported by hardware but not implemented - * by this driver - */ - if (config->head_block->source_reload_en || - config->head_block->dest_reload_en) { - LOG_ERR("source_reload_en and dest_reload_en not " - "implemented."); - return -EINVAL; - } - stream->busy = true; stream->dma_callback = config->dma_callback; stream->direction = config->channel_direction; @@ -434,8 +433,9 @@ static int dma_stm32_configure(const struct device *dev, DMA_InitStruct.SrcAddress = config->head_block->source_address; DMA_InitStruct.DestAddress = config->head_block->dest_address; - DMA_InitStruct.BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST; - DMA_InitStruct.DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD; + NodeConfig.SrcAddress = config->head_block->source_address; + NodeConfig.DestAddress = config->head_block->dest_address; + NodeConfig.BlkDataLength = config->head_block->block_size; ret = dma_stm32_get_priority(config->channel_priority, &DMA_InitStruct.Priority); @@ -500,18 +500,46 @@ static int dma_stm32_configure(const struct device *dev, /* The request ID is stored in the dma_slot */ DMA_InitStruct.Request = config->dma_slot; - LL_DMA_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitStruct); + if (config->head_block->source_reload_en == 0) { + /* Initialize the DMA structure in non-cyclic mode only */ + LL_DMA_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitStruct); + } else {/* cyclic mode */ + /* Setting GPDMA request */ + NodeConfig.DestDataWidth = DMA_InitStruct.DestDataWidth; + NodeConfig.SrcDataWidth = DMA_InitStruct.SrcDataWidth; + NodeConfig.DestIncMode = DMA_InitStruct.DestIncMode; + NodeConfig.SrcIncMode = DMA_InitStruct.SrcIncMode; + NodeConfig.Direction = DMA_InitStruct.Direction; + NodeConfig.Request = DMA_InitStruct.Request; + + /* Continuous transfers with Linked List */ + stream->cyclic = true; + LL_DMA_List_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitLinkedListStruct); + LL_DMA_CreateLinkNode(&NodeConfig, &Node_GPDMA_Channel); + LL_DMA_ConnectLinkNode(&Node_GPDMA_Channel, LL_DMA_CLLR_OFFSET5, + &Node_GPDMA_Channel, LL_DMA_CLLR_OFFSET5); + LL_DMA_SetLinkedListBaseAddr(dma, dma_stm32_id_to_stream(id), + (uint32_t)&Node_GPDMA_Channel); + LL_DMA_ConfigLinkUpdate(dma, dma_stm32_id_to_stream(id), + (LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | + LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | + LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CLLR), + (uint32_t)&Node_GPDMA_Channel); + + LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id)); + } + +#ifdef CONFIG_ARM_SECURE_FIRMWARE + LL_DMA_ConfigChannelSecure(dma, dma_stm32_id_to_stream(id), + LL_DMA_CHANNEL_SEC | LL_DMA_CHANNEL_SRC_SEC | LL_DMA_CHANNEL_DEST_SEC); + LL_DMA_EnableChannelPrivilege(dma, dma_stm32_id_to_stream(id)); +#endif LL_DMA_EnableIT_TC(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_USE(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_ULE(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_DTE(dma, dma_stm32_id_to_stream(id)); - /* Enable Half-Transfer irq if circular mode is enabled */ - if (config->head_block->source_reload_en) { - LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id)); - } - return ret; } @@ -707,7 +735,7 @@ static int dma_stm32_get_status(const struct device *dev, return 0; } -static const struct dma_driver_api dma_funcs = { +static DEVICE_API(dma, dma_funcs) = { .reload = dma_stm32_reload, .config = dma_stm32_configure, .start = dma_stm32_start, diff --git a/drivers/dma/dma_xilinx_axi_dma.c b/drivers/dma/dma_xilinx_axi_dma.c index 7138fbe212764..3b40f42f56000 100644 --- a/drivers/dma/dma_xilinx_axi_dma.c +++ b/drivers/dma/dma_xilinx_axi_dma.c @@ -1061,7 +1061,7 @@ static bool dma_xilinx_axi_dma_chan_filter(const struct device *dev, int channel } /* DMA API callbacks */ -static const struct dma_driver_api dma_xilinx_axi_dma_driver_api = { +static DEVICE_API(dma, dma_xilinx_axi_dma_driver_api) = { .config = dma_xilinx_axi_dma_configure, .reload = dma_xilinx_axi_dma_config_reload, .start = dma_xilinx_axi_dma_start, diff --git a/drivers/dma/dma_xmc4xxx.c b/drivers/dma/dma_xmc4xxx.c index ffe7b964aba85..44217a46c3739 100644 --- a/drivers/dma/dma_xmc4xxx.c +++ b/drivers/dma/dma_xmc4xxx.c @@ -24,6 +24,12 @@ LOG_MODULE_REGISTER(dma_xmc4xxx, CONFIG_DMA_LOG_LEVEL); #define DLR_SRSEL_RS_BITSIZE 4 #define DLR_SRSEL_RS_MSK 0xf +#define MULTI_BLOCK_NUM_CHANNELS 2 + +#define XMC_DMA_CTLL_MEMORY_TO_MEMORY 0 +#define XMC_DMA_CTLL_MEMORY_TO_PERIPHERAL 1 +#define XMC_DMA_CTLL_PERIPHERAL_TO_MEMORY 2 + #define ALL_EVENTS \ (XMC_DMA_CH_EVENT_TRANSFER_COMPLETE | XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE | \ XMC_DMA_CH_EVENT_SRC_TRANSACTION_COMPLETE | XMC_DMA_CH_EVENT_DST_TRANSACTION_COMPLETE | \ @@ -32,11 +38,33 @@ LOG_MODULE_REGISTER(dma_xmc4xxx, CONFIG_DMA_LOG_LEVEL); struct dma_xmc4xxx_channel { dma_callback_t cb; void *user_data; - uint16_t block_ts; + uint32_t dest_address; + uint32_t transfer_size; uint8_t source_data_size; uint8_t dlr_line; + uint8_t channel_direction; + uint8_t dest_addr_adj; + bool multi_block; +}; + +struct dma_xmc4xxx_descriptor { + uint32_t sar; /* source address */ + uint32_t dar; /* destination address */ + uint32_t llp; /* linked-list pointer to the next descriptor or null if last descriptor */ + uint32_t ctll; /* control register low */ + uint32_t ctlh; /* control register high */ + uint32_t dstat; /* status register fetched from address DSTATAR after block completes*/ +} __packed; + +struct dma_xmc4xxx_scatter_gather { + bool enabled; + uint32_t interval; + uint16_t count; }; +static struct dma_xmc4xxx_descriptor descriptor_list[MULTI_BLOCK_NUM_CHANNELS] + [CONFIG_DMA_XMC4XXX_NUM_DESCRIPTORS]; + struct dma_xmc4xxx_config { XMC_DMA_t *dma; void (*irq_configure)(void); @@ -62,7 +90,7 @@ do { if (dma_channel->cb) { \ dma_channel->cb(dev, dma_channel->user_data, channel, (ret)); \ } \ -} \ + } \ } while (0) /* Isr is level triggered, so we don't have to loop over all the channels */ @@ -120,6 +148,54 @@ static void dma_xmc4xxx_isr(const struct device *dev) } } +static uint32_t dma_xmc4xxx_reg_ctll(struct dma_block_config *block, struct dma_config *config) +{ + uint32_t ctll; + + ctll = config->dest_data_size / 2 << GPDMA0_CH_CTLL_DST_TR_WIDTH_Pos | + config->source_data_size / 2 << GPDMA0_CH_CTLL_SRC_TR_WIDTH_Pos | + block->dest_addr_adj << GPDMA0_CH_CTLL_DINC_Pos | + block->source_addr_adj << GPDMA0_CH_CTLL_SINC_Pos | + config->dest_burst_length / 4 << GPDMA0_CH_CTLL_DEST_MSIZE_Pos | + config->source_burst_length / 4 << GPDMA0_CH_CTLL_SRC_MSIZE_Pos | + BIT(GPDMA0_CH_CTLL_INT_EN_Pos); + + /* Only GPDMA flow controller supported */ + if (config->channel_direction == MEMORY_TO_PERIPHERAL) { + ctll |= XMC_DMA_CTLL_MEMORY_TO_PERIPHERAL << GPDMA0_CH_CTLL_TT_FC_Pos; + } + + if (config->channel_direction == PERIPHERAL_TO_MEMORY) { + ctll |= XMC_DMA_CTLL_PERIPHERAL_TO_MEMORY << GPDMA0_CH_CTLL_TT_FC_Pos; + } + + if (block->source_gather_en && block->source_gather_count > 0) { + ctll |= BIT(GPDMA0_CH_CTLL_SRC_GATHER_EN_Pos); + } + + if (block->dest_scatter_en && block->dest_scatter_count > 0) { + ctll |= BIT(GPDMA0_CH_CTLL_DST_SCATTER_EN_Pos); + } + + return ctll; +} + +#define SET_CHECK_SCATTER_GATHER(type) \ + do { \ + if (block->type##_en && block->type##_count > 0 && !type.enabled) { \ + type.enabled = true; \ + type.interval = block->type##_interval; \ + type.count = block->type##_count; \ + } else if (block->type##_en && type.enabled) { \ + if (block->type##_interval != type.interval || \ + block->type##_count != type.count) { \ + LOG_ERR(STRINGIFY(type) " parameters must be consistent " \ + "across enabled blocks"); \ + return -EINVAL; \ + } \ + } \ + } while (0) + static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct dma_config *config) { struct dma_xmc4xxx_data *dev_data = dev->data; @@ -127,6 +203,8 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct struct dma_block_config *block = config->head_block; XMC_DMA_t *dma = dev_cfg->dma; uint8_t dlr_line = DLR_LINE_UNSET; + struct dma_xmc4xxx_scatter_gather source_gather = { 0 }; + struct dma_xmc4xxx_scatter_gather dest_scatter = { 0 }; if (channel >= dev_data->ctx.dma_channels) { LOG_ERR("Invalid channel number"); @@ -150,14 +228,16 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct return -EINVAL; } - if (config->block_count != 1) { - LOG_ERR("Invalid block count"); + if (config->block_count > CONFIG_DMA_XMC4XXX_NUM_DESCRIPTORS) { + LOG_ERR("Block count exceeds descriptor array size"); return -EINVAL; } - if (block->source_gather_en || block->dest_scatter_en) { - if (dma != XMC_DMA0 || channel >= 2) { - LOG_ERR("Gather/scatter only supported on DMA0 on ch0 and ch1"); + if (block->source_gather_en || block->dest_scatter_en || config->block_count != 1 || + config->cyclic) { + if ((uint32_t)dma != (uint32_t)XMC_DMA0 || channel >= 2) { + LOG_ERR("Multi-block, cyclic and gather/scatter only supported on DMA0 on " + "ch0 and ch1"); return -EINVAL; } } @@ -199,24 +279,70 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct XMC_DMA_CH_ClearEventStatus(dma, channel, ALL_EVENTS); /* check dma slot number */ - dma->CH[channel].SAR = block->source_address; - dma->CH[channel].DAR = block->dest_address; - dma->CH[channel].LLP = 0; + if (config->block_count == 1 && config->cyclic == 0) { + uint32_t ctll; + + dma->CH[channel].SAR = block->source_address; + dma->CH[channel].DAR = block->dest_address; + dma->CH[channel].LLP = 0; + + /* set number of transactions */ + dma->CH[channel].CTLH = block->block_size / config->source_data_size; + + ctll = dma_xmc4xxx_reg_ctll(block, config); + + SET_CHECK_SCATTER_GATHER(source_gather); + SET_CHECK_SCATTER_GATHER(dest_scatter); + + dma->CH[channel].CTLL = ctll; + + } else { + struct dma_xmc4xxx_descriptor *desc; + + dma->CH[channel].LLP = (uint32_t)&descriptor_list[channel][0]; + dma->CH[channel].CTLL = BIT(GPDMA0_CH_CTLL_LLP_DST_EN_Pos) | + BIT(GPDMA0_CH_CTLL_LLP_SRC_EN_Pos); + for (int i = 0; i < config->block_count; i++) { + uint32_t ctll; + + desc = &descriptor_list[channel][i]; + + desc->sar = block->source_address; + desc->dar = block->dest_address; + desc->ctlh = block->block_size / config->source_data_size; + + ctll = dma_xmc4xxx_reg_ctll(block, config); + + if (i < config->block_count - 1) { + desc->llp = (uint32_t)&descriptor_list[channel][i + 1]; + } else if (config->cyclic) { + desc->llp = (uint32_t)&descriptor_list[channel][0]; + } else { + desc->llp = 0; + } + + if (i < config->block_count - 1 || config->cyclic) { + ctll |= BIT(GPDMA0_CH_CTLL_LLP_DST_EN_Pos) | + BIT(GPDMA0_CH_CTLL_LLP_SRC_EN_Pos); + } + + desc->ctll = ctll; + + SET_CHECK_SCATTER_GATHER(source_gather); + SET_CHECK_SCATTER_GATHER(dest_scatter); + + block = block->next_block; + } + } + + block = config->head_block; - /* set number of transactions */ - dma->CH[channel].CTLH = block->block_size / config->source_data_size; /* set priority and software handshaking for src/dst. if hardware hankshaking is used */ /* it will be enabled later in the code */ dma->CH[channel].CFGL = (config->channel_priority << GPDMA0_CH_CFGL_CH_PRIOR_Pos) | GPDMA0_CH_CFGL_HS_SEL_SRC_Msk | GPDMA0_CH_CFGL_HS_SEL_DST_Msk; - dma->CH[channel].CTLL = config->dest_data_size / 2 << GPDMA0_CH_CTLL_DST_TR_WIDTH_Pos | - config->source_data_size / 2 << GPDMA0_CH_CTLL_SRC_TR_WIDTH_Pos | - block->dest_addr_adj << GPDMA0_CH_CTLL_DINC_Pos | - block->source_addr_adj << GPDMA0_CH_CTLL_SINC_Pos | - config->dest_burst_length / 4 << GPDMA0_CH_CTLL_DEST_MSIZE_Pos | - config->source_burst_length / 4 << GPDMA0_CH_CTLL_SRC_MSIZE_Pos | - BIT(GPDMA0_CH_CTLL_INT_EN_Pos); + dma->CH[channel].CFGH = 0; if (config->channel_direction == MEMORY_TO_PERIPHERAL || config->channel_direction == PERIPHERAL_TO_MEMORY) { @@ -224,13 +350,13 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct uint8_t dlr_line_reg = XMC4XXX_DMA_GET_LINE(config->dma_slot); dlr_line = dlr_line_reg; - if (dma == XMC_DMA0 && dlr_line > 7) { + if ((uint32_t)dma == (uint32_t)XMC_DMA0 && dlr_line > 7) { LOG_ERR("Unsupported request line %d for DMA0." "Should be in range [0,7]", dlr_line); return -EINVAL; } - if (dma == XMC_DMA1 && (dlr_line < 8 || dlr_line > 11)) { + if ((uint32_t)dma == (uint32_t)XMC_DMA1 && (dlr_line < 8 || dlr_line > 11)) { LOG_ERR("Unsupported request line %d for DMA1." "Should be in range [8,11]", dlr_line); return -EINVAL; @@ -243,12 +369,12 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct DLR->LNEN |= BIT(dlr_line); /* connect DMA Line to SR */ - if (dma == XMC_DMA0) { + if ((uint32_t)dma == (uint32_t)XMC_DMA0) { DLR->SRSEL0 &= ~(DLR_SRSEL_RS_MSK << (dlr_line_reg * DLR_SRSEL_RS_BITSIZE)); DLR->SRSEL0 |= request_source << (dlr_line_reg * DLR_SRSEL_RS_BITSIZE); } - if (dma == XMC_DMA1) { + if ((uint32_t)dma == (uint32_t)XMC_DMA1) { dlr_line_reg -= 8; DLR->SRSEL1 &= ~(DLR_SRSEL_RS_MSK << (dlr_line_reg * DLR_SRSEL_RS_BITSIZE)); DLR->SRSEL1 |= request_source << (dlr_line_reg * DLR_SRSEL_RS_BITSIZE); @@ -258,35 +384,52 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct if (config->channel_direction == MEMORY_TO_PERIPHERAL) { dma->CH[channel].CFGH = (dlr_line_reg << GPDMA0_CH_CFGH_DEST_PER_Pos) | 4; dma->CH[channel].CFGL &= ~BIT(GPDMA0_CH_CFGL_HS_SEL_DST_Pos); - dma->CH[channel].CTLL |= 1 << GPDMA0_CH_CTLL_TT_FC_Pos; } if (config->channel_direction == PERIPHERAL_TO_MEMORY) { dma->CH[channel].CFGH = (dlr_line_reg << GPDMA0_CH_CFGH_SRC_PER_Pos) | 4; dma->CH[channel].CFGL &= ~BIT(GPDMA0_CH_CFGL_HS_SEL_SRC_Pos); - dma->CH[channel].CTLL |= 2 << GPDMA0_CH_CTLL_TT_FC_Pos; } } - if (block->source_gather_en) { - dma->CH[channel].CTLL |= BIT(GPDMA0_CH_CTLL_SRC_GATHER_EN_Pos); + if (block->fifo_mode_control > 0) { + dma->CH[channel].CFGH |= GPDMA0_CH_CFGH_FIFO_MODE_Msk; + } + + if ((uint32_t)dma == (uint32_t)XMC_DMA0) { + if (channel == 0 || channel == 1) { + /* reset scatter/gather registers */ + dma->CH[channel].SGR = 0; + dma->CH[channel].DSR = 0; + } + } + + if (source_gather.enabled) { /* truncate if we are out of range */ - dma->CH[channel].SGR = (block->source_gather_interval & GPDMA0_CH_SGR_SGI_Msk) | - block->source_gather_count << GPDMA0_CH_SGR_SGC_Pos; + dma->CH[channel].SGR = (source_gather.interval & GPDMA0_CH_SGR_SGI_Msk) | + source_gather.count << GPDMA0_CH_SGR_SGC_Pos; } - if (block->dest_scatter_en) { - dma->CH[channel].CTLL |= BIT(GPDMA0_CH_CTLL_DST_SCATTER_EN_Pos); + if (dest_scatter.enabled) { /* truncate if we are out of range */ - dma->CH[channel].DSR = (block->dest_scatter_interval & GPDMA0_CH_DSR_DSI_Msk) | - block->dest_scatter_count << GPDMA0_CH_DSR_DSC_Pos; + dma->CH[channel].DSR = (dest_scatter.interval & GPDMA0_CH_DSR_DSI_Msk) | + dest_scatter.count << GPDMA0_CH_DSR_DSC_Pos; } dev_data->channels[channel].cb = config->dma_callback; dev_data->channels[channel].user_data = config->user_data; - dev_data->channels[channel].block_ts = block->block_size / config->source_data_size; + dev_data->channels[channel].transfer_size = block->block_size; dev_data->channels[channel].source_data_size = config->source_data_size; dev_data->channels[channel].dlr_line = dlr_line; + dev_data->channels[channel].channel_direction = config->channel_direction; + dev_data->channels[channel].dest_addr_adj = block->dest_addr_adj; + dev_data->channels[channel].dest_address = block->dest_address; + + if (config->block_count > 1) { + dev_data->channels[channel].multi_block = true; + } else { + dev_data->channels[channel].multi_block = false; + } XMC_DMA_CH_DisableEvent(dma, channel, ALL_EVENTS); XMC_DMA_CH_EnableEvent(dma, channel, XMC_DMA_CH_EVENT_TRANSFER_COMPLETE); @@ -309,8 +452,14 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct static int dma_xmc4xxx_start(const struct device *dev, uint32_t channel) { const struct dma_xmc4xxx_config *dev_cfg = dev->config; + struct dma_xmc4xxx_data *dev_data = dev->data; + uint8_t dlr_line = dev_data->channels[channel].dlr_line; LOG_DBG("Starting channel %d", channel); + if (dlr_line != DLR_LINE_UNSET && (DLR->LNEN & BIT(dlr_line)) == 0) { + DLR->LNEN |= BIT(dlr_line); + } + XMC_DMA_CH_Enable(dev_cfg->dma, channel); return 0; } @@ -335,10 +484,8 @@ static int dma_xmc4xxx_stop(const struct device *dev, uint32_t channel) DLR->LNEN &= ~BIT(dma_channel->dlr_line); } - dma_channel->dlr_line = DLR_LINE_UNSET; - dma_channel->cb = NULL; - XMC_DMA_CH_Disable(dma, channel); + XMC_DMA_CH_Resume(dma, channel); return 0; } @@ -367,7 +514,8 @@ static int dma_xmc4xxx_reload(const struct device *dev, uint32_t channel, uint32 LOG_ERR("Block transactions must be <= 4095"); return -EINVAL; } - dma_channel->block_ts = block_ts; + dma_channel->transfer_size = size; + dma_channel->dest_address = dst; /* do we need to clear any errors */ dma->CH[channel].SAR = src; @@ -384,6 +532,7 @@ static int dma_xmc4xxx_get_status(const struct device *dev, uint32_t channel, const struct dma_xmc4xxx_config *dev_cfg = dev->config; XMC_DMA_t *dma = dev_cfg->dma; struct dma_xmc4xxx_channel *dma_channel; + uint32_t transferred_bytes; if (channel >= dev_data->ctx.dma_channels) { LOG_ERR("Invalid channel number"); @@ -393,8 +542,27 @@ static int dma_xmc4xxx_get_status(const struct device *dev, uint32_t channel, stat->busy = XMC_DMA_CH_IsEnabled(dma, channel); - stat->pending_length = dma_channel->block_ts - XMC_DMA_CH_GetTransferredData(dma, channel); - stat->pending_length *= dma_channel->source_data_size; + if (dma_channel->multi_block) { + /* not supported for multi-block transfers */ + stat->pending_length = 0; + return 0; + } + + /* Use DAR to check for transferred bytes when possible. Value CTL.BLOCK_TS does not */ + /* appear to guarantee that the last value is fully transferred to dest. */ + if (dma_channel->dest_addr_adj == DMA_ADDR_ADJ_INCREMENT) { + transferred_bytes = dma->CH[channel].DAR - dma_channel->dest_address; + stat->pending_length = dma_channel->transfer_size - transferred_bytes; + } else if (dma_channel->dest_addr_adj == DMA_ADDR_ADJ_DECREMENT) { + transferred_bytes = dma_channel->dest_address - dma->CH[channel].DAR; + stat->pending_length = dma_channel->transfer_size - transferred_bytes; + } else { + uint32_t num_source_transfers = XMC_DMA_CH_GetTransferredData(dma, channel); + + stat->pending_length = dma_channel->transfer_size - + num_source_transfers * dma_channel->source_data_size; + } + /* stat->dir and other remaining fields are not set. They are not */ /* useful for xmc4xxx peripheral drivers. */ @@ -457,7 +625,7 @@ static int dma_xmc4xxx_init(const struct device *dev) return 0; } -static const struct dma_driver_api dma_xmc4xxx_driver_api = { +static DEVICE_API(dma, dma_xmc4xxx_driver_api) = { .config = dma_xmc4xxx_config, .reload = dma_xmc4xxx_reload, .start = dma_xmc4xxx_start, diff --git a/drivers/dma/dmamux_stm32.c b/drivers/dma/dmamux_stm32.c index 71a470f532851..f7a16caca7638 100644 --- a/drivers/dma/dmamux_stm32.c +++ b/drivers/dma/dmamux_stm32.c @@ -290,7 +290,7 @@ static int dmamux_stm32_init(const struct device *dev) return 0; } -static const struct dma_driver_api dma_funcs = { +static DEVICE_API(dma, dma_funcs) = { .reload = dmamux_stm32_reload, .config = dmamux_stm32_configure, .start = dmamux_stm32_start, diff --git a/drivers/eeprom/eeprom_at2x.c b/drivers/eeprom/eeprom_at2x.c index 94596c86d1e55..0061ee9c26c02 100644 --- a/drivers/eeprom/eeprom_at2x.c +++ b/drivers/eeprom/eeprom_at2x.c @@ -419,7 +419,6 @@ static int eeprom_at25_read(const struct device *dev, off_t offset, void *buf, size_t len) { const struct eeprom_at2x_config *config = dev->config; - struct eeprom_at2x_data *data = dev->data; size_t cmd_len = 1 + config->addr_width / 8; uint8_t cmd[4] = { EEPROM_AT25_READ, 0, 0, 0 }; uint8_t *paddr; @@ -474,7 +473,6 @@ static int eeprom_at25_read(const struct device *dev, off_t offset, void *buf, err = eeprom_at25_wait_for_idle(dev); if (err) { LOG_ERR("EEPROM idle wait failed (err %d)", err); - k_mutex_unlock(&data->lock); return err; } @@ -648,7 +646,7 @@ static DEVICE_API(eeprom, eeprom_at2x_api) = { .write_fn = eeprom_at##t##_write, \ }; \ static struct eeprom_at2x_data eeprom_at##t##_data_##n; \ - DEVICE_DT_DEFINE(INST_DT_AT2X(n, t), &eeprom_at2x_init, \ + DEVICE_DT_DEFINE(INST_DT_AT2X(n, t), eeprom_at2x_init, \ NULL, &eeprom_at##t##_data_##n, \ &eeprom_at##t##_config_##n, POST_KERNEL, \ CONFIG_EEPROM_AT2X_INIT_PRIORITY, \ diff --git a/drivers/eeprom/eeprom_shell.c b/drivers/eeprom/eeprom_shell.c index ee6ce961e5b71..be0539780bae3 100644 --- a/drivers/eeprom/eeprom_shell.c +++ b/drivers/eeprom/eeprom_shell.c @@ -42,7 +42,7 @@ static int cmd_read(const struct shell *sh, size_t argc, char **argv) addr = strtoul(argv[args_indx.offset], NULL, 0); len = strtoul(argv[args_indx.length], NULL, 0); - eeprom = device_get_binding(argv[args_indx.device]); + eeprom = shell_device_get_binding(argv[args_indx.device]); if (!eeprom) { shell_error(sh, "EEPROM device not found"); return -EINVAL; @@ -98,7 +98,7 @@ static int cmd_write(const struct shell *sh, size_t argc, char **argv) wr_buf[i] = byte; } - eeprom = device_get_binding(argv[args_indx.device]); + eeprom = shell_device_get_binding(argv[args_indx.device]); if (!eeprom) { shell_error(sh, "EEPROM device not found"); return -EINVAL; @@ -134,7 +134,7 @@ static int cmd_size(const struct shell *sh, size_t argc, char **argv) { const struct device *eeprom; - eeprom = device_get_binding(argv[args_indx.device]); + eeprom = shell_device_get_binding(argv[args_indx.device]); if (!eeprom) { shell_error(sh, "EEPROM device not found"); return -EINVAL; @@ -167,7 +167,7 @@ static int cmd_fill(const struct shell *sh, size_t argc, char **argv) } memset(wr_buf, pattern, MIN(len, CONFIG_EEPROM_SHELL_BUFFER_SIZE)); - eeprom = device_get_binding(argv[args_indx.device]); + eeprom = shell_device_get_binding(argv[args_indx.device]); if (!eeprom) { shell_error(sh, "EEPROM device not found"); return -EINVAL; @@ -213,10 +213,15 @@ static int cmd_fill(const struct shell *sh, size_t argc, char **argv) return 0; } +static bool device_is_eeprom(const struct device *dev) +{ + return DEVICE_API_IS(eeprom, dev); +} + /* Device name autocompletion support */ static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_eeprom); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/entropy/CMakeLists.txt b/drivers/entropy/CMakeLists.txt index 8a67fc3a03e8d..6f27e39c4c6ab 100644 --- a/drivers/entropy/CMakeLists.txt +++ b/drivers/entropy/CMakeLists.txt @@ -11,7 +11,9 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_MCUX_RNG entropy_mcux_rng. zephyr_library_sources_ifdef(CONFIG_ENTROPY_MCUX_RNGA entropy_mcux_rnga.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_MCUX_TRNG entropy_mcux_trng.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_MCUX_CAAM entropy_mcux_caam.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_NXP_ELE_TRNG entropy_nxp_ele.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_NRF5_RNG entropy_nrf5.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_NRF_CRACEN_CTR_DRBG entropy_nrf_cracen.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_SAM_RNG entropy_sam.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_SMARTBOND_TRNG entropy_smartbond.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_STM32_RNG entropy_stm32.c) @@ -25,15 +27,17 @@ if(CONFIG_FAKE_ENTROPY_NATIVE_POSIX) endif() endif() -zephyr_library_sources_ifdef(CONFIG_USERSPACE entropy_handlers.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_RV32M1_TRNG entropy_rv32m1_trng.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_TRNG entropy_gecko_trng.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_NEORV32_TRNG entropy_neorv32_trng.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_BT_HCI entropy_bt_hci.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_SE entropy_gecko_se.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_PSA_CRYPTO_RNG entropy_psa_crypto.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_NPCX_DRBG entropy_npcx_drbg.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_MAX32_TRNG entropy_max32.c) -zephyr_library_sources_ifdef(CONFIG_ENTROPY_RENESAS_RA_RSIP_E51A_TRNG entropy_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_USERSPACE entropy_handlers.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_RV32M1_TRNG entropy_rv32m1_trng.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_TRNG entropy_gecko_trng.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_NEORV32_TRNG entropy_neorv32_trng.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_BT_HCI entropy_bt_hci.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_SE entropy_gecko_se.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_SILABS_SIWX91X entropy_silabs_siwx91x.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_PSA_CRYPTO_RNG entropy_psa_crypto.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_NPCX_DRBG entropy_npcx_drbg.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_MAX32_TRNG entropy_max32.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_RENESAS_RA entropy_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_SY1XX_TRNG entropy_sy1xx_trng.c) zephyr_library_link_libraries_ifdef(CONFIG_BUILD_WITH_TFM tfm_api) diff --git a/drivers/entropy/Kconfig b/drivers/entropy/Kconfig index debd0f8d7a110..62242ecaccf2b 100644 --- a/drivers/entropy/Kconfig +++ b/drivers/entropy/Kconfig @@ -23,21 +23,25 @@ config ENTROPY_INIT_PRIORITY source "drivers/entropy/Kconfig.b91" source "drivers/entropy/Kconfig.cc13xx_cc26xx" source "drivers/entropy/Kconfig.mcux" +source "drivers/entropy/Kconfig.nxp" source "drivers/entropy/Kconfig.stm32" source "drivers/entropy/Kconfig.esp32" source "drivers/entropy/Kconfig.nrf5" +source "drivers/entropy/Kconfig.nrf_cracen" source "drivers/entropy/Kconfig.sam" source "drivers/entropy/Kconfig.smartbond" source "drivers/entropy/Kconfig.native_posix" source "drivers/entropy/Kconfig.rv32m1" source "drivers/entropy/Kconfig.litex" source "drivers/entropy/Kconfig.gecko" +source "drivers/entropy/Kconfig.siwx91x" source "drivers/entropy/Kconfig.neorv32" source "drivers/entropy/Kconfig.bt_hci" source "drivers/entropy/Kconfig.psa_crypto" source "drivers/entropy/Kconfig.npcx" source "drivers/entropy/Kconfig.max32" source "drivers/entropy/Kconfig.renesas_ra" +source "drivers/entropy/Kconfig.sy1xx" config ENTROPY_HAS_DRIVER bool diff --git a/drivers/entropy/Kconfig.nrf_cracen b/drivers/entropy/Kconfig.nrf_cracen new file mode 100644 index 0000000000000..8941096a126f3 --- /dev/null +++ b/drivers/entropy/Kconfig.nrf_cracen @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config ENTROPY_NRF_CRACEN_CTR_DRBG + bool "nRF entropy driver based on the CRACEN CTR_DRBG driver" + default y + depends on DT_HAS_NORDIC_NRF_CRACEN_CTRDRBG_ENABLED + depends on SOC_COMPATIBLE_NRF54LX + select ENTROPY_HAS_DRIVER + select NRFX_CRACEN + help + This option enables the 54L CRACEN based entropy driver, based on the nrfx CRACEN CTR_DRBG + random driver. + Notes: This driver is only compatible with 54L devices, and may only be used from one processor + core. This driver cannot be used in conjunction with the nRF security PSA solution, as both + would attempt to use the CRACEN HW exclusively; When that is enabled, the PSA crypto entropy + driver should be selected instead. diff --git a/drivers/entropy/Kconfig.nxp b/drivers/entropy/Kconfig.nxp new file mode 100644 index 0000000000000..895ff59dd76f8 --- /dev/null +++ b/drivers/entropy/Kconfig.nxp @@ -0,0 +1,12 @@ +# NXP ELE entropy configuration options + +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config ENTROPY_NXP_ELE_TRNG + bool "NXP ELE TRNG driver" + default y + depends on DT_HAS_NXP_ELE_TRNG_ENABLED + select ENTROPY_HAS_DRIVER + help + This option enables the ELE true random number generator (TRNG) diff --git a/drivers/entropy/Kconfig.renesas_ra b/drivers/entropy/Kconfig.renesas_ra index c212e7ba51be9..fc5b14dc31564 100644 --- a/drivers/entropy/Kconfig.renesas_ra +++ b/drivers/entropy/Kconfig.renesas_ra @@ -3,11 +3,13 @@ # Renesas RA entropy generator driver configuration -config ENTROPY_RENESAS_RA_RSIP_E51A_TRNG - bool "Renesas RA RSIP-E51A TRNG driver" +config ENTROPY_RENESAS_RA + bool "Renesas RA TRNG driver" default y - depends on DT_HAS_RENESAS_RA_RSIP_E51A_TRNG_ENABLED + depends on DT_HAS_RENESAS_RA_RSIP_E51A_TRNG_ENABLED || DT_HAS_RENESAS_RA_SCE9_RNG_ENABLED \ + || DT_HAS_RENESAS_RA_SCE7_RNG_ENABLED || DT_HAS_RENESAS_RA_SCE5_RNG_ENABLED \ + || DT_HAS_RENESAS_RA_TRNG_ENABLED select ENTROPY_HAS_DRIVER select USE_RA_FSP_SCE help - This option enables the Renesas RA RSIP-E51A RNG. + This option enables entropy driver for Renesas RA diff --git a/drivers/entropy/Kconfig.siwx91x b/drivers/entropy/Kconfig.siwx91x new file mode 100644 index 0000000000000..e8a45fea10cdb --- /dev/null +++ b/drivers/entropy/Kconfig.siwx91x @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config ENTROPY_SILABS_SIWX91X + bool "SiWx91x RNG driver" + default y + depends on DT_HAS_SILABS_SIWX91X_RNG_ENABLED + select ENTROPY_HAS_DRIVER + help + Enable hardware Random Number Generator embedded on Silicon Labs + SiWx91x chips. diff --git a/drivers/entropy/Kconfig.stm32 b/drivers/entropy/Kconfig.stm32 index 1772b16c93f52..4bf47e7224dd1 100644 --- a/drivers/entropy/Kconfig.stm32 +++ b/drivers/entropy/Kconfig.stm32 @@ -6,7 +6,7 @@ menuconfig ENTROPY_STM32_RNG bool "STM32 RNG driver" default y - depends on DT_HAS_ST_STM32_RNG_ENABLED + depends on DT_HAS_ST_STM32_RNG_ENABLED || DT_HAS_ST_STM32_RNG_NOIRQ_ENABLED select ENTROPY_HAS_DRIVER select USE_STM32_LL_RNG help @@ -55,6 +55,7 @@ config ENTROPY_STM32_ISR_THRESHOLD config ENTROPY_STM32_CLK_CHECK bool "Runtime clock configuration check" + depends on !SOC_SERIES_STM32WB0X default y help Enables a check on RNG clock configuration. Correct clock diff --git a/drivers/entropy/Kconfig.sy1xx b/drivers/entropy/Kconfig.sy1xx new file mode 100644 index 0000000000000..bf40abe45b309 --- /dev/null +++ b/drivers/entropy/Kconfig.sy1xx @@ -0,0 +1,8 @@ +# Copyright (c) 2025 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +config ENTROPY_SY1XX_TRNG + bool "Sensry sy1xx soc family true random number generator (TRNG) driver" + default y + depends on DT_HAS_SENSRY_SY1XX_TRNG_ENABLED + select ENTROPY_HAS_DRIVER diff --git a/drivers/entropy/entropy_esp32.c b/drivers/entropy/entropy_esp32.c index ddcf961fe4ad8..ab0c4e81c26fd 100644 --- a/drivers/entropy/entropy_esp32.c +++ b/drivers/entropy/entropy_esp32.c @@ -20,6 +20,26 @@ LOG_MODULE_REGISTER(entropy, CONFIG_ENTROPY_LOG_LEVEL); +#if SOC_LP_TIMER_SUPPORTED +#include "hal/lp_timer_hal.h" +#endif + +#if defined CONFIG_SOC_SERIES_ESP32S3 +/* If APB clock is 80 MHz, the maximum sampling frequency is around 45 KHz */ +/* 45 KHz reading frequency is the maximum we have tested so far on S3 */ +#define APB_CYCLE_WAIT_NUM (1778) +#elif defined CONFIG_SOC_SERIES_ESP32C6 +/* On ESP32C6, we only read one byte at a time, then XOR the value with + * an asynchronous timer (see code below). + * The current value translates to a sampling frequency of around 62.5 KHz + * for reading 8 bit samples, which is the rate at which the RNG was tested, + * plus additional overhead for the calculation, making it slower. + */ +#define APB_CYCLE_WAIT_NUM (160 * 16) +#else +#define APB_CYCLE_WAIT_NUM (16) +#endif + static inline uint32_t entropy_esp32_get_u32(void) { /* The PRNG which implements WDEV_RANDOM register gets 2 bits @@ -30,18 +50,29 @@ static inline uint32_t entropy_esp32_get_u32(void) * wait a bit longer due to extra time spent in arithmetic and branch statements. */ - uint32_t cpu_to_apb_freq_ratio = - esp_clk_cpu_freq() / esp_clk_apb_freq(); + uint32_t cpu_to_apb_freq_ratio = esp_clk_cpu_freq() / esp_clk_apb_freq(); static uint32_t last_ccount; uint32_t ccount; - + uint32_t result = 0; +#if SOC_LP_TIMER_SUPPORTED + for (size_t i = 0; i < sizeof(result); i++) { + do { + ccount = esp_cpu_get_cycle_count(); + result ^= REG_READ(WDEV_RND_REG); + } while (ccount - last_ccount < cpu_to_apb_freq_ratio * APB_CYCLE_WAIT_NUM); + uint32_t current_rtc_timer_counter = (lp_timer_hal_get_cycle_count() & 0xFF); + + result ^= ((result ^ current_rtc_timer_counter) & 0xFF) << (i * 8); + } +#else do { ccount = esp_cpu_get_cycle_count(); - } while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16); + result ^= REG_READ(WDEV_RND_REG); + } while (ccount - last_ccount < cpu_to_apb_freq_ratio * APB_CYCLE_WAIT_NUM); +#endif last_ccount = ccount; - - return REG_READ(WDEV_RND_REG); + return result ^ REG_READ(WDEV_RND_REG); } static int entropy_esp32_get_entropy(const struct device *dev, uint8_t *buf, diff --git a/drivers/entropy/entropy_nrf_cracen.c b/drivers/entropy/entropy_nrf_cracen.c new file mode 100644 index 0000000000000..8c34a06db61aa --- /dev/null +++ b/drivers/entropy/entropy_nrf_cracen.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define DT_DRV_COMPAT nordic_nrf_cracen_ctrdrbg + +static int nrf_cracen_get_entropy_isr(const struct device *dev, uint8_t *buf, uint16_t len, + uint32_t flags) +{ + (void)dev; + (void)flags; + + unsigned int key = irq_lock(); + + /* This will take approximately 2 + (ceil(len/16) + 3)*3 us. i.e. 14us for 16 bytes */ + int ret = nrfx_cracen_ctr_drbg_random_get(buf, len); + + irq_unlock(key); + + if (likely(ret == NRFX_SUCCESS)) { + return len; + } else if (ret == NRFX_ERROR_INVALID_PARAM) { + return -EINVAL; + } else { + return -EAGAIN; + } +} + +static int nrf_cracen_get_entropy(const struct device *dev, uint8_t *buf, uint16_t len) +{ + int ret = nrf_cracen_get_entropy_isr(dev, buf, len, 0); + + if (ret < 0) { + return ret; + } else { + return 0; + } +} + +static int nrf_cracen_cracen_init(const struct device *dev) +{ + (void)dev; + + int ret = nrfx_cracen_ctr_drbg_init(); + + if (ret == NRFX_SUCCESS) { + return 0; + } else { + return -EIO; + } +} + +static DEVICE_API(entropy, nrf_cracen_api_funcs) = { + .get_entropy = nrf_cracen_get_entropy, + .get_entropy_isr = nrf_cracen_get_entropy_isr +}; + +DEVICE_DT_INST_DEFINE(0, nrf_cracen_cracen_init, NULL, NULL, NULL, PRE_KERNEL_1, + CONFIG_ENTROPY_INIT_PRIORITY, &nrf_cracen_api_funcs); diff --git a/drivers/entropy/entropy_nxp_ele.c b/drivers/entropy/entropy_nxp_ele.c new file mode 100644 index 0000000000000..8d8e037de7f04 --- /dev/null +++ b/drivers/entropy/entropy_nxp_ele.c @@ -0,0 +1,71 @@ +/* entropy_nxp_ele.c - NXP ELE entropy driver */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_ele_trng + +#include +#include +#include +#include +#include +#include + +#include "sss_crypto.h" + +struct entropy_ele_data_str { + struct k_sem sem_lock; +}; + +static struct entropy_ele_data_str entropy_ele_data; + +static int entropy_ele_get_entropy(const struct device *dev, uint8_t *buf, uint16_t len) +{ + sss_sscp_rng_t ctx; + int result = -EIO; + + __ASSERT_NO_MSG(buf != NULL); + __ASSERT_NO_MSG(&entropy_ele_data == dev->data); + + k_sem_take(&entropy_ele_data.sem_lock, K_FOREVER); + + if (CRYPTO_InitHardware() != kStatus_Success) { + goto exit; + } + + if (sss_sscp_rng_context_init(&g_sssSession, &ctx, 0u) != kStatus_SSS_Success) { + goto exit; + } + + if (sss_sscp_rng_get_random(&ctx, buf, len) != kStatus_SSS_Success) { + goto exit; + } + + if (sss_sscp_rng_free(&ctx) != kStatus_SSS_Success) { + goto exit; + } + + result = 0; + +exit: + k_sem_give(&entropy_ele_data.sem_lock); + return result; +} + +static int entropy_ele_init(const struct device *dev) +{ + __ASSERT_NO_MSG(&entropy_ele_data == dev->data); + + k_sem_init(&entropy_ele_data.sem_lock, 1, 1); + + return 0; +} + +static DEVICE_API(entropy, entropy_ele_api_funcs) = {.get_entropy = entropy_ele_get_entropy}; + +DEVICE_DT_INST_DEFINE(0, entropy_ele_init, NULL, &entropy_ele_data, NULL, PRE_KERNEL_1, + CONFIG_ENTROPY_INIT_PRIORITY, &entropy_ele_api_funcs); diff --git a/drivers/entropy/entropy_renesas_ra.c b/drivers/entropy/entropy_renesas_ra.c index 4083ecbc3e1d2..4ac70c17142fa 100644 --- a/drivers/entropy/entropy_renesas_ra.c +++ b/drivers/entropy/entropy_renesas_ra.c @@ -4,15 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT renesas_ra_rsip_e51a_trng - #include #include #include "hw_sce_trng_private.h" #include "hw_sce_private.h" -static int entropy_ra_rsip_trng_get_entropy(const struct device *dev, uint8_t *buf, uint16_t len) +static int entropy_renesas_ra_get_entropy(const struct device *dev, uint8_t *buf, uint16_t len) { ARG_UNUSED(dev); @@ -35,15 +33,22 @@ static int entropy_ra_rsip_trng_get_entropy(const struct device *dev, uint8_t *b return 0; } -static DEVICE_API(entropy, entropy_ra_rsip_trng_api) = { - .get_entropy = entropy_ra_rsip_trng_get_entropy, +static DEVICE_API(entropy, entropy_renesas_ra_api) = { + .get_entropy = entropy_renesas_ra_get_entropy, }; -static int entropy_ra_rsip_trng_init(const struct device *dev) +static int entropy_renesas_ra_init(const struct device *dev) { HW_SCE_McuSpecificInit(); return 0; } -DEVICE_DT_INST_DEFINE(0, entropy_ra_rsip_trng_init, NULL, NULL, NULL, PRE_KERNEL_1, - CONFIG_ENTROPY_INIT_PRIORITY, &entropy_ra_rsip_trng_api); +#define RENESAS_RA_ENTROPY_INIT(nodeid) \ + DEVICE_DT_DEFINE(nodeid, entropy_renesas_ra_init, NULL, NULL, NULL, PRE_KERNEL_1, \ + CONFIG_ENTROPY_INIT_PRIORITY, &entropy_renesas_ra_api) + +DT_FOREACH_STATUS_OKAY(renesas_ra_rsip_e51a_trng, RENESAS_RA_ENTROPY_INIT) +DT_FOREACH_STATUS_OKAY(renesas_ra_sce5_rng, RENESAS_RA_ENTROPY_INIT) +DT_FOREACH_STATUS_OKAY(renesas_ra_sce7_rng, RENESAS_RA_ENTROPY_INIT) +DT_FOREACH_STATUS_OKAY(renesas_ra_sce9_rng, RENESAS_RA_ENTROPY_INIT) +DT_FOREACH_STATUS_OKAY(renesas_ra_trng, RENESAS_RA_ENTROPY_INIT) diff --git a/drivers/entropy/entropy_silabs_siwx91x.c b/drivers/entropy/entropy_silabs_siwx91x.c new file mode 100644 index 0000000000000..bb4a256daeeb5 --- /dev/null +++ b/drivers/entropy/entropy_silabs_siwx91x.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT silabs_siwx91x_rng + +#include + +#include "rsi_rom_rng.h" +#include "rsi_rom_clks.h" + +static int siwx91x_get_entropy_isr(const struct device *dev, uint8_t *buffer, + uint16_t length, uint32_t flags) +{ + uint32_t u32_count = length / sizeof(uint32_t); + uint32_t u8_count = u32_count * sizeof(uint32_t); + uint32_t u8_remainder = length - u8_count; + uint32_t swap_space; + + if (!(flags & ENTROPY_BUSYWAIT)) { + return -ENOTSUP; + } + RSI_RNG_GetBytes((void *)dev->config, (uint32_t *)buffer, u32_count); + if (length % sizeof(uint32_t)) { + RSI_RNG_GetBytes((void *)dev->config, &swap_space, 1); + memcpy(buffer + u8_count, &swap_space, u8_remainder); + } + + return 0; +} + +static int siwx91x_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length) +{ + return siwx91x_get_entropy_isr(dev, buffer, length, ENTROPY_BUSYWAIT); +} + +static int siwx91x_init(const struct device *dev) +{ + int ret; + + ret = RSI_CLK_PeripheralClkEnable1(M4CLK, HWRNG_PCLK_ENABLE); + if (ret) { + return -EIO; + } + ret = RSI_RNG_Start((void *)dev->config, RSI_RNG_TRUE_RANDOM); + if (ret) { + return -EIO; + } + return 0; +} + +static DEVICE_API(entropy, siwx91x_api) = { + .get_entropy = siwx91x_get_entropy, + .get_entropy_isr = siwx91x_get_entropy_isr, +}; + +#define SIWX91X_RNG_INIT(idx) \ + DEVICE_DT_INST_DEFINE(idx, siwx91x_init, NULL, NULL, (void *)DT_INST_REG_ADDR(idx), \ + PRE_KERNEL_1, CONFIG_ENTROPY_INIT_PRIORITY, &siwx91x_api); + +DT_INST_FOREACH_STATUS_OKAY(SIWX91X_RNG_INIT) diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index 2accb94f676a7..602daf19277fa 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -6,9 +6,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ - -#define DT_DRV_COMPAT st_stm32_rng - #include #include #include @@ -32,8 +29,7 @@ #include #include "stm32_hsem.h" -#define IRQN DT_INST_IRQN(0) -#define IRQ_PRIO DT_INST_IRQ(0, priority) +#include "entropy_stm32.h" #if defined(RNG_CR_CONDRST) #define STM32_CONDRST_SUPPORT @@ -44,7 +40,7 @@ * - simple rng without hardware fifo and no DMA. * - Variable delay between two consecutive random numbers * (depending on family and clock settings) - * + * - IRQ-less TRNG instances * * Due to the first byte in a stream of bytes being more costly on * some platforms a "water system" inspired algorithm is used to @@ -57,6 +53,9 @@ * The entropy level is checked at the end of every consumption of * entropy. * + * For TRNG instances with no IRQ, a delayable work item is scheduled + * on the system work queue and used to "simulate" device-generated + * interrupts - this is done to reduce polling to a minimum. */ struct rng_pool { @@ -78,6 +77,15 @@ BUILD_ASSERT((CONFIG_ENTROPY_STM32_THR_POOL_SIZE & (CONFIG_ENTROPY_STM32_THR_POOL_SIZE - 1)) == 0, "The CONFIG_ENTROPY_STM32_THR_POOL_SIZE must be a power of 2!"); +/** + * RM0505 §14.4 "TRNG functional description": + * To use the TRNG peripheral the system clock frequency must be + * at least 32 MHz. See also: §6.2.2 "Peripheral clock details". + */ +BUILD_ASSERT(!IS_ENABLED(CONFIG_SOC_STM32WB09XX) || + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC >= (32 * 1000 * 1000), + "STM32WB09: TRNG requires system clock frequency >= 32MHz"); + struct entropy_stm32_rng_dev_cfg { struct stm32_pclken *pclken; }; @@ -88,6 +96,10 @@ struct entropy_stm32_rng_dev_data { struct k_sem sem_lock; struct k_sem sem_sync; struct k_work filling_work; +#if IRQLESS_TRNG + /* work item that polls TRNG to refill pools */ + struct k_work_delayable trng_poll_work; +#endif /* IRQLESS_TRNG */ bool filling_pools; RNG_POOL_DEFINE(isr, CONFIG_ENTROPY_STM32_ISR_POOL_SIZE); @@ -117,6 +129,14 @@ static int entropy_stm32_suspend(void) z_stm32_hsem_lock(CFG_HW_RNG_SEMID, HSEM_LOCK_WAIT_FOREVER); #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE */ LL_RNG_Disable(rng); +#if defined(CONFIG_SOC_STM32WB09XX) + /* RM0505 Rev.2 §14.4: + * "After the TRNG IP is disabled by setting CR.DISABLE, in order to + * properly restart the TRNG IP, the AES_RESET bit must be set to 1 + * (that is, resetting the AES core and restarting all health tests)." + */ + LL_RNG_SetAesReset(rng, 1); +#endif /* CONFIG_SOC_STM32WB09XX */ #ifdef CONFIG_SOC_SERIES_STM32WBAX uint32_t wait_cycles, rng_rate; @@ -158,7 +178,7 @@ static int entropy_stm32_resume(void) res = clock_control_on(dev_data->clock, (clock_control_subsys_t)&dev_cfg->pclken[0]); LL_RNG_Enable(rng); - LL_RNG_EnableIT(rng); + ll_rng_enable_it(rng); return res; } @@ -212,7 +232,7 @@ static void configure_rng(void) #endif /* STM32_CONDRST_SUPPORT */ LL_RNG_Enable(rng); - LL_RNG_EnableIT(rng); + ll_rng_enable_it(rng); } static void acquire_rng(void) @@ -238,11 +258,13 @@ static int entropy_stm32_got_error(RNG_TypeDef *rng) { __ASSERT_NO_MSG(rng != NULL); +#if defined(STM32_CONDRST_SUPPORT) if (LL_RNG_IsActiveFlag_CECS(rng)) { return 1; } +#endif - if (LL_RNG_IsActiveFlag_SEIS(rng)) { + if (ll_rng_is_active_seis(rng)) { return 1; } @@ -262,8 +284,8 @@ static int recover_seed_error(RNG_TypeDef *rng) */ while (LL_RNG_IsEnabledCondReset(rng) || - LL_RNG_IsActiveFlag_SEIS(rng) || - LL_RNG_IsActiveFlag_SECS(rng)) { + ll_rng_is_active_seis(rng) || + ll_rng_is_active_secs(rng)) { count_timeout++; if (count_timeout == 10) { return -ETIMEDOUT; @@ -277,13 +299,13 @@ static int recover_seed_error(RNG_TypeDef *rng) /* SOCS w/o soft-reset support: flush pipeline */ static int recover_seed_error(RNG_TypeDef *rng) { - LL_RNG_ClearFlag_SEIS(rng); + ll_rng_clear_seis(rng); for (int i = 0; i < 12; ++i) { - LL_RNG_ReadRandData32(rng); + (void)ll_rng_read_rand_data(rng); } - if (LL_RNG_IsActiveFlag_SEIS(rng) != 0) { + if (ll_rng_is_active_seis(rng) != 0) { return -EIO; } @@ -299,7 +321,8 @@ static int random_byte_get(void) key = irq_lock(); - if (IS_ENABLED(CONFIG_ENTROPY_STM32_CLK_CHECK) && !k_is_pre_kernel()) { +#if defined(CONFIG_ENTROPY_STM32_CLK_CHECK) + if (!k_is_pre_kernel()) { /* CECS bit signals that a clock configuration issue is detected, * which may lead to generation of non truly random data. */ @@ -307,19 +330,20 @@ static int random_byte_get(void) "CECS = 1: RNG domain clock is too slow.\n" "\tSee ref man and update target clock configuration."); } +#endif /* CONFIG_ENTROPY_STM32_CLK_CHECK */ - if (LL_RNG_IsActiveFlag_SEIS(rng) && (recover_seed_error(rng) < 0)) { + if (ll_rng_is_active_seis(rng) && (recover_seed_error(rng) < 0)) { retval = -EIO; goto out; } - if ((LL_RNG_IsActiveFlag_DRDY(rng) == 1)) { + if (ll_rng_is_active_drdy(rng) == 1) { if (entropy_stm32_got_error(rng)) { retval = -EIO; goto out; } - retval = LL_RNG_ReadRandData32(rng); + retval = ll_rng_read_rand_data(rng); if (retval == 0) { /* A seed error could have occurred between RNG_SR * polling and RND_DR output reading. @@ -342,34 +366,42 @@ static uint16_t generate_from_isr(uint8_t *buf, uint16_t len) { uint16_t remaining_len = len; +#if !IRQLESS_TRNG __ASSERT_NO_MSG(!irq_is_enabled(IRQN)); +#endif /* !IRQLESS_TRNG */ #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) __ASSERT_NO_MSG(z_stm32_hsem_is_owned(CFG_HW_RNG_SEMID)); #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE */ /* do not proceed if a Seed error occurred */ - if (LL_RNG_IsActiveFlag_SECS(entropy_stm32_rng_data.rng) || - LL_RNG_IsActiveFlag_SEIS(entropy_stm32_rng_data.rng)) { + if (ll_rng_is_active_secs(entropy_stm32_rng_data.rng) || + ll_rng_is_active_seis(entropy_stm32_rng_data.rng)) { (void)random_byte_get(); /* this will recover the error */ return 0; /* return cnt is null : no random data available */ } +#if !IRQLESS_TRNG /* Clear NVIC pending bit. This ensures that a subsequent * RNG event will set the Cortex-M single-bit event register * to 1 (the bit is set when NVIC pending IRQ status is * changed from 0 to 1) */ NVIC_ClearPendingIRQ(IRQN); +#endif /* !IRQLESS_TRNG */ do { int byte; - while (LL_RNG_IsActiveFlag_DRDY( + while (ll_rng_is_active_drdy( entropy_stm32_rng_data.rng) != 1) { +#if !IRQLESS_TRNG /* + * Enter low-power mode while waiting for event + * generated by TRNG interrupt becoming pending. + * * To guarantee waking up from the event, the * SEV-On-Pend feature must be enabled (enabled * during ARCH initialization). @@ -381,10 +413,13 @@ static uint16_t generate_from_isr(uint8_t *buf, uint16_t len) __WFE(); __SEV(); __WFE(); +#endif /* !IRQLESS_TRNG */ } byte = random_byte_get(); +#if !IRQLESS_TRNG NVIC_ClearPendingIRQ(IRQN); +#endif /* IRQLESS_TRNG */ if (byte < 0) { continue; @@ -430,8 +465,11 @@ static int start_pool_filling(bool wait) } acquire_rng(); +#if IRQLESS_TRNG + k_work_schedule(&entropy_stm32_rng_data.trng_poll_work, TRNG_GENERATION_DELAY); +#else /* !IRQLESS_TRNG */ irq_enable(IRQN); - +#endif /* IRQLESS_TRNG */ return 0; } @@ -498,8 +536,11 @@ static uint16_t rng_pool_get(struct rng_pool *rngp, uint8_t *buf, * Avoid starting pool filling from ISR as it might require * blocking if RNG is not available and a race condition could * also occur if this ISR has interrupted the RNG ISR. + * + * If the TRNG has no IRQ line, always schedule the work item, + * as this is what fills the RNG pools instead of the ISR. */ - if (k_is_in_isr()) { + if (k_is_in_isr() || IRQLESS_TRNG) { k_work_submit(&entropy_stm32_rng_data.filling_work); } else { start_pool_filling(true); @@ -536,15 +577,13 @@ static void rng_pool_init(struct rng_pool *rngp, uint16_t size, rngp->threshold = threshold; } -static void stm32_rng_isr(const void *arg) +static int perform_pool_refill(void) { int byte, ret; - ARG_UNUSED(arg); - byte = random_byte_get(); if (byte < 0) { - return; + return -EIO; } ret = rng_pool_put((struct rng_pool *)(entropy_stm32_rng_data.isr), @@ -554,7 +593,9 @@ static void stm32_rng_isr(const void *arg) (struct rng_pool *)(entropy_stm32_rng_data.thr), byte); if (ret < 0) { +#if !IRQLESS_TRNG irq_disable(IRQN); +#endif /* !IRQLESS_TRNG */ release_rng(); pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); if (IS_ENABLED(CONFIG_PM_S2RAM)) { @@ -565,7 +606,51 @@ static void stm32_rng_isr(const void *arg) k_sem_give(&entropy_stm32_rng_data.sem_sync); } + + return ret; +} + +#if IRQLESS_TRNG +static void trng_poll_work_item(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + RNG_TypeDef *rng = entropy_stm32_rng_data.rng; + + /* Seed error occurred: reset TRNG and try again */ + if (ll_rng_is_active_secs(entropy_stm32_rng_data.rng) || + ll_rng_is_active_seis(entropy_stm32_rng_data.rng)) { + + (void)random_byte_get(); /* this will recover the error */ + } else if (ll_rng_is_active_drdy(rng)) { + /* Entropy available: read it and fill pools */ + int res = perform_pool_refill(); + + if (res == -ENOBUFS) { + /** + * All RNG pools are full - no more work needed. + * Exit early to stop the work item from re-scheduling + * itself. The RNG peripheral has already been released + * by perform_pool_refill(). + */ + return; + } + } else { + /** + * No entropy available - try again later + */ + } + + /* Schedule ourselves for next cycle */ + k_work_schedule(dwork, TRNG_GENERATION_DELAY); } +#else /* !IRQLESS_TRNG */ +static void stm32_rng_isr(const void *arg) +{ + ARG_UNUSED(arg); + + (void)perform_pool_refill(); +} +#endif /* IRQLESS_TRNG */ static int entropy_stm32_rng_get_entropy(const struct device *dev, uint8_t *buf, @@ -613,20 +698,29 @@ static int entropy_stm32_rng_get_entropy_isr(const struct device *dev, } if (len) { - unsigned int key; - int irq_enabled; - bool rng_already_acquired; + /** + * On TRNG without interrupt line, we cannot allow reentrancy, + * so we have to suspend all interrupts. Otherwise, only suspend + * it until we have established ourselves as owner of the TRNG + * to prevent race with a higher priority interrupt handler. + */ + unsigned int key = irq_lock(); + bool rng_already_acquired = false; +#if !IRQLESS_TRNG + int irq_enabled = irq_is_enabled(IRQN); - key = irq_lock(); - irq_enabled = irq_is_enabled(IRQN); + rng_already_acquired = (irq_enabled != 0); irq_disable(IRQN); irq_unlock(key); +#endif /* !IRQLESS_TRNG */ /* Do not release if IRQ is enabled. RNG will be released in ISR - * when the pools are full. + * when the pools are full. On TRNG without interrupt line, the + * default value of false ensures TRNG is always released. */ - rng_already_acquired = z_stm32_hsem_is_owned(CFG_HW_RNG_SEMID) || - irq_enabled; + if (z_stm32_hsem_is_owned(CFG_HW_RNG_SEMID)) { + rng_already_acquired = true; + } acquire_rng(); cnt = generate_from_isr(buf, len); @@ -636,9 +730,14 @@ static int entropy_stm32_rng_get_entropy_isr(const struct device *dev, release_rng(); } +#if IRQLESS_TRNG + /* Exit critical section */ + irq_unlock(key); +#else if (irq_enabled) { irq_enable(IRQN); } +#endif /* !IRQLESS_TRNG */ } return cnt; @@ -684,6 +783,10 @@ static int entropy_stm32_rng_init(const struct device *dev) k_work_init(&dev_data->filling_work, pool_filling_work_handler); +#if IRQLESS_TRNG + k_work_init_delayable(&dev_data->trng_poll_work, trng_poll_work_item); +#endif /* IRQLESS_TRNG */ + rng_pool_init((struct rng_pool *)(dev_data->thr), CONFIG_ENTROPY_STM32_THR_POOL_SIZE, CONFIG_ENTROPY_STM32_THR_THRESHOLD); @@ -691,7 +794,9 @@ static int entropy_stm32_rng_init(const struct device *dev) CONFIG_ENTROPY_STM32_ISR_POOL_SIZE, CONFIG_ENTROPY_STM32_ISR_THRESHOLD); +#if !IRQLESS_TRNG IRQ_CONNECT(IRQN, IRQ_PRIO, stm32_rng_isr, &entropy_stm32_rng_data, 0); +#endif /* !IRQLESS_TRNG */ #if !defined(CONFIG_SOC_SERIES_STM32WBX) && !defined(CONFIG_STM32H7_DUAL_CORE) /* For multi-core MCUs, RNG configuration is automatically performed diff --git a/drivers/entropy/entropy_stm32.h b/drivers/entropy/entropy_stm32.h new file mode 100644 index 0000000000000..2ddc6fbac1c61 --- /dev/null +++ b/drivers/entropy/entropy_stm32.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +/** + * This driver supports two compatibles: + * - "st,stm32-rng" for TRNG with IRQ lines + * - "st,stm32-rng-noirq" for TRNG without IRQ lines + */ +#define IRQLESS_TRNG DT_HAS_COMPAT_STATUS_OKAY(st_stm32_rng_noirq) + +#if IRQLESS_TRNG +#define DT_DRV_COMPAT st_stm32_rng_noirq +#define TRNG_GENERATION_DELAY K_NSEC(DT_INST_PROP_OR(0, generation_delay_ns, 0)) +#else /* !IRQLESS_TRNG */ +#define DT_DRV_COMPAT st_stm32_rng +#define IRQN DT_INST_IRQN(0) +#define IRQ_PRIO DT_INST_IRQ(0, priority) +#endif /* IRQLESS_TRNG */ + +/* Cross-series LL compatibility wrappers */ +static inline void ll_rng_enable_it(RNG_TypeDef *RNGx) +{ + /* Silence "unused" warning on IRQ-less hardware*/ + ARG_UNUSED(RNGx); +#if !IRQLESS_TRNG +# if defined(CONFIG_SOC_STM32WB09XX) + LL_RNG_EnableEnErrorIrq(RNGx); + LL_RNG_EnableEnFfFullIrq(RNGx); +# else + LL_RNG_EnableIT(RNGx); +# endif +#endif /* !IRQLESS_TRNG */ +} + +static inline uint32_t ll_rng_is_active_seis(RNG_TypeDef *RNGx) +{ +#if defined(CONFIG_SOC_SERIES_STM32WB0X) +# if defined(CONFIG_SOC_STM32WB09XX) + return LL_RNG_IsActiveFlag_ENTROPY_ERR(RNGx); +# else + return LL_RNG_IsActiveFlag_FAULT(RNGx); +# endif +#else + return LL_RNG_IsActiveFlag_SEIS(RNGx); +#endif /* CONFIG_SOC_SERIES_STM32WB0X */ +} + +static inline void ll_rng_clear_seis(RNG_TypeDef *RNGx) +{ +#if defined(CONFIG_SOC_SERIES_STM32WB0X) +# if defined(CONFIG_SOC_STM32WB09XX) + LL_RNG_SetResetHealthErrorFlags(RNGx, 1); +# else + LL_RNG_ClearFlag_FAULT(RNGx); +# endif +#else + LL_RNG_ClearFlag_SEIS(RNGx); +#endif /* CONFIG_SOC_SERIES_STM32WB0X */ +} + +static inline uint32_t ll_rng_is_active_secs(RNG_TypeDef *RNGx) +{ +#if !defined(CONFIG_SOC_SERIES_STM32WB0X) + return LL_RNG_IsActiveFlag_SECS(RNGx); +#else + /** + * STM32WB0x RNG has no equivalent of SECS. + * Since this flag is always checked in conjunction + * with FAULT (the SEIS equivalent), returning 0 is OK. + */ + return 0; +#endif /* !CONFIG_SOC_SERIES_STM32WB0X */ +} + +static inline uint32_t ll_rng_is_active_drdy(RNG_TypeDef *RNGx) +{ +#if defined(CONFIG_SOC_SERIES_STM32WB0X) +# if defined(CONFIG_SOC_STM32WB09XX) + return LL_RNG_IsActiveFlag_VAL_READY(RNGx); +# else + return LL_RNG_IsActiveFlag_RNGRDY(RNGx); +# endif +#else + return LL_RNG_IsActiveFlag_DRDY(RNGx); +#endif /* CONFIG_SOC_SERIES_STM32WB0X */ +} + +static inline uint16_t ll_rng_read_rand_data(RNG_TypeDef *RNGx) +{ +#if defined(CONFIG_SOC_SERIES_STM32WB0X) +# if defined(CONFIG_SOC_STM32WB09XX) + return (uint16_t)LL_RNG_GetRndVal(RNGx); +# else + return LL_RNG_ReadRandData16(RNGx); +# endif +#else + return (uint16_t)LL_RNG_ReadRandData32(RNGx); +#endif /* CONFIG_SOC_SERIES_STM32WB0X */ +} diff --git a/drivers/entropy/entropy_sy1xx_trng.c b/drivers/entropy/entropy_sy1xx_trng.c new file mode 100644 index 0000000000000..636f2b2795501 --- /dev/null +++ b/drivers/entropy/entropy_sy1xx_trng.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2025 sensry.io + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sensry_sy1xx_trng + +#include +LOG_MODULE_REGISTER(sy1xx_entropy, CONFIG_ENTROPY_LOG_LEVEL); + +#include +#include +#include +#include +#include + +#define SY1XX_TRNG_VAL_OFFS 0x00 +#define SY1XX_TRNG_FIFO_COUNT_OFFS 0x04 +#define SY1XX_TRNG_STATUS_OFFS 0x08 +#define SY1XX_TRNG_ERROR_OFFS 0x0c + +#define SY1XX_TRNG_FIFO_SIZE 64 + +/* time needed to fill fifo when empty */ +#define SY1XX_TRNG_FIFO_REFILL_TIME_USEC 80 +#define SY1XX_TRNG_FIFO_REFILL_MAX_RETRIES 5 + +struct sy1xx_trng_config { + uint32_t base_addr; +}; + +struct sy1xx_trng_data { + struct k_mutex mutex; +}; + +static int sy1xx_trng_driver_init(const struct device *dev) +{ + const struct sy1xx_trng_config *const cfg = dev->config; + struct sy1xx_trng_data *const data = dev->data; + + k_mutex_init(&data->mutex); + + /* trng comes up fully initialized, so only check if all is fine */ + if (0 != sys_read32(cfg->base_addr + SY1XX_TRNG_ERROR_OFFS)) { + LOG_ERR("failure mode active, internal init failed"); + return -EINVAL; + } + + if (SY1XX_TRNG_FIFO_SIZE != sys_read32(cfg->base_addr + SY1XX_TRNG_FIFO_COUNT_OFFS)) { + LOG_ERR("fifo not fully loaded"); + return -EINVAL; + } + + return 0; +} + +static int sy1xx_trng_driver_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length) +{ + const struct sy1xx_trng_config *const cfg = dev->config; + struct sy1xx_trng_data *const data = dev->data; + uint32_t retries_left; + uint32_t random_word; + + uint32_t word_count = DIV_ROUND_UP(length, 4); + + for (uint32_t i = 0; i < word_count; i++) { + retries_left = SY1XX_TRNG_FIFO_REFILL_MAX_RETRIES; + + k_mutex_lock(&data->mutex, K_FOREVER); + while (true) { + /* make sure fifo has at least one random word */ + if (sys_read32(cfg->base_addr + SY1XX_TRNG_FIFO_COUNT_OFFS) > 0) { + /* get new random word */ + random_word = sys_read32(cfg->base_addr + SY1XX_TRNG_VAL_OFFS); + break; + } + + /* currently no random values available, thus wait */ + retries_left--; + if (!retries_left) { + /* number of retries exhausted, give up */ + k_mutex_unlock(&data->mutex); + return -ETIMEDOUT; + } + k_sleep(K_USEC(SY1XX_TRNG_FIFO_REFILL_TIME_USEC)); + }; + k_mutex_unlock(&data->mutex); + + memcpy(&buffer[i * 4], &random_word, MIN(length, 4)); + length -= 4; + } + + /* always error check, to make sure that we received valid readings */ + if (0 != sys_read32(cfg->base_addr + SY1XX_TRNG_ERROR_OFFS)) { + LOG_ERR("failure mode active, reading of values failed"); + return -EINVAL; + } + + return 0; +} + +static int sy1xx_trng_driver_get_entropy_isr(const struct device *dev, uint8_t *buffer, + uint16_t length, uint32_t flags) +{ + + const struct sy1xx_trng_config *const cfg = dev->config; + unsigned int key; + uint32_t random_word; + int ret; + + uint32_t word_count = DIV_ROUND_UP(length, 4); + + for (uint32_t i = 0; i < word_count; i++) { + + do { + key = irq_lock(); + /* make sure fifo has at least one random word */ + if (sys_read32(cfg->base_addr + SY1XX_TRNG_FIFO_COUNT_OFFS) > 0) { + /* get new random word */ + random_word = sys_read32(cfg->base_addr + SY1XX_TRNG_VAL_OFFS); + ret = 0; + } else { + ret = -EAGAIN; + } + irq_unlock(key); + + if (ret && !(flags & ENTROPY_BUSYWAIT)) { + /* no waiting allowed */ + return ret; + } + + } while (ret); + + memcpy(&buffer[i * 4], &random_word, MIN(length, 4)); + length -= 4; + } + + /* always error check, to make sure that we received valid readings */ + if (0 != sys_read32(cfg->base_addr + SY1XX_TRNG_ERROR_OFFS)) { + LOG_ERR("failure mode active, reading of values failed"); + return -EINVAL; + } + + return 0; +} + +static DEVICE_API(entropy, + sy1xx_entropy_api) = {.get_entropy = sy1xx_trng_driver_get_entropy, + .get_entropy_isr = sy1xx_trng_driver_get_entropy_isr}; + +#define SY1XX_TRNG_INIT(n) \ + \ + static const struct sy1xx_trng_config sy1xx_trng##n##_cfg = { \ + .base_addr = (uint32_t)DT_INST_REG_ADDR(n), \ + }; \ + \ + static struct sy1xx_trng_data sy1xx_trng##n##_data = {}; \ + \ + DEVICE_DT_INST_DEFINE(n, sy1xx_trng_driver_init, NULL, &sy1xx_trng##n##_data, \ + &sy1xx_trng##n##_cfg, PRE_KERNEL_1, CONFIG_ENTROPY_INIT_PRIORITY, \ + &sy1xx_entropy_api); + +DT_INST_FOREACH_STATUS_OKAY(SY1XX_TRNG_INIT) diff --git a/drivers/entropy/fake_entropy_native_posix.c b/drivers/entropy/fake_entropy_native_posix.c index 1b7e457fca6f0..04f25b2e62da1 100644 --- a/drivers/entropy/fake_entropy_native_posix.c +++ b/drivers/entropy/fake_entropy_native_posix.c @@ -42,7 +42,10 @@ static int entropy_native_posix_get_entropy(const struct device *dev, */ long value = nsi_host_random(); - size_t to_copy = MIN(length, sizeof(long int)); + /* The host random() provides a number between 0 and 2**31-1. Bit 32 is always 0. + * So let's just use the lower 3 bytes discarding the upper 7 bits + */ + size_t to_copy = MIN(length, 3); memcpy(buffer, &value, to_copy); buffer += to_copy; diff --git a/drivers/espi/Kconfig.npcx b/drivers/espi/Kconfig.npcx index dbeadaddfa2e6..14c74fbd88e84 100644 --- a/drivers/espi/Kconfig.npcx +++ b/drivers/espi/Kconfig.npcx @@ -134,4 +134,12 @@ config ESPI_NPCX_CAF_GLOBAL_RESET_WORKAROUND help Workaround the issue "Global Reset" in the npcx4 SoC errata. +config ESPI_NPCX_RESET_SLP_SX_VW_ON_ESPI_RST + bool "Reset SLP_Sx virtual wires when eSPI_RST is asserted" + help + The SLP_S3/SLP_S4/SLP_S5/ virtual wires are automatically reset when + eSPI_Reset is asserted on the global reset. + Don't enable this config if the platform implements the Deep-Sx + entry as EC needs to maintain these pins' states per request. + endif #ESPI_NPCX diff --git a/drivers/espi/espi_npcx.c b/drivers/espi/espi_npcx.c index 4a7f40b64c062..c741ada5650ff 100644 --- a/drivers/espi/espi_npcx.c +++ b/drivers/espi/espi_npcx.c @@ -91,6 +91,9 @@ static const struct espi_npcx_vw_ex espi_npcx_vw_ex_0[] = { #define NPCX_ESPI_MAXFREQ_50 3 #define NPCX_ESPI_MAXFREQ_66 4 +/* SLP_S3/SLP_S4/SLP_S5 Virtual Wire belong to Virtual Wire Index 2 */ +#define ESPI_VW_SLP_SX_INDEX 0x02 + /* Minimum delay before acknowledging a virtual wire */ #define NPCX_ESPI_VWIRE_ACK_DELAY 10ul /* 10 us */ @@ -498,6 +501,14 @@ static void espi_vw_config_input(const struct device *dev, struct espi_reg *const inst = HAL_INSTANCE(dev); int idx = config_in->reg_idx; + if (IS_ENABLED(CONFIG_ESPI_NPCX_RESET_SLP_SX_VW_ON_ESPI_RST)) { + uint8_t vwire_index = GET_FIELD(inst->VWEVMS[idx], NPCX_VWEVMS_INDEX); + + if (vwire_index == ESPI_VW_SLP_SX_INDEX) { + inst->VWEVMS[idx] |= BIT(NPCX_VWEVMS_ENESPIRST); + } + } + /* IE & WE bits are already set? */ if (IS_BIT_SET(inst->VWEVMS[idx], NPCX_VWEVMS_IE) && IS_BIT_SET(inst->VWEVMS[idx], NPCX_VWEVMS_WE)) { diff --git a/drivers/espi/espi_taf_npcx.c b/drivers/espi/espi_taf_npcx.c index 04062f4363ca3..855f2b382c7d7 100644 --- a/drivers/espi/espi_taf_npcx.c +++ b/drivers/espi/espi_taf_npcx.c @@ -18,7 +18,15 @@ LOG_MODULE_REGISTER(espi_taf, CONFIG_ESPI_LOG_LEVEL); -static const struct device *const spi_dev = DEVICE_DT_GET(DT_ALIAS(taf_flash)); +#define NPCX_TAF_PRIME_FLASH_NODE DT_ALIAS(taf_flash) +#define NPCX_TAF_SEC_FLASH_NODE DT_ALIAS(taf_flash1) + +#define NPCX_TAF_ALLOC_SIZE(node) (MB(1) << DT_ENUM_IDX(node, spi_dev_size)) + +static const struct device *const spi_dev = DEVICE_DT_GET(NPCX_TAF_PRIME_FLASH_NODE); +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) +static const struct device *const spi_dev1 = DEVICE_DT_GET(NPCX_TAF_SEC_FLASH_NODE); +#endif enum ESPI_TAF_ERASE_LEN { NPCX_ESPI_TAF_ERASE_LEN_4KB, @@ -52,6 +60,11 @@ struct espi_taf_npcx_data { uint32_t src[16]; uint8_t read_buf[MAX_TX_PAYLOAD_SIZE]; struct k_work work; +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + const struct device *low_dev_ptr; + const struct device *high_dev_ptr; + uint32_t low_dev_size; +#endif }; static struct espi_taf_npcx_data npcx_espi_taf_data; @@ -236,6 +249,11 @@ static bool espi_taf_npcx_channel_ready(const struct device *dev) if (!device_is_ready(spi_dev)) { return false; } +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if (!device_is_ready(spi_dev1)) { + return false; + } +#endif return true; } @@ -362,7 +380,34 @@ static int espi_taf_npcx_flash_read(const struct device *dev, struct espi_saf_pa } do { +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if ((addr + len) <= npcx_espi_taf_data.low_dev_size) { + rc = flash_read(npcx_espi_taf_data.low_dev_ptr, addr, + npcx_espi_taf_data.read_buf, len); + } else if (addr >= npcx_espi_taf_data.low_dev_size) { + rc = flash_read(npcx_espi_taf_data.high_dev_ptr, + (addr - npcx_espi_taf_data.low_dev_size), + npcx_espi_taf_data.read_buf, len); + } else { + rc = flash_read(npcx_espi_taf_data.low_dev_ptr, addr, + npcx_espi_taf_data.read_buf, + (npcx_espi_taf_data.low_dev_size.low_dev_size - addr)); + + if (rc) { + LOG_ERR("flash read fail 0x%x", rc); + return -EIO; + } + + uint32_t index = low_dev_size - addr; + + rc = flash_read( + npcx_espi_taf_data.high_dev_ptr, 0x0, + &npcx_espi_taf_data.read_buf[index], + (addr + len - npcx_espi_taf_data.low_dev_size.low_dev_size)); + } +#else rc = flash_read(spi_dev, addr, npcx_espi_taf_data.read_buf, len); +#endif if (rc) { LOG_ERR("flash read fail 0x%x", rc); return -EIO; @@ -394,6 +439,8 @@ static int espi_taf_npcx_flash_write(const struct device *dev, struct espi_saf_p { struct espi_taf_npcx_pckt *taf_data_ptr = (struct espi_taf_npcx_pckt *)pckt->buf; uint8_t *data_ptr = (uint8_t *)(taf_data_ptr->data); + uint32_t addr = pckt->flash_addr; + uint32_t len = pckt->len; int rc; if (espi_taf_check_write_protect(dev, pckt->flash_addr, @@ -402,7 +449,19 @@ static int espi_taf_npcx_flash_write(const struct device *dev, struct espi_saf_p return -EINVAL; } - rc = flash_write(spi_dev, pckt->flash_addr, data_ptr, pckt->len); +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if ((addr + len) <= npcx_espi_taf_data.low_dev_size) { + rc = flash_write(npcx_espi_taf_data.low_dev_ptr, addr, data_ptr, len); + } else if (addr >= npcx_espi_taf_data.low_dev_size) { + rc = flash_write(npcx_espi_taf_data.high_dev_ptr, + (addr - npcx_espi_taf_data.low_dev_size), data_ptr, len); + } else { + LOG_ERR("Write across two flashes"); + return -EINVAL; + } +#else + rc = flash_write(spi_dev, addr, data_ptr, len); +#endif if (rc) { LOG_ERR("flash write fail 0x%x", rc); return -EIO; @@ -438,7 +497,19 @@ static int espi_taf_npcx_flash_erase(const struct device *dev, struct espi_saf_p return -EINVAL; } +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if ((addr + len) <= npcx_espi_taf_data.low_dev_size) { + rc = flash_erase(npcx_espi_taf_data.low_dev_ptr, addr, len); + } else if (addr >= npcx_espi_taf_data.low_dev_size) { + rc = flash_erase(npcx_espi_taf_data.high_dev_ptr, + (addr - npcx_espi_taf_data.low_dev_size), len); + } else { + LOG_ERR("Erase across two flashes"); + return -EINVAL; + } +#else rc = flash_erase(spi_dev, addr, len); +#endif if (rc) { LOG_ERR("flash erase fail"); return -EIO; @@ -620,6 +691,18 @@ static int espi_taf_npcx_init(const struct device *dev) config->max_rd_sz); inst->FLASHBASE = config->mapped_addr; +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if (IS_ENABLED(CONFIG_FLASH_NPCX_FIU_SUPP_LOW_DEV_SWAP)) { + npcx_espi_taf_data.low_dev_ptr = spi_dev1; + npcx_espi_taf_data.high_dev_ptr = spi_dev; + npcx_espi_taf_data.low_dev_size = NPCX_TAF_ALLOC_SIZE(NPCX_TAF_SEC_FLASH_NODE); + } else { + npcx_espi_taf_data.low_dev_ptr = spi_dev; + npcx_espi_taf_data.high_dev_ptr = spi_dev1; + npcx_espi_taf_data.low_dev_size = NPCX_TAF_ALLOC_SIZE(NPCX_TAF_PRIME_FLASH_NODE); + } +#endif + #ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT uint8_t count_num = 0; diff --git a/drivers/espi/host_subs_npcx.c b/drivers/espi/host_subs_npcx.c index d92516fa0bf03..33dbeab3ccf27 100644 --- a/drivers/espi/host_subs_npcx.c +++ b/drivers/espi/host_subs_npcx.c @@ -127,7 +127,7 @@ #include #include -LOG_MODULE_REGISTER(host_sub_npcx, LOG_LEVEL_ERR); +LOG_MODULE_REGISTER(host_sub_npcx, CONFIG_ESPI_LOG_LEVEL); struct host_sub_npcx_config { /* host module instances */ @@ -897,9 +897,9 @@ int npcx_host_periph_write_request(enum lpc_peripheral_opcode op, return -ENOTSUP; } if (data) { - LOG_INF("%s: op 0x%x data %x", __func__, op, *data); + LOG_DBG("op 0x%x data %x", op, *data); } else { - LOG_INF("%s: op 0x%x only", __func__, op); + LOG_DBG("op 0x%x only", op); } switch (op) { diff --git a/drivers/ethernet/CMakeLists.txt b/drivers/ethernet/CMakeLists.txt index abab18562e15c..3eb6bbc4e63e7 100644 --- a/drivers/ethernet/CMakeLists.txt +++ b/drivers/ethernet/CMakeLists.txt @@ -42,6 +42,8 @@ zephyr_library_sources_ifdef(CONFIG_ETH_LAN865X eth_lan865x.c oa_tc6.c) zephyr_library_sources_ifdef(CONFIG_ETH_XMC4XXX eth_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_ETH_TEST eth_test.c) zephyr_library_sources_ifdef(CONFIG_ETH_RENESAS_RA eth_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_ETH_LAN9250 eth_lan9250.c) +zephyr_library_sources_ifdef(CONFIG_ETH_SY1XX eth_sensry_sy1xx_mac.c) if(CONFIG_ETH_NXP_S32_NETC) zephyr_library_sources(eth_nxp_s32_netc.c) @@ -49,11 +51,6 @@ if(CONFIG_ETH_NXP_S32_NETC) zephyr_library_sources_ifdef(CONFIG_DT_HAS_NXP_S32_NETC_VSI_ENABLED eth_nxp_s32_netc_vsi.c) endif() -if(CONFIG_ETH_NXP_IMX_NETC) - zephyr_library_sources(eth_nxp_imx_netc.c) - zephyr_library_sources(eth_nxp_imx_netc_psi.c) -endif() - zephyr_library_sources_ifdef(CONFIG_ETH_NXP_S32_GMAC eth_nxp_s32_gmac.c) zephyr_library_sources_ifdef(CONFIG_ETH_NUMAKER eth_numaker.c) @@ -74,4 +71,5 @@ endif() add_subdirectory(phy) add_subdirectory(eth_nxp_enet_qos) add_subdirectory(nxp_enet) +add_subdirectory(nxp_imx_netc) add_subdirectory(dwc_xgmac) diff --git a/drivers/ethernet/Kconfig b/drivers/ethernet/Kconfig index 7164189b1aac7..d864c9c6e136a 100644 --- a/drivers/ethernet/Kconfig +++ b/drivers/ethernet/Kconfig @@ -65,7 +65,6 @@ source "drivers/ethernet/Kconfig.w5500" source "drivers/ethernet/Kconfig.dsa" source "drivers/ethernet/Kconfig.xlnx_gem" source "drivers/ethernet/Kconfig.cyclonev" -source "drivers/ethernet/Kconfig.nxp_imx_netc" source "drivers/ethernet/Kconfig.nxp_s32_netc" source "drivers/ethernet/Kconfig.nxp_s32_gmac" source "drivers/ethernet/Kconfig.smsc91x" @@ -75,6 +74,8 @@ source "drivers/ethernet/Kconfig.numaker" source "drivers/ethernet/Kconfig.lan865x" source "drivers/ethernet/Kconfig.xmc4xxx" source "drivers/ethernet/Kconfig.test" +source "drivers/ethernet/Kconfig.lan9250" +source "drivers/ethernet/Kconfig.sy1xx_mac" source "drivers/ethernet/eth_nxp_enet_qos/Kconfig" @@ -82,6 +83,7 @@ source "drivers/ethernet/dwc_xgmac/Kconfig" source "drivers/ethernet/phy/Kconfig" source "drivers/ethernet/nxp_enet/Kconfig" +source "drivers/ethernet/nxp_imx_netc/Kconfig" source "drivers/ethernet/Kconfig.renesas_ra" endif # "Ethernet Drivers" diff --git a/drivers/ethernet/Kconfig.dsa b/drivers/ethernet/Kconfig.dsa index 1974ce97f1895..56d0109b0eb66 100644 --- a/drivers/ethernet/Kconfig.dsa +++ b/drivers/ethernet/Kconfig.dsa @@ -39,15 +39,38 @@ config DSA_KSZ8863 help Add support for KSZ8863 DSA device driver. +config DSA_KSZ8463 + bool "Support for KSZ8463" + default y + depends on DT_HAS_MICROCHIP_KSZ8463_ENABLED + select DSA_KSZ8XXX + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_MICROCHIP_KSZ8463),spi) + help + Add support for KSZ8463 DSA device driver. + config DSA_KSZ_TAIL_TAGGING bool "Support for tail tagging" - depends on DSA_KSZ8794 || DSA_KSZ8863 + depends on DSA_KSZ8794 || DSA_KSZ8863 || DSA_KSZ8463 help Add support for tail tagging on DSA device. +config DSA_TAG_SIZE + int "DSA tag size in bytes" + default 1 if DSA_KSZ8794 || DSA_KSZ8863 || DSA_KSZ8463 + default 0 + depends on DSA_KSZ_TAIL_TAGGING + help + Set the DSA tag length in bytes. + +config DSA_KSZ_PORT_ISOLATING + bool "Support for ports isolating" + depends on DSA_KSZ8794 || DSA_KSZ8863 || DSA_KSZ8463 + help + Add support for traffic isolation on DSA slave ports + config DSA_SPI bool "Support for PHY SPI interface" - depends on SPI && (DSA_KSZ8794 || DSA_KSZ8863) + depends on SPI && (DSA_KSZ8794 || DSA_KSZ8863 || DSA_KSZ8463) help Use SPI bus to communicate with PHY diff --git a/drivers/ethernet/Kconfig.lan865x b/drivers/ethernet/Kconfig.lan865x index 42138aa1ed442..1a63331e079ed 100644 --- a/drivers/ethernet/Kconfig.lan865x +++ b/drivers/ethernet/Kconfig.lan865x @@ -6,6 +6,7 @@ menuconfig ETH_LAN865X default y depends on DT_HAS_MICROCHIP_LAN865X_ENABLED select SPI + select MDIO select NET_L2_ETHERNET_MGMT help The LAN865X is a low power, 10BASE-T1S transceiver compliant with diff --git a/drivers/ethernet/Kconfig.lan9250 b/drivers/ethernet/Kconfig.lan9250 new file mode 100644 index 0000000000000..041cb7e49dd69 --- /dev/null +++ b/drivers/ethernet/Kconfig.lan9250 @@ -0,0 +1,40 @@ +# LAN9250 Stand-alone Ethernet Controller configuration options + +# Copyright (c) 2024 Mario Paja +# SPDX-License-Identifier: Apache-2.0 + + +menuconfig ETH_LAN9250 + bool "LAN9250 Ethernet Controller" + default y + depends on DT_HAS_MICROCHIP_LAN9250_ENABLED + select SPI + help + LAN9250 Stand-Alone Ethernet Controller + with SPI Interface + +if ETH_LAN9250 + +config ETH_LAN9250_RX_THREAD_STACK_SIZE + int "Stack size for internal incoming packet handler" + default 800 + help + Size of the stack used for internal thread which is ran for + incoming packet processing. + +config ETH_LAN9250_RX_THREAD_PRIO + int "Priority for internal incoming packet handler" + default 2 + help + Priority level for internal thread which is ran for incoming + packet processing. + +config ETH_LAN9250_BUF_ALLOC_TIMEOUT + int "Network buffer allocation timeout" + default 100 + help + Given timeout in milliseconds. Maximum amount of time + that the driver will wait from the IP stack to get + a memory buffer before the Ethernet frame is dropped. + +endif diff --git a/drivers/ethernet/Kconfig.nxp_imx_netc b/drivers/ethernet/Kconfig.nxp_imx_netc deleted file mode 100644 index e636f53da4798..0000000000000 --- a/drivers/ethernet/Kconfig.nxp_imx_netc +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright 2024 NXP -# SPDX-License-Identifier: Apache-2.0 - -menuconfig ETH_NXP_IMX_NETC - bool "NXP IMX Ethernet and Network Controller (NETC) driver" - default y - depends on DT_HAS_NXP_IMX_NETC_PSI_ENABLED - select MDIO - select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT - help - Enable Ethernet and Network Controller (NETC) driver for NXP IMX SoCs. - -if ETH_NXP_IMX_NETC - -config ETH_NXP_IMX_MSGINTR - int "Message Interrupt module select" - default 1 - help - Message Interrupt module select. - -config ETH_NXP_IMX_RX_THREAD_PRIO - int "RX thread priority" - default 2 - help - RX thread priority. RX thread is a cooperative thread. - -config ETH_NXP_IMX_RX_THREAD_STACK_SIZE - int "RX thread stack size" - default 1500 - help - RX thread stack size. - -config ETH_NXP_IMX_RX_BUDGET - int "RX thread budget" - default 128 - range 1 1024 - help - The budget parameter places a limit on the amount of work the driver may - do in the RX thread before yielding the processor, in case there is more - work to do. This is to prevent the RX thread to starve other threads. Each - received frame counts as one unit of work. - -config ETH_NXP_IMX_TX_RING_NUM - int "TX ring number" - default 1 - range 1 1023 - help - TX ring number used. The actual maximum value may varies from platforms. - -config ETH_NXP_IMX_TX_RING_LEN - int "TX ring length" - default 8 - range 8 256 - help - Length of the TX ring. The value must be a multiple of 8. - -config ETH_NXP_IMX_TX_RING_BUF_SIZE - int "TX ring data buffer size" - default 1000 - range 64 1536 - help - Size, in bytes, of the TX data buffer. The size must be big enough to - store one complete Ethernet frame, and be a multiple of 8. - -config ETH_NXP_IMX_RX_RING_NUM - int "RX ring number" - default 1 - range 1 1023 - help - RX ring number used. The actual maximum value may varies from platforms. - -config ETH_NXP_IMX_RX_RING_LEN - int "RX ring length" - default 8 - range 8 256 - help - Length of the RX ring. The value must be a multiple of 8. - -config ETH_NXP_IMX_RX_RING_BUF_SIZE - int "RX ring data buffer size" - default 1518 - range 64 1536 - help - Size, in bytes, of the RX data buffer. The size must be big enough to - store one complete Ethernet frame, and be a multiple of 8. - -endif # ETH_NXP_IMX_NETC diff --git a/drivers/ethernet/Kconfig.sam_gmac b/drivers/ethernet/Kconfig.sam_gmac index aecb9488f25f8..90bdd18a3eba6 100644 --- a/drivers/ethernet/Kconfig.sam_gmac +++ b/drivers/ethernet/Kconfig.sam_gmac @@ -27,8 +27,7 @@ DT_ETH_SAM_GMAC_NQ := $(dt_node_int_prop_int,$(DT_ETH_SAM_GMAC_PATH),num-queues) config ETH_SAM_GMAC_QUEUES int "Number of active hardware TX and RX queues" default 1 - range 1 $(DT_ETH_SAM_GMAC_NQ) if SOC_SERIES_SAME70 || \ - SOC_SERIES_SAMV71 || \ + range 1 $(DT_ETH_SAM_GMAC_NQ) if SOC_SERIES_SAMX7X || \ SOC_SERIES_SAM4E || \ SOC_SERIES_SAME54 help diff --git a/drivers/ethernet/Kconfig.sy1xx_mac b/drivers/ethernet/Kconfig.sy1xx_mac new file mode 100644 index 0000000000000..8493aa5305f54 --- /dev/null +++ b/drivers/ethernet/Kconfig.sy1xx_mac @@ -0,0 +1,11 @@ +# Copyright (c) 2025 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +config ETH_SY1XX + bool "Sensry SY1XX Ethernet driver" + default y + depends on DT_HAS_SENSRY_SY1XX_MAC_ENABLED + select MDIO + select PINCTRL + help + Enable Sensry SY1XX Ethernet MAC driver. diff --git a/drivers/ethernet/dsa_ksz8463.h b/drivers/ethernet/dsa_ksz8463.h new file mode 100644 index 0000000000000..b57096cbac3e7 --- /dev/null +++ b/drivers/ethernet/dsa_ksz8463.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023 Meshium + * Aleksandr Senin + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DSA_KSZ8463_H__ +#define __DSA_KSZ8463_H__ + +/* SPI commands */ +#define KSZ8463_SPI_CMD_WR (BIT(7)) +#define KSZ8463_SPI_CMD_RD (0) + +#define KSZ8463_REG_ADDR_HI_PART(x) (((x) & 0x7FF) >> 4) +#define KSZ8463_REG_ADDR_LO_PART(x) (((x) & 0x00C) << 4) +#define KSZ8463_SPI_BYTE_ENABLE(x) (BIT(((x) & 0x3) + 2)) + +/* PHY registers */ +#define KSZ8463_BMCR 0x00 +#define KSZ8463_BMSR 0x01 +#define KSZ8463_PHYID1 0x02 +#define KSZ8463_PHYID2 0x03 +#define KSZ8463_ANAR 0x04 +#define KSZ8463_ANLPAR 0x05 +#define KSZ8463_LINKMD 0x1D +#define KSZ8463_PHYSCS 0x1F + +/* SWITCH registers */ +#define KSZ8463_CHIP_ID0 0x01 +#define KSZ8463_CHIP_ID1 0x00 +#define KSZ8463_GLOBAL_CTRL_1L 0x02 +#define KSZ8463_GLOBAL_CTRL_1H 0x03 +#define KSZ8463_GLOBAL_CTRL_2L 0x04 +#define KSZ8463_GLOBAL_CTRL_2H 0x05 +#define KSZ8463_GLOBAL_CTRL_3L 0x06 +#define KSZ8463_GLOBAL_CTRL_3H 0x07 +#define KSZ8463_GLOBAL_CTRL_6L 0x0C +#define KSZ8463_GLOBAL_CTRL_6H 0x0D +#define KSZ8463_GLOBAL_CTRL_7L 0x0E +#define KSZ8463_GLOBAL_CTRL_7H 0x0F +#define KSZ8463_GLOBAL_CTRL_8L 0xAC +#define KSZ8463_GLOBAL_CTRL_8H 0xAD +#define KSZ8463_GLOBAL_CTRL_9L 0xAE +#define KSZ8463_GLOBAL_CTRL_9H 0xAF + +#define KSZ8463_CFGR_L 0xD8 + +#define KSZ8463_DSP_CNTRL_6L 0x734 +#define KSZ8463_DSP_CNTRL_6H 0x735 + +#define KSZ8463_GLOBAL_CTRL1_TAIL_TAG_EN BIT(0) +#define KSZ8463_GLOBAL_CTRL2_LEG_MAX_PKT_SIZ_CHK_ENA BIT(1) + +#define KSZ8463_CTRL2L_PORTn(n) (0x6E + ((n) * 0x18)) +#define KSZ8463_CTRL2L_VLAN_PORTS_MASK 0xF8 +#define KSZ8463_CTRL2H_PORTn(n) (0x6F + ((n) * 0x18)) +#define KSZ8463_CTRL2_TRANSMIT_EN BIT(2) +#define KSZ8463_CTRL2_RECEIVE_EN BIT(1) +#define KSZ8463_CTRL2_LEARNING_DIS BIT(0) + +#define KSZ8463_STAT2_PORTn(n) (0x80 + ((n) * 0x18)) +#define KSZ8463_STAT2_LINK_GOOD BIT(5) + +#define KSZ8463_CHIP_ID0_ID_DEFAULT 0x84 +#define KSZ8463_CHIP_ID1_ID_DEFAULT 0x43 +#define KSZ8463F_CHIP_ID1_ID_DEFAULT 0x53 +#define KSZ8463_RESET_REG 0x127 +#define KSZ8463_SOFTWARE_RESET_SET BIT(0) +#define KSZ8463_SOFTWARE_RESET_CLEAR 0 + +#define KSZ8463_P2_COPPER_MODE BIT(7) +#define KSZ8463_P1_COPPER_MODE BIT(6) +#define KSZ8463_RECV_ADJ BIT(5) + +enum { + /* LAN ports for the ksz8463 switch */ + KSZ8463_PORT1 = 0, + KSZ8463_PORT2, + /* SWITCH <-> CPU port */ + KSZ8463_PORT3, +}; + +#define KSZ8463_REG_IND_CTRL_0 0x31 +#define KSZ8463_REG_IND_CTRL_1 0x30 +#define KSZ8463_REG_IND_DATA_8 0x26 +#define KSZ8463_REG_IND_DATA_7 0x2B +#define KSZ8463_REG_IND_DATA_6 0x2A +#define KSZ8463_REG_IND_DATA_5 0x29 +#define KSZ8463_REG_IND_DATA_4 0x28 +#define KSZ8463_REG_IND_DATA_3 0x2F +#define KSZ8463_REG_IND_DATA_2 0x2E +#define KSZ8463_REG_IND_DATA_1 0x2D +#define KSZ8463_REG_IND_DATA_0 0x2C + +#define KSZ8463_STATIC_MAC_TABLE_VALID BIT(3) +#define KSZ8463_STATIC_MAC_TABLE_OVRD BIT(4) +#define KSZ8463_STATIC_MAC_TABLE_USE_FID BIT(5) + +#define KSZ8XXX_CHIP_ID0 KSZ8463_CHIP_ID0 +#define KSZ8XXX_CHIP_ID1 KSZ8463_CHIP_ID1 +#define KSZ8XXX_CHIP_ID0_ID_DEFAULT KSZ8463_CHIP_ID0_ID_DEFAULT +#define KSZ8XXX_CHIP_ID1_ID_DEFAULT KSZ8463F_CHIP_ID1_ID_DEFAULT +#define KSZ8XXX_FIRST_PORT KSZ8463_PORT1 +#define KSZ8XXX_LAST_PORT KSZ8463_PORT3 +#define KSZ8XXX_CPU_PORT KSZ8463_PORT3 +#define KSZ8XXX_REG_IND_CTRL_0 KSZ8463_REG_IND_CTRL_0 +#define KSZ8XXX_REG_IND_CTRL_1 KSZ8463_REG_IND_CTRL_1 +#define KSZ8XXX_REG_IND_DATA_8 KSZ8463_REG_IND_DATA_8 +#define KSZ8XXX_REG_IND_DATA_7 KSZ8463_REG_IND_DATA_7 +#define KSZ8XXX_REG_IND_DATA_6 KSZ8463_REG_IND_DATA_6 +#define KSZ8XXX_REG_IND_DATA_5 KSZ8463_REG_IND_DATA_5 +#define KSZ8XXX_REG_IND_DATA_4 KSZ8463_REG_IND_DATA_4 +#define KSZ8XXX_REG_IND_DATA_3 KSZ8463_REG_IND_DATA_3 +#define KSZ8XXX_REG_IND_DATA_2 KSZ8463_REG_IND_DATA_2 +#define KSZ8XXX_REG_IND_DATA_1 KSZ8463_REG_IND_DATA_1 +#define KSZ8XXX_REG_IND_DATA_0 KSZ8463_REG_IND_DATA_0 +#define KSZ8XXX_STATIC_MAC_TABLE_VALID KSZ8463_STATIC_MAC_TABLE_VALID +#define KSZ8XXX_STATIC_MAC_TABLE_OVRD KSZ8463_STATIC_MAC_TABLE_OVRD +#define KSZ8XXX_STAT2_LINK_GOOD KSZ8463_STAT2_LINK_GOOD +#define KSZ8XXX_RESET_REG KSZ8463_RESET_REG +#define KSZ8XXX_RESET_SET KSZ8463_SOFTWARE_RESET_SET +#define KSZ8XXX_RESET_CLEAR KSZ8463_SOFTWARE_RESET_CLEAR +#define KSZ8XXX_STAT2_PORTn KSZ8463_STAT2_PORTn +#define KSZ8XXX_CTRL1_PORTn KSZ8463_CTRL2L_PORTn +#define KSZ8XXX_CTRL1_VLAN_PORTS_MASK KSZ8463_CTRL2L_VLAN_PORTS_MASK +#define KSZ8XXX_SPI_CMD_RD KSZ8463_SPI_CMD_RD +#define KSZ8XXX_SPI_CMD_WR KSZ8463_SPI_CMD_WR +#define KSZ8XXX_SOFT_RESET_DURATION 1000 +#define KSZ8XXX_HARD_RESET_WAIT 10000 + +#endif /* __DSA_KSZ8463_H__ */ diff --git a/drivers/ethernet/dsa_ksz8794.h b/drivers/ethernet/dsa_ksz8794.h index 93ed81e5bac7e..d4a1c2f578bbd 100644 --- a/drivers/ethernet/dsa_ksz8794.h +++ b/drivers/ethernet/dsa_ksz8794.h @@ -234,6 +234,8 @@ #define KSZ8794_GLOBAL_CTRL10_TAIL_TAG_EN BIT(1) #define KSZ8794_GLOBAL_CTRL2_LEG_MAX_PKT_SIZ_CHK_DIS BIT(1) +#define KSZ8794_CTRL1_PORTn(n) (0x11 + ((n) * 0x10)) +#define KSZ8794_CTRL1_VLAN_PORTS_MASK 0xE0 #define KSZ8794_CTRL2_PORTn(n) (0x12 + ((n) * 0x10)) #define KSZ8794_CTRL2_TRANSMIT_EN BIT(2) #define KSZ8794_CTRL2_RECEIVE_EN BIT(1) @@ -321,6 +323,8 @@ enum { #define KSZ8XXX_RESET_SET KSZ8794_PWR_MGNT_MODE_SOFT_DOWN #define KSZ8XXX_RESET_CLEAR 0 #define KSZ8XXX_STAT2_PORTn KSZ8794_STAT2_PORTn +#define KSZ8XXX_CTRL1_PORTn KSZ8794_CTRL1_PORTn +#define KSZ8XXX_CTRL1_VLAN_PORTS_MASK KSZ8794_CTRL1_VLAN_PORTS_MASK #define KSZ8XXX_SPI_CMD_RD KSZ8794_SPI_CMD_RD #define KSZ8XXX_SPI_CMD_WR KSZ8794_SPI_CMD_WR #define KSZ8XXX_SOFT_RESET_DURATION 1000 diff --git a/drivers/ethernet/dsa_ksz8863.h b/drivers/ethernet/dsa_ksz8863.h index 602662ee1eb31..d523da9261564 100644 --- a/drivers/ethernet/dsa_ksz8863.h +++ b/drivers/ethernet/dsa_ksz8863.h @@ -94,6 +94,8 @@ #define KSZ8863_GLOBAL_CTRL1_TAIL_TAG_EN BIT(6) #define KSZ8863_GLOBAL_CTRL2_LEG_MAX_PKT_SIZ_CHK_ENA BIT(1) +#define KSZ8863_CTRL1_PORTn(n) (0x11 + ((n) * 0x10)) +#define KSZ8863_CTRL1_VLAN_PORTS_MASK 0xF8 #define KSZ8863_CTRL2_PORTn(n) (0x12 + ((n) * 0x10)) #define KSZ8863_CTRL2_TRANSMIT_EN BIT(2) #define KSZ8863_CTRL2_RECEIVE_EN BIT(1) @@ -157,6 +159,8 @@ enum { #define KSZ8XXX_RESET_SET KSZ8863_SOFTWARE_RESET_SET #define KSZ8XXX_RESET_CLEAR KSZ8863_SOFTWARE_RESET_CLEAR #define KSZ8XXX_STAT2_PORTn KSZ8863_STAT2_PORTn +#define KSZ8XXX_CTRL1_PORTn KSZ8863_CTRL1_PORTn +#define KSZ8XXX_CTRL1_VLAN_PORTS_MASK KSZ8863_CTRL1_VLAN_PORTS_MASK #define KSZ8XXX_SPI_CMD_RD KSZ8863_SPI_CMD_RD #define KSZ8XXX_SPI_CMD_WR KSZ8863_SPI_CMD_WR #define KSZ8XXX_SOFT_RESET_DURATION 1000 diff --git a/drivers/ethernet/dsa_ksz8xxx.c b/drivers/ethernet/dsa_ksz8xxx.c index 9cf136f7b0114..3a81546a91faf 100644 --- a/drivers/ethernet/dsa_ksz8xxx.c +++ b/drivers/ethernet/dsa_ksz8xxx.c @@ -30,6 +30,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_ETHERNET_LOG_LEVEL); #elif CONFIG_DSA_KSZ8794 #define DT_DRV_COMPAT microchip_ksz8794 #include "dsa_ksz8794.h" +#elif CONFIG_DSA_KSZ8463 +#define DT_DRV_COMPAT microchip_ksz8463 +#include "dsa_ksz8463.h" #else #error "Unsupported KSZ chipset" #endif @@ -59,9 +62,15 @@ static void dsa_ksz8xxx_write_reg(const struct ksz8xxx_data *pdev, .count = 1 }; +#if CONFIG_DSA_KSZ8463 + buf[0] = KSZ8XXX_SPI_CMD_WR | KSZ8463_REG_ADDR_HI_PART(reg_addr); + buf[1] = KSZ8463_REG_ADDR_LO_PART(reg_addr) | KSZ8463_SPI_BYTE_ENABLE(reg_addr); + buf[2] = value; +#else buf[0] = KSZ8XXX_SPI_CMD_WR | ((reg_addr >> 7) & 0x1F); buf[1] = (reg_addr << 1) & 0xFE; buf[2] = value; +#endif spi_write_dt(&pdev->spi, &tx); #endif @@ -91,9 +100,15 @@ static void dsa_ksz8xxx_read_reg(const struct ksz8xxx_data *pdev, .count = 1 }; +#if CONFIG_DSA_KSZ8463 + buf[0] = KSZ8XXX_SPI_CMD_RD | KSZ8463_REG_ADDR_HI_PART(reg_addr); + buf[1] = KSZ8463_REG_ADDR_LO_PART(reg_addr) | KSZ8463_SPI_BYTE_ENABLE(reg_addr); + buf[2] = 0; +#else buf[0] = KSZ8XXX_SPI_CMD_RD | ((reg_addr >> 7) & 0x1F); buf[1] = (reg_addr << 1) & 0xFE; buf[2] = 0x0; +#endif if (!spi_transceive_dt(&pdev->spi, &tx, &rx)) { *value = buf[2]; @@ -153,7 +168,12 @@ static int dsa_ksz8xxx_probe(struct ksz8xxx_data *pdev) dsa_ksz8xxx_read_reg(pdev, KSZ8XXX_CHIP_ID1, &val[1]); if (val[0] != KSZ8XXX_CHIP_ID0_ID_DEFAULT || +#if CONFIG_DSA_KSZ8463 + (val[1] != KSZ8463_CHIP_ID1_ID_DEFAULT && + val[1] != KSZ8463F_CHIP_ID1_ID_DEFAULT)) { +#else val[1] != KSZ8XXX_CHIP_ID1_ID_DEFAULT) { +#endif LOG_ERR("Chip ID mismatch. " "Expected %02x%02x but found %02x%02x", KSZ8XXX_CHIP_ID0_ID_DEFAULT, @@ -163,7 +183,7 @@ static int dsa_ksz8xxx_probe(struct ksz8xxx_data *pdev) return -ENODEV; } - LOG_DBG("KSZ8794: ID0: 0x%x ID1: 0x%x timeout: %d", val[1], val[0], + LOG_DBG("KSZ8794: ID0: 0x%x ID1: 0x%x timeout: %d", val[0], val[1], timeout); return 0; @@ -260,6 +280,79 @@ static int dsa_ksz8xxx_read_static_mac_table(struct ksz8xxx_data *pdev, return 0; } +#if defined(CONFIG_DSA_KSZ_PORT_ISOLATING) +static int dsa_ksz8xxx_port_isolate(const struct ksz8xxx_data *pdev) +{ + uint8_t tmp, i; + + for (i = KSZ8XXX_FIRST_PORT; i < KSZ8XXX_LAST_PORT; i++) { + dsa_ksz8xxx_read_reg(pdev, KSZ8XXX_CTRL1_PORTn(i), &tmp); + tmp &= KSZ8XXX_CTRL1_VLAN_PORTS_MASK; + tmp |= 1 << KSZ8XXX_CPU_PORT | 1 << i; + dsa_ksz8xxx_write_reg(pdev, KSZ8XXX_CTRL1_PORTn(i), tmp); + } + + dsa_ksz8xxx_read_reg(pdev, KSZ8XXX_CTRL1_PORTn(KSZ8XXX_CPU_PORT), + &tmp); + tmp |= ~KSZ8XXX_CTRL1_VLAN_PORTS_MASK; + dsa_ksz8xxx_write_reg(pdev, KSZ8XXX_CTRL1_PORTn(KSZ8XXX_CPU_PORT), + tmp); + + return 0; +} +#endif + +#if CONFIG_DSA_KSZ8463 +static int dsa_ksz8xxx_switch_setup(struct ksz8xxx_data *pdev) +{ + uint8_t tmp, i; + + dsa_ksz8xxx_read_reg(pdev, KSZ8XXX_CHIP_ID1, &tmp); + + if (tmp == KSZ8463F_CHIP_ID1_ID_DEFAULT) { + dsa_ksz8xxx_read_reg(pdev, KSZ8463_CFGR_L, &tmp); + tmp &= ~KSZ8463_P1_COPPER_MODE; + tmp &= ~KSZ8463_P2_COPPER_MODE; + dsa_ksz8xxx_write_reg(pdev, KSZ8463_CFGR_L, tmp); + dsa_ksz8xxx_read_reg(pdev, KSZ8463_DSP_CNTRL_6H, &tmp); + tmp &= ~KSZ8463_RECV_ADJ; + dsa_ksz8xxx_write_reg(pdev, KSZ8463_DSP_CNTRL_6H, tmp); + } + + /* + * Loop through ports - The same setup when tail tagging is enabled or + * disabled. + */ + for (i = KSZ8XXX_FIRST_PORT; i <= KSZ8XXX_LAST_PORT; i++) { + + /* Enable transmission, reception and switch address learning */ + dsa_ksz8xxx_read_reg(pdev, KSZ8463_CTRL2H_PORTn(i), &tmp); + tmp |= KSZ8463_CTRL2_TRANSMIT_EN; + tmp |= KSZ8463_CTRL2_RECEIVE_EN; + tmp &= ~KSZ8463_CTRL2_LEARNING_DIS; + dsa_ksz8xxx_write_reg(pdev, KSZ8463_CTRL2H_PORTn(i), tmp); + } + +#if defined(CONFIG_DSA_KSZ_TAIL_TAGGING) + /* Enable tail tag feature */ + dsa_ksz8xxx_read_reg(pdev, KSZ8463_GLOBAL_CTRL_8H, &tmp); + tmp |= KSZ8463_GLOBAL_CTRL1_TAIL_TAG_EN; + dsa_ksz8xxx_write_reg(pdev, KSZ8463_GLOBAL_CTRL_8H, tmp); +#else + /* Disable tail tag feature */ + dsa_ksz8xxx_read_reg(pdev, KSZ8463_GLOBAL_CTRL_8H, &tmp); + tmp &= ~KSZ8463_GLOBAL_CTRL1_TAIL_TAG_EN; + dsa_ksz8xxx_write_reg(pdev, KSZ8463_GLOBAL_CTRL_8H, tmp); +#endif + + dsa_ksz8xxx_read_reg(pdev, KSZ8463_GLOBAL_CTRL_2L, &tmp); + tmp &= ~KSZ8463_GLOBAL_CTRL2_LEG_MAX_PKT_SIZ_CHK_ENA; + dsa_ksz8xxx_write_reg(pdev, KSZ8463_GLOBAL_CTRL_2L, tmp); + + return 0; +} +#endif + #if CONFIG_DSA_KSZ8863 static int dsa_ksz8xxx_switch_setup(const struct ksz8xxx_data *pdev) { @@ -697,6 +790,10 @@ int dsa_hw_init(struct ksz8xxx_data *pdev) /* Setup KSZ8794 */ dsa_ksz8xxx_switch_setup(pdev); +#if defined(CONFIG_DSA_KSZ_PORT_ISOLATING) + dsa_ksz8xxx_port_isolate(pdev); +#endif + #if DT_INST_NODE_HAS_PROP(0, mii_lowspeed_drivestrength) dsa_ksz8794_set_lowspeed_drivestrength(pdev); #endif @@ -885,7 +982,7 @@ struct net_pkt *dsa_ksz8xxx_xmit_pkt(struct net_if *iface, struct net_pkt *pkt) port_idx = (1 << (ctx->dsa_port_idx)); } - NET_DBG("TT - port: 0x%x[%p] LEN: %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + LOG_DBG("TT - port: 0x%x[%p] LEN: %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", port_idx, iface, len, lladst.addr[0], lladst.addr[1], lladst.addr[2], lladst.addr[3], lladst.addr[4], lladst.addr[5]); @@ -948,7 +1045,7 @@ static struct net_if *dsa_ksz8xxx_get_iface(struct net_if *iface, iface_sw = net_if_get_by_index(pnum + 2); ctx = net_if_l2_data(iface); - NET_DBG("TT - plen: %d pnum: %d pos: 0x%p dsa_port_idx: %d", + LOG_DBG("TT - plen: %d pnum: %d pos: 0x%p dsa_port_idx: %d", plen - DSA_KSZ8794_EGRESS_TAG_LEN, pnum, net_pkt_cursor_get_pos(pkt), ctx->dsa_port_idx); @@ -1112,5 +1209,4 @@ static struct dsa_api dsa_api_f = { }; \ DT_INST_FOREACH_CHILD_VARGS(n, NET_SLAVE_DEVICE_INIT_INSTANCE, n); - DT_INST_FOREACH_STATUS_OKAY(DSA_DEVICE); diff --git a/drivers/ethernet/eth_enc28j60.c b/drivers/ethernet/eth_enc28j60.c index 260626d0b722e..e3c73c0ca4d74 100644 --- a/drivers/ethernet/eth_enc28j60.c +++ b/drivers/ethernet/eth_enc28j60.c @@ -683,6 +683,13 @@ static int eth_enc28j60_rx(const struct device *dev) k_sem_give(&context->tx_rx_sem); + /* Clear a potential Receive Error Interrupt Flag bit (RX buffer full). + * PKTIF was automatically cleared in eth_enc28j60_rx() when EPKTCNT + * reached zero, so no need to clear it. + */ + eth_enc28j60_clear_eth_reg(dev, ENC28J60_REG_EIR, + ENC28J60_BIT_EIR_RXERIF); + return 0; } @@ -698,14 +705,13 @@ static void eth_enc28j60_rx_thread(void *p1, void *p2, void *p3) while (true) { k_sem_take(&context->int_sem, K_FOREVER); + /* Disable interrupts during processing, otherwise there's a small race + * window where we can miss one! + */ + eth_enc28j60_clear_eth_reg(dev, ENC28J60_REG_EIE, ENC28J60_BIT_EIE_INTIE); + eth_enc28j60_read_reg(dev, ENC28J60_REG_EIR, &int_stat); - if (int_stat & ENC28J60_BIT_EIR_PKTIF) { - eth_enc28j60_rx(dev); - /* Clear rx interruption flag */ - eth_enc28j60_clear_eth_reg(dev, ENC28J60_REG_EIR, - ENC28J60_BIT_EIR_PKTIF - | ENC28J60_BIT_EIR_RXERIF); - } else if (int_stat & ENC28J60_BIT_EIR_LINKIF) { + if (int_stat & ENC28J60_BIT_EIR_LINKIF) { uint16_t phir; uint16_t phstat2; /* Clear link change interrupt flag by PHIR reg read */ @@ -729,6 +735,14 @@ static void eth_enc28j60_rx_thread(void *p1, void *p2, void *p3) } } } + + /* We cannot rely on the PKTIF flag because of errata 6. Call + * eth_enc28j60_rx() unconditionally. It will check EPKTCNT instead. + */ + eth_enc28j60_rx(dev); + + /* Now that the IRQ line was released, enable interrupts back */ + eth_enc28j60_set_eth_reg(dev, ENC28J60_REG_EIE, ENC28J60_BIT_EIE_INTIE); } } diff --git a/drivers/ethernet/eth_lan865x.c b/drivers/ethernet/eth_lan865x.c index 0ced9732928af..3a3a0421e5d38 100644 --- a/drivers/ethernet/eth_lan865x.c +++ b/drivers/ethernet/eth_lan865x.c @@ -18,9 +18,42 @@ LOG_MODULE_REGISTER(eth_lan865x, CONFIG_ETHERNET_LOG_LEVEL); #include #include #include +#include #include "eth_lan865x_priv.h" +int eth_lan865x_mdio_c22_read(const struct device *dev, uint8_t prtad, uint8_t regad, + uint16_t *data) +{ + struct lan865x_data *ctx = dev->data; + + return oa_tc6_mdio_read(ctx->tc6, prtad, regad, data); +} + +int eth_lan865x_mdio_c22_write(const struct device *dev, uint8_t prtad, uint8_t regad, + uint16_t data) +{ + struct lan865x_data *ctx = dev->data; + + return oa_tc6_mdio_write(ctx->tc6, prtad, regad, data); +} + +int eth_lan865x_mdio_c45_read(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t *data) +{ + struct lan865x_data *ctx = dev->data; + + return oa_tc6_mdio_read_c45(ctx->tc6, prtad, devad, regad, data); +} + +int eth_lan865x_mdio_c45_write(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t data) +{ + struct lan865x_data *ctx = dev->data; + + return oa_tc6_mdio_write_c45(ctx->tc6, prtad, devad, regad, data); +} + static int lan865x_mac_rxtx_control(const struct device *dev, bool en) { struct lan865x_data *ctx = dev->data; @@ -33,13 +66,38 @@ static int lan865x_mac_rxtx_control(const struct device *dev, bool en) return oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_NCR, ctl); } +static int lan865x_enable_sync(const struct device *dev) +{ + struct lan865x_data *ctx = dev->data; + uint32_t val; + int ret; + + ret = oa_tc6_reg_read(ctx->tc6, OA_CONFIG0, &val); + if (ret) { + return ret; + } + val |= OA_CONFIG0_SYNC | OA_CONFIG0_RFA_ZARFE; + ret = oa_tc6_reg_write(ctx->tc6, OA_CONFIG0, val); + if (ret) { + return ret; + } + + return lan865x_mac_rxtx_control(dev, LAN865x_MAC_TXRX_ON); +} + static void lan865x_iface_init(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); struct lan865x_data *ctx = dev->data; + int ret; + + ret = lan865x_enable_sync(dev); + if (ret) { + LOG_ERR("LAN865x sync enable failed: %d\n", ret); + return; + } - net_if_set_link_addr(iface, ctx->mac_address, sizeof(ctx->mac_address), - NET_LINK_ETHERNET); + net_if_set_link_addr(iface, ctx->mac_address, sizeof(ctx->mac_address), NET_LINK_ETHERNET); if (ctx->iface == NULL) { ctx->iface = iface; @@ -64,44 +122,35 @@ static int lan865x_set_config(const struct device *dev, enum ethernet_config_typ { const struct lan865x_config *cfg = dev->config; struct lan865x_data *ctx = dev->data; - int ret = -ENOTSUP; + struct phy_plca_cfg plca_cfg; if (type == ETHERNET_CONFIG_TYPE_PROMISC_MODE) { - return oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_NCFGR, - LAN865x_MAC_NCFGR_CAF); + return oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_NCFGR, LAN865x_MAC_NCFGR_CAF); } if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) { - memcpy(ctx->mac_address, config->mac_address.addr, - sizeof(ctx->mac_address)); + memcpy(ctx->mac_address, config->mac_address.addr, sizeof(ctx->mac_address)); lan865x_write_macaddress(dev); - return net_if_set_link_addr(ctx->iface, ctx->mac_address, - sizeof(ctx->mac_address), - NET_LINK_ETHERNET); + return net_if_set_link_addr(ctx->iface, ctx->mac_address, sizeof(ctx->mac_address), + NET_LINK_ETHERNET); } if (type == ETHERNET_CONFIG_TYPE_T1S_PARAM) { - ret = lan865x_mac_rxtx_control(dev, LAN865x_MAC_TXRX_OFF); - if (ret) { - return ret; - } - if (config->t1s_param.type == ETHERNET_T1S_PARAM_TYPE_PLCA_CONFIG) { - cfg->plca->enable = config->t1s_param.plca.enable; - cfg->plca->node_id = config->t1s_param.plca.node_id; - cfg->plca->node_count = config->t1s_param.plca.node_count; - cfg->plca->burst_count = config->t1s_param.plca.burst_count; - cfg->plca->burst_timer = config->t1s_param.plca.burst_timer; - cfg->plca->to_timer = config->t1s_param.plca.to_timer; + plca_cfg.enable = config->t1s_param.plca.enable; + plca_cfg.node_id = config->t1s_param.plca.node_id; + plca_cfg.node_count = config->t1s_param.plca.node_count; + plca_cfg.burst_count = config->t1s_param.plca.burst_count; + plca_cfg.burst_timer = config->t1s_param.plca.burst_timer; + plca_cfg.to_timer = config->t1s_param.plca.to_timer; + + return phy_set_plca_cfg(cfg->phy, &plca_cfg); } - - /* Reset is required to re-program PLCA new configuration */ - lan865x_gpio_reset(dev); } - return ret; + return -ENOTSUP; } static int lan865x_wait_for_reset(const struct device *dev) @@ -164,156 +213,6 @@ static int lan865x_check_spi(const struct device *dev) return ret; } -/* Implementation of pseudo code from AN1760 */ -static uint8_t lan865x_read_indirect_reg(const struct device *dev, uint8_t addr, - uint8_t mask) -{ - struct lan865x_data *ctx = dev->data; - uint32_t val; - - oa_tc6_reg_write(ctx->tc6, 0x000400D8, addr); - oa_tc6_reg_write(ctx->tc6, 0x000400DA, 0x02); - - oa_tc6_reg_read(ctx->tc6, 0x000400D9, &val); - - return (uint8_t) val & mask; -} - -/* - * Values in the below table for LAN865x rev. B0 and B1 (with place - * holders for cfgparamX. - */ -static oa_mem_map_t lan865x_conf[] = { - { .mms = 0x1, .address = 0x00, .value = 0x0000 }, - { .mms = 0x4, .address = 0xD0, .value = 0x3F31 }, - { .mms = 0x4, .address = 0xE0, .value = 0xC000 }, - { .mms = 0x4, .address = 0x84, .value = 0x0000 }, /* cfgparam1 */ - { .mms = 0x4, .address = 0x8A, .value = 0x0000 }, /* cfgparam2 */ - { .mms = 0x4, .address = 0xE9, .value = 0x9E50 }, - { .mms = 0x4, .address = 0xF5, .value = 0x1CF8 }, - { .mms = 0x4, .address = 0xF4, .value = 0xC020 }, - { .mms = 0x4, .address = 0xF8, .value = 0xB900 }, - { .mms = 0x4, .address = 0xF9, .value = 0x4E53 }, - { .mms = 0x4, .address = 0x91, .value = 0x9660 }, - { .mms = 0x4, .address = 0x77, .value = 0x0028 }, - { .mms = 0x4, .address = 0x43, .value = 0x00FF }, - { .mms = 0x4, .address = 0x44, .value = 0xFFFF }, - { .mms = 0x4, .address = 0x45, .value = 0x0000 }, - { .mms = 0x4, .address = 0x53, .value = 0x00FF }, - { .mms = 0x4, .address = 0x54, .value = 0xFFFF }, - { .mms = 0x4, .address = 0x55, .value = 0x0000 }, - { .mms = 0x4, .address = 0x40, .value = 0x0002 }, - { .mms = 0x4, .address = 0x50, .value = 0x0002 }, - { .mms = 0x4, .address = 0xAD, .value = 0x0000 }, /* cfgparam3 */ - { .mms = 0x4, .address = 0xAE, .value = 0x0000 }, /* cfgparam4 */ - { .mms = 0x4, .address = 0xAF, .value = 0x0000 }, /* cfgparam5 */ - { .mms = 0x4, .address = 0xB0, .value = 0x0103 }, - { .mms = 0x4, .address = 0xB1, .value = 0x0910 }, - { .mms = 0x4, .address = 0xB2, .value = 0x1D26 }, - { .mms = 0x4, .address = 0xB3, .value = 0x002A }, - { .mms = 0x4, .address = 0xB4, .value = 0x0103 }, - { .mms = 0x4, .address = 0xB5, .value = 0x070D }, - { .mms = 0x4, .address = 0xB6, .value = 0x1720 }, - { .mms = 0x4, .address = 0xB7, .value = 0x0027 }, - { .mms = 0x4, .address = 0xB8, .value = 0x0509 }, - { .mms = 0x4, .address = 0xB9, .value = 0x0E13 }, - { .mms = 0x4, .address = 0xBA, .value = 0x1C25 }, - { .mms = 0x4, .address = 0xBB, .value = 0x002B }, - { .mms = 0x4, .address = 0x0C, .value = 0x0100 }, - { .mms = 0x4, .address = 0x81, .value = 0x00E0 }, -}; - -/* Based on AN1760 DS60001760G pseudo code */ -static int lan865x_init_chip(const struct device *dev, uint8_t silicon_rev) -{ - uint16_t cfgparam1, cfgparam2, cfgparam3, cfgparam4, cfgparam5; - uint8_t i, size = ARRAY_SIZE(lan865x_conf); - struct lan865x_data *ctx = dev->data; - int8_t offset1 = 0, offset2 = 0; - uint8_t value1, value2; - - /* Enable protected control RW */ - oa_tc6_set_protected_ctrl(ctx->tc6, true); - - value1 = lan865x_read_indirect_reg(dev, 0x04, 0x1F); - if ((value1 & 0x10) != 0) { /* Convert uint8_t to int8_t */ - offset1 = (int8_t)((uint8_t)value1 - 0x20); - } else { - offset1 = (int8_t)value1; - } - - value2 = lan865x_read_indirect_reg(dev, 0x08, 0x1F); - if ((value2 & 0x10) != 0) { /* Convert uint8_t to int8_t */ - offset2 = (int8_t)((uint8_t)value2 - 0x20); - } else { - offset2 = (int8_t)value2; - } - - cfgparam1 = (uint16_t) (((9 + offset1) & 0x3F) << 10) | - (uint16_t) (((14 + offset1) & 0x3F) << 4) | 0x03; - cfgparam2 = (uint16_t) (((40 + offset2) & 0x3F) << 10); - cfgparam3 = (uint16_t) (((5 + offset1) & 0x3F) << 8) | - (uint16_t) ((9 + offset1) & 0x3F); - cfgparam4 = (uint16_t) (((9 + offset1) & 0x3F) << 8) | - (uint16_t) ((14 + offset1) & 0x3F); - cfgparam5 = (uint16_t) (((17 + offset1) & 0x3F) << 8) | - (uint16_t) ((22 + offset1) & 0x3F); - - lan865x_update_dev_cfg_array(lan865x_conf, size, - MMS_REG(0x4, 0x84), cfgparam1); - lan865x_update_dev_cfg_array(lan865x_conf, size, - MMS_REG(0x4, 0x8A), cfgparam2); - lan865x_update_dev_cfg_array(lan865x_conf, size, - MMS_REG(0x4, 0xAD), cfgparam3); - lan865x_update_dev_cfg_array(lan865x_conf, size, - MMS_REG(0x4, 0xAE), cfgparam4); - lan865x_update_dev_cfg_array(lan865x_conf, size, - MMS_REG(0x4, 0xAF), cfgparam5); - - if (silicon_rev == 1) { - /* For silicon rev 1 (B0): (bit [3..0] from 0x0A0084 */ - lan865x_update_dev_cfg_array(lan865x_conf, size, - MMS_REG(0x4, 0xD0), 0x5F21); - } - - /* Write LAN865x config with correct order */ - for (i = 0; i < size; i++) { - oa_tc6_reg_write(ctx->tc6, MMS_REG(lan865x_conf[i].mms, - lan865x_conf[i].address), - (uint32_t)lan865x_conf[i].value); - } - - return 0; -} -/* Implementation of pseudo code from AN1760 - END */ - -static int lan865x_config_plca(const struct device *dev, uint8_t node_id, - uint8_t node_cnt, uint8_t burst_cnt, uint8_t burst_timer) -{ - struct lan865x_data *ctx = dev->data; - uint32_t val; - - /* Collision Detection */ - oa_tc6_reg_write(ctx->tc6, 0x00040087, 0x0083u); /* COL_DET_CTRL0 */ - - /* T1S Phy Node ID and Max Node Count */ - if (node_id == 0) { - val = (uint32_t)node_cnt << 8; - } else { - val = (uint32_t)node_id; - } - oa_tc6_reg_write(ctx->tc6, 0x0004CA02, val); /* PLCA_CONTROL_1_REGISTER */ - - /* PLCA Burst Count and Burst Timer */ - val = ((uint32_t)burst_cnt << 8) | burst_timer; - oa_tc6_reg_write(ctx->tc6, 0x0004CA05, val); /* PLCA_BURST_MODE_REGISTER */ - - /* Enable PLCA */ - oa_tc6_reg_write(ctx->tc6, 0x0004CA01, BIT(15)); /* PLCA_CONTROL_0_REGISTER */ - - return 0; -} - static void lan865x_write_macaddress(const struct device *dev) { struct lan865x_data *ctx = dev->data; @@ -354,44 +253,34 @@ static int lan865x_set_specific_multicast_addr(const struct device *dev) return ret; } - return oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_NCFGR, - LAN865x_MAC_NCFGR_MTIHEN); + return oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_NCFGR, LAN865x_MAC_NCFGR_MTIHEN); } -static int lan865x_default_config(const struct device *dev, uint8_t silicon_rev) +static int lan865x_default_config(const struct device *dev) { - const struct lan865x_config *cfg = dev->config; + struct lan865x_data *ctx = dev->data; int ret; - lan865x_write_macaddress(dev); - lan865x_set_specific_multicast_addr(dev); + /* Enable protected control RW */ + oa_tc6_set_protected_ctrl(ctx->tc6, true); - ret = lan865x_init_chip(dev, silicon_rev); - if (ret < 0) { + ret = oa_tc6_reg_write(ctx->tc6, LAN865X_FIXUP_REG, LAN865X_FIXUP_VALUE); + if (ret) { return ret; } - if (cfg->plca->enable) { - ret = lan865x_config_plca(dev, cfg->plca->node_id, - cfg->plca->node_count, - cfg->plca->burst_count, - cfg->plca->burst_timer); - if (ret < 0) { - return ret; - } - } + lan865x_write_macaddress(dev); + lan865x_set_specific_multicast_addr(dev); + return 0; } -static void lan865x_int_callback(const struct device *dev, - struct gpio_callback *cb, - uint32_t pins) +static void lan865x_int_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { ARG_UNUSED(dev); ARG_UNUSED(pins); - struct lan865x_data *ctx = - CONTAINER_OF(cb, struct lan865x_data, gpio_int_callback); + struct lan865x_data *ctx = CONTAINER_OF(cb, struct lan865x_data, gpio_int_callback); k_sem_give(&ctx->int_sem); } @@ -432,7 +321,7 @@ static void lan865x_int_thread(const struct device *dev) { struct lan865x_data *ctx = dev->data; struct oa_tc6 *tc6 = ctx->tc6; - uint32_t sts, val, ftr; + uint32_t sts, ftr; int ret; while (true) { @@ -441,11 +330,8 @@ static void lan865x_int_thread(const struct device *dev) oa_tc6_reg_read(tc6, OA_STATUS0, &sts); if (sts & OA_STATUS0_RESETC) { oa_tc6_reg_write(tc6, OA_STATUS0, sts); - lan865x_default_config(dev, ctx->silicon_rev); - oa_tc6_reg_read(tc6, OA_CONFIG0, &val); - val |= OA_CONFIG0_SYNC | OA_CONFIG0_RFA_ZARFE; - oa_tc6_reg_write(tc6, OA_CONFIG0, val); - lan865x_mac_rxtx_control(dev, LAN865x_MAC_TXRX_ON); + + lan865x_default_config(dev); ctx->reset = true; /* @@ -490,8 +376,7 @@ static int lan865x_init(const struct device *dev) } if (!gpio_is_ready_dt(&cfg->interrupt)) { - LOG_ERR("Interrupt GPIO device %s is not ready", - cfg->interrupt.port->name); + LOG_ERR("Interrupt GPIO device %s is not ready", cfg->interrupt.port->name); return -ENODEV; } @@ -523,19 +408,15 @@ static int lan865x_init(const struct device *dev) gpio_pin_interrupt_configure_dt(&cfg->interrupt, GPIO_INT_EDGE_TO_ACTIVE); /* Start interruption-poll thread */ - ctx->tid_int = - k_thread_create(&ctx->thread, ctx->thread_stack, - CONFIG_ETH_LAN865X_IRQ_THREAD_STACK_SIZE, - (k_thread_entry_t)lan865x_int_thread, - (void *)dev, NULL, NULL, - K_PRIO_COOP(CONFIG_ETH_LAN865X_IRQ_THREAD_PRIO), - 0, K_NO_WAIT); + ctx->tid_int = k_thread_create( + &ctx->thread, ctx->thread_stack, CONFIG_ETH_LAN865X_IRQ_THREAD_STACK_SIZE, + (k_thread_entry_t)lan865x_int_thread, (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_ETH_LAN865X_IRQ_THREAD_PRIO), 0, K_NO_WAIT); k_thread_name_set(ctx->tid_int, "lan865x_interrupt"); /* Perform HW reset - 'rst-gpios' required property set in DT */ if (!gpio_is_ready_dt(&cfg->reset)) { - LOG_ERR("Reset GPIO device %s is not ready", - cfg->reset.port->name); + LOG_ERR("Reset GPIO device %s is not ready", cfg->reset.port->name); return -ENODEV; } @@ -580,36 +461,22 @@ static const struct ethernet_api lan865x_api_func = { }; #define LAN865X_DEFINE(inst) \ - static struct lan865x_config_plca lan865x_config_plca_##inst = { \ - .node_id = DT_INST_PROP(inst, plca_node_id), \ - .node_count = DT_INST_PROP(inst, plca_node_count), \ - .burst_count = DT_INST_PROP(inst, plca_burst_count), \ - .burst_timer = DT_INST_PROP(inst, plca_burst_timer), \ - .to_timer = DT_INST_PROP(inst, plca_to_timer), \ - .enable = DT_INST_PROP(inst, plca_enable), \ - }; \ - \ static const struct lan865x_config lan865x_config_##inst = { \ .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \ .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ .reset = GPIO_DT_SPEC_INST_GET(inst, rst_gpios), \ .timeout = CONFIG_ETH_LAN865X_TIMEOUT, \ - .plca = &lan865x_config_plca_##inst, \ - }; \ - \ + .phy = DEVICE_DT_GET( \ + DT_CHILD(DT_INST_CHILD(inst, lan865x_mdio), ethernet_phy_##inst))}; \ + \ struct oa_tc6 oa_tc6_##inst = { \ - .cps = 64, \ - .protected = 0, \ - .spi = &lan865x_config_##inst.spi \ - }; \ + .cps = 64, .protected = 0, .spi = &lan865x_config_##inst.spi}; \ static struct lan865x_data lan865x_data_##inst = { \ .mac_address = DT_INST_PROP(inst, local_mac_address), \ - .tx_rx_sem = \ - Z_SEM_INITIALIZER((lan865x_data_##inst).tx_rx_sem, 1, 1), \ + .tx_rx_sem = Z_SEM_INITIALIZER((lan865x_data_##inst).tx_rx_sem, 1, 1), \ .int_sem = Z_SEM_INITIALIZER((lan865x_data_##inst).int_sem, 0, 1), \ - .tc6 = &oa_tc6_##inst \ - }; \ - \ + .tc6 = &oa_tc6_##inst}; \ + \ ETH_NET_DEVICE_DT_INST_DEFINE(inst, lan865x_init, NULL, &lan865x_data_##inst, \ &lan865x_config_##inst, CONFIG_ETH_INIT_PRIORITY, \ &lan865x_api_func, NET_ETH_MTU); diff --git a/drivers/ethernet/eth_lan865x_priv.h b/drivers/ethernet/eth_lan865x_priv.h index 1ba84bd9ff728..50110dee133d8 100644 --- a/drivers/ethernet/eth_lan865x_priv.h +++ b/drivers/ethernet/eth_lan865x_priv.h @@ -15,50 +15,42 @@ #include #include "oa_tc6.h" -#define LAN865X_SPI_MAX_FREQUENCY 25000000U -#define LAN865X_HW_BOOT_DELAY_MS 7 -#define LAN8650_DEVID 0x8650 -#define LAN8651_DEVID 0x8651 -#define LAN865X_REV_MASK GENMASK(3, 0) -#define LAN865X_RESET_TIMEOUT 10 +#define LAN865X_SPI_MAX_FREQUENCY 25000000U +#define LAN865X_HW_BOOT_DELAY_MS 7 +#define LAN8650_DEVID 0x8650 +#define LAN8651_DEVID 0x8651 +#define LAN865X_REV_MASK GENMASK(3, 0) +#define LAN865X_RESET_TIMEOUT 10 /* Memory Map Sector (MMS) 1 (0x1) */ -#define LAN865x_MAC_NCR MMS_REG(0x1, 0x000) -#define LAN865x_MAC_NCR_TXEN BIT(3) -#define LAN865x_MAC_NCR_RXEN BIT(2) -#define LAN865x_MAC_NCFGR MMS_REG(0x1, 0x001) -#define LAN865x_MAC_NCFGR_CAF BIT(4) -#define LAN865x_MAC_NCFGR_MTIHEN BIT(6) -#define LAN865x_MAC_HRB MMS_REG(0x1, 0x020) -#define LAN865x_MAC_HRT MMS_REG(0x1, 0x021) -#define LAN865x_MAC_SAB1 MMS_REG(0x1, 0x022) -#define LAN865x_MAC_SAB2 MMS_REG(0x1, 0x024) -#define LAN865x_MAC_SAT2 MMS_REG(0x1, 0x025) +#define LAN865x_MAC_NCR MMS_REG(0x1, 0x000) +#define LAN865x_MAC_NCR_TXEN BIT(3) +#define LAN865x_MAC_NCR_RXEN BIT(2) +#define LAN865x_MAC_NCFGR MMS_REG(0x1, 0x001) +#define LAN865x_MAC_NCFGR_CAF BIT(4) +#define LAN865x_MAC_NCFGR_MTIHEN BIT(6) +#define LAN865x_MAC_HRB MMS_REG(0x1, 0x020) +#define LAN865x_MAC_HRT MMS_REG(0x1, 0x021) +#define LAN865x_MAC_SAB1 MMS_REG(0x1, 0x022) +#define LAN865x_MAC_SAB2 MMS_REG(0x1, 0x024) +#define LAN865x_MAC_SAT2 MMS_REG(0x1, 0x025) +/* LAN8650/1 configuration fixup from AN1760 */ +#define LAN865X_FIXUP_REG MMS_REG(0x1, 0x077) +#define LAN865X_FIXUP_VALUE 0x0028 -#define LAN865x_MAC_TXRX_ON 1 -#define LAN865x_MAC_TXRX_OFF 0 +#define LAN865x_MAC_TXRX_ON 1 +#define LAN865x_MAC_TXRX_OFF 0 /* Memory Map Sector (MMS) 10 (0xA) */ #define LAN865x_DEVID MMS_REG(0xA, 0x094) -struct lan865x_config_plca { - bool enable : 1; /* 1 - PLCA enable, 0 - CSMA/CD enable */ - uint8_t node_id /* PLCA node id range: 0 to 254 */; - uint8_t node_count; /* PLCA node count range: 1 to 255 */ - uint8_t burst_count; /* PLCA burst count range: 0x0 to 0xFF */ - uint8_t burst_timer; /* PLCA burst timer */ - uint8_t to_timer; /* PLCA TO value */ -}; - struct lan865x_config { + const struct device *phy; struct spi_dt_spec spi; struct gpio_dt_spec interrupt; struct gpio_dt_spec reset; int32_t timeout; - /* PLCA */ - struct lan865x_config_plca *plca; - /* MAC */ bool tx_cut_through_mode; /* 1 - tx cut through, 0 - Store and forward */ bool rx_cut_through_mode; /* 1 - rx cut through, 0 - Store and forward */ @@ -81,14 +73,4 @@ struct lan865x_data { k_tid_t tid_int; }; -static inline void lan865x_update_dev_cfg_array(oa_mem_map_t *cfg, uint8_t size, - uint32_t addr, uint16_t val) -{ - for (uint8_t i = 0; i < size; i++) { - if (cfg[i].address == addr) { - cfg[i].value = val; - } - } -} - #endif /* ETH_LAN865X_PRIV_H__ */ diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c new file mode 100644 index 0000000000000..0e1d3d6e74457 --- /dev/null +++ b/drivers/ethernet/eth_lan9250.c @@ -0,0 +1,719 @@ +/* LAN9250 Stand-alone Ethernet Controller with SPI + * + * Copyright (c) 2024 Mario Paja + * + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT microchip_lan9250 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eth_lan9250_priv.h" + +LOG_MODULE_REGISTER(eth_lan9250, CONFIG_ETHERNET_LOG_LEVEL); + +static int lan9250_write_sys_reg(const struct device *dev, uint16_t address, uint32_t data) +{ + const struct lan9250_config *config = dev->config; + uint8_t cmd[1] = {LAN9250_SPI_INSTR_WRITE}; + uint8_t addr[2]; + uint8_t instr[4]; + struct spi_buf tx_buf[3]; + const struct spi_buf_set tx = {.buffers = tx_buf, .count = 3}; + + sys_put_be16(address, addr); + sys_put_le32(data, instr); + + tx_buf[0].buf = &cmd; + tx_buf[0].len = ARRAY_SIZE(cmd); + tx_buf[1].buf = addr; + tx_buf[1].len = ARRAY_SIZE(addr); + tx_buf[2].buf = instr; + tx_buf[2].len = ARRAY_SIZE(instr); + + return spi_write_dt(&config->spi, &tx); +} + +static int lan9250_read_sys_reg(const struct device *dev, uint16_t address, uint32_t *value) +{ + const struct lan9250_config *config = dev->config; + uint8_t cmd[1] = {LAN9250_SPI_INSTR_READ}; + uint8_t addr[2]; + struct spi_buf tx_buf[3]; + struct spi_buf rx_buf[3]; + const struct spi_buf_set tx = {.buffers = tx_buf, .count = 3}; + const struct spi_buf_set rx = {.buffers = rx_buf, .count = 3}; + + sys_put_be16(address, addr); + + tx_buf[0].buf = &cmd; + tx_buf[0].len = ARRAY_SIZE(cmd); + tx_buf[1].buf = addr; + tx_buf[1].len = ARRAY_SIZE(addr); + tx_buf[2].buf = NULL; + tx_buf[2].len = sizeof(uint32_t); + + rx_buf[0].buf = NULL; + rx_buf[0].len = 1; + rx_buf[1].buf = NULL; + rx_buf[1].len = 2; + rx_buf[2].buf = value; + rx_buf[2].len = sizeof(uint32_t); + + return spi_transceive_dt(&config->spi, &tx, &rx); +} + +static int lan9250_wait_ready(const struct device *dev, uint16_t address, uint32_t mask, + uint32_t expected, uint32_t m_second) +{ + uint32_t tmp; + int wait_time = 0; + + while (true) { + lan9250_read_sys_reg(dev, address, &tmp); + wait_time++; + k_busy_wait(USEC_PER_MSEC * 1U); + if ((tmp & mask) == expected) { + return 0; + } else if (wait_time == m_second) { + LOG_ERR("NOT READY"); + return -EIO; + } + } +} + +static int lan9250_read_mac_reg(const struct device *dev, uint8_t address, uint32_t *value) +{ + uint32_t tmp; + + /* Wait for MAC to be ready and send writing register command and data */ + lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, + address | LAN9250_MAC_CSR_CMD_BUSY | LAN9250_MAC_CSR_CMD_READ); + + /* Wait for MAC to be ready and send writing register command and data */ + lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + lan9250_read_sys_reg(dev, LAN9250_MAC_CSR_DATA, &tmp); + + *value = tmp; + return 0; +} + +static int lan9250_write_mac_reg(const struct device *dev, uint8_t address, uint32_t data) +{ + /* Wait for MAC to be ready and send writing register command and data */ + lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_DATA, data); + lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, address | LAN9250_MAC_CSR_CMD_BUSY); + + /* Wait until writing MAC is done */ + lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + + return 0; +} + +static int lan9250_wait_mac_ready(const struct device *dev, uint8_t address, uint32_t mask, + uint32_t expected, uint32_t m_second) +{ + uint32_t tmp; + int wait_time = 0; + + while (true) { + lan9250_read_mac_reg(dev, address, &tmp); + wait_time++; + k_msleep(1); + if ((tmp & mask) == expected) { + return 0; + } else if (wait_time == m_second) { + return -EIO; + } + } +} + +static int lan9250_read_phy_reg(const struct device *dev, uint8_t address, uint16_t *value) +{ + uint32_t tmp; + + /* Wait PHY to be ready and send reading register command */ + lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + + /* Reference: Microchip Ethernet LAN9250 + * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/ + * + * Datasheet: + * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001913A.pdf + * + * 12.2.18 PHY REGISTERS + * The PHY registers are indirectly accessed through the Host MAC MII Access Register + * (HMAC_MII_ACC) and Host MAC MII Data Register (HMAC_MII_DATA). + * + * Write 32bit value to the indirect MAC registers + * Where phy_add = 0b00001 & index = address + * Data = ((phy_add & 0x1F) << 11) | ((index & 0x1F) << 6) + */ + lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, (1 << 11) | ((address & 0x1F) << 6)); + + /* Wait PHY to be ready and send reading register command */ + lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + + /* Read 32bit value from the indirect MAC registers */ + lan9250_read_mac_reg(dev, LAN9250_HMAC_MII_DATA, &tmp); + *value = tmp; + + return 0; +} + +static int lan9250_write_phy_reg(const struct device *dev, uint8_t address, uint16_t data) +{ + /* Wait PHY to be ready and send reading register command */ + lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_DATA, data); + + /* Reference: Microchip Ethernet LAN9250 + * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/ + * + * Datasheet: + * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001913A.pdf + * + * 12.2.18 PHY REGISTERS + * The PHY registers are indirectly accessed through the Host MAC MII Access Register + * (HMAC_MII_ACC) and Host MAC MII Data Register (HMAC_MII_DATA). + * + * Write 32bit value to the indirect MAC registers + * Where phy_add = 0b00001 & index = address + * Data = ((phy_add & 0x1F) << 11) | ((index & 0x1F)<< 6) | MIIWnR + */ + lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, + (1 << 11) | ((address & 0x1F) << 6) | LAN9250_HMAC_MII_ACC_MIIW_R); + + /* Wait PHY to be ready and send reading register command */ + lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + + return 0; +} + +static int lan9250_set_macaddr(const struct device *dev) +{ + struct lan9250_runtime *ctx = dev->data; + + lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRL, + ctx->mac_address[0] | (ctx->mac_address[1] << 8) | + (ctx->mac_address[2] << 16) | (ctx->mac_address[3] << 24)); + lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRH, + ctx->mac_address[4] | (ctx->mac_address[5] << 8)); + + return 0; +} + +static int lan9250_hw_cfg_check(const struct device *dev) +{ + uint32_t tmp; + + do { + lan9250_read_sys_reg(dev, LAN9250_HW_CFG, &tmp); + k_busy_wait(USEC_PER_MSEC * 1U); + } while ((tmp & LAN9250_HW_CFG_DEVICE_READY) == 0); + + return 0; +} + +static int lan9250_sw_reset(const struct device *dev) +{ + lan9250_write_sys_reg(dev, LAN9250_RESET_CTL, + LAN9250_RESET_CTL_HMAC_RST | LAN9250_RESET_CTL_PHY_RST | + LAN9250_RESET_CTL_DIGITAL_RST); + + /* Wait until LAN9250 SPI bus is ready */ + lan9250_wait_ready(dev, LAN9250_BYTE_TEST, BOTR_MASK, LAN9250_BYTE_TEST_DEFAULT, + LAN9250_RESET_TIMEOUT); + + return 0; +} + +static int lan9250_configure(const struct device *dev) +{ + uint32_t tmp; + + lan9250_hw_cfg_check(dev); + + /* Read LAN9250 hardware ID */ + lan9250_read_sys_reg(dev, LAN9250_ID_REV, &tmp); + if ((tmp & LAN9250_ID_REV_CHIP_ID) != LAN9250_ID_REV_CHIP_ID_DEFAULT) { + LOG_ERR("ERROR: Bad Rev ID: %08x\n", tmp); + return -ENODEV; + } + + /* Configure TX FIFO size mode to be 8: + * + * - TX data FIFO size: 7680 + * - RX data FIFO size: 7680 + * - TX status FIFO size: 512 + * - RX status FIFO size: 512 + */ + lan9250_write_sys_reg(dev, LAN9250_HW_CFG, + LAN9250_HW_CFG_MBO | LAN9250_HW_CFG_TX_FIF_SZ_8KB); + + /* Configure MAC automatic flow control: + * + * Reference: Microchip Ethernet LAN9250 + * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/ + * LAN_Regwrite32(AFC_CFG, 0x006E3741); + * + */ + lan9250_write_sys_reg(dev, LAN9250_AFC_CFG, 0x006e3741); + + /* Configure interrupt: + * + * - Interrupt De-assertion interval: 100 + * - Interrupt output to pin + * - Interrupt pin active output low + * - Interrupt pin push-pull driver + */ + lan9250_write_sys_reg(dev, LAN9250_IRQ_CFG, + LAN9250_IRQ_CFG_INT_DEAS_100US | LAN9250_IRQ_CFG_IRQ_EN | + LAN9250_IRQ_CFG_IRQ_TYPE_PP); + + /* Configure interrupt trigger source, please refer to macro + * LAN9250_INT_SOURCE. + */ + lan9250_write_sys_reg(dev, LAN9250_INT_EN, + LAN9250_INT_EN_PHY_INT_EN | LAN9250_INT_EN_RSFL_EN); + + /* Disable TX data FIFO available interrupt */ + lan9250_write_sys_reg(dev, LAN9250_FIFO_INT, + LAN9250_FIFO_INT_TX_DATA_AVAILABLE_LEVEL | + LAN9250_FIFO_INT_TX_STATUS_LEVEL); + + /* Configure RX: + * + * - RX DMA counter: Ethernet maximum packet size + * - RX data offset: 4, so that need read dummy before reading data + */ + lan9250_write_sys_reg(dev, LAN9250_RX_CFG, 0x06000000 | 0x00000400); + + /* Configure remote power management: + * + * - Auto wakeup + * - Disable 1588 clock + * - Disable 1588 timestamp unit clock + * - Energy-detect + * - Wake on + * - Clear wakeon + */ + lan9250_write_sys_reg(dev, LAN9250_PMT_CTRL, + LAN9250_PMT_CTRL_PM_WAKE | LAN9250_PMT_CTRL_1588_DIS | + LAN9250_PMT_CTRL_1588_TSU_DIS | LAN9250_PMT_CTRL_WOL_EN | + LAN9250_PMT_CTRL_WOL_STS); + + /* Configure PHY basic control: + * + * - Auto-Negotiation for 10/100 Mbits and Half/Full Duplex + */ + lan9250_write_phy_reg(dev, LAN9250_PHY_BASIC_CONTROL, + LAN9250_PHY_BASIC_CONTROL_PHY_AN | + LAN9250_PHY_BASIC_CONTROL_PHY_SPEED_SEL_LSB | + LAN9250_PHY_BASIC_CONTROL_PHY_DUPLEX); + + /* Configure PHY auto-negotiation advertisement capability: + * + * - Asymmetric pause + * - Symmetric pause + * - 100Base-X half/full duplex + * - 10Base-X half/full duplex + * - Select IEEE802.3 + */ + lan9250_write_phy_reg(dev, LAN9250_PHY_AN_ADV, + LAN9250_PHY_AN_ADV_ASYM_PAUSE | LAN9250_PHY_AN_ADV_SYM_PAUSE | + LAN9250_PHY_AN_ADV_100BTX_HD | LAN9250_PHY_AN_ADV_100BTX_FD | + LAN9250_PHY_AN_ADV_10BT_HD | LAN9250_PHY_AN_ADV_10BT_FD | + LAN9250_PHY_AN_ADV_SELECTOR_DEFAULT); + + /* Configure PHY special mode: + * + * - PHY mode = 111b, enable all capable and auto-nagotiation + * - PHY address = 1, default value is fixed to 1 by manufacturer + */ + lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_MODES, 0x00E0 | 1); + + /* Configure PHY special control or status indication: + * + * - Port auto-MDIX determined by bits 14 and 13 + * - Auto-MDIX + * - Disable SQE tests + */ + lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STAT_IND, + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXCTRL | + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXEN | + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_SQEOFF); + + /* Configure PHY interrupt source: + * + * - Link up + * - Link down + */ + lan9250_write_phy_reg(dev, LAN9250_PHY_INTERRUPT_MASK, + LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP | + LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN); + + /* Configure special control or status: + * + * - Fixed to write 0000010b to reserved filed + */ + lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STATUS, + LAN9250_PHY_MODE_CONTROL_STATUS_ALTINT); + + /* Clear interrupt status */ + lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFF); + + /* Configure HMAC control: + * + * - Automatically strip the pad field on incoming packets + * - TX enable + * - RX enable + * - Full duplex + * - Promiscuous disabled + */ + lan9250_write_mac_reg(dev, LAN9250_HMAC_CR, + LAN9250_HMAC_CR_PADSTR | LAN9250_HMAC_CR_TXEN | LAN9250_HMAC_CR_RXEN | + LAN9250_HMAC_CR_FDPX); + + /* Configure TX: + * + * - TX enable + */ + lan9250_write_sys_reg(dev, LAN9250_TX_CFG, LAN9250_TX_CFG_TX_ON); + + return 0; +} + +static int lan9250_write_buf(const struct device *dev, uint8_t *data_buffer, uint16_t buf_len) +{ + const struct lan9250_config *config = dev->config; + uint8_t cmd[1] = {LAN9250_SPI_INSTR_WRITE}; + uint8_t instr[2] = {(LAN9250_TX_DATA_FIFO >> 8) & 0xFF, (LAN9250_TX_DATA_FIFO & 0xFF)}; + struct spi_buf tx_buf[3]; + const struct spi_buf_set tx = {.buffers = tx_buf, .count = 3}; + + tx_buf[0].buf = &cmd; + tx_buf[0].len = ARRAY_SIZE(cmd); + tx_buf[1].buf = &instr; + tx_buf[1].len = ARRAY_SIZE(instr); + tx_buf[2].buf = data_buffer; + tx_buf[2].len = buf_len; + + return spi_transceive_dt(&config->spi, &tx, NULL); +} + +static int lan9250_read_buf(const struct device *dev, uint8_t *data_buffer, uint16_t buf_len) +{ + const struct lan9250_config *config = dev->config; + uint8_t cmd[1] = {LAN9250_SPI_INSTR_READ}; + uint8_t instr[2] = {(LAN9250_RX_DATA_FIFO >> 8) & 0xFF, (LAN9250_RX_DATA_FIFO & 0xFF)}; + struct spi_buf tx_buf[3]; + struct spi_buf rx_buf[3]; + const struct spi_buf_set tx = {.buffers = tx_buf, .count = 3}; + const struct spi_buf_set rx = {.buffers = rx_buf, .count = 3}; + + tx_buf[0].buf = &cmd; + tx_buf[0].len = ARRAY_SIZE(cmd); + tx_buf[1].buf = &instr; + tx_buf[1].len = ARRAY_SIZE(instr); + tx_buf[2].buf = NULL; + tx_buf[2].len = buf_len; + + rx_buf[0].buf = NULL; + rx_buf[0].len = 1; + rx_buf[1].buf = NULL; + rx_buf[1].len = 2; + rx_buf[2].buf = data_buffer; + rx_buf[2].len = buf_len; + + return spi_transceive_dt(&config->spi, &tx, &rx); +} + +static int lan9250_rx(const struct device *dev) +{ + const struct lan9250_config *config = dev->config; + struct lan9250_runtime *ctx = dev->data; + const uint16_t buf_rx_size = CONFIG_NET_BUF_DATA_SIZE; + struct net_pkt *pkt; + struct net_buf *pkt_buf; + uint16_t pkt_len; + uint8_t pktcnt; + uint32_t tmp; + + /* Check valid packet count */ + lan9250_read_sys_reg(dev, LAN9250_RX_FIFO_INF, &tmp); + pktcnt = (tmp & 0x00ff0000) >> 16; + + /* Check packet length */ + lan9250_read_sys_reg(dev, LAN9250_RX_STATUS_FIFO, &tmp); + pkt_len = (tmp & LAN9250_RX_STS_PACKET_LEN) >> 16; + + if (pktcnt == 0 || pkt_len == 0) { + return 0; + } + + /* Read dummy data */ + lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + pkt_len -= 4; + + if (pkt_len > NET_ETH_MAX_FRAME_SIZE) { + LOG_ERR("Maximum frame length exceeded, it should be: %d", NET_ETH_MAX_FRAME_SIZE); + eth_stats_update_errors_rx(ctx->iface); + } + + /* Get the frame from the buffer */ + pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, pkt_len, AF_UNSPEC, 0, + K_MSEC(config->timeout)); + if (!pkt) { + LOG_ERR("%s: Could not allocate rx buffer", dev->name); + eth_stats_update_errors_rx(ctx->iface); + return 0; + } + + pkt_buf = pkt->buffer; + + do { + uint8_t *data_ptr = pkt_buf->data; + uint16_t data_len; + + if (pkt_len > buf_rx_size) { + data_len = buf_rx_size; + } else { + data_len = pkt_len; + } + pkt_len -= data_len; + + lan9250_read_buf(dev, data_ptr, data_len); + net_buf_add(pkt_buf, data_len); + pkt_buf = pkt_buf->frags; + } while (pkt_len > 0); + + lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + net_pkt_set_iface(pkt, ctx->iface); + + /* Feed buffer frame to IP stack */ + if (net_recv_data(net_pkt_iface(pkt), pkt) < 0) { + net_pkt_unref(pkt); + } + + k_sem_give(&ctx->tx_rx_sem); + + return 0; +} + +static int lan9250_tx(const struct device *dev, struct net_pkt *pkt) +{ + struct lan9250_runtime *ctx = dev->data; + size_t len = net_pkt_get_len(pkt); + uint32_t regval; + uint16_t free_size; + uint8_t status_size; + uint32_t tmp; + + lan9250_read_sys_reg(dev, LAN9250_TX_FIFO_INF, ®val); + status_size = (regval & LAN9250_TX_FIFO_INF_TXSUSED) >> 16; + free_size = regval & LAN9250_TX_FIFO_INF_TXFREE; + + k_sem_take(&ctx->tx_rx_sem, K_FOREVER); + + /* TX command 'A' */ + lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, + LAN9250_TX_CMD_A_INT_ON_COMP | LAN9250_TX_CMD_A_BUFFER_ALIGN_4B | + LAN9250_TX_CMD_A_START_OFFSET_0B | + LAN9250_TX_CMD_A_FIRST_SEG | LAN9250_TX_CMD_A_LAST_SEG | len); + + /* TX command 'B' */ + lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, LAN9250_TX_CMD_B_PACKET_TAG | len); + + if (net_pkt_read(pkt, ctx->buf, len)) { + return -EIO; + } + + lan9250_write_buf(dev, ctx->buf, LAN9250_ALIGN(len)); + + for (int i = 0; i < status_size; i++) { + lan9250_read_sys_reg(dev, LAN9250_TX_STATUS_FIFO, &tmp); + } + + k_sem_give(&ctx->tx_rx_sem); + + return 0; +} + +static void lan9250_gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct lan9250_runtime *context = CONTAINER_OF(cb, struct lan9250_runtime, gpio_cb); + + k_sem_give(&context->int_sem); +} + +static void lan9250_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct lan9250_runtime *context = p1; + uint32_t int_sts; + uint16_t tmp; + uint32_t ier; + + while (true) { + k_sem_take(&context->int_sem, K_FOREVER); + + /* Save interrupt enable register value */ + lan9250_read_sys_reg(context->dev, LAN9250_INT_EN, &ier); + + /* Disable interrupts to release the interrupt line */ + lan9250_write_sys_reg(context->dev, LAN9250_INT_EN, 0); + + /* Read interrupt status register */ + lan9250_read_sys_reg(context->dev, LAN9250_INT_STS, &int_sts); + + if ((int_sts & LAN9250_INT_STS_PHY_INT) != 0) { + + /* Read PHY interrupt source register */ + lan9250_read_phy_reg(context->dev, LAN9250_PHY_INTERRUPT_SOURCE, &tmp); + if (tmp & LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP) { + LOG_DBG("LINK UP"); + net_eth_carrier_on(context->iface); + } else if (tmp & LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN) { + LOG_DBG("LINK DOWN"); + net_eth_carrier_off(context->iface); + } + } + + if ((int_sts & LAN9250_INT_STS_RSFL) != 0) { + lan9250_write_sys_reg(context->dev, LAN9250_INT_STS, LAN9250_INT_STS_RSFL); + lan9250_rx(context->dev); + } + + /* Re-enable interrupts */ + lan9250_write_sys_reg(context->dev, LAN9250_INT_EN, ier); + } +} + +static enum ethernet_hw_caps lan9250_get_capabilities(const struct device *dev) +{ + ARG_UNUSED(dev); + + return ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T; +} + +static void lan9250_iface_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct lan9250_runtime *context = dev->data; + + net_if_set_link_addr(iface, context->mac_address, sizeof(context->mac_address), + NET_LINK_ETHERNET); + context->iface = iface; + ethernet_init(iface); + + net_if_carrier_off(iface); +} + +static int lan9250_set_config(const struct device *dev, enum ethernet_config_type type, + const struct ethernet_config *config) +{ + struct lan9250_runtime *ctx = dev->data; + + if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) { + memcpy(ctx->mac_address, config->mac_address.addr, sizeof(ctx->mac_address)); + lan9250_set_macaddr(dev); + return net_if_set_link_addr(ctx->iface, ctx->mac_address, sizeof(ctx->mac_address), + NET_LINK_ETHERNET); + } + + return -ENOTSUP; +} + +static const struct ethernet_api api_funcs = { + .iface_api.init = lan9250_iface_init, + .get_capabilities = lan9250_get_capabilities, + .set_config = lan9250_set_config, + .send = lan9250_tx, +}; + +static int lan9250_init(const struct device *dev) +{ + const struct lan9250_config *config = dev->config; + struct lan9250_runtime *context = dev->data; + + context->dev = dev; + + /* SPI config */ + if (!spi_is_ready_dt(&config->spi)) { + LOG_ERR("SPI master port %s not ready", config->spi.bus->name); + return -EINVAL; + } + + /* Initialize GPIO */ + if (!gpio_is_ready_dt(&config->interrupt)) { + LOG_ERR("GPIO port %s not ready", config->interrupt.port->name); + return -EINVAL; + } + + if (gpio_pin_configure_dt(&config->interrupt, GPIO_INPUT)) { + LOG_ERR("Unable to configure GPIO pin %u", config->interrupt.pin); + return -EINVAL; + } + + gpio_init_callback(&(context->gpio_cb), lan9250_gpio_callback, BIT(config->interrupt.pin)); + if (gpio_add_callback(config->interrupt.port, &(context->gpio_cb))) { + return -EINVAL; + } + + gpio_pin_interrupt_configure_dt(&config->interrupt, GPIO_INT_EDGE_TO_ACTIVE); + + /* Wait until LAN9250 SPI bus is ready */ + lan9250_wait_ready(dev, LAN9250_BYTE_TEST, BOTR_MASK, LAN9250_BYTE_TEST_DEFAULT, + LAN9250_RESET_TIMEOUT); + lan9250_sw_reset(dev); + lan9250_configure(dev); + lan9250_set_macaddr(dev); + + k_thread_create(&context->thread, context->thread_stack, + CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE, lan9250_thread, context, NULL, + NULL, K_PRIO_COOP(CONFIG_ETH_LAN9250_RX_THREAD_PRIO), 0, K_NO_WAIT); + + LOG_INF("LAN9250 Initialized"); + + return 0; +} + +#define LAN9250_DEFINE(inst) \ + static struct lan9250_runtime lan9250_##inst##_runtime = { \ + .mac_address = DT_INST_PROP(inst, local_mac_address), \ + .tx_rx_sem = Z_SEM_INITIALIZER(lan9250_##inst##_runtime.tx_rx_sem, 1, UINT_MAX), \ + .int_sem = Z_SEM_INITIALIZER(lan9250_##inst##_runtime.int_sem, 0, UINT_MAX), \ + }; \ + \ + static const struct lan9250_config lan9250_##inst##_config = { \ + .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0), \ + .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ + .timeout = CONFIG_ETH_LAN9250_BUF_ALLOC_TIMEOUT, \ + }; \ + \ + ETH_NET_DEVICE_DT_INST_DEFINE(inst, lan9250_init, NULL, &lan9250_##inst##_runtime, \ + &lan9250_##inst##_config, CONFIG_ETH_INIT_PRIORITY, \ + &api_funcs, NET_ETH_MTU); +DT_INST_FOREACH_STATUS_OKAY(LAN9250_DEFINE); diff --git a/drivers/ethernet/eth_lan9250_priv.h b/drivers/ethernet/eth_lan9250_priv.h new file mode 100644 index 0000000000000..b6379216bdf3e --- /dev/null +++ b/drivers/ethernet/eth_lan9250_priv.h @@ -0,0 +1,333 @@ +/* LAN9250 Stand-alone Ethernet Controller with SPI + * + * Copyright (c) 2024 Mario Paja + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#ifndef _LAN9250_ +#define _LAN9250_ + +#define LAN9250_DEFAULT_NUMOF_RETRIES 3U +#define LAN9250_PHY_TIMEOUT 2000 +#define LAN9250_MAC_TIMEOUT 2000 +#define LAN9250_RESET_TIMEOUT 5000 + +#define LAN9250_ALIGN(v) (((v) + 3) & (~3)) + +/* SPI instructions */ +#define LAN9250_SPI_INSTR_WRITE 0x02 +#define LAN9250_SPI_INSTR_READ 0x03 + +/* TX command 'A' format */ +#define LAN9250_TX_CMD_A_INT_ON_COMP 0x80000000 +#define LAN9250_TX_CMD_A_BUFFER_ALIGN_4B 0x00000000 +#define LAN9250_TX_CMD_A_START_OFFSET_0B 0x00000000 +#define LAN9250_TX_CMD_A_FIRST_SEG 0x00002000 +#define LAN9250_TX_CMD_A_LAST_SEG 0x00001000 + +/* TX command 'B' format */ +#define LAN9250_TX_CMD_B_PACKET_TAG 0xFFFF0000 + +/* RX status format */ +#define LAN9250_RX_STS_PACKET_LEN 0x3FFF0000 + +/* LAN9250 System registers */ +#define LAN9250_RX_DATA_FIFO 0x0000 +#define LAN9250_TX_DATA_FIFO 0x0020 +#define LAN9250_RX_STATUS_FIFO 0x0040 +#define LAN9250_TX_STATUS_FIFO 0x0048 +#define LAN9250_ID_REV 0x0050 +#define LAN9250_IRQ_CFG 0x0054 +#define LAN9250_INT_STS 0x0058 +#define LAN9250_INT_EN 0x005C +#define LAN9250_BYTE_TEST 0x0064 +#define LAN9250_FIFO_INT 0x0068 +#define LAN9250_RX_CFG 0x006C +#define LAN9250_TX_CFG 0x0070 +#define LAN9250_HW_CFG 0x0074 +#define LAN9250_RX_FIFO_INF 0x007C +#define LAN9250_TX_FIFO_INF 0x0080 +#define LAN9250_PMT_CTRL 0x0084 +#define LAN9250_MAC_CSR_CMD 0x00A4 +#define LAN9250_MAC_CSR_DATA 0x00A8 +#define LAN9250_AFC_CFG 0x00AC +#define LAN9250_RESET_CTL 0x01F8 + +/* LAN9250 Host MAC registers */ +#define LAN9250_HMAC_CR 0x01 +#define LAN9250_HMAC_ADDRH 0x02 +#define LAN9250_HMAC_ADDRL 0x03 +#define LAN9250_HMAC_MII_ACC 0x06 +#define LAN9250_HMAC_MII_DATA 0x07 + +/* LAN9250 PHY registers */ +#define LAN9250_PHY_BASIC_CONTROL 0x00 +#define LAN9250_PHY_AN_ADV 0x04 +#define LAN9250_PHY_SPECIAL_MODES 0x12 +#define LAN9250_PHY_SPECIAL_CONTROL_STAT_IND 0x1B +#define LAN9250_PHY_INTERRUPT_SOURCE 0x1D +#define LAN9250_PHY_INTERRUPT_MASK 0x1E +#define LAN9250_PHY_SPECIAL_CONTROL_STATUS 0x1F + +/* Interrupt Configuration register */ +#define LAN9250_IRQ_CFG_INT_DEAS 0xFF000000 +#define LAN9250_IRQ_CFG_INT_DEAS_10US 0x01000000 +#define LAN9250_IRQ_CFG_INT_DEAS_100US 0x0A000000 +#define LAN9250_IRQ_CFG_INT_DEAS_1MS 0x64000000 +#define LAN9250_IRQ_CFG_INT_DEAS_CLR 0x00004000 +#define LAN9250_IRQ_CFG_INT_DEAS_STS 0x00002000 +#define LAN9250_IRQ_CFG_IRQ_INT 0x00001000 +#define LAN9250_IRQ_CFG_IRQ_EN 0x00000100 +#define LAN9250_IRQ_CFG_IRQ_POL 0x00000010 +#define LAN9250_IRQ_CFG_IRQ_POL_LOW 0x00000000 +#define LAN9250_IRQ_CFG_IRQ_POL_HIGH 0x00000010 +#define LAN9250_IRQ_CFG_IRQ_CLK_SELECT 0x00000002 +#define LAN9250_IRQ_CFG_IRQ_TYPE 0x00000001 +#define LAN9250_IRQ_CFG_IRQ_TYPE_OD 0x00000000 +#define LAN9250_IRQ_CFG_IRQ_TYPE_PP 0x00000001 + +/* INTERRUPT STATUS REGISTER (INT_STS) */ +#define LAN9250_INT_STS_SW_INT 0x80000000 +#define LAN9250_INT_STS_READY 0x40000000 +#define LAN9250_INT_STS_1588_EVNT 0x20000000 +#define LAN9250_INT_STS_PHY_INT 0x04000000 +#define LAN9250_INT_STS_TXSTOP_INT 0x02000000 +#define LAN9250_INT_STS_RXSTOP_INT 0x01000000 +#define LAN9250_INT_STS_RXDFH_INT 0x00800000 +#define LAN9250_INT_STS_TX_IOC 0x00200000 +#define LAN9250_INT_STS_RXD_INT 0x00100000 +#define LAN9250_INT_STS_GPT_INT 0x00080000 +#define LAN9250_INT_STS_PME_INT 0x00020000 +#define LAN9250_INT_STS_TXSO 0x00010000 +#define LAN9250_INT_STS_RWT 0x00008000 +#define LAN9250_INT_STS_RXE 0x00004000 +#define LAN9250_INT_STS_TXE 0x00002000 +#define LAN9250_INT_STS_GPIO 0x00001000 +#define LAN9250_INT_STS_TDFO 0x00000400 +#define LAN9250_INT_STS_TDFA 0x00000200 +#define LAN9250_INT_STS_TSFF 0x00000100 +#define LAN9250_INT_STS_TSFL 0x00000080 +#define LAN9250_INT_STS_RXDF_INT 0x00000040 +#define LAN9250_INT_STS_RSFF 0x00000010 +#define LAN9250_INT_STS_RSFL 0x00000008 + +/* INTERRUPT ENABLE REGISTER (INT_EN) */ +#define LAN9250_INT_EN_SW_INT_EN 0x80000000 +#define LAN9250_INT_EN_READY_EN 0x40000000 +#define LAN9250_INT_EN_1588_EVNT_EN 0x20000000 +#define LAN9250_INT_EN_PHY_INT_EN 0x04000000 +#define LAN9250_INT_EN_TXSTOP_INT_EN 0x02000000 +#define LAN9250_INT_EN_RXSTOP_INT_EN 0x01000000 +#define LAN9250_INT_EN_RXDFH_INT_EN 0x00800000 +#define LAN9250_INT_EN_TIOC_INT_EN 0x00200000 +#define LAN9250_INT_EN_RXD_INT_EN 0x00100000 +#define LAN9250_INT_EN_GPT_INT_EN 0x00080000 +#define LAN9250_INT_EN_PME_INT_EN 0x00020000 +#define LAN9250_INT_EN_TXSO_EN 0x00010000 +#define LAN9250_INT_EN_RWT_INT_EN 0x00008000 +#define LAN9250_INT_EN_RXE_INT_EN 0x00004000 +#define LAN9250_INT_EN_TXE_INT_EN 0x00002000 +#define LAN9250_INT_EN_GPIO_EN 0x00001000 +#define LAN9250_INT_EN_TDFO_EN 0x00000400 +#define LAN9250_INT_EN_TDFA_EN 0x00000200 +#define LAN9250_INT_EN_TSFF_EN 0x00000100 +#define LAN9250_INT_EN_TSFL_EN 0x00000080 +#define LAN9250_INT_EN_RXDF_INT_EN 0x00000040 +#define LAN9250_INT_EN_RSFF_EN 0x00000010 +#define LAN9250_INT_EN_RSFL_EN 0x00000008 + +/* Byte Order Test register */ +#define LAN9250_BYTE_TEST_DEFAULT 0x87654321 +#define BOTR_MASK 0xffffffff + +/* FIFO Level Interrupt register */ +#define LAN9250_FIFO_INT_TX_DATA_AVAILABLE_LEVEL 0xFF000000 +#define LAN9250_FIFO_INT_TX_STATUS_LEVEL 0x00FF0000 +#define LAN9250_FIFO_INT_RX_STATUS_LEVEL 0x000000FF + +/* TRANSMIT CONFIGURATION REGISTER (TX_CFG) */ +#define LAN9250_TX_CFG_TXS_DUMP 0x00008000 +#define LAN9250_TX_CFG_TXD_DUMP 0x00004000 +#define LAN9250_TX_CFG_TXSAO 0x00000004 +#define LAN9250_TX_CFG_TX_ON 0x00000002 +#define LAN9250_TX_CFG_STOP_TX 0x00000001 + +/* HARDWARE CONFIGURATION REGISTER (HW_CFG) */ +#define LAN9250_HW_CFG_DEVICE_READY 0x08000000 +#define LAN9250_HW_CFG_AMDIX_EN_STRAP_STATE 0x02000000 +#define LAN9250_HW_CFG_MBO 0x00100000 +#define LAN9250_HW_CFG_TX_FIF_SZ 0x000F0000 +#define LAN9250_HW_CFG_TX_FIF_SZ_2KB 0x00020000 +#define LAN9250_HW_CFG_TX_FIF_SZ_3KB 0x00030000 +#define LAN9250_HW_CFG_TX_FIF_SZ_4KB 0x00040000 +#define LAN9250_HW_CFG_TX_FIF_SZ_5KB 0x00050000 +#define LAN9250_HW_CFG_TX_FIF_SZ_6KB 0x00060000 +#define LAN9250_HW_CFG_TX_FIF_SZ_7KB 0x00070000 +#define LAN9250_HW_CFG_TX_FIF_SZ_8KB 0x00080000 +#define LAN9250_HW_CFG_TX_FIF_SZ_9KB 0x00090000 +#define LAN9250_HW_CFG_TX_FIF_SZ_10KB 0x000A0000 +#define LAN9250_HW_CFG_TX_FIF_SZ_11KB 0x000B0000 +#define LAN9250_HW_CFG_TX_FIF_SZ_12KB 0x000C0000 +#define LAN9250_HW_CFG_TX_FIF_SZ_13KB 0x000D0000 +#define LAN9250_HW_CFG_TX_FIF_SZ_14KB 0x000E0000 + +/* RX FIFO Information register */ +#define LAN9250_RX_FIFO_INF_RXSUSED 0x00FF0000 +#define LAN9250_RX_FIFO_INF_RXDUSED 0x0000FFFF + +/* TX FIFO Information register */ +#define LAN9250_TX_FIFO_INF_TXSUSED 0x00FF0000 +#define LAN9250_TX_FIFO_INF_TXFREE 0x0000FFFF + +/* Power Management Control Register (PMT_CTRL) */ +#define LAN9250_PMT_CTRL_PM_MODE 0xE0000000 +#define LAN9250_PMT_CTRL_PM_SLEEP_EN 0x10000000 +#define LAN9250_PMT_CTRL_PM_WAKE 0x08000000 +#define LAN9250_PMT_CTRL_LED_DIS 0x04000000 +#define LAN9250_PMT_CTRL_1588_DIS 0x02000000 +#define LAN9250_PMT_CTRL_1588_TSU_DIS 0x00400000 +#define LAN9250_PMT_CTRL_HMAC_DIS 0x00080000 +#define LAN9250_PMT_CTRL_HMAC_SYS_ONLY_DIS 0x00040000 +#define LAN9250_PMT_CTRL_ED_STS 0x00010000 +#define LAN9250_PMT_CTRL_ED_EN 0x00004000 +#define LAN9250_PMT_CTRL_WOL_EN 0x00000200 +#define LAN9250_PMT_CTRL_PME_TYPE 0x00000040 +#define LAN9250_PMT_CTRL_WOL_STS 0x00000020 +#define LAN9250_PMT_CTRL_PME_IND 0x00000008 +#define LAN9250_PMT_CTRL_PME_POL 0x00000004 +#define LAN9250_PMT_CTRL_PME_EN 0x00000002 +#define LAN9250_PMT_CTRL_READY 0x00000001 + +/* HOST MAC CSR INTERFACE COMMAND REGISTER (MAC_CSR_CMD) */ +#define LAN9250_MAC_CSR_CMD_BUSY 0x80000000 +#define LAN9250_MAC_CSR_CMD_WRITE 0x00000000 +#define LAN9250_MAC_CSR_CMD_READ 0x40000000 +#define LAN9250_MAC_CSR_CMD_ADDR 0x000000FF + +/* Reset Control Register (RESET_CTL) */ +#define LAN9250_RESET_CTL_HMAC_RST 0x00000020 +#define LAN9250_RESET_CTL_PHY_RST 0x00000002 +#define LAN9250_RESET_CTL_DIGITAL_RST 0x00000001 + +/* HOST MAC CONTROL REGISTER (HMAC_CR) */ +#define LAN9250_HMAC_CR_RXALL 0x80000000 +#define LAN9250_HMAC_CR_HMAC_EEE_ENABLE 0x02000000 +#define LAN9250_HMAC_CR_RCVOWN 0x00800000 +#define LAN9250_HMAC_CR_LOOPBK 0x00200000 +#define LAN9250_HMAC_CR_FDPX 0x00100000 +#define LAN9250_HMAC_CR_MCPAS 0x00080000 +#define LAN9250_HMAC_CR_PRMS 0x00040000 +#define LAN9250_HMAC_CR_INVFILT 0x00020000 +#define LAN9250_HMAC_CR_PASSBAD 0x00010000 +#define LAN9250_HMAC_CR_HO 0x00008000 +#define LAN9250_HMAC_CR_HPFILT 0x00002000 +#define LAN9250_HMAC_CR_BCAST 0x00000800 +#define LAN9250_HMAC_CR_DISRTY 0x00000400 +#define LAN9250_HMAC_CR_PADSTR 0x00000100 +#define LAN9250_HMAC_CR_BOLMT 0x000000C0 +#define LAN9250_HMAC_CR_BOLMT_10_BITS 0x00000000 +#define LAN9250_HMAC_CR_BOLMT_8_BITS 0x00000040 +#define LAN9250_HMAC_CR_BOLMT_4_BITS 0x00000080 +#define LAN9250_HMAC_CR_BOLMT_1_BIT 0x000000C0 +#define LAN9250_HMAC_CR_DFCHK 0x00000020 +#define LAN9250_HMAC_CR_TXEN 0x00000008 +#define LAN9250_HMAC_CR_RXEN 0x00000004 + +/* HOST MAC MII ACCESS REGISTER (HMAC_MII_ACC) */ +#define LAN9250_HMAC_MII_ACC_PHY_ADDR 0x0000F800 +#define LAN9250_HMAC_MII_ACC_PHY_ADDR_DEFAULT 0x00000800 +#define LAN9250_HMAC_MII_ACC_MIIRINDA 0x000007C0 +#define LAN9250_HMAC_MII_ACC_MIIW_R 0x00000002 +#define LAN9250_HMAC_MII_ACC_MIIBZY 0x00000001 + +/* PHY Basic Control Register (PHY_BASIC_CONTROL) */ +#define LAN9250_PHY_BASIC_CONTROL_PHY_SRST 0x8000 +#define LAN9250_PHY_BASIC_CONTROL_PHY_LOOPBACK 0x4000 +#define LAN9250_PHY_BASIC_CONTROL_PHY_SPEED_SEL_LSB 0x2000 +#define LAN9250_PHY_BASIC_CONTROL_PHY_AN 0x1000 +#define LAN9250_PHY_BASIC_CONTROL_PHY_PWR_DWN 0x0800 +#define LAN9250_PHY_BASIC_CONTROL_PHY_RST_AN 0x0200 +#define LAN9250_PHY_BASIC_CONTROL_PHY_DUPLEX 0x0100 +#define LAN9250_PHY_BASIC_CONTROL_PHY_COL_TEST 0x0080 + +/* PHY Auto-Negotiation Advertisement Register (PHY_AN_ADV) */ +#define LAN9250_PHY_AN_ADV_NEXT_PAGE 0x8000 +#define LAN9250_PHY_AN_ADV_REMOTE_FAULT 0x2000 +#define LAN9250_PHY_AN_ADV_EXTENDED_NEXT_PAGE 0x1000 +#define LAN9250_PHY_AN_ADV_ASYM_PAUSE 0x0800 +#define LAN9250_PHY_AN_ADV_SYM_PAUSE 0x0400 +#define LAN9250_PHY_AN_ADV_100BTX_FD 0x0100 +#define LAN9250_PHY_AN_ADV_100BTX_HD 0x0080 +#define LAN9250_PHY_AN_ADV_10BT_FD 0x0040 +#define LAN9250_PHY_AN_ADV_10BT_HD 0x0020 +#define LAN9250_PHY_AN_ADV_SELECTOR 0x001F +#define LAN9250_PHY_AN_ADV_SELECTOR_DEFAULT 0x0001 + +/* PHY Mode Control/Status Register (PHY_MODE_CONTROL_STATUS) */ +#define LAN9250_PHY_MODE_CONTROL_STATUS_EDPWRDOWN 0x2000 +#define LAN9250_PHY_MODE_CONTROL_STATUS_ALTINT 0x0040 +#define LAN9250_PHY_MODE_CONTROL_STATUS_ENERGYON 0x0002 + +/* PHY Special Control/Status Indication Register (PHY_SPECIAL_CONTROL_STAT_IND) */ +#define LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXCTRL 0x8000 +#define LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXEN 0x4000 +#define LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXSTATE 0x2000 +#define LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_SQEOFF 0x0800 +#define LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_FEFI_EN 0x0020 +#define LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_XPOL 0x0010 + +/* PHY Interrupt Source Flags Register (PHY_INTERRUPT_SOURCE) */ +#define LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP 0x0200 +#define LAN9250_PHY_INTERRUPT_SOURCE_ENERGYON 0x0080 +#define LAN9250_PHY_INTERRUPT_SOURCE_AN_COMPLETE 0x0040 +#define LAN9250_PHY_INTERRUPT_SOURCE_REMOTE_FAULT 0x0020 +#define LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN 0x0010 +#define LAN9250_PHY_INTERRUPT_SOURCE_AN_LP_ACK 0x0008 +#define LAN9250_PHY_INTERRUPT_SOURCE_PARALLEL_DETECT_FAULT 0x0004 +#define LAN9250_PHY_INTERRUPT_SOURCE_AN_PAGE_RECEIVED 0x0002 + +/* PHY Interrupt Mask Register (PHY_INTERRUPT_MASK) */ +#define LAN9250_PHY_INTERRUPT_MASK_LINK_UP 0x0200 +#define LAN9250_PHY_INTERRUPT_MASK_ENERGYON 0x0080 +#define LAN9250_PHY_INTERRUPT_MASK_AN_COMPLETE 0x0040 +#define LAN9250_PHY_INTERRUPT_MASK_REMOTE_FAULT 0x0020 +#define LAN9250_PHY_INTERRUPT_MASK_LINK_DOWN 0x0010 +#define LAN9250_PHY_INTERRUPT_MASK_AN_LP_ACK 0x0008 +#define LAN9250_PHY_INTERRUPT_MASK_PARALLEL_DETECT_FAULT 0x0004 +#define LAN9250_PHY_INTERRUPT_MASK_AN_PAGE_RECEIVED 0x0002 + +/* Chip ID and Revision register */ +#define LAN9250_ID_REV_CHIP_ID 0xFFFF0000 +#define LAN9250_ID_REV_CHIP_ID_DEFAULT 0x92500000 +#define LAN9250_ID_REV_CHIP_REV 0x0000FFFF + +struct lan9250_config { + struct spi_dt_spec spi; + struct gpio_dt_spec interrupt; + struct gpio_dt_spec reset; + uint8_t full_duplex; + int32_t timeout; +}; + +struct lan9250_runtime { + struct net_if *iface; + const struct device *dev; + + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE); + k_tid_t tid_int; + struct k_thread thread; + + uint8_t mac_address[6]; + struct gpio_callback gpio_cb; + struct k_sem tx_rx_sem; + struct k_sem int_sem; + uint8_t buf[NET_ETH_MAX_FRAME_SIZE]; + struct k_mutex lock; +}; + +#endif /*_LAN9250_*/ diff --git a/drivers/ethernet/eth_nxp_enet_qos/Kconfig b/drivers/ethernet/eth_nxp_enet_qos/Kconfig index 698848c65727b..fcf03148e3313 100644 --- a/drivers/ethernet/eth_nxp_enet_qos/Kconfig +++ b/drivers/ethernet/eth_nxp_enet_qos/Kconfig @@ -23,6 +23,17 @@ config ETH_NXP_ENET_QOS_MAC if ETH_NXP_ENET_QOS_MAC +DT_PROP_NXP_ENET_QOS_MAC_UNIQUE_MAC := nxp,unique-mac + +config ETH_NXP_ENET_QOS_MAC_UNIQUE_MAC_ADDRESS + bool "Unique MAC address support" + default y if $(dt_compat_any_has_prop,$(DT_COMPAT_NXP_ENET_QOS_MAC),$(DT_PROP_NXP_ENET_QOS_MAC_UNIQUE_MAC),True) + select HWINFO + select CRC + help + Enable Unique MAC address support based on device UUID. + + config ETH_NXP_ENET_QOS_TX_BUFFER_DESCRIPTORS int "Number of tx buffer descriptors" default 4 diff --git a/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c b/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c index 7f2d5bf9872e8..30b95eeff96fa 100644 --- a/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c +++ b/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c @@ -12,6 +12,10 @@ LOG_MODULE_REGISTER(eth_nxp_enet_qos_mac, CONFIG_ETHERNET_LOG_LEVEL); #include #include #include +#if defined(CONFIG_ETH_NXP_ENET_QOS_MAC_UNIQUE_MAC_ADDRESS) +#include +#include +#endif #include #include "../eth.h" #include "nxp_enet_qos_priv.h" @@ -156,7 +160,7 @@ static void tx_dma_done(struct k_work *work) static enum ethernet_hw_caps eth_nxp_enet_qos_get_capabilities(const struct device *dev) { - return ETHERNET_LINK_100BASE_T | ETHERNET_LINK_10BASE_T; + return ETHERNET_LINK_100BASE_T | ETHERNET_LINK_10BASE_T | ENET_MAC_PACKET_FILTER_PM_MASK; } static void eth_nxp_enet_qos_rx(struct k_work *work) @@ -375,6 +379,11 @@ static inline void enet_qos_mac_config_init(enet_qos_t *base, data->mac_addr.addr[1] << 8 | data->mac_addr.addr[0]); + /* permit multicast packets if there is no space in hash table for mac addresses */ + if ((base->MAC_HW_FEAT[1] & ENET_MAC_HW_FEAT_HASHTBLSZ_MASK) == 0) { + base->MAC_PACKET_FILTER |= ENET_MAC_PACKET_FILTER_PM_MASK; + } + /* Set the reference for 1 microsecond of ENET QOS CSR clock cycles */ base->MAC_ONEUS_TIC_COUNTER = ENET_QOS_REG_PREP(MAC_ONEUS_TIC_COUNTER, TIC_1US_CNTR, @@ -475,6 +484,33 @@ static inline int enet_qos_rx_desc_init(enet_qos_t *base, struct nxp_enet_qos_rx return 0; } +#if defined(CONFIG_ETH_NXP_ENET_QOS_MAC_UNIQUE_MAC_ADDRESS) +/* Note this is not universally unique, it just is probably unique on a network */ +static inline void nxp_enet_unique_mac(uint8_t *mac_addr) +{ + uint8_t unique_device_ID_16_bytes[16] = {0}; + ssize_t uuid_length = + hwinfo_get_device_id(unique_device_ID_16_bytes, sizeof(unique_device_ID_16_bytes)); + uint32_t hash = 0; + + if (uuid_length > 0) { + hash = crc24_pgp((uint8_t *)unique_device_ID_16_bytes, uuid_length); + } else { + LOG_ERR("No unique MAC can be provided in this platform"); + } + + /* Setting LAA bit because it is not guaranteed universally unique */ + mac_addr[0] = NXP_OUI_BYTE_0 | 0x02; + mac_addr[1] = NXP_OUI_BYTE_1; + mac_addr[2] = NXP_OUI_BYTE_2; + mac_addr[3] = FIELD_GET(0xFF0000, hash); + mac_addr[4] = FIELD_GET(0x00FF00, hash); + mac_addr[5] = FIELD_GET(0x0000FF, hash); +} +#else +#define nxp_enet_unique_mac(arg) +#endif + static int eth_nxp_enet_qos_mac_init(const struct device *dev) { const struct nxp_enet_qos_mac_config *config = dev->config; @@ -496,8 +532,11 @@ static int eth_nxp_enet_qos_mac_init(const struct device *dev) return ret; } - /* Random mac therefore overrides local mac that may have been initialized */ - if (config->random_mac) { + if (config->mac_addr_source == NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL) { + /* Use the mac address provided in the devicetree */ + } else if (config->mac_addr_source == NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE) { + nxp_enet_unique_mac(data->mac_addr.addr); + } else { gen_random_mac(data->mac_addr.addr, NXP_OUI_BYTE_0, NXP_OUI_BYTE_1, NXP_OUI_BYTE_2); } @@ -621,56 +660,59 @@ static const struct ethernet_api api_funcs = { .set_config = eth_nxp_enet_qos_set_config, }; -#define NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \ - BUILD_ASSERT(NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(n)) || \ - DT_INST_PROP(n, zephyr_random_mac_address), \ - "MAC address not specified on ENET QOS DT node"); - -#define NXP_ENET_QOS_CONNECT_IRQS(node_id, prop, idx) \ - do { \ - IRQ_CONNECT(DT_IRQN_BY_IDX(node_id, idx), \ - DT_IRQ_BY_IDX(node_id, idx, priority), \ - eth_nxp_enet_qos_mac_isr, \ - DEVICE_DT_GET(node_id), \ - 0); \ - irq_enable(DT_IRQN_BY_IDX(node_id, idx)); \ +#define NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \ + BUILD_ASSERT(NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(n)) || \ + DT_INST_PROP(n, zephyr_random_mac_address) || \ + DT_INST_PROP(n, nxp_unique_mac), \ + "MAC address not specified on ENET QOS DT node"); + +#define NXP_ENET_QOS_MAC_ADDR_SOURCE(n) \ + COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(n), local_mac_address), \ + (NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL), \ + (COND_CODE_1(DT_INST_PROP(n, zephyr_random_mac_address), \ + (NXP_ENET_QOS_MAC_ADDR_SOURCE_RANDOM), \ + (COND_CODE_1(DT_INST_PROP(n, nxp_unique_mac), \ + (NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE), \ + (NXP_ENET_QOS_MAC_ADDR_SOURCE_INVALID)))))) + +#define NXP_ENET_QOS_CONNECT_IRQS(node_id, prop, idx) \ + do { \ + IRQ_CONNECT(DT_IRQN_BY_IDX(node_id, idx), DT_IRQ_BY_IDX(node_id, idx, priority), \ + eth_nxp_enet_qos_mac_isr, DEVICE_DT_GET(node_id), 0); \ + irq_enable(DT_IRQN_BY_IDX(node_id, idx)); \ } while (false); -#define NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \ - static void nxp_enet_qos_##n##_irq_config_func(void) \ - { \ - DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), \ - interrupt_names, \ - NXP_ENET_QOS_CONNECT_IRQS) \ +#define NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \ + static void nxp_enet_qos_##n##_irq_config_func(void) \ + { \ + DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), interrupt_names, NXP_ENET_QOS_CONNECT_IRQS) \ } - -#define NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n) \ - static const struct nxp_enet_qos_mac_config enet_qos_##n##_mac_config = { \ - .enet_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \ - .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \ - .base = (enet_qos_t *)DT_REG_ADDR(DT_INST_PARENT(n)), \ - .hw_info = { \ - .max_frame_len = ENET_QOS_MAX_NORMAL_FRAME_LEN, \ - }, \ - .irq_config_func = nxp_enet_qos_##n##_irq_config_func, \ - .random_mac = DT_INST_PROP(n, zephyr_random_mac_address), \ - }; \ - \ - static struct nxp_enet_qos_mac_data enet_qos_##n##_mac_data = \ - { \ - .mac_addr.addr = DT_INST_PROP_OR(n, local_mac_address, {0}), \ +#define NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n) \ + static const struct nxp_enet_qos_mac_config enet_qos_##n##_mac_config = { \ + .enet_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \ + .base = (enet_qos_t *)DT_REG_ADDR(DT_INST_PARENT(n)), \ + .hw_info = \ + { \ + .max_frame_len = ENET_QOS_MAX_NORMAL_FRAME_LEN, \ + }, \ + .irq_config_func = nxp_enet_qos_##n##_irq_config_func, \ + .mac_addr_source = NXP_ENET_QOS_MAC_ADDR_SOURCE(n), \ + }; \ + static struct nxp_enet_qos_mac_data enet_qos_##n##_mac_data = { \ + .mac_addr.addr = DT_INST_PROP_OR(n, local_mac_address, {0}), \ }; -#define NXP_ENET_QOS_DRIVER_INIT(n) \ - NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \ - NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \ +#define NXP_ENET_QOS_DRIVER_INIT(n) \ + NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \ + NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \ NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n) DT_INST_FOREACH_STATUS_OKAY(NXP_ENET_QOS_DRIVER_INIT) -#define NXP_ENET_QOS_MAC_DEVICE_DEFINE(n) \ - ETH_NET_DEVICE_DT_INST_DEFINE(n, eth_nxp_enet_qos_mac_init, NULL, \ - &enet_qos_##n##_mac_data, &enet_qos_##n##_mac_config, \ - CONFIG_ETH_INIT_PRIORITY, &api_funcs, NET_ETH_MTU); +#define NXP_ENET_QOS_MAC_DEVICE_DEFINE(n) \ + ETH_NET_DEVICE_DT_INST_DEFINE(n, eth_nxp_enet_qos_mac_init, NULL, \ + &enet_qos_##n##_mac_data, &enet_qos_##n##_mac_config, \ + CONFIG_ETH_INIT_PRIORITY, &api_funcs, NET_ETH_MTU); DT_INST_FOREACH_STATUS_OKAY(NXP_ENET_QOS_MAC_DEVICE_DEFINE) diff --git a/drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h b/drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h index e1dcadc6fec2b..5d2409628142f 100644 --- a/drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h +++ b/drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h @@ -85,13 +85,20 @@ struct nxp_enet_qos_hw_info { uint16_t max_frame_len; }; +enum mac_address_source { + NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL, + NXP_ENET_QOS_MAC_ADDR_SOURCE_RANDOM, + NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE, + NXP_ENET_QOS_MAC_ADDR_SOURCE_INVALID, +}; + struct nxp_enet_qos_mac_config { const struct device *enet_dev; const struct device *phy_dev; enet_qos_t *base; struct nxp_enet_qos_hw_info hw_info; void (*irq_config_func)(void); - bool random_mac; + enum mac_address_source mac_addr_source; }; struct nxp_enet_qos_tx_data { diff --git a/drivers/ethernet/eth_renesas_ra.c b/drivers/ethernet/eth_renesas_ra.c index 9ce7d41a7ab6f..d17d0cbf78e93 100644 --- a/drivers/ethernet/eth_renesas_ra.c +++ b/drivers/ethernet/eth_renesas_ra.c @@ -35,6 +35,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define ETHER_TOTAL_BUF_NUM (CONFIG_ETH_RENESAS_TX_BUF_NUM + CONFIG_ETH_RENESAS_RX_BUF_NUM) #define ETHER_EE_RECEIVE_EVENT_MASK (0x01070000) +BUILD_ASSERT(DT_INST_ENUM_IDX(0, phy_connection_type) <= 1, "Invalid PHY connection setting"); + void ether_eint_isr(void); void renesas_ra_eth_callback(ether_callback_args_t *p_args); static void renesas_ra_eth_buffer_init(const struct device *dev); @@ -232,7 +234,6 @@ static void renesas_ra_eth_initialize(struct net_if *iface) const struct device *dev = net_if_get_device(iface); struct renesas_ra_eth_context *ctx = dev->data; const struct renesas_ra_eth_config *cfg = dev->config; - const char *phy_connection_type = DT_INST_PROP_OR(0, phy_connection_type, "rmii"); LOG_DBG("eth_initialize"); @@ -244,15 +245,6 @@ static void renesas_ra_eth_initialize(struct net_if *iface) ethernet_init(iface); - R_PMISC->PFENET = (uint8_t)(0x0 << R_PMISC_PFENET_PHYMODE0_Pos); - - if (strstr(phy_connection_type, "mii") != NULL) { - /* Configure pins for MII or RMII. Set PHYMODE0 if MII is selected. */ - R_PMISC->PFENET = (uint8_t)(0x1 << R_PMISC_PFENET_PHYMODE0_Pos); - } else { - LOG_ERR("Failed to init ether - phy-connection-type not support"); - } - err = R_ETHER_Open(&ctx->ctrl, cfg->p_cfg); if (err != FSP_SUCCESS) { @@ -385,6 +377,20 @@ int renesas_ra_eth_init(const struct device *dev) { struct renesas_ra_eth_context *ctx = dev->data; + switch (DT_INST_ENUM_IDX(0, phy_connection_type)) { + case 0: /* mii */ + R_PMISC->PFENET = (uint8_t)(0x1 << R_PMISC_PFENET_PHYMODE0_Pos); + break; + case 1: /* rmii */ + R_PMISC->PFENET = (uint8_t)(0x0 << R_PMISC_PFENET_PHYMODE0_Pos); + break; + default: + /* Build assert at top of file should catch this case */ + LOG_ERR("Failed to init Ethernet driver - phy-connection-type not support"); + + return -EINVAL; + } + R_ICU->IELSR[DT_INST_IRQN(0)] = ELC_EVENT_EDMAC_EINT(0); IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), renesas_ra_eth_isr, diff --git a/drivers/ethernet/eth_sam_gmac.c b/drivers/ethernet/eth_sam_gmac.c index e3748a8610832..0c2740095c9bc 100644 --- a/drivers/ethernet/eth_sam_gmac.c +++ b/drivers/ethernet/eth_sam_gmac.c @@ -403,7 +403,7 @@ static inline void eth_sam_gmac_init_qav(Gmac *gmac) /* * Reset ring buffer */ -static void ring_buf_reset(struct ring_buf *rb) +static void ring_buffer_reset(struct ring_buffer *rb) { rb->head = 0U; rb->tail = 0U; @@ -412,7 +412,7 @@ static void ring_buf_reset(struct ring_buf *rb) /* * Get one 32 bit item from the ring buffer */ -static uint32_t ring_buf_get(struct ring_buf *rb) +static uint32_t ring_buffer_get(struct ring_buffer *rb) { uint32_t val; @@ -428,7 +428,7 @@ static uint32_t ring_buf_get(struct ring_buf *rb) /* * Put one 32 bit item into the ring buffer */ -static void ring_buf_put(struct ring_buf *rb, uint32_t val) +static void ring_buffer_put(struct ring_buffer *rb, uint32_t val) { rb->buf[rb->head] = val; MODULO_INC(rb->head, rb->len); @@ -528,9 +528,9 @@ static void tx_descriptors_init(Gmac *gmac, struct gmac_queue *queue) #if GMAC_MULTIPLE_TX_PACKETS == 1 /* Reset TX frame list */ - ring_buf_reset(&queue->tx_frag_list); + ring_buffer_reset(&queue->tx_frag_list); #if defined(CONFIG_PTP_CLOCK_SAM_GMAC) - ring_buf_reset(&queue->tx_frames); + ring_buffer_reset(&queue->tx_frames); #endif #endif } @@ -721,14 +721,14 @@ static void tx_completed(Gmac *gmac, struct gmac_queue *queue) k_sem_give(&queue->tx_desc_sem); /* Release net buffer to the buffer pool */ - frag = UINT_TO_POINTER(ring_buf_get(&queue->tx_frag_list)); + frag = UINT_TO_POINTER(ring_buffer_get(&queue->tx_frag_list)); net_pkt_frag_unref(frag); LOG_DBG("Dropping frag %p", frag); if (tx_desc->w1 & GMAC_TXW1_LASTBUFFER) { #if defined(CONFIG_PTP_CLOCK_SAM_GMAC) /* Release net packet to the packet pool */ - pkt = UINT_TO_POINTER(ring_buf_get(&queue->tx_frames)); + pkt = UINT_TO_POINTER(ring_buffer_get(&queue->tx_frames)); #if defined(CONFIG_NET_GPTP) hdr = check_gptp_msg(get_iface(dev_data), @@ -756,10 +756,10 @@ static void tx_error_handler(Gmac *gmac, struct gmac_queue *queue) { #if GMAC_MULTIPLE_TX_PACKETS == 1 struct net_buf *frag; - struct ring_buf *tx_frag_list = &queue->tx_frag_list; + struct ring_buffer *tx_frag_list = &queue->tx_frag_list; #if defined(CONFIG_PTP_CLOCK_SAM_GMAC) struct net_pkt *pkt; - struct ring_buf *tx_frames = &queue->tx_frames; + struct ring_buffer *tx_frames = &queue->tx_frames; #endif #endif @@ -1495,7 +1495,7 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt) "tx_desc_list overflow"); /* Account for a sent frag */ - ring_buf_put(&queue->tx_frag_list, POINTER_TO_UINT(frag)); + ring_buffer_put(&queue->tx_frag_list, POINTER_TO_UINT(frag)); /* frag is internally queued, so it requires to hold a reference */ net_pkt_frag_ref(frag); @@ -1533,7 +1533,7 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt) #if GMAC_MULTIPLE_TX_PACKETS == 1 #if defined(CONFIG_PTP_CLOCK_SAM_GMAC) /* Account for a sent frame */ - ring_buf_put(&queue->tx_frames, POINTER_TO_UINT(pkt)); + ring_buffer_put(&queue->tx_frames, POINTER_TO_UINT(pkt)); /* pkt is internally queued, so it requires to hold a reference */ net_pkt_ref(pkt); diff --git a/drivers/ethernet/eth_sam_gmac_priv.h b/drivers/ethernet/eth_sam_gmac_priv.h index 8fd5a2b257b57..c2a94a1c3f11e 100644 --- a/drivers/ethernet/eth_sam_gmac_priv.h +++ b/drivers/ethernet/eth_sam_gmac_priv.h @@ -208,7 +208,7 @@ enum queue_idx { #endif /** Minimal ring buffer implementation */ -struct ring_buf { +struct ring_buffer { uint32_t *buf; uint16_t len; uint16_t head; @@ -242,9 +242,9 @@ struct gmac_queue { struct net_buf **rx_frag_list; #if GMAC_MULTIPLE_TX_PACKETS == 1 - struct ring_buf tx_frag_list; + struct ring_buffer tx_frag_list; #if defined(CONFIG_PTP_CLOCK_SAM_GMAC) - struct ring_buf tx_frames; + struct ring_buffer tx_frames; #endif #endif diff --git a/drivers/ethernet/eth_sensry_sy1xx_mac.c b/drivers/ethernet/eth_sensry_sy1xx_mac.c new file mode 100644 index 0000000000000..6a885cbc91341 --- /dev/null +++ b/drivers/ethernet/eth_sensry_sy1xx_mac.c @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2025 sensry.io + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sensry_sy1xx_mac + +#include +LOG_MODULE_REGISTER(sy1xx_mac, CONFIG_ETHERNET_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include "eth.h" + +/* MAC register offsets */ +#define SY1XX_MAC_VERSION_REG 0x0000 +#define SY1XX_MAC_ADDRESS_LOW_REG 0x0004 +#define SY1XX_MAC_ADDRESS_HIGH_REG 0x0008 +#define SY1XX_MAC_CTRL_REG 0x000c + +/* MAC control register bit offsets */ +#define SY1XX_MAC_CTRL_RESET_OFFS (0) +#define SY1XX_MAC_CTRL_RX_EN_OFFS (1) +#define SY1XX_MAC_CTRL_TX_EN_OFFS (2) +#define SY1XX_MAC_CTRL_GMII_OFFS (3) +#define SY1XX_MAC_CTRL_CLK_DIV_OFFS (8) +#define SY1XX_MAC_CTRL_CLK_SEL_OFFS (10) + +/* MAC clock sources */ +#define SY1XX_MAC_CTRL_CLK_SEL_REF_CLK 0 +#define SY1XX_MAC_CTRL_CLK_SEL_MII_CLK 1 + +/* Clock divider options */ +#define SY1XX_MAC_CTRL_CLK_DIV_1 0x0 +#define SY1XX_MAC_CTRL_CLK_DIV_5 0x1 +#define SY1XX_MAC_CTRL_CLK_DIV_10 0x2 +#define SY1XX_MAC_CTRL_CLK_DIV_50 0x3 + +/* Clock divider mask */ +#define SY1XX_MAC_CTRL_CLK_DIV_MASK (0x3) + +#define MAX_MAC_PACKET_LEN 1600 +#define MAX_TX_RETRIES 5 +#define RECEIVE_GRACE_TIME_MSEC 1 + +#define SY1XX_ETH_STACK_SIZE 4096 +#define SY1XX_ETH_THREAD_PRIORITY K_PRIO_PREEMPT(0) + +struct sy1xx_mac_dev_config { + /* address of controller configuration registers */ + uint32_t ctrl_addr; + /* address of udma for data transfers */ + uint32_t base_addr; + /* optional - enable promiscuous mode */ + bool promiscuous_mode; + /* optional - device tree mac */ + bool use_local_mac_address; + uint8_t local_mac_address[6]; + /* optional - random mac */ + bool use_zephyr_random_mac; + + /* phy config */ + const struct device *phy_dev; + + /* pinctrl for rgmii pins */ + const struct pinctrl_dev_config *pcfg; +}; + +struct sy1xx_mac_dma_buffers { + uint8_t tx[MAX_MAC_PACKET_LEN]; + uint8_t rx[MAX_MAC_PACKET_LEN]; +}; + +struct sy1xx_mac_dev_data { + struct k_mutex mutex; + + /* current state of link and mac address */ + bool link_is_up; + enum phy_link_speed link_speed; + + uint8_t mac_addr[6]; + + /* intermediate, linear buffers that can hold a received or transmit msg */ + struct { + uint8_t tx[MAX_MAC_PACKET_LEN]; + uint16_t tx_len; + + uint8_t rx[MAX_MAC_PACKET_LEN]; + uint16_t rx_len; + } temp; + + /* buffers used for dma transfer, cannot be accessed while transfer active */ + struct sy1xx_mac_dma_buffers *dma_buffers; + + struct k_thread rx_data_thread; + + K_KERNEL_STACK_MEMBER(rx_data_thread_stack, SY1XX_ETH_STACK_SIZE); + + struct net_if *iface; +}; + +/* prototypes */ +static int sy1xx_mac_set_mac_addr(const struct device *dev, uint8_t *mac_addr); +static int sy1xx_mac_set_promiscuous_mode(const struct device *dev, bool promiscuous_mode); +static int sy1xx_mac_set_config(const struct device *dev, enum ethernet_config_type type, + const struct ethernet_config *config); +static void sy1xx_mac_rx_thread_entry(void *p1, void *p2, void *p3); + +static int sy1xx_mac_initialize(const struct device *dev) +{ + struct sy1xx_mac_dev_config *cfg = (struct sy1xx_mac_dev_config *)dev->config; + struct sy1xx_mac_dev_data *data = (struct sy1xx_mac_dev_data *)dev->data; + int ret; + + data->link_is_up = false; + data->link_speed = -1; + + k_mutex_init(&data->mutex); + + /* PAD config */ + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret) { + LOG_ERR("failed to configure pins"); + return ret; + } + + /* create the receiver thread */ + k_thread_create(&data->rx_data_thread, (k_thread_stack_t *)data->rx_data_thread_stack, + SY1XX_ETH_STACK_SIZE, sy1xx_mac_rx_thread_entry, (void *)dev, NULL, NULL, + SY1XX_ETH_THREAD_PRIORITY, 0, K_NO_WAIT); + + /* start suspended and resume once we have link */ + k_thread_suspend(&data->rx_data_thread); + + k_thread_name_set(&data->rx_data_thread, "mac-rx-thread"); + + return 0; +} + +static int sy1xx_mac_set_promiscuous_mode(const struct device *dev, bool promiscuous_mode) +{ + struct sy1xx_mac_dev_config *cfg = (struct sy1xx_mac_dev_config *)dev->config; + uint32_t prom; + + /* set promiscuous mode */ + prom = sys_read32(cfg->ctrl_addr + SY1XX_MAC_ADDRESS_HIGH_REG); + if (promiscuous_mode) { + prom &= ~BIT(16); + } else { + prom |= BIT(16); + } + sys_write32(prom, cfg->ctrl_addr + SY1XX_MAC_ADDRESS_HIGH_REG); + + return 0; +} + +static int sy1xx_mac_set_mac_addr(const struct device *dev, uint8_t *mac_addr) +{ + struct sy1xx_mac_dev_config *cfg = (struct sy1xx_mac_dev_config *)dev->config; + struct sy1xx_mac_dev_data *data = (struct sy1xx_mac_dev_data *)dev->data; + int ret; + uint32_t v_low, v_high; + + LOG_INF("%s set link address %02x:%02x:%02x:%02x:%02x:%02x", dev->name, mac_addr[0], + mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + + /* update mac in controller */ + v_low = sys_get_le32(&mac_addr[0]); + sys_write32(v_low, cfg->ctrl_addr + SY1XX_MAC_ADDRESS_LOW_REG); + + v_high = sys_read32(cfg->ctrl_addr + SY1XX_MAC_ADDRESS_HIGH_REG); + v_high |= (v_high & 0xffff0000) | sys_get_le16(&mac_addr[4]); + sys_write32(v_high, cfg->ctrl_addr + SY1XX_MAC_ADDRESS_HIGH_REG); + + memcpy(data->mac_addr, mac_addr, 6); + + /* Register Ethernet MAC Address with the upper layer */ + ret = net_if_set_link_addr(data->iface, data->mac_addr, sizeof(data->mac_addr), + NET_LINK_ETHERNET); + if (ret) { + LOG_ERR("%s failed to set link address", dev->name); + return ret; + } + + return 0; +} + +static int sy1xx_mac_start(const struct device *dev) +{ + struct sy1xx_mac_dev_config *cfg = (struct sy1xx_mac_dev_config *)dev->config; + struct sy1xx_mac_dev_data *data = (struct sy1xx_mac_dev_data *)dev->data; + uint8_t rand_mac_addr[6]; + + extern void sy1xx_udma_disable_clock(sy1xx_udma_module_t module, uint32_t instance); + + /* UDMA clock reset and enable */ + sy1xx_udma_enable_clock(SY1XX_UDMA_MODULE_MAC, 0); + sy1xx_udma_disable_clock(SY1XX_UDMA_MODULE_MAC, 0); + sy1xx_udma_enable_clock(SY1XX_UDMA_MODULE_MAC, 0); + + /* reset mac controller */ + sys_write32(0x0001, cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); + sys_write32(0x0000, cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); + + /* preset mac addr */ + if (cfg->use_local_mac_address) { + /* prio 0 -- from device tree */ + sy1xx_mac_set_mac_addr(dev, cfg->local_mac_address); + } else if (cfg->use_zephyr_random_mac) { + /* prio 1 -- generate random, if set in device tree */ + sys_rand_get(&rand_mac_addr, 6); + /* Set MAC address locally administered, unicast (LAA) */ + rand_mac_addr[0] |= 0x02; + sy1xx_mac_set_mac_addr(dev, rand_mac_addr); + } else { + /* no preset mac address available */ + } + + sy1xx_mac_set_promiscuous_mode(dev, cfg->promiscuous_mode); + + k_thread_resume(&data->rx_data_thread); + + return 0; +} + +static int sy1xx_mac_stop(const struct device *dev) +{ + struct sy1xx_mac_dev_data *data = (struct sy1xx_mac_dev_data *)dev->data; + + k_thread_suspend(&data->rx_data_thread); + return 0; +} + +static void phy_link_state_changed(const struct device *pdev, struct phy_link_state *state, + void *user_data) +{ + const struct device *dev = (const struct device *)user_data; + struct sy1xx_mac_dev_data *const data = dev->data; + const struct sy1xx_mac_dev_config *const cfg = dev->config; + bool is_up; + enum phy_link_speed speed; + uint32_t v, en; + + is_up = state->is_up; + speed = state->speed; + + if (speed != data->link_speed) { + data->link_speed = speed; + + /* configure mac, based on provided link information 1Gbs/100MBit/... */ + v = sys_read32(cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); + + /* mask out relevant bits */ + v &= ~(BIT(SY1XX_MAC_CTRL_GMII_OFFS) | BIT(SY1XX_MAC_CTRL_CLK_SEL_OFFS) | + (SY1XX_MAC_CTRL_CLK_DIV_MASK << SY1XX_MAC_CTRL_CLK_DIV_OFFS)); + + switch (speed) { + case LINK_FULL_10BASE_T: + LOG_INF("link speed FULL_10BASE_T"); + /* 2.5MHz, MAC is clock source */ + v |= (SY1XX_MAC_CTRL_CLK_SEL_MII_CLK << SY1XX_MAC_CTRL_CLK_SEL_OFFS) | + (SY1XX_MAC_CTRL_CLK_DIV_10 << SY1XX_MAC_CTRL_CLK_DIV_OFFS); + break; + case LINK_FULL_100BASE_T: + LOG_INF("link speed FULL_100BASE_T"); + /* 25MHz, MAC is clock source */ + v |= (SY1XX_MAC_CTRL_CLK_SEL_MII_CLK << SY1XX_MAC_CTRL_CLK_SEL_OFFS) | + (SY1XX_MAC_CTRL_CLK_DIV_1 << SY1XX_MAC_CTRL_CLK_DIV_OFFS); + break; + case LINK_FULL_1000BASE_T: + LOG_INF("link speed FULL_1000BASE_T"); + /* 125MHz, Phy is clock source */ + v |= BIT(SY1XX_MAC_CTRL_GMII_OFFS) | + (SY1XX_MAC_CTRL_CLK_SEL_REF_CLK << SY1XX_MAC_CTRL_CLK_SEL_OFFS) | + (SY1XX_MAC_CTRL_CLK_DIV_1 << SY1XX_MAC_CTRL_CLK_DIV_OFFS); + break; + default: + LOG_ERR("invalid link speed"); + return; + } + sys_write32(v, cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); + } + + if (is_up != data->link_is_up) { + data->link_is_up = is_up; + + if (is_up) { + LOG_DBG("Link up"); + + /* enable mac controller */ + en = sys_read32(cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); + en |= BIT(SY1XX_MAC_CTRL_TX_EN_OFFS) | BIT(SY1XX_MAC_CTRL_RX_EN_OFFS); + sys_write32(en, cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); + + /* Announce link up status */ + net_eth_carrier_on(data->iface); + + } else { + LOG_DBG("Link down"); + + /* disable mac controller */ + en = sys_read32(cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); + en &= ~(BIT(SY1XX_MAC_CTRL_TX_EN_OFFS) | BIT(SY1XX_MAC_CTRL_RX_EN_OFFS)); + sys_write32(en, cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); + + /* Announce link down status */ + net_eth_carrier_off(data->iface); + } + } +} + +static void sy1xx_mac_iface_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct sy1xx_mac_dev_config *cfg = (struct sy1xx_mac_dev_config *)dev->config; + struct sy1xx_mac_dev_data *const data = dev->data; + + LOG_INF("Interface init %s (%.8x)", net_if_get_device(iface)->name, iface); + + data->iface = iface; + + ethernet_init(iface); + + if (device_is_ready(cfg->phy_dev)) { + phy_link_callback_set(cfg->phy_dev, &phy_link_state_changed, (void *)dev); + } else { + LOG_ERR("PHY device not ready"); + } + + /* Do not start the interface until PHY link is up */ + if (!(data->link_is_up)) { + LOG_INF("found PHY link down"); + net_if_carrier_off(iface); + } +} + +static enum ethernet_hw_caps sy1xx_mac_get_caps(const struct device *dev) +{ + enum ethernet_hw_caps supported = 0; + + /* basic implemented features */ + supported |= ETHERNET_PROMISC_MODE; + supported |= ETHERNET_LINK_1000BASE_T; + supported |= ETHERNET_PROMISC_MODE; + + return supported; +} + +static int sy1xx_mac_get_config(const struct device *dev, enum ethernet_config_type type, + struct ethernet_config *config) +{ + struct sy1xx_mac_dev_data *data = (struct sy1xx_mac_dev_data *)dev->data; + + /* we currently support only 1000mbit/s full duplex */ + switch (type) { + case ETHERNET_CONFIG_TYPE_LINK: + config->l.link_1000bt = true; + break; + + case ETHERNET_CONFIG_TYPE_DUPLEX: + config->full_duplex = true; + break; + + case ETHERNET_CONFIG_TYPE_MAC_ADDRESS: + memcpy(config->mac_address.addr, data->mac_addr, 6); + break; + default: + return -ENOTSUP; + } + return 0; +} + +static int sy1xx_mac_set_config(const struct device *dev, enum ethernet_config_type type, + const struct ethernet_config *config) +{ + int ret = 0; + + switch (type) { + + case ETHERNET_CONFIG_TYPE_PROMISC_MODE: + ret = sy1xx_mac_set_promiscuous_mode(dev, config->promisc_mode); + break; + + case ETHERNET_CONFIG_TYPE_MAC_ADDRESS: + ret = sy1xx_mac_set_mac_addr(dev, (uint8_t *)&(config->mac_address.addr)); + break; + default: + return -ENOTSUP; + } + return ret; +} + +static const struct device *sy1xx_mac_get_phy(const struct device *dev) +{ + const struct sy1xx_mac_dev_config *const cfg = dev->config; + + return cfg->phy_dev; +} + +/* + * rx ready status of eth is different to any other rx udma, + * so we implement here + */ +static int32_t sy1xx_mac_udma_is_finished_rx(uint32_t base) +{ + uint32_t isBusy = SY1XX_UDMA_READ_REG(base, SY1XX_UDMA_CFG_REG + 0x00) & (BIT(17)); + + return isBusy ? 0 : 1; +} + +static int sy1xx_mac_low_level_send(const struct device *dev, uint8_t *tx, uint16_t len) +{ + struct sy1xx_mac_dev_config *cfg = (struct sy1xx_mac_dev_config *)dev->config; + struct sy1xx_mac_dev_data *const data = dev->data; + + if (len == 0) { + return -EINVAL; + } + + if (len > MAX_MAC_PACKET_LEN) { + return -EINVAL; + } + + if (!SY1XX_UDMA_IS_FINISHED_TX(cfg->base_addr)) { + return -EBUSY; + } + + /* udma is ready, double check if last transmission was successful */ + if (SY1XX_UDMA_GET_REMAINING_TX(cfg->base_addr)) { + SY1XX_UDMA_CANCEL_TX(cfg->base_addr); + LOG_ERR("tx - last transmission failed"); + return -EINVAL; + } + + /* copy data to dma buffer */ + for (uint32_t i = 0; i < len; i++) { + data->dma_buffers->tx[i] = tx[i]; + } + + /* start dma transfer */ + SY1XX_UDMA_START_TX(cfg->base_addr, (uint32_t)data->dma_buffers->tx, len, 0); + + return 0; +} + +static int sy1xx_mac_low_level_receive(const struct device *dev, uint8_t *rx, uint16_t *len) +{ + struct sy1xx_mac_dev_config *cfg = (struct sy1xx_mac_dev_config *)dev->config; + struct sy1xx_mac_dev_data *const data = dev->data; + int ret; + uint32_t bytes_transferred; + + *len = 0; + + /* rx udma still busy */ + if (0 == sy1xx_mac_udma_is_finished_rx(cfg->base_addr)) { + return -EBUSY; + } + + /* rx udma is ready */ + bytes_transferred = SY1XX_UDMA_READ_REG(cfg->base_addr, SY1XX_UDMA_CFG_REG) & 0x0000ffff; + if (bytes_transferred) { + /* message received, copy data */ + memcpy(rx, data->dma_buffers->rx, bytes_transferred); + *len = bytes_transferred; + ret = 0; + } else { + /* no data, should never happen */ + SY1XX_UDMA_CANCEL_RX(cfg->base_addr); + ret = -EINVAL; + } + + /* start new reception */ + SY1XX_UDMA_START_RX(cfg->base_addr, (uint32_t)data->dma_buffers->rx, MAX_MAC_PACKET_LEN, 0); + + return ret; +} + +static int sy1xx_mac_send(const struct device *dev, struct net_pkt *pkt) +{ + struct sy1xx_mac_dev_data *const data = dev->data; + int ret; + uint32_t retries_left; + struct net_buf *frag; + + k_mutex_lock(&data->mutex, K_FOREVER); + + /* push all fragments of the packet into one linear buffer */ + frag = pkt->buffer; + data->temp.tx_len = 0; + do { + /* copy fragment to buffer */ + for (uint32_t i = 0; i < frag->len; i++) { + if (data->temp.tx_len < MAX_MAC_PACKET_LEN) { + data->temp.tx[data->temp.tx_len++] = frag->data[i]; + } else { + LOG_ERR("tx buffer overflow"); + k_mutex_unlock(&data->mutex); + return -ENOMEM; + } + } + + frag = frag->frags; + } while (frag); + + /* hand over linear tx frame to udma */ + retries_left = MAX_TX_RETRIES; + while (retries_left) { + ret = sy1xx_mac_low_level_send(dev, data->temp.tx, data->temp.tx_len); + if (ret == 0) { + break; + } + if (ret != -EBUSY) { + LOG_ERR("tx error"); + k_mutex_unlock(&data->mutex); + return ret; + } + k_sleep(K_MSEC(1)); + retries_left--; + }; + + k_mutex_unlock(&data->mutex); + return ret; +} + +static int sy1xx_mac_receive_data(const struct device *dev, uint8_t *rx, uint16_t len) +{ + struct sy1xx_mac_dev_data *const data = dev->data; + struct net_pkt *rx_pkt; + int ret; + + rx_pkt = net_pkt_alloc_with_buffer(data->iface, len, AF_UNSPEC, 0, K_FOREVER); + if (rx_pkt == NULL) { + LOG_ERR("rx packet allocation failed"); + return -EINVAL; + } + + /* add data to the net_pkt */ + if (net_pkt_write(rx_pkt, rx, len)) { + LOG_ERR("failed to write data to net_pkt"); + net_pkt_unref(rx_pkt); + return -EINVAL; + } + + /* register new packet in stack */ + ret = net_recv_data(data->iface, rx_pkt); + if (ret) { + LOG_ERR("rx packet registration failed"); + return ret; + } + + return 0; +} + +static void sy1xx_mac_rx_thread_entry(void *p1, void *p2, void *p3) +{ + const struct device *dev = p1; + struct sy1xx_mac_dev_data *const data = dev->data; + int ret; + + while (true) { + ret = sy1xx_mac_low_level_receive(dev, data->temp.rx, &data->temp.rx_len); + if (ret == 0) { + /* register a new received frame */ + if (data->temp.rx_len) { + sy1xx_mac_receive_data(dev, data->temp.rx, data->temp.rx_len); + } + } else { + /* + * rx thread is running at higher prio, in case of error or busy, + * we could lock up the system partially. + */ + + /* we wait and try again */ + k_sleep(K_MSEC(RECEIVE_GRACE_TIME_MSEC)); + } + } +} + +const struct ethernet_api sy1xx_mac_driver_api = { + .start = sy1xx_mac_start, + .stop = sy1xx_mac_stop, + .iface_api.init = sy1xx_mac_iface_init, + .get_capabilities = sy1xx_mac_get_caps, + .get_config = sy1xx_mac_get_config, + .set_config = sy1xx_mac_set_config, + .send = sy1xx_mac_send, + .get_phy = sy1xx_mac_get_phy, +}; + +#define SY1XX_MAC_INIT(n) \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static const struct sy1xx_mac_dev_config sy1xx_mac_dev_config_##n = { \ + .ctrl_addr = DT_INST_REG_ADDR_BY_NAME(n, ctrl), \ + .base_addr = DT_INST_REG_ADDR_BY_NAME(n, data), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .promiscuous_mode = DT_INST_PROP_OR(n, promiscuous_mode, false), \ + .local_mac_address = DT_INST_PROP_OR(n, local_mac_address, {0}), \ + .use_local_mac_address = DT_INST_NODE_HAS_PROP(n, local_mac_address), \ + .use_zephyr_random_mac = DT_INST_NODE_HAS_PROP(n, zephyr_random_mac_address), \ + .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(0, phy_handle))}; \ + \ + static struct sy1xx_mac_dma_buffers __attribute__((section(".udma_access"))) \ + __aligned(4) sy1xx_mac_dma_buffers_##n; \ + \ + static struct sy1xx_mac_dev_data sy1xx_mac_dev_data##n = { \ + .dma_buffers = &sy1xx_mac_dma_buffers_##n, \ + }; \ + \ + ETH_NET_DEVICE_DT_INST_DEFINE(n, &sy1xx_mac_initialize, NULL, &sy1xx_mac_dev_data##n, \ + &sy1xx_mac_dev_config_##n, CONFIG_ETH_INIT_PRIORITY, \ + &sy1xx_mac_driver_api, NET_ETH_MTU); + +DT_INST_FOREACH_STATUS_OKAY(SY1XX_MAC_INIT) diff --git a/drivers/ethernet/eth_xlnx_gem.c b/drivers/ethernet/eth_xlnx_gem.c index 0c5d09efbb0f7..499781c78797e 100644 --- a/drivers/ethernet/eth_xlnx_gem.c +++ b/drivers/ethernet/eth_xlnx_gem.c @@ -45,6 +45,9 @@ static int eth_xlnx_gem_start_device(const struct device *dev); static int eth_xlnx_gem_stop_device(const struct device *dev); static enum ethernet_hw_caps eth_xlnx_gem_get_capabilities(const struct device *dev); +static int eth_xlnx_gem_get_config(const struct device *dev, + enum ethernet_config_type type, + struct ethernet_config *config); #if defined(CONFIG_NET_STATISTICS_ETHERNET) static struct net_stats_eth *eth_xlnx_gem_stats(const struct device *dev); #endif @@ -69,6 +72,7 @@ static const struct ethernet_api eth_xlnx_gem_apis = { .send = eth_xlnx_gem_send, .start = eth_xlnx_gem_start_device, .stop = eth_xlnx_gem_stop_device, + .get_config = eth_xlnx_gem_get_config, #if defined(CONFIG_NET_STATISTICS_ETHERNET) .get_stats = eth_xlnx_gem_stats, #endif @@ -654,6 +658,58 @@ static enum ethernet_hw_caps eth_xlnx_gem_get_capabilities( return caps; } +/** + * @brief GEM hardware configuration data request function + * Returns hardware configuration details of the specified device + * instance. Multiple hardware configuration items can be queried + * depending on the type parameter. The range of configuration items + * that can be queried is specified by the Ethernet subsystem. + * The queried configuration data is returned via a struct which can + * accommodate for all supported configuration items, to which the + * caller must provide a valid pointer. + * Currently only supports querying the RX and TX hardware checksum + * capabilities of the specified device instance. + * + * @param dev Pointer to the device data + * @param type The hardware configuration item to be queried + * @param config Pointer to the struct into which the queried + * configuration data is written. + * @return 0 if the specified configuration item was successfully + * queried, -ENOTSUP if the specified configuration item + * is not supported by this function. + */ +static int eth_xlnx_gem_get_config(const struct device *dev, + enum ethernet_config_type type, + struct ethernet_config *config) +{ + const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config; + + switch (type) { + case ETHERNET_CONFIG_TYPE_RX_CHECKSUM_SUPPORT: + if (dev_conf->enable_rx_chksum_offload) { + config->chksum_support = ETHERNET_CHECKSUM_SUPPORT_IPV4_HEADER | + ETHERNET_CHECKSUM_SUPPORT_IPV6_HEADER | + ETHERNET_CHECKSUM_SUPPORT_TCP | + ETHERNET_CHECKSUM_SUPPORT_UDP; + } else { + config->chksum_support = ETHERNET_CHECKSUM_SUPPORT_NONE; + } + return 0; + case ETHERNET_CONFIG_TYPE_TX_CHECKSUM_SUPPORT: + if (dev_conf->enable_tx_chksum_offload) { + config->chksum_support = ETHERNET_CHECKSUM_SUPPORT_IPV4_HEADER | + ETHERNET_CHECKSUM_SUPPORT_IPV6_HEADER | + ETHERNET_CHECKSUM_SUPPORT_TCP | + ETHERNET_CHECKSUM_SUPPORT_UDP; + } else { + config->chksum_support = ETHERNET_CHECKSUM_SUPPORT_NONE; + } + return 0; + default: + return -ENOTSUP; + }; +} + #ifdef CONFIG_NET_STATISTICS_ETHERNET /** * @brief GEM statistics data request function diff --git a/drivers/ethernet/nxp_enet/eth_nxp_enet.c b/drivers/ethernet/nxp_enet/eth_nxp_enet.c index dd850370f3995..0278f8a5f8eb8 100644 --- a/drivers/ethernet/nxp_enet/eth_nxp_enet.c +++ b/drivers/ethernet/nxp_enet/eth_nxp_enet.c @@ -882,9 +882,6 @@ static const struct ethernet_api api_funcs = { irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \ } while (false); -#define NXP_ENET_DT_PHY_DEV(node_id, phy_phandle, idx) \ - DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, phy_phandle, idx)) - #if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_dtcm)) && \ CONFIG_ETH_NXP_ENET_USE_DTCM_FOR_DMA_BUFFER #define _nxp_enet_dma_desc_section __dtcm_bss_section diff --git a/drivers/ethernet/nxp_imx_netc/CMakeLists.txt b/drivers/ethernet/nxp_imx_netc/CMakeLists.txt new file mode 100644 index 0000000000000..91fbf4d4f1eef --- /dev/null +++ b/drivers/ethernet/nxp_imx_netc/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_ETH_NXP_IMX_NETC) + zephyr_library_sources(eth_nxp_imx_netc.c) + zephyr_library_sources(eth_nxp_imx_netc_psi.c) +endif() + +zephyr_library_sources_ifdef(CONFIG_DSA_NXP_IMX_NETC dsa_nxp_imx_netc.c) diff --git a/drivers/ethernet/nxp_imx_netc/Kconfig b/drivers/ethernet/nxp_imx_netc/Kconfig new file mode 100644 index 0000000000000..0d5629939b0ac --- /dev/null +++ b/drivers/ethernet/nxp_imx_netc/Kconfig @@ -0,0 +1,99 @@ +# Copyright 2024-2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +menuconfig ETH_NXP_IMX_NETC + bool "NXP IMX Ethernet and Network Controller (NETC) driver" + default y + depends on DT_HAS_NXP_IMX_NETC_PSI_ENABLED + select MDIO + select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT + select ETH_DSA_SUPPORT + help + Enable Ethernet and Network Controller (NETC) driver for NXP IMX SoCs. + +if ETH_NXP_IMX_NETC + +config ETH_NXP_IMX_MSGINTR + int "Message Interrupt module select" + default 1 + help + Message Interrupt module select. + +config ETH_NXP_IMX_RX_THREAD_PRIO + int "RX thread priority" + default 2 + help + RX thread priority. RX thread is a cooperative thread. + +config ETH_NXP_IMX_RX_THREAD_STACK_SIZE + int "RX thread stack size" + default 1500 + help + RX thread stack size. + +config ETH_NXP_IMX_RX_BUDGET + int "RX thread budget" + default 128 + range 1 1024 + help + The budget parameter places a limit on the amount of work the driver may + do in the RX thread before yielding the processor, in case there is more + work to do. This is to prevent the RX thread to starve other threads. Each + received frame counts as one unit of work. + +config ETH_NXP_IMX_TX_RING_NUM + int "TX ring number" + default 1 + range 1 1023 + help + TX ring number used. The actual maximum value may varies from platforms. + +config ETH_NXP_IMX_TX_RING_LEN + int "TX ring length" + default 8 + range 8 256 + help + Length of the TX ring. The value must be a multiple of 8. + +config ETH_NXP_IMX_TX_RING_BUF_SIZE + int "TX ring data buffer size" + default 1000 + range 64 1536 + help + Size, in bytes, of the TX data buffer. The size must be big enough to + store one complete Ethernet frame, and be a multiple of 8. + +config ETH_NXP_IMX_RX_RING_NUM + int "RX ring number" + default 1 + range 1 1023 + help + RX ring number used. The actual maximum value may varies from platforms. + +config ETH_NXP_IMX_RX_RING_LEN + int "RX ring length" + default 8 + range 8 256 + help + Length of the RX ring. The value must be a multiple of 8. + +config ETH_NXP_IMX_RX_RING_BUF_SIZE + int "RX ring data buffer size" + default 1518 + range 64 1536 + help + Size, in bytes, of the RX data buffer. The size must be big enough to + store one complete Ethernet frame, and be a multiple of 8. + +endif # ETH_NXP_IMX_NETC + +if NET_DSA + +config DSA_NXP_IMX_NETC + bool "Support for NXP i.MX NETC" + default y + depends on DT_HAS_NXP_NETC_SWITCH_ENABLED + help + Add support for NXP i.MX NETC DSA device driver. + +endif diff --git a/drivers/ethernet/nxp_imx_netc/dsa_nxp_imx_netc.c b/drivers/ethernet/nxp_imx_netc/dsa_nxp_imx_netc.c new file mode 100644 index 0000000000000..a1cda7cc7c16e --- /dev/null +++ b/drivers/ethernet/nxp_imx_netc/dsa_nxp_imx_netc.c @@ -0,0 +1,284 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define LOG_MODULE_NAME dsa_netc + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_ETHERNET_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsl_netc_switch.h" + +#define DT_DRV_COMPAT nxp_netc_switch +#include "nxp_imx_netc.h" + +#define PRV_DATA(ctx) ((struct dsa_netc_data *const)(ctx)->prv_data) + +struct dsa_netc_data { + int port_num; + int port_init_count; + swt_config_t swt_config; + swt_handle_t swt_handle; + const struct device *dev_master; + netc_cmd_bd_t *cmd_bd; +}; + +struct dsa_netc_slave_config { + /** MAC address for each LAN{123.,} ports */ + uint8_t mac_addr[6]; + const struct device *phy_dev; + netc_hw_mii_mode_t phy_mode; + volatile bool pseudo_mac; + const struct pinctrl_dev_config *pincfg; + int port_idx; + const struct device *ethernet_connection; +}; + +int dsa_netc_port_init(const struct device *dev) +{ + const struct dsa_netc_slave_config *cfg = dev->config; + struct dsa_context *ctx = dev->data; + struct dsa_netc_data *prv = PRV_DATA(ctx); + swt_config_t *swt_config = &prv->swt_config; + + status_t result; + int err; + + /* Get default config for whole switch before first port init */ + if (prv->port_init_count == 0) { + SWT_GetDefaultConfig(swt_config); + swt_config->bridgeCfg.dVFCfg.portMembership = 0x0; + } + + prv->port_init_count++; + + if (prv->dev_master == NULL) { + prv->dev_master = cfg->ethernet_connection; + } + + if (cfg->pseudo_mac) { + goto port_init; + } + + err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + return err; + } + +port_init: + /* miiSpeed and miiDuplex will get set correctly when link is up */ + swt_config->ports[cfg->port_idx].ethMac.miiMode = cfg->phy_mode; + + swt_config->bridgeCfg.dVFCfg.portMembership |= (1 << cfg->port_idx); + + swt_config->ports[cfg->port_idx].bridgeCfg.enMacStationMove = true; + + /* Switch init after all ports init */ + if (prv->port_init_count == prv->port_num) { + swt_config->cmdRingUse = 1U; + swt_config->cmdBdrCfg[0].bdBase = prv->cmd_bd; + swt_config->cmdBdrCfg[0].bdLength = 8U; + + result = SWT_Init(&prv->swt_handle, &prv->swt_config); + if (result != kStatus_Success) { + return -EIO; + } + } + + return 0; +} + +static int dsa_netc_sw_write_reg(const struct device *dev, uint16_t reg_addr, uint8_t value) +{ + /* This API is for PHY switch. Not available here. */ + return -ENOTSUP; +} + +static int dsa_netc_sw_read_reg(const struct device *dev, uint16_t reg_addr, uint8_t *value) +{ + /* This API is for PHY switch. Not available here. */ + return -ENOTSUP; +} + +static int dsa_netc_set_mac_table_entry(const struct device *dev, const uint8_t *mac, + uint8_t fw_port, uint16_t tbl_entry_idx, uint16_t flags) +{ + /* TODO: support it */ + return -ENOTSUP; +} + +static int dsa_netc_get_mac_table_entry(const struct device *dev, uint8_t *buf, + uint16_t tbl_entry_idx) +{ + /* TODO: support it */ + return -ENOTSUP; +} + +static void netc_eth_phylink_callback(const struct device *dev, struct phy_link_state *state, + void *user_data) +{ + const struct device *ndev = (struct device *)user_data; + struct dsa_context *context = ndev->data; + struct dsa_netc_data *prv = PRV_DATA(context); + + struct net_if *iface = net_if_lookup_by_dev(ndev); + struct ethernet_context *ctx = net_if_l2_data(iface); + status_t result; + + if (state->is_up) { + LOG_INF("DSA slave port %d Link up", ctx->dsa_port_idx); + result = SWT_SetEthPortMII(&prv->swt_handle, ctx->dsa_port_idx, + PHY_TO_NETC_SPEED(state->speed), + PHY_TO_NETC_DUPLEX_MODE(state->speed)); + if (result != kStatus_Success) { + LOG_ERR("DSA slave port %d failed to set MAC up", ctx->dsa_port_idx); + } + net_eth_carrier_on(iface); + } else { + LOG_INF("DSA slave port %d Link down", ctx->dsa_port_idx); + net_eth_carrier_off(iface); + } +} + +static void dsa_netc_iface_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct dsa_netc_slave_config *cfg = (struct dsa_netc_slave_config *)dev->config; + struct dsa_context *context = dev->data; + struct dsa_netc_data *prv = PRV_DATA(context); + + struct ethernet_context *ctx = net_if_l2_data(iface); + struct ethernet_context *ctx_master; + int i = cfg->port_idx; + + /* Find master port */ + if (context->iface_master == NULL) { + context->iface_master = net_if_lookup_by_dev(prv->dev_master); + if (context->iface_master == NULL) { + LOG_ERR("DSA: Master iface NOT found!"); + return; + } + + /* + * Provide pointer to DSA context to master's eth interface + * struct ethernet_context + */ + ctx_master = net_if_l2_data(context->iface_master); + ctx_master->dsa_ctx = context; + } + + if (context->iface_slave[i] == NULL) { + context->iface_slave[i] = iface; + net_if_set_link_addr(iface, cfg->mac_addr, sizeof(cfg->mac_addr), + NET_LINK_ETHERNET); + ctx->dsa_port_idx = i; + ctx->dsa_ctx = context; + + /* + * Initialize ethernet context 'work' for this iface to + * be able to monitor the carrier status. + */ + ethernet_init(iface); + } + + /* Do not start the interface until link is up */ + net_if_carrier_off(iface); + + if (cfg->pseudo_mac) { + return; + } + + if (!device_is_ready(cfg->phy_dev)) { + LOG_ERR("PHY device (%p) is not ready, cannot init iface", cfg->phy_dev); + return; + } + + phy_link_callback_set(cfg->phy_dev, &netc_eth_phylink_callback, (void *)dev); +} + +static enum ethernet_hw_caps dsa_netc_get_capabilities(const struct device *dev) +{ + ARG_UNUSED(dev); + + return ETHERNET_DSA_SLAVE_PORT | ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T | + ETHERNET_LINK_1000BASE_T; +} + +static const struct device *dsa_netc_get_phy(const struct device *dev) +{ + const struct dsa_netc_slave_config *cfg = dev->config; + + return cfg->phy_dev; +} + +static int dsa_netc_tx(const struct device *dev, struct net_pkt *pkt) +{ + /* TODO: frame tagging not supported on old NETC versions. Need implementation here. */ + return 0; +} + +const struct ethernet_api dsa_netc_eth_api = { + .iface_api.init = dsa_netc_iface_init, + .get_capabilities = dsa_netc_get_capabilities, + .get_phy = dsa_netc_get_phy, + .send = dsa_netc_tx, +}; + +static struct dsa_api dsa_netc_api = { + .switch_read = dsa_netc_sw_read_reg, + .switch_write = dsa_netc_sw_write_reg, + .switch_set_mac_table_entry = dsa_netc_set_mac_table_entry, + .switch_get_mac_table_entry = dsa_netc_get_mac_table_entry, +}; + +#define DSA_NETC_SLAVE_DEVICE_INIT_INSTANCE(slave, n) \ + PINCTRL_DT_DEFINE(slave); \ + const struct dsa_netc_slave_config dsa_netc_##n##_slave_##slave##_config = { \ + .mac_addr = DT_PROP_OR(slave, local_mac_address, {0}), \ + .phy_dev = (COND_CODE_1(DT_NODE_HAS_PROP(slave, phy_handle), \ + DEVICE_DT_GET(DT_PHANDLE_BY_IDX(slave, phy_handle, 0)), \ + NULL)), \ + .phy_mode = NETC_PHY_MODE(slave), \ + .pseudo_mac = DT_ENUM_HAS_VALUE(slave, phy_connection_type, internal), \ + .pincfg = PINCTRL_DT_DEV_CONFIG_GET(slave), \ + .port_idx = DT_REG_ADDR_BY_IDX(slave, 0), \ + .ethernet_connection = (COND_CODE_1(DT_NODE_HAS_PROP(slave, ethernet), \ + (DEVICE_DT_GET(DT_PHANDLE(slave, ethernet))), NULL)), \ + }; \ + NET_DEVICE_INIT_INSTANCE( \ + CONCAT(dsa_slave_port_, slave), \ + "switch_port" STRINGIFY(n), n, dsa_netc_port_init, NULL, &dsa_netc_context_##n, \ + &dsa_netc_##n##_slave_##slave##_config, \ + CONFIG_ETH_INIT_PRIORITY, &dsa_netc_eth_api, ETHERNET_L2, \ + NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU); + +#define DSA_NETC_DEVICE(n) \ + AT_NONCACHEABLE_SECTION_ALIGN(static netc_cmd_bd_t dsa_netc_##n##_cmd_bd[8], \ + NETC_BD_ALIGN); \ + static struct dsa_netc_data dsa_netc_data_prv_##n = { \ + .port_num = DT_INST_CHILD_NUM_STATUS_OKAY(n), \ + .port_init_count = 0, \ + .cmd_bd = dsa_netc_##n##_cmd_bd, \ + }; \ + static struct dsa_context dsa_netc_context_##n = { \ + .num_slave_ports = DT_INST_CHILD_NUM(n), \ + .dapi = &dsa_netc_api, \ + .prv_data = (void *)&dsa_netc_data_prv_##n, \ + }; \ + DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(n, DSA_NETC_SLAVE_DEVICE_INIT_INSTANCE, n); + +DT_INST_FOREACH_STATUS_OKAY(DSA_NETC_DEVICE); diff --git a/drivers/ethernet/eth_nxp_imx_netc.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c similarity index 94% rename from drivers/ethernet/eth_nxp_imx_netc.c rename to drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c index 0791f8fa48806..9366dda6c84eb 100644 --- a/drivers/ethernet/eth_nxp_imx_netc.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(nxp_imx_eth); #include #include -#include "eth.h" +#include "../eth.h" #include "eth_nxp_imx_netc_priv.h" const struct device *netc_dev_list[NETC_DRV_MAX_INST_SUPPORT]; @@ -187,7 +187,7 @@ int netc_eth_init_common(const struct device *dev) ep_config.reclaimCallback = netc_eth_reclaim_callback; ep_config.msixEntry = &msix_entry[0]; ep_config.entryNum = NETC_MSIX_ENTRY_NUM; - ep_config.port.ethMac.miiMode = kNETC_RmiiMode; + ep_config.port.ethMac.miiMode = config->phy_mode; ep_config.port.ethMac.miiSpeed = kNETC_MiiSpeed100M; ep_config.port.ethMac.miiDuplex = kNETC_MiiFullDuplex; ep_config.rxCacheMaintain = true; @@ -225,6 +225,7 @@ int netc_eth_init_common(const struct device *dev) int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) { + const struct netc_eth_config *cfg = dev->config; struct netc_eth_data *data = dev->data; netc_buffer_struct_t buff = {.buffer = data->tx_buff, .length = sizeof(data->tx_buff)}; netc_frame_struct_t frame = {.buffArray = &buff, .length = 1}; @@ -234,6 +235,11 @@ int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) __ASSERT(pkt, "Packet pointer is NULL"); + /* TODO: support DSA master */ + if (cfg->pseudo_mac) { + return -ENOSYS; + } + k_mutex_lock(&data->tx_mutex, K_FOREVER); /* Copy packet to tx buffer */ @@ -275,9 +281,10 @@ int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) enum ethernet_hw_caps netc_eth_get_capabilities(const struct device *dev) { - ARG_UNUSED(dev); + const struct netc_eth_config *cfg = dev->config; + uint32_t caps; - return (ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T | ETHERNET_LINK_1000BASE_T | + caps = (ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T | ETHERNET_LINK_1000BASE_T | ETHERNET_HW_RX_CHKSUM_OFFLOAD | ETHERNET_HW_FILTERING #if defined(CONFIG_NET_VLAN) | ETHERNET_HW_VLAN @@ -286,6 +293,12 @@ enum ethernet_hw_caps netc_eth_get_capabilities(const struct device *dev) | ETHERNET_PROMISC_MODE #endif ); + + if (cfg->pseudo_mac) { + caps |= ETHERNET_DSA_MASTER_PORT; + } + + return caps; } int netc_eth_set_config(const struct device *dev, enum ethernet_config_type type, diff --git a/drivers/ethernet/eth_nxp_imx_netc_priv.h b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h similarity index 86% rename from drivers/ethernet/eth_nxp_imx_netc_priv.h rename to drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h index f09e718fdc26a..2f28e1c0bf42d 100644 --- a/drivers/ethernet/eth_nxp_imx_netc_priv.h +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,11 +7,11 @@ #ifndef ZEPHYR_DRIVERS_ETHERNET_ETH_NXP_IMX_NETC_PRIV_H_ #define ZEPHYR_DRIVERS_ETHERNET_ETH_NXP_IMX_NETC_PRIV_H_ +#include "nxp_imx_netc.h" #include "fsl_netc_endpoint.h" #include "fsl_msgintr.h" /* Buffer and descriptor alignment */ -#define NETC_BD_ALIGN 128 #define NETC_BUFF_ALIGN 64 #define NETC_RX_RING_BUF_SIZE_ALIGN \ SDK_SIZEALIGN(CONFIG_ETH_NXP_IMX_RX_RING_BUF_SIZE, NETC_BUFF_ALIGN) @@ -42,15 +42,6 @@ /* Timeout for various operations */ #define NETC_TIMEOUT K_MSEC(20) -/* Helper macros to convert from Zephyr PHY speed to NETC speed/duplex types */ -#define PHY_TO_NETC_SPEED(x) \ - (PHY_LINK_IS_SPEED_1000M(x) \ - ? kNETC_MiiSpeed1000M \ - : (PHY_LINK_IS_SPEED_100M(x) ? kNETC_MiiSpeed100M : kNETC_MiiSpeed10M)) - -#define PHY_TO_NETC_DUPLEX_MODE(x) \ - (PHY_LINK_IS_FULL_DUPLEX(x) ? kNETC_MiiFullDuplex : kNETC_MiiHalfDuplex) - /* Helper function to generate an Ethernet MAC address for a given ENETC instance */ #define FREESCALE_OUI_B0 0x00 #define FREESCALE_OUI_B1 0x04 @@ -85,6 +76,8 @@ struct netc_eth_config { uint16_t si_idx; const struct device *phy_dev; + netc_hw_mii_mode_t phy_mode; + volatile bool pseudo_mac; void (*generate_mac)(uint8_t *mac_addr); void (*bdr_init)(netc_bdr_config_t *bdr_config, netc_rx_bdr_config_t *rx_bdr_config, netc_tx_bdr_config_t *tx_bdr_config); diff --git a/drivers/ethernet/eth_nxp_imx_netc_psi.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c similarity index 91% rename from drivers/ethernet/eth_nxp_imx_netc_psi.c rename to drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c index d12b34e6308a1..c210c810d2aa1 100644 --- a/drivers/ethernet/eth_nxp_imx_netc_psi.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,20 +19,21 @@ LOG_MODULE_REGISTER(nxp_imx_eth_psi); #include #include -#include "eth.h" +#include "../eth.h" #include "eth_nxp_imx_netc_priv.h" static void netc_eth_phylink_callback(const struct device *pdev, struct phy_link_state *state, void *user_data) { const struct device *dev = (struct device *)user_data; + const struct netc_eth_config *cfg = dev->config; struct netc_eth_data *data = dev->data; status_t result; ARG_UNUSED(pdev); if (state->is_up) { - LOG_DBG("Link up"); + LOG_INF("ENETC%d Link up", getSiInstance(cfg->si_idx)); result = EP_Up(&data->handle, PHY_TO_NETC_SPEED(state->speed), PHY_TO_NETC_DUPLEX_MODE(state->speed)); if (result != kStatus_Success) { @@ -40,7 +41,7 @@ static void netc_eth_phylink_callback(const struct device *pdev, struct phy_link } net_eth_carrier_on(data->iface); } else { - LOG_DBG("Link down"); + LOG_INF("ENETC%d Link down", getSiInstance(cfg->si_idx)); result = EP_Down(&data->handle); if (result != kStatus_Success) { LOG_ERR("Failed to set MAC down"); @@ -73,12 +74,16 @@ static void netc_eth_iface_init(struct net_if *iface) net_if_set_link_addr(iface, data->mac_addr, sizeof(data->mac_addr), NET_LINK_ETHERNET); - LOG_INF("SI%d MAC: %02x:%02x:%02x:%02x:%02x:%02x", cfg->si_idx, data->mac_addr[0], - data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], - data->mac_addr[5]); + LOG_INF("ENETC%d MAC: %02x:%02x:%02x:%02x:%02x:%02x", getSiInstance(cfg->si_idx), + data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], + data->mac_addr[4], data->mac_addr[5]); ethernet_init(iface); + if (cfg->pseudo_mac) { + return; + } + /* * PSI controls the PHY. If PHY is configured either as fixed * link or autoneg, the callback is executed at least once @@ -99,11 +104,16 @@ static int netc_eth_init(const struct device *dev) const struct netc_eth_config *cfg = dev->config; int err; + if (cfg->pseudo_mac) { + goto init_common; + } + err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); if (err) { return err; } +init_common: return netc_eth_init_common(dev); } @@ -181,7 +191,10 @@ static const struct ethernet_api netc_eth_api = {.iface_api.init = netc_eth_ifac static const struct netc_eth_config netc_eth##n##_config = { \ .generate_mac = netc_eth##n##_generate_mac, \ .bdr_init = netc_eth##n##_bdr_init, \ - .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \ + .phy_dev = (COND_CODE_1(DT_INST_NODE_HAS_PROP(n, phy_handle), \ + (DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle))), NULL)), \ + .phy_mode = NETC_PHY_MODE(DT_DRV_INST(n)), \ + .pseudo_mac = DT_ENUM_HAS_VALUE(DT_DRV_INST(n), phy_connection_type, internal), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .si_idx = (DT_INST_PROP(n, mac_index) << 8) | DT_INST_PROP(n, si_index), \ .tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \ diff --git a/drivers/ethernet/nxp_imx_netc/nxp_imx_netc.h b/drivers/ethernet/nxp_imx_netc/nxp_imx_netc.h new file mode 100644 index 0000000000000..72dc9f3728d59 --- /dev/null +++ b/drivers/ethernet/nxp_imx_netc/nxp_imx_netc.h @@ -0,0 +1,32 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __NXP_IMX_NETC_H__ +#define __NXP_IMX_NETC_H__ + +#define NETC_BD_ALIGN 128 + +/* Get phy mode from dts. Default RMII for i.MXRT1180 ENETC which hasn't added the property. */ +#define NETC_PHY_MODE(node_id) \ + (DT_ENUM_HAS_VALUE(node_id, phy_connection_type, mii) \ + ? kNETC_MiiMode \ + : (DT_ENUM_HAS_VALUE(node_id, phy_connection_type, rmii) \ + ? kNETC_RmiiMode \ + : (DT_ENUM_HAS_VALUE(node_id, phy_connection_type, rgmii) \ + ? kNETC_RgmiiMode \ + : (DT_ENUM_HAS_VALUE(node_id, phy_connection_type, gmii) \ + ? kNETC_GmiiMode \ + : kNETC_RmiiMode)))) + +/* Helper macros to convert from Zephyr PHY speed to NETC speed/duplex types */ +#define PHY_TO_NETC_SPEED(x) \ + (PHY_LINK_IS_SPEED_1000M(x) \ + ? kNETC_MiiSpeed1000M \ + : (PHY_LINK_IS_SPEED_100M(x) ? kNETC_MiiSpeed100M : kNETC_MiiSpeed10M)) + +#define PHY_TO_NETC_DUPLEX_MODE(x) \ + (PHY_LINK_IS_FULL_DUPLEX(x) ? kNETC_MiiFullDuplex : kNETC_MiiHalfDuplex) + +#endif diff --git a/drivers/ethernet/oa_tc6.c b/drivers/ethernet/oa_tc6.c index 1818ccf8c14df..ccdfff4dbd2e5 100644 --- a/drivers/ethernet/oa_tc6.c +++ b/drivers/ethernet/oa_tc6.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "oa_tc6.h" #include @@ -19,12 +20,12 @@ LOG_MODULE_REGISTER(oa_tc6, CONFIG_ETHERNET_LOG_LEVEL); int oa_tc6_reg_read(struct oa_tc6 *tc6, const uint32_t reg, uint32_t *val) { - uint8_t buf[OA_TC6_HDR_SIZE + 12] = { 0 }; - struct spi_buf tx_buf = { .buf = buf, .len = sizeof(buf) }; - const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 }; - struct spi_buf rx_buf = { .buf = buf, .len = sizeof(buf) }; - const struct spi_buf_set rx = { .buffers = &rx_buf, .count = 1 }; - uint32_t rv, rvn, hdr_bkp, *hdr = (uint32_t *) &buf[0]; + uint8_t buf[OA_TC6_HDR_SIZE + 12] = {0}; + struct spi_buf tx_buf = {.buf = buf, .len = sizeof(buf)}; + const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; + struct spi_buf rx_buf = {.buf = buf, .len = sizeof(buf)}; + const struct spi_buf_set rx = {.buffers = &rx_buf, .count = 1}; + uint32_t rv, rvn, hdr_bkp, *hdr = (uint32_t *)&buf[0]; int ret = 0; /* @@ -36,12 +37,10 @@ int oa_tc6_reg_read(struct oa_tc6 *tc6, const uint32_t reg, uint32_t *val) rx_buf.len -= sizeof(rvn); } - *hdr = FIELD_PREP(OA_CTRL_HDR_DNC, 0) | - FIELD_PREP(OA_CTRL_HDR_WNR, 0) | - FIELD_PREP(OA_CTRL_HDR_AID, 0) | - FIELD_PREP(OA_CTRL_HDR_MMS, reg >> 16) | - FIELD_PREP(OA_CTRL_HDR_ADDR, reg) | - FIELD_PREP(OA_CTRL_HDR_LEN, 0); /* To read single register len = 0 */ + *hdr = FIELD_PREP(OA_CTRL_HDR_DNC, 0) | FIELD_PREP(OA_CTRL_HDR_WNR, 0) | + FIELD_PREP(OA_CTRL_HDR_AID, 0) | FIELD_PREP(OA_CTRL_HDR_MMS, reg >> 16) | + FIELD_PREP(OA_CTRL_HDR_ADDR, reg) | + FIELD_PREP(OA_CTRL_HDR_LEN, 0); /* To read single register len = 0 */ *hdr |= FIELD_PREP(OA_CTRL_HDR_P, oa_tc6_get_parity(*hdr)); hdr_bkp = *hdr; *hdr = sys_cpu_to_be32(*hdr); @@ -76,13 +75,13 @@ int oa_tc6_reg_read(struct oa_tc6 *tc6, const uint32_t reg, uint32_t *val) int oa_tc6_reg_write(struct oa_tc6 *tc6, const uint32_t reg, uint32_t val) { - uint8_t buf_tx[OA_TC6_HDR_SIZE + 12] = { 0 }; - uint8_t buf_rx[OA_TC6_HDR_SIZE + 12] = { 0 }; - struct spi_buf tx_buf = { .buf = buf_tx, .len = sizeof(buf_tx) }; - const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 }; - struct spi_buf rx_buf = { .buf = buf_rx, .len = sizeof(buf_rx) }; - const struct spi_buf_set rx = { .buffers = &rx_buf, .count = 1 }; - uint32_t rv, rvn, hdr_bkp, *hdr = (uint32_t *) &buf_tx[0]; + uint8_t buf_tx[OA_TC6_HDR_SIZE + 12] = {0}; + uint8_t buf_rx[OA_TC6_HDR_SIZE + 12] = {0}; + struct spi_buf tx_buf = {.buf = buf_tx, .len = sizeof(buf_tx)}; + const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; + struct spi_buf rx_buf = {.buf = buf_rx, .len = sizeof(buf_rx)}; + const struct spi_buf_set rx = {.buffers = &rx_buf, .count = 1}; + uint32_t rv, rvn, hdr_bkp, *hdr = (uint32_t *)&buf_tx[0]; int ret; /* @@ -94,12 +93,10 @@ int oa_tc6_reg_write(struct oa_tc6 *tc6, const uint32_t reg, uint32_t val) rx_buf.len -= sizeof(rvn); } - *hdr = FIELD_PREP(OA_CTRL_HDR_DNC, 0) | - FIELD_PREP(OA_CTRL_HDR_WNR, 1) | - FIELD_PREP(OA_CTRL_HDR_AID, 0) | - FIELD_PREP(OA_CTRL_HDR_MMS, reg >> 16) | - FIELD_PREP(OA_CTRL_HDR_ADDR, reg) | - FIELD_PREP(OA_CTRL_HDR_LEN, 0); /* To read single register len = 0 */ + *hdr = FIELD_PREP(OA_CTRL_HDR_DNC, 0) | FIELD_PREP(OA_CTRL_HDR_WNR, 1) | + FIELD_PREP(OA_CTRL_HDR_AID, 0) | FIELD_PREP(OA_CTRL_HDR_MMS, reg >> 16) | + FIELD_PREP(OA_CTRL_HDR_ADDR, reg) | + FIELD_PREP(OA_CTRL_HDR_LEN, 0); /* To read single register len = 0 */ *hdr |= FIELD_PREP(OA_CTRL_HDR_P, oa_tc6_get_parity(*hdr)); hdr_bkp = *hdr; *hdr = sys_cpu_to_be32(*hdr); @@ -143,8 +140,7 @@ int oa_tc6_reg_write(struct oa_tc6 *tc6, const uint32_t reg, uint32_t val) return ret; } -int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg, - uint32_t mask, uint32_t val) +int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg, uint32_t mask, uint32_t val) { uint32_t tmp; int ret; @@ -163,10 +159,74 @@ int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg, return oa_tc6_reg_write(tc6, reg, tmp); } +int oa_tc6_mdio_read(struct oa_tc6 *tc6, uint8_t prtad, uint8_t regad, uint16_t *data) +{ + return oa_tc6_reg_read( + tc6, OA_TC6_PHY_STD_REG_ADDR_BASE | (regad & OA_TC6_PHY_STD_REG_ADDR_MASK), + (uint32_t *)data); +} + +int oa_tc6_mdio_write(struct oa_tc6 *tc6, uint8_t prtad, uint8_t regad, uint16_t data) +{ + return oa_tc6_reg_write( + tc6, OA_TC6_PHY_STD_REG_ADDR_BASE | (regad & OA_TC6_PHY_STD_REG_ADDR_MASK), data); +} + +static int oa_tc6_get_phy_c45_mms(int devad) +{ + switch (devad) { + case MDIO_MMD_PCS: + return OA_TC6_PHY_C45_PCS_MMS2; + case MDIO_MMD_PMAPMD: + return OA_TC6_PHY_C45_PMA_PMD_MMS3; + case MDIO_MMD_VENDOR_SPECIFIC2: + return OA_TC6_PHY_C45_VS_PLCA_MMS4; + case MDIO_MMD_AN: + return OA_TC6_PHY_C45_AUTO_NEG_MMS5; + default: + return -EOPNOTSUPP; + } +} + +int oa_tc6_mdio_read_c45(struct oa_tc6 *tc6, uint8_t prtad, uint8_t devad, uint16_t regad, + uint16_t *data) +{ + uint32_t tmp; + int ret; + + ret = oa_tc6_get_phy_c45_mms(devad); + if (ret < 0) { + return ret; + } + + ret = oa_tc6_reg_read(tc6, (ret << 16) | regad, &tmp); + if (ret < 0) { + return ret; + } + + *data = (uint16_t)tmp; + + return 0; +} + +int oa_tc6_mdio_write_c45(struct oa_tc6 *tc6, uint8_t prtad, uint8_t devad, uint16_t regad, + uint16_t data) +{ + int ret; + + ret = oa_tc6_get_phy_c45_mms(devad); + if (ret < 0) { + return ret; + } + + return oa_tc6_reg_write(tc6, (ret << 16) | regad, (uint32_t)data); +} + int oa_tc6_set_protected_ctrl(struct oa_tc6 *tc6, bool prote) { - int ret = oa_tc6_reg_rmw(tc6, OA_CONFIG0, OA_CONFIG0_PROTE, - prote ? OA_CONFIG0_PROTE : 0); + int ret; + + ret = oa_tc6_reg_rmw(tc6, OA_CONFIG0, OA_CONFIG0_PROTE, prote ? OA_CONFIG0_PROTE : 0); if (ret < 0) { return ret; } @@ -199,18 +259,15 @@ int oa_tc6_send_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt) /* Transform struct net_pkt content into chunks */ for (i = 1; i <= chunks; i++) { - hdr = FIELD_PREP(OA_DATA_HDR_DNC, 1) | - FIELD_PREP(OA_DATA_HDR_DV, 1) | - FIELD_PREP(OA_DATA_HDR_NORX, 1) | - FIELD_PREP(OA_DATA_HDR_SWO, 0); + hdr = FIELD_PREP(OA_DATA_HDR_DNC, 1) | FIELD_PREP(OA_DATA_HDR_DV, 1) | + FIELD_PREP(OA_DATA_HDR_NORX, 1) | FIELD_PREP(OA_DATA_HDR_SWO, 0); if (i == 1) { hdr |= FIELD_PREP(OA_DATA_HDR_SV, 1); } if (i == chunks) { - hdr |= FIELD_PREP(OA_DATA_HDR_EBO, len - 1) | - FIELD_PREP(OA_DATA_HDR_EV, 1); + hdr |= FIELD_PREP(OA_DATA_HDR_EBO, len - 1) | FIELD_PREP(OA_DATA_HDR_EV, 1); } hdr |= FIELD_PREP(OA_DATA_HDR_P, oa_tc6_get_parity(hdr)); @@ -277,8 +334,8 @@ static int oa_tc6_update_status(struct oa_tc6 *tc6, uint32_t ftr) return 0; } -int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx, - uint32_t hdr, uint32_t *ftr) +int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx, uint32_t hdr, + uint32_t *ftr) { struct spi_buf tx_buf[2]; struct spi_buf rx_buf[2]; @@ -318,9 +375,8 @@ int oa_tc6_read_status(struct oa_tc6 *tc6, uint32_t *ftr) { uint32_t hdr; - hdr = FIELD_PREP(OA_DATA_HDR_DNC, 1) | - FIELD_PREP(OA_DATA_HDR_DV, 0) | - FIELD_PREP(OA_DATA_HDR_NORX, 1); + hdr = FIELD_PREP(OA_DATA_HDR_DNC, 1) | FIELD_PREP(OA_DATA_HDR_DV, 0) | + FIELD_PREP(OA_DATA_HDR_NORX, 1); hdr |= FIELD_PREP(OA_DATA_HDR_P, oa_tc6_get_parity(hdr)); return oa_tc6_chunk_spi_transfer(tc6, NULL, NULL, hdr, ftr); @@ -445,7 +501,7 @@ int oa_tc6_read_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt) return 0; - unref_buf: +unref_buf: net_buf_unref(buf_rx); return ret; } diff --git a/drivers/ethernet/oa_tc6.h b/drivers/ethernet/oa_tc6.h index c61e0359d99b3..448e35e2794e5 100644 --- a/drivers/ethernet/oa_tc6.h +++ b/drivers/ethernet/oa_tc6.h @@ -13,72 +13,84 @@ #include #include -#define MMS_REG(m, r) ((((m) & GENMASK(3, 0)) << 16) | ((r) & GENMASK(15, 0))) +#define MMS_REG(m, r) ((((m) & GENMASK(3, 0)) << 16) | ((r) & GENMASK(15, 0))) /* Memory Map Sector (MMS) 0 */ -#define OA_ID MMS_REG(0x0, 0x000) /* expect 0x11 */ -#define OA_PHYID MMS_REG(0x0, 0x001) -#define OA_RESET MMS_REG(0x0, 0x003) -#define OA_RESET_SWRESET BIT(0) -#define OA_CONFIG0 MMS_REG(0x0, 0x004) -#define OA_CONFIG0_SYNC BIT(15) -#define OA_CONFIG0_RFA_ZARFE BIT(12) -#define OA_CONFIG0_PROTE BIT(5) -#define OA_STATUS0 MMS_REG(0x0, 0x008) -#define OA_STATUS0_RESETC BIT(6) -#define OA_STATUS1 MMS_REG(0x0, 0x009) -#define OA_BUFSTS MMS_REG(0x0, 0x00B) -#define OA_BUFSTS_TXC GENMASK(15, 8) -#define OA_BUFSTS_RCA GENMASK(7, 0) -#define OA_IMASK0 MMS_REG(0x0, 0x00C) -#define OA_IMASK0_TXPEM BIT(0) -#define OA_IMASK0_TXBOEM BIT(1) -#define OA_IMASK0_TXBUEM BIT(2) -#define OA_IMASK0_RXBOEM BIT(3) -#define OA_IMASK0_LOFEM BIT(4) -#define OA_IMASK0_HDREM BIT(5) -#define OA_IMASK1 MMS_REG(0x0, 0x00D) -#define OA_IMASK0_UV18M BIT(19) +#define OA_ID MMS_REG(0x0, 0x000) /* expect 0x11 */ +#define OA_PHYID MMS_REG(0x0, 0x001) +#define OA_RESET MMS_REG(0x0, 0x003) +#define OA_RESET_SWRESET BIT(0) +#define OA_CONFIG0 MMS_REG(0x0, 0x004) +#define OA_CONFIG0_SYNC BIT(15) +#define OA_CONFIG0_RFA_ZARFE BIT(12) +#define OA_CONFIG0_PROTE BIT(5) +#define OA_STATUS0 MMS_REG(0x0, 0x008) +#define OA_STATUS0_RESETC BIT(6) +#define OA_STATUS1 MMS_REG(0x0, 0x009) +#define OA_BUFSTS MMS_REG(0x0, 0x00B) +#define OA_BUFSTS_TXC GENMASK(15, 8) +#define OA_BUFSTS_RCA GENMASK(7, 0) +#define OA_IMASK0 MMS_REG(0x0, 0x00C) +#define OA_IMASK0_TXPEM BIT(0) +#define OA_IMASK0_TXBOEM BIT(1) +#define OA_IMASK0_TXBUEM BIT(2) +#define OA_IMASK0_RXBOEM BIT(3) +#define OA_IMASK0_LOFEM BIT(4) +#define OA_IMASK0_HDREM BIT(5) +#define OA_IMASK1 MMS_REG(0x0, 0x00D) +#define OA_IMASK0_UV18M BIT(19) /* OA Control header */ -#define OA_CTRL_HDR_DNC BIT(31) -#define OA_CTRL_HDR_HDRB BIT(30) -#define OA_CTRL_HDR_WNR BIT(29) -#define OA_CTRL_HDR_AID BIT(28) -#define OA_CTRL_HDR_MMS GENMASK(27, 24) -#define OA_CTRL_HDR_ADDR GENMASK(23, 8) -#define OA_CTRL_HDR_LEN GENMASK(7, 1) -#define OA_CTRL_HDR_P BIT(0) +#define OA_CTRL_HDR_DNC BIT(31) +#define OA_CTRL_HDR_HDRB BIT(30) +#define OA_CTRL_HDR_WNR BIT(29) +#define OA_CTRL_HDR_AID BIT(28) +#define OA_CTRL_HDR_MMS GENMASK(27, 24) +#define OA_CTRL_HDR_ADDR GENMASK(23, 8) +#define OA_CTRL_HDR_LEN GENMASK(7, 1) +#define OA_CTRL_HDR_P BIT(0) /* OA Data header */ -#define OA_DATA_HDR_DNC BIT(31) -#define OA_DATA_HDR_SEQ BIT(30) -#define OA_DATA_HDR_NORX BIT(29) -#define OA_DATA_HDR_DV BIT(21) -#define OA_DATA_HDR_SV BIT(20) -#define OA_DATA_HDR_SWO GENMASK(19, 16) -#define OA_DATA_HDR_EV BIT(14) -#define OA_DATA_HDR_EBO GENMASK(13, 8) -#define OA_DATA_HDR_P BIT(0) +#define OA_DATA_HDR_DNC BIT(31) +#define OA_DATA_HDR_SEQ BIT(30) +#define OA_DATA_HDR_NORX BIT(29) +#define OA_DATA_HDR_DV BIT(21) +#define OA_DATA_HDR_SV BIT(20) +#define OA_DATA_HDR_SWO GENMASK(19, 16) +#define OA_DATA_HDR_EV BIT(14) +#define OA_DATA_HDR_EBO GENMASK(13, 8) +#define OA_DATA_HDR_P BIT(0) /* OA Data footer */ -#define OA_DATA_FTR_EXST BIT(31) -#define OA_DATA_FTR_HDRB BIT(30) -#define OA_DATA_FTR_SYNC BIT(29) -#define OA_DATA_FTR_RCA GENMASK(28, 24) -#define OA_DATA_FTR_DV BIT(21) -#define OA_DATA_FTR_SV BIT(20) -#define OA_DATA_FTR_SWO GENMASK(19, 16) -#define OA_DATA_FTR_FD BIT(15) -#define OA_DATA_FTR_EV BIT(14) -#define OA_DATA_FTR_EBO GENMASK(13, 8) -#define OA_DATA_FTR_TXC GENMASK(5, 1) -#define OA_DATA_FTR_P BIT(0) - -#define OA_TC6_HDR_SIZE 4 -#define OA_TC6_FTR_SIZE 4 -#define OA_TC6_BUF_ALLOC_TIMEOUT K_MSEC(10) -#define OA_TC6_FTR_RCA_MAX GENMASK(4, 0) -#define OA_TC6_FTR_TXC_MAX GENMASK(4, 0) +#define OA_DATA_FTR_EXST BIT(31) +#define OA_DATA_FTR_HDRB BIT(30) +#define OA_DATA_FTR_SYNC BIT(29) +#define OA_DATA_FTR_RCA GENMASK(28, 24) +#define OA_DATA_FTR_DV BIT(21) +#define OA_DATA_FTR_SV BIT(20) +#define OA_DATA_FTR_SWO GENMASK(19, 16) +#define OA_DATA_FTR_FD BIT(15) +#define OA_DATA_FTR_EV BIT(14) +#define OA_DATA_FTR_EBO GENMASK(13, 8) +#define OA_DATA_FTR_TXC GENMASK(5, 1) +#define OA_DATA_FTR_P BIT(0) + +#define OA_TC6_HDR_SIZE 4 +#define OA_TC6_FTR_SIZE 4 +#define OA_TC6_BUF_ALLOC_TIMEOUT K_MSEC(10) +#define OA_TC6_FTR_RCA_MAX GENMASK(4, 0) +#define OA_TC6_FTR_TXC_MAX GENMASK(4, 0) + +/* PHY Clause 22 registers base address and mask */ +#define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00 +#define OA_TC6_PHY_STD_REG_ADDR_MASK 0x1F + +/* PHY – Clause 45 registers memory map selector (MMS) as per table 6 in the + * OPEN Alliance specification. + */ +#define OA_TC6_PHY_C45_PCS_MMS2 2 /* MMD 3 */ +#define OA_TC6_PHY_C45_PMA_PMD_MMS3 3 /* MMD 1 */ +#define OA_TC6_PHY_C45_VS_PLCA_MMS4 4 /* MMD 31 */ +#define OA_TC6_PHY_C45_AUTO_NEG_MMS5 5 /* MMD 7 */ /** * @brief OA TC6 data. @@ -112,12 +124,6 @@ struct oa_tc6 { struct net_buf *concat_buf; }; -typedef struct { - uint8_t mms; - uint8_t address; - uint16_t value; -} oa_mem_map_t; - /** * @brief Calculate parity bit from data * @@ -212,8 +218,8 @@ int oa_tc6_read_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt); * * @return 0 if transmission was successful, <0 otherwise. */ -int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx, - uint32_t hdr, uint32_t *ftr); +int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx, uint32_t hdr, + uint32_t *ftr); /** * @brief Read status from OA TC6 device @@ -239,8 +245,7 @@ int oa_tc6_read_status(struct oa_tc6 *tc6, uint32_t *ftr); * * @return 0 if successful, <0 otherwise. */ -int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg, - uint32_t mask, uint32_t val); +int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg, uint32_t mask, uint32_t val); /** * @brief Check the status of OA TC6 device @@ -250,4 +255,68 @@ int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg, * @return 0 if successful, <0 otherwise. */ int oa_tc6_check_status(struct oa_tc6 *tc6); + +/** + * @brief Read C22 registers using MDIO Bus + * + * This routine provides an interface to perform a C22 register read on the + * MAC-PHY MDIO bus. + * + * @param[in] tc6 Pointer to the tc6 structure for the MAC-PHY + * @param[in] prtad Port address + * @param[in] regad Register address + * @param data Pointer to receive read data + * + * @return 0 if successful, <0 otherwise. + */ +int oa_tc6_mdio_read(struct oa_tc6 *tc6, uint8_t prtad, uint8_t regad, uint16_t *data); + +/** + * @brief Write C22 registers using MDIO Bus + * + * This routine provides an interface to perform a C22 register write on the + * MAC-PHY MDIO bus. + * + * @param[in] tc6 Pointer to the tc6 structure for the MAC-PHY + * @param[in] prtad Port address + * @param[in] regad Register address + * @param[in] data Write data + * + * @return 0 if successful, <0 otherwise. + */ +int oa_tc6_mdio_write(struct oa_tc6 *tc6, uint8_t prtad, uint8_t regad, uint16_t data); + +/** + * @brief Read C45 registers using MDIO Bus + * + * This routine provides an interface to perform a C45 register read on the + * MAC-PHY MDIO bus. + * + * @param[in] tc6 Pointer to the tc6 structure for the MAC-PHY + * @param[in] prtad Port address + * @param[in] devad MMD device address + * @param[in] regad Register address + * @param data Pointer to receive read data + * + * @return 0 if successful, <0 otherwise. + */ +int oa_tc6_mdio_read_c45(struct oa_tc6 *tc6, uint8_t prtad, uint8_t devad, uint16_t regad, + uint16_t *data); + +/** + * @brief Write C45 registers using MDIO Bus + * + * This routine provides an interface to perform a C45 register write on the + * MAC-PHY MDIO bus. + * + * @param[in] tc6 Pointer to the tc6 structure for the MAC-PHY + * @param[in] prtad Port address + * @param[in] devad MMD device address + * @param[in] regad Register address + * @param[in] data Write data + * + * @return 0 if successful, <0 otherwise. + */ +int oa_tc6_mdio_write_c45(struct oa_tc6 *tc6, uint8_t prtad, uint8_t devad, uint16_t regad, + uint16_t data); #endif /* OA_TC6_CFG_H__ */ diff --git a/drivers/ethernet/phy/CMakeLists.txt b/drivers/ethernet/phy/CMakeLists.txt index d94a0c9e7fb67..40964bf8d6b85 100644 --- a/drivers/ethernet/phy/CMakeLists.txt +++ b/drivers/ethernet/phy/CMakeLists.txt @@ -2,8 +2,12 @@ zephyr_library_sources_ifdef(CONFIG_PHY_GENERIC_MII phy_mii.c) zephyr_library_sources_ifdef(CONFIG_PHY_ADIN2111 phy_adin2111.c) +zephyr_library_sources_ifdef(CONFIG_PHY_DM8806 phy_dm8806.c) zephyr_library_sources_ifdef(CONFIG_PHY_TJA1103 phy_tja1103.c) zephyr_library_sources_ifdef(CONFIG_PHY_MICROCHIP_KSZ8081 phy_microchip_ksz8081.c) +zephyr_library_sources_ifdef(CONFIG_PHY_MICROCHIP_VSC8541 phy_microchip_vsc8541.c) zephyr_library_sources_ifdef(CONFIG_PHY_TI_DP83825 phy_ti_dp83825.c) zephyr_library_sources_ifdef(CONFIG_PHY_REALTEK_RTL8211F phy_realtek_rtl8211f.c) zephyr_library_sources_ifdef(CONFIG_PHY_QUALCOMM_AR8031 phy_qualcomm_ar8031.c) +zephyr_library_sources_ifdef(CONFIG_PHY_OA_TC14_PLCA_LIB phy_oa_tc14_plca.c) +zephyr_library_sources_ifdef(CONFIG_PHY_MICROCHIP_T1S phy_microchip_t1s.c) diff --git a/drivers/ethernet/phy/Kconfig b/drivers/ethernet/phy/Kconfig index 554616fd0e366..2d2779c5f2d9f 100644 --- a/drivers/ethernet/phy/Kconfig +++ b/drivers/ethernet/phy/Kconfig @@ -15,6 +15,8 @@ module-str = Log level for Ethernet PHY driver module-help = Sets log level for Ethernet PHY Device Drivers. source "subsys/net/Kconfig.template.log_config.net" source "drivers/ethernet/phy/Kconfig.tja1103" +source "drivers/ethernet/phy/Kconfig.dm8806" +source "drivers/ethernet/phy/Kconfig.microchip_t1s" config PHY_INIT_PRIORITY int "Ethernet PHY driver init priority" @@ -49,6 +51,15 @@ config PHY_MICROCHIP_KSZ8081 help Enable Microchip KSZ8081 Ethernet PHY Driver +config PHY_MICROCHIP_VSC8541 + bool "Microchip VSC8541 PHY Driver" + default y + depends on DT_HAS_MICROCHIP_VSC8541_ENABLED + depends on MDIO + depends on GPIO + help + Enable Microchip VSC8541 Ethernet PHY Driver + config PHY_TI_DP83825 bool "TI DP83825 PHY Driver" default y @@ -91,4 +102,15 @@ config PHY_MONITOR_PERIOD periodically executed to detect and report any changes in the PHY link status to the operating system. +config PHY_OA_TC14_PLCA_LIB + bool "Open Alliance TC14 PLCA generic lib" + help + Enable Open Alliance TC14 PLCA generic lib. + +config PHY_VERIFY_DEVICE_IDENTIFICATION + bool "Verify selected phy to actual reported phy chip id" + help + Verify the organizationally unique identifier that is reported + by the phy chip. + endif # "Ethernet PHY Drivers" diff --git a/drivers/ethernet/phy/Kconfig.dm8806 b/drivers/ethernet/phy/Kconfig.dm8806 new file mode 100644 index 0000000000000..e952420f7f0c9 --- /dev/null +++ b/drivers/ethernet/phy/Kconfig.dm8806 @@ -0,0 +1,77 @@ +# Copyright 2024 Robert Slawinski +# SPDX-License-Identifier: Apache-2.0 + +# Davicom PHY DM8806 driver configuration options + +menuconfig PHY_DM8806 + bool "Davicom PHY DM8806 driver" + default y + depends on DT_HAS_DAVICOM_DM8806_PHY_ENABLED + depends on MDIO + help + Enable driver for Davicom DM8806 PHY. + +if PHY_DM8806 + +choice PHY_DM8806_TRIGGER_MODE + prompt "Trigger mode" + default PHY_DM8806_TRIGGER_GLOBAL_THREAD + help + Specify the type of triggering to be used by the driver. + +config PHY_DM8806_TRIGGER_NONE + bool "No trigger" + +config PHY_DM8806_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on GPIO + select PHY_DM8806_TRIGGER + +endchoice + +config PHY_DM8806_ENERGY_EFFICIENT_MODE + bool "Energy efficient mode" + help + By default in DM8806, the energy efficient mode is enabled. + It had been observed that the network randomly fails when + this mode is on. Thus, this symbol is by default disabled. + +config PHY_DM8806_TRIGGER + bool + +config PHY_DM8806_THREAD_PRIORITY + int "Thread priority" + depends on PHY_DM8806_TRIGGER_GLOBAL_THREAD + default 13 + help + Priority of thread used by the driver to handle interrupts. + +config PHY_DM8806_THREAD_STACK_SIZE + int "Thread stack size" + depends on PHY_DM8806_TRIGGER_GLOBAL_THREAD + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + +config PHY_DM8806_SMI_BUS_CHECK + bool "Host SMI bus error check function" + default y + help + This functionality prevents the host SMI bus to be interferered by the + noise on board-level. During write procedure, the written value in + register will be applied until the correct checksum is written. In read + procedure, the hardware calculated checksum is compared with the software + calculated one to detect correctness of received data. + +config PHY_DM8806_SMI_BUS_CHECK_REPETITION + int "SMI bus transmission repetitions" + depends on PHY_DM8806_SMI_BUS_CHECK + default 5 + help + The numbers of SMI bus transmission repetition in case if CRC checksum + fails during read or write. After this numbers of repetition, the reading + message is dropped and will not be passed to the system. In write + procedure, the written value in register will be applied until the correct + checksum is written to the PHY register. + +endif # PHY_DM8806 diff --git a/drivers/ethernet/phy/Kconfig.microchip_t1s b/drivers/ethernet/phy/Kconfig.microchip_t1s new file mode 100644 index 0000000000000..c339a7545b6dd --- /dev/null +++ b/drivers/ethernet/phy/Kconfig.microchip_t1s @@ -0,0 +1,22 @@ +# Copyright 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig PHY_MICROCHIP_T1S + bool "Microchip 10BASE-T1S Ethernet PHYs Driver" + default y + depends on DT_HAS_MICROCHIP_T1S_PHY_ENABLED + depends on MDIO + select PHY_OA_TC14_PLCA_LIB + help + Enable Microchip's LAN8650/1 Rev.B0/B1 Internal PHYs and + LAN8670/1/2 Rev.C1/C2 PHYs Driver. + +if PHY_MICROCHIP_T1S + +config PHY_MICROCHIP_T1S_INIT_PRIORITY + int "Microchip T1S PHY init priority" + default 82 + help + Microchip T1S phy device driver initialization priority. + +endif diff --git a/drivers/ethernet/phy/phy_adin2111.c b/drivers/ethernet/phy/phy_adin2111.c index 48c83b5401b59..5f762ce691964 100644 --- a/drivers/ethernet/phy/phy_adin2111.c +++ b/drivers/ethernet/phy/phy_adin2111.c @@ -7,12 +7,6 @@ #include -#if DT_NODE_HAS_STATUS_OKAY(DT_INST(0, adi_adin2111_phy)) -#define DT_DRV_COMPAT adi_adin2111_phy -#else -#define DT_DRV_COMPAT adi_adin1100_phy -#endif - LOG_MODULE_REGISTER(DT_DRV_COMPAT, CONFIG_PHY_LOG_LEVEL); #include @@ -636,22 +630,28 @@ static DEVICE_API(ethphy, phy_adin2111_api) = { .write = phy_adin2111_reg_write, }; -#define ADIN2111_PHY_INITIALIZE(n) \ - static const struct phy_adin2111_config phy_adin2111_config_##n = { \ - .mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \ - .phy_addr = DT_INST_REG_ADDR(n), \ - .led0_en = DT_INST_PROP(n, led0_en), \ - .led1_en = DT_INST_PROP(n, led1_en), \ - .tx_24v = !(DT_INST_PROP(n, disable_tx_mode_24v)), \ - IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(adi_adin1100_phy), \ - (.mii = 1)) \ - }; \ - static struct phy_adin2111_data phy_adin2111_data_##n = { \ - .sem = Z_SEM_INITIALIZER(phy_adin2111_data_##n.sem, 1, 1), \ - }; \ - DEVICE_DT_INST_DEFINE(n, &phy_adin2111_init, NULL, \ - &phy_adin2111_data_##n, &phy_adin2111_config_##n, \ - POST_KERNEL, CONFIG_PHY_INIT_PRIORITY, \ +#define ADIN2111_PHY_INITIALIZE(n, model) \ + static const struct phy_adin2111_config phy_adin##model##_config_##n = { \ + .mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .phy_addr = DT_INST_REG_ADDR(n), \ + .led0_en = DT_INST_PROP(n, led0_en), \ + .led1_en = DT_INST_PROP(n, led1_en), \ + .tx_24v = !(DT_INST_PROP(n, disable_tx_mode_24v)), \ + IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(adi_adin1100_phy), \ + (.mii = 1)) \ + }; \ + static struct phy_adin2111_data phy_adin##model##_data_##n = { \ + .sem = Z_SEM_INITIALIZER(phy_adin##model##_data_##n.sem, 1, 1), \ + }; \ + DEVICE_DT_INST_DEFINE(n, &phy_adin2111_init, NULL, \ + &phy_adin##model##_data_##n, \ + &phy_adin##model##_config_##n, \ + POST_KERNEL, CONFIG_PHY_INIT_PRIORITY, \ &phy_adin2111_api); -DT_INST_FOREACH_STATUS_OKAY(ADIN2111_PHY_INITIALIZE) +#define DT_DRV_COMPAT adi_adin2111_phy +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADIN2111_PHY_INITIALIZE, 2111) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT adi_adin1100_phy +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADIN2111_PHY_INITIALIZE, 1100) +#undef DT_DRV_COMPAT diff --git a/drivers/ethernet/phy/phy_dm8806.c b/drivers/ethernet/phy/phy_dm8806.c new file mode 100644 index 0000000000000..976d882c005cf --- /dev/null +++ b/drivers/ethernet/phy/phy_dm8806.c @@ -0,0 +1,690 @@ +/* + * DM8806 Stand-alone Ethernet PHY with RMII + * + * Copyright (c) 2024 Robert Slawinski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT davicom_dm8806_phy + +#include +LOG_MODULE_REGISTER(eth_dm8806_phy, CONFIG_ETHERNET_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include + +#include "phy_dm8806_priv.h" + +struct phy_dm8806_config { + const struct device *mdio; + uint8_t phy_addr; + uint8_t switch_addr; + struct gpio_dt_spec gpio_rst; + struct gpio_dt_spec gpio_int; + bool mii; +}; + +struct phy_dm8806_data { + const struct device *dev; + struct phy_link_state state; + phy_callback_t link_speed_chenge_cb; + void *cb_data; + struct gpio_callback gpio_cb; +#ifdef CONFIG_PHY_DM8806_TRIGGER + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_PHY_DM8806_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem gpio_sem; +#endif +}; + +#ifdef CONFIG_PHY_DM8806_SMI_BUS_CHECK +static uint16_t phy_calculate_checksum(uint16_t data, uint16_t reg_addr, uint8_t opcode) +{ + uint16_t csum[8]; + uint16_t checksum = 0; + + /* Checksum calculated formula proposed by Davicom on datasheet: + * DM8806-DAVICOM - par. 7.2.1: + * Host SMI Bus Error Check Function, page 141. + */ + csum[0] = (((data >> 0) & 1) ^ ((data >> 8) & 1) ^ ((reg_addr >> 0) & 1) ^ + ((reg_addr >> 8) & 1)); + csum[1] = (((data >> 1) & 1) ^ ((data >> 9) & 1) ^ ((reg_addr >> 1) & 1) ^ + ((reg_addr >> 9) & 1)); + csum[2] = (((data >> 2) & 1) ^ ((data >> 10) & 1) ^ ((reg_addr >> 2) & 1) ^ + ((opcode >> 0) & 1)); + csum[3] = (((data >> 3) & 1) ^ ((data >> 11) & 1) ^ ((reg_addr >> 3) & 1) ^ + ((opcode >> 1) & 1)); + csum[4] = (((data >> 4) & 1) ^ ((data >> 12) & 1) ^ ((reg_addr >> 4) & 1)); + csum[5] = (((data >> 5) & 1) ^ ((data >> 13) & 1) ^ ((reg_addr >> 5) & 1)); + csum[6] = (((data >> 6) & 1) ^ ((data >> 14) & 1) ^ ((reg_addr >> 6) & 1)); + csum[7] = (((data >> 7) & 1) ^ ((data >> 15) & 1) ^ ((reg_addr >> 7) & 1)); + for (int cnt = 0; cnt < 8; cnt++) { + checksum |= (csum[cnt] << cnt); + } + return checksum; +} +#endif + +static int phy_dm8806_write_reg(const struct device *dev, uint8_t phyad, uint8_t regad, + uint16_t data) +{ + int res = 0; + const struct phy_dm8806_config *cfg = dev->config; + +/* SMI bus check function should be activated each time, before writing + * procedure to the DM8806 registers. This is standard procedure described in + * the datasheet of the DM8806. + */ +#ifdef CONFIG_PHY_DM8806_SMI_BUS_CHECK + uint16_t checksum_status; + bool checksum_mismatch; + uint16_t sw_checksum = 0; + uint16_t abs_reg; + int repetition = 0; + + do { + /* Set register 33AH.[0] = 1 to enable SMI Bus Error Check function. */ + res = mdio_write(cfg->mdio, DM8806_SMI_BUS_CTRL_PHY_ADDRESS, + DM8806_SMI_BUS_CTRL_REG_ADDRESS, DM8806_SMI_ECE); + if (res < 0) { + LOG_ERR("Failed to write data to PHY register: SMI_BUS_CTRL_REG_ADDRESS, " + "error code: %d", + res); + return res; + } +#endif + res = mdio_write(cfg->mdio, phyad, regad, data); + if (res < 0) { + LOG_ERR("Failed to read data from PHY, error code: %d", res); + return res; + } +#ifdef CONFIG_PHY_DM8806_SMI_BUS_CHECK + /* Calculate checksum */ + abs_reg = (phyad << DM8806_REGAD_WIDTH); + abs_reg |= (regad & BIT_MASK(DM8806_REGAD_WIDTH)); + sw_checksum = phy_calculate_checksum(data, abs_reg, DM8806_PHY_WRITE); + sw_checksum &= BIT_MASK(8); + /* Write calculated checksum to the PHY register 339H.[7:0] */ + res = mdio_write(cfg->mdio, DM8806_SMI_BUS_ERR_CHK_PHY_ADDRESS, + DM8806_SMI_BUS_ERR_CHK_REG_ADDRESS, sw_checksum); + if (res < 0) { + LOG_ERR("Failed to write calculated checksum to the PHY register, " + "error code: %d", + res); + return res; + } + + /* Read status of the checksum from Serial Bus Error Check Register + * 339H.[8]. + */ + res = mdio_read(cfg->mdio, DM8806_SMI_BUS_ERR_CHK_PHY_ADDRESS, + DM8806_SMI_BUS_ERR_CHK_REG_ADDRESS, &checksum_status); + if (res < 0) { + LOG_ERR("Failed to read hardware calculated checksum from PHY, error code: " + "%d", + res); + return res; + } + /* Checksum status is present on the 8-th bit of the Serial Bus Error + * Check Register (339h) [8]. + */ + checksum_mismatch = (bool)(checksum_status & BIT(DM8806_SMI_ERR)); + + /* Repeat the writing procedure for the number of attempts defined in + * KConfig after which the transfer will failed. + */ + if (CONFIG_PHY_DM8806_SMI_BUS_CHECK_REPETITION > 0) { + repetition++; + if (checksum_mismatch) { + LOG_WRN("%d repeat of PHY read procedure due to checksum error.", + repetition); + if (repetition >= CONFIG_PHY_DM8806_SMI_BUS_CHECK_REPETITION) { + LOG_ERR("Maximum number of PHY write repetition exceed."); + res = (-EIO); + } + } else { + break; + } + /* Do not repeat the transfer if repetition number is set to 0. Just check + * the checksum in this case and report the error in case of wrong checksum + * sum. + */ + } else { + if (checksum_mismatch) { + LOG_ERR("Wrong checksum, during PHY write procedure."); + res = (-EIO); + break; + } + } + } while (repetition < CONFIG_PHY_DM8806_SMI_BUS_CHECK_REPETITION); +#endif + + return res; +} + +static int phy_dm8806_read_reg(const struct device *dev, uint8_t phyad, uint8_t regad, + uint16_t *data) +{ + int res = 0; + const struct phy_dm8806_config *cfg = dev->config; + +/* SMI bus check function should be activated each time, before reading + * procedure to the DM8806 registers. This is standard procedure described in + * the datasheet of the DM8806. + */ +#ifdef CONFIG_PHY_DM8806_SMI_BUS_CHECK + uint16_t hw_checksum; + uint16_t sw_checksum = 0; + uint16_t abs_reg; + int repetition = 0; + + do { + /* Set register 33AH.[0] = 1 to enable SMI Bus Error Check function. */ + res = mdio_write(cfg->mdio, DM8806_SMI_BUS_CTRL_PHY_ADDRESS, + DM8806_SMI_BUS_CTRL_REG_ADDRESS, DM8806_SMI_ECE); + if (res < 0) { + LOG_ERR("Failed to write data to PHY register: SMI_BUS_CTRL_REG_ADDRESS, " + "error code: %d", + res); + return res; + } +#endif + res = mdio_read(cfg->mdio, phyad, regad, data); + if (res < 0) { + LOG_ERR("Failed to read data from PHY, error code: %d", res); + return res; + } +#ifdef CONFIG_PHY_DM8806_SMI_BUS_CHECK + /* Read hardware calculated checksum from Serial Bus Error Check Register. */ + res = mdio_read(cfg->mdio, DM8806_SMI_BUS_ERR_CHK_PHY_ADDRESS, + DM8806_SMI_BUS_ERR_CHK_REG_ADDRESS, &hw_checksum); + if (res < 0) { + LOG_ERR("Failed to read hardware calculated checksum from PHY, error code: " + "%d", + res); + return res; + } + /* Calculate checksum */ + abs_reg = (phyad << DM8806_REGAD_WIDTH); + abs_reg |= (regad & BIT_MASK(DM8806_REGAD_WIDTH)); + sw_checksum = phy_calculate_checksum(*data, abs_reg, DM8806_PHY_READ); + + if (CONFIG_PHY_DM8806_SMI_BUS_CHECK_REPETITION > 0) { + repetition++; + if (hw_checksum != sw_checksum) { + LOG_WRN("%d repeat of PHY read procedure due to checksum error.", + repetition); + if (repetition >= CONFIG_PHY_DM8806_SMI_BUS_CHECK_REPETITION) { + LOG_ERR("Maximum number of PHY read repetition exceed."); + res = (-EIO); + } + } else { + break; + } + } else { + if (hw_checksum != sw_checksum) { + LOG_ERR("Wrong checksum, during PHY read procedure."); + res = (-EIO); + break; + } + } + } while (repetition < CONFIG_PHY_DM8806_SMI_BUS_CHECK_REPETITION); +#endif + + return res; +} + +static void phy_dm8806_gpio_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + ARG_UNUSED(pins); + struct phy_dm8806_data *drv_data = CONTAINER_OF(cb, struct phy_dm8806_data, gpio_cb); + const struct phy_dm8806_config *cfg = drv_data->dev->config; + + gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_DISABLE); + k_sem_give(&drv_data->gpio_sem); +} + +static void phy_dm8806_thread_cb(const struct device *dev, struct phy_link_state *state, + void *cb_data) +{ + uint16_t data; + struct phy_dm8806_data *drv_data = dev->data; + const struct phy_dm8806_config *cfg = dev->config; + + if (drv_data->link_speed_chenge_cb != NULL) { + drv_data->link_speed_chenge_cb(dev, state, cb_data); + } + /* Clear the interrupt flag, by writing "1" to LNKCHG bit of Interrupt Status + * Register (318h) + */ + mdio_read(cfg->mdio, DM8806_INT_STAT_PHY_ADDR, DM8806_INT_STAT_REG_ADDR, &data); + data |= 0x1; + mdio_write(cfg->mdio, DM8806_INT_STAT_PHY_ADDR, DM8806_INT_STAT_REG_ADDR, data); + gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); +} + +static void phy_dm8806_thread(void *p1, void *p2, void *p3) +{ + struct phy_dm8806_data *drv_data = p1; + void *cb_data = p2; + struct phy_link_state *state = p3; + + while (1) { + k_sem_take(&drv_data->gpio_sem, K_FOREVER); + phy_dm8806_thread_cb(drv_data->dev, state, cb_data); + } +} + +int phy_dm8806_port_init(const struct device *dev) +{ + int res; + const struct phy_dm8806_config *cfg = dev->config; + + res = gpio_pin_configure_dt(&cfg->gpio_rst, (GPIO_OUTPUT_INACTIVE | GPIO_PULL_UP)); + if (res < 0) { + LOG_ERR("Failed to configure gpio reset pin for PHY DM886 as an output"); + return res; + } + /* Hardware reset of the PHY DM8806 */ + gpio_pin_set_dt(&cfg->gpio_rst, true); + if (res < 0) { + LOG_ERR("Failed to assert gpio reset pin of the PHY DM886 to physical 0"); + return res; + } + /* According to DM8806 datasheet (DM8806-DAVICOM.pdf), low active state on + * the reset pin must remain minimum 10ms to perform hardware reset. + */ + k_msleep(10); + res = gpio_pin_set_dt(&cfg->gpio_rst, false); + if (res < 0) { + LOG_ERR("Failed to assert gpio reset pin of the PHY DM886 to physical 1"); + return res; + } + + return res; +} + +int phy_dm8806_init_interrupt(const struct device *dev) +{ + int res = 0; + uint16_t data; + struct phy_dm8806_data *drv_data = dev->data; + void *cb_data = drv_data->cb_data; + const struct phy_dm8806_config *cfg = dev->config; + + /* Configure Davicom PHY DM8806 interrupts: + * Activate global interrupt by writing "1" to LNKCHG of Interrupt Mask + * And Control Register (319h) + */ + res = mdio_read(cfg->mdio, DM8806_INT_MASK_CTRL_PHY_ADDR, DM8806_INT_MASK_CTRL_REG_ADDR, + &data); + if (res) { + LOG_ERR("Failed to read IRQ_LED_CONTROL, %i", res); + return res; + } + data |= 0x1; + res = mdio_write(cfg->mdio, DM8806_INT_MASK_CTRL_PHY_ADDR, DM8806_INT_MASK_CTRL_REG_ADDR, + data); + if (res) { + LOG_ERR("Failed to read IRQ_LED_CONTROL, %i", res); + return res; + } + + /* Activate interrupt per Ethernet port by writing "1" to LNK_EN0~3 + * of WoL Control Register (2BBh) + */ + res = mdio_read(cfg->mdio, DM8806_WOLL_CTRL_REG_PHY_ADDR, DM8806_WOLL_CTRL_REG_REG_ADDR, + &data); + if (res) { + LOG_ERR("Failed to read IRQ_LED_CONTROL, %i", res); + return res; + } + data |= 0xF; + res = mdio_write(cfg->mdio, DM8806_WOLL_CTRL_REG_PHY_ADDR, DM8806_WOLL_CTRL_REG_REG_ADDR, + data); + if (res) { + LOG_ERR("Failed to read IRQ_LED_CONTROL, %i", res); + return res; + } + + /* Configure external interrupts: + * Configure interrupt pin to recognize the rising edge on the Davicom + * PHY DM8806 as external interrupt + */ + if (device_is_ready(cfg->gpio_int.port) != true) { + LOG_ERR("gpio_int gpio not ready"); + return -ENODEV; + } + drv_data->dev = dev; + res = gpio_pin_configure_dt(&cfg->gpio_int, GPIO_INPUT); + if (res < 0) { + LOG_ERR("Failed to configure gpio interrupt pin for PHY DM886 as an input"); + return res; + } + /* Assign callback function to be fired by Davicom PHY DM8806 external + * interrupt pin + */ + gpio_init_callback(&drv_data->gpio_cb, phy_dm8806_gpio_callback, BIT(cfg->gpio_int.pin)); + res = gpio_add_callback(cfg->gpio_int.port, &drv_data->gpio_cb); + if (res < 0) { + LOG_ERR("Failed to set PHY DM886 gpio callback"); + return res; + } + k_sem_init(&drv_data->gpio_sem, 0, K_SEM_MAX_LIMIT); + k_thread_create(&drv_data->thread, drv_data->thread_stack, + CONFIG_PHY_DM8806_THREAD_STACK_SIZE, phy_dm8806_thread, drv_data, cb_data, + NULL, K_PRIO_COOP(CONFIG_PHY_DM8806_THREAD_PRIORITY), 0, K_NO_WAIT); + /* Configure GPIO interrupt to be triggered on pin state change to logical + * level 1 asserted by Davicom PHY DM8806 interrupt Pin + */ + gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + if (res < 0) { + LOG_ERR("Failed to configure PHY DM886 gpio interrupt pin trigger for " + "active edge"); + return res; + } + + return 0; +} + +static int phy_dm8806_init(const struct device *dev) +{ + int ret; + uint16_t val; + const struct phy_dm8806_config *cfg = dev->config; + + /* Configure reset pin for Davicom PHY DM8806 to be able to generate reset + * signal + */ + ret = phy_dm8806_port_init(dev); + if (ret != 0) { + LOG_ERR("Failed to reset PHY DM8806 "); + return ret; + } + + ret = mdio_read(cfg->mdio, DM8806_PHY_ADDRESS_18H, DM8806_PORT5_MAC_CONTROL, &val); + if (ret) { + LOG_ERR("Failed to read PORT5_MAC_CONTROL: %i", ret); + return ret; + } + + /* Activate default working mode*/ + val |= (DM8806_P5_50M_INT_CLK_SOURCE | DM8806_P5_50M_CLK_OUT_ENABLE | DM8806_P5_EN_FORCE); + val &= (DM8806_P5_SPEED_100M | DM8806_P5_FULL_DUPLEX | DM8806_P5_FORCE_LINK_ON); + + ret = mdio_write(cfg->mdio, DM8806_PHY_ADDRESS_18H, DM8806_PORT5_MAC_CONTROL, val); + if (ret) { + LOG_ERR("Failed to write PORT5_MAC_CONTROL, %i", ret); + return ret; + } + + ret = mdio_read(cfg->mdio, DM8806_PHY_ADDRESS_18H, DM8806_IRQ_LED_CONTROL, &val); + if (ret) { + LOG_ERR("Failed to read IRQ_LED_CONTROL, %i", ret); + return ret; + } + + /* Activate LED blinking mode indicator mode 0. */ + val &= DM8806_LED_MODE_0; + ret = mdio_write(cfg->mdio, DM8806_PHY_ADDRESS_18H, DM8806_IRQ_LED_CONTROL, val); + if (ret) { + LOG_ERR("Failed to write IRQ_LED_CONTROL, %i", ret); + return ret; + } + + if (!IS_ENABLED(CONFIG_PHY_DM8806_ENERGY_EFFICIENT_MODE)) { + /* Disable - 802.3az Energy Efficient Ethernet + * The switch chip DM8806 only works reliably in this mode. + */ + for (uint32_t port_address = DM8806_SWITCH_REGISTER_OFFSET; + port_address <= DM8806_SWITCH_REGISTER_OFFSET + 5; port_address++) { + ret = mdio_read(cfg->mdio, port_address, + DM8806_ENERGY_EFFICIENT_ETH_CTRL_REG_ADDR, &val); + if (ret) { + LOG_ERR("Failed to read ENERGY_EFFICIENT_ETH_CTRL_REG, %i", ret); + return ret; + } + val &= (~DM8806_EEE_EN); + ret = mdio_write(cfg->mdio, port_address, + DM8806_ENERGY_EFFICIENT_ETH_CTRL_REG_ADDR, val); + if (ret) { + LOG_ERR("Failed to write ENERGY_EFFICIENT_ETH_CTRL_REG, %i", ret); + return ret; + } + } + } /* CONFIG_PHY_DM8806_ENERGY_EFFICIENT_MODE */ + +#ifdef CONFIG_PHY_DM8806_TRIGGER + ret = phy_dm8806_init_interrupt(dev); + if (ret != 0) { + LOG_ERR("Failed to configure interrupt fot PHY DM8806"); + return ret; + } +#endif + return 0; +} + +static int phy_dm8806_get_link_state(const struct device *dev, struct phy_link_state *state) +{ + int ret; + uint16_t status; + uint16_t data; + const struct phy_dm8806_config *cfg = dev->config; + +#ifdef CONFIG_PHY_DM8806_TRIGGER + ret = mdio_read(cfg->mdio, 0x18, 0x18, &data); + if (ret) { + LOG_ERR("Failed to read IRQ_LED_CONTROL, %i", ret); + return ret; + } +#endif + /* Read data from Switch Per-Port Register. */ + ret = phy_dm8806_read_reg(dev, cfg->switch_addr, DM8806_PORTX_SWITCH_STATUS, &data); + if (ret) { + LOG_ERR("Failes to read data drom DM8806 Switch Per-Port Registers area"); + return ret; + } + /* Extract speed and duplex status from Switch Per-Port Register: Per Port + * Status Data Register + */ + status = data; + status >>= DM8806_SPEED_AND_DUPLEX_OFFSET; + switch (status & DM8806_SPEED_AND_DUPLEX_MASK) { + case DM8806_SPEED_10MBPS_HALF_DUPLEX: + state->speed = LINK_HALF_10BASE_T; + break; + case DM8806_SPEED_10MBPS_FULL_DUPLEX: + state->speed = LINK_FULL_10BASE_T; + break; + case DM8806_SPEED_100MBPS_HALF_DUPLEX: + state->speed = LINK_HALF_100BASE_T; + break; + case DM8806_SPEED_100MBPS_FULL_DUPLEX: + state->speed = LINK_FULL_100BASE_T; + break; + } + /* Extract link status from Switch Per-Port Register: Per Port Status Data + * Register + */ + status = data; + if (status & DM8806_LINK_STATUS_MASK) { + state->is_up = true; + } else { + state->is_up = false; + } + return ret; +} + +static int phy_dm8806_cfg_link(const struct device *dev, enum phy_link_speed adv_speeds) +{ + uint8_t ret; + uint16_t data; + uint16_t req_speed; + const struct phy_dm8806_config *cfg = dev->config; + + req_speed = adv_speeds; + switch (req_speed) { + case LINK_HALF_10BASE_T: + req_speed = DM8806_MODE_10_BASET_HALF_DUPLEX; + break; + + case LINK_FULL_10BASE_T: + req_speed = DM8806_MODE_10_BASET_FULL_DUPLEX; + break; + + case LINK_HALF_100BASE_T: + req_speed = DM8806_MODE_100_BASET_HALF_DUPLEX; + break; + + case LINK_FULL_100BASE_T: + req_speed = DM8806_MODE_100_BASET_FULL_DUPLEX; + break; + } + + /* Power down */ + ret = phy_dm8806_read_reg(dev, cfg->phy_addr, DM8806_PORTX_PHY_CONTROL_REGISTER, &data); + if (ret) { + LOG_ERR("Failes to read data drom DM8806"); + return ret; + } + k_busy_wait(500); + data |= DM8806_POWER_DOWN; + ret = phy_dm8806_write_reg(dev, cfg->phy_addr, DM8806_PORTX_PHY_CONTROL_REGISTER, data); + if (ret) { + LOG_ERR("Failed to write data to DM8806"); + return ret; + } + k_busy_wait(500); + + /* Turn off the auto-negotiation process. */ + ret = phy_dm8806_read_reg(dev, cfg->phy_addr, DM8806_PORTX_PHY_CONTROL_REGISTER, &data); + if (ret) { + LOG_ERR("Failed to write data to DM8806"); + return ret; + } + k_busy_wait(500); + data &= ~(DM8806_AUTO_NEGOTIATION); + ret = phy_dm8806_write_reg(dev, cfg->phy_addr, DM8806_PORTX_PHY_CONTROL_REGISTER, data); + if (ret) { + LOG_ERR("Failed to write data to DM8806"); + return ret; + } + k_busy_wait(500); + + /* Change the link speed. */ + ret = phy_dm8806_read_reg(dev, cfg->phy_addr, DM8806_PORTX_PHY_CONTROL_REGISTER, &data); + if (ret) { + LOG_ERR("Failed to read data from DM8806"); + return ret; + } + k_busy_wait(500); + data &= ~(DM8806_LINK_SPEED | DM8806_DUPLEX_MODE); + data |= req_speed; + ret = phy_dm8806_write_reg(dev, cfg->phy_addr, DM8806_PORTX_PHY_CONTROL_REGISTER, data); + if (ret) { + LOG_ERR("Failed to write data to DM8806"); + return ret; + } + k_busy_wait(500); + + /* Power up ethernet port*/ + ret = phy_dm8806_read_reg(dev, cfg->phy_addr, DM8806_PORTX_PHY_CONTROL_REGISTER, &data); + if (ret) { + LOG_ERR("Failes to read data drom DM8806"); + return ret; + } + k_busy_wait(500); + data &= ~(DM8806_POWER_DOWN); + ret = phy_dm8806_write_reg(dev, cfg->phy_addr, DM8806_PORTX_PHY_CONTROL_REGISTER, data); + if (ret) { + LOG_ERR("Failed to write data to DM8806"); + return ret; + } + k_busy_wait(500); + return ret; +} + +static int phy_dm8806_reg_read(const struct device *dev, uint16_t reg_addr, uint32_t *data) +{ + int res; + const struct phy_dm8806_config *cfg = dev->config; + + res = mdio_read(cfg->mdio, cfg->switch_addr, reg_addr, (uint16_t *)data); + if (res) { + LOG_ERR("Failed to read data from DM8806"); + return res; + } + return res; +} + +static int phy_dm8806_reg_write(const struct device *dev, uint16_t reg_addr, uint32_t data) +{ + int res; + const struct phy_dm8806_config *cfg = dev->config; + + res = mdio_write(cfg->mdio, cfg->switch_addr, reg_addr, data); + if (res) { + LOG_ERR("Failed to write data to DM8806"); + return res; + } + return res; +} + +static int phy_dm8806_link_cb_set(const struct device *dev, phy_callback_t cb, void *user_data) +{ + int res = 0; + struct phy_dm8806_data *data = dev->data; + const struct phy_dm8806_config *cfg = dev->config; + + res = gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_DISABLE); + if (res < 0) { + LOG_WRN("Failed to disable DM8806 interrupt: %i", res); + return res; + } + data->link_speed_chenge_cb = cb; + data->cb_data = user_data; + gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + if (res < 0) { + LOG_WRN("Failed to enable DM8806 interrupt: %i", res); + return res; + } + + return res; +} + +static DEVICE_API(ethphy, phy_dm8806_api) = { + .get_link = phy_dm8806_get_link_state, + .cfg_link = phy_dm8806_cfg_link, +#ifdef CONFIG_PHY_DM8806_TRIGGER + .link_cb_set = phy_dm8806_link_cb_set, +#endif + .read = phy_dm8806_reg_read, + .write = phy_dm8806_reg_write, +}; + +#define DM8806_PHY_DEFINE_CONFIG(n) \ + static const struct phy_dm8806_config phy_dm8806_config_##n = { \ + .mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .phy_addr = DT_INST_REG_ADDR(n), \ + .switch_addr = DT_PROP(DT_NODELABEL(dm8806_phy##n), reg_switch), \ + .gpio_int = GPIO_DT_SPEC_INST_GET(n, interrupt_gpio), \ + .gpio_rst = GPIO_DT_SPEC_INST_GET(n, reset_gpio), \ + } + +#define DM8806_PHY_INITIALIZE(n) \ + DM8806_PHY_DEFINE_CONFIG(n); \ + static struct phy_dm8806_data phy_dm8806_data_##n = { \ + .gpio_sem = Z_SEM_INITIALIZER(phy_dm8806_data_##n.gpio_sem, 1, 1), \ + }; \ + DEVICE_DT_INST_DEFINE(n, phy_dm8806_init, NULL, &phy_dm8806_data_##n, \ + &phy_dm8806_config_##n, POST_KERNEL, CONFIG_PHY_INIT_PRIORITY, \ + &phy_dm8806_api); + +DT_INST_FOREACH_STATUS_OKAY(DM8806_PHY_INITIALIZE) diff --git a/drivers/ethernet/phy/phy_dm8806_priv.h b/drivers/ethernet/phy/phy_dm8806_priv.h new file mode 100644 index 0000000000000..9d8bc203edd1f --- /dev/null +++ b/drivers/ethernet/phy/phy_dm8806_priv.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2024 Robert Slawinski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* The absolute PHY address is 10 bit length. Last 5 bits for oldest + * part of address - see Clause 22 of IEEE 802.3. + */ +#define DM8806_REGAD_WIDTH 0x5u + +/* Mask for checksum error. Checksum status is present on the 8-th bit of the + * Serial Bus Error Check Register (339h) [8] + */ +#define DM8806_SMI_ERR 8 + +/* PHY read opcode as part of the MDIO frame in Clause 22 */ +#define DM8806_PHY_READ 0x2u +/* PHY write opcode as part of the MDIO frame in Clause 22 */ +#define DM8806_PHY_WRITE 0x1u + +/* Port 0~4 PHY Control Register. */ +#define DM8806_PORTX_PHY_CONTROL_REGISTER 0x0u +/* 10 Mbit/s transfer with half duplex mask. */ +#define DM8806_MODE_10_BASET_HALF_DUPLEX 0x0u +/* 10 Mbit/s transfer with full duplex mask. */ +#define DM8806_MODE_10_BASET_FULL_DUPLEX 0x100u +/* 100 Mbit/s transfer with half duplex mask. */ +#define DM8806_MODE_100_BASET_HALF_DUPLEX 0x2000u +/* 100 Mbit/s transfer with full duplex mask. */ +#define DM8806_MODE_100_BASET_FULL_DUPLEX 0x2100u +/* Duplex mode ability offset. */ +#define DM8806_DUPLEX_MODE (1 << 8) +/* Power down mode offset. */ +#define DM8806_POWER_DOWN (1 << 11) +/* Auto negotiation mode offset. */ +#define DM8806_AUTO_NEGOTIATION (1 << 12) +/* Link speed selection offset. */ +#define DM8806_LINK_SPEED (1 << 13) + +/* Port 0~4 Status Data Register. */ +#define DM8806_PORTX_SWITCH_STATUS 0x10u +/* 10 Mbit/s transfer speed with half duplex. */ +#define DM8806_SPEED_10MBPS_HALF_DUPLEX 0x00u +/* 10 Mbit/s transfer speed with full duplex. */ +#define DM8806_SPEED_10MBPS_FULL_DUPLEX 0x01u +/* 100 Mbit/s transfer speed with half duplex. */ +#define DM8806_SPEED_100MBPS_HALF_DUPLEX 0x02u +/* 100 Mbit/s transfer speed with full duplex. */ +#define DM8806_SPEED_100MBPS_FULL_DUPLEX 0x03u +/* Speed and duplex mode status offset. */ +#define DM8806_SPEED_AND_DUPLEX_OFFSET 0x01u +/* Speed and duplex mode staus mask. */ +#define DM8806_SPEED_AND_DUPLEX_MASK 0x07u +/* Link status mask. */ +#define DM8806_LINK_STATUS_MASK 0x1u + +/* Switch Engine Registers */ +/* Address Table Control And Status Register PHY Address */ +#define DM8806_ADDR_TAB_CTRL_STAT_PHY_ADDR 0x15u +/* Address Table Control And Status Register Register SAddress */ +#define DM8806_ADDR_TAB_CTRL_STAT_REG_ADDR 0x10u + +/* Address Table Access bussy flag offset */ +#define DM8806_ATB_S_OFFSET 0xf +/* Address Table Command Result flag offset */ +#define DM8806_ATB_CR_OFFSET 0xd +/* Address Table Command Result flag mask */ +#define DM8806_ATB_CR_MASK 0x3 + +/* Unicast Address Table Index*/ +#define DM8806_UNICAST_ADDR_TAB (1 << 0 | 1 << 1) +/* Multicast Address Table Index*/ +#define DM8806_MULTICAST_ADDR_TAB (1 << 0) +/* IGMP Table Index*/ +#define DM8806_IGMP_ADDR_TAB (1 << 1) + +/* Read a entry with sequence number of address table */ +#define DM8806_ATB_CMD_READ (1 << 2 | 1 << 3 | 1 << 4) +/* Write a entry with MAC address */ +#define DM8806_ATB_CMD_WRITE (1 << 2) +/* Delete a entry with MAC address */ +#define DM8806_ATB_CMD_DELETE (1 << 3) +/* Search a entry with MAC address */ +#define DM8806_ATB_CMD_SEARCH (1 << 2 | 1 << 3) +/* Clear one or more than one entries with Port or FID */ +#define DM8806_ATB_CMD_CLEAR (1 << 4) + +/* Address Table Data 0 PHY Address */ +#define DM8806_ADDR_TAB_DATA0_PHY_ADDR 0x15u +/* Address Table Data 0 Register Address */ +#define DM8806_ADDR_TAB_DATA0_REG_ADDR 0x11u +/* Port number or port map mask*/ +#define DM8806_ATB_PORT_MASK 0x1f + +/* Address Table Data 1 PHY Address */ +#define DM8806_ADDR_TAB_DATA1_PHY_ADDR 0x15u +/* Address Table Data 1 Register Address */ +#define DM8806_ADDR_TAB_DATA1_REG_ADDR 0x12u + +/* Address Table Data 2 PHY Address */ +#define DM8806_ADDR_TAB_DATA2_PHY_ADDR 0x15u +/* Address Table Data 2 Register Address */ +#define DM8806_ADDR_TAB_DATA2_REG_ADDR 0x13u + +/* Address Table Data 3 PHY Address */ +#define DM8806_ADDR_TAB_DATA3_PHY_ADDR 0x15u +/* Address Table Data 3 Register Address */ +#define DM8806_ADDR_TAB_DATA3_REG_ADDR 0x14u + +/* Address Table Data 4 PHY Address */ +#define DM8806_ADDR_TAB_DATA4_PHY_ADDR 0x15u +/* Address Table Data 4 Register Address */ +#define DM8806_ADDR_TAB_DATA4_REG_ADDR 0x15u + +/* WoL Control Register PHY Address */ +#define DM8806_WOLL_CTRL_REG_PHY_ADDR 0x15u +/* WoL Control Register Register Address */ +#define DM8806_WOLL_CTRL_REG_REG_ADDR 0x1bu + +/* Serial Bus Error Check PHY Address. */ +#define DM8806_SMI_BUS_ERR_CHK_PHY_ADDRESS 0x19u +/* Serial Bus Error Check Register Address. */ +#define DM8806_SMI_BUS_ERR_CHK_REG_ADDRESS 0x19u + +/* Serial Bus Control PHY Address. */ +#define DM8806_SMI_BUS_CTRL_PHY_ADDRESS 0x19u +/* Serial Bus Control Register Address. */ +#define DM8806_SMI_BUS_CTRL_REG_ADDRESS 0x1au +/* SMI Bus Error Check Enable. */ +#define DM8806_SMI_ECE BIT(0) + +/* PHY address 0x18h */ +#define DM8806_PHY_ADDRESS_18H 0x18u + +/* Interrupt Status Register PHY Address. */ +#define DM8806_INT_STAT_PHY_ADDR 0x18u +/* Interrupt Status Register Register Address. */ +#define DM8806_INT_STAT_REG_ADDR 0x18u + +/* Interrupt Mask & Control Register PHY Address. */ +#define DM8806_INT_MASK_CTRL_PHY_ADDR 0x18u +/* Interrupt Mask & Control Register Register Address. */ +#define DM8806_INT_MASK_CTRL_REG_ADDR 0x19u + +/* Switch Register offset */ +#define DM8806_SWITCH_REGISTER_OFFSET 0x08 + +/* Energy Efficient Ethernet Control Register Address. */ +#define DM8806_ENERGY_EFFICIENT_ETH_CTRL_REG_ADDR 0x1e + +/* Energy Efficient Ethernet enable bit */ +#define DM8806_EEE_EN BIT(15) + +#define DM8806_PORT5_MAC_CONTROL 0x15u +/* Port 5 Force Speed control bit */ +#define DM8806_P5_SPEED_100M ~BIT(0) +/* Port 5 Force Duplex control bit */ +#define DM8806_P5_FULL_DUPLEX ~BIT(1) +/* Port 5 Force Link control bit. Only available in force mode. */ +#define DM8806_P5_FORCE_LINK_ON ~BIT(2) +/* Port 5 Force Mode Enable control bit. Only available for + * MII/RevMII/RMII + */ +#define DM8806_P5_EN_FORCE BIT(3) +/* Bit 4 is reserved and should not be use */ +/* Port 5 50MHz Clock Output Enable control bit. Only available when Port 5 + * be configured as RMII + */ +#define DM8806_P5_50M_CLK_OUT_ENABLE BIT(5) +/* Port 5 Clock Source Selection control bit. Only available when Port 5 + * is configured as RMII + */ +#define DM8806_P5_50M_INT_CLK_SOURCE BIT(6) +/* Port 5 Output Pin Slew Rate. */ +#define DM8806_P5_NORMAL_SLEW_RATE ~BIT(7) +/* IRQ and LED Control Register. */ +#define DM8806_IRQ_LED_CONTROL 0x17u +/* LED mode 0: + * LNK_LED: + * 100M link fail - LED off + * 100M link ok and no TX/RX activity - LED on + * 100M link ok and TX/RX activity - LED blinking + * SPD_LED: + * No colision: - LED off + * Colision: - LED blinking + * FDX_LED: + * 10M link fail - LED off + * 10M link ok and no TX/RX activity - LED on + * 10M link ok and TX/RX activity - LED blinking + */ +#define DM8806_LED_MODE_0 ~(BIT(0) | BIT(1)) diff --git a/drivers/ethernet/phy/phy_microchip_ksz8081.c b/drivers/ethernet/phy/phy_microchip_ksz8081.c index 5f80b6591611a..d580ffd42a0fa 100644 --- a/drivers/ethernet/phy/phy_microchip_ksz8081.c +++ b/drivers/ethernet/phy/phy_microchip_ksz8081.c @@ -161,13 +161,11 @@ static int phy_mc_ksz8081_get_link(const struct device *dev, ret = phy_mc_ksz8081_read(dev, MII_BMSR, &bmsr); if (ret) { LOG_ERR("Error reading phy (%d) basic status register", config->addr); - k_mutex_unlock(&data->mutex); - return ret; + goto done; } state->is_up = bmsr & MII_BMSR_LINK_STATUS; if (!state->is_up) { - k_mutex_unlock(&data->mutex); goto result; } @@ -175,21 +173,16 @@ static int phy_mc_ksz8081_get_link(const struct device *dev, ret = phy_mc_ksz8081_read(dev, MII_ANAR, &anar); if (ret) { LOG_ERR("Error reading phy (%d) advertising register", config->addr); - k_mutex_unlock(&data->mutex); - return ret; + goto done; } /* Read link partner capability */ ret = phy_mc_ksz8081_read(dev, MII_ANLPAR, &anlpar); if (ret) { LOG_ERR("Error reading phy (%d) link partner register", config->addr); - k_mutex_unlock(&data->mutex); - return ret; + goto done; } - /* Unlock mutex */ - k_mutex_unlock(&data->mutex); - uint32_t mutual_capabilities = anar & anlpar; if (mutual_capabilities & MII_ADVERTISE_100_FULL) { @@ -214,6 +207,9 @@ static int phy_mc_ksz8081_get_link(const struct device *dev, } } +done: + k_mutex_unlock(&data->mutex); + return ret; } @@ -267,30 +263,19 @@ static int phy_mc_ksz8081_static_cfg(const struct device *dev) return 0; } -static int phy_mc_ksz8081_reset(const struct device *dev) -{ #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) - const struct mc_ksz8081_config *config = dev->config; -#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ - struct mc_ksz8081_data *data = dev->data; +static int phy_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) +{ int ret; - /* Lock mutex */ - ret = k_mutex_lock(&data->mutex, K_FOREVER); - if (ret) { - LOG_ERR("PHY mutex lock error"); - return ret; - } - -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) if (!config->reset_gpio.port) { - goto skip_reset_gpio; + return -ENODEV; } /* Start reset */ ret = gpio_pin_set_dt(&config->reset_gpio, 0); if (ret) { - goto done; + return ret; } /* Wait for at least 500 us as specified by datasheet */ @@ -302,9 +287,35 @@ static int phy_mc_ksz8081_reset(const struct device *dev) /* After deasserting reset, must wait at least 100 us to use programming interface */ k_busy_wait(200); - goto done; -skip_reset_gpio: + return ret; +} +#else +static int phy_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) +{ + ARG_UNUSED(config); + + return -ENODEV; +} #endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ + +static int phy_mc_ksz8081_reset(const struct device *dev) +{ + const struct mc_ksz8081_config *config = dev->config; + struct mc_ksz8081_data *data = dev->data; + int ret; + + /* Lock mutex */ + ret = k_mutex_lock(&data->mutex, K_FOREVER); + if (ret) { + LOG_ERR("PHY mutex lock error"); + return ret; + } + + ret = phy_ksz8081_reset_gpio(config); + if (ret != -ENODEV) { /* On -ENODEV, attempt command-based reset */ + goto done; + } + ret = phy_mc_ksz8081_write(dev, MII_BMCR, MII_BMCR_RESET); if (ret) { goto done; diff --git a/drivers/ethernet/phy/phy_microchip_t1s.c b/drivers/ethernet/phy/phy_microchip_t1s.c new file mode 100644 index 0000000000000..98ab971545fc6 --- /dev/null +++ b/drivers/ethernet/phy/phy_microchip_t1s.c @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2024 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_t1s_phy + +#include +#include +#include +#include +#include + +#define LOG_MODULE_NAME phy_mc_t1s +#define LOG_LEVEL CONFIG_PHY_LOG_LEVEL +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +/* Support: Microchip Phys: + * lan8650/1 Rev.B0/B1 Internal PHYs + * lan8670/1/2 Rev.C1/C2 PHYs + */ +/* Both Rev.B0 and B1 clause 22 PHYID's are same due to B1 chip limitation */ +#define PHY_ID_LAN865X_REVB 0x0007C1B3 +#define PHY_ID_LAN867X_REVC1 0x0007C164 +#define PHY_ID_LAN867X_REVC2 0x0007C165 + +/* Configuration param registers */ +#define LAN865X_REG_CFGPARAM_ADDR 0x00D8 +#define LAN865X_REG_CFGPARAM_DATA 0x00D9 +#define LAN865X_REG_CFGPARAM_CTRL 0x00DA +#define LAN865X_REG_STS2 0x0019 +#define LAN865X_CFGPARAM_READ_ENABLE BIT(1) + +/* Collision detection enable/disable registers */ +#define LAN86XX_DISABLE_COL_DET 0x0000 +#define LAN86XX_ENABLE_COL_DET 0x8000 +#define LAN86XX_COL_DET_MASK 0x8000 +#define LAN86XX_REG_COL_DET_CTRL0 0x0087 + +/* Structure holding configuration register address and value */ +typedef struct { + uint32_t address; + uint16_t value; +} lan865x_config; + +/* LAN865x Rev.B0/B1 configuration parameters from AN1760 + * As per the Configuration Application Note AN1760 published in the below link, + * https://www.microchip.com/en-us/application-notes/an1760 + * Revision F (DS60001760G - June 2024) + * Addresses 0x0084, 0x008A, 0x00AD, 0x00AE and 0x00AF will be updated with cfgparam1, cfgparam2, + * cfgparam3, cfgparam4 and cfgparam5 respectively. + * + * LAN867x Rev.C1/C2 configuration settings described in AN1699 are equal to + * the first 11 configuration settings and all the sqi fixup settings from + * LAN865x Rev.B0/B1. So the same fixup registers and values from LAN865x + * Rev.B0/B1 are used for LAN867x Rev.C1/C2 to avoid duplication. + * Refer the below link for the AN1699, + * https://www.microchip.com/en-us/application-notes/an1699 + * Revision E (DS60001699F - June 2024) + */ +static lan865x_config lan865x_revb_config[] = { + {.address = 0x00D0, .value = 0x3F31}, {.address = 0x00E0, .value = 0xC000}, + {.address = 0x0084, .value = 0x0000}, {.address = 0x008A, .value = 0x0000}, + {.address = 0x00E9, .value = 0x9E50}, {.address = 0x00F5, .value = 0x1CF8}, + {.address = 0x00F4, .value = 0xC020}, {.address = 0x00F8, .value = 0xB900}, + {.address = 0x00F9, .value = 0x4E53}, {.address = 0x0081, .value = 0x0080}, + {.address = 0x0091, .value = 0x9660}, {.address = 0x0043, .value = 0x00FF}, + {.address = 0x0044, .value = 0xFFFF}, {.address = 0x0045, .value = 0x0000}, + {.address = 0x0053, .value = 0x00FF}, {.address = 0x0054, .value = 0xFFFF}, + {.address = 0x0055, .value = 0x0000}, {.address = 0x0040, .value = 0x0002}, + {.address = 0x0050, .value = 0x0002}, {.address = 0x00AD, .value = 0x0000}, + {.address = 0x00AE, .value = 0x0000}, {.address = 0x00AF, .value = 0x0000}, + {.address = 0x00B0, .value = 0x0103}, {.address = 0x00B1, .value = 0x0910}, + {.address = 0x00B2, .value = 0x1D26}, {.address = 0x00B3, .value = 0x002A}, + {.address = 0x00B4, .value = 0x0103}, {.address = 0x00B5, .value = 0x070D}, + {.address = 0x00B6, .value = 0x1720}, {.address = 0x00B7, .value = 0x0027}, + {.address = 0x00B8, .value = 0x0509}, {.address = 0x00B9, .value = 0x0E13}, + {.address = 0x00BA, .value = 0x1C25}, {.address = 0x00BB, .value = 0x002B}, +}; + +struct mc_t1s_plca_config { + bool enable; + uint8_t node_id; + uint8_t node_count; + uint8_t burst_count; + uint8_t burst_timer; + uint8_t to_timer; +}; + +struct mc_t1s_config { + uint8_t phy_addr; + const struct device *mdio; + struct mc_t1s_plca_config *plca; +}; + +struct mc_t1s_data { + const struct device *dev; + struct phy_link_state state; + phy_callback_t cb; + void *cb_data; + struct k_work_delayable phy_monitor_work; +}; + +static int phy_mc_t1s_read(const struct device *dev, uint16_t reg, uint32_t *data) +{ + const struct mc_t1s_config *cfg = dev->config; + + /* Make sure excessive bits 16-31 are reset */ + *data = 0U; + + return mdio_read(cfg->mdio, cfg->phy_addr, reg, (uint16_t *)data); +} + +static int phy_mc_t1s_write(const struct device *dev, uint16_t reg, uint32_t data) +{ + const struct mc_t1s_config *cfg = dev->config; + + return mdio_write(cfg->mdio, cfg->phy_addr, reg, (uint16_t)data); +} + +static int mdio_setup_c45_indirect_access(const struct device *dev, uint16_t devad, uint16_t reg) +{ + const struct mc_t1s_config *cfg = dev->config; + int ret; + + ret = mdio_write(cfg->mdio, cfg->phy_addr, MII_MMD_ACR, devad); + if (ret) { + return ret; + } + + ret = mdio_write(cfg->mdio, cfg->phy_addr, MII_MMD_AADR, reg); + if (ret < 0) { + return ret; + } + + return mdio_write(cfg->mdio, cfg->phy_addr, MII_MMD_ACR, devad | BIT(14)); +} + +static int phy_mc_t1s_c45_read(const struct device *dev, uint8_t devad, uint16_t reg, uint16_t *val) +{ + const struct mc_t1s_config *cfg = dev->config; + int ret; + + ret = mdio_read_c45(cfg->mdio, cfg->phy_addr, devad, reg, val); + /* @retval -ENOSYS if read using Clause 45 direct access is not supported */ + if (ret == -ENOSYS) { + /* Read C45 registers using C22 indirect access registers */ + ret = mdio_setup_c45_indirect_access(dev, devad, reg); + if (ret) { + return ret; + } + + return mdio_read(cfg->mdio, cfg->phy_addr, MII_MMD_AADR, val); + } + + return ret; +} + +static int phy_mc_t1s_c45_write(const struct device *dev, uint8_t devad, uint16_t reg, uint16_t val) +{ + const struct mc_t1s_config *cfg = dev->config; + int ret; + + ret = mdio_write_c45(cfg->mdio, cfg->phy_addr, devad, reg, val); + /* @retval -ENOSYS if write using Clause 45 direct access is not supported */ + if (ret == -ENOSYS) { + /* Write C45 registers using C22 indirect access registers */ + ret = mdio_setup_c45_indirect_access(dev, devad, reg); + if (ret) { + return ret; + } + + return mdio_write(cfg->mdio, cfg->phy_addr, MII_MMD_AADR, val); + } + + return ret; +} + +static int phy_mc_t1s_get_link(const struct device *dev, struct phy_link_state *state) +{ + const struct mc_t1s_config *cfg = dev->config; + struct mc_t1s_data *data = dev->data; + struct phy_link_state old_state = data->state; + uint32_t value = 0; + int ret; + + ret = phy_mc_t1s_read(dev, MII_BMSR, &value); + if (ret) { + LOG_ERR("Failed MII_BMSR register read: %d\n", ret); + return ret; + } + + state->is_up = value & MII_BMSR_LINK_STATUS; + state->speed = LINK_HALF_10BASE_T; + + if (memcmp(&old_state, state, sizeof(struct phy_link_state)) != 0) { + if (state->is_up) { + LOG_INF("PHY (%d) Link speed 10 Mbps, half duplex\n", cfg->phy_addr); + } + } + + return 0; +} + +static int phy_mc_t1s_link_cb_set(const struct device *dev, phy_callback_t cb, void *user_data) +{ + struct mc_t1s_data *data = dev->data; + + data->cb = cb; + data->cb_data = user_data; + + if (data->cb) { + data->cb(dev, &data->state, data->cb_data); + } + + return 0; +} + +static void phy_monitor_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct mc_t1s_data *const data = CONTAINER_OF(dwork, struct mc_t1s_data, phy_monitor_work); + const struct device *dev = data->dev; + + if (!data->cb) { + return; + } + + phy_mc_t1s_get_link(dev, &data->state); + + data->cb(dev, &data->state, data->cb_data); + + /* Submit delayed work */ + k_work_reschedule(&data->phy_monitor_work, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); +} + +/* Pulled from AN1760 describing 'indirect read' + * + * write_register(0x4, 0x00D8, addr) + * write_register(0x4, 0x00DA, 0x2) + * return (int8)(read_register(0x4, 0x00D9)) + * + * 0x4 refers to memory map selector 4, which maps to MDIO_MMD_VENDOR_SPECIFIC2 + */ +static int lan865x_indirect_read(const struct device *dev, uint16_t addr, uint16_t *value) +{ + int ret; + + ret = phy_mc_t1s_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC2, LAN865X_REG_CFGPARAM_ADDR, addr); + if (ret) { + return ret; + } + + ret = phy_mc_t1s_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC2, LAN865X_REG_CFGPARAM_CTRL, + LAN865X_CFGPARAM_READ_ENABLE); + if (ret) { + return ret; + } + + return phy_mc_t1s_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC2, LAN865X_REG_CFGPARAM_DATA, + value); +} + +static int lan865x_calculate_offset(const struct device *dev, uint16_t address, int8_t *offset) +{ + uint16_t value; + int ret; + + ret = lan865x_indirect_read(dev, address, &value); + if (ret) { + return ret; + } + + /* 5-bit signed value, sign extend */ + value &= GENMASK(4, 0); + if (value & BIT(4)) { + *offset = (int8_t)((uint8_t)value - 0x20); + } else { + *offset = (int8_t)value; + } + + return 0; +} + +static void lan865x_update_cfgparam(uint32_t address, uint16_t cfgparam) +{ + for (uint8_t i = 0; i < ARRAY_SIZE(lan865x_revb_config); i++) { + if (lan865x_revb_config[i].address == address) { + lan865x_revb_config[i].value = cfgparam; + } + } +} + +static int lan865x_calculate_update_cfgparams(const struct device *dev) +{ + uint16_t cfgparam; + int8_t offset1; + int8_t offset2; + int ret; + + /* Calculate offset1 */ + ret = lan865x_calculate_offset(dev, 0x04, &offset1); + if (ret) { + return ret; + } + + /* Calculate offset2 */ + ret = lan865x_calculate_offset(dev, 0x08, &offset2); + if (ret) { + return ret; + } + + /* Calculate & update cfgparam1 for configuration */ + cfgparam = (uint16_t)(((9 + offset1) & 0x3F) << 10) | + (uint16_t)(((14 + offset1) & 0x3F) << 4) | 0x03; + lan865x_update_cfgparam(0x0084, cfgparam); + + /* Calculate & update cfgparam2 for configuration */ + cfgparam = (uint16_t)(((40 + offset2) & 0x3F) << 10); + lan865x_update_cfgparam(0x008A, cfgparam); + + /* Calculate & update cfgparam3 for configuration */ + cfgparam = (uint16_t)(((5 + offset1) & 0x3F) << 8) | (uint16_t)((9 + offset1) & 0x3F); + lan865x_update_cfgparam(0x00AD, cfgparam); + + /* Calculate & update cfgparam4 for configuration */ + cfgparam = (uint16_t)(((9 + offset1) & 0x3F) << 8) | (uint16_t)((14 + offset1) & 0x3F); + lan865x_update_cfgparam(0x00AE, cfgparam); + + /* Calculate & update cfgparam5 for configuration */ + cfgparam = (uint16_t)(((17 + offset1) & 0x3F) << 8) | (uint16_t)((22 + offset1) & 0x3F); + lan865x_update_cfgparam(0x00AF, cfgparam); + + return 0; +} + +static int phy_mc_lan865x_revb_config_init(const struct device *dev) +{ + int ret; + + ret = lan865x_calculate_update_cfgparams(dev); + if (ret) { + return ret; + } + + /* Configure lan865x initial settings */ + for (int i = 0; i < ARRAY_SIZE(lan865x_revb_config); i++) { + ret = phy_mc_t1s_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC2, + lan865x_revb_config[i].address, + lan865x_revb_config[i].value); + if (ret) { + return ret; + } + } + + return 0; +} + +/* LAN867x Rev.C1/C2 configuration settings are equal to the first 11 configuration settings and all + * the sqi fixup settings from LAN865x Rev.B0/B1. So the same fixup registers and values from + * LAN865x Rev.B0/B1 are used for LAN867x Rev.C1/C2 to avoid duplication. + * Refer the below links for the comparison. + * https://www.microchip.com/en-us/application-notes/an1760 + * Revision F (DS60001760G - June 2024) + * https://www.microchip.com/en-us/application-notes/an1699 + * Revision E (DS60001699F - June 2024) + */ +static int phy_mc_lan867x_revc_config_init(const struct device *dev) +{ + int ret; + + ret = lan865x_calculate_update_cfgparams(dev); + if (ret) { + return ret; + } + + for (int i = 0; i < ARRAY_SIZE(lan865x_revb_config); i++) { + ret = phy_mc_t1s_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC2, + lan865x_revb_config[i].address, + lan865x_revb_config[i].value); + if (ret) { + return ret; + } + + /* LAN867x Rev.C1/C2 configuration settings are equal to the first 11 configuration + * settings and all the sqi fixup settings from LAN865x Rev.B0/B1. So the 8 + * inbetween configuration settings are skipped. + */ + if (i == 10) { + i += 8; + } + } + + return 0; +} + +static int lan86xx_config_collision_detection(const struct device *dev, bool plca_enable) +{ + uint16_t val; + uint16_t new; + int ret; + + ret = phy_mc_t1s_c45_read(dev, MDIO_MMD_VENDOR_SPECIFIC2, LAN86XX_REG_COL_DET_CTRL0, &val); + if (ret) { + return ret; + } + + if (plca_enable) { + new = (val & ~LAN86XX_COL_DET_MASK) | LAN86XX_DISABLE_COL_DET; + } else { + new = (val & ~LAN86XX_COL_DET_MASK) | LAN86XX_ENABLE_COL_DET; + } + + if (new == val) { + return 0; + } + + return phy_mc_t1s_c45_write(dev, MDIO_MMD_VENDOR_SPECIFIC2, LAN86XX_REG_COL_DET_CTRL0, new); +} + +static int phy_mc_t1s_cfg_link(const struct device *dev, enum phy_link_speed speeds) +{ + ARG_UNUSED(dev); + + if (speeds & LINK_HALF_10BASE_T) { + return 0; + } + + return -ENOTSUP; +} + +static int phy_mc_t1s_id(const struct device *dev, uint32_t *phy_id) +{ + uint32_t value; + int ret; + + ret = phy_mc_t1s_read(dev, MII_PHYID1R, &value); + if (ret) { + LOG_ERR("Failed MII_PHYID1R register read: %d\n", ret); + return ret; + } + + *phy_id = value << 16; + + ret = phy_mc_t1s_read(dev, MII_PHYID2R, &value); + if (ret) { + LOG_ERR("Failed MII_PHYID2R register read: %d\n", ret); + return ret; + } + + *phy_id |= value; + + return 0; +} + +static int phy_mc_t1s_set_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg) +{ + int ret; + + ret = genphy_set_plca_cfg(dev, plca_cfg); + if (ret) { + return ret; + } + + return lan86xx_config_collision_detection(dev, plca_cfg->enable); +} + +static int phy_mc_t1s_set_dt_plca(const struct device *dev) +{ + const struct mc_t1s_config *cfg = dev->config; + struct phy_plca_cfg plca_cfg; + + if (!cfg->plca->enable) { + return 0; + } + + plca_cfg.enable = cfg->plca->enable; + plca_cfg.node_id = cfg->plca->node_id; + plca_cfg.node_count = cfg->plca->node_count; + plca_cfg.burst_count = cfg->plca->burst_count; + plca_cfg.burst_timer = cfg->plca->burst_timer; + plca_cfg.to_timer = cfg->plca->to_timer; + + return phy_mc_t1s_set_plca_cfg(dev, &plca_cfg); +} + +static int phy_mc_t1s_init(const struct device *dev) +{ + struct mc_t1s_data *data = dev->data; + uint32_t phy_id; + int ret; + + data->dev = dev; + + ret = phy_mc_t1s_id(dev, &phy_id); + if (ret) { + return ret; + } + + switch (phy_id) { + case PHY_ID_LAN867X_REVC1: + case PHY_ID_LAN867X_REVC2: + ret = phy_mc_lan867x_revc_config_init(dev); + if (ret) { + LOG_ERR("PHY initial configuration error: %d\n", ret); + return ret; + } + break; + case PHY_ID_LAN865X_REVB: + ret = phy_mc_lan865x_revb_config_init(dev); + if (ret) { + LOG_ERR("PHY initial configuration error: %d\n", ret); + return ret; + } + break; + default: + LOG_ERR("Unsupported PHY ID: %x\n", phy_id); + return -ENODEV; + } + + ret = phy_mc_t1s_set_dt_plca(dev); + if (ret) { + return ret; + } + + k_work_init_delayable(&data->phy_monitor_work, phy_monitor_work_handler); + phy_monitor_work_handler(&data->phy_monitor_work.work); + + return 0; +} + +static DEVICE_API(ethphy, mc_t1s_phy_api) = { + .get_link = phy_mc_t1s_get_link, + .cfg_link = phy_mc_t1s_cfg_link, + .link_cb_set = phy_mc_t1s_link_cb_set, + .set_plca_cfg = phy_mc_t1s_set_plca_cfg, + .get_plca_cfg = genphy_get_plca_cfg, + .get_plca_sts = genphy_get_plca_sts, + .read = phy_mc_t1s_read, + .write = phy_mc_t1s_write, + .read_c45 = phy_mc_t1s_c45_read, + .write_c45 = phy_mc_t1s_c45_write, +}; + +#define MICROCHIP_T1S_PHY_INIT(n) \ + static struct mc_t1s_plca_config mc_t1s_plca_##n##_config = { \ + .enable = DT_INST_PROP(n, plca_enable), \ + .node_id = DT_INST_PROP(n, plca_node_id), \ + .node_count = DT_INST_PROP(n, plca_node_count), \ + .burst_count = DT_INST_PROP(n, plca_burst_count), \ + .burst_timer = DT_INST_PROP(n, plca_burst_timer), \ + .to_timer = DT_INST_PROP(n, plca_to_timer), \ + }; \ + \ + static const struct mc_t1s_config mc_t1s_##n##_config = { \ + .phy_addr = DT_INST_REG_ADDR(n), \ + .mdio = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .plca = &mc_t1s_plca_##n##_config, \ + }; \ + \ + static struct mc_t1s_data mc_t1s_##n##_data; \ + \ + DEVICE_DT_INST_DEFINE(n, &phy_mc_t1s_init, NULL, &mc_t1s_##n##_data, &mc_t1s_##n##_config, \ + POST_KERNEL, CONFIG_PHY_MICROCHIP_T1S_INIT_PRIORITY, &mc_t1s_phy_api); + +DT_INST_FOREACH_STATUS_OKAY(MICROCHIP_T1S_PHY_INIT); diff --git a/drivers/ethernet/phy/phy_microchip_vsc8541.c b/drivers/ethernet/phy/phy_microchip_vsc8541.c new file mode 100644 index 0000000000000..9a0c3267f6b1e --- /dev/null +++ b/drivers/ethernet/phy/phy_microchip_vsc8541.c @@ -0,0 +1,576 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 sensry.io + */ + +#define DT_DRV_COMPAT microchip_vsc8541 + +#include +LOG_MODULE_REGISTER(microchip_vsc8541, CONFIG_PHY_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include + +/* phy page selectors */ +#define PHY_PAGE_0 0x00 /* main registers space active */ +#define PHY_PAGE_1 0x01 /* reg 16 - 30 will be redirected to ext. register space 1 */ +#define PHY_PAGE_2 0x02 /* reg 16 - 30 will be redirected to ext. register space 2 */ +#define PHY_PAGE_3 0x03 /* reg 0 - 30 will be redirected to gpio register space */ + +/* virtual register, treat higher byte as page selector and lower byte is register */ +#define PHY_REG(page, reg) ((page << 8) | (reg << 0)) + +/* Generic Register */ +#define PHY_REG_PAGE0_BMCR PHY_REG(PHY_PAGE_0, 0x00) +#define PHY_REG_PAGE0_BMSR PHY_REG(PHY_PAGE_0, 0x01) +#define PHY_REG_PAGE0_ID1 PHY_REG(PHY_PAGE_0, 0x02) +#define PHY_REG_PAGE0_ID2 PHY_REG(PHY_PAGE_0, 0x03) +#define PHY_REG_PAGE0_ADV PHY_REG(PHY_PAGE_0, 0x04) +#define PHY_REG_LPA 0x05 +#define PHY_REG_EXP 0x06 +#define PHY_REG_PAGE0_CTRL1000 PHY_REG(PHY_PAGE_0, 0x09) +#define PHY_REG_PAGE0_STAT1000 PHY_REG(0, 0x0A) +#define PHY_REG_MMD_CTRL 0x0D +#define PHY_REG_MMD_DATA 0x0E +#define PHY_REG_STAT1000_EXT1 0x0F +#define PHY_REG_PAGE0_STAT100 PHY_REG(PHY_PAGE_0, 0x10) +#define PHY_REG_PAGE0_STAT1000_EXT2 PHY_REG(PHY_PAGE_0, 0x11) +#define PHY_REG_AUX_CTRL 0x12 +#define PHY_REG_PAGE0_ERROR_COUNTER_1 PHY_REG(0, 0x13) +#define PHY_REG_PAGE0_ERROR_COUNTER_2 PHY_REG(0, 0x14) +#define PHY_REG_PAGE0_EXT_CTRL_STAT PHY_REG(PHY_PAGE_0, 0x16) +#define PHY_REG_PAGE0_EXT_CONTROL_1 PHY_REG(PHY_PAGE_0, 0x17) +#define PHY_REG_LED_MODE 0x1d + +#define PHY_REG_PAGE_SELECTOR 0x1F + +/* Extended Register */ +#define PHY_REG_PAGE1_EXT_MODE_CTRL PHY_REG(PHY_PAGE_1, 0x13) +#define PHY_REG_PAGE2_RGMII_CONTROL PHY_REG(PHY_PAGE_2, 0x14) +#define PHY_REG_PAGE2_MAC_IF_CONTROL PHY_REG(PHY_PAGE_2, 0x1b) + +/* selected bits in registers */ +#define BMCR_RESET (1 << 15) +#define BMCR_LOOPBACK (1 << 14) +#define BMCR_ANENABLE (1 << 12) +#define BMCR_ANRESTART (1 << 9) +#define BMCR_FULLDPLX (1 << 8) +#define BMCR_SPEED10 ((0 << 13) | (0 << 6)) +#define BMCR_SPEED100 ((1 << 13) | (0 << 6)) +#define BMCR_SPEED1000 ((0 << 13) | (1 << 6)) + +#define BMCR_SPEEDMASK ((1 << 13) | (1 << 6)) + +#define BMSR_LSTATUS (1 << 2) + +enum vsc8541_interface { + VSC8541_MII, + VSC8541_RMII, + VSC8541_GMII, + VSC8541_RGMII, +}; + +/* Thread stack size */ +#define STACK_SIZE 512 + +/* Thread priority */ +#define THREAD_PRIORITY 7 + +struct mc_vsc8541_config { + uint8_t addr; + const struct device *mdio_dev; + enum vsc8541_interface microchip_interface_type; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + const struct gpio_dt_spec reset_gpio; +#endif +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) + const struct gpio_dt_spec interrupt_gpio; +#endif +}; + +struct mc_vsc8541_data { + const struct device *dev; + + struct phy_link_state state; + int active_page; + + struct k_mutex mutex; + + phy_callback_t cb; + void *cb_data; + + struct k_thread link_monitor_thread; + uint8_t link_monitor_thread_stack[STACK_SIZE]; +}; + +static int phy_mc_vsc8541_read(const struct device *dev, uint16_t reg_addr, uint32_t *data); +static int phy_mc_vsc8541_write(const struct device *dev, uint16_t reg_addr, uint32_t data); +static void phy_mc_vsc8541_link_monitor(void *arg1, void *arg2, void *arg3); + +#if CONFIG_PHY_VERIFY_DEVICE_IDENTIFICATION +/** + * @brief Reads the phy manufacture id and compares to designed, known model version + */ +static int phy_mc_vsc8541_verify_phy_id(const struct device *dev) +{ + uint16_t phy_id_1; + uint16_t phy_id_2; + + if (0 != phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_ID1, (uint32_t *)&phy_id_1)) { + return -EINVAL; + } + + if (0 != phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_ID2, (uint32_t *)&phy_id_2)) { + return -EINVAL; + } + + if (phy_id_1 == 0x0007) { + if (phy_id_2 == 0x0771) { + LOG_INF("model vsc8541-01 rev b"); + return 0; + } + if (phy_id_2 == 0x0772) { + LOG_INF("model vsc8541-02/-05 rev c"); + return 0; + } + } + + LOG_INF("phy id is %#.4x - %#.4x", phy_id_1, phy_id_2); + return -EINVAL; +} +#endif + +/** + * @brief Low level reset procedure that toggles the reset gpio + */ +static int phy_mc_vsc8541_reset(const struct device *dev) +{ + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + const struct mc_vsc8541_config *cfg = dev->config; + + if (!cfg->reset_gpio.port) { + LOG_WRN("missing reset port definition"); + return -EINVAL; + } + + /* configure the reset pin */ + int ret = gpio_pin_configure_dt(&cfg->reset_gpio, GPIO_OUTPUT_ACTIVE); + + if (ret) { + return ret; + } + + for (uint32_t i = 0; i < 2; i++) { + /* Start reset */ + ret = gpio_pin_set_dt(&cfg->reset_gpio, 0); + if (ret) { + LOG_WRN("failed to set reset gpio"); + return -EINVAL; + } + + /* Wait as specified by datasheet */ + k_sleep(K_MSEC(200)); + + /* Reset over */ + gpio_pin_set_dt(&cfg->reset_gpio, 1); + + /* After de-asserting reset, must wait before using the config interface */ + k_sleep(K_MSEC(200)); + } +#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) */ + + /* According to IEEE 802.3, Section 2, Subsection 22.2.4.1.1, + * a PHY reset may take up to 0.5 s. + */ + k_sleep(K_MSEC(500)); + +#if CONFIG_PHY_VERIFY_DEVICE_IDENTIFICATION + /* confirm phy organizationally unique identifier, if enabled */ + if (0 != phy_mc_vsc8541_verify_phy_id(dev)) { + LOG_ERR("failed to verify phy id"); + return -EINVAL; + } +#endif + + /* set RGMII mode (must be executed BEFORE software reset -- see datasheet) */ + if (cfg->microchip_interface_type == VSC8541_RGMII) { + ret = phy_mc_vsc8541_write(dev, PHY_REG_PAGE0_EXT_CONTROL_1, + (0x0 << 13) | (0x2 << 11)); + if (ret) { + return ret; + } + } + + /* software reset */ + ret = phy_mc_vsc8541_write(dev, PHY_REG_PAGE0_BMCR, MII_BMCR_RESET); + if (ret) { + return ret; + } + + /* wait for phy finished software reset */ + uint32_t reg = 0; + + do { + phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_BMCR, ®); + } while (reg & BMCR_RESET); + + /* forced MDI-X */ + ret = phy_mc_vsc8541_write(dev, PHY_REG_PAGE1_EXT_MODE_CTRL, (3 << 2)); + if (ret) { + return ret; + } + + /* configure the RGMII clk delay */ + /* this is highly hardware dependent and may vary between pcb designs */ + reg = 0x0; + /* RX_CLK delay */ + reg |= (0x5 << 4); + /* TX_CLK delay */ + reg |= (0x5 << 0); + ret = phy_mc_vsc8541_write(dev, PHY_REG_PAGE2_RGMII_CONTROL, reg); + if (ret) { + return ret; + } + + /* we use limited advertising, to force gigabit speed */ + /* initial version of this driver supports only 1GB/s */ + + /* 1000MBit/s + AUTO */ + ret = phy_mc_vsc8541_write(dev, PHY_REG_PAGE0_ADV, (1 << 8) | (1 << 6) | 0x01); + if (ret) { + return ret; + } + + ret = phy_mc_vsc8541_write(dev, PHY_REG_PAGE0_CTRL1000, (1 << 12) | (1 << 11) | (1 << 9)); + if (ret) { + return ret; + } + + /* start auto negotiation */ + ret = phy_mc_vsc8541_write(dev, PHY_REG_PAGE0_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); + if (ret) { + return ret; + } + + return ret; +} + +/** + * @brief Update the phy state with current speed given by readings of the phy + * + * @param dev device structure of the phy + * @param state being updated (we only update speed here) + */ +static int phy_mc_vsc8541_get_speed(const struct device *dev, struct phy_link_state *state) +{ + int ret; + uint32_t status; + uint32_t link10_status; + uint32_t link100_status; + uint32_t link1000_status; + + ret = phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_BMSR, &status); + if (ret) { + return ret; + } + + ret = phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_EXT_CTRL_STAT, &link10_status); + if (ret) { + return ret; + } + + ret = phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_STAT100, &link100_status); + if (ret) { + return ret; + } + + ret = phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_STAT1000_EXT2, &link1000_status); + if (ret) { + return ret; + } + + if ((status & (1 << 2)) == 0) { + /* no link */ + state->speed = LINK_HALF_10BASE_T; + } + + if ((status & (1 << 5)) == 0) { + /* auto negotiation not yet complete */ + state->speed = LINK_HALF_10BASE_T; + } + + if ((link1000_status & (1 << 12))) { + state->speed = LINK_FULL_1000BASE_T; + } + if (link100_status & (1 << 12)) { + state->speed = LINK_FULL_100BASE_T; + } + if (link10_status & (1 << 6)) { + state->speed = LINK_FULL_10BASE_T; + } + + return 0; +} + +/** + * @brief Initializes the phy and starts the link monitor + * + */ +static int phy_mc_vsc8541_init(const struct device *dev) +{ + struct mc_vsc8541_data *data = dev->data; + + data->cb = NULL; + data->cb_data = NULL; + data->state.is_up = false; + data->state.speed = LINK_HALF_10BASE_T; + data->active_page = -1; + + /* Reset PHY */ + int ret = phy_mc_vsc8541_reset(dev); + + if (ret) { + LOG_ERR("initialize failed"); + return ret; + } + + /* setup thread to watch link state */ + k_thread_create(&data->link_monitor_thread, + (k_thread_stack_t *)data->link_monitor_thread_stack, STACK_SIZE, + phy_mc_vsc8541_link_monitor, (void *)dev, NULL, NULL, THREAD_PRIORITY, 0, + K_NO_WAIT); + + k_thread_name_set(&data->link_monitor_thread, "phy-link-mon"); + + return 0; +} + +/** + * @brief Update the link status with readings from phy + * + * @param dev device structure to phy + * @param state which is being updated + */ +static int phy_mc_vsc8541_get_link(const struct device *dev, struct phy_link_state *state) +{ + int ret; + uint32_t reg_sr; + uint32_t reg_cr; + + ret = phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_BMSR, ®_sr); + if (ret) { + return ret; + } + + ret = phy_mc_vsc8541_read(dev, PHY_REG_PAGE0_BMCR, ®_cr); + if (ret) { + return ret; + } + + uint32_t hasLink = reg_sr & (1 << 2) ? 1 : 0; + + uint32_t auto_negotiation_finished; + + if (reg_cr & (BMCR_ANENABLE)) { + /* auto negotiation active; update status */ + auto_negotiation_finished = reg_sr & (1 << 5) ? 1 : 0; + } else { + auto_negotiation_finished = 1; + } + + if (hasLink & auto_negotiation_finished) { + state->is_up = 1; + ret = phy_mc_vsc8541_get_speed(dev, state); + if (ret) { + return ret; + } + } else { + state->is_up = 0; + state->speed = LINK_HALF_10BASE_T; + } + + return 0; +} + +/** + * @brief Reconfigure the link speed; currently unused + * + */ +static int phy_mc_vsc8541_cfg_link(const struct device *dev, enum phy_link_speed speeds) +{ + /* the initial version does not support reconfiguration */ + return -ENOTSUP; +} + +/** + * @brief Set callback which is used to announce link status changes + * + * @param dev device structure to phy device + * @param cb + * @param user_data + */ +static int phy_mc_vsc8541_link_cb_set(const struct device *dev, phy_callback_t cb, void *user_data) +{ + struct mc_vsc8541_data *data = dev->data; + + data->cb = cb; + data->cb_data = user_data; + + phy_mc_vsc8541_get_link(dev, &data->state); + + data->cb(dev, &data->state, data->cb_data); + + return 0; +} + +/** + * @brief Monitor thread to check the link state and announce if changed + * + * @param arg1 provides a pointer to device structure + * @param arg2 not used + * @param arg3 not used + */ +void phy_mc_vsc8541_link_monitor(void *arg1, void *arg2, void *arg3) +{ + const struct device *dev = arg1; + struct mc_vsc8541_data *data = dev->data; + const struct mc_vsc8541_config *cfg = dev->config; + + struct phy_link_state new_state; + + while (1) { + k_sleep(K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); + phy_mc_vsc8541_get_link(dev, &new_state); + + if ((new_state.is_up != data->state.is_up) || + (new_state.speed != data->state.speed)) { + /* state changed */ + data->state.is_up = new_state.is_up; + data->state.speed = new_state.speed; + + if (data->cb) { + /* announce new state */ + data->cb(dev, &data->state, data->cb_data); + } + } + } +} + +/** + * @brief Reading of phy register content at given address via mdio interface + * + * - high byte of register address defines page + * - low byte of register address defines the address within selected page + * - to speed up, we store the last used page and only swap page if needed + * + */ +static int phy_mc_vsc8541_read(const struct device *dev, uint16_t reg_addr, uint32_t *data) +{ + const struct mc_vsc8541_config *cfg = dev->config; + struct mc_vsc8541_data *dev_data = dev->data; + int ret; + + *data = 0U; + + /* decode page */ + uint32_t page = reg_addr >> 8; + + /* mask out lower byte */ + reg_addr &= 0x00ff; + + /* select page, given by register upper byte */ + if (dev_data->active_page != page) { + ret = mdio_write(cfg->mdio_dev, cfg->addr, PHY_REG_PAGE_SELECTOR, (uint16_t)page); + if (ret) { + return ret; + } + dev_data->active_page = (int)page; + } + + /* select register, given by register lower byte */ + ret = mdio_read(cfg->mdio_dev, cfg->addr, reg_addr, (uint16_t *)data); + if (ret) { + return ret; + } + + return 0; +} + +/** + * @brief Writing of new value to phy register at given address via mdio interface + * + * - high byte of register address defines page + * - low byte of register address defines the address within selected page + * - to speed up, we store the last used page and only swap page if needed + * + */ +static int phy_mc_vsc8541_write(const struct device *dev, uint16_t reg_addr, uint32_t data) +{ + const struct mc_vsc8541_config *cfg = dev->config; + struct mc_vsc8541_data *dev_data = dev->data; + int ret; + + /* decode page */ + uint32_t page = reg_addr >> 8; + + /* mask out lower byte */ + reg_addr &= 0x00ff; + + /* select page, given by register upper byte */ + if (dev_data->active_page != page) { + ret = mdio_write(cfg->mdio_dev, cfg->addr, PHY_REG_PAGE_SELECTOR, (uint16_t)page); + if (ret) { + return ret; + } + dev_data->active_page = (int)page; + } + + /* write register, given by lower byte */ + ret = mdio_write(cfg->mdio_dev, cfg->addr, reg_addr, (uint16_t)data); + if (ret) { + return ret; + } + + return 0; +} + +static DEVICE_API(ethphy, mc_vsc8541_phy_api) = { + .get_link = phy_mc_vsc8541_get_link, + .cfg_link = phy_mc_vsc8541_cfg_link, + .link_cb_set = phy_mc_vsc8541_link_cb_set, + .read = phy_mc_vsc8541_read, + .write = phy_mc_vsc8541_write, +}; + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) +#define RESET_GPIO(n) .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), +#else +#define RESET_GPIO(n) +#endif /* reset gpio */ + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) +#define INTERRUPT_GPIO(n) .interrupt_gpio = GPIO_DT_SPEC_INST_GET_OR(n, int_gpios, {0}), +#else +#define INTERRUPT_GPIO(n) +#endif /* interrupt gpio */ + +#define MICROCHIP_VSC8541_INIT(n) \ + static const struct mc_vsc8541_config mc_vsc8541_##n##_config = { \ + .addr = DT_INST_REG_ADDR(n), \ + .mdio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .microchip_interface_type = DT_INST_ENUM_IDX(n, microchip_interface_type), \ + RESET_GPIO(n) INTERRUPT_GPIO(n)}; \ + \ + static struct mc_vsc8541_data mc_vsc8541_##n##_data; \ + \ + DEVICE_DT_INST_DEFINE(n, &phy_mc_vsc8541_init, NULL, &mc_vsc8541_##n##_data, \ + &mc_vsc8541_##n##_config, POST_KERNEL, CONFIG_PHY_INIT_PRIORITY, \ + &mc_vsc8541_phy_api); + +DT_INST_FOREACH_STATUS_OKAY(MICROCHIP_VSC8541_INIT) diff --git a/drivers/ethernet/phy/phy_oa_tc14_plca.c b/drivers/ethernet/phy/phy_oa_tc14_plca.c new file mode 100644 index 0000000000000..1505bae8f78a1 --- /dev/null +++ b/drivers/ethernet/phy/phy_oa_tc14_plca.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2024 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* Open Alliance TC14 (10BASE-T1S) PLCA registers */ +#define MDIO_OATC14_PLCA_IDVER 0xca00 /* PLCA ID and version */ +#define MDIO_OATC14_PLCA_CTRL0 0xca01 /* PLCA Control register 0 */ +#define MDIO_OATC14_PLCA_CTRL1 0xca02 /* PLCA Control register 1 */ +#define MDIO_OATC14_PLCA_STATUS 0xca03 /* PLCA Status register */ +#define MDIO_OATC14_PLCA_TOTMR 0xca04 /* PLCA TO Timer register */ +#define MDIO_OATC14_PLCA_BURST 0xca05 /* PLCA BURST mode register */ + +/* Open Alliance TC14 PLCA IDVER register */ +#define MDIO_OATC14_PLCA_IDM GENMASK(15, 8) /* PLCA MAP ID */ +#define MDIO_OATC14_PLCA_VER GENMASK(7, 0) /* PLCA MAP version */ + +/* Open Alliance TC14 PLCA CTRL0 register */ +#define MDIO_OATC14_PLCA_EN BIT(15) /* PLCA enable */ +#define MDIO_OATC14_PLCA_RST BIT(14) /* PLCA reset */ + +/* Open Alliance TC14 PLCA CTRL1 register */ +#define MDIO_OATC14_PLCA_NCNT GENMASK(15, 8) /* PLCA node count */ +#define MDIO_OATC14_PLCA_ID GENMASK(7, 0) /* PLCA local node ID */ + +/* Open Alliance TC14 PLCA STATUS register */ +#define MDIO_OATC14_PLCA_PST BIT(15) /* PLCA status indication */ + +/* Open Alliance TC14 PLCA TOTMR register */ +#define MDIO_OATC14_PLCA_TOT GENMASK(7, 0) + +/* Open Alliance TC14 PLCA BURST register */ +#define MDIO_OATC14_PLCA_MAXBC GENMASK(15, 8) +#define MDIO_OATC14_PLCA_BTMR GENMASK(7, 0) + +/* Version Identifiers */ +#define OATC14_IDM 0x0a00 + +int genphy_set_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg) +{ + uint16_t val; + int ret; + + /* Disable plca before doing the configuration */ + ret = phy_write_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_CTRL0, 0x0); + if (ret) { + return ret; + } + + if (!plca_cfg->enable) { + /* As the PLCA is disabled above, just return */ + return 0; + } + + val = (plca_cfg->node_count << 8) | plca_cfg->node_id; + ret = phy_write_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_CTRL1, val); + if (ret) { + return ret; + } + + val = (plca_cfg->burst_count << 8) | plca_cfg->burst_timer; + ret = phy_write_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_BURST, val); + if (ret) { + return ret; + } + + ret = phy_write_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_TOTMR, + plca_cfg->to_timer); + if (ret) { + return ret; + } + + /* Enable plca after doing all the configuration */ + return phy_write_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_CTRL0, + MDIO_OATC14_PLCA_EN); +} + +int genphy_get_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg) +{ + uint16_t val; + int ret; + + ret = phy_read_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_IDVER, &val); + if (ret) { + return ret; + } + + if ((val & MDIO_OATC14_PLCA_IDM) != OATC14_IDM) { + return -ENODEV; + } + + plca_cfg->version = ret & ~MDIO_OATC14_PLCA_IDM; + + ret = phy_read_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_CTRL0, &val); + if (ret) { + return ret; + } + + plca_cfg->enable = !!(val & MDIO_OATC14_PLCA_EN); + + ret = phy_read_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_CTRL1, &val); + if (ret) { + return ret; + } + + plca_cfg->node_id = val & MDIO_OATC14_PLCA_ID; + plca_cfg->node_count = (val & MDIO_OATC14_PLCA_NCNT) >> 8; + + ret = phy_read_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_BURST, &val); + if (ret) { + return ret; + } + + plca_cfg->burst_timer = val & MDIO_OATC14_PLCA_BTMR; + plca_cfg->burst_count = (val & MDIO_OATC14_PLCA_MAXBC) >> 8; + + ret = phy_read_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_TOTMR, &val); + if (ret) { + return ret; + } + + plca_cfg->to_timer = val & MDIO_OATC14_PLCA_TOT; + + return 0; +} + +int genphy_get_plca_sts(const struct device *dev, bool *plca_sts) +{ + uint16_t val; + int ret; + + ret = phy_read_c45(dev, MDIO_MMD_VENDOR_SPECIFIC2, MDIO_OATC14_PLCA_STATUS, &val); + if (ret) { + return ret; + } + + *plca_sts = !!(val & MDIO_OATC14_PLCA_PST); + + return 0; +} diff --git a/drivers/firmware/scmi/CMakeLists.txt b/drivers/firmware/scmi/CMakeLists.txt index 68e4c7a787cb8..fbd52e6ed2d1d 100644 --- a/drivers/firmware/scmi/CMakeLists.txt +++ b/drivers/firmware/scmi/CMakeLists.txt @@ -10,3 +10,4 @@ zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_SHMEM shmem.c) # SCMI protocol helper files zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_CLK_HELPERS clk.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_PINCTRL_HELPERS pinctrl.c) +zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_POWER_DOMAIN_HELPERS power.c) diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index 1b4415452e675..93c1b1189636d 100644 --- a/drivers/firmware/scmi/Kconfig +++ b/drivers/firmware/scmi/Kconfig @@ -28,6 +28,13 @@ config ARM_SCMI_PINCTRL_HELPERS help Enable support for SCMI pinctrl protocol helper functions. +config ARM_SCMI_POWER_DOMAIN_HELPERS + bool "Helper functions for SCMI power domain protocol" + default y + depends on DT_HAS_ARM_SCMI_POWER_ENABLED + help + Enable support for SCMI power domain protocol helper functions. + config ARM_SCMI_SHMEM bool "SCMI shared memory (SHMEM) driver" default y diff --git a/drivers/firmware/scmi/clk.c b/drivers/firmware/scmi/clk.c index 415349586eeb1..1abd04f1c49a0 100644 --- a/drivers/firmware/scmi/clk.c +++ b/drivers/firmware/scmi/clk.c @@ -22,6 +22,16 @@ struct scmi_clock_rate_set_reply { uint32_t rate[2]; }; +struct scmi_clock_parent_get_reply { + int32_t status; + uint32_t parent_id; +}; + +struct scmi_clock_parent_config { + uint32_t clk_id; + uint32_t parent_id; +}; + int scmi_clock_rate_get(struct scmi_protocol *proto, uint32_t clk_id, uint32_t *rate) { @@ -61,6 +71,119 @@ int scmi_clock_rate_get(struct scmi_protocol *proto, return 0; } +int scmi_clock_rate_set(struct scmi_protocol *proto, struct scmi_clock_rate_config *cfg) +{ + struct scmi_message msg, reply; + int status, ret; + + /* sanity checks */ + if (!proto || !cfg) { + return -EINVAL; + } + + if (proto->id != SCMI_PROTOCOL_CLOCK) { + return -EINVAL; + } + + /* Currently ASYNC flag is not supported. */ + if (cfg->flags & SCMI_CLK_RATE_SET_FLAGS_ASYNC) { + return -ENOTSUP; + } + + msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_CLK_MSG_CLOCK_RATE_SET, SCMI_COMMAND, proto->id, 0x0); + msg.len = sizeof(*cfg); + msg.content = cfg; + + reply.hdr = msg.hdr; + reply.len = sizeof(status); + reply.content = &status; + + ret = scmi_send_message(proto, &msg, &reply); + if (ret < 0) { + return ret; + } + + if (status != SCMI_SUCCESS) { + return scmi_status_to_errno(status); + } + + return 0; +} + +int scmi_clock_parent_get(struct scmi_protocol *proto, uint32_t clk_id, uint32_t *parent_id) +{ + struct scmi_message msg, reply; + int ret; + struct scmi_clock_parent_get_reply reply_buffer; + + /* sanity checks */ + if (!proto || !parent_id) { + return -EINVAL; + } + + if (proto->id != SCMI_PROTOCOL_CLOCK) { + return -EINVAL; + } + + msg.hdr = + SCMI_MESSAGE_HDR_MAKE(SCMI_CLK_MSG_CLOCK_PARENT_GET, SCMI_COMMAND, proto->id, 0x0); + msg.len = sizeof(clk_id); + msg.content = &clk_id; + + reply.hdr = msg.hdr; + reply.len = sizeof(reply_buffer); + reply.content = &reply_buffer; + + ret = scmi_send_message(proto, &msg, &reply); + if (ret < 0) { + return ret; + } + + if (reply_buffer.status != SCMI_SUCCESS) { + return scmi_status_to_errno(reply_buffer.status); + } + + *parent_id = reply_buffer.parent_id; + + return 0; +} + +int scmi_clock_parent_set(struct scmi_protocol *proto, uint32_t clk_id, uint32_t parent_id) +{ + struct scmi_clock_parent_config cfg = {.clk_id = clk_id, .parent_id = parent_id}; + struct scmi_message msg, reply; + int status, ret; + + /* sanity checks */ + if (!proto) { + return -EINVAL; + } + + if (proto->id != SCMI_PROTOCOL_CLOCK) { + return -EINVAL; + } + + msg.hdr = + SCMI_MESSAGE_HDR_MAKE(SCMI_CLK_MSG_CLOCK_PARENT_SET, SCMI_COMMAND, proto->id, 0x0); + msg.len = sizeof(cfg); + msg.content = &cfg; + + reply.hdr = msg.hdr; + reply.len = sizeof(status); + reply.content = &status; + + ret = scmi_send_message(proto, &msg, &reply); + if (ret < 0) { + return ret; + } + + if (status != SCMI_SUCCESS) { + return scmi_status_to_errno(status); + } + + return 0; +} + int scmi_clock_config_set(struct scmi_protocol *proto, struct scmi_clock_config *cfg) { diff --git a/drivers/firmware/scmi/power.c b/drivers/firmware/scmi/power.c new file mode 100644 index 0000000000000..e2c639a03fc36 --- /dev/null +++ b/drivers/firmware/scmi/power.c @@ -0,0 +1,95 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, arm_scmi_power), NULL); + +struct scmi_power_state_get_reply { + int32_t status; + uint32_t power_state; +}; + +int scmi_power_state_get(uint32_t domain_id, uint32_t *power_state) +{ + struct scmi_protocol *proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_POWER_DOMAIN); + struct scmi_power_state_get_reply reply_buffer; + struct scmi_message msg, reply; + int ret; + + /* sanity checks */ + if (!proto || !power_state) { + return -EINVAL; + } + + if (proto->id != SCMI_PROTOCOL_POWER_DOMAIN) { + return -EINVAL; + } + + msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_POWER_DOMAIN_MSG_POWER_STATE_GET, SCMI_COMMAND, + proto->id, 0x0); + msg.len = sizeof(domain_id); + msg.content = &domain_id; + + reply.hdr = msg.hdr; + reply.len = sizeof(reply_buffer); + reply.content = &reply_buffer; + + ret = scmi_send_message(proto, &msg, &reply); + if (ret < 0) { + return ret; + } + + if (reply_buffer.status != SCMI_SUCCESS) { + return scmi_status_to_errno(reply_buffer.status); + } + + *power_state = reply_buffer.power_state; + + return 0; +} + +int scmi_power_state_set(struct scmi_power_state_config *cfg) +{ + struct scmi_protocol *proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_POWER_DOMAIN); + struct scmi_message msg, reply; + int status, ret; + + /* sanity checks */ + if (!proto || !cfg) { + return -EINVAL; + } + + if (proto->id != SCMI_PROTOCOL_POWER_DOMAIN) { + return -EINVAL; + } + + /* Currently ASYNC flag is not supported. */ + if (cfg->flags & SCMI_POWER_STATE_SET_FLAGS_ASYNC) { + return -ENOTSUP; + } + + msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_POWER_DOMAIN_MSG_POWER_STATE_SET, SCMI_COMMAND, + proto->id, 0x0); + msg.len = sizeof(*cfg); + msg.content = cfg; + + reply.hdr = msg.hdr; + reply.len = sizeof(status); + reply.content = &status; + + ret = scmi_send_message(proto, &msg, &reply); + if (ret < 0) { + return ret; + } + + if (status != SCMI_SUCCESS) { + return scmi_status_to_errno(status); + } + + return 0; +} diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 4bc76b2d5165f..474205e397350 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -43,6 +43,7 @@ zephyr_library_sources_ifdef(CONFIG_FLASH_STM32_XSPI flash_stm32_xspi.c) zephyr_library_sources_ifdef(CONFIG_INFINEON_CAT1_QSPI_FLASH flash_ifx_cat1_qspi.c) zephyr_library_sources_ifdef(CONFIG_NORDIC_QSPI_NOR nrf_qspi_nor.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_CC13XX_CC26XX soc_flash_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_CC23X0 soc_flash_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ESP32 flash_esp32.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_GECKO flash_gecko.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ITE_IT8XXX2 flash_ite_it8xxx2.c) @@ -59,6 +60,7 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_RV32M1 soc_flash_rv32m1.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_SAM flash_sam.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_SAM0 flash_sam0.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_SI32 flash_si32.c) +zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_SILABS_SIWX91X soc_flash_silabs_siwx91x.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_SMARTBOND flash_smartbond.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_TELINK_B91 soc_flash_b91.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_XMC4XXX soc_flash_xmc4xxx.c) @@ -90,13 +92,14 @@ if(CONFIG_FLASH_MCUX_FLEXSPI_XIP) endif() if(CONFIG_SOC_FLASH_STM32) + zephyr_library_sources_ifdef(CONFIG_FLASH_EX_OP_ENABLED flash_stm32_ex_op.c) if(CONFIG_SOC_SERIES_STM32H7X) zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_STM32H7_FLASH_CONTROLLER_ENABLED flash_stm32h7x.c) elseif(CONFIG_SOC_SERIES_STM32H7RSX) zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_STM32H7_FLASH_CONTROLLER_ENABLED flash_stm32h7x.c) elseif(CONFIG_SOC_SERIES_STM32WBAX) if(CONFIG_BT_STM32WBA) - # BLE is enabled. Use implementation over Flash Manager for coexistence wit RF activities + # BLE is enabled. Use implementation over Flash Manager for coexistence with RF activities zephyr_library_sources(flash_stm32wba_fm.c) else() zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_STM32_FLASH_CONTROLLER_ENABLED flash_stm32.c flash_stm32wbax.c) @@ -106,7 +109,6 @@ if(CONFIG_SOC_FLASH_STM32) else() if(CONFIG_DT_HAS_ST_STM32_FLASH_CONTROLLER_ENABLED) zephyr_library_sources(flash_stm32.c) - zephyr_library_sources_ifdef(CONFIG_FLASH_EX_OP_ENABLED flash_stm32_ex_op.c) # zephyr-keep-sorted-start zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_STM32F1_FLASH_CONTROLLER_ENABLED flash_stm32f1x.c) @@ -149,10 +151,11 @@ zephyr_library_include_directories_ifdef( ) zephyr_library_sources_ifdef(CONFIG_FLASH_NXP_S32_QSPI_NOR flash_nxp_s32_qspi_nor.c) -zephyr_library_include_directories_ifdef( - CONFIG_FLASH_NXP_S32_QSPI_NOR - ${ZEPHYR_BASE}/drivers/memc -) +zephyr_library_sources_ifdef(CONFIG_FLASH_NXP_S32_QSPI_HYPERFLASH flash_nxp_s32_qspi_hyperflash.c) +if(CONFIG_FLASH_NXP_S32_QSPI_NOR OR CONFIG_FLASH_NXP_S32_QSPI_HYPERFLASH) + zephyr_library_sources(flash_nxp_s32_qspi.c) + zephyr_library_include_directories(${ZEPHYR_BASE}/drivers/memc) +endif() if(CONFIG_RA_FLASH_HP) zephyr_library_sources(flash_hp_ra.c) diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index bc9f6e69d7e35..00ffd104a88c6 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -171,6 +171,7 @@ source "drivers/flash/Kconfig.b91" source "drivers/flash/Kconfig.cadence_nand" source "drivers/flash/Kconfig.cadence_qspi_nor" source "drivers/flash/Kconfig.cc13xx_cc26xx" +source "drivers/flash/Kconfig.cc23x0" source "drivers/flash/Kconfig.esp32" source "drivers/flash/Kconfig.gd32" source "drivers/flash/Kconfig.gecko" @@ -197,6 +198,7 @@ source "drivers/flash/Kconfig.sam" source "drivers/flash/Kconfig.sam0" source "drivers/flash/Kconfig.si32" source "drivers/flash/Kconfig.simulator" +source "drivers/flash/Kconfig.siwx91x" source "drivers/flash/Kconfig.smartbond" source "drivers/flash/Kconfig.stm32" source "drivers/flash/Kconfig.stm32_ospi" diff --git a/drivers/flash/Kconfig.cc23x0 b/drivers/flash/Kconfig.cc23x0 new file mode 100644 index 0000000000000..0a71900914422 --- /dev/null +++ b/drivers/flash/Kconfig.cc23x0 @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FLASH_CC23X0 + bool "TI SimpleLink CC23x0 flash controller driver" + default y + depends on DT_HAS_TI_CC23X0_FLASH_CONTROLLER_ENABLED + select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_DRIVER_ENABLED + select MPU_ALLOW_FLASH_WRITE if ARM_MPU + help + Enables TI SimpleLink CC23x0 flash controller driver. diff --git a/drivers/flash/Kconfig.nor b/drivers/flash/Kconfig.nor index 8e395fa5a0c15..ecf7a4e176a54 100644 --- a/drivers/flash/Kconfig.nor +++ b/drivers/flash/Kconfig.nor @@ -68,6 +68,15 @@ config SPI_NOR_SLEEP_WHILE_WAITING_UNTIL_READY result in significant flash savings if this driver is the only user of "k_sleep". This can be the case when building as a bootloader. +config SPI_NOR_SLEEP_ERASE_MS + int "Delay between polls while waiting for an erase operation in ms" + default 50 + depends on SPI_NOR_SLEEP_WHILE_WAITING_UNTIL_READY + help + The delay between polling while waiting for the flash to finish + an erase operation. + + config SPI_NOR_FLASH_LAYOUT_PAGE_SIZE int "Page size to use for FLASH_LAYOUT feature" default 65536 diff --git a/drivers/flash/Kconfig.npcx_fiu b/drivers/flash/Kconfig.npcx_fiu index 3ddf9a2b7e53f..1137b1ad1abdf 100644 --- a/drivers/flash/Kconfig.npcx_fiu +++ b/drivers/flash/Kconfig.npcx_fiu @@ -65,4 +65,12 @@ config FLASH_NPCX_FIU_SUPP_DRA_2_DEV Selected if NPCX series supports two external SPI devices in Direct Read Access (DRA) on QSPI bus. +DT_NPCX_FIU_LOW_DEV_SWAP := $(dt_nodelabel_bool_prop,qspi_fiu1,flash-dev-inv) +config FLASH_NPCX_FIU_SUPP_LOW_DEV_SWAP + bool "Inverse the access of the two external flashes" + default y if SOC_SERIES_NPCX4 && FLASH_NPCX_FIU_SUPP_DRA_2_DEV && \ + "$(DT_NPCX_FIU_LOW_DEV_SWAP)" + help + Select if it needs to swap the access of the two external flashes. + endif #FLASH_NPCX_FIU_QSPI diff --git a/drivers/flash/Kconfig.nrf b/drivers/flash/Kconfig.nrf index 48c4e0d3fb94b..6e29ef952cac6 100644 --- a/drivers/flash/Kconfig.nrf +++ b/drivers/flash/Kconfig.nrf @@ -37,7 +37,7 @@ config SOC_FLASH_NRF_RADIO_SYNC_TICKER depends on BT_LL_SW_SPLIT help Enable synchronization between flash memory driver and radio using - BLE LL controller ticker API. + Bluetooth LE LL controller ticker API. config SOC_FLASH_NRF_RADIO_SYNC_NONE bool "none" diff --git a/drivers/flash/Kconfig.nrf_rram b/drivers/flash/Kconfig.nrf_rram index 6251f2e90b4bb..3dea687a0f802 100644 --- a/drivers/flash/Kconfig.nrf_rram +++ b/drivers/flash/Kconfig.nrf_rram @@ -24,7 +24,7 @@ if SOC_FLASH_NRF_RRAM config NRF_RRAM_WRITE_BUFFER_SIZE int "Internal write-buffer size" default 32 if !SOC_FLASH_NRF_RADIO_SYNC_NONE - default 0 + default 1 range 0 32 help Number of 128-bit words. @@ -50,7 +50,7 @@ config SOC_FLASH_NRF_RADIO_SYNC_TICKER depends on BT_LL_SW_SPLIT help Enable synchronization between flash memory driver and radio using - BLE LL controller ticker API. + Bluetooth LE LL controller ticker API. config SOC_FLASH_NRF_RADIO_SYNC_NONE bool "none" diff --git a/drivers/flash/Kconfig.nxp_s32 b/drivers/flash/Kconfig.nxp_s32 index 47db1ab654eea..08cc11a6a86a1 100644 --- a/drivers/flash/Kconfig.nxp_s32 +++ b/drivers/flash/Kconfig.nxp_s32 @@ -1,4 +1,4 @@ -# Copyright 2023 NXP +# Copyright 2023-2024 NXP # SPDX-License-Identifier: Apache-2.0 config FLASH_NXP_S32_QSPI_NOR @@ -14,10 +14,23 @@ config FLASH_NXP_S32_QSPI_NOR Enable the Flash driver for a NOR Serial Flash Memory device connected to an NXP S32 QSPI bus. -if FLASH_NXP_S32_QSPI_NOR +config FLASH_NXP_S32_QSPI_HYPERFLASH + bool "NXP S32 QSPI HYPERFLASH driver" + default y + depends on DT_HAS_NXP_S32_QSPI_HYPERFLASH_ENABLED + select MEMC + select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE + help + Enable the Flash driver for a HyperFlash Memory device connected + to an NXP S32 QSPI bus. + +if FLASH_NXP_S32_QSPI_NOR || FLASH_NXP_S32_QSPI_HYPERFLASH -config FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME +config FLASH_NXP_S32_QSPI_SFDP_RUNTIME bool "Read flash parameters at runtime" + depends on FLASH_NXP_S32_QSPI_NOR help Read flash device characteristics from the device at runtime. This option should provide functionality for all supported @@ -52,4 +65,4 @@ config FLASH_NXP_S32_QSPI_LAYOUT_PAGE_SIZE flash memory. Other options may include the 32K-byte erase size (32768), the block size (65536), or any non-zero multiple of the sector size. -endif # FLASH_NXP_S32_QSPI_NOR +endif # FLASH_NXP_S32_QSPI_NOR || FLASH_NXP_S32_QSPI_HYPERFLASH diff --git a/drivers/flash/Kconfig.siwx91x b/drivers/flash/Kconfig.siwx91x new file mode 100644 index 0000000000000..ec7e7af209b5f --- /dev/null +++ b/drivers/flash/Kconfig.siwx91x @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FLASH_SILABS_SIWX91X + bool "Silicon Labs SiWx91x flash driver" + default y + depends on DT_HAS_SILABS_SIWX91X_FLASH_CONTROLLER_ENABLED + select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_EXPLICIT_ERASE + select FLASH_HAS_PAGE_LAYOUT + # Flash controller is handled by the network coprocessor + select WISECONNECT_NETWORK_STACK + help + Enable flash controller for flash embedded on Silicon Labs SiWx91x + chips. diff --git a/drivers/flash/Kconfig.stm32 b/drivers/flash/Kconfig.stm32 index 0d0ecf535b977..c7c9bb1e00c31 100644 --- a/drivers/flash/Kconfig.stm32 +++ b/drivers/flash/Kconfig.stm32 @@ -33,7 +33,7 @@ if SOC_FLASH_STM32 config FLASH_STM32_WRITE_PROTECT bool "Extended operation for flash write protection control" - depends on SOC_SERIES_STM32F4X + depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32H7X select FLASH_HAS_EX_OP default n help @@ -51,7 +51,8 @@ config FLASH_STM32_WRITE_PROTECT_DISABLE_PREVENTION config FLASH_STM32_READOUT_PROTECTION bool "Extended operation for flash readout protection control" depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32L4X || \ - SOC_SERIES_STM32G4X || SOC_SERIES_STM32F7X + SOC_SERIES_STM32G4X || SOC_SERIES_STM32F7X || \ + SOC_SERIES_STM32H7X select FLASH_HAS_EX_OP default n help @@ -84,6 +85,14 @@ config FLASH_STM32_BLOCK_REGISTERS registers improves system security, because flash content (or protection settings) can't be changed even when exploit was found. +config FLASH_STM32_OPTION_BYTES + bool "Extended operation for option bytes access" + select FLASH_HAS_EX_OP + default n + help + Enables flash extended operations that can be used to read and write + STM32 option bytes. + config USE_MICROCHIP_QSPI_FLASH_WITH_STM32 bool "Include patch for Microchip qspi flash when running with stm32" depends on DT_HAS_ST_STM32_QSPI_NOR_ENABLED diff --git a/drivers/flash/Kconfig.stm32_ospi b/drivers/flash/Kconfig.stm32_ospi index 91a30c8cc0a60..4b62bdcd23ee0 100644 --- a/drivers/flash/Kconfig.stm32_ospi +++ b/drivers/flash/Kconfig.stm32_ospi @@ -3,8 +3,7 @@ # Copyright (c) 2022 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 -DT_STM32_OCTOSPI_1_HAS_DMA := $(dt_nodelabel_has_prop,octospi1,dmas) -DT_STM32_OCTOSPI_2_HAS_DMA := $(dt_nodelabel_has_prop,octospi2,dmas) +DT_STM32_OCTOSPI_HAS_DMA := $(dt_compat_any_has_prop,$(DT_COMPAT_ST_STM32_OSPI),dmas) config FLASH_STM32_OSPI bool "STM32 Octo SPI Flash driver" @@ -19,11 +18,9 @@ config FLASH_STM32_OSPI select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_EXPLICIT_ERASE select PINCTRL - select DMA if $(DT_STM32_OCTOSPI_1_HAS_DMA) || $(DT_STM32_OCTOSPI_2_HAS_DMA) - select USE_STM32_HAL_DMA if $(DT_STM32_OCTOSPI_1_HAS_DMA) || \ - $(DT_STM32_OCTOSPI_2_HAS_DMA) + select DMA if $(DT_STM32_OCTOSPI_HAS_DMA) + select USE_STM32_HAL_DMA if $(DT_STM32_OCTOSPI_HAS_DMA) select USE_STM32_HAL_DMA_EX if SOC_SERIES_STM32U5X && \ - ($(DT_STM32_OCTOSPI_1_HAS_DMA) || \ - $(DT_STM32_OCTOSPI_2_HAS_DMA)) + $(DT_STM32_OCTOSPI_HAS_DMA) help Enable OSPI-NOR support on the STM32 family of processors. diff --git a/drivers/flash/Kconfig.stm32_qspi b/drivers/flash/Kconfig.stm32_qspi index 976083238b169..aa174bfd21eaf 100644 --- a/drivers/flash/Kconfig.stm32_qspi +++ b/drivers/flash/Kconfig.stm32_qspi @@ -4,7 +4,7 @@ # Copyright (c) 2020 Linaro Limited # SPDX-License-Identifier: Apache-2.0 -DT_STM32_QUADSPI_HAS_DMA := $(dt_nodelabel_has_prop,quadspi,dmas) +DT_STM32_QUADSPI_HAS_DMA := $(dt_compat_any_has_prop,$(DT_COMPAT_ST_STM32_QSPI),dmas) config FLASH_STM32_QSPI bool "STM32 Quad SPI Flash driver" diff --git a/drivers/flash/Kconfig.stm32_xspi b/drivers/flash/Kconfig.stm32_xspi index 39f62814b5c19..53a3f381af548 100644 --- a/drivers/flash/Kconfig.stm32_xspi +++ b/drivers/flash/Kconfig.stm32_xspi @@ -3,8 +3,7 @@ # Copyright (c) 2024 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 -DT_STM32_XSPI_1_HAS_DMA := $(dt_nodelabel_has_prop,xspi1,dmas) -DT_STM32_XSPI_2_HAS_DMA := $(dt_nodelabel_has_prop,xspi2,dmas) +DT_STM32_XSPI_HAS_DMA := $(dt_compat_any_has_prop,$(DT_COMPAT_ST_STM32_XSPI),dmas) config FLASH_STM32_XSPI bool "STM32 XSPI Flash driver" @@ -17,11 +16,9 @@ config FLASH_STM32_XSPI select FLASH_PAGE_LAYOUT select FLASH_HAS_PAGE_LAYOUT select PINCTRL - select DMA if $(DT_STM32_XSPI_1_HAS_DMA) || $(DT_STM32_XSPI_2_HAS_DMA) - select USE_STM32_HAL_DMA if $(DT_STM32_XSPI_1_HAS_DMA) || \ - $(DT_STM32_XSPI_2_HAS_DMA) + select DMA if $(DT_STM32_XSPI_HAS_DMA) + select USE_STM32_HAL_DMA if $(DT_STM32_XSPI_HAS_DMA) select USE_STM32_HAL_DMA_EX if SOC_SERIES_STM32H5X && \ - ($(DT_STM32_XSPI_1_HAS_DMA) || \ - $(DT_STM32_XSPI_2_HAS_DMA)) + $(DT_STM32_XSPI_HAS_DMA) help Enable XSPI-NOR support on the STM32 family of processors. diff --git a/drivers/flash/flash_andes_qspi.c b/drivers/flash/flash_andes_qspi.c index ff041e014f0fd..d7d58a73ad028 100644 --- a/drivers/flash/flash_andes_qspi.c +++ b/drivers/flash/flash_andes_qspi.c @@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(flash_andes, CONFIG_FLASH_LOG_LEVEL); +/* ATCSPI200 transfer count is limited to 512 bytes. */ +#define MAX_TRANSFER_CNT (512) + /* Indicates that an access command includes bytes for the address. * If not provided the opcode is not followed by address bytes. */ @@ -50,7 +53,7 @@ struct flash_andes_qspi_config { uint32_t base; uint32_t irq_num; struct flash_parameters parameters; - bool xip; + bool qspi_cfg_rom; #if defined(CONFIG_FLASH_ANDES_QSPI_SFDP_DEVICETREE) uint8_t jedec_id[SPI_NOR_MAX_ID_LEN]; uint32_t flash_size; @@ -304,6 +307,8 @@ static int flash_andes_qspi_read(const struct device *dev, off_t addr, void *dest, size_t size) { const size_t flash_size = dev_flash_size(dev); + size_t to_read = size; + int ret; /* should be between 0 and flash size */ @@ -317,8 +322,23 @@ static int flash_andes_qspi_read(const struct device *dev, acquire_device(dev); - ret = flash_andes_qspi_cmd_addr_read(dev, - FLASH_ANDES_CMD_4READ, addr, dest, size); + do { + /* Get the adequate size to receive */ + to_read = MIN(MAX_TRANSFER_CNT, size); + + ret = flash_andes_qspi_cmd_addr_read(dev, + FLASH_ANDES_CMD_4READ, addr, dest, to_read); + + if (ret != 0) { + break; + } + + size -= to_read; + dest = (uint8_t *)dest + to_read; + addr += to_read; + + flash_andes_qspi_wait_until_ready(dev); + } while (size > 0); release_device(dev); return ret; @@ -353,6 +373,8 @@ static int flash_andes_qspi_write(const struct device *dev, off_t addr, /* Get the adequate size to send*/ to_write = MIN(page_size - (addr % page_size), size); + flash_andes_qspi_cmd_write(dev, FLASH_ANDES_CMD_WREN); + ret = flash_andes_qspi_cmd_addr_write(dev, FLASH_ANDES_CMD_4PP, addr, src, to_write); @@ -801,7 +823,7 @@ static int flash_andes_qspi_init(const struct device *dev) uint8_t jedec_id[SPI_NOR_MAX_ID_LEN]; /* we should not configure the device we are running on */ - if (config->xip) { + if (config->qspi_cfg_rom) { return -EINVAL; } @@ -895,11 +917,21 @@ static DEVICE_API(flash, flash_andes_qspi_api) = { }; #if (CONFIG_XIP) -#define QSPI_ROM_CFG_XIP(node_id) DT_SAME_NODE(node_id, DT_CHOSEN(zephyr_flash)) +#define QSPI_FLASH_BASE DT_REG_ADDR_BY_IDX(DT_PARENT(DT_CHOSEN(zephyr_flash)), 1) +#define QSPI_FLASH_SIZE DT_REG_SIZE_BY_IDX(DT_PARENT(DT_CHOSEN(zephyr_flash)), 1) +#define QSPI_FLASH_END (QSPI_FLASH_BASE + QSPI_FLASH_SIZE) + +#if ((QSPI_FLASH_BASE <= CONFIG_FLASH_BASE_ADDRESS) && \ + (CONFIG_FLASH_BASE_ADDRESS <= QSPI_FLASH_END)) +#define QSPI_CFG_ROM(node_id) DT_SAME_NODE(node_id, DT_CHOSEN(zephyr_flash)) #else -#define QSPI_ROM_CFG_XIP(node_id) false +#define QSPI_CFG_ROM(node_id) false #endif +#else /* CONFIG_XIP */ +#define QSPI_CFG_ROM(node_id) false +#endif /* CONFIG_XIP */ + #define LAYOUT_PAGES_PROP(n) \ IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, \ (.layout = { \ @@ -940,7 +972,7 @@ static DEVICE_API(flash, flash_andes_qspi_api) = { .write_block_size = 1, \ .erase_value = 0xff \ }, \ - .xip = QSPI_ROM_CFG_XIP(DT_DRV_INST(n)), \ + .qspi_cfg_rom = QSPI_CFG_ROM(DT_DRV_INST(n)), \ ANDES_QSPI_SFDP_DEVICETREE_PROP(n) \ }; \ \ diff --git a/drivers/flash/flash_esp32.c b/drivers/flash/flash_esp32.c index 6d947064e9d8a..4baf94bcff62e 100644 --- a/drivers/flash/flash_esp32.c +++ b/drivers/flash/flash_esp32.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -69,21 +70,49 @@ static inline void flash_esp32_sem_give(const struct device *dev) #endif /* CONFIG_MULTITHREADING */ +#include +#include +#include +#include +#include + static int flash_esp32_read(const struct device *dev, off_t address, void *buffer, size_t length) { int ret = 0; - flash_esp32_sem_take(dev); +#ifdef CONFIG_MCUBOOT + /* ensure everything is 4-byte aligned */ + size_t aligned_length = ROUND_UP(length, 4); + off_t aligned_address = ROUND_DOWN(address, 4); + size_t address_offset = address - aligned_address; + uint32_t temp_buf[aligned_length / 4]; + if (!esp_flash_encryption_enabled()) { - ret = esp_flash_read(NULL, buffer, address, length); + ret = esp_rom_flash_read(aligned_address, temp_buf, aligned_length, false); } else { + ret = esp_rom_flash_read(aligned_address, temp_buf, aligned_length, true); + } + + memcpy((void *)buffer, ((uint8_t *)temp_buf) + address_offset, length); +#else + + flash_esp32_sem_take(dev); + + if (esp_flash_encryption_enabled()) { ret = esp_flash_read_encrypted(NULL, address, buffer, length); + } else { + ret = esp_flash_read(NULL, buffer, address, length); } + flash_esp32_sem_give(dev); + +#endif + if (ret != 0) { - LOG_ERR("esp_flash_read failed %d", ret); + LOG_ERR("Flash read error: %d", ret); return -EIO; } + return 0; } @@ -94,28 +123,55 @@ static int flash_esp32_write(const struct device *dev, { int ret = 0; - flash_esp32_sem_take(dev); +#ifdef CONFIG_MCUBOOT + /* ensure everything is 4-byte aligned */ + size_t aligned_length = ROUND_UP(length, 4); + off_t aligned_address = ROUND_DOWN(address, 4); + size_t address_offset = address - aligned_address; + uint32_t temp_buf[aligned_length / 4]; + if (!esp_flash_encryption_enabled()) { - ret = esp_flash_write(NULL, buffer, address, length); + ret = esp_rom_flash_write(aligned_address, temp_buf, aligned_length, false); } else { + ret = esp_rom_flash_write(aligned_address, temp_buf, aligned_length, true); + } + + memcpy((void *)buffer, ((uint8_t *)temp_buf) + address_offset, length); +#else + + flash_esp32_sem_take(dev); + + if (esp_flash_encryption_enabled()) { ret = esp_flash_write_encrypted(NULL, address, buffer, length); + } else { + ret = esp_flash_write(NULL, buffer, address, length); } + flash_esp32_sem_give(dev); +#endif + if (ret != 0) { - LOG_ERR("esp_flash_write failed %d", ret); + LOG_ERR("Flash write error: %d", ret); return -EIO; } + return 0; } static int flash_esp32_erase(const struct device *dev, off_t start, size_t len) { + int ret = 0; + +#ifdef CONFIG_MCUBOOT + ret = esp_rom_flash_erase_range(start, len); +#else flash_esp32_sem_take(dev); - int ret = esp_flash_erase_region(NULL, start, len); + ret = esp_flash_erase_region(NULL, start, len); flash_esp32_sem_give(dev); +#endif if (ret != 0) { - LOG_ERR("esp_flash_erase_region failed %d", ret); + LOG_ERR("Flash erase error: %d", ret); return -EIO; } return 0; @@ -146,18 +202,12 @@ flash_esp32_get_parameters(const struct device *dev) static int flash_esp32_init(const struct device *dev) { - uint32_t ret = 0; - #ifdef CONFIG_MULTITHREADING struct flash_esp32_dev_data *const dev_data = dev->data; k_sem_init(&dev_data->sem, 1, 1); #endif /* CONFIG_MULTITHREADING */ - ret = esp_flash_init_default_chip(); - if (ret != 0) { - LOG_ERR("esp_flash_init_default_chip failed %d", ret); - return 0; - } + return 0; } diff --git a/drivers/flash/flash_handlers.c b/drivers/flash/flash_handlers.c index 28355d1d37495..fd809e8d43bd7 100644 --- a/drivers/flash/flash_handlers.c +++ b/drivers/flash/flash_handlers.c @@ -32,7 +32,7 @@ static inline int z_vrfy_flash_write(const struct device *dev, off_t offset, static inline int z_vrfy_flash_erase(const struct device *dev, off_t offset, size_t size) { - K_OOPS(K_SYSCALL_DRIVER_FLASH(dev, erase)); + K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH)); return z_impl_flash_erase((const struct device *)dev, offset, size); } #include @@ -40,7 +40,7 @@ static inline int z_vrfy_flash_erase(const struct device *dev, off_t offset, static inline int z_vrfy_flash_get_size(const struct device *dev, uint64_t *size) { K_OOPS(K_SYSCALL_OBJ(dev, K_OBJ_DRIVER_FLASH)); - K_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(size))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(size, sizeof(*size))); return z_impl_flash_get_size((const struct device *)dev, size); } #include diff --git a/drivers/flash/flash_hp_ra.c b/drivers/flash/flash_hp_ra.c index 11237f735b250..eb5ba3ec5bb67 100644 --- a/drivers/flash/flash_hp_ra.c +++ b/drivers/flash/flash_hp_ra.c @@ -33,39 +33,11 @@ static volatile struct event_flash g_event_flash = { .write_complete = false, }; +static struct flash_pages_layout flash_ra_layout[5]; + void fcu_frdyi_isr(void); void fcu_fiferr_isr(void); -static int flash_controller_ra_init(const struct device *dev); -static int flash_ra_init(const struct device *dev); -static int flash_ra_erase(const struct device *dev, off_t offset, size_t len); -static int flash_ra_read(const struct device *dev, off_t offset, void *data, size_t len); -static int flash_ra_write(const struct device *dev, off_t offset, const void *data, size_t len); -static const struct flash_parameters *flash_ra_get_parameters(const struct device *dev); -#ifdef CONFIG_FLASH_PAGE_LAYOUT -void flash_ra_page_layout(const struct device *dev, const struct flash_pages_layout **layout, - size_t *layout_size); -#endif - -#ifdef CONFIG_FLASH_EX_OP_ENABLED -static int flash_ra_ex_op(const struct device *dev, uint16_t code, const uintptr_t in, void *out); -#endif - -static DEVICE_API(flash, flash_ra_api) = { - .erase = flash_ra_erase, - .write = flash_ra_write, - .read = flash_ra_read, - .get_parameters = flash_ra_get_parameters, -#ifdef CONFIG_FLASH_PAGE_LAYOUT - .page_layout = flash_ra_page_layout, -#endif -#ifdef CONFIG_FLASH_EX_OP_ENABLED - .ex_op = flash_ra_ex_op, -#endif -}; - -static struct flash_pages_layout flash_ra_layout[5]; - void bgo_callback(flash_callback_args_t *p_args) { if (FLASH_EVENT_ERASE_COMPLETE == p_args->event) { @@ -75,12 +47,31 @@ void bgo_callback(flash_callback_args_t *p_args) } } -static bool flash_ra_valid_range(off_t area_size, off_t offset, size_t len) +static bool flash_ra_valid_range(struct flash_hp_ra_data *flash_data, off_t offset, size_t len) { - if ((offset < 0) || (offset >= area_size) || ((area_size - offset) < len)) { +#if defined(CONFIG_DUAL_BANK_MODE) + if (flash_data->FlashRegion == DATA_FLASH) { + if ((offset < 0) || (offset >= flash_data->area_size) || + (flash_data->area_size - offset < len) || (len > UINT32_MAX - offset)) { + return false; + } + } else { + if ((offset < 0) || (offset >= FLASH_HP_CF_DUAL_HIGH_END_ADDRESS) || + (offset >= FLASH_HP_CF_DUAL_LOW_END_ADDRESS && + offset < FLASH_HP_BANK2_OFFSET) || + ((len + offset) > FLASH_HP_CF_DUAL_HIGH_END_ADDRESS) || + ((len + offset) > FLASH_HP_CF_DUAL_LOW_END_ADDRESS && + (len + offset) < FLASH_HP_BANK2_OFFSET) || + (len > UINT32_MAX - offset)) { + return false; + } + } +#else + if ((offset < 0) || (offset >= flash_data->area_size) || + (flash_data->area_size - offset < len) || (len > UINT32_MAX - offset)) { return false; } - +#endif return true; } @@ -88,7 +79,7 @@ static int flash_ra_read(const struct device *dev, off_t offset, void *data, siz { struct flash_hp_ra_data *flash_data = dev->data; - if (!flash_ra_valid_range(flash_data->area_size, offset, len)) { + if (!flash_ra_valid_range(flash_data, offset, len)) { return -EINVAL; } @@ -108,11 +99,13 @@ static int flash_ra_erase(const struct device *dev, off_t offset, size_t len) struct flash_hp_ra_data *flash_data = dev->data; struct flash_hp_ra_controller *dev_ctrl = flash_data->controller; static struct flash_pages_info page_info_off, page_info_len; - fsp_err_t err = FSP_ERR_ASSERTION; + fsp_err_t err; uint32_t block_num; int rc, rc2; + int key = 0; + bool is_contain_end_block = false; - if (!flash_ra_valid_range(flash_data->area_size, offset, len)) { + if (!flash_ra_valid_range(flash_data, offset, len)) { return -EINVAL; } @@ -132,35 +125,54 @@ static int flash_ra_erase(const struct device *dev, off_t offset, size_t len) return -EINVAL; } - rc2 = flash_get_page_info_by_offs(dev, (offset + len), &page_info_len); - if (rc2 != 0) { - return -EINVAL; - } - + if (flash_data->FlashRegion == CODE_FLASH) { #if defined(CONFIG_DUAL_BANK_MODE) - /* Invalid offset in dual bank mode, this is reversed area. */ - if ((page_info_off.index > FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END && - page_info_off.index < FLASH_HP_CF_BLOCK_8KB_HIGH_START) || - (page_info_len.index > FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END && - page_info_len.index < FLASH_HP_CF_BLOCK_8KB_HIGH_START)) { - return -EIO; - } + if ((offset + len) == (uint32_t)FLASH_HP_CF_DUAL_HIGH_END_ADDRESS) { + page_info_len.index = FLASH_HP_CF_BLOCK_32KB_DUAL_HIGH_END + 1; + is_contain_end_block = true; + } +#else + if ((offset + len) == (uint32_t)DT_REG_SIZE(DT_NODELABEL(flash0))) { + page_info_len.index = FLASH_HP_CF_BLOCK_32KB_LINEAR_END + 1; + is_contain_end_block = true; + } #endif + } else { + if ((offset + len) == (uint32_t)DT_REG_SIZE(DT_NODELABEL(flash1))) { + page_info_len.index = FLASH_HP_DF_BLOCK_END; + is_contain_end_block = true; + } + } - if ((offset + len) != (page_info_len.start_offset)) { - return -EIO; + if (!is_contain_end_block) { + rc2 = flash_get_page_info_by_offs(dev, (offset + len), &page_info_len); + if (rc2 != 0) { + return -EINVAL; + } + if ((offset + len) != (page_info_len.start_offset)) { + return -EIO; + } } block_num = (uint32_t)((page_info_len.index) - page_info_off.index); if (block_num > 0) { - k_sem_take(&dev_ctrl->ctrl_sem, K_FOREVER); + if (flash_data->FlashRegion == CODE_FLASH) { + /* Disable interrupts during code flash operations */ + key = irq_lock(); + } else { + k_sem_take(&dev_ctrl->ctrl_sem, K_FOREVER); + } err = R_FLASH_HP_Erase(&dev_ctrl->flash_ctrl, (long)(flash_data->area_address + offset), block_num); if (err != FSP_SUCCESS) { - k_sem_give(&dev_ctrl->ctrl_sem); + if (flash_data->FlashRegion == CODE_FLASH) { + irq_unlock(key); + } else { + k_sem_give(&dev_ctrl->ctrl_sem); + } return -EIO; } @@ -174,7 +186,11 @@ static int flash_ra_erase(const struct device *dev, off_t offset, size_t len) } } - k_sem_give(&dev_ctrl->ctrl_sem); + if (flash_data->FlashRegion == CODE_FLASH) { + irq_unlock(key); + } else { + k_sem_give(&dev_ctrl->ctrl_sem); + } } return 0; @@ -182,11 +198,12 @@ static int flash_ra_erase(const struct device *dev, off_t offset, size_t len) static int flash_ra_write(const struct device *dev, off_t offset, const void *data, size_t len) { - fsp_err_t err = FSP_ERR_ASSERTION; + fsp_err_t err; struct flash_hp_ra_data *flash_data = dev->data; struct flash_hp_ra_controller *dev_ctrl = flash_data->controller; + int key = 0; - if (!flash_ra_valid_range(flash_data->area_size, offset, len)) { + if (!flash_ra_valid_range(flash_data, offset, len)) { return -EINVAL; } @@ -196,13 +213,22 @@ static int flash_ra_write(const struct device *dev, off_t offset, const void *da LOG_DBG("flash: write 0x%lx, len: %u", (long)(offset + flash_data->area_address), len); - k_sem_take(&dev_ctrl->ctrl_sem, K_FOREVER); + if (flash_data->FlashRegion == CODE_FLASH) { + /* Disable interrupts during code flash operations */ + key = irq_lock(); + } else { + k_sem_take(&dev_ctrl->ctrl_sem, K_FOREVER); + } err = R_FLASH_HP_Write(&dev_ctrl->flash_ctrl, (uint32_t)data, (long)(offset + flash_data->area_address), len); if (err != FSP_SUCCESS) { - k_sem_give(&dev_ctrl->ctrl_sem); + if (flash_data->FlashRegion == CODE_FLASH) { + irq_unlock(key); + } else { + k_sem_give(&dev_ctrl->ctrl_sem); + } return -EIO; } @@ -216,11 +242,24 @@ static int flash_ra_write(const struct device *dev, off_t offset, const void *da } } - k_sem_give(&dev_ctrl->ctrl_sem); + if (flash_data->FlashRegion == CODE_FLASH) { + irq_unlock(key); + } else { + k_sem_give(&dev_ctrl->ctrl_sem); + } + + return 0; +} + +static int flash_ra_get_size(const struct device *dev, uint64_t *size) +{ + struct flash_hp_ra_data *flash_data = dev->data; + *size = (uint64_t)flash_data->area_size; return 0; } +#ifdef CONFIG_FLASH_PAGE_LAYOUT void flash_ra_page_layout(const struct device *dev, const struct flash_pages_layout **layout, size_t *layout_size) { @@ -242,12 +281,12 @@ void flash_ra_page_layout(const struct device *dev, const struct flash_pages_lay 1; flash_ra_layout[1].pages_size = FLASH_HP_CF_BLOCK_32KB_SIZE; - flash_ra_layout[2].pages_count = FLASH_RESERVED_AREA_NUM; + flash_ra_layout[2].pages_count = FLASH_HP_CF_NUM_BLOCK_RESERVED; flash_ra_layout[2].pages_size = (FLASH_HP_BANK2_OFFSET - (flash_ra_layout[0].pages_count * flash_ra_layout[0].pages_size) - (flash_ra_layout[1].pages_count * flash_ra_layout[1].pages_size)) / - FLASH_RESERVED_AREA_NUM; + FLASH_HP_CF_NUM_BLOCK_RESERVED; flash_ra_layout[3].pages_count = (FLASH_HP_CF_BLOCK_8KB_HIGH_END - FLASH_HP_CF_BLOCK_8KB_HIGH_START) + 1; @@ -275,6 +314,7 @@ void flash_ra_page_layout(const struct device *dev, const struct flash_pages_lay *layout = flash_ra_layout; } +#endif static const struct flash_parameters *flash_ra_get_parameters(const struct device *dev) { @@ -354,7 +394,7 @@ static void flash_controller_ra_irq_config_func(const struct device *dev) static int flash_controller_ra_init(const struct device *dev) { - fsp_err_t err = FSP_SUCCESS; + fsp_err_t err; const struct flash_hp_ra_controller_config *cfg = dev->config; struct flash_hp_ra_controller *data = dev->data; @@ -376,6 +416,20 @@ static struct flash_hp_ra_controller_config flash_hp_ra_controller_config = { .irq_config = flash_controller_ra_irq_config_func, }; +static DEVICE_API(flash, flash_ra_api) = { + .erase = flash_ra_erase, + .write = flash_ra_write, + .read = flash_ra_read, + .get_parameters = flash_ra_get_parameters, + .get_size = flash_ra_get_size, +#ifdef CONFIG_FLASH_PAGE_LAYOUT + .page_layout = flash_ra_page_layout, +#endif +#ifdef CONFIG_FLASH_EX_OP_ENABLED + .ex_op = flash_ra_ex_op, +#endif +}; + #define RA_FLASH_INIT(index) \ struct flash_hp_ra_data flash_hp_ra_data_##index = {.area_address = DT_REG_ADDR(index), \ .area_size = DT_REG_SIZE(index)}; \ diff --git a/drivers/flash/flash_hp_ra.h b/drivers/flash/flash_hp_ra.h index 968c74c49047f..f5592c72af55b 100644 --- a/drivers/flash/flash_hp_ra.h +++ b/drivers/flash/flash_hp_ra.h @@ -29,16 +29,29 @@ #define FLASH_HP_CF_BLOCK_8KB_HIGH_END (77) #define FLASH_HP_CF_BLOCK_32KB_LINEAR_START (8) +#define FLASH_HP_CF_BLOCK_32KB_LINEAR_END (DT_PROP(DT_NODELABEL(flash), block_32kb_linear_end)) +#define FLASH_HP_DF_BLOCK_END (DT_REG_SIZE(DT_NODELABEL(flash1)) / FLASH_HP_DF_BLOCK_SIZE) + +#if defined(CONFIG_DUAL_BANK_MODE) +#define FLASH_HP_CF_NUM_BLOCK_RESERVED (DT_PROP(DT_NODELABEL(flash), reserved_area_num)) #define FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_START (8) #define FLASH_HP_CF_BLOCK_32KB_DUAL_HIGH_START (78) -#if defined(CONFIG_SOC_R7FA8M1AHECBD) || defined(CONFIG_SOC_R7FA8D1BHECBD) || \ - defined(CONFIG_SOC_R7FA8T1AHECBD) -#define FLASH_RESERVED_AREA_NUM (33) -#define FLASH_HP_CF_BLOCK_32KB_LINEAR_END (68) -#define FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END (36) -#define FLASH_HP_CF_BLOCK_32KB_DUAL_HIGH_END (106) +#define FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END (DT_PROP(DT_NODELABEL(flash), block_32kb_dual_low_end)) +#define FLASH_HP_CF_BLOCK_32KB_DUAL_HIGH_END \ + (DT_PROP(DT_NODELABEL(flash), block_32kb_dual_high_end)) + +#define FLASH_HP_CF_DUAL_HIGH_START_ADDRESS BSP_FEATURE_FLASH_HP_CF_DUAL_BANK_START + +#define FLASH_HP_CF_DUAL_LOW_END_ADDRESS \ + (DT_REG_SIZE(DT_NODELABEL(flash0)) - \ + ((FLASH_HP_CF_BLOCK_32KB_LINEAR_END - FLASH_HP_CF_BLOCK_32KB_DUAL_LOW_END) * \ + FLASH_HP_CF_BLOCK_32KB_SIZE)) + +#define FLASH_HP_CF_DUAL_HIGH_END_ADDRESS \ + (DT_REG_SIZE(DT_NODELABEL(flash0)) + \ + (FLASH_HP_CF_NUM_BLOCK_RESERVED * FLASH_HP_CF_BLOCK_32KB_SIZE)) #endif #if defined(CONFIG_FLASH_EX_OP_ENABLED) diff --git a/drivers/flash/flash_mcux_flexspi_mx25um51345g.c b/drivers/flash/flash_mcux_flexspi_mx25um51345g.c index 0e5aaa97e0d39..56d23d52e9075 100644 --- a/drivers/flash/flash_mcux_flexspi_mx25um51345g.c +++ b/drivers/flash/flash_mcux_flexspi_mx25um51345g.c @@ -67,7 +67,7 @@ struct flash_flexspi_nor_data { const struct device *controller; flexspi_device_config_t config; flexspi_port_t port; - uint64_t *size; + uint64_t size; struct flash_pages_layout layout; struct flash_parameters flash_parameters; }; @@ -500,9 +500,9 @@ static const struct flash_parameters *flash_flexspi_nor_get_parameters( static int flash_flexspi_nor_get_size(const struct device *dev, uint64_t *size) { - const struct flash_flexspi_nor_config *config = dev->config; + const struct flash_flexspi_nor_data *data = dev->data; - *size = config->size; + *size = data->size; return 0; } diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index b8b2411f2a570..87abe2142fa4a 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -143,6 +143,14 @@ static const uint32_t flash_flexspi_nor_base_lut[][MEMC_FLEXSPI_CMD_PER_SEQ] = { }, }; +static ALWAYS_INLINE bool area_is_subregion(const struct device *dev, off_t offset, size_t size) +{ + struct flash_flexspi_nor_data *data = dev->data; + + return ((offset >= 0) && (offset < data->size) && + ((data->size - offset) >= size)); +} + /* Helper so we can read flash ID without flash access for XIP */ static int flash_flexspi_nor_read_id_helper(struct flash_flexspi_nor_data *data, uint8_t *vendor_id) @@ -316,6 +324,15 @@ static int flash_flexspi_nor_read(const struct device *dev, off_t offset, void *buffer, size_t len) { struct flash_flexspi_nor_data *data = dev->data; + + if (!buffer) { + return -EINVAL; + } + + if (!area_is_subregion(dev, offset, len)) { + return -EINVAL; + } + uint8_t *src = memc_flexspi_get_ahb_address(&data->controller, data->port, offset); @@ -329,6 +346,15 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, const void *buffer, size_t len) { struct flash_flexspi_nor_data *data = dev->data; + + if (!buffer) { + return -EINVAL; + } + + if (!area_is_subregion(dev, offset, len)) { + return -EINVAL; + } + size_t size = len; uint8_t *src = (uint8_t *) buffer; int i; @@ -345,6 +371,7 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, * code and data accessed must reside in ram. */ key = irq_lock(); + memc_flexspi_wait_bus_idle(&data->controller); } while (len) { @@ -355,6 +382,13 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, i = MIN(SPI_NOR_PAGE_SIZE - (offset % SPI_NOR_PAGE_SIZE), len); #ifdef CONFIG_FLASH_MCUX_FLEXSPI_NOR_WRITE_BUFFER memcpy(nor_write_buf, src, i); + + /* As memcpy could cause an XIP access, + * we need to wait for XIP prefetch to be finished again + */ + if (memc_flexspi_is_running_xip(&data->controller)) { + memc_flexspi_wait_bus_idle(&data->controller); + } #endif flash_flexspi_nor_write_enable(data); #ifdef CONFIG_FLASH_MCUX_FLEXSPI_NOR_WRITE_BUFFER @@ -385,6 +419,11 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, size_t size) { struct flash_flexspi_nor_data *data = dev->data; + + if (!area_is_subregion(dev, offset, size)) { + return -EINVAL; + } + const size_t num_sectors = size / SPI_NOR_SECTOR_SIZE; const size_t num_blocks = size / SPI_NOR_BLOCK_SIZE; @@ -412,6 +451,7 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, * code and data accessed must reside in ram. */ key = irq_lock(); + memc_flexspi_wait_bus_idle(&data->controller); } if ((offset == 0) && (size == data->config.flashSize * KB(1))) { @@ -954,8 +994,10 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, } /* Switch on manufacturer and vendor ID */ - switch (vendor_id & 0xFFFF) { - case 0x609d: /* IS25LP flash, needs P[4:3] cleared with same method as IS25WP */ + switch (vendor_id & 0xFFFFFF) { + case 0x16609d: /* IS25LP032 flash, needs P[4:3] cleared with same method as IS25WP */ + case 0x17609d: /* IS25LP064 */ + case 0x18609d: /* IS25LP128 */ read_params = 0xE0U; ret = flash_flexspi_nor_is25_clear_read_param(data, flexspi_lut, &read_params); if (ret < 0) { @@ -969,7 +1011,9 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, } /* Still return an error- we want the JEDEC configuration to run */ return -ENOTSUP; - case 0x709d: + case 0x16709d: /* IS25WP032 */ + case 0x17709d: /* IS25WP064 */ + case 0x18709d: /* IS25WP128 */ /* * IS25WP flash. We can support this flash with the JEDEC probe, * but we need to insure P[6:3] are at the default value @@ -987,15 +1031,8 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, } /* Still return an error- we want the JEDEC configuration to run */ return -ENOTSUP; - case 0x40ef: - if ((vendor_id & 0xFFFFFF) != 0x2040ef) { - /* - * This is not the correct flash chip, and will not - * support the LUT table. Return here - */ - return -ENOTSUP; - } - /* W25Q512JV flash, use 4 byte read/write */ + case 0x2040ef: + /* W25Q512JV-IQ/IN flash, use 4 byte read/write */ flexspi_lut[READ][0] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_4READ_4B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 32); @@ -1015,7 +1052,7 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_SE_4B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 32); flexspi_lut[ERASE_BLOCK][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xDC, + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_BE_4B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 32), /* Read instruction used for polling is 0x05 */ data->legacy_poll = true; @@ -1025,14 +1062,7 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, /* Device uses bit 1 of status reg 2 for QE */ return flash_flexspi_nor_quad_enable(data, flexspi_lut, JESD216_DW15_QER_VAL_S2B1v5); - case 0x60ef: - if ((vendor_id & 0xFFFFFF) != 0x2060ef) { - /* - * This is not the correct flash chip, and will not - * support the LUT table. Return here - */ - return -ENOTSUP; - } + case 0x2060ef: /* W25Q512NW-IQ/IN flash, use 4 byte read/write */ flexspi_lut[READ][0] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_4READ_4B, @@ -1053,7 +1083,7 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_SE_4B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 32); flexspi_lut[ERASE_BLOCK][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xDC, + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_BE_4B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 32), /* Read instruction used for polling is 0x05 */ data->legacy_poll = true; @@ -1063,8 +1093,8 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, /* Device uses bit 1 of status reg 2 for QE */ return flash_flexspi_nor_quad_enable(data, flexspi_lut, JESD216_DW15_QER_VAL_S2B1v5); - case 0x25C2: - /* MX25 flash, use 4 byte read/write */ + case 0x3A25C2: + /* MX25U51245G flash, use 4 byte read/write */ flexspi_lut[READ][0] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_4READ_4B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 32); @@ -1084,7 +1114,7 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_SE_4B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 32); flexspi_lut[ERASE_BLOCK][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xDC, + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_BE_4B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 32), /* Read instruction used for polling is 0x05 */ data->legacy_poll = true; @@ -1093,6 +1123,43 @@ static int flash_flexspi_nor_check_jedec(struct flash_flexspi_nor_data *data, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x01); /* Device uses bit 6 of status reg 1 for QE */ return flash_flexspi_nor_quad_enable(data, flexspi_lut, JESD216_DW15_QER_VAL_S1B6); + case 0x19ba20: /* MT25QL256 */ + case 0x20ba20: /* MT25QL512 */ + case 0x21ba20: /* MT25QL01G */ + case 0x22ba20: /* MT25QL02G */ + case 0x19bb20: /* MT25QU256 */ + case 0x20bb20: /* MT25QU512 */ + case 0x21bb20: /* MT25QU01G */ + case 0x22bb20: /* MT25QU02G */ + /* MT25Q flash with more than 32MB, use 4 byte read/write */ + flexspi_lut[READ][0] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_4READ_4B, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 32); + /* Flash needs 10 dummy cycles */ + flexspi_lut[READ][1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 10, + kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04); + /* Update PROGRAM commands for 4 byte 1S-4S-4S mode */ + flexspi_lut[PAGE_PROGRAM][0] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_PP_1_4_4_4B, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 32); + flexspi_lut[PAGE_PROGRAM][1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x4, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0); + /* Update ERASE commands for 4 byte mode */ + flexspi_lut[ERASE_SECTOR][0] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_SE_4B, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 32); + flexspi_lut[ERASE_BLOCK][0] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_BE_4B, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 32), + /* Read instruction used for polling is 0x05 */ + data->legacy_poll = true; + flexspi_lut[READ_STATUS_REG][0] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR, + kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x01); + /* Device has no QE bit, 1-4-4 and 1-1-4 is always enabled */ + return 0; default: return -ENOTSUP; } diff --git a/drivers/flash/flash_npcx_fiu_nor.c b/drivers/flash/flash_npcx_fiu_nor.c index ae3a31945fdfa..c368f646ad0a2 100644 --- a/drivers/flash/flash_npcx_fiu_nor.c +++ b/drivers/flash/flash_npcx_fiu_nor.c @@ -587,9 +587,23 @@ static int flash_npcx_nor_init(const struct device *dev) } } + if (config->qspi_cfg.is_logical_low_dev && IS_ENABLED(CONFIG_FLASH_NPCX_FIU_DRA_V2)) { + qspi_npcx_fiu_set_spi_size(config->qspi_bus, &config->qspi_cfg); + } + return 0; } +#define NPCX_FLASH_IS_LOGICAL_LOW_DEV(n) \ + (DT_PROP(DT_PARENT(DT_DRV_INST(n)), en_direct_access_2dev) && \ + (DT_PROP(DT_PARENT(DT_DRV_INST(n)), flash_dev_inv) == \ + ((DT_INST_PROP(n, qspi_flags) & NPCX_QSPI_SEC_FLASH_SL) == \ + NPCX_QSPI_SEC_FLASH_SL))) + +#define NPCX_FLASH_SPI_ALLOCATE_SIZE(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, spi_dev_size), \ + (DT_INST_STRING_TOKEN(n, spi_dev_size)), (0xFF)) + #define NPCX_FLASH_NOR_INIT(n) \ BUILD_ASSERT(DT_INST_QUAD_EN_PROP_OR(n) == JESD216_DW15_QER_NONE || \ DT_INST_STRING_TOKEN(n, rd_mode) == NPCX_RD_MODE_FAST_DUAL, \ @@ -606,6 +620,8 @@ static const struct flash_npcx_nor_config flash_npcx_nor_config_##n = { \ .enter_4ba = DT_INST_PROP_OR(n, enter_4byte_addr, 0), \ .qer_type = DT_INST_QUAD_EN_PROP_OR(n), \ .rd_mode = DT_INST_STRING_TOKEN(n, rd_mode), \ + .is_logical_low_dev = NPCX_FLASH_IS_LOGICAL_LOW_DEV(n), \ + .spi_dev_sz = NPCX_FLASH_SPI_ALLOCATE_SIZE(n), \ }, \ IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, ( \ .layout = { \ diff --git a/drivers/flash/flash_npcx_fiu_qspi.c b/drivers/flash/flash_npcx_fiu_qspi.c index 39e699bbef9d3..5d78eed2f3c60 100644 --- a/drivers/flash/flash_npcx_fiu_qspi.c +++ b/drivers/flash/flash_npcx_fiu_qspi.c @@ -16,7 +16,7 @@ #include "flash_npcx_fiu_qspi.h" #include -LOG_MODULE_REGISTER(npcx_fiu_qspi, LOG_LEVEL_ERR); +LOG_MODULE_REGISTER(npcx_fiu_qspi, CONFIG_FLASH_LOG_LEVEL); /* Driver convenience defines */ #define HAL_INSTANCE(dev) \ @@ -30,6 +30,7 @@ struct npcx_qspi_fiu_config { struct npcx_clk_cfg clk_cfg; /* Enable 2 external SPI devices for direct read on QSPI bus */ bool en_direct_access_2dev; + bool base_flash_inv; }; /* Device data */ @@ -244,6 +245,25 @@ void qspi_npcx_fiu_mutex_unlock(const struct device *dev) k_sem_give(&data->lock_sem); } +#if defined(CONFIG_FLASH_NPCX_FIU_DRA_V2) +void qspi_npcx_fiu_set_spi_size(const struct device *dev, const struct npcx_qspi_cfg *cfg) +{ + struct fiu_reg *const inst = HAL_INSTANCE(dev); + uint8_t flags = cfg->flags; + + if (cfg->spi_dev_sz <= NPCX_SPI_DEV_SIZE_128M) { + if ((flags & NPCX_QSPI_SEC_FLASH_SL) == 0) { + SET_FIELD(inst->BURST_CFG, NPCX_BURST_CFG_SPI_DEV_SEL, NPCX_SPI_F_CS0); + } else { + SET_FIELD(inst->BURST_CFG, NPCX_BURST_CFG_SPI_DEV_SEL, NPCX_SPI_F_CS1); + } + inst->SPI_DEV_SIZE = BIT(cfg->spi_dev_sz); + } else { + LOG_ERR("Invalid setting of low device size"); + } +} +#endif + static int qspi_npcx_fiu_init(const struct device *dev) { const struct npcx_qspi_fiu_config *const config = dev->config; @@ -273,6 +293,11 @@ static int qspi_npcx_fiu_init(const struct device *dev) struct fiu_reg *const inst = HAL_INSTANCE(dev); inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_SPI1_2DEV); +#if defined(CONFIG_FLASH_NPCX_FIU_SUPP_LOW_DEV_SWAP) + if (config->base_flash_inv) { + inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_LOW_DEV_NUM); + } +#endif #endif } @@ -284,6 +309,7 @@ static const struct npcx_qspi_fiu_config npcx_qspi_fiu_config_##n = { \ .base = DT_INST_REG_ADDR(n), \ .clk_cfg = NPCX_DT_CLK_CFG_ITEM(n), \ .en_direct_access_2dev = DT_INST_PROP(n, en_direct_access_2dev), \ + .base_flash_inv = DT_INST_PROP(n, flash_dev_inv), \ }; \ static struct npcx_qspi_fiu_data npcx_qspi_fiu_data_##n; \ DEVICE_DT_INST_DEFINE(n, qspi_npcx_fiu_init, NULL, \ diff --git a/drivers/flash/flash_npcx_fiu_qspi.h b/drivers/flash/flash_npcx_fiu_qspi.h index 1136684d453e3..6e63dd8b076f3 100644 --- a/drivers/flash/flash_npcx_fiu_qspi.h +++ b/drivers/flash/flash_npcx_fiu_qspi.h @@ -25,6 +25,20 @@ extern "C" { #define NPCX_DEV_NUM_ADDR_3BYTE 3 #define NPCX_DEV_NUM_ADDR_4BYTE 4 +#define NPCX_SPI_F_CS0 0 +#define NPCX_SPI_F_CS1 1 + +enum NPCX_SPI_DEV_SIZE { + NPCX_SPI_DEV_SIZE_1M, + NPCX_SPI_DEV_SIZE_2M, + NPCX_SPI_DEV_SIZE_4M, + NPCX_SPI_DEV_SIZE_8M, + NPCX_SPI_DEV_SIZE_16M, + NPCX_SPI_DEV_SIZE_32M, + NPCX_SPI_DEV_SIZE_64M, + NPCX_SPI_DEV_SIZE_128M, +}; + /* UMA operation configuration for a SPI device */ struct npcx_uma_cfg { uint8_t opcode; @@ -48,6 +62,8 @@ struct npcx_qspi_cfg { uint8_t enter_4ba; /* SPI read access type of Direct Read Access mode */ uint8_t rd_mode; + bool is_logical_low_dev; + uint8_t spi_dev_sz; /* Configurations for the Quad-SPI peripherals */ int flags; }; @@ -81,6 +97,14 @@ void qspi_npcx_fiu_mutex_lock_configure(const struct device *dev, */ void qspi_npcx_fiu_mutex_unlock(const struct device *dev); +/** + * @brief Set the size of the address space allocated for SPI device. + * + * @param dev Pointer to the device structure for qspi bus controller instance. + * @param cfg Pointer to the configuration for the device on qspi bus. + */ +void qspi_npcx_fiu_set_spi_size(const struct device *dev, const struct npcx_qspi_cfg *cfg); + #ifdef __cplusplus } #endif diff --git a/drivers/flash/flash_nxp_s32_qspi.c b/drivers/flash/flash_nxp_s32_qspi.c new file mode 100644 index 0000000000000..424960935ba3a --- /dev/null +++ b/drivers/flash/flash_nxp_s32_qspi.c @@ -0,0 +1,274 @@ +/* + * Copyright 2023-2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +#include "flash_nxp_s32_qspi.h" + +LOG_MODULE_REGISTER(flash_nxp_s32_qspi, CONFIG_FLASH_LOG_LEVEL); + +static ALWAYS_INLINE bool area_is_subregion(const struct device *dev, off_t offset, size_t size) +{ + Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); + + return ((offset >= 0) && (offset < memory_cfg->memSize) && + ((memory_cfg->memSize - offset) >= size)); +} + +uint8_t nxp_s32_qspi_register_device(void) +{ + static uint8_t instance_cnt; + + return instance_cnt++; +} + +/* Must be called with lock */ +int nxp_s32_qspi_wait_until_ready(const struct device *dev) +{ + struct nxp_s32_qspi_data *data = dev->data; + Qspi_Ip_StatusType status; + uint32_t timeout = 0xFFFFFF; + int ret = 0; + + do { + status = Qspi_Ip_GetMemoryStatus(data->instance); + timeout--; + } while ((status == STATUS_QSPI_IP_BUSY) && (timeout > 0)); + + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Failed to read memory status (%d)", status); + ret = -EIO; + } else if (timeout == 0) { + LOG_ERR("Timeout, memory is busy"); + ret = -ETIMEDOUT; + } + + return ret; +} + +int nxp_s32_qspi_read(const struct device *dev, off_t offset, void *dest, size_t size) +{ + struct nxp_s32_qspi_data *data = dev->data; + Qspi_Ip_StatusType status; + int ret = 0; + + if (!dest) { + return -EINVAL; + } + + if (!area_is_subregion(dev, offset, size)) { + return -EINVAL; + } + + if (size) { + nxp_s32_qspi_lock(dev); + + status = Qspi_Ip_Read(data->instance, (uint32_t)offset, (uint8_t *)dest, + (uint32_t)size); + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Failed to read %zu bytes at 0x%lx (%d)", size, offset, status); + ret = -EIO; + } + + nxp_s32_qspi_unlock(dev); + } + + return ret; +} + +int nxp_s32_qspi_write(const struct device *dev, off_t offset, const void *src, size_t size) +{ + const struct nxp_s32_qspi_config *config = dev->config; + struct nxp_s32_qspi_data *data = dev->data; + Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); + Qspi_Ip_StatusType status; + size_t max_write = (size_t)MIN(QSPI_IP_MAX_WRITE_SIZE, memory_cfg->pageSize); + size_t len; + int ret = 0; + + if (!src || !size) { + return -EINVAL; + } + + if (!area_is_subregion(dev, offset, size) || + (offset % config->flash_parameters.write_block_size) || + (size % config->flash_parameters.write_block_size)) { + return -EINVAL; + } + + nxp_s32_qspi_lock(dev); + + while (size) { + len = MIN(max_write - (offset % max_write), size); + status = Qspi_Ip_Program(data->instance, (uint32_t)offset, (const uint8_t *)src, + (uint32_t)len); + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Failed to write %zu bytes at 0x%lx (%d)", len, offset, status); + ret = -EIO; + break; + } + + ret = nxp_s32_qspi_wait_until_ready(dev); + if (ret != 0) { + break; + } + + if (IS_ENABLED(CONFIG_FLASH_NXP_S32_QSPI_VERIFY_WRITE)) { + status = Qspi_Ip_ProgramVerify(data->instance, (uint32_t)offset, + (const uint8_t *)src, (uint32_t)len); + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Write verification failed at 0x%lx (%d)", offset, status); + ret = -EIO; + break; + } + } + + size -= len; + src = (const uint8_t *)src + len; + offset += len; + } + + nxp_s32_qspi_unlock(dev); + + return ret; +} + +static int nxp_s32_qspi_erase_block(const struct device *dev, off_t offset, size_t size, + size_t *erase_size) +{ + struct nxp_s32_qspi_data *data = dev->data; + Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); + Qspi_Ip_EraseVarConfigType *etp = NULL; + Qspi_Ip_EraseVarConfigType *etp_tmp; + Qspi_Ip_StatusType status; + int ret = 0; + + /* + * Find the erase type with bigger size that can erase all or part of the + * requested memory size + */ + for (uint8_t i = 0; i < QSPI_IP_ERASE_TYPES; i++) { + etp_tmp = (Qspi_Ip_EraseVarConfigType *)&(memory_cfg->eraseSettings.eraseTypes[i]); + if ((etp_tmp->eraseLut != QSPI_IP_LUT_INVALID) && + QSPI_IS_ALIGNED(offset, etp_tmp->size) && (BIT(etp_tmp->size) <= size) && + ((etp == NULL) || (etp_tmp->size > etp->size))) { + + etp = etp_tmp; + } + } + if (etp != NULL) { + *erase_size = BIT(etp->size); + status = Qspi_Ip_EraseBlock(data->instance, (uint32_t)offset, *erase_size); + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Failed to erase %zu bytes at 0x%lx (%d)", *erase_size, + (long)offset, status); + ret = -EIO; + } + } else { + LOG_ERR("Can't find erase size to erase %zu bytes", size); + ret = -EINVAL; + } + + return ret; +} + +int nxp_s32_qspi_erase(const struct device *dev, off_t offset, size_t size) +{ + struct nxp_s32_qspi_data *data = dev->data; + Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); + Qspi_Ip_StatusType status; + size_t erase_size; + int ret = 0; + + if (!area_is_subregion(dev, offset, size) || !size) { + return -EINVAL; + } + + nxp_s32_qspi_lock(dev); + + if (size == memory_cfg->memSize) { + status = Qspi_Ip_EraseChip(data->instance); + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Failed to erase chip (%d)", status); + ret = -EIO; + } + } else { + while (size > 0) { + erase_size = 0; + + ret = nxp_s32_qspi_erase_block(dev, offset, size, &erase_size); + if (ret != 0) { + break; + } + + ret = nxp_s32_qspi_wait_until_ready(dev); + if (ret != 0) { + break; + } + + if (IS_ENABLED(CONFIG_FLASH_NXP_S32_QSPI_VERIFY_ERASE)) { + status = Qspi_Ip_EraseVerify(data->instance, (uint32_t)offset, + erase_size); + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Erase verification failed at 0x%lx (%d)", offset, + status); + ret = -EIO; + break; + } + } + + offset += erase_size; + size -= erase_size; + } + } + + nxp_s32_qspi_unlock(dev); + + return ret; +} + +const struct flash_parameters *nxp_s32_qspi_get_parameters(const struct device *dev) +{ + const struct nxp_s32_qspi_config *config = dev->config; + + return &config->flash_parameters; +} + +#if defined(CONFIG_FLASH_PAGE_LAYOUT) +void nxp_s32_qspi_pages_layout(const struct device *dev, const struct flash_pages_layout **layout, + size_t *layout_size) +{ + const struct nxp_s32_qspi_config *config = dev->config; + + *layout = &config->layout; + *layout_size = 1; +} +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +#if defined(CONFIG_FLASH_JESD216_API) || !defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) +int nxp_s32_qspi_read_id(const struct device *dev, uint8_t *id) +{ + struct nxp_s32_qspi_data *data = dev->data; + Qspi_Ip_StatusType status; + int ret = 0; + + nxp_s32_qspi_lock(dev); + + status = Qspi_Ip_ReadId(data->instance, id); + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Failed to read device ID (%d)", status); + ret = -EIO; + } + + nxp_s32_qspi_unlock(dev); + + return ret; +} +#endif /* CONFIG_FLASH_JESD216_API || !CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME */ diff --git a/drivers/flash/flash_nxp_s32_qspi.h b/drivers/flash/flash_nxp_s32_qspi.h new file mode 100644 index 0000000000000..5a296ca4d66f8 --- /dev/null +++ b/drivers/flash/flash_nxp_s32_qspi.h @@ -0,0 +1,111 @@ +/* + * Copyright 2023-2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_FLASH_NXP_S32_QSPI_H_ +#define ZEPHYR_DRIVERS_FLASH_NXP_S32_QSPI_H_ + +#include "jesd216.h" + +#define QSPI_ERASE_VALUE 0xff + +#define QSPI_IS_ALIGNED(addr, bits) (((addr) & BIT_MASK(bits)) == 0) + +#if defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) +/* Size of LUT */ +#define QSPI_SFDP_LUT_SIZE 130U +/* Size of init operations */ +#define QSPI_SFDP_INIT_OP_SIZE 8U +#if defined(CONFIG_FLASH_JESD216_API) +/* Size of all LUT sequences for JESD216 operations */ +#define QSPI_JESD216_SEQ_SIZE 8U +#endif /* CONFIG_FLASH_JESD216_API */ +#endif /* CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME */ + +struct nxp_s32_qspi_config { + const struct device *controller; + struct flash_parameters flash_parameters; +#if defined(CONFIG_FLASH_PAGE_LAYOUT) + struct flash_pages_layout layout; +#endif +#if !defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) + const Qspi_Ip_MemoryConfigType memory_cfg; + enum jesd216_dw15_qer_type qer_type; + bool quad_mode; +#endif +}; + +struct nxp_s32_qspi_data { + uint8_t instance; + Qspi_Ip_MemoryConnectionType memory_conn_cfg; + uint8_t read_sfdp_lut_idx; +#if defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) + Qspi_Ip_MemoryConfigType memory_cfg; + Qspi_Ip_InstrOpType lut_ops[QSPI_SFDP_LUT_SIZE]; + Qspi_Ip_InitOperationType init_ops[QSPI_SFDP_INIT_OP_SIZE]; +#endif +#if defined(CONFIG_MULTITHREADING) + struct k_sem sem; +#endif +}; + +static ALWAYS_INLINE Qspi_Ip_MemoryConfigType *get_memory_config(const struct device *dev) +{ +#if defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) + return &((struct nxp_s32_qspi_data *)dev->data)->memory_cfg; +#else + return ((Qspi_Ip_MemoryConfigType *)&((const struct nxp_s32_qspi_config *)dev->config) + ->memory_cfg); +#endif +} + +static inline void nxp_s32_qspi_lock(const struct device *dev) +{ +#ifdef CONFIG_MULTITHREADING + struct nxp_s32_qspi_data *data = dev->data; + + k_sem_take(&data->sem, K_FOREVER); +#else + ARG_UNUSED(dev); +#endif +} + +static inline void nxp_s32_qspi_unlock(const struct device *dev) +{ +#ifdef CONFIG_MULTITHREADING + struct nxp_s32_qspi_data *data = dev->data; + + k_sem_give(&data->sem); +#else + ARG_UNUSED(dev); +#endif +} + +/* + * This function retrieves the device instance used by the HAL + * to access the internal driver state. + */ +uint8_t nxp_s32_qspi_register_device(void); + +int nxp_s32_qspi_wait_until_ready(const struct device *dev); + +int nxp_s32_qspi_read(const struct device *dev, off_t offset, void *dest, size_t size); + +int nxp_s32_qspi_write(const struct device *dev, off_t offset, const void *src, size_t size); + +int nxp_s32_qspi_erase(const struct device *dev, off_t offset, size_t size); + +const struct flash_parameters *nxp_s32_qspi_get_parameters(const struct device *dev); + +#if defined(CONFIG_FLASH_PAGE_LAYOUT) +void nxp_s32_qspi_pages_layout(const struct device *dev, const struct flash_pages_layout **layout, + size_t *layout_size); +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +#if defined(CONFIG_FLASH_JESD216_API) || !defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) +int nxp_s32_qspi_read_id(const struct device *dev, uint8_t *id); +#endif /* CONFIG_FLASH_JESD216_API || !CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME */ + +#endif /* ZEPHYR_DRIVERS_FLASH_NXP_S32_QSPI_H_ */ diff --git a/drivers/flash/flash_nxp_s32_qspi_hyperflash.c b/drivers/flash/flash_nxp_s32_qspi_hyperflash.c new file mode 100644 index 0000000000000..4428aaded1f04 --- /dev/null +++ b/drivers/flash/flash_nxp_s32_qspi_hyperflash.c @@ -0,0 +1,247 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_s32_qspi_hyperflash + +#include +#include +#include + +#include + +#include "memc_nxp_s32_qspi.h" +#include "flash_nxp_s32_qspi.h" + +LOG_MODULE_REGISTER(nxp_s32_qspi_hyperflash, CONFIG_FLASH_LOG_LEVEL); + +/* Use the fixed command sets from Qspi_Ip_Hyperflash.c */ +extern Qspi_Ip_InstrOpType QSPI_IP_HF_LUT_NAME[QSPI_IP_HF_LUT_SIZE]; + +static int nxp_s32_qspi_init(const struct device *dev) +{ + struct nxp_s32_qspi_data *data = dev->data; + const struct nxp_s32_qspi_config *config = dev->config; + Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); + uint8_t dev_id[memory_cfg->readIdSettings.readIdSize]; + Qspi_Ip_StatusType status; + int ret = 0; + + /* Used by the HAL to retrieve the internal driver state */ + data->instance = nxp_s32_qspi_register_device(); + __ASSERT_NO_MSG(data->instance < QSPI_IP_MEM_INSTANCE_COUNT); + data->memory_conn_cfg.qspiInstance = memc_nxp_s32_qspi_get_instance(config->controller); + +#if defined(CONFIG_MULTITHREADING) + k_sem_init(&data->sem, 1, 1); +#endif + + if (!device_is_ready(config->controller)) { + LOG_ERR("Memory control device not ready"); + return -ENODEV; + } + + status = Qspi_Ip_Init(data->instance, (const Qspi_Ip_MemoryConfigType *)memory_cfg, + (const Qspi_Ip_MemoryConnectionType *)&data->memory_conn_cfg); + if (status != STATUS_QSPI_IP_SUCCESS) { + LOG_ERR("Fail to init memory device %d (%d)", data->instance, status); + return -EIO; + } + + /* Verify connectivity by reading the device ID */ + ret = nxp_s32_qspi_read_id(dev, dev_id); + if (ret != 0) { + LOG_ERR("Device ID read failed (%d)", ret); + return -ENODEV; + } + + if (memcmp(dev_id, memory_cfg->readIdSettings.readIdExpected, sizeof(dev_id))) { + LOG_ERR("Device id does not match config"); + return -EINVAL; + } + + return ret; +} + +static DEVICE_API(flash, nxp_s32_qspi_api) = { + .erase = nxp_s32_qspi_erase, + .write = nxp_s32_qspi_write, + .read = nxp_s32_qspi_read, + .get_parameters = nxp_s32_qspi_get_parameters, +#if defined(CONFIG_FLASH_PAGE_LAYOUT) + .page_layout = nxp_s32_qspi_pages_layout, +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ +}; + +#define QSPI_PAGE_LAYOUT(n) \ + .layout = { \ + .pages_count = (DT_INST_PROP(n, size) / 8) \ + / CONFIG_FLASH_NXP_S32_QSPI_LAYOUT_PAGE_SIZE, \ + .pages_size = CONFIG_FLASH_NXP_S32_QSPI_LAYOUT_PAGE_SIZE, \ + } + +#define QSPI_READ_ID_CFG(n) \ + { \ + .readIdLut = QSPI_IP_HF_LUT_READ, \ + .readIdSize = DT_INST_PROP_LEN(n, jedec_id), \ + .readIdExpected = DT_INST_PROP(n, jedec_id), \ + } + +#define QSPI_MEMORY_CONN_CFG(n) \ + { \ + .connectionType = (Qspi_Ip_ConnectionType)DT_INST_REG_ADDR(n), \ + .memAlignment = DT_INST_PROP(n, write_block_size) \ + } + +#define QSPI_ERASE_CFG(n) \ + { \ + .eraseTypes = { \ + { \ + .eraseLut = QSPI_IP_HF_LUT_SE, \ + .size = 12, /* 4 KB */ \ + }, \ + { \ + .eraseLut = QSPI_IP_HF_LUT_SE, \ + .size = 18, /* 256 KB */ \ + }, \ + { \ + .eraseLut = QSPI_IP_LUT_INVALID, \ + .size = 0, \ + }, \ + { \ + .eraseLut = QSPI_IP_LUT_INVALID, \ + .size = 0, \ + }, \ + }, \ + .chipEraseLut = QSPI_IP_HF_LUT_CE, \ + } + +#define QSPI_RESET_CFG(n) \ + { \ + .resetCmdLut = QSPI_IP_HF_LUT_RST, \ + .resetCmdCount = QSPI_IP_HF_RST_CNT, \ + } + +#define QSPI_STATUS_REG_CFG(n) \ + { \ + .statusRegInitReadLut = QSPI_IP_HF_LUT_RDSR, \ + .statusRegReadLut = QSPI_IP_HF_LUT_RDSR, \ + .statusRegWriteLut = QSPI_IP_LUT_INVALID, \ + .writeEnableSRLut = QSPI_IP_LUT_INVALID, \ + .writeEnableLut = QSPI_IP_LUT_INVALID, \ + .regSize = 1U, \ + .busyOffset = 0U, \ + .busyValue = 1U, \ + .writeEnableOffset = 1U, \ + } + +#define QSPI_INIT_CFG(n) \ + { \ + .opCount = 0U, \ + .operations = NULL, \ + } + +#define QSPI_LUT_CFG(n) \ + { \ + .opCount = QSPI_IP_HF_LUT_SIZE, \ + .lutOps = (Qspi_Ip_InstrOpType *)QSPI_IP_HF_LUT_NAME, \ + } + +#define QSPI_SUSPEND_CFG(n) \ + { \ + .eraseSuspendLut = QSPI_IP_HF_LUT_ES, \ + .eraseResumeLut = QSPI_IP_HF_LUT_ER, \ + .programSuspendLut = QSPI_IP_HF_LUT_PS, \ + .programResumeLut = QSPI_IP_HF_LUT_PR, \ + } + +#define QSPI_MEMORY_CFG(n) \ + { \ + .memType = QSPI_IP_HYPER_FLASH, \ + .hfConfig = &hyperflash_config_##n, \ + .memSize = DT_INST_PROP(n, size) / 8, \ + .pageSize = DT_INST_PROP(n, max_program_buffer_size), \ + .writeLut = QSPI_IP_HF_LUT_WRITE, \ + .readLut = QSPI_IP_HF_LUT_READ, \ + .read0xxLut = QSPI_IP_LUT_INVALID, \ + .read0xxLutAHB = QSPI_IP_LUT_INVALID, \ + .eraseSettings = QSPI_ERASE_CFG(n), \ + .statusConfig = QSPI_STATUS_REG_CFG(n), \ + .resetSettings = QSPI_RESET_CFG(n), \ + .initResetSettings = QSPI_RESET_CFG(n), \ + .initConfiguration = QSPI_INIT_CFG(n), \ + .lutSequences = QSPI_LUT_CFG(n), \ + .readIdSettings = QSPI_READ_ID_CFG(n), \ + .suspendSettings = QSPI_SUSPEND_CFG(n), \ + .initCallout = NULL, \ + .resetCallout = NULL, \ + .errorCheckCallout = NULL, \ + .eccCheckCallout = NULL, \ + .ctrlAutoCfgPtr = NULL, \ + } + +#define FLASH_NXP_S32_QSPI_DRV_STRENGTH(n) \ + COND_CODE_1(DT_INST_ENUM_IDX(n, vcc_mv), \ + (DT_INST_PROP(n, drive_strength_ohm) == 12 ? QSPI_IP_HF_DRV_STRENGTH_007 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 14 ? QSPI_IP_HF_DRV_STRENGTH_006 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 16 ? QSPI_IP_HF_DRV_STRENGTH_005 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 20 ? QSPI_IP_HF_DRV_STRENGTH_000 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 27 ? QSPI_IP_HF_DRV_STRENGTH_003 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 40 ? QSPI_IP_HF_DRV_STRENGTH_002 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 71 ? QSPI_IP_HF_DRV_STRENGTH_001 : \ + QSPI_IP_HF_DRV_STRENGTH_000))))))), \ + (DT_INST_PROP(n, drive_strength_ohm) == 20 ? QSPI_IP_HF_DRV_STRENGTH_007 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 24 ? QSPI_IP_HF_DRV_STRENGTH_006 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 27 ? QSPI_IP_HF_DRV_STRENGTH_000 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 34 ? QSPI_IP_HF_DRV_STRENGTH_004 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 45 ? QSPI_IP_HF_DRV_STRENGTH_003 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 68 ? QSPI_IP_HF_DRV_STRENGTH_002 : \ + (DT_INST_PROP(n, drive_strength_ohm) == 117 ? QSPI_IP_HF_DRV_STRENGTH_001 : \ + QSPI_IP_HF_DRV_STRENGTH_000)))))))) + +#define FLASH_NXP_S32_QSPI_SECTOR_MAP(n) \ + COND_CODE_1(DT_INST_PROP(n, support_only_uniform_sectors), \ + (DT_INST_ENUM_IDX(n, ppw_sectors_addr_mapping) ? \ + QSPI_IP_HF_UNIFORM_SECTORS_READ_PASSWORD_HIGH : \ + QSPI_IP_HF_UNIFORM_SECTORS_READ_PASSWORD_LOW), \ + (DT_INST_ENUM_IDX(n, ppw_sectors_addr_mapping) ? \ + QSPI_IP_HF_PARAM_AND_PASSWORD_MAP_HIGH : \ + QSPI_IP_HF_PARAM_AND_PASSWORD_MAP_LOW)) + +#define FLASH_NXP_S32_QSPI_INIT_DEVICE(n) \ + static Qspi_Ip_HyperFlashConfigType hyperflash_config_##n = \ + { \ + .outputDriverStrength = FLASH_NXP_S32_QSPI_DRV_STRENGTH(n), \ + .RWDSLowOnDualError = DT_INST_PROP(n, rwds_low_dual_error), \ + .secureRegionUnlocked = !DT_INST_PROP(n, secure_region_locked), \ + .readLatency = DT_INST_ENUM_IDX(n, read_latency_cycles), \ + .paramSectorMap = FLASH_NXP_S32_QSPI_SECTOR_MAP(n), \ + .deviceIdWordAddress = DT_INST_PROP(n, device_id_word_addr), \ + }; \ + static const struct nxp_s32_qspi_config nxp_s32_qspi_config_##n = { \ + .controller = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .flash_parameters = { \ + .write_block_size = DT_INST_PROP(n, write_block_size), \ + .erase_value = QSPI_ERASE_VALUE, \ + }, \ + IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, \ + (QSPI_PAGE_LAYOUT(n),)) \ + .memory_cfg = QSPI_MEMORY_CFG(n), \ + }; \ + \ + static struct nxp_s32_qspi_data nxp_s32_qspi_data_##n = { \ + .memory_conn_cfg = QSPI_MEMORY_CONN_CFG(n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + nxp_s32_qspi_init, \ + NULL, \ + &nxp_s32_qspi_data_##n, \ + &nxp_s32_qspi_config_##n, \ + POST_KERNEL, \ + CONFIG_FLASH_INIT_PRIORITY, \ + &nxp_s32_qspi_api); + +DT_INST_FOREACH_STATUS_OKAY(FLASH_NXP_S32_QSPI_INIT_DEVICE) diff --git a/drivers/flash/flash_nxp_s32_qspi_nor.c b/drivers/flash/flash_nxp_s32_qspi_nor.c index 9250b3ec0eaa3..b7c13290b3a17 100644 --- a/drivers/flash/flash_nxp_s32_qspi_nor.c +++ b/drivers/flash/flash_nxp_s32_qspi_nor.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,7 @@ LOG_MODULE_REGISTER(nxp_s32_qspi_nor, CONFIG_FLASH_LOG_LEVEL); #include "jesd216.h" #include "memc_nxp_s32_qspi.h" +#include "flash_nxp_s32_qspi.h" #define QSPI_INST_NODE_HAS_PROP_EQ_AND_OR(n, prop, val) \ COND_CODE_1(DT_INST_NODE_HAS_PROP(n, prop), \ @@ -55,52 +56,9 @@ LOG_MODULE_REGISTER(nxp_s32_qspi_nor, CONFIG_FLASH_LOG_LEVEL); (_CONCAT(QSPI_SEQ_READ_, DT_INST_STRING_UPPER_TOKEN(n, readoc))),\ (QSPI_SEQ_READ_1_1_1)) -#define QSPI_ERASE_VALUE 0xff -#define QSPI_WRITE_BLOCK_SIZE 1U - -#define QSPI_IS_ALIGNED(addr, bits) (((addr) & BIT_MASK(bits)) == 0) - #define QSPI_LUT_ENTRY_SIZE (FEATURE_QSPI_LUT_SEQUENCE_SIZE * 2) #define QSPI_LUT_IDX(n) (n * QSPI_LUT_ENTRY_SIZE) -#if defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) -/* Size of LUT */ -#define QSPI_SFDP_LUT_SIZE 130U -/* Size of init operations */ -#define QSPI_SFDP_INIT_OP_SIZE 8U -#if defined(CONFIG_FLASH_JESD216_API) -/* Size of all LUT sequences for JESD216 operations */ -#define QSPI_JESD216_SEQ_SIZE 8U -#endif /* CONFIG_FLASH_JESD216_API */ -#endif /* CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME */ - -struct nxp_s32_qspi_config { - const struct device *controller; - struct flash_parameters flash_parameters; -#if defined(CONFIG_FLASH_PAGE_LAYOUT) - struct flash_pages_layout layout; -#endif -#if !defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) - const Qspi_Ip_MemoryConfigType memory_cfg; - enum jesd216_dw15_qer_type qer_type; - bool quad_mode; -#endif -}; - -struct nxp_s32_qspi_data { - uint8_t instance; - Qspi_Ip_MemoryConnectionType memory_conn_cfg; - uint8_t read_sfdp_lut_idx; -#if defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) - Qspi_Ip_MemoryConfigType memory_cfg; - Qspi_Ip_InstrOpType lut_ops[QSPI_SFDP_LUT_SIZE]; - Qspi_Ip_InitOperationType init_ops[QSPI_SFDP_INIT_OP_SIZE]; -#endif -#if defined(CONFIG_MULTITHREADING) - struct k_sem sem; -#endif -}; - enum { QSPI_SEQ_RDSR, QSPI_SEQ_RDSR2, @@ -145,7 +103,7 @@ enum { #endif }; -#if !defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) +#if !defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) static const Qspi_Ip_InstrOpType nxp_s32_qspi_lut[][QSPI_LUT_ENTRY_SIZE] = { [QSPI_SEQ_RDSR] = { QSPI_LUT_OP(QSPI_IP_LUT_INSTR_CMD, QSPI_IP_LUT_PADS_1, SPI_NOR_CMD_RDSR), @@ -309,73 +267,9 @@ static const Qspi_Ip_InstrOpType nxp_s32_qspi_lut[][QSPI_LUT_ENTRY_SIZE] = { }, #endif }; -#endif /* !defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) */ - -static ALWAYS_INLINE Qspi_Ip_MemoryConfigType *get_memory_config(const struct device *dev) -{ -#if defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) - return &((struct nxp_s32_qspi_data *)dev->data)->memory_cfg; -#else - return ((Qspi_Ip_MemoryConfigType *) - &((const struct nxp_s32_qspi_config *)dev->config)->memory_cfg); -#endif -} - -static ALWAYS_INLINE bool area_is_subregion(const struct device *dev, off_t offset, size_t size) -{ - Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); - - return ((offset >= 0) && (offset < memory_cfg->memSize) - && ((size + offset) <= memory_cfg->memSize)); -} - -static inline void nxp_s32_qspi_lock(const struct device *dev) -{ -#ifdef CONFIG_MULTITHREADING - struct nxp_s32_qspi_data *data = dev->data; - - k_sem_take(&data->sem, K_FOREVER); -#else - ARG_UNUSED(dev); -#endif -} - -static inline void nxp_s32_qspi_unlock(const struct device *dev) -{ -#ifdef CONFIG_MULTITHREADING - struct nxp_s32_qspi_data *data = dev->data; - - k_sem_give(&data->sem); -#else - ARG_UNUSED(dev); -#endif -} - -/* Must be called with lock */ -static int nxp_s32_qspi_wait_until_ready(const struct device *dev) -{ - struct nxp_s32_qspi_data *data = dev->data; - Qspi_Ip_StatusType status; - uint32_t timeout = 0xFFFFFF; - int ret = 0; - - do { - status = Qspi_Ip_GetMemoryStatus(data->instance); - timeout--; - } while ((status == STATUS_QSPI_IP_BUSY) && (timeout > 0)); - - if (status != STATUS_QSPI_IP_SUCCESS) { - LOG_ERR("Failed to read memory status (%d)", status); - ret = -EIO; - } else if (timeout <= 0) { - LOG_ERR("Timeout, memory is busy"); - ret = -ETIMEDOUT; - } - - return ret; -} +#endif /* !defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) */ -#if !defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) +#if !defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) static int nxp_s32_qspi_read_status_register(const struct device *dev, uint8_t reg_num, uint8_t *val) @@ -565,210 +459,7 @@ static int nxp_s32_qspi_set_quad_mode(const struct device *dev, bool enabled) return ret; } -#endif /* !defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) */ - -static int nxp_s32_qspi_read(const struct device *dev, off_t offset, void *dest, size_t size) -{ - struct nxp_s32_qspi_data *data = dev->data; - Qspi_Ip_StatusType status; - int ret = 0; - - if (!dest) { - return -EINVAL; - } - - if (!area_is_subregion(dev, offset, size)) { - return -ENODEV; - } - - if (size) { - nxp_s32_qspi_lock(dev); - - status = Qspi_Ip_Read(data->instance, (uint32_t)offset, (uint8_t *)dest, - (uint32_t)size); - if (status != STATUS_QSPI_IP_SUCCESS) { - LOG_ERR("Failed to read %zu bytes at 0x%lx (%d)", - size, offset, status); - ret = -EIO; - } - - nxp_s32_qspi_unlock(dev); - } - - return ret; -} - -static int nxp_s32_qspi_write(const struct device *dev, off_t offset, const void *src, size_t size) -{ - struct nxp_s32_qspi_data *data = dev->data; - Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); - Qspi_Ip_StatusType status; - size_t max_write = (size_t)MIN(QSPI_IP_MAX_WRITE_SIZE, memory_cfg->pageSize); - size_t len; - int ret = 0; - - if (!src) { - return -EINVAL; - } - - if (!area_is_subregion(dev, offset, size)) { - return -ENODEV; - } - - nxp_s32_qspi_lock(dev); - - while (size) { - len = MIN(max_write - (offset % max_write), size); - status = Qspi_Ip_Program(data->instance, (uint32_t)offset, - (const uint8_t *)src, (uint32_t)len); - if (status != STATUS_QSPI_IP_SUCCESS) { - LOG_ERR("Failed to write %zu bytes at 0x%lx (%d)", - len, offset, status); - ret = -EIO; - break; - } - - ret = nxp_s32_qspi_wait_until_ready(dev); - if (ret != 0) { - break; - } - - if (IS_ENABLED(CONFIG_FLASH_NXP_S32_QSPI_VERIFY_WRITE)) { - status = Qspi_Ip_ProgramVerify(data->instance, (uint32_t)offset, - (const uint8_t *)src, (uint32_t)len); - if (status != STATUS_QSPI_IP_SUCCESS) { - LOG_ERR("Write verification failed at 0x%lx (%d)", - offset, status); - ret = -EIO; - break; - } - } - - size -= len; - src = (const uint8_t *)src + len; - offset += len; - } - - nxp_s32_qspi_unlock(dev); - - return ret; -} - -static int nxp_s32_qspi_erase_block(const struct device *dev, off_t offset, - size_t size, size_t *erase_size) -{ - struct nxp_s32_qspi_data *data = dev->data; - Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); - Qspi_Ip_EraseVarConfigType *etp = NULL; - Qspi_Ip_EraseVarConfigType *etp_tmp; - Qspi_Ip_StatusType status; - int ret = 0; - - /* - * Find the erase type with bigger size that can erase all or part of the - * requested memory size - */ - for (uint8_t i = 0; i < QSPI_IP_ERASE_TYPES; i++) { - etp_tmp = (Qspi_Ip_EraseVarConfigType *)&(memory_cfg->eraseSettings.eraseTypes[i]); - if ((etp_tmp->eraseLut != QSPI_IP_LUT_INVALID) - && QSPI_IS_ALIGNED(offset, etp_tmp->size) - && (BIT(etp_tmp->size) <= size) - && ((etp == NULL) || (etp_tmp->size > etp->size))) { - - etp = etp_tmp; - } - } - if (etp != NULL) { - *erase_size = BIT(etp->size); - status = Qspi_Ip_EraseBlock(data->instance, (uint32_t)offset, *erase_size); - if (status != STATUS_QSPI_IP_SUCCESS) { - LOG_ERR("Failed to erase %zu bytes at 0x%lx (%d)", - *erase_size, (long)offset, status); - ret = -EIO; - } - } else { - LOG_ERR("Can't find erase size to erase %zu bytes", size); - ret = -EINVAL; - } - - return ret; -} - -static int nxp_s32_qspi_erase(const struct device *dev, off_t offset, size_t size) -{ - struct nxp_s32_qspi_data *data = dev->data; - Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); - Qspi_Ip_StatusType status; - size_t erase_size; - int ret = 0; - - if (!area_is_subregion(dev, offset, size)) { - return -ENODEV; - } - - nxp_s32_qspi_lock(dev); - - if (size == memory_cfg->memSize) { - status = Qspi_Ip_EraseChip(data->instance); - if (status != STATUS_QSPI_IP_SUCCESS) { - LOG_ERR("Failed to erase chip (%d)", status); - ret = -EIO; - } - } else { - while (size > 0) { - erase_size = 0; - - ret = nxp_s32_qspi_erase_block(dev, offset, size, &erase_size); - if (ret != 0) { - break; - } - - ret = nxp_s32_qspi_wait_until_ready(dev); - if (ret != 0) { - break; - } - - if (IS_ENABLED(CONFIG_FLASH_NXP_S32_QSPI_VERIFY_ERASE)) { - status = Qspi_Ip_EraseVerify(data->instance, (uint32_t)offset, - erase_size); - if (status != STATUS_QSPI_IP_SUCCESS) { - LOG_ERR("Erase verification failed at 0x%lx (%d)", - offset, status); - ret = -EIO; - break; - } - } - - offset += erase_size; - size -= erase_size; - } - } - - nxp_s32_qspi_unlock(dev); - - return ret; -} - -#if defined(CONFIG_FLASH_JESD216_API) || !defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) -static int nxp_s32_qspi_read_id(const struct device *dev, uint8_t *id) -{ - struct nxp_s32_qspi_data *data = dev->data; - Qspi_Ip_StatusType status; - int ret = 0; - - nxp_s32_qspi_lock(dev); - - status = Qspi_Ip_ReadId(data->instance, id); - if (status != STATUS_QSPI_IP_SUCCESS) { - LOG_ERR("Failed to read device ID (%d)", status); - ret = -EIO; - } - - nxp_s32_qspi_unlock(dev); - - return ret; -} -#endif /* CONFIG_FLASH_JESD216_API || !CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME */ +#endif /* !defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) */ #if defined(CONFIG_FLASH_JESD216_API) static int nxp_s32_qspi_sfdp_read(const struct device *dev, off_t offset, void *buf, size_t len) @@ -792,7 +483,7 @@ static int nxp_s32_qspi_sfdp_read(const struct device *dev, off_t offset, void * } #endif /* CONFIG_FLASH_JESD216_API */ -#if defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) +#if defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) static int nxp_s32_qspi_sfdp_config(const struct device *dev) { struct nxp_s32_qspi_data *data = dev->data; @@ -852,36 +543,16 @@ static int nxp_s32_qspi_sfdp_config(const struct device *dev) } #endif -static const struct flash_parameters *nxp_s32_qspi_get_parameters(const struct device *dev) -{ - const struct nxp_s32_qspi_config *config = dev->config; - - return &config->flash_parameters; -} - -#if defined(CONFIG_FLASH_PAGE_LAYOUT) -static void nxp_s32_qspi_pages_layout(const struct device *dev, - const struct flash_pages_layout **layout, - size_t *layout_size) -{ - const struct nxp_s32_qspi_config *config = dev->config; - - *layout = &config->layout; - *layout_size = 1; -} -#endif /* CONFIG_FLASH_PAGE_LAYOUT */ - static int nxp_s32_qspi_init(const struct device *dev) { struct nxp_s32_qspi_data *data = dev->data; const struct nxp_s32_qspi_config *config = dev->config; Qspi_Ip_MemoryConfigType *memory_cfg = get_memory_config(dev); Qspi_Ip_StatusType status; - static uint8_t instance_cnt; int ret = 0; /* Used by the HAL to retrieve the internal driver state */ - data->instance = instance_cnt++; + data->instance = nxp_s32_qspi_register_device(); __ASSERT_NO_MSG(data->instance < QSPI_IP_MEM_INSTANCE_COUNT); data->memory_conn_cfg.qspiInstance = memc_nxp_s32_qspi_get_instance(config->controller); @@ -889,7 +560,7 @@ static int nxp_s32_qspi_init(const struct device *dev) k_sem_init(&data->sem, 1, 1); #endif -#if defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) +#if defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) nxp_s32_qspi_sfdp_config(dev); #endif @@ -903,7 +574,7 @@ static int nxp_s32_qspi_init(const struct device *dev) } -#if !defined(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME) +#if !defined(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME) uint8_t jedec_id[JESD216_READ_ID_LEN]; /* Verify connectivity by reading the device ID */ @@ -930,7 +601,7 @@ static int nxp_s32_qspi_init(const struct device *dev) if (ret < 0) { return ret; } -#endif /* !CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME */ +#endif /* !CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME */ return ret; } @@ -966,7 +637,7 @@ static DEVICE_API(flash, nxp_s32_qspi_api) = { #define QSPI_MEMORY_CONN_CFG(n) \ { \ .connectionType = (Qspi_Ip_ConnectionType)DT_INST_REG_ADDR(n), \ - .memAlignment = DT_INST_PROP_OR(n, memory_alignment, 1) \ + .memAlignment = DT_INST_PROP(n, write_block_size) \ } #define QSPI_ERASE_CFG(n) \ @@ -1037,7 +708,7 @@ static DEVICE_API(flash, nxp_s32_qspi_api) = { .memType = QSPI_IP_SERIAL_FLASH, \ .hfConfig = NULL, \ .memSize = DT_INST_PROP(n, size) / 8, \ - .pageSize = CONFIG_FLASH_NXP_S32_QSPI_LAYOUT_PAGE_SIZE, \ + .pageSize = DT_INST_PROP(n, max_program_buffer_size), \ .writeLut = QSPI_LUT_IDX(QSPI_WRITE_SEQ(n)), \ .readLut = QSPI_LUT_IDX(QSPI_READ_SEQ(n)), \ .read0xxLut = QSPI_IP_LUT_INVALID, \ @@ -1048,7 +719,7 @@ static DEVICE_API(flash, nxp_s32_qspi_api) = { .initResetSettings = QSPI_RESET_CFG(n), \ .initConfiguration = QSPI_INIT_CFG(n), \ .lutSequences = QSPI_LUT_CFG(n), \ - COND_CODE_1(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME, (), ( \ + COND_CODE_1(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME, (), ( \ .readIdSettings = QSPI_READ_ID_CFG(n),) \ ) \ .suspendSettings = { \ @@ -1065,7 +736,7 @@ static DEVICE_API(flash, nxp_s32_qspi_api) = { } #define FLASH_NXP_S32_QSPI_INIT_DEVICE(n) \ - COND_CODE_1(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME, (), ( \ + COND_CODE_1(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME, (), ( \ BUILD_ASSERT(DT_INST_NODE_HAS_PROP(n, jedec_id), \ "jedec-id is required for non-runtime SFDP"); \ BUILD_ASSERT(DT_INST_PROP_LEN(n, jedec_id) == JESD216_READ_ID_LEN,\ @@ -1075,12 +746,12 @@ static DEVICE_API(flash, nxp_s32_qspi_api) = { static const struct nxp_s32_qspi_config nxp_s32_qspi_config_##n = { \ .controller = DEVICE_DT_GET(DT_INST_BUS(n)), \ .flash_parameters = { \ - .write_block_size = QSPI_WRITE_BLOCK_SIZE, \ + .write_block_size = DT_INST_PROP(n, write_block_size), \ .erase_value = QSPI_ERASE_VALUE, \ }, \ IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, \ (QSPI_PAGE_LAYOUT(n),)) \ - COND_CODE_1(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME, (), ( \ + COND_CODE_1(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME, (), ( \ .memory_cfg = QSPI_MEMORY_CFG(n), \ .qer_type = QSPI_QER_TYPE(n), \ .quad_mode = QSPI_HAS_QUAD_MODE(n) \ @@ -1089,7 +760,7 @@ static DEVICE_API(flash, nxp_s32_qspi_api) = { \ static struct nxp_s32_qspi_data nxp_s32_qspi_data_##n = { \ .memory_conn_cfg = QSPI_MEMORY_CONN_CFG(n), \ - COND_CODE_1(CONFIG_FLASH_NXP_S32_QSPI_NOR_SFDP_RUNTIME, (), ( \ + COND_CODE_1(CONFIG_FLASH_NXP_S32_QSPI_SFDP_RUNTIME, (), ( \ .read_sfdp_lut_idx = QSPI_LUT_IDX(QSPI_SEQ_READ_SFDP), \ )) \ }; \ diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index 74b490266e747..068a108fc9124 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -54,7 +54,7 @@ static int parse_helper(const struct shell *sh, size_t *argc, if (*endptr != '\0') { /* flash controller from user input */ - *flash_dev = device_get_binding((*argv)[1]); + *flash_dev = shell_device_get_binding((*argv)[1]); if (!*flash_dev) { shell_error(sh, "Given flash device was not found"); return -ENODEV; @@ -193,8 +193,8 @@ static int cmd_copy(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - src_dev = device_get_binding(argv[1]); - dst_dev = device_get_binding(argv[2]); + src_dev = shell_device_get_binding(argv[1]); + dst_dev = shell_device_get_binding(argv[2]); src_offset = strtoul(argv[3], NULL, 0); dst_offset = strtoul(argv[4], NULL, 0); /* size will be padded to write_size bytes */ @@ -736,9 +736,14 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry); SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); +static bool device_is_flash(const struct device *dev) +{ + return DEVICE_API_IS(flash, dev); +} + static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_flash); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/flash/flash_stm32.c b/drivers/flash/flash_stm32.c index adcfcdd83e076..c07ccd9d056af 100644 --- a/drivers/flash/flash_stm32.c +++ b/drivers/flash/flash_stm32.c @@ -22,7 +22,6 @@ #include #include "flash_stm32.h" -#include "stm32_hsem.h" LOG_MODULE_REGISTER(flash_stm32, CONFIG_FLASH_LOG_LEVEL); @@ -43,7 +42,7 @@ static const struct flash_parameters flash_stm32_parameters = { #endif }; -static int flash_stm32_write_protection(const struct device *dev, bool enable); +static int flash_stm32_cr_lock(const struct device *dev, bool enable); bool __weak flash_stm32_valid_range(const struct device *dev, off_t offset, uint32_t len, bool write) @@ -59,32 +58,6 @@ int __weak flash_stm32_check_configuration(void) return 0; } -#if defined(CONFIG_MULTITHREADING) -/* - * This is named flash_stm32_sem_take instead of flash_stm32_lock (and - * similarly for flash_stm32_sem_give) to avoid confusion with locking - * actual flash pages. - */ -static inline void _flash_stm32_sem_take(const struct device *dev) -{ - k_sem_take(&FLASH_STM32_PRIV(dev)->sem, K_FOREVER); - z_stm32_hsem_lock(CFG_HW_FLASH_SEMID, HSEM_LOCK_WAIT_FOREVER); -} - -static inline void _flash_stm32_sem_give(const struct device *dev) -{ - z_stm32_hsem_unlock(CFG_HW_FLASH_SEMID); - k_sem_give(&FLASH_STM32_PRIV(dev)->sem); -} - -#define flash_stm32_sem_init(dev) k_sem_init(&FLASH_STM32_PRIV(dev)->sem, 1, 1) -#define flash_stm32_sem_take(dev) _flash_stm32_sem_take(dev) -#define flash_stm32_sem_give(dev) _flash_stm32_sem_give(dev) -#else -#define flash_stm32_sem_init(dev) -#define flash_stm32_sem_take(dev) -#define flash_stm32_sem_give(dev) -#endif #if !defined(CONFIG_SOC_SERIES_STM32WBX) static int flash_stm32_check_status(const struct device *dev) @@ -202,14 +175,14 @@ static int flash_stm32_erase(const struct device *dev, off_t offset, LOG_DBG("Erase offset: %ld, len: %zu", (long int) offset, len); - rc = flash_stm32_write_protection(dev, false); + rc = flash_stm32_cr_lock(dev, false); if (rc == 0) { rc = flash_stm32_block_erase_loop(dev, offset, len); } flash_stm32_flush_caches(dev, offset, len); - int rc2 = flash_stm32_write_protection(dev, true); + int rc2 = flash_stm32_cr_lock(dev, true); if (!rc) { rc = rc2; @@ -239,12 +212,12 @@ static int flash_stm32_write(const struct device *dev, off_t offset, LOG_DBG("Write offset: %ld, len: %zu", (long int) offset, len); - rc = flash_stm32_write_protection(dev, false); + rc = flash_stm32_cr_lock(dev, false); if (rc == 0) { rc = flash_stm32_write_range(dev, offset, data, len); } - int rc2 = flash_stm32_write_protection(dev, true); + int rc2 = flash_stm32_cr_lock(dev, true); if (!rc) { rc = rc2; @@ -255,7 +228,7 @@ static int flash_stm32_write(const struct device *dev, off_t offset, return rc; } -static int flash_stm32_write_protection(const struct device *dev, bool enable) +static int flash_stm32_cr_lock(const struct device *dev, bool enable) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); @@ -319,7 +292,7 @@ int flash_stm32_option_bytes_lock(const struct device *dev, bool enable) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); -#if defined(FLASH_OPTCR_OPTLOCK) /* F2, F4, F7 and H7 */ +#if defined(FLASH_OPTCR_OPTLOCK) /* F2, F4, F7 */ if (enable) { regs->OPTCR |= FLASH_OPTCR_OPTLOCK; } else if (regs->OPTCR & FLASH_OPTCR_OPTLOCK) { @@ -331,7 +304,7 @@ int flash_stm32_option_bytes_lock(const struct device *dev, bool enable) /* Unlock CR/PECR/NSCR register if needed. */ if (!enable) { - rc = flash_stm32_write_protection(dev, false); + rc = flash_stm32_cr_lock(dev, false); if (rc) { return rc; } @@ -374,7 +347,7 @@ int flash_stm32_option_bytes_lock(const struct device *dev, bool enable) #endif /* Lock CR/PECR/NSCR register if needed. */ if (enable) { - rc = flash_stm32_write_protection(dev, true); + rc = flash_stm32_cr_lock(dev, true); if (rc) { return rc; } @@ -391,12 +364,11 @@ int flash_stm32_option_bytes_lock(const struct device *dev, bool enable) } #if defined(CONFIG_FLASH_EX_OP_ENABLED) && defined(CONFIG_FLASH_STM32_BLOCK_REGISTERS) -static int flash_stm32_control_register_disable(const struct device *dev) +int flash_stm32_control_register_disable(const struct device *dev) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); -#if defined(FLASH_CR_LOCK) /* F0, F1, F2, F3, F4, F7, L4, G0, G4, H7, WB, WL \ - */ +#if defined(FLASH_CR_LOCK) /* F0, F1, F2, F3, F4, F7, L4, G0, G4, WB, WL */ /* * Access to control register can be disabled by writing wrong key to * the key register. Option register will remain disabled until reset. @@ -421,11 +393,11 @@ static int flash_stm32_control_register_disable(const struct device *dev) #endif } -static int flash_stm32_option_bytes_disable(const struct device *dev) +int flash_stm32_option_bytes_disable(const struct device *dev) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); -#if defined(FLASH_OPTCR_OPTLOCK) /* F2, F4, F7 and H7 */ +#if defined(FLASH_OPTCR_OPTLOCK) /* F2, F4, F7 */ /* * Access to option register can be disabled by writing wrong key to * the key register. Option register will remain disabled until reset. @@ -459,41 +431,6 @@ flash_stm32_get_parameters(const struct device *dev) return &flash_stm32_parameters; } -#ifdef CONFIG_FLASH_EX_OP_ENABLED -static int flash_stm32_ex_op(const struct device *dev, uint16_t code, - const uintptr_t in, void *out) -{ - int rv = -ENOTSUP; - - flash_stm32_sem_take(dev); - - switch (code) { -#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) - case FLASH_STM32_EX_OP_SECTOR_WP: - rv = flash_stm32_ex_op_sector_wp(dev, in, out); - break; -#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */ -#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) - case FLASH_STM32_EX_OP_RDP: - rv = flash_stm32_ex_op_rdp(dev, in, out); - break; -#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ -#if defined(CONFIG_FLASH_STM32_BLOCK_REGISTERS) - case FLASH_STM32_EX_OP_BLOCK_OPTION_REG: - rv = flash_stm32_option_bytes_disable(dev); - break; - case FLASH_STM32_EX_OP_BLOCK_CONTROL_REG: - rv = flash_stm32_control_register_disable(dev); - break; -#endif /* CONFIG_FLASH_STM32_BLOCK_REGISTERS */ - } - - flash_stm32_sem_give(dev); - - return rv; -} -#endif - static struct flash_stm32_priv flash_data = { .regs = (FLASH_TypeDef *) DT_INST_REG_ADDR(0), /* Getting clocks information from device tree description depending @@ -524,7 +461,7 @@ static int stm32_flash_init(const struct device *dev) { int rc; /* Below is applicable to F0, F1, F3, G0, G4, L1, L4, L5, U5 & WB55 series. - * For F2, F4, F7 & H7 series, this is not applicable. + * For F2, F4, F7 series, this is not applicable. */ #if DT_INST_NODE_HAS_PROP(0, clocks) struct flash_stm32_priv *p = FLASH_STM32_PRIV(dev); diff --git a/drivers/flash/flash_stm32.h b/drivers/flash/flash_stm32.h index b4dc26dd907a8..01d0c21d3f5fe 100644 --- a/drivers/flash/flash_stm32.h +++ b/drivers/flash/flash_stm32.h @@ -10,6 +10,7 @@ #define ZEPHYR_DRIVERS_FLASH_FLASH_STM32_H_ #include +#include "stm32_hsem.h" #if DT_NODE_HAS_PROP(DT_INST(0, st_stm32_flash_controller), clocks) || \ DT_NODE_HAS_PROP(DT_INST(0, st_stm32h7_flash_controller), clocks) @@ -271,6 +272,40 @@ static inline bool flash_stm32_range_exists(const struct device *dev, } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +#if defined(CONFIG_MULTITHREADING) || defined(CONFIG_STM32H7_DUAL_CORE) +/* + * This is named flash_stm32_sem_take instead of flash_stm32_lock (and + * similarly for flash_stm32_sem_give) to avoid confusion with locking + * actual flash pages. + */ + +static inline void _flash_stm32_sem_take(const struct device *dev) +{ + k_sem_take(&FLASH_STM32_PRIV(dev)->sem, K_FOREVER); + z_stm32_hsem_lock(CFG_HW_FLASH_SEMID, HSEM_LOCK_WAIT_FOREVER); +} + +static inline void _flash_stm32_sem_give(const struct device *dev) +{ + z_stm32_hsem_unlock(CFG_HW_FLASH_SEMID); + k_sem_give(&FLASH_STM32_PRIV(dev)->sem); +} + +#define flash_stm32_sem_init(dev) k_sem_init(&FLASH_STM32_PRIV(dev)->sem, 1, 1) +#define flash_stm32_sem_take(dev) _flash_stm32_sem_take(dev) +#define flash_stm32_sem_give(dev) _flash_stm32_sem_give(dev) +#else +#define flash_stm32_sem_init(dev) +#define flash_stm32_sem_take(dev) +#define flash_stm32_sem_give(dev) +#endif /* CONFIG_MULTITHREADING */ + +#ifdef CONFIG_FLASH_EX_OP_ENABLED +int flash_stm32_ex_op(const struct device *dev, uint16_t code, + const uintptr_t in, void *out); +#endif /* CONFIG_FLASH_EX_OP_ENABLED */ + static inline bool flash_stm32_valid_write(off_t offset, uint32_t len) { return ((offset % FLASH_STM32_WRITE_BLOCK_SIZE == 0) && @@ -291,6 +326,11 @@ int flash_stm32_wait_flash_idle(const struct device *dev); int flash_stm32_option_bytes_lock(const struct device *dev, bool enable); +uint32_t flash_stm32_option_bytes_read(const struct device *dev); + +int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask, + uint32_t value); + #ifdef CONFIG_SOC_SERIES_STM32WBX int flash_stm32_check_status(const struct device *dev); #endif /* CONFIG_SOC_SERIES_STM32WBX */ @@ -304,11 +344,11 @@ void flash_stm32_page_layout(const struct device *dev, #if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) int flash_stm32_update_wp_sectors(const struct device *dev, - uint32_t changed_sectors, - uint32_t protected_sectors); + uint64_t changed_sectors, + uint64_t protected_sectors); int flash_stm32_get_wp_sectors(const struct device *dev, - uint32_t *protected_sectors); + uint64_t *protected_sectors); #endif #if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) uint8_t flash_stm32_get_rdp_level(const struct device *dev); @@ -316,14 +356,9 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev); void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level); #endif -/* Flash extended operations */ -#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) -int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in, - void *out); -#endif -#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) -int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in, - void *out); +#if defined(CONFIG_FLASH_STM32_BLOCK_REGISTERS) +int flash_stm32_control_register_disable(const struct device *dev); +int flash_stm32_option_bytes_disable(const struct device *dev); #endif #endif /* ZEPHYR_DRIVERS_FLASH_FLASH_STM32_H_ */ diff --git a/drivers/flash/flash_stm32_ex_op.c b/drivers/flash/flash_stm32_ex_op.c index 6f7e1fd349bcf..a129e30b306f7 100644 --- a/drivers/flash/flash_stm32_ex_op.c +++ b/drivers/flash/flash_stm32_ex_op.c @@ -28,7 +28,7 @@ int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in, (const struct flash_stm32_ex_op_sector_wp_in *)in; struct flash_stm32_ex_op_sector_wp_out *result = (struct flash_stm32_ex_op_sector_wp_out *)out; - uint32_t change_mask; + uint64_t change_mask; int rc = 0, rc2 = 0; #ifdef CONFIG_USERSPACE bool syscall_trap = z_syscall_trap(); @@ -225,3 +225,71 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in, return rc; } #endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ + +int flash_stm32_ex_op(const struct device *dev, uint16_t code, + const uintptr_t in, void *out) +{ + int rv = -ENOTSUP; + + flash_stm32_sem_take(dev); + + switch (code) { +#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) + case FLASH_STM32_EX_OP_SECTOR_WP: + rv = flash_stm32_ex_op_sector_wp(dev, in, out); + break; +#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */ +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) + case FLASH_STM32_EX_OP_RDP: + rv = flash_stm32_ex_op_rdp(dev, in, out); + break; +#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ +#if defined(CONFIG_FLASH_STM32_BLOCK_REGISTERS) + case FLASH_STM32_EX_OP_BLOCK_OPTION_REG: + rv = flash_stm32_option_bytes_disable(dev); + break; + case FLASH_STM32_EX_OP_BLOCK_CONTROL_REG: + rv = flash_stm32_control_register_disable(dev); + break; +#endif /* CONFIG_FLASH_STM32_BLOCK_REGISTERS */ +#if defined(CONFIG_FLASH_STM32_OPTION_BYTES) && ( \ + defined(CONFIG_DT_HAS_ST_STM32F4_FLASH_CONTROLLER_ENABLED) || \ + defined(CONFIG_DT_HAS_ST_STM32F7_FLASH_CONTROLLER_ENABLED) || \ + defined(CONFIG_DT_HAS_ST_STM32G4_FLASH_CONTROLLER_ENABLED) || \ + defined(CONFIG_DT_HAS_ST_STM32L4_FLASH_CONTROLLER_ENABLED)) + case FLASH_STM32_EX_OP_OPTB_READ: + if (out == NULL) { + rv = -EINVAL; + break; + } + + *(uint32_t *)out = flash_stm32_option_bytes_read(dev); + rv = 0; + + break; + case FLASH_STM32_EX_OP_OPTB_WRITE: + int rv2; + + rv = flash_stm32_option_bytes_lock(dev, false); + if (rv > 0) { + break; + } + + rv2 = flash_stm32_option_bytes_write(dev, UINT32_MAX, (uint32_t)in); + /* returned later, we always re-lock */ + + rv = flash_stm32_option_bytes_lock(dev, true); + if (rv > 0) { + break; + } + + rv = rv2; + + break; +#endif + } + + flash_stm32_sem_give(dev); + + return rv; +} diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 1057ee56635f0..0f0453d967f2f 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -2103,6 +2103,21 @@ static int flash_stm32_ospi_init(const struct device *dev) uint32_t prescaler = STM32_OSPI_CLOCK_PRESCALER_MIN; int ret; + if (!device_is_ready(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE))) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + +#ifdef CONFIG_STM32_MEMMAP + /* If MemoryMapped then configure skip init */ + if (stm32_ospi_is_memorymap(dev)) { + LOG_DBG("NOR init'd in MemMapped mode"); + /* Force HAL instance in correct state */ + dev_data->hospi.State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + /* The SPI/DTR is not a valid config of data_mode/data_rate according to the DTS */ if ((dev_cfg->data_mode != OSPI_OPI_MODE) && (dev_cfg->data_rate == OSPI_DTR_TRANSFER)) { @@ -2118,21 +2133,6 @@ static int flash_stm32_ospi_init(const struct device *dev) return ret; } - if (!device_is_ready(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE))) { - LOG_ERR("clock control device not ready"); - return -ENODEV; - } - -#ifdef CONFIG_STM32_MEMMAP - /* If MemoryMapped then configure skip init */ - if (stm32_ospi_is_memorymap(dev)) { - LOG_DBG("NOR init'd in MemMapped mode\n"); - /* Force HAL instance in correct state */ - dev_data->hospi.State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; - return 0; - } -#endif /* CONFIG_STM32_MEMMAP */ - #if STM32_OSPI_USE_DMA /* * DMA configuration diff --git a/drivers/flash/flash_stm32_xspi.c b/drivers/flash/flash_stm32_xspi.c index 2eeef514393a6..81d6f21eb6487 100644 --- a/drivers/flash/flash_stm32_xspi.c +++ b/drivers/flash/flash_stm32_xspi.c @@ -2019,6 +2019,21 @@ static int flash_stm32_xspi_init(const struct device *dev) uint32_t prescaler = STM32_XSPI_CLOCK_PRESCALER_MIN; int ret; + if (!device_is_ready(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE))) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + +#ifdef CONFIG_STM32_MEMMAP + /* If MemoryMapped then configure skip init */ + if (stm32_xspi_is_memorymap(dev)) { + LOG_DBG("NOR init'd in MemMapped mode"); + /* Force HAL instance in correct state */ + dev_data->hxspi.State = HAL_XSPI_STATE_BUSY_MEM_MAPPED; + return 0; + } +#endif /* CONFIG_STM32_MEMMAP */ + /* The SPI/DTR is not a valid config of data_mode/data_rate according to the DTS */ if ((dev_cfg->data_mode != XSPI_OCTO_MODE) && (dev_cfg->data_rate == XSPI_DTR_TRANSFER)) { @@ -2034,21 +2049,6 @@ static int flash_stm32_xspi_init(const struct device *dev) return ret; } - if (!device_is_ready(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE))) { - LOG_ERR("clock control device not ready"); - return -ENODEV; - } - -#ifdef CONFIG_STM32_MEMMAP - /* If MemoryMapped then configure skip init */ - if (stm32_xspi_is_memorymap(dev)) { - LOG_DBG("NOR init'd in MemMapped mode\n"); - /* Force HAL instance in correct state */ - dev_data->hxspi.State = HAL_XSPI_STATE_BUSY_MEM_MAPPED; - return 0; - } -#endif /* CONFIG_STM32_MEMMAP */ - if (dev_cfg->pclk_len > 3) { /* Max 3 domain clock are expected */ LOG_ERR("Could not select %d XSPI domain clock", dev_cfg->pclk_len); diff --git a/drivers/flash/flash_stm32f4x.c b/drivers/flash/flash_stm32f4x.c index d1790220ed46e..c828da49363ce 100644 --- a/drivers/flash/flash_stm32f4x.c +++ b/drivers/flash/flash_stm32f4x.c @@ -231,8 +231,8 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset, return rc; } -static __unused int write_optb(const struct device *dev, uint32_t mask, - uint32_t value) +int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask, + uint32_t value) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); int rc; @@ -264,10 +264,17 @@ static __unused int write_optb(const struct device *dev, uint32_t mask, return 0; } +uint32_t flash_stm32_option_bytes_read(const struct device *dev) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + return regs->OPTCR; +} + #if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) int flash_stm32_update_wp_sectors(const struct device *dev, - uint32_t changed_sectors, - uint32_t protected_sectors) + uint64_t changed_sectors, + uint64_t protected_sectors) { changed_sectors <<= FLASH_OPTCR_nWRP_Pos; protected_sectors <<= FLASH_OPTCR_nWRP_Pos; @@ -279,11 +286,12 @@ int flash_stm32_update_wp_sectors(const struct device *dev, /* Sector is protected when bit == 0. Flip protected_sectors bits */ protected_sectors = ~protected_sectors & changed_sectors; - return write_optb(dev, changed_sectors, protected_sectors); + return flash_stm32_option_bytes_write(dev, (uint32_t)changed_sectors, + (uint32_t)protected_sectors); } int flash_stm32_get_wp_sectors(const struct device *dev, - uint32_t *protected_sectors) + uint64_t *protected_sectors) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); @@ -304,8 +312,8 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev) void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level) { - write_optb(dev, FLASH_OPTCR_RDP_Msk, - (uint32_t)level << FLASH_OPTCR_RDP_Pos); + flash_stm32_option_bytes_write(dev, FLASH_OPTCR_RDP_Msk, + (uint32_t)level << FLASH_OPTCR_RDP_Pos); } #endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ diff --git a/drivers/flash/flash_stm32f7x.c b/drivers/flash/flash_stm32f7x.c index a1d6b9c6cb6ea..449531d53917f 100644 --- a/drivers/flash/flash_stm32f7x.c +++ b/drivers/flash/flash_stm32f7x.c @@ -159,8 +159,8 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset, return rc; } -static __unused int write_optb(const struct device *dev, uint32_t mask, - uint32_t value) +int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask, + uint32_t value) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); int rc; @@ -187,6 +187,13 @@ static __unused int write_optb(const struct device *dev, uint32_t mask, return flash_stm32_wait_flash_idle(dev); } +uint32_t flash_stm32_option_bytes_read(const struct device *dev) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + return regs->OPTCR; +} + #if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) uint8_t flash_stm32_get_rdp_level(const struct device *dev) { @@ -197,8 +204,8 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev) void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level) { - write_optb(dev, FLASH_OPTCR_RDP_Msk, - (uint32_t)level << FLASH_OPTCR_RDP_Pos); + flash_stm32_option_bytes_write(dev, FLASH_OPTCR_RDP_Msk, + (uint32_t)level << FLASH_OPTCR_RDP_Pos); } #endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ diff --git a/drivers/flash/flash_stm32g4x.c b/drivers/flash/flash_stm32g4x.c index 7e7b2c0fd4832..bdb0da182a138 100644 --- a/drivers/flash/flash_stm32g4x.c +++ b/drivers/flash/flash_stm32g4x.c @@ -255,8 +255,8 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset, return rc; } -static __unused int write_optb(const struct device *dev, uint32_t mask, - uint32_t value) +int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask, + uint32_t value) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); int rc; @@ -285,7 +285,17 @@ static __unused int write_optb(const struct device *dev, uint32_t mask, return rc; } - return 0; + /* Force the option byte loading */ + regs->CR |= FLASH_CR_OBL_LAUNCH; + + return flash_stm32_wait_flash_idle(dev); +} + +uint32_t flash_stm32_option_bytes_read(const struct device *dev) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + return regs->OPTR; } #if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) @@ -314,8 +324,8 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev) void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level) { - write_optb(dev, FLASH_OPTR_RDP_Msk, - (uint32_t)level << FLASH_OPTR_RDP_Pos); + flash_stm32_option_bytes_write(dev, FLASH_OPTR_RDP_Msk, + (uint32_t)level << FLASH_OPTR_RDP_Pos); } #endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ diff --git a/drivers/flash/flash_stm32h7x.c b/drivers/flash/flash_stm32h7x.c index d7ad93d0ac495..c793e8aca6757 100644 --- a/drivers/flash/flash_stm32h7x.c +++ b/drivers/flash/flash_stm32h7x.c @@ -33,7 +33,9 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); /* Let's wait for double the max erase time to be sure that the operation is * completed. */ -#define STM32H7_FLASH_TIMEOUT (2 * DT_PROP(DT_INST(0, st_stm32_nv_flash), max_erase_time)) +#define STM32H7_FLASH_TIMEOUT (2 * DT_PROP(DT_INST(0, st_stm32_nv_flash), max_erase_time)) +/* No information in documentation about that. */ +#define STM32H7_FLASH_OPT_TIMEOUT_MS 800 #define STM32H7_M4_FLASH_SIZE DT_PROP_OR(DT_INST(0, st_stm32_nv_flash), bank2_flash_size, 0) #ifdef CONFIG_CPU_CORTEX_M4 @@ -53,6 +55,9 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); * the serie, there is a discontinuty between bank1 and bank2. */ #define DISCONTINUOUS_BANKS (REAL_FLASH_SIZE_KB < STM32H7_SERIES_MAX_FLASH_KB) +#define NUMBER_OF_BANKS 2 +#else +#define NUMBER_OF_BANKS 1 #endif struct flash_stm32_sector_t { @@ -62,32 +67,272 @@ struct flash_stm32_sector_t { volatile uint32_t *sr; }; -#if defined(CONFIG_MULTITHREADING) || defined(CONFIG_STM32H7_DUAL_CORE) -/* - * This is named flash_stm32_sem_take instead of flash_stm32_lock (and - * similarly for flash_stm32_sem_give) to avoid confusion with locking - * actual flash sectors. - */ -static inline void _flash_stm32_sem_take(const struct device *dev) +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) || defined(CONFIG_FLASH_STM32_WRITE_PROTECT) + +static int commit_optb(const struct device *dev) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + int64_t timeout_time = k_uptime_get() + STM32H7_FLASH_OPT_TIMEOUT_MS; + + /* Make sure previous write is completed before committing option bytes. */ + barrier_dsync_fence_full(); + regs->OPTCR |= FLASH_OPTCR_OPTSTART; + barrier_dsync_fence_full(); + while (regs->OPTSR_CUR & FLASH_OPTSR_OPT_BUSY) { + if (k_uptime_get() > timeout_time) { + LOG_ERR("Timeout writing option bytes."); + return -ETIMEDOUT; + } + } + + return 0; +} + +/* Returns negative value on error, 0 if a change was not need, 1 if a change has been made. */ +static int write_opt(const struct device *dev, uint32_t mask, uint32_t value, uintptr_t cur, + bool commit) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + /* PRG register always follows CUR register. */ + uintptr_t prg = cur + 4; + int rc = 0; + + if (regs->OPTCR & FLASH_OPTCR_OPTLOCK) { + LOG_ERR("Option bytes locked"); + return -EIO; + } + + rc = flash_stm32_wait_flash_idle(dev); + if (rc < 0) { + LOG_ERR("Err flash no idle"); + return rc; + } + + if ((sys_read32(cur) & mask) == value) { + /* A change not needed, return 0. */ + return 0; + } + + sys_write32((sys_read32(cur) & ~mask) | value, prg); + + if (commit) { + rc = commit_optb(dev); + if (rc < 0) { + return rc; + } + } + + /* A change has been made, return 1. */ + return 1; +} + +#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT || CONFIG_FLASH_STM32_READOUT_PROTECTION */ + +#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION) +static int write_optsr(const struct device *dev, uint32_t mask, uint32_t value) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + uintptr_t cur = (uintptr_t)regs + offsetof(FLASH_TypeDef, OPTSR_CUR); + + return write_opt(dev, mask, value, cur, true); +} + +uint8_t flash_stm32_get_rdp_level(const struct device *dev) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + return (regs->OPTSR_CUR & FLASH_OPTSR_RDP_Msk) >> FLASH_OPTSR_RDP_Pos; +} + +void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level) +{ + write_optsr(dev, FLASH_OPTSR_RDP_Msk, (uint32_t)level << FLASH_OPTSR_RDP_Pos); +} +#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ + +#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) + +#define WP_MSK FLASH_WPSN_WRPSN_Msk +#define WP_POS FLASH_WPSN_WRPSN_Pos + +static int write_optwp(const struct device *dev, uint32_t mask, uint32_t value, uint32_t bank) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + uintptr_t cur = (uintptr_t)regs + offsetof(FLASH_TypeDef, WPSN_CUR1); + + if (bank >= NUMBER_OF_BANKS) { + return -EINVAL; + } + +#ifdef DUAL_BANK + if (bank == 1) { + cur = (uintptr_t)regs + offsetof(FLASH_TypeDef, WPSN_CUR2); + } +#endif /* DUAL_BANK */ + + return write_opt(dev, mask, value, cur, false); +} + +int flash_stm32_update_wp_sectors(const struct device *dev, uint64_t changed_sectors, + uint64_t protected_sectors) +{ + /* All banks share the same sector mask. */ + const uint64_t bank_mask = WP_MSK >> WP_POS; + const uint32_t sectors_per_bank = __builtin_popcount(WP_MSK); + uint64_t sectors_mask = 0; + uint32_t protected_sectors_reg; + uint32_t changed_sectors_reg; + int ret, ret2 = 0; + bool commit = false; + + for (int i = 0; i < NUMBER_OF_BANKS; i++) { + sectors_mask |= bank_mask << (sectors_per_bank * i); + } + + if ((changed_sectors & sectors_mask) != changed_sectors) { + return -EINVAL; + } + + for (int i = 0; i < NUMBER_OF_BANKS; i++) { + /* Prepare protected and changed masks per bank. */ + protected_sectors_reg = (protected_sectors >> sectors_per_bank * i) & bank_mask; + changed_sectors_reg = (changed_sectors >> sectors_per_bank * i) & bank_mask; + + if (changed_sectors_reg == 0) { + continue; + } + changed_sectors_reg <<= WP_POS; + protected_sectors_reg <<= WP_POS; + /* Sector is protected when bit == 0. Flip protected_sectors bits */ + protected_sectors_reg = ~protected_sectors_reg; + + ret = write_optwp(dev, changed_sectors_reg, protected_sectors_reg, i); + /* Option byte was successfully changed if the return value is greater than 0. */ + if (ret > 0) { + commit = true; + } else if (ret < 0) { + /* Do not continue changing WP on error. */ + ret2 = ret; + break; + } + } + + if (commit) { + ret = commit_optb(dev); + /* Make sure to return the first error. */ + if (ret < 0 && ret2 == 0) { + ret2 = ret; + } + } + + return ret2; +} + +int flash_stm32_get_wp_sectors(const struct device *dev, uint64_t *protected_sectors) { - k_sem_take(&FLASH_STM32_PRIV(dev)->sem, K_FOREVER); - z_stm32_hsem_lock(CFG_HW_FLASH_SEMID, HSEM_LOCK_WAIT_FOREVER); + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + *protected_sectors = (~regs->WPSN_CUR1 & WP_MSK) >> WP_POS; +#ifdef DUAL_BANK + /* Available only for STM32H7x */ + uint64_t proctected_sectors_2 = + (~regs->WPSN_CUR2 & WP_MSK) >> WP_POS; + const uint32_t sectors_per_bank = __builtin_popcount(WP_MSK); + *protected_sectors |= proctected_sectors_2 << sectors_per_bank; +#endif /* DUAL_BANK */ + + return 0; } +#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */ -static inline void _flash_stm32_sem_give(const struct device *dev) +#ifdef CONFIG_FLASH_STM32_BLOCK_REGISTERS +int flash_stm32_control_register_disable(const struct device *dev) { - z_stm32_hsem_unlock(CFG_HW_FLASH_SEMID); - k_sem_give(&FLASH_STM32_PRIV(dev)->sem); + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + /* + * Access to control register can be disabled by writing wrong key to + * the key register. Option register will remain disabled until reset. + * Writing wrong key causes a bus fault, so we need to set FAULTMASK to + * disable faults, and clear bus fault pending bit before enabling them + * again. + */ + regs->CR1 |= FLASH_CR_LOCK; +#ifdef DUAL_BANK + regs->CR2 |= FLASH_CR_LOCK; +#endif /* DUAL_BANK */ + + __set_FAULTMASK(1); + regs->KEYR1 = 0xffffffff; + +#ifdef DUAL_BANK + regs->KEYR2 = 0xffffffff; +#endif /* DUAL_BANK */ + /* Make sure that the fault occurs before we clear it. */ + barrier_dsync_fence_full(); + + /* Clear Bus Fault pending bit */ + SCB->SHCSR &= ~SCB_SHCSR_BUSFAULTPENDED_Msk; + /* Make sure to clear the fault before changing the fault mask. */ + barrier_dsync_fence_full(); + + __set_FAULTMASK(0); + + return 0; +} + +int flash_stm32_option_bytes_disable(const struct device *dev) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + /* + * Access to option register can be disabled by writing wrong key to + * the key register. Option register will remain disabled until reset. + * Writing wrong key causes a bus fault, so we need to set FAULTMASK to + * disable faults, and clear bus fault pending bit before enabling them + * again. + */ + regs->OPTCR |= FLASH_OPTCR_OPTLOCK; + + __set_FAULTMASK(1); + regs->OPTKEYR = 0xffffffff; + /* Make sure that the fault occurs before we clear it. */ + barrier_dsync_fence_full(); + + /* Clear Bus Fault pending bit */ + SCB->SHCSR &= ~SCB_SHCSR_BUSFAULTPENDED_Msk; + /* Make sure to clear the fault before changing the fault mask. */ + barrier_dsync_fence_full(); + __set_FAULTMASK(0); + + return 0; } +#endif /* CONFIG_FLASH_STM32_BLOCK_REGISTERS */ -#define flash_stm32_sem_init(dev) k_sem_init(&FLASH_STM32_PRIV(dev)->sem, 1, 1) -#define flash_stm32_sem_take(dev) _flash_stm32_sem_take(dev) -#define flash_stm32_sem_give(dev) _flash_stm32_sem_give(dev) +int flash_stm32_option_bytes_lock(const struct device *dev, bool enable) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + if (enable) { + regs->OPTCR |= FLASH_OPTCR_OPTLOCK; + } else if (regs->OPTCR & FLASH_OPTCR_OPTLOCK) { +#ifdef CONFIG_SOC_SERIES_STM32H7RSX + regs->OPTKEYR = FLASH_OPTKEY1; + regs->OPTKEYR = FLASH_OPTKEY2; #else -#define flash_stm32_sem_init(dev) -#define flash_stm32_sem_take(dev) -#define flash_stm32_sem_give(dev) -#endif + regs->OPTKEYR = FLASH_OPT_KEY1; + regs->OPTKEYR = FLASH_OPT_KEY2; +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ + } + + if (enable) { + LOG_DBG("Option bytes locked"); + } else { + LOG_DBG("Option bytes unlocked"); + } + + return 0; +} bool flash_stm32_valid_range(const struct device *dev, off_t offset, uint32_t len, bool write) { @@ -429,7 +674,7 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset, const return rc; } -static int flash_stm32h7_write_protection(const struct device *dev, bool enable) +static int flash_stm32h7_cr_lock(const struct device *dev, bool enable) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); @@ -508,7 +753,7 @@ static int flash_stm32h7_erase(const struct device *dev, off_t offset, size_t le LOG_DBG("Erase offset: %ld, len: %zu", (long)offset, len); - rc = flash_stm32h7_write_protection(dev, false); + rc = flash_stm32h7_cr_lock(dev, false); if (rc) { goto done; } @@ -524,7 +769,7 @@ static int flash_stm32h7_erase(const struct device *dev, off_t offset, size_t le } #endif /* CONFIG_CPU_CORTEX_M7 */ done: - rc2 = flash_stm32h7_write_protection(dev, true); + rc2 = flash_stm32h7_cr_lock(dev, true); if (!rc) { rc = rc2; @@ -552,12 +797,12 @@ static int flash_stm32h7_write(const struct device *dev, off_t offset, const voi LOG_DBG("Write offset: %ld, len: %zu", (long)offset, len); - rc = flash_stm32h7_write_protection(dev, false); + rc = flash_stm32h7_cr_lock(dev, false); if (!rc) { rc = flash_stm32_write_range(dev, offset, data, len); } - int rc2 = flash_stm32h7_write_protection(dev, true); + int rc2 = flash_stm32h7_cr_lock(dev, true); if (!rc) { rc = rc2; @@ -676,6 +921,9 @@ static DEVICE_API(flash, flash_stm32h7_api) = { #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_stm32_page_layout, #endif +#ifdef CONFIG_FLASH_EX_OP_ENABLED + .ex_op = flash_stm32_ex_op, +#endif }; static int stm32h7_flash_init(const struct device *dev) @@ -711,7 +959,7 @@ static int stm32h7_flash_init(const struct device *dev) } #endif - return flash_stm32h7_write_protection(dev, false); + return 0; } DEVICE_DT_INST_DEFINE(0, stm32h7_flash_init, NULL, &flash_data, NULL, POST_KERNEL, diff --git a/drivers/flash/flash_stm32l4x.c b/drivers/flash/flash_stm32l4x.c index c0a9207b7a588..91f496d81d98c 100644 --- a/drivers/flash/flash_stm32l4x.c +++ b/drivers/flash/flash_stm32l4x.c @@ -246,8 +246,8 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset, return rc; } -static __unused int write_optb(const struct device *dev, uint32_t mask, - uint32_t value) +int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask, + uint32_t value) { FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); int rc; @@ -276,7 +276,17 @@ static __unused int write_optb(const struct device *dev, uint32_t mask, return rc; } - return 0; + /* Force the option byte loading */ + regs->CR |= FLASH_CR_OBL_LAUNCH; + + return flash_stm32_wait_flash_idle(dev); +} + +uint32_t flash_stm32_option_bytes_read(const struct device *dev) +{ + FLASH_TypeDef *regs = FLASH_STM32_REGS(dev); + + return regs->OPTR; } #if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) @@ -305,8 +315,8 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev) void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level) { - write_optb(dev, FLASH_OPTR_RDP_Msk, - (uint32_t)level << FLASH_OPTR_RDP_Pos); + flash_stm32_option_bytes_write(dev, FLASH_OPTR_RDP_Msk, + (uint32_t)level << FLASH_OPTR_RDP_Pos); } #endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ diff --git a/drivers/flash/flash_stm32l5x.c b/drivers/flash/flash_stm32l5x.c index 49e4259969f23..e085ac3fd8196 100644 --- a/drivers/flash/flash_stm32l5x.c +++ b/drivers/flash/flash_stm32l5x.c @@ -20,16 +20,14 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); #include "flash_stm32.h" -#if defined(CONFIG_SOC_SERIES_STM32H5X) -/* at this time stm32h5 mcus have 128KB (stm32h50x) or 2MB (stm32h56x/57x) */ -#define STM32_SERIES_MAX_FLASH 2048 -#elif defined(CONFIG_SOC_SERIES_STM32L5X) -#define STM32_SERIES_MAX_FLASH 512 -#elif defined(CONFIG_SOC_SERIES_STM32U5X) -/* It is used to handle the 2 banks discontinuity case, the discontinuity is not happen on STM32U5, - * so define it to flash size to avoid the unexptected check. +#if defined(CONFIG_SOC_SERIES_STM32H5X) || defined(CONFIG_SOC_SERIES_STM32U5X) +/* + * It is used to handle the 2 banks discontinuity case, + * so define it to flash size to avoid the unexpected check. */ #define STM32_SERIES_MAX_FLASH (CONFIG_FLASH_SIZE) +#elif defined(CONFIG_SOC_SERIES_STM32L5X) +#define STM32_SERIES_MAX_FLASH 512 #endif #define PAGES_PER_BANK ((FLASH_SIZE / FLASH_PAGE_SIZE) / 2) diff --git a/drivers/flash/flash_stm32wba_fm.c b/drivers/flash/flash_stm32wba_fm.c index 8bf3f5d186b93..08838a147aad3 100644 --- a/drivers/flash/flash_stm32wba_fm.c +++ b/drivers/flash/flash_stm32wba_fm.c @@ -66,17 +66,6 @@ bool flash_stm32_valid_range(const struct device *dev, off_t offset, return flash_stm32_range_exists(dev, offset, len); } - -static inline void flash_stm32_sem_take(const struct device *dev) -{ - k_sem_take(&FLASH_STM32_PRIV(dev)->sem, K_FOREVER); -} - -static inline void flash_stm32_sem_give(const struct device *dev) -{ - k_sem_give(&FLASH_STM32_PRIV(dev)->sem); -} - static int flash_stm32_read(const struct device *dev, off_t offset, void *data, size_t len) diff --git a/drivers/flash/soc_flash_cc23x0.c b/drivers/flash/soc_flash_cc23x0.c new file mode 100644 index 0000000000000..dbcbad776ae57 --- /dev/null +++ b/drivers/flash/soc_flash_cc23x0.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define DT_DRV_COMPAT ti_cc23x0_flash_controller +#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) + +#define FLASH_ADDR DT_REG_ADDR(SOC_NV_FLASH_NODE) +#define FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE) +#define FLASH_ERASE_SIZE DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) +#define FLASH_WRITE_SIZE DT_PROP(SOC_NV_FLASH_NODE, write_block_size) + +struct flash_cc23x0_data { + struct k_sem mutex; +}; + +static const struct flash_parameters flash_cc23x0_parameters = { + .write_block_size = FLASH_WRITE_SIZE, + .erase_value = 0xff, +}; + +static int flash_cc23x0_init(const struct device *dev) +{ + struct flash_cc23x0_data *data = dev->data; + + k_sem_init(&data->mutex, 1, 1); + + return 0; +} + +static void flash_cc23x0_cache_restore(uint32_t vims_mode) +{ + while (VIMSModeGet(VIMS_BASE) == VIMS_MODE_CHANGING) { + ; + } + + /* Restore VIMS mode and line buffers */ + if (vims_mode != VIMS_MODE_DISABLED) { + VIMSModeSafeSet(VIMS_BASE, vims_mode, true); + } + + VIMSLineBufEnable(VIMS_BASE); +} + +static uint32_t flash_cc23x0_cache_disable(void) +{ + uint32_t vims_mode; + + /* VIMS and both line buffers should be off during flash update */ + VIMSLineBufDisable(VIMS_BASE); + + while (VIMSModeGet(VIMS_BASE) == VIMS_MODE_CHANGING) { + ; + } + + /* Save current VIMS mode for restoring it later */ + vims_mode = VIMSModeGet(VIMS_BASE); + if (vims_mode != VIMS_MODE_DISABLED) { + VIMSModeSafeSet(VIMS_BASE, VIMS_MODE_DISABLED, true); + } + + return vims_mode; +} + +static int flash_cc23x0_erase(const struct device *dev, off_t offs, size_t size) +{ + struct flash_cc23x0_data *data = dev->data; + uint32_t vims_mode; + unsigned int key; + int i; + int rc = 0; + size_t cnt; + + if (!size) { + return 0; + } + + /* Offset and length should be multiple of erase size */ + if (((offs % FLASH_ERASE_SIZE) != 0) || ((size % FLASH_ERASE_SIZE) != 0)) { + return -EINVAL; + } + + if (k_sem_take(&data->mutex, K_FOREVER)) { + return -EACCES; + } + + vims_mode = flash_cc23x0_cache_disable(); + /* + * Disable all interrupts to prevent flash read, from TI's TRF: + * + * During a FLASH memory write or erase operation, the FLASH memory + * must not be read. + */ + key = irq_lock(); + + /* Erase sector/page one by one, break out in case of an error */ + cnt = size / FLASH_ERASE_SIZE; + for (i = 0; i < cnt; i++, offs += FLASH_ERASE_SIZE) { + while (FlashCheckFsmForReady() != FAPI_STATUS_FSM_READY) { + ; + } + + rc = FlashEraseSector(offs); + if (rc != FAPI_STATUS_SUCCESS) { + rc = -EIO; + break; + } + } + + irq_unlock(key); + + flash_cc23x0_cache_restore(vims_mode); + + k_sem_give(&data->mutex); + return rc; +} + +static int flash_cc23x0_write(const struct device *dev, off_t offs, const void *data, size_t size) +{ + struct flash_cc23x0_data *flash_data = dev->data; + uint32_t vims_mode; + unsigned int key; + int rc = 0; + + if (!size) { + return 0; + } + + if (offs < 0 || size < 1) { + return -EINVAL; + } + + if (offs + size > FLASH_SIZE) { + return -EINVAL; + } + + /* + * From TI's HAL 'driverlib/flash.h': + * + * The pui8DataBuffer pointer can not point to flash. + */ + if ((data >= (void *)FLASH_ADDR) && (data <= (void *)(FLASH_ADDR + FLASH_SIZE))) { + return -EINVAL; + } + + if (k_sem_take(&flash_data->mutex, K_FOREVER)) { + return -EACCES; + } + + vims_mode = flash_cc23x0_cache_disable(); + + key = irq_lock(); + + while (FlashCheckFsmForReady() != FAPI_STATUS_FSM_READY) { + ; + } + + rc = FlashProgram((uint8_t *)data, offs, size); + if (rc != FAPI_STATUS_SUCCESS) { + rc = -EIO; + } + + irq_unlock(key); + + flash_cc23x0_cache_restore(vims_mode); + + k_sem_give(&flash_data->mutex); + + return rc; +} + +static int flash_cc23x0_read(const struct device *dev, off_t offs, void *data, size_t size) +{ + ARG_UNUSED(dev); + + if (!size) { + return 0; + } + + if (offs < 0 || size < 1) { + return -EINVAL; + } + + if (offs + size > FLASH_SIZE) { + return -EINVAL; + } + + memcpy(data, (void *)offs, size); + + return 0; +} + +static const struct flash_parameters *flash_cc23x0_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_cc23x0_parameters; +} + +#if defined(CONFIG_FLASH_PAGE_LAYOUT) +static const struct flash_pages_layout dev_layout = { + .pages_count = FLASH_SIZE / FLASH_ERASE_SIZE, + .pages_size = FLASH_ERASE_SIZE, +}; + +static void flash_cc23x0_layout(const struct device *dev, const struct flash_pages_layout **layout, + size_t *layout_size) +{ + *layout = &dev_layout; + *layout_size = 1; +} +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +static DEVICE_API(flash, flash_cc23x0_api) = { + .erase = flash_cc23x0_erase, + .write = flash_cc23x0_write, + .read = flash_cc23x0_read, + .get_parameters = flash_cc23x0_get_parameters, +#if defined(CONFIG_FLASH_PAGE_LAYOUT) + .page_layout = flash_cc23x0_layout, +#endif +}; + +static struct flash_cc23x0_data cc23x0_flash_data; + +DEVICE_DT_INST_DEFINE(0, flash_cc23x0_init, NULL, &cc23x0_flash_data, NULL, POST_KERNEL, + CONFIG_FLASH_INIT_PRIORITY, &flash_cc23x0_api); diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index 3ee1f55999ffd..86a06cddff30f 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -93,7 +93,7 @@ static uint32_t get_cmd_status(uint32_t cmd, uint32_t addr, size_t len) } /* This function prevents erroneous reading. Some ECC enabled devices will - * crash when reading an erased or wrongly programmed area. + * crash when reading an erased area. */ static status_t is_area_readable(uint32_t addr, size_t len) { @@ -102,21 +102,13 @@ static status_t is_area_readable(uint32_t addr, size_t len) key = irq_lock(); - /* Check if the are is correctly programmed and can be read. */ - status = get_cmd_status(FMC_CMD_MARGIN_CHECK, addr, len); - if (status & FMC_STATUS_FAILURES) { - /* If the area was erased, ECC errors are triggered on read. */ - status = get_cmd_status(FMC_CMD_BLANK_CHECK, addr, len); - if (!(status & FMC_STATUS_FAIL)) { - LOG_DBG("read request on erased addr:0x%08x size:%d", - addr, len); - irq_unlock(key); - return -ENODATA; - } - LOG_DBG("read request error for addr:0x%08x size:%d", + /* If the area was erased, ECC errors are triggered on read. */ + status = get_cmd_status(FMC_CMD_BLANK_CHECK, addr, len); + if (!(status & FMC_STATUS_FAIL)) { + LOG_DBG("read request on erased addr:0x%08x size:%d", addr, len); irq_unlock(key); - return -EIO; + return -ENODATA; } irq_unlock(key); diff --git a/drivers/flash/soc_flash_silabs_siwx91x.c b/drivers/flash/soc_flash_silabs_siwx91x.c new file mode 100644 index 0000000000000..9e714ce814d5b --- /dev/null +++ b/drivers/flash/soc_flash_silabs_siwx91x.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT silabs_siwx91x_flash_controller + +#include +#include +#include +#include + +#include "sl_si91x_driver.h" + +LOG_MODULE_REGISTER(siwx91x_soc_flash); + +struct siwx91x_config { + uintptr_t base_address; + uint32_t size; + uint32_t write_block_size; + uint32_t erase_block_size; + struct flash_parameters flash_parameters; +#ifdef CONFIG_FLASH_PAGE_LAYOUT + struct flash_pages_layout flash_pages_layout; +#endif +}; + +struct siwx91x_data { + struct k_sem lock; +}; + +static bool flash_siwx91x_range_is_in_bounds(const struct device *dev, off_t offset, size_t len) +{ + const struct siwx91x_config *cfg = dev->config; + + /* Note: If offset < __rom_region_end, the user to overwriting the current firmware. User + * is probably doing a mistake, but not an error from this driver point of view. + */ + if (offset < 0) { + return false; + } + if (offset + len > cfg->size) { + return false; + } + return true; +} + +static const struct flash_parameters *flash_siwx91x_get_parameters(const struct device *dev) +{ + const struct siwx91x_config *cfg = dev->config; + + return &cfg->flash_parameters; +} + +static int flash_siwx91x_read(const struct device *dev, off_t offset, void *buf, size_t len) +{ + const struct siwx91x_config *cfg = dev->config; + struct siwx91x_data *data = dev->data; + void *location = (void *)(cfg->base_address + offset); + + if (!flash_siwx91x_range_is_in_bounds(dev, offset, len)) { + return -EINVAL; + } + k_sem_take(&data->lock, K_FOREVER); + memcpy(buf, location, len); + k_sem_give(&data->lock); + return 0; +} + +static int flash_siwx91x_write(const struct device *dev, off_t offset, const void *buf, size_t len) +{ + const struct siwx91x_config *cfg = dev->config; + struct siwx91x_data *data = dev->data; + uint32_t ret; + + if (!flash_siwx91x_range_is_in_bounds(dev, offset, len)) { + return -EINVAL; + } + if (offset % cfg->write_block_size) { + return -EINVAL; + } + if (len % cfg->write_block_size) { + return -EINVAL; + } + k_sem_take(&data->lock, K_FOREVER); + ret = sl_si91x_command_to_write_common_flash(cfg->base_address + offset, (void *)buf, len, + false); + k_sem_give(&data->lock); + if (ret) { + return -EIO; + } + return 0; +} + +static int flash_siwx91x_erase(const struct device *dev, off_t offset, size_t len) +{ + const struct siwx91x_config *cfg = dev->config; + struct siwx91x_data *data = dev->data; + uint32_t ret; + + if (!flash_siwx91x_range_is_in_bounds(dev, offset, len)) { + return -EINVAL; + } + if (offset % cfg->erase_block_size) { + return -EINVAL; + } + if (len % cfg->erase_block_size) { + return -EINVAL; + } + k_sem_take(&data->lock, K_FOREVER); + ret = sl_si91x_command_to_write_common_flash(cfg->base_address + offset, NULL, len, true); + k_sem_give(&data->lock); + if (ret) { + return -EIO; + } + return 0; +} + +#ifdef CONFIG_FLASH_PAGE_LAYOUT +static void flash_siwx91x_page_layout(const struct device *dev, + const struct flash_pages_layout **layout, size_t *layout_size) +{ + const struct siwx91x_config *cfg = dev->config; + + *layout = &cfg->flash_pages_layout; + *layout_size = 1; +} +#endif + +static DEVICE_API(flash, siwx91x_api) = { + .read = flash_siwx91x_read, + .write = flash_siwx91x_write, + .erase = flash_siwx91x_erase, + .get_parameters = flash_siwx91x_get_parameters, +#ifdef CONFIG_FLASH_PAGE_LAYOUT + .page_layout = flash_siwx91x_page_layout, +#endif +}; + +static int flash_siwx91x_init(const struct device *dev) +{ + struct siwx91x_data *data = dev->data; + + k_sem_init(&data->lock, 1, 1); + return 0; +} + +#ifdef CONFIG_FLASH_PAGE_LAYOUT +#define SIWX91X_PAGE_LAYOUT_FLASH_INIT(n) \ + .flash_pages_layout.pages_count = DT_REG_SIZE(n) / DT_PROP(n, erase_block_size), \ + .flash_pages_layout.pages_size = DT_PROP(n, erase_block_size), +#else +#define SIWX91X_PAGE_LAYOUT_FLASH_INIT(n) +#endif + +#define SIWX91X_FLASH_INIT_P(n, p) \ + static const struct siwx91x_config flash_siwx91x_config_##p = { \ + .base_address = DT_REG_ADDR(n), \ + .size = DT_REG_SIZE(n), \ + .write_block_size = DT_PROP(n, write_block_size), \ + .erase_block_size = DT_PROP(n, erase_block_size), \ + .flash_parameters.write_block_size = DT_PROP(n, write_block_size), \ + .flash_parameters.erase_value = 0xff, \ + SIWX91X_PAGE_LAYOUT_FLASH_INIT(n) \ + }; \ + static struct siwx91x_data flash_siwx91x_data_##p = { \ + .lock = Z_SEM_INITIALIZER(flash_siwx91x_data_##p.lock, 1, 1), \ + }; \ + DEVICE_DT_INST_DEFINE(p, flash_siwx91x_init, NULL, &flash_siwx91x_data_##p, \ + &flash_siwx91x_config_##p, POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, \ + &siwx91x_api); + +#define SIWX91X_FLASH_INIT(p) \ + BUILD_ASSERT(DT_INST_CHILD_NUM_STATUS_OKAY(p) == 1); \ + DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(p, SIWX91X_FLASH_INIT_P, p) + +DT_INST_FOREACH_STATUS_OKAY(SIWX91X_FLASH_INIT) diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index 02a5f6bb5f30c..9a6ea55cb81b2 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -45,27 +45,14 @@ LOG_MODULE_REGISTER(spi_nor, CONFIG_FLASH_LOG_LEVEL); #define SPI_NOR_MAX_ADDR_WIDTH 4 #define SPI_NOR_3B_ADDR_MAX 0xFFFFFF -#define ANY_INST_HAS_TRUE_(idx, bool_prop) \ - COND_CODE_1(DT_INST_PROP(idx, bool_prop), (1,), ()) - -#define ANY_INST_HAS_TRUE(bool_prop) \ - COND_CODE_1(IS_EMPTY(DT_INST_FOREACH_STATUS_OKAY_VARGS(ANY_INST_HAS_TRUE_, bool_prop)), \ - (0), (1)) - -#define ANY_INST_HAS_PROP_(idx, prop_name) \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(idx, prop_name), (1,), ()) -#define ANY_INST_HAS_PROP(prop_name) \ - COND_CODE_1(IS_EMPTY(DT_INST_FOREACH_STATUS_OKAY_VARGS(ANY_INST_HAS_PROP_, prop_name)), \ - (0), (1)) - -#define ANY_INST_HAS_MXICY_MX25R_POWER_MODE ANY_INST_HAS_PROP(mxicy_mx25r_power_mode) -#define ANY_INST_HAS_DPD ANY_INST_HAS_TRUE(has_dpd) -#define ANY_INST_HAS_T_EXIT_DPD ANY_INST_HAS_PROP(t_exit_dpd) -#define ANY_INST_HAS_DPD_WAKEUP_SEQUENCE ANY_INST_HAS_PROP(dpd_wakeup_sequence) -#define ANY_INST_HAS_RESET_GPIOS ANY_INST_HAS_PROP(reset_gpios) -#define ANY_INST_HAS_WP_GPIOS ANY_INST_HAS_PROP(wp_gpios) -#define ANY_INST_HAS_HOLD_GPIOS ANY_INST_HAS_PROP(hold_gpios) -#define ANY_INST_USE_4B_ADDR_OPCODES ANY_INST_HAS_TRUE(use_4b_addr_opcodes) +#define ANY_INST_HAS_MXICY_MX25R_POWER_MODE DT_ANY_INST_HAS_PROP_STATUS_OKAY(mxicy_mx25r_power_mode) +#define ANY_INST_HAS_DPD DT_ANY_INST_HAS_BOOL_STATUS_OKAY(has_dpd) +#define ANY_INST_HAS_T_EXIT_DPD DT_ANY_INST_HAS_PROP_STATUS_OKAY(t_exit_dpd) +#define ANY_INST_HAS_DPD_WAKEUP_SEQUENCE DT_ANY_INST_HAS_PROP_STATUS_OKAY(dpd_wakeup_sequence) +#define ANY_INST_HAS_RESET_GPIOS DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) +#define ANY_INST_HAS_WP_GPIOS DT_ANY_INST_HAS_PROP_STATUS_OKAY(wp_gpios) +#define ANY_INST_HAS_HOLD_GPIOS DT_ANY_INST_HAS_PROP_STATUS_OKAY(hold_gpios) +#define ANY_INST_USE_4B_ADDR_OPCODES DT_ANY_INST_HAS_BOOL_STATUS_OKAY(use_4b_addr_opcodes) #ifdef CONFIG_SPI_NOR_ACTIVE_DWELL_MS #define ACTIVE_DWELL_MS CONFIG_SPI_NOR_ACTIVE_DWELL_MS @@ -234,12 +221,17 @@ static const struct jesd216_erase_type minimal_erase_types_4b[JESD216_NUM_ERASE_ }; #endif /* CONFIG_SPI_NOR_SFDP_MINIMAL */ + /* Register writes should be ready extremely quickly */ #define WAIT_READY_REGISTER K_NO_WAIT /* Page writes range from sub-ms to 10ms */ #define WAIT_READY_WRITE K_TICKS(1) -/* Erases can range from 45ms to 240sec */ -#define WAIT_READY_ERASE K_MSEC(50) + +#ifdef CONFIG_SPI_NOR_SLEEP_WHILE_WAITING_UNTIL_READY +#define WAIT_READY_ERASE K_MSEC(CONFIG_SPI_NOR_SLEEP_ERASE_MS) +#else +#define WAIT_READY_ERASE K_NO_WAIT +#endif static int spi_nor_write_protection_set(const struct device *dev, bool write_protect); @@ -313,12 +305,12 @@ static inline void record_entered_dpd(const struct device *const dev) #endif } +#if ANY_INST_HAS_DPD /* Check the current time against the time DPD was entered and delay * until it's ok to initiate the DPD exit process. */ static inline void delay_until_exit_dpd_ok(const struct device *const dev) { -#if ANY_INST_HAS_DPD const struct spi_nor_config *const driver_config = dev->config; if (driver_config->dpd_exist) { @@ -346,10 +338,8 @@ static inline void delay_until_exit_dpd_ok(const struct device *const dev) } } } -#else - ARG_UNUSED(dev); -#endif /* ANY_INST_HAS_DPD */ } +#endif /* ANY_INST_HAS_DPD */ /* Indicates that an access command includes bytes for the address. * If not provided the opcode is not followed by address bytes. @@ -1149,13 +1139,26 @@ static int spi_nor_set_address_mode(const struct device *dev, /* This currently only supports command 0xB7 (Enter 4-Byte * Address Mode), with or without preceding WREN. + * Or when BIT(3) is set where the 4-byte address mode can be entered + * by setting BIT(7) in a register via a 0x17 write + * instruction. See JEDEC 216F 16th DWORD. */ - if ((enter_4byte_addr & 0x03) == 0) { + if ((enter_4byte_addr & 0x0b) == 0) { return -ENOTSUP; } acquire_device(dev); + if ((enter_4byte_addr & 0x08) != 0) { + /* Enter 4-byte address mode by setting BIT(7) in a register + * via a 0x17 write instruction. + */ + uint8_t sr = BIT(7); + + ret = spi_nor_access(dev, 0x17, NOR_ACCESS_WRITE, 0, &sr, sizeof(sr)); + goto done; + } + if ((enter_4byte_addr & 0x02) != 0) { /* Enter after WREN. */ ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN); @@ -1163,12 +1166,13 @@ static int spi_nor_set_address_mode(const struct device *dev, if (ret == 0) { ret = spi_nor_cmd_write(dev, SPI_NOR_CMD_4BA); + } - if (ret == 0) { - struct spi_nor_data *data = dev->data; +done: + if (ret == 0) { + struct spi_nor_data *data = dev->data; - data->flag_access_32bit = true; - } + data->flag_access_32bit = true; } release_device(dev); diff --git a/drivers/fpga/fpga_shell.c b/drivers/fpga/fpga_shell.c index 4afeba42ef97c..1ba6e728a0d0d 100644 --- a/drivers/fpga/fpga_shell.c +++ b/drivers/fpga/fpga_shell.c @@ -13,7 +13,7 @@ static int parse_common_args(const struct shell *sh, char **argv, const struct device **dev) { - *dev = device_get_binding(argv[1]); + *dev = shell_device_get_binding(argv[1]); if (!*dev) { shell_error(sh, "FPGA device %s not found", argv[1]); return -ENODEV; diff --git a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c index 75b93d3a53129..c8b4f4d411f96 100644 --- a/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c +++ b/drivers/fuel_gauge/fuel_gauge_syscall_handlers.c @@ -26,7 +26,8 @@ static inline int z_vrfy_fuel_gauge_get_prop(const struct device *dev, fuel_gaug #include -static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, fuel_gauge_prop_t *props, +static inline int z_vrfy_fuel_gauge_get_props(const struct device *dev, + const fuel_gauge_prop_t *props, union fuel_gauge_prop_val *vals, size_t len) { union fuel_gauge_prop_val k_vals[len]; @@ -58,8 +59,9 @@ static inline int z_vrfy_fuel_gauge_set_prop(const struct device *dev, fuel_gaug #include -static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, fuel_gauge_prop_t *props, - union fuel_gauge_prop_val *vals, size_t len) +static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, + const fuel_gauge_prop_t *props, + const union fuel_gauge_prop_val *vals, size_t len) { union fuel_gauge_prop_val k_vals[len]; fuel_gauge_prop_t k_props[len]; @@ -71,9 +73,6 @@ static inline int z_vrfy_fuel_gauge_set_props(const struct device *dev, fuel_gau int ret = z_impl_fuel_gauge_set_props(dev, k_props, k_vals, len); - /* We only copy back vals because props will never be modified */ - K_OOPS(k_usermode_to_copy(vals, k_vals, len * sizeof(union fuel_gauge_prop_val))); - return ret; } diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index d7f51c6de3a95..87ddb7ffc4d3f 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -61,10 +61,10 @@ config GNSS_INIT_PRIORITY Driver initialization priority for GNSS drivers. config GNSS_U_BLOX_PROTOCOL - bool "GNSS U-BLOX protocol" + bool select MODEM_UBX help - Enable gnss u-blox protocol. + Hidden option that enables gnss u-blox protocol. choice GNSS_REFERENCE_FRAME bool "GNSS reference frame datum" diff --git a/drivers/gnss/gnss_nmea0183.c b/drivers/gnss/gnss_nmea0183.c index 515606fbefe5b..bbeb50a5c7de6 100644 --- a/drivers/gnss/gnss_nmea0183.c +++ b/drivers/gnss/gnss_nmea0183.c @@ -545,6 +545,16 @@ int gnss_nmea0183_parse_gga(const char **argv, uint16_t argc, struct gnss_data * } data->nav_data.altitude = (int32_t)tmp64; + + /* Parse geoid separation */ + if ((gnss_parse_dec_to_milli(argv[11], &tmp64) < 0) || + (tmp64 > INT32_MAX) || + (tmp64 < INT32_MIN)) { + return -EINVAL; + } + + data->info.geoid_separation = (int32_t)tmp64; + return 0; } diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 428b3df1c28d6..6ed5384f03d52 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -7,7 +7,7 @@ zephyr_library() # zephyr-keep-sorted-start zephyr_library_sources_ifdef(CONFIG_GPIO_AD559X gpio_ad559x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ADP5585 gpio_adp5585.c) -zephyr_library_sources_ifdef(CONFIG_GPIO_ADS114S0X gpio_ads114s0x.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_ADS1X4S0X gpio_ads1x4s0x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AMBIQ gpio_ambiq.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ANDES_ATCGPIO100 gpio_andes_atcgpio100.c) @@ -17,6 +17,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_BCM2711 gpio_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_GPIO_BD8LB600FS gpio_bd8lb600fs.c) zephyr_library_sources_ifdef(CONFIG_GPIO_BRCMSTB gpio_brcmstb.c) zephyr_library_sources_ifdef(CONFIG_GPIO_CC13XX_CC26XX gpio_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_CC23X0 gpio_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_GPIO_CC32XX gpio_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_CMSDK_AHB gpio_cmsdk_ahb.c) zephyr_library_sources_ifdef(CONFIG_GPIO_CY8C95XX gpio_cy8c95xx.c) @@ -44,7 +45,10 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_LMP90XXX gpio_lmp90xxx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_LPC11U6X gpio_lpc11u6x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MAX14906 gpio_max14906.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MAX14916 gpio_max14916.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_MAX22017 gpio_max22017.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_MAX22190 gpio_max22190.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MAX32 gpio_max32.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_MCHP_MEC5 gpio_mchp_mec5.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCHP_MSS gpio_mchp_mss.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCP230XX gpio_mcp230xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCP23SXX gpio_mcp23sxx.c) @@ -53,6 +57,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_MCUX gpio_mcux.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCUX_IGPIO gpio_mcux_igpio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCUX_LPC gpio_mcux_lpc.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCUX_RGPIO gpio_mcux_rgpio.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_MFXSTM32L152 gpio_mfxstm32l152.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MMIO32 gpio_mmio32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NCT38XX gpio_nct38xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NCT38XX gpio_nct38xx_port.c) @@ -66,6 +71,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_NRFX gpio_nrfx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NUMAKER gpio_numaker.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NUMICRO gpio_numicro.c) zephyr_library_sources_ifdef(CONFIG_GPIO_NXP_S32 gpio_nxp_s32.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_PCA6416 gpio_pca6416.c) zephyr_library_sources_ifdef(CONFIG_GPIO_PCA953X gpio_pca953x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_PCA95XX gpio_pca95xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_PCAL64XXA gpio_pcal64xxa.c) @@ -75,9 +81,12 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_PSOC6 gpio_psoc6.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RA_IOPORT gpio_renesas_ra_ioport.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RCAR gpio_rcar.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RENESAS_RA gpio_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_RENESAS_RZ gpio_renesas_rz.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_RP1 gpio_rp1.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RPI_PICO gpio_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RT1718S gpio_rt1718s.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RT1718S gpio_rt1718s_port.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_RTS5912 gpio_rts5912.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RV32M1 gpio_rv32m1.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RZT2M gpio_rzt2m.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SAM gpio_sam.c) @@ -86,6 +95,8 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_SAM4L gpio_sam4l.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SEDI gpio_sedi.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SI32 gpio_si32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SIFIVE gpio_sifive.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_SILABS_SIWX91X gpio_silabs_siwx91x.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_SILABS_SIWX91X_UULP gpio_silabs_siwx91x_uulp.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SMARTBOND gpio_smartbond.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SN74HC595 gpio_sn74hc595.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SNPS_CREG gpio_creg_gpio.c) @@ -93,6 +104,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_STELLARIS gpio_stellaris.c) zephyr_library_sources_ifdef(CONFIG_GPIO_STM32 gpio_stm32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_STMPE1600 gpio_stmpe1600.c) zephyr_library_sources_ifdef(CONFIG_GPIO_SX1509B gpio_sx1509b.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_SY1XX gpio_sy1xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_TCA6424A gpio_tca6424a.c) zephyr_library_sources_ifdef(CONFIG_GPIO_TELINK_B91 gpio_b91.c) zephyr_library_sources_ifdef(CONFIG_GPIO_TEST gpio_test.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 9ec29bd684bf4..1b8e33ad78ebb 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -17,7 +17,6 @@ source "subsys/logging/Kconfig.template.log_config" config GPIO_SHELL bool "GPIO Shell" depends on SHELL - imply DEVICE_DT_METADATA help Enable GPIO Shell for testing. @@ -97,7 +96,7 @@ config GPIO_ENABLE_DISABLE_INTERRUPT # zephyr-keep-sorted-start source "drivers/gpio/Kconfig.ad559x" source "drivers/gpio/Kconfig.adp5585" -source "drivers/gpio/Kconfig.ads114s0x" +source "drivers/gpio/Kconfig.ads1x4s0x" source "drivers/gpio/Kconfig.altera" source "drivers/gpio/Kconfig.ambiq" source "drivers/gpio/Kconfig.andes_atcgpio100" @@ -108,6 +107,7 @@ source "drivers/gpio/Kconfig.bcm2711" source "drivers/gpio/Kconfig.bd8lb600fs" source "drivers/gpio/Kconfig.brcmstb" source "drivers/gpio/Kconfig.cc13xx_cc26xx" +source "drivers/gpio/Kconfig.cc23x0" source "drivers/gpio/Kconfig.cc32xx" source "drivers/gpio/Kconfig.cmsdk_ahb" source "drivers/gpio/Kconfig.creg_gpio" @@ -135,6 +135,8 @@ source "drivers/gpio/Kconfig.lmp90xxx" source "drivers/gpio/Kconfig.lpc11u6x" source "drivers/gpio/Kconfig.max14906" source "drivers/gpio/Kconfig.max14916" +source "drivers/gpio/Kconfig.max22017" +source "drivers/gpio/Kconfig.max22190" source "drivers/gpio/Kconfig.max32" source "drivers/gpio/Kconfig.mchp_mss" source "drivers/gpio/Kconfig.mcp23xxx" @@ -142,6 +144,8 @@ source "drivers/gpio/Kconfig.mcux" source "drivers/gpio/Kconfig.mcux_igpio" source "drivers/gpio/Kconfig.mcux_lpc" source "drivers/gpio/Kconfig.mcux_rgpio" +source "drivers/gpio/Kconfig.mec5" +source "drivers/gpio/Kconfig.mfxstm32l152" source "drivers/gpio/Kconfig.mmio32" source "drivers/gpio/Kconfig.nct38xx" source "drivers/gpio/Kconfig.neorv32" @@ -153,6 +157,7 @@ source "drivers/gpio/Kconfig.nrfx" source "drivers/gpio/Kconfig.numaker" source "drivers/gpio/Kconfig.numicro" source "drivers/gpio/Kconfig.nxp_s32" +source "drivers/gpio/Kconfig.pca6416" source "drivers/gpio/Kconfig.pca953x" source "drivers/gpio/Kconfig.pca95xx" source "drivers/gpio/Kconfig.pca_series" @@ -162,8 +167,11 @@ source "drivers/gpio/Kconfig.psoc6" source "drivers/gpio/Kconfig.rcar" source "drivers/gpio/Kconfig.renesas_ra" source "drivers/gpio/Kconfig.renesas_ra_ioport" +source "drivers/gpio/Kconfig.renesas_rz" +source "drivers/gpio/Kconfig.rp1" source "drivers/gpio/Kconfig.rpi_pico" source "drivers/gpio/Kconfig.rt1718s" +source "drivers/gpio/Kconfig.rts5912" source "drivers/gpio/Kconfig.rv32m1" source "drivers/gpio/Kconfig.rzt2m" source "drivers/gpio/Kconfig.sam" @@ -172,12 +180,14 @@ source "drivers/gpio/Kconfig.sc18im704" source "drivers/gpio/Kconfig.sedi" source "drivers/gpio/Kconfig.si32" source "drivers/gpio/Kconfig.sifive" +source "drivers/gpio/Kconfig.siwx91x" source "drivers/gpio/Kconfig.smartbond" source "drivers/gpio/Kconfig.sn74hc595" source "drivers/gpio/Kconfig.stellaris" source "drivers/gpio/Kconfig.stm32" source "drivers/gpio/Kconfig.stmpe1600" source "drivers/gpio/Kconfig.sx1509b" +source "drivers/gpio/Kconfig.sy1xx" source "drivers/gpio/Kconfig.tca6424a" source "drivers/gpio/Kconfig.test" source "drivers/gpio/Kconfig.tle9104" diff --git a/drivers/gpio/Kconfig.ads114s0x b/drivers/gpio/Kconfig.ads114s0x deleted file mode 100644 index 1dd642c6defa7..0000000000000 --- a/drivers/gpio/Kconfig.ads114s0x +++ /dev/null @@ -1,25 +0,0 @@ -# ADS114S0x GPIO configuration options - -# Copyright (c) 2023 SILA Embedded Solutions GmbH -# SPDX-License-Identifier: Apache-2.0 - -menuconfig GPIO_ADS114S0X - bool "ADS114S0x GPIO driver" - default y - depends on DT_HAS_TI_ADS114S0X_GPIO_ENABLED - depends on ADC_ADS114S0X_GPIO - help - Enable GPIO driver for ADS114S0x. - - The ADS114S0x is a multi-channel analog frontend (AFE). - - The GPIO port of the ADS114S0x (GPIO0 to GPIO3) is exposed as a - GPIO controller driver with read/write support. - -config GPIO_ADS114S0X_INIT_PRIORITY - int "Driver init priority" - default 99 - depends on GPIO_ADS114S0X - help - Device driver initialization priority. This driver must be - initialized after the ADS114S0x ADC driver. diff --git a/drivers/gpio/Kconfig.ads1x4s0x b/drivers/gpio/Kconfig.ads1x4s0x new file mode 100644 index 0000000000000..39fca26923eee --- /dev/null +++ b/drivers/gpio/Kconfig.ads1x4s0x @@ -0,0 +1,25 @@ +# ADS1X4S0X GPIO configuration options + +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +menuconfig GPIO_ADS1X4S0X + bool "ADS1X4S0X GPIO driver" + default y + depends on DT_HAS_TI_ADS1X4S0X_GPIO_ENABLED + depends on ADC_ADS1X4S0X_GPIO + help + Enable GPIO driver for ADS1X4S0X. + + The ADS1X4S0X is a multi-channel analog frontend (AFE). + + The GPIO port of the ADS1X4S0X (GPIO0 to GPIO3) is exposed as a + GPIO controller driver with read/write support. + +config GPIO_ADS1X4S0X_INIT_PRIORITY + int "Driver init priority" + default 99 + depends on GPIO_ADS1X4S0X + help + Device driver initialization priority. This driver must be + initialized after the ADS1X4S0X ADC driver. diff --git a/drivers/gpio/Kconfig.cc23x0 b/drivers/gpio/Kconfig.cc23x0 new file mode 100644 index 0000000000000..147fd029cf2cd --- /dev/null +++ b/drivers/gpio/Kconfig.cc23x0 @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_CC23X0 + bool "TI SimpleLink CC23X0 GPIO driver" + default y + depends on DT_HAS_TI_CC23X0_GPIO_ENABLED + help + Enable the TI SimpleLink CC23x0 GPIO driver. diff --git a/drivers/gpio/Kconfig.davinci b/drivers/gpio/Kconfig.davinci index 2bd94cade4382..b7de108de7141 100644 --- a/drivers/gpio/Kconfig.davinci +++ b/drivers/gpio/Kconfig.davinci @@ -7,5 +7,6 @@ config GPIO_DAVINCI bool "Davinci GPIO Driver" default y depends on DT_HAS_TI_DAVINCI_GPIO_ENABLED + select PINCTRL help Enable the Davinci GPIO controller support. diff --git a/drivers/gpio/Kconfig.max22017 b/drivers/gpio/Kconfig.max22017 new file mode 100644 index 0000000000000..49c07edd92b0b --- /dev/null +++ b/drivers/gpio/Kconfig.max22017 @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_MAX22017 + bool "Analog Devices MAX22017 GPIO support" + default y + depends on DT_HAS_ADI_MAX22017_GPIO_ENABLED + select MFD + help + Enable GPIO support for the Analog Devices MAX22017 + +if GPIO_MAX22017 + +config GPIO_MAX22017_INIT_PRIORITY + int "Init priority" + default 81 + help + Analog Devices MAX22017 gpio device driver initialization priority. + +config GPIO_MAX22017_INT_QUIRK + bool "MAX22017 GPIO Interrupt quirk" + help + The GPIO controller will not report any new GPI interrupt as long as its interrupt status + register hasn't been read. + Reading the interrupt status register happens on a falling edge of the INT pin. + There seems to be a condition when the GPIO controller detects an interrupt but it's INT + pin stays high which masks any subsequent interrupts. + To avoid being stuck in that state, fire a timer to periodically check the interrupt status + register. + +endif # GPIO_MAX22017 diff --git a/drivers/gpio/Kconfig.max22190 b/drivers/gpio/Kconfig.max22190 new file mode 100644 index 0000000000000..c7e6dd4314b14 --- /dev/null +++ b/drivers/gpio/Kconfig.max22190 @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +# MAX22190 GPIO configuration options + +menuconfig GPIO_MAX22190 + bool "MAX22190 GPIO driver" + default y + depends on SPI + depends on DT_HAS_ADI_MAX22190_GPIO_ENABLED + help + Enabe MAX22190 Octal industrial digital + input with diagnostics + +config GPIO_MAX22190_INIT_PRIORITY + int "Driver init priority" + default 99 + depends on GPIO_MAX22190 + help + Device driver initialization priority. diff --git a/drivers/gpio/Kconfig.mec5 b/drivers/gpio/Kconfig.mec5 new file mode 100644 index 0000000000000..b1b426498b92e --- /dev/null +++ b/drivers/gpio/Kconfig.mec5 @@ -0,0 +1,11 @@ +# Microchip MEC5 GPIO configuration options + +# Copyright (c) 2024 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_MCHP_MEC5 + bool "Microchip MEC5 GPIO driver" + default y + depends on DT_HAS_MICROCHIP_MEC5_GPIO_ENABLED + help + Enable the Microchip MEC5 gpio driver. diff --git a/drivers/gpio/Kconfig.mfxstm32l152 b/drivers/gpio/Kconfig.mfxstm32l152 new file mode 100644 index 0000000000000..ac9c649f0ca90 --- /dev/null +++ b/drivers/gpio/Kconfig.mfxstm32l152 @@ -0,0 +1,19 @@ +# MFXSTM32L152 GPIO configuration options + +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +menuconfig GPIO_MFXSTM32L152 + bool "MFXSTM32L152 I2C-based GPIO chip" + default y + depends on DT_HAS_ST_MFXSTM32L152_ENABLED + select I2C + help + Enable driver for MFXSTM32L152 I2C-based GPIO chip. + +config GPIO_MFXSTM32L152_INIT_PRIORITY + int "Init priority" + default 70 + depends on GPIO_MFXSTM32L152 + help + Device driver initialization priority. diff --git a/drivers/gpio/Kconfig.pca6416 b/drivers/gpio/Kconfig.pca6416 new file mode 100644 index 0000000000000..bef9568c55f2d --- /dev/null +++ b/drivers/gpio/Kconfig.pca6416 @@ -0,0 +1,22 @@ +# PCA6416 GPIO configuration options + +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +menuconfig GPIO_PCA6416 + bool "PCA6416 I2C GPIO chip" + default y + depends on DT_HAS_NXP_PCA6416_ENABLED + select I2C + help + Enable driver for PCA6416 I2C GPIO chip. + +if GPIO_PCA6416 + +config GPIO_PCA6416_INIT_PRIORITY + int "Init priority" + default 70 + help + PCA6416 Device driver initialization priority. + +endif # GPIO_PCA6416 diff --git a/drivers/gpio/Kconfig.renesas_ra_ioport b/drivers/gpio/Kconfig.renesas_ra_ioport index c09361cb1cad9..257475b4f60bc 100644 --- a/drivers/gpio/Kconfig.renesas_ra_ioport +++ b/drivers/gpio/Kconfig.renesas_ra_ioport @@ -7,3 +7,8 @@ config GPIO_RA_IOPORT depends on DT_HAS_RENESAS_RA_GPIO_IOPORT_ENABLED help Enable the Renesas RA GPIO IO port driver. + +config GPIO_RA_HAS_VBTICTLR + bool "Support VBATT input control" + help + Enable for Renesas RA which support VBATT input control. diff --git a/drivers/gpio/Kconfig.renesas_rz b/drivers/gpio/Kconfig.renesas_rz new file mode 100644 index 0000000000000..ae2e08c85de62 --- /dev/null +++ b/drivers/gpio/Kconfig.renesas_rz @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_RENESAS_RZ + bool "Renesas RZ series gpio driver" + default y + depends on DT_HAS_RENESAS_RZ_GPIO_ENABLED + select USE_RZ_FSP_IOPORT + help + Enable Renesas RZ series gpio driver. diff --git a/drivers/gpio/Kconfig.rp1 b/drivers/gpio/Kconfig.rp1 new file mode 100644 index 0000000000000..408b41e2c1cf6 --- /dev/null +++ b/drivers/gpio/Kconfig.rp1 @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Junho Lee +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_RP1 + bool "RP1 peripheral controller GPIO Driver" + default y + depends on DT_HAS_RASPBERRYPI_RP1_GPIO_ENABLED + help + Enable Driver for GPIO banks on RP1 peripheral controller. diff --git a/drivers/gpio/Kconfig.rts5912 b/drivers/gpio/Kconfig.rts5912 new file mode 100644 index 0000000000000..d1a1880c9387d --- /dev/null +++ b/drivers/gpio/Kconfig.rts5912 @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config GPIO_RTS5912 + bool "Realtek embedded controller (EC) gpio driver" + depends on SOC_SERIES_RTS5912 + default y if DT_HAS_REALTEK_RTS5912_GPIO_ENABLED + help + Enable support for Realtek GPIO controller. diff --git a/drivers/gpio/Kconfig.siwx91x b/drivers/gpio/Kconfig.siwx91x new file mode 100644 index 0000000000000..1ea818fdbb846 --- /dev/null +++ b/drivers/gpio/Kconfig.siwx91x @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig GPIO_SILABS_SIWX91X + bool "Silabs SiWx91x GPIO driver" + default y + depends on DT_HAS_SILABS_SIWX91X_GPIO_ENABLED + help + Enable the HP/ULP GPIO driver for the Silabs SiWx91x SoC series. + +config GPIO_SILABS_SIWX91X_COMMON_INIT_PRIORITY + int "Common initialization priority" + depends on GPIO_SILABS_SIWX91X + default 39 + +config GPIO_SILABS_SIWX91X_UULP + bool "Silabs SiWx91x UULP GPIO driver" + default y + depends on DT_HAS_SILABS_SIWX91X_GPIO_UULP_ENABLED + help + Enable the UULP GPIO driver for the Silabs SiWx91x SoC series. diff --git a/drivers/gpio/Kconfig.sy1xx b/drivers/gpio/Kconfig.sy1xx new file mode 100644 index 0000000000000..6fa452be85495 --- /dev/null +++ b/drivers/gpio/Kconfig.sy1xx @@ -0,0 +1,9 @@ +# Copyright (c) 2024 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_SY1XX + bool "SY1XX GPIO driver" + default y + depends on DT_HAS_SENSRY_SY1XX_GPIO_ENABLED + help + Enable the SY1XX GPIO driver. diff --git a/drivers/gpio/gpio_ads114s0x.c b/drivers/gpio/gpio_ads114s0x.c deleted file mode 100644 index 5ccbc4b553e54..0000000000000 --- a/drivers/gpio/gpio_ads114s0x.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2023 SILA Embedded Solutions GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief GPIO driver for the ADS114S0x AFE. - */ - -#define DT_DRV_COMPAT ti_ads114s0x_gpio - -#include -#include - -#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL -#include -LOG_MODULE_REGISTER(gpio_ads114s0x); - -#include - -#include - -struct gpio_ads114s0x_config { - /* gpio_driver_config needs to be first */ - struct gpio_driver_config common; - const struct device *parent; -}; - -struct gpio_ads114s0x_data { - /* gpio_driver_data needs to be first */ - struct gpio_driver_data common; -}; - -static int gpio_ads114s0x_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) -{ - const struct gpio_ads114s0x_config *config = dev->config; - int err = 0; - - if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) { - return ads114s0x_gpio_deconfigure(config->parent, pin); - } - - if ((flags & GPIO_SINGLE_ENDED) != 0) { - return -ENOTSUP; - } - - if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) { - return -ENOTSUP; - } - - if (flags & GPIO_INT_ENABLE) { - /* ads114s0x GPIOs do not support interrupts */ - return -ENOTSUP; - } - - switch (flags & GPIO_DIR_MASK) { - case GPIO_INPUT: - err = ads114s0x_gpio_set_input(config->parent, pin); - break; - case GPIO_OUTPUT: - err = ads114s0x_gpio_set_output(config->parent, pin, - (flags & GPIO_OUTPUT_INIT_HIGH) != 0); - break; - default: - return -ENOTSUP; - } - - return err; -} - -static int gpio_ads114s0x_port_get_raw(const struct device *dev, gpio_port_value_t *value) -{ - const struct gpio_ads114s0x_config *config = dev->config; - - return ads114s0x_gpio_port_get_raw(config->parent, value); -} - -static int gpio_ads114s0x_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, - gpio_port_value_t value) -{ - const struct gpio_ads114s0x_config *config = dev->config; - - return ads114s0x_gpio_port_set_masked_raw(config->parent, mask, value); -} - -static int gpio_ads114s0x_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins) -{ - const struct gpio_ads114s0x_config *config = dev->config; - - return ads114s0x_gpio_port_set_masked_raw(config->parent, pins, pins); -} - -static int gpio_ads114s0x_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins) -{ - const struct gpio_ads114s0x_config *config = dev->config; - - return ads114s0x_gpio_port_set_masked_raw(config->parent, pins, 0); -} - -static int gpio_ads114s0x_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) -{ - const struct gpio_ads114s0x_config *config = dev->config; - - return ads114s0x_gpio_port_toggle_bits(config->parent, pins); -} - -static int gpio_ads114s0x_init(const struct device *dev) -{ - const struct gpio_ads114s0x_config *config = dev->config; - - if (!device_is_ready(config->parent)) { - LOG_ERR("parent ads114s0x device '%s' not ready", config->parent->name); - return -EINVAL; - } - - return 0; -} - -static DEVICE_API(gpio, gpio_ads114s0x_api) = { - .pin_configure = gpio_ads114s0x_config, - .port_set_masked_raw = gpio_ads114s0x_port_set_masked_raw, - .port_set_bits_raw = gpio_ads114s0x_port_set_bits_raw, - .port_clear_bits_raw = gpio_ads114s0x_port_clear_bits_raw, - .port_toggle_bits = gpio_ads114s0x_port_toggle_bits, - .port_get_raw = gpio_ads114s0x_port_get_raw, -}; - -BUILD_ASSERT(CONFIG_GPIO_ADS114S0X_INIT_PRIORITY > CONFIG_ADC_INIT_PRIORITY, - "ADS114S0X GPIO driver must be initialized after ADS114S0X ADC driver"); - -#define GPIO_ADS114S0X_DEVICE(id) \ - static const struct gpio_ads114s0x_config gpio_ads114s0x_##id##_cfg = { \ - .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(id)}, \ - .parent = DEVICE_DT_GET(DT_INST_BUS(id)), \ - }; \ - \ - static struct gpio_ads114s0x_data gpio_ads114s0x_##id##_data; \ - \ - DEVICE_DT_INST_DEFINE(id, gpio_ads114s0x_init, NULL, &gpio_ads114s0x_##id##_data, \ - &gpio_ads114s0x_##id##_cfg, POST_KERNEL, \ - CONFIG_GPIO_ADS114S0X_INIT_PRIORITY, &gpio_ads114s0x_api); - -DT_INST_FOREACH_STATUS_OKAY(GPIO_ADS114S0X_DEVICE) diff --git a/drivers/gpio/gpio_ads1x4s0x.c b/drivers/gpio/gpio_ads1x4s0x.c new file mode 100644 index 0000000000000..81ed760adccf5 --- /dev/null +++ b/drivers/gpio/gpio_ads1x4s0x.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2023 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief GPIO driver for the ADS1X4S0X AFE. + */ + +#define DT_DRV_COMPAT ti_ads1x4s0x_gpio + +#include +#include + +#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL +#include +LOG_MODULE_REGISTER(gpio_ads1x4s0x); + +#include + +#include + +struct gpio_ads1x4s0x_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + const struct device *parent; +}; + +struct gpio_ads1x4s0x_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; +}; + +static int gpio_ads1x4s0x_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_ads1x4s0x_config *config = dev->config; + int err = 0; + + if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) { + return ads1x4s0x_gpio_deconfigure(config->parent, pin); + } + + if ((flags & GPIO_SINGLE_ENDED) != 0) { + return -ENOTSUP; + } + + if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) { + return -ENOTSUP; + } + + if (flags & GPIO_INT_ENABLE) { + /* ads1x4s0x GPIOs do not support interrupts */ + return -ENOTSUP; + } + + switch (flags & GPIO_DIR_MASK) { + case GPIO_INPUT: + err = ads1x4s0x_gpio_set_input(config->parent, pin); + break; + case GPIO_OUTPUT: + err = ads1x4s0x_gpio_set_output(config->parent, pin, + (flags & GPIO_OUTPUT_INIT_HIGH) != 0); + break; + default: + return -ENOTSUP; + } + + return err; +} + +static int gpio_ads1x4s0x_port_get_raw(const struct device *dev, gpio_port_value_t *value) +{ + const struct gpio_ads1x4s0x_config *config = dev->config; + + return ads1x4s0x_gpio_port_get_raw(config->parent, value); +} + +static int gpio_ads1x4s0x_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct gpio_ads1x4s0x_config *config = dev->config; + + return ads1x4s0x_gpio_port_set_masked_raw(config->parent, mask, value); +} + +static int gpio_ads1x4s0x_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_ads1x4s0x_config *config = dev->config; + + return ads1x4s0x_gpio_port_set_masked_raw(config->parent, pins, pins); +} + +static int gpio_ads1x4s0x_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_ads1x4s0x_config *config = dev->config; + + return ads1x4s0x_gpio_port_set_masked_raw(config->parent, pins, 0); +} + +static int gpio_ads1x4s0x_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_ads1x4s0x_config *config = dev->config; + + return ads1x4s0x_gpio_port_toggle_bits(config->parent, pins); +} + +static int gpio_ads1x4s0x_init(const struct device *dev) +{ + const struct gpio_ads1x4s0x_config *config = dev->config; + + if (!device_is_ready(config->parent)) { + LOG_ERR("parent ads1x4s0x device '%s' not ready", config->parent->name); + return -EINVAL; + } + + return 0; +} + +static DEVICE_API(gpio, gpio_ads1x4s0x_api) = { + .pin_configure = gpio_ads1x4s0x_config, + .port_set_masked_raw = gpio_ads1x4s0x_port_set_masked_raw, + .port_set_bits_raw = gpio_ads1x4s0x_port_set_bits_raw, + .port_clear_bits_raw = gpio_ads1x4s0x_port_clear_bits_raw, + .port_toggle_bits = gpio_ads1x4s0x_port_toggle_bits, + .port_get_raw = gpio_ads1x4s0x_port_get_raw, +}; + +BUILD_ASSERT(CONFIG_GPIO_ADS1X4S0X_INIT_PRIORITY > CONFIG_ADC_INIT_PRIORITY, + "ADS1X4S0X GPIO driver must be initialized after ADS1X4S0X ADC driver"); + +#define GPIO_ADS1X4S0X_DEVICE(id) \ + static const struct gpio_ads1x4s0x_config gpio_ads1x4s0x_##id##_cfg = { \ + .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(id)}, \ + .parent = DEVICE_DT_GET(DT_INST_BUS(id)), \ + }; \ + \ + static struct gpio_ads1x4s0x_data gpio_ads1x4s0x_##id##_data; \ + \ + DEVICE_DT_INST_DEFINE(id, gpio_ads1x4s0x_init, NULL, &gpio_ads1x4s0x_##id##_data, \ + &gpio_ads1x4s0x_##id##_cfg, POST_KERNEL, \ + CONFIG_GPIO_ADS1X4S0X_INIT_PRIORITY, &gpio_ads1x4s0x_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_ADS1X4S0X_DEVICE) diff --git a/drivers/gpio/gpio_cc23x0.c b/drivers/gpio/gpio_cc23x0.c new file mode 100644 index 0000000000000..b39c7b3ec9db7 --- /dev/null +++ b/drivers/gpio/gpio_cc23x0.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_gpio + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define IOC_ADDR(index) (IOC_BASE + IOC_O_IOC0 + (sizeof(uint32_t) * (index))) + +struct gpio_cc23x0_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; +}; + +struct gpio_cc23x0_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + sys_slist_t callbacks; +}; + +static void set_pin_mask_non_atomic(uint8_t index, uint32_t registerBaseAddress) +{ + GPIOSetConfigDio(GPIO_BASE + registerBaseAddress, BIT(index)); +} + +static int gpio_cc23x0_config(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) +{ + uint32_t config = 0; + uint32_t iocfg_reg = IOC_ADDR(pin); + gpio_flags_t direction = flags & GPIO_DIR_MASK; + + if (flags & GPIO_PULL_UP) { + config |= IOC_IOC0_PULLCTL_PULL_UP; + } else if (flags & GPIO_PULL_DOWN) { + config |= IOC_IOC0_PULLCTL_PULL_DOWN; + } else { + config |= IOC_IOC0_PULLCTL_PULL_DIS; + } + + if (!(flags & GPIO_SINGLE_ENDED)) { + config |= IOC_IOC0_IOMODE_NORMAL; + } else { + if (flags & GPIO_LINE_OPEN_DRAIN) { + config |= IOC_IOC0_IOMODE_OPEND; + } else { + config |= IOC_IOC0_IOMODE_OPENS; + } + } + if (direction & GPIO_INPUT) { + config |= IOC_IOC0_INPEN_EN | IOC_IOC0_HYSTEN_EN; + } + + GPIOSetConfigDio(iocfg_reg, config); + + if (flags & GPIO_OUTPUT) { + if (flags & GPIO_OUTPUT_INIT_HIGH) { + GPIOSetDio(pin); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + GPIOClearDio(pin); + } + GPIOSetOutputEnableDio(pin, GPIO_OUTPUT_ENABLE); + } else { + GPIOSetOutputEnableDio(pin, GPIO_OUTPUT_DISABLE); + } + return 0; +} + +#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_cc23x0_get_config(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags) +{ + uint32_t out_flag = 0; + uint32_t iocfg_reg = IOC_ADDR(pin); + uint32_t config = GPIOGetConfigDio(iocfg_reg); + + /* GPIO input/output configuration flags */ + if (config & IOC_IOC0_INPEN_EN) { + out_flag |= GPIO_INPUT; + } + + if (GPIOGetOutputEnableDio(pin)) { + out_flag |= GPIO_OUTPUT; + + if (GPIOReadDio(pin)) { + out_flag |= GPIO_OUTPUT_INIT_HIGH; + } else { + /* This is the default value. If not explicitly set, + * the returned config will not be symmetric + */ + out_flag |= GPIO_OUTPUT_INIT_LOW; + } + } + + /* GPIO interrupt configuration flags */ + if ((config & IOC_IOC0_EDGEDET_M) != IOC_IOC0_EDGEDET_EDGE_DIS) { + if (config & IOC_IOC0_EDGEDET_EDGE_POS) { + out_flag |= GPIO_INT_EDGE_RISING; + } + + if (config & IOC_IOC0_EDGEDET_EDGE_NEG) { + out_flag |= GPIO_INT_EDGE_FALLING; + } + } else { + /* This is the default value. If not explicitly set, + * the returned config will not be symmetric + */ + out_flag |= GPIO_INT_DISABLE; + } + + /* GPIO pin drive flags */ + if (config & IOC_IOC0_IOMODE_OPENS) { + out_flag |= GPIO_OPEN_SOURCE; + } + + if (config & IOC_IOC0_IOMODE_OPEND) { + out_flag |= IOC_IOC0_IOMODE_OPEND; + } + + if (config & IOC_IOC0_PULLCTL_PULL_UP) { + out_flag |= GPIO_PULL_UP; + } + + if (config & IOC_IOC0_PULLCTL_PULL_DOWN) { + out_flag |= GPIO_PULL_DOWN; + } + + *flags = out_flag; + + return 0; +} +#endif + +static int gpio_cc23x0_port_get_raw(const struct device *port, uint32_t *value) +{ + *value = GPIOReadMultiDio(GPIO_DIO_ALL_MASK); + + return 0; +} + +static int gpio_cc23x0_port_set_masked_raw(const struct device *port, uint32_t mask, uint32_t value) +{ + GPIOWriteMultiDio(mask, value); + + return 0; +} + +static int gpio_cc23x0_port_set_bits_raw(const struct device *port, uint32_t mask) +{ + GPIOSetMultiDio(mask); + + return 0; +} + +static int gpio_cc23x0_port_clear_bits_raw(const struct device *port, uint32_t mask) +{ + GPIOClearMultiDio(mask); + + return 0; +} + +static int gpio_cc23x0_port_toggle_bits(const struct device *port, uint32_t mask) +{ + GPIOToggleMultiDio(mask); + + return 0; +} + +static int gpio_cc23x0xx_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + if (mode == GPIO_INT_MODE_LEVEL) { + return ENOTSUP; + } + + uint32_t config = GPIOGetConfigDio(IOC_ADDR(pin)) & ~IOC_IOC0_EDGEDET_M; + + if (mode == GPIO_INT_MODE_DISABLED) { + config |= IOC_IOC1_EDGEDET_EDGE_DIS; + + GPIOSetConfigDio(IOC_ADDR(pin), config); + + /* Disable interrupt mask */ + set_pin_mask_non_atomic(pin, GPIO_O_IMCLR); + + } else if (mode == GPIO_INT_MODE_EDGE) { + switch (trig) { + case GPIO_INT_TRIG_LOW: + config |= IOC_IOC1_EDGEDET_EDGE_NEG; + break; + case GPIO_INT_TRIG_HIGH: + config |= IOC_IOC1_EDGEDET_EDGE_POS; + break; + case GPIO_INT_TRIG_BOTH: + config |= IOC_IOC1_EDGEDET_EDGE_BOTH; + break; + default: + return ENOTSUP; + } + + GPIOSetConfigDio(IOC_ADDR(pin), config); + + /* Enable interrupt mask */ + set_pin_mask_non_atomic(pin, GPIO_O_ICLR); + set_pin_mask_non_atomic(pin, GPIO_O_IMSET); + } + + return 0; +} + +static int gpio_cc23x0_manage_callback(const struct device *port, struct gpio_callback *callback, + bool set) +{ + struct gpio_cc23x0_data *data = port->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static uint32_t gpio_cc23x0_get_pending_int(const struct device *dev) +{ + return GPIOGetEventMultiDio(GPIO_DIO_ALL_MASK); +} + +static void gpio_cc23x0_isr(const struct device *dev) +{ + struct gpio_cc23x0_data *data = dev->data; + + uint32_t status = GPIOGetEventMultiDio(GPIO_DIO_ALL_MASK); + + GPIOClearEventMultiDio(status); + + gpio_fire_callbacks(&data->callbacks, dev, status); +} + +static int gpio_cc23x0_init(const struct device *dev) +{ + /* Enable GPIO domain clock */ + CLKCTLEnable(CLKCTL_BASE, CLKCTL_GPIO); + + /* Enable IRQ */ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), gpio_cc23x0_isr, + DEVICE_DT_INST_GET(0), 0); + + irq_enable(DT_INST_IRQN(0)); + + return 0; +} + +static DEVICE_API(gpio, gpio_cc23x0_driver_api) = { + .pin_configure = gpio_cc23x0_config, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_cc23x0_get_config, +#endif + .port_get_raw = gpio_cc23x0_port_get_raw, + .port_set_masked_raw = gpio_cc23x0_port_set_masked_raw, + .port_set_bits_raw = gpio_cc23x0_port_set_bits_raw, + .port_clear_bits_raw = gpio_cc23x0_port_clear_bits_raw, + .port_toggle_bits = gpio_cc23x0_port_toggle_bits, + .pin_interrupt_configure = gpio_cc23x0xx_pin_interrupt_configure, + .manage_callback = gpio_cc23x0_manage_callback, + .get_pending_int = gpio_cc23x0_get_pending_int, +}; + +static const struct gpio_cc23x0_config gpio_cc23x0_config_0 = { + .common = {/* Read ngpios from DT */ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0)}}; + +static struct gpio_cc23x0_data gpio_cc23x0_data_0; + +DEVICE_DT_INST_DEFINE(0, gpio_cc23x0_init, NULL, &gpio_cc23x0_data_0, &gpio_cc23x0_config_0, + PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_cc23x0_driver_api); diff --git a/drivers/gpio/gpio_ene_kb1200.c b/drivers/gpio/gpio_ene_kb1200.c index fb72fd564b099..cc6074374195f 100644 --- a/drivers/gpio/gpio_ene_kb1200.c +++ b/drivers/gpio/gpio_ene_kb1200.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -42,35 +43,51 @@ static int kb1200_gpio_pin_configure(const struct device *dev, gpio_pin_t pin, g const struct gpio_kb1200_config *config = dev->config; WRITE_BIT(config->gpio_regs->GPIOFS, pin, 0); - if ((flags & GPIO_OUTPUT) != 0) { - WRITE_BIT(config->gpio_regs->GPIOIE, pin, 1); - if ((flags & GPIO_SINGLE_ENDED) != 0) { + /* ene specific flags. low voltage mode,input voltage threshold (ViH & ViL) support 1.8V */ + if (flags & KB1200_GPIO_VOLTAGE_POS) { + WRITE_BIT(config->gpio_regs->GPIOLV, pin, 1); + } else { + WRITE_BIT(config->gpio_regs->GPIOLV, pin, 0); + } + /* ene specific flags. max current driving ability, max support 16 mA */ + if (flags & KB1200_GPIO_DRIVING_16MA) { + WRITE_BIT(config->gpio_regs->GPIODC, pin, 1); + } else { + WRITE_BIT(config->gpio_regs->GPIODC, pin, 0); + } + /* pull-up function */ + if (flags & GPIO_PULL_UP) { + WRITE_BIT(config->gpio_regs->GPIOPU, pin, 1); + } else { + WRITE_BIT(config->gpio_regs->GPIOPU, pin, 0); + } + /* output data high/low */ + if (flags & GPIO_OUTPUT_INIT_HIGH) { + WRITE_BIT(config->gpio_regs->GPIOD, pin, 1); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + WRITE_BIT(config->gpio_regs->GPIOD, pin, 0); + } + /* output enable function */ + if (flags & GPIO_OUTPUT) { + /* setting open-drain only when output is enabled */ + /* output type push-pull/open-drain */ + if (flags & GPIO_SINGLE_ENDED) { if (flags & GPIO_LINE_OPEN_DRAIN) { WRITE_BIT(config->gpio_regs->GPIOOD, pin, 1); + } else { + WRITE_BIT(config->gpio_regs->GPIOOD, pin, 0); } } else { WRITE_BIT(config->gpio_regs->GPIOOD, pin, 0); } - if (flags & GPIO_PULL_UP) { - WRITE_BIT(config->gpio_regs->GPIOPU, pin, 1); - } else { - WRITE_BIT(config->gpio_regs->GPIOPU, pin, 0); - } - if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { - WRITE_BIT(config->gpio_regs->GPIOD, pin, 1); - } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { - WRITE_BIT(config->gpio_regs->GPIOD, pin, 0); - } WRITE_BIT(config->gpio_regs->GPIOOE, pin, 1); } else { WRITE_BIT(config->gpio_regs->GPIOOE, pin, 0); - if (flags & GPIO_PULL_UP) { - WRITE_BIT(config->gpio_regs->GPIOPU, pin, 1); - } else { - WRITE_BIT(config->gpio_regs->GPIOPU, pin, 0); - } - WRITE_BIT(config->gpio_regs->GPIOIE, pin, 1); + /* disable open-drain when output is disabled */ + WRITE_BIT(config->gpio_regs->GPIOOD, pin, 0); } + /* input function always enable */ + WRITE_BIT(config->gpio_regs->GPIOIE, pin, 1); return 0; } @@ -203,8 +220,8 @@ static DEVICE_API(gpio, kb1200_gpio_api) = { .gptd_regs = (struct gptd_regs *)DT_INST_REG_ADDR_BY_IDX(n, 1), \ }; \ static struct gpio_kb1200_data gpio_kb1200_##n##_data; \ - DEVICE_DT_INST_DEFINE(n, &kb1200_gpio_##n##_init, NULL, &gpio_kb1200_##n##_data, \ - &port_##n##_kb1200_config, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &kb1200_gpio_api); + DEVICE_DT_INST_DEFINE(n, kb1200_gpio_##n##_init, NULL, &gpio_kb1200_##n##_data, \ + &port_##n##_kb1200_config, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &kb1200_gpio_api); DT_INST_FOREACH_STATUS_OKAY(KB1200_GPIO_INIT) diff --git a/drivers/gpio/gpio_gecko.c b/drivers/gpio/gpio_gecko.c index dd016d25712a3..942e56b409698 100644 --- a/drivers/gpio/gpio_gecko.c +++ b/drivers/gpio/gpio_gecko.c @@ -26,10 +26,7 @@ #if DT_NODE_HAS_PROP(id, peripheral_id) #define GET_GECKO_GPIO_INDEX(id) DT_INST_PROP(id, peripheral_id) #else -#if defined(CONFIG_SOC_SERIES_EFR32BG22) || \ - defined(CONFIG_SOC_SERIES_EFR32BG27) || \ - defined(CONFIG_SOC_SERIES_EFR32MG21) || \ - defined(CONFIG_SOC_SERIES_EFR32MG24) +#if defined(CONFIG_SOC_FAMILY_SILABS_S2) #define GECKO_GPIO_PORT_ADDR_SPACE_SIZE sizeof(GPIO_PORT_TypeDef) #else #define GECKO_GPIO_PORT_ADDR_SPACE_SIZE sizeof(GPIO_P_TypeDef) diff --git a/drivers/gpio/gpio_ite_it8801.c b/drivers/gpio/gpio_ite_it8801.c index 98e74deee0b51..ca2423f76f254 100644 --- a/drivers/gpio/gpio_ite_it8801.c +++ b/drivers/gpio/gpio_ite_it8801.c @@ -415,7 +415,7 @@ static int gpio_it8801_pin_interrupt_configure(const struct device *dev, gpio_pi return ret; } -static const struct gpio_driver_api gpio_it8801_driver_api = { +static DEVICE_API(gpio, gpio_it8801_driver_api) = { .pin_configure = gpio_it8801_configure, #ifdef CONFIG_GPIO_GET_CONFIG .pin_get_config = gpio_it8801_get_config, diff --git a/drivers/gpio/gpio_ite_it8xxx2_v2.c b/drivers/gpio/gpio_ite_it8xxx2_v2.c index e19345ca9976f..3a1b04c48734d 100644 --- a/drivers/gpio/gpio_ite_it8xxx2_v2.c +++ b/drivers/gpio/gpio_ite_it8xxx2_v2.c @@ -27,6 +27,8 @@ LOG_MODULE_REGISTER(gpio_it8xxx2, LOG_LEVEL_ERR); +#define ITE_GPIO_MAX_PINS 8 + /* * Structure gpio_ite_cfg is about the setting of GPIO * this config will be used at initial time @@ -529,33 +531,27 @@ static int gpio_ite_init(const struct device *dev) return 0; } -#define GPIO_ITE_DEV_CFG_DATA(inst) \ -static struct gpio_ite_data gpio_ite_data_##inst; \ -static const struct gpio_ite_cfg gpio_ite_cfg_##inst = { \ - .common = { \ - .port_pin_mask = \ - GPIO_PORT_PIN_MASK_FROM_DT_INST(inst) \ - }, \ - .reg_gpdr = DT_INST_REG_ADDR_BY_IDX(inst, 0), \ - .reg_gpdmr = DT_INST_REG_ADDR_BY_IDX(inst, 1), \ - .reg_gpotr = DT_INST_REG_ADDR_BY_IDX(inst, 2), \ - .reg_p18scr = DT_INST_REG_ADDR_BY_IDX(inst, 3), \ - .reg_gpcr = DT_INST_REG_ADDR_BY_IDX(inst, 4), \ - .wuc_base = DT_INST_PROP_OR(inst, wuc_base, {0}), \ - .wuc_mask = DT_INST_PROP_OR(inst, wuc_mask, {0}), \ - .gpio_irq = IT8XXX2_DT_GPIO_IRQ_LIST(inst), \ - .has_volt_sel = DT_INST_PROP_OR(inst, has_volt_sel, {0}), \ - .num_pins = DT_INST_PROP(inst, ngpios), \ - .kbs_ctrl = DT_INST_PROP_OR(inst, keyboard_controller, 0), \ - }; \ -DEVICE_DT_INST_DEFINE(inst, \ - gpio_ite_init, \ - NULL, \ - &gpio_ite_data_##inst, \ - &gpio_ite_cfg_##inst, \ - PRE_KERNEL_1, \ - CONFIG_GPIO_INIT_PRIORITY, \ - &gpio_ite_driver_api); +#define GPIO_ITE_DEV_CFG_DATA(inst) \ + BUILD_ASSERT(DT_INST_PROP(inst, ngpios) <= ITE_GPIO_MAX_PINS, \ + "The maximum number of pins per port is 8."); \ + static struct gpio_ite_data gpio_ite_data_##inst; \ + static const struct gpio_ite_cfg gpio_ite_cfg_##inst = { \ + .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst)}, \ + .reg_gpdr = DT_INST_REG_ADDR_BY_IDX(inst, 0), \ + .reg_gpdmr = DT_INST_REG_ADDR_BY_IDX(inst, 1), \ + .reg_gpotr = DT_INST_REG_ADDR_BY_IDX(inst, 2), \ + .reg_p18scr = DT_INST_REG_ADDR_BY_IDX(inst, 3), \ + .reg_gpcr = DT_INST_REG_ADDR_BY_IDX(inst, 4), \ + .wuc_base = DT_INST_PROP_OR(inst, wuc_base, {0}), \ + .wuc_mask = DT_INST_PROP_OR(inst, wuc_mask, {0}), \ + .gpio_irq = IT8XXX2_DT_GPIO_IRQ_LIST(inst), \ + .has_volt_sel = DT_INST_PROP_OR(inst, has_volt_sel, {0}), \ + .num_pins = DT_INST_PROP(inst, ngpios), \ + .kbs_ctrl = DT_INST_PROP_OR(inst, keyboard_controller, 0), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, gpio_ite_init, NULL, &gpio_ite_data_##inst, \ + &gpio_ite_cfg_##inst, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_ite_driver_api); DT_INST_FOREACH_STATUS_OKAY(GPIO_ITE_DEV_CFG_DATA) diff --git a/drivers/gpio/gpio_max149x6.h b/drivers/gpio/gpio_max149x6.h index 3266a219c65fb..6e2c0c51db539 100644 --- a/drivers/gpio/gpio_max149x6.h +++ b/drivers/gpio/gpio_max149x6.h @@ -107,10 +107,6 @@ static int max149x6_reg_transceive(const struct device *dev, uint8_t addr, uint8 }; const struct spi_buf_set rx = {.buffers = &rx_buf, .count = 1}; - if (config->crc_en & 0) { - rx_buf.len++; - } - local_tx_buff[0] = FIELD_PREP(MAX149x6_ADDR_MASK, addr) | FIELD_PREP(MAX149x6_CHIP_ADDR_MASK, config->spi_addr) | FIELD_PREP(MAX149x6_RW_MASK, rw & 0x1); diff --git a/drivers/gpio/gpio_max22017.c b/drivers/gpio/gpio_max22017.c new file mode 100644 index 0000000000000..29b2f08516b29 --- /dev/null +++ b/drivers/gpio/gpio_max22017.c @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define DT_DRV_COMPAT adi_max22017_gpio + +#include +LOG_MODULE_REGISTER(gpio_max22017, CONFIG_GPIO_LOG_LEVEL); + +#include + +#include + +struct gpio_adi_max22017_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + const struct device *parent; +}; + +struct gpio_adi_max22017_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; +#ifdef CONFIG_GPIO_MAX22017_INT_QUIRK + struct k_timer int_quirk_timer; +#endif +}; + +#ifdef CONFIG_GPIO_MAX22017_INT_QUIRK +void isr_quirk_handler(struct k_timer *int_quirk_timer) +{ + int ret; + struct max22017_data *data = k_timer_user_data_get(int_quirk_timer); + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = k_work_submit(&data->int_work); + if (ret < 0) { + LOG_WRN("Could not submit int work: %d", ret); + } + + k_mutex_unlock(&data->lock); +} +#endif + +static int adi_max22017_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value) +{ + int ret; + uint16_t gpio_data, gpio_ctrl; + struct max22017_data *data = dev->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(dev, MAX22017_GEN_GPIO_DATA_OFF, &gpio_data); + if (ret) { + goto fail; + } + + ret = max22017_reg_read(dev, MAX22017_GEN_GPIO_CTRL_OFF, &gpio_ctrl); + if (ret) { + goto fail; + } + + if (initial_value) { + gpio_data |= FIELD_PREP(MAX22017_GEN_GPIO_DATA_GPO_DATA, BIT(pin)); + } else { + gpio_data &= ~FIELD_PREP(MAX22017_GEN_GPIO_DATA_GPO_DATA, BIT(pin)); + } + + gpio_ctrl |= FIELD_PREP(MAX22017_GEN_GPIO_CTRL_GPIO_EN, BIT(pin)) | + FIELD_PREP(MAX22017_GEN_GPIO_CTRL_GPIO_DIR, BIT(pin)); + + ret = max22017_reg_write(dev, MAX22017_GEN_GPIO_DATA_OFF, gpio_data); + if (ret) { + goto fail; + } + + ret = max22017_reg_write(dev, MAX22017_GEN_GPIO_CTRL_OFF, gpio_ctrl); + +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static int adi_max22017_gpio_set_input(const struct device *dev, uint8_t pin) +{ + int ret; + uint16_t gpio_ctrl; + struct max22017_data *data = dev->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(dev, MAX22017_GEN_GPIO_CTRL_OFF, &gpio_ctrl); + if (ret) { + goto fail; + } + + gpio_ctrl |= FIELD_PREP(MAX22017_GEN_GPIO_CTRL_GPIO_EN, BIT(pin)); + gpio_ctrl &= ~FIELD_PREP(MAX22017_GEN_GPIO_CTRL_GPIO_DIR, BIT(pin)); + + ret = max22017_reg_write(dev, MAX22017_GEN_GPIO_CTRL_OFF, gpio_ctrl); +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +int adi_max22017_gpio_deconfigure(const struct device *dev, uint8_t pin) +{ + int ret; + uint16_t gpio_ctrl; + struct max22017_data *data = dev->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(dev, MAX22017_GEN_GPIO_CTRL_OFF, &gpio_ctrl); + if (ret) { + goto fail; + } + + gpio_ctrl &= ~FIELD_PREP(MAX22017_GEN_GPIO_CTRL_GPIO_EN, BIT(pin)); + + ret = max22017_reg_write(dev, MAX22017_GEN_GPIO_CTRL_OFF, gpio_ctrl); +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +int adi_max22017_gpio_set_pin_value(const struct device *dev, uint8_t pin, bool value) +{ + int ret; + uint16_t gpio_data; + struct max22017_data *data = dev->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(dev, MAX22017_GEN_GPIO_DATA_OFF, &gpio_data); + if (ret) { + goto fail; + } + + if (value) { + gpio_data |= FIELD_PREP(MAX22017_GEN_GPIO_DATA_GPO_DATA, BIT(pin)); + } else { + gpio_data &= ~FIELD_PREP(MAX22017_GEN_GPIO_DATA_GPO_DATA, BIT(pin)); + } + + ret = max22017_reg_write(dev, MAX22017_GEN_GPIO_DATA_OFF, gpio_data); +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +int adi_max22017_gpio_get_pin_value(const struct device *dev, uint8_t pin, bool *value) +{ + int ret; + uint16_t gpio_data; + struct max22017_data *data = dev->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(dev, MAX22017_GEN_GPIO_DATA_OFF, &gpio_data); + if (ret) { + goto fail; + } + + *value = FIELD_GET(MAX22017_GEN_GPIO_DATA_GPI_DATA, gpio_data) & BIT(pin); + +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static int adi_max22017_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + int ret; + uint16_t gpio_data, tmp_val; + struct max22017_data *data = dev->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(dev, MAX22017_GEN_GPIO_DATA_OFF, &gpio_data); + if (ret) { + goto fail; + } + + tmp_val = FIELD_GET(MAX22017_GEN_GPIO_DATA_GPO_DATA, gpio_data); + tmp_val = (tmp_val & ~mask) | (value & mask); + gpio_data = FIELD_PREP(MAX22017_GEN_GPIO_DATA_GPO_DATA, tmp_val) | + FIELD_PREP(MAX22017_GEN_GPIO_DATA_GPI_DATA, + FIELD_GET(MAX22017_GEN_GPIO_DATA_GPI_DATA, gpio_data)); + + ret = max22017_reg_write(dev, MAX22017_GEN_GPIO_DATA_OFF, gpio_data); +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static int gpio_adi_max22017_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_adi_max22017_config *config = dev->config; + int err = -EINVAL; + + if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) { + return adi_max22017_gpio_deconfigure(config->parent, pin); + } + + if ((flags & GPIO_SINGLE_ENDED) != 0) { + return -ENOTSUP; + } + + if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) { + return -ENOTSUP; + } + + switch (flags & GPIO_DIR_MASK) { + case GPIO_INPUT: + err = adi_max22017_gpio_set_input(config->parent, pin); + break; + case GPIO_OUTPUT: + err = adi_max22017_gpio_set_output(config->parent, pin, + (flags & GPIO_OUTPUT_INIT_HIGH) != 0); + break; + default: + return -ENOTSUP; + } + return err; +} + +static int gpio_adi_max22017_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + int ret; + uint16_t gpio_int, gen_int_en; + const struct gpio_adi_max22017_config *config = dev->config; + const struct device *parent = config->parent; + struct max22017_data *data = parent->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + if (mode == GPIO_INT_MODE_DISABLED) { + ret = -ENOTSUP; + goto fail; + } + + ret = max22017_reg_read(parent, MAX22017_GEN_GPI_INT_OFF, &gpio_int); + if (ret) { + goto fail; + } + + if (mode & GPIO_INT_EDGE_RISING) { + gpio_int |= FIELD_PREP(MAX22017_GEN_GPI_INT_GPI_POS_EDGE_INT, BIT(pin)); + } + if (mode & GPIO_INT_EDGE_FALLING) { + gpio_int |= FIELD_PREP(MAX22017_GEN_GPI_INT_GPI_NEG_EDGE_INT, BIT(pin)); + } + + ret = max22017_reg_write(parent, MAX22017_GEN_GPI_INT_OFF, gpio_int); + if (ret) { + goto fail; + } + + ret = max22017_reg_read(parent, MAX22017_GEN_INTEN_OFF, &gen_int_en); + if (ret) { + goto fail; + } + + ret = max22017_reg_write(parent, MAX22017_GEN_INTEN_OFF, + gen_int_en | FIELD_PREP(MAX22017_GEN_INTEN_GPI_INTEN, 1)); +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static int gpio_adi_max22017_port_get_raw(const struct device *dev, gpio_port_value_t *value) +{ + int ret; + const struct gpio_adi_max22017_config *config = dev->config; + const struct device *parent = config->parent; + struct max22017_data *data = parent->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(parent, MAX22017_GEN_GPIO_DATA_OFF, (uint16_t *)value); + if (ret) { + goto fail; + } + + *value = FIELD_GET(MAX22017_GEN_GPIO_DATA_GPI_DATA, *value); + +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static int gpio_adi_max22017_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct gpio_adi_max22017_config *config = dev->config; + + return adi_max22017_gpio_port_set_masked_raw(config->parent, mask, value); +} + +static int gpio_adi_max22017_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_adi_max22017_config *config = dev->config; + + return adi_max22017_gpio_port_set_masked_raw(config->parent, pins, pins); +} + +static int gpio_adi_max22017_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_adi_max22017_config *config = dev->config; + + return adi_max22017_gpio_port_set_masked_raw(config->parent, pins, 0); +} + +static int gpio_adi_max22017_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) +{ + int ret; + uint16_t gpio_data, tmp_val; + const struct gpio_adi_max22017_config *config = dev->config; + const struct device *parent = config->parent; + struct max22017_data *data = parent->data; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(parent, MAX22017_GEN_GPIO_DATA_OFF, &gpio_data); + if (ret) { + goto fail; + } + + tmp_val = FIELD_GET(MAX22017_GEN_GPIO_DATA_GPO_DATA, gpio_data); + tmp_val = (tmp_val ^ pins); + gpio_data = FIELD_PREP(MAX22017_GEN_GPIO_DATA_GPO_DATA, tmp_val) | + FIELD_PREP(MAX22017_GEN_GPIO_DATA_GPI_DATA, + FIELD_GET(MAX22017_GEN_GPIO_DATA_GPI_DATA, gpio_data)); + + ret = max22017_reg_write(parent, MAX22017_GEN_GPIO_DATA_OFF, gpio_data); +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +static int gpio_adi_max22017_manage_cb(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + int ret; + const struct gpio_adi_max22017_config *config = dev->config; + struct max22017_data *data = config->parent->data; + + k_mutex_lock(&data->lock, K_FOREVER); + ret = gpio_manage_callback(&data->callbacks_gpi, callback, set); + k_mutex_unlock(&data->lock); + + return ret; +} + +static int gpio_adi_max22017_init(const struct device *dev) +{ + const struct gpio_adi_max22017_config *config = dev->config; + const struct device *parent = config->parent; + + if (!device_is_ready(parent)) { + LOG_ERR("parent adi_max22017 MFD device '%s' not ready", config->parent->name); + return -EINVAL; + } + +#ifdef CONFIG_GPIO_MAX22017_INT_QUIRK + struct gpio_adi_max22017_data *data = dev->data; + struct k_timer *t = &data->int_quirk_timer; + + k_timer_init(t, isr_quirk_handler, NULL); + k_timer_user_data_set(t, parent->data); + k_timer_start(t, K_MSEC(25), K_MSEC(25)); +#endif + return 0; +} + +static DEVICE_API(gpio, gpio_adi_max22017_api) = { + .pin_configure = gpio_adi_max22017_configure, + .port_set_masked_raw = gpio_adi_max22017_port_set_masked_raw, + .port_set_bits_raw = gpio_adi_max22017_port_set_bits_raw, + .port_clear_bits_raw = gpio_adi_max22017_port_clear_bits_raw, + .port_toggle_bits = gpio_adi_max22017_port_toggle_bits, + .port_get_raw = gpio_adi_max22017_port_get_raw, + .pin_interrupt_configure = gpio_adi_max22017_pin_interrupt_configure, + .manage_callback = gpio_adi_max22017_manage_cb, +}; + +#define GPIO_MAX22017_DEVICE(id) \ + static const struct gpio_adi_max22017_config gpio_adi_max22017_##id##_cfg = { \ + .common = \ + { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(id), \ + }, \ + .parent = DEVICE_DT_GET(DT_INST_PARENT(id)), \ + }; \ + static struct gpio_adi_max22017_data gpio_adi_max22017_##id##_data; \ + DEVICE_DT_INST_DEFINE(id, gpio_adi_max22017_init, NULL, &gpio_adi_max22017_##id##_data, \ + &gpio_adi_max22017_##id##_cfg, POST_KERNEL, \ + CONFIG_GPIO_MAX22017_INIT_PRIORITY, &gpio_adi_max22017_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_MAX22017_DEVICE) diff --git a/drivers/gpio/gpio_max22190.c b/drivers/gpio/gpio_max22190.c new file mode 100644 index 0000000000000..8fa04821d08fe --- /dev/null +++ b/drivers/gpio/gpio_max22190.c @@ -0,0 +1,666 @@ +/* + * Copyright (c) 2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max22190_gpio + +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL +#include + +LOG_MODULE_REGISTER(gpio_max22190); + +#include + +#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 +#warning "GPIO MAX22190 driver enabled without any devices" +#endif + +#define MAX22190_ENABLE 1 +#define MAX22190_DISABLE 0 + +#define MAX22190_READ 0 +#define MAX22190_WRITE 1 + +#define MAX22190_MAX_PKT_SIZE 3 +#define MAX22190_CHANNELS 8 +#define MAX22190_FAULT2_ENABLES 5 + +#define MAX22190_WB_REG 0x0 +#define MAX22190_DI_REG 0x2 +#define MAX22190_FAULT1_REG 0x4 +#define MAX22190_FILTER_IN_REG(x) (0x6 + (2 * (x))) +#define MAX22190_CFG_REG 0x18 +#define MAX22190_IN_EN_REG 0x1A +#define MAX22190_FAULT2_REG 0x1C +#define MAX22190_FAULT2_EN_REG 0x1E +#define MAX22190_GPO_REG 0x22 +#define MAX22190_FAULT1_EN_REG 0x24 +#define MAX22190_NOP_REG 0x26 + +#define MAX22190_CH_STATE_MASK(x) BIT(x) +#define MAX22190_DELAY_MASK GENMASK(2, 0) +#define MAX22190_FBP_MASK BIT(3) +#define MAX22190_WBE_MASK BIT(4) +#define MAX22190_RW_MASK BIT(7) +#define MAX22190_ADDR_MASK GENMASK(6, 0) +#define MAX22190_ALARM_MASK GENMASK(4, 3) +#define MAX22190_POR_MASK BIT(6) + +#define MAX22190_FAULT_MASK(x) BIT(x) +#define MAX22190_FAULT2_WBE_MASK BIT(4) + +#define MAX22190_FAULT2_EN_MASK GENMASK(5, 0) + +#define MAX22190_CFG_REFDI_MASK BIT(0) +#define MAX22190_CFG_CLRF_MASK BIT(3) +#define MAX22190_CFG_24VF_MASK BIT(4) + +#define PRINT_ERR_BIT(bit1, bit2) \ + if (bit1 & bit2) { \ + LOG_ERR("[%s] %d", #bit1, bit1); \ + } + +#define MAX22190_CLEAN_POR(dev) \ + max22190_reg_update(dev, MAX22190_FAULT1_REG, MAX22190_POR_MASK, \ + FIELD_PREP(MAX22190_POR_MASK, 0)) + +enum max22190_ch_state { + MAX22190_CH_OFF, + MAX22190_CH_ON +}; + +enum max22190_ch_wb_state { + MAX22190_CH_NO_WB_BREAK, + MAX22190_CH_WB_COND_DET +}; + +enum max22190_mode { + MAX22190_MODE_0, + MAX22190_MODE_1, + MAX22190_MODE_2, + MAX22190_MODE_3, +}; + +union max22190_fault1 { + uint8_t reg_raw; + struct { + uint8_t max22190_WBG: 1; /* BIT 0 */ + uint8_t max22190_24VM: 1; + uint8_t max22190_24VL: 1; + uint8_t max22190_ALRMT1: 1; + uint8_t max22190_ALRMT2: 1; + uint8_t max22190_FAULT2: 1; + uint8_t max22190_POR: 1; + uint8_t max22190_CRC: 1; /* BIT 7 */ + } reg_bits; +}; + +union max22190_fault1_en { + uint8_t reg_raw; + struct { + uint8_t max22190_WBGE: 1; /* BIT 0 */ + uint8_t max22190_24VME: 1; + uint8_t max22190_24VLE: 1; + uint8_t max22190_ALRMT1E: 1; + uint8_t max22190_ALRMT2E: 1; + uint8_t max22190_FAULT2E: 1; + uint8_t max22190_PORE: 1; + uint8_t max22190_CRCE: 1; /* BIT 7 */ + } reg_bits; +}; + +union max22190_fault2 { + uint8_t reg_raw; + struct { + uint8_t max22190_RFWBS: 1; /* BIT 0 */ + uint8_t max22190_RFWBO: 1; + uint8_t max22190_RFDIS: 1; + uint8_t max22190_RFDIO: 1; + uint8_t max22190_OTSHDN: 1; + uint8_t max22190_FAULT8CK: 1; + uint8_t max22190_DUMMY: 2; /* BIT 7 */ + } reg_bits; +}; + +union max22190_fault2_en { + uint8_t reg_raw; + struct { + uint8_t max22190_RFWBSE: 1; /* BIT 0 */ + uint8_t max22190_RFWBOE: 1; + uint8_t max22190_RFDISE: 1; + uint8_t max22190_RFDIOE: 1; + uint8_t max22190_OTSHDNE: 1; + uint8_t max22190_FAULT8CKE: 1; + uint8_t max22190_DUMMY: 2; /* BIT 7 */ + } reg_bits; +}; + +union max22190_cfg { + uint8_t reg_raw; + struct { + uint8_t max22190_DUMMY1: 3; /* BIT 0 */ + uint8_t max22190_24VF: 1; + uint8_t max22190_CLRF: 1; + uint8_t max22190_DUMMY2: 2; + uint8_t max22190_REFDI_SH_EN: 1; /* BIT 7 */ + } reg_bits; +}; + +union max22190_filter { + uint8_t reg_raw; + struct { + uint8_t max22190_DELAY: 3; /* BIT 0 */ + uint8_t max22190_FBP: 1; + uint8_t max22190_WBE: 1; + uint8_t max22190_DUMMY: 2; /* BIT 7 */ + } reg_bits; +}; + +enum max22190_delay { + MAX22190_DELAY_50US, + MAX22190_DELAY_100US, + MAX22190_DELAY_400US, + MAX22190_DELAY_800US, + MAX22190_DELAY_1800US, + MAX22190_DELAY_3200US, + MAX22190_DELAY_12800US, + MAX22190_DELAY_20000US +}; + +struct max22190_config { + struct spi_dt_spec spi; + struct gpio_dt_spec fault_gpio; + struct gpio_dt_spec ready_gpio; + struct gpio_dt_spec latch_gpio; + union max22190_filter filter[8]; + bool crc_en; + enum max22190_mode mode; + uint8_t pkt_size; +}; + +struct max22190_data { + struct gpio_driver_data common; + enum max22190_ch_state channels[MAX22190_CHANNELS]; + enum max22190_ch_wb_state wb[MAX22190_CHANNELS]; + union max22190_cfg cfg; + union max22190_fault1 fault1; + union max22190_fault1_en fault1_en; + union max22190_fault2 fault2; + union max22190_fault2_en fault2_en; +}; + +/* + * @brief Compute the CRC5 value for MAX22190 + * @param data - Data array to calculate CRC for. + * @return CRC result. + */ +static uint8_t max22190_crc(uint8_t *data) +{ + int length = 19; + uint8_t crc_step, tmp; + uint8_t crc_init = 0x7; + uint8_t crc_poly = 0x35; + int i; + + /* + * This is the C custom implementation of CRC function for MAX22190, and + * can be found here: + * https://www.analog.com/en/design-notes/guidelines-to-implement-crc-algorithm.html + */ + uint32_t datainput = (uint32_t)((data[0] << 16) + (data[1] << 8) + data[2]); + + datainput = (datainput & 0xFFFFE0) + crc_init; + + tmp = (uint8_t)((datainput & 0xFC0000) >> 18); + + if ((tmp & 0x20) == 0x20) { + crc_step = (uint8_t)(tmp ^ crc_poly); + } else { + crc_step = tmp; + } + + for (i = 0; i < length - 1; i++) { + tmp = (uint8_t)(((crc_step & 0x1F) << 1) + + ((datainput >> (length - 2 - i)) & 0x01)); + + if ((tmp & 0x20) == 0x20) { + crc_step = (uint8_t)(tmp ^ crc_poly); + } else { + crc_step = tmp; + } + } + + return (uint8_t)(crc_step & 0x1F); +} + +/* + * @brief Update chan WB state in max22190_data + * + * @param dev - MAX22190 device. + * @param val - value to be set. + */ +static void max22190_update_wb_stat(const struct device *dev, uint8_t val) +{ + struct max22190_data *data = dev->data; + + for (int ch_n = 0; ch_n < 8; ch_n++) { + data->wb[ch_n] = (val >> ch_n) & 0x1; + } +} + +/* + * @brief Update chan IN state in max22190_data + * + * @param dev - MAX22190 device. + * @param val - value to be set. + */ +static void max22190_update_in_stat(const struct device *dev, uint8_t val) +{ + struct max22190_data *data = dev->data; + + for (int ch_n = 0; ch_n < 8; ch_n++) { + data->channels[ch_n] = (val >> ch_n) & 0x1; + } +} + +/* + * @brief Register write function for MAX22190 + * + * @param dev - MAX22190 device config. + * @param addr - Register value to which data is written. + * @param val - Value which is to be written to requested register. + * @return 0 in case of success, negative error code otherwise. + */ +static int max22190_reg_transceive(const struct device *dev, uint8_t addr, uint8_t val, uint8_t rw) +{ + uint8_t crc; + int ret; + + uint8_t local_rx_buff[MAX22190_MAX_PKT_SIZE] = {0}; + uint8_t local_tx_buff[MAX22190_MAX_PKT_SIZE] = {0}; + + const struct max22190_config *config = dev->config; + + struct spi_buf tx_buf = { + .buf = &local_tx_buff, + .len = config->pkt_size, + }; + const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; + + struct spi_buf rx_buf = { + .buf = &local_rx_buff, + .len = config->pkt_size, + }; + const struct spi_buf_set rx = {.buffers = &rx_buf, .count = 1}; + + local_tx_buff[0] = + FIELD_PREP(MAX22190_ADDR_MASK, addr) | FIELD_PREP(MAX22190_RW_MASK, rw & 0x1); + local_tx_buff[1] = val; + + /* If CRC enabled calculate it */ + if (config->crc_en) { + local_tx_buff[2] = max22190_crc(&local_tx_buff[0]); + } + + /* write cmd & read resp at once */ + ret = spi_transceive_dt(&config->spi, &tx, &rx); + + if (ret) { + LOG_ERR("Err spi_transcieve_dt [%d]\n", ret); + return ret; + } + + /* if CRC enabled check readed */ + if (config->crc_en) { + crc = max22190_crc(&local_rx_buff[0]); + if (crc != (local_rx_buff[2] & 0x1F)) { + LOG_ERR("READ CRC ERR (%d)-(%d)\n", crc, (local_rx_buff[2] & 0x1F)); + return -EINVAL; + } + } + + /* always (R/W) get DI reg in first byte */ + max22190_update_in_stat(dev, local_rx_buff[0]); + + /* in case of writing register we get as second byte WB reg */ + if (rw == MAX22190_WRITE) { + max22190_update_wb_stat(dev, local_rx_buff[1]); + } else { + /* in case of READ second byte is value we are looking for */ + ret = local_rx_buff[1]; + } + + return ret; +} + +#define max22190_reg_read(dev, addr) max22190_reg_transceive(dev, addr, 0, MAX22190_READ) +#define max22190_reg_write(dev, addr, val) max22190_reg_transceive(dev, addr, val, MAX22190_WRITE) + +/* + * @brief Register update function for MAX22190 + * + * @param dev - MAX22190 device. + * @param addr - Register valueto wich data is updated. + * @param mask - Corresponding mask to the data that will be updated. + * @param val - Updated value to be written in the register at update. + * @return 0 in case of success, negative error code otherwise. + */ +static int max22190_reg_update(const struct device *dev, uint8_t addr, uint8_t mask, uint8_t val) +{ + int ret; + uint32_t reg_val = 0; + + ret = max22190_reg_read(dev, addr); + + reg_val = ret; + reg_val &= ~mask; + reg_val |= mask & val; + + return max22190_reg_write(dev, addr, reg_val); +} + +/* + * @brief Check FAULT1 and FAULT2 + * + * @param dev - MAX22190 device + */ +static void max22190_fault_check(const struct device *dev) +{ + struct max22190_data *data = dev->data; + + /* FAULT1 */ + data->fault1.reg_raw = max22190_reg_read(dev, MAX22190_FAULT1_REG); + + if (data->fault1.reg_raw) { + /* FAULT1_EN */ + data->fault1_en.reg_raw = max22190_reg_read(dev, MAX22190_FAULT1_EN_REG); + + PRINT_ERR_BIT(data->fault1.reg_bits.max22190_CRC, + data->fault1_en.reg_bits.max22190_CRCE); + PRINT_ERR_BIT(data->fault1.reg_bits.max22190_POR, + data->fault1_en.reg_bits.max22190_PORE); + PRINT_ERR_BIT(data->fault1.reg_bits.max22190_FAULT2, + data->fault1_en.reg_bits.max22190_FAULT2E); + PRINT_ERR_BIT(data->fault1.reg_bits.max22190_ALRMT2, + data->fault1_en.reg_bits.max22190_ALRMT2E); + PRINT_ERR_BIT(data->fault1.reg_bits.max22190_ALRMT1, + data->fault1_en.reg_bits.max22190_ALRMT1E); + PRINT_ERR_BIT(data->fault1.reg_bits.max22190_24VL, + data->fault1_en.reg_bits.max22190_24VLE); + PRINT_ERR_BIT(data->fault1.reg_bits.max22190_24VM, + data->fault1_en.reg_bits.max22190_24VME); + PRINT_ERR_BIT(data->fault1.reg_bits.max22190_WBG, + data->fault1_en.reg_bits.max22190_WBGE); + + if (data->fault1.reg_bits.max22190_WBG & data->fault1_en.reg_bits.max22190_WBGE) { + uint8_t wb_val = max22190_reg_read(dev, MAX22190_WB_REG); + + max22190_update_wb_stat(dev, (uint8_t)wb_val); + } + + if (data->fault1.reg_bits.max22190_FAULT2) { + /* FAULT2 */ + data->fault2.reg_raw = max22190_reg_read(dev, MAX22190_FAULT2_REG); + + /* FAULT2_EN */ + data->fault2_en.reg_raw = max22190_reg_read(dev, MAX22190_FAULT2_EN_REG); + + PRINT_ERR_BIT(data->fault2.reg_bits.max22190_RFWBS, + data->fault2_en.reg_bits.max22190_RFWBSE); + PRINT_ERR_BIT(data->fault2.reg_bits.max22190_RFWBO, + data->fault2_en.reg_bits.max22190_RFWBOE); + PRINT_ERR_BIT(data->fault2.reg_bits.max22190_RFDIS, + data->fault2_en.reg_bits.max22190_RFDISE); + PRINT_ERR_BIT(data->fault2.reg_bits.max22190_RFDIO, + data->fault2_en.reg_bits.max22190_RFDIOE); + PRINT_ERR_BIT(data->fault2.reg_bits.max22190_OTSHDN, + data->fault2_en.reg_bits.max22190_OTSHDNE); + PRINT_ERR_BIT(data->fault2.reg_bits.max22190_FAULT8CK, + data->fault2_en.reg_bits.max22190_FAULT8CKE); + } + } +} + +static void max22190_state_get(const struct device *dev) +{ + const struct max22190_config *config = dev->config; + + if (gpio_pin_get_dt(&config->fault_gpio)) { + max22190_fault_check(dev); + } + + /* We are reading WB reg because on first byte will be clocked out DI reg + * on second byte we will ge WB value. + */ + uint8_t wb_val = max22190_reg_read(dev, MAX22190_WB_REG); + + max22190_update_wb_stat(dev, (uint8_t)wb_val); +} + +static int gpio_max22190_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + int err = 0; + + if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) { + return -ENOTSUP; + } + + if ((flags & GPIO_SINGLE_ENDED) != 0) { + return -ENOTSUP; + } + + if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) { + return -ENOTSUP; + } + + if (flags & GPIO_INT_ENABLE) { + return -ENOTSUP; + } + + switch (flags & GPIO_DIR_MASK) { + case GPIO_INPUT: + LOG_INF("Nothing to do, only INPUT supported"); + break; + default: + LOG_ERR("On MAX22190 only input option is available!"); + return -ENOTSUP; + } + + return err; +} + +static void max22190_filter_set(const struct device *dev) +{ + const struct max22190_config *config = dev->config; + + for (int ch_n = 0; ch_n < 8; ch_n++) { + max22190_reg_write(dev, MAX22190_FILTER_IN_REG(ch_n), config->filter[ch_n].reg_raw); + } +} + +static int max22190_fault_set(const struct device *dev) +{ + const struct max22190_data *data = dev->data; + int ret = 0; + + ret = max22190_reg_write(dev, MAX22190_FAULT1_EN_REG, data->fault1_en.reg_raw); + if (ret) { + goto exit_fault_set; + } + + ret = max22190_reg_write(dev, MAX22190_FAULT1_REG, data->fault1.reg_raw); + if (ret) { + goto exit_fault_set; + } + + ret = max22190_reg_write(dev, MAX22190_FAULT2_EN_REG, data->fault2_en.reg_raw); + if (ret) { + goto exit_fault_set; + } + + ret = max22190_reg_write(dev, MAX22190_FAULT2_REG, data->fault2.reg_raw); + if (ret) { + goto exit_fault_set; + } + + return ret; + +exit_fault_set: + LOG_ERR("Err spi_transcieve_dt [%d]\n", ret); + return ret; +} + +static int gpio_max22190_port_get_raw(const struct device *dev, gpio_port_value_t *value) +{ + const struct max22190_data *data = dev->data; + + max22190_state_get(dev); + *value = 0; + for (int ch_n = 0; ch_n < 8; ch_n++) { + /* IN ch state */ + *value |= data->channels[ch_n] << ch_n; + } + + return 0; +} + +static int gpio_max22190_init(const struct device *dev) +{ + const struct max22190_config *config = dev->config; + struct max22190_data *data = dev->data; + + LOG_DBG("GPIO MAX22190 init IN\n"); + + int err = 0; + + if (!spi_is_ready_dt(&config->spi)) { + LOG_ERR("SPI bus is not ready\n"); + return -ENODEV; + } + + /* setup READY gpio - normal low */ + if (!gpio_is_ready_dt(&config->ready_gpio)) { + LOG_ERR("READY GPIO device not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->ready_gpio, GPIO_INPUT); + if (err < 0) { + LOG_ERR("Failed to configure reset GPIO"); + return err; + } + + /* setup FAULT gpio - normal high */ + if (!gpio_is_ready_dt(&config->fault_gpio)) { + LOG_ERR("FAULT GPIO device not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->fault_gpio, GPIO_INPUT | GPIO_PULL_UP); + if (err < 0) { + LOG_ERR("Failed to configure DC GPIO"); + return err; + } + + /* setup LATCH gpio - normal high */ + if (!gpio_is_ready_dt(&config->latch_gpio)) { + LOG_ERR("LATCH GPIO device not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->latch_gpio, GPIO_OUTPUT_INACTIVE); + if (err < 0) { + LOG_ERR("Failed to configure busy GPIO"); + return err; + } + + for (int i = 0; i < 8; i++) { + LOG_DBG("IN%d WBE [%d] FBP[%d] DELAY[%d]\n", i, + config->filter[i].reg_bits.max22190_WBE, + config->filter[i].reg_bits.max22190_FBP, + config->filter[i].reg_bits.max22190_DELAY); + } + + LOG_DBG(" > MAX22190 MODE: %x", config->mode); + LOG_DBG(" > MAX22190 PKT SIZE: %dbits (%dbytes)", config->pkt_size * 8, config->pkt_size); + LOG_DBG(" > MAX22190 CRC: %s", config->crc_en ? "enable" : "disable"); + + data->fault1_en.reg_bits.max22190_WBGE = 1; + data->fault1_en.reg_bits.max22190_PORE = 1; + + /* Set all FAULT and FAULT_EN regs */ + max22190_fault_set(dev); + + /* Set channels filters */ + max22190_filter_set(dev); + + /* POR bit need to be cleared after start */ + MAX22190_CLEAN_POR(dev); + + LOG_DBG("GPIO MAX22190 init OUT\n"); + return 0; +} + +static DEVICE_API(gpio, gpio_max22190_api) = { + .pin_configure = gpio_max22190_config, + .port_get_raw = gpio_max22190_port_get_raw, +}; + +/* Assign appropriate value for FILTER delay*/ +#define MAX22190_FILTER_SET_DELAY(delay) \ + delay == 20000 ? MAX22190_DELAY_20000US \ + : delay == 12800 ? MAX22190_DELAY_12800US \ + : delay == 3200 ? MAX22190_DELAY_3200US \ + : delay == 1600 ? MAX22190_DELAY_1800US \ + : delay == 800 ? MAX22190_DELAY_800US \ + : delay == 400 ? MAX22190_DELAY_400US \ + : delay == 100 ? MAX22190_DELAY_100US \ + : delay == 50 ? MAX22190_DELAY_50US \ + : MAX22190_DELAY_20000US + +/* Set FILTERx reg */ +#define MAX22190_FILTER_BY_IDX(id, idx) \ + { \ + .reg_bits.max22190_DELAY = \ + MAX22190_FILTER_SET_DELAY(DT_INST_PROP_BY_IDX(id, filter_delays, idx)), \ + .reg_bits.max22190_FBP = DT_INST_PROP_BY_IDX(id, filter_fbps, idx), \ + .reg_bits.max22190_WBE = DT_INST_PROP_BY_IDX(id, filter_wbes, idx), \ + } + +#define GPIO_MAX22190_DEVICE(id) \ + static const struct max22190_config max22190_##id##_cfg = { \ + .spi = SPI_DT_SPEC_INST_GET(id, SPI_OP_MODE_MASTER | SPI_WORD_SET(8U), 0U), \ + .ready_gpio = GPIO_DT_SPEC_INST_GET(id, drdy_gpios), \ + .fault_gpio = GPIO_DT_SPEC_INST_GET(id, fault_gpios), \ + .latch_gpio = GPIO_DT_SPEC_INST_GET(id, latch_gpios), \ + .mode = DT_INST_PROP(id, max22190_mode), \ + .crc_en = !(DT_INST_PROP(id, max22190_mode) & 0x1), \ + .pkt_size = !(DT_INST_PROP(id, max22190_mode) & 0x1) ? 3 : 2, \ + .filter = \ + { \ + MAX22190_FILTER_BY_IDX(id, 0), \ + MAX22190_FILTER_BY_IDX(id, 1), \ + MAX22190_FILTER_BY_IDX(id, 2), \ + MAX22190_FILTER_BY_IDX(id, 3), \ + MAX22190_FILTER_BY_IDX(id, 4), \ + MAX22190_FILTER_BY_IDX(id, 5), \ + MAX22190_FILTER_BY_IDX(id, 6), \ + MAX22190_FILTER_BY_IDX(id, 7), \ + }, \ + }; \ + \ + static struct max22190_data max22190_##id##_data; \ + \ + DEVICE_DT_INST_DEFINE(id, &gpio_max22190_init, NULL, &max22190_##id##_data, \ + &max22190_##id##_cfg, POST_KERNEL, \ + CONFIG_GPIO_MAX22190_INIT_PRIORITY, &gpio_max22190_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_MAX22190_DEVICE) diff --git a/drivers/gpio/gpio_mchp_mec5.c b/drivers/gpio/gpio_mchp_mec5.c new file mode 100644 index 0000000000000..8b3fe7a598b14 --- /dev/null +++ b/drivers/gpio/gpio_mchp_mec5.c @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2024 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_mec5_gpio + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* 32 pins per bank. Each pin has a 4-byte control register */ +#define MEC5_GPIO_PIN_CTRL_RSHFT 7 +#define MEC5_GPIO_PIN_CTRL_ADDR_MSK 0xfu + +struct gpio_mec5_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + /* port ISR callback routine address */ + sys_slist_t callbacks; +}; + +struct gpio_mec5_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + uintptr_t pcr1_base; + uintptr_t parin_addr; + uintptr_t parout_addr; + uint32_t flags; +}; + +static inline uint32_t mec5_addr_to_port(uint32_t base_addr) +{ + return ((base_addr >> MEC5_GPIO_PIN_CTRL_RSHFT) & MEC5_GPIO_PIN_CTRL_ADDR_MSK); +} + +/* NOTE: gpio_flags_t b[0:15] are defined in the dt-binding gpio header. + * b[31:16] are defined in the driver gpio header. + */ +static int gpio_mec5_validate_flags(gpio_flags_t flags) +{ + if (flags & GPIO_LINE_OPEN_SOURCE) { + return -ENOTSUP; + } + + if ((flags & GPIO_OUTPUT_INIT_LOW) && (flags & GPIO_OUTPUT_INIT_HIGH)) { + return -EINVAL; + } + + return 0; +} + +static const struct mec_gpio_props cfg_props_init[] = { + {MEC_GPIO_PWRGT_PROP_ID, MEC_GPIO_PROP_PWRGT_VTR}, + {MEC_GPIO_OSEL_PROP_ID, MEC_GPIO_PROP_OSEL_CTRL}, + {MEC_GPIO_INPAD_DIS_PROP_ID, MEC_GPIO_PROP_INPAD_EN}, +}; + +/* Each GPIO pin has two 32-bit control registers. Control 1 configures pin + * features except for drive strength and slew rate in Control 2. + * A pin's input and output state can be read/written from either the Control 1 + * register or from corresponding bits in the GPIO parallel input/output registers. + * The parallel input and output registers group 32 pins into each register. + * The GPIO hardware restricts the pin output state to Control 1 or the parallel bit. + * Both output bits reflect each other on read and writes but only one is writable + * selected by the output control select bit in Control 1. In the configuration API + * we use Control 1 to configure all pin features and output state. Before exiting, + * we set the output select for parallel mode enabling writes to the parallel output bit. + */ +static int gpio_mec5_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t pin_num = 0u; + uint32_t port_num = 0u; + uint32_t temp = 0u; + int ret = 0; + size_t idx = 0; + struct mec_gpio_props props[8]; + + port_num = mec5_addr_to_port(config->pcr1_base); + ret = mec_hal_gpio_pin_num(port_num, pin, &pin_num); + if (ret != MEC_RET_OK) { + return -EINVAL; + } + + ret = mec_hal_gpio_port_pin_valid(port_num, pin); + if (ret != MEC_RET_OK) { + return -EINVAL; + } + + ret = gpio_mec5_validate_flags(flags); + if (ret) { + return ret; + } + + if (flags == GPIO_DISCONNECTED) { + ret = mec_hal_gpio_set_property(pin_num, MEC_GPIO_PWRGT_PROP_ID, + MEC_GPIO_PROP_PWRGT_OFF); + if (ret != MEC_RET_OK) { + ret = -EIO; + } + return ret; + } + + ret = mec_hal_gpio_set_props(pin_num, cfg_props_init, ARRAY_SIZE(cfg_props_init)); + if (ret != MEC_RET_OK) { + return -EIO; + } + + if (flags & GPIO_OUTPUT) { + props[idx].prop = MEC_GPIO_DIR_PROP_ID; + props[idx].val = MEC_GPIO_PROP_DIR_OUT; + idx++; + + props[idx].prop = MEC_GPIO_OBUFT_PROP_ID; + props[idx].val = MEC_GPIO_PROP_PUSH_PULL; + if (flags & GPIO_LINE_OPEN_DRAIN) { + props[idx].val = MEC_GPIO_PROP_OPEN_DRAIN; + } + idx++; + + props[idx].prop = MEC_GPIO_CTRL_OUT_VAL_ID; + props[idx].val = 0u; + if (flags & GPIO_OUTPUT_INIT_HIGH) { + props[idx].val = 1u; + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + props[idx].val = 0u; + } else { + mec_hal_gpio_pad_in(pin_num, &props[idx].val); + } + idx++; + } + + if (flags & GPIO_INPUT) { + props[idx].prop = MEC_GPIO_DIR_PROP_ID; + props[idx].val = MEC_GPIO_PROP_DIR_IN; + idx++; + } + + temp = flags & (GPIO_PULL_UP | GPIO_PULL_DOWN); + if (temp) { + props[idx].prop = MEC_GPIO_PUD_PROP_ID; + if (temp == (GPIO_PULL_UP | GPIO_PULL_DOWN)) { + props[idx].val = MEC_GPIO_PROP_REPEATER; + } else if (temp & GPIO_PULL_UP) { + props[idx].val = MEC_GPIO_PROP_PULL_UP; + } else { + props[idx].val = MEC_GPIO_PROP_PULL_DN; + } + idx++; + } + + ret = mec_hal_gpio_set_props(pin_num, props, idx); + if (ret != MEC_RET_OK) { + return -EIO; + } + + /* make output state in control read-only in control and read-write in parallel reg */ + ret = mec_hal_gpio_set_property(pin_num, MEC_GPIO_OSEL_PROP_ID, MEC_GPIO_PROP_OSEL_PAROUT); + if (ret != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static uint8_t gen_gpio_ctrl_icfg(enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + uint8_t idet; + + if (mode == GPIO_INT_MODE_DISABLED) { + idet = MEC_GPIO_PROP_IDET_DIS; + } else { + if (mode == GPIO_INT_MODE_LEVEL) { + if (trig == GPIO_INT_TRIG_HIGH) { + idet = MEC_GPIO_PROP_IDET_HI_LVL; + } else { + idet = MEC_GPIO_PROP_IDET_LO_LVL; + } + } else { + switch (trig) { + case GPIO_INT_TRIG_LOW: + idet = MEC_GPIO_PROP_IDET_EDGE_DN; + break; + case GPIO_INT_TRIG_HIGH: + idet = MEC_GPIO_PROP_IDET_EDGE_UP; + break; + case GPIO_INT_TRIG_BOTH: + idet = MEC_GPIO_PROP_IDET_EDGE_BOTH; + break; + default: + idet = MEC_GPIO_PROP_IDET_DIS; + break; + } + } + } + + return idet; +} + +/* Enable interrupt to propagate via its GIRQ to the NVIC */ +static void gpio_mec5_intr_en(uint8_t port, gpio_pin_t pin, enum gpio_int_mode mode) +{ + uint8_t en = 0u; + + if (mode != GPIO_INT_MODE_DISABLED) { + en = 1u; + } + + mec_hal_gpio_port_pin_ia_enable(port, pin, en); +} + +static const struct mec_gpio_props icfg_props_init[] = { + {MEC_GPIO_PWRGT_PROP_ID, MEC_GPIO_PROP_PWRGT_VTR}, + {MEC_GPIO_INPAD_DIS_PROP_ID, MEC_GPIO_PROP_INPAD_EN}, +}; + +static int gpio_mec5_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t pin_num = (uint32_t)MEC_PIN_MAX; + uint32_t port_num = 0; + int ret = 0; + uint8_t idet = 0, idet_curr = 0; + + /* Validate pin number range in terms of current port */ + port_num = mec5_addr_to_port(config->pcr1_base); + ret = mec_hal_gpio_port_pin_valid(port_num, pin); + if (ret != MEC_RET_OK) { + return -EINVAL; + } + + /* Check if GPIO port supports interrupts */ + if ((mode != GPIO_INT_MODE_DISABLED) && !(config->flags & GPIO_INT_ENABLE)) { + return -ENOTSUP; + } + + /* Disable interrupt in the EC aggregator */ + gpio_mec5_intr_en(port_num, pin, 0); + + mec_hal_gpio_pin_num(port_num, pin, &pin_num); + ret = mec_hal_gpio_set_props(pin_num, icfg_props_init, ARRAY_SIZE(icfg_props_init)); + if (ret) { + return -EIO; + } + + idet_curr = MEC_GPIO_PROP_IDET_DIS; + ret = mec_hal_gpio_get_property(pin_num, MEC_GPIO_IDET_PROP_ID, &idet_curr); + if (ret != MEC_RET_OK) { + return -EIO; + } + + idet = gen_gpio_ctrl_icfg(mode, trig); + if (idet_curr == idet) { + gpio_mec5_intr_en(port_num, pin, mode); + return 0; + } + + ret = mec_hal_gpio_set_property(pin_num, MEC_GPIO_IDET_PROP_ID, idet); + if (ret != MEC_RET_OK) { + return -EIO; + } + + ret = mec_hal_gpio_pin_ia_status_clr(pin_num); + if (ret != MEC_RET_OK) { + return -EIO; + } + + gpio_mec5_intr_en(port_num, pin, mode); + + return 0; +} + +static int gpio_mec5_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + int ret = mec_hal_gpio_parout_port_mask(port_num, value, (const uint32_t)mask); + + if (ret != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_port_set_bits_raw(const struct device *dev, uint32_t mask) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + int ret = mec_hal_gpio_parout_port_set_bits(port_num, (const uint32_t)mask); + + if (ret != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_port_clear_bits_raw(const struct device *dev, uint32_t mask) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + int ret = mec_hal_gpio_parout_port_mask(port_num, 0u, (const uint32_t)mask); + + if (ret != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_port_toggle_bits(const struct device *dev, uint32_t mask) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + + if (mec_hal_gpio_parout_port_xor(port_num, mask) != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_port_get_raw(const struct device *dev, uint32_t *value) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + + if (mec_hal_gpio_parin_port(port_num, value) != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + struct gpio_mec5_data *data = dev->data; + + gpio_manage_callback(&data->callbacks, callback, set); + + return 0; +} + +#ifdef CONFIG_GPIO_GET_DIRECTION +static int gpio_mec5_get_direction(const struct device *port, gpio_port_pins_t map, + gpio_port_pins_t *inputs, gpio_port_pins_t *outputs) +{ + if (!port) { + return -EINVAL; + } + + const struct gpio_mec5_config *config = port->config; + uint32_t valid_msk = 0u; + uint32_t pin_num = 0u, port_num = 0u; + int ret = 0; + uint8_t pwr_gate = 0u, dir = 0u, in_pad_dis = 0u; + + port_num = mec5_addr_to_port(config->pcr1_base); + ret = mec_hal_gpio_port_valid_mask(port_num, &valid_msk); + if (ret != MEC_RET_OK) { + return -EIO; + } + + *inputs = 0u; + *outputs = 0u; + for (uint8_t pin_pos = 0; pin_pos < 32; pin++) { + if (!map) { + break; + } + if ((map & BIT(pin_pos)) && (valid_msk & BIT(pin_pos))) { + mec_hal_gpio_pin_num(port_num, pin, &pin_num); + mec_hal_gpio_get_property(pin_num, MEC_GPIO_PWRGT_PROP_ID, &pwr_gate); + mec_hal_gpio_get_property(pin_num, MEC_GPIO_DIR_PROP_ID, &dir); + mec_hal_gpio_get_property(pin_num, MEC_GPIO_INPAD_DIS_PROP_ID, &in_pad_dis); + + if (pwr_gate != MEC_GPIO_PROP_PWRGT_OFF) { + if (outputs && (dir == MEC_GPIO_PROP_DIR_OUT)) { + *outputs |= BIT(pin_pos); + } else if (inputs && (in_pad_dis == MEC_GPIO_PROP_INPAD_EN)) { + *inputs |= BIT(pin_pos); + } + } + + map &= ~BIT(pin_pos); + } + } + + return 0; +} +#endif + +#ifdef CONFIG_GPIO_GET_CONFIG +int gpio_mec5_get_config(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags) +{ + if (!port || !flags) { + return -EINVAL; + } + + const struct gpio_mec5_config *config = port->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + int ret = mec_hal_gpio_port_pin_valid(port_num, pin); + + if (ret != MEC_RET_OK) { + return -EINVAL; + } + + uint32_t pin_ctrl = mec_hal_gpio_port_get_ctrl_nc(port_num, pin); + uint32_t pin_flags = 0u; + uint8_t prop = MEC_GPIO_PROP_DIR_IN; + + mec_hal_gpio_get_ctrl_property(pin_ctrl, MEC_GPIO_DIR_PROP_ID, &prop); + + if (prop == MEC_GPIO_PROP_DIR_OUT) { + pin_flags |= GPIO_OUTPUT; + mec_hal_gpio_get_ctrl_property(pin_ctrl, MEC_GPIO_CTRL_OUT_VAL_ID, &prop); + if (prop != 0) { + pin_flags |= GPIO_OUTPUT_INIT_HIGH; + } else { + pin_flags |= GPIO_OUTPUT_INIT_LOW; + } + + prop = MEC_GPIO_PROP_PUSH_PULL; + mec_hal_gpio_get_ctrl_property(pin_ctrl, MEC_GPIO_OBUFT_PROP_ID, &prop); + if (prop == MEC_GPIO_PROP_OPEN_DRAIN) { + pin_flags |= GPIO_OPEN_DRAIN; + } + } else { + prop = MEC_GPIO_PROP_INPAD_DIS; + mec_hal_gpio_get_ctrl_property(pin_ctrl, MEC_GPIO_INPAD_DIS_PROP_ID, &prop); + if (prop == MEC_GPIO_PROP_INPAD_EN) { + pin_flags |= GPIO_INPUT; + } + } + + if (pin_flags) { + *flags = pin_flags; + } else { + *flags = GPIO_DISCONNECTED; + } + + return 0; +} +#endif + +static void gpio_mec5_port_isr(const struct device *dev) +{ + const struct gpio_mec5_config *config = dev->config; + struct gpio_mec5_data *data = dev->data; + uint32_t girq_result = 0xffffffffu; + uint32_t port_num = 0u; + + /* Figure out which interrupts have been triggered from the EC + * aggregator result register + */ + port_num = mec5_addr_to_port(config->pcr1_base); + mec_hal_gpio_port_ia_result(port_num, &girq_result); + + /* Clear source register in aggregator before firing callbacks */ + mec_hal_gpio_port_ia_status_clr_mask(port_num, girq_result); + + gpio_fire_callbacks(&data->callbacks, dev, girq_result); +} + +/* GPIO driver official API table */ +static DEVICE_API(gpio, gpio_mec5_driver_api) = { + .pin_configure = gpio_mec5_configure, + .port_get_raw = gpio_mec5_port_get_raw, + .port_set_masked_raw = gpio_mec5_port_set_masked_raw, + .port_set_bits_raw = gpio_mec5_port_set_bits_raw, + .port_clear_bits_raw = gpio_mec5_port_clear_bits_raw, + .port_toggle_bits = gpio_mec5_port_toggle_bits, + .pin_interrupt_configure = gpio_mec5_pin_interrupt_configure, + .manage_callback = gpio_mec5_manage_callback, +#ifdef CONFIG_GPIO_GET_DIRECTION + .port_get_direction = gpio_mec5_get_direction, +#endif +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_mec5_get_config, +#endif +}; + +#define MEC5_GPIO_PORT_FLAGS(n) ((DT_INST_IRQ_HAS_CELL(n, irq)) ? GPIO_INT_ENABLE : 0) + +/* TODO remove port_num. Derive it from pin & pin_num? */ +#define MEC5_GPIO_PORT(n) \ + static int gpio_mec5_port_init_##n(const struct device *dev) \ + { \ + if (!(DT_INST_IRQ_HAS_CELL(n, irq))) { \ + return 0; \ + } \ + \ + const struct gpio_mec5_config *config = dev->config; \ + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); \ + \ + mec_hal_gpio_port_ia_ctrl(port_num, 1u); \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_mec5_port_isr, \ + DEVICE_DT_INST_GET(n), 0u); \ + irq_enable(DT_INST_IRQN(n)); \ + return 0; \ + } \ + static struct gpio_mec5_data gpio_mec5_port_data_##n; \ + static const struct gpio_mec5_config gpio_mec5_config_##n = { \ + .common = \ + { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .pcr1_base = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 0), \ + .parin_addr = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 1), \ + .parout_addr = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 2), \ + .flags = MEC5_GPIO_PORT_FLAGS(n), \ + }; \ + DEVICE_DT_INST_DEFINE(n, gpio_mec5_port_init_##n, NULL, &gpio_mec5_port_data_##n, \ + &gpio_mec5_config_##n, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_mec5_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MEC5_GPIO_PORT) diff --git a/drivers/gpio/gpio_mcp230xx.c b/drivers/gpio/gpio_mcp230xx.c index d44431ed96c59..e1a283ce5213e 100644 --- a/drivers/gpio/gpio_mcp230xx.c +++ b/drivers/gpio/gpio_mcp230xx.c @@ -75,15 +75,15 @@ static int mcp230xx_bus_is_ready(const struct device *dev) return 0; } -#define GPIO_MCP230XX_DEVICE(inst, num_gpios, open_drain) \ - static struct mcp23xxx_drv_data mcp230xx_##inst##_drvdata = { \ +#define GPIO_MCP230XX_DEVICE(inst, num_gpios, open_drain, model) \ + static struct mcp23xxx_drv_data mcp##model##_##inst##_drvdata = { \ /* Default for registers according to datasheet */ \ .reg_cache.iodir = 0xFFFF, .reg_cache.ipol = 0x0, .reg_cache.gpinten = 0x0, \ .reg_cache.defval = 0x0, .reg_cache.intcon = 0x0, .reg_cache.iocon = 0x0, \ .reg_cache.gppu = 0x0, .reg_cache.intf = 0x0, .reg_cache.intcap = 0x0, \ .reg_cache.gpio = 0x0, .reg_cache.olat = 0x0, \ }; \ - static const struct mcp23xxx_config mcp230xx_##inst##_config = { \ + static const struct mcp23xxx_config mcp##model##_##inst##_config = { \ .config = { \ .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \ }, \ @@ -98,22 +98,22 @@ static int mcp230xx_bus_is_ready(const struct device *dev) .write_fn = mcp230xx_write_port_regs, \ .bus_fn = mcp230xx_bus_is_ready, \ }; \ - DEVICE_DT_INST_DEFINE(inst, gpio_mcp23xxx_init, NULL, &mcp230xx_##inst##_drvdata, \ - &mcp230xx_##inst##_config, POST_KERNEL, \ + DEVICE_DT_INST_DEFINE(inst, gpio_mcp23xxx_init, NULL, &mcp##model##_##inst##_drvdata, \ + &mcp##model##_##inst##_config, POST_KERNEL, \ CONFIG_GPIO_MCP230XX_INIT_PRIORITY, &gpio_mcp23xxx_api_table); #define DT_DRV_COMPAT microchip_mcp23008 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 8, false) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 8, false, 23008) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT microchip_mcp23009 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 8, true) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 8, true, 23009) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT microchip_mcp23016 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, false) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, false, 23016) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT microchip_mcp23017 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, false) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, false, 23017) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT microchip_mcp23018 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, true) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP230XX_DEVICE, 16, true, 23018) #undef DT_DRV_COMPAT diff --git a/drivers/gpio/gpio_mcp23sxx.c b/drivers/gpio/gpio_mcp23sxx.c index c0ec7061df933..8d2749e50501a 100644 --- a/drivers/gpio/gpio_mcp23sxx.c +++ b/drivers/gpio/gpio_mcp23sxx.c @@ -113,20 +113,20 @@ static int mcp23sxx_bus_is_ready(const struct device *dev) return 0; } -#define GPIO_MCP23SXX_DEVICE(inst, num_gpios, open_drain) \ - static struct mcp23xxx_drv_data mcp23sxx_##inst##_drvdata = { \ +#define GPIO_MCP23SXX_DEVICE(inst, num_gpios, open_drain, model) \ + static struct mcp23xxx_drv_data mcp##model##_##inst##_drvdata = { \ /* Default for registers according to datasheet */ \ .reg_cache.iodir = 0xFFFF, .reg_cache.ipol = 0x0, .reg_cache.gpinten = 0x0, \ .reg_cache.defval = 0x0, .reg_cache.intcon = 0x0, .reg_cache.iocon = 0x0, \ .reg_cache.gppu = 0x0, .reg_cache.intf = 0x0, .reg_cache.intcap = 0x0, \ .reg_cache.gpio = 0x0, .reg_cache.olat = 0x0, \ }; \ - static struct mcp23xxx_config mcp23sxx_##inst##_config = { \ + static struct mcp23xxx_config mcp##model##_##inst##_config = { \ .config = { \ - .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \ }, \ .bus = { \ - .spi = SPI_DT_SPEC_INST_GET(inst, \ + .spi = SPI_DT_SPEC_INST_GET(inst, \ SPI_OP_MODE_MASTER | SPI_MODE_CPOL | \ SPI_MODE_CPHA | SPI_WORD_SET(8), 0) \ }, \ @@ -138,20 +138,20 @@ static int mcp23sxx_bus_is_ready(const struct device *dev) .write_fn = mcp23sxx_write_port_regs, \ .bus_fn = mcp23sxx_bus_is_ready \ }; \ - DEVICE_DT_INST_DEFINE(inst, gpio_mcp23xxx_init, NULL, &mcp23sxx_##inst##_drvdata, \ - &mcp23sxx_##inst##_config, POST_KERNEL, \ + DEVICE_DT_INST_DEFINE(inst, gpio_mcp23xxx_init, NULL, &mcp##model##_##inst##_drvdata, \ + &mcp##model##_##inst##_config, POST_KERNEL, \ CONFIG_GPIO_MCP23SXX_INIT_PRIORITY, &gpio_mcp23xxx_api_table); #define DT_DRV_COMPAT microchip_mcp23s08 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 8, false) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 8, false, 23s08) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT microchip_mcp23s09 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 8, true) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 8, true, 23s09) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT microchip_mcp23s17 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 16, false) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 16, false, 23s17) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT microchip_mcp23s18 -DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 16, true) +DT_INST_FOREACH_STATUS_OKAY_VARGS(GPIO_MCP23SXX_DEVICE, 16, true, 23s18) #undef DT_DRV_COMPAT diff --git a/drivers/gpio/gpio_mcp23xxx.c b/drivers/gpio/gpio_mcp23xxx.c index 48ed4bf06cd1b..a706f518ed7bb 100644 --- a/drivers/gpio/gpio_mcp23xxx.c +++ b/drivers/gpio/gpio_mcp23xxx.c @@ -23,7 +23,7 @@ #include LOG_MODULE_REGISTER(gpio_mcp23xxx); -#define MCP23XXX_RESET_TIME_US 1 +#define MCP23XXX_RESET_TIME_US 2 /** * @brief Reads given register from mcp23xxx. diff --git a/drivers/gpio/gpio_mcux.c b/drivers/gpio/gpio_mcux.c index 9a360a72a5508..44e6941ad7d2c 100644 --- a/drivers/gpio/gpio_mcux.c +++ b/drivers/gpio/gpio_mcux.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2017, 2023-2024 NXP + * Copyright 2017, 2023-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,12 +17,19 @@ #include +#if defined(CONFIG_PINCTRL_NXP_IOCON) +#include +/* Use IOCON to configure electrical characteristic, set PORT_Type as void. */ +#define PORT_Type void +#endif + struct gpio_mcux_config { /* gpio_driver_config needs to be first */ struct gpio_driver_config common; GPIO_Type *gpio_base; PORT_Type *port_base; unsigned int flags; + uint32_t port_no; }; struct gpio_mcux_data { @@ -32,8 +39,80 @@ struct gpio_mcux_data { sys_slist_t callbacks; }; -static int gpio_mcux_configure(const struct device *dev, - gpio_pin_t pin, gpio_flags_t flags) +#if defined(CONFIG_PINCTRL_NXP_IOCON) +static int gpio_mcux_iopctl_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_mcux_config *config = dev->config; + GPIO_Type *gpio_base = config->gpio_base; + uint32_t port_no = config->port_no; + volatile uint32_t pinconfig = 0; + + if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) { + return -ENOTSUP; + } + + if ((flags & GPIO_SINGLE_ENDED) != 0) { + return -ENOTSUP; + } + + /* The flags contain options that require touching registers in the + * GPIO module and the corresponding PORT module. + * + * Start with the GPIO module and set up the pin direction register. + * 0 - pin is input, 1 - pin is output + */ + + switch (flags & GPIO_DIR_MASK) { + case GPIO_INPUT: + gpio_base->PDDR &= ~BIT(pin); + /* Enable input buffer for input pins */ + pinconfig |= IOPCTL_INBUF_EN; + break; + case GPIO_OUTPUT: + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + gpio_base->PSOR = BIT(pin); + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + gpio_base->PCOR = BIT(pin); + } + gpio_base->PDDR |= BIT(pin); + break; + default: + return -ENOTSUP; + } + + /* Select GPIO mux for this pin (func 0 is always GPIO) */ + pinconfig |= IOPCTL_FUNC0; + + if ((flags & GPIO_PULL_UP) != 0) { + /* Enable and select pull up. */ + pinconfig |= (IOPCTL_PUPD_EN | IOPCTL_PULLUP_EN); + } else if ((flags & GPIO_PULL_DOWN) != 0) { + /* Enable and select pull down. */ + pinconfig |= (IOPCTL_PUPD_EN | IOPCTL_PULLDOWN_EN); + } + +#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH + /* Determine the drive strength */ + switch (flags & KINETIS_GPIO_DS_MASK) { + case KINETIS_GPIO_DS_DFLT: + /* Default is low drive strength */ + pinconfig |= IOPCTL_DRIVE_100OHM; + break; + case KINETIS_GPIO_DS_ALT: + /* Alternate is high drive strength */ + pinconfig |= IOPCTL_DRIVE_33OHM; + break; + default: + return -ENOTSUP; + } +#endif /* defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH */ + + IOPCTL_PinMuxSet(port_no, pin, pinconfig); + + return 0; +} +#else +static int gpio_mcux_port_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) { const struct gpio_mcux_config *config = dev->config; GPIO_Type *gpio_base = config->gpio_base; @@ -123,6 +202,7 @@ static int gpio_mcux_configure(const struct device *dev, return 0; } +#endif /* defined(CONFIG_PINCTRL_NXP_IOCON) */ static int gpio_mcux_port_get_raw(const struct device *dev, uint32_t *value) { @@ -134,9 +214,7 @@ static int gpio_mcux_port_get_raw(const struct device *dev, uint32_t *value) return 0; } -static int gpio_mcux_port_set_masked_raw(const struct device *dev, - uint32_t mask, - uint32_t value) +static int gpio_mcux_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) { const struct gpio_mcux_config *config = dev->config; GPIO_Type *gpio_base = config->gpio_base; @@ -146,8 +224,7 @@ static int gpio_mcux_port_set_masked_raw(const struct device *dev, return 0; } -static int gpio_mcux_port_set_bits_raw(const struct device *dev, - uint32_t mask) +static int gpio_mcux_port_set_bits_raw(const struct device *dev, uint32_t mask) { const struct gpio_mcux_config *config = dev->config; GPIO_Type *gpio_base = config->gpio_base; @@ -157,8 +234,7 @@ static int gpio_mcux_port_set_bits_raw(const struct device *dev, return 0; } -static int gpio_mcux_port_clear_bits_raw(const struct device *dev, - uint32_t mask) +static int gpio_mcux_port_clear_bits_raw(const struct device *dev, uint32_t mask) { const struct gpio_mcux_config *config = dev->config; GPIO_Type *gpio_base = config->gpio_base; @@ -178,11 +254,10 @@ static int gpio_mcux_port_toggle_bits(const struct device *dev, uint32_t mask) return 0; } +#if !(defined(CONFIG_PINCTRL_NXP_IOCON)) #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) -static uint32_t get_port_pcr_irqc_value_from_flags(const struct device *dev, - uint32_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) +static uint32_t get_port_pcr_irqc_value_from_flags(const struct device *dev, uint32_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) { port_interrupt_t port_interrupt = 0; @@ -214,22 +289,21 @@ static uint32_t get_port_pcr_irqc_value_from_flags(const struct device *dev, return PORT_PCR_IRQC(port_interrupt); } -#endif /* !defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT */ +#endif /* !defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT */ +#endif /* !(defined(CONFIG_PINCTRL_NXP_IOCON)) */ #if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && \ FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) -#define GPIO_MCUX_INTERRUPT_DISABLED 0 -#define GPIO_MCUX_INTERRUPT_LOGIC_0 0x8 -#define GPIO_MCUX_INTERRUPT_RISING_EDGE 0x9 -#define GPIO_MCUX_INTERRUPT_FALLING_EDGE 0xA -#define GPIO_MCUX_INTERRUPT_BOTH_EDGE 0xB -#define GPIO_MCUX_INTERRUPT_LOGIC_1 0xC - -static uint32_t get_gpio_icr_irqc_value_from_flags(const struct device *dev, - uint32_t pin, - enum gpio_int_mode mode, - enum gpio_int_trig trig) +#define GPIO_MCUX_INTERRUPT_DISABLED 0 +#define GPIO_MCUX_INTERRUPT_LOGIC_0 0x8 +#define GPIO_MCUX_INTERRUPT_RISING_EDGE 0x9 +#define GPIO_MCUX_INTERRUPT_FALLING_EDGE 0xA +#define GPIO_MCUX_INTERRUPT_BOTH_EDGE 0xB +#define GPIO_MCUX_INTERRUPT_LOGIC_1 0xC + +static uint32_t get_gpio_icr_irqc_value_from_flags(const struct device *dev, uint32_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) { uint8_t gpio_interrupt = 0; @@ -261,49 +335,48 @@ static uint32_t get_gpio_icr_irqc_value_from_flags(const struct device *dev, return GPIO_ICR_IRQC(gpio_interrupt); } -#endif /* (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) */ +#endif /* (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) */ -static int gpio_mcux_pin_interrupt_configure(const struct device *dev, - gpio_pin_t pin, enum gpio_int_mode mode, - enum gpio_int_trig trig) +static int gpio_mcux_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) { const struct gpio_mcux_config *config = dev->config; GPIO_Type *gpio_base = config->gpio_base; +#if !(defined(CONFIG_PINCTRL_NXP_IOCON)) PORT_Type *port_base = config->port_base; /* Check for an invalid pin number */ if (pin >= ARRAY_SIZE(port_base->PCR)) { return -EINVAL; } +#endif /* Check for an invalid pin configuration */ - if ((mode != GPIO_INT_MODE_DISABLED) && - ((gpio_base->PDDR & BIT(pin)) != 0)) { + if ((mode != GPIO_INT_MODE_DISABLED) && ((gpio_base->PDDR & BIT(pin)) != 0)) { return -EINVAL; } /* Check if GPIO port supports interrupts */ - if ((mode != GPIO_INT_MODE_DISABLED) && - ((config->flags & GPIO_INT_ENABLE) == 0U)) { + if ((mode != GPIO_INT_MODE_DISABLED) && ((config->flags & GPIO_INT_ENABLE) == 0U)) { return -ENOTSUP; } -#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) - uint32_t pcr = get_port_pcr_irqc_value_from_flags(dev, pin, mode, trig); - - port_base->PCR[pin] = (port_base->PCR[pin] & ~PORT_PCR_IRQC_MASK) | pcr; -#elif (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && \ +#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && \ FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) uint32_t icr = get_gpio_icr_irqc_value_from_flags(dev, pin, mode, trig); gpio_base->ICR[pin] = (gpio_base->ICR[pin] & ~GPIO_ICR_IRQC_MASK) | icr; -#endif /* !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) */ +#elif !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) + uint32_t pcr = get_port_pcr_irqc_value_from_flags(dev, pin, mode, trig); + + port_base->PCR[pin] = (port_base->PCR[pin] & ~PORT_PCR_IRQC_MASK) | pcr; +#endif /* !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) */ return 0; } -static int gpio_mcux_manage_callback(const struct device *dev, - struct gpio_callback *callback, bool set) +static int gpio_mcux_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) { struct gpio_mcux_data *data = dev->data; @@ -316,21 +389,21 @@ static void gpio_mcux_port_isr(const struct device *dev) struct gpio_mcux_data *data = dev->data; uint32_t int_status; -#if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) - int_status = config->port_base->ISFR; - - /* Clear the port interrupts */ - config->port_base->ISFR = int_status; -#elif (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && \ +#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) && \ FSL_FEATURE_GPIO_HAS_INTERRUPT_CHANNEL_SELECT) int_status = config->gpio_base->ISFR[0]; /* Clear the gpio interrupts */ config->gpio_base->ISFR[0] = int_status; +#elif !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) + int_status = config->port_base->ISFR; + + /* Clear the port interrupts */ + config->port_base->ISFR = int_status; #else int_status = 0U; ARG_UNUSED(config); -#endif /* !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) */ +#endif /* !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) */ gpio_fire_callbacks(&data->callbacks, dev, int_status); } @@ -350,20 +423,18 @@ static void gpio_mcux_shared_cluster_isr(const struct device *ports[]) #define CLUSTER_ARRAY_ELEMENT(node_id) DEVICE_DT_GET(node_id), -#define GPIO_MCUX_CLUSTER_INIT(node_id) \ - const struct device *shared_array##node_id[DT_CHILD_NUM_STATUS_OKAY(node_id) + 1] = \ - {DT_FOREACH_CHILD_STATUS_OKAY(node_id, CLUSTER_ARRAY_ELEMENT) NULL}; \ - \ - static int gpio_mcux_shared_interrupt_init##node_id(void) \ - { \ - IRQ_CONNECT(DT_IRQN(node_id), \ - DT_IRQ(node_id, priority), \ - gpio_mcux_shared_cluster_isr, \ - shared_array##node_id, 0); \ - irq_enable(DT_IRQN(node_id)); \ - \ - return 0; \ - } \ +#define GPIO_MCUX_CLUSTER_INIT(node_id) \ + const struct device *shared_array##node_id[DT_CHILD_NUM_STATUS_OKAY(node_id) + 1] = { \ + DT_FOREACH_CHILD_STATUS_OKAY(node_id, CLUSTER_ARRAY_ELEMENT) NULL}; \ + \ + static int gpio_mcux_shared_interrupt_init##node_id(void) \ + { \ + IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), \ + gpio_mcux_shared_cluster_isr, shared_array##node_id, 0); \ + irq_enable(DT_IRQN(node_id)); \ + \ + return 0; \ + } \ SYS_INIT(gpio_mcux_shared_interrupt_init##node_id, POST_KERNEL, 0); DT_FOREACH_STATUS_OKAY(nxp_gpio_cluster, GPIO_MCUX_CLUSTER_INIT) @@ -391,7 +462,11 @@ static int gpio_mcux_port_get_direction(const struct device *dev, gpio_port_pins #endif /* CONFIG_GPIO_GET_DIRECTION */ static DEVICE_API(gpio, gpio_mcux_driver_api) = { - .pin_configure = gpio_mcux_configure, +#if defined(CONFIG_PINCTRL_NXP_IOCON) + .pin_configure = gpio_mcux_iopctl_configure, +#else + .pin_configure = gpio_mcux_port_configure, +#endif .port_get_raw = gpio_mcux_port_get_raw, .port_set_masked_raw = gpio_mcux_port_set_masked_raw, .port_set_bits_raw = gpio_mcux_port_set_bits_raw, @@ -404,47 +479,44 @@ static DEVICE_API(gpio, gpio_mcux_driver_api) = { #endif /* CONFIG_GPIO_GET_DIRECTION */ }; -#define GPIO_MCUX_IRQ_INIT(n) \ - do { \ - IRQ_CONNECT(DT_INST_IRQN(n), \ - DT_INST_IRQ(n, priority), \ - gpio_mcux_port_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - \ - irq_enable(DT_INST_IRQN(n)); \ +#define GPIO_MCUX_IRQ_INIT(n) \ + do { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_mcux_port_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + \ + irq_enable(DT_INST_IRQN(n)); \ } while (false) #define GPIO_PORT_BASE_ADDR(n) DT_REG_ADDR(DT_INST_PHANDLE(n, nxp_kinetis_port)) - -#define GPIO_DEVICE_INIT_MCUX(n) \ - static int gpio_mcux_port## n ## _init(const struct device *dev); \ - \ - static const struct gpio_mcux_config gpio_mcux_port## n ## _config = {\ - .common = { \ - .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n),\ - }, \ - .gpio_base = (GPIO_Type *) DT_INST_REG_ADDR(n), \ - .port_base = (PORT_Type *) GPIO_PORT_BASE_ADDR(n), \ - .flags = UTIL_AND(UTIL_OR(DT_INST_IRQ_HAS_IDX(n, 0), \ - GPIO_HAS_SHARED_IRQ), GPIO_INT_ENABLE), \ - }; \ - \ - static struct gpio_mcux_data gpio_mcux_port## n ##_data; \ - \ - DEVICE_DT_INST_DEFINE(n, \ - gpio_mcux_port## n ##_init, \ - NULL, \ - &gpio_mcux_port## n ##_data, \ - &gpio_mcux_port## n##_config, \ - POST_KERNEL, \ - CONFIG_GPIO_INIT_PRIORITY, \ - &gpio_mcux_driver_api); \ - \ - static int gpio_mcux_port## n ##_init(const struct device *dev) \ - { \ +#define GPIO_PORT_NUMBER(n) COND_CODE_1(DT_INST_NODE_HAS_PROP(n, gpio_port_offest), \ + (DT_INST_PROP(n, gpio_port_offest) + n), (n)) \ + +#define GPIO_DEVICE_INIT_MCUX(n) \ + static int gpio_mcux_port##n##_init(const struct device *dev); \ + \ + static const struct gpio_mcux_config gpio_mcux_port##n##_config = { \ + .common = \ + { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .gpio_base = (GPIO_Type *)DT_INST_REG_ADDR(n), \ + .port_base = (PORT_Type *)GPIO_PORT_BASE_ADDR(n), \ + .flags = UTIL_AND(UTIL_OR(DT_INST_IRQ_HAS_IDX(n, 0), GPIO_HAS_SHARED_IRQ), \ + GPIO_INT_ENABLE), \ + .port_no = GPIO_PORT_NUMBER(n), \ + }; \ + \ + static struct gpio_mcux_data gpio_mcux_port##n##_data; \ + \ + DEVICE_DT_INST_DEFINE(n, gpio_mcux_port##n##_init, NULL, &gpio_mcux_port##n##_data, \ + &gpio_mcux_port##n##_config, POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_mcux_driver_api); \ + \ + static int gpio_mcux_port##n##_init(const struct device *dev) \ + { \ IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ - (GPIO_MCUX_IRQ_INIT(n);)) \ - return 0; \ + (GPIO_MCUX_IRQ_INIT(n);)) \ + return 0; \ } DT_INST_FOREACH_STATUS_OKAY(GPIO_DEVICE_INIT_MCUX) diff --git a/drivers/gpio/gpio_mcux_igpio.c b/drivers/gpio/gpio_mcux_igpio.c index 01cd0e4e2fd9f..e1d1b82619b6b 100644 --- a/drivers/gpio/gpio_mcux_igpio.c +++ b/drivers/gpio/gpio_mcux_igpio.c @@ -10,7 +10,9 @@ #include #include #include +#if __has_include("soc.h") #include +#endif #include #include @@ -18,11 +20,15 @@ #include +#define DEV_CFG(_dev) ((const struct mcux_igpio_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct mcux_igpio_data *)(_dev)->data) struct mcux_igpio_config { /* gpio_driver_config needs to be first */ struct gpio_driver_config common; - GPIO_Type *base; + + DEVICE_MMIO_NAMED_ROM(igpio_mmio); + const struct pinctrl_soc_pinmux *pin_muxes; uint8_t mux_count; }; @@ -30,15 +36,23 @@ struct mcux_igpio_config { struct mcux_igpio_data { /* gpio_driver_data needs to be first */ struct gpio_driver_data general; + + DEVICE_MMIO_NAMED_RAM(igpio_mmio); + /* port ISR callback routine address */ sys_slist_t callbacks; }; +static GPIO_Type *get_base(const struct device *dev) +{ + return (GPIO_Type *)DEVICE_MMIO_NAMED_GET(dev, igpio_mmio); +} + static int mcux_igpio_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) { const struct mcux_igpio_config *config = dev->config; - GPIO_Type *base = config->base; + GPIO_Type *base = get_base(dev); struct pinctrl_soc_pin pin_cfg; int cfg_idx = pin, i; @@ -63,7 +77,7 @@ static int mcux_igpio_configure(const struct device *dev, /* Set appropriate bits in pin configuration register */ volatile uint32_t *gpio_cfg_reg = - (volatile uint32_t *)config->pin_muxes[cfg_idx].config_register; + (volatile uint32_t *)(uintptr_t)config->pin_muxes[cfg_idx].config_register; uint32_t reg = *gpio_cfg_reg; #ifdef CONFIG_SOC_SERIES_IMXRT10XX @@ -204,8 +218,7 @@ static int mcux_igpio_configure(const struct device *dev, static int mcux_igpio_port_get_raw(const struct device *dev, uint32_t *value) { - const struct mcux_igpio_config *config = dev->config; - GPIO_Type *base = config->base; + GPIO_Type *base = get_base(dev); *value = base->DR; @@ -216,8 +229,7 @@ static int mcux_igpio_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) { - const struct mcux_igpio_config *config = dev->config; - GPIO_Type *base = config->base; + GPIO_Type *base = get_base(dev); base->DR = (base->DR & ~mask) | (mask & value); @@ -227,8 +239,7 @@ static int mcux_igpio_port_set_masked_raw(const struct device *dev, static int mcux_igpio_port_set_bits_raw(const struct device *dev, uint32_t mask) { - const struct mcux_igpio_config *config = dev->config; - GPIO_Type *base = config->base; + GPIO_Type *base = get_base(dev); GPIO_PortSet(base, mask); @@ -238,8 +249,7 @@ static int mcux_igpio_port_set_bits_raw(const struct device *dev, static int mcux_igpio_port_clear_bits_raw(const struct device *dev, uint32_t mask) { - const struct mcux_igpio_config *config = dev->config; - GPIO_Type *base = config->base; + GPIO_Type *base = get_base(dev); GPIO_PortClear(base, mask); @@ -249,8 +259,7 @@ static int mcux_igpio_port_clear_bits_raw(const struct device *dev, static int mcux_igpio_port_toggle_bits(const struct device *dev, uint32_t mask) { - const struct mcux_igpio_config *config = dev->config; - GPIO_Type *base = config->base; + GPIO_Type *base = get_base(dev); GPIO_PortToggle(base, mask); @@ -263,7 +272,7 @@ static int mcux_igpio_pin_interrupt_configure(const struct device *dev, enum gpio_int_trig trig) { const struct mcux_igpio_config *config = dev->config; - GPIO_Type *base = config->base; + GPIO_Type *base = get_base(dev); unsigned int key; uint8_t icr; int shift; @@ -327,9 +336,8 @@ static int mcux_igpio_manage_callback(const struct device *dev, static void mcux_igpio_port_isr(const struct device *dev) { - const struct mcux_igpio_config *config = dev->config; struct mcux_igpio_data *data = dev->data; - GPIO_Type *base = config->base; + GPIO_Type *base = get_base(dev); uint32_t int_flags; int_flags = base->ISR; @@ -375,11 +383,11 @@ static DEVICE_API(gpio, mcux_igpio_driver_api) = { static int mcux_igpio_##n##_init(const struct device *dev); \ \ static const struct mcux_igpio_config mcux_igpio_##n##_config = {\ + DEVICE_MMIO_NAMED_ROM_INIT(igpio_mmio, DT_DRV_INST(n)), \ .common = { \ .port_pin_mask = GPIO_DT_INST_PORT_PIN_MASK_NGPIOS_EXC(\ n, DT_INST_PROP(n, ngpios)),\ }, \ - .base = (GPIO_Type *)DT_INST_REG_ADDR(n), \ MCUX_IGPIO_PIN_INIT(n) \ }; \ \ @@ -402,6 +410,8 @@ static DEVICE_API(gpio, mcux_igpio_driver_api) = { IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 1), \ (MCUX_IGPIO_IRQ_INIT(n, 1);)) \ \ + DEVICE_MMIO_NAMED_MAP(dev, igpio_mmio, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); \ + \ return 0; \ } diff --git a/drivers/gpio/gpio_mfxstm32l152.c b/drivers/gpio/gpio_mfxstm32l152.c new file mode 100644 index 0000000000000..bf2e57c138a76 --- /dev/null +++ b/drivers/gpio/gpio_mfxstm32l152.c @@ -0,0 +1,639 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT st_mfxstm32l152 + +/** + * @file Driver for ST MFXstm32l152 I2C-based GPIO driver. + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL +#include +LOG_MODULE_REGISTER(mfxstm32l152); + +/* Register definitions */ +#define REG_ID 0x00 /* const 0x7b */ +#define REG_GPIO_IRQ_PEND 0x0c /* GPIO irq pending */ +#define REG_GPIO_STATE 0x10 /* GPIO state */ +#define REG_SYS_CTRL 0x40 /* System control */ +#define REG_SYS_IRQ_MODE 0x41 /* System irq mode */ +#define SYS_IRQ_MODE_OPEN_DRAIN (0 << 0) +#define SYS_IRQ_MODE_PUSH_PULL (1 << 0) +#define SYS_IRQ_MODE_POL_LOW (0 << 1) +#define SYS_IRQ_MODE_POL_HIGH (1 << 1) +#define REG_SYS_IRQ_EN 0x42 /* System irq enable */ +#define REG_GPIO_IRQ_EN 0x48 /* GPIO irq enable */ +#define REG_GPIO_IRQ_EVT 0x4c /* GPIO irq event */ +#define REG_GPIO_IRQ_TYPE 0x50 /* GPIO irq type */ +#define REG_GPIO_IRQ_ACK 0x54 /* GPIO irq ack */ +#define REG_GPIO_DIR 0x60 /* GPIO direction control */ +#define REG_GPIO_PUPD 0x68 /* GPIO pull-up/pull-down control */ +#define REG_GPIO_SET 0x6c /* GPIO set control */ +#define REG_GPIO_CLR 0x70 /* GPIO clear control */ + +#define MFXSTM32L152_ID 0x7b + +/** Configuration data */ +struct mfxstm32l152_drv_cfg { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + + /** Master I2C DT specification */ + struct i2c_dt_spec i2c_spec; + struct gpio_dt_spec int_gpio; +}; + +/** Cache of the pins configuration */ +struct mfxstm32l152_pins_state { + uint32_t direction; + uint32_t pupd; + uint32_t irq_enabled; +}; + +/** Runtime driver data */ +struct mfxstm32l152_drv_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + + /** Driver lock */ + struct k_sem lock; + + sys_slist_t callbacks; + struct k_work work; + + const struct device *dev; + struct gpio_callback int_gpio_cb; + struct mfxstm32l152_pins_state pins_state; +}; + +/** + * @brief read a register value from the MFX + * + * @param dev Pointer to the device structure for the driver instance. + * @param reg Address of the register + * @param buf Pointer to the place to store the value + * + * @retval 0 if successful. + * @retval Negative value for error code. + */ +static int read_reg(const struct device *dev, uint8_t reg, uint8_t *buf) +{ + const struct mfxstm32l152_drv_cfg *const config = dev->config; + uint8_t value; + int ret; + + ret = i2c_burst_read_dt(&config->i2c_spec, reg, (uint8_t *)&value, 1); + if (ret != 0) { + LOG_ERR("%s: error reading register 0x%X (%d)", dev->name, reg, ret); + return ret; + } + + *buf = value; + LOG_DBG("%s: Read: REG[0x%X] = 0x%X", dev->name, reg, value); + + return 0; +} + +/** + * @brief write a register of the MFX + * + * @param dev Pointer to the device structure for the driver instance. + * @param reg Address of the register to be written + * @param value Value to be written into the register + * + * @retval 0 if successful. + * @retval Negative value for error code. + */ +static int write_reg(const struct device *dev, uint8_t reg, uint8_t value) +{ + const struct mfxstm32l152_drv_cfg *const config = dev->config; + uint8_t buf[2]; + int ret; + + LOG_DBG("%s: Write: REG[0x%X] = 0x%X", dev->name, reg, value); + + buf[0] = reg; + buf[1] = value; + ret = i2c_write_dt(&config->i2c_spec, buf, sizeof(buf)); + if (ret != 0) { + LOG_ERR("%s: error writing to register 0x%X (%d)", dev->name, reg, ret); + } + + return ret; +} + +/** + * @brief Gets the state of a specified block of 3 registers from the MFX + * + * @param dev Pointer to the device structure for the driver instance. + * @param reg Address of the first of 3 registers to be read. + * @param buf Pointer to the buffer to output the register. + * + * @retval 0 if successful. + * @retval Negative value for error code. + */ +static int read_port_regs(const struct device *dev, uint8_t reg, uint32_t *buf) +{ + const struct mfxstm32l152_drv_cfg *const config = dev->config; + uint32_t port_data, value; + int ret; + + ret = i2c_burst_read_dt(&config->i2c_spec, reg, (uint8_t *)&port_data, 3); + if (ret != 0) { + LOG_ERR("%s: error reading register 0x%X (%d)", dev->name, reg, ret); + return ret; + } + + value = sys_le24_to_cpu(port_data); + *buf = value; + LOG_DBG("%s: Read: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X, REG[0x%X] = 0x%X", dev->name, reg, + (*buf & 0xFF), (reg + 1), ((*buf >> 8) & 0xFF), (reg + 2), ((*buf >> 16) & 0xFF)); + + return 0; +} + +/** + * @brief writes to a specified block of 3 registers into the MFX + * + * @param dev Pointer to the device structure for the driver instance. + * @param reg Address of the first of 3 registers to be written. + * @param value The pin value to be written into the registers. + * + * @retval 0 if successful. + * @retval Negative value for error code. + */ +static int write_port_regs(const struct device *dev, uint8_t reg, uint32_t value) +{ + const struct mfxstm32l152_drv_cfg *const config = dev->config; + uint8_t buf[4]; + int ret; + + LOG_DBG("%s: Write: REG[0x%X] = 0x%X, REG[0x%X] = 0x%X, REG[0x%X] = 0x%X", dev->name, reg, + (value & 0xFF), (reg + 1), ((value >> 8) & 0xFF), (reg + 2), + ((value >> 16) & 0xFF)); + + buf[0] = reg; + sys_put_le24(value, &buf[1]); + ret = i2c_write_dt(&config->i2c_spec, buf, sizeof(buf)); + if (ret != 0) { + LOG_ERR("%s: error writing to register 0x%X (%d)", dev->name, reg, ret); + } + + return ret; +} + +/** + * @brief Handles interrupt triggered by the interrupt pin of MFXSTM32L152. + * + * If int_gpios is configured in device tree then this will be triggered each + * time a gpio configured as an input changes state. The gpio input states are + * read in this function which clears the interrupt. + * + * @param dev Pointer to the device structure for the driver instance. + */ +static void mfxstm32l152_handle_interrupt(const struct device *dev) +{ + struct mfxstm32l152_drv_data *drv_data = dev->data; + uint32_t irq_status; + int ret; + + k_sem_take(&drv_data->lock, K_FOREVER); + + /* Any interrupts enabled? */ + if (!drv_data->pins_state.irq_enabled) { + k_sem_give(&drv_data->lock); + return; + } + + /* Check pending irq status */ + ret = read_port_regs(dev, REG_GPIO_IRQ_PEND, &irq_status); + if (ret != 0) { + k_sem_give(&drv_data->lock); + return; + } + + if (irq_status == 0) { + k_sem_give(&drv_data->lock); + return; + } + + /* Ack everything */ + ret = write_port_regs(dev, REG_GPIO_IRQ_ACK, irq_status); + if (ret != 0) { + k_sem_give(&drv_data->lock); + return; + } + + k_sem_give(&drv_data->lock); + + gpio_fire_callbacks(&drv_data->callbacks, dev, irq_status); +} + +/** + * @brief Work handler for MFXSTM32L152 interrupt + * + * @param work Work struct that contains pointer to interrupt handler function + */ +static void mfxstm32l152_work_handler(struct k_work *work) +{ + struct mfxstm32l152_drv_data *drv_data = + CONTAINER_OF(work, struct mfxstm32l152_drv_data, work); + + mfxstm32l152_handle_interrupt(drv_data->dev); +} + +/** + * @brief ISR for interrupt pin of MFXSTM32L152 + * + * @param dev Pointer to the device structure for the driver instance. + * @param gpio_cb Pointer to callback function struct + * @param pins Bitmask of pins that triggered interrupt + */ +static void mfxstm32l152_int_gpio_handler(const struct device *dev, struct gpio_callback *gpio_cb, + uint32_t pins) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pins); + + struct mfxstm32l152_drv_data *drv_data = + CONTAINER_OF(gpio_cb, struct mfxstm32l152_drv_data, int_gpio_cb); + + k_work_submit(&drv_data->work); +} + +static int set_pin_dir_mode(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + struct mfxstm32l152_drv_data *const drvdata = + (struct mfxstm32l152_drv_data *const)dev->data; + uint32_t *dir_cache = &drvdata->pins_state.direction; + uint32_t *mode_cache = &drvdata->pins_state.pupd; + bool need_update = false; + uint32_t dir, mode; + int ret = 0; + + /* In case of configure in output mode first set initial state */ + if ((flags & GPIO_OUTPUT) != 0U) { + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) { + ret = write_port_regs(dev, REG_GPIO_SET, BIT(pin)); + if (ret != 0) { + goto out; + } + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) { + ret = write_port_regs(dev, REG_GPIO_CLR, BIT(pin)); + if (ret != 0) { + goto out; + } + } + } + + /* Configure direction */ + if ((flags & GPIO_OUTPUT) && ((*mode_cache & BIT(pin)) == 0)) { + dir = *dir_cache | BIT(pin); + need_update = true; + } else if ((flags & GPIO_INPUT) && ((*mode_cache & BIT(pin)) != 0)) { + dir = *dir_cache & ~BIT(pin); + need_update = true; + } + if (need_update) { + ret = write_port_regs(dev, REG_GPIO_DIR, dir); + if (ret != 0) { + goto out; + } + *dir_cache = dir; + } + + /* In case of input mode, configure PullUp/ PullDown */ + need_update = false; + if ((flags & GPIO_INPUT) != 0U) { + if ((flags & GPIO_PULL_UP) && ((*mode_cache & BIT(pin)) == 0)) { + mode = *mode_cache | BIT(pin); + need_update = true; + } else if ((flags & GPIO_PULL_DOWN) && ((*mode_cache & BIT(pin)) != 0)) { + mode = *mode_cache & ~BIT(pin); + need_update = true; + } + } + if (need_update) { + ret = write_port_regs(dev, REG_GPIO_PUPD, mode); + if (ret != 0) { + goto out; + } + *mode_cache = mode; + } + +out: + return ret; +} + +static int mfxstm32l152_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + struct mfxstm32l152_drv_data *const drvdata = + (struct mfxstm32l152_drv_data *const)dev->data; + int ret; + + /* No support for disconnected pin, single ended and simultaneous input / output */ + if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED || + (flags & GPIO_SINGLE_ENDED) != 0 || + (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0))) { + return -ENOTSUP; + } + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_sem_take(&drvdata->lock, K_FOREVER); + + ret = set_pin_dir_mode(dev, pin, flags); + if (ret != 0) { + LOG_ERR("%s: error setting pin direction and mode (%d)", dev->name, ret); + } + + k_sem_give(&drvdata->lock); + + return ret; +} + +static int mfxstm32l152_port_get_raw(const struct device *dev, uint32_t *value) +{ + struct mfxstm32l152_drv_data *const drvdata = + (struct mfxstm32l152_drv_data *const)dev->data; + uint32_t reg_value; + int ret; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_sem_take(&drvdata->lock, K_FOREVER); + ret = read_port_regs(dev, REG_GPIO_STATE, ®_value); + k_sem_give(&drvdata->lock); + + if (ret == 0) { + *value = reg_value; + } + + return ret; +} + +static int mfxstm32l152_port_set_bits_raw(const struct device *dev, uint32_t mask) +{ + struct mfxstm32l152_drv_data *const drvdata = + (struct mfxstm32l152_drv_data *const)dev->data; + int ret; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_sem_take(&drvdata->lock, K_FOREVER); + ret = write_port_regs(dev, REG_GPIO_SET, mask); + k_sem_give(&drvdata->lock); + + return ret; +} + +static int mfxstm32l152_port_clear_bits_raw(const struct device *dev, uint32_t mask) +{ + struct mfxstm32l152_drv_data *const drvdata = + (struct mfxstm32l152_drv_data *const)dev->data; + int ret; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_sem_take(&drvdata->lock, K_FOREVER); + ret = write_port_regs(dev, REG_GPIO_CLR, mask); + k_sem_give(&drvdata->lock); + + return ret; +} + +static int mfxstm32l152_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + struct mfxstm32l152_drv_data *drv_data = dev->data; + uint32_t irq_event, irq_type; + int ret; + + k_sem_take(&drv_data->lock, K_FOREVER); + + if (mode == GPIO_INT_MODE_DISABLED) { + drv_data->pins_state.irq_enabled &= ~BIT(pin); + ret = write_port_regs(dev, REG_GPIO_IRQ_EN, drv_data->pins_state.irq_enabled); + if (ret != 0) { + k_sem_give(&drv_data->lock); + return ret; + } + + if (drv_data->pins_state.irq_enabled == 0) { + ret = write_reg(dev, REG_SYS_IRQ_EN, 0); + k_sem_give(&drv_data->lock); + return ret; + } + + k_sem_give(&drv_data->lock); + + return ret; + } + + /* Set mode (EDGE / LEVEL */ + ret = read_port_regs(dev, REG_GPIO_IRQ_EVT, &irq_event); + if (ret != 0) { + k_sem_give(&drv_data->lock); + return ret; + } + + if (mode == GPIO_INT_MODE_EDGE) { + irq_event |= BIT(pin); + } else { + irq_event &= ~BIT(pin); + } + + ret = write_port_regs(dev, REG_GPIO_IRQ_EVT, irq_event); + if (ret != 0) { + k_sem_give(&drv_data->lock); + return ret; + } + + /* Set High / Rising or Low / Falling */ + ret = read_port_regs(dev, REG_GPIO_IRQ_TYPE, &irq_type); + if (ret != 0) { + k_sem_give(&drv_data->lock); + return ret; + } + + /* We cannot handle BOTH edge so if BOTH is asked, we set it as HIGH */ + if (trig == GPIO_INT_TRIG_HIGH || trig == GPIO_INT_TRIG_BOTH) { + irq_type |= BIT(pin); + } else { + irq_type &= ~BIT(pin); + } + + ret = write_port_regs(dev, REG_GPIO_IRQ_TYPE, irq_type); + if (ret != 0) { + k_sem_give(&drv_data->lock); + return ret; + } + + /* Enable the interrupt */ + drv_data->pins_state.irq_enabled |= BIT(pin); + ret = write_port_regs(dev, REG_GPIO_IRQ_EN, drv_data->pins_state.irq_enabled); + if (ret != 0) { + k_sem_give(&drv_data->lock); + return ret; + } + + ret = write_reg(dev, REG_SYS_IRQ_EN, 1); + + k_sem_give(&drv_data->lock); + + return ret; +} + +static int mfxstm32l152_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + struct mfxstm32l152_drv_data *drv_data = dev->data; + + return gpio_manage_callback(&drv_data->callbacks, callback, set); +} + +static int mfxstm32l152_init(const struct device *dev) +{ + struct mfxstm32l152_drv_data *const drvdata = + (struct mfxstm32l152_drv_data *const)dev->data; + const struct mfxstm32l152_drv_cfg *drv_cfg = dev->config; + uint8_t chip_id, int_pin = 0; + int ret; + + if (!device_is_ready(drv_cfg->i2c_spec.bus)) { + LOG_ERR("I2C device not found"); + return -ENODEV; + } + + k_sem_init(&drvdata->lock, 1, 1); + + ret = read_reg(dev, REG_ID, &chip_id); + if (ret != 0) { + LOG_ERR("%s: Unable to read Chip ID", dev->name); + return ret; + } + + if (chip_id != MFXSTM32L152_ID) { + LOG_ERR("%s: Invalid Chip ID", dev->name); + return -EINVAL; + } + + ret = read_port_regs(dev, REG_GPIO_DIR, &drvdata->pins_state.direction); + if (ret != 0) { + LOG_ERR("%s: Unable to read initial directions", dev->name); + return ret; + } + + ret = read_port_regs(dev, REG_GPIO_PUPD, &drvdata->pins_state.pupd); + if (ret != 0) { + LOG_ERR("%s: Unable to read initial directions", dev->name); + return ret; + } + + ret = write_reg(dev, REG_SYS_CTRL, 0x01); + if (ret != 0) { + LOG_ERR("%s: Failed to enable GPIO", dev->name); + return ret; + } + + /* If the INT line is available, configure the callback for it. */ + if (drv_cfg->int_gpio.port) { + if (!gpio_is_ready_dt(&drv_cfg->int_gpio)) { + LOG_ERR("Cannot get pointer to gpio interrupt device %s init failed", + dev->name); + return -EINVAL; + } + + drvdata->dev = dev; + + k_work_init(&drvdata->work, mfxstm32l152_work_handler); + + ret = gpio_pin_configure_dt(&drv_cfg->int_gpio, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("%s init failed: %d", dev->name, ret); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&drv_cfg->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0) { + LOG_ERR("%s init failed: %d", dev->name, ret); + return ret; + } + + gpio_init_callback(&drvdata->int_gpio_cb, mfxstm32l152_int_gpio_handler, + BIT(drv_cfg->int_gpio.pin)); + + ret = gpio_add_callback(drv_cfg->int_gpio.port, &drvdata->int_gpio_cb); + if (ret != 0) { + LOG_ERR("%s init failed: %d", dev->name, ret); + return ret; + } + + /* Configure the INT_OUT pin based on int_gpio dt_flags */ + if ((drv_cfg->int_gpio.dt_flags & GPIO_OPEN_DRAIN) != 0) { + int_pin |= SYS_IRQ_MODE_OPEN_DRAIN; + } else { + int_pin |= SYS_IRQ_MODE_PUSH_PULL; + } + if ((drv_cfg->int_gpio.dt_flags & GPIO_ACTIVE_LOW) != 0) { + int_pin |= SYS_IRQ_MODE_POL_LOW; + } else { + int_pin |= SYS_IRQ_MODE_POL_HIGH; + } + + ret = write_reg(dev, REG_SYS_IRQ_MODE, int_pin); + } + + return ret; +} + +static DEVICE_API(gpio, mfxstm32l152_drv_api) = { + .pin_configure = mfxstm32l152_configure, + .port_get_raw = mfxstm32l152_port_get_raw, + .port_set_masked_raw = NULL, + .port_set_bits_raw = mfxstm32l152_port_set_bits_raw, + .port_clear_bits_raw = mfxstm32l152_port_clear_bits_raw, + .port_toggle_bits = NULL, + .pin_interrupt_configure = mfxstm32l152_pin_interrupt_configure, + .manage_callback = mfxstm32l152_manage_callback, +}; + +#define MFXSTM32L152_INIT(inst) \ + static struct mfxstm32l152_drv_cfg mfxstm32l152_##inst##_config = { \ + .common = {.port_pin_mask = 0x0fff}, \ + .i2c_spec = I2C_DT_SPEC_INST_GET(inst), \ + .int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \ + }; \ + \ + static struct mfxstm32l152_drv_data mfxstm32l152_##inst##_drv_data; \ + \ + DEVICE_DT_INST_DEFINE(inst, mfxstm32l152_init, NULL, &mfxstm32l152_##inst##_drv_data, \ + &mfxstm32l152_##inst##_config, POST_KERNEL, \ + CONFIG_GPIO_MFXSTM32L152_INIT_PRIORITY, &mfxstm32l152_drv_api); + +DT_INST_FOREACH_STATUS_OKAY(MFXSTM32L152_INIT) diff --git a/drivers/gpio/gpio_mmio32.c b/drivers/gpio/gpio_mmio32.c index b88fac97a8e97..bcc6dd258f5cb 100644 --- a/drivers/gpio/gpio_mmio32.c +++ b/drivers/gpio/gpio_mmio32.c @@ -26,27 +26,50 @@ * gpio_port_write. */ -#include +#define DT_DRV_COMPAT arm_mmio32_gpio + #include #include -static int gpio_mmio32_config(const struct device *dev, - gpio_pin_t pin, gpio_flags_t flags) +#include + +struct gpio_mmio32_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + volatile uint32_t *reg; + bool is_input; +}; + +struct gpio_mmio32_context { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + const struct gpio_mmio32_config *config; +}; + +int gpio_mmio32_init(const struct device *dev); + +static int gpio_mmio32_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) { struct gpio_mmio32_context *context = dev->data; const struct gpio_mmio32_config *config = context->config; - if ((config->mask & (1 << pin)) == 0) { + if ((config->common.port_pin_mask & (1 << pin)) == 0) { return -EINVAL; /* Pin not in our validity mask */ } - if (flags & ~(GPIO_INPUT | GPIO_OUTPUT | - GPIO_OUTPUT_INIT_LOW | GPIO_OUTPUT_INIT_HIGH | + if (flags & ~(GPIO_INPUT | GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW | GPIO_OUTPUT_INIT_HIGH | GPIO_ACTIVE_LOW)) { /* We ignore direction and fake polarity, rest is unsupported */ return -ENOTSUP; } + if (config->is_input && ((flags & GPIO_OUTPUT) != 0)) { + return -ENOTSUP; + } + if (!config->is_input && ((flags & GPIO_INPUT) != 0)) { + return -ENOTSUP; + } + if ((flags & GPIO_OUTPUT) != 0) { unsigned int key; volatile uint32_t *reg = config->reg; @@ -55,7 +78,7 @@ static int gpio_mmio32_config(const struct device *dev, if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { *reg = (*reg | (1 << pin)); } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { - *reg = (*reg & (config->mask & ~(1 << pin))); + *reg = (*reg & (config->common.port_pin_mask & ~(1 << pin))); } irq_unlock(key); } @@ -68,21 +91,19 @@ static int gpio_mmio32_port_get_raw(const struct device *dev, uint32_t *value) struct gpio_mmio32_context *context = dev->data; const struct gpio_mmio32_config *config = context->config; - *value = *config->reg & config->mask; + *value = *config->reg & config->common.port_pin_mask; return 0; } -static int gpio_mmio32_port_set_masked_raw(const struct device *dev, - uint32_t mask, - uint32_t value) +static int gpio_mmio32_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) { struct gpio_mmio32_context *context = dev->data; const struct gpio_mmio32_config *config = context->config; volatile uint32_t *reg = config->reg; unsigned int key; - mask &= config->mask; + mask &= config->common.port_pin_mask; value &= mask; /* Update pin state atomically */ @@ -93,15 +114,14 @@ static int gpio_mmio32_port_set_masked_raw(const struct device *dev, return 0; } -static int gpio_mmio32_port_set_bits_raw(const struct device *dev, - uint32_t mask) +static int gpio_mmio32_port_set_bits_raw(const struct device *dev, uint32_t mask) { struct gpio_mmio32_context *context = dev->data; const struct gpio_mmio32_config *config = context->config; volatile uint32_t *reg = config->reg; unsigned int key; - mask &= config->mask; + mask &= config->common.port_pin_mask; /* Update pin state atomically */ key = irq_lock(); @@ -111,15 +131,14 @@ static int gpio_mmio32_port_set_bits_raw(const struct device *dev, return 0; } -static int gpio_mmio32_port_clear_bits_raw(const struct device *dev, - uint32_t mask) +static int gpio_mmio32_port_clear_bits_raw(const struct device *dev, uint32_t mask) { struct gpio_mmio32_context *context = dev->data; const struct gpio_mmio32_config *config = context->config; volatile uint32_t *reg = config->reg; unsigned int key; - mask &= config->mask; + mask &= config->common.port_pin_mask; /* Update pin state atomically */ key = irq_lock(); @@ -129,15 +148,14 @@ static int gpio_mmio32_port_clear_bits_raw(const struct device *dev, return 0; } -static int gpio_mmio32_port_toggle_bits(const struct device *dev, - uint32_t mask) +static int gpio_mmio32_port_toggle_bits(const struct device *dev, uint32_t mask) { struct gpio_mmio32_context *context = dev->data; const struct gpio_mmio32_config *config = context->config; volatile uint32_t *reg = config->reg; unsigned int key; - mask &= config->mask; + mask &= config->common.port_pin_mask; /* Update pin state atomically */ key = irq_lock(); @@ -147,6 +165,14 @@ static int gpio_mmio32_port_toggle_bits(const struct device *dev, return 0; } +int gpio_mmio32_pin_interrupt_configure(const struct device *port, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + return -ENOTSUP; +} + DEVICE_API(gpio, gpio_mmio32_api) = { .pin_configure = gpio_mmio32_config, .port_get_raw = gpio_mmio32_port_get_raw, @@ -154,6 +180,7 @@ DEVICE_API(gpio, gpio_mmio32_api) = { .port_set_bits_raw = gpio_mmio32_port_set_bits_raw, .port_clear_bits_raw = gpio_mmio32_port_clear_bits_raw, .port_toggle_bits = gpio_mmio32_port_toggle_bits, + .pin_interrupt_configure = gpio_mmio32_pin_interrupt_configure, }; int gpio_mmio32_init(const struct device *dev) @@ -165,3 +192,21 @@ int gpio_mmio32_init(const struct device *dev) return 0; } + +#define MMIO32_GPIO_DEVICE(n) \ + static struct gpio_mmio32_context gpio_mmio32_##n##_ctx; \ + \ + static const struct gpio_mmio32_config gpio_mmio32_##n##_cfg = { \ + .common = \ + { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .reg = (volatile uint32_t *)DT_INST_REG_ADDR(n), \ + .is_input = DT_INST_PROP(n, direction_input), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, gpio_mmio32_init, NULL, &gpio_mmio32_##n##_ctx, \ + &gpio_mmio32_##n##_cfg, PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &gpio_mmio32_api); + +DT_INST_FOREACH_STATUS_OKAY(MMIO32_GPIO_DEVICE) diff --git a/drivers/gpio/gpio_nct38xx_alert.c b/drivers/gpio/gpio_nct38xx_alert.c index eb52339364a29..d1f3cca0d8578 100644 --- a/drivers/gpio/gpio_nct38xx_alert.c +++ b/drivers/gpio/gpio_nct38xx_alert.c @@ -157,12 +157,9 @@ static int nct38xx_alert_init(const struct device *dev) /* NCT38XX alert driver must be initialized after NCT38XX GPIO driver */ BUILD_ASSERT(CONFIG_GPIO_NCT38XX_ALERT_INIT_PRIORITY > CONFIG_GPIO_NCT38XX_INIT_PRIORITY); -#define NCT38XX_DEV_AND_COMMA(node_id, prop, idx) \ - DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)), - #define NCT38XX_ALERT_DEVICE_INSTANCE(inst) \ const struct device *nct38xx_dev_##inst[] = { \ - DT_INST_FOREACH_PROP_ELEM(inst, nct38xx_dev, NCT38XX_DEV_AND_COMMA)}; \ + DT_INST_FOREACH_PROP_ELEM_SEP(inst, nct38xx_dev, DEVICE_DT_GET_BY_IDX, (,))}; \ static struct nct38xx_mfd nct38xx_mfd_##inst[DT_INST_PROP_LEN(inst, nct38xx_dev)]; \ static const struct nct38xx_alert_config nct38xx_alert_cfg_##inst = { \ .irq_gpio = GPIO_DT_SPEC_INST_GET(inst, irq_gpios), \ diff --git a/drivers/gpio/gpio_npcx.c b/drivers/gpio/gpio_npcx.c index 9bdc3c5a08abe..6c614b2e85826 100644 --- a/drivers/gpio/gpio_npcx.c +++ b/drivers/gpio/gpio_npcx.c @@ -17,7 +17,7 @@ #include "soc_miwu.h" #include -LOG_MODULE_REGISTER(gpio_npcx, LOG_LEVEL_ERR); +LOG_MODULE_REGISTER(gpio_npcx, CONFIG_GPIO_LOG_LEVEL); /* GPIO module instances */ #define NPCX_GPIO_DEV(inst) DEVICE_DT_INST_GET(inst), diff --git a/drivers/gpio/gpio_npm2100.c b/drivers/gpio/gpio_npm2100.c index da7b649e29ad6..9fb15d19873f8 100644 --- a/drivers/gpio/gpio_npm2100.c +++ b/drivers/gpio/gpio_npm2100.c @@ -62,8 +62,8 @@ static int gpio_npm2100_port_set_masked_raw(const struct device *dev, gpio_port_ for (size_t idx = 0; idx < NPM2100_GPIO_PINS; idx++) { if ((mask & BIT(idx)) != 0U) { - i2c_reg_write_byte_dt(&config->i2c, NPM2100_GPIO_OUTPUT + idx, - !!(value & BIT(idx))); + ret = i2c_reg_write_byte_dt(&config->i2c, NPM2100_GPIO_OUTPUT + idx, + !!(value & BIT(idx))); if (ret != 0U) { return ret; } diff --git a/drivers/gpio/gpio_pca6416.c b/drivers/gpio/gpio_pca6416.c new file mode 100644 index 0000000000000..a0d9b083fffb5 --- /dev/null +++ b/drivers/gpio/gpio_pca6416.c @@ -0,0 +1,492 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_pca6416 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(pca6416, CONFIG_GPIO_LOG_LEVEL); + +#include + +/* PCA6416 Register addresses */ +#define PCA6416_INPUT_PORT0 0x00 +#define PCA6416_INPUT_PORT1 0x01 +#define PCA6416_OUTPUT_PORT0 0x02 +#define PCA6416_OUTPUT_PORT1 0x03 +#define PCA6416_POL_INV_PORT0 0x04 +#define PCA6416_POL_INV_PORT1 0x05 +#define PCA6416_CONFIG_PORT0 0x06 +#define PCA6416_CONFIG_PORT1 0x07 + +/* Number of pins supported by the device */ +#define NUM_PINS 16 + +/* Max to select all pins supported on the device. */ +#define ALL_PINS ((uint16_t)BIT_MASK(NUM_PINS)) + +/** Cache of the output configuration and data of the pins. */ +struct pca6416_pin_state { + uint16_t dir; + uint16_t input; + uint16_t output; +}; + +struct pca6416_irq_state { + uint16_t rising; + uint16_t falling; +}; + +/** Runtime driver data */ +struct pca6416_drv_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + struct pca6416_pin_state pin_state; + struct k_sem lock; + struct gpio_callback gpio_cb; + struct k_work work; + struct pca6416_irq_state irq_state; + const struct device *dev; + /* user ISR cb */ + sys_slist_t cb; +}; + +/** Configuration data */ +struct pca6416_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + struct i2c_dt_spec i2c; + const struct gpio_dt_spec gpio_int; + bool interrupt_enabled; +}; + +/** + * @brief Gets the state of input pins of the PCA6416 I/O Port and + * stores in driver data struct. + * + * @param dev Pointer to the device structure for the driver instance. + * + * @retval 0 If successful. + * @retval Negative value for error code. + */ +static int update_input(const struct device *dev) +{ + const struct pca6416_config *cfg = dev->config; + struct pca6416_drv_data *drv_data = dev->data; + uint16_t input_states; + int rc = 0; + + rc = i2c_burst_read_dt(&cfg->i2c, PCA6416_INPUT_PORT0, (uint8_t *)&input_states, 2); + if (rc == 0) { + drv_data->pin_state.input = input_states; + } + return rc; +} + +/** + * @brief Handles interrupt triggered by the interrupt pin of PCA6416 I/O Port. + * + * If interrupt-gpios is configured in device tree then this will be triggered each + * time a gpio configured as an input changes state. The gpio input states are + * read in this function which clears the interrupt. + * + * @param dev Pointer to the device structure for the driver instance. + */ +static void gpio_pca6416_handle_interrupt(const struct device *dev) +{ + struct pca6416_drv_data *drv_data = dev->data; + struct pca6416_irq_state *irq_state = &drv_data->irq_state; + int rc; + uint16_t previous_state; + uint16_t current_state; + uint16_t transitioned_pins; + uint16_t interrupt_status = 0; + + k_sem_take(&drv_data->lock, K_FOREVER); + + /* Any interrupts enabled? */ + if (!irq_state->rising && !irq_state->falling) { + rc = -EINVAL; + goto out; + } + + /* Store previous input state then read new value */ + previous_state = drv_data->pin_state.input; + rc = update_input(dev); + if (rc != 0) { + goto out; + } + + /* Find out which input pins have changed state */ + current_state = drv_data->pin_state.input; + transitioned_pins = previous_state ^ current_state; + + /* Mask gpio transactions with rising/falling edge interrupt config */ + interrupt_status = (irq_state->rising & transitioned_pins & + current_state); + interrupt_status |= (irq_state->falling & transitioned_pins & + previous_state); + +out: + k_sem_give(&drv_data->lock); + + if ((rc == 0) && (interrupt_status)) { + gpio_fire_callbacks(&drv_data->cb, dev, interrupt_status); + } +} + +/** + * @brief Work handler for PCA6416 interrupt + * + * @param work Work struct that contains pointer to interrupt handler function + */ +static void gpio_pca6416_work_handler(struct k_work *work) +{ + struct pca6416_drv_data *drv_data = + CONTAINER_OF(work, struct pca6416_drv_data, work); + + gpio_pca6416_handle_interrupt(drv_data->dev); +} + +/** + * @brief ISR for interrupt pin of PCA6416 + * + * @param dev Pointer to the device structure for the driver instance. + * @param gpio_cb Pointer to callback function struct + * @param pins Bitmask of pins that triggered interrupt + */ +static void gpio_pca6416_init_cb(const struct device *dev, + struct gpio_callback *gpio_cb, uint32_t pins) +{ + struct pca6416_drv_data *drv_data = + CONTAINER_OF(gpio_cb, struct pca6416_drv_data, gpio_cb); + ARG_UNUSED(pins); + + k_work_submit(&drv_data->work); +} + +static int gpio_pca6416_config(const struct device *dev, gpio_pin_t pin, + gpio_flags_t flags) +{ + const struct pca6416_config *cfg = dev->config; + struct pca6416_drv_data *drv_data = dev->data; + struct pca6416_pin_state *pins = &drv_data->pin_state; + int rc = 0; + bool data_first = false; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + /* Single Ended lines (Open drain and open source) not supported */ + if ((flags & GPIO_SINGLE_ENDED) != 0) { + return -ENOTSUP; + } + + /* The PCA6416 has no internal pull up support */ + if (((flags & GPIO_PULL_UP) != 0) || ((flags & GPIO_PULL_DOWN) != 0)) { + return -ENOTSUP; + } + + /* Simultaneous input & output mode not supported */ + if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) { + return -ENOTSUP; + } + + k_sem_take(&drv_data->lock, K_FOREVER); + + /* Ensure either Output or Input is specified */ + if ((flags & GPIO_OUTPUT) != 0) { + pins->dir &= ~BIT(pin); + if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + pins->output &= ~BIT(pin); + data_first = true; + } else if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + pins->output |= BIT(pin); + data_first = true; + } + } else if ((flags & GPIO_INPUT) != 0) { + pins->dir |= BIT(pin); + } else { + rc = -ENOTSUP; + goto out; + } + + /* Set output values */ + if (data_first) { + rc = i2c_burst_write_dt(&cfg->i2c, PCA6416_OUTPUT_PORT0, + (uint8_t *)&pins->output, 2); + } + + if (rc == 0) { + /* Set pin directions */ + rc = i2c_burst_write_dt(&cfg->i2c, PCA6416_CONFIG_PORT0, + (uint8_t *)&pins->dir, 2); + } + + if (rc == 0) { + /* Refresh input status */ + rc = update_input(dev); + } + +out: + k_sem_give(&drv_data->lock); + return rc; +} + +static int gpio_pca6416_port_read(const struct device *dev, + gpio_port_value_t *value) +{ + const struct pca6416_config *cfg = dev->config; + struct pca6416_drv_data *drv_data = dev->data; + uint16_t input_pin_data; + int rc = 0; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_sem_take(&drv_data->lock, K_FOREVER); + + /* Read Input Register */ + rc = i2c_burst_read_dt(&cfg->i2c, PCA6416_INPUT_PORT0, (uint8_t *)&input_pin_data, 2); + + LOG_DBG("read %x got %d", input_pin_data, rc); + + if (rc == 0) { + drv_data->pin_state.input = input_pin_data; + *value = (gpio_port_value_t)(drv_data->pin_state.input); + } + + k_sem_give(&drv_data->lock); + return rc; +} + +static int gpio_pca6416_port_write(const struct device *dev, + gpio_port_pins_t mask, + gpio_port_value_t value, + gpio_port_value_t toggle) +{ + const struct pca6416_config *cfg = dev->config; + struct pca6416_drv_data *drv_data = dev->data; + uint16_t *outp = &drv_data->pin_state.output; + int rc; + uint16_t orig_out; + uint16_t out; + + /* Can't do I2C bus operations from an ISR */ + if (k_is_in_isr()) { + return -EWOULDBLOCK; + } + + k_sem_take(&drv_data->lock, K_FOREVER); + + orig_out = *outp; + out = ((orig_out & ~mask) | (value & mask)) ^ toggle; + + rc = i2c_burst_write_dt(&cfg->i2c, PCA6416_OUTPUT_PORT0, (uint8_t *)&out, 2); + + if (rc == 0) { + *outp = out; + } + + k_sem_give(&drv_data->lock); + + LOG_DBG("write %x msk %08x val %08x => %x: %d", orig_out, mask, + value, out, rc); + + return rc; +} + +static int gpio_pca6416_port_set_masked(const struct device *dev, + gpio_port_pins_t mask, + gpio_port_value_t value) +{ + return gpio_pca6416_port_write(dev, mask, value, 0); +} + +static int gpio_pca6416_port_set_bits(const struct device *dev, + gpio_port_pins_t pins) +{ + return gpio_pca6416_port_write(dev, pins, pins, 0); +} + +static int gpio_pca6416_port_clear_bits(const struct device *dev, + gpio_port_pins_t pins) +{ + return gpio_pca6416_port_write(dev, pins, 0, 0); +} + +static int gpio_pca6416_port_toggle_bits(const struct device *dev, + gpio_port_pins_t pins) +{ + return gpio_pca6416_port_write(dev, 0, 0, pins); +} + +static int gpio_pca6416_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + const struct pca6416_config *cfg = dev->config; + struct pca6416_drv_data *drv_data = dev->data; + struct pca6416_irq_state *irq = &drv_data->irq_state; + + if (!cfg->interrupt_enabled) { + return -ENOTSUP; + } + /* Device does not support level-triggered interrupts. */ + if (mode == GPIO_INT_MODE_LEVEL) { + return -ENOTSUP; + } + + k_sem_take(&drv_data->lock, K_FOREVER); + + if (mode == GPIO_INT_MODE_DISABLED) { + irq->falling &= ~BIT(pin); + irq->rising &= ~BIT(pin); + } else { /* GPIO_INT_MODE_EDGE */ + if (trig == GPIO_INT_TRIG_BOTH) { + irq->falling |= BIT(pin); + irq->rising |= BIT(pin); + } else if (trig == GPIO_INT_TRIG_LOW) { + irq->falling |= BIT(pin); + irq->rising &= ~BIT(pin); + } else if (trig == GPIO_INT_TRIG_HIGH) { + irq->falling &= ~BIT(pin); + irq->rising |= BIT(pin); + } + } + + k_sem_give(&drv_data->lock); + + return 0; +} + +static int gpio_pca6416_manage_callback(const struct device *dev, + struct gpio_callback *callback, + bool set) +{ + struct pca6416_drv_data *data = dev->data; + + return gpio_manage_callback(&data->cb, callback, set); +} + +/** + * @brief Initialization function of PCA6416 + * + * This sets initial input/ output configuration and output states. + * The interrupt is configured if this is enabled. + * + * @param dev Device struct + * @return 0 if successful, failed otherwise. + */ +static int gpio_pca6416_init(const struct device *dev) +{ + const struct pca6416_config *cfg = dev->config; + struct pca6416_drv_data *drv_data = dev->data; + int rc = 0; + + if (!device_is_ready(cfg->i2c.bus)) { + LOG_ERR("I2C bus device not found"); + goto out; + } + + /* Do an initial read, this clears the interrupt pin and sets + * up the initial value of the pin state input data. + */ + rc = update_input(dev); + if (rc) { + goto out; + } + if (cfg->interrupt_enabled) { + if (!gpio_is_ready_dt(&cfg->gpio_int)) { + LOG_ERR("Cannot get pointer to gpio interrupt device"); + rc = -EINVAL; + goto out; + } + + drv_data->dev = dev; + + k_work_init(&drv_data->work, gpio_pca6416_work_handler); + + rc = gpio_pin_configure_dt(&cfg->gpio_int, GPIO_INPUT); + if (rc) { + goto out; + } + + rc = gpio_pin_interrupt_configure_dt(&cfg->gpio_int, + GPIO_INT_EDGE_TO_ACTIVE); + if (rc) { + goto out; + } + + gpio_init_callback(&drv_data->gpio_cb, + gpio_pca6416_init_cb, + BIT(cfg->gpio_int.pin)); + rc = gpio_add_callback(cfg->gpio_int.port, + &drv_data->gpio_cb); + + if (rc) { + goto out; + } + + } +out: + if (rc) { + LOG_ERR("%s init failed: %d", dev->name, rc); + } else { + LOG_INF("%s init ok", dev->name); + } + return rc; +} + +static DEVICE_API(gpio, api_table) = { + .pin_configure = gpio_pca6416_config, + .port_get_raw = gpio_pca6416_port_read, + .port_set_masked_raw = gpio_pca6416_port_set_masked, + .port_set_bits_raw = gpio_pca6416_port_set_bits, + .port_clear_bits_raw = gpio_pca6416_port_clear_bits, + .port_toggle_bits = gpio_pca6416_port_toggle_bits, + .pin_interrupt_configure = gpio_pca6416_pin_interrupt_configure, + .manage_callback = gpio_pca6416_manage_callback, +}; + +#define GPIO_PCA6416_INIT(n) \ + static const struct pca6416_config pca6416_cfg_##n = { \ + .i2c = I2C_DT_SPEC_INST_GET(n), \ + .common = { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .interrupt_enabled = DT_INST_NODE_HAS_PROP(n, interrupt_gpios), \ + .gpio_int = GPIO_DT_SPEC_INST_GET(n, interrupt_gpios), \ + }; \ + \ + static struct pca6416_drv_data pca6416_drvdata_##n = { \ + .lock = Z_SEM_INITIALIZER(pca6416_drvdata_##n.lock, 1, 1), \ + .pin_state.dir = ALL_PINS, \ + .pin_state.output = ALL_PINS, \ + }; \ + DEVICE_DT_INST_DEFINE(n, \ + gpio_pca6416_init, \ + NULL, \ + &pca6416_drvdata_##n, \ + &pca6416_cfg_##n, \ + POST_KERNEL, \ + CONFIG_GPIO_PCA6416_INIT_PRIORITY, \ + &api_table); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_PCA6416_INIT) diff --git a/drivers/gpio/gpio_pca95xx.c b/drivers/gpio/gpio_pca95xx.c index b31d85eeae6c5..c08094c8bb7ae 100644 --- a/drivers/gpio/gpio_pca95xx.c +++ b/drivers/gpio/gpio_pca95xx.c @@ -117,38 +117,6 @@ struct gpio_pca95xx_drv_data { #endif }; -static int read_port_reg(const struct device *dev, uint8_t reg, uint8_t pin, - uint16_t *cache, uint16_t *buf) -{ - const struct gpio_pca95xx_config * const config = dev->config; - uint8_t b_buf; - int ret; - - if (pin >= 8) { - reg++; - } - - ret = i2c_reg_read_byte_dt(&config->bus, reg, &b_buf); - if (ret != 0) { - LOG_ERR("PCA95XX[0x%X]: error reading register 0x%X (%d)", - config->bus.addr, reg, ret); - return ret; - } - - if (pin < 8) { - ((uint8_t *)cache)[LOW_BYTE_LE16_IDX] = b_buf; - } else { - ((uint8_t *)cache)[HIGH_BYTE_LE16_IDX] = b_buf; - } - - *buf = *cache; - - LOG_DBG("PCA95XX[0x%X]: Read: REG[0x%X] = 0x%X", - config->bus.addr, reg, b_buf); - - return 0; -} - /** * @brief Read both port 0 and port 1 registers of certain register function. * @@ -253,16 +221,6 @@ static int write_port_regs(const struct device *dev, uint8_t reg, return ret; } -static inline int update_input_reg(const struct device *dev, uint8_t pin, - uint16_t *buf) -{ - struct gpio_pca95xx_drv_data * const drv_data = - (struct gpio_pca95xx_drv_data * const)dev->data; - - return read_port_reg(dev, REG_INPUT_PORT0, pin, - &drv_data->reg_cache.input, buf); -} - static inline int update_input_regs(const struct device *dev, uint16_t *buf) { struct gpio_pca95xx_drv_data * const drv_data = @@ -301,6 +259,15 @@ static inline int update_direction_reg(const struct device *dev, uint8_t pin, &drv_data->reg_cache.dir, value); } +static inline int update_direction_regs(const struct device *dev, uint16_t value) +{ + struct gpio_pca95xx_drv_data * const drv_data = + (struct gpio_pca95xx_drv_data * const)dev->data; + + return write_port_regs(dev, REG_CONF_PORT0, + &drv_data->reg_cache.dir, value); +} + static inline int update_pul_sel_reg(const struct device *dev, uint8_t pin, uint16_t value) { @@ -374,6 +341,18 @@ static int setup_pin_dir(const struct device *dev, uint32_t pin, int flags) return ret; } +/** + * @brief Initialize pins to default state + * + * @param dev Device struct of the PCA95XX + * + * @return 0 if successful, failed otherwise + */ +static int init_pins(const struct device *dev) +{ + return update_direction_regs(dev, 0xFFFF); +} + /** * @brief Setup the pin pull up/pull down status * @@ -783,6 +762,7 @@ static int gpio_pca95xx_init(const struct device *dev) const struct gpio_pca95xx_config * const config = dev->config; struct gpio_pca95xx_drv_data * const drv_data = (struct gpio_pca95xx_drv_data * const)dev->data; + int ret; if (!device_is_ready(config->bus.bus)) { return -ENODEV; @@ -790,11 +770,14 @@ static int gpio_pca95xx_init(const struct device *dev) k_sem_init(&drv_data->lock, 1, 1); + ret = init_pins(dev); + if (ret != 0) { + return ret; + } + #ifdef CONFIG_GPIO_PCA95XX_INTERRUPT /* Check if GPIO port supports interrupts */ if ((config->capabilities & PCA_HAS_INTERRUPT) != 0) { - int ret; - /* Store self-reference for interrupt handling */ drv_data->instance = dev; diff --git a/drivers/gpio/gpio_pca_series.c b/drivers/gpio/gpio_pca_series.c index a4960503c0dee..7bfff83ce1ea0 100644 --- a/drivers/gpio/gpio_pca_series.c +++ b/drivers/gpio/gpio_pca_series.c @@ -376,7 +376,7 @@ static inline int gpio_pca_series_reg_write(const struct device *dev, #ifdef CONFIG_GPIO_PCA_SERIES_CACHE_ALL if (gpio_pca_series_reg_cache_offset(dev, reg_type) != PCA_REG_INVALID) { - gpio_pca_series_reg_cache_update(dev, reg_type, buf); + (void)gpio_pca_series_reg_cache_update(dev, reg_type, buf); } #endif /* CONFIG_GPIO_PCA_SERIES_CACHE_ALL */ @@ -853,11 +853,11 @@ void gpio_pca_series_cache_test(const struct device *dev) expected_offset += cache_size; LOG_WRN("testing reg %d size %d", reg_type, cache_size); - gpio_pca_series_reg_cache_update(dev, reg_type, reset_value_0); + (void)gpio_pca_series_reg_cache_update(dev, reg_type, reset_value_0); *buffer_p = 0; gpio_pca_series_reg_cache_read(dev, reg_type, buffer); LOG_WRN("fill 00, result: 0x%16.16x", *buffer_p); - gpio_pca_series_reg_cache_update(dev, reg_type, reset_value_1); + (void)gpio_pca_series_reg_cache_update(dev, reg_type, reset_value_1); *buffer_p = 0; gpio_pca_series_reg_cache_read(dev, reg_type, buffer); LOG_WRN("fill ff, result: 0x%16.16x", *buffer_p); @@ -898,7 +898,7 @@ static int gpio_pca_series_pin_configure(const struct device *dev, { const struct gpio_pca_series_config *cfg = dev->config; struct gpio_pca_series_data *data = dev->data; - uint32_t reg_value; + uint32_t reg_value = 0; int ret = 0; if ((flags & GPIO_INPUT) && (flags & GPIO_OUTPUT)) { @@ -1474,9 +1474,9 @@ static void gpio_pca_series_interrupt_handler_standard(const struct device *dev, { struct gpio_pca_series_data *data = dev->data; int ret = 0; - uint32_t input_old, int_rise, int_fall; - uint32_t input; - uint32_t transitioned_pins; + uint32_t input_old = 0, int_rise = 0, int_fall = 0; + uint32_t input = 0; + uint32_t transitioned_pins = 0; uint32_t int_status = 0; k_sem_take(&data->lock, K_FOREVER); diff --git a/drivers/gpio/gpio_renesas_ra_ioport.c b/drivers/gpio/gpio_renesas_ra_ioport.c index 8534fd87b6c8b..68d5334c67595 100644 --- a/drivers/gpio/gpio_renesas_ra_ioport.c +++ b/drivers/gpio/gpio_renesas_ra_ioport.c @@ -9,21 +9,56 @@ #include #include #include +#include #include -#include #include +struct gpio_ra_irq_info { + const struct device *port_irq; + const uint8_t *const pins; + size_t num; +}; + struct gpio_ra_config { struct gpio_driver_config common; uint8_t port_num; R_PORT0_Type *port; + const struct gpio_ra_irq_info *irq_info; + const size_t irq_info_size; gpio_pin_t vbatt_pins[]; }; struct gpio_ra_data { struct gpio_driver_data common; + sys_slist_t callbacks; }; +#if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT +static const struct gpio_ra_irq_info *query_irq_info(const struct device *dev, uint32_t pin) +{ + const struct gpio_ra_config *config = dev->config; + + for (int i = 0; i < config->irq_info_size; i++) { + const struct gpio_ra_irq_info *info = &config->irq_info[i]; + + for (int j = 0; j < info->num; j++) { + if (info->pins[j] == pin) { + return info; + } + } + } + + return NULL; +} + +static void gpio_ra_callback_adapter(const struct device *dev, gpio_pin_t pin) +{ + struct gpio_ra_data *data = dev->data; + + gpio_fire_callbacks(&data->callbacks, dev, BIT(pin)); +} +#endif + static int gpio_ra_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) { const struct gpio_ra_config *config = dev->config; @@ -39,10 +74,11 @@ static int gpio_ra_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_ return -ENOTSUP; } - if ((flags & GPIO_INT_ENABLE) != 0) { + if (!IS_ENABLED(CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT) && ((flags & GPIO_INT_ENABLE) != 0)) { return -ENOTSUP; } +#if CONFIG_GPIO_RA_HAS_VBTICTLR if (config->vbatt_pins[0] != 0xFF) { uint32_t clear = 0; @@ -58,6 +94,7 @@ static int gpio_ra_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_ R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); } +#endif pincfg.port_num = config->port_num; pincfg.pin_num = pin; @@ -88,12 +125,89 @@ static int gpio_ra_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_ WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_PCR_Pos, 1); } - pincfg.cfg = pfs_cfg | - (((flags & RENESAS_GPIO_DS_MSK) >> 8) << R_PFS_PORT_PIN_PmnPFS_DSCR_Pos); +#if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT + if ((flags & GPIO_INT_ENABLE) != 0) { + const struct gpio_ra_irq_info *irq_info = query_irq_info(dev, pin); + int err = 0; + + if (irq_info == NULL) { + return -EINVAL; + } + + if (!device_is_ready(irq_info->port_irq)) { + return -EWOULDBLOCK; + } + + struct gpio_ra_callback callback = { + .port = (struct device *)dev, + .port_num = config->port_num, + .pin = pin, + .mode = flags & (GPIO_INT_EDGE | GPIO_INT_DISABLE | GPIO_INT_ENABLE), + .trigger = flags & (GPIO_INT_LOW_0 | GPIO_INT_HIGH_1), + .isr = gpio_ra_callback_adapter, + }; + + err = gpio_ra_interrupt_set(irq_info->port_irq, &callback); + if (err < 0) { + return err; + } + + WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_ISEL_Pos, 1); + } + + if ((flags & GPIO_INT_DISABLE) != 0) { + const struct gpio_ra_irq_info *irq_info = query_irq_info(dev, pin); + + if (irq_info == NULL) { + return -EINVAL; + } + + if (!device_is_ready(irq_info->port_irq)) { + return -EWOULDBLOCK; + } + + gpio_ra_interrupt_unset(irq_info->port_irq, config->port_num, pin); + WRITE_BIT(pfs_cfg, R_PFS_PORT_PIN_PmnPFS_ISEL_Pos, 0); + } +#endif + + pincfg.cfg = + pfs_cfg | (((flags & RENESAS_GPIO_DS_MSK) >> 8) << R_PFS_PORT_PIN_PmnPFS_DSCR_Pos); return pinctrl_configure_pins(&pincfg, 1, PINCTRL_REG_NONE); } +__maybe_unused static int gpio_ra_pin_get_config(const struct device *dev, gpio_pin_t pin, + gpio_flags_t *flags) +{ + const struct gpio_ra_config *config = dev->config; + uint32_t pincfg; + + if (pin >= RA_PINCTRL_PIN_NUM) { + return -EINVAL; + } + + memset(flags, 0, sizeof(gpio_flags_t)); + + pincfg = R_PFS->PORT[config->port_num].PIN[pin].PmnPFS; + + if (pincfg & BIT(R_PFS_PORT_PIN_PmnPFS_PDR_Pos)) { + *flags |= GPIO_OUTPUT; + } else { + *flags |= GPIO_INPUT; + } + + if (pincfg & BIT(R_PFS_PORT_PIN_PmnPFS_NCODR_Pos)) { + *flags |= GPIO_LINE_OPEN_DRAIN; + } + + if (pincfg & BIT(R_PFS_PORT_PIN_PmnPFS_PCR_Pos)) { + *flags |= GPIO_PULL_UP; + } + + return 0; +} + static int gpio_ra_port_get_raw(const struct device *dev, uint32_t *value) { const struct gpio_ra_config *config = dev->config; @@ -145,18 +259,69 @@ static int gpio_ra_port_toggle_bits(const struct device *dev, gpio_port_pins_t p return 0; } +#if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT +static int gpio_ra_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + gpio_flags_t flags; + int err; + + err = gpio_ra_pin_get_config(port, pin, &flags); + if (err) { + return err; + } + + return gpio_ra_pin_configure(port, pin, (flags | mode | trig)); +} + +static int gpio_ra_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + struct gpio_ra_data *data = dev->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} +#endif + static DEVICE_API(gpio, gpio_ra_drv_api_funcs) = { .pin_configure = gpio_ra_pin_configure, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_ra_pin_get_config, +#endif .port_get_raw = gpio_ra_port_get_raw, .port_set_masked_raw = gpio_ra_port_set_masked_raw, .port_set_bits_raw = gpio_ra_port_set_bits_raw, .port_clear_bits_raw = gpio_ra_port_clear_bits_raw, .port_toggle_bits = gpio_ra_port_toggle_bits, - .pin_interrupt_configure = NULL, - .manage_callback = NULL, +#if CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT + .pin_interrupt_configure = gpio_ra_pin_interrupt_configure, + .manage_callback = gpio_ra_manage_callback, +#endif }; +#define GPIO_RA_PINS_NAME(n, p, i) CONCAT(DT_STRING_TOKEN_BY_IDX(n, p, i), _pins) + +#define GPIO_RA_DECL_PINS(n, p, i) \ + const uint8_t CONCAT(n, ___pins##i[]) = { \ + DT_FOREACH_PROP_ELEM_SEP(n, GPIO_RA_PINS_NAME(n, p, i), DT_PROP_BY_IDX, (,))}; + +#define GPIO_RA_IRQ_INFO(n, p, i) \ + { \ + .port_irq = DEVICE_DT_GET_OR_NULL(DT_PHANDLE_BY_IDX(n, port_irqs, i)), \ + .pins = CONCAT(n, ___pins##i), \ + .num = ARRAY_SIZE(CONCAT(n, ___pins##i)), \ + }, + +#define DECL_PINS_PARAMETER(node) \ + COND_CODE_1(DT_NODE_HAS_PROP(node, port_irq_names), \ + (DT_FOREACH_PROP_ELEM(node, port_irq_names, GPIO_RA_DECL_PINS)), ()) +#define IRQ_INFO_PARAMETER(node) \ + COND_CODE_1(DT_NODE_HAS_PROP(node, port_irq_names), \ + (DT_FOREACH_PROP_ELEM(node, port_irq_names, GPIO_RA_IRQ_INFO)), ()) + #define GPIO_DEVICE_INIT(node, port_number, suffix, addr) \ + DECL_PINS_PARAMETER(node); \ + struct gpio_ra_irq_info gpio_ra_irq_info_##suffix[] = {IRQ_INFO_PARAMETER(node)}; \ static const struct gpio_ra_config gpio_ra_config_##suffix = { \ .common = \ { \ @@ -165,6 +330,8 @@ static DEVICE_API(gpio, gpio_ra_drv_api_funcs) = { .port_num = port_number, \ .port = (R_PORT0_Type *)addr, \ .vbatt_pins = DT_PROP_OR(DT_NODELABEL(ioport##suffix), vbatts_pins, {0xFF}), \ + .irq_info = gpio_ra_irq_info_##suffix, \ + .irq_info_size = DT_PROP_LEN_OR(DT_NODELABEL(ioport##suffix), port_irq_names, 0), \ }; \ static struct gpio_ra_data gpio_ra_data_##suffix; \ DEVICE_DT_DEFINE(node, NULL, NULL, &gpio_ra_data_##suffix, &gpio_ra_config_##suffix, \ diff --git a/drivers/gpio/gpio_renesas_rz.c b/drivers/gpio/gpio_renesas_rz.c new file mode 100644 index 0000000000000..386bae12bfb1d --- /dev/null +++ b/drivers/gpio/gpio_renesas_rz.c @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rz_gpio + +#include +#include +#include +#include +#include "r_ioport.h" +#include +#include +#include "gpio_renesas_rz.h" +#include +LOG_MODULE_REGISTER(rz_gpio, CONFIG_GPIO_LOG_LEVEL); + +#define LOG_DEV_ERR(dev, format, ...) LOG_ERR("%s:" #format, (dev)->name, ##__VA_ARGS__) +#define LOG_DEV_DBG(dev, format, ...) LOG_DBG("%s:" #format, (dev)->name, ##__VA_ARGS__) + +struct gpio_rz_config { + struct gpio_driver_config common; + uint8_t ngpios; + uint8_t port_num; + bsp_io_port_t fsp_port; + const ioport_cfg_t *fsp_cfg; + const ioport_api_t *fsp_api; + const struct device *int_dev; + uint8_t tint_num[GPIO_RZ_MAX_TINT_NUM]; +}; + +struct gpio_rz_data { + struct gpio_driver_data common; + sys_slist_t cb; + ioport_instance_ctrl_t *fsp_ctrl; + struct k_spinlock lock; +}; + +struct gpio_rz_tint_isr_data { + const struct device *gpio_dev; + gpio_pin_t pin; +}; + +struct gpio_rz_tint_data { + struct gpio_rz_tint_isr_data tint_data[GPIO_RZ_MAX_TINT_NUM]; + uint32_t irq_set_edge; +}; + +struct gpio_rz_tint_config { + void (*gpio_int_init)(void); +}; + +static int gpio_rz_pin_config_get_raw(bsp_io_port_pin_t port_pin, uint32_t *flags); + +#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_rz_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t *flags) +{ + const struct gpio_rz_config *config = dev->config; + bsp_io_port_pin_t port_pin = config->fsp_port | pin; + + gpio_rz_pin_config_get_raw(port_pin, flags); + return 0; +} +#endif + +/* Get previous pin's configuration, used by pin_configure/pin_interrupt_configure api */ +static int gpio_rz_pin_config_get_raw(bsp_io_port_pin_t port_pin, uint32_t *flags) +{ + bsp_io_port_t port = (port_pin >> 8U) & 0xFF; + gpio_pin_t pin = port_pin & 0xFF; + volatile uint8_t *p_p = GPIO_RZ_IOPORT_P_REG_BASE_GET; + volatile uint16_t *p_pm = GPIO_RZ_IOPORT_PM_REG_BASE_GET; + + uint8_t adr_offset; + uint8_t p_value; + uint16_t pm_value; + + adr_offset = (uint8_t)GPIO_RZ_REG_OFFSET(port, pin); + + p_p = &p_p[adr_offset]; + p_pm = &p_pm[adr_offset]; + + p_value = GPIO_RZ_P_VALUE_GET(*p_p, pin); + pm_value = GPIO_RZ_PM_VALUE_GET(*p_pm, pin); + + if (p_value) { + *flags |= GPIO_OUTPUT_INIT_HIGH; + } else { + *flags |= GPIO_OUTPUT_INIT_LOW; + } + + *flags |= ((pm_value << 16)); + return 0; +} + +static int gpio_rz_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_rz_config *config = dev->config; + struct gpio_rz_data *data = dev->data; + bsp_io_port_pin_t port_pin = config->fsp_port | pin; + uint32_t ioport_config_data = 0; + gpio_flags_t pre_flags; + fsp_err_t err; + + gpio_rz_pin_config_get_raw(port_pin, &pre_flags); + + if (!flags) { + /* Disconnect mode */ + ioport_config_data = 0; + } else if (!(flags & GPIO_OPEN_DRAIN)) { + /* PM register */ + ioport_config_data &= GPIO_RZ_PIN_CONFIGURE_INPUT_OUTPUT_RESET; + if (flags & GPIO_INPUT) { + if (flags & GPIO_OUTPUT) { + ioport_config_data |= IOPORT_CFG_PORT_DIRECTION_OUTPUT_INPUT; + } else { + ioport_config_data |= IOPORT_CFG_PORT_DIRECTION_INPUT; + } + } else if (flags & GPIO_OUTPUT) { + ioport_config_data &= GPIO_RZ_PIN_CONFIGURE_INPUT_OUTPUT_RESET; + ioport_config_data |= IOPORT_CFG_PORT_DIRECTION_OUTPUT; + } + /* P register */ + if (!(flags & (GPIO_OUTPUT_INIT_HIGH | GPIO_OUTPUT_INIT_LOW))) { + flags |= pre_flags & (GPIO_OUTPUT_INIT_HIGH | GPIO_OUTPUT_INIT_LOW); + } + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + ioport_config_data |= IOPORT_CFG_PORT_OUTPUT_HIGH; + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + ioport_config_data &= ~(IOPORT_CFG_PORT_OUTPUT_HIGH); + } + /* PUPD register */ + if (flags & GPIO_PULL_UP) { + ioport_config_data |= IOPORT_CFG_PULLUP_ENABLE; + } else if (flags & GPIO_PULL_DOWN) { + ioport_config_data |= IOPORT_CFG_PULLUP_ENABLE; + } + + /* ISEL register */ + if (flags & GPIO_INT_ENABLE) { + ioport_config_data |= GPIO_RZ_PIN_CONFIGURE_INT_ENABLE; + } else if (flags & GPIO_INT_DISABLE) { + ioport_config_data &= GPIO_RZ_PIN_CONFIGURE_INT_DISABLE; + } + + /* Drive Ability register */ + ioport_config_data |= GPIO_RZ_PIN_CONFIGURE_GET_DRIVE_ABILITY(flags); + + /* Filter register, see in renesas-rz-gpio-ioport.h */ + ioport_config_data |= GPIO_RZ_PIN_CONFIGURE_GET_FILTER(flags); + } else { + return -ENOTSUP; + } + + err = config->fsp_api->pinCfg(data->fsp_ctrl, port_pin, ioport_config_data); + if (err != FSP_SUCCESS) { + return -EIO; + } + return 0; +} + +static int gpio_rz_port_get_raw(const struct device *dev, gpio_port_value_t *value) +{ + const struct gpio_rz_config *config = dev->config; + struct gpio_rz_data *data = dev->data; + fsp_err_t err; + ioport_size_t port_value; + + err = config->fsp_api->portRead(data->fsp_ctrl, config->fsp_port, &port_value); + if (err != FSP_SUCCESS) { + return -EIO; + } + *value = (gpio_port_value_t)port_value; + return 0; +} + +static int gpio_rz_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct gpio_rz_config *config = dev->config; + struct gpio_rz_data *data = dev->data; + ioport_size_t port_mask = (ioport_size_t)mask; + ioport_size_t port_value = (ioport_size_t)value; + fsp_err_t err; + + err = config->fsp_api->portWrite(data->fsp_ctrl, config->fsp_port, port_value, port_mask); + if (err != FSP_SUCCESS) { + return -EIO; + } + return 0; +} + +static int gpio_rz_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_rz_config *config = dev->config; + struct gpio_rz_data *data = dev->data; + ioport_size_t mask = (ioport_size_t)pins; + ioport_size_t value = (ioport_size_t)pins; + fsp_err_t err; + + err = config->fsp_api->portWrite(data->fsp_ctrl, config->fsp_port, value, mask); + if (err != FSP_SUCCESS) { + return -EIO; + } + return 0; +} + +static int gpio_rz_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_rz_config *config = dev->config; + struct gpio_rz_data *data = dev->data; + ioport_size_t mask = (ioport_size_t)pins; + ioport_size_t value = 0x00; + fsp_err_t err; + + err = config->fsp_api->portWrite(data->fsp_ctrl, config->fsp_port, value, mask); + if (err != FSP_SUCCESS) { + return -EIO; + } + return 0; +} + +static int gpio_rz_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) +{ + const struct gpio_rz_config *config = dev->config; + struct gpio_rz_data *data = dev->data; + bsp_io_port_pin_t port_pin; + gpio_flags_t pre_flags; + ioport_size_t value = 0; + fsp_err_t err; + + for (uint8_t idx = 0; idx < config->ngpios; idx++) { + if (pins & (1U << idx)) { + port_pin = config->fsp_port | idx; + gpio_rz_pin_config_get_raw(port_pin, &pre_flags); + if (pre_flags & GPIO_OUTPUT_INIT_HIGH) { + value &= (1U << idx); + } else if (pre_flags & GPIO_OUTPUT_INIT_LOW) { + value |= (1U << idx); + } + } + } + err = config->fsp_api->portWrite(data->fsp_ctrl, config->fsp_port, value, + (ioport_size_t)pins); + if (err != FSP_SUCCESS) { + return -EIO; + } + return 0; +} + +#define GPIO_RZ_HAS_INTERRUPT DT_HAS_COMPAT_STATUS_OKAY(renesas_rz_gpio_int) + +#if GPIO_RZ_HAS_INTERRUPT +static int gpio_rz_int_disable(const struct device *dev, uint8_t tint_num) +{ + struct gpio_rz_tint_data *data = dev->data; + volatile uint32_t *tssr = &R_INTC_IM33->TSSR0; + volatile uint32_t *titsr = &R_INTC_IM33->TITSR0; + volatile uint32_t *tscr = &R_INTC_IM33->TSCR; + + /* Get register offset base on interrupt number. */ + tssr = &tssr[tint_num / 4]; + titsr = &titsr[tint_num / 16]; + + irq_disable(GPIO_RZ_TINT_IRQ_GET(tint_num)); + /* Disable interrupt and clear interrupt source. */ + *tssr &= ~(0xFF << GPIO_RZ_TSSR_OFFSET(tint_num)); + /* Reset interrupt dectect type to default. */ + *titsr &= ~(0x3 << GPIO_RZ_TITSR_OFFSET(tint_num)); + + /* Clear interrupt detection status. */ + if (data->irq_set_edge & BIT(tint_num)) { + *tscr &= ~BIT(tint_num); + data->irq_set_edge &= ~BIT(tint_num); + } + data->tint_data[tint_num].gpio_dev = NULL; + data->tint_data[tint_num].pin = UINT8_MAX; + + return 0; +} + +static int gpio_rz_int_enable(const struct device *int_dev, const struct device *gpio_dev, + uint8_t tint_num, uint8_t irq_type, gpio_pin_t pin) +{ + struct gpio_rz_tint_data *int_data = int_dev->data; + const struct gpio_rz_config *gpio_config = gpio_dev->config; + volatile uint32_t *tssr = &R_INTC_IM33->TSSR0; + volatile uint32_t *titsr = &R_INTC_IM33->TITSR0; + + tssr = &tssr[tint_num / 4]; + titsr = &titsr[tint_num / 16]; + /* Select interrupt detect type. */ + *titsr |= (irq_type << GPIO_RZ_TITSR_OFFSET(tint_num)); + /* Select interrupt source base on port and pin number.*/ + *tssr |= (GPIO_RZ_TSSR_VAL(gpio_config->port_num, pin)) << GPIO_RZ_TSSR_OFFSET(tint_num); + + if (irq_type == GPIO_RZ_TINT_EDGE_RISING || irq_type == GPIO_RZ_TINT_EDGE_FALLING) { + int_data->irq_set_edge |= BIT(tint_num); + /* Clear interrupt status. */ + R_INTC_IM33->TSCR &= ~BIT(tint_num); + } + int_data->tint_data[tint_num].gpio_dev = gpio_dev; + int_data->tint_data[tint_num].pin = pin; + irq_enable(GPIO_RZ_TINT_IRQ_GET(tint_num)); + + return 0; +} + +static int gpio_rz_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + const struct gpio_rz_config *config = dev->config; + struct gpio_rz_data *data = dev->data; + bsp_io_port_pin_t port_pin = config->fsp_port | pin; + uint8_t tint_num = config->tint_num[pin]; + uint8_t irq_type = 0; + gpio_flags_t pre_flags = 0; + k_spinlock_key_t key; + + if (tint_num >= GPIO_RZ_MAX_TINT_NUM) { + LOG_DEV_ERR(dev, "Invalid TINT interrupt:%d >= %d", tint_num, GPIO_RZ_MAX_TINT_NUM); + } + + if (pin > config->ngpios) { + return -EINVAL; + } + + if (trig == GPIO_INT_TRIG_BOTH) { + return -ENOTSUP; + } + + key = k_spin_lock(&data->lock); + + if (mode == GPIO_INT_MODE_DISABLED) { + gpio_rz_pin_config_get_raw(port_pin, &pre_flags); + pre_flags |= GPIO_INT_DISABLE; + gpio_rz_pin_configure(dev, pin, pre_flags); + gpio_rz_int_disable(config->int_dev, tint_num); + goto exit_unlock; + } + + if (mode == GPIO_INT_MODE_EDGE) { + irq_type = GPIO_RZ_TINT_EDGE_RISING; + if (trig == GPIO_INT_TRIG_LOW) { + irq_type = GPIO_RZ_TINT_EDGE_FALLING; + } + } else { + irq_type = GPIO_RZ_TINT_LEVEL_HIGH; + if (trig == GPIO_INT_TRIG_LOW) { + irq_type = GPIO_RZ_TINT_LEVEL_LOW; + } + } + + /* Set register ISEL */ + gpio_rz_pin_config_get_raw(port_pin, &pre_flags); + pre_flags |= GPIO_INT_ENABLE; + gpio_rz_pin_configure(dev, pin, pre_flags); + gpio_rz_int_enable(config->int_dev, dev, tint_num, irq_type, pin); + +exit_unlock: + k_spin_unlock(&data->lock, key); + return 0; +} + +static int gpio_rz_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + struct gpio_rz_data *data = dev->data; + + return gpio_manage_callback(&data->cb, callback, set); +} + +static void gpio_rz_isr(const struct device *dev, uint8_t pin) +{ + struct gpio_rz_data *data = dev->data; + + gpio_fire_callbacks(&data->cb, dev, BIT(pin)); +} + +static void gpio_rz_tint_isr(uint16_t irq, const struct device *dev) +{ + struct gpio_rz_tint_data *data = dev->data; + volatile uint32_t *tscr = &R_INTC_IM33->TSCR; + uint8_t tint_num; + + tint_num = irq - GPIO_RZ_TINT_IRQ_OFFSET; + + if (!(*tscr & BIT(tint_num))) { + LOG_DEV_DBG(dev, "tint:%u spurious irq, status 0", tint_num); + return; + } + + if (data->irq_set_edge & BIT(tint_num)) { + *tscr &= ~BIT(tint_num); + } + + gpio_rz_isr(data->tint_data[tint_num].gpio_dev, data->tint_data[tint_num].pin); +} + +static int gpio_rz_int_init(const struct device *dev) +{ + const struct gpio_rz_tint_config *config = dev->config; + + config->gpio_int_init(); + return 0; +} +#endif + +static DEVICE_API(gpio, gpio_rz_driver_api) = { + .pin_configure = gpio_rz_pin_configure, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_rz_pin_get_config, +#endif + .port_get_raw = gpio_rz_port_get_raw, + .port_set_masked_raw = gpio_rz_port_set_masked_raw, + .port_set_bits_raw = gpio_rz_port_set_bits_raw, + .port_clear_bits_raw = gpio_rz_port_clear_bits_raw, + .port_toggle_bits = gpio_rz_port_toggle_bits, +#if GPIO_RZ_HAS_INTERRUPT + .pin_interrupt_configure = gpio_rz_pin_interrupt_configure, + .manage_callback = gpio_rz_manage_callback, +#endif +}; + +/*Initialize GPIO interrupt device*/ +#define GPIO_RZ_TINT_ISR_DECLARE(irq_num, node_id) \ + static void rz_gpio_isr_##irq_num(void *param) \ + { \ + gpio_rz_tint_isr(DT_IRQ_BY_IDX(node_id, irq_num, irq), param); \ + } + +#define GPIO_RZ_TINT_ISR_INIT(node_id, irq_num) LISTIFY(irq_num, \ + GPIO_RZ_TINT_ISR_DECLARE, (), node_id) + +#define GPIO_RZ_TINT_CONNECT(irq_num, node_id) \ + IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, irq_num, irq), \ + DT_IRQ_BY_IDX(node_id, irq_num, priority), rz_gpio_isr_##irq_num, \ + DEVICE_DT_GET(node_id), 0); + +#define GPIO_RZ_TINT_CONNECT_FUNC(node_id) \ + static void rz_gpio_tint_connect_func##node_id(void) \ + { \ + LISTIFY(DT_NUM_IRQS(node_id), \ + GPIO_RZ_TINT_CONNECT, (;), \ + node_id) \ + } +/* Initialize GPIO device*/ +#define GPIO_RZ_INT_INIT(node_id) \ + GPIO_RZ_TINT_ISR_INIT(node_id, DT_NUM_IRQS(node_id)) \ + GPIO_RZ_TINT_CONNECT_FUNC(node_id) \ + static const struct gpio_rz_tint_config rz_gpio_tint_cfg_##node_id = { \ + .gpio_int_init = rz_gpio_tint_connect_func##node_id, \ + }; \ + static struct gpio_rz_tint_data rz_gpio_tint_data_##node_id = {}; \ + DEVICE_DT_DEFINE(node_id, gpio_rz_int_init, NULL, &rz_gpio_tint_data_##node_id, \ + &rz_gpio_tint_cfg_##node_id, POST_KERNEL, \ + UTIL_DEC(CONFIG_GPIO_INIT_PRIORITY), NULL); + +DT_FOREACH_STATUS_OKAY(renesas_rz_gpio_int, GPIO_RZ_INT_INIT) + +#define VALUE_2X(i, _) UTIL_X2(i) +#define PIN_IRQ_GET(idx, inst) \ + COND_CODE_1(DT_INST_PROP_HAS_IDX(inst, irqs, idx), \ + ([DT_INST_PROP_BY_IDX(inst, irqs, idx)] = \ + DT_INST_PROP_BY_IDX(inst, irqs, UTIL_INC(idx)),), \ + ()) + +#define PIN_IRQS_GET(inst) \ + FOR_EACH_FIXED_ARG(PIN_IRQ_GET, (), inst, \ + LISTIFY(DT_INST_PROP_LEN_OR(inst, irqs, 0), VALUE_2X, (,))) + +#define RZG_GPIO_PORT_INIT(inst) \ + static ioport_cfg_t g_ioport_##inst##_cfg = { \ + .number_of_pins = 0, \ + .p_pin_cfg_data = NULL, \ + .p_extend = NULL, \ + }; \ + static const struct gpio_rz_config gpio_rz_##inst##_config = { \ + .common = \ + { \ + .port_pin_mask = \ + (gpio_port_pins_t)GPIO_PORT_PIN_MASK_FROM_DT_INST(inst), \ + }, \ + .fsp_port = (uint32_t)DT_INST_REG_ADDR(inst), \ + .port_num = (uint8_t)DT_NODE_CHILD_IDX(DT_DRV_INST(inst)), \ + .ngpios = (uint8_t)DT_INST_PROP(inst, ngpios), \ + .fsp_cfg = &g_ioport_##inst##_cfg, \ + .fsp_api = &g_ioport_on_ioport, \ + .int_dev = DEVICE_DT_GET_OR_NULL(DT_INST(0, renesas_rz_gpio_int)), \ + .tint_num = {PIN_IRQS_GET(inst)}, \ + }; \ + static ioport_instance_ctrl_t g_ioport_##inst##_ctrl; \ + static struct gpio_rz_data gpio_rz_##inst##_data = { \ + .fsp_ctrl = &g_ioport_##inst##_ctrl, \ + }; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &gpio_rz_##inst##_data, &gpio_rz_##inst##_config, \ + POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, &gpio_rz_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RZG_GPIO_PORT_INIT) diff --git a/drivers/gpio/gpio_renesas_rz.h b/drivers/gpio/gpio_renesas_rz.h new file mode 100644 index 0000000000000..6980450f40c9a --- /dev/null +++ b/drivers/gpio/gpio_renesas_rz.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_GPIO_RENESAS_RZ_H_ +#define ZEPHYR_DRIVERS_GPIO_RENESAS_RZ_H_ + +#include +#include "r_ioport.h" + +#define GPIO_RZ_IOPORT_P_REG_BASE_GET (&R_GPIO->P_20) +#define GPIO_RZ_IOPORT_PM_REG_BASE_GET (&R_GPIO->PM_20) + +#define GPIO_RZ_REG_OFFSET(port, pin) (port + (pin / 4)) + +#define GPIO_RZ_P_VALUE_GET(value, pin) ((value >> pin) & 1U) +#define GPIO_RZ_PM_VALUE_GET(value, pin) ((value >> (pin * 2)) & 3U) + +#define GPIO_RZ_MAX_PORT_NUM 19 +#define GPIO_RZ_MAX_TINT_NUM 32 + +#define GPIO_RZ_TINT_IRQ_OFFSET 429 +#define GPIO_RZ_TINT_IRQ_GET(tint_num) (tint_num + GPIO_RZ_TINT_IRQ_OFFSET) + +#define GPIO_RZ_TINT_EDGE_RISING 0x0 +#define GPIO_RZ_TINT_EDGE_FALLING 0x1 +#define GPIO_RZ_TINT_LEVEL_HIGH 0x2 +#define GPIO_RZ_TINT_LEVEL_LOW 0x3 + +#define GPIO_RZ_TSSR_VAL(port, pin) (0x80 | (gpio_rz_int[port] + pin)) +#define GPIO_RZ_TSSR_OFFSET(irq) ((irq % 4) * 8) +#define GPIO_RZ_TITSR_OFFSET(irq) ((irq % 16) * 2) + +#define GPIO_RZ_PIN_CONFIGURE_GET_FILTER(flag) (((flags >> RZG3S_GPIO_FILTER_SHIFT) & 0x1F) << 19U) +#define GPIO_RZ_PIN_CONFIGURE_GET_DRIVE_ABILITY(flag) \ + (((flag >> RZG3S_GPIO_IOLH_SHIFT) & 0x3) << 10U) + +#define GPIO_RZ_PIN_CONFIGURE_INT_ENABLE IOPORT_CFG_TINT_ENABLE +#define GPIO_RZ_PIN_CONFIGURE_INT_DISABLE (~(IOPORT_CFG_TINT_ENABLE)) +#define GPIO_RZ_PIN_CONFIGURE_INPUT_OUTPUT_RESET (~(0x3 << 2)) + +static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = {0, 4, 9, 13, 17, 23, 28, 33, 38, 43, + 47, 52, 56, 58, 63, 66, 70, 72, 76}; +#endif /* ZEPHYR_DRIVERS_GPIO_RENESAS_RZ_H_ */ diff --git a/drivers/gpio/gpio_rp1.c b/drivers/gpio/gpio_rp1.c new file mode 100644 index 0000000000000..3f77c54725f7e --- /dev/null +++ b/drivers/gpio/gpio_rp1.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2024 Junho Lee + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT raspberrypi_rp1_gpio + +#include +#include +#include +#include +#include + +#define GPIO_STATUS(base, n) (base + 0x8 * n) +#define GPIO_CTRL(base, n) (GPIO_STATUS(base, n) + 0x4) + +#define GPIO_STATUS_OUT_TO_PAD 0x200 +#define GPIO_STATUS_OUT_FROM_PERI 0x100 + +#define GPIO_CTRL_OUTOVER_MASK 0x3000 +#define GPIO_CTRL_OUTOVER_PERI 0x0 + +#define GPIO_CTRL_OEOVER_MASK 0xc000 +#define GPIO_CTRL_OEOVER_PERI 0x0 + +#define GPIO_CTRL_FUNCSEL_MASK 0x001f +#define GPIO_CTRL_FUNCSEL_RIO 0x5 + +#define RIO_OUT(base) (base) +#define RIO_OE(base) (base + 0x4) +#define RIO_IN(base) (base + 0x8) + +#define RIO_SET 0x2000 +#define RIO_CLR 0x3000 + +#define RIO_OUT_SET(base) (RIO_OUT(base) + RIO_SET) +#define RIO_OUT_CLR(base) (RIO_OUT(base) + RIO_CLR) + +#define RIO_OE_SET(base) (RIO_OE(base) + RIO_SET) +#define RIO_OE_CLR(base) (RIO_OE(base) + RIO_CLR) + +#define PADS_CTRL(base, n) (base + 0x4 * (n + 1)) + +#define PADS_OUTPUT_DISABLE 0x80 +#define PADS_INPUT_ENABLE 0x40 + +#define PADS_PULL_UP_ENABLE 0x8 +#define PADS_PULL_DOWN_ENABLE 0x4 + +#define DEV_CFG(dev) ((const struct gpio_rp1_config *)(dev)->config) +#define DEV_DATA(dev) ((struct gpio_rp1_data *)(dev)->data) + +struct gpio_rp1_config { + struct gpio_driver_config common; + + DEVICE_MMIO_NAMED_ROM(reg_base); + mem_addr_t gpio_offset; + mem_addr_t rio_offset; + mem_addr_t pads_offset; + + uint8_t ngpios; +}; + +struct gpio_rp1_data { + struct gpio_driver_data common; + + DEVICE_MMIO_NAMED_RAM(reg_base); + mem_addr_t gpio_base; + mem_addr_t rio_base; + mem_addr_t pads_base; +}; + +static int gpio_rp1_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) +{ + struct gpio_rp1_data *data = port->data; + + if (flags & GPIO_SINGLE_ENDED) { + return -ENOTSUP; + } + + /* Let RIO handle the input/output of GPIO */ + sys_clear_bits(GPIO_CTRL(data->gpio_base, pin), GPIO_CTRL_OEOVER_MASK); + sys_set_bits(GPIO_CTRL(data->gpio_base, pin), GPIO_CTRL_OEOVER_PERI); + + sys_clear_bits(GPIO_CTRL(data->gpio_base, pin), GPIO_CTRL_OUTOVER_MASK); + sys_set_bits(GPIO_CTRL(data->gpio_base, pin), GPIO_CTRL_OUTOVER_PERI); + + sys_clear_bits(GPIO_CTRL(data->gpio_base, pin), GPIO_CTRL_FUNCSEL_MASK); + sys_set_bits(GPIO_CTRL(data->gpio_base, pin), GPIO_CTRL_FUNCSEL_RIO); + + /* Set the direction */ + if (flags & GPIO_OUTPUT) { + sys_set_bit(RIO_OE_SET(data->rio_base), pin); + sys_clear_bits(PADS_CTRL(data->pads_base, pin), + PADS_OUTPUT_DISABLE | PADS_INPUT_ENABLE); + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + sys_set_bit(RIO_OUT_SET(data->rio_base), pin); + sys_clear_bit(RIO_OUT_CLR(data->rio_base), pin); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + sys_set_bit(RIO_OUT_CLR(data->rio_base), pin); + sys_clear_bit(RIO_OUT_SET(data->rio_base), pin); + } + } else if (flags & GPIO_INPUT) { + sys_set_bit(RIO_OE_CLR(data->rio_base), pin); + sys_set_bits(PADS_CTRL(data->pads_base, pin), + PADS_OUTPUT_DISABLE | PADS_INPUT_ENABLE); + } + + /* Set pull up/down */ + sys_clear_bits(PADS_CTRL(data->pads_base, pin), + PADS_PULL_UP_ENABLE | PADS_PULL_DOWN_ENABLE); + + if (flags & GPIO_PULL_UP) { + sys_set_bits(PADS_CTRL(data->pads_base, pin), PADS_PULL_UP_ENABLE); + } else if (flags & GPIO_PULL_DOWN) { + sys_set_bits(PADS_CTRL(data->pads_base, pin), PADS_PULL_DOWN_ENABLE); + } + + return 0; +} + +static int gpio_rp1_port_get_raw(const struct device *port, gpio_port_value_t *value) +{ + struct gpio_rp1_data *data = port->data; + + *value = sys_read32(RIO_IN(data->rio_base)); + + return 0; +} + +static int gpio_rp1_port_set_masked_raw(const struct device *port, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + struct gpio_rp1_data *data = port->data; + + sys_clear_bits(RIO_OUT_SET(data->rio_base), mask); + sys_set_bits(RIO_OUT_CLR(data->rio_base), mask); + + sys_clear_bits(RIO_OUT_CLR(data->rio_base), (value & mask)); + sys_set_bits(RIO_OUT_SET(data->rio_base), (value & mask)); + + return 0; +} + +static int gpio_rp1_port_set_bits_raw(const struct device *port, gpio_port_pins_t pins) +{ + struct gpio_rp1_data *data = port->data; + + sys_clear_bits(RIO_OUT_CLR(data->rio_base), pins); + sys_set_bits(RIO_OUT_SET(data->rio_base), pins); + + return 0; +} + +static int gpio_rp1_port_clear_bits_raw(const struct device *port, gpio_port_pins_t pins) +{ + struct gpio_rp1_data *data = port->data; + + sys_clear_bits(RIO_OUT_SET(data->rio_base), pins); + sys_set_bits(RIO_OUT_CLR(data->rio_base), pins); + + return 0; +} + +static int gpio_rp1_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) +{ + struct gpio_rp1_data *data = port->data; + uint32_t val; + + val = sys_read32(RIO_OUT(data->rio_base)); + + /* Low to high */ + sys_set_bits(RIO_OUT_SET(data->rio_base), val ^ pins); + sys_clear_bits(RIO_OUT_CLR(data->rio_base), val ^ pins); + + /* High to low */ + sys_set_bits(RIO_OUT_CLR(data->rio_base), val & pins); + sys_clear_bits(RIO_OUT_SET(data->rio_base), val & pins); + + return 0; +} + +static DEVICE_API(gpio, gpio_rp1_api) = { + .pin_configure = gpio_rp1_pin_configure, + .port_get_raw = gpio_rp1_port_get_raw, + .port_set_masked_raw = gpio_rp1_port_set_masked_raw, + .port_set_bits_raw = gpio_rp1_port_set_bits_raw, + .port_clear_bits_raw = gpio_rp1_port_clear_bits_raw, + .port_toggle_bits = gpio_rp1_port_toggle_bits, +}; + +static int gpio_rp1_init(const struct device *port) +{ + const struct gpio_rp1_config *config = port->config; + struct gpio_rp1_data *data = port->data; + + DEVICE_MMIO_NAMED_MAP(port, reg_base, K_MEM_CACHE_NONE); + data->gpio_base = DEVICE_MMIO_NAMED_GET(port, reg_base) + config->gpio_offset; + data->rio_base = DEVICE_MMIO_NAMED_GET(port, reg_base) + config->rio_offset; + data->pads_base = DEVICE_MMIO_NAMED_GET(port, reg_base) + config->pads_offset; + + return 0; +} + +#define GPIO_RP1_INIT(n) \ + static struct gpio_rp1_data gpio_rp1_data_##n; \ + \ + static const struct gpio_rp1_config gpio_rp1_cfg_##n = { \ + .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0)}, \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_INST_PARENT(n)), \ + .gpio_offset = DT_INST_REG_ADDR_BY_IDX(n, 0), \ + .rio_offset = DT_INST_REG_ADDR_BY_IDX(n, 1), \ + .pads_offset = DT_INST_REG_ADDR_BY_IDX(n, 2), \ + .ngpios = DT_INST_PROP(n, ngpios), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, gpio_rp1_init, NULL, &gpio_rp1_data_##n, &gpio_rp1_cfg_##n, \ + POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, &gpio_rp1_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_RP1_INIT) diff --git a/drivers/gpio/gpio_rpi_pico.c b/drivers/gpio/gpio_rpi_pico.c index 8b3d18e8717ab..2e2e592eee82f 100644 --- a/drivers/gpio/gpio_rpi_pico.c +++ b/drivers/gpio/gpio_rpi_pico.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Yonatan Schachter + * Copyright (c) 2025, Andrew Featherstone * * SPDX-License-Identifier: Apache-2.0 */ @@ -39,6 +40,17 @@ static int gpio_rpi_configure(const struct device *dev, { struct gpio_rpi_data *data = dev->data; + if (flags == GPIO_DISCONNECTED) { + gpio_disable_pulls(pin); + /* This is almost the opposite of the Pico SDK's gpio_set_function. */ + hw_write_masked(&pads_bank0_hw->io[pin], PADS_BANK0_GPIO0_OD_BITS, + PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS); +#ifdef SOC_SERIES_RP2350 + hw_set_bits(&pads_bank0_hw->io[gpio], PADS_BANK0_GPIO0_ISO_BITS); +#endif + return 0; + } + gpio_set_pulls(pin, (flags & GPIO_PULL_UP) != 0U, (flags & GPIO_PULL_DOWN) != 0U); @@ -46,6 +58,12 @@ static int gpio_rpi_configure(const struct device *dev, /* Avoid gpio_init, since that also clears previously set direction/high/low */ gpio_set_function(pin, GPIO_FUNC_SIO); + if (flags & GPIO_INPUT) { + gpio_set_dir(pin, GPIO_IN); + } else { + gpio_set_input_enabled(pin, false); + } + if (flags & GPIO_OUTPUT) { if (flags & GPIO_SINGLE_ENDED) { data->single_ended_mask |= BIT(pin); @@ -73,13 +91,42 @@ static int gpio_rpi_configure(const struct device *dev, } gpio_set_dir(pin, GPIO_OUT); } - } else if (flags & GPIO_INPUT) { - gpio_set_dir(pin, GPIO_IN); } return 0; } +#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_rpi_get_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t *flags) +{ + struct gpio_rpi_data *data = dev->data; + + *flags = 0; + + /* RP2xxxx supports Bus Keeper mode where both pull-up and pull-down are enabled. */ + if (gpio_is_pulled_up(pin)) { + *flags |= GPIO_PULL_UP; + } + if (gpio_is_pulled_down(pin)) { + *flags |= GPIO_PULL_DOWN; + } + + if (gpio_get_dir(pin)) { + *flags |= gpio_get_out_level(pin) ? GPIO_OUTPUT_HIGH : GPIO_OUTPUT_LOW; + if (data->single_ended_mask & BIT(pin)) { + *flags |= + data->open_drain_mask & BIT(pin) ? GPIO_OPEN_DRAIN : GPIO_PUSH_PULL; + } + } + + if (pads_bank0_hw->io[pin] & PADS_BANK0_GPIO0_IE_BITS) { + *flags |= GPIO_INPUT; + } + + return 0; +} +#endif + static int gpio_rpi_port_get_raw(const struct device *dev, uint32_t *value) { *value = gpio_get_all(); @@ -178,8 +225,50 @@ static int gpio_rpi_manage_callback(const struct device *dev, return gpio_manage_callback(&data->callbacks, callback, set); } +static uint32_t gpio_rpi_get_pending_int(const struct device *dev) +{ + io_bank0_irq_ctrl_hw_t *irq_ctrl_base = + get_core_num() ? &io_bank0_hw->proc1_irq_ctrl : &io_bank0_hw->proc0_irq_ctrl; + ARRAY_FOR_EACH_PTR(irq_ctrl_base->ints, p) { + if (*p) { + return 1; + } + } + + return 0; +} + +#ifdef CONFIG_GPIO_GET_DIRECTION +static int gpio_rpi_port_get_direction(const struct device *port, gpio_port_pins_t map, + gpio_port_pins_t *inputs, gpio_port_pins_t *outputs) +{ + /* The Zephyr API considers a disconnected pin to be neither an input nor output. + * Since we disable both OE and IE for disconnected pins clear the mask bits. + */ + for (int pin = 0; pin < NUM_BANK0_GPIOS; pin++) { + if (pads_bank0_hw->io[pin] & PADS_BANK0_GPIO0_OD_BITS) { + map &= ~BIT(pin); + } + if (inputs && (pads_bank0_hw->io[pin] & PADS_BANK0_GPIO0_IE_BITS)) { + *inputs |= BIT(pin); + } + } + if (inputs) { + *inputs &= map; + } + if (outputs) { + *outputs = sio_hw->gpio_oe & map; + } + + return 0; +} +#endif + static DEVICE_API(gpio, gpio_rpi_driver_api) = { .pin_configure = gpio_rpi_configure, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_rpi_get_config, +#endif .port_get_raw = gpio_rpi_port_get_raw, .port_set_masked_raw = gpio_rpi_port_set_masked_raw, .port_set_bits_raw = gpio_rpi_port_set_bits_raw, @@ -187,6 +276,10 @@ static DEVICE_API(gpio, gpio_rpi_driver_api) = { .port_toggle_bits = gpio_rpi_port_toggle_bits, .pin_interrupt_configure = gpio_rpi_pin_interrupt_configure, .manage_callback = gpio_rpi_manage_callback, + .get_pending_int = gpio_rpi_get_pending_int, +#ifdef CONFIG_GPIO_GET_DIRECTION + .port_get_direction = gpio_rpi_port_get_direction, +#endif }; static void gpio_rpi_isr(const struct device *dev) diff --git a/drivers/gpio/gpio_rts5912.c b/drivers/gpio/gpio_rts5912.c new file mode 100644 index 0000000000000..bda68ae39a54d --- /dev/null +++ b/drivers/gpio/gpio_rts5912.c @@ -0,0 +1,457 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#define DT_DRV_COMPAT realtek_rts5912_gpio + +#include +#include +#include +#include +#include +#include "zephyr/drivers/gpio/gpio_utils.h" +#include +#include + +#include + +LOG_MODULE_REGISTER(gpio_rts5912, CONFIG_GPIO_LOG_LEVEL); + +#define RTS5912_GPIOA_REG_BASE ((GPIO_Type *)(DT_REG_ADDR(DT_NODELABEL(gpioa)))) + +struct gpio_rts5912_config { + struct gpio_driver_config common; + volatile uint32_t *reg_base; + uint8_t num_pins; +}; + +struct gpio_rts5912_data { + struct gpio_driver_data common; + sys_slist_t callbacks; +}; + +static int pin_is_valid(const struct gpio_rts5912_config *config, gpio_pin_t pin) +{ + if (pin >= config->num_pins) { + return -EINVAL; + } + + return 0; +} + +static int pin_output_high(const struct device *port, gpio_pin_t pin) +{ + const struct gpio_rts5912_config *config = port->config; + volatile uint32_t *gcr = &config->reg_base[pin]; + + int err = pin_is_valid(config, pin); + + if (err) { + return err; + } + + if (*gcr & GPIO_GCR_OUTMD_Msk) { + /* Switch I/O mode to input mode when configuration is open-drain with output high + */ + *gcr = (*gcr & ~GPIO_GCR_DIR_Msk) | GPIO_GCR_OUTCTRL_Msk; + } else { + *gcr |= GPIO_GCR_OUTCTRL_Msk | GPIO_GCR_DIR_Msk; + } + + return 0; +} + +static int pin_output_low(const struct device *port, gpio_pin_t pin) +{ + const struct gpio_rts5912_config *config = port->config; + volatile uint32_t *gcr = &config->reg_base[pin]; + + int err = pin_is_valid(config, pin); + + if (err) { + return err; + } + + *gcr = (*gcr & ~GPIO_GCR_OUTCTRL_Msk) | GPIO_GCR_DIR_Msk; + + return 0; +} + +static int gpio_rts5912_configuration(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_rts5912_config *config = port->config; + volatile uint32_t *gcr = &config->reg_base[pin]; + uint32_t cfg_val = *gcr; + + int err = pin_is_valid(config, pin); + + if (err) { + return err; + } + + if (flags & GPIO_INPUT) { + cfg_val &= ~GPIO_GCR_DIR_Msk; + cfg_val &= ~GPIO_GCR_OUTCTRL_Msk; + cfg_val |= GPIO_GCR_INDETEN_Msk; + } + + if (flags & GPIO_OPEN_DRAIN) { + cfg_val |= GPIO_GCR_OUTMD_Msk; + } else { + cfg_val &= ~GPIO_GCR_OUTMD_Msk; + } + + switch (flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) { + case GPIO_PULL_UP: + cfg_val &= ~GPIO_GCR_PULLDWEN_Msk; + cfg_val |= GPIO_GCR_PULLUPEN_Msk; + break; + case GPIO_PULL_DOWN: + cfg_val &= ~GPIO_GCR_PULLUPEN_Msk; + cfg_val |= GPIO_GCR_PULLDWEN_Msk; + break; + default: + break; + } + + switch (flags & RTS5912_GPIO_VOLTAGE_MASK) { + case RTS5912_GPIO_VOLTAGE_1V8: + cfg_val |= GPIO_GCR_INVOLMD_Msk; + break; + case RTS5912_GPIO_VOLTAGE_DEFAULT: + case RTS5912_GPIO_VOLTAGE_3V3: + cfg_val &= ~GPIO_GCR_INVOLMD_Msk; + break; + case RTS5912_GPIO_VOLTAGE_5V0: + return -ENOTSUP; + default: + break; + } + + *gcr = cfg_val; + + if (flags & GPIO_OUTPUT) { + if (flags & GPIO_OUTPUT_INIT_HIGH) { + pin_output_high(port, pin); + } else { + pin_output_low(port, pin); + } + } + + return 0; +} + +#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_rts5912_get_configuration(const struct device *port, gpio_pin_t pin, + gpio_flags_t *flags) +{ + const struct gpio_rts5912_config *config = port->config; + volatile uint32_t *gcr = &config->reg_base[pin]; + gpio_flags_t cfg_flag = 0x0UL; + + int err = pin_is_valid(config, pin); + + if (err) { + return err; + } + + if (*gcr & GPIO_GCR_OUTCTRL_Msk) { + cfg_flag |= GPIO_OUTPUT | GPIO_OUTPUT_INIT_HIGH; + } else { + if (*gcr & GPIO_GCR_DIR_Msk) { + cfg_flag |= GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW; + } else { + cfg_flag |= GPIO_INPUT; + if (*gcr & GPIO_GCR_INVOLMD_Msk) { + cfg_flag |= RTS5912_GPIO_VOLTAGE_1V8; + } else { + cfg_flag |= RTS5912_GPIO_VOLTAGE_3V3; + } + } + } + + if (*gcr & GPIO_GCR_OUTMD_Msk) { + cfg_flag |= GPIO_OPEN_DRAIN; + } + + if (*gcr & GPIO_GCR_PULLUPEN_Msk) { + cfg_flag |= GPIO_PULL_UP; + } else if (*gcr & GPIO_GCR_PULLDWEN_Msk) { + cfg_flag |= GPIO_PULL_DOWN; + } + + *flags = cfg_flag; + + return 0; +} +#endif + +static int gpio_rts5912_port_get_raw(const struct device *port, gpio_port_value_t *value) +{ + const struct gpio_rts5912_config *config = port->config; + gpio_port_value_t ret_val = 0; + uint16_t mask = 0x1U; + + for (gpio_pin_t i = 0; i < config->num_pins; i++) { + if (config->reg_base[i] & GPIO_GCR_PINSTS_Msk) { + ret_val |= (gpio_port_value_t)mask; + } + mask <<= 1; + } + + *value = ret_val; + + return 0; +} + +static int gpio_rts5912_port_set_masked_raw(const struct device *port, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct gpio_rts5912_config *config = port->config; + uint32_t pin; + + mask &= 0x0000FFFF; + for (; mask; mask &= ~BIT(pin)) { + pin = find_lsb_set(mask) - 1; + if (pin >= config->num_pins) { + break; + } + + if (value & BIT(pin)) { + pin_output_high(port, pin); + } else { + pin_output_low(port, pin); + } + } + + return 0; +} + +static int gpio_rts5912_port_set_bits_raw(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_rts5912_config *config = port->config; + volatile uint32_t *gcr = config->reg_base; + uint32_t pin = 0; + + pins &= 0x0000FFFF; + gpio_port_pins_t sel_pin = 1; + + for (; pins;) { + if (pins & sel_pin) { + pin_output_high(port, pin); + } + pins &= ~sel_pin; + sel_pin <<= 1; + gcr++; + pin++; + } + + return 0; +} + +static int gpio_rts5912_port_clear_bits_raw(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_rts5912_config *config = port->config; + volatile uint32_t *gcr = config->reg_base; + uint32_t pin = 0; + + pins &= 0x0000FFFF; + gpio_port_pins_t sel_pin = 1; + + for (; pins;) { + if (pins & sel_pin) { + pin_output_low(port, pin); + } + pins &= ~sel_pin; + sel_pin <<= 1; + gcr++; + pin++; + } + + return 0; +} + +static int gpio_rts5912_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_rts5912_config *config = port->config; + volatile uint32_t *gcr = config->reg_base; + uint32_t pin = 0; + + pins &= 0x0000FFFF; + gpio_port_pins_t sel_pin = 0x1UL; + + for (; pins;) { + if (pins & sel_pin) { + if (*gcr & GPIO_GCR_OUTCTRL_Msk) { + pin_output_low(port, pin); + } else { + pin_output_high(port, pin); + } + } + + pins &= ~sel_pin; + sel_pin <<= 1; + gcr++; + pin++; + } + + return 0; +} + +static gpio_pin_t gpio_rts5912_get_intr_pin(volatile uint32_t *reg_base) +{ + gpio_pin_t pin = 0U; + + for (; pin < 16; pin++) { + if (reg_base[pin] & GPIO_GCR_INTSTS_Msk) { + break; + } + } + + return pin; +} + +static void gpio_rts5912_isr(const void *arg) +{ + const struct device *port = arg; + const struct gpio_rts5912_config *config = port->config; + struct gpio_rts5912_data *data = port->data; + volatile uint32_t *gcr = config->reg_base; + unsigned int key = irq_lock(); + gpio_pin_t pin = gpio_rts5912_get_intr_pin(gcr); + + if (gcr[pin] & GPIO_GCR_INTSTS_Msk) { + gcr[pin] |= GPIO_GCR_INTSTS_Msk; + + gpio_fire_callbacks(&data->callbacks, port, BIT(pin)); + } + irq_unlock(key); +} + +static int gpio_rts5912_intr_config(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + const struct gpio_rts5912_config *config = port->config; + volatile uint32_t *gcr = &config->reg_base[pin]; + uint32_t cfg_val = *gcr; + uint32_t pin_index = + DT_IRQ_BY_IDX(DT_NODELABEL(gpioa), 0, irq) + + ((uint32_t)(&config->reg_base[pin]) - (uint32_t)(RTS5912_GPIOA_REG_BASE)) / 4; + + int err = pin_is_valid(config, pin); + + if (err) { + return err; + } + + switch (mode) { + case GPIO_INT_MODE_DISABLED: + cfg_val &= ~GPIO_GCR_INTEN_Msk; + irq_disable(pin_index); + *gcr = cfg_val; + return 0; + case GPIO_INT_MODE_LEVEL: + switch (trig) { + case GPIO_INT_TRIG_LOW: + cfg_val &= ~GPIO_GCR_INTCTRL_Msk; + cfg_val |= 0x03UL << GPIO_GCR_INTCTRL_Pos; + break; + case GPIO_INT_TRIG_HIGH: + cfg_val &= ~GPIO_GCR_INTCTRL_Msk; + cfg_val |= 0x04UL << GPIO_GCR_INTCTRL_Pos; + break; + default: + return -EINVAL; + } + break; + case GPIO_INT_MODE_EDGE: + switch (trig) { + case GPIO_INT_TRIG_LOW: + cfg_val &= ~GPIO_GCR_INTCTRL_Msk; + cfg_val |= 0x01UL << GPIO_GCR_INTCTRL_Pos; + break; + case GPIO_INT_TRIG_HIGH: + cfg_val &= ~GPIO_GCR_INTCTRL_Msk; + cfg_val |= 0x00UL << GPIO_GCR_INTCTRL_Pos; + break; + case GPIO_INT_TRIG_BOTH: + cfg_val &= ~GPIO_GCR_INTCTRL_Msk; + cfg_val |= 0x2UL << GPIO_GCR_INTCTRL_Pos; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + cfg_val |= GPIO_GCR_INTEN_Msk; + *gcr = cfg_val; + + irq_enable(pin_index); + + return 0; +} + +static int gpio_rts5912_manage_cb(const struct device *port, struct gpio_callback *cb, bool set) +{ + struct gpio_rts5912_data *data = port->data; + + return gpio_manage_callback(&data->callbacks, cb, set); +} + +static DEVICE_API(gpio, gpio_rts5912_driver_api) = { + .pin_configure = gpio_rts5912_configuration, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_rts5912_get_configuration, +#endif + .port_get_raw = gpio_rts5912_port_get_raw, + .port_set_masked_raw = gpio_rts5912_port_set_masked_raw, + .port_set_bits_raw = gpio_rts5912_port_set_bits_raw, + .port_clear_bits_raw = gpio_rts5912_port_clear_bits_raw, + .port_toggle_bits = gpio_rts5912_port_toggle_bits, + .pin_interrupt_configure = gpio_rts5912_intr_config, + .manage_callback = gpio_rts5912_manage_cb, +}; + +#ifdef CONFIG_GEN_ISR_TABLES +#define RTS5912_GPIO_DTNAMIC_IRQ(id) \ + for (int i = 0; i < 16 && (DT_INST_IRQ_BY_IDX(id, 0, irq) + i) < 132; i++) { \ + irq_connect_dynamic((DT_INST_IRQ_BY_IDX(id, 0, irq) + i), \ + DT_INST_IRQ(id, priority), gpio_rts5912_isr, \ + DEVICE_DT_INST_GET(id), 0U); \ + } +#else +#define RTS5912_GPIO_DTNAMIC_IRQ(id) \ + IRQ_CONNECT(DT_INST_IRQN(id), DT_INST_IRQ(id, priority), gpio_rts5912_isr, \ + DEVICE_DT_INST_GET(id), 0U); +#endif + +#define GPIO_RTS5912_INIT(id) \ + static int gpio_rts5912_init_##id(const struct device *dev) \ + { \ + if (!(DT_INST_IRQ_HAS_CELL(id, irq))) { \ + return 0; \ + } \ + \ + RTS5912_GPIO_DTNAMIC_IRQ(id) \ + \ + return 0; \ + } \ + \ + static struct gpio_rts5912_data gpio_rts5912_data_##id; \ + \ + static const struct gpio_rts5912_config gpio_rts5912_config_##id = { \ + .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(id)}, \ + .reg_base = (volatile uint32_t *)DT_INST_REG_ADDR(id), \ + .num_pins = DT_INST_PROP(id, ngpios), \ + }; \ + DEVICE_DT_INST_DEFINE(id, gpio_rts5912_init_##id, NULL, &gpio_rts5912_data_##id, \ + &gpio_rts5912_config_##id, POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_rts5912_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_RTS5912_INIT) diff --git a/drivers/gpio/gpio_sam.c b/drivers/gpio/gpio_sam.c index ae8a954c6aecb..9ceb9173b28ba 100644 --- a/drivers/gpio/gpio_sam.c +++ b/drivers/gpio/gpio_sam.c @@ -66,8 +66,7 @@ static int gpio_sam_port_configure(const struct device *dev, uint32_t mask, pio->PIO_PUDR = mask; #if defined(CONFIG_SOC_SERIES_SAM4S) || \ defined(CONFIG_SOC_SERIES_SAM4E) || \ - defined(CONFIG_SOC_SERIES_SAME70) || \ - defined(CONFIG_SOC_SERIES_SAMV71) + defined(CONFIG_SOC_SERIES_SAMX7X) /* Disable pull-down. */ pio->PIO_PPDDR = mask; #endif @@ -108,8 +107,7 @@ static int gpio_sam_port_configure(const struct device *dev, uint32_t mask, pio->PIO_PUDR = mask; #if defined(CONFIG_SOC_SERIES_SAM4S) || \ defined(CONFIG_SOC_SERIES_SAM4E) || \ - defined(CONFIG_SOC_SERIES_SAME70) || \ - defined(CONFIG_SOC_SERIES_SAMV71) + defined(CONFIG_SOC_SERIES_SAMX7X) pio->PIO_PPDDR = mask; #endif if (flags & GPIO_PULL_UP) { @@ -117,8 +115,7 @@ static int gpio_sam_port_configure(const struct device *dev, uint32_t mask, pio->PIO_PUER = mask; #if defined(CONFIG_SOC_SERIES_SAM4S) || \ defined(CONFIG_SOC_SERIES_SAM4E) || \ - defined(CONFIG_SOC_SERIES_SAME70) || \ - defined(CONFIG_SOC_SERIES_SAMV71) + defined(CONFIG_SOC_SERIES_SAMX7X) /* Setup Pull-down resistor. */ } else if (flags & GPIO_PULL_DOWN) { @@ -136,8 +133,7 @@ static int gpio_sam_port_configure(const struct device *dev, uint32_t mask, } #elif defined(CONFIG_SOC_SERIES_SAM4S) || \ defined(CONFIG_SOC_SERIES_SAM4E) || \ - defined(CONFIG_SOC_SERIES_SAME70) || \ - defined(CONFIG_SOC_SERIES_SAMV71) + defined(CONFIG_SOC_SERIES_SAMX7X) /* Setup debounce. */ if (flags & SAM_GPIO_DEBOUNCE) { diff --git a/drivers/gpio/gpio_shell.c b/drivers/gpio/gpio_shell.c index d05683327c995..d85b72e2dca34 100644 --- a/drivers/gpio/gpio_shell.c +++ b/drivers/gpio/gpio_shell.c @@ -134,9 +134,10 @@ DT_FOREACH_STATUS_OKAY_NODE(IS_GPIO_CTRL_PIN_GET) static const struct gpio_ctrl gpio_list[] = {DT_FOREACH_STATUS_OKAY_NODE(IS_GPIO_CTRL_LIST)}; -static const struct gpio_ctrl *get_gpio_ctrl_helper(const struct device *dev) +static const struct gpio_ctrl *get_gpio_ctrl(const char *name) { size_t i; + const struct device *dev = shell_device_get_binding(name); if (dev == NULL) { return NULL; @@ -151,29 +152,6 @@ static const struct gpio_ctrl *get_gpio_ctrl_helper(const struct device *dev) return NULL; } -/* Look up a device by some human-readable string identifier. We - * always search among device names. If the feature is available, we - * search by node label as well. - */ -static const struct gpio_ctrl *get_gpio_ctrl(char *id) -{ - const struct gpio_ctrl *ctrl; - - ctrl = get_gpio_ctrl_helper(device_get_binding(id)); - if (ctrl != NULL) { - return ctrl; - } - -#ifdef CONFIG_DEVICE_DT_METADATA - ctrl = get_gpio_ctrl_helper(device_get_by_dt_nodelabel(id)); - if (ctrl != NULL) { - return ctrl; - } -#endif /* CONFIG_DEVICE_DT_METADATA */ - - return NULL; -} - int line_cmp(const char *input, const char *line_name) { int i = 0; diff --git a/drivers/gpio/gpio_silabs_siwx91x.c b/drivers/gpio/gpio_silabs_siwx91x.c new file mode 100644 index 0000000000000..d712a6909fd85 --- /dev/null +++ b/drivers/gpio/gpio_silabs_siwx91x.c @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT silabs_siwx91x_gpio + +#include "sl_si91x_driver_gpio.h" +#include "sl_status.h" + +#include +#include +#include + +/* Zephyr GPIO header must be included after driver, due to symbol conflicts + * for GPIO_INPUT and GPIO_OUTPUT between preprocessor macros in the Zephyr + * API and struct member register definitions for the SiWx91x device. + */ +#include +#include + +#if CONFIG_GPIO_SILABS_SIWX91X_COMMON_INIT_PRIORITY >= CONFIG_GPIO_INIT_PRIORITY +#error CONFIG_GPIO_SILABS_SIWX91X_COMMON_INIT_PRIORITY must be less than \ + CONFIG_GPIO_INIT_PRIORITY. +#endif + +#define MAX_PORT_COUNT 4 +#define MAX_PIN_COUNT 16 +#define INVALID_PORT 0xFF +#define INTERRUPT_COUNT 8 + +/* Types */ +struct gpio_siwx91x_common_config { + EGPIO_Type *reg; +}; + +struct gpio_siwx91x_port_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + const struct device *parent; + uint8_t pads[MAX_PIN_COUNT]; + int port; + int hal_port; + bool ulp; +}; + +struct gpio_siwx91x_common_data { + /* a list of all ports */ + const struct device *ports[MAX_PORT_COUNT]; + sl_gpio_t interrupts[INTERRUPT_COUNT]; +}; + +struct gpio_siwx91x_port_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + /* port ISR callback routine address */ + sys_slist_t callbacks; +}; + +/* Functions */ +static int gpio_siwx91x_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_siwx91x_port_config *cfg = dev->config; + const struct device *parent = cfg->parent; + const struct gpio_siwx91x_common_config *pcfg = parent->config; + sl_status_t status; + sl_si91x_gpio_driver_disable_state_t disable_state = GPIO_HZ; + + if (flags & GPIO_SINGLE_ENDED) { + return -ENOTSUP; + } + + uint8_t pad = cfg->pads[pin]; + + if (pad == 0) { + /* Enable MCU pad */ + status = sl_si91x_gpio_driver_enable_host_pad_selection((cfg->hal_port << 4) | pin); + if (status != SL_STATUS_OK) { + return -ENODEV; + } + } else if (pad != 0xFF && pad != 9) { + /* Assign pad to MCU subsystem */ + status = sl_si91x_gpio_driver_enable_pad_selection(pad); + if (status != SL_STATUS_OK) { + return -ENODEV; + } + } + + if (flags & GPIO_PULL_UP) { + disable_state = GPIO_PULLUP; + } else if (flags & GPIO_PULL_DOWN) { + disable_state = GPIO_PULLDOWN; + } + if (cfg->ulp) { + sl_si91x_gpio_select_ulp_pad_driver_disable_state(pin, disable_state); + } else { + sl_si91x_gpio_select_pad_driver_disable_state((cfg->port << 4) | pin, + disable_state); + } + + if (flags & GPIO_INPUT) { + if (cfg->ulp) { + sl_si91x_gpio_driver_enable_ulp_pad_receiver(pin); + } else { + sl_si91x_gpio_driver_enable_pad_receiver((cfg->port << 4) | pin); + } + } else { + if (cfg->ulp) { + sl_si91x_gpio_driver_disable_ulp_pad_receiver(pin); + } else { + sl_si91x_gpio_driver_disable_pad_receiver((cfg->port << 4) | pin); + } + } + + pcfg->reg->PIN_CONFIG[(cfg->port << 4) + pin].GPIO_CONFIG_REG_b.MODE = 0; + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + sl_gpio_set_pin_output(cfg->hal_port, pin); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + sl_gpio_clear_pin_output(cfg->hal_port, pin); + } + + sl_si91x_gpio_set_pin_direction(cfg->hal_port, pin, (flags & GPIO_OUTPUT) ? 0 : 1); + + return 0; +} + +static int gpio_siwx91x_port_get(const struct device *port, gpio_port_value_t *value) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + + *value = sl_gpio_get_port_input(cfg->hal_port); + + return 0; +} + +static int gpio_siwx91x_port_set_masked(const struct device *port, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + const struct device *parent = cfg->parent; + const struct gpio_siwx91x_common_config *pcfg = parent->config; + + /* Cannot use HAL function sl_gpio_set_port_output_value(), as it doesn't clear bits. */ + pcfg->reg->PORT_CONFIG[cfg->port].PORT_LOAD_REG = + (pcfg->reg->PORT_CONFIG[cfg->port].PORT_LOAD_REG & ~mask) | (value & mask); + + return 0; +} + +static int gpio_siwx91x_port_set_bits(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + + sl_gpio_set_port_output(cfg->hal_port, pins); + + return 0; +} + +static int gpio_siwx91x_port_clear_bits(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + + sl_gpio_clear_port_output(cfg->hal_port, pins); + + return 0; +} + +static int gpio_siwx91x_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + + sl_gpio_toggle_port_output(cfg->hal_port, pins); + + return 0; +} + +static bool receiver_enabled(bool ulp, sl_gpio_port_t port, int pin) +{ + if (ulp) { + return ULP_PAD_CONFIG_REG & BIT(pin); + } else { + return PAD_REG(((port << 4) | pin))->GPIO_PAD_CONFIG_REG_b.PADCONFIG_REN; + } +} + +int gpio_siwx91x_port_get_direction(const struct device *port, gpio_port_pins_t map, + gpio_port_pins_t *inputs, gpio_port_pins_t *outputs) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + + if (inputs != NULL) { + *inputs = 0; + } + if (outputs != NULL) { + *outputs = 0; + } + for (int i = 0; i < MAX_PIN_COUNT; i++) { + if ((map & BIT(i))) { + if (sl_si91x_gpio_get_pin_direction(cfg->hal_port, i) == 0) { + if (outputs != NULL) { + *outputs |= BIT(i); + } + } + if (receiver_enabled(cfg->ulp, cfg->port, i)) { + if (inputs != NULL) { + *inputs |= BIT(i); + } + } + } + } + return 0; +} + +static int gpio_siwx91x_manage_callback(const struct device *port, struct gpio_callback *callback, + bool set) +{ + struct gpio_siwx91x_port_data *data = port->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static int gpio_siwx91x_interrupt_configure(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + const struct device *parent = cfg->parent; + const struct gpio_siwx91x_common_config *pcfg = parent->config; + struct gpio_siwx91x_common_data *data = parent->data; + sl_si91x_gpio_interrupt_config_flag_t flags = 0; + + if (mode & GPIO_INT_DISABLE) { + ARRAY_FOR_EACH(data->interrupts, i) { + if (data->interrupts[i].port == cfg->port && + data->interrupts[i].pin == pin) { + data->interrupts[i].port = INVALID_PORT; + if (cfg->ulp) { + sl_si91x_gpio_configure_ulp_pin_interrupt(i, flags, pin); + } else { + sl_gpio_configure_interrupt(cfg->port, pin, i, flags); + } + /* Configure function doesn't mask interrupts when disabling */ + pcfg->reg->INTR[i].GPIO_INTR_CTRL_b.MASK = 1; + if (cfg->ulp) { + sl_si91x_gpio_clear_ulp_interrupt(i); + } else { + sl_gpio_clear_interrupts(i); + } + return 0; + } + } + /* No interrupt to disable, but this is not an error */ + return 0; + } + + if (trig == GPIO_INT_TRIG_LOW) { + flags = (mode == GPIO_INT_MODE_EDGE) ? SL_GPIO_INTERRUPT_FALL_EDGE + : SL_GPIO_INTERRUPT_LEVEL_LOW; + } else if (trig == GPIO_INT_TRIG_HIGH) { + flags = (mode == GPIO_INT_MODE_EDGE) ? SL_GPIO_INTERRUPT_RISE_EDGE + : SL_GPIO_INTERRUPT_LEVEL_HIGH; + } else if (trig == GPIO_INT_TRIG_BOTH) { + /* SL_GPIO_INTERRUPT_RISE_FALL_EDGE would make more sense, but HAL + * implementation is buggy. + */ + flags = SL_GPIO_INTERRUPT_RISE_EDGE | SL_GPIO_INTERRUPT_FALL_EDGE; + } + + ARRAY_FOR_EACH(data->interrupts, i) { + if (data->interrupts[i].port == INVALID_PORT || + (data->interrupts[i].port == cfg->port && data->interrupts[i].pin == pin)) { + data->interrupts[i].port = cfg->port; + data->interrupts[i].pin = pin; + + if (cfg->ulp) { + sl_si91x_gpio_configure_ulp_pin_interrupt(i, flags, pin); + } else { + sl_gpio_configure_interrupt(cfg->port, pin, i, flags); + } + return 0; + } + } + /* No more available interrupts */ + return -EBUSY; +} + +static inline int gpio_siwx91x_init_port(const struct device *port) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + const struct device *parent = cfg->parent; + struct gpio_siwx91x_common_data *data = parent->data; + + /* Register port as active */ + __ASSERT(cfg->port < MAX_PORT_COUNT, "Too many ports"); + data->ports[cfg->port] = port; + + return 0; +} + +static void gpio_siwx91x_isr(const struct device *parent) +{ + const struct gpio_siwx91x_common_config *pcfg = parent->config; + struct gpio_siwx91x_common_data *common = parent->data; + const struct device *port; + struct gpio_siwx91x_port_data *data; + + ARRAY_FOR_EACH(common->interrupts, i) { + sl_gpio_port_t port_no = common->interrupts[i].port; + uint32_t pending = pcfg->reg->INTR[i].GPIO_INTR_STATUS_b.INTERRUPT_STATUS; + + if (pending && port_no != INVALID_PORT) { + /* Clear interrupt */ + pcfg->reg->INTR[i].GPIO_INTR_STATUS_b.INTERRUPT_STATUS = 1; + port = common->ports[port_no]; + data = port->data; + gpio_fire_callbacks(&data->callbacks, port, BIT(common->interrupts[i].pin)); + } + } +} + +static uint32_t gpio_siwx91x_get_pending_int(const struct device *port) +{ + const struct gpio_siwx91x_port_config *cfg = port->config; + const struct device *parent = cfg->parent; + const struct gpio_siwx91x_common_config *pcfg = parent->config; + uint32_t status = 0; + + ARRAY_FOR_EACH(pcfg->reg->INTR, i) { + if (pcfg->reg->INTR[i].GPIO_INTR_STATUS_b.INTERRUPT_STATUS) { + status |= BIT(i); + } + } + return status; +} + +static DEVICE_API(gpio, gpio_siwx91x_api) = { + .pin_configure = gpio_siwx91x_pin_configure, + .port_get_raw = gpio_siwx91x_port_get, + .port_set_masked_raw = gpio_siwx91x_port_set_masked, + .port_set_bits_raw = gpio_siwx91x_port_set_bits, + .port_clear_bits_raw = gpio_siwx91x_port_clear_bits, + .port_toggle_bits = gpio_siwx91x_port_toggle_bits, + .pin_interrupt_configure = gpio_siwx91x_interrupt_configure, + .manage_callback = gpio_siwx91x_manage_callback, + .get_pending_int = gpio_siwx91x_get_pending_int, +#ifdef CONFIG_GPIO_GET_DIRECTION + .port_get_direction = gpio_siwx91x_port_get_direction, +#endif +}; + +#define GPIO_PORT_INIT(n) \ + static const struct gpio_siwx91x_port_config gpio_siwx91x_port_config##n = { \ + .common.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_NODE(n), \ + .parent = DEVICE_DT_GET(DT_PARENT(n)), \ + .pads = DT_PROP(n, silabs_pads), \ + .port = DT_REG_ADDR(n), \ + .hal_port = (DT_PROP(DT_PARENT(n), silabs_ulp) ? SL_GPIO_ULP_PORT : 0) + \ + DT_REG_ADDR(n), \ + .ulp = DT_PROP(DT_PARENT(n), silabs_ulp), \ + }; \ + static struct gpio_siwx91x_port_data gpio_siwx91x_port_data##n; \ + \ + DEVICE_DT_DEFINE(n, gpio_siwx91x_init_port, NULL, &gpio_siwx91x_port_data##n, \ + &gpio_siwx91x_port_config##n, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_siwx91x_api); + +#define CONFIGURE_SHARED_INTERRUPT(node_id, prop, idx) \ + IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), DT_IRQ_BY_IDX(node_id, idx, priority), \ + gpio_siwx91x_isr, DEVICE_DT_GET(node_id), 0); \ + irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); + +static DEVICE_API(gpio, gpio_siwx91x_common_api) = { }; + +#define GPIO_CONTROLLER_INIT(idx) \ + static const struct gpio_siwx91x_common_config gpio_siwx91x_config##idx = { \ + .reg = (EGPIO_Type *)DT_INST_REG_ADDR(idx), \ + }; \ + static struct gpio_siwx91x_common_data gpio_siwx91x_data##idx; \ + \ + static int gpio_siwx91x_init_controller_##idx(const struct device *dev) \ + { \ + struct gpio_siwx91x_common_data *data = dev->data; \ + int status; \ + \ + status = sl_si91x_gpio_driver_enable_clock( \ + COND_CODE_1(DT_INST_PROP(idx, silabs_ulp), (ULPCLK_GPIO), (M4CLK_GPIO))); \ + if (status) { \ + return -ENODEV; \ + } \ + ARRAY_FOR_EACH(data->interrupts, i) { \ + data->interrupts[i].port = INVALID_PORT; \ + } \ + DT_INST_FOREACH_PROP_ELEM(idx, interrupt_names, CONFIGURE_SHARED_INTERRUPT); \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(idx, gpio_siwx91x_init_controller_##idx, NULL, \ + &gpio_siwx91x_data##idx, &gpio_siwx91x_config##idx, \ + PRE_KERNEL_1, CONFIG_GPIO_SILABS_SIWX91X_COMMON_INIT_PRIORITY, \ + &gpio_siwx91x_common_api); \ + DT_INST_FOREACH_CHILD_STATUS_OKAY(idx, GPIO_PORT_INIT); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_CONTROLLER_INIT) diff --git a/drivers/gpio/gpio_silabs_siwx91x_uulp.c b/drivers/gpio/gpio_silabs_siwx91x_uulp.c new file mode 100644 index 0000000000000..ff9389eacdbe6 --- /dev/null +++ b/drivers/gpio/gpio_silabs_siwx91x_uulp.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT silabs_siwx91x_gpio_uulp + +#include "sl_si91x_driver_gpio.h" +#include "sl_status.h" + +#include +#include +#include + +/* Zephyr GPIO header must be included after driver, due to symbol conflicts + * for GPIO_INPUT and GPIO_OUTPUT between preprocessor macros in the Zephyr + * API and struct member register definitions for the SiWx91x device. + */ +#include +#include + +#define UULP_GPIO_COUNT 5 +#define UULP_REG_INTERRUPT_CONFIG 0x10 + +/* Types */ +struct gpio_siwx91x_uulp_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; +}; + +struct gpio_siwx91x_uulp_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + /* port ISR callback routine address */ + sys_slist_t callbacks; +}; + +/* Functions */ +static int gpio_siwx91x_uulp_pin_configure(const struct device *dev, gpio_pin_t pin, + gpio_flags_t flags) +{ + if (flags & (GPIO_SINGLE_ENDED | GPIO_PULL_UP | GPIO_PULL_DOWN)) { + return -ENOTSUP; + } + + /* Enable input */ + sl_si91x_gpio_select_uulp_npss_receiver(pin, (flags & GPIO_INPUT) ? 1 : 0); + + /* Select GPIO mode */ + sl_si91x_gpio_set_uulp_npss_pin_mux(pin, 0); + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + sl_si91x_gpio_set_uulp_npss_pin_value(pin, 1); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + sl_si91x_gpio_set_uulp_npss_pin_value(pin, 0); + } + + /* Enable output */ + sl_si91x_gpio_set_uulp_npss_direction(pin, (flags & GPIO_OUTPUT) ? 0 : 1); + + return 0; +} + +static int gpio_siwx91x_uulp_port_get(const struct device *port, gpio_port_value_t *value) +{ + for (size_t i = 0; i < UULP_GPIO_COUNT; i++) { + WRITE_BIT(*value, i, sl_si91x_gpio_get_uulp_npss_pin(i)); + } + + return 0; +} + +static int gpio_siwx91x_uulp_port_set_masked(const struct device *port, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + for (size_t i = 0; i < UULP_GPIO_COUNT; i++) { + if (mask & BIT(i)) { + sl_si91x_gpio_set_uulp_npss_pin_value(i, FIELD_GET(BIT(i), value)); + } + } + + return 0; +} + +static int gpio_siwx91x_uulp_port_set_bits(const struct device *port, gpio_port_pins_t pins) +{ + for (size_t i = 0; i < UULP_GPIO_COUNT; i++) { + if (FIELD_GET(BIT(i), pins)) { + sl_si91x_gpio_set_uulp_npss_pin_value(i, 1); + } + } + + return 0; +} + +static int gpio_siwx91x_uulp_port_clear_bits(const struct device *port, gpio_port_pins_t pins) +{ + for (size_t i = 0; i < UULP_GPIO_COUNT; i++) { + if (FIELD_GET(BIT(i), pins)) { + sl_si91x_gpio_set_uulp_npss_pin_value(i, 0); + } + } + + return 0; +} + +static int gpio_siwx91x_uulp_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) +{ + for (size_t i = 0; i < UULP_GPIO_COUNT; i++) { + if (FIELD_GET(BIT(i), pins)) { + sl_si91x_gpio_toggle_uulp_npss_pin(i); + } + } + + return 0; +} + +static int gpio_siwx91x_uulp_manage_callback(const struct device *port, + struct gpio_callback *callback, bool set) +{ + struct gpio_siwx91x_uulp_data *data = port->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static int gpio_siwx91x_uulp_interrupt_configure(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + uint32_t flags = 0; + + if (mode == GPIO_INT_MODE_DISABLED) { + sl_si91x_gpio_configure_uulp_interrupt(flags, pin); + sl_si91x_gpio_clear_uulp_interrupt(BIT(pin)); + sl_si91x_gpio_mask_uulp_npss_interrupt(BIT(pin)); + } else { + if (trig == GPIO_INT_TRIG_LOW) { + flags = (mode == GPIO_INT_MODE_EDGE) ? SL_GPIO_INTERRUPT_FALL_EDGE + : SL_GPIO_INTERRUPT_LEVEL_LOW; + } else if (trig == GPIO_INT_TRIG_HIGH) { + flags = (mode == GPIO_INT_MODE_EDGE) ? SL_GPIO_INTERRUPT_RISE_EDGE + : SL_GPIO_INTERRUPT_LEVEL_HIGH; + } else if (trig == GPIO_INT_TRIG_BOTH) { + /* SL_GPIO_INTERRUPT_RISE_FALL_EDGE would make more sense, but HAL + * implementation is buggy. + */ + flags = SL_GPIO_INTERRUPT_RISE_EDGE | SL_GPIO_INTERRUPT_FALL_EDGE; + } + + sl_si91x_gpio_configure_uulp_interrupt(flags, pin); + } + return 0; +} + +static void gpio_siwx91x_uulp_isr(const struct device *port) +{ + struct gpio_siwx91x_uulp_data *data = port->data; + uint8_t pins = sl_si91x_gpio_get_uulp_interrupt_status(); + + sl_si91x_gpio_clear_uulp_interrupt(pins); + + gpio_fire_callbacks(&data->callbacks, port, pins); +} + +static DEVICE_API(gpio, gpio_siwx91x_uulp_api) = { + .pin_configure = gpio_siwx91x_uulp_pin_configure, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = NULL, +#endif + .port_get_raw = gpio_siwx91x_uulp_port_get, + .port_set_masked_raw = gpio_siwx91x_uulp_port_set_masked, + .port_set_bits_raw = gpio_siwx91x_uulp_port_set_bits, + .port_clear_bits_raw = gpio_siwx91x_uulp_port_clear_bits, + .port_toggle_bits = gpio_siwx91x_uulp_port_toggle_bits, + .pin_interrupt_configure = gpio_siwx91x_uulp_interrupt_configure, + .manage_callback = gpio_siwx91x_uulp_manage_callback, + .get_pending_int = NULL, +#ifdef CONFIG_GPIO_GET_DIRECTION + .port_get_direction = NULL, +#endif +}; + +#define GPIO_PORT_INIT(idx) \ + static const struct gpio_siwx91x_uulp_config gpio_siwx91x_port_config##idx = { \ + .common.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(idx), \ + }; \ + static struct gpio_siwx91x_uulp_data gpio_siwx91x_port_data##idx; \ + \ + static int gpio_siwx91x_init_uulp_##idx(const struct device *dev) \ + { \ + sys_write32(0, DT_INST_REG_ADDR_BY_NAME(idx, int) + UULP_REG_INTERRUPT_CONFIG); \ + IRQ_CONNECT(DT_INST_IRQ(idx, irq), DT_INST_IRQ(idx, priority), \ + gpio_siwx91x_uulp_isr, DEVICE_DT_GET(DT_DRV_INST(idx)), 0); \ + irq_enable(DT_INST_IRQ(idx, irq)); \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(idx, gpio_siwx91x_init_uulp_##idx, NULL, \ + &gpio_siwx91x_port_data##idx, &gpio_siwx91x_port_config##idx, \ + PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_siwx91x_uulp_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_PORT_INIT) diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index 29b243b3d0616..09881a4dd01d4 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -91,6 +91,23 @@ static int gpio_stm32_flags_to_conf(gpio_flags_t flags, uint32_t *pincfg) *pincfg = STM32_PINCFG_MODE_ANALOG; } +#if !defined(CONFIG_SOC_SERIES_STM32F1X) + switch (flags & (STM32_GPIO_SPEED_MASK << STM32_GPIO_SPEED_SHIFT)) { + case STM32_GPIO_VERY_HIGH_SPEED: + *pincfg |= STM32_OSPEEDR_VERY_HIGH_SPEED; + break; + case STM32_GPIO_HIGH_SPEED: + *pincfg |= STM32_OSPEEDR_HIGH_SPEED; + break; + case STM32_GPIO_MEDIUM_SPEED: + *pincfg |= STM32_OSPEEDR_MEDIUM_SPEED; + break; + default: + *pincfg |= STM32_OSPEEDR_LOW_SPEED; + break; + } +#endif /* !CONFIG_SOC_SERIES_STM32F1X */ + return 0; } @@ -772,3 +789,4 @@ GPIO_DEVICE_INIT_STM32_IF_OKAY(m, M); GPIO_DEVICE_INIT_STM32_IF_OKAY(n, N); GPIO_DEVICE_INIT_STM32_IF_OKAY(o, O); GPIO_DEVICE_INIT_STM32_IF_OKAY(p, P); +GPIO_DEVICE_INIT_STM32_IF_OKAY(q, Q); diff --git a/drivers/gpio/gpio_sy1xx.c b/drivers/gpio/gpio_sy1xx.c new file mode 100644 index 0000000000000..300b436f3dcf4 --- /dev/null +++ b/drivers/gpio/gpio_sy1xx.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2024 sensry.io + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sensry_sy1xx_gpio + +#include +LOG_MODULE_REGISTER(sy1xx_gpio, CONFIG_GPIO_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SY1XX_GPIO_GET_OFFS 0x00 +#define SY1XX_GPIO_SET_OFFS 0x1c +#define SY1XX_GPIO_CLR_OFFS 0x20 + +struct sy1xx_gpio_config { + /* Base address for GPIO port*/ + uint32_t port_base_addr; + /* configuration base address for the pad config */ + uint32_t pad_cfg_offs; + /* mask of pins which are allowed to modify by the gpio driver */ + uint32_t pin_mask; +}; + +/* Function prototypes for the GPIO API */ +static int sy1xx_gpio_driver_configure(const struct device *dev, gpio_pin_t pin, + gpio_flags_t flags); +static int sy1xx_gpio_driver_port_get_raw(const struct device *dev, gpio_port_value_t *value); +static int sy1xx_gpio_driver_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value); +static int sy1xx_gpio_driver_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins); +static int sy1xx_gpio_driver_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins); +static int sy1xx_gpio_driver_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins); + +static int sy1xx_gpio_driver_init(const struct device *dev) +{ + return 0; +} + +int sy1xx_gpio_driver_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct sy1xx_gpio_config *const cfg = dev->config; + + if (((BIT(pin)) & cfg->pin_mask) == 0) { + return -EINVAL; + } + + /* initialize the pinctrl config for the given gpio pin */ + pinctrl_soc_pin_t pcfg = { + .addr = cfg->pad_cfg_offs + ROUND_DOWN(pin, 4), + .iro = (pin % 4) * 8, + .cfg = 0, + }; + + /* translate gpio flags into pinctrl config */ + if (flags & GPIO_INPUT) { + + if (flags & GPIO_PULL_UP) { + pcfg.cfg |= BIT(SY1XX_PAD_PULL_UP_OFFS); + } + if (flags & GPIO_PULL_DOWN) { + pcfg.cfg |= BIT(SY1XX_PAD_PULL_DOWN_OFFS); + } + + } else if (flags & GPIO_OUTPUT) { + pcfg.cfg |= BIT(SY1XX_PAD_DIR_OFFS); + + if (flags & GPIO_OUTPUT_INIT_LOW) { + sy1xx_gpio_driver_port_set_masked_raw(dev, BIT(pin), 0); + } + if (flags & GPIO_OUTPUT_INIT_HIGH) { + sy1xx_gpio_driver_port_set_masked_raw(dev, BIT(pin), BIT(pin)); + } + + } else if (flags == GPIO_DISCONNECTED) { + pcfg.cfg |= BIT(SY1XX_PAD_TRISTATE_OFFS); + + } else { + LOG_ERR("%s: unsupported pinctrl mode for pin: %u", dev->name, pin); + return -ENOTSUP; + } + + /* PAD config */ + int32_t ret = pinctrl_configure_pins(&pcfg, 1, PINCTRL_STATE_DEFAULT); + + if (ret != 0) { + LOG_ERR("%s: failed to apply pinctrl for pin: %u", dev->name, pin); + return -EINVAL; + } + + return 0; +} + +int sy1xx_gpio_driver_port_get_raw(const struct device *dev, gpio_port_value_t *value) +{ + const struct sy1xx_gpio_config *const cfg = dev->config; + + *value = sys_read32(cfg->port_base_addr | SY1XX_GPIO_GET_OFFS); + return 0; +} + +int sy1xx_gpio_driver_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct sy1xx_gpio_config *const cfg = dev->config; + + uint32_t set_mask = (mask & value) & (cfg->pin_mask); + uint32_t clr_mask = (mask & (~value)) & (cfg->pin_mask); + + sy1xx_gpio_driver_port_set_bits_raw(dev, set_mask); + sy1xx_gpio_driver_port_clear_bits_raw(dev, clr_mask); + return 0; +} + +int sy1xx_gpio_driver_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + const struct sy1xx_gpio_config *const cfg = dev->config; + + /* affects only pins that are set to logical '1' */ + sys_write32((uint32_t)pins, cfg->port_base_addr | SY1XX_GPIO_SET_OFFS); + return 0; +} + +int sy1xx_gpio_driver_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins) +{ + const struct sy1xx_gpio_config *const cfg = dev->config; + + /* affects only pins that are set to logical '1' */ + sys_write32((uint32_t)pins, cfg->port_base_addr | SY1XX_GPIO_CLR_OFFS); + return 0; +} + +int sy1xx_gpio_driver_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) +{ + const struct sy1xx_gpio_config *const cfg = dev->config; + + uint32_t current = sys_read32(cfg->port_base_addr | SY1XX_GPIO_GET_OFFS); + + sy1xx_gpio_driver_port_set_masked_raw(dev, pins, ~current); + return 0; +} + +/* Define the GPIO API structure */ +static DEVICE_API(gpio, sy1xx_gpio_driver_api) = { + .pin_configure = sy1xx_gpio_driver_configure, + .port_get_raw = sy1xx_gpio_driver_port_get_raw, + .port_set_masked_raw = sy1xx_gpio_driver_port_set_masked_raw, + .port_set_bits_raw = sy1xx_gpio_driver_port_set_bits_raw, + .port_clear_bits_raw = sy1xx_gpio_driver_port_clear_bits_raw, + .port_toggle_bits = sy1xx_gpio_driver_port_toggle_bits, +}; + +#define SY1XX_GPIO_INIT(n) \ + \ + static const struct sy1xx_gpio_config sy1xx_gpio_##n##_config = { \ + .port_base_addr = (uint32_t)DT_INST_REG_ADDR_BY_IDX(n, 0), \ + .pad_cfg_offs = (uint32_t)DT_INST_PROP(n, pad_cfg), \ + .pin_mask = (uint32_t)GPIO_PORT_PIN_MASK_FROM_DT_INST(n)}; \ + \ + DEVICE_DT_INST_DEFINE(n, sy1xx_gpio_driver_init, NULL, NULL, &sy1xx_gpio_##n##_config, \ + PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &sy1xx_gpio_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SY1XX_GPIO_INIT) diff --git a/drivers/gpio/gpio_xlnx_ps.c b/drivers/gpio/gpio_xlnx_ps.c index ed6488793f72e..896916da1f4a5 100644 --- a/drivers/gpio/gpio_xlnx_ps.c +++ b/drivers/gpio/gpio_xlnx_ps.c @@ -20,6 +20,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define DT_DRV_COMPAT xlnx_ps_gpio +#define DEV_CFG(_dev) ((const struct gpio_xlnx_ps_dev_cfg *)(_dev)->config) +#define DEV_DATA(_dev) ((struct gpio_xlnx_ps_dev_data *const)(_dev)->data) + /* * An API is required for this driver, but as no pin access is provided at * this level, use the default API contents provided by the driver subsystem. @@ -41,7 +44,22 @@ static DEVICE_API(gpio, gpio_xlnx_ps_default_apis); */ static int gpio_xlnx_ps_init(const struct device *dev) { - const struct gpio_xlnx_ps_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_dev_data *dev_data = DEV_DATA(dev); + uint32_t bank; + + /* Perform the actual memory map operation in the parent device */ + DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE); + dev_data->base = DEVICE_MMIO_NAMED_GET(dev, reg_base); + __ASSERT(dev_data->base != 0, "%s map register space failed", dev->name); + + /* Propagate the virtual base address to the bank devices */ + for (bank = 0; bank < dev_conf->num_banks; bank++) { + struct gpio_xlnx_ps_bank_dev_data *bank_data = + dev_conf->bank_devices[bank]->data; + __ASSERT(bank_data != NULL, "%s bank %u data unresolved", dev->name, bank); + bank_data->base = dev_data->base; + } /* Initialize the device's interrupt */ dev_conf->config_func(dev); @@ -63,7 +81,7 @@ static int gpio_xlnx_ps_init(const struct device *dev) */ static void gpio_xlnx_ps_isr(const struct device *dev) { - const struct gpio_xlnx_ps_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_dev_cfg *dev_conf = DEV_CFG(dev); const struct gpio_driver_api *api; struct gpio_xlnx_ps_bank_dev_data *bank_data; @@ -102,11 +120,13 @@ static const struct device *const gpio_xlnx_ps##idx##_banks[] = {\ /* Device config & run-time data struct creation macros */ #define GPIO_XLNX_PS_DEV_DATA(idx)\ -static struct gpio_xlnx_ps_dev_data gpio_xlnx_ps##idx##_data; +static struct gpio_xlnx_ps_dev_data gpio_xlnx_ps##idx##_data = {\ + .base = 0x0,\ +}; #define GPIO_XLNX_PS_DEV_CONFIG(idx)\ static const struct gpio_xlnx_ps_dev_cfg gpio_xlnx_ps##idx##_cfg = {\ - .base_addr = DT_INST_REG_ADDR(idx),\ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(idx)),\ .bank_devices = gpio_xlnx_ps##idx##_banks,\ .num_banks = ARRAY_SIZE(gpio_xlnx_ps##idx##_banks),\ .config_func = gpio_xlnx_ps##idx##_irq_config\ diff --git a/drivers/gpio/gpio_xlnx_ps.h b/drivers/gpio/gpio_xlnx_ps.h index e08b842bc0f04..7dc48ffc9d2f6 100644 --- a/drivers/gpio/gpio_xlnx_ps.h +++ b/drivers/gpio/gpio_xlnx_ps.h @@ -23,6 +23,9 @@ typedef void (*gpio_xlnx_ps_config_irq_t)(const struct device *dev); */ struct gpio_xlnx_ps_dev_data { struct gpio_driver_data common; + + DEVICE_MMIO_NAMED_RAM(reg_base); + mem_addr_t base; }; /** @@ -36,7 +39,8 @@ struct gpio_xlnx_ps_dev_data { struct gpio_xlnx_ps_dev_cfg { struct gpio_driver_config common; - uint32_t base_addr; + DEVICE_MMIO_NAMED_ROM(reg_base); + const struct device *const *bank_devices; uint32_t num_banks; gpio_xlnx_ps_config_irq_t config_func; diff --git a/drivers/gpio/gpio_xlnx_ps_bank.c b/drivers/gpio/gpio_xlnx_ps_bank.c index 046956782a6cd..8f62dc95da259 100644 --- a/drivers/gpio/gpio_xlnx_ps_bank.c +++ b/drivers/gpio/gpio_xlnx_ps_bank.c @@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define DT_DRV_COMPAT xlnx_ps_gpio_bank +#define DEV_CFG(_dev) ((const struct gpio_xlnx_ps_bank_dev_cfg *)(_dev)->config) +#define DEV_DATA(_dev) ((struct gpio_xlnx_ps_bank_dev_data *const)(_dev)->data) + /** * @brief GPIO bank pin configuration function * @@ -47,7 +50,8 @@ static int gpio_xlnx_ps_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); uint32_t pin_mask = BIT(pin); uint32_t bank_data; uint32_t dirm_data; @@ -127,7 +131,8 @@ static int gpio_xlnx_ps_pin_configure(const struct device *dev, static int gpio_xlnx_ps_bank_get(const struct device *dev, gpio_port_value_t *value) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); *value = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG); return 0; @@ -159,7 +164,8 @@ static int gpio_xlnx_ps_bank_set_masked(const struct device *dev, gpio_port_pins_t mask, gpio_port_value_t value) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); uint32_t bank_data; bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG); @@ -187,7 +193,8 @@ static int gpio_xlnx_ps_bank_set_masked(const struct device *dev, static int gpio_xlnx_ps_bank_set_bits(const struct device *dev, gpio_port_pins_t pins) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); uint32_t bank_data; bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG); @@ -215,7 +222,8 @@ static int gpio_xlnx_ps_bank_set_bits(const struct device *dev, static int gpio_xlnx_ps_bank_clear_bits(const struct device *dev, gpio_port_pins_t pins) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); uint32_t bank_data; bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG); @@ -243,7 +251,8 @@ static int gpio_xlnx_ps_bank_clear_bits(const struct device *dev, static int gpio_xlnx_ps_bank_toggle_bits(const struct device *dev, gpio_port_pins_t pins) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); uint32_t bank_data; bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG); @@ -282,7 +291,8 @@ static int gpio_xlnx_ps_bank_pin_irq_configure(const struct device *dev, enum gpio_int_mode mode, enum gpio_int_trig trig) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); uint32_t pin_mask = BIT(pin); uint32_t int_type_data; uint32_t int_polarity_data; @@ -358,7 +368,8 @@ static int gpio_xlnx_ps_bank_pin_irq_configure(const struct device *dev, */ static uint32_t gpio_xlnx_ps_bank_get_int_status(const struct device *dev) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); uint32_t int_status; int_status = sys_read32(GPIO_XLNX_PS_BANK_INT_STAT_REG); @@ -387,7 +398,7 @@ static int gpio_xlnx_ps_bank_manage_callback(const struct device *dev, struct gpio_callback *callback, bool set) { - struct gpio_xlnx_ps_bank_dev_data *dev_data = dev->data; + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); return gpio_manage_callback(&dev_data->callbacks, callback, set); } @@ -419,7 +430,14 @@ static DEVICE_API(gpio, gpio_xlnx_ps_bank_apis) = { */ static int gpio_xlnx_ps_bank_init(const struct device *dev) { - const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = dev->config; + const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev); + struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev); + + __ASSERT(dev_data->base != 0, "%s mapped base address missing", dev->name); + if (dev_data->base == 0) { + LOG_ERR("%s mapped base address missing", dev->name); + return -EIO; + } sys_write32(~0x0, GPIO_XLNX_PS_BANK_INT_DIS_REG); /* Disable all interrupts */ sys_write32(~0x0, GPIO_XLNX_PS_BANK_INT_STAT_REG); /* Clear all interrupts */ @@ -436,10 +454,11 @@ static const struct gpio_xlnx_ps_bank_dev_cfg gpio_xlnx_ps_bank##idx##_cfg = {\ .common = {\ .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(idx),\ },\ - .base_addr = DT_REG_ADDR(DT_PARENT(DT_INST(idx, DT_DRV_COMPAT))),\ - .bank_index = idx,\ + .bank_index = DT_INST_REG_ADDR(idx),\ +};\ +static struct gpio_xlnx_ps_bank_dev_data gpio_xlnx_ps_bank##idx##_data = {\ + .base = 0,\ };\ -static struct gpio_xlnx_ps_bank_dev_data gpio_xlnx_ps_bank##idx##_data;\ DEVICE_DT_INST_DEFINE(idx, gpio_xlnx_ps_bank_init, NULL,\ &gpio_xlnx_ps_bank##idx##_data, &gpio_xlnx_ps_bank##idx##_cfg,\ PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_xlnx_ps_bank_apis); diff --git a/drivers/gpio/gpio_xlnx_ps_bank.h b/drivers/gpio/gpio_xlnx_ps_bank.h index ce2385fbb20e7..f2d34274ef308 100644 --- a/drivers/gpio/gpio_xlnx_ps_bank.h +++ b/drivers/gpio/gpio_xlnx_ps_bank.h @@ -14,31 +14,31 @@ * Register address calculation macros * Register address offsets: comp. Zynq-7000 TRM, ug585, chap. B.19 */ -#define GPIO_XLNX_PS_BANK_MASK_DATA_LSW_REG (dev_conf->base_addr\ +#define GPIO_XLNX_PS_BANK_MASK_DATA_LSW_REG (dev_data->base\ + ((uint32_t)dev_conf->bank_index * 0x8)) -#define GPIO_XLNX_PS_BANK_MASK_DATA_MSW_REG ((dev_conf->base_addr + 0x04)\ +#define GPIO_XLNX_PS_BANK_MASK_DATA_MSW_REG ((dev_data->base + 0x04)\ + ((uint32_t)dev_conf->bank_index * 0x8)) -#define GPIO_XLNX_PS_BANK_DATA_REG ((dev_conf->base_addr + 0x40)\ +#define GPIO_XLNX_PS_BANK_DATA_REG ((dev_data->base + 0x40)\ + ((uint32_t)dev_conf->bank_index * 0x4)) -#define GPIO_XLNX_PS_BANK_DATA_RO_REG ((dev_conf->base_addr + 0x60)\ +#define GPIO_XLNX_PS_BANK_DATA_RO_REG ((dev_data->base + 0x60)\ + ((uint32_t)dev_conf->bank_index * 0x4)) -#define GPIO_XLNX_PS_BANK_DIRM_REG ((dev_conf->base_addr + 0x204)\ +#define GPIO_XLNX_PS_BANK_DIRM_REG ((dev_data->base + 0x204)\ + ((uint32_t)dev_conf->bank_index * 0x40)) -#define GPIO_XLNX_PS_BANK_OEN_REG ((dev_conf->base_addr + 0x208)\ +#define GPIO_XLNX_PS_BANK_OEN_REG ((dev_data->base + 0x208)\ + ((uint32_t)dev_conf->bank_index * 0x40)) -#define GPIO_XLNX_PS_BANK_INT_MASK_REG ((dev_conf->base_addr + 0x20C)\ +#define GPIO_XLNX_PS_BANK_INT_MASK_REG ((dev_data->base + 0x20C)\ + ((uint32_t)dev_conf->bank_index * 0x40)) -#define GPIO_XLNX_PS_BANK_INT_EN_REG ((dev_conf->base_addr + 0x210)\ +#define GPIO_XLNX_PS_BANK_INT_EN_REG ((dev_data->base + 0x210)\ + ((uint32_t)dev_conf->bank_index * 0x40)) -#define GPIO_XLNX_PS_BANK_INT_DIS_REG ((dev_conf->base_addr + 0x214)\ +#define GPIO_XLNX_PS_BANK_INT_DIS_REG ((dev_data->base + 0x214)\ + ((uint32_t)dev_conf->bank_index * 0x40)) -#define GPIO_XLNX_PS_BANK_INT_STAT_REG ((dev_conf->base_addr + 0x218)\ +#define GPIO_XLNX_PS_BANK_INT_STAT_REG ((dev_data->base + 0x218)\ + ((uint32_t)dev_conf->bank_index * 0x40)) -#define GPIO_XLNX_PS_BANK_INT_TYPE_REG ((dev_conf->base_addr + 0x21C)\ +#define GPIO_XLNX_PS_BANK_INT_TYPE_REG ((dev_data->base + 0x21C)\ + ((uint32_t)dev_conf->bank_index * 0x40)) -#define GPIO_XLNX_PS_BANK_INT_POLARITY_REG ((dev_conf->base_addr + 0x220)\ +#define GPIO_XLNX_PS_BANK_INT_POLARITY_REG ((dev_data->base + 0x220)\ + ((uint32_t)dev_conf->bank_index * 0x40)) -#define GPIO_XLNX_PS_BANK_INT_ANY_REG ((dev_conf->base_addr + 0x224)\ +#define GPIO_XLNX_PS_BANK_INT_ANY_REG ((dev_data->base + 0x224)\ + ((uint32_t)dev_conf->bank_index * 0x40)) /** @@ -51,6 +51,7 @@ */ struct gpio_xlnx_ps_bank_dev_data { struct gpio_driver_data common; + mem_addr_t base; sys_slist_t callbacks; }; @@ -64,8 +65,6 @@ struct gpio_xlnx_ps_bank_dev_data { */ struct gpio_xlnx_ps_bank_dev_cfg { struct gpio_driver_config common; - - uint32_t base_addr; uint8_t bank_index; }; diff --git a/drivers/haptics/drv2605.c b/drivers/haptics/drv2605.c index 0050af867e9d5..0981f1cc23094 100644 --- a/drivers/haptics/drv2605.c +++ b/drivers/haptics/drv2605.c @@ -498,16 +498,18 @@ static int drv2605_reset(const struct device *dev) k_msleep(100); while (retries > 0) { - i2c_reg_read_byte_dt(&config->i2c, DRV2605_REG_MODE, &value); + retries--; + + ret = i2c_reg_read_byte_dt(&config->i2c, DRV2605_REG_MODE, &value); + if (ret < 0) { + k_usleep(10000); + continue; + } if ((value & DRV2605_DEV_RESET) == 0U) { i2c_reg_update_byte_dt(&config->i2c, DRV2605_REG_MODE, DRV2605_STANDBY, 0); return 0; } - - retries--; - - k_usleep(10000); } return -ETIMEDOUT; diff --git a/drivers/hdlc_rcp_if/CMakeLists.txt b/drivers/hdlc_rcp_if/CMakeLists.txt index abae0200ad9b1..eb325d2550e60 100644 --- a/drivers/hdlc_rcp_if/CMakeLists.txt +++ b/drivers/hdlc_rcp_if/CMakeLists.txt @@ -3,3 +3,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_HDLC_RCP_IF_NXP hdlc_rcp_if_nxp.c) +zephyr_library_sources_ifdef(CONFIG_HDLC_RCP_IF_UART hdlc_rcp_if_uart.c) diff --git a/drivers/hdlc_rcp_if/Kconfig b/drivers/hdlc_rcp_if/Kconfig index c2b77cd42a65e..fd7eec80e0b93 100644 --- a/drivers/hdlc_rcp_if/Kconfig +++ b/drivers/hdlc_rcp_if/Kconfig @@ -14,6 +14,7 @@ menuconfig HDLC_RCP_IF if HDLC_RCP_IF source "drivers/hdlc_rcp_if/Kconfig.nxp" +source "drivers/hdlc_rcp_if/Kconfig.uart" config HDLC_RCP_IF_DRV_NAME string "HDLC RCP Interface Driver's name" diff --git a/drivers/hdlc_rcp_if/Kconfig.uart b/drivers/hdlc_rcp_if/Kconfig.uart new file mode 100644 index 0000000000000..a48c8f0a96afe --- /dev/null +++ b/drivers/hdlc_rcp_if/Kconfig.uart @@ -0,0 +1,27 @@ +# Configuration options for NXP HDLC RCP UART communication Interface + +# Copyright (c) 2024 DENX Software Engineering GmbH +# Lukasz Majewski +# SPDX-License-Identifier: Apache-2.0 + +# +# HDLC UART communication Interface used by Zephyr running Openthread RCP host +# + +config HDLC_RCP_IF_UART + bool "UART HDLC interface for Zephyr Openthread RCP host" + default y + depends on DT_HAS_UART_HDLC_RCP_IF_ENABLED + depends on UART_INTERRUPT_DRIVEN + +config OPENTHREAD_HDLC_RCP_IF_UART_RX_RING_BUFFER_SIZE + int "Set HDLC RCP IF UART RX ring buffer size" + default 4096 + help + RX buffer size for the OpenThread HDLC host UART. + +config OPENTHREAD_HDLC_RCP_IF_UART_TX_RING_BUFFER_SIZE + int "Set HDLC RCP IF UART TX ring buffer size" + default 1344 + help + TX buffer size for the OpenThread HDLC host UART. diff --git a/drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c b/drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c index fb81b20337761..f66af5b349ac3 100644 --- a/drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c +++ b/drivers/hdlc_rcp_if/hdlc_rcp_if_nxp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, NXP + * Copyright 2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,21 +34,14 @@ #define LOG_LEVEL CONFIG_HDLC_RCP_IF_DRIVER_LOG_LEVEL LOG_MODULE_REGISTER(LOG_MODULE_NAME); -#define HDLC_RCP_IF_IRQ_N DT_INST_IRQ_BY_NAME(0, hdlc_rcp_if_int, irq) -#define HDLC_RCP_IF_IRQ_P DT_INST_IRQ_BY_NAME(0, hdlc_rcp_if_int, priority) -#define HDLC_RCP_IF_WAKEUP_IRQ_N DT_INST_IRQ_BY_NAME(0, wakeup_int, irq) -#define HDLC_RCP_IF_WAKEUP_IRQ_P DT_INST_IRQ_BY_NAME(0, wakeup_int, priority) - -struct ot_hdlc_rcp_context { +static struct ot_hdlc_rcp_context { struct net_if *iface; struct openthread_context *ot_context; -}; +} ot_hdlc_rcp_ctx; /* -------------------------------------------------------------------------- */ /* Private prototypes */ /* -------------------------------------------------------------------------- */ -extern int32_t hdlc_rcp_if_handler(void); -extern int32_t hdlc_rcp_if_wakeup_done_handler(void); /* -------------------------------------------------------------------------- */ /* Private functions */ @@ -59,15 +52,6 @@ static void hdlc_iface_init(struct net_if *iface) struct ot_hdlc_rcp_context *ctx = net_if_get_device(iface)->data; otExtAddress eui64; - /* HDLC RCP interface Interrupt */ - IRQ_CONNECT(HDLC_RCP_IF_IRQ_N, HDLC_RCP_IF_IRQ_P, hdlc_rcp_if_handler, 0, 0); - irq_enable(HDLC_RCP_IF_IRQ_N); - - /* Wake up done interrupt */ - IRQ_CONNECT(HDLC_RCP_IF_WAKEUP_IRQ_N, HDLC_RCP_IF_WAKEUP_IRQ_P, - hdlc_rcp_if_wakeup_done_handler, 0, 0); - irq_enable(HDLC_RCP_IF_WAKEUP_IRQ_N); - ctx->iface = iface; ieee802154_init(iface); @@ -127,7 +111,7 @@ static const struct hdlc_api nxp_hdlc_api = { NET_DEVICE_DT_INST_DEFINE(0, NULL, /* Initialization Function */ NULL, /* No PM API support */ - NULL, /* No context data */ + &ot_hdlc_rcp_ctx, /* HDLC RCP context data */ NULL, /* Configuration info */ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, /* Initial priority */ &nxp_hdlc_api, /* API interface functions */ diff --git a/drivers/hdlc_rcp_if/hdlc_rcp_if_uart.c b/drivers/hdlc_rcp_if/hdlc_rcp_if_uart.c new file mode 100644 index 0000000000000..0157f4f369397 --- /dev/null +++ b/drivers/hdlc_rcp_if/hdlc_rcp_if_uart.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2024 DENX Software Engineering GmbH + * Lukasz Majewski + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * IEEE 802.15.4 HDLC RCP interface - serial communication interface (UART) + */ + +/* -------------------------------------------------------------------------- */ +/* Includes */ +/* -------------------------------------------------------------------------- */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* -------------------------------------------------------------------------- */ +/* Definitions */ +/* -------------------------------------------------------------------------- */ + +#define DT_DRV_COMPAT uart_hdlc_rcp_if + +#define LOG_MODULE_NAME hdlc_rcp_if_uart +#define LOG_LEVEL CONFIG_HDLC_RCP_IF_DRIVER_LOG_LEVEL +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +struct openthread_uart { + struct k_work work; + struct ring_buf *rx_ringbuf; + struct ring_buf *tx_ringbuf; + const struct device *dev; + atomic_t tx_busy; + + hdlc_rx_callback_t cb; + void *param; +}; + +#define OT_UART_DEFINE(_name, _ringbuf_rx_size, _ringbuf_tx_size) \ + RING_BUF_DECLARE(_name##_rx_ringbuf, _ringbuf_rx_size); \ + RING_BUF_DECLARE(_name##_tx_ringbuf, _ringbuf_tx_size); \ + static struct openthread_uart _name = { \ + .rx_ringbuf = &_name##_rx_ringbuf, \ + .tx_ringbuf = &_name##_tx_ringbuf, \ + } +OT_UART_DEFINE(ot_uart, CONFIG_OPENTHREAD_HDLC_RCP_IF_UART_RX_RING_BUFFER_SIZE, + CONFIG_OPENTHREAD_HDLC_RCP_IF_UART_TX_RING_BUFFER_SIZE); + +static struct ot_hdlc_rcp_context { + struct net_if *iface; + struct openthread_context *ot_context; +} ot_hdlc_rcp_ctx; + +/* -------------------------------------------------------------------------- */ +/* Private functions */ +/* -------------------------------------------------------------------------- */ + +static void ot_uart_rx_cb(struct k_work *item) +{ + struct openthread_uart *otuart = + CONTAINER_OF(item, struct openthread_uart, work); + uint8_t *data; + uint32_t len; + + len = ring_buf_get_claim(otuart->rx_ringbuf, &data, + otuart->rx_ringbuf->size); + if (len > 0) { + otuart->cb(data, len, otuart->param); + ring_buf_get_finish(otuart->rx_ringbuf, len); + } +} + +static void uart_tx_handle(const struct device *dev) +{ + uint32_t tx_len = 0, len; + uint8_t *data; + + len = ring_buf_get_claim( + ot_uart.tx_ringbuf, &data, + ot_uart.tx_ringbuf->size); + if (len > 0) { + tx_len = uart_fifo_fill(dev, data, len); + int err = ring_buf_get_finish(ot_uart.tx_ringbuf, tx_len); + (void)err; + __ASSERT_NO_MSG(err == 0); + } else { + uart_irq_tx_disable(dev); + } +} + +static void uart_rx_handle(const struct device *dev) +{ + uint32_t rd_len = 0, len; + uint8_t *data; + + len = ring_buf_put_claim( + ot_uart.rx_ringbuf, &data, + ot_uart.rx_ringbuf->size); + if (len > 0) { + rd_len = uart_fifo_read(dev, data, len); + + int err = ring_buf_put_finish(ot_uart.rx_ringbuf, rd_len); + (void)err; + __ASSERT_NO_MSG(err == 0); + } +} + +static void uart_callback(const struct device *dev, void *user_data) +{ + ARG_UNUSED(user_data); + + while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { + if (uart_irq_rx_ready(dev)) { + uart_rx_handle(dev); + } + + if (uart_irq_tx_ready(dev)) { + uart_tx_handle(dev); + } + } + + if (ring_buf_size_get(ot_uart.rx_ringbuf) > 0) { + k_work_submit(&ot_uart.work); + } +} + +static void hdlc_iface_init(struct net_if *iface) +{ + struct ot_hdlc_rcp_context *ctx = net_if_get_device(iface)->data; + otExtAddress eui64; + + ot_uart.dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_ot_uart)); + + if (!device_is_ready(ot_uart.dev)) { + LOG_ERR("UART device not ready"); + } + + uart_irq_callback_user_data_set(ot_uart.dev, + uart_callback, + (void *)&ot_uart); + + ctx->iface = iface; + ieee802154_init(iface); + ctx->ot_context = net_if_l2_data(iface); + + otPlatRadioGetIeeeEui64(ctx->ot_context->instance, eui64.m8); + net_if_set_link_addr(iface, eui64.m8, OT_EXT_ADDRESS_SIZE, + NET_LINK_IEEE802154); +} + +static int hdlc_register_rx_cb(hdlc_rx_callback_t hdlc_rx_callback, void *param) +{ + ot_uart.cb = hdlc_rx_callback; + ot_uart.param = param; + + k_work_init(&ot_uart.work, ot_uart_rx_cb); + uart_irq_rx_enable(ot_uart.dev); + + return 0; +} + +static int hdlc_send(const uint8_t *frame, uint16_t length) +{ + uint32_t ret; + + if (frame == NULL) { + return -EIO; + } + + ret = ring_buf_put(ot_uart.tx_ringbuf, frame, length); + uart_irq_tx_enable(ot_uart.dev); + + if (ret < length) { + LOG_WRN("Cannot store full frame to RB (%d < %d)", ret, length); + return -EIO; + } + + return 0; +} + +static int hdlc_deinit(void) +{ + uart_irq_tx_disable(ot_uart.dev); + uart_irq_rx_disable(ot_uart.dev); + + ring_buf_reset(ot_uart.rx_ringbuf); + ring_buf_reset(ot_uart.tx_ringbuf); + + return 0; +} + +static const struct hdlc_api uart_hdlc_api = { + .iface_api.init = hdlc_iface_init, + .register_rx_cb = hdlc_register_rx_cb, + .send = hdlc_send, + .deinit = hdlc_deinit, +}; + +#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(OPENTHREAD_L2) + +#define MTU 1280 + +NET_DEVICE_DT_INST_DEFINE(0, NULL, /* Initialization Function */ + NULL, /* No PM API support */ + &ot_hdlc_rcp_ctx, /* HDLC RCP context data */ + NULL, /* Configuration info */ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, /* Initial priority */ + &uart_hdlc_api, /* API interface functions */ + OPENTHREAD_L2, /* Openthread L2 */ + NET_L2_GET_CTX_TYPE(OPENTHREAD_L2), /* Openthread L2 context type */ + MTU); /* MTU size */ diff --git a/drivers/hwinfo/CMakeLists.txt b/drivers/hwinfo/CMakeLists.txt index e6db830d86532..bfabe8c8bb65d 100644 --- a/drivers/hwinfo/CMakeLists.txt +++ b/drivers/hwinfo/CMakeLists.txt @@ -16,6 +16,7 @@ zephyr_library_sources_ifdef(CONFIG_HWINFO_ESP32 hwinfo_esp32.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_GECKO hwinfo_gecko.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_IMXRT hwinfo_imxrt.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_LITEX hwinfo_litex.c) +zephyr_library_sources_ifdef(CONFIG_HWINFO_MAX32 hwinfo_max32.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_MCUX_RCM hwinfo_mcux_rcm.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_MCUX_SIM hwinfo_mcux_sim.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_MCUX_SRC hwinfo_mcux_src.c) @@ -31,6 +32,7 @@ zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM hwinfo_sam.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM0 hwinfo_sam0.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM4L hwinfo_sam4l.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM_RSTC hwinfo_sam_rstc.c) +zephyr_library_sources_ifdef(CONFIG_HWINFO_SILABS_S2 hwinfo_silabs_series2.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SMARTBOND hwinfo_smartbond.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_STM32 hwinfo_stm32.c) # zephyr-keep-sorted-stop diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index df1747a8e93e7..dca4ca30d0ca4 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -122,7 +122,7 @@ config HWINFO_MCUX_SYSCON config HWINFO_IMXRT bool "NXP i.mx RT device ID" default y - depends on SOC_SERIES_IMXRT10XX || SOC_SERIES_IMXRT11XX + depends on SOC_SERIES_IMXRT10XX || SOC_SERIES_IMXRT11XX || SOC_SERIES_IMXRT118X select HWINFO_HAS_DRIVER help Enable NXP i.mx RT hwinfo driver. @@ -130,7 +130,7 @@ config HWINFO_IMXRT config HWINFO_RPI_PICO bool "Raspberry Pi Pico hwinfo driver" default y - depends on SOC_SERIES_RP2XXX + depends on SOC_FAMILY_RPI_PICO select HWINFO_HAS_DRIVER select PICOSDK_USE_FLASH help @@ -204,14 +204,21 @@ config HWINFO_PSOC6 config HWINFO_GECKO bool "GECKO hwinfo" default y - depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 - depends on !SOC_SERIES_EFR32MG21 - depends on !SOC_SERIES_EFR32BG22 + depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 select HWINFO_HAS_DRIVER select SOC_GECKO_RMU help Enable Silabs GECKO hwinfo driver. +config HWINFO_SILABS_S2 + bool "Silabs Series 2 hwinfo" + default y + depends on SOC_FAMILY_SILABS_S2 + select HWINFO_HAS_DRIVER + select SOC_GECKO_RMU + help + Enable Silabs Series 2 hwinfo driver. + config HWINFO_ANDES bool "Andes system ID" default y @@ -257,4 +264,13 @@ config HWINFO_NUMAKER_RMC help Enable Nuvoton NuMaker hwinfo driver backed up by RMC +config HWINFO_MAX32 + bool "MAX32 hwinfo" + default y + depends on SOC_FAMILY_MAX32 + depends on !TRUSTED_EXECUTION_NONSECURE + select HWINFO_HAS_DRIVER + help + Enable MAX32 hwinfo driver. + endif diff --git a/drivers/hwinfo/hwinfo_imxrt.c b/drivers/hwinfo/hwinfo_imxrt.c index ea748482f76d7..ef6ae27fa15ef 100644 --- a/drivers/hwinfo/hwinfo_imxrt.c +++ b/drivers/hwinfo/hwinfo_imxrt.c @@ -10,7 +10,11 @@ #include struct imxrt_uid { +#if CONFIG_SOC_SERIES_IMXRT118X + uint32_t id[4]; +#else uint32_t id[2]; +#endif }; ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) @@ -20,6 +24,11 @@ ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) #ifdef CONFIG_SOC_SERIES_IMXRT11XX dev_id.id[0] = sys_cpu_to_be32(OCOTP->FUSEN[17].FUSE); dev_id.id[1] = sys_cpu_to_be32(OCOTP->FUSEN[16].FUSE); +#elif CONFIG_SOC_SERIES_IMXRT118X + dev_id.id[0] = sys_cpu_to_be32(OCOTP_FSB->OTP_SHADOW_PARTA[15]); + dev_id.id[1] = sys_cpu_to_be32(OCOTP_FSB->OTP_SHADOW_PARTA[14]); + dev_id.id[2] = sys_cpu_to_be32(OCOTP_FSB->OTP_SHADOW_PARTA[13]); + dev_id.id[3] = sys_cpu_to_be32(OCOTP_FSB->OTP_SHADOW_PARTA[12]); #else dev_id.id[0] = sys_cpu_to_be32(OCOTP->CFG2); dev_id.id[1] = sys_cpu_to_be32(OCOTP->CFG1); diff --git a/drivers/hwinfo/hwinfo_max32.c b/drivers/hwinfo/hwinfo_max32.c new file mode 100644 index 0000000000000..e0ec75dd72259 --- /dev/null +++ b/drivers/hwinfo/hwinfo_max32.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) +{ + uint8_t usn[MXC_SYS_USN_LEN]; + int error; + + error = Wrap_MXC_SYS_GetUSN(usn); + if (error != E_NO_ERROR) { + /* Error reading USN */ + return error; + } + + if (length > sizeof(usn)) { + length = sizeof(usn); + } + + /* Provide device ID in big endian */ + sys_memcpy_swap(buffer, usn, length); + + return length; +} diff --git a/drivers/hwinfo/hwinfo_nrf.c b/drivers/hwinfo/hwinfo_nrf.c index d1fca5350a6e1..f5a6ed38a20f9 100644 --- a/drivers/hwinfo/hwinfo_nrf.c +++ b/drivers/hwinfo/hwinfo_nrf.c @@ -8,8 +8,13 @@ #include #include #include -#if !defined(CONFIG_SOC_SERIES_NRF54HX) && !defined(CONFIG_BOARD_QEMU_CORTEX_M0) +#if defined(CONFIG_BOARD_QEMU_CORTEX_M0) || \ + (defined(CONFIG_NRF_PLATFORM_HALTIUM) && \ + defined(CONFIG_RISCV_CORE_NORDIC_VPR)) +#define RESET_CAUSE_AVAILABLE 0 +#else #include +#define RESET_CAUSE_AVAILABLE 1 #endif #if defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) && defined(NRF_FICR_S) @@ -36,7 +41,7 @@ ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) buf[1] = nrf_ficr_deviceid_get(NRF_FICR, 1); #endif #elif NRF_FICR_HAS_DEVICE_ADDR || NRF_FICR_HAS_BLE_ADDR - /* DEVICEID is not accessible, use device/ble address instead. + /* DEVICEID is not accessible, use device/Bluetooth LE address instead. * Assume that it is always accessible from the non-secure image. */ buf[0] = nrf_ficr_deviceaddr_get(NRF_FICR, 0); @@ -63,7 +68,30 @@ ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) return length; } -#if !defined(CONFIG_SOC_SERIES_NRF54HX) && !defined(CONFIG_BOARD_QEMU_CORTEX_M0) +#if RESET_CAUSE_AVAILABLE + +#if defined(NRF_RESETINFO) + +#define REASON_LOCKUP (NRFX_RESET_REASON_LOCKUP_MASK | NRFX_RESET_REASON_LOCAL_LOCKUP_MASK) +#define REASON_SOFTWARE (NRFX_RESET_REASON_SREQ_MASK | NRFX_RESET_REASON_LOCAL_SREQ_MASK) +#define REASON_WATCHDOG \ + (NRFX_RESET_REASON_DOG_MASK | \ + NRFX_RESET_REASON_LOCAL_DOG1_MASK | \ + NRFX_RESET_REASON_LOCAL_DOG0_MASK) + +#else /* NRF_RESETINFO */ + +#define REASON_LOCKUP NRFX_RESET_REASON_LOCKUP_MASK +#define REASON_SOFTWARE NRFX_RESET_REASON_SREQ_MASK + +#if NRF_POWER_HAS_RESETREAS +#define REASON_WATCHDOG NRFX_RESET_REASON_DOG_MASK +#else +#define REASON_WATCHDOG (NRFX_RESET_REASON_DOG0_MASK | NRFX_RESET_REASON_DOG1_MASK) +#endif /* NRF_POWER_HAS_RESETREAS */ + +#endif /* NRF_RESETINFO */ + int z_impl_hwinfo_get_reset_cause(uint32_t *cause) { uint32_t flags = 0; @@ -73,19 +101,21 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) if (reason & NRFX_RESET_REASON_RESETPIN_MASK) { flags |= RESET_PIN; } - if (reason & NRFX_RESET_REASON_DOG_MASK) { + if (reason & REASON_WATCHDOG) { flags |= RESET_WATCHDOG; } - if (reason & NRFX_RESET_REASON_LOCKUP_MASK) { + + if (reason & REASON_LOCKUP) { flags |= RESET_CPU_LOCKUP; } + if (reason & NRFX_RESET_REASON_OFF_MASK) { flags |= RESET_LOW_POWER_WAKE; } if (reason & NRFX_RESET_REASON_DIF_MASK) { flags |= RESET_DEBUG; } - if (reason & NRFX_RESET_REASON_SREQ_MASK) { + if (reason & REASON_SOFTWARE) { flags |= RESET_SOFTWARE; } @@ -124,11 +154,7 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) flags |= RESET_DEBUG; } #endif -#if !NRF_POWER_HAS_RESETREAS - if (reason & NRFX_RESET_REASON_DOG1_MASK) { - flags |= RESET_WATCHDOG; - } -#endif + #if NRFX_RESET_REASON_HAS_GRTC if (reason & NRFX_RESET_REASON_GRTC_MASK) { flags |= RESET_CLOCK; @@ -147,6 +173,7 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) if (reason & NRFX_RESET_REASON_LCTRLAP_MASK) { flags |= RESET_DEBUG; } + #endif #if defined(NRFX_RESET_REASON_TAMPC_MASK) if (reason & NRFX_RESET_REASON_TAMPC_MASK) { @@ -184,4 +211,4 @@ int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) return 0; } -#endif +#endif /* RESET_CAUSE_AVAILABLE */ diff --git a/drivers/hwinfo/hwinfo_rpi_pico.c b/drivers/hwinfo/hwinfo_rpi_pico.c index 89d5cb5654cda..b83078e4b494b 100644 --- a/drivers/hwinfo/hwinfo_rpi_pico.c +++ b/drivers/hwinfo/hwinfo_rpi_pico.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Yonatan Schachter + * Copyright (c) 2024 Andrew Featherstone * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,13 +8,23 @@ #include #include #include +#if defined(CONFIG_SOC_SERIES_RP2040) #include +#else +#include +#endif #define FLASH_RUID_DATA_BYTES 8 +#if defined(CONFIG_SOC_SERIES_RP2040) #define HAD_RUN_BIT BIT(VREG_AND_CHIP_RESET_CHIP_RESET_HAD_RUN_LSB) #define HAD_PSM_RESTART_BIT BIT(VREG_AND_CHIP_RESET_CHIP_RESET_HAD_PSM_RESTART_LSB) #define HAD_POR_BIT BIT(VREG_AND_CHIP_RESET_CHIP_RESET_HAD_POR_LSB) +#else +#define HAD_RUN_BIT BIT(POWMAN_CHIP_RESET_HAD_RUN_LOW_LSB) +#define HAD_PSM_RESTART_BIT BIT(POWMAN_CHIP_RESET_HAD_DP_RESET_REQ_LSB) +#define HAD_POR_BIT BIT(POWMAN_CHIP_RESET_HAD_POR_LSB) +#endif ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) { @@ -41,7 +52,11 @@ ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) int z_impl_hwinfo_get_reset_cause(uint32_t *cause) { uint32_t flags = 0; +#if defined(CONFIG_SOC_SERIES_RP2040) uint32_t reset_register = vreg_and_chip_reset_hw->chip_reset; +#else + uint32_t reset_register = powman_hw->chip_reset; +#endif if (reset_register & HAD_POR_BIT) { flags |= RESET_POR; @@ -54,6 +69,18 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) if (reset_register & HAD_PSM_RESTART_BIT) { flags |= RESET_DEBUG; } +#if defined(CONFIG_SOC_SERIES_RP2350) + if (reset_register & POWMAN_CHIP_RESET_HAD_BOR_BITS) { + flags |= RESET_BROWNOUT; + } + + if (reset_register & (POWMAN_CHIP_RESET_HAD_WATCHDOG_RESET_RSM_BITS | + POWMAN_CHIP_RESET_HAD_WATCHDOG_RESET_SWCORE_BITS | + POWMAN_CHIP_RESET_HAD_WATCHDOG_RESET_POWMAN_BITS | + POWMAN_CHIP_RESET_HAD_WATCHDOG_RESET_POWMAN_ASYNC_BITS)) { + flags |= RESET_WATCHDOG; + } +#endif *cause = flags; return 0; @@ -69,6 +96,9 @@ int z_impl_hwinfo_clear_reset_cause(void) int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) { *supported = RESET_PIN | RESET_DEBUG | RESET_POR; +#if defined(CONFIG_SOC_SERIES_RP2350) + *supported |= RESET_BROWNOUT | RESET_WATCHDOG; +#endif return 0; } diff --git a/drivers/hwinfo/hwinfo_silabs_series2.c b/drivers/hwinfo/hwinfo_silabs_series2.c new file mode 100644 index 0000000000000..bb7b45d9fe9a7 --- /dev/null +++ b/drivers/hwinfo/hwinfo_silabs_series2.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include +#include + +/* Ensure that all possible reset causes have a definition */ +#ifndef EMU_RSTCAUSE_BOOSTON +#define EMU_RSTCAUSE_BOOSTON 0 +#endif +#ifndef EMU_RSTCAUSE_WDOG1 +#define EMU_RSTCAUSE_WDOG1 0 +#endif +#ifndef EMU_RSTCAUSE_IOVDD1BOD +#define EMU_RSTCAUSE_IOVDD1BOD 0 +#endif +#ifndef EMU_RSTCAUSE_IOVDD2BOD +#define EMU_RSTCAUSE_IOVDD2BOD 0 +#endif +#ifndef EMU_RSTCAUSE_SETAMPER +#define EMU_RSTCAUSE_SETAMPER 0 +#endif +#ifndef EMU_RSTCAUSE_SESYSREQ +#define EMU_RSTCAUSE_SESYSREQ 0 +#endif +#ifndef EMU_RSTCAUSE_SELOCKUP +#define EMU_RSTCAUSE_SELOCKUP 0 +#endif +#ifndef EMU_RSTCAUSE_DCI +#define EMU_RSTCAUSE_DCI 0 +#endif + +/* The Zephyr API expects hwinfo_get_reset_cause() to return 0 after hwinfo_clear_reset_cause() has + * been called. This matches the hardware behavior on Series 2, but not the HAL API. The HAL stores + * the reset cause upon first read, and returns this cached value on subsequent calls to the API + * to allow multiple subsystems to read the reset cause despite it having been cleared in hardware + * already. Emulate the hardware behavior while staying compatible with other users of the HAL API + * by keeping track of whether the reset cause should be considered cleared or not ourselves. + */ +static bool reset_cleared; + +ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) +{ + uint64_t unique_id = sys_cpu_to_be64(SYSTEM_GetUnique()); + + if (length > sizeof(unique_id)) { + length = sizeof(unique_id); + } + + memcpy(buffer, &unique_id, length); + + return length; +} + +int z_impl_hwinfo_get_reset_cause(uint32_t *cause) +{ + uint32_t flags = 0; + uint32_t rmu = RMU_ResetCauseGet(); + + if (reset_cleared) { + *cause = 0; + return 0; + } + + if (rmu & EMU_RSTCAUSE_POR) { + flags |= RESET_POR; + } + + if (rmu & EMU_RSTCAUSE_PIN) { + flags |= RESET_PIN; + } + + if (rmu & (EMU_RSTCAUSE_EM4 | EMU_RSTCAUSE_BOOSTON)) { + flags |= RESET_LOW_POWER_WAKE; + } + + if (rmu & (EMU_RSTCAUSE_WDOG0 | EMU_RSTCAUSE_WDOG1)) { + flags |= RESET_WATCHDOG; + } + + if (rmu & EMU_RSTCAUSE_LOCKUP) { + flags |= RESET_CPU_LOCKUP; + } + + if (rmu & EMU_RSTCAUSE_SYSREQ) { + flags |= RESET_SOFTWARE; + } + + if (rmu & (EMU_RSTCAUSE_DVDDBOD | EMU_RSTCAUSE_DVDDLEBOD | EMU_RSTCAUSE_DECBOD | + EMU_RSTCAUSE_AVDDBOD | EMU_RSTCAUSE_IOVDD0BOD | + EMU_RSTCAUSE_IOVDD1BOD | EMU_RSTCAUSE_IOVDD2BOD)) { + flags |= RESET_BROWNOUT; + } + + if (rmu & (EMU_RSTCAUSE_SETAMPER | EMU_RSTCAUSE_SESYSREQ | + EMU_RSTCAUSE_SELOCKUP | EMU_RSTCAUSE_DCI)) { + flags |= RESET_SECURITY; + } + + *cause = flags; + return 0; +} + +int z_impl_hwinfo_clear_reset_cause(void) +{ + RMU_ResetCauseClear(); + reset_cleared = true; + return 0; +} + +int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) +{ + *supported = RESET_PIN | RESET_SOFTWARE | RESET_BROWNOUT | RESET_POR | RESET_WATCHDOG | + RESET_SECURITY | RESET_LOW_POWER_WAKE | RESET_CPU_LOCKUP; + return 0; +} diff --git a/drivers/i2c/CMakeLists.txt b/drivers/i2c/CMakeLists.txt index 25a68ea5f8ffa..6419417db1c86 100644 --- a/drivers/i2c/CMakeLists.txt +++ b/drivers/i2c/CMakeLists.txt @@ -6,107 +6,94 @@ zephyr_library() zephyr_library_sources(i2c_common.c) +# zephyr-keep-sorted-start +zephyr_library_sources_ifdef(CONFIG_GPIO_I2C_SWITCH gpio_i2c_switch.c) +zephyr_library_sources_ifdef(CONFIG_I2C_BITBANG i2c_bitbang.c) +zephyr_library_sources_ifdef(CONFIG_I2C_EMUL i2c_emul.c) +zephyr_library_sources_ifdef(CONFIG_I2C_GPIO i2c_gpio.c) zephyr_library_sources_ifdef(CONFIG_I2C_RTIO i2c_rtio.c i2c_rtio_default.c -) + ) zephyr_library_sources_ifdef(CONFIG_I2C_SHELL i2c_shell.c) -zephyr_library_sources_ifdef(CONFIG_I2C_BITBANG i2c_bitbang.c) -zephyr_library_sources_ifdef(CONFIG_I2C_TELINK_B91 i2c_b91.c) -zephyr_library_sources_ifdef(CONFIG_I2C_IPROC i2c_bcm_iproc.c) -zephyr_library_sources_ifdef(CONFIG_I2C_CC13XX_CC26XX i2c_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_I2C_TEST i2c_test.c) +zephyr_library_sources_ifdef(CONFIG_USERSPACE i2c_handlers.c) +# zephyr-keep-sorted-stop + +add_subdirectory_ifdef(CONFIG_I2C_TARGET target) + +# zephyr-keep-sorted-start +zephyr_library_sources_ifdef(CONFIG_I2C_AMBIQ i2c_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_I2C_ANDES_ATCIIC100 i2c_andes_atciic100.c) +zephyr_library_sources_ifdef(CONFIG_I2C_CC13XX_CC26XX i2c_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_I2C_CC32XX i2c_cc32xx.c) +zephyr_library_sources_ifdef(CONFIG_I2C_DW i2c_dw.c) +zephyr_library_sources_ifdef(CONFIG_I2C_ENE_KB1200 i2c_ene_kb1200.c) zephyr_library_sources_ifdef(CONFIG_I2C_ESP32 i2c_esp32.c) -zephyr_library_sources_ifdef(CONFIG_I2C_GPIO i2c_gpio.c) -zephyr_library_sources_ifdef(CONFIG_I2C_ITE_IT8XXX2 i2c_ite_it8xxx2.c) -zephyr_library_sources_ifdef(CONFIG_I2C_ITE_ENHANCE i2c_ite_enhance.c) +zephyr_library_sources_ifdef(CONFIG_I2C_GD32 i2c_gd32.c) +zephyr_library_sources_ifdef(CONFIG_I2C_GECKO i2c_gecko.c) zephyr_library_sources_ifdef(CONFIG_I2C_IMX i2c_imx.c) -zephyr_library_sources_ifdef(CONFIG_I2C_LPC11U6X i2c_lpc11u6x.c) -zephyr_library_sources_ifdef(CONFIG_I2C_XEC i2c_mchp_xec.c) +zephyr_library_sources_ifdef(CONFIG_I2C_INFINEON_CAT1 i2c_ifx_cat1.c) +zephyr_library_sources_ifdef(CONFIG_I2C_INFINEON_XMC4 i2c_ifx_xmc4.c) +zephyr_library_sources_ifdef(CONFIG_I2C_IPROC i2c_bcm_iproc.c) +zephyr_library_sources_ifdef(CONFIG_I2C_ITE_ENHANCE i2c_ite_enhance.c) +zephyr_library_sources_ifdef(CONFIG_I2C_ITE_IT8XXX2 i2c_ite_it8xxx2.c) +zephyr_library_sources_ifdef(CONFIG_I2C_LITEX i2c_litex.c) +zephyr_library_sources_ifdef(CONFIG_I2C_LPC11U6X i2c_lpc11u6x.c) +zephyr_library_sources_ifdef(CONFIG_I2C_MCHP_MSS i2c_mchp_mss.c) zephyr_library_sources_ifdef(CONFIG_I2C_MCUX i2c_mcux.c) zephyr_library_sources_ifdef(CONFIG_I2C_MCUX_FLEXCOMM i2c_mcux_flexcomm.c) - -if(CONFIG_I2C_RTIO) - zephyr_library_sources_ifdef(CONFIG_I2C_MCUX_LPI2C i2c_mcux_lpi2c_rtio.c) -else() - zephyr_library_sources_ifdef(CONFIG_I2C_MCUX_LPI2C i2c_mcux_lpi2c.c) -endif() - -zephyr_library_sources_ifdef(CONFIG_I2C_EMUL i2c_emul.c) - -if(CONFIG_I2C_RTIO) - zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWI - i2c_nrfx_twi_rtio.c - i2c_nrfx_twi_common.c - ) -else() - zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWI - i2c_nrfx_twi.c - i2c_nrfx_twi_common.c - ) -endif() - -if(CONFIG_I2C_RTIO) - zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIM - i2c_nrfx_twim_rtio.c - i2c_nrfx_twim_common.c - ) -else() - zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIM - i2c_nrfx_twim.c - i2c_nrfx_twim_common.c - ) -endif() -zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWI i2c_sam_twi.c) - -if(CONFIG_I2C_RTIO) - zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWIHS i2c_sam_twihs_rtio.c) -else() - zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWIHS i2c_sam_twihs.c) -endif() - -zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWIM i2c_sam4l_twim.c) -zephyr_library_sources_ifdef(CONFIG_I2C_SBCON i2c_sbcon.c) -zephyr_library_sources_ifdef(CONFIG_I2C_SIFIVE i2c_sifive.c) zephyr_library_sources_ifdef(CONFIG_I2C_NIOS2 i2c_nios2.c) -zephyr_library_sources_ifdef(CONFIG_I2C_GECKO i2c_gecko.c) -zephyr_library_sources_ifdef(CONFIG_I2C_RV32M1_LPI2C i2c_rv32m1_lpi2c.c) -zephyr_library_sources_ifdef(CONFIG_I2C_SAM0 i2c_sam0.c) -zephyr_library_sources_ifdef(CONFIG_I2C_LITEX i2c_litex.c) zephyr_library_sources_ifdef(CONFIG_I2C_NPCX i2c_npcx_controller.c) zephyr_library_sources_ifdef(CONFIG_I2C_NPCX i2c_npcx_port.c) -zephyr_library_sources_ifdef(CONFIG_I2C_DW i2c_dw.c) +zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIS i2c_nrfx_twis.c) +zephyr_library_sources_ifdef(CONFIG_I2C_NUMAKER i2c_numaker.c) +zephyr_library_sources_ifdef(CONFIG_I2C_NXP_II2C i2c_nxp_ii2c.c) +zephyr_library_sources_ifdef(CONFIG_I2C_OMAP i2c_omap.c) zephyr_library_sources_ifdef(CONFIG_I2C_RCAR i2c_rcar.c) -zephyr_library_sources_ifdef(CONFIG_I2C_TCA954X i2c_tca954x.c) -zephyr_library_sources_ifdef(CONFIG_I2C_XEC_V2 i2c_mchp_xec_v2.c) -zephyr_library_sources_ifdef(CONFIG_I2C_GD32 i2c_gd32.c) -zephyr_library_sources_ifdef(CONFIG_I2C_INFINEON_CAT1 i2c_ifx_cat1.c) -zephyr_library_sources_ifdef(CONFIG_I2C_INFINEON_XMC4 i2c_ifx_xmc4.c) -zephyr_library_sources_ifdef(CONFIG_I2C_ANDES_ATCIIC100 i2c_andes_atciic100.c) +zephyr_library_sources_ifdef(CONFIG_I2C_RENESAS_RA_IIC i2c_renesas_ra_iic.c) +zephyr_library_sources_ifdef(CONFIG_I2C_RV32M1_LPI2C i2c_rv32m1_lpi2c.c) +zephyr_library_sources_ifdef(CONFIG_I2C_SAM0 i2c_sam0.c) +zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWI i2c_sam_twi.c) +zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWIM i2c_sam4l_twim.c) +zephyr_library_sources_ifdef(CONFIG_I2C_SBCON i2c_sbcon.c) zephyr_library_sources_ifdef(CONFIG_I2C_SC18IM704 i2c_sc18im704.c) -zephyr_library_sources_ifdef(CONFIG_I2C_SMARTBOND i2c_smartbond.c) -zephyr_library_sources_ifdef(CONFIG_I2C_XILINX_AXI i2c_xilinx_axi.c) -zephyr_library_sources_ifdef(CONFIG_I2C_MCHP_MSS i2c_mchp_mss.c) zephyr_library_sources_ifdef(CONFIG_I2C_SEDI i2c_sedi.c) -zephyr_library_sources_ifdef(CONFIG_I2C_AMBIQ i2c_ambiq.c) -zephyr_library_sources_ifdef(CONFIG_I2C_ENE_KB1200 i2c_ene_kb1200.c) -zephyr_library_sources_ifdef(CONFIG_GPIO_I2C_SWITCH gpio_i2c_switch.c) -zephyr_library_sources_ifdef(CONFIG_I2C_NUMAKER i2c_numaker.c) -zephyr_library_sources_ifdef(CONFIG_I2C_MAX32 i2c_max32.c) - +zephyr_library_sources_ifdef(CONFIG_I2C_SIFIVE i2c_sifive.c) +zephyr_library_sources_ifdef(CONFIG_I2C_SMARTBOND i2c_smartbond.c) zephyr_library_sources_ifdef(CONFIG_I2C_STM32_V1 i2c_ll_stm32_v1.c i2c_ll_stm32.c - ) + ) zephyr_library_sources_ifdef(CONFIG_I2C_STM32_V2 i2c_ll_stm32_v2.c i2c_ll_stm32.c - ) - -zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_I2C_IIC i2c_renesas_ra_iic.c) - -zephyr_library_sources_ifdef(CONFIG_I2C_TEST i2c_test.c) - -zephyr_library_sources_ifdef(CONFIG_USERSPACE i2c_handlers.c) + ) +zephyr_library_sources_ifdef(CONFIG_I2C_TCA954X i2c_tca954x.c) +zephyr_library_sources_ifdef(CONFIG_I2C_TELINK_B91 i2c_b91.c) +zephyr_library_sources_ifdef(CONFIG_I2C_XEC i2c_mchp_xec.c) +zephyr_library_sources_ifdef(CONFIG_I2C_XEC_V2 i2c_mchp_xec_v2.c) +zephyr_library_sources_ifdef(CONFIG_I2C_XILINX_AXI i2c_xilinx_axi.c) +# zephyr-keep-sorted-stop -add_subdirectory_ifdef(CONFIG_I2C_TARGET target) +if(CONFIG_I2C_RTIO) + # zephyr-keep-sorted-start + zephyr_library_sources_ifdef(CONFIG_I2C_MAX32 i2c_max32_rtio.c) + zephyr_library_sources_ifdef(CONFIG_I2C_MCUX_LPI2C i2c_mcux_lpi2c_rtio.c) + zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWI i2c_nrfx_twi_common.c) + zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWI i2c_nrfx_twi_rtio.c) + zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIM i2c_nrfx_twim_common.c) + zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIM i2c_nrfx_twim_rtio.c) + zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWIHS i2c_sam_twihs_rtio.c) + # zephyr-keep-sorted-stop +else() + # zephyr-keep-sorted-start + zephyr_library_sources_ifdef(CONFIG_I2C_MAX32 i2c_max32.c) + zephyr_library_sources_ifdef(CONFIG_I2C_MCUX_LPI2C i2c_mcux_lpi2c.c) + zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWI i2c_nrfx_twi.c) + zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWI i2c_nrfx_twi_common.c) + zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIM i2c_nrfx_twim.c) + zephyr_library_sources_ifdef(CONFIG_I2C_NRFX_TWIM i2c_nrfx_twim_common.c) + zephyr_library_sources_ifdef(CONFIG_I2C_SAM_TWIHS i2c_sam_twihs.c) + # zephyr-keep-sorted-stop +endif() diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 4a9d34ffd2883..c1180acf51d6a 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -116,43 +116,46 @@ endif # I2C_RTIO # Include these first so that any properties (e.g. defaults) below can be # overridden (by defining symbols in multiple locations) +source "drivers/i2c/target/Kconfig" +# zephyr-keep-sorted-start +source "drivers/i2c/Kconfig.ambiq" +source "drivers/i2c/Kconfig.andes_atciic100" source "drivers/i2c/Kconfig.b91" source "drivers/i2c/Kconfig.bcm_iproc" source "drivers/i2c/Kconfig.cc13xx_cc26xx" source "drivers/i2c/Kconfig.dw" +source "drivers/i2c/Kconfig.ene" source "drivers/i2c/Kconfig.esp32" -source "drivers/i2c/target/Kconfig" +source "drivers/i2c/Kconfig.gd32" source "drivers/i2c/Kconfig.gpio" -source "drivers/i2c/Kconfig.xec" -source "drivers/i2c/Kconfig.nrfx" source "drivers/i2c/Kconfig.i2c_emul" +source "drivers/i2c/Kconfig.ifx_cat1" +source "drivers/i2c/Kconfig.ifx_xmc4" source "drivers/i2c/Kconfig.it8xxx2" -source "drivers/i2c/Kconfig.sbcon" -source "drivers/i2c/Kconfig.sifive" -source "drivers/i2c/Kconfig.stm32" -source "drivers/i2c/Kconfig.sam0" -source "drivers/i2c/Kconfig.sam_twihs" source "drivers/i2c/Kconfig.litex" source "drivers/i2c/Kconfig.lpc11u6x" +source "drivers/i2c/Kconfig.max32" +source "drivers/i2c/Kconfig.mchp_mss" +source "drivers/i2c/Kconfig.mcux" source "drivers/i2c/Kconfig.npcx" -source "drivers/i2c/Kconfig.test" +source "drivers/i2c/Kconfig.nrfx" +source "drivers/i2c/Kconfig.numaker" +source "drivers/i2c/Kconfig.omap" source "drivers/i2c/Kconfig.rcar" source "drivers/i2c/Kconfig.renesas_ra" -source "drivers/i2c/Kconfig.tca954x" -source "drivers/i2c/Kconfig.gd32" -source "drivers/i2c/Kconfig.ifx_cat1" -source "drivers/i2c/Kconfig.ifx_xmc4" -source "drivers/i2c/Kconfig.andes_atciic100" +source "drivers/i2c/Kconfig.sam0" +source "drivers/i2c/Kconfig.sam_twihs" +source "drivers/i2c/Kconfig.sbcon" source "drivers/i2c/Kconfig.sc18im704" +source "drivers/i2c/Kconfig.sedi" +source "drivers/i2c/Kconfig.sifive" source "drivers/i2c/Kconfig.smartbond" +source "drivers/i2c/Kconfig.stm32" +source "drivers/i2c/Kconfig.tca954x" +source "drivers/i2c/Kconfig.test" +source "drivers/i2c/Kconfig.xec" source "drivers/i2c/Kconfig.xilinx_axi" -source "drivers/i2c/Kconfig.mchp_mss" -source "drivers/i2c/Kconfig.sedi" -source "drivers/i2c/Kconfig.ambiq" -source "drivers/i2c/Kconfig.numaker" -source "drivers/i2c/Kconfig.mcux" -source "drivers/i2c/Kconfig.ene" -source "drivers/i2c/Kconfig.max32" +# zephyr-keep-sorted-stop config I2C_INIT_PRIORITY int "Init priority" @@ -258,4 +261,11 @@ config GPIO_I2C_SWITCH help Enable GPIO controlled I2C bus switch driver. +config I2C_NXP_II2C + bool "NXP i.MX8M serial I2C driver" + default y + depends on DT_HAS_NXP_II2C_ENABLED + help + Enable the NXP II2C driver. + endif # I2C diff --git a/drivers/i2c/Kconfig.b91 b/drivers/i2c/Kconfig.b91 index 932e4cc693d17..aa0bc1a89b989 100644 --- a/drivers/i2c/Kconfig.b91 +++ b/drivers/i2c/Kconfig.b91 @@ -5,5 +5,6 @@ config I2C_TELINK_B91 bool "Telink Semiconductor B91 I2C driver" default y depends on DT_HAS_TELINK_B91_I2C_ENABLED + select PINCTRL help Enables Telink B91 I2C driver. diff --git a/drivers/i2c/Kconfig.cc13xx_cc26xx b/drivers/i2c/Kconfig.cc13xx_cc26xx index d015fdc6e870c..a8ed30fb5b9b8 100644 --- a/drivers/i2c/Kconfig.cc13xx_cc26xx +++ b/drivers/i2c/Kconfig.cc13xx_cc26xx @@ -5,5 +5,6 @@ config I2C_CC13XX_CC26XX bool "TI SimpleLink CC13xx / CC26xx I2C driver" default y depends on DT_HAS_TI_CC13XX_CC26XX_I2C_ENABLED + select PINCTRL help Enable support for I2C on the TI SimpleLink CC13xx / CC26xx series. diff --git a/drivers/i2c/Kconfig.mcux b/drivers/i2c/Kconfig.mcux index f91876390147b..9a312ff66cd22 100644 --- a/drivers/i2c/Kconfig.mcux +++ b/drivers/i2c/Kconfig.mcux @@ -12,6 +12,13 @@ menuconfig I2C_MCUX_FLEXCOMM help Enable the mcux flexcomm i2c driver. +config I2C_MCUX_FLEXCOMM_BUS_RECOVERY + bool "Bus recovery support" + depends on I2C_MCUX_FLEXCOMM && PINCTRL + select I2C_BITBANG + help + Enable flexcomm i2c driver bus recovery support via GPIO bitbanging. + config I2C_NXP_TRANSFER_TIMEOUT int "Transfer timeout [ms]" default 0 diff --git a/drivers/i2c/Kconfig.nrfx b/drivers/i2c/Kconfig.nrfx index 6898d6e42a93e..2213175d5d60e 100644 --- a/drivers/i2c/Kconfig.nrfx +++ b/drivers/i2c/Kconfig.nrfx @@ -49,4 +49,33 @@ config I2C_NRFX_TRANSFER_TIMEOUT 0 means that the driver should use the K_FOREVER value, i.e. it should wait as long as necessary. +config I2C_NRFX_TWIS + def_bool y + depends on DT_HAS_NORDIC_NRF_TWIS_ENABLED + depends on I2C_TARGET + depends on I2C_TARGET_BUFFER_MODE + select NRFX_TWIS0 if HAS_HW_NRF_TWIS0 + select NRFX_TWIS1 if HAS_HW_NRF_TWIS1 + select NRFX_TWIS2 if HAS_HW_NRF_TWIS2 + select NRFX_TWIS3 if HAS_HW_NRF_TWIS3 + select NRFX_TWIS20 if HAS_HW_NRF_TWIS20 + select NRFX_TWIS21 if HAS_HW_NRF_TWIS21 + select NRFX_TWIS22 if HAS_HW_NRF_TWIS22 + select NRFX_TWIS30 if HAS_HW_NRF_TWIS30 + select NRFX_TWIS130 if HAS_HW_NRF_TWIS130 + select NRFX_TWIS131 if HAS_HW_NRF_TWIS131 + select NRFX_TWIS133 if HAS_HW_NRF_TWIS133 + select NRFX_TWIS134 if HAS_HW_NRF_TWIS134 + select NRFX_TWIS135 if HAS_HW_NRF_TWIS135 + select NRFX_TWIS136 if HAS_HW_NRF_TWIS136 + select NRFX_TWIS137 if HAS_HW_NRF_TWIS137 + +if I2C_NRFX_TWIS + +config I2C_NRFX_TWIS_BUF_SIZE + int "DMA buffer size in bytes" + default 64 + +endif # I2C_NRFX_TWIS + endif # I2C_NRFX diff --git a/drivers/i2c/Kconfig.omap b/drivers/i2c/Kconfig.omap new file mode 100644 index 0000000000000..4b7951eb0e83c --- /dev/null +++ b/drivers/i2c/Kconfig.omap @@ -0,0 +1,19 @@ +# Copyright (C) 2024 BeagleBoard.org Foundation +# Copyright (C) 2024 Dhruv Menon + +# SPDX-License-Identifier: Apache-2.0 + +config I2C_OMAP + bool "TI OMAP I2C Driver" + default y + depends on DT_HAS_TI_OMAP_I2C_ENABLED + select PINCTRL + help + Enable the I2C driver for TI OMAP SoCs. + +config I2C_OMAP_BUS_RECOVERY + bool "Bus recovery support" + depends on I2C_OMAP + select I2C_BITBANG + help + Enable OMAP I2C driver bus recovery support via bitbanging. diff --git a/drivers/i2c/Kconfig.renesas_ra b/drivers/i2c/Kconfig.renesas_ra index cf68b2a459767..a0cd23a6b6477 100644 --- a/drivers/i2c/Kconfig.renesas_ra +++ b/drivers/i2c/Kconfig.renesas_ra @@ -3,7 +3,7 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -config RENESAS_RA_I2C_IIC +config I2C_RENESAS_RA_IIC bool "Renesas RA I2C IIC Master" default y depends on DT_HAS_RENESAS_RA_IIC_ENABLED diff --git a/drivers/i2c/gpio_i2c_switch.c b/drivers/i2c/gpio_i2c_switch.c index 1564f37006679..a0b8166edbb72 100644 --- a/drivers/i2c/gpio_i2c_switch.c +++ b/drivers/i2c/gpio_i2c_switch.c @@ -64,7 +64,7 @@ static int gpio_i2c_switch_transfer(const struct device *dev, struct i2c_msg *ms return res; } -static const struct i2c_driver_api gpio_i2c_switch_api_funcs = { +static DEVICE_API(i2c, gpio_i2c_switch_api_funcs) = { .configure = gpio_i2c_switch_configure, .transfer = gpio_i2c_switch_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_ambiq.c b/drivers/i2c/i2c_ambiq.c index 69492b5a60861..50536a5dd5313 100644 --- a/drivers/i2c/i2c_ambiq.c +++ b/drivers/i2c/i2c_ambiq.c @@ -381,7 +381,7 @@ static int i2c_ambiq_init(const struct device *dev) return ret; } -static const struct i2c_driver_api i2c_ambiq_driver_api = { +static DEVICE_API(i2c, i2c_ambiq_driver_api) = { .configure = i2c_ambiq_configure, .transfer = i2c_ambiq_transfer, #if CONFIG_I2C_AMBIQ_BUS_RECOVERY diff --git a/drivers/i2c/i2c_andes_atciic100.c b/drivers/i2c/i2c_andes_atciic100.c index 3f1b4b9c3d289..60e39c040c60d 100644 --- a/drivers/i2c/i2c_andes_atciic100.c +++ b/drivers/i2c/i2c_andes_atciic100.c @@ -732,7 +732,7 @@ static void i2c_atciic100_irq_handler(void *arg) } } -static const struct i2c_driver_api i2c_atciic100_driver = { +static DEVICE_API(i2c, i2c_atciic100_driver) = { .configure = (i2c_api_configure_t)i2c_atciic100_configure, .transfer = (i2c_api_full_io_t)i2c_atciic100_transfer, #if defined(CONFIG_I2C_TARGET) diff --git a/drivers/i2c/i2c_b91.c b/drivers/i2c/i2c_b91.c index f7b25f54fd1e2..2681ef6e26fb4 100644 --- a/drivers/i2c/i2c_b91.c +++ b/drivers/i2c/i2c_b91.c @@ -147,7 +147,7 @@ static int i2c_b91_init(const struct device *dev) } /* I2C driver APIs structure */ -static const struct i2c_driver_api i2c_b91_api = { +static DEVICE_API(i2c, i2c_b91_api) = { .configure = i2c_b91_configure, .transfer = i2c_b91_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_bcm_iproc.c b/drivers/i2c/i2c_bcm_iproc.c index 18f6afb0ae68d..f424ab97e648d 100644 --- a/drivers/i2c/i2c_bcm_iproc.c +++ b/drivers/i2c/i2c_bcm_iproc.c @@ -916,7 +916,7 @@ static int iproc_i2c_init(const struct device *dev) return 0; } -static const struct i2c_driver_api iproc_i2c_driver_api = { +static DEVICE_API(i2c, iproc_i2c_driver_api) = { .configure = iproc_i2c_configure, .transfer = iproc_i2c_transfer_multi, #ifdef CONFIG_I2C_TARGET diff --git a/drivers/i2c/i2c_cc13xx_cc26xx.c b/drivers/i2c/i2c_cc13xx_cc26xx.c index d06ffe3c5cb6c..fdcd8f543abe3 100644 --- a/drivers/i2c/i2c_cc13xx_cc26xx.c +++ b/drivers/i2c/i2c_cc13xx_cc26xx.c @@ -40,153 +40,82 @@ struct i2c_cc13xx_cc26xx_config { const struct pinctrl_dev_config *pcfg; }; -static int i2c_cc13xx_cc26xx_transmit(const struct device *dev, - const uint8_t *buf, - uint32_t len, uint16_t addr) +static int i2c_cc13xx_cc26xx_transmit(const struct device *dev, const struct i2c_msg *msg, + const uint8_t addr) { const struct i2c_cc13xx_cc26xx_config *config = dev->config; const uint32_t base = config->base; struct i2c_cc13xx_cc26xx_data *data = dev->data; - /* Sending address without data is not supported */ - if (len == 0) { - return -EIO; - } - I2CMasterSlaveAddrSet(base, addr, false); - /* The following assumes a single master. Use I2CMasterBusBusy() if - * wanting to implement multiple master support. - */ - - /* Single transmission */ - if (len == 1) { - I2CMasterDataPut(base, *buf); + for (int i = 0; i < msg->len; i++) { + uint32_t command = I2C_MCTRL_RUN; - I2CMasterControl(base, I2C_MASTER_CMD_SINGLE_SEND); - - k_sem_take(&data->complete, K_FOREVER); - - return data->error == I2C_MASTER_ERR_NONE ? 0 : -EIO; - } - - /* Burst transmission */ - I2CMasterDataPut(base, buf[0]); - - I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_START); - - k_sem_take(&data->complete, K_FOREVER); - - if (data->error != I2C_MASTER_ERR_NONE) { - goto send_error_stop; - } - - for (int i = 1; i < len - 1; i++) { - I2CMasterDataPut(base, buf[i]); + if (i == 0 && msg->flags & I2C_MSG_RESTART) { + command |= I2C_MCTRL_START; + } - I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_CONT); + if (i == msg->len - 1 && msg->flags & I2C_MSG_STOP) { + command |= I2C_MCTRL_STOP; + } + I2CMasterDataPut(base, msg->buf[i]); + I2CMasterControl(base, command); k_sem_take(&data->complete, K_FOREVER); if (data->error != I2C_MASTER_ERR_NONE) { - goto send_error_stop; + if ((command & I2C_MCTRL_STOP) == 0) { + I2CMasterControl(base, I2C_MCTRL_STOP); + } + return -EIO; } } - I2CMasterDataPut(base, buf[len - 1]); - - I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_FINISH); - - k_sem_take(&data->complete, K_FOREVER); - - if (data->error != I2C_MASTER_ERR_NONE) { - return -EIO; - } - return 0; - -send_error_stop: - I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP); - return -EIO; } -static int i2c_cc13xx_cc26xx_receive(const struct device *dev, uint8_t *buf, - uint32_t len, - uint16_t addr) +static int i2c_cc13xx_cc26xx_receive(const struct device *dev, const struct i2c_msg *msg, + const uint8_t addr) { + struct i2c_cc13xx_cc26xx_data *data = dev->data; const struct i2c_cc13xx_cc26xx_config *config = dev->config; const uint32_t base = config->base; - struct i2c_cc13xx_cc26xx_data *data = dev->data; - - /* Sending address without data is not supported */ - if (len == 0) { - return -EIO; - } I2CMasterSlaveAddrSet(base, addr, true); - /* The following assumes a single master. Use I2CMasterBusBusy() if - * wanting to implement multiple master support. - */ - - /* Single receive */ - if (len == 1) { - I2CMasterControl(base, I2C_MASTER_CMD_SINGLE_RECEIVE); - - k_sem_take(&data->complete, K_FOREVER); + for (int i = 0; i < msg->len; i++) { + uint32_t command = I2C_MCTRL_RUN; - if (data->error != I2C_MASTER_ERR_NONE) { - return -EIO; + if (i == 0 && msg->flags & I2C_MSG_RESTART) { + command |= I2C_MCTRL_START; } - *buf = I2CMasterDataGet(base); - - return 0; - } - - /* Burst receive */ - I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_START); - - k_sem_take(&data->complete, K_FOREVER); - - if (data->error != I2C_MASTER_ERR_NONE) { - goto recv_error_stop; - } - - buf[0] = I2CMasterDataGet(base); + if (i == msg->len - 1 && msg->flags & I2C_MSG_STOP) { + command |= I2C_MCTRL_STOP; + } else if (i < msg->len - 1) { + command |= I2C_MCTRL_ACK; + } - for (int i = 1; i < len - 1; i++) { - I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_CONT); + I2CMasterControl(base, command); k_sem_take(&data->complete, K_FOREVER); if (data->error != I2C_MASTER_ERR_NONE) { - goto recv_error_stop; + if ((command & I2C_MCTRL_STOP) == 0) { + I2CMasterControl(base, I2C_MCTRL_STOP); + } + return -EIO; } - buf[i] = I2CMasterDataGet(base); - } - - I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); - - k_sem_take(&data->complete, K_FOREVER); - - if (data->error != I2C_MASTER_ERR_NONE) { - return -EIO; + msg->buf[i] = I2CMasterDataGet(base); } - buf[len - 1] = I2CMasterDataGet(base); - return 0; - -recv_error_stop: - I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP); - return -EIO; } -static int i2c_cc13xx_cc26xx_transfer(const struct device *dev, - struct i2c_msg *msgs, - uint8_t num_msgs, uint16_t addr) +static int i2c_cc13xx_cc26xx_transfer(const struct device *dev, struct i2c_msg *msgs, + const uint8_t num_msgs, const uint16_t addr) { struct i2c_cc13xx_cc26xx_data *data = dev->data; int ret = 0; @@ -195,6 +124,9 @@ static int i2c_cc13xx_cc26xx_transfer(const struct device *dev, return 0; } + /* Always a start condition in the first message */ + msgs[0].flags |= I2C_MSG_RESTART; + k_sem_take(&data->lock, K_FOREVER); pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); @@ -206,12 +138,16 @@ static int i2c_cc13xx_cc26xx_transfer(const struct device *dev, break; } + /* Sending address without data is not supported */ + if (msgs[i].len == 0) { + ret = -EIO; + break; + } + if ((msgs[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) { - ret = i2c_cc13xx_cc26xx_transmit(dev, msgs[i].buf, - msgs[i].len, addr); + ret = i2c_cc13xx_cc26xx_transmit(dev, &msgs[i], addr); } else { - ret = i2c_cc13xx_cc26xx_receive(dev, msgs[i].buf, - msgs[i].len, addr); + ret = i2c_cc13xx_cc26xx_receive(dev, &msgs[i], addr); } if (ret) { @@ -419,7 +355,7 @@ static int i2c_cc13xx_cc26xx_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_cc13xx_cc26xx_driver_api = { +static DEVICE_API(i2c, i2c_cc13xx_cc26xx_driver_api) = { .configure = i2c_cc13xx_cc26xx_configure, .transfer = i2c_cc13xx_cc26xx_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_cc32xx.c b/drivers/i2c/i2c_cc32xx.c index 57fee76179905..a5ce43b4a7aa4 100644 --- a/drivers/i2c/i2c_cc32xx.c +++ b/drivers/i2c/i2c_cc32xx.c @@ -379,7 +379,7 @@ static int i2c_cc32xx_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_cc32xx_driver_api = { +static DEVICE_API(i2c, i2c_cc32xx_driver_api) = { .configure = i2c_cc32xx_configure, .transfer = i2c_cc32xx_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_dw.c b/drivers/i2c/i2c_dw.c index 5d274dcf0adcd..2915a79debc66 100644 --- a/drivers/i2c/i2c_dw.c +++ b/drivers/i2c/i2c_dw.c @@ -739,6 +739,7 @@ static int i2c_dw_transfer(const struct device *dev, struct i2c_msg *msgs, uint8 static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config) { struct i2c_dw_dev_config *const dw = dev->data; + const struct i2c_dw_rom_config *const rom = dev->config; uint32_t value = 0U; uint32_t rc = 0U; uint32_t reg_base = get_regs(dev); @@ -752,10 +753,9 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config) /* Following the directions on DW spec page 59, IC_SS_SCL_LCNT * must have register values larger than IC_FS_SPKLEN + 7 */ - if (I2C_STD_LCNT <= (read_fs_spklen(reg_base) + 7)) { + value = I2C_STD_LCNT + rom->lcnt_offset; + if (value <= (read_fs_spklen(reg_base) + 7)) { value = read_fs_spklen(reg_base) + 8; - } else { - value = I2C_STD_LCNT; } dw->lcnt = value; @@ -763,10 +763,9 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config) /* Following the directions on DW spec page 59, IC_SS_SCL_HCNT * must have register values larger than IC_FS_SPKLEN + 5 */ - if (I2C_STD_HCNT <= (read_fs_spklen(reg_base) + 5)) { + value = I2C_STD_HCNT + rom->hcnt_offset; + if (value <= (read_fs_spklen(reg_base) + 5)) { value = read_fs_spklen(reg_base) + 6; - } else { - value = I2C_STD_HCNT; } dw->hcnt = value; @@ -776,10 +775,9 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config) * Following the directions on DW spec page 59, IC_FS_SCL_LCNT * must have register values larger than IC_FS_SPKLEN + 7 */ - if (I2C_FS_LCNT <= (read_fs_spklen(reg_base) + 7)) { + value = I2C_FS_LCNT + rom->lcnt_offset; + if (value <= (read_fs_spklen(reg_base) + 7)) { value = read_fs_spklen(reg_base) + 8; - } else { - value = I2C_FS_LCNT; } dw->lcnt = value; @@ -788,10 +786,9 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config) * Following the directions on DW spec page 59, IC_FS_SCL_HCNT * must have register values larger than IC_FS_SPKLEN + 5 */ - if (I2C_FS_HCNT <= (read_fs_spklen(reg_base) + 5)) { + value = I2C_FS_HCNT + rom->hcnt_offset; + if (value <= (read_fs_spklen(reg_base) + 5)) { value = read_fs_spklen(reg_base) + 6; - } else { - value = I2C_FS_HCNT; } dw->hcnt = value; @@ -801,10 +798,9 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config) * Following the directions on DW spec page 59, IC_FS_SCL_LCNT * must have register values larger than IC_FS_SPKLEN + 7 */ - if (I2C_FSP_LCNT <= (read_fs_spklen(reg_base) + 7)) { + value = I2C_FSP_LCNT + rom->lcnt_offset; + if (value <= (read_fs_spklen(reg_base) + 7)) { value = read_fs_spklen(reg_base) + 8; - } else { - value = I2C_FSP_LCNT; } dw->lcnt = value; @@ -813,28 +809,25 @@ static int i2c_dw_runtime_configure(const struct device *dev, uint32_t config) * Following the directions on DW spec page 59, IC_FS_SCL_HCNT * must have register values larger than IC_FS_SPKLEN + 5 */ - if (I2C_FSP_HCNT <= (read_fs_spklen(reg_base) + 5)) { + value = I2C_FSP_HCNT + rom->hcnt_offset; + if (value <= (read_fs_spklen(reg_base) + 5)) { value = read_fs_spklen(reg_base) + 6; - } else { - value = I2C_FSP_HCNT; } dw->hcnt = value; break; case I2C_SPEED_HIGH: if (dw->support_hs_mode) { - if (I2C_HS_LCNT <= (read_hs_spklen(reg_base) + 7)) { + value = I2C_HS_LCNT + rom->lcnt_offset; + if (value <= (read_hs_spklen(reg_base) + 7)) { value = read_hs_spklen(reg_base) + 8; - } else { - value = I2C_HS_LCNT; } dw->lcnt = value; - if (I2C_HS_HCNT <= (read_hs_spklen(reg_base) + 5)) { + value = I2C_HS_HCNT + rom->hcnt_offset; + if (value <= (read_hs_spklen(reg_base) + 5)) { value = read_hs_spklen(reg_base) + 6; - } else { - value = I2C_HS_HCNT; } dw->hcnt = value; @@ -1023,7 +1016,7 @@ static void i2c_dw_slave_read_clear_intr_bits(const struct device *dev) } #endif /* CONFIG_I2C_TARGET */ -static const struct i2c_driver_api funcs = { +static DEVICE_API(i2c, funcs) = { .configure = i2c_dw_runtime_configure, .transfer = i2c_dw_transfer, #ifdef CONFIG_I2C_TARGET @@ -1147,8 +1140,8 @@ static int i2c_dw_initialize(const struct device *dev) #endif #if defined(CONFIG_RESET) -#define RESET_DW_CONFIG(n) \ - IF_ENABLED(DT_INST_NODE_HAS_PROP(0, resets), \ +#define RESET_DW_CONFIG(n) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(n, resets), \ (.reset = RESET_DT_SPEC_INST_GET(n),)) #else #define RESET_DW_CONFIG(n) @@ -1215,6 +1208,8 @@ static int i2c_dw_initialize(const struct device *dev) static const struct i2c_dw_rom_config i2c_config_dw_##n = { \ I2C_CONFIG_REG_INIT(n).config_func = i2c_config_##n, \ .bitrate = DT_INST_PROP(n, clock_frequency), \ + .lcnt_offset = (int16_t)DT_INST_PROP_OR(n, lcnt_offset, 0), \ + .hcnt_offset = (int16_t)DT_INST_PROP_OR(n, hcnt_offset, 0), \ RESET_DW_CONFIG(n) PINCTRL_DW_CONFIG(n) I2C_DW_INIT_PCIE(n) \ I2C_CONFIG_DMA_INIT(n)}; \ static struct i2c_dw_dev_config i2c_##n##_runtime; \ diff --git a/drivers/i2c/i2c_dw.h b/drivers/i2c/i2c_dw.h index 004cbb0a11076..2a4f64cd86bdc 100644 --- a/drivers/i2c/i2c_dw.h +++ b/drivers/i2c/i2c_dw.h @@ -84,6 +84,8 @@ struct i2c_dw_rom_config { DEVICE_MMIO_ROM; i2c_isr_cb_t config_func; uint32_t bitrate; + int16_t lcnt_offset; + int16_t hcnt_offset; #if defined(CONFIG_PINCTRL) const struct pinctrl_dev_config *pcfg; diff --git a/drivers/i2c/i2c_emul.c b/drivers/i2c/i2c_emul.c index 5554ce81b5c65..7069b79af09ce 100644 --- a/drivers/i2c/i2c_emul.c +++ b/drivers/i2c/i2c_emul.c @@ -292,7 +292,7 @@ static int i2c_emul_target_unregister(const struct device *dev, struct i2c_targe /* Device instantiation */ -static const struct i2c_driver_api i2c_emul_api = { +static DEVICE_API(i2c, i2c_emul_api) = { .configure = i2c_emul_configure, .get_config = i2c_emul_get_config, .transfer = i2c_emul_transfer, @@ -312,7 +312,7 @@ static const struct i2c_driver_api i2c_emul_api = { #define EMUL_FORWARD_ITEM(node_id, prop, idx) \ { \ - .bus = DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)), \ + .bus = DEVICE_DT_GET_BY_IDX(node_id, prop, idx), \ .addr = DT_PHA_BY_IDX(node_id, prop, idx, addr), \ }, diff --git a/drivers/i2c/i2c_ene_kb1200.c b/drivers/i2c/i2c_ene_kb1200.c index 322efd2e30c51..359f99793e42e 100644 --- a/drivers/i2c/i2c_ene_kb1200.c +++ b/drivers/i2c/i2c_ene_kb1200.c @@ -293,7 +293,7 @@ static int i2c_kb1200_transfer(const struct device *dev, struct i2c_msg *msgs, u } /* I2C Master driver registration */ -static const struct i2c_driver_api i2c_kb1200_api = { +static DEVICE_API(i2c, i2c_kb1200_api) = { .configure = i2c_kb1200_configure, .get_config = i2c_kb1200_get_config, .transfer = i2c_kb1200_transfer, diff --git a/drivers/i2c/i2c_esp32.c b/drivers/i2c/i2c_esp32.c index 07c8ea536caf6..a46e76f31a77f 100644 --- a/drivers/i2c/i2c_esp32.c +++ b/drivers/i2c/i2c_esp32.c @@ -722,7 +722,7 @@ static void IRAM_ATTR i2c_esp32_isr(void *arg) k_sem_give(&data->cmd_sem); } -static const struct i2c_driver_api i2c_esp32_driver_api = { +static DEVICE_API(i2c, i2c_esp32_driver_api) = { .configure = i2c_esp32_configure, .get_config = i2c_esp32_get_config, .transfer = i2c_esp32_transfer, diff --git a/drivers/i2c/i2c_gd32.c b/drivers/i2c/i2c_gd32.c index 9b6d6f5e4e616..381911fafb79c 100644 --- a/drivers/i2c/i2c_gd32.c +++ b/drivers/i2c/i2c_gd32.c @@ -641,7 +641,7 @@ static int i2c_gd32_configure(const struct device *dev, return err; } -static const struct i2c_driver_api i2c_gd32_driver_api = { +static DEVICE_API(i2c, i2c_gd32_driver_api) = { .configure = i2c_gd32_configure, .transfer = i2c_gd32_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_gecko.c b/drivers/i2c/i2c_gecko.c index e2d44f3989c40..373eb231f9ac4 100644 --- a/drivers/i2c/i2c_gecko.c +++ b/drivers/i2c/i2c_gecko.c @@ -216,7 +216,7 @@ static int i2c_gecko_target_unregister(const struct device *dev, struct i2c_targ } #endif -static const struct i2c_driver_api i2c_gecko_driver_api = { +static DEVICE_API(i2c, i2c_gecko_driver_api) = { .configure = i2c_gecko_configure, .transfer = i2c_gecko_transfer, #if defined(CONFIG_I2C_TARGET) diff --git a/drivers/i2c/i2c_gpio.c b/drivers/i2c/i2c_gpio.c index 80a1a221490f3..406b10af8634f 100644 --- a/drivers/i2c/i2c_gpio.c +++ b/drivers/i2c/i2c_gpio.c @@ -140,7 +140,7 @@ static int i2c_gpio_recover_bus(const struct device *dev) return rc; } -static const struct i2c_driver_api api = { +static DEVICE_API(i2c, api) = { .configure = i2c_gpio_configure, .get_config = i2c_gpio_get_config, .transfer = i2c_gpio_transfer, diff --git a/drivers/i2c/i2c_ifx_cat1.c b/drivers/i2c/i2c_ifx_cat1.c index 90bf9c1e68b45..f272d87346e7e 100644 --- a/drivers/i2c/i2c_ifx_cat1.c +++ b/drivers/i2c/i2c_ifx_cat1.c @@ -81,11 +81,14 @@ static const cy_stc_scb_i2c_config_t _cyhal_i2c_default_config = { static int32_t _get_hw_block_num(CySCB_Type *reg_addr) { + extern const uint8_t _CYHAL_SCB_BASE_ADDRESS_INDEX[_SCB_ARRAY_SIZE]; + extern CySCB_Type *const _CYHAL_SCB_BASE_ADDRESSES[_SCB_ARRAY_SIZE]; + uint32_t i; for (i = 0u; i < _SCB_ARRAY_SIZE; i++) { if (_CYHAL_SCB_BASE_ADDRESSES[i] == reg_addr) { - return i; + return _CYHAL_SCB_BASE_ADDRESS_INDEX[i]; } } @@ -492,7 +495,7 @@ static int ifx_cat1_i2c_target_unregister(const struct device *dev, struct i2c_t } /* I2C API structure */ -static const struct i2c_driver_api i2c_cat1_driver_api = { +static DEVICE_API(i2c, i2c_cat1_driver_api) = { .configure = ifx_cat1_i2c_configure, .transfer = ifx_cat1_i2c_transfer, .get_config = ifx_cat1_i2c_get_config, diff --git a/drivers/i2c/i2c_ifx_xmc4.c b/drivers/i2c/i2c_ifx_xmc4.c index 253445809c383..789f4f408f714 100644 --- a/drivers/i2c/i2c_ifx_xmc4.c +++ b/drivers/i2c/i2c_ifx_xmc4.c @@ -425,7 +425,7 @@ static void i2c_xmc4_isr(const struct device *dev) /* I2C API structure */ -static const struct i2c_driver_api i2c_xmc4_driver_api = { +static DEVICE_API(i2c, i2c_xmc4_driver_api) = { .configure = ifx_xmc4_i2c_configure, .transfer = ifx_xmc4_i2c_transfer, .get_config = ifx_xmc4_i2c_get_config, diff --git a/drivers/i2c/i2c_imx.c b/drivers/i2c/i2c_imx.c index eba04101693f8..d2c99ef9a8022 100644 --- a/drivers/i2c/i2c_imx.c +++ b/drivers/i2c/i2c_imx.c @@ -360,7 +360,7 @@ static int i2c_imx_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_imx_driver_api = { +static DEVICE_API(i2c, i2c_imx_driver_api) = { .configure = i2c_imx_configure, .transfer = i2c_imx_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_ite_enhance.c b/drivers/i2c/i2c_ite_enhance.c index 1264bcec84491..e67083218ff79 100644 --- a/drivers/i2c/i2c_ite_enhance.c +++ b/drivers/i2c/i2c_ite_enhance.c @@ -1452,7 +1452,7 @@ static int i2c_enhance_target_unregister(const struct device *dev, } #endif -static const struct i2c_driver_api i2c_enhance_driver_api = { +static DEVICE_API(i2c, i2c_enhance_driver_api) = { .configure = i2c_enhance_configure, .get_config = i2c_enhance_get_config, .transfer = i2c_enhance_transfer, diff --git a/drivers/i2c/i2c_ite_it8xxx2.c b/drivers/i2c/i2c_ite_it8xxx2.c index a9247734be3fc..203eaaa3d339e 100644 --- a/drivers/i2c/i2c_ite_it8xxx2.c +++ b/drivers/i2c/i2c_ite_it8xxx2.c @@ -1250,7 +1250,7 @@ static int i2c_it8xxx2_recover_bus(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_it8xxx2_driver_api = { +static DEVICE_API(i2c, i2c_it8xxx2_driver_api) = { .configure = i2c_it8xxx2_configure, .get_config = i2c_it8xxx2_get_config, .transfer = i2c_it8xxx2_transfer, diff --git a/drivers/i2c/i2c_litex.c b/drivers/i2c/i2c_litex.c index 38e0cfa8cfd7f..104829b6f7981 100644 --- a/drivers/i2c/i2c_litex.c +++ b/drivers/i2c/i2c_litex.c @@ -136,7 +136,7 @@ static int i2c_litex_recover_bus(const struct device *dev) return i2c_bitbang_recover_bus(bitbang); } -static const struct i2c_driver_api i2c_litex_driver_api = { +static DEVICE_API(i2c, i2c_litex_driver_api) = { .configure = i2c_litex_configure, .get_config = i2c_litex_get_config, .transfer = i2c_litex_transfer, diff --git a/drivers/i2c/i2c_ll_stm32.c b/drivers/i2c/i2c_ll_stm32.c index 677d1f688e5a2..6e1d2c48f2c4c 100644 --- a/drivers/i2c/i2c_ll_stm32.c +++ b/drivers/i2c/i2c_ll_stm32.c @@ -115,7 +115,7 @@ int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config) #endif LL_I2C_Disable(i2c); -#if defined(I2C_CR1_SMBDEN) && defined(I2C_CR1_SMBHEN) +#if defined(I2C_CR1_SMBUS) || defined(I2C_CR1_SMBDEN) || defined(I2C_CR1_SMBHEN) i2c_stm32_set_smbus_mode(dev, data->mode); #endif ret = stm32_i2c_configure_timing(dev, i2c_clock); @@ -310,7 +310,7 @@ static int i2c_stm32_recover_bus(const struct device *dev) } #endif /* CONFIG_I2C_STM32_BUS_RECOVERY */ -static const struct i2c_driver_api api_funcs = { +static DEVICE_API(i2c, api_funcs) = { .configure = i2c_stm32_runtime_configure, .transfer = i2c_stm32_transfer, .get_config = i2c_stm32_get_config, @@ -480,7 +480,7 @@ void i2c_stm32_smbalert_set_callback(const struct device *dev, i2c_stm32_smbaler } #endif /* CONFIG_SMBUS_STM32_SMBALERT */ -#if defined(I2C_CR1_SMBDEN) && defined(I2C_CR1_SMBHEN) +#if defined(I2C_CR1_SMBUS) || defined(I2C_CR1_SMBDEN) || defined(I2C_CR1_SMBHEN) void i2c_stm32_set_smbus_mode(const struct device *dev, enum i2c_stm32_mode mode) { const struct i2c_stm32_config *cfg = dev->config; diff --git a/drivers/i2c/i2c_lpc11u6x.c b/drivers/i2c/i2c_lpc11u6x.c index 2a32822be5c3c..a00ac10dd5c6f 100644 --- a/drivers/i2c/i2c_lpc11u6x.c +++ b/drivers/i2c/i2c_lpc11u6x.c @@ -340,7 +340,7 @@ static int lpc11u6x_i2c_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_api = { +static DEVICE_API(i2c, i2c_api) = { .configure = lpc11u6x_i2c_configure, .transfer = lpc11u6x_i2c_transfer, .target_register = lpc11u6x_i2c_slave_register, diff --git a/drivers/i2c/i2c_max32.c b/drivers/i2c/i2c_max32.c index e08612114323b..c42f837bf3efe 100644 --- a/drivers/i2c/i2c_max32.c +++ b/drivers/i2c/i2c_max32.c @@ -832,7 +832,7 @@ static void i2c_max32_isr(const struct device *dev) } #endif /* CONFIG_I2C_TARGET || CONFIG_I2C_MAX32_INTERRUPT */ -static const struct i2c_driver_api api = { +static DEVICE_API(i2c, api) = { .configure = api_configure, .transfer = api_transfer, #ifdef CONFIG_I2C_TARGET diff --git a/drivers/i2c/i2c_max32_rtio.c b/drivers/i2c/i2c_max32_rtio.c new file mode 100644 index 0000000000000..40ceeffdd4132 --- /dev/null +++ b/drivers/i2c/i2c_max32_rtio.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max32_i2c + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +LOG_MODULE_REGISTER(max32_i2c); + +#define ADI_MAX32_I2C_INT_FL0_MASK 0x00FFFFFF +#define ADI_MAX32_I2C_INT_FL1_MASK 0x7 + +#define ADI_MAX32_I2C_STATUS_MASTER_BUSY BIT(5) + +#define I2C_RECOVER_MAX_RETRIES 3 +#define I2C_STANDAR_BITRATE_CLKHI 0x12b + +static int complete_flag; + +/* Driver config */ +struct max32_i2c_config { + mxc_i2c_regs_t *regs; + const struct pinctrl_dev_config *pctrl; + const struct device *clock; + struct max32_perclk perclk; + uint32_t bitrate; +#if defined(CONFIG_I2C_MAX32_INTERRUPT) + uint8_t irqn; + void (*irq_config_func)(const struct device *dev); +#endif +}; + +struct max32_i2c_data { + mxc_i2c_req_t req; + const struct device *dev; + uint8_t target_mode; + uint8_t flags; + struct i2c_rtio *ctx; + uint32_t readb; + uint32_t written; + uint8_t second_msg_flag; +#if defined(CONFIG_I2C_MAX32_INTERRUPT) + int err; +#endif +}; + +static int max32_configure(const struct device *dev, + uint32_t dev_cfg) +{ + struct i2c_rtio *const ctx = ((struct max32_i2c_data *) + dev->data)->ctx; + + return i2c_rtio_configure(ctx, dev_cfg); +} + +static int max32_do_configure(const struct device *dev, uint32_t dev_cfg) +{ + int ret = 0; + const struct max32_i2c_config *const cfg = dev->config; + mxc_i2c_regs_t *i2c = cfg->regs; + + switch (I2C_SPEED_GET(dev_cfg)) { + case I2C_SPEED_STANDARD: /** I2C Standard Speed: 100 kHz */ + ret = MXC_I2C_SetFrequency(i2c, MXC_I2C_STD_MODE); + break; + + case I2C_SPEED_FAST: /** I2C Fast Speed: 400 kHz */ + ret = MXC_I2C_SetFrequency(i2c, MXC_I2C_FAST_SPEED); + break; + +#if defined(MXC_I2C_FASTPLUS_SPEED) + case I2C_SPEED_FAST_PLUS: /** I2C Fast Plus Speed: 1 MHz */ + ret = MXC_I2C_SetFrequency(i2c, MXC_I2C_FASTPLUS_SPEED); + break; +#endif + +#if defined(MXC_I2C_HIGH_SPEED) + case I2C_SPEED_HIGH: /** I2C High Speed: 3.4 MHz */ + ret = MXC_I2C_SetFrequency(i2c, MXC_I2C_HIGH_SPEED); + break; +#endif + + default: + /* Speed not supported */ + return -ENOTSUP; + } + + return ret; +} + +static void max32_complete(const struct device *dev, int status); + +static int max32_msg_start(const struct device *dev, uint8_t flags, + uint8_t *buf, size_t buf_len, uint16_t i2c_addr) +{ + int ret = 0; + const struct max32_i2c_config *const cfg = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = cfg->regs; + mxc_i2c_req_t *req = &data->req; + uint8_t target_rw; + + req->i2c = i2c; + req->addr = i2c_addr; + + if (data->second_msg_flag == 0) { + MXC_I2C_ClearRXFIFO(i2c); + MXC_I2C_ClearTXFIFO(i2c); + MXC_I2C_SetRXThreshold(i2c, 1); + + /* First message should always begin with a START condition */ + flags |= I2C_MSG_RESTART; + } + + if (flags & I2C_MSG_READ) { + req->rx_buf = (unsigned char *)buf; + req->rx_len = buf_len; + req->tx_buf = NULL; + req->tx_len = 0; + target_rw = (i2c_addr << 1) | 0x1; + } else { + req->tx_buf = (unsigned char *)buf; + req->tx_len = buf_len; + req->rx_buf = NULL; + req->rx_len = 0; + target_rw = (i2c_addr << 1) & ~0x1; + } + data->flags = flags; + data->readb = 0; + data->written = 0; + data->err = 0; + + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, ADI_MAX32_I2C_INT_FL1_MASK); + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_ERR, 0); + Wrap_MXC_I2C_SetRxCount(i2c, req->rx_len); + if ((data->flags & I2C_MSG_RESTART)) { + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_ADDR_ACK, 0); + MXC_I2C_Start(i2c); + Wrap_MXC_I2C_WaitForRestart(i2c); + MXC_I2C_WriteTXFIFO(i2c, &target_rw, 1); + } else { + if (req->tx_len) { + data->written = MXC_I2C_WriteTXFIFO(i2c, req->tx_buf, 1); + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_TX_THD, 0); + } else { + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_RX_THD, 0); + } + } + + if (data->err) { + MXC_I2C_Stop(i2c); + ret = data->err; + } + + return ret; +} + +static int max32_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t target_address) +{ + struct i2c_rtio *const ctx = ((struct max32_i2c_data *) + dev->data)->ctx; + ((struct max32_i2c_data *)dev->data)->second_msg_flag = 0; + + return i2c_rtio_transfer(ctx, msgs, num_msgs, target_address); +} + + + +static void i2c_max32_isr_controller(const struct device *dev, mxc_i2c_regs_t *i2c) +{ + struct max32_i2c_data *data = dev->data; + mxc_i2c_req_t *req = &data->req; + uint32_t written, readb; + uint32_t txfifolevel; + uint32_t int_fl0, int_fl1; + uint32_t int_en0, int_en1; + + written = data->written; + readb = data->readb; + + Wrap_MXC_I2C_GetIntEn(i2c, &int_en0, &int_en1); + MXC_I2C_GetFlags(i2c, &int_fl0, &int_fl1); + MXC_I2C_ClearFlags(i2c, ADI_MAX32_I2C_INT_FL0_MASK, ADI_MAX32_I2C_INT_FL1_MASK); + txfifolevel = Wrap_MXC_I2C_GetTxFIFOLevel(i2c); + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ERR) { + data->err = -EIO; + Wrap_MXC_I2C_SetIntEn(i2c, 0, 0); + return; + } + + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_ADDR_ACK) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_ADDR_ACK, 0); + if (written < req->tx_len) { + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_TX_THD, 0); + } else if (readb < req->rx_len) { + MXC_I2C_EnableInt( + i2c, ADI_MAX32_I2C_INT_EN0_RX_THD | ADI_MAX32_I2C_INT_EN0_DONE, 0); + } + } + + if (req->tx_len && + (int_fl0 & (ADI_MAX32_I2C_INT_FL0_TX_THD | ADI_MAX32_I2C_INT_FL0_DONE))) { + if (written < req->tx_len) { + written += MXC_I2C_WriteTXFIFO(i2c, &req->tx_buf[written], + req->tx_len - written); + } else { + if (!(int_en0 & ADI_MAX32_I2C_INT_EN0_DONE)) { + /* We are done, stop sending more data */ + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_TX_THD, 0); + if (data->flags & I2C_MSG_STOP) { + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_DONE, 0); + /* Done flag is not set if stop/restart is not set */ + Wrap_MXC_I2C_Stop(i2c); + } else { + complete_flag++; + } + } + + if ((int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE)) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_DONE, 0); + complete_flag++; + } + } + } else if ((int_fl0 & (ADI_MAX32_I2C_INT_FL0_RX_THD | ADI_MAX32_I2C_INT_FL0_DONE))) { + readb += MXC_I2C_ReadRXFIFO(i2c, &req->rx_buf[readb], req->rx_len - readb); + if (readb == req->rx_len) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_RX_THD, 0); + if (data->flags & I2C_MSG_STOP) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_DONE, 0); + Wrap_MXC_I2C_Stop(i2c); + complete_flag++; + } else { + if (int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE) { + MXC_I2C_DisableInt(i2c, ADI_MAX32_I2C_INT_EN0_DONE, 0); + } + } + } else if ((int_en0 & ADI_MAX32_I2C_INT_EN0_DONE) && + (int_fl0 & ADI_MAX32_I2C_INT_FL0_DONE)) { + MXC_I2C_DisableInt( + i2c, (ADI_MAX32_I2C_INT_EN0_RX_THD | ADI_MAX32_I2C_INT_EN0_DONE), + 0); + Wrap_MXC_I2C_SetRxCount(i2c, req->rx_len - readb); + MXC_I2C_EnableInt(i2c, ADI_MAX32_I2C_INT_EN0_ADDR_ACK, 0); + i2c->fifo = (req->addr << 1) | 0x1; + Wrap_MXC_I2C_Restart(i2c); + } + } + data->written = written; + data->readb = readb; + + if (complete_flag == 1) { + max32_complete(dev, 0); + complete_flag = 0; + } +} + +static bool max32_start(const struct device *dev) +{ + struct max32_i2c_data *data = dev->data; + struct i2c_rtio *ctx = data->ctx; + struct rtio_sqe *sqe = &ctx->txn_curr->sqe; + struct i2c_dt_spec *dt_spec = sqe->iodev->data; + int res = 0; + + switch (sqe->op) { + case RTIO_OP_RX: + return max32_msg_start(dev, I2C_MSG_READ | sqe->iodev_flags, + sqe->rx.buf, sqe->rx.buf_len, dt_spec->addr); + case RTIO_OP_TINY_TX: + data->second_msg_flag = 0; + return max32_msg_start(dev, I2C_MSG_WRITE | sqe->iodev_flags, + (uint8_t *)sqe->tiny_tx.buf, sqe->tiny_tx.buf_len, + dt_spec->addr); + case RTIO_OP_TX: + return max32_msg_start(dev, I2C_MSG_WRITE | sqe->iodev_flags, + (uint8_t *)sqe->tx.buf, sqe->tx.buf_len, + dt_spec->addr); + case RTIO_OP_I2C_CONFIGURE: + res = max32_do_configure(dev, sqe->i2c_config); + return i2c_rtio_complete(data->ctx, res); + default: + LOG_ERR("Invalid op code %d for submission %p\n", sqe->op, (void *)sqe); + return i2c_rtio_complete(data->ctx, -EINVAL); + } +} + +static void max32_complete(const struct device *dev, int status) +{ + struct max32_i2c_data *data = dev->data; + struct i2c_rtio *const ctx = data->ctx; + const struct max32_i2c_config *const cfg = dev->config; + int ret = 0; + + if (cfg->regs->clkhi == I2C_STANDAR_BITRATE_CLKHI) { + /* When I2C is configured in Standard Bitrate 100KHz + * Hardware completes first read sample transaction + * and gets stuck in idle instead of starting the + * next transaction, if given k_busy_wait for + * 20 us ~= 2 additional I2C cycles sample read + * won't have any issues but all other transactions + * (like setup of sensor) will have this unnecessary + * delay. This doesn't happen when using Fast + * Bitrate 400Hz. + */ + LOG_ERR("For Standard speed HW needs more time to run"); + return; + } + if (i2c_rtio_complete(ctx, ret)) { + data->second_msg_flag = 1; + max32_start(dev); + } +} + +static void max32_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + struct max32_i2c_data *data = dev->data; + struct i2c_rtio *const ctx = data->ctx; + + if (i2c_rtio_submit(ctx, iodev_sqe)) { + max32_start(dev); + } +} + + +static void i2c_max32_isr(const struct device *dev) +{ + const struct max32_i2c_config *cfg = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = cfg->regs; + + if (data->target_mode == 0) { + i2c_max32_isr_controller(dev, i2c); + return; + } +} + +static int i2c_max32_init(const struct device *dev) +{ + const struct max32_i2c_config *const cfg = dev->config; + struct max32_i2c_data *data = dev->data; + mxc_i2c_regs_t *i2c = cfg->regs; + int ret = 0; + + if (!device_is_ready(cfg->clock)) { + return -ENODEV; + } + + MXC_I2C_Shutdown(i2c); /* Clear everything out */ + + ret = clock_control_on(cfg->clock, (clock_control_subsys_t)&cfg->perclk); + if (ret) { + return ret; + } + + ret = pinctrl_apply_state(cfg->pctrl, PINCTRL_STATE_DEFAULT); + if (ret) { + return ret; + } + + ret = MXC_I2C_Init(i2c, 1, 0); /* Configure as master */ + if (ret) { + return ret; + } + + MXC_I2C_SetFrequency(i2c, cfg->bitrate); + +#if defined(CONFIG_I2C_MAX32_INTERRUPT) + cfg->irq_config_func(dev); +#endif + +#ifdef CONFIG_I2C_MAX32_INTERRUPT + irq_enable(cfg->irqn); + +#endif + + data->dev = dev; + + i2c_rtio_init(data->ctx, dev); + return ret; +} + +static const struct i2c_driver_api max32_driver_api = { + .configure = max32_configure, + .transfer = max32_transfer, + .iodev_submit = max32_submit, +}; + +#if defined(CONFIG_I2C_TARGET) || defined(CONFIG_I2C_MAX32_INTERRUPT) +#define I2C_MAX32_CONFIG_IRQ_FUNC(n) \ + .irq_config_func = i2c_max32_irq_config_func_##n, .irqn = DT_INST_IRQN(n), + +#define I2C_MAX32_IRQ_CONFIG_FUNC(n) \ + static void i2c_max32_irq_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), i2c_max32_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + } +#else +#define I2C_MAX32_CONFIG_IRQ_FUNC(n) +#define I2C_MAX32_IRQ_CONFIG_FUNC(n) +#endif + + +#define DEFINE_I2C_MAX32(_num) \ + PINCTRL_DT_INST_DEFINE(_num); \ + I2C_MAX32_IRQ_CONFIG_FUNC(_num) \ + static const struct max32_i2c_config max32_i2c_dev_cfg_##_num = { \ + .regs = (mxc_i2c_regs_t *)DT_INST_REG_ADDR(_num), \ + .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(_num), \ + .clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(_num)), \ + .perclk.bus = DT_INST_CLOCKS_CELL(_num, offset), \ + .perclk.bit = DT_INST_CLOCKS_CELL(_num, bit), \ + .bitrate = DT_INST_PROP(_num, clock_frequency), \ + I2C_MAX32_CONFIG_IRQ_FUNC(_num)}; \ + I2C_RTIO_DEFINE(_i2c##n##_max32_rtio, \ + DT_INST_PROP_OR(n, sq_size, CONFIG_I2C_RTIO_SQ_SIZE), \ + DT_INST_PROP_OR(n, cq_size, CONFIG_I2C_RTIO_CQ_SIZE)); \ + static struct max32_i2c_data max32_i2c_data_##_num = { \ + .ctx = &CONCAT(_i2c, n, _max32_rtio), \ + }; \ + I2C_DEVICE_DT_INST_DEFINE(_num, i2c_max32_init, NULL, &max32_i2c_data_##_num, \ + &max32_i2c_dev_cfg_##_num, PRE_KERNEL_2, \ + CONFIG_I2C_INIT_PRIORITY, &max32_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_I2C_MAX32) diff --git a/drivers/i2c/i2c_mchp_mss.c b/drivers/i2c/i2c_mchp_mss.c index ef132c6182cbf..25e4e7c094a5f 100644 --- a/drivers/i2c/i2c_mchp_mss.c +++ b/drivers/i2c/i2c_mchp_mss.c @@ -232,7 +232,7 @@ static int mss_i2c_transfer(const struct device *dev, struct i2c_msg *msgs, uint return 0; } -static const struct i2c_driver_api mss_i2c_driver_api = { +static DEVICE_API(i2c, mss_i2c_driver_api) = { .configure = mss_i2c_configure, .transfer = mss_i2c_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_mchp_xec.c b/drivers/i2c/i2c_mchp_xec.c index 6f48e9404b15c..e1376470ff405 100644 --- a/drivers/i2c/i2c_mchp_xec.c +++ b/drivers/i2c/i2c_mchp_xec.c @@ -829,7 +829,7 @@ static int i2c_xec_target_unregister(const struct device *dev, } #endif -static const struct i2c_driver_api i2c_xec_driver_api = { +static DEVICE_API(i2c, i2c_xec_driver_api) = { .configure = i2c_xec_configure, .transfer = i2c_xec_transfer, #ifdef CONFIG_I2C_TARGET diff --git a/drivers/i2c/i2c_mchp_xec_v2.c b/drivers/i2c/i2c_mchp_xec_v2.c index c0ab170ba03ef..4feda66823ef6 100644 --- a/drivers/i2c/i2c_mchp_xec_v2.c +++ b/drivers/i2c/i2c_mchp_xec_v2.c @@ -1033,7 +1033,7 @@ static int i2c_xec_target_unregister(const struct device *dev, } #endif -static const struct i2c_driver_api i2c_xec_driver_api = { +static DEVICE_API(i2c, i2c_xec_driver_api) = { .configure = i2c_xec_configure, .transfer = i2c_xec_transfer, #ifdef CONFIG_I2C_TARGET diff --git a/drivers/i2c/i2c_mcux.c b/drivers/i2c/i2c_mcux.c index aaf6b0116a6de..1ef10cc402060 100644 --- a/drivers/i2c/i2c_mcux.c +++ b/drivers/i2c/i2c_mcux.c @@ -342,7 +342,7 @@ static int i2c_mcux_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_mcux_driver_api = { +static DEVICE_API(i2c, i2c_mcux_driver_api) = { .configure = i2c_mcux_configure, .transfer = i2c_mcux_transfer, #ifdef CONFIG_I2C_CALLBACK diff --git a/drivers/i2c/i2c_mcux_flexcomm.c b/drivers/i2c/i2c_mcux_flexcomm.c index 158deacc6dedd..cba19771cdfae 100644 --- a/drivers/i2c/i2c_mcux_flexcomm.c +++ b/drivers/i2c/i2c_mcux_flexcomm.c @@ -14,6 +14,11 @@ #include #include +#ifdef CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY +#include "i2c_bitbang.h" +#include +#endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */ + #include #include LOG_MODULE_REGISTER(mcux_flexcomm); @@ -34,6 +39,10 @@ struct mcux_flexcomm_config { uint32_t bitrate; const struct pinctrl_dev_config *pincfg; const struct reset_dt_spec reset; +#ifdef CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY + struct gpio_dt_spec scl; + struct gpio_dt_spec sda; +#endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */ }; #ifdef CONFIG_I2C_TARGET @@ -204,6 +213,89 @@ static int mcux_flexcomm_transfer(const struct device *dev, return ret; } +#if CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY +static void mcux_flexcomm_bitbang_set_scl(void *io_context, int state) +{ + const struct mcux_flexcomm_config *config = io_context; + + gpio_pin_set_dt(&config->scl, state); +} + +static void mcux_flexcomm_bitbang_set_sda(void *io_context, int state) +{ + const struct mcux_flexcomm_config *config = io_context; + + gpio_pin_set_dt(&config->sda, state); +} + +static int mcux_flexcomm_bitbang_get_sda(void *io_context) +{ + const struct mcux_flexcomm_config *config = io_context; + + return gpio_pin_get_dt(&config->sda) == 0 ? 0 : 1; +} + +static int mcux_flexcomm_recover_bus(const struct device *dev) +{ + const struct mcux_flexcomm_config *config = dev->config; + struct mcux_flexcomm_data *data = dev->data; + struct i2c_bitbang bitbang_ctx; + struct i2c_bitbang_io bitbang_io = { + .set_scl = mcux_flexcomm_bitbang_set_scl, + .set_sda = mcux_flexcomm_bitbang_set_sda, + .get_sda = mcux_flexcomm_bitbang_get_sda, + }; + uint32_t bitrate_cfg; + int error = 0; + + if (!gpio_is_ready_dt(&config->scl)) { + LOG_ERR("SCL GPIO device not ready"); + return -EIO; + } + + if (!gpio_is_ready_dt(&config->sda)) { + LOG_ERR("SDA GPIO device not ready"); + return -EIO; + } + + k_sem_take(&data->lock, K_FOREVER); + + error = gpio_pin_configure_dt(&config->scl, GPIO_OUTPUT_HIGH); + if (error != 0) { + LOG_ERR("failed to configure SCL GPIO (err %d)", error); + goto restore; + } + + error = gpio_pin_configure_dt(&config->sda, GPIO_OUTPUT_HIGH); + if (error != 0) { + LOG_ERR("failed to configure SDA GPIO (err %d)", error); + goto restore; + } + + i2c_bitbang_init(&bitbang_ctx, &bitbang_io, (void *)config); + + bitrate_cfg = i2c_map_dt_bitrate(config->bitrate) | I2C_MODE_CONTROLLER; + error = i2c_bitbang_configure(&bitbang_ctx, bitrate_cfg); + if (error != 0) { + LOG_ERR("failed to configure I2C bitbang (err %d)", error); + goto restore; + } + + error = i2c_bitbang_recover_bus(&bitbang_ctx); + if (error != 0) { + LOG_ERR("failed to recover bus (err %d)", error); + goto restore; + } + +restore: + (void)pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + + k_sem_give(&data->lock); + + return error; +} +#endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */ + #if defined(CONFIG_I2C_TARGET) static struct mcux_flexcomm_target_data *mcux_flexcomm_find_free_target( @@ -519,9 +611,12 @@ static int mcux_flexcomm_init(const struct device *dev) return 0; } -static const struct i2c_driver_api mcux_flexcomm_driver_api = { +static DEVICE_API(i2c, mcux_flexcomm_driver_api) = { .configure = mcux_flexcomm_configure, .transfer = mcux_flexcomm_transfer, +#if CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY + .recover_bus = mcux_flexcomm_recover_bus, +#endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */ #if defined(CONFIG_I2C_TARGET) .target_register = mcux_flexcomm_target_register, .target_unregister = mcux_flexcomm_target_unregister, @@ -531,6 +626,14 @@ static const struct i2c_driver_api mcux_flexcomm_driver_api = { #endif }; +#if CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY +#define I2C_MCUX_FLEXCOMM_SCL_INIT(n) .scl = GPIO_DT_SPEC_INST_GET_OR(n, scl_gpios, {0}), +#define I2C_MCUX_FLEXCOMM_SDA_INIT(n) .sda = GPIO_DT_SPEC_INST_GET_OR(n, sda_gpios, {0}), +#else +#define I2C_MCUX_FLEXCOMM_SCL_INIT(n) +#define I2C_MCUX_FLEXCOMM_SDA_INIT(n) +#endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */ + #define I2C_MCUX_FLEXCOMM_DEVICE(id) \ PINCTRL_DT_INST_DEFINE(id); \ static void mcux_flexcomm_config_func_##id(const struct device *dev); \ @@ -542,6 +645,8 @@ static const struct i2c_driver_api mcux_flexcomm_driver_api = { .irq_config_func = mcux_flexcomm_config_func_##id, \ .bitrate = DT_INST_PROP(id, clock_frequency), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \ + I2C_MCUX_FLEXCOMM_SCL_INIT(id) \ + I2C_MCUX_FLEXCOMM_SDA_INIT(id) \ .reset = RESET_DT_SPEC_INST_GET(id), \ }; \ static struct mcux_flexcomm_data mcux_flexcomm_data_##id; \ diff --git a/drivers/i2c/i2c_mcux_lpi2c.c b/drivers/i2c/i2c_mcux_lpi2c.c index 74881543ede07..3121b6902a4e0 100644 --- a/drivers/i2c/i2c_mcux_lpi2c.c +++ b/drivers/i2c/i2c_mcux_lpi2c.c @@ -42,9 +42,6 @@ LOG_MODULE_REGISTER(mcux_lpi2c); struct mcux_lpi2c_config { DEVICE_MMIO_NAMED_ROM(reg_base); -#ifdef CONFIG_NXP_LP_FLEXCOMM - const struct device *parent_dev; -#endif const struct device *clock_dev; clock_control_subsys_t clock_subsys; void (*irq_config_func)(const struct device *dev); @@ -536,21 +533,13 @@ static int mcux_lpi2c_init(const struct device *dev) if (error) { return error; } -#if CONFIG_NXP_LP_FLEXCOMM - /* When using LP Flexcomm driver, register the interrupt handler - * so we receive notification from the LP Flexcomm interrupt handler. - */ - nxp_lp_flexcomm_setirqhandler(config->parent_dev, dev, - LP_FLEXCOMM_PERIPH_LPI2C, mcux_lpi2c_isr); -#else - /* Interrupt is managed by this driver */ + config->irq_config_func(dev); -#endif return 0; } -static const struct i2c_driver_api mcux_lpi2c_driver_api = { +static DEVICE_API(i2c, mcux_lpi2c_driver_api) = { .configure = mcux_lpi2c_configure, .transfer = mcux_lpi2c_transfer, #if CONFIG_I2C_MCUX_LPI2C_BUS_RECOVERY @@ -583,21 +572,31 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = { IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ (I2C_MCUX_LPI2C_MODULE_IRQ_CONNECT(n))) -#ifdef CONFIG_NXP_LP_FLEXCOMM -#define PARENT_DEV(n) \ - .parent_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), -#else -#define PARENT_DEV(n) -#endif /* CONFIG_NXP_LP_FLEXCOMM */ +/* When using LP Flexcomm driver, register the interrupt handler + * so we receive notification from the LP Flexcomm interrupt handler. + */ +#define I2C_MCUX_LPI2C_LPFLEXCOMM_IRQ_FUNC(n) \ + nxp_lp_flexcomm_setirqhandler(DEVICE_DT_GET(DT_INST_PARENT(n)), \ + DEVICE_DT_INST_GET(n), \ + LP_FLEXCOMM_PERIPH_LPI2C, \ + mcux_lpi2c_isr) + +#define I2C_MCUX_LPI2C_IRQ_SETUP_FUNC(n) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), \ + nxp_lp_flexcomm), \ + (I2C_MCUX_LPI2C_LPFLEXCOMM_IRQ_FUNC(n)), \ + (I2C_MCUX_LPI2C_MODULE_IRQ(n))) \ #define I2C_MCUX_LPI2C_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ \ - static void mcux_lpi2c_config_func_##n(const struct device *dev); \ + static void mcux_lpi2c_config_func_##n(const struct device *dev)\ + { \ + I2C_MCUX_LPI2C_IRQ_SETUP_FUNC(n); \ + } \ \ static const struct mcux_lpi2c_config mcux_lpi2c_config_##n = { \ DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ - PARENT_DEV(n) \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = \ (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ @@ -616,12 +615,7 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = { I2C_DEVICE_DT_INST_DEFINE(n, mcux_lpi2c_init, NULL, \ &mcux_lpi2c_data_##n, \ &mcux_lpi2c_config_##n, POST_KERNEL, \ - CONFIG_I2C_INIT_PRIORITY, \ - &mcux_lpi2c_driver_api); \ - \ - static void mcux_lpi2c_config_func_##n(const struct device *dev) \ - { \ - I2C_MCUX_LPI2C_MODULE_IRQ(n); \ - } + CONFIG_I2C_INIT_PRIORITY, \ + &mcux_lpi2c_driver_api); DT_INST_FOREACH_STATUS_OKAY(I2C_MCUX_LPI2C_INIT) diff --git a/drivers/i2c/i2c_mcux_lpi2c_rtio.c b/drivers/i2c/i2c_mcux_lpi2c_rtio.c index c88cdf3b78f7e..f267b7ada4ce1 100644 --- a/drivers/i2c/i2c_mcux_lpi2c_rtio.c +++ b/drivers/i2c/i2c_mcux_lpi2c_rtio.c @@ -332,7 +332,7 @@ static int mcux_lpi2c_init(const struct device *dev) return 0; } -static const struct i2c_driver_api mcux_lpi2c_driver_api = { +static DEVICE_API(i2c, mcux_lpi2c_driver_api) = { .configure = mcux_lpi2c_configure, .transfer = mcux_lpi2c_transfer, .iodev_submit = mcux_lpi2c_submit, diff --git a/drivers/i2c/i2c_nios2.c b/drivers/i2c/i2c_nios2.c index bbd1cf2223a5e..c146aa210c674 100644 --- a/drivers/i2c/i2c_nios2.c +++ b/drivers/i2c/i2c_nios2.c @@ -152,7 +152,7 @@ static void i2c_nios2_isr(const struct device *dev) static int i2c_nios2_init(const struct device *dev); -static const struct i2c_driver_api i2c_nios2_driver_api = { +static DEVICE_API(i2c, i2c_nios2_driver_api) = { .configure = i2c_nios2_configure, .transfer = i2c_nios2_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_npcx_controller.c b/drivers/i2c/i2c_npcx_controller.c index 8adcf792e6af6..6c6cac01c7cdb 100644 --- a/drivers/i2c/i2c_npcx_controller.c +++ b/drivers/i2c/i2c_npcx_controller.c @@ -73,10 +73,13 @@ #include #include #include +#include "soc_miwu.h" +#include "soc_pins.h" +#include "soc_power.h" #include #include -LOG_MODULE_REGISTER(i2c_npcx, LOG_LEVEL_ERR); +LOG_MODULE_REGISTER(i2c_npcx, CONFIG_I2C_LOG_LEVEL); /* I2C controller mode */ #define NPCX_I2C_BANK_NORMAL 0 @@ -117,6 +120,11 @@ enum npcx_i2c_flag { NPCX_I2C_FLAG_COUNT, }; +enum i2c_pm_policy_state_flag { + I2C_PM_POLICY_STATE_FLAG_TGT, + I2C_PM_POLICY_STATE_FLAG_COUNT, +}; + /* * Internal SMBus Interface driver states values, which reflect events * which occurred on the bus @@ -145,6 +153,11 @@ struct i2c_ctrl_config { uintptr_t base; /* i2c controller base address */ struct npcx_clk_cfg clk_cfg; /* clock configuration */ uint8_t irq; /* i2c controller irq */ +#ifdef CONFIG_I2C_TARGET + /* i2c wake-up input source configuration */ + const struct npcx_wui smb_wui; + bool wakeup_source; +#endif /* CONFIG_I2C_TARGET */ }; /* Driver data */ @@ -164,7 +177,13 @@ struct i2c_ctrl_data { #ifdef CONFIG_I2C_TARGET struct i2c_target_config *target_cfg; atomic_t flags; -#endif + /* i2c wake-up callback configuration */ + struct miwu_callback smb_wk_cb; +#endif /* CONFIG_I2C_TARGET */ + +#if defined(CONFIG_PM) && defined(CONFIG_I2C_TARGET) + ATOMIC_DEFINE(pm_policy_state_flag, I2C_PM_POLICY_STATE_FLAG_COUNT); +#endif /* CONFIG_PM && CONFIG_I2C_TARGET */ }; /* Driver convenience defines */ @@ -184,6 +203,38 @@ static const struct npcx_i2c_timing_cfg npcx_20m_speed_confs[] = { [NPCX_I2C_BUS_SPEED_1MHZ] = {.HLDT = 7, .k1 = 16, .k2 = 10}, }; +#if defined(CONFIG_PM) && defined(CONFIG_I2C_TARGET) +static void i2c_npcx_pm_policy_state_lock_get(const struct device *dev, + enum i2c_pm_policy_state_flag flag) +{ + const struct i2c_ctrl_config *const config = dev->config; + struct i2c_ctrl_data *const data = dev->data; + + if (!config->wakeup_source) { + return; + } + + if (atomic_test_and_set_bit(data->pm_policy_state_flag, flag) == 0) { + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + } +} + +static void i2c_npcx_pm_policy_state_lock_put(const struct device *dev, + enum i2c_pm_policy_state_flag flag) +{ + const struct i2c_ctrl_config *const config = dev->config; + struct i2c_ctrl_data *const data = dev->data; + + if (!config->wakeup_source) { + return; + } + + if (atomic_test_and_clear_bit(data->pm_policy_state_flag, flag) == 1) { + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + } +} +#endif /* CONFIG_PM && CONFIG_I2C_TARGET */ + /* I2C controller inline functions access shared registers */ static inline void i2c_ctrl_start(const struct device *dev) { @@ -779,6 +830,10 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status) /* End of transaction */ data->oper_state = NPCX_I2C_IDLE; +#ifdef CONFIG_PM + i2c_npcx_pm_policy_state_lock_put(dev, I2C_PM_POLICY_STATE_FLAG_TGT); +#endif /* CONFIG_PM */ + LOG_DBG("target: Bus error on port%02x!", data->port); return; } @@ -793,6 +848,10 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status) if (target_cb->stop) { target_cb->stop(data->target_cfg); } + +#ifdef CONFIG_PM + i2c_npcx_pm_policy_state_lock_put(dev, I2C_PM_POLICY_STATE_FLAG_TGT); +#endif /* CONFIG_PM */ return; } @@ -857,7 +916,7 @@ static void i2c_ctrl_target_isr(const struct device *dev, uint8_t status) status, data->port); } } -#endif +#endif /* CONFIG_I2C_TARGET */ /* I2C controller isr function */ static void i2c_ctrl_isr(const struct device *dev) @@ -874,7 +933,7 @@ static void i2c_ctrl_isr(const struct device *dev) i2c_ctrl_target_isr(dev, status); return; } -#endif +#endif /* CONFIG_I2C_TARGET */ /* A 'Bus Error' has been identified */ if (IS_BIT_SET(status, NPCX_SMBST_BER)) { @@ -1073,6 +1132,7 @@ int npcx_i2c_ctrl_target_register(const struct device *i2c_dev, struct i2c_target_config *target_cfg, uint8_t port) { struct smb_reg *const inst = HAL_I2C_INSTANCE(i2c_dev); + const struct i2c_ctrl_config *const config = i2c_dev->config; struct i2c_ctrl_data *const data = i2c_dev->data; int idx_ctrl = (port & 0xF0) >> 4; int idx_port = (port & 0x0F); @@ -1105,16 +1165,29 @@ int npcx_i2c_ctrl_target_register(const struct device *i2c_dev, /* Reconfigure SMBCTL1 */ inst->SMBCTL1 |= BIT(NPCX_SMBCTL1_NMINTE) | BIT(NPCX_SMBCTL1_INTEN); + + /* Enable irq of smb wake-up event */ + if (IS_ENABLED(CONFIG_PM) && config->wakeup_source) { + + /* Enable SMB wake up detection */ + npcx_i2c_target_start_wk_enable(idx_ctrl, true); + /* Enable start detect in IDLE */ + inst->SMBCTL3 |= BIT(NPCX_SMBCTL3_IDL_START); + /* Enable SMB's MIWU interrupts */ + npcx_miwu_irq_enable(&config->smb_wui); + } i2c_ctrl_irq_enable(i2c_dev, 1); return 0; } int npcx_i2c_ctrl_target_unregister(const struct device *i2c_dev, - struct i2c_target_config *target_cfg) + struct i2c_target_config *target_cfg, uint8_t port) { struct smb_reg *const inst = HAL_I2C_INSTANCE(i2c_dev); + const struct i2c_ctrl_config *const config = i2c_dev->config; struct i2c_ctrl_data *const data = i2c_dev->data; + int idx_ctrl = (port & 0xF0) >> 4; /* No I2c module has been configured to target mode */ if (!atomic_test_bit(&data->flags, NPCX_I2C_FLAG_TARGET)) { @@ -1139,14 +1212,46 @@ int npcx_i2c_ctrl_target_unregister(const struct device *i2c_dev, /* Reconfigure SMBCTL1 */ inst->SMBCTL1 |= BIT(NPCX_SMBCTL1_NMINTE) | BIT(NPCX_SMBCTL1_INTEN); - i2c_ctrl_irq_enable(i2c_dev, 1); + /* Disable irq of smb wake-up event */ + if (IS_ENABLED(CONFIG_PM)) { + /* Disable SMB wake up detection */ + npcx_i2c_target_start_wk_enable(idx_ctrl, false); + /* Disable start detect in IDLE */ + inst->SMBCTL3 &= ~BIT(NPCX_SMBCTL3_IDL_START); + /* Disable SMB's MIWU interrupts */ + npcx_miwu_irq_disable(&config->smb_wui); + + } + i2c_ctrl_irq_enable(i2c_dev, 1); /* Mark it as controller mode */ atomic_clear_bit(&data->flags, NPCX_I2C_FLAG_TARGET); return 0; } -#endif + +static void i2c_target_wk_isr(const struct device *dev, struct npcx_wui *wui) +{ + struct smb_reg *const inst = HAL_I2C_INSTANCE(dev); + + /* Clear wake up detection event status */ + npcx_i2c_target_clear_detection_event(); + + /* Reconfigure SMBCTL1 */ + inst->SMBCTL1 |= BIT(NPCX_SMBCTL1_NMINTE) | BIT(NPCX_SMBCTL1_INTEN); + + /* + * Suspend-to-idle stops SMB module clocks (derived from APB2/APB3), which must remain + * active during a transaction. + * + * This also prevent Sr set pm_policy_state_lock_get() twice. + * Otherwise, it will cause I2C cannot switch to deep sleep state for the next time. + */ +#ifdef CONFIG_PM + i2c_npcx_pm_policy_state_lock_get(dev, I2C_PM_POLICY_STATE_FLAG_TGT); +#endif /* CONFIG_PM */ +} +#endif /* CONFIG_I2C_TARGET */ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr, int port) @@ -1160,7 +1265,7 @@ int npcx_i2c_ctrl_transfer(const struct device *i2c_dev, struct i2c_msg *msgs, if (atomic_test_bit(&data->flags, NPCX_I2C_FLAG_TARGET)) { return -EBUSY; } -#endif +#endif /* CONFIG_I2C_TARGET */ /* * suspend-to-idle stops SMB module clocks (derived from APB2/APB3), which must remain @@ -1285,6 +1390,21 @@ static int i2c_ctrl_init(const struct device *dev) /* Initialize i2c module */ i2c_ctrl_init_module(dev); +#ifdef CONFIG_I2C_TARGET + if (IS_ENABLED(CONFIG_PM) && config->wakeup_source) { + /* Initialize a miwu device input and its callback function */ + npcx_miwu_init_dev_callback(&data->smb_wk_cb, &config->smb_wui, + i2c_target_wk_isr, dev); + npcx_miwu_manage_callback(&data->smb_wk_cb, true); + /* + * Configure Start condition wake-up configuration of SMB + * controller. + */ + npcx_miwu_interrupt_configure(&config->smb_wui, NPCX_MIWU_MODE_EDGE, + NPCX_MIWU_TRIG_HIGH); + } +#endif /* CONFIG_I2C_TARGET */ + /* initialize mutex and semaphore for i2c/smb controller */ k_sem_init(&data->lock_sem, 1, 1); k_sem_init(&data->sync_sem, 0, K_SEM_MAX_LIMIT); @@ -1316,24 +1436,28 @@ static int i2c_ctrl_init(const struct device *dev) } -#define NPCX_I2C_CTRL_INIT(inst) \ - NPCX_I2C_CTRL_INIT_FUNC_DECL(inst); \ - \ - static const struct i2c_ctrl_config i2c_ctrl_cfg_##inst = { \ - .base = DT_INST_REG_ADDR(inst), \ - .irq = DT_INST_IRQN(inst), \ - .clk_cfg = NPCX_DT_CLK_CFG_ITEM(inst), \ - }; \ - \ - static struct i2c_ctrl_data i2c_ctrl_data_##inst; \ - \ - DEVICE_DT_INST_DEFINE(inst, \ - NPCX_I2C_CTRL_INIT_FUNC(inst), \ - NULL, \ - &i2c_ctrl_data_##inst, &i2c_ctrl_cfg_##inst, \ - PRE_KERNEL_1, CONFIG_I2C_INIT_PRIORITY, \ - NULL); \ - \ +#define NPCX_I2C_CTRL_INIT(inst) \ + NPCX_I2C_CTRL_INIT_FUNC_DECL(inst); \ + \ + static const struct i2c_ctrl_config i2c_ctrl_cfg_##inst = { \ + .base = DT_INST_REG_ADDR(inst), \ + .irq = DT_INST_IRQN(inst), \ + .clk_cfg = NPCX_DT_CLK_CFG_ITEM(inst), \ + IF_ENABLED(CONFIG_I2C_TARGET, ( \ + .smb_wui = NPCX_DT_WUI_ITEM_BY_NAME(inst, smb_wui), \ + .wakeup_source = DT_INST_PROP_OR(inst, wakeup_source, 0) \ + )) \ + }; \ + \ + static struct i2c_ctrl_data i2c_ctrl_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, \ + NPCX_I2C_CTRL_INIT_FUNC(inst), \ + NULL, \ + &i2c_ctrl_data_##inst, &i2c_ctrl_cfg_##inst, \ + PRE_KERNEL_1, CONFIG_I2C_INIT_PRIORITY, \ + NULL); \ + \ NPCX_I2C_CTRL_INIT_FUNC_IMPL(inst) DT_INST_FOREACH_STATUS_OKAY(NPCX_I2C_CTRL_INIT) diff --git a/drivers/i2c/i2c_npcx_controller.h b/drivers/i2c/i2c_npcx_controller.h index 6155f1a1499c1..dc80aba386fdf 100644 --- a/drivers/i2c/i2c_npcx_controller.h +++ b/drivers/i2c/i2c_npcx_controller.h @@ -98,13 +98,14 @@ int npcx_i2c_ctrl_target_register(const struct device *i2c_dev, * * @param i2c_dev Pointer to the device structure for i2c controller instance. * @param target_cfg Config struct used by the i2c target driver + * @param port Port index of selected i2c port. * * @retval 0 Is successful * @retval -EBUSY If i2c transaction is proceeding. * @retval -EINVAL If parameters are invalid */ int npcx_i2c_ctrl_target_unregister(const struct device *i2c_dev, - struct i2c_target_config *target_cfg); + struct i2c_target_config *target_cfg, uint8_t port); #ifdef __cplusplus } diff --git a/drivers/i2c/i2c_npcx_port.c b/drivers/i2c/i2c_npcx_port.c index 1763890956172..37505787319d1 100644 --- a/drivers/i2c/i2c_npcx_port.c +++ b/drivers/i2c/i2c_npcx_port.c @@ -36,7 +36,7 @@ #include #include -LOG_MODULE_REGISTER(i2c_npcx_port, LOG_LEVEL_ERR); +LOG_MODULE_REGISTER(i2c_npcx_port, CONFIG_I2C_LOG_LEVEL); #include "i2c_npcx_controller.h" #include "i2c-priv.h" @@ -171,7 +171,7 @@ static int i2c_npcx_target_unregister(const struct device *dev, return -EIO; } - return npcx_i2c_ctrl_target_unregister(config->i2c_ctrl, target_cfg); + return npcx_i2c_ctrl_target_unregister(config->i2c_ctrl, target_cfg, config->port); } #endif @@ -200,7 +200,7 @@ static int i2c_npcx_port_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_port_npcx_driver_api = { +static DEVICE_API(i2c, i2c_port_npcx_driver_api) = { .configure = i2c_npcx_port_configure, .get_config = i2c_npcx_port_get_config, .transfer = i2c_npcx_port_transfer, diff --git a/drivers/i2c/i2c_nrfx_twi.c b/drivers/i2c/i2c_nrfx_twi.c index 56d3727e125ef..c2c0a28d8756e 100644 --- a/drivers/i2c/i2c_nrfx_twi.c +++ b/drivers/i2c/i2c_nrfx_twi.c @@ -125,7 +125,7 @@ static void event_handler(nrfx_twi_evt_t const *p_event, void *p_context) k_sem_give(&dev_data->completion_sync); } -static const struct i2c_driver_api i2c_nrfx_twi_driver_api = { +static DEVICE_API(i2c, i2c_nrfx_twi_driver_api) = { .configure = i2c_nrfx_twi_configure, .transfer = i2c_nrfx_twi_transfer, .recover_bus = i2c_nrfx_twi_recover_bus, diff --git a/drivers/i2c/i2c_nrfx_twi_rtio.c b/drivers/i2c/i2c_nrfx_twi_rtio.c index 1eb9b3762b297..9dc1b54914cd6 100644 --- a/drivers/i2c/i2c_nrfx_twi_rtio.c +++ b/drivers/i2c/i2c_nrfx_twi_rtio.c @@ -152,7 +152,7 @@ static void i2c_nrfx_twi_rtio_submit(const struct device *dev, struct rtio_iodev } } -static const struct i2c_driver_api i2c_nrfx_twi_rtio_driver_api = { +static DEVICE_API(i2c, i2c_nrfx_twi_rtio_driver_api) = { .configure = i2c_nrfx_twi_rtio_configure, .transfer = i2c_nrfx_twi_rtio_transfer, .recover_bus = i2c_nrfx_twi_rtio_recover_bus, diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index 9609709d8c354..6be4b1c1050a7 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -204,7 +204,7 @@ static int i2c_nrfx_twim_init(const struct device *dev) return i2c_nrfx_twim_common_init(dev); } -static const struct i2c_driver_api i2c_nrfx_twim_driver_api = { +static DEVICE_API(i2c, i2c_nrfx_twim_driver_api) = { .configure = i2c_nrfx_twim_configure, .transfer = i2c_nrfx_twim_transfer, #ifdef CONFIG_I2C_RTIO @@ -258,7 +258,8 @@ static const struct i2c_driver_api i2c_nrfx_twim_driver_api = { .max_transfer_size = BIT_MASK( \ DT_PROP(I2C(idx), easydma_maxcnt_bits)), \ }; \ - PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action); \ + PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, \ + PM_DEVICE_ISR_SAFE); \ I2C_DEVICE_DT_DEFINE(I2C(idx), \ i2c_nrfx_twim_init, \ PM_DEVICE_DT_GET(I2C(idx)), \ diff --git a/drivers/i2c/i2c_nrfx_twim_rtio.c b/drivers/i2c/i2c_nrfx_twim_rtio.c index ad4554332639b..8b5f2c625f8fc 100644 --- a/drivers/i2c/i2c_nrfx_twim_rtio.c +++ b/drivers/i2c/i2c_nrfx_twim_rtio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "i2c_nrfx_twim_common.h" @@ -25,6 +26,11 @@ struct i2c_nrfx_twim_rtio_config { struct i2c_rtio *ctx; }; +struct i2c_nrfx_twim_rtio_data { + uint8_t *user_rx_buf; + uint16_t user_rx_buf_size; +}; + static bool i2c_nrfx_twim_rtio_msg_start(const struct device *dev, uint8_t flags, uint8_t *buf, size_t buf_len, uint16_t i2c_addr) { @@ -43,12 +49,28 @@ static bool i2c_nrfx_twim_rtio_msg_start(const struct device *dev, uint8_t flags static bool i2c_nrfx_twim_rtio_start(const struct device *dev) { const struct i2c_nrfx_twim_rtio_config *config = dev->config; + struct i2c_nrfx_twim_rtio_data *data = dev->data; struct i2c_rtio *ctx = config->ctx; struct rtio_sqe *sqe = &ctx->txn_curr->sqe; struct i2c_dt_spec *dt_spec = sqe->iodev->data; switch (sqe->op) { case RTIO_OP_RX: + if (!nrf_dma_accessible_check(&config->common.twim, sqe->rx.buf)) { + if (sqe->rx.buf_len > config->common.msg_buf_size) { + return i2c_rtio_complete(ctx, -ENOSPC); + } + + data->user_rx_buf = sqe->rx.buf; + data->user_rx_buf_size = sqe->rx.buf_len; + return i2c_nrfx_twim_rtio_msg_start(dev, + I2C_MSG_READ | sqe->iodev_flags, + config->common.msg_buf, + data->user_rx_buf_size, + dt_spec->addr); + } + + data->user_rx_buf = NULL; return i2c_nrfx_twim_rtio_msg_start(dev, I2C_MSG_READ | sqe->iodev_flags, sqe->rx.buf, sqe->rx.buf_len, dt_spec->addr); case RTIO_OP_TINY_TX: @@ -74,7 +96,8 @@ static bool i2c_nrfx_twim_rtio_start(const struct device *dev) sqe->tx.buf = config->common.msg_buf; } return i2c_nrfx_twim_rtio_msg_start(dev, I2C_MSG_WRITE | sqe->iodev_flags, - sqe->tx.buf, sqe->tx.buf_len, dt_spec->addr); + (uint8_t *)sqe->tx.buf, sqe->tx.buf_len, + dt_spec->addr); case RTIO_OP_I2C_CONFIGURE: (void)i2c_nrfx_twim_configure(dev, sqe->i2c_config); return false; @@ -143,12 +166,18 @@ static void i2c_nrfx_twim_rtio_submit(const struct device *dev, struct rtio_iode static void event_handler(nrfx_twim_evt_t const *p_event, void *p_context) { const struct device *dev = p_context; + const struct i2c_nrfx_twim_rtio_config *config = dev->config; + struct i2c_nrfx_twim_rtio_data *data = dev->data; int status = p_event->type == NRFX_TWIM_EVT_DONE ? 0 : -EIO; + if (data->user_rx_buf) { + memcpy(data->user_rx_buf, config->common.msg_buf, data->user_rx_buf_size); + } + i2c_nrfx_twim_rtio_complete(dev, status); } -static const struct i2c_driver_api i2c_nrfx_twim_driver_api = { +static DEVICE_API(i2c, i2c_nrfx_twim_driver_api) = { .configure = i2c_nrfx_twim_rtio_configure, .transfer = i2c_nrfx_twim_rtio_transfer, .recover_bus = i2c_nrfx_twim_rtio_recover_bus, @@ -174,6 +203,31 @@ int i2c_nrfx_twim_rtio_init(const struct device *dev) COND_CODE_0(CONCAT_BUF_SIZE(idx), (COND_CODE_0(FLASH_BUF_MAX_SIZE(idx), (0), (1))), (1)) #define MSG_BUF_SIZE(idx) MAX(CONCAT_BUF_SIZE(idx), FLASH_BUF_MAX_SIZE(idx)) +#define MSG_BUF_HAS_MEMORY_REGIONS(idx) \ + DT_NODE_HAS_PROP(I2C(idx), memory_regions) + +#define MSG_BUF_LINKER_REGION_NAME(idx) \ + LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(I2C(idx), memory_regions)) + +#define MSG_BUF_ATTR_SECTION(idx) \ + __attribute__((__section__(MSG_BUF_LINKER_REGION_NAME(idx)))) + +#define MSG_BUF_ATTR(idx) \ + COND_CODE_1( \ + MSG_BUF_HAS_MEMORY_REGIONS(idx), \ + (MSG_BUF_ATTR_SECTION(idx)), \ + () \ + ) + +#define MSG_BUF_SYM(idx) \ + _CONCAT_3(twim_, idx, _msg_buf) + +#define MSG_BUF_DEFINE(idx) \ + static uint8_t MSG_BUF_SYM(idx)[MSG_BUF_SIZE(idx)] MSG_BUF_ATTR(idx) + +#define MAX_TRANSFER_SIZE(idx) \ + BIT_MASK(DT_PROP(I2C(idx), easydma_maxcnt_bits)) + #define I2C_NRFX_TWIM_RTIO_DEVICE(idx) \ NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(I2C(idx)); \ BUILD_ASSERT(I2C_FREQUENCY(idx) != I2C_NRFX_TWIM_INVALID_FREQUENCY, \ @@ -183,13 +237,12 @@ int i2c_nrfx_twim_rtio_init(const struct device *dev) IRQ_CONNECT(DT_IRQN(I2C(idx)), DT_IRQ(I2C(idx), priority), nrfx_isr, \ nrfx_twim_##idx##_irq_handler, 0); \ } \ - IF_ENABLED( \ - USES_MSG_BUF(idx), \ - (static uint8_t twim_##idx##_msg_buf[MSG_BUF_SIZE(idx)] I2C_MEMORY_SECTION(idx);)) \ + IF_ENABLED(USES_MSG_BUF(idx), (MSG_BUF_DEFINE(idx);)) \ I2C_RTIO_DEFINE(_i2c##idx##_twim_rtio, \ DT_INST_PROP_OR(n, sq_size, CONFIG_I2C_RTIO_SQ_SIZE), \ DT_INST_PROP_OR(n, cq_size, CONFIG_I2C_RTIO_CQ_SIZE)); \ PINCTRL_DT_DEFINE(I2C(idx)); \ + static struct i2c_nrfx_twim_rtio_data twim_##idx##z_data; \ static const struct i2c_nrfx_twim_rtio_config twim_##idx##z_config = { \ .common = \ { \ @@ -204,22 +257,15 @@ int i2c_nrfx_twim_rtio_init(const struct device *dev) .msg_buf_size = MSG_BUF_SIZE(idx), \ .irq_connect = irq_connect##idx, \ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \ - IF_ENABLED(USES_MSG_BUF(idx), (.msg_buf = twim_##idx##_msg_buf,)) \ - .max_transfer_size = \ - BIT_MASK(DT_PROP(I2C(idx), easydma_maxcnt_bits)), \ + IF_ENABLED(USES_MSG_BUF(idx), (.msg_buf = MSG_BUF_SYM(idx),)) \ + .max_transfer_size = MAX_TRANSFER_SIZE(idx), \ }, \ .ctx = &_i2c##idx##_twim_rtio, \ }; \ - PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action); \ - I2C_DEVICE_DT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, PM_DEVICE_DT_GET(I2C(idx)), NULL, \ - &twim_##idx##z_config, POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \ - &i2c_nrfx_twim_driver_api) - -#define I2C_MEMORY_SECTION(idx) \ - COND_CODE_1(I2C_HAS_PROP(idx, memory_regions), \ - (__attribute__((__section__( \ - LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(I2C(idx), memory_regions)))))), \ - ()) + PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, PM_DEVICE_ISR_SAFE); \ + I2C_DEVICE_DT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, PM_DEVICE_DT_GET(I2C(idx)), \ + &twim_##idx##z_data, &twim_##idx##z_config, POST_KERNEL, \ + CONFIG_I2C_INIT_PRIORITY, &i2c_nrfx_twim_driver_api); #ifdef CONFIG_HAS_HW_NRF_TWIM0 I2C_NRFX_TWIM_RTIO_DEVICE(0); diff --git a/drivers/i2c/i2c_nrfx_twis.c b/drivers/i2c/i2c_nrfx_twis.c new file mode 100644 index 0000000000000..9e2b0759f2a3a --- /dev/null +++ b/drivers/i2c/i2c_nrfx_twis.c @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DT_DRV_COMPAT nordic_nrf_twis + +#define SHIM_NRF_TWIS_NODE(id) \ + DT_NODELABEL(_CONCAT(i2c, id)) + +#define SHIM_NRF_TWIS_DEVICE_GET(id) \ + DEVICE_DT_GET(SHIM_NRF_TWIS_NODE(id)) + +#define SHIM_NRF_TWIS_IRQ_HANDLER(id) \ + _CONCAT_3(nrfx_twis_, id, _irq_handler) + +#define SHIM_NRF_TWIS_IRQN(id) \ + DT_IRQN(SHIM_NRF_TWIS_NODE(id)) + +#define SHIM_NRF_TWIS_IRQ_PRIO(id) \ + DT_IRQ(SHIM_NRF_TWIS_NODE(id), priority) + +#define SHIM_NRF_TWIS_HAS_MEMORY_REGIONS(id) \ + DT_NODE_HAS_PROP(SHIM_NRF_TWIS_NODE(id), memory_regions) + +#define SHIM_NRF_TWIS_LINKER_REGION_NAME(id) \ + LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(SHIM_NRF_TWIS_NODE(id), memory_regions)) + +#define SHIM_NRF_TWIS_BUF_ATTR_SECTION(id) \ + __attribute__((__section__(SHIM_NRF_TWIS_LINKER_REGION_NAME(id)))) + +#define SHIM_NRF_TWIS_BUF_ATTR(id) \ + COND_CODE_1( \ + SHIM_NRF_TWIS_HAS_MEMORY_REGIONS(id), \ + (SHIM_NRF_TWIS_BUF_ATTR_SECTION(id)), \ + () \ + ) + +#define SHIM_NRF_TWIS_BUF_SIZE \ + CONFIG_I2C_NRFX_TWIS_BUF_SIZE + +LOG_MODULE_REGISTER(i2c_nrfx_twis, CONFIG_I2C_LOG_LEVEL); + +struct shim_nrf_twis_config { + nrfx_twis_t twis; + void (*irq_connect)(void); + void (*event_handler)(nrfx_twis_evt_t const *event); + const struct pinctrl_dev_config *pcfg; + uint8_t *buf; +}; + +struct shim_nrf_twis_data { + struct i2c_target_config *target_config; + bool enabled; +}; + +#if CONFIG_PM_DEVICE +static bool shim_nrf_twis_is_resumed(const struct device *dev) +{ + enum pm_device_state state; + + (void)pm_device_state_get(dev, &state); + return state == PM_DEVICE_STATE_ACTIVE; +} +#else +static bool shim_nrf_twis_is_resumed(const struct device *dev) +{ + ARG_UNUSED(dev); + + return true; +} +#endif + +static void shim_nrf_twis_enable(const struct device *dev) +{ + struct shim_nrf_twis_data *dev_data = dev->data; + const struct shim_nrf_twis_config *dev_config = dev->config; + + if (dev_data->enabled) { + return; + } + + if (dev_data->target_config == NULL) { + return; + } + + (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + nrfx_twis_enable(&dev_config->twis); + dev_data->enabled = true; +} + +static void shim_nrf_twis_disable(const struct device *dev) +{ + struct shim_nrf_twis_data *dev_data = dev->data; + const struct shim_nrf_twis_config *dev_config = dev->config; + + if (!dev_data->enabled) { + return; + } + + dev_data->enabled = false; + nrfx_twis_disable(&dev_config->twis); + (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); +} + +static void shim_nrf_twis_handle_read_req(const struct device *dev) +{ + struct shim_nrf_twis_data *dev_data = dev->data; + const struct shim_nrf_twis_config *dev_config = dev->config; + struct i2c_target_config *target_config = dev_data->target_config; + const struct i2c_target_callbacks *callbacks = target_config->callbacks; + const nrfx_twis_t *twis = &dev_config->twis; + uint8_t *buf; + uint32_t buf_size; + nrfx_err_t err; + + if (callbacks->buf_read_requested(target_config, &buf, &buf_size)) { + LOG_ERR("no buffer provided"); + return; + } + + if (SHIM_NRF_TWIS_BUF_SIZE < buf_size) { + LOG_ERR("provided buffer too large"); + return; + } + + memcpy(dev_config->buf, buf, buf_size); + + err = nrfx_twis_tx_prepare(twis, dev_config->buf, buf_size); + if (err != NRFX_SUCCESS) { + LOG_ERR("tx prepare failed"); + return; + } +} + +static void shim_nrf_twis_handle_write_req(const struct device *dev) +{ + const struct shim_nrf_twis_config *dev_config = dev->config; + const nrfx_twis_t *twis = &dev_config->twis; + nrfx_err_t err; + + err = nrfx_twis_rx_prepare(twis, dev_config->buf, SHIM_NRF_TWIS_BUF_SIZE); + if (err != NRFX_SUCCESS) { + LOG_ERR("rx prepare failed"); + return; + } +} + +static void shim_nrf_twis_handle_write_done(const struct device *dev) +{ + struct shim_nrf_twis_data *dev_data = dev->data; + const struct shim_nrf_twis_config *dev_config = dev->config; + struct i2c_target_config *target_config = dev_data->target_config; + const struct i2c_target_callbacks *callbacks = target_config->callbacks; + const nrfx_twis_t *twis = &dev_config->twis; + + callbacks->buf_write_received(target_config, dev_config->buf, nrfx_twis_rx_amount(twis)); +} + +static void shim_nrf_twis_event_handler(const struct device *dev, + nrfx_twis_evt_t const *event) +{ + switch (event->type) { + case NRFX_TWIS_EVT_READ_REQ: + shim_nrf_twis_handle_read_req(dev); + break; + + case NRFX_TWIS_EVT_WRITE_REQ: + shim_nrf_twis_handle_write_req(dev); + break; + + case NRFX_TWIS_EVT_WRITE_DONE: + shim_nrf_twis_handle_write_done(dev); + break; + + default: + break; + } +} + +static int shim_nrf_twis_pm_action_cb(const struct device *dev, + enum pm_device_action action) +{ + switch (action) { + case PM_DEVICE_ACTION_RESUME: + shim_nrf_twis_enable(dev); + break; + +#if CONFIG_PM_DEVICE + case PM_DEVICE_ACTION_SUSPEND: + shim_nrf_twis_disable(); + break; +#endif + + default: + return -ENOTSUP; + } + + return 0; +} + +static int shim_nrf_twis_target_register(const struct device *dev, + struct i2c_target_config *target_config) +{ + struct shim_nrf_twis_data *dev_data = dev->data; + const struct shim_nrf_twis_config *dev_config = dev->config; + const nrfx_twis_t *twis = &dev_config->twis; + nrfx_err_t err; + const nrfx_twis_config_t config = { + .addr = { + target_config->address, + }, + .skip_gpio_cfg = true, + .skip_psel_cfg = true, + }; + + if (target_config->flags) { + LOG_ERR("16-bit address unsupported"); + return -EINVAL; + } + + shim_nrf_twis_disable(dev); + + err = nrfx_twis_reconfigure(twis, &config); + if (err != NRFX_SUCCESS) { + return -ENODEV; + } + + dev_data->target_config = target_config; + + if (shim_nrf_twis_is_resumed(dev)) { + shim_nrf_twis_enable(dev); + } + + return 0; +} + +static int shim_nrf_twis_target_unregister(const struct device *dev, + struct i2c_target_config *target_config) +{ + struct shim_nrf_twis_data *dev_data = dev->data; + + if (dev_data->target_config != target_config) { + return -EINVAL; + } + + shim_nrf_twis_disable(dev); + dev_data->target_config = NULL; + return 0; +} + +const struct i2c_driver_api shim_nrf_twis_api = { + .target_register = shim_nrf_twis_target_register, + .target_unregister = shim_nrf_twis_target_unregister, +}; + +static int shim_nrf_twis_init(const struct device *dev) +{ + const struct shim_nrf_twis_config *dev_config = dev->config; + nrfx_err_t err; + const nrfx_twis_config_t config = { + .skip_gpio_cfg = true, + .skip_psel_cfg = true, + }; + + err = nrfx_twis_init(&dev_config->twis, &config, dev_config->event_handler); + if (err != NRFX_SUCCESS) { + return -ENODEV; + } + + dev_config->irq_connect(); + return pm_device_driver_init(dev, shim_nrf_twis_pm_action_cb); +} + +#define SHIM_NRF_TWIS_NAME(id, name) \ + _CONCAT_4(shim_nrf_twis_, name, _, id) + +#define SHIM_NRF_TWIS_DEVICE_DEFINE(id) \ + static void SHIM_NRF_TWIS_NAME(id, irq_connect)(void) \ + { \ + IRQ_CONNECT( \ + SHIM_NRF_TWIS_IRQN(id), \ + SHIM_NRF_TWIS_IRQ_PRIO(id), \ + nrfx_isr, \ + SHIM_NRF_TWIS_IRQ_HANDLER(id), \ + 0 \ + ); \ + } \ + \ + static void SHIM_NRF_TWIS_NAME(id, event_handler)(nrfx_twis_evt_t const *event) \ + { \ + shim_nrf_twis_event_handler(SHIM_NRF_TWIS_DEVICE_GET(id), event); \ + } \ + \ + static struct shim_nrf_twis_data SHIM_NRF_TWIS_NAME(id, data); \ + \ + PINCTRL_DT_DEFINE(SHIM_NRF_TWIS_NODE(id)); \ + \ + static uint8_t SHIM_NRF_TWIS_NAME(id, buf) \ + [SHIM_NRF_TWIS_BUF_SIZE] SHIM_NRF_TWIS_BUF_ATTR(id); \ + \ + static const struct shim_nrf_twis_config SHIM_NRF_TWIS_NAME(id, config) = { \ + .twis = NRFX_TWIS_INSTANCE(id), \ + .irq_connect = SHIM_NRF_TWIS_NAME(id, irq_connect), \ + .event_handler = SHIM_NRF_TWIS_NAME(id, event_handler), \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SHIM_NRF_TWIS_NODE(id)), \ + .buf = SHIM_NRF_TWIS_NAME(id, buf), \ + }; \ + \ + PM_DEVICE_DT_DEFINE( \ + SHIM_NRF_TWIS_NODE(id), \ + shim_nrf_twis_pm_action_cb, \ + ); \ + \ + DEVICE_DT_DEFINE( \ + SHIM_NRF_TWIS_NODE(id), \ + shim_nrf_twis_init, \ + PM_DEVICE_DT_GET(SHIM_NRF_TWIS_NODE(id)), \ + &SHIM_NRF_TWIS_NAME(id, data), \ + &SHIM_NRF_TWIS_NAME(id, config), \ + POST_KERNEL, \ + CONFIG_I2C_INIT_PRIORITY, \ + &shim_nrf_twis_api \ + ); + +#ifdef CONFIG_HAS_HW_NRF_TWIS0 +SHIM_NRF_TWIS_DEVICE_DEFINE(0); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS1 +SHIM_NRF_TWIS_DEVICE_DEFINE(1); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS2 +SHIM_NRF_TWIS_DEVICE_DEFINE(2); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS3 +SHIM_NRF_TWIS_DEVICE_DEFINE(3); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS20 +SHIM_NRF_TWIS_DEVICE_DEFINE(20); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS21 +SHIM_NRF_TWIS_DEVICE_DEFINE(21); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS22 +SHIM_NRF_TWIS_DEVICE_DEFINE(22); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS30 +SHIM_NRF_TWIS_DEVICE_DEFINE(30); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS130 +SHIM_NRF_TWIS_DEVICE_DEFINE(130); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS131 +SHIM_NRF_TWIS_DEVICE_DEFINE(131); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS133 +SHIM_NRF_TWIS_DEVICE_DEFINE(133); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS134 +SHIM_NRF_TWIS_DEVICE_DEFINE(134); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS135 +SHIM_NRF_TWIS_DEVICE_DEFINE(135); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS136 +SHIM_NRF_TWIS_DEVICE_DEFINE(136); +#endif + +#ifdef CONFIG_HAS_HW_NRF_TWIS137 +SHIM_NRF_TWIS_DEVICE_DEFINE(137); +#endif diff --git a/drivers/i2c/i2c_numaker.c b/drivers/i2c/i2c_numaker.c index 9441db55ca0e5..df2076becac35 100644 --- a/drivers/i2c/i2c_numaker.c +++ b/drivers/i2c/i2c_numaker.c @@ -732,7 +732,7 @@ static int i2c_numaker_init(const struct device *dev) return err; } -static const struct i2c_driver_api i2c_numaker_driver_api = { +static DEVICE_API(i2c, i2c_numaker_driver_api) = { .configure = i2c_numaker_configure, .get_config = i2c_numaker_get_config, .transfer = i2c_numaker_transfer, diff --git a/drivers/i2c/i2c_nxp_ii2c.c b/drivers/i2c/i2c_nxp_ii2c.c new file mode 100644 index 0000000000000..bfe6cf1467e9c --- /dev/null +++ b/drivers/i2c/i2c_nxp_ii2c.c @@ -0,0 +1,414 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_ii2c + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +LOG_MODULE_REGISTER(i2c_nxp_ii2c); + +#include "i2c-priv.h" + +#define DEV_CFG(_dev) ((const struct nxp_ii2c_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct nxp_ii2c_data *)(_dev)->data) + +struct nxp_ii2c_config { + DEVICE_MMIO_NAMED_ROM(reg_base); + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + void (*irq_config_func)(const struct device *dev); + uint32_t bitrate; + const struct pinctrl_dev_config *pincfg; +}; + +struct nxp_ii2c_data { + DEVICE_MMIO_NAMED_RAM(reg_base); + i2c_master_handle_t handle; + struct k_sem lock; + struct k_sem device_sync_sem; + status_t callback_status; +#ifdef CONFIG_I2C_CALLBACK + uint16_t addr; + uint32_t msg; + struct i2c_msg *msgs; + uint32_t num_msgs; + i2c_callback_t cb; + void *userdata; +#endif /* CONFIG_I2C_CALLBACK */ +}; + +static I2C_Type *get_base(const struct device *dev) +{ + return (I2C_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); +} + +static int nxp_ii2c_configure(const struct device *dev, + uint32_t dev_config_raw) +{ + I2C_Type *base = get_base(dev); + struct nxp_ii2c_data *data = dev->data; + const struct nxp_ii2c_config *config = dev->config; + uint32_t clock_freq; + uint32_t baudrate; + + if (!(I2C_MODE_CONTROLLER & dev_config_raw)) { + return -EINVAL; + } + + if (I2C_ADDR_10_BITS & dev_config_raw) { + return -EINVAL; + } + + switch (I2C_SPEED_GET(dev_config_raw)) { + case I2C_SPEED_STANDARD: + baudrate = KHZ(100); + break; + case I2C_SPEED_FAST: + baudrate = KHZ(400); + break; + case I2C_SPEED_FAST_PLUS: + baudrate = MHZ(1); + break; + default: + return -EINVAL; + } + + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, + &clock_freq)) { + return -EINVAL; + } + + k_sem_take(&data->lock, K_FOREVER); + I2C_MasterSetBaudRate(base, baudrate, clock_freq); + k_sem_give(&data->lock); + + return 0; +} + +#ifdef CONFIG_I2C_CALLBACK + +static void nxp_ii2c_async_done(const struct device *dev, struct nxp_ii2c_data *data, int result); +static void nxp_ii2c_async_iter(const struct device *dev); + +#endif + +static void nxp_ii2c_master_transfer_callback(I2C_Type *base, + i2c_master_handle_t *handle, + status_t status, void *userdata) +{ + + ARG_UNUSED(handle); + ARG_UNUSED(base); + + struct device *dev = userdata; + struct nxp_ii2c_data *data = dev->data; + +#ifdef CONFIG_I2C_CALLBACK + if (data->cb != NULL) { + /* Async transfer */ + if (status != kStatus_Success) { + I2C_MasterTransferAbort(base, &data->handle); + nxp_ii2c_async_done(dev, data, -EIO); + } else if (data->msg == data->num_msgs - 1) { + nxp_ii2c_async_done(dev, data, 0); + } else { + data->msg++; + nxp_ii2c_async_iter(dev); + } + return; + } +#endif /* CONFIG_I2C_CALLBACK */ + + data->callback_status = status; + + k_sem_give(&data->device_sync_sem); +} + +static uint32_t nxp_ii2c_convert_flags(int msg_flags) +{ + uint32_t flags = kI2C_TransferDefaultFlag; + + if (!(msg_flags & I2C_MSG_STOP)) { + flags |= kI2C_TransferNoStopFlag; + } + + if (msg_flags & I2C_MSG_RESTART) { + flags |= kI2C_TransferRepeatedStartFlag; + } + + return flags; +} + +static int nxp_ii2c_transfer(const struct device *dev, struct i2c_msg *msgs, + uint8_t num_msgs, uint16_t addr) +{ + I2C_Type *base = get_base(dev); + struct nxp_ii2c_data *data = dev->data; + i2c_master_transfer_t transfer; + status_t status; + int ret = 0; + + k_sem_take(&data->lock, K_FOREVER); + + /* Iterate over all the messages */ + for (int i = 0; i < num_msgs; i++) { + if (I2C_MSG_ADDR_10_BITS & msgs->flags) { + ret = -ENOTSUP; + break; + } + + /* Initialize the transfer descriptor */ + transfer.flags = nxp_ii2c_convert_flags(msgs->flags); + transfer.slaveAddress = addr; + transfer.direction = (msgs->flags & I2C_MSG_READ) + ? kI2C_Read : kI2C_Write; + transfer.subaddress = 0; + transfer.subaddressSize = 0; + transfer.data = msgs->buf; + transfer.dataSize = msgs->len; + + /* Prevent the controller to send a start condition between + * messages, except if explicitly requested. + */ + if (i != 0 && !(msgs->flags & I2C_MSG_RESTART)) { + transfer.flags |= kI2C_TransferNoStartFlag; + } + + /* Start the transfer */ + status = I2C_MasterTransferNonBlocking(base, + &data->handle, &transfer); + + /* Return an error if the transfer didn't start successfully + * e.g., if the bus was busy + */ + if (status != kStatus_Success) { + I2C_MasterTransferAbort(base, &data->handle); + ret = -EIO; + break; + } + + /* Wait for the transfer to complete */ + k_sem_take(&data->device_sync_sem, K_FOREVER); + + /* Return an error if the transfer didn't complete + * successfully. e.g., nak, timeout, lost arbitration + */ + if (data->callback_status != kStatus_Success) { + I2C_MasterTransferAbort(base, &data->handle); + ret = -EIO; + break; + } + + /* Move to the next message */ + msgs++; + } + + k_sem_give(&data->lock); + + return ret; +} + +#ifdef CONFIG_I2C_CALLBACK + +static void nxp_ii2c_async_done(const struct device *dev, struct nxp_ii2c_data *data, int result) +{ + + i2c_callback_t cb = data->cb; + void *userdata = data->userdata; + + data->msg = 0; + data->msgs = NULL; + data->num_msgs = 0; + data->cb = NULL; + data->userdata = NULL; + data->addr = 0; + + k_sem_give(&data->lock); + + /* Callback may wish to start another transfer */ + cb(dev, result, userdata); +} + +/* Start a transfer asynchronously */ +static void nxp_ii2c_async_iter(const struct device *dev) +{ + I2C_Type *base = get_base(dev); + struct nxp_ii2c_data *data = dev->data; + i2c_master_transfer_t transfer; + status_t status; + struct i2c_msg *msg = &data->msgs[data->msg]; + + if (I2C_MSG_ADDR_10_BITS & msg->flags) { + nxp_ii2c_async_done(dev, data, -ENOTSUP); + return; + } + + /* Initialize the transfer descriptor */ + transfer.flags = nxp_ii2c_convert_flags(msg->flags); + transfer.slaveAddress = data->addr; + transfer.direction = (msg->flags & I2C_MSG_READ) ? kI2C_Read : kI2C_Write; + transfer.subaddress = 0; + transfer.subaddressSize = 0; + transfer.data = msg->buf; + transfer.dataSize = msg->len; + + /* Prevent the controller to send a start condition between + * messages, except if explicitly requested. + */ + if (data->msg != 0 && !(msg->flags & I2C_MSG_RESTART)) { + transfer.flags |= kI2C_TransferNoStartFlag; + } + + /* Start the transfer */ + status = I2C_MasterTransferNonBlocking(base, &data->handle, &transfer); + + /* Return an error if the transfer didn't start successfully + * e.g., if the bus was busy + */ + if (status != kStatus_Success) { + I2C_MasterTransferAbort(base, &data->handle); + nxp_ii2c_async_done(dev, data, -EIO); + } +} + +static int nxp_ii2c_transfer_cb(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t addr, i2c_callback_t cb, void *userdata) +{ + struct nxp_ii2c_data *data = dev->data; + + int res = k_sem_take(&data->lock, K_NO_WAIT); + + if (res != 0) { + return -EWOULDBLOCK; + } + + data->msg = 0; + data->msgs = msgs; + data->num_msgs = num_msgs; + data->addr = addr; + data->cb = cb; + data->userdata = userdata; + data->addr = addr; + + nxp_ii2c_async_iter(dev); + + return 0; +} + +#endif /* CONFIG_I2C_CALLBACK */ + +static void nxp_ii2c_isr(const struct device *dev) +{ + I2C_Type *base = get_base(dev); + struct nxp_ii2c_data *data = dev->data; + + I2C_MasterTransferHandleIRQ(base, &data->handle); +} + +static int nxp_ii2c_init(const struct device *dev) +{ + I2C_Type *base; + const struct nxp_ii2c_config *config = dev->config; + struct nxp_ii2c_data *data = dev->data; + uint32_t clock_freq, bitrate_cfg; + i2c_master_config_t master_config; + int error; + + DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, + &clock_freq)) { + return -EINVAL; + } + + error = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (error) { + return error; + } + + base = get_base(dev); + + k_sem_init(&data->lock, 1, 1); + k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT); + + I2C_MasterGetDefaultConfig(&master_config); + I2C_MasterInit(base, &master_config, clock_freq); + I2C_MasterTransferCreateHandle(base, &data->handle, + nxp_ii2c_master_transfer_callback, (void *)dev); + + bitrate_cfg = i2c_map_dt_bitrate(config->bitrate); + + error = nxp_ii2c_configure(dev, I2C_MODE_CONTROLLER | bitrate_cfg); + if (error) { + return error; + } + + config->irq_config_func(dev); + + return 0; +} + +static DEVICE_API(i2c, nxp_ii2c_driver_api) = { + .configure = nxp_ii2c_configure, + .transfer = nxp_ii2c_transfer, +#ifdef CONFIG_I2C_CALLBACK + .transfer_cb = nxp_ii2c_transfer_cb, +#endif +#ifdef CONFIG_I2C_RTIO + .iodev_submit = i2c_iodev_submit_fallback, +#endif +}; + +#define I2C_DEVICE_INIT_MCUX(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static void nxp_ii2c_config_func_ ## n(const struct device *dev); \ + \ + static const struct nxp_ii2c_config nxp_ii2c_config_ ## n = { \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = \ + (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ + .irq_config_func = nxp_ii2c_config_func_ ## n, \ + .bitrate = DT_INST_PROP(n, clock_frequency), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + static struct nxp_ii2c_data nxp_ii2c_data_ ## n; \ + \ + I2C_DEVICE_DT_INST_DEFINE(n, \ + nxp_ii2c_init, NULL, \ + &nxp_ii2c_data_ ## n, \ + &nxp_ii2c_config_ ## n, POST_KERNEL, \ + CONFIG_I2C_INIT_PRIORITY, \ + &nxp_ii2c_driver_api); \ + \ + static void nxp_ii2c_config_func_ ## n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + nxp_ii2c_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + \ + irq_enable(DT_INST_IRQN(n)); \ + } + +DT_INST_FOREACH_STATUS_OKAY(I2C_DEVICE_INIT_MCUX) diff --git a/drivers/i2c/i2c_omap.c b/drivers/i2c/i2c_omap.c new file mode 100644 index 0000000000000..222232d106e57 --- /dev/null +++ b/drivers/i2c/i2c_omap.c @@ -0,0 +1,724 @@ +/* Copyright (C) 2024 BeagleBoard.org Foundation + * Copyright (C) 2024 Dhruv Menon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_omap_i2c +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_I2C_OMAP_BUS_RECOVERY +#include "i2c_bitbang.h" +#endif /* CONFIG_I2C_OMAP_BUS_RECOVERY */ + +LOG_MODULE_REGISTER(omap_i2c, CONFIG_I2C_LOG_LEVEL); + +#define I2C_OMAP_TIMEOUT 100U +/* OCP_SYSSTATUS bit definitions */ +#define SYSS_RESETDONE_MASK BIT(0) +#define RETRY -1 +#define I2C_BITRATE_FAST 400000 +#define I2C_BITRATE_STANDARD 100000 + +/* I2C Registers */ +typedef struct { + uint8_t RESERVED_0[0x10]; /**< Reserved, offset: 0x0 */ + + __IO uint32_t SYSC; /**< System Configuration, offset: 0x10 */ + uint8_t RESERVED_1[0x18]; /**< Reserved, offset: 0x14 - 0x2C */ + __IO uint32_t IRQENABLE_SET; /**< Interrupt Enable Set, offset: 0x2C */ + uint8_t RESERVED_2[0x4]; /**< Reserved, offset: 0x30 - 0x34 */ + __IO uint32_t WE; /**< Wakeup Enable, offset: 0x34 */ + uint8_t RESERVED_3[0x4C]; /**< Reserved, offset: 0x38 - 0x84 */ + __IO uint32_t IE; /**< Interrupt Enable (Legacy), offset: 0x84 */ + __IO uint32_t STAT; /**< Status, offset: 0x88 */ + uint8_t RESERVED_4[0x4]; /**< Reserved, offset: 0x8C - 0x90 */ + __IO uint32_t SYSS; /**< System Status, offset: 0x90 */ + __IO uint32_t BUF; /**< Buffer, offset: 0x94 */ + __IO uint32_t CNT; /**< Data Count, offset: 0x98 */ + __IO uint32_t DATA; /**< Data Access, offset: 0x9C */ + uint8_t RESERVED_5[0x4]; /**< Reserved, offset: 0xA0 - 0xA4 */ + __IO uint32_t CON; /**< Configuration, offset: 0xA4 */ + __IO uint32_t OA; /**< Own Address, offset: 0xA8 */ + __IO uint32_t SA; /**< Target Address, offset: 0xAC */ + __IO uint32_t PSC; /**< Clock Prescaler, offset: 0xB0 */ + __IO uint32_t SCLL; /**< SCL Low Time, offset: 0xB4 */ + __IO uint32_t SCLH; /**< SCL High Time, offset: 0xB8 */ + __IO uint32_t SYSTEST; /**< System Test, offset: 0xBC */ + __IO uint32_t BUFSTAT; /**< Buffer Status, offset: 0xC0 */ +} i2c_omap_regs_t; + +/* I2C Configuration Register (I2C_OMAP_CON) */ +#define I2C_OMAP_CON_EN BIT(15) /* I2C module enable */ +#define I2C_OMAP_CON_OPMODE_HS BIT(12) /* High Speed support */ +#define I2C_OMAP_CON_MST BIT(10) /* Controller/target mode */ +#define I2C_OMAP_CON_TRX BIT(9) /* TX/RX mode (controller only) */ +#define I2C_OMAP_CON_STP BIT(1) /* Stop condition (controller only) */ +#define I2C_OMAP_CON_STT BIT(0) /* Start condition (controller) */ + +/* I2C Buffer Configuration Register (I2C_OMAP_BUF): */ +#define I2C_OMAP_BUF_RXFIF_CLR BIT(14) /* RX FIFO Clear */ +#define I2C_OMAP_BUF_TXFIF_CLR BIT(6) /* TX FIFO Clear */ + +/* I2C Status Register (I2C_OMAP_STAT): */ +#define I2C_OMAP_STAT_XDR BIT(14) /* TX Buffer draining */ +#define I2C_OMAP_STAT_RDR BIT(13) /* RX Buffer draining */ +#define I2C_OMAP_STAT_BB BIT(12) /* Bus busy */ +#define I2C_OMAP_STAT_ROVR BIT(11) /* Receive overrun */ +#define I2C_OMAP_STAT_XUDF BIT(10) /* Transmit underflow */ +#define I2C_OMAP_STAT_AAS BIT(9) /* Address as target */ +#define I2C_OMAP_STAT_XRDY BIT(4) /* Transmit data ready */ +#define I2C_OMAP_STAT_RRDY BIT(3) /* Receive data ready */ +#define I2C_OMAP_STAT_ARDY BIT(2) /* Register access ready */ +#define I2C_OMAP_STAT_NACK BIT(1) /* No ack interrupt enable */ +#define I2C_OMAP_STAT_AL BIT(0) /* Arbitration lost */ + +/* I2C System Test Register (I2C_OMAP_SYSTEST): */ +#define I2C_OMAP_SYSTEST_ST_EN BIT(15) /* System test enable */ +#define I2C_OMAP_SYSTEST_FREE BIT(14) /* Free running mode */ +#define I2C_OMAP_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select mask */ +#define I2C_OMAP_SYSTEST_TMODE_SHIFT (12) /* Test mode select shift */ + +/* Functional mode */ +#define I2C_OMAP_SYSTEST_SCL_I_FUNC BIT(8) /* SCL line input value */ +#define I2C_OMAP_SYSTEST_SDA_I_FUNC BIT(6) /* SDA line input value */ + +/* SDA/SCL IO mode */ +#define I2C_OMAP_SYSTEST_SCL_I BIT(3) /* SCL line sense in */ +#define I2C_OMAP_SYSTEST_SCL_O BIT(2) /* SCL line drive out */ +#define I2C_OMAP_SYSTEST_SDA_I BIT(1) /* SDA line sense in */ +#define I2C_OMAP_SYSTEST_SDA_O BIT(0) /* SDA line drive out */ + +typedef void (*init_func_t)(const struct device *dev); +#define DEV_CFG(dev) ((const struct i2c_omap_cfg *)(dev)->config) +#define DEV_DATA(dev) ((struct i2c_omap_data *)(dev)->data) +#define DEV_I2C_BASE(dev) ((i2c_omap_regs_t *)DEVICE_MMIO_NAMED_GET(dev, base)) + +struct i2c_omap_cfg { + DEVICE_MMIO_NAMED_ROM(base); + uint32_t irq; + uint32_t speed; + const struct pinctrl_dev_config *pcfg; +}; + +enum i2c_omap_speed { + I2C_OMAP_SPEED_STANDARD, + I2C_OMAP_SPEED_FAST, + I2C_OMAP_SPEED_FAST_PLUS, +}; + +struct i2c_omap_speed_config { + uint32_t pscstate; + uint32_t scllstate; + uint32_t sclhstate; +}; + +struct i2c_omap_data { + DEVICE_MMIO_NAMED_RAM(base); + enum i2c_omap_speed speed; + struct i2c_omap_speed_config speed_config; + struct i2c_msg current_msg; + struct k_sem lock; + bool receiver; + bool bb_valid; +}; + +/** + * @brief Initializes the OMAP I2C driver. + * + * This function is responsible for initializing the OMAP I2C driver. + * + * @param dev Pointer to the device structure for the I2C driver instance. + */ +static void i2c_omap_init_ll(const struct device *dev) +{ + + struct i2c_omap_data *data = DEV_DATA(dev); + i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev); + + i2c_base_addr->CON = 0; + i2c_base_addr->PSC = data->speed_config.pscstate; + i2c_base_addr->SCLL = data->speed_config.scllstate; + i2c_base_addr->SCLH = data->speed_config.sclhstate; + i2c_base_addr->CON = I2C_OMAP_CON_EN; +} + +/** + * @brief Reset the OMAP I2C controller. + * + * This function resets the OMAP I2C controller specified by the device pointer. + * + * @param dev Pointer to the device structure for the I2C controller. + * @return 0 on success, negative errno code on failure. + */ +static int i2c_omap_reset(const struct device *dev) +{ + struct i2c_omap_data *data = DEV_DATA(dev); + i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev); + uint64_t timeout; + uint16_t sysc; + + sysc = i2c_base_addr->SYSC; + i2c_base_addr->CON &= ~I2C_OMAP_CON_EN; + timeout = k_uptime_get() + I2C_OMAP_TIMEOUT; + i2c_base_addr->CON = I2C_OMAP_CON_EN; + while (!(i2c_base_addr->SYSS & SYSS_RESETDONE_MASK)) { + if (k_uptime_get() > timeout) { + LOG_WRN("timeout waiting for controller reset"); + return -ETIMEDOUT; + } + k_busy_wait(100); + } + i2c_base_addr->SYSC = sysc; + data->bb_valid = 0; + return 0; +} + +/** + * @brief Set the speed of the OMAP I2C controller. + * + * This function sets the speed of the OMAP I2C controller based on the + * specified speed parameter. The speed can be set to either Fast mode or + * Standard mode. + * + * @param dev The pointer to the device structure. + * @param speed The desired speed for the I2C controller. + * + * @return 0 on success, negative error code on failure. + */ +static int i2c_omap_set_speed(const struct device *dev, uint32_t speed) +{ + struct i2c_omap_data *data = DEV_DATA(dev); + + /* If configured for High Speed */ + switch (speed) { + case I2C_BITRATE_FAST: + /* Fast mode */ + data->speed_config = (struct i2c_omap_speed_config){ + .pscstate = 9, + .scllstate = 7, + .sclhstate = 5, + }; + break; + case I2C_BITRATE_STANDARD: + /* Standard mode */ + data->speed_config = (struct i2c_omap_speed_config){ + .pscstate = 23, + .scllstate = 13, + .sclhstate = 15, + }; + break; + default: + return -ERANGE; + } + + return 0; +} + +/** + * @brief Configure the OMAP I2C controller with the specified device configuration. + * + * This function configures the OMAP I2C controller with the specified device configuration. + * + * @param dev The pointer to the device structure. + * @param dev_config The device configuration to be applied. + * + * @return 0 on success, negative error code on failure. + */ +static int i2c_omap_configure(const struct device *dev, uint32_t dev_config) +{ + uint32_t speed_cfg = I2C_BITRATE_STANDARD; + struct i2c_omap_data *data = DEV_DATA(dev); + + switch (I2C_SPEED_GET(dev_config)) { + case I2C_SPEED_STANDARD: + speed_cfg = I2C_BITRATE_STANDARD; + break; + case I2C_SPEED_FAST: + speed_cfg = I2C_BITRATE_FAST; + break; + default: + return -ENOTSUP; + } + if ((dev_config & I2C_MODE_CONTROLLER) != I2C_MODE_CONTROLLER) { + return -ENOTSUP; + } + k_sem_take(&data->lock, K_FOREVER); + i2c_omap_set_speed(dev, speed_cfg); + i2c_omap_init_ll(dev); + k_sem_give(&data->lock); + return 0; +} + +/** + * @brief Transmit or receive data over I2C bus + * + * This function transmits or receives data over the I2C bus using the OMAP I2C controller. + * + * @param dev Pointer to the I2C device structure + * @param num_bytes Number of bytes to transmit or receive + */ +static void i2c_omap_transmit_receive_data(const struct device *dev, uint8_t num_bytes) +{ + struct i2c_omap_data *data = DEV_DATA(dev); + i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev); + uint8_t *buf_ptr = data->current_msg.buf; + + while (num_bytes--) { + if (data->receiver) { + *buf_ptr++ = i2c_base_addr->DATA; + } else { + i2c_base_addr->DATA = *(buf_ptr++); + } + } +} + +/** + * @brief Resize the FIFO buffer for the OMAP I2C controller. + * + * This function resizes the FIFO buffer for the OMAP I2C controller based on the specified size. + * It clears the RX threshold and sets the new size for the receiver, or clears the TX threshold + * and sets the new size for the transmitter. + * + * @param dev Pointer to the device structure. + * @param size The new size of the FIFO buffer. + */ +static void i2c_omap_resize_fifo(const struct device *dev, uint8_t size) +{ + struct i2c_omap_data *data = DEV_DATA(dev); + i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev); + + if (data->receiver) { + i2c_base_addr->BUF &= I2C_OMAP_BUF_RXFIF_CLR; + i2c_base_addr->BUF |= ((size) << 8) | I2C_OMAP_BUF_RXFIF_CLR; + } else { + i2c_base_addr->BUF &= I2C_OMAP_BUF_TXFIF_CLR; + i2c_base_addr->BUF |= (size) | I2C_OMAP_BUF_TXFIF_CLR; + } +} + +#ifdef CONFIG_I2C_OMAP_BUS_RECOVERY +/** + * @brief Get the state of the SDA line. + * + * This function retrieves the state of the SDA (data) line for the OMAP I2C controller. + * + * @param io_context The I2C context. + * @return The state of the SDA line. + */ +static int i2c_omap_get_sda(void *io_context) +{ + const struct i2c_omap_cfg *cfg = (const struct i2c_omap_cfg *)io_context; + i2c_omap_regs_t *i2c_base_addr = (i2c_omap_regs_t *)cfg->base.addr; + + return (i2c_base_addr->SYSTEST & I2C_OMAP_SYSTEST_SDA_I_FUNC) ? 1 : 0; +} + +/** + * @brief Set the state of the SDA line. + * + * This function sets the state of the SDA (data) line for the OMAP I2C controller. + * + * @param io_context The I2C context. + * @param state The state to set (0 for low, 1 for high). + */ +static void i2c_omap_set_sda(void *io_context, int state) +{ + const struct i2c_omap_cfg *cfg = (const struct i2c_omap_cfg *)io_context; + i2c_omap_regs_t *i2c_base_addr = (i2c_omap_regs_t *)cfg->base.addr; + + if (state) { + i2c_base_addr->SYSTEST |= I2C_OMAP_SYSTEST_SDA_O; + } else { + i2c_base_addr->SYSTEST &= ~I2C_OMAP_SYSTEST_SDA_O; + } +} + +/** + * @brief Set the state of the SCL line. + * + * This function sets the state of the SCL (clock) line for the OMAP I2C controller. + * + * @param io_context The I2C context. + * @param state The state to set (0 for low, 1 for high). + */ +static void i2c_omap_set_scl(void *io_context, int state) +{ + const struct i2c_omap_cfg *cfg = (const struct i2c_omap_cfg *)io_context; + i2c_omap_regs_t *i2c_base_addr = (i2c_omap_regs_t *)cfg->base.addr; + + if (state) { + i2c_base_addr->SYSTEST |= I2C_OMAP_SYSTEST_SCL_O; + } else { + i2c_base_addr->SYSTEST &= ~I2C_OMAP_SYSTEST_SCL_O; + } +} +/** + * @brief Recovers the I2C bus using the OMAP I2C controller. + * + * This function attempts to recover the I2C bus by performing a bus recovery + * sequence using the OMAP I2C controller. It uses the provided device + * configuration and bit-banging operations to recover the bus. + * + * @param dev Pointer to the device structure. + * @return 0 on success, negative error code on failure. + */ + +static int i2c_omap_recover_bus(const struct device *dev) +{ + const struct i2c_omap_cfg *cfg = DEV_CFG(dev); + i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev); + struct i2c_omap_data *data = DEV_DATA(dev); + + struct i2c_bitbang bitbang_omap; + struct i2c_bitbang_io bitbang_omap_io = { + .get_sda = i2c_omap_get_sda, + .set_scl = i2c_omap_set_scl, + .set_sda = i2c_omap_set_sda, + }; + int error = 0; + + k_sem_take(&data->lock, K_FOREVER); + i2c_base_addr->SYSTEST |= I2C_OMAP_SYSTEST_ST_EN | (3 << I2C_OMAP_SYSTEST_TMODE_SHIFT) | + I2C_OMAP_SYSTEST_SCL_O | I2C_OMAP_SYSTEST_SDA_O; + i2c_bitbang_init(&bitbang_omap, &bitbang_omap_io, (void *)cfg); + error = i2c_bitbang_recover_bus(&bitbang_omap); + if (error != 0) { + LOG_ERR("failed to recover bus (err %d)", error); + goto restore; + } + +restore: + i2c_base_addr->SYSTEST &= ~(I2C_OMAP_SYSTEST_ST_EN | I2C_OMAP_SYSTEST_TMODE_MASK | + I2C_OMAP_SYSTEST_SCL_O | I2C_OMAP_SYSTEST_SDA_O); + i2c_omap_reset(dev); + k_sem_give(&data->lock); + return error; +} +#endif /* CONFIG_I2C_OMAP_BUS_RECOVERY */ + +/** + * @brief Wait for the bus to become free (no longer busy). + * + * This function waits for the bus to become free by continuously checking the + * status register of the OMAP I2C controller. If the bus remains busy for a + * certain timeout period, the function will return attempts to recover the bus by calling + * i2c_omap_recover_bus(). + * + * @param dev The I2C device structure. + * @return 0 if the bus becomes free, or a negative error code if the bus cannot + * be recovered. + */ +static int i2c_omap_wait_for_bb(const struct device *dev) +{ + i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev); + uint32_t timeout = k_uptime_get_32() + I2C_OMAP_TIMEOUT; + + while (i2c_base_addr->STAT & I2C_OMAP_STAT_BB) { + if (k_uptime_get_32() > timeout) { + LOG_ERR("Bus busy timeout"); +#ifdef CONFIG_I2C_OMAP_BUS_RECOVERY + return i2c_omap_recover_bus(dev); +#else + return -ETIMEDOUT; +#endif /* CONFIG_I2C_OMAP_BUS_RECOVERY */ + } + k_busy_wait(100); + } + return 0; +} + +/** + * @brief Performs data transfer for the OMAP I2C driver. + * + * This function is responsible for handling the data transfer logic for the OMAP I2C driver. + * It reads the status register and performs the necessary actions based on the status flags. + * It handles both receive and transmit logic, and also handles error conditions such as NACK, + * arbitration lost, receive overrun, and transmit underflow. + * + * @param dev Pointer to the device structure. + * + * @return Returns 0 on success, or a negative error code on failure. + */ +static int i2c_omap_transfer_message_ll(const struct device *dev) +{ + struct i2c_omap_data *data = DEV_DATA(dev); + i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev); + uint16_t stat = i2c_base_addr->STAT, result = 0; + + if (data->receiver) { + stat &= ~(I2C_OMAP_STAT_XDR | I2C_OMAP_STAT_XRDY); + } else { + stat &= ~(I2C_OMAP_STAT_RDR | I2C_OMAP_STAT_RRDY); + } + if (stat & I2C_OMAP_STAT_NACK) { + result |= I2C_OMAP_STAT_NACK; + i2c_base_addr->STAT |= I2C_OMAP_STAT_NACK; + } + if (stat & I2C_OMAP_STAT_AL) { + result |= I2C_OMAP_STAT_AL; + i2c_base_addr->STAT |= I2C_OMAP_STAT_AL; + } + if (stat & I2C_OMAP_STAT_ARDY) { + i2c_base_addr->STAT |= I2C_OMAP_STAT_ARDY; + } + if (stat & (I2C_OMAP_STAT_ARDY | I2C_OMAP_STAT_NACK | I2C_OMAP_STAT_AL)) { + + i2c_base_addr->STAT |= + (I2C_OMAP_STAT_RRDY | I2C_OMAP_STAT_RDR | I2C_OMAP_STAT_XRDY | + I2C_OMAP_STAT_XDR | I2C_OMAP_STAT_ARDY); + return result; + } + + /* Handle receive logic */ + if (stat & (I2C_OMAP_STAT_RRDY | I2C_OMAP_STAT_RDR)) { + int buffer = + (stat & I2C_OMAP_STAT_RRDY) ? i2c_base_addr->BUF : i2c_base_addr->BUFSTAT; + i2c_omap_transmit_receive_data(dev, buffer); + i2c_base_addr->STAT |= + (stat & I2C_OMAP_STAT_RRDY) ? I2C_OMAP_STAT_RRDY : I2C_OMAP_STAT_RDR; + return RETRY; + } + + /* Handle transmit logic */ + if (stat & (I2C_OMAP_STAT_XRDY | I2C_OMAP_STAT_XDR)) { + int buffer = + (stat & I2C_OMAP_STAT_XRDY) ? i2c_base_addr->BUF : i2c_base_addr->BUFSTAT; + i2c_omap_transmit_receive_data(dev, buffer); + i2c_base_addr->STAT |= + (stat & I2C_OMAP_STAT_XRDY) ? I2C_OMAP_STAT_XRDY : I2C_OMAP_STAT_XDR; + return RETRY; + } + + if (stat & I2C_OMAP_STAT_ROVR) { + i2c_base_addr->STAT |= I2C_OMAP_STAT_ROVR; + return I2C_OMAP_STAT_ROVR; + } + if (stat & I2C_OMAP_STAT_XUDF) { + i2c_base_addr->STAT |= I2C_OMAP_STAT_XUDF; + return I2C_OMAP_STAT_XUDF; + } + return RETRY; +} + +/** + * @brief Performs an I2C transfer of a single message. + * + * This function is responsible for performing an I2C transfer of a single message. + * It sets up the necessary configurations, writes the target device address, + * sets the buffer and buffer length, and handles various error conditions. + * + * @param dev The I2C device structure. + * @param msg Pointer to the I2C message structure. + * @param polling Flag indicating whether to use polling mode or not. + * @param addr The target device address. + * + * @return 0 on success, negative error code on failure. + * Possible error codes include: + * - ETIMEDOUT: Timeout occurred during the transfer. + * - EIO: I/O error due to receiver overrun or transmit underflow. + * - EAGAIN: Arbitration lost error, try again. + * - ENOMSG: Message error due to NACK. + */ +static int i2c_omap_transfer_message(const struct device *dev, struct i2c_msg *msg, bool polling, + uint16_t addr) +{ + struct i2c_omap_data *data = DEV_DATA(dev); + i2c_omap_regs_t *i2c_base_addr = DEV_I2C_BASE(dev); + unsigned long time_left = 1000; + uint16_t control_reg; + int result = 0; + /* Determine message direction (read or write) and update the receiver flag */ + data->receiver = msg->flags & I2C_MSG_READ; + /* Adjust the FIFO size according to the message length */ + i2c_omap_resize_fifo(dev, msg->len); + /* Set the target I2C address for the transfer */ + i2c_base_addr->SA = addr; + /* Store the message in the data structure */ + data->current_msg = *msg; + /* Set the message length in the I2C controller */ + i2c_base_addr->CNT = msg->len; + /* Clear FIFO buffers */ + control_reg = i2c_base_addr->BUF; + control_reg |= I2C_OMAP_BUF_RXFIF_CLR | I2C_OMAP_BUF_TXFIF_CLR; + i2c_base_addr->BUF = control_reg; + /* If we're not polling, reset the command completion semaphore */ + if (!polling) { + k_sem_reset(&data->lock); + } + /* Reset the command error status */ + /* Prepare the control register for the I2C operation */ + control_reg = I2C_OMAP_CON_EN | I2C_OMAP_CON_MST | I2C_OMAP_CON_STT; + /* Enable high-speed mode if required by the transfer speed */ + if (data->speed > I2C_BITRATE_FAST) { + control_reg |= I2C_OMAP_CON_OPMODE_HS; + } + /* Set the STOP condition if it's specified in the message flags */ + if (msg->flags & I2C_MSG_STOP) { + control_reg |= I2C_OMAP_CON_STP; + } + /* Set the transmission mode based on whether it's a read or write operation */ + if (!(msg->flags & I2C_MSG_READ)) { + control_reg |= I2C_OMAP_CON_TRX; + } + /* Start the I2C transfer by writing the control register */ + i2c_base_addr->CON = control_reg; + /* Poll for status until the transfer is complete */ + /* Call a lower-level function to continue the transfer */ + do { + result = i2c_omap_transfer_message_ll(dev); + time_left--; + } while (result == RETRY && time_left); + + /* If no errors occurred, return success */ + if (!result) { + return 0; + } + + /* Handle timeout or specific error conditions */ + if (result & (I2C_OMAP_STAT_ROVR | I2C_OMAP_STAT_XUDF)) { + i2c_omap_reset(dev); + i2c_omap_init_ll(dev); + /* Return an error code based on whether it was a timeout or buffer error */ + return -EIO; /* Receiver overrun or transmitter underflow */ + } + /* Handle arbitration loss and NACK errors */ + if (result & (I2C_OMAP_STAT_AL | -EAGAIN)) { + return -EAGAIN; + } + if (result & I2C_OMAP_STAT_NACK) { + /* Issue a STOP condition after NACK */ + i2c_base_addr->CON |= I2C_OMAP_CON_STP; + return -ENOMSG; /* Indicate a message error due to NACK */ + } + + /* Return a general I/O error if no specific error conditions matched */ + return -EIO; +} + +/** + * @brief Performs a common transfer operation for OMAP I2C devices. + * + * This function is responsible for transferring multiple I2C messages in a common way + * for OMAP I2C devices. It waits for the bus to be idle, then iterates through each + * message in the provided array and transfers them one by one using the i2c_omap_transfer_message() + * function. After all messages have been transferred, it waits for the bus to be idle again + * before returning. + * + * @param dev The pointer to the I2C device structure. + * @param msg An array of I2C messages to be transferred. + * @param num The number of messages in the array. + * @param polling Specifies whether to use polling or interrupt-based transfer. + * @param addr The I2C target address. + * @return 0 on success, or a negative error code on failure. + */ +static int i2c_omap_transfer_main(const struct device *dev, struct i2c_msg msg[], int num, + bool polling, uint16_t addr) +{ + int ret; + + ret = i2c_omap_wait_for_bb(dev); + struct i2c_omap_data *data = DEV_DATA(dev); + + k_sem_take(&data->lock, K_FOREVER); + if (ret < 0) { + return ret; + } + for (int msg_idx = 0; msg_idx < num; msg_idx++) { + ret = i2c_omap_transfer_message(dev, &msg[msg_idx], polling, addr); + if (ret < 0) { + break; + } + } + k_sem_give(&data->lock); + i2c_omap_wait_for_bb(dev); + return ret; +} + +/** + * @brief OMAP I2C transfer function using polling. + * + * This function performs the I2C transfer using the OMAP I2C controller + * in polling mode. It calls the common transfer function with the + * specified messages, number of messages, and target address. + * + * @param dev Pointer to the I2C device structure. + * @param msgs Array of I2C messages to be transferred. + * @param num_msgs Number of I2C messages in the array. + * @param addr Target address. + * @return 0 on success, negative error code on failure. + */ +static int i2c_omap_transfer_polling(const struct device *dev, struct i2c_msg msgs[], + uint8_t num_msgs, uint16_t addr) +{ + return i2c_omap_transfer_main(dev, msgs, num_msgs, true, addr); +} + +static DEVICE_API(i2c, i2c_omap_api) = { + .transfer = i2c_omap_transfer_polling, + .configure = i2c_omap_configure, +#ifdef CONFIG_I2C_OMAP_BUS_RECOVERY + .recover_bus = i2c_omap_recover_bus, +#endif /* CONFIG_I2C_OMAP_BUS_RECOVERY */ +}; + +/** + * @brief Initialize the OMAP I2C controller. + * + * This function initializes the OMAP I2C controller by setting the speed and + * performing any necessary initialization steps. + * + * @param dev Pointer to the device structure for the I2C controller. + * @return 0 if successful, negative error code otherwise. + */ +static int i2c_omap_init(const struct device *dev) +{ + struct i2c_omap_data *data = DEV_DATA(dev); + const struct i2c_omap_cfg *cfg = DEV_CFG(dev); + int ret; + + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("failed to apply pinctrl"); + return ret; + } + + k_sem_init(&data->lock, 1, 1); + /* Set the speed for I2C */ + if (i2c_omap_set_speed(dev, cfg->speed)) { + LOG_ERR("Failed to set speed"); + return -ENOTSUP; + } + i2c_omap_init_ll(dev); + return 0; +} + +#define I2C_OMAP_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + LOG_INSTANCE_REGISTER(omap_i2c, inst, CONFIG_I2C_LOG_LEVEL); \ + static const struct i2c_omap_cfg i2c_omap_cfg_##inst = { \ + DEVICE_MMIO_NAMED_ROM_INIT(base, DT_DRV_INST(inst)), \ + .irq = DT_INST_IRQN(inst), \ + .speed = DT_INST_PROP(inst, clock_frequency), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + }; \ + \ + static struct i2c_omap_data i2c_omap_data_##inst; \ + \ + I2C_DEVICE_DT_INST_DEFINE(inst, \ + i2c_omap_init, \ + NULL, \ + &i2c_omap_data_##inst, \ + &i2c_omap_cfg_##inst, \ + POST_KERNEL, \ + CONFIG_I2C_INIT_PRIORITY, \ + &i2c_omap_api); + +DT_INST_FOREACH_STATUS_OKAY(I2C_OMAP_INIT) diff --git a/drivers/i2c/i2c_rcar.c b/drivers/i2c/i2c_rcar.c index 495579bb1e431..e8b7cd8950545 100644 --- a/drivers/i2c/i2c_rcar.c +++ b/drivers/i2c/i2c_rcar.c @@ -344,7 +344,7 @@ static int i2c_rcar_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_rcar_driver_api = { +static DEVICE_API(i2c, i2c_rcar_driver_api) = { .configure = i2c_rcar_configure, .transfer = i2c_rcar_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_renesas_ra_iic.c b/drivers/i2c/i2c_renesas_ra_iic.c index 98eb46f625d59..8643b0c3d2e70 100644 --- a/drivers/i2c/i2c_renesas_ra_iic.c +++ b/drivers/i2c/i2c_renesas_ra_iic.c @@ -473,7 +473,7 @@ static void calc_iic_master_clock_setting(const struct device *dev, const uint32 clk_cfg->brl_value, clk_cfg->brh_value, clk_cfg->cks_value); } -static const struct i2c_driver_api i2c_ra_iic_driver_api = { +static DEVICE_API(i2c, i2c_ra_iic_driver_api) = { .configure = i2c_ra_iic_configure, .get_config = i2c_ra_iic_get_config, .transfer = i2c_ra_iic_transfer, diff --git a/drivers/i2c/i2c_rv32m1_lpi2c.c b/drivers/i2c/i2c_rv32m1_lpi2c.c index a7bffef4d4b4d..db378f7f104e9 100644 --- a/drivers/i2c/i2c_rv32m1_lpi2c.c +++ b/drivers/i2c/i2c_rv32m1_lpi2c.c @@ -255,7 +255,7 @@ static int rv32m1_lpi2c_init(const struct device *dev) return 0; } -static const struct i2c_driver_api rv32m1_lpi2c_driver_api = { +static DEVICE_API(i2c, rv32m1_lpi2c_driver_api) = { .configure = rv32m1_lpi2c_configure, .transfer = rv32m1_lpi2c_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_sam0.c b/drivers/i2c/i2c_sam0.c index ff0b6c67fb652..f28c65a359e79 100644 --- a/drivers/i2c/i2c_sam0.c +++ b/drivers/i2c/i2c_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Derek Hageman + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +19,8 @@ #include LOG_MODULE_REGISTER(i2c_sam0, CONFIG_I2C_LOG_LEVEL); +/* clang-format off */ + #include "i2c-priv.h" #ifndef SERCOM_I2CM_CTRLA_MODE_I2C_MASTER @@ -34,14 +37,10 @@ struct i2c_sam0_dev_config { SercomI2cm *regs; const struct pinctrl_dev_config *pcfg; uint32_t bitrate; -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; - uint16_t gclk_core_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif + uint32_t gclk_gen; + uint16_t gclk_id; void (*irq_config_func)(const struct device *dev); #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN @@ -711,20 +710,17 @@ static int i2c_sam0_initialize(const struct device *dev) SercomI2cm *i2c = cfg->regs; int retval; -#ifdef MCLK - /* Enable the GCLK */ - GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 | - GCLK_PCHCTRL_CHEN; - /* Enable SERCOM clock in MCLK */ *cfg->mclk |= cfg->mclk_mask; -#else - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - /* Enable SERCOM clock in PM */ - PM->APBCMASK.reg |= cfg->pm_apbcmask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif + /* Disable all I2C interrupts */ i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK; @@ -772,7 +768,7 @@ static int i2c_sam0_initialize(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_sam0_driver_api = { +static DEVICE_API(i2c, i2c_sam0_driver_api) = { .configure = i2c_sam0_configure, .transfer = i2c_sam0_transfer, #ifdef CONFIG_I2C_RTIO @@ -801,7 +797,7 @@ static const struct i2c_driver_api i2c_sam0_driver_api = { #if DT_INST_IRQ_HAS_IDX(0, 3) #define I2C_SAM0_IRQ_HANDLER(n) \ -static void i2c_sam0_irq_config_##n(const struct device *dev) \ +static void i2c_sam0_irq_config_##n(const struct device *dev) \ { \ SAM0_I2C_IRQ_CONNECT(n, 0); \ SAM0_I2C_IRQ_CONNECT(n, 1); \ @@ -810,21 +806,25 @@ static void i2c_sam0_irq_config_##n(const struct device *dev) \ } #else #define I2C_SAM0_IRQ_HANDLER(n) \ -static void i2c_sam0_irq_config_##n(const struct device *dev) \ +static void i2c_sam0_irq_config_##n(const struct device *dev) \ { \ SAM0_I2C_IRQ_CONNECT(n, 0); \ } #endif +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + #ifdef MCLK #define I2C_SAM0_CONFIG(n) \ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \ .regs = (SercomI2cm *)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .bitrate = DT_INST_PROP(n, clock_frequency), \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .irq_config_func = &i2c_sam0_irq_config_##n, \ I2C_SAM0_DMA_CHANNELS(n) \ } @@ -834,8 +834,10 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \ .regs = (SercomI2cm *)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .bitrate = DT_INST_PROP(n, clock_frequency), \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .irq_config_func = &i2c_sam0_irq_config_##n, \ I2C_SAM0_DMA_CHANNELS(n) \ } @@ -856,3 +858,5 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \ I2C_SAM0_IRQ_HANDLER(n) DT_INST_FOREACH_STATUS_OKAY(I2C_SAM0_DEVICE) + +/* clang-format on */ diff --git a/drivers/i2c/i2c_sam4l_twim.c b/drivers/i2c/i2c_sam4l_twim.c index 3f8551267f76a..3abd1b8c3fdf5 100644 --- a/drivers/i2c/i2c_sam4l_twim.c +++ b/drivers/i2c/i2c_sam4l_twim.c @@ -588,7 +588,7 @@ static int i2c_sam_twim_initialize(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_sam_twim_driver_api = { +static DEVICE_API(i2c, i2c_sam_twim_driver_api) = { .configure = i2c_sam_twim_configure, .transfer = i2c_sam_twim_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_sam_twi.c b/drivers/i2c/i2c_sam_twi.c index ad6a327785988..2ef99caa90781 100644 --- a/drivers/i2c/i2c_sam_twi.c +++ b/drivers/i2c/i2c_sam_twi.c @@ -350,7 +350,7 @@ static int i2c_sam_twi_initialize(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_sam_twi_driver_api = { +static DEVICE_API(i2c, i2c_sam_twi_driver_api) = { .configure = i2c_sam_twi_configure, .transfer = i2c_sam_twi_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_sam_twihs.c b/drivers/i2c/i2c_sam_twihs.c index 4b1fda4ce573c..0a5f4e0ade9da 100644 --- a/drivers/i2c/i2c_sam_twihs.c +++ b/drivers/i2c/i2c_sam_twihs.c @@ -321,7 +321,7 @@ static int i2c_sam_twihs_initialize(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_sam_twihs_driver_api = { +static DEVICE_API(i2c, i2c_sam_twihs_driver_api) = { .configure = i2c_sam_twihs_configure, .transfer = i2c_sam_twihs_transfer, }; diff --git a/drivers/i2c/i2c_sam_twihs_rtio.c b/drivers/i2c/i2c_sam_twihs_rtio.c index bbece9d50e506..0f8cf5730d098 100644 --- a/drivers/i2c/i2c_sam_twihs_rtio.c +++ b/drivers/i2c/i2c_sam_twihs_rtio.c @@ -327,7 +327,7 @@ static int i2c_sam_twihs_initialize(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_sam_twihs_driver_api = { +static DEVICE_API(i2c, i2c_sam_twihs_driver_api) = { .configure = i2c_sam_twihs_configure, .transfer = i2c_sam_twihs_transfer, .iodev_submit = i2c_sam_twihs_submit, diff --git a/drivers/i2c/i2c_sbcon.c b/drivers/i2c/i2c_sbcon.c index 0212593ed3e53..bf77fcdf352bc 100644 --- a/drivers/i2c/i2c_sbcon.c +++ b/drivers/i2c/i2c_sbcon.c @@ -113,7 +113,7 @@ static int i2c_sbcon_recover_bus(const struct device *dev) return i2c_bitbang_recover_bus(&context->bitbang); } -static const struct i2c_driver_api api = { +static DEVICE_API(i2c, api) = { .configure = i2c_sbcon_configure, .get_config = i2c_sbcon_get_config, .transfer = i2c_sbcon_transfer, diff --git a/drivers/i2c/i2c_sc18im704.c b/drivers/i2c/i2c_sc18im704.c index 64ea3482b28af..722772931ba28 100644 --- a/drivers/i2c/i2c_sc18im704.c +++ b/drivers/i2c/i2c_sc18im704.c @@ -320,7 +320,7 @@ static int i2c_sc18im_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_sc18im_driver_api = { +static DEVICE_API(i2c, i2c_sc18im_driver_api) = { .configure = i2c_sc18im_configure, .get_config = i2c_sc18im_get_config, .transfer = i2c_sc18im_transfer, diff --git a/drivers/i2c/i2c_sedi.c b/drivers/i2c/i2c_sedi.c index 00ec5e06d4a0f..79744729a0396 100644 --- a/drivers/i2c/i2c_sedi.c +++ b/drivers/i2c/i2c_sedi.c @@ -112,7 +112,7 @@ static int i2c_sedi_api_full_io(const struct device *dev, struct i2c_msg *msgs, return ret; } -static const struct i2c_driver_api i2c_sedi_apis = { +static DEVICE_API(i2c, i2c_sedi_apis) = { .configure = i2c_sedi_api_configure, .transfer = i2c_sedi_api_full_io, #ifdef CONFIG_I2C_RTIO @@ -237,8 +237,8 @@ static void i2c_sedi_isr(const struct device *dev) .cb_sedi = &i2c_sedi_callback_##n, \ .irq_config = &i2c_sedi_irq_config_##n, \ }; \ - PM_DEVICE_DT_DEFINE(DT_NODELABEL(i2c##n), i2c_sedi_pm_action); \ - I2C_DEVICE_DT_INST_DEFINE(n, i2c_sedi_init, PM_DEVICE_DT_GET(DT_NODELABEL(i2c##n)), \ + PM_DEVICE_DT_INST_DEFINE(n, i2c_sedi_pm_action); \ + I2C_DEVICE_DT_INST_DEFINE(n, i2c_sedi_init, PM_DEVICE_DT_INST_GET(n), \ &i2c_sedi_data_##n, &i2c_sedi_config_##n, PRE_KERNEL_2, \ CONFIG_I2C_INIT_PRIORITY, &i2c_sedi_apis); diff --git a/drivers/i2c/i2c_shell.c b/drivers/i2c/i2c_shell.c index 176a0d46c561d..0817f27aae501 100644 --- a/drivers/i2c/i2c_shell.c +++ b/drivers/i2c/i2c_shell.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -53,7 +54,7 @@ static int cmd_i2c_scan(const struct shell *shell_ctx, const struct device *dev; uint8_t cnt = 0, first = 0x04, last = 0x77; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(shell_ctx, "I2C: Device driver %s not found.", @@ -102,7 +103,7 @@ static int cmd_i2c_recover(const struct shell *shell_ctx, const struct device *dev; int err; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(shell_ctx, "I2C: Device driver %s not found.", argv[1]); @@ -135,7 +136,7 @@ static int i2c_write_from_buffer(const struct shell *shell_ctx, int ret; int i; - dev = device_get_binding(s_dev_name); + dev = shell_device_get_binding(s_dev_name); if (!dev) { shell_error(shell_ctx, "I2C: Device driver %s not found.", s_dev_name); @@ -198,7 +199,7 @@ static int i2c_read_to_buffer(const struct shell *shell_ctx, int dev_addr; int ret; - dev = device_get_binding(s_dev_name); + dev = shell_device_get_binding(s_dev_name); if (!dev) { shell_error(shell_ctx, "I2C: Device driver %s not found.", s_dev_name); @@ -310,7 +311,7 @@ static int cmd_i2c_speed(const struct shell *shell_ctx, size_t argc, char **argv uint32_t speed; int ret; - dev = device_get_binding(s_dev_name); + dev = shell_device_get_binding(s_dev_name); if (!dev) { shell_error(shell_ctx, "I2C: Device driver %s not found.", s_dev_name); @@ -336,9 +337,18 @@ static int cmd_i2c_speed(const struct shell *shell_ctx, size_t argc, char **argv return 0; } +static bool device_is_i2c(const struct device *dev) +{ +#ifdef CONFIG_I3C + return DEVICE_API_IS(i2c, dev) || DEVICE_API_IS(i3c, dev); +#else + return DEVICE_API_IS(i2c, dev); +#endif +} + static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_i2c); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/i2c/i2c_sifive.c b/drivers/i2c/i2c_sifive.c index 54ba5a779e462..2677e530c0961 100644 --- a/drivers/i2c/i2c_sifive.c +++ b/drivers/i2c/i2c_sifive.c @@ -316,7 +316,7 @@ static int i2c_sifive_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_sifive_api = { +static DEVICE_API(i2c, i2c_sifive_api) = { .configure = i2c_sifive_configure, .transfer = i2c_sifive_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_smartbond.c b/drivers/i2c/i2c_smartbond.c index c402251e49b0e..f7f2a5a0f1a7e 100644 --- a/drivers/i2c/i2c_smartbond.c +++ b/drivers/i2c/i2c_smartbond.c @@ -548,7 +548,7 @@ static void i2c_smartbond_isr(const struct device *dev) #define I2C_SMARTBOND_CONFIGURE(id) #endif -static const struct i2c_driver_api i2c_smartbond_driver_api = { +static DEVICE_API(i2c, i2c_smartbond_driver_api) = { .configure = i2c_smartbond_configure, .get_config = i2c_smartbond_get_config, .transfer = i2c_smartbond_transfer, diff --git a/drivers/i2c/i2c_tca954x.c b/drivers/i2c/i2c_tca954x.c index 572b8daaf62e0..ab8c3f0101341 100644 --- a/drivers/i2c/i2c_tca954x.c +++ b/drivers/i2c/i2c_tca954x.c @@ -153,7 +153,7 @@ static int tca954x_channel_init(const struct device *dev) return 0; } -static const struct i2c_driver_api tca954x_api_funcs = { +static DEVICE_API(i2c, tca954x_api_funcs) = { .configure = tca954x_configure, .transfer = tca954x_transfer, #ifdef CONFIG_I2C_RTIO diff --git a/drivers/i2c/i2c_test.c b/drivers/i2c/i2c_test.c index 89001f617827e..dfe994deae6e7 100644 --- a/drivers/i2c/i2c_test.c +++ b/drivers/i2c/i2c_test.c @@ -27,7 +27,7 @@ static int vnd_i2c_transfer(const struct device *dev, return -ENOTSUP; } -static const struct i2c_driver_api vnd_i2c_api = { +static DEVICE_API(i2c, vnd_i2c_api) = { .configure = vnd_i2c_configure, .transfer = vnd_i2c_transfer, }; diff --git a/drivers/i2c/i2c_xilinx_axi.c b/drivers/i2c/i2c_xilinx_axi.c index 715deaa6bb71d..61f9108b53607 100644 --- a/drivers/i2c/i2c_xilinx_axi.c +++ b/drivers/i2c/i2c_xilinx_axi.c @@ -620,7 +620,7 @@ static int i2c_xilinx_axi_init(const struct device *dev) return 0; } -static const struct i2c_driver_api i2c_xilinx_axi_driver_api = { +static DEVICE_API(i2c, i2c_xilinx_axi_driver_api) = { .configure = i2c_xilinx_axi_configure, .transfer = i2c_xilinx_axi_transfer, #if defined(CONFIG_I2C_TARGET) diff --git a/drivers/i2c/target/CMakeLists.txt b/drivers/i2c/target/CMakeLists.txt index d74c75140d647..7339581d5989d 100644 --- a/drivers/i2c/target/CMakeLists.txt +++ b/drivers/i2c/target/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 +# zephyr-keep-sorted-start zephyr_library_sources_ifdef(CONFIG_I2C_EEPROM_TARGET eeprom_target.c) +# zephyr-keep-sorted-stop diff --git a/drivers/i2c/target/Kconfig b/drivers/i2c/target/Kconfig index 6894d12bef449..6926fdb7c781b 100644 --- a/drivers/i2c/target/Kconfig +++ b/drivers/i2c/target/Kconfig @@ -25,6 +25,8 @@ config I2C_TARGET_BUFFER_MODE help This is an option to enable buffer mode. +# zephyr-keep-sorted-start source "drivers/i2c/target/Kconfig.eeprom" +# zephyr-keep-sorted-stop endif # I2C_TARGET diff --git a/drivers/i2s/Kconfig.mcux b/drivers/i2s/Kconfig.mcux index 4a7ef1b1eef69..7a6889db61741 100644 --- a/drivers/i2s/Kconfig.mcux +++ b/drivers/i2s/Kconfig.mcux @@ -1,6 +1,6 @@ # MCUX I2S driver configuration options -# Copyright (c) 2021, NXP +# Copyright 2021,2024 NXP # SPDX-License-Identifier: Apache-2.0 menuconfig I2S_MCUX_SAI @@ -28,4 +28,8 @@ config I2S_EDMA_BURST_SIZE help I2S EDMA burst size in bytes. +config I2S_HAS_PLL_SETTING + bool "I2S will setting pll in driver" + default y + endif # I2S_MCUX_SAI diff --git a/drivers/i2s/i2s_litex.c b/drivers/i2s/i2s_litex.c index 06bc4d5bc1d5a..4e759e6755fed 100644 --- a/drivers/i2s/i2s_litex.c +++ b/drivers/i2s/i2s_litex.c @@ -260,7 +260,7 @@ static void i2s_copy_to_fifo(uint8_t *src, size_t size, int sample_width, /* * Get data from the queue */ -static int queue_get(struct ring_buf *rb, void **mem_block, size_t *size) +static int queue_get(struct ring_buffer *rb, void **mem_block, size_t *size) { unsigned int key; @@ -282,7 +282,7 @@ static int queue_get(struct ring_buf *rb, void **mem_block, size_t *size) /* * Put data in the queue */ -static int queue_put(struct ring_buf *rb, void *mem_block, size_t size) +static int queue_put(struct ring_buffer *rb, void *mem_block, size_t size) { uint16_t head_next; unsigned int key; diff --git a/drivers/i2s/i2s_litex.h b/drivers/i2s/i2s_litex.h index c373371cf9a20..9fcae9f98c598 100644 --- a/drivers/i2s/i2s_litex.h +++ b/drivers/i2s/i2s_litex.h @@ -70,7 +70,7 @@ struct queue_item { }; /* Minimal ring buffer implementation */ -struct ring_buf { +struct ring_buffer { struct queue_item *buf; uint16_t len; uint16_t head; @@ -81,7 +81,7 @@ struct stream { int32_t state; struct k_sem sem; struct i2s_config cfg; - struct ring_buf mem_block_queue; + struct ring_buffer mem_block_queue; void *mem_block; }; diff --git a/drivers/i2s/i2s_ll_stm32.c b/drivers/i2s/i2s_ll_stm32.c index 24df83639a46d..bbf7e60de62f0 100644 --- a/drivers/i2s/i2s_ll_stm32.c +++ b/drivers/i2s/i2s_ll_stm32.c @@ -23,79 +23,49 @@ #include LOG_MODULE_REGISTER(i2s_ll_stm32); -#define MODULO_INC(val, max) { val = (++val < max) ? val : 0; } - static unsigned int div_round_closest(uint32_t dividend, uint32_t divisor) { return (dividend + (divisor / 2U)) / divisor; } -static bool queue_is_empty(struct ring_buf *rb) +static bool queue_is_empty(struct k_msgq *q) { - unsigned int key; - - key = irq_lock(); - - if (rb->tail != rb->head) { - /* Ring buffer is not empty */ - irq_unlock(key); - return false; - } - - irq_unlock(key); - - return true; + return (k_msgq_num_used_get(q) == 0) ? true : false; } /* * Get data from the queue */ -static int queue_get(struct ring_buf *rb, void **mem_block, size_t *size) +static int queue_get(struct k_msgq *q, void **mem_block, size_t *size, int32_t timeout) { - unsigned int key; + struct queue_item item; + int result = k_msgq_get(q, &item, SYS_TIMEOUT_MS(timeout)); - key = irq_lock(); - - if (queue_is_empty(rb) == true) { - irq_unlock(key); - return -ENOMEM; + if (result == 0) { + *mem_block = item.mem_block; + *size = item.size; } - - *mem_block = rb->buf[rb->tail].mem_block; - *size = rb->buf[rb->tail].size; - MODULO_INC(rb->tail, rb->len); - - irq_unlock(key); - - return 0; + return result; } /* * Put data in the queue */ -static int queue_put(struct ring_buf *rb, void *mem_block, size_t size) +static int queue_put(struct k_msgq *q, void *mem_block, size_t size, int32_t timeout) { - uint16_t head_next; - unsigned int key; + struct queue_item item = {.mem_block = mem_block, .size = size}; - key = irq_lock(); + return k_msgq_put(q, &item, SYS_TIMEOUT_MS(timeout)); +} - head_next = rb->head; - MODULO_INC(head_next, rb->len); +static void stream_queue_drop(struct stream *s) +{ + size_t size; + void *mem_block; - if (head_next == rb->tail) { - /* Ring buffer is full */ - irq_unlock(key); - return -ENOMEM; + while (queue_get(s->msgq, &mem_block, &size, 0) == 0) { + k_mem_slab_free(s->cfg.mem_slab, mem_block); } - - rb->buf[rb->head].mem_block = mem_block; - rb->buf[rb->head].size = size; - rb->head = head_next; - - irq_unlock(key); - - return 0; } static int i2s_stm32_enable_clock(const struct device *dev) @@ -224,7 +194,7 @@ static int i2s_stm32_configure(const struct device *dev, enum i2s_dir dir, } if (i2s_cfg->frame_clk_freq == 0U) { - stream->queue_drop(stream); + stream_queue_drop(stream); memset(&stream->cfg, 0, sizeof(struct i2s_config)); stream->state = I2S_STATE_NOT_READY; return 0; @@ -385,7 +355,7 @@ static int i2s_stm32_trigger(const struct device *dev, enum i2s_dir dir, } if (dir == I2S_DIR_TX) { - if ((queue_is_empty(&stream->mem_block_queue) == false) || + if ((queue_is_empty(stream->msgq) == false) || (ll_func_i2s_dma_busy(cfg->i2s))) { stream->state = I2S_STATE_STOPPING; /* @@ -412,7 +382,7 @@ static int i2s_stm32_trigger(const struct device *dev, enum i2s_dir dir, return -EIO; } stream->stream_disable(stream, dev); - stream->queue_drop(stream); + stream_queue_drop(stream); stream->state = I2S_STATE_READY; break; @@ -422,7 +392,7 @@ static int i2s_stm32_trigger(const struct device *dev, enum i2s_dir dir, return -EIO; } stream->state = I2S_STATE_READY; - stream->queue_drop(stream); + stream_queue_drop(stream); break; default: @@ -444,16 +414,8 @@ static int i2s_stm32_read(const struct device *dev, void **mem_block, return -EIO; } - if (dev_data->rx.state != I2S_STATE_ERROR) { - ret = k_sem_take(&dev_data->rx.sem, - SYS_TIMEOUT_MS(dev_data->rx.cfg.timeout)); - if (ret < 0) { - return ret; - } - } - /* Get data from the beginning of RX queue */ - ret = queue_get(&dev_data->rx.mem_block_queue, mem_block, size); + ret = queue_get(dev_data->rx.msgq, mem_block, size, dev_data->rx.cfg.timeout); if (ret < 0) { return -EIO; } @@ -465,7 +427,6 @@ static int i2s_stm32_write(const struct device *dev, void *mem_block, size_t size) { struct i2s_stm32_data *const dev_data = dev->data; - int ret; if (dev_data->tx.state != I2S_STATE_RUNNING && dev_data->tx.state != I2S_STATE_READY) { @@ -473,14 +434,8 @@ static int i2s_stm32_write(const struct device *dev, void *mem_block, return -EIO; } - ret = k_sem_take(&dev_data->tx.sem, - SYS_TIMEOUT_MS(dev_data->tx.cfg.timeout)); - if (ret < 0) { - return ret; - } - /* Add data to the end of the TX queue */ - return queue_put(&dev_data->tx.mem_block_queue, mem_block, size); + return queue_put(dev_data->tx.msgq, mem_block, size, dev_data->tx.cfg.timeout); } static DEVICE_API(i2s, i2s_stm32_driver_api) = { @@ -604,13 +559,12 @@ static void dma_rx_callback(const struct device *dma_dev, void *arg, sys_cache_data_invd_range(mblk_tmp, stream->cfg.block_size); /* All block data received */ - ret = queue_put(&stream->mem_block_queue, mblk_tmp, - stream->cfg.block_size); + ret = queue_put(stream->msgq, mblk_tmp, + stream->cfg.block_size, 0); if (ret < 0) { stream->state = I2S_STATE_ERROR; goto rx_disable; } - k_sem_give(&stream->sem); /* Stop reception if we were requested */ if (stream->state == I2S_STATE_STOPPING) { @@ -659,8 +613,8 @@ static void dma_tx_callback(const struct device *dma_dev, void *arg, * as stated in zephyr i2s specification, in case of DRAIN command * send all data in the transmit queue and stop the transmission. */ - if (queue_is_empty(&stream->mem_block_queue) == true) { - stream->queue_drop(stream); + if (queue_is_empty(stream->msgq) == true) { + stream_queue_drop(stream); stream->state = I2S_STATE_READY; goto tx_disable; } else if (stream->tx_stop_for_drain == false) { @@ -681,8 +635,8 @@ static void dma_tx_callback(const struct device *dma_dev, void *arg, } /* Prepare to send the next data block */ - ret = queue_get(&stream->mem_block_queue, &stream->mem_block, - &mem_block_size); + ret = queue_get(stream->msgq, &stream->mem_block, + &mem_block_size, 0); if (ret < 0) { if (stream->state == I2S_STATE_STOPPING) { stream->state = I2S_STATE_READY; @@ -691,7 +645,6 @@ static void dma_tx_callback(const struct device *dma_dev, void *arg, } goto tx_disable; } - k_sem_give(&stream->sem); /* Assure cache coherency before DMA read operation */ sys_cache_data_flush_range(stream->mem_block, mem_block_size); @@ -765,10 +718,6 @@ static int i2s_stm32_initialize(const struct device *dev) cfg->irq_config(dev); - k_sem_init(&dev_data->rx.sem, 0, CONFIG_I2S_STM32_RX_BLOCK_COUNT); - k_sem_init(&dev_data->tx.sem, CONFIG_I2S_STM32_TX_BLOCK_COUNT, - CONFIG_I2S_STM32_TX_BLOCK_COUNT); - for (i = 0; i < STM32_DMA_NUM_CHANNELS; i++) { active_dma_rx_channel[i] = NULL; active_dma_tx_channel[i] = NULL; @@ -847,12 +796,11 @@ static int tx_stream_start(struct stream *stream, const struct device *dev) size_t mem_block_size; int ret; - ret = queue_get(&stream->mem_block_queue, &stream->mem_block, - &mem_block_size); + ret = queue_get(stream->msgq, &stream->mem_block, + &mem_block_size, 0); if (ret < 0) { return ret; } - k_sem_give(&stream->sem); /* Assure cache coherency before DMA read operation */ sys_cache_data_flush_range(stream->mem_block, mem_block_size); @@ -948,34 +896,6 @@ static void tx_stream_disable(struct stream *stream, const struct device *dev) active_dma_tx_channel[stream->dma_channel] = NULL; } -static void rx_queue_drop(struct stream *stream) -{ - size_t size; - void *mem_block; - - while (queue_get(&stream->mem_block_queue, &mem_block, &size) == 0) { - k_mem_slab_free(stream->cfg.mem_slab, mem_block); - } - - k_sem_reset(&stream->sem); -} - -static void tx_queue_drop(struct stream *stream) -{ - size_t size; - void *mem_block; - unsigned int n = 0U; - - while (queue_get(&stream->mem_block_queue, &mem_block, &size) == 0) { - k_mem_slab_free(stream->cfg.mem_slab, mem_block); - n++; - } - - for (; n > 0; n--) { - k_sem_give(&stream->sem); - } -} - static const struct device *get_dev_from_rx_dma_channel(uint32_t dma_channel) { return active_dma_rx_channel[dma_channel]; @@ -1011,9 +931,7 @@ static const struct device *get_dev_from_tx_dma_channel(uint32_t dma_channel) STM32_DMA_FEATURES(index, dir)), \ .stream_start = dir##_stream_start, \ .stream_disable = dir##_stream_disable, \ - .queue_drop = dir##_queue_drop, \ - .mem_block_queue.buf = dir##_##index##_ring_buf, \ - .mem_block_queue.len = ARRAY_SIZE(dir##_##index##_ring_buf) \ + .msgq = &dir##_##index##_queue, \ } #define I2S_STM32_INIT(index) \ @@ -1034,8 +952,8 @@ static const struct i2s_stm32_cfg i2s_stm32_config_##index = { \ .master_clk_sel = DT_INST_PROP(index, mck_enabled) \ }; \ \ -struct queue_item rx_##index##_ring_buf[CONFIG_I2S_STM32_RX_BLOCK_COUNT + 1];\ -struct queue_item tx_##index##_ring_buf[CONFIG_I2S_STM32_TX_BLOCK_COUNT + 1];\ +K_MSGQ_DEFINE(rx_##index##_queue, sizeof(struct queue_item), CONFIG_I2S_STM32_RX_BLOCK_COUNT, 4);\ +K_MSGQ_DEFINE(tx_##index##_queue, sizeof(struct queue_item), CONFIG_I2S_STM32_TX_BLOCK_COUNT, 4);\ \ static struct i2s_stm32_data i2s_stm32_data_##index = { \ UTIL_AND(DT_INST_DMAS_HAS_NAME(index, rx), \ diff --git a/drivers/i2s/i2s_ll_stm32.h b/drivers/i2s/i2s_ll_stm32.h index 1f9d0eb0113dc..439fefafaf928 100644 --- a/drivers/i2s/i2s_ll_stm32.h +++ b/drivers/i2s/i2s_ll_stm32.h @@ -12,14 +12,6 @@ struct queue_item { size_t size; }; -/* Minimal ring buffer implementation */ -struct ring_buf { - struct queue_item *buf; - uint16_t len; - uint16_t head; - uint16_t tail; -}; - /* Device constant configuration parameters */ struct i2s_stm32_cfg { SPI_TypeDef *i2s; @@ -32,7 +24,7 @@ struct i2s_stm32_cfg { struct stream { int32_t state; - struct k_sem sem; + struct k_msgq *msgq; const struct device *dev_dma; uint32_t dma_channel; @@ -44,13 +36,11 @@ struct stream { bool tx_stop_for_drain; struct i2s_config cfg; - struct ring_buf mem_block_queue; void *mem_block; bool last_block; bool master; int (*stream_start)(struct stream *, const struct device *dev); void (*stream_disable)(struct stream *, const struct device *dev); - void (*queue_drop)(struct stream *); }; /* Device run time data */ diff --git a/drivers/i2s/i2s_mcux_sai.c b/drivers/i2s/i2s_mcux_sai.c index 3e7de1b0f11a5..a6982a055cac4 100644 --- a/drivers/i2s/i2s_mcux_sai.c +++ b/drivers/i2s/i2s_mcux_sai.c @@ -9,6 +9,8 @@ * @brief I2S bus (SAI) driver for NXP i.MX RT series. */ +#define DT_DRV_COMPAT nxp_mcux_i2s + #include #include #include @@ -21,26 +23,30 @@ #include #include #include +#include #include -#include "i2s_mcux_sai.h" +#include +#include -#define LOG_DOMAIN dev_i2s_mcux -#define LOG_LEVEL CONFIG_I2S_LOG_LEVEL #include -#include +LOG_MODULE_REGISTER(dev_i2s_mcux, CONFIG_I2S_LOG_LEVEL); -LOG_MODULE_REGISTER(LOG_DOMAIN); - -#define DT_DRV_COMPAT nxp_mcux_i2s #define NUM_DMA_BLOCKS_RX_PREP 3 -#define MAX_TX_DMA_BLOCKS CONFIG_DMA_TCD_QUEUE_SIZE -#if (NUM_DMA_BLOCKS_RX_PREP >= CONFIG_DMA_TCD_QUEUE_SIZE) -#error NUM_DMA_BLOCKS_RX_PREP must be < CONFIG_DMA_TCD_QUEUE_SIZE -#endif -#if defined(CONFIG_DMA_MCUX_EDMA) && (NUM_DMA_BLOCKS_RX_PREP < 3) -#error eDMA avoids TCD coherency issue if NUM_DMA_BLOCKS_RX_PREP >= 3 -#endif +#if defined(CONFIG_DMA_MCUX_EDMA) +BUILD_ASSERT(NUM_DMA_BLOCKS_RX_PREP >= 3, + "eDMA avoids TCD coherency issue if NUM_DMA_BLOCKS_RX_PREP >= 3"); +#endif /* CONFIG_DMA_MCUX_EDMA */ + +#define MAX_TX_DMA_BLOCKS CONFIG_DMA_TCD_QUEUE_SIZE +BUILD_ASSERT(MAX_TX_DMA_BLOCKS > NUM_DMA_BLOCKS_RX_PREP, + "NUM_DMA_BLOCKS_RX_PREP must be < CONFIG_DMA_TCD_QUEUE_SIZE"); + +#define SAI_WORD_SIZE_BITS_MIN 8 +#define SAI_WORD_SIZE_BITS_MAX 32 + +#define SAI_WORD_PER_FRAME_MIN 0 +#define SAI_WORD_PER_FRAME_MAX 32 /* * SAI driver uses source_gather_en/dest_scatter_en feature of DMA, and relies @@ -65,7 +71,7 @@ LOG_MODULE_REGISTER(LOG_DOMAIN); * (may optionally block) from out_queue and presented to application. */ struct stream { - int32_t state; + enum i2s_state state; uint32_t dma_channel; uint32_t start_channel; void (*irq_call_back)(void); @@ -88,6 +94,7 @@ struct i2s_mcux_config { uint32_t pll_pd; uint32_t pll_num; uint32_t pll_den; + uint32_t mclk_control_base; uint32_t mclk_pin_mask; uint32_t mclk_pin_offset; uint32_t tx_channel; @@ -95,8 +102,8 @@ struct i2s_mcux_config { const struct device *ccm_dev; const struct pinctrl_dev_config *pinctrl; void (*irq_connect)(const struct device *dev); - bool rx_sync_mode; - bool tx_sync_mode; + sai_sync_mode_t rx_sync_mode; + sai_sync_mode_t tx_sync_mode; }; /* Device run time data */ @@ -110,12 +117,8 @@ struct i2s_dev_data { void *rx_out_msgs[CONFIG_I2S_RX_BLOCK_COUNT]; }; -static void i2s_dma_tx_callback(const struct device *, void *, uint32_t, int); -static void i2s_tx_stream_disable(const struct device *, bool drop); -static void i2s_rx_stream_disable(const struct device *, bool in_drop, bool out_drop); - -static inline void i2s_purge_stream_buffers(struct stream *strm, struct k_mem_slab *mem_slab, - bool in_drop, bool out_drop) +static void i2s_purge_stream_buffers(struct stream *strm, struct k_mem_slab *mem_slab, bool in_drop, + bool out_drop) { void *buffer; @@ -164,9 +167,7 @@ static void i2s_tx_stream_disable(const struct device *dev, bool drop) } /* purge buffers queued in the stream */ - if (drop) { - i2s_purge_stream_buffers(strm, dev_data->tx.cfg.mem_slab, true, true); - } + i2s_purge_stream_buffers(strm, dev_data->tx.cfg.mem_slab, drop, drop); } static void i2s_rx_stream_disable(const struct device *dev, bool in_drop, bool out_drop) @@ -197,9 +198,7 @@ static void i2s_rx_stream_disable(const struct device *dev, bool in_drop, bool o dev_cfg->base->RCSR &= ~I2S_RCSR_SR_MASK; /* purge buffers queued in the stream */ - if (in_drop || out_drop) { - i2s_purge_stream_buffers(strm, dev_data->rx.cfg.mem_slab, in_drop, out_drop); - } + i2s_purge_stream_buffers(strm, dev_data->rx.cfg.mem_slab, in_drop, out_drop); } static int i2s_tx_reload_multiple_dma_blocks(const struct device *dev, uint8_t *blocks_queued) @@ -256,9 +255,9 @@ static void i2s_dma_tx_callback(const struct device *dma_dev, void *arg, uint32_ const struct device *dev = (struct device *)arg; struct i2s_dev_data *dev_data = dev->data; struct stream *strm = &dev_data->tx; + uint8_t blocks_queued; void *buffer = NULL; int ret; - uint8_t blocks_queued; LOG_DBG("tx cb"); @@ -290,35 +289,42 @@ static void i2s_dma_tx_callback(const struct device *dma_dev, void *arg, uint32_ goto disabled_exit_no_drop; } - switch (strm->state) { - case I2S_STATE_RUNNING: - case I2S_STATE_STOPPING: - ret = i2s_tx_reload_multiple_dma_blocks(dev, &blocks_queued); + if (strm->state != I2S_STATE_RUNNING && strm->state != I2S_STATE_STOPPING) { + goto disabled_exit_drop; + } - if (ret) { - strm->state = I2S_STATE_ERROR; - goto disabled_exit_no_drop; - } + ret = i2s_tx_reload_multiple_dma_blocks(dev, &blocks_queued); + if (ret) { + strm->state = I2S_STATE_ERROR; + goto disabled_exit_no_drop; + } - if (blocks_queued || (strm->free_tx_dma_blocks < MAX_TX_DMA_BLOCKS)) { - goto enabled_exit; - } else { - /* all DMA blocks are free but no blocks were queued */ - if (strm->state == I2S_STATE_STOPPING) { - /* TX queue has drained */ - strm->state = I2S_STATE_READY; - LOG_DBG("TX stream has stopped"); - } else { - strm->state = I2S_STATE_ERROR; - LOG_ERR("TX Failed to reload DMA"); - } - goto disabled_exit_no_drop; - } + if (blocks_queued || (strm->free_tx_dma_blocks < MAX_TX_DMA_BLOCKS)) { + goto enabled_exit; + } - case I2S_STATE_ERROR: - default: - goto disabled_exit_drop; + /* all DMA blocks are free but no blocks were queued */ + if (strm->state == I2S_STATE_STOPPING) { + /* TX queue has drained */ + strm->state = I2S_STATE_READY; + LOG_DBG("TX stream has stopped"); + goto disabled_exit_no_drop; + } + + LOG_WRN("TX input queue empty!"); + if (strm->free_tx_dma_blocks >= MAX_TX_DMA_BLOCKS) { + /* In running state, no TX blocks for transferring, so stop + * TX (This will disable bit clock to avoid dummy bits + * received in RX side. + */ + const struct i2s_mcux_config *dev_cfg = dev->config; + I2S_Type *base = (I2S_Type *)dev_cfg->base; + + SAI_TxEnable(base, false); + LOG_WRN("TX is paused."); } + goto enabled_exit; + disabled_exit_no_drop: i2s_tx_stream_disable(dev, false); @@ -345,73 +351,76 @@ static void i2s_dma_rx_callback(const struct device *dma_dev, void *arg, uint32_ LOG_DBG("RX cb"); - switch (strm->state) { - case I2S_STATE_STOPPING: - case I2S_STATE_RUNNING: - /* retrieve buffer from input queue */ - ret = k_msgq_get(&strm->in_queue, &buffer, K_NO_WAIT); - __ASSERT_NO_MSG(ret == 0); - - /* put buffer to output queue */ - ret = k_msgq_put(&strm->out_queue, &buffer, K_NO_WAIT); - if (ret != 0) { - LOG_ERR("buffer %p -> out_queue %p err %d", buffer, &strm->out_queue, ret); - i2s_rx_stream_disable(dev, false, false); - strm->state = I2S_STATE_ERROR; - return; - } - if (strm->state == I2S_STATE_RUNNING) { - /* allocate new buffer for next audio frame */ - ret = k_mem_slab_alloc(strm->cfg.mem_slab, &buffer, K_NO_WAIT); - if (ret != 0) { - LOG_ERR("buffer alloc from slab %p err %d", strm->cfg.mem_slab, - ret); - i2s_rx_stream_disable(dev, false, false); - strm->state = I2S_STATE_ERROR; - } else { - uint32_t data_path = strm->start_channel; - - ret = dma_reload(dev_data->dev_dma, strm->dma_channel, - (uint32_t)&base->RDR[data_path], (uint32_t)buffer, - strm->cfg.block_size); - if (ret != 0) { - LOG_ERR("dma_reload() failed with error 0x%x", ret); - i2s_rx_stream_disable(dev, false, false); - strm->state = I2S_STATE_ERROR; - return; - } - - /* put buffer in input queue */ - ret = k_msgq_put(&strm->in_queue, &buffer, K_NO_WAIT); - if (ret != 0) { - LOG_ERR("%p -> in_queue %p err %d", buffer, &strm->in_queue, - ret); - } - - } - } else { - i2s_rx_stream_disable(dev, true, false); - /* Received a STOP/DRAIN trigger */ - strm->state = I2S_STATE_READY; - } - break; - case I2S_STATE_ERROR: + if (strm->state == I2S_STATE_ERROR) { i2s_rx_stream_disable(dev, true, true); - break; } + + if (strm->state != I2S_STATE_STOPPING && strm->state != I2S_STATE_RUNNING) { + return; + } + + /* retrieve buffer from input queue */ + ret = k_msgq_get(&strm->in_queue, &buffer, K_NO_WAIT); + __ASSERT_NO_MSG(ret == 0); + + /* put buffer to output queue */ + ret = k_msgq_put(&strm->out_queue, &buffer, K_NO_WAIT); + if (ret != 0) { + LOG_ERR("buffer %p -> out_queue %p err %d", buffer, &strm->out_queue, ret); + goto error; + } + + if (strm->state == I2S_STATE_STOPPING) { + i2s_rx_stream_disable(dev, true, false); + /* Received a STOP/DRAIN trigger */ + strm->state = I2S_STATE_READY; + return; + } + + /* Now the only possible case is the running state */ + + /* allocate new buffer for next audio frame */ + ret = k_mem_slab_alloc(strm->cfg.mem_slab, &buffer, K_NO_WAIT); + if (ret != 0) { + LOG_ERR("buffer alloc from slab %p err %d", strm->cfg.mem_slab, ret); + goto error; + } + + uint32_t data_path = strm->start_channel; + + ret = dma_reload(dev_data->dev_dma, strm->dma_channel, + (uint32_t)&base->RDR[data_path], (uint32_t)buffer, + strm->cfg.block_size); + if (ret != 0) { + LOG_ERR("dma_reload() failed with error 0x%x", ret); + goto error; + } + + /* put buffer in input queue */ + ret = k_msgq_put(&strm->in_queue, &buffer, K_NO_WAIT); + if (ret != 0) { + LOG_ERR("%p -> in_queue %p err %d", buffer, &strm->in_queue, ret); + } + + return; + +error: + i2s_rx_stream_disable(dev, false, false); + strm->state = I2S_STATE_ERROR; } static void enable_mclk_direction(const struct device *dev, bool dir) { const struct i2s_mcux_config *dev_cfg = dev->config; + uint32_t control_base = dev_cfg->mclk_control_base; uint32_t offset = dev_cfg->mclk_pin_offset; uint32_t mask = dev_cfg->mclk_pin_mask; - uint32_t *gpr = (uint32_t *)(DT_REG_ADDR(DT_NODELABEL(iomuxcgpr)) + offset); + uint32_t *base = (uint32_t *)(control_base + offset); if (dir) { - *gpr |= mask; + *base |= mask; } else { - *gpr &= ~mask; + *base &= ~mask; } } @@ -438,63 +447,42 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, const struct i2s_mcux_config *dev_cfg = dev->config; I2S_Type *base = (I2S_Type *)dev_cfg->base; struct i2s_dev_data *dev_data = dev->data; + enum i2s_state *tx_state = &(dev_data->tx.state); + enum i2s_state *rx_state = &(dev_data->rx.state); + uint8_t word_size_bits = i2s_cfg->word_size; + uint8_t word_size_bytes = word_size_bits / 8; + uint8_t num_words = i2s_cfg->channels; sai_transceiver_t config; + int ret = -EINVAL; uint32_t mclk; - /*num_words is frame size*/ - uint8_t num_words = i2s_cfg->channels; - uint8_t word_size_bits = i2s_cfg->word_size; if ((dev_data->tx.state != I2S_STATE_NOT_READY) && (dev_data->tx.state != I2S_STATE_READY) && (dev_data->rx.state != I2S_STATE_NOT_READY) && (dev_data->rx.state != I2S_STATE_READY)) { LOG_ERR("invalid state tx(%u) rx(%u)", dev_data->tx.state, dev_data->rx.state); - if (dir == I2S_DIR_TX) { - dev_data->tx.state = I2S_STATE_NOT_READY; - } else { - dev_data->rx.state = I2S_STATE_NOT_READY; - } - return -EINVAL; + goto invalid_config; } if (i2s_cfg->frame_clk_freq == 0U) { LOG_ERR("Invalid frame_clk_freq %u", i2s_cfg->frame_clk_freq); - if (dir == I2S_DIR_TX) { - dev_data->tx.state = I2S_STATE_NOT_READY; - } else { - dev_data->rx.state = I2S_STATE_NOT_READY; - } - return 0; + goto invalid_config; } if (word_size_bits < SAI_WORD_SIZE_BITS_MIN || word_size_bits > SAI_WORD_SIZE_BITS_MAX) { LOG_ERR("Unsupported I2S word size %u", word_size_bits); - if (dir == I2S_DIR_TX) { - dev_data->tx.state = I2S_STATE_NOT_READY; - } else { - dev_data->rx.state = I2S_STATE_NOT_READY; - } - return -EINVAL; + goto invalid_config; } if (num_words < SAI_WORD_PER_FRAME_MIN || num_words > SAI_WORD_PER_FRAME_MAX) { LOG_ERR("Unsupported words length %u", num_words); - if (dir == I2S_DIR_TX) { - dev_data->tx.state = I2S_STATE_NOT_READY; - } else { - dev_data->rx.state = I2S_STATE_NOT_READY; - } - return -EINVAL; + goto invalid_config; } if ((i2s_cfg->options & I2S_OPT_PINGPONG) == I2S_OPT_PINGPONG) { LOG_ERR("Ping-pong mode not supported"); - if (dir == I2S_DIR_TX) { - dev_data->tx.state = I2S_STATE_NOT_READY; - } else { - dev_data->rx.state = I2S_STATE_NOT_READY; - } - return -ENOTSUP; + ret = -ENOTSUP; + goto invalid_config; } memset(&config, 0, sizeof(config)); @@ -552,43 +540,28 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, break; default: LOG_ERR("Unsupported I2S data format"); - if (dir == I2S_DIR_TX) { - dev_data->tx.state = I2S_STATE_NOT_READY; - } else { - dev_data->rx.state = I2S_STATE_NOT_READY; - } - return -EINVAL; + ret = -EINVAL; + goto invalid_config; } /* sync mode configurations */ if (dir == I2S_DIR_TX) { - /* TX */ - if (dev_cfg->tx_sync_mode) { - config.syncMode = kSAI_ModeSync; - } else { - config.syncMode = kSAI_ModeAsync; - } - } else { - /* RX */ - if (dev_cfg->rx_sync_mode) { - config.syncMode = kSAI_ModeSync; - } else { - config.syncMode = kSAI_ModeAsync; - } + config.syncMode = dev_cfg->tx_sync_mode; + } else if (dir == I2S_DIR_RX) { + config.syncMode = dev_cfg->rx_sync_mode; } - if (i2s_cfg->options & I2S_OPT_FRAME_CLK_SLAVE) { - if (i2s_cfg->options & I2S_OPT_BIT_CLK_SLAVE) { - config.masterSlave = kSAI_Slave; - } else { - config.masterSlave = kSAI_Bclk_Master_FrameSync_Slave; - } + bool frame_clk_slave = i2s_cfg->options & I2S_OPT_FRAME_CLK_SLAVE; + bool bit_clk_slave = i2s_cfg->options & I2S_OPT_BIT_CLK_SLAVE; + + if (frame_clk_slave && bit_clk_slave) { + config.masterSlave = kSAI_Slave; + } else if (frame_clk_slave && !bit_clk_slave) { + config.masterSlave = kSAI_Bclk_Master_FrameSync_Slave; + } else if (!frame_clk_slave && bit_clk_slave) { + config.masterSlave = kSAI_Bclk_Slave_FrameSync_Master; } else { - if (i2s_cfg->options & I2S_OPT_BIT_CLK_SLAVE) { - config.masterSlave = kSAI_Bclk_Slave_FrameSync_Master; - } else { - config.masterSlave = kSAI_Master; - } + config.masterSlave = kSAI_Master; } /* clock signal polarity */ @@ -604,7 +577,6 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, ? kSAI_SampleOnRisingEdge : kSAI_SampleOnFallingEdge; break; - case I2S_FMT_CLK_IF_NB: /* Swap frame sync polarity */ config.frameSync.frameSyncPolarity = @@ -612,7 +584,6 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, ? kSAI_PolarityActiveLow : kSAI_PolarityActiveHigh; break; - case I2S_FMT_CLK_IF_IB: /* Swap frame sync and bclk polarity */ config.frameSync.frameSyncPolarity = @@ -638,6 +609,7 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, LOG_DBG("tx slab block_size = %d", (uint32_t)i2s_cfg->mem_slab->info.block_size); LOG_DBG("tx slab buffer = 0x%x", (uint32_t)i2s_cfg->mem_slab->buffer); + config.fifo.fifoWatermark = (uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) - 1; /* set bit clock divider */ SAI_TxSetConfig(base, &config); dev_data->tx.start_channel = config.startChannel; @@ -647,10 +619,10 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, i2s_cfg->channels); LOG_DBG("tx start_channel = %d", dev_data->tx.start_channel); /*set up dma settings*/ - dev_data->tx.dma_cfg.source_data_size = word_size_bits / 8; - dev_data->tx.dma_cfg.dest_data_size = word_size_bits / 8; - dev_data->tx.dma_cfg.source_burst_length = i2s_cfg->word_size / 8; - dev_data->tx.dma_cfg.dest_burst_length = i2s_cfg->word_size / 8; + dev_data->tx.dma_cfg.source_data_size = word_size_bytes; + dev_data->tx.dma_cfg.dest_data_size = word_size_bytes; + dev_data->tx.dma_cfg.source_burst_length = word_size_bytes; + dev_data->tx.dma_cfg.dest_burst_length = word_size_bytes; dev_data->tx.dma_cfg.user_data = (void *)dev; dev_data->tx.state = I2S_STATE_READY; } else { @@ -670,15 +642,23 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir, i2s_cfg->channels); LOG_DBG("rx start_channel = %d", dev_data->rx.start_channel); /*set up dma settings*/ - dev_data->rx.dma_cfg.source_data_size = word_size_bits / 8; - dev_data->rx.dma_cfg.dest_data_size = word_size_bits / 8; - dev_data->rx.dma_cfg.source_burst_length = i2s_cfg->word_size / 8; - dev_data->rx.dma_cfg.dest_burst_length = i2s_cfg->word_size / 8; + dev_data->rx.dma_cfg.source_data_size = word_size_bytes; + dev_data->rx.dma_cfg.dest_data_size = word_size_bytes; + dev_data->rx.dma_cfg.source_burst_length = word_size_bytes; + dev_data->rx.dma_cfg.dest_burst_length = word_size_bytes; dev_data->rx.dma_cfg.user_data = (void *)dev; dev_data->rx.state = I2S_STATE_READY; } return 0; + +invalid_config: + if (dir == I2S_DIR_TX) { + *tx_state = I2S_STATE_NOT_READY; + } else if (dir == I2S_DIR_RX) { + *rx_state = I2S_STATE_NOT_READY; + } + return ret; } const struct i2s_config *i2s_mcux_config_get(const struct device *dev, enum i2s_dir dir) @@ -1009,6 +989,23 @@ static int i2s_mcux_write(const struct device *dev, void *mem_block, size_t size return ret; } + if (strm->state == I2S_STATE_RUNNING && strm->free_tx_dma_blocks >= MAX_TX_DMA_BLOCKS) { + uint8_t blocks_queued = 0; + const struct i2s_mcux_config *dev_cfg = dev->config; + I2S_Type *base = (I2S_Type *)dev_cfg->base; + /* As DMA has been stopped because reloading failure in TX callback, + * here is a good place to reload it and resume TX. + */ + ret = i2s_tx_reload_multiple_dma_blocks(dev, &blocks_queued); + if (ret == 0 && blocks_queued > 0) { + SAI_TxEnable(base, true); + LOG_WRN("TX is resumed"); + } else { + LOG_ERR("TX block reload err, TX is not resumed"); + return ret; + } + } + return ret; } @@ -1064,6 +1061,7 @@ static void i2s_mcux_isr(void *arg) static void audio_clock_settings(const struct device *dev) { +#ifdef CONFIG_I2S_HAS_PLL_SETTING clock_audio_pll_config_t audioPllConfig; const struct i2s_mcux_config *dev_cfg = dev->config; uint32_t clock_name = (uint32_t)dev_cfg->clk_sub_sys; @@ -1089,6 +1087,7 @@ static void audio_clock_settings(const struct device *dev) #endif /* CONFIG_SOC_SERIES */ CLOCK_InitAudioPll(&audioPllConfig); +#endif } static int i2s_mcux_initialize(const struct device *dev) @@ -1147,7 +1146,8 @@ static int i2s_mcux_initialize(const struct device *dev) /* master clock configurations */ #if (defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)) || \ (defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) -#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) +#if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \ + (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV))) mclkConfig.mclkHz = mclk; mclkConfig.mclkSourceClkHz = mclk; #endif @@ -1174,23 +1174,26 @@ static DEVICE_API(i2s, i2s_mcux_driver_api) = { \ static const struct i2s_mcux_config i2s_##i2s_id##_config = { \ .base = (I2S_Type *)DT_INST_REG_ADDR(i2s_id), \ - .clk_src = DT_INST_PROP(i2s_id, clock_mux), \ - .clk_pre_div = DT_INST_PROP(i2s_id, pre_div), \ - .clk_src_div = DT_INST_PROP(i2s_id, podf), \ - .pll_src = DT_PHA_BY_NAME(DT_DRV_INST(i2s_id), pll_clocks, src, value), \ - .pll_lp = DT_PHA_BY_NAME(DT_DRV_INST(i2s_id), pll_clocks, lp, value), \ - .pll_pd = DT_PHA_BY_NAME(DT_DRV_INST(i2s_id), pll_clocks, pd, value), \ - .pll_num = DT_PHA_BY_NAME(DT_DRV_INST(i2s_id), pll_clocks, num, value), \ - .pll_den = DT_PHA_BY_NAME(DT_DRV_INST(i2s_id), pll_clocks, den, value), \ - .mclk_pin_mask = DT_PHA_BY_IDX(DT_DRV_INST(i2s_id), pinmuxes, 0, function), \ - .mclk_pin_offset = DT_PHA_BY_IDX(DT_DRV_INST(i2s_id), pinmuxes, 0, pin), \ + .clk_src = DT_INST_PROP_OR(i2s_id, clock_mux, 0), \ + .clk_pre_div = DT_INST_PROP_OR(i2s_id, pre_div, 0), \ + .clk_src_div = DT_INST_PROP_OR(i2s_id, podf, 0), \ + .pll_src = DT_PHA_BY_NAME_OR(DT_DRV_INST(i2s_id), pll_clocks, src, value, 0), \ + .pll_lp = DT_PHA_BY_NAME_OR(DT_DRV_INST(i2s_id), pll_clocks, lp, value, 0), \ + .pll_pd = DT_PHA_BY_NAME_OR(DT_DRV_INST(i2s_id), pll_clocks, pd, value, 0), \ + .pll_num = DT_PHA_BY_NAME_OR(DT_DRV_INST(i2s_id), pll_clocks, num, value, 0), \ + .pll_den = DT_PHA_BY_NAME_OR(DT_DRV_INST(i2s_id), pll_clocks, den, value, 0), \ + .mclk_control_base = DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(i2s_id), pinmuxes)), \ + .mclk_pin_mask = DT_PHA_BY_IDX(DT_DRV_INST(i2s_id), pinmuxes, 0, mask), \ + .mclk_pin_offset = DT_PHA_BY_IDX(DT_DRV_INST(i2s_id), pinmuxes, 0, offset), \ .clk_sub_sys = \ (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(i2s_id, 0, name), \ .ccm_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(i2s_id)), \ .irq_connect = i2s_irq_connect_##i2s_id, \ .pinctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(i2s_id), \ - .tx_sync_mode = DT_INST_PROP(i2s_id, nxp_tx_sync_mode), \ - .rx_sync_mode = DT_INST_PROP(i2s_id, nxp_rx_sync_mode), \ + .tx_sync_mode = \ + DT_INST_PROP(i2s_id, nxp_tx_sync_mode) ? kSAI_ModeSync : kSAI_ModeAsync, \ + .rx_sync_mode = \ + DT_INST_PROP(i2s_id, nxp_rx_sync_mode) ? kSAI_ModeSync : kSAI_ModeAsync, \ .tx_channel = DT_INST_PROP(i2s_id, nxp_tx_channel), \ }; \ \ diff --git a/drivers/i2s/i2s_mcux_sai.h b/drivers/i2s/i2s_mcux_sai.h deleted file mode 100644 index 3599320d113a7..0000000000000 --- a/drivers/i2s/i2s_mcux_sai.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#ifndef ZEPHYR_DRIVERS_I2S_MCUX_H_ -#define ZEPHYR_DRIVERS_I2S_MCUX_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#define SAI_WORD_SIZE_BITS_MIN 8 -#define SAI_WORD_SIZE_BITS_MAX 32 - -#define SAI_WORD_PER_FRAME_MIN 0 -#define SAI_WORD_PER_FRAME_MAX 32 - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_DRIVERS_I2S_MCUX_H_ */ diff --git a/drivers/i2s/i2s_sam_ssc.c b/drivers/i2s/i2s_sam_ssc.c index f96bb34d6d421..cabf8ec64c1da 100644 --- a/drivers/i2s/i2s_sam_ssc.c +++ b/drivers/i2s/i2s_sam_ssc.c @@ -58,7 +58,7 @@ struct queue_item { }; /* Minimal ring buffer implementation */ -struct ring_buf { +struct ring_buffer { struct queue_item *buf; uint16_t len; uint16_t head; @@ -83,7 +83,7 @@ struct stream { uint8_t word_size_bytes; bool last_block; struct i2s_config cfg; - struct ring_buf mem_block_queue; + struct ring_buffer mem_block_queue; void *mem_block; int (*stream_start)(struct stream *, Ssc *const, const struct device *); @@ -113,7 +113,7 @@ static void tx_stream_disable(struct stream *, Ssc *const, /* * Get data from the queue */ -static int queue_get(struct ring_buf *rb, void **mem_block, size_t *size) +static int queue_get(struct ring_buffer *rb, void **mem_block, size_t *size) { unsigned int key; @@ -137,7 +137,7 @@ static int queue_get(struct ring_buf *rb, void **mem_block, size_t *size) /* * Put data in the queue */ -static int queue_put(struct ring_buf *rb, void *mem_block, size_t size) +static int queue_put(struct ring_buffer *rb, void *mem_block, size_t size) { uint16_t head_next; unsigned int key; diff --git a/drivers/i3c/CMakeLists.txt b/drivers/i3c/CMakeLists.txt index 0a2ef3a5f5d6e..4b916a8c48011 100644 --- a/drivers/i3c/CMakeLists.txt +++ b/drivers/i3c/CMakeLists.txt @@ -11,6 +11,14 @@ zephyr_library_sources( i3c_common.c ) +if(CONFIG_I3C_NUM_OF_DESC_MEM_SLABS GREATER 0) + zephyr_library_sources(i3c_mem_slab.c) +endif() + +if(CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS GREATER 0) + zephyr_library_sources(i3c_i2c_mem_slab.c) +endif() + zephyr_library_sources_ifdef( CONFIG_USERSPACE i3c_handlers.c @@ -41,7 +49,23 @@ zephyr_library_sources_ifdef( i3c_npcx.c ) +zephyr_library_sources_ifdef( + CONFIG_I3C_STM32 + i3c_stm32.c +) + +zephyr_library_sources_ifdef( + CONFIG_I3C_DW + i3c_dw.c +) + zephyr_library_sources_ifdef( CONFIG_I3C_TEST i3c_test.c ) + +zephyr_library_sources_ifdef( + CONFIG_I3C_RTIO + i3c_rtio.c + i3c_rtio_default.c +) diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig index 33ecb653aa9f0..3bf69e2eaa6fc 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -117,11 +117,73 @@ config I3C_INIT_RSTACT This determines whether the bus initialization routine sends a reset action command to I3C targets. +config I3C_NUM_OF_DESC_MEM_SLABS + int "Number of I3C Device Descriptors Mem Slabs" + default 3 + help + This is the number of memory slabs allocated from when + there is a device encounted through ENTDAA or DEFTGTS that + is not within known I3C devices. + +config I3C_I2C_NUM_OF_DESC_MEM_SLABS + int "Number of I2C Device Descriptors Mem Slabs" + default 3 + help + This is the number of memory slabs allocated from when + there is a device encounted through DEFTGTS that is not + within known I2C devices. + +config I3C_RTIO + bool "I3C RTIO API" + select EXPERIMENTAL + select RTIO + select RTIO_WORKQ + help + API and implementations of I3C for RTIO + +if I3C_RTIO +config I3C_RTIO_SQ_SIZE + int "Submission queue size for blocking calls" + default 4 + help + Blocking i3c calls when I3C_RTIO is enabled are copied into a per driver + submission queue. The queue depth determines the number of possible i3c_msg + structs that may be in the array given to i3c_transfer. A sensible default + is going to be 4 given the device address, register address, and a value + to be read or written. + +config I3C_RTIO_CQ_SIZE + int "Completion queue size for blocking calls" + default 4 + help + Blocking i3c calls when I3C_RTIO is enabled are copied into a per driver + submission queue. The queue depth determines the number of possible i3c_msg + structs that may be in the array given to i3c_transfer. A sensible default + is going to be 4 given the device address, register address, and a value + to be read or written. + +config I3C_RTIO_FALLBACK_MSGS + int "Number of available i3c_msg structs for the default handler to use" + default 4 + help + When RTIO is used with a driver that does not yet implement the submit API + natively the submissions are converted back to struct i3c_msg values that + are given to i3c_transfer. This requires some number of msgs be available to convert + the submissions into on the stack. MISRA rules dictate we must know this in + advance. + + In all likelihood 4 is going to work for everyone, but in case you do end up with + an issue where you are using RTIO, your driver does not implement submit natively, + +endif # I3C_RTIO + comment "Device Drivers" rsource "Kconfig.nxp" rsource "Kconfig.cdns" rsource "Kconfig.npcx" +rsource "Kconfig.dw" rsource "Kconfig.test" +rsource "Kconfig.stm32" endif # I3C diff --git a/drivers/i3c/Kconfig.dw b/drivers/i3c/Kconfig.dw new file mode 100644 index 0000000000000..6dbfceba16112 --- /dev/null +++ b/drivers/i3c/Kconfig.dw @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Meta Platforms, Inc. and its affiliates. +# +# SPDX-License-Identifier: Apache-2.0 + +module = I3C_DW +module-str = i3c-dw +source "subsys/logging/Kconfig.template.log_config" + +config I3C_DW + bool "DW I3C support" + select I3C_IBI_WORKQUEUE if I3C_USE_IBI + depends on DT_HAS_SNPS_DESIGNWARE_I3C_ENABLED + depends on CLOCK_CONTROL + default y + help + Enable the Synopsys Designware I3C driver diff --git a/drivers/i3c/Kconfig.stm32 b/drivers/i3c/Kconfig.stm32 new file mode 100644 index 0000000000000..5aad52c221d3a --- /dev/null +++ b/drivers/i3c/Kconfig.stm32 @@ -0,0 +1,36 @@ +# Copyright (c) 2024 EXALT Technologies. +# +# SPDX-License-Identifier: Apache-2.0 + +module = I3C_STM32 +module-str = i3c_stm32 + +source "subsys/logging/Kconfig.template.log_config" +config I3C_STM32 + bool "STM32 I3C driver support" + depends on DT_HAS_ST_STM32_I3C_ENABLED + select I3C_IBI_WORKQUEUE if I3C_USE_IBI + default y + help + Enable support for I3C on STM32 microcontrollers. + +if I3C_STM32 + +config I3C_STM32_DMA + bool "STM32 I3C DMA driver support" + select DMA + help + Enables support for I3C DMA mode on STM32 microcontrollers. + +config I3C_STM32_DMA_FIFO_HEAP_SIZE + int "Status FIFO and control FIFO heap" + depends on I3C_STM32_DMA + default 2048 + help + Configures the heap size for dynamically allocating the regions for + storing status FIFO and control FIFO words which will be used by the DMA. + This value depends on the maximum number of messages that will be sent + during a single transfer. 2KB guarantees enough heap size for sending 256 + messages on a single transfer. + +endif # I3C_STM32 diff --git a/drivers/i3c/i3c_ccc.c b/drivers/i3c/i3c_ccc.c index f2a5cbfbf8d61..f0a50dd7674c5 100644 --- a/drivers/i3c/i3c_ccc.c +++ b/drivers/i3c/i3c_ccc.c @@ -860,14 +860,14 @@ int i3c_ccc_do_getmxds(const struct i3c_device_desc *target, len = ccc_tgt_payload.num_xfer; if ((fmt == GETMXDS_FORMAT_1) || (fmt == GETMXDS_FORMAT_2)) { - if (len == sizeof(((union i3c_ccc_getmxds *)0)->fmt1)) { + if (len == SIZEOF_FIELD(union i3c_ccc_getmxds, fmt1)) { mxds->fmt1.maxwr = data[0]; mxds->fmt1.maxrd = data[1]; /* It is unknown wither format 1 or format 2 is returned ahead of * time */ memset(&mxds->fmt2.maxrdturn, 0, sizeof(mxds->fmt2.maxrdturn)); - } else if (len == sizeof(((union i3c_ccc_getmxds *)0)->fmt2)) { + } else if (len == SIZEOF_FIELD(union i3c_ccc_getmxds, fmt2)) { mxds->fmt2.maxwr = data[0]; mxds->fmt2.maxrd = data[1]; memcpy(&mxds->fmt2.maxrdturn, &data[2], @@ -910,3 +910,28 @@ int i3c_ccc_do_setbuscon(const struct device *controller, return i3c_do_ccc(controller, &ccc_payload); } + +int i3c_ccc_do_getacccr(const struct i3c_device_desc *target, + struct i3c_ccc_address *handoff_address) +{ + struct i3c_ccc_payload ccc_payload; + struct i3c_ccc_target_payload ccc_tgt_payload; + int ret; + + __ASSERT_NO_MSG(target != NULL); + __ASSERT_NO_MSG(handoff_address != NULL); + + ccc_tgt_payload.addr = target->dynamic_addr; + ccc_tgt_payload.rnw = 1; + ccc_tgt_payload.data = &handoff_address->addr; + ccc_tgt_payload.data_len = 1; + + memset(&ccc_payload, 0, sizeof(ccc_payload)); + ccc_payload.ccc.id = I3C_CCC_GETACCCR; + ccc_payload.targets.payloads = &ccc_tgt_payload; + ccc_payload.targets.num_targets = 1; + + ret = i3c_do_ccc(target->bus, &ccc_payload); + + return ret; +} diff --git a/drivers/i3c/i3c_cdns.c b/drivers/i3c/i3c_cdns.c index 1690b33f9a43b..f40c9d4825f04 100644 --- a/drivers/i3c/i3c_cdns.c +++ b/drivers/i3c/i3c_cdns.c @@ -14,6 +14,8 @@ #include #include +#include + #define DEV_ID 0x0 #define DEV_ID_I3C_MASTER 0x5034 @@ -344,7 +346,8 @@ #define SLV_ERR1 BIT(1) #define SLV_ERR0 BIT(0) -#define SLV_STATUS2 0xA8 +#define SLV_STATUS2 0xA8 +#define SLV_STATUS2_MRL(s) (((s) & GENMASK(23, 8)) >> 8) #define SLV_STATUS3 0xAC #define SLV_STATUS3_BC_FSM(s) (((s) & GENMASK(26, 16)) >> 16) @@ -483,8 +486,6 @@ #define I3C_CMDR_THR 1 /* command tx fifo threshold - unused */ #define I3C_CMDD_THR 1 -/* in-band-interrupt data fifo threshold - unused */ -#define I3C_IBID_THR 1 /* in-band-interrupt response queue threshold */ #define I3C_IBIR_THR 1 /* tx data threshold - unused */ @@ -537,6 +538,7 @@ struct cdns_i3c_cmd { uint32_t *num_xfer; void *buf; uint32_t error; + enum i3c_sdr_controller_error_types *sdr_err; enum i3c_data_rate hdr; }; @@ -571,7 +573,9 @@ struct cdns_i3c_config { /* Driver instance data */ struct cdns_i3c_data { + /* common must be first! */ struct i3c_driver_data common; + const struct device *dev; struct cdns_i3c_hw_config hw_cfg; #ifdef CONFIG_I3C_USE_IBI struct cdns_i3c_ibi_buf ibi_buf; @@ -580,7 +584,12 @@ struct cdns_i3c_data { struct cdns_i3c_i2c_dev_data cdns_i3c_i2c_priv_data[I3C_MAX_DEVS]; struct cdns_i3c_xfer xfer; struct i3c_target_config *target_config; + struct k_work deftgts_work; +#ifdef CONFIG_I3C_USE_IBI struct k_sem ibi_hj_complete; + struct k_sem ibi_cr_complete; +#endif + struct k_sem ch_complete; uint32_t free_rr_slots; uint16_t fifo_bytes_read; uint8_t max_devs; @@ -998,7 +1007,8 @@ static uint32_t prepare_rr0_dev_address(uint16_t addr) /** * @brief Program Retaining Registers with device lists * - * This will program the retaining register with the controller itself + * This will program the retaining register with the controller itself, this should + * only be called if it is a primary controller. * * @param dev Pointer to controller device driver instance. */ @@ -1014,12 +1024,26 @@ static void cdns_i3c_program_controller_retaining_reg(const struct device *dev) i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots, 0); LOG_DBG("%s: 0x%02x DA selected for controller", dev->name, controller_da); } - sys_write32(prepare_rr0_dev_address(controller_da), config->base + DEV_ID_RR0(0)); + sys_write32(prepare_rr0_dev_address(controller_da) | DEV_ID_RR0_IS_I3C, + config->base + DEV_ID_RR0(0)); /* Mark the address as I3C device */ i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, controller_da); } #ifdef CONFIG_I3C_USE_IBI +static int cdns_i3c_ibi_hj_response(const struct device *dev, bool ack) +{ + const struct cdns_i3c_config *config = dev->config; + + if (ack) { + sys_write32(CTRL_HJ_ACK | sys_read32(config->base + CTRL), config->base + CTRL); + } else { + sys_write32(~CTRL_HJ_ACK & sys_read32(config->base + CTRL), config->base + CTRL); + } + + return 0; +} + static int cdns_i3c_controller_ibi_enable(const struct device *dev, struct i3c_device_desc *target) { uint32_t sir_map; @@ -1029,7 +1053,8 @@ static int cdns_i3c_controller_ibi_enable(const struct device *dev, struct i3c_d struct i3c_ccc_events i3c_events; int ret = 0; - if (!i3c_device_is_ibi_capable(target)) { + /* Check if the device can issue IBI TIRs or CR */ + if (!i3c_device_is_ibi_capable(target) && !i3c_device_is_controller_capable(target)) { ret = -EINVAL; return ret; } @@ -1039,7 +1064,8 @@ static int cdns_i3c_controller_ibi_enable(const struct device *dev, struct i3c_d sir_cfg = SIR_MAP_DEV_ROLE(I3C_BCR_DEVICE_ROLE(target->bcr)) | SIR_MAP_DEV_DA(target->dynamic_addr) | SIR_MAP_DEV_PL(target->data_length.max_ibi); - if (target->ibi_cb != NULL) { + /* ACK if there is an ibi tir cb or if it is controller capable*/ + if ((target->ibi_cb != NULL) || i3c_device_is_controller_capable(target)) { sir_cfg |= SIR_MAP_DEV_ACK; } if (target->bcr & I3C_BCR_MAX_DATA_SPEED_LIMIT) { @@ -1049,8 +1075,8 @@ static int cdns_i3c_controller_ibi_enable(const struct device *dev, struct i3c_d LOG_DBG("%s: IBI enabling for 0x%02x (BCR 0x%02x)", dev->name, target->dynamic_addr, target->bcr); - /* Tell target to enable IBI */ - i3c_events.events = I3C_CCC_EVT_INTR; + /* Tell target to enable IBI TIRs and CRs */ + i3c_events.events = I3C_CCC_EVT_INTR | I3C_CCC_EVT_CR; ret = i3c_ccc_do_events_set(target, true, &i3c_events); if (ret != 0) { LOG_ERR("%s: Error sending IBI ENEC for 0x%02x (%d)", dev->name, @@ -1129,6 +1155,31 @@ static int cdns_i3c_target_ibi_raise_hj(const struct device *dev) return 0; } +static int cdns_i3c_target_ibi_raise_cr(const struct device *dev) +{ + const struct cdns_i3c_config *config = dev->config; + struct cdns_i3c_data *data = dev->data; + + /* Check if target does not have a DA assigned to it */ + if (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_HAS_DA)) { + LOG_ERR("%s: CR not available, DA not assigned", dev->name); + return -EACCES; + } + /* Check if CR requests DISEC CCC with DISMR field set has been received */ + if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_MR_DIS) { + LOG_ERR("%s: CR requests are currently disabled by DISEC", dev->name); + return -EAGAIN; + } + + sys_write32(CTRL_MST_INIT | sys_read32(config->base + CTRL), config->base + CTRL); + k_sem_reset(&data->ibi_cr_complete); + if (k_sem_take(&data->ibi_cr_complete, K_MSEC(500)) != 0) { + LOG_ERR("%s: timeout waiting for GETACCCR after CR", dev->name); + return -ETIMEDOUT; + } + return 0; +} + static int cdns_i3c_target_ibi_raise_intr(const struct device *dev, struct i3c_ibi *request) { const struct cdns_i3c_config *config = dev->config; @@ -1137,6 +1188,17 @@ static int cdns_i3c_target_ibi_raise_intr(const struct device *dev, struct i3c_i LOG_DBG("%s: issuing IBI TIR", dev->name); + /* Check if target does not have a DA assigned to it */ + if (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_HAS_DA)) { + LOG_ERR("%s: TIR not available, DA not assigned", dev->name); + return -EACCES; + } + /* Check if TIR requests DISEC CCC with DISMR field set has been received */ + if (sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_IBI_DIS) { + LOG_ERR("%s: TIR requests are currently disabled by DISEC", dev->name); + return -EAGAIN; + } + /* * Ensure data will fit within FIFO * @@ -1161,10 +1223,14 @@ static int cdns_i3c_target_ibi_raise_intr(const struct device *dev, struct i3c_i static int cdns_i3c_target_ibi_raise(const struct device *dev, struct i3c_ibi *request) { + const struct cdns_i3c_config *config = dev->config; struct cdns_i3c_data *data = dev->data; - if (request == NULL) { - return -EINVAL; + __ASSERT_NO_MSG(request != NULL); + + /* make sure we are not currently the active controller */ + if (sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE) { + return -EACCES; } switch (request->ibi_type) { @@ -1176,8 +1242,7 @@ static int cdns_i3c_target_ibi_raise(const struct device *dev, struct i3c_ibi *r return -ENOTSUP; } case I3C_IBI_CONTROLLER_ROLE_REQUEST: - /* TODO: Cadence I3C can support CR, but not implemented yet */ - return -ENOTSUP; + return cdns_i3c_target_ibi_raise_cr(dev); case I3C_IBI_HOTJOIN: return cdns_i3c_target_ibi_raise_hj(dev); default: @@ -1438,10 +1503,11 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay } cmd->hdr = I3C_DATA_RATE_SDR; /* - * write the address of num_xfer which is to be updated upon message - * completion + * write the address of num_xfer and err which is to be updated upon + * message completion */ cmd->num_xfer = &(payload->targets.payloads[i].num_xfer); + cmd->sdr_err = &(payload->targets.payloads[i].err); } } else { cmd = &data->xfer.cmds[0]; @@ -1464,6 +1530,7 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay cmd->len = 0; cmd->num_xfer = NULL; } + cmd->sdr_err = &(payload->ccc.err); } data->xfer.ret = -ETIMEDOUT; @@ -1479,6 +1546,12 @@ static int cdns_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay } ret = data->xfer.ret; + + /* TODO: decide if this is the right approach or add a new separate API for CH */ + /* Wait for Controller Handoff to finish */ + if (payload->ccc.id == I3C_CCC_GETACCCR) { + ret = k_sem_take(&data->ch_complete, K_MSEC(1000)); + } error: k_mutex_unlock(&data->bus_lock); @@ -1564,20 +1637,46 @@ static int cdns_i3c_do_daa(const struct device *dev) const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid); struct i3c_device_desc *target = i3c_device_find(dev, &i3c_id); - if (target == NULL) { + if (!target) { + /* Target found that is not known, allocate a desc */ + target = i3c_device_desc_alloc(); + if (target) { + /* + * able to allocate a descriptor + * write all known values + */ + *(const struct device **)&target->bus = dev; + *(uint64_t *)&target->pid = pid; + target->dynamic_addr = dyn_addr; + target->bcr = bcr; + target->dcr = dcr; + /* attach it to the slist */ + sys_slist_append( + &data->common.attached_dev.devices.i3c, + &target->node); + + data->cdns_i3c_i2c_priv_data[rr_idx].id = rr_idx; + target->controller_priv = + &(data->cdns_i3c_i2c_priv_data[rr_idx]); + } + LOG_INF("%s: PID 0x%012llx is not in registered device " "list, given DA 0x%02x", dev->name, pid, dyn_addr); - i3c_addr_slots_mark_i3c( - &data->common.attached_dev.addr_slots, dyn_addr); } else { target->dynamic_addr = dyn_addr; target->bcr = bcr; target->dcr = dcr; + data->cdns_i3c_i2c_priv_data[rr_idx].id = rr_idx; + target->controller_priv = + &(data->cdns_i3c_i2c_priv_data[rr_idx]); + LOG_DBG("%s: PID 0x%012llx assigned dynamic address 0x%02x", dev->name, pid, dyn_addr); } + i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, + dyn_addr); } } } else { @@ -1740,6 +1839,9 @@ static void cdns_i3c_complete_transfer(const struct device *dev) for (int i = 0; i < data->xfer.num_cmds; i++) { switch (data->xfer.cmds[i].error) { case CMDR_NO_ERROR: + if (data->xfer.cmds[i].sdr_err) { + *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_NONE; + } break; case CMDR_MST_ABORT: @@ -1762,6 +1864,9 @@ static void cdns_i3c_complete_transfer(const struct device *dev) "no EoD from target", dev->name); } + if (data->xfer.cmds[i].sdr_err) { + *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_NONE; + } break; case CMDR_M0_ERROR: { @@ -1782,9 +1887,9 @@ static void cdns_i3c_complete_transfer(const struct device *dev) * time which will be returned. */ if ((*data->xfer.cmds[i].num_xfer != - sizeof(((union i3c_ccc_getmxds *)0)->fmt1)) && + SIZEOF_FIELD(union i3c_ccc_getmxds, fmt1)) && (*data->xfer.cmds[i].num_xfer != - sizeof(((union i3c_ccc_getmxds *)0)->fmt2))) { + SIZEOF_FIELD(union i3c_ccc_getmxds, fmt2))) { ret = -EIO; } } else if (ccc == I3C_CCC_GETCAPS) { @@ -1793,27 +1898,50 @@ static void cdns_i3c_complete_transfer(const struct device *dev) ret = -EIO; } } else { + if (data->xfer.cmds[i].sdr_err) { + *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE0; + } ret = -EIO; } break; } - case CMDR_DDR_PREAMBLE_ERROR: - case CMDR_DDR_PARITY_ERROR: case CMDR_M1_ERROR: + if (data->xfer.cmds[i].sdr_err) { + *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE1; + } + ret = -EIO; + break; case CMDR_M2_ERROR: + if (data->xfer.cmds[i].sdr_err) { + *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE2; + } + ret = -EIO; + break; + + case CMDR_DDR_PREAMBLE_ERROR: + case CMDR_DDR_PARITY_ERROR: case CMDR_NACK_RESP: case CMDR_DDR_DROPPED: + if (data->xfer.cmds[i].sdr_err) { + *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_UNKNOWN; + } ret = -EIO; break; case CMDR_DDR_RX_FIFO_OVF: case CMDR_DDR_TX_FIFO_UNF: + if (data->xfer.cmds[i].sdr_err) { + *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_UNKNOWN; + } ret = -ENOSPC; break; case CMDR_INVALID_DA: default: + if (data->xfer.cmds[i].sdr_err) { + *data->xfer.cmds[i].sdr_err = I3C_ERROR_CE_UNKNOWN; + } ret = -EINVAL; break; } @@ -1910,8 +2038,9 @@ static int cdns_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device cmd->cmd0 |= CMD0_FIFO_RNW; } - /* i2c transfers are a don't care for num_xfer */ + /* i2c transfers are a don't care for num_xfer and sdr error */ cmd->num_xfer = NULL; + cmd->sdr_err = NULL; } data->xfer.ret = -ETIMEDOUT; @@ -1955,7 +2084,7 @@ static int cdns_i3c_master_get_rr_slot(const struct device *dev, uint8_t dyn_add rr_idx = i - 1; if (activedevs & BIT(rr_idx)) { rr = sys_read32(config->base + DEV_ID_RR0(rr_idx)); - if ((rr & DEV_ID_RR0_IS_I3C) && DEV_ID_RR0_GET_DEV_ADDR(rr) == dyn_addr) { + if ((rr & DEV_ID_RR0_IS_I3C) && (DEV_ID_RR0_GET_DEV_ADDR(rr) == dyn_addr)) { return rr_idx; } } @@ -1979,8 +2108,7 @@ static int cdns_i3c_attach_device(const struct device *dev, struct i3c_device_de const struct cdns_i3c_config *config = dev->config; struct cdns_i3c_data *data = dev->data; - int slot = cdns_i3c_master_get_rr_slot(dev, desc->dynamic_addr ? desc->dynamic_addr - : desc->static_addr); + int slot = cdns_i3c_master_get_rr_slot(dev, desc->dynamic_addr); if (slot < 0) { LOG_ERR("%s: no space for i3c device: %s", dev->name, desc->dev->name); @@ -2237,6 +2365,7 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t * completion */ cmd->num_xfer = &(msgs[i].num_xfer); + cmd->sdr_err = &(msgs[i].err); cmd->hdr = I3C_DATA_RATE_SDR; } else if ((data->common.ctrl_config.supported_hdr & I3C_MSG_HDR_DDR) && (msgs[i].hdr_mode == I3C_MSG_HDR_DDR) && (msgs[i].flags & I3C_MSG_HDR)) { @@ -2290,6 +2419,7 @@ static int cdns_i3c_transfer(const struct device *dev, struct i3c_device_desc *t * completion */ cmd->num_xfer = &(msgs[i].num_xfer); + cmd->sdr_err = &(msgs[i].err); cmd->hdr = I3C_DATA_RATE_HDR_DDR; } else { LOG_ERR("%s: Unsupported HDR Mode %d", dev->name, msgs[i].hdr_mode); @@ -2393,6 +2523,45 @@ static void cdns_i3c_handle_ibi(const struct device *dev, uint32_t ibir) } } +static void cdns_i3c_handle_cr(const struct device *dev, uint32_t ibir) +{ + const struct cdns_i3c_config *config = dev->config; + + /* The slave ID returned here is the device ID in the SIR map NOT the device ID + * in the RR map. + */ + uint8_t slave_id = IBIR_SLVID(ibir); + + if (slave_id == IBIR_SLVID_INV) { + /* DA does not match any value among SIR map */ + return; + } + + uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(slave_id + 1)); + uint8_t dyn_addr = DEV_ID_RR0_GET_DEV_ADDR(dev_id_rr0); + struct i3c_device_desc *desc = i3c_dev_list_i3c_addr_find(dev, dyn_addr); + + /* + * Check for NAK or error conditions. + * + * Note: The logging is for debugging only so will be compiled out in most cases. + * However, if the log level for this module is DEBUG and log mode is IMMEDIATE or MINIMAL, + * this option is also set this may cause problems due to being inside an ISR. + */ + if (!(IBIR_ACKED & ibir)) { + LOG_DBG("%s: NAK for slave ID %u", dev->name, (unsigned int)slave_id); + return; + } + if (ibir & IBIR_ERROR) { + LOG_ERR("%s: Data overflow", dev->name); + return; + } + + if (i3c_ibi_work_enqueue_controller_request(desc) != 0) { + LOG_ERR("%s: Error enqueue IBI IRQ work", dev->name); + } +} + static void cdns_i3c_handle_hj(const struct device *dev, uint32_t ibir) { if (!(IBIR_ACKED & ibir)) { @@ -2400,6 +2569,7 @@ static void cdns_i3c_handle_hj(const struct device *dev, uint32_t ibir) return; } + /* TODO: disable CTRL_HJ_DISEC and process auto-ENTDAA*/ if (i3c_ibi_work_enqueue_hotjoin(dev) != 0) { LOG_ERR("%s: Error enqueue IBI HJ work", dev->name); } @@ -2421,7 +2591,7 @@ static void cnds_i3c_master_demux_ibis(const struct device *dev) cdns_i3c_handle_hj(dev, ibir); break; case IBIR_TYPE_MR: - /* not implemented */ + cdns_i3c_handle_cr(dev, ibir); break; default: break; @@ -2435,6 +2605,13 @@ static void cdns_i3c_target_ibi_hj_complete(const struct device *dev) k_sem_give(&data->ibi_hj_complete); } + +static void cdns_i3c_target_ibi_cr_complete(const struct device *dev) +{ + struct cdns_i3c_data *data = dev->data; + + k_sem_give(&data->ibi_cr_complete); +} #endif static void cdns_i3c_target_sdr_tx_thr_int_handler(const struct device *dev, @@ -2495,236 +2672,239 @@ static void cdns_i3c_irq_handler(const struct device *dev) { const struct cdns_i3c_config *config = dev->config; struct cdns_i3c_data *data = dev->data; + uint32_t int_st = sys_read32(config->base + MST_ISR); - if (sys_read32(config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE) { - uint32_t int_st = sys_read32(config->base + MST_ISR); - sys_write32(int_st, config->base + MST_ICR); + sys_write32(int_st, config->base + MST_ICR); - /* Command queue empty */ - if (int_st & MST_INT_HALTED) { - LOG_WRN("Core Halted, 2 read aborts"); - } + /* Command queue empty */ + if (int_st & MST_INT_HALTED) { + LOG_WRN("Core Halted, 2 read aborts"); + } - /* Command queue empty */ - if (int_st & MST_INT_CMDD_EMP) { - cdns_i3c_complete_transfer(dev); - } + /* Command queue empty */ + if (int_st & MST_INT_CMDD_EMP) { + cdns_i3c_complete_transfer(dev); + } - /* In-band interrupt */ - if (int_st & MST_INT_IBIR_THR) { + /* In-band interrupt */ + if (int_st & MST_INT_IBIR_THR) { #ifdef CONFIG_I3C_USE_IBI - cnds_i3c_master_demux_ibis(dev); + cnds_i3c_master_demux_ibis(dev); #else - LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", - dev->name); + LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", dev->name); #endif - } + } - /* In-band interrupt data threshold */ - if (int_st & MST_INT_IBID_THR) { + /* In-band interrupt data threshold */ + if (int_st & MST_INT_IBID_THR) { #ifdef CONFIG_I3C_USE_IBI - /* pop data out of the IBI FIFO */ - while (!cdns_i3c_ibi_fifo_empty(config)) { - uint32_t *ptr = (uint32_t *)&data->ibi_buf - .ibi_data[data->ibi_buf.ibi_data_cnt]; - *ptr = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); - data->ibi_buf.ibi_data_cnt += 4; - } + /* pop data out of the IBI FIFO */ + while (!cdns_i3c_ibi_fifo_empty(config)) { + uint32_t *ptr = + (uint32_t *)&data->ibi_buf.ibi_data[data->ibi_buf.ibi_data_cnt]; + *ptr = sys_le32_to_cpu(sys_read32(config->base + IBI_DATA_FIFO)); + data->ibi_buf.ibi_data_cnt += 4; + } #else - LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", - dev->name); + LOG_ERR("%s: IBI received - Kconfig for using IBIs is not enabled", dev->name); #endif - } + } - /* In-band interrupt response overflow */ - if (int_st & MST_INT_IBIR_OVF) { - LOG_ERR("%s: controller ibir overflow,", dev->name); - } + /* In-band interrupt response overflow */ + if (int_st & MST_INT_IBIR_OVF) { + LOG_ERR("%s: controller ibir overflow,", dev->name); + } - /* In-band interrupt data */ - if (int_st & MST_INT_TX_OVF) { - LOG_ERR("%s: controller tx buffer overflow,", dev->name); - } + /* In-band interrupt data */ + if (int_st & MST_INT_TX_OVF) { + LOG_ERR("%s: controller tx buffer overflow,", dev->name); + } - /* In-band interrupt data */ - if (int_st & MST_INT_RX_UNF) { - LOG_ERR("%s: controller rx buffer underflow,", dev->name); - } - } else { - uint32_t int_sl = sys_read32(config->base + SLV_ISR); - const struct i3c_target_callbacks *target_cb = - data->target_config ? data->target_config->callbacks : NULL; - /* Clear interrupts */ - sys_write32(int_sl, config->base + SLV_ICR); - - /* SLV SDR rx fifo threshold */ - if (int_sl & SLV_INT_SDR_RX_THR) { - /* while rx fifo is not empty */ - while (!(sys_read32(config->base + SLV_STATUS1) & - SLV_STATUS1_SDR_RX_EMPTY)) { - if (target_cb != NULL && target_cb->write_received_cb != NULL) { - cdns_i3c_target_read_rx_fifo(dev); - } + /* In-band interrupt data */ + if (int_st & MST_INT_RX_UNF) { + LOG_ERR("%s: controller rx buffer underflow,", dev->name); + } + + if (int_st & MST_INT_MR_DONE) { + LOG_DBG("%s: controller CR Handoff done,", dev->name); + k_sem_give(&data->ch_complete); + } + + uint32_t int_sl = sys_read32(config->base + SLV_ISR); + const struct i3c_target_callbacks *target_cb = + data->target_config ? data->target_config->callbacks : NULL; + /* Clear interrupts */ + sys_write32(int_sl, config->base + SLV_ICR); + + /* SLV SDR rx fifo threshold */ + if (int_sl & SLV_INT_SDR_RX_THR) { + /* while rx fifo is not empty */ + while (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_SDR_RX_EMPTY)) { + if (target_cb != NULL && target_cb->write_received_cb != NULL) { + cdns_i3c_target_read_rx_fifo(dev); } } + } - /* SLV SDR tx fifo threshold */ - if (int_sl & SLV_INT_SDR_TX_THR) { - cdns_i3c_target_sdr_tx_thr_int_handler(dev, target_cb); - } + /* SLV SDR tx fifo threshold */ + if (int_sl & SLV_INT_SDR_TX_THR) { + cdns_i3c_target_sdr_tx_thr_int_handler(dev, target_cb); + } - /* SLV SDR rx complete */ - if (int_sl & SLV_INT_SDR_RD_COMP) { - /* a read needs to be done on slv_status 0 else a NACK will happen */ - (void)sys_read32(config->base + SLV_STATUS0); - /* call stop function pointer */ - if (target_cb != NULL && target_cb->stop_cb) { - target_cb->stop_cb(data->target_config); - } + /* SLV SDR rx complete */ + if (int_sl & SLV_INT_SDR_RD_COMP) { + /* a read needs to be done on slv_status 0 else a NACK will happen */ + (void)sys_read32(config->base + SLV_STATUS0); + /* call stop function pointer */ + if (target_cb != NULL && target_cb->stop_cb) { + target_cb->stop_cb(data->target_config); } + } - /* SLV SDR tx complete */ - if (int_sl & SLV_INT_SDR_WR_COMP) { - /* a read needs to be done on slv_status 0 else a NACK will happen */ - (void)sys_read32(config->base + SLV_STATUS0); - /* clear bytes read parameter */ - data->fifo_bytes_read = 0; - /* call stop function pointer */ - if (target_cb != NULL && target_cb->stop_cb) { - target_cb->stop_cb(data->target_config); - } + /* SLV SDR tx complete */ + if (int_sl & SLV_INT_SDR_WR_COMP) { + /* a read needs to be done on slv_status 0 else a NACK will happen */ + (void)sys_read32(config->base + SLV_STATUS0); + /* clear bytes read parameter */ + data->fifo_bytes_read = 0; + /* call stop function pointer */ + if (target_cb != NULL && target_cb->stop_cb) { + target_cb->stop_cb(data->target_config); } + } - /* DA has been updated */ - if (int_sl & SLV_INT_DA_UPD) { - LOG_INF("%s: DA updated to 0x%02lx", dev->name, - SLV_STATUS1_DA(sys_read32(config->base + SLV_STATUS1))); - /* HJ could send a DISEC which would trigger the SLV_INT_EVENT_UP bit, - * but it's still expected to eventually send a DAA - */ + /* DA has been updated */ + if (int_sl & SLV_INT_DA_UPD) { + LOG_INF("%s: DA updated to 0x%02lx", dev->name, + SLV_STATUS1_DA(sys_read32(config->base + SLV_STATUS1))); #ifdef CONFIG_I3C_USE_IBI - cdns_i3c_target_ibi_hj_complete(dev); + cdns_i3c_target_ibi_hj_complete(dev); #endif - } + } - /* HJ complete and DA has been assigned */ - if (int_sl & SLV_INT_HJ_DONE) { - } + /* HJ complete and DA has been assigned or HJ NACK'ed or DISEC disabled HJ */ + if (int_sl & SLV_INT_HJ_DONE) { - /* Controllership has been been given */ - if (int_sl & SLV_INT_MR_DONE) { - /* TODO: implement support for controllership handoff */ - } + } - /* EISC or DISEC has been received */ - if (int_sl & SLV_INT_EVENT_UP) { + /* Controllership has been been given to us */ + if (int_sl & SLV_INT_MR_DONE) { +#ifdef CONFIG_I3C_USE_IBI + cdns_i3c_target_ibi_cr_complete(dev); + i3c_ibi_work_enqueue_cb(dev, i3c_sec_handoffed); + if (target_cb != NULL && target_cb->controller_handoff_cb) { + target_cb->controller_handoff_cb(data->target_config); } +#endif + } - /* sdr transfer aborted by controller */ - if (int_sl & SLV_INT_M_RD_ABORT) { - /* TODO: consider flushing tx buffer? */ - } + /* EISC or DISEC has been received */ + if (int_sl & SLV_INT_EVENT_UP) { + } - /* SLV SDR rx fifo underflow */ - if (int_sl & SLV_INT_SDR_RX_UNF) { - LOG_ERR("%s: slave sdr rx buffer underflow", dev->name); - } + /* sdr transfer aborted by controller */ + if (int_sl & SLV_INT_M_RD_ABORT) { + /* TODO: consider flushing tx buffer? */ + } - /* SLV SDR tx fifo overflow */ - if (int_sl & SLV_INT_SDR_TX_OVF) { - LOG_ERR("%s: slave sdr tx buffer overflow,", dev->name); - } + /* SLV SDR rx fifo underflow */ + if (int_sl & SLV_INT_SDR_RX_UNF) { + LOG_ERR("%s: slave sdr rx buffer underflow", dev->name); + } - if (int_sl & SLV_INT_DDR_RX_THR) { - } + /* SLV SDR tx fifo overflow */ + if (int_sl & SLV_INT_SDR_TX_OVF) { + LOG_ERR("%s: slave sdr tx buffer overflow,", dev->name); + } - /* SLV DDR WR COMPLETE */ - if (int_sl & SLV_INT_DDR_WR_COMP) { - /* initial value of CRC5 for HDR-DDR is 0x1F */ - uint8_t crc5 = 0x1F; + if (int_sl & SLV_INT_DDR_RX_THR) { + } - while (!(sys_read32(config->base + SLV_STATUS1) & - SLV_STATUS1_DDR_RX_EMPTY)) { - uint32_t ddr_rx_data = sys_read32(config->base + SLV_DDR_RX_FIFO); - uint32_t preamble = (ddr_rx_data & DDR_PREAMBLE_MASK); + /* SLV DDR WR COMPLETE */ + if (int_sl & SLV_INT_DDR_WR_COMP) { + /* initial value of CRC5 for HDR-DDR is 0x1F */ + uint8_t crc5 = 0x1F; - if (preamble == DDR_PREAMBLE_DATA_ABORT || - preamble == DDR_PREAMBLE_DATA_ABORT_ALT) { - uint16_t ddr_payload = DDR_DATA(ddr_rx_data); + while (!(sys_read32(config->base + SLV_STATUS1) & SLV_STATUS1_DDR_RX_EMPTY)) { + uint32_t ddr_rx_data = sys_read32(config->base + SLV_DDR_RX_FIFO); + uint32_t preamble = (ddr_rx_data & DDR_PREAMBLE_MASK); - if (cdns_i3c_ddr_parity(ddr_payload) != - (ddr_rx_data & (DDR_ODD_PARITY | DDR_EVEN_PARITY))) { - LOG_ERR("%s: Received incorrect DDR Parity", - dev->name); - } - /* calculate a running a crc */ - crc5 = i3c_cdns_crc5(crc5, ddr_payload); - - if (target_cb != NULL && - target_cb->write_received_cb != NULL) { - /* DDR receives 2B for each payload */ - target_cb->write_received_cb( - data->target_config, - (uint8_t)((ddr_payload >> 8) & 0xFF)); - target_cb->write_received_cb( - data->target_config, - (uint8_t)(ddr_payload)); - } + if (preamble == DDR_PREAMBLE_DATA_ABORT || + preamble == DDR_PREAMBLE_DATA_ABORT_ALT) { + uint16_t ddr_payload = DDR_DATA(ddr_rx_data); - } else if ((preamble == DDR_PREAMBLE_CMD_CRC) && - ((ddr_rx_data & DDR_CRC_TOKEN_MASK) == DDR_CRC_TOKEN)) { - /* should come through here last */ - if (crc5 != DDR_CRC(ddr_rx_data)) { - LOG_ERR("%s: Received incorrect DDR CRC5", - dev->name); - } - } else if (preamble == DDR_PREAMBLE_CMD_CRC) { - /* should come through here first */ - uint16_t ddr_header_payload = DDR_DATA(ddr_rx_data); + if (cdns_i3c_ddr_parity(ddr_payload) != + (ddr_rx_data & (DDR_ODD_PARITY | DDR_EVEN_PARITY))) { + LOG_ERR("%s: Received incorrect DDR Parity", dev->name); + } + /* calculate a running a crc */ + crc5 = i3c_cdns_crc5(crc5, ddr_payload); - crc5 = i3c_cdns_crc5(crc5, ddr_header_payload); + if (target_cb != NULL && target_cb->write_received_cb != NULL) { + /* DDR receives 2B for each payload */ + target_cb->write_received_cb( + data->target_config, + (uint8_t)((ddr_payload >> 8) & 0xFF)); + target_cb->write_received_cb(data->target_config, + (uint8_t)(ddr_payload)); } - } - if (target_cb != NULL && target_cb->stop_cb != NULL) { - target_cb->stop_cb(data->target_config); + } else if ((preamble == DDR_PREAMBLE_CMD_CRC) && + ((ddr_rx_data & DDR_CRC_TOKEN_MASK) == DDR_CRC_TOKEN)) { + /* should come through here last */ + if (crc5 != DDR_CRC(ddr_rx_data)) { + LOG_ERR("%s: Received incorrect DDR CRC5", dev->name); + } + } else if (preamble == DDR_PREAMBLE_CMD_CRC) { + /* should come through here first */ + uint16_t ddr_header_payload = DDR_DATA(ddr_rx_data); + + crc5 = i3c_cdns_crc5(crc5, ddr_header_payload); } } - /* SLV SDR rx complete */ - if (int_sl & SLV_INT_DDR_RD_COMP) { - /* a read needs to be done on slv_status 0 else a NACK will happen */ - (void)sys_read32(config->base + SLV_STATUS0); - /* call stop function pointer */ - if (target_cb != NULL && target_cb->stop_cb) { - target_cb->stop_cb(data->target_config); - } + if (target_cb != NULL && target_cb->stop_cb != NULL) { + target_cb->stop_cb(data->target_config); + } + } + + /* SLV SDR rx complete */ + if (int_sl & SLV_INT_DDR_RD_COMP) { + /* a read needs to be done on slv_status 0 else a NACK will happen */ + (void)sys_read32(config->base + SLV_STATUS0); + /* call stop function pointer */ + if (target_cb != NULL && target_cb->stop_cb) { + target_cb->stop_cb(data->target_config); } + } - /*SLV DDR TX THR*/ - if (int_sl & SLV_INT_DDR_TX_THR) { - int status = 0; + /* SLV DDR TX THR */ + if (int_sl & SLV_INT_DDR_TX_THR) { + int status = 0; - if (target_cb != NULL && target_cb->read_processed_cb) { + if (target_cb != NULL && target_cb->read_processed_cb) { - while ((!(sys_read32(config->base + SLV_STATUS1) & - SLV_STATUS1_DDR_TX_FULL)) && - (status == 0)) { - /* call function pointer for read */ - uint8_t byte; - /* will return negative if no data left to transmit - * and 0 if data available - */ - status = target_cb->read_processed_cb(data->target_config, - &byte); - if (status == 0) { - cdns_i3c_write_ddr_tx_fifo(config, &byte, - sizeof(byte)); - } + while ((!(sys_read32(config->base + SLV_STATUS1) & + SLV_STATUS1_DDR_TX_FULL)) && + (status == 0)) { + /* call function pointer for read */ + uint8_t byte; + /* will return negative if no data left to transmit + * and 0 if data available + */ + status = target_cb->read_processed_cb(data->target_config, &byte); + if (status == 0) { + cdns_i3c_write_ddr_tx_fifo(config, &byte, sizeof(byte)); } } } } + + /* DEFTGTS */ + if (int_sl & SLV_INT_DEFSLVS) { + /* Execute outside of the ISR context */ + k_work_submit(&data->deftgts_work); + } } static void cdns_i3c_read_hw_cfg(const struct device *dev) @@ -2798,18 +2978,50 @@ static void cdns_i3c_read_hw_cfg(const struct device *dev) */ static int cdns_i3c_config_get(const struct device *dev, enum i3c_config_type type, void *config) { + const struct cdns_i3c_config *dev_config = dev->config; struct cdns_i3c_data *data = dev->data; - int ret = 0; - if (config == NULL) { - ret = -EINVAL; - goto out_configure; + __ASSERT_NO_MSG(config != NULL); + + if (type == I3C_CONFIG_CONTROLLER) { + (void)memcpy(config, &data->common.ctrl_config, sizeof(data->common.ctrl_config)); + } else if (type == I3C_CONFIG_TARGET) { + struct i3c_config_target *target_config = (struct i3c_config_target *)config; + /* Read RR_0 registers for itself */ + uint32_t dev_id_rr0 = sys_read32(dev_config->base + DEV_ID_RR0(0)); + uint32_t dev_id_rr1 = sys_read32(dev_config->base + DEV_ID_RR1(0)); + uint32_t dev_id_rr2 = sys_read32(dev_config->base + DEV_ID_RR2(0)); + uint32_t slv_status1 = sys_read32(dev_config->base + SLV_STATUS1); + + /* if we are currently a target */ + target_config->enable = + !!!(sys_read32(dev_config->base + MST_STATUS0) & MST_STATUS0_MASTER_MODE); + if (data->common.ctrl_config.is_secondary) { + target_config->dynamic_addr = SLV_STATUS1_DA(slv_status1); + } else { + target_config->dynamic_addr = (dev_id_rr0 & 0xFE) >> 1; + } + target_config->static_addr = 0; + target_config->pid = ((uint64_t)dev_id_rr1 << 16) + (dev_id_rr2 >> 16); + target_config->pid_random = !!(slv_status1 & SLV_STATUS1_VEN_TM); + target_config->bcr = dev_id_rr2 >> 8; + target_config->dcr = dev_id_rr2 & 0xFF; + /* Version 1p7 supports reading MRL/MWL */ + if (REV_ID_REV(data->hw_cfg.rev_id) >= REV_ID_VERSION(1, 7)) { + target_config->max_read_len = + SLV_STATUS2_MRL(sys_read32(dev_config->base + SLV_STATUS2)); + target_config->max_write_len = + SLV_STATUS3_MWL(sys_read32(dev_config->base + SLV_STATUS3)); + } else { + target_config->max_read_len = 0; + target_config->max_write_len = 0; + } + target_config->supported_hdr = data->common.ctrl_config.supported_hdr; + } else { + return -EINVAL; } - (void)memcpy(config, &data->common.ctrl_config, sizeof(data->common.ctrl_config)); - -out_configure: - return ret; + return 0; } static int cdns_i3c_target_tx_ddr_write(const struct device *dev, uint8_t *buf, uint16_t len) @@ -3067,6 +3279,31 @@ static int cdns_i3c_i2c_api_transfer(const struct device *dev, struct i2c_msg *m return ret; } +/** + * ACK or NACK Controller Handoffs + * + * Reads the LVR of all I2C devices and returns the I3C bus + * Mode + * + * @param dev Pointer to device driver instance. + * @param accept True to accept controller handoffs, False to decline + * + * @return @see i3c_target_controller_handoff + */ +static int cdns_i3c_target_controller_handoff(const struct device *dev, bool accept) +{ + const struct cdns_i3c_config *config = dev->config; + uint32_t ctrl = sys_read32(config->base + CTRL); + + if (accept) { + sys_write32(ctrl | CTRL_MST_ACK, config->base + CTRL); + } else { + sys_write32(ctrl & ~CTRL_MST_ACK, config->base + CTRL); + } + + return 0; +} + /** * Determine I3C bus mode from the i2c devices on the bus * @@ -3129,6 +3366,89 @@ static uint8_t cdns_i3c_sda_data_hold(const struct device *dev) return (THD_DELAY_MAX - thd_delay); } +static void i3c_cdns_deftgts_work_fn(struct k_work *work) +{ + const struct cdns_i3c_config *config; + struct cdns_i3c_data *data; + const struct device *dev; + uint32_t devs; + uint8_t count; + uint8_t n = 0; + + data = CONTAINER_OF(work, struct cdns_i3c_data, deftgts_work); + dev = data->dev; + config = dev->config; + data = dev->data; + + devs = sys_read32(config->base + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK; + data->free_rr_slots = GENMASK(data->max_devs, 1) & ~devs; + + /* + * count the number of ones in devs, The IP will 'skip' writing it self to the RR if + * it was in DEFTGTS. Also, if the IP never had a DA, then the deftgts interrupt will + * never fire. Subtract 1 as the active controller is not included in `count`. + */ + count = POPCOUNT(devs) - 1; + + /* Free memory if it was previously allocated */ + if (data->common.deftgts) { + free(data->common.deftgts); + data->common.deftgts = NULL; + } + + /* Allocate memory for deftgts */ + data->common.deftgts = + malloc(sizeof(uint8_t) + sizeof(struct i3c_ccc_deftgts_active_controller) + + (count * sizeof(struct i3c_ccc_deftgts_target))); + if (!data->common.deftgts) { + LOG_ERR("%s: Failed to allocate memory for DEFTGTS", dev->name); + return; + } + + data->common.deftgts->count = count; + + for (uint8_t i = find_lsb_set(devs); i <= find_msb_set(devs); i++) { + uint8_t rr_idx = i - 1; + + if (devs & BIT(rr_idx)) { + /* Read RRx registers */ + uint32_t dev_id_rr0 = sys_read32(config->base + DEV_ID_RR0(rr_idx)); + uint32_t dev_id_rr2 = sys_read32(config->base + DEV_ID_RR2(rr_idx)); + + uint8_t addr = (dev_id_rr0 & 0xFE) >> 1; + uint8_t bcr = dev_id_rr2 >> 8; + uint8_t dcr_lvr = dev_id_rr2 & 0xFF; + bool is_i3c = !!(dev_id_rr0 & DEV_ID_RR0_IS_I3C); + + + /* RR IDX 1 should always be expected to be the AC */ + if (rr_idx == 1) { + data->common.deftgts->active_controller.addr = addr; + data->common.deftgts->active_controller.dcr = dcr_lvr; + data->common.deftgts->active_controller.bcr = bcr; + data->common.deftgts->active_controller.static_addr = 0; + } else if (is_i3c) { + data->common.deftgts->targets[n].addr = addr; + data->common.deftgts->targets[n].dcr = dcr_lvr; + data->common.deftgts->targets[n].bcr = bcr; + data->common.deftgts->targets[n].static_addr = 0; + n++; + } else { + data->common.deftgts->targets[n].addr = 0; + data->common.deftgts->targets[n].lvr = dcr_lvr; + data->common.deftgts->targets[n].bcr = 0; + data->common.deftgts->targets[n].static_addr = addr; + n++; + } + } + } + data->common.deftgts_refreshed = true; + LOG_HEXDUMP_DBG((uint8_t *)data->common.deftgts, + sizeof(uint8_t) + sizeof(struct i3c_ccc_deftgts_active_controller) + + (data->common.deftgts->count * sizeof(struct i3c_ccc_deftgts_target)), + "DEFTGTS Received"); +} + /** * @brief Initialize the hardware. * @@ -3140,6 +3460,8 @@ static int cdns_i3c_bus_init(const struct device *dev) const struct cdns_i3c_config *config = dev->config; struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; + data->dev = dev; + cdns_i3c_read_hw_cfg(dev); /* Clear all retaining regs */ @@ -3164,7 +3486,12 @@ static int cdns_i3c_bus_init(const struct device *dev) } k_mutex_init(&data->bus_lock); k_sem_init(&data->xfer.complete, 0, 1); + k_sem_init(&data->ch_complete, 0, 1); + k_work_init(&data->deftgts_work, i3c_cdns_deftgts_work_fn); +#ifdef CONFIG_I3C_USE_IBI k_sem_init(&data->ibi_hj_complete, 0, 1); + k_sem_init(&data->ibi_cr_complete, 0, 1); +#endif cdns_i3c_interrupts_disable(config); cdns_i3c_interrupts_clear(config); @@ -3204,9 +3531,8 @@ static int cdns_i3c_bus_init(const struct device *dev) * * Set the I3C Bus Mode based on the LVR of the I2C devices */ - uint32_t ctrl = CTRL_HJ_DISEC | CTRL_MCS_EN | (CTRL_BUS_MODE_MASK & cdns_mode); - /* Disable Controllership requests as it is not supported yet by the driver */ - ctrl &= ~CTRL_MST_ACK; + uint32_t ctrl = + CTRL_HJ_DISEC | CTRL_MCS_EN | CTRL_MST_ACK | (CTRL_BUS_MODE_MASK & cdns_mode); /* * Cadence I3C release r104v1p0 and above support configuration of the sda data hold time @@ -3231,8 +3557,8 @@ static int cdns_i3c_bus_init(const struct device *dev) sys_write32(CTRL_DEV_EN | ctrl, config->base + CTRL); /* Set fifo thresholds. */ - sys_write32(CMD_THR(I3C_CMDD_THR) | IBI_THR(I3C_IBID_THR) | CMDR_THR(I3C_CMDR_THR) | - IBIR_THR(config->ibid_thr), + sys_write32(CMD_THR(I3C_CMDD_THR) | IBI_THR(config->ibid_thr) | CMDR_THR(I3C_CMDR_THR) | + IBIR_THR(I3C_IBIR_THR), config->base + CMD_IBI_THR_CTRL); /* Set TX/RX interrupt thresholds. */ @@ -3248,13 +3574,14 @@ static int cdns_i3c_bus_init(const struct device *dev) /* enable target interrupts */ sys_write32(SLV_INT_DA_UPD | SLV_INT_SDR_RD_COMP | SLV_INT_SDR_WR_COMP | SLV_INT_SDR_RX_THR | SLV_INT_SDR_TX_THR | SLV_INT_SDR_RX_UNF | - SLV_INT_SDR_TX_OVF | SLV_INT_HJ_DONE | SLV_INT_DDR_WR_COMP | - SLV_INT_DDR_RD_COMP | SLV_INT_DDR_RX_THR | SLV_INT_DDR_TX_THR, + SLV_INT_SDR_TX_OVF | SLV_INT_HJ_DONE | SLV_INT_MR_DONE | + SLV_INT_DEFSLVS | SLV_INT_DDR_WR_COMP | SLV_INT_DDR_RD_COMP | + SLV_INT_DDR_RX_THR | SLV_INT_DDR_TX_THR, config->base + SLV_IER); - /* Enable IBI interrupts. */ - sys_write32(MST_INT_IBIR_THR | MST_INT_RX_UNF | MST_INT_HALTED | MST_INT_TX_OVF | - MST_INT_IBIR_OVF | MST_INT_IBID_THR, + /* Enable controller interrupts. */ + sys_write32(MST_INT_IBIR_THR | MST_INT_RX_UNF | MST_INT_HALTED | MST_INT_MR_DONE | + MST_INT_TX_OVF | MST_INT_IBIR_OVF | MST_INT_IBID_THR, config->base + MST_IER); int ret = i3c_addr_slots_init(dev); @@ -3263,11 +3590,10 @@ static int cdns_i3c_bus_init(const struct device *dev) return ret; } - /* Program retaining regs. */ - cdns_i3c_program_controller_retaining_reg(dev); - /* only primary controllers are responsible for initializing the bus */ if (!ctrl_config->is_secondary) { + /* Program retaining regs. */ + cdns_i3c_program_controller_retaining_reg(dev); /* Sleep to wait for bus idle. */ k_busy_wait(201); /* Perform bus initialization */ @@ -3281,9 +3607,12 @@ static int cdns_i3c_bus_init(const struct device *dev) return 0; } -static struct i3c_driver_api api = { +static DEVICE_API(i3c, api) = { .i2c_api.configure = cdns_i3c_i2c_api_configure, .i2c_api.transfer = cdns_i3c_i2c_api_transfer, +#ifdef CONFIG_I2C_RTIO + .i2c_api.iodev_submit = i2c_iodev_submit_fallback, +#endif .configure = cdns_i3c_configure, .config_get = cdns_i3c_config_get, @@ -3304,12 +3633,18 @@ static struct i3c_driver_api api = { .target_tx_write = cdns_i3c_target_tx_write, .target_register = cdns_i3c_target_register, .target_unregister = cdns_i3c_target_unregister, + .target_controller_handoff = cdns_i3c_target_controller_handoff, #ifdef CONFIG_I3C_USE_IBI + .ibi_hj_response = cdns_i3c_ibi_hj_response, .ibi_enable = cdns_i3c_controller_ibi_enable, .ibi_disable = cdns_i3c_controller_ibi_disable, .ibi_raise = cdns_i3c_target_ibi_raise, #endif + +#ifdef CONFIG_I3C_RTIO + .iodev_submit = i3c_iodev_submit_fallback, +#endif }; #define CADENCE_I3C_INSTANTIATE(n) \ diff --git a/drivers/i3c/i3c_common.c b/drivers/i3c/i3c_common.c index 9e3783876b848..70b7ebdf9d4ff 100644 --- a/drivers/i3c/i3c_common.c +++ b/drivers/i3c/i3c_common.c @@ -216,6 +216,24 @@ struct i3c_device_desc *i3c_dev_list_i3c_addr_find(const struct device *dev, return ret; } +struct i3c_device_desc *i3c_dev_list_i3c_static_addr_find(const struct device *dev, + uint8_t addr) +{ + struct i3c_device_desc *ret = NULL; + struct i3c_device_desc *desc; + + __ASSERT_NO_MSG(dev != NULL); + + I3C_BUS_FOR_EACH_I3CDEV(dev, desc) { + if (desc->static_addr == addr) { + ret = desc; + break; + } + } + + return ret; +} + struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(const struct device *dev, uint16_t addr) { @@ -318,6 +336,11 @@ int i3c_detach_i3c_device(struct i3c_device_desc *target) i3c_addr_slots_mark_free(&data->attached_dev.addr_slots, target->dynamic_addr ? target->dynamic_addr : target->static_addr); + /* if it was from allocated memory, free it */ + if (i3c_device_desc_in_pool(target)) { + i3c_device_desc_free(target); + } + return status; } @@ -370,9 +393,171 @@ int i3c_detach_i2c_device(struct i3c_i2c_device_desc *target) i3c_addr_slots_mark_free(&data->attached_dev.addr_slots, target->addr); + /* if it was from allocated memory, free it */ + if (i3c_i2c_device_desc_in_pool(target)) { + i3c_i2c_device_desc_free(target); + } + return status; } +int i3c_sec_get_basic_info(const struct device *dev, + uint8_t dynamic_addr, uint8_t static_addr, uint8_t bcr, uint8_t dcr) +{ + struct i3c_ccc_getpid getpid; + struct i3c_device_desc temp_desc; + struct i3c_device_desc *desc; + struct i3c_device_id id; + const struct i3c_driver_config *config = dev->config; + int ret; + + *(const struct device **)&temp_desc.bus = dev; + temp_desc.dynamic_addr = dynamic_addr; + temp_desc.bcr = bcr; + temp_desc.dcr = dcr; + /* attach it first with a temperary value so we can at least get the pid */ + ret = i3c_attach_i3c_device(&temp_desc); + if (ret != 0) { + return ret; + } + + /* First try to look up if this is a known device in the list by PID */ + ret = i3c_ccc_do_getpid(&temp_desc, &getpid); + if (ret != 0) { + return ret; + } + + *(uint64_t *)&id = sys_get_be48(getpid.pid); + + /* try to see if we already have a device statically allocated */ + desc = i3c_dev_list_find(&config->dev_list, &id); + if (!desc) { + /* device was not found so allocate a descriptor */ + desc = i3c_device_desc_alloc(); + if (!desc) { + return -ENOMEM; + } + *(uint64_t *)&desc->pid = id.pid; + *(uint16_t *)&temp_desc.static_addr = (uint16_t)static_addr; + } + desc->dynamic_addr = dynamic_addr; + desc->bcr = bcr; + desc->dcr = dcr; + + /* Detach that temporary device */ + ret = i3c_detach_i3c_device(&temp_desc); + if (ret != 0) { + return ret; + } + ret = i3c_attach_i3c_device(desc); + if (ret != 0) { + return ret; + } + + /* Skip reading BCR and DCR as they came from DEFTGTS */ + ret = i3c_device_adv_info_get(desc); + + return ret; +} + +int i3c_sec_i2c_attach(const struct device *dev, uint8_t static_addr, uint8_t lvr) +{ + struct i3c_i2c_device_desc *i2c_desc; + int ret; + + /* try to see if we already have a device statically allocated */ + i2c_desc = i3c_dev_list_i2c_addr_find(dev, (uint16_t)static_addr); + if (!i2c_desc) { + /* device was not found so allocate a descriptor */ + i2c_desc = i3c_i2c_device_desc_alloc(); + if (!i2c_desc) { + return -ENOMEM; + } + *(const struct device **)&i2c_desc->bus = dev; + *(uint16_t *)&i2c_desc->addr = (uint16_t)static_addr; + *(uint8_t *)&i2c_desc->lvr = lvr; + } + + ret = i3c_attach_i2c_device(i2c_desc); + return ret; +} + +static void i3c_sec_bus_reset(const struct device *dev) +{ + struct i3c_device_desc *i3c_desc; + struct i3c_i2c_device_desc *i3c_i2c_desc; + + I3C_BUS_FOR_EACH_I3CDEV(dev, i3c_desc) { + i3c_detach_i3c_device(i3c_desc); + } + + I3C_BUS_FOR_EACH_I2CDEV(dev, i3c_i2c_desc) { + i3c_detach_i2c_device(i3c_i2c_desc); + } +} +#ifdef CONFIG_I3C_USE_IBI +/* call this from a workq after the interrupt from a controller */ +void i3c_sec_handoffed(struct k_work *work) +{ + struct i3c_ibi_work *ibi_node = CONTAINER_OF(work, struct i3c_ibi_work, work); + const struct device *dev = ibi_node->controller; + struct i3c_driver_data *data = (struct i3c_driver_data *)dev->data; + struct i3c_ccc_deftgts *deftgts = data->deftgts; + struct i3c_config_target config_target; + uint8_t n, cur_dyn_addr; + int ret; + + if (!deftgts) { + LOG_ERR("Did not receive DEFTGTS before Handoff"); + return; + } + + if (!data->deftgts_refreshed) { + LOG_DBG("Already processed DEFTGTS from previous handoff"); + return; + } + + /* Forget all devices as another controller made changes */ + i3c_sec_bus_reset(dev); + + /* + * Retrieve the active controller information + */ + ret = i3c_config_get(dev, I3C_CONFIG_TARGET, &config_target); + if (ret != 0) { + LOG_ERR("Failed to retrieve active controller info"); + return; + } + + cur_dyn_addr = config_target.dynamic_addr; + + /* Attach the previous AC */ + ret = i3c_sec_get_basic_info(dev, deftgts->active_controller.addr, + deftgts->active_controller.static_addr, + deftgts->active_controller.bcr, + deftgts->active_controller.dcr); + + /* Attach all Targets */ + for (n = 0; n < deftgts->count; n++) { + if (deftgts->targets[n].addr != 0) { + /* Must be an I3C device and skip itself */ + if (deftgts->targets[n].addr != cur_dyn_addr) { + ret = i3c_sec_get_basic_info(dev, deftgts->targets[n].addr, + deftgts->targets[n].static_addr, deftgts->targets[n].bcr, + deftgts->targets[n].dcr); + } + } else { + /* Must be an I2C device */ + ret = i3c_sec_i2c_attach(dev, deftgts->targets[n].static_addr, + deftgts->targets[n].lvr); + } + } + + /* Set false, so the next handoff doesn't retrigger regathering info */ + data->deftgts_refreshed = false; +} +#endif + int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots, const struct i3c_dev_list *dev_list, uint64_t pid, bool must_match, @@ -388,6 +573,10 @@ int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots, const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid); desc = i3c_dev_list_find(dev_list, &i3c_id); + /* If a device was not found, try to allocate a descriptor */ + if (desc == NULL) { + desc = i3c_device_desc_alloc(); + } if (must_match && (desc == NULL)) { /* * No device descriptor matching incoming PID and @@ -450,40 +639,156 @@ int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots, return ret; } -int i3c_device_basic_info_get(struct i3c_device_desc *target) +uint8_t i3c_odd_parity(uint8_t p) +{ + p ^= p >> 4; + p &= 0xf; + return (0x9669 >> p) & 1; +} + +int i3c_device_controller_handoff(const struct i3c_device_desc *target, bool requested) { int ret; - uint8_t tmp_bcr; + union i3c_ccc_getstatus status = {0}; + struct i3c_ccc_events i3c_events; + struct i3c_ccc_address handoff_address; - struct i3c_ccc_getbcr bcr = {0}; - struct i3c_ccc_getdcr dcr = {0}; - struct i3c_ccc_mrl mrl = {0}; - struct i3c_ccc_mwl mwl = {0}; - union i3c_ccc_getcaps caps = {0}; - union i3c_ccc_getmxds mxds = {0}; + /* + * If the Active Controller intends to pass the Controller Role to a selected Secondary + * Controller that did not send a Controller Role Request, then the Active Controller should + * verify that the selected Secondary Controller is active and ready to respond to + * additional commands + */ + if (!requested) { + ret = i3c_ccc_do_getstatus_fmt1(target, &status); + if (ret != 0) { + return ret; + } + + if (I3C_CCC_GETSTATUS_ACTIVITY_MODE(status.fmt1.status) == + I3C_CCC_GETSTATUS_ACTIVITY_MODE_NCH) { + return -EBUSY; + } + } + + /* + * The Active Controller needs to disable Hot-Joins, Target Interrupt Requests, and other + * Bus events that could interfere with the Handoff, then it sends the appropriate + * Broadcast to disable those events before the Handoff. Once the Handoff is complete, the + * new Active Controller should re-enable events that are disabled in this step. + */ + i3c_events.events = I3C_CCC_EVT_ALL; + ret = i3c_ccc_do_events_all_set(target->bus, false, &i3c_events); + if (ret != 0) { + return ret; + } + + /** TODO: reconfigure MLANE if needed */ + + /* + * If the Active Controller knows that the selected Secondary Controller must be put into a + * different Activity State before Handoff, then the Active Controller shall send the + * appropriate Broadcast or Direct CCCs to put the Bus (or selected Devices) into a + * different Activity State + */ + if (target->crhdly1 & I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE) { + ret = i3c_ccc_do_entas( + target, I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE(target->crhdly1)); + if (ret != 0) { + return ret; + } + } + + if ((target->getcaps.getcap3 & I3C_CCC_GETCAPS3_GETSTATUS_DEFINING_BYTE_SUPPORT) && + (target->crcaps.crcaps2 & I3C_CCC_GETCAPS_CRCAPS2_DEEP_SLEEP_CAPABLE)) { + ret = i3c_ccc_do_getstatus_fmt2(target, &status, GETSTATUS_FORMAT_2_PRECR); + if (ret != 0) { + return ret; + } + + /* + * If the Active Controller determines that the indicated Secondary Controller has + * been in a “deep sleep” state and may need to be re-synchronized with the most + * current list of I3C Targets and Group Addresses, then the Active Controller + * should send CCC DEFTGTS and DEFGRPA + */ + if (status.fmt2.precr & I3C_CCC_GETSTATUS_PRECR_DEEP_SLEEP_DETECTED) { + ret = i3c_bus_deftgts(target->bus); + if (ret != 0) { + return ret; + } + /* TODO: broadcast DEFGRPA when group address support comes */ + + /* Check CRCAPS if the device needs additional time to process */ + if (target->crcaps.crcaps2 & + I3C_CCC_GETCAPS_CRCAPS2_DELAYED_CONTROLLER_HANDOFF) { + /* + * Afterwards, the Active Controller should poll the Secondary + * Controller to ensure that it has successfully processed this data + * and indicates that it is ready to accept the Controller Role + */ + do { + ret = i3c_ccc_do_getstatus_fmt2(target, &status, + GETSTATUS_FORMAT_2_PRECR); + if (ret != 0) { + return ret; + } + } while (!(status.fmt2.precr & + I3C_CCC_GETSTATUS_PRECR_HANDOFF_DELAY_NACK)); + } + } + } /* - * Since some CCC functions requires BCR to function - * correctly, we save the BCR here and update the BCR - * in the descriptor. If any following operations fails, - * we can restore the BCR. + * After the Active Controller has prepared for Handoff, the Active Controller shall + * then issue a GETACCCR CCC */ - tmp_bcr = target->bcr; + ret = i3c_ccc_do_getacccr(target, &handoff_address); + if (ret != 0) { + return ret; + } + + /* Verify Odd Parity and Correct Dynamic Address Reply */ + if ((i3c_odd_parity(handoff_address.addr >> 1) != (handoff_address.addr & BIT(0))) || + (handoff_address.addr >> 1 != target->dynamic_addr)) { + return -EIO; + } + + return ret; +} + +int i3c_device_basic_info_get(struct i3c_device_desc *target) +{ + int ret; + struct i3c_ccc_getbcr bcr = {0}; + struct i3c_ccc_getdcr dcr = {0}; /* GETBCR */ ret = i3c_ccc_do_getbcr(target, &bcr); if (ret != 0) { - goto out; + return ret; } - target->bcr = bcr.bcr; - /* GETDCR */ ret = i3c_ccc_do_getdcr(target, &dcr); if (ret != 0) { - goto out; + return ret; } + target->bcr = bcr.bcr; + target->dcr = dcr.dcr; + + return 0; +} + +int i3c_device_adv_info_get(struct i3c_device_desc *target) +{ + struct i3c_ccc_mrl mrl = {0}; + struct i3c_ccc_mwl mwl = {0}; + union i3c_ccc_getcaps caps = {0}; + union i3c_ccc_getmxds mxds = {0}; + int ret; + /* GETMRL */ if (i3c_ccc_do_getmrl(target, &mrl) != 0) { /* GETMRL may be optionally supported if no settable limit */ @@ -505,36 +810,44 @@ int i3c_device_basic_info_get(struct i3c_device_desc *target) * set, then it is expected for GETCAPS to always be supported. Otherwise, then it's a I3C * v1.0 device without any HDR modes so do not treat as an error if no valid response. */ - if (ret == 0) { - memcpy(&target->getcaps, &caps, sizeof(target->getcaps)); - } else if ((ret != 0) && (target->bcr & I3C_BCR_ADV_CAPABILITIES)) { - goto out; + if ((ret != 0) && (target->bcr & I3C_BCR_ADV_CAPABILITIES)) { + return ret; } else { ret = 0; } + /* CRCAPS */ + if ((target->getcaps.getcap3 & I3C_CCC_GETCAPS3_GETCAPS_DEFINING_BYTE_SUPPORT) && + (i3c_device_is_controller_capable(target))) { + ret = i3c_ccc_do_getcaps_fmt2(target, &caps, GETCAPS_FORMAT_2_CRCAPS); + if (ret != 0) { + return ret; + } + } + /* GETMXDS */ if (target->bcr & I3C_BCR_MAX_DATA_SPEED_LIMIT) { ret = i3c_ccc_do_getmxds_fmt2(target, &mxds); if (ret != 0) { - goto out; + return ret; } - target->data_speed.maxrd = mxds.fmt2.maxrd; - target->data_speed.maxwr = mxds.fmt2.maxwr; - target->data_speed.max_read_turnaround = sys_get_le24(mxds.fmt2.maxrdturn); + /* Get CRHDLY if supported */ + if ((target->data_speed.maxwr & I3C_CCC_GETMXDS_MAXWR_DEFINING_BYTE_SUPPORT) && + (i3c_device_is_controller_capable(target))) { + ret = i3c_ccc_do_getmxds_fmt3(target, &mxds, GETMXDS_FORMAT_3_CRHDLY); + if (ret != 0) { + return ret; + } + + target->crhdly1 = mxds.fmt3.crhdly1; + } } - target->dcr = dcr.dcr; target->data_length.mrl = mrl.len; target->data_length.mwl = mwl.len; target->data_length.max_ibi = mrl.ibi_len; -out: - if (ret != 0) { - /* Restore BCR is any CCC fails. */ - target->bcr = tmp_bcr; - } return ret; } @@ -824,9 +1137,14 @@ int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list) continue; } - ret = i3c_device_basic_info_get(desc); + /* + * If static address is 0, then it is assumed that BCR + * and DCR were already read through ENTDAA + */ + ret = (desc->static_addr == 0) ? i3c_device_adv_info_get(desc) + : i3c_device_info_get(desc); if (ret != 0) { - LOG_ERR("Error getting basic device info for 0x%02x", + LOG_ERR("Error getting device info for 0x%02x", desc->static_addr); } else { LOG_DBG("Target 0x%02x, BCR 0x%02x, DCR 0x%02x, MRL %d, MWL %d, IBI %d", @@ -846,8 +1164,6 @@ int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *dev_list) /* * Only re-enable Hot-Join from targets. * Target interrupts will be enabled when IBI is enabled. - * And transferring controller role is not supported so not need to - * enable the event. */ i3c_events.events = I3C_CCC_EVT_HJ; ret = i3c_ccc_do_events_all_set(dev, true, &i3c_events); diff --git a/drivers/i3c/i3c_dw.c b/drivers/i3c/i3c_dw.c new file mode 100644 index 0000000000000..25168e9dd4f3b --- /dev/null +++ b/drivers/i3c/i3c_dw.c @@ -0,0 +1,2376 @@ +/* + * Copyright (C) 2020 Samsung Electronics Co., Ltd. + * Copyright (C) 2023 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define NANO_SEC 1000000000ULL +#define BYTES_PER_DWORD 4 + +LOG_MODULE_REGISTER(i3c_dw, CONFIG_I3C_DW_LOG_LEVEL); + +#define DEVICE_CTRL 0x0 +#define DEV_CTRL_ENABLE BIT(31) +#define DEV_CTRL_RESUME BIT(30) +#define DEV_CTRL_HOT_JOIN_NACK BIT(8) +#define DEV_CTRL_I2C_SLAVE_PRESENT BIT(7) +#define DEV_CTRL_IBA_INCLUDE BIT(0) + +#define DEVICE_ADDR 0x4 +#define DEVICE_ADDR_DYNAMIC_ADDR_VALID BIT(31) +#define DEVICE_ADDR_DYNAMIC(x) (((x) << 16) & GENMASK(22, 16)) +#define DEVICE_ADDR_STATIC_ADDR_VALID BIT(15) +#define DEVICE_ADDR_STATIC_MASK GENMASK(6, 0) +#define DEVICE_ADDR_STATIC(x) ((x) & DEVICE_ADDR_STATIC_MASK) + +#define HW_CAPABILITY 0x8 +#define HW_CAPABILITY_SLV_IBI_CAP BIT(19) +#define HW_CAPABILITY_SLV_HJ_CAP BIT(18) +#define HW_CAPABILITY_HDR_TS_EN BIT(4) +#define HW_CAPABILITY_HDR_DDR_EN BIT(3) +#define HW_CAPABILITY_DEVICE_ROLE_CONFIG_MASK GENMASK(2, 0) + +#define COMMAND_QUEUE_PORT 0xc +#define COMMAND_PORT_TOC BIT(30) +#define COMMAND_PORT_READ_TRANSFER BIT(28) +#define COMMAND_PORT_SDAP BIT(27) +#define COMMAND_PORT_ROC BIT(26) +#define COMMAND_PORT_DBP BIT(25) +#define COMMAND_PORT_SPEED(x) (((x) << 21) & GENMASK(23, 21)) +#define COMMAND_PORT_SPEED_I2C_FM 0 +#define COMMAND_PORT_SPEED_I2C_FMP 1 +#define COMMAND_PORT_SPEED_I3C_DDR 6 +#define COMMAND_PORT_SPEED_I3C_TS 7 +#define COMMAND_PORT_DEV_INDEX(x) (((x) << 16) & GENMASK(20, 16)) +#define COMMAND_PORT_CP BIT(15) +#define COMMAND_PORT_CMD(x) (((x) << 7) & GENMASK(14, 7)) +#define COMMAND_PORT_TID(x) (((x) << 3) & GENMASK(6, 3)) + +#define COMMAND_PORT_ARG_DATA_LEN(x) (((x) << 16) & GENMASK(31, 16)) +#define COMMAND_PORT_ARG_DB(x) (((x) << 8) & GENMASK(15, 8)) +#define COMMAND_PORT_ARG_DATA_LEN_MAX 65536 +#define COMMAND_PORT_TRANSFER_ARG 0x01 + +#define COMMAND_PORT_SDA_DATA_BYTE_3(x) (((x) << 24) & GENMASK(31, 24)) +#define COMMAND_PORT_SDA_DATA_BYTE_2(x) (((x) << 16) & GENMASK(23, 16)) +#define COMMAND_PORT_SDA_DATA_BYTE_1(x) (((x) << 8) & GENMASK(15, 8)) +#define COMMAND_PORT_SDA_BYTE_STRB_3 BIT(5) +#define COMMAND_PORT_SDA_BYTE_STRB_2 BIT(4) +#define COMMAND_PORT_SDA_BYTE_STRB_1 BIT(3) +#define COMMAND_PORT_SHORT_DATA_ARG 0x02 + +#define COMMAND_PORT_DEV_COUNT(x) (((x) << 21) & GENMASK(25, 21)) +#define COMMAND_PORT_ADDR_ASSGN_CMD 0x03 + +#define RESPONSE_QUEUE_PORT 0x10 +#define RESPONSE_PORT_ERR_STATUS(x) (((x) & GENMASK(31, 28)) >> 28) +#define RESPONSE_NO_ERROR 0 +#define RESPONSE_ERROR_CRC 1 +#define RESPONSE_ERROR_PARITY 2 +#define RESPONSE_ERROR_FRAME 3 +#define RESPONSE_ERROR_IBA_NACK 4 +#define RESPONSE_ERROR_ADDRESS_NACK 5 +#define RESPONSE_ERROR_OVER_UNDER_FLOW 6 +#define RESPONSE_ERROR_TRANSF_ABORT 8 +#define RESPONSE_ERROR_I2C_W_NACK_ERR 9 +#define RESPONSE_PORT_TID(x) (((x) & GENMASK(27, 24)) >> 24) +#define RESPONSE_PORT_DATA_LEN(x) ((x) & GENMASK(15, 0)) + +#define RX_TX_DATA_PORT 0x14 +#define IBI_QUEUE_STATUS 0x18 +#define IBI_QUEUE_STATUS_IBI_STS(x) (((x) & GENMASK(31, 28)) >> 28) +#define IBI_QUEUE_STATUS_IBI_ID(x) (((x) & GENMASK(15, 8)) >> 8) +#define IBI_QUEUE_STATUS_DATA_LEN(x) ((x) & GENMASK(7, 0)) +#define IBI_QUEUE_IBI_ADDR(x) (IBI_QUEUE_STATUS_IBI_ID(x) >> 1) +#define IBI_QUEUE_IBI_RNW(x) (IBI_QUEUE_STATUS_IBI_ID(x) & BIT(0)) +#define IBI_TYPE_MR(x) \ + ((IBI_QUEUE_IBI_ADDR(x) != I3C_HOT_JOIN_ADDR) && !IBI_QUEUE_IBI_RNW(x)) +#define IBI_TYPE_HJ(x) \ + ((IBI_QUEUE_IBI_ADDR(x) == I3C_HOT_JOIN_ADDR) && !IBI_QUEUE_IBI_RNW(x)) +#define IBI_TYPE_SIRQ(x) \ + ((IBI_QUEUE_IBI_ADDR(x) != I3C_HOT_JOIN_ADDR) && IBI_QUEUE_IBI_RNW(x)) + +#define QUEUE_THLD_CTRL 0x1c +#define QUEUE_THLD_CTRL_IBI_STS_MASK GENMASK(31, 24) +#define QUEUE_THLD_CTRL_RESP_BUF_MASK GENMASK(15, 8) +#define QUEUE_THLD_CTRL_RESP_BUF(x) (((x) - 1) << 8) + +#define DATA_BUFFER_THLD_CTRL 0x20 +#define DATA_BUFFER_THLD_CTRL_RX_BUF GENMASK(11, 8) + +#define IBI_QUEUE_CTRL 0x24 +#define IBI_MR_REQ_REJECT 0x2C +#define IBI_SIR_REQ_REJECT 0x30 +#define IBI_SIR_REQ_ID(x) ((((x) & GENMASK(6, 5)) >> 5) + ((x) & GENMASK(4, 0))) +#define IBI_REQ_REJECT_ALL GENMASK(31, 0) + +#define RESET_CTRL 0x34 +#define RESET_CTRL_IBI_QUEUE BIT(5) +#define RESET_CTRL_RX_FIFO BIT(4) +#define RESET_CTRL_TX_FIFO BIT(3) +#define RESET_CTRL_RESP_QUEUE BIT(2) +#define RESET_CTRL_CMD_QUEUE BIT(1) +#define RESET_CTRL_SOFT BIT(0) +#define RESET_CTRL_ALL \ + (RESET_CTRL_IBI_QUEUE | RESET_CTRL_RX_FIFO | RESET_CTRL_TX_FIFO | RESET_CTRL_RESP_QUEUE | \ + RESET_CTRL_CMD_QUEUE | RESET_CTRL_SOFT) + +#define SLV_EVENT_STATUS 0x38 +#define SLV_EVENT_STATUS_HJ_EN BIT(3) +#define SLV_EVENT_STATUS_MR_EN BIT(1) +#define SLV_EVENT_STATUS_SIR_EN BIT(0) + +#define INTR_STATUS 0x3c +#define INTR_STATUS_EN 0x40 +#define INTR_SIGNAL_EN 0x44 +#define INTR_FORCE 0x48 +#define INTR_BUSOWNER_UPDATE_STAT BIT(13) +#define INTR_IBI_UPDATED_STAT BIT(12) +#define INTR_READ_REQ_RECV_STAT BIT(11) +#define INTR_DEFSLV_STAT BIT(10) +#define INTR_TRANSFER_ERR_STAT BIT(9) +#define INTR_DYN_ADDR_ASSGN_STAT BIT(8) +#define INTR_CCC_UPDATED_STAT BIT(6) +#define INTR_TRANSFER_ABORT_STAT BIT(5) +#define INTR_RESP_READY_STAT BIT(4) +#define INTR_CMD_QUEUE_READY_STAT BIT(3) +#define INTR_IBI_THLD_STAT BIT(2) +#define INTR_RX_THLD_STAT BIT(1) +#define INTR_TX_THLD_STAT BIT(0) +#define INTR_ALL \ + (INTR_BUSOWNER_UPDATE_STAT | INTR_IBI_UPDATED_STAT | INTR_READ_REQ_RECV_STAT | \ + INTR_DEFSLV_STAT | INTR_TRANSFER_ERR_STAT | INTR_DYN_ADDR_ASSGN_STAT | \ + INTR_CCC_UPDATED_STAT | INTR_TRANSFER_ABORT_STAT | INTR_RESP_READY_STAT | \ + INTR_CMD_QUEUE_READY_STAT | INTR_IBI_THLD_STAT | INTR_TX_THLD_STAT | INTR_RX_THLD_STAT) + +#ifdef CONFIG_I3C_USE_IBI +#define INTR_MASTER_MASK (INTR_TRANSFER_ERR_STAT | INTR_RESP_READY_STAT | INTR_IBI_THLD_STAT) +#else +#define INTR_MASTER_MASK (INTR_TRANSFER_ERR_STAT | INTR_RESP_READY_STAT) +#endif +#define INTR_SLAVE_MASK \ + (INTR_TRANSFER_ERR_STAT | INTR_IBI_UPDATED_STAT | INTR_READ_REQ_RECV_STAT | \ + INTR_DYN_ADDR_ASSGN_STAT | INTR_RESP_READY_STAT) + +#define QUEUE_STATUS_LEVEL 0x4c +#define QUEUE_STATUS_IBI_STATUS_CNT(x) (((x) & GENMASK(28, 24)) >> 24) +#define QUEUE_STATUS_IBI_BUF_BLR(x) (((x) & GENMASK(23, 16)) >> 16) +#define QUEUE_STATUS_LEVEL_RESP(x) (((x) & GENMASK(15, 8)) >> 8) +#define QUEUE_STATUS_LEVEL_CMD(x) ((x) & GENMASK(7, 0)) + +#define DATA_BUFFER_STATUS_LEVEL 0x50 +#define DATA_BUFFER_STATUS_LEVEL_RX(x) (((x) & GENMASK(23, 16)) >> 16) +#define DATA_BUFFER_STATUS_LEVEL_TX(x) ((x) & GENMASK(7, 0)) + +#define PRESENT_STATE 0x54 +#define PRESENT_STATE_CURRENT_MASTER BIT(2) + +#define CCC_DEVICE_STATUS 0x58 +#define DEVICE_ADDR_TABLE_POINTER 0x5c +#define DEVICE_ADDR_TABLE_DEPTH(x) (((x) & GENMASK(31, 16)) >> 16) +#define DEVICE_ADDR_TABLE_ADDR(x) ((x) & GENMASK(15, 0)) + +#define DEV_CHAR_TABLE_POINTER 0x60 +#define DEVICE_CHAR_TABLE_ADDR(x) ((x) & GENMASK(11, 0)) +#define VENDOR_SPECIFIC_REG_POINTER 0x6c + +#define SLV_MIPI_ID_VALUE 0x70 +#define SLV_MIPI_ID_VALUE_SLV_MIPI_MFG_ID_MASK GENMASK(15, 1) +#define SLV_MIPI_ID_VALUE_SLV_MIPI_MFG_ID(x) ((x) & SLV_MIPI_ID_VALUE_SLV_MIPI_MFG_ID_MASK) +#define SLV_MIPI_ID_VALUE_SLV_PROV_ID_SEL BIT(0) + +#define SLV_PID_VALUE 0x74 + +#define SLV_CHAR_CTRL 0x78 +#define SLV_CHAR_CTRL_MAX_DATA_SPEED_LIMIT BIT(0) +#define SLV_CHAR_CTRL_IBI_REQUEST_CAPABLE BIT(1) +#define SLV_CHAR_CTRL_IBI_PAYLOAD BIT(2) +#define SLV_CHAR_CTRL_BCR_MASK GENMASK(7, 0) +#define SLV_CHAR_CTRL_BCR(x) ((x) & SLV_CHAR_CTRL_BCR_MASK) +#define SLV_CHAR_CTRL_DCR_MASK GENMASK(15, 8) +#define SLV_CHAR_CTRL_DCR(x) (((x) & SLV_CHAR_CTRL_DCR_MASK) >> 8) +#define SLV_CHAR_CTRL_HDR_CAP_MASK GENMASK(23, 16) +#define SLV_CHAR_CTRL_HDR_CAP(x) (((x) & SLV_CHAR_CTRL_HDR_CAP_MASK) >> 16) + +#define SLV_MAX_LEN 0x7c +#define SLV_MAX_LEN_MRL(x) (((x) & GENMASK(31, 16)) >> 16) +#define SLV_MAX_LEN_MWL(x) ((x) & GENMASK(15, 0)) + +#define MAX_READ_TURNAROUND 0x80 +#define MAX_READ_TURNAROUND_MXDX_MAX_RD_TURN(x) ((x) & GENMASK(23, 0)) + +#define MAX_DATA_SPEED 0x84 +#define SLV_DEBUG_STATUS 0x88 + +#define SLV_INTR_REQ 0x8c +#define SLV_INTR_REQ_SIR_DATA_LENGTH(x) (((x) << 16) & GENMASK(23, 16)) +#define SLV_INTR_REQ_MDB(x) (((x) << 8) & GENMASK(15, 8)) +#define SLV_INTR_REQ_IBI_STS(x) (((x) & GENMASK(9, 8)) >> 8) +#define SLV_INTR_REQ_IBI_STS_IBI_ACCEPT 0x01 +#define SLV_INTR_REQ_IBI_STS_IBI_NO_ATTEMPT 0x03 +#define SLV_INTR_REQ_TS BIT(4) +#define SLV_INTR_REQ_MR BIT(3) +#define SLV_INTR_REQ_SIR_CTRL(x) (((x) & GENMASK(2, 1)) >> 1) +#define SLV_INTR_REQ_SIR BIT(0) + +#define SLV_SIR_DATA 0x94 +#define SLV_SIR_DATA_BYTE3(x) (((x) << 24) & GENMASK(31, 24)) +#define SLV_SIR_DATA_BYTE2(x) (((x) << 16) & GENMASK(23, 16)) +#define SLV_SIR_DATA_BYTE1(x) (((x) << 8) & GENMASK(15, 8)) +#define SLV_SIR_DATA_BYTE0(x) ((x) & GENMASK(7, 0)) + +#define SLV_IBI_RESP 0x98 +#define SLV_IBI_RESP_DATA_LENGTH(x) (((x) & GENMASK(23, 8)) >> 8) +#define SLV_IBI_RESP_IBI_STS(x) ((x) & GENMASK(1, 0)) +#define SLV_IBI_RESP_IBI_STS_ACK 0x01 +#define SLV_IBI_RESP_IBI_STS_EARLY_TERMINATE 0x02 +#define SLV_IBI_RESP_IBI_STS_NACK 0x03 + +#define SLV_NACK_REQ 0x9c +#define SLV_NACK_REQ_NACK_REQ(x) ((x) & GENMASK(1, 0)) +#define SLV_NACK_REQ_NACK_REQ_ACK 0x00 +#define SLV_NACK_REQ_NACK_REQ_NACK 0x01 + +#define DEVICE_CTRL_EXTENDED 0xb0 +#define DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE(x) ((x) & GENMASK(1, 0)) +#define DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE_MASTER 0 +#define DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE_SLAVE 1 + +#define SCL_I3C_OD_TIMING 0xb4 +#define SCL_I3C_PP_TIMING 0xb8 +#define SCL_I3C_TIMING_HCNT(x) (((x) << 16) & GENMASK(23, 16)) +#define SCL_I3C_TIMING_LCNT(x) ((x) & GENMASK(7, 0)) +#define SCL_I3C_TIMING_CNT_MIN 5 +#define SCL_I3C_TIMING_CNT_MAX 255 + +#define SCL_I2C_FM_TIMING 0xbc +#define SCL_I2C_FM_TIMING_HCNT(x) (((x) << 16) & GENMASK(31, 16)) +#define SCL_I2C_FM_TIMING_LCNT(x) ((x) & GENMASK(15, 0)) + +#define SCL_I2C_FMP_TIMING 0xc0 +#define SCL_I2C_FMP_TIMING_HCNT(x) (((x) << 16) & GENMASK(23, 16)) +#define SCL_I2C_FMP_TIMING_LCNT(x) ((x) & GENMASK(15, 0)) + +#define SCL_EXT_LCNT_TIMING 0xc8 +#define SCL_EXT_LCNT_4(x) (((x) << 24) & GENMASK(31, 24)) +#define SCL_EXT_LCNT_3(x) (((x) << 16) & GENMASK(23, 16)) +#define SCL_EXT_LCNT_2(x) (((x) << 8) & GENMASK(15, 8)) +#define SCL_EXT_LCNT_1(x) ((x) & GENMASK(7, 0)) + +#define SCL_EXT_TERMN_LCNT_TIMING 0xcc + +#define SDA_HOLD_SWITCH_DLY_TIMING 0xd0 +#define SDA_HOLD_SWITCH_DLY_TIMING_SDA_TX_HOLD(x) (((x)&GENMASK(18, 16)) >> 16) +#define SDA_HOLD_SWITCH_DLY_TIMING_SDA_PP_OD_SWITCH_DLY(x) (((x)&GENMASK(10, 8)) >> 8) +#define SDA_HOLD_SWITCH_DLY_TIMING_SDA_OD_PP_SWITCH_DLY(x) ((x)&GENMASK(2, 0)) + +#define BUS_FREE_TIMING 0xd4 +/* Bus available time of 1us in ns */ +#define I3C_BUS_AVAILABLE_TIME_NS 1000U +#define BUS_I3C_MST_FREE(x) ((x) & GENMASK(15, 0)) +#define BUS_I3C_AVAIL_TIME(x) ((x << 16) & GENMASK(31, 16)) + +#define BUS_IDLE_TIMING 0xd8 +/* Bus Idle time of 1ms in ns */ +#define I3C_BUS_IDLE_TIME_NS 1000000U +#define BUS_I3C_IDLE_TIME(x) ((x) & GENMASK(19, 0)) + +#define I3C_VER_ID 0xe0 +#define I3C_VER_TYPE 0xe4 +#define EXTENDED_CAPABILITY 0xe8 +#define SLAVE_CONFIG 0xec + +#define QUEUE_SIZE_CAPABILITY 0xe8 +#define QUEUE_SIZE_CAPABILITY_IBI_BUF_DWORD_SIZE(x) (2 << (((x) & GENMASK(19, 16)) >> 16)) +#define QUEUE_SIZE_CAPABILITY_RESP_BUF_DWORD_SIZE(x) (2 << (((x) & GENMASK(15, 12)) >> 12)) +#define QUEUE_SIZE_CAPABILITY_CMD_BUF_DWORD_SIZE(x) (2 << (((x) & GENMASK(11, 8)) >> 8)) +#define QUEUE_SIZE_CAPABILITY_RX_BUF_DWORD_SIZE(x) (2 << (((x) & GENMASK(7, 4)) >> 4)) +#define QUEUE_SIZE_CAPABILITY_TX_BUF_DWORD_SIZE(x) (2 << ((x) & GENMASK(3, 0))) + +#define DEV_ADDR_TABLE_LEGACY_I2C_DEV BIT(31) +#define DEV_ADDR_TABLE_DYNAMIC_ADDR_MASK GENMASK(23, 16) +#define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) (((x) << 16) & GENMASK(23, 16)) +#define DEV_ADDR_TABLE_SIR_REJECT BIT(13) +#define DEV_ADDR_TABLE_IBI_WITH_DATA BIT(12) +#define DEV_ADDR_TABLE_STATIC_ADDR(x) ((x) & GENMASK(6, 0)) +#define DEV_ADDR_TABLE_LOC(start, idx) ((start) + ((idx) << 2)) + +#define DEV_CHAR_TABLE_LOC1(start, idx) ((start) + ((idx) << 4)) +#define DEV_CHAR_TABLE_MSB_PID(x) ((x) & GENMASK(31, 16)) +#define DEV_CHAR_TABLE_LSB_PID(x) ((x) & GENMASK(15, 0)) +#define DEV_CHAR_TABLE_LOC2(start, idx) ((DEV_CHAR_TABLE_LOC1(start, idx)) + 4) +#define DEV_CHAR_TABLE_LOC3(start, idx) ((DEV_CHAR_TABLE_LOC1(start, idx)) + 8) +#define DEV_CHAR_TABLE_DCR(x) ((x) & GENMASK(7, 0)) +#define DEV_CHAR_TABLE_BCR(x) (((x) & GENMASK(15, 8)) >> 8) + +#define I3C_BUS_SDR1_SCL_RATE 8000000 +#define I3C_BUS_SDR2_SCL_RATE 6000000 +#define I3C_BUS_SDR3_SCL_RATE 4000000 +#define I3C_BUS_SDR4_SCL_RATE 2000000 +#define I3C_BUS_I2C_FM_TLOW_MIN_NS 1300 +#define I3C_BUS_I2C_FMP_TLOW_MIN_NS 500 +#define I3C_BUS_THIGH_MAX_NS 41 +#define I3C_PERIOD_NS 1000000000ULL + +#define I3C_BUS_MAX_I3C_SCL_RATE 12900000 +#define I3C_BUS_TYP_I3C_SCL_RATE 12500000 +#define I3C_BUS_I2C_FM_PLUS_SCL_RATE 1000000 +#define I3C_BUS_I2C_FM_SCL_RATE 400000 +#define I3C_BUS_TLOW_OD_MIN_NS 200 + +#define I3C_HOT_JOIN_ADDR 0x02 + +#define DW_I3C_MAX_DEVS 32 +#define DW_I3C_MAX_CMD_BUF_SIZE 16 + +/* Snps I3C/I2C Device Private Data */ +struct dw_i3c_i2c_dev_data { + /* Device id within the retaining registers. This is set after bus initialization by the + * controller. + */ + uint8_t id; +}; + +struct dw_i3c_cmd { + uint32_t cmd_lo; + uint32_t cmd_hi; + void *buf; + uint16_t tx_len; + uint16_t rx_len; + uint8_t error; +}; + +struct dw_i3c_xfer { + int32_t ret; + uint32_t ncmds; + struct dw_i3c_cmd cmds[DW_I3C_MAX_CMD_BUF_SIZE]; +}; + +struct dw_i3c_config { + struct i3c_driver_config common; + const struct device *clock; + uint32_t regs; + + /* Initial clk configuration */ + /* Maximum OD high clk pulse length */ + uint32_t od_thigh_max_ns; + /* Minimum OD low clk pulse length */ + uint32_t od_tlow_min_ns; + + void (*irq_config_func)(); +}; + +struct dw_i3c_data { + struct i3c_driver_data common; + uint32_t free_pos; + + uint16_t datstartaddr; + uint16_t dctstartaddr; + uint16_t maxdevs; + + /* fifo depth is in words (32b) */ + uint8_t ibififodepth; + uint8_t respfifodepth; + uint8_t cmdfifodepth; + uint8_t rxfifodepth; + uint8_t txfifodepth; + + enum i3c_bus_mode mode; + + struct i3c_target_config *target_config; + + struct k_sem sem_xfer; + struct k_mutex mt; + +#ifdef CONFIG_I3C_USE_IBI + struct k_sem ibi_sts_sem; + struct k_sem sem_hj; +#endif + + struct dw_i3c_xfer xfer; + + struct dw_i3c_i2c_dev_data dw_i3c_i2c_priv_data[DW_I3C_MAX_DEVS]; +}; + +static uint8_t get_free_pos(uint32_t free_pos) +{ + return find_lsb_set(free_pos) - 1; +} + +/** + * @brief Read data from the Receive FIFO of the I3C device. + * + * This function reads data from the Receive FIFO of the I3C device specified by + * the given device structure and stores it in the provided buffer. + * + * @param dev Pointer to the I3C device structure. + * @param buf Pointer to the buffer where the received data will be stored. + * @param nbytes Number of bytes to read from the Receive FIFO. + */ +static void read_rx_fifo(const struct device *dev, uint8_t *buf, int32_t nbytes) +{ + __ASSERT((buf != NULL), "Rx buffer should not be NULL"); + + const struct dw_i3c_config *config = dev->config; + int32_t i; + uint32_t tmp; + + if (nbytes >= 4) { + for (i = 0; i <= nbytes - 4; i += 4) { + tmp = sys_read32(config->regs + RX_TX_DATA_PORT); + memcpy(buf + i, &tmp, 4); + } + } + if (nbytes & 3) { + tmp = sys_read32(config->regs + RX_TX_DATA_PORT); + memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3); + } +} + +/** + * @brief Write data to the Transmit FIFO of the I3C device. + * + * This function writes data to the Transmit FIFO of the I3C device specified by + * the given device structure from the provided buffer. + * + * @param dev Pointer to the I3C device structure. + * @param buf Pointer to the buffer containing the data to be written. + * @param nbytes Number of bytes to write to the Transmit FIFO. + */ +static void write_tx_fifo(const struct device *dev, const uint8_t *buf, int32_t nbytes) +{ + __ASSERT((buf != NULL), "Tx buffer should not be NULL"); + + const struct dw_i3c_config *config = dev->config; + int32_t i; + uint32_t tmp; + + if (nbytes >= 4) { + for (i = 0; i <= nbytes - 4; i += 4) { + memcpy(&tmp, buf + i, 4); + sys_write32(tmp, config->regs + RX_TX_DATA_PORT); + } + } + + if (nbytes & 3) { + tmp = 0; + memcpy(&tmp, buf + (nbytes & ~3), nbytes & 3); + sys_write32(tmp, config->regs + RX_TX_DATA_PORT); + } +} + +#ifdef CONFIG_I3C_USE_IBI +/** + * @brief Read data from the In-Band Interrupt (IBI) FIFO of the I3C device. + * + * This function reads data from the In-Band Interrupt (IBI) FIFO of the I3C device + * specified by the given device structure and stores it in the provided buffer. + * + * @param dev Pointer to the I3C device structure. + * @param buf Pointer to the buffer where the received IBI data will be stored. + * @param nbytes Number of bytes to read from the IBI FIFO. + */ +static void read_ibi_fifo(const struct device *dev, uint8_t *buf, int32_t nbytes) +{ + __ASSERT((buf != NULL), "Rx IBI buffer should not be NULL"); + + const struct dw_i3c_config *config = dev->config; + int32_t i; + uint32_t tmp; + + if (nbytes >= 4) { + for (i = 0; i <= nbytes - 4; i += 4) { + tmp = sys_read32(config->regs + IBI_QUEUE_STATUS); + memcpy(buf + i, &tmp, 4); + } + } + if (nbytes & 3) { + tmp = sys_read32(config->regs + IBI_QUEUE_STATUS); + memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3); + } +} +#endif + +/** + * @brief End the I3C transfer and process responses. + * + * This function is responsible for ending the I3C transfer on the specified + * I3C device. It processes the responses received from the I3C bus, updating the + * status and error information in the transfer structure. + * + * @param dev Pointer to the I3C device structure. + */ +static void dw_i3c_end_xfer(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_xfer *xfer = &data->xfer; + struct dw_i3c_cmd *cmd; + uint32_t nresp, resp, rx_data; + int32_t i, j, k, ret = 0; + + nresp = QUEUE_STATUS_LEVEL_RESP(sys_read32(config->regs + QUEUE_STATUS_LEVEL)); + for (i = 0; i < nresp; i++) { + uint8_t tid; + + resp = sys_read32(config->regs + RESPONSE_QUEUE_PORT); + tid = RESPONSE_PORT_TID(resp); + if (tid == 0xf) { + /* TODO: handle vendor extension ccc or hdr header in target mode */ + continue; + } + + cmd = &xfer->cmds[tid]; + cmd->rx_len = RESPONSE_PORT_DATA_LEN(resp); + cmd->error = RESPONSE_PORT_ERR_STATUS(resp); + + /* if we are in target mode */ + if (!(sys_read32(config->regs + PRESENT_STATE) & PRESENT_STATE_CURRENT_MASTER)) { + const struct i3c_target_callbacks *target_cb = + data->target_config->callbacks; + + for (j = 0; j < cmd->rx_len; j += 4) { + rx_data = sys_read32(config->regs + RX_TX_DATA_PORT); + /* Call write received cb for each remaining byte */ + for (k = 0; k < MIN(4, cmd->rx_len - j); k++) { + target_cb->write_received_cb(data->target_config, + (rx_data >> (8 * k)) & 0xff); + } + } + + if (target_cb != NULL && target_cb->stop_cb != NULL) { + /* + * TODO: modify API to include status, such as success or aborted + * transfer + */ + target_cb->stop_cb(data->target_config); + } + } + } + + for (i = 0; i < nresp; i++) { + switch (xfer->cmds[i].error) { + case RESPONSE_NO_ERROR: + break; + case RESPONSE_ERROR_PARITY: + case RESPONSE_ERROR_IBA_NACK: + case RESPONSE_ERROR_TRANSF_ABORT: + case RESPONSE_ERROR_CRC: + case RESPONSE_ERROR_FRAME: + ret = -EIO; + break; + case RESPONSE_ERROR_OVER_UNDER_FLOW: + ret = -ENOSPC; + break; + case RESPONSE_ERROR_I2C_W_NACK_ERR: + case RESPONSE_ERROR_ADDRESS_NACK: + ret = -ENXIO; + break; + default: + ret = -EINVAL; + break; + } + } + xfer->ret = ret; + + if (ret < 0) { + sys_write32(RESET_CTRL_RX_FIFO | RESET_CTRL_TX_FIFO | RESET_CTRL_RESP_QUEUE | + RESET_CTRL_CMD_QUEUE, + config->regs + RESET_CTRL); + sys_write32(sys_read32(config->regs + DEVICE_CTRL) | DEV_CTRL_RESUME, + config->regs + DEVICE_CTRL); + } + k_sem_give(&data->sem_xfer); +} + +/** + * @brief Start an I3C transfer on the specified device. + * + * This function initiates an I3C transfer on the specified I3C device by pushing + * data to the Transmit FIFO (TXFIFO) and enqueuing commands to the command queue. + * + * @param dev Pointer to the I3C device structure. + */ +static void start_xfer(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_xfer *xfer = &data->xfer; + struct dw_i3c_cmd *cmd; + uint32_t thld_ctrl, present_state; + int32_t i; + + present_state = sys_read32(config->regs + PRESENT_STATE); + + /* Push data to TXFIFO */ + for (i = 0; i < xfer->ncmds; i++) { + cmd = &xfer->cmds[i]; + /* Not all the commands use write_tx_fifo function */ + if (cmd->buf != NULL) { + write_tx_fifo(dev, cmd->buf, cmd->tx_len); + } + } + + thld_ctrl = sys_read32(config->regs + QUEUE_THLD_CTRL); + thld_ctrl &= ~QUEUE_THLD_CTRL_RESP_BUF_MASK; + thld_ctrl |= QUEUE_THLD_CTRL_RESP_BUF(xfer->ncmds); + sys_write32(thld_ctrl, config->regs + QUEUE_THLD_CTRL); + + /* Enqueue CMD */ + for (i = 0; i < xfer->ncmds; i++) { + cmd = &xfer->cmds[i]; + /* Only cmd_lo is used when it is a target */ + if (present_state & PRESENT_STATE_CURRENT_MASTER) { + sys_write32(cmd->cmd_hi, config->regs + COMMAND_QUEUE_PORT); + } + sys_write32(cmd->cmd_lo, config->regs + COMMAND_QUEUE_PORT); + } +} + +/** + * @brief Get the position of an I3C device with the specified address. + * + * This function retrieves the position (ID) of an I3C device with the specified + * address on the I3C bus associated with the provided I3C device structure. This + * utilizes the controller private data for where the id reg is stored. + * + * @param dev Pointer to the I3C device structure. + * @param addr I3C address of the device whose position is to be retrieved. + * @param sa True if looking up by Static Address, False if by Dynamic Address + * + * @return The position (ID) of the device on success, or a negative error code + * if the device with the given address is not found. + */ +static int get_i3c_addr_pos(const struct device *dev, uint8_t addr, bool sa) +{ + struct dw_i3c_i2c_dev_data *dw_i3c_device_data; + struct i3c_device_desc *desc = sa ? i3c_dev_list_i3c_static_addr_find(dev, addr) + : i3c_dev_list_i3c_addr_find(dev, addr); + + if (desc == NULL) { + return -ENODEV; + } + + dw_i3c_device_data = desc->controller_priv; + + return dw_i3c_device_data->id; +} + +/** + * @brief Get the position of an I2C device with the specified address. + * + * This function retrieves the position (ID) of an I2C device with the specified + * address on the I3C bus associated with the provided I3C device structure. This + * utilizes the controller private data for where the id reg is stored. + * + * @param dev Pointer to the I3C device structure. + * @param addr I2C address of the device whose position is to be retrieved. + * + * @return The position (ID) of the device on success, or a negative error code + * if the device with the given address is not found. + */ +static int get_i2c_addr_pos(const struct device *dev, uint16_t addr) +{ + struct dw_i3c_i2c_dev_data *dw_i3c_device_data; + struct i3c_i2c_device_desc *desc = i3c_dev_list_i2c_addr_find(dev, addr); + + if (desc == NULL) { + return -ENODEV; + } + + dw_i3c_device_data = desc->controller_priv; + + return dw_i3c_device_data->id; +} + +/** + * @brief Transfer messages in I3C mode. + * + * @param dev Pointer to device driver instance. + * @param target Pointer to target device descriptor. + * @param msgs Pointer to I3C messages. + * @param num_msgs Number of messages to transfers. + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -EINVAL Address not registered + */ +static int dw_i3c_xfers(const struct device *dev, struct i3c_device_desc *target, + struct i3c_msg *msgs, uint8_t num_msgs) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_xfer *xfer = &data->xfer; + int32_t ret, i, pos, nrxwords = 0, ntxwords = 0; + uint32_t present_state; + + present_state = sys_read32(config->regs + PRESENT_STATE); + if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) { + return -EACCES; + } + + if (num_msgs > data->cmdfifodepth) { + return -ENOTSUP; + } + + pos = get_i3c_addr_pos(dev, target->dynamic_addr, false); + if (pos < 0) { + LOG_ERR("%s: Invalid slave device", dev->name); + return -EINVAL; + } + + for (i = 0; i < num_msgs; i++) { + if (msgs[i].flags & I2C_MSG_READ) { + nrxwords += DIV_ROUND_UP(msgs[i].len, 4); + } else { + ntxwords += DIV_ROUND_UP(msgs[i].len, 4); + } + } + + if (ntxwords > data->txfifodepth || nrxwords > data->rxfifodepth) { + return -ENOTSUP; + } + + ret = k_mutex_lock(&data->mt, K_MSEC(1000)); + if (ret) { + LOG_ERR("%s: Mutex err (%d)", dev->name, ret); + return ret; + } + + memset(xfer, 0, sizeof(struct dw_i3c_xfer)); + + xfer->ncmds = num_msgs; + xfer->ret = -1; + + for (i = 0; i < num_msgs; i++) { + struct dw_i3c_cmd *cmd = &xfer->cmds[i]; + + cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(msgs[i].len) | COMMAND_PORT_TRANSFER_ARG; + cmd->cmd_lo = COMMAND_PORT_TID(i) | COMMAND_PORT_DEV_INDEX(pos) | COMMAND_PORT_ROC; + + cmd->buf = msgs[i].buf; + + if (msgs[i].flags & I3C_MSG_NBCH) { + sys_write32(sys_read32(config->regs + DEVICE_CTRL) & ~DEV_CTRL_IBA_INCLUDE, + config->regs + DEVICE_CTRL); + } else { + sys_write32(sys_read32(config->regs + DEVICE_CTRL) | DEV_CTRL_IBA_INCLUDE, + config->regs + DEVICE_CTRL); + } + + if (msgs[i].flags & I3C_MSG_READ) { + uint8_t rd_speed; + + if (msgs[i].flags & I3C_MSG_HDR) { + /* Set read command bit for DDR and TS */ + cmd->cmd_lo |= COMMAND_PORT_CP | + COMMAND_PORT_CMD(BIT(7) | (msgs[i].hdr_cmd_code & + GENMASK(6, 0))); + if (msgs[i].hdr_mode & I3C_MSG_HDR_DDR) { + if (data->common.ctrl_config.supported_hdr & + I3C_MSG_HDR_DDR) { + rd_speed = COMMAND_PORT_SPEED_I3C_DDR; + } else { + /* DDR support not configured with this */ + LOG_ERR("%s: HDR-DDR not supported", dev->name); + ret = -ENOTSUP; + goto error; + } + } else if (msgs[i].hdr_mode & I3C_MSG_HDR_TSP || + msgs[i].hdr_mode & I3C_MSG_HDR_TSL) { + if (data->common.ctrl_config.supported_hdr & + (I3C_MSG_HDR_TSP | I3C_MSG_HDR_TSL)) { + rd_speed = COMMAND_PORT_SPEED_I3C_TS; + } else { + /* TS support not configured with this */ + LOG_ERR("%s: HDR-TS not supported", dev->name); + ret = -ENOTSUP; + goto error; + } + } else { + LOG_ERR("%s: HDR %d not supported", dev->name, + msgs[i].hdr_mode); + ret = -ENOTSUP; + goto error; + } + } else { + rd_speed = I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL( + target->data_speed.maxrd); + } + + cmd->cmd_lo |= (COMMAND_PORT_READ_TRANSFER | COMMAND_PORT_SPEED(rd_speed)); + cmd->rx_len = msgs[i].len; + } else { + uint8_t wr_speed; + + if (msgs[i].flags & I3C_MSG_HDR) { + cmd->cmd_lo |= + COMMAND_PORT_CP | + COMMAND_PORT_CMD(msgs[i].hdr_cmd_code & GENMASK(6, 0)); + if (msgs[i].hdr_mode & I3C_MSG_HDR_DDR) { + if (data->common.ctrl_config.supported_hdr & + I3C_MSG_HDR_DDR) { + wr_speed = COMMAND_PORT_SPEED_I3C_DDR; + } else { + /* DDR support not configured with this */ + LOG_ERR("%s: HDR-DDR not supported", dev->name); + ret = -ENOTSUP; + goto error; + } + } else if (msgs[i].hdr_mode & I3C_MSG_HDR_TSP || + msgs[i].hdr_mode & I3C_MSG_HDR_TSL) { + if (data->common.ctrl_config.supported_hdr & + (I3C_MSG_HDR_TSP | I3C_MSG_HDR_TSL)) { + wr_speed = COMMAND_PORT_SPEED_I3C_TS; + } else { + /* TS support not configured with this */ + LOG_ERR("%s: HDR-TS not supported", dev->name); + ret = -ENOTSUP; + goto error; + } + } else { + LOG_ERR("%s: HDR %d not supported", dev->name, + msgs[i].hdr_mode); + ret = -ENOTSUP; + goto error; + } + } else { + wr_speed = I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL( + target->data_speed.maxwr); + } + + cmd->cmd_lo |= COMMAND_PORT_SPEED(wr_speed); + cmd->tx_len = msgs[i].len; + } + + if (i == (num_msgs - 1)) { + cmd->cmd_lo |= COMMAND_PORT_TOC; + } + } + + start_xfer(dev); + + ret = k_sem_take(&data->sem_xfer, K_MSEC(1000)); + if (ret) { + LOG_ERR("%s: Semaphore err (%d)", dev->name, ret); + goto error; + } + + for (i = 0; i < xfer->ncmds; i++) { + msgs[i].num_xfer = (msgs[i].flags & I3C_MSG_READ) ? xfer->cmds[i].rx_len + : xfer->cmds[i].tx_len; + if (xfer->cmds[i].rx_len && !xfer->cmds[i].error) { + read_rx_fifo(dev, xfer->cmds[i].buf, xfer->cmds[i].rx_len); + } + } + + ret = xfer->ret; + +error: + k_mutex_unlock(&data->mt); + + return ret; +} + +/** + * @brief Transfer messages in I2C mode. + * + * @param dev Pointer to device driver instance. + * @param target Pointer to target device descriptor. + * @param msgs Pointer to I2C messages. + * @param num_msgs Number of messages to transfers. + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -EINVAL Address not registered + */ +static int dw_i3c_i2c_transfer(const struct device *dev, struct i3c_i2c_device_desc *target, + struct i2c_msg *msgs, uint8_t num_msgs) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_xfer *xfer = &data->xfer; + int32_t ret, i, pos, nrxwords = 0, ntxwords = 0; + uint32_t present_state; + + present_state = sys_read32(config->regs + PRESENT_STATE); + if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) { + return -EACCES; + } + + if (num_msgs > data->cmdfifodepth) { + return -ENOTSUP; + } + + pos = get_i2c_addr_pos(dev, target->addr); + if (pos < 0) { + LOG_ERR("%s: Invalid slave device", dev->name); + return -EINVAL; + } + + for (i = 0; i < num_msgs; i++) { + if (msgs[i].flags & I2C_MSG_READ) { + nrxwords += DIV_ROUND_UP(msgs[i].len, 4); + } else { + ntxwords += DIV_ROUND_UP(msgs[i].len, 4); + } + } + + if (ntxwords > data->txfifodepth || nrxwords > data->rxfifodepth) { + return -ENOTSUP; + } + + ret = k_mutex_lock(&data->mt, K_MSEC(1000)); + if (ret) { + LOG_ERR("%s: Mutex err (%d)", dev->name, ret); + return ret; + } + + memset(xfer, 0, sizeof(struct dw_i3c_xfer)); + + xfer->ncmds = num_msgs; + xfer->ret = -1; + + for (i = 0; i < num_msgs; i++) { + struct dw_i3c_cmd *cmd = &xfer->cmds[i]; + + cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(msgs[i].len) | COMMAND_PORT_TRANSFER_ARG; + cmd->cmd_lo = COMMAND_PORT_TID(i) | COMMAND_PORT_DEV_INDEX(pos) | COMMAND_PORT_ROC; + + cmd->buf = msgs[i].buf; + + if (msgs[i].flags & I2C_MSG_READ) { + uint8_t rd_speed = I3C_LVR_I2C_MODE(target->lvr) == I3C_LVR_I2C_FM_MODE + ? COMMAND_PORT_SPEED_I2C_FM + : COMMAND_PORT_SPEED_I2C_FMP; + + cmd->cmd_lo |= (COMMAND_PORT_READ_TRANSFER | COMMAND_PORT_SPEED(rd_speed)); + cmd->rx_len = msgs[i].len; + } else { + uint8_t wr_speed = I3C_LVR_I2C_MODE(target->lvr) == I3C_LVR_I2C_FM_MODE + ? COMMAND_PORT_SPEED_I2C_FM + : COMMAND_PORT_SPEED_I2C_FMP; + + cmd->cmd_lo |= COMMAND_PORT_SPEED(wr_speed); + cmd->tx_len = msgs[i].len; + } + + if (i == (num_msgs - 1)) { + cmd->cmd_lo |= COMMAND_PORT_TOC; + } + } + + /* Do not send broadcast address (0x7E) with I2C transfers */ + sys_write32(sys_read32(config->regs + DEVICE_CTRL) & ~DEV_CTRL_IBA_INCLUDE, + config->regs + DEVICE_CTRL); + + start_xfer(dev); + + ret = k_sem_take(&data->sem_xfer, K_MSEC(1000)); + if (ret) { + LOG_ERR("%s: Semaphore err (%d)", dev->name, ret); + goto error; + } + + for (i = 0; i < xfer->ncmds; i++) { + if (xfer->cmds[i].rx_len && !xfer->cmds[i].error) { + read_rx_fifo(dev, xfer->cmds[i].buf, xfer->cmds[i].rx_len); + } + } + + ret = xfer->ret; + +error: + k_mutex_unlock(&data->mt); + + return ret; +} + +/** + * Find a registered I2C target device. + * + * Controller only API. + * + * This returns the I2C device descriptor of the I2C device + * matching the device address @p addr. + * + * @param dev Pointer to controller device driver instance. + * @param id I2C target device address. + * + * @return @see i3c_i2c_device_find. + */ +static struct i3c_i2c_device_desc *dw_i3c_i2c_device_find(const struct device *dev, uint16_t addr) +{ + return i3c_dev_list_i2c_addr_find(dev, addr); +} + +/** + * @brief Transfer messages in I2C mode. + * + * @see i2c_transfer + * + * @param dev Pointer to device driver instance. + * @param target Pointer to target device descriptor. + * @param msgs Pointer to I2C messages. + * @param num_msgs Number of messages to transfers. + * + * @return @see i2c_transfer + */ +static int dw_i3c_i2c_api_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t addr) +{ + struct i3c_i2c_device_desc *i2c_dev = dw_i3c_i2c_device_find(dev, addr); + int ret; + + if (i2c_dev == NULL) { + ret = -ENODEV; + } else { + ret = dw_i3c_i2c_transfer(dev, i2c_dev, msgs, num_msgs); + } + + return ret; +} + +#ifdef CONFIG_I3C_USE_IBI +static int dw_i3c_controller_ibi_hj_response(const struct device *dev, bool ack) +{ + const struct dw_i3c_config *config = dev->config; + uint32_t ctrl = sys_read32(config->regs + DEVICE_CTRL); + + if (ack) { + ctrl &= ~DEV_CTRL_HOT_JOIN_NACK; + } else { + ctrl |= DEV_CTRL_HOT_JOIN_NACK; + } + + sys_write32(ctrl, config->regs + DEVICE_CTRL); + + return 0; +} + +static int i3c_dw_endis_ibi(const struct device *dev, struct i3c_device_desc *target, bool en) +{ + struct dw_i3c_data *data = dev->data; + const struct dw_i3c_config *config = dev->config; + uint32_t bitpos, sir_con; + struct i3c_ccc_events i3c_events; + int ret; + int pos; + + pos = get_i3c_addr_pos(dev, target->dynamic_addr, false); + if (pos < 0) { + LOG_ERR("%s: Invalid Slave address", dev->name); + return pos; + } + + uint32_t reg = sys_read32(config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos)); + + if (i3c_ibi_has_payload(target)) { + reg |= DEV_ADDR_TABLE_IBI_WITH_DATA; + } else { + reg &= ~DEV_ADDR_TABLE_IBI_WITH_DATA; + } + if (en) { + reg &= ~DEV_ADDR_TABLE_SIR_REJECT; + } else { + reg |= DEV_ADDR_TABLE_SIR_REJECT; + } + sys_write32(reg, config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos)); + + sir_con = sys_read32(config->regs + IBI_SIR_REQ_REJECT); + /* TODO: what is this macro doing?? */ + bitpos = IBI_SIR_REQ_ID(target->dynamic_addr); + + if (en) { + sir_con &= ~BIT(bitpos); + } else { + sir_con |= BIT(bitpos); + } + sys_write32(sir_con, config->regs + IBI_SIR_REQ_REJECT); + + /* Tell target to enable IBI */ + i3c_events.events = I3C_CCC_EVT_INTR; + ret = i3c_ccc_do_events_set(target, en, &i3c_events); + if (ret != 0) { + LOG_ERR("%s: Error sending IBI ENEC for 0x%02x (%d)", dev->name, + target->dynamic_addr, ret); + return ret; + } + + return 0; +} + +static int dw_i3c_controller_enable_ibi(const struct device *dev, struct i3c_device_desc *target) +{ + return i3c_dw_endis_ibi(dev, target, true); +} + +static int dw_i3c_controller_disable_ibi(const struct device *dev, struct i3c_device_desc *target) +{ + return i3c_dw_endis_ibi(dev, target, false); +} + +static void dw_i3c_handle_tir(const struct device *dev, uint32_t ibi_status) +{ + uint8_t ibi_data[CONFIG_I3C_IBI_MAX_PAYLOAD_SIZE]; + uint8_t addr, len; + int pos; + + addr = IBI_QUEUE_IBI_ADDR(ibi_status); + len = IBI_QUEUE_STATUS_DATA_LEN(ibi_status); + + pos = get_i3c_addr_pos(dev, addr, false); + if (pos < 0) { + LOG_ERR("%s: Invalid Slave address", dev->name); + return; + } + + struct i3c_device_desc *desc = i3c_dev_list_i3c_addr_find(dev, addr); + + if (desc == NULL) { + return; + } + + if (len > 0) { + read_ibi_fifo(dev, ibi_data, len); + } + + if (i3c_ibi_work_enqueue_target_irq(desc, ibi_data, len) != 0) { + LOG_ERR("%s: Error enqueue IBI IRQ work", dev->name); + } +} + +static void dw_i3c_handle_hj(const struct device *dev, uint32_t ibi_status) +{ + if (IBI_QUEUE_STATUS_IBI_STS(ibi_status) & BIT(3)) { + LOG_DBG("%s: NAK for HJ", dev->name); + return; + } + + if (i3c_ibi_work_enqueue_hotjoin(dev) != 0) { + LOG_ERR("%s: Error enqueue IBI HJ work", dev->name); + } +} + +static void ibis_handle(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + uint32_t nibis, ibi_stat; + int32_t i; + + nibis = sys_read32(config->regs + QUEUE_STATUS_LEVEL); + nibis = QUEUE_STATUS_IBI_BUF_BLR(nibis); + for (i = 0; i < nibis; i++) { + ibi_stat = sys_read32(config->regs + IBI_QUEUE_STATUS); + if (IBI_TYPE_SIRQ(ibi_stat)) { + dw_i3c_handle_tir(dev, ibi_stat); + } else if (IBI_TYPE_HJ(ibi_stat)) { + dw_i3c_handle_hj(dev, ibi_stat); + } else { + LOG_DBG("%s: Secondary Master Request Not implemented", dev->name); + } + } +} + +static int dw_i3c_target_ibi_raise_hj(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + int ret; + + if (!(sys_read32(config->regs + HW_CAPABILITY) & HW_CAPABILITY_SLV_HJ_CAP)) { + LOG_ERR("%s: HJ not supported", dev->name); + return -ENOTSUP; + } + if (sys_read32(config->regs + DEVICE_ADDR) & DEVICE_ADDR_DYNAMIC_ADDR_VALID) { + LOG_ERR("%s: HJ not available, DA already assigned", dev->name); + return -EACCES; + } + /* if this is set, then it is assumed it is already trying */ + if ((sys_read32(config->regs + SLV_EVENT_STATUS) & SLV_EVENT_STATUS_HJ_EN)) { + LOG_ERR("%s: HJ requests are currently disabled by DISEC", dev->name); + return -EAGAIN; + } + + /* + * This is issued auto-magically by the IP when certain conditions are meet. + * These include: + * 1. SLV_EVENT_STATUS[HJ_EN] = 1 (or a controller issues Enables HJ events with + * the CCC ENEC, This can be set to 0 with CCC DISEC from a controller) + * 2. The Dynamic address is invalid. (not assigned yet) + * 3. Bus Idle condition is met (1ms) as programmed in the Bus Timing Register + */ + + /* enable HJ */ + sys_write32(sys_read32(config->regs + SLV_EVENT_STATUS) | SLV_EVENT_STATUS_HJ_EN, + config->regs + SLV_EVENT_STATUS); + + ret = k_sem_take(&data->sem_hj, K_MSEC(1000)); + if (ret) { + return ret; + } + + return 0; +} + +static int dw_i3c_target_ibi_raise_tir(const struct device *dev, struct i3c_ibi *request) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + int status; + uint32_t slv_intr_req, slv_ibi_resp; + + if (!(sys_read32(config->regs + HW_CAPABILITY) & HW_CAPABILITY_SLV_IBI_CAP)) { + LOG_ERR("%s: IBI TIR not supported", dev->name); + return -ENOTSUP; + } + + if (!(sys_read32(config->regs + DEVICE_ADDR) & DEVICE_ADDR_DYNAMIC_ADDR_VALID)) { + LOG_ERR("%s: IBI TIR not available, DA not assigned", dev->name); + return -EACCES; + } + + if (!(sys_read32(config->regs + SLV_EVENT_STATUS) & SLV_EVENT_STATUS_SIR_EN)) { + LOG_ERR("%s: IBI TIR requests are currently disabled by DISEC", dev->name); + return -EAGAIN; + } + + slv_intr_req = sys_read32(config->regs + SLV_INTR_REQ); + if (sys_read32(config->regs + SLV_CHAR_CTRL) & SLV_CHAR_CTRL_IBI_PAYLOAD) { + uint32_t tir_data = 0; + + /* max support length is DA + MDB (1 byte) + 4 data bytes, MDB must be at least + * included + */ + if ((request->payload_len > 5) || (request->payload_len == 0)) { + return -EINVAL; + } + + /* MDB should be the first byte of the payload */ + slv_intr_req |= SLV_INTR_REQ_MDB(request->payload[0]) | + SLV_INTR_REQ_SIR_DATA_LENGTH(request->payload_len - 1); + + /* program the tir data packet */ + tir_data |= + SLV_SIR_DATA_BYTE0((request->payload_len > 1) ? request->payload[1] : 0); + tir_data |= + SLV_SIR_DATA_BYTE1((request->payload_len > 2) ? request->payload[2] : 0); + tir_data |= + SLV_SIR_DATA_BYTE2((request->payload_len > 3) ? request->payload[3] : 0); + tir_data |= + SLV_SIR_DATA_BYTE3((request->payload_len > 4) ? request->payload[4] : 0); + sys_write32(tir_data, config->regs + SLV_SIR_DATA); + } + + /* kick off the ibi tir request */ + slv_intr_req |= SLV_INTR_REQ_SIR; + sys_write32(slv_intr_req, config->regs + SLV_INTR_REQ); + + /* wait for SLV_IBI_RESP update */ + status = k_sem_take(&data->ibi_sts_sem, K_MSEC(100)); + if (status != 0) { + return -ETIMEDOUT; + } + + slv_ibi_resp = sys_read32(config->regs + SLV_INTR_REQ); + switch (SLV_IBI_RESP_IBI_STS(slv_ibi_resp)) { + case SLV_IBI_RESP_IBI_STS_ACK: + LOG_DBG("%s: Controller ACKed IBI TIR", dev->name); + return 0; + case SLV_IBI_RESP_IBI_STS_NACK: + LOG_ERR("%s: Controller NACKed IBI TIR", dev->name); + return -EAGAIN; + case SLV_IBI_RESP_IBI_STS_EARLY_TERMINATE: + LOG_ERR("%s: Controller aborted IBI TIR with %lu remaining", dev->name, + SLV_IBI_RESP_DATA_LENGTH(slv_ibi_resp)); + return -EIO; + default: + return -EIO; + } +} + +static int dw_i3c_target_ibi_raise(const struct device *dev, struct i3c_ibi *request) +{ + if (request == NULL) { + return -EINVAL; + } + + switch (request->ibi_type) { + case I3C_IBI_TARGET_INTR: + return dw_i3c_target_ibi_raise_tir(dev, request); + case I3C_IBI_CONTROLLER_ROLE_REQUEST: + /* TODO: Synopsys I3C can support CR, but not implemented yet */ + return -ENOTSUP; + case I3C_IBI_HOTJOIN: + return dw_i3c_target_ibi_raise_hj(dev); + default: + return -EINVAL; + } +} + +#endif /* CONFIG_I3C_USE_IBI */ + +static int i3c_dw_irq(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + uint32_t status; + uint32_t present_state; + + status = sys_read32(config->regs + INTR_STATUS); + if (status & (INTR_TRANSFER_ERR_STAT | INTR_RESP_READY_STAT)) { + dw_i3c_end_xfer(dev); + + if (status & INTR_TRANSFER_ERR_STAT) { + sys_write32(INTR_TRANSFER_ERR_STAT, config->regs + INTR_STATUS); + } + } + + if (status & INTR_IBI_THLD_STAT) { +#ifdef CONFIG_I3C_USE_IBI + ibis_handle(dev); +#endif /* CONFIG_I3C_USE_IBI */ + } + + /* target mode related interrupts */ + present_state = sys_read32(config->regs + PRESENT_STATE); + if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) { + const struct i3c_target_callbacks *target_cb = + data->target_config ? data->target_config->callbacks : NULL; + + /* Read Requested when the CMDQ is empty*/ + if (status & INTR_READ_REQ_RECV_STAT) { + if (target_cb != NULL && target_cb->read_requested_cb != NULL) { + /* Inform app so that it can send data. */ + target_cb->read_requested_cb(data->target_config, NULL); + } + sys_write32(INTR_READ_REQ_RECV_STAT, config->regs + INTR_STATUS); + } +#ifdef CONFIG_I3C_USE_IBI + /* IBI TIR request register is addressed and status is updated*/ + if (status & INTR_IBI_UPDATED_STAT) { + k_sem_give(&data->ibi_sts_sem); + sys_write32(INTR_IBI_UPDATED_STAT, config->regs + INTR_STATUS); + } + /* DA has been assigned, could happen after a IBI HJ request */ + if (status & INTR_DYN_ADDR_ASSGN_STAT) { + /* TODO: handle IBI HJ with semaphore */ + sys_write32(INTR_DYN_ADDR_ASSGN_STAT, config->regs + INTR_STATUS); + } +#endif /* CONFIG_I3C_USE_IBI */ + } + + return 0; +} + +static int init_scl_timing(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + uint32_t scl_timing, hcnt, lcnt, core_rate; + + if (clock_control_get_rate(config->clock, NULL, &core_rate) != 0) { + LOG_ERR("%s: get clock rate failed", dev->name); + return -EINVAL; + } + + /* I3C_OD */ + hcnt = DIV_ROUND_UP(config->od_thigh_max_ns * (uint64_t)core_rate, I3C_PERIOD_NS) - 1; + hcnt = CLAMP(hcnt, SCL_I3C_TIMING_CNT_MIN, SCL_I3C_TIMING_CNT_MAX); + + lcnt = DIV_ROUND_UP(config->od_tlow_min_ns * (uint64_t)core_rate, I3C_PERIOD_NS); + lcnt = CLAMP(lcnt, SCL_I3C_TIMING_CNT_MIN, SCL_I3C_TIMING_CNT_MAX); + + scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | SCL_I3C_TIMING_LCNT(lcnt); + sys_write32(scl_timing, config->regs + SCL_I3C_OD_TIMING); + + /* Set bus free timing to match tlow setting for OD clk config. */ + sys_write32(BUS_I3C_MST_FREE(lcnt), config->regs + BUS_FREE_TIMING); + + /* I3C_PP */ + hcnt = DIV_ROUND_UP(I3C_BUS_THIGH_MAX_NS * (uint64_t)core_rate, I3C_PERIOD_NS) - 1; + hcnt = CLAMP(hcnt, SCL_I3C_TIMING_CNT_MIN, SCL_I3C_TIMING_CNT_MAX); + + lcnt = DIV_ROUND_UP(core_rate, data->common.ctrl_config.scl.i3c) - hcnt; + lcnt = CLAMP(lcnt, SCL_I3C_TIMING_CNT_MIN, SCL_I3C_TIMING_CNT_MAX); + + scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | SCL_I3C_TIMING_LCNT(lcnt); + sys_write32(scl_timing, config->regs + SCL_I3C_PP_TIMING); + + /* I3C */ + lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR1_SCL_RATE) - hcnt; + scl_timing = SCL_EXT_LCNT_1(lcnt); + lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR2_SCL_RATE) - hcnt; + scl_timing |= SCL_EXT_LCNT_2(lcnt); + lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR3_SCL_RATE) - hcnt; + scl_timing |= SCL_EXT_LCNT_3(lcnt); + lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR4_SCL_RATE) - hcnt; + scl_timing |= SCL_EXT_LCNT_4(lcnt); + sys_write32(scl_timing, config->regs + SCL_EXT_LCNT_TIMING); + + /* I2C FM+ */ + lcnt = DIV_ROUND_UP(I3C_BUS_I2C_FMP_TLOW_MIN_NS * (uint64_t)core_rate, I3C_PERIOD_NS); + hcnt = DIV_ROUND_UP(core_rate, I3C_BUS_I2C_FM_PLUS_SCL_RATE) - lcnt; + scl_timing = SCL_I2C_FMP_TIMING_HCNT(hcnt) | SCL_I2C_FMP_TIMING_LCNT(lcnt); + sys_write32(scl_timing, config->regs + SCL_I2C_FMP_TIMING); + + /* I2C FM */ + lcnt = DIV_ROUND_UP(I3C_BUS_I2C_FM_TLOW_MIN_NS * (uint64_t)core_rate, I3C_PERIOD_NS); + hcnt = DIV_ROUND_UP(core_rate, I3C_BUS_I2C_FM_SCL_RATE) - lcnt; + scl_timing = SCL_I2C_FM_TIMING_HCNT(hcnt) | SCL_I2C_FM_TIMING_LCNT(lcnt); + sys_write32(scl_timing, config->regs + SCL_I2C_FM_TIMING); + + if (data->mode != I3C_BUS_MODE_PURE) { + sys_write32(BUS_I3C_MST_FREE(lcnt), config->regs + BUS_FREE_TIMING); + sys_write32(sys_read32(config->regs + DEVICE_CTRL) | DEV_CTRL_I2C_SLAVE_PRESENT, + config->regs + DEVICE_CTRL); + } + /* I3C Bus Available Time */ + scl_timing = DIV_ROUND_UP(I3C_BUS_AVAILABLE_TIME_NS * (uint64_t)core_rate, + I3C_PERIOD_NS); + sys_write32(BUS_I3C_AVAIL_TIME(scl_timing), config->regs + BUS_FREE_TIMING); + + /* I3C Bus Idle Time */ + scl_timing = + DIV_ROUND_UP(I3C_BUS_IDLE_TIME_NS * (uint64_t)core_rate, I3C_PERIOD_NS); + sys_write32(BUS_I3C_IDLE_TIME(scl_timing), config->regs + BUS_IDLE_TIMING); + + return 0; +} + +/** + * Determine I3C bus mode from the i2c devices on the bus + * + * Reads the LVR of all I2C devices and returns the I3C bus + * Mode + * + * @param dev_list Pointer to device list + * + * @return @see enum i3c_bus_mode. + */ +static enum i3c_bus_mode i3c_bus_mode(const struct i3c_dev_list *dev_list) +{ + enum i3c_bus_mode mode = I3C_BUS_MODE_PURE; + + for (int i = 0; i < dev_list->num_i2c; i++) { + switch (I3C_LVR_I2C_DEV_IDX(dev_list->i2c[i].lvr)) { + case I3C_LVR_I2C_DEV_IDX_0: + if (mode < I3C_BUS_MODE_MIXED_FAST) { + mode = I3C_BUS_MODE_MIXED_FAST; + } + break; + case I3C_LVR_I2C_DEV_IDX_1: + if (mode < I3C_BUS_MODE_MIXED_LIMITED) { + mode = I3C_BUS_MODE_MIXED_LIMITED; + } + break; + case I3C_LVR_I2C_DEV_IDX_2: + if (mode < I3C_BUS_MODE_MIXED_SLOW) { + mode = I3C_BUS_MODE_MIXED_SLOW; + } + break; + default: + mode = I3C_BUS_MODE_INVALID; + break; + } + } + return mode; +} + +static int dw_i3c_attach_device(const struct device *dev, struct i3c_device_desc *desc) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + uint8_t pos = get_free_pos(data->free_pos); + uint8_t addr = desc->dynamic_addr ? desc->dynamic_addr : desc->static_addr; + + if (pos < 0) { + LOG_ERR("%s: no space for i3c device: %s", dev->name, desc->dev->name); + return -ENOSPC; + } + + data->dw_i3c_i2c_priv_data[pos].id = pos; + desc->controller_priv = &(data->dw_i3c_i2c_priv_data[pos]); + data->free_pos &= ~BIT(pos); + + LOG_DBG("%s: Attaching %s", dev->name, desc->dev->name); + + sys_write32(DEV_ADDR_TABLE_DYNAMIC_ADDR(addr), + config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos)); + + return 0; +} + +static int dw_i3c_reattach_device(const struct device *dev, struct i3c_device_desc *desc, + uint8_t old_dyn_addr) +{ + ARG_UNUSED(old_dyn_addr); + + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_i2c_dev_data *dw_i3c_device_data = desc->controller_priv; + uint32_t dat; + + if (dw_i3c_device_data == NULL) { + LOG_ERR("%s: %s: device not attached", dev->name, desc->dev->name); + return -EINVAL; + } + /* TODO: investigate clearing table beforehand */ + + LOG_DBG("Reattaching %s", desc->dev->name); + + dat = sys_read32(config->regs + + DEV_ADDR_TABLE_LOC(data->datstartaddr, dw_i3c_device_data->id)); + dat &= ~DEV_ADDR_TABLE_DYNAMIC_ADDR_MASK; + sys_write32(DEV_ADDR_TABLE_DYNAMIC_ADDR(desc->dynamic_addr) | dat, + config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, dw_i3c_device_data->id)); + + return 0; +} + +static int dw_i3c_detach_device(const struct device *dev, struct i3c_device_desc *desc) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_i2c_dev_data *dw_i3c_device_data = desc->controller_priv; + + if (dw_i3c_device_data == NULL) { + LOG_ERR("%s: %s: device not attached", dev->name, desc->dev->name); + return -EINVAL; + } + + LOG_DBG("%s: Detaching %s", dev->name, desc->dev->name); + + sys_write32(0, + config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, dw_i3c_device_data->id)); + data->free_pos |= BIT(dw_i3c_device_data->id); + desc->controller_priv = NULL; + + return 0; +} + +static int dw_i3c_i2c_attach_device(const struct device *dev, struct i3c_i2c_device_desc *desc) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + uint8_t pos; + + pos = get_free_pos(data->free_pos); + if (pos < 0) { + return -ENOSPC; + } + + data->dw_i3c_i2c_priv_data[pos].id = pos; + desc->controller_priv = &(data->dw_i3c_i2c_priv_data[pos]); + data->free_pos &= ~BIT(pos); + + sys_write32(DEV_ADDR_TABLE_LEGACY_I2C_DEV | DEV_ADDR_TABLE_STATIC_ADDR(desc->addr), + config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos)); + + return 0; +} + +static int dw_i3c_i2c_detach_device(const struct device *dev, struct i3c_i2c_device_desc *desc) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_i2c_dev_data *dw_i2c_device_data = desc->controller_priv; + + if (dw_i2c_device_data == NULL) { + LOG_ERR("%s: device not attached", dev->name); + return -EINVAL; + } + + k_mutex_lock(&data->mt, K_FOREVER); + + sys_write32(0, + config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, dw_i2c_device_data->id)); + data->free_pos |= BIT(dw_i2c_device_data->id); + desc->controller_priv = NULL; + + k_mutex_unlock(&data->mt); + + return 0; +} + +static int set_controller_info(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + + uint8_t controller_da = + i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots, 0); + LOG_DBG("%s: 0x%02x DA selected for controller", dev->name, controller_da); + + sys_write32(DEVICE_ADDR_DYNAMIC_ADDR_VALID | DEVICE_ADDR_DYNAMIC(controller_da), + config->regs + DEVICE_ADDR); + /* Mark the address as I3C device */ + i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, controller_da); + + return 0; +} + +static void enable_interrupts(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + uint32_t thld_ctrl; + + config->irq_config_func(); + + thld_ctrl = sys_read32(config->regs + QUEUE_THLD_CTRL); + thld_ctrl &= (~QUEUE_THLD_CTRL_RESP_BUF_MASK & ~QUEUE_THLD_CTRL_IBI_STS_MASK); + sys_write32(thld_ctrl, config->regs + QUEUE_THLD_CTRL); + + thld_ctrl = sys_read32(config->regs + DATA_BUFFER_THLD_CTRL); + thld_ctrl &= ~DATA_BUFFER_THLD_CTRL_RX_BUF; + sys_write32(thld_ctrl, config->regs + DATA_BUFFER_THLD_CTRL); + + sys_write32(INTR_ALL, config->regs + INTR_STATUS); + + sys_write32(INTR_SLAVE_MASK | INTR_MASTER_MASK, config->regs + INTR_STATUS_EN); + sys_write32(INTR_SLAVE_MASK | INTR_MASTER_MASK, config->regs + INTR_SIGNAL_EN); +} + +/** + * @brief Calculate the odd parity of a byte. + * + * This function calculates the odd parity of the input byte, returning 1 if the + * number of set bits is odd and 0 otherwise. + * + * @param p The byte for which odd parity is to be calculated. + * + * @return The odd parity result (1 if odd, 0 if even). + */ +static uint8_t odd_parity(uint8_t p) +{ + p ^= p >> 4; + p &= 0xf; + return (0x9669 >> p) & 1; +} + +/** + * @brief Send Common Command Code (CCC). + * + * @see i3c_do_ccc + * + * @param dev Pointer to controller device driver instance. + * @param payload Pointer to CCC payload. + * + * @return @see i3c_do_ccc + */ +static int dw_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *payload) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_xfer *xfer = &data->xfer; + struct dw_i3c_cmd *cmd; + int ret, i, pos; + uint32_t present_state; + + present_state = sys_read32(config->regs + PRESENT_STATE); + if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) { + return -EACCES; + } + + ret = k_mutex_lock(&data->mt, K_MSEC(1000)); + if (ret) { + LOG_DBG("%s: Mutex err (%d)", dev->name, ret); + return ret; + } + + memset(xfer, 0, sizeof(struct dw_i3c_xfer)); + xfer->ret = -1; + + /* in the case of multiple targets in a CCC, each command queue must have the same CCC ID + * loaded along with different dev index fields pointing to the targets + */ + if (i3c_ccc_is_payload_broadcast(payload)) { + xfer->ncmds = 1; + cmd = &xfer->cmds[0]; + cmd->buf = payload->ccc.data; + + cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(payload->ccc.data_len) | + COMMAND_PORT_TRANSFER_ARG; + cmd->cmd_lo = COMMAND_PORT_CP | COMMAND_PORT_TOC | COMMAND_PORT_ROC | + COMMAND_PORT_CMD(payload->ccc.id); + + if ((payload->targets.payloads) && (payload->targets.payloads[0].rnw)) { + cmd->cmd_lo |= COMMAND_PORT_READ_TRANSFER; + cmd->rx_len = payload->ccc.data_len; + } else { + cmd->tx_len = payload->ccc.data_len; + } + } else { + if (!(payload->targets.payloads)) { + LOG_ERR("%s: Direct CCC Payload structure Empty", dev->name); + ret = -EINVAL; + goto error; + } + xfer->ncmds = payload->targets.num_targets; + for (i = 0; i < payload->targets.num_targets; i++) { + cmd = &xfer->cmds[i]; + /* Look up position, SETDASA will perform the look up by static addr */ + pos = get_i3c_addr_pos(dev, payload->targets.payloads[i].addr, + payload->ccc.id == I3C_CCC_SETDASA); + if (pos < 0) { + LOG_ERR("%s: Invalid Slave address with pos %d", dev->name, pos); + ret = -ENOSPC; + goto error; + } + cmd->buf = payload->targets.payloads[i].data; + + cmd->cmd_hi = + COMMAND_PORT_ARG_DATA_LEN(payload->targets.payloads[i].data_len) | + COMMAND_PORT_TRANSFER_ARG; + cmd->cmd_lo = COMMAND_PORT_CP | COMMAND_PORT_DEV_INDEX(pos) | + COMMAND_PORT_ROC | COMMAND_PORT_CMD(payload->ccc.id); + /* last command queue with multiple targets must have TOC set */ + if (i == (payload->targets.num_targets - 1)) { + cmd->cmd_lo |= COMMAND_PORT_TOC; + } + /* If there is a defining byte for direct CCC */ + if (payload->ccc.data_len == 1) { + cmd->cmd_lo |= COMMAND_PORT_DBP; + cmd->cmd_hi |= COMMAND_PORT_ARG_DB(payload->ccc.data[0]); + } else if (payload->ccc.data_len > 1) { + LOG_ERR("%s: direct CCCs defining byte >1", dev->name); + ret = -EINVAL; + goto error; + } + + if (payload->targets.payloads[i].rnw) { + cmd->cmd_lo |= COMMAND_PORT_READ_TRANSFER; + cmd->rx_len = payload->targets.payloads[i].data_len; + } else { + cmd->tx_len = payload->targets.payloads[i].data_len; + } + } + } + + start_xfer(dev); + + ret = k_sem_take(&data->sem_xfer, K_MSEC(1000)); + if (ret) { + LOG_ERR("%s: Semaphore err (%d)", dev->name, ret); + goto error; + } + + /* the only way data_len would not equal num_xfer would be if an abort happened */ + payload->ccc.num_xfer = payload->ccc.data_len; + for (i = 0; i < xfer->ncmds; i++) { + /* if this is a direct ccc, then write back the number of bytes tx or rx */ + if (!i3c_ccc_is_payload_broadcast(payload)) { + payload->targets.payloads[i].num_xfer = payload->targets.payloads[i].rnw + ? xfer->cmds[i].rx_len + : xfer->cmds[i].tx_len; + } + if (xfer->cmds[i].rx_len && !xfer->cmds[i].error) { + read_rx_fifo(dev, xfer->cmds[i].buf, xfer->cmds[i].rx_len); + } + } + + ret = xfer->ret; +error: + k_mutex_unlock(&data->mt); + + return ret; +} + +/** + * @brief Add a slave device from Dynamic Address Assignment (DAA) information. + * + * This function adds a slave device to the I3C controller based on the Dynamic + * Address Assignment (DAA) information at the specified position. It retrieves + * the dynamic address, PID (Provisional ID), and additional device characteristics + * from the corresponding tables and associates the device with a registered device + * descriptor if the PID is known. + * + * @param dev Pointer to the I3C device structure. + * @param pos Position of the device in the DAA and DCT tables. + * + * @return 0 on success, or a negative error code on failure. + */ +static int add_slave_from_daa(const struct device *dev, int32_t pos) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + uint32_t tmp; + uint64_t pid; + uint8_t dyn_addr; + + /* retrieve dynamic address assigned */ + tmp = sys_read32(config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos)); + dyn_addr = (((tmp) & GENMASK(22, 16)) >> 16); + + /* retrieve pid */ + tmp = sys_read32(config->regs + DEV_CHAR_TABLE_LOC1(data->dctstartaddr, pos)); + pid = ((uint64_t)DEV_CHAR_TABLE_MSB_PID(tmp) << 16) + (DEV_CHAR_TABLE_LSB_PID(tmp) << 16); + tmp = sys_read32(config->regs + DEV_CHAR_TABLE_LOC2(data->dctstartaddr, pos)); + pid |= DEV_CHAR_TABLE_LSB_PID(tmp); + + /* lookup known pids */ + const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid); + struct i3c_device_desc *target = i3c_device_find(dev, &i3c_id); + + if (target == NULL) { + LOG_INF("%s: PID 0x%012llx is not in registered device " + "list, given DA 0x%02x", + dev->name, pid, dyn_addr); + } else { + target->dynamic_addr = dyn_addr; + tmp = sys_read32(config->regs + DEV_CHAR_TABLE_LOC3(data->dctstartaddr, pos)); + target->bcr = DEV_CHAR_TABLE_BCR(tmp); + target->dcr = DEV_CHAR_TABLE_DCR(tmp); + + LOG_DBG("%s: PID 0x%012llx assigned dynamic address 0x%02x", dev->name, pid, + dyn_addr); + } + i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, dyn_addr); + + return 0; +} + +/** + * @brief Perform Dynamic Address Assignment. + * + * @see i3c_do_daa + * + * @param dev Pointer to controller device driver instance. + * + * @return @see i3c_do_daa + */ +static int dw_i3c_do_daa(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_xfer *xfer = &data->xfer; + struct dw_i3c_cmd *cmd; + uint32_t olddevs, newdevs; + uint8_t p, idx, last_addr = 0; + int32_t pos, addr, ret; + uint32_t present_state; + + present_state = sys_read32(config->regs + PRESENT_STATE); + if (!(present_state & PRESENT_STATE_CURRENT_MASTER)) { + return -EACCES; + } + + olddevs = ~(data->free_pos); + + /* Prepare DAT before launching DAA. */ + for (pos = 0; pos < data->maxdevs; pos++) { + if (olddevs & BIT(pos)) { + continue; + } + + addr = i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots, + last_addr + 1); + if (addr == 0) { + return -ENOSPC; + } + + p = odd_parity(addr); + last_addr = addr; + addr |= (p << 7); + sys_write32(DEV_ADDR_TABLE_DYNAMIC_ADDR(addr), + config->regs + DEV_ADDR_TABLE_LOC(data->datstartaddr, pos)); + } + + pos = get_free_pos(data->free_pos); + if (pos < 0) { + LOG_ERR("%s: find free pos failed", dev->name); + return -ENOSPC; + } + + ret = k_mutex_lock(&data->mt, K_MSEC(1000)); + if (ret) { + LOG_ERR("%s: Mutex err (%d)", dev->name, ret); + return ret; + } + memset(xfer, 0, sizeof(struct dw_i3c_xfer)); + + xfer->ncmds = 1; + xfer->ret = -1; + + cmd = &xfer->cmds[0]; + cmd->cmd_hi = COMMAND_PORT_TRANSFER_ARG; + cmd->cmd_lo = COMMAND_PORT_TOC | COMMAND_PORT_ROC | + COMMAND_PORT_DEV_COUNT(data->maxdevs - pos) | COMMAND_PORT_DEV_INDEX(pos) | + COMMAND_PORT_CMD(I3C_CCC_ENTDAA) | COMMAND_PORT_ADDR_ASSGN_CMD; + + start_xfer(dev); + ret = k_sem_take(&data->sem_xfer, K_MSEC(1000)); + if (ret) { + LOG_ERR("%s: Semaphore err (%d)", dev->name, ret); + k_mutex_unlock(&data->mt); + return ret; + } + + k_mutex_unlock(&data->mt); + + if (data->maxdevs == cmd->rx_len) { + newdevs = 0; + } else { + newdevs = GENMASK(data->maxdevs - cmd->rx_len - 1, 0); + } + newdevs &= ~olddevs; + + for (pos = find_lsb_set(newdevs); pos <= find_msb_set(newdevs); pos++) { + idx = pos - 1; + if (newdevs & BIT(idx)) { + add_slave_from_daa(dev, idx); + } + } + + return 0; +} + +static void dw_i3c_enable_controller(const struct dw_i3c_config *config, bool enable) +{ + uint32_t reg = sys_read32(config->regs + DEVICE_CTRL); + + if (enable) { + reg |= DEV_CTRL_ENABLE; + } else { + reg &= ~DEV_CTRL_ENABLE; + } + + sys_write32(reg, config->regs + DEVICE_CTRL); +} + +/** + * @brief Get configuration of the I3C hardware. + * + * This provides a way to get the current configuration of the I3C hardware. + * + * This can return cached config or probed hardware parameters, but it has to + * be up to date with current configuration. + * + * @param[in] dev Pointer to controller device driver instance. + * @param[in] type Type of configuration parameters being passed + * in @p config. + * @param[in,out] config Pointer to the configuration parameters. + * + * Note that if @p type is @c I3C_CONFIG_CUSTOM, @p config must contain + * the ID of the parameter to be retrieved. + * + * @retval 0 If successful. + * @retval -EIO General Input/Output errors. + * @retval -ENOSYS If not implemented. + */ +static int dw_i3c_config_get(const struct device *dev, enum i3c_config_type type, void *config) +{ + const struct dw_i3c_config *dev_config = dev->config; + struct dw_i3c_data *data = dev->data; + int ret = 0; + + if (type == I3C_CONFIG_CONTROLLER) { + (void)memcpy(config, &data->common.ctrl_config, sizeof(data->common.ctrl_config)); + } else if (type == I3C_CONFIG_TARGET) { + struct i3c_config_target *target_config = config; + uint32_t reg; + + reg = sys_read32(dev_config->regs + SLV_MAX_LEN); + target_config->max_read_len = SLV_MAX_LEN_MRL(reg); + target_config->max_write_len = SLV_MAX_LEN_MWL(reg); + + reg = sys_read32(dev_config->regs + DEVICE_ADDR); + if (reg & DEVICE_ADDR_STATIC_ADDR_VALID) { + target_config->static_addr = DEVICE_ADDR_STATIC(reg); + } else { + target_config->static_addr = 0x00; + } + + reg = sys_read32(dev_config->regs + SLV_CHAR_CTRL); + target_config->bcr = SLV_CHAR_CTRL_BCR(reg); + target_config->dcr = SLV_CHAR_CTRL_DCR(reg); + target_config->supported_hdr = SLV_CHAR_CTRL_HDR_CAP(reg); + + reg = sys_read32(dev_config->regs + SLV_MIPI_ID_VALUE); + target_config->pid = ((uint64_t)reg) << 32; + target_config->pid_random = (bool)!!(reg & SLV_MIPI_ID_VALUE_SLV_PROV_ID_SEL); + reg = sys_read32(dev_config->regs + SLV_PID_VALUE); + target_config->pid |= reg; + + if (!(sys_read32(dev_config->regs + PRESENT_STATE) & + PRESENT_STATE_CURRENT_MASTER)) { + target_config->enable = true; + } else { + target_config->enable = false; + } + } else { + return -EINVAL; + } + + return ret; +} + +/** + * @brief Configure I3C hardware. + * + * @param dev Pointer to controller device driver instance. + * @param type Type of configuration parameters being passed + * in @p config. + * @param config Pointer to the configuration parameters. + * + * @retval 0 If successful. + * @retval -EINVAL If invalid configure parameters. + * @retval -EIO General Input/Output errors. + * @retval -ENOSYS If not implemented. + */ +static int dw_i3c_configure(const struct device *dev, enum i3c_config_type type, void *config) +{ + const struct dw_i3c_config *dev_config = dev->config; + + if (type == I3C_CONFIG_CONTROLLER) { + /* struct i3c_config_controller *ctrl_cfg = config; */ + /* TODO: somehow determine i3c rate? snps is complicated */ + return -ENOTSUP; + } else if (type == I3C_CONFIG_TARGET) { + struct i3c_config_target *target_cfg = config; + uint32_t val; + + /* TODO: some how randomly generate pid */ + if (target_cfg->pid_random) { + return -EINVAL; + } + + val = SLV_MAX_LEN_MWL(target_cfg->max_write_len) | + (SLV_MAX_LEN_MRL(target_cfg->max_read_len) << 16); + sys_write32(val, dev_config->regs + SLV_MAX_LEN); + + /* set static address */ + val = sys_read32(dev_config->regs + DEVICE_ADDR); + /* if static address is set to 0x00, then disable static_addr_en */ + if (target_cfg->static_addr != 0x00) { + val |= DEVICE_ADDR_STATIC_ADDR_VALID; + } else { + val &= ~DEVICE_ADDR_STATIC_ADDR_VALID; + } + val &= ~DEVICE_ADDR_STATIC_MASK; + val |= DEVICE_ADDR_STATIC(target_cfg->static_addr); + sys_write32(val, dev_config->regs + DEVICE_ADDR); + + val = sys_read32(dev_config->regs + SLV_CHAR_CTRL); + val &= ~(SLV_CHAR_CTRL_BCR_MASK | SLV_CHAR_CTRL_DCR_MASK); + /* Bridge identifier, offline capable, ibi_payload, ibi_request_capable can not be + * written to in bcr + */ + val |= SLV_CHAR_CTRL_BCR(target_cfg->bcr); + val |= SLV_CHAR_CTRL_DCR(target_cfg->dcr) << 8; + /* HDR CAPs is not settable */ + sys_write32(val, dev_config->regs + SLV_CHAR_CTRL); + + val = sys_read32(dev_config->regs + SLV_MIPI_ID_VALUE); + val &= ~(SLV_MIPI_ID_VALUE_SLV_MIPI_MFG_ID_MASK | + SLV_MIPI_ID_VALUE_SLV_PROV_ID_SEL); + val |= (uint32_t)(target_cfg->pid >> 16); + sys_write32(val, dev_config->regs + SLV_MIPI_ID_VALUE); + + val = (uint32_t)(target_cfg->pid & 0xFFFFFFFF); + sys_write32(val, dev_config->regs + SLV_PID_VALUE); + } + + return 0; +} + +/** + * @brief Find a registered I3C target device. + * + * This returns the I3C device descriptor of the I3C device + * matching the incoming @p id. + * + * @param dev Pointer to controller device driver instance. + * @param id Pointer to I3C device ID. + * + * @return @see i3c_device_find. + */ +static struct i3c_device_desc *dw_i3c_device_find(const struct device *dev, + const struct i3c_device_id *id) +{ + const struct dw_i3c_config *config = dev->config; + + return i3c_dev_list_find(&config->common.dev_list, id); +} + +/** + * @brief Writes to the Target's TX FIFO + * + * The Synopsys I3C will then ACK read requests to it's TX FIFO from a + * Controller, if there is no tx cmd in cmd Q. Then it will NACK. + * + * @param dev Pointer to the device structure for an I3C controller + * driver configured in target mode. + * @param buf Pointer to the buffer + * @param len Length of the buffer + * + * @retval Total number of bytes written + * @retval -EACCES Not in Target Mode + * @retval -ENOSPC No space in Tx FIFO + */ +static int dw_i3c_target_tx_write(const struct device *dev, uint8_t *buf, uint16_t len, + uint8_t hdr_mode) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct dw_i3c_xfer *xfer = &data->xfer; + uint32_t present_state; + + /* check if we are in target mode */ + present_state = sys_read32(config->regs + PRESENT_STATE); + if (present_state & PRESENT_STATE_CURRENT_MASTER) { + return -EACCES; + } + + /* + * TODO: if len is greater than fifo size, then it will need to be written to based + * on the threshold interrupt + */ + if (len > (data->txfifodepth * BYTES_PER_DWORD)) { + return -ENOSPC; + } + + k_mutex_lock(&data->mt, K_FOREVER); + + if ((hdr_mode == 0) || (hdr_mode & data->common.ctrl_config.supported_hdr)) { + /* Write to CMD */ + memset(xfer, 0, sizeof(struct dw_i3c_xfer)); + xfer->ncmds = 1; + + /* TODO: write_tx_fifo needs to check that the fifo doesn't fill up */ + struct dw_i3c_cmd *cmd = &xfer->cmds[0]; + + cmd->cmd_hi = 0; + cmd->cmd_lo = COMMAND_PORT_TID(0) | COMMAND_PORT_ARG_DATA_LEN(len); + cmd->buf = buf; + cmd->tx_len = len; + + start_xfer(dev); + } else { + k_mutex_unlock(&data->mt); + LOG_ERR("%s: Unsupported HDR Mode %d", dev->name, hdr_mode); + return -ENOTSUP; + } + + k_mutex_unlock(&data->mt); + + /* return total bytes written */ + return (int)len; +} + +/** + * @brief Instructs the I3C Target device to register itself to the I3C Controller + * + * This routine instructs the I3C Target device to register itself to the I3C + * Controller via its parent controller's i3c_target_register() API. + * + * @param dev Pointer to target device driver instance. + * @param cfg Config struct with functions and parameters used by the I3C driver + * to send bus events + * + * @return @see i3c_device_find. + */ +static int dw_i3c_target_register(const struct device *dev, struct i3c_target_config *cfg) +{ + struct dw_i3c_data *data = dev->data; + + data->target_config = cfg; + return 0; +} + +/** + * @brief Unregisters the provided config as Target device + * + * This routine disables I3C target mode for the 'dev' I3C bus driver using + * the provided 'config' struct containing the functions and parameters + * to send bus events. + * + * @param dev Pointer to target device driver instance. + * @param cfg Config struct with functions and parameters used by the I3C driver + * to send bus events + * + * @return @see i3c_device_find. + */ +static int dw_i3c_target_unregister(const struct device *dev, struct i3c_target_config *cfg) +{ + /* no way to disable? maybe write DA to 0? */ + return 0; +} + +static int dw_i3c_init(const struct device *dev) +{ + const struct dw_i3c_config *config = dev->config; + struct dw_i3c_data *data = dev->data; + struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; + int ret; + uint32_t hw_capabilities; + uint32_t queue_capability; + uint32_t device_ctrl_ext; + + if (!device_is_ready(config->clock)) { + return -ENODEV; + } + + ret = clock_control_on(config->clock, NULL); + if (ret < 0) { + return ret; + } + +#ifdef CONFIG_I3C_USE_IBI + k_sem_init(&data->ibi_sts_sem, 0, 1); +#endif + k_sem_init(&data->sem_xfer, 0, 1); + k_mutex_init(&data->mt); + + data->mode = i3c_bus_mode(&config->common.dev_list); + + /* reset all */ + sys_write32(RESET_CTRL_ALL, config->regs + RESET_CTRL); + + /* get DAT, DCT pointer */ + data->datstartaddr = + DEVICE_ADDR_TABLE_ADDR(sys_read32(config->regs + DEVICE_ADDR_TABLE_POINTER)); + data->dctstartaddr = + DEVICE_CHAR_TABLE_ADDR(sys_read32(config->regs + DEV_CHAR_TABLE_POINTER)); + + /* get max devices based on table depth */ + data->maxdevs = + DEVICE_ADDR_TABLE_DEPTH(sys_read32(config->regs + DEVICE_ADDR_TABLE_POINTER)); + data->free_pos = GENMASK(data->maxdevs - 1, 0); + + /* get fifo sizes */ + queue_capability = sys_read32(config->regs + QUEUE_SIZE_CAPABILITY); + data->txfifodepth = QUEUE_SIZE_CAPABILITY_TX_BUF_DWORD_SIZE(queue_capability); + data->rxfifodepth = QUEUE_SIZE_CAPABILITY_RX_BUF_DWORD_SIZE(queue_capability); + data->cmdfifodepth = QUEUE_SIZE_CAPABILITY_CMD_BUF_DWORD_SIZE(queue_capability); + data->respfifodepth = QUEUE_SIZE_CAPABILITY_RESP_BUF_DWORD_SIZE(queue_capability); + data->ibififodepth = QUEUE_SIZE_CAPABILITY_IBI_BUF_DWORD_SIZE(queue_capability); + + /* get HDR capabilities */ + ctrl_config->supported_hdr = 0; + hw_capabilities = sys_read32(config->regs + HW_CAPABILITY); + if (hw_capabilities & HW_CAPABILITY_HDR_TS_EN) { + ctrl_config->supported_hdr |= I3C_MSG_HDR_TSP | I3C_MSG_HDR_TSL; + } + if (hw_capabilities & HW_CAPABILITY_HDR_DDR_EN) { + ctrl_config->supported_hdr |= I3C_MSG_HDR_DDR; + } + + /* if the boot condition starts as a target, then it's a secondary controller */ + device_ctrl_ext = sys_read32(config->regs + DEVICE_CTRL_EXTENDED); + if (DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE(device_ctrl_ext) & + DEVICE_CTRL_EXTENDED_DEV_OPERATION_MODE_SLAVE) { + ctrl_config->is_secondary = true; + } else { + ctrl_config->is_secondary = false; + } + + ret = init_scl_timing(dev); + if (ret != 0) { + return ret; + } + + enable_interrupts(dev); + + /* disable ibi */ + sys_write32(IBI_REQ_REJECT_ALL, config->regs + IBI_SIR_REQ_REJECT); + sys_write32(IBI_REQ_REJECT_ALL, config->regs + IBI_MR_REQ_REJECT); + + /* disable hot-join */ + sys_write32(sys_read32(config->regs + DEVICE_CTRL) | (DEV_CTRL_HOT_JOIN_NACK), + config->regs + DEVICE_CTRL); + + ret = i3c_addr_slots_init(dev); + if (ret != 0) { + return ret; + } + + dw_i3c_enable_controller(config, true); + + if (!(ctrl_config->is_secondary)) { + ret = set_controller_info(dev); + if (ret) { + return ret; + } + /* Perform bus initialization */ + ret = i3c_bus_init(dev, &config->common.dev_list); + /* Bus Initialization Complete, allow HJ ACKs */ + sys_write32(sys_read32(config->regs + DEVICE_CTRL) & ~(DEV_CTRL_HOT_JOIN_NACK), + config->regs + DEVICE_CTRL); + } + + return 0; +} + +static DEVICE_API(i3c, dw_i3c_api) = { + .i2c_api.transfer = dw_i3c_i2c_api_transfer, + + .configure = dw_i3c_configure, + .config_get = dw_i3c_config_get, + + .attach_i3c_device = dw_i3c_attach_device, + .reattach_i3c_device = dw_i3c_reattach_device, + .detach_i3c_device = dw_i3c_detach_device, + .attach_i2c_device = dw_i3c_i2c_attach_device, + .detach_i2c_device = dw_i3c_i2c_detach_device, + + .do_daa = dw_i3c_do_daa, + .do_ccc = dw_i3c_do_ccc, + + .i3c_device_find = dw_i3c_device_find, + + .i3c_xfers = dw_i3c_xfers, + + .target_tx_write = dw_i3c_target_tx_write, + .target_register = dw_i3c_target_register, + .target_unregister = dw_i3c_target_unregister, + +#ifdef CONFIG_I3C_USE_IBI + .ibi_hj_response = dw_i3c_controller_ibi_hj_response, + .ibi_enable = dw_i3c_controller_enable_ibi, + .ibi_disable = dw_i3c_controller_disable_ibi, + .ibi_raise = dw_i3c_target_ibi_raise, +#endif /* CONFIG_I3C_USE_IBI */ +}; + +#define I3C_DW_IRQ_HANDLER(n) \ + static void i3c_dw_irq_config_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), i3c_dw_irq, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } + +#define DEFINE_DEVICE_FN(n) \ + I3C_DW_IRQ_HANDLER(n) \ + static struct i3c_device_desc dw_i3c_device_array_##n[] = I3C_DEVICE_ARRAY_DT_INST(n); \ + static struct i3c_i2c_device_desc dw_i3c_i2c_device_array_##n[] = \ + I3C_I2C_DEVICE_ARRAY_DT_INST(n); \ + static struct dw_i3c_data dw_i3c_data_##n = { \ + .common.ctrl_config.scl.i3c = \ + DT_INST_PROP_OR(n, i3c_scl_hz, I3C_BUS_TYP_I3C_SCL_RATE), \ + .common.ctrl_config.scl.i2c = DT_INST_PROP_OR(n, i2c_scl_hz, 0), \ + }; \ + static const struct dw_i3c_config dw_i3c_cfg_##n = { \ + .regs = DT_INST_REG_ADDR(n), \ + .clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .od_thigh_max_ns = DT_INST_PROP(n, od_thigh_max_ns), \ + .od_tlow_min_ns = DT_INST_PROP(n, od_tlow_min_ns), \ + .irq_config_func = &i3c_dw_irq_config_##n, \ + .common.dev_list.i3c = dw_i3c_device_array_##n, \ + .common.dev_list.num_i3c = ARRAY_SIZE(dw_i3c_device_array_##n), \ + .common.dev_list.i2c = dw_i3c_i2c_device_array_##n, \ + .common.dev_list.num_i2c = ARRAY_SIZE(dw_i3c_i2c_device_array_##n), \ + }; \ + DEVICE_DT_INST_DEFINE(n, dw_i3c_init, NULL, &dw_i3c_data_##n, &dw_i3c_cfg_##n, \ + POST_KERNEL, CONFIG_I3C_CONTROLLER_INIT_PRIORITY, &dw_i3c_api); + +#define DT_DRV_COMPAT snps_designware_i3c +DT_INST_FOREACH_STATUS_OKAY(DEFINE_DEVICE_FN); diff --git a/drivers/i3c/i3c_i2c_mem_slab.c b/drivers/i3c/i3c_i2c_mem_slab.c new file mode 100644 index 0000000000000..472d39df76f48 --- /dev/null +++ b/drivers/i3c/i3c_i2c_mem_slab.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include +LOG_MODULE_DECLARE(i3c, CONFIG_I3C_LOG_LEVEL); + +K_MEM_SLAB_DEFINE(i3c_i2c_device_desc_pool, sizeof(struct i3c_i2c_device_desc), + CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS, 4); + +struct i3c_i2c_device_desc *i3c_i2c_device_desc_alloc(void) +{ + struct i3c_i2c_device_desc *desc; + + if (k_mem_slab_alloc(&i3c_i2c_device_desc_pool, (void **)&desc, K_NO_WAIT) == 0) { + memset(desc, 0, sizeof(struct i3c_i2c_device_desc)); + LOG_INF("I2C Device Desc allocated - %d free", + k_mem_slab_num_free_get(&i3c_i2c_device_desc_pool)); + } else { + LOG_WRN("No memory left for I2C descriptors"); + } + + return desc; +} + +void i3c_i2c_device_desc_free(struct i3c_i2c_device_desc *desc) +{ + k_mem_slab_free(&i3c_i2c_device_desc_pool, (void *)desc); + LOG_DBG("I2C Device Desc freed"); +} + +bool i3c_i2c_device_desc_in_pool(struct i3c_i2c_device_desc *desc) +{ + const char *p = (const char *)desc; + ptrdiff_t offset = p - i3c_i2c_device_desc_pool.buffer; + + return (offset >= 0) && + (offset < (i3c_i2c_device_desc_pool.info.block_size * + i3c_i2c_device_desc_pool.info.num_blocks)) && + ((offset % i3c_i2c_device_desc_pool.info.block_size) == 0); +} diff --git a/drivers/i3c/i3c_ibi_workq.c b/drivers/i3c/i3c_ibi_workq.c index 108f20f44e569..45cc1585b788a 100644 --- a/drivers/i3c/i3c_ibi_workq.c +++ b/drivers/i3c/i3c_ibi_workq.c @@ -86,6 +86,32 @@ int i3c_ibi_work_enqueue_target_irq(struct i3c_device_desc *target, return ret; } +int i3c_ibi_work_enqueue_controller_request(struct i3c_device_desc *target) +{ + sys_snode_t *node; + struct i3c_ibi_work *ibi_node; + int ret; + + node = sys_slist_get(&i3c_ibi_work_nodes_free); + if (node == NULL) { + ret = -ENOMEM; + goto out; + } + + ibi_node = (struct i3c_ibi_work *)node; + + ibi_node->type = I3C_IBI_CONTROLLER_ROLE_REQUEST; + ibi_node->target = target; + + ret = ibi_work_submit(ibi_node); + if (ret >= 0) { + ret = 0; + } + +out: + return ret; +} + int i3c_ibi_work_enqueue_hotjoin(const struct device *dev) { sys_snode_t *node; @@ -167,9 +193,13 @@ static void i3c_ibi_work_handler(struct k_work *work) payload = NULL; } - ret = ibi_node->target->ibi_cb(ibi_node->target, payload); - if ((ret != 0) && (ret != -EBUSY)) { - LOG_ERR("IBI work %p cb returns %d", ibi_node, ret); + if (ibi_node->target->ibi_cb) { + ret = ibi_node->target->ibi_cb(ibi_node->target, payload); + if ((ret != 0) && (ret != -EBUSY)) { + LOG_ERR("IBI work %p cb returns %d", ibi_node, ret); + } + } else { + LOG_ERR("No IBI callback for target %s", ibi_node->target->dev->name); } break; @@ -194,8 +224,11 @@ static void i3c_ibi_work_handler(struct k_work *work) break; case I3C_IBI_CONTROLLER_ROLE_REQUEST: - /* TODO: Add support for controller role request */ - __fallthrough; + ret = i3c_device_controller_handoff(ibi_node->target, true); + if (ret != 0) { + LOG_ERR("i3c_device_controller_handoff returns %d", ret); + } + break; default: /* Unknown IBI type: do nothing */ diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index 3c81dd0d22496..581c1d2d1c3bd 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -2090,10 +2090,13 @@ static int mcux_i3c_i2c_api_transfer(const struct device *dev, return ret; } -static const struct i3c_driver_api mcux_i3c_driver_api = { +static DEVICE_API(i3c, mcux_i3c_driver_api) = { .i2c_api.configure = mcux_i3c_i2c_api_configure, .i2c_api.transfer = mcux_i3c_i2c_api_transfer, .i2c_api.recover_bus = mcux_i3c_recover_bus, +#ifdef CONFIG_I2C_RTIO + .i2c_api.iodev_submit = i2c_iodev_submit_fallback, +#endif .configure = mcux_i3c_configure, .config_get = mcux_i3c_config_get, @@ -2111,6 +2114,10 @@ static const struct i3c_driver_api mcux_i3c_driver_api = { .ibi_enable = mcux_i3c_ibi_enable, .ibi_disable = mcux_i3c_ibi_disable, #endif + +#ifdef CONFIG_I3C_RTIO + .iodev_submit = i3c_iodev_submit_fallback, +#endif }; #define I3C_MCUX_DEVICE(id) \ diff --git a/drivers/i3c/i3c_mem_slab.c b/drivers/i3c/i3c_mem_slab.c new file mode 100644 index 0000000000000..2c80aa58418dd --- /dev/null +++ b/drivers/i3c/i3c_mem_slab.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include +LOG_MODULE_DECLARE(i3c, CONFIG_I3C_LOG_LEVEL); + +/* Generate Names */ +#define UNKNOWN_NAME_STR(i, _) \ + { \ + .name = "unknown-" STRINGIFY(i) \ + } +const struct device dummy_devs[] = { + LISTIFY(CONFIG_I3C_NUM_OF_DESC_MEM_SLABS, UNKNOWN_NAME_STR, (,)) }; + +K_MEM_SLAB_DEFINE(i3c_device_desc_pool, sizeof(struct i3c_device_desc), + CONFIG_I3C_NUM_OF_DESC_MEM_SLABS, 4); + +struct i3c_device_desc *i3c_device_desc_alloc(void) +{ + struct i3c_device_desc *desc; + + if (k_mem_slab_alloc(&i3c_device_desc_pool, (void **)&desc, K_NO_WAIT) == 0) { + memset(desc, 0, sizeof(struct i3c_device_desc)); + *(const struct device **)&desc->dev = + &dummy_devs[k_mem_slab_num_free_get(&i3c_device_desc_pool)]; + LOG_DBG("I3C Device Desc allocated - %d free", + k_mem_slab_num_free_get(&i3c_device_desc_pool)); + } else { + LOG_WRN("No memory left for I3C descriptors"); + } + + return desc; +} + +void i3c_device_desc_free(struct i3c_device_desc *desc) +{ + k_mem_slab_free(&i3c_device_desc_pool, (void *)desc); + LOG_DBG("I3C Device Desc freed"); +} + +bool i3c_device_desc_in_pool(struct i3c_device_desc *desc) +{ + const char *p = (const char *)desc; + ptrdiff_t offset = p - i3c_device_desc_pool.buffer; + + return (offset >= 0) && + (offset < (i3c_device_desc_pool.info.block_size * + i3c_device_desc_pool.info.num_blocks)) && + ((offset % i3c_device_desc_pool.info.block_size) == 0); +} diff --git a/drivers/i3c/i3c_npcx.c b/drivers/i3c/i3c_npcx.c index 11b4c1efe9e08..437e941c2e32c 100644 --- a/drivers/i3c/i3c_npcx.c +++ b/drivers/i3c/i3c_npcx.c @@ -2963,7 +2963,7 @@ static int npcx_i3c_init(const struct device *dev) return 0; } -static const struct i3c_driver_api npcx_i3c_driver_api = { +static DEVICE_API(i3c, npcx_i3c_driver_api) = { .configure = npcx_i3c_configure, .config_get = npcx_i3c_config_get, @@ -2986,6 +2986,10 @@ static const struct i3c_driver_api npcx_i3c_driver_api = { .ibi_raise = npcx_i3c_target_ibi_raise, #endif + +#ifdef CONFIG_I3C_RTIO + .iodev_submit = i3c_iodev_submit_fallback, +#endif }; #define DT_INST_TGT_PID_PROP_OR(id, prop, idx) \ diff --git a/drivers/i3c/i3c_rtio.c b/drivers/i3c/i3c_rtio.c new file mode 100644 index 0000000000000..60aaf2de9e81b --- /dev/null +++ b/drivers/i3c/i3c_rtio.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2023 Intel Corporation + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_I3C_LOG_LEVEL +#include +LOG_MODULE_REGISTER(i3c_rtio); + +const struct rtio_iodev_api i3c_iodev_api = { + .submit = i3c_iodev_submit, +}; + +struct rtio_sqe *i3c_rtio_copy(struct rtio *r, struct rtio_iodev *iodev, const struct i3c_msg *msgs, + uint8_t num_msgs) +{ + __ASSERT(num_msgs > 0, "Expecting at least one message to copy"); + + struct rtio_sqe *sqe = NULL; + + for (uint8_t i = 0; i < num_msgs; i++) { + sqe = rtio_sqe_acquire(r); + + if (sqe == NULL) { + rtio_sqe_drop_all(r); + return NULL; + } + + if (msgs[i].flags & I3C_MSG_READ) { + rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM, msgs[i].buf, msgs[i].len, + NULL); + } else { + rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM, msgs[i].buf, msgs[i].len, + NULL); + } + sqe->flags |= RTIO_SQE_TRANSACTION; + sqe->iodev_flags = + ((msgs[i].flags & I3C_MSG_STOP) ? RTIO_IODEV_I3C_STOP : 0) | + ((msgs[i].flags & I3C_MSG_RESTART) ? RTIO_IODEV_I3C_RESTART : 0) | + ((msgs[i].flags & I3C_MSG_HDR) ? RTIO_IODEV_I3C_HDR : 0) | + ((msgs[i].flags & I3C_MSG_NBCH) ? RTIO_IODEV_I3C_NBCH : 0) | + RTIO_IODEV_I3C_HDR_MODE_SET(msgs[i].hdr_mode) | + RTIO_IODEV_I3C_HDR_CMD_CODE_SET(msgs[i].hdr_cmd_code); + } + + sqe->flags &= ~RTIO_SQE_TRANSACTION; + + return sqe; +} + +void i3c_rtio_init(struct i3c_rtio *ctx) +{ + k_sem_init(&ctx->lock, 1, 1); + mpsc_init(&ctx->io_q); + ctx->txn_curr = NULL; + ctx->txn_head = NULL; + ctx->iodev.api = &i3c_iodev_api; +} + +/** + * @private + * @brief Setup the next transaction (could be a single op) if needed + * + * @retval true New transaction to start with the hardware is setup + * @retval false No new transaction to start + */ +static bool i3c_rtio_next(struct i3c_rtio *ctx, bool completion) +{ + k_spinlock_key_t key = k_spin_lock(&ctx->slock); + + /* Already working on something, bail early */ + if (!completion && ctx->txn_head != NULL) { + k_spin_unlock(&ctx->slock, key); + return false; + } + + struct mpsc_node *next = mpsc_pop(&ctx->io_q); + + /* Nothing left to do */ + if (next == NULL) { + ctx->txn_head = NULL; + ctx->txn_curr = NULL; + k_spin_unlock(&ctx->slock, key); + return false; + } + + ctx->txn_head = CONTAINER_OF(next, struct rtio_iodev_sqe, q); + ctx->txn_curr = ctx->txn_head; + + k_spin_unlock(&ctx->slock, key); + + return true; +} + +bool i3c_rtio_complete(struct i3c_rtio *ctx, int status) +{ + /* On error bail */ + if (status < 0) { + rtio_iodev_sqe_err(ctx->txn_head, status); + return i3c_rtio_next(ctx, true); + } + + /* Try for next submission in the transaction */ + ctx->txn_curr = rtio_txn_next(ctx->txn_curr); + if (ctx->txn_curr) { + return true; + } + + rtio_iodev_sqe_ok(ctx->txn_head, status); + return i3c_rtio_next(ctx, true); +} +bool i3c_rtio_submit(struct i3c_rtio *ctx, struct rtio_iodev_sqe *iodev_sqe) +{ + mpsc_push(&ctx->io_q, &iodev_sqe->q); + return i3c_rtio_next(ctx, false); +} + +int i3c_rtio_transfer(struct i3c_rtio *ctx, struct i3c_msg *msgs, uint8_t num_msgs, + struct i3c_device_desc *desc) +{ + struct rtio_iodev *iodev = &ctx->iodev; + struct rtio *const r = ctx->r; + struct rtio_sqe *sqe = NULL; + struct rtio_cqe *cqe = NULL; + int res = 0; + + k_sem_take(&ctx->lock, K_FOREVER); + + ctx->i3c_desc = desc; + + sqe = i3c_rtio_copy(r, iodev, msgs, num_msgs); + if (sqe == NULL) { + LOG_ERR("Not enough submission queue entries"); + res = -ENOMEM; + goto out; + } + + rtio_submit(r, 1); + + cqe = rtio_cqe_consume(r); + while (cqe != NULL) { + res = cqe->result; + rtio_cqe_release(r, cqe); + cqe = rtio_cqe_consume(r); + } + +out: + k_sem_give(&ctx->lock); + return res; +} + +int i3c_rtio_configure(struct i3c_rtio *ctx, enum i3c_config_type type, void *config) +{ + struct rtio_iodev *iodev = &ctx->iodev; + struct rtio *const r = ctx->r; + struct rtio_sqe *sqe = NULL; + struct rtio_cqe *cqe = NULL; + int res = 0; + + k_sem_take(&ctx->lock, K_FOREVER); + + sqe = rtio_sqe_acquire(r); + if (sqe == NULL) { + LOG_ERR("Not enough submission queue entries"); + res = -ENOMEM; + goto out; + } + + sqe->op = RTIO_OP_I3C_CONFIGURE; + sqe->iodev = iodev; + sqe->i3c_config.type = type; + sqe->i3c_config.config = config; + + rtio_submit(r, 1); + + cqe = rtio_cqe_consume(r); + res = cqe->result; + rtio_cqe_release(r, cqe); + +out: + k_sem_give(&ctx->lock); + return res; +} + +int i3c_rtio_ccc(struct i3c_rtio *ctx, struct i3c_ccc_payload *payload) +{ + struct rtio_iodev *iodev = &ctx->iodev; + struct rtio *const r = ctx->r; + struct rtio_sqe *sqe = NULL; + struct rtio_cqe *cqe = NULL; + int res = 0; + + k_sem_take(&ctx->lock, K_FOREVER); + + sqe = rtio_sqe_acquire(r); + if (sqe == NULL) { + LOG_ERR("Not enough submission queue entries"); + res = -ENOMEM; + goto out; + } + + sqe->op = RTIO_OP_I3C_CCC; + sqe->iodev = iodev; + sqe->ccc_payload = payload; + + rtio_submit(r, 1); + + cqe = rtio_cqe_consume(r); + res = cqe->result; + rtio_cqe_release(r, cqe); + +out: + k_sem_give(&ctx->lock); + return res; +} + +int i3c_rtio_recover(struct i3c_rtio *ctx) +{ + struct rtio_iodev *iodev = &ctx->iodev; + struct rtio *const r = ctx->r; + struct rtio_sqe *sqe = NULL; + struct rtio_cqe *cqe = NULL; + int res = 0; + + k_sem_take(&ctx->lock, K_FOREVER); + + sqe = rtio_sqe_acquire(r); + if (sqe == NULL) { + LOG_ERR("Not enough submission queue entries"); + res = -ENOMEM; + goto out; + } + + sqe->op = RTIO_OP_I3C_RECOVER; + sqe->iodev = iodev; + + rtio_submit(r, 1); + + cqe = rtio_cqe_consume(r); + res = cqe->result; + rtio_cqe_release(r, cqe); + +out: + k_sem_give(&ctx->lock); + return res; +} diff --git a/drivers/i3c/i3c_rtio_default.c b/drivers/i3c/i3c_rtio_default.c new file mode 100644 index 0000000000000..b3cf6a309ef91 --- /dev/null +++ b/drivers/i3c/i3c_rtio_default.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2024 Google LLC + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +LOG_MODULE_DECLARE(i3c_rtio, CONFIG_I3C_LOG_LEVEL); + +static inline void i3c_msg_from_rx(const struct rtio_iodev_sqe *iodev_sqe, struct i3c_msg *msg) +{ + __ASSERT_NO_MSG(iodev_sqe->sqe.op == RTIO_OP_RX); + + msg->buf = iodev_sqe->sqe.rx.buf; + msg->len = iodev_sqe->sqe.rx.buf_len; + msg->flags = + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_STOP) ? I3C_MSG_STOP : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_RESTART) ? I3C_MSG_RESTART : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_HDR) ? I3C_MSG_HDR : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_NBCH) ? I3C_MSG_NBCH : 0) | + I3C_MSG_READ; +} + +static inline void i3c_msg_from_tx(const struct rtio_iodev_sqe *iodev_sqe, struct i3c_msg *msg) +{ + __ASSERT_NO_MSG(iodev_sqe->sqe.op == RTIO_OP_TX); + + msg->buf = (uint8_t *)iodev_sqe->sqe.tx.buf; + msg->len = iodev_sqe->sqe.tx.buf_len; + msg->flags = + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_STOP) ? I3C_MSG_STOP : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_RESTART) ? I3C_MSG_RESTART : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_HDR) ? I3C_MSG_HDR : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_NBCH) ? I3C_MSG_NBCH : 0) | + I3C_MSG_WRITE; +} + +static inline void i3c_msg_from_tiny_tx(const struct rtio_iodev_sqe *iodev_sqe, struct i3c_msg *msg) +{ + __ASSERT_NO_MSG(iodev_sqe->sqe.op == RTIO_OP_TINY_TX); + + msg->buf = (uint8_t *)iodev_sqe->sqe.tiny_tx.buf; + msg->len = iodev_sqe->sqe.tiny_tx.buf_len; + msg->flags = + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_STOP) ? I3C_MSG_STOP : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_RESTART) ? I3C_MSG_RESTART : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_HDR) ? I3C_MSG_HDR : 0) | + ((iodev_sqe->sqe.iodev_flags & RTIO_IODEV_I3C_NBCH) ? I3C_MSG_NBCH : 0) | + I3C_MSG_WRITE; +} + +void i3c_iodev_submit_work_handler(struct rtio_iodev_sqe *txn_first) +{ + const struct i3c_iodev_data *data = + (const struct i3c_iodev_data *)txn_first->sqe.iodev->data; + struct i3c_device_desc *desc; + + LOG_DBG("Sync RTIO work item for: %p", (void *)txn_first); + uint32_t num_msgs = 0; + int rc = 0; + struct rtio_iodev_sqe *txn_last = txn_first; + + /* TODO: there really needs to be a compile time way to get the i3c_device_desc */ + desc = i3c_device_find(data->bus, &data->dev_id); + if (!desc) { + LOG_ERR("Cannot find I3C device descriptor"); + rc = -ENODEV; + rtio_iodev_sqe_err(txn_first, rc); + return; + } + + /* Allocate the i3c_msg's on the stack, to do so + * the count of messages needs to be determined. + */ + do { + switch (txn_last->sqe.op) { + case RTIO_OP_RX: + case RTIO_OP_TX: + case RTIO_OP_TINY_TX: + num_msgs++; + break; + default: + LOG_ERR("Invalid op code %d for submission %p", txn_last->sqe.op, + (void *)&txn_last->sqe); + rc = -EIO; + break; + } + txn_last = rtio_txn_next(txn_last); + } while (rc == 0 && txn_last != NULL); + + if (rc != 0) { + rtio_iodev_sqe_err(txn_first, rc); + return; + } + + /* Allocate msgs on the stack, MISRA doesn't like VLAs so we need a statically + * sized array here. It's pretty unlikely we have more than 4 i3c messages + * in a transaction as we typically would only have 2, one to write a + * register address, and another to read/write the register into an array + */ + if (num_msgs > CONFIG_I3C_RTIO_FALLBACK_MSGS) { + LOG_ERR("At most CONFIG_I3C_RTIO_FALLBACK_MSGS" + " submissions in a transaction are" + " allowed in the default handler"); + rtio_iodev_sqe_err(txn_first, -ENOMEM); + return; + } + struct i3c_msg msgs[CONFIG_I3C_RTIO_FALLBACK_MSGS]; + + rc = 0; + txn_last = txn_first; + + /* Copy the transaction into the stack allocated msgs */ + for (int i = 0; i < num_msgs; i++) { + switch (txn_last->sqe.op) { + case RTIO_OP_RX: + i3c_msg_from_rx(txn_last, &msgs[i]); + break; + case RTIO_OP_TX: + i3c_msg_from_tx(txn_last, &msgs[i]); + break; + case RTIO_OP_TINY_TX: + i3c_msg_from_tiny_tx(txn_last, &msgs[i]); + break; + default: + rc = -EIO; + break; + } + + txn_last = rtio_txn_next(txn_last); + } + + if (rc == 0) { + __ASSERT_NO_MSG(num_msgs > 0); + + rc = i3c_transfer(desc, msgs, num_msgs); + } + + if (rc != 0) { + rtio_iodev_sqe_err(txn_first, rc); + } else { + rtio_iodev_sqe_ok(txn_first, 0); + } +} + +void i3c_iodev_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + LOG_DBG("Executing fallback for dev: %p, sqe: %p", (void *)dev, (void *)iodev_sqe); + + struct rtio_work_req *req = rtio_work_req_alloc(); + + if (req == NULL) { + rtio_iodev_sqe_err(iodev_sqe, -ENOMEM); + return; + } + + rtio_work_req_submit(req, iodev_sqe, i3c_iodev_submit_work_handler); +} diff --git a/drivers/i3c/i3c_shell.c b/drivers/i3c/i3c_shell.c index 569cf5571eb67..95ba3f1c117ff 100644 --- a/drivers/i3c/i3c_shell.c +++ b/drivers/i3c/i3c_shell.c @@ -82,6 +82,8 @@ struct i3c_ctrl { DT_FOREACH_STATUS_OKAY(cdns_i3c, I3C_CTRL_FN) DT_FOREACH_STATUS_OKAY(nuvoton_npcx_i3c, I3C_CTRL_FN) DT_FOREACH_STATUS_OKAY(nxp_mcux_i3c, I3C_CTRL_FN) +DT_FOREACH_STATUS_OKAY(snps_designware_i3c, I3C_CTRL_FN) +DT_FOREACH_STATUS_OKAY(st_stm32_i3c, I3C_CTRL_FN) /* zephyr-keep-sorted-stop */ #define I3C_CTRL_LIST_ENTRY(node_id) \ @@ -96,6 +98,8 @@ const struct i3c_ctrl i3c_list[] = { DT_FOREACH_STATUS_OKAY(cdns_i3c, I3C_CTRL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(nuvoton_npcx_i3c, I3C_CTRL_LIST_ENTRY) DT_FOREACH_STATUS_OKAY(nxp_mcux_i3c, I3C_CTRL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(snps_designware_i3c, I3C_CTRL_LIST_ENTRY) + DT_FOREACH_STATUS_OKAY(st_stm32_i3c, I3C_CTRL_LIST_ENTRY) /* zephyr-keep-sorted-stop */ }; @@ -145,12 +149,12 @@ static struct i3c_device_desc *get_i3c_attached_desc_from_dev_name(const struct static int i3c_parse_args(const struct shell *sh, char **argv, const struct device **dev, const struct device **tdev, struct i3c_device_desc **desc) { - *dev = device_get_binding(argv[ARGV_DEV]); + *dev = shell_device_get_binding(argv[ARGV_DEV]); if (!*dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; } - *tdev = device_get_binding(argv[ARGV_TDEV]); + *tdev = shell_device_get_binding(argv[ARGV_TDEV]); if (!*tdev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]); return -ENODEV; @@ -173,7 +177,7 @@ static int cmd_i3c_info(const struct shell *sh, size_t argc, char **argv) struct i3c_i2c_device_desc *i2c_desc; bool found = false; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); @@ -182,7 +186,7 @@ static int cmd_i3c_info(const struct shell *sh, size_t argc, char **argv) data = (struct i3c_driver_data *)dev->data; if (argc == 3) { - tdev = device_get_binding(argv[ARGV_TDEV]); + tdev = shell_device_get_binding(argv[ARGV_TDEV]); if (!tdev) { shell_error(sh, "I3C: Target Device driver %s not found.", argv[ARGV_TDEV]); return -ENODEV; @@ -207,7 +211,9 @@ static int cmd_i3c_info(const struct shell *sh, size_t argc, char **argv) "\tmrl: 0x%04x\n" "\tmwl: 0x%04x\n" "\tmax_ibi: 0x%02x\n" - "\tgetcaps: 0x%02x; 0x%02x; 0x%02x; 0x%02x", + "\tcrhdly1: 0x%02x\n" + "\tgetcaps: 0x%02x; 0x%02x; 0x%02x; 0x%02x\n" + "\tcrcaps: 0x%02x; 0x%02x", desc->dev->name, (uint64_t)desc->pid, desc->static_addr, desc->dynamic_addr, #if defined(CONFIG_I3C_USE_GROUP_ADDR) @@ -217,9 +223,10 @@ static int cmd_i3c_info(const struct shell *sh, size_t argc, char **argv) desc->data_speed.maxwr, desc->data_speed.max_read_turnaround, desc->data_length.mrl, desc->data_length.mwl, - desc->data_length.max_ibi, + desc->data_length.max_ibi, desc->crhdly1, desc->getcaps.getcap1, desc->getcaps.getcap2, - desc->getcaps.getcap3, desc->getcaps.getcap4); + desc->getcaps.getcap3, desc->getcaps.getcap4, + desc->crcaps.crcaps1, desc->crcaps.crcaps2); found = true; break; } @@ -253,7 +260,9 @@ static int cmd_i3c_info(const struct shell *sh, size_t argc, char **argv) "\tmrl: 0x%04x\n" "\tmwl: 0x%04x\n" "\tmax_ibi: 0x%02x\n" - "\tgetcaps: 0x%02x; 0x%02x; 0x%02x; 0x%02x", + "\tcrhdly1: 0x%02x\n" + "\tgetcaps: 0x%02x; 0x%02x; 0x%02x; 0x%02x\n" + "\tcrcaps: 0x%02x; 0x%02x", desc->dev->name, (uint64_t)desc->pid, desc->static_addr, desc->dynamic_addr, #if defined(CONFIG_I3C_USE_GROUP_ADDR) @@ -263,9 +272,10 @@ static int cmd_i3c_info(const struct shell *sh, size_t argc, char **argv) desc->data_speed.maxwr, desc->data_speed.max_read_turnaround, desc->data_length.mrl, desc->data_length.mwl, - desc->data_length.max_ibi, desc->getcaps.getcap1, - desc->getcaps.getcap2, desc->getcaps.getcap3, - desc->getcaps.getcap4); + desc->data_length.max_ibi, desc->crhdly1, + desc->getcaps.getcap1, desc->getcaps.getcap2, + desc->getcaps.getcap3, desc->getcaps.getcap4, + desc->crcaps.crcaps1, desc->crcaps.crcaps2); } } else { shell_print(sh, "I3C: No devices found."); @@ -296,7 +306,7 @@ static int cmd_i3c_speed(const struct shell *sh, size_t argc, char **argv) uint32_t speed; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[1]); return -ENODEV; @@ -327,7 +337,7 @@ static int cmd_i3c_recover(const struct shell *sh, size_t argc, char **argv) const struct device *dev; int err; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[1]); return -ENODEV; @@ -357,12 +367,12 @@ static int i3c_write_from_buffer(const struct shell *sh, char *s_dev_name, char int ret; int i; - dev = device_get_binding(s_dev_name); + dev = shell_device_get_binding(s_dev_name); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", s_dev_name); return -ENODEV; } - tdev = device_get_binding(s_tdev_name); + tdev = shell_device_get_binding(s_tdev_name); if (!tdev) { shell_error(sh, "I3C: Device driver %s not found.", s_tdev_name); return -ENODEV; @@ -422,12 +432,12 @@ static int i3c_read_to_buffer(const struct shell *sh, char *s_dev_name, char *s_ int reg_addr; int ret; - dev = device_get_binding(s_dev_name); + dev = shell_device_get_binding(s_dev_name); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", s_dev_name); return -ENODEV; } - tdev = device_get_binding(s_tdev_name); + tdev = shell_device_get_binding(s_tdev_name); if (!tdev) { shell_error(sh, "I3C: Device driver %s not found.", s_dev_name); return -ENODEV; @@ -572,7 +582,7 @@ static int cmd_i3c_ccc_rstdaa(const struct shell *sh, size_t argc, char **argv) struct i3c_device_desc *desc; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -598,7 +608,7 @@ static int cmd_i3c_ccc_entdaa(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -614,7 +624,7 @@ static int cmd_i3c_ccc_setaasa(const struct shell *sh, size_t argc, char **argv) struct i3c_device_desc *desc; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -924,7 +934,7 @@ static int cmd_i3c_ccc_setmrl_bc(const struct shell *sh, size_t argc, char **arg struct i3c_ccc_mrl mrl; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -959,7 +969,7 @@ static int cmd_i3c_ccc_setmwl_bc(const struct shell *sh, size_t argc, char **arg struct i3c_ccc_mwl mwl; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -986,7 +996,7 @@ static int cmd_i3c_ccc_deftgts(const struct shell *sh, size_t argc, char **argv) const struct device *dev; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1013,7 +1023,7 @@ static int cmd_i3c_ccc_enttm(const struct shell *sh, size_t argc, char **argv) enum i3c_ccc_enttm_defbyte defbyte; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1030,6 +1040,43 @@ static int cmd_i3c_ccc_enttm(const struct shell *sh, size_t argc, char **argv) return ret; } +/* i3c ccc getacccr */ +static int cmd_i3c_ccc_getacccr(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev, *tdev; + struct i3c_device_desc *desc; + struct i3c_ccc_address handoff_address; + int ret; + + ret = i3c_parse_args(sh, argv, &dev, &tdev, &desc); + if (ret != 0) { + return ret; + } + + if (!i3c_device_is_controller_capable(desc)) { + shell_error(sh, "I3C: Not a Controller Capable Device"); + return -EINVAL; + } + + ret = i3c_ccc_do_getacccr(desc, &handoff_address); + if (ret < 0) { + shell_error(sh, "I3C: unable to send CCC GETACCCR."); + return ret; + } + + /* Verify Odd Parity and Correct Dynamic Address Reply */ + if ((i3c_odd_parity(handoff_address.addr >> 1) != (handoff_address.addr & BIT(0))) || + (handoff_address.addr >> 1 != desc->dynamic_addr)) { + shell_error(sh, "I3C: invalid returned address 0x%02x; expected 0x%02x", + handoff_address.addr, desc->dynamic_addr); + return -EIO; + } + + shell_print(sh, "I3C: Controller Handoff successful"); + + return ret; +} + /* i3c ccc rstact_bc */ static int cmd_i3c_ccc_rstact_bc(const struct shell *sh, size_t argc, char **argv) { @@ -1037,7 +1084,7 @@ static int cmd_i3c_ccc_rstact_bc(const struct shell *sh, size_t argc, char **arg enum i3c_ccc_rstact_defining_byte action; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1054,7 +1101,7 @@ static int cmd_i3c_ccc_rstact_bc(const struct shell *sh, size_t argc, char **arg return ret; } -/* i3c ccc rstact */ +/* i3c ccc rstact <"set"/"get"> */ static int cmd_i3c_ccc_rstact(const struct shell *sh, size_t argc, char **argv) { const struct device *dev, *tdev; @@ -1068,11 +1115,11 @@ static int cmd_i3c_ccc_rstact(const struct shell *sh, size_t argc, char **argv) return ret; } - action = strtol(argv[5], NULL, 16); + action = strtol(argv[4], NULL, 16); - if (strcmp(argv[4], "get") == 0) { + if (strcmp(argv[3], "get") == 0) { ret = i3c_ccc_do_rstact_fmt3(desc, action, &data); - } else if (strcmp(argv[4], "set") == 0) { + } else if (strcmp(argv[3], "set") == 0) { ret = i3c_ccc_do_rstact_fmt2(desc, action); } else { shell_error(sh, "I3C: invalid parameter"); @@ -1099,7 +1146,7 @@ static int cmd_i3c_ccc_enec_bc(const struct shell *sh, size_t argc, char **argv) struct i3c_ccc_events events; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1123,7 +1170,7 @@ static int cmd_i3c_ccc_disec_bc(const struct shell *sh, size_t argc, char **argv struct i3c_ccc_events events; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1195,7 +1242,7 @@ static int cmd_i3c_ccc_entas0_bc(const struct shell *sh, size_t argc, char **arg struct i3c_driver_data *data; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1218,7 +1265,7 @@ static int cmd_i3c_ccc_entas1_bc(const struct shell *sh, size_t argc, char **arg struct i3c_driver_data *data; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1241,7 +1288,7 @@ static int cmd_i3c_ccc_entas2_bc(const struct shell *sh, size_t argc, char **arg struct i3c_driver_data *data; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1264,7 +1311,7 @@ static int cmd_i3c_ccc_entas3_bc(const struct shell *sh, size_t argc, char **arg struct i3c_driver_data *data; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1455,6 +1502,7 @@ static int cmd_i3c_ccc_getcaps(const struct shell *sh, size_t argc, char **argv) } else if (defbyte == GETCAPS_FORMAT_2_CRCAPS) { shell_print(sh, "CRCAPS: 0x%02x; 0x%02x", caps.fmt2.crcaps[0], caps.fmt2.crcaps[1]); + memcpy(&desc->crcaps, &caps, sizeof(desc->crcaps)); } else if (defbyte == GETCAPS_FORMAT_2_VTCAPS) { shell_print(sh, "VTCAPS: 0x%02x; 0x%02x", caps.fmt2.vtcaps[0], caps.fmt2.vtcaps[1]); @@ -1480,13 +1528,13 @@ static int cmd_i3c_ccc_getvendor(const struct shell *sh, size_t argc, char **arg int err = 0; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; } - tdev = device_get_binding(argv[ARGV_TDEV]); + tdev = shell_device_get_binding(argv[ARGV_TDEV]); if (!tdev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]); return -ENODEV; @@ -1534,13 +1582,13 @@ static int cmd_i3c_ccc_setvendor(const struct shell *sh, size_t argc, char **arg int ret; int i; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; } - tdev = device_get_binding(argv[ARGV_TDEV]); + tdev = shell_device_get_binding(argv[ARGV_TDEV]); if (!tdev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]); return -ENODEV; @@ -1583,7 +1631,7 @@ static int cmd_i3c_ccc_setvendor_bc(const struct shell *sh, size_t argc, char ** int ret; int i; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1618,7 +1666,7 @@ static int cmd_i3c_ccc_setbuscon(const struct shell *sh, size_t argc, char **arg int ret; int i; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1688,6 +1736,7 @@ static int cmd_i3c_ccc_getmxds(const struct shell *sh, size_t argc, char **argv) desc->data_speed.max_read_turnaround = sys_get_le24(&mxds.fmt3.wrrdturn[2]); } else if (defbyte == GETMXDS_FORMAT_3_CRHDLY) { shell_print(sh, "CRHDLY1: 0x%02x", mxds.fmt3.crhdly1); + desc->crhdly1 = mxds.fmt3.crhdly1; } } else { shell_print(sh, "GETMXDS: maxwr 0x%02x; maxrd 0x%02x; maxrdturn 0x%06x", @@ -1707,12 +1756,12 @@ static int cmd_i3c_attach(const struct shell *sh, size_t argc, char **argv) struct i3c_device_desc *desc; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; } - tdev = device_get_binding(argv[ARGV_TDEV]); + tdev = shell_device_get_binding(argv[ARGV_TDEV]); if (!tdev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_TDEV]); return -ENODEV; @@ -1781,7 +1830,7 @@ static int cmd_i3c_i2c_attach(const struct shell *sh, size_t argc, char **argv) uint16_t addr = 0; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1808,7 +1857,7 @@ static int cmd_i3c_i2c_detach(const struct shell *sh, size_t argc, char **argv) uint16_t addr = 0; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1857,7 +1906,7 @@ static int cmd_i3c_i2c_scan(const struct shell *sh, size_t argc, char **argv) enum i3c_addr_slot_status slot; uint8_t cnt = 0, first = 0x04, last = 0x77; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); @@ -1927,6 +1976,39 @@ static int cmd_i3c_i2c_scan(const struct shell *sh, size_t argc, char **argv) } #ifdef CONFIG_I3C_USE_IBI +/* i3c ibi hj_response <"ack"/"nack"> */ +static int cmd_i3c_ibi_hj_response(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + bool ack; + int ret; + + dev = device_get_binding(argv[ARGV_DEV]); + if (!dev) { + shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); + return -ENODEV; + } + + if (strcmp(argv[2], "ack") == 0) { + ack = true; + } else if (strcmp(argv[2], "nack") == 0) { + ack = false; + } else { + shell_error(sh, "I3C: invalid parameter"); + return -EINVAL; + } + + ret = i3c_ibi_hj_response(dev, ack); + if (ret != 0) { + shell_error(sh, "I3C: Unable to set IBI HJ Response"); + return ret; + } + + shell_print(sh, "I3C: Set IBI HJ Response"); + + return 0; +} + /* i3c ibi hj */ static int cmd_i3c_ibi_hj(const struct shell *sh, size_t argc, char **argv) { @@ -1934,7 +2016,7 @@ static int cmd_i3c_ibi_hj(const struct shell *sh, size_t argc, char **argv) struct i3c_ibi request; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1959,7 +2041,7 @@ static int cmd_i3c_ibi_cr(const struct shell *sh, size_t argc, char **argv) struct i3c_ibi request; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -1987,7 +2069,7 @@ static int cmd_i3c_ibi_tir(const struct shell *sh, size_t argc, char **argv) int ret; uint8_t i; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "I3C: Device driver %s not found.", argv[ARGV_DEV]); return -ENODEV; @@ -2106,6 +2188,10 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_i3c_device_name, i3c_device_name_get); /* L2 I3C IBI Shell Commands*/ SHELL_STATIC_SUBCMD_SET_CREATE( sub_i3c_ibi_cmds, + SHELL_CMD_ARG(hj_response, &dsub_i3c_device_name, + "Set IBI HJ Response\n" + "Usage: ibi hj_response <\"ack\"/\"nack\">", + cmd_i3c_ibi_hj_response, 3, 0), SHELL_CMD_ARG(hj, &dsub_i3c_device_name, "Send IBI HJ\n" "Usage: ibi hj ", @@ -2225,6 +2311,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE( "Send CCC RSTACT\n" "Usage: ccc rstact <\"set\"/\"get\"> ", cmd_i3c_ccc_rstact, 5, 0), + SHELL_CMD_ARG(getacccr, &dsub_i3c_device_attached_name, + "Send CCC GETACCCR\n" + "Usage: ccc getacccr ", + cmd_i3c_ccc_getacccr, 3, 0), SHELL_CMD_ARG(rstact_bc, &dsub_i3c_device_name, "Send CCC RSTACT BC\n" "Usage: ccc rstact_bc ", diff --git a/drivers/i3c/i3c_stm32.c b/drivers/i3c/i3c_stm32.c new file mode 100644 index 0000000000000..eb5525e4a7541 --- /dev/null +++ b/drivers/i3c/i3c_stm32.c @@ -0,0 +1,2210 @@ +/* + * Copyright (c) 2024 EXALT Technologies. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_I3C_STM32_DMA +#include +#include +#endif +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(i3c_stm32, CONFIG_I3C_LOG_LEVEL); + +#define DT_DRV_COMPAT st_stm32_i3c + +#define STM32_I3C_SCLH_I2C_MIN_FM_NS 600ull +#define STM32_I3C_SCLH_I2C_MIN_FMP_NS 260ull +#define STM32_I3C_SCLL_OD_MIN_FM_NS 1320ull +#define STM32_I3C_SCLL_OD_MIN_FMP_NS 500ull +#define STM32_I3C_SCLL_OD_MIN_I3C_NS 200ull + +#define STM32_I3C_SCLL_PP_MIN_NS 32ull +#define STM32_I3C_SCLH_I3C_MIN_NS 32ull + +#define STM32_I3C_TBUF_FMP_MIN_NS 500.0 +#define STM32_I3C_TBUF_FM_MIN_NS 1300.0 +#define STM32_I3C_TCAS_MIN_NS 38.4 + +#define STM32_I3C_TRANSFER_TIMEOUT K_MSEC(100) + +#ifdef CONFIG_I3C_STM32_DMA +K_HEAP_DEFINE(stm32_i3c_fifo_heap, CONFIG_I3C_STM32_DMA_FIFO_HEAP_SIZE); +#endif + +typedef void (*irq_config_func_t)(const struct device *port); + +enum i3c_stm32_sf_state { + STM32_I3C_SF_DAA, /* Dynamic addressing state */ + STM32_I3C_SF_CCC, /* First part of CCC command state*/ + STM32_I3C_SF_CCC_P2, /* Second part of CCC command state (used for direct commands)*/ + STM32_I3C_SF, /* Private msg state */ + STM32_I2C_SF, /* I2C legacy msg state */ + STM32_I3C_SF_IDLE, /* Idle bus state */ + STM32_I3C_SF_ERR, /* Error state */ + STM32_I3C_SF_INVAL, /* Invalid state */ +}; + +enum i3c_stm32_msg_state { + STM32_I3C_MSG_DAA, /* Dynamic addressing state */ + STM32_I3C_MSG_CCC, /* First part of CCC command state*/ + STM32_I3C_MSG_CCC_P2, /* Second part of CCC command state (used for direct commands)*/ + STM32_I3C_MSG, /* Private msg state */ + STM32_I3C_MSG_IDLE, /* Idle bus state */ + STM32_I3C_MSG_ERR, /* Error state */ + STM32_I3C_MSG_INVAL, /* Invalid state */ +}; + +#ifdef CONFIG_I3C_STM32_DMA +struct i3c_stm32_dma_stream { + const struct device *dma_dev; + uint32_t dma_channel; + struct dma_config dma_cfg; + uint8_t priority; + bool src_addr_increment; + bool dst_addr_increment; + int fifo_threshold; + struct dma_block_config blk_cfg; +}; +#endif + +/* Struct to hold the information about the current message on the bus */ +struct i3c_stm32_msg { + uint8_t target_addr; /* Current target xfer address */ + struct i3c_msg *i3c_msg_ptr; /* Pointer to the current private message to send on the bus */ + struct i3c_msg *i3c_msg_ctrl_ptr; /* Pointer to the private message that will be used by the + * control FIFO + */ + struct i3c_msg *i3c_msg_status_ptr; /* Pointer to the private message that will be used by + * the status FIFO + */ + struct i2c_msg *i2c_msg_ptr; /* Pointer to the current legacy message to send on the bus */ + struct i2c_msg *i2c_msg_ctrl_ptr; /* Pointer to the I2C legavy message that will be used by + * the control FIFO + */ + size_t num_msgs; /* Number of messages */ + size_t ctrl_msg_idx; /* Current control message index */ + size_t status_msg_idx; /* Current status message index */ + size_t xfer_msg_idx; /* Current trasnfer message index */ + size_t xfer_offset; /* Current message transfer offset */ + uint32_t msg_type; /* Either LL_I3C_CONTROLLER_MTYPE_PRIVATE or + * LL_I3C_CONTROLLER_MTYPE_LEGACY_I2C + */ +}; + +struct i3c_stm32_config { + struct i3c_driver_config drv_cfg; /* I3C driver config */ + I3C_TypeDef *i3c; /* Pointer to I3C module base addr */ + irq_config_func_t irq_config_func; /* IRQ config function */ + const struct stm32_pclken *pclken; /* Pointer to peripheral clock configuration */ + const struct pinctrl_dev_config *pcfg; /* Pointer to pin control configuration */ +}; + +struct i3c_stm32_data { + struct i3c_driver_data drv_data; /* I3C driver data */ + enum i3c_stm32_msg_state msg_state; /* Current I3C bus state */ + enum i3c_stm32_sf_state sf_state; /* Current I3C status FIFO state */ + struct i3c_ccc_payload *ccc_payload; /* Current CCC message payload */ + struct i3c_ccc_target_payload * + ccc_target_payload; /* Current target addressed by 2nd part of direct CCC command */ + struct i3c_ccc_target_payload + *ccc_target_payload_sf; /* Current target addressed + * by 2nd part of direct CCC command used by the + status FIFO + */ + size_t ccc_target_idx; /* Current target index, used for filling C-FIFO */ + struct k_sem device_sync_sem; /* Sync between device communication messages */ + struct k_mutex bus_mutex; /* Sync between transfers */ + struct i3c_stm32_msg curr_msg; + uint8_t target_addr; /* Current target xfer address */ + uint8_t num_msgs; /* Number of messages to send on bus */ +#ifdef CONFIG_I3C_STM32_DMA + struct i3c_stm32_dma_stream dma_rx; /* RX DMA channel config */ + struct i3c_stm32_dma_stream dma_tx; /* TX DMA channel config */ + struct i3c_stm32_dma_stream dma_tc; /* Control FIFO DMA channel config */ + struct i3c_stm32_dma_stream dma_rs; /* Status FIFO DMA channel config */ + uint32_t *status_fifo; /* Pointer to the allocated region for status FIFO words */ + uint32_t *control_fifo; /* Pointer to the allocated region for control FIFO words */ + size_t fifo_len; /* The size in bytes for the allocated region for each FIFO */ +#endif + uint64_t pid; /* Current DAA target PID */ + size_t daa_rx_rcv; /* Number of RX bytes received during DAA */ + uint8_t target_id; /* Target id */ +#ifdef CONFIG_I3C_USE_IBI + uint32_t ibi_payload; /* Received ibi payload */ + uint32_t ibi_payload_size; /* Received payload size */ + uint32_t ibi_target_addr; /* Received target dynamic address */ + struct { + uint8_t addr[4]; /* List of target addresses */ + uint8_t num_addr; /* Number of valid addresses */ + } ibi; + struct k_sem ibi_lock_sem; /* Semaphore used for ibi requests */ + bool hj_pm_lock; /* Used as flag for setting pm */ +#endif +}; +/** + * Determine I3C bus mode from the i2c devices on the bus. + * + * Reads the LVR of all I2C devices and returns the I3C bus + * Mode. + * + * @param dev_list Pointer to device list + * + * @return @see enum i3c_bus_mode. + */ +static enum i3c_bus_mode i3c_bus_mode(const struct i3c_dev_list *dev_list) +{ + enum i3c_bus_mode mode = I3C_BUS_MODE_PURE; + + for (int i = 0; i < dev_list->num_i2c; i++) { + switch (I3C_LVR_I2C_DEV_IDX(dev_list->i2c[i].lvr)) { + case I3C_LVR_I2C_DEV_IDX_0: + if (mode < I3C_BUS_MODE_MIXED_FAST) { + mode = I3C_BUS_MODE_MIXED_FAST; + } + break; + case I3C_LVR_I2C_DEV_IDX_1: + if (mode < I3C_BUS_MODE_MIXED_LIMITED) { + mode = I3C_BUS_MODE_MIXED_LIMITED; + } + break; + case I3C_LVR_I2C_DEV_IDX_2: + if (mode < I3C_BUS_MODE_MIXED_SLOW) { + mode = I3C_BUS_MODE_MIXED_SLOW; + } + break; + default: + mode = I3C_BUS_MODE_INVALID; + break; + } + } + return mode; +} + +static int get_i3c_lvr_ic_mode(const struct i3c_dev_list *dev_list) +{ + for (int i = 0; i < dev_list->num_i2c; i++) { + if (I3C_LVR_I2C_DEV_IDX(dev_list->i2c[i].lvr) == I3C_LVR_I2C_DEV_IDX_0) { + if (I3C_LVR_I2C_MODE(dev_list->i2c[i].lvr) == I3C_LVR_I2C_FM_MODE) { + return I3C_LVR_I2C_FM_MODE; + } + } + } + return I3C_LVR_I2C_FM_PLUS_MODE; +} + +static bool i3c_stm32_curr_msg_is_i3c(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + return (curr_msg->msg_type == LL_I3C_CONTROLLER_MTYPE_PRIVATE); +} + +static void i3c_stm32_arbitration_header_config(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + if (i3c_stm32_curr_msg_is_i3c(dev)) { + if (curr_msg->i3c_msg_ctrl_ptr->flags & I3C_MSG_NBCH) { + /* Disable arbitration header for this transaction */ + LL_I3C_DisableArbitrationHeader(i3c); + } else { + /* Enable arbitration header for this transaction */ + LL_I3C_EnableArbitrationHeader(i3c); + } + } +} + +static int i3c_stm32_curr_msg_init(const struct device *dev, struct i3c_msg *i3c_msgs, + struct i2c_msg *i2c_msgs, uint8_t num_msgs, uint8_t tgt_addr) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + /* Either should be NULL */ + __ASSERT(!(i3c_msgs == NULL && i2c_msgs == NULL), "Both i3c_msgs and i2c_msgs are NULL"); + __ASSERT(!(i3c_msgs != NULL && i2c_msgs != NULL), + "Both i3c_msgs and i2c_msgs are not NULL"); + + curr_msg->target_addr = tgt_addr; + curr_msg->xfer_offset = 0; + curr_msg->num_msgs = num_msgs; + curr_msg->ctrl_msg_idx = 0; + curr_msg->status_msg_idx = 0; + curr_msg->xfer_msg_idx = 0; + + /* I3C private message */ + if (i2c_msgs == NULL) { + curr_msg->msg_type = LL_I3C_CONTROLLER_MTYPE_PRIVATE; + curr_msg->i3c_msg_ptr = i3c_msgs; + curr_msg->i3c_msg_ctrl_ptr = i3c_msgs; + curr_msg->i3c_msg_status_ptr = i3c_msgs; + } else { + /* Legacy I2C message */ + curr_msg->msg_type = LL_I3C_CONTROLLER_MTYPE_LEGACY_I2C; + curr_msg->i2c_msg_ptr = i2c_msgs; + curr_msg->i2c_msg_ctrl_ptr = i2c_msgs; + } + + i3c_stm32_arbitration_header_config(dev); + return 0; +} + +static int i3c_stm32_curr_msg_control_get_dir(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + if (i3c_stm32_curr_msg_is_i3c(dev)) { + return (((curr_msg->i3c_msg_ctrl_ptr->flags & I3C_MSG_RW_MASK) == I3C_MSG_READ) + ? LL_I3C_DIRECTION_READ + : LL_I3C_DIRECTION_WRITE); + } + + return (((curr_msg->i2c_msg_ctrl_ptr->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) + ? LL_I3C_DIRECTION_READ + : LL_I3C_DIRECTION_WRITE); +} + +static int i3c_stm32_curr_msg_control_get_len(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + return (i3c_stm32_curr_msg_is_i3c(dev)) ? curr_msg->i3c_msg_ctrl_ptr->len + : curr_msg->i2c_msg_ctrl_ptr->len; +} + +static int i3c_stm32_curr_msg_control_get_end(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + return ((curr_msg->ctrl_msg_idx < (curr_msg->num_msgs - 1)) ? LL_I3C_GENERATE_RESTART + : LL_I3C_GENERATE_STOP); +} + +static int i3c_stm32_curr_msg_control_next(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + if (curr_msg->ctrl_msg_idx >= curr_msg->num_msgs) { + LOG_ERR("No more messages left"); + return -EFAULT; + } + + if (i3c_stm32_curr_msg_is_i3c(dev)) { + curr_msg->i3c_msg_ctrl_ptr++; + } else { + curr_msg->i2c_msg_ctrl_ptr++; + } + + curr_msg->ctrl_msg_idx++; + + return 0; +} + +static int i3c_stm32_curr_msg_status_update_num_xfer(const struct device *dev, size_t num_xfer) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + if (curr_msg->status_msg_idx >= curr_msg->num_msgs) { + LOG_ERR("No more messages left"); + return -EFAULT; + } + + /* Legacy I2C messages do not have num_xfer */ + if (i3c_stm32_curr_msg_is_i3c(dev)) { + curr_msg->i3c_msg_status_ptr->num_xfer = num_xfer; + } + + return 0; +} + +static int i3c_stm32_curr_msg_status_next(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + if (curr_msg->status_msg_idx >= curr_msg->num_msgs) { + LOG_ERR("No more messages left"); + return -EFAULT; + } + + if (i3c_stm32_curr_msg_is_i3c(dev)) { + curr_msg->i3c_msg_status_ptr++; + curr_msg->status_msg_idx++; + } + + return 0; +} + +static int i3c_stm32_curr_msg_xfer_get_buf(const struct device *dev, uint8_t **buf, uint32_t *len, + size_t **offset) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + if (curr_msg->xfer_msg_idx >= curr_msg->num_msgs) { + LOG_ERR("No more messages left"); + return -EFAULT; + } + + if (i3c_stm32_curr_msg_is_i3c(dev)) { + *buf = curr_msg->i3c_msg_ptr->buf; + *len = curr_msg->i3c_msg_ptr->len; + } else { + *buf = curr_msg->i2c_msg_ptr->buf; + *len = curr_msg->i2c_msg_ptr->len; + } + + *offset = &curr_msg->xfer_offset; + + return 0; +} + +/* This method is only used in DMA mode */ +#ifdef CONFIG_I3C_STM32_DMA +static bool i3c_stm32_curr_msg_xfer_is_read(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + if (curr_msg->xfer_msg_idx >= curr_msg->num_msgs) { + LOG_ERR("No more messages left"); + return false; + } + + if (i3c_stm32_curr_msg_is_i3c(dev)) { + return ((curr_msg->i3c_msg_ptr->flags & I3C_MSG_RW_MASK) == I3C_MSG_READ); + } + + return ((curr_msg->i2c_msg_ptr->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ); +} +#endif /* CONFIG_I3C_STM32_DMA */ + +static int i3c_stm32_curr_msg_xfer_next(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + if (curr_msg->xfer_msg_idx >= curr_msg->num_msgs) { + LOG_ERR("No more messages left"); + return -EFAULT; + } + + if (i3c_stm32_curr_msg_is_i3c(dev)) { + curr_msg->i3c_msg_ptr++; + } else { + curr_msg->i2c_msg_ptr++; + } + + curr_msg->xfer_msg_idx++; + curr_msg->xfer_offset = 0; + + return 0; +} + +/* Activates the device I3C pinctrl and CLK */ +static int i3c_stm32_activate(const struct device *dev) +{ + int ret; + struct i3c_stm32_config *config = (struct i3c_stm32_config *)dev->config; + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + if (clock_control_on(clk, (clock_control_subsys_t)&config->pclken[0]) != 0) { + return -EIO; + } + return 0; +} + +static int i3c_stm32_calc_scll_od_sclh_i2c(const struct device *dev, uint32_t i2c_bus_freq, + uint32_t i3c_clock, uint8_t *scll_od, uint8_t *sclh_i2c) +{ + const struct i3c_stm32_config *config = dev->config; + + if (i2c_bus_freq != 0) { + if (i2c_bus_freq > 400000) { + /* I2C bus is FM+ */ + *scll_od = DIV_ROUND_UP(STM32_I3C_SCLL_OD_MIN_FMP_NS * i3c_clock, + 1000000000ull) - + 1; + *sclh_i2c = DIV_ROUND_UP(i3c_clock, i2c_bus_freq) - *scll_od - 2; + if (*sclh_i2c < + DIV_ROUND_UP(STM32_I3C_SCLH_I2C_MIN_FMP_NS * i3c_clock, 1000000000ull) - + 1) { + LOG_ERR("Cannot find a combination of SCLL_OD and SCLH_I2C at " + "current I3C clock " + "frequency for FM+ I2C bus"); + return -EINVAL; + } + } else { + /* I2C bus is FM */ + *scll_od = DIV_ROUND_UP(STM32_I3C_SCLL_OD_MIN_FM_NS * i3c_clock, + 1000000000ull) - + 1; + *sclh_i2c = DIV_ROUND_UP(i3c_clock, i2c_bus_freq) - *scll_od - 2; + } + + if (*sclh_i2c < + DIV_ROUND_UP(STM32_I3C_SCLH_I2C_MIN_FM_NS * i3c_clock, 1000000000ull) - 1) { + LOG_ERR("Cannot find a combination of SCLL_OD and SCLH_I2C at current I3C " + "clock " + "frequency for FM I2C bus"); + return -EINVAL; + } + } else { + if (config->drv_cfg.dev_list.num_i2c > 0) { + enum i3c_bus_mode mode = i3c_bus_mode(&config->drv_cfg.dev_list); + + if (mode == I3C_BUS_MODE_MIXED_FAST) { + if (get_i3c_lvr_ic_mode(&config->drv_cfg.dev_list) == + I3C_LVR_I2C_FM_MODE) { + /* I2C bus is FM */ + i2c_bus_freq = 400000; + *scll_od = DIV_ROUND_UP(STM32_I3C_SCLL_OD_MIN_FM_NS * + i3c_clock, + 1000000000ull) - + 1; + *sclh_i2c = DIV_ROUND_UP(i3c_clock, i2c_bus_freq) - + *scll_od - 2; + } else { + /* I2C bus is FM+ */ + i2c_bus_freq = 1000000; + *scll_od = DIV_ROUND_UP(STM32_I3C_SCLL_OD_MIN_FMP_NS * + i3c_clock, + 1000000000ull) - + 1; + *sclh_i2c = DIV_ROUND_UP(i3c_clock, i2c_bus_freq) - + *scll_od - 2; + if (*sclh_i2c < + DIV_ROUND_UP(STM32_I3C_SCLH_I2C_MIN_FMP_NS * i3c_clock, + 1000000000ull) - + 1) { + LOG_ERR("Cannot find a combination of SCLL_OD and " + "SCLH_I2C at current I3C clock " + "frequency for FM+ I2C bus"); + return -EINVAL; + } + } + + if (*sclh_i2c < + DIV_ROUND_UP(STM32_I3C_SCLH_I2C_MIN_FM_NS * i3c_clock, + 1000000000ull) - + 1) { + LOG_ERR("Cannot find a combination of SCLL_OD and SCLH_I2C " + "at current I3C clock " + "frequency for FM I2C bus"); + return -EINVAL; + } + } else { + return -EINVAL; + } + } else { + /* Assume no I2C devices on the bus */ + *scll_od = DIV_ROUND_UP(STM32_I3C_SCLL_OD_MIN_I3C_NS * i3c_clock, + 1000000000ull) - + 1; + *sclh_i2c = 0; + } + } + + LOG_DBG("TimingReg0: SCLL_OD = %d, SCLH_I2C = %d", *scll_od, *sclh_i2c); + return 0; +} + +static int i3c_stm32_calc_scll_pp_sclh_i3c(uint32_t i3c_bus_freq, uint32_t i3c_clock, + uint8_t *scll_pp, uint8_t *sclh_i3c) +{ + *sclh_i3c = DIV_ROUND_UP(STM32_I3C_SCLH_I3C_MIN_NS * i3c_clock, 1000000000ull) - 1; + *scll_pp = DIV_ROUND_UP(i3c_clock, i3c_bus_freq) - *sclh_i3c - 2; + + if (*scll_pp < DIV_ROUND_UP(STM32_I3C_SCLL_PP_MIN_NS * i3c_clock, 1000000000ull) - 1) { + LOG_ERR("Cannot find a combination of SCLL_PP and SCLH_I3C at current I3C clock " + "frequency for specified I3C bus speed"); + return -EINVAL; + } + + LOG_DBG("TimingReg0: SCLL_PP = %d, SCLH_I3C = %d", *scll_pp, *sclh_i3c); + return 0; +} + +static int i3c_stm32_config_clk_wave(const struct device *dev) +{ + const struct i3c_stm32_config *cfg = dev->config; + struct i3c_stm32_data *data = dev->data; + const struct device *clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + I3C_TypeDef *i3c = cfg->i3c; + uint32_t i3c_clock = 0; + uint32_t i2c_bus_freq = data->drv_data.ctrl_config.scl.i2c; + uint32_t i3c_bus_freq = data->drv_data.ctrl_config.scl.i3c; + + if (clock_control_get_rate(clk, (clock_control_subsys_t)&cfg->pclken[0], &i3c_clock) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclken[0])"); + return -EIO; + } + + uint8_t scll_od = 0; + uint8_t sclh_i2c = 0; + uint8_t scll_pp = 0; + uint8_t sclh_i3c = 0; + uint32_t clk_wave = 0; + int ret; + + LOG_DBG("I3C Clock = %u, I2C Bus Freq = %u, I3C Bus Freq = %u", i3c_clock, i2c_bus_freq, + i3c_bus_freq); + + ret = i3c_stm32_calc_scll_od_sclh_i2c(dev, i2c_bus_freq, i3c_clock, &scll_od, &sclh_i2c); + if (ret != 0) { + LOG_ERR("Cannot calculate the timing for TimingReg0, err=%d", ret); + return ret; + } + + ret = i3c_stm32_calc_scll_pp_sclh_i3c(i3c_bus_freq, i3c_clock, &scll_pp, &sclh_i3c); + if (ret != 0) { + LOG_ERR("Cannot calculate the timing for TimingReg0, err=%d", ret); + return ret; + } + + clk_wave = ((uint32_t)sclh_i2c << 24) | ((uint32_t)scll_od << 16) | + ((uint32_t)sclh_i3c << 8) | (scll_pp); + + LOG_DBG("TimigReg0 = 0x%08x", clk_wave); + + LL_I3C_ConfigClockWaveForm(i3c, clk_wave); + + return 0; +} +/** + * @brief Get current configuration of the I3C hardware. + * + * @param[in] dev Pointer to controller device driver instance. + * @param[in] type Type of configuration. + * @param[in,out] config Pointer to the configuration parameters. + * + * @retval 0 If successful. + * @retval -EIO General Input/Output errors. + * @retval -ENOSYS If not implemented. + */ +static int i3c_stm32_config_get(const struct device *dev, enum i3c_config_type type, void *config) +{ + struct i3c_stm32_data *data = dev->data; + + if ((type != I3C_CONFIG_CONTROLLER) || (config == NULL)) { + return -EINVAL; + } + + (void)memcpy(config, &data->drv_data.ctrl_config, sizeof(data->drv_data.ctrl_config)); + + return 0; +} + +static int i3c_stm32_config_ctrl_bus_char(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + const struct device *clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + I3C_TypeDef *i3c = config->i3c; + uint32_t i3c_clock = 0; + uint32_t i2c_bus_freq = data->drv_data.ctrl_config.scl.i2c; + + uint8_t free_timing = 0; + uint8_t aval = 0; + + if (clock_control_get_rate(clk, (clock_control_subsys_t)&config->pclken[0], &i3c_clock) < + 0) { + LOG_ERR("Failed call clock_control_get_rate(pclken[0])"); + return -EIO; + } + + /* Satisfying I3C start timing min timing will statisfy the rest of the conditions */ + + if (i2c_bus_freq != 0) { + if (i2c_bus_freq > 400000) { + /* Mixed bus with I2C FM+ device */ + free_timing = (uint8_t)ceil( + (STM32_I3C_TBUF_FMP_MIN_NS * i3c_clock / 1e9 - 0.5) / 2); + } else { + /* Mixed bus with I2C FM device */ + free_timing = (uint8_t)ceil( + (STM32_I3C_TBUF_FM_MIN_NS * i3c_clock / 1e9 - 0.5) / 2); + } + } else { + if (config->drv_cfg.dev_list.num_i2c > 0) { + enum i3c_bus_mode mode = i3c_bus_mode(&config->drv_cfg.dev_list); + + if (mode == I3C_BUS_MODE_MIXED_FAST) { + if (get_i3c_lvr_ic_mode(&config->drv_cfg.dev_list) == + I3C_LVR_I2C_FM_MODE) { + /* Mixed bus with I2C FM device */ + free_timing = (uint8_t)ceil( + (STM32_I3C_TBUF_FM_MIN_NS * i3c_clock / 1e9 - 0.5) / + 2); + } else { + /* Mixed bus with I2C FM+ device */ + free_timing = (uint8_t)ceil( + (STM32_I3C_TBUF_FMP_MIN_NS * i3c_clock / 1e9 - + 0.5) / + 2); + } + } else { + return -EINVAL; + } + } else { + /* Pure I3C bus */ + free_timing = + (uint8_t)ceil((STM32_I3C_TCAS_MIN_NS * i3c_clock / 1e9 - 0.5) / 2); + } + } + + aval = DIV_ROUND_UP(1000ull * i3c_clock, 1000000000ull) - 1; + + LL_I3C_SetFreeTiming(i3c, free_timing); + LL_I3C_SetAvalTiming(i3c, aval); + LL_I3C_SetDataHoldTime(i3c, LL_I3C_SDA_HOLD_TIME_1_5); + + LOG_DBG("TimingReg1 = 0x%08x", LL_I3C_GetCtrlBusCharacteristic(i3c)); + + return 0; +} + +/* Configures the I3C module in controller mode */ +static int i3c_stm32_configure(const struct device *dev, enum i3c_config_type type, void *cfg) +{ + int ret; + + if (type == I3C_CONFIG_TARGET || type == I3C_CONFIG_CUSTOM) { + return -ENOTSUP; + } + + struct i3c_stm32_data *data = dev->data; + struct i3c_config_controller *ctrl_cfg = cfg; + + if ((ctrl_cfg->scl.i2c == 0U) || (ctrl_cfg->scl.i3c == 0U)) { + return -EINVAL; + } + + data->drv_data.ctrl_config.scl.i3c = ctrl_cfg->scl.i3c; + data->drv_data.ctrl_config.scl.i2c = ctrl_cfg->scl.i2c; + + ret = i3c_stm32_activate(dev); + if (ret != 0) { + LOG_ERR("Clock and GPIO could not be initialized for the I3C module, err=%d", ret); + return ret; + } + + ret = i3c_stm32_config_clk_wave(dev); + if (ret != 0) { + LOG_ERR("TimigReg0 timing could not be calculated, err=%d", ret); + return ret; + } + + ret = i3c_stm32_config_ctrl_bus_char(dev); + if (ret != 0) { + LOG_ERR("TimingReg1 timing could not be calculated, err=%d", ret); + return ret; + } + + return 0; +} + +static int i3c_stm32_i2c_configure(const struct device *dev, uint32_t config) +{ + struct i3c_stm32_data *data = dev->data; + struct i3c_config_controller *ctrl_config = &data->drv_data.ctrl_config; + + switch (I2C_SPEED_GET(config)) { + case I2C_SPEED_FAST: + ctrl_config->scl.i2c = 400000; + break; + case I2C_SPEED_FAST_PLUS: + ctrl_config->scl.i2c = 1000000; + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * @brief Find a registered I3C target device. + * + * This returns the I3C device descriptor of the I3C device + * matching the incoming @p id. + * + * @param dev Pointer to controller device driver instance. + * @param id Pointer to I3C device ID. + * + * @return @see i3c_device_find. + */ +static struct i3c_device_desc *i3c_stm32_device_find(const struct device *dev, + const struct i3c_device_id *id) +{ + const struct i3c_stm32_config *config = dev->config; + + return i3c_dev_list_find(&config->drv_cfg.dev_list, id); +} + +#ifdef CONFIG_I3C_STM32_DMA + +static void i3c_stm32_end_dma_requests(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + LL_I3C_EnableIT_TXFNF(i3c); + LL_I3C_EnableIT_RXFNE(i3c); + LL_I3C_EnableIT_CFNF(i3c); + LL_I3C_EnableIT_SFNE(i3c); + + LL_I3C_DisableDMAReq_TX(i3c); + LL_I3C_DisableDMAReq_RX(i3c); + LL_I3C_DisableDMAReq_Control(i3c); + LL_I3C_DisableDMAReq_Status(i3c); +} + +static void i3c_stm32_prepare_dma_requests(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + LL_I3C_DisableIT_TXFNF(i3c); + LL_I3C_DisableIT_RXFNE(i3c); + LL_I3C_DisableIT_CFNF(i3c); + LL_I3C_DisableIT_SFNE(i3c); + + LL_I3C_EnableDMAReq_TX(i3c); + LL_I3C_EnableDMAReq_RX(i3c); + LL_I3C_EnableDMAReq_Control(i3c); + LL_I3C_EnableDMAReq_Status(i3c); +} + +#endif /* CONFIG_I3C_STM32_DMA */ + +static void i3c_stm32_flush_all_fifo(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + LL_I3C_RequestTxFIFOFlush(i3c); + LL_I3C_RequestRxFIFOFlush(i3c); + LL_I3C_RequestControlFIFOFlush(i3c); + LL_I3C_RequestStatusFIFOFlush(i3c); +} + +static void i3c_stm32_log_err_type(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + if (LL_I3C_IsActiveFlag_ANACK(i3c)) { + LOG_ERR("Address NACK"); + } + + if (LL_I3C_IsActiveFlag_COVR(i3c)) { + LOG_ERR("Control/Status FIFO underrun/overrun"); + } + + if (LL_I3C_IsActiveFlag_DOVR(i3c)) { + LOG_ERR("TX/RX FIFO underrun/overrun"); + } + + if (LL_I3C_IsActiveFlag_DNACK(i3c)) { + LOG_ERR("Data NACK by target"); + } + + if (LL_I3C_IsActiveFlag_PERR(i3c)) { + switch (LL_I3C_GetMessageErrorCode(i3c)) { + case LL_I3C_CONTROLLER_ERROR_CE0: + LOG_ERR("Illegally formatted CCC detected"); + break; + case LL_I3C_CONTROLLER_ERROR_CE1: + LOG_ERR("Data on bus is not as expected"); + break; + case LL_I3C_CONTROLLER_ERROR_CE2: + LOG_ERR("No response to broadcast address"); + break; + default: + LOG_ERR("Unsupported error detected"); + break; + } + } +} + +static void i3c_stm32_clear_err(const struct device *dev, bool is_i2c_xfer) +{ + struct i3c_stm32_data *data = dev->data; + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + i3c_stm32_flush_all_fifo(dev); + + /* Re-enable arbirtation header after exiting from error caused by legacy I2C msg */ + if (is_i2c_xfer) { + LL_I3C_EnableArbitrationHeader(i3c); + } + +#ifdef CONFIG_I3C_STM32_DMA + i3c_stm32_end_dma_requests(dev); + + k_heap_free(&stm32_i3c_fifo_heap, data->status_fifo); + k_heap_free(&stm32_i3c_fifo_heap, data->control_fifo); +#endif + + data->msg_state = STM32_I3C_MSG_IDLE; + data->sf_state = STM32_I3C_SF_IDLE; + + k_mutex_unlock(&data->bus_mutex); +} + +/** + * @brief Fills the I3C TX FIFO from a given buffer + * + * @param buf The buffer to fill the TX FIFO from + * @param len The total buffer length + * @param offset Pointer to the offset from the beginning of buffer which will be incremented by the + * number of bytes sent to the TX FIFO + * + * @return Returns true if last byte was sent (TXLAST flag was set) + */ +static bool i3c_stm32_fill_tx_fifo(const struct device *dev, uint8_t *buf, size_t len, + size_t *offset) +{ + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + bool is_last = false; + + if (*offset >= len) { + return 0; + } + + while (LL_I3C_IsActiveFlag_TXFNF(i3c)) { + if (LL_I3C_IsActiveFlag_TXLAST(i3c)) { + is_last = true; + } + + if (*offset < len) { + LL_I3C_TransmitData8(i3c, buf[(*offset)++]); + } + + if (is_last) { + return is_last; + } + } + + return is_last; +} + +/** + * @brief Drains the I3C RX FIFO from a given buffer + * + * @param buf The buffer to drain the RX FIFO to + * @param len The total buffer length + * @param offset Pointer to the offset from the beginning of buffer which will be incremented by the + * number of bytes drained from the RX FIFO + * + * @return Returns true if last byte was received (RXLAST flag was set) + */ +static bool i3c_stm32_drain_rx_fifo(const struct device *dev, uint8_t *buf, uint32_t len, + size_t *offset) +{ + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + bool is_last = false; + + if (*offset >= len) { + return 0; + } + + while (LL_I3C_IsActiveFlag_RXFNE(i3c)) { + if (LL_I3C_IsActiveFlag_RXLAST(i3c)) { + is_last = true; + } + + if (*offset < len) { + buf[(*offset)++] = LL_I3C_ReceiveData8(i3c); + } + + if (is_last) { + return is_last; + } + } + + return is_last; +} + +/* Handles broadcast/direct CCCs except for ENTDAA */ +static int i3c_stm32_do_ccc(const struct device *dev, struct i3c_ccc_payload *payload) +{ + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + I3C_TypeDef *i3c = config->i3c; + + __ASSERT(dev != NULL, "I3C Device is NULL."); + __ASSERT(payload != NULL, "I3C Payload is NULL."); + + if (payload->ccc.id == I3C_CCC_ENTDAA) { + return -EINVAL; + } + + /* Check if payload has targets when sending a direct CCC */ + if (!i3c_ccc_is_payload_broadcast(payload) && + (payload->targets.payloads == NULL || payload->targets.num_targets == 0)) { + return -EINVAL; + } + + if (payload->ccc.data_len > 0 && payload->ccc.data == NULL) { + return -EINVAL; + } + + k_mutex_lock(&data->bus_mutex, K_FOREVER); + + /* Disable Status FIFO and enable the RXTGTEND interrupt flag to detected early read + * termination from target during read CCC commands + */ + LL_I3C_DisableStatusFIFO(i3c); + LL_I3C_EnableIT_RXTGTEND(i3c); + + (void)pm_device_runtime_get(dev); + + /* Prevent the clocks to be stopped during the transaction */ + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + + /* Mark current transfer as CCC */ + data->msg_state = STM32_I3C_MSG_CCC; + data->ccc_payload = payload; + data->ccc_target_idx = 0; + data->ccc_target_payload = payload->targets.payloads; + + payload->ccc.num_xfer = 0; + + for (size_t i = 0; i < payload->targets.num_targets; i++) { + payload->targets.payloads[i].num_xfer = 0; + } + + /* Start CCC transfer */ + LL_I3C_ControllerHandleCCC(i3c, payload->ccc.id, payload->ccc.data_len, + (i3c_ccc_is_payload_broadcast(payload) + ? LL_I3C_GENERATE_STOP + : LL_I3C_GENERATE_RESTART)); + + /* Wait for CCC to complete */ + if (k_sem_take(&data->device_sync_sem, STM32_I3C_TRANSFER_TIMEOUT) != 0) { + LL_I3C_DisableIT_RXTGTEND(i3c); + LL_I3C_EnableStatusFIFO(i3c); + i3c_stm32_clear_err(dev, false); + return -ETIMEDOUT; + } + + if (data->msg_state == STM32_I3C_MSG_ERR) { + LL_I3C_DisableIT_RXTGTEND(i3c); + LL_I3C_EnableStatusFIFO(i3c); + i3c_stm32_clear_err(dev, false); + return -EIO; + } + + LL_I3C_DisableIT_RXTGTEND(i3c); + LL_I3C_EnableStatusFIFO(i3c); + k_mutex_unlock(&data->bus_mutex); + + return 0; +} + +/* Handles the ENTDAA CCC */ +static int i3c_stm32_do_daa(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + I3C_TypeDef *i3c = config->i3c; + + k_mutex_lock(&data->bus_mutex, K_FOREVER); + + (void)pm_device_runtime_get(dev); + + /* Prevent the clocks to be stopped during the transaction */ + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + + /* Mark current transfer as DAA */ + data->msg_state = STM32_I3C_MSG_DAA; + + /* Disable TXFNF interrupt, the RXFNE interrupt will enable it once all PID bytes are + * received + */ + LL_I3C_DisableIT_TXFNF(i3c); + + /* Start DAA */ + LL_I3C_ControllerHandleCCC(i3c, I3C_CCC_ENTDAA, 0, LL_I3C_GENERATE_STOP); + + /* Wait for DAA to finish */ + if (k_sem_take(&data->device_sync_sem, STM32_I3C_TRANSFER_TIMEOUT) != 0) { + return -ETIMEDOUT; + } + + if (data->msg_state == STM32_I3C_MSG_ERR) { + i3c_stm32_clear_err(dev, false); + /* Enable TXFNF interrupt in case an error occurred before it was enabled by RXFNE + */ + LL_I3C_EnableIT_TXFNF(i3c); + return -EIO; + } + + k_mutex_unlock(&data->bus_mutex); + + return 0; +} + +#ifdef CONFIG_I3C_STM32_DMA + +static int i3c_stm32_dma_msg_control_fifo_config(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + int ret; + + data->dma_tc.blk_cfg.source_address = (uint32_t)data->control_fifo; + data->dma_tc.blk_cfg.block_size = data->fifo_len; + + ret = dma_config(data->dma_tc.dma_dev, data->dma_tc.dma_channel, &data->dma_tc.dma_cfg); + + if (ret != 0) { + LOG_ERR("Control DMA config error, err=%d", ret); + return -EINVAL; + } + + if (dma_start(data->dma_tc.dma_dev, data->dma_tc.dma_channel)) { + LOG_ERR("Control DMA start failed"); + return -EFAULT; + } + + return 0; +} + +static int i3c_stm32_dma_msg_status_fifo_config(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + int ret; + + data->dma_rs.blk_cfg.dest_address = (uint32_t)data->status_fifo; + data->dma_rs.blk_cfg.block_size = data->fifo_len; + + ret = dma_config(data->dma_rs.dma_dev, data->dma_rs.dma_channel, &data->dma_rs.dma_cfg); + + if (ret != 0) { + LOG_ERR("Status DMA config error, err=%d", ret); + return -EINVAL; + } + + if (dma_start(data->dma_rs.dma_dev, data->dma_rs.dma_channel)) { + LOG_ERR("Status DMA start failed"); + return -EFAULT; + } + + return 0; +} + +static int i3c_stm32_dma_msg_config(const struct device *dev, uint32_t buf_addr, size_t buf_len) +{ + struct i3c_stm32_dma_stream *dma_stream; + struct i3c_stm32_data *data = dev->data; + int ret; + + if (i3c_stm32_curr_msg_xfer_is_read(dev)) { + dma_stream = &(data->dma_rx); + dma_stream->blk_cfg.dest_address = buf_addr; + } else { + dma_stream = &(data->dma_tx); + dma_stream->blk_cfg.source_address = buf_addr; + } + + i3c_stm32_arbitration_header_config(dev); + + dma_stream->blk_cfg.block_size = buf_len; + ret = dma_config(dma_stream->dma_dev, dma_stream->dma_channel, &dma_stream->dma_cfg); + + if (ret != 0) { + LOG_ERR("TX/RX DMA config error, err=%d", ret); + return -EINVAL; + } + + if (dma_start(dma_stream->dma_dev, dma_stream->dma_channel)) { + LOG_ERR("TX/RX DMA start failed"); + return -EFAULT; + } + return 0; +} +#endif + +static int i3c_stm32_transfer_begin(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + data->msg_state = STM32_I3C_MSG; + data->sf_state = STM32_I3C_SF; + + (void)pm_device_runtime_get(dev); + + /* Prevent the clocks to be stopped during the transaction */ + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + +#ifdef CONFIG_I3C_STM32_DMA + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + + data->fifo_len = curr_msg->num_msgs * sizeof(uint32_t); + data->control_fifo = k_heap_alloc(&stm32_i3c_fifo_heap, data->fifo_len, K_FOREVER); + data->status_fifo = k_heap_alloc(&stm32_i3c_fifo_heap, data->fifo_len, K_FOREVER); + int ret; + + /* Prepare all control words for all messages on the transfer */ + for (size_t i = 0; i < curr_msg->num_msgs; i++) { + WRITE_REG(data->control_fifo[i], + ((curr_msg->target_addr << I3C_CR_ADD_Pos) | + i3c_stm32_curr_msg_control_get_len(dev) | + i3c_stm32_curr_msg_control_get_dir(dev) | curr_msg->msg_type | + i3c_stm32_curr_msg_control_get_end(dev)) & + (I3C_CR_ADD | I3C_CR_DCNT | I3C_CR_RNW | I3C_CR_MTYPE | + I3C_CR_MEND)); + + i3c_stm32_curr_msg_control_next(dev); + } + + /* Configure DMA for the first message only, DMA callback will take care of the rest */ + uint8_t *buf = NULL; + size_t *offset = 0; + uint32_t len = 0; + + i3c_stm32_curr_msg_xfer_get_buf(dev, &buf, &len, &offset); + + ret = i3c_stm32_dma_msg_config(dev, (uint32_t)buf, len); + if (ret != 0) { + return ret; + } + + ret = i3c_stm32_dma_msg_control_fifo_config(dev); + if (ret != 0) { + return ret; + } + + ret = i3c_stm32_dma_msg_status_fifo_config(dev); + if (ret != 0) { + return ret; + } + + i3c_stm32_prepare_dma_requests(dev); +#endif + + /* Begin transmission */ + LL_I3C_RequestTransfer(i3c); + + /* Wait for whole transfer to complete */ + if (k_sem_take(&data->device_sync_sem, STM32_I3C_TRANSFER_TIMEOUT) != 0) { + return -ETIMEDOUT; + } + + if (data->msg_state == STM32_I3C_MSG_ERR) { + return -EIO; + } + + return 0; +} + +/* Handles the controller private read/write transfers */ +static int i3c_stm32_i3c_transfer(const struct device *dev, struct i3c_device_desc *target, + struct i3c_msg *msgs, uint8_t num_msgs) +{ + struct i3c_stm32_data *data = dev->data; + int ret; + + /* Verify all messages */ + for (size_t i = 0; i < num_msgs; i++) { + if (msgs[i].buf == NULL) { + return -EINVAL; + } + if ((msgs[i].flags & I3C_MSG_HDR) && (msgs[i].hdr_mode != 0)) { + return -ENOTSUP; + } + } + + k_mutex_lock(&data->bus_mutex, K_FOREVER); + ret = i3c_stm32_curr_msg_init(dev, msgs, NULL, num_msgs, target->dynamic_addr); + if (ret != 0) { + i3c_stm32_clear_err(dev, false); + LOG_ERR("Failed to initialize transfer messages, err=%d", ret); + return ret; + } + + ret = i3c_stm32_transfer_begin(dev); + if (ret != 0) { + i3c_stm32_clear_err(dev, false); + LOG_ERR("Failed to transfer messages, err=%d", ret); + return ret; + } + +#ifdef CONFIG_I3C_STM32_DMA + /* Fill the num_xfer for each message from the status FIFO */ + for (size_t i = 0; i < num_msgs; i++) { + msgs[i].num_xfer = READ_BIT(data->status_fifo[i], I3C_SR_XDCNT); + } + + k_heap_free(&stm32_i3c_fifo_heap, data->control_fifo); + k_heap_free(&stm32_i3c_fifo_heap, data->status_fifo); + + i3c_stm32_end_dma_requests(dev); +#endif + + k_mutex_unlock(&data->bus_mutex); + + return 0; +} + +static int i3c_stm32_i2c_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t addr) +{ + struct i3c_stm32_data *data = dev->data; + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + int ret; + + /* Verify all messages */ + for (size_t i = 0; i < num_msgs; i++) { + if (msgs[i].buf == NULL) { + return -EINVAL; + } + if (msgs[i].flags & I2C_MSG_ADDR_10_BITS) { + LOG_ERR("10-bit addressing mode is not supported"); + return -ENOTSUP; + } + } + + k_mutex_lock(&data->bus_mutex, K_FOREVER); + + /* Disable arbitration header for all I2C messages in case no I3C devices exist on bus */ + LL_I3C_DisableArbitrationHeader(i3c); + + ret = i3c_stm32_curr_msg_init(dev, NULL, msgs, num_msgs, addr); + if (ret != 0) { + i3c_stm32_clear_err(dev, false); + LOG_ERR("Failed to initialize transfer messages, err=%d", ret); + return ret; + } + + ret = i3c_stm32_transfer_begin(dev); + if (ret != 0) { + i3c_stm32_clear_err(dev, false); + LOG_ERR("Failed to transfer messages, err=%d", ret); + return ret; + } + + LL_I3C_EnableArbitrationHeader(i3c); + +#ifdef CONFIG_I3C_STM32_DMA + k_heap_free(&stm32_i3c_fifo_heap, data->control_fifo); + k_heap_free(&stm32_i3c_fifo_heap, data->status_fifo); + + i3c_stm32_end_dma_requests(dev); +#endif + + k_mutex_unlock(&data->bus_mutex); + + return 0; +} + +#ifdef CONFIG_PM_DEVICE +static int i3c_stm32_suspend(const struct device *dev) +{ + int ret; + const struct i3c_stm32_config *cfg = dev->config; + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + + /* Disable device clock. */ + ret = clock_control_off(clk, (clock_control_subsys_t)&cfg->pclken[0]); + if (ret < 0) { + LOG_ERR("failure disabling I3C clock"); + return ret; + } + + /* Move pins to sleep state */ + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP); + if (ret == -ENOENT) { + /* Warn but don't block suspend */ + LOG_WRN("I3C pinctrl sleep state not available"); + } else if (ret < 0) { + return ret; + } + + return 0; +} + +static int i3c_stm32_pm_action(const struct device *dev, enum pm_device_action action) +{ + int err; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + err = i3c_stm32_activate(dev); + break; + case PM_DEVICE_ACTION_SUSPEND: + err = i3c_stm32_suspend(dev); + break; + default: + return -ENOTSUP; + } + + return err; +} +#endif + +#ifdef CONFIG_I3C_STM32_DMA +static int i3c_stm32_dma_stream_config(const struct device *dev, + struct i3c_stm32_dma_stream *dma_stream, uint64_t src_addr, + uint64_t dst_addr) +{ + if (dma_stream->dma_dev != NULL) { + if (!device_is_ready(dma_stream->dma_dev)) { + return -ENODEV; + } + } + + memset(&dma_stream->blk_cfg, 0, sizeof(dma_stream->blk_cfg)); + + dma_stream->blk_cfg.source_address = src_addr; + + dma_stream->blk_cfg.dest_address = dst_addr; + + if (dma_stream->src_addr_increment) { + dma_stream->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; + } else { + dma_stream->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } + + if (dma_stream->dst_addr_increment) { + dma_stream->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + } else { + dma_stream->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } + + dma_stream->blk_cfg.source_reload_en = 0; + dma_stream->blk_cfg.dest_reload_en = 0; + dma_stream->blk_cfg.fifo_mode_control = dma_stream->fifo_threshold; + + dma_stream->dma_cfg.head_block = &dma_stream->blk_cfg; + dma_stream->dma_cfg.user_data = (void *)dev; + + return 0; +} + +/* Initializes the I3C DMA */ +static int i3c_stm32_init_dma(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + int err; + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + /*Configure DMA RX */ + err = i3c_stm32_dma_stream_config( + dev, &data->dma_rx, LL_I3C_DMA_GetRegAddr(i3c, LL_I3C_DMA_REG_DATA_RECEIVE_BYTE), + 0); + if (err != 0) { + return err; + } + + /*Configure DMA RS */ + err = i3c_stm32_dma_stream_config(dev, &data->dma_rs, + LL_I3C_DMA_GetRegAddr(i3c, LL_I3C_DMA_REG_STATUS), 0); + if (err != 0) { + return err; + } + + /*Configure DMA TX */ + err = i3c_stm32_dma_stream_config( + dev, &data->dma_tx, 0, + LL_I3C_DMA_GetRegAddr(i3c, LL_I3C_DMA_REG_DATA_TRANSMIT_BYTE)); + if (err != 0) { + return err; + } + + /*Configure DMA TC */ + err = i3c_stm32_dma_stream_config(dev, &data->dma_tc, 0, + LL_I3C_DMA_GetRegAddr(i3c, LL_I3C_DMA_REG_CONTROL)); + if (err != 0) { + return err; + } + + return err; +} +#endif + +static void i3c_stm32_controller_init(const struct device *dev) +{ + struct i3c_stm32_data *data = dev->data; + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + /* Configure FIFO */ + LL_I3C_SetRxFIFOThreshold(i3c, LL_I3C_RXFIFO_THRESHOLD_1_4); + LL_I3C_SetTxFIFOThreshold(i3c, LL_I3C_TXFIFO_THRESHOLD_1_4); + LL_I3C_EnableControlFIFO(i3c); + LL_I3C_EnableStatusFIFO(i3c); + + /* I3C Initialization */ + LL_I3C_SetMode(i3c, LL_I3C_MODE_CONTROLLER); + LL_I3C_SetStallTime(i3c, 0x00); + LL_I3C_DisableStallACK(i3c); + LL_I3C_DisableStallParityCCC(i3c); + LL_I3C_DisableStallParityData(i3c); + LL_I3C_DisableStallTbit(i3c); + LL_I3C_DisableHighKeeperSDA(i3c); + LL_I3C_SetControllerActivityState(i3c, LL_I3C_OWN_ACTIVITY_STATE_0); + + LL_I3C_Enable(i3c); + + LL_I3C_EnableIT_FC(i3c); + LL_I3C_EnableIT_CFNF(i3c); + LL_I3C_EnableIT_SFNE(i3c); + LL_I3C_EnableIT_RXFNE(i3c); + LL_I3C_EnableIT_TXFNF(i3c); + LL_I3C_EnableIT_ERR(i3c); + LL_I3C_EnableIT_WKP(i3c); + +#ifdef CONFIG_I3C_USE_IBI + LL_I3C_EnableIT_IBI(i3c); + LL_I3C_EnableIT_HJ(i3c); +#endif + + /* Bus will be idle initially */ + data->msg_state = STM32_I3C_MSG_IDLE; + data->sf_state = STM32_I3C_SF_IDLE; + data->target_id = 0; +#ifdef CONFIG_I3C_USE_IBI + data->ibi_payload = 0; + data->ibi_payload_size = 0; + data->ibi_target_addr = 0; +#endif +} + +/* Initializes the I3C device and I3C bus */ +static int i3c_stm32_init(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + I3C_TypeDef *i3c = config->i3c; + int ret; + +#ifdef CONFIG_I3C_STM32_DMA + ret = i3c_stm32_init_dma(dev); + + if (ret != 0) { + LOG_ERR("Failed to init I3C DMA, err=%d", ret); + return ret; + } +#endif + + k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT); + + /* initialize mutex used when multiple transfers + * are taking place to guarantee that each one is + * atomic and has exclusive access to the I3C bus. + */ + k_mutex_init(&data->bus_mutex); + + /* initialize semaphore used when multiple ibi requests are taking place */ +#ifdef CONFIG_I3C_USE_IBI + k_sem_init(&data->ibi_lock_sem, 1, 1); +#endif + ret = i3c_addr_slots_init(dev); + if (ret != 0) { + LOG_ERR("Addr slots init fail, err=%d", ret); + return ret; + } + + config->irq_config_func(dev); + i3c_stm32_configure(dev, I3C_CONFIG_CONTROLLER, &data->drv_data.ctrl_config); + i3c_stm32_controller_init(dev); + + /* Perform bus initialization only if there are devices that already exist on the bus */ + if (config->drv_cfg.dev_list.num_i3c > 0) { + ret = i3c_bus_init(dev, &config->drv_cfg.dev_list); + if (ret != 0) { + LOG_ERR("Failed to do i3c bus init, err=%d", ret); + return ret; + } + } + +#ifdef CONFIG_I3C_USE_IBI + LL_I3C_EnableHJAck(i3c); + hj_pm_lock = true; + (void)pm_device_runtime_get(dev); + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +#endif + + return 0; +} + +static void i3c_stm32_event_isr_tx(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + I3C_TypeDef *i3c = config->i3c; + + switch (data->msg_state) { + case STM32_I3C_MSG: { + uint8_t *buf = NULL; + size_t *offset = NULL; + uint32_t len = 0; + + i3c_stm32_curr_msg_xfer_get_buf(dev, &buf, &len, &offset); + + if (i3c_stm32_fill_tx_fifo(dev, buf, len, offset)) { + i3c_stm32_curr_msg_xfer_next(dev); + } + + break; + } + case STM32_I3C_MSG_DAA: { + struct i3c_device_desc *target; + uint8_t bcr; + uint8_t dcr; + uint8_t dyn_addr = 0; + int ret; + + bcr = (data->pid >> 8) & 0xFF; + dcr = data->pid & 0xFF; + data->pid >>= 16; + + /* Find the device in the device list */ + ret = i3c_dev_list_daa_addr_helper(&data->drv_data.attached_dev.addr_slots, + &config->drv_cfg.dev_list, data->pid, false, + false, &target, &dyn_addr); + if (ret != 0) { + /* TODO: figure out what is the correct sequence to exit form this error + * It is expected that a TX overrun error to occur which triggers err isr + */ + LOG_ERR("No dynamic address could be assigned to target"); + + return; + } + + /* Put the new dynamic address in TX FIFO for transmission */ + LL_I3C_TransmitData8(i3c, dyn_addr); + + if (target != NULL) { + /* Update target descriptor */ + target->dynamic_addr = dyn_addr; + target->bcr = bcr; + target->dcr = dcr; + } + + /* Mark the address as used */ + i3c_addr_slots_mark_i3c(&data->drv_data.attached_dev.addr_slots, dyn_addr); + + /* Mark the static address as free */ + if ((target != NULL) && (target->static_addr != 0) && + (dyn_addr != target->static_addr)) { + i3c_addr_slots_mark_free(&data->drv_data.attached_dev.addr_slots, dyn_addr); + } + + break; + } + case STM32_I3C_MSG_CCC: { + struct i3c_ccc_payload *payload = data->ccc_payload; + + if (payload->ccc.num_xfer < payload->ccc.data_len) { + LL_I3C_TransmitData8(i3c, payload->ccc.data[payload->ccc.num_xfer++]); + } + break; + } + case STM32_I3C_MSG_CCC_P2: { + struct i3c_ccc_target_payload *target = data->ccc_target_payload; + + if (target->num_xfer < target->data_len) { + LL_I3C_TransmitData8(i3c, target->data[target->num_xfer++]); + + /* After sending all bytes for current target, move on to the next target */ + if (target->num_xfer == target->data_len) { + data->ccc_target_payload++; + } + } + break; + } + default: + break; + } +} + +static void i3c_stm32_event_isr_rx(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + I3C_TypeDef *i3c = config->i3c; + + switch (data->msg_state) { + case STM32_I3C_MSG: { + uint8_t *buf = NULL; + size_t *offset = NULL; + uint32_t len = 0; + + i3c_stm32_curr_msg_xfer_get_buf(dev, &buf, &len, &offset); + if (i3c_stm32_drain_rx_fifo(dev, buf, len, offset)) { + i3c_stm32_curr_msg_xfer_next(dev); + } + + break; + } + case STM32_I3C_MSG_DAA: { + data->pid <<= 8; + data->pid |= LL_I3C_ReceiveData8(i3c); + + data->daa_rx_rcv++; + + /* After receiving 8 PID bytes from DAA, enable TXFNF interrupt to send the dynamic + * address + */ + if (data->daa_rx_rcv == 8) { + LL_I3C_EnableIT_TXFNF(i3c); + data->daa_rx_rcv = 0; + } + break; + } + case STM32_I3C_MSG_CCC_P2: { + struct i3c_ccc_target_payload *target = data->ccc_target_payload; + + if (target->num_xfer < target->data_len) { + target->data[target->num_xfer++] = LL_I3C_ReceiveData8(i3c); + + /* After receiving all bytes for current target, move on to the next target + */ + if (target->num_xfer == target->data_len) { + data->ccc_target_payload++; + } + } + break; + } + default: + break; + } +} + +static void i3c_stm32_event_isr_cf(const struct device *dev) +{ + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + struct i3c_stm32_msg *curr_msg = &data->curr_msg; + I3C_TypeDef *i3c = config->i3c; + + switch (data->msg_state) { + case STM32_I3C_MSG: { + LL_I3C_ControllerHandleMessage( + i3c, curr_msg->target_addr, i3c_stm32_curr_msg_control_get_len(dev), + i3c_stm32_curr_msg_control_get_dir(dev), curr_msg->msg_type, + i3c_stm32_curr_msg_control_get_end(dev)); + + i3c_stm32_curr_msg_control_next(dev); + break; + } + case STM32_I3C_MSG_CCC: + case STM32_I3C_MSG_CCC_P2: { + struct i3c_ccc_payload *payload = data->ccc_payload; + struct i3c_ccc_target_payload *target; + + if (data->ccc_target_idx < payload->targets.num_targets) { + target = &payload->targets.payloads[data->ccc_target_idx++]; + + LL_I3C_ControllerHandleMessage( + i3c, target->addr, target->data_len, + target->rnw ? LL_I3C_DIRECTION_READ : LL_I3C_DIRECTION_WRITE, + LL_I3C_CONTROLLER_MTYPE_DIRECT, + (data->ccc_target_idx == payload->targets.num_targets) + ? LL_I3C_GENERATE_STOP + : LL_I3C_GENERATE_RESTART); + + /* Change state to second part of CCC communication */ + if (data->msg_state == STM32_I3C_MSG_CCC) { + data->msg_state = STM32_I3C_MSG_CCC_P2; + } + } + break; + } + default: + break; + } +} + +/* Handles the I3C event ISR */ +static void i3c_stm32_event_isr(void *arg) +{ + const struct device *dev = (const struct device *)arg; + + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + I3C_TypeDef *i3c = config->i3c; + + /* TX FIFO not full handler */ + if (LL_I3C_IsActiveFlag_TXFNF(i3c) && LL_I3C_IsEnabledIT_TXFNF(i3c)) { + i3c_stm32_event_isr_tx(dev); + } + + /* RX FIFO not empty handler */ + if (LL_I3C_IsActiveFlag_RXFNE(i3c) && LL_I3C_IsEnabledIT_RXFNE(i3c)) { + i3c_stm32_event_isr_rx(dev); + } + + /* Control FIFO not full handler */ + if (LL_I3C_IsActiveFlag_CFNF(i3c) && LL_I3C_IsEnabledIT_CFNF(i3c)) { + i3c_stm32_event_isr_cf(dev); + } + + /* Status FIFO not empty handler */ + if (LL_I3C_IsActiveFlag_SFNE(i3c) && LL_I3C_IsEnabledIT_SFNE(i3c)) { + + if (data->msg_state == STM32_I3C_MSG) { + size_t num_xfer = LL_I3C_GetXferDataCount(i3c); + + i3c_stm32_curr_msg_status_update_num_xfer(dev, num_xfer); + i3c_stm32_curr_msg_status_next(dev); + } else { + /* Read and discard the status FIFO word since it will not be used */ + uint32_t status_reg = i3c->SR; + + ARG_UNUSED(status_reg); + } + } + + /* Target read early termination flag (only used during CCC commands)*/ + if (LL_I3C_IsActiveFlag_RXTGTEND(i3c) && LL_I3C_IsEnabledIT_RXTGTEND(i3c)) { + /* A target ended a read request early during a CCC command, move the ptr to the + * next target + */ + data->ccc_target_payload++; + LL_I3C_ClearFlag_RXTGTEND(i3c); + } + + /* Frame complete handler */ + if (LL_I3C_IsActiveFlag_FC(i3c) && LL_I3C_IsEnabledIT_FC(i3c)) { + LL_I3C_ClearFlag_FC(i3c); + k_sem_give(&data->device_sync_sem); + + (void)pm_device_runtime_put(dev); + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + + /* Mark bus as idle after each frame complete */ + data->msg_state = STM32_I3C_MSG_IDLE; + } + +#ifdef CONFIG_I3C_USE_IBI + + k_sem_take(&data->ibi_lock_sem, K_FOREVER); + + if (LL_I3C_IsActiveFlag_IBI(i3c)) { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_IBI(i3c); + data->ibi_payload = LL_I3C_GetIBIPayload(i3c); + data->ibi_payload_size = LL_I3C_GetNbIBIAddData(i3c); + data->ibi_target_addr = LL_I3C_GetIBITargetAddr(i3c); + if ((data->ibi_payload == 0) && (data->ibi_payload_size == 0) && + (data->ibi_target_addr == 0)) { + LOG_ERR("Invalid Payload\n"); + } else { + LOG_INF("IBI done, payload received :%d,%d,%d\n", data->ibi_payload, + data->ibi_payload_size, data->ibi_target_addr); + if ((data->ibi_payload != 0) && (data->ibi_payload_size != 0)) { + struct i3c_device_desc *target; + + target = i3c_dev_list_i3c_addr_find(dev, data->ibi_target_addr); + + if (target != NULL) { + if (i3c_ibi_work_enqueue_target_irq( + target, (uint8_t *)&data->ibi_payload, + data->ibi_payload_size) != 0) { + LOG_ERR("Error enqueue IBI IRQ work"); + } + } else { + LOG_ERR("IBI from unknown device addr 0x%x", + data->ibi_target_addr); + } + } + } + } + + if (LL_I3C_IsActiveFlag_HJ(i3c)) { + int ret; + + LL_I3C_ClearFlag_HJ(i3c); + + ret = i3c_ibi_work_enqueue_hotjoin(dev); + if (ret != 0) { + LOG_ERR("IBI Failed to enqueue hotjoin work"); + } + } + + k_sem_give(&data->ibi_lock_sem); + +#endif + + if (LL_I3C_IsActiveFlag_WKP(i3c)) { + LL_I3C_ClearFlag_WKP(i3c); + } +} + +/* Handles the I3C error ISR */ +static void i3c_stm32_error_isr(void *arg) +{ + const struct device *dev = (const struct device *)arg; + + const struct i3c_stm32_config *config = dev->config; + struct i3c_stm32_data *data = dev->data; + I3C_TypeDef *i3c = config->i3c; + + i3c_stm32_log_err_type(dev); + + LL_I3C_ClearFlag_ERR(i3c); + + data->msg_state = STM32_I3C_MSG_ERR; + + k_sem_give(&data->device_sync_sem); + + (void)pm_device_runtime_put(dev); + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); +} + +#ifdef CONFIG_I3C_USE_IBI + +int i3c_stm32_ibi_hj_response(const struct device *dev, bool ack) +{ + const struct i3c_stm32_config *config = dev->config; + I3C_TypeDef *i3c = config->i3c; + + if (ack) { + /* + * This prevents pm_device_runtime from being called multiple times + * with redunant calls + */ + if (!hj_pm_lock) { + hj_pm_lock = true; + (void)pm_device_runtime_get(dev); + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + } + LL_I3C_EnableHJAck(i3c); + } else { + LL_I3C_DisableHJAck(i3c); + if (hj_pm_lock) { + hj_pm_lock = false; + (void)pm_device_runtime_put(dev); + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + } + } + + return 0; +} + +int i3c_stm32_ibi_enable(const struct device *dev, struct i3c_device_desc *target) +{ + int ret = 0; + uint8_t idx; + I3C_TypeDef *i3c; + struct i3c_ccc_events i3c_events; + struct i3c_stm32_data *data = dev->data; + const struct i3c_stm32_config *config = dev->config; + + i3c = config->i3c; + if (!i3c_device_is_ibi_capable(target)) { + return -EINVAL; + } + + if (data->ibi.num_addr >= ARRAY_SIZE(data->ibi.addr)) { + /* No more free entries in the IBI table */ + LOG_ERR("%s: no more free space in the IBI table", __func__); + return -ENOMEM; + } + + for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) { + if (data->ibi.addr[idx] == target->dynamic_addr) { + LOG_ERR("%s: selected target is already in the list", __func__); + return -EINVAL; + } + } + + if (data->ibi.num_addr > 0) { + for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) { + if (data->ibi.addr[idx] == 0U) { + break; + } + } + + if (idx >= ARRAY_SIZE(data->ibi.addr)) { + LOG_ERR("Cannot support more IBIs"); + return -ENOTSUP; + } + + } else { + idx = 0; + } + + data->ibi.addr[idx] = target->dynamic_addr; + data->ibi.num_addr += 1U; + + if (data->ibi.num_addr == 1U) { + (void)pm_device_runtime_get(dev); + } + + /* Tell target to enable IBI */ + i3c_events.events = I3C_CCC_EVT_INTR; + ret = i3c_ccc_do_events_set(target, true, &i3c_events); + if (ret != 0) { + LOG_ERR("Error sending IBI ENEC for 0x%02x (%d)", target->dynamic_addr, ret); + } + + /* Set I3C bus devices configuration */ + LL_I3C_ConfigDeviceCapabilities(i3c, (idx + 1), target->dynamic_addr, + LL_I3C_IBI_CAPABILITY, + i3c_ibi_has_payload(target) ? LL_I3C_IBI_DATA_ENABLE + : LL_I3C_IBI_DATA_DISABLE, + LL_I3C_CR_NO_CAPABILITY); + + return ret; +} + +int i3c_stm32_ibi_disable(const struct device *dev, struct i3c_device_desc *target) +{ + int ret = 0; + uint8_t idx; + I3C_TypeDef *i3c; + struct i3c_ccc_events i3c_events; + struct i3c_stm32_data *data = dev->data; + const struct i3c_stm32_config *config = dev->config; + + i3c = config->i3c; + if (!i3c_device_is_ibi_capable(target)) { + return -EINVAL; + } + + for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) { + if (target->dynamic_addr == data->ibi.addr[idx]) { + break; + } + } + + if (idx == ARRAY_SIZE(data->ibi.addr)) { + LOG_ERR("%s: target is not in list of registered addresses", __func__); + return -ENODEV; + } + + data->ibi.addr[idx] = 0U; + data->ibi.num_addr -= 1U; + + if (data->ibi.num_addr == 0U) { + (void)pm_device_runtime_put(dev); + } + + /* Tell target to disable IBI */ + i3c_events.events = I3C_CCC_EVT_INTR; + ret = i3c_ccc_do_events_set(target, false, &i3c_events); + if (ret != 0) { + LOG_ERR("Error sending IBI DISEC for 0x%02x (%d)", target->dynamic_addr, ret); + } + + /* Set I3C bus devices configuration */ + LL_I3C_ConfigDeviceCapabilities(i3c, (idx + 1), target->dynamic_addr, + LL_I3C_IBI_NO_CAPABILITY, + LL_I3C_IBI_DATA_DISABLE, + LL_I3C_CR_NO_CAPABILITY); + + return ret; +} + +#endif /* CONFIG_I3C_USE_IBI */ + +#ifdef CONFIG_I3C_STM32_DMA +static void i3c_stm32_tx_rx_msg_config(const struct device *dma_dev, void *user_data, + uint32_t channel, int status) +{ + const struct device *dev = (const struct device *)user_data; + + if (i3c_stm32_curr_msg_xfer_next(dev) != 0) { + /* No more messages to transmit/receive */ + return; + } + + uint8_t *buf = NULL; + size_t *offset = 0; + uint32_t len = 0; + + i3c_stm32_curr_msg_xfer_get_buf(dev, &buf, &len, &offset); + i3c_stm32_dma_msg_config(dev, (uint32_t)buf, len); +} + +static void i3c_stm32_dma_tx_cb(const struct device *dma_dev, void *user_data, uint32_t channel, + int status) +{ + i3c_stm32_tx_rx_msg_config(dma_dev, user_data, channel, status); +} + +static void i3c_stm32_dma_rx_cb(const struct device *dma_dev, void *user_data, uint32_t channel, + int status) +{ + i3c_stm32_tx_rx_msg_config(dma_dev, user_data, channel, status); +} + +static void i3c_stm32_dma_tc_cb(const struct device *dma_dev, void *user_data, uint32_t channel, + int status) +{ +} + +static void i3c_stm32_dma_rs_cb(const struct device *dma_dev, void *user_data, uint32_t channel, + int status) +{ +} + +#endif + +static DEVICE_API(i3c, i3c_stm32_driver_api) = { + .i2c_api.configure = i3c_stm32_i2c_configure, + .i2c_api.transfer = i3c_stm32_i2c_transfer, +#ifdef CONFIG_I2C_RTIO + .i2c_api.iodev_submit = i2c_iodev_submit_fallback, +#endif + .configure = i3c_stm32_configure, + .config_get = i3c_stm32_config_get, + .i3c_device_find = i3c_stm32_device_find, + .i3c_xfers = i3c_stm32_i3c_transfer, + .do_daa = i3c_stm32_do_daa, + .do_ccc = i3c_stm32_do_ccc, +#ifdef CONFIG_I3C_USE_IBI + .ibi_hj_response = i3c_stm32_ibi_hj_response, + .ibi_enable = i3c_stm32_ibi_enable, + .ibi_disable = i3c_stm32_ibi_disable, +#endif +#ifdef CONFIG_I3C_RTIO + .iodev_submit = i3c_iodev_submit_fallback, +#endif +}; + +#ifdef CONFIG_I3C_STM32_DMA +#define STM32_I3C_DMA_CHANNEL_INIT(index, dir, dir_cap, src_dev, dest_dev) \ + .dma_dev = DEVICE_DT_GET(STM32_DMA_CTLR(index, dir)), \ + .dma_channel = DT_INST_DMAS_CELL_BY_NAME(index, dir, channel), \ + .dma_cfg = \ + { \ + .dma_slot = STM32_DMA_SLOT(index, dir, slot), \ + .channel_direction = \ + STM32_DMA_CONFIG_DIRECTION(STM32_DMA_CHANNEL_CONFIG(index, dir)), \ + .channel_priority = \ + STM32_DMA_CONFIG_PRIORITY(STM32_DMA_CHANNEL_CONFIG(index, dir)), \ + .source_data_size = STM32_DMA_CONFIG_##src_dev##_DATA_SIZE( \ + STM32_DMA_CHANNEL_CONFIG(index, dir)), \ + .dest_data_size = STM32_DMA_CONFIG_##dest_dev##_DATA_SIZE( \ + STM32_DMA_CHANNEL_CONFIG(index, dir)), \ + .source_burst_length = 1, /* SINGLE transfer */ \ + .dest_burst_length = 1, \ + .block_count = 1, \ + .dma_callback = i3c_stm32_dma_##dir##_cb, \ + }, \ + .src_addr_increment = \ + STM32_DMA_CONFIG_##src_dev##_ADDR_INC(STM32_DMA_CHANNEL_CONFIG(index, dir)), \ + .dst_addr_increment = \ + STM32_DMA_CONFIG_##dest_dev##_ADDR_INC(STM32_DMA_CHANNEL_CONFIG(index, dir)), \ + .fifo_threshold = STM32_DMA_FEATURES_FIFO_THRESHOLD(STM32_DMA_FEATURES(index, dir)), + +#endif + +#ifdef CONFIG_I3C_STM32_DMA +#define STM32_I3C_DMA_CHANNEL(index, dir, DIR, src, dest) \ + .dma_##dir = {COND_CODE_1(DT_INST_DMAS_HAS_NAME(index, dir), \ + (STM32_I3C_DMA_CHANNEL_INIT(index, dir, DIR, src, dest)), \ + (NULL))}, + +#else +#define STM32_I3C_DMA_CHANNEL(index, dir, DIR, src, dest) +#endif + +#define STM32_I3C_IRQ_CONNECT_AND_ENABLE(index) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, event, irq), \ + DT_INST_IRQ_BY_NAME(index, event, priority), i3c_stm32_event_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, event, irq)); \ + \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, error, irq), \ + DT_INST_IRQ_BY_NAME(index, error, priority), i3c_stm32_error_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, error, irq)); \ + } while (false) + +#define STM32_I3C_IRQ_HANDLER_DECL(index) \ + static void i3c_stm32_irq_config_func_##index(const struct device *dev) + +#define STM32_I3C_IRQ_HANDLER_FUNCTION(index) .irq_config_func = i3c_stm32_irq_config_func_##index, + +#define STM32_I3C_IRQ_HANDLER(index) \ + static void i3c_stm32_irq_config_func_##index(const struct device *dev) \ + { \ + STM32_I3C_IRQ_CONNECT_AND_ENABLE(index); \ + } + +#define I3C_STM32_INIT(index) \ + STM32_I3C_IRQ_HANDLER_DECL(index); \ + \ + static const struct stm32_pclken pclken_##index[] = STM32_DT_INST_CLOCKS(index); \ + PINCTRL_DT_INST_DEFINE(index); \ + static struct i3c_device_desc i3c_stm32_dev_arr_##index[] = \ + I3C_DEVICE_ARRAY_DT_INST(index); \ + static struct i3c_i2c_device_desc i3c_i2c_stm32_dev_arr_##index[] = \ + I3C_I2C_DEVICE_ARRAY_DT_INST(index); \ + \ + static const struct i3c_stm32_config i3c_stm32_cfg_##index = { \ + .i3c = (I3C_TypeDef *)DT_INST_REG_ADDR(index), \ + STM32_I3C_IRQ_HANDLER_FUNCTION(index).pclken = pclken_##index, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .drv_cfg.dev_list.i3c = i3c_stm32_dev_arr_##index, \ + .drv_cfg.dev_list.num_i3c = ARRAY_SIZE(i3c_stm32_dev_arr_##index), \ + .drv_cfg.dev_list.i2c = i3c_i2c_stm32_dev_arr_##index, \ + .drv_cfg.dev_list.num_i2c = ARRAY_SIZE(i3c_i2c_stm32_dev_arr_##index), \ + }; \ + \ + static struct i3c_stm32_data i3c_stm32_data_##index = { \ + .drv_data.ctrl_config.scl.i2c = DT_INST_PROP_OR(index, i2c_scl_hz, 0), \ + .drv_data.ctrl_config.scl.i3c = DT_INST_PROP_OR(index, i3c_scl_hz, 0), \ + STM32_I3C_DMA_CHANNEL(index, rx, RX, PERIPHERAL, MEMORY) \ + STM32_I3C_DMA_CHANNEL(index, tx, TX, MEMORY, PERIPHERAL) \ + STM32_I3C_DMA_CHANNEL(index, tc, TC, MEMORY, PERIPHERAL) \ + STM32_I3C_DMA_CHANNEL(index, rs, RS, PERIPHERAL, MEMORY)}; \ + \ + PM_DEVICE_DT_INST_DEFINE(index, i3c_stm32_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(index, &i3c_stm32_init, PM_DEVICE_DT_INST_GET(index), \ + &i3c_stm32_data_##index, &i3c_stm32_cfg_##index, POST_KERNEL, \ + CONFIG_I3C_CONTROLLER_INIT_PRIORITY, &i3c_stm32_driver_api); \ + \ + STM32_I3C_IRQ_HANDLER(index) + +DT_INST_FOREACH_STATUS_OKAY(I3C_STM32_INIT) diff --git a/drivers/i3c/i3c_test.c b/drivers/i3c/i3c_test.c index 165449747d859..09586433ec954 100644 --- a/drivers/i3c/i3c_test.c +++ b/drivers/i3c/i3c_test.c @@ -32,7 +32,7 @@ static int vnd_i3c_recover_bus(const struct device *dev) return -ENOTSUP; } -static const struct i3c_driver_api vnd_i3c_api = { +static DEVICE_API(i3c, vnd_i3c_api) = { .configure = vnd_i3c_configure, .config_get = vnd_i3c_config_get, .recover_bus = vnd_i3c_recover_bus, diff --git a/drivers/ieee802154/CMakeLists.txt b/drivers/ieee802154/CMakeLists.txt index 3fdb65790afeb..f731bdb9f55bf 100644 --- a/drivers/ieee802154/CMakeLists.txt +++ b/drivers/ieee802154/CMakeLists.txt @@ -15,6 +15,7 @@ zephyr_library_sources_ifdef(CONFIG_IEEE802154_CC2520 ieee802154_cc2520.c) zephyr_library_sources_ifdef(CONFIG_IEEE802154_DW1000 ieee802154_dw1000.c) zephyr_library_sources_ifdef(CONFIG_IEEE802154_KW41Z ieee802154_kw41z.c) zephyr_library_sources_ifdef(CONFIG_IEEE802154_MCR20A ieee802154_mcr20a.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_MCXW ieee802154_mcxw.c ieee802154_mcxw_utils.c) zephyr_library_sources_ifdef(CONFIG_IEEE802154_NRF5 ieee802154_nrf5.c) zephyr_library_sources_ifdef(CONFIG_IEEE802154_RF2XX ieee802154_rf2xx.c) zephyr_library_sources_ifdef(CONFIG_IEEE802154_RF2XX ieee802154_rf2xx_iface.c) diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index 629b492a57997..a3f89c72665b9 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -60,6 +60,14 @@ config IEEE802154_VENDOR_OUI endif # IEEE802154_VENDOR_OUI_ENABLE +config IEEE802154_L2_PKT_INCL_FCS + bool "Include FCS field in the L2 packet" + default y if IEEE802154_RAW_MODE || NET_L2_OPENTHREAD + help + Some 802.15.4 L2 implementations expect FCS to be included in the + packet, while others do not. Allow to configure this behavior based + on the upper layer selected. + source "drivers/ieee802154/Kconfig.b91" source "drivers/ieee802154/Kconfig.cc2520" @@ -68,6 +76,8 @@ source "drivers/ieee802154/Kconfig.kw41z" source "drivers/ieee802154/Kconfig.mcr20a" +source "drivers/ieee802154/Kconfig.mcxw" + source "drivers/ieee802154/Kconfig.nrf5" source "drivers/ieee802154/Kconfig.cc1200" diff --git a/drivers/ieee802154/Kconfig.mcxw b/drivers/ieee802154/Kconfig.mcxw new file mode 100644 index 0000000000000..5829a8f9736f4 --- /dev/null +++ b/drivers/ieee802154/Kconfig.mcxw @@ -0,0 +1,28 @@ +# NXP MCXW 802.15.4 configuration options + +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +menuconfig IEEE802154_MCXW + bool "NXP MCXW series IEEE 802.15.4 Driver" + default y + depends on DT_HAS_NXP_MCXW_IEEE802154_ENABLED + depends on COUNTER + +if IEEE802154_MCXW + +config IEEE802154_MCXW_INIT_PRIO + int "Initial priority for the IEEE802154 driver" + default 80 + +config IEEE802154_MCXW_RX_STACK_SIZE + int "Driver's internal RX thread stack size" + default 800 + + +config IEEE802154_MCXW_CSL_ACCURACY + int "Csl accuracy for delayed operations" + default 100 + + +endif diff --git a/drivers/ieee802154/Kconfig.nrf5 b/drivers/ieee802154/Kconfig.nrf5 index bf4bcd1be8cf4..90f1d512d5b2b 100644 --- a/drivers/ieee802154/Kconfig.nrf5 +++ b/drivers/ieee802154/Kconfig.nrf5 @@ -62,14 +62,6 @@ config IEEE802154_NRF5_UICR_EUI64_REG endif # IEEE802154_NRF5_UICR_EUI64_ENABLE -config IEEE802154_NRF5_FCS_IN_LENGTH - bool "Include FCS field in the overall packet length" - default y if IEEE802154_RAW_MODE || NET_L2_OPENTHREAD - help - Some 802.15.4 L2 implementations expect that FCS length is included in - the overall packet length while others not. Allow to configure this - behavior, based on the selected upper layer. - config IEEE802154_NRF5_DELAY_TRX_ACC int "Clock accuracy for delayed operations" default CLOCK_CONTROL_NRF_ACCURACY if (CLOCK_CONTROL_NRF && (CLOCK_CONTROL_NRF_ACCURACY < $(UINT8_MAX))) diff --git a/drivers/ieee802154/ieee802154_b91.c b/drivers/ieee802154/ieee802154_b91.c index 0a28af4715d08..a5d03db3cec49 100644 --- a/drivers/ieee802154/ieee802154_b91.c +++ b/drivers/ieee802154/ieee802154_b91.c @@ -260,7 +260,7 @@ static void b91_send_ack(uint8_t seq_num) /* RX IRQ handler */ static void b91_rf_rx_isr(void) { - uint8_t status; + int status; uint8_t length; uint8_t *payload; struct net_pkt *pkt; @@ -272,8 +272,7 @@ static void b91_rf_rx_isr(void) /* check CRC */ if (rf_zigbee_packet_crc_ok(data.rx_buffer)) { /* get payload length */ - if (IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) || - IS_ENABLED(CONFIG_NET_L2_OPENTHREAD)) { + if (IS_ENABLED(CONFIG_IEEE802154_L2_PKT_INCL_FCS)) { length = data.rx_buffer[B91_LENGTH_OFFSET]; } else { length = data.rx_buffer[B91_LENGTH_OFFSET] - B91_FCS_LENGTH; diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c index 62f0a151b3d78..519ea9aa9d6dc 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c @@ -413,10 +413,7 @@ static void ieee802154_cc13xx_cc26xx_rx_done( corr = drv_data->rx_data[i][len--] & 0x3F; rssi = drv_data->rx_data[i][len--]; - /* remove fcs as it is not expected by L2 - * But keep it for RAW mode - */ - if (IS_ENABLED(CONFIG_NET_L2_IEEE802154)) { + if (!IS_ENABLED(CONFIG_IEEE802154_L2_PKT_INCL_FCS)) { len -= 2; } diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index 3f6d7067705b6..3a9f215ce0e17 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -340,8 +340,7 @@ static void drv_rx_done(struct ieee802154_cc13xx_cc26xx_subg_data *drv_data) status = drv_data->rx_data[i][len--]; rssi = drv_data->rx_data[i][len--]; - /* TODO: Configure firmware to include CRC in raw mode. */ - if (IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) && len > 0) { + if (IS_ENABLED(CONFIG_IEEE802154_L2_PKT_INCL_FCS) && len > 0) { /* append CRC-16/CCITT */ uint16_t crc = 0; diff --git a/drivers/ieee802154/ieee802154_cc2520.c b/drivers/ieee802154/ieee802154_cc2520.c index b1c7dd699e735..0ed4467dd3bb1 100644 --- a/drivers/ieee802154/ieee802154_cc2520.c +++ b/drivers/ieee802154/ieee802154_cc2520.c @@ -624,7 +624,7 @@ static void cc2520_rx(void *p1, void *p2, void *p3) goto flush; } - if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE)) { + if (!IS_ENABLED(CONFIG_IEEE802154_L2_PKT_INCL_FCS)) { pkt_len -= 2U; } @@ -1397,7 +1397,7 @@ static int cc2520_crypto_init(const struct device *dev) return 0; } -struct crypto_driver_api cc2520_crypto_api = { +DEVICE_API(crypto, cc2520_crypto_api) = { .query_hw_caps = cc2520_crypto_hw_caps, .cipher_begin_session = cc2520_crypto_begin_session, .cipher_free_session = cc2520_crypto_free_session, diff --git a/drivers/ieee802154/ieee802154_dw1000.c b/drivers/ieee802154/ieee802154_dw1000.c index b0e06488731f4..f8acaa928d470 100644 --- a/drivers/ieee802154/ieee802154_dw1000.c +++ b/drivers/ieee802154/ieee802154_dw1000.c @@ -274,16 +274,6 @@ static inline uint32_t dwt_reg_read_u32(const struct device *dev, return sys_get_le32(buf); } -static inline uint16_t dwt_reg_read_u16(const struct device *dev, - uint8_t reg, uint16_t offset) -{ - uint8_t buf[sizeof(uint16_t)]; - - dwt_spi_transfer(dev, reg, offset, sizeof(buf), buf, false); - - return sys_get_le16(buf); -} - static inline uint8_t dwt_reg_read_u8(const struct device *dev, uint8_t reg, uint16_t offset) { @@ -416,7 +406,7 @@ static inline void dwt_irq_handle_rx(const struct device *dev, uint32_t sys_stat rx_pacc = (rx_finfo & DWT_RX_FINFO_RXPACC_MASK) >> DWT_RX_FINFO_RXPACC_SHIFT; - if (!(IS_ENABLED(CONFIG_IEEE802154_RAW_MODE))) { + if (!IS_ENABLED(CONFIG_IEEE802154_L2_PKT_INCL_FCS)) { pkt_len -= DWT_FCS_LENGTH; } diff --git a/drivers/ieee802154/ieee802154_mcxw.c b/drivers/ieee802154/ieee802154_mcxw.c new file mode 100644 index 0000000000000..247342e66a132 --- /dev/null +++ b/drivers/ieee802154/ieee802154_mcxw.c @@ -0,0 +1,1360 @@ +/* ieee802154_mcxw.c - NXP MCXW 802.15.4 driver */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_mcxw_ieee802154 + +#define LOG_MODULE_NAME ieee802154_mcxw + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_NET_L2_OPENTHREAD) +#include +#include +#endif + +#include +#include + +#include + +#include +#include +#include + +#include "EmbeddedTypes.h" +#include "Phy.h" + +#include "fwk_platform_ot.h" + +#include "ieee802154_mcxw.h" +#include "ieee802154_mcxw_utils.h" + +void PLATFORM_RemoteActiveReq(void); +void PLATFORM_RemoteActiveRel(void); + +#if CONFIG_IEEE802154_CSL_ENDPOINT + +#define CMP_OVHD (4 * IEEE802154_SYMBOL_TIME_US) /* 2 LPTRM (32 kHz) ticks */ + +static bool_t csl_rx = FALSE; + +static void set_csl_sample_time(void); +static void start_csl_receiver(void); +static void stop_csl_receiver(void); +static uint16_t rf_compute_csl_phase(uint32_t aTimeUs); + +#else /* CONFIG_IEEE802154_CSL_ENDPOINT */ +#define start_csl_receiver() +#define stop_csl_receiver() +#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */ + +static volatile uint32_t sun_rx_mode = RX_ON_IDLE_START; + +/* Private functions */ +static void rf_abort(void); +static void rf_set_channel(uint8_t channel); +static void rf_set_tx_power(int8_t tx_power); +static uint64_t rf_adjust_tstamp_from_phy(uint64_t ts); + +#if CONFIG_IEEE802154_CSL_ENDPOINT || CONFIG_NET_PKT_TXTIME +static uint32_t rf_adjust_tstamp_from_app(uint32_t time); +#endif /* CONFIG_IEEE802154_CSL_ENDPOINT || CONFIG_NET_PKT_TXTIME */ + +static void rf_rx_on_idle(uint32_t newValue); + +static uint8_t ot_phy_ctx = (uint8_t)(-1); + +static struct mcxw_context mcxw_ctx; + +/** + * Stub function used for controlling low power mode + */ +WEAK void app_allow_device_to_slepp(void) +{ +} + +/** + * Stub function used for controlling low power mode + */ +WEAK void app_disallow_device_to_slepp(void) +{ +} + +void mcxw_get_eui64(uint8_t *eui64) +{ + __ASSERT_NO_MSG(eui64); + + /* PLATFORM_GetIeee802_15_4Addr(); */ + sys_rand_get(eui64, sizeof(mcxw_ctx.mac)); + + eui64[0] = (eui64[0] & ~0x01) | 0x02; +} + +static int mcxw_set_pan_id(const struct device *dev, uint16_t aPanId) +{ + struct mcxw_context *mcxw_radio = dev->data; + + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibPanId_c; + msg.msgData.setReq.PibAttributeValue = (uint64_t)aPanId; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); + + mcxw_radio->pan_id = aPanId; + + return 0; +} + +static int mcxw_set_extended_address(const struct device *dev, const uint8_t *ieee_addr) +{ + struct mcxw_context *mcxw_radio = dev->data; + + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibLongAddress_c; + msg.msgData.setReq.PibAttributeValue = *(uint64_t *)ieee_addr; + + memcpy(mcxw_radio->mac, ieee_addr, 8); + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); + + return 0; +} + +static int mcxw_set_short_address(const struct device *dev, uint16_t aShortAddress) +{ + ARG_UNUSED(dev); + + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibShortAddress_c; + msg.msgData.setReq.PibAttributeValue = (uint64_t)aShortAddress; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); + + return 0; +} + +static int mcxw_filter(const struct device *dev, bool set, enum ieee802154_filter_type type, + const struct ieee802154_filter *filter) +{ + LOG_DBG("Applying filter %u", type); + + if (!set) { + return -ENOTSUP; + } + + if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) { + return mcxw_set_extended_address(dev, filter->ieee_addr); + } else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) { + return mcxw_set_short_address(dev, filter->short_addr); + } else if (type == IEEE802154_FILTER_TYPE_PAN_ID) { + return mcxw_set_pan_id(dev, filter->pan_id); + } + + return -ENOTSUP; +} + +void mcxw_radio_receive(void) +{ + macToPlmeMessage_t msg; + phyStatus_t phy_status; + + app_disallow_device_to_slepp(); + + __ASSERT(mcxw_ctx.state != RADIO_STATE_DISABLED, "Radio RX invalid state"); + + mcxw_ctx.state = RADIO_STATE_RECEIVE; + + rf_abort(); + rf_set_channel(mcxw_ctx.channel); + + if (sun_rx_mode) { + start_csl_receiver(); + + /* restart Rx on idle only if it was enabled */ + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibRxOnWhenIdle; + msg.msgData.setReq.PibAttributeValue = (uint64_t)1; + + phy_status = MAC_PLME_SapHandler(&msg, ot_phy_ctx); + __ASSERT_NO_MSG(phy_status == gPhySuccess_c); + } +} + +static uint8_t mcxw_get_acc(const struct device *dev) +{ + ARG_UNUSED(dev); + + return CONFIG_IEEE802154_MCXW_CSL_ACCURACY; +} + +static int mcxw_start(const struct device *dev) +{ + struct mcxw_context *mcxw_radio = dev->data; + + __ASSERT(mcxw_radio->state == RADIO_STATE_DISABLED, "%s", __func__); + + mcxw_radio->state = RADIO_STATE_SLEEP; + + rf_rx_on_idle(RX_ON_IDLE_START); + + mcxw_radio_receive(); + + return 0; +} + +static int mcxw_stop(const struct device *dev) +{ + struct mcxw_context *mcxw_radio = dev->data; + + __ASSERT(mcxw_radio->state != RADIO_STATE_DISABLED, "%s", __func__); + + stop_csl_receiver(); + + mcxw_radio->state = RADIO_STATE_DISABLED; + + return 0; +} + +void mcxw_radio_sleep(void) +{ + __ASSERT_NO_MSG(((mcxw_ctx.state != RADIO_STATE_TRANSMIT) && + (mcxw_ctx.state != RADIO_STATE_DISABLED))); + + rf_abort(); + + stop_csl_receiver(); + + app_allow_device_to_slepp(); + + mcxw_ctx.state = RADIO_STATE_SLEEP; +} + +static void mcxw_enable_src_match(bool enable) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetSAMState_c; + msg.msgData.SAMState = enable; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +static int mcxw_src_match_entry(bool extended, uint8_t *address) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeAddToSapTable_c; + msg.msgData.deviceAddr.panId = mcxw_ctx.pan_id; + + if (extended) { + msg.msgData.deviceAddr.mode = 3; + memcpy(msg.msgData.deviceAddr.addr, address, 8); + } else { + msg.msgData.deviceAddr.mode = 2; + memcpy(msg.msgData.deviceAddr.addr, address, 2); + } + + if (gPhySuccess_c != MAC_PLME_SapHandler(&msg, ot_phy_ctx)) { + /* the status is not returned from PHY over RPMSG */ + return -ENOMEM; + } + + return 0; +} + +static int mcxw_src_clear_entry(bool extended, uint8_t *address) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeRemoveFromSAMTable_c; + msg.msgData.deviceAddr.panId = mcxw_ctx.pan_id; + + if (extended) { + msg.msgData.deviceAddr.mode = 3; + memcpy(msg.msgData.deviceAddr.addr, address, 8); + } else { + msg.msgData.deviceAddr.mode = 2; + memcpy(msg.msgData.deviceAddr.addr, address, 2); + } + + if (gPhySuccess_c != MAC_PLME_SapHandler(&msg, ot_phy_ctx)) { + /* the status is not returned from PHY over RPMSG */ + return -ENOENT; + } + + return 0; +} + +static int handle_ack(struct mcxw_context *mcxw_radio) +{ + uint8_t len; + struct net_pkt *pkt; + int err = 0; + + len = mcxw_radio->rx_ack_frame.length; + pkt = net_pkt_rx_alloc_with_buffer(mcxw_radio->iface, len, AF_UNSPEC, 0, K_NO_WAIT); + if (!pkt) { + LOG_ERR("No free packet available."); + err = -ENOMEM; + goto exit; + } + + if (net_pkt_write(pkt, mcxw_radio->rx_ack_frame.psdu, len) < 0) { + LOG_ERR("Failed to write to a packet."); + err = -ENOMEM; + goto free_ack; + } + + /* Use some fake values for LQI and RSSI. */ + net_pkt_set_ieee802154_lqi(pkt, 80); + net_pkt_set_ieee802154_rssi_dbm(pkt, -40); + + net_pkt_set_timestamp_ns(pkt, mcxw_radio->rx_ack_frame.timestamp); + + net_pkt_cursor_init(pkt); + + if (ieee802154_handle_ack(mcxw_radio->iface, pkt) != NET_OK) { + LOG_ERR("ACK packet not handled - releasing."); + } + +free_ack: + net_pkt_unref(pkt); + +exit: + mcxw_radio->rx_ack_frame.length = 0; + return err; +} + +static int mcxw_tx(const struct device *dev, enum ieee802154_tx_mode mode, struct net_pkt *pkt, + struct net_buf *frag) +{ + struct mcxw_context *mcxw_radio = dev->data; + /* tx_data buffer has reserved memory for both macToPdDataMessage_t and actual data frame + * after + */ + macToPdDataMessage_t *msg = (macToPdDataMessage_t *)mcxw_radio->tx_data; + phyStatus_t phy_status; + + uint8_t payload_len = frag->len; + uint8_t *payload = frag->data; + + app_disallow_device_to_slepp(); + + __ASSERT(mcxw_radio->state != RADIO_STATE_DISABLED, "%s: radio disabled", __func__); + + if (payload_len > IEEE802154_MTU) { + LOG_ERR("Payload too large: %d", payload_len); + return -EMSGSIZE; + } + + mcxw_radio->tx_frame.length = payload_len + IEEE802154_FCS_LENGTH; + memcpy(mcxw_radio->tx_frame.psdu, payload, payload_len); + + mcxw_radio->tx_frame.sec_processed = net_pkt_ieee802154_frame_secured(pkt); + mcxw_radio->tx_frame.hdr_updated = net_pkt_ieee802154_mac_hdr_rdy(pkt); + + rf_set_channel(mcxw_radio->channel); + + msg->msgType = gPdDataReq_c; + msg->msgData.dataReq.slottedTx = gPhyUnslottedMode_c; + msg->msgData.dataReq.psduLength = mcxw_radio->tx_frame.length; + msg->msgData.dataReq.CCABeforeTx = gPhyNoCCABeforeTx_c; + msg->msgData.dataReq.startTime = gPhySeqStartAsap_c; + + /* tx_frame.psdu will point to tx_frame.tx_data data buffer after macToPdDataMessage_t + * structure + */ + msg->msgData.dataReq.pPsdu = mcxw_radio->tx_frame.psdu; + + if (ieee802154_is_ar_flag_set(frag)) { + msg->msgData.dataReq.ackRequired = gPhyRxAckRqd_c; + /* The 3 bytes are 1 byte frame length and 2 bytes FCS */ + msg->msgData.dataReq.txDuration = + IEEE802154_CCA_LEN_SYM + IEEE802154_PHY_SHR_LEN_SYM + + (3 + mcxw_radio->tx_frame.length) * RADIO_SYMBOLS_PER_OCTET + + IEEE802154_TURNAROUND_LEN_SYM; + + if (is_frame_version_2015(frag->data, frag->len)) { + /* Because enhanced ack can be of variable length we need to set the timeout + * value to account for the FCF and addressing fields only, and stop the + * timeout timer after they are received and validated as a valid ACK + */ + msg->msgData.dataReq.txDuration += IEEE802154_ENH_ACK_WAIT_SYM; + } else { + msg->msgData.dataReq.txDuration += IEEE802154_IMM_ACK_WAIT_SYM; + } + } else { + msg->msgData.dataReq.ackRequired = gPhyNoAckRqd_c; + msg->msgData.dataReq.txDuration = 0xFFFFFFFFU; + } + + switch (mode) { + case IEEE802154_TX_MODE_DIRECT: + msg->msgData.dataReq.CCABeforeTx = gPhyNoCCABeforeTx_c; + break; + case IEEE802154_TX_MODE_CCA: + msg->msgData.dataReq.CCABeforeTx = gPhyCCAMode1_c; + break; + +#if defined(CONFIG_NET_PKT_TXTIME) + case IEEE802154_TX_MODE_TXTIME: + case IEEE802154_TX_MODE_TXTIME_CCA: + mcxw_radio->tx_frame.tx_delay = net_pkt_timestamp_ns(pkt); + msg->msgData.dataReq.startTime = + rf_adjust_tstamp_from_app(mcxw_radio->tx_frame.tx_delay); + msg->msgData.dataReq.startTime /= IEEE802154_SYMBOL_TIME_US; + break; +#endif + default: + break; + } + + msg->msgData.dataReq.flags = 0; + +#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 + if (is_keyid_mode_1(mcxw_radio->tx_frame.psdu, mcxw_radio->tx_frame.length)) { + if (!net_pkt_ieee802154_frame_secured(pkt)) { + msg->msgData.dataReq.flags |= gPhyEncFrame; + + if (!net_pkt_ieee802154_mac_hdr_rdy(pkt)) { + msg->msgData.dataReq.flags |= gPhyUpdHDr; + +#if CONFIG_IEEE802154_CSL_ENDPOINT + /* Previously aFrame->mInfo.mTxInfo.mCslPresent was used to + * determine if the radio code should update the IE header. This + * field is no longer set by the OT stack. Until the issue is fixed + * in OT stack check if CSL period is > 0 and always update CSL IE + * in that case. + */ + if (mcxw_radio->csl_period) { + uint32_t hdr_time_us; + + start_csl_receiver(); + + /* Add TX_ENCRYPT_DELAY_SYM symbols delay to allow + * encryption to finish + */ + msg->msgData.dataReq.startTime = + PhyTime_ReadClock() + TX_ENCRYPT_DELAY_SYM; + + hdr_time_us = mcxw_get_time(NULL) + + (TX_ENCRYPT_DELAY_SYM + + IEEE802154_PHY_SHR_LEN_SYM) * + IEEE802154_SYMBOL_TIME_US; + set_csl_ie(mcxw_radio->tx_frame.psdu, + mcxw_radio->tx_frame.length, + mcxw_radio->csl_period, + rf_compute_csl_phase(hdr_time_us)); + } +#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */ + } + } + } + +#endif + + k_sem_reset(&mcxw_radio->tx_wait); + + phy_status = MAC_PD_SapHandler(msg, ot_phy_ctx); + if (phy_status == gPhySuccess_c) { + mcxw_radio->tx_status = 0; + mcxw_radio->state = RADIO_STATE_TRANSMIT; + } else { + return -EIO; + } + + k_sem_take(&mcxw_radio->tx_wait, K_FOREVER); + + /* PWR_AllowDeviceToSleep(); */ + + mcxw_radio_receive(); + + switch (mcxw_radio->tx_status) { + case 0: + if (mcxw_radio->rx_ack_frame.length) { + return handle_ack(mcxw_radio); + } + return 0; + + default: + return -(mcxw_radio->tx_status); + } +} + +void mcxw_rx_thread(void *arg1, void *arg2, void *arg3) +{ + struct mcxw_context *mcxw_radio = (struct mcxw_context *)arg1; + struct net_pkt *pkt; + struct mcxw_rx_frame rx_frame; + + ARG_UNUSED(arg2); + ARG_UNUSED(arg3); + + while (true) { + pkt = NULL; + + LOG_DBG("Waiting for frame"); + + if (k_msgq_get(&mcxw_radio->rx_msgq, &rx_frame, K_FOREVER) < 0) { + LOG_ERR("Failed to get RX data from message queue"); + continue; + } + + pkt = net_pkt_rx_alloc_with_buffer(mcxw_radio->iface, rx_frame.length, AF_UNSPEC, 0, + K_FOREVER); + + if (net_pkt_write(pkt, rx_frame.psdu, rx_frame.length)) { + goto drop; + } + + net_pkt_set_ieee802154_lqi(pkt, rx_frame.lqi); + net_pkt_set_ieee802154_rssi_dbm(pkt, rx_frame.rssi); + net_pkt_set_ieee802154_ack_fpb(pkt, rx_frame.ack_fpb); + +#if defined(CONFIG_NET_PKT_TIMESTAMP) + net_pkt_set_timestamp_ns(pkt, rx_frame.timestamp); +#endif + +#if defined(CONFIG_NET_L2_OPENTHREAD) + net_pkt_set_ieee802154_ack_seb(pkt, rx_frame.ack_seb); +#endif + if (net_recv_data(mcxw_radio->iface, pkt) < 0) { + LOG_ERR("Packet dropped by NET stack"); + goto drop; + } + + k_free(rx_frame.phy_buffer); + rx_frame.phy_buffer = NULL; + + /* restart rx on idle if enough space in message queue */ + if (k_msgq_num_free_get(&mcxw_radio->rx_msgq) >= 2) { + rf_rx_on_idle(RX_ON_IDLE_START); + } + + continue; + +drop: + /* PWR_AllowDeviceToSleep(); */ + net_pkt_unref(pkt); + } +} + +int8_t mcxw_get_rssi(void) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeGetReq_c; + msg.msgData.getReq.PibAttribute = gPhyGetRSSILevel_c; + msg.msgData.getReq.PibAttributeValue = 127; /* RSSI is invalid*/ + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); + + return (int8_t)msg.msgData.getReq.PibAttributeValue; +} + +void mcxw_set_promiscuous(bool aEnable) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibPromiscuousMode_c; + msg.msgData.setReq.PibAttributeValue = (uint64_t)aEnable; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +void mcxw_set_pan_coord(bool aEnable) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibPanCoordinator_c; + msg.msgData.setReq.PibAttributeValue = (uint64_t)aEnable; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +static int mcxw_energy_scan(const struct device *dev, uint16_t duration, + energy_scan_done_cb_t done_cb) +{ + + int status = 0; + phyStatus_t phy_status; + macToPlmeMessage_t msg; + + app_disallow_device_to_slepp(); + + struct mcxw_context *mcxw_radio = dev->data; + + __ASSERT_NO_MSG(((mcxw_radio->state != RADIO_STATE_TRANSMIT) && + (mcxw_radio->state != RADIO_STATE_DISABLED))); + + rf_abort(); + + rf_set_channel(mcxw_radio->channel); + + mcxw_radio->energy_scan_done = done_cb; + + msg.msgType = gPlmeEdReq_c; + msg.msgData.edReq.startTime = gPhySeqStartAsap_c; + msg.msgData.edReq.measureDurationSym = duration * 1000; + + phy_status = MAC_PLME_SapHandler(&msg, ot_phy_ctx); + if (phy_status != gPhySuccess_c) { + mcxw_radio->energy_scan_done = NULL; + status = -EIO; + } + + return status; +} + +static int mcxw_set_txpower(const struct device *dev, int16_t dbm) +{ + struct mcxw_context *mcxw_radio = dev->data; + + LOG_DBG("%d", dbm); + + if (dbm != mcxw_radio->tx_pwr_lvl) { + /* Set Power level for TX */ + rf_set_tx_power(dbm); + mcxw_radio->tx_pwr_lvl = dbm; + } + + return 0; +} + +static void mcxw_configure_enh_ack_probing(const struct ieee802154_config *config) +{ + uint32_t ie_param = 0; + macToPlmeMessage_t msg; + + uint8_t *header_ie_buf = (uint8_t *)(config->ack_ie.header_ie); + + ie_param = (header_ie_buf[6] == 0x03 ? IeData_Lqi_c : 0) | + (header_ie_buf[7] == 0x02 ? IeData_LinkMargin_c : 0) | + (header_ie_buf[8] == 0x01 ? IeData_Rssi_c : 0); + + msg.msgType = gPlmeConfigureAckIeData_c; + msg.msgData.AckIeData.param = (ie_param > 0 ? IeData_MSB_VALID_DATA : 0); + msg.msgData.AckIeData.param |= ie_param; + msg.msgData.AckIeData.shortAddr = config->ack_ie.short_addr; + memcpy(msg.msgData.AckIeData.extAddr, config->ack_ie.ext_addr, 8); + memcpy(msg.msgData.AckIeData.data, config->ack_ie.header_ie, + config->ack_ie.header_ie->length); + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +static void mcxw_set_mac_key(struct ieee802154_key *mac_keys) +{ + macToPlmeMessage_t msg; + + __ASSERT_NO_MSG(mac_keys); + __ASSERT_NO_MSG(mac_keys[0].key_id && mac_keys[0].key_value); + __ASSERT_NO_MSG(mac_keys[1].key_id && mac_keys[1].key_value); + __ASSERT_NO_MSG(mac_keys[2].key_id && mac_keys[2].key_value); + + msg.msgType = gPlmeSetMacKey_c; + msg.msgData.MacKeyData.keyId = *(mac_keys[1].key_id); + + memcpy(msg.msgData.MacKeyData.prevKey, mac_keys[0].key_value, 16); + memcpy(msg.msgData.MacKeyData.currKey, mac_keys[1].key_value, 16); + memcpy(msg.msgData.MacKeyData.nextKey, mac_keys[2].key_value, 16); + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +void mcxw_set_mac_frame_counter(uint32_t frame_counter) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetMacFrameCounter_c; + msg.msgData.MacFrameCounter = frame_counter; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +void mcxw_set_mac_frame_counter_if_larger(uint32_t frame_counter) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetMacFrameCounterIfLarger_c; + msg.msgData.MacFrameCounter = frame_counter; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +#if CONFIG_IEEE802154_CSL_ENDPOINT + +static void mcxw_receive_at(uint8_t channel, uint32_t start, uint32_t duration) +{ + macToPlmeMessage_t msg; + + __ASSERT_NO_MSG(mcxw_ctx.state == RADIO_STATE_SLEEP); + mcxw_ctx.state = RADIO_STATE_RECEIVE; + + /* checks internally if the channel needs to be changed */ + rf_set_channel(mcxw_ctx.channel); + + start = rf_adjust_tstamp_from_app(start); + + msg.msgType = gPlmeSetTRxStateReq_c; + msg.msgData.setTRxStateReq.slottedMode = gPhyUnslottedMode_c; + msg.msgData.setTRxStateReq.state = gPhySetRxOn_c; + msg.msgData.setTRxStateReq.rxDuration = duration / IEEE802154_SYMBOL_TIME_US; + msg.msgData.setTRxStateReq.startTime = start / IEEE802154_SYMBOL_TIME_US; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +static void mcxw_enable_csl(uint16_t period) +{ + mcxw_ctx.csl_period = period; + + macToPlmeMessage_t msg; + + msg.msgType = gPlmeCslEnable_c; + msg.msgData.cslPeriod = period; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +static void set_csl_sample_time(void) +{ + if (!mcxw_ctx.csl_period) { + return; + } + + macToPlmeMessage_t msg; + uint32_t csl_period = mcxw_ctx.csl_period * 10 * IEEE802154_SYMBOL_TIME_US; + uint32_t dt = mcxw_ctx.csl_sample_time - (uint32_t)mcxw_get_time(NULL); + + /* next channel sample should be in the future */ + while ((dt <= CMP_OVHD) || (dt > (CMP_OVHD + 2 * csl_period))) { + mcxw_ctx.csl_sample_time += csl_period; + dt = mcxw_ctx.csl_sample_time - (uint32_t)mcxw_get_time(NULL); + } + + /* The CSL sample time is in microseconds and PHY function expects also microseconds */ + msg.msgType = gPlmeCslSetSampleTime_c; + msg.msgData.cslSampleTime = rf_adjust_tstamp_from_app(mcxw_ctx.csl_sample_time); + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +static void start_csl_receiver(void) +{ + if (!mcxw_ctx.csl_period) { + return; + } + + /* NBU has to be awake during CSL receiver trx so that conversion from + * PHY timebase (NBU) to TMR timebase (host) is valid + */ + if (!csl_rx) { + PLATFORM_RemoteActiveReq(); + + csl_rx = TRUE; + } + + /* sample time is converted to PHY time */ + set_csl_sample_time(); +} + +static void stop_csl_receiver(void) +{ + if (csl_rx) { + PLATFORM_RemoteActiveRel(); + + csl_rx = FALSE; + } +} + +/* + * Compute the CSL Phase for the time_us - i.e. the time from the time_us to + * mcxw_ctx.csl_sample_time. The assumption is that mcxw_ctx.csl_sample_time > time_us. Since the + * time is kept with a limited timer in reality it means that sometimes mcxw_ctx.csl_sample_time < + * time_us, when the timer overflows. Therefore the formula should be: + * + * if (time_us <= mcxw_ctx.csl_sample_time) + * csl_phase_us = mcxw_ctx.csl_sample_time - time_us; + * else + * csl_phase_us = MAX_TIMER_VALUE - time_us + mcxw_ctx.csl_sample_time; + * + * For simplicity the formula below has been used. + */ +static uint16_t rf_compute_csl_phase(uint32_t time_us) +{ + /* convert CSL Period in microseconds - it was given in 10 symbols */ + uint32_t csl_period_us = mcxw_ctx.csl_period * 10 * IEEE802154_SYMBOL_TIME_US; + uint32_t csl_phase_us = + (csl_period_us - (time_us % csl_period_us) + + (mcxw_ctx.csl_sample_time % csl_period_us)) % csl_period_us; + + return (uint16_t)(csl_phase_us / (10 * IEEE802154_SYMBOL_TIME_US) + 1); +} +#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */ + +/*************************************************************************************************/ +static void rf_abort(void) +{ + macToPlmeMessage_t msg; + + sun_rx_mode = RX_ON_IDLE_START; + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibRxOnWhenIdle; + msg.msgData.setReq.PibAttributeValue = (uint64_t)0; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); + + msg.msgType = gPlmeSetTRxStateReq_c; + msg.msgData.setTRxStateReq.state = gPhyForceTRxOff_c; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +static void rf_set_channel(uint8_t channel) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibCurrentChannel_c; + msg.msgData.setReq.PibAttributeValue = (uint64_t)channel; + + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +static int mcxw_cca(const struct device *dev) +{ + macToPlmeMessage_t msg; + phyStatus_t phy_status; + + struct mcxw_context *mcxw_radio = dev->data; + + msg.msgType = gPlmeCcaReq_c; + msg.msgData.ccaReq.ccaType = gPhyCCAMode1_c; + msg.msgData.ccaReq.contCcaMode = gPhyContCcaDisabled; + + phy_status = MAC_PLME_SapHandler(&msg, ot_phy_ctx); + + __ASSERT_NO_MSG(phy_status == gPhySuccess_c); + + k_sem_take(&mcxw_radio->cca_wait, K_FOREVER); + + return (mcxw_radio->tx_status == OT_ERROR_CHANNEL_ACCESS_FAILURE) ? -EBUSY : 0; +} + +static int mcxw_set_channel(const struct device *dev, uint16_t channel) +{ + struct mcxw_context *mcxw_radio = dev->data; + + LOG_DBG("%u", channel); + + if (channel != mcxw_radio->channel) { + + if (channel < 11 || channel > 26) { + return channel < 11 ? -ENOTSUP : -EINVAL; + } + + mcxw_radio->channel = channel; + } + + return 0; +} + +static net_time_t mcxw_get_time(const struct device *dev) +{ + static uint64_t sw_timestamp; + static uint64_t hw_timestamp; + + ARG_UNUSED(dev); + + /* Get new 32bit HW timestamp */ + uint32_t ticks; + uint64_t hw_timestamp_new; + uint64_t wrapped_val = 0; + uint64_t increment; + unsigned int key; + + key = irq_lock(); + + if (counter_get_value(mcxw_ctx.counter, &ticks)) { + irq_unlock(key); + return -1; + } + + hw_timestamp_new = counter_ticks_to_us(mcxw_ctx.counter, ticks); + + /* Check if the timestamp has wrapped around */ + if (hw_timestamp > hw_timestamp_new) { + wrapped_val = + COUNT_TO_USEC(((uint64_t)1 << 32), counter_get_frequency(mcxw_ctx.counter)); + } + + increment = (hw_timestamp_new + wrapped_val) - hw_timestamp; + sw_timestamp += increment; + + /* Store new HW timestamp for next iteration */ + hw_timestamp = hw_timestamp_new; + + irq_unlock(key); + + return (net_time_t)sw_timestamp; +} + +static void rf_set_tx_power(int8_t tx_power) +{ + macToPlmeMessage_t msg; + + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibTransmitPower_c; + msg.msgData.setReq.PibAttributeValue = (uint64_t)tx_power; + + MAC_PLME_SapHandler(&msg, ot_phy_ctx); +} + +/* Used to convert from phy clock timestamp (in symbols) to platform time (in us) + * the reception timestamp which must use a true 64bit timestamp source + */ +static uint64_t rf_adjust_tstamp_from_phy(uint64_t ts) +{ + uint64_t now = PhyTime_ReadClock(); + uint64_t delta; + + delta = (now >= ts) ? (now - ts) : ((PHY_TMR_MAX_VALUE + now) - ts); + delta *= IEEE802154_SYMBOL_TIME_US; + + return mcxw_get_time(NULL) - delta; +} + +#if CONFIG_IEEE802154_CSL_ENDPOINT || CONFIG_NET_PKT_TXTIME +static uint32_t rf_adjust_tstamp_from_app(uint32_t time) +{ + /* The phy timestamp is in symbols so we need to convert it to microseconds */ + uint64_t ts = PhyTime_ReadClock() * IEEE802154_SYMBOL_TIME_US; + uint32_t delta = time - (uint32_t)mcxw_get_time(NULL); + + return (uint32_t)(ts + delta); +} +#endif /* CONFIG_IEEE802154_CSL_ENDPOINT || CONFIG_NET_PKT_TXTIME */ + +/* Phy Data Service Access Point handler + * Called by Phy to notify when Tx has been done or Rx data is available + */ +phyStatus_t pd_mac_sap_handler(void *msg, instanceId_t instance) +{ + pdDataToMacMessage_t *data_msg = (pdDataToMacMessage_t *)msg; + + __ASSERT_NO_MSG(msg != NULL); + + /* PWR_DisallowDeviceToSleep(); */ + + switch (data_msg->msgType) { + case gPdDataCnf_c: + /* TX is done */ +#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 + if (is_keyid_mode_1(mcxw_ctx.tx_frame.psdu, mcxw_ctx.tx_frame.length) && + !mcxw_ctx.tx_frame.sec_processed && !mcxw_ctx.tx_frame.hdr_updated) { + set_frame_counter(mcxw_ctx.tx_frame.psdu, mcxw_ctx.tx_frame.length, + data_msg->fc); + mcxw_ctx.tx_frame.hdr_updated = true; + } +#endif + + mcxw_ctx.tx_frame.length = 0; + mcxw_ctx.tx_status = 0; + mcxw_ctx.state = RADIO_STATE_RECEIVE; + + mcxw_ctx.rx_ack_frame.channel = mcxw_ctx.channel; + mcxw_ctx.rx_ack_frame.length = data_msg->msgData.dataCnf.ackLength; + mcxw_ctx.rx_ack_frame.timestamp = data_msg->msgData.dataCnf.timeStamp; + memcpy(mcxw_ctx.rx_ack_frame.psdu, data_msg->msgData.dataCnf.ackData, + mcxw_ctx.rx_ack_frame.length); + + k_sem_give(&mcxw_ctx.tx_wait); + + k_free(msg); + break; + + case gPdDataInd_c: + /* RX is done */ + struct mcxw_rx_frame rx_frame; + + /* retrieve frame information and data */ + rx_frame.lqi = data_msg->msgData.dataInd.ppduLinkQuality; + rx_frame.rssi = data_msg->msgData.dataInd.ppduRssi; + rx_frame.timestamp = rf_adjust_tstamp_from_phy(data_msg->msgData.dataInd.timeStamp); + rx_frame.ack_fpb = data_msg->msgData.dataInd.rxAckFp; + rx_frame.length = data_msg->msgData.dataInd.psduLength; + rx_frame.psdu = data_msg->msgData.dataInd.pPsdu; + rx_frame.ack_seb = data_msg->msgData.dataInd.ackedWithSecEnhAck; + + rx_frame.phy_buffer = (void *)msg; + + /* stop rx on idle if message queue is almost full */ + if (k_msgq_num_free_get(&mcxw_ctx.rx_msgq) == 1) { + rf_rx_on_idle(RX_ON_IDLE_STOP); + } + + /* add the rx message in queue */ + if (k_msgq_put(&mcxw_ctx.rx_msgq, &rx_frame, K_NO_WAIT) < 0) { + LOG_ERR("Failed to push RX data to message queue"); + } + break; + + default: + /* PWR_AllowDeviceToSleep(); */ + break; + } + + stop_csl_receiver(); + + return gPhySuccess_c; +} + +/* Phy Layer Management Entities Service Access Point handler + * Called by Phy to notify PLME event + */ +phyStatus_t plme_mac_sap_handler(void *msg, instanceId_t instance) +{ + plmeToMacMessage_t *plme_msg = (plmeToMacMessage_t *)msg; + + __ASSERT_NO_MSG(msg != NULL); + + /* PWR_DisallowDeviceToSleep(); */ + + switch (plme_msg->msgType) { + case gPlmeCcaCnf_c: + if (plme_msg->msgData.ccaCnf.status == gPhyChannelBusy_c) { + /* Channel is busy */ + mcxw_ctx.tx_status = EBUSY; + } else { + mcxw_ctx.tx_status = 0; + } + mcxw_ctx.state = RADIO_STATE_RECEIVE; + + k_sem_give(&mcxw_ctx.cca_wait); + break; + case gPlmeEdCnf_c: + /* Scan done */ + if (mcxw_ctx.energy_scan_done != NULL) { + energy_scan_done_cb_t callback = mcxw_ctx.energy_scan_done; + + mcxw_ctx.max_ed = plme_msg->msgData.edCnf.maxEnergyLeveldB; + + mcxw_ctx.energy_scan_done = NULL; + callback(net_if_get_device(mcxw_ctx.iface), mcxw_ctx.max_ed); + } + break; + case gPlmeTimeoutInd_c: + if (RADIO_STATE_TRANSMIT == mcxw_ctx.state) { + /* Ack timeout */ +#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 + if (is_keyid_mode_1(mcxw_ctx.tx_frame.psdu, mcxw_ctx.tx_frame.length) && + !mcxw_ctx.tx_frame.sec_processed && !mcxw_ctx.tx_frame.hdr_updated) { + set_frame_counter(mcxw_ctx.tx_frame.psdu, mcxw_ctx.tx_frame.length, + plme_msg->fc); + mcxw_ctx.tx_frame.hdr_updated = true; + } +#endif + + mcxw_ctx.state = RADIO_STATE_RECEIVE; + /* No ack */ + mcxw_ctx.tx_status = ENOMSG; + + k_sem_give(&mcxw_ctx.tx_wait); + } else if (RADIO_STATE_RECEIVE == mcxw_ctx.state) { + /* CSL Receive AT state has ended with timeout and we are returning to SLEEP + * state + */ + mcxw_ctx.state = RADIO_STATE_SLEEP; + /* PWR_AllowDeviceToSleep(); */ + } + break; + case gPlmeAbortInd_c: + /* TX Packet was loaded into TX Packet RAM but the TX/TR seq did not ended ok */ +#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 + if (is_keyid_mode_1(mcxw_ctx.tx_frame.psdu, mcxw_ctx.tx_frame.length) && + !mcxw_ctx.tx_frame.sec_processed && !mcxw_ctx.tx_frame.hdr_updated) { + set_frame_counter(mcxw_ctx.tx_frame.psdu, mcxw_ctx.tx_frame.length, + plme_msg->fc); + mcxw_ctx.tx_frame.hdr_updated = true; + } +#endif + + mcxw_ctx.state = RADIO_STATE_RECEIVE; + mcxw_ctx.tx_status = EIO; + + k_sem_give(&mcxw_ctx.tx_wait); + break; + default: + /* PWR_AllowDeviceToSleep(); */ + break; + } + /* The message has been allocated by the Phy, we have to free it */ + k_free(msg); + + stop_csl_receiver(); + + return gPhySuccess_c; +} + +static int mcxw_configure(const struct device *dev, enum ieee802154_config_type type, + const struct ieee802154_config *config) +{ + ARG_UNUSED(dev); + + switch (type) { + + case IEEE802154_CONFIG_AUTO_ACK_FPB: + if (config->auto_ack_fpb.mode == IEEE802154_FPB_ADDR_MATCH_THREAD) { + mcxw_enable_src_match(config->auto_ack_fpb.enabled); + } + /* TODO IEEE802154_FPB_ADDR_MATCH_ZIGBEE */ + break; + + case IEEE802154_CONFIG_ACK_FPB: + if (config->ack_fpb.enabled) { + return mcxw_src_match_entry(config->ack_fpb.extended, config->ack_fpb.addr); + } else { + return mcxw_src_clear_entry(config->ack_fpb.extended, config->ack_fpb.addr); + } + + /* TODO otPlatRadioClearSrcMatchShortEntries */ + /* TODO otPlatRadioClearSrcMatchExtEntries */ + break; + + case IEEE802154_CONFIG_PAN_COORDINATOR: + mcxw_set_pan_coord(config->pan_coordinator); + break; + + case IEEE802154_CONFIG_PROMISCUOUS: + mcxw_set_promiscuous(config->promiscuous); + break; + + case IEEE802154_CONFIG_MAC_KEYS: + mcxw_set_mac_key(config->mac_keys); + break; + + case IEEE802154_CONFIG_FRAME_COUNTER: + mcxw_set_mac_frame_counter(config->frame_counter); + break; + + case IEEE802154_CONFIG_FRAME_COUNTER_IF_LARGER: + mcxw_set_mac_frame_counter_if_larger(config->frame_counter); + break; + + case IEEE802154_CONFIG_ENH_ACK_HEADER_IE: + mcxw_configure_enh_ack_probing(config); + break; + +#if defined(CONFIG_IEEE802154_CSL_ENDPOINT) + case IEEE802154_CONFIG_EXPECTED_RX_TIME: + mcxw_ctx.csl_sample_time = config->expected_rx_time; + break; + + case IEEE802154_CONFIG_RX_SLOT: + mcxw_receive_at(config->rx_slot.channel, config->rx_slot.start / NSEC_PER_USEC, + config->rx_slot.duration / NSEC_PER_USEC); + break; + + case IEEE802154_CONFIG_CSL_PERIOD: + mcxw_enable_csl(config->csl_period); + break; +#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */ + + case IEEE802154_CONFIG_RX_ON_WHEN_IDLE: + if (config->rx_on_when_idle) { + rf_rx_on_idle(RX_ON_IDLE_START); + } else { + rf_rx_on_idle(RX_ON_IDLE_STOP); + } + break; + + case IEEE802154_CONFIG_EVENT_HANDLER: + break; + + case IEEE802154_OPENTHREAD_CONFIG_MAX_EXTRA_CCA_ATTEMPTS: + break; + + default: + return -EINVAL; + } + + return 0; +} + +IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26); + +static int mcxw_attr_get(const struct device *dev, enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + + if (ieee802154_attr_get_channel_page_and_range( + attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915, + &drv_attr.phy_supported_channels, value) == 0) { + return 0; + } + + return -EIO; +} + +static enum ieee802154_hw_caps mcxw_get_capabilities(const struct device *dev) +{ + enum ieee802154_hw_caps caps; + + caps = IEEE802154_HW_FCS | IEEE802154_HW_PROMISC | IEEE802154_HW_FILTER | + IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_RX_TX_ACK | IEEE802154_HW_ENERGY_SCAN | + IEEE802154_HW_TXTIME | IEEE802154_HW_RXTIME | IEEE802154_HW_SLEEP_TO_TX | + IEEE802154_RX_ON_WHEN_IDLE | IEEE802154_HW_TX_SEC | + IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA | IEEE802154_HW_SELECTIVE_TXCHANNEL | + IEEE802154_OPENTHREAD_HW_CST; + return caps; +} + +static int mcxw_init(const struct device *dev) +{ + struct mcxw_context *mcxw_radio = dev->data; + + macToPlmeMessage_t msg; + + if (PLATFORM_InitOT() < 0) { + return -EIO; + } + + Phy_Init(); + + ot_phy_ctx = PHY_get_ctx(); + + /* Register Phy Data Service Access Point and Phy Layer Management Entities Service Access + * Point handlers + */ + Phy_RegisterSapHandlers((PD_MAC_SapHandler_t)pd_mac_sap_handler, + (PLME_MAC_SapHandler_t)plme_mac_sap_handler, ot_phy_ctx); + + msg.msgType = gPlmeEnableEncryption_c; + (void)MAC_PLME_SapHandler(&msg, ot_phy_ctx); + + mcxw_radio->state = RADIO_STATE_DISABLED; + mcxw_radio->energy_scan_done = NULL; + + mcxw_radio->channel = DEFAULT_CHANNEL; + rf_set_channel(mcxw_radio->channel); + + mcxw_radio->tx_frame.length = 0; + /* Make the psdu point to the space after macToPdDataMessage_t in the data buffer */ + mcxw_radio->tx_frame.psdu = mcxw_radio->tx_data + sizeof(macToPdDataMessage_t); + + /* Get and start LPTRM counter */ + mcxw_radio->counter = DEVICE_DT_GET(DT_NODELABEL(lptmr0)); + if (counter_start(mcxw_radio->counter)) { + return -EIO; + } + + /* Init TX semaphore */ + k_sem_init(&mcxw_radio->tx_wait, 0, 1); + /* Init CCA semaphore */ + k_sem_init(&mcxw_radio->cca_wait, 0, 1); + + /* Init RX message queue */ + k_msgq_init(&mcxw_radio->rx_msgq, mcxw_radio->rx_msgq_buffer, sizeof(mcxw_rx_frame), + NMAX_RXRING_BUFFERS); + + memset(&(mcxw_radio->rx_ack_frame), 0, sizeof(mcxw_radio->rx_ack_frame)); + mcxw_radio->rx_ack_frame.psdu = mcxw_radio->rx_ack_data; + + k_thread_create(&mcxw_radio->rx_thread, mcxw_radio->rx_stack, + CONFIG_IEEE802154_MCXW_RX_STACK_SIZE, mcxw_rx_thread, mcxw_radio, NULL, + NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); + + k_thread_name_set(&mcxw_radio->rx_thread, "mcxw_rx"); + + return 0; +} + +static void mcxw_iface_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct mcxw_context *mcxw_radio = dev->data; + + mcxw_get_eui64(mcxw_radio->mac); + + net_if_set_link_addr(iface, mcxw_radio->mac, sizeof(mcxw_radio->mac), NET_LINK_IEEE802154); + mcxw_radio->iface = iface; + ieee802154_init(iface); +} + +static void rf_rx_on_idle(uint32_t new_val) +{ + macToPlmeMessage_t msg; + phyStatus_t phy_status; + + new_val %= 2; + if (sun_rx_mode != new_val) { + sun_rx_mode = new_val; + msg.msgType = gPlmeSetReq_c; + msg.msgData.setReq.PibAttribute = gPhyPibRxOnWhenIdle; + msg.msgData.setReq.PibAttributeValue = (uint64_t)sun_rx_mode; + + phy_status = MAC_PLME_SapHandler(&msg, ot_phy_ctx); + + __ASSERT_NO_MSG(phy_status == gPhySuccess_c); + } +} + +static const struct ieee802154_radio_api mcxw71_radio_api = { + .iface_api.init = mcxw_iface_init, + + .get_capabilities = mcxw_get_capabilities, + .cca = mcxw_cca, + .set_channel = mcxw_set_channel, + .filter = mcxw_filter, + .set_txpower = mcxw_set_txpower, + .start = mcxw_start, + .stop = mcxw_stop, + .configure = mcxw_configure, + .tx = mcxw_tx, + .ed_scan = mcxw_energy_scan, + .get_time = mcxw_get_time, + .get_sch_acc = mcxw_get_acc, + .attr_get = mcxw_attr_get, +}; + +#if defined(CONFIG_NET_L2_IEEE802154) +#define L2 IEEE802154_L2 +#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(IEEE802154_L2) +#define MTU IEEE802154_MTU +#elif defined(CONFIG_NET_L2_OPENTHREAD) +#define L2 OPENTHREAD_L2 +#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(OPENTHREAD_L2) +#define MTU 1280 +#elif defined(CONFIG_NET_L2_CUSTOM_IEEE802154) +#define L2 CUSTOM_IEEE802154_L2 +#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(CUSTOM_IEEE802154_L2) +#define MTU CONFIG_NET_L2_CUSTOM_IEEE802154_MTU +#endif + +NET_DEVICE_DT_INST_DEFINE(0, mcxw_init, NULL, &mcxw_ctx, NULL, CONFIG_IEEE802154_MCXW_INIT_PRIO, + &mcxw71_radio_api, L2, L2_CTX_TYPE, MTU); diff --git a/drivers/ieee802154/ieee802154_mcxw.h b/drivers/ieee802154/ieee802154_mcxw.h new file mode 100644 index 0000000000000..eb3fb284dc6ef --- /dev/null +++ b/drivers/ieee802154/ieee802154_mcxw.h @@ -0,0 +1,125 @@ +/* ieee802154_mcxw.h - NXP MCXW 802.15.4 driver */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_IEEE802154_IEEE802154_MCXW_H_ +#define ZEPHYR_DRIVERS_IEEE802154_IEEE802154_MCXW_H_ + +#include + +#include "PhyInterface.h" + +#define TX_ENCRYPT_DELAY_SYM 200 + +#define DEFAULT_CHANNEL (11) +#define DEFAULT_CCA_MODE (gPhyCCAMode1_c) +#define IEEE802154_ACK_REQUEST (1 << 5) +#define IEEE802154_MIN_LENGTH (5) +#define IEEE802154_FRM_CTL_LO_OFFSET (0) +#define IEEE802154_DSN_OFFSET (2) +#define IEEE802154_FRM_TYPE_MASK (0x7) +#define IEEE802154_FRM_TYPE_ACK (0x2) +#define IEEE802154_SYMBOL_TIME_US (16) +#define IEEE802154_TURNAROUND_LEN_SYM (12) +#define IEEE802154_CCA_LEN_SYM (8) +#define IEEE802154_PHY_SHR_LEN_SYM (10) +#define IEEE802154_IMM_ACK_WAIT_SYM (54) +#define IEEE802154_ENH_ACK_WAIT_SYM (90) + +#define NMAX_RXRING_BUFFERS (8) +#define RX_ON_IDLE_START (1) +#define RX_ON_IDLE_STOP (0) + +#define PHY_TMR_MAX_VALUE (0x00FFFFFF) + +/* The Uncertainty of the scheduling CSL of transmission by the parent, in Âą10 us units. */ +#define CSL_UNCERT 32 + +#define RADIO_SYMBOLS_PER_OCTET (2) + +typedef enum mcxw_radio_state { + RADIO_STATE_DISABLED = 0, + RADIO_STATE_SLEEP = 1, + RADIO_STATE_RECEIVE = 2, + RADIO_STATE_TRANSMIT = 3, + RADIO_STATE_INVALID = 255, +} mcxw_radio_state; + +typedef struct mcxw_rx_frame { + uint8_t *psdu; + uint8_t length; + int8_t rssi; + uint8_t lqi; + uint32_t timestamp; + bool ack_fpb; + bool ack_seb; + uint64_t time; + void *phy_buffer; + uint8_t channel; +} mcxw_rx_frame; + +typedef struct mcxw_tx_frame { + uint8_t *psdu; + uint8_t length; + uint32_t tx_delay; + uint32_t tx_delay_base; + bool sec_processed; + bool hdr_updated; +} mcxw_tx_frame; + +struct mcxw_context { + /* Pointer to the network interface. */ + struct net_if *iface; + /* Pointer to the LPTMR counter device structure*/ + const struct device *counter; + /* 802.15.4 HW address. */ + uint8_t mac[8]; + /* RX thread stack. */ + K_KERNEL_STACK_MEMBER(rx_stack, CONFIG_IEEE802154_MCXW_RX_STACK_SIZE); + /* RX thread control block. */ + struct k_thread rx_thread; + /* RX message queue */ + struct k_msgq rx_msgq; + /* RX message queue buffer */ + char rx_msgq_buffer[NMAX_RXRING_BUFFERS * sizeof(mcxw_rx_frame)]; + /* TX synchronization semaphore */ + struct k_sem tx_wait; + /* TX synchronization semaphore */ + struct k_sem cca_wait; + /* Radio state */ + mcxw_radio_state state; + /* Pan ID */ + uint16_t pan_id; + /* Channel */ + uint8_t channel; + /* Maximum energy detected during ED scan */ + int8_t max_ed; + /* TX power level */ + int8_t tx_pwr_lvl; + /* Enery detect */ + energy_scan_done_cb_t energy_scan_done; + /* TX Status */ + int tx_status; + /* TX frame */ + mcxw_tx_frame tx_frame; + /* TX data */ + uint8_t tx_data[sizeof(macToPdDataMessage_t) + IEEE802154_MAX_PHY_PACKET_SIZE]; + /* RX mode */ + uint32_t rx_mode; + /* RX ACK buffers */ + mcxw_rx_frame rx_ack_frame; + /* RX ACK data */ + uint8_t rx_ack_data[IEEE802154_MAX_PHY_PACKET_SIZE]; + /* CSL period */ + uint32_t csl_period; + /* CSL sample time in microseconds */ + uint32_t csl_sample_time; + /* PHY context */ + uint8_t ot_phy_ctx; +}; + +#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_MCXW_H_ */ diff --git a/drivers/ieee802154/ieee802154_mcxw_utils.c b/drivers/ieee802154/ieee802154_mcxw_utils.c new file mode 100644 index 0000000000000..0367f8a26b64c --- /dev/null +++ b/drivers/ieee802154/ieee802154_mcxw_utils.c @@ -0,0 +1,356 @@ +/* ieee802154_mcxw_utils.c - NXP MCXW 802.15.4 driver utils*/ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include +#include +#include +#include + +#include + +#include "ieee802154_mcxw_utils.h" + +/* TODO IEEE 802.15.4 MAC Multipurpose frame format */ +/* TODO add function checks */ + +enum offset_fcf_fields { + OffsetFrameType = 0x00, + OffsetSecurityEnabled = 0x03, + OffsetFramePending = 0x04, + OffsetAR = 0x05, + OffsetPanIdCompression = 0x06, + OffsetSeqNumberSuppression = 0x08, + OffsetIEPresent = 0x09, + OffsetDstAddrMode = 0x0A, + OffsetFrameVersion = 0x0C, + OffsetSrcAddrMode = 0x0E, +}; + +enum mask_fcf_fields { + MaskFrameType = (0x7 << OffsetFrameType), + MaskSecurityEnabled = (0x01 << OffsetSecurityEnabled), + MaskFramePending = (0x01 << OffsetFramePending), + MaskAR = (0x01 << OffsetAR), + MaskPanIdCompression = (0x01 << OffsetPanIdCompression), + MaskSeqNumberSuppression = (0x01 << OffsetSeqNumberSuppression), + MaskIEPresent = (0x01 << OffsetIEPresent), + MaskDstAddrMode = (0x03 << OffsetDstAddrMode), + MaskFrameVersion = (0x03 << OffsetFrameVersion), + MaskSrcAddrMode = (0x03 << OffsetSrcAddrMode), +}; + +enum modes_dst_addr { + ModeDstAddrNone = 0x00, + ModeDstAddrShort = (0x02 << OffsetDstAddrMode), + ModeDstAddrExt = (0x03 << OffsetDstAddrMode), +}; + +enum version_frame { + VersionIeee2003 = 0x00, + VersionIeee2006 = 0x01, + VersionIeee2015 = 0x02, +}; + +enum modes_src_addr { + ModeSrcAddrNone = 0x00, + ModeSrcAddrShort = (0x02 << OffsetSrcAddrMode), + ModeSrcAddrExt = (0x03 << OffsetSrcAddrMode), +}; + +enum offset_scf_fields { + OffsetSecurityLevel = 0x00, + OffsetKeyIdMode = 0x03, + OffsetFrameCntSuppression = 0x05, + OffsetASNinNonce = 0x06, +}; + +enum mask_scf_fields { + MaskSecurityLevel = (0x07 << OffsetSecurityLevel), + MaskKeyIdMode = (0x03 << OffsetKeyIdMode), + MaskFrameCntSuppression = (0x1 << OffsetFrameCntSuppression), + MaskASNinNonce = (0x01 << OffsetASNinNonce), +}; + +static uint16_t get_frame_control_field(uint8_t *pdu, uint16_t length) +{ + if ((pdu == NULL) || (length < 3)) { + return 0x00; + } + + return (uint16_t)(pdu[0] | (pdu[1] << 8)); +} + +static bool is_security_enabled(uint16_t fcf) +{ + if (fcf) { + return (bool)(fcf & MaskSecurityEnabled); + } + + return false; +} + +static bool is_ie_present(uint16_t fcf) +{ + if (fcf) { + return (bool)(fcf & MaskIEPresent); + } + + return false; +} + +static uint8_t get_frame_version(uint16_t fcf) +{ + if (fcf) { + return (uint8_t)((fcf & MaskFrameVersion) >> OffsetFrameVersion); + } + + return 0xFF; +} + +static bool is_frame_version_2015_fcf(uint16_t fcf) +{ + if (fcf) { + return get_frame_version(fcf) == VersionIeee2015; + } + + return false; +} + +bool is_frame_version_2015(uint8_t *pdu, uint16_t length) +{ + uint16_t fcf = get_frame_control_field(pdu, length); + + if (fcf) { + return get_frame_version(fcf) == VersionIeee2015; + } + + return false; +} + +static bool is_sequence_number_suppression(uint16_t fcf) +{ + if (fcf) { + return (bool)(fcf & MaskSeqNumberSuppression); + } + + return false; +} + +static bool is_dst_panid_present(uint16_t fcf) +{ + bool present; + + if (!fcf) { + return false; + } + + if (is_frame_version_2015_fcf(fcf)) { + switch (fcf & (MaskDstAddrMode | MaskSrcAddrMode | MaskPanIdCompression)) { + case (ModeDstAddrNone | ModeSrcAddrNone): + case (ModeDstAddrShort | ModeSrcAddrNone | MaskPanIdCompression): + case (ModeDstAddrExt | ModeSrcAddrNone | MaskPanIdCompression): + case (ModeDstAddrNone | ModeSrcAddrShort): + case (ModeDstAddrNone | ModeSrcAddrExt): + case (ModeDstAddrNone | ModeSrcAddrShort | MaskPanIdCompression): + case (ModeDstAddrNone | ModeSrcAddrExt | MaskPanIdCompression): + case (ModeDstAddrExt | ModeSrcAddrExt | MaskPanIdCompression): + present = false; + break; + default: + present = true; + } + } else { + present = (bool)(fcf & MaskDstAddrMode); + } + + return present; +} + +static bool is_src_panid_present(uint16_t fcf) +{ + bool present; + + if (!fcf) { + return false; + } + + if (is_frame_version_2015_fcf(fcf)) { + switch (fcf & (MaskDstAddrMode | MaskSrcAddrMode | MaskPanIdCompression)) { + case (ModeDstAddrNone | ModeSrcAddrShort): + case (ModeDstAddrNone | ModeSrcAddrExt): + case (ModeDstAddrShort | ModeSrcAddrShort): + case (ModeDstAddrShort | ModeSrcAddrExt): + case (ModeDstAddrExt | ModeSrcAddrShort): + present = true; + break; + default: + present = false; + } + + } else { + present = ((fcf & MaskSrcAddrMode) != 0) && ((fcf & MaskPanIdCompression) == 0); + } + + return present; +} + +static uint8_t calculate_addr_field_size(uint16_t fcf) +{ + uint8_t size = 2; + + if (!fcf) { + return 0; + } + + if (!is_sequence_number_suppression(fcf)) { + size += 1; + } + + if (is_dst_panid_present(fcf)) { + size += 2; + } + + /* destination addressing mode */ + switch (fcf & MaskDstAddrMode) { + case ModeDstAddrShort: + size += 2; + break; + case ModeDstAddrExt: + size += 8; + break; + default: + break; + } + + if (is_src_panid_present(fcf)) { + size += 2; + } + + /* source addressing mode */ + switch (fcf & MaskSrcAddrMode) { + case ModeSrcAddrShort: + size += 2; + break; + case ModeSrcAddrExt: + size += 8; + break; + default: + break; + } + + return size; +} + +static uint8_t get_keyid_mode(uint8_t *pdu, uint16_t length) +{ + uint16_t fcf = get_frame_control_field(pdu, length); + uint8_t ash_start; + + if (is_security_enabled(fcf)) { + ash_start = calculate_addr_field_size(fcf); + return (uint8_t)((pdu[ash_start] & MaskKeyIdMode) >> OffsetKeyIdMode); + } + + return 0xFF; +} + +bool is_keyid_mode_1(uint8_t *pdu, uint16_t length) +{ + uint8_t key_mode = get_keyid_mode(pdu, length); + + if (key_mode == 0x01) { + return true; + } + + return false; +} + +void set_frame_counter(uint8_t *pdu, uint16_t length, uint32_t fc) +{ + uint16_t fcf = get_frame_control_field(pdu, length); + + if (is_security_enabled(fcf)) { + uint8_t ash_start = calculate_addr_field_size(fcf); + uint8_t scf = pdu[ash_start]; + + /* check that Frame Counter Suppression is not set */ + if (!(scf & MaskFrameCntSuppression)) { + sys_put_le32(fc, &pdu[ash_start + 1]); + } + } +} + +static uint8_t get_asn_size(uint8_t *pdu, uint16_t length) +{ + uint16_t fcf = get_frame_control_field(pdu, length); + + if (is_security_enabled(fcf)) { + uint8_t ash_start = calculate_addr_field_size(fcf); + uint8_t scf = pdu[ash_start]; + uint8_t size = 1; + + /* Frame Counter Suppression is not set */ + if (!(scf & MaskFrameCntSuppression)) { + size += 4; + } + + uint8_t key_mode = get_keyid_mode(pdu, length); + + switch (key_mode) { + case 0x01: + size += 1; + break; + case 0x02: + size += 5; + case 0x03: + size += 9; + default: + break; + } + + return size; + } + return 0; +} + +static uint8_t *get_csl_ie_content_start(uint8_t *pdu, uint16_t length) +{ + uint16_t fcf = get_frame_control_field(pdu, length); + + if (is_ie_present(fcf)) { + uint8_t ie_start_idx = calculate_addr_field_size(fcf) + get_asn_size(pdu, length); + uint8_t *cur_ie = &pdu[ie_start_idx]; + + uint8_t ie_header = (uint16_t)(cur_ie[0] | (cur_ie[1] << 8)); + uint8_t ie_length = ie_header & 0x7F; + uint8_t ie_el_id = ie_header & 0x7F80; + + while ((ie_el_id != 0x7e) && (ie_el_id != 0x7f)) { + if (ie_el_id == 0x1a) { + return (cur_ie + 2); + } + cur_ie += (2 + ie_length); + ie_header = (uint16_t)(cur_ie[0] | (cur_ie[1] << 8)); + ie_length = ie_header & 0x7F; + ie_el_id = ie_header & 0x7F80; + } + } + + return NULL; +} + +void set_csl_ie(uint8_t *pdu, uint16_t length, uint16_t period, uint16_t phase) +{ + uint8_t *csl_ie_content = get_csl_ie_content_start(pdu, length); + + if (csl_ie_content) { + sys_put_le16(phase, csl_ie_content); + sys_put_le16(period, csl_ie_content + 2); + } +} diff --git a/drivers/ieee802154/ieee802154_mcxw_utils.h b/drivers/ieee802154/ieee802154_mcxw_utils.h new file mode 100644 index 0000000000000..2b37538eeeb05 --- /dev/null +++ b/drivers/ieee802154/ieee802154_mcxw_utils.h @@ -0,0 +1,16 @@ +/* ieee802154_mcxw_utils.h - NXP MCXW 802.15.4 driver utils*/ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +bool is_frame_version_2015(uint8_t *pdu, uint16_t length); + +bool is_keyid_mode_1(uint8_t *pdu, uint16_t length); + +void set_frame_counter(uint8_t *pdu, uint16_t length, uint32_t fc); + +void set_csl_ie(uint8_t *pdu, uint16_t length, uint16_t period, uint16_t phase); diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 556ae9e0a36aa..ef6208ecc2755 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -172,7 +172,7 @@ static void nrf5_rx_thread(void *arg1, void *arg2, void *arg3) * The last 2 bytes contain LQI or FCS, depending if * automatic CRC handling is enabled or not, respectively. */ - if (IS_ENABLED(CONFIG_IEEE802154_NRF5_FCS_IN_LENGTH)) { + if (IS_ENABLED(CONFIG_IEEE802154_L2_PKT_INCL_FCS)) { pkt_len = rx_frame->psdu[0]; } else { pkt_len = rx_frame->psdu[0] - IEEE802154_FCS_LENGTH; @@ -419,7 +419,7 @@ static int handle_ack(struct nrf5_802154_data *nrf5_radio) } #endif - if (IS_ENABLED(CONFIG_IEEE802154_NRF5_FCS_IN_LENGTH)) { + if (IS_ENABLED(CONFIG_IEEE802154_L2_PKT_INCL_FCS)) { ack_len = nrf5_radio->ack_frame.psdu[0]; } else { ack_len = nrf5_radio->ack_frame.psdu[0] - IEEE802154_FCS_LENGTH; @@ -585,7 +585,7 @@ static int nrf5_tx(const struct device *dev, return -EMSGSIZE; } - LOG_DBG("%p (%u)", payload, payload_len); + LOG_DBG("%p (%u)", (void *)payload, payload_len); nrf5_radio->tx_psdu[0] = payload_len + IEEE802154_FCS_LENGTH; memcpy(nrf5_radio->tx_psdu + 1, payload, payload_len); diff --git a/drivers/ieee802154/ieee802154_rf2xx.c b/drivers/ieee802154/ieee802154_rf2xx.c index 1dd00c213ba7d..12c8106c08b18 100644 --- a/drivers/ieee802154/ieee802154_rf2xx.c +++ b/drivers/ieee802154/ieee802154_rf2xx.c @@ -208,9 +208,7 @@ static void rf2xx_trx_rx(const struct device *dev) return; } - if (!IS_ENABLED(CONFIG_IEEE802154_RAW_MODE) && - !IS_ENABLED(CONFIG_NET_L2_OPENTHREAD) && - pkt_len >= RX2XX_FRAME_FCS_LENGTH) { + if (!IS_ENABLED(CONFIG_IEEE802154_L2_PKT_INCL_FCS) && pkt_len >= RX2XX_FRAME_FCS_LENGTH) { pkt_len -= RX2XX_FRAME_FCS_LENGTH; } diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index 5232f05e2d127..ab28b03f03e2c 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -7,10 +7,11 @@ zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_INPUT_ADC_KEYS input_adc_keys.c) zephyr_library_sources_ifdef(CONFIG_INPUT_ANALOG_AXIS input_analog_axis.c) zephyr_library_sources_ifdef(CONFIG_INPUT_ANALOG_AXIS_SETTINGS input_analog_axis_settings.c) -zephyr_library_sources_ifdef(CONFIG_INPUT_CAP1203 input_cap1203.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_CAP12XX input_cap12xx.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CF1133 input_cf1133.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CHSC6X input_chsc6x.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CST816S input_cst816s.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_CY8CMBR3XXX input_cy8cmbr3xxx.c) zephyr_library_sources_ifdef(CONFIG_INPUT_ESP32_TOUCH_SENSOR input_esp32_touch_sensor.c) zephyr_library_sources_ifdef(CONFIG_INPUT_FT5336 input_ft5336.c) zephyr_library_sources_ifdef(CONFIG_INPUT_GPIO_KBD_MATRIX input_gpio_kbd_matrix.c) @@ -22,6 +23,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_ITE_IT8801_KBD input_ite_it8801_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_ITE_IT8XXX2_KBD input_ite_it8xxx2_kbd.c) zephyr_library_sources_ifdef(CONFIG_INPUT_KBD_MATRIX input_kbd_matrix.c) zephyr_library_sources_ifdef(CONFIG_INPUT_NPCX_KBD input_npcx_kbd.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_NUNCHUK input_nunchuk.c) zephyr_library_sources_ifdef(CONFIG_INPUT_PAT912X input_pat912x.c) zephyr_library_sources_ifdef(CONFIG_INPUT_PAW32XX input_paw32xx.c) zephyr_library_sources_ifdef(CONFIG_INPUT_PINNACLE input_pinnacle.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index d199ec88a319d..726916675b3f1 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -8,10 +8,11 @@ menu "Input drivers" # zephyr-keep-sorted-start source "drivers/input/Kconfig.adc_keys" source "drivers/input/Kconfig.analog_axis" -source "drivers/input/Kconfig.cap1203" +source "drivers/input/Kconfig.cap12xx" source "drivers/input/Kconfig.cf1133" source "drivers/input/Kconfig.chsc6x" source "drivers/input/Kconfig.cst816s" +source "drivers/input/Kconfig.cy8cmbr3xxx" source "drivers/input/Kconfig.esp32" source "drivers/input/Kconfig.evdev" source "drivers/input/Kconfig.ft5336" @@ -24,6 +25,7 @@ source "drivers/input/Kconfig.it8801" source "drivers/input/Kconfig.it8xxx2" source "drivers/input/Kconfig.kbd_matrix" source "drivers/input/Kconfig.npcx" +source "drivers/input/Kconfig.nunchuk" source "drivers/input/Kconfig.pat912x" source "drivers/input/Kconfig.paw32xx" source "drivers/input/Kconfig.pinnacle" diff --git a/drivers/input/Kconfig.cap1203 b/drivers/input/Kconfig.cap1203 deleted file mode 100644 index 28a87b6c7045a..0000000000000 --- a/drivers/input/Kconfig.cap1203 +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2022 Keiya Nobuta -# SPDX-License-Identifier: Apache-2.0 - -menuconfig INPUT_CAP1203 - bool "CAP1203 3-cannel capacitive touch sensor driver" - default y - depends on DT_HAS_MICROCHIP_CAP1203_ENABLED - select I2C - help - Enable driver for microchip CAP1203 3-cannel capacitive - touch sensor. - -if INPUT_CAP1203 - -config INPUT_CAP1203_POLL - bool "Polling" - help - Enable polling mode when interrupt GPIO is not specified. - -config INPUT_CAP1203_PERIOD - int "Sample period" - depends on INPUT_CAP1203_POLL - default 10 - help - Sample period in milliseconds when in polling mode. - -endif # INPUT_CAP1203 diff --git a/drivers/input/Kconfig.cap12xx b/drivers/input/Kconfig.cap12xx new file mode 100644 index 0000000000000..a217bc266baa3 --- /dev/null +++ b/drivers/input/Kconfig.cap12xx @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Keiya Nobuta +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_CAP12XX + bool "Microchip CAP12xx multi-channel capacitive touch sensor driver" + default y + depends on DT_HAS_MICROCHIP_CAP12XX_ENABLED + select I2C + help + Enable driver for Microchip CAP12xx multi-channel capacitive + touch sensor. diff --git a/drivers/input/Kconfig.cy8cmbr3xxx b/drivers/input/Kconfig.cy8cmbr3xxx new file mode 100644 index 0000000000000..d09702109d725 --- /dev/null +++ b/drivers/input/Kconfig.cy8cmbr3xxx @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Basalte bv +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_CY8CMBR3XXX + bool "CY8CMBR3XXX capacitive touch sensor driver" + default y + depends on DT_HAS_CYPRESS_CY8CMBR3XXX_ENABLED + select I2C + help + Enable driver for cypress CY8CMBR3XXX capacitive + touch sensor. diff --git a/drivers/input/Kconfig.ft5336 b/drivers/input/Kconfig.ft5336 index 1f09483cc3289..782bdb2fdba91 100644 --- a/drivers/input/Kconfig.ft5336 +++ b/drivers/input/Kconfig.ft5336 @@ -25,6 +25,7 @@ config INPUT_FT5336_PERIOD config INPUT_FT5336_INTERRUPT bool "Interrupt" + default y if $(dt_compat_any_has_prop,$(DT_COMPAT_FOCALTECH_FT5336),int-gpios) help Enable interrupt support (requires GPIO). diff --git a/drivers/input/Kconfig.nunchuk b/drivers/input/Kconfig.nunchuk new file mode 100644 index 0000000000000..8feb191b183b9 --- /dev/null +++ b/drivers/input/Kconfig.nunchuk @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Bootlin +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_NUNCHUK + bool "Nintendo Nunchuk joystick" + default y + depends on DT_HAS_NINTENDO_NUNCHUK_ENABLED + select I2C + help + This option enable the driver for the Nintendo Nunchuk joystick. diff --git a/drivers/input/input_cap1203.c b/drivers/input/input_cap1203.c deleted file mode 100644 index 91965d3c255ce..0000000000000 --- a/drivers/input/input_cap1203.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2022 Keiya Nobuta - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT microchip_cap1203 - -#include -#include -#include - -#include -LOG_MODULE_REGISTER(cap1203, CONFIG_INPUT_LOG_LEVEL); - -#define REG_MAIN_CONTROL 0x0 -#define CONTROL_INT 0x1 - -#define REG_INPUT_STATUS 0x03 - -#define REG_INTERRUPT_ENABLE 0x27 -#define INTERRUPT_ENABLE 0x7 -#define INTERRUPT_DISABLE 0x0 - -#define TOUCH_INPUT_COUNT 3 - -struct cap1203_config { - struct i2c_dt_spec i2c; - struct gpio_dt_spec int_gpio; - const uint16_t *input_codes; -}; - -struct cap1203_data { - const struct device *dev; - struct k_work work; - /* Interrupt GPIO callback. */ - struct gpio_callback int_gpio_cb; - uint8_t prev_input_state; -#ifdef CONFIG_INPUT_CAP1203_POLL - /* Timer (polling mode). */ - struct k_timer timer; -#endif -}; - -static int cap1203_clear_interrupt(const struct i2c_dt_spec *i2c) -{ - uint8_t ctrl; - int r; - - r = i2c_reg_read_byte_dt(i2c, REG_MAIN_CONTROL, &ctrl); - if (r < 0) { - return r; - } - - ctrl = ctrl & ~CONTROL_INT; - return i2c_reg_write_byte_dt(i2c, REG_MAIN_CONTROL, ctrl); -} - -static int cap1203_enable_interrupt(const struct i2c_dt_spec *i2c, bool enable) -{ - uint8_t intr = enable ? INTERRUPT_ENABLE : INTERRUPT_DISABLE; - - return i2c_reg_write_byte_dt(i2c, REG_INTERRUPT_ENABLE, intr); -} - -static int cap1203_process(const struct device *dev) -{ - const struct cap1203_config *config = dev->config; - struct cap1203_data *data = dev->data; - int r; - uint8_t input; - uint8_t single_input_state; - - r = i2c_reg_read_byte_dt(&config->i2c, REG_INPUT_STATUS, &input); - if (r < 0) { - return r; - } - - for (uint8_t i = 0; i < TOUCH_INPUT_COUNT; i++) { - single_input_state = input & BIT(i); - if (single_input_state != (data->prev_input_state & BIT(i))) { - input_report_key(dev, config->input_codes[i], single_input_state, true, - K_FOREVER); - } - } - data->prev_input_state = input; - - LOG_DBG("event: input: %d\n", input); - - /* - * Clear INT bit to clear SENSOR INPUT STATUS bits. - * Note that this is also required in polling mode. - */ - r = cap1203_clear_interrupt(&config->i2c); - if (r < 0) { - return r; - } - - return 0; -} - -static void cap1203_work_handler(struct k_work *work) -{ - struct cap1203_data *data = CONTAINER_OF(work, struct cap1203_data, work); - - cap1203_process(data->dev); -} - -static void cap1203_isr_handler(const struct device *dev, - struct gpio_callback *cb, uint32_t pins) -{ - struct cap1203_data *data = CONTAINER_OF(cb, struct cap1203_data, int_gpio_cb); - - k_work_submit(&data->work); -} - -#ifdef CONFIG_INPUT_CAP1203_POLL -static void cap1203_timer_handler(struct k_timer *timer) -{ - struct cap1203_data *data = CONTAINER_OF(timer, struct cap1203_data, timer); - - k_work_submit(&data->work); -} -#endif - -static int cap1203_init(const struct device *dev) -{ - const struct cap1203_config *config = dev->config; - struct cap1203_data *data = dev->data; - int r; - - if (!device_is_ready(config->i2c.bus)) { - LOG_ERR("I2C controller device not ready"); - return -ENODEV; - } - - data->dev = dev; - - k_work_init(&data->work, cap1203_work_handler); - - if (config->int_gpio.port != NULL) { - if (!gpio_is_ready_dt(&config->int_gpio)) { - LOG_ERR("Interrupt GPIO controller device not ready"); - return -ENODEV; - } - - r = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); - if (r < 0) { - LOG_ERR("Could not confighure interrupt GPIO pin"); - return r; - } - - r = gpio_pin_interrupt_configure_dt(&config->int_gpio, - GPIO_INT_EDGE_TO_ACTIVE); - if (r < 0) { - LOG_ERR("Could not configure interrupt GPIO interrupt"); - return r; - } - - gpio_init_callback(&data->int_gpio_cb, cap1203_isr_handler, - BIT(config->int_gpio.pin)); - - r = gpio_add_callback(config->int_gpio.port, &data->int_gpio_cb); - if (r < 0) { - LOG_ERR("Could not set gpio callback"); - return r; - } - - r = cap1203_clear_interrupt(&config->i2c); - if (r < 0) { - LOG_ERR("Could not clear interrupt"); - return r; - } - - r = cap1203_enable_interrupt(&config->i2c, true); - if (r < 0) { - LOG_ERR("Could not configure interrupt"); - return r; - } - } -#ifdef CONFIG_INPUT_CAP1203_POLL - else { - k_timer_init(&data->timer, cap1203_timer_handler, NULL); - - r = cap1203_enable_interrupt(&config->i2c, false); - if (r < 0) { - LOG_ERR("Could not configure interrupt"); - return r; - } - - k_timer_start(&data->timer, K_MSEC(CONFIG_INPUT_CAP1203_PERIOD), - K_MSEC(CONFIG_INPUT_CAP1203_PERIOD)); - } -#endif - - return 0; -} - -#define CAP1203_INIT(index) \ - static const uint16_t cap1203_input_codes_##inst[] = DT_INST_PROP(index, input_codes); \ - BUILD_ASSERT(DT_INST_PROP_LEN(index, input_codes) == TOUCH_INPUT_COUNT); \ - static const struct cap1203_config cap1203_config_##index = { \ - .i2c = I2C_DT_SPEC_INST_GET(index), \ - .int_gpio = GPIO_DT_SPEC_INST_GET_OR(index, int_gpios, {0}), \ - .input_codes = cap1203_input_codes_##inst, \ - }; \ - static struct cap1203_data cap1203_data_##index; \ - DEVICE_DT_INST_DEFINE(index, cap1203_init, NULL, &cap1203_data_##index, \ - &cap1203_config_##index, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ - NULL); - -DT_INST_FOREACH_STATUS_OKAY(CAP1203_INIT) diff --git a/drivers/input/input_cap12xx.c b/drivers/input/input_cap12xx.c new file mode 100644 index 0000000000000..8b0a23130915f --- /dev/null +++ b/drivers/input/input_cap12xx.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2022 Keiya Nobuta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_cap12xx + +#include +#include +#include +#include +LOG_MODULE_REGISTER(cap12xx, CONFIG_INPUT_LOG_LEVEL); + +#define REG_MAIN_CONTROL 0x00 +#define CONTROL_INT 0x01 + +#define REG_INPUT_STATUS 0x03 + +#define REG_INTERRUPT_ENABLE 0x27 +#define INTERRUPT_ENABLE 0xFF +#define INTERRUPT_DISABLE 0x00 + +#define REG_REPEAT_ENABLE 0x28 +#define REPEAT_ENABLE 0xFF +#define REPEAT_DISABLE 0x00 + +struct cap12xx_config { + struct i2c_dt_spec i2c; + const uint8_t input_channels; + const uint16_t *input_codes; + struct gpio_dt_spec *int_gpio; + bool repeat; + const uint16_t poll_interval_ms; +}; + +struct cap12xx_data { + const struct device *dev; + struct k_work work; + uint8_t prev_input_state; + struct gpio_callback int_gpio_cb; + struct k_timer poll_timer; +}; + +static int cap12xx_clear_interrupt(const struct i2c_dt_spec *i2c) +{ + uint8_t ctrl; + int r; + + r = i2c_reg_read_byte_dt(i2c, REG_MAIN_CONTROL, &ctrl); + if (r < 0) { + return r; + } + + ctrl = ctrl & ~CONTROL_INT; + return i2c_reg_write_byte_dt(i2c, REG_MAIN_CONTROL, ctrl); +} + +static int cap12xx_enable_interrupt(const struct i2c_dt_spec *i2c, bool enable) +{ + uint8_t intr = enable ? INTERRUPT_ENABLE : INTERRUPT_DISABLE; + + return i2c_reg_write_byte_dt(i2c, REG_INTERRUPT_ENABLE, intr); +} + +static int cap12xx_process(const struct device *dev) +{ + const struct cap12xx_config *config = dev->config; + struct cap12xx_data *data = dev->data; + int r; + uint8_t input_state; + + /* + * Clear INT bit to clear SENSOR INPUT STATUS bits. + * Note that this is also required in polling mode. + */ + r = cap12xx_clear_interrupt(&config->i2c); + + if (r < 0) { + return r; + } + r = i2c_reg_read_byte_dt(&config->i2c, REG_INPUT_STATUS, &input_state); + if (r < 0) { + return r; + } + + if (config->int_gpio == NULL) { + if (data->prev_input_state == input_state) { + return 0; + } + } + + for (uint8_t i = 0; i < config->input_channels; i++) { + if (input_state & BIT(i)) { + input_report_key(dev, config->input_codes[i], input_state & BIT(i), true, + K_FOREVER); + } else if (data->prev_input_state & BIT(i)) { + input_report_key(dev, config->input_codes[i], input_state & BIT(i), true, + K_FOREVER); + } + } + data->prev_input_state = input_state; + + return 0; +} + +static void cap12xx_work_handler(struct k_work *work) +{ + struct cap12xx_data *data = CONTAINER_OF(work, struct cap12xx_data, work); + + cap12xx_process(data->dev); +} + +static void cap12xx_timer_handler(struct k_timer *poll_timer) +{ + struct cap12xx_data *data = CONTAINER_OF(poll_timer, struct cap12xx_data, poll_timer); + + k_work_submit(&data->work); +} + +static void cap12xx_isr_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct cap12xx_data *data = CONTAINER_OF(cb, struct cap12xx_data, int_gpio_cb); + + k_work_submit(&data->work); +} + +static int cap12xx_init(const struct device *dev) +{ + const struct cap12xx_config *config = dev->config; + struct cap12xx_data *data = dev->data; + int r; + + if (!device_is_ready(config->i2c.bus)) { + LOG_ERR("I2C controller device not ready"); + return -ENODEV; + } + + data->dev = dev; + + k_work_init(&data->work, cap12xx_work_handler); + + if (config->int_gpio == NULL) { + LOG_DBG("cap12xx driver in polling mode"); + k_timer_init(&data->poll_timer, cap12xx_timer_handler, NULL); + r = cap12xx_enable_interrupt(&config->i2c, true); + if (r < 0) { + LOG_ERR("Could not configure interrupt"); + return r; + } + k_timer_start(&data->poll_timer, K_MSEC(config->poll_interval_ms), + K_MSEC(config->poll_interval_ms)); + } else { + LOG_DBG("cap12xx driver in interrupt mode"); + if (!gpio_is_ready_dt(config->int_gpio)) { + LOG_ERR("Interrupt GPIO controller device not ready (missing device tree " + "node?)"); + return -ENODEV; + } + + r = gpio_pin_configure_dt(config->int_gpio, GPIO_INPUT); + if (r < 0) { + LOG_ERR("Could not configure interrupt GPIO pin"); + return r; + } + + r = gpio_pin_interrupt_configure_dt(config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (r < 0) { + LOG_ERR("Could not configure interrupt GPIO interrupt"); + return r; + } + + gpio_init_callback(&data->int_gpio_cb, cap12xx_isr_handler, + BIT(config->int_gpio->pin)); + + r = gpio_add_callback_dt(config->int_gpio, &data->int_gpio_cb); + if (r < 0) { + LOG_ERR("Could not set gpio callback"); + return r; + } + + r = cap12xx_clear_interrupt(&config->i2c); + if (r < 0) { + LOG_ERR("Could not clear interrupt"); + return r; + } + r = cap12xx_enable_interrupt(&config->i2c, true); + if (r < 0) { + LOG_ERR("Could not configure interrupt"); + return r; + } + if (config->repeat) { + r = i2c_reg_write_byte_dt(&config->i2c, REG_REPEAT_ENABLE, REPEAT_ENABLE); + if (r < 0) { + LOG_ERR("Could not disable repeated interrupts"); + return r; + } + LOG_DBG("cap12xx enabled repeated interrupts"); + } else { + r = i2c_reg_write_byte_dt(&config->i2c, REG_REPEAT_ENABLE, REPEAT_DISABLE); + if (r < 0) { + LOG_ERR("Could not enable repeated interrupts"); + return r; + } + LOG_DBG("cap12xx disabled repeated interrupts"); + } + } + LOG_DBG("%d channels configured", config->input_channels); + return 0; +} + +#define CAP12XX_INIT(index) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(index, int_gpios), ( \ + static struct gpio_dt_spec cap12xx_int_gpio_##index = \ + GPIO_DT_SPEC_INST_GET(index, int_gpios);)) \ + static const uint16_t cap12xx_input_codes_##index[] = DT_INST_PROP(index, input_codes); \ + static const struct cap12xx_config cap12xx_config_##index = { \ + .i2c = I2C_DT_SPEC_INST_GET(index), \ + .input_channels = DT_INST_PROP_LEN(index, input_codes), \ + .input_codes = cap12xx_input_codes_##index, \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(index, int_gpios), ( \ + .int_gpio = &cap12xx_int_gpio_##index,)) \ + .repeat = DT_INST_PROP(index, repeat), \ + .poll_interval_ms = DT_INST_PROP_OR(index, poll_interval_ms, 10)}; \ + static struct cap12xx_data cap12xx_data_##index; \ + DEVICE_DT_INST_DEFINE(index, cap12xx_init, NULL, &cap12xx_data_##index, \ + &cap12xx_config_##index, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(CAP12XX_INIT) diff --git a/drivers/input/input_cy8cmbr3xxx.c b/drivers/input/input_cy8cmbr3xxx.c new file mode 100644 index 0000000000000..a724f0652e5fd --- /dev/null +++ b/drivers/input/input_cy8cmbr3xxx.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2025 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT cypress_cy8cmbr3xxx + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(cy8cmbr3xxx, CONFIG_INPUT_LOG_LEVEL); + +#define CY8CMBR3XXX_SENSOR_EN 0x00 +#define CY8CMBR3XXX_FSS_EN 0x02 +#define CY8CMBR3XXX_TOGGLE_EN 0x04 +#define CY8CMBR3XXX_LED_ON_EN 0x06 +#define CY8CMBR3XXX_SENSITIVITY0 0x08 +#define CY8CMBR3XXX_SENSITIVITY1 0x09 +#define CY8CMBR3XXX_SENSITIVITY2 0x0A +#define CY8CMBR3XXX_SENSITIVITY3 0x0B +#define CY8CMBR3XXX_BASE_THRESHOLD0 0x0C +#define CY8CMBR3XXX_BASE_THRESHOLD1 0x0D +#define CY8CMBR3XXX_FINGER_THRESHOLD2 0x0E +#define CY8CMBR3XXX_FINGER_THRESHOLD3 0x0F +#define CY8CMBR3XXX_FINGER_THRESHOLD4 0x10 +#define CY8CMBR3XXX_FINGER_THRESHOLD5 0x11 +#define CY8CMBR3XXX_FINGER_THRESHOLD6 0x12 +#define CY8CMBR3XXX_FINGER_THRESHOLD7 0x13 +#define CY8CMBR3XXX_FINGER_THRESHOLD8 0x14 +#define CY8CMBR3XXX_FINGER_THRESHOLD9 0x15 +#define CY8CMBR3XXX_FINGER_THRESHOLD10 0x16 +#define CY8CMBR3XXX_FINGER_THRESHOLD11 0x17 +#define CY8CMBR3XXX_FINGER_THRESHOLD12 0x18 +#define CY8CMBR3XXX_FINGER_THRESHOLD13 0x19 +#define CY8CMBR3XXX_FINGER_THRESHOLD14 0x1A +#define CY8CMBR3XXX_FINGER_THRESHOLD15 0x1B +#define CY8CMBR3XXX_SENSOR_DEBOUNCE 0x1C +#define CY8CMBR3XXX_BUTTON_HYS 0x1D +#define CY8CMBR3XXX_BUTTON_LBR 0x1F +#define CY8CMBR3XXX_BUTTON_NNT 0x20 +#define CY8CMBR3XXX_BUTTON_NT 0x21 +#define CY8CMBR3XXX_PROX_EN 0x26 +#define CY8CMBR3XXX_PROX_CFG 0x27 +#define CY8CMBR3XXX_PROX_CFG2 0x28 +#define CY8CMBR3XXX_PROX_TOUCH_TH0 0x2A +#define CY8CMBR3XXX_PROX_TOUCH_TH1 0x2C +#define CY8CMBR3XXX_PROX_RESOLUTION0 0x2E +#define CY8CMBR3XXX_PROX_RESOLUTION1 0x2F +#define CY8CMBR3XXX_PROX_HYS 0x30 +#define CY8CMBR3XXX_PROX_LBR 0x32 +#define CY8CMBR3XXX_PROX_NNT 0x33 +#define CY8CMBR3XXX_PROX_NT 0x34 +#define CY8CMBR3XXX_PROX_POSITIVE_TH0 0x35 +#define CY8CMBR3XXX_PROX_POSITIVE_TH1 0x36 +#define CY8CMBR3XXX_PROX_NEGATIVE_TH0 0x39 +#define CY8CMBR3XXX_PROX_NEGATIVE_TH1 0x3A +#define CY8CMBR3XXX_LED_ON_TIME 0x3D +#define CY8CMBR3XXX_BUZZER_CFG 0x3E +#define CY8CMBR3XXX_BUZZER_ON_TIME 0x3F +#define CY8CMBR3XXX_GPO_CFG 0x40 +#define CY8CMBR3XXX_PWM_DUTYCYCLE_CFG0 0x41 +#define CY8CMBR3XXX_PWM_DUTYCYCLE_CFG1 0x42 +#define CY8CMBR3XXX_PWM_DUTYCYCLE_CFG2 0x43 +#define CY8CMBR3XXX_PWM_DUTYCYCLE_CFG3 0x44 +#define CY8CMBR3XXX_PWM_DUTYCYCLE_CFG4 0x45 +#define CY8CMBR3XXX_PWM_DUTYCYCLE_CFG5 0x46 +#define CY8CMBR3XXX_PWM_DUTYCYCLE_CFG6 0x47 +#define CY8CMBR3XXX_PWM_DUTYCYCLE_CFG7 0x48 +#define CY8CMBR3XXX_SPO_CFG 0x4C +#define CY8CMBR3XXX_DEVICE_CFG0 0x4D +#define CY8CMBR3XXX_DEVICE_CFG1 0x4E +#define CY8CMBR3XXX_DEVICE_CFG2 0x4F +#define CY8CMBR3XXX_DEVICE_CFG3 0x50 +#define CY8CMBR3XXX_I2C_ADDR 0x51 +#define CY8CMBR3XXX_REFRESH_CTRL 0x52 +#define CY8CMBR3XXX_STATE_TIMEOUT 0x55 +#define CY8CMBR3XXX_SLIDER_CFG 0x5D +#define CY8CMBR3XXX_SLIDER1_CFG 0x61 +#define CY8CMBR3XXX_SLIDER1_RESOLUTION 0x62 +#define CY8CMBR3XXX_SLIDER1_THRESHOLD 0x63 +#define CY8CMBR3XXX_SLIDER2_CFG 0x67 +#define CY8CMBR3XXX_SLIDER2_RESOLUTION 0x68 +#define CY8CMBR3XXX_SLIDER2_THRESHOLD 0x69 +#define CY8CMBR3XXX_SLIDER_LBR 0x71 +#define CY8CMBR3XXX_SLIDER_NNT 0x72 +#define CY8CMBR3XXX_SLIDER_NT 0x73 +#define CY8CMBR3XXX_SCRATCHPAD0 0x7A +#define CY8CMBR3XXX_SCRATCHPAD1 0x7B +#define CY8CMBR3XXX_CONFIG_CRC 0x7E +#define CY8CMBR3XXX_GPO_OUTPUT_STATE 0x80 +#define CY8CMBR3XXX_SENSOR_ID 0x82 +#define CY8CMBR3XXX_CTRL_CMD 0x86 +#define CY8CMBR3XXX_CTRL_CMD_STATUS 0x88 +#define CY8CMBR3XXX_CTRL_CMD_ERR 0x89 +#define CY8CMBR3XXX_SYSTEM_STATUS 0x8A +#define CY8CMBR3XXX_PREV_CTRL_CMD_CODE 0x8C +#define CY8CMBR3XXX_FAMILY_ID 0x8F +#define CY8CMBR3XXX_DEVICE_ID 0x90 +#define CY8CMBR3XXX_DEVICE_REV 0x92 +#define CY8CMBR3XXX_CALC_CRC 0x94 +#define CY8CMBR3XXX_TOTAL_WORKING_SNS 0x97 +#define CY8CMBR3XXX_SNS_CP_HIGH 0x98 +#define CY8CMBR3XXX_SNS_VDD_SHORT 0x9A +#define CY8CMBR3XXX_SNS_GND_SHORT 0x9C +#define CY8CMBR3XXX_SNS_SNS_SHORT 0x9E +#define CY8CMBR3XXX_CMOD_SHIELD_TEST 0xA0 +#define CY8CMBR3XXX_BUTTON_STAT 0xAA +#define CY8CMBR3XXX_LATCHED_BUTTON_STAT 0xAC +#define CY8CMBR3XXX_PROX_STAT 0xAE +#define CY8CMBR3XXX_LATCHED_PROX_STAT 0xAF +#define CY8CMBR3XXX_SLIDER1_POSITION 0xB0 +#define CY8CMBR3XXX_LIFTOFF_SLIDER1_POSITION 0xB1 +#define CY8CMBR3XXX_SLIDER2_POSITION 0xB2 +#define CY8CMBR3XXX_LIFTOFF_SLIDER2_POSITION 0xB3 +#define CY8CMBR3XXX_SYNC_COUNTER0 0xB9 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR0 0xBA +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR1 0xBC +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR2 0xBE +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR3 0xC0 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR4 0xC2 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR5 0xC4 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR6 0xC6 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR7 0xC8 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR8 0xCA +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR9 0xCC +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR10 0xCE +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR11 0xD0 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR12 0xD2 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR13 0xD4 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR14 0xD6 +#define CY8CMBR3XXX_DIFFERENCE_COUNT_SENSOR15 0xD8 +#define CY8CMBR3XXX_GPO_DATA 0xDA +#define CY8CMBR3XXX_SYNC_COUNTER1 0xDB +#define CY8CMBR3XXX_DEBUG_SENSOR_ID 0xDC +#define CY8CMBR3XXX_DEBUG_CP 0xDD +#define CY8CMBR3XXX_DEBUG_DIFFERENCE_COUNT0 0xDE +#define CY8CMBR3XXX_DEBUG_BASELINE0 0xE0 +#define CY8CMBR3XXX_DEBUG_RAW_COUNT0 0xE2 +#define CY8CMBR3XXX_DEBUG_AVG_RAW_COUNT0 0xE4 +#define CY8CMBR3XXX_SYNC_COUNTER2 0xE7 + +#define CY8CMBR3XXX_CTRL_CMD_CALC_CRC 0x02 +#define CY8CMBR3XXX_CTRL_CMD_RESET 0xFF + +/* The controller wakes up from the low-power state on an address match but sends NACK + * until it transitions into the Active state. When the device NACKs a transaction, the host is + * expected to retry the transaction until it receives an ACK. Typically, no more than 3 retries are + * necessary, depending on time between the interrupt and the first i2c transfer or if + * no interrupt has caused the initiation of the communication. + */ +#define CY8CMBR3XXX_I2C_RETRIES 5 + +struct cy8cmbr3xxx_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec int_gpio; + struct gpio_dt_spec rst_gpio; + const uint16_t *input_codes; + uint8_t input_codes_count; + const uint16_t *proximity_codes; + uint8_t proximity_codes_count; +}; + +struct cy8cmbr3xxx_data { + const struct device *dev; + struct k_work work; + struct gpio_callback int_gpio_cb; + uint16_t prev_button_state; + uint8_t prev_proximity_state; +}; + +static int cy8cmbr3xxx_i2c_read(const struct device *dev, uint8_t address, void *buf, size_t len) +{ + const struct cy8cmbr3xxx_config *config = dev->config; + int ret; + + for (int i = 0; i < CY8CMBR3XXX_I2C_RETRIES; i++) { + ret = i2c_write_read_dt(&config->i2c, &address, sizeof(address), buf, len); + if (ret == 0) { + break; + } + } + + return ret; +} + +static int cy8cmbr3xxx_i2c_write(const struct device *dev, uint8_t address, const void *buf, + size_t len) +{ + const struct cy8cmbr3xxx_config *config = dev->config; + int ret; + + for (int i = 0; i < CY8CMBR3XXX_I2C_RETRIES; i++) { + ret = i2c_burst_write_dt(&config->i2c, address, buf, len); + if (ret == 0) { + break; + } + } + + return ret; +} + +static int cy8cmbr3xxx_wait_for_command_completion(const struct device *dev, k_timeout_t timeout) +{ + uint8_t current_command; + int ret; + k_timepoint_t end = sys_timepoint_calc(timeout); + + do { + /* Wait for the completion of the command. After a reset command, it can + * happen that the device NACKs for some time. + */ + ret = cy8cmbr3xxx_i2c_read(dev, CY8CMBR3XXX_CTRL_CMD, ¤t_command, + sizeof(uint8_t)); + + /* As soon as current_command is 0x00, the command is completed */ + if (ret == 0 && current_command == 0x00) { + return 0; + } + + k_msleep(1); + } while (!sys_timepoint_expired(end)); + + LOG_ERR("Wait for command completion timed out"); + + return -ETIMEDOUT; +} + +int cy8cmbr3xxx_configure(const struct device *dev, const struct cy8cmbr3xxx_config_data *config) +{ + int ret; + uint8_t read_config[CY8CMBR3XXX_EZ_CLICK_CONFIG_SIZE]; + uint8_t command; + + if (config == NULL) { + return -EINVAL; + } + + /* Read the complete configuration */ + ret = cy8cmbr3xxx_i2c_read(dev, CY8CMBR3XXX_SENSOR_EN, read_config, sizeof(read_config)); + if (ret < 0) { + LOG_ERR("Failed to read i2c (%d)", ret); + return ret; + } + + if (memcmp(read_config, config->data, sizeof(config->data)) == 0) { + return 0; + } + + /* Write the complete configuration of 128 bytes to the CY8CMBR3XXX controller */ + ret = cy8cmbr3xxx_i2c_write(dev, CY8CMBR3XXX_SENSOR_EN, config->data, sizeof(config->data)); + if (ret < 0) { + LOG_ERR("Failed to write i2c (%d)", ret); + return ret; + } + + /* The device calculates a CRC checksum over the configuration data in this + * register map and compares the result with the content of CONFIG_CRC. If the + * two values match, the device saves the configuration and the CRC checksum to + * nonvolatile memory. + */ + command = CY8CMBR3XXX_CTRL_CMD_CALC_CRC; + ret = cy8cmbr3xxx_i2c_write(dev, CY8CMBR3XXX_CTRL_CMD, &command, 1); + if (ret < 0) { + LOG_ERR("Failed to write i2c (%d)", ret); + return ret; + } + + /* 600ms seems to be sufficient */ + ret = cy8cmbr3xxx_wait_for_command_completion(dev, K_MSEC(600)); + if (ret < 0) { + LOG_ERR("Failed to wait for command completion (%d)", ret); + return ret; + } + + /* The device resets itself */ + command = CY8CMBR3XXX_CTRL_CMD_RESET; + ret = cy8cmbr3xxx_i2c_write(dev, CY8CMBR3XXX_CTRL_CMD, &command, 1); + if (ret < 0) { + LOG_ERR("Failed to write i2c (%d)", ret); + return ret; + } + + ret = cy8cmbr3xxx_wait_for_command_completion(dev, K_MSEC(50)); + if (ret < 0) { + LOG_ERR("Failed to wait for command completion (%d)", ret); + return ret; + } + + return 0; +} + +static int cy8cmbr3xxx_process(const struct device *dev) +{ + const struct cy8cmbr3xxx_config *config = dev->config; + struct cy8cmbr3xxx_data *data = dev->data; + int ret; + uint16_t button_state, single_button_state; + uint8_t proximity_state, single_proximity_state; + + /* Request button status */ + ret = cy8cmbr3xxx_i2c_read(dev, CY8CMBR3XXX_BUTTON_STAT, &button_state, sizeof(uint16_t)); + if (ret < 0) { + LOG_ERR("Failed to read button status (%d)", ret); + return ret; + } + + for (uint8_t i = 0; i < config->input_codes_count; i++) { + single_button_state = button_state & BIT(i); + if (single_button_state != (data->prev_button_state & BIT(i))) { + input_report_key(dev, config->input_codes[i], single_button_state, true, + K_FOREVER); + } + } + data->prev_button_state = button_state; + + /* Request proximity status */ + if (config->proximity_codes_count > 0) { + ret = cy8cmbr3xxx_i2c_read(dev, CY8CMBR3XXX_PROX_STAT, &proximity_state, + sizeof(uint8_t)); + if (ret < 0) { + LOG_ERR("Failed to read proximity status (%d)", ret); + return ret; + } + + for (uint8_t i = 0; i < config->proximity_codes_count; i++) { + single_proximity_state = proximity_state & BIT(i); + if (single_proximity_state != (data->prev_proximity_state & BIT(i))) { + input_report_key(dev, config->proximity_codes[i], + single_proximity_state, true, K_FOREVER); + } + } + data->prev_proximity_state = proximity_state; + } + + return 0; +} + +static void cy8cmbr3xxx_work_handler(struct k_work *work) +{ + struct cy8cmbr3xxx_data *data = CONTAINER_OF(work, struct cy8cmbr3xxx_data, work); + + cy8cmbr3xxx_process(data->dev); +} + +static void cy8cmbr3xxx_isr_handler(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + struct cy8cmbr3xxx_data *data = CONTAINER_OF(cb, struct cy8cmbr3xxx_data, int_gpio_cb); + + k_work_submit(&data->work); +} + +static void cy8cmbr3xxx_reset(const struct device *dev) +{ + const struct cy8cmbr3xxx_config *config = dev->config; + int ret; + + if (!gpio_is_ready_dt(&config->rst_gpio)) { + LOG_ERR("GPIO controller device not ready"); + return; + } + + ret = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_ERR("Could not configure reset GPIO pin (%d)", ret); + return; + } + + k_usleep(5); + + ret = gpio_pin_set_dt(&config->rst_gpio, 0); + if (ret < 0) { + LOG_ERR("Could not set reset GPIO pin (%d)", ret); + return; + } +} + +static int cy8cmbr3xxx_init(const struct device *dev) +{ + const struct cy8cmbr3xxx_config *config = dev->config; + struct cy8cmbr3xxx_data *data = dev->data; + int ret; + + data->dev = dev; + + k_work_init(&data->work, cy8cmbr3xxx_work_handler); + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C controller device not ready"); + return -ENODEV; + } + + cy8cmbr3xxx_reset(dev); + + if (!gpio_is_ready_dt(&config->int_gpio)) { + LOG_ERR("GPIO controller device not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Could not configure interrupt GPIO pin (%d)", ret); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("Could not configure GPIO interrupt (%d)", ret); + return ret; + } + + gpio_init_callback(&data->int_gpio_cb, cy8cmbr3xxx_isr_handler, BIT(config->int_gpio.pin)); + + ret = gpio_add_callback(config->int_gpio.port, &data->int_gpio_cb); + if (ret < 0) { + LOG_ERR("Could not set gpio callback (%d)", ret); + return ret; + } + + return 0; +} + +#define CY8CMBR3XXX_INIT(inst) \ + static const uint16_t cy8cmbr3xxx_input_codes_##inst[] = DT_INST_PROP(inst, input_codes); \ + static const uint16_t cy8cmbr3xxx_proximity_codes_##inst[] = \ + DT_INST_PROP_OR(inst, proximity_codes, {}); \ + static const struct cy8cmbr3xxx_config cy8cmbr3xxx_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ + .rst_gpio = GPIO_DT_SPEC_INST_GET(inst, rst_gpios), \ + .input_codes = cy8cmbr3xxx_input_codes_##inst, \ + .input_codes_count = DT_INST_PROP_LEN(inst, input_codes), \ + .proximity_codes = cy8cmbr3xxx_proximity_codes_##inst, \ + .proximity_codes_count = DT_INST_PROP_LEN_OR(inst, proximity_codes, 0), \ + }; \ + static struct cy8cmbr3xxx_data cy8cmbr3xxx_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, cy8cmbr3xxx_init, NULL, &cy8cmbr3xxx_data_##inst, \ + &cy8cmbr3xxx_config_##inst, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(CY8CMBR3XXX_INIT) diff --git a/drivers/input/input_ft5336.c b/drivers/input/input_ft5336.c index 2b82f7fbc7b92..ee6f9a89c62b6 100644 --- a/drivers/input/input_ft5336.c +++ b/drivers/input/input_ft5336.c @@ -294,7 +294,7 @@ static int ft5336_pm_action(const struct device *dev, #endif #define FT5336_INIT(index) \ - PM_DEVICE_DT_INST_DEFINE(n, ft5336_pm_action); \ + PM_DEVICE_DT_INST_DEFINE(index, ft5336_pm_action); \ static const struct ft5336_config ft5336_config_##index = { \ .common = INPUT_TOUCH_DT_INST_COMMON_CONFIG_INIT(index), \ .bus = I2C_DT_SPEC_INST_GET(index), \ @@ -303,7 +303,7 @@ static int ft5336_pm_action(const struct device *dev, (.int_gpio = GPIO_DT_SPEC_INST_GET(index, int_gpios),)) \ }; \ static struct ft5336_data ft5336_data_##index; \ - DEVICE_DT_INST_DEFINE(index, ft5336_init, PM_DEVICE_DT_INST_GET(n), \ + DEVICE_DT_INST_DEFINE(index, ft5336_init, PM_DEVICE_DT_INST_GET(index), \ &ft5336_data_##index, &ft5336_config_##index, \ POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL); diff --git a/drivers/input/input_nunchuk.c b/drivers/input/input_nunchuk.c new file mode 100644 index 0000000000000..5c7910de55de6 --- /dev/null +++ b/drivers/input/input_nunchuk.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2024 Bootlin + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nintendo_nunchuk + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(input_nunchuk, CONFIG_INPUT_LOG_LEVEL); + +#define NUNCHUK_DELAY_MS 10 +#define NUNCHUK_READ_SIZE 6 + +struct nunchuk_config { + struct i2c_dt_spec i2c_bus; + int polling_interval_ms; +}; + +struct nunchuk_data { + const struct device *dev; + uint8_t joystick_x; + uint8_t joystick_y; + bool button_c; + bool button_z; + struct k_work_delayable work; + k_timeout_t interval_ms; +}; + +static int nunchuk_read_registers(const struct device *dev, uint8_t *buffer) +{ + const struct nunchuk_config *cfg = dev->config; + int ret; + uint8_t value = 0; + + ret = i2c_write_dt(&cfg->i2c_bus, &value, sizeof(value)); + if (ret < 0) { + return ret; + } + + k_msleep(NUNCHUK_DELAY_MS); + ret = i2c_read_dt(&cfg->i2c_bus, buffer, NUNCHUK_READ_SIZE); + if (ret < 0) { + return ret; + } + + return 0; +} + +static void nunchuk_poll(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct nunchuk_data *data = CONTAINER_OF(dwork, struct nunchuk_data, work); + const struct device *dev = data->dev; + uint8_t buffer[NUNCHUK_READ_SIZE]; + uint8_t joystick_x, joystick_y; + bool button_c, button_z; + bool y_changed; + bool sync_flag; + int ret; + + nunchuk_read_registers(dev, buffer); + + joystick_x = buffer[0]; + joystick_y = buffer[1]; + y_changed = (joystick_y != data->joystick_y); + + if (joystick_x != data->joystick_x) { + data->joystick_x = joystick_x; + sync_flag = !y_changed; + ret = input_report_abs(dev, INPUT_ABS_X, data->joystick_x, sync_flag, K_FOREVER); + } + + if (y_changed) { + data->joystick_y = joystick_y; + ret = input_report_abs(dev, INPUT_ABS_Y, data->joystick_y, true, K_FOREVER); + } + + button_z = buffer[5] & BIT(0); + if (button_z != data->button_z) { + data->button_z = button_z; + ret = input_report_key(dev, INPUT_KEY_Z, !data->button_z, true, K_FOREVER); + } + + button_c = buffer[5] & BIT(1); + if (button_c != data->button_c) { + data->button_c = button_c; + ret = input_report_key(dev, INPUT_KEY_C, !data->button_c, true, K_FOREVER); + } + + k_work_reschedule(dwork, data->interval_ms); +} + +static int nunchuk_init(const struct device *dev) +{ + const struct nunchuk_config *cfg = dev->config; + struct nunchuk_data *data = dev->data; + int ret; + + uint8_t init_seq_1[2] = {0xf0, 0x55}; + uint8_t init_seq_2[2] = {0xfb, 0x00}; + uint8_t buffer[NUNCHUK_READ_SIZE]; + + data->dev = dev; + data->interval_ms = K_MSEC(cfg->polling_interval_ms - 11); + + if (!i2c_is_ready_dt(&cfg->i2c_bus)) { + LOG_ERR("Bus device is not ready"); + return -ENODEV; + } + + /* Send the unencrypted init sequence */ + ret = i2c_write_dt(&cfg->i2c_bus, init_seq_1, sizeof(init_seq_1)); + if (ret < 0) { + LOG_ERR("I2C write failed (%d).", ret); + return ret; + } + + k_msleep(1); + ret = i2c_write_dt(&cfg->i2c_bus, init_seq_2, sizeof(init_seq_2)); + if (ret < 0) { + return ret; + } + + k_msleep(1); + ret = nunchuk_read_registers(dev, buffer); + if (ret < 0) { + return ret; + } + + /* Sometimes, the first read gives unexpected results, so we make another one. */ + k_msleep(1); + ret = nunchuk_read_registers(dev, buffer); + if (ret < 0) { + return ret; + } + + data->joystick_x = buffer[0]; + data->joystick_y = buffer[1]; + data->button_z = buffer[5] & BIT(0); + data->button_c = buffer[5] & BIT(1); + + k_work_init_delayable(&data->work, nunchuk_poll); + ret = k_work_reschedule(&data->work, data->interval_ms); + + return ret; +} + +#define NUNCHUK_INIT(inst) \ + static const struct nunchuk_config nunchuk_config_##inst = { \ + .i2c_bus = I2C_DT_SPEC_INST_GET(inst), \ + .polling_interval_ms = DT_INST_PROP(inst, polling_interval_ms), \ + }; \ + BUILD_ASSERT(DT_INST_PROP(inst, polling_interval_ms) > 20); \ + \ + static struct nunchuk_data nunchuk_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, &nunchuk_init, NULL, &nunchuk_data_##inst, \ + &nunchuk_config_##inst, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(NUNCHUK_INIT) diff --git a/drivers/input/input_sbus.c b/drivers/input/input_sbus.c index b9eb44e03e668..10e6498a698e7 100644 --- a/drivers/input/input_sbus.c +++ b/drivers/input/input_sbus.c @@ -123,7 +123,7 @@ static void input_sbus_input_report_thread(const struct device *dev, void *dummy uint8_t i, channel; uint8_t *sbus_channel_data = &data->sbus_frame[1]; /* Omit header */ - uint16_t value; + uint32_t value; int bits_read; unsigned int key; int ret; diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt index 0e458d033f24e..8f3b279eda626 100644 --- a/drivers/interrupt_controller/CMakeLists.txt +++ b/drivers/interrupt_controller/CMakeLists.txt @@ -41,6 +41,7 @@ zephyr_library_sources_ifdef(CONFIG_NXP_S32_WKPU intc_wkpu_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_XMC4XXX_INTC intc_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_NXP_PINT intc_nxp_pint.c) zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_ICU intc_renesas_ra_icu.c) +zephyr_library_sources_ifdef(CONFIG_RENESAS_RZ_EXT_IRQ intc_renesas_rz_ext_irq.c) zephyr_library_sources_ifdef(CONFIG_NXP_IRQSTEER intc_nxp_irqsteer.c) zephyr_library_sources_ifdef(CONFIG_INTC_MTK_ADSP intc_mtk_adsp.c) zephyr_library_sources_ifdef(CONFIG_WCH_PFIC intc_wch_pfic.c) diff --git a/drivers/interrupt_controller/Kconfig b/drivers/interrupt_controller/Kconfig index caabfc576902a..388bfd2eb9fb7 100644 --- a/drivers/interrupt_controller/Kconfig +++ b/drivers/interrupt_controller/Kconfig @@ -104,6 +104,8 @@ source "drivers/interrupt_controller/Kconfig.vim" source "drivers/interrupt_controller/Kconfig.renesas_ra" +source "drivers/interrupt_controller/Kconfig.renesas_rz" + source "drivers/interrupt_controller/Kconfig.nxp_irqsteer" source "drivers/interrupt_controller/Kconfig.mtk_adsp" diff --git a/drivers/interrupt_controller/Kconfig.mtk_adsp b/drivers/interrupt_controller/Kconfig.mtk_adsp index 0c8875973e8ad..112358986bbd4 100644 --- a/drivers/interrupt_controller/Kconfig.mtk_adsp +++ b/drivers/interrupt_controller/Kconfig.mtk_adsp @@ -3,6 +3,7 @@ config INTC_MTK_ADSP bool "MediaTek Audio DSP Interrupt Controller" + depends on SOC_FAMILY_MTK help Very simple cascaded interrupt controller consisting of two bitfield registers (status and enable) and one mask value diff --git a/drivers/interrupt_controller/Kconfig.renesas_rz b/drivers/interrupt_controller/Kconfig.renesas_rz new file mode 100644 index 0000000000000..6fe45f73788a6 --- /dev/null +++ b/drivers/interrupt_controller/Kconfig.renesas_rz @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config RENESAS_RZ_EXT_IRQ + bool "Renesas RZ external interrupt controller driver" + default y + depends on DT_HAS_RENESAS_RZ_EXT_IRQ_ENABLED + select USE_RZ_FSP_EXT_IRQ + select PINCTRL + help + Renesas RZ external interrupt controller driver diff --git a/drivers/interrupt_controller/intc_esp32c3.c b/drivers/interrupt_controller/intc_esp32c3.c index 7e8545034449c..da889a8f0afb9 100644 --- a/drivers/interrupt_controller/intc_esp32c3.c +++ b/drivers/interrupt_controller/intc_esp32c3.c @@ -49,17 +49,20 @@ LOG_MODULE_REGISTER(intc_esp32c3, CONFIG_LOG_DEFAULT_LEVEL); #define ESP32C6_INTC_SRCS_PER_IRQ 2 #define ESP32C6_INTC_AVAILABLE_IRQS 31 -/* For ESP32C6 only CPU peripheral interrupts number - * 1, 2, 5, 6, 8 ~ 31 are available. - * IRQ 31 is reserved for disabled interrupts +/* Interrupt overview for ESP32C6: + * - 0, 3, 4, and 7 are used by the CPU for core-local interrupts (CLINT) + * - 1 is used for Wi-Fi in Espressif HAL + * - 2, 5, 6, 8 .. 31 are available for Zephyr + * - 31 is reserved for disabled interrupts */ static uint8_t esp_intr_irq_alloc[ESP32C6_INTC_AVAILABLE_IRQS][ESP32C6_INTC_SRCS_PER_IRQ] = { [0] = {IRQ_NA, IRQ_NA}, + [1] = {IRQ_NA, IRQ_NA}, + [2] = {IRQ_FREE, IRQ_FREE}, [3] = {IRQ_NA, IRQ_NA}, [4] = {IRQ_NA, IRQ_NA}, + [5 ... 6] = {IRQ_FREE, IRQ_FREE}, [7] = {IRQ_NA, IRQ_NA}, - [1 ... 2] = {IRQ_FREE, IRQ_FREE}, - [5 ... 6] = {IRQ_FREE, IRQ_FREE}, [8 ... 30] = {IRQ_FREE, IRQ_FREE} }; #endif diff --git a/drivers/interrupt_controller/intc_gicv3.c b/drivers/interrupt_controller/intc_gicv3.c index c84a42c7e3632..50e36f1e87ae1 100644 --- a/drivers/interrupt_controller/intc_gicv3.c +++ b/drivers/interrupt_controller/intc_gicv3.c @@ -1,6 +1,7 @@ /* * Copyright 2020 Broadcom * Copyright 2024 NXP + * Copyright 2025 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +21,33 @@ #define DT_DRV_COMPAT arm_gic_v3 +#define GIC_V3_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(DT_DRV_COMPAT) + +#define GIC_REDISTRIBUTOR_STRIDE DT_PROP_OR(GIC_V3_NODE, redistributor_stride, 0) +#define GIC_NUM_REDISTRIBUTOR_REGIONS DT_PROP_OR(GIC_V3_NODE, redistributor_regions, 1) + +#define GIC_REG_REGION(idx, node_id) \ + { \ + .base = DT_REG_ADDR_BY_IDX(node_id, idx), \ + .size = DT_REG_SIZE_BY_IDX(node_id, idx), \ + } + +/* + * Structure to save GIC register region info + */ +struct gic_reg_region { + mem_addr_t base; + mem_addr_t size; +}; + +/* + * GIC register regions info table + */ +static struct gic_reg_region gic_reg_regions[] = { + LISTIFY(DT_NUM_REGS(GIC_V3_NODE), GIC_REG_REGION, (,), GIC_V3_NODE) +}; + + /* Redistributor base addresses for each core */ mem_addr_t gic_rdists[CONFIG_MP_MAX_NUM_CPUS]; @@ -578,20 +606,34 @@ static inline uint64_t arm_gic_get_typer(mem_addr_t addr) static mem_addr_t arm_gic_iterate_rdists(void) { uint64_t aff = arm_gic_mpidr_to_affinity(GET_MPIDR()); + uint32_t idx; - for (mem_addr_t rdist_addr = GIC_RDIST_BASE; - rdist_addr < GIC_RDIST_BASE + GIC_RDIST_SIZE; - rdist_addr += 0x20000) { - uint64_t val = arm_gic_get_typer(rdist_addr + GICR_TYPER); - uint64_t gicr_aff = GICR_TYPER_AFFINITY_VALUE_GET(val); + /* Skip the first array entry as it refers to the GIC distributor */ + for (idx = 1; idx < GIC_NUM_REDISTRIBUTOR_REGIONS + 1; idx++) { + uint64_t val; + mem_addr_t rdist_addr = gic_reg_regions[idx].base; + mem_addr_t rdist_end = rdist_addr + gic_reg_regions[idx].size; - if (arm_gic_aff_matching(gicr_aff, aff)) { - return rdist_addr; - } + do { + val = arm_gic_get_typer(rdist_addr + GICR_TYPER); + uint64_t gicr_aff = GICR_TYPER_AFFINITY_VALUE_GET(val); - if (GICR_TYPER_LAST_GET(val) == 1) { - return (mem_addr_t)NULL; - } + if (arm_gic_aff_matching(gicr_aff, aff)) { + return rdist_addr; + } + + if (GIC_REDISTRIBUTOR_STRIDE > 0) { + rdist_addr += GIC_REDISTRIBUTOR_STRIDE; + } else { + /* + * Skip RD_base and SGI_base + * In GICv3, GICR_TYPER.VLPIS bit is RES0 and can can be ignored + * as there are no VLPI and reserved pages. + */ + rdist_addr += KB(64) * 2; + } + + } while ((!GICR_TYPER_LAST_GET(val)) && (rdist_addr < rdist_end)); } return (mem_addr_t)NULL; diff --git a/drivers/interrupt_controller/intc_gicv3_priv.h b/drivers/interrupt_controller/intc_gicv3_priv.h index 64fabe2153769..30c7a6fa84ddd 100644 --- a/drivers/interrupt_controller/intc_gicv3_priv.h +++ b/drivers/interrupt_controller/intc_gicv3_priv.h @@ -1,5 +1,6 @@ /* * Copyright 2020 Broadcom + * Copyright 2025 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,13 +26,6 @@ #define GIC_BASER_SHARE_INNER 0x1UL /* Inner Shareable */ #define GIC_BASER_SHARE_OUTER 0x2UL /* Outer Shareable */ -/* - * GIC Register Interface Base Addresses - */ - -#define GIC_RDIST_BASE DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1) -#define GIC_RDIST_SIZE DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1) - /* SGI base is at 64K offset from Redistributor */ #define GICR_SGI_BASE_OFF 0x10000 diff --git a/drivers/interrupt_controller/intc_renesas_rz_ext_irq.c b/drivers/interrupt_controller/intc_renesas_rz_ext_irq.c new file mode 100644 index 0000000000000..7447441086c76 --- /dev/null +++ b/drivers/interrupt_controller/intc_renesas_rz_ext_irq.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rz_ext_irq + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(rz_ext_irq, CONFIG_INTC_LOG_LEVEL); + +struct intc_rz_ext_irq_config { + const struct pinctrl_dev_config *pin_config; + const external_irq_cfg_t *fsp_cfg; + const external_irq_api_t *fsp_api; +}; + +struct intc_rz_ext_irq_data { + external_irq_ctrl_t *fsp_ctrl; + intc_rz_ext_irq_callback_t callback; + void *callback_data; +}; + +/* FSP interruption handlers. */ +void r_intc_irq_isr(void); +void r_intc_nmi_isr(void); + +int intc_rz_ext_irq_enable(const struct device *dev) +{ + const struct intc_rz_ext_irq_config *config = dev->config; + struct intc_rz_ext_irq_data *data = dev->data; + fsp_err_t err = FSP_SUCCESS; + + err = config->fsp_api->enable(data->fsp_ctrl); + + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +int intc_rz_ext_irq_disable(const struct device *dev) +{ + const struct intc_rz_ext_irq_config *config = dev->config; + struct intc_rz_ext_irq_data *data = dev->data; + fsp_err_t err = FSP_SUCCESS; + + err = config->fsp_api->disable(data->fsp_ctrl); + + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +int intc_rz_ext_irq_set_callback(const struct device *dev, intc_rz_ext_irq_callback_t cb, void *arg) +{ + struct intc_rz_ext_irq_data *data = dev->data; + + data->callback = cb; + data->callback_data = arg; + + return 0; +} + +static int intc_rz_ext_irq_init(const struct device *dev) +{ + const struct intc_rz_ext_irq_config *config = dev->config; + struct intc_rz_ext_irq_data *data = dev->data; + fsp_err_t err = FSP_SUCCESS; + int ret = 0; + + if (config->pin_config) { + ret = pinctrl_apply_state(config->pin_config, PINCTRL_STATE_DEFAULT); + + if (ret < 0) { + LOG_ERR("%s: pinctrl config failed.", __func__); + return ret; + } + } + + err = config->fsp_api->open(data->fsp_ctrl, config->fsp_cfg); + + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +static void intc_rz_ext_irq_callback(external_irq_callback_args_t *args) +{ + const struct device *dev = (const struct device *)args->p_context; + struct intc_rz_ext_irq_data *data = dev->data; + + if (data->callback) { + data->callback(data->callback_data); + } +} + +#define EXT_IRQ_RZG_IRQ_CONNECT(index, isr, isr_nmi) \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(index, 0, irq), DT_INST_IRQ_BY_IDX(index, 0, priority), \ + COND_CODE_0(DT_INST_IRQ_BY_IDX(index, 0, irq), \ + (isr_nmi), (isr)), NULL, 0); + +#define INTC_RZG_EXT_IRQ_INIT(index) \ + static const external_irq_cfg_t g_external_irq##index##_cfg = { \ + .trigger = DT_INST_ENUM_IDX_OR(index, trigger_type, 0), \ + .filter_enable = true, \ + .pclk_div = EXTERNAL_IRQ_PCLK_DIV_BY_1, \ + .p_callback = intc_rz_ext_irq_callback, \ + .p_context = DEVICE_DT_INST_GET(index), \ + .p_extend = NULL, \ + .ipl = DT_INST_IRQ_BY_IDX(index, 0, priority), \ + .irq = DT_INST_IRQ_BY_IDX(index, 0, irq), \ + COND_CODE_0(DT_INST_IRQ_BY_IDX(index, 0, irq), \ + (.channel = DT_INST_IRQ_BY_IDX(index, 0, irq)), \ + (.channel = DT_INST_IRQ_BY_IDX(index, 0, irq) - 1)), \ + }; \ + \ + PINCTRL_DT_INST_DEFINE(index); \ + \ + struct intc_rz_ext_irq_config intc_rz_ext_irq_config##index = { \ + .pin_config = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .fsp_cfg = (external_irq_cfg_t *)&g_external_irq##index##_cfg, \ + COND_CODE_0(DT_INST_IRQ_BY_IDX(index, 0, irq), ( \ + .fsp_api = &g_external_irq_on_intc_nmi), ( \ + .fsp_api = &g_external_irq_on_intc_irq)), \ + }; \ + \ + COND_CODE_0(DT_INST_IRQ_BY_IDX(index, 0, irq), \ + (static intc_nmi_instance_ctrl_t g_external_irq##index##_ctrl;), \ + (static intc_irq_instance_ctrl_t g_external_irq##index##_ctrl;)) \ + \ + static struct intc_rz_ext_irq_data intc_rz_ext_irq_data##index = { \ + .fsp_ctrl = (external_irq_ctrl_t *)&g_external_irq##index##_ctrl, \ + }; \ + \ + static int intc_rz_ext_irq_init_##index(const struct device *dev) \ + { \ + EXT_IRQ_RZG_IRQ_CONNECT(index, r_intc_irq_isr, r_intc_nmi_isr) \ + return intc_rz_ext_irq_init(dev); \ + }; \ + \ + DEVICE_DT_INST_DEFINE(index, intc_rz_ext_irq_init_##index, NULL, \ + &intc_rz_ext_irq_data##index, &intc_rz_ext_irq_config##index, \ + PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(INTC_RZG_EXT_IRQ_INIT) diff --git a/drivers/ipm/Kconfig b/drivers/ipm/Kconfig index 0648cdd32c89d..8d7a3f3288e04 100644 --- a/drivers/ipm/Kconfig +++ b/drivers/ipm/Kconfig @@ -59,7 +59,7 @@ config IPM_MBOX bool "IPM over MBOX driver" default y depends on DT_HAS_ZEPHYR_MBOX_IPM_ENABLED - depends on MBOX + select MBOX help IPM driver using a MBOX driver as the backend mechanism. diff --git a/drivers/ipm/ipm_mcux.c b/drivers/ipm/ipm_mcux.c index ac0ad8c3b3c07..8d860710c8818 100644 --- a/drivers/ipm/ipm_mcux.c +++ b/drivers/ipm/ipm_mcux.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, NXP + * Copyright (c) 2017-2018, 2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,8 +20,11 @@ #define MCUX_IPM_DATA_REGS 1 #define MCUX_IPM_MAX_ID_VAL 0 -#if (defined(LPC55S69_cm33_core0_SERIES) || defined(LPC55S69_cm33_core1_SERIES)) -#ifdef LPC55S69_cm33_core0_SERIES +#if (defined(LPC55S69_cm33_core0_SERIES) || defined(LPC55S69_cm33_core1_SERIES) || \ +defined(CONFIG_SOC_SERIES_MCXN)) +#if (defined(LPC55S69_cm33_core0_SERIES) || defined(MCXN947_cm33_core0_SERIES) || \ +defined(MCXN946_cm33_core0_SERIES) || defined(MCXN547_cm33_core0_SERIES) || \ +defined(MCXN546_cm33_core0_SERIES)) #define MAILBOX_ID_THIS_CPU kMAILBOX_CM33_Core0 #define MAILBOX_ID_OTHER_CPU kMAILBOX_CM33_Core1 #else diff --git a/drivers/ipm/ipm_sedi.c b/drivers/ipm/ipm_sedi.c index a5f689556b6ad..7fa93ea19860f 100644 --- a/drivers/ipm/ipm_sedi.c +++ b/drivers/ipm/ipm_sedi.c @@ -284,10 +284,10 @@ static DEVICE_API(ipm, ipm_funcs) = { DT_INST_PROP(n, peripheral_id), \ DT_INST_IRQ(n, sense)); \ } \ - PM_DEVICE_DT_DEFINE(DT_NODELABEL(ipm##n), ipm_power_ctrl); \ + PM_DEVICE_DT_INST_DEFINE(n, ipm_power_ctrl); \ DEVICE_DT_INST_DEFINE(n, \ &ipm_init, \ - PM_DEVICE_DT_GET(DT_NODELABEL(ipm##n)), \ + PM_DEVICE_DT_INST_GET(n), \ &ipm_data_##n, \ &ipm_config_##n, \ POST_KERNEL, \ diff --git a/drivers/led/Kconfig.gpio b/drivers/led/Kconfig.gpio index 7288daae29ed8..ce4bfffe0d3b7 100644 --- a/drivers/led/Kconfig.gpio +++ b/drivers/led/Kconfig.gpio @@ -4,6 +4,7 @@ config LED_GPIO bool "GPIO LED driver" default y - depends on GPIO && DT_HAS_GPIO_LEDS_ENABLED + depends on DT_HAS_GPIO_LEDS_ENABLED + select GPIO help Enable driver for GPIO LEDs. diff --git a/drivers/led/is31fl3194.c b/drivers/led/is31fl3194.c index 98f1de410d20e..649afa5556ac2 100644 --- a/drivers/led/is31fl3194.c +++ b/drivers/led/is31fl3194.c @@ -109,7 +109,7 @@ static int is31fl3194_set_color(const struct device *dev, uint32_t led, uint8_t break; default: /* unreachable: mapping already tested in is31fl3194_check_config */ - continue; + return -EINVAL; } ret = i2c_reg_write_byte_dt(&config->bus, led_channels[i], value); diff --git a/drivers/led/led_shell.c b/drivers/led/led_shell.c index 1bc09c8bb7f1d..65db93c67562c 100644 --- a/drivers/led/led_shell.c +++ b/drivers/led/led_shell.c @@ -26,7 +26,7 @@ static int parse_common_args(const struct shell *sh, char **argv, { char *end_ptr; - *dev = device_get_binding(argv[arg_idx_dev]); + *dev = shell_device_get_binding(argv[arg_idx_dev]); if (!*dev) { shell_error(sh, "LED device %s not found", argv[arg_idx_dev]); @@ -330,14 +330,14 @@ cmd_write_channels(const struct shell *sh, size_t argc, char **argv) return err; } -static bool device_is_led_and_ready(const struct device *dev) +static bool device_is_led(const struct device *dev) { - return device_is_ready(dev) && DEVICE_API_IS(led, dev); + return DEVICE_API_IS(led, dev); } static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_filter(idx, device_is_led_and_ready); + const struct device *dev = shell_device_filter(idx, device_is_led); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/led/lp50xx.c b/drivers/led/lp50xx.c index 57ffb1db3b0d8..bd1fd11b529e7 100644 --- a/drivers/led/lp50xx.c +++ b/drivers/led/lp50xx.c @@ -153,7 +153,8 @@ static int lp50xx_set_color(const struct device *dev, uint32_t led, { const struct lp50xx_config *config = dev->config; const struct led_info *led_info = lp50xx_led_to_info(config, led); - uint8_t buf[4]; + uint8_t buf[LP50XX_COLORS_PER_LED + 1]; + uint8_t i; if (!led_info) { return -ENODEV; @@ -170,11 +171,11 @@ static int lp50xx_set_color(const struct device *dev, uint32_t led, buf[0] = LP50XX_OUT0_COLOR(config->num_modules); buf[0] += LP50XX_COLORS_PER_LED * led_info->index; - buf[1] = color[0]; - buf[2] = color[1]; - buf[3] = color[2]; + for (i = 0; i < led_info->num_colors; i++) { + buf[1 + i] = color[i]; + } - return i2c_write_dt(&config->bus, buf, sizeof(buf)); + return i2c_write_dt(&config->bus, buf, led_info->num_colors + 1); } static int lp50xx_write_channels(const struct device *dev, @@ -266,6 +267,7 @@ static int lp50xx_enable(const struct device *dev, bool enable) static int lp50xx_init(const struct device *dev) { const struct lp50xx_config *config = dev->config; + uint8_t led; int err; if (!i2c_is_ready_dt(&config->bus)) { @@ -273,6 +275,7 @@ static int lp50xx_init(const struct device *dev) return -ENODEV; } + /* Check LED configuration found in DT */ if (config->num_leds > config->max_leds) { LOG_ERR("%s: invalid number of LEDs %d (max %d)", dev->name, @@ -280,6 +283,16 @@ static int lp50xx_init(const struct device *dev) config->max_leds); return -EINVAL; } + for (led = 0; led < config->num_leds; led++) { + const struct led_info *led_info = + lp50xx_led_to_info(config, led); + + if (led_info->num_colors > LP50XX_COLORS_PER_LED) { + LOG_ERR("%s: LED %d: invalid number of colors (max %d)", + dev->name, led, LP50XX_COLORS_PER_LED); + return -EINVAL; + } + } /* Configure GPIO if present */ if (config->gpio_enable.port != NULL) { diff --git a/drivers/led_strip/apa102.c b/drivers/led_strip/apa102.c index 1ba14af8b51c9..f0df75241d6db 100644 --- a/drivers/led_strip/apa102.c +++ b/drivers/led_strip/apa102.c @@ -15,13 +15,15 @@ struct apa102_config { struct spi_dt_spec bus; size_t length; + uint8_t *const end_frame; + const size_t end_frame_size; }; static int apa102_update(const struct device *dev, void *buf, size_t size) { const struct apa102_config *config = dev->config; static const uint8_t zeros[] = { 0, 0, 0, 0 }; - static const uint8_t ones[] = { 0xFF, 0xFF, 0xFF, 0xFF }; + const struct spi_buf tx_bufs[] = { { /* Start frame: at least 32 zeros */ @@ -38,8 +40,8 @@ static int apa102_update(const struct device *dev, void *buf, size_t size) * remaining bits to the LEDs at the end of * the strip. */ - .buf = (uint8_t *)ones, - .len = sizeof(ones), + .buf = (uint8_t *)config->end_frame, + .len = config->end_frame_size, }, }; const struct spi_buf_set tx = { @@ -89,6 +91,8 @@ static int apa102_init(const struct device *dev) return -ENODEV; } + memset(config->end_frame, 0xFF, config->end_frame_size); + return 0; } @@ -97,13 +101,26 @@ static DEVICE_API(led_strip, apa102_api) = { .length = apa102_length, }; +/* + * The "End frame" is statically allocated, as a sequence of 0xFF bytes + * The only function of the “End frame” is to supply more clock pulses + * to the string until the data has permeated to the last LED. The + * number of clock pulses required is exactly half the total number + * of LEDs in the string. See below `end_frame`. + */ #define APA102_DEVICE(idx) \ + static uint8_t apa102_end_frame_##idx \ + [(DT_INST_PROP(idx, chain_length) / \ + sizeof(struct led_rgb) / 2) + 1]; \ static const struct apa102_config apa102_##idx##_config = { \ .bus = SPI_DT_SPEC_INST_GET( \ idx, \ SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), \ 0), \ .length = DT_INST_PROP(idx, chain_length), \ + .end_frame = apa102_end_frame_##idx, \ + .end_frame_size = (DT_INST_PROP(idx, chain_length) / \ + sizeof(struct led_rgb) / 2) + 1, \ }; \ \ DEVICE_DT_INST_DEFINE(idx, \ diff --git a/drivers/led_strip/ws2812_i2s.c b/drivers/led_strip/ws2812_i2s.c index 1c7cf2aa48cfc..4e2d8a96f5dbc 100644 --- a/drivers/led_strip/ws2812_i2s.c +++ b/drivers/led_strip/ws2812_i2s.c @@ -230,7 +230,7 @@ static DEVICE_API(led_strip, ws2812_i2s_api) = { DT_INST_PROP(idx, color_mapping); \ \ static const struct ws2812_i2s_cfg ws2812_i2s_##idx##_cfg = { \ - .dev = DEVICE_DT_GET(DT_INST_PROP(idx, i2s_dev)), \ + .dev = DEVICE_DT_GET(DT_INST_BUS(idx)), \ .tx_buf_bytes = WS2812_I2S_BUFSIZE(idx), \ .mem_slab = &ws2812_i2s_##idx##_slab, \ .num_colors = WS2812_NUM_COLORS(idx), \ diff --git a/drivers/lora/rylrxxx.c b/drivers/lora/rylrxxx.c index 15d17ab406ef7..6ed47d4c90e56 100644 --- a/drivers/lora/rylrxxx.c +++ b/drivers/lora/rylrxxx.c @@ -102,6 +102,7 @@ struct rylr_data { uint8_t pending_async_flags; struct k_poll_signal *async_tx_signal; lora_recv_cb async_rx_cb; + void *async_user_data; const struct device *dev; uint8_t msgq_buffer[CONFIG_RYLRXXX_UNSOLICITED_RX_MSGQ_SIZE]; struct modem_pipe *modem_pipe; @@ -170,7 +171,8 @@ static void on_rx(struct modem_chat *chat, char **argv, uint16_t argc, void *use msg.snr = atoi(argv[5]); if (RYLR_IS_RX_PENDING(driver_data->pending_async_flags)) { - driver_data->async_rx_cb(driver_data->dev, msg.data, msg.length, msg.rssi, msg.snr); + driver_data->async_rx_cb(driver_data->dev, msg.data, msg.length, msg.rssi, msg.snr, + driver_data->async_user_data); } else { err = k_msgq_put(&driver_data->rx_msgq, &msg, K_NO_WAIT); if (err != 0) { @@ -515,7 +517,7 @@ int rylr_recv(const struct device *dev, uint8_t *ret_msg, uint8_t size, k_timeou return ret; } -int rylr_recv_async(const struct device *dev, lora_recv_cb cb) +int rylr_recv_async(const struct device *dev, lora_recv_cb cb, void *user_data) { int err = 0; struct rylr_data *data = dev->data; @@ -538,6 +540,7 @@ int rylr_recv_async(const struct device *dev, lora_recv_cb cb) } data->async_rx_cb = cb; + data->async_user_data = user_data; if (RYLR_IS_ASYNC_OP_PENDING(data->pending_async_flags)) { LOG_ERR("pending async opperation"); err = -EBUSY; diff --git a/drivers/lora/sx12xx_common.c b/drivers/lora/sx12xx_common.c index b8be10541bce2..25d72ff806113 100644 --- a/drivers/lora/sx12xx_common.c +++ b/drivers/lora/sx12xx_common.c @@ -33,6 +33,7 @@ static struct sx12xx_data { const struct device *dev; struct k_poll_signal *operation_done; lora_recv_cb async_rx_cb; + void *async_user_data; RadioEvents_t events; struct lora_modem_config tx_cfg; atomic_t modem_usage; @@ -106,7 +107,8 @@ static void sx12xx_ev_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, /* Start receiving again */ Radio.Rx(0); /* Run the callback */ - dev_data.async_rx_cb(dev_data.dev, payload, size, rssi, snr); + dev_data.async_rx_cb(dev_data.dev, payload, size, rssi, snr, + dev_data.async_user_data); /* Don't run the synchronous code */ return; } @@ -305,7 +307,7 @@ int sx12xx_lora_recv(const struct device *dev, uint8_t *data, uint8_t size, return size; } -int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb) +int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb, void *user_data) { /* Cancel ongoing reception */ if (cb == NULL) { @@ -323,6 +325,7 @@ int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb) /* Store parameters */ dev_data.async_rx_cb = cb; + dev_data.async_user_data = user_data; /* Start reception */ Radio.SetMaxPayloadLength(MODEM_LORA, 255); diff --git a/drivers/lora/sx12xx_common.h b/drivers/lora/sx12xx_common.h index d8602eb758b17..2a26485f2c077 100644 --- a/drivers/lora/sx12xx_common.h +++ b/drivers/lora/sx12xx_common.h @@ -29,7 +29,7 @@ int sx12xx_lora_send_async(const struct device *dev, uint8_t *data, int sx12xx_lora_recv(const struct device *dev, uint8_t *data, uint8_t size, k_timeout_t timeout, int16_t *rssi, int8_t *snr); -int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb); +int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb, void *user_data); int sx12xx_lora_config(const struct device *dev, struct lora_modem_config *config); diff --git a/drivers/mbox/CMakeLists.txt b/drivers/mbox/CMakeLists.txt index 1a862e6375a53..bc1a38cb0b0ef 100644 --- a/drivers/mbox/CMakeLists.txt +++ b/drivers/mbox/CMakeLists.txt @@ -19,3 +19,4 @@ zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_BELLBOARD_RX mbox_nrf_bellboard_rx. zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_BELLBOARD_TX mbox_nrf_bellboard_tx.c) zephyr_library_sources_ifdef(CONFIG_MBOX_STM32_HSEM mbox_stm32_hsem.c) zephyr_library_sources_ifdef(CONFIG_MBOX_IVSHMEM mbox_ivshmem.c) +zephyr_library_sources_ifdef(CONFIG_MBOX_TI_OMAP_MAILBOX mbox_ti_omap.c) diff --git a/drivers/mbox/Kconfig b/drivers/mbox/Kconfig index 660297801285b..7c614849907d7 100644 --- a/drivers/mbox/Kconfig +++ b/drivers/mbox/Kconfig @@ -23,6 +23,8 @@ source "drivers/mbox/Kconfig.nrf_bellboard" source "drivers/mbox/Kconfig.stm32_hsem" source "drivers/mbox/Kconfig.esp32" source "drivers/mbox/Kconfig.ivshmem" +source "drivers/mbox/Kconfig.ti_omap" + config MBOX_INIT_PRIORITY int "MBOX init priority" diff --git a/drivers/mbox/Kconfig.nrf_vevif_event b/drivers/mbox/Kconfig.nrf_vevif_event index c9d634dac828c..655cc82f38509 100644 --- a/drivers/mbox/Kconfig.nrf_vevif_event +++ b/drivers/mbox/Kconfig.nrf_vevif_event @@ -14,3 +14,8 @@ config MBOX_NRF_VEVIF_EVENT_TX default y help Mailbox driver for transmitting events from VPR to a remote core + +config MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16 + bool "Apply errata 16 for nRF54L series" + depends on SOC_SERIES_NRF54LX + default y diff --git a/drivers/mbox/Kconfig.ti_omap b/drivers/mbox/Kconfig.ti_omap new file mode 100644 index 0000000000000..8cc040ea521a0 --- /dev/null +++ b/drivers/mbox/Kconfig.ti_omap @@ -0,0 +1,9 @@ +# Copyright 2024 Texas Instruments Incorporated. +# SPDX-License-Identifier: Apache-2.0 + +config MBOX_TI_OMAP_MAILBOX + bool "TI OMAP Mailbox driver" + default y + depends on DT_HAS_TI_OMAP_MAILBOX_ENABLED + help + Driver for TI OMAP Mailbox. diff --git a/drivers/mbox/mbox_andes_plic_sw.c b/drivers/mbox/mbox_andes_plic_sw.c index b297200233180..0f17240347453 100644 --- a/drivers/mbox/mbox_andes_plic_sw.c +++ b/drivers/mbox/mbox_andes_plic_sw.c @@ -104,7 +104,7 @@ static int mbox_plic_set_enabled(const struct device *dev, uint32_t ch, bool ena return 0; } -static const struct mbox_driver_api mbox_plic_driver_api = { +static DEVICE_API(mbox, mbox_plic_driver_api) = { .send = mbox_plic_send, .register_callback = mbox_plic_register_callback, .mtu_get = mbox_plic_mtu_get, diff --git a/drivers/mbox/mbox_esp32.c b/drivers/mbox/mbox_esp32.c index b7764b0f2daf7..39bb2c9fa3543 100644 --- a/drivers/mbox/mbox_esp32.c +++ b/drivers/mbox/mbox_esp32.c @@ -235,7 +235,7 @@ static int esp32_mbox_init(const struct device *dev) return ret; } -static const struct mbox_driver_api esp32_mbox_driver_api = { +static DEVICE_API(mbox, esp32_mbox_driver_api) = { .send = esp32_mbox_send, .register_callback = esp32_mbox_register_callback, .mtu_get = esp32_mbox_mtu_get, diff --git a/drivers/mbox/mbox_ivshmem.c b/drivers/mbox/mbox_ivshmem.c index 39b30087a7589..624d9f5d46ca9 100644 --- a/drivers/mbox/mbox_ivshmem.c +++ b/drivers/mbox/mbox_ivshmem.c @@ -132,7 +132,7 @@ static int ivshmem_mbox_init(const struct device *dev) return 0; } -static const struct mbox_driver_api ivshmem_mbox_driver_api = { +static DEVICE_API(mbox, ivshmem_mbox_driver_api) = { .send = ivshmem_mbox_send, .register_callback = ivshmem_mbox_register_callback, .mtu_get = ivshmem_mbox_mtu_get, diff --git a/drivers/mbox/mbox_nrf_bellboard_rx.c b/drivers/mbox/mbox_nrf_bellboard_rx.c index 54dd21b9624ff..c8bac16139704 100644 --- a/drivers/mbox/mbox_nrf_bellboard_rx.c +++ b/drivers/mbox/mbox_nrf_bellboard_rx.c @@ -135,7 +135,7 @@ static int bellboard_rx_set_enabled(const struct device *dev, uint32_t id, bool return 0; } -static const struct mbox_driver_api bellboard_rx_driver_api = { +static DEVICE_API(mbox, bellboard_rx_driver_api) = { .max_channels_get = bellboard_rx_max_channels_get, .register_callback = bellboard_rx_register_callback, .set_enabled = bellboard_rx_set_enabled, diff --git a/drivers/mbox/mbox_nrf_bellboard_tx.c b/drivers/mbox/mbox_nrf_bellboard_tx.c index 9f98f57ff5d2a..4b00c7c353dc5 100644 --- a/drivers/mbox/mbox_nrf_bellboard_tx.c +++ b/drivers/mbox/mbox_nrf_bellboard_tx.c @@ -45,7 +45,7 @@ static uint32_t bellboard_tx_max_channels_get(const struct device *dev) return BELLBOARD_TASKS_TRIGGER_MaxCount; } -static const struct mbox_driver_api bellboard_tx_driver_api = { +static DEVICE_API(mbox, bellboard_tx_driver_api) = { .send = bellboard_tx_send, .mtu_get = bellboard_tx_mtu_get, .max_channels_get = bellboard_tx_max_channels_get, diff --git a/drivers/mbox/mbox_nrf_vevif_event_rx.c b/drivers/mbox/mbox_nrf_vevif_event_rx.c index b5be6a97b79dc..b26bb4a19fbaf 100644 --- a/drivers/mbox/mbox_nrf_vevif_event_rx.c +++ b/drivers/mbox/mbox_nrf_vevif_event_rx.c @@ -13,6 +13,12 @@ #define EVENTS_IDX_MIN NRF_VPR_EVENTS_TRIGGERED_MIN #define EVENTS_IDX_MAX NRF_VPR_EVENTS_TRIGGERED_MAX +#if defined(CONFIG_MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16) +#define VEVIF_54L_EVENT_IDX 20 +BUILD_ASSERT(DT_INST_PROP(0, nordic_events) == 1); +BUILD_ASSERT(DT_INST_PROP(0, nordic_events_mask) & BIT(VEVIF_54L_EVENT_IDX)); +#endif + /* callbacks */ struct mbox_vevif_event_rx_cbs { mbox_callback_t cb[EVENTS_IDX_MAX - EVENTS_IDX_MIN + 1U]; @@ -27,24 +33,34 @@ struct mbox_vevif_event_rx_conf { void (*irq_connect)(void); }; +static void trigger_callback(const struct device *dev, struct mbox_vevif_event_rx_cbs *cbs, + uint8_t id) +{ + uint8_t idx = id - EVENTS_IDX_MIN; + + if ((cbs->enabled_mask & BIT(id)) && (cbs->cb[idx] != NULL)) { + cbs->cb[idx](dev, id, cbs->user_data[idx], NULL); + } +} + static void vevif_event_rx_isr(const void *device) { const struct device *dev = (struct device *)device; - const struct mbox_vevif_event_rx_conf *config = dev->config; struct mbox_vevif_event_rx_cbs *cbs = dev->data; +#if !defined(CONFIG_MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16) + const struct mbox_vevif_event_rx_conf *config = dev->config; + for (uint8_t id = EVENTS_IDX_MIN; id < EVENTS_IDX_MAX + 1U; id++) { nrf_vpr_event_t event = nrfy_vpr_triggered_event_get(id); - if (nrfy_vpr_event_check(config->vpr, event)) { nrfy_vpr_event_clear(config->vpr, event); - uint8_t idx = id - EVENTS_IDX_MIN; - - if ((cbs->enabled_mask & BIT(id)) && (cbs->cb[idx] != NULL)) { - cbs->cb[idx](dev, id, cbs->user_data[idx], NULL); - } + trigger_callback(dev, cbs, id); } } +#else + trigger_callback(dev, cbs, VEVIF_54L_EVENT_IDX); +#endif } static inline bool vevif_event_rx_event_is_valid(uint32_t events_mask, uint32_t id) @@ -104,7 +120,7 @@ static int vevif_event_rx_set_enabled(const struct device *dev, uint32_t id, boo return 0; } -static const struct mbox_driver_api vevif_event_rx_driver_api = { +static DEVICE_API(mbox, vevif_event_rx_driver_api) = { .max_channels_get = vevif_event_rx_max_channels_get, .register_callback = vevif_event_rx_register_callback, .set_enabled = vevif_event_rx_set_enabled, @@ -135,7 +151,7 @@ static int vevif_event_rx_init(const struct device *dev) .enabled_mask = 0, \ }; \ static const struct mbox_vevif_event_rx_conf conf##inst = { \ - .vpr = (NRF_VPR_Type *)DT_INST_REG_ADDR(inst), \ + .vpr = (NRF_VPR_Type *)DT_REG_ADDR(DT_INST_PARENT(inst)), \ .events = DT_INST_PROP(inst, nordic_events), \ .events_mask = DT_INST_PROP(inst, nordic_events_mask), \ .irq_connect = irq_connect##inst, \ diff --git a/drivers/mbox/mbox_nrf_vevif_event_tx.c b/drivers/mbox/mbox_nrf_vevif_event_tx.c index 8bd731f56a592..f7703c8d3b806 100644 --- a/drivers/mbox/mbox_nrf_vevif_event_tx.c +++ b/drivers/mbox/mbox_nrf_vevif_event_tx.c @@ -39,6 +39,13 @@ static int vevif_event_tx_send(const struct device *dev, uint32_t id, const stru nrf_vpr_csr_vevif_events_trigger(BIT(id)); +#if defined(CONFIG_MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16) + while (!nrf_vpr_csr_vevif_events_get()) { + ; + } + nrf_vpr_csr_vevif_events_set(0); +#endif + return 0; } @@ -56,7 +63,7 @@ static uint32_t vevif_event_tx_max_channels_get(const struct device *dev) return VEVIF_EVENTS_NUM; } -static const struct mbox_driver_api vevif_event_tx_driver_api = { +static DEVICE_API(mbox, vevif_event_tx_driver_api) = { .send = vevif_event_tx_send, .mtu_get = vevif_event_tx_mtu_get, .max_channels_get = vevif_event_tx_max_channels_get, diff --git a/drivers/mbox/mbox_nrf_vevif_task_rx.c b/drivers/mbox/mbox_nrf_vevif_task_rx.c index 8783424ae9899..8afe9eeb50bb8 100644 --- a/drivers/mbox/mbox_nrf_vevif_task_rx.c +++ b/drivers/mbox/mbox_nrf_vevif_task_rx.c @@ -105,7 +105,7 @@ static int vevif_task_rx_set_enabled(const struct device *dev, uint32_t id, bool return 0; } -static const struct mbox_driver_api vevif_task_rx_driver_api = { +static DEVICE_API(mbox, vevif_task_rx_driver_api) = { .max_channels_get = vevif_task_rx_max_channels_get, .register_callback = vevif_task_rx_register_callback, .set_enabled = vevif_task_rx_set_enabled, diff --git a/drivers/mbox/mbox_nrf_vevif_task_tx.c b/drivers/mbox/mbox_nrf_vevif_task_tx.c index a409ef214b7de..3d553d4b48415 100644 --- a/drivers/mbox/mbox_nrf_vevif_task_tx.c +++ b/drivers/mbox/mbox_nrf_vevif_task_tx.c @@ -56,7 +56,7 @@ static uint32_t vevif_task_tx_max_channels_get(const struct device *dev) return config->tasks; } -static const struct mbox_driver_api vevif_task_tx_driver_api = { +static DEVICE_API(mbox, vevif_task_tx_driver_api) = { .send = vevif_task_tx_send, .mtu_get = vevif_task_tx_mtu_get, .max_channels_get = vevif_task_tx_max_channels_get, diff --git a/drivers/mbox/mbox_nrfx_ipc.c b/drivers/mbox/mbox_nrfx_ipc.c index 189e00d5967e6..e5fcaf9d4a865 100644 --- a/drivers/mbox/mbox_nrfx_ipc.c +++ b/drivers/mbox/mbox_nrfx_ipc.c @@ -190,7 +190,7 @@ static int mbox_nrf_init(const struct device *dev) return 0; } -static const struct mbox_driver_api mbox_nrf_driver_api = { +static DEVICE_API(mbox, mbox_nrf_driver_api) = { .send = mbox_nrf_send, .register_callback = mbox_nrf_register_callback, .mtu_get = mbox_nrf_mtu_get, diff --git a/drivers/mbox/mbox_nxp_imx_mu.c b/drivers/mbox/mbox_nxp_imx_mu.c index fa11f84bfc2c6..8b5dfd3b73868 100644 --- a/drivers/mbox/mbox_nxp_imx_mu.c +++ b/drivers/mbox/mbox_nxp_imx_mu.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 * @@ -21,6 +21,25 @@ LOG_MODULE_REGISTER(nxp_mbox_imx_mu); #define MU_MAX_CHANNELS 4 #define MU_MBOX_SIZE sizeof(uint32_t) +/* + * Arrays to translate the channel number to Generic Interrupt Mask for mu driver. + * The kMU_GenInt[0..3]Flag comes from MU driver header mu.h. + * There are more MU drivers implementations. For the `mu` driver + * the kMU_GenInt0Flag goes from 3 to 0 relative bit for the + * `mu1` driver kMU_GenInt0Flag goes from 0 to 3. + * Same for kMU_GenInt0InterruptTrigger and kMU_Rx0FullFlag. + * Therefore use this mapping table to select correct mask based on channel index. + */ +const static uint32_t g_gen_int_pend_mask[MU_MAX_CHANNELS] = {kMU_GenInt0Flag, kMU_GenInt1Flag, + kMU_GenInt2Flag, kMU_GenInt3Flag}; + +const static uint32_t g_gen_int_trig_mask[MU_MAX_CHANNELS] = { + kMU_GenInt0InterruptTrigger, kMU_GenInt1InterruptTrigger, kMU_GenInt2InterruptTrigger, + kMU_GenInt3InterruptTrigger}; + +const static uint32_t g_rx_flag_mask[MU_MAX_CHANNELS] = {kMU_Rx0FullFlag, kMU_Rx1FullFlag, + kMU_Rx2FullFlag, kMU_Rx3FullFlag}; + struct nxp_imx_mu_data { mbox_callback_t cb[MU_MAX_CHANNELS]; void *user_data[MU_MAX_CHANNELS]; @@ -42,11 +61,11 @@ static int nxp_imx_mu_send(const struct device *dev, uint32_t channel, const str /* Signalling mode. */ if (msg == NULL) { - return MU_TriggerInterrupts(cfg->base, kMU_GenInt0InterruptTrigger >> channel); + return MU_TriggerInterrupts(cfg->base, g_gen_int_trig_mask[channel]); } /* Data transfer mode. */ - if (msg->size != MU_MBOX_SIZE) { + if (msg->size > MU_MBOX_SIZE) { /* We can only send this many bytes at a time. */ return -EMSGSIZE; } @@ -113,7 +132,7 @@ static int nxp_imx_mu_set_enabled(const struct device *dev, uint32_t channel, bo return 0; } -static const struct mbox_driver_api nxp_imx_mu_driver_api = { +static DEVICE_API(mbox, nxp_imx_mu_driver_api) = { .send = nxp_imx_mu_send, .register_callback = nxp_imx_mu_register_callback, .mtu_get = nxp_imx_mu_mtu_get, @@ -159,10 +178,13 @@ static void handle_irq(const struct device *dev) { struct nxp_imx_mu_data *data = dev->data; const struct nxp_imx_mu_config *config = dev->config; - const uint32_t flag = MU_GetStatusFlags(config->base); + const uint32_t flags = MU_GetStatusFlags(config->base); for (int i_channel = 0; i_channel < MU_MAX_CHANNELS; i_channel++) { - if ((flag & (kMU_Rx0FullFlag >> i_channel)) == (kMU_Rx0FullFlag >> i_channel)) { + const uint32_t rx_int_mask = g_rx_flag_mask[i_channel]; + const uint32_t gen_int_mask = g_gen_int_pend_mask[i_channel]; + + if ((flags & rx_int_mask) == rx_int_mask) { data->received_data = MU_ReceiveMsgNonBlocking(config->base, i_channel); struct mbox_msg msg = {(const void *)&data->received_data, MU_MBOX_SIZE}; @@ -170,9 +192,8 @@ static void handle_irq(const struct device *dev) data->cb[i_channel](dev, i_channel, data->user_data[i_channel], &msg); } - } else if ((flag & (kMU_GenInt0Flag >> i_channel)) == - (kMU_GenInt0Flag >> i_channel)) { - MU_ClearStatusFlags(config->base, (kMU_GenInt0Flag >> i_channel)); + } else if ((flags & gen_int_mask) == gen_int_mask) { + MU_ClearStatusFlags(config->base, gen_int_mask); if (data->cb[i_channel]) { data->cb[i_channel](dev, i_channel, data->user_data[i_channel], NULL); diff --git a/drivers/mbox/mbox_nxp_mailbox.c b/drivers/mbox/mbox_nxp_mailbox.c index cfd0640cddc00..807d78efdf992 100644 --- a/drivers/mbox/mbox_nxp_mailbox.c +++ b/drivers/mbox/mbox_nxp_mailbox.c @@ -21,8 +21,11 @@ LOG_MODULE_REGISTER(nxp_mbox_mailbox); #define MAILBOX_MAX_CHANNELS 4 #define MAILBOX_MBOX_SIZE 3 -#if (defined(LPC55S69_cm33_core0_SERIES) || defined(LPC55S69_cm33_core1_SERIES)) -#ifdef LPC55S69_cm33_core0_SERIES +#if (defined(LPC55S69_cm33_core0_SERIES) || defined(LPC55S69_cm33_core1_SERIES) || \ +defined(CONFIG_SOC_SERIES_MCXN)) +#if (defined(LPC55S69_cm33_core0_SERIES) || defined(MCXN947_cm33_core0_SERIES) || \ +defined(MCXN946_cm33_core0_SERIES) || defined(MCXN547_cm33_core0_SERIES) || \ +defined(MCXN546_cm33_core0_SERIES)) #define MAILBOX_ID_THIS_CPU kMAILBOX_CM33_Core0 #define MAILBOX_ID_OTHER_CPU kMAILBOX_CM33_Core1 #else @@ -180,7 +183,7 @@ static int nxp_mailbox_set_enabled(const struct device *dev, uint32_t channel, b return 0; } -static const struct mbox_driver_api nxp_mailbox_driver_api = { +static DEVICE_API(mbox, nxp_mailbox_driver_api) = { .send = nxp_mailbox_send, .register_callback = nxp_mailbox_register_callback, .mtu_get = nxp_mailbox_mtu_get, diff --git a/drivers/mbox/mbox_nxp_s32_mru.c b/drivers/mbox/mbox_nxp_s32_mru.c index 4a3f8cdff219c..8fe64f789ea09 100644 --- a/drivers/mbox/mbox_nxp_s32_mru.c +++ b/drivers/mbox/mbox_nxp_s32_mru.c @@ -177,7 +177,7 @@ void nxp_s32_mru_isr(const struct device *dev) Mru_Ip_IrqHandler(config->hw_cfg.InstanceId, config->irq_group); } -static const struct mbox_driver_api nxp_s32_mru_driver_api = { +static DEVICE_API(mbox, nxp_s32_mru_driver_api) = { .send = nxp_s32_mru_send, .register_callback = nxp_s32_mru_register_callback, .mtu_get = nxp_s32_mru_mtu_get, diff --git a/drivers/mbox/mbox_stm32_hsem.c b/drivers/mbox/mbox_stm32_hsem.c index 3f416c2b85dac..9482fc02a1a51 100644 --- a/drivers/mbox/mbox_stm32_hsem.c +++ b/drivers/mbox/mbox_stm32_hsem.c @@ -241,7 +241,7 @@ static int mbox_stm32_hsem_init(const struct device *dev) return ret; } -static const struct mbox_driver_api mbox_stm32_hsem_driver_api = { +static DEVICE_API(mbox, mbox_stm32_hsem_driver_api) = { .send = mbox_stm32_hsem_send, .register_callback = mbox_stm32_hsem_register_callback, .mtu_get = mbox_stm32_hsem_mtu_get, diff --git a/drivers/mbox/mbox_ti_omap.c b/drivers/mbox/mbox_ti_omap.c new file mode 100644 index 0000000000000..847d9106282c6 --- /dev/null +++ b/drivers/mbox/mbox_ti_omap.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated. + * + * TI OMAP Mailbox driver for Zephyr's MBOX model. + */ + +#include +#include +#include +#include +#define LOG_LEVEL CONFIG_MBOX_LOG_LEVEL +#include +LOG_MODULE_REGISTER(ti_omap_mailbox); + +#define DT_DRV_COMPAT ti_omap_mailbox + +#define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m))) +#define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1)) +#define OMAP_MAILBOX_NUM_MSGS 16 +#define MAILBOX_MAX_CHANNELS 16 +#define OMAP_MAILBOX_NUM_USERS 4 +#define MAILBOX_MBOX_SIZE sizeof(uint32_t) + +#define DEV_CFG(_dev) ((const struct omap_mailbox_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct omap_mailbox_data *)(_dev)->data) +#define DEV_REG_BASE(dev) ((struct omap_mailbox_regs *)DEVICE_MMIO_NAMED_GET(dev, reg_base)) + +struct omap_mailbox_data { + DEVICE_MMIO_NAMED_RAM(reg_base); + mbox_callback_t cb[MAILBOX_MAX_CHANNELS]; + void *user_data[MAILBOX_MAX_CHANNELS]; + bool channel_enable[MAILBOX_MAX_CHANNELS]; + uint32_t received_data; + struct k_spinlock lock; +}; + +struct omap_mailbox_config { + DEVICE_MMIO_NAMED_ROM(reg_base); + uint32_t irq; + uint32_t usr_id; +}; + +struct omap_mailbox_irq_regs { + uint32_t status_raw; + uint32_t status_clear; + uint32_t enable_set; + uint32_t enable_clear; +}; + +struct omap_mailbox_regs { + uint32_t revision; + uint32_t __pad0[3]; + uint32_t sysconfig; + uint32_t __pad1[11]; + uint32_t message[OMAP_MAILBOX_NUM_MSGS]; + uint32_t fifo_status[OMAP_MAILBOX_NUM_MSGS]; + uint32_t msg_status[OMAP_MAILBOX_NUM_MSGS]; + struct omap_mailbox_irq_regs irq_regs[OMAP_MAILBOX_NUM_USERS]; +}; + +static void omap_mailbox_isr(const struct device *dev) +{ + volatile struct omap_mailbox_regs *regs = DEV_REG_BASE(dev); + const struct omap_mailbox_config *cfg = DEV_CFG(dev); + struct omap_mailbox_data *data = DEV_DATA(dev); + + uint32_t irq_enabled = regs->irq_regs[cfg->usr_id].enable_set; + uint32_t flags = regs->irq_regs[cfg->usr_id].status_clear; + + regs->irq_regs[cfg->usr_id].enable_set = 0; + + for (int i_channel = 0; i_channel < MAILBOX_MAX_CHANNELS; i_channel++) { + if (!data->channel_enable[i_channel]) { + continue; + } + + if ((flags & MAILBOX_IRQ_NEWMSG(i_channel))) { + data->received_data = regs->message[i_channel]; + struct mbox_msg msg = { + .data = (const void *)&data->received_data, + .size = MAILBOX_MBOX_SIZE, + }; + + if (data->cb[i_channel]) { + data->cb[i_channel](dev, i_channel, data->user_data[i_channel], + &msg); + } + } + } + + regs->irq_regs[cfg->usr_id].status_clear = flags; + regs->irq_regs[cfg->usr_id].enable_set = irq_enabled; +} + +static int omap_mailbox_send(const struct device *dev, uint32_t channel, const struct mbox_msg *msg) +{ + uint32_t __aligned(4) data32; + + volatile struct omap_mailbox_regs *regs = DEV_REG_BASE(dev); + struct omap_mailbox_data *data = DEV_DATA(dev); + k_spinlock_key_t key; + + if (channel >= MAILBOX_MAX_CHANNELS) { + return -EINVAL; + } + + if (regs->fifo_status[channel]) { + return -EBUSY; + } + + key = k_spin_lock(&data->lock); + if (!msg) { + regs->message[channel] = 0; + k_spin_unlock(&data->lock, key); + return 0; + } + + if (msg->size > MAILBOX_MBOX_SIZE) { + k_spin_unlock(&data->lock, key); + return -EMSGSIZE; + } + + memcpy(&data32, msg->data, msg->size); + regs->message[channel] = data32; + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int omap_mailbox_register_callback(const struct device *dev, uint32_t channel, + mbox_callback_t cb, void *user_data) +{ + struct omap_mailbox_data *data = DEV_DATA(dev); + k_spinlock_key_t key; + + if (channel >= MAILBOX_MAX_CHANNELS) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + data->cb[channel] = cb; + data->user_data[channel] = user_data; + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int omap_mailbox_mtu_get(const struct device *dev) +{ + ARG_UNUSED(dev); + + return MAILBOX_MBOX_SIZE; +} + +static uint32_t omap_mailbox_max_channels_get(const struct device *dev) +{ + ARG_UNUSED(dev); + + return MAILBOX_MAX_CHANNELS; +} + +static int omap_mailbox_set_enabled(const struct device *dev, uint32_t channel, bool enable) +{ + const struct omap_mailbox_config *cfg = DEV_CFG(dev); + struct omap_mailbox_data *data = DEV_DATA(dev); + volatile struct omap_mailbox_regs *regs; + k_spinlock_key_t key; + uint32_t irqstatus; + + if (channel >= MAILBOX_MAX_CHANNELS) { + return -EINVAL; + } + + if (enable && data->channel_enable[channel]) { + return -EALREADY; + } + + key = k_spin_lock(&data->lock); + regs = DEV_REG_BASE(dev); + irqstatus = regs->irq_regs[cfg->usr_id].enable_set; + + if (enable) { + irqstatus |= MAILBOX_IRQ_NEWMSG(channel); + } else { + irqstatus &= ~MAILBOX_IRQ_NEWMSG(channel); + } + + regs->irq_regs[cfg->usr_id].enable_set = irqstatus; + data->channel_enable[channel] = enable; + + if (enable) { + irq_enable(cfg->irq); + } else { + irq_disable(cfg->irq); + } + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static DEVICE_API(mbox, omap_mailbox_driver_api) = { + .send = omap_mailbox_send, + .register_callback = omap_mailbox_register_callback, + .mtu_get = omap_mailbox_mtu_get, + .max_channels_get = omap_mailbox_max_channels_get, + .set_enabled = omap_mailbox_set_enabled, +}; + +#define MAILBOX_INSTANCE_DEFINE(idx) \ + static struct omap_mailbox_data omap_mailbox_##idx##_data; \ + const static struct omap_mailbox_config omap_mailbox_##idx##_config = { \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(idx)), \ + .irq = DT_INST_IRQN(idx), \ + .usr_id = DT_INST_PROP(idx, usr_id), \ + }; \ + static int omap_mailbox_##idx##_init(const struct device *dev) \ + { \ + DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE); \ + IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority), omap_mailbox_isr, \ + DEVICE_DT_INST_GET(idx), \ + COND_CODE_1(DT_INST_IRQ_HAS_CELL(idx, flags), \ + (DT_INST_IRQ(idx, flags)), (0))); \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(idx, omap_mailbox_##idx##_init, NULL, &omap_mailbox_##idx##_data, \ + &omap_mailbox_##idx##_config, POST_KERNEL, \ + CONFIG_MBOX_INIT_PRIORITY, &omap_mailbox_driver_api) + +DT_INST_FOREACH_STATUS_OKAY(MAILBOX_INSTANCE_DEFINE) diff --git a/drivers/mdio/CMakeLists.txt b/drivers/mdio/CMakeLists.txt index 779ba7ed5ef30..9c1f1d47fe0ca 100644 --- a/drivers/mdio/CMakeLists.txt +++ b/drivers/mdio/CMakeLists.txt @@ -17,3 +17,5 @@ zephyr_library_sources_ifdef(CONFIG_MDIO_INFINEON_XMC4XXX mdio_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_MDIO_NXP_ENET_QOS mdio_nxp_enet_qos.c) zephyr_library_sources_ifdef(CONFIG_MDIO_DWCXGMAC mdio_dwcxgmac.c) zephyr_library_sources_ifdef(CONFIG_MDIO_RENESAS_RA mdio_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_MDIO_LAN865X mdio_lan865x.c) +zephyr_library_sources_ifdef(CONFIG_MDIO_SENSRY_SY1XX mdio_sy1xx.c) diff --git a/drivers/mdio/Kconfig b/drivers/mdio/Kconfig index 77dc4d3411171..dea9bea190976 100644 --- a/drivers/mdio/Kconfig +++ b/drivers/mdio/Kconfig @@ -38,6 +38,8 @@ source "drivers/mdio/Kconfig.xmc4xxx" source "drivers/mdio/Kconfig.nxp_enet_qos" source "drivers/mdio/Kconfig.dwcxgmac" source "drivers/mdio/Kconfig.renesas_ra" +source "drivers/mdio/Kconfig.lan865x" +source "drivers/mdio/Kconfig.sy1xx" config MDIO_INIT_PRIORITY int "Init priority" diff --git a/drivers/mdio/Kconfig.lan865x b/drivers/mdio/Kconfig.lan865x new file mode 100644 index 0000000000000..8cf7f0c0e8394 --- /dev/null +++ b/drivers/mdio/Kconfig.lan865x @@ -0,0 +1,20 @@ +# Copyright 2024 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +menuconfig MDIO_LAN865X + bool "LAN865X MDIO driver" + default y + depends on DT_HAS_MICROCHIP_LAN865X_MDIO_ENABLED + depends on ETH_LAN865X + help + Enable LAN865X MDIO driver. + +if MDIO_LAN865X + +config MDIO_LAN865X_INIT_PRIORITY + int "LAN865X MDIO init priority" + default 81 + help + LAN865X MDIO device driver initialization priority. + +endif diff --git a/drivers/mdio/Kconfig.sy1xx b/drivers/mdio/Kconfig.sy1xx new file mode 100644 index 0000000000000..be2b4105c2543 --- /dev/null +++ b/drivers/mdio/Kconfig.sy1xx @@ -0,0 +1,10 @@ +# Copyright (c) 2024 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +config MDIO_SENSRY_SY1XX + bool "Sensry SY1XX MDIO driver" + select PINCTRL + depends on DT_HAS_SENSRY_SY1XX_MDIO_ENABLED + default y + help + Enable Sensry SY1xx SOC Family MDIO driver. diff --git a/drivers/mdio/mdio_lan865x.c b/drivers/mdio/mdio_lan865x.c new file mode 100644 index 0000000000000..dc46100ce89f8 --- /dev/null +++ b/drivers/mdio/mdio_lan865x.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(mdio_lan865x, CONFIG_MDIO_LOG_LEVEL); + +#define DT_DRV_COMPAT microchip_lan865x_mdio + +#include +#include +#include +#include +#include +#include + +struct mdio_lan865x_config { + const struct device *dev; +}; + +static void lan865x_mdio_bus_enable(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +static void lan865x_mdio_bus_disable(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +static int lan865x_mdio_c22_read(const struct device *dev, uint8_t prtad, uint8_t regad, + uint16_t *data) +{ + const struct mdio_lan865x_config *const cfg = dev->config; + + return eth_lan865x_mdio_c22_read(cfg->dev, prtad, regad, data); +} + +static int lan865x_mdio_c22_write(const struct device *dev, uint8_t prtad, uint8_t regad, + uint16_t data) +{ + const struct mdio_lan865x_config *const cfg = dev->config; + + return eth_lan865x_mdio_c22_write(cfg->dev, prtad, regad, data); +} + +static int lan865x_mdio_c45_read(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t *data) +{ + const struct mdio_lan865x_config *const cfg = dev->config; + + return eth_lan865x_mdio_c45_read(cfg->dev, prtad, devad, regad, data); +} + +static int lan865x_mdio_c45_write(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t data) +{ + const struct mdio_lan865x_config *const cfg = dev->config; + + return eth_lan865x_mdio_c45_write(cfg->dev, prtad, devad, regad, data); +} + +static DEVICE_API(mdio, mdio_lan865x_api) = { + .read = lan865x_mdio_c22_read, + .write = lan865x_mdio_c22_write, + .read_c45 = lan865x_mdio_c45_read, + .write_c45 = lan865x_mdio_c45_write, + .bus_enable = lan865x_mdio_bus_enable, + .bus_disable = lan865x_mdio_bus_disable, +}; + +#define MICROCHIP_LAN865X_MDIO_INIT(n) \ + static const struct mdio_lan865x_config mdio_lan865x_config_##n = { \ + .dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + }; \ + DEVICE_DT_INST_DEFINE(n, NULL, NULL, NULL, &mdio_lan865x_config_##n, POST_KERNEL, \ + CONFIG_MDIO_LAN865X_INIT_PRIORITY, &mdio_lan865x_api); + +DT_INST_FOREACH_STATUS_OKAY(MICROCHIP_LAN865X_MDIO_INIT) diff --git a/drivers/mdio/mdio_shell.c b/drivers/mdio/mdio_shell.c index 856005bc4e192..e3366f4299332 100644 --- a/drivers/mdio/mdio_shell.c +++ b/drivers/mdio/mdio_shell.c @@ -43,6 +43,8 @@ LOG_MODULE_REGISTER(mdio_shell, CONFIG_LOG_DEFAULT_LEVEL); #define DT_DRV_COMPAT st_stm32_mdio #elif DT_HAS_COMPAT_STATUS_OKAY(snps_dwcxgmac_mdio) #define DT_DRV_COMPAT snps_dwcxgmac_mdio +#elif DT_HAS_COMPAT_STATUS_OKAY(sensry_sy1xx_mdio) +#define DT_DRV_COMPAT sensry_sy1xx_mdio #else #error "No known devicetree compatible match for MDIO shell" #endif diff --git a/drivers/mdio/mdio_sy1xx.c b/drivers/mdio/mdio_sy1xx.c new file mode 100644 index 0000000000000..21be9c148dbb4 --- /dev/null +++ b/drivers/mdio/mdio_sy1xx.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2024 sensry.io + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sensry_sy1xx_mdio + +#include +LOG_MODULE_REGISTER(sy1xx_mdio, CONFIG_MDIO_LOG_LEVEL); + +#include +#include +#include +#include + +struct sy1xx_mdio_dev_config { + const struct pinctrl_dev_config *pcfg; + uint32_t base_addr; + uint32_t mdc_freq; +}; + +struct sy1xx_mdio_dev_data { + struct k_sem sem; +}; + +/* mdio register offsets */ +#define SY1XX_MDIO_CFG_REG 0x0000 +#define SY1XX_MDIO_CTRL_REG 0x0004 +#define SY1XX_MDIO_READ_DATA_REG 0x0008 +#define SY1XX_MDIO_WRITE_DATA_REG 0x000c +#define SY1XX_MDIO_IRQ_REG 0x0010 + +/* mdio config register bit offsets */ +#define SY1XX_MDIO_CFG_DIV_OFFS (0) +#define SY1XX_MDIO_CFG_EN_OFFS (8) + +/* mdio ctrl register bit offsets */ +#define SY1XX_MDIO_CTRL_READY_OFFS (0) +#define SY1XX_MDIO_CTRL_INIT_OFFS (8) +#define SY1XX_MDIO_CTRL_REG_ADDR_OFFS (16) +#define SY1XX_MDIO_CTRL_PHY_ADDR_OFFS (24) +#define SY1XX_MDIO_CTRL_OP_OFFS (30) + +/* mdio ctrl operations */ +#define SY1XX_MDIO_CTRL_OP_WRITE (0x1) +#define SY1XX_MDIO_CTRL_OP_READ (0x2) + +#define SY1XX_MDIO_READ_WRITE_WAIT_TIME_US (15) +#define SY1XX_MDIO_READ_WRITE_RETRY_COUNT (5) + +static int sy1xx_mdio_wait_for_ready(const struct device *dev); + +static int sy1xx_mdio_initialize(const struct device *dev) +{ + + struct sy1xx_mdio_dev_config *cfg = (struct sy1xx_mdio_dev_config *)dev->config; + int ret; + uint32_t divider; + uint32_t reg; + + /* zero mdio controller regs */ + sys_write32(0x0, cfg->base_addr + SY1XX_MDIO_CFG_REG); + sys_write32(0x0, cfg->base_addr + SY1XX_MDIO_CTRL_REG); + sys_write32(0x0, cfg->base_addr + SY1XX_MDIO_READ_DATA_REG); + sys_write32(0x0, cfg->base_addr + SY1XX_MDIO_WRITE_DATA_REG); + sys_write32(0x0, cfg->base_addr + SY1XX_MDIO_IRQ_REG); + + /* prepare mdio clock and enable mdio controller */ + divider = (((sy1xx_soc_get_peripheral_clock() / cfg->mdc_freq) / 2) - 1) & 0xff; + reg = (divider << SY1XX_MDIO_CFG_DIV_OFFS) | BIT(SY1XX_MDIO_CFG_EN_OFFS); + + LOG_DBG("config, div: %d, freq: %d", divider, cfg->mdc_freq); + + sys_write32(reg, cfg->base_addr + SY1XX_MDIO_CFG_REG); + + /* PAD config */ + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("failed to configure pins"); + return ret; + } + + ret = sy1xx_mdio_wait_for_ready(dev); + if (ret < 0) { + LOG_ERR("not ready"); + return ret; + } + + return 0; +} + +static uint32_t sy1xx_mdio_is_ready(const struct device *dev) +{ + struct sy1xx_mdio_dev_config *cfg = (struct sy1xx_mdio_dev_config *)dev->config; + uint32_t status = sys_read32(cfg->base_addr + SY1XX_MDIO_CTRL_REG); + + return (status & BIT(SY1XX_MDIO_CTRL_READY_OFFS)); +} + +static int sy1xx_mdio_wait_for_ready(const struct device *dev) +{ + uint32_t retries_left = SY1XX_MDIO_READ_WRITE_RETRY_COUNT; + + while (!sy1xx_mdio_is_ready(dev)) { + k_sleep(K_USEC(SY1XX_MDIO_READ_WRITE_WAIT_TIME_US)); + retries_left--; + if (!retries_left) { + return -EINVAL; + } + } + return 0; +} + +static int sy1xx_mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data) +{ + struct sy1xx_mdio_dev_config *cfg = (struct sy1xx_mdio_dev_config *)dev->config; + int ret; + uint32_t v; + + prtad &= 0x1f; + regad &= 0x1f; + + v = (SY1XX_MDIO_CTRL_OP_READ << SY1XX_MDIO_CTRL_OP_OFFS) | + (prtad << SY1XX_MDIO_CTRL_PHY_ADDR_OFFS) | (regad << SY1XX_MDIO_CTRL_REG_ADDR_OFFS) | + BIT(SY1XX_MDIO_CTRL_INIT_OFFS); + + /* start the reading procedure */ + sys_write32(v, cfg->base_addr + SY1XX_MDIO_CTRL_REG); + + /* wait for the reading operation to finish */ + ret = sy1xx_mdio_wait_for_ready(dev); + if (ret < 0) { + *data = sys_read32(cfg->base_addr + SY1XX_MDIO_READ_DATA_REG); + + LOG_WRN("timeout while reading from phy: %d, reg: %d, val: %d", prtad, regad, + *data); + return ret; + } + + /* get the data from the read result register */ + *data = sys_read32(cfg->base_addr + SY1XX_MDIO_READ_DATA_REG); + + return 0; +} + +static int sy1xx_mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data) +{ + struct sy1xx_mdio_dev_config *cfg = (struct sy1xx_mdio_dev_config *)dev->config; + int ret; + uint32_t v; + + prtad &= 0x1f; + regad &= 0x1f; + + /* put the data to the write register */ + sys_write32(data, cfg->base_addr + SY1XX_MDIO_WRITE_DATA_REG); + + v = (SY1XX_MDIO_CTRL_OP_WRITE << SY1XX_MDIO_CTRL_OP_OFFS) | + (prtad << SY1XX_MDIO_CTRL_PHY_ADDR_OFFS) | (regad << SY1XX_MDIO_CTRL_REG_ADDR_OFFS) | + BIT(SY1XX_MDIO_CTRL_INIT_OFFS); + + /* start the writing procedure */ + sys_write32(v, cfg->base_addr + SY1XX_MDIO_CTRL_REG); + + /* wait for the writing operation to finish */ + ret = sy1xx_mdio_wait_for_ready(dev); + if (ret < 0) { + LOG_WRN("timeout while writing to phy: %d, reg: %d, val: %d", prtad, regad, data); + return ret; + } + + return 0; +} + +static DEVICE_API(mdio, sy1xx_mdio_driver_api) = { + .read = sy1xx_mdio_read, + .write = sy1xx_mdio_write, +}; + +#define SY1XX_MDIO_INIT(n) \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static const struct sy1xx_mdio_dev_config sy1xx_mdio_dev_config_##n = { \ + .base_addr = DT_INST_REG_ADDR(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .mdc_freq = DT_INST_PROP(n, clock_frequency), \ + }; \ + \ + static struct sy1xx_mdio_dev_data sy1xx_mdio_dev_data##n; \ + \ + DEVICE_DT_INST_DEFINE(n, &sy1xx_mdio_initialize, NULL, &sy1xx_mdio_dev_data##n, \ + &sy1xx_mdio_dev_config_##n, POST_KERNEL, CONFIG_MDIO_INIT_PRIORITY, \ + &sy1xx_mdio_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SY1XX_MDIO_INIT) diff --git a/drivers/memc/CMakeLists.txt b/drivers/memc/CMakeLists.txt index 5cfb571c34233..fcdc5f06e4556 100644 --- a/drivers/memc/CMakeLists.txt +++ b/drivers/memc/CMakeLists.txt @@ -14,6 +14,7 @@ zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_APS6408L memc_mcux_flexspi zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_APS6404L memc_mcux_flexspi_aps6404l.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_IS66WVQ8M4 memc_mcux_flexspi_is66wvq8m4.c) zephyr_library_sources_ifdef(CONFIG_MEMC_NXP_FLEXRAM memc_nxp_flexram.c) +zephyr_library_sources_ifdef(CONFIG_MEMC_RENESAS_RA_SDRAM memc_renesas_ra_sdram.c) zephyr_library_sources_ifdef(CONFIG_MEMC_SAM_SMC memc_sam_smc.c) diff --git a/drivers/memc/Kconfig b/drivers/memc/Kconfig index 966b7ecb63494..ce0eac6043064 100644 --- a/drivers/memc/Kconfig +++ b/drivers/memc/Kconfig @@ -32,6 +32,8 @@ source "drivers/memc/Kconfig.smartbond" source "drivers/memc/Kconfig.mspi" +source "drivers/memc/Kconfig.renesas_ra" + module = MEMC module-str = memc source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/memc/Kconfig.renesas_ra b/drivers/memc/Kconfig.renesas_ra new file mode 100644 index 0000000000000..a05910c72d49a --- /dev/null +++ b/drivers/memc/Kconfig.renesas_ra @@ -0,0 +1,12 @@ +# Renesas RA Family + +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config MEMC_RENESAS_RA_SDRAM + bool "Renesas RA sdram controller" + default y + depends on DT_HAS_RENESAS_RA_SDRAM_ENABLED + select USE_RA_FSP_SDRAM + help + Enable Renesas RA sdram controller diff --git a/drivers/memc/memc_nxp_s32_qspi.c b/drivers/memc/memc_nxp_s32_qspi.c index e1d5c60bd67d7..0eeef1e057229 100644 --- a/drivers/memc/memc_nxp_s32_qspi.c +++ b/drivers/memc/memc_nxp_s32_qspi.c @@ -11,6 +11,7 @@ LOG_MODULE_REGISTER(nxp_s32_qspi_memc, CONFIG_MEMC_LOG_LEVEL); #include #include +#include #include #include "memc_nxp_s32_qspi.h" @@ -138,7 +139,7 @@ uint8_t memc_nxp_s32_qspi_get_instance(const struct device *dev) )) #define QSPI_PORT_SIZE_FN(node_id, side_upper, port) \ - COND_CODE_1(IS_EQ(DT_REG_ADDR(node_id), QSPI_PCSF##side_upper##port), \ + COND_CODE_1(IS_EQ(DT_REG_ADDR_RAW(node_id), QSPI_PCSF##side_upper##port), \ (COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(node_id), \ (.memSize##side_upper##port = DT_PROP(node_id, size) / 8,), \ (.memSize##side_upper##port = 0,))), \ @@ -154,6 +155,81 @@ uint8_t memc_nxp_s32_qspi_get_instance(const struct device *dev) QSPI_PORT_SIZE(n, side_upper) \ .readMode##side_upper = QSPI_READ_MODE(n, side, side_upper), +#if FEATURE_QSPI_HAS_SFP + +#if QSPI_IP_SFP_ENABLE_MDAD +#define SFP_MDAD_NODE(n) DT_INST_CHILD(n, sfp_mdad) + +#define QSPI_SECURE_ATTRIBUTE(node_id) \ + (DT_PROP(node_id, secure_attribute) == NXP_S32_QSPI_NON_SECURE ? QSPI_IP_SFP_UNSECURE : \ + (DT_PROP(node_id, secure_attribute) == NXP_S32_QSPI_SECURE ? QSPI_IP_SFP_SECURE : \ + (DT_PROP(node_id, secure_attribute) == (NXP_S32_QSPI_NON_SECURE | NXP_S32_QSPI_SECURE) ?\ + QSPI_IP_SFP_BOTH : \ + QSPI_IP_SFP_RESERVED))) + +#define _QSPI_SFP_MDAD_CFG(node_id, n) \ + { \ + .SecureAttribute = QSPI_SECURE_ATTRIBUTE(node_id), \ + .MaskType = DT_ENUM_IDX(node_id, mask_type), \ + .Valid = true, \ + .Mask = DT_PROP(node_id, mask), \ + .DomainId = DT_PROP(node_id, domain_id), \ + }, + +#define QSPI_SFP_MDAD_CFG(n) \ + .Tg = { \ + DT_FOREACH_CHILD_STATUS_OKAY_VARGS(SFP_MDAD_NODE(n), _QSPI_SFP_MDAD_CFG, n)\ + }, +#endif /* QSPI_IP_SFP_ENABLE_MDAD */ + +#if QSPI_IP_SFP_ENABLE_FRAD +#define SFP_FRAD_NODE(n) DT_INST_CHILD(n, sfp_frad) + +#define QSPI_ACP_POLICY(node_id) \ + (DT_PROP(node_id, master_domain_acp_policy) == NXP_S32_QSPI_SECURE ? \ + QSPI_IP_SFP_ACP_SECURE :\ + (DT_PROP(node_id, master_domain_acp_policy) == (NXP_S32_QSPI_NON_SECURE | \ + NXP_S32_QSPI_PRIVILEGE) ? QSPI_IP_SFP_ACP_PRIVILEGED : \ + (DT_PROP(node_id, master_domain_acp_policy) == (NXP_S32_QSPI_SECURE | \ + NXP_S32_QSPI_PRIVILEGE) ? QSPI_IP_SFP_ACP_SECURE_PRIVILEGED :\ + (DT_PROP(node_id, master_domain_acp_policy) == (NXP_S32_QSPI_NON_SECURE | \ + NXP_S32_QSPI_SECURE | NXP_S32_QSPI_PRIVILEGE) ? QSPI_IP_SFP_ACP_ALL : \ + QSPI_IP_SFP_ACP_NONE)))) + +#define QSPI_EXCLUSIVE_ACCESS_LOCK(node_id) \ + (DT_ENUM_IDX(node_id, exclusive_access_lock) == 0 ? QSPI_IP_SFP_EAL_DISABLED : \ + (DT_ENUM_IDX(node_id, exclusive_access_lock) == 1 ? QSPI_IP_SFP_EAL_OWNER : \ + QSPI_IP_SFP_EAL_NONE)) + +#define _QSPI_SFP_FRAD_CFG(node_id, n) \ + { \ + .StartAddress = DT_REG_ADDR(node_id), \ + .EndAddress = DT_REG_ADDR(node_id) + DT_REG_SIZE(node_id) - 1, \ + .Valid = true, \ + .Md0Acp = QSPI_ACP_POLICY(node_id), \ + .Md1Acp = QSPI_ACP_POLICY(node_id), \ + .ExclusiveAccessLock = QSPI_EXCLUSIVE_ACCESS_LOCK(node_id), \ + .ExclusiveAccessOwner = DT_PROP(node_id, exclusive_access_owner), \ + }, + +#define QSPI_SFP_FRAD_CFG(n) \ + .Frad = { \ + DT_FOREACH_CHILD_STATUS_OKAY_VARGS(SFP_FRAD_NODE(n), _QSPI_SFP_FRAD_CFG, n)\ + }, +#endif /* QSPI_IP_SFP_ENABLE_FRAD */ + +#define QSPI_SFP_MASTER_TIMEOUT_CYCLES 0xffff + +#define QSPI_SFP_CFG(n) \ + IF_ENABLED(QSPI_IP_SFP_ENABLE_GLOBAL, \ + (.SfpCfg = { \ + .MasterTimeout = QSPI_SFP_MASTER_TIMEOUT_CYCLES, \ + IF_ENABLED(QSPI_IP_SFP_ENABLE_MDAD, (QSPI_SFP_MDAD_CFG(n))) \ + IF_ENABLED(QSPI_IP_SFP_ENABLE_FRAD, (QSPI_SFP_FRAD_CFG(n))) \ + },)) + +#endif /* FEATURE_QSPI_HAS_SFP */ + #define MEMC_NXP_S32_QSPI_CONTROLLER_CONFIG(n) \ BUILD_ASSERT(DT_INST_PROP_LEN(n, ahb_buffers_masters) == QSPI_IP_AHB_BUFFERS, \ "ahb-buffers-masters must be of size QSPI_IP_AHB_BUFFERS"); \ @@ -174,6 +250,7 @@ uint8_t memc_nxp_s32_qspi_get_instance(const struct device *dev) QSPI_DATA_CFG(n) \ QSPI_ADDR_CFG(n) \ QSPI_BYTES_SWAP_ADDR(n) \ + IF_ENABLED(FEATURE_QSPI_HAS_SFP, (QSPI_SFP_CFG(n))) \ } #define MEMC_NXP_S32_QSPI_INIT_DEVICE(n) \ diff --git a/drivers/memc/memc_renesas_ra_sdram.c b/drivers/memc/memc_renesas_ra_sdram.c new file mode 100644 index 0000000000000..0c5343f73f1a8 --- /dev/null +++ b/drivers/memc/memc_renesas_ra_sdram.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_sdram + +#include +#include +#include + +LOG_MODULE_REGISTER(memc_renesas_ra_sdram, CONFIG_MEMC_LOG_LEVEL); + +struct memc_renesas_ra_sdram_config { + const struct pinctrl_dev_config *pincfg; +}; + +static int renesas_ra_sdram_init(const struct device *dev) +{ + const struct memc_renesas_ra_sdram_config *config = dev->config; + int err; + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + LOG_ERR("pin function initial failed"); + return err; + } + + R_BSP_SdramInit(true); + + return 0; +} + +PINCTRL_DT_INST_DEFINE(0); +static const struct memc_renesas_ra_sdram_config config = { + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), +}; + +DEVICE_DT_INST_DEFINE(0, renesas_ra_sdram_init, NULL, NULL, &config, POST_KERNEL, + CONFIG_MEMC_INIT_PRIORITY, NULL); diff --git a/drivers/mfd/CMakeLists.txt b/drivers/mfd/CMakeLists.txt index e422fc9ee4c0a..4bbb7eb637cbc 100644 --- a/drivers/mfd/CMakeLists.txt +++ b/drivers/mfd/CMakeLists.txt @@ -20,3 +20,6 @@ zephyr_library_sources_ifdef(CONFIG_MFD_TLE9104 mfd_tle9104.c) zephyr_library_sources_ifdef(CONFIG_MFD_ITE_IT8801 mfd_ite_it8801.c) zephyr_library_sources_ifdef(CONFIG_MFD_ITE_IT8801_ALTCTRL mfd_it8801_altctrl.c) zephyr_library_sources_ifdef(CONFIG_MFD_AW9523B mfd_aw9523b.c) +zephyr_library_sources_ifdef(CONFIG_MFD_DS3231 mfd_ds3231.c) +zephyr_library_sources_ifdef(CONFIG_MFD_MAX22017 mfd_max22017.c) +zephyr_library_sources_ifdef(CONFIG_MFD_PF1550 mfd_pf1550.c) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 34d9f595b780e..ed3af13ddd7d8 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -23,12 +23,15 @@ source "drivers/mfd/Kconfig.adp5585" source "drivers/mfd/Kconfig.axp192" source "drivers/mfd/Kconfig.aw9523b" source "drivers/mfd/Kconfig.bd8lb600fs" +source "drivers/mfd/Kconfig.ds3231" source "drivers/mfd/Kconfig.max20335" +source "drivers/mfd/Kconfig.max22017" source "drivers/mfd/Kconfig.max31790" source "drivers/mfd/Kconfig.nct38xx" source "drivers/mfd/Kconfig.npm1300" source "drivers/mfd/Kconfig.npm2100" source "drivers/mfd/Kconfig.npm6001" +source "drivers/mfd/Kconfig.pf1550" source "drivers/mfd/Kconfig.lpflexcomm" source "drivers/mfd/Kconfig.tle9104" source "drivers/mfd/Kconfig.it8801" diff --git a/drivers/mfd/Kconfig.ds3231 b/drivers/mfd/Kconfig.ds3231 new file mode 100644 index 0000000000000..2fad980580d9b --- /dev/null +++ b/drivers/mfd/Kconfig.ds3231 @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Gergo Vari +# SPDX-License-Identifier: Apache-2.0 + +config MFD_DS3231 + bool "DS3231 multi-function device driver" + default y + depends on DT_HAS_MAXIM_DS3231_MFD_ENABLED + select I2C + help + Enable the Maxim DS3231 multi-function device driver diff --git a/drivers/mfd/Kconfig.max22017 b/drivers/mfd/Kconfig.max22017 new file mode 100644 index 0000000000000..8a28f19614e43 --- /dev/null +++ b/drivers/mfd/Kconfig.max22017 @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +config MFD_MAX22017 + bool "Analog Devices MAX22017 DAC/GPIO chip" + default y + depends on SPI + select CRC + depends on DT_HAS_ADI_MAX22017_ENABLED + help + Enable the driver for the Analog Devices MAX22017 DAC/GPIO chip diff --git a/drivers/mfd/Kconfig.pf1550 b/drivers/mfd/Kconfig.pf1550 new file mode 100644 index 0000000000000..127bcbabe0b52 --- /dev/null +++ b/drivers/mfd/Kconfig.pf1550 @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +config MFD_PF1550 + bool "PF1550 PMIC multi-function device driver" + default y + depends on DT_HAS_NXP_PF1550_ENABLED + select I2C + help + Enable the NXP PF1550 PMIC multi-function device driver diff --git a/drivers/mfd/mfd_adp5585.c b/drivers/mfd/mfd_adp5585.c index d57b82035dca4..61d0e386e4cc3 100644 --- a/drivers/mfd/mfd_adp5585.c +++ b/drivers/mfd/mfd_adp5585.c @@ -56,9 +56,8 @@ static void mfd_adp5585_work_handler(struct k_work *work) k_sem_take(&data->lock, K_FOREVER); /* Read Interrput Flag */ - if (ret == 0) { - ret = i2c_reg_read_byte_dt(&config->i2c_bus, ADP5585_INT_STATUS, ®_int_status); - } + ret = i2c_reg_read_byte_dt(&config->i2c_bus, ADP5585_INT_STATUS, ®_int_status); + /* Clear Interrput Flag */ if (ret == 0) { ret = i2c_reg_write_byte_dt(&config->i2c_bus, ADP5585_INT_STATUS, reg_int_status); diff --git a/drivers/mfd/mfd_ds3231.c b/drivers/mfd/mfd_ds3231.c new file mode 100644 index 0000000000000..22728029dd643 --- /dev/null +++ b/drivers/mfd/mfd_ds3231.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 Gergo Vari + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +#include + +#include +LOG_MODULE_REGISTER(mfd_ds3231, CONFIG_MFD_LOG_LEVEL); + +#define DT_DRV_COMPAT maxim_ds3231_mfd + +struct mfd_ds3231_data { + struct k_sem lock; + const struct device *dev; +}; + +struct mfd_ds3231_conf { + struct i2c_dt_spec i2c_bus; +}; + +int mfd_ds3231_i2c_get_registers(const struct device *dev, uint8_t start_reg, uint8_t *buf, + const size_t buf_size) +{ + struct mfd_ds3231_data *data = dev->data; + const struct mfd_ds3231_conf *config = dev->config; + + /* FIXME: bad start_reg/buf_size values break i2c for that run */ + + (void)k_sem_take(&data->lock, K_FOREVER); + int err = i2c_burst_read_dt(&config->i2c_bus, start_reg, buf, buf_size); + + k_sem_give(&data->lock); + + return err; +} + +int mfd_ds3231_i2c_set_registers(const struct device *dev, uint8_t start_reg, const uint8_t *buf, + const size_t buf_size) +{ + struct mfd_ds3231_data *data = dev->data; + const struct mfd_ds3231_conf *config = dev->config; + + (void)k_sem_take(&data->lock, K_FOREVER); + int err = i2c_burst_write_dt(&config->i2c_bus, start_reg, buf, buf_size); + + k_sem_give(&data->lock); + + return err; +} + +static int mfd_ds3231_init(const struct device *dev) +{ + struct mfd_ds3231_data *data = dev->data; + const struct mfd_ds3231_conf *config = (struct mfd_ds3231_conf *)(dev->config); + + k_sem_init(&data->lock, 1, 1); + if (!i2c_is_ready_dt(&(config->i2c_bus))) { + LOG_ERR("I2C bus not ready."); + return -ENODEV; + } + return 0; +} + +#define MFD_DS3231_DEFINE(inst) \ + static const struct mfd_ds3231_conf config##inst = {.i2c_bus = \ + I2C_DT_SPEC_INST_GET(inst)}; \ + static struct mfd_ds3231_data data##inst; \ + DEVICE_DT_INST_DEFINE(inst, &mfd_ds3231_init, NULL, &data##inst, &config##inst, \ + POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(MFD_DS3231_DEFINE) diff --git a/drivers/mfd/mfd_max22017.c b/drivers/mfd/mfd_max22017.c new file mode 100644 index 0000000000000..a4b7d6fa1557c --- /dev/null +++ b/drivers/mfd/mfd_max22017.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max22017 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(mfd_max22017, CONFIG_MFD_LOG_LEVEL); + +#include + +struct max22017_config { + struct spi_dt_spec spi; + const struct gpio_dt_spec gpio_reset; + const struct gpio_dt_spec gpio_int; + bool crc_mode; +}; + +int max22017_reg_read(const struct device *dev, uint8_t addr, uint16_t *value) +{ + int ret; + const struct max22017_config *config = dev->config; + const struct max22017_data *data = dev->data; + uint8_t rxbuffer[4] = {0}; + size_t recv_len = 3; + + *value = 0; + addr = FIELD_PREP(MAX22017_SPI_TRANS_ADDR, addr) | FIELD_PREP(MAX22017_SPI_TRANS_DIR, 1); + + if (data->crc_enabled) { + recv_len += 1; + } + + const struct spi_buf txb[] = { + { + .buf = &addr, + .len = 1, + }, + }; + const struct spi_buf rxb[] = { + { + .buf = rxbuffer, + .len = recv_len, + }, + }; + + struct spi_buf_set tx = { + .buffers = txb, + .count = ARRAY_SIZE(txb), + }; + + struct spi_buf_set rx = { + .buffers = rxb, + .count = ARRAY_SIZE(rxb), + }; + + ret = spi_transceive_dt(&config->spi, &tx, &rx); + + if (ret) { + return ret; + } + + if (!data->crc_enabled) { + goto out_skip_crc; + } + + uint8_t crc_in[] = {addr, rxbuffer[1], rxbuffer[2]}; + + ret = crc8(crc_in, 3, MAX22017_CRC_POLY, 0, true); + + if (ret != rxbuffer[3]) { + LOG_ERR("Reg read: CRC Mismatch calculated / read: %x / %x", ret, rxbuffer[3]); + return -EINVAL; + } + +out_skip_crc: + *value = rxbuffer[1] | rxbuffer[2] << 8; + *value = sys_be16_to_cpu(*value); + + return 0; +} + +int max22017_reg_write(const struct device *dev, uint8_t addr, uint16_t value) +{ + uint8_t crc; + size_t crc_len = 0; + const struct max22017_config *config = dev->config; + const struct max22017_data *data = dev->data; + + addr = FIELD_PREP(MAX22017_SPI_TRANS_ADDR, addr) | FIELD_PREP(MAX22017_SPI_TRANS_DIR, 0); + value = sys_cpu_to_be16(value); + + if (data->crc_enabled) { + uint8_t crc_in[] = {addr, ((uint8_t *)&value)[0], ((uint8_t *)&value)[1]}; + + crc_len = 1; + crc = crc8(crc_in, 3, MAX22017_CRC_POLY, 0, true); + } + + const struct spi_buf buf[] = { + { + .buf = &addr, + .len = 1, + }, + { + .buf = &value, + .len = 2, + }, + { + .buf = &crc, + .len = crc_len, + }, + }; + + struct spi_buf_set tx = { + .buffers = buf, + .count = ARRAY_SIZE(buf), + }; + + return spi_write_dt(&config->spi, &tx); +} + +static int max22017_reset(const struct device *dev) +{ + int ret = 0; + uint16_t ao_sta; + const struct max22017_config *config = dev->config; + + if (config->gpio_reset.port != NULL) { + ret = gpio_pin_set_dt(&config->gpio_reset, 0); + if (ret) { + return ret; + } + k_sleep(K_MSEC(100)); + ret = gpio_pin_set_dt(&config->gpio_reset, 1); + k_sleep(K_MSEC(500)); + } else { + ret = max22017_reg_write(dev, MAX22017_GEN_RST_CTRL_OFF, + FIELD_PREP(MAX22017_GEN_RST_CTRL_GEN_RST, 1)); + if (ret) { + return ret; + } + k_sleep(K_MSEC(100)); + ret = max22017_reg_write(dev, MAX22017_GEN_RST_CTRL_OFF, + FIELD_PREP(MAX22017_GEN_RST_CTRL_GEN_RST, 0)); + if (ret) { + return ret; + } + k_sleep(K_MSEC(500)); + ret = max22017_reg_read(dev, MAX22017_AO_STA_OFF, &ao_sta); + if (ret) { + return ret; + } + if (FIELD_GET(MAX22017_AO_STA_BUSY_STA, ao_sta)) { + ret = -EBUSY; + } + } + return ret; +} + +static void max22017_isr(const struct device *dev, struct gpio_callback *gpio_cb, uint32_t pins) +{ + struct max22017_data *data = CONTAINER_OF(gpio_cb, struct max22017_data, callback_int); + int ret; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = k_work_submit(&data->int_work); + if (ret < 0) { + LOG_WRN("Could not submit int work: %d", ret); + } + + k_mutex_unlock(&data->lock); +} + +static void max22017_int_worker(struct k_work *work) +{ + struct max22017_data *data = CONTAINER_OF(work, struct max22017_data, int_work); + const struct device *dev = data->dev; + int ret; + uint16_t gen_int; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(dev, MAX22017_GEN_INT_OFF, &gen_int); + if (ret) { + LOG_ERR("Unable to read GEN_INT register"); + goto fail; + } + + if (FIELD_GET(MAX22017_GEN_INT_FAIL_INT, gen_int)) { + LOG_ERR("Boot failure"); + } + + ret = FIELD_GET(MAX22017_GEN_INT_CONV_OVF_INT, gen_int); + if (ret) { + LOG_ERR("Conversion failure on channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + ret = FIELD_GET(MAX22017_GEN_INT_OPENWIRE_DTCT_INT, gen_int); + if (ret) { + LOG_ERR("Openwire detected on channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + if (FIELD_GET(MAX22017_GEN_INT_HVDD_INT, gen_int)) { + LOG_ERR("HVDD/HVSS voltage difference below 1.5V"); + } + + if (FIELD_GET(MAX22017_GEN_INT_TMOUT_INT, gen_int)) { + LOG_ERR("SPI transaction timeout"); + } + + ret = FIELD_GET(MAX22017_GEN_INT_THSHDN_INT, gen_int); + if (ret) { + LOG_ERR("Thermal shutdown AO channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + ret = FIELD_GET(MAX22017_GEN_INT_THWRNG_INT, gen_int); + if (ret) { + LOG_ERR("Thermal warning AO channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + ret = FIELD_GET(MAX22017_GEN_INT_OVC_INT, gen_int); + if (ret) { + LOG_ERR("Over current on channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + if (FIELD_GET(MAX22017_GEN_INT_CRC_INT, gen_int)) { + LOG_ERR("CRC Error"); + } + + ret = FIELD_GET(MAX22017_GEN_INT_GPI_INT, gen_int); + if (ret) { + LOG_INF("GPI Interrupt: %d", ret); +#ifdef CONFIG_GPIO_MAX22017 + uint16_t gpi_sta, lsb; + + ret = max22017_reg_read(dev, MAX22017_GEN_GPI_INT_STA_OFF, &gpi_sta); + if (ret) { + goto fail; + } + + /* Aggregate both positive and negative edge together */ + gpi_sta = FIELD_GET(MAX22017_GEN_GPI_INT_GPI_NEG_EDGE_INT, gpi_sta) | + FIELD_GET(MAX22017_GEN_GPI_INT_GPI_POS_EDGE_INT, gpi_sta); + while (gpi_sta) { + lsb = LSB_GET(gpi_sta); + gpio_fire_callbacks(&data->callbacks_gpi, dev, lsb); + gpi_sta &= ~lsb; + } +#endif + } +fail: + k_mutex_unlock(&data->lock); +} + +static int max22017_init(const struct device *dev) +{ + const struct max22017_config *config = dev->config; + struct max22017_data *data = dev->data; + uint16_t version; + int ret; + uint16_t gen_cnfg = 0, gen_int_en = 0; + + if (!spi_is_ready_dt(&config->spi)) { + LOG_ERR("SPI spi %s not ready", config->spi.bus->name); + return -ENODEV; + } + + if (config->gpio_reset.port != NULL) { + ret = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE); + if (ret) { + LOG_ERR("failed to initialize GPIO reset pin"); + return ret; + } + } + + ret = max22017_reset(dev); + if (ret) { + LOG_ERR("failed to reset MAX22017"); + return ret; + } + + data->dev = dev; + k_work_init(&data->int_work, max22017_int_worker); + k_mutex_init(&data->lock); + + if (config->gpio_int.port) { + ret = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT); + if (ret) { + LOG_ERR("failed to initialize GPIO interrupt pin"); + goto fail; + } + + ret = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + if (ret) { + LOG_ERR("failed to configure interrupt pin"); + goto fail; + } + + gpio_init_callback(&data->callback_int, max22017_isr, BIT(config->gpio_int.pin)); + ret = gpio_add_callback(config->gpio_int.port, &data->callback_int); + if (ret) { + LOG_ERR("failed to add data ready callback"); + goto fail; + } + } + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_write(dev, MAX22017_AO_CNFG_OFF, 0); + if (ret) { + return ret; + } + + ret = max22017_reg_write(dev, MAX22017_AO_DATA_CHn_OFF(0), 0); + if (ret) { + goto fail; + } + + ret = max22017_reg_write(dev, MAX22017_AO_DATA_CHn_OFF(1), 0); + if (ret) { + goto fail; + } + + if (config->crc_mode) { + gen_cnfg |= FIELD_PREP(MAX22017_GEN_CNFG_CRC_EN, 1); + gen_int_en |= FIELD_PREP(MAX22017_GEN_INTEN_CRC_INTEN, 1); + } + + ret = max22017_reg_write(dev, MAX22017_GEN_INTEN_OFF, gen_int_en); + if (ret) { + goto fail; + } + + ret = max22017_reg_write(dev, MAX22017_GEN_CNFG_OFF, gen_cnfg); + if (ret) { + goto fail; + } + + if (config->crc_mode) { + data->crc_enabled = true; + } + + ret = max22017_reg_read(dev, MAX22017_GEN_ID_OFF, &version); + if (ret) { + LOG_ERR("Unable to read MAX22017 version over SPI: %d", ret); + goto fail; + } + + LOG_INF("MAX22017 version: 0x%lx 0x%lx", FIELD_GET(MAX22017_GEN_ID_PROD_ID, version), + FIELD_GET(MAX22017_GEN_ID_REV_ID, version)); + +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +#define INST_DT_MAX22017(index) \ + static const struct max22017_config max22017_config_##index = { \ + .spi = SPI_DT_SPEC_INST_GET(index, SPI_OP_MODE_MASTER | SPI_WORD_SET(8U), 0U), \ + .gpio_int = GPIO_DT_SPEC_INST_GET_OR(index, int_gpios, {0}), \ + .gpio_reset = GPIO_DT_SPEC_INST_GET_OR(index, rst_gpios, {0}), \ + .crc_mode = DT_INST_PROP_OR(index, crc_mode, 0), \ + }; \ + \ + static struct max22017_data max22017_data_##index; \ + \ + DEVICE_DT_INST_DEFINE(index, max22017_init, NULL, &max22017_data_##index, \ + &max22017_config_##index, POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(INST_DT_MAX22017); diff --git a/drivers/mfd/mfd_npm2100.c b/drivers/mfd/mfd_npm2100.c index 316687da1e946..78049dff56e6c 100644 --- a/drivers/mfd/mfd_npm2100.c +++ b/drivers/mfd/mfd_npm2100.c @@ -14,23 +14,24 @@ #include #include -#define EVENTS_SET 0x00U -#define EVENTS_CLR 0x05U -#define INTEN_SET 0x0AU -#define GPIO_CONFIG 0x80U -#define GPIO_USAGE 0x83U -#define TIMER_TASKS_START 0xB0U -#define TIMER_CONFIG 0xB3U -#define TIMER_TARGET 0xB4U -#define TIMER_STATUS 0xB7U -#define SHPHLD_WAKEUP 0xC1U -#define SHPHLD_SHPHLD 0xC2U -#define HIBERNATE_TASKS_HIBER 0xC8U -#define RESET_TASKS_RESET 0xD0U -#define RESET_BUTTON 0xD2U -#define RESET_PIN 0xD3U -#define RESET_WRITESTICKY 0xDBU -#define RESET_STROBESTICKY 0xDCU +#define EVENTS_SET 0x00U +#define EVENTS_CLR 0x05U +#define INTEN_SET 0x0AU +#define GPIO_CONFIG 0x80U +#define GPIO_USAGE 0x83U +#define TIMER_TASKS_START 0xB0U +#define TIMER_CONFIG 0xB3U +#define TIMER_TARGET 0xB4U +#define TIMER_STATUS 0xB7U +#define SHPHLD_WAKEUP 0xC1U +#define SHPHLD_SHPHLD 0xC2U +#define HIBERNATE_TASKS_HIBER 0xC8U +#define HIBERNATE_TASKS_HIBERPT 0xC9U +#define RESET_TASKS_RESET 0xD0U +#define RESET_BUTTON 0xD2U +#define RESET_PIN 0xD3U +#define RESET_WRITESTICKY 0xDBU +#define RESET_STROBESTICKY 0xDCU #define SHPHLD_RESISTOR_MASK 0x03U #define SHPHLD_RESISTOR_PULLUP 0x00U @@ -218,7 +219,7 @@ static int config_shphold(const struct device *dev) } reg = config->shiphold_hibernate_wakeup ? WAKEUP_HIBERNATE_PIN : WAKEUP_HIBERNATE_NOPIN; - if ((config->shiphold_flags & GPIO_ACTIVE_HIGH) != 0U) { + if ((config->shiphold_flags & GPIO_ACTIVE_LOW) == 0U) { reg |= WAKEUP_EDGE_RISING; } @@ -337,7 +338,7 @@ int mfd_npm2100_reset(const struct device *dev) return i2c_reg_write_byte_dt(&config->i2c, RESET_TASKS_RESET, 1U); } -int mfd_npm2100_hibernate(const struct device *dev, uint32_t time_ms) +int mfd_npm2100_hibernate(const struct device *dev, uint32_t time_ms, bool pass_through) { const struct mfd_npm2100_config *config = dev->config; int ret; @@ -354,18 +355,8 @@ int mfd_npm2100_hibernate(const struct device *dev, uint32_t time_ms) } } - /* Ensure shiphold button is enabled so that wakeup will work */ - ret = i2c_reg_write_byte_dt(&config->i2c, RESET_WRITESTICKY, 0); - if (ret < 0) { - return ret; - } - - ret = i2c_reg_write_byte_dt(&config->i2c, RESET_STROBESTICKY, 1U); - if (ret < 0) { - return ret; - } - - return i2c_reg_write_byte_dt(&config->i2c, HIBERNATE_TASKS_HIBER, 1U); + return i2c_reg_write_byte_dt( + &config->i2c, pass_through ? HIBERNATE_TASKS_HIBERPT : HIBERNATE_TASKS_HIBER, 1U); } int mfd_npm2100_add_callback(const struct device *dev, struct gpio_callback *callback) diff --git a/drivers/mfd/mfd_pf1550.c b/drivers/mfd/mfd_pf1550.c new file mode 100644 index 0000000000000..492f516e25335 --- /dev/null +++ b/drivers/mfd/mfd_pf1550.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Arduino SA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_pf1550 + +#include + +#include +#include + +#define PF1550_REG_CHIP_ID 0x00 +#define PF1550_CHIP_ID_VAL ((15 << 3) | 4) + +struct mfd_pf1550_config { + struct i2c_dt_spec bus; +}; + +static int mfd_pf1550_init(const struct device *dev) +{ + const struct mfd_pf1550_config *config = dev->config; + uint8_t val; + int ret; + + if (!i2c_is_ready_dt(&config->bus)) { + return -ENODEV; + } + + ret = i2c_reg_read_byte_dt(&config->bus, PF1550_REG_CHIP_ID, &val); + if (ret < 0) { + return ret; + } + + if (val != PF1550_CHIP_ID_VAL) { + return -ENODEV; + } + + return 0; +} + +#define MFD_PF1550_DEFINE(inst) \ + static const struct mfd_pf1550_config mfd_pf1550_config##inst = { \ + .bus = I2C_DT_SPEC_INST_GET(inst), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, mfd_pf1550_init, NULL, NULL, &mfd_pf1550_config##inst, \ + POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(MFD_PF1550_DEFINE) diff --git a/drivers/mipi_dbi/mipi_dbi_bitbang.c b/drivers/mipi_dbi/mipi_dbi_bitbang.c index 4549dfb570ec3..802262b1683b1 100644 --- a/drivers/mipi_dbi/mipi_dbi_bitbang.c +++ b/drivers/mipi_dbi/mipi_dbi_bitbang.c @@ -337,7 +337,7 @@ static DEVICE_API(mipi_dbi, mipi_dbi_bitbang_driver_api) = { .reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {}), \ DATA_LUT_OPTIMIZATION(n) \ }; \ - BUILD_ASSERT(DT_INST_PROP_LEN(n, data_gpios) < MIPI_DBI_MAX_DATA_BUS_WIDTH, \ + BUILD_ASSERT(DT_INST_PROP_LEN(n, data_gpios) <= MIPI_DBI_MAX_DATA_BUS_WIDTH, \ "Number of data GPIOs in DT exceeds MIPI_DBI_MAX_DATA_BUS_WIDTH"); \ static struct mipi_dbi_bitbang_data mipi_dbi_bitbang_data_##n; \ DEVICE_DT_INST_DEFINE(n, mipi_dbi_bitbang_init, NULL, &mipi_dbi_bitbang_data_##n, \ diff --git a/drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c b/drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c index 63e725945346a..9af91a72d86b0 100644 --- a/drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c +++ b/drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c @@ -34,6 +34,12 @@ enum lcdic_cmd_type { LCDIC_TX = 1, }; +enum lcdic_cmd_te { + LCDIC_TE_NO_SYNC = 0, + LCDIC_TE_RISING_EDGE = 1, + LCDIC_TE_FALLING_EDGE = 2, +}; + /* Limit imposed by size of data length field in LCDIC command */ #define LCDIC_MAX_XFER 0x40000 /* Max reset width (in terms of Timer0_Period, see RST_CTRL register) */ @@ -102,6 +108,10 @@ struct mipi_dbi_lcdic_data { uint32_t unaligned_word __aligned(4); /* Tracks lcdic_data_fmt value we should use for pixel data */ uint8_t pixel_fmt; + /* Tracks TE edge setting we should use for pixel data */ + uint8_t te_edge; + /* Are we starting a new display frame */ + bool new_frame; const struct mipi_dbi_config *active_cfg; struct k_sem xfer_sem; struct k_sem lock; @@ -376,6 +386,7 @@ static void mipi_dbi_lcdic_set_cmd(LCDIC_Type *base, enum lcdic_cmd_type dir, enum lcdic_cmd_dc dc, enum lcdic_data_fmt data_fmt, + enum lcdic_cmd_te te_sync, uint32_t buf_len) { union lcdic_trx_cmd cmd = {0}; @@ -387,6 +398,7 @@ static void mipi_dbi_lcdic_set_cmd(LCDIC_Type *base, cmd.bits.trx = dir; cmd.bits.cmd_done_int = true; cmd.bits.data_format = data_fmt; + cmd.bits.te_sync_mode = te_sync; /* Write command */ base->TFIFO_WDATA = cmd.u32; } @@ -401,6 +413,7 @@ static int mipi_dbi_lcdic_write_display(const struct device *dev, struct mipi_dbi_lcdic_data *dev_data = dev->data; LCDIC_Type *base = config->base; int ret; + enum lcdic_cmd_te te_sync = LCDIC_TE_NO_SYNC; uint32_t interrupts = 0U; ret = k_sem_take(&dev_data->lock, K_FOREVER); @@ -413,6 +426,26 @@ static int mipi_dbi_lcdic_write_display(const struct device *dev, goto out; } + if (dev_data->new_frame) { + switch (dev_data->te_edge) { + case MIPI_DBI_TE_RISING_EDGE: + te_sync = LCDIC_TE_RISING_EDGE; + break; + case MIPI_DBI_TE_FALLING_EDGE: + te_sync = LCDIC_TE_FALLING_EDGE; + break; + default: + te_sync = LCDIC_TE_NO_SYNC; + break; + } + dev_data->new_frame = false; + } + + if (!desc->frame_incomplete) { + /* Next frame will be a new one */ + dev_data->new_frame = true; + } + /* State reset is required before transfer */ mipi_dbi_lcdic_reset_state(dev); @@ -448,6 +481,7 @@ static int mipi_dbi_lcdic_write_display(const struct device *dev, */ mipi_dbi_lcdic_set_cmd(base, LCDIC_TX, LCDIC_DATA, dev_data->pixel_fmt, + te_sync, dev_data->cmd_bytes); #ifdef CONFIG_MIPI_DBI_NXP_LCDIC_DMA /* Enable command complete interrupt */ @@ -506,7 +540,7 @@ static int mipi_dbi_lcdic_write_cmd(const struct device *dev, /* Write command */ mipi_dbi_lcdic_set_cmd(base, LCDIC_TX, LCDIC_COMMAND, - LCDIC_DATA_FMT_BYTE, 1); + LCDIC_DATA_FMT_BYTE, LCDIC_TE_NO_SYNC, 1); /* Use standard byte writes */ dev_data->pixel_fmt = LCDIC_DATA_FMT_BYTE; base->TFIFO_WDATA = cmd; @@ -530,18 +564,10 @@ static int mipi_dbi_lcdic_write_cmd(const struct device *dev, dev_data->xfer_buf, dev_data->cmd_bytes); } - if (cmd == MIPI_DCS_WRITE_MEMORY_START) { - /* Use pixel format data width, so we can byte swap - * if needed - */ - mipi_dbi_lcdic_set_cmd(base, LCDIC_TX, LCDIC_DATA, - dev_data->pixel_fmt, - dev_data->cmd_bytes); - } else { - mipi_dbi_lcdic_set_cmd(base, LCDIC_TX, LCDIC_DATA, - LCDIC_DATA_FMT_BYTE, - dev_data->cmd_bytes); - } + mipi_dbi_lcdic_set_cmd(base, LCDIC_TX, LCDIC_DATA, + LCDIC_DATA_FMT_BYTE, + LCDIC_TE_NO_SYNC, + dev_data->cmd_bytes); #ifdef CONFIG_MIPI_DBI_NXP_LCDIC_DMA if (((((uint32_t)dev_data->xfer_buf) & 0x3) == 0) || (dev_data->cmd_bytes < 4)) { @@ -618,6 +644,50 @@ static int mipi_dbi_lcdic_reset(const struct device *dev, k_timeout_t delay) return 0; } +static int mipi_dbi_lcdic_configure_te(const struct device *dev, + uint8_t edge, + k_timeout_t delay) +{ + const struct mipi_dbi_lcdic_config *config = dev->config; + LCDIC_Type *base = config->base; + struct mipi_dbi_lcdic_data *data = dev->data; + uint32_t lcdic_freq, ttew, reg; + uint32_t delay_us = k_ticks_to_us_ceil32(delay.ticks); + + /* Calculate delay based off timer0 ratio. Formula given + * by RM is as follows: + * TE delay = Timer1_Period * ttew + * Timer1_Period = 2^(TIMER_RATIO1) * Timer0_Period + * Timer0_Period = 2^(TIMER_RATIO0) / LCDIC_Clock_Freq + */ + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, + &lcdic_freq)) { + return -EIO; + } + + /* + * Calculate TTEW. Done in multiple steps to avoid overflowing + * the uint32_t type. Full formula is: + * (lcdic_freq * delay_us) / + * ((2 ^ (TIMER_RATIO1 + TIMER_RATIO0)) * USEC_PER_SEC) + */ + ttew = lcdic_freq / (1 << config->timer0_ratio); + ttew *= delay_us; + ttew /= (1 << config->timer1_ratio); + ttew /= USEC_PER_SEC; + + /* Check to see if the delay is shorter than we can support */ + if ((ttew == 0) && (delay_us != 0)) { + LOG_ERR("Timer ratios too large to support this TE delay"); + return -ENOTSUP; + } + reg = base->TE_CTRL; + reg &= ~LCDIC_TE_CTRL_TTEW_MASK; + reg |= LCDIC_TE_CTRL_TTEW(ttew); + base->TE_CTRL = reg; + data->te_edge = edge; + return 0; +} /* Initializes LCDIC peripheral */ @@ -671,6 +741,8 @@ static int mipi_dbi_lcdic_init(const struct device *dev) base->TIMER_CTRL = LCDIC_TIMER_CTRL_TIMER_RATIO1(config->timer1_ratio) | LCDIC_TIMER_CTRL_TIMER_RATIO0(config->timer0_ratio); + data->te_edge = MIPI_DBI_TE_NO_EDGE; + #ifdef CONFIG_MIPI_DBI_NXP_LCDIC_DMA /* Attach the LCDIC DMA request signal to the DMA channel we will * use with hardware triggering. @@ -687,6 +759,7 @@ static int mipi_dbi_lcdic_init(const struct device *dev) static DEVICE_API(mipi_dbi, mipi_dbi_lcdic_driver_api) = { .command_write = mipi_dbi_lcdic_write_cmd, .write_display = mipi_dbi_lcdic_write_display, + .configure_te = mipi_dbi_lcdic_configure_te, .reset = mipi_dbi_lcdic_reset, }; @@ -718,7 +791,8 @@ static void mipi_dbi_lcdic_isr(const struct device *dev) /* Command done. Queue next command */ data->cmd_bytes = MIN(data->xfer_bytes, LCDIC_MAX_XFER); mipi_dbi_lcdic_set_cmd(base, LCDIC_TX, LCDIC_DATA, - LCDIC_DATA_FMT_BYTE, + data->pixel_fmt, + LCDIC_TE_NO_SYNC, data->cmd_bytes); if (data->cmd_bytes & 0x3) { /* Save unaligned portion of transfer into diff --git a/drivers/mipi_dbi/mipi_dbi_spi.c b/drivers/mipi_dbi/mipi_dbi_spi.c index eb90cd2b4de09..85cba935dff3b 100644 --- a/drivers/mipi_dbi/mipi_dbi_spi.c +++ b/drivers/mipi_dbi/mipi_dbi_spi.c @@ -1,5 +1,6 @@ /* * Copyright 2023 NXP + * Copyright 2024-2025 TiaC Systems * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +10,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(mipi_dbi_spi, CONFIG_MIPI_DBI_LOG_LEVEL); @@ -20,6 +22,8 @@ struct mipi_dbi_spi_config { const struct gpio_dt_spec cmd_data; /* Reset GPIO */ const struct gpio_dt_spec reset; + /* Minimum transfer bits */ + const uint8_t xfr_min_bits; }; struct mipi_dbi_spi_data { @@ -29,15 +33,29 @@ struct mipi_dbi_spi_data { }; /* Expands to 1 if the node does not have the `write-only` property */ -#define _WRITE_ONLY_ABSENT(n) (!DT_INST_PROP(n, write_only)) | +#define MIPI_DBI_SPI_WRITE_ONLY_ABSENT(n) (!DT_INST_PROP(n, write_only)) | /* This macro will evaluate to 1 if any of the nodes with zephyr,mipi-dbi-spi * lack a `write-only` property. The intention here is to allow the entire * command_read function to be optimized out when it is not needed. */ -#define MIPI_DBI_SPI_READ_REQUIRED DT_INST_FOREACH_STATUS_OKAY(_WRITE_ONLY_ABSENT) 0 +#define MIPI_DBI_SPI_READ_REQUIRED DT_INST_FOREACH_STATUS_OKAY(MIPI_DBI_SPI_WRITE_ONLY_ABSENT) 0 uint32_t var = MIPI_DBI_SPI_READ_REQUIRED; +/* Expands to 1 if the node does reflect the enum in `xfr-min-bits` property */ +#define MIPI_DBI_SPI_XFR_8BITS(n) (DT_INST_STRING_UPPER_TOKEN(n, xfr_min_bits) \ + == MIPI_DBI_SPI_XFR_8BIT) | +#define MIPI_DBI_SPI_XFR_16BITS(n) (DT_INST_STRING_UPPER_TOKEN(n, xfr_min_bits) \ + == MIPI_DBI_SPI_XFR_16BIT) | + +/* This macros will evaluate to 1 if any of the nodes with zephyr,mipi-dbi-spi + * have the `xfr-min-bits` property to corresponding enum value. The intention + * here is to allow the write helper functions to be optimized out when not all + * minimum transfer bits will be needed. + */ +#define MIPI_DBI_SPI_WRITE_8BIT_REQUIRED DT_INST_FOREACH_STATUS_OKAY(MIPI_DBI_SPI_XFR_8BITS) 0 +#define MIPI_DBI_SPI_WRITE_16BIT_REQUIRED DT_INST_FOREACH_STATUS_OKAY(MIPI_DBI_SPI_XFR_16BITS) 0 + /* In Type C mode 1 MIPI BIT communication, the 9th bit of the word * (first bit sent in each word) indicates if the word is a command or * data. Typically 0 indicates a command and 1 indicates data, but some @@ -46,13 +64,62 @@ uint32_t var = MIPI_DBI_SPI_READ_REQUIRED; */ #define MIPI_DBI_DC_BIT BIT(8) -static int mipi_dbi_spi_write_helper(const struct device *dev, +static inline int +mipi_dbi_spi_write_helper_3wire(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + bool cmd_present, uint8_t cmd, + const uint8_t *data_buf, size_t len) +{ + const struct mipi_dbi_spi_config *config = dev->config; + struct mipi_dbi_spi_data *data = dev->data; + struct spi_buf buffer; + struct spi_buf_set buf_set = { + .buffers = &buffer, + .count = 1, + }; + int ret = 0; + + /* + * 9 bit word mode must be used, as the command/data bit + * is stored before the data word. + */ + + if ((dbi_config->config.operation & SPI_WORD_SIZE_MASK) + != SPI_WORD_SET(9)) { + return -ENOTSUP; + } + buffer.buf = &data->spi_byte; + buffer.len = 2; + + /* Send command */ + if (cmd_present) { + data->spi_byte = cmd; + ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set); + if (ret < 0) { + goto out; + } + } + /* Write data, byte by byte */ + for (size_t i = 0; i < len; i++) { + data->spi_byte = MIPI_DBI_DC_BIT | data_buf[i]; + ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set); + if (ret < 0) { + goto out; + } + } +out: + return ret; +} + +#if MIPI_DBI_SPI_WRITE_8BIT_REQUIRED + +static inline int +mipi_dbi_spi_write_helper_4wire_8bit(const struct device *dev, const struct mipi_dbi_config *dbi_config, bool cmd_present, uint8_t cmd, const uint8_t *data_buf, size_t len) { const struct mipi_dbi_spi_config *config = dev->config; - struct mipi_dbi_spi_data *data = dev->data; struct spi_buf buffer; struct spi_buf_set buf_set = { .buffers = &buffer, @@ -60,52 +127,105 @@ static int mipi_dbi_spi_write_helper(const struct device *dev, }; int ret = 0; - ret = k_mutex_lock(&data->lock, K_FOREVER); - if (ret < 0) { - return ret; + /* + * 4 wire mode is much simpler. We just toggle the + * command/data GPIO to indicate if we are sending + * a command or data + */ + + buffer.buf = &cmd; + buffer.len = sizeof(cmd); + + if (cmd_present) { + /* Set CD pin low for command */ + gpio_pin_set_dt(&config->cmd_data, 0); + ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set); + if (ret < 0) { + goto out; + } } - if (dbi_config->mode == MIPI_DBI_MODE_SPI_3WIRE && - IS_ENABLED(CONFIG_MIPI_DBI_SPI_3WIRE)) { - /* 9 bit word mode must be used, as the command/data bit - * is stored before the data word. - */ - if ((dbi_config->config.operation & SPI_WORD_SIZE_MASK) - != SPI_WORD_SET(9)) { - return -ENOTSUP; + if (len > 0) { + buffer.buf = (void *)data_buf; + buffer.len = len; + + /* Set CD pin high for data */ + gpio_pin_set_dt(&config->cmd_data, 1); + ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set); + if (ret < 0) { + goto out; } - buffer.buf = &data->spi_byte; - buffer.len = 2; + } +out: + return ret; +} - /* Send command */ - if (cmd_present) { - data->spi_byte = cmd; - ret = spi_write(config->spi_dev, &dbi_config->config, - &buf_set); - if (ret < 0) { - goto out; - } +#endif /* MIPI_DBI_SPI_WRITE_8BIT_REQUIRED */ + +#if MIPI_DBI_SPI_WRITE_16BIT_REQUIRED + +static inline int +mipi_dbi_spi_write_helper_4wire_16bit(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + bool cmd_present, uint8_t cmd, + const uint8_t *data_buf, size_t len) +{ + const struct mipi_dbi_spi_config *config = dev->config; + struct spi_buf buffer; + struct spi_buf_set buf_set = { + .buffers = &buffer, + .count = 1, + }; + uint16_t data16; + int ret = 0; + + /* + * 4 wire mode with toggle the command/data GPIO + * to indicate if we are sending a command or data + * but send 16-bit blocks (with bit stuffing). + */ + + if (cmd_present) { + data16 = sys_cpu_to_be16(cmd); + buffer.buf = &data16; + buffer.len = sizeof(data16); + + /* Set CD pin low for command */ + gpio_pin_set_dt(&config->cmd_data, 0); + ret = spi_write(config->spi_dev, &dbi_config->config, + &buf_set); + if (ret < 0) { + goto out; + } + + /* Set CD pin high for data, if there are any */ + if (len > 0) { + gpio_pin_set_dt(&config->cmd_data, 1); } - /* Write data, byte by byte */ - for (size_t i = 0; i < len; i++) { - data->spi_byte = MIPI_DBI_DC_BIT | data_buf[i]; + + /* iterate command data */ + for (int i = 0; i < len; i++) { + data16 = sys_cpu_to_be16(data_buf[i]); + ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set); if (ret < 0) { goto out; } } - } else if (dbi_config->mode == MIPI_DBI_MODE_SPI_4WIRE) { - /* 4 wire mode is much simpler. We just toggle the - * command/data GPIO to indicate if we are sending - * a command or data - */ - buffer.buf = &cmd; - buffer.len = sizeof(cmd); - - if (cmd_present) { - /* Set CD pin low for command */ - gpio_pin_set_dt(&config->cmd_data, 0); + } else { + int stuffing = len % sizeof(data16); + + /* Set CD pin high for data, if there are any */ + if (len > 0) { + gpio_pin_set_dt(&config->cmd_data, 1); + } + + /* pass through generic device data */ + if (len - stuffing > 0) { + buffer.buf = (void *)data_buf; + buffer.len = len - stuffing; + ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set); if (ret < 0) { @@ -113,22 +233,74 @@ static int mipi_dbi_spi_write_helper(const struct device *dev, } } - if (len > 0) { - buffer.buf = (void *)data_buf; - buffer.len = len; + /* iterate remaining data with stuffing */ + for (int i = len - stuffing; i < len; i++) { + data16 = sys_cpu_to_be16(data_buf[i]); + buffer.buf = &data16; + buffer.len = sizeof(data16); - /* Set CD pin high for data */ - gpio_pin_set_dt(&config->cmd_data, 1); ret = spi_write(config->spi_dev, &dbi_config->config, &buf_set); if (ret < 0) { goto out; } } - } else { - /* Otherwise, unsupported mode */ - ret = -ENOTSUP; } +out: + return ret; +} + +#endif /* MIPI_DBI_SPI_WRITE_16BIT_REQUIRED */ + +static int mipi_dbi_spi_write_helper(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + bool cmd_present, uint8_t cmd, + const uint8_t *data_buf, size_t len) +{ + const struct mipi_dbi_spi_config *config = dev->config; + struct mipi_dbi_spi_data *data = dev->data; + int ret = 0; + + ret = k_mutex_lock(&data->lock, K_FOREVER); + if (ret < 0) { + return ret; + } + + if (dbi_config->mode == MIPI_DBI_MODE_SPI_3WIRE && + IS_ENABLED(CONFIG_MIPI_DBI_SPI_3WIRE)) { + ret = mipi_dbi_spi_write_helper_3wire(dev, dbi_config, + cmd_present, cmd, + data_buf, len); + goto out; + } + + if (dbi_config->mode == MIPI_DBI_MODE_SPI_4WIRE) { + +#if MIPI_DBI_SPI_WRITE_8BIT_REQUIRED + if (config->xfr_min_bits == MIPI_DBI_SPI_XFR_8BIT) { + ret = mipi_dbi_spi_write_helper_4wire_8bit( + dev, dbi_config, + cmd_present, cmd, + data_buf, len); + goto out; + } +#endif + +#if MIPI_DBI_SPI_WRITE_16BIT_REQUIRED + if (config->xfr_min_bits == MIPI_DBI_SPI_XFR_16BIT) { + ret = mipi_dbi_spi_write_helper_4wire_16bit( + dev, dbi_config, + cmd_present, cmd, + data_buf, len); + goto out; + } +#endif + + } + + /* Otherwise, unsupported mode */ + ret = -ENOTSUP; + out: k_mutex_unlock(&data->lock); return ret; @@ -157,89 +329,148 @@ static int mipi_dbi_spi_write_display(const struct device *dev, #if MIPI_DBI_SPI_READ_REQUIRED -static int mipi_dbi_spi_command_read(const struct device *dev, - const struct mipi_dbi_config *dbi_config, - uint8_t *cmds, size_t num_cmds, - uint8_t *response, size_t len) +static inline int +mipi_dbi_spi_read_helper_3wire(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + uint8_t *cmds, size_t num_cmds, + uint8_t *response, size_t len) { const struct mipi_dbi_spi_config *config = dev->config; struct mipi_dbi_spi_data *data = dev->data; + struct spi_config tmp_config; struct spi_buf buffer; struct spi_buf_set buf_set = { .buffers = &buffer, .count = 1, }; int ret = 0; + + /* + * We have to emulate 3 wire mode by packing the data/command + * bit into the upper bit of the SPI transfer, switch SPI to + * 9 bit mode, and write the transfer. + */ + + if ((dbi_config->config.operation & SPI_WORD_SIZE_MASK) + != SPI_WORD_SET(9)) { + return -ENOTSUP; + } + + memcpy(&tmp_config, &dbi_config->config, sizeof(tmp_config)); + tmp_config.operation &= ~SPI_WORD_SIZE_MASK; + tmp_config.operation |= SPI_WORD_SET(9); + + buffer.buf = &data->spi_byte; + buffer.len = 1; + + /* Send each command */ + for (size_t i = 0; i < num_cmds; i++) { + data->spi_byte = cmds[i]; + ret = spi_write(config->spi_dev, &tmp_config, &buf_set); + if (ret < 0) { + goto out; + } + } + + /* Now, we can switch to 8 bit mode, and read data */ + buffer.buf = (void *)response; + buffer.len = len; + ret = spi_read(config->spi_dev, &dbi_config->config, &buf_set); + +out: + spi_release(config->spi_dev, &tmp_config); /* Really necessary here? */ + return ret; +} + +static inline int +mipi_dbi_spi_read_helper_4wire(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + uint8_t *cmds, size_t num_cmds, + uint8_t *response, size_t len) +{ + const struct mipi_dbi_spi_config *config = dev->config; struct spi_config tmp_config; + struct spi_buf buffer; + struct spi_buf_set buf_set = { + .buffers = &buffer, + .count = 1, + }; + int ret = 0; + + /* + * 4 wire mode is much simpler. We just toggle the + * command/data GPIO to indicate if we are sending + * a command or data. Note that since some SPI displays + * require CS to be held low for the entire read sequence, + * we set SPI_HOLD_ON_CS + */ + + memcpy(&tmp_config, &dbi_config->config, sizeof(tmp_config)); + tmp_config.operation |= SPI_HOLD_ON_CS; + + if (num_cmds > 0) { + buffer.buf = cmds; + buffer.len = num_cmds; + + /* Set CD pin low for command */ + gpio_pin_set_dt(&config->cmd_data, 0); + + ret = spi_write(config->spi_dev, &tmp_config, &buf_set); + if (ret < 0) { + goto out; + } + } + + if (len > 0) { + buffer.buf = (void *)response; + buffer.len = len; + + /* Set CD pin high for data */ + gpio_pin_set_dt(&config->cmd_data, 1); + + ret = spi_read(config->spi_dev, &tmp_config, &buf_set); + if (ret < 0) { + goto out; + } + } + +out: + spi_release(config->spi_dev, &tmp_config); + return ret; +} + +static int mipi_dbi_spi_command_read(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + uint8_t *cmds, size_t num_cmds, + uint8_t *response, size_t len) +{ + struct mipi_dbi_spi_data *data = dev->data; + int ret = 0; ret = k_mutex_lock(&data->lock, K_FOREVER); if (ret < 0) { return ret; } - memcpy(&tmp_config, &dbi_config->config, sizeof(tmp_config)); if (dbi_config->mode == MIPI_DBI_MODE_SPI_3WIRE && IS_ENABLED(CONFIG_MIPI_DBI_SPI_3WIRE)) { - /* We have to emulate 3 wire mode by packing the data/command - * bit into the upper bit of the SPI transfer. - * switch SPI to 9 bit mode, and write the transfer - */ - tmp_config.operation &= ~SPI_WORD_SIZE_MASK; - tmp_config.operation |= SPI_WORD_SET(9); - - buffer.buf = &data->spi_byte; - buffer.len = 1; - /* Send each command */ - for (size_t i = 0; i < num_cmds; i++) { - data->spi_byte = cmds[i]; - ret = spi_write(config->spi_dev, &tmp_config, &buf_set); - if (ret < 0) { - goto out; - } + ret = mipi_dbi_spi_read_helper_3wire(dev, dbi_config, + cmds, num_cmds, + response, len); + if (ret < 0) { + goto out; } - /* Now, we can switch to 8 bit mode, and read data */ - buffer.buf = (void *)response; - buffer.len = len; - ret = spi_read(config->spi_dev, &dbi_config->config, &buf_set); } else if (dbi_config->mode == MIPI_DBI_MODE_SPI_4WIRE) { - /* 4 wire mode is much simpler. We just toggle the - * command/data GPIO to indicate if we are sending - * a command or data. Note that since some SPI displays - * require CS to be held low for the entire read sequence, - * we set SPI_HOLD_ON_CS - */ - tmp_config.operation |= SPI_HOLD_ON_CS; - - if (num_cmds > 0) { - buffer.buf = cmds; - buffer.len = num_cmds; - /* Set CD pin low for command */ - gpio_pin_set_dt(&config->cmd_data, 0); - - ret = spi_write(config->spi_dev, &tmp_config, - &buf_set); - if (ret < 0) { - goto out; - } - } - - if (len > 0) { - /* Set CD pin high for data */ - gpio_pin_set_dt(&config->cmd_data, 1); - - buffer.buf = (void *)response; - buffer.len = len; - ret = spi_read(config->spi_dev, &tmp_config, - &buf_set); - if (ret < 0) { - goto out; - } + ret = mipi_dbi_spi_read_helper_4wire(dev, dbi_config, + cmds, num_cmds, + response, len); + if (ret < 0) { + goto out; } } else { /* Otherwise, unsupported mode */ ret = -ENOTSUP; } out: - spi_release(config->spi_dev, &tmp_config); k_mutex_unlock(&data->lock); return ret; } @@ -331,6 +562,7 @@ static DEVICE_API(mipi_dbi, mipi_dbi_spi_driver_api) = { DT_INST_PHANDLE(n, spi_dev)), \ .cmd_data = GPIO_DT_SPEC_INST_GET_OR(n, dc_gpios, {}), \ .reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {}), \ + .xfr_min_bits = DT_INST_STRING_UPPER_TOKEN(n, xfr_min_bits) \ }; \ static struct mipi_dbi_spi_data mipi_dbi_spi_data_##n; \ \ diff --git a/drivers/mipi_dsi/CMakeLists.txt b/drivers/mipi_dsi/CMakeLists.txt index 35477023c6bb9..eb28fb952c08a 100644 --- a/drivers/mipi_dsi/CMakeLists.txt +++ b/drivers/mipi_dsi/CMakeLists.txt @@ -3,3 +3,4 @@ zephyr_sources_ifdef(CONFIG_MIPI_DSI_MCUX dsi_mcux.c) zephyr_sources_ifdef(CONFIG_MIPI_DSI_MCUX_2L dsi_mcux_2l.c) zephyr_sources_ifdef(CONFIG_MIPI_DSI_STM32 dsi_stm32.c) zephyr_sources_ifdef(CONFIG_MIPI_DSI_TEST dsi_test.c) +zephyr_sources_ifdef(CONFIG_MIPI_DSI_RENESAS_RA dsi_renesas_ra.c) diff --git a/drivers/mipi_dsi/Kconfig b/drivers/mipi_dsi/Kconfig index 3f5928ff6c18f..508579001f2ad 100644 --- a/drivers/mipi_dsi/Kconfig +++ b/drivers/mipi_dsi/Kconfig @@ -24,5 +24,6 @@ config MIPI_DSI_INIT_PRIORITY source "drivers/mipi_dsi/Kconfig.mcux" source "drivers/mipi_dsi/Kconfig.stm32" source "drivers/mipi_dsi/Kconfig.test" +source "drivers/mipi_dsi/Kconfig.renesas_ra" endif diff --git a/drivers/mipi_dsi/Kconfig.renesas_ra b/drivers/mipi_dsi/Kconfig.renesas_ra new file mode 100644 index 0000000000000..eb2cf950c87b0 --- /dev/null +++ b/drivers/mipi_dsi/Kconfig.renesas_ra @@ -0,0 +1,12 @@ +# Renesas RA Family + +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config MIPI_DSI_RENESAS_RA + bool "Renesas RA MIPI-DSI Host Controller" + default y + depends on DT_HAS_RENESAS_RA_MIPI_DSI_ENABLED + select USE_RA_FSP_MIPI_DSI + help + Renesas RA MIPI DSI controller driver diff --git a/drivers/mipi_dsi/dsi_mcux_2l.c b/drivers/mipi_dsi/dsi_mcux_2l.c index 9adfc19b8387e..c3ebd1ce7b7e5 100644 --- a/drivers/mipi_dsi/dsi_mcux_2l.c +++ b/drivers/mipi_dsi/dsi_mcux_2l.c @@ -1,5 +1,5 @@ /* - * Copyright 2023, NXP + * Copyright 2023,2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,10 +16,10 @@ #include #include -#include #include #include #ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA +#include #include #endif @@ -49,6 +49,12 @@ struct mcux_mipi_dsi_config { struct mcux_mipi_dsi_data { dsi_handle_t mipi_handle; struct k_sem transfer_sem; + uint16_t flags; + uint8_t lane_mask; +#if DT_PROP(DT_NODELABEL(mipi_dsi), ulps_control) + uint32_t delay_hs_to_ulps_ns; + uint32_t delay_lp_to_ulps_ns; +#endif #ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA smartdma_dsi_param_t smartdma_params __aligned(4); uint32_t smartdma_stack[32]; @@ -60,6 +66,40 @@ struct mcux_mipi_dsi_data { /* MAX DSI TX payload */ #define DSI_TX_MAX_PAYLOAD_BYTE (64U * 4U) +static void dsi_mcux_transfer_prepare(const struct device *dev) +{ +#if DT_PROP(DT_NODELABEL(mipi_dsi), ulps_control) + const struct mcux_mipi_dsi_config *config = dev->config; + + /* If in ULPS state, exit before transfer. */ + if (DSI_GetUlpsStatus(config->base) != 0U) { + DSI_SetUlpsStatus(config->base, 0U); + while (DSI_GetUlpsStatus(config->base) != 0U) { + } + } +#endif +} + +static void dsi_mcux_transfer_complete(const struct device *dev) +{ +#if DT_PROP(DT_NODELABEL(mipi_dsi), ulps_control) + const struct mcux_mipi_dsi_config *config = dev->config; + struct mcux_mipi_dsi_data *data = dev->data; + + /* Enter ulps state after transfer completes. */ + if ((data->flags & MCUX_DSI_2L_ULPS) != 0U) { + /* It is necessary to delay a period. */ + if (data->flags & MIPI_DSI_MSG_USE_LPM) { + k_busy_wait(data->delay_lp_to_ulps_ns / 1000U); + } else { + k_busy_wait(data->delay_hs_to_ulps_ns / 1000U); + } + DSI_SetUlpsStatus(config->base, data->lane_mask); + while (DSI_GetUlpsStatus(config->base) != data->lane_mask) { + } + } +#endif +} #ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA @@ -81,6 +121,8 @@ static void dsi_mcux_dma_cb(const struct device *dma_dev, DSI_GetAndClearInterruptStatus(config->base, &int_flags1, &int_flags2); k_sem_give(&data->transfer_sem); } + + dsi_mcux_transfer_complete(dev); } /* Helper function to transfer DSI color (DMA based implementation) */ @@ -146,7 +188,10 @@ static int dsi_mcux_tx_color(const struct device *dev, uint8_t channel, static void dsi_transfer_complete(MIPI_DSI_HOST_Type *base, dsi_handle_t *handle, status_t status, void *userData) { - struct mcux_mipi_dsi_data *data = userData; + struct device *dev = userData; + struct mcux_mipi_dsi_data *data = dev->data; + + dsi_mcux_transfer_complete(dev); k_sem_give(&data->transfer_sem); } @@ -219,6 +264,7 @@ static int dsi_mcux_attach(const struct device *dev, const struct mipi_dsi_device *mdev) { const struct mcux_mipi_dsi_config *config = dev->config; + struct mcux_mipi_dsi_data *data = dev->data; dsi_dphy_config_t dphy_config; dsi_config_t dsi_config; uint32_t dphy_bit_clk_freq; @@ -250,8 +296,6 @@ static int dsi_mcux_attach(const struct device *dev, return -ENODEV; } - struct mcux_mipi_dsi_data *data = dev->data; - switch (mdev->pixfmt) { case MIPI_DSI_PIXFMT_RGB888: data->dma_slot = kSMARTDMA_MIPI_RGB888_DMA; @@ -277,15 +321,30 @@ static int dsi_mcux_attach(const struct device *dev, (uint8_t *)s_smartdmaDisplayFirmware, s_smartdmaDisplayFirmwareSize); #else - struct mcux_mipi_dsi_data *data = dev->data; - /* Create transfer handle */ if (DSI_TransferCreateHandle(config->base, &data->mipi_handle, - dsi_transfer_complete, data) != kStatus_Success) { + dsi_transfer_complete, (void *)dev) != kStatus_Success) { return -ENODEV; } #endif +#if DT_PROP(DT_NODELABEL(mipi_dsi), ulps_control) + /* Get how many lanes are enabled. */ + uint8_t data_lanes = mdev->data_lanes; + + /* Calculate the lane mask. */ + data->lane_mask = 2U; + while (data_lanes--) { + data->lane_mask <<= 1U; + } + data->lane_mask--; + + /* Clock lane cannot go into ULPS if not in non-continuous mode. */ + if (!dsi_config.enableNonContinuousHsClk) { + data->lane_mask &= ~0x1U; + } +#endif + /* Get the DPHY bit clock frequency */ if (clock_control_get_rate(config->bit_clk_dev, config->bit_clk_subsys, @@ -353,6 +412,47 @@ static int dsi_mcux_attach(const struct device *dev, dsi_pixel_clk_freq, dphy_bit_clk_freq); } +#if DT_PROP(DT_NODELABEL(mipi_dsi), ulps_control) + /* Calculate the delay before entering ULPS. After the last cycle of data has + * been accepted from the controller to the PHY, the data still needs to be + * serialized, transmitted, then the appropriate timing must be met before + * entering the ULPS. The data lane rate can impact this, so calcuate the time + * it takes for one data lane to send 1 bit in HS and LP mode first. + */ + uint32_t hs_bit_ns = 1000000000UL / dphy_bit_clk_freq; + uint32_t lp_bit_ns = 1000000000UL / dphy_esc_clk_freq; + + /* When the clock is in non-continuous mode, the formula for the delay after + * HS transmit would be: + * delay = 4*(UI*8) + m_prg_hs_trail*(UI*8) + 2*TxClkEsc_period + + * (cfg_t_post+2)*(UI*8) + mc_prg_hs_trail*(UI*8) + 2*TxClkEsc_period. + * Similarly, the delay after LP transmit would be: + * 4*(UI*8) + 2*TxClkEsc_period + TxClkEsc_period + 2*TxClkEsc_period. + */ + if (dsi_config.enableNonContinuousHsClk) { + data->delay_hs_to_ulps_ns = 4U * 8U * hs_bit_ns / dsi_config.numLanes + + dphy_config.tHsTrail_ByteClk * 8U * hs_bit_ns + + 2U * lp_bit_ns + + (dphy_config.tClkPost_ByteClk + 2U) * hs_bit_ns + + dphy_config.tClkTrail_ByteClk * 8U * hs_bit_ns + + 2U * lp_bit_ns; + data->delay_lp_to_ulps_ns = (2U + 1U + 2U) * lp_bit_ns + + 4U * 8U * lp_bit_ns / dsi_config.numLanes; + /* When the clock is in continuous mode, the formula for the delay after + * HS transmit would be: + * delay = 4*(UI*8) + m_prg_hs_trail*(UI*8) + 2*TxClkEsc_period. + * Similarly, the delay after LP transmit would be: + * delay = 4*(UI*8) + 2*TxClkEsc_period + TxClkEsc_period. + */ + } else { + data->delay_hs_to_ulps_ns = 2U * lp_bit_ns + + 4U * 8U * hs_bit_ns / dsi_config.numLanes + + dphy_config.tHsTrail_ByteClk * 8U * hs_bit_ns; + data->delay_lp_to_ulps_ns = (2U + 1U) * lp_bit_ns + + 4U * 8U * lp_bit_ns / dsi_config.numLanes; + } +#endif + imxrt_post_init_display_interface(); return 0; @@ -380,6 +480,7 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, struct mipi_dsi_msg *msg) { const struct mcux_mipi_dsi_config *config = dev->config; + dsi_transfer_t dsi_xfer = {0}; status_t status; int ret; @@ -392,6 +493,17 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, /* default to high speed unless told to use low power */ dsi_xfer.flags = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? 0 : kDSI_TransferUseHighSpeed; +#if DT_PROP(DT_NODELABEL(mipi_dsi), ulps_control) + struct mcux_mipi_dsi_data *data = dev->data; + + data->flags = (msg->flags & MIPI_DSI_MSG_USE_LPM) ? MIPI_DSI_MSG_USE_LPM : 0U; + if (msg->flags & MCUX_DSI_2L_ULPS) { + data->flags |= MCUX_DSI_2L_ULPS; + } +#endif + + dsi_mcux_transfer_prepare(dev); + switch (msg->type) { case MIPI_DSI_DCS_READ: LOG_ERR("DCS Read not yet implemented or used"); @@ -449,6 +561,9 @@ static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel, } status = DSI_TransferBlocking(config->base, &dsi_xfer); + + dsi_mcux_transfer_complete(dev); + if (status != kStatus_Success) { LOG_ERR("Transmission failed"); return -EIO; diff --git a/drivers/mipi_dsi/dsi_renesas_ra.c b/drivers/mipi_dsi/dsi_renesas_ra.c new file mode 100644 index 0000000000000..608bbb6867fab --- /dev/null +++ b/drivers/mipi_dsi/dsi_renesas_ra.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_mipi_dsi + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "r_mipi_dsi.h" +#include "r_mipi_phy.h" + +LOG_MODULE_REGISTER(dsi_renesas_ra, CONFIG_MIPI_DSI_LOG_LEVEL); + +/* MIPI PHY Macros */ +#define MIPI_PHY_CLKSTPT (1183) +#define MIPI_PHY_CLKBFHT (11) +#define MIPI_PHY_CLKKPT (26) +#define MIPI_PHY_GOLPBKT (40) + +#define MIPI_PHY_TINIT (71999) +#define MIPI_PHY_TCLKPREP (8) +#define MIPI_PHY_THSPREP (5) +#define MIPI_PHY_TCLKTRAIL (7) +#define MIPI_PHY_TCLKPOST (19) +#define MIPI_PHY_TCLKPRE (1) +#define MIPI_PHY_TCLKZERO (27) +#define MIPI_PHY_THSEXIT (11) +#define MIPI_PHY_THSTRAIL (8) +#define MIPI_PHY_THSZERO (19) +#define MIPI_PHY_TLPEXIT (7) +#define LP_DIVISOR (4) +#define PLL_MUL_SETTING (49) +#define VIDEO_MODE_DELAY (186) +#define ULPS_WAKEUP_PERIOD (97) +struct mipi_dsi_renesas_ra_config { + const struct device *clock_dev; + struct clock_control_ra_subsys_cfg clock_dsi_subsys; + void (*irq_configure)(void); +}; + +struct mipi_dsi_renesas_ra_data { + mipi_dsi_instance_ctrl_t mipi_dsi_ctrl; + mipi_dsi_cfg_t mipi_dsi_cfg; + volatile bool message_sent; + volatile bool fatal_error; +}; + +void mipi_dsi_seq0(void); +void mipi_dsi_ferr(void); +void mipi_dsi_callback(mipi_dsi_callback_args_t *p_args); + +typedef struct { + unsigned char size; + unsigned char buffer[256]; + mipi_dsi_cmd_id_t cmd_id; + mipi_dsi_cmd_flag_t flags; +} lcd_table_setting_t; + +void mipi_dsi_callback(mipi_dsi_callback_args_t *p_args) +{ + const struct device *dev = (struct device *)p_args->p_context; + struct mipi_dsi_renesas_ra_data *data = dev->data; + + switch (p_args->event) { + case MIPI_DSI_EVENT_SEQUENCE_0: { + if (MIPI_DSI_SEQUENCE_STATUS_DESCRIPTORS_FINISHED == p_args->tx_status) { + data->message_sent = true; + } + break; + } + case MIPI_DSI_EVENT_FATAL: { + data->fatal_error = true; + break; + } + default: { + break; + } + } +} + +static int mipi_dsi_renesas_ra_attach(const struct device *dev, uint8_t channel, + const struct mipi_dsi_device *mdev) +{ + struct mipi_dsi_renesas_ra_data *data = dev->data; + mipi_dsi_cfg_t cfg = data->mipi_dsi_cfg; + int ret; + + if (!(mdev->mode_flags & MIPI_DSI_MODE_VIDEO)) { + LOG_ERR("DSI host supports video mode only!"); + return -ENOTSUP; + } + cfg.virtual_channel_id = channel; + cfg.num_lanes = mdev->data_lanes; + if (mdev->pixfmt == MIPI_DSI_PIXFMT_RGB888) { + cfg.data_type = MIPI_DSI_VIDEO_DATA_24RGB_PIXEL_STREAM; + } else if (mdev->pixfmt == MIPI_DSI_PIXFMT_RGB565) { + cfg.data_type = MIPI_DSI_VIDEO_DATA_16RGB_PIXEL_STREAM; + } + cfg.horizontal_active_lines = mdev->timings.hactive; + cfg.horizontal_front_porch = mdev->timings.hfp; + cfg.horizontal_back_porch = mdev->timings.hbp; + cfg.horizontal_sync_lines = mdev->timings.hsync; + + cfg.vertical_active_lines = mdev->timings.vactive; + cfg.vertical_front_porch = mdev->timings.vfp; + cfg.vertical_back_porch = mdev->timings.vbp; + cfg.vertical_sync_lines = mdev->timings.vsync; + + ret = R_MIPI_DSI_Open(&data->mipi_dsi_ctrl, &cfg); + if (ret) { + LOG_ERR("Open DSI failed (%d)", ret); + return -EIO; + } + + ret = R_MIPI_DSI_Start(&data->mipi_dsi_ctrl); + if (ret) { + LOG_ERR("Start DSI host failed! (%d)", ret); + return -EIO; + } + + return 0; +} + +static ssize_t mipi_dsi_renesas_ra_transfer(const struct device *dev, uint8_t channel, + struct mipi_dsi_msg *msg) +{ + struct mipi_dsi_renesas_ra_data *data = dev->data; + ssize_t len; + int ret; + uint8_t combined_tx_buffer[msg->tx_len + 1]; + + combined_tx_buffer[0] = msg->cmd; + memcpy(&combined_tx_buffer[1], msg->tx_buf, msg->tx_len); + + mipi_dsi_cmd_t fsp_msg = { + .channel = channel, + .cmd_id = msg->type, + .flags = MIPI_DSI_CMD_FLAG_LOW_POWER, + .tx_len = msg->tx_len + 1, + .p_tx_buffer = combined_tx_buffer, + }; + data->message_sent = false; + data->fatal_error = false; + + switch (msg->type) { + case MIPI_DSI_DCS_READ: + LOG_ERR("DCS Read not yet implemented or used"); + return -ENOTSUP; + case MIPI_DSI_DCS_SHORT_WRITE: + case MIPI_DSI_DCS_SHORT_WRITE_PARAM: + case MIPI_DSI_DCS_LONG_WRITE: + ret = R_MIPI_DSI_Command(&data->mipi_dsi_ctrl, &fsp_msg); + if (ret) { + LOG_ERR("DSI write fail: err: (%d)", ret); + return -EIO; + } + while (!(data->message_sent)) { + if (data->fatal_error) { + LOG_ERR("fatal error"); + return -EIO; + } + } + len = msg->tx_len; + break; + default: + LOG_ERR("Unsupported message type (%d)", msg->type); + return -ENOTSUP; + } + + return len; +} + +static DEVICE_API(mipi_dsi, mipi_dsi_api) = { + .attach = mipi_dsi_renesas_ra_attach, + .transfer = mipi_dsi_renesas_ra_transfer, +}; + +static int mipi_dsi_renesas_ra_init(const struct device *dev) +{ + const struct mipi_dsi_renesas_ra_config *config = dev->config; + struct mipi_dsi_renesas_ra_data *data = dev->data; + int ret; + + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + + ret = clock_control_on(config->clock_dev, + (clock_control_subsys_t)&config->clock_dsi_subsys); + if (ret) { + LOG_ERR("Enable DSI peripheral clock failed! (%d)", ret); + return ret; + } + + config->irq_configure(); + data->mipi_dsi_cfg.p_context = dev; + + return 0; +} + +#define IRQ_CONFIGURE_FUNC(id) \ + static void mipi_dsi_ra_configure_func_##id(void) \ + { \ + R_ICU->IELSR[DT_INST_IRQ_BY_NAME(id, sq0, irq)] = ELC_EVENT_MIPIDSI_SEQ0; \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(id, sq0, irq), \ + DT_INST_IRQ_BY_NAME(id, sq0, priority), mipi_dsi_seq0, \ + DEVICE_DT_INST_GET(id), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(id, sq0, irq)); \ + R_ICU->IELSR[DT_INST_IRQ_BY_NAME(id, ferr, irq)] = ELC_EVENT_MIPIDSI_FERR; \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(id, ferr, irq), \ + DT_INST_IRQ_BY_NAME(id, ferr, priority), mipi_dsi_ferr, \ + DEVICE_DT_INST_GET(id), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(id, ferr, irq)); \ + } + +#define IRQ_CONFIGURE_DEFINE(id) .irq_configure = mipi_dsi_ra_configure_func_##id + +#define RENESAS_MIPI_DSI_DEVICE(id) \ + IRQ_CONFIGURE_FUNC(id) \ + mipi_phy_ctrl_t mipi_phy_##id##_ctrl; \ + static const mipi_phy_timing_t mipi_phy_##id##_timing = { \ + .t_init = 0x3FFFF & (uint32_t)MIPI_PHY_TINIT, \ + .t_clk_prep = (uint8_t)MIPI_PHY_TCLKPREP, \ + .t_hs_prep = (uint8_t)MIPI_PHY_THSPREP, \ + .dphytim4_b.t_clk_trail = (uint32_t)MIPI_PHY_TCLKTRAIL, \ + .dphytim4_b.t_clk_post = (uint32_t)MIPI_PHY_TCLKPOST, \ + .dphytim4_b.t_clk_pre = (uint32_t)MIPI_PHY_TCLKPRE, \ + .dphytim4_b.t_clk_zero = (uint32_t)MIPI_PHY_TCLKZERO, \ + .dphytim5_b.t_hs_exit = (uint32_t)MIPI_PHY_THSEXIT, \ + .dphytim5_b.t_hs_trail = (uint32_t)MIPI_PHY_THSTRAIL, \ + .dphytim5_b.t_hs_zero = (uint32_t)MIPI_PHY_THSZERO, \ + .t_lp_exit = (uint32_t)MIPI_PHY_TLPEXIT, \ + }; \ + static const mipi_phy_cfg_t mipi_phy_##id##_cfg = { \ + .pll_settings = {.div = 0, .mul_int = PLL_MUL_SETTING, .mul_frac = 0}, \ + .lp_divisor = LP_DIVISOR, \ + .p_timing = &mipi_phy_##id##_timing, \ + }; \ + static const mipi_phy_instance_t mipi_phy##id = { \ + .p_ctrl = &mipi_phy_##id##_ctrl, \ + .p_cfg = &mipi_phy_##id##_cfg, \ + .p_api = &g_mipi_phy, \ + }; \ + static const mipi_dsi_extended_cfg_t mipi_dsi_##id##_extended_cfg = { \ + .dsi_seq0.ipl = DT_INST_IRQ_BY_NAME(id, sq0, priority), \ + .dsi_seq0.irq = DT_INST_IRQ_BY_NAME(id, sq0, irq), \ + .dsi_seq1.ipl = DT_INST_IRQ_BY_NAME(id, sq1, priority), \ + .dsi_seq1.irq = DT_INST_IRQ_BY_NAME(id, sq1, irq), \ + .dsi_vin1.ipl = DT_INST_IRQ_BY_NAME(id, vm, priority), \ + .dsi_vin1.irq = DT_INST_IRQ_BY_NAME(id, vm, irq), \ + .dsi_rcv.ipl = DT_INST_IRQ_BY_NAME(id, rcv, priority), \ + .dsi_rcv.irq = DT_INST_IRQ_BY_NAME(id, rcv, irq), \ + .dsi_ferr.ipl = DT_INST_IRQ_BY_NAME(id, ferr, priority), \ + .dsi_ferr.irq = DT_INST_IRQ_BY_NAME(id, ferr, irq), \ + .dsi_ppi.ipl = DT_INST_IRQ_BY_NAME(id, ppi, priority), \ + .dsi_ppi.irq = DT_INST_IRQ_BY_NAME(id, ppi, irq), \ + .dsi_rxie = R_DSILINK_RXIER_BTAREND_Msk | R_DSILINK_RXIER_LRXHTO_Msk | \ + R_DSILINK_RXIER_TATO_Msk | R_DSILINK_RXIER_RXRESP_Msk | \ + R_DSILINK_RXIER_RXEOTP_Msk | R_DSILINK_RXIER_RXTE_Msk | \ + R_DSILINK_RXIER_RXACK_Msk | R_DSILINK_RXIER_EXTEDET_Msk | \ + R_DSILINK_RXIER_MLFERR_Msk | R_DSILINK_RXIER_ECCERRM_Msk | \ + R_DSILINK_RXIER_UNEXERR_Msk | R_DSILINK_RXIER_WCERR_Msk | \ + R_DSILINK_RXIER_CRCERR_Msk | R_DSILINK_RXIER_IBERR_Msk | \ + R_DSILINK_RXIER_RXOVFERR_Msk | R_DSILINK_RXIER_PRTOERR_Msk | \ + R_DSILINK_RXIER_NORESERR_Msk | R_DSILINK_RXIER_RSIZEERR_Msk | \ + R_DSILINK_RXIER_ECCERRS_Msk | R_DSILINK_RXIER_RXAKE_Msk | 0x0, \ + .dsi_ferrie = R_DSILINK_FERRIER_HTXTO_Msk | R_DSILINK_FERRIER_LRXHTO_Msk | \ + R_DSILINK_FERRIER_TATO_Msk | R_DSILINK_FERRIER_ESCENT_Msk | \ + R_DSILINK_FERRIER_SYNCESC_Msk | R_DSILINK_FERRIER_CTRL_Msk | \ + R_DSILINK_FERRIER_CLP0_Msk | R_DSILINK_FERRIER_CLP1_Msk | 0x0, \ + .dsi_plie = R_DSILINK_PLIER_DLULPENT_Msk | R_DSILINK_PLIER_DLULPEXT_Msk | 0x0, \ + .dsi_vmie = R_DSILINK_VMIER_VBUFUDF_Msk | R_DSILINK_VMIER_VBUFOVF_Msk | 0x0, \ + .dsi_sqch0ie = R_DSILINK_SQCH0IER_AACTFIN_Msk | R_DSILINK_SQCH0IER_ADESFIN_Msk | \ + R_DSILINK_SQCH0IER_TXIBERR_Msk | R_DSILINK_SQCH0IER_RXFERR_Msk | \ + R_DSILINK_SQCH0IER_RXFAIL_Msk | R_DSILINK_SQCH0IER_RXPFAIL_Msk | \ + R_DSILINK_SQCH0IER_RXCORERR_Msk | R_DSILINK_SQCH0IER_RXAKE_Msk | \ + 0x0, \ + .dsi_sqch1ie = R_DSILINK_SQCH1IER_AACTFIN_Msk | R_DSILINK_SQCH1IER_ADESFIN_Msk | \ + R_DSILINK_SQCH1IER_SIZEERR_Msk | R_DSILINK_SQCH1IER_TXIBERR_Msk | \ + R_DSILINK_SQCH1IER_RXFERR_Msk | R_DSILINK_SQCH1IER_RXFAIL_Msk | \ + R_DSILINK_SQCH1IER_RXPFAIL_Msk | R_DSILINK_SQCH1IER_RXCORERR_Msk | \ + R_DSILINK_SQCH1IER_RXAKE_Msk | 0x0, \ + }; \ + static const mipi_dsi_timing_t mipi_dsi_##id##_timing = { \ + .clock_stop_time = MIPI_PHY_CLKSTPT, \ + .clock_beforehand_time = MIPI_PHY_CLKBFHT, \ + .clock_keep_time = MIPI_PHY_CLKKPT, \ + .go_lp_and_back = MIPI_PHY_GOLPBKT, \ + }; \ + static const struct mipi_dsi_renesas_ra_config ra_config_##id = { \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \ + IRQ_CONFIGURE_DEFINE(id), \ + .clock_dsi_subsys = {.mstp = (uint32_t)DT_INST_CLOCKS_CELL_BY_IDX(id, 0, mstp), \ + .stop_bit = DT_INST_CLOCKS_CELL_BY_IDX(id, 0, stop_bit)}}; \ + static struct mipi_dsi_renesas_ra_data ra_data_##id = { \ + .mipi_dsi_cfg = \ + { \ + .p_mipi_phy_instance = &mipi_phy##id, \ + .p_timing = &mipi_dsi_##id##_timing, \ + .sync_pulse = (0), \ + .data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24, \ + .vertical_sync_polarity = 1, \ + .horizontal_sync_polarity = 1, \ + .video_mode_delay = VIDEO_MODE_DELAY, \ + .hsa_no_lp = ((0x0) & R_DSILINK_VMSET0R_HSANOLP_Msk), \ + .hbp_no_lp = ((0x0) & R_DSILINK_VMSET0R_HBPNOLP_Msk), \ + .hfp_no_lp = ((0x0) & R_DSILINK_VMSET0R_HFPNOLP_Msk), \ + .num_lanes = \ + DT_PROP_BY_IDX(DT_NODELABEL(ili9806e), data_lanes, 0), \ + .ulps_wakeup_period = ULPS_WAKEUP_PERIOD, \ + .continuous_clock = (1), \ + .hs_tx_timeout = 0, \ + .lp_rx_timeout = 0, \ + .turnaround_timeout = 0, \ + .bta_timeout = 0, \ + .lprw_timeout = (0 << R_DSILINK_PRESPTOLPSETR_LPRTO_Pos) | 0, \ + .hsrw_timeout = (0 << R_DSILINK_PRESPTOHSSETR_HSRTO_Pos) | 0, \ + .max_return_packet_size = 1, \ + .ecc_enable = (1), \ + .crc_check_mask = (mipi_dsi_vc_t)(0x0), \ + .scramble_enable = (0), \ + .tearing_detect = (0), \ + .eotp_enable = (1), \ + .p_extend = &mipi_dsi_##id##_extended_cfg, \ + .p_callback = mipi_dsi_callback, \ + .p_context = NULL, \ + }, \ + }; \ + DEVICE_DT_INST_DEFINE(id, &mipi_dsi_renesas_ra_init, NULL, &ra_data_##id, &ra_config_##id, \ + POST_KERNEL, CONFIG_MIPI_DSI_INIT_PRIORITY, &mipi_dsi_api); + +DT_INST_FOREACH_STATUS_OKAY(RENESAS_MIPI_DSI_DEVICE) diff --git a/drivers/misc/CMakeLists.txt b/drivers/misc/CMakeLists.txt index f1453a8c28494..320358adc8d42 100644 --- a/drivers/misc/CMakeLists.txt +++ b/drivers/misc/CMakeLists.txt @@ -9,4 +9,5 @@ add_subdirectory_ifdef(CONFIG_TIMEAWARE_GPIO timeaware_gpio) add_subdirectory_ifdef(CONFIG_DEVMUX devmux) add_subdirectory_ifdef(CONFIG_NORDIC_VPR_LAUNCHER nordic_vpr_launcher) add_subdirectory_ifdef(CONFIG_MCUX_FLEXIO mcux_flexio) +add_subdirectory_ifdef(CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT renesas_ra_external_interrupt) add_subdirectory(coresight) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1202a360ae1f5..a0baae98bde51 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -14,5 +14,6 @@ source "drivers/misc/devmux/Kconfig" source "drivers/misc/nordic_vpr_launcher/Kconfig" source "drivers/misc/mcux_flexio/Kconfig" source "drivers/misc/coresight/Kconfig" +source "drivers/misc/renesas_ra_external_interrupt/Kconfig" endmenu diff --git a/drivers/misc/coresight/nrf_etr.c b/drivers/misc/coresight/nrf_etr.c index a9179a951094e..11d2240d86160 100644 --- a/drivers/misc/coresight/nrf_etr.c +++ b/drivers/misc/coresight/nrf_etr.c @@ -97,6 +97,7 @@ BUILD_ASSERT((DT_REG_ADDR(ETR_BUFFER_NODE) % CONFIG_DCACHE_LINE_SIZE) == 0); /* Domain details and prefixes. */ static const uint16_t stm_m_id[] = {0x21, 0x22, 0x23, 0x2c, 0x2d, 0x2e, 0x24, 0x80}; +static uint32_t source_id_buf[ARRAY_SIZE(stm_m_id) * 8]; static const char *const stm_m_name[] = {"sec", "app", "rad", "sys", "flpr", "ppr", "mod", "hw"}; static const char *const hw_evts[] = { "CTI211_0", /* 0 CTI211 triger out 1 */ @@ -196,17 +197,36 @@ static void log_message_process(struct log_frontend_stmesp_demux_log *packet) /** @brief Process a trace point message. */ static void trace_point_process(struct log_frontend_stmesp_demux_trace_point *packet) { - static const uint32_t flags = LOG_OUTPUT_FLAG_TIMESTAMP | LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP; + static const uint32_t flags = LOG_OUTPUT_FLAG_TIMESTAMP | LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP | + LOG_OUTPUT_FLAG_LEVEL; static const char *tp = "%d"; static const char *tp_d32 = "%d %08x"; const char *dname = stm_m_name[packet->major]; static const char *sname = "tp"; - - if (packet->has_data) { + const char **lptr; + + if (packet->id >= CONFIG_LOG_FRONTEND_STMESP_TURBO_LOG_BASE) { + TYPE_SECTION_GET(const char *, log_stmesp_ptr, + packet->id - CONFIG_LOG_FRONTEND_STMESP_TURBO_LOG_BASE, &lptr); + uint8_t level = (uint8_t)((*lptr)[0]) - (uint8_t)'0'; + const char *ptr = *lptr + 1; + static const union cbprintf_package_hdr desc0 = { + .desc = {.len = 2 /* hdr + fmt */}}; + static const union cbprintf_package_hdr desc1 = { + .desc = {.len = 3 /* hdr + fmt + data */}}; + uint32_t tp_log[] = {packet->has_data ? (uint32_t)desc1.raw : (uint32_t)desc0.raw, + (uint32_t)ptr, packet->data}; + const char *source = + log_frontend_stmesp_demux_sname_get(packet->major, packet->source_id); + + log_output_process(&log_output, packet->timestamp, dname, source, NULL, level, + (const uint8_t *)tp_log, NULL, 0, flags); + return; + } else if (packet->has_data) { + uint32_t id = (uint32_t)packet->id - CONFIG_LOG_FRONTEND_STMESP_TP_CHAN_BASE; static const union cbprintf_package_hdr desc = { .desc = {.len = 4 /* hdr + fmt + id + data */}}; - uint32_t tp_d32_p[] = {(uint32_t)desc.raw, (uint32_t)tp_d32, packet->id, - packet->data}; + uint32_t tp_d32_p[] = {(uint32_t)desc.raw, (uint32_t)tp_d32, id, packet->data}; log_output_process(&log_output, packet->timestamp, dname, sname, NULL, 1, (const uint8_t *)tp_d32_p, NULL, 0, flags); @@ -368,7 +388,16 @@ static void decoder_cb(enum mipi_stp_decoder_ctrl_type type, } break; case STP_DATA16: - log_frontend_stmesp_demux_data((char *)&data.data, 2); + if (marked) { + if (ts) { + rv = log_frontend_stmesp_demux_log0((uint16_t)data.data, ts); + new_msg_cnt += rv; + } else { + log_frontend_stmesp_demux_source_id((uint16_t)data.data); + } + } else { + log_frontend_stmesp_demux_data((char *)&data.data, 2); + } break; case STP_DATA32: if (marked) { @@ -584,8 +613,11 @@ static int decoder_init(void) once = true; if (IS_ENABLED(CONFIG_NRF_ETR_DECODE)) { - static const struct log_frontend_stmesp_demux_config config = {.m_ids = stm_m_id, - .m_ids_cnt = ARRAY_SIZE(stm_m_id)}; + static const struct log_frontend_stmesp_demux_config config = { + .m_ids = stm_m_id, + .m_ids_cnt = ARRAY_SIZE(stm_m_id), + .source_id_buf = source_id_buf, + .source_id_buf_len = ARRAY_SIZE(source_id_buf)}; err = log_frontend_stmesp_demux_init(&config); if (err < 0) { diff --git a/drivers/misc/devmux/devmux.c b/drivers/misc/devmux/devmux.c index d8c1a9b90c74e..b01ebdae45f78 100644 --- a/drivers/misc/devmux/devmux.c +++ b/drivers/misc/devmux/devmux.c @@ -148,11 +148,8 @@ static int devmux_init(struct device *const dev) return 0; } -#define DEVMUX_PHANDLE_TO_DEVICE(node_id, prop, idx) \ - DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)) - #define DEVMUX_PHANDLE_DEVICES(_n) \ - DT_INST_FOREACH_PROP_ELEM_SEP(_n, devices, DEVMUX_PHANDLE_TO_DEVICE, (,)) + DT_INST_FOREACH_PROP_ELEM_SEP(_n, devices, DEVICE_DT_GET_BY_IDX, (,)) #define DEVMUX_SELECTED(_n) DT_INST_PROP(_n, selected) diff --git a/drivers/misc/ft8xx/ft8xx.c b/drivers/misc/ft8xx/ft8xx.c index 1dcbe581b13e4..a77eb0016edc1 100644 --- a/drivers/misc/ft8xx/ft8xx.c +++ b/drivers/misc/ft8xx/ft8xx.c @@ -20,6 +20,7 @@ #include #include +#include "ft8xx_dev_data.h" #include "ft8xx_drv.h" #include "ft8xx_host_commands.h" @@ -46,38 +47,11 @@ struct ft8xx_config { uint8_t swizzle :4; }; -struct ft8xx_data { - const struct ft8xx_config *config; - ft8xx_int_callback irq_callback; -}; - -const static struct ft8xx_config ft8xx_config = { - .pclk = DT_INST_PROP(0, pclk), - .pclk_pol = DT_INST_PROP(0, pclk_pol), - .cspread = DT_INST_PROP(0, cspread), - .swizzle = DT_INST_PROP(0, swizzle), - .vsize = DT_INST_PROP(0, vsize), - .voffset = DT_INST_PROP(0, voffset), - .vcycle = DT_INST_PROP(0, vcycle), - .vsync0 = DT_INST_PROP(0, vsync0), - .vsync1 = DT_INST_PROP(0, vsync1), - .hsize = DT_INST_PROP(0, hsize), - .hoffset = DT_INST_PROP(0, hoffset), - .hcycle = DT_INST_PROP(0, hcycle), - .hsync0 = DT_INST_PROP(0, hsync0), - .hsync1 = DT_INST_PROP(0, hsync1), -}; - -static struct ft8xx_data ft8xx_data = { - .config = &ft8xx_config, - .irq_callback = NULL, -}; - -static void host_command(uint8_t cmd) +static void host_command(const struct device *dev, uint8_t cmd) { int err; - err = ft8xx_drv_command(cmd); + err = ft8xx_drv_command(dev, cmd); __ASSERT(err == 0, "Writing FT8xx command failed"); } @@ -86,9 +60,9 @@ static void wait(void) k_sleep(K_MSEC(20)); } -static bool verify_chip(void) +static bool verify_chip(const struct device *dev) { - uint32_t id = ft8xx_rd32(FT800_REG_ID); + uint32_t id = ft8xx_rd32(dev, FT800_REG_ID); return (id & 0xff) == FT8XX_EXPECTED_ID; } @@ -97,131 +71,167 @@ static int ft8xx_init(const struct device *dev) { int ret; const struct ft8xx_config *config = dev->config; + struct ft8xx_data *data = dev->data; + + data->ft8xx_dev = dev; - ret = ft8xx_drv_init(); + ret = ft8xx_drv_init(dev); if (ret < 0) { LOG_ERR("FT8xx driver initialization failed with %d", ret); return ret; } /* Reset display controller */ - host_command(CORERST); - host_command(ACTIVE); + host_command(dev, CORERST); + host_command(dev, ACTIVE); wait(); - host_command(CLKEXT); - host_command(CLK48M); + host_command(dev, CLKEXT); + host_command(dev, CLK48M); wait(); - host_command(CORERST); - host_command(ACTIVE); + host_command(dev, CORERST); + host_command(dev, ACTIVE); wait(); - host_command(CLKEXT); - host_command(CLK48M); + host_command(dev, CLKEXT); + host_command(dev, CLK48M); wait(); - if (!verify_chip()) { + if (!verify_chip(dev)) { LOG_ERR("FT8xx chip not recognized"); return -ENODEV; } /* Disable LCD */ - ft8xx_wr8(FT800_REG_GPIO, 0); - ft8xx_wr8(FT800_REG_PCLK, 0); + ft8xx_wr8(dev, FT800_REG_GPIO, 0); + ft8xx_wr8(dev, FT800_REG_PCLK, 0); /* Configure LCD */ - ft8xx_wr16(FT800_REG_HSIZE, config->hsize); - ft8xx_wr16(FT800_REG_HCYCLE, config->hcycle); - ft8xx_wr16(FT800_REG_HOFFSET, config->hoffset); - ft8xx_wr16(FT800_REG_HSYNC0, config->hsync0); - ft8xx_wr16(FT800_REG_HSYNC1, config->hsync1); - ft8xx_wr16(FT800_REG_VSIZE, config->vsize); - ft8xx_wr16(FT800_REG_VCYCLE, config->vcycle); - ft8xx_wr16(FT800_REG_VOFFSET, config->voffset); - ft8xx_wr16(FT800_REG_VSYNC0, config->vsync0); - ft8xx_wr16(FT800_REG_VSYNC1, config->vsync1); - ft8xx_wr8(FT800_REG_SWIZZLE, config->swizzle); - ft8xx_wr8(FT800_REG_PCLK_POL, config->pclk_pol); - ft8xx_wr8(FT800_REG_CSPREAD, config->cspread); + ft8xx_wr16(dev, FT800_REG_HSIZE, config->hsize); + ft8xx_wr16(dev, FT800_REG_HCYCLE, config->hcycle); + ft8xx_wr16(dev, FT800_REG_HOFFSET, config->hoffset); + ft8xx_wr16(dev, FT800_REG_HSYNC0, config->hsync0); + ft8xx_wr16(dev, FT800_REG_HSYNC1, config->hsync1); + ft8xx_wr16(dev, FT800_REG_VSIZE, config->vsize); + ft8xx_wr16(dev, FT800_REG_VCYCLE, config->vcycle); + ft8xx_wr16(dev, FT800_REG_VOFFSET, config->voffset); + ft8xx_wr16(dev, FT800_REG_VSYNC0, config->vsync0); + ft8xx_wr16(dev, FT800_REG_VSYNC1, config->vsync1); + ft8xx_wr8(dev, FT800_REG_SWIZZLE, config->swizzle); + ft8xx_wr8(dev, FT800_REG_PCLK_POL, config->pclk_pol); + ft8xx_wr8(dev, FT800_REG_CSPREAD, config->cspread); /* Display initial screen */ /* Set the initial color */ - ft8xx_wr32(FT800_RAM_DL + 0, FT8XX_CLEAR_COLOR_RGB(0, 0x80, 0)); + ft8xx_wr32(dev, FT800_RAM_DL + 0, FT8XX_CLEAR_COLOR_RGB(0, 0x80, 0)); /* Clear to the initial color */ - ft8xx_wr32(FT800_RAM_DL + 4, FT8XX_CLEAR(1, 1, 1)); + ft8xx_wr32(dev, FT800_RAM_DL + 4, FT8XX_CLEAR(1, 1, 1)); /* End the display list */ - ft8xx_wr32(FT800_RAM_DL + 8, FT8XX_DISPLAY()); - ft8xx_wr8(FT800_REG_DLSWAP, FT8XX_DLSWAP_FRAME); + ft8xx_wr32(dev, FT800_RAM_DL + 8, FT8XX_DISPLAY()); + ft8xx_wr8(dev, FT800_REG_DLSWAP, FT8XX_DLSWAP_FRAME); /* Enable LCD */ /* Enable display bit */ - ft8xx_wr8(FT800_REG_GPIO_DIR, 0x80); - ft8xx_wr8(FT800_REG_GPIO, 0x80); + ft8xx_wr8(dev, FT800_REG_GPIO_DIR, 0x80); + ft8xx_wr8(dev, FT800_REG_GPIO, 0x80); /* Enable backlight */ - ft8xx_wr16(FT800_REG_PWM_HZ, 0x00FA); - ft8xx_wr8(FT800_REG_PWM_DUTY, 0x10); + ft8xx_wr16(dev, FT800_REG_PWM_HZ, 0x00FA); + ft8xx_wr8(dev, FT800_REG_PWM_DUTY, 0x10); /* Enable LCD signals */ - ft8xx_wr8(FT800_REG_PCLK, config->pclk); + ft8xx_wr8(dev, FT800_REG_PCLK, config->pclk); return 0; } -DEVICE_DT_INST_DEFINE(0, ft8xx_init, NULL, &ft8xx_data, &ft8xx_config, - POST_KERNEL, CONFIG_FT800_INIT_PRIORITY, NULL); - -int ft8xx_get_touch_tag(void) +int ft8xx_get_touch_tag(const struct device *dev) { /* Read FT800_REG_INT_FLAGS to clear IRQ */ - (void)ft8xx_rd8(FT800_REG_INT_FLAGS); + (void)ft8xx_rd8(dev, FT800_REG_INT_FLAGS); - return (int)ft8xx_rd8(FT800_REG_TOUCH_TAG); + return (int)ft8xx_rd8(dev, FT800_REG_TOUCH_TAG); } -void ft8xx_drv_irq_triggered(const struct device *dev, struct gpio_callback *cb, - uint32_t pins) +void ft8xx_drv_irq_triggered(const struct device *gpio_port, struct gpio_callback *cb, + uint32_t pins) { - if (ft8xx_data.irq_callback != NULL) { - ft8xx_data.irq_callback(); + struct ft8xx_data *ft8xx_data = CONTAINER_OF(cb, struct ft8xx_data, irq_cb_data); + const struct device *ft8xx_dev = ft8xx_data->ft8xx_dev; + + if (ft8xx_data->irq_callback != NULL) { + ft8xx_data->irq_callback(ft8xx_dev, ft8xx_data->irq_callback_ud); } } -void ft8xx_register_int(ft8xx_int_callback callback) +void ft8xx_register_int(const struct device *dev, ft8xx_int_callback callback, void *user_data) { - if (ft8xx_data.irq_callback != NULL) { + struct ft8xx_data *ft8xx_data = dev->data; + + if (ft8xx_data->irq_callback != NULL) { return; } - ft8xx_data.irq_callback = callback; - ft8xx_wr8(FT800_REG_INT_MASK, 0x04); - ft8xx_wr8(FT800_REG_INT_EN, 0x01); + ft8xx_data->irq_callback = callback; + ft8xx_data->irq_callback_ud = user_data; + ft8xx_wr8(dev, FT800_REG_INT_MASK, 0x04); + ft8xx_wr8(dev, FT800_REG_INT_EN, 0x01); } -void ft8xx_calibrate(struct ft8xx_touch_transform *data) +void ft8xx_calibrate(const struct device *dev, struct ft8xx_touch_transform *data) { uint32_t result = 0; do { - ft8xx_copro_cmd_dlstart(); - ft8xx_copro_cmd(FT8XX_CLEAR_COLOR_RGB(0x00, 0x00, 0x00)); - ft8xx_copro_cmd(FT8XX_CLEAR(1, 1, 1)); - ft8xx_copro_cmd_calibrate(&result); + ft8xx_copro_cmd_dlstart(dev); + ft8xx_copro_cmd(dev, FT8XX_CLEAR_COLOR_RGB(0x00, 0x00, 0x00)); + ft8xx_copro_cmd(dev, FT8XX_CLEAR(1, 1, 1)); + ft8xx_copro_cmd_calibrate(dev, &result); } while (result == 0); - data->a = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_A); - data->b = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_B); - data->c = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_C); - data->d = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_D); - data->e = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_E); - data->f = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_F); + data->a = ft8xx_rd32(dev, FT800_REG_TOUCH_TRANSFORM_A); + data->b = ft8xx_rd32(dev, FT800_REG_TOUCH_TRANSFORM_B); + data->c = ft8xx_rd32(dev, FT800_REG_TOUCH_TRANSFORM_C); + data->d = ft8xx_rd32(dev, FT800_REG_TOUCH_TRANSFORM_D); + data->e = ft8xx_rd32(dev, FT800_REG_TOUCH_TRANSFORM_E); + data->f = ft8xx_rd32(dev, FT800_REG_TOUCH_TRANSFORM_F); } -void ft8xx_touch_transform_set(const struct ft8xx_touch_transform *data) +void ft8xx_touch_transform_set(const struct device *dev, const struct ft8xx_touch_transform *data) { - ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_A, data->a); - ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_B, data->b); - ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_C, data->c); - ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_D, data->d); - ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_E, data->e); - ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_F, data->f); + ft8xx_wr32(dev, FT800_REG_TOUCH_TRANSFORM_A, data->a); + ft8xx_wr32(dev, FT800_REG_TOUCH_TRANSFORM_B, data->b); + ft8xx_wr32(dev, FT800_REG_TOUCH_TRANSFORM_C, data->c); + ft8xx_wr32(dev, FT800_REG_TOUCH_TRANSFORM_D, data->d); + ft8xx_wr32(dev, FT800_REG_TOUCH_TRANSFORM_E, data->e); + ft8xx_wr32(dev, FT800_REG_TOUCH_TRANSFORM_F, data->f); } + +#define FT8XX_DEVICE(idx) \ +const static struct ft8xx_config ft8xx_##idx##_config = { \ + .pclk = DT_INST_PROP(idx, pclk), \ + .pclk_pol = DT_INST_PROP(idx, pclk_pol), \ + .cspread = DT_INST_PROP(idx, cspread), \ + .swizzle = DT_INST_PROP(idx, swizzle), \ + .vsize = DT_INST_PROP(idx, vsize), \ + .voffset = DT_INST_PROP(idx, voffset), \ + .vcycle = DT_INST_PROP(idx, vcycle), \ + .vsync0 = DT_INST_PROP(idx, vsync0), \ + .vsync1 = DT_INST_PROP(idx, vsync1), \ + .hsize = DT_INST_PROP(idx, hsize), \ + .hoffset = DT_INST_PROP(idx, hoffset), \ + .hcycle = DT_INST_PROP(idx, hcycle), \ + .hsync0 = DT_INST_PROP(idx, hsync0), \ + .hsync1 = DT_INST_PROP(idx, hsync1), \ +}; \ +static struct ft8xx_data ft8xx_##idx##_data = { \ + .ft8xx_dev = NULL, \ + .irq_callback = NULL, \ + .irq_callback_ud = NULL, \ + \ + .spi = SPI_DT_SPEC_INST_GET(idx, SPI_WORD_SET(8) | SPI_OP_MODE_MASTER, 0), \ + .irq_gpio = GPIO_DT_SPEC_INST_GET(idx, irq_gpios), \ +}; \ +DEVICE_DT_INST_DEFINE(idx, ft8xx_init, NULL, &ft8xx_##idx##_data, &ft8xx_##idx##_config, \ + POST_KERNEL, CONFIG_FT800_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(FT8XX_DEVICE) diff --git a/drivers/misc/ft8xx/ft8xx_common.c b/drivers/misc/ft8xx/ft8xx_common.c index ebf2d11cd99a9..f35fbd72fe330 100644 --- a/drivers/misc/ft8xx/ft8xx_common.c +++ b/drivers/misc/ft8xx/ft8xx_common.c @@ -9,62 +9,62 @@ #include #include "ft8xx_drv.h" -void ft8xx_wr8(uint32_t address, uint8_t data) +void ft8xx_wr8(const struct device *dev, uint32_t address, uint8_t data) { int err; - err = ft8xx_drv_write(address, &data, sizeof(data)); + err = ft8xx_drv_write(dev, address, &data, sizeof(data)); __ASSERT(err == 0, "Writing FT8xx data at 0x%x failed", address); } -void ft8xx_wr16(uint32_t address, uint16_t data) +void ft8xx_wr16(const struct device *dev, uint32_t address, uint16_t data) { int err; uint8_t buffer[2]; *(uint16_t *)buffer = sys_cpu_to_le16(data); - err = ft8xx_drv_write(address, buffer, sizeof(buffer)); + err = ft8xx_drv_write(dev, address, buffer, sizeof(buffer)); __ASSERT(err == 0, "Writing FT8xx data at 0x%x failed", address); } -void ft8xx_wr32(uint32_t address, uint32_t data) +void ft8xx_wr32(const struct device *dev, uint32_t address, uint32_t data) { int err; uint8_t buffer[4]; *(uint32_t *)buffer = sys_cpu_to_le32(data); - err = ft8xx_drv_write(address, buffer, sizeof(buffer)); + err = ft8xx_drv_write(dev, address, buffer, sizeof(buffer)); __ASSERT(err == 0, "Writing FT8xx data at 0x%x failed", address); } -uint8_t ft8xx_rd8(uint32_t address) +uint8_t ft8xx_rd8(const struct device *dev, uint32_t address) { int err; uint8_t data = 0; - err = ft8xx_drv_read(address, &data, sizeof(data)); + err = ft8xx_drv_read(dev, address, &data, sizeof(data)); __ASSERT(err == 0, "Reading FT8xx data from 0x%x failed", address); return data; } -uint16_t ft8xx_rd16(uint32_t address) +uint16_t ft8xx_rd16(const struct device *dev, uint32_t address) { int err; uint8_t buffer[2] = {0}; - err = ft8xx_drv_read(address, buffer, sizeof(buffer)); + err = ft8xx_drv_read(dev, address, buffer, sizeof(buffer)); __ASSERT(err == 0, "Reading FT8xx data from 0x%x failed", address); return sys_le16_to_cpu(*(const uint16_t *)buffer); } -uint32_t ft8xx_rd32(uint32_t address) +uint32_t ft8xx_rd32(const struct device *dev, uint32_t address) { int err; uint8_t buffer[4] = {0}; - err = ft8xx_drv_read(address, buffer, sizeof(buffer)); + err = ft8xx_drv_read(dev, address, buffer, sizeof(buffer)); __ASSERT(err == 0, "Reading FT8xx data from 0x%x failed", address); return sys_le32_to_cpu(*(const uint32_t *)buffer); diff --git a/drivers/misc/ft8xx/ft8xx_copro.c b/drivers/misc/ft8xx/ft8xx_copro.c index d1f1f82c663ca..7b4c599cb077e 100644 --- a/drivers/misc/ft8xx/ft8xx_copro.c +++ b/drivers/misc/ft8xx/ft8xx_copro.c @@ -11,6 +11,7 @@ #include #include +#include "ft8xx_dev_data.h" #include "ft8xx_drv.h" #define FT800_RAM_CMD_SIZE 4096UL @@ -23,62 +24,72 @@ enum { CMD_CALIBRATE = 0xffffff15, } ft8xx_cmd; -static uint16_t reg_cmd_read; -static uint16_t reg_cmd_write; - -static uint16_t ram_cmd_fullness(void) +static uint16_t ram_cmd_fullness(const struct device *dev) { - return (reg_cmd_write - reg_cmd_read) % 4096UL; + const struct ft8xx_data *data = dev->data; + + return (data->reg_cmd_write - data->reg_cmd_read) % 4096UL; } -static uint16_t ram_cmd_freespace(void) +static uint16_t ram_cmd_freespace(const struct device *dev) { - return (FT800_RAM_CMD_SIZE - 4UL) - ram_cmd_fullness(); + return (FT800_RAM_CMD_SIZE - 4UL) - ram_cmd_fullness(dev); } -static void refresh_reg_cmd_read(void) +static void refresh_reg_cmd_read(const struct device *dev) { - reg_cmd_read = ft8xx_rd32(FT800_REG_CMD_READ); + struct ft8xx_data *data = dev->data; + + data->reg_cmd_read = ft8xx_rd32(dev, FT800_REG_CMD_READ); } -static void flush_reg_cmd_write(void) +static void flush_reg_cmd_write(const struct device *dev) { - ft8xx_wr32(FT800_REG_CMD_WRITE, reg_cmd_write); + struct ft8xx_data *data = dev->data; + + ft8xx_wr32(dev, FT800_REG_CMD_WRITE, data->reg_cmd_write); } -static void increase_reg_cmd_write(uint16_t value) +static void increase_reg_cmd_write(const struct device *dev, uint16_t value) { - reg_cmd_write = (reg_cmd_write + value) % FT800_RAM_CMD_SIZE; + struct ft8xx_data *data = dev->data; + + data->reg_cmd_write = (data->reg_cmd_write + value) % FT800_RAM_CMD_SIZE; } -void ft8xx_copro_cmd(uint32_t cmd) +void ft8xx_copro_cmd(const struct device *dev, uint32_t cmd) { - while (ram_cmd_freespace() < sizeof(cmd)) { - refresh_reg_cmd_read(); + struct ft8xx_data *data = dev->data; + + while (ram_cmd_freespace(dev) < sizeof(cmd)) { + refresh_reg_cmd_read(dev); } - ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, cmd); - increase_reg_cmd_write(sizeof(cmd)); + ft8xx_wr32(dev, FT800_RAM_CMD + data->reg_cmd_write, cmd); + increase_reg_cmd_write(dev, sizeof(cmd)); - flush_reg_cmd_write(); + flush_reg_cmd_write(dev); } -void ft8xx_copro_cmd_dlstart(void) +void ft8xx_copro_cmd_dlstart(const struct device *dev) { - ft8xx_copro_cmd(CMD_DLSTART); + ft8xx_copro_cmd(dev, CMD_DLSTART); } -void ft8xx_copro_cmd_swap(void) +void ft8xx_copro_cmd_swap(const struct device *dev) { - ft8xx_copro_cmd(CMD_SWAP); + ft8xx_copro_cmd(dev, CMD_SWAP); } -void ft8xx_copro_cmd_text(int16_t x, +void ft8xx_copro_cmd_text(const struct device *dev, + int16_t x, int16_t y, int16_t font, uint16_t options, const char *s) { + struct ft8xx_data *data = dev->data; + const uint16_t str_bytes = strlen(s) + 1; const uint16_t padding_bytes = (4 - (str_bytes % 4)) % 4; const uint16_t cmd_size = sizeof(CMD_TEXT) + @@ -89,37 +100,40 @@ void ft8xx_copro_cmd_text(int16_t x, str_bytes + padding_bytes; - while (ram_cmd_freespace() < cmd_size) { - refresh_reg_cmd_read(); + while (ram_cmd_freespace(dev) < cmd_size) { + refresh_reg_cmd_read(dev); } - ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_TEXT); - increase_reg_cmd_write(sizeof(CMD_TEXT)); + ft8xx_wr32(dev, FT800_RAM_CMD + data->reg_cmd_write, CMD_TEXT); + increase_reg_cmd_write(dev, sizeof(CMD_TEXT)); - ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, x); - increase_reg_cmd_write(sizeof(x)); + ft8xx_wr16(dev, FT800_RAM_CMD + data->reg_cmd_write, x); + increase_reg_cmd_write(dev, sizeof(x)); - ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, y); - increase_reg_cmd_write(sizeof(y)); + ft8xx_wr16(dev, FT800_RAM_CMD + data->reg_cmd_write, y); + increase_reg_cmd_write(dev, sizeof(y)); - ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, font); - increase_reg_cmd_write(sizeof(font)); + ft8xx_wr16(dev, FT800_RAM_CMD + data->reg_cmd_write, font); + increase_reg_cmd_write(dev, sizeof(font)); - ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, options); - increase_reg_cmd_write(sizeof(options)); + ft8xx_wr16(dev, FT800_RAM_CMD + data->reg_cmd_write, options); + increase_reg_cmd_write(dev, sizeof(options)); - (void)ft8xx_drv_write(FT800_RAM_CMD + reg_cmd_write, s, str_bytes); - increase_reg_cmd_write(str_bytes + padding_bytes); + (void)ft8xx_drv_write(dev, FT800_RAM_CMD + data->reg_cmd_write, (uint8_t *)s, str_bytes); + increase_reg_cmd_write(dev, str_bytes + padding_bytes); - flush_reg_cmd_write(); + flush_reg_cmd_write(dev); } -void ft8xx_copro_cmd_number(int16_t x, +void ft8xx_copro_cmd_number(const struct device *dev, + int16_t x, int16_t y, int16_t font, uint16_t options, int32_t n) { + struct ft8xx_data *data = dev->data; + const uint16_t cmd_size = sizeof(CMD_NUMBER) + sizeof(x) + sizeof(y) + @@ -127,53 +141,55 @@ void ft8xx_copro_cmd_number(int16_t x, sizeof(options) + sizeof(n); - while (ram_cmd_freespace() < cmd_size) { - refresh_reg_cmd_read(); + while (ram_cmd_freespace(dev) < cmd_size) { + refresh_reg_cmd_read(dev); } - ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_NUMBER); - increase_reg_cmd_write(sizeof(CMD_NUMBER)); + ft8xx_wr32(dev, FT800_RAM_CMD + data->reg_cmd_write, CMD_NUMBER); + increase_reg_cmd_write(dev, sizeof(CMD_NUMBER)); - ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, x); - increase_reg_cmd_write(sizeof(x)); + ft8xx_wr16(dev, FT800_RAM_CMD + data->reg_cmd_write, x); + increase_reg_cmd_write(dev, sizeof(x)); - ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, y); - increase_reg_cmd_write(sizeof(y)); + ft8xx_wr16(dev, FT800_RAM_CMD + data->reg_cmd_write, y); + increase_reg_cmd_write(dev, sizeof(y)); - ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, font); - increase_reg_cmd_write(sizeof(font)); + ft8xx_wr16(dev, FT800_RAM_CMD + data->reg_cmd_write, font); + increase_reg_cmd_write(dev, sizeof(font)); - ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, options); - increase_reg_cmd_write(sizeof(options)); + ft8xx_wr16(dev, FT800_RAM_CMD + data->reg_cmd_write, options); + increase_reg_cmd_write(dev, sizeof(options)); - ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, n); - increase_reg_cmd_write(sizeof(n)); + ft8xx_wr32(dev, FT800_RAM_CMD + data->reg_cmd_write, n); + increase_reg_cmd_write(dev, sizeof(n)); - flush_reg_cmd_write(); + flush_reg_cmd_write(dev); } -void ft8xx_copro_cmd_calibrate(uint32_t *result) +void ft8xx_copro_cmd_calibrate(const struct device *dev, uint32_t *result) { + struct ft8xx_data *data = dev->data; + const uint16_t cmd_size = sizeof(CMD_CALIBRATE) + sizeof(uint32_t); uint32_t result_address; - while (ram_cmd_freespace() < cmd_size) { - refresh_reg_cmd_read(); + while (ram_cmd_freespace(dev) < cmd_size) { + refresh_reg_cmd_read(dev); } - ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_CALIBRATE); - increase_reg_cmd_write(sizeof(CMD_CALIBRATE)); + ft8xx_wr32(dev, FT800_RAM_CMD + data->reg_cmd_write, CMD_CALIBRATE); + increase_reg_cmd_write(dev, sizeof(CMD_CALIBRATE)); - result_address = FT800_RAM_CMD + reg_cmd_write; - ft8xx_wr32(result_address, 1UL); - increase_reg_cmd_write(sizeof(uint32_t)); + result_address = FT800_RAM_CMD + data->reg_cmd_write; + ft8xx_wr32(dev, result_address, 1UL); + increase_reg_cmd_write(dev, sizeof(uint32_t)); - flush_reg_cmd_write(); + flush_reg_cmd_write(dev); /* Wait until calibration is finished. */ - while (ram_cmd_fullness() > 0) { - refresh_reg_cmd_read(); + while (ram_cmd_fullness(dev) > 0) { + refresh_reg_cmd_read(dev); } - *result = ft8xx_rd32(result_address); + *result = ft8xx_rd32(dev, result_address); } diff --git a/drivers/misc/ft8xx/ft8xx_dev_data.h b/drivers/misc/ft8xx/ft8xx_dev_data.h new file mode 100644 index 0000000000000..e459d37c4d522 --- /dev/null +++ b/drivers/misc/ft8xx/ft8xx_dev_data.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Hubert Miś + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief FT8XX device driver data structure + */ + +#ifndef ZEPHYR_DRIVERS_MISC_FT8XX_FT8XX_DEV_DATA_H_ +#define ZEPHYR_DRIVERS_MISC_FT8XX_FT8XX_DEV_DATA_H_ + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ft8xx_data { + const struct device *ft8xx_dev; /* Required for GPIO IRQ handling */ + ft8xx_int_callback irq_callback; + void *irq_callback_ud; + + const struct spi_dt_spec spi; + const struct gpio_dt_spec irq_gpio; + struct gpio_callback irq_cb_data; + + uint16_t reg_cmd_read; + uint16_t reg_cmd_write; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_DRIVERS_MISC_FT8XX_FT8XX_DEV_DATA_H_ */ diff --git a/drivers/misc/ft8xx/ft8xx_drv.c b/drivers/misc/ft8xx/ft8xx_drv.c index 93b2522937dd7..f392a79cd138c 100644 --- a/drivers/misc/ft8xx/ft8xx_drv.c +++ b/drivers/misc/ft8xx/ft8xx_drv.c @@ -6,6 +6,9 @@ #include "ft8xx_drv.h" +#include "ft8xx_dev_data.h" + +#include #include #include #include @@ -17,17 +20,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define DT_DRV_COMPAT ftdi_ft800 #define NODE_ID DT_INST(0, DT_DRV_COMPAT) -/* SPI device */ -static const struct spi_dt_spec spi = SPI_DT_SPEC_INST_GET(0, - SPI_WORD_SET(8) | SPI_OP_MODE_MASTER, - 0); - -/* GPIO int line */ -static const struct gpio_dt_spec irq_gpio = GPIO_DT_SPEC_INST_GET(0, irq_gpios); - -static struct gpio_callback irq_cb_data; - -__weak void ft8xx_drv_irq_triggered(const struct device *dev, +__weak void ft8xx_drv_irq_triggered(const struct device *gpio_port, struct gpio_callback *cb, uint32_t pins) { /* Intentionally empty */ @@ -51,43 +44,46 @@ static void insert_addr(uint32_t addr, uint8_t *buff) buff[2] = (addr) & 0xff; } -int ft8xx_drv_init(void) +int ft8xx_drv_init(const struct device *dev) { int ret; + struct ft8xx_data *data = dev->data; - if (!spi_is_ready_dt(&spi)) { - LOG_ERR("SPI bus %s not ready", spi.bus->name); + if (!spi_is_ready_dt(&data->spi)) { + LOG_ERR("SPI bus %s not ready", data->spi.bus->name); return -ENODEV; } /* TODO: Verify if such entry in DTS is present. * If not, use polling mode. */ - if (!gpio_is_ready_dt(&irq_gpio)) { - LOG_ERR("GPIO device %s is not ready", irq_gpio.port->name); + if (!gpio_is_ready_dt(&data->irq_gpio)) { + LOG_ERR("GPIO device %s is not ready", data->irq_gpio.port->name); return -ENODEV; } - ret = gpio_pin_configure_dt(&irq_gpio, GPIO_INPUT); + ret = gpio_pin_configure_dt(&data->irq_gpio, GPIO_INPUT); if (ret != 0) { return ret; } - ret = gpio_pin_interrupt_configure_dt(&irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + ret = gpio_pin_interrupt_configure_dt(&data->irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); if (ret != 0) { return ret; } - gpio_init_callback(&irq_cb_data, ft8xx_drv_irq_triggered, BIT(irq_gpio.pin)); - gpio_add_callback(irq_gpio.port, &irq_cb_data); + gpio_init_callback(&data->irq_cb_data, ft8xx_drv_irq_triggered, BIT(data->irq_gpio.pin)); + gpio_add_callback(data->irq_gpio.port, &data->irq_cb_data); return 0; } -int ft8xx_drv_write(uint32_t address, const uint8_t *data, unsigned int length) +int ft8xx_drv_write(const struct device *dev, uint32_t address, const uint8_t *data, + unsigned int length) { int ret; uint8_t addr_buf[ADDR_SIZE]; + const struct ft8xx_data *dev_data = dev->data; insert_addr(address, addr_buf); addr_buf[0] |= WRITE_OP; @@ -109,7 +105,7 @@ int ft8xx_drv_write(uint32_t address, const uint8_t *data, unsigned int length) .count = 2, }; - ret = spi_write_dt(&spi, &tx_bufs); + ret = spi_write_dt(&dev_data->spi, &tx_bufs); if (ret < 0) { LOG_ERR("SPI write error: %d", ret); } @@ -117,11 +113,12 @@ int ft8xx_drv_write(uint32_t address, const uint8_t *data, unsigned int length) return ret; } -int ft8xx_drv_read(uint32_t address, uint8_t *data, unsigned int length) +int ft8xx_drv_read(const struct device *dev, uint32_t address, uint8_t *data, unsigned int length) { int ret; uint8_t dummy_read_buf[ADDR_SIZE + DUMMY_READ_SIZE]; uint8_t addr_buf[ADDR_SIZE]; + const struct ft8xx_data *dev_data = dev->data; insert_addr(address, addr_buf); addr_buf[0] |= READ_OP; @@ -152,7 +149,7 @@ int ft8xx_drv_read(uint32_t address, uint8_t *data, unsigned int length) .count = 2, }; - ret = spi_transceive_dt(&spi, &tx_bufs, &rx_bufs); + ret = spi_transceive_dt(&dev_data->spi, &tx_bufs, &rx_bufs); if (ret < 0) { LOG_ERR("SPI transceive error: %d", ret); } @@ -160,9 +157,10 @@ int ft8xx_drv_read(uint32_t address, uint8_t *data, unsigned int length) return ret; } -int ft8xx_drv_command(uint8_t command) +int ft8xx_drv_command(const struct device *dev, uint8_t command) { int ret; + const struct ft8xx_data *dev_data = dev->data; /* Most commands include COMMAND_OP bit. ACTIVE power mode command is * an exception with value 0x00. */ @@ -178,7 +176,7 @@ int ft8xx_drv_command(uint8_t command) .count = 1, }; - ret = spi_write_dt(&spi, &tx_bufs); + ret = spi_write_dt(&dev_data->spi, &tx_bufs); if (ret < 0) { LOG_ERR("SPI command error: %d", ret); } diff --git a/drivers/misc/ft8xx/ft8xx_drv.h b/drivers/misc/ft8xx/ft8xx_drv.h index 46632f6964297..37461d40f327a 100644 --- a/drivers/misc/ft8xx/ft8xx_drv.h +++ b/drivers/misc/ft8xx/ft8xx_drv.h @@ -21,10 +21,11 @@ extern "C" { #endif -int ft8xx_drv_init(void); -int ft8xx_drv_read(uint32_t address, uint8_t *data, unsigned int length); -int ft8xx_drv_write(uint32_t address, const uint8_t *data, unsigned int length); -int ft8xx_drv_command(uint8_t command); +int ft8xx_drv_init(const struct device *dev); +int ft8xx_drv_read(const struct device *dev, uint32_t address, uint8_t *data, unsigned int length); +int ft8xx_drv_write(const struct device *dev, uint32_t address, const uint8_t *data, + unsigned int length); +int ft8xx_drv_command(const struct device *dev, uint8_t command); extern void ft8xx_drv_irq_triggered(const struct device *dev, struct gpio_callback *cb, uint32_t pins); diff --git a/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c b/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c index 2c2915a798438..5bd43f87fb914 100644 --- a/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c +++ b/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c @@ -7,6 +7,7 @@ #include +#include #include #include #include @@ -38,6 +39,11 @@ static int nordic_vpr_launcher_init(const struct device *dev) LOG_DBG("Loading VPR (%p) from %p to %p (%zu bytes)", config->vpr, (void *)config->src_addr, (void *)config->exec_addr, config->size); memcpy((void *)config->exec_addr, (void *)config->src_addr, config->size); +#if defined(CONFIG_DCACHE) + LOG_DBG("Writing back cache with loaded VPR (from %p %zu bytes)", + (void *)config->exec_addr, config->size); + sys_cache_data_flush_range((void *)config->exec_addr, config->size); +#endif } #endif diff --git a/drivers/misc/nxp_s32_emios/nxp_s32_emios.c b/drivers/misc/nxp_s32_emios/nxp_s32_emios.c index d22d94b301542..371dca15389b0 100644 --- a/drivers/misc/nxp_s32_emios/nxp_s32_emios.c +++ b/drivers/misc/nxp_s32_emios/nxp_s32_emios.c @@ -59,15 +59,10 @@ static int nxp_s32_emios_init(const struct device *dev) .enableGlobalTimeBase = true \ }; -#define NXP_S32_EMIOS_MASTER_BUS_VERIFY(node_id) \ - BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, period), \ - MIN_MASTER_BUS_PERIOD, MAX_MASTER_BUS_PERIOD), \ - "Node "DT_NODE_PATH(node_id)": period is out of range"); - #define NXP_S32_EMIOS_MASTER_BUS_CONFIG(node_id) \ { \ .hwChannel = DT_PROP(node_id, channel), \ - .defaultPeriod = DT_PROP(node_id, period), \ + .defaultPeriod = MAX_MASTER_BUS_PERIOD, \ .masterBusPrescaler = DT_PROP(node_id, prescaler) - 1, \ .allowDebugMode = DT_PROP(node_id, freeze), \ .masterMode = NXP_S32_EMIOS_MASTER_BUS_MODE(DT_STRING_TOKEN(node_id, mode)), \ @@ -75,8 +70,6 @@ static int nxp_s32_emios_init(const struct device *dev) }, #define NXP_S32_EMIOS_GENERATE_MASTER_BUS_CONFIG(n) \ - DT_FOREACH_CHILD_STATUS_OKAY(DT_INST_CHILD(n, master_bus), \ - NXP_S32_EMIOS_MASTER_BUS_VERIFY) \ const Emios_Ip_MasterBusConfigType nxp_s32_emios_##n##_master_bus_config[] = { \ DT_FOREACH_CHILD_STATUS_OKAY(DT_INST_CHILD(n, master_bus), \ NXP_S32_EMIOS_MASTER_BUS_CONFIG) \ diff --git a/drivers/misc/renesas_ra_external_interrupt/CMakeLists.txt b/drivers/misc/renesas_ra_external_interrupt/CMakeLists.txt new file mode 100644 index 0000000000000..043c23499e845 --- /dev/null +++ b/drivers/misc/renesas_ra_external_interrupt/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT renesas_ra_external_interrupt.c) diff --git a/drivers/misc/renesas_ra_external_interrupt/Kconfig b/drivers/misc/renesas_ra_external_interrupt/Kconfig new file mode 100644 index 0000000000000..e75b7c14b49fa --- /dev/null +++ b/drivers/misc/renesas_ra_external_interrupt/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Renesas RA External Interrupt Option + +config RENESAS_RA_EXTERNAL_INTERRUPT + bool "Renesas RA External Interrupt Driver" + depends on DT_HAS_RENESAS_RA_EXTERNAL_INTERRUPT_ENABLED + default y + help + Enable config options for Renesas RA external interrupt diff --git a/drivers/misc/renesas_ra_external_interrupt/renesas_ra_external_interrupt.c b/drivers/misc/renesas_ra_external_interrupt/renesas_ra_external_interrupt.c new file mode 100644 index 0000000000000..a8da3c622e35d --- /dev/null +++ b/drivers/misc/renesas_ra_external_interrupt/renesas_ra_external_interrupt.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_external_interrupt + +#include +#include +#include +#include +#include +#include + +enum ext_irq_trigger { + EXT_INTERRUPT_EDGE_FALLING = 0, + EXT_INTERRUPT_EDGE_RISING, + EXT_INTERRUPT_EDGE_BOTH, + EXT_INTERRUPT_EDGE_LOW_LEVEL, +}; + +enum ext_irq_sample_clock { + EXT_INTERRUPT_SAMPLE_CLOCK_DIV_1 = 0, + EXT_INTERRUPT_SAMPLE_CLOCK_DIV_8, + EXT_INTERRUPT_SAMPLE_CLOCK_DIV_32, + EXT_INTERRUPT_SAMPLE_CLOCK_DIV_64, +}; + +struct gpio_ra_irq_config { + mem_addr_t reg; + unsigned int channel; + enum ext_irq_trigger trigger; + enum ext_irq_sample_clock sample_clock; + bool digital_filter; + unsigned int irq; +}; + +struct gpio_ra_irq_data { + struct gpio_ra_callback callback; + struct k_sem irq_sem; +}; + +/** + * @brief setting interrupt for gpio input + * + * @param dev devive instance for gpio interrupt line + * @param callback setting context for the callback + * @retval 0 if success + * @retval -EBUSY if interrupt line is inuse + * @retval -ENOTSUP if interrupt mode is not supported + */ +int gpio_ra_interrupt_set(const struct device *dev, struct gpio_ra_callback *callback) +{ + const struct gpio_ra_irq_config *config = dev->config; + struct gpio_ra_irq_data *data = dev->data; + uint8_t irqcr = sys_read8(config->reg) & ~R_ICU_IRQCR_IRQMD_Msk; + + irq_disable(config->irq); + + if (callback->mode == GPIO_INT_MODE_LEVEL) { + if (callback->trigger != GPIO_INT_TRIG_LOW) { + return -ENOTSUP; + } + + irqcr |= (EXT_INTERRUPT_EDGE_LOW_LEVEL & R_ICU_IRQCR_IRQMD_Msk); + } else if (callback->mode == GPIO_INT_MODE_EDGE) { + switch (callback->trigger) { + case GPIO_INT_TRIG_LOW: + irqcr |= (EXT_INTERRUPT_EDGE_FALLING & R_ICU_IRQCR_IRQMD_Msk); + break; + case GPIO_INT_TRIG_HIGH: + irqcr |= (EXT_INTERRUPT_EDGE_RISING & R_ICU_IRQCR_IRQMD_Msk); + break; + case GPIO_INT_TRIG_BOTH: + irqcr |= (EXT_INTERRUPT_EDGE_BOTH & R_ICU_IRQCR_IRQMD_Msk); + break; + default: + return -ENOTSUP; + } + } else { + return -ENOTSUP; + } + + if (data->callback.port_num != callback->port_num || data->callback.pin != callback->pin) { + if (0 != k_sem_take(&data->irq_sem, K_NO_WAIT)) { + return -EBUSY; + } + } + + sys_write8(irqcr, config->reg); + data->callback = *callback; + irq_enable(config->irq); + + return 0; +} + +/** + * @brief unset interrupt configuration for the gpio interrupt + * + * @param dev device instance for port irq line + * @param port_num gpio port number + * @param pin the pin to disable interrupt + */ +void gpio_ra_interrupt_unset(const struct device *dev, uint8_t port_num, uint8_t pin) +{ + const struct gpio_ra_irq_config *config = dev->config; + struct gpio_ra_irq_data *data = dev->data; + + if ((port_num != data->callback.port_num) && (pin != data->callback.pin)) { + return; + } + + irq_disable(config->irq); + k_sem_give(&data->irq_sem); +} + +void gpio_ra_isr(const struct device *dev) +{ + const struct gpio_ra_irq_data *data = dev->data; + const struct gpio_ra_irq_config *config = dev->config; + + data->callback.isr(data->callback.port, data->callback.pin); + R_BSP_IrqStatusClear(config->irq); +} + +static int gpio_ra_interrupt_init(const struct device *dev) +{ + const struct gpio_ra_irq_config *config = dev->config; + struct gpio_ra_irq_data *data = dev->data; + uint8_t irqcr = ((config->trigger << R_ICU_IRQCR_IRQMD_Pos)); + + WRITE_BIT(irqcr, R_ICU_IRQCR_FLTEN_Pos, config->digital_filter); + sys_write8(irqcr, config->reg); + k_sem_init(&data->irq_sem, 1, 1); + + return 0; +} + +#define GPIO_INTERRUPT_INIT(index) \ + static const struct gpio_ra_irq_config gpio_ra_irq_config##index = { \ + .reg = DT_INST_REG_ADDR(index), \ + .channel = DT_INST_PROP(index, channel), \ + .trigger = \ + DT_INST_ENUM_IDX_OR(index, renesas_trigger, EXT_INTERRUPT_EDGE_FALLING), \ + .digital_filter = DT_INST_PROP_OR(index, renesas_digital_filtering, false), \ + .sample_clock = UTIL_CAT(EXT_INTERRUPT_SAMPLE_CLOCK_DIV_, \ + DT_INST_PROP_OR(index, renesas_sample_clock_div, 1)), \ + .irq = DT_INST_IRQ(index, irq), \ + }; \ + static struct gpio_ra_irq_data gpio_ra_irq_data##index; \ + static int gpio_ra_irq_init##index(const struct device *dev) \ + { \ + R_ICU->IELSR[DT_INST_IRQ(index, irq)] = \ + UTIL_CAT(ELC_EVENT_ICU_IRQ, DT_INST_PROP(index, channel)); \ + IRQ_CONNECT(DT_INST_IRQ(index, irq), DT_INST_IRQ(index, priority), gpio_ra_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + return gpio_ra_interrupt_init(dev); \ + }; \ + DEVICE_DT_INST_DEFINE(index, gpio_ra_irq_init##index, NULL, &gpio_ra_irq_data##index, \ + &gpio_ra_irq_config##index, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_INTERRUPT_INIT) diff --git a/drivers/mm/mm_drv_intel_adsp.h b/drivers/mm/mm_drv_intel_adsp.h index 861621a510f44..133e5a2f9d150 100644 --- a/drivers/mm/mm_drv_intel_adsp.h +++ b/drivers/mm/mm_drv_intel_adsp.h @@ -55,7 +55,6 @@ #define MAX_EBB_BANKS_IN_SEGMENT 32 #define SRAM_BANK_SIZE (128 * 1024) #define L2_SRAM_BANK_NUM (L2_SRAM_SIZE / SRAM_BANK_SIZE) -#define IS_BIT_SET(value, idx) ((value) & (1 << (idx))) /** * Calculate TLB entry based on physical address. diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index b7b046f3b9542..ac0d56072d2e8 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -462,7 +462,7 @@ int sys_mm_drv_update_page_flags(void *virt, uint32_t flags) tlb_entries[entry_idx] = entry; #ifdef CONFIG_MMU - arch_mem_map(virt, tlb_entry_to_pa(entry), CONFIG_MM_DRV_PAGE_SIZE, flags); + arch_mem_map(virt, va, CONFIG_MM_DRV_PAGE_SIZE, flags); #endif out: diff --git a/drivers/modem/Kconfig b/drivers/modem/Kconfig index 7219312e18f73..b8e66ef427482 100644 --- a/drivers/modem/Kconfig +++ b/drivers/modem/Kconfig @@ -146,6 +146,7 @@ endif # MODEM_CONTEXT config MODEM_SOCKET bool "Generic modem socket support layer" + depends on NET_SOCKETS help This layer provides much of the groundwork for keeping track of modem "sockets" throughout their lifecycle (from the initial offload diff --git a/drivers/modem/hl7800.c b/drivers/modem/hl7800.c index a30d3cbd8c61c..58e4f663838db 100644 --- a/drivers/modem/hl7800.c +++ b/drivers/modem/hl7800.c @@ -252,6 +252,7 @@ struct xmodem_packet { #define DNS_WORK_DELAY_SECS 1 #define IFACE_WORK_DELAY K_MSEC(500) #define SOCKET_CLEANUP_WORK_DELAY K_MSEC(100) +#define STORED_SOCKETS_DELAY K_SECONDS(1) #define WAIT_FOR_KSUP_RETRIES 5 #define CGCONTRDP_RESPONSE_NUM_DELIMS 7 @@ -427,6 +428,7 @@ struct hl7800_iface_ctx { bool wait_for_KSUP; uint32_t wait_for_KSUP_tries; bool reconfig_IP_connection; + bool reset_sockets; char dns_v4_string[NET_IPV4_ADDR_LEN]; char no_id_resp_cmd[NO_ID_RESP_CMD_MAX_LENGTH]; bool search_no_id_resp; @@ -456,6 +458,7 @@ struct hl7800_iface_ctx { /* semaphores */ struct k_sem response_sem; struct k_sem mdm_awake; + struct k_sem wait_urc; /* work */ struct k_work_delayable rssi_query_work; @@ -476,6 +479,7 @@ struct hl7800_iface_ctx { int file_pos; struct k_work finish_fw_update_work; bool fw_updated; + bool fw_updating; #endif /* modem info */ @@ -520,11 +524,14 @@ struct hl7800_iface_ctx { struct tm local_time; int32_t local_time_offset; bool local_time_valid; - bool configured; + enum mdm_hl7800_state state; bool off; void (*wake_up_callback)(int state); void (*gpio6_callback)(int state); void (*cts_callback)(int state); + bool user_at_cmd; + char *user_at_cmd_resp_buf; + uint16_t user_at_cmd_resp_buf_len; #ifdef CONFIG_MODEM_HL7800_GPS struct k_work_delayable gps_work; @@ -562,6 +569,9 @@ static char *get_sleep_state_string(enum mdm_hl7800_sleep state); static void set_network_state(enum mdm_hl7800_network_state state); static void set_startup_state(enum mdm_hl7800_startup_state state); static void set_sleep_state(enum mdm_hl7800_sleep state); +static void set_state(enum mdm_hl7800_state state); +static void generate_state_event(void); +static char *get_state_string(enum mdm_hl7800_state state); static void generate_network_state_event(void); static void generate_startup_state_event(void); static void generate_sleep_state_event(void); @@ -812,6 +822,11 @@ static struct hl7800_socket *socket_from_id(int socket_id) static inline void set_busy(bool busy) { +#ifdef CONFIG_MODEM_HL7800_FW_UPDATE + if (iface_ctx.fw_updating && !busy) { + return; + } +#endif iface_ctx.busy = busy; } @@ -1073,7 +1088,8 @@ static int wakeup_hl7800(void) return 0; } -int32_t mdm_hl7800_send_at_cmd(const uint8_t *data) +int32_t mdm_hl7800_send_at_cmd(const uint8_t *data, uint8_t resp_timeout, char *resp, + uint16_t *resp_len) { int ret; @@ -1084,7 +1100,21 @@ int32_t mdm_hl7800_send_at_cmd(const uint8_t *data) hl7800_lock(); wakeup_hl7800(); iface_ctx.last_socket_id = 0; - ret = send_at_cmd(NULL, data, MDM_CMD_SEND_TIMEOUT, 0, false); + iface_ctx.user_at_cmd = true; + iface_ctx.user_at_cmd_resp_buf = resp; + if (resp_len) { + iface_ctx.user_at_cmd_resp_buf_len = *resp_len; + } else { + iface_ctx.user_at_cmd_resp_buf_len = 0; + } + if (iface_ctx.user_at_cmd_resp_buf) { + iface_ctx.user_at_cmd_resp_buf[0] = '\0'; + } + ret = send_at_cmd(NULL, data, K_SECONDS(resp_timeout), 0, false); + iface_ctx.user_at_cmd = false; + if (resp_len && iface_ctx.user_at_cmd_resp_buf) { + *resp_len = strlen(iface_ctx.user_at_cmd_resp_buf); + } set_busy(false); allow_sleep(true); hl7800_unlock(); @@ -1391,6 +1421,7 @@ void mdm_hl7800_generate_status_events(void) event_handler(HL7800_EVENT_BANDS, iface_ctx.mdm_bands_string); event_handler(HL7800_EVENT_ACTIVE_BANDS, iface_ctx.mdm_active_bands_string); event_handler(HL7800_EVENT_REVISION, iface_ctx.mdm_revision); + generate_state_event(); hl7800_unlock(); } @@ -1440,7 +1471,7 @@ static int send_data(struct hl7800_socket *sock, struct net_pkt *pkt) } snprintk(buf, sizeof(buf), "AT+KUDPSND=%d,\"%s\",%u,%zu", sock->socket_id, dst_addr, - net_sin(&sock->dst)->sin_port, send_len); + ntohs(net_sin(&sock->dst)->sin_port), send_len); } send_at_cmd(sock, buf, K_NO_WAIT, 0, false); @@ -1590,8 +1621,8 @@ static int pkt_setup_ip_data(struct net_pkt *pkt, struct hl7800_socket *sock) } net_pkt_set_remote_address(pkt, &sock->dst, sizeof(struct sockaddr_in6)); pkt->remote.sa_family = AF_INET6; - src_port = ntohs(net_sin6(&sock->src)->sin6_port); - dst_port = ntohs(net_sin6(&sock->dst)->sin6_port); + src_port = net_sin6(&sock->src)->sin6_port; + dst_port = net_sin6(&sock->dst)->sin6_port; hdr_len = sizeof(struct net_ipv6_hdr); } @@ -1605,8 +1636,8 @@ static int pkt_setup_ip_data(struct net_pkt *pkt, struct hl7800_socket *sock) } net_pkt_set_remote_address(pkt, &sock->dst, sizeof(struct sockaddr_in)); pkt->remote.sa_family = AF_INET; - src_port = ntohs(net_sin(&sock->src)->sin_port); - dst_port = ntohs(net_sin(&sock->dst)->sin_port); + src_port = net_sin(&sock->src)->sin_port; + dst_port = net_sin(&sock->dst)->sin_port; hdr_len = sizeof(struct net_ipv4_hdr); } @@ -1945,7 +1976,7 @@ static void dns_work_cb(struct k_work *work) LOG_DBG("DNS ready"); iface_ctx.dns_ready = true; } else { - LOG_DBG("DNS not ready, schedule a retry"); + LOG_WRN("DNS not ready, schedule a retry"); k_work_reschedule_for_queue(&hl7800_workq, &iface_ctx.dns_work, K_SECONDS(DNS_WORK_DELAY_SECS * 2)); } @@ -2531,6 +2562,34 @@ static void set_sleep_state(enum mdm_hl7800_sleep state) generate_sleep_state_event(); } +static char *get_state_string(enum mdm_hl7800_state state) +{ + /* clang-format off */ + switch (state) { + PREFIXED_SWITCH_CASE_RETURN_STRING(HL7800_STATE, NOT_READY); + PREFIXED_SWITCH_CASE_RETURN_STRING(HL7800_STATE, INITIALIZED); + default: + return "UNKNOWN"; + } + /* clang-format on */ +} + +static void generate_state_event(void) +{ + struct mdm_hl7800_compound_event event; + + event.code = iface_ctx.state; + event.string = get_state_string(iface_ctx.state); + LOG_INF("State: %s", event.string); + event_handler(HL7800_EVENT_STATE, &event); +} + +static void set_state(enum mdm_hl7800_state state) +{ + iface_ctx.state = state; + generate_state_event(); +} + static void generate_sleep_state_event(void) { struct mdm_hl7800_compound_event event; @@ -2604,6 +2663,7 @@ static bool on_cmd_startup_report(struct net_buf **buf, uint16_t len) #ifdef CONFIG_MODEM_HL7800_FW_UPDATE if (iface_ctx.fw_updated) { iface_ctx.fw_updated = false; + iface_ctx.fw_updating = false; set_fota_state(HL7800_FOTA_REBOOT_AND_RECONFIGURE); /* issue reset after a firmware update to reconfigure modem state */ k_work_reschedule_for_queue(&hl7800_workq, &iface_ctx.mdm_reset_work, @@ -3823,9 +3883,9 @@ static bool on_cmd_sockerror(struct net_buf **buf, uint16_t len) LOG_ERR("'%s'", string); } + iface_ctx.last_error = -EIO; sock = socket_from_id(iface_ctx.last_socket_id); if (!sock) { - iface_ctx.last_error = -EIO; k_sem_give(&iface_ctx.response_sem); } else { sock->error = -EIO; @@ -3844,12 +3904,11 @@ static bool on_cmd_sock_error_code(struct net_buf **buf, uint16_t len) out_len = net_buf_linearize(value, sizeof(value), *buf, 0, len); value[out_len] = 0; - + iface_ctx.last_error = strtol(value, NULL, 10); LOG_ERR("Error code: %s", value); sock = socket_from_id(iface_ctx.last_socket_id); if (!sock) { - iface_ctx.last_error = -EIO; k_sem_give(&iface_ctx.response_sem); } else { sock->error = -EIO; @@ -4009,7 +4068,8 @@ static bool on_cmd_sockcreate(enum net_sock_type type, struct net_buf **buf, uin if (!sock) { LOG_DBG("look up new socket by creation id"); sock = socket_from_id(MDM_CREATE_SOCKET_ID); - if (!sock || sock->type != type) { + if (iface_ctx.reset_sockets || !sock || sock->type != type) { + iface_ctx.reset_sockets = false; if (queue_stale_socket(type, iface_ctx.last_socket_id) == 0) { /* delay some time before socket cleanup in case there * are multiple sockets to cleanup @@ -4027,6 +4087,9 @@ static bool on_cmd_sockcreate(enum net_sock_type type, struct net_buf **buf, uin sock->reconfig = false; /* don't give back semaphore -- OK to follow */ done: + if (iface_ctx.reconfig_IP_connection) { + k_sem_give(&iface_ctx.wait_urc); + } return true; } @@ -4581,7 +4644,8 @@ static void hl7800_rx(void *p1, void *p2, void *p3) struct net_buf *rx_buf = NULL; struct net_buf *frag = NULL; int i, cmp_res; - uint16_t len; + uint16_t len, resp_offset; + int16_t resp_max_len; size_t out_len; bool cmd_handled = false; static char rx_msg[MDM_HANDLER_MATCH_MAX_LEN]; @@ -4770,6 +4834,30 @@ static void hl7800_rx(void *p1, void *p2, void *p3) } } + if (iface_ctx.user_at_cmd && iface_ctx.user_at_cmd_resp_buf && + iface_ctx.user_at_cmd_resp_buf_len > 0 && frag && len > 1) { + /* Get the current length of the response. Multi-line responses will + * be appended. + */ + resp_offset = strlen(iface_ctx.user_at_cmd_resp_buf); + /* Make sure we have room for the new data and '\n\0' */ + resp_max_len = iface_ctx.user_at_cmd_resp_buf_len - resp_offset - 2; + if (resp_max_len < 0) { + resp_max_len = 0; + } + if (resp_max_len > 0) { + out_len = net_buf_linearize(iface_ctx.user_at_cmd_resp_buf + + resp_offset, + resp_max_len, rx_buf, 0, len); + /* Add '\n\0' to terminate the response */ + memcpy(iface_ctx.user_at_cmd_resp_buf + resp_offset + + out_len, + "\n\0", 2); + } else { + LOG_WRN("User AT cmd resp buf full"); + } + } + /* Handle unhandled commands */ if (IS_ENABLED(HL7800_LOG_UNHANDLED_RX_MSGS) && !cmd_handled && frag && len > 1) { @@ -5313,11 +5401,11 @@ static int modem_reset_and_configure(void) /* If CONFIG_MODEM_HL7800_RAT_M1 or CONFIG_MODEM_HL7800_RAT_NB1, then * set the radio mode. This is only done here if the driver has not been - * initialized (!iface_ctx.configured) yet because the public API also + * initialized yet because the public API also * allows the RAT to be changed (and will reset the modem). */ #ifndef CONFIG_MODEM_HL7800_RAT_NO_CHANGE - if (!iface_ctx.configured) { + if (iface_ctx.state == HL7800_STATE_NOT_READY) { #if CONFIG_MODEM_HL7800_RAT_M1 if (iface_ctx.mdm_rat != MDM_RAT_CAT_M1) { if (iface_ctx.new_rat_cmd_support) { @@ -5517,14 +5605,11 @@ static int modem_reset_and_configure(void) config_apn = true; } - /* Query PDP authentication context to get APN username/password. - * Temporary Workaround - Ignore error - * On some modules this is returning an error and the response data. - */ - SEND_AT_CMD_IGNORE_ERROR("AT+WPPP?"); + /* Disable PDP authentication, the driver does not support it */ + SEND_AT_CMD_EXPECT_OK("AT+WPPP=0"); #if CONFIG_MODEM_HL7800_SET_APN_NAME_ON_STARTUP - if (!iface_ctx.configured) { + if (iface_ctx.state == HL7800_STATE_NOT_READY) { if (strncmp(iface_ctx.mdm_apn.value, CONFIG_MODEM_HL7800_APN_NAME, MDM_HL7800_APN_MAX_STRLEN) != 0) { apn = CONFIG_MODEM_HL7800_APN_NAME; @@ -5553,12 +5638,6 @@ static int modem_reset_and_configure(void) /* Turn on EPS network registration status reporting */ SEND_AT_CMD_EXPECT_OK("AT+CEREG=5"); - /* query all socket configs to cleanup any sockets that are not - * tracked by the driver - */ - SEND_AT_CMD_EXPECT_OK("AT+KTCPCFG?"); - SEND_AT_CMD_EXPECT_OK("AT+KUDPCFG?"); - /* Enabled the LTE radio */ #if !defined(CONFIG_MODEM_HL7800_BOOT_IN_AIRPLANE_MODE) SEND_AT_CMD_EXPECT_OK("AT+CFUN=1,0"); @@ -5569,7 +5648,7 @@ static int modem_reset_and_configure(void) */ LOG_INF("Modem ready!"); iface_ctx.restarting = false; - iface_ctx.configured = true; + set_state(HL7800_STATE_INITIALIZED); set_busy(false); allow_sleep(sleep); /* trigger APN update event */ @@ -5591,7 +5670,7 @@ static int modem_reset_and_configure(void) error: LOG_ERR("Unable to configure modem"); - iface_ctx.configured = false; + set_state(HL7800_STATE_NOT_READY); set_network_state(HL7800_UNABLE_TO_CONFIGURE); /* Kernel will fault with non-zero return value. * Allow other parts of application to run when modem cannot be configured. @@ -5621,20 +5700,16 @@ static void mdm_reset_work_callback(struct k_work *item) { ARG_UNUSED(item); - mdm_hl7800_reset(); -} - -int32_t mdm_hl7800_reset(void) -{ - int ret; - hl7800_lock(); - ret = modem_reset_and_configure(); + (void)modem_reset_and_configure(); hl7800_unlock(); +} - return ret; +int32_t mdm_hl7800_reset(void) +{ + return k_work_reschedule_for_queue(&hl7800_workq, &iface_ctx.mdm_reset_work, K_NO_WAIT); } static void mdm_power_off_work_callback(struct k_work *item) @@ -5660,7 +5735,7 @@ static void mdm_power_off_work_callback(struct k_work *item) } prepare_io_for_reset(); iface_ctx.dns_ready = false; - iface_ctx.configured = false; + set_state(HL7800_STATE_NOT_READY); iface_ctx.off = true; set_busy(false); /* bring the iface down */ @@ -5668,6 +5743,9 @@ static void mdm_power_off_work_callback(struct k_work *item) net_if_carrier_off(iface_ctx.iface); } LOG_INF("Modem powered off"); + set_sleep_state(HL7800_SLEEP_UNINITIALIZED); + set_network_state(HL7800_NOT_REGISTERED); + set_startup_state(HL7800_STARTUP_STATE_UNKNOWN); hl7800_unlock(); } @@ -5782,10 +5860,10 @@ static int configure_TCP_socket(struct hl7800_socket *sock) if (sock->dst.sa_family == AF_INET6) { af = MDM_HL7800_SOCKET_AF_IPV6; - dst_port = net_sin6(&sock->dst)->sin6_port; + dst_port = ntohs(net_sin6(&sock->dst)->sin6_port); } else if (sock->dst.sa_family == AF_INET) { af = MDM_HL7800_SOCKET_AF_IPV4; - dst_port = net_sin(&sock->dst)->sin_port; + dst_port = ntohs(net_sin(&sock->dst)->sin_port); } else { return -EINVAL; } @@ -5855,8 +5933,6 @@ static int reconfigure_IP_connection(void) int ret = 0; if (iface_ctx.reconfig_IP_connection) { - iface_ctx.reconfig_IP_connection = false; - /* reconfigure GPRS connection so sockets can be used */ ret = setup_gprs_connection(iface_ctx.mdm_apn.value); if (ret < 0) { @@ -5864,6 +5940,8 @@ static int reconfigure_IP_connection(void) goto done; } + k_sem_reset(&iface_ctx.wait_urc); + /* query all TCP socket configs */ ret = send_at_cmd(NULL, "AT+KTCPCFG?", MDM_CMD_SEND_TIMEOUT, 0, false); @@ -5872,8 +5950,13 @@ static int reconfigure_IP_connection(void) ret = send_at_cmd(NULL, "AT+KUDPCFG?", MDM_CMD_SEND_TIMEOUT, 0, false); - /* TODO: to make this better, wait for +KUDP_IND or timeout */ - k_sleep(K_SECONDS(1)); + ret = k_sem_take(&iface_ctx.wait_urc, STORED_SOCKETS_DELAY); + if (ret == -EAGAIN) { + /* There are no sockets to reset */ + iface_ctx.reset_sockets = false; + } + + iface_ctx.reconfig_IP_connection = false; } done: @@ -6006,7 +6089,7 @@ static int offload_connect(struct net_context *context, if (addr->sa_family == AF_INET6) { net_ipaddr_copy(&net_sin6(&sock->dst)->sin6_addr, &net_sin6(addr)->sin6_addr); - dst_port = ntohs(net_sin6(addr)->sin6_port); + dst_port = net_sin6(addr)->sin6_port; net_sin6(&sock->dst)->sin6_port = dst_port; } else #endif @@ -6014,7 +6097,7 @@ static int offload_connect(struct net_context *context, if (addr->sa_family == AF_INET) { net_ipaddr_copy(&net_sin(&sock->dst)->sin_addr, &net_sin(addr)->sin_addr); - dst_port = ntohs(net_sin(addr)->sin_port); + dst_port = net_sin(addr)->sin_port; net_sin(&sock->dst)->sin_port = dst_port; } else #endif @@ -6023,7 +6106,7 @@ static int offload_connect(struct net_context *context, } if (dst_port < 0) { - LOG_ERR("Invalid port: %d", dst_port); + LOG_ERR("Invalid port: %d", ntohs(dst_port)); return -EINVAL; } @@ -6074,7 +6157,7 @@ static int offload_sendto(struct net_pkt *pkt, const struct sockaddr *dst_addr, { struct net_context *context = net_pkt_context(pkt); struct hl7800_socket *sock; - int ret, dst_port = 0; + int ret; if (!context) { return -EINVAL; @@ -6090,16 +6173,14 @@ static int offload_sendto(struct net_pkt *pkt, const struct sockaddr *dst_addr, if (dst_addr->sa_family == AF_INET6) { net_ipaddr_copy(&net_sin6(&sock->dst)->sin6_addr, &net_sin6(dst_addr)->sin6_addr); - dst_port = ntohs(net_sin6(dst_addr)->sin6_port); - net_sin6(&sock->dst)->sin6_port = dst_port; + net_sin6(&sock->dst)->sin6_port = net_sin6(dst_addr)->sin6_port; } else #endif #if defined(CONFIG_NET_IPV4) if (dst_addr->sa_family == AF_INET) { net_ipaddr_copy(&net_sin(&sock->dst)->sin_addr, &net_sin(dst_addr)->sin_addr); - dst_port = ntohs(net_sin(dst_addr)->sin_port); - net_sin(&sock->dst)->sin_port = dst_port; + net_sin(&sock->dst)->sin_port = net_sin(dst_addr)->sin_port; } else #endif { @@ -6278,11 +6359,14 @@ int32_t mdm_hl7800_update_fw(char *file_path) goto err; } + wakeup_hl7800(); + /* turn on device service indications */ ret = send_at_cmd(NULL, "AT+WDSI=2", MDM_CMD_SEND_TIMEOUT, 0, false); if (ret < 0) { goto err; } + iface_ctx.fw_updating = true; notify_all_tcp_sockets_closed(); hl7800_stop_rssi_work(); @@ -6321,6 +6405,7 @@ static int hl7800_init(const struct device *dev) ARG_UNUSED(dev); LOG_DBG("HL7800 Init"); + iface_ctx.reset_sockets = true; /* The UART starts in the on state and CTS is set low by the HL7800 */ iface_ctx.cts_state = iface_ctx.last_cts_state = 0; @@ -6350,6 +6435,7 @@ static int hl7800_init(const struct device *dev) iface_ctx.last_socket_id = 0; k_sem_init(&iface_ctx.response_sem, 0, 1); k_sem_init(&iface_ctx.mdm_awake, 0, 1); + k_sem_init(&iface_ctx.wait_urc, 0, 1); /* initialize the work queue */ k_work_queue_start(&hl7800_workq, hl7800_workq_stack, @@ -6376,6 +6462,7 @@ static int hl7800_init(const struct device *dev) k_work_init(&iface_ctx.finish_fw_update_work, finish_fw_update_work_callback); iface_ctx.fw_updated = false; + iface_ctx.fw_updating = false; #endif /* setup port devices and pin directions */ diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index aaac17ffbc9b3..317c76dd847b8 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -1464,6 +1464,7 @@ static void modem_cellular_event_handler(struct modem_cellular_data *data, case MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT: modem_cellular_run_shutdown_script_event_handler(data, evt); + break; case MODEM_CELLULAR_STATE_POWER_OFF_PULSE: modem_cellular_power_off_pulse_event_handler(data, evt); diff --git a/drivers/modem/modem_cmd_handler.c b/drivers/modem/modem_cmd_handler.c index 8bc84f5c5f2f1..99b1548051585 100644 --- a/drivers/modem/modem_cmd_handler.c +++ b/drivers/modem/modem_cmd_handler.c @@ -99,12 +99,6 @@ static bool starts_with(struct net_buf *buf, const char *str) * Cmd Handler Functions */ -static inline struct net_buf *read_rx_allocator(k_timeout_t timeout, - void *user_data) -{ - return net_buf_alloc((struct net_buf_pool *)user_data, timeout); -} - /* return scanned length for params */ static int parse_params(struct modem_cmd_handler_data *data, size_t match_len, const struct modem_cmd *cmd, diff --git a/drivers/modem/modem_socket.c b/drivers/modem/modem_socket.c index a30528ba899dd..81c5a5cd31de8 100644 --- a/drivers/modem/modem_socket.c +++ b/drivers/modem/modem_socket.c @@ -437,6 +437,7 @@ int modem_socket_init(struct modem_socket_config *cfg, struct modem_socket *sock k_sem_init(&cfg->sockets[i].sem_data_ready, 0, 1); k_poll_signal_init(&cfg->sockets[i].sig_data_ready); cfg->sockets[i].id = -1; + cfg->sockets[i].sock_fd = -1; } return 0; } diff --git a/drivers/net/nsos_sockets.c b/drivers/net/nsos_sockets.c index 6a1cc7637391a..7aa4e3cb9245b 100644 --- a/drivers/net/nsos_sockets.c +++ b/drivers/net/nsos_sockets.c @@ -258,6 +258,7 @@ static ssize_t nsos_write(void *obj, const void *buf, size_t sz) static int nsos_close(void *obj) { struct nsos_socket *sock = obj; + struct nsos_socket_poll *poll; int ret; ret = nsi_host_close(sock->poll.mid.fd); @@ -265,6 +266,13 @@ static int nsos_close(void *obj) errno = nsos_adapt_get_zephyr_errno(); } + SYS_DLIST_FOR_EACH_CONTAINER(&nsos_polls, poll, node) { + if (poll == &sock->poll) { + poll->mid.revents = ZSOCK_POLLHUP; + poll->mid.cb(&poll->mid); + } + } + k_free(sock); return ret; diff --git a/drivers/pcie/CMakeLists.txt b/drivers/pcie/CMakeLists.txt index 351f355ffec0d..7840524a7686c 100644 --- a/drivers/pcie/CMakeLists.txt +++ b/drivers/pcie/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory_ifdef(CONFIG_PCIE host) add_subdirectory_ifdef(CONFIG_PCIE_ENDPOINT endpoint) +add_subdirectory_ifdef(CONFIG_PCIE_CONTROLLER controller) diff --git a/drivers/pcie/Kconfig b/drivers/pcie/Kconfig index 2651a84f6a68f..2315889787570 100644 --- a/drivers/pcie/Kconfig +++ b/drivers/pcie/Kconfig @@ -2,3 +2,4 @@ source "drivers/pcie/host/Kconfig" source "drivers/pcie/endpoint/Kconfig" +source "drivers/pcie/controller/Kconfig" diff --git a/drivers/pcie/controller/CMakeLists.txt b/drivers/pcie/controller/CMakeLists.txt new file mode 100644 index 0000000000000..3a2ca4fddc864 --- /dev/null +++ b/drivers/pcie/controller/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_PCIE_BRCMSTB pcie_brcmstb.c) diff --git a/drivers/pcie/controller/Kconfig b/drivers/pcie/controller/Kconfig new file mode 100644 index 0000000000000..29804ce1cb4d0 --- /dev/null +++ b/drivers/pcie/controller/Kconfig @@ -0,0 +1,10 @@ +# PCIe controller configuration options + +# Copyright 2024 TSN Lab, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if PCIE_CONTROLLER + +source "drivers/pcie/controller/Kconfig.brcmstb" + +endif # PCIE_CONTROLLER diff --git a/drivers/pcie/controller/Kconfig.brcmstb b/drivers/pcie/controller/Kconfig.brcmstb new file mode 100644 index 0000000000000..439e57e1ecd57 --- /dev/null +++ b/drivers/pcie/controller/Kconfig.brcmstb @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Junho Lee +# SPDX-License-Identifier: Apache-2.0 + +config PCIE_BRCMSTB + bool "Broadcom Set-top box SoC PCIe Driver" + default y + depends on DT_HAS_BRCM_BRCMSTB_PCIE_ENABLED + help + Enable Driver for Broadcom Set-top box SoC PCIe controllers. diff --git a/drivers/pcie/controller/pcie_brcmstb.c b/drivers/pcie/controller/pcie_brcmstb.c new file mode 100644 index 0000000000000..68e66bc424f60 --- /dev/null +++ b/drivers/pcie/controller/pcie_brcmstb.c @@ -0,0 +1,635 @@ +/* + * Copyright (c) 2024 Junho Lee + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(pcie_brcmstb, LOG_LEVEL_ERR); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DT_DRV_COMPAT brcm_brcmstb_pcie + +#define PCIE_RC_PL_PHY_CTL_15 0x184c +#define PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK 0xff + +#define PCIE_MISC_MISC_CTRL 0x4008 +#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000 +#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000 +#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000 +#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_LSB 20 +#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000 +#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_LSB 27 + +#define PCIE_MISC_RC_BAR_CONFIG_LO_SIZE_MASK 0x1f + +#define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c +#define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f + +#define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034 +#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f +#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_LSB 0 +#define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038 + +#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c +#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f + +#define PCIE_MISC_RC_BAR4_CONFIG_LO 0x40d4 +#define PCIE_MISC_RC_BAR4_CONFIG_HI 0x40d8 + +#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_ENABLE 0x1 +#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_LO_MASK 0xfffff000 +#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_HI_MASK 0xff + +#define PCIE_MISC_UBUS_BAR2_CONFIG_REMAP 0x40b4 +#define PCIE_MISC_UBUS_BAR2_CONFIG_REMAP_ACCESS_ENABLE_MASK 0x1 + +#define PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_LO 0x410c +#define PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_HI 0x4110 + +#define PCIE_MISC_UBUS_CTRL 0x40a4 +#define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK 0x2000 +#define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK 0x80000 + +#define PCIE_MISC_AXI_READ_ERROR_DATA 0x4170 +#define PCIE_MISC_UBUS_TIMEOUT 0x40a8 +#define PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT 0x405c + +#define PCIE_MISC_PCIE_CTRL 0x4064 +#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK 0x4 + +#define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c +#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff + +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 0x0188 +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_LSB 2 +#define PCIE_RC_CFG_VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN 0x0 + +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010 +#define PCIE_MEM_WIN0_LO(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + (win) * 8) +#define PCIE_MEM_WIN0_HI(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + (win) * 8) + +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_LSB 20 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_LSB 4 + +#define PCIE_MEM_WIN0_BASE_LIMIT(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + (win) * 4) + +/* Hamming weight of PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK */ +#define HIGH_ADDR_SHIFT 12 + +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK 0xff +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_LSB 0 + +#define PCIE_MEM_WIN0_BASE_HI(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + (win) * 8) + +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_LSB 0 + +#define PCIE_MEM_WIN0_LIMIT_HI(win) (PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + (win) * 8) + +#define PCIE_EXT_CFG_DATA 0x8000 +#define PCIE_EXT_CFG_INDEX 0x9000 + +#define PCI_BASE_ADDRESS_0 0x10 + +#define PCI_COMMAND 0x0004 +#define PCI_COMMAND_MEMORY 0x2 +#define PCI_COMMAND_MASTER 0x4 + +#define PCI_EXP_LNKCAP 0x0c +#define PCI_EXP_LNKCAP_SLS 0xf +#define PCI_EXP_LNKCTL2 0x30 + +#define BRCM_PCIE_CAP_REGS 0x00ac + +#define BCM2712_RC_BAR2_SIZE 0x400000 +#define BCM2712_RC_BAR2_OFFSET 0x0 +#define BCM2712_RC_BAR4_CPU 0x0 +#define BCM2712_RC_BAR4_SIZE 0x0 +#define BCM2712_RC_BAR4_PCI 0x0 +#define BCM2712_SCB0_SIZE 0x400000 + +#define BCM2712_BURST_SIZE 0x1 + +#define BCM2712_CLOCK_RATE 750000000ULL /* 750Mhz */ + +#define BCM2712_UBUS_TIMEOUT_NS 250000000ULL /* 250ms */ +#define BCM2712_UBUS_TIMEOUT_TICKS (BCM2712_UBUS_TIMEOUT_NS * BCM2712_CLOCK_RATE / 1000000000ULL) + +#define BCM2712_RC_CONFIG_RETRY_TIMEOUT_NS 240000000ULL /* 240ms */ +#define BCM2712_RC_CONFIG_RETRY_TIMEOUT_TICKS \ + (BCM2712_RC_CONFIG_RETRY_TIMEOUT_NS * BCM2712_CLOCK_RATE / 1000000000ULL) + +#define BCM2712_PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE 0x060400 + +#define MDIO_DATA_DONE_MASK 0x80000000 +#define MDIO_CMD_WRITE 0x0 +#define MDIO_PORT0 0x0 + +#define PCIE_RC_DL_MDIO_ADDR 0x1100 +#define PCIE_RC_DL_MDIO_WR_DATA 0x1104 +#define PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD 0x12 /* 18.52ns as ticks */ + +#define SET_ADDR_OFFSET 0x1f + +#define DMA_RANGES_IDX 2 + +#define PCIE_ECAM_BDF_SHIFT 12 + +#define BAR_MAX 8 + +#define SZ_1M 0x100000 + +struct pcie_brcmstb_config { + const struct pcie_ctrl_config *common; + size_t regs_count; + struct { + uintptr_t addr; + size_t size; + } regs[BAR_MAX]; +}; + +enum pcie_region_type { + PCIE_REGION_IO = 0, + PCIE_REGION_MEM, + PCIE_REGION_MEM64, + PCIE_REGION_MAX, +}; + +struct pcie_brcmstb_data { + uintptr_t cfg_phys_addr; + mm_reg_t cfg_addr; + size_t cfg_size; + struct { + uintptr_t phys_start; + uintptr_t bus_start; + size_t size; + size_t allocation_offset; + } regions[PCIE_REGION_MAX]; + size_t bar_cnt; +}; + +static inline uint32_t lower_32_bits(uint64_t val) +{ + return val & 0xffffffff; +} + +static inline uint32_t upper_32_bits(uint64_t val) +{ + return (val >> 32) & 0xffffffff; +} + +static uint32_t encode_ibar_size(uint64_t size) +{ + uint32_t tmp; + uint32_t size_upper = (uint32_t)(size >> 32); + + if (size_upper > 0) { + tmp = ilog2(size_upper) + 32; + } else { + tmp = ilog2(size); + } + + if (tmp >= 12 && tmp <= 15) { + return (tmp - 12) + 0x1c; + } else if (tmp >= 16 && tmp <= 36) { + return tmp - 15; + } + + return 0; +} + +static mm_reg_t pcie_brcmstb_map_bus(const struct device *dev, pcie_bdf_t bdf, unsigned int reg) +{ + struct pcie_brcmstb_data *data = dev->data; + + sys_write32(bdf << PCIE_ECAM_BDF_SHIFT, data->cfg_addr + PCIE_EXT_CFG_INDEX); + return data->cfg_addr + PCIE_EXT_CFG_DATA + reg * sizeof(uint32_t); +} + +static uint32_t pcie_brcmstb_conf_read(const struct device *dev, pcie_bdf_t bdf, unsigned int reg) +{ + mm_reg_t conf_addr = pcie_brcmstb_map_bus(dev, bdf, reg); + + if (!conf_addr) { + return 0xffffffff; + } + + return sys_read32(conf_addr); +} + +void pcie_brcmstb_conf_write(const struct device *dev, pcie_bdf_t bdf, unsigned int reg, + uint32_t data) +{ + mm_reg_t conf_addr = pcie_brcmstb_map_bus(dev, bdf, reg); + + if (!conf_addr) { + return; + } + + sys_write32(data, conf_addr); +} + +static inline enum pcie_region_type pcie_brcmstb_determine_region_type(const struct device *dev, + bool mem, bool mem64) +{ + struct pcie_brcmstb_data *data = dev->data; + + if (!mem) { + return PCIE_REGION_IO; + } + + if ((data->regions[PCIE_REGION_MEM64].size > 0) && + (mem64 || data->regions[PCIE_REGION_MEM].size == 0)) { + return PCIE_REGION_MEM64; + } + + return PCIE_REGION_MEM; +} + +static bool pcie_brcmstb_region_allocate_type(const struct device *dev, pcie_bdf_t bdf, + size_t bar_size, uintptr_t *bar_bus_addr, + enum pcie_region_type type) +{ + const struct pcie_brcmstb_config *config = dev->config; + struct pcie_brcmstb_data *data = dev->data; + uintptr_t addr; + + addr = (((data->regions[type].bus_start + config->regs[PCIE_BDF_TO_BUS(bdf) + 1].addr + + data->regions[type].allocation_offset) - + 1) | + ((bar_size)-1)) + + 1; + + if (addr + bar_size > data->regions[type].bus_start + data->regions[type].size) { + return false; + } + + *bar_bus_addr = addr; + + return true; +} + +static bool pcie_brcmstb_region_allocate(const struct device *dev, pcie_bdf_t bdf, bool mem, + bool mem64, size_t bar_size, uintptr_t *bar_bus_addr) +{ + struct pcie_brcmstb_data *data = dev->data; + enum pcie_region_type type; + + if (!mem && mem64) { + return false; + } + + if (mem && data->regions[PCIE_REGION_MEM64].size == 0 && + data->regions[PCIE_REGION_MEM].size == 0) { + return false; + } + + if (!mem && data->regions[PCIE_REGION_IO].size == 0) { + return false; + } + + type = pcie_brcmstb_determine_region_type(dev, mem, mem64); + + return pcie_brcmstb_region_allocate_type(dev, bdf, bar_size, bar_bus_addr, type); +} + +static bool pcie_brcmstb_region_get_allocate_base(const struct device *dev, pcie_bdf_t bdf, + bool mem, bool mem64, size_t align, + uintptr_t *bar_base_addr) +{ + struct pcie_brcmstb_data *data = dev->data; + enum pcie_region_type type; + + if (!mem && mem64) { + return false; + } + + if (mem && data->regions[PCIE_REGION_MEM64].size == 0 && + data->regions[PCIE_REGION_MEM].size == 0) { + return false; + } + + if (!mem && data->regions[PCIE_REGION_IO].size == 0) { + return false; + } + + type = pcie_brcmstb_determine_region_type(dev, mem, mem64); + + *bar_base_addr = + (((data->regions[type].bus_start + data->regions[type].allocation_offset) - 1) | + ((align)-1)) + + 1; + + return true; +} + +static bool pcie_brcmstb_region_translate(const struct device *dev, pcie_bdf_t bdf, bool mem, + bool mem64, uintptr_t bar_bus_addr, uintptr_t *bar_addr) +{ + struct pcie_brcmstb_data *data = dev->data; + enum pcie_region_type type; + + type = pcie_brcmstb_determine_region_type(dev, mem, mem64); + + *bar_addr = data->regions[type].phys_start + (bar_bus_addr - data->regions[type].bus_start); + + return true; +} + +static DEVICE_API(pcie_ctrl, pcie_brcmstb_api) = { + .conf_read = pcie_brcmstb_conf_read, + .conf_write = pcie_brcmstb_conf_write, + .region_allocate = pcie_brcmstb_region_allocate, + .region_get_allocate_base = pcie_brcmstb_region_get_allocate_base, + .region_translate = pcie_brcmstb_region_translate, +}; + +static int pcie_brcmstb_parse_regions(const struct device *dev) +{ + const struct pcie_brcmstb_config *config = dev->config; + struct pcie_brcmstb_data *data = dev->data; + enum pcie_region_type type; + int i; + + for (i = 0; i < DMA_RANGES_IDX; i++) { + switch ((config->common->ranges[i].flags >> 24) & 0x03) { + case 0x01: + type = PCIE_REGION_IO; + break; + case 0x02: + type = PCIE_REGION_MEM; + break; + case 0x03: + type = PCIE_REGION_MEM64; + break; + default: + continue; + } + data->regions[type].bus_start = config->common->ranges[i].pcie_bus_addr; + data->regions[type].phys_start = config->common->ranges[i].host_map_addr; + data->regions[type].size = config->common->ranges[i].map_length; + } + + if (!data->regions[PCIE_REGION_IO].size && !data->regions[PCIE_REGION_MEM].size && + !data->regions[PCIE_REGION_MEM64].size) { + return -EINVAL; + } + + return 0; +} + +static mm_reg_t pcie_brcmstb_mdio_from_pkt(int port, int regad, int cmd) +{ + return (mm_reg_t)cmd << 20 | port << 16 | regad; +} + +static void pcie_brcmstb_mdio_write(mm_reg_t base, uint8_t port, uint8_t regad, uint16_t wrdata) +{ + sys_write32(pcie_brcmstb_mdio_from_pkt(port, regad, MDIO_CMD_WRITE), + base + PCIE_RC_DL_MDIO_ADDR); + sys_write32(MDIO_DATA_DONE_MASK | wrdata, base + PCIE_RC_DL_MDIO_WR_DATA); +} + +static void pcie_brcmstb_munge_pll(const struct device *dev) +{ + struct pcie_brcmstb_data *data = dev->data; + int i; + + uint8_t regs[] = {0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e}; + uint16_t vals[] = {0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030, 0x5030, 0x0007}; + + pcie_brcmstb_mdio_write(data->cfg_addr, MDIO_PORT0, SET_ADDR_OFFSET, 0x1600); + for (i = 0; i < 7; i++) { + k_busy_wait(300); + pcie_brcmstb_mdio_write(data->cfg_addr, MDIO_PORT0, regs[i], vals[i]); + } +} + +static void pcie_brcmstb_set_outbound_win(const struct device *dev, uint8_t win, uintptr_t cpu_addr, + uintptr_t pcie_addr, size_t size) +{ + struct pcie_brcmstb_data *data = dev->data; + uint32_t cpu_addr_mb_high, limit_addr_mb_high; + uintptr_t cpu_addr_mb, limit_addr_mb; + uint32_t tmp, tmp2; + + sys_write32(lower_32_bits(pcie_addr), data->cfg_addr + PCIE_MEM_WIN0_LO(win)); + sys_write32(upper_32_bits(pcie_addr), data->cfg_addr + PCIE_MEM_WIN0_HI(win)); + + cpu_addr_mb = cpu_addr / SZ_1M; + limit_addr_mb = (cpu_addr + size - 1) / SZ_1M; + + tmp = sys_read32(data->cfg_addr + PCIE_MEM_WIN0_BASE_LIMIT(win)); + tmp &= ~PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK; + tmp &= ~PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK; + tmp2 = (cpu_addr_mb << PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_LSB); + tmp2 &= PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK; + tmp |= tmp2; + tmp2 = (limit_addr_mb << PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_LSB); + tmp2 &= PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK; + tmp |= tmp2; + sys_write32(tmp, data->cfg_addr + PCIE_MEM_WIN0_BASE_LIMIT(win)); + + cpu_addr_mb_high = cpu_addr_mb >> HIGH_ADDR_SHIFT; + tmp = sys_read32(data->cfg_addr + PCIE_MEM_WIN0_BASE_HI(win)); + tmp &= ~PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK; + tmp |= (cpu_addr_mb_high << PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_LSB); + sys_write32(tmp, data->cfg_addr + PCIE_MEM_WIN0_BASE_HI(win)); + + limit_addr_mb_high = limit_addr_mb >> HIGH_ADDR_SHIFT; + tmp = sys_read32(data->cfg_addr + PCIE_MEM_WIN0_LIMIT_HI(win)); + tmp &= ~PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK; + tmp |= (cpu_addr_mb_high << PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_LSB); + sys_write32(tmp, data->cfg_addr + PCIE_MEM_WIN0_LIMIT_HI(win)); +} + +static int pcie_brcmstb_setup(const struct device *dev) +{ + const struct pcie_brcmstb_config *config = dev->config; + struct pcie_brcmstb_data *data = dev->data; + uint32_t tmp; + uint16_t tmp16; + + /* This block is for BCM2712 only */ + pcie_brcmstb_munge_pll(dev); + tmp = sys_read32(data->cfg_addr + PCIE_RC_PL_PHY_CTL_15); + tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK; + tmp |= PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD; + sys_write32(tmp, data->cfg_addr + PCIE_RC_PL_PHY_CTL_15); + + tmp = sys_read32(data->cfg_addr + PCIE_MISC_MISC_CTRL); + tmp |= PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK; + tmp |= PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK; + tmp &= ~PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK; + tmp |= (BCM2712_BURST_SIZE << PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_LSB); + sys_write32(tmp, data->cfg_addr + PCIE_MISC_MISC_CTRL); + + uint64_t rc_bar2_offset = config->common->ranges[DMA_RANGES_IDX].host_map_addr - + config->common->ranges[DMA_RANGES_IDX].pcie_bus_addr; + uint64_t rc_bar2_size = config->common->ranges[DMA_RANGES_IDX].map_length; + + tmp = lower_32_bits(rc_bar2_offset); + tmp &= ~PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK; + tmp |= encode_ibar_size(rc_bar2_size) << PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_LSB; + sys_write32(tmp, data->cfg_addr + PCIE_MISC_RC_BAR2_CONFIG_LO); + sys_write32(upper_32_bits(rc_bar2_offset), data->cfg_addr + PCIE_MISC_RC_BAR2_CONFIG_HI); + + tmp = sys_read32(data->cfg_addr + PCIE_MISC_UBUS_BAR2_CONFIG_REMAP); + tmp |= PCIE_MISC_UBUS_BAR2_CONFIG_REMAP_ACCESS_ENABLE_MASK; + sys_write32(tmp, data->cfg_addr + PCIE_MISC_UBUS_BAR2_CONFIG_REMAP); + + /* Set SCB Size */ + tmp = sys_read32(data->cfg_addr + PCIE_MISC_MISC_CTRL); + tmp &= ~PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK; + tmp |= (ilog2(config->common->ranges[DMA_RANGES_IDX].map_length) - 15) + << PCIE_MISC_MISC_CTRL_SCB0_SIZE_LSB; + sys_write32(tmp, data->cfg_addr + PCIE_MISC_MISC_CTRL); + + tmp = sys_read32(data->cfg_addr + PCIE_MISC_UBUS_CTRL); + tmp |= PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK; + tmp |= PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK; + sys_write32(tmp, data->cfg_addr + PCIE_MISC_UBUS_CTRL); + sys_write32(0xffffffff, data->cfg_addr + PCIE_MISC_AXI_READ_ERROR_DATA); + + /* Set timeouts */ + sys_write32(BCM2712_UBUS_TIMEOUT_TICKS, data->cfg_addr + PCIE_MISC_UBUS_TIMEOUT); + sys_write32(BCM2712_RC_CONFIG_RETRY_TIMEOUT_TICKS, + data->cfg_addr + PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT); + + tmp = sys_read32(data->cfg_addr + PCIE_MISC_RC_BAR1_CONFIG_LO); + tmp &= ~PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK; + sys_write32(tmp, data->cfg_addr + PCIE_MISC_RC_BAR1_CONFIG_LO); + + tmp = sys_read32(data->cfg_addr + PCIE_MISC_RC_BAR3_CONFIG_LO); + tmp &= ~PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK; + sys_write32(tmp, data->cfg_addr + PCIE_MISC_RC_BAR3_CONFIG_LO); + + /* Set gen to 2 */ + tmp16 = sys_read16(data->cfg_addr + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2); + tmp = sys_read32(data->cfg_addr + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP); + tmp &= ~PCI_EXP_LNKCAP_SLS; + tmp |= 0x2; + sys_write32(tmp, data->cfg_addr + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP); + tmp16 &= ~0xf; + tmp16 |= 0x2; + sys_write16(tmp16, data->cfg_addr + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2); + + tmp = sys_read32(data->cfg_addr + PCIE_RC_CFG_PRIV1_ID_VAL3); + tmp &= ~PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK; + tmp |= BCM2712_PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE; + sys_write32(tmp, data->cfg_addr + PCIE_RC_CFG_PRIV1_ID_VAL3); + + tmp = sys_read32(data->cfg_addr + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1); + tmp &= ~PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK; + tmp |= PCIE_RC_CFG_VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN + << PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_LSB; + sys_write32(tmp, data->cfg_addr + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1); + + return 0; +} + +static int pcie_brcmstb_init(const struct device *dev) +{ + const struct pcie_brcmstb_config *config = dev->config; + struct pcie_brcmstb_data *data = dev->data; + uint32_t tmp; + int ret; + + if (config->common->ranges_count < DMA_RANGES_IDX) { + /* Workaround since macros for `dma-ranges` property is not available */ + return -EINVAL; + } + + ret = pcie_brcmstb_parse_regions(dev); + if (ret != 0) { + return ret; + } + + data->cfg_phys_addr = config->common->cfg_addr; + data->cfg_size = config->common->cfg_size; + + device_map(&data->cfg_addr, data->cfg_phys_addr, data->cfg_size, K_MEM_CACHE_NONE); + + /* PCIe Setup */ + pcie_brcmstb_setup(dev); + + /* Assert PERST# */ + tmp = sys_read32(data->cfg_addr + PCIE_MISC_PCIE_CTRL); + tmp |= PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK; + sys_write32(tmp, data->cfg_addr + PCIE_MISC_PCIE_CTRL); + + k_busy_wait(500000); + + /* Enable resources and bus-mastering */ + tmp = sys_read32(data->cfg_addr + PCI_COMMAND); + tmp |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + sys_write32(tmp, data->cfg_addr + PCI_COMMAND); + + for (int i = 0; i < DMA_RANGES_IDX; i++) { + pcie_brcmstb_set_outbound_win(dev, i, config->common->ranges[i].host_map_addr, + config->common->ranges[i].pcie_bus_addr, + config->common->ranges[i].map_length); + } + + /* Assign BARs */ + /* TODO: It might be possible to do this without extra property */ + for (int i = 1; i < config->regs_count; i++) { + sys_write32(config->regs[i].addr, data->cfg_addr + PCIE_EXT_CFG_DATA + + PCI_BASE_ADDRESS_0 + 0x4 * (i - 1)); + } + + /* Enable resources */ + tmp = sys_read32(data->cfg_addr + PCIE_EXT_CFG_DATA + PCI_COMMAND); + tmp |= PCI_COMMAND_MEMORY; + sys_write32(tmp, data->cfg_addr + PCIE_EXT_CFG_DATA + PCI_COMMAND); + k_busy_wait(500000); + + return 0; +} + +#define PCIE_BRCMSTB_INIT(n) \ + static struct pcie_brcmstb_data pcie_brcmstb_data_##n = {}; \ + \ + static const struct pcie_ctrl_config pcie_ctrl_cfg_##n = { \ + .cfg_addr = DT_INST_REG_ADDR(n), \ + .cfg_size = DT_INST_REG_SIZE(n), \ + .ranges_count = DT_NUM_RANGES(DT_DRV_INST(n)), \ + .ranges = {DT_FOREACH_RANGE(DT_DRV_INST(n), PCIE_RANGE_FORMAT)}, \ + }; \ + \ + static const struct pcie_brcmstb_config pcie_brcmstb_cfg_##n = { \ + .common = &pcie_ctrl_cfg_##n, \ + .regs_count = DT_NUM_REGS(DT_DRV_INST(n)), \ + .regs = \ + { \ + {DT_REG_ADDR_BY_IDX(DT_DRV_INST(n), 0), \ + DT_REG_SIZE_BY_IDX(DT_DRV_INST(n), 0)}, \ + {DT_REG_ADDR_BY_IDX(DT_DRV_INST(n), 1), \ + DT_REG_SIZE_BY_IDX(DT_DRV_INST(n), 1)}, \ + {DT_REG_ADDR_BY_IDX(DT_DRV_INST(n), 2), \ + DT_REG_SIZE_BY_IDX(DT_DRV_INST(n), 2)}, \ + }, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, pcie_brcmstb_init, NULL, &pcie_brcmstb_data_##n, \ + &pcie_brcmstb_cfg_##n, PRE_KERNEL_1, CONFIG_PCIE_INIT_PRIORITY, \ + &pcie_brcmstb_api); + +DT_INST_FOREACH_STATUS_OKAY(PCIE_BRCMSTB_INIT) diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index d2834504eb2e0..08ecc2fc65e70 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX pinctrl_imx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SIFIVE pinctrl_sifive.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_IOCON pinctrl_lpc_iocon.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_CC13XX_CC26XX pinctrl_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_CC23X0 pinctrl_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ESP32 pinctrl_esp32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RV32M1 pinctrl_rv32m1.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_INFINEON_CAT1 pinctrl_ifx_cat1.c) @@ -29,6 +30,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_XLNX_ZYNQMP pinctrl_xlnx_zynqmp.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_XMC4XXX pinctrl_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_S32 pinctrl_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_GECKO pinctrl_gecko.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_SILABS_SIWX91X pinctrl_silabs_siwx91x.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SILABS_DBUS pinctrl_silabs_dbus.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TI_K3 pinctrl_ti_k3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_EMSDP pinctrl_emsdp.c) @@ -42,5 +44,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_MAX32 pinctrl_max32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCMI pinctrl_imx_scmi.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_MEC5 pinctrl_mchp_mec5.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_AFIO pinctrl_wch_afio.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_SY1XX pinctrl_sy1xx.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_REALTEK_RTS5912 pinctrl_realtek_rts5912.c) add_subdirectory(renesas) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d8621e7ad9e1d..e5a7da34c6f9e 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -50,6 +50,7 @@ source "drivers/pinctrl/Kconfig.imx" source "drivers/pinctrl/Kconfig.sifive" source "drivers/pinctrl/Kconfig.lpc_iocon" source "drivers/pinctrl/Kconfig.cc13xx_cc26xx" +source "drivers/pinctrl/Kconfig.cc23x0" source "drivers/pinctrl/Kconfig.esp32" source "drivers/pinctrl/Kconfig.rv32m1" source "drivers/pinctrl/Kconfig.ifx_cat1" @@ -58,6 +59,7 @@ source "drivers/pinctrl/Kconfig.xmc4xxx" source "drivers/pinctrl/Kconfig.nxp_s32" source "drivers/pinctrl/Kconfig.gecko" source "drivers/pinctrl/Kconfig.silabs_dbus" +source "drivers/pinctrl/Kconfig.siwx91x" source "drivers/pinctrl/Kconfig.ti_k3" source "drivers/pinctrl/Kconfig.emsdp" source "drivers/pinctrl/Kconfig.ti_cc32xx" @@ -69,6 +71,8 @@ source "drivers/pinctrl/Kconfig.zynqmp" source "drivers/pinctrl/Kconfig.max32" source "drivers/pinctrl/Kconfig.mec5" source "drivers/pinctrl/Kconfig.wch_afio" +source "drivers/pinctrl/Kconfig.sy1xx" +source "drivers/pinctrl/Kconfig.realtek_rts5912" rsource "renesas/Kconfig" diff --git a/drivers/pinctrl/Kconfig.cc23x0 b/drivers/pinctrl/Kconfig.cc23x0 new file mode 100644 index 0000000000000..f10e2215aa05e --- /dev/null +++ b/drivers/pinctrl/Kconfig.cc23x0 @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_CC23X0 + bool "TI SimpleLink CC23X0 pinctrl driver" + default y + depends on DT_HAS_TI_CC23X0_PINCTRL_ENABLED + help + Enable the TI SimpleLink CC23X0 pinctrl driver diff --git a/drivers/pinctrl/Kconfig.imx b/drivers/pinctrl/Kconfig.imx index ceb61d7451394..a79d91e28b90b 100644 --- a/drivers/pinctrl/Kconfig.imx +++ b/drivers/pinctrl/Kconfig.imx @@ -26,6 +26,12 @@ config PINCTRL_IMX_SCMI # TODO: Find better place for this option config MCUX_XBARA bool "MCUX XBARA driver" - depends on HAS_MCUX_XBARA + depends on DT_HAS_NXP_MCUX_XBAR_ENABLED help Enable the MCUX XBARA driver. + +config MCUX_XBARB + bool "MCUX XBARB driver" + depends on DT_HAS_NXP_MCUX_XBAR_ENABLED + help + Enable the MCUX XBARB driver. diff --git a/drivers/pinctrl/Kconfig.realtek_rts5912 b/drivers/pinctrl/Kconfig.realtek_rts5912 new file mode 100644 index 0000000000000..925729389abd7 --- /dev/null +++ b/drivers/pinctrl/Kconfig.realtek_rts5912 @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config PINCTRL_REALTEK_RTS5912 + bool "Pin controller driver for REALTEK RTS MCUs" + depends on SOC_SERIES_RTS5912 + default y if DT_HAS_REALTEK_RTS5912_PINCTRL_ENABLED + help + Enable pin controller driver for REALTEK RTS MCUs diff --git a/drivers/pinctrl/Kconfig.siwx91x b/drivers/pinctrl/Kconfig.siwx91x new file mode 100644 index 0000000000000..7c803364dde76 --- /dev/null +++ b/drivers/pinctrl/Kconfig.siwx91x @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_SILABS_SIWX91X + bool "Silabs SiWx91x SoC series pinctrl driver" + default y + depends on DT_HAS_SILABS_SIWX91X_PINCTRL_ENABLED + help + Enable the pinctrl driver for the Silabs SiWx91x SoC series. diff --git a/drivers/pinctrl/Kconfig.sy1xx b/drivers/pinctrl/Kconfig.sy1xx new file mode 100644 index 0000000000000..857920bf9d812 --- /dev/null +++ b/drivers/pinctrl/Kconfig.sy1xx @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 sensry.io + +config PINCTRL_SY1XX + bool "Sensry sy1xx pin controller driver" + default y + depends on DT_HAS_SENSRY_SY1XX_PINCTRL_ENABLED + help + Sensry pin controller driver is used on sy1xx SoC series diff --git a/drivers/pinctrl/pinctrl_cc23x0.c b/drivers/pinctrl/pinctrl_cc23x0.c new file mode 100644 index 0000000000000..41ce0be662e97 --- /dev/null +++ b/drivers/pinctrl/pinctrl_cc23x0.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_pinctrl + +#include + +#include + +#define IOC_BASE_REG DT_REG_ADDR(DT_NODELABEL(pinctrl)) +#define IOC_BASE_PIN_REG 0x00000100 +#define IOC_ADDR(index) (IOC_BASE_REG + IOC_BASE_PIN_REG + (sizeof(uint32_t) * (index))) + +static int pinctrl_cc23x0_set(uint32_t pin, uint32_t func, uint32_t mode) +{ + uint32_t iocfg_reg = IOC_ADDR(pin); + + HWREG(iocfg_reg) = mode | func; + + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (uint8_t i = 0U; i < pin_cnt; i++) { + pinctrl_cc23x0_set(pins[i].pin, pins[i].iofunc, pins[i].iomode); + } + + return 0; +} diff --git a/drivers/pinctrl/pinctrl_gecko.c b/drivers/pinctrl/pinctrl_gecko.c index db8f5523c0156..ffca6c45e2b56 100644 --- a/drivers/pinctrl/pinctrl_gecko.c +++ b/drivers/pinctrl/pinctrl_gecko.c @@ -142,7 +142,7 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp #endif /* CONFIG_SOC_FAMILY_SILABS_S1 */ #endif /* CONFIG_UART_GECKO */ -#ifdef CONFIG_SPI_GECKO_USART +#ifdef CONFIG_SPI_SILABS_USART #ifdef CONFIG_SOC_FAMILY_SILABS_S1 case GECKO_FUN_SPIM_SCK: pin_config.mode = gpioModePushPull; @@ -224,7 +224,7 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp base->ROUTELOC0 |= (loc << _USART_ROUTELOC0_CSLOC_SHIFT); break; #endif /* CONFIG_SOC_FAMILY_SILABS_S1 */ -#endif /* CONFIG_SPI_GECKO_USART */ +#endif /* CONFIG_SPI_SILABS_USART */ #ifdef CONFIG_I2C_GECKO case GECKO_FUN_I2C_SDA: diff --git a/drivers/pinctrl/pinctrl_imx.c b/drivers/pinctrl/pinctrl_imx.c index 8d60cea5817bc..51a81f134ea7c 100644 --- a/drivers/pinctrl/pinctrl_imx.c +++ b/drivers/pinctrl/pinctrl_imx.c @@ -1,5 +1,5 @@ /* - * Copyright 2022, 2024 NXP + * Copyright 2022, 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,7 +33,7 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, } #endif -#ifdef CONFIG_SOC_MIMX9352 +#if defined(CONFIG_SOC_MIMX9352) || defined(CONFIG_SOC_MIMX9131) sys_write32(IOMUXC1_SW_MUX_CTL_PAD_MUX_MODE(mux_mode) | IOMUXC1_SW_MUX_CTL_PAD_SION(MCUX_IMX_INPUT_ENABLE(pin_ctrl_flags)), (mem_addr_t)mux_register); diff --git a/drivers/pinctrl/pinctrl_lpc_iocon.c b/drivers/pinctrl/pinctrl_lpc_iocon.c index 805cd46849ba0..ff85bb0cbba69 100644 --- a/drivers/pinctrl/pinctrl_lpc_iocon.c +++ b/drivers/pinctrl/pinctrl_lpc_iocon.c @@ -1,5 +1,5 @@ /* - * Copyright 2022, NXP + * Copyright 2022,2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,22 +11,40 @@ #include #endif +/* IOCON register addresses. */ +static uint32_t volatile *iocon[] = { +#if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(iocon))) + (uint32_t *)DT_REG_ADDR(DT_NODELABEL(iocon)), +#else + NULL, +#endif +#if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(iocon1))) + (uint32_t *)DT_REG_ADDR(DT_NODELABEL(iocon1)), +#else + NULL, +#endif +#if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(iocon2))) + (uint32_t *)DT_REG_ADDR(DT_NODELABEL(iocon2)), +#else + NULL, +#endif +}; + #define OFFSET(mux) (((mux) & 0xFFF00000) >> 20) #define TYPE(mux) (((mux) & 0xC0000) >> 18) +#define INDEX(mux) (((mux) & 0x38000) >> 15) #define IOCON_TYPE_D 0x0 #define IOCON_TYPE_I 0x1 #define IOCON_TYPE_A 0x2 -static volatile uint32_t *iocon = - (volatile uint32_t *)DT_REG_ADDR(DT_NODELABEL(iocon)); -int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, - uintptr_t reg) +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) { for (uint8_t i = 0; i < pin_cnt; i++) { uint32_t pin_mux = pins[i]; uint32_t offset = OFFSET(pin_mux); + uint8_t index = INDEX(pin_mux); /* Check if this is an analog or i2c type pin */ switch (TYPE(pin_mux)) { @@ -44,7 +62,8 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, __ASSERT_NO_MSG(TYPE(pin_mux) <= IOCON_TYPE_A); } /* Set pinmux */ - *(iocon + offset) = pin_mux; + *(iocon[index] + offset) = pin_mux; + } return 0; } diff --git a/drivers/pinctrl/pinctrl_nrf.c b/drivers/pinctrl/pinctrl_nrf.c index d3689a2796c25..3ede211958ac8 100644 --- a/drivers/pinctrl/pinctrl_nrf.c +++ b/drivers/pinctrl/pinctrl_nrf.c @@ -94,6 +94,20 @@ static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = { #define NRF_PSEL_QSPI(reg, line) ((NRF_QSPI_Type *)reg)->PSEL.line #endif +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_twis) || defined(CONFIG_NRFX_TWIS) +#include +#define NRF_PSEL_TWIS(reg, line) ((NRF_TWIS_Type *)reg)->PSEL.line +#endif + +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_grtc) || defined(CONFIG_NRFX_GRTC) +#if DT_NODE_HAS_PROP(DT_NODELABEL(grtc), clkout_fast_frequency_hz) +#define NRF_GRTC_CLKOUT_FAST 1 +#endif +#if DT_NODE_HAS_PROP(DT_NODELABEL(grtc), clkout_32k) +#define NRF_GRTC_CLKOUT_SLOW 1 +#endif +#endif + int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) { @@ -340,6 +354,24 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, input = NRF_GPIO_PIN_INPUT_DISCONNECT; break; #endif /* defined(NRF_PSEL_QSPI) */ +#if defined(NRF_GRTC_CLKOUT_FAST) + case NRF_FUN_GRTC_CLKOUT_FAST: +#if NRF_GPIO_HAS_SEL && defined(GPIO_PIN_CNF_CTRLSEL_GRTC) + nrf_gpio_pin_control_select(psel, NRF_GPIO_PIN_SEL_GRTC); +#endif + dir = NRF_GPIO_PIN_DIR_OUTPUT; + input = NRF_GPIO_PIN_INPUT_DISCONNECT; + break; +#endif /* defined(NRF_GRTC_CLKOUT_FAST) */ +#if defined(NRF_GRTC_CLKOUT_SLOW) + case NRF_FUN_GRTC_CLKOUT_32K: +#if NRF_GPIO_HAS_SEL && defined(GPIO_PIN_CNF_CTRLSEL_GRTC) + nrf_gpio_pin_control_select(psel, NRF_GPIO_PIN_SEL_GRTC); +#endif + dir = NRF_GPIO_PIN_DIR_OUTPUT; + input = NRF_GPIO_PIN_INPUT_DISCONNECT; + break; +#endif /* defined(NRF_GRTC_CLKOUT_SLOW) */ #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_can) /* Pin routing is controlled by secure domain, via UICR */ case NRF_FUN_CAN_TX: @@ -351,6 +383,24 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, input = NRF_GPIO_PIN_INPUT_CONNECT; break; #endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_can) */ +#if defined(NRF_PSEL_TWIS) + case NRF_FUN_TWIS_SCL: + NRF_PSEL_TWIS(reg, SCL) = psel; + if (drive == NRF_GPIO_PIN_S0S1) { + drive = NRF_GPIO_PIN_S0D1; + } + dir = NRF_GPIO_PIN_DIR_INPUT; + input = NRF_GPIO_PIN_INPUT_CONNECT; + break; + case NRF_FUN_TWIS_SDA: + NRF_PSEL_TWIS(reg, SDA) = psel; + if (drive == NRF_GPIO_PIN_S0S1) { + drive = NRF_GPIO_PIN_S0D1; + } + dir = NRF_GPIO_PIN_DIR_INPUT; + input = NRF_GPIO_PIN_INPUT_CONNECT; + break; +#endif /* defined(NRF_PSEL_TWIS) */ default: return -ENOTSUP; } diff --git a/drivers/pinctrl/pinctrl_realtek_rts5912.c b/drivers/pinctrl/pinctrl_realtek_rts5912.c new file mode 100644 index 0000000000000..5764a73f086ce --- /dev/null +++ b/drivers/pinctrl/pinctrl_realtek_rts5912.c @@ -0,0 +1,38 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#define DT_DRV_COMPAT realtek_rts5912_pinctrl + +#include +#include + +#include + +#define REALTEK_RTS5912_PINMUX_GET_GPIO_PIN(n) \ + (((((n) >> REALTEK_RTS5912_GPIO_LOW_POS) & REALTEK_RTS5912_GPIO_LOW_MSK)) | \ + (((((n) >> REALTEK_RTS5912_GPIO_HIGH_POS) & REALTEK_RTS5912_GPIO_HIGH_MSK)) << 5)) + +#define PURE_PINMUX_MASK (GENMASK(31, 24) | GENMASK(17, 8) | GENMASK(2, 0)) +#define REALTEK_RTS5912_GET_PURE_PINMUX(n) (n & PURE_PINMUX_MASK) + +static volatile GPIO_Type *pinctrl_base = + (volatile GPIO_Type *)(DT_REG_ADDR(DT_NODELABEL(pinctrl))); + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + uint32_t pin, pinmux, func; + + for (uint8_t i = 0U; i < pin_cnt; i++) { + pinmux = (uint32_t)pins[i]; + pin = REALTEK_RTS5912_PINMUX_GET_GPIO_PIN(pinmux); + func = REALTEK_RTS5912_GET_PURE_PINMUX(pinmux); + pinctrl_base->GCR[pin] = func; + } + + return 0; +} diff --git a/drivers/pinctrl/pinctrl_silabs_dbus.c b/drivers/pinctrl/pinctrl_silabs_dbus.c index be918847b1688..022ce27e18c7e 100644 --- a/drivers/pinctrl/pinctrl_silabs_dbus.c +++ b/drivers/pinctrl/pinctrl_silabs_dbus.c @@ -11,6 +11,7 @@ #define DT_DRV_COMPAT silabs_dbus_pinctrl #define PIN_MASK 0xF0000UL +#define ABUS_MASK(i) GENMASK(((i) * 8) + 3, (i) * 8) int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) { @@ -19,17 +20,31 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp for (uint8_t i = 0U; i < pin_cnt; i++) { mem_addr_t enable_reg, route_reg; + /* Configure ABUS */ + if (pins[i].en_bit == SILABS_PINCTRL_ANALOG) { + enable_reg = DT_INST_REG_ADDR_BY_NAME(0, abus) + + (pins[i].base_offset * sizeof(mem_addr_t)); + sys_write32(FIELD_PREP(ABUS_MASK(pins[i].mode), pins[i].route_offset), + enable_reg); + continue; + } + /* Configure GPIO */ GPIO_PinModeSet(pins[i].port, pins[i].pin, pins[i].mode, pins[i].dout); /* Configure DBUS */ - enable_reg = DT_INST_REG_ADDR(0) + (pins[i].base_offset * sizeof(mem_addr_t)); + enable_reg = DT_INST_REG_ADDR_BY_NAME(0, dbus) + + (pins[i].base_offset * sizeof(mem_addr_t)); route_reg = enable_reg + (pins[i].route_offset * sizeof(mem_addr_t)); sys_write32(pins[i].port | FIELD_PREP(PIN_MASK, pins[i].pin), route_reg); - if (pins[i].en_bit != 0xFFU) { - sys_set_bit(enable_reg, pins[i].en_bit); + if (pins[i].en_bit != SILABS_PINCTRL_UNUSED) { + if (pins[i].mode == gpioModeDisabled) { + sys_clear_bit(enable_reg, pins[i].en_bit); + } else { + sys_set_bit(enable_reg, pins[i].en_bit); + } } } diff --git a/drivers/pinctrl/pinctrl_silabs_siwx91x.c b/drivers/pinctrl/pinctrl_silabs_siwx91x.c new file mode 100644 index 0000000000000..2e3a9f62488b4 --- /dev/null +++ b/drivers/pinctrl/pinctrl_silabs_siwx91x.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT silabs_siwx91x_pinctrl + +#include +#include "sl_si91x_peripheral_gpio.h" + +#define MODE_COUNT 16 +#define HP_PERIPHERAL_ON_ULP_PIN 6 + +static bool pinctrl_siwx91x_valid_mode(uint8_t mode) +{ + return mode < MODE_COUNT; +} + +static void pinctrl_siwx91x_set(uint8_t port, uint8_t pin, uint8_t ulppin, uint8_t mode, + uint8_t ulpmode, uint8_t pad) +{ + if (pad == 0) { + sl_si91x_gpio_enable_host_pad_selection((port << 4) | pin); + } else if (pad != 0xFF && pad != 9) { + sl_si91x_gpio_enable_pad_selection(pad); + } + + if (port == SL_GPIO_ULP_PORT) { + sl_si91x_gpio_enable_ulp_pad_receiver(ulppin); + } else { + sl_si91x_gpio_enable_pad_receiver((port << 4) | pin); + } + + if (pinctrl_siwx91x_valid_mode(mode)) { + GPIO->PIN_CONFIG[(port << 4) | pin].GPIO_CONFIG_REG_b.MODE = mode; + } + + if (pinctrl_siwx91x_valid_mode(ulpmode)) { + if (pinctrl_siwx91x_valid_mode(mode) && ulpmode != HP_PERIPHERAL_ON_ULP_PIN) { + sl_si91x_gpio_ulp_soc_mode(ulppin, ulpmode); + ulpmode = 0; + } + ULP_GPIO->PIN_CONFIG[ulppin].GPIO_CONFIG_REG_b.MODE = ulpmode; + } +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + int i; + + for (i = 0; i < pin_cnt; i++) { + pinctrl_siwx91x_set(pins[i].port, pins[i].pin, pins[i].ulppin, pins[i].mode, + pins[i].ulpmode, pins[i].pad); + } + + return 0; +} diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 9dc3e26f37cca..dd7905e59bedc 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -63,6 +63,7 @@ static const struct device *const gpio_ports[] = { DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpion)), DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpioo)), DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpiop)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpioq)), }; /** Number of GPIO ports. */ @@ -168,19 +169,23 @@ static int stm32_pins_remap(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt) uint32_t reg_val; uint16_t remap; - remap = (uint16_t)STM32_DT_PINMUX_REMAP(pins[0].pinmux); + remap = NO_REMAP; + + for (size_t i = 0U; i < pin_cnt; i++) { + if (remap == NO_REMAP) { + remap = STM32_DT_PINMUX_REMAP(pins[i].pinmux); + } else if (STM32_DT_PINMUX_REMAP(pins[i].pinmux) == NO_REMAP) { + continue; + } else if (STM32_DT_PINMUX_REMAP(pins[i].pinmux) != remap) { + return -EINVAL; + } + } /* not remappable */ if (remap == NO_REMAP) { return 0; } - for (size_t i = 1U; i < pin_cnt; i++) { - if (STM32_DT_PINMUX_REMAP(pins[i].pinmux) != remap) { - return -EINVAL; - } - } - /* A valid remapping configuration is available */ /* Apply remapping before proceeding with pin configuration */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO); diff --git a/drivers/pinctrl/pinctrl_sy1xx.c b/drivers/pinctrl/pinctrl_sy1xx.c new file mode 100644 index 0000000000000..1343ba2c98739 --- /dev/null +++ b/drivers/pinctrl/pinctrl_sy1xx.c @@ -0,0 +1,59 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 sensry.io + */ + +#define DT_DRV_COMPAT sensry_sy1xx_pinctrl + +#include +#include +#include + +#include + +static uint32_t pinctrl0_base_addr = DT_REG_ADDR(DT_NODELABEL(pinctrl)); +static uint32_t pinctrl0_base_mask = DT_REG_SIZE(DT_NODELABEL(pinctrl)) - 1; + +/** + * @brief Configure a pin. + * + * @param pin The pin to configure. + */ +static int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint32_t addr = (pin->addr & pinctrl0_base_mask) | pinctrl0_base_addr; + + switch (pin->iro) { + case 0: + case 8: + case 16: + case 24: + /* fall through */ + break; + default: + /* invalid inter address offset */ + return -EINVAL; + } + + uint32_t reg = ~(0xFFUL << pin->iro) & sys_read32(addr); + + reg |= FIELD_PREP((0xFFUL << pin->iro), pin->cfg); + sys_write32(reg, addr); + + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (uint8_t i = 0U; i < pin_cnt; i++) { + int ret = pinctrl_configure_pin(pins++); + + if (ret < 0) { + return ret; + } + } + + return 0; +} diff --git a/drivers/pinctrl/pinctrl_wch_afio.c b/drivers/pinctrl/pinctrl_wch_afio.c index ede0acaaae7bc..4a56787d56503 100644 --- a/drivers/pinctrl/pinctrl_wch_afio.c +++ b/drivers/pinctrl/pinctrl_wch_afio.c @@ -28,6 +28,10 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintp uint32_t pcfr1 = AFIO->PCFR1; uint8_t cfg = 0; + if (remap != 0) { + RCC->APB2PCENR |= RCC_AFIOEN; + } + if (pins->output_high || pins->output_low) { cfg |= (pins->slew_rate + 1); if (pins->drive_open_drain) { diff --git a/drivers/pinctrl/renesas/CMakeLists.txt b/drivers/pinctrl/renesas/CMakeLists.txt index 80e4c95ec14ea..4d42052917892 100644 --- a/drivers/pinctrl/renesas/CMakeLists.txt +++ b/drivers/pinctrl/renesas/CMakeLists.txt @@ -5,5 +5,6 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_RENESAS_RA_PFS ra/pinctrl_ra.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RZT2M rz/pinctrl_rzt2m.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SMARTBOND smartbond/pinctrl_smartbond.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_RENESAS_RZ rz/pinctrl_renesas_rz.c) add_subdirectory_ifdef(CONFIG_PINCTRL_RCAR_PFC rcar) diff --git a/drivers/pinctrl/renesas/rz/Kconfig b/drivers/pinctrl/renesas/rz/Kconfig index 236afdcf55ec3..745496b8f1700 100644 --- a/drivers/pinctrl/renesas/rz/Kconfig +++ b/drivers/pinctrl/renesas/rz/Kconfig @@ -1,4 +1,5 @@ # Copyright (c) 2023 Antmicro +# Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 config PINCTRL_RZT2M @@ -7,3 +8,11 @@ config PINCTRL_RZT2M depends on DT_HAS_RENESAS_RZT2M_PINCTRL_ENABLED help Renesas RZ/T2M pinctrl driver + +config PINCTRL_RENESAS_RZ + bool "Renesas RZ pin controller driver" + default y + depends on DT_HAS_RENESAS_RZG_PINCTRL_ENABLED + select USE_RZ_FSP_IOPORT + help + Enable Renesas RZ pinctrl driver. diff --git a/drivers/pinctrl/renesas/rz/pinctrl_renesas_rz.c b/drivers/pinctrl/renesas/rz/pinctrl_renesas_rz.c new file mode 100644 index 0000000000000..8ed2e8c4015ec --- /dev/null +++ b/drivers/pinctrl/renesas/rz/pinctrl_renesas_rz.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "r_ioport.h" + +static void pinctrl_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint32_t cfg = *(uint32_t *)&pin->config; + + R_IOPORT_PinCfg(NULL, pin->port_pin, cfg); +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (uint8_t i = 0U; i < pin_cnt; i++) { + pinctrl_configure_pin(pins++); + } + + return 0; +} diff --git a/drivers/power_domain/CMakeLists.txt b/drivers/power_domain/CMakeLists.txt index dedd7a50dffa6..d459e0d88c372 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO power_domain_gpio.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO_MONITOR power_domain_gpio_monitor.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_adsp.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NXP_SCU power_domain_nxp_scu.c) +zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_SOC_PM_STATE power_domain_soc_state_change.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index f29057acf5c9d..7bf5fe42470fe 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -90,4 +90,13 @@ config POWER_DOMAIN_NXP_SCU_INIT_PRIORITY endif #POWER_DOMAIN_NXP_SCU +config POWER_DOMAIN_SOC_PM_STATE + bool "SoC PM state power domain" + default y + depends on DT_HAS_POWER_DOMAIN_SOC_STATE_CHANGE_ENABLED + select DEVICE_DEPS + help + Generic power domain control to turn on/off devices when the + PM subsystem transitions in and out certain power states. + endif diff --git a/drivers/power_domain/power_domain_soc_state_change.c b/drivers/power_domain/power_domain_soc_state_change.c new file mode 100644 index 0000000000000..e177c60b4e4be --- /dev/null +++ b/drivers/power_domain/power_domain_soc_state_change.c @@ -0,0 +1,117 @@ +/* + * Copyright 2024-25 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(power_domain_soc_state_change, CONFIG_POWER_DOMAIN_LOG_LEVEL); + +/* Indicates the end of the onoff_power_states array */ +#define POWER_DOMAIN_DEVICE_ONOFF_STATE_MARKER 0xFF + +struct pd_deviceonoff_config { + uint8_t *onoff_power_states; +}; + +struct pd_visitor_context { + const struct device *domain; + enum pm_device_action action; +}; + +static int pd_domain_visitor(const struct device *dev, void *context) +{ + struct pd_visitor_context *visitor_context = context; + + /* Only run action if the device is on the specified domain */ + if (!dev->pm || (dev->pm_base->domain != visitor_context->domain)) { + return 0; + } + + /* In case device is active, first suspend it before turning it off */ + if ((visitor_context->action == PM_DEVICE_ACTION_TURN_OFF) && + (dev->pm_base->state == PM_DEVICE_STATE_ACTIVE)) { + (void)pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); + } + (void)pm_device_action_run(dev, visitor_context->action); + return 0; +} + +static int pd_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct pd_deviceonoff_config *config = dev->config; + uint8_t i = 0; + /* Get the next power state that will be used */ + enum pm_state state = pm_state_next_get(_current_cpu->id)->state; + struct pd_visitor_context context = {.domain = dev}; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + LOG_DBG("%s: resuming", dev->name); + while (config->onoff_power_states[i] != POWER_DOMAIN_DEVICE_ONOFF_STATE_MARKER) { + /* Check if we need do the turn on action for this state */ + if (state == config->onoff_power_states[i]) { + /* Notify devices on the domain they are now powered */ + context.action = PM_DEVICE_ACTION_TURN_ON; + (void)device_supported_foreach(dev, pd_domain_visitor, &context); + /* No need to go through the rest of the array of states */ + break; + } + i++; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + LOG_DBG("%s: suspending", dev->name); + while (config->onoff_power_states[i] != POWER_DOMAIN_DEVICE_ONOFF_STATE_MARKER) { + /* Check if need to do the turn off action for this state */ + if (state == config->onoff_power_states[i]) { + /* Notify devices on the domain that power is going down */ + context.action = PM_DEVICE_ACTION_TURN_OFF; + (void)device_supported_foreach(dev, pd_domain_visitor, &context); + /* No need to go through the rest of the array of states */ + break; + } + i++; + } + break; + case PM_DEVICE_ACTION_TURN_ON: + break; + case PM_DEVICE_ACTION_TURN_OFF: + break; + default: + return -ENOTSUP; + } + + return 0; +} + +#define DT_DRV_COMPAT power_domain_soc_state_change + +#define PM_STATE_FROM_DT(i, node_id, prop_name) \ + COND_CODE_1(DT_NODE_HAS_STATUS(DT_PHANDLE_BY_IDX(node_id, prop_name, i), okay), \ + (PM_STATE_DT_INIT(DT_PHANDLE_BY_IDX(node_id, prop_name, i)),), ()) + +#define POWER_DOMAIN_DEVICE_ONOFF_STATES(id, node_id) \ + uint8_t onoff_states_##id[] = { \ + LISTIFY(DT_PROP_LEN_OR(node_id, onoff_power_states, 0), \ + PM_STATE_FROM_DT, (), node_id, onoff_power_states) \ + POWER_DOMAIN_DEVICE_ONOFF_STATE_MARKER \ + }; + +#define POWER_DOMAIN_DEVICE(id) \ + POWER_DOMAIN_DEVICE_ONOFF_STATES(id, DT_DRV_INST(id)) \ + \ + static const struct pd_deviceonoff_config pd_deviceonoff_##id##_cfg = { \ + .onoff_power_states = onoff_states_##id, \ + }; \ + PM_DEVICE_DT_INST_DEFINE(id, pd_pm_action); \ + DEVICE_DT_INST_DEFINE(id, NULL, PM_DEVICE_DT_INST_GET(id), \ + NULL, &pd_deviceonoff_##id##_cfg, PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL); + +DT_INST_FOREACH_STATUS_OKAY(POWER_DOMAIN_DEVICE) diff --git a/drivers/ptp_clock/Kconfig b/drivers/ptp_clock/Kconfig index 74ab3e14eb852..f6479b65aab53 100644 --- a/drivers/ptp_clock/Kconfig +++ b/drivers/ptp_clock/Kconfig @@ -1,7 +1,7 @@ # Copyright (c) 2018 Intel Corporation. # SPDX-License-Identifier: Apache-2.0 -config PTP_CLOCK +menuconfig PTP_CLOCK bool "Precision Time Protocol (PTP) Clock drivers" help Enable options for Precision Time Protocol Clock drivers. diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index e5c30af25c817..c194ac8485fb0 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -26,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_RV32M1_TPM pwm_rv32m1_tpm.c) zephyr_library_sources_ifdef(CONFIG_PWM_MAX32 pwm_max32.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_TPM pwm_mcux_tpm.c) zephyr_library_sources_ifdef(CONFIG_PWM_SAM0_TCC pwm_sam0_tcc.c) +zephyr_library_sources_ifdef(CONFIG_PWM_SAM0_TC pwm_sam0_tc.c) zephyr_library_sources_ifdef(CONFIG_PWM_NPCX pwm_npcx.c) zephyr_library_sources_ifdef(CONFIG_PWM_XLNX_AXI_TIMER pwm_xlnx_axi_timer.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_PWT pwm_mcux_pwt.c) @@ -45,9 +46,10 @@ zephyr_library_sources_ifdef(CONFIG_PWM_NUMAKER pwm_numaker.c) zephyr_library_sources_ifdef(CONFIG_PWM_NXP_FLEXIO pwm_nxp_flexio.c) zephyr_library_sources_ifdef(CONFIG_PWM_NXP_S32_EMIOS pwm_nxp_s32_emios.c) zephyr_library_sources_ifdef(CONFIG_PWM_ENE_KB1200 pwm_ene_kb1200.c) -zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RA8 pwm_renesas_ra8.c) +zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RA pwm_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_PWM_INFINEON_CAT1 pwm_ifx_cat1.c) - +zephyr_library_sources_ifdef(CONFIG_PWM_FAKE pwm_fake.c) +zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RZ_GPT pwm_renesas_rz_gpt.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE pwm_handlers.c) zephyr_library_sources_ifdef(CONFIG_PWM_CAPTURE pwm_capture.c) zephyr_library_sources_ifdef(CONFIG_PWM_SHELL pwm_shell.c) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 5584b68cd9aac..0dd835a8973c2 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -74,6 +74,8 @@ source "drivers/pwm/Kconfig.mcux_tpm" source "drivers/pwm/Kconfig.sam0" +source "drivers/pwm/Kconfig.sam0_tc" + source "drivers/pwm/Kconfig.npcx" source "drivers/pwm/Kconfig.xlnx" @@ -110,8 +112,12 @@ source "drivers/pwm/Kconfig.nxp_flexio" source "drivers/pwm/Kconfig.ene" -source "drivers/pwm/Kconfig.renesas_ra8" +source "drivers/pwm/Kconfig.renesas_ra" source "drivers/pwm/Kconfig.ifx_cat1" +source "drivers/pwm/Kconfig.fake" + +source "drivers/pwm/Kconfig.renesas_rz" + endif # PWM diff --git a/drivers/pwm/Kconfig.b91 b/drivers/pwm/Kconfig.b91 index 9e710b4a6de13..4102483ebc02c 100644 --- a/drivers/pwm/Kconfig.b91 +++ b/drivers/pwm/Kconfig.b91 @@ -5,5 +5,6 @@ config PWM_TELINK_B91 bool "Telink Semiconductor B91 PWM driver" default y depends on DT_HAS_TELINK_B91_PWM_ENABLED + select PINCTRL help Enables Telink B91 PWM driver. diff --git a/drivers/pwm/Kconfig.cc13xx_cc26xx_timer b/drivers/pwm/Kconfig.cc13xx_cc26xx_timer index c111ad307fae8..11d8b90ac9ef9 100644 --- a/drivers/pwm/Kconfig.cc13xx_cc26xx_timer +++ b/drivers/pwm/Kconfig.cc13xx_cc26xx_timer @@ -5,5 +5,6 @@ config PWM_CC13XX_CC26XX_TIMER bool "TI SimpleLink CC13xx/CC26xx GPT timer PWM driver" default y depends on DT_HAS_TI_CC13XX_CC26XX_TIMER_PWM_ENABLED + select PINCTRL help Enables TI SimpleLink CC13xx/CC26xx GPT timer PWM driver. diff --git a/drivers/pwm/Kconfig.fake b/drivers/pwm/Kconfig.fake new file mode 100644 index 0000000000000..bc7fa46ee74b9 --- /dev/null +++ b/drivers/pwm/Kconfig.fake @@ -0,0 +1,11 @@ +# Fake PWM configuration options + +# Copyright (c) 2024 Kickmaker +# SPDX-License-Identifier: Apache-2.0 + +config PWM_FAKE + bool "Fake PWM driver" + default y + depends on DT_HAS_ZEPHYR_FAKE_PWM_ENABLED + help + Enable support for the FFF-based fake PWM driver. diff --git a/drivers/pwm/Kconfig.mcux_ftm b/drivers/pwm/Kconfig.mcux_ftm index 9af580f117cda..b9ed7c629bc81 100644 --- a/drivers/pwm/Kconfig.mcux_ftm +++ b/drivers/pwm/Kconfig.mcux_ftm @@ -6,10 +6,10 @@ config PWM_MCUX_FTM bool "MCUX FTM PWM driver" default y - depends on DT_HAS_NXP_KINETIS_FTM_PWM_ENABLED + depends on DT_HAS_NXP_FTM_PWM_ENABLED select PINCTRL help - Enable support for mcux ftm pwm driver. + Enable support for MCUX FTM PWM driver. config PWM_CAPTURE_MCUX_FTM_FILTER_VALUE int "MCUX FTM PWM capture filter value" diff --git a/drivers/pwm/Kconfig.renesas_ra b/drivers/pwm/Kconfig.renesas_ra new file mode 100644 index 0000000000000..7b7a42be05484 --- /dev/null +++ b/drivers/pwm/Kconfig.renesas_ra @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config PWM_RENESAS_RA + bool "Renesas RA PWM driver" + default y + depends on DT_HAS_RENESAS_RA_PWM_ENABLED + select USE_RA_FSP_GPT + select PINCTRL + help + Enable Renesas RA PWM Driver. diff --git a/drivers/pwm/Kconfig.renesas_ra8 b/drivers/pwm/Kconfig.renesas_ra8 deleted file mode 100644 index b44a1bc971180..0000000000000 --- a/drivers/pwm/Kconfig.renesas_ra8 +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) 2024 Renesas Electronics Corporation -# SPDX-License-Identifier: Apache-2.0 - -config PWM_RENESAS_RA8 - bool "Renesas RA8 PWM driver" - default y - depends on DT_HAS_RENESAS_RA8_PWM_ENABLED - select USE_RA_FSP_GPT - select PINCTRL - help - Enable Renesas RA8 PWM Driver. diff --git a/drivers/pwm/Kconfig.renesas_rz b/drivers/pwm/Kconfig.renesas_rz new file mode 100644 index 0000000000000..2d9a9a831ccd7 --- /dev/null +++ b/drivers/pwm/Kconfig.renesas_rz @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config PWM_RENESAS_RZ_GPT + bool "Renesas RZ General PWM Timer (GPT) PWM driver" + default y + depends on DT_HAS_RENESAS_RZ_GPT_PWM_ENABLED + select USE_RZ_FSP_GPT + help + Enable the PWM driver for the Renesas RZ General PWM Timer (GPT). diff --git a/drivers/pwm/Kconfig.sam0_tc b/drivers/pwm/Kconfig.sam0_tc new file mode 100644 index 0000000000000..41a6f907119e9 --- /dev/null +++ b/drivers/pwm/Kconfig.sam0_tc @@ -0,0 +1,17 @@ +# Atmel SAM0 TCC as PWM configuration + +# Copyright (c) 2020 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config PWM_SAM0_TC + bool "Atmel SAM0 MCU Family TC PWM Driver" + default y + depends on DT_HAS_ATMEL_SAM0_TC_PWM_ENABLED + help + Enable PWM driver for Atmel SAM0 MCUs using the TC timer/counter. + +config PWM_TC_INIT_PRIORITY + int "Init Priority" + default 50 + help + Device driver initialization priority diff --git a/drivers/pwm/pwm_b91.c b/drivers/pwm/pwm_b91.c index c74587db03275..f0d9fa7c04c82 100644 --- a/drivers/pwm/pwm_b91.c +++ b/drivers/pwm/pwm_b91.c @@ -110,7 +110,7 @@ static int pwm_b91_get_cycles_per_sec(const struct device *dev, } /* PWM driver APIs structure */ -static const struct pwm_driver_api pwm_b91_driver_api = { +static DEVICE_API(pwm, pwm_b91_driver_api) = { .set_cycles = pwm_b91_set_cycles, .get_cycles_per_sec = pwm_b91_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_cc13xx_cc26xx_timer.c b/drivers/pwm/pwm_cc13xx_cc26xx_timer.c index 947457b63c753..19837ad08b88b 100644 --- a/drivers/pwm/pwm_cc13xx_cc26xx_timer.c +++ b/drivers/pwm/pwm_cc13xx_cc26xx_timer.c @@ -128,7 +128,7 @@ static int get_cycles_per_sec(const struct device *dev, uint32_t channel, uint64 return 0; } -static const struct pwm_driver_api pwm_driver_api = { +static DEVICE_API(pwm, pwm_driver_api) = { .set_cycles = set_cycles, .get_cycles_per_sec = get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_ene_kb1200.c b/drivers/pwm/pwm_ene_kb1200.c index a54afa878b08e..0ef742d9845a0 100644 --- a/drivers/pwm/pwm_ene_kb1200.c +++ b/drivers/pwm/pwm_ene_kb1200.c @@ -90,7 +90,7 @@ static int pwm_kb1200_get_cycles_per_sec(const struct device *dev, uint32_t chan return 0; } -static const struct pwm_driver_api pwm_kb1200_driver_api = { +static DEVICE_API(pwm, pwm_kb1200_driver_api) = { .set_cycles = pwm_kb1200_set_cycles, .get_cycles_per_sec = pwm_kb1200_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_fake.c b/drivers/pwm/pwm_fake.c new file mode 100644 index 0000000000000..babdce93f9ba6 --- /dev/null +++ b/drivers/pwm/pwm_fake.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Kickmaker + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_ZTEST +#include +#endif /* CONFIG_ZTEST */ + +#define DT_DRV_COMPAT zephyr_fake_pwm + +/** Fake PWM config structure */ +struct fake_pwm_config { + /** Frequency of the (fake) underlying timer */ + uint64_t frequency_hz; +}; + +DEFINE_FAKE_VALUE_FUNC(int, fake_pwm_set_cycles, const struct device *, uint32_t, uint32_t, + uint32_t, pwm_flags_t); + +#ifdef CONFIG_ZTEST +static void fake_pwm_reset_rule_before(const struct ztest_unit_test *test, void *fixture) +{ + ARG_UNUSED(test); + ARG_UNUSED(fixture); + + RESET_FAKE(fake_pwm_set_cycles); +} + +ZTEST_RULE(fake_pwm_reset_rule, fake_pwm_reset_rule_before, NULL); +#endif /* CONFIG_ZTEST */ + +static int fake_pwm_get_cycles_per_sec(const struct device *dev, uint32_t channel, uint64_t *cycles) +{ + ARG_UNUSED(channel); + const struct fake_pwm_config *config = dev->config; + + *cycles = config->frequency_hz; + + return 0; +} + +static DEVICE_API(pwm, fake_pwm_driver_api) = { + .set_cycles = fake_pwm_set_cycles, + .get_cycles_per_sec = fake_pwm_get_cycles_per_sec, +}; + +#define FAKE_PWM_INIT(inst) \ + static const struct fake_pwm_config fake_pwm_config_##inst = { \ + .frequency_hz = DT_INST_PROP(inst, frequency), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, NULL, &fake_pwm_config_##inst, POST_KERNEL, \ + CONFIG_PWM_INIT_PRIORITY, &fake_pwm_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(FAKE_PWM_INIT) diff --git a/drivers/pwm/pwm_gd32.c b/drivers/pwm/pwm_gd32.c index 81c912514a157..887beb4d8fedd 100644 --- a/drivers/pwm/pwm_gd32.c +++ b/drivers/pwm/pwm_gd32.c @@ -143,7 +143,7 @@ static int pwm_gd32_get_cycles_per_sec(const struct device *dev, return 0; } -static const struct pwm_driver_api pwm_gd32_driver_api = { +static DEVICE_API(pwm, pwm_gd32_driver_api) = { .set_cycles = pwm_gd32_set_cycles, .get_cycles_per_sec = pwm_gd32_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_gecko.c b/drivers/pwm/pwm_gecko.c index 55c21a8681b88..db24b69883bbe 100644 --- a/drivers/pwm/pwm_gecko.c +++ b/drivers/pwm/pwm_gecko.c @@ -72,7 +72,7 @@ static int pwm_gecko_get_cycles_per_sec(const struct device *dev, return 0; } -static const struct pwm_driver_api pwm_gecko_driver_api = { +static DEVICE_API(pwm, pwm_gecko_driver_api) = { .set_cycles = pwm_gecko_set_cycles, .get_cycles_per_sec = pwm_gecko_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_ifx_cat1.c b/drivers/pwm/pwm_ifx_cat1.c index c6aa8ae57b0e9..811daf7e89fcf 100644 --- a/drivers/pwm/pwm_ifx_cat1.c +++ b/drivers/pwm/pwm_ifx_cat1.c @@ -151,7 +151,7 @@ static int ifx_cat1_pwm_get_cycles_per_sec(const struct device *dev, uint32_t ch return 0; } -static const struct pwm_driver_api ifx_cat1_pwm_api = { +static DEVICE_API(pwm, ifx_cat1_pwm_api) = { .set_cycles = ifx_cat1_pwm_set_cycles, .get_cycles_per_sec = ifx_cat1_pwm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_imx.c b/drivers/pwm/pwm_imx.c index 28886a0b052a0..72e3f69186099 100644 --- a/drivers/pwm/pwm_imx.c +++ b/drivers/pwm/pwm_imx.c @@ -152,7 +152,7 @@ static int imx_pwm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api imx_pwm_driver_api = { +static DEVICE_API(pwm, imx_pwm_driver_api) = { .set_cycles = imx_pwm_set_cycles, .get_cycles_per_sec = imx_pwm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_intel_blinky.c b/drivers/pwm/pwm_intel_blinky.c index cf6df303a7411..2396ae2246a6c 100644 --- a/drivers/pwm/pwm_intel_blinky.c +++ b/drivers/pwm/pwm_intel_blinky.c @@ -94,7 +94,7 @@ static int bk_intel_get_cycles_per_sec(const struct device *dev, uint32_t pin, return 0; } -static const struct pwm_driver_api api_funcs = { +static DEVICE_API(pwm, api_funcs) = { .set_cycles = bk_intel_set_cycles, .get_cycles_per_sec = bk_intel_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_ite_it8801.c b/drivers/pwm/pwm_ite_it8801.c index d93875d4aaafd..a10bd030e4788 100644 --- a/drivers/pwm/pwm_ite_it8801.c +++ b/drivers/pwm/pwm_ite_it8801.c @@ -148,7 +148,7 @@ static int pwm_it8801_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_it8801_api = { +static DEVICE_API(pwm, pwm_it8801_api) = { .set_cycles = pwm_it8801_set_cycles, .get_cycles_per_sec = pwm_it8801_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_ite_it8xxx2.c b/drivers/pwm/pwm_ite_it8xxx2.c index 1e5e47f33507f..6e265c8be5dff 100644 --- a/drivers/pwm/pwm_ite_it8xxx2.c +++ b/drivers/pwm/pwm_ite_it8xxx2.c @@ -275,7 +275,7 @@ static int pwm_it8xxx2_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_it8xxx2_api = { +static DEVICE_API(pwm, pwm_it8xxx2_api) = { .set_cycles = pwm_it8xxx2_set_cycles, .get_cycles_per_sec = pwm_it8xxx2_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_led_esp32.c b/drivers/pwm/pwm_led_esp32.c index ab787bb52ef2f..f2a46abd886e6 100644 --- a/drivers/pwm/pwm_led_esp32.c +++ b/drivers/pwm/pwm_led_esp32.c @@ -1,15 +1,15 @@ /* * Copyright (c) 2017 Vitor Massaru Iha - * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT espressif_esp32_ledc -/* Include esp-idf headers first to avoid redefining BIT() macro */ #include #include +#include #include #include @@ -22,15 +22,13 @@ #include LOG_MODULE_REGISTER(pwm_ledc_esp32, CONFIG_PWM_LOG_LEVEL); -#if SOC_LEDC_SUPPORT_APB_CLOCK -#define CLOCK_SOURCE LEDC_APB_CLK -#elif SOC_LEDC_SUPPORT_PLL_DIV_CLOCK -#define CLOCK_SOURCE LEDC_SCLK -#if defined(CONFIG_SOC_SERIES_ESP32C2) -#define SCLK_CLK_FREQ MHZ(60) -#elif defined(CONFIG_SOC_SERIES_ESP32C6) -#define SCLK_CLK_FREQ MHZ(80) +static const int global_clks[] = LEDC_LL_GLOBAL_CLOCKS; +#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX +static const int timer_specific_clks[] = LEDC_LL_TIMER_SPECIFIC_CLOCKS; +static int lowspd_clks[ARRAY_SIZE(global_clks) + ARRAY_SIZE(timer_specific_clks)]; #endif +#if SOC_LEDC_SUPPORT_HS_MODE +static const int highspd_clks[] = {LEDC_APB_CLK, LEDC_REF_TICK}; #endif struct pwm_ledc_esp32_data { @@ -46,7 +44,9 @@ struct pwm_ledc_esp32_channel_config { const ledc_mode_t speed_mode; uint8_t resolution; ledc_clk_src_t clock_src; + uint32_t clock_src_hz; uint32_t duty_val; + bool inverted; }; struct pwm_ledc_esp32_config { @@ -58,10 +58,9 @@ struct pwm_ledc_esp32_config { }; static struct pwm_ledc_esp32_channel_config *get_channel_config(const struct device *dev, - int channel_id) + int channel_id) { - struct pwm_ledc_esp32_config *config = - (struct pwm_ledc_esp32_config *) dev->config; + struct pwm_ledc_esp32_config *config = (struct pwm_ledc_esp32_config *)dev->config; for (uint8_t i = 0; i < config->channel_len; i++) { if (config->channel_config[i].idx == channel_id) { @@ -71,27 +70,31 @@ static struct pwm_ledc_esp32_channel_config *get_channel_config(const struct dev return NULL; } -static void pwm_led_esp32_low_speed_update(const struct device *dev, int speed_mode, int channel) +static void pwm_led_esp32_start(struct pwm_ledc_esp32_data *data, + struct pwm_ledc_esp32_channel_config *channel) { - struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data; + ledc_hal_set_sig_out_en(&data->hal, channel->channel_num, true); + ledc_hal_set_duty_start(&data->hal, channel->channel_num, true); - if (speed_mode == LEDC_LOW_SPEED_MODE) { - ledc_hal_ls_channel_update(&data->hal, channel); + if (channel->speed_mode == LEDC_LOW_SPEED_MODE) { + ledc_hal_ls_channel_update(&data->hal, channel->channel_num); } } -static void pwm_led_esp32_update_duty(const struct device *dev, int speed_mode, int channel) +static void pwm_led_esp32_stop(struct pwm_ledc_esp32_data *data, + struct pwm_ledc_esp32_channel_config *channel, bool idle_level) { - struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data; - - ledc_hal_set_sig_out_en(&data->hal, channel, true); - ledc_hal_set_duty_start(&data->hal, channel, true); + ledc_hal_set_idle_level(&data->hal, channel->channel_num, idle_level); + ledc_hal_set_sig_out_en(&data->hal, channel->channel_num, false); + ledc_hal_set_duty_start(&data->hal, channel->channel_num, false); - pwm_led_esp32_low_speed_update(dev, speed_mode, channel); + if (channel->speed_mode == LEDC_LOW_SPEED_MODE) { + ledc_hal_ls_channel_update(&data->hal, channel->channel_num); + } } static void pwm_led_esp32_duty_set(const struct device *dev, - struct pwm_ledc_esp32_channel_config *channel) + struct pwm_ledc_esp32_channel_config *channel) { struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data; @@ -101,31 +104,6 @@ static void pwm_led_esp32_duty_set(const struct device *dev, ledc_hal_set_duty_num(&data->hal, channel->channel_num, 1); ledc_hal_set_duty_cycle(&data->hal, channel->channel_num, 1); ledc_hal_set_duty_scale(&data->hal, channel->channel_num, 0); - pwm_led_esp32_low_speed_update(dev, channel->speed_mode, channel->channel_num); - pwm_led_esp32_update_duty(dev, channel->speed_mode, channel->channel_num); -} - -static int pwm_led_esp32_configure_pinctrl(const struct device *dev) -{ - int ret; - struct pwm_ledc_esp32_config *config = (struct pwm_ledc_esp32_config *) dev->config; - - ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); - if (ret < 0) { - LOG_ERR("PWM pinctrl setup failed (%d)", ret); - return ret; - } - return 0; -} - -static void pwm_led_esp32_bind_channel_timer(const struct device *dev, - struct pwm_ledc_esp32_channel_config *channel) -{ - struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data; - - ledc_hal_bind_channel_timer(&data->hal, channel->channel_num, channel->timer_num); - - pwm_led_esp32_low_speed_update(dev, channel->speed_mode, channel->channel_num); } static int pwm_led_esp32_calculate_max_resolution(struct pwm_ledc_esp32_channel_config *channel) @@ -134,74 +112,65 @@ static int pwm_led_esp32_calculate_max_resolution(struct pwm_ledc_esp32_channel_ * Max duty resolution can be obtained with * max_res = log2(CLK_FREQ/FREQ) */ -#if SOC_LEDC_SUPPORT_APB_CLOCK - uint64_t clock_freq = channel->clock_src == LEDC_APB_CLK ? APB_CLK_FREQ : REF_CLK_FREQ; -#elif SOC_LEDC_SUPPORT_PLL_DIV_CLOCK - uint64_t clock_freq = SCLK_CLK_FREQ; -#endif - uint32_t max_precision_n = clock_freq/channel->freq; + uint32_t max_precision_n = channel->clock_src_hz / channel->freq; for (uint8_t i = 0; i <= SOC_LEDC_TIMER_BIT_WIDTH; i++) { max_precision_n /= 2; if (!max_precision_n) { - channel->resolution = i; + channel->resolution = i; return 0; } } return -EINVAL; - } static int pwm_led_esp32_timer_config(struct pwm_ledc_esp32_channel_config *channel) { - /** - * Calculate max resolution based on the given frequency and the pwm clock. - * - * There are 2 clock resources for PWM: - * - * 1. APB_CLK (80MHz) - * 2. REF_TICK (1MHz) - * - * The low speed timers can be sourced from: - * - * 1. APB_CLK (80MHz) - * 2. RTC_CLK (8Mhz) - * - * The APB_CLK is mostly used - * - * First we try to find the largest resolution using the APB_CLK source. - * If the given frequency doesn't support it, we move to the next clock source. - */ + const int *clock_src; + int clock_src_num; -#if SOC_LEDC_SUPPORT_APB_CLOCK - channel->clock_src = LEDC_APB_CLK; + if (channel->speed_mode == LEDC_LOW_SPEED_MODE) { +#ifdef SOC_LEDC_HAS_TIMER_SPECIFIC_MUX + clock_src = lowspd_clks; + clock_src_num = ARRAY_SIZE(lowspd_clks); +#else + clock_src = global_clks; + clock_src_num = ARRAY_SIZE(global_clks); #endif - if (!pwm_led_esp32_calculate_max_resolution(channel)) { - return 0; } - -#if SOC_LEDC_SUPPORT_REF_TICK - channel->clock_src = LEDC_REF_TICK; - if (!pwm_led_esp32_calculate_max_resolution(channel)) { - return 0; +#ifdef SOC_LEDC_SUPPORT_HS_MODE + else { + clock_src = highspd_clks; + clock_src_num = ARRAY_SIZE(highspd_clks); } #endif /** - * ESP32 - S2,S3 and C3 variants have only 14 bits counter. - * where as the plain ESP32 variant has 20 bits counter. - * application failed to set low frequency(1Hz) in S2, S3 and C3 variants. - * to get very low frequencies on these variants, - * frequency needs to be tuned with 18 bits clock divider. - * so select the slow clock source (1MHz) with highest counter resolution. - * this can be handled on the func 'pwm_led_esp32_timer_set' with 'prescaler'. + * Calculate max resolution based on the given frequency and the pwm clock. + * Try each clock source available depending on the device and channel type. + */ + for (int i = 0; i < clock_src_num; i++) { + channel->clock_src = clock_src[i]; + esp_clk_tree_src_get_freq_hz(channel->clock_src, + ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, + &channel->clock_src_hz); + if (!pwm_led_esp32_calculate_max_resolution(channel)) { + return 0; + } + } + + /* Frequency is too low for this device, so even though best precision can't + * be achieved we can set max resolution and consider that the previous + * loop selects clock from fastest to slowest, so this is the best + * configuration achievable. */ channel->resolution = SOC_LEDC_TIMER_BIT_WIDTH; + return 0; } static int pwm_led_esp32_timer_set(const struct device *dev, - struct pwm_ledc_esp32_channel_config *channel) + struct pwm_ledc_esp32_channel_config *channel) { int prescaler = 0; uint32_t precision = (0x1 << channel->resolution); @@ -209,30 +178,7 @@ static int pwm_led_esp32_timer_set(const struct device *dev, __ASSERT_NO_MSG(channel->freq > 0); - switch (channel->clock_src) { -#if SOC_LEDC_SUPPORT_APB_CLOCK - case LEDC_APB_CLK: - /** This expression comes from ESP32 Espressif's Technical Reference - * Manual chapter 13.2.2 Timers. - * div_num is a fixed point value (Q10.8). - */ - prescaler = ((uint64_t) APB_CLK_FREQ << 8) / channel->freq / precision; - break; -#endif -#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK - case LEDC_SCLK: - prescaler = ((uint64_t) SCLK_CLK_FREQ << 8) / channel->freq / precision; - break; -#endif -#if SOC_LEDC_SUPPORT_REF_TICK - case LEDC_REF_TICK: - prescaler = ((uint64_t) REF_CLK_FREQ << 8) / channel->freq / precision; - break; -#endif - default: - LOG_ERR("Invalid clock source (%d)", channel->clock_src); - return -EINVAL; - } + prescaler = ((uint64_t)channel->clock_src_hz << 8) / channel->freq / precision; if (prescaler < 0x100 || prescaler > 0x3FFFF) { LOG_ERR("Prescaler out of range: %#X", prescaler); @@ -251,14 +197,16 @@ static int pwm_led_esp32_timer_set(const struct device *dev, ledc_hal_ls_timer_update(&data->hal, channel->timer_num); } - /* reset low speed timer */ - ledc_hal_timer_rst(&data->hal, channel->timer_num); + LOG_DBG("channel_num=%d, speed_mode=%d, timer_num=%d, clock_src=%d, prescaler=%d, " + "resolution=%d\n", + channel->channel_num, channel->speed_mode, channel->timer_num, channel->clock_src, + prescaler, channel->resolution); return 0; } -static int pwm_led_esp32_get_cycles_per_sec(const struct device *dev, - uint32_t channel_idx, uint64_t *cycles) +static int pwm_led_esp32_get_cycles_per_sec(const struct device *dev, uint32_t channel_idx, + uint64_t *cycles) { struct pwm_ledc_esp32_channel_config *channel = get_channel_config(dev, channel_idx); @@ -267,81 +215,126 @@ static int pwm_led_esp32_get_cycles_per_sec(const struct device *dev, return -EINVAL; } -#if SOC_LEDC_SUPPORT_APB_CLOCK - *cycles = channel->clock_src == LEDC_APB_CLK ? APB_CLK_FREQ : REF_CLK_FREQ; -#elif SOC_LEDC_SUPPORT_PLL_DIV_CLOCK - *cycles = SCLK_CLK_FREQ; -#endif + *cycles = (uint64_t)channel->clock_src_hz; return 0; } -static int pwm_led_esp32_set_cycles(const struct device *dev, uint32_t channel_idx, - uint32_t period_cycles, - uint32_t pulse_cycles, pwm_flags_t flags) +static int pwm_led_esp32_channel_update_frequency(const struct device *dev, + struct pwm_ledc_esp32_channel_config *channel, + uint32_t period_cycles) { - int ret; + const struct pwm_ledc_esp32_config *config = dev->config; + uint32_t current_freq = channel->freq; uint64_t clk_freq; - struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data; - struct pwm_ledc_esp32_channel_config *channel = get_channel_config(dev, channel_idx); + int ret; - if (!channel) { - LOG_ERR("Error getting channel %d", channel_idx); - return -EINVAL; - } + ret = pwm_led_esp32_get_cycles_per_sec(dev, channel->idx, &clk_freq); - /* Update PWM frequency according to period_cycles */ - ret = pwm_led_esp32_get_cycles_per_sec(dev, channel_idx, &clk_freq); if (ret < 0) { return ret; } - channel->freq = (uint32_t) (clk_freq/period_cycles); + channel->freq = (uint32_t)(clk_freq / period_cycles); + if (!channel->freq) { channel->freq = 1; } - k_sem_take(&data->cmd_sem, K_FOREVER); - - ledc_hal_init(&data->hal, channel->speed_mode); + if (channel->freq == current_freq) { + /* No need to reconfigure timer */ + return 0; + } - ret = pwm_led_esp32_timer_config(channel); - if (ret < 0) { - k_sem_give(&data->cmd_sem); - return ret; + /* Check whether another channel is using the same timer. + * Timers can only be shared if the same frequency is used, so + * first set operation will take precedence. + */ + for (int i = 0; i < config->channel_len; ++i) { + struct pwm_ledc_esp32_channel_config *ch = &config->channel_config[i]; + + if (ch->freq && (channel->channel_num != ch->channel_num) && + (channel->timer_num == ch->timer_num) && + (channel->speed_mode == ch->speed_mode) && + (channel->freq != ch->freq)) { + LOG_ERR("Timer can't be shared and different frequency be " + "requested"); + channel->freq = 0; + return -EINVAL; + } } + pwm_led_esp32_timer_config(channel); + ret = pwm_led_esp32_timer_set(dev, channel); + if (ret < 0) { - k_sem_give(&data->cmd_sem); + LOG_ERR("Error setting timer for channel %d", channel->idx); return ret; } - pwm_led_esp32_bind_channel_timer(dev, channel); + return 0; +} - /* Update PWM duty */ +static int pwm_led_esp32_set_cycles(const struct device *dev, uint32_t channel_idx, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) +{ + struct pwm_ledc_esp32_data *data = (struct pwm_ledc_esp32_data *const)(dev)->data; + struct pwm_ledc_esp32_channel_config *channel = get_channel_config(dev, channel_idx); + int ret = 0; + + if (!channel) { + LOG_ERR("Error getting channel %d", channel_idx); + return -EINVAL; + } - double duty_cycle = (double) pulse_cycles / (double) period_cycles; + k_sem_take(&data->cmd_sem, K_FOREVER); - channel->duty_val = (uint32_t)((double) (1 << channel->resolution) * duty_cycle); + if (flags & PWM_POLARITY_INVERTED) { + pulse_cycles = period_cycles - pulse_cycles; + channel->inverted = true; + } else { + channel->inverted = false; + } - pwm_led_esp32_duty_set(dev, channel); + ledc_hal_init(&data->hal, channel->speed_mode); + + if ((pulse_cycles == period_cycles) || (pulse_cycles == 0)) { + /* For duty 0% and 100% stop PWM, set output level and return */ + pwm_led_esp32_stop(data, channel, (pulse_cycles == period_cycles)); + goto sem_give; + } + + ret = pwm_led_esp32_channel_update_frequency(dev, channel, period_cycles); - ret = pwm_led_esp32_configure_pinctrl(dev); if (ret < 0) { - k_sem_give(&data->cmd_sem); - return ret; + LOG_ERR("Error updating frequency of channel %d", channel_idx); + goto sem_give; } + /* Update PWM duty */ + + double duty_cycle = (double)pulse_cycles / (double)period_cycles; + + channel->duty_val = (uint32_t)((double)(1 << channel->resolution) * duty_cycle); + + pwm_led_esp32_duty_set(dev, channel); + + pwm_led_esp32_start(data, channel); + +sem_give: k_sem_give(&data->cmd_sem); return ret; } - int pwm_led_esp32_init(const struct device *dev) { const struct pwm_ledc_esp32_config *config = dev->config; + struct pwm_ledc_esp32_data *data = dev->data; + struct pwm_ledc_esp32_channel_config *channel; + int ret = 0; if (!device_is_ready(config->clock_dev)) { LOG_ERR("clock control device not ready"); @@ -351,30 +344,67 @@ int pwm_led_esp32_init(const struct device *dev) /* Enable peripheral */ clock_control_on(config->clock_dev, config->clock_subsys); +#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX + /* Combine clock sources to include timer specific sources */ + memcpy(lowspd_clks, global_clks, sizeof(global_clks)); + memcpy(&lowspd_clks[ARRAY_SIZE(global_clks)], timer_specific_clks, + sizeof(timer_specific_clks)); +#endif + + for (int i = 0; i < config->channel_len; ++i) { + channel = &config->channel_config[i]; + + ledc_hal_init(&data->hal, channel->speed_mode); + + if (channel->speed_mode == LEDC_LOW_SPEED_MODE) { + channel->clock_src = global_clks[0]; + ledc_hal_set_slow_clk_sel(&data->hal, channel->clock_src); + } +#ifdef SOC_LEDC_SUPPORT_HS_MODE + else { + channel->clock_src = highspd_clks[0]; + } +#endif + ledc_hal_set_clock_source(&data->hal, channel->timer_num, channel->clock_src); + + esp_clk_tree_src_get_freq_hz(channel->clock_src, + ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, + &channel->clock_src_hz); + + ledc_hal_bind_channel_timer(&data->hal, channel->channel_num, channel->timer_num); + pwm_led_esp32_stop(data, channel, channel->inverted); + ledc_hal_timer_rst(&data->hal, channel->timer_num); + } + + ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + + if (ret < 0) { + LOG_ERR("PWM pinctrl setup failed (%d)", ret); + return ret; + } + return 0; } -static const struct pwm_driver_api pwm_led_esp32_api = { +static DEVICE_API(pwm, pwm_led_esp32_api) = { .set_cycles = pwm_led_esp32_set_cycles, .get_cycles_per_sec = pwm_led_esp32_get_cycles_per_sec, }; PINCTRL_DT_INST_DEFINE(0); -#define CHANNEL_CONFIG(node_id) \ - { \ - .idx = DT_REG_ADDR(node_id), \ - .channel_num = DT_REG_ADDR(node_id) % 8, \ - .timer_num = DT_PROP(node_id, timer), \ - .speed_mode = DT_REG_ADDR(node_id) < SOC_LEDC_CHANNEL_NUM \ - ? LEDC_LOW_SPEED_MODE \ - : !LEDC_LOW_SPEED_MODE, \ - .clock_src = CLOCK_SOURCE, \ +#define CHANNEL_CONFIG(node_id) \ + { \ + .idx = DT_REG_ADDR(node_id), \ + .channel_num = DT_REG_ADDR(node_id) % 8, \ + .timer_num = DT_PROP(node_id, timer), \ + .speed_mode = DT_REG_ADDR(node_id) < SOC_LEDC_CHANNEL_NUM ? LEDC_LOW_SPEED_MODE \ + : !LEDC_LOW_SPEED_MODE, \ + .inverted = DT_PROP(node_id, inverted), \ }, static struct pwm_ledc_esp32_channel_config channel_config[] = { - DT_INST_FOREACH_CHILD(0, CHANNEL_CONFIG) -}; + DT_INST_FOREACH_CHILD(0, CHANNEL_CONFIG)}; static struct pwm_ledc_esp32_config pwm_ledc_esp32_config = { .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), @@ -391,9 +421,5 @@ static struct pwm_ledc_esp32_data pwm_ledc_esp32_data = { .cmd_sem = Z_SEM_INITIALIZER(pwm_ledc_esp32_data.cmd_sem, 1, 1), }; -DEVICE_DT_INST_DEFINE(0, &pwm_led_esp32_init, NULL, - &pwm_ledc_esp32_data, - &pwm_ledc_esp32_config, - POST_KERNEL, - CONFIG_PWM_INIT_PRIORITY, - &pwm_led_esp32_api); +DEVICE_DT_INST_DEFINE(0, &pwm_led_esp32_init, NULL, &pwm_ledc_esp32_data, &pwm_ledc_esp32_config, + POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, &pwm_led_esp32_api); diff --git a/drivers/pwm/pwm_litex.c b/drivers/pwm/pwm_litex.c index 9f38a1792c6fa..f7be54ccd2b46 100644 --- a/drivers/pwm/pwm_litex.c +++ b/drivers/pwm/pwm_litex.c @@ -61,7 +61,7 @@ int pwm_litex_get_cycles_per_sec(const struct device *dev, uint32_t channel, return 0; } -static const struct pwm_driver_api pwm_litex_driver_api = { +static DEVICE_API(pwm, pwm_litex_driver_api) = { .set_cycles = pwm_litex_set_cycles, .get_cycles_per_sec = pwm_litex_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_max31790.c b/drivers/pwm/pwm_max31790.c index a655c8b10b734..0c529c5fed708 100644 --- a/drivers/pwm/pwm_max31790.c +++ b/drivers/pwm/pwm_max31790.c @@ -321,7 +321,7 @@ static int max31790_get_cycles_per_sec(const struct device *dev, uint32_t channe return 0; } -static const struct pwm_driver_api max31790_pwm_api = { +static DEVICE_API(pwm, max31790_pwm_api) = { .set_cycles = max31790_set_cycles, .get_cycles_per_sec = max31790_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_max32.c b/drivers/pwm/pwm_max32.c index 5228b4a89de61..85b734de600eb 100644 --- a/drivers/pwm/pwm_max32.c +++ b/drivers/pwm/pwm_max32.c @@ -105,7 +105,7 @@ static int api_get_cycles_per_sec(const struct device *dev, uint32_t channel, ui return ret; } -static const struct pwm_driver_api pwm_max32_driver_api = { +static DEVICE_API(pwm, pwm_max32_driver_api) = { .set_cycles = api_set_cycles, .get_cycles_per_sec = api_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_mc_esp32.c b/drivers/pwm/pwm_mc_esp32.c index d0c470528a0c2..b7bb59f1cd5ab 100644 --- a/drivers/pwm/pwm_mc_esp32.c +++ b/drivers/pwm/pwm_mc_esp32.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,18 +17,27 @@ #include #include #include +#include #ifdef CONFIG_PWM_CAPTURE +#if defined(CONFIG_RISCV) +#include +#else #include +#endif #endif /* CONFIG_PWM_CAPTURE */ #include LOG_MODULE_REGISTER(mcpwm_esp32, CONFIG_PWM_LOG_LEVEL); -#define SOC_MCPWM_BASE_CLK_HZ (160000000U) +#if defined(CONFIG_RISCV) +#define ISR_HANDLER isr_handler_t +#else +#define ISR_HANDLER intr_handler_t +#endif + #ifdef CONFIG_PWM_CAPTURE -#define SKIP_IRQ_NUM 4U -#define MCPWM_INTR_CAP0 BIT(0) -#define MCPWM_INTR_CAP1 BIT(1) -#define MCPWM_INTR_CAP2 BIT(2) +#define SKIP_IRQ_NUM 4U +#define CAP_INT_MASK 7U +#define CAP_INT_BASE_BIT 27U #define MCPWM_CHANNEL_NUM 8U #define CAPTURE_CHANNEL_IDX 6U #else @@ -37,7 +46,7 @@ LOG_MODULE_REGISTER(mcpwm_esp32, CONFIG_PWM_LOG_LEVEL); struct mcpwm_esp32_data { mcpwm_hal_context_t hal; - mcpwm_hal_init_config_t init_config; + uint32_t mcpwm_clk_hz; struct k_sem cmd_sem; }; @@ -53,7 +62,6 @@ struct mcpwm_esp32_capture_config { void *user_data; uint32_t period; uint32_t pulse; - uint32_t overflows; uint8_t skip_irq; bool capture_period; bool capture_pulse; @@ -94,6 +102,7 @@ struct mcpwm_esp32_config { static void mcpwm_esp32_duty_set(const struct device *dev, struct mcpwm_esp32_channel_config *channel) { + struct mcpwm_esp32_config *config = (struct mcpwm_esp32_config *)dev->config; struct mcpwm_esp32_data *data = (struct mcpwm_esp32_data *const)(dev)->data; mcpwm_duty_type_t duty_type; uint32_t set_duty; @@ -108,8 +117,9 @@ static void mcpwm_esp32_duty_set(const struct device *dev, MCPWM_HAL_GENERATOR_MODE_FORCE_HIGH : MCPWM_DUTY_MODE_0; } - set_duty = mcpwm_ll_timer_get_peak(data->hal.dev, channel->timer_id, false) * - channel->duty / 100; + uint32_t timer_clk_hz = data->mcpwm_clk_hz / config->prescale / channel->prescale; + + set_duty = (timer_clk_hz / channel->freq) * channel->duty / 100; mcpwm_ll_operator_connect_timer(data->hal.dev, channel->operator_id, channel->timer_id); mcpwm_ll_operator_set_compare_value(data->hal.dev, channel->operator_id, channel->generator_id, set_duty); @@ -175,6 +185,7 @@ static int mcpwm_esp32_configure_pinctrl(const struct device *dev) static int mcpwm_esp32_timer_set(const struct device *dev, struct mcpwm_esp32_channel_config *channel) { + struct mcpwm_esp32_config *config = (struct mcpwm_esp32_config *)dev->config; struct mcpwm_esp32_data *data = (struct mcpwm_esp32_data *const)(dev)->data; __ASSERT_NO_MSG(channel->freq > 0); @@ -182,11 +193,10 @@ static int mcpwm_esp32_timer_set(const struct device *dev, mcpwm_ll_timer_set_clock_prescale(data->hal.dev, channel->timer_id, channel->prescale); mcpwm_ll_timer_set_count_mode(data->hal.dev, channel->timer_id, MCPWM_TIMER_COUNT_MODE_UP); mcpwm_ll_timer_update_period_at_once(data->hal.dev, channel->timer_id); - int real_group_prescale = mcpwm_ll_group_get_clock_prescale(data->hal.dev); - uint32_t real_timer_clk_hz = - SOC_MCPWM_BASE_CLK_HZ / real_group_prescale / - mcpwm_ll_timer_get_clock_prescale(data->hal.dev, channel->timer_id); - mcpwm_ll_timer_set_peak(data->hal.dev, channel->timer_id, real_timer_clk_hz / channel->freq, + + uint32_t timer_clk_hz = data->mcpwm_clk_hz / config->prescale / channel->prescale; + + mcpwm_ll_timer_set_peak(data->hal.dev, channel->timer_id, timer_clk_hz / channel->freq, false); return 0; @@ -197,6 +207,7 @@ static int mcpwm_esp32_get_cycles_per_sec(const struct device *dev, uint32_t cha { struct mcpwm_esp32_config *config = (struct mcpwm_esp32_config *)dev->config; struct mcpwm_esp32_channel_config *channel = &config->channel_config[channel_idx]; + struct mcpwm_esp32_data *data = (struct mcpwm_esp32_data *const)(dev)->data; if (!channel) { LOG_ERR("Error getting channel %d", channel_idx); @@ -205,13 +216,18 @@ static int mcpwm_esp32_get_cycles_per_sec(const struct device *dev, uint32_t cha #ifdef CONFIG_PWM_CAPTURE if (channel->idx >= CAPTURE_CHANNEL_IDX) { +#if SOC_MCPWM_CAPTURE_CLK_FROM_GROUP + /* Capture prescaler is disabled by default (equals 1) */ + *cycles = (uint64_t)data->mcpwm_clk_hz / (config->prescale + 1) / 1; +#else *cycles = (uint64_t)APB_CLK_FREQ; +#endif return 0; } #endif /* CONFIG_PWM_CAPTURE */ *cycles = - (uint64_t)SOC_MCPWM_BASE_CLK_HZ / (config->prescale + 1) / (channel->prescale + 1); + (uint64_t)data->mcpwm_clk_hz / (config->prescale + 1) / (channel->prescale + 1); return 0; } @@ -368,7 +384,6 @@ static int mcpwm_esp32_enable_capture(const struct device *dev, uint32_t channel .cap_prescale = 1, }; - mcpwm_hal_init(&data->hal, &data->init_config); mcpwm_ll_group_set_clock_prescale(data->hal.dev, config->prescale); mcpwm_ll_group_enable_shadow_mode(data->hal.dev); mcpwm_ll_group_flush_shadow(data->hal.dev); @@ -383,7 +398,7 @@ static int mcpwm_esp32_enable_capture(const struct device *dev, uint32_t channel cap_conf.cap_prescale); mcpwm_ll_intr_enable(data->hal.dev, MCPWM_LL_EVENT_CAPTURE(capture->capture_signal), true); - mcpwm_ll_intr_clear_capture_status(data->hal.dev, 1 << capture->capture_signal); + mcpwm_ll_intr_clear_status(data->hal.dev, MCPWM_LL_EVENT_CAPTURE(capture->capture_signal)); capture->skip_irq = 0; @@ -419,6 +434,10 @@ int mcpwm_esp32_init(const struct device *dev) return -ENODEV; } + mcpwm_ll_group_set_clock_source(data->hal.dev, MCPWM_TIMER_CLK_SRC_DEFAULT); + esp_clk_tree_src_get_freq_hz(MCPWM_TIMER_CLK_SRC_DEFAULT, + ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &data->mcpwm_clk_hz); + /* Enable peripheral */ ret = clock_control_on(config->clock_dev, config->clock_subsys); if (ret < 0) { @@ -428,7 +447,6 @@ int mcpwm_esp32_init(const struct device *dev) channel_init(dev); - mcpwm_hal_init(&data->hal, &data->init_config); mcpwm_ll_group_set_clock_prescale(data->hal.dev, config->prescale); mcpwm_ll_group_enable_shadow_mode(data->hal.dev); mcpwm_ll_group_flush_shadow(data->hal.dev); @@ -450,26 +468,22 @@ static void IRAM_ATTR mcpwm_esp32_isr(const struct device *dev) struct mcpwm_esp32_data *data = (struct mcpwm_esp32_data *const)(dev)->data; struct mcpwm_esp32_channel_config *channel; struct mcpwm_esp32_capture_config *capture; - uint32_t mcpwm_intr_status; - - mcpwm_intr_status = mcpwm_ll_intr_get_capture_status(data->hal.dev); + uint32_t mcpwm_intr_status, mcpwm_cap_intr_status; + uint8_t cap_id; - mcpwm_ll_intr_clear_capture_status(data->hal.dev, mcpwm_intr_status); + mcpwm_intr_status = mcpwm_ll_intr_get_status(data->hal.dev); + mcpwm_cap_intr_status = (mcpwm_intr_status >> CAP_INT_BASE_BIT) & CAP_INT_MASK; - if (mcpwm_intr_status & MCPWM_INTR_CAP0) { - channel = &config->channel_config[CAPTURE_CHANNEL_IDX]; - } else if (mcpwm_intr_status & MCPWM_INTR_CAP1) { - channel = &config->channel_config[CAPTURE_CHANNEL_IDX + 1]; - } else if (mcpwm_intr_status & MCPWM_INTR_CAP2) { - channel = &config->channel_config[CAPTURE_CHANNEL_IDX + 2]; - } else { + if (!mcpwm_cap_intr_status) { return; } - if (!channel) { - return; - } + cap_id = __builtin_ctz(mcpwm_cap_intr_status); + + mcpwm_ll_intr_clear_status(data->hal.dev, + mcpwm_intr_status & MCPWM_LL_EVENT_CAPTURE(cap_id)); + channel = &config->channel_config[CAPTURE_CHANNEL_IDX + cap_id]; capture = &channel->capture; /* We need to wait at least 4 (2 positive edges and 2 negative edges) interrupts to @@ -521,7 +535,7 @@ static void IRAM_ATTR mcpwm_esp32_isr(const struct device *dev) } #endif /* CONFIG_PWM_CAPTURE */ -static const struct pwm_driver_api mcpwm_esp32_api = { +static DEVICE_API(pwm, mcpwm_esp32_api) = { .set_cycles = mcpwm_esp32_set_cycles, .get_cycles_per_sec = mcpwm_esp32_get_cycles_per_sec, #ifdef CONFIG_PWM_CAPTURE @@ -540,7 +554,7 @@ static const struct pwm_driver_api mcpwm_esp32_api = { ESP_PRIO_TO_FLAGS(DT_INST_IRQ_BY_IDX(idx, 0, priority)) | \ ESP_INT_FLAGS_CHECK(DT_INST_IRQ_BY_IDX(idx, 0, flags)) | \ ESP_INTR_FLAG_IRAM, \ - (intr_handler_t)mcpwm_esp32_isr, (void *)dev, NULL); \ + (ISR_HANDLER)mcpwm_esp32_isr, (void *)dev, NULL); \ return ret; \ } #define CAPTURE_INIT(idx) .irq_config_func = mcpwm_esp32_irq_config_func_##idx @@ -557,10 +571,6 @@ static const struct pwm_driver_api mcpwm_esp32_api = { { \ .dev = (mcpwm_dev_t *)DT_INST_REG_ADDR(idx), \ }, \ - .init_config = \ - { \ - .group_id = idx, \ - }, \ .cmd_sem = Z_SEM_INITIALIZER(mcpwm_esp32_data_##idx.cmd_sem, 1, 1), \ }; \ \ diff --git a/drivers/pwm/pwm_mchp_xec.c b/drivers/pwm/pwm_mchp_xec.c index bd326680d3dbd..c0d87a0da2dec 100644 --- a/drivers/pwm/pwm_mchp_xec.c +++ b/drivers/pwm/pwm_mchp_xec.c @@ -418,7 +418,7 @@ static int pwm_xec_pm_action(const struct device *dev, enum pm_device_action act } #endif /* CONFIG_PM_DEVICE */ -static const struct pwm_driver_api pwm_xec_driver_api = { +static DEVICE_API(pwm, pwm_xec_driver_api) = { .set_cycles = pwm_xec_set_cycles, .get_cycles_per_sec = pwm_xec_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_mchp_xec_bbled.c b/drivers/pwm/pwm_mchp_xec_bbled.c index 52177ee3ee2e6..bd73748675f95 100644 --- a/drivers/pwm/pwm_mchp_xec_bbled.c +++ b/drivers/pwm/pwm_mchp_xec_bbled.c @@ -321,7 +321,7 @@ static int pwm_bbled_xec_pm_action(const struct device *dev, enum pm_device_acti } #endif /* CONFIG_PM_DEVICE */ -static const struct pwm_driver_api pwm_bbled_xec_driver_api = { +static DEVICE_API(pwm, pwm_bbled_xec_driver_api) = { .set_cycles = pwm_bbled_xec_set_cycles, .get_cycles_per_sec = pwm_bbled_xec_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_mcux.c b/drivers/pwm/pwm_mcux.c index 617ac3e4b7f7c..308581731f0d8 100644 --- a/drivers/pwm/pwm_mcux.c +++ b/drivers/pwm/pwm_mcux.c @@ -238,7 +238,7 @@ static int pwm_mcux_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_mcux_driver_api = { +static DEVICE_API(pwm, pwm_mcux_driver_api) = { .set_cycles = mcux_pwm_set_cycles, .get_cycles_per_sec = mcux_pwm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_mcux_ctimer.c b/drivers/pwm/pwm_mcux_ctimer.c index 63d9459747c56..27d48211cc86f 100644 --- a/drivers/pwm/pwm_mcux_ctimer.c +++ b/drivers/pwm/pwm_mcux_ctimer.c @@ -237,7 +237,7 @@ static int mcux_ctimer_pwm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_mcux_ctimer_driver_api = { +static DEVICE_API(pwm, pwm_mcux_ctimer_driver_api) = { .set_cycles = mcux_ctimer_pwm_set_cycles, .get_cycles_per_sec = mcux_ctimer_pwm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_mcux_ftm.c b/drivers/pwm/pwm_mcux_ftm.c index 4774fad4f8094..a8d578371777f 100644 --- a/drivers/pwm/pwm_mcux_ftm.c +++ b/drivers/pwm/pwm_mcux_ftm.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nxp_kinetis_ftm_pwm +#define DT_DRV_COMPAT nxp_ftm_pwm #include #include @@ -492,7 +492,7 @@ static int mcux_ftm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api mcux_ftm_driver_api = { +static DEVICE_API(pwm, mcux_ftm_driver_api) = { .set_cycles = mcux_ftm_set_cycles, .get_cycles_per_sec = mcux_ftm_get_cycles_per_sec, #ifdef CONFIG_PWM_CAPTURE diff --git a/drivers/pwm/pwm_mcux_pwt.c b/drivers/pwm/pwm_mcux_pwt.c index 0413e256b1289..13c0401b49960 100644 --- a/drivers/pwm/pwm_mcux_pwt.c +++ b/drivers/pwm/pwm_mcux_pwt.c @@ -325,7 +325,7 @@ static int mcux_pwt_init(const struct device *dev) return 0; } -static const struct pwm_driver_api mcux_pwt_driver_api = { +static DEVICE_API(pwm, mcux_pwt_driver_api) = { .set_cycles = mcux_pwt_set_cycles, .get_cycles_per_sec = mcux_pwt_get_cycles_per_sec, .configure_capture = mcux_pwt_configure_capture, diff --git a/drivers/pwm/pwm_mcux_qtmr.c b/drivers/pwm/pwm_mcux_qtmr.c index b78f43b0436b1..44b33b829f718 100644 --- a/drivers/pwm/pwm_mcux_qtmr.c +++ b/drivers/pwm/pwm_mcux_qtmr.c @@ -149,7 +149,7 @@ static int mcux_qtmr_pwm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_mcux_qtmr_driver_api = { +static DEVICE_API(pwm, pwm_mcux_qtmr_driver_api) = { .set_cycles = mcux_qtmr_pwm_set_cycles, .get_cycles_per_sec = mcux_qtmr_pwm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_mcux_sctimer.c b/drivers/pwm/pwm_mcux_sctimer.c index fcd3272cfdc6a..9f572f452ee1e 100644 --- a/drivers/pwm/pwm_mcux_sctimer.c +++ b/drivers/pwm/pwm_mcux_sctimer.c @@ -243,7 +243,7 @@ static int mcux_sctimer_pwm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_mcux_sctimer_driver_api = { +static DEVICE_API(pwm, pwm_mcux_sctimer_driver_api) = { .set_cycles = mcux_sctimer_pwm_set_cycles, .get_cycles_per_sec = mcux_sctimer_pwm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_mcux_tpm.c b/drivers/pwm/pwm_mcux_tpm.c index 7a6aaed6e0f0f..ae869c51815a0 100644 --- a/drivers/pwm/pwm_mcux_tpm.c +++ b/drivers/pwm/pwm_mcux_tpm.c @@ -190,7 +190,7 @@ static int mcux_tpm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api mcux_tpm_driver_api = { +static DEVICE_API(pwm, mcux_tpm_driver_api) = { .set_cycles = mcux_tpm_set_cycles, .get_cycles_per_sec = mcux_tpm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_npcx.c b/drivers/pwm/pwm_npcx.c index f4bdb039c6993..12a794c183930 100644 --- a/drivers/pwm/pwm_npcx.c +++ b/drivers/pwm/pwm_npcx.c @@ -15,7 +15,7 @@ #include -LOG_MODULE_REGISTER(pwm_npcx, LOG_LEVEL_ERR); +LOG_MODULE_REGISTER(pwm_npcx, CONFIG_PWM_LOG_LEVEL); /* 16-bit period cycles/prescaler in NPCX PWM modules */ #define NPCX_PWM_MAX_PRESCALER (1UL << (16)) @@ -163,7 +163,7 @@ static int pwm_npcx_get_cycles_per_sec(const struct device *dev, } /* PWM driver registration */ -static const struct pwm_driver_api pwm_npcx_driver_api = { +static DEVICE_API(pwm, pwm_npcx_driver_api) = { .set_cycles = pwm_npcx_set_cycles, .get_cycles_per_sec = pwm_npcx_get_cycles_per_sec }; diff --git a/drivers/pwm/pwm_nrf_sw.c b/drivers/pwm/pwm_nrf_sw.c index 2b9a22a38f081..5ea5a128873b6 100644 --- a/drivers/pwm/pwm_nrf_sw.c +++ b/drivers/pwm/pwm_nrf_sw.c @@ -335,7 +335,7 @@ static int pwm_nrf_sw_get_cycles_per_sec(const struct device *dev, return 0; } -static const struct pwm_driver_api pwm_nrf_sw_drv_api_funcs = { +static DEVICE_API(pwm, pwm_nrf_sw_drv_api_funcs) = { .set_cycles = pwm_nrf_sw_set_cycles, .get_cycles_per_sec = pwm_nrf_sw_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_nrfx.c b/drivers/pwm/pwm_nrfx.c index 230a90d6cdf78..8b853537375f2 100644 --- a/drivers/pwm/pwm_nrfx.c +++ b/drivers/pwm/pwm_nrfx.c @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef CONFIG_SOC_NRF54H20_GPD #include #endif @@ -35,6 +36,24 @@ LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL); #define ANOMALY_109_EGU_IRQ_CONNECT(idx) #endif +#define PWM(dev_idx) DT_NODELABEL(pwm##dev_idx) +#define PWM_PROP(dev_idx, prop) DT_PROP(PWM(dev_idx), prop) +#define PWM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(PWM(idx), prop) + +#define PWM_NRFX_IS_FAST(unused, prefix, idx, _) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(PWM(idx)), \ + (COND_CODE_1(PWM_HAS_PROP(idx, power_domains), \ + (IS_EQ(DT_PHA(PWM(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)), \ + (0))), (0)) + +#if NRFX_FOREACH_PRESENT(PWM, PWM_NRFX_IS_FAST, (||), (0)) +#define PWM_NRFX_FAST_PRESENT 1 +#endif + +#if defined(PWM_NRFX_FAST_PRESENT) && CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL +#define PWM_NRFX_USE_CLOCK_CONTROL 1 +#endif + #define PWM_NRFX_CH_POLARITY_MASK BIT(15) #define PWM_NRFX_CH_COMPARE_MASK BIT_MASK(15) #define PWM_NRFX_CH_VALUE(compare_value, inverted) \ @@ -49,6 +68,10 @@ struct pwm_nrfx_config { #ifdef CONFIG_DCACHE uint32_t mem_attr; #endif +#ifdef PWM_NRFX_USE_CLOCK_CONTROL + const struct device *clk_dev; + struct nrf_clock_spec clk_spec; +#endif }; struct pwm_nrfx_data { @@ -57,12 +80,27 @@ struct pwm_nrfx_data { uint8_t pwm_needed; uint8_t prescaler; bool stop_requested; +#ifdef PWM_NRFX_USE_CLOCK_CONTROL + bool clock_requested; +#endif }; /* Ensure the pwm_needed bit mask can accommodate all available channels. */ #if (NRF_PWM_CHANNEL_COUNT > 8) #error "Current implementation supports maximum 8 channels." #endif +#ifdef PWM_NRFX_FAST_PRESENT +static bool pwm_is_fast(const struct pwm_nrfx_config *config) +{ + return config->clock_freq > MHZ(16); +} +#else +static bool pwm_is_fast(const struct pwm_nrfx_config *config) +{ + return false; +} +#endif + static uint16_t *seq_values_ptr_get(const struct device *dev) { const struct pwm_nrfx_config *config = dev->config; @@ -134,6 +172,33 @@ static bool channel_psel_get(uint32_t channel, uint32_t *psel, == PWM_PSEL_OUT_CONNECT_Connected); } +static int stop_pwm(const struct device *dev) +{ + const struct pwm_nrfx_config *config = dev->config; + + /* Don't wait here for the peripheral to actually stop. Instead, + * ensure it is stopped before starting the next playback. + */ + nrfx_pwm_stop(&config->pwm, false); + +#if PWM_NRFX_USE_CLOCK_CONTROL + struct pwm_nrfx_data *data = dev->data; + + if (data->clock_requested) { + int ret = nrf_clock_control_release(config->clk_dev, &config->clk_spec); + + if (ret < 0) { + LOG_ERR("Global HSFLL release failed: %d", ret); + return ret; + } + + data->clock_requested = false; + } +#endif + + return 0; +} + static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_cycles, uint32_t pulse_cycles, pwm_flags_t flags) @@ -209,8 +274,20 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel, if (inverted) { out_level ^= 1; } - - nrf_gpio_pin_write(psel, out_level); + /* Output of fast PWM instance is directly connected to GPIO pads, + * thus it cannot controlled by GPIO. Use regular 0%/100% duty cycle + * playback instead. + */ +#ifdef PWM_NRFX_FAST_PRESENT + if (pwm_is_fast(config)) { + nrfx_pwm_simple_playback(&config->pwm, &config->seq, 1, + NRFX_PWM_FLAG_NO_EVT_FINISHED); + } else { +#else + { +#endif + nrf_gpio_pin_write(psel, out_level); + } } data->pwm_needed &= ~BIT(channel); @@ -225,10 +302,29 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel, * registers and drives its outputs accordingly. */ if (data->pwm_needed == 0) { - /* Don't wait here for the peripheral to actually stop. Instead, - * ensure it is stopped before starting the next playback. - */ - nrfx_pwm_stop(&config->pwm, false); + if (pwm_is_fast(config)) { +#if PWM_NRFX_USE_CLOCK_CONTROL + if (data->clock_requested) { + int ret = nrf_clock_control_release(config->clk_dev, + &config->clk_spec); + + if (ret < 0) { + LOG_ERR("Global HSFLL release failed: %d", ret); + return ret; + } + + data->clock_requested = false; + } +#endif + return 0; + } + int ret = stop_pwm(dev); + + if (ret < 0) { + LOG_ERR("PWM stop failed: %d", ret); + return ret; + } + data->stop_requested = true; } else { if (data->stop_requested) { @@ -248,6 +344,20 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel, * until another playback is requested (new values will be * loaded then) or the PWM peripheral is stopped. */ +#if PWM_NRFX_USE_CLOCK_CONTROL + if (config->clk_dev && !data->clock_requested) { + int ret = nrf_clock_control_request_sync(config->clk_dev, + &config->clk_spec, + K_FOREVER); + + if (ret < 0) { + LOG_ERR("Global HSFLL request failed: %d", ret); + return ret; + } + + data->clock_requested = true; + } +#endif nrfx_pwm_simple_playback(&config->pwm, &config->seq, 1, NRFX_PWM_FLAG_NO_EVT_FINISHED); } @@ -265,12 +375,12 @@ static int pwm_nrfx_get_cycles_per_sec(const struct device *dev, uint32_t channe return 0; } -static const struct pwm_driver_api pwm_nrfx_drv_api_funcs = { +static DEVICE_API(pwm, pwm_nrfx_drv_api_funcs) = { .set_cycles = pwm_nrfx_set_cycles, .get_cycles_per_sec = pwm_nrfx_get_cycles_per_sec, }; -static void pwm_resume(const struct device *dev) +static int pwm_resume(const struct device *dev) { const struct pwm_nrfx_config *config = dev->config; uint8_t initially_inverted = 0; @@ -299,13 +409,21 @@ static void pwm_resume(const struct device *dev) seq_values_ptr_get(dev)[i] = PWM_NRFX_CH_VALUE(0, inverted); } + + return 0; } -static void pwm_suspend(const struct device *dev) +static int pwm_suspend(const struct device *dev) { const struct pwm_nrfx_config *config = dev->config; - nrfx_pwm_stop(&config->pwm, false); + int ret = stop_pwm(dev); + + if (ret < 0) { + LOG_ERR("PWM stop failed: %d", ret); + return ret; + } + while (!nrfx_pwm_stopped_check(&config->pwm)) { } @@ -315,15 +433,17 @@ static void pwm_suspend(const struct device *dev) memset(dev->data, 0, sizeof(struct pwm_nrfx_data)); (void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); + + return 0; } static int pwm_nrfx_pm_action(const struct device *dev, enum pm_device_action action) { if (action == PM_DEVICE_ACTION_RESUME) { - pwm_resume(dev); + return pwm_resume(dev); } else if (IS_ENABLED(CONFIG_PM_DEVICE) && (action == PM_DEVICE_ACTION_SUSPEND)) { - pwm_suspend(dev); + return pwm_suspend(dev); } else { return -ENOTSUP; } @@ -351,9 +471,6 @@ static int pwm_nrfx_init(const struct device *dev) return pm_device_driver_init(dev, pwm_nrfx_pm_action); } -#define PWM(dev_idx) DT_NODELABEL(pwm##dev_idx) -#define PWM_PROP(dev_idx, prop) DT_PROP(PWM(dev_idx), prop) -#define PWM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(PWM(idx), prop) #define PWM_MEM_REGION(idx) DT_PHANDLE(PWM(idx), memory_regions) #define PWM_MEMORY_SECTION(idx) \ @@ -366,6 +483,21 @@ static int pwm_nrfx_init(const struct device *dev) COND_CODE_1(PWM_HAS_PROP(idx, memory_regions), \ (DT_PROP_OR(PWM_MEM_REGION(idx), zephyr_memory_attr, 0)), (0)) +/* Fast instances depend on the global HSFLL clock controller (as they need + * to request the highest frequency from it to operate correctly), so they + * must be initialized after that controller driver, hence the default PWM + * initialization priority may be too early for them. + */ +#if defined(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY) && \ + CONFIG_PWM_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY +#define PWM_INIT_PRIORITY(idx) \ + COND_CODE_1(PWM_NRFX_IS_FAST(_, /*empty*/, idx, _), \ + (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \ + (CONFIG_PWM_INIT_PRIORITY)) +#else +#define PWM_INIT_PRIORITY(idx) CONFIG_PWM_INIT_PRIORITY +#endif + #define PWM_NRFX_DEVICE(idx) \ NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(PWM(idx)); \ static struct pwm_nrfx_data pwm_nrfx_##idx##_data; \ @@ -393,6 +525,14 @@ static int pwm_nrfx_init(const struct device *dev) (16ul * 1000ul * 1000ul)), \ IF_ENABLED(CONFIG_DCACHE, \ (.mem_attr = PWM_GET_MEM_ATTR(idx),)) \ + IF_ENABLED(PWM_NRFX_USE_CLOCK_CONTROL, \ + (.clk_dev = PWM_NRFX_IS_FAST(_, /*empty*/, idx, _) \ + ? DEVICE_DT_GET(DT_CLOCKS_CTLR(PWM(idx))) \ + : NULL, \ + .clk_spec = { \ + .frequency = \ + NRF_PERIPH_GET_FREQUENCY(PWM(idx)), \ + },)) \ }; \ static int pwm_nrfx_init##idx(const struct device *dev) \ { \ @@ -405,7 +545,7 @@ static int pwm_nrfx_init(const struct device *dev) pwm_nrfx_init##idx, PM_DEVICE_DT_GET(PWM(idx)), \ &pwm_nrfx_##idx##_data, \ &pwm_nrfx_##idx##_config, \ - POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + POST_KERNEL, PWM_INIT_PRIORITY(idx), \ &pwm_nrfx_drv_api_funcs) #define COND_PWM_NRFX_DEVICE(unused, prefix, i, _) \ diff --git a/drivers/pwm/pwm_numaker.c b/drivers/pwm/pwm_numaker.c index e67c7a0e05bf5..a4cadec4256cd 100644 --- a/drivers/pwm/pwm_numaker.c +++ b/drivers/pwm/pwm_numaker.c @@ -416,7 +416,7 @@ static void pwm_numaker_p2_isr(const struct device *dev) #endif /* CONFIG_PWM_CAPTURE */ /* PWM driver registration */ -static const struct pwm_driver_api pwm_numaker_driver_api = { +static DEVICE_API(pwm, pwm_numaker_driver_api) = { .set_cycles = pwm_numaker_set_cycles, .get_cycles_per_sec = pwm_numaker_get_cycles_per_sec, #ifdef CONFIG_PWM_CAPTURE diff --git a/drivers/pwm/pwm_nxp_flexio.c b/drivers/pwm/pwm_nxp_flexio.c index 4dbafd8250f9e..ed8075f6ee471 100644 --- a/drivers/pwm/pwm_nxp_flexio.c +++ b/drivers/pwm/pwm_nxp_flexio.c @@ -272,7 +272,7 @@ static int mcux_flexio_pwm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_nxp_flexio_driver_api = { +static DEVICE_API(pwm, pwm_nxp_flexio_driver_api) = { .set_cycles = pwm_nxp_flexio_set_cycles, .get_cycles_per_sec = pwm_nxp_flexio_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_nxp_s32_emios.c b/drivers/pwm/pwm_nxp_s32_emios.c index e5a0513fb2ffa..2547892d56c21 100644 --- a/drivers/pwm/pwm_nxp_s32_emios.c +++ b/drivers/pwm/pwm_nxp_s32_emios.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -22,40 +23,58 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_PWM_LOG_LEVEL); #define DT_DRV_COMPAT nxp_s32_emios_pwm +#if !defined(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED) +#define EMIOS_PWM_IP_NUM_OF_CHANNELS_USED EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 +#endif + /* * Need to fill to this array at runtime, cannot do at build time like * the HAL over configuration tool due to limitation of the integration */ #if EMIOS_PWM_IP_USED extern uint8 eMios_Pwm_Ip_IndexInChState[EMIOS_PWM_IP_INSTANCE_COUNT][EMIOS_PWM_IP_CHANNEL_COUNT]; +#define EMIOS_PWM_MASTER_CHANNEL(channel, bus) \ + ((bus == EMIOS_PWM_IP_BUS_A) ? 23 : \ + ((bus == EMIOS_PWM_IP_BUS_F) ? 22 : \ + ((bus == EMIOS_PWM_IP_BUS_BCDE) ? ((channel >> 3) * 8) : channel))) #endif #ifdef CONFIG_PWM_CAPTURE extern uint8 eMios_Icu_Ip_IndexInChState[EMIOS_ICU_IP_INSTANCE_COUNT][EMIOS_ICU_IP_NUM_OF_CHANNELS]; +#define EMIOS_ICU_MASTER_CHANNEL(channel, bus) \ + ((bus == EMIOS_ICU_BUS_A) ? 23 : \ + ((bus == EMIOS_ICU_BUS_F) ? 22 : \ + ((bus == EMIOS_ICU_BUS_DIVERSE) ? ((channel >> 3) * 8) : channel))) + /* We need maximum three edges for measure both period and cycle */ #define MAX_NUM_EDGE 3 +#endif -struct pwm_nxp_s32_capture_data { - bool continuous; +struct pwm_nxp_s32_channel_data { bool inverted; + uint8_t master_channel; + +#if EMIOS_PWM_IP_USED + uint32_t curr_period; +#endif + +#ifdef CONFIG_PWM_CAPTURE + bool continuous; bool pulse_capture; bool period_capture; void *user_data; pwm_capture_callback_handler_t callback; eMios_Icu_ValueType edge_buff[MAX_NUM_EDGE]; -}; #endif +}; struct pwm_nxp_s32_data { uint32_t emios_clk; #if EMIOS_PWM_IP_USED uint8_t start_pwm_ch; #endif - -#ifdef CONFIG_PWM_CAPTURE - struct pwm_nxp_s32_capture_data capture[EMIOS_ICU_IP_NUM_OF_CHANNELS]; -#endif + struct pwm_nxp_s32_channel_data ch_data[eMIOS_CH_UC_UC_COUNT]; }; #if EMIOS_PWM_IP_USED @@ -83,69 +102,237 @@ struct pwm_nxp_s32_config { #if EMIOS_PWM_IP_USED #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED -static int pwm_nxp_s32_set_cycles_internal_timebase(uint8_t instance, uint32_t channel, - uint32_t period_cycles, uint32_t pulse_cycles) +static int pwm_nxp_s32_set_cycles_opwfmb(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) { - bool need_update = false; + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + struct pwm_nxp_s32_channel_data *ch_data = &data->ch_data[channel]; - if ((period_cycles > EMIOS_PWM_IP_MAX_CNT_VAL) || - (period_cycles <= EMIOS_PWM_IP_MIN_CNT_VAL)) { - LOG_ERR("period_cycles is out of range"); - return -EINVAL; - } + Emios_Pwm_Ip_PolarityType polarity; - if (Emios_Pwm_Ip_GetPeriod(instance, channel) != period_cycles) { - Emios_Pwm_Ip_SetPeriod(instance, channel, period_cycles); - need_update = true; - } + unsigned int key; + + if ((ch_data->inverted != flags) || (!ch_data->curr_period)) { + /* If PWM flag is changed or this is the first time PWM channel is configured */ + polarity = (flags & PWM_POLARITY_MASK) ? EMIOS_PWM_IP_ACTIVE_LOW : + EMIOS_PWM_IP_ACTIVE_HIGH; - if (Emios_Pwm_Ip_GetDutyCycle(instance, channel) != pulse_cycles) { - need_update = true; - if (Emios_Pwm_Ip_SetDutyCycle(instance, channel, pulse_cycles)) { - LOG_ERR("Cannot set pulse cycles"); - return -EIO; + config->base->CH.UC[channel].C &= ~(eMIOS_C_MODE_MASK | + eMIOS_C_EDPOL_MASK); + config->base->CH.UC[channel].A = pulse_cycles; + config->base->CH.UC[channel].B = period_cycles; + + /* + * When entering OPWFMB mode, Output = Cn[EDPOL]. Unless 100% pulse cycle is + * expected, Cn[EDPOL] is set to complement value (i.e 0 if active high and + * 1 if active low). + */ + if (pulse_cycles) { + config->base->CH.UC[channel].C |= eMIOS_C_EDPOL(polarity); + } else { + config->base->CH.UC[channel].C |= eMIOS_C_EDPOL(!polarity); } - } - if (need_update) { - /* Force match so that the new period, duty cycle takes effect immediately */ - Emios_Pwm_Ip_ForceMatchTrailingEdge(instance, channel, true); + key = irq_lock(); + config->base->CH.UC[channel].C |= eMIOS_C_MODE(EMIOS_PWM_IP_MODE_OPWFMB_FLAG); + + if (pulse_cycles) { + /* Restore expected value for Cn[EDPOL] */ + config->base->CH.UC[channel].C = (config->base->CH.UC[channel].C & + ~(eMIOS_C_EDPOL_MASK)) | + eMIOS_C_EDPOL(!polarity); + } + irq_unlock(key); + + ch_data->curr_period = period_cycles; + ch_data->inverted = flags; + } else { + key = irq_lock(); + config->base->CH.UC[channel].A = pulse_cycles; + config->base->CH.UC[channel].B = period_cycles; + irq_unlock(key); } return 0; } #endif -#if defined(EMIOS_PWM_IP_MODE_OPWMCB_USED) || defined(EMIOS_PWM_IP_MODE_OPWMB_USED) -static int pwm_nxp_s32_set_cycles_external_timebase(uint8_t instance, uint32_t channel, - uint32_t period_cycles, uint32_t pulse_cycles) +#if defined(EMIOS_PWM_IP_MODE_OPWMCB_USED) +static int pwm_nxp_s32_set_cycles_opwmcb(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + Emios_Pwm_Ip_ChannelConfigType *pwm_info, + pwm_flags_t flags) { - uint8_t master_channel; + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + struct pwm_nxp_s32_channel_data *ch_data = &data->ch_data[channel]; + struct pwm_nxp_s32_channel_data *master_ch_data = &data->ch_data[ch_data->master_channel]; - if ((period_cycles > EMIOS_PWM_IP_MAX_CNT_VAL) || - (period_cycles <= EMIOS_PWM_IP_MIN_CNT_VAL)) { - LOG_ERR("period_cycles is out of range"); - return -EINVAL; - } + unsigned int key; + Emios_Pwm_Ip_PolarityType polarity; + + /* Convert to written value into eMIOS register */ + if (pulse_cycles == 0) { + pulse_cycles = EMIOS_PWM_IP_MAX_CNT_VAL; + } else if (pulse_cycles == period_cycles) { + pulse_cycles = 1; + } else { + pulse_cycles = period_cycles - (pulse_cycles >> 1); + } + + if ((ch_data->inverted != flags) || (!ch_data->curr_period)) { + /* If PWM flag is changed or this is the first time PWM channel is configured */ + polarity = (flags & PWM_POLARITY_MASK) ? EMIOS_PWM_IP_ACTIVE_LOW : + EMIOS_PWM_IP_ACTIVE_HIGH; + + if (master_ch_data->curr_period != period_cycles) { + /* + * Move timebase channel to GPIO mode --> configure period --> MCB mode + * Period can be shared between multiple PWM channels, only configure + * when needed. + */ + config->base->CH.UC[ch_data->master_channel].C &= ~eMIOS_C_MODE_MASK; + config->base->CH.UC[ch_data->master_channel].A = period_cycles; + } + + config->base->CH.UC[channel].C &= ~(eMIOS_C_MODE_MASK | + eMIOS_C_EDPOL_MASK | + eMIOS_C_BSL_MASK); - if (Emios_Pwm_Ip_GetPeriod(instance, channel) != period_cycles) { /* - * This mode uses internal counter, so change period and cycle - * don't effect to the others + * When entering OPWMCB mode, Output = !Cn[EDPOL]. If 100% pulse cycle is expected + * Cn[EDPOL] is set to complement value (i.e 0 if active high and 1 if active low). */ - master_channel = Emios_Pwm_Ip_GetMasterBusChannel(instance, channel); + if (pulse_cycles == 1) { + /* 100% pulse cycle */ + config->base->CH.UC[channel].C |= eMIOS_C_EDPOL(!polarity); + } else { + config->base->CH.UC[channel].C |= eMIOS_C_EDPOL(polarity); + } + + config->base->CH.UC[channel].A = pulse_cycles; + config->base->CH.UC[channel].B = pwm_info->DeadTime; + + key = irq_lock(); + config->base->CH.UC[channel].C |= (eMIOS_C_MODE(pwm_info->Mode) | + eMIOS_C_BSL(pwm_info->Timebase)); + + if (pulse_cycles == 1) { + config->base->CH.UC[channel].C = (config->base->CH.UC[channel].C & + ~eMIOS_C_EDPOL_MASK) | + eMIOS_C_EDPOL(polarity); + } + irq_unlock(key); - if (Emios_Mcl_Ip_SetCounterBusPeriod(instance, master_channel, period_cycles)) { - LOG_ERR("Cannot set counter period"); - return -EIO; + if (master_ch_data->curr_period != period_cycles) { + config->base->CH.UC[ch_data->master_channel].C |= + eMIOS_C_MODE(EMIOS_IP_MCB_UP_DOWN_COUNTER); + master_ch_data->curr_period = period_cycles; } + + ch_data->inverted = flags; + ch_data->curr_period = period_cycles; + } else if (master_ch_data->curr_period != period_cycles) { + key = irq_lock(); + config->base->CH.UC[ch_data->master_channel].A = period_cycles; + config->base->CH.UC[channel].A = pulse_cycles; + irq_unlock(key); + + master_ch_data->curr_period = period_cycles; + } else { + config->base->CH.UC[channel].A = pulse_cycles; } - if (Emios_Pwm_Ip_GetDutyCycle(instance, channel) != pulse_cycles) { - if (Emios_Pwm_Ip_SetDutyCycle(instance, channel, pulse_cycles)) { - LOG_ERR("Cannot set pulse cycles"); - return -EIO; + return 0; +} +#endif + +#if defined(EMIOS_PWM_IP_MODE_OPWMB_USED) +static int pwm_nxp_s32_set_cycles_opwmb(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + Emios_Pwm_Ip_ChannelConfigType *pwm_info, + pwm_flags_t flags) +{ + const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + struct pwm_nxp_s32_channel_data *ch_data = &data->ch_data[channel]; + struct pwm_nxp_s32_channel_data *master_ch_data = &data->ch_data[ch_data->master_channel]; + + Emios_Pwm_Ip_PolarityType polarity; + + unsigned int key; + + if ((ch_data->inverted != flags) || (!ch_data->curr_period)) { + /* If PWM flag is changed or this is the first time PWM channel is configured */ + polarity = (flags & PWM_POLARITY_MASK) ? EMIOS_PWM_IP_ACTIVE_LOW : + EMIOS_PWM_IP_ACTIVE_HIGH; + + if (master_ch_data->curr_period != period_cycles) { + /* + * Move timebase channel to GPIO mode --> configure period --> MCB mode + * Period can be shared between multiple PWM channels, only configure + * when needed. + */ + config->base->CH.UC[ch_data->master_channel].C &= ~eMIOS_C_MODE_MASK; + config->base->CH.UC[ch_data->master_channel].A = period_cycles; + } + + config->base->CH.UC[channel].C &= ~(eMIOS_C_MODE_MASK | + eMIOS_C_EDPOL_MASK | eMIOS_C_BSL_MASK); + + config->base->CH.UC[channel].A = pwm_info->PhaseShift; + config->base->CH.UC[channel].B = pulse_cycles; + + /* + * When entering OPWMB mode, Output = Cn[EDPOL]. Unless 100% pulse cycle is + * expected, Cn[EDPOL] is set to complement value (i.e 0 if active high and + * 1 if active low). + */ + if (pulse_cycles == period_cycles) { + config->base->CH.UC[channel].C |= eMIOS_C_EDPOL(polarity); + } else { + config->base->CH.UC[channel].C |= eMIOS_C_EDPOL(!polarity); + } + + key = irq_lock(); + config->base->CH.UC[channel].C |= eMIOS_C_MODE(pwm_info->Mode) | + eMIOS_C_BSL(pwm_info->Timebase); + + if (pulse_cycles != period_cycles) { + config->base->CH.UC[channel].C = (config->base->CH.UC[channel].C & + ~(eMIOS_C_EDPOL_MASK)) | + eMIOS_C_EDPOL(polarity); + } + + if (!pwm_info->PhaseShift) { + /* + * If Phase Shift == 0, Force Match A to ensure PWM pulse can be + * generated immediately. Otherwise, it will need to wait until + * next period boundary. + */ + config->base->CH.UC[channel].C |= eMIOS_C_FORCMA(1); } + irq_unlock(key); + + if (master_ch_data->curr_period != period_cycles) { + config->base->CH.UC[ch_data->master_channel].C |= + eMIOS_C_MODE(EMIOS_IP_MCB_UP_COUNTER); + master_ch_data->curr_period = period_cycles; + } + + ch_data->inverted = flags; + ch_data->curr_period = period_cycles; + } else if (master_ch_data->curr_period != period_cycles) { + key = irq_lock(); + config->base->CH.UC[ch_data->master_channel].A = period_cycles; + config->base->CH.UC[channel].B = pulse_cycles; + irq_unlock(key); + + master_ch_data->curr_period = period_cycles; + } else { + config->base->CH.UC[channel].B = pulse_cycles; } return 0; @@ -176,49 +363,60 @@ static int pwm_nxp_s32_set_cycles(const struct device *dev, uint32_t channel, logic_ch = eMios_Pwm_Ip_IndexInChState[config->instance][channel] - data->start_pwm_ch; pwm_info = &config->pulse_info->pwm_info[logic_ch]; - if ((flags & PWM_POLARITY_MASK) == pwm_info->OutputPolarity) { - LOG_ERR("Only support configuring output polarity at boot time"); - return -ENOTSUP; - } - switch (pwm_info->Mode) { #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED case EMIOS_PWM_IP_MODE_OPWFMB_FLAG: - return pwm_nxp_s32_set_cycles_internal_timebase(config->instance, channel, - period_cycles, pulse_cycles); + + if ((period_cycles > EMIOS_PWM_IP_MAX_CNT_VAL) || + (period_cycles <= EMIOS_PWM_IP_MIN_CNT_VAL)) { + LOG_ERR("Period cycles is out of range"); + return -EINVAL; + } + + return pwm_nxp_s32_set_cycles_opwfmb(dev, channel, period_cycles, + pulse_cycles, flags); #endif #ifdef EMIOS_PWM_IP_MODE_OPWMCB_USED case EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG: case EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG: - if ((period_cycles % 2)) { - LOG_ERR("OPWMCB mode: period must be an even number"); + + period_cycles = (period_cycles + 2) / 2; + + if ((period_cycles > EMIOS_PWM_IP_MAX_CNT_VAL) || + (period_cycles <= EMIOS_PWM_IP_MIN_CNT_VAL)) { + LOG_ERR("Period cycles is out of range"); return -EINVAL; } - return pwm_nxp_s32_set_cycles_external_timebase(config->instance, channel, - (period_cycles + 2) / 2, - pulse_cycles); + return pwm_nxp_s32_set_cycles_opwmcb(dev, channel, period_cycles, + pulse_cycles, pwm_info, flags); #endif #if defined(EMIOS_PWM_IP_MODE_OPWMB_USED) case EMIOS_PWM_IP_MODE_OPWMB_FLAG: - if ((Emios_Pwm_Ip_GetPhaseShift(config->instance, channel) + - pulse_cycles) > period_cycles) { - LOG_ERR("OPWMB mode: new duty cycle + phase shift must <= new period"); + + if ((period_cycles > EMIOS_PWM_IP_MAX_CNT_VAL) || + (period_cycles <= EMIOS_PWM_IP_MIN_CNT_VAL)) { + LOG_ERR("Period cycles is out of range"); return -EINVAL; } - return pwm_nxp_s32_set_cycles_external_timebase(config->instance, channel, - period_cycles, pulse_cycles); + pulse_cycles += pwm_info->PhaseShift; + + if (pulse_cycles > period_cycles) { + LOG_ERR("Pulse cycles is out of range"); + return -EINVAL; + } + + return pwm_nxp_s32_set_cycles_opwmb(dev, channel, period_cycles, + pulse_cycles, pwm_info, flags); #endif default: /* Never reach here */ - break; + return 0; } - - return 0; } #endif @@ -284,12 +482,12 @@ static int pwm_nxp_s32_capture_configure(const struct device *dev, return -EBUSY; } - data->capture[channel].continuous = (flags & PWM_CAPTURE_MODE_MASK); - data->capture[channel].inverted = (flags & PWM_POLARITY_MASK); - data->capture[channel].pulse_capture = (flags & PWM_CAPTURE_TYPE_PULSE); - data->capture[channel].period_capture = (flags & PWM_CAPTURE_TYPE_PERIOD); - data->capture[channel].callback = cb; - data->capture[channel].user_data = user_data; + data->ch_data[channel].continuous = (flags & PWM_CAPTURE_MODE_MASK); + data->ch_data[channel].inverted = (flags & PWM_POLARITY_MASK); + data->ch_data[channel].pulse_capture = (flags & PWM_CAPTURE_TYPE_PULSE); + data->ch_data[channel].period_capture = (flags & PWM_CAPTURE_TYPE_PERIOD); + data->ch_data[channel].callback = cb; + data->ch_data[channel].user_data = user_data; return 0; } @@ -313,7 +511,7 @@ static int pwm_nxp_s32_capture_enable(const struct device *dev, uint32_t channel return -EINVAL; } - if (!data->capture[channel].callback) { + if (!data->ch_data[channel].callback) { LOG_ERR("Callback is not configured"); return -EINVAL; } @@ -325,7 +523,7 @@ static int pwm_nxp_s32_capture_enable(const struct device *dev, uint32_t channel } /* If just measure period, we just need 2 edges */ - if (data->capture[channel].period_capture && !data->capture[channel].pulse_capture) { + if (data->ch_data[channel].period_capture && !data->ch_data[channel].pulse_capture) { num_edge = 2U; edge = EMIOS_ICU_RISING_EDGE; } else { @@ -338,7 +536,7 @@ static int pwm_nxp_s32_capture_enable(const struct device *dev, uint32_t channel Emios_Icu_Ip_EnableNotification(config->instance, channel); Emios_Icu_Ip_StartTimestamp(config->instance, channel, - data->capture[channel].edge_buff, + data->ch_data[channel].edge_buff, MAX_NUM_EDGE, num_edge); return 0; @@ -363,68 +561,22 @@ static int pwm_nxp_s32_capture_disable(const struct device *dev, uint32_t channe return 0; } - -static int pwm_nxp_s32_get_master_bus(const struct device *dev, uint32_t channel) -{ - const struct pwm_nxp_s32_config *config = dev->config; - uint8_t bus_select, master_bus; - - bus_select = (config->base->CH.UC[channel].C & eMIOS_C_BSL_MASK) >> eMIOS_C_BSL_SHIFT; - - switch (bus_select) { - case 0: - master_bus = 23U; - break; - case 1: - master_bus = (channel < 8U) ? 0U : ((channel < 16U) ? 8U : 16U); - break; - case 2: - master_bus = 22U; - break; - default: - /* Default is internal counter */ - master_bus = channel; - break; - } - - return master_bus; -} #endif static int pwm_nxp_s32_get_cycles_per_sec(const struct device *dev, - uint32_t channel, - uint64_t *cycles) + uint32_t channel, uint64_t *cycles) { const struct pwm_nxp_s32_config *config = dev->config; struct pwm_nxp_s32_data *data = dev->data; - uint8_t master_bus = 0xFFU; - uint8_t internal_prescaler, global_prescaler; + uint8_t internal_prescaler, global_prescaler, master_channel; -#if EMIOS_PWM_IP_USED - if (eMios_Pwm_Ip_IndexInChState[config->instance][channel] < - EMIOS_PWM_IP_NUM_OF_CHANNELS_USED) { - master_bus = Emios_Pwm_Ip_GetMasterBusChannel(config->instance, channel); - } -#endif - -#ifdef CONFIG_PWM_CAPTURE - if (eMios_Icu_Ip_IndexInChState[config->instance][channel] < - EMIOS_ICU_IP_NUM_OF_CHANNELS_USED) { - master_bus = pwm_nxp_s32_get_master_bus(dev, channel); - } -#endif - - if (master_bus == 0xFF) { - LOG_ERR("Channel %d is not configured for PWM", channel); - return -EINVAL; - } - - internal_prescaler = (config->base->CH.UC[master_bus].C2 & eMIOS_C2_UCEXTPRE_MASK) >> + master_channel = data->ch_data[channel].master_channel; + internal_prescaler = (config->base->CH.UC[master_channel].C2 & eMIOS_C2_UCEXTPRE_MASK) >> eMIOS_C2_UCEXTPRE_SHIFT; /* Clock source for internal prescaler is from either eMIOS or eMIOS / global prescaler */ - if (config->base->CH.UC[master_bus].C2 & eMIOS_C2_UCPRECLK_MASK) { + if (config->base->CH.UC[master_channel].C2 & eMIOS_C2_UCPRECLK_MASK) { *cycles = data->emios_clk / (internal_prescaler + 1); } else { global_prescaler = (config->base->MCR & eMIOS_MCR_GPRE_MASK) >> @@ -441,7 +593,8 @@ static int pwm_nxp_s32_pulse_gen_init(const struct device *dev) const struct pwm_nxp_s32_config *config = dev->config; struct pwm_nxp_s32_data *data = dev->data; - const Emios_Pwm_Ip_ChannelConfigType *pwm_info; + struct pwm_nxp_s32_channel_data *ch_data; + Emios_Pwm_Ip_ChannelConfigType pwm_info; uint8_t ch_id; static uint8_t logic_ch; @@ -449,9 +602,20 @@ static int pwm_nxp_s32_pulse_gen_init(const struct device *dev) data->start_pwm_ch = logic_ch; for (ch_id = 0; ch_id < config->pulse_info->pwm_pulse_channels; ch_id++) { - pwm_info = &config->pulse_info->pwm_info[ch_id]; - eMios_Pwm_Ip_IndexInChState[config->instance][pwm_info->ChannelId] = logic_ch++; - Emios_Pwm_Ip_InitChannel(config->instance, pwm_info); + memcpy(&pwm_info, &config->pulse_info->pwm_info[ch_id], + sizeof(Emios_Pwm_Ip_ChannelConfigType)); + + /* + * Let eMIOS channel is in GPIO mode, the actual PWM mode will be + * configured at the first time pwm_set* is called. + */ + pwm_info.Mode = EMIOS_PWM_IP_MODE_GPO; + eMios_Pwm_Ip_IndexInChState[config->instance][pwm_info.ChannelId] = logic_ch++; + Emios_Pwm_Ip_InitChannel(config->instance, &pwm_info); + + ch_data = &data->ch_data[pwm_info.ChannelId]; + ch_data->master_channel = EMIOS_PWM_MASTER_CHANNEL(pwm_info.ChannelId, + pwm_info.Timebase); } return 0; @@ -462,7 +626,9 @@ static int pwm_nxp_s32_pulse_gen_init(const struct device *dev) static int pwm_nxp_s32_pulse_capture_init(const struct device *dev) { const struct pwm_nxp_s32_config *config = dev->config; + struct pwm_nxp_s32_data *data = dev->data; + struct pwm_nxp_s32_channel_data *ch_data; const eMios_Icu_Ip_ChannelConfigType *icu_info; uint8_t ch_id; @@ -470,7 +636,11 @@ static int pwm_nxp_s32_pulse_capture_init(const struct device *dev) for (ch_id = 0; ch_id < config->icu_cfg->nNumChannels; ch_id++) { icu_info = &(*config->icu_cfg->pChannelsConfig)[ch_id]; + ch_data = &data->ch_data[icu_info->hwChannel]; + eMios_Icu_Ip_IndexInChState[config->instance][icu_info->hwChannel] = logic_ch++; + ch_data->master_channel = EMIOS_ICU_MASTER_CHANNEL(icu_info->hwChannel, + icu_info->CntBus); } if (Emios_Icu_Ip_Init(config->instance, config->icu_cfg)) { @@ -487,29 +657,29 @@ static void pwm_nxp_s32_capture_callback(const struct device *dev, uint32_t chan uint32_t period = 0, pulse = 0; - if (data->capture[channel].period_capture && !data->capture[channel].pulse_capture) { - period = pwm_nxp_s32_capture_calc(data->capture[channel].edge_buff[0], - data->capture[channel].edge_buff[1]); + if (data->ch_data[channel].period_capture && !data->ch_data[channel].pulse_capture) { + period = pwm_nxp_s32_capture_calc(data->ch_data[channel].edge_buff[0], + data->ch_data[channel].edge_buff[1]); } else { - if (data->capture[channel].pulse_capture) { - pulse = pwm_nxp_s32_pulse_calc(data->capture[channel].inverted, - data->capture[channel].edge_buff, + if (data->ch_data[channel].pulse_capture) { + pulse = pwm_nxp_s32_pulse_calc(data->ch_data[channel].inverted, + data->ch_data[channel].edge_buff, Emios_Icu_Ip_GetInputLevel(config->instance, channel)); } - if (data->capture[channel].period_capture) { - period = pwm_nxp_s32_capture_calc(data->capture[channel].edge_buff[0], - data->capture[channel].edge_buff[2]); + if (data->ch_data[channel].period_capture) { + period = pwm_nxp_s32_capture_calc(data->ch_data[channel].edge_buff[0], + data->ch_data[channel].edge_buff[2]); } } - if (!data->capture[channel].continuous) { + if (!data->ch_data[channel].continuous) { Emios_Icu_Ip_StopTimestamp(config->instance, channel); } - data->capture[channel].callback(dev, channel, period, pulse, 0, - data->capture[channel].user_data); + data->ch_data[channel].callback(dev, channel, period, pulse, 0, + data->ch_data[channel].user_data); } #endif @@ -551,7 +721,7 @@ static int pwm_nxp_s32_init(const struct device *dev) return err; } -static const struct pwm_driver_api pwm_nxp_s32_driver_api = { +static DEVICE_API(pwm, pwm_nxp_s32_driver_api) = { .set_cycles = pwm_nxp_s32_set_cycles, .get_cycles_per_sec = pwm_nxp_s32_get_cycles_per_sec, #ifdef CONFIG_PWM_CAPTURE @@ -561,14 +731,6 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { #endif }; -/* - * If timebase is configured in MCB up/down count mode: pwm period = (2 * master bus's period - 2) - */ -#define EMIOS_PWM_PERIOD_TIME_BASE(node_id) \ - COND_CODE_1(DT_ENUM_HAS_VALUE(node_id, mode, MCB_UP_DOWN_COUNTER), \ - (2 * DT_PROP_BY_PHANDLE(node_id, master_bus, period) - 2), \ - (DT_PROP_BY_PHANDLE(node_id, master_bus, period))) - #define EMIOS_PWM_IS_MODE_OPWFMB(node_id) \ DT_ENUM_HAS_VALUE(node_id, pwm_mode, OPWFMB) @@ -594,22 +756,11 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { EMIOS_PWM_LOG(node_id, "invalid master bus")); #define EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ - BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, duty_cycle), \ - EMIOS_PWM_LOG(node_id, "duty-cycle must be configured")); \ - BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, polarity), \ - EMIOS_PWM_LOG(node_id, "polarity must be configured")); \ BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, input_filter), \ EMIOS_PWM_LOG(node_id, "input-filter is not used")); #define EMIOS_PWM_VERIFY_MODE_OPWFMB(node_id) \ EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ - BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, period), \ - EMIOS_PWM_LOG(node_id, "period must be configured")); \ - BUILD_ASSERT(IN_RANGE(DT_PROP(node_id, period), EMIOS_PWM_IP_MIN_CNT_VAL + 1, \ - EMIOS_PWM_IP_MAX_CNT_VAL), \ - EMIOS_PWM_LOG(node_id, "period is out of range")); \ - BUILD_ASSERT(DT_PROP(node_id, duty_cycle) <= DT_PROP(node_id, period), \ - EMIOS_PWM_LOG(node_id, "duty-cycle must <= period")); \ BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, master_bus), \ EMIOS_PWM_LOG(node_id, "master-bus must not be configured")); \ BUILD_ASSERT(DT_PROP(node_id, dead_time) == 0, \ @@ -622,16 +773,8 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, \ MCB_UP_DOWN_COUNTER), \ EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up-down")); \ - BUILD_ASSERT((DT_PROP(node_id, duty_cycle) + DT_PROP(node_id, dead_time)) <= \ - EMIOS_PWM_PERIOD_TIME_BASE(node_id), \ - EMIOS_PWM_LOG(node_id, "duty-cycle + dead-time must <= period")); \ - BUILD_ASSERT(DT_PROP(node_id, dead_time) <= DT_PROP(node_id, duty_cycle), \ - EMIOS_PWM_LOG(node_id, "dead-time must <= duty-cycle")); \ BUILD_ASSERT(DT_PROP(node_id, phase_shift) == 0, \ EMIOS_PWM_LOG(node_id, "phase-shift is not used")); \ - BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ - EMIOS_PWM_LOG(node_id, "period is not used," \ - " driver takes the value from master bus")); \ BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, prescaler), \ EMIOS_PWM_LOG(node_id, "prescaler is not used," \ " driver takes the value from master bus")); \ @@ -643,12 +786,6 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { EMIOS_PWM_PULSE_GEN_COMMON_VERIFY(node_id) \ BUILD_ASSERT(DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, MCB_UP_COUNTER), \ EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up")); \ - BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ - EMIOS_PWM_LOG(node_id, "period is not used," \ - " driver takes the value from master bus")); \ - BUILD_ASSERT((DT_PROP(node_id, duty_cycle) + DT_PROP(node_id, phase_shift)) <= \ - EMIOS_PWM_PERIOD_TIME_BASE(node_id), \ - EMIOS_PWM_LOG(node_id, "duty-cycle + phase-shift must <= period")); \ BUILD_ASSERT(DT_PROP(node_id, dead_time) == 0, \ EMIOS_PWM_LOG(node_id, "dead-time is not used")); \ BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, prescaler), \ @@ -662,9 +799,6 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { (BUILD_ASSERT( \ DT_ENUM_HAS_VALUE(DT_PHANDLE(node_id, master_bus), mode, MCB_UP_COUNTER), \ EMIOS_PWM_LOG(node_id, "master-bus must be configured in MCB up"));)) \ - IF_ENABLED(DT_NODE_HAS_PROP(node_id, master_bus), \ - (BUILD_ASSERT(DT_PROP_BY_PHANDLE(node_id, master_bus, period) == 0xFFFF, \ - EMIOS_PWM_LOG(node_id, "master-bus period must be 0xFFFF"));)) \ IF_ENABLED(UTIL_NOT(DT_NODE_HAS_PROP(node_id, master_bus)), \ (BUILD_ASSERT( \ BIT(DT_PROP(node_id, channel)) & DT_PROP(DT_GPARENT(node_id), internal_cnt),\ @@ -674,12 +808,6 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { (BUILD_ASSERT(DT_NODE_HAS_PROP(node_id, prescaler), \ EMIOS_PWM_LOG(node_id, "if use internal counter, prescaler must" \ " be configured")))); \ - BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, duty_cycle), \ - EMIOS_PWM_LOG(node_id, "duty-cycle is not used")); \ - BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, polarity), \ - EMIOS_PWM_LOG(node_id, "polarity is not used")); \ - BUILD_ASSERT(!DT_NODE_HAS_PROP(node_id, period), \ - EMIOS_PWM_LOG(node_id, "period is not used")); \ BUILD_ASSERT(DT_ENUM_HAS_VALUE(node_id, prescaler_src, PRESCALED_CLOCK), \ EMIOS_PWM_LOG(node_id, "prescaler-src is not used," \ " always use prescalered source")); @@ -707,9 +835,9 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { #define EMIOS_PWM_BUS(mode) DT_CAT(EMIOS_PWM_, mode) #define EMIOS_PWM_MODE(mode) DT_CAT3(EMIOS_PWM_IP_MODE_, mode, _FLAG) -#define EMIOS_PWM_POLARITY(mode) DT_CAT(EMIOS_PWM_IP_, mode) #define EMIOS_PWM_PS_SRC(mode) DT_CAT(EMIOS_PWM_IP_PS_SRC_, mode) +/* Keep minimal configuration used at driver initialization, no PWM signal is produced */ #define _EMIOS_PWM_PULSE_GEN_CONFIG(node_id) \ IF_ENABLED(UTIL_NOT(EMIOS_PWM_IS_CAPTURE_MODE(node_id)), \ ({ \ @@ -725,10 +853,10 @@ static const struct pwm_driver_api pwm_nxp_s32_driver_api = { .PhaseShift = DT_PROP(node_id, phase_shift), \ .DeadTime = DT_PROP(node_id, dead_time), \ .OutputDisableSource = EMIOS_PWM_IP_OUTPUT_DISABLE_NONE, \ - .OutputPolarity = EMIOS_PWM_POLARITY(DT_STRING_TOKEN(node_id, polarity)), \ + .OutputPolarity = EMIOS_PWM_IP_ACTIVE_LOW, \ .DebugMode = DT_PROP(node_id, freeze), \ - .PeriodCount = DT_PROP_OR(node_id, period, EMIOS_PWM_PERIOD_TIME_BASE(node_id)),\ - .DutyCycle = DT_PROP(node_id, duty_cycle), \ + .PeriodCount = 0, \ + .DutyCycle = 0, \ },)) #define EMIOS_PWM_PULSE_GEN_CONFIG(n) \ diff --git a/drivers/pwm/pwm_pca9685.c b/drivers/pwm/pwm_pca9685.c index f08bdd4cf9b04..110e8e71a24af 100644 --- a/drivers/pwm/pwm_pca9685.c +++ b/drivers/pwm/pwm_pca9685.c @@ -229,7 +229,7 @@ static int pca9685_get_cycles_per_sec(const struct device *dev, return 0; } -static const struct pwm_driver_api pca9685_api = { +static DEVICE_API(pwm, pca9685_api) = { .set_cycles = pca9685_set_cycles, .get_cycles_per_sec = pca9685_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_rcar.c b/drivers/pwm/pwm_rcar.c index 051d02503ccd0..b79b0e3089b0a 100644 --- a/drivers/pwm/pwm_rcar.c +++ b/drivers/pwm/pwm_rcar.c @@ -243,7 +243,7 @@ static int pwm_rcar_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_rcar_driver_api = { +static DEVICE_API(pwm, pwm_rcar_driver_api) = { .set_cycles = pwm_rcar_set_cycles, .get_cycles_per_sec = pwm_rcar_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_renesas_ra.c b/drivers/pwm/pwm_renesas_ra.c new file mode 100644 index 0000000000000..8942b76aa0fdf --- /dev/null +++ b/drivers/pwm/pwm_renesas_ra.c @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include +#include "r_gpt.h" +#include "r_gpt_cfg.h" +#include +#include + +LOG_MODULE_REGISTER(pwm_renesas_ra, CONFIG_PWM_LOG_LEVEL); + +#define DT_DRV_COMPAT renesas_ra_pwm + +#define MAX_PIN 2U +#define GPT_PRV_GTIO_HIGH_COMPARE_MATCH_LOW_CYCLE_END 0x6U +#define GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END 0x9U +#define GPT_PRV_GTIOR_INITIAL_LEVEL_BIT 4 +#define GPT_PRV_GTIO_TOGGLE_COMPARE_MATCH 0x3U + +struct pwm_renesas_ra_capture_data { + pwm_capture_callback_handler_t callback; + void *user_data; + uint64_t period; + uint64_t pulse; + bool is_pulse_capture; + bool is_busy; + uint32_t overflows; + bool continuous; +}; + +struct pwm_renesas_ra_data { + gpt_instance_ctrl_t fsp_ctrl; + timer_cfg_t fsp_cfg; + gpt_extended_cfg_t extend_cfg; + uint16_t capture_a_event; + uint16_t overflow_event; + +#ifdef CONFIG_PWM_CAPTURE + struct pwm_renesas_ra_capture_data capture; +#endif /* CONFIG_PWM_CAPTURE */ +}; + +struct pwm_renesas_ra_config { + const struct device *clock_dev; + struct clock_control_ra_subsys_cfg clock_subsys; + const struct pinctrl_dev_config *pincfg; +}; + +static uint32_t pwm_renesas_ra_gtior_calculate(gpt_pin_level_t const stop_level) +{ + /* The stop level is used as both the initial level and the stop level. */ + uint32_t gtior = R_GPT0_GTIOR_OAE_Msk | ((uint32_t)stop_level << R_GPT0_GTIOR_OADFLT_Pos) | + ((uint32_t)stop_level << GPT_PRV_GTIOR_INITIAL_LEVEL_BIT); + + uint32_t gtion = GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END; + + /* Calculate the gtior value for PWM mode only */ + gtior |= gtion; + + return gtior; +} + +static int pwm_renesas_ra_apply_gtior_config(gpt_instance_ctrl_t *const p_ctrl, + timer_cfg_t const *const p_cfg) +{ + gpt_extended_cfg_t *p_extend = (gpt_extended_cfg_t *)p_cfg->p_extend; + uint32_t gtior = p_extend->gtior_setting.gtior; + +#if GPT_CFG_OUTPUT_SUPPORT_ENABLE + + /* Check if custom GTIOR settings are provided. */ + if (p_extend->gtior_setting.gtior == 0) { + /* If custom GTIOR settings are not provided, calculate GTIOR. */ + if (p_extend->gtioca.output_enabled) { + uint32_t gtioca_gtior = + pwm_renesas_ra_gtior_calculate(p_extend->gtioca.stop_level); + + gtior |= gtioca_gtior << R_GPT0_GTIOR_GTIOA_Pos; + } + + if (p_extend->gtiocb.output_enabled) { + uint32_t gtiocb_gtior = + pwm_renesas_ra_gtior_calculate(p_extend->gtiocb.stop_level); + + gtior |= gtiocb_gtior << R_GPT0_GTIOR_GTIOB_Pos; + } + } +#endif + +#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE + gpt_extended_pwm_cfg_t const *p_pwm_cfg = p_extend->p_pwm_cfg; + + if (NULL != p_pwm_cfg) { + /* Check if custom GTIOR settings are provided. */ + if (p_extend->gtior_setting.gtior == 0) { + /* If custom GTIOR settings are not provided, set gtioca_disable_settings + * and gtiocb_disable_settings. + */ + gtior |= (uint32_t)(p_pwm_cfg->gtioca_disable_setting + << R_GPT0_GTIOR_OADF_Pos); + gtior |= (uint32_t)(p_pwm_cfg->gtiocb_disable_setting + << R_GPT0_GTIOR_OBDF_Pos); + } + } +#endif + + /* Check if custom GTIOR settings are provided. */ + if (p_extend->gtior_setting.gtior == 0) { + /* + * If custom GTIOR settings are not provided, configure the noise filter for + * the GTIOC pins. + */ + gtior |= (uint32_t)(p_extend->capture_filter_gtioca << R_GPT0_GTIOR_NFAEN_Pos); + gtior |= (uint32_t)(p_extend->capture_filter_gtiocb << R_GPT0_GTIOR_NFBEN_Pos); + } + + /* Set the I/O control register. */ + p_ctrl->p_reg->GTIOR = gtior; + + return 0; +} + +static int pwm_renesas_ra_set_cycles(const struct device *dev, uint32_t pin, uint32_t period_cycles, + uint32_t pulse_cycles, pwm_flags_t flags) +{ + struct pwm_renesas_ra_data *data = dev->data; + uint32_t pulse; + fsp_err_t err; + + if (pin >= MAX_PIN) { + LOG_ERR("Only valid for gtioca and gtiocb pins"); + return -EINVAL; + } + + if ((data->fsp_ctrl.variant == TIMER_VARIANT_16_BIT && period_cycles > UINT16_MAX) || + (data->fsp_ctrl.variant == TIMER_VARIANT_32_BIT && period_cycles > UINT32_MAX)) { + LOG_ERR("Out of range period cycles are not valid"); + return -EINVAL; + } + + /* gtioca and gtiocb setting */ + if (pin == GPT_IO_PIN_GTIOCA) { + data->extend_cfg.gtioca.output_enabled = true; + } else { + data->extend_cfg.gtiocb.output_enabled = true; + } + + pulse = (flags & PWM_POLARITY_INVERTED) ? period_cycles - pulse_cycles : pulse_cycles; + + /* Apply gtio output setting */ + pwm_renesas_ra_apply_gtior_config(&data->fsp_ctrl, &data->fsp_cfg); + + /* Stop timer */ + err = R_GPT_Stop(&data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Update period cycles, reflected at an overflow */ + err = R_GPT_PeriodSet(&data->fsp_ctrl, period_cycles); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Update pulse cycles, reflected at an overflow */ + err = R_GPT_DutyCycleSet(&data->fsp_ctrl, pulse, pin); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Start timer */ + err = R_GPT_Start(&data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + LOG_DBG("channel %u, pin %u, pulse %u, period %u, prescaler: %u.", data->fsp_cfg.channel, + pin, pulse_cycles, period_cycles, data->fsp_cfg.source_div); + + return 0; +}; + +static int pwm_renesas_ra_get_cycles_per_sec(const struct device *dev, uint32_t pin, + uint64_t *cycles) +{ + struct pwm_renesas_ra_data *data = dev->data; + timer_info_t info; + fsp_err_t err; + + if (pin >= MAX_PIN) { + LOG_ERR("Only valid for gtioca and gtiocb pins"); + return -EINVAL; + } + + err = R_GPT_InfoGet(&data->fsp_ctrl, &info); + if (err != FSP_SUCCESS) { + return -EIO; + } + *cycles = (uint64_t)info.clock_frequency; + + return 0; +}; + +#ifdef CONFIG_PWM_CAPTURE +extern void gpt_capture_compare_a_isr(void); +extern void gpt_counter_overflow_isr(void); + +static void enable_irq(IRQn_Type const irq, uint32_t priority, void *p_context) +{ + if (irq >= 0) { + R_BSP_IrqCfgEnable(irq, priority, p_context); + } +} +static void disable_irq(IRQn_Type irq) +{ + /* Disable interrupts. */ + if (irq >= 0) { + R_BSP_IrqDisable(irq); + R_FSP_IsrContextSet(irq, NULL); + } +} + +static int pwm_renesas_ra_configure_capture(const struct device *dev, uint32_t pin, + pwm_flags_t flags, pwm_capture_callback_handler_t cb, + void *user_data) +{ + struct pwm_renesas_ra_data *data = dev->data; + + if (pin != GPT_IO_PIN_GTIOCA) { + LOG_ERR("Feature only support for gtioca"); + return -EINVAL; + } + if (!(flags & PWM_CAPTURE_TYPE_MASK)) { + LOG_ERR("No PWWM capture type specified"); + return -EINVAL; + } + if ((flags & PWM_CAPTURE_TYPE_MASK) == PWM_CAPTURE_TYPE_BOTH) { + LOG_ERR("Cannot capture both period and pulse width"); + return -ENOTSUP; + } + if (data->capture.is_busy) { + LOG_ERR("Capture already active on this pin"); + return -EBUSY; + } + + if (flags & PWM_CAPTURE_TYPE_PERIOD) { + data->capture.is_pulse_capture = false; + + if (flags & PWM_POLARITY_INVERTED) { + data->extend_cfg.start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + data->extend_cfg.capture_a_source = data->extend_cfg.start_source; + + } else { + data->extend_cfg.start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + data->extend_cfg.capture_a_source = data->extend_cfg.start_source; + } + } else { + data->capture.is_pulse_capture = true; + + if (flags & PWM_POLARITY_INVERTED) { + data->extend_cfg.start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + + data->extend_cfg.capture_a_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + } else { + data->extend_cfg.start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + + data->extend_cfg.capture_a_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + } + } + + data->capture.callback = cb; + data->capture.user_data = user_data; + data->capture.continuous = flags & PWM_CAPTURE_MODE_CONTINUOUS; + + if (data->capture.continuous) { + data->extend_cfg.stop_source = data->extend_cfg.capture_a_source; + data->extend_cfg.clear_source = data->extend_cfg.start_source; + } else { + data->extend_cfg.stop_source = (gpt_source_t)(GPT_SOURCE_NONE); + data->extend_cfg.clear_source = (gpt_source_t)(GPT_SOURCE_NONE); + } + + return 0; +} + +static int pwm_renesas_ra_enable_capture(const struct device *dev, uint32_t pin) +{ + struct pwm_renesas_ra_data *data = dev->data; + fsp_err_t err; + + if (pin != GPT_IO_PIN_GTIOCA) { + LOG_ERR("Feature only support for gtioca"); + return -EINVAL; + } + + if (data->capture.is_busy) { + LOG_ERR("Capture already active on this pin"); + return -EBUSY; + } + + if (!data->capture.callback) { + LOG_ERR("PWM capture not configured"); + return -EINVAL; + } + + data->capture.is_busy = true; + + /* Enable capture source */ + err = R_GPT_Enable(&data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Enable interruption */ + enable_irq(data->fsp_cfg.cycle_end_irq, data->fsp_cfg.cycle_end_irq, &data->fsp_ctrl); + enable_irq(data->extend_cfg.capture_a_irq, data->extend_cfg.capture_a_ipl, &data->fsp_ctrl); + + R_ICU->IELSR[data->fsp_cfg.cycle_end_irq] = (elc_event_t)data->overflow_event; + R_ICU->IELSR[data->extend_cfg.capture_a_irq] = (elc_event_t)data->capture_a_event; + + return 0; +} + +static int pwm_renesas_ra_disable_capture(const struct device *dev, uint32_t pin) +{ + struct pwm_renesas_ra_data *data = dev->data; + fsp_err_t err; + + if (pin != GPT_IO_PIN_GTIOCA) { + LOG_ERR("Feature only support for gtioca"); + return -EINVAL; + } + data->capture.is_busy = false; + + /* Disable interruption */ + disable_irq(data->fsp_cfg.cycle_end_irq); + disable_irq(data->extend_cfg.capture_a_irq); + + R_ICU->IELSR[data->fsp_cfg.cycle_end_irq] = (elc_event_t)ELC_EVENT_NONE; + R_ICU->IELSR[data->extend_cfg.capture_a_irq] = (elc_event_t)ELC_EVENT_NONE; + + /* Disable capture source */ + err = R_GPT_Disable(&data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Stop timer */ + err = R_GPT_Stop(&data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Clear timer */ + err = R_GPT_Reset(&data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +static void fsp_callback(timer_callback_args_t *p_args) +{ + const struct device *dev = p_args->p_context; + struct pwm_renesas_ra_data *data = dev->data; + timer_info_t info; + + (void)R_GPT_InfoGet(&data->fsp_ctrl, &info); + + uint64_t period = info.period_counts; + + /* The maximum period is one more than the maximum 16,32-bit number, but will be reflected + * as 0 + */ + if (period == 0U) { + if (data->fsp_ctrl.variant == TIMER_VARIANT_16_BIT) { + period = UINT16_MAX + 1U; + } else { + period = UINT32_MAX + 1U; + } + } + + /* Capture event */ + if (p_args->event == TIMER_EVENT_CAPTURE_A) { + if (p_args->capture != 0U) { + if (data->capture.is_pulse_capture == true) { + data->capture.pulse = + (data->capture.overflows * period) + p_args->capture; + data->capture.callback(dev, GPT_IO_PIN_GTIOCA, 0, + data->capture.pulse, 0, + data->capture.user_data); + } else { + data->capture.period = + (data->capture.overflows * period) + p_args->capture; + data->capture.callback(dev, GPT_IO_PIN_GTIOCA, data->capture.period, + 0, 0, data->capture.user_data); + } + data->capture.overflows = 0U; + /* Disable capture in single mode */ + if (data->capture.continuous == false) { + pwm_renesas_ra_disable_capture(dev, GPT_IO_PIN_GTIOCA); + } + } + } else if (p_args->event == TIMER_EVENT_CYCLE_END) { + data->capture.overflows++; + } else { + data->capture.callback(dev, GPT_IO_PIN_GTIOCA, 0, 0, -ECANCELED, + data->capture.user_data); + } +} + +#endif /* CONFIG_PWM_CAPTURE */ + +static DEVICE_API(pwm, pwm_renesas_ra_driver_api) = { + .get_cycles_per_sec = pwm_renesas_ra_get_cycles_per_sec, + .set_cycles = pwm_renesas_ra_set_cycles, +#ifdef CONFIG_PWM_CAPTURE + .configure_capture = pwm_renesas_ra_configure_capture, + .enable_capture = pwm_renesas_ra_enable_capture, + .disable_capture = pwm_renesas_ra_disable_capture, +#endif /* CONFIG_PWM_CAPTURE */ +}; + +static int pwm_renesas_ra_init(const struct device *dev) +{ + struct pwm_renesas_ra_data *data = dev->data; + const struct pwm_renesas_ra_config *cfg = dev->config; + int err; + + if (!device_is_ready(cfg->clock_dev)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + + err = clock_control_on(cfg->clock_dev, (clock_control_subsys_t)&cfg->clock_subsys); + if (err < 0) { + LOG_ERR("Could not initialize clock (%d)", err); + return err; + } + + err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + LOG_ERR("Failed to configure pins for PWM (%d)", err); + return err; + } + +#if defined(CONFIG_PWM_CAPTURE) + data->fsp_cfg.p_callback = fsp_callback; + data->fsp_cfg.p_context = dev; +#endif /* defined(CONFIG_PWM_CAPTURE) */ + + data->fsp_cfg.p_extend = &data->extend_cfg; + + err = R_GPT_Open(&data->fsp_ctrl, &data->fsp_cfg); + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +#define _ELC_EVENT_GPT_CAPTURE_COMPARE_A(channel) ELC_EVENT_GPT##channel##_CAPTURE_COMPARE_A +#define _ELC_EVENT_GPT_COUNTER_OVERFLOW(channel) ELC_EVENT_GPT##channel##_COUNTER_OVERFLOW + +#define ELC_EVENT_GPT_CAPTURE_COMPARE_A(channel) _ELC_EVENT_GPT_CAPTURE_COMPARE_A(channel) +#define ELC_EVENT_GPT_COUNTER_OVERFLOW(channel) _ELC_EVENT_GPT_COUNTER_OVERFLOW(channel) + +#ifdef CONFIG_PWM_CAPTURE +#define PWM_RA_IRQ_CONFIG_INIT(index) \ + do { \ + \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, gtioca, irq), \ + DT_INST_IRQ_BY_NAME(index, gtioca, priority), \ + gpt_capture_compare_a_isr, NULL, 0); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, overflow, irq), \ + DT_INST_IRQ_BY_NAME(index, overflow, priority), \ + gpt_counter_overflow_isr, NULL, 0); \ + } while (0) + +#else +#define PWM_RA_IRQ_CONFIG_INIT(index) +#endif /* CONFIG_PWM_CAPTURE */ + +#define PWM_RA8_INIT(index) \ + PINCTRL_DT_INST_DEFINE(index); \ + static const gpt_extended_cfg_t g_timer1_extend_##index = { \ + .gtioca = \ + { \ + .output_enabled = false, \ + .stop_level = GPT_PIN_LEVEL_LOW, \ + }, \ + .gtiocb = \ + { \ + .output_enabled = false, \ + .stop_level = GPT_PIN_LEVEL_LOW, \ + }, \ + .start_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .stop_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .clear_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .count_up_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .count_down_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .capture_a_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .capture_b_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .capture_a_ipl = DT_INST_IRQ_BY_NAME(index, gtioca, priority), \ + .capture_b_ipl = BSP_IRQ_DISABLED, \ + .capture_a_irq = DT_INST_IRQ_BY_NAME(index, gtioca, irq), \ + .capture_b_irq = FSP_INVALID_VECTOR, \ + .capture_filter_gtioca = GPT_CAPTURE_FILTER_NONE, \ + .capture_filter_gtiocb = GPT_CAPTURE_FILTER_NONE, \ + .p_pwm_cfg = NULL, \ + .gtior_setting.gtior = (0x0U), \ + }; \ + static struct pwm_renesas_ra_data pwm_renesas_ra_data_##index = { \ + .fsp_cfg = \ + { \ + .mode = TIMER_MODE_PWM, \ + .source_div = DT_INST_PROP(index, divider), \ + .channel = DT_INST_PROP(index, channel), \ + .cycle_end_ipl = DT_INST_IRQ_BY_NAME(index, overflow, priority), \ + .cycle_end_irq = DT_INST_IRQ_BY_NAME(index, overflow, irq), \ + }, \ + .extend_cfg = g_timer1_extend_##index, \ + .capture_a_event = ELC_EVENT_GPT_CAPTURE_COMPARE_A(DT_INST_PROP(index, channel)), \ + .overflow_event = ELC_EVENT_GPT_COUNTER_OVERFLOW(DT_INST_PROP(index, channel)), \ + }; \ + static const struct pwm_renesas_ra_config pwm_renesas_ra_config_##index = { \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(index)), \ + .clock_subsys = { \ + .mstp = (uint32_t)DT_INST_CLOCKS_CELL_BY_IDX(index, 0, mstp), \ + .stop_bit = DT_INST_CLOCKS_CELL_BY_IDX(index, 0, stop_bit), \ + }}; \ + static int pwm_renesas_ra_init_##index(const struct device *dev) \ + { \ + PWM_RA_IRQ_CONFIG_INIT(index); \ + int err = pwm_renesas_ra_init(dev); \ + if (err != 0) { \ + return err; \ + } \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(index, pwm_renesas_ra_init_##index, NULL, \ + &pwm_renesas_ra_data_##index, &pwm_renesas_ra_config_##index, \ + POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, &pwm_renesas_ra_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_RA8_INIT); diff --git a/drivers/pwm/pwm_renesas_ra8.c b/drivers/pwm/pwm_renesas_ra8.c deleted file mode 100644 index cb41ae82a1eae..0000000000000 --- a/drivers/pwm/pwm_renesas_ra8.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include -#include -#include -#include -#include "r_gpt.h" -#include "r_gpt_cfg.h" -#include -#include - -LOG_MODULE_REGISTER(pwm_renesas_ra8, CONFIG_PWM_LOG_LEVEL); - -#define DT_DRV_COMPAT renesas_ra8_pwm - -#define MAX_PIN 2U -#define GPT_PRV_GTIO_HIGH_COMPARE_MATCH_LOW_CYCLE_END 0x6U -#define GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END 0x9U -#define GPT_PRV_GTIOR_INITIAL_LEVEL_BIT 4 -#define GPT_PRV_GTIO_TOGGLE_COMPARE_MATCH 0x3U - -struct pwm_ra8_capture_data { - pwm_capture_callback_handler_t callback; - void *user_data; - uint64_t period; - uint64_t pulse; - bool is_pulse_capture; - bool is_busy; - uint32_t overflows; - bool continuous; -}; - -struct pwm_ra8_data { - gpt_instance_ctrl_t fsp_ctrl; - timer_cfg_t fsp_cfg; - gpt_extended_cfg_t extend_cfg; - uint16_t capture_a_event; - uint16_t overflow_event; - -#ifdef CONFIG_PWM_CAPTURE - struct pwm_ra8_capture_data capture; -#endif /* CONFIG_PWM_CAPTURE */ -}; - -struct pwm_ra8_config { - const struct device *clock_dev; - struct clock_control_ra_subsys_cfg clock_subsys; - const struct pinctrl_dev_config *pincfg; -}; - -static uint32_t pwm_ra8_gtior_calculate(gpt_pin_level_t const stop_level) -{ - /* The stop level is used as both the initial level and the stop level. */ - uint32_t gtior = R_GPT0_GTIOR_OAE_Msk | ((uint32_t)stop_level << R_GPT0_GTIOR_OADFLT_Pos) | - ((uint32_t)stop_level << GPT_PRV_GTIOR_INITIAL_LEVEL_BIT); - - uint32_t gtion = GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END; - - /* Calculate the gtior value for PWM mode only */ - gtior |= gtion; - - return gtior; -} - -static int pwm_ra8_apply_gtior_config(gpt_instance_ctrl_t *const p_ctrl, - timer_cfg_t const *const p_cfg) -{ - gpt_extended_cfg_t *p_extend = (gpt_extended_cfg_t *)p_cfg->p_extend; - uint32_t gtior = p_extend->gtior_setting.gtior; - -#if GPT_CFG_OUTPUT_SUPPORT_ENABLE - - /* Check if custom GTIOR settings are provided. */ - if (p_extend->gtior_setting.gtior == 0) { - /* If custom GTIOR settings are not provided, calculate GTIOR. */ - if (p_extend->gtioca.output_enabled) { - uint32_t gtioca_gtior = - pwm_ra8_gtior_calculate(p_extend->gtioca.stop_level); - - gtior |= gtioca_gtior << R_GPT0_GTIOR_GTIOA_Pos; - } - - if (p_extend->gtiocb.output_enabled) { - uint32_t gtiocb_gtior = - pwm_ra8_gtior_calculate(p_extend->gtiocb.stop_level); - - gtior |= gtiocb_gtior << R_GPT0_GTIOR_GTIOB_Pos; - } - } -#endif - -#if GPT_PRV_EXTRA_FEATURES_ENABLED == GPT_CFG_OUTPUT_SUPPORT_ENABLE - gpt_extended_pwm_cfg_t const *p_pwm_cfg = p_extend->p_pwm_cfg; - - if (NULL != p_pwm_cfg) { - /* Check if custom GTIOR settings are provided. */ - if (p_extend->gtior_setting.gtior == 0) { - /* If custom GTIOR settings are not provided, set gtioca_disable_settings - * and gtiocb_disable_settings. - */ - gtior |= (uint32_t)(p_pwm_cfg->gtioca_disable_setting - << R_GPT0_GTIOR_OADF_Pos); - gtior |= (uint32_t)(p_pwm_cfg->gtiocb_disable_setting - << R_GPT0_GTIOR_OBDF_Pos); - } - } -#endif - - /* Check if custom GTIOR settings are provided. */ - if (p_extend->gtior_setting.gtior == 0) { - /* - * If custom GTIOR settings are not provided, configure the noise filter for - * the GTIOC pins. - */ - gtior |= (uint32_t)(p_extend->capture_filter_gtioca << R_GPT0_GTIOR_NFAEN_Pos); - gtior |= (uint32_t)(p_extend->capture_filter_gtiocb << R_GPT0_GTIOR_NFBEN_Pos); - } - - /* Set the I/O control register. */ - p_ctrl->p_reg->GTIOR = gtior; - - return 0; -} - -static int pwm_ra8_set_cycles(const struct device *dev, uint32_t pin, uint32_t period_cycles, - uint32_t pulse_cycles, pwm_flags_t flags) -{ - struct pwm_ra8_data *data = dev->data; - uint32_t pulse; - fsp_err_t err; - - if (pin >= MAX_PIN) { - LOG_ERR("Only valid for gtioca and gtiocb pins"); - return -EINVAL; - } - - if ((data->fsp_ctrl.variant == TIMER_VARIANT_16_BIT && period_cycles > UINT16_MAX) || - (data->fsp_ctrl.variant == TIMER_VARIANT_32_BIT && period_cycles > UINT32_MAX)) { - LOG_ERR("Out of range period cycles are not valid"); - return -EINVAL; - } - - /* gtioca and gtiocb setting */ - if (pin == GPT_IO_PIN_GTIOCA) { - data->extend_cfg.gtioca.output_enabled = true; - } else { - data->extend_cfg.gtiocb.output_enabled = true; - } - - pulse = (flags & PWM_POLARITY_INVERTED) ? period_cycles - pulse_cycles : pulse_cycles; - - /* Apply gtio output setting */ - pwm_ra8_apply_gtior_config(&data->fsp_ctrl, &data->fsp_cfg); - - /* Stop timer */ - err = R_GPT_Stop(&data->fsp_ctrl); - if (err != FSP_SUCCESS) { - return -EIO; - } - - /* Update period cycles, reflected at an overflow */ - err = R_GPT_PeriodSet(&data->fsp_ctrl, period_cycles); - if (err != FSP_SUCCESS) { - return -EIO; - } - - /* Update pulse cycles, reflected at an overflow */ - err = R_GPT_DutyCycleSet(&data->fsp_ctrl, pulse, pin); - if (err != FSP_SUCCESS) { - return -EIO; - } - - /* Start timer */ - err = R_GPT_Start(&data->fsp_ctrl); - if (err != FSP_SUCCESS) { - return -EIO; - } - - LOG_DBG("channel %u, pin %u, pulse %u, period %u, prescaler: %u.", data->fsp_cfg.channel, - pin, pulse_cycles, period_cycles, data->fsp_cfg.source_div); - - return 0; -}; - -static int pwm_ra8_get_cycles_per_sec(const struct device *dev, uint32_t pin, uint64_t *cycles) -{ - struct pwm_ra8_data *data = dev->data; - timer_info_t info; - fsp_err_t err; - - if (pin >= MAX_PIN) { - LOG_ERR("Only valid for gtioca and gtiocb pins"); - return -EINVAL; - } - - err = R_GPT_InfoGet(&data->fsp_ctrl, &info); - if (err != FSP_SUCCESS) { - return -EIO; - } - *cycles = (uint64_t)info.clock_frequency; - - return 0; -}; - -#ifdef CONFIG_PWM_CAPTURE -extern void gpt_capture_compare_a_isr(void); -extern void gpt_counter_overflow_isr(void); - -static void enable_irq(IRQn_Type const irq, uint32_t priority, void *p_context) -{ - if (irq >= 0) { - R_BSP_IrqCfgEnable(irq, priority, p_context); - } -} -static void disable_irq(IRQn_Type irq) -{ - /* Disable interrupts. */ - if (irq >= 0) { - R_BSP_IrqDisable(irq); - R_FSP_IsrContextSet(irq, NULL); - } -} - -static int pwm_ra8_configure_capture(const struct device *dev, uint32_t pin, pwm_flags_t flags, - pwm_capture_callback_handler_t cb, void *user_data) -{ - struct pwm_ra8_data *data = dev->data; - - if (pin != GPT_IO_PIN_GTIOCA) { - LOG_ERR("Feature only support for gtioca"); - return -EINVAL; - } - if (!(flags & PWM_CAPTURE_TYPE_MASK)) { - LOG_ERR("No PWWM capture type specified"); - return -EINVAL; - } - if ((flags & PWM_CAPTURE_TYPE_MASK) == PWM_CAPTURE_TYPE_BOTH) { - LOG_ERR("Cannot capture both period and pulse width"); - return -ENOTSUP; - } - if (data->capture.is_busy) { - LOG_ERR("Capture already active on this pin"); - return -EBUSY; - } - - if (flags & PWM_CAPTURE_TYPE_PERIOD) { - data->capture.is_pulse_capture = false; - - if (flags & PWM_POLARITY_INVERTED) { - data->extend_cfg.start_source = - (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | - GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | - GPT_SOURCE_NONE); - data->extend_cfg.capture_a_source = data->extend_cfg.start_source; - - } else { - data->extend_cfg.start_source = - (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | - GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | - GPT_SOURCE_NONE); - data->extend_cfg.capture_a_source = data->extend_cfg.start_source; - } - } else { - data->capture.is_pulse_capture = true; - - if (flags & PWM_POLARITY_INVERTED) { - data->extend_cfg.start_source = - (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | - GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | - GPT_SOURCE_NONE); - - data->extend_cfg.capture_a_source = - (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | - GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | - GPT_SOURCE_NONE); - } else { - data->extend_cfg.start_source = - (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | - GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | - GPT_SOURCE_NONE); - - data->extend_cfg.capture_a_source = - (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | - GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | - GPT_SOURCE_NONE); - } - } - - data->capture.callback = cb; - data->capture.user_data = user_data; - data->capture.continuous = flags & PWM_CAPTURE_MODE_CONTINUOUS; - - if (data->capture.continuous) { - data->extend_cfg.stop_source = data->extend_cfg.capture_a_source; - data->extend_cfg.clear_source = data->extend_cfg.start_source; - } else { - data->extend_cfg.stop_source = (gpt_source_t)(GPT_SOURCE_NONE); - data->extend_cfg.clear_source = (gpt_source_t)(GPT_SOURCE_NONE); - } - - return 0; -} - -static int pwm_ra8_enable_capture(const struct device *dev, uint32_t pin) -{ - struct pwm_ra8_data *data = dev->data; - fsp_err_t err; - - if (pin != GPT_IO_PIN_GTIOCA) { - LOG_ERR("Feature only support for gtioca"); - return -EINVAL; - } - - if (data->capture.is_busy) { - LOG_ERR("Capture already active on this pin"); - return -EBUSY; - } - - if (!data->capture.callback) { - LOG_ERR("PWM capture not configured"); - return -EINVAL; - } - - data->capture.is_busy = true; - - /* Enable capture source */ - err = R_GPT_Enable(&data->fsp_ctrl); - if (err != FSP_SUCCESS) { - return -EIO; - } - - /* Enable interruption */ - enable_irq(data->fsp_cfg.cycle_end_irq, data->fsp_cfg.cycle_end_irq, &data->fsp_ctrl); - enable_irq(data->extend_cfg.capture_a_irq, data->extend_cfg.capture_a_ipl, &data->fsp_ctrl); - - R_ICU->IELSR[data->fsp_cfg.cycle_end_irq] = (elc_event_t)data->overflow_event; - R_ICU->IELSR[data->extend_cfg.capture_a_irq] = (elc_event_t)data->capture_a_event; - - return 0; -} - -static int pwm_ra8_disable_capture(const struct device *dev, uint32_t pin) -{ - struct pwm_ra8_data *data = dev->data; - fsp_err_t err; - - if (pin != GPT_IO_PIN_GTIOCA) { - LOG_ERR("Feature only support for gtioca"); - return -EINVAL; - } - data->capture.is_busy = false; - - /* Disable interruption */ - disable_irq(data->fsp_cfg.cycle_end_irq); - disable_irq(data->extend_cfg.capture_a_irq); - - R_ICU->IELSR[data->fsp_cfg.cycle_end_irq] = (elc_event_t)ELC_EVENT_NONE; - R_ICU->IELSR[data->extend_cfg.capture_a_irq] = (elc_event_t)ELC_EVENT_NONE; - - /* Disable capture source */ - err = R_GPT_Disable(&data->fsp_ctrl); - if (err != FSP_SUCCESS) { - return -EIO; - } - - /* Stop timer */ - err = R_GPT_Stop(&data->fsp_ctrl); - if (err != FSP_SUCCESS) { - return -EIO; - } - - /* Clear timer */ - err = R_GPT_Reset(&data->fsp_ctrl); - if (err != FSP_SUCCESS) { - return -EIO; - } - - return 0; -} - -static void fsp_callback(timer_callback_args_t *p_args) -{ - const struct device *dev = p_args->p_context; - struct pwm_ra8_data *data = dev->data; - timer_info_t info; - - (void)R_GPT_InfoGet(&data->fsp_ctrl, &info); - - uint64_t period = info.period_counts; - - /* The maximum period is one more than the maximum 16,32-bit number, but will be reflected - * as 0 - */ - if (period == 0U) { - if (data->fsp_ctrl.variant == TIMER_VARIANT_16_BIT) { - period = UINT16_MAX + 1U; - } else { - period = UINT32_MAX + 1U; - } - } - - /* Capture event */ - if (p_args->event == TIMER_EVENT_CAPTURE_A) { - if (p_args->capture != 0U) { - if (data->capture.is_pulse_capture == true) { - data->capture.pulse = - (data->capture.overflows * period) + p_args->capture; - data->capture.callback(dev, GPT_IO_PIN_GTIOCA, 0, - data->capture.pulse, 0, - data->capture.user_data); - } else { - data->capture.period = - (data->capture.overflows * period) + p_args->capture; - data->capture.callback(dev, GPT_IO_PIN_GTIOCA, data->capture.period, - 0, 0, data->capture.user_data); - } - data->capture.overflows = 0U; - /* Disable capture in single mode */ - if (data->capture.continuous == false) { - pwm_ra8_disable_capture(dev, GPT_IO_PIN_GTIOCA); - } - } - } else if (p_args->event == TIMER_EVENT_CYCLE_END) { - data->capture.overflows++; - } else { - data->capture.callback(dev, GPT_IO_PIN_GTIOCA, 0, 0, -ECANCELED, - data->capture.user_data); - } -} - -#endif /* CONFIG_PWM_CAPTURE */ - -static const struct pwm_driver_api pwm_ra8_driver_api = { - .get_cycles_per_sec = pwm_ra8_get_cycles_per_sec, - .set_cycles = pwm_ra8_set_cycles, -#ifdef CONFIG_PWM_CAPTURE - .configure_capture = pwm_ra8_configure_capture, - .enable_capture = pwm_ra8_enable_capture, - .disable_capture = pwm_ra8_disable_capture, -#endif /* CONFIG_PWM_CAPTURE */ -}; - -static int pwm_ra8_init(const struct device *dev) -{ - struct pwm_ra8_data *data = dev->data; - const struct pwm_ra8_config *cfg = dev->config; - int err; - - if (!device_is_ready(cfg->clock_dev)) { - LOG_ERR("clock control device not ready"); - return -ENODEV; - } - - err = clock_control_on(cfg->clock_dev, (clock_control_subsys_t)&cfg->clock_subsys); - if (err < 0) { - LOG_ERR("Could not initialize clock (%d)", err); - return err; - } - - err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); - if (err) { - LOG_ERR("Failed to configure pins for PWM (%d)", err); - return err; - } - -#if defined(CONFIG_PWM_CAPTURE) - data->fsp_cfg.p_callback = fsp_callback; - data->fsp_cfg.p_context = dev; -#endif /* defined(CONFIG_PWM_CAPTURE) */ - - data->fsp_cfg.p_extend = &data->extend_cfg; - - err = R_GPT_Open(&data->fsp_ctrl, &data->fsp_cfg); - if (err != FSP_SUCCESS) { - return -EIO; - } - - return 0; -} - -#define _ELC_EVENT_GPT_CAPTURE_COMPARE_A(channel) ELC_EVENT_GPT##channel##_CAPTURE_COMPARE_A -#define _ELC_EVENT_GPT_COUNTER_OVERFLOW(channel) ELC_EVENT_GPT##channel##_COUNTER_OVERFLOW - -#define ELC_EVENT_GPT_CAPTURE_COMPARE_A(channel) _ELC_EVENT_GPT_CAPTURE_COMPARE_A(channel) -#define ELC_EVENT_GPT_COUNTER_OVERFLOW(channel) _ELC_EVENT_GPT_COUNTER_OVERFLOW(channel) - -#ifdef CONFIG_PWM_CAPTURE -#define PWM_RA_IRQ_CONFIG_INIT(index) \ - do { \ - \ - IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, gtioca, irq), \ - DT_INST_IRQ_BY_NAME(index, gtioca, priority), \ - gpt_capture_compare_a_isr, NULL, 0); \ - IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, overflow, irq), \ - DT_INST_IRQ_BY_NAME(index, overflow, priority), \ - gpt_counter_overflow_isr, NULL, 0); \ - } while (0) - -#else -#define PWM_RA_IRQ_CONFIG_INIT(index) -#endif /* CONFIG_PWM_CAPTURE */ - -#define PWM_RA8_INIT(index) \ - PINCTRL_DT_INST_DEFINE(index); \ - static const gpt_extended_cfg_t g_timer1_extend_##index = { \ - .gtioca = \ - { \ - .output_enabled = false, \ - .stop_level = GPT_PIN_LEVEL_LOW, \ - }, \ - .gtiocb = \ - { \ - .output_enabled = false, \ - .stop_level = GPT_PIN_LEVEL_LOW, \ - }, \ - .start_source = (gpt_source_t)(GPT_SOURCE_NONE), \ - .stop_source = (gpt_source_t)(GPT_SOURCE_NONE), \ - .clear_source = (gpt_source_t)(GPT_SOURCE_NONE), \ - .count_up_source = (gpt_source_t)(GPT_SOURCE_NONE), \ - .count_down_source = (gpt_source_t)(GPT_SOURCE_NONE), \ - .capture_a_source = (gpt_source_t)(GPT_SOURCE_NONE), \ - .capture_b_source = (gpt_source_t)(GPT_SOURCE_NONE), \ - .capture_a_ipl = DT_INST_IRQ_BY_NAME(index, gtioca, priority), \ - .capture_b_ipl = BSP_IRQ_DISABLED, \ - .capture_a_irq = DT_INST_IRQ_BY_NAME(index, gtioca, irq), \ - .capture_b_irq = FSP_INVALID_VECTOR, \ - .capture_filter_gtioca = GPT_CAPTURE_FILTER_NONE, \ - .capture_filter_gtiocb = GPT_CAPTURE_FILTER_NONE, \ - .p_pwm_cfg = NULL, \ - .gtior_setting.gtior = (0x0U), \ - }; \ - static struct pwm_ra8_data pwm_ra8_data_##index = { \ - .fsp_cfg = \ - { \ - .mode = TIMER_MODE_PWM, \ - .source_div = DT_INST_PROP(index, divider), \ - .channel = DT_INST_PROP(index, channel), \ - .cycle_end_ipl = DT_INST_IRQ_BY_NAME(index, overflow, priority), \ - .cycle_end_irq = DT_INST_IRQ_BY_NAME(index, overflow, irq), \ - }, \ - .extend_cfg = g_timer1_extend_##index, \ - .capture_a_event = ELC_EVENT_GPT_CAPTURE_COMPARE_A(DT_INST_PROP(index, channel)), \ - .overflow_event = ELC_EVENT_GPT_COUNTER_OVERFLOW(DT_INST_PROP(index, channel)), \ - }; \ - static const struct pwm_ra8_config pwm_ra8_config_##index = { \ - .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ - .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(index)), \ - .clock_subsys = { \ - .mstp = (uint32_t)DT_INST_CLOCKS_CELL_BY_IDX(index, 0, mstp), \ - .stop_bit = DT_INST_CLOCKS_CELL_BY_IDX(index, 0, stop_bit), \ - }}; \ - static int pwm_ra8_init_##index(const struct device *dev) \ - { \ - PWM_RA_IRQ_CONFIG_INIT(index); \ - int err = pwm_ra8_init(dev); \ - if (err != 0) { \ - return err; \ - } \ - return 0; \ - } \ - DEVICE_DT_INST_DEFINE(index, pwm_ra8_init_##index, NULL, &pwm_ra8_data_##index, \ - &pwm_ra8_config_##index, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ - &pwm_ra8_driver_api); - -DT_INST_FOREACH_STATUS_OKAY(PWM_RA8_INIT); diff --git a/drivers/pwm/pwm_renesas_rz_gpt.c b/drivers/pwm/pwm_renesas_rz_gpt.c new file mode 100644 index 0000000000000..faae50c23a0b9 --- /dev/null +++ b/drivers/pwm/pwm_renesas_rz_gpt.c @@ -0,0 +1,664 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include "r_gpt.h" +#include "r_gpt_cfg.h" +#include + +LOG_MODULE_REGISTER(pwm_renesas_rz_gpt, CONFIG_PWM_LOG_LEVEL); + +#define DT_DRV_COMPAT renesas_rz_gpt_pwm + +#define GPT_PRV_GTIO_HIGH_COMPARE_MATCH_LOW_CYCLE_END 0x6U +#define GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END 0x9U +#define GPT_PRV_GTIOR_INITIAL_LEVEL_BIT 4 + +#define CAPTURE_BOTH_MODE_FIRST_EVENT_IS_CAPTURE_PULSE 1 +#define CAPTURE_BOTH_MODE_SECOND_EVENT_IS_CAPTURE_PERIOD 2 + +struct pwm_rz_gpt_capture_data { + pwm_capture_callback_handler_t callback; + void *user_data; + uint64_t period; + uint64_t pulse; + uint16_t capture_type_flag; + uint32_t capture_both_event_count; + bool is_busy; + uint32_t overflows; + bool continuous; + uint32_t capture_channel; +}; + +struct pwm_rz_gpt_data { + timer_cfg_t *fsp_cfg; + gpt_instance_ctrl_t *fsp_ctrl; +#ifdef CONFIG_PWM_CAPTURE + struct pwm_rz_gpt_capture_data capture; +#endif /* CONFIG_PWM_CAPTURE */ +}; + +struct pwm_rz_gpt_config { + const struct pinctrl_dev_config *pincfg; + const timer_api_t *fsp_api; +}; + +static uint32_t pwm_rz_gpt_gtior_calculate(gpt_pin_level_t const stop_level) +{ + /* The stop level is used as both the initial level and the stop level. */ + uint32_t gtior = R_GPT0_GTIOR_OAE_Msk | ((uint32_t)stop_level << R_GPT0_GTIOR_OADFLT_Pos) | + ((uint32_t)stop_level << GPT_PRV_GTIOR_INITIAL_LEVEL_BIT); + + uint32_t gtion = GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END; + + /* Calculate the gtior value for PWM mode only */ + gtior |= gtion; + + return gtior; +} + +static int pwm_rz_gpt_apply_gtior_config(gpt_instance_ctrl_t *const p_ctrl, + timer_cfg_t const *const p_cfg) +{ + gpt_extended_cfg_t *p_extend = (gpt_extended_cfg_t *)p_cfg->p_extend; + uint32_t gtior = p_extend->gtior_setting.gtior; + +#if GPT_CFG_OUTPUT_SUPPORT_ENABLE + /* Check if custom GTIOR settings are provided. */ + if (p_extend->gtior_setting.gtior == 0) { + /* If custom GTIOR settings are not provided, calculate GTIOR. */ + if (p_extend->gtioca.output_enabled) { + uint32_t gtioca_gtior = + pwm_rz_gpt_gtior_calculate(p_extend->gtioca.stop_level); + gtior |= gtioca_gtior << R_GPT0_GTIOR_GTIOA_Pos; + } + + if (p_extend->gtiocb.output_enabled) { + uint32_t gtiocb_gtior = + pwm_rz_gpt_gtior_calculate(p_extend->gtiocb.stop_level); + gtior |= gtiocb_gtior << R_GPT0_GTIOR_GTIOB_Pos; + } + } +#endif + + /* Check if custom GTIOR settings are provided. */ + if (p_extend->gtior_setting.gtior == 0) { + /* + * If custom GTIOR settings are not provided, configure the noise filter for + * the GTIOC pins. + */ + gtior |= (uint32_t)(p_extend->capture_filter_gtioca << R_GPT0_GTIOR_NFAEN_Pos); + gtior |= (uint32_t)(p_extend->capture_filter_gtiocb << R_GPT0_GTIOR_NFBEN_Pos); + } + + /* Set the I/O control register. */ + p_ctrl->p_reg->GTIOR = gtior; + + return 0; +} + +static int pwm_rz_gpt_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_cycles, + uint32_t pulse_cycles, pwm_flags_t flags) +{ + const struct pwm_rz_gpt_config *cfg = dev->config; + struct pwm_rz_gpt_data *data = dev->data; + gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend; + uint32_t pulse; + fsp_err_t err; + uint32_t pin; + + /* gtioca and gtiocb setting */ + if (channel == RZ_PWM_GPT_IO_A) { + pin = GPT_IO_PIN_GTIOCA; + fsp_cfg_extend->gtioca.output_enabled = true; + } else if (channel == RZ_PWM_GPT_IO_B) { + pin = GPT_IO_PIN_GTIOCB; + fsp_cfg_extend->gtiocb.output_enabled = true; + } else { + LOG_ERR("Valid only for RZ_PWM_GPT_IO_A and RZ_PWM_GPT_IO_B pins"); + return -EINVAL; + } + + if ((data->fsp_ctrl->variant == TIMER_VARIANT_16_BIT && period_cycles > UINT16_MAX) || + (data->fsp_ctrl->variant == TIMER_VARIANT_32_BIT && period_cycles > UINT32_MAX)) { + LOG_ERR("Out of range period cycles are not valid"); + return -EINVAL; + } + + pulse = (flags & PWM_POLARITY_INVERTED) ? period_cycles - pulse_cycles : pulse_cycles; + + /* Apply gtio output setting */ + pwm_rz_gpt_apply_gtior_config(data->fsp_ctrl, data->fsp_cfg); + + /* Stop timer */ + err = cfg->fsp_api->stop(data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Update period cycles, reflected at an overflow */ + err = cfg->fsp_api->periodSet(data->fsp_ctrl, period_cycles); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Update pulse cycles, reflected at an overflow */ + err = cfg->fsp_api->dutyCycleSet(data->fsp_ctrl, pulse, pin); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Start timer */ + err = cfg->fsp_api->start(data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +}; + +static int pwm_rz_gpt_get_cycles_per_sec(const struct device *dev, uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_rz_gpt_config *cfg = dev->config; + struct pwm_rz_gpt_data *data = dev->data; + timer_info_t info; + fsp_err_t err; + + if (!(channel == RZ_PWM_GPT_IO_A || channel == RZ_PWM_GPT_IO_B)) { + LOG_ERR("Valid only for RZ_PWM_GPT_IO_A and RZ_PWM_GPT_IO_B pins"); + return -EINVAL; + } + + err = cfg->fsp_api->infoGet(data->fsp_ctrl, &info); + if (err != FSP_SUCCESS) { + return -EIO; + } + *cycles = (uint64_t)info.clock_frequency; + + return 0; +}; + +extern void gpt_capture_a_isr(void); +extern void gpt_capture_b_isr(void); +extern void gpt_counter_overflow_isr(void); + +#ifdef CONFIG_PWM_CAPTURE + +static int pwm_rz_gpt_configure_capture(const struct device *dev, uint32_t channel, + pwm_flags_t flags, pwm_capture_callback_handler_t cb, + void *user_data) +{ + struct pwm_rz_gpt_data *data = dev->data; + gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend; + + if (!(flags & PWM_CAPTURE_TYPE_MASK)) { + LOG_ERR("No PWWM capture type specified"); + return -EINVAL; + } + data->capture.capture_type_flag = flags & PWM_CAPTURE_TYPE_MASK; + data->capture.capture_channel = channel; + if (data->capture.is_busy) { + LOG_ERR("Capture already active on this pin"); + return -EBUSY; + } + if (channel == RZ_PWM_GPT_IO_A) { + if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) { + data->capture.capture_both_event_count = 0; + if (flags & PWM_POLARITY_INVERTED) { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + } else { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + } + fsp_cfg_extend->capture_a_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + } else if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_PERIOD) { + if (flags & PWM_POLARITY_INVERTED) { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + fsp_cfg_extend->capture_a_source = fsp_cfg_extend->start_source; + } else { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + fsp_cfg_extend->capture_a_source = fsp_cfg_extend->start_source; + } + } else { + if (flags & PWM_POLARITY_INVERTED) { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + fsp_cfg_extend->capture_a_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + } else { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + fsp_cfg_extend->capture_a_source = + (gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW | + GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH | + GPT_SOURCE_NONE); + } + } + } else if (channel == RZ_PWM_GPT_IO_B) { + if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) { + data->capture.capture_both_event_count = 0; + if (flags & PWM_POLARITY_INVERTED) { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + } else { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + } + fsp_cfg_extend->capture_b_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + } else if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_PERIOD) { + if (flags & PWM_POLARITY_INVERTED) { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + fsp_cfg_extend->capture_b_source = fsp_cfg_extend->start_source; + } else { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + fsp_cfg_extend->capture_b_source = fsp_cfg_extend->start_source; + } + } else { + if (flags & PWM_POLARITY_INVERTED) { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + fsp_cfg_extend->capture_b_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + } else { + fsp_cfg_extend->start_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + fsp_cfg_extend->capture_b_source = + (gpt_source_t)(GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW | + GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH | + GPT_SOURCE_NONE); + } + } + } + + data->capture.callback = cb; + data->capture.user_data = user_data; + data->capture.continuous = flags & PWM_CAPTURE_MODE_CONTINUOUS; + if (data->capture.continuous) { + if (channel == RZ_PWM_GPT_IO_A) { + fsp_cfg_extend->stop_source = fsp_cfg_extend->capture_a_source; + } else if (channel == RZ_PWM_GPT_IO_B) { + fsp_cfg_extend->stop_source = fsp_cfg_extend->capture_b_source; + } + fsp_cfg_extend->clear_source = fsp_cfg_extend->start_source; + } + + else { + fsp_cfg_extend->stop_source = (gpt_source_t)(GPT_SOURCE_NONE); + fsp_cfg_extend->clear_source = (gpt_source_t)(GPT_SOURCE_NONE); + } + + return 0; +} + +static int pwm_rz_gpt_enable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_rz_gpt_config *cfg = dev->config; + struct pwm_rz_gpt_data *data = dev->data; + gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend; + fsp_err_t err; + + data->capture.capture_channel = channel; + + if (data->capture.is_busy) { + LOG_ERR("Capture already active on this pin"); + return -EBUSY; + } + + if (!data->capture.callback) { + LOG_ERR("PWM capture not configured"); + return -EINVAL; + } + + data->capture.is_busy = true; + + /* Enable capture source */ + err = cfg->fsp_api->enable(data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Enable interruption */ + irq_enable(data->fsp_cfg->cycle_end_irq); + if (channel == RZ_PWM_GPT_IO_A) { + irq_enable(fsp_cfg_extend->capture_a_irq); + } else if (channel == RZ_PWM_GPT_IO_B) { + irq_enable(fsp_cfg_extend->capture_b_irq); + } + + return 0; +} + +static int pwm_rz_gpt_disable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_rz_gpt_config *cfg = dev->config; + struct pwm_rz_gpt_data *data = dev->data; + fsp_err_t err; + gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend; + + data->capture.capture_channel = channel; + data->capture.is_busy = false; + + /* Disable interruption */ + irq_disable(data->fsp_cfg->cycle_end_irq); + if (channel == RZ_PWM_GPT_IO_A) { + irq_disable(fsp_cfg_extend->capture_a_irq); + } else if (channel == RZ_PWM_GPT_IO_B) { + irq_disable(fsp_cfg_extend->capture_b_irq); + } + + /* Disable capture source */ + err = cfg->fsp_api->disable(data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Stop timer */ + err = cfg->fsp_api->stop(data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + /* Clear timer */ + err = cfg->fsp_api->reset(data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +static void fsp_callback(timer_callback_args_t *p_args) +{ + const struct device *dev = p_args->p_context; + const struct pwm_rz_gpt_config *cfg = dev->config; + struct pwm_rz_gpt_data *data = dev->data; + timer_info_t info; + + (void)cfg->fsp_api->infoGet(data->fsp_ctrl, &info); + + uint64_t period = info.period_counts; + + /* The maximum period is one more than the maximum 16,32-bit number, but will be reflected + * as 0 + */ + if (period == 0U) { + if (data->fsp_ctrl->variant == TIMER_VARIANT_16_BIT) { + period = UINT16_MAX + 1U; + } else { + period = UINT32_MAX + 1U; + } + } + + /* Capture event */ + if (p_args->event == TIMER_EVENT_CAPTURE_A) { + if (p_args->capture != 0U) { + bool check_disable_capture = false; + + if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) { + data->capture.capture_both_event_count++; + if (data->capture.capture_both_event_count == + CAPTURE_BOTH_MODE_FIRST_EVENT_IS_CAPTURE_PULSE) { + data->capture.pulse = (data->capture.overflows * period) + + p_args->capture; + } + if (data->capture.capture_both_event_count == + CAPTURE_BOTH_MODE_SECOND_EVENT_IS_CAPTURE_PERIOD) { + data->capture.capture_both_event_count = 0; + data->capture.period = (data->capture.overflows * period) + + p_args->capture; + data->capture.callback( + dev, GPT_IO_PIN_GTIOCA, data->capture.period, + data->capture.pulse, 0, data->capture.user_data); + + check_disable_capture = true; + } + } else if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_PULSE) { + data->capture.pulse = + (data->capture.overflows * period) + p_args->capture; + data->capture.callback(dev, GPT_IO_PIN_GTIOCA, 0, + data->capture.pulse, 0, + data->capture.user_data); + + check_disable_capture = true; + } else { + data->capture.period = + (data->capture.overflows * period) + p_args->capture; + data->capture.callback(dev, GPT_IO_PIN_GTIOCA, data->capture.period, + 0, 0, data->capture.user_data); + + check_disable_capture = true; + } + if (check_disable_capture) { + data->capture.overflows = 0U; + /* Disable capture in single mode */ + if (data->capture.continuous == false) { + pwm_rz_gpt_disable_capture(dev, GPT_IO_PIN_GTIOCA); + } + } + } + } else if (p_args->event == TIMER_EVENT_CAPTURE_B) { + if (p_args->capture != 0U) { + bool check_disable_capture = false; + + if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) { + data->capture.capture_both_event_count++; + if (data->capture.capture_both_event_count == + CAPTURE_BOTH_MODE_FIRST_EVENT_IS_CAPTURE_PULSE) { + data->capture.pulse = (data->capture.overflows * period) + + p_args->capture; + } + if (data->capture.capture_both_event_count == + CAPTURE_BOTH_MODE_SECOND_EVENT_IS_CAPTURE_PERIOD) { + data->capture.capture_both_event_count = 0; + data->capture.period = (data->capture.overflows * period) + + p_args->capture; + data->capture.callback( + dev, GPT_IO_PIN_GTIOCB, data->capture.period, + data->capture.pulse, 0, data->capture.user_data); + + check_disable_capture = true; + } + } else if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_PULSE) { + data->capture.pulse = + (data->capture.overflows * period) + p_args->capture; + data->capture.callback(dev, GPT_IO_PIN_GTIOCB, 0, + data->capture.pulse, 0, + data->capture.user_data); + + check_disable_capture = true; + } else { + data->capture.period = + (data->capture.overflows * period) + p_args->capture; + data->capture.callback(dev, GPT_IO_PIN_GTIOCB, data->capture.period, + 0, 0, data->capture.user_data); + + check_disable_capture = true; + } + if (check_disable_capture) { + data->capture.overflows = 0U; + /* Disable capture in single mode */ + if (data->capture.continuous == false) { + pwm_rz_gpt_disable_capture(dev, GPT_IO_PIN_GTIOCB); + } + } + } + } else if (p_args->event == TIMER_EVENT_CYCLE_END) { + data->capture.overflows++; + } else { + if (data->capture.capture_channel == RZ_PWM_GPT_IO_A) { + data->capture.callback(dev, GPT_IO_PIN_GTIOCA, 0, 0, -ECANCELED, + data->capture.user_data); + } else if (data->capture.capture_channel == RZ_PWM_GPT_IO_B) { + data->capture.callback(dev, GPT_IO_PIN_GTIOCB, 0, 0, -ECANCELED, + data->capture.user_data); + } + } +} + +#endif /* CONFIG_PWM_CAPTURE */ + +static DEVICE_API(pwm, pwm_rz_gpt_driver_api) = { + .get_cycles_per_sec = pwm_rz_gpt_get_cycles_per_sec, + .set_cycles = pwm_rz_gpt_set_cycles, +#ifdef CONFIG_PWM_CAPTURE + .configure_capture = pwm_rz_gpt_configure_capture, + .enable_capture = pwm_rz_gpt_enable_capture, + .disable_capture = pwm_rz_gpt_disable_capture, +#endif /* CONFIG_PWM_CAPTURE */ +}; + +static int pwm_rz_gpt_init(const struct device *dev) +{ + const struct pwm_rz_gpt_config *cfg = dev->config; + struct pwm_rz_gpt_data *data = dev->data; + gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend; + int err; + + err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + LOG_ERR("Failed to configure pins for PWM (%d)", err); + return err; + } + +#if defined(CONFIG_PWM_CAPTURE) + data->fsp_cfg->p_callback = fsp_callback; + data->fsp_cfg->p_context = dev; +#endif /* defined(CONFIG_PWM_CAPTURE) */ + + err = cfg->fsp_api->open(data->fsp_ctrl, data->fsp_cfg); + if (err != FSP_SUCCESS) { + return -EIO; + } + + irq_disable(data->fsp_cfg->cycle_end_irq); + irq_disable(fsp_cfg_extend->capture_a_irq); + irq_disable(fsp_cfg_extend->capture_b_irq); + + return 0; +} + +#define GPT(idx) DT_INST_PARENT(idx) + +#define PWM_RZ_IRQ_CONFIG_INIT(inst) \ + do { \ + IRQ_CONNECT(DT_IRQ_BY_NAME(GPT(inst), ccmpa, irq), \ + DT_IRQ_BY_NAME(GPT(inst), ccmpa, priority), gpt_capture_a_isr, NULL, \ + 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(GPT(inst), ccmpb, irq), \ + DT_IRQ_BY_NAME(GPT(inst), ccmpb, priority), gpt_capture_b_isr, NULL, \ + 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(GPT(inst), ovf, irq), \ + DT_IRQ_BY_NAME(GPT(inst), ovf, priority), gpt_counter_overflow_isr, \ + NULL, 0); \ + } while (0) + +#define PWM_RZG_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + static gpt_instance_ctrl_t g_timer##inst##_ctrl; \ + static gpt_extended_cfg_t g_timer##inst##_extend = { \ + .gtioca = \ + { \ + .output_enabled = false, \ + .stop_level = GPT_PIN_LEVEL_LOW, \ + }, \ + .gtiocb = \ + { \ + .output_enabled = false, \ + .stop_level = GPT_PIN_LEVEL_LOW, \ + }, \ + .start_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .stop_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .clear_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .count_up_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .count_down_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .capture_a_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .capture_b_source = (gpt_source_t)(GPT_SOURCE_NONE), \ + .capture_a_ipl = DT_IRQ_BY_NAME(GPT(inst), ccmpa, priority), \ + .capture_b_ipl = DT_IRQ_BY_NAME(GPT(inst), ccmpb, priority), \ + .capture_a_irq = DT_IRQ_BY_NAME(GPT(inst), ccmpa, irq), \ + .capture_b_irq = DT_IRQ_BY_NAME(GPT(inst), ccmpb, irq), \ + .capture_filter_gtioca = GPT_CAPTURE_FILTER_NONE, \ + .capture_filter_gtiocb = GPT_CAPTURE_FILTER_NONE, \ + .p_pwm_cfg = NULL, \ + .gtior_setting.gtior = (0x0U), \ + }; \ + static timer_cfg_t g_timer##inst##_cfg = { \ + .mode = TIMER_MODE_PWM, \ + .channel = DT_PROP(GPT(inst), channel), \ + .source_div = DT_ENUM_IDX(GPT(inst), prescaler), \ + .cycle_end_ipl = DT_IRQ_BY_NAME(GPT(inst), ovf, priority), \ + .cycle_end_irq = DT_IRQ_BY_NAME(GPT(inst), ovf, irq), \ + .p_extend = &g_timer##inst##_extend, \ + }; \ + static const struct pwm_rz_gpt_config pwm_rz_gpt_config_##inst = { \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .fsp_api = &g_timer_on_gpt, \ + }; \ + static struct pwm_rz_gpt_data pwm_rz_gpt_data_##inst = { \ + .fsp_cfg = &g_timer##inst##_cfg, .fsp_ctrl = &g_timer##inst##_ctrl}; \ + static int pwm_rz_gpt_init_##inst(const struct device *dev) \ + { \ + PWM_RZ_IRQ_CONFIG_INIT(inst); \ + int err = pwm_rz_gpt_init(dev); \ + if (err != 0) { \ + return err; \ + } \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(inst, pwm_rz_gpt_init_##inst, NULL, &pwm_rz_gpt_data_##inst, \ + &pwm_rz_gpt_config_##inst, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_rz_gpt_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_RZG_INIT); diff --git a/drivers/pwm/pwm_rpi_pico.c b/drivers/pwm/pwm_rpi_pico.c index a6b9489b4e45f..98fefe1aad630 100644 --- a/drivers/pwm/pwm_rpi_pico.c +++ b/drivers/pwm/pwm_rpi_pico.c @@ -146,7 +146,7 @@ static int pwm_rpi_set_cycles(const struct device *dev, uint32_t ch, uint32_t pe return 0; }; -struct pwm_driver_api pwm_rpi_driver_api = { +static DEVICE_API(pwm, pwm_rpi_driver_api) = { .get_cycles_per_sec = pwm_rpi_get_cycles_per_sec, .set_cycles = pwm_rpi_set_cycles, }; diff --git a/drivers/pwm/pwm_rv32m1_tpm.c b/drivers/pwm/pwm_rv32m1_tpm.c index 3d2f5a5465335..dddc914a31d5d 100644 --- a/drivers/pwm/pwm_rv32m1_tpm.c +++ b/drivers/pwm/pwm_rv32m1_tpm.c @@ -178,7 +178,7 @@ static int rv32m1_tpm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api rv32m1_tpm_driver_api = { +static DEVICE_API(pwm, rv32m1_tpm_driver_api) = { .set_cycles = rv32m1_tpm_set_cycles, .get_cycles_per_sec = rv32m1_tpm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_sam.c b/drivers/pwm/pwm_sam.c index 672b2cdb8d05b..ed7b96ba9d4f9 100644 --- a/drivers/pwm/pwm_sam.c +++ b/drivers/pwm/pwm_sam.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Aurelien Jarno + * Copyright (c) 2021 Linaro Limited * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +12,6 @@ #include #include #include -#include #include @@ -22,6 +22,13 @@ LOG_MODULE_REGISTER(pwm_sam, CONFIG_PWM_LOG_LEVEL); #define PWMCHNUM_NUMBER PWMCH_NUM_NUMBER #endif +/* The SAMV71 HALs change the name of the field, so we need to + * define it this way to match how the other SoC variants name it + */ +#if defined(CONFIG_SOC_ATMEL_SAMV71) || defined(CONFIG_SOC_ATMEL_SAMV71_REVB) +#define PWM_CH_NUM PwmChNum +#endif + struct sam_pwm_config { Pwm *regs; const struct atmel_sam_pmc_config clock_cfg; @@ -118,7 +125,7 @@ static int sam_pwm_init(const struct device *dev) return 0; } -static const struct pwm_driver_api sam_pwm_driver_api = { +static DEVICE_API(pwm, sam_pwm_driver_api) = { .set_cycles = sam_pwm_set_cycles, .get_cycles_per_sec = sam_pwm_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_sam0_tc.c b/drivers/pwm/pwm_sam0_tc.c new file mode 100644 index 0000000000000..871a14ab8ec03 --- /dev/null +++ b/drivers/pwm/pwm_sam0_tc.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2024 Daikin Comfort Technologies North America, Inc. + * + * Heavily based on pwm_sam0_tcc.c, which is: + * Copyright (c) 2020 Google LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * PWM driver using the SAM0 Timer/Counter (TC) Supports the SAMD21 and SAMD5x series, + * 8 and 16 bit counter size is supported. + * + * The 8-bit counter operates in Normal PWM (NPWM) mode, it supports pulse width and period + * values between 0 and 255. It is ideal for applications requiring moderate frequency PWM, + * however, it is not suitable for high-precision or low-frequency applications. + * + * The 16-bit counter operates in Match PWM (MPWM) mode to generate the PWM signal. + * this mode sacrifices the timer's CC0 channel in order to achieve pulse width modulation. + */ + +#define DT_DRV_COMPAT atmel_sam0_tc_pwm + +#include +#include +#include +#include +#include +#include + +/* clang-format off */ + +/* Static configuration */ +struct pwm_sam0_config { + Tc *regs; + const struct pinctrl_dev_config *pcfg; + uint8_t channels; + uint8_t counter_size; + uint16_t prescaler; + uint32_t freq; + volatile uint32_t *mclk; + uint32_t mclk_mask; + uint32_t gclk_gen; + uint16_t gclk_id; +}; + +#define COUNTER_8BITS 8U + +/* Wait for the peripheral to finish all commands */ +static void wait_synchronization(Tc *regs, uint8_t counter_size) +{ + if (COUNTER_8BITS == counter_size) { + while (regs->COUNT8.SYNCBUSY.reg != 0) { + } + } else { + while (regs->COUNT16.SYNCBUSY.reg != 0) { + } + } +} + +static int pwm_sam0_get_cycles_per_sec(const struct device *dev, + uint32_t channel, uint64_t *cycles) +{ + const struct pwm_sam0_config *const cfg = dev->config; + + if (channel >= cfg->channels) { + return -EINVAL; + } + + *cycles = cfg->freq; + + return 0; +} + +static int pwm_sam0_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_cycles, + uint32_t pulse_cycles, pwm_flags_t flags) +{ + const struct pwm_sam0_config *const cfg = dev->config; + Tc *regs = cfg->regs; + uint8_t counter_size = cfg->counter_size; + uint32_t top = 1 << counter_size; + uint32_t invert_mask = 1 << channel; + bool invert = ((flags & PWM_POLARITY_INVERTED) != 0); + bool inverted; + + if (channel >= cfg->channels) { + return -EINVAL; + } + if (period_cycles >= top || pulse_cycles >= top) { + return -EINVAL; + } + + /* + * Update the buffered width and period. These will be automatically + * loaded on the next cycle. + */ + if (COUNTER_8BITS == counter_size) { + inverted = ((regs->COUNT8.DRVCTRL.vec.INVEN & invert_mask) != 0); + regs->COUNT8.CCBUF[channel].reg = TC_COUNT8_CCBUF_CCBUF(pulse_cycles); + regs->COUNT8.PERBUF.reg = TC_COUNT8_PERBUF_PERBUF(period_cycles); + wait_synchronization(regs, counter_size); + + if (invert != inverted) { + regs->COUNT8.CTRLA.bit.ENABLE = 0; + wait_synchronization(regs, counter_size); + + regs->COUNT8.DRVCTRL.vec.INVEN ^= invert_mask; + regs->COUNT8.CTRLA.bit.ENABLE = 1; + wait_synchronization(regs, counter_size); + } + } else { + inverted = ((regs->COUNT16.DRVCTRL.vec.INVEN & invert_mask) != 0); + regs->COUNT16.CCBUF[0].reg = TC_COUNT16_CCBUF_CCBUF(period_cycles); + regs->COUNT16.CCBUF[1].reg = TC_COUNT16_CCBUF_CCBUF(pulse_cycles); + wait_synchronization(regs, counter_size); + + if (invert != inverted) { + regs->COUNT16.CTRLA.bit.ENABLE = 0; + wait_synchronization(regs, counter_size); + + regs->COUNT16.DRVCTRL.vec.INVEN ^= invert_mask; + regs->COUNT16.CTRLA.bit.ENABLE = 1; + wait_synchronization(regs, counter_size); + } + } + + return 0; +} + +static int pwm_sam0_init(const struct device *dev) +{ + const struct pwm_sam0_config *const cfg = dev->config; + uint8_t counter_size = cfg->counter_size; + Tc *regs = cfg->regs; + int retval; + + *cfg->mclk |= cfg->mclk_mask; + +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); +#endif + + retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (retval < 0) { + return retval; + } + + if (COUNTER_8BITS == counter_size) { + regs->COUNT8.CTRLA.bit.SWRST = 1; + wait_synchronization(regs, counter_size); + + regs->COUNT8.CTRLA.reg = cfg->prescaler | TC_CTRLA_MODE_COUNT8 | + TC_CTRLA_PRESCSYNC_PRESC; + regs->COUNT8.WAVE.reg = TC_WAVE_WAVEGEN_NPWM; + regs->COUNT8.PER.reg = TC_COUNT8_PER_PER(1); + + regs->COUNT8.CTRLA.bit.ENABLE = 1; + wait_synchronization(regs, counter_size); + } else { + regs->COUNT16.CTRLA.bit.SWRST = 1; + wait_synchronization(regs, counter_size); + + regs->COUNT16.CTRLA.reg = cfg->prescaler | TC_CTRLA_MODE_COUNT16 | + TC_CTRLA_PRESCSYNC_PRESC; + regs->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MPWM; + regs->COUNT16.CC[0].reg = TC_COUNT16_CC_CC(1); + + regs->COUNT16.CTRLA.bit.ENABLE = 1; + wait_synchronization(regs, cfg->counter_size); + } + + return 0; +} + +static DEVICE_API(pwm, pwm_sam0_driver_api) = { + .set_cycles = pwm_sam0_set_cycles, + .get_cycles_per_sec = pwm_sam0_get_cycles_per_sec, +}; + +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define PWM_SAM0_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + \ + static const struct pwm_sam0_config pwm_sam0_config_##inst = { \ + .regs = (Tc *)DT_INST_REG_ADDR(inst), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .channels = DT_INST_PROP(inst, channels), \ + .counter_size = DT_INST_PROP(inst, counter_size), \ + .prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \ + DT_INST_PROP(inst, prescaler)), \ + .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ + DT_INST_PROP(inst, prescaler), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \ + NULL, &pwm_sam0_config_##inst, \ + POST_KERNEL, CONFIG_PWM_TC_INIT_PRIORITY, \ + &pwm_sam0_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_SAM0_INIT) + +/* clang-format on */ diff --git a/drivers/pwm/pwm_sam0_tcc.c b/drivers/pwm/pwm_sam0_tcc.c index 3a12c81b76c9a..1d5578c5a77c6 100644 --- a/drivers/pwm/pwm_sam0_tcc.c +++ b/drivers/pwm/pwm_sam0_tcc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +18,8 @@ #include #include +/* clang-format off */ + /* Static configuration */ struct pwm_sam0_config { Tcc *regs; @@ -25,15 +28,10 @@ struct pwm_sam0_config { uint8_t counter_size; uint16_t prescaler; uint32_t freq; - -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; + uint32_t gclk_gen; uint16_t gclk_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif }; /* Wait for the peripheral to finish all commands */ @@ -106,15 +104,15 @@ static int pwm_sam0_init(const struct device *dev) Tcc *regs = cfg->regs; int retval; - /* Enable the clocks */ -#ifdef MCLK - GCLK->PCHCTRL[cfg->gclk_id].reg = - GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; *cfg->mclk |= cfg->mclk_mask; + +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); #else - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - PM->APBCMASK.reg |= cfg->pm_apbcmask; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); @@ -135,39 +133,36 @@ static int pwm_sam0_init(const struct device *dev) return 0; } -static const struct pwm_driver_api pwm_sam0_driver_api = { +static DEVICE_API(pwm, pwm_sam0_driver_api) = { .set_cycles = pwm_sam0_set_cycles, .get_cycles_per_sec = pwm_sam0_get_cycles_per_sec, }; -#ifdef MCLK -#define PWM_SAM0_INIT_CLOCKS(inst) \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \ - .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch) -#else -#define PWM_SAM0_INIT_CLOCKS(inst) \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, clkctrl_id) -#endif - -#define PWM_SAM0_INIT(inst) \ - PINCTRL_DT_INST_DEFINE(inst); \ - static const struct pwm_sam0_config pwm_sam0_config_##inst = { \ - .regs = (Tcc *)DT_INST_REG_ADDR(inst), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ - .channels = DT_INST_PROP(inst, channels), \ - .counter_size = DT_INST_PROP(inst, counter_size), \ - .prescaler = UTIL_CAT(TCC_CTRLA_PRESCALER_DIV, \ - DT_INST_PROP(inst, prescaler)), \ - .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ - DT_INST_PROP(inst, prescaler), \ - PWM_SAM0_INIT_CLOCKS(inst), \ - }; \ - \ - DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \ - NULL, &pwm_sam0_config_##inst, \ - POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ - &pwm_sam0_driver_api); +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define PWM_SAM0_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + static const struct pwm_sam0_config pwm_sam0_config_##inst = { \ + .regs = (Tcc *)DT_INST_REG_ADDR(inst), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .channels = DT_INST_PROP(inst, channels), \ + .counter_size = DT_INST_PROP(inst, counter_size), \ + .prescaler = UTIL_CAT(TCC_CTRLA_PRESCALER_DIV, \ + DT_INST_PROP(inst, prescaler)), \ + .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ + DT_INST_PROP(inst, prescaler), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \ + NULL, &pwm_sam0_config_##inst, \ + POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_sam0_driver_api); DT_INST_FOREACH_STATUS_OKAY(PWM_SAM0_INIT) + +/* clang-format on */ diff --git a/drivers/pwm/pwm_shell.c b/drivers/pwm/pwm_shell.c index 1caecad939f52..e827710286e42 100644 --- a/drivers/pwm/pwm_shell.c +++ b/drivers/pwm/pwm_shell.c @@ -38,7 +38,7 @@ static int cmd_cycles(const struct shell *sh, size_t argc, char **argv) uint32_t channel; int err; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "PWM device not found"); return -EINVAL; @@ -71,7 +71,7 @@ static int cmd_usec(const struct shell *sh, size_t argc, char **argv) uint32_t channel; int err; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "PWM device not found"); return -EINVAL; @@ -103,7 +103,7 @@ static int cmd_nsec(const struct shell *sh, size_t argc, char **argv) uint32_t channel; int err; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "PWM device not found"); return -EINVAL; @@ -126,12 +126,29 @@ static int cmd_nsec(const struct shell *sh, size_t argc, char **argv) return 0; } +static bool device_is_pwm(const struct device *dev) +{ + return DEVICE_API_IS(pwm, dev); +} + +static void device_name_get(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_filter(idx, device_is_pwm); + + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; +} + +SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); + SHELL_STATIC_SUBCMD_SET_CREATE(pwm_cmds, - SHELL_CMD_ARG(cycles, NULL, " " + SHELL_CMD_ARG(cycles, &dsub_device_name, " " " [flags]", cmd_cycles, 5, 1), - SHELL_CMD_ARG(usec, NULL, " " + SHELL_CMD_ARG(usec, &dsub_device_name, " " " [flags]", cmd_usec, 5, 1), - SHELL_CMD_ARG(nsec, NULL, " " + SHELL_CMD_ARG(nsec, &dsub_device_name, " " " [flags]", cmd_nsec, 5, 1), SHELL_SUBCMD_SET_END ); diff --git a/drivers/pwm/pwm_sifive.c b/drivers/pwm/pwm_sifive.c index b11f10b2d0bd8..cf3200ccd1209 100644 --- a/drivers/pwm/pwm_sifive.c +++ b/drivers/pwm/pwm_sifive.c @@ -208,7 +208,7 @@ static int pwm_sifive_get_cycles_per_sec(const struct device *dev, /* Device Instantiation */ -static const struct pwm_driver_api pwm_sifive_api = { +static DEVICE_API(pwm, pwm_sifive_api) = { .set_cycles = pwm_sifive_set_cycles, .get_cycles_per_sec = pwm_sifive_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_stm32.c b/drivers/pwm/pwm_stm32.c index d120ec33b5b1f..708709bf2ef35 100644 --- a/drivers/pwm/pwm_stm32.c +++ b/drivers/pwm/pwm_stm32.c @@ -116,16 +116,19 @@ static const uint32_t ch2ll[TIMER_MAX_CH] = { #endif }; -/** Some stm32 mcus have complementary channels : 3 or 4 */ +/** STM32 MCUs have between 1 and 4 complementary channels */ static const uint32_t ch2ll_n[] = { #if defined(LL_TIM_CHANNEL_CH1N) LL_TIM_CHANNEL_CH1N, +#if defined(LL_TIM_CHANNEL_CH2N) LL_TIM_CHANNEL_CH2N, +#if defined(LL_TIM_CHANNEL_CH3N) LL_TIM_CHANNEL_CH3N, #if defined(LL_TIM_CHANNEL_CH4N) -/** stm32g4x and stm32u5x have 4 complementary channels */ LL_TIM_CHANNEL_CH4N, #endif /* LL_TIM_CHANNEL_CH4N */ +#endif /* LL_TIM_CHANNEL_CH3N */ +#endif /* LL_TIM_CHANNEL_CH2N */ #endif /* LL_TIM_CHANNEL_CH1N */ }; /** Maximum number of complemented timer channels is ARRAY_SIZE(ch2ll_n)*/ @@ -231,7 +234,10 @@ static int get_tim_clk(const struct stm32_pclken *pclken, uint32_t *tim_clk) return r; } -#if defined(CONFIG_SOC_SERIES_STM32H7X) +#if defined(CONFIG_SOC_SERIES_STM32WB0X) + /* Timers are clocked by SYSCLK on STM32WB0 */ + apb_psc = 1; +#elif defined(CONFIG_SOC_SERIES_STM32H7X) if (pclken->bus == STM32_CLOCK_BUS_APB1) { apb_psc = STM32_D2PPRE1; } else { @@ -761,7 +767,7 @@ static int pwm_stm32_get_cycles_per_sec(const struct device *dev, return 0; } -static const struct pwm_driver_api pwm_stm32_driver_api = { +static DEVICE_API(pwm, pwm_stm32_driver_api) = { .set_cycles = pwm_stm32_set_cycles, .get_cycles_per_sec = pwm_stm32_get_cycles_per_sec, #ifdef CONFIG_PWM_CAPTURE diff --git a/drivers/pwm/pwm_test.c b/drivers/pwm/pwm_test.c index 4961e90f3fe22..a94142ea1a14e 100644 --- a/drivers/pwm/pwm_test.c +++ b/drivers/pwm/pwm_test.c @@ -48,7 +48,7 @@ static int vnd_pwm_get_cycles_per_sec(const struct device *dev, return -ENOTSUP; } -static const struct pwm_driver_api vnd_pwm_api = { +static DEVICE_API(pwm, vnd_pwm_api) = { .set_cycles = vnd_pwm_set_cycles, #ifdef CONFIG_PWM_CAPTURE .configure_capture = vnd_pwm_configure_capture, diff --git a/drivers/pwm/pwm_xlnx_axi_timer.c b/drivers/pwm/pwm_xlnx_axi_timer.c index 6e5c594a0af94..88407a330d649 100644 --- a/drivers/pwm/pwm_xlnx_axi_timer.c +++ b/drivers/pwm/pwm_xlnx_axi_timer.c @@ -172,7 +172,7 @@ static int xlnx_axi_timer_get_cycles_per_sec(const struct device *dev, return 0; } -static const struct pwm_driver_api xlnx_axi_timer_driver_api = { +static DEVICE_API(pwm, xlnx_axi_timer_driver_api) = { .set_cycles = xlnx_axi_timer_set_cycles, .get_cycles_per_sec = xlnx_axi_timer_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_xmc4xxx_ccu4.c b/drivers/pwm/pwm_xmc4xxx_ccu4.c index 9800003df3962..4220c7d30cd76 100644 --- a/drivers/pwm/pwm_xmc4xxx_ccu4.c +++ b/drivers/pwm/pwm_xmc4xxx_ccu4.c @@ -93,7 +93,7 @@ static int pwm_xmc4xxx_ccu4_get_cycles_per_sec(const struct device *dev, uint32_ return 0; } -static const struct pwm_driver_api pwm_xmc4xxx_ccu4_driver_api = { +static DEVICE_API(pwm, pwm_xmc4xxx_ccu4_driver_api) = { .set_cycles = pwm_xmc4xxx_ccu4_set_cycles, .get_cycles_per_sec = pwm_xmc4xxx_ccu4_get_cycles_per_sec, }; diff --git a/drivers/pwm/pwm_xmc4xxx_ccu8.c b/drivers/pwm/pwm_xmc4xxx_ccu8.c index e6d68cb115b43..2ff9167b5a321 100644 --- a/drivers/pwm/pwm_xmc4xxx_ccu8.c +++ b/drivers/pwm/pwm_xmc4xxx_ccu8.c @@ -148,7 +148,7 @@ static int pwm_xmc4xxx_ccu8_get_cycles_per_sec(const struct device *dev, uint32_ return 0; } -static const struct pwm_driver_api pwm_xmc4xxx_ccu8_driver_api = { +static DEVICE_API(pwm, pwm_xmc4xxx_ccu8_driver_api) = { .set_cycles = pwm_xmc4xxx_ccu8_set_cycles, .get_cycles_per_sec = pwm_xmc4xxx_ccu8_get_cycles_per_sec, }; diff --git a/drivers/regulator/CMakeLists.txt b/drivers/regulator/CMakeLists.txt index 7ed90137c3f24..1a71ae534b64f 100644 --- a/drivers/regulator/CMakeLists.txt +++ b/drivers/regulator/CMakeLists.txt @@ -17,6 +17,7 @@ zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM1300 regulator_npm1300.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM2100 regulator_npm2100.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM6001 regulator_npm6001.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_PCA9420 regulator_pca9420.c) +zephyr_library_sources_ifdef(CONFIG_REGULATOR_PF1550 regulator_pf1550.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_SHELL regulator_shell.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_RPI_PICO regulator_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NXP_VREF regulator_nxp_vref.c) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index d4b70e6b76add..dc331b2139d36 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -39,6 +39,7 @@ source "drivers/regulator/Kconfig.npm1300" source "drivers/regulator/Kconfig.npm2100" source "drivers/regulator/Kconfig.npm6001" source "drivers/regulator/Kconfig.pca9420" +source "drivers/regulator/Kconfig.pf1550" source "drivers/regulator/Kconfig.rpi_pico" source "drivers/regulator/Kconfig.nxp_vref" source "drivers/regulator/Kconfig.mpm54304" diff --git a/drivers/regulator/Kconfig.pf1550 b/drivers/regulator/Kconfig.pf1550 new file mode 100644 index 0000000000000..667a4b411ee02 --- /dev/null +++ b/drivers/regulator/Kconfig.pf1550 @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +config REGULATOR_PF1550 + bool "NXP PF1550 PMIC regulator driver" + default y + depends on DT_HAS_NXP_PF1550_REGULATOR_ENABLED + select I2C + select MFD + help + Enable the NXP PF1550 PMIC regulator driver diff --git a/drivers/regulator/regulator_fake.c b/drivers/regulator/regulator_fake.c index e48bd8cdb398a..9e483ae7d3bfa 100644 --- a/drivers/regulator/regulator_fake.c +++ b/drivers/regulator/regulator_fake.c @@ -32,6 +32,9 @@ DEFINE_FAKE_VALUE_FUNC(int, regulator_fake_set_voltage, const struct device *, int32_t, int32_t); DEFINE_FAKE_VALUE_FUNC(int, regulator_fake_get_voltage, const struct device *, int32_t *); +DEFINE_FAKE_VALUE_FUNC(unsigned int, regulator_fake_count_current_limits, const struct device *); +DEFINE_FAKE_VALUE_FUNC(int, regulator_fake_list_current_limit, const struct device *, unsigned int, + int32_t *); DEFINE_FAKE_VALUE_FUNC(int, regulator_fake_set_current_limit, const struct device *, int32_t, int32_t); DEFINE_FAKE_VALUE_FUNC(int, regulator_fake_get_current_limit, @@ -54,6 +57,8 @@ static DEVICE_API(regulator, api) = { .list_voltage = regulator_fake_list_voltage, .set_voltage = regulator_fake_set_voltage, .get_voltage = regulator_fake_get_voltage, + .count_current_limits = regulator_fake_count_current_limits, + .list_current_limit = regulator_fake_list_current_limit, .set_current_limit = regulator_fake_set_current_limit, .get_current_limit = regulator_fake_get_current_limit, .set_mode = regulator_fake_set_mode, diff --git a/drivers/regulator/regulator_npm1300.c b/drivers/regulator/regulator_npm1300.c index ff4fcb5df434a..c44339ccabfec 100644 --- a/drivers/regulator/regulator_npm1300.c +++ b/drivers/regulator/regulator_npm1300.c @@ -87,6 +87,7 @@ struct regulator_npm1300_config { struct gpio_dt_spec retention_gpios; struct gpio_dt_spec pwm_gpios; uint8_t soft_start; + bool ldo_disable_workaround; }; struct regulator_npm1300_data { @@ -357,6 +358,7 @@ int regulator_npm1300_set_mode(const struct device *dev, regulator_mode_t mode) int regulator_npm1300_enable(const struct device *dev) { const struct regulator_npm1300_config *config = dev->config; + int ret; switch (config->source) { case NPM1300_SOURCE_BUCK1: @@ -364,12 +366,27 @@ int regulator_npm1300_enable(const struct device *dev) case NPM1300_SOURCE_BUCK2: return mfd_npm1300_reg_write(config->mfd, BUCK_BASE, BUCK_OFFSET_EN_SET + 2U, 1U); case NPM1300_SOURCE_LDO1: - return mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_EN_SET, 1U); + ret = mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_EN_SET, 1U); + break; case NPM1300_SOURCE_LDO2: - return mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_EN_SET + 2U, 1U); + ret = mfd_npm1300_reg_write(config->mfd, LDSW_BASE, LDSW_OFFSET_EN_SET + 2U, 1U); + break; default: return 0; } + + if (ret < 0) { + return ret; + } + + if (!config->ldo_disable_workaround) { + uint8_t unused; + + k_msleep(2); + return mfd_npm1300_reg_read(config->mfd, LDSW_BASE, LDSW_OFFSET_STATUS, &unused); + } + + return ret; } int regulator_npm1300_disable(const struct device *dev) @@ -655,7 +672,8 @@ static DEVICE_API(regulator, api) = { .soft_start = DT_ENUM_IDX_OR(node_id, soft_start_microamp, UINT8_MAX), \ .enable_gpios = GPIO_DT_SPEC_GET_OR(node_id, enable_gpios, {0}), \ .retention_gpios = GPIO_DT_SPEC_GET_OR(node_id, retention_gpios, {0}), \ - .pwm_gpios = GPIO_DT_SPEC_GET_OR(node_id, pwm_gpios, {0})}; \ + .pwm_gpios = GPIO_DT_SPEC_GET_OR(node_id, pwm_gpios, {0}), \ + .ldo_disable_workaround = DT_PROP(node_id, nordic_ldo_disable_workaround)}; \ \ DEVICE_DT_DEFINE(node_id, regulator_npm1300_init, NULL, &data_##id, &config_##id, \ POST_KERNEL, CONFIG_REGULATOR_NPM1300_INIT_PRIORITY, &api); diff --git a/drivers/regulator/regulator_npm2100.c b/drivers/regulator/regulator_npm2100.c index afad574c767ea..0797d11536890 100644 --- a/drivers/regulator/regulator_npm2100.c +++ b/drivers/regulator/regulator_npm2100.c @@ -642,18 +642,6 @@ static int regulator_npm2100_ship_mode(const struct device *dev) { const struct regulator_npm2100_pconfig *pconfig = dev->config; - /* Ensure shiphold button is enabled so that wakeup will work */ - int ret = i2c_reg_write_byte_dt(&pconfig->i2c, RESET_WRITESTICKY, 0); - - if (ret < 0) { - return ret; - } - - ret = i2c_reg_write_byte_dt(&pconfig->i2c, RESET_STROBESTICKY, 1U); - if (ret < 0) { - return ret; - } - return i2c_reg_write_byte_dt(&pconfig->i2c, SHIP_TASK_SHIP, 1U); } diff --git a/drivers/regulator/regulator_pf1550.c b/drivers/regulator/regulator_pf1550.c new file mode 100644 index 0000000000000..3759e8e912397 --- /dev/null +++ b/drivers/regulator/regulator_pf1550.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2024 Arduino SA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_pf1550_regulator + +#include +#include +#include +#include + +#define PMIC_DEVICE_ID 0x00 +#define PMIC_OTP_FLAVOR 0x01 +#define PMIC_SILICON_REV 0x02 +#define PMIC_INT_CATEGORY 0x06 +#define PMIC_SW_INT_STAT0 0x08 +#define PMIC_SW_INT_MASK0 0x09 +#define PMIC_SW_INT_SENSE0 0x0A +#define PMIC_SW_INT_STAT1 0x0B +#define PMIC_SW_INT_MASK1 0x0C +#define PMIC_SW_INT_SENSE1 0x0D +#define PMIC_SW_INT_STAT2 0x0E +#define PMIC_SW_INT_MASK2 0x0F +#define PMIC_SW_INT_SENSE2 0x10 +#define PMIC_LDO_INT_STAT0 0x18 +#define PMIC_LDO_INT_MASK0 0x19 +#define PMIC_LDO_INT_SENSE0 0x1A +#define PMIC_TEMP_INT_STAT0 0x20 +#define PMIC_TEMP_INT_MASK0 0x21 +#define PMIC_TEMP_INT_SENSE0 0x22 +#define PMIC_ONKEY_INT_STAT0 0x24 +#define PMIC_ONKEY_INT_MASK0 0x25 +#define PMIC_ONKEY_INT_SENSE0 0x26 +#define PMIC_MISC_INT_STAT0 0x28 +#define PMIC_MISC_INT_MASK0 0x29 +#define PMIC_MISC_INT_SENSE0 0x2A +#define PMIC_COINCELL_CONTROL 0x30 +#define PMIC_SW1_VOLT 0x32 +#define PMIC_SW1_STBY_VOLT 0x33 +#define PMIC_SW1_SLP_VOLT 0x34 +#define PMIC_SW1_CTRL 0x35 +#define PMIC_SW1_CTRL1 0x36 +#define PMIC_SW2_VOLT 0x38 +#define PMIC_SW2_STBY_VOLT 0x39 +#define PMIC_SW2_SLP_VOLT 0x3A +#define PMIC_SW2_CTRL 0x3B +#define PMIC_SW2_CTRL1 0x3C +#define PMIC_SW3_VOLT 0x3E +#define PMIC_SW3_STBY_VOLT 0x3F +#define PMIC_SW3_SLP_VOLT 0x40 +#define PMIC_SW3_CTRL 0x41 +#define PMIC_SW3_CTRL1 0x42 +#define PMIC_VSNVS_CTRL 0x48 +#define PMIC_VREFDDR_CTRL 0x4A +#define PMIC_LDO1_VOLT 0x4C +#define PMIC_LDO1_CTRL 0x4D +#define PMIC_LDO2_VOLT 0x4F +#define PMIC_LDO2_CTRL 0x50 +#define PMIC_LDO3_VOLT 0x52 +#define PMIC_LDO3_CTRL 0x53 +#define PMIC_PWRCTRL0 0x58 +#define PMIC_PWRCTRL1 0x59 +#define PMIC_PWRCTRL2 0x5A +#define PMIC_PWRCTRL3 0x5B +#define PMIC_SW1_PWRDN_SEQ 0x5F +#define PMIC_SW2_PWRDN_SEQ 0x60 +#define PMIC_SW3_PWRDN_SEQ 0x61 +#define PMIC_LDO1_PWRDN_SEQ 0x62 +#define PMIC_LDO2_PWRDN_SEQ 0x63 +#define PMIC_LDO3_PWRDN_SEQ 0x64 +#define PMIC_VREFDDR_PWRDN_SEQ 0x65 +#define PMIC_STATE_INFO 0x67 +#define PMIC_I2C_ADDR 0x68 +#define PMIC_RC_16MHZ 0x6B +#define PMIC_KEY1 0x6B + +enum pf1550_pmic_sources { + PF1550_PMIC_SOURCE_BUCK1, + PF1550_PMIC_SOURCE_BUCK2, + PF1550_PMIC_SOURCE_BUCK3, + PF1550_PMIC_SOURCE_LDO1, + PF1550_PMIC_SOURCE_LDO2, + PF1550_PMIC_SOURCE_LDO3, +}; + +struct regulator_pf1550_desc { + uint8_t vsel_reg; + uint8_t enable_mask; + uint8_t enable_val; + uint8_t cfg_reg; + const struct linear_range *uv_range; + uint8_t uv_nranges; + const struct linear_range *ua_range; + uint8_t ua_nranges; +}; + +struct regulator_pf1550_common_config { + struct i2c_dt_spec bus; +}; + +struct regulator_pf1550_config { + struct regulator_common_config common; + struct i2c_dt_spec bus; + const struct regulator_pf1550_desc *desc; + uint8_t source; +}; + +struct regulator_pf1550_data { + struct regulator_common_data common; +}; + +/* + * Output voltage for BUCK1/2 with DVS disabled (OTP_SWx_DVS_SEL = 1). + * This is needed to reach the 3V3 maximum range + */ +static const struct linear_range buck12_range[] = { + LINEAR_RANGE_INIT(1100000, 0, 0, 0), LINEAR_RANGE_INIT(1200000, 0, 1, 1), + LINEAR_RANGE_INIT(1350000, 0, 2, 2), LINEAR_RANGE_INIT(1500000, 0, 3, 3), + LINEAR_RANGE_INIT(1800000, 0, 4, 4), LINEAR_RANGE_INIT(2500000, 0, 5, 5), + LINEAR_RANGE_INIT(3000000, 0, 6, 6), LINEAR_RANGE_INIT(3300000, 0, 7, 7), +}; +static const struct linear_range buck3_range[] = { + LINEAR_RANGE_INIT(1800000, 100000, 0, 15), +}; +static const struct linear_range buck123_current_limit_range[] = { + LINEAR_RANGE_INIT(1000000, 0, 0, 0), + LINEAR_RANGE_INIT(1200000, 0, 0, 0), + LINEAR_RANGE_INIT(1500000, 0, 0, 0), + LINEAR_RANGE_INIT(2000000, 0, 0, 0), +}; +static const struct linear_range ldo13_range[] = { + LINEAR_RANGE_INIT(750000, 50000, 0, 15), + LINEAR_RANGE_INIT(1800000, 100000, 16, 31), +}; +static const struct linear_range ldo2_range[] = { + LINEAR_RANGE_INIT(1800000, 100000, 0, 15), +}; + +#define PF1550_RAIL_EN BIT(0) +#define PF1550_RAIL_EN_MASK GENMASK(1, 0) +#define PF1550_GOTO_SHIP BIT(0) +#define PF1550_GOTO_SHIP_MASK GENMASK(1, 0) + +static const struct regulator_pf1550_desc __maybe_unused buck1_desc = { + .vsel_reg = PMIC_SW1_VOLT, + .enable_mask = PF1550_RAIL_EN, + .enable_val = PF1550_RAIL_EN_MASK, + .cfg_reg = PMIC_SW1_CTRL, + .uv_range = buck12_range, + .uv_nranges = ARRAY_SIZE(buck12_range), + .ua_range = buck123_current_limit_range, + .ua_nranges = ARRAY_SIZE(buck123_current_limit_range), +}; + +static const struct regulator_pf1550_desc __maybe_unused buck2_desc = { + .vsel_reg = PMIC_SW2_VOLT, + .enable_mask = PF1550_RAIL_EN, + .enable_val = PF1550_RAIL_EN_MASK, + .cfg_reg = PMIC_SW2_CTRL, + .uv_range = buck12_range, + .uv_nranges = ARRAY_SIZE(buck12_range), + .ua_range = buck123_current_limit_range, + .ua_nranges = ARRAY_SIZE(buck123_current_limit_range), +}; + +static const struct regulator_pf1550_desc __maybe_unused buck3_desc = { + .vsel_reg = PMIC_SW3_VOLT, + .enable_mask = PF1550_RAIL_EN, + .enable_val = PF1550_RAIL_EN_MASK, + .cfg_reg = PMIC_SW3_CTRL, + .uv_range = buck3_range, + .uv_nranges = ARRAY_SIZE(buck3_range), + .ua_range = buck123_current_limit_range, + .ua_nranges = ARRAY_SIZE(buck123_current_limit_range), +}; + +static const struct regulator_pf1550_desc __maybe_unused ldo1_desc = { + .vsel_reg = PMIC_LDO1_VOLT, + .enable_mask = PF1550_RAIL_EN, + .enable_val = PF1550_RAIL_EN_MASK, + .cfg_reg = PMIC_LDO1_CTRL, + .uv_range = ldo13_range, + .uv_nranges = ARRAY_SIZE(ldo13_range), +}; + +static const struct regulator_pf1550_desc __maybe_unused ldo2_desc = { + .vsel_reg = PMIC_LDO2_VOLT, + .enable_mask = PF1550_RAIL_EN, + .enable_val = PF1550_RAIL_EN_MASK, + .cfg_reg = PMIC_LDO2_CTRL, + .uv_range = ldo2_range, + .uv_nranges = ARRAY_SIZE(ldo2_range), +}; + +static const struct regulator_pf1550_desc __maybe_unused ldo3_desc = { + .vsel_reg = PMIC_LDO3_VOLT, + .enable_mask = PF1550_RAIL_EN, + .enable_val = PF1550_RAIL_EN_MASK, + .cfg_reg = PMIC_LDO3_CTRL, + .uv_range = ldo13_range, + .uv_nranges = ARRAY_SIZE(ldo13_range), +}; + +static int regulator_pf1550_set_enable(const struct device *dev, bool enable) +{ + const struct regulator_pf1550_config *config = dev->config; + + return i2c_reg_update_byte_dt(&config->bus, config->desc->cfg_reg, + config->desc->enable_mask, + enable ? config->desc->enable_val : 0); +} + +static int regulator_pf1550_enable(const struct device *dev) +{ + return regulator_pf1550_set_enable(dev, true); +} + +static int regulator_pf1550_disable(const struct device *dev) +{ + return regulator_pf1550_set_enable(dev, false); +} + +static unsigned int regulator_pf1550_count_voltages(const struct device *dev) +{ + const struct regulator_pf1550_config *config = dev->config; + + return linear_range_group_values_count(config->desc->uv_range, config->desc->uv_nranges); +} + +static int regulator_pf1550_list_voltage(const struct device *dev, unsigned int idx, + int32_t *volt_uv) +{ + const struct regulator_pf1550_config *config = dev->config; + + return linear_range_group_get_value(config->desc->uv_range, config->desc->uv_nranges, idx, + volt_uv); +} + +static int regulator_pf1550_set_buck_ldo_voltage(const struct device *dev, int32_t min_uv, + int32_t max_uv, const struct linear_range *range, + const uint8_t nranges, uint8_t vout_reg) +{ + const struct regulator_pf1550_config *config = dev->config; + uint16_t idx; + int ret; + + ret = linear_range_group_get_win_index(range, nranges, min_uv, max_uv, &idx); + if (ret < 0) { + return ret; + } + + return i2c_reg_write_byte_dt(&config->bus, vout_reg, (uint8_t)idx); +} + +static int regulator_pf1550_buck12_ldo123_get_voltage(const struct device *dev, + const struct linear_range *range, + const uint8_t nranges, uint8_t vout_reg, + int32_t *volt_uv) +{ + const struct regulator_pf1550_config *config = dev->config; + uint8_t idx; + int ret; + + ret = i2c_reg_read_byte_dt(&config->bus, vout_reg, &idx); + if (ret < 0) { + return ret; + } + + return linear_range_group_get_value(range, nranges, idx, volt_uv); +} + +static int regulator_pf1550_get_voltage(const struct device *dev, int32_t *volt_uv) +{ + const struct regulator_pf1550_config *config = dev->config; + + return regulator_pf1550_buck12_ldo123_get_voltage(dev, config->desc->uv_range, + config->desc->uv_nranges, + config->desc->vsel_reg, volt_uv); +} + +static int regulator_pf1550_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv) +{ + const struct regulator_pf1550_config *config = dev->config; + + return regulator_pf1550_set_buck_ldo_voltage(dev, min_uv, max_uv, config->desc->uv_range, + config->desc->uv_nranges, + config->desc->vsel_reg); +} + +static unsigned int regulator_pf1550_count_current_limits(const struct device *dev) +{ + const struct regulator_pf1550_config *config = dev->config; + + if (config->source != PF1550_PMIC_SOURCE_BUCK1 && + config->source != PF1550_PMIC_SOURCE_BUCK2 && + config->source != PF1550_PMIC_SOURCE_BUCK3) { + return -ENOTSUP; + } + + return linear_range_group_values_count(config->desc->ua_range, config->desc->ua_nranges); +} + +static int regulator_pf1550_list_current_limit(const struct device *dev, unsigned int idx, + int32_t *current_ua) +{ + const struct regulator_pf1550_config *config = dev->config; + + if (config->source != PF1550_PMIC_SOURCE_BUCK1 && + config->source != PF1550_PMIC_SOURCE_BUCK2 && + config->source != PF1550_PMIC_SOURCE_BUCK3) { + return -ENOTSUP; + } + + return linear_range_group_get_value(config->desc->ua_range, config->desc->ua_nranges, idx, + current_ua); +} + +static int regulator_pf1550_set_current_limit(const struct device *dev, int32_t min_ua, + int32_t max_ua) +{ + const struct regulator_pf1550_config *config = dev->config; + uint8_t val; + uint16_t idx; + int ret; + + if (config->source != PF1550_PMIC_SOURCE_BUCK1 && + config->source != PF1550_PMIC_SOURCE_BUCK2 && + config->source != PF1550_PMIC_SOURCE_BUCK3) { + return -ENOTSUP; + } + + /* Current is stored in SW*_CTRL1 register */ + ret = i2c_reg_read_byte_dt(&config->bus, config->desc->cfg_reg + 1, &val); + if (ret < 0) { + return ret; + } + + ret = linear_range_group_get_win_index(config->desc->ua_range, config->desc->ua_nranges, + min_ua, max_ua, &idx); + if (ret < 0) { + return ret; + } + + val |= idx; + return i2c_reg_write_byte_dt(&config->bus, config->desc->cfg_reg + 1, val); +} + +static int regulator_pf1550_power_off(const struct device *dev) +{ + const struct regulator_pf1550_common_config *common_config = dev->config; + + return i2c_reg_update_byte_dt(&common_config->bus, PMIC_PWRCTRL3, PF1550_GOTO_SHIP_MASK, + PF1550_GOTO_SHIP); +} + +static int regulator_pf1550_init(const struct device *dev) +{ + const struct regulator_pf1550_config *config = dev->config; + + if (!i2c_is_ready_dt(&config->bus)) { + return -ENODEV; + } + + regulator_common_data_init(dev); + + return regulator_common_init(dev, false); +} + +static int regulator_pf1550_common_init(const struct device *dev) +{ + const struct regulator_pf1550_common_config *common_config = dev->config; + + if (!i2c_is_ready_dt(&common_config->bus)) { + return -ENODEV; + } + + return 0; +} + +static const struct regulator_parent_driver_api parent_api = { + .ship_mode = regulator_pf1550_power_off, +}; + +static const struct regulator_driver_api api = { + .enable = regulator_pf1550_enable, + .disable = regulator_pf1550_disable, + .count_voltages = regulator_pf1550_count_voltages, + .list_voltage = regulator_pf1550_list_voltage, + .set_voltage = regulator_pf1550_set_voltage, + .get_voltage = regulator_pf1550_get_voltage, + .count_current_limits = regulator_pf1550_count_current_limits, + .list_current_limit = regulator_pf1550_list_current_limit, + .set_current_limit = regulator_pf1550_set_current_limit, +}; + +#define REGULATOR_PF1550_DEFINE(node_id, id, child_name, _source) \ + static const struct regulator_pf1550_config regulator_pf1550_config_##id = { \ + .common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id), \ + .bus = I2C_DT_SPEC_GET(DT_GPARENT(node_id)), \ + .desc = &child_name##_desc, \ + .source = _source, \ + }; \ + \ + static struct regulator_pf1550_data regulator_pf1550_data_##id; \ + DEVICE_DT_DEFINE(node_id, regulator_pf1550_init, NULL, ®ulator_pf1550_data_##id, \ + ®ulator_pf1550_config_##id, POST_KERNEL, \ + CONFIG_MFD_INIT_PRIORITY, &api); + +#define REGULATOR_PF1550_DEFINE_COND(inst, child, source) \ + COND_CODE_1( \ + DT_NODE_EXISTS(DT_INST_CHILD(inst, child)), \ + (REGULATOR_PF1550_DEFINE(DT_INST_CHILD(inst, child), child##inst, child, source)), \ + ()) + +#define REGULATOR_PF1550_DEFINE_ALL(inst) \ + static const struct regulator_pf1550_common_config common_config_##inst = { \ + .bus = I2C_DT_SPEC_GET(DT_INST_PARENT(inst)), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, regulator_pf1550_common_init, NULL, NULL, \ + &common_config_##inst, POST_KERNEL, \ + CONFIG_MFD_INIT_PRIORITY, &parent_api); \ + \ + REGULATOR_PF1550_DEFINE_COND(inst, buck1, PF1550_PMIC_SOURCE_BUCK1) \ + REGULATOR_PF1550_DEFINE_COND(inst, buck2, PF1550_PMIC_SOURCE_BUCK2) \ + REGULATOR_PF1550_DEFINE_COND(inst, buck3, PF1550_PMIC_SOURCE_BUCK3) \ + REGULATOR_PF1550_DEFINE_COND(inst, ldo1, PF1550_PMIC_SOURCE_LDO1) \ + REGULATOR_PF1550_DEFINE_COND(inst, ldo2, PF1550_PMIC_SOURCE_LDO2) \ + REGULATOR_PF1550_DEFINE_COND(inst, ldo3, PF1550_PMIC_SOURCE_LDO3) + +DT_INST_FOREACH_STATUS_OKAY(REGULATOR_PF1550_DEFINE_ALL) diff --git a/drivers/regulator/regulator_shell.c b/drivers/regulator/regulator_shell.c index ba0c29e34b803..259b4f8e89c45 100644 --- a/drivers/regulator/regulator_shell.c +++ b/drivers/regulator/regulator_shell.c @@ -89,7 +89,7 @@ static int cmd_enable(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -111,7 +111,7 @@ static int cmd_disable(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -132,7 +132,7 @@ static int cmd_is_enabled(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -155,7 +155,7 @@ static int cmd_vlist(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -185,7 +185,7 @@ static int cmd_vset(const struct shell *sh, size_t argc, char **argv) int32_t min_uv, max_uv; int ret; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -224,7 +224,7 @@ static int cmd_vget(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -249,7 +249,7 @@ static int cmd_clist(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -279,7 +279,7 @@ static int cmd_iset(const struct shell *sh, size_t argc, char **argv) int32_t min_ua, max_ua; int ret; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -317,7 +317,7 @@ static int cmd_iget(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -342,7 +342,7 @@ static int cmd_modeset(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -367,7 +367,7 @@ static int cmd_modeget(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -392,7 +392,7 @@ static int cmd_adset(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -424,7 +424,7 @@ static int cmd_adget(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -449,7 +449,7 @@ static int cmd_errors(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -479,7 +479,7 @@ static int cmd_dvsset(const struct shell *sh, size_t argc, char **argv) int ret = 0; regulator_dvs_state_t state; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -507,7 +507,7 @@ static int cmd_shipmode(const struct shell *sh, size_t argc, char **argv) ARG_UNUSED(argc); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL) { shell_error(sh, "Regulator device %s not available", argv[1]); return -ENODEV; @@ -522,9 +522,14 @@ static int cmd_shipmode(const struct shell *sh, size_t argc, char **argv) return 0; } +static bool device_is_regulator(const struct device *dev) +{ + return DEVICE_API_IS(regulator, dev); +} + static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_regulator); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/retained_mem/Kconfig.nrf b/drivers/retained_mem/Kconfig.nrf index 348361e5f6f5e..70aef8b504fd0 100644 --- a/drivers/retained_mem/Kconfig.nrf +++ b/drivers/retained_mem/Kconfig.nrf @@ -13,6 +13,6 @@ config RETAINED_MEM_NRF_RAM_CTRL bool "nRF RAM retention driver" default y depends on DT_HAS_ZEPHYR_RETAINED_RAM_ENABLED && RETAINED_MEM_ZEPHYR_RAM && POWEROFF - depends on SOC_FAMILY_NORDIC_NRF + depends on HAS_NORDIC_RAM_CTRL help Enable driver for Nordic RAM retention. diff --git a/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c b/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c index 8be3d5c35a36c..08e777aa6fa11 100644 --- a/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c +++ b/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c @@ -6,6 +6,7 @@ #include #include +#include #include @@ -22,7 +23,7 @@ static const struct ret_mem_region ret_mem_regions[] = { DT_FOREACH_STATUS_OKAY(zephyr_retained_ram, _BUILD_MEM_REGION) }; -static int retained_mem_nrf_init(void) +int z_nrf_retained_mem_retention_apply(void) { const struct ret_mem_region *rmr; @@ -33,5 +34,3 @@ static int retained_mem_nrf_init(void) return 0; } - -SYS_INIT(retained_mem_nrf_init, PRE_KERNEL_1, 0); diff --git a/drivers/rtc/CMakeLists.txt b/drivers/rtc/CMakeLists.txt index 6b298b969b71c..0344e8d63d6a3 100644 --- a/drivers/rtc/CMakeLists.txt +++ b/drivers/rtc/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(CONFIG_RTC_RV8263 rtc_rv8263.c) zephyr_library_sources_ifdef(CONFIG_RTC_AM1805 rtc_am1805.c) zephyr_library_sources_ifdef(CONFIG_RTC_AMBIQ rtc_ambiq.c) zephyr_library_sources_ifdef(CONFIG_RTC_DS1307 rtc_ds1307.c) +zephyr_library_sources_ifdef(CONFIG_RTC_DS3231 rtc_ds3231.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE rtc_handlers.c) zephyr_library_sources_ifdef(CONFIG_RTC_EMUL rtc_emul.c) zephyr_library_sources_ifdef(CONFIG_RTC_INFINEON_CAT1 rtc_ifx_cat1.c) @@ -22,8 +23,13 @@ zephyr_library_sources_ifdef(CONFIG_RTC_SHELL rtc_shell.c) zephyr_library_sources_ifdef(CONFIG_RTC_FAKE rtc_fake.c) zephyr_library_sources_ifdef(CONFIG_RTC_SMARTBOND rtc_smartbond.c) zephyr_library_sources_ifdef(CONFIG_RTC_ATMEL_SAM rtc_sam.c) +zephyr_library_sources_ifdef(CONFIG_RTC_ATMEL_SAM0 rtc_sam0.c) zephyr_library_sources_ifdef(CONFIG_RTC_RPI_PICO rtc_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_RTC_RV3028 rtc_rv3028.c) zephyr_library_sources_ifdef(CONFIG_RTC_NUMAKER rtc_numaker.c) zephyr_library_sources_ifdef(CONFIG_RTC_XMC4XXX rtc_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_RTC_NXP_IRTC rtc_nxp_irtc.c) +zephyr_library_sources_ifdef(CONFIG_RTC_RV8803 rtc_rv8803.c) +zephyr_library_sources_ifdef(CONFIG_RTC_BQ32002 rtc_bq32002.c) +zephyr_library_sources_ifdef(CONFIG_RTC_RX8130CE rtc_rx8130ce.c) +zephyr_library_sources_ifdef(CONFIG_RTC_DS1337 rtc_ds1337.c) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 5dd3eaf1301b7..7846eb2c67a7c 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -44,6 +44,7 @@ config RTC_SHELL source "drivers/rtc/Kconfig.am1805" source "drivers/rtc/Kconfig.ambiq" source "drivers/rtc/Kconfig.ds1307" +source "drivers/rtc/Kconfig.ds3231" source "drivers/rtc/Kconfig.emul" source "drivers/rtc/Kconfig.fake" source "drivers/rtc/Kconfig.ifx_cat1" @@ -53,11 +54,16 @@ source "drivers/rtc/Kconfig.pcf8563" source "drivers/rtc/Kconfig.rpi_pico" source "drivers/rtc/Kconfig.rv3028" source "drivers/rtc/Kconfig.sam" +source "drivers/rtc/Kconfig.sam0" source "drivers/rtc/Kconfig.smartbond" source "drivers/rtc/Kconfig.stm32" source "drivers/rtc/Kconfig.numaker" source "drivers/rtc/Kconfig.rv8263" source "drivers/rtc/Kconfig.xmc4xxx" source "drivers/rtc/Kconfig.nxp_irtc" +source "drivers/rtc/Kconfig.rv8803" +source "drivers/rtc/Kconfig.bq32002" +source "drivers/rtc/Kconfig.rx8130ce" +source "drivers/rtc/Kconfig.ds1337" endif # RTC diff --git a/drivers/rtc/Kconfig.bq32002 b/drivers/rtc/Kconfig.bq32002 new file mode 100644 index 0000000000000..1f413d4f58e38 --- /dev/null +++ b/drivers/rtc/Kconfig.bq32002 @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Marcin Lyda +# SPDX-License-Identifier: Apache-2.0 + +config RTC_BQ32002 + bool "Texas Instruments BQ32002 Real-Time Clock driver" + default y + depends on DT_HAS_TI_BQ32002_ENABLED + select I2C + help + Enable Texas Instruments BQ32002 I2C RTC driver. diff --git a/drivers/rtc/Kconfig.ds1337 b/drivers/rtc/Kconfig.ds1337 new file mode 100644 index 0000000000000..9d2079f46551c --- /dev/null +++ b/drivers/rtc/Kconfig.ds1337 @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Marcin Lyda +# SPDX-License-Identifier: Apache-2.0 + +config RTC_DS1337 + bool "Maxim DS1337 RTC driver" + default y + depends on DT_HAS_MAXIM_DS1337_ENABLED + select I2C + help + Enable Maxim DS1337 RTC driver. diff --git a/drivers/rtc/Kconfig.ds3231 b/drivers/rtc/Kconfig.ds3231 new file mode 100644 index 0000000000000..52daa3888ae21 --- /dev/null +++ b/drivers/rtc/Kconfig.ds3231 @@ -0,0 +1,23 @@ +# Copyright (c) 2024, Gergo Vari +# +# SPDX-License-Identifier: Apache-2.0 +# + +config RTC_DS3231 + bool "Maxim DS3231 RTC/TCXO" + default y + depends on DT_HAS_MAXIM_DS3231_MFD_ENABLED + depends on DT_HAS_MAXIM_DS3231_RTC_ENABLED + select I2C + select MFD + help + Enable RTC driver based on Maxim DS3231 I2C device. + +config RTC_DS3231_INIT_PRIORITY + int "DS3231 RTC driver initialization priority" + depends on RTC_DS3231 + default 86 + help + Initialization priority for the DS3231 RTC driver. It must be + greater than the I2C controller init priority and the mfd driver + init priority. diff --git a/drivers/rtc/Kconfig.rv8803 b/drivers/rtc/Kconfig.rv8803 new file mode 100644 index 0000000000000..3e3982f7789ea --- /dev/null +++ b/drivers/rtc/Kconfig.rv8803 @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Marcin Lyda +# SPDX-License-Identifier: Apache-2.0 + +config RTC_RV8803 + bool "Micro Crystal RV8803 Extreme Low Power Real-Time Clock Module driver" + default y + depends on DT_HAS_MICROCRYSTAL_RV8803_ENABLED + select I2C + help + Enable Micro Crystal RV8803 I2C RTC driver. diff --git a/drivers/rtc/Kconfig.rx8130ce b/drivers/rtc/Kconfig.rx8130ce new file mode 100644 index 0000000000000..ccd909b428aa4 --- /dev/null +++ b/drivers/rtc/Kconfig.rx8130ce @@ -0,0 +1,11 @@ +#Copyright (c) 2025 MĂĽns Ansgariusson +# +#SPDX-License-Identifier: Apache-2.0 + +config RTC_RX8130CE + bool "EPSON rx8130ce rtc driver" + default y + depends on DT_HAS_EPSON_RX8130CE_RTC_ENABLED + select I2C + help + Enable RTC driver for the Epson rx8130ce rtc diff --git a/drivers/rtc/Kconfig.sam0 b/drivers/rtc/Kconfig.sam0 new file mode 100644 index 0000000000000..5dccc7b357c70 --- /dev/null +++ b/drivers/rtc/Kconfig.sam0 @@ -0,0 +1,10 @@ +# Copyright (c) 2024-2025 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +config RTC_ATMEL_SAM0 + bool "Atmel SAM RTC driver" + default y + depends on DT_HAS_ATMEL_SAM0_RTC_ENABLED \ + && !$(dt_nodelabel_bool_prop,rtc,systimer) + help + Atmel Real-Time Clock (RTC) driver used on SAM0 SoC series. diff --git a/drivers/rtc/rtc_ambiq.c b/drivers/rtc/rtc_ambiq.c index 90b2609efe590..39459e3b38a01 100644 --- a/drivers/rtc/rtc_ambiq.c +++ b/drivers/rtc/rtc_ambiq.c @@ -42,7 +42,11 @@ struct ambiq_rtc_data { static void rtc_time_to_ambiq_time_set(const struct rtc_time *tm, am_hal_rtc_time_t *atm) { - atm->ui32CenturyBit = ((tm->tm_year <= 99) || (tm->tm_year >= 200)); +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + atm->ui32Century = ((tm->tm_year <= 99) || (tm->tm_year >= 200)); +#else + atm->ui32CenturyBit = ((tm->tm_year > 99) && (tm->tm_year < 200)); +#endif atm->ui32Year = tm->tm_year; if (tm->tm_year > 99) { atm->ui32Year = tm->tm_year % 100; @@ -68,11 +72,19 @@ static void rtc_time_to_ambiq_time_set(const struct rtc_time *tm, am_hal_rtc_tim static void ambiq_time_to_rtc_time_set(const am_hal_rtc_time_t *atm, struct rtc_time *tm) { tm->tm_year = atm->ui32Year; - if (atm->ui32CenturyBit == 0) { +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + if (atm->ui32Century == 0) { tm->tm_year += 100; } else { tm->tm_year += 200; } +#else + if (atm->ui32CenturyBit == 0) { + tm->tm_year += 200; + } else { + tm->tm_year += 100; + } +#endif tm->tm_wday = atm->ui32Weekday; tm->tm_mon = atm->ui32Month - 1; tm->tm_mday = atm->ui32DayOfMonth; @@ -180,8 +192,6 @@ static int ambiq_rtc_alarm_get_supported_fields(const struct device *dev, static int ambiq_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, struct rtc_time *timeptr) { - - int err = 0; am_hal_rtc_time_t ambiq_time = {0}; struct ambiq_rtc_data *data = dev->data; @@ -192,11 +202,11 @@ static int ambiq_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint1 k_spinlock_key_t key = k_spin_lock(&data->lock); - err = am_hal_rtc_alarm_get(&ambiq_time, NULL); - if (err != 0) { - LOG_DBG("Invalid Input Value"); - return -EINVAL; - } +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + am_hal_rtc_alarm_get(&ambiq_time); +#else + am_hal_rtc_alarm_get(&ambiq_time, NULL); +#endif ambiq_time_to_rtc_time_set(&ambiq_time, timeptr); @@ -208,13 +218,12 @@ static int ambiq_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint1 k_spin_unlock(&data->lock, key); - return err; + return 0; } static int ambiq_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, const struct rtc_time *timeptr) { - int err = 0; struct ambiq_rtc_data *data = dev->data; am_hal_rtc_time_t ambiq_time = {0}; uint16_t mask_available; @@ -240,8 +249,13 @@ static int ambiq_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint1 k_spinlock_key_t key = k_spin_lock(&data->lock); /* Disable and clear the alarm */ +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + am_hal_rtc_int_disable(AM_HAL_RTC_INT_ALM); + am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM); +#else am_hal_rtc_interrupt_disable(AM_HAL_RTC_INT_ALM); am_hal_rtc_interrupt_clear(AM_HAL_RTC_INT_ALM); +#endif /* When mask is 0 */ if (mask == 0) { @@ -258,18 +272,18 @@ static int ambiq_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint1 rtc_time_to_ambiq_time_set(timeptr, &ambiq_time); /* Set RTC ALARM, Ambiq must have interval != AM_HAL_RTC_ALM_RPT_DIS */ - if (0 != am_hal_rtc_alarm_set(&ambiq_time, AM_HAL_RTC_ALM_RPT_YR)) { - LOG_DBG("Invalid Input Value"); - err = -EINVAL; - goto unlock; - } + am_hal_rtc_alarm_set(&ambiq_time, AM_HAL_RTC_ALM_RPT_YR); +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + am_hal_rtc_int_enable(AM_HAL_RTC_INT_ALM); +#else am_hal_rtc_interrupt_enable(AM_HAL_RTC_INT_ALM); +#endif unlock: k_spin_unlock(&data->lock, key); - return err; + return 0; } static int ambiq_rtc_alarm_is_pending(const struct device *dev, uint16_t id) @@ -292,7 +306,11 @@ static int ambiq_rtc_alarm_is_pending(const struct device *dev, uint16_t id) static void ambiq_rtc_isr(const struct device *dev) { /* Clear the RTC alarm interrupt. 8*/ +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM); +#else am_hal_rtc_interrupt_clear(AM_HAL_RTC_INT_ALM); +#endif #if defined(CONFIG_RTC_ALARM) struct ambiq_rtc_data *data = dev->data; @@ -321,7 +339,11 @@ static int ambiq_rtc_alarm_set_callback(const struct device *dev, uint16_t id, data->alarm_user_callback = callback; data->alarm_user_data = user_data; if ((callback == NULL) && (user_data == NULL)) { +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + am_hal_rtc_int_disable(AM_HAL_RTC_INT_ALM); +#else am_hal_rtc_interrupt_disable(AM_HAL_RTC_INT_ALM); +#endif } } @@ -332,14 +354,16 @@ static int ambiq_rtc_alarm_set_callback(const struct device *dev, uint16_t id, static int ambiq_rtc_init(const struct device *dev) { const struct ambiq_rtc_config *config = dev->config; -# + #ifdef CONFIG_RTC_ALARM struct ambiq_rtc_data *data = dev->data; #endif - /* Enable the clock for RTC. */ - am_hal_clkgen_control(config->clk_src, NULL); - +/* Enable the clock for RTC. */ +#if defined(CONFIG_SOC_SERIES_APOLLO3X) + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_XTAL_START + config->clk_src, NULL); +#endif + am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_RTC_SEL_XTAL + config->clk_src, NULL); /* Enable the RTC. */ am_hal_rtc_osc_enable(); diff --git a/drivers/rtc/rtc_bq32002.c b/drivers/rtc/rtc_bq32002.c new file mode 100644 index 0000000000000..38eb77835739b --- /dev/null +++ b/drivers/rtc/rtc_bq32002.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2025 Marcin Lyda + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "rtc_utils.h" + +LOG_MODULE_REGISTER(bq32002, CONFIG_RTC_LOG_LEVEL); + +#define DT_DRV_COMPAT ti_bq32002 + +#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 +#warning "Texas Instruments BQ32002 RTC driver enabled without any devices" +#endif + +/* Registers */ +#define BQ32002_SECONDS_REG 0x00 +#define BQ32002_MINUTES_REG 0x01 +#define BQ32002_CENT_HOURS_REG 0x02 +#define BQ32002_DAY_REG 0x03 +#define BQ32002_DATE_REG 0x04 +#define BQ32002_MONTH_REG 0x05 +#define BQ32002_YEARS_REG 0x06 +#define BQ32002_CAL_CFG1_REG 0x07 +#define BQ32002_CFG2_REG 0x09 +#define BQ32002_SF_KEY_1_REG 0x20 +#define BQ32002_SF_KEY_2_REG 0x21 +#define BQ32002_SFR_REG 0x22 + +/* Bitmasks */ +#define BQ32002_SECONDS_MASK GENMASK(6, 0) +#define BQ32002_MINUTES_MASK GENMASK(6, 0) +#define BQ32002_HOURS_MASK GENMASK(5, 0) +#define BQ32002_DAY_MASK GENMASK(2, 0) +#define BQ32002_DATE_MASK GENMASK(5, 0) +#define BQ32002_MONTH_MASK GENMASK(4, 0) +#define BQ32002_YEAR_MASK GENMASK(7, 0) +#define BQ32002_CAL_MASK GENMASK(4, 0) + +#define BQ32002_OSC_STOP_MASK BIT(7) +#define BQ32002_OSC_FAIL_MASK BIT(7) +#define BQ32002_CENT_EN_MASK BIT(7) +#define BQ32002_CENT_MASK BIT(6) +#define BQ32002_OUT_MASK BIT(7) +#define BQ32002_FREQ_TEST_MASK BIT(6) +#define BQ32002_CAL_SIGN_MASK BIT(5) +#define BQ32002_FTF_MASK BIT(0) + +/* Keys to unlock special function register */ +#define BQ32002_SF_KEY_1 0x5E +#define BQ32002_SF_KEY_2 0xC7 + +/* BQ32002 counts weekdays from 1 to 7 */ +#define BQ32002_DAY_OFFSET -1 + +/* BQ32002 counts months from 1 to 12 */ +#define BQ32002_MONTH_OFFSET -1 + +/* Year 2000 value represented as tm_year value */ +#define BQ32002_TM_YEAR_2000 (2000 - 1900) + +/* Calibration constants, see BQ32002 datasheet, Table 12, p.16 */ +#define BQ32002_CAL_PPB_PER_LSB_POS 2034 /* 1e9 / 491520 */ +#define BQ32002_CAL_PPB_PER_LSB_NEG 4069 /* 1e9 / 245760 */ +#define BQ32002_CAL_PPB_MIN (-31 * BQ32002_CAL_PPB_PER_LSB_POS) +#define BQ32002_CAL_PPB_MAX (31 * BQ32002_CAL_PPB_PER_LSB_NEG) + +/* IRQ frequency property enum values */ +#define BQ32002_IRQ_FREQ_ENUM_1HZ 0 +#define BQ32002_IRQ_FREQ_ENUM_512HZ 1 +#define BQ32002_IRQ_FREQ_ENUM_DISABLED 2 + +/* RTC time fields supported by BQ32002 */ +#define BQ32002_RTC_TIME_MASK \ + (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_YEAR | \ + RTC_ALARM_TIME_MASK_WEEKDAY) + +struct bq32002_config { + struct i2c_dt_spec i2c; + uint8_t irq_freq; +}; + +struct bq32002_data { + struct k_sem lock; +}; + +static void bq32002_lock_sem(const struct device *dev) +{ + struct bq32002_data *data = dev->data; + + (void)k_sem_take(&data->lock, K_FOREVER); +} + +static void bq32002_unlock_sem(const struct device *dev) +{ + struct bq32002_data *data = dev->data; + + k_sem_give(&data->lock); +} + +static int bq32002_set_irq_frequency(const struct device *dev) +{ + const struct bq32002_config *config = dev->config; + uint8_t sf_regs[3]; + uint8_t cfg1_val; + uint8_t cfg2_val; + int err; + + switch (config->irq_freq) { + case BQ32002_IRQ_FREQ_ENUM_1HZ: + cfg1_val = BQ32002_FREQ_TEST_MASK; + cfg2_val = BQ32002_FTF_MASK; + break; + case BQ32002_IRQ_FREQ_ENUM_512HZ: + cfg1_val = BQ32002_FREQ_TEST_MASK; + cfg2_val = 0; + break; + default: + cfg1_val = BQ32002_OUT_MASK; + cfg2_val = 0; + break; + } + + err = i2c_reg_update_byte_dt(&config->i2c, BQ32002_CAL_CFG1_REG, BQ32002_FREQ_TEST_MASK, + cfg1_val); + if (err) { + return err; + } + + /* Update FTF value if frequency output enabled */ + if (cfg1_val & BQ32002_FREQ_TEST_MASK) { + sf_regs[0] = BQ32002_SF_KEY_1; + sf_regs[1] = BQ32002_SF_KEY_2; + sf_regs[2] = cfg2_val; + err = i2c_burst_write_dt(&config->i2c, BQ32002_SF_KEY_1_REG, sf_regs, + sizeof(sf_regs)); + if (err) { + return err; + } + } + + return 0; +} + +static int bq32002_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + const struct bq32002_config *config = dev->config; + int err; + uint8_t regs[7]; + + if ((timeptr == NULL) || !rtc_utils_validate_rtc_time(timeptr, BQ32002_RTC_TIME_MASK)) { + return -EINVAL; + } + + bq32002_lock_sem(dev); + + /* Update the registers */ + regs[0] = bin2bcd(timeptr->tm_sec) & BQ32002_SECONDS_MASK; + regs[1] = bin2bcd(timeptr->tm_min) & BQ32002_MINUTES_MASK; /* Clear oscillator fail flag */ + regs[2] = (bin2bcd(timeptr->tm_hour) & BQ32002_HOURS_MASK) | BQ32002_CENT_EN_MASK; + regs[3] = bin2bcd(timeptr->tm_wday - BQ32002_DAY_OFFSET) & BQ32002_DAY_MASK; + regs[4] = bin2bcd(timeptr->tm_mday) & BQ32002_DATE_MASK; + regs[5] = bin2bcd(timeptr->tm_mon - BQ32002_MONTH_OFFSET) & BQ32002_MONTH_MASK; + + /* Determine which century we're in */ + if (timeptr->tm_year >= BQ32002_TM_YEAR_2000) { + regs[2] |= BQ32002_CENT_MASK; + regs[6] = bin2bcd(timeptr->tm_year - BQ32002_TM_YEAR_2000) & BQ32002_YEAR_MASK; + } else { + regs[6] = bin2bcd(timeptr->tm_year) & BQ32002_YEAR_MASK; + } + + /* Write new time to the chip */ + err = i2c_burst_write_dt(&config->i2c, BQ32002_SECONDS_REG, regs, sizeof(regs)); + + bq32002_unlock_sem(dev); + + if (!err) { + LOG_DBG("Set time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, " + "minute: %d, second: %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + } + + return err; +} + +static int bq32002_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + const struct bq32002_config *config = dev->config; + int err; + uint8_t reg_val; + uint8_t regs[7]; + + if (timeptr == NULL) { + return -EINVAL; + } + + bq32002_lock_sem(dev); + + err = i2c_reg_read_byte_dt(&config->i2c, BQ32002_MINUTES_REG, ®_val); + if (err) { + goto out_unlock; + } + + /* Oscillator failure detected, data might be invalid */ + if (reg_val & BQ32002_OSC_FAIL_MASK) { + err = -ENODATA; + goto out_unlock; + } + + err = i2c_burst_read_dt(&config->i2c, BQ32002_SECONDS_REG, regs, sizeof(regs)); + if (err) { + goto out_unlock; + } + + timeptr->tm_sec = bcd2bin(regs[0] & BQ32002_SECONDS_MASK); + timeptr->tm_min = bcd2bin(regs[1] & BQ32002_MINUTES_MASK); + timeptr->tm_hour = bcd2bin(regs[2] & BQ32002_HOURS_MASK); + timeptr->tm_wday = bcd2bin(regs[3] & BQ32002_DAY_MASK) + BQ32002_DAY_OFFSET; + timeptr->tm_mday = bcd2bin(regs[4] & BQ32002_DATE_MASK); + timeptr->tm_mon = bcd2bin(regs[5] & BQ32002_MONTH_MASK) + BQ32002_MONTH_OFFSET; + timeptr->tm_year = bcd2bin(regs[6] & BQ32002_YEAR_MASK); + timeptr->tm_yday = -1; /* Unsupported */ + timeptr->tm_isdst = -1; /* Unsupported */ + timeptr->tm_nsec = 0; /* Unsupported */ + + /* Apply century offset */ + if (regs[2] & BQ32002_CENT_MASK) { + timeptr->tm_year += BQ32002_TM_YEAR_2000; + } + +out_unlock: + bq32002_unlock_sem(dev); + + if (!err) { + LOG_DBG("Read time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, " + "minute: " + "%d, second: %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + } + + return err; +} + +#ifdef CONFIG_RTC_CALIBRATION + +static int bq32002_set_calibration(const struct device *dev, int32_t freq_ppb) +{ + const struct bq32002_config *config = dev->config; + int err; + uint8_t offset; + uint8_t reg_val; + + if ((freq_ppb < BQ32002_CAL_PPB_MIN) || (freq_ppb > BQ32002_CAL_PPB_MAX)) { + LOG_ERR("Calibration value %d ppb out of range", freq_ppb); + return -EINVAL; + } + + err = i2c_reg_read_byte_dt(&config->i2c, BQ32002_CAL_CFG1_REG, ®_val); + if (err) { + return err; + } + + reg_val &= ~(BQ32002_CAL_SIGN_MASK | BQ32002_CAL_MASK); + + if (freq_ppb > 0) { + reg_val |= BQ32002_CAL_SIGN_MASK; /* Negative sign speeds the oscillator up */ + offset = + DIV_ROUND_CLOSEST(freq_ppb, BQ32002_CAL_PPB_PER_LSB_NEG) & BQ32002_CAL_MASK; + } else { + offset = DIV_ROUND_CLOSEST(-freq_ppb, BQ32002_CAL_PPB_PER_LSB_POS) & + BQ32002_CAL_MASK; + } + reg_val |= offset; + + err = i2c_reg_write_byte_dt(&config->i2c, BQ32002_CAL_CFG1_REG, reg_val); + if (err) { + return err; + } + + LOG_DBG("Set calibration: frequency ppb: %d, offset value: %d, sign: %d", freq_ppb, offset, + freq_ppb > 0); + + return 0; +} + +static int bq32002_get_calibration(const struct device *dev, int32_t *freq_ppb) +{ + const struct bq32002_config *config = dev->config; + uint8_t reg_val; + uint8_t offset; + int err; + + err = i2c_reg_read_byte_dt(&config->i2c, BQ32002_CAL_CFG1_REG, ®_val); + if (err) { + return err; + } + + offset = reg_val & BQ32002_CAL_MASK; + + if (reg_val & BQ32002_CAL_SIGN_MASK) { + *freq_ppb = offset * BQ32002_CAL_PPB_PER_LSB_NEG; + } else { + *freq_ppb = -offset * BQ32002_CAL_PPB_PER_LSB_POS; + } + + LOG_DBG("Get calibration: frequency ppb: %d, offset value: %d, sign: %d", *freq_ppb, offset, + *freq_ppb > 0); + + return 0; +} + +#endif + +static DEVICE_API(rtc, bq32002_driver_api) = { + .set_time = bq32002_set_time, + .get_time = bq32002_get_time, +#ifdef CONFIG_RTC_CALIBRATION + .set_calibration = bq32002_set_calibration, + .get_calibration = bq32002_get_calibration +#endif +}; + +static int bq32002_init(const struct device *dev) +{ + const struct bq32002_config *config = dev->config; + struct bq32002_data *data = dev->data; + int err; + + (void)k_sem_init(&data->lock, 1, 1); + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C bus not ready"); + return -ENODEV; + } + + /* Start the oscillator */ + err = i2c_reg_update_byte_dt(&config->i2c, BQ32002_SECONDS_REG, BQ32002_OSC_STOP_MASK, 0); + if (err) { + return err; + } + + /* Configure IRQ output frequency */ + err = bq32002_set_irq_frequency(dev); + if (err) { + return err; + } + + return 0; +} + +#define BQ32002_INIT(inst) \ + static struct bq32002_data bq32002_data_##inst; \ + static const struct bq32002_config bq32002_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .irq_freq = \ + DT_INST_ENUM_IDX_OR(inst, irq_frequency, BQ32002_IRQ_FREQ_ENUM_DISABLED) \ + }; \ + DEVICE_DT_INST_DEFINE(inst, &bq32002_init, NULL, &bq32002_data_##inst, \ + &bq32002_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \ + &bq32002_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BQ32002_INIT) diff --git a/drivers/rtc/rtc_ds1307.c b/drivers/rtc/rtc_ds1307.c index 48b934102cd9a..b5685cddd1300 100644 --- a/drivers/rtc/rtc_ds1307.c +++ b/drivers/rtc/rtc_ds1307.c @@ -3,6 +3,8 @@ * * Copyright (c) 2023 Arunmani Alagarsamy * Author: Arunmani Alagarsamy + * + * Copyright (c) 2025 Marcin Lyda */ #include @@ -25,6 +27,7 @@ LOG_MODULE_REGISTER(ds1307, CONFIG_RTC_LOG_LEVEL); #define DS1307_REG_YEAR 0x06 #define DS1307_REG_CTRL 0x07 +/* DS1307 bitmasks */ #define SECONDS_BITS GENMASK(6, 0) #define MINUTES_BITS GENMASK(7, 0) #define HOURS_BITS GENMASK(5, 0) @@ -34,8 +37,24 @@ LOG_MODULE_REGISTER(ds1307, CONFIG_RTC_LOG_LEVEL); #define YEAR_BITS GENMASK(7, 0) #define VALIDATE_24HR BIT(6) +#define CTRL_RS_BITS GENMASK(1, 0) +#define CTRL_SQWE_BIT BIT(4) + +#define SQW_FREQ_1Hz FIELD_PREP(CTRL_RS_BITS, 0x00) +#define SQW_FREQ_4096Hz FIELD_PREP(CTRL_RS_BITS, 0x01) +#define SQW_FREQ_8192Hz FIELD_PREP(CTRL_RS_BITS, 0x02) +#define SQW_FREQ_32768Hz FIELD_PREP(CTRL_RS_BITS, 0x03) + +/* SQW frequency property enum values */ +#define SQW_PROP_ENUM_1HZ 0 +#define SQW_PROP_ENUM_4096HZ 1 +#define SQW_PROP_ENUM_8192HZ 2 +#define SQW_PROP_ENUM_32768HZ 3 +#define SQW_PROP_ENUM_DISABLED 4 + struct ds1307_config { struct i2c_dt_spec i2c_bus; + uint8_t sqw_freq; }; struct ds1307_data { @@ -126,6 +145,7 @@ static DEVICE_API(rtc, ds1307_driver_api) = { static int ds1307_init(const struct device *dev) { int err; + uint8_t reg_val; const struct ds1307_config *config = dev->config; if (!i2c_is_ready_dt(&config->i2c_bus)) { @@ -133,25 +153,42 @@ static int ds1307_init(const struct device *dev) return -ENODEV; } - /* Disable squarewave output */ - err = i2c_reg_write_byte_dt(&config->i2c_bus, DS1307_REG_CTRL, 0x00); + /* Configure SQW output frequency */ + reg_val = CTRL_SQWE_BIT; + switch (config->sqw_freq) { + case SQW_PROP_ENUM_1HZ: + reg_val |= SQW_FREQ_1Hz; + break; + case SQW_PROP_ENUM_4096HZ: + reg_val |= SQW_FREQ_4096Hz; + break; + case SQW_PROP_ENUM_8192HZ: + reg_val |= SQW_FREQ_8192Hz; + break; + case SQW_PROP_ENUM_32768HZ: + reg_val |= SQW_FREQ_32768Hz; + break; + case SQW_PROP_ENUM_DISABLED: + default: + reg_val &= ~CTRL_SQWE_BIT; + break; + } + err = i2c_reg_write_byte_dt(&config->i2c_bus, DS1307_REG_CTRL, reg_val); if (err < 0) { - LOG_ERR("Error: SQW: %d\n", err); + LOG_ERR("Error: Configure SQW: %d", err); } /* Ensure Clock Halt = 0 */ - uint8_t reg = 0; - - err = i2c_reg_read_byte_dt(&config->i2c_bus, DS1307_REG_SECONDS, ®); + err = i2c_reg_read_byte_dt(&config->i2c_bus, DS1307_REG_SECONDS, ®_val); if (err < 0) { - LOG_ERR("Error: Read SECONDS/Clock Halt register: %d\n", err); + LOG_ERR("Error: Read SECONDS/Clock Halt register: %d", err); } - if (reg & ~SECONDS_BITS) { + if (reg_val & ~SECONDS_BITS) { /* Clock Halt bit is set */ err = i2c_reg_write_byte_dt(&config->i2c_bus, DS1307_REG_SECONDS, - reg & SECONDS_BITS); + reg_val & SECONDS_BITS); if (err < 0) { - LOG_ERR("Error: Clear Clock Halt bit: %d\n", err); + LOG_ERR("Error: Clear Clock Halt bit: %d", err); } } @@ -162,7 +199,8 @@ static int ds1307_init(const struct device *dev) static struct ds1307_data ds1307_data_##inst; \ static const struct ds1307_config ds1307_config_##inst = { \ .i2c_bus = I2C_DT_SPEC_INST_GET(inst), \ - }; \ + .sqw_freq = DT_INST_ENUM_IDX_OR(inst, sqw_frequency, SQW_PROP_ENUM_DISABLED) \ + }; \ DEVICE_DT_INST_DEFINE(inst, &ds1307_init, NULL, &ds1307_data_##inst, \ &ds1307_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \ &ds1307_driver_api); diff --git a/drivers/rtc/rtc_ds1337.c b/drivers/rtc/rtc_ds1337.c new file mode 100644 index 0000000000000..209f5086d1c82 --- /dev/null +++ b/drivers/rtc/rtc_ds1337.c @@ -0,0 +1,737 @@ +/* + * Copyright (c) 2025 Marcin Lyda + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include "rtc_utils.h" + +LOG_MODULE_REGISTER(ds1337, CONFIG_RTC_LOG_LEVEL); + +#define DT_DRV_COMPAT maxim_ds1337 + +#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 +#warning "Maxim DS1337 RTC driver enabled without any devices" +#endif + +/* Registers */ +#define DS1337_SECONDS_REG 0x00 +#define DS1337_ALARM_1_SECONDS_REG 0x07 +#define DS1337_ALARM_2_MINUTES_REG 0x0B +#define DS1337_CONTROL_REG 0x0E +#define DS1337_STATUS_REG 0x0F + +/* Bitmasks */ +#define DS1337_SECONDS_MASK GENMASK(6, 0) +#define DS1337_MINUTES_MASK GENMASK(6, 0) +#define DS1337_HOURS_MASK GENMASK(5, 0) +#define DS1337_DAY_MASK GENMASK(2, 0) +#define DS1337_DATE_MASK GENMASK(5, 0) +#define DS1337_MONTH_MASK GENMASK(4, 0) +#define DS1337_YEAR_MASK GENMASK(7, 0) +#define DS1337_ALARM_SECONDS_MASK GENMASK(6, 0) +#define DS1337_ALARM_MINUTES_MASK GENMASK(6, 0) +#define DS1337_ALARM_HOURS_MASK GENMASK(5, 0) +#define DS1337_ALARM_DAY_MASK GENMASK(3, 0) +#define DS1337_ALARM_DATE_MASK GENMASK(5, 0) + +#define DS1337_12_24_MODE_MASK BIT(6) +#define DS1337_CENTURY_MASK BIT(7) +#define DS1337_DY_DT_MASK BIT(6) + +#define DS1337_ALARM_DISABLE_MASK BIT(7) + +#define DS1337_EOSC_MASK BIT(7) +#define DS1337_RS_MASK GENMASK(4, 3) +#define DS1337_INTCN_MASK BIT(2) +#define DS1337_A2IE_MASK BIT(1) +#define DS1337_A1IE_MASK BIT(0) + +#define DS1337_OSF_MASK BIT(7) +#define DS1337_A2F_MASK BIT(1) +#define DS1337_A1F_MASK BIT(0) + +#define DS1337_SQW_FREQ_1Hz FIELD_PREP(DS1337_RS_MASK, 0x00) +#define DS1337_SQW_FREQ_4096Hz FIELD_PREP(DS1337_RS_MASK, 0x01) +#define DS1337_SQW_FREQ_8192Hz FIELD_PREP(DS1337_RS_MASK, 0x02) +#define DS1337_SQW_FREQ_32768Hz FIELD_PREP(DS1337_RS_MASK, 0x03) + +/* DS1337 features two independent alarms */ +#define DS1337_ALARM_1_ID 0 +#define DS1337_ALARM_2_ID 1 +#define DS1337_ALARMS_COUNT 2 + +/* SQW frequency property enum values */ +#define DS1337_SQW_PROP_ENUM_1HZ 0 +#define DS1337_SQW_PROP_ENUM_4096HZ 1 +#define DS1337_SQW_PROP_ENUM_8192HZ 2 +#define DS1337_SQW_PROP_ENUM_32768HZ 3 + +/* DS1337 counts weekdays from 1 to 7 */ +#define DS1337_DAY_OFFSET -1 + +/* DS1337 counts months 1 to 12 */ +#define DS1337_MONTH_OFFSET -1 + +/* Year 2000 value represented as tm_year value */ +#define DS1337_TM_YEAR_2000 (2000 - 1900) + +/* RTC time fields supported by DS1337 */ +#define DS1337_RTC_TIME_MASK \ + (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_YEAR | \ + RTC_ALARM_TIME_MASK_WEEKDAY) + +/* RTC alarm 1 fields supported by DS1337 */ +#define DS1337_RTC_ALARM_TIME_1_MASK \ + (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_WEEKDAY) + +/* RTC alarm 2 fields supported by DS1337 */ +#define DS1337_RTC_ALARM_TIME_2_MASK \ + (RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MONTHDAY | \ + RTC_ALARM_TIME_MASK_WEEKDAY) + +/* Helper macro to guard GPIO interrupt related stuff */ +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) && defined(CONFIG_RTC_ALARM) +#define DS1337_INT_GPIOS_IN_USE 1 +#endif + +struct ds1337_config { + const struct i2c_dt_spec i2c; +#ifdef DS1337_INT_GPIOS_IN_USE + struct gpio_dt_spec gpio_int; +#endif + uint8_t sqw_freq; +}; + +struct ds1337_data { + struct k_sem lock; +#ifdef DS1337_INT_GPIOS_IN_USE + const struct device *dev; + struct gpio_callback irq_callback; + struct k_work work; +#ifdef CONFIG_RTC_ALARM + rtc_alarm_callback alarm_callbacks[DS1337_ALARMS_COUNT]; + void *alarm_user_data[DS1337_ALARMS_COUNT]; +#endif +#endif +}; + +static void ds1337_lock_sem(const struct device *dev) +{ + struct ds1337_data *data = dev->data; + + (void)k_sem_take(&data->lock, K_FOREVER); +} + +static void ds1337_unlock_sem(const struct device *dev) +{ + struct ds1337_data *data = dev->data; + + k_sem_give(&data->lock); +} + +static bool ds1337_validate_alarm_mask(uint16_t alarm_mask, uint16_t alarm_id) +{ + const uint16_t allowed_configs[6] = { + 0, + RTC_ALARM_TIME_MASK_SECOND, + RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE, + RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR, + RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | + RTC_ALARM_TIME_MASK_WEEKDAY, + RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | + RTC_ALARM_TIME_MASK_MONTHDAY + }; + + const uint16_t available_fields = + (alarm_id == 0) ? DS1337_RTC_ALARM_TIME_1_MASK : DS1337_RTC_ALARM_TIME_2_MASK; + if (alarm_mask & ~available_fields) { + return false; + } + + ARRAY_FOR_EACH_PTR(allowed_configs, config) { + if (alarm_mask == (*config & available_fields)) { + return true; + } + } + return false; +} + +#ifdef DS1337_INT_GPIOS_IN_USE + +static void ds1337_work_callback(struct k_work *work) +{ + struct ds1337_data *data = CONTAINER_OF(work, struct ds1337_data, work); + const struct device *dev = data->dev; + const struct ds1337_config *config = dev->config; + rtc_alarm_callback alarm_callbacks[DS1337_ALARMS_COUNT] = {NULL}; + void *alarm_user_data[DS1337_ALARMS_COUNT] = {NULL}; + uint8_t status_reg; + int err; + + ds1337_lock_sem(dev); + + /* Read status register */ + err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &status_reg); + if (err) { + goto out_unlock; + } + +#ifdef CONFIG_RTC_ALARM + /* Handle alarm 1 event */ + if ((status_reg & DS1337_A1F_MASK) && (data->alarm_callbacks[DS1337_ALARM_1_ID] != NULL)) { + status_reg &= ~DS1337_A1F_MASK; + alarm_callbacks[DS1337_ALARM_1_ID] = data->alarm_callbacks[DS1337_ALARM_1_ID]; + alarm_user_data[DS1337_ALARM_1_ID] = data->alarm_user_data[DS1337_ALARM_1_ID]; + } + + /* Handle alarm 2 event */ + if ((status_reg & DS1337_A2F_MASK) && (data->alarm_callbacks[DS1337_ALARM_2_ID] != NULL)) { + status_reg &= ~DS1337_A2F_MASK; + alarm_callbacks[DS1337_ALARM_2_ID] = data->alarm_callbacks[DS1337_ALARM_2_ID]; + alarm_user_data[DS1337_ALARM_2_ID] = data->alarm_user_data[DS1337_ALARM_2_ID]; + } +#endif + + /* Clear alarm flag(s) */ + err = i2c_reg_write_byte_dt(&config->i2c, DS1337_STATUS_REG, status_reg); + if (err) { + goto out_unlock; + } + + /* Check if any interrupt occurred between flags register read/write */ + err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &status_reg); + if (err) { + goto out_unlock; + } + + if (((status_reg & DS1337_A1F_MASK) && (alarm_callbacks[0] != NULL)) || + ((status_reg & DS1337_A2F_MASK) && (alarm_callbacks[1] != NULL))) { + /* Another interrupt occurred while servicing this one */ + (void)k_work_submit(&data->work); + } + +out_unlock: + ds1337_unlock_sem(dev); + + /* Execute alarm callback(s) */ + for (uint8_t alarm_id = DS1337_ALARM_1_ID; alarm_id < DS1337_ALARMS_COUNT; ++alarm_id) { + if (alarm_callbacks[alarm_id] != NULL) { + alarm_callbacks[alarm_id](dev, alarm_id, alarm_user_data[alarm_id]); + alarm_callbacks[alarm_id] = NULL; + } + } +} + +static void ds1337_irq_handler(const struct device *port, struct gpio_callback *callback, + gpio_port_pins_t pins) +{ + ARG_UNUSED(port); + ARG_UNUSED(pins); + + struct ds1337_data *data = CONTAINER_OF(callback, struct ds1337_data, irq_callback); + + (void)k_work_submit(&data->work); +} + +#endif + +static int ds1337_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + const struct ds1337_config *config = dev->config; + uint8_t regs[7]; + int err; + + if ((timeptr == NULL) || !rtc_utils_validate_rtc_time(timeptr, DS1337_RTC_TIME_MASK)) { + return -EINVAL; + } + + ds1337_lock_sem(dev); + + regs[0] = bin2bcd(timeptr->tm_sec) & DS1337_SECONDS_MASK; + regs[1] = bin2bcd(timeptr->tm_min) & DS1337_MINUTES_MASK; + regs[2] = bin2bcd(timeptr->tm_hour) & DS1337_HOURS_MASK; + regs[3] = bin2bcd(timeptr->tm_wday - DS1337_DAY_OFFSET) & DS1337_DAY_MASK; + regs[4] = bin2bcd(timeptr->tm_mday) & DS1337_DATE_MASK; + regs[5] = bin2bcd(timeptr->tm_mon - DS1337_MONTH_OFFSET) & DS1337_MONTH_MASK; + + /* Determine which century we're in */ + if (timeptr->tm_year >= DS1337_TM_YEAR_2000) { + regs[5] |= DS1337_CENTURY_MASK; + regs[6] = bin2bcd(timeptr->tm_year - DS1337_TM_YEAR_2000) & DS1337_YEAR_MASK; + } else { + regs[6] = bin2bcd(timeptr->tm_year) & DS1337_YEAR_MASK; + } + + /* Set new time */ + err = i2c_burst_write_dt(&config->i2c, DS1337_SECONDS_REG, regs, sizeof(regs)); + if (err) { + goto out_unlock; + } + + /* Clear Oscillator Stop Flag, indicating data validity */ + err = i2c_reg_update_byte_dt(&config->i2c, DS1337_STATUS_REG, DS1337_OSF_MASK, 0); + +out_unlock: + ds1337_unlock_sem(dev); + + if (!err) { + LOG_DBG("Set time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, " + "minute: %d, second: %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + } + + return err; +} + +static int ds1337_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + const struct ds1337_config *config = dev->config; + uint8_t regs[7]; + uint8_t status_reg; + int err; + + if (timeptr == NULL) { + return -EINVAL; + } + + ds1337_lock_sem(dev); + + /* Check data validity */ + err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &status_reg); + if (err) { + goto out_unlock; + } + if (status_reg & DS1337_OSF_MASK) { + err = -ENODATA; + goto out_unlock; + } + + /* Read time data */ + err = i2c_burst_read_dt(&config->i2c, DS1337_SECONDS_REG, regs, sizeof(regs)); + if (err) { + goto out_unlock; + } + + timeptr->tm_sec = bcd2bin(regs[0] & DS1337_SECONDS_MASK); + timeptr->tm_min = bcd2bin(regs[1] & DS1337_MINUTES_MASK); + timeptr->tm_hour = bcd2bin(regs[2] & DS1337_HOURS_MASK); + timeptr->tm_wday = bcd2bin(regs[3] & DS1337_DAY_MASK) + DS1337_DAY_OFFSET; + timeptr->tm_mday = bcd2bin(regs[4] & DS1337_DATE_MASK); + timeptr->tm_mon = bcd2bin(regs[5] & DS1337_MONTH_MASK) + DS1337_MONTH_OFFSET; + timeptr->tm_year = bcd2bin(regs[6] & DS1337_YEAR_MASK); + timeptr->tm_yday = -1; /* Unsupported */ + timeptr->tm_isdst = -1; /* Unsupported */ + timeptr->tm_nsec = 0; /* Unsupported */ + + /* Apply century offset */ + if (regs[5] & DS1337_CENTURY_MASK) { + timeptr->tm_year += DS1337_TM_YEAR_2000; + } + +out_unlock: + ds1337_unlock_sem(dev); + + if (!err) { + LOG_DBG("Read time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, " + "minute: %d, second: %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + } + + return err; +} + +#ifdef CONFIG_RTC_ALARM + +static int ds1337_alarm_get_supported_fields(const struct device *dev, uint16_t id, uint16_t *mask) +{ + ARG_UNUSED(dev); + + if (id == DS1337_ALARM_1_ID) { + *mask = DS1337_RTC_ALARM_TIME_1_MASK; + return 0; + } else if (id == DS1337_ALARM_2_ID) { + *mask = DS1337_RTC_ALARM_TIME_2_MASK; + return 0; + } + + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; +} + +static int ds1337_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + const struct ds1337_config *config = dev->config; + uint8_t regs[4]; + uint8_t reg_addr; + uint8_t reg_offset; + int err; + + if (id >= DS1337_ALARMS_COUNT) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) && (mask & RTC_ALARM_TIME_MASK_WEEKDAY)) { + LOG_ERR("Month day and week day alarms cannot be set simultaneously"); + return -EINVAL; + } + + if (!ds1337_validate_alarm_mask(mask, id)) { + LOG_ERR("Unsupported mask 0x%04X for alarm %d", mask, id); + return -EINVAL; + } + + if (!rtc_utils_validate_rtc_time(timeptr, mask)) { + LOG_ERR("Invalid alarm time"); + return -EINVAL; + } + + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + regs[0] = bin2bcd(timeptr->tm_sec) & DS1337_ALARM_SECONDS_MASK; + } else { + regs[0] = DS1337_ALARM_DISABLE_MASK; + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + regs[1] = bin2bcd(timeptr->tm_min) & DS1337_ALARM_MINUTES_MASK; + } else { + regs[1] = DS1337_ALARM_DISABLE_MASK; + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + regs[2] = bin2bcd(timeptr->tm_hour) & DS1337_ALARM_HOURS_MASK; + } else { + regs[2] = DS1337_ALARM_DISABLE_MASK; + } + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + regs[3] = bin2bcd(timeptr->tm_mday) & DS1337_ALARM_DATE_MASK; + } else if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) { + regs[3] = bin2bcd(timeptr->tm_wday - DS1337_DAY_OFFSET) & DS1337_ALARM_DAY_MASK; + regs[3] |= DS1337_DY_DT_MASK; + } else { + regs[3] = DS1337_ALARM_DISABLE_MASK; + } + + /* Update alarm registers */ + if (id == DS1337_ALARM_1_ID) { + reg_addr = DS1337_ALARM_1_SECONDS_REG; + reg_offset = 0; + } else { + reg_addr = DS1337_ALARM_2_MINUTES_REG; + reg_offset = 1; + } + + err = i2c_burst_write_dt(&config->i2c, reg_addr, ®s[reg_offset], + sizeof(regs) - reg_offset); + if (err) { + return err; + } + + LOG_DBG("Set alarm: month day: %d, week day: %d, hour: %d, minute: %d, second: %d mask: " + "0x%04X", + timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour, timeptr->tm_min, + timeptr->tm_sec, mask); + + return 0; +} + +static int ds1337_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + const struct ds1337_config *config = dev->config; + uint8_t regs[4]; + uint8_t reg_addr; + uint8_t reg_offset; + int err; + + if (id >= DS1337_ALARMS_COUNT) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + /* Read alarm registers */ + if (id == DS1337_ALARM_1_ID) { + reg_addr = DS1337_ALARM_1_SECONDS_REG; + reg_offset = 0; + } else { + reg_addr = DS1337_ALARM_2_MINUTES_REG; + reg_offset = 1; + } + err = i2c_burst_read_dt(&config->i2c, reg_addr, ®s[reg_offset], + sizeof(regs) - reg_offset); + if (err) { + return err; + } + + (void)memset(timeptr, 0, sizeof(*timeptr)); + *mask = 0; + + if ((regs[0] & DS1337_ALARM_DISABLE_MASK) == 0) { + timeptr->tm_sec = bcd2bin(regs[0] & DS1337_ALARM_SECONDS_MASK); + *mask |= RTC_ALARM_TIME_MASK_SECOND; + } + + if ((regs[1] & DS1337_ALARM_DISABLE_MASK) == 0) { + timeptr->tm_min = bcd2bin(regs[1] & DS1337_ALARM_MINUTES_MASK); + *mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + + if ((regs[2] & DS1337_ALARM_DISABLE_MASK) == 0) { + timeptr->tm_hour = bcd2bin(regs[2] & DS1337_ALARM_HOURS_MASK); + *mask |= RTC_ALARM_TIME_MASK_HOUR; + } + + if ((regs[3] & DS1337_ALARM_DISABLE_MASK) == 0) { + if ((regs[3] & DS1337_DY_DT_MASK) == 0) { + timeptr->tm_mday = bcd2bin(regs[3] & DS1337_ALARM_DATE_MASK); + *mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } else { + timeptr->tm_wday = + bcd2bin(regs[3] & DS1337_ALARM_DAY_MASK) + DS1337_DAY_OFFSET; + *mask |= RTC_ALARM_TIME_MASK_WEEKDAY; + } + } + + LOG_DBG("Get alarm: month day: %d, week day: %d, hour: %d, minute: %d, second: %d mask: " + "0x%04X", + timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour, timeptr->tm_min, + timeptr->tm_sec, *mask); + + return 0; +} + +static int ds1337_alarm_is_pending(const struct device *dev, uint16_t id) +{ + const struct ds1337_config *config = dev->config; + uint8_t pending = 0; + uint8_t status_reg; + int err; + + if (id >= DS1337_ALARMS_COUNT) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + ds1337_lock_sem(dev); + + err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, &status_reg); + if (err) { + goto out_unlock; + } + + if (id == DS1337_ALARM_1_ID) { + if (status_reg & DS1337_A1F_MASK) { + status_reg &= ~DS1337_A1F_MASK; + pending = 1; + } + } else { + if (status_reg & DS1337_A2F_MASK) { + status_reg &= ~DS1337_A2F_MASK; + pending = 1; + } + } + + err = i2c_reg_write_byte_dt(&config->i2c, DS1337_STATUS_REG, status_reg); + if (err) { + goto out_unlock; + } + +out_unlock: + ds1337_unlock_sem(dev); + + if (err) { + return err; + } + return pending; +} + +#ifdef DS1337_INT_GPIOS_IN_USE + +static int ds1337_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + const struct ds1337_config *config = dev->config; + struct ds1337_data *data = dev->data; + uint8_t reg_val = 0; + uint8_t mask = 0; + int err; + + if (config->gpio_int.port == NULL) { + return -ENOTSUP; + } + + if (id >= DS1337_ALARMS_COUNT) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + ds1337_lock_sem(dev); + + data->alarm_callbacks[id] = callback; + data->alarm_user_data[id] = user_data; + + /* Enable alarm interrupt if callback provided */ + if (id == DS1337_ALARM_1_ID) { + mask = DS1337_A1IE_MASK; + reg_val = (callback != NULL) ? DS1337_A1IE_MASK : 0; + } else { + mask = DS1337_A2IE_MASK; + reg_val = (callback != NULL) ? DS1337_A2IE_MASK : 0; + } + err = i2c_reg_update_byte_dt(&config->i2c, DS1337_CONTROL_REG, mask, reg_val); + + ds1337_unlock_sem(dev); + + /* Alarm IRQ might have already been triggered */ + (void)k_work_submit(&data->work); + + return err; +} + +#endif + +#endif + +static int ds1337_init(const struct device *dev) +{ + const struct ds1337_config *config = dev->config; + struct ds1337_data *data = dev->data; + uint8_t reg_val; + int err; + + (void)k_sem_init(&data->lock, 1, 1); + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C bus not ready"); + return -ENODEV; + } + +#ifdef DS1337_INT_GPIOS_IN_USE + if (config->gpio_int.port != NULL) { + if (!gpio_is_ready_dt(&config->gpio_int)) { + LOG_ERR("GPIO not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT); + if (err) { + LOG_ERR("Failed to configure interrupt GPIO, error: %d", err); + return err; + } + + err = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + if (err) { + LOG_ERR("Failed to enable GPIO interrupt, error: %d", err); + return err; + } + + gpio_init_callback(&data->irq_callback, ds1337_irq_handler, + BIT(config->gpio_int.pin)); + + err = gpio_add_callback_dt(&config->gpio_int, &data->irq_callback); + if (err) { + LOG_ERR("Failed to add GPIO callback, error: %d", err); + return err; + } + + data->dev = dev; + data->work.handler = ds1337_work_callback; + } +#endif + + /* Display warning if alarm flags are set */ + err = i2c_reg_read_byte_dt(&config->i2c, DS1337_STATUS_REG, ®_val); + if (err) { + return err; + } + if (reg_val & DS1337_A1F_MASK) { + LOG_WRN("Alarm 1 might have been missed!"); + } + if (reg_val & DS1337_A2F_MASK) { + LOG_WRN("Alarm 2 might have been missed!"); + } + + /* Enable oscillator */ + err = i2c_reg_update_byte_dt(&config->i2c, DS1337_CONTROL_REG, DS1337_EOSC_MASK, 0); + if (err) { + return err; + } + + /* Configure SQW output frequency */ + switch (config->sqw_freq) { + case DS1337_SQW_PROP_ENUM_1HZ: + reg_val = DS1337_SQW_FREQ_1Hz; + break; + case DS1337_SQW_PROP_ENUM_4096HZ: + reg_val = DS1337_SQW_FREQ_4096Hz; + break; + case DS1337_SQW_PROP_ENUM_8192HZ: + reg_val = DS1337_SQW_FREQ_8192Hz; + break; + case DS1337_SQW_PROP_ENUM_32768HZ: + default: + reg_val = DS1337_SQW_FREQ_32768Hz; + break; + } + + /* + * Set SQW frequency, enable oscillator, clear INTCN (both alarms will trigger INTA), + * disable IRQs + */ + err = i2c_reg_write_byte_dt(&config->i2c, DS1337_CONTROL_REG, reg_val); + if (err) { + return err; + } + + /* Clear alarm flags */ + err = i2c_reg_update_byte_dt(&config->i2c, DS1337_STATUS_REG, + DS1337_A1F_MASK | DS1337_A2F_MASK, 0); + if (err) { + return err; + } + + return 0; +} + +static DEVICE_API(rtc, ds1337_driver_api) = { + .get_time = ds1337_get_time, + .set_time = ds1337_set_time, +#ifdef CONFIG_RTC_ALARM + .alarm_get_supported_fields = ds1337_alarm_get_supported_fields, + .alarm_set_time = ds1337_alarm_set_time, + .alarm_get_time = ds1337_alarm_get_time, + .alarm_is_pending = ds1337_alarm_is_pending, +#ifdef DS1337_INT_GPIOS_IN_USE + .alarm_set_callback = ds1337_alarm_set_callback, +#endif +#endif +}; + +#define DS1337_INIT(inst) \ + static struct ds1337_data ds1337_data_##inst; \ + static const struct ds1337_config ds1337_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .sqw_freq = DT_INST_ENUM_IDX_OR(inst, sqw_frequency, DS1337_SQW_PROP_ENUM_1HZ), \ + IF_ENABLED( \ + DS1337_INT_GPIOS_IN_USE, \ + (.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0})) \ + ) \ + }; \ + DEVICE_DT_INST_DEFINE(inst, &ds1337_init, NULL, &ds1337_data_##inst, \ + &ds1337_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \ + &ds1337_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DS1337_INIT) diff --git a/drivers/rtc/rtc_ds3231.c b/drivers/rtc/rtc_ds3231.c new file mode 100644 index 0000000000000..3d149fec00714 --- /dev/null +++ b/drivers/rtc/rtc_ds3231.c @@ -0,0 +1,862 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Gergo Vari + */ + +/* TODO: implement user mode? */ +/* TODO: implement aging offset with calibration */ +/* TODO: handle century bit, external storage? */ + +#include +#include + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(RTC_DS3231, CONFIG_RTC_LOG_LEVEL); + +#include + +#define DT_DRV_COMPAT maxim_ds3231_rtc + +#ifdef CONFIG_RTC_ALARM +#define ALARM_COUNT 2 +struct rtc_ds3231_alarm { + rtc_alarm_callback cb; + void *user_data; +}; +#endif + +#ifdef CONFIG_RTC_UPDATE +struct rtc_ds3231_update { + rtc_update_callback cb; + void *user_data; +}; +#endif + +struct rtc_ds3231_data { +#ifdef CONFIG_RTC_ALARM + struct rtc_ds3231_alarm alarms[ALARM_COUNT]; +#endif +#ifdef CONFIG_RTC_UPDATE + struct rtc_ds3231_update update; +#endif + struct k_sem lock; + struct gpio_callback isw_cb_data; + struct k_work work; + const struct device *dev; +}; + +struct rtc_ds3231_conf { + const struct device *mfd; + struct gpio_dt_spec freq_32k_gpios; + struct gpio_dt_spec isw_gpios; +}; + +static int rtc_ds3231_modify_register(const struct device *dev, uint8_t reg, uint8_t *buf, + const uint8_t bitmask) +{ + int err; + const struct rtc_ds3231_conf *config = dev->config; + + if (bitmask != 255) { + uint8_t og_buf = 0; + + err = mfd_ds3231_i2c_get_registers(config->mfd, reg, &og_buf, 1); + if (err != 0) { + return err; + } + og_buf &= ~bitmask; + *buf &= bitmask; + og_buf |= *buf; + *buf = og_buf; + } + if (err != 0) { + return err; + } + err = mfd_ds3231_i2c_set_registers(config->mfd, reg, buf, 1); + return err; +} + +enum rtc_ds3231_freq { + FREQ_1000, + FREQ_1024, + FREQ_4096, + FREQ_8192 +}; +struct rtc_ds3231_ctrl { + bool en_osc; + + bool conv; + + enum rtc_ds3231_freq sqw_freq; + + bool intctrl; + bool en_alarm_1; + bool en_alarm_2; +}; +static int rtc_ds3231_ctrl_to_buf(const struct rtc_ds3231_ctrl *ctrl, uint8_t *buf) +{ + if (ctrl->en_alarm_1) { + *buf |= DS3231_BITS_CTRL_ALARM_1_EN; + } + + if (ctrl->en_alarm_2) { + *buf |= DS3231_BITS_CTRL_ALARM_2_EN; + } + + switch (ctrl->sqw_freq) { + case FREQ_1000: + break; + case FREQ_1024: + *buf |= DS3231_BITS_CTRL_RS1; + break; + case FREQ_4096: + *buf |= DS3231_BITS_CTRL_RS2; + break; + case FREQ_8192: + *buf |= DS3231_BITS_CTRL_RS1; + *buf |= DS3231_BITS_CTRL_RS2; + break; + } + if (ctrl->intctrl) { + *buf |= DS3231_BITS_CTRL_INTCTRL; + } else { /* enable sqw */ + *buf |= DS3231_BITS_CTRL_BBSQW; + } + + if (ctrl->conv) { + *buf |= DS3231_BITS_CTRL_CONV; + } + + if (!ctrl->en_osc) { /* active low */ + *buf |= DS3231_BITS_CTRL_EOSC; + } + return 0; +} +static int rtc_ds3231_modify_ctrl(const struct device *dev, const struct rtc_ds3231_ctrl *ctrl, + const uint8_t bitmask) +{ + uint8_t reg = DS3231_REG_CTRL; + uint8_t buf = 0; + + int err = rtc_ds3231_ctrl_to_buf(ctrl, &buf); + + if (err != 0) { + return err; + } + + return rtc_ds3231_modify_register(dev, reg, &buf, bitmask); +} + +struct rtc_ds3231_ctrl_sts { + bool osf; + bool en_32khz; + bool bsy; + bool a1f; + bool a2f; +}; +static int rtc_ds3231_ctrl_sts_to_buf(const struct rtc_ds3231_ctrl_sts *ctrl, uint8_t *buf) +{ + if (ctrl->a1f) { + *buf |= DS3231_BITS_CTRL_STS_ALARM_1_FLAG; + } + if (ctrl->a2f) { + *buf |= DS3231_BITS_CTRL_STS_ALARM_2_FLAG; + } + if (ctrl->osf) { + *buf |= DS3231_BITS_CTRL_STS_OSF; + } + if (ctrl->en_32khz) { + *buf |= DS3231_BITS_CTRL_STS_32_EN; + } + if (ctrl->bsy) { + *buf |= DS3231_BITS_CTRL_STS_BSY; + } + return 0; +} +static int rtc_ds3231_modify_ctrl_sts(const struct device *dev, + const struct rtc_ds3231_ctrl_sts *ctrl, const uint8_t bitmask) +{ + const uint8_t reg = DS3231_REG_CTRL_STS; + uint8_t buf = 0; + + int err = rtc_ds3231_ctrl_sts_to_buf(ctrl, &buf); + + if (err != 0) { + return err; + } + + return rtc_ds3231_modify_register(dev, reg, &buf, bitmask); +} + +#ifdef CONFIG_RTC_ALARM +static int rtc_ds3231_get_ctrl_sts(const struct device *dev, uint8_t *buf) +{ + const struct rtc_ds3231_conf *config = dev->config; + + return mfd_ds3231_i2c_get_registers(config->mfd, DS3231_REG_CTRL_STS, buf, 1); +} +#endif /* CONFIG_RTC_ALARM */ + +struct rtc_ds3231_settings { + bool osc; /* bit 0 */ + bool intctrl_or_sqw; /* bit 1 */ + enum rtc_ds3231_freq freq_sqw; /* bit 2 */ + bool freq_32khz; /* bit 3 */ + bool alarm_1; /* bit 4 */ + bool alarm_2; /* bit 5 */ +}; +static int rtc_ds3231_modify_settings(const struct device *dev, struct rtc_ds3231_settings *conf, + uint8_t mask) +{ + struct rtc_ds3231_ctrl ctrl = {}; + uint8_t ctrl_mask = 0; + + struct rtc_ds3231_ctrl_sts ctrl_sts = {}; + uint8_t ctrl_sts_mask = 0; + + if (mask & DS3231_BITS_STS_OSC) { + ctrl.en_osc = conf->osc; + ctrl_mask |= DS3231_BITS_CTRL_EOSC; + } + if (mask & DS3231_BITS_STS_INTCTRL) { + ctrl.intctrl = !conf->intctrl_or_sqw; + ctrl_mask |= DS3231_BITS_CTRL_BBSQW; + } + if (mask & DS3231_BITS_STS_SQW) { + ctrl.sqw_freq = conf->freq_sqw; + ctrl_mask |= DS3231_BITS_CTRL_RS1; + ctrl_mask |= DS3231_BITS_CTRL_RS2; + } + if (mask & DS3231_BITS_STS_32KHZ) { + ctrl_sts.en_32khz = conf->freq_32khz; + ctrl_sts_mask |= DS3231_BITS_CTRL_STS_32_EN; + } + if (mask & DS3231_BITS_STS_ALARM_1) { + ctrl.en_alarm_1 = conf->alarm_1; + ctrl_mask |= DS3231_BITS_CTRL_ALARM_1_EN; + } + if (mask & DS3231_BITS_STS_ALARM_2) { + ctrl.en_alarm_2 = conf->alarm_2; + ctrl_mask |= DS3231_BITS_CTRL_ALARM_2_EN; + } + + ctrl.conv = false; + + int err = rtc_ds3231_modify_ctrl(dev, &ctrl, ctrl_mask); + + if (err != 0) { + LOG_ERR("Couldn't set control register."); + return -EIO; + } + err = rtc_ds3231_modify_ctrl_sts(dev, &ctrl_sts, ctrl_sts_mask); + if (err != 0) { + LOG_ERR("Couldn't set status register."); + return -EIO; + } + return 0; +} + +static int rtc_ds3231_rtc_time_to_buf(const struct rtc_time *tm, uint8_t *buf) +{ + buf[0] = bin2bcd(tm->tm_sec) & DS3231_BITS_TIME_SECONDS; + buf[1] = bin2bcd(tm->tm_min) & DS3231_BITS_TIME_MINUTES; + buf[2] = bin2bcd(tm->tm_hour) & DS3231_BITS_TIME_HOURS; + buf[3] = bin2bcd(tm->tm_wday) & DS3231_BITS_TIME_DAY_OF_WEEK; + buf[4] = bin2bcd(tm->tm_mday) & DS3231_BITS_TIME_DATE; + buf[5] = bin2bcd(tm->tm_mon) & DS3231_BITS_TIME_MONTH; + + /* here modulo 100 returns the last two digits of the year, + * as the DS3231 chip can only store year data for 0-99, + * hitting that ceiling can be detected with the century bit. + */ + + /* TODO: figure out a way to store the WHOLE year, not just the last 2 digits. */ + buf[6] = bin2bcd((tm->tm_year % 100)) & DS3231_BITS_TIME_YEAR; + return 0; +} +static int rtc_ds3231_set_time(const struct device *dev, const struct rtc_time *tm) +{ + const struct rtc_ds3231_conf *config = dev->config; + + int buf_size = 7; + uint8_t buf[buf_size]; + int err = rtc_ds3231_rtc_time_to_buf(tm, buf); + + if (err != 0) { + return err; + } + + return mfd_ds3231_i2c_set_registers(config->mfd, DS3231_REG_TIME_SECONDS, buf, buf_size); +} + +static void rtc_ds3231_reset_rtc_time(struct rtc_time *tm) +{ + tm->tm_sec = 0; + tm->tm_min = 0; + tm->tm_hour = 0; + tm->tm_wday = 0; + tm->tm_mday = 0; + tm->tm_mon = 0; + tm->tm_year = 0; + tm->tm_nsec = 0; + tm->tm_isdst = -1; + tm->tm_yday = -1; +} +static int rtc_ds3231_buf_to_rtc_time(const uint8_t *buf, struct rtc_time *timeptr) +{ + rtc_ds3231_reset_rtc_time(timeptr); + + timeptr->tm_sec = bcd2bin(buf[0] & DS3231_BITS_TIME_SECONDS); + timeptr->tm_min = bcd2bin(buf[1] & DS3231_BITS_TIME_MINUTES); + + int hour = buf[2] & DS3231_BITS_TIME_HOURS; + + if (hour & DS3231_BITS_TIME_12HR) { + bool pm = hour & DS3231_BITS_TIME_PM; + + hour &= ~DS3231_BITS_TIME_12HR; + hour &= ~DS3231_BITS_TIME_PM; + timeptr->tm_hour = bcd2bin(hour + 12 * pm); + } else { + timeptr->tm_hour = bcd2bin(hour); + } + + timeptr->tm_wday = bcd2bin(buf[3] & DS3231_BITS_TIME_DAY_OF_WEEK); + timeptr->tm_mday = bcd2bin(buf[4] & DS3231_BITS_TIME_DATE); + timeptr->tm_mon = bcd2bin(buf[5] & DS3231_BITS_TIME_MONTH); + timeptr->tm_year = bcd2bin(buf[6] & DS3231_BITS_TIME_YEAR); + + /* FIXME: we will always just set us to 20xx for year */ + timeptr->tm_year = timeptr->tm_year + 100; + + return 0; +} +static int rtc_ds3231_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + const struct rtc_ds3231_conf *config = dev->config; + + const size_t buf_size = 7; + uint8_t buf[buf_size]; + int err = mfd_ds3231_i2c_get_registers(config->mfd, DS3231_REG_TIME_SECONDS, buf, buf_size); + + if (err != 0) { + return err; + } + + return rtc_ds3231_buf_to_rtc_time(buf, timeptr); +} + +#ifdef CONFIG_RTC_ALARM +struct rtc_ds3231_alarm_details { + uint8_t start_reg; + size_t buf_size; +}; +static struct rtc_ds3231_alarm_details alarms[] = {{DS3231_REG_ALARM_1_SECONDS, 4}, + {DS3231_REG_ALARM_2_MINUTES, 3}}; +static int rtc_ds3231_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask) +{ + *mask = RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_WEEKDAY | + RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MINUTE; + + switch (id) { + case 0: + *mask |= RTC_ALARM_TIME_MASK_SECOND; + break; + case 1: + break; + default: + return -EINVAL; + } + + return 0; +} + +static int rtc_ds3231_rtc_time_to_alarm_buf(const struct rtc_time *tm, int id, const uint16_t mask, + uint8_t *buf) +{ + if ((mask & RTC_ALARM_TIME_MASK_WEEKDAY) && (mask & RTC_ALARM_TIME_MASK_MONTHDAY)) { + LOG_ERR("rtc_time_to_alarm_buf: Mask is invalid (%d)!\n", mask); + return -EINVAL; + } + if (id < 0 || id >= ALARM_COUNT) { + LOG_ERR("rtc_time_to_alarm_buf: Alarm ID is out of range (%d)!\n", id); + return -EINVAL; + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + buf[1] = bin2bcd(tm->tm_min) & DS3231_BITS_TIME_MINUTES; + } else { + buf[1] |= DS3231_BITS_ALARM_RATE; + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + buf[2] = bin2bcd(tm->tm_hour) & DS3231_BITS_TIME_HOURS; + } else { + buf[2] |= DS3231_BITS_ALARM_RATE; + } + + if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) { + buf[3] = bin2bcd(tm->tm_wday) & DS3231_BITS_TIME_DAY_OF_WEEK; + buf[3] |= DS3231_BITS_ALARM_DATE_W_OR_M; + } else if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + buf[3] = bin2bcd(tm->tm_mday) & DS3231_BITS_TIME_DATE; + } else { + buf[3] |= DS3231_BITS_ALARM_RATE; + } + + switch (id) { + case 0: + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + buf[0] = bin2bcd(tm->tm_sec) & DS3231_BITS_TIME_SECONDS; + } else { + buf[0] |= DS3231_BITS_ALARM_RATE; + } + break; + case 1: + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + return -EINVAL; + } + + for (int i = 0; i < 3; i++) { + buf[i] = buf[i + 1]; + } + + break; + default: + return -EINVAL; + } + + return 0; +} + +static int rtc_ds3231_modify_alarm_time(const struct device *dev, int id, const struct rtc_time *tm, + const uint8_t mask) +{ + const struct rtc_ds3231_conf *config = dev->config; + + if (id >= ALARM_COUNT) { + return -EINVAL; + } + struct rtc_ds3231_alarm_details details = alarms[id]; + uint8_t start_reg = details.start_reg; + size_t buf_size = details.buf_size; + + uint8_t buf[buf_size]; + int err = rtc_ds3231_rtc_time_to_alarm_buf(tm, id, mask, buf); + + if (err != 0) { + return err; + } + + return mfd_ds3231_i2c_set_registers(config->mfd, start_reg, buf, buf_size); +} + +static int rtc_ds3231_modify_alarm_state(const struct device *dev, uint16_t id, bool state) +{ + struct rtc_ds3231_settings conf; + uint8_t mask = 0; + + switch (id) { + case 0: + conf.alarm_1 = state; + mask = DS3231_BITS_STS_ALARM_1; + break; + case 1: + conf.alarm_2 = state; + mask = DS3231_BITS_STS_ALARM_2; + break; + default: + return -EINVAL; + } + + return rtc_ds3231_modify_settings(dev, &conf, mask); +} +static int rtc_ds3231_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + if (mask == 0) { + return rtc_ds3231_modify_alarm_state(dev, id, false); + } + + int err = rtc_ds3231_modify_alarm_state(dev, id, true); + + if (err != 0) { + return err; + } + + return rtc_ds3231_modify_alarm_time(dev, id, timeptr, mask); +} + +static int rtc_ds3231_alarm_buf_to_rtc_time(uint8_t *buf, int id, struct rtc_time *tm, + uint16_t *mask) +{ + rtc_ds3231_reset_rtc_time(tm); + + if (id < 0 || id > 1) { + return -EINVAL; + } else if (id == 1) { + /* shift to the right to match original func */ + for (int i = 3; i > 0; i--) { + buf[i] = buf[i - 1]; + } + buf[0] = 0; + } + + *mask = 0; + if (!(buf[1] & DS3231_BITS_ALARM_RATE)) { + tm->tm_min = bcd2bin(buf[1] & DS3231_BITS_TIME_MINUTES); + *mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + if (!(buf[2] & DS3231_BITS_ALARM_RATE)) { + tm->tm_hour = bcd2bin(buf[2] & DS3231_BITS_TIME_HOURS); + *mask |= RTC_ALARM_TIME_MASK_HOUR; + } + if (!(buf[3] & DS3231_BITS_ALARM_RATE)) { + if (buf[3] & DS3231_BITS_ALARM_DATE_W_OR_M) { + tm->tm_wday = bcd2bin(buf[3] & DS3231_BITS_TIME_DAY_OF_WEEK); + *mask |= RTC_ALARM_TIME_MASK_WEEKDAY; + } else { + tm->tm_mday = bcd2bin(buf[3] & DS3231_BITS_TIME_DATE); + *mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } + } + if (!(buf[0] & DS3231_BITS_ALARM_RATE)) { + tm->tm_sec = bcd2bin(buf[0] & DS3231_BITS_TIME_SECONDS); + *mask |= RTC_ALARM_TIME_MASK_SECOND; + } + + if ((*mask & RTC_ALARM_TIME_MASK_WEEKDAY) && (*mask & RTC_ALARM_TIME_MASK_MONTHDAY)) { + return -EINVAL; + } + + return 0; +} +static int rtc_ds3231_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + const struct rtc_ds3231_conf *config = dev->config; + + if (id >= ALARM_COUNT) { + return -EINVAL; + } + struct rtc_ds3231_alarm_details details = alarms[id]; + uint8_t start_reg = details.start_reg; + size_t buf_size = details.buf_size; + + uint8_t buf[4]; + int err = mfd_ds3231_i2c_get_registers(config->mfd, start_reg, buf, buf_size); + + if (err != 0) { + return err; + } + + return rtc_ds3231_alarm_buf_to_rtc_time(buf, id, timeptr, mask); +} + +static int rtc_ds3231_alarm_is_pending(const struct device *dev, uint16_t id) +{ + uint8_t buf; + int err = rtc_ds3231_get_ctrl_sts(dev, &buf); + + if (err != 0) { + return err; + } + + uint8_t mask = 0; + + switch (id) { + case 0: + mask |= DS3231_BITS_CTRL_STS_ALARM_1_FLAG; + break; + case 1: + mask |= DS3231_BITS_CTRL_STS_ALARM_2_FLAG; + break; + default: + return -EINVAL; + } + + bool state = buf & mask; + + if (state) { + const struct rtc_ds3231_ctrl_sts ctrl = {.a1f = false, .a2f = false}; + + err = rtc_ds3231_modify_ctrl_sts(dev, &ctrl, mask); + if (err != 0) { + return err; + } + } + return state; +} + +static int rtc_ds3231_get_alarm_states(const struct device *dev, bool *states) +{ + int err = 0; + + for (int i = 0; i < ALARM_COUNT; i++) { + states[i] = rtc_ds3231_alarm_is_pending(dev, i); + if (!(states[i] == 0 || states[i] == 1)) { + states[i] = -EINVAL; + err = -EINVAL; + } + } + return err; +} + +static int rtc_ds3231_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback cb, void *user_data) +{ + if (id < 0 || id >= ALARM_COUNT) { + return -EINVAL; + } + + struct rtc_ds3231_data *data = dev->data; + + data->alarms[id] = (struct rtc_ds3231_alarm){cb, user_data}; + + return 0; +} + +static void rtc_ds3231_check_alarms(const struct device *dev) +{ + struct rtc_ds3231_data *data = dev->data; + + bool states[2]; + + rtc_ds3231_get_alarm_states(dev, states); + + for (int i = 0; i < ALARM_COUNT; i++) { + if (states[i]) { + if (data->alarms[i].cb) { + data->alarms[i].cb(dev, i, data->alarms[i].user_data); + } + } + } +} +static int rtc_ds3231_init_alarms(struct rtc_ds3231_data *data) +{ + data->alarms[0] = (struct rtc_ds3231_alarm){NULL, NULL}; + data->alarms[1] = (struct rtc_ds3231_alarm){NULL, NULL}; + return 0; +} +#endif /* CONFIG_RTC_ALARM */ + +#ifdef CONFIG_RTC_UPDATE +static int rtc_ds3231_init_update(struct rtc_ds3231_data *data) +{ + data->update = (struct rtc_ds3231_update){NULL, NULL}; + return 0; +} +static int rtc_ds3231_update_set_callback(const struct device *dev, rtc_update_callback cb, + void *user_data) +{ + struct rtc_ds3231_data *data = dev->data; + + data->update = (struct rtc_ds3231_update){cb, user_data}; + return 0; +} +static void rtc_ds3231_update_callback(const struct device *dev) +{ + struct rtc_ds3231_data *data = dev->data; + + if (data->update.cb) { + data->update.cb(dev, data->update.user_data); + } +} +#endif /* CONFIG_RTC_UPDATE */ + +#if defined(CONFIG_RTC_UPDATE) || defined(CONFIG_RTC_ALARM) +static void rtc_ds3231_isw_h(struct k_work *work) +{ + struct rtc_ds3231_data *data = CONTAINER_OF(work, struct rtc_ds3231_data, work); + const struct device *dev = data->dev; + +#ifdef CONFIG_RTC_UPDATE + rtc_ds3231_update_callback(dev); +#endif /* CONFIG_RTC_UPDATE */ + +#ifdef CONFIG_RTC_ALARM + rtc_ds3231_check_alarms(dev); +#endif /* CONFIG_RTC_ALARM */ +} +static void rtc_ds3231_isw_isr(const struct device *port, struct gpio_callback *cb, uint32_t pins) +{ + struct rtc_ds3231_data *data = CONTAINER_OF(cb, struct rtc_ds3231_data, isw_cb_data); + + k_work_submit(&data->work); +} +static int rtc_ds3231_init_isw(const struct rtc_ds3231_conf *config, struct rtc_ds3231_data *data) +{ + if (!gpio_is_ready_dt(&config->isw_gpios)) { + LOG_ERR("ISW GPIO pin is not ready."); + return -ENODEV; + } + + k_work_init(&data->work, rtc_ds3231_isw_h); + + int err = gpio_pin_configure_dt(&(config->isw_gpios), GPIO_INPUT); + + if (err != 0) { + LOG_ERR("Couldn't configure ISW GPIO pin."); + return err; + } + err = gpio_pin_interrupt_configure_dt(&(config->isw_gpios), GPIO_INT_EDGE_TO_ACTIVE); + if (err != 0) { + LOG_ERR("Couldn't configure ISW interrupt."); + return err; + } + + gpio_init_callback(&data->isw_cb_data, rtc_ds3231_isw_isr, BIT((config->isw_gpios).pin)); + err = gpio_add_callback((config->isw_gpios).port, &data->isw_cb_data); + if (err != 0) { + LOG_ERR("Couldn't add ISW interrupt callback."); + return err; + } + + return 0; +} +#endif /* defined(CONFIG_RTC_UPDATE) || defined(CONFIG_RTC_ALARM) */ + +static DEVICE_API(rtc, driver_api) = { + .set_time = rtc_ds3231_set_time, + .get_time = rtc_ds3231_get_time, + +#ifdef CONFIG_RTC_ALARM + .alarm_get_supported_fields = rtc_ds3231_alarm_get_supported_fields, + .alarm_set_time = rtc_ds3231_alarm_set_time, + .alarm_get_time = rtc_ds3231_alarm_get_time, + .alarm_is_pending = rtc_ds3231_alarm_is_pending, + .alarm_set_callback = rtc_ds3231_alarm_set_callback, +#endif /* CONFIG_RTC_ALARM */ + +#ifdef CONFIG_RTC_UPDATE + .update_set_callback = rtc_ds3231_update_set_callback, +#endif /* CONFIG_RTC_UPDATE */ + +#ifdef CONFIG_RTC_CALIBRATION +/*.set_calibration = set_calibration, + * .get_calibration = get_calibration, + */ +#endif /* CONFIG_RTC_CALIBRATION */ +}; + +static int rtc_ds3231_init_settings(const struct device *dev, const struct rtc_ds3231_conf *config) +{ + struct rtc_ds3231_settings conf = { + .osc = true, +#ifdef CONFIG_RTC_UPDATE + .intctrl_or_sqw = false, + .freq_sqw = FREQ_1000, +#else + .intctrl_or_sqw = true, +#endif + .freq_32khz = config->freq_32k_gpios.port, + }; + uint8_t mask = 255 & ~DS3231_BITS_STS_ALARM_1 & ~DS3231_BITS_STS_ALARM_2; + int err = rtc_ds3231_modify_settings(dev, &conf, mask); + + if (err != 0) { + return err; + } + return 0; +} + +#ifdef CONFIG_PM_DEVICE +static int rtc_ds3231_pm_action(const struct device *dev, enum pm_device_action action) +{ + int err = 0; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: { + struct rtc_ds3231_settings conf = {.osc = true, + .intctrl_or_sqw = false, + .freq_sqw = FREQ_1000, + .freq_32khz = false}; + uint8_t mask = 255 & ~DS3231_BITS_STS_ALARM_1 & ~DS3231_BITS_STS_ALARM_2; + + err = rtc_ds3231_modify_settings(dev, &conf, mask); + if (err != 0) { + return err; + } + break; + } + case PM_DEVICE_ACTION_RESUME: { + /* TODO: trigger a temp CONV */ + const struct rtc_ds3231_conf *config = dev->config; + + err = rtc_ds3231_init_settings(dev, config); + if (err != 0) { + return err; + } + break; + } + default: + return -ENOTSUP; + } + + return 0; +} +#endif /* CONFIG_PM_DEVICE */ + +static int rtc_ds3231_init(const struct device *dev) +{ + int err = 0; + + const struct rtc_ds3231_conf *config = dev->config; + struct rtc_ds3231_data __maybe_unused *data = dev->data; + + if (!device_is_ready(config->mfd)) { + return -ENODEV; + } + +#ifdef CONFIG_RTC_ALARM + err = rtc_ds3231_init_alarms(data); + if (err != 0) { + LOG_ERR("Failed to init alarms."); + return err; + } +#endif + +#ifdef CONFIG_RTC_UPDATE + err = rtc_ds3231_init_update(data); + if (err != 0) { + LOG_ERR("Failed to init update callback."); + return err; + } +#endif + + err = rtc_ds3231_init_settings(dev, config); + if (err != 0) { + LOG_ERR("Failed to init settings."); + return err; + } + +#if defined(CONFIG_RTC_UPDATE) || defined(CONFIG_RTC_ALARM) + data->dev = dev; + err = rtc_ds3231_init_isw(config, data); + if (err != 0) { + LOG_ERR("Initing ISW interrupt failed!"); + return err; + } +#endif /* defined(CONFIG_RTC_UPDATE) || defined(CONFIG_RTC_ALARM) */ + + return 0; +} + +#define RTC_DS3231_DEFINE(inst) \ + static struct rtc_ds3231_data rtc_ds3231_data_##inst; \ + static const struct rtc_ds3231_conf rtc_ds3231_conf_##inst = { \ + .mfd = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + .isw_gpios = GPIO_DT_SPEC_INST_GET(inst, isw_gpios), \ + .freq_32k_gpios = GPIO_DT_SPEC_INST_GET_OR(inst, freq_32khz_gpios, {NULL})}; \ + PM_DEVICE_DT_INST_DEFINE(inst, rtc_ds3231_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, &rtc_ds3231_init, PM_DEVICE_DT_INST_GET(inst), \ + &rtc_ds3231_data_##inst, &rtc_ds3231_conf_##inst, POST_KERNEL, \ + CONFIG_RTC_DS3231_INIT_PRIORITY, &driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RTC_DS3231_DEFINE) diff --git a/drivers/rtc/rtc_rv8263.c b/drivers/rtc/rtc_rv8263.c index 255c7a06ea888..95ab199eb21f3 100644 --- a/drivers/rtc/rtc_rv8263.c +++ b/drivers/rtc/rtc_rv8263.c @@ -163,7 +163,7 @@ static void rv8263c8_interrupt_worker(struct k_work *p_work) struct rv8263c8_data *data = CONTAINER_OF(p_work, struct rv8263c8_data, interrupt_work); const struct rv8263c8_config *config = data->dev->config; - i2c_reg_read_byte_dt(&config->i2c_bus, RV8263C8_REGISTER_CONTROL_2, ®); + (void)i2c_reg_read_byte_dt(&config->i2c_bus, RV8263C8_REGISTER_CONTROL_2, ®); #if CONFIG_RTC_ALARM /* An alarm interrupt occurs. Clear the timer flag, */ diff --git a/drivers/rtc/rtc_rv8803.c b/drivers/rtc/rtc_rv8803.c new file mode 100644 index 0000000000000..568938269e77c --- /dev/null +++ b/drivers/rtc/rtc_rv8803.c @@ -0,0 +1,865 @@ +/* + * Copyright (c) 2024 Marcin Lyda + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "rtc_utils.h" + +/* Registers */ +#define RV8803_SECONDS_REG 0x00 +#define RV8803_MINUTES_REG 0x01 +#define RV8803_HOURS_REG 0x02 +#define RV8803_WEEKDAY_REG 0x03 +#define RV8803_DATE_REG 0x04 +#define RV8803_MONTH_REG 0x05 +#define RV8803_YEAR_REG 0x06 +#define RV8803_RAM_REG 0x07 +#define RV8803_MINUTES_ALARM_REG 0x08 +#define RV8803_HOURS_ALARM_REG 0x09 +#define RV8803_WEEKDAY_OR_DATE_ALARM_REG 0x0A +#define RV8803_EXTENSION_REG 0x0D +#define RV8803_FLAG_REG 0x0E +#define RV8803_CONTROL_REG 0x0F +#define RV8803_OFFSET_REG 0x2C + +/* Bitmasks */ +#define RV8803_SECONDS_MASK GENMASK(6, 0) +#define RV8803_MINUTES_MASK GENMASK(6, 0) +#define RV8803_HOURS_MASK GENMASK(5, 0) +#define RV8803_WEEKDAY_MASK GENMASK(6, 0) +#define RV8803_DATE_MASK GENMASK(5, 0) +#define RV8803_MONTH_MASK GENMASK(4, 0) +#define RV8803_YEAR_MASK GENMASK(7, 0) + +#define RV8803_MINUTES_ALARM_AE_M_BIT BIT(7) +#define RV8803_MINUTES_ALARM_MASK GENMASK(6, 0) +#define RV8803_HOURS_ALARM_AE_H_BIT BIT(7) +#define RV8803_HOURS_ALARM_MASK GENMASK(5, 0) +#define RV8803_WEEKDAY_OR_DATE_ALARM_AE_WD_BIT BIT(7) +#define RV8803_WEEKDAY_ALARM_MASK GENMASK(6, 0) +#define RV8803_DATE_ALARM_MASK GENMASK(5, 0) + +#define RV8803_EXTENSION_TEST_BIT BIT(7) +#define RV8803_EXTENSION_WADA_BIT BIT(6) +#define RV8803_EXTENSION_USEL_BIT BIT(5) +#define RV8803_EXTENSION_TE_BIT BIT(4) +#define RV8803_EXTENSION_FD_MASK GENMASK(3, 2) +#define RV8803_EXTENSION_TD_MASK GENMASK(1, 0) + +#define RV8803_EXTENSION_FD_32768Hz FIELD_PREP(RV8803_EXTENSION_FD_MASK, 0x00) +#define RV8803_EXTENSION_FD_1024Hz FIELD_PREP(RV8803_EXTENSION_FD_MASK, 0x01) +#define RV8803_EXTENSION_FD_1Hz FIELD_PREP(RV8803_EXTENSION_FD_MASK, 0x02) + +#define RV8803_FLAG_UF_BIT BIT(5) +#define RV8803_FLAG_TF_BIT BIT(4) +#define RV8803_FLAG_AF_BIT BIT(3) +#define RV8803_FLAG_EVF_BIT BIT(2) +#define RV8803_FLAG_V2F_BIT BIT(1) +#define RV8803_FLAG_V1F_BIT BIT(0) + +#define RV8803_CONTROL_UIE_BIT BIT(5) +#define RV8803_CONTROL_TIE_BIT BIT(4) +#define RV8803_CONTROL_AIE_BIT BIT(3) +#define RV8803_CONTROL_EIE_BIT BIT(2) +#define RV8803_CONTROL_RESET_BIT BIT(0) + +#define RV8803_MONDAY_MASK BIT(0) +#define RV8803_TUESDAY_MASK BIT(1) +#define RV8803_WEDNESDAY_MASK BIT(2) +#define RV8803_THURSDAY_MASK BIT(3) +#define RV8803_FRIDAY_MASK BIT(4) +#define RV8803_SATURDAY_MASK BIT(5) +#define RV8803_SUNDAY_MASK BIT(6) + +#define RV8803_OFFSET_MASK GENMASK(5, 0) + +/* Offset between first tm_year and first RV8803 year */ +#define RV8803_YEAR_OFFSET (2000 - 1900) + +/* RV8803 enumerates months 1 to 12 */ +#define RV8803_MONTH_OFFSET -1 + +/* Max value of seconds, needed for readout procedure workaround */ +#define RV8803_SECONDS_MAX_VALUE 59 + +/* See RV-8803-C7 Application Manual p. 22, 3.9. */ +#define RV8803_OFFSET_PPB_PER_LSB 238 +#define RV8803_OFFSET_PPB_MIN (-32 * RV8803_OFFSET_PPB_PER_LSB) +#define RV8803_OFFSET_PPB_MAX (31 * RV8803_OFFSET_PPB_PER_LSB) +#define RV8803_OFFSET_SIGN_BIT_INDEX 5 /* Required for aging offset sign extension */ + +/* CLKOUT property enum values */ +#define RV8803_PROP_ENUM_1HZ 0 +#define RV8803_PROP_ENUM_1024HZ 1 +#define RV8803_PROP_ENUM_32768HZ 2 + +#define DT_DRV_COMPAT microcrystal_rv8803 + +#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 +#warning "Micro Crystal RV8803 driver enabled without any devices" +#endif + +/* RTC time fields supported by RV8803 */ +#define RV8803_RTC_TIME_MASK \ + (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_YEAR | \ + RTC_ALARM_TIME_MASK_WEEKDAY) + +/* RTC alarm time fields supported by RV8803 */ +#define RV8803_RTC_ALARM_TIME_MASK \ + (RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MONTHDAY | \ + RTC_ALARM_TIME_MASK_WEEKDAY) + +/* Helper macro to guard GPIO interrupt related stuff */ +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios) && \ + (defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_UPDATE)) +#define RV8803_INT_GPIOS_IN_USE 1 +#endif + +LOG_MODULE_REGISTER(rv8803, CONFIG_RTC_LOG_LEVEL); + +struct rv8803_config { + const struct i2c_dt_spec i2c; +#ifdef RV8803_INT_GPIOS_IN_USE + struct gpio_dt_spec gpio_int; +#endif + uint16_t clkout_freq; +}; + +struct rv8803_data { + struct k_sem lock; +#ifdef RV8803_INT_GPIOS_IN_USE + const struct device *dev; + struct gpio_callback irq_callback; + struct k_work work; + +#ifdef CONFIG_RTC_ALARM + rtc_alarm_callback alarm_callback; + void *alarm_user_data; +#endif + +#ifdef CONFIG_RTC_UPDATE + rtc_update_callback update_callback; + void *update_user_data; +#endif +#endif +}; + +static void rv8803_lock_sem(const struct device *dev) +{ + struct rv8803_data *data = dev->data; + + k_sem_take(&data->lock, K_FOREVER); +} + +static void rv8803_unlock_sem(const struct device *dev) +{ + struct rv8803_data *data = dev->data; + + k_sem_give(&data->lock); +} + +static int rv8803_read_regs(const struct device *dev, uint8_t addr, void *buffer, size_t size) +{ + const struct rv8803_config *config = dev->config; + int err; + + err = i2c_write_read_dt(&config->i2c, &addr, sizeof(addr), buffer, size); + if (err) { + LOG_ERR("Failed to read %zuB from register 0x%02X, error: %d", size, addr, err); + } + return err; +} + +static int rv8803_read_reg8(const struct device *dev, uint8_t addr, uint8_t *val) +{ + return rv8803_read_regs(dev, addr, val, sizeof(*val)); +} + +static int rv8803_write_regs(const struct device *dev, uint8_t addr, const void *buffer, + size_t size) +{ + const struct rv8803_config *config = dev->config; + const size_t i2c_data_size = sizeof(addr) + size; + uint8_t i2c_data[i2c_data_size]; + int err; + + /* Prepend data with I2C device address */ + i2c_data[0] = addr; + memcpy(&i2c_data[1], buffer, size); + + err = i2c_write_dt(&config->i2c, i2c_data, i2c_data_size); + if (err) { + LOG_ERR("Failed to write %zuB to register 0x%02X, error: %d", i2c_data_size, addr, + err); + } + + return err; +} + +#if defined(RV8803_INT_GPIOS_IN_USE) || defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_CALIBRATION) +static int rv8803_write_reg8(const struct device *dev, uint8_t addr, uint8_t val) +{ + return rv8803_write_regs(dev, addr, &val, sizeof(val)); +} +#endif + +static int rv8803_update_reg8(const struct device *dev, uint8_t addr, uint8_t mask, uint8_t val) +{ + const struct rv8803_config *config = dev->config; + int err; + + err = i2c_reg_update_byte_dt(&config->i2c, addr, mask, val); + if (err) { + LOG_ERR("Failed to update register 0x%02X with value 0x%02X and mask 0x%02X, " + "error: %d", + addr, val, mask, err); + } + return err; +} + +static uint8_t rv8803_weekday2mask(int weekday) +{ + return (1 << weekday); +} + +static int rv8803_mask2weekday(uint8_t mask) +{ + return find_lsb_set(mask) - 1; +} + +#ifdef RV8803_INT_GPIOS_IN_USE + +static void rv8803_work_callback(struct k_work *work) +{ + struct rv8803_data *data = CONTAINER_OF(work, struct rv8803_data, work); + const struct device *dev = data->dev; + rtc_alarm_callback alarm_callback = NULL; + void *alarm_user_data = NULL; + rtc_update_callback update_callback = NULL; + void *update_user_data = NULL; + int err; + uint8_t flags; + + rv8803_lock_sem(dev); + + do { + /* Read flags register */ + err = rv8803_read_reg8(dev, RV8803_FLAG_REG, &flags); + if (err) { + break; + } + +#ifdef CONFIG_RTC_ALARM + /* Handle alarm event */ + if ((flags & RV8803_FLAG_AF_BIT) && (data->alarm_callback != NULL)) { + flags &= ~RV8803_FLAG_AF_BIT; + alarm_callback = data->alarm_callback; + alarm_user_data = data->alarm_user_data; + } +#endif + +#ifdef CONFIG_RTC_UPDATE + /* Handle update event */ + if ((flags & RV8803_FLAG_UF_BIT) && (data->update_callback != NULL)) { + flags &= ~RV8803_FLAG_UF_BIT; + update_callback = data->update_callback; + update_user_data = data->update_user_data; + } +#endif + + /* Clear flags */ + err = rv8803_write_reg8(dev, RV8803_FLAG_REG, flags); + if (err) { + break; + } + + /* Check if any interrupt occurred between flags register read/write */ + err = rv8803_read_reg8(dev, RV8803_FLAG_REG, &flags); + if (err) { + break; + } + + if (((flags & RV8803_FLAG_AF_BIT) && (alarm_callback != NULL)) || + ((flags & RV8803_FLAG_UF_BIT) && (update_callback != NULL))) { + /* Another interrupt occurred while servicing this one */ + k_work_submit(&data->work); + } + } while (0); + + rv8803_unlock_sem(dev); + + if (alarm_callback != NULL) { + /* ID is always zero, there's only one set of alarm regs on chip */ + alarm_callback(dev, 0, alarm_user_data); + alarm_callback = NULL; + } + + if (update_callback != NULL) { + update_callback(dev, update_user_data); + update_callback = NULL; + } +} + +static void rv8803_irq_handler(const struct device *port, struct gpio_callback *callback, + gpio_port_pins_t pins) +{ + ARG_UNUSED(port); + ARG_UNUSED(pins); + + struct rv8803_data *data = CONTAINER_OF(callback, struct rv8803_data, irq_callback); + + k_work_submit(&data->work); +} + +#endif + +static int rv8803_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + uint8_t date[7]; + int err; + + if ((timeptr == NULL) || !rtc_utils_validate_rtc_time(timeptr, RV8803_RTC_TIME_MASK) || + (timeptr->tm_year < RV8803_YEAR_OFFSET)) { + return -EINVAL; + } + + rv8803_lock_sem(dev); + + date[0] = bin2bcd(timeptr->tm_sec) & RV8803_SECONDS_MASK; + date[1] = bin2bcd(timeptr->tm_min) & RV8803_MINUTES_MASK; + date[2] = bin2bcd(timeptr->tm_hour) & RV8803_HOURS_MASK; + date[3] = rv8803_weekday2mask(timeptr->tm_wday); + date[4] = bin2bcd(timeptr->tm_mday) & RV8803_DATE_MASK; + date[5] = bin2bcd(timeptr->tm_mon - RV8803_MONTH_OFFSET) & RV8803_MONTH_MASK; + date[6] = bin2bcd(timeptr->tm_year - RV8803_YEAR_OFFSET) & RV8803_YEAR_MASK; + + do { + /* Reset and freeze countdown chain */ + err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_CONTROL_RESET_BIT, + RV8803_CONTROL_RESET_BIT); + if (err) { + break; + } + + /* Write new time value */ + err = rv8803_write_regs(dev, RV8803_SECONDS_REG, date, sizeof(date)); + if (err) { + break; + } + + /* Clear Voltage Low flags */ + err = rv8803_update_reg8(dev, RV8803_FLAG_REG, + RV8803_FLAG_V1F_BIT | RV8803_FLAG_V2F_BIT, 0); + if (err) { + break; + } + + /* Release countdown chain lock */ + err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_CONTROL_RESET_BIT, 0); + if (err) { + break; + } + } while (0); + + rv8803_unlock_sem(dev); + + if (!err) { + LOG_DBG("Set time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, " + "minute: %d, second: %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + } + + return err; +} + +static int rv8803_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + uint8_t flags; + uint8_t date_1[7]; + uint8_t date_2[7]; + uint8_t *date = date_1; + uint8_t seconds_1; + uint8_t seconds_2; + int err; + + if (timeptr == NULL) { + return -EINVAL; + } + + err = rv8803_read_reg8(dev, RV8803_FLAG_REG, &flags); + if (err) { + return err; + } + + /* Voltage Flag 2 indicates data loss */ + if (flags & RV8803_FLAG_V2F_BIT) { + return -ENODATA; + } + + /* Time readout procedure to bypass the inability to freeze registers. */ + /* See RV-8803-C7 Application Manual p. 42, 4.12.2. */ + err = rv8803_read_regs(dev, RV8803_SECONDS_REG, date_1, sizeof(date_1)); + if (err) { + return err; + } + seconds_1 = bcd2bin(date_1[0] & RV8803_SECONDS_MASK); + if (seconds_1 == RV8803_SECONDS_MAX_VALUE) { + err = rv8803_read_regs(dev, RV8803_SECONDS_REG, date_2, sizeof(date_2)); + if (err) { + return err; + } + + seconds_2 = bcd2bin(date_2[0] & RV8803_SECONDS_MASK); + if (seconds_2 != RV8803_SECONDS_MAX_VALUE) { + date = date_2; + } + } + + memset(timeptr, 0, sizeof(*timeptr)); + timeptr->tm_sec = bcd2bin(date[0] & RV8803_SECONDS_MASK); + timeptr->tm_min = bcd2bin(date[1] & RV8803_MINUTES_MASK); + timeptr->tm_hour = bcd2bin(date[2] & RV8803_HOURS_MASK); + timeptr->tm_wday = rv8803_mask2weekday(date[3] & RV8803_WEEKDAY_MASK); + timeptr->tm_mday = bcd2bin(date[4] & RV8803_DATE_MASK); + timeptr->tm_mon = bcd2bin(date[5] & RV8803_MONTH_MASK) + RV8803_MONTH_OFFSET; + timeptr->tm_year = bcd2bin(date[6] & RV8803_YEAR_MASK) + RV8803_YEAR_OFFSET; + timeptr->tm_yday = -1; /* Unsupported */ + timeptr->tm_isdst = -1; /* Unsupported */ + timeptr->tm_nsec = 0; /* Unsupported */ + + LOG_DBG("Read time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, minute: " + "%d, second: %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + + return 0; +} + +#ifdef CONFIG_RTC_ALARM + +static int rv8803_alarm_get_supported_fields(const struct device *dev, uint16_t id, uint16_t *mask) +{ + ARG_UNUSED(dev); + + if (id != 0) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + *mask = RV8803_RTC_ALARM_TIME_MASK; + + return 0; +} + +static int rv8803_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + uint8_t regs[3]; + uint8_t reg_val; + int err; + + if (id != 0) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + if (mask & ~RV8803_RTC_ALARM_TIME_MASK) { + LOG_ERR("Unsupported alarm mask 0x%04X, excess field(s): 0x%04X", mask, + mask & ~(int16_t)RV8803_RTC_ALARM_TIME_MASK); + return -EINVAL; + } + + if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) && (mask & RTC_ALARM_TIME_MASK_WEEKDAY)) { + LOG_ERR("Month day and week day alarms cannot be set simultaneously"); + return -EINVAL; + } + + if (!rtc_utils_validate_rtc_time(timeptr, mask)) { + LOG_ERR("Invalid alarm time"); + return -EINVAL; + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + regs[0] = bin2bcd(timeptr->tm_min) & RV8803_MINUTES_ALARM_MASK; + } else { + regs[0] = RV8803_MINUTES_ALARM_AE_M_BIT; + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + regs[1] = bin2bcd(timeptr->tm_hour) & RV8803_HOURS_ALARM_MASK; + } else { + regs[1] = RV8803_HOURS_ALARM_AE_H_BIT; + } + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + regs[2] = bin2bcd(timeptr->tm_mday) & RV8803_DATE_ALARM_MASK; + } else if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) { + regs[2] = rv8803_weekday2mask(timeptr->tm_wday) & RV8803_WEEKDAY_ALARM_MASK; + } else { + regs[2] = RV8803_WEEKDAY_OR_DATE_ALARM_AE_WD_BIT; + } + + /* Update WADA bit */ + if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) || (mask & RTC_ALARM_TIME_MASK_WEEKDAY)) { + reg_val = (mask & RTC_ALARM_TIME_MASK_MONTHDAY) ? RV8803_EXTENSION_WADA_BIT : 0; + err = rv8803_update_reg8(dev, RV8803_EXTENSION_REG, RV8803_EXTENSION_WADA_BIT, + reg_val); + if (err) { + return err; + } + } + + /* Update alarm registers */ + err = rv8803_write_regs(dev, RV8803_MINUTES_ALARM_REG, regs, sizeof(regs)); + if (err) { + return err; + } + + LOG_DBG("Set alarm: month day: %d, week day: %d, hour: %d, minute: %d, mask: 0x%04X", + timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour, timeptr->tm_min, mask); + + return 0; +} + +static int rv8803_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + uint8_t regs[3]; + uint8_t reg_val; + int err; + + if (id != 0) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + err = rv8803_read_regs(dev, RV8803_MINUTES_ALARM_REG, regs, sizeof(regs)); + if (err) { + return err; + } + + /* Read extension register to get WADA bit */ + err = rv8803_read_reg8(dev, RV8803_EXTENSION_REG, ®_val); + if (err) { + return err; + } + + memset(timeptr, 0, sizeof(*timeptr)); + *mask = 0; + + if ((regs[0] & RV8803_MINUTES_ALARM_AE_M_BIT) == 0) { + timeptr->tm_min = bcd2bin(regs[0] & RV8803_MINUTES_ALARM_MASK); + *mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + + if ((regs[1] & RV8803_HOURS_ALARM_AE_H_BIT) == 0) { + timeptr->tm_hour = bcd2bin(regs[1] & RV8803_HOURS_ALARM_MASK); + *mask |= RTC_ALARM_TIME_MASK_HOUR; + } + + if ((regs[2] & RV8803_WEEKDAY_OR_DATE_ALARM_AE_WD_BIT) == 0) { + if (reg_val & RV8803_EXTENSION_WADA_BIT) { + timeptr->tm_mday = bcd2bin(regs[2] & RV8803_DATE_ALARM_MASK); + *mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } else { + timeptr->tm_wday = find_lsb_set(regs[2] & RV8803_WEEKDAY_ALARM_MASK); + *mask |= RTC_ALARM_TIME_MASK_WEEKDAY; + } + } + + LOG_DBG("Get alarm: month day: %d, week day: %d, hour: %d, minute: %d, mask: 0x%04X", + timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour, timeptr->tm_min, *mask); + + return 0; +} + +static int rv8803_alarm_is_pending(const struct device *dev, uint16_t id) +{ + uint8_t flags; + int err; + + if (id != 0) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + rv8803_lock_sem(dev); + + do { + err = rv8803_read_reg8(dev, RV8803_FLAG_REG, &flags); + if (err) { + break; + } + + if (flags & RV8803_FLAG_AF_BIT) { + flags &= ~RV8803_FLAG_AF_BIT; + + err = rv8803_write_reg8(dev, RV8803_FLAG_REG, flags); + if (err) { + break; + } + + /* Indicate that alarm is pending */ + err = 1; + } + } while (0); + + rv8803_unlock_sem(dev); + + return err; +} + +#ifdef RV8803_INT_GPIOS_IN_USE + +static int rv8803_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + const struct rv8803_config *config = dev->config; + struct rv8803_data *data = dev->data; + uint8_t reg_val; + int err; + + if (config->gpio_int.port == NULL) { + return -ENOTSUP; + } + + if (id != 0) { + LOG_ERR("Invalid alarm ID: %d", id); + return -EINVAL; + } + + rv8803_lock_sem(dev); + + data->alarm_callback = callback; + data->alarm_user_data = user_data; + + /* Enable alarm interrupt if callback provided */ + reg_val = (callback != NULL) ? RV8803_CONTROL_AIE_BIT : 0; + err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_CONTROL_AIE_BIT, reg_val); + + rv8803_unlock_sem(dev); + + /* Alarm IRQ might have already been triggered */ + k_work_submit(&data->work); + + return err; +} + +#endif + +#endif + +#if defined(RV8803_INT_GPIOS_IN_USE) && defined(CONFIG_RTC_UPDATE) + +static int rv8803_update_set_callback(const struct device *dev, rtc_update_callback callback, + void *user_data) +{ + const struct rv8803_config *config = dev->config; + struct rv8803_data *data = dev->data; + uint8_t reg_val; + int err; + + if (config->gpio_int.port == NULL) { + return -ENOTSUP; + } + + rv8803_lock_sem(dev); + + data->update_callback = callback; + data->update_user_data = user_data; + + /* Enable update interrupt if callback provided */ + reg_val = (callback != NULL) ? RV8803_CONTROL_UIE_BIT : 0; + err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_CONTROL_UIE_BIT, reg_val); + + rv8803_unlock_sem(dev); + + /* Update IRQ might have already been triggered */ + k_work_submit(&data->work); + + return err; +} + +#endif + +#ifdef CONFIG_RTC_CALIBRATION + +static int rv8803_set_calibration(const struct device *dev, int32_t freq_ppb) +{ + int8_t offset; + + if ((freq_ppb < RV8803_OFFSET_PPB_MIN) || (freq_ppb > RV8803_OFFSET_PPB_MAX)) { + LOG_ERR("Calibration value %d ppb out of range", freq_ppb); + return -EINVAL; + } + + offset = (freq_ppb / RV8803_OFFSET_PPB_PER_LSB) & RV8803_OFFSET_MASK; + + LOG_DBG("Set calibration: frequency ppb: %d, offset value: %d", freq_ppb, offset); + + return rv8803_write_reg8(dev, RV8803_OFFSET_REG, offset); +} + +static int rv8803_get_calibration(const struct device *dev, int32_t *freq_ppb) +{ + int8_t offset; + int err; + + err = rv8803_read_reg8(dev, RV8803_OFFSET_REG, &offset); + if (err) { + return err; + } + + *freq_ppb = sign_extend(offset, RV8803_OFFSET_SIGN_BIT_INDEX) * RV8803_OFFSET_PPB_PER_LSB; + + LOG_DBG("Get calibration: frequency ppb: %d, offset value: %d", *freq_ppb, offset); + + return 0; +} +#endif + +static int rv8803_init(const struct device *dev) +{ + const struct rv8803_config *config = dev->config; + struct rv8803_data *data = dev->data; + uint8_t freq; + uint8_t regs[3]; + int err; + + k_sem_init(&data->lock, 1, 1); + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C bus not ready"); + return -ENODEV; + } + +#ifdef RV8803_INT_GPIOS_IN_USE + if (config->gpio_int.port != NULL) { + if (!gpio_is_ready_dt(&config->gpio_int)) { + LOG_ERR("GPIO not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT); + if (err) { + LOG_ERR("Failed to configure interrupt GPIO, error: %d", err); + return err; + } + + err = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + if (err) { + LOG_ERR("Failed to enable GPIO interrupt, error: %d", err); + return err; + } + + gpio_init_callback(&data->irq_callback, rv8803_irq_handler, + BIT(config->gpio_int.pin)); + + err = gpio_add_callback_dt(&config->gpio_int, &data->irq_callback); + if (err) { + LOG_ERR("Failed to add GPIO callback, error: %d", err); + return err; + } + + data->dev = dev; + data->work.handler = rv8803_work_callback; + } +#endif + + /* Configure CLKOUT frequency */ + switch (config->clkout_freq) { + case RV8803_PROP_ENUM_1HZ: + freq = RV8803_EXTENSION_FD_1Hz; + break; + case RV8803_PROP_ENUM_1024HZ: + freq = RV8803_EXTENSION_FD_1024Hz; + break; + case RV8803_PROP_ENUM_32768HZ: + default: + freq = RV8803_EXTENSION_FD_32768Hz; + break; + } + err = rv8803_update_reg8(dev, RV8803_EXTENSION_REG, RV8803_EXTENSION_FD_MASK, freq); + if (err) { + return -ENODEV; + } + + /* Clear alarm and update flag */ + err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, RV8803_FLAG_AF_BIT | RV8803_FLAG_UF_BIT, + RV8803_FLAG_AF_BIT | RV8803_FLAG_UF_BIT); + if (err) { + return -ENODEV; + } + + /* Disable IRQs */ + err = rv8803_update_reg8(dev, RV8803_CONTROL_REG, + RV8803_CONTROL_AIE_BIT | RV8803_CONTROL_UIE_BIT, 0); + if (err) { + return -ENODEV; + } + + /* Disable alarms */ + err = rv8803_read_regs(dev, RV8803_MINUTES_ALARM_REG, regs, sizeof(regs)); + if (err) { + return -ENODEV; + } + + regs[0] |= RV8803_MINUTES_ALARM_AE_M_BIT; + regs[1] |= RV8803_HOURS_ALARM_AE_H_BIT; + regs[2] |= RV8803_WEEKDAY_OR_DATE_ALARM_AE_WD_BIT; + + err = rv8803_write_regs(dev, RV8803_MINUTES_ALARM_REG, regs, sizeof(regs)); + if (err) { + return -ENODEV; + } + + return 0; +} + +static DEVICE_API(rtc, rv8803_driver_api) = { + .set_time = rv8803_set_time, + .get_time = rv8803_get_time, +#ifdef CONFIG_RTC_ALARM + .alarm_get_supported_fields = rv8803_alarm_get_supported_fields, + .alarm_set_time = rv8803_alarm_set_time, + .alarm_get_time = rv8803_alarm_get_time, + .alarm_is_pending = rv8803_alarm_is_pending, +#ifdef RV8803_INT_GPIOS_IN_USE + .alarm_set_callback = rv8803_alarm_set_callback, +#endif +#endif +#if defined(RV8803_INT_GPIOS_IN_USE) && defined(CONFIG_RTC_UPDATE) + .update_set_callback = rv8803_update_set_callback, +#endif +#ifdef CONFIG_RTC_CALIBRATION + .set_calibration = rv8803_set_calibration, + .get_calibration = rv8803_get_calibration +#endif +}; + +#define RV8803_INIT(inst) \ + static const struct rv8803_config rv8803_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .clkout_freq = DT_INST_ENUM_IDX_OR(inst, clkout_frequency, 0), \ + IF_ENABLED( \ + RV8803_INT_GPIOS_IN_USE, \ + (.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0})) \ + ) \ + }; \ + \ + static struct rv8803_data rv8803_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, rv8803_init, NULL, &rv8803_data_##inst, &rv8803_config_##inst, \ + POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, &rv8803_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RV8803_INIT); diff --git a/drivers/rtc/rtc_rx8130ce.c b/drivers/rtc/rtc_rx8130ce.c new file mode 100644 index 0000000000000..d181bea8a0f1b --- /dev/null +++ b/drivers/rtc/rtc_rx8130ce.c @@ -0,0 +1,776 @@ +/* + * Copyright (c) 2025 MĂĽns Ansgariusson + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(rx8130ce, CONFIG_RTC_LOG_LEVEL); + +#define DT_DRV_COMPAT epson_rx8130ce_rtc + +enum registers { + TIME = 0x10, + ALARM = 0x17, + /* control registers */ + EXTENSION = 0x1C, + FLAG = 0x1D, + CTRL0 = 0x1E, + CTRL1 = 0x1F, + OFFSET = 0x30, +}; + +#define RX8130CE_SECONDS_MASK GENMASK(6, 0) +#define RX8130CE_MINUTES_MASK GENMASK(6, 0) +#define RX8130CE_HOURS_MASK GENMASK(5, 0) +#define RX8130CE_DAYS_MASK GENMASK(5, 0) +#define RX8130CE_WEEKDAYS_MASK GENMASK(6, 0) +#define RX8130CE_MONTHS_MASK GENMASK(4, 0) +#define RX8130CE_YEARS_MASK GENMASK(7, 0) + +#define RX8130CE_MONTHS_OFFSET (1) +#define RX8130CE_YEARS_OFFSET (100) + +/* Alarm AE bit */ +#define ALARM_DISABLE BIT(7) + +/* Extension reg(0x1C) bit field */ +#define EXT_TSEL0 BIT(0) +#define EXT_TSEL1 BIT(1) +#define EXT_TSEL2 BIT(2) +#define EXT_WADA BIT(3) +#define EXT_TE BIT(4) +#define EXT_USEL BIT(5) +#define EXT_FSEL0 BIT(6) +#define EXT_FSEL1 BIT(7) + +/* Flag reg(0x1D) bit field */ +#define FLAG_VBFF BIT(0) +#define FLAG_VLF BIT(1) +#define FLAG_RSF BIT(2) +#define FLAG_AF BIT(3) +#define FLAG_TF BIT(4) +#define FLAG_UF BIT(5) +#define FLAG_VBLF BIT(7) + +/* Control0 reg(0x1E) bit field */ +#define CTRL0_TBKE BIT(0) +#define CTRL0_TBKON BIT(1) +#define CTRL0_TSTP BIT(2) +#define CTRL0_AIE BIT(3) +#define CTRL0_TIE BIT(4) +#define CTRL0_UIE BIT(5) +#define CTRL0_STOP BIT(6) +#define CTRL0_TEST BIT(7) + +/* ctrl1 reg(0x1F) bit field */ +#define CTRL1_BFVSEL0 BIT(0) +#define CTRL1_BFVSEL1 BIT(1) +#define CTRL1_RSVSEL BIT(2) +#define CTRL1_INIEN BIT(4) +#define CTRL1_CHGEN BIT(5) +#define CTRL1_SMPTSEL0 BIT(6) +#define CTRL1_SMPTSEL1 BIT(7) + + +/* Digital Offest reg(0x30) bit field */ +#define DIGITAL_OFFSET_NEG BIT(6) +#define DIGITAL_OFFSET_DTE BIT(7) + +/* Digital Offset register values */ +#define DIGITAL_OFFSET_MAX 192260 +#define DIGITAL_OFFSET_MIN -195310 +#define DIGITAL_OFFSET_STEP_PPB 3050 + +/** + * @brief rx8130ce control registers + * 0x1C extension register + * 0x1D Flag register + * 0x1E control0 + * 0x1F ctrl1 + */ +struct __packed rx8130ce_registers { + uint8_t extension; + uint8_t flag; + uint8_t ctrl0; + uint8_t ctrl1; +}; + +struct __packed rx8130ce_time { + uint8_t second; + uint8_t minute; + uint8_t hour; + uint8_t weekday; + uint8_t day; + uint8_t month; + uint8_t year; +}; + +struct __packed rx8130ce_alarm { + uint8_t minute; + uint8_t hour; + union { + uint8_t wday; + uint8_t day; + }; +}; + +struct rx8130ce_config { + const struct i2c_dt_spec i2c; + struct gpio_dt_spec irq; + uint16_t clockout_frequency; + uint8_t battery_switchover; +}; + +struct rx8130ce_data { + struct k_sem lock; + const struct device *dev; + struct rx8130ce_registers reg; + +#if defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_UPDATE) + struct gpio_callback irq_cb; + struct k_work irq_work; +#endif +#ifdef CONFIG_RTC_ALARM + void *alarm_user_data; + rtc_alarm_callback alarm_callback; +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_UPDATE + void *update_user_data; + rtc_update_callback update_callback; +#endif /* CONFIG_RTC_UPDATE */ +}; + +static inline uint8_t wday2rtc(uint8_t wday) +{ + return 1 << wday; +} + +static inline uint8_t rtc2wday(uint8_t rtc_wday) +{ + for (size_t bit = 0 ; bit < 7; bit++) { + if (rtc_wday & (1 << bit)) { + return bit; + } + } + return 0; +} + +static int rx8130ce_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + int rc = 0; + struct rx8130ce_time rtc_time; + const struct rx8130ce_config *cfg = dev->config; + struct rx8130ce_data *data = dev->data; + + memset(timeptr, 0U, sizeof(*timeptr)); + + k_sem_take(&data->lock, K_FOREVER); + rc = i2c_burst_read_dt(&cfg->i2c, TIME, (uint8_t *)&rtc_time, sizeof(rtc_time)); + if (rc != 0) { + LOG_ERR("Failed to read time"); + goto error; + } + timeptr->tm_sec = bcd2bin(rtc_time.second & RX8130CE_SECONDS_MASK); + timeptr->tm_min = bcd2bin(rtc_time.minute & RX8130CE_MINUTES_MASK); + timeptr->tm_hour = bcd2bin(rtc_time.hour & RX8130CE_HOURS_MASK); + timeptr->tm_mday = bcd2bin(rtc_time.day & RX8130CE_DAYS_MASK); + timeptr->tm_wday = rtc2wday(rtc_time.weekday & RX8130CE_WEEKDAYS_MASK); + timeptr->tm_mon = bcd2bin(rtc_time.month & RX8130CE_MONTHS_MASK) - RX8130CE_MONTHS_OFFSET; + timeptr->tm_year = bcd2bin(rtc_time.year & RX8130CE_YEARS_MASK) + RX8130CE_YEARS_OFFSET; + timeptr->tm_yday = -1; + timeptr->tm_isdst = -1; + +error: + k_sem_give(&data->lock); + return rc; +} + +static int rx8130ce_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + int rc = 0; + struct rx8130ce_time rtc_time; + const struct rx8130ce_config *cfg = dev->config; + struct rx8130ce_data *data = dev->data; + + rtc_time.second = bin2bcd(timeptr->tm_sec); + rtc_time.minute = bin2bcd(timeptr->tm_min); + rtc_time.hour = bin2bcd(timeptr->tm_hour); + rtc_time.weekday = wday2rtc(timeptr->tm_wday); + rtc_time.day = bin2bcd(timeptr->tm_mday); + rtc_time.month = bin2bcd(timeptr->tm_mon + RX8130CE_MONTHS_OFFSET); + rtc_time.year = bin2bcd(timeptr->tm_year - + (timeptr->tm_year >= RX8130CE_YEARS_OFFSET ? RX8130CE_YEARS_OFFSET : 0)); + + k_sem_take(&data->lock, K_FOREVER); + + rc = i2c_burst_write_dt(&cfg->i2c, TIME, (uint8_t *)&rtc_time, sizeof(rtc_time)); + if (rc != 0) { + LOG_ERR("Failed to write time"); + goto error; + } + LOG_DBG("set time: year = %d, mon = %d, mday = %d, hour = %d, min = %d, sec = %d", + timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); +error: + k_sem_give(&data->lock); + return rc; +} + +#if defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_UPDATE) +static void rx8130ce_irq_work_handler(struct k_work *work) +{ + int rc; + const struct device *dev = CONTAINER_OF(work, struct rx8130ce_data, irq_work)->dev; + struct rx8130ce_data *data = CONTAINER_OF(work, struct rx8130ce_data, irq_work); + const struct rx8130ce_config *cfg = data->dev->config; + #ifdef CONFIG_RTC_ALARM + rtc_alarm_callback alarm_callback = NULL; + void *alarm_user_data = NULL; + #endif /* CONFIG_RTC_ALARM */ + #ifdef CONFIG_RTC_UPDATE + rtc_update_callback update_callback = NULL; + void *update_user_data = NULL; + #endif /* CONFIG_RTC_UPDATE */ + + k_sem_take(&data->lock, K_FOREVER); + rc = i2c_burst_read_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to read flag register"); + goto exit; + } +#ifdef CONFIG_RTC_ALARM + if ((data->reg.flag & FLAG_AF) != 0) { + LOG_INF("Alarm triggered"); + alarm_callback = data->alarm_callback; + alarm_user_data = data->alarm_user_data; + } +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_UPDATE + if ((data->reg.flag & FLAG_UF) != 0) { + LOG_INF("Update triggered"); + update_callback = data->update_callback; + update_user_data = data->update_user_data; + } +#endif /* CONFIG_RTC_UPDATE */ + /* Clear alarm flags */ + data->reg.flag &= ~(FLAG_AF | FLAG_UF); + rc = i2c_burst_write_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to clear alarm flag"); + goto exit; + } +exit: + k_sem_give(&data->lock); + +#ifdef CONFIG_RTC_ALARM + if (alarm_callback) { + alarm_callback(dev, 0, alarm_user_data); + } +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_UPDATE + if (update_callback) { + update_callback(dev, update_user_data); + } +#endif /* CONFIG_RTC_UPDATE */ +} + +static void rx8130ce_irq(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct rx8130ce_data *data = CONTAINER_OF(cb, struct rx8130ce_data, irq_cb); + + LOG_DBG("IRQ-recv"); + k_work_submit(&data->irq_work); +} +#endif /* CONFIG_RTC_ALARM || CONFIG_RTC_UPDATE */ + +#ifdef CONFIG_RTC_ALARM +#define RX8130CE_ALARM_MASK (RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTHDAY) +static int rx8130ce_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask) +{ + const struct rx8130ce_config *cfg = dev->config; + + if (cfg->irq.port == NULL) { + LOG_ERR("IRQ not configured"); + return -ENOTSUP; + } + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + *mask = RX8130CE_ALARM_MASK; + return 0; +} + +static int rx8130ce_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + int rc = 0; + bool alarm_enabled; + struct rx8130ce_alarm alarm_time; + struct rx8130ce_data *data = dev->data; + const struct rx8130ce_config *cfg = dev->config; + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + if ((mask & ~(RX8130CE_ALARM_MASK)) != 0U) { + LOG_ERR("unsupported alarm field mask 0x%04x", mask); + return -EINVAL; + } + + k_sem_take(&data->lock, K_FOREVER); + + rc = i2c_burst_read_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to read control registers"); + goto error; + } + /* Prevent alarm interrupts inadvertently while entering settings/time */ + if ((data->reg.ctrl0 & CTRL0_AIE) != 0) { + alarm_enabled = true; + data->reg.ctrl0 &= ~CTRL0_AIE; + rc = i2c_burst_write_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, + sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to write time"); + goto error; + } + } + + /* Set alarm */ + if (alarm_enabled) { + data->reg.ctrl0 |= CTRL0_AIE; + } + + alarm_time.minute = bin2bcd(timeptr->tm_min); + alarm_time.hour = bin2bcd(timeptr->tm_hour); + alarm_time.day = bin2bcd(timeptr->tm_mday); + data->reg.extension &= ~EXT_WADA; + + if ((mask & RTC_ALARM_TIME_MASK_MINUTE) == 0U) { + alarm_time.minute |= ALARM_DISABLE; + } + if ((mask & RTC_ALARM_TIME_MASK_HOUR) == 0U) { + alarm_time.hour |= ALARM_DISABLE; + } + if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) == 0U) { + alarm_time.day |= ALARM_DISABLE; + } + + /* Write alarm time */ + rc = i2c_burst_write_dt(&cfg->i2c, ALARM, (uint8_t *)&alarm_time, sizeof(alarm_time)); + if (rc != 0) { + LOG_ERR("Failed to write alarm time"); + goto error; + } + + /* Enable alarm */ + rc = i2c_burst_write_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to write control registers"); + goto error; + } +error: + k_sem_give(&data->lock); + return rc; + +} + +static int rx8130ce_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + int rc = 0; + struct rx8130ce_alarm alarm_time; + struct rx8130ce_data *data = dev->data; + const struct rx8130ce_config *cfg = dev->config; + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + k_sem_take(&data->lock, K_FOREVER); + *mask = 0U; + memset(timeptr, 0x00, sizeof(*timeptr)); + rc = i2c_burst_read_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to read control registers"); + goto error; + } + + rc = i2c_burst_read_dt(&cfg->i2c, ALARM, (uint8_t *)&alarm_time, sizeof(alarm_time)); + if (rc != 0) { + LOG_ERR("Failed to read alarm time"); + goto error; + } + + timeptr->tm_min = bcd2bin(alarm_time.minute & RX8130CE_MINUTES_MASK); + timeptr->tm_hour = bcd2bin(alarm_time.hour & RX8130CE_HOURS_MASK); + if (!(alarm_time.minute & ALARM_DISABLE)) { + *mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + if (!(alarm_time.hour & ALARM_DISABLE)) { + *mask |= RTC_ALARM_TIME_MASK_HOUR; + } + if (data->reg.extension & EXT_WADA) { + timeptr->tm_wday = rtc2wday(alarm_time.wday & RX8130CE_WEEKDAYS_MASK); + if (!(alarm_time.wday & ALARM_DISABLE)) { + *mask |= RTC_ALARM_TIME_MASK_WEEKDAY; + } + } else { + timeptr->tm_mday = bcd2bin(alarm_time.day & RX8130CE_DAYS_MASK); + if (!(alarm_time.day & ALARM_DISABLE)) { + *mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } + } +error: + k_sem_give(&data->lock); + return rc; +} + +static int rx8130ce_alarm_is_pending(const struct device *dev, uint16_t id) +{ + int rc = 0; + struct rx8130ce_data *data = dev->data; + const struct rx8130ce_config *cfg = dev->config; + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + k_sem_take(&data->lock, K_FOREVER); + rc = i2c_burst_read_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to read control registers"); + goto error; + } + + rc = (data->reg.ctrl0 & CTRL0_AIE) != 0; +error: + k_sem_give(&data->lock); + return rc; +} + +static int rx8130ce_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + int rc = 0; + struct rx8130ce_data *data = dev->data; + const struct rx8130ce_config *cfg = dev->config; + + if (id != 0U) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + if (cfg->irq.port == NULL) { + LOG_ERR("IRQ not configured"); + return -ENOTSUP; + } + + k_sem_take(&data->lock, K_FOREVER); + rc = i2c_burst_read_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to read control registers"); + goto exit; + } + if (callback == NULL) { + data->alarm_user_data = NULL; + data->alarm_callback = NULL; + data->reg.ctrl0 &= ~CTRL0_AIE; +#ifdef CONFIG_RTC_UPDATE + if (data->update_callback == NULL) { +#endif + rc = gpio_pin_interrupt_configure_dt(&cfg->irq, GPIO_INT_DISABLE); + if (rc != 0) { + LOG_ERR("Failed to disable interrupt"); + goto exit; + } +#ifdef CONFIG_RTC_UPDATE + } +#endif + } else { + /* Enable alarm interrupt & clear Alarm flag */ + data->reg.ctrl0 |= CTRL0_AIE; + data->reg.flag &= ~FLAG_AF; + data->alarm_callback = callback; + data->alarm_user_data = user_data; + rc = gpio_pin_interrupt_configure_dt(&cfg->irq, GPIO_INT_EDGE_TO_ACTIVE); + if (rc != 0) { + LOG_ERR("Failed to configure interrupt"); + goto exit; + } + } + rc = i2c_burst_write_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to write control registers"); + goto exit; + } +exit: + k_sem_give(&data->lock); + return rc; +} +#endif /* CONFIG_RTC_ALARM */ + +#ifdef CONFIG_RTC_UPDATE +static int rx8130ce_update_set_callback(const struct device *dev, rtc_update_callback callback, + void *user_data) +{ + int rc = 0; + const struct rx8130ce_config *cfg = dev->config; + struct rx8130ce_data *data = dev->data; + + if (cfg->irq.port == NULL) { + LOG_ERR("IRQ not configured"); + return -ENOTSUP; + } + + k_sem_take(&data->lock, K_FOREVER); + rc = i2c_burst_read_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to read control registers"); + goto exit; + } + if (callback == NULL) { + data->reg.ctrl0 &= ~CTRL0_UIE; + data->update_user_data = NULL; + data->update_callback = NULL; + + #ifdef CONFIG_RTC_ALARM + if (data->alarm_callback == NULL) { + #endif + rc = gpio_pin_interrupt_configure_dt(&cfg->irq, GPIO_INT_DISABLE); + if (rc != 0) { + LOG_ERR("Failed to disable interrupt"); + goto exit; + } + #ifdef CONFIG_RTC_ALARM + } + #endif + } else { + data->reg.ctrl0 |= CTRL0_UIE; + data->update_callback = callback; + data->update_user_data = user_data; + rc = gpio_pin_interrupt_configure_dt(&cfg->irq, GPIO_INT_EDGE_TO_ACTIVE); + if (rc != 0) { + LOG_ERR("Failed to configure interrupt"); + goto exit; + } + } + rc = i2c_burst_write_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to write control registers"); + goto exit; + } +exit: + k_sem_give(&data->lock); + return rc; + +} +#endif /* CONFIG_RTC_UPDATE */ + +#ifdef CONFIG_RTC_CALIBRATION +static int rx8130ce_set_calibration(const struct device *dev, int32_t freq_ppb) +{ + int rc; + const struct rx8130ce_config *cfg = dev->config; + struct rx8130ce_data *data = dev->data; + uint8_t offset = 0; + + if (freq_ppb < DIGITAL_OFFSET_MIN || freq_ppb > DIGITAL_OFFSET_MAX) { + LOG_ERR("Invalid calibration value: %d", freq_ppb); + return -EINVAL; + } + + k_sem_take(&data->lock, K_FOREVER); + /* Explanation see section 17 of the datasheet */ + if (freq_ppb < 0) { + offset |= DIGITAL_OFFSET_DTE; + offset |= DIGITAL_OFFSET_NEG; + offset |= 128 - (-freq_ppb / DIGITAL_OFFSET_STEP_PPB); + } else if (freq_ppb > 0) { + offset |= DIGITAL_OFFSET_DTE; + offset |= freq_ppb / DIGITAL_OFFSET_STEP_PPB; + } + LOG_DBG("set calibration: offset = 0x%02x, from %d", offset, freq_ppb); + + rc = i2c_burst_write_dt(&cfg->i2c, OFFSET, &offset, sizeof(offset)); + if (rc != 0) { + LOG_ERR("Failed to write calibration value"); + goto exit; + } +exit: + k_sem_give(&data->lock); + return rc; +} + +static int rx8130ce_get_calibration(const struct device *dev, int32_t *freq_ppb) +{ + int rc; + const struct rx8130ce_config *cfg = dev->config; + struct rx8130ce_data *data = dev->data; + uint8_t offset; + *freq_ppb = 0; + + k_sem_take(&data->lock, K_FOREVER); + rc = i2c_burst_read_dt(&cfg->i2c, OFFSET, &offset, sizeof(offset)); + if (rc != 0) { + LOG_ERR("Failed to read calibration value"); + goto exit; + } + /* Explanation see section 17 of the datasheet */ + if (offset & DIGITAL_OFFSET_DTE) { + offset &= ~DIGITAL_OFFSET_DTE; + if (offset & DIGITAL_OFFSET_NEG) { + *freq_ppb = -((128 - offset) * DIGITAL_OFFSET_STEP_PPB); + } else { + *freq_ppb = offset * DIGITAL_OFFSET_STEP_PPB; + } + } + LOG_DBG("get calibration: offset = 0x%02x, freq_ppb = %d", offset, *freq_ppb); + +exit: + k_sem_give(&data->lock); + return rc; +} +#endif /* CONFIG_RTC_CALIBRATION */ + + +static int rx8130ce_init(const struct device *dev) +{ + int rc; + const struct rx8130ce_config *cfg = dev->config; + struct rx8130ce_data *data = dev->data; + + data->dev = dev; + k_sem_init(&data->lock, 1, 1); + if (!i2c_is_ready_dt(&cfg->i2c)) { + LOG_ERR("I2C bus not ready"); + return -ENODEV; + } + + /* read all control registers */ + rc = i2c_burst_read_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to read control registers"); + return rc; + } + data->reg.flag = 0x00; + data->reg.extension &= ~EXT_TE; + + + switch (cfg->clockout_frequency) { + case 0: /* OFF */ + data->reg.extension |= EXT_FSEL1 | EXT_FSEL0; + break; + case 1: /* 1 Hz */ + data->reg.extension &= ~EXT_FSEL0; + data->reg.extension |= EXT_FSEL1; + break; + case 1024: /* 1.024 kHz */ + data->reg.extension |= EXT_FSEL0; + data->reg.extension &= ~EXT_FSEL1; + break; + case 32768: /* 32.768 kHz */ + data->reg.extension &= ~(EXT_FSEL1 | EXT_FSEL0); + break; + default: + LOG_ERR("Invalid clockout frequency option: %d", cfg->clockout_frequency); + return -EINVAL; + } + + if (cfg->battery_switchover != 0) { + /* Enable initial voltage detection, following settings depend + * on if the CTRL1_INIEN has been set prior (lifetime) + */ + data->reg.ctrl1 |= CTRL1_INIEN; + rc = i2c_burst_write_dt(&cfg->i2c, CTRL1, + (uint8_t *)&data->reg.ctrl1, sizeof(data->reg.ctrl1)); + if (rc != 0) { + LOG_ERR("Failed to write ctrl1 register"); + return rc; + } + } + + switch (cfg->battery_switchover) { + case 1: /* Power switch on, non rechargeable battery */ + data->reg.ctrl1 |= CTRL1_INIEN; + break; + case 2: /* Power switch on, rechargeable battery */ + data->reg.ctrl1 &= ~(CTRL1_INIEN | CTRL1_CHGEN); + break; + case 3: /* Power switch on, rechargeable battery, i2c & Fout disabled if VDD < Vdet1 */ + data->reg.ctrl1 |= CTRL1_CHGEN | CTRL1_INIEN; + break; + case 4: /* Power switch on, rechargeable battery, i2c & Fout always enabled */ + data->reg.ctrl1 |= CTRL1_CHGEN; + data->reg.ctrl1 &= ~CTRL1_INIEN; + break; + } + +#if defined(CONFIG_RTC_ALARM) || defined(CONFIG_RTC_UPDATE) + k_work_init(&data->irq_work, rx8130ce_irq_work_handler); + if (cfg->irq.port != NULL) { + gpio_pin_configure_dt(&cfg->irq, GPIO_INPUT); + gpio_init_callback(&data->irq_cb, rx8130ce_irq, BIT(cfg->irq.pin)); + rc = gpio_add_callback_dt(&cfg->irq, &data->irq_cb); + if (rc != 0) { + LOG_ERR("Failed to add callback"); + return rc; + } + } +#endif /* CONFIG_RTC_ALARM || CONFIG_RTC_UPDATE */ + rc = i2c_burst_write_dt(&cfg->i2c, EXTENSION, (uint8_t *)&data->reg, sizeof(data->reg)); + if (rc != 0) { + LOG_ERR("Failed to write control registers"); + return rc; + } + return 0; +} +static DEVICE_API(rtc, rx8130ce_driver_api) = { + .set_time = rx8130ce_set_time, + .get_time = rx8130ce_get_time, +#ifdef CONFIG_RTC_ALARM + .alarm_get_supported_fields = rx8130ce_alarm_get_supported_fields, + .alarm_set_time = rx8130ce_alarm_set_time, + .alarm_get_time = rx8130ce_alarm_get_time, + .alarm_is_pending = rx8130ce_alarm_is_pending, + .alarm_set_callback = rx8130ce_alarm_set_callback, +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_UPDATE + .update_set_callback = rx8130ce_update_set_callback, +#endif /* CONFIG_RTC_UPDATE */ +#ifdef CONFIG_RTC_CALIBRATION + .set_calibration = rx8130ce_set_calibration, + .get_calibration = rx8130ce_get_calibration, +#endif /* CONFIG_RTC_CALIBRATION */ +}; + +#define RX8130CE_INIT(inst) \ + static const struct rx8130ce_config rx8130ce_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .clockout_frequency = DT_INST_PROP_OR(inst, clockout_frequency, 0), \ + .battery_switchover = DT_INST_PROP_OR(inst, battery_switchover, 0), \ + .irq = GPIO_DT_SPEC_INST_GET_OR(inst, irq_gpios, {0}), \ + }; \ + \ + static struct rx8130ce_data rx8130ce_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, &rx8130ce_init, NULL, \ + &rx8130ce_data_##inst, &rx8130ce_config_##inst, POST_KERNEL, \ + CONFIG_RTC_INIT_PRIORITY, &rx8130ce_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RX8130CE_INIT) diff --git a/drivers/rtc/rtc_sam0.c b/drivers/rtc/rtc_sam0.c new file mode 100644 index 0000000000000..a6dc578a01da7 --- /dev/null +++ b/drivers/rtc/rtc_sam0.c @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2024-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT atmel_sam0_rtc + +/** @file + * @brief RTC driver for Atmel SAM0 MCU family. + */ + +#include + +#include +#include +#include "rtc_utils.h" + +#include +LOG_MODULE_REGISTER(rtc_sam0, CONFIG_RTC_LOG_LEVEL); + +/* clang-format off */ + +#define RTC_SAM0_TIME_MASK \ + (RTC_ALARM_TIME_MASK_SECOND \ + | RTC_ALARM_TIME_MASK_MINUTE \ + | RTC_ALARM_TIME_MASK_HOUR \ + | RTC_ALARM_TIME_MASK_MONTHDAY \ + | RTC_ALARM_TIME_MASK_MONTH \ + | RTC_ALARM_TIME_MASK_YEAR \ + ) + +#define RTC_SAM0_CALIBRATE_PPB_MAX (127) +#define RTC_SAM0_CALIBRATE_PPB_QUANTA (1000) + +enum rtc_sam0_counter_mode { + COUNTER_MODE_0, + COUNTER_MODE_1, + COUNTER_MODE_2, +}; + +struct rtc_sam0_config { + Rtc *regs; + enum rtc_sam0_counter_mode mode; + uint16_t prescaler; + + volatile uint32_t *mclk; + uint32_t mclk_mask; + uint32_t gclk_gen; + uint16_t gclk_id; + bool has_gclk; + bool has_osc32kctrl; + uint8_t osc32_src; + uint32_t evt_ctrl_msk; + +#ifdef CONFIG_RTC_ALARM + uint8_t alarms_count; +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_CALIBRATION + int32_t cal_constant; +#endif +}; + +struct rtc_sam0_data_cb { + rtc_alarm_callback cb; + void *cb_data; +}; + +struct rtc_sam0_data { + struct k_spinlock lock; +#ifdef CONFIG_RTC_ALARM + struct rtc_sam0_data_cb *const alarms; +#endif /* CONFIG_RTC_ALARM */ +}; + +static inline void rtc_sam0_sync(Rtc *rtc) +{ + /* Wait for synchronization */ +#ifdef MCLK + while (rtc->MODE0.SYNCBUSY.reg & RTC_MODE0_SYNCBUSY_MASK) { + } +#else + while (rtc->MODE0.STATUS.reg & RTC_STATUS_SYNCBUSY) { + } +#endif +} + +static int rtc_sam0_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + const struct rtc_sam0_config *cfg = dev->config; + struct rtc_sam0_data *data = dev->data; + RtcMode2 *regs = &cfg->regs->MODE2; + uint32_t datetime = 0; + + if (rtc_utils_validate_rtc_time(timeptr, RTC_SAM0_TIME_MASK) == false) { + return -EINVAL; + } + + datetime |= RTC_MODE2_CLOCK_SECOND(timeptr->tm_sec); + datetime |= RTC_MODE2_CLOCK_MINUTE(timeptr->tm_min); + datetime |= RTC_MODE2_CLOCK_HOUR(timeptr->tm_hour); + datetime |= RTC_MODE2_CLOCK_DAY(timeptr->tm_mday); + datetime |= RTC_MODE2_CLOCK_MONTH(timeptr->tm_mon + 1); + datetime |= RTC_MODE2_CLOCK_YEAR(timeptr->tm_year - 99); + + k_spinlock_key_t key = k_spin_lock(&data->lock); + +#ifdef MCLK + regs->CTRLA.reg &= ~RTC_MODE0_CTRLA_ENABLE; + rtc_sam0_sync(cfg->regs); + regs->CLOCK.reg = datetime; + regs->CTRLA.reg |= RTC_MODE0_CTRLA_ENABLE; +#else + regs->CTRL.reg &= ~RTC_MODE0_CTRL_ENABLE; + rtc_sam0_sync(cfg->regs); + regs->CLOCK.reg = datetime; + regs->CTRL.reg |= RTC_MODE0_CTRL_ENABLE; +#endif + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int rtc_sam0_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + const struct rtc_sam0_config *cfg = dev->config; + RTC_MODE2_CLOCK_Type calendar = cfg->regs->MODE2.CLOCK; + + timeptr->tm_sec = calendar.bit.SECOND; + timeptr->tm_min = calendar.bit.MINUTE; + timeptr->tm_hour = calendar.bit.HOUR; + timeptr->tm_mday = calendar.bit.DAY; + timeptr->tm_mon = calendar.bit.MONTH - 1; + timeptr->tm_year = calendar.bit.YEAR + 99; + timeptr->tm_wday = -1; + timeptr->tm_yday = -1; + timeptr->tm_isdst = -1; + timeptr->tm_nsec = 0; + + LOG_DBG("D/M/Y H:M:S %02d/%02d/%02d %02d:%02d:%02d", + timeptr->tm_mday, timeptr->tm_mon + 1, timeptr->tm_year - 99, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + + return 0; +} + +#ifdef CONFIG_RTC_ALARM +static inline uint32_t rtc_sam0_datetime_from_tm(const struct rtc_time *timeptr, + uint32_t mask) +{ + uint32_t datetime = 0; + + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + datetime |= RTC_MODE2_CLOCK_SECOND(timeptr->tm_sec); + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + datetime |= RTC_MODE2_CLOCK_MINUTE(timeptr->tm_min); + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + datetime |= RTC_MODE2_CLOCK_HOUR(timeptr->tm_hour); + } + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + datetime |= RTC_MODE2_CLOCK_DAY(timeptr->tm_mday); + } + + if (mask & RTC_ALARM_TIME_MASK_MONTH) { + datetime |= RTC_MODE2_CLOCK_MONTH(timeptr->tm_mon + 1); + } + + if (mask & RTC_ALARM_TIME_MASK_YEAR) { + datetime |= RTC_MODE2_CLOCK_YEAR(timeptr->tm_year - 99); + } + + return datetime; +} + +static inline void rtc_sam0_tm_from_datetime(struct rtc_time *timeptr, uint32_t mask, + RTC_MODE2_ALARM_Type calendar) +{ + memset(timeptr, 0x00, sizeof(struct rtc_time)); + + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + timeptr->tm_sec = calendar.bit.SECOND; + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + timeptr->tm_min = calendar.bit.MINUTE; + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + timeptr->tm_hour = calendar.bit.HOUR; + } + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + timeptr->tm_mday = calendar.bit.DAY; + } + + if (mask & RTC_ALARM_TIME_MASK_MONTH) { + timeptr->tm_mon = calendar.bit.MONTH - 1; + } + + if (mask & RTC_ALARM_TIME_MASK_YEAR) { + timeptr->tm_year = calendar.bit.YEAR + 99; + } + + timeptr->tm_wday = -1; + timeptr->tm_yday = -1; + timeptr->tm_isdst = -1; + timeptr->tm_nsec = 0; +} + +static inline uint32_t rtc_sam0_alarm_msk_from_mask(uint32_t mask) +{ + uint32_t alarm_mask = 0; + + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + alarm_mask = RTC_MODE2_MASK_SEL_SS_Val; + } + + if (mask & RTC_ALARM_TIME_MASK_MINUTE) { + alarm_mask = RTC_MODE2_MASK_SEL_MMSS_Val; + } + + if (mask & RTC_ALARM_TIME_MASK_HOUR) { + alarm_mask = RTC_MODE2_MASK_SEL_HHMMSS_Val; + } + + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + alarm_mask = RTC_MODE2_MASK_SEL_DDHHMMSS_Val; + } + + if (mask & RTC_ALARM_TIME_MASK_MONTH) { + alarm_mask = RTC_MODE2_MASK_SEL_MMDDHHMMSS_Val; + } + + if (mask & RTC_ALARM_TIME_MASK_YEAR) { + alarm_mask = RTC_MODE2_MASK_SEL_YYMMDDHHMMSS_Val; + } + + return alarm_mask; +} + +static inline uint32_t rtc_sam0_mask_from_alarm_msk(uint32_t alarm_mask) +{ + uint32_t mask = 0; + + switch (alarm_mask) { + case RTC_MODE2_MASK_SEL_YYMMDDHHMMSS_Val: + mask |= RTC_ALARM_TIME_MASK_YEAR; + __fallthrough; + case RTC_MODE2_MASK_SEL_MMDDHHMMSS_Val: + mask |= RTC_ALARM_TIME_MASK_MONTH; + __fallthrough; + case RTC_MODE2_MASK_SEL_DDHHMMSS_Val: + mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + __fallthrough; + case RTC_MODE2_MASK_SEL_HHMMSS_Val: + mask |= RTC_ALARM_TIME_MASK_HOUR; + __fallthrough; + case RTC_MODE2_MASK_SEL_MMSS_Val: + mask |= RTC_ALARM_TIME_MASK_MINUTE; + __fallthrough; + case RTC_MODE2_MASK_SEL_SS_Val: + mask |= RTC_ALARM_TIME_MASK_SECOND; + break; + default: + break; + } + + return mask; +} + +static int rtc_sam0_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask) +{ + ARG_UNUSED(dev); + ARG_UNUSED(id); + + *mask = RTC_SAM0_TIME_MASK; + + return 0; +} + +static int rtc_sam0_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + const struct rtc_sam0_config *cfg = dev->config; + struct rtc_sam0_data *data = dev->data; + RtcMode2 *regs = &cfg->regs->MODE2; + uint32_t mask_supported = RTC_SAM0_TIME_MASK; + uint32_t datetime; + uint32_t alarm_msk; + + if (BIT(id) > RTC_MODE2_INTFLAG_ALARM_Msk) { + return -EINVAL; + } + + if ((mask > 0) && (timeptr == NULL)) { + return -EINVAL; + } + + if (mask & ~mask_supported) { + return -EINVAL; + } + + if (rtc_utils_validate_rtc_time(timeptr, mask) == false) { + return -EINVAL; + } + + datetime = rtc_sam0_datetime_from_tm(timeptr, mask); + alarm_msk = rtc_sam0_alarm_msk_from_mask(mask); + + LOG_DBG("S: datetime: %d, mask: %d", datetime, alarm_msk); + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + irq_disable(DT_INST_IRQN(0)); + + rtc_sam0_sync(cfg->regs); + regs->Mode2Alarm[id].ALARM.reg = datetime; + regs->Mode2Alarm[id].MASK.reg = RTC_MODE2_MASK_SEL(alarm_msk); + regs->INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM(BIT(id)); + + irq_enable(DT_INST_IRQN(0)); + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int rtc_sam0_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + const struct rtc_sam0_config *cfg = dev->config; + struct rtc_sam0_data *data = dev->data; + RtcMode2 *regs = &cfg->regs->MODE2; + RTC_MODE2_ALARM_Type datetime; + uint32_t alarm_msk; + + if (BIT(id) > RTC_MODE2_INTFLAG_ALARM_Msk) { + return -EINVAL; + } + + if ((mask == NULL) || (timeptr == NULL)) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + rtc_sam0_sync(cfg->regs); + + datetime = regs->Mode2Alarm[id].ALARM; + alarm_msk = regs->Mode2Alarm[id].MASK.reg; + + LOG_DBG("G: datetime: %d, mask: %d", datetime.reg, alarm_msk); + + k_spin_unlock(&data->lock, key); + + *mask = rtc_sam0_mask_from_alarm_msk(alarm_msk); + + rtc_sam0_tm_from_datetime(timeptr, *mask, datetime); + + return 0; +} + +static int rtc_sam0_alarm_is_pending(const struct device *dev, uint16_t id) +{ + const struct rtc_sam0_config *cfg = dev->config; + struct rtc_sam0_data *data = dev->data; + RtcMode2 *regs = &cfg->regs->MODE2; + + if (BIT(id) > RTC_MODE2_INTFLAG_ALARM_Msk) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if ((regs->INTFLAG.reg & RTC_MODE2_INTFLAG_ALARM(BIT(id))) == 0) { + k_spin_unlock(&data->lock, key); + + return 0; + } + + regs->INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM(BIT(id)); + + k_spin_unlock(&data->lock, key); + + return 1; +} + +static int rtc_sam0_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + const struct rtc_sam0_config *cfg = dev->config; + struct rtc_sam0_data *data = dev->data; + RtcMode2 *regs = &cfg->regs->MODE2; + + if (BIT(id) > RTC_MODE2_INTFLAG_ALARM_Msk) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->alarms[id].cb = callback; + data->alarms[id].cb_data = user_data; + + if (callback) { + regs->INTENSET.reg = RTC_MODE2_INTENSET_ALARM(BIT(id)); + } else { + regs->INTENCLR.reg = RTC_MODE2_INTENCLR_ALARM(BIT(id)); + } + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static void rtc_sam0_isr(const struct device *dev) +{ + const struct rtc_sam0_config *cfg = dev->config; + struct rtc_sam0_data *data = dev->data; + RtcMode2 *regs = &cfg->regs->MODE2; + uint32_t int_flags = regs->INTFLAG.reg; + + for (int i = 0; i < cfg->alarms_count; ++i) { + if (int_flags & RTC_MODE2_INTFLAG_ALARM(BIT(i))) { + if (data->alarms[i].cb != NULL) { + data->alarms[i].cb(dev, i, data->alarms[i].cb_data); + } + } + } + + regs->INTFLAG.reg |= int_flags; +} + +#endif /* CONFIG_RTC_ALARM */ + +#ifdef CONFIG_RTC_CALIBRATION +static int rtc_sam0_set_calibration(const struct device *dev, int32_t calibration) +{ + const struct rtc_sam0_config *cfg = dev->config; + RtcMode2 *regs = &cfg->regs->MODE2; + int32_t correction = calibration / (1000000000 / cfg->cal_constant); + uint32_t abs_correction = abs(correction); + + LOG_DBG("Correction: %d, Absolute: %d, Calibration: %d", + correction, abs_correction, calibration); + + if (abs_correction == 0) { + regs->FREQCORR.reg = 0; + return 0; + } + + if (abs_correction > RTC_SAM0_CALIBRATE_PPB_MAX) { + LOG_ERR("The calibration %d result in an out of range value %d", + calibration, abs_correction); + return -EINVAL; + } + + rtc_sam0_sync(cfg->regs); + regs->FREQCORR.reg = RTC_FREQCORR_VALUE(abs_correction) + | (correction < 0 ? RTC_FREQCORR_SIGN : 0); + + LOG_DBG("W REG: 0x%02x", regs->FREQCORR.reg); + + return 0; +} + +static int rtc_sam0_get_calibration(const struct device *dev, int32_t *calibration) +{ + const struct rtc_sam0_config *cfg = dev->config; + RtcMode2 *regs = &cfg->regs->MODE2; + int32_t correction; + + if (calibration == NULL) { + return -EINVAL; + } + + correction = regs->FREQCORR.bit.VALUE; + + if (correction == 0) { + *calibration = 0; + } else { + *calibration = (correction * 1000000000) / cfg->cal_constant; + } + + if (regs->FREQCORR.bit.SIGN) { + *calibration *= -1; + } + + LOG_DBG("R REG: 0x%02x", regs->FREQCORR.reg); + + return 0; +} +#endif /* CONFIG_RTC_CALIBRATION */ + +static int rtc_sam0_init(const struct device *dev) +{ + const struct rtc_sam0_config *cfg = dev->config; + RtcMode0 *regs = &cfg->regs->MODE0; + + LOG_DBG("Counter Mode %d selected", cfg->mode); + LOG_DBG("gclk_id: %d, gclk_gen: %d, prescaler: %d, osc32k: %d", + cfg->gclk_id, cfg->gclk_gen, cfg->prescaler, cfg->osc32_src); + + *cfg->mclk |= cfg->mclk_mask; + +#ifdef MCLK + if (cfg->has_gclk) { + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); + } +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); +#endif + rtc_sam0_sync(cfg->regs); + +#ifdef MCLK + if (cfg->has_osc32kctrl) { + OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL(cfg->osc32_src); + } +#endif + + rtc_sam0_sync(cfg->regs); + regs->EVCTRL.reg = (cfg->evt_ctrl_msk & RTC_MODE0_EVCTRL_MASK); + +#ifdef MCLK + regs->CTRLA.reg = RTC_MODE0_CTRLA_ENABLE + | RTC_MODE0_CTRLA_COUNTSYNC + | RTC_MODE0_CTRLA_MODE(cfg->mode) + | RTC_MODE0_CTRLA_PRESCALER(cfg->prescaler + 1); +#else + regs->CTRL.reg = RTC_MODE0_CTRL_ENABLE + | RTC_MODE0_CTRL_MODE(cfg->mode) + | RTC_MODE0_CTRL_PRESCALER(cfg->prescaler); +#endif + + regs->INTFLAG.reg = 0; +#ifdef CONFIG_RTC_ALARM + IRQ_CONNECT(DT_INST_IRQN(0), + DT_INST_IRQ(0, priority), + rtc_sam0_isr, + DEVICE_DT_INST_GET(0), 0); + irq_enable(DT_INST_IRQN(0)); +#endif + return 0; +} + +static DEVICE_API(rtc, rtc_sam0_driver_api) = { + .set_time = rtc_sam0_set_time, + .get_time = rtc_sam0_get_time, +#ifdef CONFIG_RTC_ALARM + .alarm_get_supported_fields = rtc_sam0_alarm_get_supported_fields, + .alarm_set_time = rtc_sam0_alarm_set_time, + .alarm_get_time = rtc_sam0_alarm_get_time, + .alarm_is_pending = rtc_sam0_alarm_is_pending, + .alarm_set_callback = rtc_sam0_alarm_set_callback, +#endif /* CONFIG_RTC_ALARM */ +#ifdef CONFIG_RTC_CALIBRATION + .set_calibration = rtc_sam0_set_calibration, + .get_calibration = rtc_sam0_get_calibration, +#endif /* CONFIG_RTC_CALIBRATION */ +}; + +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define RTC_SAM0_GCLK(n) \ + COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(n, gclk), \ + ( \ + .has_gclk = true, \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id) \ + ), \ + ( \ + .has_gclk = false, \ + .gclk_gen = 0, \ + .gclk_id = 0 \ + )) + +#define RTC_SAM0_OSC32KCTRL(n) \ + COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(n, osc32kctrl), \ + ( \ + .has_osc32kctrl = true, \ + .osc32_src = ASSIGNED_CLOCKS_CELL_BY_NAME(n, osc32kctrl, src) \ + ), \ + ( \ + .has_osc32kctrl = false, \ + .osc32_src = 0 \ + )) + +#define RTC_SAM0_DEVICE(n) \ + BUILD_ASSERT(DT_INST_NODE_HAS_PROP(n, counter_mode), \ + "sam0:rtc: Missing counter-mode devicetree property"); \ + BUILD_ASSERT(DT_INST_NODE_HAS_PROP(n, prescaler), \ + "sam0:rtc: Missing prescaler devicetree property"); \ + \ + static const struct rtc_sam0_config rtc_sam0_config_##n = { \ + .regs = (Rtc *)DT_INST_REG_ADDR(n), \ + .mode = DT_INST_ENUM_IDX(n, counter_mode), \ + .prescaler = DT_INST_ENUM_IDX(n, prescaler), \ + .evt_ctrl_msk = DT_INST_PROP(n, event_control_msk), \ + RTC_SAM0_GCLK(n), \ + RTC_SAM0_OSC32KCTRL(n), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ + IF_ENABLED(CONFIG_RTC_ALARM, ( \ + .alarms_count = DT_INST_PROP(n, alarms_count), \ + )) \ + IF_ENABLED(CONFIG_RTC_CALIBRATION, ( \ + .cal_constant = DT_INST_PROP(n, cal_constant), \ + )) \ + }; \ + \ + IF_ENABLED(CONFIG_RTC_ALARM, ( \ + static struct rtc_sam0_data_cb \ + rtc_sam0_data_cb_##n[DT_INST_PROP(n, alarms_count)] = {}; \ + )) \ + \ + static struct rtc_sam0_data rtc_sam0_data_##n = { \ + IF_ENABLED(CONFIG_RTC_ALARM, ( \ + .alarms = rtc_sam0_data_cb_##n, \ + )) \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, rtc_sam0_init, \ + NULL, \ + &rtc_sam0_data_##n, \ + &rtc_sam0_config_##n, POST_KERNEL, \ + CONFIG_RTC_INIT_PRIORITY, \ + &rtc_sam0_driver_api); \ + +DT_INST_FOREACH_STATUS_OKAY(RTC_SAM0_DEVICE); + +/* clang-format on */ diff --git a/drivers/rtc/rtc_shell.c b/drivers/rtc/rtc_shell.c index a87056c6ed707..2ea8ba3047d23 100644 --- a/drivers/rtc/rtc_shell.c +++ b/drivers/rtc/rtc_shell.c @@ -148,7 +148,7 @@ static char *strptime(const char *s, const char *format, struct tm *tm_time) static int cmd_set(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); if (!device_is_ready(dev)) { shell_error(sh, "device %s not ready", argv[1]); @@ -191,7 +191,7 @@ static int cmd_set(const struct shell *sh, size_t argc, char **argv) static int cmd_get(const struct shell *sh, size_t argc, char **argv) { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); if (!device_is_ready(dev)) { shell_error(sh, "device %s not ready", argv[1]); @@ -217,9 +217,14 @@ static int cmd_get(const struct shell *sh, size_t argc, char **argv) return 0; } +static bool device_is_rtc(const struct device *dev) +{ + return DEVICE_API_IS(rtc, dev); +} + static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_rtc); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/sdhc/CMakeLists.txt b/drivers/sdhc/CMakeLists.txt index 42985f873f1f0..d2f0cf1e11309 100644 --- a/drivers/sdhc/CMakeLists.txt +++ b/drivers/sdhc/CMakeLists.txt @@ -12,4 +12,6 @@ zephyr_library_sources_ifdef(CONFIG_INTEL_EMMC_HOST intel_emmc_host.c) zephyr_library_sources_ifdef(CONFIG_SDHC_INFINEON_CAT1 ifx_cat1_sdio.c) zephyr_library_sources_ifdef(CONFIG_CDNS_SDHC sdhc_cdns_ll.c sdhc_cdns.c) zephyr_library_sources_ifdef(CONFIG_SDHC_ESP32 sdhc_esp32.c) +zephyr_library_sources_ifdef(CONFIG_SDHC_RENESAS_RA sdhc_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_SDHC_MAX32 sdhc_max32.c) endif() diff --git a/drivers/sdhc/Kconfig b/drivers/sdhc/Kconfig index b6b1276207b95..8791d828e10c0 100644 --- a/drivers/sdhc/Kconfig +++ b/drivers/sdhc/Kconfig @@ -2,9 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 menuconfig SDHC - bool "Secure Digital High Capacity (SDHC) drivers" + bool "Secure Digital (SD card) host controller drivers" help - Include drivers for SD host controller + Include drivers for interacting with SD cards if SDHC @@ -17,6 +17,8 @@ source "drivers/sdhc/Kconfig.sam_hsmci" source "drivers/sdhc/Kconfig.intel" source "drivers/sdhc/Kconfig.sdhc_cdns" source "drivers/sdhc/Kconfig.esp32" +source "drivers/sdhc/Kconfig.renesas_ra" +source "drivers/sdhc/Kconfig.max32" config SDHC_INIT_PRIORITY int "SDHC driver init priority" diff --git a/drivers/sdhc/Kconfig.max32 b/drivers/sdhc/Kconfig.max32 new file mode 100644 index 0000000000000..71212042ae137 --- /dev/null +++ b/drivers/sdhc/Kconfig.max32 @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SDHC_MAX32 + bool "Analog Devices MAX32 SDHC driver" + default y + depends on DT_HAS_ADI_MAX32_SDHC_ENABLED + select SDHC_SUPPORTS_NATIVE_MODE + help + sdhc driver for max32 family. diff --git a/drivers/sdhc/Kconfig.renesas_ra b/drivers/sdhc/Kconfig.renesas_ra new file mode 100644 index 0000000000000..04313f23c1fba --- /dev/null +++ b/drivers/sdhc/Kconfig.renesas_ra @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SDHC_RENESAS_RA + bool "Renesas RA SDHI driver" + default y + depends on DT_HAS_RENESAS_RA_SDHC_ENABLED + select SDHC_SUPPORTS_NATIVE_MODE + select USE_RA_FSP_SDHI + select USE_RA_FSP_DTC + select PINCTRL + help + Enables Renesas SD Host controller driver diff --git a/drivers/sdhc/ifx_cat1_sdio.c b/drivers/sdhc/ifx_cat1_sdio.c index 537b68e339579..4449b532f0b29 100644 --- a/drivers/sdhc/ifx_cat1_sdio.c +++ b/drivers/sdhc/ifx_cat1_sdio.c @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -283,13 +284,21 @@ static int ifx_cat1_sdio_init(const struct device *dev) } /* Dedicate SDIO HW resource */ - data->hw_resource.type = CYHAL_RSC_SDIODEV; + data->hw_resource.type = CYHAL_RSC_SDHC; data->hw_resource.block_num = _get_hw_block_num(config->reg_addr); + data->hw_resource.channel_num = 0; /* Initialize the SDIO peripheral */ data->cyhal_sdio_config.resource = &data->hw_resource; data->cyhal_sdio_config.host_config = &host_config, data->cyhal_sdio_config.card_config = &sd_host_sd_card_config, + data->cyhal_sdio_config.gpios.cmd = NC; + data->cyhal_sdio_config.gpios.clk = NC; + data->cyhal_sdio_config.gpios.data[0] = NC; + data->cyhal_sdio_config.gpios.data[1] = NC; + data->cyhal_sdio_config.gpios.data[2] = NC; + data->cyhal_sdio_config.gpios.data[3] = NC; + data->cyhal_sdio_config.clock = NULL; ret = cyhal_sdio_init_cfg(&data->sdio_obj, &data->cyhal_sdio_config); if (ret != CY_RSLT_SUCCESS) { diff --git a/drivers/sdhc/sdhc_max32.c b/drivers/sdhc/sdhc_max32.c new file mode 100644 index 0000000000000..0bc8caa3233c0 --- /dev/null +++ b/drivers/sdhc/sdhc_max32.c @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max32_sdhc + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(sdhc_max32, CONFIG_SDHC_LOG_LEVEL); + +static int cmd_opcode_converter(int opcode, unsigned int *cmd); +static int convert_freq_to_divider(int freq); + +/* **** Definitions **** + * todo: added from sdhc_resp_regs.h cmd51 is mandatory and is missing in msdk. + * SDHC commands and associated cmd register bits which inform hardware to wait for response, etc. + */ +#define MXC_SDHC_LIB_CMD0 0x0000 +#define MXC_SDHC_LIB_CMD1 0x0102 +#define MXC_SDHC_LIB_CMD2 0x0209 +#define MXC_SDHC_LIB_CMD3 0x031A +#define MXC_SDHC_LIB_CMD4 0x0400 +#define MXC_SDHC_LIB_CMD5 0x051A +#define MXC_SDHC_LIB_CMD6 0x060A +#define MXC_SDHC_LIB_CMD7 0x071B +#define MXC_SDHC_LIB_CMD8 0x081A +#define MXC_SDHC_LIB_CMD9 0x0901 +#define MXC_SDHC_LIB_CMD10 0x0A01 +#define MXC_SDHC_LIB_CMD11 0x0B1A +#define MXC_SDHC_LIB_CMD12 0x0C1B +#define MXC_SDHC_LIB_CMD13 0x0D1A +#define MXC_SDHC_LIB_CMD16 0x101A +#define MXC_SDHC_LIB_CMD17 0x113A +#define MXC_SDHC_LIB_CMD18 0x123A +#define MXC_SDHC_LIB_CMD23 0x171A +#define MXC_SDHC_LIB_CMD24 0x183E +#define MXC_SDHC_LIB_CMD25 0x193E +#define MXC_SDHC_LIB_CMD55 0x371A + +/* Application commands (SD Card) which are prefixed by CMD55 */ +#define MXC_SDHC_LIB_ACMD6 0x061B +#define MXC_SDHC_LIB_ACMD41 0x2902 +#define MXC_SDHC_LIB_ACMD51 0x331B + +/* todo: GCR dependent division might be 4 as well. if set to = 1 sdhcfrq. add support in msdk */ +#define SDHC_CLOCK (ADI_MAX32_CLK_IPO_FREQ / 2) + +#define SDHC_SDHC_MAX_DIV_VAL 0x3FF +#define SDHC_SDHC_PCLK_DIV 2 + +/* todo: cmd.arg = SD_IF_COND_VHS_3V3 | check_pattern; + * todo: zephyr always configures response types. msdk needs to support this as well. + * todo: add host io support + */ + +struct sdhc_max32_data { + struct sdhc_host_props props; +}; + +/* SDHC configuration. */ +struct sdhc_max32_config { + void (*irq_func)(void); + const struct pinctrl_dev_config *pcfg; + unsigned int power_delay_ms; + unsigned int bus_volt; + const struct device *clock; + struct max32_perclk perclk; +}; + +static void sdhc_max32_init_props(const struct device *dev) +{ + struct sdhc_max32_data *sdhc_data = dev->data; + const struct sdhc_max32_config *sdhc_config = dev->config; + + memset(sdhc_data, 0, sizeof(struct sdhc_max32_data)); + + sdhc_data->props.f_min = SDHC_CLOCK / (SDHC_SDHC_PCLK_DIV * SDHC_SDHC_MAX_DIV_VAL); + sdhc_data->props.f_max = SDHC_CLOCK; + sdhc_data->props.is_spi = 0; + sdhc_data->props.max_current_180 = 0; + sdhc_data->props.max_current_300 = 0; + sdhc_data->props.max_current_330 = 0; + sdhc_data->props.host_caps.timeout_clk_freq = 0x01; + sdhc_data->props.host_caps.timeout_clk_unit = 1; + sdhc_data->props.host_caps.sd_base_clk = 0x00; + sdhc_data->props.host_caps.max_blk_len = 0b10; + sdhc_data->props.host_caps.bus_8_bit_support = false; + sdhc_data->props.host_caps.bus_4_bit_support = false; + sdhc_data->props.host_caps.adma_2_support = true; + sdhc_data->props.host_caps.high_spd_support = true; + sdhc_data->props.host_caps.sdma_support = true; + sdhc_data->props.host_caps.suspend_res_support = true; + sdhc_data->props.host_caps.vol_330_support = true; + sdhc_data->props.host_caps.vol_300_support = false; + sdhc_data->props.host_caps.vol_180_support = false; + sdhc_data->props.host_caps.address_64_bit_support_v4 = false; + sdhc_data->props.host_caps.address_64_bit_support_v3 = false; + sdhc_data->props.host_caps.sdio_async_interrupt_support = true; + sdhc_data->props.host_caps.slot_type = 00; + sdhc_data->props.host_caps.sdr50_support = true; + sdhc_data->props.host_caps.sdr104_support = true; + sdhc_data->props.host_caps.ddr50_support = true; + sdhc_data->props.host_caps.uhs_2_support = false; + sdhc_data->props.host_caps.drv_type_a_support = true; + sdhc_data->props.host_caps.drv_type_c_support = true; + sdhc_data->props.host_caps.drv_type_d_support = true; + sdhc_data->props.host_caps.retune_timer_count = 0; + sdhc_data->props.host_caps.sdr50_needs_tuning = 0; + sdhc_data->props.host_caps.retuning_mode = 0; + sdhc_data->props.host_caps.clk_multiplier = 0; + sdhc_data->props.host_caps.adma3_support = false; + sdhc_data->props.host_caps.vdd2_180_support = false; + sdhc_data->props.host_caps.hs200_support = false; + sdhc_data->props.host_caps.hs400_support = false; + sdhc_data->props.power_delay = sdhc_config->power_delay_ms; +} + +static int sdhc_max32_init(const struct device *dev) +{ + const struct sdhc_max32_config *sdhc_config = dev->config; + int ret = 0; + mxc_sdhc_cfg_t cfg; + + ret = pinctrl_apply_state(sdhc_config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("Pinctrl apply error:%d", ret); + return ret; + } + + ret = clock_control_on(sdhc_config->clock, (clock_control_subsys_t)&sdhc_config->perclk); + if (ret) { + LOG_ERR("Clock control on error:%d", ret); + return ret; + } + + cfg.bus_voltage = MXC_SDHC_Bus_Voltage_3_3; + cfg.block_gap = 0; + /* Maximum divide ratio, frequency must be 100 - 400 kHz during Card Identification"*/ + cfg.clk_div = SDHC_SDHC_MAX_DIV_VAL; + + ret = MXC_SDHC_Init(&cfg); + if (ret != E_NO_ERROR) { + LOG_ERR("MXC_SDHC_Init error:%d", ret); + return ret; + } + +/* note: init delay, without it applications fail. 5ms found empirically. + * todo: investigate why fails, see if it can be removed via polling a register bit etc. + */ + k_sleep(K_MSEC(5)); + + sdhc_max32_init_props(dev); + + return 0; +} + +static int sdhc_max32_card_busy(const struct device *dev) +{ + int ret = 0; + + ret = MXC_SDHC_Card_Busy(); + + return ret; +} + +static int sdhc_max32_reset(const struct device *dev) +{ + MXC_SDHC_Reset(); + + return 0; +} + +static int sdhc_max32_request(const struct device *dev, struct sdhc_command *cmd, + struct sdhc_data *data) +{ + int ret = 0; + unsigned int mxc_cmd = 0; + mxc_sdhc_cmd_cfg_t sd_cmd_cfg; + bool card_size_workaround = false; + + if (data) { + sd_cmd_cfg.sdma = (unsigned int)data->data; + sd_cmd_cfg.block_size = data->block_size; + sd_cmd_cfg.block_count = data->blocks; + } + + sd_cmd_cfg.arg_1 = cmd->arg; + sd_cmd_cfg.dma = true; /* todo: add config depending on config_dma etc. */ + + switch (cmd->opcode) { + case SD_READ_SINGLE_BLOCK: + case SD_READ_MULTIPLE_BLOCK: + sd_cmd_cfg.direction = MXC_SDHC_DIRECTION_READ; + sd_cmd_cfg.arg_1 = data->block_addr; + break; + case SD_WRITE_SINGLE_BLOCK: + case SD_WRITE_MULTIPLE_BLOCK: + sd_cmd_cfg.direction = MXC_SDHC_DIRECTION_WRITE; + sd_cmd_cfg.arg_1 = data->block_addr; + break; + case SD_SEND_CSD: + card_size_workaround = true; + default: + sd_cmd_cfg.direction = MXC_SDHC_DIRECTION_CFG; + break; + } + + ret = cmd_opcode_converter(cmd->opcode, &mxc_cmd); + if (ret) { + return ret; + } + sd_cmd_cfg.command = mxc_cmd; + sd_cmd_cfg.host_control_1 = MXC_SDHC_Get_Host_Cn_1(); + sd_cmd_cfg.callback = NULL; + + /* + * todo: this was also needed, otherwise applications failed randomly. it would be good to + * remove this with a better solution in future. + */ + k_sleep(K_MSEC(1)); + ret = MXC_SDHC_SendCommand(&sd_cmd_cfg); + if (ret) { + LOG_ERR("MXC_SDHC_SendCommand error:%d, SD opcode: %d", ret, cmd->opcode); + return ret; + } + + MXC_SDHC_Get_Response128((char *)(cmd->response)); + + if (card_size_workaround) { + /* + * this workaround is required for only CMD9. This fixes size problem. Otherwise + * it doesn't give the correct device size information. + */ + cmd->response[1] <<= 8; + cmd->response[3] <<= 8; + } + + return 0; +} + +static int sdhc_max32_get_card_present(const struct device *dev) +{ + return MXC_SDHC_Card_Inserted(); +} + +static int sdhc_max32_get_host_props(const struct device *dev, struct sdhc_host_props *props) +{ + struct sdhc_max32_data *sdhc_data = dev->data; + + memcpy(props, &sdhc_data->props, sizeof(struct sdhc_host_props)); + + return 0; +} + +static int sdhc_max32_set_io(const struct device *dev, struct sdhc_io *ios) +{ + struct sdhc_max32_data *data = dev->data; + struct sdhc_host_props *props = &data->props; + enum sdhc_clock_speed speed = ios->clock; + unsigned int clk_div = 0; + + if (speed) { + if (speed < props->f_min || speed > props->f_max) { + LOG_ERR("Speed range error %d", speed); + return -ENOTSUP; + } + clk_div = convert_freq_to_divider(speed); + MXC_SDHC_Set_Clock_Config(clk_div); + } + + if (ios->power_mode == SDHC_POWER_OFF) { + MXC_SDHC_PowerDown(); + } else { + MXC_SDHC_PowerUp(); + } + + return 0; +} + +static DEVICE_API(sdhc, sdhc_max32_driver_api) = { + .reset = sdhc_max32_reset, + .request = sdhc_max32_request, + .set_io = sdhc_max32_set_io, + .get_card_present = sdhc_max32_get_card_present, + .card_busy = sdhc_max32_card_busy, + .get_host_props = sdhc_max32_get_host_props, + .enable_interrupt = NULL, + .disable_interrupt = NULL, + .execute_tuning = NULL, +}; + +static int cmd_opcode_converter(int opcode, unsigned int *cmd) +{ + switch (opcode) { + case SD_GO_IDLE_STATE: + *cmd = MXC_SDHC_LIB_CMD0; + break; + case MMC_SEND_OP_COND: + *cmd = MXC_SDHC_LIB_CMD1; + break; + case SD_ALL_SEND_CID: + *cmd = MXC_SDHC_LIB_CMD2; + break; + case SD_SEND_RELATIVE_ADDR: + *cmd = MXC_SDHC_LIB_CMD3; + break; + case SDIO_SEND_OP_COND: + *cmd = MXC_SDHC_LIB_CMD5; + break; + case SD_SWITCH: + *cmd = MXC_SDHC_LIB_CMD6; + break; + case SD_SELECT_CARD: + *cmd = MXC_SDHC_LIB_CMD7; + break; + case SD_SEND_IF_COND: + *cmd = MXC_SDHC_LIB_CMD8; + break; + case SD_SEND_CSD: + *cmd = MXC_SDHC_LIB_CMD9; + break; + case SD_SEND_CID: + *cmd = MXC_SDHC_LIB_CMD10; + break; + case SD_VOL_SWITCH: + *cmd = MXC_SDHC_LIB_CMD11; + break; + case SD_STOP_TRANSMISSION: + *cmd = MXC_SDHC_LIB_CMD12; + break; + case SD_SEND_STATUS: + *cmd = MXC_SDHC_LIB_CMD13; + break; + case SD_SET_BLOCK_SIZE: + *cmd = MXC_SDHC_LIB_CMD16; + break; + case SD_READ_SINGLE_BLOCK: + *cmd = MXC_SDHC_LIB_CMD17; + break; + case SD_READ_MULTIPLE_BLOCK: + *cmd = MXC_SDHC_LIB_CMD18; + break; + case SD_SET_BLOCK_COUNT: + *cmd = MXC_SDHC_LIB_CMD23; + break; + case SD_WRITE_SINGLE_BLOCK: + *cmd = MXC_SDHC_LIB_CMD24; + break; + case SD_WRITE_MULTIPLE_BLOCK: + *cmd = MXC_SDHC_LIB_CMD25; + break; + case SD_APP_CMD: + *cmd = MXC_SDHC_LIB_CMD55; + break; + case SD_APP_SEND_OP_COND: + *cmd = MXC_SDHC_LIB_ACMD41; + break; + case SD_APP_SEND_SCR: + *cmd = MXC_SDHC_LIB_ACMD51; + break; + /* todo: below are not defined in msdk, support might be added later */ + case SD_ERASE_BLOCK_START: + case SD_ERASE_BLOCK_END: + case SD_ERASE_BLOCK_OPERATION: + case SDIO_RW_DIRECT: + case SD_SEND_TUNING_BLOCK: + case SD_GO_INACTIVE_STATE: + case SDIO_RW_EXTENDED: + default: + LOG_ERR("Opcode convert error %d", opcode); + return -EINVAL; + } + + return 0; +} + +static int convert_freq_to_divider(int freq) +{ + if (!freq) { + return 0; + } + + int divider = 0; + /* note: this causes a bit different speed than exact number. */ + divider = SDHC_CLOCK / (2 * freq); + + return divider; +} + +#define DEFINE_SDHC_MAX32(_num) \ + PINCTRL_DT_INST_DEFINE(_num); \ + static struct sdhc_max32_data sdhc_max32_data_##_num; \ + static const struct sdhc_max32_config sdhc_max32_config_##_num = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(_num), \ + .power_delay_ms = DT_INST_PROP(_num, power_delay_ms), \ + .clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(_num)), \ + .perclk.bus = DT_INST_CLOCKS_CELL(_num, offset), \ + .perclk.bit = DT_INST_CLOCKS_CELL(_num, bit), \ + }; \ + DEVICE_DT_INST_DEFINE(_num, sdhc_max32_init, NULL, &sdhc_max32_data_##_num, \ + &sdhc_max32_config_##_num, POST_KERNEL, 2, &sdhc_max32_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_SDHC_MAX32) diff --git a/drivers/sdhc/sdhc_renesas_ra.c b/drivers/sdhc/sdhc_renesas_ra.c new file mode 100644 index 0000000000000..9993d5be3bf3b --- /dev/null +++ b/drivers/sdhc/sdhc_renesas_ra.c @@ -0,0 +1,744 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_sdhc + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Renesas include */ +#include "sdhc_renesas_ra.h" +#include "r_sdhi.h" +#include "r_dtc.h" +#include "r_sdhi_private.h" + +LOG_MODULE_REGISTER(sdhc_renesas_ra, CONFIG_SDHC_LOG_LEVEL); + +/* + * The extern functions below are implemented in the r_sdhi.c source file. + * For more information, please refer to r_sdhi.c in HAL Renesas + */ +extern fsp_err_t r_sdhi_transfer_write(sdhi_instance_ctrl_t *const p_ctrl, uint32_t block_count, + uint32_t bytes, const uint8_t *p_data); +extern fsp_err_t r_sdhi_transfer_read(sdhi_instance_ctrl_t *const p_ctrl, uint32_t block_count, + uint32_t bytes, void *p_data); +extern fsp_err_t r_sdhi_max_clock_rate_set(sdhi_instance_ctrl_t *p_ctrl, uint32_t max_rate); +extern fsp_err_t r_sdhi_hw_cfg(sdhi_instance_ctrl_t *const p_ctrl); +extern fsp_err_t r_sdhi_read_and_block(sdhi_instance_ctrl_t *const p_ctrl, uint32_t command, + uint32_t argument, uint32_t byte_count); +extern fsp_err_t r_sdhi_wait_for_device(sdhi_instance_ctrl_t *const p_ctrl); +extern fsp_err_t r_sdhi_wait_for_event(sdhi_instance_ctrl_t *const p_ctrl, uint32_t bit, + uint32_t timeout); +extern void r_sdhi_command_send_no_wait(sdhi_instance_ctrl_t *p_ctrl, uint32_t command, + uint32_t argument); +extern void r_sdhi_read_write_common(sdhi_instance_ctrl_t *const p_ctrl, uint32_t sector_count, + uint32_t sector_size, uint32_t command, uint32_t argument); + +struct sdhc_ra_config { + const struct pinctrl_dev_config *pcfg; + void *const regs; +}; + +struct sdhc_ra_priv { + struct st_sdmmc_instance_ctrl sdmmc_ctrl; + struct st_sdmmc_cfg fsp_config; + struct gpio_dt_spec sdhi_en; + struct sdmmc_ra_event sdmmc_event; + uint8_t channel; + bool app_cmd; + uint32_t bus_clock; + uint8_t bus_width; + enum sdhc_timing_mode timing; + enum sdhc_power power_mode; + struct k_sem thread_lock; + uint8_t status; + struct sdhc_host_props props; + /* Transfer DTC */ + struct st_transfer_instance transfer; + struct st_dtc_instance_ctrl transfer_ctrl; + struct st_transfer_info transfer_info; + struct st_transfer_cfg transfer_cfg; + struct st_dtc_extended_cfg transfer_cfg_extend; +}; + +void sdhimmc_accs_isr(void); +void sdhimmc_card_isr(void); +void sdhimmc_dma_req_isr(void); + +static void ra_sdmmc_accs_isr(const void *parameter) +{ + ARG_UNUSED(parameter); + sdhimmc_accs_isr(); +} + +static void ra_sdmmc_card_isr(const void *parameter) +{ + ARG_UNUSED(parameter); + sdhimmc_card_isr(); +} + +static void ra_sdmmc_dma_req_isr(const void *parameter) +{ + ARG_UNUSED(parameter); + sdhimmc_dma_req_isr(); +} + +static int sdhc_ra_get_card_present(const struct device *dev) +{ + struct sdhc_ra_priv *priv = dev->data; + fsp_err_t fsp_err; + int ret; + sdmmc_status_t status; + + /* SDMMC_CARD_DETECT_CD must be configured as true to check here */ + fsp_err = R_SDHI_StatusGet(&priv->sdmmc_ctrl, &status); + ret = err_fsp2zep(fsp_err); + if (ret < 0) { + return ret; + } + + return (status.card_inserted); +} + +static int sdhc_ra_card_busy(const struct device *dev) +{ + struct sdhc_ra_priv *priv = dev->data; + fsp_err_t fsp_err; + int ret; + sdmmc_status_t status; + + fsp_err = R_SDHI_StatusGet(&priv->sdmmc_ctrl, &status); + ret = err_fsp2zep(fsp_err); + if (ret < 0) { + return ret; + } + + return (status.transfer_in_progress); +} + +static int sdhi_command_send_wait(sdhi_instance_ctrl_t *p_ctrl, uint32_t command, uint32_t argument, + uint32_t timeout) +{ + /* Verify the device is not busy. */ + r_sdhi_wait_for_device(p_ctrl); + + /* Send the command. */ + r_sdhi_command_send_no_wait(p_ctrl, command, argument); + + /* Wait for end of response, error or timeout */ + return r_sdhi_wait_for_event(p_ctrl, SDHI_PRV_RESPONSE_BIT, timeout); +} + +static int sdhc_ra_send_cmd(struct sdhc_ra_priv *priv, struct sdmmc_ra_command *ra_cmd, int retries) +{ + int fsp_err = 0; + + while (retries > 0) { + fsp_err = sdhi_command_send_wait(&priv->sdmmc_ctrl, ra_cmd->opcode, ra_cmd->arg, + ra_cmd->timeout_ms); + if (fsp_err != 0) { + retries--; /* error, retry */ + } else { + break; + } + } + return err_fsp2zep(fsp_err); +} + +/* + * Send CMD or CMD/DATA via SDHC + */ +static int sdhc_ra_request(const struct device *dev, struct sdhc_command *cmd, + struct sdhc_data *data) +{ + struct sdhc_ra_priv *priv = dev->data; + int retries = (int)(cmd->retries + 1); /* first try plus retries */ + uint32_t timeout_cfg = 0; + fsp_err_t fsp_err = 0; + int ret = 0; + sdmmc_priv_csd_reg_t p_csd_reg; + + struct sdmmc_ra_command ra_cmd = { + .opcode = cmd->opcode, + .arg = cmd->arg, + }; + + if (data) { + ra_cmd.data = (uint8_t *)data->data; + ra_cmd.sector_count = data->blocks; + ra_cmd.sector_size = data->block_size; + timeout_cfg = data->timeout_ms; + } else { + timeout_cfg = cmd->timeout_ms; + } + + if (cmd->timeout_ms == SDHC_TIMEOUT_FOREVER) { + ra_cmd.timeout_ms = SDHI_TIME_OUT_MAX; + } else { + ra_cmd.timeout_ms = timeout_cfg; + } + + /* Reset semaphore */ + k_sem_reset(&priv->sdmmc_event.transfer_sem); + k_sem_take(&priv->thread_lock, K_FOREVER); + if (ret < 0) { + LOG_ERR("Can not take sem!"); + goto end; + } + + /* + * Handle opcode with RA specifics + */ + switch (cmd->opcode) { + case SD_GO_IDLE_STATE: + case SD_ALL_SEND_CID: + case SD_SEND_RELATIVE_ADDR: + case SD_SELECT_CARD: + case SD_SEND_IF_COND: + case SD_SET_BLOCK_SIZE: + case SD_ERASE_BLOCK_START: + case SD_ERASE_BLOCK_END: + case SD_ERASE_BLOCK_OPERATION: + case SD_APP_CMD: + case SD_SEND_STATUS: + /* Send command with argument */ + ret = sdhc_ra_send_cmd(priv, &ra_cmd, retries); + if (ret < 0) { + goto end; + } + break; + case SD_SEND_CSD: + /* Read card specific data register */ + ret = sdhc_ra_send_cmd(priv, &ra_cmd, retries); + if (ret < 0) { + goto end; + } + /* SDResponseR2 are bits from 8-127, first 8 MSBs are reserved */ + p_csd_reg.reg.sdrsp10 = priv->sdmmc_ctrl.p_reg->SD_RSP10; + p_csd_reg.reg.sdrsp32 = priv->sdmmc_ctrl.p_reg->SD_RSP32; + p_csd_reg.reg.sdrsp54 = priv->sdmmc_ctrl.p_reg->SD_RSP54; + p_csd_reg.reg.sdrsp76 = priv->sdmmc_ctrl.p_reg->SD_RSP76; + + /* Get the CSD version. */ + uint32_t csd_version = p_csd_reg.csd_v1_b.csd_structure; + uint32_t mult; + + if ((SDHI_PRV_CSD_VERSION_1_0 == csd_version) || + (SDMMC_CARD_TYPE_MMC == priv->sdmmc_ctrl.device.card_type)) { + mult = (1U << (p_csd_reg.csd_v1_b.c_size_mult + 2)); + priv->sdmmc_ctrl.device.sector_count = + ((p_csd_reg.csd_v1_b.c_size + 1U) * mult); + + /* Scale the sector count by the actual block size. */ + uint32_t read_sector_size = 1U << p_csd_reg.csd_v1_b.read_bl_len; + + priv->sdmmc_ctrl.device.sector_count = + priv->sdmmc_ctrl.device.sector_count * + (read_sector_size / SDHI_MAX_BLOCK_SIZE); + + if (SDMMC_CARD_TYPE_MMC == priv->sdmmc_ctrl.device.card_type) { + /* + * If c_size is 0xFFF, then sector_count should be obtained from the + * extended CSD. Set it to 0 to indicate it should come from the + * extended CSD later. + */ + if (SDHI_PRV_SECTOR_COUNT_IN_EXT_CSD == p_csd_reg.csd_v1_b.c_size) { + priv->sdmmc_ctrl.device.sector_count = 0U; + } + } + } + +#if SDHI_CFG_SD_SUPPORT_ENABLE + else if (SDHI_PRV_CSD_VERSION_2_0 == csd_version) { + priv->sdmmc_ctrl.device.sector_count = + (p_csd_reg.csd_v2_b.c_size + 1U) * SDHI_PRV_BYTES_PER_KILOBYTE; + } else { + /* Do Nothing */ + } + + if (SDHI_PRV_CSD_VERSION_1_0 == csd_version) { + /* Get the minimum erasable unit (in 512 byte sectors). */ + priv->sdmmc_ctrl.device.erase_sector_count = + p_csd_reg.csd_v1_b.sector_size + 1U; + } else +#endif + { + /* + * For SDHC and SDXC cards, there are no erase group restrictions. + * Using the eMMC TRIM operation, there are no erase group restrictions. + */ + priv->sdmmc_ctrl.device.erase_sector_count = 1U; + } + break; + case SD_APP_SEND_OP_COND: + ra_cmd.opcode |= SDHI_PRV_CMD_C_ACMD; + ret = sdhc_ra_send_cmd(priv, &ra_cmd, retries); + if (ret < 0) { + goto end; + } + sdmmc_response_t response; + /* get response of ACMD41 (R3) */ + response.status = priv->sdmmc_ctrl.p_reg->SD_RSP10; + /* Initialization complete? */ + if (response.r3.power_up_status) { + /* High capacity card ? */ + /* 0 = SDSC, 1 = SDHC or SDXC */ + priv->sdmmc_ctrl.sector_addressing = + (response.r3.card_capacity_status > 0U); + priv->sdmmc_ctrl.device.card_type = SDMMC_CARD_TYPE_SD; + } + priv->sdmmc_ctrl.initialized = true; + break; + case SD_SWITCH: + /* Check app cmd */ + if (priv->app_cmd && cmd->opcode == SD_APP_SET_BUS_WIDTH) { + /* ACMD41*/ + ra_cmd.opcode |= SDHI_PRV_CMD_C_ACMD; + ret = sdhc_ra_send_cmd(priv, &ra_cmd, retries); + if (ret < 0) { + goto end; + } + } else { + /* SD SWITCH CMD6*/ + fsp_err = r_sdhi_read_and_block(&priv->sdmmc_ctrl, ra_cmd.opcode, + ra_cmd.arg, ra_cmd.sector_size); + ret = err_fsp2zep(fsp_err); + if (ret < 0) { + goto end; + } + memcpy(ra_cmd.data, priv->sdmmc_ctrl.aligned_buff, 8); + priv->sdmmc_event.transfer_completed = false; + break; + } + break; + + /* Read write with data */ + case SD_APP_SEND_SCR: + ra_cmd.opcode = cmd->opcode | SDHI_PRV_CMD_C_ACMD; + fsp_err = r_sdhi_read_and_block(&priv->sdmmc_ctrl, ra_cmd.opcode, ra_cmd.arg, + ra_cmd.sector_size); + + if (fsp_err != 0) { + ret = -ETIMEDOUT; + goto end; + } + memcpy(ra_cmd.data, priv->sdmmc_ctrl.aligned_buff, 8); + priv->sdmmc_event.transfer_completed = false; + break; + case SD_READ_SINGLE_BLOCK: + case SD_READ_MULTIPLE_BLOCK: + /* Configure the transfer interface for reading.*/ + fsp_err = r_sdhi_transfer_read(&priv->sdmmc_ctrl, ra_cmd.sector_count, + ra_cmd.sector_size, ra_cmd.data); + ret = err_fsp2zep(fsp_err); + if (ret < 0) { + goto end; + } + + r_sdhi_read_write_common(&priv->sdmmc_ctrl, ra_cmd.sector_count, ra_cmd.sector_size, + ra_cmd.opcode, ra_cmd.arg); + + /* Verify card is back in transfer state after write */ + ret = k_sem_take(&priv->sdmmc_event.transfer_sem, K_MSEC(ra_cmd.timeout_ms)); + if (ret < 0) { + LOG_ERR("Can not take sem!"); + goto end; + } + + if (!priv->sdmmc_event.transfer_completed) { + ret = -EIO; + goto end; + } + + priv->sdmmc_event.transfer_completed = false; + break; + + case SD_WRITE_SINGLE_BLOCK: + case SD_WRITE_MULTIPLE_BLOCK: + + fsp_err = r_sdhi_transfer_write(&priv->sdmmc_ctrl, ra_cmd.sector_count, + ra_cmd.sector_size, ra_cmd.data); + ret = err_fsp2zep(fsp_err); + if (ret < 0) { + goto end; + } + /* Send command with data for reading */ + r_sdhi_read_write_common(&priv->sdmmc_ctrl, ra_cmd.sector_count, ra_cmd.sector_size, + ra_cmd.opcode, ra_cmd.arg); + + /* Verify card is back in transfer state after write */ + ret = k_sem_take(&priv->sdmmc_event.transfer_sem, K_MSEC(ra_cmd.timeout_ms)); + if (ret < 0) { + LOG_ERR("Can not take sem!"); + goto end; + } + + if (!priv->sdmmc_event.transfer_completed) { + ret = -EIO; + goto end; + } + + priv->sdmmc_event.transfer_completed = false; + break; + + default: + LOG_INF("SDHC driver: command %u not supported", cmd->opcode); + ret = -ENOTSUP; + } + + if (ra_cmd.opcode == SD_ALL_SEND_CID || ra_cmd.opcode == SD_SEND_CSD) { + /* SDResponseR2 are bits from 8-127, first 8 MSBs are reserved */ + p_csd_reg.reg.sdrsp10 = (uint32_t)priv->sdmmc_ctrl.p_reg->SD_RSP10 << 8; + p_csd_reg.reg.sdrsp32 = (uint32_t)priv->sdmmc_ctrl.p_reg->SD_RSP32 << 8; + p_csd_reg.reg.sdrsp54 = (uint32_t)priv->sdmmc_ctrl.p_reg->SD_RSP54 << 8; + p_csd_reg.reg.sdrsp76 = (uint32_t)priv->sdmmc_ctrl.p_reg->SD_RSP76 << 8; + + memcpy(cmd->response, &p_csd_reg.reg, sizeof(cmd->response)); + } else { + /* Fill response buffer */ + p_csd_reg.reg.sdrsp10 = (uint32_t)priv->sdmmc_ctrl.p_reg->SD_RSP10; + p_csd_reg.reg.sdrsp32 = (uint32_t)priv->sdmmc_ctrl.p_reg->SD_RSP32; + p_csd_reg.reg.sdrsp54 = (uint32_t)priv->sdmmc_ctrl.p_reg->SD_RSP54; + p_csd_reg.reg.sdrsp76 = (uint32_t)priv->sdmmc_ctrl.p_reg->SD_RSP76; + + memcpy(cmd->response, &p_csd_reg.reg, sizeof(cmd->response)); + } +end: + if (cmd->opcode == SD_APP_CMD) { + priv->app_cmd = true; + } else { + priv->app_cmd = false; + } + + k_sem_give(&priv->thread_lock); + + return ret; +} + +static int sdhc_ra_reset(const struct device *dev) +{ + struct sdhc_ra_priv *priv = dev->data; + const struct sdhc_ra_config *cfg = dev->config; + + k_sem_take(&priv->thread_lock, K_USEC(50)); + + /* Reset SDHI. */ + ((R_SDHI0_Type *)cfg->regs)->SOFT_RST = 0x0U; + ((R_SDHI0_Type *)cfg->regs)->SOFT_RST = 0x1U; + + k_sem_give(&priv->thread_lock); + + return 0; +} + +/* + * Set SDHC io properties + */ +static int sdhc_ra_set_io(const struct device *dev, struct sdhc_io *ios) +{ + struct sdhc_ra_priv *priv = dev->data; + const struct sdhc_ra_config *cfg = dev->config; + struct st_sdmmc_instance_ctrl *p_ctrl = &priv->sdmmc_ctrl; + int fsp_err; + int ret = 0; + + uint8_t bus_width; + uint32_t bus_width_reg; + + if (ios->bus_width > 0) { + bus_width_reg = 0; + /* Set bus width, SD bus interface doesn't support 8BIT */ + switch (ios->bus_width) { + case SDHC_BUS_WIDTH1BIT: + bus_width = 1; + bus_width_reg = 4; + break; + case SDHC_BUS_WIDTH4BIT: + bus_width = 4; + break; + default: + ret = -ENOTSUP; + goto end; + } + + if (priv->bus_width != bus_width) { + /* Set the bus width in the SDHI peripheral. */ + ((R_SDHI0_Type *)cfg->regs)->SD_OPTION = + SDHI_PRV_SD_OPTION_DEFAULT | + (bus_width_reg << SDHI_PRV_SD_OPTION_WIDTH8_BIT); + priv->bus_width = bus_width; + } + } + + if (ios->clock) { + if (ios->clock > priv->props.f_max || ios->clock < priv->props.f_min) { + LOG_ERR("Proposed clock outside supported host range"); + return -EINVAL; + } + + if (priv->bus_clock != (uint32_t)ios->clock) { + fsp_err = r_sdhi_max_clock_rate_set(p_ctrl, ios->clock); + ret = err_fsp2zep(fsp_err); + if (ret < 0) { + goto end; + } + priv->bus_clock = ios->clock; + } + } + + if (ios->timing > 0) { + /* Set I/O timing */ + if (priv->timing != ios->timing) { + switch (ios->timing) { + case SDHC_TIMING_LEGACY: + case SDHC_TIMING_HS: + case SDHC_TIMING_SDR12: + case SDHC_TIMING_SDR25: + break; + default: + LOG_ERR("Timing mode not supported for this device"); + ret = -ENOTSUP; + break; + } + + priv->timing = ios->timing; + } + } +end: + + return ret; +} + +/* + * Get host properties + */ +static int sdhc_ra_get_host_props(const struct device *dev, struct sdhc_host_props *props) +{ + struct sdhc_ra_priv *priv = dev->data; + + memcpy(props, &priv->props, sizeof(struct sdhc_host_props)); + return 0; +} + +static int sdhc_ra_init(const struct device *dev) +{ + const struct sdhc_ra_config *config = dev->config; + struct sdhc_ra_priv *priv = dev->data; + fsp_err_t fsp_err; + int timeout = SDHI_PRV_ACCESS_TIMEOUT_US; + int ret = 0; + + priv->sdmmc_event.transfer_completed = false; + k_sem_init(&priv->sdmmc_event.transfer_sem, 1, 1); + + /* Configure dt provided device signals when available */ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + if (priv->sdhi_en.port != NULL) { + int err = gpio_pin_configure_dt(&priv->sdhi_en, GPIO_OUTPUT_HIGH); + + if (err) { + return err; + } + k_sleep(K_MSEC(50)); + } + + k_sem_init(&priv->thread_lock, 1, 1); + fsp_err = R_SDHI_Open(&priv->sdmmc_ctrl, &priv->fsp_config); + ret = err_fsp2zep(fsp_err); + + if (ret < 0) { + LOG_INF("R_SDHI_Open error: %d", fsp_err); + return ret; /* I/O error*/ + } + + k_busy_wait(100); + + k_sem_take(&priv->thread_lock, K_USEC(timeout)); + + fsp_err = r_sdhi_hw_cfg(&priv->sdmmc_ctrl); + ret = err_fsp2zep(fsp_err); + if (ret < 0) { + LOG_ERR("failed to init sdmmc media"); + goto end; + } + priv->bus_width = SDMMC_BUS_WIDTH_1_BIT; + priv->timing = SDHC_TIMING_LEGACY; + priv->bus_clock = SDMMC_CLOCK_400KHZ; + +end: + k_sem_give(&priv->thread_lock); + return ret; +} + +static DEVICE_API(sdhc, sdhc_api) = { + .reset = sdhc_ra_reset, + .request = sdhc_ra_request, + .set_io = sdhc_ra_set_io, + .get_card_present = sdhc_ra_get_card_present, + .card_busy = sdhc_ra_card_busy, + .get_host_props = sdhc_ra_get_host_props, +}; + +#define _ELC_EVENT_SDMMC_ACCS(channel) ELC_EVENT_SDHIMMC##channel##_ACCS +#define _ELC_EVENT_SDMMC_CARD(channel) ELC_EVENT_SDHIMMC##channel##_CARD +#define _ELC_EVENT_SDMMC_DMA_REQ(channel) ELC_EVENT_SDHIMMC##channel##_DMA_REQ + +#define ELC_EVENT_SDMMC_ACCS(channel) _ELC_EVENT_SDMMC_ACCS(channel) +#define ELC_EVENT_SDMMC_CARD(channel) _ELC_EVENT_SDMMC_CARD(channel) +#define ELC_EVENT_SDMMC_DMA_REQ(channel) _ELC_EVENT_SDMMC_DMA_REQ(channel) + +#define RA_SDMMC_IRQ_CONFIG_INIT(index) \ + do { \ + ARG_UNUSED(dev); \ + \ + R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, accs, irq)] = \ + ELC_EVENT_SDMMC_ACCS(DT_INST_PROP(index, channel)); \ + R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, card, irq)] = \ + ELC_EVENT_SDMMC_CARD(DT_INST_PROP(index, channel)); \ + R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, dma_req, irq)] = \ + ELC_EVENT_SDMMC_DMA_REQ(DT_INST_PROP(index, channel)); \ + \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, accs, irq), \ + DT_INST_IRQ_BY_NAME(index, accs, priority), ra_sdmmc_accs_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, card, irq), \ + DT_INST_IRQ_BY_NAME(index, card, priority), ra_sdmmc_card_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, dma_req, irq), \ + DT_INST_IRQ_BY_NAME(index, dma_req, priority), ra_sdmmc_dma_req_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + \ + irq_enable(DT_INST_IRQ_BY_NAME(index, accs, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, card, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, dma_req, irq)); \ + } while (0) + +#define RA_SDHI_EN(index) .sdhi_en = GPIO_DT_SPEC_INST_GET_OR(index, enable_gpios, {0}) + +#define RA_SDMMC_DTC_INIT(index) \ + sdhc_ra_priv_##index.fsp_config.p_lower_lvl_transfer = &sdhc_ra_priv_##index.transfer; + +#define RA_SDMMC_DTC_STRUCT_INIT(index) \ + .transfer_info = \ + { \ + .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED, \ + .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE, \ + .transfer_settings_word_b.irq = TRANSFER_IRQ_END, \ + .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \ + .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \ + .transfer_settings_word_b.size = TRANSFER_SIZE_4_BYTE, \ + .transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \ + .p_dest = (void *)NULL, \ + .p_src = (void const *)NULL, \ + .num_blocks = 0, \ + .length = 128, \ + }, \ + .transfer_cfg_extend = {.activation_source = DT_INST_IRQ_BY_NAME(index, dma_req, irq)}, \ + .transfer_cfg = \ + { \ + .p_info = &sdhc_ra_priv_##index.transfer_info, \ + .p_extend = &sdhc_ra_priv_##index.transfer_cfg_extend, \ + }, \ + .transfer = { \ + .p_ctrl = &sdhc_ra_priv_##index.transfer_ctrl, \ + .p_cfg = &sdhc_ra_priv_##index.transfer_cfg, \ + .p_api = &g_transfer_on_dtc, \ + }, + +#define RA_SDHC_INIT(index) \ + \ + PINCTRL_DT_INST_DEFINE(index); \ + \ + static const struct sdhc_ra_config sdhc_ra_config_##index = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .regs = (R_SDHI0_Type *)DT_INST_REG_ADDR(index), \ + }; \ + void r_sdhi_callback_##index(sdmmc_callback_args_t *p_args) \ + { \ + const struct device *dev = DEVICE_DT_INST_GET(index); \ + struct sdhc_ra_priv *priv = dev->data; \ + if (p_args->event == SDMMC_EVENT_TRANSFER_COMPLETE) { \ + priv->sdmmc_event.transfer_completed = true; \ + k_sem_give(&priv->sdmmc_event.transfer_sem); \ + } else if (p_args->event == SDMMC_EVENT_TRANSFER_ERROR) { \ + priv->sdmmc_event.transfer_completed = false; \ + k_sem_give(&priv->sdmmc_event.transfer_sem); \ + } \ + } \ + \ + static struct sdhc_ra_priv sdhc_ra_priv_##index = { \ + .power_mode = SDHC_POWER_ON, \ + .timing = SDHC_TIMING_LEGACY, \ + .fsp_config = \ + { \ + .channel = DT_INST_PROP(index, channel), \ + .bus_width = DT_INST_PROP(index, bus_width), \ + .access_ipl = DT_INST_IRQ_BY_NAME(index, accs, priority), \ + .access_irq = DT_INST_IRQ_BY_NAME(index, accs, irq), \ + .card_ipl = DT_INST_IRQ_BY_NAME(index, card, priority), \ + .card_irq = DT_INST_IRQ_BY_NAME(index, card, irq), \ + .dma_req_ipl = DT_INST_IRQ_BY_NAME(index, dma_req, priority), \ + .dma_req_irq = DT_INST_IRQ_BY_NAME(index, dma_req, irq), \ + .p_context = NULL, \ + .p_callback = r_sdhi_callback_##index, \ + .card_detect = DT_INST_PROP(index, card_detect), \ + .write_protect = DT_INST_PROP(index, write_protect), \ + .p_extend = NULL, \ + .p_lower_lvl_transfer = &sdhc_ra_priv_##index.transfer, \ + }, \ + .props = {.is_spi = false, \ + .f_max = DT_INST_PROP(index, max_bus_freq), \ + .f_min = DT_INST_PROP(index, min_bus_freq), \ + .max_current_330 = DT_INST_PROP(index, max_current_330), \ + .max_current_180 = DT_INST_PROP(index, max_current_180), \ + .power_delay = DT_INST_PROP_OR(index, power_delay_ms, 0), \ + .host_caps = {.vol_180_support = false, \ + .vol_300_support = false, \ + .vol_330_support = true, \ + .suspend_res_support = false, \ + .sdma_support = true, \ + .high_spd_support = (DT_INST_PROP(index, bus_width) == 4) \ + ? true \ + : false, \ + .adma_2_support = false, \ + .max_blk_len = 0, \ + .ddr50_support = false, \ + .sdr104_support = false, \ + .sdr50_support = false, \ + .bus_8_bit_support = false, \ + .bus_4_bit_support = (DT_INST_PROP(index, bus_width) == 4) \ + ? true \ + : false, \ + .hs200_support = false, \ + .hs400_support = false}}, \ + RA_SDHI_EN(index), \ + RA_SDMMC_DTC_STRUCT_INIT(index)}; \ + \ + static int sdhc_ra_init##index(const struct device *dev) \ + { \ + RA_SDMMC_DTC_INIT(index); \ + RA_SDMMC_IRQ_CONFIG_INIT(index); \ + int err = sdhc_ra_init(dev); \ + if (err != 0) { \ + return err; \ + } \ + return 0; \ + } \ + \ + DEVICE_DT_INST_DEFINE(index, sdhc_ra_init##index, NULL, &sdhc_ra_priv_##index, \ + &sdhc_ra_config_##index, POST_KERNEL, CONFIG_SDHC_INIT_PRIORITY, \ + &sdhc_api); + +DT_INST_FOREACH_STATUS_OKAY(RA_SDHC_INIT) diff --git a/drivers/sdhc/sdhc_renesas_ra.h b/drivers/sdhc/sdhc_renesas_ra.h new file mode 100644 index 0000000000000..ada297508de57 --- /dev/null +++ b/drivers/sdhc/sdhc_renesas_ra.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define SDHI_PRV_ACCESS_TIMEOUT_US 100000U +#define SDHI_PRV_SD_OPTION_DEFAULT 0x40E0U +#define SDHI_PRV_SD_OPTION_WIDTH8_BIT 13 +#define SDHI_PRV_BYTES_PER_KILOBYTE 1024 +#define SDHI_PRV_SECTOR_COUNT_IN_EXT_CSD 0xFFFU +#define SDHI_TIME_OUT_MAX 0xFFFFFFFF +#define SDHI_PRV_RESPONSE_BIT 0 + +struct sdmmc_ra_event { + volatile bool transfer_completed; + struct k_sem transfer_sem; +}; + +struct sdmmc_ra_command { + uint32_t opcode; + uint32_t arg; + void *data; + unsigned int sector_count; + unsigned int sector_size; + int timeout_ms; +}; + +static ALWAYS_INLINE int err_fsp2zep(int fsp_err) +{ + int ret; + + switch (fsp_err) { + /* Treating the error codes most relevant to be individuated */ + case FSP_SUCCESS: + ret = 0; + break; + case FSP_ERR_TIMEOUT: + ret = -ETIMEDOUT; + break; + case FSP_ERR_NOT_FOUND: + ret = -ENODEV; /* SD card not inserted (requires CD signal) */ + break; + case FSP_ERR_INVALID_STATE: + ret = -EACCES; /* SD card write-protected (requires WP sinal) */ + break; + case FSP_ERR_RESPONSE: + default: + ret = -EIO; + break; + } + + return ret; +} diff --git a/drivers/sdhc/sdhc_spi.c b/drivers/sdhc/sdhc_spi.c index c4771f493e7e2..aaf75ebf10007 100644 --- a/drivers/sdhc/sdhc_spi.c +++ b/drivers/sdhc/sdhc_spi.c @@ -183,8 +183,13 @@ static int sdhc_spi_card_busy(const struct device *dev) int ret; uint8_t response; + /* Request SPI bus to be active */ + if (pm_device_runtime_get(config->spi_dev) < 0) { + return -EIO; + } ret = sdhc_spi_rx(config->spi_dev, data->spi_cfg, &response, 1); + (void)pm_device_runtime_put(config->spi_dev); if (ret) { return -EIO; } @@ -722,20 +727,27 @@ static int sdhc_spi_set_io(const struct device *dev, struct sdhc_io *ios) } if (data->power_mode != ios->power_mode) { if (ios->power_mode == SDHC_POWER_ON) { + if (cfg->pwr_gpio.port) { + if (gpio_pin_set_dt(&cfg->pwr_gpio, 1)) { + return -EIO; + } + + /* Wait until VDD is stable. Per the spec: + * Maximum VDD rise time of 35ms. + * Minimum 1ms VDD stable time. + */ + k_sleep(K_MSEC(36)); + + LOG_INF("Powered up"); + } + /* Send 74 clock cycles to start card */ if (sdhc_spi_init_card(dev) != 0) { LOG_ERR("Card SCLK init sequence failed"); return -EIO; } - } - if (cfg->pwr_gpio.port) { - /* If power control GPIO is defined, toggle SD power */ - if (ios->power_mode == SDHC_POWER_ON) { - if (gpio_pin_set_dt(&cfg->pwr_gpio, 1)) { - return -EIO; - } - LOG_INF("Powered up"); - } else { + } else { + if (cfg->pwr_gpio.port) { if (gpio_pin_set_dt(&cfg->pwr_gpio, 0)) { return -EIO; } diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index ca65a4128003c..46496280f0cd4 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -13,6 +13,7 @@ add_subdirectory(ite) add_subdirectory(jedec) add_subdirectory(maxim) add_subdirectory(meas) +add_subdirectory(melexis) add_subdirectory(memsic) add_subdirectory(microchip) add_subdirectory(nordic) @@ -62,6 +63,7 @@ add_subdirectory_ifdef(CONFIG_TH02 th02) add_subdirectory_ifdef(CONFIG_TSIC_XX6 tsic_xx6) add_subdirectory_ifdef(CONFIG_VEAA_X_3 veaa_x_3) add_subdirectory_ifdef(CONFIG_VOLTAGE_DIVIDER voltage_divider) +add_subdirectory_ifdef(CONFIG_XBR818 xbr818) add_subdirectory_ifdef(CONFIG_TACH_ENE_KB1200 ene_tach_kb1200) zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/sensor.h) @@ -74,3 +76,15 @@ zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL sensor_shell.c) zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL_STREAM sensor_shell_stream.c) zephyr_library_sources_ifdef(CONFIG_SENSOR_SHELL_BATTERY shell_battery.c) zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API sensor_decoders_init.c default_rtio_sensor.c) + +dt_has_chosen(has_zephyr_sensor_clock PROPERTY "zephyr,sensor-clock") + +if(CONFIG_SENSOR_CLOCK_RTC OR CONFIG_SENSOR_CLOCK_COUNTER) + if(has_zephyr_sensor_clock) + zephyr_library_sources(sensor_clock_external.c) + else() + message(FATAL_ERROR "Sensor clock type (RTC or Counter) is selected, but no zephyr,sensor-clock is defined in the device tree.") + endif() +elseif(CONFIG_SENSOR_CLOCK_SYSTEM) + zephyr_library_sources(sensor_clock_sys.c) +endif() diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 452d8182eb798..096379c9c553f 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -82,6 +82,8 @@ config SENSOR_SHELL_MAX_TRIGGER_DEVICES config SENSOR_INFO bool "Sensor Info iterable section" +source "drivers/sensor/Kconfig.sensor_clock" + comment "Device Drivers" # zephyr-keep-sorted-start @@ -97,6 +99,7 @@ source "drivers/sensor/ite/Kconfig" source "drivers/sensor/jedec/Kconfig" source "drivers/sensor/maxim/Kconfig" source "drivers/sensor/meas/Kconfig" +source "drivers/sensor/melexis/Kconfig" source "drivers/sensor/memsic/Kconfig" source "drivers/sensor/microchip/Kconfig" source "drivers/sensor/nordic/Kconfig" @@ -146,6 +149,7 @@ source "drivers/sensor/th02/Kconfig" source "drivers/sensor/tsic_xx6/Kconfig" source "drivers/sensor/veaa_x_3/Kconfig" source "drivers/sensor/voltage_divider/Kconfig" +source "drivers/sensor/xbr818/Kconfig" source "drivers/sensor/ene_tach_kb1200/Kconfig" endif # SENSOR diff --git a/drivers/sensor/Kconfig.sensor_clock b/drivers/sensor/Kconfig.sensor_clock new file mode 100644 index 0000000000000..be985746197c8 --- /dev/null +++ b/drivers/sensor/Kconfig.sensor_clock @@ -0,0 +1,30 @@ +# Sensor clock configuration options +# Copyright(c) 2024 Cienet +# SPDX-License-Identifier: Apache-2.0 + +config SENSOR_CLOCK + bool + default y if SENSOR_ASYNC_API + help + Configure the sensor clock source for the system. + +if SENSOR_CLOCK + +choice + prompt "Sensor clock type" + default SENSOR_CLOCK_SYSTEM + help + Select the clock source to be used for sensor timing. + +config SENSOR_CLOCK_SYSTEM + bool "Use the system counter for sensor time" + +config SENSOR_CLOCK_COUNTER + bool "Use a counter device/API for sensor time" + +config SENSOR_CLOCK_RTC + bool "Use an RTC device/API for sensor time" + +endchoice + +endif # SENSOR_CLOCK diff --git a/drivers/sensor/Kconfig.trigger_template b/drivers/sensor/Kconfig.trigger_template index 7cb98e10e9e67..37f7121f0033d 100644 --- a/drivers/sensor/Kconfig.trigger_template +++ b/drivers/sensor/Kconfig.trigger_template @@ -4,6 +4,7 @@ choice "$(module)_TRIGGER_MODE" prompt "Trigger mode" + default $(module)_TRIGGER_NONE help Specify the type of triggering to be used by the sensor module. diff --git a/drivers/sensor/adi/adltc2990/adltc2990.c b/drivers/sensor/adi/adltc2990/adltc2990.c index f1d5e54084260..912b0acf5f7ea 100644 --- a/drivers/sensor/adi/adltc2990/adltc2990.c +++ b/drivers/sensor/adi/adltc2990/adltc2990.c @@ -1,15 +1,19 @@ /* * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT adi_adltc2990 +#include + #include #include +#include #include "adltc2990_reg.h" -#include "adltc2990.h" +#include "adltc2990_internal.h" #include LOG_MODULE_REGISTER(adltc2990, CONFIG_SENSOR_LOG_LEVEL); @@ -30,26 +34,25 @@ static enum adltc2990_monitoring_type adltc2990_get_v1_v2_measurement_modes(uint switch (mode_2_0) { case ADLTC2990_MODE_V1_V2_TR2: - case ADLTC2990_MODE_V1_V2_V3_V4: { + case ADLTC2990_MODE_V1_V2_V3_V4: type = VOLTAGE_SINGLEENDED; break; - } + case ADLTC2990_MODE_V1_MINUS_V2_TR2: case ADLTC2990_MODE_V1_MINUS_V2_V3_V4: - case ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4: { + case ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4: type = VOLTAGE_DIFFERENTIAL; break; - } + case ADLTC2990_MODE_TR1_V3_V4: - case ADLTC2990_MODE_TR1_V3_MINUS_V4: { + case ADLTC2990_MODE_TR1_V3_MINUS_V4: case ADLTC2990_MODE_TR1_TR2: type = TEMPERATURE; break; - } - default: { + + default: break; } - } return type; } @@ -70,38 +73,34 @@ static enum adltc2990_monitoring_type adltc2990_get_v3_v4_measurement_modes(uint switch (mode_2_0) { case ADLTC2990_MODE_V1_V2_TR2: case ADLTC2990_MODE_V1_MINUS_V2_TR2: - case ADLTC2990_MODE_TR1_TR2: { + case ADLTC2990_MODE_TR1_TR2: type = TEMPERATURE; break; - } case ADLTC2990_MODE_V1_MINUS_V2_V3_V4: case ADLTC2990_MODE_TR1_V3_V4: - case ADLTC2990_MODE_V1_V2_V3_V4: { + case ADLTC2990_MODE_V1_V2_V3_V4: type = VOLTAGE_SINGLEENDED; break; - } + case ADLTC2990_MODE_TR1_V3_MINUS_V4: - case ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4: { + case ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4: type = VOLTAGE_DIFFERENTIAL; break; - } - default: { + + default: break; } - } return type; } -static int adltc2990_is_busy(const struct device *dev, bool *is_busy) +int adltc2990_is_busy(const struct device *dev, bool *is_busy) { const struct adltc2990_config *cfg = dev->config; uint8_t status_reg = 0; - int ret; - ret = i2c_reg_read_byte_dt(&cfg->bus, ADLTC2990_REG_STATUS, &status_reg); - if (ret) { - return ret; + if (i2c_reg_read_byte_dt(&cfg->bus, ADLTC2990_REG_STATUS, &status_reg)) { + return -EIO; } *is_busy = status_reg & BIT(0); @@ -134,17 +133,37 @@ static void adltc2990_get_v3_v4_val(const struct device *dev, struct sensor_valu } } -static int adltc2990_trigger_measurement(const struct device *dev) +int adltc2990_trigger_measurement(const struct device *dev, + enum adltc2990_acquisition_format format) { const struct adltc2990_config *cfg = dev->config; + struct adltc2990_data *data = dev->data; + + if (data->acq_format == format) { + goto trigger_conversion; + } + + data->acq_format = format; + uint8_t ctrl_reg_setting; + + if (i2c_reg_read_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, &ctrl_reg_setting)) { + LOG_ERR("reading control register failed."); + return -EIO; + } + + ctrl_reg_setting |= format << 6; + if (i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, ctrl_reg_setting)) { + LOG_ERR("configuring for single bus failed."); + return -EIO; + } +trigger_conversion: return i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_TRIGGER, 0x1); } static int adltc2990_fetch_property_value(const struct device *dev, enum adltc2990_monitoring_type type, - enum adltc2990_monitor_pins pin, - int32_t *output) + enum adltc2990_monitor_pins pin, int32_t *output) { const struct adltc2990_config *cfg = dev->config; @@ -152,52 +171,49 @@ static int adltc2990_fetch_property_value(const struct device *dev, uint8_t msb_address, lsb_address; switch (pin) { - case V1: { + case V1: msb_address = ADLTC2990_REG_V1_MSB; lsb_address = ADLTC2990_REG_V1_LSB; break; - } - case V2: { + + case V2: msb_address = ADLTC2990_REG_V2_MSB; lsb_address = ADLTC2990_REG_V2_LSB; break; - } - case V3: { + + case V3: msb_address = ADLTC2990_REG_V3_MSB; lsb_address = ADLTC2990_REG_V3_LSB; break; - } - case V4: { + + case V4: msb_address = ADLTC2990_REG_V4_MSB; lsb_address = ADLTC2990_REG_V4_LSB; break; - } - case INTERNAL_TEMPERATURE: { + + case INTERNAL_TEMPERATURE: msb_address = ADLTC2990_REG_INTERNAL_TEMP_MSB; lsb_address = ADLTC2990_REG_INTERNAL_TEMP_LSB; break; - } - case SUPPLY_VOLTAGE: { + + case SUPPLY_VOLTAGE: msb_address = ADLTC2990_REG_VCC_MSB; lsb_address = ADLTC2990_REG_VCC_LSB; break; - } - default: { + + default: LOG_ERR("Trying to access illegal register"); return -EINVAL; } - } - int ret; - ret = i2c_reg_read_byte_dt(&cfg->bus, msb_address, &msb_value); - if (ret) { - return ret; + if (i2c_reg_read_byte_dt(&cfg->bus, msb_address, &msb_value)) { + return -EIO; } - ret = i2c_reg_read_byte_dt(&cfg->bus, lsb_address, &lsb_value); - if (ret) { - return ret; + if (i2c_reg_read_byte_dt(&cfg->bus, lsb_address, &lsb_value)) { + return -EIO; } + uint16_t conversion_factor; uint8_t negative_bit_index = 14U, sensor_val_divisor = 100U; @@ -228,6 +244,7 @@ static int adltc2990_fetch_property_value(const struct device *dev, static int adltc2990_init(const struct device *dev) { const struct adltc2990_config *cfg = dev->config; + struct adltc2990_data *data = dev->data; int err; if (!i2c_is_ready_dt(&cfg->bus)) { @@ -235,17 +252,16 @@ static int adltc2990_init(const struct device *dev) return -ENODEV; } - const uint8_t ctrl_reg_setting = cfg->temp_format << 7 | cfg->acq_format << 6 | 0 << 5 | + const uint8_t ctrl_reg_setting = cfg->temp_format << 7 | data->acq_format << 6 | 0 << 5 | cfg->measurement_mode[1] << 3 | cfg->measurement_mode[0]; LOG_DBG("Setting Control Register to: 0x%x", ctrl_reg_setting); - err = i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, ctrl_reg_setting); - if (err < 0) { - LOG_ERR("configuring for single bus failed: %d", err); - return err; + if (i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, ctrl_reg_setting)) { + LOG_ERR("configuring for single bus failed."); + return -EIO; } - err = adltc2990_trigger_measurement(dev); + err = adltc2990_trigger_measurement(dev, data->acq_format); if (err < 0) { LOG_ERR("triggering measurement failed: %d", err); } @@ -254,6 +270,171 @@ static int adltc2990_init(const struct device *dev) return 0; } +static int fetch_pin_differential_voltage_value(const struct device *dev, + const enum adltc2990_monitoring_type mode, + const enum adltc2990_monitor_pins pin) +{ + if (mode != VOLTAGE_DIFFERENTIAL) { + LOG_DBG("Pin is not configured to measure voltage differential"); + return 0; + } + + struct adltc2990_data *data = dev->data; + int32_t value; + int ret; + + ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, pin, &value); + if (ret) { + return ret; + } + + switch (pin) { + case V1: + case V2: + data->pins_v1_v2_values[0] = value; + break; + + case V3: + case V4: + data->pins_v3_v4_values[0] = value; + default: + break; + } + + return 0; +} + +static int fetch_pin_single_ended_voltage_value(const struct device *dev, + const enum adltc2990_monitoring_type mode, + const enum adltc2990_monitor_pins pin_1, + const enum adltc2990_monitor_pins pin_2) +{ + if (mode != VOLTAGE_SINGLEENDED) { + LOG_DBG("Pin is not configured to measure voltage single ended"); + return 0; + } + + const struct adltc2990_config *cfg = dev->config; + struct adltc2990_data *data = dev->data; + int value_1, value_2, ret; + + ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, pin_1, &value_1); + if (ret) { + return ret; + } + + ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, pin_2, &value_2); + if (ret) { + return ret; + } + + if (pin_1 == V1 && pin_2 == V2) { + + uint32_t v1_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[0]; + uint32_t v1_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[1]; + + float voltage_divider_ratio = (v1_r1 + v1_r2) / (float)v1_r2; + + data->pins_v1_v2_values[0] = value_1 * voltage_divider_ratio; + + uint32_t v2_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[0]; + uint32_t v2_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; + + voltage_divider_ratio = (v2_r1 + v2_r2) / (float)v2_r2; + + data->pins_v1_v2_values[1] = value_2 * voltage_divider_ratio; + + } else if (pin_1 == V3 && pin_2 == V4) { + + uint32_t v3_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[0]; + uint32_t v3_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[1]; + + float voltage_divider_ratio = (v3_r1 + v3_r2) / (float)v3_r2; + + data->pins_v3_v4_values[0] = value_1 * voltage_divider_ratio; + + uint32_t v4_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[0]; + uint32_t v4_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[1]; + + voltage_divider_ratio = (v4_r1 + v4_r2) / (float)v4_r2; + + data->pins_v3_v4_values[1] = value_2 * voltage_divider_ratio; + + } else { + LOG_ERR("Invalid pin configuration"); + return -EINVAL; + } + return 0; +} + +static int fetch_pin_temperature_value(const struct device *dev, + const enum adltc2990_monitoring_type mode, + const enum adltc2990_monitor_pins pin) +{ + if (mode != TEMPERATURE) { + LOG_DBG("Pin is not configured to measure temperature"); + return 0; + } + + struct adltc2990_data *data = dev->data; + int32_t value; + int ret; + + ret = adltc2990_fetch_property_value(dev, TEMPERATURE, pin, &value); + if (ret) { + return ret; + } + + switch (pin) { + case V1: + case V2: + data->pins_v1_v2_values[0] = value; + break; + + case V3: + case V4: + data->pins_v3_v4_values[0] = value; + default: + break; + } + + return 0; +} + +static int fetch_pin_current_value(const struct device *dev, + const enum adltc2990_monitoring_type mode, + const enum adltc2990_monitor_pins pin) +{ + int ret; + + ret = fetch_pin_differential_voltage_value(dev, mode, pin); + if (ret) { + return ret; + } + + const struct adltc2990_config *cfg = dev->config; + struct adltc2990_data *data = dev->data; + + switch (pin) { + case V1: + case V2: + data->pins_v1_v2_values[0] *= (ADLTC2990_MICROOHM_CONVERSION_FACTOR / + (float)cfg->pins_v1_v2.pins_current_resistor); + break; + + case V3: + case V4: + data->pins_v3_v4_values[0] *= (ADLTC2990_MICROOHM_CONVERSION_FACTOR / + (float)cfg->pins_v3_v4.pins_current_resistor); + break; + + default: + break; + } + + return 0; +} + static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel chan) { struct adltc2990_data *data = dev->data; @@ -262,13 +443,11 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel cfg->measurement_mode[1], cfg->measurement_mode[0]); enum adltc2990_monitoring_type mode_v3_v4 = adltc2990_get_v3_v4_measurement_modes( cfg->measurement_mode[1], cfg->measurement_mode[0]); - - float voltage_divider_ratio; int ret; int32_t value; switch (chan) { - case SENSOR_CHAN_DIE_TEMP: { + case SENSOR_CHAN_DIE_TEMP: ret = adltc2990_fetch_property_value(dev, TEMPERATURE, INTERNAL_TEMPERATURE, &value); if (ret) { @@ -276,32 +455,26 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel } data->internal_temperature = value; break; - } - case SENSOR_CHAN_CURRENT: { + + case SENSOR_CHAN_CURRENT: if (!(mode_v1_v2 == VOLTAGE_DIFFERENTIAL || mode_v3_v4 == VOLTAGE_DIFFERENTIAL)) { LOG_ERR("Sensor is not configured to measure Current"); return -EINVAL; } - if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { - ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1, &value); - if (ret) { - return ret; - } - data->pins_v1_v2_values[0] = - value * (ADLTC2990_MICROOHM_CONVERSION_FACTOR / - (float)cfg->pins_v1_v2.pins_current_resistor); + + ret = fetch_pin_current_value(dev, mode_v1_v2, V1); + if (ret) { + return ret; } - if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { - ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3, &value); - if (ret) { - return ret; - } - data->pins_v3_v4_values[0] = value * (ADLTC2990_MICROOHM_CONVERSION_FACTOR / - (float)cfg->pins_v3_v4.pins_current_resistor); + + ret = fetch_pin_current_value(dev, mode_v3_v4, V3); + if (ret) { + return ret; } + break; - } - case SENSOR_CHAN_VOLTAGE: { + + case SENSOR_CHAN_VOLTAGE: ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, SUPPLY_VOLTAGE, &value); if (ret) { @@ -309,109 +482,49 @@ static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel } data->supply_voltage = value + 2500000; - if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) { - ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1, &value); - if (ret) { - return ret; - } - data->pins_v1_v2_values[0] = value; - } else if (mode_v1_v2 == VOLTAGE_SINGLEENDED) { - uint32_t v1_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[0]; - - uint32_t v1_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[1]; - - voltage_divider_ratio = (v1_r1 + v1_r2) / (float)v1_r2; - ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V1, &value); - if (ret) { - return ret; - } - data->pins_v1_v2_values[0] = value * voltage_divider_ratio; - - uint32_t v2_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[0]; - - uint32_t v2_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1]; - - voltage_divider_ratio = (v2_r1 + v2_r2) / (float)v2_r2; - ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V2, &value); - if (ret) { - return ret; - } - data->pins_v1_v2_values[1] = value * voltage_divider_ratio; + ret = fetch_pin_differential_voltage_value(dev, mode_v1_v2, V1); + if (ret) { + return ret; } - if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) { - ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3, &value); - if (ret) { - return ret; - } - data->pins_v3_v4_values[0] = value; - } else if (mode_v3_v4 == VOLTAGE_SINGLEENDED) { - uint32_t v3_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[0]; - - uint32_t v3_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[1]; - - voltage_divider_ratio = (v3_r1 + v3_r2) / (float)v3_r2; - ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V3, &value); - if (ret) { - return ret; - } - data->pins_v3_v4_values[0] = value * voltage_divider_ratio; - - uint32_t v4_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[0]; - - uint32_t v4_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[1]; + ret = fetch_pin_differential_voltage_value(dev, mode_v3_v4, V3); + if (ret) { + return ret; + } - voltage_divider_ratio = (v4_r1 + v4_r2) / (float)v4_r2; + ret = fetch_pin_single_ended_voltage_value(dev, mode_v1_v2, V1, V2); + if (ret) { + return ret; + } - ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V4, &value); - if (ret) { - return ret; - } - data->pins_v3_v4_values[1] = value * voltage_divider_ratio; + ret = fetch_pin_single_ended_voltage_value(dev, mode_v3_v4, V3, V4); + if (ret) { + return ret; } + break; - } - case SENSOR_CHAN_AMBIENT_TEMP: { + + case SENSOR_CHAN_AMBIENT_TEMP: if (!(mode_v1_v2 == TEMPERATURE || mode_v3_v4 == TEMPERATURE)) { LOG_ERR("Sensor is not configured to measure Ambient Temperature"); return -EINVAL; } - if (mode_v1_v2 == TEMPERATURE) { - ret = adltc2990_fetch_property_value(dev, TEMPERATURE, V1, &value); - if (ret) { - return ret; - } - data->pins_v1_v2_values[0] = value; - } - if (mode_v3_v4 == TEMPERATURE) { - ret = adltc2990_fetch_property_value(dev, TEMPERATURE, V3, &value); - if (ret) { - return ret; - } - data->pins_v3_v4_values[0] = value; - } - break; - } - case SENSOR_CHAN_ALL: { - bool is_busy; - ret = adltc2990_is_busy(dev, &is_busy); + ret = fetch_pin_temperature_value(dev, mode_v1_v2, V1); if (ret) { return ret; } - if (is_busy) { - LOG_INF("ADLTC2990 conversion ongoing"); - return -EBUSY; + ret = fetch_pin_temperature_value(dev, mode_v3_v4, V3); + if (ret) { + return ret; } - adltc2990_trigger_measurement(dev); break; - } - default: { + + default: LOG_ERR("does not measure channel: %d", chan); return -ENOTSUP; } - } return 0; } @@ -433,13 +546,13 @@ static int adltc2990_channel_get(const struct device *dev, enum sensor_channel c uint8_t offset_index = 0, num_values_v1_v2 = 0, num_values_v3_v4 = 0; switch (chan) { - case SENSOR_CHAN_DIE_TEMP: { + case SENSOR_CHAN_DIE_TEMP: val->val1 = (data->internal_temperature) / 1000000; val->val2 = (data->internal_temperature) % 1000000; LOG_DBG("Internal Temperature Value is:%d.%d", val->val1, val->val2); break; - } - case SENSOR_CHAN_VOLTAGE: { + + case SENSOR_CHAN_VOLTAGE: if (mode_v1_v2 == VOLTAGE_SINGLEENDED) { LOG_DBG("Getting V1,V2"); num_values_v1_v2 = ADLTC2990_VOLTAGE_SINGLE_ENDED_VALUES; @@ -458,8 +571,8 @@ static int adltc2990_channel_get(const struct device *dev, enum sensor_channel c val[num_values_v1_v2 + num_values_v3_v4].val1 = data->supply_voltage / 1000000; val[num_values_v1_v2 + num_values_v3_v4].val2 = data->supply_voltage % 1000000; break; - } - case SENSOR_CHAN_CURRENT: { + + case SENSOR_CHAN_CURRENT: if (!(mode_v1_v2 == VOLTAGE_DIFFERENTIAL || mode_v3_v4 == VOLTAGE_DIFFERENTIAL)) { LOG_ERR("Sensor is not configured to measure Current"); return -EINVAL; @@ -476,8 +589,8 @@ static int adltc2990_channel_get(const struct device *dev, enum sensor_channel c num_values_v3_v4 = ADLTC2990_CURRENT_VALUES; } break; - } - case SENSOR_CHAN_AMBIENT_TEMP: { + + case SENSOR_CHAN_AMBIENT_TEMP: if (!(mode_v1_v2 == TEMPERATURE || mode_v3_v4 == TEMPERATURE)) { LOG_ERR("Sensor is not configured to measure Ambient Temperature"); return -EINVAL; @@ -494,11 +607,10 @@ static int adltc2990_channel_get(const struct device *dev, enum sensor_channel c num_values_v3_v4 = ADLTC2990_TEMP_VALUES; } break; - } - default: { + + default: return -ENOTSUP; } - } adltc2990_get_v1_v2_val(dev, val, num_values_v1_v2, &offset_index); adltc2990_get_v3_v4_val(dev, val, num_values_v3_v4, &offset_index); @@ -511,11 +623,12 @@ static DEVICE_API(sensor, adltc2990_driver_api) = { }; #define ADLTC2990_DEFINE(inst) \ - static struct adltc2990_data adltc2990_data_##inst; \ + static struct adltc2990_data adltc2990_data_##inst = { \ + .acq_format = DT_INST_PROP(inst, acquistion_format), \ + }; \ static const struct adltc2990_config adltc2990_config_##inst = { \ .bus = I2C_DT_SPEC_INST_GET(inst), \ .temp_format = DT_INST_PROP(inst, temperature_format), \ - .acq_format = DT_INST_PROP(inst, acquistion_format), \ .measurement_mode = DT_INST_PROP(inst, measurement_mode), \ .pins_v1_v2.pins_current_resistor = \ DT_INST_PROP_OR(inst, pins_v1_v2_current_resistor, 1), \ diff --git a/drivers/sensor/adi/adltc2990/adltc2990.h b/drivers/sensor/adi/adltc2990/adltc2990.h deleted file mode 100644 index af2d199553155..0000000000000 --- a/drivers/sensor/adi/adltc2990/adltc2990.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H -#define ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H - -#include -#include -#include -#include -#include - -enum adltc2990_monitor_pins { - V1, - V2, - V3, - V4, - INTERNAL_TEMPERATURE, - SUPPLY_VOLTAGE -}; - -enum adltc2990_monitoring_type { - NOTHING, - VOLTAGE_DIFFERENTIAL, - VOLTAGE_SINGLEENDED, - TEMPERATURE -}; - -union voltage_divider_resistors { - struct { - uint32_t v1_r1_r2[2]; - uint32_t v2_r1_r2[2]; - }; - struct { - uint32_t v3_r1_r2[2]; - uint32_t v4_r1_r2[2]; - }; -}; - -struct pins_configuration { - uint32_t pins_current_resistor; - union voltage_divider_resistors voltage_divider_resistors; -}; - -struct adltc2990_data { - int32_t internal_temperature; - int32_t supply_voltage; - int32_t pins_v1_v2_values[2]; - int32_t pins_v3_v4_values[2]; -}; - -struct adltc2990_config { - struct i2c_dt_spec bus; - uint8_t temp_format; - uint8_t acq_format; - uint8_t measurement_mode[2]; - struct pins_configuration pins_v1_v2; - struct pins_configuration pins_v3_v4; -}; - -#endif /* ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H */ diff --git a/drivers/sensor/adi/adltc2990/adltc2990_emul.c b/drivers/sensor/adi/adltc2990/adltc2990_emul.c index 80078f21dc58b..d4b9c310ea3a8 100644 --- a/drivers/sensor/adi/adltc2990/adltc2990_emul.c +++ b/drivers/sensor/adi/adltc2990/adltc2990_emul.c @@ -1,5 +1,6 @@ /* * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +14,7 @@ #include #include -#include "adltc2990.h" +#include "adltc2990_internal.h" #include "adltc2990_reg.h" #include "adltc2990_emul.h" diff --git a/drivers/sensor/adi/adltc2990/adltc2990_internal.h b/drivers/sensor/adi/adltc2990/adltc2990_internal.h new file mode 100644 index 0000000000000..a58db120ee956 --- /dev/null +++ b/drivers/sensor/adi/adltc2990/adltc2990_internal.h @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG + * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H +#define ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H + +#include +#include +#include +#include +#include + +enum adltc2990_monitor_pins { + V1, + V2, + V3, + V4, + INTERNAL_TEMPERATURE, + SUPPLY_VOLTAGE +}; + +enum adltc2990_monitoring_type { + NOTHING, + VOLTAGE_DIFFERENTIAL, + VOLTAGE_SINGLEENDED, + TEMPERATURE +}; + +union voltage_divider_resistors { + struct { + uint32_t v1_r1_r2[2]; + uint32_t v2_r1_r2[2]; + }; + struct { + uint32_t v3_r1_r2[2]; + uint32_t v4_r1_r2[2]; + }; +}; + +struct pins_configuration { + uint32_t pins_current_resistor; + union voltage_divider_resistors voltage_divider_resistors; +}; + +struct adltc2990_data { + uint8_t acq_format; + int32_t internal_temperature; + int32_t supply_voltage; + int32_t pins_v1_v2_values[2]; + int32_t pins_v3_v4_values[2]; +}; + +struct adltc2990_config { + struct i2c_dt_spec bus; + uint8_t temp_format; + uint8_t measurement_mode[2]; + struct pins_configuration pins_v1_v2; + struct pins_configuration pins_v3_v4; +}; + +#endif /* ZEPHYR_DRIVERS_SENSOR_ADLTC2990_H */ diff --git a/drivers/sensor/adi/adxl345/Kconfig b/drivers/sensor/adi/adxl345/Kconfig index 9463eb0c51cc4..481ddd404ad86 100644 --- a/drivers/sensor/adi/adxl345/Kconfig +++ b/drivers/sensor/adi/adxl345/Kconfig @@ -37,8 +37,7 @@ endchoice config ADXL345_STREAM bool "Use FIFO to stream data" select ADXL345_TRIGGER - default y - depends on SPI_RTIO + depends on (SPI_RTIO || I2C_RTIO) depends on SENSOR_ASYNC_API help Use this configuration option to enable streaming sensor data via RTIO. diff --git a/drivers/sensor/adi/adxl345/adxl345.c b/drivers/sensor/adi/adxl345/adxl345.c index d955c3b1ef532..14463392bb7e2 100644 --- a/drivers/sensor/adi/adxl345/adxl345.c +++ b/drivers/sensor/adi/adxl345/adxl345.c @@ -229,7 +229,7 @@ static int adxl345_attr_set_odr(const struct device *dev, const struct sensor_value *val) { enum adxl345_odr odr; - struct adxl345_dev_config *cfg = (struct adxl345_dev_config *)dev->config; + struct adxl345_dev_data *data = dev->data; switch (val->val1) { case 12: @@ -257,7 +257,7 @@ static int adxl345_attr_set_odr(const struct device *dev, int ret = adxl345_set_odr(dev, odr); if (ret == 0) { - cfg->odr = odr; + data->odr = odr; } return ret; @@ -281,6 +281,7 @@ int adxl345_read_sample(const struct device *dev, { int16_t raw_x, raw_y, raw_z; uint8_t axis_data[6], status1; + struct adxl345_dev_data *data = dev->data; if (!IS_ENABLED(CONFIG_ADXL345_TRIGGER)) { do { @@ -303,6 +304,9 @@ int adxl345_read_sample(const struct device *dev, sample->y = raw_y; sample->z = raw_z; + sample->selected_range = data->selected_range; + sample->is_full_res = data->is_full_res; + return 0; } @@ -453,11 +457,13 @@ static int adxl345_init(const struct device *dev) return -ENODEV; } +#if CONFIG_ADXL345_STREAM rc = adxl345_reg_write_byte(dev, ADXL345_FIFO_CTL_REG, ADXL345_FIFO_STREAM_MODE); if (rc < 0) { LOG_ERR("FIFO enable failed\n"); return -EIO; } +#endif rc = adxl345_reg_write_byte(dev, ADXL345_DATA_FORMAT_REG, ADXL345_RANGE_8G); if (rc < 0) { @@ -519,18 +525,43 @@ static int adxl345_init(const struct device *dev) #define ADXL345_CFG_IRQ(inst) #endif /* CONFIG_ADXL345_TRIGGER */ -#define ADXL345_RTIO_DEFINE(inst) \ - SPI_DT_IODEV_DEFINE(adxl345_iodev_##inst, DT_DRV_INST(inst), \ - SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \ - SPI_MODE_CPOL | SPI_MODE_CPHA, 0U); \ - RTIO_DEFINE(adxl345_rtio_ctx_##inst, 64, 64); +#define ADXL345_RTIO_SPI_DEFINE(inst) \ + COND_CODE_1(CONFIG_SPI_RTIO, \ + (SPI_DT_IODEV_DEFINE(adxl345_iodev_##inst, DT_DRV_INST(inst), \ + SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \ + SPI_MODE_CPOL | SPI_MODE_CPHA, 0U);), \ + ()) + +#define ADXL345_RTIO_I2C_DEFINE(inst) \ + COND_CODE_1(CONFIG_I2C_RTIO, \ + (I2C_DT_IODEV_DEFINE(adxl345_iodev_##inst, DT_DRV_INST(inst));), \ + ()) + + /* Conditionally set the RTIO size based on the presence of SPI/I2C + * lines 541 - 542. + * The sizes of sqe and cqe pools are increased due to the amount of + * multibyte reads needed for watermark using 31 samples + * (adx345_stram - line 203), using smaller amounts of samples + * to trigger an interrupt can decrease the pool sizes. + */ +#define ADXL345_RTIO_DEFINE(inst) \ + /* Conditionally include SPI and/or I2C parts based on their presence */ \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (ADXL345_RTIO_SPI_DEFINE(inst)), \ + ()) \ + COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \ + (ADXL345_RTIO_I2C_DEFINE(inst)), \ + ()) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, spi_dt_spec) && \ + DT_INST_NODE_HAS_PROP(inst, i2c_dt_spec), \ + (RTIO_DEFINE(adxl345_rtio_ctx_##inst, 128, 128);), \ + (RTIO_DEFINE(adxl345_rtio_ctx_##inst, 64, 64);)) \ #define ADXL345_CONFIG(inst) \ .odr = DT_INST_PROP(inst, odr), \ .fifo_config.fifo_mode = ADXL345_FIFO_STREAMED, \ .fifo_config.fifo_trigger = ADXL345_INT2, \ .fifo_config.fifo_samples = SAMPLE_NUM, \ - .op_mode = TRUE, \ .odr = ADXL345_RATE_25HZ, \ #define ADXL345_CONFIG_SPI(inst) \ @@ -543,6 +574,7 @@ static int adxl345_init(const struct device *dev) 0)}, \ .bus_is_ready = adxl345_bus_is_ready_spi, \ .reg_access = adxl345_reg_access_spi, \ + .bus_type = ADXL345_BUS_SPI, \ ADXL345_CONFIG(inst) \ COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int2_gpios), \ (ADXL345_CFG_IRQ(inst)), ()) \ @@ -553,13 +585,17 @@ static int adxl345_init(const struct device *dev) .bus = {.i2c = I2C_DT_SPEC_INST_GET(inst)}, \ .bus_is_ready = adxl345_bus_is_ready_i2c, \ .reg_access = adxl345_reg_access_i2c, \ + .bus_type = ADXL345_BUS_I2C, \ + ADXL345_CONFIG(inst) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int2_gpios), \ + (ADXL345_CFG_IRQ(inst)), ()) \ } #define ADXL345_DEFINE(inst) \ IF_ENABLED(CONFIG_ADXL345_STREAM, (ADXL345_RTIO_DEFINE(inst))); \ - static struct adxl345_dev_data adxl345_data_##inst = { \ - IF_ENABLED(CONFIG_ADXL345_STREAM, (.rtio_ctx = &adxl345_rtio_ctx_##inst, \ - .iodev = &adxl345_iodev_##inst,)) \ + static struct adxl345_dev_data adxl345_data_##inst = { \ + COND_CODE_1(adxl345_iodev_##inst, (.rtio_ctx = &adxl345_rtio_ctx_##inst, \ + .iodev = &adxl345_iodev_##inst,), ()) \ }; \ static const struct adxl345_dev_config adxl345_config_##inst = \ COND_CODE_1(DT_INST_ON_BUS(inst, spi), (ADXL345_CONFIG_SPI(inst)), \ diff --git a/drivers/sensor/adi/adxl345/adxl345.h b/drivers/sensor/adi/adxl345/adxl345.h index 4fc55d307c1a3..8bc25f5034028 100644 --- a/drivers/sensor/adi/adxl345/adxl345.h +++ b/drivers/sensor/adi/adxl345/adxl345.h @@ -113,6 +113,9 @@ #define ADXL345_ODR_MSK GENMASK(3, 0) #define ADXL345_ODR_MODE(x) ((x) & 0xF) +#define ADXL345_BUS_I2C 0 +#define ADXL345_BUS_SPI 1 + enum adxl345_odr { ADXL345_ODR_12HZ = 0x7, ADXL345_ODR_25HZ, @@ -153,6 +156,7 @@ struct adxl345_dev_data { struct adxl345_fifo_config fifo_config; uint8_t is_full_res; uint8_t selected_range; + enum adxl345_odr odr; #ifdef CONFIG_ADXL345_TRIGGER struct gpio_callback gpio_cb; @@ -201,6 +205,7 @@ struct adxl345_sample { uint8_t res: 7; #endif /* CONFIG_ADXL345_STREAM */ uint8_t selected_range; + bool is_full_res; int16_t x; int16_t y; int16_t z; @@ -226,6 +231,7 @@ struct adxl345_dev_config { enum adxl345_odr odr; bool op_mode; struct adxl345_fifo_config fifo_config; + uint8_t bus_type; #ifdef CONFIG_ADXL345_TRIGGER struct gpio_dt_spec interrupt; #endif diff --git a/drivers/sensor/adi/adxl345/adxl345_decoder.c b/drivers/sensor/adi/adxl345/adxl345_decoder.c index 7a1bf53cb0584..1f39fb9d1d141 100644 --- a/drivers/sensor/adi/adxl345/adxl345_decoder.c +++ b/drivers/sensor/adi/adxl345/adxl345_decoder.c @@ -6,17 +6,42 @@ #include "adxl345.h" -#ifdef CONFIG_ADXL345_STREAM +/** The q-scale factor will always be the same, as the nominal LSB/g + * changes at the same rate the selected shift parameter per range: + * + * - At 2G: 256 LSB/g, 10-bits resolution. + * - At 4g: 128 LSB/g, 10-bits resolution. + * - At 8g: 64 LSB/g, 10-bits resolution. + * - At 16g 32 LSB/g, 10-bits resolution. + */ +static const uint32_t qscale_factor_no_full_res[] = { + /* (1.0 / Resolution-LSB-per-g * (2^31 / 2^5) * SENSOR_G / 1000000 */ + [ADXL345_RANGE_2G] = UINT32_C(2570754), + /* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^6) * SENSOR_G / 1000000 */ + [ADXL345_RANGE_4G] = UINT32_C(2570754), + /* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */ + [ADXL345_RANGE_8G] = UINT32_C(2570754), + /* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */ + [ADXL345_RANGE_16G] = UINT32_C(2570754), +}; -#define SENSOR_SCALING_FACTOR (SENSOR_G / (16 * 1000 / 100)) -static const uint32_t accel_period_ns[] = { - [ADXL345_ODR_12HZ] = UINT32_C(1000000000) / 12, - [ADXL345_ODR_25HZ] = UINT32_C(1000000000) / 25, - [ADXL345_ODR_50HZ] = UINT32_C(1000000000) / 50, - [ADXL345_ODR_100HZ] = UINT32_C(1000000000) / 100, - [ADXL345_ODR_200HZ] = UINT32_C(1000000000) / 200, - [ADXL345_ODR_400HZ] = UINT32_C(1000000000) / 400, +/** Sensitivities based on Range: + * + * - At 2G: 256 LSB/g, 10-bits resolution. + * - At 4g: 256 LSB/g, 11-bits resolution. + * - At 8g: 256 LSB/g, 12-bits resolution. + * - At 16g 256 LSB/g, 13-bits resolution. + */ +static const uint32_t qscale_factor_full_res[] = { + /* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^5) * SENSOR_G / 1000000 */ + [ADXL345_RANGE_2G] = UINT32_C(2570754), + /* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^6) * SENSOR_G / 1000000 */ + [ADXL345_RANGE_4G] = UINT32_C(1285377), + /* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */ + [ADXL345_RANGE_8G] = UINT32_C(642688), + /* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */ + [ADXL345_RANGE_16G] = UINT32_C(321344), }; static const uint32_t range_to_shift[] = { @@ -26,30 +51,6 @@ static const uint32_t range_to_shift[] = { [ADXL345_RANGE_16G] = 8, }; -/* (1 / sensitivity) * (pow(2,31) / pow(2,shift)) * (unit_scaler) */ -static const uint32_t qscale_factor_no_full_res[] = { - /* (1.0 / ADXL362_ACCEL_2G_LSB_PER_G) * (2^31 / 2^5) * SENSOR_G / 1000000 */ - [ADXL345_RANGE_2G] = UINT32_C(2569011), - /* (1.0 / ADXL362_ACCEL_4G_LSB_PER_G) * (2^31 / 2^6) * SENSOR_G / 1000000 */ - [ADXL345_RANGE_4G] = UINT32_C(642253), - /* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */ - [ADXL345_RANGE_8G] = UINT32_C(160563), - /* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */ - [ADXL345_RANGE_16G] = UINT32_C(40141), -}; - -/* (1 / sensitivity) * (pow(2,31) / pow(2,shift)) * (unit_scaler) */ -static const uint32_t qscale_factor_full_res[] = { - /* (1.0 / ADXL362_ACCEL_2G_LSB_PER_G) * (2^31 / 2^5) * SENSOR_G / 1000000 */ - [ADXL345_RANGE_2G] = UINT32_C(2569011), - /* (1.0 / ADXL362_ACCEL_4G_LSB_PER_G) * (2^31 / 2^6) * SENSOR_G / 1000000 */ - [ADXL345_RANGE_4G] = UINT32_C(1284506), - /* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */ - [ADXL345_RANGE_8G] = UINT32_C(642253), - /* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */ - [ADXL345_RANGE_16G] = UINT32_C(321126), -}; - static inline void adxl345_accel_convert_q31(q31_t *out, int16_t sample, int32_t range, uint8_t is_full_res) { @@ -76,15 +77,28 @@ static inline void adxl345_accel_convert_q31(q31_t *out, int16_t sample, int32_t } break; } + *out = sample * qscale_factor_full_res[range]; } else { if (sample & BIT(9)) { sample |= ADXL345_COMPLEMENT; } + *out = sample * qscale_factor_no_full_res[range]; } - - *out = sample * qscale_factor_no_full_res[range]; } +#ifdef CONFIG_ADXL345_STREAM + +#define SENSOR_SCALING_FACTOR (SENSOR_G / (16 * 1000 / 100)) + +static const uint32_t accel_period_ns[] = { + [ADXL345_ODR_12HZ] = UINT32_C(1000000000) / 12, + [ADXL345_ODR_25HZ] = UINT32_C(1000000000) / 25, + [ADXL345_ODR_50HZ] = UINT32_C(1000000000) / 50, + [ADXL345_ODR_100HZ] = UINT32_C(1000000000) / 100, + [ADXL345_ODR_200HZ] = UINT32_C(1000000000) / 200, + [ADXL345_ODR_400HZ] = UINT32_C(1000000000) / 400, +}; + static int adxl345_decode_stream(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint32_t *fit, uint16_t max_count, void *data_out) { @@ -208,7 +222,12 @@ static int adxl345_decode_sample(const struct adxl345_sample *data, struct sensor_chan_spec chan_spec, uint32_t *fit, uint16_t max_count, void *data_out) { - struct sensor_value *out = (struct sensor_value *)data_out; + struct sensor_three_axis_data *out = (struct sensor_three_axis_data *)data_out; + + memset(out, 0, sizeof(struct sensor_three_axis_data)); + out->header.base_timestamp_ns = k_ticks_to_ns_floor64(k_uptime_ticks()); + out->header.reading_count = 1; + out->shift = range_to_shift[data->selected_range]; if (*fit > 0) { return -ENOTSUP; @@ -216,9 +235,12 @@ static int adxl345_decode_sample(const struct adxl345_sample *data, switch (chan_spec.chan_type) { case SENSOR_CHAN_ACCEL_XYZ: - adxl345_accel_convert(out++, data->x); - adxl345_accel_convert(out++, data->y); - adxl345_accel_convert(out, data->z); + adxl345_accel_convert_q31(&out->readings->x, data->x, data->selected_range, + data->is_full_res); + adxl345_accel_convert_q31(&out->readings->y, data->y, data->selected_range, + data->is_full_res); + adxl345_accel_convert_q31(&out->readings->z, data->z, data->selected_range, + data->is_full_res); break; default: return -ENOTSUP; @@ -226,7 +248,7 @@ static int adxl345_decode_sample(const struct adxl345_sample *data, *fit = 1; - return 0; + return 1; } static int adxl345_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, @@ -259,10 +281,33 @@ static bool adxl345_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigg } } +static int adxl345_get_size_info(struct sensor_chan_spec channel, size_t *base_size, + size_t *frame_size) +{ + __ASSERT_NO_MSG(base_size != NULL); + __ASSERT_NO_MSG(frame_size != NULL); + + if (channel.chan_type >= SENSOR_CHAN_ALL) { + return -ENOTSUP; + } + + switch (channel.chan_type) { + case SENSOR_CHAN_ACCEL_XYZ: + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; + default: + break; + } + + return -ENOTSUP; +} + SENSOR_DECODER_API_DT_DEFINE() = { .get_frame_count = adxl345_decoder_get_frame_count, .decode = adxl345_decoder_decode, .has_trigger = adxl345_decoder_has_trigger, + .get_size_info = adxl345_get_size_info, }; int adxl345_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) diff --git a/drivers/sensor/adi/adxl345/adxl345_stream.c b/drivers/sensor/adi/adxl345/adxl345_stream.c index c07778dd3dabe..ac62f3fbf6a2a 100644 --- a/drivers/sensor/adi/adxl345/adxl345_stream.c +++ b/drivers/sensor/adi/adxl345/adxl345_stream.c @@ -6,7 +6,7 @@ #include #include - +#include #include "adxl345.h" LOG_MODULE_DECLARE(ADXL345, CONFIG_SENSOR_LOG_LEVEL); @@ -159,7 +159,7 @@ static void adxl345_process_fifo_samples_cb(struct rtio *r, const struct rtio_sq hdr->int_status = data->status1; hdr->is_full_res = data->is_full_res; hdr->selected_range = data->selected_range; - hdr->accel_odr = cfg->odr; + hdr->accel_odr = data->odr; hdr->sample_set_size = sample_set_size; uint32_t buf_avail = buf_len; @@ -216,6 +216,9 @@ static void adxl345_process_fifo_samples_cb(struct rtio *r, const struct rtio_sq read_buf + data->fifo_total_bytes, SAMPLE_SIZE, current_sqe); data->fifo_total_bytes += SAMPLE_SIZE; + if (cfg->bus_type == ADXL345_BUS_I2C) { + read_fifo_data->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + } if (i == fifo_samples-1) { struct rtio_sqe *complete_op = rtio_sqe_acquire(data->rtio_ctx); @@ -342,6 +345,9 @@ static void adxl345_process_status1_cb(struct rtio *r, const struct rtio_sqe *sq rtio_sqe_prep_read(read_fifo_data, data->iodev, RTIO_PRIO_NORM, data->fifo_ent, 1, current_sqe); read_fifo_data->flags = RTIO_SQE_CHAINED; + if (cfg->bus_type == ADXL345_BUS_I2C) { + read_fifo_data->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + } rtio_sqe_prep_callback(complete_op, adxl345_process_fifo_samples_cb, (void *)dev, current_sqe); @@ -351,11 +357,22 @@ static void adxl345_process_status1_cb(struct rtio *r, const struct rtio_sqe *sq void adxl345_stream_irq_handler(const struct device *dev) { struct adxl345_dev_data *data = (struct adxl345_dev_data *) dev->data; + const struct adxl345_dev_config *cfg = (const struct adxl345_dev_config *) dev->config; + uint64_t cycles; + int rc; if (data->sqe == NULL) { return; } - data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(data->sqe, rc); + return; + } + + data->timestamp = sensor_clock_cycles_to_ns(cycles); struct rtio_sqe *write_status_addr = rtio_sqe_acquire(data->rtio_ctx); struct rtio_sqe *read_status_reg = rtio_sqe_acquire(data->rtio_ctx); struct rtio_sqe *check_status_reg = rtio_sqe_acquire(data->rtio_ctx); @@ -366,6 +383,9 @@ void adxl345_stream_irq_handler(const struct device *dev) rtio_sqe_prep_read(read_status_reg, data->iodev, RTIO_PRIO_NORM, &data->status1, 1, NULL); read_status_reg->flags = RTIO_SQE_CHAINED; + if (cfg->bus_type == ADXL345_BUS_I2C) { + read_status_reg->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + } rtio_sqe_prep_callback(check_status_reg, adxl345_process_status1_cb, (void *)dev, NULL); rtio_submit(data->rtio_ctx, 0); } diff --git a/drivers/sensor/adi/adxl362/adxl362_stream.c b/drivers/sensor/adi/adxl362/adxl362_stream.c index 55175a4f9b01a..453ed334348a7 100644 --- a/drivers/sensor/adi/adxl362/adxl362_stream.c +++ b/drivers/sensor/adi/adxl362/adxl362_stream.c @@ -6,7 +6,7 @@ #include #include - +#include #include "adxl362.h" LOG_MODULE_DECLARE(ADXL362, CONFIG_SENSOR_LOG_LEVEL); @@ -384,12 +384,20 @@ static void adxl362_process_status_cb(struct rtio *r, const struct rtio_sqe *sqr void adxl362_stream_irq_handler(const struct device *dev) { struct adxl362_data *data = (struct adxl362_data *) dev->data; - + uint64_t cycles; + int rc; if (data->sqe == NULL) { return; } - data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(data->sqe, rc); + return; + } + + data->timestamp = sensor_clock_cycles_to_ns(cycles); struct rtio_sqe *write_status_addr = rtio_sqe_acquire(data->rtio_ctx); struct rtio_sqe *read_status_reg = rtio_sqe_acquire(data->rtio_ctx); diff --git a/drivers/sensor/adi/adxl367/adxl367_stream.c b/drivers/sensor/adi/adxl367/adxl367_stream.c index 5826ed8d6cc2f..eb57349a2997c 100644 --- a/drivers/sensor/adi/adxl367/adxl367_stream.c +++ b/drivers/sensor/adi/adxl367/adxl367_stream.c @@ -6,7 +6,7 @@ #include #include - +#include #include "adxl367.h" LOG_MODULE_DECLARE(ADXL362, CONFIG_SENSOR_LOG_LEVEL); @@ -537,12 +537,20 @@ static void adxl367_process_status_cb(struct rtio *r, const struct rtio_sqe *sqr void adxl367_stream_irq_handler(const struct device *dev) { struct adxl367_data *data = (struct adxl367_data *) dev->data; - + uint64_t cycles; + int rc; if (data->sqe == NULL) { return; } - data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(data->sqe, rc); + return; + } + + data->timestamp = sensor_clock_cycles_to_ns(cycles); struct rtio_sqe *write_status_addr = rtio_sqe_acquire(data->rtio_ctx); struct rtio_sqe *read_status_reg = rtio_sqe_acquire(data->rtio_ctx); diff --git a/drivers/sensor/adi/adxl372/adxl372.c b/drivers/sensor/adi/adxl372/adxl372.c index 675d91705d37c..dbffe36ec3df9 100644 --- a/drivers/sensor/adi/adxl372/adxl372.c +++ b/drivers/sensor/adi/adxl372/adxl372.c @@ -550,7 +550,7 @@ static int adxl372_attr_set_odr(const struct device *dev, const struct sensor_value *val) { enum adxl372_odr odr; - struct adxl372_dev_config *cfg = (struct adxl372_dev_config *)dev->config; + struct adxl372_data *data = dev->data; switch (val->val1) { case 400: @@ -575,7 +575,7 @@ static int adxl372_attr_set_odr(const struct device *dev, int ret = adxl372_set_odr(dev, odr); if (ret == 0) { - cfg->odr = odr; + data->odr = odr; } return ret; diff --git a/drivers/sensor/adi/adxl372/adxl372.h b/drivers/sensor/adi/adxl372/adxl372.h index a3f93cebb3268..acfcf5fddb4fe 100644 --- a/drivers/sensor/adi/adxl372/adxl372.h +++ b/drivers/sensor/adi/adxl372/adxl372.h @@ -312,6 +312,7 @@ struct adxl372_data { const struct adxl372_transfer_function *hw_tf; struct adxl372_fifo_config fifo_config; enum adxl372_act_proc_mode act_proc_mode; + enum adxl372_odr odr; #ifdef CONFIG_ADXL372_TRIGGER struct gpio_callback gpio_cb; diff --git a/drivers/sensor/adi/adxl372/adxl372_stream.c b/drivers/sensor/adi/adxl372/adxl372_stream.c index a4dda2f2ce80b..71624344ec233 100644 --- a/drivers/sensor/adi/adxl372/adxl372_stream.c +++ b/drivers/sensor/adi/adxl372/adxl372_stream.c @@ -6,6 +6,7 @@ #include #include +#include #include "adxl372.h" @@ -213,7 +214,7 @@ static void adxl372_process_fifo_samples_cb(struct rtio *r, const struct rtio_sq hdr->is_fifo = 1; hdr->timestamp = data->timestamp; hdr->int_status = data->status1; - hdr->accel_odr = cfg->odr; + hdr->accel_odr = data->odr; hdr->sample_set_size = sample_set_size; if ((cfg->fifo_config.fifo_format == ADXL372_X_FIFO) || @@ -424,12 +425,20 @@ static void adxl372_process_status1_cb(struct rtio *r, const struct rtio_sqe *sq void adxl372_stream_irq_handler(const struct device *dev) { struct adxl372_data *data = (struct adxl372_data *)dev->data; - + uint64_t cycles; + int rc; if (data->sqe == NULL) { return; } - data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(data->sqe, rc); + return; + } + + data->timestamp = sensor_clock_cycles_to_ns(cycles); struct rtio_sqe *write_status_addr = rtio_sqe_acquire(data->rtio_ctx); struct rtio_sqe *read_status_reg = rtio_sqe_acquire(data->rtio_ctx); diff --git a/drivers/sensor/ams/tsl2591/tsl2591.c b/drivers/sensor/ams/tsl2591/tsl2591.c index 51bc0891f10e4..bc378ecd2897e 100644 --- a/drivers/sensor/ams/tsl2591/tsl2591.c +++ b/drivers/sensor/ams/tsl2591/tsl2591.c @@ -418,11 +418,11 @@ static int tsl2591_setup(const struct device *dev) uint8_t device_id; int ret; - ret = tsl2591_reg_write(dev, TSL2591_REG_CONFIG, TSL2591_SRESET); - if (ret < 0) { - LOG_ERR("Failed to reset device"); - return ret; - } + /* Reset the sensor. Although this is not clearly documented in the datasheet, + * it is suspected that because the sensor is reset, it doesn't explicitly send + * an ACK. Thus, don't check the return code. + */ + tsl2591_reg_write(dev, TSL2591_REG_CONFIG, TSL2591_SRESET); ret = tsl2591_reg_read(dev, TSL2591_REG_ID, &device_id, 1U); if (ret < 0) { diff --git a/drivers/sensor/aosong/dht/dht.c b/drivers/sensor/aosong/dht/dht.c index 43babce02eeac..88d16f1c6e70b 100644 --- a/drivers/sensor/aosong/dht/dht.c +++ b/drivers/sensor/aosong/dht/dht.c @@ -82,8 +82,6 @@ static int dht_sample_fetch(const struct device *dev, k_busy_wait(DHT_START_SIGNAL_DURATION); - gpio_pin_set_dt(&cfg->dio_gpio, false); - /* switch to DIR_IN to read sensor signals */ gpio_pin_configure_dt(&cfg->dio_gpio, GPIO_INPUT); diff --git a/drivers/sensor/apds9306/apds9306.c b/drivers/sensor/apds9306/apds9306.c index fab461d983abd..87723b21624fc 100644 --- a/drivers/sensor/apds9306/apds9306.c +++ b/drivers/sensor/apds9306/apds9306.c @@ -271,7 +271,10 @@ static int apds9306_sensor_setup(const struct device *dev) /* Wait for the device to become ready after a possible power cycle. */ now = k_uptime_get_32(); do { - i2c_reg_read_byte_dt(&config->i2c, APDS9306_REGISTER_MAIN_STATUS, &temp); + if (i2c_reg_read_byte_dt(&config->i2c, APDS9306_REGISTER_MAIN_STATUS, &temp)) { + LOG_ERR("Failed reading sensor status!"); + return -EFAULT; + } /* We wait 100 ms maximum for the device to become ready. */ if ((k_uptime_get_32() - now) > 100) { @@ -308,7 +311,10 @@ static int apds9306_sensor_setup(const struct device *dev) /* Perform a dummy read to avoid bus errors after the reset. See */ /* https://lore.kernel.org/lkml/ab1d9746-4d23-efcc-0ee1-d2b8c634becd@tweaklogic.com/ */ - i2c_reg_read_byte_dt(&config->i2c, APDS9306_REGISTER_PART_ID, &temp); + if (i2c_reg_read_byte_dt(&config->i2c, APDS9306_REGISTER_PART_ID, &temp)) { + LOG_ERR("Failed reading chip id!"); + return -EFAULT; + } return 0; } diff --git a/drivers/sensor/asahi_kasei/akm09918c/akm09918c_async.c b/drivers/sensor/asahi_kasei/akm09918c/akm09918c_async.c index 832d046bdd7ab..dedc2411489a1 100644 --- a/drivers/sensor/asahi_kasei/akm09918c/akm09918c_async.c +++ b/drivers/sensor/asahi_kasei/akm09918c/akm09918c_async.c @@ -8,6 +8,7 @@ #include #include +#include #include "akm09918c.h" @@ -20,6 +21,7 @@ void akm09918c_submit_sync(struct rtio_iodev_sqe *iodev_sqe) struct akm09918c_data *data = dev->data; const struct sensor_chan_spec *const channels = cfg->channels; const size_t num_channels = cfg->count; + uint64_t cycles; int rc; /* Check if the requested channels are supported */ @@ -46,8 +48,15 @@ void akm09918c_submit_sync(struct rtio_iodev_sqe *iodev_sqe) return; } + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + /* save information for the work item */ - data->work_ctx.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + data->work_ctx.timestamp = sensor_clock_cycles_to_ns(cycles); data->work_ctx.iodev_sqe = iodev_sqe; rc = k_work_schedule(&data->work_ctx.async_fetch_work, K_USEC(AKM09918C_MEASURE_TIME_US)); diff --git a/drivers/sensor/bosch/bma4xx/bma4xx.c b/drivers/sensor/bosch/bma4xx/bma4xx.c index 219d65dc5ed28..0340f20ed4782 100644 --- a/drivers/sensor/bosch/bma4xx/bma4xx.c +++ b/drivers/sensor/bosch/bma4xx/bma4xx.c @@ -14,6 +14,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(bma4xx, CONFIG_SENSOR_LOG_LEVEL); #include "bma4xx.h" @@ -352,6 +353,7 @@ static void bma4xx_submit_one_shot(const struct device *dev, struct rtio_iodev_s struct bma4xx_encoded_data *edata; uint8_t *buf; uint32_t buf_len; + uint64_t cycles; int rc; /* Get the buffer for the frame, it may be allocated dynamically by the rtio context */ @@ -362,11 +364,18 @@ static void bma4xx_submit_one_shot(const struct device *dev, struct rtio_iodev_s return; } + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + /* Prepare response */ edata = (struct bma4xx_encoded_data *)buf; edata->header.is_fifo = false; edata->header.accel_fs = bma4xx->accel_fs_range; - edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); edata->has_accel = 0; edata->has_temp = 0; diff --git a/drivers/sensor/bosch/bme280/bme280.c b/drivers/sensor/bosch/bme280/bme280.c index 903433b7a70a3..327e25a1cc8bf 100644 --- a/drivers/sensor/bosch/bme280/bme280.c +++ b/drivers/sensor/bosch/bme280/bme280.c @@ -33,6 +33,13 @@ LOG_MODULE_REGISTER(BME280, CONFIG_SENSOR_LOG_LEVEL); */ #define BME280_MEASUREMENT_TIMEOUT_MS 150 +/* Equation 9.1, with the fractional parts rounded down */ +#define BME280_EXPECTED_SAMPLE_TIME_MS \ + 1 + BME280_TEMP_SAMPLE_TIME + BME280_PRESS_SAMPLE_TIME + BME280_HUMIDITY_SAMPLE_TIME + +BUILD_ASSERT(BME280_EXPECTED_SAMPLE_TIME_MS < BME280_MEASUREMENT_TIMEOUT_MS, + "Expected duration over timeout duration"); + struct bme280_config { union bme280_bus bus; const struct bme280_bus_io *bus_io; @@ -154,6 +161,7 @@ int bme280_sample_fetch_helper(const struct device *dev, struct bme280_data *dev_data = dev->data; uint8_t buf[8]; int32_t adc_press, adc_temp, adc_humidity; + uint32_t poll_timeout; int size = 6; int ret; @@ -173,9 +181,14 @@ int bme280_sample_fetch_helper(const struct device *dev, if (ret < 0) { return ret; } + /* Wait until the expected measurement time elapses */ + k_sleep(K_MSEC(BME280_EXPECTED_SAMPLE_TIME_MS)); + poll_timeout = BME280_MEASUREMENT_TIMEOUT_MS - BME280_EXPECTED_SAMPLE_TIME_MS; +#else + poll_timeout = BME280_MEASUREMENT_TIMEOUT_MS; #endif - ret = bme280_wait_until_ready(dev, K_MSEC(BME280_MEASUREMENT_TIMEOUT_MS)); + ret = bme280_wait_until_ready(dev, K_MSEC(poll_timeout)); if (ret < 0) { return ret; } diff --git a/drivers/sensor/bosch/bme280/bme280.h b/drivers/sensor/bosch/bme280/bme280.h index 62fbefec38cd3..e20f3210c2f17 100644 --- a/drivers/sensor/bosch/bme280/bme280.h +++ b/drivers/sensor/bosch/bme280/bme280.h @@ -81,39 +81,54 @@ extern const struct bme280_bus_io bme280_bus_io_i2c; #endif #if defined CONFIG_BME280_TEMP_OVER_1X -#define BME280_TEMP_OVER (1 << 5) +#define BME280_TEMP_OVER (1 << 5) +#define BME280_TEMP_SAMPLE_TIME 2 #elif defined CONFIG_BME280_TEMP_OVER_2X -#define BME280_TEMP_OVER (2 << 5) +#define BME280_TEMP_OVER (2 << 5) +#define BME280_TEMP_SAMPLE_TIME 4 #elif defined CONFIG_BME280_TEMP_OVER_4X -#define BME280_TEMP_OVER (3 << 5) +#define BME280_TEMP_OVER (3 << 5) +#define BME280_TEMP_SAMPLE_TIME 8 #elif defined CONFIG_BME280_TEMP_OVER_8X -#define BME280_TEMP_OVER (4 << 5) +#define BME280_TEMP_OVER (4 << 5) +#define BME280_TEMP_SAMPLE_TIME 16 #elif defined CONFIG_BME280_TEMP_OVER_16X -#define BME280_TEMP_OVER (5 << 5) +#define BME280_TEMP_OVER (5 << 5) +#define BME280_TEMP_SAMPLE_TIME 32 #endif #if defined CONFIG_BME280_PRESS_OVER_1X -#define BME280_PRESS_OVER (1 << 2) +#define BME280_PRESS_OVER (1 << 2) +#define BME280_PRESS_SAMPLE_TIME 2 #elif defined CONFIG_BME280_PRESS_OVER_2X -#define BME280_PRESS_OVER (2 << 2) +#define BME280_PRESS_OVER (2 << 2) +#define BME280_PRESS_SAMPLE_TIME 4 #elif defined CONFIG_BME280_PRESS_OVER_4X -#define BME280_PRESS_OVER (3 << 2) +#define BME280_PRESS_OVER (3 << 2) +#define BME280_PRESS_SAMPLE_TIME 8 #elif defined CONFIG_BME280_PRESS_OVER_8X -#define BME280_PRESS_OVER (4 << 2) +#define BME280_PRESS_OVER (4 << 2) +#define BME280_PRESS_SAMPLE_TIME 16 #elif defined CONFIG_BME280_PRESS_OVER_16X -#define BME280_PRESS_OVER (5 << 2) +#define BME280_PRESS_OVER (5 << 2) +#define BME280_PRESS_SAMPLE_TIME 32 #endif #if defined CONFIG_BME280_HUMIDITY_OVER_1X -#define BME280_HUMIDITY_OVER 1 +#define BME280_HUMIDITY_OVER 1 +#define BME280_HUMIDITY_SAMPLE_TIME 2 #elif defined CONFIG_BME280_HUMIDITY_OVER_2X -#define BME280_HUMIDITY_OVER 2 +#define BME280_HUMIDITY_OVER 2 +#define BME280_HUMIDITY_SAMPLE_TIME 4 #elif defined CONFIG_BME280_HUMIDITY_OVER_4X -#define BME280_HUMIDITY_OVER 3 +#define BME280_HUMIDITY_OVER 3 +#define BME280_HUMIDITY_SAMPLE_TIME 8 #elif defined CONFIG_BME280_HUMIDITY_OVER_8X -#define BME280_HUMIDITY_OVER 4 +#define BME280_HUMIDITY_OVER 4 +#define BME280_HUMIDITY_SAMPLE_TIME 16 #elif defined CONFIG_BME280_HUMIDITY_OVER_16X -#define BME280_HUMIDITY_OVER 5 +#define BME280_HUMIDITY_OVER 5 +#define BME280_HUMIDITY_SAMPLE_TIME 32 #endif #if defined CONFIG_BME280_STANDBY_05MS diff --git a/drivers/sensor/bosch/bme280/bme280_async.c b/drivers/sensor/bosch/bme280/bme280_async.c index 0cf0359b0944f..1ad6e3d22d2cc 100644 --- a/drivers/sensor/bosch/bme280/bme280_async.c +++ b/drivers/sensor/bosch/bme280/bme280_async.c @@ -7,6 +7,7 @@ #include #include +#include #include "bme280.h" @@ -16,6 +17,7 @@ void bme280_submit_sync(struct rtio_iodev_sqe *iodev_sqe) { uint32_t min_buf_len = sizeof(struct bme280_encoded_data); int rc; + uint64_t cycles; uint8_t *buf; uint32_t buf_len; @@ -31,10 +33,17 @@ void bme280_submit_sync(struct rtio_iodev_sqe *iodev_sqe) return; } + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + struct bme280_encoded_data *edata; edata = (struct bme280_encoded_data *)buf; - edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); edata->has_temp = 0; edata->has_humidity = 0; edata->has_press = 0; diff --git a/drivers/sensor/bosch/bmg160/bmg160.c b/drivers/sensor/bosch/bmg160/bmg160.c index da16a6080bdd3..463c3630f61a6 100644 --- a/drivers/sensor/bosch/bmg160/bmg160.c +++ b/drivers/sensor/bosch/bmg160/bmg160.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 * * Datasheet: - * http://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMG160-DS000-09.pdf + * https://web.archive.org/web/20181111220522/https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMG160-DS000-09.pdf */ #define DT_DRV_COMPAT bosch_bmg160 diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel.c b/drivers/sensor/bosch/bmi08x/bmi08x_accel.c index 58f08ead3f7df..4642b41ffa001 100644 --- a/drivers/sensor/bosch/bmi08x/bmi08x_accel.c +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel.c @@ -454,16 +454,41 @@ static int bmi08x_temp_channel_get(const struct device *dev, struct sensor_value { uint16_t temp_raw = 0U; int32_t temp_micro = 0; + int16_t temp_int11 = 0; int ret; ret = bmi08x_accel_word_read(dev, BMI08X_REG_TEMP_MSB, &temp_raw); - if (ret < 0) { + if (!ret) { + temp_int11 = (temp_raw & 0xFF) << 3; + } else { + LOG_ERR("Error reading BMI08X_REG_TEMP_MSB. (err %d)", ret); return ret; } - /* the scale is 1/2^5/LSB = 31250 micro degrees */ - temp_micro = BMI08X_TEMP_OFFSET * 1000000ULL + temp_raw * 31250ULL; + if (temp_raw == 0x80) { + /* temperature invalid */ + LOG_ERR("BMI08X returned invalid temperature."); + return -ENODATA; + } + ret = bmi08x_accel_word_read(dev, BMI08X_REG_TEMP_LSB, &temp_raw); + if (!ret) { + temp_int11 |= (temp_raw & 0xE0) >> 5; + } else { + LOG_ERR("Error reading BMI08X_REG_TEMP_LSB. (err %d)", ret); + return ret; + } + /* + * int11 type ranges in [-1024, 1023] + * the 11st bit declares +/- + * if larger than 1023, it is negative. + */ + if (temp_int11 > 1023) { + temp_int11 -= 2048; + } + /* the value ranges in [-504, 496] */ + /* the scale is 0.125°C/LSB = 125 micro degrees */ + temp_micro = temp_int11 * 125 + 23 * 1000000; val->val1 = temp_micro / 1000000ULL; val->val2 = temp_micro % 1000000ULL; diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel_trigger.c b/drivers/sensor/bosch/bmi08x/bmi08x_accel_trigger.c index 223b3df7f7402..881bc4850c34f 100644 --- a/drivers/sensor/bosch/bmi08x/bmi08x_accel_trigger.c +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel_trigger.c @@ -89,8 +89,8 @@ int bmi08x_trigger_set_acc(const struct device *dev, const struct sensor_trigger struct bmi08x_accel_data *data = dev->data; if ((trig->chan == SENSOR_CHAN_ACCEL_XYZ) && (trig->type == SENSOR_TRIG_DATA_READY)) { - data->handler_drdy_acc = handler; data->drdy_trig_acc = trig; + data->handler_drdy_acc = handler; return 0; } diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_gyro_trigger.c b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_trigger.c index 8be14312abb07..14f67b72997e0 100644 --- a/drivers/sensor/bosch/bmi08x/bmi08x_gyro_trigger.c +++ b/drivers/sensor/bosch/bmi08x/bmi08x_gyro_trigger.c @@ -89,8 +89,8 @@ int bmi08x_trigger_set_gyr(const struct device *dev, const struct sensor_trigger struct bmi08x_gyro_data *data = dev->data; if ((trig->chan == SENSOR_CHAN_GYRO_XYZ) && (trig->type == SENSOR_TRIG_DATA_READY)) { - data->handler_drdy_gyr = handler; data->drdy_trig_gyr = trig; + data->handler_drdy_gyr = handler; return 0; } diff --git a/drivers/sensor/bosch/bmp180/bmp180.c b/drivers/sensor/bosch/bmp180/bmp180.c index f14a15a01b234..c476fb532acf7 100644 --- a/drivers/sensor/bosch/bmp180/bmp180.c +++ b/drivers/sensor/bosch/bmp180/bmp180.c @@ -278,10 +278,16 @@ static void bmp180_compensate_temp(struct bmp180_data *data) { int32_t partial_data1; int32_t partial_data2; + int32_t divisor; struct bmp180_cal_data *cal = &data->cal; partial_data1 = (data->raw_temp - cal->ac6) * cal->ac5 / 0x8000; - partial_data2 = cal->mc * 0x800 / (partial_data1 + cal->md); + + /* Check divisor before division */ + divisor = partial_data1 + cal->md; + __ASSERT(divisor != 0, "divisor is zero: partial_data1=%d, md=%d", partial_data1, cal->md); + + partial_data2 = cal->mc * 0x800 / divisor; /* Store for pressure calculation */ data->comp_temp = (partial_data1 + partial_data2); @@ -327,7 +333,7 @@ static uint32_t bmp180_compensate_press(struct bmp180_data *data) partial_X1 = (cal->ac3 * partial_B6) / 0x2000; partial_X2 = cal->b1 * partial_B6 * (float)(1.0f * partial_B6 / 0x8000000); partial_X3 = (partial_X1 + partial_X2 + 2) / 4; - partial_B4 = (uint64_t)(cal->ac4 * (partial_X3 + 32768)) / 0x8000; + partial_B4 = (uint64_t)(cal->ac4 * ((int64_t)(partial_X3) + 32768)) >> 15; partial_B7 = (uint64_t)(raw_pressure - partial_B3) * (50000 >> data->osr_pressure); comp_press = (uint32_t)(partial_B7 / partial_B4 * 2); diff --git a/drivers/sensor/default_rtio_sensor.c b/drivers/sensor/default_rtio_sensor.c index 123d6b1ff955f..511ad0b6f0020 100644 --- a/drivers/sensor/default_rtio_sensor.c +++ b/drivers/sensor/default_rtio_sensor.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -119,11 +120,21 @@ static void sensor_submit_fallback_sync(struct rtio_iodev_sqe *iodev_sqe) const struct sensor_chan_spec *const channels = cfg->channels; const int num_output_samples = compute_num_samples(channels, cfg->count); uint32_t min_buf_len = compute_min_buf_len(num_output_samples); - uint64_t timestamp_ns = k_ticks_to_ns_floor64(k_uptime_ticks()); - int rc = sensor_sample_fetch(dev); + uint64_t cycles; + int rc; + + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + + uint64_t timestamp_ns = sensor_clock_cycles_to_ns(cycles); uint8_t *buf; uint32_t buf_len; + rc = sensor_sample_fetch(dev); /* Check that the fetch succeeded */ if (rc != 0) { LOG_WRN("Failed to fetch samples"); @@ -318,25 +329,44 @@ static int get_frame_count(const uint8_t *buffer, struct sensor_chan_spec channe switch (channel.chan_type) { case SENSOR_CHAN_ACCEL_XYZ: - channel.chan_type = SENSOR_CHAN_ACCEL_X; - break; case SENSOR_CHAN_GYRO_XYZ: - channel.chan_type = SENSOR_CHAN_GYRO_X; - break; case SENSOR_CHAN_MAGN_XYZ: - channel.chan_type = SENSOR_CHAN_MAGN_X; - break; case SENSOR_CHAN_POS_DXYZ: - channel.chan_type = SENSOR_CHAN_POS_DX; + for (size_t i = 0 ; i < header->num_channels; ++i) { + /* For 3-axis channels, we need to verify we have each individual axis */ + struct sensor_chan_spec channel_x = { + .chan_type = channel.chan_type - 3, + .chan_idx = channel.chan_idx, + }; + struct sensor_chan_spec channel_y = { + .chan_type = channel.chan_type - 2, + .chan_idx = channel.chan_idx, + }; + struct sensor_chan_spec channel_z = { + .chan_type = channel.chan_type - 1, + .chan_idx = channel.chan_idx, + }; + + /** The three axes don't need to be at the beginning of the header, but + * they should be consecutive. + */ + if (((header->num_channels - i) >= 3) && + sensor_chan_spec_eq(header->channels[i], channel_x) && + sensor_chan_spec_eq(header->channels[i + 1], channel_y) && + sensor_chan_spec_eq(header->channels[i + 2], channel_z)) { + *frame_count = 1; + return 0; + } + } break; default: - break; - } - for (size_t i = 0; i < header->num_channels; ++i) { - if (sensor_chan_spec_eq(header->channels[i], channel)) { - *frame_count = 1; - return 0; + for (size_t i = 0; i < header->num_channels; ++i) { + if (sensor_chan_spec_eq(header->channels[i], channel)) { + *frame_count = 1; + return 0; + } } + break; } return -ENOTSUP; @@ -353,21 +383,9 @@ int sensor_natively_supported_channel_size_info(struct sensor_chan_spec channel, } switch (channel.chan_type) { - case SENSOR_CHAN_ACCEL_X: - case SENSOR_CHAN_ACCEL_Y: - case SENSOR_CHAN_ACCEL_Z: case SENSOR_CHAN_ACCEL_XYZ: - case SENSOR_CHAN_GYRO_X: - case SENSOR_CHAN_GYRO_Y: - case SENSOR_CHAN_GYRO_Z: case SENSOR_CHAN_GYRO_XYZ: - case SENSOR_CHAN_MAGN_X: - case SENSOR_CHAN_MAGN_Y: - case SENSOR_CHAN_MAGN_Z: case SENSOR_CHAN_MAGN_XYZ: - case SENSOR_CHAN_POS_DX: - case SENSOR_CHAN_POS_DY: - case SENSOR_CHAN_POS_DZ: case SENSOR_CHAN_POS_DXYZ: *base_size = sizeof(struct sensor_three_axis_data); *frame_size = sizeof(struct sensor_three_axis_sample_data); @@ -480,33 +498,21 @@ static int decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, /* Check for 3d channel mappings */ switch (chan_spec.chan_type) { - case SENSOR_CHAN_ACCEL_X: - case SENSOR_CHAN_ACCEL_Y: - case SENSOR_CHAN_ACCEL_Z: case SENSOR_CHAN_ACCEL_XYZ: count = decode_three_axis(header, q, data_out, SENSOR_CHAN_ACCEL_X, SENSOR_CHAN_ACCEL_Y, SENSOR_CHAN_ACCEL_Z, chan_spec.chan_idx); break; - case SENSOR_CHAN_GYRO_X: - case SENSOR_CHAN_GYRO_Y: - case SENSOR_CHAN_GYRO_Z: case SENSOR_CHAN_GYRO_XYZ: count = decode_three_axis(header, q, data_out, SENSOR_CHAN_GYRO_X, SENSOR_CHAN_GYRO_Y, SENSOR_CHAN_GYRO_Z, chan_spec.chan_idx); break; - case SENSOR_CHAN_MAGN_X: - case SENSOR_CHAN_MAGN_Y: - case SENSOR_CHAN_MAGN_Z: case SENSOR_CHAN_MAGN_XYZ: count = decode_three_axis(header, q, data_out, SENSOR_CHAN_MAGN_X, SENSOR_CHAN_MAGN_Y, SENSOR_CHAN_MAGN_Z, chan_spec.chan_idx); break; - case SENSOR_CHAN_POS_DX: - case SENSOR_CHAN_POS_DY: - case SENSOR_CHAN_POS_DZ: case SENSOR_CHAN_POS_DXYZ: count = decode_three_axis(header, q, data_out, SENSOR_CHAN_POS_DX, SENSOR_CHAN_POS_DY, SENSOR_CHAN_POS_DZ, diff --git a/drivers/sensor/grow_r502a/grow_r502a.c b/drivers/sensor/grow_r502a/grow_r502a.c index fd3d05832f70b..055a4e9d58060 100644 --- a/drivers/sensor/grow_r502a/grow_r502a.c +++ b/drivers/sensor/grow_r502a/grow_r502a.c @@ -101,7 +101,14 @@ static int r502a_validate_rx_packet(union r502a_packet *rx_packet) return -EINVAL; } - cks_start_idx = sys_be16_to_cpu(rx_packet->len) - R502A_CHECKSUM_LEN; + const uint16_t packet_len = sys_be16_to_cpu(rx_packet->len); + + if (packet_len < R502A_CHECKSUM_LEN || packet_len > CONFIG_R502A_DATA_PKT_SIZE) { + LOG_ERR("Invalid packet length %d", packet_len); + return -EINVAL; + } + + cks_start_idx = packet_len - R502A_CHECKSUM_LEN; recv_cks = sys_get_be16(&rx_packet->data[cks_start_idx]); diff --git a/drivers/sensor/maxim/CMakeLists.txt b/drivers/sensor/maxim/CMakeLists.txt index c93ffbb7adab2..d24cacfe8ad62 100644 --- a/drivers/sensor/maxim/CMakeLists.txt +++ b/drivers/sensor/maxim/CMakeLists.txt @@ -12,4 +12,5 @@ add_subdirectory_ifdef(CONFIG_MAX31865 max31865) add_subdirectory_ifdef(CONFIG_MAX31875 max31875) add_subdirectory_ifdef(CONFIG_MAX44009 max44009) add_subdirectory_ifdef(CONFIG_MAX6675 max6675) +add_subdirectory_ifdef(CONFIG_SENSOR_DS3231 ds3231) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/maxim/Kconfig b/drivers/sensor/maxim/Kconfig index ada577b05ad1f..07213c8d1c4da 100644 --- a/drivers/sensor/maxim/Kconfig +++ b/drivers/sensor/maxim/Kconfig @@ -3,6 +3,7 @@ # zephyr-keep-sorted-start source "drivers/sensor/maxim/ds18b20/Kconfig" +source "drivers/sensor/maxim/ds3231/Kconfig" source "drivers/sensor/maxim/max17055/Kconfig" source "drivers/sensor/maxim/max17262/Kconfig" source "drivers/sensor/maxim/max30101/Kconfig" diff --git a/drivers/sensor/maxim/ds3231/CMakeLists.txt b/drivers/sensor/maxim/ds3231/CMakeLists.txt new file mode 100644 index 0000000000000..961780ef64afc --- /dev/null +++ b/drivers/sensor/maxim/ds3231/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Gergo Vari + + +zephyr_library() + +zephyr_library_sources(ds3231.c) diff --git a/drivers/sensor/maxim/ds3231/Kconfig b/drivers/sensor/maxim/ds3231/Kconfig new file mode 100644 index 0000000000000..073d4dccde883 --- /dev/null +++ b/drivers/sensor/maxim/ds3231/Kconfig @@ -0,0 +1,22 @@ +# DS3231 temperature sensor configuration options + +# Copyright (c) 2024 Gergo Vari +# SPDX-License-Identifier: Apache-2.0 + +config SENSOR_DS3231 + bool "DS3231 sensor" + default y + depends on DT_HAS_MAXIM_DS3231_MFD_ENABLED + depends on DT_HAS_MAXIM_DS3231_SENSOR_ENABLED + select I2C + select MFD + select RTIO_WORKQ if SENSOR_ASYNC_API + help + Enable driver for DS3231 I2C-based temperature sensor. + +config SENSOR_DS3231_INIT_PRIORITY + int "DS3231 sensor driver init priority" + default 86 + help + Init priority for the DS3231 sensor driver. It must be + greater than MFD_INIT_PRIORITY. diff --git a/drivers/sensor/maxim/ds3231/ds3231.c b/drivers/sensor/maxim/ds3231/ds3231.c new file mode 100644 index 0000000000000..360d234f1415a --- /dev/null +++ b/drivers/sensor/maxim/ds3231/ds3231.c @@ -0,0 +1,276 @@ +/* ds3231.c - Driver for Maxim DS3231 temperature sensor */ + +/* + * Copyright (c) 2024 Gergo Vari + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include "ds3231.h" + +#include +LOG_MODULE_REGISTER(SENSOR_DS3231, CONFIG_SENSOR_LOG_LEVEL); + +#include + +#define DT_DRV_COMPAT maxim_ds3231_sensor + +struct sensor_ds3231_data { + const struct device *dev; + uint16_t raw_temp; +}; + +struct sensor_ds3231_conf { + const struct device *mfd; +}; + +static inline void sensor_ds3231_temp_from_raw(struct sensor_ds3231_data *data, + struct sensor_value *val) +{ + const uint16_t raw_temp = data->raw_temp; + uint8_t frac = raw_temp & 3; + + val->val1 = (int8_t)(raw_temp & GENMASK(8, 2)) >> 2; + val->val2 = (frac * 25) * pow(10, 4); +} + +int sensor_ds3231_read_temp(const struct device *dev, uint16_t *raw_temp) +{ + const struct sensor_ds3231_conf *config = dev->config; + + uint8_t buf[2]; + int err = mfd_ds3231_i2c_get_registers(config->mfd, DS3231_REG_TEMP_MSB, buf, 2); + *raw_temp = ((uint16_t)((buf[0]) << 2) | (buf[1] >> 6)); + + if (err != 0) { + return err; + } + + return 0; +} + +/* Fetch and Get (will be deprecated) */ + +int sensor_ds3231_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct sensor_ds3231_data *data = dev->data; + int err = sensor_ds3231_read_temp(dev, &(data->raw_temp)); + + if (err != 0) { + LOG_ERR("ds3231 sample fetch failed %d", err); + return err; + } + + return 0; +} + +static int sensor_ds3231_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct sensor_ds3231_data *data = dev->data; + + switch (chan) { + case SENSOR_CHAN_AMBIENT_TEMP: + sensor_ds3231_temp_from_raw(data, val); + break; + default: + return -ENOTSUP; + } + + return 0; +} + +/* Read and Decode */ + +struct sensor_ds3231_header { + uint64_t timestamp; +} __attribute__((__packed__)); + +struct sensor_ds3231_edata { + struct sensor_ds3231_header header; + uint16_t raw_temp; +}; + +void sensor_ds3231_submit_sync(struct rtio_iodev_sqe *iodev_sqe) +{ + uint32_t min_buf_len = sizeof(struct sensor_ds3231_edata); + int rc; + uint8_t *buf; + uint32_t buf_len; + + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + const struct device *dev = cfg->sensor; + const struct sensor_chan_spec *const channels = cfg->channels; + + rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len); + if (rc != 0) { + LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + + struct sensor_ds3231_edata *edata; + + edata = (struct sensor_ds3231_edata *)buf; + + if (channels[0].chan_type != SENSOR_CHAN_AMBIENT_TEMP) { + return; + } + + uint16_t raw_temp; + + rc = sensor_ds3231_read_temp(dev, &raw_temp); + if (rc != 0) { + LOG_ERR("Failed to fetch samples"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + edata->raw_temp = raw_temp; + + rtio_iodev_sqe_ok(iodev_sqe, 0); +} + +void sensor_ds3231_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + struct rtio_work_req *req = rtio_work_req_alloc(); + + if (req == NULL) { + LOG_ERR("RTIO work item allocation failed." + "Consider to increase CONFIG_RTIO_WORKQ_POOL_ITEMS."); + rtio_iodev_sqe_err(iodev_sqe, -ENOMEM); + return; + } + + /* TODO: optimize with new bus shims + * to avoid swapping execution contexts + * for a small register read + */ + rtio_work_req_submit(req, iodev_sqe, sensor_ds3231_submit_sync); +} + +static int sensor_ds3231_decoder_get_frame_count(const uint8_t *buffer, + struct sensor_chan_spec chan_spec, + uint16_t *frame_count) +{ + int err = -ENOTSUP; + + if (chan_spec.chan_idx != 0) { + return err; + } + + switch (chan_spec.chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + *frame_count = 1; + break; + default: + return err; + } + + if (*frame_count > 0) { + err = 0; + } + + return err; +} + +static int sensor_ds3231_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size, + size_t *frame_size) +{ + switch (chan_spec.chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + *base_size = sizeof(struct sensor_q31_sample_data); + *frame_size = sizeof(struct sensor_q31_sample_data); + return 0; + default: + return -ENOTSUP; + } +} + +static int sensor_ds3231_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + if (*fit != 0) { + return 0; + } + + struct sensor_q31_data *out = data_out; + + out->header.reading_count = 1; + + const struct sensor_ds3231_edata *edata = (const struct sensor_ds3231_edata *)buffer; + + switch (chan_spec.chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + out->header.base_timestamp_ns = edata->header.timestamp; + const uint16_t raw_temp = edata->raw_temp; + + out->shift = 8 - 1; + out->readings[0].temperature = (q31_t)raw_temp << (32 - 10); + + break; + default: + return -EINVAL; + } + + *fit = 1; + + return 1; +} + +SENSOR_DECODER_API_DT_DEFINE() = { + .get_frame_count = sensor_ds3231_decoder_get_frame_count, + .get_size_info = sensor_ds3231_decoder_get_size_info, + .decode = sensor_ds3231_decoder_decode, +}; + +int sensor_ds3231_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) +{ + ARG_UNUSED(dev); + *decoder = &SENSOR_DECODER_NAME(); + + return 0; +} + +static int sensor_ds3231_init(const struct device *dev) +{ + const struct sensor_ds3231_conf *config = dev->config; + + if (!device_is_ready(config->mfd)) { + return -ENODEV; + } + + return 0; +} + +static DEVICE_API(sensor, driver_api) = { + .sample_fetch = sensor_ds3231_sample_fetch, + .channel_get = sensor_ds3231_channel_get, +#ifdef CONFIG_SENSOR_ASYNC_API + .submit = sensor_ds3231_submit, + .get_decoder = sensor_ds3231_get_decoder, +#endif +}; + +#define SENSOR_DS3231_DEFINE(inst) \ + static struct sensor_ds3231_data sensor_ds3231_data_##inst; \ + static const struct sensor_ds3231_conf sensor_ds3231_conf_##inst = { \ + .mfd = DEVICE_DT_GET(DT_INST_PARENT(inst))}; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, &sensor_ds3231_init, NULL, &sensor_ds3231_data_##inst, \ + &sensor_ds3231_conf_##inst, POST_KERNEL, \ + CONFIG_SENSOR_DS3231_INIT_PRIORITY, &driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SENSOR_DS3231_DEFINE) diff --git a/drivers/sensor/maxim/ds3231/ds3231.h b/drivers/sensor/maxim/ds3231/ds3231.h new file mode 100644 index 0000000000000..b4452df49cd8f --- /dev/null +++ b/drivers/sensor/maxim/ds3231/ds3231.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Gergo Vari + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_DS3231_DS3231_H_ +#define ZEPHYR_DRIVERS_SENSOR_DS3231_DS3231_H_ + +/* Temperature registers */ +#define DS3231_REG_TEMP_MSB 0x11 +#define DS3231_REG_TEMP_LSB 0x12 + +/* Temperature bitmasks */ +#define DS3231_BITS_TEMP_LSB GENMASK(7, 6) /* fractional portion */ + +#endif diff --git a/drivers/sensor/maxim/max31865/max31865.c b/drivers/sensor/maxim/max31865/max31865.c index f9cf6f0e7dfce..e42992acf746d 100644 --- a/drivers/sensor/maxim/max31865/max31865.c +++ b/drivers/sensor/maxim/max31865/max31865.c @@ -99,9 +99,9 @@ static double calculate_temperature(double resistance, double resistance_0) } resistance /= resistance_0; resistance *= 100.0; - temperature = A[0] + A[1] * resistance + A[2] * pow(resistance, 2) - - A[3] * pow(resistance, 3) - A[4] * pow(resistance, 4) + - A[5] * pow(resistance, 5); + temperature = RTD_C[0] + RTD_C[1] * resistance + RTD_C[2] * pow(resistance, 2) - + RTD_C[3] * pow(resistance, 3) - RTD_C[4] * pow(resistance, 4) + + RTD_C[5] * pow(resistance, 5); return temperature; } diff --git a/drivers/sensor/maxim/max31865/max31865.h b/drivers/sensor/maxim/max31865/max31865.h index 1b8681bf9f8fa..d5279533cb16c 100644 --- a/drivers/sensor/maxim/max31865/max31865.h +++ b/drivers/sensor/maxim/max31865/max31865.h @@ -71,7 +71,7 @@ LOG_MODULE_REGISTER(MAX31865, CONFIG_SENSOR_LOG_LEVEL); * For under zero, taken from * https://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf */ -static const float A[6] = {-242.02, 2.2228, 2.5859e-3, 4.8260e-6, 2.8183e-8, 1.5243e-10}; +static const double RTD_C[6] = {-242.02, 2.2228, 2.5859e-3, 4.8260e-6, 2.8183e-8, 1.5243e-10}; struct max31865_data { double temperature; diff --git a/drivers/sensor/melexis/CMakeLists.txt b/drivers/sensor/melexis/CMakeLists.txt new file mode 100644 index 0000000000000..64debd75720ec --- /dev/null +++ b/drivers/sensor/melexis/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Florian Weber +# SPDX-License-Identifier: Apache-2.0 + +# zephyr-keep-sorted-start +add_subdirectory_ifdef(CONFIG_MLX90394 mlx90394) +# zephyr-keep-sorted-stop diff --git a/drivers/sensor/melexis/Kconfig b/drivers/sensor/melexis/Kconfig new file mode 100644 index 0000000000000..aca3baa8b0507 --- /dev/null +++ b/drivers/sensor/melexis/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Florian Weber +# SPDX-License-Identifier: Apache-2.0 + +# zephyr-keep-sorted-start +source "drivers/sensor/melexis/mlx90394/Kconfig" +# zephyr-keep-sorted-stop diff --git a/drivers/sensor/melexis/mlx90394/CMakeLists.txt b/drivers/sensor/melexis/mlx90394/CMakeLists.txt new file mode 100644 index 0000000000000..800212bb85c43 --- /dev/null +++ b/drivers/sensor/melexis/mlx90394/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) Florian Weber +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(mlx90394.c) +zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API mlx90394_async.c mlx90394_decoder.c) diff --git a/drivers/sensor/melexis/mlx90394/Kconfig b/drivers/sensor/melexis/mlx90394/Kconfig new file mode 100644 index 0000000000000..2fbb670c6e10d --- /dev/null +++ b/drivers/sensor/melexis/mlx90394/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Florian Weber +# SPDX-License-Identifier: Apache-2.0 + + +config MLX90394 + bool "MLX90394 Magnetometer" + default y + depends on DT_HAS_MELEXIS_MLX90394_ENABLED + select I2C + help + Enable driver for MLX90394 magnetometer. diff --git a/drivers/sensor/melexis/mlx90394/mlx90394.c b/drivers/sensor/melexis/mlx90394/mlx90394.c new file mode 100644 index 0000000000000..84e53ac737969 --- /dev/null +++ b/drivers/sensor/melexis/mlx90394/mlx90394.c @@ -0,0 +1,656 @@ +/* + * Copyright (c) 2024 Florian Weber + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT melexis_mlx90394 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mlx90394.h" +#include "mlx90394_reg.h" + +LOG_MODULE_REGISTER(MLX90394, CONFIG_SENSOR_LOG_LEVEL); + +/* + * conversion time of one single axis for different filter orders if osr is enabled the value has + * to be doubled + */ +static const int32_t MLX90394_CONVERSION_TIME_US_AXIS[] = {111, 170, 270, 490, + 910, 1770, 3470, 6890}; + +/* conversion time per axis dependent of filter order */ + +/* + * DSP Time per measurement first index:temperature sensor count ( 0..1 ) second index: + * magnetic axis count (0..3) in us + */ +static const int32_t MLX90394_DSP_TIME_US[2][4] = {{0, 27, 50, 73}, {20, 63, 86, 110}}; + +static void mlx90394_update_measurement_Time_us(struct mlx90394_data *data) +{ + int32_t en_x = FIELD_GET(MLX90394_CTRL1_X_EN, data->ctrl_reg_values.ctrl1); + int32_t en_y = FIELD_GET(MLX90394_CTRL1_Y_EN, data->ctrl_reg_values.ctrl1); + int32_t en_z = FIELD_GET(MLX90394_CTRL1_Z_EN, data->ctrl_reg_values.ctrl1); + int32_t en_temp = FIELD_GET(MLX90394_CTRL4_T_EN, data->ctrl_reg_values.ctrl4); + int32_t filter_hall_xy = + FIELD_GET(MLX90394_CTRL3_DIG_FILT_HALL_XY, data->ctrl_reg_values.ctrl3); + int32_t filter_hall_z = + FIELD_GET(MLX90394_CTRL4_DIG_FILT_HALL_Z, data->ctrl_reg_values.ctrl4); + int32_t filter_temp = FIELD_GET(MLX90394_CTRL3_DIG_FILT_TEMP, data->ctrl_reg_values.ctrl3); + int32_t osr_temp = FIELD_GET(MLX90394_CTRL3_OSR_TEMP, data->ctrl_reg_values.ctrl3); + int32_t osr_hall = FIELD_GET(MLX90394_CTRL3_OSR_HALL, data->ctrl_reg_values.ctrl3); + + int32_t conversion_time_us = + (osr_hall + 1) * ((en_x + en_y) * MLX90394_CONVERSION_TIME_US_AXIS[filter_hall_xy] + + en_z * MLX90394_CONVERSION_TIME_US_AXIS[filter_hall_z]) + + (osr_temp + 1) * en_temp * MLX90394_CONVERSION_TIME_US_AXIS[filter_temp]; + int32_t dsp_time_us = MLX90394_DSP_TIME_US[en_temp][en_x + en_y + en_z]; + + /* + * adding 5% tolerance from datasheet + */ + data->measurement_time_us = (conversion_time_us + dsp_time_us) * 105 / 100; +} + +static void mlx90394_convert_magn(enum mlx90394_reg_config_val config, struct sensor_value *val, + uint8_t sample_l, uint8_t sample_h) +{ + int64_t scale, conv_val; + + if (config == MLX90394_CTRL2_CONFIG_HIGH_SENSITIVITY_LOW_NOISE) { + scale = MLX90394_HIGH_SENSITIVITY_MICRO_GAUSS_PER_BIT; + } else { + scale = MLX90394_HIGH_RANGE_MICRO_GAUSS_PER_BIT; + } + conv_val = (int16_t)((uint16_t)sample_l | (uint16_t)(sample_h << 8)) * scale; + + val->val1 = conv_val / 1000000; /* G */ + val->val2 = conv_val - (val->val1 * 1000000); /* uG */ +} + +static void mlx90394_convert_temp(struct sensor_value *val, uint8_t sample_l, uint8_t sample_h) +{ + int64_t conv_val = sample_l | (sample_h << 8) * MLX90394_MICRO_CELSIUS_PER_BIT; + + val->val1 = conv_val / 1000000; /* C */ + val->val2 = (conv_val - (val->val1 * 1000000)); /* uC */ +} + +/* + * The user has to take care about that the requested channel was fetched before. Else the data will + * be random. Magnetic Flux Density is in Gauss, Temperature in Celsius + */ +static int mlx90394_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct mlx90394_data *data = dev->data; + + switch (chan) { + case SENSOR_CHAN_MAGN_X: { + mlx90394_convert_magn(data->config_val, val, data->sample.x_l, data->sample.x_h); + } break; + case SENSOR_CHAN_MAGN_Y: { + mlx90394_convert_magn(data->config_val, val, data->sample.y_l, data->sample.y_h); + } break; + case SENSOR_CHAN_MAGN_Z: { + mlx90394_convert_magn(data->config_val, val, data->sample.z_l, data->sample.z_h); + } break; + case SENSOR_CHAN_AMBIENT_TEMP: { + mlx90394_convert_temp(val, data->sample.temp_l, data->sample.temp_h); + } break; + case SENSOR_CHAN_MAGN_XYZ: { + mlx90394_convert_magn(data->config_val, val, data->sample.x_l, data->sample.x_h); + mlx90394_convert_magn(data->config_val, val + 1, data->sample.y_l, + data->sample.y_h); + mlx90394_convert_magn(data->config_val, val + 2, data->sample.z_l, + data->sample.z_h); + } break; + case SENSOR_CHAN_ALL: { + mlx90394_convert_magn(data->config_val, val, data->sample.x_l, data->sample.x_h); + mlx90394_convert_magn(data->config_val, val + 1, data->sample.y_l, + data->sample.y_h); + mlx90394_convert_magn(data->config_val, val + 2, data->sample.z_l, + data->sample.z_h); + mlx90394_convert_temp(val + 3, data->sample.temp_l, data->sample.temp_h); + } break; + default: { + LOG_DBG("Invalid channel %d", chan); + return -ENOTSUP; + } + } + return 0; +} + +/** + * update a register on the device and @param old_value as well + */ +static inline int mlx90394_update_register(const struct device *dev, const uint8_t reg_addr, + const uint8_t new_val, uint8_t *old_value) +{ + const struct mlx90394_config *cfg = dev->config; + + if (new_val != *old_value) { + *old_value = new_val; + return i2c_reg_write_byte_dt(&cfg->i2c, reg_addr, new_val); + } + return 0; +} + +static inline int mlx90394_sync_config_val(const struct device *dev) +{ + struct mlx90394_data *data = dev->data; + uint8_t updated_ctrl2; + + updated_ctrl2 = MLX90394_FIELD_MOD(MLX90394_CTRL2_CONFIG, data->config_val, + data->ctrl_reg_values.ctrl2); + + return mlx90394_update_register(dev, MLX90394_REG_CTRL2, updated_ctrl2, + &data->ctrl_reg_values.ctrl2); +} + +static inline int mlx90394_fs_set(const struct device *dev, const struct sensor_value *val) +{ + struct mlx90394_data *data = dev->data; + + /* + * in low current mode, only High Range is possible + */ + if (data->config_val == MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_CURRENT) { + LOG_ERR("different FS values only supported in low noise mode"); + + return -ENOTSUP; + } + + /* if the requested range is greater the driver switches from HIGH_SENSITIVITY to + * HIGH_RANGE + */ + if (val->val1 > MLX90394_ATTR_FS_LOW_G) { + data->config_val = MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_NOISE; + } else { + data->config_val = MLX90394_CTRL2_CONFIG_HIGH_SENSITIVITY_LOW_NOISE; + } + + return mlx90394_sync_config_val(dev); +} + +static inline int mlx90394_fs_get(const struct device *dev, struct sensor_value *val) +{ + struct mlx90394_data *data = dev->data; + + val->val2 = 0; + if (data->config_val == MLX90394_CTRL2_CONFIG_HIGH_SENSITIVITY_LOW_NOISE) { + val->val1 = MLX90394_ATTR_FS_LOW_G; + } else { + val->val1 = MLX90394_ATTR_FS_HIGH_G; + } + + return 0; +} + +static inline int mlx90394_low_noise_set(const struct device *dev, struct sensor_value *val) +{ + struct mlx90394_data *data = dev->data; + + switch (data->config_val) { + case MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_CURRENT: { + if (val->val1) { + data->config_val = MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_NOISE; + + return mlx90394_sync_config_val(dev); + } + } break; + case MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_NOISE: { + if (val->val1 == 0) { + data->config_val = MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_CURRENT; + + return mlx90394_sync_config_val(dev); + } + } break; + case MLX90394_CTRL2_CONFIG_HIGH_SENSITIVITY_LOW_NOISE: { + if (val->val1 == 0) { + LOG_ERR("High Sensitivity only supported in Low-Noise config, therefore " + "changing now to Low-Current config is not possible"); + + return -ENOTSUP; + } + } break; + } + + return 0; +} + +static inline int mlx90394_low_noise_get(const struct device *dev, struct sensor_value *val) +{ + struct mlx90394_data *data = dev->data; + + val->val2 = 0; + if (data->config_val == MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_CURRENT) { + val->val1 = 0; + } else { + val->val1 = 1; + } + + return 0; +} + +/* + * helper function to get/set attributes if set is 0 it will be a get, otherwise is interpreted + * as set + */ +static int mlx90394_attr_helper(const struct device *dev, enum sensor_channel chan, + unsigned int attr, struct sensor_value *val, uint8_t set) +{ + struct mlx90394_data *data = dev->data; + + if (!data->initialized) { + return -ENODEV; + } + + switch (attr) { + case SENSOR_ATTR_FULL_SCALE: { + if (chan != SENSOR_CHAN_MAGN_XYZ) { + return -ENOTSUP; + } + + if (set) { + return mlx90394_fs_set(dev, val); + } else { + return mlx90394_fs_get(dev, val); + } + } break; + + case MLX90394_SENSOR_ATTR_MAGN_LOW_NOISE: { + if (chan != SENSOR_CHAN_MAGN_XYZ) { + return -ENOTSUP; + } + + if (set) { + return mlx90394_low_noise_set(dev, val); + } else { + return mlx90394_low_noise_get(dev, val); + } + } break; + + case MLX90394_SENSOR_ATTR_MAGN_FILTER_XY: { + if (set) { + if (val->val1 > 7 || val->val1 < 0) { + return -EINVAL; + } + + return mlx90394_update_register( + dev, MLX90394_REG_CTRL3, + MLX90394_FIELD_MOD(MLX90394_CTRL3_DIG_FILT_HALL_XY, val->val1, + data->ctrl_reg_values.ctrl3), + &data->ctrl_reg_values.ctrl3); + } else { + val->val1 = FIELD_GET(MLX90394_CTRL3_DIG_FILT_HALL_XY, + data->ctrl_reg_values.ctrl3); + val->val2 = 0; + } + } break; + case MLX90394_SENSOR_ATTR_MAGN_FILTER_Z: { + if (set) { + if (val->val1 > 7 || val->val1 < 0) { + + return -EINVAL; + } + + return mlx90394_update_register( + dev, MLX90394_REG_CTRL4, + MLX90394_FIELD_MOD(MLX90394_CTRL4_DIG_FILT_HALL_Z, val->val1, + data->ctrl_reg_values.ctrl4), + &data->ctrl_reg_values.ctrl4); + } else { + val->val1 = FIELD_GET(MLX90394_CTRL4_DIG_FILT_HALL_Z, + data->ctrl_reg_values.ctrl4); + val->val2 = 0; + } + } break; + case MLX90394_SENSOR_ATTR_MAGN_OSR: { + if (set) { + if (val->val1 > 1 || val->val1 < 0) { + + return -EINVAL; + } + + return mlx90394_update_register( + dev, MLX90394_REG_CTRL3, + MLX90394_FIELD_MOD(MLX90394_CTRL3_OSR_HALL, val->val1, + data->ctrl_reg_values.ctrl3), + &data->ctrl_reg_values.ctrl3); + } else { + val->val1 = FIELD_GET(MLX90394_CTRL3_OSR_HALL, data->ctrl_reg_values.ctrl3); + val->val2 = 0; + } + } break; + case MLX90394_SENSOR_ATTR_TEMP_FILTER: { + if (set) { + if (val->val1 > 7 || val->val1 < 0) { + return -EINVAL; + } + return mlx90394_update_register( + dev, MLX90394_REG_CTRL3, + MLX90394_FIELD_MOD(MLX90394_CTRL3_DIG_FILT_TEMP, val->val1, + data->ctrl_reg_values.ctrl3), + &data->ctrl_reg_values.ctrl3); + } else { + val->val1 = FIELD_GET(MLX90394_CTRL3_DIG_FILT_TEMP, + data->ctrl_reg_values.ctrl3); + val->val2 = 0; + } + } break; + case MLX90394_SENSOR_ATTR_TEMP_OSR: { + if (set) { + if (val->val1 > 1 || val->val1 < 0) { + return -EINVAL; + } + return mlx90394_update_register( + dev, MLX90394_REG_CTRL3, + MLX90394_FIELD_MOD(MLX90394_CTRL3_OSR_TEMP, val->val1, + data->ctrl_reg_values.ctrl3), + &data->ctrl_reg_values.ctrl3); + } else { + val->val1 = FIELD_GET(MLX90394_CTRL3_OSR_TEMP, data->ctrl_reg_values.ctrl3); + val->val2 = 0; + } + } break; + default: { + return -ENOTSUP; + } + } + + return 0; +} +static int mlx90394_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + return mlx90394_attr_helper(dev, chan, (unsigned int)attr, val, 0); +} + +static int mlx90394_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + /* + * must be a copy because val is const + */ + struct sensor_value val_copy = *val; + int rc; + + rc = mlx90394_attr_helper(dev, chan, (unsigned int)attr, &val_copy, 1); + if (rc == 0) { + mlx90394_update_measurement_Time_us(dev->data); + } + + return rc; +} + +static inline int mlx90394_check_who_am_i(const struct i2c_dt_spec *i2c) +{ + uint8_t buffer[2]; + int rc; + + rc = i2c_burst_read_dt(i2c, MLX90394_REG_CID, buffer, ARRAY_SIZE(buffer)); + if (rc != 0) { + LOG_ERR("Failed to read who-am-i register (rc=%d)", rc); + return -EIO; + } + + if (buffer[0] != MLX90394_CID || buffer[1] != MLX90394_DID) { + LOG_ERR("Wrong who-am-i value"); + return -EINVAL; + } + + return 0; +} + +static int mlx90394_write_read_dt(const struct i2c_dt_spec *i2c, uint8_t start_addr, + uint8_t *buffer_write, uint8_t *buffer_read, size_t cnt) +{ + int rc; + + rc = i2c_burst_write_dt(i2c, start_addr, buffer_write, cnt); + if (rc != 0) { + LOG_ERR("Failed to write %d bytes to register %d (rc=%d)", cnt, start_addr, rc); + return -EIO; + } + rc = i2c_burst_read_dt(i2c, start_addr, buffer_read, cnt); + if (rc != 0) { + LOG_ERR("Failed to read %d bytes from register %d (rc=%d)", cnt, start_addr, rc); + return -EIO; + } + + return 0; +} + +int mlx90394_sample_fetch_internal(const struct device *dev, enum sensor_channel chan) +{ + const struct mlx90394_config *cfg = dev->config; + struct mlx90394_data *data = dev->data; + int rc; + + if (!data->initialized) { + return -ENODEV; + } + + rc = i2c_burst_read_dt(&cfg->i2c, MLX90394_REG_STAT1, (uint8_t *)&data->sample, + MLX90394_REG_TH + 1); + if (rc != 0) { + LOG_ERR("Failed to read bytes"); + return rc; + } + + if (FIELD_GET(MLX90394_STAT1_DRDY, data->sample.stat1) != 1) { + LOG_ERR("Data was not ready during fetch. In continues mode consider to " + "adjust " + "sample frequency"); + return -EIO; + } + return 0; +} + +int mlx90394_trigger_measurement_internal(const struct device *dev, enum sensor_channel chan) +{ + const struct mlx90394_config *cfg = dev->config; + struct mlx90394_data *data = dev->data; + int rc; + + if (!data->initialized) { + return -ENODEV; + } + + /* + * set single measurement mode as default if not already done + */ + if (FIELD_GET(MLX90394_CTRL1_MODE, data->ctrl_reg_values.ctrl1) != + MLX90394_CTRL1_MODE_SINGLE) { + data->ctrl_reg_values.ctrl1 = + MLX90394_FIELD_MOD(MLX90394_CTRL1_MODE, MLX90394_CTRL1_MODE_SINGLE, + data->ctrl_reg_values.ctrl1); + } + + /* + * change channel bits and update ctrl4 and the measurement time + * if the channel is different than during the last measurement + */ + if (chan != data->channel) { + switch (chan) { + case SENSOR_CHAN_MAGN_X: { + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_X_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Y_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Z_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl4, MLX90394_CTRL4_T_EN_BIT, 0); + } break; + case SENSOR_CHAN_MAGN_Y: { + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_X_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Y_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Z_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl4, MLX90394_CTRL4_T_EN_BIT, 0); + } break; + case SENSOR_CHAN_MAGN_Z: { + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_X_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Y_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Z_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl4, MLX90394_CTRL4_T_EN_BIT, 0); + } break; + case SENSOR_CHAN_MAGN_XYZ: { + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_X_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Y_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Z_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl4, MLX90394_CTRL4_T_EN_BIT, 0); + } break; + case SENSOR_CHAN_AMBIENT_TEMP: { + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_X_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Y_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Z_EN_BIT, 0); + WRITE_BIT(data->ctrl_reg_values.ctrl4, MLX90394_CTRL4_T_EN_BIT, 1); + } break; + case SENSOR_CHAN_ALL: { + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_X_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Y_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl1, MLX90394_CTRL1_Z_EN_BIT, 1); + WRITE_BIT(data->ctrl_reg_values.ctrl4, MLX90394_CTRL4_T_EN_BIT, 1); + } break; + default: { + return -ENOTSUP; + } + } + rc = i2c_reg_write_byte_dt(&cfg->i2c, MLX90394_REG_CTRL4, + data->ctrl_reg_values.ctrl4); + if (rc != 0) { + LOG_ERR("Failed to write ctrl4"); + return rc; + } + + data->channel = chan; + mlx90394_update_measurement_Time_us(data); + } + + rc = i2c_reg_write_byte_dt(&cfg->i2c, MLX90394_REG_CTRL1, data->ctrl_reg_values.ctrl1); + if (rc != 0) { + LOG_ERR("Failed to write ctrl1"); + } + + return rc; +} + +static int mlx90394_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + int rc; + struct mlx90394_data *data = dev->data; + + rc = mlx90394_trigger_measurement_internal(dev, chan); + if (rc != 0) { + return rc; + } + + k_usleep(data->measurement_time_us); + rc = mlx90394_sample_fetch_internal(dev, chan); + + return rc; +} + +static int mlx90394_init(const struct device *dev) +{ + const struct mlx90394_config *cfg = dev->config; + struct mlx90394_data *data = dev->data; + int rc; + + if (!i2c_is_ready_dt(&cfg->i2c)) { + LOG_ERR("I2C bus device not ready"); + return -ENODEV; + } + + /* + * Soft reset the chip + */ + rc = i2c_reg_write_byte_dt(&cfg->i2c, MLX90394_REG_RST, MLX90394_RST); + if (rc != 0) { + LOG_ERR("Failed to soft reset"); + return -EIO; + } + k_usleep(MLX90394_STARTUP_TIME_US); + + /* + * check chip ID + */ + rc = mlx90394_check_who_am_i(&cfg->i2c); + if (rc != 0) { + return rc; + } + + /* + * set all to default and read the settings back + */ + rc = mlx90394_write_read_dt(&cfg->i2c, MLX90394_REG_CTRL1, + (uint8_t *)&data->ctrl_reg_values.ctrl1, + (uint8_t *)&data->ctrl_reg_values.ctrl1, 2); + if (rc != 0) { + return rc; + } + + rc = mlx90394_write_read_dt(&cfg->i2c, MLX90394_REG_CTRL3, + (uint8_t *)&data->ctrl_reg_values.ctrl3, + (uint8_t *)&data->ctrl_reg_values.ctrl3, 2); + if (rc != 0) { + return rc; + } + + mlx90394_update_measurement_Time_us(data); + +#ifdef CONFIG_SENSOR_ASYNC_API + data->dev = dev; + /* + * init work for fetching after measurement has completed + */ + k_work_init_delayable(&data->async_fetch_work, mlx90394_async_fetch); +#endif + data->initialized = true; + return 0; +} + +static DEVICE_API(sensor, mlx90394_driver_api) = { + .sample_fetch = mlx90394_sample_fetch, + .channel_get = mlx90394_channel_get, + .attr_get = mlx90394_attr_get, + .attr_set = mlx90394_attr_set, +#ifdef CONFIG_SENSOR_ASYNC_API + .submit = mlx90394_submit, + .get_decoder = mlx90394_get_decoder, +#endif +}; + +#define MLX90394_DEFINE(inst) \ + static struct mlx90394_data mlx90394_data_##inst = { \ + .sample = {.x_l = 0, \ + .x_h = 0, \ + .y_l = 0, \ + .y_h = 0, \ + .z_l = 0, \ + .z_h = 0, \ + .temp_l = 0, \ + .temp_h = 0}, \ + .channel = SENSOR_CHAN_MAGN_XYZ, \ + .config_val = FIELD_GET(MLX90394_CTRL2_CONFIG, MLX90394_CTRL2_DEFAULT), \ + .measurement_time_us = 0, \ + .ctrl_reg_values = {.ctrl1 = MLX90394_CTRL1_DEFAULT, \ + .ctrl2 = MLX90394_CTRL2_DEFAULT, \ + .ctrl3 = MLX90394_CTRL3_DEFAULT, \ + .ctrl4 = MLX90394_CTRL4_DEFAULT}, \ + .initialized = false}; \ + static const struct mlx90394_config mlx90394_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst)}; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, mlx90394_init, NULL, &mlx90394_data_##inst, \ + &mlx90394_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &mlx90394_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MLX90394_DEFINE) diff --git a/drivers/sensor/melexis/mlx90394/mlx90394.h b/drivers/sensor/melexis/mlx90394/mlx90394.h new file mode 100644 index 0000000000000..3c61e1f506922 --- /dev/null +++ b/drivers/sensor/melexis/mlx90394/mlx90394.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 Florian Weber + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_MLX90394_MLX90394_H_ +#define ZEPHYR_DRIVERS_SENSOR_MLX90394_MLX90394_H_ + +#include +#include +#include +#include + +#include "mlx90394_reg.h" + +/* + * Time it takes to start-up the device and switch to powerdown mode (after powercycle or soft + * reset) + */ +#define MLX90394_STARTUP_TIME_US 400 + +/* Conversion values */ +#define MLX90394_HIGH_RANGE_MICRO_GAUSS_PER_BIT INT64_C(15000) +#define MLX90394_HIGH_SENSITIVITY_MICRO_GAUSS_PER_BIT INT64_C(1500) +#define MLX90394_MICRO_CELSIUS_PER_BIT INT64_C(20000) + +/* values for setting SENSOR_ATTR_FULL_SCALE */ +#define MLX90394_ATTR_FS_HIGH_G INT32_C(500) +#define MLX90394_ATTR_FS_LOW_G INT32_C(50) + +struct mlx90394_data { + struct __packed { + uint8_t stat1; + uint8_t x_l; + uint8_t x_h; + uint8_t y_l; + uint8_t y_h; + uint8_t z_l; + uint8_t z_h; + uint8_t stat2; + uint8_t temp_l; + uint8_t temp_h; + } sample; + enum sensor_channel channel; + enum mlx90394_reg_config_val config_val; + int32_t measurement_time_us; + struct __packed { + uint8_t ctrl1; + uint8_t ctrl2; + uint8_t ctrl3; + uint8_t ctrl4; + } ctrl_reg_values; + bool initialized; +#ifdef CONFIG_SENSOR_ASYNC_API + struct { + struct rtio_iodev_sqe *iodev_sqe; + uint64_t timestamp; + enum mlx90394_reg_config_val config_val; + } work_ctx; + struct k_work_delayable async_fetch_work; + const struct device *dev; +#endif +}; + +struct mlx90394_config { + struct i2c_dt_spec i2c; +}; + +int mlx90394_sample_fetch_internal(const struct device *dev, enum sensor_channel chan); +int mlx90394_trigger_measurement_internal(const struct device *dev, enum sensor_channel chan); + +/* RTIO types and defines */ +#ifdef CONFIG_SENSOR_ASYNC_API + +/* shift value to use. */ +#define MLX90394_SHIFT_MAGN_HIGH_SENSITIVITY (6) +#define MLX90394_SHIFT_MAGN_HIGH_RANGE (9) +#define MLX90394_SHIFT_TEMP (10) + +void mlx90394_async_fetch(struct k_work *work); + +struct mlx90394_decoder_header { + uint64_t timestamp; + enum mlx90394_reg_config_val config_val; +}; + +struct mlx90394_encoded_data { + struct mlx90394_decoder_header header; + int16_t readings[4]; +}; + +int mlx90394_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); +void mlx90394_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); +#endif + +#endif /* ZEPHYR_DRIVERS_SENSOR_MLX90394_MLX90394_H_ */ diff --git a/drivers/sensor/melexis/mlx90394/mlx90394_async.c b/drivers/sensor/melexis/mlx90394/mlx90394_async.c new file mode 100644 index 0000000000000..f3309da68deab --- /dev/null +++ b/drivers/sensor/melexis/mlx90394/mlx90394_async.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2024 Florian Weber + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT melexis_mlx90394 + +#include +#include +#include +#include +#include + +#include "mlx90394.h" +#include "mlx90394_reg.h" + +#include + +LOG_MODULE_DECLARE(MLX90394, CONFIG_SENSOR_LOG_LEVEL); + +void mlx90394_async_fetch(struct k_work *work) +{ + int rc; + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct mlx90394_data *data = CONTAINER_OF(dwork, struct mlx90394_data, async_fetch_work); + const struct device *dev = data->dev; + const struct sensor_read_config *cfg = + data->work_ctx.iodev_sqe->sqe.iodev->data; + struct mlx90394_encoded_data *edata; + uint32_t buf_len = sizeof(struct mlx90394_encoded_data); + uint8_t *buf; + + rc = mlx90394_sample_fetch_internal(dev, cfg->channels->chan_type); + if (rc != 0) { + LOG_ERR("Failed to fetch samples"); + rtio_iodev_sqe_err(data->work_ctx.iodev_sqe, rc); + return; + } + /* Get the buffer for the frame, it may be allocated dynamically by the rtio context */ + rc = rtio_sqe_rx_buf(data->work_ctx.iodev_sqe, buf_len, buf_len, &buf, &buf_len); + if (rc != 0) { + LOG_ERR("Failed to get a read buffer of size %u bytes", buf_len); + rtio_iodev_sqe_err(data->work_ctx.iodev_sqe, rc); + return; + } + + edata = (struct mlx90394_encoded_data *)buf; + + /* buffered from submit */ + edata->header.timestamp = data->work_ctx.timestamp; + edata->header.config_val = data->work_ctx.config_val; + + switch (cfg->channels->chan_type) { + case SENSOR_CHAN_MAGN_X: { + edata->readings[0] = + (int16_t)((uint16_t)data->sample.x_l | (uint16_t)(data->sample.x_h << 8)); + } break; + case SENSOR_CHAN_MAGN_Y: { + edata->readings[1] = + (int16_t)((uint16_t)data->sample.y_l | (uint16_t)(data->sample.y_h << 8)); + } break; + case SENSOR_CHAN_MAGN_Z: { + edata->readings[2] = + (int16_t)((uint16_t)data->sample.z_l | (uint16_t)(data->sample.z_h << 8)); + } break; + case SENSOR_CHAN_AMBIENT_TEMP: { + edata->readings[3] = (int16_t)((uint16_t)data->sample.temp_l | + (uint16_t)(data->sample.temp_h << 8)); + } break; + case SENSOR_CHAN_MAGN_XYZ: { + edata->readings[0] = + (int16_t)((uint16_t)data->sample.x_l | (uint16_t)(data->sample.x_h << 8)); + edata->readings[1] = + (int16_t)((uint16_t)data->sample.y_l | (uint16_t)(data->sample.y_h << 8)); + edata->readings[2] = + (int16_t)((uint16_t)data->sample.z_l | (uint16_t)(data->sample.z_h << 8)); + } break; + case SENSOR_CHAN_ALL: { + edata->readings[0] = + (int16_t)((uint16_t)data->sample.x_l | (uint16_t)(data->sample.x_h << 8)); + edata->readings[1] = + (int16_t)((uint16_t)data->sample.y_l | (uint16_t)(data->sample.y_h << 8)); + edata->readings[2] = + (int16_t)((uint16_t)data->sample.z_l | (uint16_t)(data->sample.z_h << 8)); + edata->readings[3] = (int16_t)((uint16_t)data->sample.temp_l | + (uint16_t)(data->sample.temp_h << 8)); + } break; + default: { + LOG_DBG("Invalid channel %d", cfg->channels->chan_type); + rtio_iodev_sqe_err(data->work_ctx.iodev_sqe, -ENOTSUP); + return; + } + } + rtio_iodev_sqe_ok(data->work_ctx.iodev_sqe, 0); +} + +void mlx90394_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + int rc; + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + struct mlx90394_data *data = dev->data; + uint64_t cycles; + + rc = mlx90394_trigger_measurement_internal(dev, cfg->channels->chan_type); + if (rc != 0) { + LOG_ERR("Failed to trigger measurement"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + + /* save information for the work item */ + data->work_ctx.timestamp = sensor_clock_cycles_to_ns(cycles); + data->work_ctx.iodev_sqe = iodev_sqe; + data->work_ctx.config_val = data->config_val; + + /* schedule work to read out sensor and inform the executor about completion with success */ + k_work_schedule(&data->async_fetch_work, K_USEC(data->measurement_time_us)); +} diff --git a/drivers/sensor/melexis/mlx90394/mlx90394_decoder.c b/drivers/sensor/melexis/mlx90394/mlx90394_decoder.c new file mode 100644 index 0000000000000..46365f7dbd438 --- /dev/null +++ b/drivers/sensor/melexis/mlx90394/mlx90394_decoder.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2024 Florian Weber + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mlx90394.h" +#include + +#define DT_DRV_COMPAT melexis_mlx90394 + +static int mlx90394_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec channel, + uint16_t *frame_count) +{ + ARG_UNUSED(buffer); + ARG_UNUSED(channel); + + /* This sensor lacks a FIFO; there will always only be one frame at a time. */ + *frame_count = 1; + return 0; +} + +static int mlx90394_decoder_get_size_info(struct sensor_chan_spec channel, size_t *base_size, + size_t *frame_size) +{ + switch (channel.chan_type) { + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_MAGN_Z: + case SENSOR_CHAN_MAGN_XYZ: { + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + } break; + case SENSOR_CHAN_AMBIENT_TEMP: { + *base_size = sizeof(struct sensor_q31_data); + *frame_size = sizeof(struct sensor_q31_sample_data); + } break; + default: + return -ENOTSUP; + } + return 0; +} + +static int mlx90394_convert_raw_magn_to_q31(int16_t reading, q31_t *out, + const enum mlx90394_reg_config_val config_val) +{ + int64_t intermediate; + + if (config_val == MLX90394_CTRL2_CONFIG_HIGH_SENSITIVITY_LOW_NOISE) { + intermediate = ((int64_t)reading * MLX90394_HIGH_SENSITIVITY_MICRO_GAUSS_PER_BIT) * + ((int64_t)INT32_MAX + 1) / + ((1 << MLX90394_SHIFT_MAGN_HIGH_SENSITIVITY) * INT64_C(1000000)); + } else { + intermediate = ((int64_t)reading * MLX90394_HIGH_RANGE_MICRO_GAUSS_PER_BIT) * + ((int64_t)INT32_MAX + 1) / + ((1 << MLX90394_SHIFT_MAGN_HIGH_RANGE) * INT64_C(1000000)); + } + + *out = CLAMP(intermediate, INT32_MIN, INT32_MAX); + return 0; +} +static int mlx90394_convert_raw_temp_to_q31(int16_t reading, q31_t *out) +{ + + int64_t intermediate = ((int64_t)reading * MLX90394_MICRO_CELSIUS_PER_BIT) * + ((int64_t)INT32_MAX + 1) / + ((1 << MLX90394_SHIFT_TEMP) * INT64_C(1000000)); + + *out = CLAMP(intermediate, INT32_MIN, INT32_MAX); + return 0; +} + +static int mlx90394_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec channel, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + const struct mlx90394_encoded_data *edata = (const struct mlx90394_encoded_data *)buffer; + + if (*fit != 0) { + return 0; + } + + switch (channel.chan_type) { + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_MAGN_Z: + case SENSOR_CHAN_MAGN_XYZ: { + struct sensor_three_axis_data *out = data_out; + + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + if (edata->header.config_val == MLX90394_CTRL2_CONFIG_HIGH_SENSITIVITY_LOW_NOISE) { + out->shift = MLX90394_SHIFT_MAGN_HIGH_SENSITIVITY; + } else { + out->shift = MLX90394_SHIFT_MAGN_HIGH_RANGE; + } + + mlx90394_convert_raw_magn_to_q31(edata->readings[0], &out->readings[0].x, + edata->header.config_val); + mlx90394_convert_raw_magn_to_q31(edata->readings[1], &out->readings[0].y, + edata->header.config_val); + mlx90394_convert_raw_magn_to_q31(edata->readings[2], &out->readings[0].z, + edata->header.config_val); + *fit = 1; + } break; + case SENSOR_CHAN_AMBIENT_TEMP: { + struct sensor_q31_data *out = data_out; + + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + out->shift = MLX90394_SHIFT_TEMP; + mlx90394_convert_raw_temp_to_q31(edata->readings[3], &out->readings[0].temperature); + *fit = 1; + } break; + default: + return -ENOTSUP; + } + return 1; +} + +SENSOR_DECODER_API_DT_DEFINE() = { + .get_frame_count = mlx90394_decoder_get_frame_count, + .get_size_info = mlx90394_decoder_get_size_info, + .decode = mlx90394_decoder_decode, +}; + +int mlx90394_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) +{ + ARG_UNUSED(dev); + *decoder = &SENSOR_DECODER_NAME(); + + return 0; +} diff --git a/drivers/sensor/melexis/mlx90394/mlx90394_reg.h b/drivers/sensor/melexis/mlx90394/mlx90394_reg.h new file mode 100644 index 0000000000000..5ad185cf2510d --- /dev/null +++ b/drivers/sensor/melexis/mlx90394/mlx90394_reg.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2024 Florian Weber + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_MLX90394_MLX90394_REG_H +#define ZEPHYR_DRIVERS_SENSOR_MLX90394_MLX90394_REG_H + +#include +/* REGISTERS */ +/* Status and measurent output */ +#define MLX90394_REG_STAT1 0x00 +#define MLX90394_REG_BXL 0x01 +#define MLX90394_REG_BXH 0x02 +#define MLX90394_REG_BYL 0x03 +#define MLX90394_REG_BYH 0x04 +#define MLX90394_REG_BZL 0x05 +#define MLX90394_REG_BZH 0x06 +#define MLX90394_REG_STAT2 0x07 +#define MLX90394_REG_TL 0x08 +#define MLX90394_REG_TH 0x09 + +/* Who Am I registers */ +#define MLX90394_REG_CID 0x0A +#define MLX90394_REG_DID 0x0B + +/* Control registers */ +#define MLX90394_REG_CTRL1 0x0E +#define MLX90394_REG_CTRL2 0x0F +#define MLX90394_REG_CTRL3 0x14 +#define MLX90394_REG_CTRL4 0x15 + +/* Reset register */ +#define MLX90394_REG_RST 0x11 + +/* Wake On Change registers */ +#define MLX90394_REG_WOC_XL 0x58 +#define MLX90394_REG_WOC_XH 0x59 +#define MLX90394_REG_WOC_YL 0x5A +#define MLX90394_REG_WOC_YH 0x5B +#define MLX90394_REG_WOC_ZL 0x5C +#define MLX90394_REG_WOC_ZH 0x5D + +/* VALUES */ +/* STAT1 values RO */ +#define MLX90394_STAT1_DRDY BIT(0) +#define MLX90394_STAT1_DOR BIT(3) +#define MLX90394_STAT1_RT BIT(3) +#define MLX90394_STAT1_INT BIT(4) +#define MLX90394_STAT1_DEFAULT (MLX90394_STAT1_RT) + +/* STAT2 values RO */ +#define MLX90394_STAT2_HOVF_X BIT(0) +#define MLX90394_STAT2_HOVF_Y BIT(1) +#define MLX90394_STAT2_HOVF_Z BIT(2) +#define MLX90394_STAT2_DOR BIT(3) +#define MLX90394_STAT2_DEFAULT 0 + +/* Who-I-Am register values RO */ +#define MLX90394_CID 0x94 +#define MLX90394_DID 0xaa + +/* Write this value to reset Register soft resets the chip RW */ +#define MLX90394_RST 0x06 + +/* CTRL1 values RW */ +#define MLX90394_CTRL1_X_EN_BIT 4 +#define MLX90394_CTRL1_Y_EN_BIT 5 +#define MLX90394_CTRL1_Z_EN_BIT 6 +#define MLX90394_CTRL1_MODE GENMASK(3, 0) +#define MLX90394_CTRL1_MODE_SINGLE 1 +#define MLX90394_CTRL1_X_EN BIT(MLX90394_CTRL1_X_EN_BIT) +#define MLX90394_CTRL1_Y_EN BIT(MLX90394_CTRL1_Y_EN_BIT) +#define MLX90394_CTRL1_Z_EN BIT(MLX90394_CTRL1_Z_EN_BIT) +#define MLX90394_CTRL1_SWOK BIT(7) +#define MLX90394_CTRL1_PREP(MODE, X_EN, Y_EN, Z_EN, SWOK) \ + (FIELD_PREP(MLX90394_CTRL1_MODE, MODE) | FIELD_PREP(MLX90394_CTRL1_X_EN, X_EN) | \ + FIELD_PREP(MLX90394_CTRL1_Y_EN, Y_EN) | FIELD_PREP(MLX90394_CTRL1_Z_EN, Z_EN) | \ + FIELD_PREP(MLX90394_CTRL1_SWOK, SWOK)) +#define MLX90394_CTRL1_DEFAULT MLX90394_CTRL1_PREP(0, 1, 1, 1, 0) + +/* CTRL2 values RW */ +enum mlx90394_reg_config_val { + MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_CURRENT = 0, + MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_NOISE, + MLX90394_CTRL2_CONFIG_HIGH_SENSITIVITY_LOW_NOISE +}; +#define MLX90394_CTRL2_WOC_MODE GENMASK(1, 0) +#define MLX90394_CTRL2_INTREPB BIT(2) +#define MLX90394_CTRL2_INTB_SCL_B BIT(3) +#define MLX90394_CTRL2_INTDUR GENMASK(5, 4) +#define MLX90394_CTRL2_CONFIG GENMASK(7, 6) +#define MLX90394_CTRL2_PREP(WOC_MODE, INTREPB, INTB_SCL_B, INTDUR, CONFIG) \ + (FIELD_PREP(MLX90394_CTRL2_WOC_MODE, WOC_MODE) | \ + FIELD_PREP(MLX90394_CTRL2_INTREPB, INTREPB) | \ + FIELD_PREP(MLX90394_CTRL2_INTB_SCL_B, INTB_SCL_B) | \ + FIELD_PREP(MLX90394_CTRL2_INTDUR, INTDUR) | FIELD_PREP(MLX90394_CTRL2_CONFIG, CONFIG)) +#define MLX90394_CTRL2_DEFAULT \ + MLX90394_CTRL2_PREP(0, 0, 1, 0, MLX90394_CTRL2_CONFIG_HIGH_RANGE_LOW_NOISE) + +/* CTRL3 values RW */ +#define MLX90394_CTRL3_DIG_FILT_TEMP GENMASK(2, 0) +#define MLX90394_CTRL3_DIG_FILT_HALL_XY GENMASK(5, 3) +#define MLX90394_CTRL3_OSR_TEMP BIT(6) +#define MLX90394_CTRL3_OSR_HALL BIT(7) +#define MLX90394_CTRL3_PREP(DIG_FILT_TEMP, DIG_FILT_HALL_XY, OSR_TEMP, OSR_HALL) \ + (FIELD_PREP(MLX90394_CTRL3_DIG_FILT_TEMP, DIG_FILT_TEMP) | \ + FIELD_PREP(MLX90394_CTRL3_DIG_FILT_HALL_XY, DIG_FILT_HALL_XY) | \ + FIELD_PREP(MLX90394_CTRL3_OSR_TEMP, OSR_TEMP) | \ + FIELD_PREP(MLX90394_CTRL3_OSR_HALL, OSR_HALL)) +#define MLX90394_CTRL3_DEFAULT MLX90394_CTRL3_PREP(1, 4, 1, 1) + +/* CTRL4 values RW BIT(6) has to be always 0 so it is not included here */ +#define MLX90394_CTRL4_T_EN_BIT 5 +#define MLX90394_CTRL4_DIG_FILT_HALL_Z GENMASK(2, 0) +#define MLX90394_CTRL4_DRDY_EN BIT(3) +#define MLX90394_CTRL4_T_EN BIT(MLX90394_CTRL4_T_EN_BIT) +#define MLX90394_CTRL4_PREP(DIG_FILT_HALL_Z, DRDY_EN, T_EN) \ + (FIELD_PREP(MLX90394_CTRL4_DIG_FILT_HALL_Z, DIG_FILT_HALL_Z) | \ + FIELD_PREP(MLX90394_CTRL4_DRDY_EN, DRDY_EN) | FIELD_PREP(MLX90394_CTRL4_T_EN, T_EN) | \ + BIT(4) | BIT(7)) +#define MLX90394_CTRL4_DEFAULT MLX90394_CTRL4_PREP(5, 0, 0) + +/* helper function to modify only one field */ +#define MLX90394_FIELD_MOD(mask, new_field_val, val) \ + ((val & ~mask) | FIELD_PREP(mask, new_field_val)) + +#endif /* ZEPHYR_DRIVERS_SENSOR_MLX90394_MLX90394_REG_H */ diff --git a/drivers/sensor/memsic/mmc56x3/mmc56x3_async.c b/drivers/sensor/memsic/mmc56x3/mmc56x3_async.c index 332327b28c261..63b8e93189973 100644 --- a/drivers/sensor/memsic/mmc56x3/mmc56x3_async.c +++ b/drivers/sensor/memsic/mmc56x3/mmc56x3_async.c @@ -5,6 +5,7 @@ #include #include +#include #include "mmc56x3.h" @@ -16,6 +17,7 @@ void mmc56x3_submit_sync(struct rtio_iodev_sqe *iodev_sqe) int rc; uint8_t *buf; uint32_t buf_len; + uint64_t cycles; const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; const struct device *dev = cfg->sensor; @@ -29,10 +31,17 @@ void mmc56x3_submit_sync(struct rtio_iodev_sqe *iodev_sqe) return; } + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + struct mmc56x3_encoded_data *edata; edata = (struct mmc56x3_encoded_data *)buf; - edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); edata->has_temp = 0; edata->has_magn_x = 0; edata->has_magn_y = 0; @@ -53,9 +62,13 @@ void mmc56x3_submit_sync(struct rtio_iodev_sqe *iodev_sqe) case SENSOR_CHAN_MAGN_Z: edata->has_magn_z = 1; break; + case SENSOR_CHAN_MAGN_XYZ: + edata->has_magn_x = 1; + edata->has_magn_y = 1; + edata->has_magn_z = 1; + break; case SENSOR_CHAN_ALL: edata->has_temp = 1; - case SENSOR_CHAN_MAGN_XYZ: edata->has_magn_x = 1; edata->has_magn_y = 1; edata->has_magn_z = 1; diff --git a/drivers/sensor/memsic/mmc56x3/mmc56x3_decoder.c b/drivers/sensor/memsic/mmc56x3/mmc56x3_decoder.c index 830ed31d0c1a2..f0b6922763fea 100644 --- a/drivers/sensor/memsic/mmc56x3/mmc56x3_decoder.c +++ b/drivers/sensor/memsic/mmc56x3/mmc56x3_decoder.c @@ -99,6 +99,7 @@ static int mmc56x3_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec } else { return -ENODATA; } + break; case SENSOR_CHAN_MAGN_Y: if (edata->has_magn_y) { struct sensor_q31_data *out = data_out; @@ -110,6 +111,7 @@ static int mmc56x3_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec } else { return -ENODATA; } + break; case SENSOR_CHAN_MAGN_Z: if (edata->has_magn_z) { struct sensor_q31_data *out = data_out; @@ -121,6 +123,7 @@ static int mmc56x3_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec } else { return -ENODATA; } + break; case SENSOR_CHAN_MAGN_XYZ: { if (edata->has_magn_x && edata->has_magn_y && edata->has_magn_z) { struct sensor_three_axis_data *out_3 = data_out; diff --git a/drivers/sensor/nordic/npm1300_charger/npm1300_charger.c b/drivers/sensor/nordic/npm1300_charger/npm1300_charger.c index f772494915ce8..eb49859f3e819 100644 --- a/drivers/sensor/nordic/npm1300_charger/npm1300_charger.c +++ b/drivers/sensor/nordic/npm1300_charger/npm1300_charger.c @@ -18,6 +18,7 @@ struct npm1300_charger_config { int32_t term_warm_microvolt; int32_t current_microamp; int32_t dischg_limit_microamp; + uint8_t dischg_limit_idx; int32_t vbus_limit_microamp; int32_t temp_thresholds[4U]; int32_t dietemp_thresholds[2U]; @@ -142,8 +143,8 @@ static const struct linear_range charger_volt_ranges[] = { /* Linear range for charger current */ static const struct linear_range charger_current_range = LINEAR_RANGE_INIT(32000, 2000, 16U, 400U); -/* Linear range for Discharge limit */ -static const struct linear_range discharge_limit_range = LINEAR_RANGE_INIT(268090, 3230, 83U, 415U); +/* Allowed values for discharge limit */ +static const uint16_t discharge_limits[] = {84U, 415U}; /* Linear range for vbusin current limit */ static const struct linear_range vbus_current_ranges[] = { @@ -197,7 +198,7 @@ static void calc_current(const struct npm1300_charger_config *const config, switch (data->ibat_stat) { case IBAT_STAT_DISCHARGE: - full_scale_ma = config->dischg_limit_microamp / 1000; + full_scale_ma = config->dischg_limit_microamp / 893; break; case IBAT_STAT_CHARGE_TRICKLE: /* Fallthrough */ @@ -563,16 +564,10 @@ int npm1300_charger_init(const struct device *dev) return ret; } - /* Set discharge limit, allow rounding down to closest value */ - ret = linear_range_get_win_index(&discharge_limit_range, - config->dischg_limit_microamp - discharge_limit_range.step, - config->dischg_limit_microamp, &idx); - if (ret == -EINVAL) { - return ret; - } - - ret = mfd_npm1300_reg_write2(config->mfd, CHGR_BASE, CHGR_OFFSET_ISET_DISCHG, idx / 2U, - idx & 1U); + /* Set discharge limit */ + ret = mfd_npm1300_reg_write2(config->mfd, CHGR_BASE, CHGR_OFFSET_ISET_DISCHG, + discharge_limits[config->dischg_limit_idx] / 2U, + discharge_limits[config->dischg_limit_idx] & 1U); if (ret != 0) { return ret; } @@ -669,6 +664,8 @@ static DEVICE_API(sensor, npm1300_charger_battery_driver_api) = { }; #define NPM1300_CHARGER_INIT(n) \ + BUILD_ASSERT(DT_INST_ENUM_IDX(n, dischg_limit_microamp) < ARRAY_SIZE(discharge_limits)); \ + \ static struct npm1300_charger_data npm1300_charger_data_##n; \ \ static const struct npm1300_charger_config npm1300_charger_config_##n = { \ @@ -678,6 +675,7 @@ static DEVICE_API(sensor, npm1300_charger_battery_driver_api) = { DT_INST_PROP_OR(n, term_warm_microvolt, DT_INST_PROP(n, term_microvolt)), \ .current_microamp = DT_INST_PROP(n, current_microamp), \ .dischg_limit_microamp = DT_INST_PROP(n, dischg_limit_microamp), \ + .dischg_limit_idx = DT_INST_ENUM_IDX(n, dischg_limit_microamp), \ .vbus_limit_microamp = DT_INST_PROP(n, vbus_limit_microamp), \ .thermistor_ohms = DT_INST_PROP(n, thermistor_ohms), \ .thermistor_idx = DT_INST_ENUM_IDX(n, thermistor_ohms), \ diff --git a/drivers/sensor/nxp/fxls8974/fxls8974.c b/drivers/sensor/nxp/fxls8974/fxls8974.c index bbe602a76d379..708bfe9a1784e 100644 --- a/drivers/sensor/nxp/fxls8974/fxls8974.c +++ b/drivers/sensor/nxp/fxls8974/fxls8974.c @@ -379,9 +379,7 @@ static int fxls8974_channel_get(const struct device *dev, val += FXLS8974_MAX_ACCEL_CHANNELS; - if (fxls8974_get_temp_data(dev, val)) { - return -EIO; - } + return fxls8974_get_temp_data(dev, val); break; case SENSOR_CHAN_ACCEL_XYZ: return fxls8974_get_accel_data(dev, val, SENSOR_CHAN_ACCEL_XYZ); @@ -401,7 +399,7 @@ static int fxls8974_channel_get(const struct device *dev, return 0; } -int fxls8974_get_active(const struct device *dev, enum fxls8974_active *active) +int fxls8974_get_active(const struct device *dev, uint8_t *active) { const struct fxls8974_config *cfg = dev->config; uint8_t val; @@ -417,7 +415,7 @@ int fxls8974_get_active(const struct device *dev, enum fxls8974_active *active) return 0; } -int fxls8974_set_active(const struct device *dev, enum fxls8974_active active) +int fxls8974_set_active(const struct device *dev, uint8_t active) { const struct fxls8974_config *cfg = dev->config; @@ -500,7 +498,7 @@ static int fxls8974_init(const struct device *dev) return -EIO; } - if (fxls8974_get_active(dev, (enum fxls8974_active *)®Val)) { + if (fxls8974_get_active(dev, ®Val)) { LOG_ERR("Failed to set standby mode"); return -EIO; } @@ -562,7 +560,7 @@ static int fxls8974_init(const struct device *dev) return -EIO; } - if (fxls8974_get_active(dev, (enum fxls8974_active *)®Val)) { + if (fxls8974_get_active(dev, ®Val)) { LOG_ERR("Failed to get active mode"); return -EIO; } diff --git a/drivers/sensor/nxp/fxls8974/fxls8974.h b/drivers/sensor/nxp/fxls8974/fxls8974.h index e01cc78fe7c4f..42114f169d17b 100644 --- a/drivers/sensor/nxp/fxls8974/fxls8974.h +++ b/drivers/sensor/nxp/fxls8974/fxls8974.h @@ -155,8 +155,8 @@ struct fxls8974_data { #endif }; -int fxls8974_get_active(const struct device *dev, enum fxls8974_active *active); -int fxls8974_set_active(const struct device *dev, enum fxls8974_active active); +int fxls8974_get_active(const struct device *dev, uint8_t *active); +int fxls8974_set_active(const struct device *dev, uint8_t active); #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) int fxls8974_byte_write_spi(const struct device *dev, diff --git a/drivers/sensor/nxp/p3t1755/p3t1755.c b/drivers/sensor/nxp/p3t1755/p3t1755.c index cc456dabb558d..361b25b7ca645 100644 --- a/drivers/sensor/nxp/p3t1755/p3t1755.c +++ b/drivers/sensor/nxp/p3t1755/p3t1755.c @@ -51,7 +51,7 @@ static int p3t1755_sample_fetch(const struct device *dev, enum sensor_channel ch { const struct p3t1755_config *config = dev->config; struct p3t1755_data *data = dev->data; - uint8_t raw_temp[2]; + uint8_t raw_temp[2] = {0}; if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP) { LOG_ERR("Invalid channel provided"); @@ -65,7 +65,12 @@ static int p3t1755_sample_fetch(const struct device *dev, enum sensor_channel ch k_sleep(K_MSEC(12)); } - config->ops.read(dev, P3T1755_TEMPERATURE_REG, raw_temp, 2); + int status = config->ops.read(dev, P3T1755_TEMPERATURE_REG, raw_temp, 2); + + if (status) { + LOG_ERR("read return error %d", status); + return -ENOTSUP; + } /* Byte 1 contains the MSByte and Byte 2 contains the LSByte, we need to swap the 2 bytes. * The 4 least significant bits of the LSByte are zero and should be ignored. diff --git a/drivers/sensor/renesas/CMakeLists.txt b/drivers/sensor/renesas/CMakeLists.txt index 28ff2d1db9fa6..bfe5d9bf400fd 100644 --- a/drivers/sensor/renesas/CMakeLists.txt +++ b/drivers/sensor/renesas/CMakeLists.txt @@ -3,5 +3,6 @@ # zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_HS300X hs300x) +add_subdirectory_ifdef(CONFIG_HS400X hs400x) add_subdirectory_ifdef(CONFIG_ISL29035 isl29035) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/renesas/Kconfig b/drivers/sensor/renesas/Kconfig index 00d5dd6b796e2..832e003edec22 100644 --- a/drivers/sensor/renesas/Kconfig +++ b/drivers/sensor/renesas/Kconfig @@ -3,5 +3,6 @@ # zephyr-keep-sorted-start source "drivers/sensor/renesas/hs300x/Kconfig" +source "drivers/sensor/renesas/hs400x/Kconfig" source "drivers/sensor/renesas/isl29035/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/renesas/hs400x/CMakeLists.txt b/drivers/sensor/renesas/hs400x/CMakeLists.txt new file mode 100644 index 0000000000000..5c051a1167697 --- /dev/null +++ b/drivers/sensor/renesas/hs400x/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(hs400x.c) diff --git a/drivers/sensor/renesas/hs400x/Kconfig b/drivers/sensor/renesas/hs400x/Kconfig new file mode 100644 index 0000000000000..d0bb96e41a7b0 --- /dev/null +++ b/drivers/sensor/renesas/hs400x/Kconfig @@ -0,0 +1,21 @@ +# HS400X temperature and humidity sensor + +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config HS400X + bool "HS400x sensor" + default y + depends on DT_HAS_RENESAS_HS400X_ENABLED + help + Enable driver for HS400x temperature and humidity sensors. + +if HS400X + +config HS400X_CRC + bool "HS400X CRC check" + select CRC + help + Verify the checksum byte from measurements + +endif # HS400x diff --git a/drivers/sensor/renesas/hs400x/hs400x.c b/drivers/sensor/renesas/hs400x/hs400x.c new file mode 100644 index 0000000000000..a739a0256daea --- /dev/null +++ b/drivers/sensor/renesas/hs400x/hs400x.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_hs400x + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CRC_POLYNOMIAL 0x1D +#define CRC_INITIAL 0xFF + +LOG_MODULE_REGISTER(HS400X, CONFIG_SENSOR_LOG_LEVEL); + +struct hs400x_config { + struct i2c_dt_spec bus; +}; + +struct hs400x_data { + int16_t t_sample; + uint16_t rh_sample; +}; + +static int hs400x_read_sample(const struct device *dev, uint16_t *t_sample, uint16_t *rh_sample) +{ + const struct hs400x_config *cfg = dev->config; + uint8_t rx_buf[5]; + int rc; + + rc = i2c_read_dt(&cfg->bus, rx_buf, sizeof(rx_buf)); + if (rc < 0) { + LOG_ERR("Failed to read data from device."); + return rc; + } + + *rh_sample = sys_get_be16(rx_buf); + *t_sample = sys_get_be16(&rx_buf[2]); + + /* + * The sensor sends a checkum after each measurement. See datasheet "CRC Checksum + * Calculation" section for more details on checking the checksum. + */ +#if CONFIG_HS400X_CRC + uint8_t crc = crc8(rx_buf, 4, CRC_POLYNOMIAL, CRC_INITIAL, 0); + + if (crc != rx_buf[4]) { + LOG_ERR("CRC check failed: computed=%u,expected=%u", crc, rx_buf[4]); + return -EIO; + } +#endif + + return 0; +} + +static int hs400x_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct hs400x_data *data = dev->data; + const struct hs400x_config *cfg = dev->config; + int rc; + uint8_t no_hold_measurement = 0xF5; + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP && + chan != SENSOR_CHAN_HUMIDITY) { + return -ENOTSUP; + } + + rc = i2c_write_dt(&cfg->bus, (const uint8_t *)&no_hold_measurement, 1); + if (rc < 0) { + LOG_ERR("Failed to send measurement."); + return rc; + } + + /* + * According to datasheet maximum time to make temperature and humidity + * measurements is 33ms, add a little safety margin... + */ + k_msleep(50); + + rc = hs400x_read_sample(dev, &data->t_sample, &data->rh_sample); + if (rc < 0) { + LOG_ERR("Failed to fetch data."); + return rc; + } + + return 0; +} + +static void hs400x_temp_convert(struct sensor_value *val, int16_t raw) +{ + int32_t micro_c; + + /* + * Convert to micro Celsius. See datasheet "Calculating Humidity and + * Temperature Output" section for more details on processing sample data. + */ + micro_c = (((int64_t)raw * 165000000) / 16383) - 40000000; + + val->val1 = micro_c / 1000000; + val->val2 = micro_c % 1000000; +} + +static void hs400x_rh_convert(struct sensor_value *val, uint16_t raw) +{ + int32_t micro_rh; + + /* + * Convert to micro %RH. See datasheet "Calculating Humidity and + * Temperature Output" section for more details on processing sample data. + */ + micro_rh = ((uint64_t)raw * 100000000) / 16383; + + val->val1 = micro_rh / 1000000; + val->val2 = micro_rh % 1000000; +} + +static int hs400x_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + const struct hs400x_data *data = dev->data; + + if (chan == SENSOR_CHAN_AMBIENT_TEMP) { + hs400x_temp_convert(val, data->t_sample); + } else if (chan == SENSOR_CHAN_HUMIDITY) { + hs400x_rh_convert(val, data->rh_sample); + } else { + return -ENOTSUP; + } + + return 0; +} + +static int hs400x_init(const struct device *dev) +{ + const struct hs400x_config *cfg = dev->config; + + if (!i2c_is_ready_dt(&cfg->bus)) { + LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name); + return -ENODEV; + } + + return 0; +} + +static DEVICE_API(sensor, hs400x_driver_api) = { + .sample_fetch = hs400x_sample_fetch, + .channel_get = hs400x_channel_get, +}; + +#define DEFINE_HS400X(n) \ + static struct hs400x_data hs400x_data_##n; \ + \ + static const struct hs400x_config hs400x_config_##n = {.bus = I2C_DT_SPEC_INST_GET(n)}; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(n, hs400x_init, NULL, &hs400x_data_##n, &hs400x_config_##n, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &hs400x_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_HS400X) diff --git a/drivers/sensor/sensirion/scd4x/scd4x.c b/drivers/sensor/sensirion/scd4x/scd4x.c index bc9edead01d98..e989c155d5037 100644 --- a/drivers/sensor/sensirion/scd4x/scd4x.c +++ b/drivers/sensor/sensirion/scd4x/scd4x.c @@ -889,14 +889,14 @@ static DEVICE_API(sensor, scd4x_api_funcs) = { }; #define SCD4X_INIT(inst, scd4x_model) \ - static struct scd4x_data scd4x_data_##inst; \ - static const struct scd4x_config scd4x_config_##inst = { \ + static struct scd4x_data scd4x_data_##scd4x_model##_##inst; \ + static const struct scd4x_config scd4x_config_##scd4x_model##_##inst = { \ .bus = I2C_DT_SPEC_INST_GET(inst), \ .model = scd4x_model, \ .mode = DT_INST_ENUM_IDX_OR(inst, mode, SCD4X_MODE_NORMAL), \ }; \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, scd4x_init, NULL, &scd4x_data_##inst, \ - &scd4x_config_##inst, POST_KERNEL, \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, scd4x_init, NULL, &scd4x_data_##scd4x_model##_##inst, \ + &scd4x_config_##scd4x_model##_##inst, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, &scd4x_api_funcs); #define DT_DRV_COMPAT sensirion_scd40 diff --git a/drivers/sensor/sensirion/scd4x/scd4x.h b/drivers/sensor/sensirion/scd4x/scd4x.h index 3955d2021990f..2e7c8e0dcc42a 100644 --- a/drivers/sensor/sensirion/scd4x/scd4x.h +++ b/drivers/sensor/sensirion/scd4x/scd4x.h @@ -29,7 +29,7 @@ #define SCD4X_CMD_FACTORY_RESET 17 #define SCD4X_CMD_MEASURE_SINGLE_SHOT 18 #define SCD4X_CMD_MEASURE_SINGLE_SHOT_RHT 19 -#define SCD4X_CMD_POWER_DOWN 10 +#define SCD4X_CMD_POWER_DOWN 20 #define SCD4X_CMD_WAKE_UP 21 #define SCD4X_CMD_SET_SELF_CALIB_INITIAL_PERIOD 22 #define SCD4X_CMD_GET_SELF_CALIB_INITIAL_PERIOD 23 diff --git a/drivers/sensor/sensor_clock_external.c b/drivers/sensor/sensor_clock_external.c new file mode 100644 index 0000000000000..5baf1ac156398 --- /dev/null +++ b/drivers/sensor/sensor_clock_external.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Cienet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(sensor_clock, CONFIG_SENSOR_LOG_LEVEL); + +static const struct device *external_sensor_clock = DEVICE_DT_GET(DT_CHOSEN(zephyr_sensor_clock)); +static uint32_t freq; + +static int external_sensor_clock_init(void) +{ + int rc; + + rc = counter_start(external_sensor_clock); + if (rc != 0) { + LOG_ERR("Failed to start sensor clock counter: %d\n", rc); + return rc; + } + + freq = counter_get_frequency(external_sensor_clock); + if (freq == 0) { + LOG_ERR("Sensor clock %s has no fixed frequency\n", external_sensor_clock->name); + return -EINVAL; + } + + return 0; +} + +int sensor_clock_get_cycles(uint64_t *cycles) +{ + __ASSERT_NO_MSG(counter_is_counting_up(external_sensor_clock)); + + int rc; + const struct counter_driver_api *api = + (const struct counter_driver_api *)external_sensor_clock->api; + + if (api->get_value_64) { + rc = counter_get_value_64(external_sensor_clock, cycles); + } else { + uint32_t result_32; + + rc = counter_get_value(external_sensor_clock, &result_32); + *cycles = (uint64_t)result_32; + } + + return rc; +} + +uint64_t sensor_clock_cycles_to_ns(uint64_t cycles) +{ + return (cycles * NSEC_PER_SEC) / freq; +} + +SYS_INIT(external_sensor_clock_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/drivers/sensor/sensor_clock_sys.c b/drivers/sensor/sensor_clock_sys.c new file mode 100644 index 0000000000000..e98292684663b --- /dev/null +++ b/drivers/sensor/sensor_clock_sys.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Cienet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +int sensor_clock_get_cycles(uint64_t *cycles) +{ + if (cycles == NULL) { + return -EINVAL; + } + +#ifdef CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER + *cycles = k_cycle_get_64(); +#else + *cycles = (uint64_t)k_cycle_get_32(); +#endif + + return 0; +} + +uint64_t sensor_clock_cycles_to_ns(uint64_t cycles) +{ + return (cycles * NSEC_PER_SEC) / sys_clock_hw_cycles_per_sec(); +} diff --git a/drivers/sensor/sensor_shell.c b/drivers/sensor/sensor_shell.c index aa7742b61df89..2bddf8b9b0070 100644 --- a/drivers/sensor/sensor_shell.c +++ b/drivers/sensor/sensor_shell.c @@ -88,6 +88,7 @@ static const char *sensor_channel_name[SENSOR_CHAN_COMMON_COUNT] = { [SENSOR_CHAN_POS_DZ] = "pos_dz", [SENSOR_CHAN_POS_DXYZ] = "pos_dxyz", [SENSOR_CHAN_RPM] = "rpm", + [SENSOR_CHAN_FREQUENCY] = "frequency", [SENSOR_CHAN_GAUGE_VOLTAGE] = "gauge_voltage", [SENSOR_CHAN_GAUGE_AVG_CURRENT] = "gauge_avg_current", [SENSOR_CHAN_GAUGE_STDBY_CURRENT] = "gauge_stdby_current", @@ -106,6 +107,9 @@ static const char *sensor_channel_name[SENSOR_CHAN_COMMON_COUNT] = { [SENSOR_CHAN_GAUGE_DESIGN_VOLTAGE] = "gauge_design_voltage", [SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE] = "gauge_desired_voltage", [SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT] = "gauge_desired_charging_current", + [SENSOR_CHAN_GAME_ROTATION_VECTOR] = "game_rotation_vector", + [SENSOR_CHAN_GRAVITY_VECTOR] = "gravity_vector", + [SENSOR_CHAN_GBIAS_XYZ] = "gbias_xyz", [SENSOR_CHAN_ALL] = "all", }; @@ -126,6 +130,8 @@ static const char *sensor_attribute_name[SENSOR_ATTR_COMMON_COUNT] = { [SENSOR_ATTR_ALERT] = "alert", [SENSOR_ATTR_FF_DUR] = "ff_dur", [SENSOR_ATTR_BATCH_DURATION] = "batch_dur", + [SENSOR_ATTR_GAIN] = "gain", + [SENSOR_ATTR_RESOLUTION] = "resolution", }; enum sample_stats_state { @@ -359,23 +365,6 @@ void sensor_shell_processing_callback(int result, uint8_t *buf, uint32_t buf_len size_t frame_size; uint16_t frame_count; - /* Channels with multi-axis equivalents are skipped */ - switch (ch.chan_type) { - case SENSOR_CHAN_ACCEL_X: - case SENSOR_CHAN_ACCEL_Y: - case SENSOR_CHAN_ACCEL_Z: - case SENSOR_CHAN_GYRO_X: - case SENSOR_CHAN_GYRO_Y: - case SENSOR_CHAN_GYRO_Z: - case SENSOR_CHAN_MAGN_X: - case SENSOR_CHAN_MAGN_Y: - case SENSOR_CHAN_MAGN_Z: - case SENSOR_CHAN_POS_DX: - case SENSOR_CHAN_POS_DY: - case SENSOR_CHAN_POS_DZ: - continue; - } - rc = decoder->get_size_info(ch, &base_size, &frame_size); if (rc != 0) { LOG_DBG("skipping unsupported channel %s:%d", @@ -548,7 +537,7 @@ static int cmd_get_sensor(const struct shell *sh, size_t argc, char *argv[]) return err; } - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL || !sensor_device_check(dev)) { shell_error(sh, "Sensor device unknown (%s)", argv[1]); k_mutex_unlock(&cmd_get_mutex); @@ -617,7 +606,7 @@ static int cmd_sensor_attr_set(const struct shell *shell_ptr, size_t argc, char const struct device *dev; int rc; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL || !sensor_device_check(dev)) { shell_error(shell_ptr, "Sensor device unknown (%s)", argv[1]); return -ENODEV; @@ -701,7 +690,7 @@ static int cmd_sensor_attr_get(const struct shell *shell_ptr, size_t argc, char { const struct device *dev; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL || !sensor_device_check(dev)) { shell_error(shell_ptr, "Sensor device unknown (%s)", argv[1]); return -ENODEV; @@ -864,7 +853,7 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry) static void device_name_get_for_attr(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, sensor_device_check); current_cmd_ctx = CTX_ATTR_GET_SET; entry->syntax = (dev != NULL) ? dev->name : NULL; @@ -919,7 +908,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_trigger_onoff, trigger_on_off_get); static void device_name_get_for_trigger(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, sensor_device_check); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; @@ -931,7 +920,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_trigger, device_name_get_for_trigger); static void device_name_get_for_stream(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, sensor_device_check); current_cmd_ctx = CTX_STREAM_ON_OFF; entry->syntax = (dev != NULL) ? dev->name : NULL; @@ -1051,7 +1040,7 @@ static int cmd_trig_sensor(const struct shell *sh, size_t argc, char **argv) } /* Parse device name */ - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (dev == NULL || !sensor_device_check(dev)) { shell_error(sh, "Sensor device unknown (%s)", argv[1]); return -ENODEV; diff --git a/drivers/sensor/silabs/si7006/Kconfig b/drivers/sensor/silabs/si7006/Kconfig index 37872744bdd56..33b2a95b9a078 100644 --- a/drivers/sensor/silabs/si7006/Kconfig +++ b/drivers/sensor/silabs/si7006/Kconfig @@ -6,6 +6,7 @@ config SI7006 default y depends on DT_HAS_SILABS_SI7006_ENABLED || DT_HAS_SENSIRION_SHT21_ENABLED select I2C + select REGULATOR if $(dt_compat_any_has_prop,$(DT_COMPAT_SILABS_SI7006),vin-supply) help Enable I2C-based driver for several humidity and temperature sensors compatible with the Sensirion SHT21, such as the Silicon Labs diff --git a/drivers/sensor/silabs/si7006/si7006.c b/drivers/sensor/silabs/si7006/si7006.c index bbfe67df49af3..90e33a2e55a2d 100644 --- a/drivers/sensor/silabs/si7006/si7006.c +++ b/drivers/sensor/silabs/si7006/si7006.c @@ -7,11 +7,11 @@ #include #include +#include #include #include #include #include -#include #include #include #include @@ -27,6 +27,7 @@ struct si7006_data { struct si7006_config { struct i2c_dt_spec i2c; + const struct device *vin_supply; /** Use "read temp" vs "read old temp" command, the latter only with SiLabs sensors. */ uint8_t read_temp_cmd; }; @@ -192,6 +193,13 @@ static int si7006_init(const struct device *dev) return -ENODEV; } + if (IS_ENABLED(CONFIG_REGULATOR) && config->vin_supply) { + regulator_enable(config->vin_supply); + + /* As stated by the Si7006 spec - Maximum powerup time is 80ms */ + k_msleep(80); + } + LOG_DBG("si7006 init ok"); return 0; @@ -202,6 +210,7 @@ static int si7006_init(const struct device *dev) \ static const struct si7006_config si7006_config_##name##_##inst = { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .vin_supply = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(inst, vin_supply)), \ .read_temp_cmd = temp_cmd, \ }; \ \ diff --git a/drivers/sensor/st/Kconfig b/drivers/sensor/st/Kconfig index 79a57bb6168ad..a38b12109419c 100644 --- a/drivers/sensor/st/Kconfig +++ b/drivers/sensor/st/Kconfig @@ -37,6 +37,7 @@ source "drivers/sensor/st/stm32_digi_temp/Kconfig" source "drivers/sensor/st/stm32_temp/Kconfig" source "drivers/sensor/st/stm32_vbat/Kconfig" source "drivers/sensor/st/stm32_vref/Kconfig" +source "drivers/sensor/st/stmemsc/Kconfig" source "drivers/sensor/st/stts22h/Kconfig" source "drivers/sensor/st/stts751/Kconfig" source "drivers/sensor/st/vl53l0x/Kconfig" diff --git a/drivers/sensor/st/hts221/hts221.c b/drivers/sensor/st/hts221/hts221.c index 9cc8f5afc94b2..6dbb771207a26 100644 --- a/drivers/sensor/st/hts221/hts221.c +++ b/drivers/sensor/st/hts221/hts221.c @@ -72,7 +72,8 @@ static int hts221_sample_fetch(const struct device *dev, uint8_t buf[4]; int status; - __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + __ASSERT_NO_MSG(chan == SENSOR_CHAN_HUMIDITY || chan == SENSOR_CHAN_AMBIENT_TEMP || + chan == SENSOR_CHAN_ALL); status = hts221_read_reg(ctx, HTS221_HUMIDITY_OUT_L | HTS221_AUTOINCREMENT_ADDR, buf, 4); diff --git a/drivers/sensor/st/iis2iclx/iis2iclx.c b/drivers/sensor/st/iis2iclx/iis2iclx.c index c7222a3ff071e..864e13e2f5788 100644 --- a/drivers/sensor/st/iis2iclx/iis2iclx.c +++ b/drivers/sensor/st/iis2iclx/iis2iclx.c @@ -65,20 +65,6 @@ static int iis2iclx_accel_range_to_fs_val(int32_t range) return -EINVAL; } -static inline int iis2iclx_reboot(const struct device *dev) -{ - const struct iis2iclx_config *cfg = dev->config; - - if (iis2iclx_boot_set((stmdev_ctx_t *)&cfg->ctx, 1) < 0) { - return -EIO; - } - - /* Wait sensor turn-on time as per datasheet */ - k_msleep(35); - - return 0; -} - static int iis2iclx_accel_set_fs_raw(const struct device *dev, uint8_t fs) { const struct iis2iclx_config *cfg = dev->config; diff --git a/drivers/sensor/st/iis3dhhc/iis3dhhc.c b/drivers/sensor/st/iis3dhhc/iis3dhhc.c index 9b428db526f50..dfa3e15e6ef3e 100644 --- a/drivers/sensor/st/iis3dhhc/iis3dhhc.c +++ b/drivers/sensor/st/iis3dhhc/iis3dhhc.c @@ -26,7 +26,7 @@ static int iis3dhhc_sample_fetch(const struct device *dev, struct iis3dhhc_data *data = dev->data; int16_t raw_accel[3]; - __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ACCEL_XYZ || chan == SENSOR_CHAN_ALL); iis3dhhc_acceleration_raw_get(data->ctx, raw_accel); data->acc[0] = raw_accel[0]; diff --git a/drivers/sensor/st/ism330dhcx/ism330dhcx.c b/drivers/sensor/st/ism330dhcx/ism330dhcx.c index c6f7087ddde9b..44b8506664e6d 100644 --- a/drivers/sensor/st/ism330dhcx/ism330dhcx.c +++ b/drivers/sensor/st/ism330dhcx/ism330dhcx.c @@ -104,20 +104,6 @@ static int ism330dhcx_gyro_range_to_fs_val(int32_t range) return -EINVAL; } -static inline int ism330dhcx_reboot(const struct device *dev) -{ - struct ism330dhcx_data *data = dev->data; - - if (ism330dhcx_boot_set(data->ctx, 1) < 0) { - return -EIO; - } - - /* Wait sensor turn-on time as per datasheet */ - k_busy_wait(35 * USEC_PER_MSEC); - - return 0; -} - static int ism330dhcx_accel_set_fs_raw(const struct device *dev, uint8_t fs) { struct ism330dhcx_data *data = dev->data; @@ -713,6 +699,15 @@ static int ism330dhcx_init_chip(const struct device *dev) k_busy_wait(100); + /* + * Set device_conf bit to 1 for a proper configuration + * as stated in DS chapter paragraph 9.20 + */ + if (ism330dhcx_device_conf_set(ism330dhcx->ctx, 1) < 0) { + LOG_DBG("Failed setting device_conf bit"); + return -EIO; + } + LOG_DBG("accel range is %d", cfg->accel_range); if (ism330dhcx_accel_range_set(dev, cfg->accel_range) < 0) { LOG_DBG("failed to set accelerometer full-scale"); diff --git a/drivers/sensor/st/lis2de12/lis2de12.c b/drivers/sensor/st/lis2de12/lis2de12.c index 77d5e59f018e3..bd32b66553a16 100644 --- a/drivers/sensor/st/lis2de12/lis2de12.c +++ b/drivers/sensor/st/lis2de12/lis2de12.c @@ -435,7 +435,7 @@ static int lis2de12_init(const struct device *dev) #define LIS2DE12_CONFIG_SPI(inst) \ { \ - STMEMSC_CTX_SPI(&lis2de12_config_##inst.stmemsc_cfg), \ + STMEMSC_CTX_SPI_INCR(&lis2de12_config_##inst.stmemsc_cfg), \ .stmemsc_cfg = { \ .spi = SPI_DT_SPEC_INST_GET(inst, LIS2DE12_SPI_OP, 0), \ }, \ diff --git a/drivers/sensor/st/lis2dh/lis2dh.c b/drivers/sensor/st/lis2dh/lis2dh.c index ec476ea53e29e..1721fd963bf60 100644 --- a/drivers/sensor/st/lis2dh/lis2dh.c +++ b/drivers/sensor/st/lis2dh/lis2dh.c @@ -271,6 +271,21 @@ static int lis2dh_acc_range_set(const struct device *dev, int32_t range) } #endif +#ifdef CONFIG_LIS2DH_ACCEL_HP_FILTERS +static int lis2dh_acc_hp_filter_set(const struct device *dev, int32_t val) +{ + struct lis2dh_data *lis2dh = dev->data; + int status; + + status = lis2dh->hw_tf->write_reg(dev, LIS2DH_REG_CTRL2, val); + if (status < 0) { + LOG_ERR("Failed to set high pass filters"); + } + + return status; +} +#endif + static int lis2dh_acc_config(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, diff --git a/drivers/sensor/st/lis2dh/lis2dh.h b/drivers/sensor/st/lis2dh/lis2dh.h index f746e983e28b9..d18d8fb3cd8e3 100644 --- a/drivers/sensor/st/lis2dh/lis2dh.h +++ b/drivers/sensor/st/lis2dh/lis2dh.h @@ -87,9 +87,12 @@ #define LIS2DH_REG_CTRL2 0x21 #define LIS2DH_HPIS1_EN_BIT BIT(0) #define LIS2DH_HPIS2_EN_BIT BIT(1) +#define LIS2DH_HPCLICK_EN_BIT BIT(2) #define LIS2DH_FDS_EN_BIT BIT(3) - -#define LIS2DH_HPIS_EN_MASK BIT_MASK(2) +#define LIS2DH_HPCF0_EN_BIT BIT(4) +#define LIS2DH_HPCF1_EN_BIT BIT(5) +#define LIS2DH_HPM0_EN_BIT BIT(6) +#define LIS2DH_HPM1_EN_BIT BIT(7) #define LIS2DH_REG_CTRL3 0x22 #define LIS2DH_EN_CLICK_INT1 BIT(7) @@ -305,11 +308,6 @@ int lis2dh_acc_slope_config(const struct device *dev, const struct sensor_value *val); #endif -#ifdef CONFIG_LIS2DH_ACCEL_HP_FILTERS -int lis2dh_acc_hp_filter_set(const struct device *dev, - int32_t val); -#endif - int lis2dh_spi_init(const struct device *dev); int lis2dh_i2c_init(const struct device *dev); diff --git a/drivers/sensor/st/lis2dh/lis2dh_trigger.c b/drivers/sensor/st/lis2dh/lis2dh_trigger.c index 16b0ea52fb850..eb24bba445c23 100644 --- a/drivers/sensor/st/lis2dh/lis2dh_trigger.c +++ b/drivers/sensor/st/lis2dh/lis2dh_trigger.c @@ -361,22 +361,6 @@ int lis2dh_acc_slope_config(const struct device *dev, return status; } -#ifdef CONFIG_LIS2DH_ACCEL_HP_FILTERS -int lis2dh_acc_hp_filter_set(const struct device *dev, int32_t val) -{ - struct lis2dh_data *lis2dh = dev->data; - int status; - - status = lis2dh->hw_tf->update_reg(dev, LIS2DH_REG_CTRL2, - LIS2DH_HPIS_EN_MASK, val); - if (status < 0) { - LOG_ERR("Failed to set high pass filters"); - } - - return status; -} -#endif - static void lis2dh_gpio_int1_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { diff --git a/drivers/sensor/st/lis2dux12/CMakeLists.txt b/drivers/sensor/st/lis2dux12/CMakeLists.txt index 87f0e6b89284f..ea8f5c50c6946 100644 --- a/drivers/sensor/st/lis2dux12/CMakeLists.txt +++ b/drivers/sensor/st/lis2dux12/CMakeLists.txt @@ -4,5 +4,7 @@ zephyr_library() zephyr_library_sources(lis2dux12.c) zephyr_library_sources_ifdef(CONFIG_LIS2DUX12_TRIGGER lis2dux12_trigger.c) +zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LIS2DUX12_ENABLED lis2dux12_api.c ) +zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LIS2DUXS12_ENABLED lis2duxs12_api.c ) zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/st/lis2dux12/Kconfig b/drivers/sensor/st/lis2dux12/Kconfig index d27344484a79f..e2ed9f710af2a 100644 --- a/drivers/sensor/st/lis2dux12/Kconfig +++ b/drivers/sensor/st/lis2dux12/Kconfig @@ -6,12 +6,15 @@ menuconfig LIS2DUX12 bool "LIS2DUX12 I2C/SPI accelerometer sensor driver" default y - depends on DT_HAS_ST_LIS2DUX12_ENABLED + depends on DT_HAS_ST_LIS2DUX12_ENABLED || DT_HAS_ST_LIS2DUXS12_ENABLED depends on ZEPHYR_HAL_ST_MODULE - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUX12),i2c) - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUX12),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUX12),i2c) || \ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUXS12),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUX12),spi) || \ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LIS2DUXS12),spi) select HAS_STMEMSC - select USE_STDC_LIS2DUX12 + select USE_STDC_LIS2DUX12 if DT_HAS_ST_LIS2DUX12_ENABLED + select USE_STDC_LIS2DUXS12 if DT_HAS_ST_LIS2DUXS12_ENABLED help Enable driver for LIS2DUX12 accelerometer sensor driver diff --git a/drivers/sensor/st/lis2dux12/lis2dux12.c b/drivers/sensor/st/lis2dux12/lis2dux12.c index f41e23daad40c..cb3c5bee9e331 100644 --- a/drivers/sensor/st/lis2dux12/lis2dux12.c +++ b/drivers/sensor/st/lis2dux12/lis2dux12.c @@ -8,8 +8,6 @@ * https://www.st.com/resource/en/datasheet/lis2dux12.pdf */ -#define DT_DRV_COMPAT st_lis2dux12 - #include #include #include @@ -18,58 +16,18 @@ #include #include #include -#include #include "lis2dux12.h" -LOG_MODULE_REGISTER(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL); - -static int lis2dux12_set_odr(const struct device *dev, uint8_t odr) -{ - struct lis2dux12_data *data = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_md_t mode = {.odr = odr, .fs = data->range}; - - data->odr = odr; - return lis2dux12_mode_set(ctx, &mode); -} - -static int lis2dux12_set_range(const struct device *dev, uint8_t range) -{ - int err; - struct lis2dux12_data *data = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_md_t val = { .odr = data->odr, .fs = range }; - - err = lis2dux12_mode_set(ctx, &val); - - if (err) { - return err; - } +#if DT_HAS_COMPAT_STATUS_OKAY(st_lis2dux12) +#include "lis2dux12_api.h" +#endif - switch (range) { - default: - LOG_ERR("range [%d] not supported.", range); - return -EINVAL; - case LIS2DUX12_DT_FS_2G: - data->gain = lis2dux12_from_fs2g_to_mg(1); - break; - case LIS2DUX12_DT_FS_4G: - data->gain = lis2dux12_from_fs4g_to_mg(1); - break; - case LIS2DUX12_DT_FS_8G: - data->gain = lis2dux12_from_fs8g_to_mg(1); - break; - case LIS2DUX12_DT_FS_16G: - data->gain = lis2dux12_from_fs16g_to_mg(1); - break; - } +#if DT_HAS_COMPAT_STATUS_OKAY(st_lis2duxs12) +#include "lis2duxs12_api.h" +#endif - data->range = range; - return 0; -} +LOG_MODULE_REGISTER(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL); #define FOREACH_ODR_ENUM(ODR_VAL) \ ODR_VAL(LIS2DUX12_DT_ODR_OFF, 0.0f) \ @@ -113,6 +71,8 @@ static int lis2dux12_set_fs(const struct device *dev, int16_t fs) { int ret; uint8_t range; + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; switch (fs) { case 2: @@ -132,7 +92,7 @@ static int lis2dux12_set_fs(const struct device *dev, int16_t fs) return -EINVAL; } - ret = lis2dux12_set_range(dev, range); + ret = chip_api->set_range(dev, range); if (ret < 0) { LOG_ERR("%s: range init error %d", dev->name, range); return ret; @@ -146,6 +106,8 @@ static int lis2dux12_accel_config(const struct device *dev, enum sensor_channel enum sensor_attribute attr, const struct sensor_value *val) { int odr_val; + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; switch (attr) { case SENSOR_ATTR_FULL_SCALE: @@ -159,7 +121,7 @@ static int lis2dux12_accel_config(const struct device *dev, enum sensor_channel LOG_DBG("%s: set odr to %d Hz", dev->name, val->val1); - return lis2dux12_set_odr(dev, odr_val); + return chip_api->set_odr_raw(dev, odr_val); default: LOG_ERR("Accel attribute not supported."); return -ENOTSUP; @@ -182,71 +144,34 @@ static int lis2dux12_attr_set(const struct device *dev, enum sensor_channel chan return 0; } -static int lis2dux12_sample_fetch_accel(const struct device *dev) -{ - struct lis2dux12_data *data = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - - /* fetch raw data sample */ - lis2dux12_md_t mode = {.fs = data->range}; - lis2dux12_xl_data_t xzy_data = {0}; - - if (lis2dux12_xl_data_get(ctx, &mode, &xzy_data) < 0) { - LOG_ERR("Failed to fetch raw data sample"); - return -EIO; - } - - data->sample_x = xzy_data.raw[0]; - data->sample_y = xzy_data.raw[1]; - data->sample_z = xzy_data.raw[2]; - - return 0; -} - -#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP -static int lis2dux12_sample_fetch_temp(const struct device *dev) -{ - struct lis2dux12_data *data = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - - /* fetch raw data sample */ - lis2dux12_outt_data_t temp_data = {0}; - - if (lis2dux12_outt_data_get(ctx, &temp_data) < 0) { - LOG_ERR("Failed to fetch raw temperature data sample"); - return -EIO; - } - - data->sample_temp = temp_data.heat.deg_c; - - return 0; -} -#endif - static int lis2dux12_sample_fetch(const struct device *dev, enum sensor_channel chan) { + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; + int ret; + switch (chan) { case SENSOR_CHAN_ACCEL_XYZ: - lis2dux12_sample_fetch_accel(dev); + ret = chip_api->sample_fetch_accel(dev); break; #if defined(CONFIG_LIS2DUX12_ENABLE_TEMP) case SENSOR_CHAN_DIE_TEMP: - lis2dux12_sample_fetch_temp(dev); + ret = chip_api->sample_fetch_temp(dev); break; #endif case SENSOR_CHAN_ALL: - lis2dux12_sample_fetch_accel(dev); + ret = chip_api->sample_fetch_accel(dev); + if (ret != 0) + break; #if defined(CONFIG_LIS2DUX12_ENABLE_TEMP) - lis2dux12_sample_fetch_temp(dev); + ret = chip_api->sample_fetch_temp(dev); #endif break; default: return -ENOTSUP; } - return 0; + return ret; } static inline void lis2dux12_convert(struct sensor_value *val, int raw_val, float gain) @@ -307,129 +232,59 @@ static DEVICE_API(sensor, lis2dux12_driver_api) = { .channel_get = lis2dux12_channel_get, }; -static int lis2dux12_init(const struct device *dev) -{ - const struct lis2dux12_config *const cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - uint8_t chip_id; - int ret; - - lis2dux12_exit_deep_power_down(ctx); - k_busy_wait(25000); - - /* check chip ID */ - ret = lis2dux12_device_id_get(ctx, &chip_id); - if (ret < 0) { - LOG_ERR("%s: Not able to read dev id", dev->name); - return ret; - } - - if (chip_id != LIS2DUX12_ID) { - LOG_ERR("%s: Invalid chip ID 0x%02x", dev->name, chip_id); - return -EINVAL; - } - - /* reset device */ - ret = lis2dux12_init_set(ctx, LIS2DUX12_RESET); - if (ret < 0) { - return ret; - } - - k_busy_wait(100); - - LOG_INF("%s: chip id 0x%x", dev->name, chip_id); - - /* Set bdu and if_inc recommended for driver usage */ - lis2dux12_init_set(ctx, LIS2DUX12_SENSOR_ONLY_ON); - - lis2dux12_timestamp_set(ctx, PROPERTY_ENABLE); - -#ifdef CONFIG_LIS2DUX12_TRIGGER - if (cfg->trig_enabled) { - ret = lis2dux12_trigger_init(dev); - if (ret < 0) { - LOG_ERR("%s: Failed to initialize triggers", dev->name); - return ret; - } - } -#endif - - /* set sensor default pm and odr */ - LOG_DBG("%s: pm: %d, odr: %d", dev->name, cfg->pm, cfg->odr); - ret = lis2dux12_set_odr(dev, cfg->odr); - if (ret < 0) { - LOG_ERR("%s: odr init error (12.5 Hz)", dev->name); - return ret; - } - - /* set sensor default scale (used to convert sample values) */ - LOG_DBG("%s: range is %d", dev->name, cfg->range); - ret = lis2dux12_set_range(dev, cfg->range); - if (ret < 0) { - LOG_ERR("%s: range init error %d", dev->name, cfg->range); - return ret; - } - - return 0; -} - /* * Device creation macro, shared by LIS2DUX12_DEFINE_SPI() and * LIS2DUX12_DEFINE_I2C(). */ -#define LIS2DUX12_DEVICE_INIT(inst) \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, lis2dux12_init, NULL, &lis2dux12_data_##inst, \ - &lis2dux12_config_##inst, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, &lis2dux12_driver_api); - /* * Instantiation macros used when a device is on a SPI bus. */ #ifdef CONFIG_LIS2DUX12_TRIGGER -#define LIS2DUX12_CFG_IRQ(inst) \ - .trig_enabled = true, \ - .int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, {0}), \ - .int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, {0}), \ +#define LIS2DUX12_CFG_IRQ(inst) \ + .trig_enabled = true, \ + .int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, {0}), \ + .int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, {0}), \ .drdy_pin = DT_INST_PROP(inst, drdy_pin), #else #define LIS2DUX12_CFG_IRQ(inst) #endif /* CONFIG_LIS2DUX12_TRIGGER */ +#define LIS2DUX12_CONFIG_COMMON(inst, name) \ + .chip_api = &name##_chip_api, \ + .range = DT_INST_PROP(inst, range), \ + .pm = DT_INST_PROP(inst, power_mode), \ + .odr = DT_INST_PROP(inst, odr), \ + IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ + DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ + (LIS2DUX12_CFG_IRQ(inst))) \ + #define LIS2DUX12_SPI_OPERATION \ (SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA) -#define LIS2DUX12_CONFIG_SPI(inst) \ +/* + * Instantiation macros used when a device is on a SPI bus. + */ +#define LIS2DUX12_CONFIG_SPI(inst, name) \ { \ - STMEMSC_CTX_SPI(&lis2dux12_config_##inst.stmemsc_cfg), \ + STMEMSC_CTX_SPI(&lis2dux12_config_##name##_##inst.stmemsc_cfg), \ .stmemsc_cfg = { \ .spi = SPI_DT_SPEC_INST_GET(inst, LIS2DUX12_SPI_OPERATION, 0), \ }, \ - .range = DT_INST_PROP(inst, range), \ - .pm = DT_INST_PROP(inst, power_mode), \ - .odr = DT_INST_PROP(inst, odr), \ - IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ - DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ - (LIS2DUX12_CFG_IRQ(inst))) \ + LIS2DUX12_CONFIG_COMMON(inst, name) \ } /* * Instantiation macros used when a device is on an I2C bus. */ - -#define LIS2DUX12_CONFIG_I2C(inst) \ +#define LIS2DUX12_CONFIG_I2C(inst, name) \ { \ - STMEMSC_CTX_I2C(&lis2dux12_config_##inst.stmemsc_cfg), \ + STMEMSC_CTX_I2C(&lis2dux12_config_##name##_##inst.stmemsc_cfg), \ .stmemsc_cfg = { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ }, \ - .range = DT_INST_PROP(inst, range), \ - .pm = DT_INST_PROP(inst, power_mode), \ - .odr = DT_INST_PROP(inst, odr), \ - IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ - DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ - (LIS2DUX12_CFG_IRQ(inst))) \ + LIS2DUX12_CONFIG_COMMON(inst, name) \ } /* @@ -437,11 +292,24 @@ static int lis2dux12_init(const struct device *dev) * bus-specific macro at preprocessor time. */ -#define LIS2DUX12_DEFINE(inst) \ - static struct lis2dux12_data lis2dux12_data_##inst; \ - static const struct lis2dux12_config lis2dux12_config_##inst = \ - COND_CODE_1(DT_INST_ON_BUS(inst, spi), (LIS2DUX12_CONFIG_SPI(inst)), \ - (LIS2DUX12_CONFIG_I2C(inst))); \ - LIS2DUX12_DEVICE_INIT(inst) +#define LIS2DUX12_DEFINE(inst, name) \ + static struct lis2dux12_data lis2dux12_data_##name##_##inst; \ + static const struct lis2dux12_config lis2dux12_config_##name##_##inst = \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (LIS2DUX12_CONFIG_SPI(inst, name)), \ + (LIS2DUX12_CONFIG_I2C(inst, name))); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, name##_init, NULL, \ + &lis2dux12_data_##name##_##inst, \ + &lis2dux12_config_##name##_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ + &lis2dux12_driver_api); + + +#define DT_DRV_COMPAT st_lis2dux12 +DT_INST_FOREACH_STATUS_OKAY_VARGS(LIS2DUX12_DEFINE, DT_DRV_COMPAT) +#undef DT_DRV_COMPAT -DT_INST_FOREACH_STATUS_OKAY(LIS2DUX12_DEFINE) +#define DT_DRV_COMPAT st_lis2duxs12 +DT_INST_FOREACH_STATUS_OKAY_VARGS(LIS2DUX12_DEFINE, DT_DRV_COMPAT) +#undef DT_DRV_COMPAT diff --git a/drivers/sensor/st/lis2dux12/lis2dux12.h b/drivers/sensor/st/lis2dux12/lis2dux12.h index 7d0d85f34ed69..57acdb61982f5 100644 --- a/drivers/sensor/st/lis2dux12/lis2dux12.h +++ b/drivers/sensor/st/lis2dux12/lis2dux12.h @@ -15,23 +15,58 @@ #include #include #include + +#if DT_HAS_COMPAT_STATUS_OKAY(st_lis2dux12) #include "lis2dux12_reg.h" +#endif -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#if DT_HAS_COMPAT_STATUS_OKAY(st_lis2duxs12) +#include "lis2duxs12_reg.h" +#endif + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, spi) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2duxs12, spi) #include -#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ +#endif -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2duxs12, i2c) #include -#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ +#endif + +typedef int32_t (*api_lis2dux12_set_odr_raw)(const struct device *dev, uint8_t odr); +typedef int32_t (*api_lis2dux12_set_range)(const struct device *dev, uint8_t range); +typedef int32_t (*api_lis2dux12_sample_fetch_accel)(const struct device *dev); +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP +typedef int32_t (*api_lis2dux12_sample_fetch_temp)(const struct device *dev); +#endif +#ifdef CONFIG_LIS2DUX12_TRIGGER +typedef void (*api_lis2dux12_handle_interrupt)(const struct device *dev); +typedef int32_t (*api_lis2dux12_init_interrupt)(const struct device *dev); +#endif + +struct lis2dux12_chip_api { + api_lis2dux12_set_odr_raw set_odr_raw; + api_lis2dux12_set_range set_range; + api_lis2dux12_sample_fetch_accel sample_fetch_accel; +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP + api_lis2dux12_sample_fetch_temp sample_fetch_temp; +#endif +#ifdef CONFIG_LIS2DUX12_TRIGGER + api_lis2dux12_handle_interrupt handle_interrupt; + api_lis2dux12_init_interrupt init_interrupt; +#endif +}; struct lis2dux12_config { stmdev_ctx_t ctx; union { -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2duxs12, i2c) const struct i2c_dt_spec i2c; #endif -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2dux12, spi) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lis2duxs12, spi) const struct spi_dt_spec spi; #endif } stmemsc_cfg; @@ -44,6 +79,8 @@ struct lis2dux12_config { uint8_t drdy_pin; bool trig_enabled; #endif + + const struct lis2dux12_chip_api *chip_api; }; struct lis2dux12_data { diff --git a/drivers/sensor/st/lis2dux12/lis2dux12_api.c b/drivers/sensor/st/lis2dux12/lis2dux12_api.c new file mode 100644 index 0000000000000..3a00fdf1f6354 --- /dev/null +++ b/drivers/sensor/st/lis2dux12/lis2dux12_api.c @@ -0,0 +1,237 @@ +/* ST Microelectronics LIS2DUX12 smart accelerometer APIs + * + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2023 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lis2dux12.h" +#include "lis2dux12_api.h" +#include + +LOG_MODULE_DECLARE(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL); + +static int32_t st_lis2dux12_set_odr_raw(const struct device *dev, uint8_t odr) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2dux12_md_t mode = {.odr = odr, .fs = data->range}; + + data->odr = odr; + return lis2dux12_mode_set(ctx, &mode); +} + +static int32_t st_lis2dux12_set_range(const struct device *dev, uint8_t range) +{ + int err; + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2dux12_md_t val = { .odr = data->odr, .fs = range }; + + err = lis2dux12_mode_set(ctx, &val); + if (err) { + return err; + } + + switch (range) { + case LIS2DUX12_DT_FS_2G: + data->gain = lis2dux12_from_fs2g_to_mg(1); + break; + case LIS2DUX12_DT_FS_4G: + data->gain = lis2dux12_from_fs4g_to_mg(1); + break; + case LIS2DUX12_DT_FS_8G: + data->gain = lis2dux12_from_fs8g_to_mg(1); + break; + case LIS2DUX12_DT_FS_16G: + data->gain = lis2dux12_from_fs16g_to_mg(1); + break; + default: + LOG_ERR("range %d not supported.", range); + return -EINVAL; + } + + data->range = range; + return 0; +} + +static int32_t st_lis2dux12_sample_fetch_accel(const struct device *dev) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + /* fetch raw data sample */ + lis2dux12_md_t mode = {.fs = data->range}; + lis2dux12_xl_data_t xzy_data = {0}; + + if (lis2dux12_xl_data_get(ctx, &mode, &xzy_data) < 0) { + LOG_ERR("Failed to fetch raw data sample"); + return -EIO; + } + + data->sample_x = xzy_data.raw[0]; + data->sample_y = xzy_data.raw[1]; + data->sample_z = xzy_data.raw[2]; + + return 0; +} + +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP +static int32_t st_lis2dux12_sample_fetch_temp(const struct device *dev) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + /* fetch raw data sample */ + lis2dux12_outt_data_t temp_data = {0}; + + if (lis2dux12_outt_data_get(ctx, &temp_data) < 0) { + LOG_ERR("Failed to fetch raw temperature data sample"); + return -EIO; + } + + data->sample_temp = temp_data.heat.deg_c; + + return 0; +} +#endif + +#ifdef CONFIG_LIS2DUX12_TRIGGER +static void st_lis2dux12_handle_interrupt(const struct device *dev) +{ + struct lis2dux12_data *lis2dux12 = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2dux12_all_sources_t sources; + int ret; + + lis2dux12_all_sources_get(ctx, &sources); + + if (sources.drdy == 0) { + goto exit; /* spurious interrupt */ + } + + if (lis2dux12->data_ready_handler != NULL) { + lis2dux12->data_ready_handler(dev, lis2dux12->data_ready_trigger); + } + +exit: + ret = gpio_pin_interrupt_configure_dt(lis2dux12->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("%s: Not able to configure pin_int", dev->name); + } +} + +static int32_t st_lis2dux12_init_interrupt(const struct device *dev) +{ + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2dux12_pin_int_route_t route; + int err; + + /* Enable pulsed mode */ + err = lis2dux12_data_ready_mode_set(ctx, LIS2DUX12_DRDY_PULSED); + if (err < 0) { + return err; + } + + /* route data-ready interrupt on int1 */ + err = lis2dux12_pin_int1_route_get(ctx, &route); + if (err < 0) { + return err; + } + + route.drdy = 1; + + err = lis2dux12_pin_int1_route_set(ctx, &route); + if (err < 0) { + return err; + } + + return 0; +} +#endif + +const struct lis2dux12_chip_api st_lis2dux12_chip_api = { + .set_odr_raw = st_lis2dux12_set_odr_raw, + .set_range = st_lis2dux12_set_range, + .sample_fetch_accel = st_lis2dux12_sample_fetch_accel, +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP + .sample_fetch_temp = st_lis2dux12_sample_fetch_temp, +#endif +#ifdef CONFIG_LIS2DUX12_TRIGGER + .handle_interrupt = st_lis2dux12_handle_interrupt, + .init_interrupt = st_lis2dux12_init_interrupt, +#endif +}; + +int st_lis2dux12_init(const struct device *dev) +{ + const struct lis2dux12_config *const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + uint8_t chip_id; + int ret; + + lis2dux12_exit_deep_power_down(ctx); + k_busy_wait(25000); + + /* check chip ID */ + ret = lis2dux12_device_id_get(ctx, &chip_id); + if (ret < 0) { + LOG_ERR("%s: Not able to read dev id", dev->name); + return ret; + } + + if (chip_id != LIS2DUX12_ID) { + LOG_ERR("%s: Invalid chip ID 0x%02x", dev->name, chip_id); + return -EINVAL; + } + + /* reset device */ + ret = lis2dux12_init_set(ctx, LIS2DUX12_RESET); + if (ret < 0) { + return ret; + } + + k_busy_wait(100); + + LOG_INF("%s: chip id 0x%x", dev->name, chip_id); + + /* Set bdu and if_inc recommended for driver usage */ + lis2dux12_init_set(ctx, LIS2DUX12_SENSOR_ONLY_ON); + + lis2dux12_timestamp_set(ctx, PROPERTY_ENABLE); + +#ifdef CONFIG_LIS2DUX12_TRIGGER + if (cfg->trig_enabled) { + ret = lis2dux12_trigger_init(dev); + if (ret < 0) { + LOG_ERR("%s: Failed to initialize triggers", dev->name); + return ret; + } + } +#endif + + /* set sensor default pm and odr */ + LOG_DBG("%s: pm: %d, odr: %d", dev->name, cfg->pm, cfg->odr); + ret = st_lis2dux12_set_odr_raw(dev, cfg->odr); + if (ret < 0) { + LOG_ERR("%s: odr init error (12.5 Hz)", dev->name); + return ret; + } + + /* set sensor default scale (used to convert sample values) */ + LOG_DBG("%s: range is %d", dev->name, cfg->range); + ret = st_lis2dux12_set_range(dev, cfg->range); + if (ret < 0) { + LOG_ERR("%s: range init error %d", dev->name, cfg->range); + return ret; + } + + return 0; +} diff --git a/drivers/sensor/st/lis2dux12/lis2dux12_api.h b/drivers/sensor/st/lis2dux12/lis2dux12_api.h new file mode 100644 index 0000000000000..fc07c32de925f --- /dev/null +++ b/drivers/sensor/st/lis2dux12/lis2dux12_api.h @@ -0,0 +1,24 @@ +/* ST Microelectronics LIS2DUX12 smart accelerometer APIs + * + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2023 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "lis2dux12_reg.h" +#include + +#include + +#ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_LIS2DUX12_API_H_ +#define ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_LIS2DUX12_API_H_ + +extern const struct lis2dux12_chip_api st_lis2dux12_chip_api; + +int st_lis2dux12_init(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_LIS2DUX12_LIS2DUX12_API_H_ */ diff --git a/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c b/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c index 30ede375ec3bb..effc40e5d2b75 100644 --- a/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c +++ b/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c @@ -8,8 +8,6 @@ * https://www.st.com/resource/en/datasheet/lis2dux12.pdf */ -#define DT_DRV_COMPAT st_lis2dux12 - #include #include "lis2dux12.h" @@ -35,41 +33,16 @@ static void lis2dux12_gpio_callback(const struct device *dev, struct gpio_callba #endif } -static void lis2dux12_handle_drdy_int(const struct device *dev) -{ - struct lis2dux12_data *data = dev->data; - - if (data->data_ready_handler != NULL) { - data->data_ready_handler(dev, data->data_ready_trigger); - } -} - -static void lis2dux12_handle_int(const struct device *dev) -{ - struct lis2dux12_data *lis2dux12 = dev->data; - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_all_sources_t sources; - int ret; - - lis2dux12_all_sources_get(ctx, &sources); - - if (sources.drdy) { - lis2dux12_handle_drdy_int(dev); - } - - ret = gpio_pin_interrupt_configure_dt(lis2dux12->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); - if (ret < 0) { - LOG_ERR("%s: Not able to configure pin_int", dev->name); - } -} - #ifdef CONFIG_LIS2DUX12_TRIGGER_OWN_THREAD static void lis2dux12_thread(struct lis2dux12_data *data) { + const struct device *dev = data->dev; + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; + while (1) { k_sem_take(&data->trig_sem, K_FOREVER); - lis2dux12_handle_int(data->dev); + chip_api->handle_interrupt(dev); } } #endif @@ -78,40 +51,14 @@ static void lis2dux12_thread(struct lis2dux12_data *data) static void lis2dux12_work_cb(struct k_work *work) { struct lis2dux12_data *data = CONTAINER_OF(work, struct lis2dux12_data, work); + const struct device *dev = data->dev; + const struct lis2dux12_config *const cfg = dev->config; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; - lis2dux12_handle_int(data->dev); + chip_api->handle_interrupt(dev); } #endif -static int lis2dux12_init_interrupt(const struct device *dev) -{ - const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_pin_int_route_t route; - int err; - - /* Enable pulsed mode */ - err = lis2dux12_data_ready_mode_set(ctx, LIS2DUX12_DRDY_PULSED); - if (err < 0) { - return err; - } - - /* route data-ready interrupt on int1 */ - err = lis2dux12_pin_int1_route_get(ctx, &route); - if (err < 0) { - return err; - } - - route.drdy = 1; - - err = lis2dux12_pin_int1_route_set(ctx, &route); - if (err < 0) { - return err; - } - - return 0; -} - int lis2dux12_trigger_init(const struct device *dev) { struct lis2dux12_data *data = dev->data; @@ -162,9 +109,7 @@ int lis2dux12_trigger_set(const struct device *dev, const struct sensor_trigger { struct lis2dux12_data *data = dev->data; const struct lis2dux12_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - lis2dux12_xl_data_t xldata; - lis2dux12_md_t mode = {.fs = cfg->range}; + const struct lis2dux12_chip_api *chip_api = cfg->chip_api; int ret; if (!cfg->trig_enabled) { @@ -190,10 +135,15 @@ int lis2dux12_trigger_set(const struct device *dev, const struct sensor_trigger } /* re-trigger lost interrupt */ - lis2dux12_xl_data_get(ctx, &mode, &xldata); + chip_api->sample_fetch_accel(dev); data->data_ready_trigger = trig; - lis2dux12_init_interrupt(dev); + ret = chip_api->init_interrupt(dev); + if (ret < 0) { + LOG_ERR("%s: Not able to initialize device interrupt", dev->name); + return ret; + } + return gpio_pin_interrupt_configure_dt(data->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); } diff --git a/drivers/sensor/st/lis2dux12/lis2duxs12_api.c b/drivers/sensor/st/lis2dux12/lis2duxs12_api.c new file mode 100644 index 0000000000000..23100aee4b49a --- /dev/null +++ b/drivers/sensor/st/lis2dux12/lis2duxs12_api.c @@ -0,0 +1,237 @@ +/* ST Microelectronics LIS2DUXS12 smart accelerometer APIs + * + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2023 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lis2dux12.h" +#include "lis2duxs12_api.h" +#include + +LOG_MODULE_DECLARE(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL); + +static int32_t st_lis2duxs12_set_odr_raw(const struct device *dev, uint8_t odr) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2duxs12_md_t mode = {.odr = odr, .fs = data->range}; + + data->odr = odr; + return lis2duxs12_mode_set(ctx, &mode); +} + +static int32_t st_lis2duxs12_set_range(const struct device *dev, uint8_t range) +{ + int err; + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2duxs12_md_t val = { .odr = data->odr, .fs = range }; + + err = lis2duxs12_mode_set(ctx, &val); + if (err) { + return err; + } + + switch (range) { + case LIS2DUX12_DT_FS_2G: + data->gain = lis2duxs12_from_fs2g_to_mg(1); + break; + case LIS2DUX12_DT_FS_4G: + data->gain = lis2duxs12_from_fs4g_to_mg(1); + break; + case LIS2DUX12_DT_FS_8G: + data->gain = lis2duxs12_from_fs8g_to_mg(1); + break; + case LIS2DUX12_DT_FS_16G: + data->gain = lis2duxs12_from_fs16g_to_mg(1); + break; + default: + LOG_ERR("range %d not supported.", range); + return -EINVAL; + } + + data->range = range; + return 0; +} + +static int32_t st_lis2duxs12_sample_fetch_accel(const struct device *dev) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + /* fetch raw data sample */ + lis2duxs12_md_t mode = {.fs = data->range}; + lis2duxs12_xl_data_t xzy_data = {0}; + + if (lis2duxs12_xl_data_get(ctx, &mode, &xzy_data) < 0) { + LOG_ERR("Failed to fetch raw data sample"); + return -EIO; + } + + data->sample_x = xzy_data.raw[0]; + data->sample_y = xzy_data.raw[1]; + data->sample_z = xzy_data.raw[2]; + + return 0; +} + +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP +static int32_t st_lis2duxs12_sample_fetch_temp(const struct device *dev) +{ + struct lis2dux12_data *data = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + /* fetch raw data sample */ + lis2duxs12_outt_data_t temp_data = {0}; + + if (lis2duxs12_outt_data_get(ctx, &temp_data) < 0) { + LOG_ERR("Failed to fetch raw temperature data sample"); + return -EIO; + } + + data->sample_temp = temp_data.heat.deg_c; + + return 0; +} +#endif + +#ifdef CONFIG_LIS2DUX12_TRIGGER +static void st_lis2duxs12_handle_interrupt(const struct device *dev) +{ + struct lis2dux12_data *lis2duxs12 = dev->data; + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2duxs12_all_sources_t sources; + int ret; + + lis2duxs12_all_sources_get(ctx, &sources); + + if (sources.drdy == 0) { + goto exit; /* spurious interrupt */ + } + + if (lis2duxs12->data_ready_handler != NULL) { + lis2duxs12->data_ready_handler(dev, lis2duxs12->data_ready_trigger); + } + +exit: + ret = gpio_pin_interrupt_configure_dt(lis2duxs12->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("%s: Not able to configure pin_int", dev->name); + } +} + +static int32_t st_lis2duxs12_init_interrupt(const struct device *dev) +{ + const struct lis2dux12_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lis2duxs12_pin_int_route_t route; + int err; + + /* Enable pulsed mode */ + err = lis2duxs12_data_ready_mode_set(ctx, LIS2DUXS12_DRDY_PULSED); + if (err < 0) { + return err; + } + + /* route data-ready interrupt on int1 */ + err = lis2duxs12_pin_int1_route_get(ctx, &route); + if (err < 0) { + return err; + } + + route.drdy = 1; + + err = lis2duxs12_pin_int1_route_set(ctx, &route); + if (err < 0) { + return err; + } + + return 0; +} +#endif + +const struct lis2dux12_chip_api st_lis2duxs12_chip_api = { + .set_odr_raw = st_lis2duxs12_set_odr_raw, + .set_range = st_lis2duxs12_set_range, + .sample_fetch_accel = st_lis2duxs12_sample_fetch_accel, +#ifdef CONFIG_LIS2DUX12_ENABLE_TEMP + .sample_fetch_temp = st_lis2duxs12_sample_fetch_temp, +#endif +#ifdef CONFIG_LIS2DUX12_TRIGGER + .handle_interrupt = st_lis2duxs12_handle_interrupt, + .init_interrupt = st_lis2duxs12_init_interrupt, +#endif +}; + +int st_lis2duxs12_init(const struct device *dev) +{ + const struct lis2dux12_config *const cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + uint8_t chip_id; + int ret; + + lis2duxs12_exit_deep_power_down(ctx); + k_busy_wait(25000); + + /* check chip ID */ + ret = lis2duxs12_device_id_get(ctx, &chip_id); + if (ret < 0) { + LOG_ERR("%s: Not able to read dev id", dev->name); + return ret; + } + + if (chip_id != LIS2DUXS12_ID) { + LOG_ERR("%s: Invalid chip ID 0x%02x", dev->name, chip_id); + return -EINVAL; + } + + /* reset device */ + ret = lis2duxs12_init_set(ctx, LIS2DUXS12_RESET); + if (ret < 0) { + return ret; + } + + k_busy_wait(100); + + LOG_INF("%s: chip id 0x%x", dev->name, chip_id); + + /* Set bdu and if_inc recommended for driver usage */ + lis2duxs12_init_set(ctx, LIS2DUXS12_SENSOR_ONLY_ON); + + lis2duxs12_timestamp_set(ctx, PROPERTY_ENABLE); + +#ifdef CONFIG_LIS2DUX12_TRIGGER + if (cfg->trig_enabled) { + ret = lis2dux12_trigger_init(dev); + if (ret < 0) { + LOG_ERR("%s: Failed to initialize triggers", dev->name); + return ret; + } + } +#endif + + /* set sensor default pm and odr */ + LOG_DBG("%s: pm: %d, odr: %d", dev->name, cfg->pm, cfg->odr); + ret = st_lis2duxs12_set_odr_raw(dev, cfg->odr); + if (ret < 0) { + LOG_ERR("%s: odr init error (12.5 Hz)", dev->name); + return ret; + } + + /* set sensor default scale (used to convert sample values) */ + LOG_DBG("%s: range is %d", dev->name, cfg->range); + ret = st_lis2duxs12_set_range(dev, cfg->range); + if (ret < 0) { + LOG_ERR("%s: range init error %d", dev->name, cfg->range); + return ret; + } + + return 0; +} diff --git a/drivers/sensor/st/lis2dux12/lis2duxs12_api.h b/drivers/sensor/st/lis2dux12/lis2duxs12_api.h new file mode 100644 index 0000000000000..5932c32626190 --- /dev/null +++ b/drivers/sensor/st/lis2dux12/lis2duxs12_api.h @@ -0,0 +1,24 @@ +/* ST Microelectronics LIS2DUXS12 smart accelerometer APIs + * + * Copyright (c) 2024 STMicroelectronics + * Copyright (c) 2023 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "lis2duxs12_reg.h" +#include + +#include + +#ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DUXS12_LIS2DUXS12_API_H_ +#define ZEPHYR_DRIVERS_SENSOR_LIS2DUXS12_LIS2DUXS12_API_H_ + +extern const struct lis2dux12_chip_api st_lis2duxs12_chip_api; + +int st_lis2duxs12_init(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_LIS2DUXS12_LIS2DUXS12_API_H_ */ diff --git a/drivers/sensor/st/lis2dw12/lis2dw12.c b/drivers/sensor/st/lis2dw12/lis2dw12.c index bea05819f365a..e36043f47d61c 100644 --- a/drivers/sensor/st/lis2dw12/lis2dw12.c +++ b/drivers/sensor/st/lis2dw12/lis2dw12.c @@ -190,18 +190,6 @@ static int lis2dw12_config(const struct device *dev, enum sensor_channel chan, return -ENOTSUP; } - -static inline int32_t sensor_ms2_to_mg(const struct sensor_value *ms2) -{ - int64_t nano_ms2 = (ms2->val1 * 1000000LL + ms2->val2) * 1000LL; - - if (nano_ms2 > 0) { - return (nano_ms2 + SENSOR_G / 2) / SENSOR_G; - } else { - return (nano_ms2 - SENSOR_G / 2) / SENSOR_G; - } -} - #if (CONFIG_LIS2DW12_SLEEP || CONFIG_LIS2DW12_WAKEUP) /* Converts a lis2dw12_fs_t range to its value in milli-g diff --git a/drivers/sensor/st/lis3mdl/lis3mdl.c b/drivers/sensor/st/lis3mdl/lis3mdl.c index 52bcb13f786ef..49c73ddff44d0 100644 --- a/drivers/sensor/st/lis3mdl/lis3mdl.c +++ b/drivers/sensor/st/lis3mdl/lis3mdl.c @@ -66,7 +66,7 @@ int lis3mdl_sample_fetch(const struct device *dev, enum sensor_channel chan) const struct lis3mdl_config *config = dev->config; int16_t buf[4]; - __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_MAGN_XYZ); /* fetch magnetometer sample */ if (i2c_burst_read_dt(&config->i2c, LIS3MDL_REG_SAMPLE_START, diff --git a/drivers/sensor/st/lps22hb/lps22hb.c b/drivers/sensor/st/lps22hb/lps22hb.c index 3c230300232ab..e32b9d7e28c36 100644 --- a/drivers/sensor/st/lps22hb/lps22hb.c +++ b/drivers/sensor/st/lps22hb/lps22hb.c @@ -36,7 +36,7 @@ static int lps22hb_sample_fetch(const struct device *dev, const struct lps22hb_config *config = dev->config; uint8_t out[5]; - __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + __ASSERT_NO_MSG(chan == SENSOR_CHAN_PRESS || chan == SENSOR_CHAN_ALL); if (i2c_burst_read_dt(&config->i2c, LPS22HB_REG_PRESS_OUT_XL, out, 5) < 0) { diff --git a/drivers/sensor/st/lps25hb/lps25hb.c b/drivers/sensor/st/lps25hb/lps25hb.c index 402e8d85838ac..87094fa0718e7 100644 --- a/drivers/sensor/st/lps25hb/lps25hb.c +++ b/drivers/sensor/st/lps25hb/lps25hb.c @@ -46,7 +46,7 @@ static int lps25hb_sample_fetch(const struct device *dev, uint8_t out[5]; int offset; - __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + __ASSERT_NO_MSG(chan == SENSOR_CHAN_PRESS || chan == SENSOR_CHAN_ALL); for (offset = 0; offset < sizeof(out); ++offset) { if (i2c_reg_read_byte_dt(&config->i2c, diff --git a/drivers/sensor/st/lps2xdf/ilps22qs.c b/drivers/sensor/st/lps2xdf/ilps22qs.c index e320ea941302c..3fd868b766e09 100644 --- a/drivers/sensor/st/lps2xdf/ilps22qs.c +++ b/drivers/sensor/st/lps2xdf/ilps22qs.c @@ -149,7 +149,7 @@ int st_ilps22qs_init(const struct device *dev) /* Select bus interface */ ilps22qs_bus_mode_get(ctx, &bus_mode); - bus_mode.filter = ILPS22QS_AUTO; + bus_mode.filter = ILPS22QS_FILTER_AUTO; bus_mode.interface = ILPS22QS_SEL_BY_HW; ilps22qs_bus_mode_set(ctx, &bus_mode); } diff --git a/drivers/sensor/st/lps2xdf/lps22df.c b/drivers/sensor/st/lps2xdf/lps22df.c index d18536984c486..afd0c4dd2bc08 100644 --- a/drivers/sensor/st/lps2xdf/lps22df.c +++ b/drivers/sensor/st/lps2xdf/lps22df.c @@ -227,7 +227,7 @@ int st_lps22df_init(const struct device *dev) /* Select bus interface */ lps22df_bus_mode_get(ctx, &bus_mode); - bus_mode.filter = LPS22DF_AUTO; + bus_mode.filter = LPS22DF_FILTER_AUTO; bus_mode.interface = LPS22DF_SEL_BY_HW; lps22df_bus_mode_set(ctx, &bus_mode); } diff --git a/drivers/sensor/st/lps2xdf/lps2xdf.c b/drivers/sensor/st/lps2xdf/lps2xdf.c index 3a7392c82762f..480f49255db15 100644 --- a/drivers/sensor/st/lps2xdf/lps2xdf.c +++ b/drivers/sensor/st/lps2xdf/lps2xdf.c @@ -136,7 +136,7 @@ static int lps2xdf_sample_fetch(const struct device *dev, enum sensor_channel ch const struct lps2xdf_config *const cfg = dev->config; const struct lps2xdf_chip_api *chip_api = cfg->chip_api; - __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + __ASSERT_NO_MSG(chan == SENSOR_CHAN_PRESS || chan == SENSOR_CHAN_ALL); return chip_api->sample_fetch(dev, chan); } diff --git a/drivers/sensor/st/lps2xdf/lps2xdf_trigger.c b/drivers/sensor/st/lps2xdf/lps2xdf_trigger.c index de51ba14e6ef4..de719731ec7d8 100644 --- a/drivers/sensor/st/lps2xdf/lps2xdf_trigger.c +++ b/drivers/sensor/st/lps2xdf/lps2xdf_trigger.c @@ -179,7 +179,7 @@ int lps2xdf_init_interrupt(const struct device *dev, enum sensor_variant variant #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) ||\ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c)) - if (cfg->i3c.bus == NULL) { + if (cfg->i3c.bus != NULL) { /* I3C IBI does not utilize GPIO interrupt. */ lps2xdf->i3c_dev->ibi_cb = lps2xdf_ibi_cb; diff --git a/drivers/sensor/st/lsm6dso/Kconfig b/drivers/sensor/st/lsm6dso/Kconfig index aa0f189033034..c0c1b7fd9942b 100644 --- a/drivers/sensor/st/lsm6dso/Kconfig +++ b/drivers/sensor/st/lsm6dso/Kconfig @@ -6,10 +6,12 @@ menuconfig LSM6DSO bool "LSM6DSO I2C/SPI accelerometer and gyroscope Chip" default y - depends on DT_HAS_ST_LSM6DSO_ENABLED + depends on DT_HAS_ST_LSM6DSO_ENABLED || DT_HAS_ST_LSM6DSO32_ENABLED depends on ZEPHYR_HAL_ST_MODULE - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSO),i2c) - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSO),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSO),i2c) || \ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSO32),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSO),spi) || \ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSO32),spi) select HAS_STMEMSC select USE_STDC_LSM6DSO help diff --git a/drivers/sensor/st/lsm6dso/lsm6dso.c b/drivers/sensor/st/lsm6dso/lsm6dso.c index 07b9a69c55f5c..d3cdaf9dfd2c6 100644 --- a/drivers/sensor/st/lsm6dso/lsm6dso.c +++ b/drivers/sensor/st/lsm6dso/lsm6dso.c @@ -8,8 +8,6 @@ * https://www.st.com/resource/en/datasheet/lsm6dso.pdf */ -#define DT_DRV_COMPAT st_lsm6dso - #include #include #include @@ -88,21 +86,6 @@ static int lsm6dso_gyro_range_to_fs_val(int32_t range) return -EINVAL; } -static inline int lsm6dso_reboot(const struct device *dev) -{ - const struct lsm6dso_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - - if (lsm6dso_boot_set(ctx, 1) < 0) { - return -EIO; - } - - /* Wait sensor turn-on time as per datasheet */ - k_busy_wait(35 * USEC_PER_MSEC); - - return 0; -} - static int lsm6dso_accel_set_fs_raw(const struct device *dev, uint8_t fs) { const struct lsm6dso_config *cfg = dev->config; @@ -867,21 +850,17 @@ static int lsm6dso_init(const struct device *dev) return 0; } -#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 -#warning "LSM6DSO driver enabled without any devices" -#endif - /* * Device creation macro, shared by LSM6DSO_DEFINE_SPI() and * LSM6DSO_DEFINE_I2C(). */ -#define LSM6DSO_DEVICE_INIT(inst) \ +#define LSM6DSO_DEVICE_INIT(inst, model) \ SENSOR_DEVICE_DT_INST_DEFINE(inst, \ lsm6dso_init, \ NULL, \ - &lsm6dso_data_##inst, \ - &lsm6dso_config_##inst, \ + &model##_data_##inst, \ + &model##_config_##inst, \ POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, \ &lsm6dso_driver_api); @@ -917,9 +896,9 @@ static int lsm6dso_init(const struct device *dev) COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios), \ (LSM6DSO_CFG_IRQ(inst)), ()) -#define LSM6DSO_CONFIG_SPI(inst) \ +#define LSM6DSO_CONFIG_SPI(inst, model) \ { \ - STMEMSC_CTX_SPI(&lsm6dso_config_##inst.stmemsc_cfg), \ + STMEMSC_CTX_SPI(&model##_config_##inst.stmemsc_cfg), \ .stmemsc_cfg = { \ .spi = SPI_DT_SPEC_INST_GET(inst, \ LSM6DSO_SPI_OP, \ @@ -932,9 +911,9 @@ static int lsm6dso_init(const struct device *dev) * Instantiation macros used when a device is on an I2C bus. */ -#define LSM6DSO_CONFIG_I2C(inst) \ +#define LSM6DSO_CONFIG_I2C(inst, model) \ { \ - STMEMSC_CTX_I2C(&lsm6dso_config_##inst.stmemsc_cfg), \ + STMEMSC_CTX_I2C(&model##_config_##inst.stmemsc_cfg), \ .stmemsc_cfg = { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ }, \ @@ -946,12 +925,18 @@ static int lsm6dso_init(const struct device *dev) * bus-specific macro at preprocessor time. */ -#define LSM6DSO_DEFINE(inst) \ - static struct lsm6dso_data lsm6dso_data_##inst; \ - static const struct lsm6dso_config lsm6dso_config_##inst = \ +#define LSM6DSO_DEFINE(inst, model) \ + static struct lsm6dso_data model##_data_##inst; \ + static const struct lsm6dso_config model##_config_##inst = \ COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ - (LSM6DSO_CONFIG_SPI(inst)), \ - (LSM6DSO_CONFIG_I2C(inst))); \ - LSM6DSO_DEVICE_INIT(inst) + (LSM6DSO_CONFIG_SPI(inst, model)), \ + (LSM6DSO_CONFIG_I2C(inst, model))); \ + LSM6DSO_DEVICE_INIT(inst, model) + +#define DT_DRV_COMPAT st_lsm6dso +DT_INST_FOREACH_STATUS_OKAY_VARGS(LSM6DSO_DEFINE, lsm6dso) +#undef DT_DRV_COMPAT -DT_INST_FOREACH_STATUS_OKAY(LSM6DSO_DEFINE) +#define DT_DRV_COMPAT st_lsm6dso32 +DT_INST_FOREACH_STATUS_OKAY_VARGS(LSM6DSO_DEFINE, lsm6dso32) +#undef DT_DRV_COMPAT diff --git a/drivers/sensor/st/lsm6dso/lsm6dso.h b/drivers/sensor/st/lsm6dso/lsm6dso.h index c7f7279d3baf2..a721f0244c17a 100644 --- a/drivers/sensor/st/lsm6dso/lsm6dso.h +++ b/drivers/sensor/st/lsm6dso/lsm6dso.h @@ -19,13 +19,15 @@ #include #include "lsm6dso_reg.h" -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso, spi) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso32, spi) #include -#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ +#endif -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso32, i2c) #include -#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ +#endif #define LSM6DSO_EN_BIT 0x01 #define LSM6DSO_DIS_BIT 0x00 @@ -39,10 +41,12 @@ struct lsm6dso_config { stmdev_ctx_t ctx; union { -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso32, i2c) const struct i2c_dt_spec i2c; #endif -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso, spi) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso32, spi) const struct spi_dt_spec spi; #endif } stmemsc_cfg; diff --git a/drivers/sensor/st/lsm6dso16is/lsm6dso16is.c b/drivers/sensor/st/lsm6dso16is/lsm6dso16is.c index 1c4113c7c3504..1171d7fa380e3 100644 --- a/drivers/sensor/st/lsm6dso16is/lsm6dso16is.c +++ b/drivers/sensor/st/lsm6dso16is/lsm6dso16is.c @@ -80,21 +80,6 @@ static int lsm6dso16is_gyro_range_to_fs_val(int32_t range) return -EINVAL; } -static inline int lsm6dso16is_reboot(const struct device *dev) -{ - const struct lsm6dso16is_config *cfg = dev->config; - stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; - - if (lsm6dso16is_boot_set(ctx, 1) < 0) { - return -EIO; - } - - /* Wait sensor turn-on time as per datasheet */ - k_sleep(K_MSEC(35)); /* turn-on time in ms */ - - return 0; -} - static int lsm6dso16is_accel_set_fs_raw(const struct device *dev, uint8_t fs) { const struct lsm6dso16is_config *cfg = dev->config; diff --git a/drivers/sensor/st/lsm6dsv16x/Kconfig b/drivers/sensor/st/lsm6dsv16x/Kconfig index ae02dfd1e2ea3..9d41fdda25599 100644 --- a/drivers/sensor/st/lsm6dsv16x/Kconfig +++ b/drivers/sensor/st/lsm6dsv16x/Kconfig @@ -4,11 +4,12 @@ # SPDX-License-Identifier: Apache-2.0 menuconfig LSM6DSV16X - bool "LSM6DSV16X I2C/SPI accelerometer and gyroscope Chip" + bool "LSM6DSV16X I3C/I2C/SPI accelerometer and gyroscope Chip" default y depends on DT_HAS_ST_LSM6DSV16X_ENABLED depends on ZEPHYR_HAL_ST_MODULE select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV16X),i2c) + select I3C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV16X),i3c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV16X),spi) select HAS_STMEMSC select USE_STDC_LSM6DSV16X @@ -23,7 +24,7 @@ config LSM6DSV16X_STREAM bool "Use hardware FIFO to stream data" select LSM6DSV16X_TRIGGER default y - depends on I2C_RTIO || SPI_RTIO + depends on I2C_RTIO || SPI_RTIO || I3C_RTIO depends on SENSOR_ASYNC_API help Use this config option to enable streaming sensor data via RTIO subsystem. @@ -40,16 +41,18 @@ config LSM6DSV16X_TRIGGER_NONE config LSM6DSV16X_TRIGGER_GLOBAL_THREAD bool "Use global thread" - depends on GPIO + depends on GPIO || I3C depends on $(dt_compat_any_has_prop,$(DT_COMPAT_ST_LSM6DSV16X),int1-gpios) ||\ - $(dt_compat_any_has_prop,$(DT_COMPAT_ST_LSM6DSV16X),int2-gpios) + $(dt_compat_any_has_prop,$(DT_COMPAT_ST_LSM6DSV16X),int2-gpios) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV16X),i3c) select LSM6DSV16X_TRIGGER config LSM6DSV16X_TRIGGER_OWN_THREAD bool "Use own thread" - depends on GPIO + depends on GPIO || I3C depends on $(dt_compat_any_has_prop,$(DT_COMPAT_ST_LSM6DSV16X),int1-gpios) ||\ - $(dt_compat_any_has_prop,$(DT_COMPAT_ST_LSM6DSV16X),int2-gpios) + $(dt_compat_any_has_prop,$(DT_COMPAT_ST_LSM6DSV16X),int2-gpios) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV16X),i3c) select LSM6DSV16X_TRIGGER endchoice diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c index cd89d94b64b04..4dadcebeff726 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c @@ -14,16 +14,29 @@ #include #include #include +#include #include #include #include +#include #include "lsm6dsv16x.h" #include "lsm6dsv16x_decoder.h" #include "lsm6dsv16x_rtio.h" LOG_MODULE_REGISTER(LSM6DSV16X, CONFIG_SENSOR_LOG_LEVEL); +bool lsm6dsv16x_is_active(const struct device *dev) +{ +#if defined(CONFIG_PM_DEVICE) + enum pm_device_state state; + (void)pm_device_state_get(dev, &state); + return (state == PM_DEVICE_STATE_ACTIVE); +#else + return true; +#endif /* CONFIG_PM_DEVICE*/ +} + /* * values taken from lsm6dsv16x_data_rate_t in hal/st module. The mode/accuracy * should be selected through accel-odr property in DT @@ -221,6 +234,55 @@ static int lsm6dsv16x_accel_range_set(const struct device *dev, int32_t range) return 0; } +#define LSM6DSV16X_WU_INACT_THS_W_MAX 5 +#define LSM6DSV16X_WAKE_UP_THS_MAX 0x3FU +static const float wu_inact_ths_w_lsb[] = {7.8125f, 15.625f, 31.25f, 62.5f, 125.0f, 250.0f}; + +static int lsm6dsv16x_accel_wake_threshold_set(const struct device *dev, + const struct sensor_value *val) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv16x_act_thresholds_t thresholds; + + if (lsm6dsv16x_act_thresholds_get(ctx, &thresholds) < 0) { + LOG_DBG("failed to get thresholds"); + return -EIO; + } + + float val_mg = sensor_ms2_to_ug(val) / 1000.0f; + + thresholds.inactivity_cfg.wu_inact_ths_w = LSM6DSV16X_WU_INACT_THS_W_MAX; + thresholds.threshold = LSM6DSV16X_WAKE_UP_THS_MAX; + + for (uint8_t i = 0; i <= LSM6DSV16X_WU_INACT_THS_W_MAX; i++) { + if (val_mg < (wu_inact_ths_w_lsb[i] * (float)LSM6DSV16X_WAKE_UP_THS_MAX)) { + thresholds.inactivity_cfg.wu_inact_ths_w = i; + thresholds.threshold = (uint8_t)(val_mg / wu_inact_ths_w_lsb[i]); + break; + } + } + + return lsm6dsv16x_act_thresholds_set(ctx, &thresholds); +} + +static int lsm6dsv16x_accel_wake_duration_set(const struct device *dev, + const struct sensor_value *val) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv16x_act_thresholds_t thresholds; + + if (lsm6dsv16x_act_thresholds_get(ctx, &thresholds) < 0) { + LOG_DBG("failed to get thresholds"); + return -EIO; + } + + thresholds.duration = MIN(val->val1, 3); + + return lsm6dsv16x_act_thresholds_set(ctx, &thresholds); +} + static int lsm6dsv16x_accel_config(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, @@ -235,6 +297,10 @@ static int lsm6dsv16x_accel_config(const struct device *dev, return lsm6dsv16x_accel_range_set(dev, sensor_ms2_to_g(val)); case SENSOR_ATTR_SAMPLING_FREQUENCY: return lsm6dsv16x_accel_odr_set(dev, val->val1); + case SENSOR_ATTR_SLOPE_TH: + return lsm6dsv16x_accel_wake_threshold_set(dev, val); + case SENSOR_ATTR_SLOPE_DUR: + return lsm6dsv16x_accel_wake_duration_set(dev, val); case SENSOR_ATTR_CONFIGURATION: switch (val->val1) { case 0: /* High Performance */ @@ -361,6 +427,10 @@ static int lsm6dsv16x_attr_set(const struct device *dev, struct lsm6dsv16x_data *data = dev->data; #endif /* CONFIG_LSM6DSV16X_SENSORHUB */ + if (!lsm6dsv16x_is_active(dev)) { + return -EBUSY; + } + switch (chan) { case SENSOR_CHAN_ACCEL_XYZ: return lsm6dsv16x_accel_config(dev, chan, attr, val); @@ -385,6 +455,43 @@ static int lsm6dsv16x_attr_set(const struct device *dev, return 0; } +static int lsm6dsv16x_accel_wake_threshold_get(const struct device *dev, struct sensor_value *val) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv16x_act_thresholds_t thresholds; + float val_mg; + + if (lsm6dsv16x_act_thresholds_get(ctx, &thresholds) < 0) { + LOG_DBG("failed to get thresholds"); + return -EIO; + } + + val_mg = wu_inact_ths_w_lsb[thresholds.inactivity_cfg.wu_inact_ths_w]; + val_mg *= (float)thresholds.threshold; + + sensor_ug_to_ms2(1000.0f * val_mg, val); + + return 0; +} + +static int lsm6dsv16x_accel_wake_duration_get(const struct device *dev, struct sensor_value *val) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv16x_act_thresholds_t thresholds; + + if (lsm6dsv16x_act_thresholds_get(ctx, &thresholds) < 0) { + LOG_DBG("failed to get thresholds"); + return -EIO; + } + + val->val1 = thresholds.duration; + val->val2 = 0; + + return 0; +} + static int lsm6dsv16x_accel_get_config(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, @@ -412,6 +519,10 @@ static int lsm6dsv16x_accel_get_config(const struct device *dev, val->val2 = 0; break; } + case SENSOR_ATTR_SLOPE_TH: + return lsm6dsv16x_accel_wake_threshold_get(dev, val); + case SENSOR_ATTR_SLOPE_DUR: + return lsm6dsv16x_accel_wake_duration_get(dev, val); case SENSOR_ATTR_CONFIGURATION: { lsm6dsv16x_xl_mode_t mode; @@ -512,11 +623,13 @@ static int lsm6dsv16x_gyro_get_config(const struct device *dev, return 0; } -static int lsm6dsv16x_attr_get(const struct device *dev, - enum sensor_channel chan, - enum sensor_attribute attr, - struct sensor_value *val) +static int lsm6dsv16x_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) { + if (!lsm6dsv16x_is_active(dev)) { + return -EBUSY; + } + switch (chan) { case SENSOR_CHAN_ACCEL_XYZ: return lsm6dsv16x_accel_get_config(dev, chan, attr, val); @@ -593,6 +706,10 @@ static int lsm6dsv16x_sample_fetch(const struct device *dev, struct lsm6dsv16x_data *data = dev->data; #endif /* CONFIG_LSM6DSV16X_SENSORHUB */ + if (!lsm6dsv16x_is_active(dev)) { + return -EBUSY; + } + switch (chan) { case SENSOR_CHAN_ACCEL_XYZ: lsm6dsv16x_sample_fetch_accel(dev); @@ -864,6 +981,10 @@ static int lsm6dsv16x_channel_get(const struct device *dev, { struct lsm6dsv16x_data *data = dev->data; + if (!lsm6dsv16x_is_active(dev)) { + return -EBUSY; + } + switch (chan) { case SENSOR_CHAN_ACCEL_X: case SENSOR_CHAN_ACCEL_Y: @@ -951,6 +1072,20 @@ static int lsm6dsv16x_init_chip(const struct device *dev) uint8_t chip_id; uint8_t odr, fs; +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (cfg->i3c.bus != NULL) { + /* + * Need to grab the pointer to the I3C device descriptor + * before we can talk to the sensor. + */ + lsm6dsv16x->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id); + if (lsm6dsv16x->i3c_dev == NULL) { + LOG_ERR("Cannot find I3C device descriptor"); + return -ENODEV; + } + } +#endif + /* All registers except 0x01 are different between banks, including the WHO_AM_I * register and the register used for a SW reset. If the lsm6dsv16x wasn't on the user * bank when it reset, then both the chip id check and the sw reset will fail unless we @@ -973,13 +1108,26 @@ static int lsm6dsv16x_init_chip(const struct device *dev) return -EIO; } - /* reset device (sw_por) */ - if (lsm6dsv16x_reset_set(ctx, LSM6DSV16X_GLOBAL_RST) < 0) { - return -EIO; - } + /* Resetting the whole device while using I3C will also reset the DA, therefore perform + * only a software reset if the bus is I3C. It should be assumed that the device was + * already fully reset by the I3C CCC RSTACT (whole chip) done as apart of the I3C Bus + * initialization. + */ + if (ON_I3C_BUS(cfg)) { + /* Restore default configuration */ + lsm6dsv16x_reset_set(ctx, LSM6DSV16X_RESTORE_CAL_PARAM); + + /* wait 150us as reported in AN5763 */ + k_sleep(K_USEC(150)); + } else { + /* reset device (sw_por) */ + if (lsm6dsv16x_reset_set(ctx, LSM6DSV16X_GLOBAL_RST) < 0) { + return -EIO; + } - /* wait 30ms as reported in AN5763 */ - k_sleep(K_MSEC(30)); + /* wait 30ms as reported in AN5763 */ + k_sleep(K_MSEC(30)); + } fs = cfg->accel_range; LOG_DBG("accel range is %d", fs); @@ -1012,6 +1160,23 @@ static int lsm6dsv16x_init_chip(const struct device *dev) return -EIO; } +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (IS_ENABLED(CONFIG_LSM6DSV16X_STREAM) && (ON_I3C_BUS(cfg))) { + /* + * Set MRL to the Max Size of the FIFO so the entire FIFO can be read + * out at once + */ + struct i3c_ccc_mrl setmrl = { + .len = 0x0700, + .ibi_len = lsm6dsv16x->i3c_dev->data_length.max_ibi, + }; + if (i3c_ccc_do_setmrl(lsm6dsv16x->i3c_dev, &setmrl) < 0) { + LOG_ERR("failed to set mrl"); + return -EIO; + } + } +#endif + if (lsm6dsv16x_block_data_update_set(ctx, 1) < 0) { LOG_DBG("failed to set BDU mode"); return -EIO; @@ -1055,6 +1220,46 @@ static int lsm6dsv16x_init(const struct device *dev) return 0; } +#if defined(CONFIG_PM_DEVICE) +static int lsm6dsv16x_pm_action(const struct device *dev, enum pm_device_action action) +{ + struct lsm6dsv16x_data *data = dev->data; + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + int ret = 0; + + LOG_DBG("PM action: %d", (int)action); + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + if (lsm6dsv16x_xl_data_rate_set(ctx, data->accel_freq) < 0) { + LOG_ERR("failed to set accelerometer odr %d", (int)data->accel_freq); + ret = -EIO; + } + if (lsm6dsv16x_gy_data_rate_set(ctx, data->gyro_freq) < 0) { + LOG_ERR("failed to set gyroscope odr %d", (int)data->gyro_freq); + ret = -EIO; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + if (lsm6dsv16x_xl_data_rate_set(ctx, LSM6DSV16X_DT_ODR_OFF) < 0) { + LOG_ERR("failed to disable accelerometer"); + ret = -EIO; + } + if (lsm6dsv16x_gy_data_rate_set(ctx, LSM6DSV16X_DT_ODR_OFF) < 0) { + LOG_ERR("failed to disable gyroscope"); + ret = -EIO; + } + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 #warning "LSM6DSV16X driver enabled without any devices" #endif @@ -1064,15 +1269,12 @@ static int lsm6dsv16x_init(const struct device *dev) * LSM6DSV16X_DEFINE_I2C(). */ -#define LSM6DSV16X_DEVICE_INIT(inst) \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, \ - lsm6dsv16x_init, \ - NULL, \ - &lsm6dsv16x_data_##inst, \ - &lsm6dsv16x_config_##inst, \ - POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, \ - &lsm6dsv16x_driver_api); +#define LSM6DSV16X_DEVICE_INIT(inst) \ + PM_DEVICE_DT_INST_DEFINE(inst, lsm6dsv16x_pm_action); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, lsm6dsv16x_init, PM_DEVICE_DT_INST_GET(inst), \ + &lsm6dsv16x_data_##inst, &lsm6dsv16x_config_##inst, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &lsm6dsv16x_driver_api); #ifdef CONFIG_LSM6DSV16X_TRIGGER #define LSM6DSV16X_CFG_IRQ(inst) \ @@ -1094,6 +1296,8 @@ static int lsm6dsv16x_init(const struct device *dev) (.fifo_wtm = DT_INST_PROP(inst, fifo_watermark), \ .accel_batch = DT_INST_PROP(inst, accel_fifo_batch_rate), \ .gyro_batch = DT_INST_PROP(inst, gyro_fifo_batch_rate), \ + .sflp_odr = DT_INST_PROP(inst, sflp_odr), \ + .sflp_fifo_en = DT_INST_PROP(inst, sflp_fifo_enable), \ .temp_batch = DT_INST_PROP(inst, temp_fifo_batch_rate),)) \ IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ @@ -1164,15 +1368,55 @@ static int lsm6dsv16x_init(const struct device *dev) static const struct lsm6dsv16x_config lsm6dsv16x_config_##inst = \ LSM6DSV16X_CONFIG_I2C(inst); \ +/* + * Instantiation macros used when a device is on an I3C bus. + */ + +#define LSM6DSV16X_I3C_RTIO_DEFINE(inst) \ + I3C_DT_IODEV_DEFINE(lsm6dsv16x_i3c_iodev_##inst, DT_DRV_INST(inst)); \ + RTIO_DEFINE(lsm6dsv16x_rtio_ctx_##inst, 4, 4); + +#define LSM6DSV16X_CONFIG_I3C(inst) \ + { \ + STMEMSC_CTX_I3C(&lsm6dsv16x_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .i3c = &lsm6dsv16x_data_##inst.i3c_dev, \ + }, \ + .i3c.bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .i3c.dev_id = I3C_DEVICE_ID_DT_INST(inst), \ + IF_ENABLED(CONFIG_LSM6DSV16X_TRIGGER, \ + (.int_en_i3c = DT_INST_PROP(inst, int_en_i3c), \ + .bus_act_sel = DT_INST_ENUM_IDX(inst, bus_act_sel_us),)) \ + LSM6DSV16X_CONFIG_COMMON(inst) \ + } + +#define LSM6DSV16X_DEFINE_I3C(inst) \ + IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, (LSM6DSV16X_I3C_RTIO_DEFINE(inst))); \ + static struct lsm6dsv16x_data lsm6dsv16x_data_##inst = { \ + IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, \ + (.rtio_ctx = &lsm6dsv16x_rtio_ctx_##inst, \ + .iodev = &lsm6dsv16x_i3c_iodev_##inst, \ + .bus_type = BUS_I3C,)) \ + }; \ + static const struct lsm6dsv16x_config lsm6dsv16x_config_##inst = \ + LSM6DSV16X_CONFIG_I3C(inst); \ + +#define LSM6DSV16X_DEFINE_I3C_OR_I2C(inst) \ + COND_CODE_0(DT_INST_PROP_BY_IDX(inst, reg, 1), \ + (LSM6DSV16X_DEFINE_I2C(inst)), \ + (LSM6DSV16X_DEFINE_I3C(inst))) + /* * Main instantiation macro. Use of COND_CODE_1() selects the right * bus-specific macro at preprocessor time. */ -#define LSM6DSV16X_DEFINE(inst) \ - COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ - (LSM6DSV16X_DEFINE_SPI(inst)), \ - (LSM6DSV16X_DEFINE_I2C(inst))); \ - LSM6DSV16X_DEVICE_INIT(inst) +#define LSM6DSV16X_DEFINE(inst) \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (LSM6DSV16X_DEFINE_SPI(inst)), \ + (COND_CODE_1(DT_INST_ON_BUS(inst, i3c), \ + (LSM6DSV16X_DEFINE_I3C_OR_I2C(inst)), \ + (LSM6DSV16X_DEFINE_I2C(inst))))); \ + LSM6DSV16X_DEVICE_INIT(inst) DT_INST_FOREACH_STATUS_OKAY(LSM6DSV16X_DEFINE) diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h index 79daeb476b0b8..343d1befbc2d4 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h @@ -26,6 +26,20 @@ #include #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) +#include +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) */ + +bool lsm6dsv16x_is_active(const struct device *dev); + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + #define ON_I3C_BUS(cfg) (cfg->i3c.bus != NULL) + #define I3C_INT_PIN(cfg) (cfg->int_en_i3c) +#else + #define ON_I3C_BUS(cfg) (false) + #define I3C_INT_PIN(cfg) (false) +#endif + #define LSM6DSV16X_EN_BIT 0x01 #define LSM6DSV16X_DIS_BIT 0x00 @@ -46,6 +60,9 @@ struct lsm6dsv16x_config { #endif #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) const struct spi_dt_spec spi; +#endif +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct i3c_device_desc **i3c; #endif } stmemsc_cfg; uint8_t accel_pm; @@ -60,13 +77,26 @@ struct lsm6dsv16x_config { uint8_t accel_batch : 4; uint8_t gyro_batch : 4; uint8_t temp_batch : 2; + uint8_t sflp_odr : 3; + uint8_t sflp_fifo_en : 3; #endif #ifdef CONFIG_LSM6DSV16X_TRIGGER const struct gpio_dt_spec int1_gpio; const struct gpio_dt_spec int2_gpio; uint8_t drdy_pin; bool trig_enabled; +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + bool int_en_i3c; + lsm6dsv16x_i3c_ibi_time_t bus_act_sel; +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) */ #endif /* CONFIG_LSM6DSV16X_TRIGGER */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct { + const struct device *bus; + const struct i3c_device_id dev_id; + } i3c; +#endif }; union samples { @@ -78,6 +108,19 @@ union samples { #define LSM6DSV16X_SHUB_MAX_NUM_TARGETS 3 +struct lsm6dsv16x_ibi_payload { + uint8_t mdb; + uint8_t fifo_status1; + uint8_t fifo_status2; + uint8_t all_int_src; + uint8_t status_reg; + uint8_t status_reg_ois; + uint8_t status_master_main; + uint8_t emb_func_status; + uint8_t fsm_status; + uint8_t mlc_status; +} __packed; + struct lsm6dsv16x_data { const struct device *dev; int16_t acc[3]; @@ -118,8 +161,9 @@ struct lsm6dsv16x_data { uint8_t accel_batch_odr : 4; uint8_t gyro_batch_odr : 4; uint8_t temp_batch_odr : 2; - uint8_t bus_type : 1; /* I2C is 0, SPI is 1 */ - uint8_t reserved : 5; + uint8_t bus_type : 2; /* I2C is 0, SPI is 1, I3C is 2 */ + uint8_t sflp_batch_odr : 3; + uint8_t reserved : 1; #endif #ifdef CONFIG_LSM6DSV16X_TRIGGER @@ -130,22 +174,28 @@ struct lsm6dsv16x_data { const struct sensor_trigger *trig_drdy_acc; sensor_trigger_handler_t handler_drdy_gyr; const struct sensor_trigger *trig_drdy_gyr; - sensor_trigger_handler_t handler_drdy_temp; - const struct sensor_trigger *trig_drdy_temp; + sensor_trigger_handler_t handler_wakeup; + const struct sensor_trigger *trig_wakeup; #if defined(CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD) K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_LSM6DSV16X_THREAD_STACK_SIZE); struct k_thread thread; - struct k_sem gpio_sem; + struct k_sem intr_sem; #elif defined(CONFIG_LSM6DSV16X_TRIGGER_GLOBAL_THREAD) struct k_work work; #endif #endif /* CONFIG_LSM6DSV16X_TRIGGER */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct i3c_device_desc *i3c_dev; + struct lsm6dsv16x_ibi_payload ibi_payload; +#endif }; #ifdef CONFIG_LSM6DSV16X_STREAM #define BUS_I2C 0 #define BUS_SPI 1 +#define BUS_I3C 2 static inline uint8_t lsm6dsv16x_bus_reg(struct lsm6dsv16x_data *data, uint8_t x) { diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c index 8ebf6bc2137d7..1ea21ace988b9 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c @@ -51,8 +51,23 @@ static const uint32_t temp_period_ns[] = { [LSM6DSV16X_TEMP_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, }; #endif + +static const uint32_t sflp_period_ns[] = { + [LSM6DSV16X_DT_SFLP_ODR_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSV16X_DT_SFLP_ODR_AT_30Hz] = UINT32_C(1000000000) / 30, + [LSM6DSV16X_DT_SFLP_ODR_AT_60Hz] = UINT32_C(1000000000) / 60, + [LSM6DSV16X_DT_SFLP_ODR_AT_120Hz] = UINT32_C(1000000000) / 120, + [LSM6DSV16X_DT_SFLP_ODR_AT_240Hz] = UINT32_C(1000000000) / 240, + [LSM6DSV16X_DT_SFLP_ODR_AT_480Hz] = UINT32_C(1000000000) / 480, +}; #endif /* CONFIG_LSM6DSV16X_STREAM */ +/* + * Expand val to q31_t according to its range; this is achieved multiplying by 2^31/2^range. + */ +#define Q31_SHIFT_VAL(val, range) \ + (q31_t) (round((val) * ((int64_t)1 << (31 - (range))))) + /* * Expand micro_val (a generic micro unit) to q31_t according to its range; this is achieved * multiplying by 2^31/2^range. Then transform it to val. @@ -145,6 +160,7 @@ static int lsm6dsv16x_decoder_get_frame_count(const uint8_t *buffer, *frame_count = 1; return 0; default: + *frame_count = 0; return -ENOTSUP; } @@ -152,35 +168,22 @@ static int lsm6dsv16x_decoder_get_frame_count(const uint8_t *buffer, } #ifdef CONFIG_LSM6DSV16X_STREAM - *frame_count = data->fifo_count; -#endif - return 0; -} - -#ifdef CONFIG_LSM6DSV16X_STREAM -static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec chan_spec, - uint32_t *fit, uint16_t max_count, void *data_out) -{ const struct lsm6dsv16x_fifo_data *edata = (const struct lsm6dsv16x_fifo_data *)buffer; - const uint8_t *buffer_end, *tmp_buffer; - const struct lsm6dsv16x_decoder_header *header = &edata->header; - int count = 0; + const uint8_t *buffer_end; uint8_t fifo_tag; - uint16_t xl_count = 0, gy_count = 0; uint8_t tot_accel_fifo_words = 0, tot_gyro_fifo_words = 0; + uint8_t tot_sflp_gbias = 0, tot_sflp_gravity = 0, tot_sflp_game_rotation = 0; #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP) uint8_t tot_temp_fifo_words = 0; - uint16_t temp_count = 0; #endif buffer += sizeof(struct lsm6dsv16x_fifo_data); buffer_end = buffer + LSM6DSV16X_FIFO_SIZE(edata->fifo_count); /* count total FIFO word for each tag */ - tmp_buffer = buffer; - while (tmp_buffer < buffer_end) { - fifo_tag = (tmp_buffer[0] >> 3); + while (buffer < buffer_end) { + fifo_tag = (buffer[0] >> 3); switch (fifo_tag) { case LSM6DSV16X_XL_NC_TAG: @@ -194,13 +197,87 @@ static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec tot_temp_fifo_words++; break; #endif + case LSM6DSV16X_SFLP_GYROSCOPE_BIAS_TAG: + tot_sflp_gbias++; + break; + case LSM6DSV16X_SFLP_GRAVITY_VECTOR_TAG: + tot_sflp_gravity++; + break; + case LSM6DSV16X_SFLP_GAME_ROTATION_VECTOR_TAG: + tot_sflp_game_rotation++; + break; default: break; } - tmp_buffer += LSM6DSV16X_FIFO_ITEM_LEN; + buffer += LSM6DSV16X_FIFO_ITEM_LEN; + } + + switch (chan_spec.chan_type) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + *frame_count = tot_accel_fifo_words; + break; + + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + *frame_count = tot_gyro_fifo_words; + break; + +#if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP) + case SENSOR_CHAN_DIE_TEMP: + *frame_count = tot_temp_fifo_words; + break; +#endif + case SENSOR_CHAN_GAME_ROTATION_VECTOR: + *frame_count = tot_sflp_game_rotation; + break; + case SENSOR_CHAN_GRAVITY_VECTOR: + *frame_count = tot_sflp_gravity; + break; + case SENSOR_CHAN_GBIAS_XYZ: + *frame_count = tot_sflp_gbias; + break; + default: + *frame_count = 0; + break; + } +#endif + + return 0; +} + +#ifdef CONFIG_LSM6DSV16X_STREAM +static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + const struct lsm6dsv16x_fifo_data *edata = (const struct lsm6dsv16x_fifo_data *)buffer; + const uint8_t *buffer_end; + const struct lsm6dsv16x_decoder_header *header = &edata->header; + int count = 0; + uint8_t fifo_tag; + uint16_t xl_count = 0, gy_count = 0; + uint16_t tot_chan_fifo_words = 0; + +#if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP) + uint16_t temp_count = 0; +#endif + uint16_t game_rot_count = 0, gravity_count = 0, gbias_count = 0; + int ret; + + /* count total FIFO word for each tag */ + ret = lsm6dsv16x_decoder_get_frame_count(buffer, chan_spec, &tot_chan_fifo_words); + if (ret < 0) { + return 0; } + buffer += sizeof(struct lsm6dsv16x_fifo_data); + buffer_end = buffer + LSM6DSV16X_FIFO_SIZE(edata->fifo_count); + /* * Timestamp in header is set when FIFO threshold is reached, so * set time baseline going back in past according to total number @@ -209,17 +286,23 @@ static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec if (SENSOR_CHANNEL_IS_ACCEL(chan_spec.chan_type)) { ((struct sensor_data_header *)data_out)->base_timestamp_ns = edata->header.timestamp - - (tot_accel_fifo_words - 1) * accel_period_ns[edata->accel_batch_odr]; + (tot_chan_fifo_words - 1) * accel_period_ns[edata->accel_batch_odr]; } else if (SENSOR_CHANNEL_IS_GYRO(chan_spec.chan_type)) { ((struct sensor_data_header *)data_out)->base_timestamp_ns = edata->header.timestamp - - (tot_gyro_fifo_words - 1) * gyro_period_ns[edata->gyro_batch_odr]; + (tot_chan_fifo_words - 1) * gyro_period_ns[edata->gyro_batch_odr]; #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP) } else if (chan_spec.chan_type == SENSOR_CHAN_DIE_TEMP) { ((struct sensor_data_header *)data_out)->base_timestamp_ns = edata->header.timestamp - - (tot_temp_fifo_words - 1) * temp_period_ns[edata->temp_batch_odr]; + (tot_chan_fifo_words - 1) * temp_period_ns[edata->temp_batch_odr]; #endif + } else if (chan_spec.chan_type == SENSOR_CHAN_GRAVITY_VECTOR || + chan_spec.chan_type == SENSOR_CHAN_GAME_ROTATION_VECTOR || + chan_spec.chan_type == SENSOR_CHAN_GBIAS_XYZ) { + ((struct sensor_data_header *)data_out)->base_timestamp_ns = + edata->header.timestamp - + (tot_chan_fifo_words - 1) * sflp_period_ns[edata->sflp_batch_odr]; } while (count < max_count && buffer < buffer_end) { @@ -324,6 +407,126 @@ static int lsm6dsv16x_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec break; } #endif + case LSM6DSV16X_SFLP_GAME_ROTATION_VECTOR_TAG: { + struct sensor_game_rotation_vector_data *out = data_out; + union { float32_t f; uint32_t i; } x, y, z; + float32_t w, sumsq; + + game_rot_count++; + if ((uintptr_t)buffer < *fit) { + /* This frame was already decoded, move on to the next frame */ + buffer = frame_end; + continue; + } + + if (chan_spec.chan_type != SENSOR_CHAN_GAME_ROTATION_VECTOR) { + buffer = frame_end; + continue; + } + + out->readings[count].timestamp_delta = + (game_rot_count - 1) * sflp_period_ns[edata->sflp_batch_odr]; + + x.i = lsm6dsv16x_from_f16_to_f32(buffer[1] | (buffer[2] << 8)); + y.i = lsm6dsv16x_from_f16_to_f32(buffer[3] | (buffer[4] << 8)); + z.i = lsm6dsv16x_from_f16_to_f32(buffer[5] | (buffer[6] << 8)); + + sumsq = powf(x.f, 2) + powf(y.f, 2) + powf(z.f, 2); + + /* + * Theoretically sumsq should never be greater than 1, but due to + * lack of precision it might happen. So, add a software correction + * which consists in normalizing the (x, y, z) vector. + */ + if (sumsq > 1.0f) { + float n = sqrtf(sumsq); + + x.f /= n; + y.f /= n; + z.f /= n; + sumsq = 1.0f; + } + + /* unity vector quaternions */ + w = sqrtf(1.0f - sumsq); + + /* + * Quaternions are numbers between -1 and 1. So let's select the signed + * Q0.31 format (m = 0, n (fractional bits) == 31) + */ + out->shift = 0; + + out->readings[count].x = Q31_SHIFT_VAL(x.f, out->shift); + out->readings[count].y = Q31_SHIFT_VAL(y.f, out->shift); + out->readings[count].z = Q31_SHIFT_VAL(z.f, out->shift); + out->readings[count].w = Q31_SHIFT_VAL(w, out->shift); + + break; + } + + case LSM6DSV16X_SFLP_GYROSCOPE_BIAS_TAG: { + struct sensor_three_axis_data *out = data_out; + int16_t x, y, z; + const int32_t scale = gyro_scaler[LSM6DSV16X_DT_FS_125DPS]; + + gbias_count++; + if ((uintptr_t)buffer < *fit) { + /* This frame was already decoded, move on to the next frame */ + buffer = frame_end; + continue; + } + + if (chan_spec.chan_type != SENSOR_CHAN_GBIAS_XYZ) { + buffer = frame_end; + continue; + } + + out->readings[count].timestamp_delta = + (gbias_count - 1) * sflp_period_ns[edata->sflp_batch_odr]; + + x = buffer[1] | (buffer[2] << 8); + y = buffer[3] | (buffer[4] << 8); + z = buffer[5] | (buffer[6] << 8); + + out->shift = gyro_range[LSM6DSV16X_DT_FS_125DPS]; + + out->readings[count].x = Q31_SHIFT_MICROVAL(scale * x, out->shift); + out->readings[count].y = Q31_SHIFT_MICROVAL(scale * y, out->shift); + out->readings[count].z = Q31_SHIFT_MICROVAL(scale * z, out->shift); + break; + } + + case LSM6DSV16X_SFLP_GRAVITY_VECTOR_TAG: { + struct sensor_three_axis_data *out = data_out; + float32_t x, y, z; + + gravity_count++; + if ((uintptr_t)buffer < *fit) { + /* This frame was already decoded, move on to the next frame */ + buffer = frame_end; + continue; + } + + if (chan_spec.chan_type != SENSOR_CHAN_GRAVITY_VECTOR) { + buffer = frame_end; + continue; + } + + out->readings[count].timestamp_delta = + (gravity_count - 1) * sflp_period_ns[edata->sflp_batch_odr]; + + x = lsm6dsv16x_from_sflp_to_mg(buffer[1] | (buffer[2] << 8)); + y = lsm6dsv16x_from_sflp_to_mg(buffer[3] | (buffer[4] << 8)); + z = lsm6dsv16x_from_sflp_to_mg(buffer[5] | (buffer[6] << 8)); + + out->shift = 12; + + out->readings[count].x = Q31_SHIFT_VAL(x, out->shift); + out->readings[count].y = Q31_SHIFT_VAL(y, out->shift); + out->readings[count].z = Q31_SHIFT_VAL(z, out->shift); + break; + } + default: /* skip unhandled FIFO tag */ buffer = frame_end; diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.h b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.h index 1a02af51e720c..22553c9665174 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.h +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.h @@ -30,7 +30,8 @@ struct lsm6dsv16x_fifo_data { uint16_t gyro_batch_odr: 4; uint16_t accel_batch_odr: 4; uint16_t temp_batch_odr: 4; - uint16_t reserved_2: 4; + uint16_t sflp_batch_odr: 3; + uint16_t reserved_2: 1; } __attribute__((__packed__)); struct lsm6dsv16x_rtio_data { diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio.c index c43f0c9b89853..b039ad2f5bbe8 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio.c @@ -11,6 +11,7 @@ #include "lsm6dsv16x_rtio.h" #include "lsm6dsv16x_decoder.h" #include +#include #include LOG_MODULE_REGISTER(LSM6DSV16X_RTIO, CONFIG_SENSOR_LOG_LEVEL); @@ -21,6 +22,7 @@ static void lsm6dsv16x_submit_sample(const struct device *dev, struct rtio_iodev const struct sensor_chan_spec *const channels = cfg->channels; const size_t num_channels = cfg->count; uint32_t min_buf_len = sizeof(struct lsm6dsv16x_rtio_data); + uint64_t cycles; int rc = 0; uint8_t *buf; uint32_t buf_len; @@ -112,10 +114,17 @@ static void lsm6dsv16x_submit_sample(const struct device *dev, struct rtio_iodev } } + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(iodev_sqe, rc); + goto err; + } + edata->header.is_fifo = false; edata->header.accel_fs = data->accel_fs; edata->header.gyro_fs = data->gyro_fs; - edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); rtio_iodev_sqe_ok(iodev_sqe, 0); @@ -144,6 +153,10 @@ void lsm6dsv16x_submit_sync(struct rtio_iodev_sqe *iodev_sqe) void lsm6dsv16x_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) { + if (!lsm6dsv16x_is_active(dev)) { + return; + } + struct rtio_work_req *req = rtio_work_req_alloc(); if (req == NULL) { diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c index 42537fb4f95ae..b2b1614977921 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c @@ -13,6 +13,7 @@ #include "lsm6dsv16x.h" #include "lsm6dsv16x_decoder.h" #include +#include #include LOG_MODULE_DECLARE(LSM6DSV16X_RTIO); @@ -31,6 +32,8 @@ static void lsm6dsv16x_config_fifo(const struct device *dev, uint8_t fifo_irq) lsm6dsv16x_fifo_gy_batch_t gy_batch = LSM6DSV16X_DT_GY_NOT_BATCHED; lsm6dsv16x_fifo_temp_batch_t temp_batch = LSM6DSV16X_DT_TEMP_NOT_BATCHED; lsm6dsv16x_fifo_mode_t fifo_mode = LSM6DSV16X_BYPASS_MODE; + lsm6dsv16x_sflp_data_rate_t sflp_odr = LSM6DSV16X_SFLP_120Hz; + lsm6dsv16x_fifo_sflp_raw_t sflp_fifo = { 0 }; /* disable FIFO as first thing */ lsm6dsv16x_fifo_mode_set(ctx, LSM6DSV16X_BYPASS_MODE); @@ -48,6 +51,20 @@ static void lsm6dsv16x_config_fifo(const struct device *dev, uint8_t fifo_irq) fifo_mode = LSM6DSV16X_STREAM_MODE; fifo_wtm = config->fifo_wtm; + + if (config->sflp_fifo_en & LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION) { + sflp_fifo.game_rotation = 1; + } + + if (config->sflp_fifo_en & LSM6DSV16X_DT_SFLP_FIFO_GRAVITY) { + sflp_fifo.gravity = 1; + } + + if (config->sflp_fifo_en & LSM6DSV16X_DT_SFLP_FIFO_GBIAS) { + sflp_fifo.gbias = 1; + } + + sflp_odr = config->sflp_odr; } /* @@ -69,8 +86,13 @@ static void lsm6dsv16x_config_fifo(const struct device *dev, uint8_t fifo_irq) lsm6dsv16x->temp_batch_odr = temp_batch; #endif + lsm6dsv16x_sflp_data_rate_set(ctx, sflp_odr); + lsm6dsv16x->sflp_batch_odr = sflp_odr; + lsm6dsv16x_fifo_sflp_batch_set(ctx, sflp_fifo); + lsm6dsv16x_sflp_game_rotation_set(ctx, PROPERTY_ENABLE); + /* Set pin interrupt (fifo_th could be on or off) */ - if (config->drdy_pin == 1) { + if ((config->drdy_pin == 1) || (ON_I3C_BUS(config) && (!I3C_INT_PIN(config)))) { lsm6dsv16x_pin_int1_route_set(ctx, &pin_int); } else { lsm6dsv16x_pin_int2_route_set(ctx, &pin_int); @@ -80,10 +102,15 @@ static void lsm6dsv16x_config_fifo(const struct device *dev, uint8_t fifo_irq) void lsm6dsv16x_submit_stream(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) { struct lsm6dsv16x_data *lsm6dsv16x = dev->data; +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + const struct lsm6dsv16x_config *config = dev->config; +#endif const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; uint8_t fifo_irq = 0; - gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_DISABLE); + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_DISABLE); + } for (size_t i = 0; i < cfg->count; i++) { if (cfg->triggers[i].trigger == SENSOR_TRIG_FIFO_WATERMARK) { @@ -103,12 +130,17 @@ void lsm6dsv16x_submit_stream(const struct device *dev, struct rtio_iodev_sqe *i lsm6dsv16x->streaming_sqe = iodev_sqe; - gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); + } } static void lsm6dsv16x_complete_op_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) { const struct device *dev = arg; +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + const struct lsm6dsv16x_config *config = dev->config; +#endif struct lsm6dsv16x_data *lsm6dsv16x = dev->data; /* @@ -116,12 +148,17 @@ static void lsm6dsv16x_complete_op_cb(struct rtio *r, const struct rtio_sqe *sqe */ rtio_iodev_sqe_ok(sqe->userdata, 0); lsm6dsv16x->streaming_sqe = NULL; - gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); + } } static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) { const struct device *dev = arg; +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + const struct lsm6dsv16x_config *config = dev->config; +#endif struct lsm6dsv16x_data *lsm6dsv16x = dev->data; struct gpio_dt_spec *irq_gpio = lsm6dsv16x->drdy_gpio; struct rtio_iodev *iodev = lsm6dsv16x->iodev; @@ -168,7 +205,9 @@ static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, rtio_iodev_sqe_ok(sqe->userdata, 0); lsm6dsv16x->streaming_sqe = NULL; - gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + } return; } @@ -215,7 +254,9 @@ static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, sizeof(struct lsm6dsv16x_fifo_data), &buf, &buf_len) != 0) { rtio_iodev_sqe_err(lsm6dsv16x->streaming_sqe, -ENOMEM); lsm6dsv16x->streaming_sqe = NULL; - gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + } return; } @@ -230,7 +271,9 @@ static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, /* complete request with ok */ rtio_iodev_sqe_ok(lsm6dsv16x->streaming_sqe, 0); lsm6dsv16x->streaming_sqe = NULL; - gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + } if (data_opt == SENSOR_STREAM_DATA_DROP) { @@ -266,7 +309,9 @@ static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, LOG_ERR("Failed to get buffer"); rtio_iodev_sqe_err(lsm6dsv16x->streaming_sqe, -ENOMEM); lsm6dsv16x->streaming_sqe = NULL; - gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + } return; } @@ -283,6 +328,7 @@ static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP) .temp_batch_odr = lsm6dsv16x->temp_batch_odr, #endif + .sflp_batch_odr = lsm6dsv16x->sflp_batch_odr, }; memcpy(buf, &hdr, sizeof(hdr)); @@ -316,6 +362,8 @@ static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, read_fifo_dout_reg->flags = RTIO_SQE_CHAINED; if (lsm6dsv16x->bus_type == BUS_I2C) { read_fifo_dout_reg->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + } else if (lsm6dsv16x->bus_type == BUS_I3C) { + read_fifo_dout_reg->iodev_flags |= RTIO_IODEV_I3C_STOP | RTIO_IODEV_I3C_RESTART; } rtio_sqe_prep_callback_no_cqe(complete_op, lsm6dsv16x_complete_op_cb, (void *)dev, lsm6dsv16x->streaming_sqe); @@ -327,40 +375,70 @@ void lsm6dsv16x_stream_irq_handler(const struct device *dev) { struct lsm6dsv16x_data *lsm6dsv16x = dev->data; struct rtio_iodev *iodev = lsm6dsv16x->iodev; +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + const struct lsm6dsv16x_config *config = dev->config; +#endif + uint64_t cycles; + int rc; if (lsm6dsv16x->streaming_sqe == NULL) { return; } - /* get timestamp as soon as the irq is served */ - lsm6dsv16x->fifo_timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); - - lsm6dsv16x->fifo_status[0] = lsm6dsv16x->fifo_status[1] = 0; + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(lsm6dsv16x->streaming_sqe, rc); + return; + } - /* - * Prepare rtio enabled bus to read LSM6DSV16X_FIFO_STATUS1 and LSM6DSV16X_FIFO_STATUS2 - * registers where FIFO threshold condition and count are reported. - * Then lsm6dsv16x_read_fifo_cb callback will be invoked. - * - * STMEMSC API equivalent code: - * - * lsm6dsv16x_fifo_status_t fifo_status; - * - * lsm6dsv16x_fifo_status_get(&dev_ctx, &fifo_status); - */ - struct rtio_sqe *write_fifo_status_addr = rtio_sqe_acquire(lsm6dsv16x->rtio_ctx); - struct rtio_sqe *read_fifo_status_reg = rtio_sqe_acquire(lsm6dsv16x->rtio_ctx); + /* get timestamp as soon as the irq is served */ + lsm6dsv16x->fifo_timestamp = sensor_clock_cycles_to_ns(cycles); + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (ON_I3C_BUS(config) && (!I3C_INT_PIN(config))) { + /* + * If we are on an I3C bus, then it should be expected that the fifo status was + * already received in the IBI payload and we don't need to read it again. + */ + lsm6dsv16x->fifo_status[0] = lsm6dsv16x->ibi_payload.fifo_status1; + lsm6dsv16x->fifo_status[1] = lsm6dsv16x->ibi_payload.fifo_status2; + } else +#endif + { + lsm6dsv16x->fifo_status[0] = lsm6dsv16x->fifo_status[1] = 0; + + /* + * Prepare rtio enabled bus to read LSM6DSV16X_FIFO_STATUS1 and + * LSM6DSV16X_FIFO_STATUS2 registers where FIFO threshold condition and count are + * reported. Then lsm6dsv16x_read_fifo_cb callback will be invoked. + * + * STMEMSC API equivalent code: + * + * lsm6dsv16x_fifo_status_t fifo_status; + * + * lsm6dsv16x_fifo_status_get(&dev_ctx, &fifo_status); + */ + struct rtio_sqe *write_fifo_status_addr = rtio_sqe_acquire(lsm6dsv16x->rtio_ctx); + struct rtio_sqe *read_fifo_status_reg = rtio_sqe_acquire(lsm6dsv16x->rtio_ctx); + uint8_t reg = lsm6dsv16x_bus_reg(lsm6dsv16x, LSM6DSV16X_FIFO_STATUS1); + + rtio_sqe_prep_tiny_write(write_fifo_status_addr, iodev, RTIO_PRIO_NORM, ®, 1, + NULL); + write_fifo_status_addr->flags = RTIO_SQE_TRANSACTION; + rtio_sqe_prep_read(read_fifo_status_reg, iodev, RTIO_PRIO_NORM, + lsm6dsv16x->fifo_status, 2, NULL); + read_fifo_status_reg->flags = RTIO_SQE_CHAINED; + if (lsm6dsv16x->bus_type == BUS_I2C) { + read_fifo_status_reg->iodev_flags |= + RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + } else if (lsm6dsv16x->bus_type == BUS_I3C) { + read_fifo_status_reg->iodev_flags |= + RTIO_IODEV_I3C_STOP | RTIO_IODEV_I3C_RESTART; + } + } struct rtio_sqe *check_fifo_status_reg = rtio_sqe_acquire(lsm6dsv16x->rtio_ctx); - uint8_t reg = lsm6dsv16x_bus_reg(lsm6dsv16x, LSM6DSV16X_FIFO_STATUS1); - rtio_sqe_prep_tiny_write(write_fifo_status_addr, iodev, RTIO_PRIO_NORM, ®, 1, NULL); - write_fifo_status_addr->flags = RTIO_SQE_TRANSACTION; - rtio_sqe_prep_read(read_fifo_status_reg, iodev, RTIO_PRIO_NORM, - lsm6dsv16x->fifo_status, 2, NULL); - read_fifo_status_reg->flags = RTIO_SQE_CHAINED; - if (lsm6dsv16x->bus_type == BUS_I2C) { - read_fifo_status_reg->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; - } rtio_sqe_prep_callback_no_cqe(check_fifo_status_reg, lsm6dsv16x_read_fifo_cb, (void *)dev, NULL); rtio_submit(lsm6dsv16x->rtio_ctx, 0); diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_trigger.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_trigger.c index d9e0fc50ad02c..a6a52f2ea9e2b 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_trigger.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_trigger.c @@ -37,7 +37,7 @@ static int lsm6dsv16x_enable_xl_int(const struct device *dev, int enable) } /* set interrupt */ - if (cfg->drdy_pin == 1) { + if ((cfg->drdy_pin == 1) || (ON_I3C_BUS(cfg) && (!I3C_INT_PIN(cfg)))) { lsm6dsv16x_pin_int_route_t val = {}; ret = lsm6dsv16x_pin_int1_route_get(ctx, &val); @@ -83,7 +83,7 @@ static int lsm6dsv16x_enable_g_int(const struct device *dev, int enable) } /* set interrupt */ - if (cfg->drdy_pin == 1) { + if ((cfg->drdy_pin == 1) || (ON_I3C_BUS(cfg) && (!I3C_INT_PIN(cfg)))) { lsm6dsv16x_pin_int_route_t val = {}; ret = lsm6dsv16x_pin_int1_route_get(ctx, &val); @@ -112,6 +112,53 @@ static int lsm6dsv16x_enable_g_int(const struct device *dev, int enable) return ret; } +/** + * lsm6dsv16x_enable_wake_int - Enable selected int pin to generate wakeup interrupt + */ +static int lsm6dsv16x_enable_wake_int(const struct device *dev, int enable) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + int ret; + lsm6dsv16x_interrupt_mode_t int_mode; + + int_mode.enable = enable ? 1 : 0; + int_mode.lir = !cfg->drdy_pulsed; + ret = lsm6dsv16x_interrupt_enable_set(ctx, int_mode); + if (ret < 0) { + LOG_ERR("interrupt_enable_set error"); + return ret; + } + + if ((cfg->drdy_pin == 1) || ON_I3C_BUS(cfg)) { + lsm6dsv16x_pin_int_route_t val; + + ret = lsm6dsv16x_pin_int1_route_get(ctx, &val); + if (ret < 0) { + LOG_ERR("pint_int1_route_get error"); + return ret; + } + + val.wakeup = enable ? 1 : 0; + + ret = lsm6dsv16x_pin_int1_route_set(ctx, &val); + } else { + lsm6dsv16x_pin_int_route_t val; + + ret = lsm6dsv16x_pin_int2_route_get(ctx, &val); + if (ret < 0) { + LOG_ERR("pint_int2_route_get error"); + return ret; + } + + val.wakeup = enable ? 1 : 0; + + ret = lsm6dsv16x_pin_int2_route_set(ctx, &val); + } + + return ret; +} + /** * lsm6dsv16x_trigger_set - link external trigger to event data ready */ @@ -133,6 +180,10 @@ int lsm6dsv16x_trigger_set(const struct device *dev, return -EINVAL; } + if (!lsm6dsv16x_is_active(dev)) { + return -EBUSY; + } + switch (trig->type) { case SENSOR_TRIG_DATA_READY: if (trig->chan == SENSOR_CHAN_ACCEL_XYZ) { @@ -152,7 +203,18 @@ int lsm6dsv16x_trigger_set(const struct device *dev, lsm6dsv16x_enable_g_int(dev, LSM6DSV16X_DIS_BIT); } } - + break; + case SENSOR_TRIG_DELTA: + if (trig->chan != SENSOR_CHAN_ACCEL_XYZ) { + return -ENOTSUP; + } + lsm6dsv16x->handler_wakeup = handler; + lsm6dsv16x->trig_wakeup = trig; + if (handler) { + lsm6dsv16x_enable_wake_int(dev, LSM6DSV16X_EN_BIT); + } else { + lsm6dsv16x_enable_wake_int(dev, LSM6DSV16X_DIS_BIT); + } break; default: ret = -ENOTSUP; @@ -174,14 +236,31 @@ static void lsm6dsv16x_handle_interrupt(const struct device *dev) const struct lsm6dsv16x_config *cfg = dev->config; stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; lsm6dsv16x_data_ready_t status; + lsm6dsv16x_all_int_src_t all_int_src; + int ret; while (1) { + /* When using I3C IBI interrupt the status register is already automatically + * read (clearing the interrupt condition), so we can skip the extra bus + * transaction for FIFO stream case. + */ + if (ON_I3C_BUS(cfg) && !I3C_INT_PIN(cfg) && IS_ENABLED(CONFIG_LSM6DSV16X_STREAM)) { + break; + } + if (lsm6dsv16x_flag_data_ready_get(ctx, &status) < 0) { LOG_DBG("failed reading status reg"); return; } - if ((status.drdy_xl == 0) && (status.drdy_gy == 0)) { + ret = lsm6dsv16x_read_reg(ctx, LSM6DSV16X_ALL_INT_SRC, (uint8_t *)&all_int_src, 1); + if (ret < 0) { + LOG_DBG("failed reading all_int_src reg"); + return; + } + + if (((status.drdy_xl == 0) && (status.drdy_gy == 0) && (all_int_src.wu_ia == 0)) || + IS_ENABLED(CONFIG_LSM6DSV16X_STREAM)) { break; } @@ -193,32 +272,48 @@ static void lsm6dsv16x_handle_interrupt(const struct device *dev) lsm6dsv16x->handler_drdy_gyr(dev, lsm6dsv16x->trig_drdy_gyr); } + if ((all_int_src.wu_ia) && lsm6dsv16x->handler_wakeup != NULL) { + lsm6dsv16x->handler_wakeup(dev, lsm6dsv16x->trig_wakeup); + } } - gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, - GPIO_INT_EDGE_TO_ACTIVE); + if (!ON_I3C_BUS(cfg) || (I3C_INT_PIN(cfg))) { + ret = gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("%s: Not able to configure pin_int", dev->name); + } + } } #endif /* CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD || CONFIG_LSM6DSV16X_TRIGGER_GLOBAL_THREAD */ +static void lsm6dsv16x_intr_callback(struct lsm6dsv16x_data *lsm6dsv16x) +{ +#if defined(CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD) + k_sem_give(&lsm6dsv16x->intr_sem); +#elif defined(CONFIG_LSM6DSV16X_TRIGGER_GLOBAL_THREAD) + k_work_submit(&lsm6dsv16x->work); +#endif /* CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD */ + if (IS_ENABLED(CONFIG_LSM6DSV16X_STREAM)) { + lsm6dsv16x_stream_irq_handler(lsm6dsv16x->dev); + } +} + static void lsm6dsv16x_gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { struct lsm6dsv16x_data *lsm6dsv16x = CONTAINER_OF(cb, struct lsm6dsv16x_data, gpio_cb); + int ret; ARG_UNUSED(pins); - gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_DISABLE); - - if (IS_ENABLED(CONFIG_LSM6DSV16X_STREAM)) { - lsm6dsv16x_stream_irq_handler(lsm6dsv16x->dev); + ret = gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_DISABLE); + if (ret < 0) { + LOG_ERR("%s: Not able to configure pin_int", dev->name); } -#if defined(CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD) - k_sem_give(&lsm6dsv16x->gpio_sem); -#elif defined(CONFIG_LSM6DSV16X_TRIGGER_GLOBAL_THREAD) - k_work_submit(&lsm6dsv16x->work); -#endif /* CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD */ + lsm6dsv16x_intr_callback(lsm6dsv16x); } #ifdef CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD @@ -230,7 +325,7 @@ static void lsm6dsv16x_thread(void *p1, void *p2, void *p3) struct lsm6dsv16x_data *lsm6dsv16x = p1; while (1) { - k_sem_take(&lsm6dsv16x->gpio_sem, K_FOREVER); + k_sem_take(&lsm6dsv16x->intr_sem, K_FOREVER); lsm6dsv16x_handle_interrupt(lsm6dsv16x->dev); } } @@ -246,6 +341,47 @@ static void lsm6dsv16x_work_cb(struct k_work *work) } #endif /* CONFIG_LSM6DSV16X_TRIGGER_GLOBAL_THREAD */ +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) +static int lsm6dsv16x_ibi_cb(struct i3c_device_desc *target, + struct i3c_ibi_payload *payload) +{ + const struct device *dev = target->dev; + struct lsm6dsv16x_data *lsm6dsv16x = dev->data; + + /* + * The IBI Payload consist of the following 10 bytes : + * 1st byte: MDB + * - MDB[0]: FIFO interrupts (FIFO_WTM_IA, FIFO_OVR_IA, FIFO_FULL_IA, CONTER_BDR_IA) + * - MDB[1]: Physical interrupts (XLDS, GDA, TDA, XLDA_OIS, GDA_OIS) + * - MDB[2]: Basic interrupts (SLEEP_CHANGE_IA, D6D_IA, DOUBLE_TAP, SINGLE_TAP, WU_IA, + * FF_IA) + * - MDB[3]: SHUB DRDY (SENS_HUB_ENDOP) + * - MDB[4]: Advanced Function interrupt group + * - MDB[7:5]: 3'b000: Vendor Definied + * 3'b100: Timing Information + * 2nd byte: FIFO_STATUS1 + * 3rd byte: FIFO_STATUS2 + * 4th byte: ALL_INT_SRC + * 5th byte: STATUS_REG + * 6th byte: STATUS_REG_OIS + * 7th byte: STATUS_MASTER_MAIN + * 8th byte: EMB_FUNC_STATUS + * 9th byte: FSM_STATUS + * 10th byte: MLC_STATUS + */ + if (payload->payload_len != sizeof(lsm6dsv16x->ibi_payload)) { + LOG_ERR("Invalid IBI payload length"); + return -EINVAL; + } + + memcpy(&lsm6dsv16x->ibi_payload, payload->payload, payload->payload_len); + + lsm6dsv16x_intr_callback(lsm6dsv16x); + + return 0; +} +#endif + int lsm6dsv16x_init_interrupt(const struct device *dev) { struct lsm6dsv16x_data *lsm6dsv16x = dev->data; @@ -258,13 +394,17 @@ int lsm6dsv16x_init_interrupt(const struct device *dev) (struct gpio_dt_spec *)&cfg->int2_gpio; /* setup data ready gpio interrupt (INT1 or INT2) */ - if (!gpio_is_ready_dt(lsm6dsv16x->drdy_gpio)) { + if ((!ON_I3C_BUS(cfg) || (I3C_INT_PIN(cfg))) && !gpio_is_ready_dt(lsm6dsv16x->drdy_gpio)) { LOG_ERR("Cannot get pointer to drdy_gpio device"); return -EINVAL; } + if (IS_ENABLED(CONFIG_LSM6DSV16X_STREAM)) { + lsm6dsv16x_stream_irq_handler(lsm6dsv16x->dev); + } + #if defined(CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD) - k_sem_init(&lsm6dsv16x->gpio_sem, 0, K_SEM_MAX_LIMIT); + k_sem_init(&lsm6dsv16x->intr_sem, 0, K_SEM_MAX_LIMIT); k_thread_create(&lsm6dsv16x->thread, lsm6dsv16x->thread_stack, CONFIG_LSM6DSV16X_THREAD_STACK_SIZE, @@ -276,26 +416,29 @@ int lsm6dsv16x_init_interrupt(const struct device *dev) lsm6dsv16x->work.handler = lsm6dsv16x_work_cb; #endif /* CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD */ - ret = gpio_pin_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INPUT); - if (ret < 0) { - LOG_DBG("Could not configure gpio"); - return ret; - } + if (!ON_I3C_BUS(cfg) || (I3C_INT_PIN(cfg))) { + ret = gpio_pin_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_DBG("Could not configure gpio"); + return ret; + } - gpio_init_callback(&lsm6dsv16x->gpio_cb, - lsm6dsv16x_gpio_callback, - BIT(lsm6dsv16x->drdy_gpio->pin)); + gpio_init_callback(&lsm6dsv16x->gpio_cb, + lsm6dsv16x_gpio_callback, + BIT(lsm6dsv16x->drdy_gpio->pin)); - if (gpio_add_callback(lsm6dsv16x->drdy_gpio->port, &lsm6dsv16x->gpio_cb) < 0) { - LOG_DBG("Could not set gpio callback"); - return -EIO; - } + if (gpio_add_callback(lsm6dsv16x->drdy_gpio->port, &lsm6dsv16x->gpio_cb) < 0) { + LOG_DBG("Could not set gpio callback"); + return -EIO; + } + } - /* set data ready mode on int1/int2 */ + /* set data ready mode on int1/int2/tir */ LOG_DBG("drdy_pulsed is %d", (int)cfg->drdy_pulsed); lsm6dsv16x_data_ready_mode_t mode = cfg->drdy_pulsed ? LSM6DSV16X_DRDY_PULSED : - LSM6DSV16X_DRDY_LATCHED; + LSM6DSV16X_DRDY_LATCHED; + ret = lsm6dsv16x_data_ready_mode_set(ctx, mode); if (ret < 0) { @@ -303,6 +446,53 @@ int lsm6dsv16x_init_interrupt(const struct device *dev) return ret; } +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (ON_I3C_BUS(cfg)) { + if (I3C_INT_PIN(cfg)) { + /* Enable INT Pins when using I3C */ + ret = lsm6dsv16x_i3c_int_en_set(ctx, I3C_INT_PIN(cfg)); + if (ret < 0) { + LOG_ERR("failed to enable int pin for I3C %d", ret); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("Could not configure gpio interrupt"); + return ret; + } + } else { + /* I3C IBI does not utilize GPIO interrupt. */ + lsm6dsv16x->i3c_dev->ibi_cb = lsm6dsv16x_ibi_cb; + + /* + * Set IBI availability time, this is the time that the sensor + * will wait for inactivity before it is okay to generate an IBI TIR. + * + * NOTE: There is a bug in the API and the Documentation where + * the defines for the values are incorrect. The correct values are: + * 0 = 50us + * 1 = 2us + * 2 = 1ms + * 3 = 25ms + */ + ret = lsm6dsv16x_i3c_ibi_time_set(ctx, cfg->bus_act_sel); + if (ret < 0) { + LOG_ERR("failed to set ibi available time %d", ret); + return -EIO; + } + + if (i3c_ibi_enable(lsm6dsv16x->i3c_dev) != 0) { + LOG_ERR("Could not enable I3C IBI"); + return -EIO; + } + } + + return 0; + } +#endif + return gpio_pin_interrupt_configure_dt(lsm6dsv16x->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); } diff --git a/drivers/sensor/st/lsm9ds0_mfd/lsm9ds0_mfd.c b/drivers/sensor/st/lsm9ds0_mfd/lsm9ds0_mfd.c index 5186eb0f0090f..3db5aa8d27a0b 100644 --- a/drivers/sensor/st/lsm9ds0_mfd/lsm9ds0_mfd.c +++ b/drivers/sensor/st/lsm9ds0_mfd/lsm9ds0_mfd.c @@ -38,7 +38,8 @@ static inline int lsm9ds0_mfd_reboot_memory(const struct device *dev) return 0; } -#if !defined(LSM9DS0_MFD_ACCEL_DISABLED) +#if !defined(LSM9DS0_MFD_ACCEL_DISABLED) && defined(CONFIG_LSM9DS0_MFD_ACCEL_SAMPLING_RATE_RUNTIME) + static inline int lsm9ds0_mfd_accel_set_odr_raw(const struct device *dev, uint8_t odr) { @@ -49,7 +50,6 @@ static inline int lsm9ds0_mfd_accel_set_odr_raw(const struct device *dev, odr << LSM9DS0_MFD_SHIFT_CTRL_REG1_XM_AODR); } -#if defined(CONFIG_LSM9DS0_MFD_ACCEL_SAMPLING_RATE_RUNTIME) static const struct { int freq_int; int freq_micro; @@ -122,7 +122,6 @@ static int lsm9ds0_mfd_accel_set_fs(const struct device *dev, int val) return -ENOTSUP; } #endif -#endif #if !defined(LSM9DS0_MFD_MAGN_DISABLED) static inline int lsm9ds0_mfd_magn_set_odr_raw(const struct device *dev, diff --git a/drivers/sensor/st/stm32_vref/stm32_vref.c b/drivers/sensor/st/stm32_vref/stm32_vref.c index fbf6af5013348..95148e45d6cb8 100644 --- a/drivers/sensor/st/stm32_vref/stm32_vref.c +++ b/drivers/sensor/st/stm32_vref/stm32_vref.c @@ -19,6 +19,9 @@ LOG_MODULE_REGISTER(stm32_vref, CONFIG_SENSOR_LOG_LEVEL); +/* Resolution used to perform the Vref measurement */ +#define MEAS_RES (12U) + struct stm32_vref_data { const struct device *adc; const struct adc_channel_cfg adc_cfg; @@ -32,6 +35,7 @@ struct stm32_vref_data { struct stm32_vref_config { uint16_t *cal_addr; int cal_mv; + uint8_t cal_shift; }; static int stm32_vref_sample_fetch(const struct device *dev, enum sensor_channel chan) @@ -103,16 +107,7 @@ static int stm32_vref_channel_get(const struct device *dev, enum sensor_channel #endif /* CONFIG_SOC_SERIES_STM32H5X */ /* Calculate VREF+ using VREFINT bandgap voltage and calibration data */ -#if defined(CONFIG_SOC_SERIES_STM32U5X) - /* - * The VREF CALIBRATION value is acquired on 14 bits - * and the data acquired is on 12 bits - * since the adc_sequence.resolution is 12 - */ - vref = (cfg->cal_mv * (*cfg->cal_addr) >> 2) / data->raw; -#else - vref = cfg->cal_mv * (*cfg->cal_addr) / data->raw; -#endif /* CONFIG_SOC_SERIES_STM32H5X */ + vref = (cfg->cal_mv * ((*cfg->cal_addr) >> cfg->cal_shift)) / data->raw; #if defined(CONFIG_SOC_SERIES_STM32H5X) LL_ICACHE_Enable(); @@ -142,7 +137,7 @@ static int stm32_vref_init(const struct device *dev) .channels = BIT(data->adc_cfg.channel_id), .buffer = &data->sample_buffer, .buffer_size = sizeof(data->sample_buffer), - .resolution = 12U, + .resolution = MEAS_RES, }; return 0; @@ -178,8 +173,13 @@ static struct stm32_vref_data stm32_vref_dev_data = { static const struct stm32_vref_config stm32_vref_dev_config = { .cal_addr = (uint16_t *)DT_INST_PROP(0, vrefint_cal_addr), .cal_mv = DT_INST_PROP(0, vrefint_cal_mv), + .cal_shift = (DT_INST_PROP(0, vrefint_cal_resolution) - MEAS_RES), }; +/* Make sure no series with unsupported configuration can be added silently */ +BUILD_ASSERT(DT_INST_PROP(0, vrefint_cal_resolution) >= MEAS_RES, + "VREFINT calibration resolution is too low"); + SENSOR_DEVICE_DT_INST_DEFINE(0, stm32_vref_init, NULL, &stm32_vref_dev_data, &stm32_vref_dev_config, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &stm32_vref_driver_api); diff --git a/drivers/sensor/st/stmemsc/Kconfig b/drivers/sensor/st/stmemsc/Kconfig new file mode 100644 index 0000000000000..bf509065d4e71 --- /dev/null +++ b/drivers/sensor/st/stmemsc/Kconfig @@ -0,0 +1,13 @@ +# ST MEMS sensor configuration options + +# Copyright (c) 2025 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +config STMEMSC_I3C_I2C_WRITE_BUFFER_SIZE + int "ST memsc I2C write buffer size" + default 16 + depends on I2C || I3C + depends on HAS_STMEMSC + help + The size of the buffer pushed on the stack used to copy + the data to be written along with the register address. diff --git a/drivers/sensor/st/stmemsc/stmemsc_i2c.c b/drivers/sensor/st/stmemsc/stmemsc_i2c.c index bf6ddebbd4f0d..25652196faa10 100644 --- a/drivers/sensor/st/stmemsc/stmemsc_i2c.c +++ b/drivers/sensor/st/stmemsc/stmemsc_i2c.c @@ -21,7 +21,14 @@ int stmemsc_i2c_read(const struct i2c_dt_spec *stmemsc, int stmemsc_i2c_write(const struct i2c_dt_spec *stmemsc, uint8_t reg_addr, uint8_t *value, uint8_t len) { - return i2c_burst_write_dt(stmemsc, reg_addr, value, len); + uint8_t buf[CONFIG_STMEMSC_I3C_I2C_WRITE_BUFFER_SIZE]; + + __ASSERT_NO_MSG(len <= sizeof(buf) - 1); + + buf[0] = reg_addr; + memcpy(&buf[1], value, len); + + return i2c_write_dt(stmemsc, buf, len + 1); } int stmemsc_i2c_read_incr(const struct i2c_dt_spec *stmemsc, @@ -34,6 +41,12 @@ int stmemsc_i2c_read_incr(const struct i2c_dt_spec *stmemsc, int stmemsc_i2c_write_incr(const struct i2c_dt_spec *stmemsc, uint8_t reg_addr, uint8_t *value, uint8_t len) { - reg_addr |= STMEMSC_I2C_ADDR_AUTO_INCR; - return stmemsc_i2c_write(stmemsc, reg_addr, value, len); + uint8_t buf[CONFIG_STMEMSC_I3C_I2C_WRITE_BUFFER_SIZE]; + + __ASSERT_NO_MSG(len <= sizeof(buf) - 1); + + buf[0] = reg_addr | STMEMSC_I2C_ADDR_AUTO_INCR; + memcpy(&buf[1], value, len); + + return i2c_write_dt(stmemsc, buf, len + 1); } diff --git a/drivers/sensor/st/stmemsc/stmemsc_i3c.c b/drivers/sensor/st/stmemsc/stmemsc_i3c.c index 04b7446170c22..6ef6b65c7544b 100644 --- a/drivers/sensor/st/stmemsc/stmemsc_i3c.c +++ b/drivers/sensor/st/stmemsc/stmemsc_i3c.c @@ -21,6 +21,12 @@ int stmemsc_i3c_write(void *stmemsc, uint8_t reg_addr, uint8_t *value, uint8_t len) { struct i3c_device_desc *target = **(struct i3c_device_desc ***)stmemsc; + uint8_t buf[CONFIG_STMEMSC_I3C_I2C_WRITE_BUFFER_SIZE]; - return i3c_burst_write(target, reg_addr, value, len); + __ASSERT_NO_MSG(len <= sizeof(buf) - 1); + + buf[0] = reg_addr; + memcpy(&buf[1], value, len); + + return i3c_write(target, buf, len + 1); } diff --git a/drivers/sensor/st/stmemsc/stmemsc_spi.c b/drivers/sensor/st/stmemsc/stmemsc_spi.c index 3d728c78d8b18..66421f17ca000 100644 --- a/drivers/sensor/st/stmemsc/stmemsc_spi.c +++ b/drivers/sensor/st/stmemsc/stmemsc_spi.c @@ -63,13 +63,19 @@ int stmemsc_spi_write(const struct spi_dt_spec *stmemsc, int stmemsc_spi_read_incr(const struct spi_dt_spec *stmemsc, uint8_t reg_addr, uint8_t *value, uint8_t len) { - reg_addr |= STMEMSC_SPI_ADDR_AUTO_INCR; + if (len > 1) { + reg_addr |= STMEMSC_SPI_ADDR_AUTO_INCR; + } + return stmemsc_spi_read(stmemsc, reg_addr, value, len); } int stmemsc_spi_write_incr(const struct spi_dt_spec *stmemsc, uint8_t reg_addr, uint8_t *value, uint8_t len) { - reg_addr |= STMEMSC_SPI_ADDR_AUTO_INCR; + if (len > 1) { + reg_addr |= STMEMSC_SPI_ADDR_AUTO_INCR; + } + return stmemsc_spi_write(stmemsc, reg_addr, value, len); } diff --git a/drivers/sensor/st/stts751/stts751.c b/drivers/sensor/st/stts751/stts751.c index 00bdf3288f22b..66f3456b86f67 100644 --- a/drivers/sensor/st/stts751/stts751.c +++ b/drivers/sensor/st/stts751/stts751.c @@ -35,7 +35,7 @@ static int stts751_sample_fetch(const struct device *dev, struct stts751_data *data = dev->data; int16_t raw_temp; - __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + __ASSERT_NO_MSG(chan == SENSOR_CHAN_AMBIENT_TEMP || chan == SENSOR_CHAN_ALL); if (stts751_temperature_raw_get(data->ctx, &raw_temp) < 0) { LOG_DBG("Failed to read sample"); diff --git a/drivers/sensor/st/vl53l0x/vl53l0x.c b/drivers/sensor/st/vl53l0x/vl53l0x.c index 569288f085135..b43046250cd3b 100644 --- a/drivers/sensor/st/vl53l0x/vl53l0x.c +++ b/drivers/sensor/st/vl53l0x/vl53l0x.c @@ -20,12 +20,16 @@ #include #include #include +#include #include "vl53l0x_api.h" #include "vl53l0x_platform.h" LOG_MODULE_REGISTER(VL53L0X, CONFIG_SENSOR_LOG_LEVEL); +#define VL53L0X_FIXPOINT1616_SCALE_FACTOR (65536) +#define VL53L0X_SENSOR_CHANNEL_VAL2_FACTOR (1000000) + /* All the values used in this driver are coming from ST datasheet and examples. * It can be found here: * https://www.st.com/en/embedded-software/stsw-img005.html @@ -288,6 +292,26 @@ static int vl53l0x_channel_get(const struct device *dev, } else if (chan == SENSOR_CHAN_DISTANCE) { val->val1 = drv_data->RangingMeasurementData.RangeMilliMeter / 1000; val->val2 = (drv_data->RangingMeasurementData.RangeMilliMeter % 1000) * 1000; + } else if ((enum sensor_channel_vl53l0x)chan == + SENSOR_CHAN_VL53L0X_EFFECTIVE_SPAD_RTN_COUNT) { + val->val1 = drv_data->RangingMeasurementData.EffectiveSpadRtnCount / 256; + val->val2 = 0; + } else if ((enum sensor_channel_vl53l0x)chan == SENSOR_CHAN_VL53L0X_AMBIENT_RATE_RTN_CPS) { + val->val1 = (drv_data->RangingMeasurementData.AmbientRateRtnMegaCps >> 16) + + (((drv_data->RangingMeasurementData.AmbientRateRtnMegaCps & 0xFFFF) * + VL53L0X_SENSOR_CHANNEL_VAL2_FACTOR) / VL53L0X_FIXPOINT1616_SCALE_FACTOR); + val->val2 = 0; + } else if ((enum sensor_channel_vl53l0x)chan == SENSOR_CHAN_VL53L0X_SIGNAL_RATE_RTN_CPS) { + val->val1 = (drv_data->RangingMeasurementData.SignalRateRtnMegaCps >> 16) + + (((drv_data->RangingMeasurementData.SignalRateRtnMegaCps & 0xFFFF) * + VL53L0X_SENSOR_CHANNEL_VAL2_FACTOR) / VL53L0X_FIXPOINT1616_SCALE_FACTOR); + val->val2 = 0; + } else if ((enum sensor_channel_vl53l0x)chan == SENSOR_CHAN_VL53L0X_RANGE_DMAX) { + val->val1 = drv_data->RangingMeasurementData.RangeDMaxMilliMeter / 1000; + val->val2 = (drv_data->RangingMeasurementData.RangeDMaxMilliMeter % 1000) * 1000; + } else if ((enum sensor_channel_vl53l0x)chan == SENSOR_CHAN_VL53L0X_RANGE_STATUS) { + val->val1 = drv_data->RangingMeasurementData.RangeStatus; + val->val2 = 0; } else { return -ENOTSUP; } diff --git a/drivers/sensor/tdk/CMakeLists.txt b/drivers/sensor/tdk/CMakeLists.txt index 0f5c85a2db0e8..7e6c4090391a3 100644 --- a/drivers/sensor/tdk/CMakeLists.txt +++ b/drivers/sensor/tdk/CMakeLists.txt @@ -3,9 +3,9 @@ # zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_ICM42605 icm42605) -add_subdirectory_ifdef(CONFIG_ICM42670 icm42670) add_subdirectory_ifdef(CONFIG_ICM42688 icm42688) -add_subdirectory_ifdef(CONFIG_ICP10125 icp10125) +add_subdirectory_ifdef(CONFIG_ICM42X70 icm42x70) +add_subdirectory_ifdef(CONFIG_ICP101XX icp101xx) add_subdirectory_ifdef(CONFIG_MPU6050 mpu6050) add_subdirectory_ifdef(CONFIG_MPU9250 mpu9250) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/tdk/Kconfig b/drivers/sensor/tdk/Kconfig index 57d92f9faf60c..c903842785121 100644 --- a/drivers/sensor/tdk/Kconfig +++ b/drivers/sensor/tdk/Kconfig @@ -3,9 +3,9 @@ # zephyr-keep-sorted-start source "drivers/sensor/tdk/icm42605/Kconfig" -source "drivers/sensor/tdk/icm42670/Kconfig" source "drivers/sensor/tdk/icm42688/Kconfig" -source "drivers/sensor/tdk/icp10125/Kconfig" +source "drivers/sensor/tdk/icm42x70/Kconfig" +source "drivers/sensor/tdk/icp101xx/Kconfig" source "drivers/sensor/tdk/mpu6050/Kconfig" source "drivers/sensor/tdk/mpu9250/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/tdk/icm42670/CMakeLists.txt b/drivers/sensor/tdk/icm42670/CMakeLists.txt deleted file mode 100644 index e2257782e6990..0000000000000 --- a/drivers/sensor/tdk/icm42670/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library() - -zephyr_library_sources( - icm42670.c - icm42670_spi.c - icm42670_i2c.c -) - -zephyr_library_sources_ifdef(CONFIG_ICM42670_TRIGGER icm42670_trigger.c) diff --git a/drivers/sensor/tdk/icm42670/Kconfig b/drivers/sensor/tdk/icm42670/Kconfig deleted file mode 100644 index bd16320c472da..0000000000000 --- a/drivers/sensor/tdk/icm42670/Kconfig +++ /dev/null @@ -1,59 +0,0 @@ -# ICM42670 Six-Axis Motion Tracking device configuration options -# -# Copyright (c) 2022 Esco Medical ApS -# Copyright (c) 2020 TDK Invensense -# -# SPDX-License-Identifier: Apache-2.0 - -menuconfig ICM42670 - bool "ICM42670 Six-Axis Motion Tracking Device" - default y - depends on DT_HAS_INVENSENSE_ICM42670_ENABLED - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM42670),spi) - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM42670),i2c) - help - Enable driver for ICM42670 SPI-based six-axis motion tracking device. - -if ICM42670 - -choice ICM42670_TRIGGER_MODE - prompt "Trigger mode" - default ICM42670_TRIGGER_NONE - help - Specify the type of triggering to be used by the driver. - -config ICM42670_TRIGGER_NONE - bool "No trigger" - -config ICM42670_TRIGGER_GLOBAL_THREAD - bool "Use global thread" - depends on GPIO - depends on $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42670),int-gpios) - select ICM42670_TRIGGER - -config ICM42670_TRIGGER_OWN_THREAD - bool "Use own thread" - depends on GPIO - depends on $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42670),int-gpios) - select ICM42670_TRIGGER - -endchoice - -config ICM42670_TRIGGER - bool - -config ICM42670_THREAD_PRIORITY - int "Thread priority" - depends on ICM42670_TRIGGER_OWN_THREAD - default 10 - help - Priority of thread used by the driver to handle interrupts. - -config ICM42670_THREAD_STACK_SIZE - int "Thread stack size" - depends on ICM42670_TRIGGER_OWN_THREAD - default 1024 - help - Stack size of thread used by the driver to handle interrupts. - -endif # ICM42670 diff --git a/drivers/sensor/tdk/icm42670/icm42670.c b/drivers/sensor/tdk/icm42670/icm42670.c deleted file mode 100644 index e16b9b20e71cf..0000000000000 --- a/drivers/sensor/tdk/icm42670/icm42670.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * Copyright (c) 2022 Esco Medical ApS - * Copyright (c) 2020 TDK Invensense - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT invensense_icm42670 - -#include -#include -#include -#include "icm42670.h" -#include "icm42670_reg.h" -#include "icm42670_trigger.h" - -#include -LOG_MODULE_REGISTER(ICM42670, CONFIG_SENSOR_LOG_LEVEL); - -/* - * Gyro FS to scaling factor mapping. - * See datasheet section 3.1 for details - */ -static const uint16_t icm42670_gyro_sensitivity_x10[] = { - 164, /* BIT_GYRO_UI_FS_2000 */ - 328, /* BIT_GYRO_UI_FS_1000 */ - 655, /* BIT_GYRO_UI_FS_500 */ - 1310, /* BIT_GYRO_UI_FS_250 */ -}; - -static int icm42670_set_accel_fs(const struct device *dev, uint16_t fs) -{ - const struct icm42670_config *cfg = dev->config; - struct icm42670_data *data = dev->data; - uint8_t temp; - - if ((fs > 16) || (fs < 2)) { - LOG_ERR("Unsupported range"); - return -ENOTSUP; - } - - if (fs > 8) { - temp = BIT_ACCEL_UI_FS_16; - } else if (fs > 4) { - temp = BIT_ACCEL_UI_FS_8; - } else if (fs > 2) { - temp = BIT_ACCEL_UI_FS_4; - } else { - temp = BIT_ACCEL_UI_FS_2; - } - - data->accel_sensitivity_shift = MIN_ACCEL_SENS_SHIFT + temp; - - return cfg->bus_io->update(&cfg->bus, REG_ACCEL_CONFIG0, - (uint8_t)MASK_ACCEL_UI_FS_SEL, temp); -} - -static int icm42670_set_gyro_fs(const struct device *dev, uint16_t fs) -{ - const struct icm42670_config *cfg = dev->config; - struct icm42670_data *data = dev->data; - uint8_t temp; - - if ((fs > 2000) || (fs < 250)) { - LOG_ERR("Unsupported range"); - return -ENOTSUP; - } - - if (fs > 1000) { - temp = BIT_GYRO_UI_FS_2000; - } else if (fs > 500) { - temp = BIT_GYRO_UI_FS_1000; - } else if (fs > 250) { - temp = BIT_GYRO_UI_FS_500; - } else { - temp = BIT_GYRO_UI_FS_250; - } - - data->gyro_sensitivity_x10 = icm42670_gyro_sensitivity_x10[temp]; - - return cfg->bus_io->update(&cfg->bus, REG_GYRO_CONFIG0, - (uint8_t)MASK_GYRO_UI_FS_SEL, temp); -} - -static int icm42670_set_accel_odr(const struct device *dev, uint16_t rate) -{ - const struct icm42670_config *cfg = dev->config; - uint8_t temp; - - if ((rate > 1600) || (rate < 1)) { - LOG_ERR("Unsupported frequency"); - return -ENOTSUP; - } - - if (rate > 800) { - temp = BIT_ACCEL_ODR_1600; - } else if (rate > 400) { - temp = BIT_ACCEL_ODR_800; - } else if (rate > 200) { - temp = BIT_ACCEL_ODR_400; - } else if (rate > 100) { - temp = BIT_ACCEL_ODR_200; - } else if (rate > 50) { - temp = BIT_ACCEL_ODR_100; - } else if (rate > 25) { - temp = BIT_ACCEL_ODR_50; - } else if (rate > 12) { - temp = BIT_ACCEL_ODR_25; - } else if (rate > 6) { - temp = BIT_ACCEL_ODR_12; - } else if (rate > 3) { - temp = BIT_ACCEL_ODR_6; - } else if (rate > 1) { - temp = BIT_ACCEL_ODR_3; - } else { - temp = BIT_ACCEL_ODR_1; - } - - return cfg->bus_io->update(&cfg->bus, REG_ACCEL_CONFIG0, (uint8_t)MASK_ACCEL_ODR, - temp); -} - -static int icm42670_set_gyro_odr(const struct device *dev, uint16_t rate) -{ - const struct icm42670_config *cfg = dev->config; - uint8_t temp; - - if ((rate > 1600) || (rate < 12)) { - LOG_ERR("Unsupported frequency"); - return -ENOTSUP; - } - - if (rate > 800) { - temp = BIT_GYRO_ODR_1600; - } else if (rate > 400) { - temp = BIT_GYRO_ODR_800; - } else if (rate > 200) { - temp = BIT_GYRO_ODR_400; - } else if (rate > 100) { - temp = BIT_GYRO_ODR_200; - } else if (rate > 50) { - temp = BIT_GYRO_ODR_100; - } else if (rate > 25) { - temp = BIT_GYRO_ODR_50; - } else if (rate > 12) { - temp = BIT_GYRO_ODR_25; - } else { - temp = BIT_GYRO_ODR_12; - } - - return cfg->bus_io->update(&cfg->bus, REG_GYRO_CONFIG0, (uint8_t)MASK_GYRO_ODR, - temp); -} - -static int icm42670_enable_mclk(const struct device *dev) -{ - const struct icm42670_config *cfg = dev->config; - - /* switch on MCLK by setting the IDLE bit */ - int res = cfg->bus_io->write(&cfg->bus, REG_PWR_MGMT0, BIT_IDLE); - - if (res) { - return res; - } - - /* wait for the MCLK to stabilize by polling MCLK_RDY register */ - for (int i = 0; i < MCLK_POLL_ATTEMPTS; i++) { - uint8_t value = 0; - - k_usleep(MCLK_POLL_INTERVAL_US); - res = cfg->bus_io->read(&cfg->bus, REG_MCLK_RDY, &value, 1); - - if (res) { - return res; - } - - if (FIELD_GET(BIT_MCLK_RDY, value)) { - return 0; - } - } - - return -EIO; -} - -static int icm42670_sensor_init(const struct device *dev) -{ - int res; - uint8_t value; - const struct icm42670_config *cfg = dev->config; - - /* start up time for register read/write after POR is 1ms and supply ramp time is 3ms */ - k_msleep(3); - - /* perform a soft reset to ensure a clean slate, reset bit will auto-clear */ - res = cfg->bus_io->write(&cfg->bus, REG_SIGNAL_PATH_RESET, BIT_SOFT_RESET); - - if (res) { - LOG_ERR("write REG_SIGNAL_PATH_RESET failed"); - return res; - } - - /* wait for soft reset to take effect */ - k_msleep(SOFT_RESET_TIME_MS); - - /* force SPI-4w hardware configuration (so that next read is correct) */ - res = cfg->bus_io->write(&cfg->bus, REG_DEVICE_CONFIG, BIT_SPI_AP_4WIRE); - - if (res) { - return res; - } - - /* always use internal RC oscillator */ - res = cfg->bus_io->write(&cfg->bus, REG_INTF_CONFIG1, - (uint8_t)FIELD_PREP(MASK_CLKSEL, BIT_CLKSEL_INT_RC)); - - if (res) { - return res; - } - - /* clear reset done int flag */ - res = cfg->bus_io->read(&cfg->bus, REG_INT_STATUS, &value, 1); - - if (res) { - return res; - } - - if (FIELD_GET(BIT_STATUS_RESET_DONE_INT, value) != 1) { - LOG_ERR("unexpected RESET_DONE_INT value, %i", value); - return -EINVAL; - } - - /* enable the master clock to ensure proper operation */ - res = icm42670_enable_mclk(dev); - - if (res) { - return res; - } - - res = cfg->bus_io->read(&cfg->bus, REG_WHO_AM_I, &value, 1); - - if (res) { - return res; - } - - if (value != WHO_AM_I_ICM42670) { - LOG_ERR("invalid WHO_AM_I value, was %i but expected %i", value, WHO_AM_I_ICM42670); - return -EINVAL; - } - - LOG_DBG("device id: 0x%02X", value); - - return 0; -} - -static int icm42670_turn_on_sensor(const struct device *dev) -{ - struct icm42670_data *data = dev->data; - const struct icm42670_config *cfg = dev->config; - uint8_t value; - int res; - - value = FIELD_PREP(MASK_ACCEL_MODE, BIT_ACCEL_MODE_LNM) | - FIELD_PREP(MASK_GYRO_MODE, BIT_GYRO_MODE_LNM); - - res = cfg->bus_io->update(&cfg->bus, REG_PWR_MGMT0, - (uint8_t)(MASK_ACCEL_MODE | MASK_GYRO_MODE), value); - - if (res) { - return res; - } - - res = icm42670_set_accel_fs(dev, data->accel_fs); - - if (res) { - return res; - } - - res = icm42670_set_accel_odr(dev, data->accel_hz); - - if (res) { - return res; - } - - res = icm42670_set_gyro_fs(dev, data->gyro_fs); - - if (res) { - return res; - } - - res = icm42670_set_gyro_odr(dev, data->gyro_hz); - - if (res) { - return res; - } - - /* - * Accelerometer sensor need at least 10ms startup time - * Gyroscope sensor need at least 30ms startup time - */ - k_msleep(100); - - return 0; -} - -static void icm42670_convert_accel(struct sensor_value *val, int16_t raw_val, - uint16_t sensitivity_shift) -{ - /* see datasheet section 3.2 for details */ - int64_t conv_val = ((int64_t)raw_val * SENSOR_G) >> sensitivity_shift; - - val->val1 = conv_val / 1000000LL; - val->val2 = conv_val % 1000000LL; -} - -static void icm42670_convert_gyro(struct sensor_value *val, int16_t raw_val, - uint16_t sensitivity_x10) -{ - /* see datasheet section 3.1 for details */ - int64_t conv_val = ((int64_t)raw_val * SENSOR_PI * 10) / (sensitivity_x10 * 180LL); - - val->val1 = conv_val / 1000000LL; - val->val2 = conv_val % 1000000LL; -} - -static inline void icm42670_convert_temp(struct sensor_value *val, int16_t raw_val) -{ - /* see datasheet section 15.9 for details */ - val->val1 = (((int64_t)raw_val * 100) / 12800) + 25; - val->val2 = ((((int64_t)raw_val * 100) % 12800) * 1000000) / 12800; - - if (val->val2 < 0) { - val->val1--; - val->val2 += 1000000; - } else if (val->val2 >= 1000000) { - val->val1++; - val->val2 -= 1000000; - } -} - -static int icm42670_channel_get(const struct device *dev, enum sensor_channel chan, - struct sensor_value *val) -{ - int res = 0; - const struct icm42670_data *data = dev->data; - - icm42670_lock(dev); - - switch (chan) { - case SENSOR_CHAN_ACCEL_XYZ: - icm42670_convert_accel(&val[0], data->accel_x, data->accel_sensitivity_shift); - icm42670_convert_accel(&val[1], data->accel_y, data->accel_sensitivity_shift); - icm42670_convert_accel(&val[2], data->accel_z, data->accel_sensitivity_shift); - break; - case SENSOR_CHAN_ACCEL_X: - icm42670_convert_accel(val, data->accel_x, data->accel_sensitivity_shift); - break; - case SENSOR_CHAN_ACCEL_Y: - icm42670_convert_accel(val, data->accel_y, data->accel_sensitivity_shift); - break; - case SENSOR_CHAN_ACCEL_Z: - icm42670_convert_accel(val, data->accel_z, data->accel_sensitivity_shift); - break; - case SENSOR_CHAN_GYRO_XYZ: - icm42670_convert_gyro(&val[0], data->gyro_x, data->gyro_sensitivity_x10); - icm42670_convert_gyro(&val[1], data->gyro_y, data->gyro_sensitivity_x10); - icm42670_convert_gyro(&val[2], data->gyro_z, data->gyro_sensitivity_x10); - break; - case SENSOR_CHAN_GYRO_X: - icm42670_convert_gyro(val, data->gyro_x, data->gyro_sensitivity_x10); - break; - case SENSOR_CHAN_GYRO_Y: - icm42670_convert_gyro(val, data->gyro_y, data->gyro_sensitivity_x10); - break; - case SENSOR_CHAN_GYRO_Z: - icm42670_convert_gyro(val, data->gyro_z, data->gyro_sensitivity_x10); - break; - case SENSOR_CHAN_DIE_TEMP: - icm42670_convert_temp(val, data->temp); - break; - default: - res = -ENOTSUP; - break; - } - - icm42670_unlock(dev); - - return res; -} - -static int icm42670_sample_fetch_accel(const struct device *dev) -{ - const struct icm42670_config *cfg = dev->config; - struct icm42670_data *data = dev->data; - uint8_t buffer[ACCEL_DATA_SIZE]; - - int res = cfg->bus_io->read(&cfg->bus, REG_ACCEL_DATA_X1, buffer, ACCEL_DATA_SIZE); - - if (res) { - return res; - } - - data->accel_x = (int16_t)sys_get_be16(&buffer[0]); - data->accel_y = (int16_t)sys_get_be16(&buffer[2]); - data->accel_z = (int16_t)sys_get_be16(&buffer[4]); - - return 0; -} - -static int icm42670_sample_fetch_gyro(const struct device *dev) -{ - const struct icm42670_config *cfg = dev->config; - struct icm42670_data *data = dev->data; - uint8_t buffer[GYRO_DATA_SIZE]; - - int res = cfg->bus_io->read(&cfg->bus, REG_GYRO_DATA_X1, buffer, GYRO_DATA_SIZE); - - if (res) { - return res; - } - - data->gyro_x = (int16_t)sys_get_be16(&buffer[0]); - data->gyro_y = (int16_t)sys_get_be16(&buffer[2]); - data->gyro_z = (int16_t)sys_get_be16(&buffer[4]); - - return 0; -} - -static int icm42670_sample_fetch_temp(const struct device *dev) -{ - const struct icm42670_config *cfg = dev->config; - struct icm42670_data *data = dev->data; - uint8_t buffer[TEMP_DATA_SIZE]; - - int res = cfg->bus_io->read(&cfg->bus, REG_TEMP_DATA1, buffer, TEMP_DATA_SIZE); - - if (res) { - return res; - } - - data->temp = (int16_t)sys_get_be16(&buffer[0]); - - return 0; -} - -static int icm42670_sample_fetch(const struct device *dev, enum sensor_channel chan) -{ - uint8_t status; - const struct icm42670_config *cfg = dev->config; - - icm42670_lock(dev); - - int res = cfg->bus_io->read(&cfg->bus, REG_INT_STATUS_DRDY, &status, 1); - - if (res) { - goto cleanup; - } - - if (!FIELD_GET(BIT_INT_STATUS_DATA_DRDY, status)) { - res = -EBUSY; - goto cleanup; - } - - switch (chan) { - case SENSOR_CHAN_ALL: - res |= icm42670_sample_fetch_accel(dev); - res |= icm42670_sample_fetch_gyro(dev); - res |= icm42670_sample_fetch_temp(dev); - break; - case SENSOR_CHAN_ACCEL_XYZ: - case SENSOR_CHAN_ACCEL_X: - case SENSOR_CHAN_ACCEL_Y: - case SENSOR_CHAN_ACCEL_Z: - res = icm42670_sample_fetch_accel(dev); - break; - case SENSOR_CHAN_GYRO_XYZ: - case SENSOR_CHAN_GYRO_X: - case SENSOR_CHAN_GYRO_Y: - case SENSOR_CHAN_GYRO_Z: - res = icm42670_sample_fetch_gyro(dev); - break; - case SENSOR_CHAN_DIE_TEMP: - res = icm42670_sample_fetch_temp(dev); - break; - default: - res = -ENOTSUP; - break; - } - -cleanup: - icm42670_unlock(dev); - return res; -} - -static int icm42670_attr_set(const struct device *dev, enum sensor_channel chan, - enum sensor_attribute attr, const struct sensor_value *val) -{ - int res = 0; - struct icm42670_data *data = dev->data; - - __ASSERT_NO_MSG(val != NULL); - - icm42670_lock(dev); - - switch (chan) { - case SENSOR_CHAN_ACCEL_X: - case SENSOR_CHAN_ACCEL_Y: - case SENSOR_CHAN_ACCEL_Z: - case SENSOR_CHAN_ACCEL_XYZ: - if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { - res = icm42670_set_accel_odr(dev, data->accel_hz); - - if (res) { - LOG_ERR("Incorrect sampling value"); - } else { - data->accel_hz = val->val1; - } - } else if (attr == SENSOR_ATTR_FULL_SCALE) { - res = icm42670_set_accel_fs(dev, data->accel_fs); - - if (res) { - LOG_ERR("Incorrect fullscale value"); - } else { - data->accel_fs = val->val1; - } - } else { - LOG_ERR("Unsupported attribute"); - res = -ENOTSUP; - } - break; - - case SENSOR_CHAN_GYRO_X: - case SENSOR_CHAN_GYRO_Y: - case SENSOR_CHAN_GYRO_Z: - case SENSOR_CHAN_GYRO_XYZ: - if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { - res = icm42670_set_gyro_odr(dev, data->gyro_hz); - - if (res) { - LOG_ERR("Incorrect sampling value"); - } else { - data->gyro_hz = val->val1; - } - } else if (attr == SENSOR_ATTR_FULL_SCALE) { - res = icm42670_set_gyro_fs(dev, data->gyro_fs); - - if (res) { - LOG_ERR("Incorrect fullscale value"); - } else { - data->gyro_fs = val->val1; - } - } else { - LOG_ERR("Unsupported attribute"); - res = -EINVAL; - } - break; - - default: - LOG_ERR("Unsupported channel"); - res = -EINVAL; - break; - } - - icm42670_unlock(dev); - - return res; -} - -static int icm42670_attr_get(const struct device *dev, enum sensor_channel chan, - enum sensor_attribute attr, struct sensor_value *val) -{ - const struct icm42670_data *data = dev->data; - int res = 0; - - __ASSERT_NO_MSG(val != NULL); - - icm42670_lock(dev); - - switch (chan) { - case SENSOR_CHAN_ACCEL_X: - case SENSOR_CHAN_ACCEL_Y: - case SENSOR_CHAN_ACCEL_Z: - case SENSOR_CHAN_ACCEL_XYZ: - if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { - val->val1 = data->accel_hz; - } else if (attr == SENSOR_ATTR_FULL_SCALE) { - val->val1 = data->accel_fs; - } else { - LOG_ERR("Unsupported attribute"); - res = -EINVAL; - } - break; - - case SENSOR_CHAN_GYRO_X: - case SENSOR_CHAN_GYRO_Y: - case SENSOR_CHAN_GYRO_Z: - case SENSOR_CHAN_GYRO_XYZ: - if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { - val->val1 = data->gyro_hz; - } else if (attr == SENSOR_ATTR_FULL_SCALE) { - val->val1 = data->gyro_fs; - } else { - LOG_ERR("Unsupported attribute"); - res = -EINVAL; - } - break; - - default: - LOG_ERR("Unsupported channel"); - res = -EINVAL; - break; - } - - icm42670_unlock(dev); - - return res; -} - -static inline int icm42670_bus_check(const struct device *dev) -{ - const struct icm42670_config *cfg = dev->config; - - return cfg->bus_io->check(&cfg->bus); -} - -static int icm42670_init(const struct device *dev) -{ - struct icm42670_data *data = dev->data; - - if (icm42670_bus_check(dev) < 0) { - LOG_ERR("SPI bus is not ready"); - return -ENODEV; - } - - data->accel_x = 0; - data->accel_y = 0; - data->accel_z = 0; - data->gyro_x = 0; - data->gyro_y = 0; - data->gyro_z = 0; - data->temp = 0; - - if (icm42670_sensor_init(dev)) { - LOG_ERR("could not initialize sensor"); - return -EIO; - } - -#ifdef CONFIG_ICM42670_TRIGGER - if (icm42670_trigger_init(dev)) { - LOG_ERR("Failed to initialize interrupts."); - return -EIO; - } -#endif - - int res = icm42670_turn_on_sensor(dev); - -#ifdef CONFIG_ICM42670_TRIGGER - if (icm42670_trigger_enable_interrupt(dev)) { - LOG_ERR("Failed to enable interrupts"); - return -EIO; - } -#endif - - return res; -} - -#ifndef CONFIG_ICM42670_TRIGGER - -void icm42670_lock(const struct device *dev) -{ - ARG_UNUSED(dev); -} - -void icm42670_unlock(const struct device *dev) -{ - ARG_UNUSED(dev); -} - -#endif - -static DEVICE_API(sensor, icm42670_driver_api) = { -#ifdef CONFIG_ICM42670_TRIGGER - .trigger_set = icm42670_trigger_set, -#endif - .sample_fetch = icm42670_sample_fetch, - .channel_get = icm42670_channel_get, - .attr_set = icm42670_attr_set, - .attr_get = icm42670_attr_get, -}; - -/* device defaults to spi mode 0/3 support */ -#define ICM42670_SPI_CFG \ - SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_TRANSFER_MSB - -/* Initializes the bus members for an instance on a SPI bus. */ -#define ICM42670_CONFIG_SPI(inst) \ - .bus.spi = SPI_DT_SPEC_INST_GET(inst, ICM42670_SPI_CFG, 0), \ - .bus_io = &icm42670_bus_io_spi, - -/* Initializes the bus members for an instance on an I2C bus. */ -#define ICM42670_CONFIG_I2C(inst) \ - .bus.i2c = I2C_DT_SPEC_INST_GET(inst), \ - .bus_io = &icm42670_bus_io_i2c, - -#define ICM42670_INIT(inst) \ - static struct icm42670_data icm42670_driver_##inst = { \ - .accel_hz = DT_INST_PROP(inst, accel_hz), \ - .accel_fs = DT_INST_PROP(inst, accel_fs), \ - .gyro_hz = DT_INST_PROP(inst, gyro_hz), \ - .gyro_fs = DT_INST_PROP(inst, gyro_fs), \ - }; \ - \ - static const struct icm42670_config icm42670_cfg_##inst = { \ - COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ - (ICM42670_CONFIG_SPI(inst)), \ - (ICM42670_CONFIG_I2C(inst))) \ - .gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \ - }; \ - \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, icm42670_init, NULL, &icm42670_driver_##inst, \ - &icm42670_cfg_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ - &icm42670_driver_api); - -DT_INST_FOREACH_STATUS_OKAY(ICM42670_INIT) diff --git a/drivers/sensor/tdk/icm42670/icm42670.h b/drivers/sensor/tdk/icm42670/icm42670.h deleted file mode 100644 index 43adc3efb7196..0000000000000 --- a/drivers/sensor/tdk/icm42670/icm42670.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2022 Esco Medical ApS - * Copyright (c) 2020 TDK Invensense - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42670_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42670_H_ - -#include -#include -#include -#include -#include - -#define ICM42670_BUS_SPI DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(invensense_icm42670, spi) -#define ICM42670_BUS_I2C DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(invensense_icm42670, i2c) - -union icm42670_bus { -#if ICM42670_BUS_SPI - struct spi_dt_spec spi; -#endif -#if ICM42670_BUS_I2C - struct i2c_dt_spec i2c; -#endif -}; - -typedef int (*icm42670_bus_check_fn)(const union icm42670_bus *bus); -typedef int (*icm42670_reg_read_fn)(const union icm42670_bus *bus, - uint16_t reg, uint8_t *data, size_t size); -typedef int (*icm42670_reg_write_fn)(const union icm42670_bus *bus, - uint16_t reg, uint8_t data); - -typedef int (*icm42670_reg_update_fn)(const union icm42670_bus *bus, - uint16_t reg, uint8_t mask, uint8_t data); - -struct icm42670_bus_io { - icm42670_bus_check_fn check; - icm42670_reg_read_fn read; - icm42670_reg_write_fn write; - icm42670_reg_update_fn update; -}; - -#if ICM42670_BUS_SPI -extern const struct icm42670_bus_io icm42670_bus_io_spi; -#endif - -#if ICM42670_BUS_I2C -extern const struct icm42670_bus_io icm42670_bus_io_i2c; -#endif - -struct icm42670_data { - int16_t accel_x; - int16_t accel_y; - int16_t accel_z; - uint16_t accel_sensitivity_shift; - uint16_t accel_hz; - uint16_t accel_fs; - int16_t gyro_x; - int16_t gyro_y; - int16_t gyro_z; - uint16_t gyro_sensitivity_x10; - uint16_t gyro_hz; - uint16_t gyro_fs; - int16_t temp; -#ifdef CONFIG_ICM42670_TRIGGER - const struct device *dev; - struct gpio_callback gpio_cb; - sensor_trigger_handler_t data_ready_handler; - const struct sensor_trigger *data_ready_trigger; - struct k_mutex mutex; -#endif -#ifdef CONFIG_ICM42670_TRIGGER_OWN_THREAD - K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ICM42670_THREAD_STACK_SIZE); - struct k_thread thread; - struct k_sem gpio_sem; -#endif -#ifdef CONFIG_ICM42670_TRIGGER_GLOBAL_THREAD - struct k_work work; -#endif -}; - -struct icm42670_config { - union icm42670_bus bus; - const struct icm42670_bus_io *bus_io; - struct gpio_dt_spec gpio_int; -}; - -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42670_H_ */ diff --git a/drivers/sensor/tdk/icm42670/icm42670_i2c.c b/drivers/sensor/tdk/icm42670/icm42670_i2c.c deleted file mode 100644 index 3ee3dfef24e4b..0000000000000 --- a/drivers/sensor/tdk/icm42670/icm42670_i2c.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * Bus-specific functionality for ICM42670 accessed via I2C. - */ - -#include "icm42670.h" -#include "icm42670_reg.h" - -#if ICM42670_BUS_I2C -static int icm42670_bus_check_i2c(const union icm42670_bus *bus) -{ - return i2c_is_ready_dt(&bus->i2c) ? 0 : -ENODEV; -} - -static int i2c_read_mreg(const union icm42670_bus *bus, uint8_t reg, uint8_t bank, - uint8_t *buf, size_t len) -{ - int res = i2c_reg_write_byte_dt(&bus->i2c, REG_BLK_SEL_R, bank); - - if (res) { - return res; - } - - /* reads from MREG registers must be done byte-by-byte */ - for (size_t i = 0; i < len; i++) { - uint8_t addr = reg + i; - - res = i2c_reg_write_byte_dt(&bus->i2c, REG_MADDR_R, addr); - - if (res) { - return res; - } - - k_usleep(MREG_R_W_WAIT_US); - res = i2c_reg_read_byte_dt(&bus->i2c, REG_M_R, &buf[i]); - - if (res) { - return res; - } - - k_usleep(MREG_R_W_WAIT_US); - } - - return 0; -} - -static int icm42670_reg_read_i2c(const union icm42670_bus *bus, uint16_t reg, uint8_t *data, - size_t len) -{ - int res = 0; - uint8_t bank = FIELD_GET(REG_BANK_MASK, reg); - uint8_t address = FIELD_GET(REG_ADDRESS_MASK, reg); - - if (bank) { - res = i2c_read_mreg(bus, address, bank, data, len); - } else { - res = i2c_burst_read_dt(&bus->i2c, address, data, len); - } - - return res; -} - -static int i2c_write_mreg(const union icm42670_bus *bus, uint16_t reg, uint8_t bank, - uint8_t buf) -{ - int res = i2c_reg_write_byte_dt(&bus->i2c, REG_BLK_SEL_W, bank); - - if (res) { - return res; - } - - res = i2c_reg_write_byte_dt(&bus->i2c, REG_MADDR_W, reg); - - if (res) { - return res; - } - - res = i2c_reg_write_byte_dt(&bus->i2c, REG_M_W, buf); - - if (res) { - return res; - } - - k_usleep(MREG_R_W_WAIT_US); - - return 0; -} - -static int icm42670_reg_write_i2c(const union icm42670_bus *bus, - uint16_t reg, uint8_t data) -{ - int res = 0; - uint8_t bank = FIELD_GET(REG_BANK_MASK, reg); - uint8_t address = FIELD_GET(REG_ADDRESS_MASK, reg); - - if (bank) { - res = i2c_write_mreg(bus, address, bank, data); - } else { - res = i2c_reg_write_byte_dt(&bus->i2c, address, data); - } - - return res; -} - -static int icm42670_reg_update_i2c(const union icm42670_bus *bus, uint16_t reg, uint8_t mask, - uint8_t val) -{ - return i2c_reg_update_byte_dt(&bus->i2c, reg, mask, val); -} - -const struct icm42670_bus_io icm42670_bus_io_i2c = { - .check = icm42670_bus_check_i2c, - .read = icm42670_reg_read_i2c, - .write = icm42670_reg_write_i2c, - .update = icm42670_reg_update_i2c, -}; -#endif /* ICM42670_BUS_I2C */ diff --git a/drivers/sensor/tdk/icm42670/icm42670_reg.h b/drivers/sensor/tdk/icm42670/icm42670_reg.h deleted file mode 100644 index 6a26f859a515b..0000000000000 --- a/drivers/sensor/tdk/icm42670/icm42670_reg.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2022 Esco Medical ApS - * Copyright (c) 2020 TDK Invensense - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42670_REG_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42670_REG_H_ - -#include - -/* Helper macros for addressing registers in MREG1-3, see datasheet section 13 */ -#define REG_MADDR_BASE 0x0028 -#define REG_MREG1_SHIFT 8 -#define REG_MREG2_SHIFT 9 -#define REG_MREG3_SHIFT 10 -#define REG_BANK0_OFFSET 0x0000 -#define REG_MREG1_OFFSET (REG_MADDR_BASE << REG_MREG1_SHIFT) -#define REG_MREG2_OFFSET (REG_MADDR_BASE << REG_MREG2_SHIFT) -#define REG_MREG3_OFFSET (REG_MADDR_BASE << REG_MREG3_SHIFT) -#define REG_ADDRESS_MASK GENMASK(7, 0) -#define REG_BANK_MASK GENMASK(15, 8) -#define REG_SPI_READ_BIT BIT(7) -#define MREG_R_W_WAIT_US 20 /* 10us, but use 20us to be on the safe side */ - -/* BANK 0 */ -#define REG_MCLK_RDY (REG_BANK0_OFFSET | 0x00) -#define REG_DEVICE_CONFIG (REG_BANK0_OFFSET | 0x01) -#define REG_SIGNAL_PATH_RESET (REG_BANK0_OFFSET | 0x02) -#define REG_DRIVE_CONFIG1 (REG_BANK0_OFFSET | 0x03) -#define REG_DRIVE_CONFIG2 (REG_BANK0_OFFSET | 0x04) -#define REG_DRIVE_CONFIG3 (REG_BANK0_OFFSET | 0x05) -#define REG_INT_CONFIG (REG_BANK0_OFFSET | 0x06) -#define REG_TEMP_DATA1 (REG_BANK0_OFFSET | 0x09) -#define REG_TEMP_DATA0 (REG_BANK0_OFFSET | 0x0a) -#define REG_ACCEL_DATA_X1 (REG_BANK0_OFFSET | 0x0b) -#define REG_ACCEL_DATA_X0 (REG_BANK0_OFFSET | 0x0c) -#define REG_ACCEL_DATA_Y1 (REG_BANK0_OFFSET | 0x0d) -#define REG_ACCEL_DATA_Y0 (REG_BANK0_OFFSET | 0x0e) -#define REG_ACCEL_DATA_Z1 (REG_BANK0_OFFSET | 0x0f) -#define REG_ACCEL_DATA_Z0 (REG_BANK0_OFFSET | 0x10) -#define REG_GYRO_DATA_X1 (REG_BANK0_OFFSET | 0x11) -#define REG_GYRO_DATA_X0 (REG_BANK0_OFFSET | 0x12) -#define REG_GYRO_DATA_Y1 (REG_BANK0_OFFSET | 0x13) -#define REG_GYRO_DATA_Y0 (REG_BANK0_OFFSET | 0x14) -#define REG_GYRO_DATA_Z1 (REG_BANK0_OFFSET | 0x15) -#define REG_GYRO_DATA_Z0 (REG_BANK0_OFFSET | 0x16) -#define REG_TMST_FSYNCH (REG_BANK0_OFFSET | 0x17) -#define REG_TMST_FSYNCL (REG_BANK0_OFFSET | 0x18) -#define REG_APEX_DATA4 (REG_BANK0_OFFSET | 0x1d) -#define REG_APEX_DATA5 (REG_BANK0_OFFSET | 0x1e) -#define REG_PWR_MGMT0 (REG_BANK0_OFFSET | 0x1f) -#define REG_GYRO_CONFIG0 (REG_BANK0_OFFSET | 0x20) -#define REG_ACCEL_CONFIG0 (REG_BANK0_OFFSET | 0x21) -#define REG_TEMP_CONFIG0 (REG_BANK0_OFFSET | 0x22) -#define REG_GYRO_CONFIG1 (REG_BANK0_OFFSET | 0x23) -#define REG_ACCEL_CONFIG1 (REG_BANK0_OFFSET | 0x24) -#define REG_APEX_CONFIG0 (REG_BANK0_OFFSET | 0x25) -#define REG_APEX_CONFIG1 (REG_BANK0_OFFSET | 0x26) -#define REG_WOM_CONFIG (REG_BANK0_OFFSET | 0x27) -#define REG_FIFO_CONFIG1 (REG_BANK0_OFFSET | 0x28) -#define REG_FIFO_CONFIG2 (REG_BANK0_OFFSET | 0x29) -#define REG_FIFO_CONFIG3 (REG_BANK0_OFFSET | 0x2a) -#define REG_INT_SOURCE0 (REG_BANK0_OFFSET | 0x2b) -#define REG_INT_SOURCE1 (REG_BANK0_OFFSET | 0x2c) -#define REG_INT_SOURCE3 (REG_BANK0_OFFSET | 0x2d) -#define REG_INT_SOURCE4 (REG_BANK0_OFFSET | 0x2e) -#define REG_FIFO_LOST_PKT0 (REG_BANK0_OFFSET | 0x2f) -#define REG_FIFO_LOST_PKT1 (REG_BANK0_OFFSET | 0x30) -#define REG_APEX_DATA0 (REG_BANK0_OFFSET | 0x31) -#define REG_APEX_DATA1 (REG_BANK0_OFFSET | 0x32) -#define REG_APEX_DATA2 (REG_BANK0_OFFSET | 0x33) -#define REG_APEX_DATA3 (REG_BANK0_OFFSET | 0x34) -#define REG_INTF_CONFIG0 (REG_BANK0_OFFSET | 0x35) -#define REG_INTF_CONFIG1 (REG_BANK0_OFFSET | 0x36) -#define REG_INT_STATUS_DRDY (REG_BANK0_OFFSET | 0x39) -#define REG_INT_STATUS (REG_BANK0_OFFSET | 0x3a) -#define REG_INT_STATUS2 (REG_BANK0_OFFSET | 0x3b) -#define REG_INT_STATUS3 (REG_BANK0_OFFSET | 0x3c) -#define REG_FIFO_COUNTH (REG_BANK0_OFFSET | 0x3d) -#define REG_FIFO_COUNTL (REG_BANK0_OFFSET | 0x3e) -#define REG_FIFO_DATA (REG_BANK0_OFFSET | 0x3f) -#define REG_WHO_AM_I (REG_BANK0_OFFSET | 0x75) -#define REG_BLK_SEL_W (REG_BANK0_OFFSET | 0x79) -#define REG_MADDR_W (REG_BANK0_OFFSET | 0x7a) -#define REG_M_W (REG_BANK0_OFFSET | 0x7b) -#define REG_BLK_SEL_R (REG_BANK0_OFFSET | 0x7c) -#define REG_MADDR_R (REG_BANK0_OFFSET | 0x7d) -#define REG_M_R (REG_BANK0_OFFSET | 0x7e) - -/* MREG1 */ -#define REG_TMST_CONFIG1 (REG_MREG1_OFFSET | 0x00) -#define REG_FIFO_CONFIG5 (REG_MREG1_OFFSET | 0x01) -#define REG_FIFO_CONFIG6 (REG_MREG1_OFFSET | 0x02) -#define REG_FSYNC_CONFIG (REG_MREG1_OFFSET | 0x03) -#define REG_INT_CONFIG0 (REG_MREG1_OFFSET | 0x04) -#define REG_INT_CONFIG1 (REG_MREG1_OFFSET | 0x05) -#define REG_SENSOR_CONFIG3 (REG_MREG1_OFFSET | 0x06) -#define REG_ST_CONFIG (REG_MREG1_OFFSET | 0x13) -#define REG_SELFTEST (REG_MREG1_OFFSET | 0x14) -#define REG_INTF_CONFIG6 (REG_MREG1_OFFSET | 0x23) -#define REG_INTF_CONFIG10 (REG_MREG1_OFFSET | 0x25) -#define REG_INTF_CONFIG7 (REG_MREG1_OFFSET | 0x28) -#define REG_OTP_CONFIG (REG_MREG1_OFFSET | 0x2b) -#define REG_INT_SOURCE6 (REG_MREG1_OFFSET | 0x2f) -#define REG_INT_SOURCE7 (REG_MREG1_OFFSET | 0x30) -#define REG_INT_SOURCE8 (REG_MREG1_OFFSET | 0x31) -#define REG_INT_SOURCE9 (REG_MREG1_OFFSET | 0x32) -#define REG_INT_SOURCE10 (REG_MREG1_OFFSET | 0x33) -#define REG_APEX_CONFIG2 (REG_MREG1_OFFSET | 0x44) -#define REG_APEX_CONFIG3 (REG_MREG1_OFFSET | 0x45) -#define REG_APEX_CONFIG4 (REG_MREG1_OFFSET | 0x46) -#define REG_APEX_CONFIG5 (REG_MREG1_OFFSET | 0x47) -#define REG_APEX_CONFIG9 (REG_MREG1_OFFSET | 0x48) -#define REG_APEX_CONFIG10 (REG_MREG1_OFFSET | 0x49) -#define REG_APEX_CONFIG11 (REG_MREG1_OFFSET | 0x4a) -#define REG_ACCEL_WOM_X_THR (REG_MREG1_OFFSET | 0x4b) -#define REG_ACCEL_WOM_Y_THR (REG_MREG1_OFFSET | 0x4c) -#define REG_ACCEL_WOM_Z_THR (REG_MREG1_OFFSET | 0x4d) -#define REG_OFFSET_USER0 (REG_MREG1_OFFSET | 0x4e) -#define REG_OFFSET_USER1 (REG_MREG1_OFFSET | 0x4f) -#define REG_OFFSET_USER2 (REG_MREG1_OFFSET | 0x50) -#define REG_OFFSET_USER3 (REG_MREG1_OFFSET | 0x51) -#define REG_OFFSET_USER4 (REG_MREG1_OFFSET | 0x52) -#define REG_OFFSET_USER5 (REG_MREG1_OFFSET | 0x53) -#define REG_OFFSET_USER6 (REG_MREG1_OFFSET | 0x54) -#define REG_OFFSET_USER7 (REG_MREG1_OFFSET | 0x55) -#define REG_OFFSET_USER8 (REG_MREG1_OFFSET | 0x56) -#define REG_ST_STATUS1 (REG_MREG1_OFFSET | 0x63) -#define REG_ST_STATUS2 (REG_MREG1_OFFSET | 0x64) -#define REG_FDR_CONFIG (REG_MREG1_OFFSET | 0x66) -#define REG_APEX_CONFIG12 (REG_MREG1_OFFSET | 0x67) - -/* MREG2 */ -#define REG_OTP_CTRL7 (REG_MREG2_OFFSET | 0x06) - -/* MREG3 */ -#define REG_XA_ST_DATA3 (REG_MREG3_OFFSET | 0x00) -#define REG_YA_ST_DATA3 (REG_MREG3_OFFSET | 0x01) -#define REG_ZA_ST_DATA3 (REG_MREG3_OFFSET | 0x02) -#define REG_XG_ST_DATA3 (REG_MREG3_OFFSET | 0x03) -#define REG_YG_ST_DATA3 (REG_MREG3_OFFSET | 0x04) -#define REG_ZG_ST_DATA3 (REG_MREG3_OFFSET | 0x05) - -/* Bank0 REG_MCLK_RDY */ -#define BIT_MCLK_RDY BIT(3) - -/* Bank0 REG_DEVICE_CONFIG */ -#define BIT_SPI_AP_4WIRE BIT(2) -#define BIT_SPI_MODE BIT(0) - -/* Bank0 REG_SIGNAL_PATH_RESET */ -#define BIT_FIFO_FLUSH BIT(2) -#define BIT_SOFT_RESET BIT(4) - -/* Bank0 REG_INST_STATUS */ -#define BIT_STATUS_RESET_DONE_INT BIT(4) - -/* Bank0 REG_INT_CONFIG */ -#define BIT_INT1_POLARITY BIT(0) -#define BIT_INT1_DRIVE_CIRCUIT BIT(1) -#define BIT_INT1_MODE BIT(2) -#define BIT_INT2_POLARITY BIT(3) -#define BIT_INT2_DRIVE_CIRCUIT BIT(4) -#define BIT_INT2_MODE BIT(5) - -/* Bank0 REG_PWR_MGMT_0 */ -#define MASK_ACCEL_MODE GENMASK(1, 0) -#define BIT_ACCEL_MODE_OFF 0x00 -#define BIT_ACCEL_MODE_LPM 0x02 -#define BIT_ACCEL_MODE_LNM 0x03 -#define MASK_GYRO_MODE GENMASK(3, 2) -#define BIT_GYRO_MODE_OFF 0x00 -#define BIT_GYRO_MODE_STBY 0x01 -#define BIT_GYRO_MODE_LNM 0x03 -#define BIT_IDLE BIT(4) -#define BIT_ACCEL_LP_CLK_SEL BIT(7) - -/* Bank0 REG_INT_SOURCE0 */ -#define BIT_INT_AGC_RDY_INT1_EN BIT(0) -#define BIT_INT_FIFO_FULL_INT1_EN BIT(1) -#define BIT_INT_FIFO_THS_INT1_EN BIT(2) -#define BIT_INT_DRDY_INT1_EN BIT(3) -#define BIT_INT_RESET_DONE_INT1_EN BIT(4) -#define BIT_INT_PLL_RDY_INT1_EN BIT(5) -#define BIT_INT_FSYNC_INT1_EN BIT(6) -#define BIT_INT_ST_INT1_EN BIT(7) - -/* Bank0 REG_INT_STATUS_DRDY */ -#define BIT_INT_STATUS_DATA_DRDY BIT(0) - -/* Bank9 REG_INTF_CONFIG1 */ -#define BIT_I3C_SDR_EN BIT(3) -#define BIT_I3C_DDR_EN BIT(2) -#define MASK_CLKSEL GENMASK(1, 0) -#define BIT_CLKSEL_INT_RC 0x00 -#define BIT_CLKSEL_PLL_OR_RC 0x01 -#define BIT_CLKSEL_DISABLE 0x11 - -/* Bank0 REG_INT_STATUS */ -#define BIT_INT_STATUS_AGC_RDY BIT(0) -#define BIT_INT_STATUS_FIFO_FULL BIT(1) -#define BIT_INT_STATUS_FIFO_THS BIT(2) -#define BIT_INT_STATUS_RESET_DONE BIT(4) -#define BIT_INT_STATUS_PLL_RDY BIT(5) -#define BIT_INT_STATUS_FSYNC BIT(6) -#define BIT_INT_STATUS_ST BIT(7) - -/* Bank0 REG_INT_STATUS2 */ -#define BIT_INT_STATUS_WOM_Z BIT(0) -#define BIT_INT_STATUS_WOM_Y BIT(1) -#define BIT_INT_STATUS_WOM_X BIT(2) -#define BIT_INT_STATUS_SMD BIT(3) - -/* Bank0 REG_INT_STATUS3 */ -#define BIT_INT_STATUS_LOWG_DET BIT(1) -#define BIT_INT_STATUS_FF_DET BIT(2) -#define BIT_INT_STATUS_TILT_DET BIT(3) -#define BIT_INT_STATUS_STEP_CNT_OVFL BIT(4) -#define BIT_INT_STATUS_STEP_DET BIT(5) - -/* Bank0 REG_ACCEL_CONFIG0 */ -#define MASK_ACCEL_UI_FS_SEL GENMASK(6, 5) -#define BIT_ACCEL_UI_FS_16 0x00 -#define BIT_ACCEL_UI_FS_8 0x01 -#define BIT_ACCEL_UI_FS_4 0x02 -#define BIT_ACCEL_UI_FS_2 0x03 -#define MASK_ACCEL_ODR GENMASK(3, 0) -#define BIT_ACCEL_ODR_1600 0x05 -#define BIT_ACCEL_ODR_800 0x06 -#define BIT_ACCEL_ODR_400 0x07 -#define BIT_ACCEL_ODR_200 0x08 -#define BIT_ACCEL_ODR_100 0x09 -#define BIT_ACCEL_ODR_50 0x0A -#define BIT_ACCEL_ODR_25 0x0B -#define BIT_ACCEL_ODR_12 0x0C -#define BIT_ACCEL_ODR_6 0x0D -#define BIT_ACCEL_ODR_3 0x0E -#define BIT_ACCEL_ODR_1 0x0F - -/* Bank0 REG_GYRO_CONFIG0 */ -#define MASK_GYRO_UI_FS_SEL GENMASK(6, 5) -#define BIT_GYRO_UI_FS_2000 0x00 -#define BIT_GYRO_UI_FS_1000 0x01 -#define BIT_GYRO_UI_FS_500 0x02 -#define BIT_GYRO_UI_FS_250 0x03 -#define MASK_GYRO_ODR GENMASK(3, 0) -#define BIT_GYRO_ODR_1600 0x05 -#define BIT_GYRO_ODR_800 0x06 -#define BIT_GYRO_ODR_400 0x07 -#define BIT_GYRO_ODR_200 0x08 -#define BIT_GYRO_ODR_100 0x09 -#define BIT_GYRO_ODR_50 0x0A -#define BIT_GYRO_ODR_25 0x0B -#define BIT_GYRO_ODR_12 0x0C - -/* misc. defines */ -#define WHO_AM_I_ICM42670 0x67 -#define MIN_ACCEL_SENS_SHIFT 11 -#define ACCEL_DATA_SIZE 6 -#define GYRO_DATA_SIZE 6 -#define TEMP_DATA_SIZE 2 -#define MCLK_POLL_INTERVAL_US 250 -#define MCLK_POLL_ATTEMPTS 100 -#define SOFT_RESET_TIME_MS 2 /* 1ms + elbow room */ - -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42670_REG_H_ */ diff --git a/drivers/sensor/tdk/icm42670/icm42670_spi.c b/drivers/sensor/tdk/icm42670/icm42670_spi.c deleted file mode 100644 index ce1b7b1148499..0000000000000 --- a/drivers/sensor/tdk/icm42670/icm42670_spi.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2022 Esco Medical ApS - * Copyright (c) 2020 TDK Invensense - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "icm42670.h" -#include "icm42670_reg.h" - -#if ICM42670_BUS_SPI -static inline int spi_write_register(const union icm42670_bus *bus, uint8_t reg, uint8_t data) -{ - const struct spi_buf buf[2] = { - { - .buf = ®, - .len = 1, - }, - { - .buf = &data, - .len = 1, - } - }; - - const struct spi_buf_set tx = { - .buffers = buf, - .count = 2, - }; - - return spi_write_dt(&bus->spi, &tx); -} - -static inline int spi_read_register(const union icm42670_bus *bus, uint8_t reg, uint8_t *data, - size_t len) -{ - uint8_t tx_buffer = REG_SPI_READ_BIT | reg; - - const struct spi_buf tx_buf = { - .buf = &tx_buffer, - .len = 1, - }; - - const struct spi_buf_set tx = { - .buffers = &tx_buf, - .count = 1, - }; - - struct spi_buf rx_buf[2] = { - { - .buf = NULL, - .len = 1, - }, - { - .buf = data, - .len = len, - } - }; - - const struct spi_buf_set rx = { - .buffers = rx_buf, - .count = 2, - }; - - return spi_transceive_dt(&bus->spi, &tx, &rx); -} - -static inline int spi_read_mreg(const union icm42670_bus *bus, uint8_t reg, uint8_t bank, - uint8_t *buf, size_t len) -{ - int res = spi_write_register(bus, REG_BLK_SEL_R, bank); - - if (res) { - return res; - } - - /* reads from MREG registers must be done byte-by-byte */ - for (size_t i = 0; i < len; i++) { - uint8_t addr = reg + i; - - res = spi_write_register(bus, REG_MADDR_R, addr); - - if (res) { - return res; - } - - k_usleep(MREG_R_W_WAIT_US); - res = spi_read_register(bus, REG_M_R, &buf[i], 1); - - if (res) { - return res; - } - - k_usleep(MREG_R_W_WAIT_US); - } - - return 0; -} - -static inline int spi_write_mreg(const union icm42670_bus *bus, uint8_t reg, uint8_t bank, - uint8_t buf) -{ - int res = spi_write_register(bus, REG_BLK_SEL_W, bank); - - if (res) { - return res; - } - - res = spi_write_register(bus, REG_MADDR_W, reg); - - if (res) { - return res; - } - - res = spi_write_register(bus, REG_M_W, buf); - - if (res) { - return res; - } - - k_usleep(MREG_R_W_WAIT_US); - - return 0; -} - -int icm42670_spi_read(const union icm42670_bus *bus, uint16_t reg, uint8_t *data, size_t len) -{ - int res = 0; - uint8_t bank = FIELD_GET(REG_BANK_MASK, reg); - uint8_t address = FIELD_GET(REG_ADDRESS_MASK, reg); - - if (bank) { - res = spi_read_mreg(bus, address, bank, data, len); - } else { - res = spi_read_register(bus, address, data, len); - } - - return res; -} - -int icm42670_spi_single_write(const union icm42670_bus *bus, uint16_t reg, uint8_t data) -{ - int res = 0; - uint8_t bank = FIELD_GET(REG_BANK_MASK, reg); - uint8_t address = FIELD_GET(REG_ADDRESS_MASK, reg); - - if (bank) { - res = spi_write_mreg(bus, address, bank, data); - } else { - res = spi_write_register(bus, address, data); - } - - return res; -} - -int icm42670_spi_update_register(const union icm42670_bus *bus, uint16_t reg, uint8_t mask, - uint8_t data) -{ - uint8_t temp = 0; - int res = icm42670_spi_read(bus, reg, &temp, 1); - - if (res) { - return res; - } - - temp &= ~mask; - temp |= FIELD_PREP(mask, data); - - return icm42670_spi_single_write(bus, reg, temp); -} - -static int icm42670_bus_check_spi(const union icm42670_bus *bus) -{ - return spi_is_ready_dt(&bus->spi) ? 0 : -ENODEV; -} - -const struct icm42670_bus_io icm42670_bus_io_spi = { - .check = icm42670_bus_check_spi, - .read = icm42670_spi_read, - .write = icm42670_spi_single_write, - .update = icm42670_spi_update_register, -}; - -#endif /* ICM42670_BUS_SPI */ diff --git a/drivers/sensor/tdk/icm42670/icm42670_trigger.c b/drivers/sensor/tdk/icm42670/icm42670_trigger.c deleted file mode 100644 index 3d84d884e8049..0000000000000 --- a/drivers/sensor/tdk/icm42670/icm42670_trigger.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2022 Esco Medical ApS - * Copyright (c) 2016 TDK Invensense - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include "icm42670.h" -#include "icm42670_reg.h" -#include "icm42670_trigger.h" - -#include -LOG_MODULE_DECLARE(ICM42670, CONFIG_SENSOR_LOG_LEVEL); - -static void icm42670_gpio_callback(const struct device *dev, struct gpio_callback *cb, - uint32_t pins) -{ - ARG_UNUSED(dev); - ARG_UNUSED(pins); - - struct icm42670_data *data = CONTAINER_OF(cb, struct icm42670_data, gpio_cb); - -#if defined(CONFIG_ICM42670_TRIGGER_OWN_THREAD) - k_sem_give(&data->gpio_sem); -#elif defined(CONFIG_ICM42670_TRIGGER_GLOBAL_THREAD) - k_work_submit(&data->work); -#endif -} - -static void icm42670_thread_cb(const struct device *dev) -{ - struct icm42670_data *data = dev->data; - const struct icm42670_config *cfg = dev->config; - - icm42670_lock(dev); - gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_DISABLE); - - if (data->data_ready_handler) { - data->data_ready_handler(dev, data->data_ready_trigger); - } - - gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); - icm42670_unlock(dev); -} - -#if defined(CONFIG_ICM42670_TRIGGER_OWN_THREAD) - -static void icm42670_thread(void *p1, void *p2, void *p3) -{ - ARG_UNUSED(p2); - ARG_UNUSED(p3); - - struct icm42670_data *data = p1; - - while (1) { - k_sem_take(&data->gpio_sem, K_FOREVER); - icm42670_thread_cb(data->dev); - } -} - -#elif defined(CONFIG_ICM42670_TRIGGER_GLOBAL_THREAD) - -static void icm42670_work_handler(struct k_work *work) -{ - struct icm42670_data *data = CONTAINER_OF(work, struct icm42670_data, work); - - icm42670_thread_cb(data->dev); -} - -#endif - -int icm42670_trigger_set(const struct device *dev, const struct sensor_trigger *trig, - sensor_trigger_handler_t handler) -{ - int res = 0; - struct icm42670_data *data = dev->data; - const struct icm42670_config *cfg = dev->config; - - if (!handler) { - return -EINVAL; - } - - icm42670_lock(dev); - gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_DISABLE); - - switch (trig->type) { - case SENSOR_TRIG_DATA_READY: - data->data_ready_handler = handler; - data->data_ready_trigger = trig; - break; - default: - res = -ENOTSUP; - break; - } - - icm42670_unlock(dev); - gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); - - return res; -} - -int icm42670_trigger_init(const struct device *dev) -{ - struct icm42670_data *data = dev->data; - const struct icm42670_config *cfg = dev->config; - int res = 0; - - if (!cfg->gpio_int.port) { - LOG_ERR("trigger enabled but no interrupt gpio supplied"); - return -ENODEV; - } - - if (!gpio_is_ready_dt(&cfg->gpio_int)) { - LOG_ERR("gpio_int gpio not ready"); - return -ENODEV; - } - - data->dev = dev; - gpio_pin_configure_dt(&cfg->gpio_int, GPIO_INPUT); - gpio_init_callback(&data->gpio_cb, icm42670_gpio_callback, BIT(cfg->gpio_int.pin)); - res = gpio_add_callback(cfg->gpio_int.port, &data->gpio_cb); - - if (res < 0) { - LOG_ERR("Failed to set gpio callback"); - return res; - } - - k_mutex_init(&data->mutex); - -#if defined(CONFIG_ICM42670_TRIGGER_OWN_THREAD) - k_sem_init(&data->gpio_sem, 0, K_SEM_MAX_LIMIT); - k_thread_create(&data->thread, data->thread_stack, CONFIG_ICM42670_THREAD_STACK_SIZE, - icm42670_thread, data, NULL, NULL, - K_PRIO_COOP(CONFIG_ICM42670_THREAD_PRIORITY), 0, K_NO_WAIT); -#elif defined(CONFIG_ICM42670_TRIGGER_GLOBAL_THREAD) - data->work.handler = icm42670_work_handler; -#endif - - return gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); -} - -int icm42670_trigger_enable_interrupt(const struct device *dev) -{ - int res; - const struct icm42670_config *cfg = dev->config; - - /* pulse-mode (auto clearing), push-pull and active-high */ - res = cfg->bus_io->write(&cfg->bus, REG_INT_CONFIG, - BIT_INT1_DRIVE_CIRCUIT | BIT_INT1_POLARITY); - - if (res) { - return res; - } - - /* enable data ready interrupt on INT1 pin */ - return cfg->bus_io->write(&cfg->bus, REG_INT_SOURCE0, BIT_INT_DRDY_INT1_EN); -} - -void icm42670_lock(const struct device *dev) -{ - struct icm42670_data *data = dev->data; - - k_mutex_lock(&data->mutex, K_FOREVER); -} - -void icm42670_unlock(const struct device *dev) -{ - struct icm42670_data *data = dev->data; - - k_mutex_unlock(&data->mutex); -} diff --git a/drivers/sensor/tdk/icm42670/icm42670_trigger.h b/drivers/sensor/tdk/icm42670/icm42670_trigger.h deleted file mode 100644 index 7a9d2e1ab0bc0..0000000000000 --- a/drivers/sensor/tdk/icm42670/icm42670_trigger.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2022 Esco Medical ApS - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42670_TRIGGER_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42670_TRIGGER_H_ - -#include - -/** implement the trigger_set sensor api function */ -int icm42670_trigger_set(const struct device *dev, const struct sensor_trigger *trig, - sensor_trigger_handler_t handler); - -/** - * @brief initialize the icm42670 trigger system - * - * @param dev icm42670 device pointer - * @return int 0 on success, negative error code otherwise - */ -int icm42670_trigger_init(const struct device *dev); - -/** - * @brief enable the trigger gpio interrupt - * - * @param dev icm42670 device pointer - * @return int 0 on success, negative error code otherwise - */ -int icm42670_trigger_enable_interrupt(const struct device *dev); - -/** - * @brief lock access to the icm42670 device driver - * - * @param dev icm42670 device pointer - */ -void icm42670_lock(const struct device *dev); - -/** - * @brief lock access to the icm42670 device driver - * - * @param dev icm42670 device pointer - */ -void icm42670_unlock(const struct device *dev); - -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42670_TRIGGER_H_ */ diff --git a/drivers/sensor/tdk/icm42688/icm42688.h b/drivers/sensor/tdk/icm42688/icm42688.h index 5ca61a82cfae8..410f0f983fbd0 100644 --- a/drivers/sensor/tdk/icm42688/icm42688.h +++ b/drivers/sensor/tdk/icm42688/icm42688.h @@ -506,7 +506,7 @@ static inline void icm42688_gyro_dps(const struct icm42688_cfg *cfg, int32_t in, static inline void icm42688_accel_ms(const struct icm42688_cfg *cfg, int32_t in, int32_t *out_ms, int32_t *out_ums) { - int64_t sensitivity = 0; /* value equivalent for 1g */ + int64_t sensitivity; switch (cfg->accel_fs) { case ICM42688_DT_ACCEL_FS_2: @@ -521,6 +521,8 @@ static inline void icm42688_accel_ms(const struct icm42688_cfg *cfg, int32_t in, case ICM42688_DT_ACCEL_FS_16: sensitivity = 2048; break; + default: + CODE_UNREACHABLE; } /* Convert to micrometers/s^2 */ @@ -544,7 +546,7 @@ static inline void icm42688_accel_ms(const struct icm42688_cfg *cfg, int32_t in, static inline void icm42688_gyro_rads(const struct icm42688_cfg *cfg, int32_t in, int32_t *out_rads, int32_t *out_urads) { - int64_t sensitivity = 0; /* value equivalent for 10x gyro reading deg/s */ + int64_t sensitivity; switch (cfg->gyro_fs) { case ICM42688_DT_GYRO_FS_2000: @@ -571,6 +573,8 @@ static inline void icm42688_gyro_rads(const struct icm42688_cfg *cfg, int32_t in case ICM42688_DT_GYRO_FS_15_625: sensitivity = 20972; break; + default: + CODE_UNREACHABLE; } int64_t in10_rads = (int64_t)in * SENSOR_PI * 10LL; diff --git a/drivers/sensor/tdk/icm42688/icm42688_common.c b/drivers/sensor/tdk/icm42688/icm42688_common.c index 3a0c79869be9c..b674b07009a8d 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_common.c +++ b/drivers/sensor/tdk/icm42688/icm42688_common.c @@ -255,8 +255,11 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) * temp/accel/gyro en fields in cfg */ uint8_t fifo_cfg1 = - FIELD_PREP(BIT_FIFO_TEMP_EN, 1) | FIELD_PREP(BIT_FIFO_GYRO_EN, 1) | - FIELD_PREP(BIT_FIFO_ACCEL_EN, 1) | FIELD_PREP(BIT_FIFO_TMST_FSYNC_EN, 1); + FIELD_PREP(BIT_FIFO_TEMP_EN, 1) | + FIELD_PREP(BIT_FIFO_GYRO_EN, 1) | + FIELD_PREP(BIT_FIFO_ACCEL_EN, 1) | + FIELD_PREP(BIT_FIFO_TMST_FSYNC_EN, 1) | + FIELD_PREP(BIT_FIFO_HIRES_EN, 1); LOG_DBG("FIFO_CONFIG1 (0x%x) 0x%x", REG_FIFO_CONFIG1, fifo_cfg1); res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG1, fifo_cfg1); diff --git a/drivers/sensor/tdk/icm42688/icm42688_decoder.c b/drivers/sensor/tdk/icm42688/icm42688_decoder.c index c01cc3f9c27e1..bb2730ef70802 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_decoder.c +++ b/drivers/sensor/tdk/icm42688/icm42688_decoder.c @@ -10,6 +10,8 @@ #include #include +#include + LOG_MODULE_REGISTER(ICM42688_DECODER, CONFIG_SENSOR_LOG_LEVEL); #define DT_DRV_COMPAT invensense_icm42688 @@ -183,6 +185,8 @@ int icm42688_encode(const struct device *dev, const struct sensor_chan_spec *con { struct icm42688_dev_data *data = dev->data; struct icm42688_encoded_data *edata = (struct icm42688_encoded_data *)buf; + uint64_t cycles; + int rc; edata->channels = 0; @@ -190,10 +194,15 @@ int icm42688_encode(const struct device *dev, const struct sensor_chan_spec *con edata->channels |= icm42688_encode_channel(channels[i].chan_type); } + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + return rc; + } + edata->header.is_fifo = false; edata->header.accel_fs = data->cfg.accel_fs; edata->header.gyro_fs = data->cfg.gyro_fs; - edata->header.timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); return 0; } @@ -234,81 +243,33 @@ static inline q31_t icm42688_read_temperature_from_packet(const uint8_t *pkt) static int icm42688_read_imu_from_packet(const uint8_t *pkt, bool is_accel, int fs, uint8_t axis_offset, q31_t *out) { - int32_t value; - int64_t scale = 0; - int32_t max = BIT(15); + uint32_t unsigned_value; + int32_t signed_value; + bool is_hires = FIELD_GET(FIFO_HEADER_ACCEL, pkt[0]) == 1; int offset = 1 + (axis_offset * 2); - if (is_accel) { - switch (fs) { - case ICM42688_DT_ACCEL_FS_2: - scale = INT64_C(2) * BIT(31 - 5) * 9.80665; - break; - case ICM42688_DT_ACCEL_FS_4: - scale = INT64_C(4) * BIT(31 - 6) * 9.80665; - break; - case ICM42688_DT_ACCEL_FS_8: - scale = INT64_C(8) * BIT(31 - 7) * 9.80665; - break; - case ICM42688_DT_ACCEL_FS_16: - scale = INT64_C(16) * BIT(31 - 8) * 9.80665; - break; - } - } else { - switch (fs) { - case ICM42688_DT_GYRO_FS_2000: - scale = 164; - break; - case ICM42688_DT_GYRO_FS_1000: - scale = 328; - break; - case ICM42688_DT_GYRO_FS_500: - scale = 655; - break; - case ICM42688_DT_GYRO_FS_250: - scale = 1310; - break; - case ICM42688_DT_GYRO_FS_125: - scale = 2620; - break; - case ICM42688_DT_GYRO_FS_62_5: - scale = 5243; - break; - case ICM42688_DT_GYRO_FS_31_25: - scale = 10486; - break; - case ICM42688_DT_GYRO_FS_15_625: - scale = 20972; - break; - } - } + const uint32_t scale[2][2] = { + /* low-res, hi-res */ + {35744, 8936}, /* gyro */ + {40168, 2511}, /* accel */ + }; if (!is_accel && FIELD_GET(FIFO_HEADER_ACCEL, pkt[0]) == 1) { - offset += 7; + offset += 6; } - value = (int16_t)sys_le16_to_cpu((pkt[offset] << 8) | pkt[offset + 1]); + unsigned_value = (pkt[offset] << 8) | pkt[offset + 1]; - if (FIELD_GET(FIFO_HEADER_20, pkt[0]) == 1) { + if (is_hires) { uint32_t mask = is_accel ? GENMASK(7, 4) : GENMASK(3, 0); - - offset = 0x11 + axis_offset; - value = (value << 4) | FIELD_GET(mask, pkt[offset]); - /* In 20 bit mode, FS can only be +/-16g and +/-2000dps */ - scale = is_accel ? (INT64_C(16) * BIT(8) * 9.80665) : 131; - max = is_accel ? BIT(18) : BIT(19); - if (value == -524288) { - /* Invalid 20 bit value */ - return -ENODATA; - } + offset = 17 + axis_offset; + unsigned_value = (unsigned_value << 4) | FIELD_GET(mask, pkt[offset]); + signed_value = unsigned_value | (0 - (unsigned_value & BIT(19))); } else { - if (value <= -32767) { - /* Invalid 16 bit value */ - return -ENODATA; - } + signed_value = unsigned_value | (0 - (unsigned_value & BIT(16))); } - *out = (q31_t)(value * scale / max); + *out = (q31_t)(signed_value * scale[is_accel][is_hires]); return 0; } @@ -425,7 +386,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c /* Decode gyro */ struct sensor_three_axis_data *data = (struct sensor_three_axis_data *)data_out; - uint64_t period_ns = accel_period_ns[edata->gyro_odr]; + uint64_t period_ns = gyro_period_ns[edata->gyro_odr]; icm42688_get_shift(SENSOR_CHAN_GYRO_XYZ, edata->header.accel_fs, edata->header.gyro_fs, &data->shift); @@ -473,42 +434,36 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, struct sensor_chan_sp case SENSOR_CHAN_ACCEL_X: case SENSOR_CHAN_ACCEL_Y: case SENSOR_CHAN_ACCEL_Z: - case SENSOR_CHAN_ACCEL_XYZ: { - channel_request = icm42688_encode_channel(SENSOR_CHAN_ACCEL_XYZ); + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_DIE_TEMP: { + channel_request = icm42688_encode_channel(chan_spec.chan_type); if ((channel_request & edata->channels) != channel_request) { return -ENODATA; } - struct sensor_three_axis_data *out = data_out; + struct sensor_q31_data *out = data_out; out->header.base_timestamp_ns = edata->header.timestamp; out->header.reading_count = 1; - rc = icm42688_get_shift(SENSOR_CHAN_ACCEL_XYZ, header->accel_fs, header->gyro_fs, + + rc = icm42688_get_shift(chan_spec.chan_type, header->accel_fs, header->gyro_fs, &out->shift); if (rc != 0) { return -EINVAL; } icm42688_convert_raw_to_q31( - &cfg, SENSOR_CHAN_ACCEL_X, - edata->readings[icm42688_get_channel_position(SENSOR_CHAN_ACCEL_X)], - &out->readings[0].x); - icm42688_convert_raw_to_q31( - &cfg, SENSOR_CHAN_ACCEL_Y, - edata->readings[icm42688_get_channel_position(SENSOR_CHAN_ACCEL_Y)], - &out->readings[0].y); - icm42688_convert_raw_to_q31( - &cfg, SENSOR_CHAN_ACCEL_Z, - edata->readings[icm42688_get_channel_position(SENSOR_CHAN_ACCEL_Z)], - &out->readings[0].z); + &cfg, chan_spec.chan_type, + edata->readings[icm42688_get_channel_position(chan_spec.chan_type)], + &out->readings[0].value); *fit = 1; return 1; } - case SENSOR_CHAN_GYRO_X: - case SENSOR_CHAN_GYRO_Y: - case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_ACCEL_XYZ: case SENSOR_CHAN_GYRO_XYZ: { - channel_request = icm42688_encode_channel(SENSOR_CHAN_GYRO_XYZ); + channel_request = icm42688_encode_channel(chan_spec.chan_type); if ((channel_request & edata->channels) != channel_request) { return -ENODATA; } @@ -517,52 +472,27 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, struct sensor_chan_sp out->header.base_timestamp_ns = edata->header.timestamp; out->header.reading_count = 1; - rc = icm42688_get_shift(SENSOR_CHAN_GYRO_XYZ, header->accel_fs, header->gyro_fs, + rc = icm42688_get_shift(chan_spec.chan_type, header->accel_fs, header->gyro_fs, &out->shift); if (rc != 0) { return -EINVAL; } - out->readings[0].timestamp_delta = 0; icm42688_convert_raw_to_q31( - &cfg, SENSOR_CHAN_GYRO_X, - edata->readings[icm42688_get_channel_position(SENSOR_CHAN_GYRO_X)], + &cfg, chan_spec.chan_type - 3, + edata->readings[icm42688_get_channel_position(chan_spec.chan_type - 3)], &out->readings[0].x); icm42688_convert_raw_to_q31( - &cfg, SENSOR_CHAN_GYRO_Y, - edata->readings[icm42688_get_channel_position(SENSOR_CHAN_GYRO_Y)], + &cfg, chan_spec.chan_type - 2, + edata->readings[icm42688_get_channel_position(chan_spec.chan_type - 2)], &out->readings[0].y); icm42688_convert_raw_to_q31( - &cfg, SENSOR_CHAN_GYRO_Z, - edata->readings[icm42688_get_channel_position(SENSOR_CHAN_GYRO_Z)], + &cfg, chan_spec.chan_type - 1, + edata->readings[icm42688_get_channel_position(chan_spec.chan_type - 1)], &out->readings[0].z); *fit = 1; return 1; } - case SENSOR_CHAN_DIE_TEMP: { - channel_request = icm42688_encode_channel(SENSOR_CHAN_DIE_TEMP); - if ((channel_request & edata->channels) != channel_request) { - return -ENODATA; - } - - struct sensor_q31_data *out = data_out; - - out->header.base_timestamp_ns = edata->header.timestamp; - out->header.reading_count = 1; - - rc = icm42688_get_shift(SENSOR_CHAN_DIE_TEMP, header->accel_fs, header->gyro_fs, - &out->shift); - if (rc != 0) { - return -EINVAL; - } - out->readings[0].timestamp_delta = 0; - icm42688_convert_raw_to_q31( - &cfg, SENSOR_CHAN_DIE_TEMP, - edata->readings[icm42688_get_channel_position(SENSOR_CHAN_DIE_TEMP)], - &out->readings[0].temperature); - *fit = 1; - return 1; - } default: return -EINVAL; } @@ -585,12 +515,21 @@ static int icm42688_decoder_get_frame_count(const uint8_t *buffer, uint16_t *frame_count) { const struct icm42688_fifo_data *data = (const struct icm42688_fifo_data *)buffer; + const struct icm42688_encoded_data *enc_data = (const struct icm42688_encoded_data *)buffer; const struct icm42688_decoder_header *header = &data->header; if (chan_spec.chan_idx != 0) { return -ENOTSUP; } + uint8_t channel_request = icm42688_encode_channel(chan_spec.chan_type); + + + if ((!enc_data->header.is_fifo) && + (enc_data->channels & channel_request) != channel_request) { + return -ENODATA; + } + if (!header->is_fifo) { switch (chan_spec.chan_type) { case SENSOR_CHAN_ACCEL_X: @@ -645,17 +584,17 @@ static int icm42688_decoder_get_size_info(struct sensor_chan_spec chan_spec, siz size_t *frame_size) { switch (chan_spec.chan_type) { + case SENSOR_CHAN_ACCEL_XYZ: + case SENSOR_CHAN_GYRO_XYZ: + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; case SENSOR_CHAN_ACCEL_X: case SENSOR_CHAN_ACCEL_Y: case SENSOR_CHAN_ACCEL_Z: - case SENSOR_CHAN_ACCEL_XYZ: case SENSOR_CHAN_GYRO_X: case SENSOR_CHAN_GYRO_Y: case SENSOR_CHAN_GYRO_Z: - case SENSOR_CHAN_GYRO_XYZ: - *base_size = sizeof(struct sensor_three_axis_data); - *frame_size = sizeof(struct sensor_three_axis_sample_data); - return 0; case SENSOR_CHAN_DIE_TEMP: *base_size = sizeof(struct sensor_q31_data); *frame_size = sizeof(struct sensor_q31_sample_data); diff --git a/drivers/sensor/tdk/icm42688/icm42688_reg.h b/drivers/sensor/tdk/icm42688/icm42688_reg.h index 5f3b58f0b3c07..486a745ad53c7 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_reg.h +++ b/drivers/sensor/tdk/icm42688/icm42688_reg.h @@ -254,9 +254,9 @@ #define BIT_FIFO_WM_GT_TH BIT(5) #define BIT_FIFO_HIRES_EN BIT(4) #define BIT_FIFO_TMST_FSYNC_EN BIT(3) -#define BIT_FIFO_GYRO_EN BIT(2) -#define BIT_FIFO_ACCEL_EN BIT(1) -#define BIT_FIFO_TEMP_EN BIT(0) +#define BIT_FIFO_TEMP_EN BIT(2) +#define BIT_FIFO_GYRO_EN BIT(1) +#define BIT_FIFO_ACCEL_EN BIT(0) /* Bank0 INT_SOURCE0 */ #define BIT_UI_FSYNC_INT1_EN BIT(6) diff --git a/drivers/sensor/tdk/icm42688/icm42688_rtio.c b/drivers/sensor/tdk/icm42688/icm42688_rtio.c index aaa640699f9d7..1d865110758ec 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_rtio.c +++ b/drivers/sensor/tdk/icm42688/icm42688_rtio.c @@ -66,7 +66,12 @@ static void icm42688_submit_one_shot(const struct device *dev, struct rtio_iodev edata = (struct icm42688_encoded_data *)buf; - icm42688_encode(dev, channels, num_channels, buf); + rc = icm42688_encode(dev, channels, num_channels, buf); + if (rc != 0) { + LOG_ERR("Failed to encode sensor data"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } rc = icm42688_rtio_sample_fetch(dev, edata->readings); /* Check that the fetch succeeded */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_rtio_stream.c b/drivers/sensor/tdk/icm42688/icm42688_rtio_stream.c index fd901742309dd..e6f2a60b8fcae 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_rtio_stream.c +++ b/drivers/sensor/tdk/icm42688/icm42688_rtio_stream.c @@ -5,7 +5,7 @@ */ #include - +#include #include "icm42688.h" #include "icm42688_decoder.h" #include "icm42688_reg.h" @@ -130,7 +130,7 @@ static void icm42688_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, v read_len = pkts * packet_size; ((struct icm42688_fifo_data *)buf)->fifo_count = read_len; - __ASSERT_NO_MSG(read_len % pkt_size == 0); + __ASSERT_NO_MSG(read_len % packet_size == 0); uint8_t *read_buf = buf + sizeof(hdr); @@ -292,12 +292,21 @@ void icm42688_fifo_event(const struct device *dev) struct icm42688_dev_data *drv_data = dev->data; struct rtio_iodev *spi_iodev = drv_data->spi_iodev; struct rtio *r = drv_data->r; + uint64_t cycles; + int rc; if (drv_data->streaming_sqe == NULL) { return; } - drv_data->timestamp = k_ticks_to_ns_floor64(k_uptime_ticks()); + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(drv_data->streaming_sqe, rc); + return; + } + + drv_data->timestamp = sensor_clock_cycles_to_ns(cycles); /* * Setup rtio chain of ops with inline calls to make decisions diff --git a/drivers/sensor/tdk/icm42x70/CMakeLists.txt b/drivers/sensor/tdk/icm42x70/CMakeLists.txt new file mode 100644 index 0000000000000..0fd3a92aaa2bb --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/CMakeLists.txt @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(icm42x70.c) + +zephyr_library_sources_ifdef(CONFIG_SPI icm42x70_spi.c) +zephyr_library_sources_ifdef(CONFIG_I2C icm42x70_i2c.c) + +zephyr_library_sources_ifdef(CONFIG_USE_EMD_ICM42670 icm42670.c) + +zephyr_library_sources_ifdef(CONFIG_ICM42X70_TRIGGER icm42x70_trigger.c) +zephyr_library_sources_ifdef(CONFIG_TDK_APEX icm42x70_apex.c) diff --git a/drivers/sensor/tdk/icm42x70/Kconfig b/drivers/sensor/tdk/icm42x70/Kconfig new file mode 100644 index 0000000000000..bc218388e2427 --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/Kconfig @@ -0,0 +1,88 @@ +# ICM42670-P ICM42670-S Six-Axis Motion Tracking device configuration options +# +# Copyright (c) 2024 TDK Invensense +# Copyright (c) 2022 Esco Medical ApS +# Copyright (c) 2020 TDK Invensense +# +# SPDX-License-Identifier: Apache-2.0 +config TDK_APEX + bool + +menuconfig ICM42X70 + bool "ICM42670-P/-S Six-Axis or ICM42370-P Three-Axis Motion Tracking Device" + default y + depends on DT_HAS_INVENSENSE_ICM42670P_ENABLED \ + || DT_HAS_INVENSENSE_ICM42670S_ENABLED \ + || DT_HAS_INVENSENSE_ICM42370P_ENABLED + depends on ZEPHYR_HAL_TDK_MODULE + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM42670P),spi) \ + || $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM42670S),spi) \ + || $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM42370P),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM42670P),i2c) \ + || $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM42670S),i2c) \ + || $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM42370P),i2c) + select TDK_APEX if $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42670p),apex,pedometer) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42670p),apex,tilt) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42670p),apex,smd) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42670p),apex,wom) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42670s),apex,pedometer) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42670s),apex,tilt) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42670s),apex,smd) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42670s),apex,wom) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42370p),apex,pedometer) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42370p),apex,tilt) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42370p),apex,smd) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,icm42370p),apex,wom) + select USE_EMD_ICM42670 if DT_HAS_INVENSENSE_ICM42670P_ENABLED || DT_HAS_INVENSENSE_ICM42670S_ENABLED + select USE_EMD_ICM42370 if DT_HAS_INVENSENSE_ICM42370P_ENABLED + select SENSOR_ASYNC_API + help + Enable driver for ICM42x70 SPI-based or I2C-based Six-Axis or Three-Axis Motion Tracking device. + +if ICM42X70 + +choice ICM42X70_TRIGGER_MODE + prompt "Trigger mode" + default ICM42X70_TRIGGER_NONE + help + Specify the type of triggering to be used by the driver. + +config ICM42X70_TRIGGER_NONE + bool "No trigger" + +config ICM42X70_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on GPIO + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42670P),int-gpios) \ + || $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42670S),int-gpios) \ + || $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42370P),int-gpios) + select ICM42X70_TRIGGER + +config ICM42X70_TRIGGER_OWN_THREAD + bool "Use own thread" + depends on GPIO + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42670P),int-gpios) \ + || $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42670S),int-gpios) \ + || $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42370P),int-gpios) + select ICM42X70_TRIGGER + +endchoice + +config ICM42X70_TRIGGER + bool + +config ICM42X70_THREAD_PRIORITY + int "Thread priority" + depends on ICM42X70_TRIGGER_OWN_THREAD + default 10 + help + Priority of thread used by the driver to handle interrupts. + +config ICM42X70_THREAD_STACK_SIZE + int "Thread stack size" + depends on ICM42X70_TRIGGER_OWN_THREAD + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + +endif # ICM42X70 diff --git a/drivers/sensor/tdk/icm42x70/icm42670.c b/drivers/sensor/tdk/icm42x70/icm42670.c new file mode 100644 index 0000000000000..5da95ed7cf2b7 --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42670.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2025 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "icm42670.h" + +#include +#include + +#include +LOG_MODULE_REGISTER(ICM42670, CONFIG_SENSOR_LOG_LEVEL); + +static uint32_t convert_gyr_fs_to_bitfield(uint32_t val, uint16_t *fs) +{ + uint32_t bitfield = 0; + + if (val < 500 && val >= 250) { + bitfield = GYRO_CONFIG0_FS_SEL_250dps; + *fs = 250; + } else if (val < 1000 && val >= 500) { + bitfield = GYRO_CONFIG0_FS_SEL_500dps; + *fs = 500; + } else if (val < 2000 && val >= 1000) { + bitfield = GYRO_CONFIG0_FS_SEL_1000dps; + *fs = 1000; + } else if (val == 2000) { + bitfield = GYRO_CONFIG0_FS_SEL_2000dps; + *fs = 2000; + } + return bitfield; +} + +static int icm42670_set_gyro_odr(struct icm42x70_data *drv_data, const struct sensor_value *val) +{ + if (val->val1 <= 1600 && val->val1 >= 12) { + if (drv_data->gyro_hz == 0) { + inv_imu_set_gyro_frequency( + &drv_data->driver, + convert_freq_to_bitfield(val->val1, &drv_data->gyro_hz)); + inv_imu_enable_gyro_low_noise_mode(&drv_data->driver); + } else { + inv_imu_set_gyro_frequency( + &drv_data->driver, + convert_freq_to_bitfield(val->val1, &drv_data->gyro_hz)); + } + } else if (val->val1 == 0) { + inv_imu_disable_gyro(&drv_data->driver); + drv_data->gyro_hz = val->val1; + } else { + LOG_ERR("Incorrect sampling value"); + return -EINVAL; + } + return 0; +} + +static int icm42670_set_gyro_fs(struct icm42x70_data *drv_data, const struct sensor_value *val) +{ + int32_t val_dps = sensor_rad_to_degrees(val); + + if (val_dps > 2000 || val_dps < 250) { + LOG_ERR("Incorrect fullscale value"); + return -EINVAL; + } + inv_imu_set_gyro_fsr(&drv_data->driver, + convert_gyr_fs_to_bitfield(val_dps, &drv_data->gyro_fs)); + LOG_DBG("Set gyro fullscale to: %d dps", drv_data->gyro_fs); + return 0; +} + +int icm42670_gyro_config(struct icm42x70_data *drv_data, enum sensor_attribute attr, + const struct sensor_value *val) +{ + if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { + icm42670_set_gyro_odr(drv_data, val); + + } else if (attr == SENSOR_ATTR_FULL_SCALE) { + icm42670_set_gyro_fs(drv_data, val); + + } else if ((enum sensor_attribute_icm42x70)attr == SENSOR_ATTR_BW_FILTER_LPF) { + if (val->val1 > 180) { + LOG_ERR("Incorrect low pass filter bandwidth value"); + return -EINVAL; + } + inv_imu_set_gyro_ln_bw(&drv_data->driver, convert_ln_bw_to_bitfield(val->val1)); + + } else { + LOG_ERR("Unsupported attribute"); + return -EINVAL; + } + return 0; +} + +void icm42670_convert_gyro(struct sensor_value *val, int16_t raw_val, uint16_t fs) +{ + int64_t conv_val; + + /* 16 bit gyroscope. 2^15 bits represent the range in degrees/s */ + /* see datasheet section 3.1 for details */ + conv_val = ((int64_t)raw_val * fs * SENSOR_PI) / (INT16_MAX * 180U); + + val->val1 = conv_val / 1000000; + val->val2 = conv_val % 1000000; +} + +int icm42670_sample_fetch_gyro(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + uint8_t buffer[GYRO_DATA_SIZE]; + + int res = inv_imu_read_reg(&data->driver, GYRO_DATA_X1, GYRO_DATA_SIZE, buffer); + + if (res) { + return res; + } + + data->gyro_x = (int16_t)sys_get_be16(&buffer[0]); + data->gyro_y = (int16_t)sys_get_be16(&buffer[2]); + data->gyro_z = (int16_t)sys_get_be16(&buffer[4]); + + return 0; +} + +uint16_t convert_bitfield_to_gyr_fs(uint8_t bitfield) +{ + uint16_t gyr_fs = 0; + + if (bitfield == GYRO_CONFIG0_FS_SEL_250dps) { + gyr_fs = 250; + } else if (bitfield == GYRO_CONFIG0_FS_SEL_500dps) { + gyr_fs = 500; + } else if (bitfield == GYRO_CONFIG0_FS_SEL_1000dps) { + gyr_fs = 1000; + } else if (bitfield == GYRO_CONFIG0_FS_SEL_2000dps) { + gyr_fs = 2000; + } + return gyr_fs; +} diff --git a/drivers/sensor/tdk/icm42x70/icm42670.h b/drivers/sensor/tdk/icm42x70/icm42670.h new file mode 100644 index 0000000000000..abff4cf478e1c --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42670.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42670_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM42670_H_ + +#include +#include +#include + +#include "icm42x70.h" + +int icm42670_gyro_config(struct icm42x70_data *drv_data, enum sensor_attribute attr, + const struct sensor_value *val); +void icm42670_convert_gyro(struct sensor_value *val, int16_t raw_val, uint16_t fs); +int icm42670_sample_fetch_gyro(const struct device *dev); +uint16_t convert_bitfield_to_gyr_fs(uint8_t bitfield); + +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42670_H_ */ diff --git a/drivers/sensor/tdk/icm42x70/icm42x70.c b/drivers/sensor/tdk/icm42x70/icm42x70.c new file mode 100644 index 0000000000000..4e52c83d923ff --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42x70.c @@ -0,0 +1,1032 @@ +/* + * Copyright (c) 2024 TDK Invensense + * Copyright (c) 2022 Esco Medical ApS + * Copyright (c) 2020 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "icm42x70.h" +#include "icm42x70_trigger.h" +#include "icm42670.h" + +#include +LOG_MODULE_REGISTER(ICM42X70, CONFIG_SENSOR_LOG_LEVEL); + +/* Convert DT enum to sensor ODR selection */ +#define ICM42X70_CONVERT_ENUM_TO_ODR_POS (4) + +/* Maximum bytes to read/write on ICM42X70 serial interface */ +#define ICM42X70_SERIAL_INTERFACE_MAX_READ (1024 * 32) +#define ICM42X70_SERIAL_INTERFACE_MAX_WRITE (1024 * 32) + +static inline int icm42x70_reg_read(const struct device *dev, uint8_t reg, uint8_t *buf, + uint32_t size) +{ + const struct icm42x70_config *cfg = dev->config; + + return cfg->bus_io->read(&cfg->bus, reg, buf, size); +} + +static inline int inv_io_hal_read_reg(struct inv_imu_serif *serif, uint8_t reg, uint8_t *rbuffer, + uint32_t rlen) +{ + return icm42x70_reg_read(serif->context, reg, rbuffer, rlen); +} + +static inline int icm42x70_reg_write(const struct device *dev, uint8_t reg, const uint8_t *buf, + uint32_t size) +{ + const struct icm42x70_config *cfg = dev->config; + + return cfg->bus_io->write(&cfg->bus, reg, (uint8_t *)buf, size); +} + +static inline int inv_io_hal_write_reg(struct inv_imu_serif *serif, uint8_t reg, + const uint8_t *wbuffer, uint32_t wlen) +{ + return icm42x70_reg_write(serif->context, reg, wbuffer, wlen); +} + +void inv_imu_sleep_us(uint32_t us) +{ + k_sleep(K_USEC(us)); +} + +uint64_t inv_imu_get_time_us(void) +{ + /* returns the elapsed time since the system booted, in milliseconds */ + return k_uptime_get() * 1000; +} + +static uint16_t convert_dt_enum_to_freq(uint8_t val) +{ + uint16_t freq; + + switch (val) { + case 0: + freq = 0; + break; + case 1: + freq = 1600; + break; + case 2: + freq = 800; + break; + case 3: + freq = 400; + break; + case 4: + freq = 200; + break; + case 5: + freq = 100; + break; + case 6: + freq = 50; + break; + case 7: + freq = 25; + break; + case 8: + freq = 12; + break; + case 9: + freq = 6; + break; + case 10: + freq = 3; + break; + case 11: + freq = 1; + break; + default: + freq = 0; + break; + } + return freq; +} + +uint32_t convert_freq_to_bitfield(uint32_t val, uint16_t *freq) +{ + uint32_t odr_bitfield = 0; + + if (val < 3 && val >= 1) { + odr_bitfield = ACCEL_CONFIG0_ODR_1_5625_HZ; /*(= GYRO_CONFIG0_ODR_1_5625_HZ )*/ + *freq = 1; + } else if (val < 6 && val >= 3) { + odr_bitfield = ACCEL_CONFIG0_ODR_3_125_HZ; /*(= GYRO_CONFIG0_ODR_3_125_HZ )*/ + *freq = 3; + } else if (val < 12 && val >= 6) { + odr_bitfield = ACCEL_CONFIG0_ODR_6_25_HZ; /*(= GYRO_CONFIG0_ODR_6_25_HZ )*/ + *freq = 6; + } else if (val < 25 && val >= 12) { + odr_bitfield = ACCEL_CONFIG0_ODR_12_5_HZ; /*(= GYRO_CONFIG0_ODR_12_5_HZ )*/ + *freq = 12; + } else if (val < 50 && val >= 25) { + odr_bitfield = ACCEL_CONFIG0_ODR_25_HZ; /*(= GYRO_CONFIG0_ODR_25_HZ )*/ + *freq = 25; + } else if (val < 100 && val >= 50) { + odr_bitfield = ACCEL_CONFIG0_ODR_50_HZ; /*(GYRO_CONFIG0_ODR_50_HZ)*/ + *freq = 50; + } else if (val < 200 && val >= 100) { + odr_bitfield = ACCEL_CONFIG0_ODR_100_HZ; /*(= GYRO_CONFIG0_ODR_100_HZ )*/ + *freq = 100; + } else if (val < 400 && val >= 200) { + odr_bitfield = ACCEL_CONFIG0_ODR_200_HZ; /*(= GYRO_CONFIG0_ODR_200_HZ )*/ + *freq = 200; + } else if (val < 800 && val >= 400) { + odr_bitfield = ACCEL_CONFIG0_ODR_400_HZ; /*(= GYRO_CONFIG0_ODR_400_HZ )*/ + *freq = 400; + } else if (val < 1600 && val >= 800) { + odr_bitfield = ACCEL_CONFIG0_ODR_800_HZ; /*(= GYRO_CONFIG0_ODR_800_HZ )*/ + *freq = 800; + } else if (val == 1600) { + odr_bitfield = ACCEL_CONFIG0_ODR_1600_HZ; /*(= GYRO_CONFIG0_ODR_1600_HZ )*/ + *freq = 1600; + } + return odr_bitfield; +} + +static uint32_t convert_acc_fs_to_bitfield(uint32_t val, uint8_t *fs) +{ + uint32_t bitfield = 0; + + if (val < 4 && val >= 2) { + bitfield = ACCEL_CONFIG0_FS_SEL_2g; + *fs = 2; + } else if (val < 8 && val >= 4) { + bitfield = ACCEL_CONFIG0_FS_SEL_4g; + *fs = 4; + } else if (val < 16 && val >= 8) { + bitfield = ACCEL_CONFIG0_FS_SEL_8g; + *fs = 8; + } else if (val == 16) { + bitfield = ACCEL_CONFIG0_FS_SEL_16g; + *fs = 16; + } + return bitfield; +} + +uint32_t convert_ln_bw_to_bitfield(uint32_t val) +{ + uint32_t bitfield = 0xFF; + + if (val < 25 && val >= 16) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_16; /* (= GYRO_CONFIG1_GYRO_FILT_BW_16) */ + } else if (val < 34 && val >= 25) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_25; /* (= GYRO_CONFIG1_GYRO_FILT_BW_25) */ + } else if (val < 53 && val >= 34) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_34; /* (= GYRO_CONFIG1_GYRO_FILT_BW_34) */ + } else if (val < 73 && val >= 53) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_53; /* (= GYRO_CONFIG1_GYRO_FILT_BW_53) */ + } else if (val < 121 && val >= 73) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_73; /* (= GYRO_CONFIG1_GYRO_FILT_BW_73) */ + } else if (val < 180 && val >= 121) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_121; /* (= GYRO_CONFIG1_GYRO_FILT_BW_121) */ + } else if (val == 180) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_180; /* (= GYRO_CONFIG1_GYRO_FILT_BW_180) */ + } else if (val == 0) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_NO_FILTER; + /*(= GYRO_CONFIG1_GYRO_FILT_BW_NO_FILTER)*/ + } + return bitfield; +} + +static uint32_t convert_lp_avg_to_bitfield(uint32_t val) +{ + uint32_t bitfield = 0xFF; + + if (val < 4 && val >= 2) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_2; + } else if (val < 8 && val >= 4) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_4; + } else if (val < 16 && val >= 8) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_8; + } else if (val < 32 && val >= 16) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_16; + } else if (val < 64 && val >= 32) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_32; + } else if (val == 64) { + bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_64; + } + return bitfield; +} + +static uint8_t convert_bitfield_to_acc_fs(uint8_t bitfield) +{ + uint8_t acc_fs = 0; + + if (bitfield == ACCEL_CONFIG0_FS_SEL_2g) { + acc_fs = 2; + } else if (bitfield == ACCEL_CONFIG0_FS_SEL_4g) { + acc_fs = 4; + } else if (bitfield == ACCEL_CONFIG0_FS_SEL_8g) { + acc_fs = 8; + } else if (bitfield == ACCEL_CONFIG0_FS_SEL_16g) { + acc_fs = 16; + } + return acc_fs; +} + +static int icm42x70_set_accel_power_mode(struct icm42x70_data *drv_data, + const struct sensor_value *val) +{ + if ((val->val1 == ICM42X70_LOW_POWER_MODE) && + (drv_data->accel_pwr_mode != ICM42X70_LOW_POWER_MODE)) { + if (drv_data->accel_hz != 0) { + if (drv_data->accel_hz <= 400) { + inv_imu_enable_accel_low_power_mode(&drv_data->driver); + } else { + LOG_ERR("Not supported ATTR value"); + return -EINVAL; + } + } + drv_data->accel_pwr_mode = val->val1; + } else if ((val->val1 == ICM42X70_LOW_NOISE_MODE) && + (drv_data->accel_pwr_mode != ICM42X70_LOW_NOISE_MODE)) { + if (drv_data->accel_hz != 0) { + if (drv_data->accel_hz >= 12) { + inv_imu_enable_accel_low_noise_mode(&drv_data->driver); + } else { + LOG_ERR("Not supported ATTR value"); + return -EINVAL; + } + } + drv_data->accel_pwr_mode = val->val1; + } else { + LOG_ERR("Not supported ATTR value"); + return -EINVAL; + } + return 0; +} + +static int icm42x70_set_accel_odr(struct icm42x70_data *drv_data, const struct sensor_value *val) +{ + if (val->val1 <= 1600 && val->val1 >= 1) { + if (drv_data->accel_hz == 0) { + inv_imu_set_accel_frequency( + &drv_data->driver, + convert_freq_to_bitfield(val->val1, &drv_data->accel_hz)); + if (drv_data->accel_pwr_mode == ICM42X70_LOW_POWER_MODE) { + inv_imu_enable_accel_low_power_mode(&drv_data->driver); + } else if (drv_data->accel_pwr_mode == ICM42X70_LOW_NOISE_MODE) { + inv_imu_enable_accel_low_noise_mode(&drv_data->driver); + } + } else { + inv_imu_set_accel_frequency( + &drv_data->driver, + convert_freq_to_bitfield(val->val1, &drv_data->accel_hz)); + } + } else if (val->val1 == 0) { + inv_imu_disable_accel(&drv_data->driver); + drv_data->accel_hz = val->val1; + } else { + LOG_ERR("Incorrect sampling value"); + return -EINVAL; + } + return 0; +} + +static int icm42x70_set_accel_fs(struct icm42x70_data *drv_data, const struct sensor_value *val) +{ + if (val->val1 > 16 || val->val1 < 2) { + LOG_ERR("Incorrect fullscale value"); + return -EINVAL; + } + inv_imu_set_accel_fsr(&drv_data->driver, + convert_acc_fs_to_bitfield(val->val1, &drv_data->accel_fs)); + LOG_DBG("Set accel full scale to: %d G", drv_data->accel_fs); + return 0; +} + +static int icm42x70_accel_config(struct icm42x70_data *drv_data, enum sensor_attribute attr, + const struct sensor_value *val) +{ + if (attr == SENSOR_ATTR_CONFIGURATION) { + icm42x70_set_accel_power_mode(drv_data, val); + + } else if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { + icm42x70_set_accel_odr(drv_data, val); + + } else if (attr == SENSOR_ATTR_FULL_SCALE) { + icm42x70_set_accel_fs(drv_data, val); + + } else if ((enum sensor_attribute_icm42x70)attr == SENSOR_ATTR_BW_FILTER_LPF) { + if (val->val1 > 180) { + LOG_ERR("Incorrect low pass filter bandwidth value"); + return -EINVAL; + } + inv_imu_set_accel_ln_bw(&drv_data->driver, convert_ln_bw_to_bitfield(val->val1)); + + } else if ((enum sensor_attribute_icm42x70)attr == SENSOR_ATTR_AVERAGING) { + if (val->val1 > 64 || val->val1 < 2) { + LOG_ERR("Incorrect averaging filter value"); + return -EINVAL; + } + inv_imu_set_accel_lp_avg(&drv_data->driver, convert_lp_avg_to_bitfield(val->val1)); + } else { + LOG_ERR("Unsupported attribute"); + return -EINVAL; + } + return 0; +} + +static int icm42x70_sensor_init(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + const struct icm42x70_config *config = dev->config; + int err = 0; + + /* Initialize serial interface and device */ + data->serif.context = (struct device *)dev; + data->serif.read_reg = inv_io_hal_read_reg; + data->serif.write_reg = inv_io_hal_write_reg; + data->serif.max_read = ICM42X70_SERIAL_INTERFACE_MAX_READ; + data->serif.max_write = ICM42X70_SERIAL_INTERFACE_MAX_WRITE; + data->serif.serif_type = config->serif_type; + err = inv_imu_init(&data->driver, &data->serif, NULL); + if (err < 0) { + LOG_ERR("Init failed: %d", err); + return err; + } + + err = inv_imu_get_who_am_i(&data->driver, &data->chip_id); + if (err < 0) { + LOG_ERR("ID read failed: %d", err); + return err; + } + + if (data->chip_id != data->imu_whoami) { + LOG_ERR("invalid WHO_AM_I value, was 0x%x but expected 0x%x for %s", data->chip_id, + data->imu_whoami, data->imu_name); + return -ENOTSUP; + } + + LOG_DBG("\"%s\" %s OK", dev->name, data->imu_name); + return 0; +} + +static int icm42x70_turn_on_sensor(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + const struct icm42x70_config *cfg = dev->config; + int err = 0; + + err = inv_imu_set_accel_fsr(&data->driver, + (cfg->accel_fs << ACCEL_CONFIG0_ACCEL_UI_FS_SEL_POS)); + data->accel_fs = + convert_bitfield_to_acc_fs((cfg->accel_fs << ACCEL_CONFIG0_ACCEL_UI_FS_SEL_POS)); + if ((err < 0) || (data->accel_fs == 0)) { + LOG_ERR("Failed to configure accel FSR"); + return -EIO; + } + LOG_DBG("Set accel full scale to: %d G", data->accel_fs); + +#if CONFIG_USE_EMD_ICM42670 + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + err = inv_imu_set_gyro_fsr(&data->driver, + (cfg->gyro_fs << GYRO_CONFIG0_GYRO_UI_FS_SEL_POS)); + data->gyro_fs = convert_bitfield_to_gyr_fs( + (cfg->gyro_fs << GYRO_CONFIG0_GYRO_UI_FS_SEL_POS)); + if ((err < 0) || (data->gyro_fs == 0)) { + LOG_ERR("Failed to configure gyro FSR"); + return -EIO; + } + LOG_DBG("Set gyro full scale to: %d dps", data->gyro_fs); + } +#endif + + err = inv_imu_set_accel_lp_avg(&data->driver, + (cfg->accel_avg << ACCEL_CONFIG1_ACCEL_UI_AVG_POS)); + err |= inv_imu_set_accel_ln_bw(&data->driver, + (cfg->accel_filt_bw << ACCEL_CONFIG1_ACCEL_UI_FILT_BW_POS)); +#if CONFIG_USE_EMD_ICM42670 + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + err |= inv_imu_set_gyro_ln_bw( + &data->driver, (cfg->gyro_filt_bw << GYRO_CONFIG1_GYRO_UI_FILT_BW_POS)); + } +#endif + if (err < 0) { + LOG_ERR("Failed to configure filtering."); + return -EIO; + } + + if (cfg->accel_hz != 0) { + err |= inv_imu_set_accel_frequency( + &data->driver, cfg->accel_hz + ICM42X70_CONVERT_ENUM_TO_ODR_POS); + if ((cfg->accel_pwr_mode == ICM42X70_LOW_NOISE_MODE) && + (convert_dt_enum_to_freq(cfg->accel_hz) >= 12)) { + err |= inv_imu_enable_accel_low_noise_mode(&data->driver); + } else if ((cfg->accel_pwr_mode == ICM42X70_LOW_POWER_MODE) && + (convert_dt_enum_to_freq(cfg->accel_hz) <= 400)) { + err |= inv_imu_enable_accel_low_power_mode(&data->driver); + } else { + LOG_ERR("Not supported power mode value"); + } + } +#if CONFIG_USE_EMD_ICM42670 + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + if (cfg->gyro_hz != 0) { + err |= inv_imu_set_gyro_frequency( + &data->driver, cfg->gyro_hz + ICM42X70_CONVERT_ENUM_TO_ODR_POS); + err |= inv_imu_enable_gyro_low_noise_mode(&data->driver); + } + } +#endif + if (err < 0) { + LOG_ERR("Failed to configure ODR."); + return -EIO; + } + + data->accel_pwr_mode = cfg->accel_pwr_mode; + data->accel_hz = convert_dt_enum_to_freq(cfg->accel_hz); +#if CONFIG_USE_EMD_ICM42670 + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + data->gyro_hz = convert_dt_enum_to_freq(cfg->gyro_hz); + } +#endif + + /* + * Accelerometer sensor need at least 10ms startup time + * Gyroscope sensor need at least 30ms startup time + */ + k_msleep(100); + + return 0; +} + +static void icm42x70_convert_accel(struct sensor_value *val, int16_t raw_val, uint16_t fs) +{ + int64_t conv_val; + + /* 16 bit accelerometer. 2^15 bits represent the range in G */ + /* see datasheet section 3.2 for details */ + conv_val = (int64_t)raw_val * SENSOR_G * fs / INT16_MAX; + + val->val1 = conv_val / 1000000; + val->val2 = conv_val % 1000000; +} + +static void icm42x70_convert_temp(struct sensor_value *val, int16_t raw_val) +{ + int64_t conv_val; + + /* see datasheet section 15.9 for details */ + conv_val = 25 * 1000000 + ((int64_t)raw_val * 1000000 / 2); + val->val1 = conv_val / 1000000; + val->val2 = conv_val % 1000000; +} + +static int icm42x70_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + int res = 0; + struct icm42x70_data *data = dev->data; +#ifdef CONFIG_TDK_APEX + const struct icm42x70_config *cfg = dev->config; +#endif + + icm42x70_lock(dev); + + if (chan == SENSOR_CHAN_ACCEL_XYZ) { + icm42x70_convert_accel(&val[0], data->accel_x, data->accel_fs); + icm42x70_convert_accel(&val[1], data->accel_y, data->accel_fs); + icm42x70_convert_accel(&val[2], data->accel_z, data->accel_fs); + } else if (chan == SENSOR_CHAN_ACCEL_X) { + icm42x70_convert_accel(val, data->accel_x, data->accel_fs); + } else if (chan == SENSOR_CHAN_ACCEL_Y) { + icm42x70_convert_accel(val, data->accel_y, data->accel_fs); + } else if (chan == SENSOR_CHAN_ACCEL_Z) { + icm42x70_convert_accel(val, data->accel_z, data->accel_fs); +#if CONFIG_USE_EMD_ICM42670 + } else if ((chan == SENSOR_CHAN_GYRO_XYZ) && ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI))) { + icm42670_convert_gyro(&val[0], data->gyro_x, data->gyro_fs); + icm42670_convert_gyro(&val[1], data->gyro_y, data->gyro_fs); + icm42670_convert_gyro(&val[2], data->gyro_z, data->gyro_fs); + } else if ((chan == SENSOR_CHAN_GYRO_X) && ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI))) { + icm42670_convert_gyro(val, data->gyro_x, data->gyro_fs); + } else if ((chan == SENSOR_CHAN_GYRO_Y) && ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI))) { + icm42670_convert_gyro(val, data->gyro_y, data->gyro_fs); + } else if ((chan == SENSOR_CHAN_GYRO_Z) && ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI))) { + icm42670_convert_gyro(val, data->gyro_z, data->gyro_fs); +#endif + } else if (chan == SENSOR_CHAN_DIE_TEMP) { + icm42x70_convert_temp(val, data->temp); +#ifdef CONFIG_TDK_APEX + } else if ((enum sensor_channel_tdk_apex)chan == SENSOR_CHAN_APEX_MOTION) { + if (cfg->apex == TDK_APEX_PEDOMETER) { + val[0].val1 = data->pedometer_cnt; + val[1].val1 = data->pedometer_activity; + icm42x70_apex_pedometer_cadence_convert(&val[2], data->pedometer_cadence, + data->dmp_odr_hz); + } else if (cfg->apex == TDK_APEX_WOM) { + val[0].val1 = (data->apex_status & ICM42X70_APEX_STATUS_MASK_WOM_X) ? 1 : 0; + val[1].val1 = (data->apex_status & ICM42X70_APEX_STATUS_MASK_WOM_Y) ? 1 : 0; + val[2].val1 = (data->apex_status & ICM42X70_APEX_STATUS_MASK_WOM_Z) ? 1 : 0; + } else if ((cfg->apex == TDK_APEX_TILT) || (cfg->apex == TDK_APEX_SMD)) { + val[0].val1 = data->apex_status; + } +#endif + } else { + res = -ENOTSUP; + } + + icm42x70_unlock(dev); + + return res; +} + +#ifdef CONFIG_ICM42X70_TRIGGER +static int icm42x70_fetch_from_fifo(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + int status = 0; + uint8_t int_status; + uint16_t packet_size = FIFO_HEADER_SIZE + FIFO_ACCEL_DATA_SIZE + FIFO_GYRO_DATA_SIZE + + FIFO_TEMP_DATA_SIZE + FIFO_TS_FSYNC_SIZE; + uint16_t fifo_idx = 0; + + /* Ensure data ready status bit is set */ + status |= inv_imu_read_reg(&data->driver, INT_STATUS, 1, &int_status); + if (status != 0) { + return status; + } + + if ((int_status & INT_STATUS_FIFO_THS_INT_MASK) || + (int_status & INT_STATUS_FIFO_FULL_INT_MASK)) { + uint16_t packet_count; + + /* Make sure RCOSC is enabled to guarrantee FIFO read */ + status |= inv_imu_switch_on_mclk(&data->driver); + + /* Read FIFO frame count */ + status |= inv_imu_get_frame_count(&data->driver, &packet_count); + + /* Check for error */ + if (status != 0) { + status |= inv_imu_switch_off_mclk(&data->driver); + return status; + } + + /* Read FIFO data */ + status |= inv_imu_read_reg(&data->driver, FIFO_DATA, packet_size * packet_count, + (uint8_t *)&data->driver.fifo_data); + + /* Check for error */ + if (status != 0) { + status |= inv_imu_reset_fifo(&data->driver); + status |= inv_imu_switch_off_mclk(&data->driver); + return status; + } + + for (uint16_t i = 0; i < packet_count; i++) { + inv_imu_sensor_event_t event; + + status |= inv_imu_decode_fifo_frame( + &data->driver, &data->driver.fifo_data[fifo_idx], &event); + fifo_idx += packet_size; + + /* Check for error */ + if (status != 0) { + status |= inv_imu_reset_fifo(&data->driver); + status |= inv_imu_switch_off_mclk(&data->driver); + return status; + } + + if (event.sensor_mask & (1 << INV_SENSOR_ACCEL)) { + data->accel_x = event.accel[0]; + data->accel_y = event.accel[1]; + data->accel_z = event.accel[2]; + } +#if CONFIG_USE_EMD_ICM42670 + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + if (event.sensor_mask & (1 << INV_SENSOR_GYRO)) { + data->gyro_x = event.gyro[0]; + data->gyro_y = event.gyro[1]; + data->gyro_z = event.gyro[2]; + } + } +#endif + if (event.sensor_mask & (1 << INV_SENSOR_TEMPERATURE)) { + data->temp = event.temperature; + } + /* + * TODO use the sensor streaming interface with RTIO to handle multiple + * samples in FIFO + */ + + } /* end of FIFO read for loop */ + + status |= inv_imu_switch_off_mclk(&data->driver); + if (status < 0) { + return status; + } + } /*else: FIFO threshold was not reached and FIFO was not full */ + + return 0; +} +#endif + +#ifndef CONFIG_ICM42X70_TRIGGER +static int icm42x70_sample_fetch_accel(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + uint8_t buffer[ACCEL_DATA_SIZE]; + + int res = inv_imu_read_reg(&data->driver, ACCEL_DATA_X1, ACCEL_DATA_SIZE, buffer); + + if (res) { + return res; + } + + data->accel_x = (int16_t)sys_get_be16(&buffer[0]); + data->accel_y = (int16_t)sys_get_be16(&buffer[2]); + data->accel_z = (int16_t)sys_get_be16(&buffer[4]); + + return 0; +} + +static int icm42x70_sample_fetch_temp(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + uint8_t buffer[TEMP_DATA_SIZE]; + + int res = inv_imu_read_reg(&data->driver, TEMP_DATA1, TEMP_DATA_SIZE, buffer); + + if (res) { + return res; + } + + data->temp = (int16_t)sys_get_be16(&buffer[0]); + + return 0; +} + +static int icm42x70_fetch_from_registers(const struct device *dev, enum sensor_channel chan) +{ + struct icm42x70_data *data = dev->data; + int res = 0; + uint8_t int_status; + + LOG_DBG("Fetch from reg"); + + icm42x70_lock(dev); + + /* Ensure data ready status bit is set */ + int err = inv_imu_read_reg(&data->driver, INT_STATUS_DRDY, 1, &int_status); + + if (int_status & INT_STATUS_DRDY_DATA_RDY_INT_MASK) { + switch (chan) { + case SENSOR_CHAN_ALL: + err |= icm42x70_sample_fetch_accel(dev); +#if CONFIG_USE_EMD_ICM42670 + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + err |= icm42670_sample_fetch_gyro(dev); + } +#endif + err |= icm42x70_sample_fetch_temp(dev); + break; + case SENSOR_CHAN_ACCEL_XYZ: + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + err |= icm42x70_sample_fetch_accel(dev); + break; +#if CONFIG_USE_EMD_ICM42670 + case SENSOR_CHAN_GYRO_XYZ: + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + err |= icm42670_sample_fetch_gyro(dev); + } else { + res = -ENOTSUP; + } + break; +#endif + case SENSOR_CHAN_DIE_TEMP: + err |= icm42x70_sample_fetch_temp(dev); + break; + default: + res = -ENOTSUP; + break; + } + } + + icm42x70_unlock(dev); + + if (err < 0) { + res = -EIO; + } + return res; +} +#endif + +static int icm42x70_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ +#if CONFIG_USE_EMD_ICM42670 + struct icm42x70_data *data = dev->data; +#endif + int status = -ENOTSUP; + + icm42x70_lock(dev); + +#ifdef CONFIG_TDK_APEX + if ((enum sensor_channel_tdk_apex)chan == SENSOR_CHAN_APEX_MOTION) { + status = icm42x70_apex_fetch_from_dmp(dev); + } +#endif + + if ((chan == SENSOR_CHAN_ALL) || SENSOR_CHANNEL_IS_ACCEL(chan) || +#if CONFIG_USE_EMD_ICM42670 + (SENSOR_CHANNEL_IS_GYRO(chan) && ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI))) || +#endif + (chan == SENSOR_CHAN_DIE_TEMP)) { +#ifdef CONFIG_ICM42X70_TRIGGER + status = icm42x70_fetch_from_fifo(dev); +#else + status = icm42x70_fetch_from_registers(dev, chan); +#endif + } + + icm42x70_unlock(dev); + return status; +} + +static int icm42x70_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + struct icm42x70_data *drv_data = dev->data; + + __ASSERT_NO_MSG(val != NULL); + + icm42x70_lock(dev); + + if ((enum sensor_channel_tdk_apex)chan == SENSOR_CHAN_APEX_MOTION) { + if (attr == SENSOR_ATTR_CONFIGURATION) { +#ifdef CONFIG_TDK_APEX + if (val->val1 == TDK_APEX_PEDOMETER) { + icm42x70_apex_enable(&drv_data->driver); + icm42x70_apex_enable_pedometer(dev, &drv_data->driver); + } else if (val->val1 == TDK_APEX_TILT) { + icm42x70_apex_enable(&drv_data->driver); + icm42x70_apex_enable_tilt(&drv_data->driver); + } else if (val->val1 == TDK_APEX_SMD) { + icm42x70_apex_enable(&drv_data->driver); + icm42x70_apex_enable_smd(&drv_data->driver); + } else if (val->val1 == TDK_APEX_WOM) { + icm42x70_apex_enable_wom(&drv_data->driver); + } else { + LOG_ERR("Not supported ATTR value"); + } +#endif + } else { + LOG_ERR("Not supported ATTR"); + return -EINVAL; + } + } else if (SENSOR_CHANNEL_IS_ACCEL(chan)) { + icm42x70_accel_config(drv_data, attr, val); +#if CONFIG_USE_EMD_ICM42670 + } else if ((SENSOR_CHANNEL_IS_GYRO(chan)) && + ((drv_data->imu_whoami == INV_ICM42670P_WHOAMI) || + (drv_data->imu_whoami == INV_ICM42670S_WHOAMI))) { + icm42670_gyro_config(drv_data, attr, val); +#endif + } else { + LOG_ERR("Unsupported channel"); + (void)drv_data; + return -EINVAL; + } + + icm42x70_unlock(dev); + + return 0; +} + +static int icm42x70_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + const struct icm42x70_data *data = dev->data; + const struct icm42x70_config *cfg = dev->config; + int res = 0; + + __ASSERT_NO_MSG(val != NULL); + + icm42x70_lock(dev); + + switch (chan) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { + val->val1 = data->accel_hz; + } else if (attr == SENSOR_ATTR_FULL_SCALE) { + val->val1 = data->accel_fs; + } else { + LOG_ERR("Unsupported attribute"); + res = -EINVAL; + } + break; +#if CONFIG_USE_EMD_ICM42670 + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { + val->val1 = data->gyro_hz; + } else if (attr == SENSOR_ATTR_FULL_SCALE) { + val->val1 = data->gyro_fs; + } else { + LOG_ERR("Unsupported attribute"); + res = -EINVAL; + } + } else { + res = -EINVAL; + } + break; +#endif + case SENSOR_CHAN_APEX_MOTION: + if (attr == SENSOR_ATTR_CONFIGURATION) { + val->val1 = cfg->apex; + } + break; + + default: + LOG_ERR("Unsupported channel"); + res = -EINVAL; + break; + } + + icm42x70_unlock(dev); + + return res; +} + +static inline int icm42x70_bus_check(const struct device *dev) +{ + const struct icm42x70_config *cfg = dev->config; + + return cfg->bus_io->check(&cfg->bus); +} + +static int icm42x70_init(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + int res = 0; + + if (icm42x70_bus_check(dev) < 0) { + LOG_ERR("bus check failed"); + return -ENODEV; + } + + data->accel_x = 0; + data->accel_y = 0; + data->accel_z = 0; +#if CONFIG_USE_EMD_ICM42670 + if ((data->imu_whoami == INV_ICM42670P_WHOAMI) || + (data->imu_whoami == INV_ICM42670S_WHOAMI)) { + data->gyro_x = 0; + data->gyro_y = 0; + data->gyro_z = 0; + } +#endif + data->temp = 0; + + if (icm42x70_sensor_init(dev)) { + LOG_ERR("could not initialize sensor"); + return -EIO; + } + +#ifdef CONFIG_ICM42X70_TRIGGER + res |= icm42x70_trigger_enable_interrupt(dev); + res |= icm42x70_trigger_init(dev); + if (res < 0) { + LOG_ERR("Failed to initialize interrupt."); + return res; + } +#endif + + res |= icm42x70_turn_on_sensor(dev); + + return res; +} + +#ifndef CONFIG_ICM42X70_TRIGGER + +void icm42x70_lock(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +void icm42x70_unlock(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +#endif + +static DEVICE_API(sensor, icm42x70_driver_api) = { +#ifdef CONFIG_ICM42X70_TRIGGER + .trigger_set = icm42x70_trigger_set, +#endif + .sample_fetch = icm42x70_sample_fetch, + .channel_get = icm42x70_channel_get, + .attr_set = icm42x70_attr_set, + .attr_get = icm42x70_attr_get, +}; + +/* device defaults to spi mode 0/3 support */ +#define ICM42X70_SPI_CFG (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPOL | SPI_MODE_CPHA) + +/* Initializes a common struct icm42x70_config */ +#define ICM42X70_CONFIG_COMMON(inst) \ + IF_ENABLED(CONFIG_ICM42X70_TRIGGER, \ + (.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}),)) \ + .accel_fs = DT_INST_ENUM_IDX(inst, accel_fs), \ + .accel_hz = DT_INST_ENUM_IDX(inst, accel_hz), \ + .accel_avg = DT_INST_ENUM_IDX(inst, accel_avg), \ + .accel_filt_bw = DT_INST_ENUM_IDX(inst, accel_filt_bw_hz), \ + .accel_pwr_mode = DT_INST_ENUM_IDX(inst, power_mode), \ + .apex = DT_INST_ENUM_IDX(inst, apex), \ + .accel_pwr_mode = DT_INST_ENUM_IDX(inst, power_mode), \ + .apex = DT_INST_ENUM_IDX(inst, apex), \ + IF_ENABLED(CONFIG_USE_EMD_ICM42670, \ + (.gyro_fs = DT_INST_ENUM_IDX(inst, gyro_fs),)) \ + IF_ENABLED(CONFIG_USE_EMD_ICM42670, \ + (.gyro_hz = DT_INST_ENUM_IDX(inst, gyro_hz),)) \ + IF_ENABLED(CONFIG_USE_EMD_ICM42670, \ + (.gyro_filt_bw = DT_INST_ENUM_IDX(inst, gyro_filt_bw_hz),)) + +/* Initializes the bus members for an instance on a SPI bus. */ +#define ICM42X70_CONFIG_SPI(inst) \ + {.bus.spi = SPI_DT_SPEC_INST_GET(inst, ICM42X70_SPI_CFG, 0), \ + .bus_io = &icm42x70_bus_io_spi, \ + .serif_type = UI_SPI4, \ + ICM42X70_CONFIG_COMMON(inst)} + +/* Initializes the bus members for an instance on an I2C bus. */ +#define ICM42X70_CONFIG_I2C(inst) \ + {.bus.i2c = I2C_DT_SPEC_INST_GET(inst), \ + .bus_io = &icm42x70_bus_io_i2c, \ + .serif_type = UI_I2C, \ + ICM42X70_CONFIG_COMMON(inst)} + +/* + * Main instantiation macro, which selects the correct bus-specific + * instantiation macros for the instance. + */ +#define ICM42X70_DEFINE(inst, name, whoami) \ + static struct icm42x70_data icm42x70_data_##inst = { \ + .imu_name = name, \ + .imu_whoami = whoami, \ + }; \ + static const struct icm42x70_config icm42x70_config_##inst = \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (ICM42X70_CONFIG_SPI(inst)), \ + (ICM42X70_CONFIG_I2C(inst))); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, icm42x70_init, NULL, &icm42x70_data_##inst, \ + &icm42x70_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &icm42x70_driver_api); + +#define DT_DRV_COMPAT invensense_icm42670p +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +DT_INST_FOREACH_STATUS_OKAY_VARGS(ICM42X70_DEFINE, INV_ICM42670P_STRING_ID, INV_ICM42670P_WHOAMI); +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT invensense_icm42670s +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +DT_INST_FOREACH_STATUS_OKAY_VARGS(ICM42X70_DEFINE, INV_ICM42670S_STRING_ID, INV_ICM42670S_WHOAMI); +#endif +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT invensense_icm42370p +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) +DT_INST_FOREACH_STATUS_OKAY_VARGS(ICM42X70_DEFINE, INV_ICM42370P_STRING_ID, INV_ICM42370P_WHOAMI); +#endif diff --git a/drivers/sensor/tdk/icm42x70/icm42x70.h b/drivers/sensor/tdk/icm42x70/icm42x70.h new file mode 100644 index 0000000000000..10461268b2be3 --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42x70.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024 TDK Invensense + * Copyright (c) 2022 Esco Medical ApS + * Copyright (c) 2020 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42X70_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM42X70_H_ + +#include +#include +#include +#include +#include + +#include "imu/inv_imu_driver.h" +#ifdef CONFIG_TDK_APEX +#include "imu/inv_imu_apex.h" +#endif + +union icm42x70_bus { +#if CONFIG_SPI + struct spi_dt_spec spi; +#endif +#if CONFIG_I2C + struct i2c_dt_spec i2c; +#endif +}; + +typedef int (*icm42x70_bus_check_fn)(const union icm42x70_bus *bus); +typedef int (*icm42x70_reg_read_fn)(const union icm42x70_bus *bus, uint8_t reg, uint8_t *buf, + uint32_t size); +typedef int (*icm42x70_reg_write_fn)(const union icm42x70_bus *bus, uint8_t reg, uint8_t *buf, + uint32_t size); + +struct icm42x70_bus_io { + icm42x70_bus_check_fn check; + icm42x70_reg_read_fn read; + icm42x70_reg_write_fn write; +}; + +#if CONFIG_SPI +extern const struct icm42x70_bus_io icm42x70_bus_io_spi; +#endif + +#if CONFIG_I2C +extern const struct icm42x70_bus_io icm42x70_bus_io_i2c; +#endif + +struct icm42x70_data { + struct inv_imu_serif serif; + struct inv_imu_device driver; + uint8_t imu_whoami; + char *imu_name; + uint8_t chip_id; + int32_t accel_x; + int32_t accel_y; + int32_t accel_z; + uint16_t accel_hz; + uint8_t accel_fs; + uint8_t accel_pwr_mode; +#if CONFIG_USE_EMD_ICM42670 + int32_t gyro_x; + int32_t gyro_y; + int32_t gyro_z; + uint16_t gyro_hz; + uint16_t gyro_fs; +#endif + int32_t temp; +#ifdef CONFIG_TDK_APEX + uint8_t dmp_odr_hz; + uint64_t pedometer_cnt; + uint8_t pedometer_activity; + uint8_t pedometer_cadence; + uint8_t apex_status; +#endif + +#ifdef CONFIG_ICM42X70_TRIGGER + const struct device *dev; + struct gpio_callback gpio_cb; + sensor_trigger_handler_t data_ready_handler; + const struct sensor_trigger *data_ready_trigger; + struct k_mutex mutex; +#endif +#ifdef CONFIG_ICM42X70_TRIGGER_OWN_THREAD + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ICM42X70_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem gpio_sem; +#endif +#ifdef CONFIG_ICM42X70_TRIGGER_GLOBAL_THREAD + struct k_work work; +#endif +}; + +struct icm42x70_config { + union icm42x70_bus bus; + const struct icm42x70_bus_io *bus_io; + uint32_t serif_type; + struct gpio_dt_spec gpio_int; + uint8_t accel_fs; + uint16_t accel_hz; + uint16_t accel_avg; + uint16_t accel_filt_bw; +#if CONFIG_USE_EMD_ICM42670 + uint16_t gyro_fs; + uint16_t gyro_hz; + uint16_t gyro_filt_bw; +#endif + uint8_t accel_pwr_mode; + uint8_t apex; +}; + +uint32_t convert_freq_to_bitfield(uint32_t val, uint16_t *freq); +uint32_t convert_ln_bw_to_bitfield(uint32_t val); + +#ifdef CONFIG_TDK_APEX + +#define ICM42X70_APEX_STATUS_MASK_TILT BIT(0) +#define ICM42X70_APEX_STATUS_MASK_SMD BIT(1) +#define ICM42X70_APEX_STATUS_MASK_WOM_X BIT(2) +#define ICM42X70_APEX_STATUS_MASK_WOM_Y BIT(3) +#define ICM42X70_APEX_STATUS_MASK_WOM_Z BIT(4) + +int icm42x70_apex_enable(inv_imu_device_t *s); +int icm42x70_apex_fetch_from_dmp(const struct device *dev); +void icm42x70_apex_pedometer_cadence_convert(struct sensor_value *val, uint8_t raw_val, + uint8_t dmp_odr_hz); +int icm42x70_apex_enable_pedometer(const struct device *dev, inv_imu_device_t *s); +int icm42x70_apex_enable_tilt(inv_imu_device_t *s); +int icm42x70_apex_enable_smd(inv_imu_device_t *s); +int icm42x70_apex_enable_wom(inv_imu_device_t *s); +#endif + +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42X70_H_ */ diff --git a/drivers/sensor/tdk/icm42x70/icm42x70_apex.c b/drivers/sensor/tdk/icm42x70/icm42x70_apex.c new file mode 100644 index 0000000000000..0761ff9db6923 --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42x70_apex.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2024 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "icm42x70.h" +#include "imu/inv_imu_apex.h" + +int icm42x70_apex_enable(inv_imu_device_t *s) +{ + int err = 0; + inv_imu_apex_parameters_t apex_inputs; + inv_imu_interrupt_parameter_t config_int = {(inv_imu_interrupt_value)0}; + + /* Disabling FIFO to avoid extra power consumption due to ALP config */ + err |= inv_imu_configure_fifo(s, INV_IMU_FIFO_DISABLED); + + /* Enable Pedometer, Tilt and SMD interrupts */ + config_int.INV_STEP_DET = INV_IMU_ENABLE; + config_int.INV_STEP_CNT_OVFL = INV_IMU_ENABLE; + config_int.INV_TILT_DET = INV_IMU_ENABLE; + config_int.INV_SMD = INV_IMU_ENABLE; + err |= inv_imu_set_config_int1(s, &config_int); + + /* Enable accelerometer to feed the APEX Pedometer algorithm */ + err |= inv_imu_set_accel_frequency(s, ACCEL_CONFIG0_ODR_50_HZ); + + /* Set 2x averaging, in order to minimize power consumption (16x by default) */ + err |= inv_imu_set_accel_lp_avg(s, ACCEL_CONFIG1_ACCEL_FILT_AVG_2); + err |= inv_imu_enable_accel_low_power_mode(s); + + /* Get the default parameters for the APEX features */ + err |= inv_imu_apex_init_parameters_struct(s, &apex_inputs); + + /* + * Configure the power mode Normal mode. + * Avalaible mode : Low Power mode (WoM+Pedometer), + * configure the WoM to wake-up the DMP once it goes in power save mode + */ + apex_inputs.power_save = APEX_CONFIG0_DMP_POWER_SAVE_DIS; + err |= inv_imu_apex_configure_parameters(s, &apex_inputs); + + /* Configure sampling frequency to 50Hz */ + err |= inv_imu_apex_set_frequency(s, APEX_CONFIG1_DMP_ODR_50Hz); + + return err; +} + +int icm42x70_apex_fetch_from_dmp(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + int rc = 0; + uint8_t int_status2, int_status3; + + /* Read APEX interrupt status */ + rc |= inv_imu_read_reg(&data->driver, INT_STATUS2, 1, &int_status2); + rc |= inv_imu_read_reg(&data->driver, INT_STATUS3, 1, &int_status3); + + /* Test Pedometer interrupt */ + if (int_status3 & (INT_STATUS3_STEP_DET_INT_MASK)) { + inv_imu_apex_step_activity_t apex_pedometer; + uint8_t step_cnt_ovflw = 0; + + if (int_status3 & INT_STATUS3_STEP_CNT_OVF_INT_MASK) { + step_cnt_ovflw = 1; + } + + rc |= inv_imu_apex_get_data_activity(&data->driver, &apex_pedometer); + + if (data->pedometer_cnt != + apex_pedometer.step_cnt + step_cnt_ovflw * (uint64_t)UINT16_MAX) { + data->pedometer_cnt = + apex_pedometer.step_cnt + step_cnt_ovflw * (uint64_t)UINT16_MAX; + data->pedometer_activity = apex_pedometer.activity_class; + data->pedometer_cadence = apex_pedometer.step_cadence; + } else { + /* Pedometer data processing */ + rc = 1; + } + } + /* Test Tilt interrupt */ + if (int_status3 & (INT_STATUS3_TILT_DET_INT_MASK)) { + data->apex_status = ICM42X70_APEX_STATUS_MASK_TILT; + } + /* Test SMD interrupt */ + if ((int_status2 & (INT_STATUS2_SMD_INT_MASK)) || (rc != 0)) { + data->apex_status = ICM42X70_APEX_STATUS_MASK_SMD; + } + /* Test WOM interrupts */ + if (int_status2 & (INT_STATUS2_WOM_X_INT_MASK | INT_STATUS2_WOM_Y_INT_MASK | + INT_STATUS2_WOM_Z_INT_MASK)) { + data->apex_status = 0; + if (int_status2 & INT_STATUS2_WOM_X_INT_MASK) { + data->apex_status |= ICM42X70_APEX_STATUS_MASK_WOM_X; + } + if (int_status2 & INT_STATUS2_WOM_Y_INT_MASK) { + data->apex_status |= ICM42X70_APEX_STATUS_MASK_WOM_Y; + } + if (int_status2 & INT_STATUS2_WOM_Z_INT_MASK) { + data->apex_status |= ICM42X70_APEX_STATUS_MASK_WOM_Z; + } + } + return rc; +} + +void icm42x70_apex_pedometer_cadence_convert(struct sensor_value *val, uint8_t raw_val, + uint8_t dmp_odr_hz) +{ + int64_t conv_val; + + /* Converting u6.2 */ + conv_val = (int64_t)(dmp_odr_hz << 2) * 1000000 / (raw_val + (raw_val & 0x03)); + val->val1 = conv_val / 1000000; + val->val2 = conv_val % 1000000; +} + +int icm42x70_apex_enable_pedometer(const struct device *dev, inv_imu_device_t *s) +{ + struct icm42x70_data *data = dev->data; + + data->dmp_odr_hz = 50; + /* Enable the pedometer */ + return inv_imu_apex_enable_pedometer(s); +} + +int icm42x70_apex_enable_tilt(inv_imu_device_t *s) +{ + /* Enable Tilt */ + return inv_imu_apex_enable_tilt(s); +} + +int icm42x70_apex_enable_smd(inv_imu_device_t *s) +{ + int rc = 0; + + /* Enable SMD (and Pedometer as SMD uses it) */ + rc |= inv_imu_apex_enable_pedometer(s); + rc |= inv_imu_apex_enable_smd(s); + + return rc; +} + +int icm42x70_apex_enable_wom(inv_imu_device_t *s) +{ + int rc = 0; + inv_imu_interrupt_parameter_t config_int = {(inv_imu_interrupt_value)0}; + + /* + * Optimize power consumption: + * - Disable FIFO usage. + * - Disable data ready interrupt and enable WOM interrupts. + * - Set 2X averaging. + * - Use Low-Power mode at low frequency. + */ + rc |= inv_imu_configure_fifo(s, INV_IMU_FIFO_DISABLED); + + config_int.INV_WOM_X = INV_IMU_ENABLE; + config_int.INV_WOM_Y = INV_IMU_ENABLE; + config_int.INV_WOM_Z = INV_IMU_ENABLE; + rc |= inv_imu_set_config_int1(s, &config_int); + + rc |= inv_imu_set_accel_lp_avg(s, ACCEL_CONFIG1_ACCEL_FILT_AVG_2); + rc |= inv_imu_set_accel_frequency(s, ACCEL_CONFIG0_ODR_12_5_HZ); + rc |= inv_imu_enable_accel_low_power_mode(s); + + /* + * Configure WOM thresholds for each axis to 195 mg (Resolution 1g/256) + * WOM threshold = 50 * 1000 / 256 = 195 mg + * and enable WOM + */ + rc |= inv_imu_configure_wom(s, 50, 50, 50, WOM_CONFIG_WOM_INT_MODE_ORED, + WOM_CONFIG_WOM_INT_DUR_1_SMPL); + rc |= inv_imu_enable_wom(s); + + return rc; +} diff --git a/drivers/sensor/tdk/icm42x70/icm42x70_i2c.c b/drivers/sensor/tdk/icm42x70/icm42x70_i2c.c new file mode 100644 index 0000000000000..7f81c9bc8a7e4 --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42x70_i2c.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 TDK Invensense + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Bus-specific functionality for ICM42X70 accessed via I2C. + */ + +#include "icm42x70.h" + +#if CONFIG_I2C +static int icm42x70_bus_check_i2c(const union icm42x70_bus *bus) +{ + return device_is_ready(bus->i2c.bus) ? 0 : -ENODEV; +} + +static int icm42x70_reg_read_i2c(const union icm42x70_bus *bus, uint8_t reg, uint8_t *buf, + uint32_t size) +{ + return i2c_burst_read_dt(&bus->i2c, reg, buf, size); +} + +static int icm42x70_reg_write_i2c(const union icm42x70_bus *bus, uint8_t reg, uint8_t *buf, + uint32_t size) +{ + return i2c_burst_write_dt(&bus->i2c, reg, buf, size); +} + +const struct icm42x70_bus_io icm42x70_bus_io_i2c = { + .check = icm42x70_bus_check_i2c, + .read = icm42x70_reg_read_i2c, + .write = icm42x70_reg_write_i2c, +}; +#endif /* CONFIG_I2C */ diff --git a/drivers/sensor/tdk/icm42x70/icm42x70_spi.c b/drivers/sensor/tdk/icm42x70/icm42x70_spi.c new file mode 100644 index 0000000000000..1e55efcd5073a --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42x70_spi.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 TDK Invensense + * Copyright (c) 2022 Esco Medical ApS + * Copyright (c) 2020 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Bus-specific functionality for ICM42X70 accessed via SPI. + */ + +#include "icm42x70.h" + +#if CONFIG_SPI + +#include +LOG_MODULE_DECLARE(ICM42X70, CONFIG_SENSOR_LOG_LEVEL); + +static int icm42x70_bus_check_spi(const union icm42x70_bus *bus) +{ + return spi_is_ready_dt(&bus->spi) ? 0 : -ENODEV; +} + +static int icm42x70_reg_read_spi(const union icm42x70_bus *bus, uint8_t start, uint8_t *buf, + uint32_t size) + +{ + uint8_t cmd[] = {(start | 0x80)}; + const struct spi_buf tx_buf = {.buf = cmd, .len = sizeof(cmd)}; + const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; + struct spi_buf rx_buf[2]; + const struct spi_buf_set rx = {.buffers = rx_buf, .count = ARRAY_SIZE(rx_buf)}; + int ret; + + rx_buf[0].buf = NULL; + rx_buf[0].len = 1; + + rx_buf[1].len = size; + rx_buf[1].buf = buf; + + ret = spi_transceive_dt(&bus->spi, &tx, &rx); + if (ret) { + LOG_ERR("spi_transceive FAIL %d\n", ret); + return ret; + } + return 0; +} + +static int icm42x70_reg_write_spi(const union icm42x70_bus *bus, uint8_t reg, uint8_t *buf, + uint32_t size) +{ + uint8_t cmd[] = {reg & 0x7F}; + const struct spi_buf tx_buf[2] = {{.buf = cmd, .len = sizeof(cmd)}, + {.buf = buf, .len = size}}; + const struct spi_buf_set tx = {.buffers = tx_buf, .count = 2}; + int ret = spi_write_dt(&bus->spi, &tx); + + if (ret) { + LOG_ERR("spi_write FAIL %d\n", ret); + return ret; + } + return 0; +} + +const struct icm42x70_bus_io icm42x70_bus_io_spi = { + .check = icm42x70_bus_check_spi, + .read = icm42x70_reg_read_spi, + .write = icm42x70_reg_write_spi, +}; + +#endif /* CONFIG_SPI */ diff --git a/drivers/sensor/tdk/icm42x70/icm42x70_trigger.c b/drivers/sensor/tdk/icm42x70/icm42x70_trigger.c new file mode 100644 index 0000000000000..e6dfd0e33e1cb --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42x70_trigger.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2024 TDK Invensense + * Copyright (c) 2022 Esco Medical ApS + * Copyright (c) 2016 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "icm42x70.h" +#include "icm42x70_trigger.h" + +#include +LOG_MODULE_DECLARE(ICM42X70, CONFIG_SENSOR_LOG_LEVEL); + +static void icm42x70_gpio_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + ARG_UNUSED(dev); + ARG_UNUSED(pins); + + struct icm42x70_data *data = CONTAINER_OF(cb, struct icm42x70_data, gpio_cb); + +#if defined(CONFIG_ICM42X70_TRIGGER_OWN_THREAD) + k_sem_give(&data->gpio_sem); +#elif defined(CONFIG_ICM42X70_TRIGGER_GLOBAL_THREAD) + k_work_submit(&data->work); +#endif +} + +static void icm42x70_thread_cb(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + const struct icm42x70_config *cfg = dev->config; + + icm42x70_lock(dev); + gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_DISABLE); + + if (data->data_ready_handler) { + data->data_ready_handler(dev, data->data_ready_trigger); + } + + gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + icm42x70_unlock(dev); +} + +#if defined(CONFIG_ICM42X70_TRIGGER_OWN_THREAD) + +static void icm42x70_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct icm42x70_data *data = p1; + + while (1) { + k_sem_take(&data->gpio_sem, K_FOREVER); + icm42x70_thread_cb(data->dev); + } +} +#elif defined(CONFIG_ICM42X70_TRIGGER_GLOBAL_THREAD) + +static void icm42x70_work_handler(struct k_work *work) +{ + struct icm42x70_data *data = CONTAINER_OF(work, struct icm42x70_data, work); + + icm42x70_thread_cb(data->dev); +} + +#endif + +int icm42x70_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + struct icm42x70_data *data = dev->data; + const struct icm42x70_config *cfg = dev->config; + + if (!handler) { + return -EINVAL; + } + + icm42x70_lock(dev); + gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_DISABLE); + + if (trig->type == SENSOR_TRIG_DATA_READY) { + data->data_ready_handler = handler; + data->data_ready_trigger = trig; +#ifdef CONFIG_TDK_APEX + } else if (trig->type == SENSOR_TRIG_MOTION) { + data->data_ready_handler = handler; + data->data_ready_trigger = trig; +#endif + } else { + return -ENOTSUP; + } + + icm42x70_unlock(dev); + gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + + return 0; +} + +int icm42x70_trigger_init(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + const struct icm42x70_config *cfg = dev->config; + int res = 0; + + if (!cfg->gpio_int.port) { + LOG_ERR("trigger enabled but no interrupt gpio supplied"); + return -ENODEV; + } + + if (!gpio_is_ready_dt(&cfg->gpio_int)) { + LOG_ERR("gpio_int gpio not ready"); + return -ENODEV; + } + + data->dev = dev; + gpio_pin_configure_dt(&cfg->gpio_int, GPIO_INPUT); + gpio_init_callback(&data->gpio_cb, icm42x70_gpio_callback, BIT(cfg->gpio_int.pin)); + res = gpio_add_callback(cfg->gpio_int.port, &data->gpio_cb); + + if (res < 0) { + LOG_ERR("Failed to set gpio callback"); + return res; + } + + k_mutex_init(&data->mutex); + +#if defined(CONFIG_ICM42X70_TRIGGER_OWN_THREAD) + k_sem_init(&data->gpio_sem, 0, K_SEM_MAX_LIMIT); + k_thread_create(&data->thread, data->thread_stack, CONFIG_ICM42X70_THREAD_STACK_SIZE, + icm42x70_thread, data, NULL, NULL, + K_PRIO_COOP(CONFIG_ICM42X70_THREAD_PRIORITY), 0, K_NO_WAIT); +#elif defined(CONFIG_ICM42X70_TRIGGER_GLOBAL_THREAD) + data->work.handler = icm42x70_work_handler; +#endif + + return gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_INACTIVE); +} + +int icm42x70_trigger_enable_interrupt(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + int err = 0; + inv_imu_int1_pin_config_t int1_pin_config; + inv_imu_interrupt_parameter_t config_int = {(inv_imu_interrupt_value)0}; + + /* Set interrupt config */ + int1_pin_config.int_polarity = INT_CONFIG_INT1_POLARITY_HIGH; + int1_pin_config.int_mode = INT_CONFIG_INT1_MODE_PULSED; + int1_pin_config.int_drive = INT_CONFIG_INT1_DRIVE_CIRCUIT_PP; + err |= inv_imu_set_pin_config_int1(&data->driver, &int1_pin_config); + + config_int.INV_FIFO_THS = INV_IMU_ENABLE; + err |= inv_imu_set_config_int1(&data->driver, &config_int); + + return err; +} + +void icm42x70_lock(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + + k_mutex_lock(&data->mutex, K_FOREVER); +} + +void icm42x70_unlock(const struct device *dev) +{ + struct icm42x70_data *data = dev->data; + + k_mutex_unlock(&data->mutex); +} diff --git a/drivers/sensor/tdk/icm42x70/icm42x70_trigger.h b/drivers/sensor/tdk/icm42x70/icm42x70_trigger.h new file mode 100644 index 0000000000000..bd89107ac4fb9 --- /dev/null +++ b/drivers/sensor/tdk/icm42x70/icm42x70_trigger.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Esco Medical ApS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42X70_TRIGGER_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM42X70_TRIGGER_H_ + +#include + +/** implement the trigger_set sensor api function */ +int icm42x70_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + +/** + * @brief initialize the icm42x70 trigger system + * + * @param dev icm42x70 device pointer + * @return int 0 on success, negative error code otherwise + */ +int icm42x70_trigger_init(const struct device *dev); + +/** + * @brief enable the trigger gpio interrupt + * + * @param dev icm42x70 device pointer + * @return int 0 on success, negative error code otherwise + */ +int icm42x70_trigger_enable_interrupt(const struct device *dev); + +/** + * @brief lock access to the icm42x70 device driver + * + * @param dev icm42x70 device pointer + */ +void icm42x70_lock(const struct device *dev); + +/** + * @brief lock access to the icm42x70 device driver + * + * @param dev icm42x70 device pointer + */ +void icm42x70_unlock(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42X70_TRIGGER_H_ */ diff --git a/drivers/sensor/tdk/icp10125/CMakeLists.txt b/drivers/sensor/tdk/icp10125/CMakeLists.txt deleted file mode 100644 index 12279906928d5..0000000000000 --- a/drivers/sensor/tdk/icp10125/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2022 Mizuki Agawa -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library() - -zephyr_library_sources(icp10125.c) diff --git a/drivers/sensor/tdk/icp10125/Kconfig b/drivers/sensor/tdk/icp10125/Kconfig deleted file mode 100644 index 96240de1be7b6..0000000000000 --- a/drivers/sensor/tdk/icp10125/Kconfig +++ /dev/null @@ -1,23 +0,0 @@ -# ICP10125 barometric pressure/temperature sensor configuration options - -# Copyright (c) 2022 Mizuki Agawa -# SPDX-License-Identifier: Apache-2.0 - -menuconfig ICP10125 - bool "ICP10125 Barometric Pressure & Temperature Sensor" - default y - depends on DT_HAS_INVENSENSE_ICP10125_ENABLED - select I2C - help - Enable driver for ICP10125 barometric pressure/temperature sensor. - -if ICP10125 - -config ICP10125_CHECK_CRC - bool "Check the CRC of measument data" - imply CRC - default y - help - Verify the CRC checksum that appended to the measurement data. - -endif # ICP10125 diff --git a/drivers/sensor/tdk/icp10125/icp10125.c b/drivers/sensor/tdk/icp10125/icp10125.c deleted file mode 100644 index 7393b5bbe64f3..0000000000000 --- a/drivers/sensor/tdk/icp10125/icp10125.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2022 Mizuki Agawa - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT invensense_icp10125 - -#include -#include -#include -#include - -#ifdef CONFIG_ICP10125_CHECK_CRC -#include -#endif /* CONFIG_ICP10125_CHECK_CRC */ - -LOG_MODULE_REGISTER(ICP10125, CONFIG_SENSOR_LOG_LEVEL); - -#define CRC_POLY 0x31 -#define SENSOR_DATA_SIZE 2 - -#define AMBIENT_TEMP_DATA_NUM 1 -#define PRESS_DATA_NUM 2 -#define PRESS_AND_AMBIENT_TEMP_DATA_NUM (AMBIENT_TEMP_DATA_NUM + PRESS_DATA_NUM) - -enum { - LOW_POWER, - NORMAL, - LOW_NOISE, - ULTRA_LOW_NOISE, - NUM_MEASURE_MODE -}; - -struct icp10125_data { - uint16_t raw_ambient_temp; - uint32_t raw_press; - float sensor_constants[4]; -}; - -struct icp10125_dev_config { - struct i2c_dt_spec i2c; - uint8_t ambient_temp_mode; - uint8_t press_mode; -}; - -struct icp10125_cmd { - uint8_t data[2]; -}; - -struct icp10125_sensor_data { - uint8_t data[2]; - uint8_t crc; -}; - -struct icp10125_otp_read_setup { - struct icp10125_cmd cmd; - uint8_t data[3]; -} __packed __aligned(1); - -/* ambient temperature measurement command for each mode. - * (Section 5.2 MEASUREMENT COMMANDS in the Datasheet) - */ -static const struct icp10125_cmd ambient_temp_measurement_cmds[] = { - {{0x60, 0x9C}}, {{0x68, 0x25}}, {{0x70, 0xDF}}, {{0x78, 0x66}} -}; - -/* pressure measurement command for each mode. - * (Section 5.2 MEASUREMENT COMMANDS in the Datasheet) - */ -static const struct icp10125_cmd press_measurement_cmds[] = { - {{0x40, 0x1A}}, {{0x48, 0xA3}}, {{0x50, 0x59}}, {{0x59, 0xE0}} -}; - -/* Request preparation for OTP data read. It should issue before data read request. - * (Section 5.2 MEASUREMENT COMMANDS in the Datasheet) - */ -static const struct icp10125_otp_read_setup otp_read_setup = { - .cmd = {{0xC5, 0x95}}, - .data = {0x00, 0x66, 0x9C} -}; - -/* OTP data read request. - * After issue this command 2byte x 4 sensor constant value can readable. - */ -static const struct icp10125_cmd otp_read_request_cmd = {{0xC7, 0xF7}}; - -/* The max conversion time for each modes. - * (Section 2.2 OPERATION MODES in the Datasheet) - */ -static const uint32_t conv_time_max[] = {1800, 6300, 23800, 94500}; - -/* The typical conversion time for each modes. - * (Section 2.2 OPERATION MODES in the Datasheet) - */ -static const uint32_t conv_time_typ[] = {1600, 5600, 20800, 83200}; - -/* The Datasheet has no mention of the constants and formulas. - * Instead, it shows only how to use it in the sample code. - * Since there is no detailed description in the ICP10125 product manual, - * the calculation of the pressure implements is the same as shown in - * the 5.11 SAMPLE CODE: EXAMPLE C SYNTAX - */ - -static void icp10125_calculate_conversion_constants(const float *p_LUT, float *A, float *B, - float *C) -{ - const float p_Pa[] = {45000.0, 80000.0, 105000.0}; - - *C = (p_LUT[0] * p_LUT[1] * (p_Pa[0] - p_Pa[1]) + - p_LUT[1] * p_LUT[2] * (p_Pa[1] - p_Pa[2]) + - p_LUT[2] * p_LUT[0] * (p_Pa[2] - p_Pa[0])) / - (p_LUT[2] * (p_Pa[0] - p_Pa[1]) + p_LUT[0] * (p_Pa[1] - p_Pa[2]) + - p_LUT[1] * (p_Pa[2] - p_Pa[0])); - *A = (p_Pa[0] * p_LUT[0] - p_Pa[1] * p_LUT[1] - (p_Pa[1] - p_Pa[0]) * (*C)) / - (p_LUT[0] - p_LUT[1]); - *B = (p_Pa[0] - (*A)) * (p_LUT[0] + (*C)); -} - -static float icp10125_calc_calibrated_ambient_temp(const struct icp10125_data *data) -{ - return -45.f + 175.f / 65536.f * data->raw_ambient_temp; -} - -static float icp10125_calc_calibrated_press(const struct icp10125_data *data) -{ - const float quadr_factor = 1 / 16777216.0; - const float offst_factor = 2048.0; - const float LUT_lower = 3.5 * (1 << 20); - const float LUT_upper = 11.5 * (1 << 20); - float t; - float in[3]; - float A, B, C; - - t = data->raw_ambient_temp - 32768.f; - in[0] = LUT_lower + (data->sensor_constants[0] * t * t) * quadr_factor; - in[1] = offst_factor * data->sensor_constants[3] + - (data->sensor_constants[1] * t * t) * quadr_factor; - in[2] = LUT_upper + (data->sensor_constants[2] * t * t) * quadr_factor; - icp10125_calculate_conversion_constants(in, &A, &B, &C); - - return A + B / (C + data->raw_press); -} - -/* End of porting the 5.11 SAMPLE CODE: EXAMPLE C SYNTAX */ - -static int icp10125_read_otp(const struct device *dev) -{ - struct icp10125_data *data = dev->data; - struct icp10125_sensor_data sensor_data; - - const struct icp10125_dev_config *cfg = dev->config; - int rc = 0; - - rc = i2c_write_dt(&cfg->i2c, (uint8_t *)&otp_read_setup, sizeof(otp_read_setup)); - if (rc < 0) { - LOG_ERR("Failed to write otp_read_setup.\n"); - return rc; - } - - for (size_t i = 0; i < ARRAY_SIZE(data->sensor_constants); i++) { - rc = i2c_write_dt(&cfg->i2c, (uint8_t *)&otp_read_request_cmd, - sizeof(otp_read_request_cmd)); - if (rc < 0) { - LOG_ERR("Failed to write otp_read_request.\n"); - return rc; - } - - rc = i2c_read_dt(&cfg->i2c, (uint8_t *)&sensor_data, sizeof(sensor_data)); - if (rc < 0) { - LOG_ERR("Failed to read otp_read_request.\n"); - return rc; - } - - data->sensor_constants[i] = sys_get_be16(sensor_data.data); - } - - return 0; -} - -#ifdef CONFIG_ICP10125_CHECK_CRC -static int icp10125_check_crc(const uint8_t *data, const size_t len) -{ - /* Details of CRC are described in Chapter 5 Section 8 of the product - * specifications. - */ - return crc8(data, len, CRC_POLY, 0xFF, false); -} -#endif - -static int icp10125_measure(const struct i2c_dt_spec *i2c, const struct icp10125_cmd *cmds, - const uint8_t mode, struct icp10125_sensor_data *sensor_data, - const size_t data_num) -{ - int rc = 0; - - rc = i2c_write_dt(i2c, (uint8_t *)&cmds[mode], sizeof(cmds[mode])); - if (rc < 0) { - LOG_ERR("Failed to start measurement.\n"); - return rc; - } - - /* Wait for the sensor to become readable. - * First wait for the typical time and then read. - * If that fails, wait until the time to surely became readable. - */ - k_sleep(K_USEC(conv_time_typ[mode])); - if (i2c_read_dt(i2c, (uint8_t *)sensor_data, sizeof(sensor_data[0]) * data_num) < 0) { - k_sleep(K_USEC(conv_time_max[mode] - conv_time_typ[mode])); - rc = i2c_read_dt(i2c, (uint8_t *)sensor_data, sizeof(sensor_data[0]) * data_num); - if (rc < 0) { - LOG_ERR("Failed to read measurement.\n"); - return rc; - } - } - -#ifdef CONFIG_ICP10125_CHECK_CRC - /* Calculate CRC from Chapter 5 Section 8 of ICP10125 Product manuals. */ - for (size_t i = 0; i < data_num; i++) { - if (!icp10125_check_crc(sensor_data[i].data, SENSOR_DATA_SIZE)) { - LOG_ERR("Sensor data has invalid CRC.\n"); - return -EIO; - } - } -#endif /* CONFIG_ICP10125_CHECK_CRC */ - - return 0; -} - -static int icp10125_sample_fetch(const struct device *dev, const enum sensor_channel chan) -{ - struct icp10125_data *data = dev->data; - const struct icp10125_dev_config *cfg = dev->config; - uint8_t endian_conversion[3]; - struct icp10125_sensor_data sensor_data[PRESS_AND_AMBIENT_TEMP_DATA_NUM] = {0}; - int rc = 0; - - if (!(chan == SENSOR_CHAN_AMBIENT_TEMP || chan == SENSOR_CHAN_PRESS || - chan == SENSOR_CHAN_ALL)) { - return -ENOTSUP; - } - - if (chan == SENSOR_CHAN_AMBIENT_TEMP) { - rc = icp10125_measure(&cfg->i2c, ambient_temp_measurement_cmds, - cfg->ambient_temp_mode, sensor_data, AMBIENT_TEMP_DATA_NUM); - if (rc < 0) { - return rc; - } - - data->raw_ambient_temp = sys_get_be16(sensor_data[0].data); - } else { - rc = icp10125_measure(&cfg->i2c, press_measurement_cmds, cfg->press_mode, - sensor_data, PRESS_AND_AMBIENT_TEMP_DATA_NUM); - if (rc < 0) { - return rc; - } - - endian_conversion[0] = sensor_data[0].data[0]; - endian_conversion[1] = sensor_data[0].data[1]; - endian_conversion[2] = sensor_data[1].data[0]; - data->raw_press = sys_get_be24(endian_conversion); - data->raw_ambient_temp = sys_get_be16(sensor_data[2].data); - } - - return 0; -} - -static void icp10125_convert_press_value(struct icp10125_data *data, struct sensor_value *val) -{ - sensor_value_from_float(val, icp10125_calc_calibrated_press(data) / 1000.f); -} - -static void icp10125_convert_ambient_temp_value(struct icp10125_data *data, - struct sensor_value *val) -{ - sensor_value_from_float(val, icp10125_calc_calibrated_ambient_temp(data)); -} - -static int icp10125_channel_get(const struct device *dev, enum sensor_channel chan, - struct sensor_value *val) -{ - struct icp10125_data *data = dev->data; - - if (chan == SENSOR_CHAN_AMBIENT_TEMP) { - icp10125_convert_ambient_temp_value(data, val); - } else if (chan == SENSOR_CHAN_PRESS) { - icp10125_convert_press_value(data, val); - } else { - return -ENOTSUP; - } - - return 0; -} - -static int icp10125_init(const struct device *dev) -{ - int rc = icp10125_read_otp(dev); - - if (rc < 0) { - return rc; - } - - return 0; -} - -static DEVICE_API(sensor, icp10125_api_funcs) = { - .sample_fetch = icp10125_sample_fetch, - .channel_get = icp10125_channel_get, -}; - -#define ICP10125_DEFINE(inst) \ - static struct icp10125_data icp10125_drv_##inst; \ - static const struct icp10125_dev_config icp10125_config_##inst = { \ - .i2c = I2C_DT_SPEC_INST_GET(inst), \ - .ambient_temp_mode = DT_INST_ENUM_IDX(inst, temperature_measurement_mode), \ - .press_mode = DT_INST_ENUM_IDX(inst, pressure_measurement_mode)}; \ - DEVICE_DT_INST_DEFINE(inst, icp10125_init, NULL, &icp10125_drv_##inst, \ - &icp10125_config_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ - &icp10125_api_funcs); - -DT_INST_FOREACH_STATUS_OKAY(ICP10125_DEFINE) diff --git a/drivers/sensor/tdk/icp101xx/CMakeLists.txt b/drivers/sensor/tdk/icp101xx/CMakeLists.txt new file mode 100644 index 0000000000000..35912eaf85528 --- /dev/null +++ b/drivers/sensor/tdk/icp101xx/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_compile_definitions_ifdef(CONFIG_CPU_HAS_FPU ICP101XX_DRV_USE_FLOATS) + +zephyr_library_sources(icp101xx_drv.c) +zephyr_library_include_directories(.) diff --git a/drivers/sensor/tdk/icp101xx/Kconfig b/drivers/sensor/tdk/icp101xx/Kconfig new file mode 100644 index 0000000000000..32aaea0bfdee4 --- /dev/null +++ b/drivers/sensor/tdk/icp101xx/Kconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2024 TDK Invensense + +# ICP101xx High Accuracy, Low Power, Barometric Pressure and Temperature Sensor option + +# SPDX-License-Identifier: Apache-2.0 +config ICP101XX + bool "ICP101XX Barometric Pressure and Temperature Sensor" + default y + depends on DT_HAS_INVENSENSE_ICP101XX_ENABLED + select I2C + select USE_EMD_ICP101XX + help + Enable driver for ICP101XX barometric pressure/temperature sensors. diff --git a/drivers/sensor/tdk/icp101xx/icp101xx_drv.c b/drivers/sensor/tdk/icp101xx/icp101xx_drv.c new file mode 100644 index 0000000000000..d198cec2b73e7 --- /dev/null +++ b/drivers/sensor/tdk/icp101xx/icp101xx_drv.c @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2024 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT invensense_icp101xx + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "icp101xx_drv.h" + +LOG_MODULE_REGISTER(ICP101XX, CONFIG_SENSOR_LOG_LEVEL); + +#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 +#error "ICP101XX driver enabled without any compatible device in devicetree" +#endif + +inline void inv_icp101xx_sleep_us(int us) +{ + k_sleep(K_USEC(us)); +} + +static int inv_io_hal_read_reg(void *ctx, uint8_t reg, uint8_t *rbuffer, uint32_t rlen) +{ + struct device *dev = (struct device *)ctx; + const struct icp101xx_config *cfg = (const struct icp101xx_config *)dev->config; + + return i2c_read_dt(&cfg->i2c, (uint8_t *)rbuffer, rlen); +} + +static int inv_io_hal_write_reg(void *ctx, uint8_t reg, const uint8_t *wbuffer, uint32_t wlen) +{ + struct device *dev = (struct device *)ctx; + const struct icp101xx_config *cfg = (const struct icp101xx_config *)dev->config; + + return i2c_write_dt(&cfg->i2c, (uint8_t *)wbuffer, wlen); +} + +static uint8_t get_timeout_ms(enum icp101xx_meas mode) +{ + switch (mode) { + case ICP101XX_MEAS_LOW_POWER_T_FIRST: + case ICP101XX_MEAS_LOW_POWER_P_FIRST: + return 2; + case ICP101XX_MEAS_NORMAL_T_FIRST: + case ICP101XX_MEAS_NORMAL_P_FIRST: + return 7; + case ICP101XX_MEAS_LOW_NOISE_T_FIRST: + case ICP101XX_MEAS_LOW_NOISE_P_FIRST: + return 24; + default: + case ICP101XX_MEAS_ULTRA_LOW_NOISE_T_FIRST: + case ICP101XX_MEAS_ULTRA_LOW_NOISE_P_FIRST: + return 95; + } +} + +static uint8_t get_conversion_ms(enum icp101xx_meas mode) +{ + switch (mode) { + case ICP101XX_MEAS_LOW_POWER_T_FIRST: + case ICP101XX_MEAS_LOW_POWER_P_FIRST: + return 1; + case ICP101XX_MEAS_NORMAL_T_FIRST: + case ICP101XX_MEAS_NORMAL_P_FIRST: + return 5; + case ICP101XX_MEAS_LOW_NOISE_T_FIRST: + case ICP101XX_MEAS_LOW_NOISE_P_FIRST: + return 20; + default: + case ICP101XX_MEAS_ULTRA_LOW_NOISE_T_FIRST: + case ICP101XX_MEAS_ULTRA_LOW_NOISE_P_FIRST: + return 80; + } +} + +#ifdef ICP101XX_DRV_USE_FLOATS +#define ATMOSPHERICAL_PRESSURE_KPA ((float)101.325) +#define TO_KELVIN(temp_C) ((float)273.15 + temp_C) +/* + * Constant in altitude formula: + * M*g/R = (0,0289644 * 9,80665 / 8,31432) + * with M the molar mass of air. + * with g the gravitational force acceleration. + * with R the universal gaz constant. + */ +#define HEIGHT_TO_PRESSURE_COEFF ((float)0.03424) + +/* + * Constant in altitude formula: + * R / (M*g) = 8,31432 / (0,0289644 * 9,80665) + * with M the molar mass of air. + * with g the gravitational force acceleration. + * with R the universal gaz constant. + */ +#define PRESSURE_TO_HEIGHT_COEFF ((float)29.27127) +/* + * Constant for altitude formula: + * logarithm of pressure at 0m + * ln(101.325) + */ +#define LOG_ATMOSPHERICAL_PRESSURE ((float)4.61833) + +float convertToHeight(float pressure_kp, float temperature_C) +{ + return PRESSURE_TO_HEIGHT_COEFF * TO_KELVIN(temperature_C) * + (LOG_ATMOSPHERICAL_PRESSURE - logf(pressure_kp)); +} +#endif + +static int icp101xx_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + int err = 0; + struct icp101xx_data *data = (struct icp101xx_data *)dev->data; + + __ASSERT_NO_MSG(val != NULL); + if (chan == SENSOR_CHAN_PRESS) { + if (attr == SENSOR_ATTR_CONFIGURATION) { + if ((val->val1 >= ICP101XX_MEAS_LOW_POWER_T_FIRST) && + (val->val1 <= ICP101XX_MEAS_ULTRA_LOW_NOISE_P_FIRST)) { + data->icp_device.measurement_mode = val->val1; + } else { + LOG_ERR("Not supported ATTR value"); + return -EINVAL; + } + + } else { + LOG_ERR("Not supported ATTR"); + return -EINVAL; + } + }; + return err; +} + +static int icp101xx_sample_fetch(const struct device *dev, const enum sensor_channel chan) +{ + struct icp101xx_data *data = (struct icp101xx_data *)dev->data; + int rc = 0; + uint64_t timeout; + + if (!((chan == SENSOR_CHAN_AMBIENT_TEMP) || (chan == SENSOR_CHAN_PRESS) || + (chan == SENSOR_CHAN_ALTITUDE) || (chan == SENSOR_CHAN_ALL))) { + return -ENOTSUP; + } + rc = inv_icp101xx_enable_sensor(&data->icp_device, 1); + /* Compute timeout for the measure */ + timeout = k_uptime_get() + get_timeout_ms(data->icp_device.measurement_mode); + /* Initial sleep waiting the sensor proceeds with the measure */ + k_sleep(K_MSEC(get_conversion_ms(data->icp_device.measurement_mode))); + do { + k_sleep(K_USEC(200)); + rc = inv_icp101xx_get_data(&data->icp_device, &(data->raw_pressure), + &(data->raw_temperature), &(data->pressure), + &(data->temperature)); + } while ((rc != 0) && (k_uptime_get() <= timeout)); + return rc; +} + +static int icp101xx_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + + struct icp101xx_data *data = (struct icp101xx_data *)dev->data; + + val->val1 = 0; + val->val2 = 0; + + if (!((chan == SENSOR_CHAN_AMBIENT_TEMP) || (chan == SENSOR_CHAN_PRESS) || + (chan == SENSOR_CHAN_ALTITUDE))) { + return -ENOTSUP; + } + /* Zephyr expects kPa while ICP101xx returns Pa */ + if (chan == SENSOR_CHAN_AMBIENT_TEMP) { +#ifdef ICP101XX_DRV_USE_FLOATS + sensor_value_from_float(val, data->temperature); +#else + val->val1 = data->temperature >> 4; + val->val2 = (data->temperature % 16) * 1000000 / 16; +#endif + } else if (chan == SENSOR_CHAN_PRESS) { +#ifdef ICP101XX_DRV_USE_FLOATS + sensor_value_from_float(val, data->pressure / 1000); +#else + val->val1 = data->pressure / 1000; + val->val2 = (data->pressure % 1000) * 1000; +#endif +#ifdef ICP101XX_DRV_USE_FLOATS + } else if (chan == SENSOR_CHAN_ALTITUDE) { + float altitude = convertToHeight(data->pressure / 1000, data->temperature); + + sensor_value_from_float(val, altitude); +#endif + } else { + return -ENOTSUP; + } + + return 0; +} + +static int icp101xx_init(const struct device *dev) +{ + int rc = 0; + struct icp101xx_data *data = (struct icp101xx_data *)dev->data; + const struct icp101xx_config *cfg = (const struct icp101xx_config *)dev->config; + + memset(&(data->icp_device), 0, sizeof(data->icp_device)); + + data->icp_device.serif.context = (void *)dev; + data->icp_device.serif.read_reg = inv_io_hal_read_reg; + data->icp_device.serif.write_reg = inv_io_hal_write_reg; + /* maximum number of bytes allowed per serial read */ + data->icp_device.serif.max_read = 2048; + /* maximum number of bytes allowed per serial write */ + data->icp_device.serif.max_write = 2048; + + rc = inv_icp101xx_soft_reset(&data->icp_device); + if (rc != 0) { + LOG_ERR("Soft reset error %d", rc); + return rc; + } + inv_icp101xx_init(&data->icp_device); + if (rc != 0) { + LOG_ERR("Init error %d", rc); + return rc; + } + data->icp_device.measurement_mode = cfg->mode; + + /* successful init, return 0 */ + return 0; +} + +static DEVICE_API(sensor, icp101xx_api_funcs) = { + .sample_fetch = icp101xx_sample_fetch, + .channel_get = icp101xx_channel_get, + .attr_set = icp101xx_attr_set, +}; + +#define ICP101XX_DEFINE(inst) \ + static struct icp101xx_data icp101xx_drv_##inst; \ + static const struct icp101xx_config icp101xx_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .mode = DT_INST_ENUM_IDX(inst, mode), \ + }; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, icp101xx_init, NULL, &icp101xx_drv_##inst, \ + &icp101xx_config_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &icp101xx_api_funcs); + +DT_INST_FOREACH_STATUS_OKAY(ICP101XX_DEFINE) diff --git a/drivers/sensor/tdk/icp101xx/icp101xx_drv.h b/drivers/sensor/tdk/icp101xx/icp101xx_drv.h new file mode 100644 index 0000000000000..9ecac4257f2ed --- /dev/null +++ b/drivers/sensor/tdk/icp101xx/icp101xx_drv.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ICP101XXX_ICP101XXX_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICP101XXX_ICP101XXX_H_ + +#include +#include +#include +#include +#include +#include "Icp101xx.h" +#include "Icp101xxSerif.h" + +#define ICP101XX_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) + +struct icp101xx_data { + int raw_pressure; + int raw_temperature; +#ifdef ICP101XX_DRV_USE_FLOATS + float pressure; + float temperature; +#else + int32_t pressure; + int32_t temperature; +#endif + inv_icp101xx_t icp_device; +}; + +struct icp101xx_config { + struct i2c_dt_spec i2c; + int mode; +}; + +#endif diff --git a/drivers/sensor/ti/CMakeLists.txt b/drivers/sensor/ti/CMakeLists.txt index 452d0e8e37a4f..8a497df294846 100644 --- a/drivers/sensor/ti/CMakeLists.txt +++ b/drivers/sensor/ti/CMakeLists.txt @@ -20,4 +20,5 @@ add_subdirectory_ifdef(CONFIG_TMP108 tmp108) add_subdirectory_ifdef(CONFIG_TMP112 tmp112) add_subdirectory_ifdef(CONFIG_TMP114 tmp114) add_subdirectory_ifdef(CONFIG_TMP116 tmp116) +add_subdirectory_ifdef(CONFIG_TMP435 tmp435) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/ti/Kconfig b/drivers/sensor/ti/Kconfig index f0655981a4c36..7e9f0e95f291e 100644 --- a/drivers/sensor/ti/Kconfig +++ b/drivers/sensor/ti/Kconfig @@ -20,4 +20,5 @@ source "drivers/sensor/ti/tmp108/Kconfig" source "drivers/sensor/ti/tmp112/Kconfig" source "drivers/sensor/ti/tmp114/Kconfig" source "drivers/sensor/ti/tmp116/Kconfig" +source "drivers/sensor/ti/tmp435/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/ti/ina23x/ina230.c b/drivers/sensor/ti/ina23x/ina230.c index c65d5b80d97f2..1e496a400ff06 100644 --- a/drivers/sensor/ti/ina23x/ina230.c +++ b/drivers/sensor/ti/ina23x/ina230.c @@ -249,7 +249,7 @@ static DEVICE_API(sensor, ina230_driver_api) = { #endif /* CONFIG_INA230_TRIGGER */ #define INA230_DRIVER_INIT(inst, type) \ - static struct ina230_data drv_data_##inst; \ + static struct ina230_data drv_data_##type##inst; \ static const struct ina230_config drv_config_##type##inst = { \ .bus = I2C_DT_SPEC_INST_GET(inst), \ .config = (DT_INST_PROP_OR(inst, high_precision, 0) << 12) | \ @@ -266,7 +266,7 @@ static DEVICE_API(sensor, ina230_driver_api) = { (DT_INST_PROP_OR(inst, high_precision, 0) << 1)), \ COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, alert_gpios), (INA230_CFG_IRQ(inst)), \ ())}; \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, &ina230_init, NULL, &drv_data_##inst, \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, &ina230_init, NULL, &drv_data_##type##inst, \ &drv_config_##type##inst, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, &ina230_driver_api); diff --git a/drivers/sensor/ti/tmag5170/tmag5170.c b/drivers/sensor/ti/tmag5170/tmag5170.c index 48f3eaaaa6315..258e3c5fcfb01 100644 --- a/drivers/sensor/ti/tmag5170/tmag5170.c +++ b/drivers/sensor/ti/tmag5170/tmag5170.c @@ -266,7 +266,7 @@ static void tmag5170_convert_temp_reading_to_celsius(struct sensor_value *output output->val2 = (result % 100000) * 10; } -static void tmag5170_covert_angle_reading_to_degrees(struct sensor_value *output, +static void tmag5170_convert_angle_reading_to_degrees(struct sensor_value *output, uint16_t chan_reading) { /* 12 MSBs store the integer part of the result, @@ -427,7 +427,7 @@ static int tmag5170_channel_get(const struct device *dev, drv_data->chip_revision); break; case SENSOR_CHAN_ROTATION: - tmag5170_covert_angle_reading_to_degrees(val, drv_data->angle); + tmag5170_convert_angle_reading_to_degrees(val, drv_data->angle); break; case SENSOR_CHAN_AMBIENT_TEMP: tmag5170_convert_temp_reading_to_celsius(val, drv_data->temperature); @@ -482,7 +482,7 @@ static int tmag5170_init_registers(const struct device *dev) TMAG5170_OPERATING_MODE_SET(cfg->operating_mode) | TMAG5170_CONV_AVG_SET(cfg->oversampling) | TMAG5170_MAG_TEMPCO_SET(cfg->magnet_type) | - TMAG5170_T_CH_EN_SET(cfg->tempeature_measurement) | + TMAG5170_T_CH_EN_SET(cfg->temperature_measurement) | TMAG5170_T_RATE_SET(cfg->disable_temperature_oversampling)); } @@ -563,7 +563,7 @@ static int tmag5170_init(const struct device *dev) .z_range = DT_INST_ENUM_IDX(_num, z_range), \ .operating_mode = DT_INST_PROP(_num, operating_mode), \ .oversampling = DT_INST_ENUM_IDX(_num, oversampling), \ - .tempeature_measurement = DT_INST_PROP(_num, enable_temperature_channel), \ + .temperature_measurement = DT_INST_PROP(_num, enable_temperature_channel), \ .magnet_type = DT_INST_ENUM_IDX(_num, magnet_type), \ .angle_measurement = DT_INST_ENUM_IDX(_num, angle_measurement), \ .disable_temperature_oversampling = DT_INST_PROP(_num, \ diff --git a/drivers/sensor/ti/tmag5170/tmag5170.h b/drivers/sensor/ti/tmag5170/tmag5170.h index 28f76d2e12b05..c694d4f34ec83 100644 --- a/drivers/sensor/ti/tmag5170/tmag5170.h +++ b/drivers/sensor/ti/tmag5170/tmag5170.h @@ -19,7 +19,7 @@ struct tmag5170_dev_config { uint8_t y_range; uint8_t z_range; uint8_t oversampling; - bool tempeature_measurement; + bool temperature_measurement; uint8_t magnet_type; uint8_t angle_measurement; bool disable_temperature_oversampling; diff --git a/drivers/sensor/ti/tmag5273/Kconfig b/drivers/sensor/ti/tmag5273/Kconfig index 8d45c5d152223..95db0ecc0352e 100644 --- a/drivers/sensor/ti/tmag5273/Kconfig +++ b/drivers/sensor/ti/tmag5273/Kconfig @@ -6,7 +6,7 @@ config TMAG5273 bool "TMAG5273/TMAG3001 3D Hall-Effect Sensor" default y - depends on DT_HAS_TI_TMAG5273_ENABLED + depends on DT_HAS_TI_TMAG5273_ENABLED || DT_HAS_TI_TMAG3001_ENABLED select I2C select GPIO imply CRC diff --git a/drivers/sensor/ti/tmag5273/tmag5273.c b/drivers/sensor/ti/tmag5273/tmag5273.c index 0d53acc269e37..d3711da694420 100644 --- a/drivers/sensor/ti/tmag5273/tmag5273.c +++ b/drivers/sensor/ti/tmag5273/tmag5273.c @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT ti_tmag5273 - #include "tmag5273.h" #include @@ -47,6 +45,11 @@ LOG_MODULE_REGISTER(TMAG5273, CONFIG_SENSOR_LOG_LEVEL); struct tmag5273_config { struct i2c_dt_spec i2c; + enum { + TMAG5273_PART, + TMAG3001_PART + } part; + uint8_t mag_channel; uint8_t axis; bool temperature; @@ -71,8 +74,8 @@ struct tmag5273_config { }; struct tmag5273_data { - uint8_t version; /** version as given by the sensor */ - uint16_t conversion_time_us; /** time for one conversion */ + enum tmag5273_version version; /** version as given by the sensor */ + uint16_t conversion_time_us; /** time for one conversion */ int16_t x_sample; /** measured B-field @x-axis */ int16_t y_sample; /** measured B-field @y-axis */ @@ -1152,7 +1155,26 @@ static int tmag5273_init(const struct device *dev) return -EIO; } - drv_data->version = regdata & TMAG5273_VER_MSK; + switch (drv_cfg->part) { + case TMAG5273_PART: + drv_data->version = regdata & TMAG5273_VER_MSK; + break; + case TMAG3001_PART: + drv_data->version = regdata & TMAG3001_VER_MSK; + break; + default: + __ASSERT(false, "invalid part %d", drv_cfg->part); + } + switch (drv_data->version) { + case TMAG5273_VER_TMAG5273X1: + case TMAG5273_VER_TMAG5273X2: + case TMAG5273_VER_TMAG3001X1: + case TMAG5273_VER_TMAG3001X2: + break; + default: + LOG_ERR("unsupported version %d", drv_data->version); + return -EIO; + } /* magnetic measurement range based on version, apply correct one */ if (drv_cfg->meas_range == TMAG5273_DT_AXIS_RANGE_LOW) { @@ -1217,33 +1239,38 @@ static DEVICE_API(sensor, tmag5273_driver_api) = { : 0) /** Instantiation macro */ -#define TMAG5273_DEFINE(inst) \ - BUILD_ASSERT(IS_ENABLED(CONFIG_CRC) || (DT_INST_PROP(inst, crc_enabled) == 0), \ +#define TMAG5273_DEFINE(inst, compat, _part) \ + BUILD_ASSERT(IS_ENABLED(CONFIG_CRC) || (DT_PROP(DT_INST(inst, compat), crc_enabled) == 0), \ "CRC support necessary"); \ - BUILD_ASSERT(!DT_INST_PROP(inst, trigger_conversion_via_int) || \ - DT_INST_NODE_HAS_PROP(inst, int_gpios), \ + BUILD_ASSERT(!DT_PROP(DT_INST(inst, compat), trigger_conversion_via_int) || \ + DT_NODE_HAS_PROP(DT_INST(inst, compat), int_gpios), \ "trigger-conversion-via-int requires int-gpios to be defined"); \ - static const struct tmag5273_config tmag5273_driver_cfg##inst = { \ - .i2c = I2C_DT_SPEC_INST_GET(inst), \ - .mag_channel = DT_INST_PROP(inst, axis), \ - .axis = (TMAG5273_DT_X_AXIS_BIT(DT_INST_PROP(inst, axis)) | \ - TMAG5273_DT_Y_AXIS_BIT(DT_INST_PROP(inst, axis)) | \ - TMAG5273_DT_Z_AXIS_BIT(DT_INST_PROP(inst, axis))), \ - .temperature = DT_INST_PROP(inst, temperature), \ - .meas_range = DT_INST_PROP(inst, range), \ - .temperature_coefficient = DT_INST_PROP(inst, temperature_coefficient), \ - .angle_magnitude_axis = DT_INST_PROP(inst, angle_magnitude_axis), \ - .ch_mag_gain_correction = DT_INST_PROP(inst, ch_mag_gain_correction), \ - .operation_mode = DT_INST_PROP(inst, operation_mode), \ - .averaging = DT_INST_PROP(inst, average_mode), \ - .trigger_conv_via_int = DT_INST_PROP(inst, trigger_conversion_via_int), \ - .low_noise_mode = DT_INST_PROP(inst, low_noise), \ - .ignore_diag_fail = DT_INST_PROP(inst, ignore_diag_fail), \ - .int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \ - IF_ENABLED(CONFIG_CRC, (.crc_enabled = DT_INST_PROP(inst, crc_enabled),))}; \ - static struct tmag5273_data tmag5273_driver_data##inst; \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, tmag5273_init, NULL, &tmag5273_driver_data##inst, \ - &tmag5273_driver_cfg##inst, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, &tmag5273_driver_api); - -DT_INST_FOREACH_STATUS_OKAY(TMAG5273_DEFINE) + static const struct tmag5273_config compat##_driver_cfg##inst = { \ + .i2c = I2C_DT_SPEC_GET(DT_INST(inst, compat)), \ + .part = _part, \ + .mag_channel = DT_PROP(DT_INST(inst, compat), axis), \ + .axis = (TMAG5273_DT_X_AXIS_BIT(DT_PROP(DT_INST(inst, compat), axis)) | \ + TMAG5273_DT_Y_AXIS_BIT(DT_PROP(DT_INST(inst, compat), axis)) | \ + TMAG5273_DT_Z_AXIS_BIT(DT_PROP(DT_INST(inst, compat), axis))), \ + .temperature = DT_PROP(DT_INST(inst, compat), temperature), \ + .meas_range = DT_PROP(DT_INST(inst, compat), range), \ + .temperature_coefficient = \ + DT_PROP(DT_INST(inst, compat), temperature_coefficient), \ + .angle_magnitude_axis = DT_PROP(DT_INST(inst, compat), angle_magnitude_axis), \ + .ch_mag_gain_correction = DT_PROP(DT_INST(inst, compat), ch_mag_gain_correction), \ + .operation_mode = DT_PROP(DT_INST(inst, compat), operation_mode), \ + .averaging = DT_PROP(DT_INST(inst, compat), average_mode), \ + .trigger_conv_via_int = \ + DT_PROP(DT_INST(inst, compat), trigger_conversion_via_int), \ + .low_noise_mode = DT_PROP(DT_INST(inst, compat), low_noise), \ + .ignore_diag_fail = DT_PROP(DT_INST(inst, compat), ignore_diag_fail), \ + .int_gpio = GPIO_DT_SPEC_GET_OR(DT_INST(inst, compat), int_gpios, {0}), \ + IF_ENABLED(CONFIG_CRC, \ + (.crc_enabled = DT_PROP(DT_INST(inst, compat), crc_enabled),))}; \ + static struct tmag5273_data compat##_driver_data##inst; \ + SENSOR_DEVICE_DT_DEFINE(DT_INST(inst, compat), tmag5273_init, NULL, \ + &compat##_driver_data##inst, &compat##_driver_cfg##inst, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &tmag5273_driver_api); + +DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(ti_tmag5273, TMAG5273_DEFINE, TMAG5273_PART) +DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(ti_tmag3001, TMAG5273_DEFINE, TMAG3001_PART) diff --git a/drivers/sensor/ti/tmag5273/tmag5273.h b/drivers/sensor/ti/tmag5273/tmag5273.h index 76cc84a99ab8c..461e311ea46af 100644 --- a/drivers/sensor/ti/tmag5273/tmag5273.h +++ b/drivers/sensor/ti/tmag5273/tmag5273.h @@ -194,14 +194,17 @@ #define TMAG5273_I2C_ADDRESS_UPDATE_ENABLE (1 << TMAG5273_I2C_ADDRESS_UPDATE_EN_POS) /* Register DEVICE_ID */ -#define TMAG5273_VER_POS 0 -#define TMAG3001_VER_POS 2 -#define TMAG5273_VER_MSK GENMASK(3, 0) - -#define TMAG5273_VER_TMAG5273X1 (1 << TMAG5273_VER_POS) -#define TMAG5273_VER_TMAG5273X2 (2 << TMAG5273_VER_POS) -#define TMAG5273_VER_TMAG3001X1 (0 << TMAG3001_VER_POS) -#define TMAG5273_VER_TMAG3001X2 (2 << TMAG3001_VER_POS) +#define TMAG5273_VER_POS 0 +#define TMAG3001_VER_POS 2 +#define TMAG5273_VER_MSK GENMASK(1, 0) +#define TMAG3001_VER_MSK GENMASK(3, 2) + +enum tmag5273_version { + TMAG5273_VER_TMAG5273X1 = 1 << TMAG5273_VER_POS, + TMAG5273_VER_TMAG5273X2 = 2 << TMAG5273_VER_POS, + TMAG5273_VER_TMAG3001X1 = 0 << TMAG3001_VER_POS, + TMAG5273_VER_TMAG3001X2 = 2 << TMAG3001_VER_POS, +}; /* Register CONV_STATUS */ #define TMAG5273_SET_COUNT_POS 5 diff --git a/drivers/sensor/ti/tmp108/CMakeLists.txt b/drivers/sensor/ti/tmp108/CMakeLists.txt index f8cce2bad852b..620f9ea928368 100644 --- a/drivers/sensor/ti/tmp108/CMakeLists.txt +++ b/drivers/sensor/ti/tmp108/CMakeLists.txt @@ -2,4 +2,5 @@ zephyr_library() -zephyr_library_sources(tmp108.c tmp108_trigger.c) +zephyr_library_sources(tmp108.c) +zephyr_library_sources_ifdef(CONFIG_TMP108_ALERT_INTERRUPTS tmp108_trigger.c) diff --git a/drivers/sensor/ti/tmp108/tmp108.c b/drivers/sensor/ti/tmp108/tmp108.c index 7c130d23eec21..e503a30090e8b 100644 --- a/drivers/sensor/ti/tmp108/tmp108.c +++ b/drivers/sensor/ti/tmp108/tmp108.c @@ -100,45 +100,57 @@ static int tmp108_sample_fetch(const struct device *dev, enum sensor_channel chan) { struct tmp108_data *drv_data = dev->data; + uint16_t config, converting_mask; int result; if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP) { return -ENOTSUP; } - /* If one shot mode is set, query chip for reading - * should be finished 30 ms later - */ - if (drv_data->one_shot_mode == true) { + if (!drv_data->one_shot_mode) { + /* Read the latest temperature result */ + return ti_tmp108_read_temp(dev); + } - result = tmp108_write_config(dev, - TI_TMP108_MODE_MASK(dev), - TI_TMP108_MODE_ONE_SHOT(dev)); + /* Trigger the conversion */ + result = tmp108_write_config(dev, + TI_TMP108_MODE_MASK(dev), + TI_TMP108_MODE_ONE_SHOT(dev)); + if (result < 0) { + return result; + } - if (result < 0) { - return result; - } + /* Typical conversion time: + * TMP108: 27ms + * AS6212: 36ms + * Maximum conversion time: + * TMP108: 35ms + * AS6212: 51ms + */ + const uint32_t conv_time_min = 25; + const uint32_t conv_time_max = 100; + const uint32_t poll_period = 5; - /* Schedule read to start in 30 ms if mode change was successful - * the typical wakeup time given in the data sheet is 27 - */ - result = k_work_schedule(&drv_data->scheduled_work, - K_MSEC(TMP108_WAKEUP_TIME_IN_MS(dev))); + k_sleep(K_MSEC(conv_time_min)); + converting_mask = TI_TMP108_CONF_M1(dev) | TI_TMP108_CONF_M0(dev); + for (int i = conv_time_min; i < conv_time_max; i += poll_period) { + /* Read the config register */ + result = tmp108_reg_read(dev, TI_TMP108_REG_CONF, &config); if (result < 0) { return result; } - - return 0; - } - - result = ti_tmp108_read_temp(dev); - - if (result < 0) { - return result; + if ((config & converting_mask) == 0) { + /* Conversion has finished */ + LOG_DBG("Conversion complete after %d ms", i); + return ti_tmp108_read_temp(dev); + } + /* Wait before reading again */ + k_sleep(K_MSEC(poll_period)); } - return 0; + /* Conversion timed out */ + return -EAGAIN; } static int tmp108_channel_get(const struct device *dev, @@ -153,10 +165,7 @@ static int tmp108_channel_get(const struct device *dev, } uval = ((int32_t)drv_data->sample * TMP108_TEMP_MULTIPLIER(dev)) / TMP108_TEMP_DIVISOR(dev); - val->val1 = uval / 1000000; - val->val2 = uval % 1000000; - - return 0; + return sensor_value_from_micro(val, uval); } static int tmp108_attr_get(const struct device *dev, @@ -192,16 +201,17 @@ static int tmp108_attr_set(const struct device *dev, const struct sensor_value *val) { struct tmp108_data *drv_data = dev->data; - uint16_t mode = 0; - uint16_t reg_value = 0; + __maybe_unused uint16_t reg_value; + __maybe_unused int32_t uval; + uint16_t mode; int result = 0; - int32_t uval; if (chan != SENSOR_CHAN_AMBIENT_TEMP && chan != SENSOR_CHAN_ALL) { return -ENOTSUP; } switch ((int) attr) { +#ifdef CONFIG_TMP108_ALERT_INTERRUPTS case SENSOR_ATTR_HYSTERESIS: if (TI_TMP108_HYSTER_0_C(dev) == TI_TMP108_CONF_NA) { LOG_WRN("AS621x Series lacks Hysterisis setttings"); @@ -236,7 +246,7 @@ static int tmp108_attr_set(const struct device *dev, break; case SENSOR_ATTR_LOWER_THRESH: - uval = val->val1 * 1000000 + val->val2; + uval = sensor_value_to_micro(val); reg_value = (uval * TMP108_TEMP_DIVISOR(dev)) / TMP108_TEMP_MULTIPLIER(dev); result = tmp108_reg_write(dev, TI_TMP108_REG_LOW_LIMIT, @@ -244,13 +254,25 @@ static int tmp108_attr_set(const struct device *dev, break; case SENSOR_ATTR_UPPER_THRESH: - uval = val->val1 * 1000000 + val->val2; + uval = sensor_value_to_micro(val); reg_value = (uval * TMP108_TEMP_DIVISOR(dev)) / TMP108_TEMP_MULTIPLIER(dev); result = tmp108_reg_write(dev, TI_TMP108_REG_HIGH_LIMIT, reg_value); break; + case SENSOR_ATTR_TMP108_ALERT_POLARITY: + if (val->val1 == 1) { + mode = TI_TMP108_CONF_POL_HIGH(dev); + } else { + mode = TI_TMP108_CONF_POL_LOW(dev); + } + result = tmp108_write_config(dev, + TI_TMP108_CONF_POL_MASK(dev), + mode); + break; +#endif /* CONFIG_TMP108_ALERT_INTERRUPTS */ + case SENSOR_ATTR_SAMPLING_FREQUENCY: if (val->val1 < 1) { mode = TI_TMP108_FREQ_4_SECS(dev); @@ -287,17 +309,6 @@ static int tmp108_attr_set(const struct device *dev, drv_data->one_shot_mode = true; break; - case SENSOR_ATTR_TMP108_ALERT_POLARITY: - if (val->val1 == 1) { - mode = TI_TMP108_CONF_POL_HIGH(dev); - } else { - mode = TI_TMP108_CONF_POL_LOW(dev); - } - result = tmp108_write_config(dev, - TI_TMP108_CONF_POL_MASK(dev), - mode); - break; - default: return -ENOTSUP; } @@ -314,7 +325,9 @@ static DEVICE_API(sensor, tmp108_driver_api) = { .attr_get = tmp108_attr_get, .sample_fetch = tmp108_sample_fetch, .channel_get = tmp108_channel_get, +#ifdef CONFIG_TMP108_ALERT_INTERRUPTS .trigger_set = tmp_108_trigger_set, +#endif }; #ifdef CONFIG_TMP108_ALERT_INTERRUPTS @@ -362,7 +375,6 @@ static int setup_interrupts(const struct device *dev) static int tmp108_init(const struct device *dev) { const struct tmp108_config *cfg = dev->config; - struct tmp108_data *drv_data = dev->data; int result = 0; if (!device_is_ready(cfg->i2c_spec.bus)) { @@ -370,12 +382,12 @@ static int tmp108_init(const struct device *dev) return -ENODEV; } - drv_data->scheduled_work.work.handler = tmp108_trigger_handle_one_shot; +#ifdef CONFIG_TMP108_ALERT_INTERRUPTS + struct tmp108_data *drv_data = dev->data; /* save this driver instance for passing to other functions */ drv_data->tmp108_dev = dev; -#ifdef CONFIG_TMP108_ALERT_INTERRUPTS result = setup_interrupts(dev); if (result < 0) { @@ -389,22 +401,16 @@ static int tmp108_init(const struct device *dev) return result; } -#define TMP108_DEFINE(inst, t) \ - static struct tmp108_data tmp108_prv_data_##inst##t; \ - static const struct tmp108_config tmp108_config_##inst##t = { \ - .i2c_spec = I2C_DT_SPEC_INST_GET(inst), \ - .alert_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, \ - alert_gpios, { 0 }),\ - .reg_def = t##_CONF \ - }; \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, \ - &tmp108_init, \ - NULL, \ - &tmp108_prv_data_##inst##t, \ - &tmp108_config_##inst##t, \ - POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, \ - &tmp108_driver_api); +#define TMP108_DEFINE(inst, t) \ + static struct tmp108_data tmp108_prv_data_##inst##t; \ + static const struct tmp108_config tmp108_config_##inst##t = { \ + .i2c_spec = I2C_DT_SPEC_INST_GET(inst), \ + IF_ENABLED(CONFIG_TMP108_ALERT_INTERRUPTS, \ + (.alert_gpio = GPIO_DT_SPEC_INST_GET(inst, alert_gpios),)) \ + .reg_def = t##_CONF}; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, &tmp108_init, NULL, &tmp108_prv_data_##inst##t, \ + &tmp108_config_##inst##t, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &tmp108_driver_api); #define TMP108_INIT(n) TMP108_DEFINE(n, TI_TMP108) #undef DT_DRV_COMPAT diff --git a/drivers/sensor/ti/tmp108/tmp108.h b/drivers/sensor/ti/tmp108/tmp108.h index 44dc2d119364c..14d8f92be2c4a 100644 --- a/drivers/sensor/ti/tmp108/tmp108.h +++ b/drivers/sensor/ti/tmp108/tmp108.h @@ -20,36 +20,36 @@ #define TI_TMP108_REG_LOW_LIMIT 0x02 /** Low alert set register */ #define TI_TMP108_REG_HIGH_LIMIT 0x03 /** High alert set register */ -#define AMS_AS6212_CONF {.CONF_HYS1 = TI_TMP108_CONF_NA,\ - .CONF_HYS0 = TI_TMP108_CONF_NA,\ - .CONF_CR0 = 0x0040, \ - .CONF_CR1 = 0x0080, \ - .CONF_M1 = 0x0000, \ - .CONF_TM = 0x0200, \ - .CONF_POL = 0x0400, \ - .CONF_M0 = 0x8000, \ - .CONF_RST = 0x0080, \ - .TEMP_MULT = 15625, \ - .TEMP_DIV = 2, \ - .WAKEUP_TIME_IN_MS = 120 } - -#define TI_TMP108_CONF {.CONF_HYS0 = 0x0010, \ - .CONF_HYS1 = 0x0020, \ - .CONF_POL = 0x0080, \ - .CONF_M0 = 0x0100, \ - .CONF_M1 = 0x0200, \ - .CONF_TM = 0x0400, \ - .CONF_CR0 = 0x2000, \ - .CONF_CR1 = 0x4000, \ - .CONF_RST = 0x0022, \ - .TEMP_MULT = 15625, \ - .TEMP_DIV = 4, \ - .WAKEUP_TIME_IN_MS = 30 } +#define AMS_AS6212_CONF \ + {.CONF_CR0 = 0x0040, \ + .CONF_CR1 = 0x0080, \ + .CONF_SLEEP = 0x0100, \ + .CONF_M1 = 0x0000, \ + .CONF_TM = 0x0200, \ + .CONF_M0 = 0x8000, \ + .CONF_RST = 0x0080, \ + .TEMP_MULT = 15625, \ + .TEMP_DIV = 2, \ + IF_ENABLED(CONFIG_TMP108_ALERT_INTERRUPTS, (.CONF_POL = 0x0400))} + +#define TI_TMP108_CONF \ + {.CONF_M0 = 0x0100, \ + .CONF_M1 = 0x0200, \ + .CONF_TM = 0x0400, \ + .CONF_CR0 = 0x2000, \ + .CONF_CR1 = 0x4000, \ + .CONF_RST = 0x0022, \ + .TEMP_MULT = 15625, \ + .TEMP_DIV = 4, \ + IF_ENABLED(CONFIG_TMP108_ALERT_INTERRUPTS, \ + (.CONF_HYS0 = 0x0010, .CONF_HYS1 = 0x0020, .CONF_POL = 0x0080))} #define TI_TMP108_MODE_SHUTDOWN(x) 0 -#define TI_TMP108_MODE_ONE_SHOT(x) TI_TMP108_CONF_M0(x) +#define TI_TMP108_MODE_ONE_SHOT(x) (TI_TMP108_CONF_M0(x) | TI_TMP108_CONF_SLEEP(x)) #define TI_TMP108_MODE_CONTINUOUS(x) TI_TMP108_CONF_M1(x) -#define TI_TMP108_MODE_MASK(x) ~(TI_TMP108_CONF_M0(x) | TI_TMP108_CONF_M1(x)) +#define TI_TMP108_MODE_MASK(x) ~(TI_TMP108_CONF_M0(x) | \ + TI_TMP108_CONF_M1(x) | \ + TI_TMP108_CONF_SLEEP(x)) #define TI_TMP108_FREQ_4_SECS(x) 0 #define TI_TMP108_FREQ_1_HZ(x) TI_TMP108_GET_CONF(x, CONF_CR0) @@ -77,53 +77,54 @@ #define TI_TMP108_CONF_M1(x) TI_TMP108_GET_CONF(x, CONF_M1) #define TI_TMP108_CONF_M0(x) TI_TMP108_GET_CONF(x, CONF_M0) +#define TI_TMP108_CONF_SLEEP(x) TI_TMP108_GET_CONF(x, CONF_SLEEP) #define TMP108_TEMP_MULTIPLIER(x) TI_TMP108_GET_CONF(x, TEMP_MULT) #define TMP108_TEMP_DIVISOR(x) TI_TMP108_GET_CONF(x, TEMP_DIV) -#define TMP108_WAKEUP_TIME_IN_MS(x) TI_TMP108_GET_CONF(x, WAKEUP_TIME_IN_MS) #define TMP108_CONF_RST(x) TI_TMP108_GET_CONF(x, CONF_RST) #define TI_TMP108_CONF_NA 0x0000 struct tmp_108_reg_def { - uint16_t CONF_M0; /** Mode 1 configuration bit */ - uint16_t CONF_M1; /** Mode 2 configuration bit */ - uint16_t CONF_CR0; /** Conversion rate 1 configuration bit */ - uint16_t CONF_CR1; /** Conversion rate 2 configuration bit */ - uint16_t CONF_POL; /** Alert pin Polarity configuration bit */ - uint16_t CONF_TM; /** Thermostat mode setting bit */ - uint16_t CONF_HYS1; /** Temperature hysteresis config 1 bit */ - uint16_t CONF_HYS0; /** Temperature hysteresis config 2 bit */ - int32_t TEMP_MULT; /** Temperature multiplier */ - int32_t TEMP_DIV; /** Temperature divisor */ - uint16_t WAKEUP_TIME_IN_MS; /** Wake up and conversion time from one shot */ - uint16_t CONF_RST; /** default reset values on init */ + uint16_t CONF_M0; /** Mode 1 configuration bit */ + uint16_t CONF_M1; /** Mode 2 configuration bit */ + uint16_t CONF_SLEEP; /** Sleep mode configuration bit */ + uint16_t CONF_CR0; /** Conversion rate 1 configuration bit */ + uint16_t CONF_CR1; /** Conversion rate 2 configuration bit */ + uint16_t CONF_TM; /** Thermostat mode setting bit */ + int32_t TEMP_MULT; /** Temperature multiplier */ + int32_t TEMP_DIV; /** Temperature divisor */ + uint16_t CONF_RST; /** default reset values on init */ +#ifdef CONFIG_TMP108_ALERT_INTERRUPTS + uint16_t CONF_POL; /** Alert pin Polarity configuration bit */ + uint16_t CONF_HYS1; /** Temperature hysteresis config 1 bit */ + uint16_t CONF_HYS0; /** Temperature hysteresis config 2 bit */ +#endif }; #define TI_TMP108_GET_CONF(x, cfg) ((struct tmp108_config *)(x->config))->reg_def.cfg struct tmp108_config { const struct i2c_dt_spec i2c_spec; - const struct gpio_dt_spec alert_gpio; struct tmp_108_reg_def reg_def; +#ifdef CONFIG_TMP108_ALERT_INTERRUPTS + const struct gpio_dt_spec alert_gpio; +#endif /* CONFIG_TMP108_ALERT_INTERRUPTS */ }; struct tmp108_data { - const struct device *tmp108_dev; - int16_t sample; bool one_shot_mode; - struct k_work_delayable scheduled_work; +#ifdef CONFIG_TMP108_ALERT_INTERRUPTS + const struct device *tmp108_dev; const struct sensor_trigger *temp_alert_trigger; sensor_trigger_handler_t temp_alert_handler; - sensor_trigger_handler_t data_ready_handler; - const struct sensor_trigger *data_ready_trigger; - struct gpio_callback temp_alert_gpio_cb; +#endif /* CONFIG_TMP108_ALERT_INTERRUPTS */ }; int tmp_108_trigger_set(const struct device *dev, diff --git a/drivers/sensor/ti/tmp108/tmp108_trigger.c b/drivers/sensor/ti/tmp108/tmp108_trigger.c index feb587bec467e..9ef840f9d920d 100644 --- a/drivers/sensor/ti/tmp108/tmp108_trigger.c +++ b/drivers/sensor/ti/tmp108/tmp108_trigger.c @@ -10,46 +10,8 @@ #include "tmp108.h" -#define TMP108_ONE_SHOT_RETRY_TIME_IN_MS 10 - LOG_MODULE_DECLARE(TMP108, CONFIG_SENSOR_LOG_LEVEL); -void tmp108_trigger_handle_one_shot(struct k_work *work) -{ - struct k_work_delayable *delayable_work = k_work_delayable_from_work(work); - struct tmp108_data *drv_data = CONTAINER_OF(delayable_work, - struct tmp108_data, - scheduled_work); - - uint16_t config = 0; - bool shutdown_mode = false; - - tmp108_reg_read(drv_data->tmp108_dev, TI_TMP108_REG_CONF, &config); - - /* check shutdown mode which indicates a one shot read was successful */ - shutdown_mode = (config & (TI_TMP108_CONF_M1(drv_data->tmp108_dev) | - TI_TMP108_CONF_M0(drv_data->tmp108_dev))) == 0; - - if (shutdown_mode == true) { - ti_tmp108_read_temp(drv_data->tmp108_dev); - } else { - LOG_ERR("Temperature one shot mode read failed, retrying"); - /* Wait for typical wake up time, retry if the read fails - * assuming the chip should wake up and take a reading after the typical - * wake up time and call of this thread plus 10 ms time has passed - */ - k_work_reschedule(&drv_data->scheduled_work, - K_MSEC(TMP108_ONE_SHOT_RETRY_TIME_IN_MS)); - return; - } - - /* Successful read, call set callbacks */ - if (drv_data->data_ready_handler) { - drv_data->data_ready_handler(drv_data->tmp108_dev, - drv_data->data_ready_trigger); - } -} - void tmp108_trigger_handle_alert(const struct device *gpio, struct gpio_callback *cb, gpio_port_pins_t pins) @@ -72,12 +34,6 @@ int tmp_108_trigger_set(const struct device *dev, { struct tmp108_data *drv_data = dev->data; - if (trig->type == SENSOR_TRIG_DATA_READY) { - drv_data->data_ready_handler = handler; - drv_data->data_ready_trigger = trig; - return 0; - } - if (trig->type == SENSOR_TRIG_THRESHOLD) { drv_data->temp_alert_handler = handler; drv_data->temp_alert_trigger = trig; diff --git a/drivers/sensor/ti/tmp116/tmp116.c b/drivers/sensor/ti/tmp116/tmp116.c index 977d010a28f2e..26a7f8383ea5e 100644 --- a/drivers/sensor/ti/tmp116/tmp116.c +++ b/drivers/sensor/ti/tmp116/tmp116.c @@ -398,6 +398,11 @@ static int tmp116_init(const struct device *dev) drv_data->id = id; rc = tmp116_write_config(dev, TMP116_CFGR_CONV, cfg->odr); + if (rc < 0) { + return rc; + } + + rc = tmp116_write_config(dev, TMP116_CFGR_AVG, cfg->oversampling); return rc; } @@ -407,6 +412,7 @@ static int tmp116_init(const struct device *dev) static const struct tmp116_dev_config tmp116_config_##_num = { \ .bus = I2C_DT_SPEC_INST_GET(_num), \ .odr = DT_INST_PROP(_num, odr), \ + .oversampling = DT_INST_PROP(_num, oversampling), \ }; \ SENSOR_DEVICE_DT_INST_DEFINE(_num, tmp116_init, NULL, \ &tmp116_data_##_num, &tmp116_config_##_num, POST_KERNEL, \ diff --git a/drivers/sensor/ti/tmp116/tmp116.h b/drivers/sensor/ti/tmp116/tmp116.h index 6211d9a71f14d..fc57feb055279 100644 --- a/drivers/sensor/ti/tmp116/tmp116.h +++ b/drivers/sensor/ti/tmp116/tmp116.h @@ -50,6 +50,7 @@ struct tmp116_data { struct tmp116_dev_config { struct i2c_dt_spec bus; uint16_t odr; + uint16_t oversampling; }; #endif /* ZEPHYR_DRIVERS_SENSOR_TMP116_TMP116_H_ */ diff --git a/drivers/sensor/ti/tmp435/CMakeLists.txt b/drivers/sensor/ti/tmp435/CMakeLists.txt new file mode 100644 index 0000000000000..c84b5c9544596 --- /dev/null +++ b/drivers/sensor/ti/tmp435/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Bittium Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_library() + +zephyr_library_sources(tmp435.c) diff --git a/drivers/sensor/ti/tmp435/Kconfig b/drivers/sensor/ti/tmp435/Kconfig new file mode 100644 index 0000000000000..dfbd455fcc5e7 --- /dev/null +++ b/drivers/sensor/ti/tmp435/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Bittium Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +config TMP435 + bool "TMP435 temperature sensor" + default y + depends on DT_HAS_TI_TMP435_ENABLED + select I2C + help + Enable the driver for the TMP435 temperature sensor diff --git a/drivers/sensor/ti/tmp435/tmp435.c b/drivers/sensor/ti/tmp435/tmp435.c new file mode 100644 index 0000000000000..d1c27f83cd7e4 --- /dev/null +++ b/drivers/sensor/ti/tmp435/tmp435.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2024 Bittium Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_tmp435 + +#include +#include + +#include +#include +#include +#include +#include +#include "tmp435.h" + +LOG_MODULE_REGISTER(TMP435, CONFIG_SENSOR_LOG_LEVEL); + +static inline int tmp435_reg_read(const struct tmp435_config *cfg, uint8_t reg, uint8_t *buf, + uint32_t size) +{ + return i2c_burst_read_dt(&cfg->i2c, reg, buf, size); +} + +static inline int tmp435_reg_write(const struct tmp435_config *cfg, uint8_t reg, uint8_t *buf, + uint32_t size) +{ + return i2c_burst_write_dt(&cfg->i2c, reg, buf, size); +} + +static inline int tmp435_get_status(const struct tmp435_config *cfg, uint8_t *status) +{ + return tmp435_reg_read(cfg, TMP435_STATUS_REG, status, 1); +} + +static int tmp435_one_shot(const struct device *dev) +{ + uint8_t data = 0; + uint8_t status = 0; + int ret = 0; + const struct tmp435_config *cfg = dev->config; + + data = 1; /* write anything to start */ + ret = tmp435_reg_write(cfg, TMP435_ONE_SHOT_START_REG, &data, 1); + for (uint16_t i = 0; i < TMP435_CONV_LOOP_LIMIT; i++) { + ret = tmp435_get_status(cfg, &status); + if (ret < 0) { + LOG_DBG("Failed to read TMP435_STATUS_REG, ret:%d", ret); + } else { + if (status & TMP435_STATUS_REG_BUSY) { + /* conversion not ready */ + k_msleep(10); + } else { + LOG_DBG("conv over, loops:%d status:%x", i, status); + break; + } + } + } + return ret; +} + +static int tmp435_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + int ret = 0; + uint8_t value = 0; + int32_t temp = 0; + const struct tmp435_config *cfg = dev->config; + struct tmp435_data *data = dev->data; + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP && + chan != SENSOR_CHAN_AMBIENT_TEMP) { + return -ENOTSUP; + } + tmp435_one_shot(dev); /* start conversion */ + if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_DIE_TEMP)) { + ret = tmp435_reg_read(cfg, TMP435_LOCAL_TEMP_H_REG, &value, sizeof(value)); + if (ret < 0) { + LOG_ERR("Failed to read TMP435_LOCAL_TEMP_H_REG, ret:%d", ret); + return ret; + } + temp = value; + ret = tmp435_reg_read(cfg, TMP435_LOCAL_TEMP_L_REG, &value, sizeof(value)); + if (ret < 0) { + LOG_ERR("Failed to read TMP435_LOCAL_TEMP_L_REG, ret:%d", ret); + return ret; + } + if (value > TMP435_FRACTION_INC) { + temp++; + } + data->temp_die = temp + tmp435_temp_offset; + } + + if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_AMBIENT_TEMP)) { + if (!(cfg->external_channel)) { + return 0; /* not enabled, just return */ + } + ret = tmp435_reg_read(cfg, TMP435_REMOTE_TEMP_H_REG, &value, sizeof(value)); + if (ret < 0) { + LOG_ERR("Failed to read TMP435_REMOTE_TEMP_H_REG ret:%d", ret); + return ret; + } + temp = value; + ret = tmp435_reg_read(cfg, TMP435_REMOTE_TEMP_L_REG, &value, sizeof(value)); + if (ret < 0) { + LOG_ERR("Failed to read TMP435_REMOTE_TEMP_L_REG, ret:%d", ret); + return ret; + } + if (value > TMP435_FRACTION_INC) { + temp++; + } + data->temp_ambient = temp + tmp435_temp_offset; + } + return 0; +} + +static int tmp435_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + int ret = 0; + struct tmp435_data *data = dev->data; + const struct tmp435_config *cfg = dev->config; + + switch (chan) { + + case SENSOR_CHAN_DIE_TEMP: + val->val1 = data->temp_die; + val->val2 = 0; + break; + case SENSOR_CHAN_AMBIENT_TEMP: + if (cfg->external_channel) { + val->val1 = data->temp_ambient; + val->val2 = 0; + } else { + ret = -ENOTSUP; + } + break; + default: + ret = -ENOTSUP; + break; + } + return ret; +} + +static DEVICE_API(sensor, tmp435_driver_api) = { + .sample_fetch = tmp435_sample_fetch, + .channel_get = tmp435_channel_get, +}; + +static int tmp435_init(const struct device *dev) +{ + uint8_t data = 0; + int ret = 0; + const struct tmp435_config *cfg = dev->config; + + if (!(i2c_is_ready_dt(&cfg->i2c))) { + LOG_ERR("I2C dev not ready"); + return -ENODEV; + } + + data = 1; /* write anything to reset */ + ret = tmp435_reg_write(cfg, TMP435_SOFTWARE_RESET_REG, &data, 1); + if (ret < 0) { + LOG_ERR("Failed to write TMP435_SOFTWARE_RESET_REG ret:%d", ret); + return ret; + } + + data = TMP435_CONF_REG_1_DATA; + ret = tmp435_reg_write(cfg, TMP435_CONF_REG_1, &data, 1); + if (ret < 0) { + LOG_ERR("Failed to write TMP435_CONF_REG_1 ret:%d", ret); + return ret; + } + + data = TMP435_CONF_REG_2_DATA; + if (cfg->external_channel) { + data = data + TMP435_CONF_REG_2_REN; + } + if (cfg->resistance_correction) { + data = data + TMP435_CONF_REG_2_RC; + } + ret = tmp435_reg_write(cfg, TMP435_CONF_REG_2, &data, 1); + if (ret < 0) { + LOG_ERR("Failed to write TMP435_CONF_REG_2 ret:%d", ret); + return ret; + } + + data = cfg->beta_compensation; + ret = tmp435_reg_write(cfg, TMP435_BETA_RANGE_REG, &data, 1); + if (ret < 0) { + LOG_ERR("Failed to write TMP435_BETA_RANGE_REG ret:%d", ret); + return ret; + } + return 0; +} + +/* + * Device creation macros + */ + +#define TMP435_INST(inst) \ + static struct tmp435_data tmp435_data_##inst; \ + static const struct tmp435_config tmp435_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .external_channel = DT_INST_PROP(inst, external_channel), \ + .resistance_correction = DT_INST_PROP(inst, resistance_correction), \ + .beta_compensation = DT_INST_PROP(inst, beta_compensation), \ + }; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, tmp435_init, NULL, &tmp435_data_##inst, \ + &tmp435_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &tmp435_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(TMP435_INST) diff --git a/drivers/sensor/ti/tmp435/tmp435.h b/drivers/sensor/ti/tmp435/tmp435.h new file mode 100644 index 0000000000000..f138e15f37bf9 --- /dev/null +++ b/drivers/sensor/ti/tmp435/tmp435.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Bittium Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_TMP435_H_ +#define ZEPHYR_DRIVERS_SENSOR_TMP435_H_ + +#define TMP435_CONF_REG_1 0x03 +#define TMP435_CONF_REG_1_DATA 0xc4 +/* [7]=1 ALERT Masked, [6]=1 Shut Down (one shot mode), [2]=1 −55 C to +150 C */ +#define TMP435_CONF_REG_2 0x1a +#define TMP435_CONF_REG_2_REN 0x10 /* [4]=1 External channel 1 enabled */ +#define TMP435_CONF_REG_2_RC 0x04 /* [2]=1 Resistance correction enabled */ +#define TMP435_CONF_REG_2_DATA 0x08 /* [3]=1 Local channel enabled */ +#define TMP435_BETA_RANGE_REG 0x25 +#define TMP435_STATUS_REG 0x02 +#define TMP435_STATUS_REG_BUSY 0x80 /* conv not ready */ +#define TMP435_SOFTWARE_RESET_REG 0xfc +#define TMP435_ONE_SHOT_START_REG 0x0f +#define TMP435_LOCAL_TEMP_H_REG 0x00 +#define TMP435_LOCAL_TEMP_L_REG 0x15 +#define TMP435_REMOTE_TEMP_H_REG 0x01 +#define TMP435_REMOTE_TEMP_L_REG 0x10 + +#define TMP435_CONV_LOOP_LIMIT 50 /* max 50*10 ms */ +#define TMP435_FRACTION_INC 0x80 /* 0.5000 */ + +static const int32_t tmp435_temp_offset = -64; + +struct tmp435_data { + int32_t temp_die; /* Celsius degrees */ + int32_t temp_ambient; /* Celsius degrees */ +}; + +struct tmp435_config { + struct i2c_dt_spec i2c; + bool external_channel; + bool resistance_correction; + uint8_t beta_compensation; +}; + +#endif /* ZEPHYR_DRIVERS_SENSOR_TMP435_H_ */ diff --git a/drivers/sensor/vishay/vcnl4040/vcnl4040.c b/drivers/sensor/vishay/vcnl4040/vcnl4040.c index 73690f520ed81..03f0d1e4e45e0 100644 --- a/drivers/sensor/vishay/vcnl4040/vcnl4040.c +++ b/drivers/sensor/vishay/vcnl4040/vcnl4040.c @@ -136,21 +136,21 @@ static int vcnl4040_reg_setup(const struct device *dev) /* * scale the lux depending on the value of the integration time - * see page 8 of the VCNL4040 application note: - * https://www.vishay.com/docs/84307/designingvcnl4040.pdf + * see page 12 of the VCNL4040 application note: + * https://www.vishay.com/docs/84274/vcnl4040.pdf */ switch (config->als_it) { case VCNL4040_AMBIENT_INTEGRATION_TIME_80MS: - data->sensitivity = 0.12; + data->sensitivity = 0.1; break; case VCNL4040_AMBIENT_INTEGRATION_TIME_160MS: - data->sensitivity = 0.06; + data->sensitivity = 0.05; break; case VCNL4040_AMBIENT_INTEGRATION_TIME_320MS: - data->sensitivity = 0.03; + data->sensitivity = 0.025; break; case VCNL4040_AMBIENT_INTEGRATION_TIME_640MS: - data->sensitivity = 0.015; + data->sensitivity = 0.0125; break; default: data->sensitivity = 1.0; diff --git a/drivers/sensor/voltage_divider/voltage.c b/drivers/sensor/voltage_divider/voltage.c index 090c879a54c91..97d2523bd775e 100644 --- a/drivers/sensor/voltage_divider/voltage.c +++ b/drivers/sensor/voltage_divider/voltage.c @@ -40,6 +40,14 @@ static int fetch(const struct device *dev, enum sensor_channel chan) /* Wait until sampling is valid */ k_sleep(data->earliest_sample); + /* configure the active channel to be converted */ + ret = adc_channel_setup_dt(&config->voltage.port); + if (ret != 0) { + LOG_ERR("adc_setup failed: %d", ret); + return ret; + } + + /* start conversion */ ret = adc_read(config->voltage.port.dev, &data->sequence); if (ret != 0) { LOG_ERR("adc_read: %d", ret); diff --git a/drivers/sensor/wsen/CMakeLists.txt b/drivers/sensor/wsen/CMakeLists.txt index fc72c7754bd49..035878a3ad04d 100644 --- a/drivers/sensor/wsen/CMakeLists.txt +++ b/drivers/sensor/wsen/CMakeLists.txt @@ -4,4 +4,7 @@ # zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_WSEN_HIDS_2525020210002 wsen_hids_2525020210002) +add_subdirectory_ifdef(CONFIG_WSEN_PADS_2511020213301 wsen_pads_2511020213301) +add_subdirectory_ifdef(CONFIG_WSEN_PDUS_25131308XXXXX wsen_pdus_25131308XXXXX) +add_subdirectory_ifdef(CONFIG_WSEN_TIDS_2521020222501 wsen_tids_2521020222501) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/wsen/Kconfig b/drivers/sensor/wsen/Kconfig index 39d727f9f4fca..4f7ebd9c3beab 100644 --- a/drivers/sensor/wsen/Kconfig +++ b/drivers/sensor/wsen/Kconfig @@ -4,4 +4,7 @@ # zephyr-keep-sorted-start source "drivers/sensor/wsen/wsen_hids_2525020210002/Kconfig" +source "drivers/sensor/wsen/wsen_pads_2511020213301/Kconfig" +source "drivers/sensor/wsen/wsen_pdus_25131308XXXXX/Kconfig" +source "drivers/sensor/wsen/wsen_tids_2521020222501/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/wsen/wsen_pads_2511020213301/CMakeLists.txt b/drivers/sensor/wsen/wsen_pads_2511020213301/CMakeLists.txt new file mode 100644 index 0000000000000..60c9fbf828626 --- /dev/null +++ b/drivers/sensor/wsen/wsen_pads_2511020213301/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(wsen_pads_2511020213301.c) +zephyr_library_sources_ifdef(CONFIG_WSEN_PADS_2511020213301_TRIGGER wsen_pads_2511020213301_trigger.c) diff --git a/drivers/sensor/wsen/wsen_pads_2511020213301/Kconfig b/drivers/sensor/wsen/wsen_pads_2511020213301/Kconfig new file mode 100644 index 0000000000000..489e261edf33d --- /dev/null +++ b/drivers/sensor/wsen/wsen_pads_2511020213301/Kconfig @@ -0,0 +1,62 @@ +# Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +menuconfig WSEN_PADS_2511020213301 + bool "WSEN-PADS-2511020213301 absolute pressure and temperature sensor" + default y + depends on DT_HAS_WE_WSEN_PADS_2511020213301_ENABLED + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_WE_WSEN_PADS),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_WE_WSEN_PADS),spi) + select HAS_WESENSORS + help + Enable driver for the WSEN-PADS-2511020213301 I2C/SPI-based absolute pressure sensor with integrated + temperature sensor. + +if WSEN_PADS_2511020213301 + +choice WSEN_PADS_2511020213301_TRIGGER_MODE + prompt "Trigger mode" + default WSEN_PADS_2511020213301_TRIGGER_NONE + help + Specify the type of triggering to be used by the driver. + +config WSEN_PADS_2511020213301_TRIGGER_NONE + bool "No trigger" + +config WSEN_PADS_2511020213301_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on GPIO + select WSEN_PADS_2511020213301_TRIGGER + +config WSEN_PADS_2511020213301_TRIGGER_OWN_THREAD + bool "Use own thread" + depends on GPIO + select WSEN_PADS_2511020213301_TRIGGER + +endchoice # WSEN_PADS_2511020213301_TRIGGER_MODE + +config WSEN_PADS_2511020213301_TRIGGER + bool + +config WSEN_PADS_2511020213301_THREAD_PRIORITY + int "Thread priority" + depends on WSEN_PADS_2511020213301_TRIGGER_OWN_THREAD + default 10 + help + Priority of thread used by the driver to handle interrupts. + +config WSEN_PADS_2511020213301_THREAD_STACK_SIZE + int "Thread stack size" + depends on WSEN_PADS_2511020213301_TRIGGER_OWN_THREAD + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + +config WSEN_PADS_2511020213301_PRESSURE_THRESHOLD + bool "Pressure threshold triggers" + depends on WSEN_PADS_2511020213301_TRIGGER + help + Allows you to set up triggers for high and/or low pressure thresholds. + if activated then data ready trigger can't be set up. + +endif # WSEN_PADS_2511020213301 diff --git a/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301.c b/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301.c new file mode 100644 index 0000000000000..996773c04dd95 --- /dev/null +++ b/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301.c @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT we_wsen_pads_2511020213301 + +#include + +#include +#include +#include + +#include "wsen_pads_2511020213301.h" + +LOG_MODULE_REGISTER(WSEN_PADS_2511020213301, CONFIG_SENSOR_LOG_LEVEL); + +/* + * List of supported output data rates. Index into this list is used as + * argument for PADS_setOutputDataRate() + */ +static const int32_t pads_2511020213301_odr_list[] = { + 0, 1, 10, 25, 50, 75, 100, 200, +}; + +#define SAMPLES_TO_DISCARD (uint8_t)2 + +#define MAX_POLL_STEP_COUNT 10 + +static int pads_2511020213301_sample_fetch(const struct device *dev, enum sensor_channel channel) +{ + struct pads_2511020213301_data *data = dev->data; + const struct pads_2511020213301_config *cfg = dev->config; + + switch (channel) { + case SENSOR_CHAN_ALL: + case SENSOR_CHAN_AMBIENT_TEMP: + case SENSOR_CHAN_PRESS: + break; + default: + LOG_ERR("Fetching is not supported on channel %d.", channel); + return -ENOTSUP; + } + + if (data->sensor_odr == PADS_outputDataRatePowerDown) { + if (PADS_enableOneShot(&data->sensor_interface, PADS_enable) != WE_SUCCESS) { + LOG_ERR("Failed to fetch %s sample.", "pressure"); + return -EIO; + } + + switch (cfg->configuration) { + case PADS_lowPower: + k_sleep(K_USEC(4700)); + break; + case PADS_lowNoise: + k_sleep(K_USEC(13200)); + break; + default: + LOG_ERR("Invalid sensor configuration"); + return -EIO; + } + + PADS_state_t one_shot_state; + + do { + if (PADS_isOneShotEnabled(&data->sensor_interface, &one_shot_state) != + WE_SUCCESS) { + LOG_ERR("Failed to check for data ready"); + return -EIO; + } + } while (PADS_enable == one_shot_state); + } else { + + bool data_ready = false; + int step_count = 0; + uint32_t step_sleep_duration = + ((uint32_t)1000000000 / + (pads_2511020213301_odr_list[data->sensor_odr] * 1000)) / + MAX_POLL_STEP_COUNT; + + while (1) { + PADS_state_t pressure_state, temp_state; + + pressure_state = temp_state = PADS_disable; + + if (PADS_isDataAvailable(&data->sensor_interface, &temp_state, + &pressure_state) != WE_SUCCESS) { + LOG_ERR("Failed to check for data available"); + return -EIO; + } + + switch (channel) { + case SENSOR_CHAN_ALL: + data_ready = (pressure_state == PADS_enable && + temp_state == PADS_enable); + break; + case SENSOR_CHAN_AMBIENT_TEMP: + data_ready = (temp_state == PADS_enable); + break; + case SENSOR_CHAN_PRESS: + data_ready = (pressure_state == PADS_enable); + break; + default: + break; + } + + if (data_ready) { + break; + } else if (step_count >= MAX_POLL_STEP_COUNT) { + return -EIO; + } + + step_count++; + k_sleep(K_USEC(step_sleep_duration)); + } + } + + switch (channel) { + case SENSOR_CHAN_ALL: { + + if (PADS_getPressure_int(&data->sensor_interface, &data->pressure) != WE_SUCCESS) { + LOG_ERR("Failed to fetch %s sample.", "pressure"); + return -EIO; + } + + if (PADS_getTemperature_int(&data->sensor_interface, &data->temperature) != + WE_SUCCESS) { + LOG_ERR("Failed to fetch %s sample.", "temperature"); + return -EIO; + } + + break; + } + case SENSOR_CHAN_AMBIENT_TEMP: { + + if (PADS_getTemperature_int(&data->sensor_interface, &data->temperature) != + WE_SUCCESS) { + LOG_ERR("Failed to fetch %s sample.", "temperature"); + return -EIO; + } + + break; + } + case SENSOR_CHAN_PRESS: { + + if (PADS_getPressure_int(&data->sensor_interface, &data->pressure) != WE_SUCCESS) { + LOG_ERR("Failed to fetch %s sample.", "pressure"); + return -EIO; + } + + break; + } + default: + break; + } + + return 0; +} + +static int pads_2511020213301_channel_get(const struct device *dev, enum sensor_channel channel, + struct sensor_value *value) +{ + struct pads_2511020213301_data *data = dev->data; + + switch (channel) { + case SENSOR_CHAN_AMBIENT_TEMP: + /* Convert temperature from 0.01 degrees Celsius to degrees Celsius */ + value->val1 = data->temperature / 100; + value->val2 = ((int32_t)data->temperature % 100) * (1000000 / 100); + break; + case SENSOR_CHAN_PRESS: + /* Convert pressure from Pa to kPa */ + value->val1 = data->pressure / 1000; + value->val2 = ((int32_t)data->pressure % 1000) * (1000000 / 1000); + break; + default: + LOG_ERR("Channel not supported %d", channel); + return -ENOTSUP; + } + + return 0; +} + +/* Set output data rate. See pads_2511020213301_odr_list for allowed values. */ +static int pads_2511020213301_odr_set(const struct device *dev, const struct sensor_value *odr) +{ + struct pads_2511020213301_data *data = dev->data; + const struct pads_2511020213301_config *cfg = dev->config; + int odr_index; + + for (odr_index = 0; odr_index < ARRAY_SIZE(pads_2511020213301_odr_list); odr_index++) { + if (odr->val1 == pads_2511020213301_odr_list[odr_index] && odr->val2 == 0) { + break; + } + } + + if (odr_index == ARRAY_SIZE(pads_2511020213301_odr_list)) { + /* ODR not allowed (was not found in pads_2511020213301_odr_list) */ + LOG_ERR("Bad sampling frequency %d.%d", odr->val1, odr->val2); + return -EINVAL; + } + + if (cfg->configuration == PADS_lowNoise && + (PADS_outputDataRate_t)odr_index > PADS_outputDataRate75Hz) { + LOG_ERR("Failed to set ODR > 75Hz is not possible with low noise sensor " + "configuration."); + return -EIO; + } + + if (PADS_setOutputDataRate(&data->sensor_interface, (PADS_outputDataRate_t)odr_index) != + WE_SUCCESS) { + LOG_ERR("Failed to set output data rate"); + return -EIO; + } + + if (PADS_enableBlockDataUpdate(&data->sensor_interface, + (PADS_outputDataRate_t)odr_index != + PADS_outputDataRatePowerDown + ? PADS_enable + : PADS_disable) != WE_SUCCESS) { + LOG_ERR("Failed to enable block data update."); + return -EIO; + } + + data->sensor_odr = (PADS_outputDataRate_t)odr_index; + + return 0; +} + +/* Get output data rate. */ +static int pads_2511020213301_odr_get(const struct device *dev, struct sensor_value *odr) +{ + + struct pads_2511020213301_data *data = dev->data; + + PADS_outputDataRate_t odr_index; + + if (PADS_getOutputDataRate(&data->sensor_interface, &odr_index) != WE_SUCCESS) { + LOG_ERR("Failed to get output data rate"); + return -EIO; + } + + data->sensor_odr = odr_index; + + odr->val1 = pads_2511020213301_odr_list[odr_index]; + odr->val2 = 0; + + return 0; +} + +static int pads_2511020213301_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + + if (val == NULL) { + LOG_WRN("address of passed value is NULL."); + return -EFAULT; + } + + switch ((int)attr) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: + if (chan != SENSOR_CHAN_ALL) { + LOG_ERR("attr_get() is not supported on channel %d.", chan); + return -ENOTSUP; + } + return pads_2511020213301_odr_get(dev, val); +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD + case SENSOR_ATTR_WSEN_PADS_2511020213301_REFERENCE_POINT: + if (chan != SENSOR_CHAN_PRESS) { + LOG_ERR("attr_get() is not supported on channel %d.", chan); + return -ENOTSUP; + } + return pads_2511020213301_reference_point_get(dev, val); + case SENSOR_ATTR_UPPER_THRESH: + case SENSOR_ATTR_LOWER_THRESH: + if (chan != SENSOR_CHAN_PRESS) { + LOG_ERR("attr_get() is not supported on channel %d.", chan); + return -ENOTSUP; + } + return pads_2511020213301_threshold_get(dev, val); +#endif + default: + LOG_ERR("Operation not supported."); + return -ENOTSUP; + } + + return 0; +} + +static int pads_2511020213301_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + switch ((int)attr) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: + if (chan != SENSOR_CHAN_ALL) { + LOG_ERR("attr_set() is not supported on channel %d.", chan); + return -ENOTSUP; + } + return pads_2511020213301_odr_set(dev, val); +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD + case SENSOR_ATTR_WSEN_PADS_2511020213301_REFERENCE_POINT: + if (chan != SENSOR_CHAN_PRESS) { + LOG_ERR("attr_set() is not supported on channel %d.", chan); + return -ENOTSUP; + } + return pads_2511020213301_reference_point_set(dev, val); + case SENSOR_ATTR_UPPER_THRESH: + case SENSOR_ATTR_LOWER_THRESH: + if (chan != SENSOR_CHAN_PRESS) { + LOG_ERR("attr_set() is not supported on channel %d.", chan); + return -ENOTSUP; + } + return pads_2511020213301_threshold_set(dev, val); +#endif + default: + LOG_ERR("Operation not supported."); + return -ENOTSUP; + } +} + +static DEVICE_API(sensor, pads_2511020213301_driver_api) = { + .attr_set = pads_2511020213301_attr_set, +#if CONFIG_WSEN_PADS_2511020213301_TRIGGER + .trigger_set = pads_2511020213301_trigger_set, +#endif + .attr_get = pads_2511020213301_attr_get, + .sample_fetch = pads_2511020213301_sample_fetch, + .channel_get = pads_2511020213301_channel_get, +}; + +static int pads_2511020213301_init(const struct device *dev) +{ + const struct pads_2511020213301_config *config = dev->config; + struct pads_2511020213301_data *data = dev->data; + struct sensor_value odr; + uint8_t device_id; + + /* Initialize WE sensor interface */ + WE_sensorInterfaceType_t interface_type = data->sensor_interface.interfaceType; + + PADS_getDefaultInterface(&data->sensor_interface); + data->sensor_interface.interfaceType = interface_type; + + switch (data->sensor_interface.interfaceType) { +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) + case WE_i2c: + if (!i2c_is_ready_dt(&config->bus_cfg.i2c)) { + LOG_ERR("I2C bus device not ready"); + return -ENODEV; + } + data->sensor_interface.handle = (void *)&config->bus_cfg.i2c; + break; +#endif +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) + case WE_spi: + if (!spi_is_ready_dt(&config->bus_cfg.spi)) { + LOG_ERR("SPI bus device not ready"); + return -ENODEV; + } + data->sensor_interface.handle = (void *)&config->bus_cfg.spi; + break; +#endif + default: + LOG_ERR("Invalid interface type"); + return -EINVAL; + } + + /* needed after power up */ + k_sleep(K_USEC(4500)); + + PADS_state_t boot_state = PADS_enable; + + do { + if (PADS_getBootStatus(&data->sensor_interface, &boot_state) != WE_SUCCESS) { + LOG_ERR("Failed to get sensor reset state."); + return -EIO; + } + } while (PADS_enable == boot_state); + + /* First communication test - check device ID */ + if (PADS_getDeviceID(&data->sensor_interface, &device_id) != WE_SUCCESS) { + LOG_ERR("Failed to read device ID."); + return -EIO; + } + + if (device_id != PADS_DEVICE_ID_VALUE) { + LOG_ERR("Invalid device ID 0x%x.", device_id); + return -EINVAL; + } + + /* Reset sensor */ + PADS_softReset(&data->sensor_interface, PADS_enable); + k_sleep(K_USEC(50)); + + PADS_state_t sw_reset; + + do { + if (PADS_getSoftResetState(&data->sensor_interface, &sw_reset) != WE_SUCCESS) { + LOG_ERR("Failed to get sensor reset state."); + return -EIO; + } + } while (PADS_enable == sw_reset); + + if (PADS_setPowerMode(&data->sensor_interface, config->configuration) != WE_SUCCESS) { + LOG_ERR("Failed to set sensor configuration."); + return -EIO; + } + + odr.val1 = pads_2511020213301_odr_list[config->odr]; + odr.val2 = 0; + + if (pads_2511020213301_odr_set(dev, &odr) < 0) { + LOG_ERR("Failed to set output data rate."); + return -EIO; + } + + if (PADS_enableLowPassFilter(&data->sensor_interface, config->alpf) != WE_SUCCESS) { + LOG_ERR("Failed to set additional low pass filter."); + return -EIO; + } + + if (config->alpf == PADS_enable) { + if (PADS_setLowPassFilterConfig(&data->sensor_interface, + config->alpf_configuration) != WE_SUCCESS) { + LOG_ERR("Failed to set additional low pass filter configuration."); + return -EIO; + } + + for (uint8_t i = 0; i < SAMPLES_TO_DISCARD; i++) { + pads_2511020213301_sample_fetch(dev, SENSOR_CHAN_ALL); + } + + data->pressure = 0; + data->temperature = 0; + } + +#if CONFIG_WSEN_PADS_2511020213301_TRIGGER + if (pads_2511020213301_init_interrupt(dev) < 0) { + LOG_ERR("Failed to initialize interrupt."); + return -EIO; + } +#endif + + return 0; +} + +#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0 +#warning "PADS driver enabled without any devices" +#endif + +#ifdef CONFIG_WSEN_PADS_2511020213301_TRIGGER +#define PADS_2511020213301_CFG_IRQ(inst) \ + .interrupt_gpio = GPIO_DT_SPEC_INST_GET(inst, interrupt_gpios) +#else +#define PADS_2511020213301_CFG_IRQ(inst) +#endif /* CONFIG_WSEN_PADS_2511020213301_TRIGGER */ + +#define PADS_2511020213301_CFG_ALPF(inst) \ + .alpf = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, additional_low_pass_filter), \ + (PADS_enable), (PADS_disable)) + +#define PADS_2511020213301_CONFIG_COMMON(inst) \ + .odr = (PADS_outputDataRate_t)(DT_INST_ENUM_IDX(inst, odr)), \ + .configuration = (PADS_powerMode_t)(DT_INST_ENUM_IDX(inst, configuration)), \ + .alpf_configuration = \ + (PADS_filterConf_t)DT_INST_PROP(inst, additional_low_pass_filter_configuration), \ + PADS_2511020213301_CFG_ALPF(inst), \ + IF_ENABLED(CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD, \ + (.threshold = (uint16_t)DT_INST_PROP_OR(inst, threshold, 0),)) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, interrupt_gpios), \ + (PADS_2511020213301_CFG_IRQ(inst)), ()) + +/* + * Instantiation macros used when device is on SPI bus. + */ + +#define PADS_2511020213301_SPI_OPERATION \ + (SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA) + +#define PADS_2511020213301_CONFIG_SPI(inst) \ + {.bus_cfg = \ + { \ + .spi = SPI_DT_SPEC_INST_GET(inst, PADS_2511020213301_SPI_OPERATION, 0), \ + }, \ + PADS_2511020213301_CONFIG_COMMON(inst)} + +/* + * Instantiation macros used when device is on I2C bus. + */ + +#define PADS_2511020213301_CONFIG_I2C(inst) \ + {.bus_cfg = \ + { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }, \ + PADS_2511020213301_CONFIG_COMMON(inst)} + +#define PADS_2511020213301_CONFIG_WE_INTERFACE(inst) \ + {COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \ + (.sensor_interface = {.interfaceType = WE_i2c}), \ + ()) COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (.sensor_interface = {.interfaceType = WE_spi}), \ + ()) } + +/* + * Main instantiation macro. Use of COND_CODE_1() selects the right + * bus-specific macro at preprocessor time. + */ +#define PADS_2511020213301_DEFINE(inst) \ + static struct pads_2511020213301_data pads_2511020213301_data_##inst = \ + PADS_2511020213301_CONFIG_WE_INTERFACE(inst); \ + static const struct pads_2511020213301_config pads_2511020213301_config_##inst = \ + COND_CODE_1(DT_INST_ON_BUS(inst, i2c),\ + (PADS_2511020213301_CONFIG_I2C(inst)), \ + ()) \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (PADS_2511020213301_CONFIG_SPI(inst)),\ + ()); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, pads_2511020213301_init, NULL, \ + &pads_2511020213301_data_##inst, \ + &pads_2511020213301_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &pads_2511020213301_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PADS_2511020213301_DEFINE) diff --git a/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301.h b/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301.h new file mode 100644 index 0000000000000..8fb335e6e68a5 --- /dev/null +++ b/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_WSEN_PADS_2511020213301_WSEN_PADS_2511020213301_H_ +#define ZEPHYR_DRIVERS_SENSOR_WSEN_PADS_2511020213301_WSEN_PADS_2511020213301_H_ + +#include +#include + +#include + +#include "WSEN_PADS_2511020213301_hal.h" +#include + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#include +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ + +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#include +#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ + +struct pads_2511020213301_data { + /* WE sensor interface configuration */ + WE_sensorInterface_t sensor_interface; + + /* Last pressure sample */ + int32_t pressure; + + /* Last temperature sample */ + int16_t temperature; + + PADS_outputDataRate_t sensor_odr; + +#ifdef CONFIG_WSEN_PADS_2511020213301_TRIGGER + const struct device *dev; + + struct gpio_callback interrupt_cb; + +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD + sensor_trigger_handler_t pressure_high_trigger_handler; + sensor_trigger_handler_t pressure_low_trigger_handler; + const struct sensor_trigger *pressure_high_trigger; + const struct sensor_trigger *pressure_low_trigger; +#else + sensor_trigger_handler_t data_ready_trigger_handler; + const struct sensor_trigger *data_ready_trigger; +#endif /* CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD */ + +#if defined(CONFIG_WSEN_PADS_2511020213301_TRIGGER_OWN_THREAD) + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_WSEN_PADS_2511020213301_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem sem; +#elif defined(CONFIG_WSEN_PADS_2511020213301_TRIGGER_GLOBAL_THREAD) + struct k_work work; +#endif +#endif /* CONFIG_WSEN_PADS_2511020213301_TRIGGER */ +}; + +struct pads_2511020213301_config { + union { +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) + const struct i2c_dt_spec i2c; +#endif +#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) + const struct spi_dt_spec spi; +#endif + } bus_cfg; + + /* Output data rate */ + const PADS_outputDataRate_t odr; + + const PADS_powerMode_t configuration; + + const PADS_state_t alpf; + + const PADS_filterConf_t alpf_configuration; +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD + const uint16_t threshold; +#endif /* CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD */ +#ifdef CONFIG_WSEN_PADS_2511020213301_TRIGGER + /* Interrupt pin */ + const struct gpio_dt_spec interrupt_gpio; +#endif /* CONFIG_WSEN_PADS_2511020213301_TRIGGER */ +}; + +#ifdef CONFIG_WSEN_PADS_2511020213301_TRIGGER +int pads_2511020213301_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + +int pads_2511020213301_init_interrupt(const struct device *dev); + +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD +int pads_2511020213301_threshold_set(const struct device *dev, + const struct sensor_value *threshold); + +int pads_2511020213301_threshold_get(const struct device *dev, struct sensor_value *threshold); + +int pads_2511020213301_reference_point_set(const struct device *dev, + const struct sensor_value *reference_point); + +int pads_2511020213301_reference_point_get(const struct device *dev, + struct sensor_value *reference_point); + +#endif /* CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD */ +#endif /* CONFIG_WSEN_PADS_2511020213301_TRIGGER */ + +int pads_2511020213301_spi_init(const struct device *dev); +int pads_2511020213301_i2c_init(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_WSEN_PADS_2511020213301_WSEN_PADS_2511020213301_H_ */ diff --git a/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301_trigger.c b/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301_trigger.c new file mode 100644 index 0000000000000..5850c14ae0303 --- /dev/null +++ b/drivers/sensor/wsen/wsen_pads_2511020213301/wsen_pads_2511020213301_trigger.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT we_wsen_pads_2511020213301 + +#include + +#include "wsen_pads_2511020213301.h" + +LOG_MODULE_DECLARE(WSEN_PADS_2511020213301, CONFIG_SENSOR_LOG_LEVEL); + +/* Enable/disable data-ready interrupt handling */ +static inline int pads_2511020213301_setup_interrupt(const struct device *dev, bool enable) +{ + const struct pads_2511020213301_config *cfg = dev->config; + unsigned int flags = enable ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE; + + return gpio_pin_interrupt_configure_dt(&cfg->interrupt_gpio, flags); +} + +/* + * Is called when an interrupt has occurred. + */ +static inline void pads_2511020213301_handle_interrupt(const struct device *dev) +{ + struct pads_2511020213301_data *data = dev->data; + + /* Disable interrupt handling until the interrupt has been processed */ + pads_2511020213301_setup_interrupt(dev, false); + +#if defined(CONFIG_WSEN_PADS_2511020213301_TRIGGER_OWN_THREAD) + k_sem_give(&data->sem); +#elif defined(CONFIG_WSEN_PADS_2511020213301_TRIGGER_GLOBAL_THREAD) + k_work_submit(&data->work); +#endif +} + +/* Calls data-ready trigger handler (if any) */ +static void pads_2511020213301_process_interrupt(const struct device *dev) +{ + struct pads_2511020213301_data *data = dev->data; + +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD + if (data->pressure_low_trigger_handler != NULL || + data->pressure_high_trigger_handler != NULL) { + PADS_state_t pressure_high_state, pressure_low_state; + + if (PADS_getHighPressureInterruptStatus(&data->sensor_interface, + &pressure_high_state) != WE_SUCCESS) { + LOG_ERR("Failed to read pressure high state"); + return; + } + + if (PADS_getLowPressureInterruptStatus(&data->sensor_interface, + &pressure_low_state) != WE_SUCCESS) { + LOG_ERR("Failed to read pressure high state"); + return; + } + + if (data->pressure_high_trigger_handler != NULL && + pressure_high_state == PADS_enable) { + data->pressure_high_trigger_handler(dev, data->pressure_high_trigger); + } else if (data->pressure_low_trigger_handler != NULL && + pressure_low_state == PADS_enable) { + data->pressure_low_trigger_handler(dev, data->pressure_low_trigger); + } + } +#else + if (data->data_ready_trigger_handler != NULL) { + data->data_ready_trigger_handler(dev, data->data_ready_trigger); + } +#endif /* CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD */ + + pads_2511020213301_setup_interrupt(dev, true); +} + +int pads_2511020213301_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + struct pads_2511020213301_data *data = dev->data; + const struct pads_2511020213301_config *cfg = dev->config; + + if (trig->chan != SENSOR_CHAN_PRESS) { + LOG_ERR("Unsupported sensor trigger"); + return -ENOTSUP; + } + + switch ((int)trig->type) { +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD + case SENSOR_TRIG_WSEN_PADS_2511020213301_THRESHOLD_LOWER: + case SENSOR_TRIG_WSEN_PADS_2511020213301_THRESHOLD_UPPER: { + switch ((int)trig->type) { + case SENSOR_TRIG_WSEN_PADS_2511020213301_THRESHOLD_LOWER: + data->pressure_low_trigger_handler = handler; + data->pressure_low_trigger = trig; + break; + case SENSOR_TRIG_WSEN_PADS_2511020213301_THRESHOLD_UPPER: + data->pressure_high_trigger_handler = handler; + data->pressure_high_trigger = trig; + break; + default: + break; + } + + if (PADS_setInterruptEventControl(&data->sensor_interface, + PADS_pressureHighOrLow) != WE_SUCCESS) { + LOG_ERR("Failed to set interrupt event control to pressure high or low"); + return -EIO; + } + + if (PADS_enableDiffPressureInterrupt(&data->sensor_interface, + (data->pressure_high_trigger_handler || + data->pressure_low_trigger_handler) + ? PADS_enable + : PADS_disable) != WE_SUCCESS) { + LOG_ERR("Failed to enable pressure diff interrupt."); + return -EIO; + } + + if (PADS_enableLowPressureInterrupt(&data->sensor_interface, + (data->pressure_low_trigger_handler == NULL) + ? PADS_disable + : PADS_enable) != WE_SUCCESS) { + LOG_ERR("Failed to enable low pressure interrupt."); + return -EIO; + } + if (PADS_enableHighPressureInterrupt(&data->sensor_interface, + (data->pressure_high_trigger_handler == NULL) + ? PADS_disable + : PADS_enable) != WE_SUCCESS) { + LOG_ERR("Failed to enable high pressure interrupt."); + return -EIO; + } + + pads_2511020213301_setup_interrupt(dev, data->pressure_high_trigger_handler || + data->pressure_low_trigger_handler); + break; + } +#else + case SENSOR_TRIG_DATA_READY: { + int32_t pressure_dummy; + /* Read pressure to retrigger interrupt */ + if (PADS_getPressure_int(&data->sensor_interface, &pressure_dummy) != WE_SUCCESS) { + LOG_ERR("Failed to read sample"); + return -EIO; + } + + if (PADS_setInterruptEventControl(&data->sensor_interface, PADS_dataReady)) { + LOG_ERR("Failed to set interrupt event control to data ready"); + return -EIO; + } + + /* Enable data-ready interrupt */ + if (PADS_enableDataReadyInterrupt(&data->sensor_interface, + (handler == NULL) ? PADS_disable : PADS_enable) != + WE_SUCCESS) { + LOG_ERR("Failed to enable data-ready interrupt."); + return -EIO; + } + + data->data_ready_trigger_handler = handler; + data->data_ready_trigger = trig; + + pads_2511020213301_setup_interrupt(dev, data->data_ready_trigger_handler); + + break; + } +#endif /* CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD */ + default: + LOG_ERR("Unsupported sensor trigger"); + return -ENOTSUP; + } + + if (gpio_pin_get_dt(&cfg->interrupt_gpio) > 0) { + pads_2511020213301_handle_interrupt(dev); + } + + return 0; +} + +static void pads_2511020213301_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + struct pads_2511020213301_data *data = + CONTAINER_OF(cb, struct pads_2511020213301_data, interrupt_cb); + + ARG_UNUSED(pins); + + pads_2511020213301_handle_interrupt(data->dev); +} + +#ifdef CONFIG_WSEN_PADS_2511020213301_TRIGGER_OWN_THREAD +static void pads_2511020213301_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct pads_2511020213301_data *data = p1; + + while (true) { + k_sem_take(&data->sem, K_FOREVER); + pads_2511020213301_process_interrupt(data->dev); + } +} +#endif /* CONFIG_WSEN_PADS_2511020213301_TRIGGER_OWN_THREAD */ + +#ifdef CONFIG_WSEN_PADS_2511020213301_TRIGGER_GLOBAL_THREAD +static void pads_2511020213301_work_cb(struct k_work *work) +{ + struct pads_2511020213301_data *data = + CONTAINER_OF(work, struct pads_2511020213301_data, work); + + pads_2511020213301_process_interrupt(data->dev); +} +#endif /* CONFIG_WSEN_PADS_2511020213301_TRIGGER_GLOBAL_THREAD */ + +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD +/* Set threshold for the differential pressure interrupt. */ +int pads_2511020213301_threshold_set(const struct device *dev, const struct sensor_value *threshold) +{ + struct pads_2511020213301_data *data = dev->data; + + if (PADS_setPressureThreshold(&data->sensor_interface, (uint32_t)threshold->val1) != + WE_SUCCESS) { + LOG_ERR("Failed to set threshold"); + return -EIO; + } + + return 0; +} + +/* Get threshold for the differential pressure interrupt. */ +int pads_2511020213301_threshold_get(const struct device *dev, struct sensor_value *threshold) +{ + + struct pads_2511020213301_data *data = dev->data; + + if (PADS_getPressureThreshold(&data->sensor_interface, (uint32_t *)&threshold->val1) != + WE_SUCCESS) { + LOG_ERR("Failed to get threshold"); + return -EIO; + } + + return 0; +} + +/* Set reference point to current measured pressure state. */ +int pads_2511020213301_reference_point_set(const struct device *dev, + const struct sensor_value *reference_point) +{ + struct pads_2511020213301_data *data = dev->data; + + if (reference_point != NULL) { + LOG_ERR("Sensor value should be null"); + return -EIO; + } + + if (PADS_enableAutoRefp(&data->sensor_interface, PADS_enable) != WE_SUCCESS) { + LOG_ERR("Failed to set additional low pass filter"); + return -EIO; + } + + return 0; +} + +/* Get reference point from registers. */ +int pads_2511020213301_reference_point_get(const struct device *dev, + struct sensor_value *reference_point) +{ + + struct pads_2511020213301_data *data = dev->data; + + if (PADS_getReferencePressure(&data->sensor_interface, + (uint32_t *)&reference_point->val1) != WE_SUCCESS) { + LOG_ERR("Failed to get reference point"); + return -EIO; + } + + return 0; +} +#endif /* CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD */ + +int pads_2511020213301_init_interrupt(const struct device *dev) +{ + struct pads_2511020213301_data *data = dev->data; + const struct pads_2511020213301_config *cfg = dev->config; + + data->dev = dev; + + if (cfg->interrupt_gpio.port == NULL) { + LOG_ERR("interrupt-gpio is not defined in the device tree."); + return -EINVAL; + } + + if (!gpio_is_ready_dt(&cfg->interrupt_gpio)) { + LOG_ERR("Device %s is not ready", cfg->interrupt_gpio.port->name); + return -ENODEV; + } + + if (gpio_pin_configure_dt(&cfg->interrupt_gpio, GPIO_INPUT) < 0) { + LOG_ERR("Failed to configure %s.%02u", cfg->interrupt_gpio.port->name, + cfg->interrupt_gpio.pin); + return -EIO; + } + + gpio_init_callback(&data->interrupt_cb, pads_2511020213301_callback, + BIT(cfg->interrupt_gpio.pin)); + + if (gpio_add_callback(cfg->interrupt_gpio.port, &data->interrupt_cb) < 0) { + LOG_ERR("Failed to set gpio callback."); + return -EIO; + } +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD + + struct sensor_value threshold; + + threshold.val1 = cfg->threshold; + threshold.val2 = 0; + if (pads_2511020213301_threshold_set(dev, &threshold) < 0) { + LOG_ERR("Failed to set threshold."); + return -EIO; + } + +#endif /* CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD */ + +#if defined(CONFIG_WSEN_PADS_2511020213301_TRIGGER_OWN_THREAD) + k_sem_init(&data->sem, 0, K_SEM_MAX_LIMIT); + + k_thread_create(&data->thread, data->thread_stack, + CONFIG_WSEN_PADS_2511020213301_THREAD_STACK_SIZE, pads_2511020213301_thread, + data, NULL, NULL, + K_PRIO_COOP(CONFIG_WSEN_PADS_2511020213301_THREAD_PRIORITY), 0, K_NO_WAIT); +#elif defined(CONFIG_WSEN_PADS_2511020213301_TRIGGER_GLOBAL_THREAD) + data->work.handler = pads_2511020213301_work_cb; +#endif + + return 0; +} diff --git a/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/CMakeLists.txt b/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/CMakeLists.txt new file mode 100644 index 0000000000000..d88e689e54ebd --- /dev/null +++ b/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 WĂźrth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(wsen_pdus_25131308XXXXX.c) diff --git a/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/Kconfig b/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/Kconfig new file mode 100644 index 0000000000000..3257c89aaeb7a --- /dev/null +++ b/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2024 WĂźrth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +config WSEN_PDUS_25131308XXXXX + bool "WSEN-PDUS-25131308XXXXX differential pressure sensor" + default y + depends on DT_HAS_WE_WSEN_PDUS_25131308XXXXX_ENABLED + select I2C + select HAS_WESENSORS + help + Enable driver for the WSEN-PDUS-25131308XXXXX I2C-based differential pressure sensor. diff --git a/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/wsen_pdus_25131308XXXXX.c b/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/wsen_pdus_25131308XXXXX.c new file mode 100644 index 0000000000000..9b85f401902e8 --- /dev/null +++ b/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/wsen_pdus_25131308XXXXX.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2024 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT we_wsen_pdus_25131308xxxxx + +#include + +#include +#include +#include + +#include "wsen_pdus_25131308XXXXX.h" + +LOG_MODULE_REGISTER(WSEN_PDUS_25131308XXXXX, CONFIG_SENSOR_LOG_LEVEL); + +static int pdus_25131308XXXXX_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct pdus_25131308XXXXX_data *data = dev->data; + uint16_t pressure_dummy; + + switch (chan) { + case SENSOR_CHAN_ALL: { + if (PDUS_getRawPressureAndTemperature(&data->sensor_interface, &data->pressure, + &data->temperature) != WE_SUCCESS) { + LOG_ERR("Failed to fetch data sample"); + return -EIO; + } + break; + } + case SENSOR_CHAN_AMBIENT_TEMP: { + if (PDUS_getRawPressureAndTemperature(&data->sensor_interface, &pressure_dummy, + &data->temperature) != WE_SUCCESS) { + LOG_ERR("Failed to fetch data sample"); + return -EIO; + } + break; + } + case SENSOR_CHAN_PRESS: { + if (PDUS_getRawPressure(&data->sensor_interface, &data->pressure) != WE_SUCCESS) { + LOG_ERR("Failed to fetch data sample"); + return -EIO; + } + break; + } + default: + LOG_ERR("Fetching is not supported on channel %d.", chan); + return -ENOTSUP; + } + + return 0; +} + +static int pdus_25131308XXXXX_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *value) +{ + struct pdus_25131308XXXXX_data *data = dev->data; + const struct pdus_25131308XXXXX_config *config = dev->config; + + switch (chan) { + case SENSOR_CHAN_AMBIENT_TEMP: { + int32_t temperature_mega = ((int32_t)(data->temperature - T_MIN_VAL_PDUS)) * 4272; + + value->val1 = temperature_mega / 1000000; + value->val2 = temperature_mega % 1000000; + break; + } + case SENSOR_CHAN_PRESS: { + int32_t pressure_temp = ((int32_t)(data->pressure - P_MIN_VAL_PDUS)); + + /* + * these values are conversion factors based on the sensor type defined in the user + * manual of the respective sensor + */ + switch (config->sensor_type) { + case PDUS_pdus0: + value->val1 = ((pressure_temp * 763) - 10000000) / 100000000; + value->val2 = (((pressure_temp * 763) - 10000000) % 100000000) / 100; + break; + case PDUS_pdus1: + value->val1 = ((pressure_temp * 763) - 10000000) / 10000000; + value->val2 = (((pressure_temp * 763) - 10000000) % 10000000) / 10; + break; + case PDUS_pdus2: + value->val1 = ((pressure_temp * 763) - 10000000) / 1000000; + value->val2 = ((pressure_temp * 763) - 10000000) % 1000000; + break; + case PDUS_pdus3: + value->val1 = (pressure_temp * 3815) / 1000000; + value->val2 = (pressure_temp * 3815) % 1000000; + break; + case PDUS_pdus4: + value->val1 = ((pressure_temp * 4196) - 10000000) / 100000; + value->val2 = + ((pressure_temp * 4196) - 10000000) % 100000 * (1000000 / 100000); + break; + case PDUS_pdus5: + value->val1 = (pressure_temp * 5722) / 100000; + value->val2 = (pressure_temp * 5722) % 100000 * (1000000 / 100000); + break; + default: + LOG_ERR("Sensor type doesn't exist"); + return -ENOTSUP; + } + break; + } + default: + LOG_ERR("Channel not supported %d", chan); + return -ENOTSUP; + } + + return 0; +} + +static DEVICE_API(sensor, pdus_25131308XXXXX_driver_api) = { + .sample_fetch = pdus_25131308XXXXX_sample_fetch, + .channel_get = pdus_25131308XXXXX_channel_get +}; + +static int pdus_25131308XXXXX_init(const struct device *dev) +{ + struct pdus_25131308XXXXX_data *data = dev->data; + const struct pdus_25131308XXXXX_config *config = dev->config; + + /* Initialize WE sensor interface */ + PDUS_getDefaultInterface(&data->sensor_interface); + data->sensor_interface.interfaceType = WE_i2c; + + if (!i2c_is_ready_dt(&config->bus_cfg.i2c)) { + LOG_ERR("I2C bus device not ready"); + return -ENODEV; + } + + data->sensor_interface.handle = (void *)&config->bus_cfg.i2c; + + return 0; +} + +/* + * Main instantiation macro. + */ +#define PDUS_25131308XXXXX_DEFINE(inst) \ + static struct pdus_25131308XXXXX_data pdus_25131308XXXXX_data_##inst; \ + static const struct pdus_25131308XXXXX_config pdus_25131308XXXXX_config_##inst = { \ + .bus_cfg = \ + { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }, \ + .sensor_type = (PDUS_SensorType_t)DT_INST_ENUM_IDX(inst, sensor_type)}; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, pdus_25131308XXXXX_init, NULL, \ + &pdus_25131308XXXXX_data_##inst, \ + &pdus_25131308XXXXX_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &pdus_25131308XXXXX_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PDUS_25131308XXXXX_DEFINE) diff --git a/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/wsen_pdus_25131308XXXXX.h b/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/wsen_pdus_25131308XXXXX.h new file mode 100644 index 0000000000000..ee065f0b16dee --- /dev/null +++ b/drivers/sensor/wsen/wsen_pdus_25131308XXXXX/wsen_pdus_25131308XXXXX.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_WSEN_PDUS_25131308XXXXX_WSEN_PDUS_25131308XXXXX_H_ +#define ZEPHYR_DRIVERS_SENSOR_WSEN_PDUS_25131308XXXXX_WSEN_PDUS_25131308XXXXX_H_ + +#include +#include + +#include + +#include "WSEN_PDUS_25131308XXX01_hal.h" +#include + +struct pdus_25131308XXXXX_data { + /* WE sensor interface configuration */ + WE_sensorInterface_t sensor_interface; + + /* Last pressure sample */ + uint16_t pressure; + + /* Last temperature sample */ + uint16_t temperature; +}; + +struct pdus_25131308XXXXX_config { + union { + const struct i2c_dt_spec i2c; + } bus_cfg; + + PDUS_SensorType_t sensor_type; +}; + +#endif /* ZEPHYR_DRIVERS_SENSOR_WSEN_PDUS_25131308XXXXX_WSEN_PDUS_25131308XXXXX_H_ */ diff --git a/drivers/sensor/wsen/wsen_tids_2521020222501/CMakeLists.txt b/drivers/sensor/wsen/wsen_tids_2521020222501/CMakeLists.txt new file mode 100644 index 0000000000000..36488ae2846fe --- /dev/null +++ b/drivers/sensor/wsen/wsen_tids_2521020222501/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(wsen_tids_2521020222501.c) +zephyr_library_sources_ifdef(CONFIG_WSEN_TIDS_2521020222501_TRIGGER wsen_tids_2521020222501_trigger.c) diff --git a/drivers/sensor/wsen/wsen_tids_2521020222501/Kconfig b/drivers/sensor/wsen/wsen_tids_2521020222501/Kconfig new file mode 100644 index 0000000000000..07b5b0db47810 --- /dev/null +++ b/drivers/sensor/wsen/wsen_tids_2521020222501/Kconfig @@ -0,0 +1,53 @@ +# Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +menuconfig WSEN_TIDS_2521020222501 + bool "WSEN-TIDS-2521020222501 temperature sensor" + default y + depends on DT_HAS_WE_WSEN_TIDS_2521020222501_ENABLED + select I2C + select HAS_WESENSORS + help + Enable driver for the WSEN-TIDS-2521020222501 I2C-based temperature sensor. + +if WSEN_TIDS_2521020222501 + +choice WSEN_TIDS_2521020222501_TRIGGER_MODE + prompt "Trigger mode" + default WSEN_TIDS_2521020222501_TRIGGER_NONE + help + Specify the type of triggering to be used by the driver. + +config WSEN_TIDS_2521020222501_TRIGGER_NONE + bool "No trigger" + +config WSEN_TIDS_2521020222501_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on GPIO + select WSEN_TIDS_2521020222501_TRIGGER + +config WSEN_TIDS_2521020222501_TRIGGER_OWN_THREAD + bool "Use own thread" + depends on GPIO + select WSEN_TIDS_2521020222501_TRIGGER + +endchoice # WSEN_TIDS_2521020222501_TRIGGER_MODE + +config WSEN_TIDS_2521020222501_TRIGGER + bool + +config WSEN_TIDS_2521020222501_THREAD_PRIORITY + int "Thread priority" + depends on WSEN_TIDS_2521020222501_TRIGGER_OWN_THREAD + default 10 + help + Priority of thread used by the driver to handle interrupts. + +config WSEN_TIDS_2521020222501_THREAD_STACK_SIZE + int "Thread stack size" + depends on WSEN_TIDS_2521020222501_TRIGGER_OWN_THREAD + default 1024 + help + Stack size of thread used by the driver to handle interrupts. + +endif # WSEN_TIDS_2521020222501 diff --git a/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501.c b/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501.c new file mode 100644 index 0000000000000..e014945bb1ce7 --- /dev/null +++ b/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT we_wsen_tids_2521020222501 + +#include + +#include +#include +#include + +#include "wsen_tids_2521020222501.h" + +LOG_MODULE_REGISTER(WSEN_TIDS_2521020222501, CONFIG_SENSOR_LOG_LEVEL); + +static const struct sensor_value tids_2521020222501_odr_list[] = {{.val1 = 0, .val2 = 0}, + {.val1 = 25, .val2 = 0}, + {.val1 = 50, .val2 = 0}, + {.val1 = 100, .val2 = 0}, + {.val1 = 200, .val2 = 0}}; + +static int tids_2521020222501_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct tids_2521020222501_data *data = dev->data; + int16_t raw_temperature; + + switch (chan) { + case SENSOR_CHAN_ALL: + case SENSOR_CHAN_AMBIENT_TEMP: + break; + default: + LOG_ERR("Fetching is not supported on channel %d.", chan); + return -ENOTSUP; + } + if (data->sensor_odr == ((uint8_t)tids_2521020222501_odr_list[0].val1)) { + + TIDS_softReset(&data->sensor_interface, TIDS_enable); + + k_sleep(K_USEC(5)); + + TIDS_softReset(&data->sensor_interface, TIDS_disable); + + if (TIDS_enableOneShot(&data->sensor_interface, TIDS_enable) != WE_SUCCESS) { + LOG_ERR("Failed to enable one shot"); + return -EIO; + } + + TIDS_state_t busy = TIDS_enable; + + do { + if (TIDS_isBusy(&data->sensor_interface, &busy) != WE_SUCCESS) { + LOG_ERR("Failed to check for data ready"); + return -EIO; + } + } while (TIDS_enable == busy); + } + + if (TIDS_getRawTemperature(&data->sensor_interface, &raw_temperature) != WE_SUCCESS) { + LOG_ERR("Failed to fetch data sample"); + return -EIO; + } + + data->temperature = raw_temperature; + + return 0; +} + +static int tids_2521020222501_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct tids_2521020222501_data *data = dev->data; + + switch (chan) { + case SENSOR_CHAN_AMBIENT_TEMP: + /* Convert temperature from 0.01 degrees Celsius to degrees Celsius */ + val->val1 = data->temperature / 100; + val->val2 = ((int32_t)data->temperature % 100) * (1000000 / 100); + break; + default: + LOG_ERR("Channel not supported %d", chan); + return -ENOTSUP; + } + + return 0; +} + +/* Set output data rate. See tids_2521020222501_odr_list for allowed values. */ +static int tids_2521020222501_odr_set(const struct device *dev, const struct sensor_value *odr) +{ + struct tids_2521020222501_data *data = dev->data; + + int odr_index; + + for (odr_index = 0; odr_index < ARRAY_SIZE(tids_2521020222501_odr_list); odr_index++) { + if (odr->val1 == tids_2521020222501_odr_list[odr_index].val1 && + odr->val2 == tids_2521020222501_odr_list[odr_index].val2) { + break; + } + } + + if (odr_index == ARRAY_SIZE(tids_2521020222501_odr_list)) { + /* ODR not allowed (was not found in tids_2521020222501_odr_list) */ + LOG_ERR("Bad sampling frequency %d.%d", odr->val1, odr->val2); + return -EINVAL; + } + + if (odr->val1 == tids_2521020222501_odr_list[0].val1) { + if (TIDS_enableBlockDataUpdate(&data->sensor_interface, TIDS_disable) != + WE_SUCCESS) { + LOG_ERR("Failed to enable block data update."); + return -EIO; + } + + if (TIDS_enableContinuousMode(&data->sensor_interface, TIDS_disable) != + WE_SUCCESS) { + LOG_ERR("Failed to enable continuous mode."); + return -EIO; + } + } else { + if (TIDS_setOutputDataRate(&data->sensor_interface, + (TIDS_outputDataRate_t)(odr->val1 - 1)) != WE_SUCCESS) { + LOG_ERR("Failed to set output data rate"); + return -EIO; + } + + if (TIDS_enableBlockDataUpdate(&data->sensor_interface, TIDS_enable) != + WE_SUCCESS) { + LOG_ERR("Failed to enable block data update."); + return -EIO; + } + + if (TIDS_enableContinuousMode(&data->sensor_interface, TIDS_enable) != WE_SUCCESS) { + LOG_ERR("Failed to enable continuous mode."); + return -EIO; + } + } + + data->sensor_odr = (uint8_t)odr->val1; + + return 0; +} + +/* Get output data rate. */ +static int tids_2521020222501_odr_get(const struct device *dev, struct sensor_value *odr) +{ + + struct tids_2521020222501_data *data = dev->data; + + TIDS_state_t continuous_mode_state; + + if (TIDS_isContinuousModeEnabled(&data->sensor_interface, &continuous_mode_state) != + WE_SUCCESS) { + LOG_ERR("Failed to get continuous mode."); + return -EIO; + } + + if (continuous_mode_state == TIDS_disable) { + odr->val1 = tids_2521020222501_odr_list[0].val1; + } else { + TIDS_outputDataRate_t odrIndex; + + if (TIDS_getOutputDataRate(&data->sensor_interface, &odrIndex) != WE_SUCCESS) { + LOG_ERR("Failed to get output data rate"); + return -EIO; + } + + odr->val1 = tids_2521020222501_odr_list[odrIndex + 1].val1; + } + + data->sensor_odr = (uint8_t)odr->val1; + + odr->val2 = 0; + + return 0; +} + +static int tids_2521020222501_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + + switch (chan) { + case SENSOR_CHAN_ALL: + case SENSOR_CHAN_AMBIENT_TEMP: + break; + default: + LOG_ERR("attr_set() is not supported on channel %d.", chan); + return -ENOTSUP; + } + + switch (attr) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: + return tids_2521020222501_odr_set(dev, val); +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER + case SENSOR_ATTR_LOWER_THRESH: + return tids_2521020222501_threshold_lower_set(dev, val); + case SENSOR_ATTR_UPPER_THRESH: + return tids_2521020222501_threshold_upper_set(dev, val); +#endif /* CONFIG_WSEN_TIDS_2521020222501_TRIGGER */ + + default: + LOG_ERR("Operation not supported."); + return -ENOTSUP; + } +} + +static int tids_2521020222501_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + + if (val == NULL) { + LOG_WRN("address of passed value is NULL."); + return -EFAULT; + } + + switch (chan) { + case SENSOR_CHAN_ALL: + case SENSOR_CHAN_AMBIENT_TEMP: + break; + default: + LOG_ERR("attr_get() is not supported on channel %d.", chan); + return -ENOTSUP; + } + + switch (attr) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: + return tids_2521020222501_odr_get(dev, val); +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER + case SENSOR_ATTR_LOWER_THRESH: + return tids_2521020222501_threshold_lower_get(dev, val); + case SENSOR_ATTR_UPPER_THRESH: + return tids_2521020222501_threshold_upper_get(dev, val); +#endif /* CONFIG_WSEN_TIDS_2521020222501_TRIGGER */ + default: + LOG_ERR("Operation not supported."); + return -ENOTSUP; + } + + return 0; +} + +static DEVICE_API(sensor, tids_2521020222501_driver_api) = { + .attr_set = tids_2521020222501_attr_set, +#if CONFIG_WSEN_TIDS_2521020222501_TRIGGER + .trigger_set = tids_2521020222501_trigger_set, +#endif + .attr_get = tids_2521020222501_attr_get, + .sample_fetch = tids_2521020222501_sample_fetch, + .channel_get = tids_2521020222501_channel_get, +}; + +static int tids_2521020222501_init(const struct device *dev) +{ + const struct tids_2521020222501_config *const config = dev->config; + struct tids_2521020222501_data *data = dev->data; + uint8_t device_id; + + /* Initialize WE sensor interface */ + TIDS_getDefaultInterface(&data->sensor_interface); + data->sensor_interface.interfaceType = WE_i2c; + if (!i2c_is_ready_dt(&config->bus_cfg.i2c)) { + LOG_ERR("I2C bus device not ready"); + return -ENODEV; + } + data->sensor_interface.handle = (void *)&config->bus_cfg.i2c; + + /* Needed after power up */ + k_sleep(K_MSEC(12)); + + /* First communication test - check device ID */ + if (TIDS_getDeviceID(&data->sensor_interface, &device_id) != WE_SUCCESS) { + LOG_ERR("Failed to read device ID."); + return -EIO; + } + + if (device_id != TIDS_DEVICE_ID_VALUE) { + LOG_ERR("Invalid device ID 0x%x.", device_id); + return -EIO; + } + + /* Reset the sensor with an arbitrary off time of 5 us */ + TIDS_softReset(&data->sensor_interface, TIDS_enable); + k_sleep(K_USEC(5)); + TIDS_softReset(&data->sensor_interface, TIDS_disable); + + if (tids_2521020222501_odr_set(dev, &tids_2521020222501_odr_list[config->odr]) < 0) { + LOG_ERR("Failed to set output data rate."); + return -EIO; + } + +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER + if (tids_2521020222501_init_interrupt(dev) < 0) { + LOG_ERR("Failed to initialize interrupt."); + return -EIO; + } +#endif + + return 0; +} + +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER +#define TIDS_2521020222501_CFG_IRQ(inst) \ + .interrupt_gpio = GPIO_DT_SPEC_INST_GET(inst, interrupt_gpios), \ + .high_threshold = DT_INST_PROP(inst, temp_high_threshold), \ + .low_threshold = DT_INST_PROP(inst, temp_low_threshold) +#else +#define TIDS_2521020222501_CFG_IRQ(inst) +#endif /* CONFIG_WSEN_TIDS_2521020222501_TRIGGER */ + +/* + * Main instantiation macro. + */ +#define TIDS_2521020222501_DEFINE(inst) \ + static struct tids_2521020222501_data tids_2521020222501_data_##inst; \ + static const struct tids_2521020222501_config tids_2521020222501_config_##inst = { \ + .bus_cfg = \ + { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }, \ + .odr = (uint8_t)(DT_INST_ENUM_IDX(inst, odr)), \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, interrupt_gpios), \ + (TIDS_2521020222501_CFG_IRQ(inst)), ())}; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, tids_2521020222501_init, NULL, \ + &tids_2521020222501_data_##inst, \ + &tids_2521020222501_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &tids_2521020222501_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(TIDS_2521020222501_DEFINE) diff --git a/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501.h b/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501.h new file mode 100644 index 0000000000000..46051ac5fc13f --- /dev/null +++ b/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_WSEN_TIDS_2521020222501_WSEN_TIDS_2521020222501_H_ +#define ZEPHYR_DRIVERS_SENSOR_WSEN_TIDS_2521020222501_WSEN_TIDS_2521020222501_H_ + +#include +#include + +#include + +#include "WSEN_TIDS_2521020222501_hal.h" +#include + +#include + +struct tids_2521020222501_data { + /* WE sensor interface configuration */ + WE_sensorInterface_t sensor_interface; + + /* Last temperature sample */ + int16_t temperature; + + uint8_t sensor_odr; + +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER + const struct device *dev; + + /* Callback for high/low limit interrupts */ + struct gpio_callback interrupt_cb; + + int32_t sensor_high_threshold; + int32_t sensor_low_threshold; + + sensor_trigger_handler_t temperature_high_handler; + sensor_trigger_handler_t temperature_low_handler; + + const struct sensor_trigger *temperature_high_trigger; + const struct sensor_trigger *temperature_low_trigger; + +#if defined(CONFIG_WSEN_TIDS_2521020222501_TRIGGER_OWN_THREAD) + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_WSEN_TIDS_2521020222501_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem sem; +#elif defined(CONFIG_WSEN_TIDS_2521020222501_TRIGGER_GLOBAL_THREAD) + struct k_work work; +#endif +#endif /* CONFIG_WSEN_TIDS_2521020222501_TRIGGER */ +}; + +struct tids_2521020222501_config { + union { + const struct i2c_dt_spec i2c; + } bus_cfg; + + /* Output data rate */ + const uint8_t odr; + +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER + /* Interrupt pin used for high and low limit interrupt events */ + const struct gpio_dt_spec interrupt_gpio; + + /* High temperature interrupt threshold */ + const int32_t high_threshold; + + /* Low temperature interrupt threshold */ + const int32_t low_threshold; +#endif +}; + +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER +int tids_2521020222501_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + +int tids_2521020222501_threshold_upper_set(const struct device *dev, + const struct sensor_value *thresh_value); + +int tids_2521020222501_threshold_upper_get(const struct device *dev, + struct sensor_value *thresh_value); + +int tids_2521020222501_threshold_lower_set(const struct device *dev, + const struct sensor_value *thresh_value); + +int tids_2521020222501_threshold_lower_get(const struct device *dev, + struct sensor_value *thresh_value); + +int tids_2521020222501_init_interrupt(const struct device *dev); +#endif + +int tids_2521020222501_i2c_init(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_WSEN_TIDS_2521020222501_WSEN_TIDS_2521020222501_H_ */ diff --git a/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501_trigger.c b/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501_trigger.c new file mode 100644 index 0000000000000..62fd442829dfe --- /dev/null +++ b/drivers/sensor/wsen/wsen_tids_2521020222501/wsen_tids_2521020222501_trigger.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2025 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT we_wsen_tids_2521020222501 + +#include + +#include + +#include "wsen_tids_2521020222501.h" + +LOG_MODULE_DECLARE(WSEN_TIDS_2521020222501, CONFIG_SENSOR_LOG_LEVEL); + +/* Enable/disable interrupt handling */ +static inline void tids_2521020222501_setup_interrupt(const struct device *dev, bool enable) +{ + const struct tids_2521020222501_config *cfg = dev->config; + unsigned int flags = enable ? GPIO_INT_EDGE_TO_ACTIVE : GPIO_INT_DISABLE; + + gpio_pin_interrupt_configure_dt(&cfg->interrupt_gpio, flags); +} + +/* + * Is called when an interrupt has occurred. + */ +static void tids_2521020222501_handle_interrupt(const struct device *dev) +{ + struct tids_2521020222501_data *data = dev->data; + + /* Disable interrupt handling until the interrupt has been processed */ + tids_2521020222501_setup_interrupt(dev, false); + +#if defined(CONFIG_WSEN_TIDS_2521020222501_TRIGGER_OWN_THREAD) + k_sem_give(&data->sem); +#elif defined(CONFIG_WSEN_TIDS_2521020222501_TRIGGER_GLOBAL_THREAD) + k_work_submit(&data->work); +#endif +} + +/* + * Calls trigger handles. + */ +static void tids_2521020222501_process_interrupt(const struct device *dev) +{ + struct tids_2521020222501_data *data = dev->data; + + if (data->temperature_high_handler != NULL || data->temperature_low_handler != NULL) { + /* + * Read the sensor's status register - this also causes the interrupt pin + * to be de-asserted + */ + TIDS_status_t status; + + if (TIDS_getStatusRegister(&data->sensor_interface, &status) != WE_SUCCESS) { + LOG_ERR("Failed to read status register"); + return; + } + + if (data->temperature_high_handler != NULL && + status.upperLimitExceeded == TIDS_enable) { + data->temperature_high_handler(dev, data->temperature_high_trigger); + } else if (data->temperature_low_handler != NULL && + status.lowerLimitExceeded == TIDS_enable) { + data->temperature_low_handler(dev, data->temperature_low_trigger); + } + } + + tids_2521020222501_setup_interrupt(dev, true); +} + +/* Enables/disables processing of the "threshold exceeded" interrupt. */ +int tids_2521020222501_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + struct tids_2521020222501_data *data = dev->data; + const struct tids_2521020222501_config *cfg = dev->config; + + switch (trig->chan) { + case SENSOR_CHAN_ALL: + case SENSOR_CHAN_AMBIENT_TEMP: + break; + default: + LOG_ERR("Unsupported sensor trigger"); + return -ENOTSUP; + } + + struct sensor_value interruptOFF = {.val1 = -40, .val2 = -320000}; + struct sensor_value threshold; + + switch ((int)trig->type) { + case SENSOR_TRIG_WSEN_TIDS_2521020222501_THRESHOLD_LOWER: { + + threshold.val1 = data->sensor_low_threshold / 1000; + threshold.val2 = ((int32_t)data->sensor_low_threshold % 1000) * (1000000 / 1000); + + if (tids_2521020222501_threshold_lower_set( + dev, (handler == NULL) ? &interruptOFF : &threshold) < 0) { + LOG_ERR("Failed to set low temp threshold"); + } + data->temperature_low_handler = handler; + data->temperature_low_trigger = trig; + break; + } + case SENSOR_TRIG_WSEN_TIDS_2521020222501_THRESHOLD_UPPER: { + + threshold.val1 = data->sensor_high_threshold / 1000; + threshold.val2 = ((int32_t)data->sensor_high_threshold % 1000) * (1000000 / 1000); + + if (tids_2521020222501_threshold_upper_set( + dev, (handler == NULL) ? &interruptOFF : &threshold) < 0) { + LOG_ERR("Failed to set high temp threshold"); + } + data->temperature_high_handler = handler; + data->temperature_high_trigger = trig; + break; + } + default: + LOG_ERR("Unsupported sensor trigger"); + return -ENOTSUP; + } + + tids_2521020222501_setup_interrupt(dev, data->temperature_high_handler || + data->temperature_low_handler); + + if (gpio_pin_get_dt(&cfg->interrupt_gpio) > 0) { + tids_2521020222501_handle_interrupt(dev); + } + + return 0; +} + +static void tids_2521020222501_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + struct tids_2521020222501_data *data = + CONTAINER_OF(cb, struct tids_2521020222501_data, interrupt_cb); + + ARG_UNUSED(pins); + + tids_2521020222501_handle_interrupt(data->dev); +} + +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER_OWN_THREAD +static void tids_2521020222501_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct tids_2521020222501_data *tids_2521020222501 = p1; + + while (true) { + k_sem_take(&tids_2521020222501->sem, K_FOREVER); + tids_2521020222501_process_interrupt(tids_2521020222501->dev); + } +} +#endif /* CONFIG_WSEN_TIDS_2521020222501_TRIGGER_OWN_THREAD */ + +#ifdef CONFIG_WSEN_TIDS_2521020222501_TRIGGER_GLOBAL_THREAD +static void tids_2521020222501_work_cb(struct k_work *work) +{ + struct tids_2521020222501_data *tids_2521020222501 = + CONTAINER_OF(work, struct tids_2521020222501_data, work); + + tids_2521020222501_process_interrupt(tids_2521020222501->dev); +} +#endif /* CONFIG_WSEN_TIDS_2521020222501_TRIGGER_GLOBAL_THREAD */ + +int tids_2521020222501_threshold_upper_set(const struct device *dev, + const struct sensor_value *thresh_value) +{ + struct tids_2521020222501_data *data = dev->data; + int32_t thresh = thresh_value->val1 * 1000 + thresh_value->val2 / 1000; + + if (TIDS_setTempHighLimit(&data->sensor_interface, thresh) != WE_SUCCESS) { + LOG_ERR("Failed to set high temperature threshold."); + return -EIO; + } + + data->sensor_high_threshold = thresh; + + return 0; +} + +int tids_2521020222501_threshold_upper_get(const struct device *dev, + struct sensor_value *thresh_value) +{ + struct tids_2521020222501_data *data = dev->data; + int32_t thresh; + + if (TIDS_getTempHighLimit(&data->sensor_interface, &thresh) != WE_SUCCESS) { + LOG_ERR("Failed to get high temperature threshold."); + return -EIO; + } + + thresh_value->val1 = thresh / 1000; + thresh_value->val2 = (thresh % 1000) * (1000000 / 1000); + + return 0; +} + +int tids_2521020222501_threshold_lower_set(const struct device *dev, + const struct sensor_value *thresh_value) +{ + struct tids_2521020222501_data *data = dev->data; + int32_t thresh = thresh_value->val1 * 1000 + thresh_value->val2 / 1000; + + if (TIDS_setTempLowLimit(&data->sensor_interface, thresh) != WE_SUCCESS) { + LOG_ERR("Failed to set low temperature threshold."); + return -EIO; + } + + data->sensor_low_threshold = thresh; + + return 0; +} + +int tids_2521020222501_threshold_lower_get(const struct device *dev, + struct sensor_value *thresh_value) +{ + struct tids_2521020222501_data *data = dev->data; + int32_t thresh; + + if (TIDS_getTempLowLimit(&data->sensor_interface, &thresh) != WE_SUCCESS) { + LOG_ERR("Failed to get low temperature threshold."); + return -EIO; + } + + thresh_value->val1 = thresh / 1000; + thresh_value->val2 = (thresh % 1000) * (1000000 / 1000); + + return 0; +} + +int tids_2521020222501_init_interrupt(const struct device *dev) +{ + struct tids_2521020222501_data *data = dev->data; + const struct tids_2521020222501_config *cfg = dev->config; + struct sensor_value upper_limit, lower_limit; + + if (cfg->interrupt_gpio.port == NULL) { + LOG_ERR("interrupt-gpios is not defined in the device tree."); + return -EINVAL; + } + + if (!gpio_is_ready_dt(&cfg->interrupt_gpio)) { + LOG_ERR("Device %s is not ready", cfg->interrupt_gpio.port->name); + return -ENODEV; + } + + data->dev = dev; + + /* Setup threshold gpio interrupt */ + if (gpio_pin_configure_dt(&cfg->interrupt_gpio, GPIO_INPUT) < 0) { + LOG_ERR("Failed to configure %s.%02u", cfg->interrupt_gpio.port->name, + cfg->interrupt_gpio.pin); + return -EIO; + } + + gpio_init_callback(&data->interrupt_cb, tids_2521020222501_callback, + BIT(cfg->interrupt_gpio.pin)); + + if (gpio_add_callback(cfg->interrupt_gpio.port, &data->interrupt_cb) < 0) { + LOG_ERR("Failed to set gpio callback."); + return -EIO; + } + + /* + * Enable interrupt on high/low temperature (interrupt generation is enabled if at + * least one threshold is non-zero) + */ + + upper_limit.val1 = cfg->high_threshold / 1000; + upper_limit.val2 = ((int32_t)cfg->high_threshold % 1000) * (1000000 / 1000); + + lower_limit.val1 = cfg->low_threshold / 1000; + lower_limit.val2 = ((int32_t)cfg->low_threshold % 1000) * (1000000 / 1000); + + if (tids_2521020222501_threshold_upper_set(dev, &upper_limit) < 0) { + LOG_ERR("Failed to set upper threshold"); + return -EIO; + } + + if (tids_2521020222501_threshold_lower_set(dev, &lower_limit) < 0) { + LOG_ERR("Failed to set lower threshold"); + return -EIO; + } + +#if defined(CONFIG_WSEN_TIDS_2521020222501_TRIGGER_OWN_THREAD) + k_sem_init(&data->sem, 0, K_SEM_MAX_LIMIT); + + k_thread_create(&data->thread, data->thread_stack, + CONFIG_WSEN_TIDS_2521020222501_THREAD_STACK_SIZE, tids_2521020222501_thread, + data, NULL, NULL, + K_PRIO_COOP(CONFIG_WSEN_TIDS_2521020222501_THREAD_PRIORITY), 0, K_NO_WAIT); +#elif defined(CONFIG_WSEN_TIDS_2521020222501_TRIGGER_GLOBAL_THREAD) + data->work.handler = tids_2521020222501_work_cb; +#endif + + return 0; +} diff --git a/drivers/sensor/xbr818/CMakeLists.txt b/drivers/sensor/xbr818/CMakeLists.txt new file mode 100644 index 0000000000000..96d6c578d64db --- /dev/null +++ b/drivers/sensor/xbr818/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_XBR818 xbr818.c) diff --git a/drivers/sensor/xbr818/Kconfig b/drivers/sensor/xbr818/Kconfig new file mode 100644 index 0000000000000..75b91c758ac78 --- /dev/null +++ b/drivers/sensor/xbr818/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config XBR818 + bool "XBR818 Radar" + default y + depends on DT_HAS_PHOSENSE_XBR818_ENABLED + select I2C + help + Enable driver for the Phosense XBR818 Radar Sensor diff --git a/drivers/sensor/xbr818/xbr818.c b/drivers/sensor/xbr818/xbr818.c new file mode 100644 index 0000000000000..1b426cbfefe59 --- /dev/null +++ b/drivers/sensor/xbr818/xbr818.c @@ -0,0 +1,434 @@ +/* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT phosense_xbr818 + +#include +#include + +#include +LOG_MODULE_REGISTER(XBR818, CONFIG_SENSOR_LOG_LEVEL); + +#include "xbr818.h" +#include + +static int xbr818_enable_i2c(const struct device *dev) +{ + const struct xbr818_config *config = dev->config; + int ret; + + if (config->i2c_en.port) { + ret = gpio_pin_set_dt(&config->i2c_en, 1); + if (ret != 0) { + LOG_ERR("%s: could not set i2c_en pin", dev->name); + } + k_usleep(10); + return ret; + } + return 0; +} + +static int xbr818_disable_i2c(const struct device *dev) +{ + const struct xbr818_config *config = dev->config; + int ret; + + if (config->i2c_en.port) { + ret = gpio_pin_set_dt(&config->i2c_en, 0); + if (ret != 0) { + LOG_ERR("%s: could not unset i2c_en pin", dev->name); + } + return ret; + } + return 0; +} + +static int xbr818_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + const struct xbr818_config *config = dev->config; + struct xbr818_data *data = dev->data; + int ret; + + if (chan != SENSOR_CHAN_PROX && chan != SENSOR_CHAN_ALL) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } + + ret = gpio_pin_get_dt(&config->io_val); + if (ret < 0) { + return ret; + } + data->value = (ret == 1 ? true : false); + + return 0; +} + +static int xbr818_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct xbr818_data *data = dev->data; + + if (chan != SENSOR_CHAN_PROX) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } + + val->val1 = (data->value ? 1 : 0); + val->val2 = 0; + + return 0; +} + +static int xbr818_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + const struct xbr818_config *config = dev->config; + int ret; + uint8_t tmp[3]; + uint64_t tmpf; + + if (chan != SENSOR_CHAN_PROX) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } + + if (val->val1 < 0) { + return -EINVAL; + } + + ret = xbr818_enable_i2c(dev); + if (ret != 0) { + return ret; + } + + if (attr == SENSOR_ATTR_LOWER_THRESH) { + if (val->val1 > 0xFFFF || val->val1 < 0) { + return -EINVAL; + } + tmp[0] = val->val1 & 0xFF; + tmp[1] = (val->val1 & 0xFF00) >> 8; + ret = i2c_burst_write_dt(&config->i2c, XBR818_THRESHOLD_1, tmp, 2); + } else if ((enum sensor_attribute_xbr818)attr == SENSOR_ATTR_XBR818_NOISE_FLOOR) { + if (val->val1 > 0xFFFF || val->val1 < 0) { + return -EINVAL; + } + tmp[0] = val->val1 & 0xFF; + tmp[1] = (val->val1 & 0xFF00) >> 8; + ret = i2c_burst_write_dt(&config->i2c, XBR818_THRESHOLD_NOISE_1, tmp, 2); + } else if ((enum sensor_attribute_xbr818)attr == SENSOR_ATTR_XBR818_DELAY_TIME) { + if (val->val1 < 0 || val->val2 < 0) { + return -EINVAL; + } + tmpf = (uint64_t)val->val1 * 1000000 + (uint64_t)val->val2; + tmpf = (tmpf * SENSOR_XBR818_CLOCKRATE) / 1000000; + if (tmpf > 0xFFFFFF) { + return -EINVAL; + } + tmp[0] = tmpf & 0xFF; + tmp[1] = (tmpf & 0xFF00) >> 8; + tmp[2] = (tmpf & 0xFF0000) >> 16; + ret = i2c_burst_write_dt(&config->i2c, XBR818_DELAY_TIME_1, tmp, 3); + } else if ((enum sensor_attribute_xbr818)attr == SENSOR_ATTR_XBR818_LOCK_TIME) { + if (val->val1 < 0 || val->val2 < 0) { + return -EINVAL; + } + tmpf = (uint64_t)val->val1 * 1000000 + (uint64_t)val->val2; + tmpf = (tmpf * SENSOR_XBR818_CLOCKRATE) / 1000000; + if (tmpf > 0xFFFFFF) { + return -EINVAL; + } + tmp[0] = tmpf & 0xFF; + tmp[1] = (tmpf & 0xFF00) >> 8; + tmp[2] = (tmpf & 0xFF0000) >> 16; + ret = i2c_burst_write_dt(&config->i2c, XBR818_LOCK_TIME_1, tmp, 3); + } else if ((enum sensor_attribute_xbr818)attr == SENSOR_ATTR_XBR818_RF_POWER) { + if (val->val1 > 0x7 || val->val1 < 0) { + return -EINVAL; + } + tmp[0] = val->val1 & 0x7; + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_RF_POWER, tmp[0]); + } else if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { + if (val->val1 > SENSOR_XBR818_CLOCKRATE || val->val1 <= 0) { + return -EINVAL; + } + tmp[0] = SENSOR_XBR818_CLOCKRATE / val->val1; + if (tmp[0] > 0xFF) { + return -EINVAL; + } + ret = i2c_reg_write_byte_dt(&config->i2c, XBR818_SAMPLE_RATE_DIVIDER, tmp[0]); + } else { + ret = xbr818_disable_i2c(dev); + if (ret != 0) { + return ret; + } + return -ENODEV; + } + + if (ret != 0) { + return ret; + } + + ret = xbr818_disable_i2c(dev); + + return ret; +} + +static int xbr818_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + const struct xbr818_config *config = dev->config; + int ret; + uint8_t tmp[3]; + uint64_t tmpf; + + if (chan != SENSOR_CHAN_PROX) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } + + ret = xbr818_enable_i2c(dev); + if (ret != 0) { + return ret; + } + + if (attr == SENSOR_ATTR_LOWER_THRESH) { + ret = i2c_burst_read_dt(&config->i2c, XBR818_THRESHOLD_1, tmp, 2); + if (ret != 0) { + return ret; + } + val->val1 = tmp[0] & 0xFF; + val->val1 |= (uint32_t)tmp[1] << 8; + } else if ((enum sensor_attribute_xbr818)attr == SENSOR_ATTR_XBR818_NOISE_FLOOR) { + ret = i2c_burst_read_dt(&config->i2c, XBR818_THRESHOLD_NOISE_1, tmp, 2); + if (ret != 0) { + return ret; + } + val->val1 = tmp[0] & 0xFF; + val->val1 |= (uint32_t)tmp[1] << 8; + } else if ((enum sensor_attribute_xbr818)attr == SENSOR_ATTR_XBR818_DELAY_TIME) { + ret = i2c_burst_read_dt(&config->i2c, XBR818_DELAY_TIME_1, tmp, 3); + if (ret != 0) { + return ret; + } + val->val1 = tmp[0] & 0xFF; + val->val1 |= (uint32_t)tmp[1] << 8; + val->val1 |= (uint32_t)tmp[2] << 16; + tmpf = (uint64_t)val->val1 * 1000000; + tmpf /= SENSOR_XBR818_CLOCKRATE; + val->val1 = tmpf / 1000000; + val->val2 = tmpf - val->val1 * 1000000; + } else if ((enum sensor_attribute_xbr818)attr == SENSOR_ATTR_XBR818_LOCK_TIME) { + ret = i2c_burst_read_dt(&config->i2c, XBR818_LOCK_TIME_1, tmp, 3); + if (ret != 0) { + return ret; + } + val->val1 = tmp[0] & 0xFF; + val->val1 |= (uint32_t)tmp[1] << 8; + val->val1 |= (uint32_t)tmp[2] << 16; + tmpf = (uint64_t)val->val1 * 1000000; + tmpf /= SENSOR_XBR818_CLOCKRATE; + val->val1 = tmpf / 1000000; + val->val2 = tmpf - val->val1 * 1000000; + } else if ((enum sensor_attribute_xbr818)attr == SENSOR_ATTR_XBR818_RF_POWER) { + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_RF_POWER, tmp); + if (ret != 0) { + return ret; + } + val->val1 = *tmp & 0x7; + } else if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { + ret = i2c_reg_read_byte_dt(&config->i2c, XBR818_SAMPLE_RATE_DIVIDER, tmp); + if (ret != 0) { + return ret; + } + val->val1 = SENSOR_XBR818_CLOCKRATE / *tmp; + } else { + ret = xbr818_disable_i2c(dev); + if (ret != 0) { + return ret; + } + return -ENODEV; + } + + ret = xbr818_disable_i2c(dev); + + return ret; +} + +static void xbr818_work(struct k_work *work) +{ + struct xbr818_data *data = CONTAINER_OF(work, struct xbr818_data, work); + + if (likely(data->handler != NULL)) { + data->handler(data->dev, data->trigger); + } +} + +static void xbr818_gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct xbr818_data *data = CONTAINER_OF(cb, struct xbr818_data, gpio_cb); + + k_work_submit(&data->work); +} + +static int xbr818_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + const struct xbr818_config *config = dev->config; + struct xbr818_data *data = dev->data; + int ret; + + if (trig->chan != SENSOR_CHAN_PROX) { + LOG_ERR("%s: requesting unsupported channel %i", dev->name, trig->chan); + return -ENOTSUP; + } + + if (trig->type != SENSOR_TRIG_MOTION) { + LOG_ERR("%s: requesting unsupported trigger %i", dev->name, trig->type); + return -ENOTSUP; + } + + data->handler = handler; + data->trigger = trig; + ret = gpio_pin_interrupt_configure_dt(&config->io_val, GPIO_INT_EDGE_RISING); + if (ret < 0) { + return ret; + } + + if (handler) { + ret = gpio_add_callback(config->io_val.port, &data->gpio_cb); + } else { + ret = gpio_remove_callback(config->io_val.port, &data->gpio_cb); + } + + return ret; +} + +static int xbr818_init_defaults(const struct device *dev) +{ + const struct xbr818_config *config = dev->config; + int ret = 0; + uint8_t data[3]; + + ret |= i2c_reg_write_byte_dt(&config->i2c, XBR818_IO_ACTIVE_VALUE_REG, 0x03); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_IO_ACTIVE_VALUE_REG"); + ret |= i2c_reg_write_byte_dt(&config->i2c, XBR818_RF_EN_SEL, 0x20); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_RF_EN_SEL"); + ret |= i2c_reg_write_byte_dt(&config->i2c, XBR818_SAMPLE_RATE_DIVIDER, 0x20); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_SAMPLE_RATE_DIVIDER"); + ret |= i2c_reg_write_byte_dt(&config->i2c, XBR818_RF_POWER, 0x45); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_RF_POWER"); + ret |= i2c_reg_write_byte_dt(&config->i2c, XBR818_TIMER_CTRL, 0x21); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_TIMER_CTRL"); + + data[0] = 0x5a; + data[1] = 0x01; + ret |= i2c_burst_write_dt(&config->i2c, XBR818_THRESHOLD_1, data, 2); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_THRESHOLD"); + + data[0] = 0x55; + data[1] = 0x01; + ret |= i2c_burst_write_dt(&config->i2c, XBR818_THRESHOLD_NOISE_1, data, 2); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_THRESHOLD_NOISE"); + + /* 0.1 seconds */ + data[0] = 0x80; + data[1] = 0x0C; + data[2] = 0x00; + ret |= i2c_burst_write_dt(&config->i2c, XBR818_DELAY_TIME_1, data, 3); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_DELAY_TIME"); + + /* 0.5 seconds */ + data[0] = 0x80; + data[1] = 0x3E; + data[2] = 0x00; + ret |= i2c_burst_write_dt(&config->i2c, XBR818_LOCK_TIME_1, data, 3); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_LOCK_TIME"); + + ret |= i2c_reg_write_byte_dt(&config->i2c, XBR818_PIN_SETTINGS, 0x0C); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_PIN_SETTINGS"); + + ret |= i2c_reg_write_byte_dt(&config->i2c, XBR818_I2C_OUT, 0x1); + __ASSERT(ret == 0, "Error sending XBR818 defaults for XBR818_I2C_OUT"); + + return ret; +} + +static int xbr818_init(const struct device *dev) +{ + const struct xbr818_config *config = dev->config; + struct xbr818_data *data = dev->data; + int ret; + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C device not ready"); + return -ENODEV; + } + + data->dev = dev; + data->work.handler = xbr818_work; + + ret = gpio_pin_configure_dt(&config->io_val, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("%s: could not configure io_val(int) pin", dev->name); + return ret; + } + + if (config->i2c_en.port) { + ret = gpio_pin_configure_dt(&config->i2c_en, GPIO_OUTPUT); + if (ret != 0) { + LOG_ERR("%s: could not configure i2c_en pin", dev->name); + return ret; + } + } + + ret = xbr818_enable_i2c(dev); + if (ret != 0) { + return ret; + } + + ret = xbr818_init_defaults(dev); + if (ret != 0) { + LOG_ERR("%s: unable to configure", dev->name); + } + + ret = xbr818_disable_i2c(dev); + if (ret != 0) { + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->io_val, GPIO_INT_DISABLE); + if (ret) { + LOG_ERR("%s: failed to configure gpio interrupt: %d", dev->name, ret); + return ret; + } + + gpio_init_callback(&data->gpio_cb, xbr818_gpio_callback, BIT(config->io_val.pin)); + + return ret; +} + +static DEVICE_API(sensor, xbr818_api) = { + .sample_fetch = xbr818_sample_fetch, + .channel_get = xbr818_channel_get, + .attr_set = xbr818_attr_set, + .attr_get = xbr818_attr_get, + .trigger_set = xbr818_trigger_set, +}; + +#define XBR818_INIT(inst) \ + static const struct xbr818_config xbr818_##inst##_config = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + .i2c_en = GPIO_DT_SPEC_GET_OR(DT_INST(inst, phosense_xbr818), i2c_en_gpios, {0}), \ + .io_val = GPIO_DT_SPEC_GET(DT_INST(inst, phosense_xbr818), int_gpios), \ + }; \ + \ + static struct xbr818_data xbr818_##inst##_data; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, xbr818_init, NULL, &xbr818_##inst##_data, \ + &xbr818_##inst##_config, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &xbr818_api); + +DT_INST_FOREACH_STATUS_OKAY(XBR818_INIT); diff --git a/drivers/sensor/xbr818/xbr818.h b/drivers/sensor/xbr818/xbr818.h new file mode 100644 index 0000000000000..f30f6d5ed0d48 --- /dev/null +++ b/drivers/sensor/xbr818/xbr818.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_XBR818_XBR818_H_ +#define ZEPHYR_DRIVERS_SENSOR_XBR818_XBR818_H_ + +#include +#include +#include +#include + +/* 32Khz clockrate, most time values are multiple of this */ +#define SENSOR_XBR818_CLOCKRATE 32000 + +struct xbr818_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec i2c_en; + struct gpio_dt_spec io_val; +}; + +struct xbr818_data { + bool value; + uint32_t trigger_type; + sensor_trigger_handler_t handler; + struct gpio_callback gpio_cb; + const struct sensor_trigger *trigger; + const struct device *dev; + struct k_work work; +}; + +/* reference rd-04 module manual for more information */ +/* [0-2]: power of PA + * [4-6]: mixer trim + */ +#define XBR818_RF_POWER 0x03 +#define XBR818_RF_EN_SEL 0x04 +/* minimum value of 2 */ +#define XBR818_SAMPLE_RATE_DIVIDER 0x10 +/* [0]: enable detection + * [1-2]: readable data. 0: det_dc_sum 1: det_ac_sum 2: det_dc_used 3: det_noise + * [3]: enable read on 0x28-0x29 + * [4]: signal detection threshold. 0: auto by pin 1: register + * [7]: enable read on 0x26-0x29 + */ +#define XBR818_I2C_OUT 0x13 +/* Threshold for detection + * [0-7] + */ +#define XBR818_THRESHOLD_1 0x18 +/* [8-15] */ +#define XBR818_THRESHOLD_2 0x19 +/* Threshold for noise + * [0-7] + */ +#define XBR818_THRESHOLD_NOISE_1 0x1A +/* [8-15] */ +#define XBR818_THRESHOLD_NOISE_2 0x1B +/* Delay Time (in 1/32000 seconds) + * [0-7] + */ +#define XBR818_DELAY_TIME_1 0x1D +/* [8-15] */ +#define XBR818_DELAY_TIME_2 0x1E +/* [16-23] */ +#define XBR818_DELAY_TIME_3 0x1F +/* [0]: enable + * [1-2]: light sensor timer. 0: disabled 1: 4 sec 2: 1 minute 3: 1 hour + * [3-4]: output timer. 0: 1 sec 1: 1 minute 2: 1 hour 3: 1 day + * [5]: delay time. 0: 'configure by pin' 1: configure by register + */ +#define XBR818_TIMER_CTRL 0x1C +/* Lock Time (in 1/32000 seconds) + * [0-7] + */ +#define XBR818_LOCK_TIME_1 0x20 +/* [8-15] */ +#define XBR818_LOCK_TIME_2 0x21 +/* [16-23] */ +#define XBR818_LOCK_TIME_3 0x22 +/* Pin settings + * [0-3]: IO_VAL pin + * 0xc: io_value_out, 0xd: io_value_out inverted, 0xf: GPIO + * [4-7]: INT_IRQ pin + * 0x0: t3_int_irq, 0x9: io_value_out, 0xa: io_value_out inverted, 0xf: GPIO + */ +#define XBR818_PIN_SETTINGS 0x23 +/* [0]: ADC1 is configured for VCO trimming. 0: enable, 1: disable + * [1]: Low power mode is pin or register. 0: pin 1: register + * [2]: If IO_VAL pin is GPIO, output. 0: no 1: yes + * [3]: if INT_IRQ pin is GPIO, output. 0:no 1:yes + */ +#define XBR818_IO_ACTIVE_VALUE_REG 0x24 + +#endif /* ZEPHYR_DRIVERS_SENSOR_XBR818_XBR818_H_ */ diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 15afe117e477e..05ef5c3bdfcdf 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -8,6 +8,8 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_SERIAL_TEST serial_test.c) zephyr_library_sources_ifdef(CONFIG_UART_ASYNC_RX_HELPER uart_async_rx.c) zephyr_library_sources_ifdef(CONFIG_UART_ASYNC_TO_INT_DRIVEN_API uart_async_to_irq.c) +zephyr_library_sources_ifdef(CONFIG_UART_SHELL uart_shell.c) +zephyr_library_sources_ifdef(CONFIG_USBD_CDC_ACM_CLASS ${ZEPHYR_BASE}/misc/empty_file.c) zephyr_library_sources_ifdef(CONFIG_USB_CDC_ACM ${ZEPHYR_BASE}/misc/empty_file.c) # zephyr-keep-sorted-stop @@ -20,6 +22,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_APBUART uart_apbuart.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_UART_BT uart_bt.c) zephyr_library_sources_ifdef(CONFIG_UART_CC13XX_CC26XX uart_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_UART_CC23X0 uart_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_UART_CC32XX uart_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_UART_CDNS uart_cdns.c) zephyr_library_sources_ifdef(CONFIG_UART_CMSDK_APB uart_cmsdk_apb.c) @@ -36,6 +39,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_ITE_IT8XXX2 uart_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_UART_LITEX uart_litex.c) zephyr_library_sources_ifdef(CONFIG_UART_LPC11U6X uart_lpc11u6x.c) zephyr_library_sources_ifdef(CONFIG_UART_MAX32 uart_max32.c) +zephyr_library_sources_ifdef(CONFIG_UART_MCHP_MEC5 uart_mchp_mec5.c) zephyr_library_sources_ifdef(CONFIG_UART_MCUX uart_mcux.c) zephyr_library_sources_ifdef(CONFIG_UART_MCUX_FLEXCOMM uart_mcux_flexcomm.c) zephyr_library_sources_ifdef(CONFIG_UART_MCUX_IUART uart_mcux_iuart.c) @@ -58,7 +62,9 @@ zephyr_library_sources_ifdef(CONFIG_UART_QUICKLOGIC_USBSERIALPORT_S3B uart_ql_us zephyr_library_sources_ifdef(CONFIG_UART_RA8_SCI_B uart_renesas_ra8_sci_b.c) zephyr_library_sources_ifdef(CONFIG_UART_RCAR uart_rcar.c) zephyr_library_sources_ifdef(CONFIG_UART_RENESAS_RA uart_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_UART_RENESAS_RZ_SCIF uart_renesas_rz_scif.c) zephyr_library_sources_ifdef(CONFIG_UART_RPI_PICO_PIO uart_rpi_pico_pio.c) +zephyr_library_sources_ifdef(CONFIG_UART_RTS5912 uart_realtek_rts5912.c) zephyr_library_sources_ifdef(CONFIG_UART_RTT_DRIVER uart_rtt.c) zephyr_library_sources_ifdef(CONFIG_UART_RV32M1_LPUART uart_rv32m1_lpuart.c) zephyr_library_sources_ifdef(CONFIG_UART_RZT2M uart_rzt2m.c) @@ -68,6 +74,8 @@ zephyr_library_sources_ifdef(CONFIG_UART_SCI_RA uart_renesas_ra_sci.c) zephyr_library_sources_ifdef(CONFIG_UART_SEDI uart_sedi.c) zephyr_library_sources_ifdef(CONFIG_UART_SI32_USART uart_si32_usart.c) zephyr_library_sources_ifdef(CONFIG_UART_SIFIVE uart_sifive.c) +zephyr_library_sources_ifdef(CONFIG_UART_SILABS_EUSART uart_silabs_eusart.c) +zephyr_library_sources_ifdef(CONFIG_UART_SILABS_USART uart_silabs_usart.c) zephyr_library_sources_ifdef(CONFIG_UART_SMARTBOND uart_smartbond.c) zephyr_library_sources_ifdef(CONFIG_UART_STELLARIS uart_stellaris.c) zephyr_library_sources_ifdef(CONFIG_UART_STM32 uart_stm32.c) @@ -89,6 +97,8 @@ if (CONFIG_UART_NRFX_UARTE) if (CONFIG_UART_NRFX_UARTE_LEGACY_SHIM) zephyr_library_sources(uart_nrfx_uarte.c) else() + message(DEPRECATION + "Do not set CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=n as this option is deprecated.") zephyr_library_sources(uart_nrfx_uarte2.c) endif() endif() diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 9b76ac170c704..92e68f90741f2 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -148,6 +148,12 @@ config UART_ASYNC_TO_INT_DRIVEN_RX_TIMEOUT help Receiver inactivity timeout. It is used to calculate timeout in microseconds. +config UART_SHELL + bool "UART Shell commands" + depends on SHELL + help + UART Shell commands + comment "Serial Drivers" # zephyr-keep-sorted-start @@ -158,6 +164,7 @@ rsource "Kconfig.b91" rsource "Kconfig.bcm2711" rsource "Kconfig.bt" rsource "Kconfig.cc13xx_cc26xx" +rsource "Kconfig.cc23x0" rsource "Kconfig.cc32xx" rsource "Kconfig.cdns" rsource "Kconfig.cmsdk_apb" @@ -181,6 +188,7 @@ rsource "Kconfig.mcux_flexcomm" rsource "Kconfig.mcux_iuart" rsource "Kconfig.mcux_lpsci" rsource "Kconfig.mcux_lpuart" +rsource "Kconfig.mec5" rsource "Kconfig.miv" rsource "Kconfig.msp432p4xx" rsource "Kconfig.native_posix" @@ -199,6 +207,7 @@ rsource "Kconfig.ql_usbserialport_s3b" rsource "Kconfig.rcar" rsource "Kconfig.renesas_ra" rsource "Kconfig.renesas_ra8" +rsource "Kconfig.renesas_rz" rsource "Kconfig.rpi_pico" rsource "Kconfig.rtt" rsource "Kconfig.rv32m1_lpuart" @@ -206,6 +215,8 @@ rsource "Kconfig.rzt2m" rsource "Kconfig.sam0" rsource "Kconfig.sedi" rsource "Kconfig.sifive" +rsource "Kconfig.silabs_eusart" +rsource "Kconfig.silabs_usart" rsource "Kconfig.smartbond" rsource "Kconfig.stellaris" rsource "Kconfig.stm32" @@ -223,4 +234,6 @@ source "drivers/serial/Kconfig.si32" source "drivers/serial/Kconfig.wch_usart" +source "drivers/serial/Kconfig.realtek_rts5912" + endif # SERIAL diff --git a/drivers/serial/Kconfig.b91 b/drivers/serial/Kconfig.b91 index e7eb9d1f579f8..3664d1cb8e58a 100644 --- a/drivers/serial/Kconfig.b91 +++ b/drivers/serial/Kconfig.b91 @@ -9,5 +9,6 @@ config UART_TELINK_B91 depends on DT_HAS_TELINK_B91_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT + select PINCTRL help This option enables the B91 serial driver. diff --git a/drivers/serial/Kconfig.cc13xx_cc26xx b/drivers/serial/Kconfig.cc13xx_cc26xx index bae19b38ffb92..4c17db3764ef0 100644 --- a/drivers/serial/Kconfig.cc13xx_cc26xx +++ b/drivers/serial/Kconfig.cc13xx_cc26xx @@ -9,5 +9,6 @@ config UART_CC13XX_CC26XX depends on DT_HAS_TI_CC13XX_CC26XX_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT + select PINCTRL help Enable the TI SimpleLink CC13xx / CC26xx UART driver. diff --git a/drivers/serial/Kconfig.cc23x0 b/drivers/serial/Kconfig.cc23x0 new file mode 100644 index 0000000000000..e285ee14671a8 --- /dev/null +++ b/drivers/serial/Kconfig.cc23x0 @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config UART_CC23X0 + bool "TI SimpleLink CC23x0 UART driver" + default y + depends on DT_HAS_TI_CC23X0_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + select PINCTRL + help + Enable the TI SimpleLink CC23x0 UART driver. diff --git a/drivers/serial/Kconfig.gecko b/drivers/serial/Kconfig.gecko index 6160845a36390..8bc311cd5232b 100644 --- a/drivers/serial/Kconfig.gecko +++ b/drivers/serial/Kconfig.gecko @@ -10,8 +10,6 @@ config UART_GECKO select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT select SOC_GECKO_USART - select PINCTRL if (SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2) - select CLOCK_CONTROL if SOC_FAMILY_SILABS_S2 - select PM_DEVICE if PM && SOC_FAMILY_SILABS_S2 + select PINCTRL if SOC_FAMILY_SILABS_S1 help Enable the Gecko uart driver. diff --git a/drivers/serial/Kconfig.ifx_cat1 b/drivers/serial/Kconfig.ifx_cat1 index 0c32b1cda3214..5ddfde91191b7 100644 --- a/drivers/serial/Kconfig.ifx_cat1 +++ b/drivers/serial/Kconfig.ifx_cat1 @@ -10,7 +10,9 @@ config UART_INFINEON_CAT1 depends on DT_HAS_INFINEON_CAT1_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT + select SERIAL_SUPPORT_ASYNC select USE_INFINEON_UART select PINCTRL + select DMA if UART_ASYNC_API help This option enables the UART driver for Infineon CAT1 family. diff --git a/drivers/serial/Kconfig.max32 b/drivers/serial/Kconfig.max32 index 99b5c7b45ef50..b2c86c2359eb2 100644 --- a/drivers/serial/Kconfig.max32 +++ b/drivers/serial/Kconfig.max32 @@ -10,7 +10,21 @@ config UART_MAX32 select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT select PINCTRL + select SERIAL_SUPPORT_ASYNC if DT_HAS_ADI_MAX32_DMA_ENABLED + select DMA if UART_ASYNC_API help This option enables the UART driver for MAX32 family of processors. Say y if you wish to use serial port on MAX32 MCU. + +if UART_MAX32 + +config UART_TX_CACHE_LEN + int "TX cache buffer size" + range 8 64 + default 8 + help + Size of UART transmit buffer that is used when source buffer + is not located in a DMA-able region. + +endif # UART_MAX32 diff --git a/drivers/serial/Kconfig.mcux_lpuart b/drivers/serial/Kconfig.mcux_lpuart index 5833c49268e27..58ccc999cdcb4 100644 --- a/drivers/serial/Kconfig.mcux_lpuart +++ b/drivers/serial/Kconfig.mcux_lpuart @@ -6,7 +6,7 @@ config UART_MCUX_LPUART bool "MCUX LPUART driver" default y - depends on DT_HAS_NXP_KINETIS_LPUART_ENABLED + depends on DT_HAS_NXP_LPUART_ENABLED depends on CLOCK_CONTROL select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT diff --git a/drivers/serial/Kconfig.mec5 b/drivers/serial/Kconfig.mec5 new file mode 100644 index 0000000000000..6c46bf9b9c601 --- /dev/null +++ b/drivers/serial/Kconfig.mec5 @@ -0,0 +1,27 @@ +# Microchip MEC5 UART + +# Copyright (c) 2024 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config UART_MCHP_MEC5 + bool "Microchip MEC5 family ns16550 compatible UART driver" + default y + depends on DT_HAS_MICROCHIP_MEC5_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + help + This option enables the UART driver for Microchip MEC5 + family processors. + +if UART_MCHP_MEC5 + +config UART_MCHP_MEC5_LINE_CTRL + bool "Serial Line Control for Apps" + depends on UART_LINE_CTRL + help + This enables the API for apps to control the serial line, + such as CTS and RTS. + + Says n if not sure. + +endif # UART_MCHP_MEC5 diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index 650404fceecb3..278540ce38244 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -32,12 +32,20 @@ config UART_NRFX_UARTE_LEGACY_SHIM bool "Legacy UARTE shim" depends on UART_NRFX_UARTE default y + help + Disabling this option is deprecated. + +config DEPRECATED_UART_NRFX_UARTE_LEGACY_SHIM + bool + default y if !UART_NRFX_UARTE_LEGACY_SHIM + depends on UART_NRFX_UARTE + select DEPRECATED config UART_NRFX_UARTE_ENHANCED_RX bool "Enhanced RX handling" depends on UART_ASYNC_API depends on UART_NRFX_UARTE_LEGACY_SHIM - default y if !(UART_0_NRF_HW_ASYNC || UART_1_NRF_HW_ASYNC || UART_2_NRF_HW_ASYNC) + default y help Enable RX handling mode which is switching buffers on timeout. This is an enhancement compared to other two modes (default and hardware assisted). @@ -101,6 +109,11 @@ rsource "Kconfig.nrfx_uart_instance" endif if HAS_HW_NRF_UARTE120 + +config UART_NRFX_UARTE_USE_CLOCK_CONTROL + def_bool y + select CLOCK_CONTROL + nrfx_uart_num = 120 rsource "Kconfig.nrfx_uart_instance" endif diff --git a/drivers/serial/Kconfig.nrfx_uart_instance b/drivers/serial/Kconfig.nrfx_uart_instance index f75ee78c62b35..fa93a8144828f 100644 --- a/drivers/serial/Kconfig.nrfx_uart_instance +++ b/drivers/serial/Kconfig.nrfx_uart_instance @@ -20,7 +20,7 @@ config UART_$(nrfx_uart_num)_ASYNC config UART_$(nrfx_uart_num)_ENHANCED_POLL_OUT bool "Efficient poll out on port $(nrfx_uart_num)" - depends on !$(dt_nodelabel_has_prop,uart$(nrfx_uart_num),endtx-stoptx-supported) + depends on !$(dt_nodelabel_bool_prop,uart$(nrfx_uart_num),endtx-stoptx-supported) default y depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) depends on HAS_HW_NRF_PPI || HAS_HW_NRF_DPPIC @@ -49,18 +49,23 @@ config UART_$(nrfx_uart_num)_NRF_TX_BUFFER_SIZE particular SoC. config UART_$(nrfx_uart_num)_NRF_HW_ASYNC - bool "Use hardware RX byte counting" + bool "[DEPRECATED] Use hardware RX byte counting" depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) depends on UART_ASYNC_API depends on UART_NRFX_UARTE_LEGACY_SHIM + depends on !UART_NRFX_UARTE_ENHANCED_RX depends on HAS_HW_NRF_PPI || HAS_HW_NRF_DPPIC select NRFX_GPPI + select DEPRECATED help If default driver uses interrupts to count incoming bytes, it is possible that with higher speeds and/or high cpu load some data can be lost. It is recommended to use hardware byte counting in such scenarios. Hardware RX byte counting requires timer instance and one PPI channel. + This options is deprecated. Use UART_NRFX_UARTE_ENHANCED_RX which supports + reliable byte counting without additional HW resources (TIMER and (D)PPI). + config UART_$(nrfx_uart_num)_NRF_ASYNC_LOW_POWER bool "Low power mode" depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index fb7bcebe098ae..4c6676cdab64f 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -6,6 +6,7 @@ menuconfig UART_NS16550 depends on DT_HAS_NS16550_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT + select PINCTRL if $(dt_compat_any_has_prop,$(DT_COMPAT_NS16550),pinctrl-0) help This option enables the NS16550 serial driver. This driver can be used for the serial hardware diff --git a/drivers/serial/Kconfig.pl011 b/drivers/serial/Kconfig.pl011 index e68771f97e9e4..b03133707aab9 100644 --- a/drivers/serial/Kconfig.pl011 +++ b/drivers/serial/Kconfig.pl011 @@ -7,9 +7,7 @@ menuconfig UART_PL011 depends on DT_HAS_ARM_PL011_ENABLED || DT_HAS_ARM_SBSA_UART_ENABLED select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT - select PINCTRL if SOC_EOS_S3 - select PINCTRL if DT_HAS_AMBIQ_UART_ENABLED - select PINCTRL if DT_HAS_RASPBERRYPI_PICO_UART_ENABLED + select PINCTRL if $(dt_compat_any_has_prop,$(DT_COMPAT_ARM_PL011),pinctrl-0) help This option enables the UART driver for the PL011 diff --git a/drivers/serial/Kconfig.realtek_rts5912 b/drivers/serial/Kconfig.realtek_rts5912 new file mode 100644 index 0000000000000..fd4c32c3c5f7c --- /dev/null +++ b/drivers/serial/Kconfig.realtek_rts5912 @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config UART_RTS5912 + bool "UART driver for Realtek RTS5912 EC" + depends on SOC_SERIES_RTS5912 + default y if DT_HAS_REALTEK_RTS5912_UART_ENABLED + select PINCTRL + select CLOCK_CONTROL + help + This option enables the RTS5912 UART wrapper driver. + +config UART_RTS5912_INIT_PRIORITY + int "RTS5912 UART wrapper init priority" + default 49 + depends on UART_RTS5912 + help + Initialization priority for Realtek RTS5912 UART wrapper driver. diff --git a/drivers/serial/Kconfig.renesas_rz b/drivers/serial/Kconfig.renesas_rz new file mode 100644 index 0000000000000..ea904e2c2e51f --- /dev/null +++ b/drivers/serial/Kconfig.renesas_rz @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config UART_RENESAS_RZ_SCIF + bool "Renesas RZ SCIF UART" + default y + depends on DT_HAS_RENESAS_RZ_SCIF_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + select USE_RZ_FSP_SCIF_UART + select PINCTRL + help + Enable Renesas RZ SCIF UART Driver. + +if UART_RENESAS_RZ_SCIF + +config UART_RENESAS_RZG_INIT_DELAY_MS + int "UART initialization delay in milliseconds" + default 8000 + help + This option is to make a delay to wait for the A55 to complete its setting first + before UART initialization of M33. + +endif diff --git a/drivers/serial/Kconfig.silabs_eusart b/drivers/serial/Kconfig.silabs_eusart new file mode 100644 index 0000000000000..156a75c4ec3bc --- /dev/null +++ b/drivers/serial/Kconfig.silabs_eusart @@ -0,0 +1,15 @@ +# Copyright (c) 2024, Yishai Jaffe +# SPDX-License-Identifier: Apache-2.0 + +config UART_SILABS_EUSART + bool "Silabs EUSART UART driver" + default y + depends on DT_HAS_SILABS_EUSART_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + select SOC_GECKO_EUSART + select PINCTRL + select CLOCK_CONTROL + select PM_DEVICE if PM + help + Enable the eusart uart driver. diff --git a/drivers/serial/Kconfig.silabs_usart b/drivers/serial/Kconfig.silabs_usart new file mode 100644 index 0000000000000..078e09db9a870 --- /dev/null +++ b/drivers/serial/Kconfig.silabs_usart @@ -0,0 +1,17 @@ +# Copyright (c) 2025, Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config UART_SILABS_USART + bool "Silabs USART UART driver" + default y + depends on DT_HAS_SILABS_USART_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + select SOC_GECKO_USART + select SERIAL_SUPPORT_ASYNC \ + if DT_HAS_SILABS_LDMA_ENABLED + select DMA if UART_ASYNC_API + select PINCTRL + select CLOCK_CONTROL + help + Enable the Silicon Labs usart driver. diff --git a/drivers/serial/Kconfig.sy1xx b/drivers/serial/Kconfig.sy1xx index 2f345b6379421..5d6de8234e861 100644 --- a/drivers/serial/Kconfig.sy1xx +++ b/drivers/serial/Kconfig.sy1xx @@ -6,5 +6,6 @@ config UART_SY1XX default y depends on DT_HAS_SENSRY_SY1XX_UART_ENABLED select SERIAL_HAS_DRIVER + select PINCTRL help Driver for Sensry Sy1xx series uart. diff --git a/drivers/serial/Kconfig.wch_usart b/drivers/serial/Kconfig.wch_usart index e60c9ad794cbf..815c2e67dcd18 100644 --- a/drivers/serial/Kconfig.wch_usart +++ b/drivers/serial/Kconfig.wch_usart @@ -6,6 +6,7 @@ config UART_WCH_USART default y depends on DT_HAS_WCH_USART_ENABLED select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT select PINCTRL help This option enables the USART driver for CH32V00x SoC family. diff --git a/drivers/serial/uart_altera.c b/drivers/serial/uart_altera.c index 9a5392c7b13ce..a9f469f3eea83 100644 --- a/drivers/serial/uart_altera.c +++ b/drivers/serial/uart_altera.c @@ -960,12 +960,9 @@ static struct uart_altera_device_data uart_altera_dev_data_##n = { \ .uart_cfg = \ { \ .baudrate = DT_INST_PROP(n, current_speed), \ - .parity = DT_INST_ENUM_IDX_OR(n, parity, \ - UART_CFG_PARITY_NONE), \ - .stop_bits = DT_INST_ENUM_IDX_OR(n, stop_bits, \ - UART_CFG_STOP_BITS_1), \ - .data_bits = DT_INST_ENUM_IDX_OR(n, data_bits, \ - UART_CFG_DATA_BITS_8), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ + .stop_bits = DT_INST_ENUM_IDX(n, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(n, data_bits), \ .flow_ctrl = DT_INST_PROP(n, hw_flow_control) ? \ UART_CFG_FLOW_CTRL_RTS_CTS : \ UART_CFG_FLOW_CTRL_NONE, \ diff --git a/drivers/serial/uart_async_to_irq.c b/drivers/serial/uart_async_to_irq.c index 762c4462837c9..45c190a14fab2 100644 --- a/drivers/serial/uart_async_to_irq.c +++ b/drivers/serial/uart_async_to_irq.c @@ -56,6 +56,8 @@ static uint32_t get_rx_timeout(const struct device *dev) baudrate = get_config(dev)->baudrate; } + __ASSERT_NO_MSG(baudrate != 0); + uint32_t us = (CONFIG_UART_ASYNC_TO_INT_DRIVEN_RX_TIMEOUT * 1000000) / baudrate; return us; diff --git a/drivers/serial/uart_cc13xx_cc26xx.c b/drivers/serial/uart_cc13xx_cc26xx.c index 969c8df5ec2d6..7d286a9ba5e24 100644 --- a/drivers/serial/uart_cc13xx_cc26xx.c +++ b/drivers/serial/uart_cc13xx_cc26xx.c @@ -617,9 +617,9 @@ static DEVICE_API(uart, uart_cc13xx_cc26xx_driver_api) = { uart_cc13xx_cc26xx_data_##n = { \ .uart_config = { \ .baudrate = DT_INST_PROP(n, current_speed), \ - .parity = UART_CFG_PARITY_NONE, \ - .stop_bits = UART_CFG_STOP_BITS_1, \ - .data_bits = UART_CFG_DATA_BITS_8, \ + .parity = DT_INST_ENUM_IDX(n, parity), \ + .stop_bits = DT_INST_ENUM_IDX(n, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(n, data_bits), \ .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, \ }, \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ diff --git a/drivers/serial/uart_cc23x0.c b/drivers/serial/uart_cc23x0.c new file mode 100644 index 0000000000000..c26bb40e59fc4 --- /dev/null +++ b/drivers/serial/uart_cc23x0.c @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_uart + +#include +#include +#include +#include + +#include + +#include +#include + +struct uart_cc23x0_config { + uint32_t reg; + uint32_t sys_clk_freq; + const struct pinctrl_dev_config *pcfg; +}; + +struct uart_cc23x0_data { + struct uart_config uart_config; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t callback; + void *user_data; +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +static int uart_cc23x0_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uart_cc23x0_config *config = dev->config; + + if (!UARTCharAvailable(config->reg)) { + return -1; + } + + *c = UARTGetCharNonBlocking(config->reg); + + return 0; +} + +static void uart_cc23x0_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_cc23x0_config *config = dev->config; + + UARTPutChar(config->reg, c); +} + +static int uart_cc23x0_err_check(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + uint32_t flags = UARTGetRxError(config->reg); + int error = 0; + + error |= (flags & UART_RXERROR_FRAMING) ? UART_ERROR_FRAMING : 0; + error |= (flags & UART_RXERROR_PARITY) ? UART_ERROR_PARITY : 0; + error |= (flags & UART_RXERROR_BREAK) ? UART_BREAK : 0; + error |= (flags & UART_RXERROR_OVERRUN) ? UART_ERROR_OVERRUN : 0; + + UARTClearRxError(config->reg); + + return error; +} + +static int uart_cc23x0_configure(const struct device *dev, const struct uart_config *cfg) +{ + const struct uart_cc23x0_config *config = dev->config; + struct uart_cc23x0_data *data = dev->data; + uint32_t line_ctrl = 0; + bool flow_ctrl; + + switch (cfg->parity) { + case UART_CFG_PARITY_NONE: + line_ctrl |= UART_CONFIG_PAR_NONE; + break; + case UART_CFG_PARITY_ODD: + line_ctrl |= UART_CONFIG_PAR_ODD; + break; + case UART_CFG_PARITY_EVEN: + line_ctrl |= UART_CONFIG_PAR_EVEN; + break; + case UART_CFG_PARITY_MARK: + line_ctrl |= UART_CONFIG_PAR_ONE; + break; + case UART_CFG_PARITY_SPACE: + line_ctrl |= UART_CONFIG_PAR_ZERO; + break; + default: + return -EINVAL; + } + + switch (cfg->stop_bits) { + case UART_CFG_STOP_BITS_1: + line_ctrl |= UART_CONFIG_STOP_ONE; + break; + case UART_CFG_STOP_BITS_2: + line_ctrl |= UART_CONFIG_STOP_TWO; + break; + case UART_CFG_STOP_BITS_0_5: + case UART_CFG_STOP_BITS_1_5: + return -ENOTSUP; + default: + return -EINVAL; + } + + switch (cfg->data_bits) { + case UART_CFG_DATA_BITS_5: + line_ctrl |= UART_CONFIG_WLEN_5; + break; + case UART_CFG_DATA_BITS_6: + line_ctrl |= UART_CONFIG_WLEN_6; + break; + case UART_CFG_DATA_BITS_7: + line_ctrl |= UART_CONFIG_WLEN_7; + break; + case UART_CFG_DATA_BITS_8: + line_ctrl |= UART_CONFIG_WLEN_8; + break; + default: + return -EINVAL; + } + + switch (cfg->flow_ctrl) { + case UART_CFG_FLOW_CTRL_NONE: + flow_ctrl = false; + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + flow_ctrl = true; + break; + case UART_CFG_FLOW_CTRL_DTR_DSR: + return -ENOTSUP; + default: + return -EINVAL; + } + + /* Disables UART before setting control registers */ + UARTConfigSetExpClk(config->reg, config->sys_clk_freq, cfg->baudrate, line_ctrl); + + if (flow_ctrl) { + UARTEnableCTS(config->reg); + UARTEnableRTS(config->reg); + } else { + UARTDisableCTS(config->reg); + UARTDisableRTS(config->reg); + } + + /* Re-enable UART */ + UARTEnable(config->reg); + + /* Make use of the FIFO to reduce chances of data being lost */ + UARTEnableFifo(config->reg); + + data->uart_config = *cfg; + + return 0; +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +static int uart_cc23x0_config_get(const struct device *dev, struct uart_config *cfg) +{ + const struct uart_cc23x0_data *data = dev->data; + + *cfg = data->uart_config; + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static int uart_cc23x0_fifo_fill(const struct device *dev, const uint8_t *buf, int len) +{ + const struct uart_cc23x0_config *config = dev->config; + int n = 0; + + while (n < len) { + if (!UARTSpaceAvailable(config->reg)) { + break; + } + UARTPutCharNonBlocking(config->reg, buf[n]); + n++; + } + + return n; +} + +static int uart_cc23x0_fifo_read(const struct device *dev, uint8_t *buf, const int len) +{ + const struct uart_cc23x0_config *config = dev->config; + int c, n; + + n = 0; + while (n < len) { + if (!UARTCharAvailable(config->reg)) { + break; + } + c = UARTGetCharNonBlocking(config->reg); + buf[n++] = c; + } + + return n; +} + +static void uart_cc23x0_irq_tx_enable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + UARTEnableInt(config->reg, UART_INT_TX); +} + +static void uart_cc23x0_irq_tx_disable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + UARTDisableInt(config->reg, UART_INT_TX); +} + +static int uart_cc23x0_irq_tx_ready(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTSpaceAvailable(config->reg) ? 1 : 0; +} + +static void uart_cc23x0_irq_rx_enable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + /* Trigger the ISR on both RX and Receive Timeout. This is to allow + * the use of the hardware FIFOs for more efficient operation + */ + UARTEnableInt(config->reg, UART_INT_RX | UART_INT_RT); +} + +static void uart_cc23x0_irq_rx_disable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + UARTDisableInt(config->reg, UART_INT_RX | UART_INT_RT); +} + +static int uart_cc23x0_irq_tx_complete(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTBusy(config->reg) ? 0 : 1; +} + +static int uart_cc23x0_irq_rx_ready(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTCharAvailable(config->reg) ? 1 : 0; +} + +static void uart_cc23x0_irq_err_enable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTEnableInt(config->reg, UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE); +} + +static void uart_cc23x0_irq_err_disable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTDisableInt(config->reg, UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE); +} + +static int uart_cc23x0_irq_is_pending(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + /* Read masked interrupt status */ + uint32_t status = UARTIntStatus(config->reg, true); + + return status ? 1 : 0; +} + +static int uart_cc23x0_irq_update(const struct device *dev) +{ + ARG_UNUSED(dev); + return 1; +} + +static void uart_cc23x0_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct uart_cc23x0_data *data = dev->data; + + data->callback = cb; + data->user_data = user_data; +} + +static void uart_cc23x0_isr(const struct device *dev) +{ + struct uart_cc23x0_data *data = dev->data; + + if (data->callback) { + data->callback(dev, data->user_data); + } +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static DEVICE_API(uart, uart_cc23x0_driver_api) = { + .poll_in = uart_cc23x0_poll_in, + .poll_out = uart_cc23x0_poll_out, + .err_check = uart_cc23x0_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_cc23x0_configure, + .config_get = uart_cc23x0_config_get, +#endif +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_cc23x0_fifo_fill, + .fifo_read = uart_cc23x0_fifo_read, + .irq_tx_enable = uart_cc23x0_irq_tx_enable, + .irq_tx_disable = uart_cc23x0_irq_tx_disable, + .irq_tx_ready = uart_cc23x0_irq_tx_ready, + .irq_rx_enable = uart_cc23x0_irq_rx_enable, + .irq_rx_disable = uart_cc23x0_irq_rx_disable, + .irq_tx_complete = uart_cc23x0_irq_tx_complete, + .irq_rx_ready = uart_cc23x0_irq_rx_ready, + .irq_err_enable = uart_cc23x0_irq_err_enable, + .irq_err_disable = uart_cc23x0_irq_err_disable, + .irq_is_pending = uart_cc23x0_irq_is_pending, + .irq_update = uart_cc23x0_irq_update, + .irq_callback_set = uart_cc23x0_irq_callback_set, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define UART_CC23X0_IRQ_CFG(n) \ + do { \ + UARTClearInt(config->reg, UART_INT_RX); \ + UARTClearInt(config->reg, UART_INT_RT); \ + \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), uart_cc23x0_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } while (false) + +#define UART_CC23X0_INT_FIELDS .callback = NULL, .user_data = NULL, +#else +#define UART_CC23X0_IRQ_CFG(n) +#define UART_CC23X0_INT_FIELDS +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#define UART_CC23X0_DEVICE_DEFINE(n) \ + \ + DEVICE_DT_INST_DEFINE(n, uart_cc23x0_init_##n, NULL, &uart_cc23x0_data_##n, \ + &uart_cc23x0_config_##n, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_cc23x0_driver_api) + +#define UART_CC23X0_INIT_FUNC(n) \ + static int uart_cc23x0_init_##n(const struct device *dev) \ + { \ + const struct uart_cc23x0_config *config = dev->config; \ + struct uart_cc23x0_data *data = dev->data; \ + int ret; \ + \ + CLKCTLEnable(CLKCTL_BASE, CLKCTL_UART0); \ + \ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); \ + if (ret < 0) { \ + return ret; \ + } \ + \ + /* Configure and enable UART */ \ + ret = uart_cc23x0_configure(dev, &data->uart_config); \ + \ + /* Enable interrupts */ \ + UART_CC23X0_IRQ_CFG(n); \ + \ + return ret; \ + } + +#define UART_CC23X0_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + UART_CC23X0_INIT_FUNC(n); \ + \ + static struct uart_cc23x0_config uart_cc23x0_config_##n = { \ + .reg = DT_INST_REG_ADDR(n), \ + .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(n, clocks, clock_frequency), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + static struct uart_cc23x0_data uart_cc23x0_data_##n = { \ + .uart_config = \ + { \ + .baudrate = DT_INST_PROP(n, current_speed), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ + .stop_bits = DT_INST_ENUM_IDX(n, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(n, data_bits), \ + .flow_ctrl = DT_INST_PROP(n, hw_flow_control), \ + }, \ + UART_CC23X0_INT_FIELDS \ + }; \ + UART_CC23X0_DEVICE_DEFINE(n); + +DT_INST_FOREACH_STATUS_OKAY(UART_CC23X0_INIT) diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index 373260af5926e..53a2b4f2d6f2c 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -98,10 +98,15 @@ struct k_work_q uart_emul_work_q; int uart_emul_init_work_q(void) { + struct k_work_queue_config cfg = { + .name = "uart_emul_workq", + .no_yield = false, + }; + k_work_queue_init(&uart_emul_work_q); k_work_queue_start(&uart_emul_work_q, uart_emul_stack_area, K_THREAD_STACK_SIZEOF(uart_emul_stack_area), - CONFIG_UART_EMUL_WORK_Q_PRIORITY, NULL); + CONFIG_UART_EMUL_WORK_Q_PRIORITY, &cfg); return 0; } diff --git a/drivers/serial/uart_esp32.c b/drivers/serial/uart_esp32.c index b2d05e50b4806..47d652b829141 100644 --- a/drivers/serial/uart_esp32.c +++ b/drivers/serial/uart_esp32.c @@ -170,6 +170,29 @@ static int uart_esp32_err_check(const struct device *dev) } #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + +static uint32_t uart_esp32_get_standard_baud(uint32_t calc_baud) +{ + const uint32_t standard_bauds[] = {9600, 14400, 19200, 38400, 57600, + 74880, 115200, 230400, 460800, 921600}; + int num_bauds = ARRAY_SIZE(standard_bauds); + uint32_t baud = calc_baud; + + /* Find the standard baudrate within 0.1% range. If no close + * value is found, input is returned. + */ + for (int i = 0; i < num_bauds; i++) { + float range = (float)abs(calc_baud - standard_bauds[i]) / standard_bauds[i]; + + if (range < 0.001f) { + baud = standard_bauds[i]; + break; + } + } + + return baud; +} + static int uart_esp32_config_get(const struct device *dev, struct uart_config *cfg) { struct uart_esp32_data *data = dev->data; @@ -179,11 +202,14 @@ static int uart_esp32_config_get(const struct device *dev, struct uart_config *c uart_hw_flowcontrol_t hw_flow; uart_sclk_t src_clk; uint32_t sclk_freq; + uint32_t calc_baud; uart_hal_get_sclk(&data->hal, &src_clk); esp_clk_tree_src_get_freq_hz((soc_module_clk_t)src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq); - uart_hal_get_baudrate(&data->hal, &cfg->baudrate, sclk_freq); + + uart_hal_get_baudrate(&data->hal, &calc_baud, sclk_freq); + cfg->baudrate = uart_esp32_get_standard_baud(calc_baud); uart_hal_get_parity(&data->hal, &parity); switch (parity) { @@ -276,6 +302,7 @@ static int uart_esp32_configure(const struct device *dev, const struct uart_conf uart_hal_set_rxfifo_full_thr(&data->hal, UART_RX_FIFO_THRESH); uart_hal_set_txfifo_empty_thr(&data->hal, UART_TX_FIFO_THRESH); uart_hal_rxfifo_rst(&data->hal); + uart_hal_txfifo_rst(&data->hal); switch (cfg->parity) { case UART_CFG_PARITY_NONE: @@ -1028,11 +1055,9 @@ static DEVICE_API(uart, uart_esp32_api) = { \ static struct uart_esp32_data uart_esp32_data_##idx = { \ .uart_config = {.baudrate = DT_INST_PROP(idx, current_speed), \ - .parity = DT_INST_ENUM_IDX_OR(idx, parity, UART_CFG_PARITY_NONE), \ - .stop_bits = DT_INST_ENUM_IDX_OR(idx, stop_bits, \ - UART_CFG_STOP_BITS_1), \ - .data_bits = DT_INST_ENUM_IDX_OR(idx, data_bits, \ - UART_CFG_DATA_BITS_8), \ + .parity = DT_INST_ENUM_IDX(idx, parity), \ + .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \ .flow_ctrl = MAX(COND_CODE_1(DT_INST_PROP(idx, hw_rs485_hd_mode), \ (UART_CFG_FLOW_CTRL_RS485), \ (UART_CFG_FLOW_CTRL_NONE)), \ diff --git a/drivers/serial/uart_gecko.c b/drivers/serial/uart_gecko.c index ceecde5d229ef..78665dcd0e260 100644 --- a/drivers/serial/uart_gecko.c +++ b/drivers/serial/uart_gecko.c @@ -19,13 +19,7 @@ #include #endif /* CONFIG_PINCTRL */ -#ifdef CONFIG_CLOCK_CONTROL -#include -#include -#define GET_GECKO_USART_CLOCK(idx) \ - .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ - .clock_cfg = SILABS_DT_INST_CLOCK_CFG(idx), -#elif DT_NODE_HAS_PROP(id, peripheral_id) +#if DT_NODE_HAS_PROP(id, peripheral_id) #define USART_PREFIX cmuClock_USART #define UART_PREFIX cmuClock_UART #define CLOCK_USART(id) _CONCAT(USART_PREFIX, id) @@ -130,18 +124,7 @@ struct uart_gecko_config { const struct pinctrl_dev_config *pcfg; #endif /* CONFIG_PINCTRL */ USART_TypeDef *base; -#ifdef CONFIG_CLOCK_CONTROL - const struct device *clock_dev; - const struct silabs_clock_control_cmu_config clock_cfg; -#else CMU_Clock_TypeDef clock; -#endif - uint32_t baud_rate; -#ifndef CONFIG_PINCTRL -#ifdef UART_GECKO_HW_FLOW_CONTROL - bool hw_flowcontrol; -#endif /* UART_GECKO_HW_FLOW_CONTROL */ -#endif #ifdef CONFIG_UART_INTERRUPT_DRIVEN void (*irq_config_func)(const struct device *dev); #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -166,6 +149,7 @@ struct uart_gecko_config { }; struct uart_gecko_data { + struct uart_config *uart_cfg; #ifdef CONFIG_UART_INTERRUPT_DRIVEN uart_irq_callback_user_data_t callback; void *cb_data; @@ -402,8 +386,10 @@ static void uart_gecko_init_pins(const struct device *dev) #endif /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */ #ifdef UART_GECKO_HW_FLOW_CONTROL + const struct uart_gecko_data *data = dev->data; + const struct uart_config *uart_cfg = data->uart_cfg; /* Configure HW flow control (RTS, CTS) */ - if (config->hw_flowcontrol) { + if (uart_cfg->flow_ctrl) { GPIO_PinModeSet(config->pin_rts.port, config->pin_rts.pin, config->pin_rts.mode, config->pin_rts.out); GPIO_PinModeSet(config->pin_cts.port, config->pin_cts.pin, @@ -438,6 +424,202 @@ static void uart_gecko_init_pins(const struct device *dev) } #endif /* !CONFIG_PINCTRL */ +static inline USART_Parity_TypeDef uart_gecko_cfg2ll_parity(enum uart_config_parity parity) +{ + switch (parity) { + case UART_CFG_PARITY_ODD: + return usartOddParity; + case UART_CFG_PARITY_EVEN: + return usartEvenParity; + case UART_CFG_PARITY_NONE: + default: + return usartNoParity; + } +} + +static inline enum uart_config_parity uart_gecko_ll2cfg_parity(USART_Parity_TypeDef parity) +{ + switch (parity) { + case usartOddParity: + return UART_CFG_PARITY_ODD; + case usartEvenParity: + return UART_CFG_PARITY_EVEN; + case usartNoParity: + default: + return UART_CFG_PARITY_NONE; + } +} + +static inline USART_Stopbits_TypeDef uart_gecko_cfg2ll_stopbits(enum uart_config_stop_bits sb) +{ + switch (sb) { + case UART_CFG_STOP_BITS_0_5: + return usartStopbits0p5; + case UART_CFG_STOP_BITS_1: + return usartStopbits1; + case UART_CFG_STOP_BITS_2: + return usartStopbits2; + case UART_CFG_STOP_BITS_1_5: + return usartStopbits1p5; + default: + return usartStopbits1; + } +} + +static inline enum uart_config_stop_bits uart_gecko_ll2cfg_stopbits(USART_Stopbits_TypeDef sb) +{ + switch (sb) { + case usartStopbits0p5: + return UART_CFG_STOP_BITS_0_5; + case usartStopbits1: + return UART_CFG_STOP_BITS_1; + case usartStopbits1p5: + return UART_CFG_STOP_BITS_1_5; + case usartStopbits2: + return UART_CFG_STOP_BITS_2; + default: + return UART_CFG_STOP_BITS_1; + } +} + +static inline USART_Databits_TypeDef uart_gecko_cfg2ll_databits(enum uart_config_data_bits db, + enum uart_config_parity p) +{ + switch (db) { + case UART_CFG_DATA_BITS_7: + if (p == UART_CFG_PARITY_NONE) { + return usartDatabits7; + } else { + return usartDatabits8; + } + case UART_CFG_DATA_BITS_9: + return usartDatabits9; + case UART_CFG_DATA_BITS_8: + default: + if (p == UART_CFG_PARITY_NONE) { + return usartDatabits8; + } else { + return usartDatabits9; + } + return usartDatabits8; + } +} + +static inline enum uart_config_data_bits uart_gecko_ll2cfg_databits(USART_Databits_TypeDef db, + USART_Parity_TypeDef p) +{ + switch (db) { + case usartDatabits7: + if (p == usartNoParity) { + return UART_CFG_DATA_BITS_7; + } else { + return UART_CFG_DATA_BITS_6; + } + case usartDatabits9: + if (p == usartNoParity) { + return UART_CFG_DATA_BITS_9; + } else { + return UART_CFG_DATA_BITS_8; + } + case usartDatabits8: + default: + if (p == usartNoParity) { + return UART_CFG_DATA_BITS_8; + } else { + return UART_CFG_DATA_BITS_7; + } + } +} + +#if UART_GECKO_HW_FLOW_CONTROL +/** + * @brief Get LL hardware flow control define from + * Zephyr hardware flow control option. + * @note Supports only UART_CFG_FLOW_CTRL_RTS_CTS and UART_CFG_FLOW_CTRL_RS485. + * @param fc: Zephyr hardware flow control option. + * @retval usartHwFlowControlCtsAndRts, or usartHwFlowControlNone. + */ +static inline USART_HwFlowControl_TypeDef uart_gecko_cfg2ll_hwctrl( + enum uart_config_flow_control fc) +{ + if (fc == UART_CFG_FLOW_CTRL_RTS_CTS) { + return usartHwFlowControlCtsAndRts; + } + + return usartHwFlowControlNone; +} + +/** + * @brief Get Zephyr hardware flow control option from + * LL hardware flow control define. + * @note Supports only usartHwFlowControlCtsAndRts. + * @param fc: LL hardware flow control definition. + * @retval UART_CFG_FLOW_CTRL_RTS_CTS, or UART_CFG_FLOW_CTRL_NONE. + */ +static inline enum uart_config_flow_control uart_gecko_ll2cfg_hwctrl( + USART_HwFlowControl_TypeDef fc) +{ + if (fc == usartHwFlowControlCtsAndRts) { + return UART_CFG_FLOW_CTRL_RTS_CTS; + } + + return UART_CFG_FLOW_CTRL_NONE; +} +#endif + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +static int uart_gecko_configure(const struct device *dev, + const struct uart_config *cfg) +{ + const struct uart_gecko_config *config = dev->config; + USART_TypeDef *base = config->base; + struct uart_gecko_data *data = dev->data; + struct uart_config *uart_cfg = data->uart_cfg; + + if (uart_cfg->parity != cfg->parity) { + return -ENOTSUP; + } + + if (uart_cfg->stop_bits != cfg->stop_bits) { + return -ENOTSUP; + } + + if (uart_cfg->data_bits != cfg->data_bits) { + return -ENOTSUP; + } + + if (uart_cfg->flow_ctrl != cfg->flow_ctrl) { + return -ENOTSUP; + } + + USART_BaudrateAsyncSet(base, 0, cfg->baudrate, usartOVS16); + + /* Upon successful configuration, persist the syscall-passed + * uart_config. + * This allows restoring it, should the device return from a low-power + * mode in which register contents are lost. + */ + *uart_cfg = *cfg; + + return 0; +}; + +static int uart_gecko_config_get(const struct device *dev, + struct uart_config *cfg) +{ + struct uart_gecko_data *data = dev->data; + struct uart_config *uart_cfg = data->uart_cfg; + + cfg->baudrate = uart_cfg->baudrate; + cfg->parity = uart_cfg->parity; + cfg->stop_bits = uart_cfg->stop_bits; + cfg->data_bits = uart_cfg->data_bits; + cfg->flow_ctrl = uart_cfg->flow_ctrl; + + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + /** * @brief Main initializer for UART * @@ -450,24 +632,22 @@ static int uart_gecko_init(const struct device *dev) int err; #endif /* CONFIG_PINCTRL */ const struct uart_gecko_config *config = dev->config; + const struct uart_gecko_data *data = dev->data; + const struct uart_config *uart_cfg = data->uart_cfg; USART_InitAsync_TypeDef usartInit = USART_INITASYNC_DEFAULT; /* The peripheral and gpio clock are already enabled from soc and gpio driver */ /* Enable USART clock */ -#ifdef CONFIG_CLOCK_CONTROL - err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg); - if (err < 0) { - return err; - } -#else CMU_ClockEnable(config->clock, true); -#endif /* Init USART */ - usartInit.baudrate = config->baud_rate; + usartInit.baudrate = uart_cfg->baudrate; + usartInit.parity = uart_gecko_cfg2ll_parity(uart_cfg->parity); + usartInit.stopbits = uart_gecko_cfg2ll_stopbits(uart_cfg->stop_bits); + usartInit.databits = uart_gecko_cfg2ll_databits(uart_cfg->data_bits, uart_cfg->parity); #ifdef UART_GECKO_HW_FLOW_CONTROL - usartInit.hwFlowControl = config->hw_flowcontrol ? + usartInit.hwFlowControl = uart_cfg->flow_ctrl ? usartHwFlowControlCtsAndRts : usartHwFlowControlNone; #endif USART_InitAsync(config->base, &usartInit); @@ -518,6 +698,10 @@ static DEVICE_API(uart, uart_gecko_driver_api) = { .poll_in = uart_gecko_poll_in, .poll_out = uart_gecko_poll_out, .err_check = uart_gecko_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_gecko_configure, + .config_get = uart_gecko_config_get, +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ #ifdef CONFIG_UART_INTERRUPT_DRIVEN .fifo_fill = uart_gecko_fifo_fill, .fifo_read = uart_gecko_fifo_read, @@ -638,45 +822,51 @@ static DEVICE_API(uart, uart_gecko_driver_api) = { .pin_rts = PIN_UART_RTS(idx), \ .pin_cts = PIN_UART_CTS(idx), -#define GECKO_UART_HW_FLOW_CONTROL(idx) \ - .hw_flowcontrol = DT_INST_PROP(idx, hw_flow_control), - #else /* UART_GECKO_HW_FLOW_CONTROL */ #define GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) #define VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) #define GECKO_UART_RTS_CTS_PINS(idx) -#define GECKO_UART_HW_FLOW_CONTROL(idx) #endif /* UART_GECKO_HW_FLOW_CONTROL */ -#define GECKO_UART_INIT(idx) \ - VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx); \ - VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx); \ - \ - GECKO_UART_IRQ_HANDLER_DECL(idx); \ - \ - static const struct uart_gecko_config uart_gecko_cfg_##idx = { \ - .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ - GET_GECKO_UART_CLOCK(idx) \ - .baud_rate = DT_INST_PROP(idx, current_speed), \ - GECKO_UART_HW_FLOW_CONTROL(idx) \ - GECKO_UART_RX_TX_PINS(idx) \ - GECKO_UART_RTS_CTS_PINS(idx) \ - GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \ - GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) \ - GECKO_UART_IRQ_HANDLER_FUNC(idx) \ - }; \ - \ - static struct uart_gecko_data uart_gecko_data_##idx; \ - \ - DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, \ - NULL, &uart_gecko_data_##idx, \ - &uart_gecko_cfg_##idx, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, \ - &uart_gecko_driver_api); \ - \ - \ +#define GECKO_UART_INIT(idx) \ + VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx); \ + VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx); \ + \ + GECKO_UART_IRQ_HANDLER_DECL(idx); \ + PM_DEVICE_DT_INST_DEFINE(idx, uart_gecko_pm_action); \ + \ + static struct uart_config uart_cfg_##idx = { \ + .baudrate = DT_INST_PROP(idx, current_speed), \ + .parity = DT_INST_ENUM_IDX(idx, parity), \ + .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \ + .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) \ + ? UART_CFG_FLOW_CTRL_RTS_CTS \ + : UART_CFG_FLOW_CTRL_NONE, \ + }; \ + \ + static const struct uart_gecko_config uart_gecko_cfg_##idx = { \ + .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ + GET_GECKO_UART_CLOCK(idx) \ + GECKO_UART_RX_TX_PINS(idx) \ + GECKO_UART_RTS_CTS_PINS(idx) \ + GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \ + GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) \ + GECKO_UART_IRQ_HANDLER_FUNC(idx) \ + }; \ + \ + \ + static struct uart_gecko_data uart_gecko_data_##idx = { \ + .uart_cfg = &uart_cfg_##idx, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, PM_DEVICE_DT_INST_GET(idx), \ + &uart_gecko_data_##idx, &uart_gecko_cfg_##idx, \ + PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_gecko_driver_api); \ + \ GECKO_UART_IRQ_HANDLER(idx) DT_INST_FOREACH_STATUS_OKAY(GECKO_UART_INIT) @@ -709,56 +899,77 @@ DT_INST_FOREACH_STATUS_OKAY(GECKO_UART_INIT) #endif #ifdef CONFIG_PINCTRL -#define GECKO_USART_INIT(idx) \ - PINCTRL_DT_INST_DEFINE(idx); \ - GECKO_USART_IRQ_HANDLER_DECL(idx); \ - PM_DEVICE_DT_INST_DEFINE(idx, uart_gecko_pm_action); \ - \ - static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ - .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ - GET_GECKO_USART_CLOCK(idx) \ - .baud_rate = DT_INST_PROP(idx, current_speed), \ - GECKO_USART_IRQ_HANDLER_FUNC(idx) \ - }; \ - \ - static struct uart_gecko_data usart_gecko_data_##idx; \ - \ - DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, PM_DEVICE_DT_INST_GET(idx),\ - &usart_gecko_data_##idx, \ - &usart_gecko_cfg_##idx, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, \ - &uart_gecko_driver_api); \ - \ +#define GECKO_USART_INIT(idx) \ + PINCTRL_DT_INST_DEFINE(idx); \ + GECKO_USART_IRQ_HANDLER_DECL(idx); \ + PM_DEVICE_DT_INST_DEFINE(idx, uart_gecko_pm_action); \ + \ + static struct uart_config uart_cfg_##idx = { \ + .baudrate = DT_INST_PROP(idx, current_speed), \ + .parity = DT_INST_ENUM_IDX(idx, parity), \ + .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \ + .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) \ + ? UART_CFG_FLOW_CTRL_RTS_CTS \ + : UART_CFG_FLOW_CTRL_NONE, \ + }; \ + \ + static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ + GET_GECKO_USART_CLOCK(idx) \ + GECKO_USART_IRQ_HANDLER_FUNC(idx) \ + } ; \ + \ + static struct uart_gecko_data usart_gecko_data_##idx = { \ + .uart_cfg = &uart_cfg_##idx, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, PM_DEVICE_DT_INST_GET(idx), \ + &usart_gecko_data_##idx, \ + &usart_gecko_cfg_##idx, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_gecko_driver_api); \ + \ GECKO_USART_IRQ_HANDLER(idx) #else -#define GECKO_USART_INIT(idx) \ - VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx); \ - VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx); \ - \ - GECKO_USART_IRQ_HANDLER_DECL(idx); \ - PM_DEVICE_DT_INST_DEFINE(idx, uart_gecko_pm_action); \ - \ - static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ - .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ - GET_GECKO_USART_CLOCK(idx) \ - .baud_rate = DT_INST_PROP(idx, current_speed), \ - GECKO_UART_HW_FLOW_CONTROL(idx) \ - GECKO_UART_RX_TX_PINS(idx) \ - GECKO_UART_RTS_CTS_PINS(idx) \ - GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \ - GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) \ - GECKO_USART_IRQ_HANDLER_FUNC(idx) \ - }; \ - \ - static struct uart_gecko_data usart_gecko_data_##idx; \ - \ - DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, PM_DEVICE_DT_INST_GET(idx),\ - &usart_gecko_data_##idx, \ - &usart_gecko_cfg_##idx, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, \ - &uart_gecko_driver_api); \ - \ +#define GECKO_USART_INIT(idx) \ + VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx); \ + VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx); \ + \ + GECKO_USART_IRQ_HANDLER_DECL(idx); \ + PM_DEVICE_DT_INST_DEFINE(idx, uart_gecko_pm_action); \ + \ + static struct uart_config uart_cfg_##idx = { \ + .baudrate = DT_INST_PROP(idx, current_speed), \ + .parity = DT_INST_ENUM_IDX(idx, parity), \ + .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \ + .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) \ + ? UART_CFG_FLOW_CTRL_RTS_CTS \ + : UART_CFG_FLOW_CTRL_NONE, \ + }; \ + \ + static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ + .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ + GET_GECKO_USART_CLOCK(idx) \ + GECKO_UART_RX_TX_PINS(idx) \ + GECKO_UART_RTS_CTS_PINS(idx) \ + GECKO_UART_RX_TX_PIN_LOCATIONS(idx) \ + GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx) \ + GECKO_USART_IRQ_HANDLER_FUNC(idx) \ + }; \ + \ + static struct uart_gecko_data usart_gecko_data_##idx = { \ + .uart_cfg = &uart_cfg_##idx, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, uart_gecko_init, PM_DEVICE_DT_INST_GET(idx), \ + &usart_gecko_data_##idx, \ + &usart_gecko_cfg_##idx, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_gecko_driver_api); \ + \ GECKO_USART_IRQ_HANDLER(idx) #endif diff --git a/drivers/serial/uart_ifx_cat1.c b/drivers/serial/uart_ifx_cat1.c index c421a01c4a9e0..4f9f1064f2197 100644 --- a/drivers/serial/uart_ifx_cat1.c +++ b/drivers/serial/uart_ifx_cat1.c @@ -8,9 +8,6 @@ /** * @brief UART driver for Infineon CAT1 MCU family. * - * Note: - * - Uart ASYNC functionality is not implemented in current - * version of Uart CAT1 driver. */ #define DT_DRV_COMPAT infineon_cat1_uart @@ -21,17 +18,65 @@ #include #include +#include "cy_scb_uart.h" + +#include +LOG_MODULE_REGISTER(uart_ifx_cat1, CONFIG_UART_LOG_LEVEL); + +#ifdef CONFIG_UART_ASYNC_API +#include +#include + +extern int ifx_cat1_dma_ex_connect_digital(const struct device *dev, uint32_t channel, + cyhal_source_t source, cyhal_dma_input_t input); + +struct ifx_cat1_dma_stream { + const struct device *dev; + uint32_t dma_channel; + struct dma_config dma_cfg; + struct dma_block_config blk_cfg; + uint8_t *buf; + size_t buf_len; + size_t offset; + size_t counter; + uint32_t timeout; + size_t dma_transmitted_bytes; + + struct k_work_delayable timeout_work; +}; + +struct ifx_cat1_uart_async { + const struct device *uart_dev; + uart_callback_t cb; + void *user_data; + + struct ifx_cat1_dma_stream dma_rx; + struct ifx_cat1_dma_stream dma_tx; + + uint8_t *rx_next_buf; + size_t rx_next_buf_len; +}; + +#define CURRENT_BUFFER 0 +#define NEXT_BUFFER 1 + +#endif /* CONFIG_UART_ASYNC_API */ + /* Data structure */ struct ifx_cat1_uart_data { - cyhal_uart_t obj; /* UART CYHAL object */ + cyhal_uart_t obj; /* UART CYHAL object */ struct uart_config cfg; cyhal_resource_inst_t hw_resource; cyhal_clock_t clock; #if CONFIG_UART_INTERRUPT_DRIVEN - uart_irq_callback_user_data_t irq_cb; /* Interrupt Callback */ - void *irq_cb_data; /* Interrupt Callback Arg */ -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + uart_irq_callback_user_data_t irq_cb; /* Interrupt Callback */ + void *irq_cb_data; /* Interrupt Callback Arg */ +#endif + +#ifdef CONFIG_UART_ASYNC_API + struct ifx_cat1_uart_async async; +#endif }; /* Device config structure */ @@ -153,17 +198,34 @@ static uint32_t _convert_uart_data_bits_z_to_cyhal(enum uart_config_data_bits da static int32_t _get_hw_block_num(CySCB_Type *reg_addr) { + extern const uint8_t _CYHAL_SCB_BASE_ADDRESS_INDEX[_SCB_ARRAY_SIZE]; + extern CySCB_Type *const _CYHAL_SCB_BASE_ADDRESSES[_SCB_ARRAY_SIZE]; + uint32_t i; for (i = 0u; i < _SCB_ARRAY_SIZE; i++) { if (_CYHAL_SCB_BASE_ADDRESSES[i] == reg_addr) { - return i; + return _CYHAL_SCB_BASE_ADDRESS_INDEX[i]; } } return -1; } +uint32_t ifx_cat1_uart_get_num_in_tx_fifo(const struct device *dev) +{ + const struct ifx_cat1_uart_config *const config = dev->config; + + return Cy_SCB_GetNumInTxFifo(config->reg_addr); +} + +bool ifx_cat1_uart_get_tx_active(const struct device *dev) +{ + const struct ifx_cat1_uart_config *const config = dev->config; + + return Cy_SCB_GetTxSrValid(config->reg_addr) ? true : false; +} + static int ifx_cat1_uart_poll_in(const struct device *dev, unsigned char *c) { cy_rslt_t rec; @@ -178,7 +240,7 @@ static void ifx_cat1_uart_poll_out(const struct device *dev, unsigned char c) { struct ifx_cat1_uart_data *data = dev->data; - (void) cyhal_uart_putc(&data->obj, (uint32_t)c); + (void)cyhal_uart_putc(&data->obj, (uint32_t)c); } static int ifx_cat1_uart_err_check(const struct device *dev) @@ -202,8 +264,7 @@ static int ifx_cat1_uart_err_check(const struct device *dev) return errors; } -static int ifx_cat1_uart_configure(const struct device *dev, - const struct uart_config *cfg) +static int ifx_cat1_uart_configure(const struct device *dev, const struct uart_config *cfg) { __ASSERT_NO_MSG(cfg != NULL); @@ -213,8 +274,7 @@ static int ifx_cat1_uart_configure(const struct device *dev, cyhal_uart_cfg_t uart_cfg = { .data_bits = _convert_uart_data_bits_z_to_cyhal(cfg->data_bits), .stop_bits = _convert_uart_stop_bits_z_to_cyhal(cfg->stop_bits), - .parity = _convert_uart_parity_z_to_cyhal(cfg->parity) - }; + .parity = _convert_uart_parity_z_to_cyhal(cfg->parity)}; /* Store Uart Zephyr configuration (uart config) into data structure */ data->cfg = *cfg; @@ -233,14 +293,13 @@ static int ifx_cat1_uart_configure(const struct device *dev, /* Enable RTS/CTS flow control */ if ((result == CY_RSLT_SUCCESS) && cfg->flow_ctrl) { - Cy_SCB_UART_EnableCts(data->obj.base); + result = cyhal_uart_enable_flow_control(&data->obj, true, true); } return (result == CY_RSLT_SUCCESS) ? 0 : -ENOTSUP; }; -static int ifx_cat1_uart_config_get(const struct device *dev, - struct uart_config *cfg) +static int ifx_cat1_uart_config_get(const struct device *dev, struct uart_config *cfg) { ARG_UNUSED(dev); @@ -261,7 +320,7 @@ static void _uart_event_callback_irq_mode(void *arg, cyhal_uart_event_t event) { ARG_UNUSED(event); - const struct device *dev = (const struct device *) arg; + const struct device *dev = (const struct device *)arg; struct ifx_cat1_uart_data *const data = dev->data; if (data->irq_cb != NULL) { @@ -270,25 +329,23 @@ static void _uart_event_callback_irq_mode(void *arg, cyhal_uart_event_t event) } /* Fill FIFO with data */ -static int ifx_cat1_uart_fifo_fill(const struct device *dev, - const uint8_t *tx_data, int size) +static int ifx_cat1_uart_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) { struct ifx_cat1_uart_data *const data = dev->data; - size_t _size = (size_t) size; + size_t _size = (size_t)size; - (void)cyhal_uart_write(&data->obj, (uint8_t *) tx_data, &_size); - return (int) _size; + (void)cyhal_uart_write(&data->obj, (uint8_t *)tx_data, &_size); + return (int)_size; } /* Read data from FIFO */ -static int ifx_cat1_uart_fifo_read(const struct device *dev, - uint8_t *rx_data, const int size) +static int ifx_cat1_uart_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) { struct ifx_cat1_uart_data *const data = dev->data; - size_t _size = (size_t) size; + size_t _size = (size_t)size; (void)cyhal_uart_read(&data->obj, rx_data, &_size); - return (int) _size; + return (int)_size; } /* Enable TX interrupt */ @@ -297,8 +354,7 @@ static void ifx_cat1_uart_irq_tx_enable(const struct device *dev) struct ifx_cat1_uart_data *const data = dev->data; const struct ifx_cat1_uart_config *const config = dev->config; - cyhal_uart_enable_event(&data->obj, - (cyhal_uart_event_t) CYHAL_UART_IRQ_TX_EMPTY, + cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t)CYHAL_UART_IRQ_TX_EMPTY, config->irq_priority, 1); } @@ -308,8 +364,7 @@ static void ifx_cat1_uart_irq_tx_disable(const struct device *dev) struct ifx_cat1_uart_data *const data = dev->data; const struct ifx_cat1_uart_config *const config = dev->config; - cyhal_uart_enable_event(&data->obj, - (cyhal_uart_event_t) CYHAL_UART_IRQ_TX_EMPTY, + cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t)CYHAL_UART_IRQ_TX_EMPTY, config->irq_priority, 0); } @@ -327,7 +382,7 @@ static int ifx_cat1_uart_irq_tx_complete(const struct device *dev) { struct ifx_cat1_uart_data *const data = dev->data; - return (int) !(cyhal_uart_is_tx_active(&data->obj)); + return (int)!(cyhal_uart_is_tx_active(&data->obj)); } /* Enable RX interrupt */ @@ -336,8 +391,7 @@ static void ifx_cat1_uart_irq_rx_enable(const struct device *dev) struct ifx_cat1_uart_data *const data = dev->data; const struct ifx_cat1_uart_config *const config = dev->config; - cyhal_uart_enable_event(&data->obj, - (cyhal_uart_event_t) CYHAL_UART_IRQ_RX_NOT_EMPTY, + cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t)CYHAL_UART_IRQ_RX_NOT_EMPTY, config->irq_priority, 1); } @@ -347,8 +401,7 @@ static void ifx_cat1_uart_irq_rx_disable(const struct device *dev) struct ifx_cat1_uart_data *const data = dev->data; const struct ifx_cat1_uart_config *const config = dev->config; - cyhal_uart_enable_event(&data->obj, - (cyhal_uart_event_t) CYHAL_UART_IRQ_RX_NOT_EMPTY, + cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t)CYHAL_UART_IRQ_RX_NOT_EMPTY, config->irq_priority, 0); } @@ -366,9 +419,9 @@ static void ifx_cat1_uart_irq_err_enable(const struct device *dev) struct ifx_cat1_uart_data *const data = dev->data; const struct ifx_cat1_uart_config *const config = dev->config; - cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t) - (CYHAL_UART_IRQ_TX_ERROR | CYHAL_UART_IRQ_RX_ERROR), - config->irq_priority, 1); + cyhal_uart_enable_event( + &data->obj, (cyhal_uart_event_t)(CYHAL_UART_IRQ_TX_ERROR | CYHAL_UART_IRQ_RX_ERROR), + config->irq_priority, 1); } /* Disable Error interrupts */ @@ -377,9 +430,9 @@ static void ifx_cat1_uart_irq_err_disable(const struct device *dev) struct ifx_cat1_uart_data *const data = dev->data; const struct ifx_cat1_uart_config *const config = dev->config; - cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t) - (CYHAL_UART_IRQ_TX_ERROR | CYHAL_UART_IRQ_RX_ERROR), - config->irq_priority, 0); + cyhal_uart_enable_event( + &data->obj, (cyhal_uart_event_t)(CYHAL_UART_IRQ_TX_ERROR | CYHAL_UART_IRQ_RX_ERROR), + config->irq_priority, 0); } /* Check if any IRQs is pending */ @@ -388,7 +441,7 @@ static int ifx_cat1_uart_irq_is_pending(const struct device *dev) struct ifx_cat1_uart_data *const data = dev->data; uint32_t intcause = Cy_SCB_GetInterruptCause(data->obj.base); - return (int) (intcause & (CY_SCB_TX_INTR | CY_SCB_RX_INTR)); + return (int)(intcause & (CY_SCB_TX_INTR | CY_SCB_RX_INTR)); } /* Start processing interrupts in ISR. @@ -410,8 +463,7 @@ static int ifx_cat1_uart_irq_update(const struct device *dev) } static void ifx_cat1_uart_irq_callback_set(const struct device *dev, - uart_irq_callback_user_data_t cb, - void *cb_data) + uart_irq_callback_user_data_t cb, void *cb_data) { struct ifx_cat1_uart_data *data = dev->data; cyhal_uart_t *uart_obj = &data->obj; @@ -421,10 +473,455 @@ static void ifx_cat1_uart_irq_callback_set(const struct device *dev, data->irq_cb_data = cb_data; /* Register a uart general callback handler */ - cyhal_uart_register_callback(uart_obj, _uart_event_callback_irq_mode, (void *) dev); + cyhal_uart_register_callback(uart_obj, _uart_event_callback_irq_mode, (void *)dev); } + #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API +static int ifx_cat1_uart_async_callback_set(const struct device *dev, uart_callback_t callback, + void *user_data) +{ + struct ifx_cat1_uart_data *const data = dev->data; + + data->async.cb = callback; + data->async.user_data = user_data; + data->async.dma_tx.dma_cfg.user_data = (void *)dev; + + return 0; +} + +/* Async DMA helper */ +static int ifx_cat1_uart_async_dma_config_buffer(const struct device *dev, bool tx) +{ + int ret; + struct ifx_cat1_uart_data *const data = dev->data; + struct ifx_cat1_dma_stream *dma_stream = tx ? &data->async.dma_tx : &data->async.dma_rx; + + /* Configure byte mode */ + dma_stream->blk_cfg.block_size = dma_stream->buf_len; + + if (tx) { + dma_stream->blk_cfg.source_address = (uint32_t)dma_stream->buf; + } else { + dma_stream->blk_cfg.dest_address = (uint32_t)dma_stream->buf; + } + + ret = dma_config(dma_stream->dev, dma_stream->dma_channel, &dma_stream->dma_cfg); + + if (!ret) { + ret = dma_start(dma_stream->dev, dma_stream->dma_channel); + } + + return ret; +} + +static int ifx_cat1_uart_async_tx(const struct device *dev, const uint8_t *tx_data, + size_t tx_data_size, int32_t timeout) +{ + struct ifx_cat1_uart_data *const data = dev->data; + const struct device *dev_dma = data->async.dma_tx.dev; + int err; + + if (dev_dma == NULL) { + err = -ENODEV; + goto exit; + } + + if (tx_data == NULL || tx_data_size == 0) { + err = -EINVAL; + goto exit; + } + + /* Store information about data buffer need to send */ + data->async.dma_tx.buf = (uint8_t *)tx_data; + data->async.dma_tx.buf_len = tx_data_size; + data->async.dma_tx.blk_cfg.block_size = 0; + data->async.dma_tx.dma_transmitted_bytes = 0; + + /* Configure dma to transfer */ + err = ifx_cat1_uart_async_dma_config_buffer(dev, true); + if (err) { + LOG_ERR("Error Tx DMA configure (%d)", err); + goto exit; + } + + /* Configure timeout */ + if ((timeout != SYS_FOREVER_US) && (timeout != 0)) { + k_work_reschedule(&data->async.dma_tx.timeout_work, K_USEC(timeout)); + } + +exit: + return err; +} + +static int ifx_cat1_uart_async_tx_abort(const struct device *dev) +{ + struct ifx_cat1_uart_data *data = dev->data; + struct uart_event evt = {0}; + struct dma_status stat; + int err = 0; + unsigned int key = irq_lock(); + + k_work_cancel_delayable(&data->async.dma_tx.timeout_work); + + err = dma_stop(data->async.dma_tx.dev, data->async.dma_tx.dma_channel); + if (err) { + LOG_ERR("Error stopping Tx DMA (%d)", err); + goto unlock; + } + + err = dma_get_status(data->async.dma_tx.dev, data->async.dma_tx.dma_channel, &stat); + if (err) { + LOG_ERR("Error stopping Tx DMA (%d)", err); + goto unlock; + } + + evt.type = UART_TX_ABORTED; + evt.data.tx.buf = data->async.dma_tx.buf; + evt.data.tx.len = 0; + + if (data->async.cb) { + data->async.cb(dev, &evt, data->async.user_data); + } + +unlock: + irq_unlock(key); + return err; +} + +static void dma_callback_tx_done(const struct device *dma_dev, void *arg, uint32_t channel, + int status) +{ + const struct device *uart_dev = (void *)arg; + struct ifx_cat1_uart_data *const data = uart_dev->data; + unsigned int key = irq_lock(); + + if (status == 0) { + + k_work_cancel_delayable(&data->async.dma_tx.timeout_work); + dma_stop(data->async.dma_tx.dev, data->async.dma_tx.dma_channel); + + struct uart_event evt = {.type = UART_TX_DONE, + .data.tx.buf = data->async.dma_tx.buf, + .data.tx.len = data->async.dma_tx.buf_len}; + + data->async.dma_tx.buf = NULL; + data->async.dma_tx.buf_len = 0; + + if (data->async.cb) { + data->async.cb(uart_dev, &evt, data->async.user_data); + } + + } else { + /* DMA error */ + dma_stop(data->async.dma_tx.dev, data->async.dma_tx.dma_channel); + } + irq_unlock(key); +} + +static void ifx_cat1_uart_async_tx_timeout(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct ifx_cat1_dma_stream *dma_tx = + CONTAINER_OF(dwork, struct ifx_cat1_dma_stream, timeout_work); + struct ifx_cat1_uart_async *async = + CONTAINER_OF(dma_tx, struct ifx_cat1_uart_async, dma_tx); + + (void)ifx_cat1_uart_async_tx_abort(async->uart_dev); +} + +static inline void async_evt_rx_rdy(struct ifx_cat1_uart_data *data) +{ + struct uart_event event = {.type = UART_RX_RDY, + .data.rx.buf = (uint8_t *)data->async.dma_rx.buf, + .data.rx.len = + data->async.dma_rx.counter - data->async.dma_rx.offset, + .data.rx.offset = data->async.dma_rx.offset}; + + data->async.dma_rx.offset = data->async.dma_rx.counter; + + if (event.data.rx.len > 0 && data->async.cb) { + data->async.cb(data->async.uart_dev, &event, data->async.user_data); + } +} + +static inline void async_evt_rx_buf_request(struct ifx_cat1_uart_data *data) +{ + struct uart_event evt = {.type = UART_RX_BUF_REQUEST}; + + if (data->async.cb) { + data->async.cb(data->async.uart_dev, &evt, data->async.user_data); + } +} + +static inline void async_evt_rx_release_buffer(struct ifx_cat1_uart_data *data, int buffer_type) +{ + struct uart_event event = {.type = UART_RX_BUF_RELEASED}; + + if (buffer_type == NEXT_BUFFER && !data->async.rx_next_buf) { + return; + } + + if (buffer_type == CURRENT_BUFFER && !data->async.dma_rx.buf) { + return; + } + + if (buffer_type == NEXT_BUFFER) { + event.data.rx_buf.buf = data->async.rx_next_buf; + data->async.rx_next_buf = NULL; + data->async.rx_next_buf_len = 0; + } else { + event.data.rx_buf.buf = data->async.dma_rx.buf; + data->async.dma_rx.buf = NULL; + data->async.dma_rx.buf_len = 0; + } + + if (data->async.cb) { + data->async.cb(data->async.uart_dev, &event, data->async.user_data); + } +} + +static inline void async_evt_rx_disabled(struct ifx_cat1_uart_data *data) +{ + struct uart_event event = {.type = UART_RX_DISABLED}; + + data->async.dma_rx.buf = NULL; + data->async.dma_rx.buf_len = 0; + data->async.dma_rx.offset = 0; + data->async.dma_rx.counter = 0; + + if (data->async.cb) { + data->async.cb(data->async.uart_dev, &event, data->async.user_data); + } +} + +static inline void async_evt_rx_stopped(struct ifx_cat1_uart_data *data, + enum uart_rx_stop_reason reason) +{ + struct uart_event event = {.type = UART_RX_STOPPED, .data.rx_stop.reason = reason}; + struct uart_event_rx *rx = &event.data.rx_stop.data; + struct dma_status stat; + + if (data->async.dma_rx.buf_len == 0 || data->async.cb == NULL) { + return; + } + + rx->buf = data->async.dma_rx.buf; + + if (dma_get_status(data->async.dma_rx.dev, data->async.dma_rx.dma_channel, &stat) == 0) { + data->async.dma_rx.counter = data->async.dma_rx.buf_len - stat.pending_length; + } + rx->len = data->async.dma_rx.counter - data->async.dma_rx.offset; + rx->offset = data->async.dma_rx.counter; + + data->async.cb(data->async.uart_dev, &event, data->async.user_data); +} + +static int ifx_cat1_uart_async_rx_enable(const struct device *dev, uint8_t *rx_data, + size_t rx_data_size, int32_t timeout) +{ + struct ifx_cat1_uart_data *const data = dev->data; + struct dma_status dma_status = {0}; + int err = 0; + unsigned int key = irq_lock(); + + if (data->async.dma_rx.dev == NULL) { + return -ENODEV; + } + + if (data->async.dma_rx.buf_len != 0) { + return -EBUSY; + } + + /* Store information about data buffer need to send */ + data->async.dma_rx.buf = (uint8_t *)rx_data; + data->async.dma_rx.buf_len = rx_data_size; + data->async.dma_rx.blk_cfg.block_size = 0; + data->async.dma_rx.dma_transmitted_bytes = 0; + data->async.dma_rx.timeout = timeout; + + /* Request buffers before enabling rx */ + async_evt_rx_buf_request(data); + + /* Configure dma to transfer */ + err = ifx_cat1_uart_async_dma_config_buffer(dev, false); + if (err) { + LOG_ERR("Error Rx DMA configure (%d)", err); + goto unlock; + } + err = dma_get_status(data->async.dma_rx.dev, data->async.dma_rx.dma_channel, &dma_status); + if (err) { + return err; + } + + if (dma_status.busy) { + return -EBUSY; + } + + /* Configure timeout */ + if ((timeout != SYS_FOREVER_US) && (timeout != 0)) { + k_work_reschedule(&data->async.dma_rx.timeout_work, K_USEC(timeout)); + } + +unlock: + irq_unlock(key); + return err; +} + +static void dma_callback_rx_rdy(const struct device *dma_dev, void *arg, uint32_t channel, + int status) +{ + const struct device *uart_dev = (void *)arg; + struct ifx_cat1_uart_data *const data = uart_dev->data; + unsigned int key = irq_lock(); + + if (status == 0) { + /* All data are sent, call user callback */ + + k_work_cancel_delayable(&data->async.dma_rx.timeout_work); + data->async.dma_rx.counter = data->async.dma_rx.buf_len; + + async_evt_rx_rdy(data); + async_evt_rx_release_buffer(data, CURRENT_BUFFER); + + data->async.dma_rx.buf = NULL; + data->async.dma_rx.buf_len = 0; + data->async.dma_rx.blk_cfg.block_size = 0; + data->async.dma_rx.dma_transmitted_bytes = 0; + + if (!data->async.rx_next_buf) { + dma_stop(data->async.dma_rx.dev, data->async.dma_rx.dma_channel); + async_evt_rx_disabled(data); + goto unlock; + } + + data->async.dma_rx.buf = data->async.rx_next_buf; + data->async.dma_rx.buf_len = data->async.rx_next_buf_len; + data->async.dma_rx.offset = 0; + data->async.dma_rx.counter = 0; + data->async.rx_next_buf = NULL; + data->async.rx_next_buf_len = 0; + + ifx_cat1_uart_async_dma_config_buffer(uart_dev, false); + + async_evt_rx_buf_request(data); + + if ((data->async.dma_rx.timeout != SYS_FOREVER_US) && + (data->async.dma_rx.timeout != 0)) { + k_work_reschedule(&data->async.dma_rx.timeout_work, + K_USEC(data->async.dma_rx.timeout)); + } + + } else { + /* DMA error */ + dma_stop(data->async.dma_rx.dev, data->async.dma_rx.dma_channel); + + async_evt_rx_stopped(data, UART_ERROR_OVERRUN); + async_evt_rx_release_buffer(data, CURRENT_BUFFER); + async_evt_rx_release_buffer(data, NEXT_BUFFER); + async_evt_rx_disabled(data); + goto unlock; + } +unlock: + irq_unlock(key); +} + +static void ifx_cat1_uart_async_rx_timeout(struct k_work *work) +{ + + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct ifx_cat1_dma_stream *dma_rx = + CONTAINER_OF(dwork, struct ifx_cat1_dma_stream, timeout_work); + struct ifx_cat1_uart_async *async = + CONTAINER_OF(dma_rx, struct ifx_cat1_uart_async, dma_rx); + struct ifx_cat1_uart_data *data = CONTAINER_OF(async, struct ifx_cat1_uart_data, async); + + struct dma_status stat; + unsigned int key = irq_lock(); + + if (dma_rx->buf_len == 0) { + irq_unlock(key); + return; + } + if (dma_get_status(dma_rx->dev, dma_rx->dma_channel, &stat) == 0) { + size_t rx_rcv_len = dma_rx->buf_len - stat.pending_length; + + if ((rx_rcv_len > 0) && (rx_rcv_len == dma_rx->counter)) { + dma_rx->counter = rx_rcv_len; + async_evt_rx_rdy(data); + } else { + dma_rx->counter = rx_rcv_len; + } + } + irq_unlock(key); + + if ((dma_rx->timeout != SYS_FOREVER_US) && (dma_rx->timeout != 0)) { + k_work_reschedule(&dma_rx->timeout_work, K_USEC(dma_rx->timeout)); + } +} + +static int ifx_cat1_uart_async_rx_disable(const struct device *dev) +{ + struct ifx_cat1_uart_data *data = dev->data; + struct dma_status stat; + unsigned int key; + + k_work_cancel_delayable(&data->async.dma_rx.timeout_work); + + key = irq_lock(); + + if (data->async.dma_rx.buf_len == 0) { + __ASSERT_NO_MSG(data->async.dma_rx.buf == NULL); + irq_unlock(key); + return -EINVAL; + } + + dma_stop(data->async.dma_rx.dev, data->async.dma_rx.dma_channel); + + if (dma_get_status(data->async.dma_rx.dev, data->async.dma_rx.dma_channel, &stat) == 0) { + size_t rx_rcv_len = data->async.dma_rx.buf_len - stat.pending_length; + + if (rx_rcv_len > data->async.dma_rx.offset) { + data->async.dma_rx.counter = rx_rcv_len; + async_evt_rx_rdy(data); + } + } + async_evt_rx_release_buffer(data, CURRENT_BUFFER); + async_evt_rx_release_buffer(data, NEXT_BUFFER); + async_evt_rx_disabled(data); + + irq_unlock(key); + return 0; +} + +static int ifx_cat1_uart_async_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len) +{ + struct ifx_cat1_uart_data *data = dev->data; + unsigned int key; + int ret = 0; + + key = irq_lock(); + + if (data->async.dma_rx.buf_len == 0U) { + ret = -EACCES; + goto unlock; + } + + if (data->async.rx_next_buf_len != 0U) { + ret = -EBUSY; + goto unlock; + } + + data->async.rx_next_buf = buf; + data->async.rx_next_buf_len = len; + +unlock: + irq_unlock(key); + return ret; +} + +#endif /*CONFIG_UART_ASYNC_API */ static int ifx_cat1_uart_init(const struct device *dev) { @@ -437,11 +934,7 @@ static int ifx_cat1_uart_init(const struct device *dev) .resource = &data->hw_resource, .config = &_cyhal_uart_default_config, .clock = &data->clock, - .gpios = { - .pin_tx = NC, - .pin_rts = NC, - .pin_cts = NC, - }, + .gpios = {.pin_tx = NC, .pin_rts = NC, .pin_cts = NC}, }; /* Dedicate SCB HW resource */ @@ -479,6 +972,71 @@ static int ifx_cat1_uart_init(const struct device *dev) data->obj.is_clock_owned = true; ret = ifx_cat1_uart_configure(dev, &config->dt_cfg); +#ifdef CONFIG_UART_ASYNC_API + data->async.uart_dev = dev; + if (data->async.dma_rx.dev != NULL) { + cyhal_source_t uart_source; + + if (!device_is_ready(data->async.dma_rx.dev)) { + return -ENODEV; + } + + data->async.dma_rx.blk_cfg.source_address = + (uint32_t)(&config->reg_addr->RX_FIFO_RD); + data->async.dma_rx.blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + data->async.dma_rx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + data->async.dma_rx.dma_cfg.head_block = &data->async.dma_rx.blk_cfg; + data->async.dma_rx.dma_cfg.user_data = (void *)dev; + data->async.dma_rx.dma_cfg.dma_callback = dma_callback_rx_rdy; + + if (cyhal_uart_enable_output(&data->obj, + CYHAL_UART_OUTPUT_TRIGGER_RX_FIFO_LEVEL_REACHED, + &uart_source)) { + return -ENOTSUP; + } + + if (ifx_cat1_dma_ex_connect_digital(data->async.dma_rx.dev, + data->async.dma_rx.dma_channel, uart_source, + CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS)) { + return -ENOTSUP; + } + + Cy_SCB_SetRxFifoLevel(config->reg_addr, 0); + } + + if (data->async.dma_tx.dev != NULL) { + cyhal_source_t uart_source; + + if (!device_is_ready(data->async.dma_tx.dev)) { + return -ENODEV; + } + + data->async.dma_tx.blk_cfg.dest_address = (uint32_t)(&config->reg_addr->TX_FIFO_WR); + data->async.dma_tx.blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; + data->async.dma_tx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + data->async.dma_tx.dma_cfg.head_block = &data->async.dma_tx.blk_cfg; + data->async.dma_tx.dma_cfg.user_data = (void *)dev; + data->async.dma_tx.dma_cfg.dma_callback = dma_callback_tx_done; + + if (cyhal_uart_enable_output(&data->obj, + CYHAL_UART_OUTPUT_TRIGGER_TX_FIFO_LEVEL_REACHED, + &uart_source)) { + return -ENOTSUP; + } + + if (ifx_cat1_dma_ex_connect_digital(data->async.dma_tx.dev, + data->async.dma_tx.dma_channel, uart_source, + CYHAL_DMA_INPUT_TRIGGER_ALL_ELEMENTS)) { + return -ENOTSUP; + } + Cy_SCB_SetTxFifoLevel(config->reg_addr, 1); + } + + k_work_init_delayable(&data->async.dma_tx.timeout_work, ifx_cat1_uart_async_tx_timeout); + k_work_init_delayable(&data->async.dma_rx.timeout_work, ifx_cat1_uart_async_rx_timeout); + +#endif /* CONFIG_UART_ASYNC_API */ + return ret; } @@ -507,29 +1065,61 @@ static DEVICE_API(uart, ifx_cat1_uart_driver_api) = { .irq_is_pending = ifx_cat1_uart_irq_is_pending, .irq_update = ifx_cat1_uart_irq_update, .irq_callback_set = ifx_cat1_uart_irq_callback_set, -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#if CONFIG_UART_ASYNC_API + .callback_set = ifx_cat1_uart_async_callback_set, + .tx = ifx_cat1_uart_async_tx, + .rx_enable = ifx_cat1_uart_async_rx_enable, + .tx_abort = ifx_cat1_uart_async_tx_abort, + .rx_buf_rsp = ifx_cat1_uart_async_rx_buf_rsp, + .rx_disable = ifx_cat1_uart_async_rx_disable, +#endif /*CONFIG_UART_ASYNC_API*/ + }; -#define INFINEON_CAT1_UART_INIT(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static struct ifx_cat1_uart_data ifx_cat1_uart##n##_data; \ - \ - static struct ifx_cat1_uart_config ifx_cat1_uart##n##_cfg = { \ - .dt_cfg.baudrate = DT_INST_PROP(n, current_speed), \ - .dt_cfg.parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ - .dt_cfg.stop_bits = DT_INST_ENUM_IDX_OR(n, stop_bits, UART_CFG_STOP_BITS_1), \ - .dt_cfg.data_bits = DT_INST_ENUM_IDX_OR(n, data_bits, UART_CFG_DATA_BITS_8), \ - .dt_cfg.flow_ctrl = DT_INST_PROP(n, hw_flow_control), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .reg_addr = (CySCB_Type *)DT_INST_REG_ADDR(n), \ - .irq_priority = DT_INST_IRQ(n, priority) \ - }; \ - \ - DEVICE_DT_INST_DEFINE(n, \ - ifx_cat1_uart_init, NULL, \ - &ifx_cat1_uart##n##_data, \ - &ifx_cat1_uart##n##_cfg, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, \ +#if defined(CONFIG_UART_ASYNC_API) +#define UART_DMA_CHANNEL_INIT(index, dir, ch_dir, src_data_size, dst_data_size) \ + .dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(index, dir)), \ + .dma_channel = DT_INST_DMAS_CELL_BY_NAME(index, dir, channel), \ + .dma_cfg = { \ + .channel_direction = ch_dir, \ + .source_data_size = src_data_size, \ + .dest_data_size = dst_data_size, \ + .source_burst_length = 0, \ + .dest_burst_length = 0, \ + .block_count = 1, \ + .complete_callback_en = 0, \ + }, + +#define UART_DMA_CHANNEL(index, dir, ch_dir, src_data_size, dst_data_size) \ + .async.dma_##dir = {COND_CODE_1( \ + DT_INST_DMAS_HAS_NAME(index, dir), \ + (UART_DMA_CHANNEL_INIT(index, dir, ch_dir, src_data_size, dst_data_size)), \ + (NULL))}, + +#else +#define UART_DMA_CHANNEL(index, dir, ch_dir, src_data_size, dst_data_size) +#endif /* CONFIG_UART_ASYNC_API */ + +#define INFINEON_CAT1_UART_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct ifx_cat1_uart_data ifx_cat1_uart##n##_data = { \ + UART_DMA_CHANNEL(n, tx, MEMORY_TO_PERIPHERAL, 1, 1) \ + UART_DMA_CHANNEL(n, rx, PERIPHERAL_TO_MEMORY, 1, 1)}; \ + \ + static struct ifx_cat1_uart_config ifx_cat1_uart##n##_cfg = { \ + .dt_cfg.baudrate = DT_INST_PROP(n, current_speed), \ + .dt_cfg.parity = DT_INST_ENUM_IDX(n, parity), \ + .dt_cfg.stop_bits = DT_INST_ENUM_IDX(n, stop_bits), \ + .dt_cfg.data_bits = DT_INST_ENUM_IDX(n, data_bits), \ + .dt_cfg.flow_ctrl = DT_INST_PROP(n, hw_flow_control), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .reg_addr = (CySCB_Type *)DT_INST_REG_ADDR(n), \ + .irq_priority = DT_INST_IRQ(n, priority)}; \ + \ + DEVICE_DT_INST_DEFINE(n, &ifx_cat1_uart_init, NULL, &ifx_cat1_uart##n##_data, \ + &ifx_cat1_uart##n##_cfg, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ &ifx_cat1_uart_driver_api); DT_INST_FOREACH_STATUS_OKAY(INFINEON_CAT1_UART_INIT) diff --git a/drivers/serial/uart_intel_lw.c b/drivers/serial/uart_intel_lw.c index 64c0d0a6dd192..786360c2050ba 100644 --- a/drivers/serial/uart_intel_lw.c +++ b/drivers/serial/uart_intel_lw.c @@ -994,12 +994,9 @@ static struct uart_intel_lw_device_data uart_intel_lw_dev_data_##n = { \ .uart_cfg = \ { \ .baudrate = DT_INST_PROP(n, current_speed), \ - .parity = DT_INST_ENUM_IDX_OR(n, parity, \ - UART_CFG_PARITY_NONE), \ - .stop_bits = DT_INST_ENUM_IDX_OR(n, stop_bits, \ - UART_CFG_STOP_BITS_1), \ - .data_bits = DT_INST_ENUM_IDX_OR(n, data_bits, \ - UART_CFG_DATA_BITS_8), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ + .stop_bits = DT_INST_ENUM_IDX(n, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(n, data_bits), \ .flow_ctrl = DT_INST_PROP(n, hw_flow_control) ? \ UART_CFG_FLOW_CTRL_RTS_CTS : \ UART_CFG_FLOW_CTRL_NONE, \ diff --git a/drivers/serial/uart_max32.c b/drivers/serial/uart_max32.c index c09cb0b09badc..0ed5bcf709f95 100644 --- a/drivers/serial/uart_max32.c +++ b/drivers/serial/uart_max32.c @@ -4,6 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifdef CONFIG_UART_ASYNC_API +#include +#include +#endif #include #include #include @@ -16,16 +20,61 @@ LOG_MODULE_REGISTER(uart_max32, CONFIG_UART_LOG_LEVEL); +#ifdef CONFIG_UART_ASYNC_API +struct max32_uart_dma_config { + const struct device *dev; + const uint32_t channel; + const uint32_t slot; +}; +#endif /* CONFIG_UART_ASYNC_API */ + struct max32_uart_config { mxc_uart_regs_t *regs; const struct pinctrl_dev_config *pctrl; const struct device *clock; struct max32_perclk perclk; struct uart_config uart_conf; -#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) uart_irq_config_func_t irq_config_func; -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#endif /* CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API */ +#ifdef CONFIG_UART_ASYNC_API + const struct max32_uart_dma_config tx_dma; + const struct max32_uart_dma_config rx_dma; +#endif /* CONFIG_UART_ASYNC_API */ +}; + +#ifdef CONFIG_UART_ASYNC_API +#define MAX32_UART_TX_CACHE_NUM 2 +struct max32_uart_async_tx { + const uint8_t *buf; + const uint8_t *src; + size_t len; + uint8_t cache[MAX32_UART_TX_CACHE_NUM][CONFIG_UART_TX_CACHE_LEN]; + uint8_t cache_id; + struct dma_block_config dma_blk; + int32_t timeout; + struct k_work_delayable timeout_work; +}; + +struct max32_uart_async_rx { + uint8_t *buf; + size_t len; + size_t offset; + size_t counter; + uint8_t *next_buf; + size_t next_len; + int32_t timeout; + struct k_work_delayable timeout_work; +}; + +struct max32_uart_async_data { + const struct device *uart_dev; + struct max32_uart_async_tx tx; + struct max32_uart_async_rx rx; + uart_callback_t cb; + void *user_data; }; +#endif struct max32_uart_data { #ifdef CONFIG_UART_INTERRUPT_DRIVEN @@ -33,6 +82,9 @@ struct max32_uart_data { void *cb_data; /* Interrupt callback arg */ uint32_t flags; /* Cached interrupt flags */ uint32_t status; /* Cached status flags */ +#endif +#ifdef CONFIG_UART_ASYNC_API + struct max32_uart_async_data async; #endif struct uart_config conf; /* baudrate, stopbits, ... */ }; @@ -41,6 +93,10 @@ struct max32_uart_data { static void uart_max32_isr(const struct device *dev); #endif +#ifdef CONFIG_UART_ASYNC_API +static int uart_max32_tx_dma_load(const struct device *dev, uint8_t *buf, size_t len); +#endif + static void api_poll_out(const struct device *dev, unsigned char c) { const struct max32_uart_config *cfg = dev->config; @@ -207,11 +263,19 @@ static int api_config_get(const struct device *dev, struct uart_config *uart_cfg #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ +#ifdef CONFIG_UART_ASYNC_API +static void uart_max32_async_tx_timeout(struct k_work *work); +static void uart_max32_async_rx_timeout(struct k_work *work); +#endif /* CONFIG_UART_ASYNC_API */ + static int uart_max32_init(const struct device *dev) { int ret; const struct max32_uart_config *const cfg = dev->config; mxc_uart_regs_t *regs = cfg->regs; +#ifdef CONFIG_UART_ASYNC_API + struct max32_uart_data *data = dev->data; +#endif if (!device_is_ready(cfg->clock)) { LOG_ERR("Clock control device not ready"); @@ -244,12 +308,20 @@ static int uart_max32_init(const struct device *dev) return ret; } -#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) /* Clear any pending UART RX/TX interrupts */ MXC_UART_ClearFlags(regs, (ADI_MAX32_UART_INT_RX | ADI_MAX32_UART_INT_TX)); cfg->irq_config_func(dev); #endif +#ifdef CONFIG_UART_ASYNC_API + data->async.uart_dev = dev; + k_work_init_delayable(&data->async.tx.timeout_work, uart_max32_async_tx_timeout); + k_work_init_delayable(&data->async.rx.timeout_work, uart_max32_async_rx_timeout); + data->async.rx.len = 0; + data->async.rx.offset = 0; +#endif + return ret; } @@ -304,21 +376,7 @@ static int api_irq_tx_ready(const struct device *dev) uint32_t inten = Wrap_MXC_UART_GetRegINTEN(cfg->regs); return ((inten & (ADI_MAX32_UART_INT_TX | ADI_MAX32_UART_INT_TX_OEM)) && - !(data->status & MXC_F_UART_STATUS_TX_FULL)); -} - -static void api_irq_rx_enable(const struct device *dev) -{ - const struct max32_uart_config *cfg = dev->config; - - MXC_UART_EnableInt(cfg->regs, ADI_MAX32_UART_INT_RX); -} - -static void api_irq_rx_disable(const struct device *dev) -{ - const struct max32_uart_config *cfg = dev->config; - - MXC_UART_DisableInt(cfg->regs, ADI_MAX32_UART_INT_RX); + !(data->status & ADI_MAX32_UART_STATUS_TX_FULL)); } static int api_irq_tx_complete(const struct device *dev) @@ -378,22 +436,527 @@ static int api_irq_update(const struct device *dev) static void api_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, void *cb_data) { - struct max32_uart_data *const data = dev->data; + struct max32_uart_data *const dev_data = dev->data; + + dev_data->cb = cb; + dev_data->cb_data = cb_data; +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) +static void api_irq_rx_enable(const struct device *dev) +{ + const struct max32_uart_config *cfg = dev->config; + + MXC_UART_EnableInt(cfg->regs, ADI_MAX32_UART_INT_RX); +} + +static void api_irq_rx_disable(const struct device *dev) +{ + const struct max32_uart_config *cfg = dev->config; - data->cb = cb; - data->cb_data = cb_data; + MXC_UART_DisableInt(cfg->regs, ADI_MAX32_UART_INT_RX); } static void uart_max32_isr(const struct device *dev) { struct max32_uart_data *data = dev->data; + const struct max32_uart_config *cfg = dev->config; + uint32_t intfl; + + intfl = MXC_UART_GetFlags(cfg->regs); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN if (data->cb) { data->cb(dev, data->cb_data); } +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#ifdef CONFIG_UART_ASYNC_API + if (data->async.rx.timeout != SYS_FOREVER_US && data->async.rx.timeout != 0 && + (intfl & ADI_MAX32_UART_INT_RX)) { + k_work_reschedule(&data->async.rx.timeout_work, K_USEC(data->async.rx.timeout)); + } +#endif /* CONFIG_UART_ASYNC_API */ + + /* Clear RX/TX interrupts flag after cb is called */ + MXC_UART_ClearFlags(cfg->regs, intfl); } +#endif /* CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API */ -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#if defined(CONFIG_UART_ASYNC_API) + +static inline void async_timer_start(struct k_work_delayable *work, int32_t timeout) +{ + if ((timeout != SYS_FOREVER_US) && (timeout != 0)) { + k_work_reschedule(work, K_USEC(timeout)); + } +} + +static void async_user_callback(const struct device *dev, struct uart_event *evt) +{ + const struct max32_uart_data *data = dev->data; + + if (data->async.cb) { + data->async.cb(dev, evt, data->async.user_data); + } +} + +static uint32_t load_tx_cache(const uint8_t *src, size_t len, uint8_t *dest) +{ + memcpy(dest, src, MIN(len, CONFIG_UART_TX_CACHE_LEN)); + + return MIN(len, CONFIG_UART_TX_CACHE_LEN); +} + +static void uart_max32_async_tx_callback(const struct device *dma_dev, void *user_data, + uint32_t channel, int status) +{ + const struct device *dev = user_data; + const struct max32_uart_config *config = dev->config; + struct max32_uart_data *data = dev->data; + struct max32_uart_async_tx *tx = &data->async.tx; + struct dma_status dma_stat; + int ret; + + unsigned int key = irq_lock(); + + dma_get_status(config->tx_dma.dev, config->tx_dma.channel, &dma_stat); + /* Skip callback if channel is still busy */ + if (dma_stat.busy) { + irq_unlock(key); + return; + } + + k_work_cancel_delayable(&tx->timeout_work); + Wrap_MXC_UART_DisableTxDMA(config->regs); + + irq_unlock(key); + + tx->len -= tx->dma_blk.block_size; + if (tx->len > 0) { + tx->cache_id = !(tx->cache_id); + ret = uart_max32_tx_dma_load(dev, tx->cache[tx->cache_id], + MIN(tx->len, CONFIG_UART_TX_CACHE_LEN)); + if (ret < 0) { + LOG_ERR("Error configuring Tx DMA (%d)", ret); + return; + } + + ret = dma_start(config->tx_dma.dev, config->tx_dma.channel); + if (ret < 0) { + LOG_ERR("Error starting Tx DMA (%d)", ret); + return; + } + + async_timer_start(&tx->timeout_work, tx->timeout); + + Wrap_MXC_UART_SetTxDMALevel(config->regs, 2); + Wrap_MXC_UART_EnableTxDMA(config->regs); + + /* Load next chunk as well */ + if (tx->len > CONFIG_UART_TX_CACHE_LEN) { + tx->src += load_tx_cache(tx->src, tx->len - CONFIG_UART_TX_CACHE_LEN, + tx->cache[!(tx->cache_id)]); + } + } else { + struct uart_event tx_done = { + .type = status == 0 ? UART_TX_DONE : UART_TX_ABORTED, + .data.tx.buf = tx->buf, + .data.tx.len = tx->len, + }; + async_user_callback(dev, &tx_done); + } +} + +static int uart_max32_tx_dma_load(const struct device *dev, uint8_t *buf, size_t len) +{ + int ret; + const struct max32_uart_config *config = dev->config; + struct max32_uart_data *data = dev->data; + struct dma_config dma_cfg = {0}; + struct dma_block_config *dma_blk = &data->async.tx.dma_blk; + + dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + dma_cfg.dma_callback = uart_max32_async_tx_callback; + dma_cfg.user_data = (void *)dev; + dma_cfg.dma_slot = config->tx_dma.slot; + dma_cfg.block_count = 1; + dma_cfg.source_data_size = 1U; + dma_cfg.source_burst_length = 1U; + dma_cfg.dest_data_size = 1U; + dma_cfg.head_block = dma_blk; + dma_blk->block_size = len; + dma_blk->source_address = (uint32_t)buf; + + ret = dma_config(config->tx_dma.dev, config->tx_dma.channel, &dma_cfg); + if (ret < 0) { + return ret; + } + + return 0; +} + +static int api_callback_set(const struct device *dev, uart_callback_t callback, void *user_data) +{ + struct max32_uart_data *data = dev->data; + + data->async.cb = callback; + data->async.user_data = user_data; + + return 0; +} + +static int api_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout) +{ + struct max32_uart_data *data = dev->data; + const struct max32_uart_config *config = dev->config; + struct dma_status dma_stat; + int ret; + bool use_cache = false; + unsigned int key = irq_lock(); + + if (config->tx_dma.channel == 0xFF) { + LOG_ERR("Tx DMA channel is not configured"); + ret = -ENOTSUP; + goto unlock; + } + + ret = dma_get_status(config->tx_dma.dev, config->tx_dma.channel, &dma_stat); + if (ret < 0 || dma_stat.busy) { + LOG_ERR("DMA Tx %s", ret < 0 ? "error" : "busy"); + irq_unlock(key); + return ret < 0 ? ret : -EBUSY; + } + + data->async.tx.buf = buf; + data->async.tx.len = len; + data->async.tx.src = data->async.tx.buf; + + if (((uint32_t)buf < MXC_SRAM_MEM_BASE) || + (((uint32_t)buf + len) > (MXC_SRAM_MEM_BASE + MXC_SRAM_MEM_SIZE))) { + use_cache = true; + len = load_tx_cache(data->async.tx.src, MIN(len, CONFIG_UART_TX_CACHE_LEN), + data->async.tx.cache[0]); + data->async.tx.src += len; + data->async.tx.cache_id = 0; + } + + ret = uart_max32_tx_dma_load(dev, use_cache ? data->async.tx.cache[0] : ((uint8_t *)buf), + len); + if (ret < 0) { + LOG_ERR("Error configuring Tx DMA (%d)", ret); + goto unlock; + } + + ret = dma_start(config->tx_dma.dev, config->tx_dma.channel); + if (ret < 0) { + LOG_ERR("Error starting Tx DMA (%d)", ret); + goto unlock; + } + + data->async.tx.timeout = timeout; + async_timer_start(&data->async.tx.timeout_work, timeout); + + Wrap_MXC_UART_SetTxDMALevel(config->regs, 2); + Wrap_MXC_UART_EnableTxDMA(config->regs); + +unlock: + irq_unlock(key); + + return ret; +} + +static int api_tx_abort(const struct device *dev) +{ + int ret; + struct max32_uart_data *data = dev->data; + const struct max32_uart_config *config = dev->config; + struct dma_status dma_stat; + size_t bytes_sent; + + unsigned int key = irq_lock(); + + k_work_cancel_delayable(&data->async.tx.timeout_work); + + Wrap_MXC_UART_DisableTxDMA(config->regs); + + ret = dma_get_status(config->tx_dma.dev, config->tx_dma.channel, &dma_stat); + if (!dma_stat.busy) { + irq_unlock(key); + return 0; + } + + bytes_sent = (ret == 0) ? (data->async.tx.len - dma_stat.pending_length) : 0; + + ret = dma_stop(config->tx_dma.dev, config->tx_dma.channel); + + irq_unlock(key); + + if (ret == 0) { + struct uart_event tx_aborted = { + .type = UART_TX_ABORTED, + .data.tx.buf = data->async.tx.buf, + .data.tx.len = bytes_sent, + }; + async_user_callback(dev, &tx_aborted); + } + + return 0; +} + +static void uart_max32_async_tx_timeout(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct max32_uart_async_tx *tx = + CONTAINER_OF(dwork, struct max32_uart_async_tx, timeout_work); + struct max32_uart_async_data *async = CONTAINER_OF(tx, struct max32_uart_async_data, tx); + struct max32_uart_data *data = CONTAINER_OF(async, struct max32_uart_data, async); + + api_tx_abort(data->async.uart_dev); +} + +static int api_rx_disable(const struct device *dev) +{ + struct max32_uart_data *data = dev->data; + const struct max32_uart_config *config = dev->config; + int ret; + unsigned int key = irq_lock(); + + k_work_cancel_delayable(&data->async.rx.timeout_work); + + Wrap_MXC_UART_DisableRxDMA(config->regs); + + ret = dma_stop(config->rx_dma.dev, config->rx_dma.channel); + if (ret) { + LOG_ERR("Error stopping Rx DMA (%d)", ret); + irq_unlock(key); + return ret; + } + + api_irq_rx_disable(dev); + + irq_unlock(key); + + /* Release current buffer event */ + struct uart_event rel_event = { + .type = UART_RX_BUF_RELEASED, + .data.rx_buf.buf = data->async.rx.buf, + }; + async_user_callback(dev, &rel_event); + + /* Disable RX event */ + struct uart_event rx_disabled = {.type = UART_RX_DISABLED}; + + async_user_callback(dev, &rx_disabled); + + data->async.rx.buf = NULL; + data->async.rx.len = 0; + data->async.rx.counter = 0; + data->async.rx.offset = 0; + + if (data->async.rx.next_buf) { + /* Release next buffer event */ + struct uart_event next_rel_event = { + .type = UART_RX_BUF_RELEASED, + .data.rx_buf.buf = data->async.rx.next_buf, + }; + async_user_callback(dev, &next_rel_event); + data->async.rx.next_buf = NULL; + data->async.rx.next_len = 0; + } + + return 0; +} + +static void uart_max32_async_rx_callback(const struct device *dma_dev, void *user_data, + uint32_t channel, int status) +{ + const struct device *dev = user_data; + const struct max32_uart_config *config = dev->config; + struct max32_uart_data *data = dev->data; + struct max32_uart_async_data *async = &data->async; + struct dma_status dma_stat; + size_t total_rx; + + unsigned int key = irq_lock(); + + dma_get_status(config->rx_dma.dev, config->rx_dma.channel, &dma_stat); + + if (dma_stat.pending_length > 0) { + irq_unlock(key); + return; + } + + total_rx = async->rx.len - dma_stat.pending_length; + + api_irq_rx_disable(dev); + + irq_unlock(key); + + if (total_rx > async->rx.offset) { + async->rx.counter = total_rx - async->rx.offset; + struct uart_event rdy_event = { + .type = UART_RX_RDY, + .data.rx.buf = async->rx.buf, + .data.rx.len = async->rx.counter, + .data.rx.offset = async->rx.offset, + }; + async_user_callback(dev, &rdy_event); + } + + if (async->rx.next_buf) { + async->rx.offset = 0; + async->rx.counter = 0; + + struct uart_event rel_event = { + .type = UART_RX_BUF_RELEASED, + .data.rx_buf.buf = async->rx.buf, + }; + async_user_callback(dev, &rel_event); + + async->rx.buf = async->rx.next_buf; + async->rx.len = async->rx.next_len; + + async->rx.next_buf = NULL; + async->rx.next_len = 0; + struct uart_event req_event = { + .type = UART_RX_BUF_REQUEST, + }; + async_user_callback(dev, &req_event); + + dma_reload(config->rx_dma.dev, config->rx_dma.channel, config->rx_dma.slot, + (uint32_t)async->rx.buf, async->rx.len); + dma_start(config->rx_dma.dev, config->rx_dma.channel); + + api_irq_rx_enable(dev); + async_timer_start(&async->rx.timeout_work, async->rx.timeout); + } else { + api_rx_disable(dev); + } +} + +static int api_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout) +{ + struct max32_uart_data *data = dev->data; + const struct max32_uart_config *config = dev->config; + struct dma_status dma_stat; + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int ret; + + unsigned int key = irq_lock(); + + if (config->rx_dma.channel == 0xFF) { + LOG_ERR("Rx DMA channel is not configured"); + irq_unlock(key); + return -ENOTSUP; + } + + ret = dma_get_status(config->rx_dma.dev, config->rx_dma.channel, &dma_stat); + if (ret < 0 || dma_stat.busy) { + LOG_ERR("DMA Rx %s", ret < 0 ? "error" : "busy"); + irq_unlock(key); + return ret < 0 ? ret : -EBUSY; + } + + data->async.rx.buf = buf; + data->async.rx.len = len; + + dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + dma_cfg.dma_callback = uart_max32_async_rx_callback; + dma_cfg.user_data = (void *)dev; + dma_cfg.dma_slot = config->rx_dma.slot; + dma_cfg.block_count = 1; + dma_cfg.source_data_size = 1U; + dma_cfg.source_burst_length = 1U; + dma_cfg.dest_data_size = 1U; + dma_cfg.head_block = &dma_blk; + dma_blk.block_size = len; + dma_blk.dest_address = (uint32_t)buf; + + ret = dma_config(config->rx_dma.dev, config->rx_dma.channel, &dma_cfg); + if (ret < 0) { + LOG_ERR("Error configuring Rx DMA (%d)", ret); + irq_unlock(key); + return ret; + } + + ret = dma_start(config->rx_dma.dev, config->rx_dma.channel); + if (ret < 0) { + LOG_ERR("Error starting Rx DMA (%d)", ret); + irq_unlock(key); + return ret; + } + + data->async.rx.timeout = timeout; + + Wrap_MXC_UART_SetRxDMALevel(config->regs, 1); + Wrap_MXC_UART_EnableRxDMA(config->regs); + + struct uart_event buf_req = { + .type = UART_RX_BUF_REQUEST, + }; + + async_user_callback(dev, &buf_req); + + api_irq_rx_enable(dev); + async_timer_start(&data->async.rx.timeout_work, timeout); + + irq_unlock(key); + return ret; +} + +static int api_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len) +{ + struct max32_uart_data *data = dev->data; + + data->async.rx.next_buf = buf; + data->async.rx.next_len = len; + + return 0; +} + +static void uart_max32_async_rx_timeout(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct max32_uart_async_rx *rx = + CONTAINER_OF(dwork, struct max32_uart_async_rx, timeout_work); + struct max32_uart_async_data *async = CONTAINER_OF(rx, struct max32_uart_async_data, rx); + struct max32_uart_data *data = CONTAINER_OF(async, struct max32_uart_data, async); + const struct max32_uart_config *config = data->async.uart_dev->config; + struct dma_status dma_stat; + uint32_t total_rx; + + unsigned int key = irq_lock(); + + dma_get_status(config->rx_dma.dev, config->rx_dma.channel, &dma_stat); + + api_irq_rx_disable(data->async.uart_dev); + k_work_cancel_delayable(&data->async.rx.timeout_work); + + irq_unlock(key); + + total_rx = async->rx.len - dma_stat.pending_length; + + if (total_rx > async->rx.offset) { + async->rx.counter = total_rx - async->rx.offset; + struct uart_event rdy_event = { + .type = UART_RX_RDY, + .data.rx.buf = async->rx.buf, + .data.rx.len = async->rx.counter, + .data.rx.offset = async->rx.offset, + }; + async_user_callback(async->uart_dev, &rdy_event); + } + async->rx.offset += async->rx.counter; + async->rx.counter = 0; + + api_irq_rx_enable(data->async.uart_dev); +} + +#endif static DEVICE_API(uart, uart_max32_driver_api) = { .poll_in = api_poll_in, @@ -419,12 +982,46 @@ static DEVICE_API(uart, uart_max32_driver_api) = { .irq_update = api_irq_update, .irq_callback_set = api_irq_callback_set, #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API + .callback_set = api_callback_set, + .tx = api_tx, + .tx_abort = api_tx_abort, + .rx_enable = api_rx_enable, + .rx_buf_rsp = api_rx_buf_rsp, + .rx_disable = api_rx_disable, +#endif /* CONFIG_UART_ASYNC_API */ }; +#ifdef CONFIG_UART_ASYNC_API +#define MAX32_DT_INST_DMA_CTLR(n, name) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ + (DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, name))), (NULL)) + +#define MAX32_DT_INST_DMA_CELL(n, name, cell) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), (DT_INST_DMAS_CELL_BY_NAME(n, name, cell)), \ + (0xff)) + +#define MAX32_UART_DMA_INIT(n) \ + .tx_dma.dev = MAX32_DT_INST_DMA_CTLR(n, tx), \ + .tx_dma.channel = MAX32_DT_INST_DMA_CELL(n, tx, channel), \ + .tx_dma.slot = MAX32_DT_INST_DMA_CELL(n, tx, slot), \ + .rx_dma.dev = MAX32_DT_INST_DMA_CTLR(n, rx), \ + .rx_dma.channel = MAX32_DT_INST_DMA_CELL(n, rx, channel), \ + .rx_dma.slot = MAX32_DT_INST_DMA_CELL(n, rx, slot), +#else +#define MAX32_UART_DMA_INIT(n) +#endif + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) +#define MAX32_UART_USE_IRQ 1 +#else +#define MAX32_UART_USE_IRQ 0 +#endif + #define MAX32_UART_INIT(_num) \ PINCTRL_DT_INST_DEFINE(_num); \ - IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ - (static void uart_max32_irq_init_##_num(const struct device *dev) \ + IF_ENABLED(MAX32_UART_USE_IRQ, \ + (static void uart_max32_irq_init_##_num(const struct device *dev) \ { \ IRQ_CONNECT(DT_INST_IRQN(_num), DT_INST_IRQ(_num, priority), \ uart_max32_isr, DEVICE_DT_INST_GET(_num), 0); \ @@ -438,14 +1035,14 @@ static DEVICE_API(uart, uart_max32_driver_api) = { .perclk.bit = DT_INST_CLOCKS_CELL(_num, bit), \ .perclk.clk_src = \ DT_INST_PROP_OR(_num, clock_source, ADI_MAX32_PRPH_CLK_SRC_PCLK), \ - .uart_conf.baudrate = DT_INST_PROP_OR(_num, current_speed, 115200), \ - .uart_conf.parity = DT_INST_ENUM_IDX_OR(_num, parity, UART_CFG_PARITY_NONE), \ - .uart_conf.data_bits = DT_INST_ENUM_IDX_OR(_num, data_bits, UART_CFG_DATA_BITS_8), \ - .uart_conf.stop_bits = DT_INST_ENUM_IDX_OR(_num, stop_bits, UART_CFG_STOP_BITS_1), \ + .uart_conf.baudrate = DT_INST_PROP(_num, current_speed), \ + .uart_conf.parity = DT_INST_ENUM_IDX(_num, parity), \ + .uart_conf.data_bits = DT_INST_ENUM_IDX(_num, data_bits), \ + .uart_conf.stop_bits = DT_INST_ENUM_IDX(_num, stop_bits), \ .uart_conf.flow_ctrl = \ - DT_INST_PROP_OR(_num, hw_flow_control, UART_CFG_FLOW_CTRL_NONE), \ - IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ - (.irq_config_func = uart_max32_irq_init_##_num,))}; \ + DT_INST_PROP_OR(index, hw_flow_control, UART_CFG_FLOW_CTRL_NONE), \ + MAX32_UART_DMA_INIT(_num) IF_ENABLED( \ + MAX32_UART_USE_IRQ, (.irq_config_func = uart_max32_irq_init_##_num,))}; \ static struct max32_uart_data max32_uart_data##_num = { \ IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (.cb = NULL,))}; \ DEVICE_DT_INST_DEFINE(_num, uart_max32_init, NULL, &max32_uart_data##_num, \ diff --git a/drivers/serial/uart_mchp_mec5.c b/drivers/serial/uart_mchp_mec5.c new file mode 100644 index 0000000000000..61f0a010e8394 --- /dev/null +++ b/drivers/serial/uart_mchp_mec5.c @@ -0,0 +1,662 @@ +/* + * Copyright (c) 2024 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Microchip MEC5 ns16550 compatible UART Serial Driver + */ + +#define DT_DRV_COMPAT microchip_mec5_uart + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(uart_mec5, CONFIG_UART_LOG_LEVEL); + +/* MEC5 HAL */ +#include +#include +#include + +#define UART_MEC_DFLT_CLK_FREQ 1843200u +#define UART_MEC_DEVCFG_FLAG_RX_FIFO_TRIG_POS 0 +#define UART_MEC_DEVCFG_FLAG_RX_FIFO_TRIG_MSK 0x3u +#define UART_MEC_DEVCFG_FLAG_FIFO_DIS_POS 4 +#define UART_MEC_DEVCFG_FLAG_USE_EXTCLK_POS 5 + +struct uart_mec5_devcfg { + struct mec_uart_regs *regs; + const struct pinctrl_dev_config *pcfg; + uint32_t clock_freq; + uint32_t flags; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + void (*irq_config_func)(const struct device *dev); +#endif +}; + +struct uart_mec5_dev_data { + const struct device *dev; + struct uart_config current_config; + struct uart_config ucfg; + struct k_spinlock lock; + enum mec_uart_ipend ipend; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t cb; /* Callback function pointer */ + void *cb_data; /* Callback function arg */ + uint32_t flags; + uint8_t rx_enabled; + uint8_t tx_enabled; +#endif +}; + +static const uint8_t mec5_xlat_word_len[4] = { + MEC_UART_WORD_LEN_5, + MEC_UART_WORD_LEN_6, + MEC_UART_WORD_LEN_7, + MEC_UART_WORD_LEN_8, +}; + +static const uint8_t mec5_xlat_stop_bits[4] = { + MEC_UART_STOP_BITS_1, + MEC_UART_STOP_BITS_1, + MEC_UART_STOP_BITS_2, + MEC_UART_STOP_BITS_2, +}; + +static const uint8_t mec5_xlat_parity[5] = { + (uint8_t)(MEC5_UART_CFG_PARITY_NONE >> MEC5_UART_CFG_PARITY_POS), + (uint8_t)(MEC5_UART_CFG_PARITY_ODD >> MEC5_UART_CFG_PARITY_POS), + (uint8_t)(MEC5_UART_CFG_PARITY_EVEN >> MEC5_UART_CFG_PARITY_POS), + (uint8_t)(MEC5_UART_CFG_PARITY_MARK >> MEC5_UART_CFG_PARITY_POS), + (uint8_t)(MEC5_UART_CFG_PARITY_SPACE >> MEC5_UART_CFG_PARITY_POS), +}; + +static int uart_mec5_xlat_cfg(const struct uart_config *cfg, uint32_t *cfg_word) +{ + uint32_t temp; + + if (!cfg || !cfg_word) { + return -EINVAL; + } + + *cfg_word = 0u; + + if (cfg->data_bits > UART_CFG_DATA_BITS_8) { + return -EINVAL; + } + temp = mec5_xlat_word_len[cfg->data_bits]; + *cfg_word |= ((temp << MEC5_UART_CFG_WORD_LEN_POS) & MEC5_UART_CFG_WORD_LEN_MSK); + + if (cfg->stop_bits > UART_CFG_STOP_BITS_2) { + return -EINVAL; + } + temp = mec5_xlat_stop_bits[cfg->stop_bits]; + *cfg_word |= ((temp << MEC5_UART_CFG_STOP_BITS_POS) & MEC5_UART_CFG_STOP_BITS_MSK); + + if (cfg->parity > UART_CFG_PARITY_SPACE) { + return -EINVAL; + } + temp = mec5_xlat_parity[cfg->parity]; + *cfg_word |= ((temp << MEC5_UART_CFG_PARITY_POS) & MEC5_UART_CFG_PARITY_MSK); + + return 0; +} + +/* Configure UART TX and RX FIFOs based on device tree. + * Both FIFOs are fixed 16-byte. + * RX FIFO has a configurable interrupt trigger level of 1, 4, 8, or 14 bytes. + */ +static uint32_t uart_mec5_fifo_config(uint32_t mcfg, uint32_t cfg_flags) +{ + uint32_t new_mcfg = mcfg; + uint32_t temp = 0; + + if (!(cfg_flags & BIT(UART_MEC_DEVCFG_FLAG_FIFO_DIS_POS))) { + new_mcfg |= BIT(MEC5_UART_CFG_FIFO_EN_POS); + temp = (cfg_flags & UART_MEC_DEVCFG_FLAG_RX_FIFO_TRIG_MSK) >> + UART_MEC_DEVCFG_FLAG_RX_FIFO_TRIG_POS; + switch (temp) { + case 0: + new_mcfg |= MEC5_UART_CFG_RX_FIFO_TRIG_LVL_1; + break; + case 1: + new_mcfg |= MEC5_UART_CFG_RX_FIFO_TRIG_LVL_4; + break; + case 2: + new_mcfg |= MEC5_UART_CFG_RX_FIFO_TRIG_LVL_8; + break; + default: + new_mcfg |= MEC5_UART_CFG_RX_FIFO_TRIG_LVL_14; + break; + } + } + + return new_mcfg; +} + +static int config_mec5_uart(const struct device *dev, const struct uart_config *cfg) +{ + const struct uart_mec5_devcfg *devcfg = dev->config; + struct mec_uart_regs *const regs = devcfg->regs; + struct uart_mec5_dev_data *const data = dev->data; + int ret = 0; + uint32_t mcfg = 0, extclk = 0; + + data->ipend = MEC_UART_IPEND_NONE; + + ret = uart_mec5_xlat_cfg(cfg, &mcfg); + if (ret) { + return ret; + } + + mcfg = uart_mec5_fifo_config(mcfg, devcfg->flags); + mcfg |= BIT(MEC5_UART_CFG_GIRQ_EN_POS); + + if (devcfg->flags & BIT(UART_MEC_DEVCFG_FLAG_USE_EXTCLK_POS)) { + extclk = devcfg->clock_freq; + } + + ret = mec_hal_uart_init(regs, cfg->baudrate, mcfg, extclk); + if (ret != MEC_RET_OK) { + return -EIO; + } + + memcpy(&data->ucfg, cfg, sizeof(struct uart_config)); + + return ret; +}; + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +/* run-time driver configuration API */ +static int uart_mec5_configure(const struct device *dev, const struct uart_config *cfg) +{ + const struct uart_mec5_devcfg *devcfg = dev->config; + struct uart_mec5_dev_data *const data = dev->data; + int ret = 0; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + ret = pinctrl_apply_state(devcfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret) { + LOG_ERR("MEC5 UART pinctrl error (%d)", ret); + } + + ret = config_mec5_uart(dev, cfg); + if (ret) { + LOG_ERR("MEC5 UART config error (%d)", ret); + return ret; + } + + data->current_config = *cfg; + + k_spin_unlock(&data->lock, key); + + return ret; +} + +static int uart_mec5_config_get(const struct device *dev, struct uart_config *cfg) +{ + struct uart_mec5_dev_data *const data = dev->data; + + if (!cfg) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + *cfg = data->current_config; + + k_spin_unlock(&data->lock, key); + + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +/* Called by kernel during driver initialization phase */ +static int uart_mec5_init(const struct device *dev) +{ + const struct uart_mec5_devcfg *devcfg = dev->config; + struct uart_mec5_dev_data *data = dev->data; + int ret = 0; + + ret = pinctrl_apply_state(devcfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret) { + LOG_ERR("MEC5 UART init pinctrl error (%d)", ret); + return ret; + } + + ret = config_mec5_uart(dev, &data->ucfg); + if (ret != 0) { + return -EIO; + } + + return ret; +} + +/* + * Poll the UART for input. + * return 0 is a byte arrived else -1 if no data. + */ +static int uart_mec5_poll_in(const struct device *dev, unsigned char *cptr) +{ + const struct uart_mec5_devcfg *devcfg = dev->config; + struct mec_uart_regs *const regs = devcfg->regs; + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + int ret = 0; + + ret = mec_hal_uart_rx_byte(regs, (uint8_t *)cptr); + if (ret == MEC_RET_ERR_NO_DATA) { + k_spin_unlock(&data->lock, key); + return -1; + } + + k_spin_unlock(&data->lock, key); + + return 0; +} + +/* Block until UART can accept data byte. */ +static void uart_mec5_poll_out(const struct device *dev, unsigned char out_data) +{ + const struct uart_mec5_devcfg *devcfg = dev->config; + struct mec_uart_regs *const regs = devcfg->regs; + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + int ret = 0; + + do { + ret = mec_hal_uart_tx_byte(regs, (uint8_t)out_data); + } while (ret == MEC_RET_ERR_BUSY); + + k_spin_unlock(&data->lock, key); +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static inline void irq_tx_enable(const struct device *dev) +{ + const struct uart_mec5_devcfg *devcfg = dev->config; + struct mec_uart_regs *const regs = devcfg->regs; + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ETHREI, MEC_UART_IEN_FLAG_ETHREI); + + k_spin_unlock(&data->lock, key); +} + +static inline void irq_tx_disable(const struct device *dev) +{ + const struct uart_mec5_devcfg *devcfg = dev->config; + struct uart_mec5_dev_data *data = dev->data; + struct mec_uart_regs *const regs = devcfg->regs; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ETHREI, 0); + + k_spin_unlock(&data->lock, key); +} + +static inline void irq_rx_enable(const struct device *dev) +{ + const struct uart_mec5_devcfg *const devcfg = dev->config; + struct uart_mec5_dev_data *data = dev->data; + struct mec_uart_regs *const regs = devcfg->regs; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ERDAI, MEC_UART_IEN_FLAG_ERDAI); + + k_spin_unlock(&data->lock, key); +} + +static inline void irq_rx_disable(const struct device *dev) +{ + const struct uart_mec5_devcfg *const devcfg = dev->config; + struct uart_mec5_dev_data *data = dev->data; + struct mec_uart_regs *const regs = devcfg->regs; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ERDAI, 0); + + k_spin_unlock(&data->lock, key); +} + +static int uart_mec5_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) +{ + const struct uart_mec5_devcfg *const devcfg = dev->config; + struct uart_mec5_dev_data *data = dev->data; + struct mec_uart_regs *const regs = devcfg->regs; + int num_tx = 0, ret = 0; + + if (len < 0) { + return 0; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + while (num_tx < len) { + ret = mec_hal_uart_tx_byte(regs, tx_data[num_tx]); + if (ret == MEC_RET_ERR_BUSY) { + break; + } + num_tx++; + } + + if (data->tx_enabled) { + irq_tx_enable(dev); + } + + k_spin_unlock(&data->lock, key); + + return num_tx; +} + +static int uart_mec5_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + const struct uart_mec5_devcfg *const devcfg = dev->config; + struct uart_mec5_dev_data *data = dev->data; + struct mec_uart_regs *const regs = devcfg->regs; + int num_rx = 0, ret = 0; + + if (size < 0) { + return 0; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + uint8_t *pdata = rx_data; + + while (num_rx < size) { + ret = mec_hal_uart_rx_byte(regs, pdata); + if (ret != MEC_RET_OK) { + break; + } + pdata++; + num_rx++; + } + + if (data->rx_enabled) { + irq_rx_enable(dev); + } + + k_spin_unlock(&data->lock, key); + + return num_rx; +} + +static void uart_mec5_irq_tx_enable(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->tx_enabled = 1; + irq_tx_enable(dev); + + k_spin_unlock(&data->lock, key); +} + +static void uart_mec5_irq_tx_disable(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + irq_tx_disable(dev); + data->tx_enabled = 0; + + k_spin_unlock(&data->lock, key); +} + +static int uart_mec5_irq_tx_ready(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + int ret = 0; + + if (data->ipend == MEC_UART_IPEND_TX) { + ret = 1; + } + + k_spin_unlock(&data->lock, key); + + return ret; +} + +static void uart_mec5_irq_rx_enable(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->rx_enabled = 1; + irq_rx_enable(dev); + + k_spin_unlock(&data->lock, key); +} + +static void uart_mec5_irq_rx_disable(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + irq_rx_disable(dev); + data->rx_enabled = 0; + + k_spin_unlock(&data->lock, key); +} + +/* check if UART TX shift register is empty. Empty TX shift register indicates + * the UART does not need clocks and can be put into a low power state. + * return 1 nothing remains to be transmitted, 0 otherwise. + */ +static int uart_mec5_irq_tx_complete(const struct device *dev) +{ + const struct uart_mec5_devcfg *const devcfg = dev->config; + struct mec_uart_regs *const regs = devcfg->regs; + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + int ret = mec_hal_uart_is_tx_empty(regs); + + k_spin_unlock(&data->lock, key); + + return ret; +} + +static int uart_mec5_irq_rx_ready(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + int ret = 0; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if (data->ipend == MEC_UART_IPEND_RX_DATA) { + ret = 1; + } + + k_spin_unlock(&data->lock, key); + + return ret; +} + +static void irq_error_enable(const struct device *dev, uint8_t enable) +{ + const struct uart_mec5_devcfg *const devcfg = dev->config; + struct mec_uart_regs *const regs = devcfg->regs; + uint8_t msk = 0; + + if (enable) { + msk = MEC_UART_IEN_FLAG_ELSI; + } + + mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ELSI, msk); +} + +/* + * Enable received line status interrupt active when one or more of the following errors + * occur: overrun, parity, framing, or break. + */ +static void uart_mec5_irq_err_enable(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + irq_error_enable(dev, 1u); + + k_spin_unlock(&data->lock, key); +} + +static void uart_mec5_irq_err_disable(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + irq_error_enable(dev, 0); + + k_spin_unlock(&data->lock, key); +} + +static int uart_mec5_irq_is_pending(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + int ret = 0; + + if (data->ipend != MEC_UART_IPEND_NONE) { + ret = 1; + } + + k_spin_unlock(&data->lock, key); + + return ret; +} + +static int uart_mec5_irq_update(const struct device *dev) +{ + const struct uart_mec5_devcfg *const devcfg = dev->config; + struct mec_uart_regs *const regs = devcfg->regs; + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->ipend = MEC_UART_IPEND_NONE; + mec_hal_uart_pending_status(regs, &data->ipend); + + switch (data->ipend) { + case MEC_UART_IPEND_NONE: + break; + case MEC_UART_IPEND_TX: + irq_tx_disable(dev); + break; + case MEC_UART_IPEND_RX_DATA: + irq_rx_disable(dev); + break; + case MEC_UART_IPEND_RX_ERR: + irq_error_enable(dev, 0); + break; + case MEC_UART_IPEND_MODEM: + __fallthrough; /* fall through */ + default: + k_panic(); + break; + } + + k_spin_unlock(&data->lock, key); + + return 1; +} + +static void uart_mec5_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *cb_data) +{ + struct uart_mec5_dev_data *data = dev->data; + k_spinlock_key_t key = k_spin_lock(&data->lock); + + data->cb = cb; + data->cb_data = cb_data; + + k_spin_unlock(&data->lock, key); +} + +static void uart_mec5_isr(const struct device *dev) +{ + struct uart_mec5_dev_data *data = dev->data; + + if (data->cb) { + data->cb(dev, data->cb_data); + } +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static DEVICE_API(uart, uart_mec5_driver_api) = { + .poll_in = uart_mec5_poll_in, + .poll_out = uart_mec5_poll_out, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_mec5_configure, + .config_get = uart_mec5_config_get, +#endif +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_mec5_fifo_fill, + .fifo_read = uart_mec5_fifo_read, + .irq_tx_enable = uart_mec5_irq_tx_enable, + .irq_tx_disable = uart_mec5_irq_tx_disable, + .irq_tx_ready = uart_mec5_irq_tx_ready, + .irq_rx_enable = uart_mec5_irq_rx_enable, + .irq_rx_disable = uart_mec5_irq_rx_disable, + .irq_tx_complete = uart_mec5_irq_tx_complete, + .irq_rx_ready = uart_mec5_irq_rx_ready, + .irq_err_enable = uart_mec5_irq_err_enable, + .irq_err_disable = uart_mec5_irq_err_disable, + .irq_is_pending = uart_mec5_irq_is_pending, + .irq_update = uart_mec5_irq_update, + .irq_callback_set = uart_mec5_irq_callback_set, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define UART_MEC5_CONFIGURE(n) \ + do { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), uart_mec5_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + \ + irq_enable(DT_INST_IRQN(n)); \ + } while (0) +#else +#define UART_MEC5_CONFIGURE(n) +#endif + +#define UART_MEC5_DCFG_FLAGS(i) \ + ((DT_INST_ENUM_IDX_OR(i, rx_fifo_trig, 2) & 0x3u) | \ + ((DT_INST_PROP_OR(i, fifo_mode_disable, 0) & 0x1u) << 4) | \ + ((DT_INST_PROP_OR(i, use_extclk, 0) & 0x1u) << 5)) + +#define DEV_DATA_FLOW_CTRL(n) DT_INST_PROP_OR(n, hw_flow_control, UART_CFG_FLOW_CTRL_NONE) + +#define UART_MEC5_DEVICE(i) \ + PINCTRL_DT_INST_DEFINE(i); \ + static const struct uart_mec5_devcfg uart_mec5_##i##_devcfg = { \ + .regs = (struct mec_uart_regs *)DT_INST_REG_ADDR(i), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(i), \ + .clock_freq = DT_INST_PROP_OR(i, clock_frequency, UART_MEC_DFLT_CLK_FREQ), \ + .flags = UART_MEC5_DCFG_FLAGS(i), \ + }; \ + static struct uart_mec5_dev_data uart_mec5_##i##_dev_data = { \ + .ucfg.baudrate = DT_INST_PROP_OR(i, current_speed, 0), \ + .ucfg.parity = UART_CFG_PARITY_NONE, \ + .ucfg.stop_bits = UART_CFG_STOP_BITS_1, \ + .ucfg.data_bits = UART_CFG_DATA_BITS_8, \ + .ucfg.flow_ctrl = DEV_DATA_FLOW_CTRL(i), \ + }; \ + static int uart_mec5_##i##_init(const struct device *dev) \ + { \ + UART_MEC5_CONFIGURE(i); \ + return uart_mec5_init(dev); \ + } \ + DEVICE_DT_INST_DEFINE(i, uart_mec5_##i##_init, NULL, &uart_mec5_##i##_dev_data, \ + &uart_mec5_##i##_devcfg, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_mec5_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(UART_MEC5_DEVICE) diff --git a/drivers/serial/uart_mcux_flexcomm.c b/drivers/serial/uart_mcux_flexcomm.c index b0a51b4d1a359..fcb7f41121e0e 100644 --- a/drivers/serial/uart_mcux_flexcomm.c +++ b/drivers/serial/uart_mcux_flexcomm.c @@ -1188,7 +1188,7 @@ static const struct mcux_flexcomm_config mcux_flexcomm_##n##_config = { \ .clock_subsys = \ (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ .baud_rate = DT_INST_PROP(n, current_speed), \ - .parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ UART_MCUX_FLEXCOMM_IRQ_CFG_FUNC_INIT(n) \ UART_MCUX_FLEXCOMM_ASYNC_CFG(n) \ diff --git a/drivers/serial/uart_mcux_iuart.c b/drivers/serial/uart_mcux_iuart.c index 6906d6c98b644..2024efa760378 100644 --- a/drivers/serial/uart_mcux_iuart.c +++ b/drivers/serial/uart_mcux_iuart.c @@ -329,7 +329,7 @@ static const struct mcux_iuart_config mcux_iuart_##n##_config = { \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ .baud_rate = DT_INST_PROP(n, current_speed), \ - .parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ IRQ_FUNC_INIT \ } diff --git a/drivers/serial/uart_mcux_lpuart.c b/drivers/serial/uart_mcux_lpuart.c index 87b6f7d571739..c39635b4128c4 100644 --- a/drivers/serial/uart_mcux_lpuart.c +++ b/drivers/serial/uart_mcux_lpuart.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nxp_kinetis_lpuart +#define DT_DRV_COMPAT nxp_lpuart #include #include @@ -19,6 +19,7 @@ #include #endif #include +#include #include #if CONFIG_NXP_LP_FLEXCOMM @@ -47,9 +48,6 @@ struct lpuart_dma_config { struct mcux_lpuart_config { LPUART_Type *base; -#ifdef CONFIG_NXP_LP_FLEXCOMM - const struct device *parent_dev; -#endif const struct device *clock_dev; const struct pinctrl_dev_config *pincfg; clock_control_subsys_t clock_subsys; @@ -1211,20 +1209,12 @@ static int mcux_lpuart_init(const struct device *dev) } #ifdef CONFIG_UART_MCUX_LPUART_ISR_SUPPORT -#if CONFIG_NXP_LP_FLEXCOMM - /* When using LP Flexcomm driver, register the interrupt handler - * so we receive notification from the LP Flexcomm interrupt handler. - */ - nxp_lp_flexcomm_setirqhandler(config->parent_dev, dev, - LP_FLEXCOMM_PERIPH_LPUART, mcux_lpuart_isr); -#else - /* Interrupt is managed by this driver */ config->irq_config_func(dev); #endif + #ifdef CONFIG_UART_EXCLUSIVE_API_CALLBACKS data->api_type = LPUART_NONE; #endif -#endif #ifdef CONFIG_PM data->pm_state_lock_on = false; @@ -1279,15 +1269,26 @@ static DEVICE_API(uart, mcux_lpuart_driver_api) = { \ irq_enable(DT_INST_IRQ_BY_IDX(n, i, irq)); \ } while (false) +#define MCUX_LPUART_IRQS_INSTALL(n) \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ + (MCUX_LPUART_IRQ_INSTALL(n, 0);)) \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 1), \ + (MCUX_LPUART_IRQ_INSTALL(n, 1);)) +/* When using LP Flexcomm driver, register the interrupt handler + * so we receive notification from the LP Flexcomm interrupt handler. + */ +#define MCUX_LPUART_LPFLEXCOMM_IRQ_CONFIG(n) \ + nxp_lp_flexcomm_setirqhandler(DEVICE_DT_GET(DT_INST_PARENT(n)), \ + DEVICE_DT_INST_GET(n), \ + LP_FLEXCOMM_PERIPH_LPUART, \ + mcux_lpuart_isr) #define MCUX_LPUART_IRQ_INIT(n) .irq_config_func = mcux_lpuart_config_func_##n, #define MCUX_LPUART_IRQ_DEFINE(n) \ static void mcux_lpuart_config_func_##n(const struct device *dev) \ { \ - IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ - (MCUX_LPUART_IRQ_INSTALL(n, 0);)) \ - \ - IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 1), \ - (MCUX_LPUART_IRQ_INSTALL(n, 1);)) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), nxp_lp_flexcomm), \ + (MCUX_LPUART_LPFLEXCOMM_IRQ_CONFIG(n)), \ + (MCUX_LPUART_IRQS_INSTALL(n))); \ } #else #define MCUX_LPUART_IRQ_INIT(n) @@ -1353,22 +1354,15 @@ static DEVICE_API(uart, mcux_lpuart_driver_api) = { : DT_INST_PROP(n, nxp_rs485_mode)\ ? UART_CFG_FLOW_CTRL_RS485 \ : UART_CFG_FLOW_CTRL_NONE -#ifdef CONFIG_NXP_LP_FLEXCOMM -#define PARENT_DEV(n) \ - .parent_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), -#else -#define PARENT_DEV(n) -#endif /* CONFIG_NXP_LP_FLEXCOMM */ #define LPUART_MCUX_DECLARE_CFG(n) \ static const struct mcux_lpuart_config mcux_lpuart_##n##_config = { \ .base = (LPUART_Type *) DT_INST_REG_ADDR(n), \ - PARENT_DEV(n) \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ .baud_rate = DT_INST_PROP(n, current_speed), \ .flow_ctrl = FLOW_CONTROL(n), \ - .parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ .rs485_de_active_low = DT_INST_PROP(n, nxp_rs485_de_active_low), \ .loopback_en = DT_INST_PROP(n, nxp_loopback), \ .single_wire = DT_INST_PROP(n, single_wire), \ diff --git a/drivers/serial/uart_neorv32.c b/drivers/serial/uart_neorv32.c index c4668e7e27cfd..8165ff7277eb8 100644 --- a/drivers/serial/uart_neorv32.c +++ b/drivers/serial/uart_neorv32.c @@ -491,8 +491,7 @@ static DEVICE_API(uart, neorv32_uart_driver_api) = { static struct neorv32_uart_data neorv32_uart_##n##_data = { \ .uart_cfg = { \ .baudrate = DT_PROP(node_id, current_speed), \ - .parity = DT_ENUM_IDX_OR(node_id, parity, \ - UART_CFG_PARITY_NONE), \ + .parity = DT_ENUM_IDX(node_id, parity), \ .stop_bits = UART_CFG_STOP_BITS_1, \ .data_bits = UART_CFG_DATA_BITS_8, \ .flow_ctrl = DT_PROP(node_id, hw_flow_control) ? \ diff --git a/drivers/serial/uart_npcx.c b/drivers/serial/uart_npcx.c index fc68fce79b046..14e32c62ae1b9 100644 --- a/drivers/serial/uart_npcx.c +++ b/drivers/serial/uart_npcx.c @@ -1066,6 +1066,9 @@ static int uart_npcx_init(const struct device *dev) /* Disable all UART tx FIFO interrupts */ uart_npcx_dis_all_tx_interrupts(dev); + /* Disable rx FIFO not empty interrupt */ + uart_npcx_irq_rx_disable(dev); + /* Clear UART rx FIFO */ uart_npcx_clear_rx_fifo(dev); diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index 8b139e99abc5d..b973ce9fd7af9 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -23,10 +23,7 @@ #include #include #include - -#ifdef CONFIG_SOC_NRF54H20_GPD -#include -#endif +#include LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL); @@ -110,6 +107,35 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL); #define UARTE_ANY_LOW_POWER 1 #endif +#ifdef CONFIG_SOC_NRF54H20_GPD +#include + +/* Macro must resolve to literal 0 or 1 */ +#define INSTANCE_IS_FAST_PD(unused, prefix, idx, _) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), \ + (COND_CODE_1(DT_NODE_HAS_PROP(UARTE(idx), power_domains), \ + (IS_EQ(DT_PHA(UARTE(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)), \ + (0))), (0)) + +#if UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_FAST_PD, (||), (0)) +/* Instance in fast power domain (PD) requires special PM treatment so device runtime PM must + * be enabled. + */ +BUILD_ASSERT(IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)); +#define UARTE_ANY_FAST_PD 1 +#endif +#endif + +#define INSTANCE_IS_HIGH_SPEED(unused, prefix, idx, _) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(prefix##idx)), \ + ((NRF_PERIPH_GET_FREQUENCY(UARTE(prefix##idx)) > NRF_UARTE_BASE_FREQUENCY_16MHZ)), \ + (0)) + +/* Macro determines if there is any high speed instance (instance that is driven using + * clock that is faster than 16 MHz). + */ +#define UARTE_ANY_HIGH_SPEED (UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_HIGH_SPEED, (||), (0))) + #ifdef UARTE_ANY_CACHE /* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance * is used then baudrate must be set after enabling the peripheral and not before. @@ -240,6 +266,17 @@ struct uarte_nrfx_data { /* If enabled then UARTE peripheral is using memory which is cacheable. */ #define UARTE_CFG_FLAG_CACHEABLE BIT(3) +/* Formula for getting the baudrate settings is following: + * 2^12 * (2^20 / (f_PCLK / desired_baudrate)) where f_PCLK is a frequency that + * drives the UARTE. + * + * @param f_pclk Frequency of the clock that drives the peripheral. + * @param baudrate Desired baudrate. + * + * @return Baudrate setting to be written to the BAUDRATE register + */ +#define UARTE_GET_CUSTOM_BAUDRATE(f_pclk, baudrate) ((BIT(20) / (f_pclk / baudrate)) << 12) + /* Macro for converting numerical baudrate to register value. It is convenient * to use this approach because for constant input it can calculate nrf setting * at compile time. @@ -269,6 +306,21 @@ struct uarte_nrfx_data { (IS_ENABLED(UARTE_ANY_LOW_POWER) && \ !IS_ENABLED(CONFIG_PM_DEVICE) && \ (_config->flags & UARTE_CFG_FLAG_LOW_POWER)) + +/** @brief Check if device has PM that works in ISR safe mode. + * + * Only fast UARTE instance does not work in that mode so check PM configuration + * flags only if there is any fast instance present. + * + * @retval true if device PM is ISR safe. + * @retval false if device PM is not ISR safe. + */ +#define IS_PM_ISR_SAFE(dev) \ + (!IS_ENABLED(UARTE_ANY_FAST_PD) ||\ + COND_CODE_1(CONFIG_PM_DEVICE,\ + ((dev->pm_base->flags & BIT(PM_DEVICE_FLAG_ISR_SAFE))), \ + (0))) + /** * @brief Structure for UARTE configuration. */ @@ -280,6 +332,10 @@ struct uarte_nrfx_config { #ifdef CONFIG_HAS_NORDIC_DMM void *mem_reg; #endif +#ifdef UARTE_ANY_FAST_PD + const struct device *clk_dev; + struct nrf_clock_spec clk_spec; +#endif #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE /* None-zero in case of high speed instances. Baudrate is adjusted by that ratio. */ uint32_t clock_freq; @@ -300,6 +356,13 @@ struct uarte_nrfx_config { uint8_t *poll_in_byte; }; +/* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case + * where static inline fails on linking. + */ +#define HW_RX_COUNTING_ENABLED(config) \ + (IS_ENABLED(UARTE_ANY_HW_ASYNC) ? \ + (config->flags & UARTE_CFG_FLAG_HW_BYTE_COUNTING) : false) + static inline NRF_UARTE_Type *get_uarte_instance(const struct device *dev) { const struct uarte_nrfx_config *config = dev->config; @@ -322,6 +385,44 @@ static void endtx_isr(const struct device *dev) } +/** @brief Disable UARTE peripheral is not used by RX or TX. + * + * It must be called with interrupts locked so that deciding if no direction is + * using the UARTE is atomically performed with UARTE peripheral disabling. Otherwise + * it would be possible that after clearing flags we get preempted and UARTE is + * enabled from the higher priority context and when we come back UARTE is disabled + * here. + * @param dev Device. + * @param dis_mask Mask of direction (RX or TX) which now longer uses the UARTE instance. + */ +static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask) +{ + struct uarte_nrfx_data *data = dev->data; + + data->flags &= ~dis_mask; + if (data->flags & UARTE_FLAG_LOW_POWER) { + return; + } + +#if defined(UARTE_ANY_ASYNC) && !defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX) + const struct uarte_nrfx_config *config = dev->config; + + if (data->async && HW_RX_COUNTING_ENABLED(config)) { + nrfx_timer_disable(&config->timer); + /* Timer/counter value is reset when disabled. */ + data->async->rx.total_byte_cnt = 0; + data->async->rx.total_user_byte_cnt = 0; + } +#endif + +#ifdef CONFIG_SOC_NRF54H20_GPD + const struct uarte_nrfx_config *cfg = dev->config; + + nrf_gpd_retain_pins_set(cfg->pcfg, true); +#endif + nrf_uarte_disable(get_uarte_instance(dev)); +} + #ifdef UARTE_ANY_NONE_ASYNC /** * @brief Interrupt service routine. @@ -357,7 +458,7 @@ static void uarte_nrfx_isr_int(const void *arg) pm_device_runtime_put_async(dev, K_NO_WAIT); } } else { - nrf_uarte_disable(uarte); + uarte_disable_locked(dev, UARTE_FLAG_LOW_POWER_TX); } #ifdef UARTE_INTERRUPT_DRIVEN if (!data->int_driven) @@ -415,18 +516,19 @@ static void uarte_nrfx_isr_int(const void *arg) static int baudrate_set(const struct device *dev, uint32_t baudrate) { const struct uarte_nrfx_config *config = dev->config; + nrf_uarte_baudrate_t nrf_baudrate; + /* calculated baudrate divisor */ - nrf_uarte_baudrate_t nrf_baudrate = NRF_BAUDRATE(baudrate); + if (UARTE_ANY_HIGH_SPEED && (config->clock_freq > NRF_UARTE_BASE_FREQUENCY_16MHZ)) { + nrf_baudrate = UARTE_GET_CUSTOM_BAUDRATE(config->clock_freq, baudrate); + } else { + nrf_baudrate = NRF_BAUDRATE(baudrate); + } if (nrf_baudrate == 0) { return -EINVAL; } - /* scale baudrate setting */ - if (config->clock_freq > 0U) { - nrf_baudrate /= config->clock_freq / NRF_UARTE_BASE_FREQUENCY_16MHZ; - } - #ifdef UARTE_BAUDRATE_RETENTION_WORKAROUND struct uarte_nrfx_data *data = dev->data; @@ -577,13 +679,6 @@ static int wait_tx_ready(const struct device *dev) return key; } -/* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case - * where static inline fails on linking. - */ -#define HW_RX_COUNTING_ENABLED(config) \ - (IS_ENABLED(UARTE_ANY_HW_ASYNC) ? \ - (config->flags & UARTE_CFG_FLAG_HW_BYTE_COUNTING) : false) - static void uarte_periph_enable(const struct device *dev) { NRF_UARTE_Type *uarte = get_uarte_instance(dev); @@ -591,6 +686,16 @@ static void uarte_periph_enable(const struct device *dev) struct uarte_nrfx_data *data = dev->data; (void)data; +#ifdef UARTE_ANY_FAST_PD + if (config->clk_dev) { + int err; + + err = nrf_clock_control_request_sync(config->clk_dev, &config->clk_spec, K_FOREVER); + (void)err; + __ASSERT_NO_MSG(err >= 0); + } +#endif + nrf_uarte_enable(uarte); #ifdef CONFIG_SOC_NRF54H20_GPD nrf_gpd_retain_pins_set(config->pcfg, false); @@ -672,49 +777,10 @@ static void tx_start(const struct device *dev, const uint8_t *buf, size_t len) if (LOW_POWER_ENABLED(config)) { uarte_enable_locked(dev, UARTE_FLAG_LOW_POWER_TX); } - nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTTX); } #if defined(UARTE_ANY_ASYNC) -/** @brief Disable UARTE peripheral is not used by RX or TX. - * - * It must be called with interrupts locked so that deciding if no direction is - * using the UARTE is atomically performed with UARTE peripheral disabling. Otherwise - * it would be possible that after clearing flags we get preempted and UARTE is - * enabled from the higher priority context and when we come back UARTE is disabled - * here. - * @param dev Device. - * @param dis_mask Mask of direction (RX or TX) which now longer uses the UARTE instance. - */ -static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask) -{ - struct uarte_nrfx_data *data = dev->data; - - data->flags &= ~dis_mask; - if (data->flags & UARTE_FLAG_LOW_POWER) { - return; - } - -#if !defined(CONFIG_UART_NRFX_UARTE_ENHANCED_RX) - const struct uarte_nrfx_config *config = dev->config; - - if (data->async && HW_RX_COUNTING_ENABLED(config)) { - nrfx_timer_disable(&config->timer); - /* Timer/counter value is reset when disabled. */ - data->async->rx.total_byte_cnt = 0; - data->async->rx.total_user_byte_cnt = 0; - } -#endif - -#ifdef CONFIG_SOC_NRF54H20_GPD - const struct uarte_nrfx_config *cfg = dev->config; - - nrf_gpd_retain_pins_set(cfg->pcfg, true); -#endif - nrf_uarte_disable(get_uarte_instance(dev)); -} - static void rx_timeout(struct k_timer *timer); static void tx_timeout(struct k_timer *timer); @@ -873,6 +939,20 @@ static int uarte_nrfx_tx(const struct device *dev, const uint8_t *buf, } if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + if (!IS_PM_ISR_SAFE(dev) && k_is_in_isr()) { + /* If instance does not support PM from ISR device shall + * already be turned on. + */ + enum pm_device_state state; + int err; + + err = pm_device_state_get(dev, &state); + (void)err; + __ASSERT_NO_MSG(err == 0); + if (state != PM_DEVICE_STATE_ACTIVE) { + return -ENOTSUP; + } + } pm_device_runtime_get(dev); } @@ -941,6 +1021,10 @@ static void notify_rx_disable(const struct device *dev) }; user_callback(dev, (struct uart_event *)&evt); + + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + pm_device_runtime_put_async(dev, K_NO_WAIT); + } } #ifdef UARTE_HAS_FRAME_TIMEOUT @@ -1015,6 +1099,24 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf, async_rx->next_buf = NULL; async_rx->next_buf_len = 0; + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + if (!IS_PM_ISR_SAFE(dev) && k_is_in_isr()) { + /* If instance does not support PM from ISR device shall + * already be turned on. + */ + enum pm_device_state state; + int err; + + err = pm_device_state_get(dev, &state); + (void)err; + __ASSERT_NO_MSG(err == 0); + if (state != PM_DEVICE_STATE_ACTIVE) { + return -ENOTSUP; + } + } + pm_device_runtime_get(dev); + } + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) || LOW_POWER_ENABLED(cfg)) { if (async_rx->flush_cnt) { int cpy_len = MIN(len, async_rx->flush_cnt); @@ -1063,14 +1165,20 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf, nrf_uarte_rx_buffer_set(uarte, buf, len); + if (IS_ENABLED(UARTE_ANY_FAST_PD) && (cfg->flags & UARTE_CFG_FLAG_CACHEABLE)) { + /* Spurious RXTO event was seen on fast instance (UARTE120) thus + * RXTO interrupt is kept enabled only when RX is active. + */ + nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXTO); + nrf_uarte_int_enable(uarte, NRF_UARTE_INT_RXTO_MASK); + } + nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_ENDRX); nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXSTARTED); async_rx->enabled = true; - if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { - pm_device_runtime_get(dev); - } else if (LOW_POWER_ENABLED(cfg)) { + if (LOW_POWER_ENABLED(cfg)) { unsigned int key = irq_lock(); uarte_enable_locked(dev, UARTE_FLAG_LOW_POWER_RX); @@ -1537,15 +1645,19 @@ static void rxto_isr(const struct device *dev) #ifdef CONFIG_UART_NRFX_UARTE_ENHANCED_RX NRF_UARTE_Type *uarte = get_uarte_instance(dev); + if (IS_ENABLED(UARTE_ANY_FAST_PD) && (config->flags & UARTE_CFG_FLAG_CACHEABLE)) { + /* Spurious RXTO event was seen on fast instance (UARTE120) thus + * RXTO interrupt is kept enabled only when RX is active. + */ + nrf_uarte_int_disable(uarte, NRF_UARTE_INT_RXTO_MASK); + } #ifdef UARTE_HAS_FRAME_TIMEOUT nrf_uarte_shorts_disable(uarte, NRF_UARTE_SHORT_FRAME_TIMEOUT_STOPRX); #endif nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXDRDY); #endif - if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { - pm_device_runtime_put(dev); - } else if (LOW_POWER_ENABLED(config)) { + if (LOW_POWER_ENABLED(config)) { uint32_t key = irq_lock(); uarte_disable_locked(dev, UARTE_FLAG_LOW_POWER_RX); @@ -1570,7 +1682,7 @@ static void txstopped_isr(const struct device *dev) if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { nrf_uarte_int_disable(uarte, NRF_UARTE_INT_TXSTOPPED_MASK); if (data->flags & UARTE_FLAG_POLL_OUT) { - pm_device_runtime_put(dev); + pm_device_runtime_put_async(dev, K_NO_WAIT); data->flags &= ~UARTE_FLAG_POLL_OUT; } } else if (LOW_POWER_ENABLED(config)) { @@ -1633,11 +1745,11 @@ static void txstopped_isr(const struct device *dev) data->async->tx.buf = NULL; data->async->tx.len = 0; + user_callback(dev, &evt); + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { - pm_device_runtime_put(dev); + pm_device_runtime_put_async(dev, K_NO_WAIT); } - - user_callback(dev, &evt); } static void rxdrdy_isr(const struct device *dev) @@ -1824,6 +1936,22 @@ static void uarte_nrfx_poll_out(const struct device *dev, unsigned char c) } if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + if (!IS_PM_ISR_SAFE(dev) && k_is_in_isr()) { + /* If instance does not support PM from ISR device shall + * already be turned on. + */ + enum pm_device_state state; + int err; + + err = pm_device_state_get(dev, &state); + (void)err; + __ASSERT_NO_MSG(err == 0); + if (state != PM_DEVICE_STATE_ACTIVE) { + irq_unlock(key); + return; + } + } + if (!(data->flags & UARTE_FLAG_POLL_OUT)) { data->flags |= UARTE_FLAG_POLL_OUT; pm_device_runtime_get(dev); @@ -2128,6 +2256,16 @@ static void uarte_pm_suspend(const struct device *dev) struct uarte_nrfx_data *data = dev->data; (void)data; +#ifdef UARTE_ANY_FAST_PD + if (cfg->clk_dev) { + int err; + + err = nrf_clock_control_release(cfg->clk_dev, &cfg->clk_spec); + (void)err; + __ASSERT_NO_MSG(err >= 0); + } +#endif + #ifdef UARTE_ANY_ASYNC if (data->async) { /* Entering inactive state requires device to be no @@ -2311,18 +2449,35 @@ static int uarte_instance_init(const struct device *dev, #define UARTE_DISABLE_RX_INIT(node_id) \ .disable_rx = DT_PROP(node_id, disable_rx) -#define UARTE_GET_FREQ(idx) DT_PROP(DT_CLOCKS_CTLR(UARTE(idx)), clock_frequency) - -#define UARTE_GET_BAUDRATE_DIV(idx) \ - COND_CODE_1(DT_CLOCKS_HAS_IDX(UARTE(idx), 0), \ - ((UARTE_GET_FREQ(idx) / NRF_UARTE_BASE_FREQUENCY_16MHZ)), (1)) +/* Get frequency divider that is used to adjust the BAUDRATE value. */ +#define UARTE_GET_BAUDRATE_DIV(f_pclk) (f_pclk / NRF_UARTE_BASE_FREQUENCY_16MHZ) /* When calculating baudrate we need to take into account that high speed instances * must have baudrate adjust to the ratio between UARTE clocking frequency and 16 MHz. + * Additionally, >1Mbaud speeds are calculated using a formula. */ +#define UARTE_GET_BAUDRATE2(f_pclk, current_speed) \ + ((f_pclk > NRF_UARTE_BASE_FREQUENCY_16MHZ) && (current_speed > 1000000)) ? \ + UARTE_GET_CUSTOM_BAUDRATE(f_pclk, current_speed) : \ + (NRF_BAUDRATE(current_speed) / UARTE_GET_BAUDRATE_DIV(f_pclk)) + +/* Convert DT current-speed to a value that is written to the BAUDRATE register. */ #define UARTE_GET_BAUDRATE(idx) \ - (NRF_BAUDRATE(UARTE_PROP(idx, current_speed)) / UARTE_GET_BAUDRATE_DIV(idx)) + UARTE_GET_BAUDRATE2(NRF_PERIPH_GET_FREQUENCY(UARTE(idx)), UARTE_PROP(idx, current_speed)) +/* Get initialization level of an instance. Instances that requires clock control + * which is using nrfs (IPC) are initialized later. + */ +#define UARTE_INIT_LEVEL(idx) \ + COND_CODE_1(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), (POST_KERNEL), (PRE_KERNEL_1)) + +/* Get initialization priority of an instance. Instances that requires clock control + * which is using nrfs (IPC) are initialized later. + */ +#define UARTE_INIT_PRIO(idx) \ + COND_CODE_1(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), \ + (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \ + (CONFIG_SERIAL_INIT_PRIORITY)) /* Macro for setting nRF specific configuration structures. */ #define UARTE_NRF_CONFIG(idx) { \ @@ -2373,12 +2528,11 @@ static int uarte_instance_init(const struct device *dev, (.int_driven = &uarte##idx##_int_driven,)) \ }; \ COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, (), \ - (BUILD_ASSERT(NRF_BAUDRATE(UARTE_PROP(idx, current_speed)) > 0,\ - "Unsupported baudrate");)) \ + (BUILD_ASSERT(UARTE_GET_BAUDRATE(idx) > 0, \ + "Unsupported baudrate");)) \ static const struct uarte_nrfx_config uarte_##idx##z_config = { \ COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, \ - (IF_ENABLED(DT_CLOCKS_HAS_IDX(UARTE(idx), 0), \ - (.clock_freq = UARTE_GET_FREQ(idx),))), \ + (.clock_freq = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),), \ (IF_ENABLED(UARTE_HAS_FRAME_TIMEOUT, \ (.baudrate = UARTE_PROP(idx, current_speed),)) \ .nrf_baudrate = UARTE_GET_BAUDRATE(idx), \ @@ -2405,6 +2559,13 @@ static int uarte_instance_init(const struct device *dev, IF_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC, \ (.timer = NRFX_TIMER_INSTANCE( \ CONFIG_UART_##idx##_NRF_HW_ASYNC_TIMER),)) \ + IF_ENABLED(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _), \ + (.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(UARTE(idx))), \ + .clk_spec = { \ + .frequency = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),\ + .accuracy = 0, \ + .precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\ + },)) \ }; \ static int uarte_##idx##_init(const struct device *dev) \ { \ @@ -2417,15 +2578,16 @@ static int uarte_instance_init(const struct device *dev, } \ \ PM_DEVICE_DT_DEFINE(UARTE(idx), uarte_nrfx_pm_action, \ - PM_DEVICE_ISR_SAFE); \ + COND_CODE_1(INSTANCE_IS_FAST_PD(_, /*empty*/, idx, _),\ + (0), (PM_DEVICE_ISR_SAFE))); \ \ DEVICE_DT_DEFINE(UARTE(idx), \ uarte_##idx##_init, \ PM_DEVICE_DT_GET(UARTE(idx)), \ &uarte_##idx##_data, \ &uarte_##idx##z_config, \ - PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, \ + UARTE_INIT_LEVEL(idx), \ + UARTE_INIT_PRIO(idx), \ &uart_nrfx_uarte_driver_api) #define UARTE_INT_DRIVEN(idx) \ diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index ea80df3070109..283f0cbffe082 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -573,9 +573,7 @@ static int uart_ns16550_configure(const struct device *dev, const struct uart_ns16550_dev_config * const dev_cfg = dev->config; uint8_t mdc = 0U, c; uint32_t pclk = 0U; - - /* temp for return value if error occurs in this locked region */ - int ret = 0; + int ret; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); @@ -622,6 +620,11 @@ static int uart_ns16550_configure(const struct device *dev, goto out; } + ret = clock_control_on(dev_cfg->clock_dev, dev_cfg->clock_subsys); + if (ret != 0 && ret != -EALREADY) { + goto out; + } + if (clock_control_get_rate(dev_cfg->clock_dev, dev_cfg->clock_subsys, &pclk) != 0) { @@ -722,6 +725,7 @@ static int uart_ns16550_configure(const struct device *dev, /* disable interrupts */ ns16550_outbyte(dev_cfg, IER(dev), 0x00); + ret = 0; out: k_spin_unlock(&dev_data->lock, key); diff --git a/drivers/serial/uart_pl011.c b/drivers/serial/uart_pl011.c index cbaa507e9a7cd..4495414438804 100644 --- a/drivers/serial/uart_pl011.c +++ b/drivers/serial/uart_pl011.c @@ -74,6 +74,7 @@ struct pl011_data { #ifdef CONFIG_UART_INTERRUPT_DRIVEN volatile bool sw_call_txdrdy; uart_irq_callback_user_data_t irq_cb; + struct k_spinlock irq_cb_lock; void *irq_cb_data; #endif }; @@ -342,29 +343,45 @@ static void pl011_irq_tx_enable(const struct device *dev) struct pl011_data *data = dev->data; get_uart(dev)->imsc |= PL011_IMSC_TXIM; - if (data->sw_call_txdrdy) { - /* Verify if the callback has been registered */ - if (data->irq_cb) { - /* - * Due to HW limitation, the first TX interrupt should - * be triggered by the software. - * - * PL011 TX interrupt is based on a transition through - * a level, rather than on the level itself[1]. So that, - * enable TX interrupt can not trigger TX interrupt if - * no data was filled to TX FIFO at the beginning. - * - * [1]: PrimeCell UART (PL011) Technical Reference Manual - * functional-overview/interrupts - */ + if (!data->sw_call_txdrdy) { + return; + } + data->sw_call_txdrdy = false; + + /* + * Verify if the callback has been registered. Due to HW limitation, the + * first TX interrupt should be triggered by the software. + * + * PL011 TX interrupt is based on a transition through a level, rather + * than on the level itself[1]. So that, enable TX interrupt can not + * trigger TX interrupt if no data was filled to TX FIFO at the + * beginning. + * + * [1]: PrimeCell UART (PL011) Technical Reference Manual + * functional-overview/interrupts + */ + if (!data->irq_cb) { + return; + } + + /* + * Execute callback while TX interrupt remains enabled. If + * uart_fifo_fill() is called with small amounts of data, the 1/8 TX + * FIFO threshold may never be reached, and the hardware TX interrupt + * will never trigger. + */ + while (get_uart(dev)->imsc & PL011_IMSC_TXIM) { + K_SPINLOCK(&data->irq_cb_lock) { data->irq_cb(dev, data->irq_cb_data); } - data->sw_call_txdrdy = false; } } static void pl011_irq_tx_disable(const struct device *dev) { + struct pl011_data *data = dev->data; + + data->sw_call_txdrdy = true; get_uart(dev)->imsc &= ~PL011_IMSC_TXIM; } @@ -620,7 +637,9 @@ void pl011_isr(const struct device *dev) /* Verify if the callback has been registered */ if (data->irq_cb) { - data->irq_cb(dev, data->irq_cb_data); + K_SPINLOCK(&data->irq_cb_lock) { + data->irq_cb(dev, data->irq_cb_data); + } } } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ diff --git a/drivers/serial/uart_realtek_rts5912.c b/drivers/serial/uart_realtek_rts5912.c new file mode 100644 index 0000000000000..c57c37745149a --- /dev/null +++ b/drivers/serial/uart_realtek_rts5912.c @@ -0,0 +1,75 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#define DT_DRV_COMPAT realtek_rts5912_uart + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(uart_rts5912, CONFIG_UART_LOG_LEVEL); + +BUILD_ASSERT(CONFIG_UART_RTS5912_INIT_PRIORITY < CONFIG_SERIAL_INIT_PRIORITY, + "The uart_realtek_rts5912 driver must be initialized before the uart_ns16550 driver"); + +/* device config */ +struct uart_rts5912_device_config { + const struct pinctrl_dev_config *pcfg; + const struct device *clk_dev; + struct rts5912_sccon_subsys sccon_cfg; +}; + +/** Device data structure */ +struct uart_rts5912_dev_data { +}; + +static int rts5912_uart_init(const struct device *dev) +{ + const struct uart_rts5912_device_config *const dev_cfg = dev->config; + int rc; + + if (!device_is_ready(dev_cfg->clk_dev)) { + return -ENODEV; + } + + rc = clock_control_on(dev_cfg->clk_dev, (clock_control_subsys_t)&dev_cfg->sccon_cfg); + if (rc != 0) { + return rc; + } + + rc = pinctrl_apply_state(dev_cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (rc != 0) { + return rc; + } + + return 0; +} + +#define UART_RTS5912_DEVICE_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static const struct uart_rts5912_device_config uart_rts5912_dev_cfg_##n = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .sccon_cfg = \ + { \ + .clk_grp = DT_INST_CLOCKS_CELL_BY_NAME(n, uart##n, clk_grp), \ + .clk_idx = DT_INST_CLOCKS_CELL_BY_NAME(n, uart##n, clk_idx), \ + }, \ + }; \ + \ + static struct uart_rts5912_dev_data uart_rts5912_dev_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, &rts5912_uart_init, NULL, &uart_rts5912_dev_data_##n, \ + &uart_rts5912_dev_cfg_##n, PRE_KERNEL_1, \ + CONFIG_UART_RTS5912_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(UART_RTS5912_DEVICE_INIT) diff --git a/drivers/serial/uart_renesas_rz_scif.c b/drivers/serial/uart_renesas_rz_scif.c new file mode 100644 index 0000000000000..92fe28cdc8ff2 --- /dev/null +++ b/drivers/serial/uart_renesas_rz_scif.c @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rz_scif_uart + +#include +#include +#include +#include +#include "r_scif_uart.h" + +LOG_MODULE_REGISTER(rz_scif_uart); + +struct uart_rz_scif_config { + const struct pinctrl_dev_config *pin_config; + const uart_api_t *fsp_api; +}; + +struct uart_rz_scif_int { + bool rxi_flag; + bool tei_flag; + bool rx_fifo_busy; + bool irq_rx_enable; + bool irq_tx_enable; + uint8_t rx_byte; + uint8_t tx_byte; + uart_event_t event; +}; + +struct uart_rz_scif_data { + struct uart_config uart_config; + uart_cfg_t *fsp_cfg; + struct uart_rz_scif_int int_data; + scif_uart_instance_ctrl_t *fsp_ctrl; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t callback; + void *callback_data; +#endif +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +void scif_uart_rxi_isr(void); +void scif_uart_txi_isr(void); +void scif_uart_tei_isr(void); +void scif_uart_eri_isr(void); +void scif_uart_bri_isr(void); +#endif + +static int uart_rz_scif_poll_in(const struct device *dev, unsigned char *c) +{ + struct uart_rz_scif_data *data = dev->data; + R_SCIFA0_Type *reg = data->fsp_ctrl->p_reg; + + if (reg->FDR_b.R == 0U) { + /* There are no characters available to read. */ + return -1; + } + *c = reg->FRDR; + + return 0; +} + +static void uart_rz_scif_poll_out(const struct device *dev, unsigned char c) +{ + struct uart_rz_scif_data *data = dev->data; + R_SCIFA0_Type *reg = data->fsp_ctrl->p_reg; + uint8_t key; + + key = irq_lock(); + + while (!reg->FSR_b.TDFE) { + } + + reg->FTDR = c; + + while (!reg->FSR_b.TEND) { + } + + irq_unlock(key); +} + +static int uart_rz_scif_err_check(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + uart_event_t event = data->int_data.event; + int err = 0; + + if (event & UART_EVENT_ERR_OVERFLOW) { + err |= UART_ERROR_OVERRUN; + } + if (event & UART_EVENT_ERR_FRAMING) { + err |= UART_ERROR_FRAMING; + } + if (event & UART_EVENT_ERR_PARITY) { + err |= UART_ERROR_PARITY; + } + + return err; +} + +static int uart_rz_scif_apply_config(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + + struct uart_config *uart_config = &data->uart_config; + uart_cfg_t *fsp_cfg = data->fsp_cfg; + + scif_baud_setting_t baud_setting; + scif_uart_extended_cfg_t config_extend; + const scif_uart_extended_cfg_t *fsp_config_extend = fsp_cfg->p_extend; + + fsp_err_t fsp_err; + + fsp_err = R_SCIF_UART_BaudCalculate(data->fsp_ctrl, uart_config->baudrate, false, 5000, + &baud_setting); + if (fsp_err) { + return -EIO; + } + + memcpy(fsp_config_extend->p_baud_setting, &baud_setting, sizeof(scif_baud_setting_t)); + + switch (uart_config->data_bits) { + case UART_CFG_DATA_BITS_7: + fsp_cfg->data_bits = UART_DATA_BITS_7; + break; + case UART_CFG_DATA_BITS_8: + fsp_cfg->data_bits = UART_DATA_BITS_8; + break; + default: + return -ENOTSUP; + } + + switch (uart_config->parity) { + case UART_CFG_PARITY_NONE: + fsp_cfg->parity = UART_PARITY_OFF; + break; + case UART_CFG_PARITY_ODD: + fsp_cfg->parity = UART_PARITY_ODD; + break; + case UART_CFG_PARITY_EVEN: + fsp_cfg->parity = UART_PARITY_EVEN; + break; + default: + return -ENOTSUP; + } + + switch (uart_config->stop_bits) { + case UART_CFG_STOP_BITS_1: + fsp_cfg->stop_bits = UART_STOP_BITS_1; + break; + case UART_CFG_STOP_BITS_2: + fsp_cfg->stop_bits = UART_STOP_BITS_2; + break; + default: + return -ENOTSUP; + } + + memcpy(&config_extend, fsp_config_extend->p_baud_setting, sizeof(scif_baud_setting_t)); + + switch (uart_config->flow_ctrl) { + case UART_CFG_FLOW_CTRL_NONE: + config_extend.flow_control = SCIF_UART_FLOW_CONTROL_NONE; + config_extend.uart_mode = SCIF_UART_MODE_RS232; + config_extend.rs485_setting.enable = SCI_UART_RS485_DISABLE; + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + config_extend.flow_control = SCIF_UART_FLOW_CONTROL_AUTO; + config_extend.uart_mode = SCIF_UART_MODE_RS232; + config_extend.rs485_setting.enable = SCI_UART_RS485_DISABLE; + break; + default: + return -ENOTSUP; + } + + memcpy(fsp_config_extend->p_baud_setting, &config_extend, sizeof(scif_baud_setting_t)); + + return 0; +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + +static int uart_rz_scif_configure(const struct device *dev, const struct uart_config *cfg) +{ + int err; + fsp_err_t fsp_err; + const struct uart_rz_scif_config *config = dev->config; + struct uart_rz_scif_data *data = dev->data; + + memcpy(&data->uart_config, cfg, sizeof(struct uart_config)); + + err = uart_rz_scif_apply_config(dev); + + if (err) { + return err; + } + + fsp_err = config->fsp_api->close(data->fsp_ctrl); + if (fsp_err) { + return -EIO; + } + + fsp_err = config->fsp_api->open(data->fsp_ctrl, data->fsp_cfg); + if (fsp_err) { + return -EIO; + } + + return err; +} + +static int uart_rz_scif_config_get(const struct device *dev, struct uart_config *cfg) +{ + struct uart_rz_scif_data *data = dev->data; + + memcpy(cfg, &data->uart_config, sizeof(struct uart_config)); + return 0; +} + +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static int uart_rz_scif_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) +{ + struct uart_rz_scif_data *data = dev->data; + scif_uart_instance_ctrl_t *fsp_ctrl = data->fsp_ctrl; + + fsp_ctrl->tx_src_bytes = size; + fsp_ctrl->p_tx_src = tx_data; + + scif_uart_txi_isr(); + + return (size - fsp_ctrl->tx_src_bytes); +} + +static int uart_rz_scif_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + struct uart_rz_scif_data *data = dev->data; + + scif_uart_instance_ctrl_t *fsp_ctrl = data->fsp_ctrl; + + fsp_ctrl->rx_dest_bytes = size; + fsp_ctrl->p_rx_dest = rx_data; + + /* Read all available data in the FIFO */ + /* If there are more available data than required, they will be lost */ + if (data->int_data.rxi_flag) { + scif_uart_rxi_isr(); + } else { + scif_uart_tei_isr(); + } + + data->int_data.rx_fifo_busy = false; + + return (size - fsp_ctrl->rx_dest_bytes); +} + +static void uart_rz_scif_irq_rx_enable(const struct device *dev) +{ + const struct uart_rz_scif_config *config = dev->config; + struct uart_rz_scif_data *data = dev->data; + + data->int_data.irq_rx_enable = true; + + /* Prepare 1-byte buffer to receive, it will be overwritten by fifo read */ + config->fsp_api->read(data->fsp_ctrl, &(data->int_data.rx_byte), 1); +} + +static void uart_rz_scif_irq_rx_disable(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + + data->int_data.irq_rx_enable = false; + data->int_data.rx_fifo_busy = false; +} + +static void uart_rz_scif_irq_tx_enable(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + const struct uart_rz_scif_config *config = dev->config; + + data->int_data.irq_tx_enable = true; + + /* Trigger TX with a NULL frame */ + /* It is expected not to be sent, and will be overwritten by the fifo fill */ + data->int_data.tx_byte = '\0'; + config->fsp_api->write(data->fsp_ctrl, &data->int_data.tx_byte, 1); +} + +static void uart_rz_scif_irq_tx_disable(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + + data->int_data.irq_tx_enable = false; +} + +static int uart_rz_scif_irq_tx_ready(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + + return data->int_data.irq_tx_enable; +} + +static int uart_rz_scif_irq_rx_ready(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + + return data->int_data.rx_fifo_busy && data->int_data.irq_rx_enable; +} + +static int uart_rz_scif_irq_is_pending(const struct device *dev) +{ + return (uart_rz_scif_irq_tx_ready(dev)) || (uart_rz_scif_irq_rx_ready(dev)); +} + +static void uart_rz_scif_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, void *cb_data) +{ + struct uart_rz_scif_data *data = dev->data; + + data->callback = cb; + data->callback_data = cb_data; +} + +static int uart_rz_scif_irq_update(const struct device *dev) +{ + ARG_UNUSED(dev); + return 1; +} + +static void uart_rz_scif_rxi_isr(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + + data->int_data.rxi_flag = true; + data->int_data.rx_fifo_busy = true; + if (data->callback) { + data->callback(dev, data->callback_data); + } +} + +static void uart_rz_scif_txi_isr(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + + data->int_data.tei_flag = false; + if (data->callback) { + data->callback(dev, data->callback_data); + } +} + +static void uart_rz_scif_tei_isr(const struct device *dev) +{ + struct uart_rz_scif_data *data = dev->data; + + if (data->int_data.tei_flag) { + scif_uart_tei_isr(); + } else { + data->int_data.rxi_flag = false; + data->int_data.rx_fifo_busy = true; + if (data->callback) { + data->callback(dev, data->callback_data); + } + } +} + +static void uart_rz_scif_eri_isr(const struct device *dev) +{ + scif_uart_eri_isr(); +} + +static void uart_rz_scif_bri_isr(const struct device *dev) +{ + scif_uart_bri_isr(); +} + +static void uart_rz_scif_event_handler(uart_callback_args_t *p_args) +{ + const struct device *dev = (const struct device *)p_args->p_context; + struct uart_rz_scif_data *data = dev->data; + + data->int_data.event = p_args->event; + switch (p_args->event) { + case UART_EVENT_RX_CHAR: + data->int_data.rx_byte = p_args->data; + break; + case UART_EVENT_RX_COMPLETE: + break; + case UART_EVENT_TX_DATA_EMPTY: + data->int_data.tei_flag = true; + break; + case UART_EVENT_TX_COMPLETE: + data->int_data.tei_flag = false; + break; + default: + break; + } +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static DEVICE_API(uart, uart_rz_scif_driver_api) = { + .poll_in = uart_rz_scif_poll_in, + .poll_out = uart_rz_scif_poll_out, + .err_check = uart_rz_scif_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_rz_scif_configure, + .config_get = uart_rz_scif_config_get, +#endif +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_rz_scif_fifo_fill, + .fifo_read = uart_rz_scif_fifo_read, + .irq_rx_enable = uart_rz_scif_irq_rx_enable, + .irq_rx_disable = uart_rz_scif_irq_rx_disable, + .irq_tx_enable = uart_rz_scif_irq_tx_enable, + .irq_tx_disable = uart_rz_scif_irq_tx_disable, + .irq_tx_ready = uart_rz_scif_irq_tx_ready, + .irq_rx_ready = uart_rz_scif_irq_rx_ready, + .irq_is_pending = uart_rz_scif_irq_is_pending, + .irq_callback_set = uart_rz_scif_irq_callback_set, + .irq_update = uart_rz_scif_irq_update, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +static int uart_rz_scif_init(const struct device *dev) +{ + const struct uart_rz_scif_config *config = dev->config; + struct uart_rz_scif_data *data = dev->data; + int ret; + + /* Configure dt provided device signals when available */ + ret = pinctrl_apply_state(config->pin_config, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + /* uart_rz_scif_apply_config must be called first before open api */ + ret = uart_rz_scif_apply_config(dev); + if (ret < 0) { + return ret; + } + + config->fsp_api->open(data->fsp_ctrl, data->fsp_cfg); + + return 0; +} + +#define UART_RZG_IRQ_CONNECT(n, irq_name, isr) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, irq_name, irq), \ + DT_INST_IRQ_BY_NAME(n, irq_name, priority), isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(n, irq_name, irq)); \ + } while (0) + +#define UART_RZG_CONFIG_FUNC(n) \ + UART_RZG_IRQ_CONNECT(n, eri, uart_rz_scif_eri_isr); \ + UART_RZG_IRQ_CONNECT(n, rxi, uart_rz_scif_rxi_isr); \ + UART_RZG_IRQ_CONNECT(n, txi, uart_rz_scif_txi_isr); \ + UART_RZG_IRQ_CONNECT(n, tei, uart_rz_scif_tei_isr); \ + UART_RZG_IRQ_CONNECT(n, bri, uart_rz_scif_bri_isr); + +#define UART_RZG_INIT(n) \ + static scif_uart_instance_ctrl_t g_uart##n##_ctrl; \ + static scif_baud_setting_t g_uart##n##_baud_setting; \ + static scif_uart_extended_cfg_t g_uart##n##_cfg_extend = { \ + .bri_ipl = DT_INST_IRQ_BY_NAME(n, bri, priority), \ + .bri_irq = DT_INST_IRQ_BY_NAME(n, bri, irq), \ + .clock = SCIF_UART_CLOCK_INT, \ + .noise_cancel = SCIF_UART_NOISE_CANCELLATION_ENABLE, \ + .p_baud_setting = &g_uart##n##_baud_setting, \ + .rx_fifo_trigger = SCIF_UART_RECEIVE_TRIGGER_MAX, \ + .rts_fifo_trigger = SCIF_UART_RTS_TRIGGER_14, \ + .uart_mode = SCIF_UART_MODE_RS232, \ + .flow_control = SCIF_UART_FLOW_CONTROL_NONE, \ + .rs485_setting = \ + { \ + .enable = (sci_uart_rs485_enable_t)NULL, \ + .polarity = SCI_UART_RS485_DE_POLARITY_HIGH, \ + .de_control_pin = \ + (bsp_io_port_pin_t)SCIF_UART_INVALID_16BIT_PARAM, \ + }, \ + }; \ + static uart_cfg_t g_uart##n##_cfg = { \ + .channel = DT_INST_PROP(n, channel), \ + .p_extend = &g_uart##n##_cfg_extend, \ + .p_transfer_tx = NULL, \ + .p_transfer_rx = NULL, \ + .rxi_ipl = DT_INST_IRQ_BY_NAME(n, rxi, priority), \ + .txi_ipl = DT_INST_IRQ_BY_NAME(n, txi, priority), \ + .tei_ipl = DT_INST_IRQ_BY_NAME(n, tei, priority), \ + .eri_ipl = DT_INST_IRQ_BY_NAME(n, eri, priority), \ + .rxi_irq = DT_INST_IRQ_BY_NAME(n, rxi, irq), \ + .txi_irq = DT_INST_IRQ_BY_NAME(n, txi, irq), \ + .tei_irq = DT_INST_IRQ_BY_NAME(n, tei, irq), \ + .eri_irq = DT_INST_IRQ_BY_NAME(n, eri, irq), \ + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, ( \ + .p_callback = uart_rz_scif_event_handler, \ + .p_context = (void *)DEVICE_DT_INST_GET(n),)) }; \ + PINCTRL_DT_INST_DEFINE(n); \ + static const struct uart_rz_scif_config uart_rz_scif_config_##n = { \ + .pin_config = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .fsp_api = &g_uart_on_scif, \ + }; \ + static struct uart_rz_scif_data uart_rz_scif_data_##n = { \ + .uart_config = \ + { \ + .baudrate = DT_INST_PROP(n, current_speed), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ + .stop_bits = DT_INST_ENUM_IDX(n, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(n, data_bits), \ + .flow_ctrl = DT_INST_PROP_OR(n, hw_flow_control, \ + UART_CFG_FLOW_CTRL_NONE), \ + }, \ + .fsp_cfg = &g_uart##n##_cfg, \ + .fsp_ctrl = &g_uart##n##_ctrl, \ + }; \ + static int uart_rz_scif_init_##n(const struct device *dev) \ + { \ + IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, \ + (UART_RZG_CONFIG_FUNC(n);)) \ + return uart_rz_scif_init(dev); \ + } \ + DEVICE_DT_INST_DEFINE(n, &uart_rz_scif_init_##n, NULL, &uart_rz_scif_data_##n, \ + &uart_rz_scif_config_##n, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_rz_scif_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(UART_RZG_INIT) diff --git a/drivers/serial/uart_rpi_pico_pio.c b/drivers/serial/uart_rpi_pico_pio.c index cfbd084c86bb2..7e221d4ad0a58 100644 --- a/drivers/serial/uart_rpi_pico_pio.c +++ b/drivers/serial/uart_rpi_pico_pio.c @@ -39,15 +39,15 @@ RPI_PICO_PIO_DEFINE_PROGRAM(uart_tx, 0, 3, /* .wrap */ ); -RPI_PICO_PIO_DEFINE_PROGRAM(uart_rx, 0, 8, +RPI_PICO_PIO_DEFINE_PROGRAM(uart_rx, 1, 8, + 0x20a0, /* 0: wait 1 pin, 0 */ /* .wrap_target */ - 0x2020, /* 0: wait 0 pin, 0 */ - 0xea27, /* 1: set x, 7 [10] */ - 0x4001, /* 2: in pins, 1 */ - 0x0642, /* 3: jmp x--, 2 [6] */ - 0x00c8, /* 4: jmp pin, 8 */ - 0xc014, /* 5: irq nowait 4 rel */ - 0x20a0, /* 6: wait 1 pin, 0 */ + 0x2020, /* 1: wait 0 pin, 0 */ + 0xea27, /* 2: set x, 7 [10] */ + 0x4001, /* 3: in pins, 1 */ + 0x0643, /* 4: jmp x--, 3 [6] */ + 0x00c8, /* 5: jmp pin, 8 */ + 0xc014, /* 6: irq nowait 4 rel */ 0x0000, /* 7: jmp 0 */ 0x8020, /* 8: push block */ /* .wrap */ diff --git a/drivers/serial/uart_rzt2m.c b/drivers/serial/uart_rzt2m.c index 83b929619ea97..e42f3e7e743c8 100644 --- a/drivers/serial/uart_rzt2m.c +++ b/drivers/serial/uart_rzt2m.c @@ -427,11 +427,9 @@ static void uart_rzt2m_isr(const struct device *dev) .uart_cfg = \ { \ .baudrate = DT_INST_ENUM_IDX(n, current_speed), \ - .parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ - .stop_bits = \ - DT_INST_ENUM_IDX_OR(n, stop_bits, UART_CFG_STOP_BITS_1), \ - .data_bits = \ - DT_INST_ENUM_IDX_OR(n, data_bits, UART_CFG_DATA_BITS_8), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ + .stop_bits = DT_INST_ENUM_IDX(n, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(n, data_bits), \ }, \ }; \ UART_RZT2M_CONFIG_FUNC(n); \ diff --git a/drivers/serial/uart_sam0.c b/drivers/serial/uart_sam0.c index 10e222f12c666..407e2ebe7b66b 100644 --- a/drivers/serial/uart_sam0.c +++ b/drivers/serial/uart_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +18,8 @@ #include #include +/* clang-format off */ + #ifndef SERCOM_USART_CTRLA_MODE_USART_INT_CLK #define SERCOM_USART_CTRLA_MODE_USART_INT_CLK SERCOM_USART_CTRLA_MODE(0x1) #endif @@ -35,14 +38,11 @@ struct uart_sam0_dev_cfg { uint32_t baudrate; uint32_t pads; bool collision_detect; -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; - uint16_t gclk_core_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif + uint32_t gclk_gen; + uint16_t gclk_id; + #if CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_SAM0_ASYNC void (*irq_config_func)(const struct device *dev); #endif @@ -510,20 +510,15 @@ static int uart_sam0_init(const struct device *dev) SercomUsart * const usart = cfg->regs; -#ifdef MCLK - /* Enable the GCLK */ - GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 | - GCLK_PCHCTRL_CHEN; - - /* Enable SERCOM clock in MCLK */ *cfg->mclk |= cfg->mclk_mask; -#else - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - /* Enable SERCOM clock in PM */ - PM->APBCMASK.reg |= cfg->pm_apbcmask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif /* Disable all USART interrupts */ @@ -1272,34 +1267,23 @@ static void uart_sam0_irq_config_##n(const struct device *dev) \ #define UART_SAM0_SERCOM_COLLISION_DETECT(n) \ (DT_INST_PROP(n, collision_detection)) -#ifdef MCLK -#define UART_SAM0_CONFIG_DEFN(n) \ -static const struct uart_sam0_dev_cfg uart_sam0_config_##n = { \ - .regs = (SercomUsart *)DT_INST_REG_ADDR(n), \ - .baudrate = DT_INST_PROP(n, current_speed), \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\ - .pads = UART_SAM0_SERCOM_PADS(n), \ - .collision_detect = UART_SAM0_SERCOM_COLLISION_DETECT(n), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - UART_SAM0_IRQ_HANDLER_FUNC(n) \ - UART_SAM0_DMA_CHANNELS(n) \ -} -#else +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + #define UART_SAM0_CONFIG_DEFN(n) \ static const struct uart_sam0_dev_cfg uart_sam0_config_##n = { \ .regs = (SercomUsart *)DT_INST_REG_ADDR(n), \ .baudrate = DT_INST_PROP(n, current_speed), \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .pads = UART_SAM0_SERCOM_PADS(n), \ .collision_detect = UART_SAM0_SERCOM_COLLISION_DETECT(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ UART_SAM0_IRQ_HANDLER_FUNC(n) \ UART_SAM0_DMA_CHANNELS(n) \ } -#endif #define UART_SAM0_DEVICE_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ @@ -1314,3 +1298,5 @@ DEVICE_DT_INST_DEFINE(n, uart_sam0_init, NULL, \ UART_SAM0_IRQ_HANDLER(n) DT_INST_FOREACH_STATUS_OKAY(UART_SAM0_DEVICE_INIT) + +/* clang-format on */ diff --git a/drivers/serial/uart_sedi.c b/drivers/serial/uart_sedi.c index 3a82a9a77470f..1bee633b36cb8 100644 --- a/drivers/serial/uart_sedi.c +++ b/drivers/serial/uart_sedi.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "sedi_driver_uart.h" #ifdef CONFIG_UART_INTERRUPT_DRIVEN @@ -63,11 +64,11 @@ static void uart_sedi_cb(struct device *port); }; \ \ static struct uart_sedi_drv_data drv_data_##n; \ - PM_DEVICE_DT_DEFINE(DT_NODELABEL(uart##n), \ + PM_DEVICE_DT_INST_DEFINE(n, \ uart_sedi_pm_action); \ - DEVICE_DT_DEFINE(DT_NODELABEL(uart##n), \ + DEVICE_DT_INST_DEFINE(n, \ &uart_sedi_init, \ - PM_DEVICE_DT_GET(DT_NODELABEL(uart##n)), \ + PM_DEVICE_DT_INST_GET(n), \ &drv_data_##n, &config_info_##n, \ PRE_KERNEL_1, \ CONFIG_SERIAL_INIT_PRIORITY, &api); \ @@ -222,6 +223,8 @@ static int uart_sedi_poll_in(const struct device *dev, unsigned char *data) uint32_t status; int ret = 0; + (void)pm_device_runtime_get(dev); + sedi_uart_get_status(instance, (uint32_t *) &status); /* In order to check if there is any data to read from UART @@ -236,6 +239,9 @@ static int uart_sedi_poll_in(const struct device *dev, unsigned char *data) ret = -1; } } + + pm_device_runtime_put(dev); + return ret; } @@ -244,7 +250,11 @@ static void uart_sedi_poll_out(const struct device *dev, { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + (void)pm_device_runtime_get(dev); + sedi_uart_write(instance, data); + + pm_device_runtime_put(dev); } #ifdef CONFIG_UART_LINE_CTRL @@ -281,6 +291,8 @@ static int uart_sedi_err_check(const struct device *dev) uint32_t status; int ret_status = 0; + (void)pm_device_runtime_get(dev); + sedi_uart_get_status(instance, (uint32_t *const)&status); if (status & SEDI_UART_RX_OE) { ret_status = UART_ERROR_OVERRUN; @@ -298,6 +310,8 @@ static int uart_sedi_err_check(const struct device *dev) ret_status = UART_BREAK; } + pm_device_runtime_put(dev); + return ret_status; } @@ -308,30 +322,52 @@ static int uart_sedi_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + int ret = 0; + + pm_device_runtime_get(dev); - return sedi_uart_fifo_fill(instance, tx_data, size); + ret = sedi_uart_fifo_fill(instance, tx_data, size); + + pm_device_runtime_put(dev); + + return ret; } static int uart_sedi_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + int ret = 0; + + pm_device_runtime_get(dev); + + ret = sedi_uart_fifo_read(instance, rx_data, size); - return sedi_uart_fifo_read(instance, rx_data, size); + pm_device_runtime_put(dev); + + return ret; } static void uart_sedi_irq_tx_enable(const struct device *dev) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + pm_device_runtime_get(dev); + sedi_uart_irq_tx_enable(instance); + + pm_device_runtime_put(dev); } static void uart_sedi_irq_tx_disable(const struct device *dev) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + pm_device_runtime_get(dev); + sedi_uart_irq_tx_disable(instance); + + pm_device_runtime_put(dev); } static int uart_sedi_irq_tx_ready(const struct device *dev) @@ -344,15 +380,26 @@ static int uart_sedi_irq_tx_ready(const struct device *dev) static int uart_sedi_irq_tx_complete(const struct device *dev) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + int ret = 0; + + pm_device_runtime_get(dev); - return sedi_uart_is_tx_complete(instance); + ret = sedi_uart_is_tx_complete(instance); + + pm_device_runtime_put(dev); + + return ret; } static void uart_sedi_irq_rx_enable(const struct device *dev) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); +#ifdef CONFIG_PM_DEVICE_RUNTIME + pm_device_runtime_get(dev); +#else uart_busy_set(dev); +#endif sedi_uart_irq_rx_enable(instance); } @@ -361,7 +408,11 @@ static void uart_sedi_irq_rx_disable(const struct device *dev) sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); sedi_uart_irq_rx_disable(instance); +#ifdef CONFIG_PM_DEVICE_RUNTIME + pm_device_runtime_put(dev); +#else uart_busy_clear(dev); +#endif } static int uart_sedi_irq_rx_ready(const struct device *dev) @@ -375,14 +426,22 @@ static void uart_sedi_irq_err_enable(const struct device *dev) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + pm_device_runtime_get(dev); + sedi_uart_irq_err_enable(instance); + + pm_device_runtime_put(dev); } static void uart_sedi_irq_err_disable(const struct device *dev) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + pm_device_runtime_get(dev); + sedi_uart_irq_err_disable(instance); + + pm_device_runtime_put(dev); } static int uart_sedi_irq_is_pending(const struct device *dev) @@ -397,7 +456,12 @@ static int uart_sedi_irq_update(const struct device *dev) { sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev); + pm_device_runtime_get(dev); + sedi_uart_update_irq_cache(instance); + + pm_device_runtime_put(dev); + return 1; } @@ -444,6 +508,9 @@ static int uart_sedi_line_ctrl_set(struct device *dev, int ret; k_mutex_lock(GET_MUTEX(dev), K_FOREVER); + + pm_device_runtime_get(dev); + switch (ctrl) { case UART_LINE_CTRL_BAUD_RATE: sedi_uart_get_config(instance, &cfg); @@ -454,6 +521,9 @@ static int uart_sedi_line_ctrl_set(struct device *dev, default: ret = -ENODEV; } + + pm_device_runtime_put(dev); + k_mutex_unlock(GET_MUTEX(dev)); ret = get_xfer_error(ret); return ret; @@ -468,6 +538,9 @@ static int uart_sedi_line_ctrl_get(struct device *dev, int ret; k_mutex_lock(GET_MUTEX(dev), K_FOREVER); + + pm_device_runtime_get(dev); + switch (ctrl) { case UART_LINE_CTRL_BAUD_RATE: ret = sedi_uart_get_config(instance, &cfg); @@ -506,6 +579,9 @@ static int uart_sedi_line_ctrl_get(struct device *dev, default: ret = -ENODEV; } + + pm_device_runtime_put(dev); + k_mutex_unlock(GET_MUTEX(dev)); ret = get_xfer_error(ret); return ret; @@ -562,6 +638,8 @@ static int uart_sedi_init(const struct device *dev) config->uart_irq_config_func(dev); #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + pm_device_runtime_enable(dev); + return 0; } diff --git a/drivers/serial/uart_shell.c b/drivers/serial/uart_shell.c new file mode 100644 index 0000000000000..129fba143fb09 --- /dev/null +++ b/drivers/serial/uart_shell.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2024 Yishai Jaffe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(uart_shell, CONFIG_LOG_DEFAULT_LEVEL); + +static bool device_is_uart(const struct device *dev) +{ + return DEVICE_API_IS(uart, dev); +} + +static int cmd_uart_write(const struct shell *sh, size_t argc, char **argv) +{ + char *s_dev_name = argv[1]; + const struct device *dev = shell_device_get_binding(s_dev_name); + + if (!dev || !device_is_uart(dev)) { + shell_error(sh, "UART: Device driver %s not found.", s_dev_name); + return -ENODEV; + } + + char *buf = argv[2]; + int msg_len = strlen(buf); + + for (int i = 0; i < msg_len; i++) { + uart_poll_out(dev, buf[i]); + } + + return 0; +} + +static int cmd_uart_baudrate(const struct shell *sh, size_t argc, char **argv) +{ + char *s_dev_name = argv[1]; + const struct device *dev; + struct uart_config cfg; + uint32_t baudrate; + int ret; + + dev = shell_device_get_binding(s_dev_name); + if (!dev || !device_is_uart(dev)) { + shell_error(sh, "UART: Device driver %s not found.", s_dev_name); + return -ENODEV; + } + + baudrate = strtol(argv[2], NULL, 10); + ret = uart_config_get(dev, &cfg); + if (ret < 0) { + shell_error(sh, "UART: Failed to get current configuration: %d", ret); + return ret; + } + cfg.baudrate = baudrate; + + ret = uart_configure(dev, &cfg); + if (ret < 0) { + shell_error(sh, "UART: Failed to configure device: %d", ret); + return ret; + } + return 0; +} + +static int cmd_uart_flow_control(const struct shell *sh, size_t argc, char **argv) +{ + char *s_dev_name = argv[1]; + const struct device *dev; + struct uart_config cfg; + uint8_t flow_control; + int ret; + + dev = shell_device_get_binding(s_dev_name); + if (!dev || !device_is_uart(dev)) { + shell_error(sh, "UART: Device driver %s not found.", s_dev_name); + return -ENODEV; + } + + if (!strcmp(argv[2], "none")) { + flow_control = UART_CFG_FLOW_CTRL_NONE; + } else if (!strcmp(argv[2], "rtscts")) { + flow_control = UART_CFG_FLOW_CTRL_RTS_CTS; + } else if (!strcmp(argv[2], "dtrdsr")) { + flow_control = UART_CFG_FLOW_CTRL_DTR_DSR; + } else if (!strcmp(argv[2], "rs485")) { + flow_control = UART_CFG_FLOW_CTRL_RS485; + } else { + shell_error(sh, "Unknown: '%s'", argv[2]); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + ret = uart_config_get(dev, &cfg); + if (ret < 0) { + shell_error(sh, "UART: Failed to get current configuration: %d", ret); + return ret; + } + cfg.flow_ctrl = flow_control; + + ret = uart_configure(dev, &cfg); + if (ret < 0) { + shell_error(sh, "UART: Failed to configure device: %d", ret); + return ret; + } + return 0; +} + +static void device_name_get(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_filter(idx, device_is_uart); + + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; +} + +SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_uart_cmds, + SHELL_CMD_ARG(write, &dsub_device_name, + "Write data to the UART device\n" + "Usage: write ", + cmd_uart_write, 3, 0), + SHELL_CMD_ARG(baudrate, &dsub_device_name, + "Configure UART device baudrate\n" + "Usage: baudrate ", + cmd_uart_baudrate, 3, 0), + SHELL_CMD_ARG(fc, &dsub_device_name, + "Configure UART device flow control\n" + "Usage: fc ", + cmd_uart_flow_control, 3, 0), + SHELL_SUBCMD_SET_END /* Array terminated. */ +); + +SHELL_CMD_REGISTER(uart, &sub_uart_cmds, "UART commands", NULL); diff --git a/drivers/serial/uart_si32_usart.c b/drivers/serial/uart_si32_usart.c index 472f53c244c53..89283e4639b15 100644 --- a/drivers/serial/uart_si32_usart.c +++ b/drivers/serial/uart_si32_usart.c @@ -378,7 +378,7 @@ static int usart_si32_init(const struct device *dev) static const struct usart_si32_config usart_si32_cfg_##index = { \ .usart = (SI32_USART_A_Type *)DT_INST_REG_ADDR(index), \ .hw_flow_control = DT_INST_PROP(index, hw_flow_control), \ - .parity = DT_INST_ENUM_IDX_OR(index, parity, UART_CFG_PARITY_NONE), \ + .parity = DT_INST_ENUM_IDX(index, parity), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(index)), \ SI32_USART_IRQ_HANDLER_FUNC(index)}; \ \ diff --git a/drivers/serial/uart_silabs_eusart.c b/drivers/serial/uart_silabs_eusart.c new file mode 100644 index 0000000000000..01dc3cff196ab --- /dev/null +++ b/drivers/serial/uart_silabs_eusart.c @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2024, Yishai Jaffe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT silabs_eusart_uart + +#include +#include +#include +#include +#include +#include +#include +#include + +struct uart_silabs_eusart_config { + EUSART_TypeDef *eusart; + const struct pinctrl_dev_config *pcfg; + const struct device *clock_dev; + const struct silabs_clock_control_cmu_config clock_cfg; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + void (*irq_config_func)(const struct device *dev); +#endif +}; + +struct uart_silabs_eusart_data { + struct uart_config uart_cfg; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t callback; + void *cb_data; +#endif +}; + +static int uart_silabs_eusart_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + if (EUSART_StatusGet(config->eusart) & EUSART_STATUS_RXFL) { + *c = EUSART_Rx(config->eusart); + return 0; + } + + return -1; +} + +static void uart_silabs_eusart_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + /* EUSART_Tx function already waits for the transmit buffer being empty + * and waits for the bus to be free to transmit. + */ + EUSART_Tx(config->eusart, c); +} + +static int uart_silabs_eusart_err_check(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + uint32_t flags = EUSART_IntGet(config->eusart); + int err = 0; + + if (flags & EUSART_IF_RXOF) { + err |= UART_ERROR_OVERRUN; + } + + if (flags & EUSART_IF_PERR) { + err |= UART_ERROR_PARITY; + } + + if (flags & EUSART_IF_FERR) { + err |= UART_ERROR_FRAMING; + } + + EUSART_IntClear(config->eusart, EUSART_IF_RXOF | EUSART_IF_PERR | EUSART_IF_FERR); + + return err; +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static int uart_silabs_eusart_fifo_fill(const struct device *dev, + const uint8_t *tx_data, + int len) +{ + const struct uart_silabs_eusart_config *config = dev->config; + int num_tx = 0; + + while ((len - num_tx > 0) && + (EUSART_StatusGet(config->eusart) & EUSART_STATUS_TXFL)) { + + config->eusart->TXDATA = (uint32_t)tx_data[num_tx++]; + } + + if (!(EUSART_StatusGet(config->eusart) & EUSART_STATUS_TXFL)) { + EUSART_IntClear(config->eusart, EUSART_IF_TXFL); + } + + return num_tx; +} + +static int uart_silabs_eusart_fifo_read(const struct device *dev, uint8_t *rx_data, + const int len) +{ + const struct uart_silabs_eusart_config *config = dev->config; + int num_rx = 0; + + while ((len - num_rx > 0) && + (EUSART_StatusGet(config->eusart) & EUSART_STATUS_RXFL)) { + rx_data[num_rx++] = (uint8_t)config->eusart->RXDATA; + } + + if (!(EUSART_StatusGet(config->eusart) & EUSART_STATUS_RXFL)) { + EUSART_IntClear(config->eusart, EUSART_IF_RXFL); + } + + return num_rx; +} + +static void uart_silabs_eusart_irq_tx_enable(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + EUSART_IntClear(config->eusart, EUSART_IEN_TXFL | EUSART_IEN_TXC); + EUSART_IntEnable(config->eusart, EUSART_IEN_TXFL | EUSART_IEN_TXC); +} + +static void uart_silabs_eusart_irq_tx_disable(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + EUSART_IntDisable(config->eusart, EUSART_IEN_TXFL | EUSART_IEN_TXC); + EUSART_IntClear(config->eusart, EUSART_IEN_TXFL | EUSART_IEN_TXC); +} + +static int uart_silabs_eusart_irq_tx_complete(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + uint32_t flags = EUSART_IntGet(config->eusart); + + EUSART_IntClear(config->eusart, EUSART_IF_TXC); + + return (flags & EUSART_IF_TXC) != 0; +} + +static int uart_silabs_eusart_irq_tx_ready(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + return (config->eusart->IEN & EUSART_IEN_TXFL) + && (EUSART_IntGet(config->eusart) & EUSART_IF_TXFL); +} + +static void uart_silabs_eusart_irq_rx_enable(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + EUSART_IntClear(config->eusart, EUSART_IEN_RXFL); + EUSART_IntEnable(config->eusart, EUSART_IEN_RXFL); +} + +static void uart_silabs_eusart_irq_rx_disable(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + EUSART_IntDisable(config->eusart, EUSART_IEN_RXFL); + EUSART_IntClear(config->eusart, EUSART_IEN_RXFL); +} + +static int uart_silabs_eusart_irq_rx_ready(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + return (config->eusart->IEN & EUSART_IEN_RXFL) + && (EUSART_IntGet(config->eusart) & EUSART_IF_RXFL); +} + +static void uart_silabs_eusart_irq_err_enable(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + EUSART_IntClear(config->eusart, EUSART_IF_RXOF | EUSART_IF_PERR | EUSART_IF_FERR); + EUSART_IntEnable(config->eusart, EUSART_IF_RXOF | EUSART_IF_PERR | EUSART_IF_FERR); +} + +static void uart_silabs_eusart_irq_err_disable(const struct device *dev) +{ + const struct uart_silabs_eusart_config *config = dev->config; + + EUSART_IntDisable(config->eusart, EUSART_IF_RXOF | EUSART_IF_PERR | EUSART_IF_FERR); + EUSART_IntClear(config->eusart, EUSART_IF_RXOF | EUSART_IF_PERR | EUSART_IF_FERR); +} + +static int uart_silabs_eusart_irq_is_pending(const struct device *dev) +{ + return uart_silabs_eusart_irq_tx_ready(dev) || uart_silabs_eusart_irq_rx_ready(dev); +} + +static int uart_silabs_eusart_irq_update(const struct device *dev) +{ + return 1; +} + +static void uart_silabs_eusart_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *cb_data) +{ + struct uart_silabs_eusart_data *data = dev->data; + + data->callback = cb; + data->cb_data = cb_data; +} + +static void uart_silabs_eusart_isr(const struct device *dev) +{ + struct uart_silabs_eusart_data *data = dev->data; + + if (data->callback) { + data->callback(dev, data->cb_data); + } +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static inline EUSART_Parity_TypeDef uart_silabs_eusart_cfg2ll_parity( + enum uart_config_parity parity) +{ + switch (parity) { + case UART_CFG_PARITY_ODD: + return eusartOddParity; + case UART_CFG_PARITY_EVEN: + return eusartEvenParity; + case UART_CFG_PARITY_NONE: + default: + return eusartNoParity; + } +} + +static inline enum uart_config_parity uart_silabs_eusart_ll2cfg_parity( + EUSART_Parity_TypeDef parity) +{ + switch (parity) { + case eusartOddParity: + return UART_CFG_PARITY_ODD; + case eusartEvenParity: + return UART_CFG_PARITY_EVEN; + case eusartNoParity: + default: + return UART_CFG_PARITY_NONE; + } +} + +static inline EUSART_Stopbits_TypeDef uart_silabs_eusart_cfg2ll_stopbits( + enum uart_config_stop_bits sb) +{ + switch (sb) { + case UART_CFG_STOP_BITS_0_5: + return eusartStopbits0p5; + case UART_CFG_STOP_BITS_1: + return eusartStopbits1; + case UART_CFG_STOP_BITS_2: + return eusartStopbits2; + case UART_CFG_STOP_BITS_1_5: + return eusartStopbits1p5; + default: + return eusartStopbits1; + } +} + +static inline enum uart_config_stop_bits uart_silabs_eusart_ll2cfg_stopbits( + EUSART_Stopbits_TypeDef sb) +{ + switch (sb) { + case eusartStopbits0p5: + return UART_CFG_STOP_BITS_0_5; + case eusartStopbits1: + return UART_CFG_STOP_BITS_1; + case eusartStopbits1p5: + return UART_CFG_STOP_BITS_1_5; + case eusartStopbits2: + return UART_CFG_STOP_BITS_2; + default: + return UART_CFG_STOP_BITS_1; + } +} + +static inline EUSART_Databits_TypeDef uart_silabs_eusart_cfg2ll_databits( + enum uart_config_data_bits db, enum uart_config_parity p) +{ + switch (db) { + case UART_CFG_DATA_BITS_7: + if (p == UART_CFG_PARITY_NONE) { + return eusartDataBits7; + } else { + return eusartDataBits8; + } + case UART_CFG_DATA_BITS_9: + return eusartDataBits9; + case UART_CFG_DATA_BITS_8: + default: + if (p == UART_CFG_PARITY_NONE) { + return eusartDataBits8; + } else { + return eusartDataBits9; + } + return eusartDataBits8; + } +} + +static inline enum uart_config_data_bits uart_silabs_eusart_ll2cfg_databits( + EUSART_Databits_TypeDef db, EUSART_Parity_TypeDef p) +{ + switch (db) { + case eusartDataBits7: + if (p == eusartNoParity) { + return UART_CFG_DATA_BITS_7; + } else { + return UART_CFG_DATA_BITS_6; + } + case eusartDataBits9: + if (p == eusartNoParity) { + return UART_CFG_DATA_BITS_9; + } else { + return UART_CFG_DATA_BITS_8; + } + case eusartDataBits8: + default: + if (p == eusartNoParity) { + return UART_CFG_DATA_BITS_8; + } else { + return UART_CFG_DATA_BITS_7; + } + } +} + +/** + * @brief Get LL hardware flow control define from + * Zephyr hardware flow control option. + * @note Supports only UART_CFG_FLOW_CTRL_RTS_CTS and UART_CFG_FLOW_CTRL_RS485. + * @param fc: Zephyr hardware flow control option. + * @retval eusartHwFlowControlCtsAndRts, or eusartHwFlowControlNone. + */ +static inline EUSART_HwFlowControl_TypeDef uart_silabs_eusart_cfg2ll_hwctrl( + enum uart_config_flow_control fc) +{ + if (fc == UART_CFG_FLOW_CTRL_RTS_CTS) { + return eusartHwFlowControlCtsAndRts; + } + + return eusartHwFlowControlNone; +} + +/** + * @brief Get Zephyr hardware flow control option from + * LL hardware flow control define. + * @note Supports only eusartHwFlowControlCtsAndRts. + * @param fc: LL hardware flow control definition. + * @retval UART_CFG_FLOW_CTRL_RTS_CTS, or UART_CFG_FLOW_CTRL_NONE. + */ +static inline enum uart_config_flow_control uart_silabs_eusart_ll2cfg_hwctrl( + EUSART_HwFlowControl_TypeDef fc) +{ + if (fc == eusartHwFlowControlCtsAndRts) { + return UART_CFG_FLOW_CTRL_RTS_CTS; + } + + return UART_CFG_FLOW_CTRL_NONE; +} + +/** + * @brief Main initializer for UART + * + * @param dev UART device to be initialized + * @return int 0 + */ +static int uart_silabs_eusart_init(const struct device *dev) +{ + int err; + const struct uart_silabs_eusart_config *config = dev->config; + struct uart_silabs_eusart_data *data = dev->data; + struct uart_config *uart_cfg = &data->uart_cfg; + + EUSART_UartInit_TypeDef eusartInit = EUSART_UART_INIT_DEFAULT_HF; + EUSART_AdvancedInit_TypeDef advancedSettings = EUSART_ADVANCED_INIT_DEFAULT; + + /* The peripheral and gpio clock are already enabled from soc and gpio + * driver + */ + /* Enable EUSART clock */ + err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg); + if (err < 0) { + return err; + } + + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + /* Init EUSART */ + eusartInit.baudrate = uart_cfg->baudrate; + eusartInit.parity = uart_silabs_eusart_cfg2ll_parity(uart_cfg->parity); + eusartInit.stopbits = uart_silabs_eusart_cfg2ll_stopbits(uart_cfg->stop_bits); + eusartInit.databits = uart_silabs_eusart_cfg2ll_databits(uart_cfg->data_bits, + uart_cfg->parity); + advancedSettings.hwFlowControl = uart_silabs_eusart_cfg2ll_hwctrl(uart_cfg->flow_ctrl); + eusartInit.advancedSettings = &advancedSettings; + + EUSART_UartInitHf(config->eusart, &eusartInit); + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + config->irq_config_func(dev); +#endif + + return 0; +} + +#ifdef CONFIG_PM_DEVICE +static int uart_silabs_eusart_pm_action(const struct device *dev, enum pm_device_action action) +{ + __maybe_unused const struct uart_silabs_eusart_config *config = dev->config; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: +#ifdef EUSART_STATUS_TXIDLE + /* Wait for TX FIFO to flush before suspending */ + while (!(EUSART_StatusGet(config->eusart) & EUSART_STATUS_TXIDLE)) { + } +#endif + break; + + case PM_DEVICE_ACTION_RESUME: + break; + + default: + return -ENOTSUP; + } + + return 0; +} +#endif + +static DEVICE_API(uart, uart_silabs_eusart_driver_api) = { + .poll_in = uart_silabs_eusart_poll_in, + .poll_out = uart_silabs_eusart_poll_out, + .err_check = uart_silabs_eusart_err_check, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_silabs_eusart_fifo_fill, + .fifo_read = uart_silabs_eusart_fifo_read, + .irq_tx_enable = uart_silabs_eusart_irq_tx_enable, + .irq_tx_disable = uart_silabs_eusart_irq_tx_disable, + .irq_tx_complete = uart_silabs_eusart_irq_tx_complete, + .irq_tx_ready = uart_silabs_eusart_irq_tx_ready, + .irq_rx_enable = uart_silabs_eusart_irq_rx_enable, + .irq_rx_disable = uart_silabs_eusart_irq_rx_disable, + .irq_rx_ready = uart_silabs_eusart_irq_rx_ready, + .irq_err_enable = uart_silabs_eusart_irq_err_enable, + .irq_err_disable = uart_silabs_eusart_irq_err_disable, + .irq_is_pending = uart_silabs_eusart_irq_is_pending, + .irq_update = uart_silabs_eusart_irq_update, + .irq_callback_set = uart_silabs_eusart_irq_callback_set, +#endif +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define UART_IRQ_HANDLER_FUNC(idx) \ + .irq_config_func = uart_silabs_eusart_config_func_##idx, +#define UART_IRQ_HANDLER(idx) \ + static void uart_silabs_eusart_config_func_##idx(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, rx, irq), \ + DT_INST_IRQ_BY_NAME(idx, rx, priority), \ + uart_silabs_eusart_isr, DEVICE_DT_INST_GET(idx), 0); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, tx, irq), \ + DT_INST_IRQ_BY_NAME(idx, tx, priority), \ + uart_silabs_eusart_isr, DEVICE_DT_INST_GET(idx), 0); \ + \ + irq_enable(DT_INST_IRQ_BY_NAME(idx, rx, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(idx, tx, irq)); \ + } +#else +#define UART_IRQ_HANDLER_FUNC(idx) +#define UART_IRQ_HANDLER(idx) +#endif + +#define UART_INIT(idx) \ +UART_IRQ_HANDLER(idx) \ + \ +PINCTRL_DT_INST_DEFINE(idx); \ + \ +static const struct uart_silabs_eusart_config uart_silabs_eusart_cfg_##idx = { \ + .eusart = (EUSART_TypeDef *)DT_INST_REG_ADDR(idx), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ + .clock_cfg = SILABS_DT_INST_CLOCK_CFG(idx), \ + UART_IRQ_HANDLER_FUNC(idx) \ +}; \ + \ +static struct uart_silabs_eusart_data uart_silabs_eusart_data_##idx = { \ + .uart_cfg = { \ + .baudrate = DT_INST_PROP(idx, current_speed), \ + .parity = DT_INST_ENUM_IDX(idx, parity), \ + .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \ + .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) \ + ? UART_CFG_FLOW_CTRL_RTS_CTS \ + : UART_CFG_FLOW_CTRL_NONE, \ + }, \ +}; \ + \ +PM_DEVICE_DT_INST_DEFINE(idx, uart_silabs_eusart_pm_action); \ + \ +DEVICE_DT_INST_DEFINE(idx, uart_silabs_eusart_init, PM_DEVICE_DT_INST_GET(idx), \ + &uart_silabs_eusart_data_##idx, \ + &uart_silabs_eusart_cfg_##idx, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_silabs_eusart_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(UART_INIT) diff --git a/drivers/serial/uart_silabs_usart.c b/drivers/serial/uart_silabs_usart.c new file mode 100644 index 0000000000000..ee330c5fdee4d --- /dev/null +++ b/drivers/serial/uart_silabs_usart.c @@ -0,0 +1,1189 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT silabs_usart_uart + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_UART_ASYNC_API +#include +#include +#endif + +LOG_MODULE_REGISTER(uart_silabs_usart, CONFIG_UART_LOG_LEVEL); + +#define SILABS_USART_TIMER_COMPARE_VALUE 0xff +#define SILABS_USART_TIMEOUT_TO_TIMERCOUNTER(timeout, baudrate) \ + ((timeout * NSEC_PER_USEC) / ((NSEC_PER_SEC / baudrate) * SILABS_USART_TIMER_COMPARE_VALUE)) + +#ifdef CONFIG_UART_ASYNC_API +struct uart_dma_channel { + const struct device *dma_dev; + uint32_t dma_channel; + struct dma_block_config blk_cfg; + struct dma_config dma_cfg; + uint8_t priority; + uint8_t *buffer; + size_t buffer_length; + volatile size_t counter; + size_t offset; + int32_t timeout_cnt; + int32_t timeout; + bool enabled; +}; +#endif +struct uart_silabs_config { + const struct pinctrl_dev_config *pcfg; + const struct device *clock_dev; + const struct silabs_clock_control_cmu_config clock_cfg; + USART_TypeDef *base; + void (*irq_config_func)(const struct device *dev); +}; + +enum uart_silabs_pm_lock { + UART_SILABS_PM_LOCK_TX, + UART_SILABS_PM_LOCK_TX_POLL, + UART_SILABS_PM_LOCK_RX, + UART_SILABS_PM_LOCK_COUNT, +}; + +struct uart_silabs_data { + struct uart_config *uart_cfg; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t callback; + void *cb_data; +#endif +#ifdef CONFIG_UART_ASYNC_API + const struct device *uart_dev; + uart_callback_t async_cb; + void *async_user_data; + struct uart_dma_channel dma_rx; + struct uart_dma_channel dma_tx; + uint8_t *rx_next_buffer; + size_t rx_next_buffer_len; +#endif +#ifdef CONFIG_PM + ATOMIC_DEFINE(pm_lock, UART_SILABS_PM_LOCK_COUNT); +#endif +}; + +static int uart_silabs_pm_action(const struct device *dev, enum pm_device_action action); + +/** + * @brief Get PM lock on low power states + * + * @param dev UART device struct + * @param lock UART PM lock type + * + * @return true if lock was taken, false otherwise + */ +static bool uart_silabs_pm_lock_get(const struct device *dev, enum uart_silabs_pm_lock lock) +{ +#ifdef CONFIG_PM + struct uart_silabs_data *data = dev->data; + bool was_locked = atomic_test_and_set_bit(data->pm_lock, lock); + + if (!was_locked) { + /* Lock out low-power states that would interfere with UART traffic */ + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + } + + return !was_locked; +#else + return false; +#endif +} + +/** + * @brief Release PM lock on low power states + * + * @param dev UART device struct + * @param lock UART PM lock type + * + * @return true if lock was released, false otherwise + */ +static bool uart_silabs_pm_lock_put(const struct device *dev, enum uart_silabs_pm_lock lock) +{ +#ifdef CONFIG_PM + struct uart_silabs_data *data = dev->data; + bool was_locked = atomic_test_and_clear_bit(data->pm_lock, lock); + + if (was_locked) { + /* Unlock low-power states that would interfere with UART traffic */ + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + } + + return was_locked; +#else + return false; +#endif +} + +static int uart_silabs_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uart_silabs_config *config = dev->config; + uint32_t flags = USART_StatusGet(config->base); + + if (flags & USART_STATUS_RXDATAV) { + *c = USART_Rx(config->base); + return 0; + } + + return -1; +} + +static void uart_silabs_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_silabs_config *config = dev->config; + + if (uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_TX_POLL)) { + USART_IntEnable(config->base, USART_IF_TXC); + } + + USART_Tx(config->base, c); +} + +static int uart_silabs_err_check(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + uint32_t flags = USART_IntGet(config->base); + int err = 0; + + if (flags & USART_IF_RXOF) { + err |= UART_ERROR_OVERRUN; + } + + if (flags & USART_IF_PERR) { + err |= UART_ERROR_PARITY; + } + + if (flags & USART_IF_FERR) { + err |= UART_ERROR_FRAMING; + } + + USART_IntClear(config->base, USART_IF_RXOF | USART_IF_PERR | USART_IF_FERR); + + return err; +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static int uart_silabs_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) +{ + const struct uart_silabs_config *config = dev->config; + int i = 0; + + while ((i < len) && (config->base->STATUS & USART_STATUS_TXBL)) { + config->base->TXDATA = tx_data[i++]; + } + + return i; +} + +static int uart_silabs_fifo_read(const struct device *dev, uint8_t *rx_data, const int len) +{ + const struct uart_silabs_config *config = dev->config; + int i = 0; + + while ((i < len) && (config->base->STATUS & USART_STATUS_RXDATAV)) { + rx_data[i++] = (uint8_t)config->base->RXDATA; + } + + return i; +} + +static void uart_silabs_irq_tx_enable(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + + (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_TX); + USART_IntEnable(config->base, USART_IEN_TXBL | USART_IEN_TXC); +} + +static void uart_silabs_irq_tx_disable(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + + USART_IntDisable(config->base, USART_IEN_TXBL | USART_IEN_TXC); + (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX); +} + +static int uart_silabs_irq_tx_complete(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + uint32_t flags = USART_IntGet(config->base); + + USART_IntClear(config->base, USART_IF_TXC); + + return !!(flags & USART_IF_TXC); +} + +static int uart_silabs_irq_tx_ready(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + uint32_t flags = USART_IntGetEnabled(config->base); + + return !!(flags & USART_IF_TXBL); +} + +static void uart_silabs_irq_rx_enable(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + + (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_RX); + USART_IntEnable(config->base, USART_IEN_RXDATAV); +} + +static void uart_silabs_irq_rx_disable(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + + USART_IntDisable(config->base, USART_IEN_RXDATAV); + (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_RX); +} + +static int uart_silabs_irq_rx_full(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + uint32_t flags = USART_IntGet(config->base); + + return !!(flags & USART_IF_RXDATAV); +} + +static int uart_silabs_irq_rx_ready(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + + return (config->base->IEN & USART_IEN_RXDATAV) && uart_silabs_irq_rx_full(dev); +} + +static void uart_silabs_irq_err_enable(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + + USART_IntEnable(config->base, USART_IF_RXOF | USART_IF_PERR | USART_IF_FERR); +} + +static void uart_silabs_irq_err_disable(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + + USART_IntDisable(config->base, USART_IF_RXOF | USART_IF_PERR | USART_IF_FERR); +} + +static int uart_silabs_irq_is_pending(const struct device *dev) +{ + return uart_silabs_irq_tx_ready(dev) || uart_silabs_irq_rx_ready(dev); +} + +static int uart_silabs_irq_update(const struct device *dev) +{ + return 1; +} + +static void uart_silabs_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *cb_data) +{ + struct uart_silabs_data *data = dev->data; + + data->callback = cb; + data->cb_data = cb_data; +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#ifdef CONFIG_UART_ASYNC_API +static inline void async_user_callback(struct uart_silabs_data *data, struct uart_event *event) +{ + if (data->async_cb) { + data->async_cb(data->uart_dev, event, data->async_user_data); + } +} + +static inline void async_evt_rx_rdy(struct uart_silabs_data *data) +{ + struct uart_event event = { + .type = UART_RX_RDY, + .data.rx.buf = data->dma_rx.buffer, + .data.rx.len = data->dma_rx.counter - data->dma_rx.offset, + .data.rx.offset = data->dma_rx.offset + }; + + data->dma_rx.offset = data->dma_rx.counter; + + if (event.data.rx.len > 0) { + async_user_callback(data, &event); + } +} + +static inline void async_evt_tx_done(struct uart_silabs_data *data) +{ + struct uart_event event = { + .type = UART_TX_DONE, + .data.tx.buf = data->dma_tx.buffer, + .data.tx.len = data->dma_tx.counter + }; + + data->dma_tx.buffer_length = 0; + data->dma_tx.counter = 0; + + async_user_callback(data, &event); +} + +static inline void async_evt_tx_abort(struct uart_silabs_data *data) +{ + struct uart_event event = { + .type = UART_TX_ABORTED, + .data.tx.buf = data->dma_tx.buffer, + .data.tx.len = data->dma_tx.counter + }; + + data->dma_tx.buffer_length = 0; + data->dma_tx.counter = 0; + + async_user_callback(data, &event); +} + +static inline void async_evt_rx_err(struct uart_silabs_data *data, int err_code) +{ + struct uart_event event = { + .type = UART_RX_STOPPED, + .data.rx_stop.reason = err_code, + .data.rx_stop.data.len = data->dma_rx.counter, + .data.rx_stop.data.offset = 0, + .data.rx_stop.data.buf = data->dma_rx.buffer + }; + + async_user_callback(data, &event); +} + +static inline void async_evt_rx_buf_release(struct uart_silabs_data *data) +{ + struct uart_event evt = { + .type = UART_RX_BUF_RELEASED, + .data.rx_buf.buf = data->dma_rx.buffer, + }; + + async_user_callback(data, &evt); +} + +static inline void async_evt_rx_buf_request(struct uart_silabs_data *data) +{ + struct uart_event evt = { + .type = UART_RX_BUF_REQUEST, + }; + + async_user_callback(data, &evt); +} + +static int uart_silabs_async_callback_set(const struct device *dev, uart_callback_t callback, + void *user_data) +{ + struct uart_silabs_data *data = dev->data; + + data->async_cb = callback; + data->async_user_data = user_data; + + return 0; +} + +static void uart_silabs_dma_replace_buffer(const struct device *dev) +{ + struct uart_silabs_data *data = dev->data; + + data->dma_rx.offset = 0; + data->dma_rx.counter = 0; + data->dma_rx.buffer = data->rx_next_buffer; + data->dma_rx.buffer_length = data->rx_next_buffer_len; + data->rx_next_buffer = NULL; + data->rx_next_buffer_len = 0; + + async_evt_rx_buf_request(data); +} + +static void uart_silabs_dma_rx_flush(struct uart_silabs_data *data) +{ + struct dma_status stat; + size_t rx_rcv_len; + + if (!dma_get_status(data->dma_rx.dma_dev, data->dma_rx.dma_channel, &stat)) { + rx_rcv_len = data->dma_rx.buffer_length - stat.pending_length; + if (rx_rcv_len > data->dma_rx.offset) { + data->dma_rx.counter = rx_rcv_len; + async_evt_rx_rdy(data); + } + } +} + +void uart_silabs_dma_rx_cb(const struct device *dma_dev, void *user_data, uint32_t channel, + int status) +{ + const struct device *uart_dev = user_data; + struct uart_silabs_data *data = uart_dev->data; + struct uart_event disabled_event = {.type = UART_RX_DISABLED}; + + if (status < 0) { + async_evt_rx_err(data, status); + return; + } + + data->dma_rx.counter = data->dma_rx.buffer_length; + + async_evt_rx_rdy(data); + + if (data->rx_next_buffer) { + async_evt_rx_buf_release(data); + uart_silabs_dma_replace_buffer(uart_dev); + } else { + dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel); + data->dma_rx.enabled = false; + async_evt_rx_buf_release(data); + async_user_callback(data, &disabled_event); + } +} + +void uart_silabs_dma_tx_cb(const struct device *dma_dev, void *user_data, uint32_t channel, + int status) +{ + const struct device *uart_dev = user_data; + struct uart_silabs_data *data = uart_dev->data; + + dma_stop(data->dma_tx.dma_dev, data->dma_tx.dma_channel); + data->dma_tx.enabled = false; +} + +static int uart_silabs_async_tx(const struct device *dev, const uint8_t *tx_data, size_t buf_size, + int32_t timeout) +{ + const struct uart_silabs_config *config = dev->config; + struct uart_silabs_data *data = dev->data; + int ret; + + if (!data->dma_tx.dma_dev) { + return -ENODEV; + } + + if (data->dma_tx.buffer_length) { + return -EBUSY; + } + + data->dma_tx.buffer = (uint8_t *)tx_data; + data->dma_tx.buffer_length = buf_size; + + /* User timeout is expressed as number of TCMP2 interrupt which occurs every + * SILABS_USART_TIMER_COMPARE_VALUE baud-times + */ + if (data->uart_cfg->baudrate > 0 && timeout >= 0) { + data->dma_tx.timeout = + SILABS_USART_TIMEOUT_TO_TIMERCOUNTER(timeout, data->uart_cfg->baudrate); + } else { + data->dma_tx.timeout = 0; + } + + data->dma_tx.blk_cfg.source_address = (uint32_t)data->dma_tx.buffer; + data->dma_tx.blk_cfg.block_size = data->dma_tx.buffer_length; + + (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_TX); + USART_IntClear(config->base, USART_IF_TXC | USART_IF_TCMP2); + USART_IntEnable(config->base, USART_IF_TXC); + if (timeout >= 0) { + USART_IntEnable(config->base, USART_IF_TCMP2); + } + + ret = dma_config(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &data->dma_tx.dma_cfg); + if (ret) { + LOG_ERR("dma tx config error!"); + return ret; + } + + ret = dma_start(data->dma_tx.dma_dev, data->dma_tx.dma_channel); + if (ret) { + LOG_ERR("UART err: TX DMA start failed!"); + return ret; + } + + data->dma_tx.enabled = true; + + return 0; +} + +static int uart_silabs_async_tx_abort(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + struct uart_silabs_data *data = dev->data; + size_t tx_buffer_length = data->dma_tx.buffer_length; + struct dma_status stat; + + if (!tx_buffer_length) { + return -EFAULT; + } + + USART_IntDisable(config->base, USART_IF_TXC); + USART_IntDisable(config->base, USART_IF_TCMP2); + USART_IntClear(config->base, USART_IF_TXC | USART_IF_TCMP2); + (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX); + + if (!dma_get_status(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &stat)) { + data->dma_tx.counter = tx_buffer_length - stat.pending_length; + } + + dma_stop(data->dma_tx.dma_dev, data->dma_tx.dma_channel); + data->dma_tx.enabled = false; + + async_evt_tx_abort(data); + + return 0; +} + +static int uart_silabs_async_rx_enable(const struct device *dev, uint8_t *rx_buf, size_t buf_size, + int32_t timeout) +{ + const struct uart_silabs_config *config = dev->config; + struct uart_silabs_data *data = dev->data; + int ret; + + if (!data->dma_rx.dma_dev) { + return -ENODEV; + } + + if (data->dma_rx.enabled) { + LOG_WRN("RX was already enabled"); + return -EBUSY; + } + + data->dma_rx.offset = 0; + data->dma_rx.buffer = rx_buf; + data->dma_rx.buffer_length = buf_size; + data->dma_rx.counter = 0; + + /* User timeout is expressed as number of TCMP1 interrupt which occurs every + * SILABS_USART_TIMER_COMPARE_VALUE baud-times + */ + if (data->uart_cfg->baudrate > 0 && timeout >= 0) { + data->dma_rx.timeout = + SILABS_USART_TIMEOUT_TO_TIMERCOUNTER(timeout, data->uart_cfg->baudrate); + } else { + data->dma_rx.timeout = 0; + } + + data->dma_rx.blk_cfg.block_size = buf_size; + data->dma_rx.blk_cfg.dest_address = (uint32_t)data->dma_rx.buffer; + + ret = dma_config(data->dma_rx.dma_dev, data->dma_rx.dma_channel, &data->dma_rx.dma_cfg); + + if (ret) { + LOG_ERR("UART ERR: RX DMA config failed!"); + return -EINVAL; + } + + if (dma_start(data->dma_rx.dma_dev, data->dma_rx.dma_channel)) { + LOG_ERR("UART ERR: RX DMA start failed!"); + return -EFAULT; + } + + (void)uart_silabs_pm_lock_get(dev, UART_SILABS_PM_LOCK_RX); + USART_IntClear(config->base, USART_IF_RXOF | USART_IF_TCMP1); + USART_IntEnable(config->base, USART_IF_RXOF); + + if (timeout >= 0) { + USART_IntEnable(config->base, USART_IF_TCMP1); + } + + data->dma_rx.enabled = true; + + async_evt_rx_buf_request(data); + + return ret; +} + +static int uart_silabs_async_rx_disable(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + USART_TypeDef *usart = config->base; + struct uart_silabs_data *data = dev->data; + struct uart_event disabled_event = {.type = UART_RX_DISABLED}; + + if (!data->dma_rx.enabled) { + return -EFAULT; + } + + dma_stop(data->dma_rx.dma_dev, data->dma_rx.dma_channel); + + USART_IntDisable(usart, USART_IF_RXOF); + USART_IntDisable(usart, USART_IF_TCMP1); + USART_IntClear(usart, USART_IF_RXOF | USART_IF_TCMP1); + (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_RX); + + if (!data->dma_rx.enabled) { + usart->CMD = USART_CMD_CLEARRX; + } + + uart_silabs_dma_rx_flush(data); + + async_evt_rx_buf_release(data); + + if (data->rx_next_buffer) { + struct uart_event rx_next_buf_release_evt = { + .type = UART_RX_BUF_RELEASED, + .data.rx_buf.buf = data->rx_next_buffer, + }; + async_user_callback(data, &rx_next_buf_release_evt); + } + + data->rx_next_buffer = NULL; + data->rx_next_buffer_len = 0; + + data->dma_rx.enabled = false; + + async_user_callback(data, &disabled_event); + + return 0; +} + +static int uart_silabs_async_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len) +{ + struct uart_silabs_data *data = dev->data; + unsigned int key; + int ret; + + key = irq_lock(); + + if (data->rx_next_buffer) { + return -EBUSY; + } else if (!data->dma_rx.enabled) { + return -EACCES; + } + + data->rx_next_buffer = buf; + data->rx_next_buffer_len = len; + data->dma_rx.blk_cfg.dest_address = (uint32_t)buf; + data->dma_rx.blk_cfg.block_size = len; + + irq_unlock(key); + + ret = silabs_ldma_append_block(data->dma_rx.dma_dev, data->dma_rx.dma_channel, + &data->dma_rx.dma_cfg); + if (ret) { + LOG_ERR("UART ERR: RX DMA append failed!"); + return -EINVAL; + } + + return ret; +} + +static int uart_silabs_async_init(const struct device *dev) +{ + const struct uart_silabs_config *config = dev->config; + USART_TypeDef *usart = config->base; + struct uart_silabs_data *data = dev->data; + + data->uart_dev = dev; + + if (data->dma_rx.dma_dev) { + if (!device_is_ready(data->dma_rx.dma_dev)) { + return -ENODEV; + } + data->dma_rx.dma_channel = dma_request_channel(data->dma_rx.dma_dev, NULL); + } + + if (data->dma_tx.dma_dev) { + if (!device_is_ready(data->dma_tx.dma_dev)) { + return -ENODEV; + } + data->dma_tx.dma_channel = dma_request_channel(data->dma_tx.dma_dev, NULL); + } + + data->dma_rx.enabled = false; + data->dma_tx.enabled = false; + + memset(&data->dma_rx.blk_cfg, 0, sizeof(data->dma_rx.blk_cfg)); + data->dma_rx.blk_cfg.source_address = (uintptr_t)&(usart->RXDATA); + data->dma_rx.blk_cfg.dest_address = 0; + data->dma_rx.blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + data->dma_rx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + data->dma_rx.dma_cfg.complete_callback_en = 1; + data->dma_rx.dma_cfg.channel_priority = 3; + data->dma_rx.dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + data->dma_rx.dma_cfg.head_block = &data->dma_rx.blk_cfg; + data->dma_rx.dma_cfg.user_data = (void *)dev; + data->rx_next_buffer = NULL; + data->rx_next_buffer_len = 0; + + memset(&data->dma_tx.blk_cfg, 0, sizeof(data->dma_tx.blk_cfg)); + data->dma_tx.blk_cfg.dest_address = (uintptr_t)&(usart->TXDATA); + data->dma_tx.blk_cfg.source_address = 0; + data->dma_tx.blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; + data->dma_tx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + data->dma_tx.dma_cfg.complete_callback_en = 1; + data->dma_tx.dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + data->dma_tx.dma_cfg.head_block = &data->dma_tx.blk_cfg; + data->dma_tx.dma_cfg.user_data = (void *)dev; + + config->base->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX; + config->base->TIMECMP1 = + USART_TIMECMP1_TSTOP_RXACT | USART_TIMECMP1_TSTART_RXEOF | + USART_TIMECMP1_RESTARTEN | + (SILABS_USART_TIMER_COMPARE_VALUE << _USART_TIMECMP1_TCMPVAL_SHIFT); + config->base->TIMECMP2 = + USART_TIMECMP2_TSTOP_TXST | USART_TIMECMP2_TSTART_TXEOF | USART_TIMECMP2_RESTARTEN | + (SILABS_USART_TIMER_COMPARE_VALUE << _USART_TIMECMP2_TCMPVAL_SHIFT); + + return 0; +} +#endif /* CONFIG_UART_ASYNC_API */ + +static void uart_silabs_isr(const struct device *dev) +{ + __maybe_unused struct uart_silabs_data *data = dev->data; + const struct uart_silabs_config *config = dev->config; + USART_TypeDef *usart = config->base; + uint32_t flags = USART_IntGet(usart); +#ifdef CONFIG_UART_ASYNC_API + struct dma_status stat; +#endif + + if (flags & USART_IF_TXC) { + if (uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX_POLL)) { + USART_IntDisable(usart, USART_IEN_TXC); + USART_IntClear(usart, USART_IF_TXC); + } + } +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + if (data->callback) { + data->callback(dev, data->cb_data); + } +#endif +#ifdef CONFIG_UART_ASYNC_API + if (flags & USART_IF_TCMP1) { + + data->dma_rx.timeout_cnt++; + if (data->dma_rx.timeout_cnt >= data->dma_rx.timeout) { + uart_silabs_dma_rx_flush(data); + + usart->TIMECMP1 &= ~_USART_TIMECMP1_TSTART_MASK; + usart->TIMECMP1 |= USART_TIMECMP1_TSTART_RXEOF; + data->dma_rx.timeout_cnt = 0; + } + + USART_IntClear(usart, USART_IF_TCMP1); + } + if (flags & USART_IF_RXOF) { + async_evt_rx_err(data, UART_ERROR_OVERRUN); + + uart_silabs_async_rx_disable(dev); + + USART_IntClear(usart, USART_IF_RXOF); + } + if (flags & USART_IF_TXC) { + if (!dma_get_status(data->dma_tx.dma_dev, data->dma_tx.dma_channel, &stat)) { + data->dma_tx.counter = data->dma_tx.buffer_length - stat.pending_length; + } + + if (data->dma_tx.counter == data->dma_tx.buffer_length) { + USART_IntDisable(config->base, USART_IF_TXC); + USART_IntDisable(config->base, USART_IF_TCMP2); + USART_IntClear(usart, USART_IF_TXC | USART_IF_TCMP2); + (void)uart_silabs_pm_lock_put(dev, UART_SILABS_PM_LOCK_TX); + + usart->TIMECMP2 &= ~_USART_TIMECMP2_TSTART_MASK; + usart->TIMECMP2 |= USART_TIMECMP2_TSTART_DISABLE; + } + + async_evt_tx_done(data); + } + if (flags & USART_IF_TCMP2) { + data->dma_tx.timeout_cnt++; + if (data->dma_tx.timeout_cnt >= data->dma_tx.timeout) { + usart->TIMECMP2 &= ~_USART_TIMECMP2_TSTART_MASK; + usart->TIMECMP2 |= USART_TIMECMP2_TSTART_DISABLE; + data->dma_tx.timeout_cnt = 0; + + uart_silabs_async_tx_abort(dev); + } + + USART_IntClear(usart, USART_IF_TCMP2); + } +#endif /* CONFIG_UART_ASYNC_API */ +} + +static inline USART_Parity_TypeDef uart_silabs_cfg2ll_parity( + enum uart_config_parity parity) +{ + switch (parity) { + case UART_CFG_PARITY_ODD: + return usartOddParity; + case UART_CFG_PARITY_EVEN: + return usartEvenParity; + case UART_CFG_PARITY_NONE: + default: + return usartNoParity; + } +} + +static inline USART_Stopbits_TypeDef uart_silabs_cfg2ll_stopbits( + enum uart_config_stop_bits sb) +{ + switch (sb) { + case UART_CFG_STOP_BITS_0_5: + return usartStopbits0p5; + case UART_CFG_STOP_BITS_1: + return usartStopbits1; + case UART_CFG_STOP_BITS_2: + return usartStopbits2; + case UART_CFG_STOP_BITS_1_5: + return usartStopbits1p5; + default: + return usartStopbits1; + } +} + +static inline USART_Databits_TypeDef uart_silabs_cfg2ll_databits( + enum uart_config_data_bits db, enum uart_config_parity p) +{ + switch (db) { + case UART_CFG_DATA_BITS_7: + if (p == UART_CFG_PARITY_NONE) { + return usartDatabits7; + } else { + return usartDatabits8; + } + case UART_CFG_DATA_BITS_9: + return usartDatabits9; + case UART_CFG_DATA_BITS_8: + default: + if (p == UART_CFG_PARITY_NONE) { + return usartDatabits8; + } else { + return usartDatabits9; + } + return usartDatabits8; + } +} + +static inline USART_HwFlowControl_TypeDef uart_silabs_cfg2ll_hwctrl( + enum uart_config_flow_control fc) +{ + if (fc == UART_CFG_FLOW_CTRL_RTS_CTS) { + return usartHwFlowControlCtsAndRts; + } + + return usartHwFlowControlNone; +} + +static inline enum uart_config_parity uart_silabs_ll2cfg_parity(USART_Parity_TypeDef parity) +{ + switch (parity) { + case usartOddParity: + return UART_CFG_PARITY_ODD; + case usartEvenParity: + return UART_CFG_PARITY_EVEN; + case usartNoParity: + default: + return UART_CFG_PARITY_NONE; + } +} + +static inline enum uart_config_stop_bits uart_silabs_ll2cfg_stopbits(USART_Stopbits_TypeDef sb) +{ + switch (sb) { + case usartStopbits0p5: + return UART_CFG_STOP_BITS_0_5; + case usartStopbits1: + return UART_CFG_STOP_BITS_1; + case usartStopbits1p5: + return UART_CFG_STOP_BITS_1_5; + case usartStopbits2: + return UART_CFG_STOP_BITS_2; + default: + return UART_CFG_STOP_BITS_1; + } +} + +static inline enum uart_config_data_bits uart_silabs_ll2cfg_databits(USART_Databits_TypeDef db, + USART_Parity_TypeDef p) +{ + switch (db) { + case usartDatabits7: + if (p == usartNoParity) { + return UART_CFG_DATA_BITS_7; + } else { + return UART_CFG_DATA_BITS_6; + } + case usartDatabits9: + if (p == usartNoParity) { + return UART_CFG_DATA_BITS_9; + } else { + return UART_CFG_DATA_BITS_8; + } + case usartDatabits8: + default: + if (p == usartNoParity) { + return UART_CFG_DATA_BITS_8; + } else { + return UART_CFG_DATA_BITS_7; + } + } +} + +static inline enum uart_config_flow_control uart_silabs_ll2cfg_hwctrl( + USART_HwFlowControl_TypeDef fc) +{ + if (fc == usartHwFlowControlCtsAndRts) { + return UART_CFG_FLOW_CTRL_RTS_CTS; + } + + return UART_CFG_FLOW_CTRL_NONE; +} + +static void uart_silabs_configure_peripheral(const struct device *dev, bool enable) +{ + const struct uart_silabs_config *config = dev->config; + const struct uart_silabs_data *data = dev->data; + USART_InitAsync_TypeDef usartInit = USART_INITASYNC_DEFAULT; + + usartInit.baudrate = data->uart_cfg->baudrate; + usartInit.parity = uart_silabs_cfg2ll_parity(data->uart_cfg->parity); + usartInit.stopbits = uart_silabs_cfg2ll_stopbits(data->uart_cfg->stop_bits); + usartInit.databits = uart_silabs_cfg2ll_databits(data->uart_cfg->data_bits, + data->uart_cfg->parity); + usartInit.hwFlowControl = uart_silabs_cfg2ll_hwctrl(data->uart_cfg->flow_ctrl); + usartInit.enable = enable ? usartEnable : usartDisable; + + USART_InitAsync(config->base, &usartInit); +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +static int uart_silabs_configure(const struct device *dev, + const struct uart_config *cfg) +{ + const struct uart_silabs_config *config = dev->config; + USART_TypeDef *base = config->base; + struct uart_silabs_data *data = dev->data; + +#ifdef CONFIG_UART_ASYNC_API + if (data->dma_rx.enabled || data->dma_tx.enabled) { + return -EBUSY; + } +#endif + + if ((cfg->parity == UART_CFG_PARITY_MARK) || + (cfg->parity == UART_CFG_PARITY_SPACE)) { + return -ENOSYS; + } + + if (cfg->flow_ctrl == UART_CFG_FLOW_CTRL_DTR_DSR || + cfg->flow_ctrl == UART_CFG_FLOW_CTRL_RS485) { + return -ENOSYS; + } + + *data->uart_cfg = *cfg; + USART_Enable(base, usartDisable); + + uart_silabs_configure_peripheral(dev, true); + + return 0; +}; + +static int uart_silabs_config_get(const struct device *dev, + struct uart_config *cfg) +{ + struct uart_silabs_data *data = dev->data; + struct uart_config *uart_cfg = data->uart_cfg; + + cfg->baudrate = uart_cfg->baudrate; + cfg->parity = uart_cfg->parity; + cfg->stop_bits = uart_cfg->stop_bits; + cfg->data_bits = uart_cfg->data_bits; + cfg->flow_ctrl = uart_cfg->flow_ctrl; + + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +static int uart_silabs_init(const struct device *dev) +{ + int err; + const struct uart_silabs_config *config = dev->config; + + /* The peripheral and gpio clock are already enabled from soc and gpio driver */ + /* Enable USART clock */ + err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg); + if (err < 0) { + return err; + } + + uart_silabs_configure_peripheral(dev, false); + + config->irq_config_func(dev); + +#ifdef CONFIG_UART_ASYNC_API + err = uart_silabs_async_init(dev); + if (err < 0) { + return err; + } +#endif + return pm_device_driver_init(dev, uart_silabs_pm_action); +} + +static int uart_silabs_pm_action(const struct device *dev, enum pm_device_action action) +{ + int err; + const struct uart_silabs_config *config = dev->config; + __maybe_unused struct uart_silabs_data *data = dev->data; + + if (action == PM_DEVICE_ACTION_RESUME) { + err = clock_control_on(config->clock_dev, + (clock_control_subsys_t)&config->clock_cfg); + if (err < 0 && err != -EALREADY) { + return err; + } + + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + USART_Enable(config->base, usartEnable); + } else if (IS_ENABLED(CONFIG_PM_DEVICE) && (action == PM_DEVICE_ACTION_SUSPEND)) { +#ifdef CONFIG_UART_ASYNC_API + /* Entering suspend requires there to be no active asynchronous calls. */ + __ASSERT_NO_MSG(!data->dma_rx.enabled); + __ASSERT_NO_MSG(!data->dma_tx.enabled); +#endif + USART_Enable(config->base, usartDisable); + + err = clock_control_off(config->clock_dev, + (clock_control_subsys_t)&config->clock_cfg); + if (err < 0) { + return err; + } + + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); + if (err < 0 && err != -ENOENT) { + return err; + } + + } else { + return -ENOTSUP; + } + + return 0; +} + +static DEVICE_API(uart, uart_silabs_driver_api) = { + .poll_in = uart_silabs_poll_in, + .poll_out = uart_silabs_poll_out, + .err_check = uart_silabs_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_silabs_configure, + .config_get = uart_silabs_config_get, +#endif +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_silabs_fifo_fill, + .fifo_read = uart_silabs_fifo_read, + .irq_tx_enable = uart_silabs_irq_tx_enable, + .irq_tx_disable = uart_silabs_irq_tx_disable, + .irq_tx_complete = uart_silabs_irq_tx_complete, + .irq_tx_ready = uart_silabs_irq_tx_ready, + .irq_rx_enable = uart_silabs_irq_rx_enable, + .irq_rx_disable = uart_silabs_irq_rx_disable, + .irq_rx_ready = uart_silabs_irq_rx_ready, + .irq_err_enable = uart_silabs_irq_err_enable, + .irq_err_disable = uart_silabs_irq_err_disable, + .irq_is_pending = uart_silabs_irq_is_pending, + .irq_update = uart_silabs_irq_update, + .irq_callback_set = uart_silabs_irq_callback_set, +#endif +#ifdef CONFIG_UART_ASYNC_API + .callback_set = uart_silabs_async_callback_set, + .tx = uart_silabs_async_tx, + .tx_abort = uart_silabs_async_tx_abort, + .rx_enable = uart_silabs_async_rx_enable, + .rx_disable = uart_silabs_async_rx_disable, + .rx_buf_rsp = uart_silabs_async_rx_buf_rsp, +#endif +}; + +#ifdef CONFIG_UART_ASYNC_API + +#define UART_DMA_CHANNEL_INIT(index, dir) \ + .dma_##dir = { \ + .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(index, dir)), \ + .dma_cfg = { \ + .dma_slot = SILABS_LDMA_REQSEL_TO_SLOT( \ + DT_INST_DMAS_CELL_BY_NAME(index, dir, slot)), \ + .source_data_size = 1, \ + .dest_data_size = 1, \ + .source_burst_length = 1, \ + .dest_burst_length = 1, \ + .dma_callback = uart_silabs_dma_##dir##_cb, \ + } \ + }, +#define UART_DMA_CHANNEL(index, dir) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(index, dmas), \ + (UART_DMA_CHANNEL_INIT(index, dir)), ()) +#else + +#define UART_DMA_CHANNEL(index, dir) + +#endif + +#define SILABS_USART_IRQ_HANDLER_FUNC(idx) .irq_config_func = usart_silabs_config_func_##idx, +#define SILABS_USART_IRQ_HANDLER(idx) \ + static void usart_silabs_config_func_##idx(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, rx, irq), \ + DT_INST_IRQ_BY_NAME(idx, rx, priority), uart_silabs_isr, \ + DEVICE_DT_INST_GET(idx), 0); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, tx, irq), \ + DT_INST_IRQ_BY_NAME(idx, tx, priority), uart_silabs_isr, \ + DEVICE_DT_INST_GET(idx), 0); \ + \ + irq_enable(DT_INST_IRQ_BY_NAME(idx, rx, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(idx, tx, irq)); \ + } + +#define SILABS_USART_INIT(idx) \ + SILABS_USART_IRQ_HANDLER(idx); \ + PINCTRL_DT_INST_DEFINE(idx); \ + PM_DEVICE_DT_INST_DEFINE(idx, uart_silabs_pm_action); \ + \ + static struct uart_config uart_cfg_##idx = { \ + .baudrate = DT_INST_PROP(idx, current_speed), \ + .parity = DT_INST_ENUM_IDX(idx, parity), \ + .stop_bits = DT_INST_ENUM_IDX(idx, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(idx, data_bits), \ + .flow_ctrl = DT_INST_PROP(idx, hw_flow_control) ? UART_CFG_FLOW_CTRL_RTS_CTS \ + : UART_CFG_FLOW_CTRL_NONE, \ + }; \ + \ + static const struct uart_silabs_config uart_silabs_cfg_##idx = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ + .clock_cfg = SILABS_DT_INST_CLOCK_CFG(idx), \ + SILABS_USART_IRQ_HANDLER_FUNC(idx) \ + }; \ + \ + static struct uart_silabs_data uart_silabs_data_##idx = { \ + .uart_cfg = &uart_cfg_##idx, \ + UART_DMA_CHANNEL(idx, rx) \ + UART_DMA_CHANNEL(idx, tx) \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, uart_silabs_init, PM_DEVICE_DT_INST_GET(idx), \ + &uart_silabs_data_##idx, &uart_silabs_cfg_##idx, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, &uart_silabs_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SILABS_USART_INIT) diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index d0c511b3b4aba..13c85a5066dd0 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -99,6 +99,10 @@ uint32_t lpuartdiv_calc(const uint64_t clock_rate, const uint32_t baud_rate) #endif /* USART_PRESC_PRESCALER */ #endif /* HAS_LPUART */ +#ifdef CONFIG_UART_ASYNC_API +#define STM32_ASYNC_STATUS_TIMEOUT (DMA_STATUS_BLOCK + 1) +#endif + #ifdef CONFIG_PM static void uart_stm32_pm_policy_state_lock_get(const struct device *dev) { @@ -1117,11 +1121,16 @@ static inline void async_evt_rx_rdy(struct uart_stm32_data *data) .data.rx.offset = data->dma_rx.offset }; - /* update the current pos for new data */ - data->dma_rx.offset = data->dma_rx.counter; + /* When cyclic DMA is used, buffer positions are not updated - call callback every time*/ + if (data->dma_rx.dma_cfg.cyclic == 0) { + /* update the current pos for new data */ + data->dma_rx.offset = data->dma_rx.counter; - /* send event only for new data */ - if (event.data.rx.len > 0) { + /* send event only for new data */ + if (event.data.rx.len > 0) { + async_user_callback(data, &event); + } + } else { async_user_callback(data, &event); } } @@ -1204,20 +1213,45 @@ static inline void async_timer_start(struct k_work_delayable *work, } } -static void uart_stm32_dma_rx_flush(const struct device *dev) +static void uart_stm32_dma_rx_flush(const struct device *dev, int status) { struct dma_status stat; struct uart_stm32_data *data = dev->data; - if (dma_get_status(data->dma_rx.dma_dev, - data->dma_rx.dma_channel, &stat) == 0) { - size_t rx_rcv_len = data->dma_rx.buffer_length - - stat.pending_length; - if (rx_rcv_len > data->dma_rx.offset) { - data->dma_rx.counter = rx_rcv_len; + size_t rx_rcv_len = 0; - async_evt_rx_rdy(data); + switch (status) { + case DMA_STATUS_COMPLETE: + /* fully complete */ + data->dma_rx.counter = data->dma_rx.buffer_length; + break; + case DMA_STATUS_BLOCK: + /* half complete */ + data->dma_rx.counter = data->dma_rx.buffer_length / 2; + + break; + default: /* likely STM32_ASYNC_STATUS_TIMEOUT */ + if (dma_get_status(data->dma_rx.dma_dev, data->dma_rx.dma_channel, &stat) == 0) { + rx_rcv_len = data->dma_rx.buffer_length - stat.pending_length; + data->dma_rx.counter = rx_rcv_len; } + break; + } + + async_evt_rx_rdy(data); + + switch (status) { /* update offset*/ + case DMA_STATUS_COMPLETE: + /* fully complete */ + data->dma_rx.offset = 0; + break; + case DMA_STATUS_BLOCK: + /* half complete */ + data->dma_rx.offset = data->dma_rx.buffer_length / 2; + break; + default: /* likely STM32_ASYNC_STATUS_TIMEOUT */ + data->dma_rx.offset += rx_rcv_len - data->dma_rx.offset; + break; } } @@ -1269,7 +1303,7 @@ static void uart_stm32_isr(const struct device *dev) LOG_DBG("idle interrupt occurred"); if (data->dma_rx.timeout == 0) { - uart_stm32_dma_rx_flush(dev); + uart_stm32_dma_rx_flush(dev, STM32_ASYNC_STATUS_TIMEOUT); } else { /* Start the RX timer not null */ async_timer_start(&data->dma_rx.timeout_work, @@ -1417,7 +1451,7 @@ static int uart_stm32_async_rx_disable(const struct device *dev) LL_USART_DisableIT_IDLE(usart); - uart_stm32_dma_rx_flush(dev); + uart_stm32_dma_rx_flush(dev, STM32_ASYNC_STATUS_TIMEOUT); async_evt_rx_buf_release(data); @@ -1517,27 +1551,32 @@ void uart_stm32_dma_rx_cb(const struct device *dma_dev, void *user_data, (void)k_work_cancel_delayable(&data->dma_rx.timeout_work); - /* true since this functions occurs when buffer if full */ - data->dma_rx.counter = data->dma_rx.buffer_length; + /* If we are in NORMAL MODE */ + if (data->dma_rx.dma_cfg.cyclic == 0) { - async_evt_rx_rdy(data); - - if (data->rx_next_buffer != NULL) { - async_evt_rx_buf_release(data); + /* true since this functions occurs when buffer is full */ + data->dma_rx.counter = data->dma_rx.buffer_length; + async_evt_rx_rdy(data); + if (data->rx_next_buffer != NULL) { + async_evt_rx_buf_release(data); - /* replace the buffer when the current - * is full and not the same as the next - * one. - */ - uart_stm32_dma_replace_buffer(uart_dev); + /* replace the buffer when the current + * is full and not the same as the next + * one. + */ + uart_stm32_dma_replace_buffer(uart_dev); + } else { + /* Buffer full without valid next buffer, + * an UART_RX_DISABLED event must be generated, + * but uart_stm32_async_rx_disable() cannot be + * called in ISR context. So force the RX timeout + * to minimum value and let the RX timeout to do the job. + */ + k_work_reschedule(&data->dma_rx.timeout_work, K_TICKS(1)); + } } else { - /* Buffer full without valid next buffer, - * an UART_RX_DISABLED event must be generated, - * but uart_stm32_async_rx_disable() cannot be - * called in ISR context. So force the RX timeout - * to minimum value and let the RX timeout to do the job. - */ - k_work_reschedule(&data->dma_rx.timeout_work, K_TICKS(1)); + /* CIRCULAR MODE */ + uart_stm32_dma_rx_flush(data->uart_dev, status); } } @@ -1722,7 +1761,7 @@ static void uart_stm32_async_rx_timeout(struct k_work *work) if (data->dma_rx.counter == data->dma_rx.buffer_length) { uart_stm32_async_rx_disable(dev); } else { - uart_stm32_dma_rx_flush(dev); + uart_stm32_dma_rx_flush(dev, STM32_ASYNC_STATUS_TIMEOUT); } } @@ -1829,9 +1868,10 @@ static int uart_stm32_async_init(const struct device *dev) data->dma_rx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; } - /* RX disable circular buffer */ - data->dma_rx.blk_cfg.source_reload_en = 0; - data->dma_rx.blk_cfg.dest_reload_en = 0; + /* Enable/disable RX circular buffer */ + data->dma_rx.blk_cfg.source_reload_en = data->dma_rx.dma_cfg.cyclic; + data->dma_rx.blk_cfg.dest_reload_en = data->dma_rx.dma_cfg.cyclic; + data->dma_rx.blk_cfg.fifo_mode_control = data->dma_rx.fifo_threshold; data->dma_rx.dma_cfg.head_block = &data->dma_rx.blk_cfg; @@ -1868,6 +1908,10 @@ static int uart_stm32_async_init(const struct device *dev) data->dma_tx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; } + /* Enable/disable TX circular buffer */ + data->dma_tx.blk_cfg.source_reload_en = data->dma_tx.dma_cfg.cyclic; + data->dma_tx.blk_cfg.dest_reload_en = data->dma_tx.dma_cfg.cyclic; + data->dma_tx.blk_cfg.fifo_mode_control = data->dma_tx.fifo_threshold; data->dma_tx.dma_cfg.head_block = &data->dma_tx.blk_cfg; @@ -2225,6 +2269,8 @@ static int uart_stm32_pm_action(const struct device *dev, .dma_slot = STM32_DMA_SLOT(index, dir, slot),\ .channel_direction = STM32_DMA_CONFIG_DIRECTION( \ STM32_DMA_CHANNEL_CONFIG(index, dir)),\ + .cyclic = STM32_DMA_CONFIG_CYCLIC( \ + STM32_DMA_CHANNEL_CONFIG(index, dir)), \ .channel_priority = STM32_DMA_CONFIG_PRIORITY( \ STM32_DMA_CHANNEL_CONFIG(index, dir)), \ .source_data_size = STM32_DMA_CONFIG_##src_dev##_DATA_SIZE(\ @@ -2299,18 +2345,13 @@ static void uart_stm32_irq_config_func_##index(const struct device *dev) \ */ #define STM32_UART_CHECK_DT_PARITY(index) \ BUILD_ASSERT( \ - !(DT_INST_ENUM_IDX_OR(index, parity, STM32_UART_DEFAULT_PARITY) \ - == UART_CFG_PARITY_MARK || \ - DT_INST_ENUM_IDX_OR(index, parity, STM32_UART_DEFAULT_PARITY) \ - == UART_CFG_PARITY_SPACE), \ + !(DT_INST_ENUM_IDX(index, parity) == UART_CFG_PARITY_MARK || \ + DT_INST_ENUM_IDX(index, parity) == UART_CFG_PARITY_SPACE), \ "Node " DT_NODE_PATH(DT_DRV_INST(index)) \ " has unsupported parity configuration"); \ BUILD_ASSERT( \ - !(DT_INST_ENUM_IDX_OR(index, parity, STM32_UART_DEFAULT_PARITY) \ - != UART_CFG_PARITY_NONE && \ - DT_INST_ENUM_IDX_OR(index, data_bits, \ - STM32_UART_DEFAULT_DATA_BITS) \ - == UART_CFG_DATA_BITS_9), \ + !(DT_INST_ENUM_IDX(index, parity) != UART_CFG_PARITY_NONE && \ + DT_INST_ENUM_IDX(index, data_bits) == UART_CFG_DATA_BITS_9), \ "Node " DT_NODE_PATH(DT_DRV_INST(index)) \ " has unsupported parity + data bits combination"); @@ -2321,32 +2362,18 @@ BUILD_ASSERT( \ #ifdef LL_USART_DATAWIDTH_7B #define STM32_UART_CHECK_DT_DATA_BITS(index) \ BUILD_ASSERT( \ - !(DT_INST_ENUM_IDX_OR(index, data_bits, \ - STM32_UART_DEFAULT_DATA_BITS) \ - == UART_CFG_DATA_BITS_5 || \ - (DT_INST_ENUM_IDX_OR(index, data_bits, \ - STM32_UART_DEFAULT_DATA_BITS) \ - == UART_CFG_DATA_BITS_6 && \ - DT_INST_ENUM_IDX_OR(index, parity, \ - STM32_UART_DEFAULT_PARITY) \ - == UART_CFG_PARITY_NONE)), \ + !(DT_INST_ENUM_IDX(index, data_bits) == UART_CFG_DATA_BITS_5 || \ + (DT_INST_ENUM_IDX(index, data_bits) == UART_CFG_DATA_BITS_6 && \ + DT_INST_ENUM_IDX(index, parity) == UART_CFG_PARITY_NONE)), \ "Node " DT_NODE_PATH(DT_DRV_INST(index)) \ " has unsupported data bits configuration"); #else #define STM32_UART_CHECK_DT_DATA_BITS(index) \ BUILD_ASSERT( \ - !(DT_INST_ENUM_IDX_OR(index, data_bits, \ - STM32_UART_DEFAULT_DATA_BITS) \ - == UART_CFG_DATA_BITS_5 || \ - DT_INST_ENUM_IDX_OR(index, data_bits, \ - STM32_UART_DEFAULT_DATA_BITS) \ - == UART_CFG_DATA_BITS_6 || \ - (DT_INST_ENUM_IDX_OR(index, data_bits, \ - STM32_UART_DEFAULT_DATA_BITS) \ - == UART_CFG_DATA_BITS_7 && \ - DT_INST_ENUM_IDX_OR(index, parity, \ - STM32_UART_DEFAULT_PARITY) \ - == UART_CFG_PARITY_NONE)), \ + !(DT_INST_ENUM_IDX(index, data_bits) == UART_CFG_DATA_BITS_5 || \ + DT_INST_ENUM_IDX(index, data_bits) == UART_CFG_DATA_BITS_6 || \ + (DT_INST_ENUM_IDX(index, data_bits) == UART_CFG_DATA_BITS_7 && \ + DT_INST_ENUM_IDX(index, parity) == UART_CFG_PARITY_NONE)), \ "Node " DT_NODE_PATH(DT_DRV_INST(index)) \ " has unsupported data bits configuration"); #endif @@ -2358,9 +2385,7 @@ BUILD_ASSERT( \ #ifndef LL_USART_STOPBITS_0_5 #define STM32_UART_CHECK_DT_STOP_BITS_0_5(index) \ BUILD_ASSERT( \ - !(DT_INST_ENUM_IDX_OR(index, stop_bits, \ - STM32_UART_DEFAULT_STOP_BITS) \ - == UART_CFG_STOP_BITS_0_5), \ + DT_INST_ENUM_IDX(index, stop_bits) != UART_CFG_STOP_BITS_0_5, \ "Node " DT_NODE_PATH(DT_DRV_INST(index)) \ " has unsupported stop bits configuration"); /* LPUARTs don't support 0.5 stop bits configurations */ @@ -2368,9 +2393,7 @@ BUILD_ASSERT( \ #define STM32_UART_CHECK_DT_STOP_BITS_0_5(index) \ BUILD_ASSERT( \ !(DT_HAS_COMPAT_STATUS_OKAY(st_stm32_lpuart) && \ - DT_INST_ENUM_IDX_OR(index, stop_bits, \ - STM32_UART_DEFAULT_STOP_BITS) \ - == UART_CFG_STOP_BITS_0_5), \ + DT_INST_ENUM_IDX(index, stop_bits) == UART_CFG_STOP_BITS_0_5), \ "Node " DT_NODE_PATH(DT_DRV_INST(index)) \ " has unsupported stop bits configuration"); #endif @@ -2382,9 +2405,7 @@ BUILD_ASSERT( \ #ifndef LL_USART_STOPBITS_1_5 #define STM32_UART_CHECK_DT_STOP_BITS_1_5(index) \ BUILD_ASSERT( \ - DT_INST_ENUM_IDX_OR(index, stop_bits, \ - STM32_UART_DEFAULT_STOP_BITS) \ - != UART_CFG_STOP_BITS_1_5, \ + DT_INST_ENUM_IDX(index, stop_bits) != UART_CFG_STOP_BITS_1_5, \ "Node " DT_NODE_PATH(DT_DRV_INST(index)) \ " has unsupported stop bits configuration"); /* LPUARTs don't support 1.5 stop bits configurations */ @@ -2392,9 +2413,7 @@ BUILD_ASSERT( \ #define STM32_UART_CHECK_DT_STOP_BITS_1_5(index) \ BUILD_ASSERT( \ !(DT_HAS_COMPAT_STATUS_OKAY(st_stm32_lpuart) && \ - DT_INST_ENUM_IDX_OR(index, stop_bits, \ - STM32_UART_DEFAULT_STOP_BITS) \ - == UART_CFG_STOP_BITS_1_5), \ + DT_INST_ENUM_IDX(index, stop_bits) == UART_CFG_STOP_BITS_1_5), \ "Node " DT_NODE_PATH(DT_DRV_INST(index)) \ " has unsupported stop bits configuration"); #endif @@ -2408,14 +2427,10 @@ static const struct stm32_pclken pclken_##index[] = \ STM32_DT_INST_CLOCKS(index);\ \ static struct uart_config uart_cfg_##index = { \ - .baudrate = DT_INST_PROP_OR(index, current_speed, \ - STM32_UART_DEFAULT_BAUDRATE), \ - .parity = DT_INST_ENUM_IDX_OR(index, parity, \ - STM32_UART_DEFAULT_PARITY), \ - .stop_bits = DT_INST_ENUM_IDX_OR(index, stop_bits, \ - STM32_UART_DEFAULT_STOP_BITS), \ - .data_bits = DT_INST_ENUM_IDX_OR(index, data_bits, \ - STM32_UART_DEFAULT_DATA_BITS), \ + .baudrate = DT_INST_PROP(index, current_speed), \ + .parity = DT_INST_ENUM_IDX(index, parity), \ + .stop_bits = DT_INST_ENUM_IDX(index, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(index, data_bits), \ .flow_ctrl = DT_INST_PROP(index, hw_flow_control) \ ? UART_CFG_FLOW_CTRL_RTS_CTS \ : UART_CFG_FLOW_CTRL_NONE, \ diff --git a/drivers/serial/uart_stm32.h b/drivers/serial/uart_stm32.h index 7c6f432a50451..6420f67f64eda 100644 --- a/drivers/serial/uart_stm32.h +++ b/drivers/serial/uart_stm32.h @@ -18,11 +18,6 @@ #include -#define STM32_UART_DEFAULT_BAUDRATE 115200 -#define STM32_UART_DEFAULT_PARITY UART_CFG_PARITY_NONE -#define STM32_UART_DEFAULT_STOP_BITS UART_CFG_STOP_BITS_1 -#define STM32_UART_DEFAULT_DATA_BITS UART_CFG_DATA_BITS_8 - /* device config */ struct uart_stm32_config { /* USART instance */ diff --git a/drivers/serial/uart_sy1xx.c b/drivers/serial/uart_sy1xx.c index 7bc4de39380e3..7027849b9bb1f 100644 --- a/drivers/serial/uart_sy1xx.c +++ b/drivers/serial/uart_sy1xx.c @@ -11,10 +11,12 @@ #include #include #include +#include struct sy1xx_uart_config { uint32_t base; uint32_t inst; + const struct pinctrl_dev_config *pcfg; }; typedef struct { @@ -259,28 +261,11 @@ static int sy1xx_uart_init(const struct device *dev) sy1xx_udma_enable_clock(SY1XX_UDMA_MODULE_UART, config->inst); /* PAD config */ - uint32_t pad_config_tx = - SY1XX_PAD_CONFIG(0, SY1XX_PAD_SMT_DISABLE, SY1XX_PAD_SLEW_LOW, SY1XX_PAD_PULLUP_DIS, - SY1XX_PAD_PULLDOWN_DIS, SY1XX_PAD_DRIVE_2PF, SY1XX_PAD_PMOD_NORMAL, - SY1XX_PAD_DIR_OUTPUT); + int32_t ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); - uint32_t pad_config_rx = - SY1XX_PAD_CONFIG(8, SY1XX_PAD_SMT_DISABLE, SY1XX_PAD_SLEW_LOW, SY1XX_PAD_PULLUP_DIS, - SY1XX_PAD_PULLDOWN_DIS, SY1XX_PAD_DRIVE_2PF, SY1XX_PAD_PMOD_NORMAL, - SY1XX_PAD_DIR_INPUT); - - uint32_t pad_config_cts = - SY1XX_PAD_CONFIG(16, SY1XX_PAD_SMT_DISABLE, SY1XX_PAD_SLEW_LOW, SY1XX_PAD_PULLUP_EN, - SY1XX_PAD_PULLDOWN_DIS, SY1XX_PAD_DRIVE_2PF, SY1XX_PAD_PMOD_NORMAL, - SY1XX_PAD_DIR_INPUT); - - uint32_t pad_config_rts = - SY1XX_PAD_CONFIG(24, SY1XX_PAD_SMT_DISABLE, SY1XX_PAD_SLEW_LOW, - SY1XX_PAD_PULLUP_DIS, SY1XX_PAD_PULLDOWN_DIS, SY1XX_PAD_DRIVE_2PF, - SY1XX_PAD_PMOD_NORMAL, SY1XX_PAD_DIR_OUTPUT); - - sys_write32((pad_config_tx | pad_config_rx | pad_config_cts | pad_config_rts), - SY1XX_PAD_CONFIG_ADDR_UART + (config->inst * 4 + 0)); + if (ret < 0) { + return ret; + } sy1xx_uartConfig_t default_config = { .baudrate = 1000000, @@ -306,9 +291,12 @@ static DEVICE_API(uart, sy1xx_uart_driver_api) = { #define SYS1XX_UART_INIT(n) \ \ + PINCTRL_DT_INST_DEFINE(n); \ + \ static const struct sy1xx_uart_config sy1xx_uart_##n##_cfg = { \ .base = (uint32_t)DT_INST_REG_ADDR(n), \ .inst = (uint32_t)DT_INST_PROP(n, instance), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ }; \ \ static struct sy1xx_uart_data __attribute__((section(".udma_access"))) \ diff --git a/drivers/serial/uart_wch_usart.c b/drivers/serial/uart_wch_usart.c index aac67c8e63e2a..25a10b2ed0694 100644 --- a/drivers/serial/uart_wch_usart.c +++ b/drivers/serial/uart_wch_usart.c @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -20,9 +21,14 @@ struct usart_wch_config { uint8_t parity; uint8_t clock_id; const struct pinctrl_dev_config *pin_cfg; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + void (*irq_config_func)(const struct device *dev); +#endif }; struct usart_wch_data { + uart_irq_callback_user_data_t cb; + void *user_data; }; static int usart_wch_init(const struct device *dev) @@ -66,6 +72,10 @@ static int usart_wch_init(const struct device *dev) return err; } +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + config->irq_config_func(dev); +#endif + return 0; } @@ -103,6 +113,9 @@ static int usart_wch_err_check(const struct device *dev) if ((statr & USART_STATR_PE) != 0) { errors |= UART_ERROR_PARITY; } + if ((statr & USART_STATR_LBD) != 0) { + errors |= UART_BREAK; + } if ((statr & USART_STATR_FE) != 0) { errors |= UART_ERROR_FRAMING; } @@ -116,25 +129,214 @@ static int usart_wch_err_check(const struct device *dev) return errors; } +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static void usart_wch_isr(const struct device *dev) +{ + struct usart_wch_data *data = dev->data; + + if (data->cb) { + data->cb(dev, data->user_data); + } +} + +static int usart_wch_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + if (!len || !(regs->STATR & USART_STATR_TXE)) { + return 0; + } + + regs->DATAR = tx_data[0]; + return 1; +} + +static int usart_wch_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + if (!size || !(regs->STATR & USART_STATR_RXNE)) { + return 0; + } + + rx_data[0] = regs->DATAR; + return 1; +} + +static void usart_wch_irq_tx_enable(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + regs->CTLR1 |= (USART_CTLR1_TXEIE | USART_CTLR1_TCIE); +} + +static void usart_wch_irq_tx_disable(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + regs->CTLR1 &= ~(USART_CTLR1_TXEIE | USART_CTLR1_TCIE); +} + +static int usart_wch_irq_tx_ready(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + return (regs->STATR & USART_STATR_TXE) > 0; +} + +static void usart_wch_irq_rx_enable(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + regs->CTLR1 |= USART_CTLR1_RXNEIE; +} + +static void usart_wch_irq_rx_disable(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + regs->CTLR1 &= ~USART_CTLR1_RXNEIE; +} + +static int usart_wch_irq_tx_complete(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + return (regs->STATR & USART_STATR_TC) > 0; +} + +static int usart_wch_irq_rx_ready(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + return (regs->STATR & USART_STATR_RXNE) > 0; +} + +static void usart_wch_irq_err_enable(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + regs->CTLR1 |= USART_CTLR1_PEIE; + regs->CTLR2 |= USART_CTLR2_LBDIE; + regs->CTLR3 |= USART_CTLR3_EIE; +} + +static void usart_wch_irq_err_disable(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + + regs->CTLR1 &= ~USART_CTLR1_PEIE; + regs->CTLR2 &= ~USART_CTLR2_LBDIE; + regs->CTLR3 &= ~USART_CTLR3_EIE; +} + +static int usart_wch_irq_is_pending(const struct device *dev) +{ + const struct usart_wch_config *config = dev->config; + USART_TypeDef *regs = config->regs; + uint16_t ctlr1 = regs->CTLR1; + uint16_t ctlr2 = regs->CTLR2; + uint16_t ctlr3 = regs->CTLR3; + uint16_t statr = regs->STATR; + uint16_t stat_mask = 0; + + stat_mask |= (ctlr1 & USART_CTLR1_TXEIE) ? USART_STATR_TXE : 0; + stat_mask |= (ctlr1 & USART_CTLR1_TCIE) ? USART_STATR_TC : 0; + stat_mask |= (ctlr1 & USART_CTLR1_RXNEIE) ? USART_STATR_RXNE | USART_STATR_ORE : 0; + stat_mask |= (ctlr1 & USART_CTLR1_IDLEIE) ? USART_STATR_IDLE : 0; + stat_mask |= (ctlr1 & USART_CTLR1_PEIE) ? USART_STATR_PE : 0; + + stat_mask |= (ctlr2 & USART_CTLR2_LBDIE) ? USART_STATR_LBD : 0; + stat_mask |= + (ctlr3 & USART_CTLR3_EIE) ? USART_STATR_NE | USART_STATR_ORE | USART_STATR_FE : 0; + stat_mask |= (ctlr3 & USART_CTLR3_CTSIE) ? USART_STATR_CTS : 0; + + return (statr & stat_mask) > 0; +} + +static int usart_wch_irq_update(const struct device *dev) +{ + return 1; +} + +static void usart_wch_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct usart_wch_data *data = dev->data; + + data->cb = cb; + data->user_data = user_data; +} +#endif /*CONFIG_UART_INTERRUPT_DRIVEN*/ + static DEVICE_API(uart, usart_wch_driver_api) = { .poll_in = usart_wch_poll_in, .poll_out = usart_wch_poll_out, .err_check = usart_wch_err_check, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = usart_wch_fifo_fill, + .fifo_read = usart_wch_fifo_read, + .irq_tx_enable = usart_wch_irq_tx_enable, + .irq_tx_disable = usart_wch_irq_tx_disable, + .irq_tx_ready = usart_wch_irq_tx_ready, + .irq_rx_enable = usart_wch_irq_rx_enable, + .irq_rx_disable = usart_wch_irq_rx_disable, + .irq_tx_complete = usart_wch_irq_tx_complete, + .irq_rx_ready = usart_wch_irq_rx_ready, + .irq_err_enable = usart_wch_irq_err_enable, + .irq_err_disable = usart_wch_irq_err_disable, + .irq_is_pending = usart_wch_irq_is_pending, + .irq_update = usart_wch_irq_update, + .irq_callback_set = usart_wch_irq_callback_set, +#endif }; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define USART_WCH_IRQ_HANDLER_DECL(idx) \ + static void usart_wch_irq_config_func_##idx(const struct device *dev); + +#define USART_WCH_IRQ_HANDLER_FUNC(idx) .irq_config_func = usart_wch_irq_config_func_##idx, + +#define USART_WCH_IRQ_HANDLER(idx) \ + static void usart_wch_irq_config_func_##idx(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(index, priority), usart_wch_isr, \ + DEVICE_DT_INST_GET(idx), 0); \ + irq_enable(DT_INST_IRQN(idx)); \ + } +#else +#define USART_WCH_IRQ_HANDLER_DECL(idx) +#define USART_WCH_IRQ_HANDLER_FUNC(idx) +#define USART_WCH_IRQ_HANDLER(idx) +#endif + #define USART_WCH_INIT(idx) \ PINCTRL_DT_INST_DEFINE(idx); \ + USART_WCH_IRQ_HANDLER_DECL(idx) \ static struct usart_wch_data usart_wch_##idx##_data; \ static const struct usart_wch_config usart_wch_##idx##_config = { \ .regs = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ .current_speed = DT_INST_PROP(idx, current_speed), \ - .parity = DT_INST_ENUM_IDX_OR(idx, parity, UART_CFG_PARITY_NONE), \ + .parity = DT_INST_ENUM_IDX(idx, parity), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ .clock_id = DT_INST_CLOCKS_CELL(idx, id), \ .pin_cfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ - }; \ + USART_WCH_IRQ_HANDLER_FUNC(idx)}; \ DEVICE_DT_INST_DEFINE(idx, &usart_wch_init, NULL, &usart_wch_##idx##_data, \ &usart_wch_##idx##_config, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, &usart_wch_driver_api); + CONFIG_SERIAL_INIT_PRIORITY, &usart_wch_driver_api); \ + USART_WCH_IRQ_HANDLER(idx) DT_INST_FOREACH_STATUS_OKAY(USART_WCH_INIT) diff --git a/drivers/serial/uart_xlnx_uartlite.c b/drivers/serial/uart_xlnx_uartlite.c index 6ae60cf1d0be9..8898ff6783373 100644 --- a/drivers/serial/uart_xlnx_uartlite.c +++ b/drivers/serial/uart_xlnx_uartlite.c @@ -382,7 +382,7 @@ static DEVICE_API(uart, xlnx_uartlite_driver_api) = { xlnx_uartlite_isr, \ DEVICE_DT_INST_GET(n), 0); \ \ - irq_enable(DT_INST_IRQ_BY_IDX(n, i, irq)); \ + irq_enable(DT_INST_IRQN_BY_IDX(n, i)); \ } while (false) #define XLNX_UARTLITE_CONFIG_FUNC(n) \ static void xlnx_uartlite_config_func_##n(const struct device *dev) \ diff --git a/drivers/serial/usart_gd32.c b/drivers/serial/usart_gd32.c index 9936a818124b4..bbccf6525ceae 100644 --- a/drivers/serial/usart_gd32.c +++ b/drivers/serial/usart_gd32.c @@ -335,7 +335,7 @@ static DEVICE_API(uart, usart_gd32_driver_api) = { .clkid = DT_INST_CLOCKS_CELL(n, id), \ .reset = RESET_DT_SPEC_INST_GET(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ GD32_USART_IRQ_HANDLER_FUNC_INIT(n) \ }; \ DEVICE_DT_INST_DEFINE(n, usart_gd32_init, \ diff --git a/drivers/smbus/smbus_shell.c b/drivers/smbus/smbus_shell.c index 9ecbefa495b6d..7f31ea93e8d1b 100644 --- a/drivers/smbus/smbus_shell.c +++ b/drivers/smbus/smbus_shell.c @@ -48,7 +48,7 @@ static int cmd_smbus_scan(const struct shell *sh, size_t argc, char **argv) const struct device *dev; uint8_t cnt = 0, first = 0x04, last = 0x77; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -87,7 +87,7 @@ static int cmd_smbus_quick(const struct shell *sh, size_t argc, char **argv) uint8_t addr; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -111,7 +111,7 @@ static int cmd_smbus_byte_read(const struct shell *sh, size_t argc, char **argv) uint8_t out; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -140,7 +140,7 @@ static int cmd_smbus_byte_write(const struct shell *sh, uint8_t value; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -169,7 +169,7 @@ static int cmd_smbus_byte_data_read(const struct shell *sh, uint8_t out; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -199,7 +199,7 @@ static int cmd_smbus_byte_data_write(const struct shell *sh, uint8_t value; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -228,7 +228,7 @@ static int cmd_smbus_word_data_read(const struct shell *sh, uint16_t out; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -258,7 +258,7 @@ static int cmd_smbus_word_data_write(const struct shell *sh, uint16_t value; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -293,7 +293,7 @@ static int cmd_smbus_block_write(const struct shell *sh, return -EINVAL; } - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; @@ -328,7 +328,7 @@ static int cmd_smbus_block_read(const struct shell *sh, uint8_t count; int ret; - dev = device_get_binding(argv[ARGV_DEV]); + dev = shell_device_get_binding(argv[ARGV_DEV]); if (!dev) { shell_error(sh, "SMBus: Device %s not found", argv[ARGV_DEV]); return -ENODEV; diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index e7746e17edb26..c120d75ea9cf1 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -23,8 +23,6 @@ zephyr_library_sources_ifdef(CONFIG_SPI_CC13XX_CC26XX spi_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_SPI_DW spi_dw.c) zephyr_library_sources_ifdef(CONFIG_SPI_EMUL spi_emul.c) zephyr_library_sources_ifdef(CONFIG_SPI_GD32 spi_gd32.c) -zephyr_library_sources_ifdef(CONFIG_SPI_GECKO_EUSART spi_gecko_eusart.c) -zephyr_library_sources_ifdef(CONFIG_SPI_GECKO_USART spi_gecko_usart.c) zephyr_library_sources_ifdef(CONFIG_SPI_GRLIB_SPIMCTRL spi_grlib_spimctrl.c) zephyr_library_sources_ifdef(CONFIG_SPI_INFINEON_CAT1 spi_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_SPI_ITE_IT8XXX2 spi_it8xxx2.c) @@ -37,7 +35,6 @@ zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_DSPI spi_mcux_dspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_ECSPI spi_mcux_ecspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_FLEXCOMM spi_mcux_flexcomm.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_FLEXIO spi_mcux_flexio.c) -zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_LPSPI spi_mcux_lpspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_NPCX_SPIP spi_npcx_spip.c) zephyr_library_sources_ifdef(CONFIG_SPI_NRFX_SPI spi_nrfx_spi.c spi_nrfx_common.c) zephyr_library_sources_ifdef(CONFIG_SPI_NRFX_SPIM spi_nrfx_spim.c spi_nrfx_common.c) @@ -56,6 +53,8 @@ zephyr_library_sources_ifdef(CONFIG_SPI_SAM spi_sam.c) zephyr_library_sources_ifdef(CONFIG_SPI_SAM0 spi_sam0.c) zephyr_library_sources_ifdef(CONFIG_SPI_SEDI spi_sedi.c) zephyr_library_sources_ifdef(CONFIG_SPI_SIFIVE spi_sifive.c) +zephyr_library_sources_ifdef(CONFIG_SPI_SILABS_EUSART spi_silabs_eusart.c) +zephyr_library_sources_ifdef(CONFIG_SPI_SILABS_USART spi_silabs_usart.c) zephyr_library_sources_ifdef(CONFIG_SPI_SMARTBOND spi_smartbond.c) zephyr_library_sources_ifdef(CONFIG_SPI_STM32 spi_ll_stm32.c) zephyr_library_sources_ifdef(CONFIG_SPI_TELINK_B91 spi_b91.c) @@ -65,3 +64,5 @@ zephyr_library_sources_ifdef(CONFIG_SPI_XEC_QMSPI_LDMA spi_xec_qmspi_ldma.c) zephyr_library_sources_ifdef(CONFIG_SPI_XLNX_AXI_QUADSPI spi_xlnx_axi_quadspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_XMC4XXX spi_xmc4xxx.c) # zephyr-keep-sorted-stop + +add_subdirectory(spi_nxp_lpspi) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 136a1fcca5615..e335051daca92 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -84,8 +84,6 @@ source "drivers/spi/Kconfig.cc13xx_cc26xx" source "drivers/spi/Kconfig.dw" source "drivers/spi/Kconfig.esp32" source "drivers/spi/Kconfig.gd32" -source "drivers/spi/Kconfig.gecko_eusart" -source "drivers/spi/Kconfig.gecko_usart" source "drivers/spi/Kconfig.grlib_spimctrl" source "drivers/spi/Kconfig.ifx_cat1" source "drivers/spi/Kconfig.it8xxx2" @@ -97,7 +95,6 @@ source "drivers/spi/Kconfig.mcux_dspi" source "drivers/spi/Kconfig.mcux_ecspi" source "drivers/spi/Kconfig.mcux_flexcomm" source "drivers/spi/Kconfig.mcux_flexio" -source "drivers/spi/Kconfig.mcux_lpspi" source "drivers/spi/Kconfig.npcx" source "drivers/spi/Kconfig.nrfx" source "drivers/spi/Kconfig.numaker" @@ -115,6 +112,8 @@ source "drivers/spi/Kconfig.sam" source "drivers/spi/Kconfig.sam0" source "drivers/spi/Kconfig.sedi" source "drivers/spi/Kconfig.sifive" +source "drivers/spi/Kconfig.silabs_eusart" +source "drivers/spi/Kconfig.silabs_usart" source "drivers/spi/Kconfig.smartbond" source "drivers/spi/Kconfig.spi_emul" source "drivers/spi/Kconfig.stm32" @@ -122,6 +121,7 @@ source "drivers/spi/Kconfig.test" source "drivers/spi/Kconfig.xec_qmspi" source "drivers/spi/Kconfig.xlnx" source "drivers/spi/Kconfig.xmc4xxx" +source "drivers/spi/spi_nxp_lpspi/Kconfig" # zephyr-keep-sorted-stop endif # SPI diff --git a/drivers/spi/Kconfig.b91 b/drivers/spi/Kconfig.b91 index 3cc63d3289c85..4192a6695e625 100644 --- a/drivers/spi/Kconfig.b91 +++ b/drivers/spi/Kconfig.b91 @@ -5,5 +5,6 @@ config SPI_TELINK_B91 bool "Telink Semiconductor B91 SPI driver" default y depends on DT_HAS_TELINK_B91_SPI_ENABLED + select PINCTRL help Enables Telink B91 SPI driver. diff --git a/drivers/spi/Kconfig.cc13xx_cc26xx b/drivers/spi/Kconfig.cc13xx_cc26xx index 58e6a6c02d9e0..cf64ee39a6398 100644 --- a/drivers/spi/Kconfig.cc13xx_cc26xx +++ b/drivers/spi/Kconfig.cc13xx_cc26xx @@ -7,5 +7,6 @@ config SPI_CC13XX_CC26XX bool "TI SimpleLink CC13xx / CC26xx SPI driver" default y depends on DT_HAS_TI_CC13XX_CC26XX_SPI_ENABLED + select PINCTRL help Enable support for the TI SimpleLink CC13xx / CC26xx SPI peripheral diff --git a/drivers/spi/Kconfig.dw b/drivers/spi/Kconfig.dw index ed45361d8eda4..88395e5a13f9a 100644 --- a/drivers/spi/Kconfig.dw +++ b/drivers/spi/Kconfig.dw @@ -5,11 +5,12 @@ # SPDX-License-Identifier: Apache-2.0 menuconfig SPI_DW - bool "Designware SPI controller driver" + bool "DesignWare SPI controller driver" default y depends on DT_HAS_SNPS_DESIGNWARE_SPI_ENABLED + select PINCTRL if $(dt_compat_any_has_prop,$(DT_COMPAT_SNPS_DESIGNWARE_SPI),pinctrl-0) help - Enable support for Designware's SPI controllers. + Enable support for DesignWare SPI controllers. if SPI_DW @@ -21,7 +22,7 @@ config SPI_DW_ACCESS_WORD_ONLY exception. config SPI_DW_HSSI - bool "Designware SPI HSSI variant" + bool "DesignWare SPI HSSI variant" help Use register layout compatible with the SPI DW HSSI variant of the peripheral. diff --git a/drivers/spi/Kconfig.gecko_eusart b/drivers/spi/Kconfig.gecko_eusart deleted file mode 100644 index 0734658d4adc7..0000000000000 --- a/drivers/spi/Kconfig.gecko_eusart +++ /dev/null @@ -1,14 +0,0 @@ -# Gecko SPI configuration option - -# Copyright (c) 2024 Daikin Comfort Technologies North America, Inc. -# SPDX-License-Identifier: Apache-2.0 - -config SPI_GECKO_EUSART - bool "Gecko EUSART SPI controller driver" - default y - depends on DT_HAS_SILABS_GECKO_SPI_EUSART_ENABLED - depends on GPIO - select SOC_GECKO_EUSART - select PINCTRL if SOC_FAMILY_SILABS_S2 - help - Enable the EUSART SPI peripherals on Gecko diff --git a/drivers/spi/Kconfig.gecko_usart b/drivers/spi/Kconfig.gecko_usart deleted file mode 100644 index cba8f4f5278a8..0000000000000 --- a/drivers/spi/Kconfig.gecko_usart +++ /dev/null @@ -1,15 +0,0 @@ -# Gecko SPI configuration option - -# Copyright (c) 2019 Christian Taedcke -# SPDX-License-Identifier: Apache-2.0 - -config SPI_GECKO_USART - bool "Gecko SPI controller driver" - default y - depends on DT_HAS_SILABS_GECKO_SPI_USART_ENABLED - depends on GPIO - select SOC_GECKO_USART - select CLOCK_CONTROL_SILABS_SERIES if SOC_FAMILY_SILABS_S2 - select PINCTRL if SOC_FAMILY_SILABS_S2 - help - Enable the SPI peripherals on Gecko diff --git a/drivers/spi/Kconfig.mcux_dspi b/drivers/spi/Kconfig.mcux_dspi index 7b99101c67207..9f76b9f7fedec 100644 --- a/drivers/spi/Kconfig.mcux_dspi +++ b/drivers/spi/Kconfig.mcux_dspi @@ -5,13 +5,13 @@ # SPDX-License-Identifier: Apache-2.0 config SPI_MCUX_DSPI - bool "MCUX SPI driver" + bool "MCUX DSPI driver" default y - depends on DT_HAS_NXP_KINETIS_DSPI_ENABLED + depends on DT_HAS_NXP_DSPI_ENABLED depends on CLOCK_CONTROL select PINCTRL help - Enable support for mcux spi driver. + Enable the MCUX DSPI driver. if SPI_MCUX_DSPI @@ -19,7 +19,7 @@ config DSPI_MCUX_EDMA bool "ENABLE EDMA for DSPI driver" depends on HAS_MCUX && HAS_MCUX_EDMA help - Enable the MCUX DSPI driver. + Enable DMA support for the MCUX DSPI driver. if DSPI_MCUX_EDMA diff --git a/drivers/spi/Kconfig.mcux_lpspi b/drivers/spi/Kconfig.mcux_lpspi deleted file mode 100644 index 20e2c4bed91d6..0000000000000 --- a/drivers/spi/Kconfig.mcux_lpspi +++ /dev/null @@ -1,36 +0,0 @@ -# MCUXpresso SDK SPI - -# Copyright (c) 2018, NXP -# SPDX-License-Identifier: Apache-2.0 - -config SPI_MCUX_LPSPI - bool "MCUX LPSPI driver" - default y - depends on DT_HAS_NXP_LPSPI_ENABLED - depends on CLOCK_CONTROL - select PINCTRL - help - Enable support for MCUX LPSPI driver. - -if SPI_MCUX_LPSPI -config SPI_MCUX_LPSPI_DMA - bool "MCUX LPSPI SPI DMA Support" - select DMA - help - Enable the SPI DMA mode for SPI instances - that enable dma channels in their device tree node. - -if SPI_RTIO -config SPI_MCUX_RTIO_SQ_SIZE - int "number of available submission queue entries" - default 8 # sensible default that covers most common spi transactions - help - when rtio is use with spi each driver holds a context with which blocking - api calls use to perform spi transactions. this queue needs to be as deep - as the longest set of spi_buf_sets used, where normal spi operations are - used (equal length buffers). it may need to be slightly deeper where the - spi buffer sets for transmit/receive are not always matched equally in - length as these are transformed into normal transceives. -endif # SPI_RTIO - -endif # SPI_MCUX_LPSPI diff --git a/drivers/spi/Kconfig.pl022 b/drivers/spi/Kconfig.pl022 index 65a0d0aedc3a8..4a0b00a74c967 100644 --- a/drivers/spi/Kconfig.pl022 +++ b/drivers/spi/Kconfig.pl022 @@ -4,7 +4,7 @@ config SPI_PL022 default y depends on DT_HAS_ARM_PL022_ENABLED - select PINCTRL if DT_HAS_RASPBERRYPI_PICO_SPI_ENABLED + select PINCTRL if $(dt_compat_any_has_prop,$(DT_COMPAT_ARM_PL022),pinctrl-0) bool "ARM PL022 SPI driver" if SPI_PL022 diff --git a/drivers/spi/Kconfig.renesas_ra b/drivers/spi/Kconfig.renesas_ra index f0e012d98ecbf..a7ae2c1d0c9e2 100644 --- a/drivers/spi/Kconfig.renesas_ra +++ b/drivers/spi/Kconfig.renesas_ra @@ -26,10 +26,10 @@ config SPI_RA_DTC Enable the SPI DTC mode for SPI instances config SPI_USE_HW_SS - bool "RA MCU SPI Hardware Slave Select support" + bool "RA MCU SPI Hardware Peripheral Select support" default y - depends on !SOC_SERIES_RA2A1 + depends on !(SOC_SERIES_RA2A1 || SOC_SERIES_RA4M1) help - Use Slave Select pin instead of software Slave Select. + Use Hardware Peripheral Select instead of Software Peripheral Select. endif # SPI_RENESAS_RA diff --git a/drivers/spi/Kconfig.silabs_eusart b/drivers/spi/Kconfig.silabs_eusart new file mode 100644 index 0000000000000..8bffdd7f9d92a --- /dev/null +++ b/drivers/spi/Kconfig.silabs_eusart @@ -0,0 +1,14 @@ +# Silabs EUSART SPI configuration option + +# Copyright (c) 2024 Daikin Comfort Technologies North America, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SPI_SILABS_EUSART + bool "Silabs EUSART SPI controller driver" + default y + depends on DT_HAS_SILABS_EUSART_SPI_ENABLED + depends on GPIO + select SOC_GECKO_EUSART + select PINCTRL if SOC_FAMILY_SILABS_S2 + help + Enable the EUSART SPI driver diff --git a/drivers/spi/Kconfig.silabs_usart b/drivers/spi/Kconfig.silabs_usart new file mode 100644 index 0000000000000..23a93a5784720 --- /dev/null +++ b/drivers/spi/Kconfig.silabs_usart @@ -0,0 +1,15 @@ +# Silabs USART SPI configuration option + +# Copyright (c) 2019 Christian Taedcke +# SPDX-License-Identifier: Apache-2.0 + +config SPI_SILABS_USART + bool "Silabs USART SPI controller driver" + default y + depends on DT_HAS_SILABS_USART_SPI_ENABLED + depends on GPIO + select SOC_GECKO_USART + select CLOCK_CONTROL_SILABS_SERIES if SOC_FAMILY_SILABS_S2 + select PINCTRL if SOC_FAMILY_SILABS_S2 + help + Enable the USART SPI driver diff --git a/drivers/spi/Kconfig.smartbond b/drivers/spi/Kconfig.smartbond index d1e91bd6654d5..bbfeac7ddd922 100644 --- a/drivers/spi/Kconfig.smartbond +++ b/drivers/spi/Kconfig.smartbond @@ -11,10 +11,9 @@ config SPI_SMARTBOND config SPI_SMARTBOND_DMA bool "Renesas Smartbond(tm) SPI with DMA acceleration" - default y depends on SPI_SMARTBOND select DMA help Enables using the DMA engine instead of interrupt-driven approach. This acceleration is available only for - asynchronous transfers. + synchronous transfers. diff --git a/drivers/spi/spi_ambiq_bleif.c b/drivers/spi/spi_ambiq_bleif.c index d25ac4ce06ce3..299920842fff8 100644 --- a/drivers/spi/spi_ambiq_bleif.c +++ b/drivers/spi/spi_ambiq_bleif.c @@ -213,7 +213,8 @@ static int spi_ambiq_init(const struct device *dev) .size = DT_INST_REG_SIZE(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .pwr_func = pwr_on_ambiq_spi_##n}; \ - DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, NULL, &spi_ambiq_data##n, &spi_ambiq_config##n, \ - POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_ambiq_driver_api); + SPI_DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, NULL, &spi_ambiq_data##n, \ + &spi_ambiq_config##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &spi_ambiq_driver_api); DT_INST_FOREACH_STATUS_OKAY(AMBIQ_SPI_BLEIF_INIT) diff --git a/drivers/spi/spi_ambiq_spic.c b/drivers/spi/spi_ambiq_spic.c index 2a728eaf4ab45..19e7bf1d14562 100644 --- a/drivers/spi/spi_ambiq_spic.c +++ b/drivers/spi/spi_ambiq_spic.c @@ -517,8 +517,8 @@ static int spi_ambiq_pm_action(const struct device *dev, enum pm_device_action a .irq_config_func = spi_irq_config_func_##n, \ .pwr_func = pwr_on_ambiq_spi_##n}; \ PM_DEVICE_DT_INST_DEFINE(n, spi_ambiq_pm_action); \ - DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, PM_DEVICE_DT_INST_GET(n), &spi_ambiq_data##n, \ - &spi_ambiq_config##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ - &spi_ambiq_driver_api); + SPI_DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, PM_DEVICE_DT_INST_GET(n), &spi_ambiq_data##n, \ + &spi_ambiq_config##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &spi_ambiq_driver_api); DT_INST_FOREACH_STATUS_OKAY(AMBIQ_SPI_INIT) diff --git a/drivers/spi/spi_ambiq_spid.c b/drivers/spi/spi_ambiq_spid.c index 30a4e54acd261..822332ac93a8b 100644 --- a/drivers/spi/spi_ambiq_spid.c +++ b/drivers/spi/spi_ambiq_spid.c @@ -423,8 +423,8 @@ static int spi_ambiq_pm_action(const struct device *dev, enum pm_device_action a .irq_config_func = spi_irq_config_func_##n, \ .pwr_func = pwr_on_ambiq_spi_##n}; \ PM_DEVICE_DT_INST_DEFINE(n, spi_ambiq_pm_action); \ - DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, PM_DEVICE_DT_INST_GET(n), &spi_ambiq_data##n, \ - &spi_ambiq_config##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ - &spi_ambiq_driver_api); + SPI_DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, PM_DEVICE_DT_INST_GET(n), &spi_ambiq_data##n, \ + &spi_ambiq_config##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &spi_ambiq_driver_api); DT_INST_FOREACH_STATUS_OKAY(AMBIQ_SPID_INIT) diff --git a/drivers/spi/spi_andes_atcspi200.c b/drivers/spi/spi_andes_atcspi200.c index 54a2350a417b0..91988cd1df272 100644 --- a/drivers/spi/spi_andes_atcspi200.c +++ b/drivers/spi/spi_andes_atcspi200.c @@ -957,7 +957,7 @@ static void spi_atcspi200_irq_handler(void *arg) .xip = SPI_ROM_CFG_XIP(DT_DRV_INST(n)), \ }; \ \ - DEVICE_DT_INST_DEFINE(n, \ + SPI_DEVICE_DT_INST_DEFINE(n, \ spi_atcspi200_init, \ NULL, \ &spi_atcspi200_dev_data_##n, \ diff --git a/drivers/spi/spi_b91.c b/drivers/spi/spi_b91.c index 7ee4d2eca67c9..eeb26b2d3c460 100644 --- a/drivers/spi/spi_b91.c +++ b/drivers/spi/spi_b91.c @@ -483,7 +483,7 @@ static DEVICE_API(spi, spi_b91_api) = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ }; \ \ - DEVICE_DT_INST_DEFINE(inst, spi_b91_init, \ + SPI_DEVICE_DT_INST_DEFINE(inst, spi_b91_init, \ NULL, \ &spi_b91_data_##inst, \ &spi_b91_cfg_##inst, \ diff --git a/drivers/spi/spi_b_renesas_ra8.c b/drivers/spi/spi_b_renesas_ra8.c index a135f7a29f395..d2fbc3a8f797d 100644 --- a/drivers/spi/spi_b_renesas_ra8.c +++ b/drivers/spi/spi_b_renesas_ra8.c @@ -766,8 +766,8 @@ static void ra_spi_eri_isr(const struct device *dev) return 0; \ } \ \ - DEVICE_DT_INST_DEFINE(index, spi_b_ra_init##index, PM_DEVICE_DT_INST_GET(index), \ - &ra_spi_data_##index, &ra_spi_config_##index, POST_KERNEL, \ - CONFIG_SPI_INIT_PRIORITY, &ra_spi_driver_api); + SPI_DEVICE_DT_INST_DEFINE(index, spi_b_ra_init##index, PM_DEVICE_DT_INST_GET(index), \ + &ra_spi_data_##index, &ra_spi_config_##index, POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, &ra_spi_driver_api); DT_INST_FOREACH_STATUS_OKAY(RA_SPI_INIT) diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 1768d303ef8a4..b860111767488 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -37,8 +37,7 @@ static int spi_bitbang_configure(const struct spi_bitbang_config *info, return -ENOTSUP; } - if (config->operation & (SPI_TRANSFER_LSB | SPI_LINES_DUAL - | SPI_LINES_QUAD)) { + if (config->operation & (SPI_LINES_DUAL | SPI_LINES_QUAD | SPI_LINES_OCTAL)) { LOG_ERR("Unsupported configuration"); return -ENOTSUP; } @@ -125,6 +124,7 @@ static int spi_bitbang_transceive(const struct device *dev, int clock_state = 0; int cpha = 0; bool loop = false; + bool lsb = false; if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) { clock_state = 1; @@ -135,6 +135,9 @@ static int spi_bitbang_transceive(const struct device *dev, if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_LOOP) { loop = true; } + if (spi_cfg->operation & SPI_TRANSFER_LSB) { + lsb = true; + } /* set the initial clock state before CS */ gpio_pin_set_dt(&info->clk_gpio, clock_state); @@ -157,8 +160,8 @@ static int spi_bitbang_transceive(const struct device *dev, } } - int shift = data->bits - 1; uint16_t r = 0; + uint8_t i = 0; int b = 0; bool do_read = false; @@ -166,7 +169,8 @@ static int spi_bitbang_transceive(const struct device *dev, do_read = true; } - while (shift >= 0) { + while (i < data->bits) { + const int shift = lsb ? i : (data->bits - 1 - i); const int d = (w >> shift) & 0x1; b = 0; @@ -198,9 +202,9 @@ static int spi_bitbang_transceive(const struct device *dev, b = d; } - r = (r << 1) | (b ? 0x1 : 0x0); + r |= (b ? 0x1 : 0x0) << shift; - --shift; + ++i; } if (spi_context_rx_buf_on(ctx)) { @@ -325,7 +329,7 @@ int spi_bitbang_init(const struct device *dev) SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), ctx) \ }; \ \ - DEVICE_DT_INST_DEFINE(inst, \ + SPI_DEVICE_DT_INST_DEFINE(inst, \ spi_bitbang_init, \ NULL, \ &spi_bitbang_data_##inst, \ diff --git a/drivers/spi/spi_cc13xx_cc26xx.c b/drivers/spi/spi_cc13xx_cc26xx.c index b5c342b81f6e1..26a4ad4007c43 100644 --- a/drivers/spi/spi_cc13xx_cc26xx.c +++ b/drivers/spi/spi_cc13xx_cc26xx.c @@ -291,7 +291,7 @@ static DEVICE_API(spi, spi_cc13xx_cc26xx_driver_api) = { #define SPI_CC13XX_CC26XX_DEVICE_INIT(n) \ PM_DEVICE_DT_INST_DEFINE(n, spi_cc13xx_cc26xx_pm_action); \ \ - DEVICE_DT_INST_DEFINE(n, \ + SPI_DEVICE_DT_INST_DEFINE(n, \ spi_cc13xx_cc26xx_init_##n, \ PM_DEVICE_DT_INST_GET(n), \ &spi_cc13xx_cc26xx_data_##n, &spi_cc13xx_cc26xx_config_##n, \ diff --git a/drivers/spi/spi_context.h b/drivers/spi/spi_context.h index a5110f52de8c6..d91efece24805 100644 --- a/drivers/spi/spi_context.h +++ b/drivers/spi/spi_context.h @@ -92,14 +92,14 @@ static inline void spi_context_lock(struct spi_context *ctx, void *callback_data, const struct spi_config *spi_cfg) { - if ((spi_cfg->operation & SPI_LOCK_ON) && - (k_sem_count_get(&ctx->lock) == 0) && - (ctx->owner == spi_cfg)) { - return; - } + bool already_locked = (spi_cfg->operation & SPI_LOCK_ON) && + (k_sem_count_get(&ctx->lock) == 0) && + (ctx->owner == spi_cfg); - k_sem_take(&ctx->lock, K_FOREVER); - ctx->owner = spi_cfg; + if (!already_locked) { + k_sem_take(&ctx->lock, K_FOREVER); + ctx->owner = spi_cfg; + } #ifdef CONFIG_SPI_ASYNC ctx->asynchronous = asynchronous; @@ -437,30 +437,51 @@ static inline size_t spi_context_longest_current_buf(struct spi_context *ctx) return ctx->tx_len > ctx->rx_len ? ctx->tx_len : ctx->rx_len; } -static inline size_t spi_context_total_tx_len(struct spi_context *ctx) +static size_t spi_context_count_tx_buf_lens(struct spi_context *ctx, size_t start_index) { size_t n; size_t total_len = 0; - for (n = 0; n < ctx->tx_count; ++n) { + for (n = start_index; n < ctx->tx_count; ++n) { total_len += ctx->current_tx[n].len; } return total_len; } -static inline size_t spi_context_total_rx_len(struct spi_context *ctx) +static size_t spi_context_count_rx_buf_lens(struct spi_context *ctx, size_t start_index) { size_t n; size_t total_len = 0; - for (n = 0; n < ctx->rx_count; ++n) { + for (n = start_index; n < ctx->rx_count; ++n) { total_len += ctx->current_rx[n].len; } return total_len; } + +static inline size_t spi_context_total_tx_len(struct spi_context *ctx) +{ + return spi_context_count_tx_buf_lens(ctx, 0); +} + +static inline size_t spi_context_total_rx_len(struct spi_context *ctx) +{ + return spi_context_count_rx_buf_lens(ctx, 0); +} + +static inline size_t spi_context_tx_len_left(struct spi_context *ctx) +{ + return ctx->tx_len + spi_context_count_tx_buf_lens(ctx, 1); +} + +static inline size_t spi_context_rx_len_left(struct spi_context *ctx) +{ + return ctx->rx_len + spi_context_count_rx_buf_lens(ctx, 1); +} + #ifdef __cplusplus } #endif diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 3a4c40ed23ad0..bb40deb1c8593 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -660,7 +660,7 @@ COND_CODE_1(IS_EQ(DT_NUM_IRQS(DT_DRV_INST(inst)), 1), \ .clear_bit_func = reg_clear_bit, \ .test_bit_func = reg_test_bit,)) \ }; \ - DEVICE_DT_INST_DEFINE(inst, \ + SPI_DEVICE_DT_INST_DEFINE(inst, \ spi_dw_init, \ NULL, \ &spi_dw_data_##inst, \ diff --git a/drivers/spi/spi_emul.c b/drivers/spi/spi_emul.c index b2214fba8d5d7..d040d4077e4c5 100644 --- a/drivers/spi/spi_emul.c +++ b/drivers/spi/spi_emul.c @@ -151,7 +151,7 @@ static DEVICE_API(spi, spi_emul_api) = { .num_children = ARRAY_SIZE(emuls_##n), \ }; \ static struct spi_emul_data spi_emul_data_##n; \ - DEVICE_DT_INST_DEFINE(n, spi_emul_init, NULL, &spi_emul_data_##n, &spi_emul_cfg_##n, \ - POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_emul_api); + SPI_DEVICE_DT_INST_DEFINE(n, spi_emul_init, NULL, &spi_emul_data_##n, &spi_emul_cfg_##n, \ + POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_emul_api); DT_INST_FOREACH_STATUS_OKAY(SPI_EMUL_INIT) diff --git a/drivers/spi/spi_esp32_spim.c b/drivers/spi/spi_esp32_spim.c index b8b7cdfea3536..8ad679b76ece9 100644 --- a/drivers/spi/spi_esp32_spim.c +++ b/drivers/spi/spi_esp32_spim.c @@ -559,7 +559,7 @@ static DEVICE_API(spi, spi_api) = { .clock_source = SPI_CLK_SRC_DEFAULT, \ }; \ \ - DEVICE_DT_INST_DEFINE(idx, spi_esp32_init, \ + SPI_DEVICE_DT_INST_DEFINE(idx, spi_esp32_init, \ NULL, &spi_data_##idx, \ &spi_config_##idx, POST_KERNEL, \ CONFIG_SPI_INIT_PRIORITY, &spi_api); diff --git a/drivers/spi/spi_gd32.c b/drivers/spi/spi_gd32.c index 46f1e76be3e87..acc29859f63fa 100644 --- a/drivers/spi/spi_gd32.c +++ b/drivers/spi/spi_gd32.c @@ -683,7 +683,7 @@ int spi_gd32_init(const struct device *dev) IF_ENABLED(CONFIG_SPI_GD32_DMA, (.dma = DMAS_DECL(idx),)) \ IF_ENABLED(CONFIG_SPI_GD32_INTERRUPT, \ (.irq_configure = spi_gd32_irq_configure_##idx)) }; \ - DEVICE_DT_INST_DEFINE(idx, spi_gd32_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(idx, spi_gd32_init, NULL, \ &spi_gd32_data_##idx, &spi_gd32_config_##idx, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &spi_gd32_driver_api); diff --git a/drivers/spi/spi_gecko_eusart.c b/drivers/spi/spi_gecko_eusart.c deleted file mode 100644 index a7be2c21dc8b5..0000000000000 --- a/drivers/spi/spi_gecko_eusart.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2024 Daikin Comfort Technologies North America, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT silabs_gecko_spi_eusart - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -LOG_MODULE_REGISTER(spi_gecko_eusart, CONFIG_SPI_LOG_LEVEL); - -#include "spi_context.h" - -#define SPI_WORD_SIZE 8 - -/* Structure Declarations */ - -struct spi_gecko_eusart_data { - struct spi_context ctx; -}; - -struct spi_gecko_eusart_config { - EUSART_TypeDef *base; - const struct device *clock_dev; - const struct silabs_clock_control_cmu_config clock_cfg; - uint32_t clock_frequency; - const struct pinctrl_dev_config *pcfg; -}; - -/* Helper Functions */ -static int spi_eusart_config(const struct device *dev, const struct spi_config *config, - uint16_t *control) -{ - struct spi_gecko_eusart_data *data = dev->data; - const struct spi_gecko_eusart_config *gecko_config = dev->config; - uint32_t spi_frequency; - - EUSART_SpiAdvancedInit_TypeDef eusartAdvancedSpiInit = EUSART_SPI_ADVANCED_INIT_DEFAULT; - EUSART_SpiInit_TypeDef eusartInit = EUSART_SPI_MASTER_INIT_DEFAULT_HF; - - int err; - - err = clock_control_get_rate(gecko_config->clock_dev, - (clock_control_subsys_t)&gecko_config->clock_cfg, - &spi_frequency); - if (err) { - return err; - } - /* Max supported SPI frequency is half the source clock */ - spi_frequency /= 2; - - if (spi_context_configured(&data->ctx, config)) { - /* Already configured. No need to do it again. */ - return 0; - } - - if (config->operation & SPI_HALF_DUPLEX) { - LOG_ERR("Half-duplex not supported"); - return -ENOTSUP; - } - - if (SPI_WORD_SIZE_GET(config->operation) != SPI_WORD_SIZE) { - LOG_ERR("Word size must be %d", SPI_WORD_SIZE); - return -ENOTSUP; - } - - if (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES) && - (config->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { - LOG_ERR("Only supports single mode"); - return -ENOTSUP; - } - - if (config->operation & SPI_TRANSFER_LSB) { - LOG_ERR("LSB first not supported"); - return -ENOTSUP; - } - - if (config->operation & SPI_OP_MODE_SLAVE) { - LOG_ERR("Slave mode not supported"); - return -ENOTSUP; - } - - /* Set frequency to the minimum of what the device supports, what the - * user has configured the controller to, and the max frequency for the - * transaction. - */ - if (gecko_config->clock_frequency > spi_frequency) { - LOG_ERR("SPI clock-frequency too high"); - return -EINVAL; - } - spi_frequency = MIN(gecko_config->clock_frequency, spi_frequency); - if (config->frequency) { - spi_frequency = MIN(config->frequency, spi_frequency); - } - eusartInit.bitRate = spi_frequency; - - if (config->operation & SPI_MODE_LOOP) { - eusartInit.loopbackEnable = eusartLoopbackEnable; - } else { - eusartInit.loopbackEnable = eusartLoopbackDisable; - } - - /* Set Clock Mode */ - if (config->operation & SPI_MODE_CPOL) { - if (config->operation & SPI_MODE_CPHA) { - eusartInit.clockMode = eusartClockMode3; - } else { - eusartInit.clockMode = eusartClockMode2; - } - } else { - if (config->operation & SPI_MODE_CPHA) { - eusartInit.clockMode = eusartClockMode1; - } else { - eusartInit.clockMode = eusartClockMode0; - } - } - - if (config->operation & SPI_CS_ACTIVE_HIGH) { - eusartAdvancedSpiInit.csPolarity = eusartCsActiveHigh; - } else { - eusartAdvancedSpiInit.csPolarity = eusartCsActiveLow; - } - - eusartInit.databits = eusartDataBits8; - eusartInit.advancedSettings = &eusartAdvancedSpiInit; - - /* Enable EUSART clock */ - err = clock_control_on(gecko_config->clock_dev, - (clock_control_subsys_t)&gecko_config->clock_cfg); - if (err < 0) { - return err; - } - - /* Initialize the EUSART */ - EUSART_SpiInit(gecko_config->base, &eusartInit); - - data->ctx.config = config; - - /* Enable the peripheral */ - gecko_config->base->CMD = (uint32_t)eusartEnable; - - return 0; -} - -static void spi_gecko_eusart_send(EUSART_TypeDef *eusart, uint8_t frame) -{ - /* Write frame to register */ - EUSART_Tx(eusart, frame); - - /* Wait until the transfer ends */ - while (!(eusart->STATUS & EUSART_STATUS_TXC)) { - } -} - -static uint8_t spi_gecko_eusart_recv(EUSART_TypeDef *eusart) -{ - /* Return data inside rx register */ - return EUSART_Rx(eusart); -} - -static bool spi_eusart_transfer_ongoing(struct spi_gecko_eusart_data *data) -{ - return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); -} - -static inline uint8_t spi_eusart_next_tx(struct spi_gecko_eusart_data *data) -{ - uint8_t tx_frame = 0; - - if (spi_context_tx_buf_on(&data->ctx)) { - tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)); - } - - return tx_frame; -} - -static int spi_eusart_shift_frames(EUSART_TypeDef *eusart, struct spi_gecko_eusart_data *data) -{ - uint8_t tx_frame; - uint8_t rx_frame; - - tx_frame = spi_eusart_next_tx(data); - spi_gecko_eusart_send(eusart, tx_frame); - spi_context_update_tx(&data->ctx, 1, 1); - - rx_frame = spi_gecko_eusart_recv(eusart); - - if (spi_context_rx_buf_on(&data->ctx)) { - UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf); - } - spi_context_update_rx(&data->ctx, 1, 1); - return 0; -} - -static void spi_gecko_eusart_xfer(const struct device *dev, const struct spi_config *config) -{ - int ret; - struct spi_gecko_eusart_data *data = dev->data; - struct spi_context *ctx = &data->ctx; - const struct spi_gecko_eusart_config *gecko_config = dev->config; - - spi_context_cs_control(ctx, true); - - do { - ret = spi_eusart_shift_frames(gecko_config->base, data); - } while (!ret && spi_eusart_transfer_ongoing(data)); - - spi_context_cs_control(ctx, false); - spi_context_complete(ctx, dev, 0); -} - -/* API Functions */ -static int spi_gecko_eusart_init(const struct device *dev) -{ - int err; - const struct spi_gecko_eusart_config *config = dev->config; - struct spi_gecko_eusart_data *data = dev->data; - - err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); - if (err < 0) { - return err; - } - - err = spi_context_cs_configure_all(&data->ctx); - if (err < 0) { - return err; - } - spi_context_unlock_unconditionally(&data->ctx); - - return 0; -} - -static int spi_gecko_eusart_transceive(const struct device *dev, const struct spi_config *config, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs) -{ - struct spi_gecko_eusart_data *data = dev->data; - uint16_t control = 0; - int ret; - - spi_context_lock(&data->ctx, false, NULL, NULL, config); - - ret = spi_eusart_config(dev, config, &control); - if (ret < 0) { - spi_context_release(&data->ctx, ret); - return ret; - } - - spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); - spi_gecko_eusart_xfer(dev, config); - - spi_context_release(&data->ctx, ret); - - return 0; -} - -#ifdef CONFIG_SPI_ASYNC -static int spi_gecko_eusart_transceive_async(const struct device *dev, - const struct spi_config *config, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) -{ - return -ENOTSUP; -} -#endif /* CONFIG_SPI_ASYNC */ - -static int spi_gecko_eusart_release(const struct device *dev, const struct spi_config *config) -{ - const struct spi_gecko_eusart_config *gecko_config = dev->config; - struct spi_gecko_eusart_data *data = dev->data; - - spi_context_unlock_unconditionally(&data->ctx); - - if (!(gecko_config->base->STATUS & EUSART_STATUS_TXIDLE)) { - return -EBUSY; - } - return 0; -} - -/* Device Instantiation */ -static DEVICE_API(spi, spi_gecko_eusart_api) = { - .transceive = spi_gecko_eusart_transceive, -#ifdef CONFIG_SPI_ASYNC - .transceive_async = spi_gecko_eusart_transceive_async, -#endif /* CONFIG_SPI_ASYNC */ - .release = spi_gecko_eusart_release, -}; - -#define SPI_INIT(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static struct spi_gecko_eusart_data spi_gecko_eusart_data_##n = { \ - SPI_CONTEXT_INIT_LOCK(spi_gecko_eusart_data_##n, ctx), \ - SPI_CONTEXT_INIT_SYNC(spi_gecko_eusart_data_##n, ctx), \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)}; \ - static struct spi_gecko_eusart_config spi_gecko_eusart_cfg_##n = { \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .base = (EUSART_TypeDef *)DT_INST_REG_ADDR(n), \ - .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ - .clock_cfg = SILABS_DT_INST_CLOCK_CFG(n), \ - .clock_frequency = DT_INST_PROP_OR(n, clock_frequency, 1000000) \ - }; \ - DEVICE_DT_INST_DEFINE(n, spi_gecko_eusart_init, NULL, &spi_gecko_eusart_data_##n, \ - &spi_gecko_eusart_cfg_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ - &spi_gecko_eusart_api); - -DT_INST_FOREACH_STATUS_OKAY(SPI_INIT) diff --git a/drivers/spi/spi_gecko_usart.c b/drivers/spi/spi_gecko_usart.c deleted file mode 100644 index 5aca11063ee91..0000000000000 --- a/drivers/spi/spi_gecko_usart.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (c) 2019 Christian Taedcke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT silabs_gecko_spi_usart - -#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL -#include -LOG_MODULE_REGISTER(spi_gecko); -#include "spi_context.h" - -#include -#include -#include -#include -#include - -#include "em_cmu.h" -#include "em_usart.h" - -#include - -#ifdef CONFIG_PINCTRL -#include -#else -#ifndef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION -#error "Individual pin location support is required" -#endif -#endif /* CONFIG_PINCTRL */ - -#ifdef CONFIG_CLOCK_CONTROL -#include -#include -#define GET_GECKO_USART_CLOCK(idx) \ - .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ - .clock_cfg = SILABS_DT_INST_CLOCK_CFG(idx), -#elif DT_NODE_HAS_PROP(n, peripheral_id) -#define CLOCK_USART(id) _CONCAT(cmuClock_USART, id) -#define GET_GECKO_USART_CLOCK(n) \ - .clock = CLOCK_USART(DT_INST_PROP(n, peripheral_id)), -#else -#if (USART_COUNT == 1) -#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ - : -1) -#elif (USART_COUNT == 2) -#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ - : ((ref) == USART1) ? cmuClock_USART1 \ - : -1) -#elif (USART_COUNT == 3) -#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ - : ((ref) == USART1) ? cmuClock_USART1 \ - : ((ref) == USART2) ? cmuClock_USART2 \ - : -1) -#elif (USART_COUNT == 4) -#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ - : ((ref) == USART1) ? cmuClock_USART1 \ - : ((ref) == USART2) ? cmuClock_USART2 \ - : ((ref) == USART3) ? cmuClock_USART3 \ - : -1) -#elif (USART_COUNT == 5) -#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ - : ((ref) == USART1) ? cmuClock_USART1 \ - : ((ref) == USART2) ? cmuClock_USART2 \ - : ((ref) == USART3) ? cmuClock_USART3 \ - : ((ref) == USART4) ? cmuClock_USART4 \ - : -1) -#elif (USART_COUNT == 6) -#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ - : ((ref) == USART1) ? cmuClock_USART1 \ - : ((ref) == USART2) ? cmuClock_USART2 \ - : ((ref) == USART3) ? cmuClock_USART3 \ - : ((ref) == USART4) ? cmuClock_USART4 \ - : ((ref) == USART5) ? cmuClock_USART5 \ - : -1) -#else -#error "Undefined number of USARTs." -#endif /* USART_COUNT */ -#define GET_GECKO_USART_CLOCK(id) \ - .clock = CLOCK_USART((USART_TypeDef *)DT_INST_REG_ADDR(id)), -#endif /* DT_NODE_HAS_PROP(n, peripheral_id) */ - - -#define SPI_WORD_SIZE 8 - -/* Structure Declarations */ - -struct spi_gecko_data { - struct spi_context ctx; -}; - -struct spi_gecko_config { - USART_TypeDef *base; -#ifdef CONFIG_CLOCK_CONTROL - const struct device *clock_dev; - const struct silabs_clock_control_cmu_config clock_cfg; -#else - CMU_Clock_TypeDef clock; -#endif - uint32_t clock_frequency; -#ifdef CONFIG_PINCTRL - const struct pinctrl_dev_config *pcfg; -#else - struct soc_gpio_pin pin_rx; - struct soc_gpio_pin pin_tx; - struct soc_gpio_pin pin_clk; - uint8_t loc_rx; - uint8_t loc_tx; - uint8_t loc_clk; -#endif /* CONFIG_PINCTRL */ -}; - - -/* Helper Functions */ -static int spi_config(const struct device *dev, - const struct spi_config *config, - uint16_t *control) -{ - const struct spi_gecko_config *gecko_config = dev->config; - struct spi_gecko_data *data = dev->data; - uint32_t spi_frequency; - -#ifdef CONFIG_CLOCK_CONTROL - int err; - - err = clock_control_get_rate(gecko_config->clock_dev, - (clock_control_subsys_t)&gecko_config->clock_cfg, - &spi_frequency); - if (err) { - return err; - } - /* Max supported SPI frequency is half the source clock */ - spi_frequency /= 2; -#else - spi_frequency = CMU_ClockFreqGet(gecko_config->clock) / 2; -#endif - - if (config->operation & SPI_HALF_DUPLEX) { - LOG_ERR("Half-duplex not supported"); - return -ENOTSUP; - } - - if (SPI_WORD_SIZE_GET(config->operation) != SPI_WORD_SIZE) { - LOG_ERR("Word size must be %d", SPI_WORD_SIZE); - return -ENOTSUP; - } - - if (config->operation & SPI_CS_ACTIVE_HIGH) { - LOG_ERR("CS active high not supported"); - return -ENOTSUP; - } - - if (config->operation & SPI_LOCK_ON) { - LOG_ERR("Lock On not supported"); - return -ENOTSUP; - } - - if (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES) && - (config->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { - LOG_ERR("Only supports single mode"); - return -ENOTSUP; - } - - if (config->operation & SPI_TRANSFER_LSB) { - LOG_ERR("LSB first not supported"); - return -ENOTSUP; - } - - if (config->operation & SPI_OP_MODE_SLAVE) { - LOG_ERR("Slave mode not supported"); - return -ENOTSUP; - } - - /* Set frequency to the minimum of what the device supports, what the - * user has configured the controller to, and the max frequency for the - * transaction. - */ - if (gecko_config->clock_frequency > spi_frequency) { - LOG_ERR("SPI clock-frequency too high"); - return -EINVAL; - } - spi_frequency = MIN(gecko_config->clock_frequency, spi_frequency); - if (config->frequency) { - spi_frequency = MIN(config->frequency, spi_frequency); - } - USART_BaudrateSyncSet(gecko_config->base, 0, spi_frequency); - - /* Set Loopback */ - if (config->operation & SPI_MODE_LOOP) { - gecko_config->base->CTRL |= USART_CTRL_LOOPBK; - } else { - gecko_config->base->CTRL &= ~USART_CTRL_LOOPBK; - } - - /* Set CPOL */ - if (config->operation & SPI_MODE_CPOL) { - gecko_config->base->CTRL |= USART_CTRL_CLKPOL; - } else { - gecko_config->base->CTRL &= ~USART_CTRL_CLKPOL; - } - - /* Set CPHA */ - if (config->operation & SPI_MODE_CPHA) { - gecko_config->base->CTRL |= USART_CTRL_CLKPHA; - } else { - gecko_config->base->CTRL &= ~USART_CTRL_CLKPHA; - } - - /* Set word size */ - gecko_config->base->FRAME = usartDatabits8 - | USART_FRAME_STOPBITS_DEFAULT - | USART_FRAME_PARITY_DEFAULT; - - /* At this point, it's mandatory to set this on the context! */ - data->ctx.config = config; - - return 0; -} - -static void spi_gecko_send(USART_TypeDef *usart, uint8_t frame) -{ - /* Write frame to register */ - USART_Tx(usart, frame); - - /* Wait until the transfer ends */ - while (!(usart->STATUS & USART_STATUS_TXC)) { - } -} - -static uint8_t spi_gecko_recv(USART_TypeDef *usart) -{ - /* Return data inside rx register */ - return (uint8_t)usart->RXDATA; -} - -static bool spi_gecko_transfer_ongoing(struct spi_gecko_data *data) -{ - return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); -} - -static inline uint8_t spi_gecko_next_tx(struct spi_gecko_data *data) -{ - uint8_t tx_frame = 0; - - if (spi_context_tx_buf_on(&data->ctx)) { - tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)); - } - - return tx_frame; -} - -static int spi_gecko_shift_frames(USART_TypeDef *usart, - struct spi_gecko_data *data) -{ - uint8_t tx_frame; - uint8_t rx_frame; - - tx_frame = spi_gecko_next_tx(data); - spi_gecko_send(usart, tx_frame); - spi_context_update_tx(&data->ctx, 1, 1); - - rx_frame = spi_gecko_recv(usart); - - if (spi_context_rx_buf_on(&data->ctx)) { - UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf); - } - spi_context_update_rx(&data->ctx, 1, 1); - return 0; -} - - -static void spi_gecko_xfer(const struct device *dev, - const struct spi_config *config) -{ - int ret; - struct spi_gecko_data *data = dev->data; - struct spi_context *ctx = &data->ctx; - const struct spi_gecko_config *gecko_config = dev->config; - - spi_context_cs_control(ctx, true); - - do { - ret = spi_gecko_shift_frames(gecko_config->base, data); - } while (!ret && spi_gecko_transfer_ongoing(data)); - - spi_context_cs_control(ctx, false); - spi_context_complete(ctx, dev, 0); -} - -#ifndef CONFIG_PINCTRL -static void spi_gecko_init_pins(const struct device *dev) -{ - const struct spi_gecko_config *config = dev->config; - - GPIO_PinModeSet(config->pin_rx.port, config->pin_rx.pin, - config->pin_rx.mode, config->pin_rx.out); - GPIO_PinModeSet(config->pin_tx.port, config->pin_tx.pin, - config->pin_tx.mode, config->pin_tx.out); - GPIO_PinModeSet(config->pin_clk.port, config->pin_clk.pin, - config->pin_clk.mode, config->pin_clk.out); - - /* disable all pins while configuring */ - config->base->ROUTEPEN = 0; - - config->base->ROUTELOC0 = - (config->loc_tx << _USART_ROUTELOC0_TXLOC_SHIFT) | - (config->loc_rx << _USART_ROUTELOC0_RXLOC_SHIFT) | - (config->loc_clk << _USART_ROUTELOC0_CLKLOC_SHIFT); - - config->base->ROUTELOC1 = _USART_ROUTELOC1_RESETVALUE; - - config->base->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN | - USART_ROUTEPEN_CLKPEN; -} -#endif /* !CONFIG_PINCTRL */ - - -/* API Functions */ - -static int spi_gecko_init(const struct device *dev) -{ - int err; - const struct spi_gecko_config *config = dev->config; - struct spi_gecko_data *data = dev->data; - USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT; - - /* The peripheral and gpio clock are already enabled from soc and gpio - * driver - */ - - usartInit.enable = usartDisable; - usartInit.baudrate = 1000000; - usartInit.databits = usartDatabits8; - usartInit.master = 1; - usartInit.msbf = 1; - usartInit.clockMode = usartClockMode0; -#if defined(USART_INPUT_RXPRS) && defined(USART_TRIGCTRL_AUTOTXTEN) - usartInit.prsRxEnable = 0; - usartInit.prsRxCh = 0; - usartInit.autoTx = 0; -#endif - - /* Enable USART clock */ -#ifdef CONFIG_CLOCK_CONTROL - err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg); - if (err < 0) { - return err; - } -#else - CMU_ClockEnable(config->clock, true); -#endif - - /* Init USART */ - USART_InitSync(config->base, &usartInit); - -#ifdef CONFIG_PINCTRL - err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); - if (err < 0) { - return err; - } -#else - /* Initialize USART pins */ - spi_gecko_init_pins(dev); -#endif /* CONFIG_PINCTRL */ - - err = spi_context_cs_configure_all(&data->ctx); - if (err < 0) { - return err; - } - - /* Enable the peripheral */ - config->base->CMD = (uint32_t) usartEnable; - - return 0; -} - -static int spi_gecko_transceive(const struct device *dev, - const struct spi_config *config, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs) -{ - struct spi_gecko_data *data = dev->data; - uint16_t control = 0; - int ret; - - ret = spi_config(dev, config, &control); - if (ret < 0) { - return ret; - } - - spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); - spi_gecko_xfer(dev, config); - return 0; -} - -#ifdef CONFIG_SPI_ASYNC -static int spi_gecko_transceive_async(const struct device *dev, - const struct spi_config *config, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs, - struct k_poll_signal *async) -{ - return -ENOTSUP; -} -#endif /* CONFIG_SPI_ASYNC */ - -static int spi_gecko_release(const struct device *dev, - const struct spi_config *config) -{ - const struct spi_gecko_config *gecko_config = dev->config; - - if (!(gecko_config->base->STATUS & USART_STATUS_TXIDLE)) { - return -EBUSY; - } - return 0; -} - -/* Device Instantiation */ -static DEVICE_API(spi, spi_gecko_api) = { - .transceive = spi_gecko_transceive, -#ifdef CONFIG_SPI_ASYNC - .transceive_async = spi_gecko_transceive_async, -#endif /* CONFIG_SPI_ASYNC */ -#ifdef CONFIG_SPI_RTIO - .iodev_submit = spi_rtio_iodev_default_submit, -#endif - .release = spi_gecko_release, -}; - -#ifdef CONFIG_PINCTRL -#define SPI_INIT(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static struct spi_gecko_data spi_gecko_data_##n = { \ - SPI_CONTEXT_INIT_LOCK(spi_gecko_data_##n, ctx), \ - SPI_CONTEXT_INIT_SYNC(spi_gecko_data_##n, ctx), \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ - }; \ - static struct spi_gecko_config spi_gecko_cfg_##n = { \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .base = (USART_TypeDef *) \ - DT_INST_REG_ADDR(n), \ - GET_GECKO_USART_CLOCK(n) \ - .clock_frequency = DT_INST_PROP_OR(n, clock_frequency, 1000000) \ - }; \ - DEVICE_DT_INST_DEFINE(n, \ - spi_gecko_init, \ - NULL, \ - &spi_gecko_data_##n, \ - &spi_gecko_cfg_##n, \ - POST_KERNEL, \ - CONFIG_SPI_INIT_PRIORITY, \ - &spi_gecko_api); -#else -#define SPI_INIT(n) \ - static struct spi_gecko_data spi_gecko_data_##n = { \ - SPI_CONTEXT_INIT_LOCK(spi_gecko_data_##n, ctx), \ - SPI_CONTEXT_INIT_SYNC(spi_gecko_data_##n, ctx), \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ - }; \ - static struct spi_gecko_config spi_gecko_cfg_##n = { \ - .base = (USART_TypeDef *) \ - DT_INST_REG_ADDR(n), \ - GET_GECKO_USART_CLOCK(n) \ - .clock_frequency = DT_INST_PROP_OR(n, clock_frequency, 1000000), \ - .pin_rx = { DT_INST_PROP_BY_IDX(n, location_rx, 1), \ - DT_INST_PROP_BY_IDX(n, location_rx, 2), \ - gpioModeInput, 1}, \ - .pin_tx = { DT_INST_PROP_BY_IDX(n, location_tx, 1), \ - DT_INST_PROP_BY_IDX(n, location_tx, 2), \ - gpioModePushPull, 1}, \ - .pin_clk = { DT_INST_PROP_BY_IDX(n, location_clk, 1), \ - DT_INST_PROP_BY_IDX(n, location_clk, 2), \ - gpioModePushPull, 1}, \ - .loc_rx = DT_INST_PROP_BY_IDX(n, location_rx, 0), \ - .loc_tx = DT_INST_PROP_BY_IDX(n, location_tx, 0), \ - .loc_clk = DT_INST_PROP_BY_IDX(n, location_clk, 0), \ - }; \ - DEVICE_DT_INST_DEFINE(n, \ - spi_gecko_init, \ - NULL, \ - &spi_gecko_data_##n, \ - &spi_gecko_cfg_##n, \ - POST_KERNEL, \ - CONFIG_SPI_INIT_PRIORITY, \ - &spi_gecko_api); -#endif /* CONFIG_PINCTRL */ - -DT_INST_FOREACH_STATUS_OKAY(SPI_INIT) diff --git a/drivers/spi/spi_grlib_spimctrl.c b/drivers/spi/spi_grlib_spimctrl.c index c43f894ecc766..463cd6b8c9225 100644 --- a/drivers/spi/spi_grlib_spimctrl.c +++ b/drivers/spi/spi_grlib_spimctrl.c @@ -236,7 +236,7 @@ static DEVICE_API(spi, api) = { SPI_CONTEXT_INIT_LOCK(data_##n, ctx), \ SPI_CONTEXT_INIT_SYNC(data_##n, ctx), \ }; \ - DEVICE_DT_INST_DEFINE(n, \ + SPI_DEVICE_DT_INST_DEFINE(n, \ init, \ NULL, \ &data_##n, \ diff --git a/drivers/spi/spi_ifx_cat1.c b/drivers/spi/spi_ifx_cat1.c index c3c825a4b8448..2a1cf0b6a8bc5 100644 --- a/drivers/spi/spi_ifx_cat1.c +++ b/drivers/spi/spi_ifx_cat1.c @@ -45,11 +45,14 @@ struct ifx_cat1_spi_data { static int32_t get_hw_block_num(CySCB_Type *reg_addr) { + extern const uint8_t _CYHAL_SCB_BASE_ADDRESS_INDEX[_SCB_ARRAY_SIZE]; + extern CySCB_Type *const _CYHAL_SCB_BASE_ADDRESSES[_SCB_ARRAY_SIZE]; + uint32_t i; for (i = 0u; i < _SCB_ARRAY_SIZE; i++) { if (_CYHAL_SCB_BASE_ADDRESSES[i] == reg_addr) { - return i; + return _CYHAL_SCB_BASE_ADDRESS_INDEX[i]; } } @@ -332,20 +335,21 @@ static int ifx_cat1_spi_init(const struct device *dev) .reg_addr = (CySCB_Type *)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .scb_spi_config = \ - {.spiMode = CY_SCB_SPI_MASTER, /* overwrite by cfg */ \ - .sclkMode = CY_SCB_SPI_CPHA0_CPOL0, /* overwrite by cfg */ \ - .rxDataWidth = 8, /* overwrite by cfg */ \ - .txDataWidth = 8, /* overwrite by cfg */ \ - .enableMsbFirst = true, /* overwrite by cfg */ \ - .subMode = CY_SCB_SPI_MOTOROLA, \ - .oversample = IFX_CAT1_SPI_DEFAULT_OVERSAMPLE, \ - .enableMisoLateSample = true, \ - .ssPolarity = CY_SCB_SPI_ACTIVE_LOW, \ - }, \ + { \ + .spiMode = CY_SCB_SPI_MASTER, /* overwrite by cfg */ \ + .sclkMode = CY_SCB_SPI_CPHA0_CPOL0, /* overwrite by cfg */ \ + .rxDataWidth = 8, /* overwrite by cfg */ \ + .txDataWidth = 8, /* overwrite by cfg */ \ + .enableMsbFirst = true, /* overwrite by cfg */ \ + .subMode = CY_SCB_SPI_MOTOROLA, \ + .oversample = IFX_CAT1_SPI_DEFAULT_OVERSAMPLE, \ + .enableMisoLateSample = true, \ + .ssPolarity = CY_SCB_SPI_ACTIVE_LOW, \ + }, \ .irq_priority = DT_INST_IRQ(n, priority), \ }; \ - DEVICE_DT_INST_DEFINE(n, ifx_cat1_spi_init, NULL, &spi_cat1_data_##n, \ - &spi_cat1_config_##n, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &ifx_cat1_spi_api); + SPI_DEVICE_DT_INST_DEFINE(n, ifx_cat1_spi_init, NULL, &spi_cat1_data_##n, \ + &spi_cat1_config_##n, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &ifx_cat1_spi_api); DT_INST_FOREACH_STATUS_OKAY(IFX_CAT1_SPI_INIT) diff --git a/drivers/spi/spi_litex.c b/drivers/spi/spi_litex.c index 6162ca8d21916..7f8c3d42f7fc0 100644 --- a/drivers/spi/spi_litex.c +++ b/drivers/spi/spi_litex.c @@ -251,7 +251,7 @@ static DEVICE_API(spi, spi_litex_api) = { .data_width = DT_INST_PROP(n, data_width), \ .max_cs = DT_INST_PROP(n, max_cs), \ }; \ - DEVICE_DT_INST_DEFINE(n, \ + SPI_DEVICE_DT_INST_DEFINE(n, \ NULL, \ NULL, \ &spi_litex_data_##n, \ diff --git a/drivers/spi/spi_litex_litespi.c b/drivers/spi/spi_litex_litespi.c index 880a59a6616d2..706426437723d 100644 --- a/drivers/spi/spi_litex_litespi.c +++ b/drivers/spi/spi_litex_litespi.c @@ -271,7 +271,7 @@ static DEVICE_API(spi, spi_litex_api) = { .phy_clk_divisor_addr = DT_INST_REG_ADDR_BY_NAME_OR(n, phy_clk_divisor, 0) \ \ }; \ - DEVICE_DT_INST_DEFINE(n, NULL, NULL, &spi_litex_data_##n, &spi_litex_cfg_##n, POST_KERNEL, \ - CONFIG_SPI_INIT_PRIORITY, &spi_litex_api); + SPI_DEVICE_DT_INST_DEFINE(n, NULL, NULL, &spi_litex_data_##n, &spi_litex_cfg_##n, \ + POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_litex_api); DT_INST_FOREACH_STATUS_OKAY(SPI_INIT) diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index a7a54d109fddf..e0184c3e52a90 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -274,23 +274,35 @@ static int spi_stm32_dma_rx_load(const struct device *dev, uint8_t *buf, return dma_start(data->dma_rx.dma_dev, data->dma_rx.channel); } -static int spi_dma_move_buffers(const struct device *dev, size_t len) +static int spi_dma_move_rx_buffers(const struct device *dev, size_t len) { struct spi_stm32_data *data = dev->data; - int ret; size_t dma_segment_len; dma_segment_len = len * data->dma_rx.dma_cfg.dest_data_size; - ret = spi_stm32_dma_rx_load(dev, data->ctx.rx_buf, dma_segment_len); + return spi_stm32_dma_rx_load(dev, data->ctx.rx_buf, dma_segment_len); +} + +static int spi_dma_move_tx_buffers(const struct device *dev, size_t len) +{ + struct spi_stm32_data *data = dev->data; + size_t dma_segment_len; + + dma_segment_len = len * data->dma_tx.dma_cfg.source_data_size; + return spi_stm32_dma_tx_load(dev, data->ctx.tx_buf, dma_segment_len); +} + +static int spi_dma_move_buffers(const struct device *dev, size_t len) +{ + int ret; + + ret = spi_dma_move_rx_buffers(dev, len); if (ret != 0) { return ret; } - dma_segment_len = len * data->dma_tx.dma_cfg.source_data_size; - ret = spi_stm32_dma_tx_load(dev, data->ctx.tx_buf, dma_segment_len); - - return ret; + return spi_dma_move_tx_buffers(dev, len); } #endif /* CONFIG_SPI_STM32_DMA */ @@ -366,11 +378,15 @@ static int spi_stm32_get_err(SPI_TypeDef *spi) static void spi_stm32_shift_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data) { - if (ll_func_rx_is_not_empty(spi)) { + uint32_t transfer_dir = LL_SPI_GetTransferDirection(spi); + + if (transfer_dir != LL_SPI_HALF_DUPLEX_TX && + ll_func_rx_is_not_empty(spi)) { spi_stm32_read_next_frame(spi, data); } - if (ll_func_tx_is_not_full(spi)) { + if (transfer_dir != LL_SPI_HALF_DUPLEX_RX && + ll_func_tx_is_not_full(spi)) { spi_stm32_send_next_frame(spi, data); } } @@ -382,17 +398,23 @@ static void spi_stm32_shift_m(const struct spi_stm32_config *cfg, if (cfg->fifo_enabled) { spi_stm32_shift_fifo(cfg->spi, data); } else { - while (!ll_func_tx_is_not_full(cfg->spi)) { - /* NOP */ - } + uint32_t transfer_dir = LL_SPI_GetTransferDirection(cfg->spi); - spi_stm32_send_next_frame(cfg->spi, data); + if (transfer_dir != LL_SPI_HALF_DUPLEX_RX) { + while (!ll_func_tx_is_not_full(cfg->spi)) { + /* NOP */ + } - while (!ll_func_rx_is_not_empty(cfg->spi)) { - /* NOP */ + spi_stm32_send_next_frame(cfg->spi, data); } - spi_stm32_read_next_frame(cfg->spi, data); + if (transfer_dir != LL_SPI_HALF_DUPLEX_TX) { + while (!ll_func_rx_is_not_empty(cfg->spi)) { + /* NOP */ + } + + spi_stm32_read_next_frame(cfg->spi, data); + } } } @@ -440,7 +462,7 @@ static void spi_stm32_shift_s(SPI_TypeDef *spi, struct spi_stm32_data *data) static int spi_stm32_shift_frames(const struct spi_stm32_config *cfg, struct spi_stm32_data *data) { - uint16_t operation = data->ctx.config->operation; + spi_operation_t operation = data->ctx.config->operation; if (SPI_OP_MODE_GET(operation) == SPI_OP_MODE_MASTER) { spi_stm32_shift_m(cfg, data); @@ -511,11 +533,15 @@ static void spi_stm32_complete(const struct device *dev, int status) } #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) + uint32_t transfer_dir = LL_SPI_GetTransferDirection(spi); + if (cfg->fifo_enabled) { LL_SPI_ClearFlag_TXTF(spi); LL_SPI_ClearFlag_OVR(spi); LL_SPI_ClearFlag_EOT(spi); LL_SPI_SetTransferSize(spi, 0); + } else if (transfer_dir == LL_SPI_HALF_DUPLEX_RX) { + LL_SPI_SetTransferSize(spi, 0); } #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ @@ -557,14 +583,31 @@ static void spi_stm32_isr(const struct device *dev) err = spi_stm32_shift_frames(cfg, data); } - if (err || !spi_stm32_transfer_ongoing(data)) { + if (err) { spi_stm32_complete(dev, err); } + + uint32_t transfer_dir = LL_SPI_GetTransferDirection(spi); + + if (transfer_dir == LL_SPI_FULL_DUPLEX) { + if (!spi_stm32_transfer_ongoing(data)) { + spi_stm32_complete(dev, err); + } + } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX) { + if (!spi_context_tx_on(&data->ctx)) { + spi_stm32_complete(dev, err); + } + } else { + if (!spi_context_rx_on(&data->ctx)) { + spi_stm32_complete(dev, err); + } + } } #endif /* CONFIG_SPI_STM32_INTERRUPT */ static int spi_stm32_configure(const struct device *dev, - const struct spi_config *config) + const struct spi_config *config, + bool write) { const struct spi_stm32_config *cfg = dev->config; struct spi_stm32_data *data = dev->data; @@ -583,7 +626,13 @@ static int spi_stm32_configure(const struct device *dev, int br; if (spi_context_configured(&data->ctx, config)) { - /* Nothing to do */ + if (config->operation & SPI_HALF_DUPLEX) { + if (write) { + LL_SPI_SetTransferDirection(spi, LL_SPI_HALF_DUPLEX_TX); + } else { + LL_SPI_SetTransferDirection(spi, LL_SPI_HALF_DUPLEX_RX); + } + } return 0; } @@ -652,7 +701,15 @@ static int spi_stm32_configure(const struct device *dev, LL_SPI_SetClockPhase(spi, LL_SPI_PHASE_1EDGE); } - LL_SPI_SetTransferDirection(spi, LL_SPI_FULL_DUPLEX); + if (config->operation & SPI_HALF_DUPLEX) { + if (write) { + LL_SPI_SetTransferDirection(spi, LL_SPI_HALF_DUPLEX_TX); + } else { + LL_SPI_SetTransferDirection(spi, LL_SPI_HALF_DUPLEX_RX); + } + } else { + LL_SPI_SetTransferDirection(spi, LL_SPI_FULL_DUPLEX); + } if (config->operation & SPI_TRANSFER_LSB) { LL_SPI_SetTransferBitOrder(spi, LL_SPI_LSB_FIRST); @@ -744,7 +801,14 @@ static int32_t spi_stm32_count_bufset_frames(const struct spi_config *config, if ((num_bytes % bytes_per_frame) != 0) { return -EINVAL; } - return num_bytes / bytes_per_frame; + + int frames = num_bytes / bytes_per_frame; + + if (frames > UINT16_MAX) { + return -EMSGSIZE; + } + + return frames; } static int32_t spi_stm32_count_total_frames(const struct spi_config *config, @@ -763,14 +827,80 @@ static int32_t spi_stm32_count_total_frames(const struct spi_config *config, return rx_frames; } - if (tx_frames > UINT16_MAX || rx_frames > UINT16_MAX) { - return -EMSGSIZE; - } - return MAX(rx_frames, tx_frames); } #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ +static int spi_stm32_half_duplex_switch_to_receive(const struct spi_stm32_config *cfg, + struct spi_stm32_data *data) +{ + SPI_TypeDef *spi = cfg->spi; + + if (!spi_context_tx_on(&data->ctx) && + spi_context_rx_on(&data->ctx)) { +#ifndef CONFIG_SPI_STM32_INTERRUPT + while (ll_func_spi_is_busy(spi)) { + /* NOP */ + } + LL_SPI_Disable(spi); +#endif /* CONFIG_SPI_STM32_INTERRUPT*/ + +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) + const struct spi_config *config = data->ctx.config; + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + int num_bytes = spi_context_total_rx_len(&data->ctx); + uint8_t bytes_per_frame = SPI_WORD_SIZE_GET(config->operation) / 8; + + if ((num_bytes % bytes_per_frame) != 0) { + return -EINVAL; + } + + LL_SPI_SetTransferSize(spi, (uint32_t) num_bytes / bytes_per_frame); + } +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ + + LL_SPI_SetTransferDirection(spi, LL_SPI_HALF_DUPLEX_RX); + + LL_SPI_Enable(spi); + +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) + /* With the STM32MP1, STM32U5 and the STM32H7, + * if the device is the SPI master, + * we need to enable the start of the transfer with + * LL_SPI_StartMasterTransfer(spi). + */ + if (LL_SPI_GetMode(spi) == LL_SPI_MODE_MASTER) { + LL_SPI_StartMasterTransfer(spi); + while (!LL_SPI_IsActiveMasterTransfer(spi)) { + /* NOP */ + } + } +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ + +#if CONFIG_SOC_SERIES_STM32H7X + /* + * Add a small delay after enabling to prevent transfer stalling at high + * system clock frequency (see errata sheet ES0392). + */ + k_busy_wait(WAIT_1US); +#endif + +#ifdef CONFIG_SPI_STM32_INTERRUPT +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) + if (cfg->fifo_enabled) { + LL_SPI_EnableIT_EOT(spi); + } +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */ + + ll_func_enable_int_errors(spi); + ll_func_enable_int_rx_not_empty(spi); +#endif /* CONFIG_SPI_STM32_INTERRUPT */ + } + + return 0; +} + static int transceive(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, @@ -798,7 +928,7 @@ static int transceive(const struct device *dev, spi_stm32_pm_policy_state_lock_get(dev); - ret = spi_stm32_configure(dev, config); + ret = spi_stm32_configure(dev, config, tx_bufs != NULL); if (ret) { goto end; } @@ -810,10 +940,23 @@ static int transceive(const struct device *dev, spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 2); } + uint32_t transfer_dir = LL_SPI_GetTransferDirection(spi); + #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) if (cfg->fifo_enabled && SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { - int total_frames = spi_stm32_count_total_frames( - config, tx_bufs, rx_bufs); + int total_frames; + + if (transfer_dir == LL_SPI_FULL_DUPLEX) { + total_frames = spi_stm32_count_total_frames( + config, tx_bufs, rx_bufs); + } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX) { + total_frames = spi_stm32_count_bufset_frames( + config, tx_bufs); + } else { + total_frames = spi_stm32_count_bufset_frames( + config, rx_bufs); + } + if (total_frames < 0) { ret = total_frames; goto end; @@ -866,10 +1009,24 @@ static int transceive(const struct device *dev, ll_func_enable_int_tx_empty(spi); - ret = spi_context_wait_for_completion(&data->ctx); + do { + ret = spi_context_wait_for_completion(&data->ctx); + + if (!ret && + transfer_dir == LL_SPI_HALF_DUPLEX_TX) { + ret = spi_stm32_half_duplex_switch_to_receive(cfg, data); + transfer_dir = LL_SPI_GetTransferDirection(spi); + } + } while (!ret && spi_stm32_transfer_ongoing(data)); #else /* CONFIG_SPI_STM32_INTERRUPT */ do { ret = spi_stm32_shift_frames(cfg, data); + + if (!ret && + transfer_dir == LL_SPI_HALF_DUPLEX_TX) { + ret = spi_stm32_half_duplex_switch_to_receive(cfg, data); + transfer_dir = LL_SPI_GetTransferDirection(spi); + } } while (!ret && spi_stm32_transfer_ongoing(data)); spi_stm32_complete(dev, ret); @@ -999,11 +1156,26 @@ static int transceive_dma(const struct device *dev, k_sem_reset(&data->status_sem); - ret = spi_stm32_configure(dev, config); + ret = spi_stm32_configure(dev, config, tx_bufs != NULL); if (ret) { goto end; } + uint32_t transfer_dir = LL_SPI_GetTransferDirection(spi); + +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) + if (transfer_dir == LL_SPI_HALF_DUPLEX_RX) { + int frames = spi_stm32_count_bufset_frames(config, rx_bufs); + + if (frames < 0) { + ret = frames; + goto end; + } + + LL_SPI_SetTransferSize(cfg->spi, frames); + } +#endif /* st_stm32h7_spi */ + /* Set buffers info */ if (SPI_WORD_SIZE_GET(config->operation) == 8) { spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); @@ -1013,11 +1185,22 @@ static int transceive_dma(const struct device *dev, #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) /* set request before enabling (else SPI CFG1 reg is write protected) */ - LL_SPI_EnableDMAReq_RX(spi); - LL_SPI_EnableDMAReq_TX(spi); + if (transfer_dir == LL_SPI_FULL_DUPLEX) { + LL_SPI_EnableDMAReq_RX(spi); + LL_SPI_EnableDMAReq_TX(spi); + } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX) { + LL_SPI_EnableDMAReq_TX(spi); + } else { + LL_SPI_EnableDMAReq_RX(spi); + } LL_SPI_Enable(spi); - if (LL_SPI_GetMode(spi) == LL_SPI_MODE_MASTER) { + + /* In half-duplex rx mode, start transfer after + * setting DMA configurations + */ + if (transfer_dir != LL_SPI_HALF_DUPLEX_RX && + LL_SPI_GetMode(spi) == LL_SPI_MODE_MASTER) { LL_SPI_StartMasterTransfer(spi); } #else @@ -1030,17 +1213,33 @@ static int transceive_dma(const struct device *dev, while (data->ctx.rx_len > 0 || data->ctx.tx_len > 0) { size_t dma_len; - if (data->ctx.rx_len == 0) { + data->status_flags = 0; + + if (transfer_dir == LL_SPI_FULL_DUPLEX) { + if (data->ctx.rx_len == 0) { + dma_len = data->ctx.tx_len; + } else if (data->ctx.tx_len == 0) { + dma_len = data->ctx.rx_len; + } else { + dma_len = MIN(data->ctx.tx_len, data->ctx.rx_len); + } + + ret = spi_dma_move_buffers(dev, dma_len); + } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX) { dma_len = data->ctx.tx_len; - } else if (data->ctx.tx_len == 0) { - dma_len = data->ctx.rx_len; + ret = spi_dma_move_tx_buffers(dev, dma_len); } else { - dma_len = MIN(data->ctx.tx_len, data->ctx.rx_len); + dma_len = data->ctx.rx_len; + ret = spi_dma_move_rx_buffers(dev, dma_len); } - data->status_flags = 0; +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) + if (transfer_dir == LL_SPI_HALF_DUPLEX_RX && + LL_SPI_GetMode(spi) == LL_SPI_MODE_MASTER) { + LL_SPI_StartMasterTransfer(spi); + } +#endif /* st_stm32h7_spi */ - ret = spi_dma_move_buffers(dev, dma_len); if (ret != 0) { break; } @@ -1048,8 +1247,14 @@ static int transceive_dma(const struct device *dev, #if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) /* toggle the DMA request to restart the transfer */ - LL_SPI_EnableDMAReq_RX(spi); - LL_SPI_EnableDMAReq_TX(spi); + if (transfer_dir == LL_SPI_FULL_DUPLEX) { + LL_SPI_EnableDMAReq_RX(spi); + LL_SPI_EnableDMAReq_TX(spi); + } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX) { + LL_SPI_EnableDMAReq_TX(spi); + } else { + LL_SPI_EnableDMAReq_RX(spi); + } #endif /* ! st_stm32h7_spi */ ret = wait_dma_rx_tx_done(dev); @@ -1081,8 +1286,38 @@ static int transceive_dma(const struct device *dev, uint8_t frame_size_bytes = bits2bytes( SPI_WORD_SIZE_GET(config->operation)); - spi_context_update_tx(&data->ctx, frame_size_bytes, dma_len); - spi_context_update_rx(&data->ctx, frame_size_bytes, dma_len); + if (transfer_dir == LL_SPI_FULL_DUPLEX) { + spi_context_update_tx(&data->ctx, frame_size_bytes, dma_len); + spi_context_update_rx(&data->ctx, frame_size_bytes, dma_len); + } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX) { + spi_context_update_tx(&data->ctx, frame_size_bytes, dma_len); + } else { + spi_context_update_rx(&data->ctx, frame_size_bytes, dma_len); + } + + if (transfer_dir == LL_SPI_HALF_DUPLEX_TX && + !spi_context_tx_on(&data->ctx) && + spi_context_rx_on(&data->ctx)) { + LL_SPI_Disable(spi); + LL_SPI_SetTransferDirection(spi, LL_SPI_HALF_DUPLEX_RX); + + transfer_dir = LL_SPI_HALF_DUPLEX_RX; + +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) + int frames = spi_stm32_count_bufset_frames(config, rx_bufs); + + if (frames < 0) { + ret = frames; + break; + } + + LL_SPI_SetTransferSize(cfg->spi, frames); + + LL_SPI_EnableDMAReq_RX(spi); +#endif /* st_stm32h7_spi */ + + LL_SPI_Enable(spi); + } } /* spi complete relies on SPI Status Reg which cannot be disabled */ @@ -1396,7 +1631,7 @@ static struct spi_stm32_data spi_stm32_dev_data_##id = { \ \ PM_DEVICE_DT_INST_DEFINE(id, spi_stm32_pm_action); \ \ -DEVICE_DT_INST_DEFINE(id, spi_stm32_init, PM_DEVICE_DT_INST_GET(id), \ +SPI_DEVICE_DT_INST_DEFINE(id, spi_stm32_init, PM_DEVICE_DT_INST_GET(id),\ &spi_stm32_dev_data_##id, &spi_stm32_cfg_##id, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &api_funcs); \ diff --git a/drivers/spi/spi_max32.c b/drivers/spi/spi_max32.c index c2aaee303bcb9..1c2d66ede12d1 100644 --- a/drivers/spi/spi_max32.c +++ b/drivers/spi/spi_max32.c @@ -539,6 +539,8 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con spi_context_lock(ctx, async, cb, userdata, config); + MXC_SPI_ClearTXFIFO(spi); + ret = dma_get_status(cfg->tx_dma.dev, cfg->tx_dma.channel, &status); if (ret < 0 || status.busy) { ret = ret < 0 ? ret : -EBUSY; @@ -568,13 +570,13 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con /* Assert the CS line if HW control disabled */ if (!hw_cs_ctrl) { spi_context_cs_control(ctx, true); + } else { + spi->ctrl0 = (spi->ctrl0 & ~MXC_F_SPI_CTRL0_START) | MXC_F_SPI_CTRL0_SS_CTRL; } MXC_SPI_SetSlave(cfg->regs, ctx->config->slave); do { - spi->ctrl0 &= ~(MXC_F_SPI_CTRL0_EN); - len = spi_context_max_continuous_chunk(ctx); dfs_shift = spi_max32_get_dfs_shift(ctx); word_count = len >> dfs_shift; @@ -603,17 +605,24 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con goto unlock; } - spi->ctrl0 |= MXC_F_SPI_CTRL0_EN; - data->dma_stat = 0; MXC_SPI_StartTransmission(spi); ret = spi_context_wait_for_completion(ctx); } while (!ret && (spi_context_tx_on(ctx) || spi_context_rx_on(ctx))); + if (ret < 0) { + dma_stop(cfg->tx_dma.dev, cfg->tx_dma.channel); + dma_stop(cfg->rx_dma.dev, cfg->rx_dma.channel); + } + unlock: /* Deassert the CS line if hw control disabled */ if (!hw_cs_ctrl) { spi_context_cs_control(ctx, false); + } else { + spi->ctrl0 &= + ~(MXC_F_SPI_CTRL0_START | MXC_F_SPI_CTRL0_SS_CTRL | MXC_F_SPI_CTRL0_EN); + spi->ctrl0 |= MXC_F_SPI_CTRL0_EN; } spi_context_release(ctx, ret); @@ -965,7 +974,7 @@ static DEVICE_API(spi, spi_max32_api) = { SPI_CONTEXT_INIT_SYNC(max32_spi_data_##_num, ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(_num), ctx) \ IF_ENABLED(CONFIG_SPI_RTIO, (.rtio_ctx = &max32_spi_rtio_##_num))}; \ - DEVICE_DT_INST_DEFINE(_num, spi_max32_init, NULL, &max32_spi_data_##_num, \ + SPI_DEVICE_DT_INST_DEFINE(_num, spi_max32_init, NULL, &max32_spi_data_##_num, \ &max32_spi_config_##_num, PRE_KERNEL_2, CONFIG_SPI_INIT_PRIORITY, \ &spi_max32_api); diff --git a/drivers/spi/spi_mchp_mss.c b/drivers/spi/spi_mchp_mss.c index 94b216961e75c..e1138cfb86f88 100644 --- a/drivers/spi/spi_mchp_mss.c +++ b/drivers/spi/spi_mchp_mss.c @@ -477,8 +477,8 @@ static DEVICE_API(spi, mss_spi_driver_api) = { SPI_CONTEXT_INIT_SYNC(mss_spi_data_##n, ctx), \ }; \ \ - DEVICE_DT_INST_DEFINE(n, mss_spi_init_##n, NULL, &mss_spi_data_##n, &mss_spi_config_##n, \ - POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ - &mss_spi_driver_api); + SPI_DEVICE_DT_INST_DEFINE(n, mss_spi_init_##n, NULL, &mss_spi_data_##n, \ + &mss_spi_config_##n, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &mss_spi_driver_api); DT_INST_FOREACH_STATUS_OKAY(MSS_SPI_INIT) diff --git a/drivers/spi/spi_mchp_mss_qspi.c b/drivers/spi/spi_mchp_mss_qspi.c index f902af6e8dcb2..dc822da978fe3 100644 --- a/drivers/spi/spi_mchp_mss_qspi.c +++ b/drivers/spi/spi_mchp_mss_qspi.c @@ -580,33 +580,29 @@ static DEVICE_API(spi, mss_qspi_driver_api) = { .release = mss_qspi_release, }; -#define MSS_QSPI_INIT(n) \ - static void mss_qspi_config_func_##n(const struct device *dev); \ - \ - static const struct mss_qspi_config mss_qspi_config_##n = { \ - .base = DT_INST_REG_ADDR(n), \ - .irq_config_func = mss_qspi_config_func_##n, \ - .clock_freq = DT_INST_PROP(n, clock_frequency), \ - }; \ - \ - static struct mss_qspi_data mss_qspi_data_##n = { \ - SPI_CONTEXT_INIT_LOCK(mss_qspi_data_##n, ctx), \ - SPI_CONTEXT_INIT_SYNC(mss_qspi_data_##n, ctx), \ - }; \ - \ - DEVICE_DT_INST_DEFINE(n, mss_qspi_init, \ - NULL, \ - &mss_qspi_data_##n, \ - &mss_qspi_config_##n, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ - &mss_qspi_driver_api); \ - \ - static void mss_qspi_config_func_##n(const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ - mss_qspi_interrupt, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQN(n)); \ +#define MSS_QSPI_INIT(n) \ + static void mss_qspi_config_func_##n(const struct device *dev); \ + \ + static const struct mss_qspi_config mss_qspi_config_##n = { \ + .base = DT_INST_REG_ADDR(n), \ + .irq_config_func = mss_qspi_config_func_##n, \ + .clock_freq = DT_INST_PROP(n, clock_frequency), \ + }; \ + \ + static struct mss_qspi_data mss_qspi_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(mss_qspi_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(mss_qspi_data_##n, ctx), \ + }; \ + \ + SPI_DEVICE_DT_INST_DEFINE(n, mss_qspi_init, NULL, &mss_qspi_data_##n, \ + &mss_qspi_config_##n, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &mss_qspi_driver_api); \ + \ + static void mss_qspi_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), mss_qspi_interrupt, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ } DT_INST_FOREACH_STATUS_OKAY(MSS_QSPI_INIT) diff --git a/drivers/spi/spi_mcux_dspi.c b/drivers/spi/spi_mcux_dspi.c index 32ebe274d3727..0ab47811f1cb7 100644 --- a/drivers/spi/spi_mcux_dspi.c +++ b/drivers/spi/spi_mcux_dspi.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nxp_kinetis_dspi +#define DT_DRV_COMPAT nxp_dspi #include #include @@ -906,23 +906,23 @@ static DEVICE_API(spi, spi_mcux_driver_api) = { DT_INST_PROP_OR(id, ctar, 0), \ .samplePoint = \ DT_INST_PROP_OR(id, sample_point, 0), \ - .enable_continuous_sck = \ + .enable_continuous_sck = \ DT_INST_PROP(id, continuous_sck), \ .enable_rxfifo_overwrite = \ DT_INST_PROP(id, rx_fifo_overwrite), \ - .enable_modified_timing_format = \ + .enable_modified_timing_format = \ DT_INST_PROP(id, modified_timing_format), \ .is_dma_chn_shared = \ DT_INST_PROP(id, nxp_rx_tx_chn_share), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \ }; \ - DEVICE_DT_INST_DEFINE(id, \ + SPI_DEVICE_DT_INST_DEFINE(id, \ spi_mcux_init, \ NULL, \ &spi_mcux_data_##id, \ &spi_mcux_config_##id, \ POST_KERNEL, \ - CONFIG_SPI_INIT_PRIORITY, \ + CONFIG_SPI_INIT_PRIORITY, \ &spi_mcux_driver_api); \ static void spi_mcux_config_func_##id(const struct device *dev) \ { \ diff --git a/drivers/spi/spi_mcux_ecspi.c b/drivers/spi/spi_mcux_ecspi.c index 0d98ba9f5a979..8138e7fdc2a7e 100644 --- a/drivers/spi/spi_mcux_ecspi.c +++ b/drivers/spi/spi_mcux_ecspi.c @@ -93,7 +93,8 @@ static void spi_mcux_transfer_next_packet(const struct device *dev) transfer.txData = NULL; } - transfer.dataSize = data->dfs; + /* Burst length is set in the configure step */ + transfer.dataSize = 1; status = ECSPI_MasterTransferNonBlocking(base, &data->handle, &transfer); if (status != kStatus_Success) { @@ -163,7 +164,7 @@ static int spi_mcux_configure(const struct device *dev, return -ENOTSUP; } - if (spi_cfg->slave > kECSPI_Channel3) { + if (!spi_cs_is_gpio(spi_cfg) && spi_cfg->slave > kECSPI_Channel3) { LOG_ERR("Slave %d is greater than %d", spi_cfg->slave, kECSPI_Channel3); return -EINVAL; } @@ -181,7 +182,8 @@ static int spi_mcux_configure(const struct device *dev, ECSPI_MasterGetDefaultConfig(&master_config); - master_config.channel = (ecspi_channel_source_t)spi_cfg->slave; + master_config.channel = + spi_cs_is_gpio(spi_cfg) ? kECSPI_Channel0 : (ecspi_channel_source_t)spi_cfg->slave; master_config.channelConfig.polarity = (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) ? kECSPI_PolarityActiveLow @@ -331,7 +333,7 @@ static DEVICE_API(spi, spi_mcux_driver_api) = { SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ }; \ \ - DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, \ &spi_mcux_data_##n, &spi_mcux_config_##n, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &spi_mcux_driver_api); \ diff --git a/drivers/spi/spi_mcux_flexcomm.c b/drivers/spi/spi_mcux_flexcomm.c index 1699fbf2feb3e..258fe320393de 100644 --- a/drivers/spi/spi_mcux_flexcomm.c +++ b/drivers/spi/spi_mcux_flexcomm.c @@ -901,7 +901,7 @@ static void spi_mcux_config_func_##id(const struct device *dev) \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(id), ctx) \ SPI_DMA_CHANNELS(id) \ }; \ - DEVICE_DT_INST_DEFINE(id, \ + SPI_DEVICE_DT_INST_DEFINE(id, \ spi_mcux_init, \ NULL, \ &spi_mcux_data_##id, \ diff --git a/drivers/spi/spi_mcux_flexio.c b/drivers/spi/spi_mcux_flexio.c index 96c01624ba195..56a2c19fbf161 100644 --- a/drivers/spi/spi_mcux_flexio.c +++ b/drivers/spi/spi_mcux_flexio.c @@ -439,7 +439,7 @@ static DEVICE_API(spi, spi_mcux_driver_api) = { SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ }; \ \ - DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, \ &spi_mcux_flexio_data_##n, \ &spi_mcux_flexio_config_##n, POST_KERNEL, \ CONFIG_SPI_INIT_PRIORITY, \ diff --git a/drivers/spi/spi_mcux_lpspi.c b/drivers/spi/spi_mcux_lpspi.c deleted file mode 100644 index b98a5fca8b8c7..0000000000000 --- a/drivers/spi/spi_mcux_lpspi.c +++ /dev/null @@ -1,856 +0,0 @@ -/* - * Copyright 2018, 2024 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT nxp_lpspi - -#include -#include -#include -#include - -#include -LOG_MODULE_REGISTER(spi_mcux_lpspi, CONFIG_SPI_LOG_LEVEL); - -#ifdef CONFIG_SPI_RTIO -#include -#endif - -#include "spi_context.h" - -#if CONFIG_NXP_LP_FLEXCOMM -#include -#endif - -#include - -/* If any hardware revisions change this, make it into a DT property. - * DONT'T make #ifdefs here by platform. - */ -#define CHIP_SELECT_COUNT 4 -#define MAX_DATA_WIDTH 4096 - -/* Required by DEVICE_MMIO_NAMED_* macros */ -#define DEV_CFG(_dev) ((const struct spi_mcux_config *)(_dev)->config) -#define DEV_DATA(_dev) ((struct spi_mcux_data *)(_dev)->data) - -/* Argument to MCUX SDK IRQ handler */ -#define LPSPI_IRQ_HANDLE_ARG COND_CODE_1(CONFIG_NXP_LP_FLEXCOMM, (LPSPI_GetInstance(base)), (base)) - -/* flag for SDK API for master transfers */ -#define LPSPI_MASTER_XFER_CFG_FLAGS(slave) \ - kLPSPI_MasterPcsContinuous | (slave << LPSPI_MASTER_PCS_SHIFT) - -#ifdef CONFIG_SPI_MCUX_LPSPI_DMA -#include - -/* These flags are arbitrary */ -#define LPSPI_DMA_ERROR_FLAG BIT(0) -#define LPSPI_DMA_RX_DONE_FLAG BIT(1) -#define LPSPI_DMA_TX_DONE_FLAG BIT(2) -#define LPSPI_DMA_DONE_FLAG (LPSPI_DMA_RX_DONE_FLAG | LPSPI_DMA_TX_DONE_FLAG) - -struct spi_dma_stream { - const struct device *dma_dev; - uint32_t channel; /* stores the channel for dma */ - struct dma_config dma_cfg; - struct dma_block_config dma_blk_cfg; -}; -#endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ - -struct spi_mcux_config { - DEVICE_MMIO_NAMED_ROM(reg_base); - const struct device *clock_dev; - clock_control_subsys_t clock_subsys; - void (*irq_config_func)(const struct device *dev); - uint32_t pcs_sck_delay; - uint32_t sck_pcs_delay; - uint32_t transfer_delay; - const struct pinctrl_dev_config *pincfg; - lpspi_pin_config_t data_pin_config; -}; - -struct spi_mcux_data { - DEVICE_MMIO_NAMED_RAM(reg_base); - const struct device *dev; - lpspi_master_handle_t handle; - struct spi_context ctx; - size_t transfer_len; -#ifdef CONFIG_SPI_RTIO - struct spi_rtio *rtio_ctx; -#endif -#ifdef CONFIG_SPI_MCUX_LPSPI_DMA - volatile uint32_t status_flags; - struct spi_dma_stream dma_rx; - struct spi_dma_stream dma_tx; - /* dummy value used for transferring NOP when tx buf is null */ - uint32_t dummy_buffer; -#endif -}; - -static int spi_mcux_transfer_next_packet(const struct device *dev); -#ifdef CONFIG_SPI_RTIO -static void spi_mcux_iodev_complete(const struct device *dev, int status); -#endif - -static void spi_mcux_isr(const struct device *dev) -{ - struct spi_mcux_data *data = dev->data; - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - - LPSPI_MasterTransferHandleIRQ(LPSPI_IRQ_HANDLE_ARG, &data->handle); -} - -static void spi_mcux_master_callback(LPSPI_Type *base, lpspi_master_handle_t *handle, - status_t status, void *userData) -{ - struct spi_mcux_data *data = userData; - -#ifdef CONFIG_SPI_RTIO - struct spi_rtio *rtio_ctx = data->rtio_ctx; - - if (rtio_ctx->txn_head != NULL) { - spi_mcux_iodev_complete(data->dev, status); - return; - } -#endif - spi_context_update_tx(&data->ctx, 1, data->transfer_len); - spi_context_update_rx(&data->ctx, 1, data->transfer_len); - - spi_mcux_transfer_next_packet(data->dev); -} - -static int spi_mcux_transfer_next_packet(const struct device *dev) -{ - struct spi_mcux_data *data = dev->data; - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_context *ctx = &data->ctx; - size_t max_chunk = spi_context_max_continuous_chunk(ctx); - lpspi_transfer_t transfer; - status_t status; - - if (max_chunk == 0) { - spi_context_cs_control(ctx, false); - spi_context_complete(ctx, dev, 0); - return 0; - } - - data->transfer_len = max_chunk; - - transfer.configFlags = LPSPI_MASTER_XFER_CFG_FLAGS(ctx->config->slave); - transfer.txData = (ctx->tx_len == 0 ? NULL : ctx->tx_buf); - transfer.rxData = (ctx->rx_len == 0 ? NULL : ctx->rx_buf); - transfer.dataSize = max_chunk; - - status = LPSPI_MasterTransferNonBlocking(base, &data->handle, &transfer); - if (status != kStatus_Success) { - LOG_ERR("Transfer could not start on %s: %d", dev->name, status); - return status == kStatus_LPSPI_Busy ? -EBUSY : -EINVAL; - } - - return 0; -} - -static int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cfg) -{ - const struct spi_mcux_config *config = dev->config; - struct spi_mcux_data *data = dev->data; - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - uint32_t word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); - lpspi_master_config_t master_config; - uint32_t clock_freq; - - if (spi_cfg->operation & SPI_HALF_DUPLEX) { - LOG_ERR("Half-duplex not supported"); - return -ENOTSUP; - } - - if (spi_cfg->slave > CHIP_SELECT_COUNT) { - LOG_ERR("Slave %d is greater than %d", spi_cfg->slave, CHIP_SELECT_COUNT); - return -EINVAL; - } - - if (word_size > MAX_DATA_WIDTH) { - LOG_ERR("Word size %d is greater than %d", word_size, MAX_DATA_WIDTH); - return -EINVAL; - } - - if (!device_is_ready(config->clock_dev)) { - LOG_ERR("clock control device not ready"); - return -ENODEV; - } - - if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_freq)) { - return -EINVAL; - } - - if (data->ctx.config != NULL) { - /* Setting the baud rate in LPSPI_MasterInit requires module to be disabled. Only - * disable if already configured, otherwise the clock is not enabled and the - * CR register cannot be written. - */ - LPSPI_Enable(base, false); - while ((base->CR & LPSPI_CR_MEN_MASK) != 0U) { - /* Wait until LPSPI is disabled. Datasheet: - * After writing 0, MEN (Module Enable) remains set until the LPSPI has - * completed the current transfer and is idle. - */ - } - } - - if (IS_ENABLED(CONFIG_DEBUG)) { - base->CR |= LPSPI_CR_DBGEN_MASK; - } - - data->ctx.config = spi_cfg; - - LPSPI_MasterGetDefaultConfig(&master_config); - - master_config.bitsPerFrame = word_size; - master_config.cpol = (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) - ? kLPSPI_ClockPolarityActiveLow - : kLPSPI_ClockPolarityActiveHigh; - master_config.cpha = (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) - ? kLPSPI_ClockPhaseSecondEdge - : kLPSPI_ClockPhaseFirstEdge; - master_config.direction = - (spi_cfg->operation & SPI_TRANSFER_LSB) ? kLPSPI_LsbFirst : kLPSPI_MsbFirst; - master_config.baudRate = spi_cfg->frequency; - master_config.pcsToSckDelayInNanoSec = config->pcs_sck_delay; - master_config.lastSckToPcsDelayInNanoSec = config->sck_pcs_delay; - master_config.betweenTransferDelayInNanoSec = config->transfer_delay; - master_config.pinCfg = config->data_pin_config; - - LPSPI_MasterInit(base, &master_config, clock_freq); - LPSPI_MasterTransferCreateHandle(base, &data->handle, spi_mcux_master_callback, data); - LPSPI_SetDummyData(base, 0); - - return 0; -} - -#ifdef CONFIG_SPI_MCUX_LPSPI_DMA -static bool lpspi_inst_has_dma(const struct spi_mcux_data *data) -{ - return (data->dma_tx.dma_dev && data->dma_rx.dma_dev); -} - -/* This function is executed in the interrupt context */ -static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t channel, int status) -{ - /* arg directly holds the spi device */ - const struct device *spi_dev = arg; - struct spi_mcux_data *data = (struct spi_mcux_data *)spi_dev->data; - char debug_char; - - if (status < 0) { - goto error; - } - - /* identify the origin of this callback */ - if (channel == data->dma_tx.channel) { - /* this part of the transfer ends */ - data->status_flags |= LPSPI_DMA_TX_DONE_FLAG; - debug_char = 'T'; - } else if (channel == data->dma_rx.channel) { - /* this part of the transfer ends */ - data->status_flags |= LPSPI_DMA_RX_DONE_FLAG; - debug_char = 'R'; - } else { - goto error; - } - - LOG_DBG("DMA %cX Block Complete", debug_char); - -#if CONFIG_SPI_ASYNC - if (data->ctx.asynchronous && (data->status_flags & LPSPI_DMA_DONE_FLAG)) { - /* Load dma blocks of equal length */ - size_t dma_size = spi_context_max_continuous_chunk(data->ctx); - - if (dma_size != 0) { - return; - } - - spi_context_update_tx(&data->ctx, 1, dma_size); - spi_context_update_rx(&data->ctx, 1, dma_size); - } -#endif - - goto done; -error: - LOG_ERR("DMA callback error with channel %d.", channel); - data->status_flags |= LPSPI_DMA_ERROR_FLAG; -done: - spi_context_complete(&data->ctx, spi_dev, 0); -} - -static struct dma_block_config *spi_mcux_dma_common_load(struct spi_dma_stream *stream, - const struct device *dev, - const uint8_t *buf, size_t len) -{ - struct spi_mcux_data *data = dev->data; - struct dma_block_config *blk_cfg = &stream->dma_blk_cfg; - - /* prepare the block for this TX DMA channel */ - memset(blk_cfg, 0, sizeof(struct dma_block_config)); - - blk_cfg->block_size = len; - - if (buf == NULL) { - blk_cfg->source_address = (uint32_t)&data->dummy_buffer; - blk_cfg->dest_address = (uint32_t)&data->dummy_buffer; - /* pretend it is peripheral xfer so DMA just xfer to dummy buf */ - stream->dma_cfg.channel_direction = PERIPHERAL_TO_PERIPHERAL; - } else { - blk_cfg->source_address = (uint32_t)buf; - blk_cfg->dest_address = (uint32_t)buf; - } - - /* Transfer 1 byte each DMA loop */ - stream->dma_cfg.source_burst_length = 1; - stream->dma_cfg.user_data = (void *)dev; - stream->dma_cfg.head_block = blk_cfg; - - return blk_cfg; -} - -static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, size_t len) -{ - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; - /* remember active TX DMA channel (used in callback) */ - struct spi_dma_stream *stream = &data->dma_tx; - struct dma_block_config *blk_cfg = spi_mcux_dma_common_load(stream, dev, buf, len); - - if (buf != NULL) { - /* tx direction has memory as source and periph as dest. */ - stream->dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; - } - - /* Dest is LPSPI tx fifo */ - blk_cfg->dest_address = LPSPI_GetTxRegisterAddress(base); - - /* give the client dev as arg, as the callback comes from the dma */ - /* pass our client origin to the dma: data->dma_tx.dma_channel */ - return dma_config(stream->dma_dev, stream->channel, &stream->dma_cfg); -} - -static int spi_mcux_dma_rx_load(const struct device *dev, uint8_t *buf, size_t len) -{ - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; - /* retrieve active RX DMA channel (used in callback) */ - struct spi_dma_stream *stream = &data->dma_rx; - struct dma_block_config *blk_cfg = spi_mcux_dma_common_load(stream, dev, buf, len); - - if (buf != NULL) { - /* rx direction has periph as source and mem as dest. */ - stream->dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; - } - - /* Source is LPSPI rx fifo */ - blk_cfg->source_address = LPSPI_GetRxRegisterAddress(base); - - /* pass our client origin to the dma: data->dma_rx.channel */ - return dma_config(stream->dma_dev, stream->channel, &stream->dma_cfg); -} - -static int wait_dma_rx_tx_done(const struct device *dev) -{ - struct spi_mcux_data *data = dev->data; - int ret; - - do { - ret = spi_context_wait_for_completion(&data->ctx); - if (ret) { - LOG_DBG("Timed out waiting for SPI context to complete"); - return ret; - } else if (data->status_flags & LPSPI_DMA_ERROR_FLAG) { - return -EIO; - } - } while (!((data->status_flags & LPSPI_DMA_DONE_FLAG) == LPSPI_DMA_DONE_FLAG)); - - LOG_DBG("DMA block completed"); - return 0; -} - -static inline int spi_mcux_dma_rxtx_load(const struct device *dev, size_t *dma_size) -{ - struct spi_mcux_data *data = dev->data; - struct spi_context *ctx = &data->ctx; - int ret = 0; - - /* Clear status flags */ - data->status_flags = 0U; - - /* Load dma blocks of equal length */ - *dma_size = spi_context_max_continuous_chunk(ctx); - - ret = spi_mcux_dma_tx_load(dev, ctx->tx_buf, *dma_size); - if (ret != 0) { - return ret; - } - - ret = spi_mcux_dma_rx_load(dev, ctx->rx_buf, *dma_size); - if (ret != 0) { - return ret; - } - - /* Start DMA */ - ret = dma_start(data->dma_tx.dma_dev, data->dma_tx.channel); - if (ret != 0) { - return ret; - } - - ret = dma_start(data->dma_rx.dma_dev, data->dma_rx.channel); - return ret; -} - -#ifdef CONFIG_SPI_ASYNC -static int transceive_dma_async(const struct device *dev, spi_callback_t cb, void *userdata) -{ - struct spi_mcux_data *data = dev->data; - struct spi_context *ctx = &data->ctx; - size_t dma_size; - int ret; - - ctx->asynchronous = true; - ctx->callback = cb; - ctx->callback_data = userdata; - - ret = spi_mcux_dma_rxtx_load(dev, &dma_size); - if (ret) { - return ret; - } - - /* Enable DMA Requests */ - LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); - - return 0; -} -#else -#define transceive_dma_async(...) 0 -#endif /* CONFIG_SPI_ASYNC */ - -static int transceive_dma_sync(const struct device *dev) -{ - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; - struct spi_context *ctx = &data->ctx; - size_t dma_size; - int ret; - - spi_context_cs_control(ctx, true); - - /* Send each spi buf via DMA, updating context as DMA completes */ - while (ctx->rx_len > 0 || ctx->tx_len > 0) { - /* Load dma block */ - ret = spi_mcux_dma_rxtx_load(dev, &dma_size); - if (ret) { - return ret; - } - -#ifdef CONFIG_SOC_SERIES_MCXN - while (!(LPSPI_GetStatusFlags(base) & kLPSPI_TxDataRequestFlag)) { - /* wait until previous tx finished */ - } -#endif - - /* Enable DMA Requests */ - LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); - - /* Wait for DMA to finish */ - ret = wait_dma_rx_tx_done(dev); - if (ret) { - return ret; - } - -#ifndef CONFIG_SOC_SERIES_MCXN - while ((LPSPI_GetStatusFlags(base) & kLPSPI_ModuleBusyFlag)) { - /* wait until module is idle */ - } -#endif - - /* Disable DMA */ - LPSPI_DisableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); - - /* Update SPI contexts with amount of data we just sent */ - spi_context_update_tx(ctx, 1, dma_size); - spi_context_update_rx(ctx, 1, dma_size); - } - - spi_context_cs_control(ctx, false); - - base->TCR = 0; - - return 0; -} - -static int transceive_dma(const struct device *dev, const struct spi_config *spi_cfg, - const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - bool asynchronous, spi_callback_t cb, void *userdata) -{ - struct spi_mcux_data *data = dev->data; - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - int ret; - - if (!asynchronous) { - spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); - } - - ret = spi_mcux_configure(dev, spi_cfg); - if (ret && !asynchronous) { - goto out; - } else if (ret) { - return ret; - } - -#ifdef CONFIG_SOC_SERIES_MCXN - base->TCR |= LPSPI_TCR_CONT_MASK; -#endif - - /* DMA is fast enough watermarks are not required */ - LPSPI_SetFifoWatermarks(base, 0U, 0U); - - spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); - - if (asynchronous) { - ret = transceive_dma_async(dev, cb, userdata); - } else { - ret = transceive_dma_sync(dev); - } - -out: - spi_context_release(&data->ctx, ret); - return ret; -} -#else -#define lpspi_inst_has_dma(arg) arg != arg -#define transceive_dma(...) 0 -#endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ - -#ifdef CONFIG_SPI_RTIO -static void spi_mcux_iodev_start(const struct device *dev) -{ - struct spi_mcux_data *data = dev->data; - struct spi_rtio *rtio_ctx = data->rtio_ctx; - struct rtio_sqe *sqe = &rtio_ctx->txn_curr->sqe; - struct spi_dt_spec *spi_dt_spec = sqe->iodev->data; - struct spi_config *spi_cfg = &spi_dt_spec->config; - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - lpspi_transfer_t transfer; - status_t status; - - status = spi_mcux_configure(dev, spi_cfg); - if (status) { - LOG_ERR("Error configuring lpspi"); - return; - } - - transfer.configFlags = LPSPI_MASTER_XFER_CFG_FLAGS(spi_cfg->slave); - - switch (sqe->op) { - case RTIO_OP_RX: - transfer.txData = NULL; - transfer.rxData = sqe->rx.buf; - transfer.dataSize = sqe->rx.buf_len; - break; - case RTIO_OP_TX: - transfer.rxData = NULL; - transfer.txData = sqe->tx.buf; - transfer.dataSize = sqe->tx.buf_len; - break; - case RTIO_OP_TINY_TX: - transfer.rxData = NULL; - transfer.txData = sqe->tiny_tx.buf; - transfer.dataSize = sqe->tiny_tx.buf_len; - break; - case RTIO_OP_TXRX: - transfer.txData = sqe->txrx.tx_buf; - transfer.rxData = sqe->txrx.rx_buf; - transfer.dataSize = sqe->txrx.buf_len; - break; - default: - LOG_ERR("Invalid op code %d for submission %p\n", sqe->op, (void *)sqe); - spi_mcux_iodev_complete(dev, -EINVAL); - return; - } - - data->transfer_len = transfer.dataSize; - - spi_context_cs_control(&data->ctx, true); - - status = LPSPI_MasterTransferNonBlocking(base, &data->handle, &transfer); - if (status != kStatus_Success) { - LOG_ERR("Transfer could not start on %s: %d", dev->name, status); - spi_mcux_iodev_complete(dev, -EIO); - } -} - -static void spi_mcux_iodev_complete(const struct device *dev, int status) -{ - struct spi_mcux_data *data = dev->data; - struct spi_rtio *rtio_ctx = data->rtio_ctx; - - if (!status && rtio_ctx->txn_curr->sqe.flags & RTIO_SQE_TRANSACTION) { - rtio_ctx->txn_curr = rtio_txn_next(rtio_ctx->txn_curr); - spi_mcux_iodev_start(dev); - return; - } - - /** De-assert CS-line to space from next transaction */ - spi_context_cs_control(&data->ctx, false); - - if (spi_rtio_complete(rtio_ctx, status)) { - spi_mcux_iodev_start(dev); - } -} - -static void spi_mcux_iodev_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) -{ - struct spi_mcux_data *data = dev->data; - struct spi_rtio *rtio_ctx = data->rtio_ctx; - - if (spi_rtio_submit(rtio_ctx, iodev_sqe)) { - spi_mcux_iodev_start(dev); - } -} - -static inline int transceive_rtio(const struct device *dev, const struct spi_config *spi_cfg, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs) -{ - struct spi_mcux_data *data = dev->data; - struct spi_rtio *rtio_ctx = data->rtio_ctx; - int ret; - - spi_context_lock(&data->ctx, false, NULL, NULL, spi_cfg); - - ret = spi_rtio_transceive(rtio_ctx, spi_cfg, tx_bufs, rx_bufs); - - spi_context_release(&data->ctx, ret); - - return ret; -} -#else -#define transceive_rtio(...) 0 -#endif /* CONFIG_SPI_RTIO */ - -static int transceive(const struct device *dev, const struct spi_config *spi_cfg, - const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - bool asynchronous, spi_callback_t cb, void *userdata) -{ - struct spi_mcux_data *data = dev->data; - int ret; - - spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); - - ret = spi_mcux_configure(dev, spi_cfg); - if (ret) { - goto out; - } - - spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); - - spi_context_cs_control(&data->ctx, true); - - ret = spi_mcux_transfer_next_packet(dev); - if (ret) { - goto out; - } - - ret = spi_context_wait_for_completion(&data->ctx); -out: - spi_context_release(&data->ctx, ret); - - return ret; -} - -static int spi_mcux_transceive(const struct device *dev, const struct spi_config *spi_cfg, - const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, - spi_callback_t cb, void *userdata, bool async) -{ - struct spi_mcux_data *data = dev->data; - - if (lpspi_inst_has_dma(data)) { - return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, async, cb, userdata); - } - - if (IS_ENABLED(CONFIG_SPI_RTIO)) { - return transceive_rtio(dev, spi_cfg, tx_bufs, rx_bufs); - } - - return transceive(dev, spi_cfg, tx_bufs, rx_bufs, async, cb, userdata); -} - -static int spi_mcux_transceive_sync(const struct device *dev, const struct spi_config *spi_cfg, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs) -{ - return spi_mcux_transceive(dev, spi_cfg, tx_bufs, rx_bufs, NULL, NULL, false); -} - -#ifdef CONFIG_SPI_ASYNC -static int spi_mcux_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs, spi_callback_t cb, - void *userdata) -{ - return spi_mcux_transceive(dev, spi_cfg, tx_bufs, rx_bufs, cb, userdata, true); -} -#endif /* CONFIG_SPI_ASYNC */ - -static int spi_mcux_release(const struct device *dev, const struct spi_config *spi_cfg) -{ - struct spi_mcux_data *data = dev->data; - - spi_context_unlock_unconditionally(&data->ctx); - - return 0; -} - -static DEVICE_API(spi, spi_mcux_driver_api) = { - .transceive = spi_mcux_transceive_sync, -#ifdef CONFIG_SPI_ASYNC - .transceive_async = spi_mcux_transceive_async, -#endif -#ifdef CONFIG_SPI_RTIO - .iodev_submit = spi_mcux_iodev_submit, -#endif - .release = spi_mcux_release, -}; - -#if defined(CONFIG_SPI_MCUX_LPSPI_DMA) -static int lpspi_dma_dev_ready(const struct device *dma_dev) -{ - if (!device_is_ready(dma_dev)) { - LOG_ERR("%s device is not ready", dma_dev->name); - return -ENODEV; - } - - return 0; -} - -static int lpspi_dma_devs_ready(struct spi_mcux_data *data) -{ - return lpspi_dma_dev_ready(data->dma_tx.dma_dev) | - lpspi_dma_dev_ready(data->dma_rx.dma_dev); -} -#else -#define lpspi_dma_devs_ready(...) 0 -#endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ - -static int spi_mcux_init(const struct device *dev) -{ - const struct spi_mcux_config *config = dev->config; - struct spi_mcux_data *data = dev->data; - int err = 0; - - DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); - - data->dev = dev; - - if (IS_ENABLED(CONFIG_SPI_MCUX_LPSPI_DMA) && lpspi_inst_has_dma(data)) { - err = lpspi_dma_devs_ready(data); - } - if (err < 0) { - return err; - } - - err = spi_context_cs_configure_all(&data->ctx); - if (err < 0) { - return err; - } - - err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); - if (err) { - return err; - } - - config->irq_config_func(dev); - -#ifdef CONFIG_SPI_RTIO - spi_rtio_init(data->rtio_ctx, dev); -#endif - spi_context_unlock_unconditionally(&data->ctx); - - return 0; -} - -#define SPI_MCUX_RTIO_DEFINE(n) \ - SPI_RTIO_DEFINE(spi_mcux_rtio_##n, CONFIG_SPI_MCUX_RTIO_SQ_SIZE, \ - CONFIG_SPI_MCUX_RTIO_SQ_SIZE) - -#ifdef CONFIG_SPI_MCUX_LPSPI_DMA -#define SPI_DMA_CHANNELS(n) \ - IF_ENABLED( \ - DT_INST_DMAS_HAS_NAME(n, tx), \ - (.dma_tx = {.dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, tx)), \ - .channel = DT_INST_DMAS_CELL_BY_NAME(n, tx, mux), \ - .dma_cfg = {.channel_direction = MEMORY_TO_PERIPHERAL, \ - .dma_callback = spi_mcux_dma_callback, \ - .source_data_size = 1, \ - .dest_data_size = 1, \ - .block_count = 1, \ - .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, tx, source)}},)) \ - IF_ENABLED( \ - DT_INST_DMAS_HAS_NAME(n, rx), \ - (.dma_rx = {.dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, rx)), \ - .channel = DT_INST_DMAS_CELL_BY_NAME(n, rx, mux), \ - .dma_cfg = {.channel_direction = PERIPHERAL_TO_MEMORY, \ - .dma_callback = spi_mcux_dma_callback, \ - .source_data_size = 1, \ - .dest_data_size = 1, \ - .block_count = 1, \ - .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, rx, source)}},)) -#else -#define SPI_DMA_CHANNELS(n) -#endif /* CONFIG_SPI_MCUX_LPSPI_DMA */ - -#if defined(CONFIG_NXP_LP_FLEXCOMM) -#define SPI_MCUX_LPSPI_IRQ_FUNC(n) \ - nxp_lp_flexcomm_setirqhandler(DEVICE_DT_GET(DT_INST_PARENT(n)), DEVICE_DT_INST_GET(n), \ - LP_FLEXCOMM_PERIPH_LPSPI, spi_mcux_isr); -#else -#define SPI_MCUX_LPSPI_IRQ_FUNC(n) \ - IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), spi_mcux_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQN(n)); -#endif - -#define SPI_MCUX_LPSPI_INIT(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - COND_CODE_1(CONFIG_SPI_RTIO, (SPI_MCUX_RTIO_DEFINE(n)), ()); \ - \ - static void spi_mcux_config_func_##n(const struct device *dev) \ - { \ - SPI_MCUX_LPSPI_IRQ_FUNC(n) \ - } \ - \ - static const struct spi_mcux_config spi_mcux_config_##n = { \ - DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ - .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ - .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ - .irq_config_func = spi_mcux_config_func_##n, \ - .pcs_sck_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, pcs_sck_delay), \ - DT_INST_PROP(n, pcs_sck_delay)), \ - .sck_pcs_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, sck_pcs_delay), \ - DT_INST_PROP(n, sck_pcs_delay)), \ - .transfer_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, transfer_delay), \ - DT_INST_PROP(n, transfer_delay)), \ - .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .data_pin_config = DT_INST_ENUM_IDX(n, data_pin_config), \ - }; \ - \ - static struct spi_mcux_data spi_mcux_data_##n = { \ - SPI_CONTEXT_INIT_LOCK(spi_mcux_data_##n, ctx), \ - SPI_CONTEXT_INIT_SYNC(spi_mcux_data_##n, ctx), \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) SPI_DMA_CHANNELS(n) \ - IF_ENABLED(CONFIG_SPI_RTIO, (.rtio_ctx = &spi_mcux_rtio_##n,)) \ - }; \ - \ - DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, &spi_mcux_data_##n, &spi_mcux_config_##n, \ - POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_mcux_driver_api); - -DT_INST_FOREACH_STATUS_OKAY(SPI_MCUX_LPSPI_INIT) diff --git a/drivers/spi/spi_npcx_spip.c b/drivers/spi/spi_npcx_spip.c index 350232d307cc4..8263fe9e8783c 100644 --- a/drivers/spi/spi_npcx_spip.c +++ b/drivers/spi/spi_npcx_spip.c @@ -443,7 +443,7 @@ static DEVICE_API(spi, spi_npcx_spip_api) = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ NPCX_SPIP_IRQ_HANDLER_FUNC(n)}; \ \ - DEVICE_DT_INST_DEFINE(n, spi_npcx_spip_init, NULL, &spi_npcx_spip_data_##n, \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_npcx_spip_init, NULL, &spi_npcx_spip_data_##n, \ &spi_npcx_spip_cfg_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &spi_npcx_spip_api); diff --git a/drivers/spi/spi_nrfx_spi.c b/drivers/spi/spi_nrfx_spi.c index b7706e7259ba7..e0aeb66802952 100644 --- a/drivers/spi/spi_nrfx_spi.c +++ b/drivers/spi/spi_nrfx_spi.c @@ -92,6 +92,7 @@ static int configure(const struct device *dev, struct spi_context *ctx = &dev_data->ctx; nrfx_spi_config_t config; nrfx_err_t result; + uint32_t sck_pin; if (dev_data->initialized && spi_context_configured(ctx, spi_cfg)) { /* Already configured. No need to do it again. */ @@ -135,8 +136,11 @@ static int configure(const struct device *dev, config.mode = get_nrf_spi_mode(spi_cfg->operation); config.bit_order = get_nrf_spi_bit_order(spi_cfg->operation); - nrf_gpio_pin_write(nrf_spi_sck_pin_get(dev_config->spi.p_reg), - spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0); + sck_pin = nrf_spi_sck_pin_get(dev_config->spi.p_reg); + + if (sck_pin != NRF_SPI_PIN_NOT_CONNECTED) { + nrf_gpio_pin_write(sck_pin, spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0); + } if (dev_data->initialized) { nrfx_spi_uninit(&dev_config->spi); @@ -456,7 +460,7 @@ static int spi_nrfx_init(const struct device *dev) !(DT_GPIO_FLAGS(SPI(idx), wake_gpios) & GPIO_ACTIVE_LOW), \ "WAKE line must be configured as active high"); \ PM_DEVICE_DT_DEFINE(SPI(idx), spi_nrfx_pm_action); \ - DEVICE_DT_DEFINE(SPI(idx), \ + SPI_DEVICE_DT_DEFINE(SPI(idx), \ spi_nrfx_init, \ PM_DEVICE_DT_GET(SPI(idx)), \ &spi_##idx##_data, \ diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 9cc73f02de4e2..8b14695361fe4 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -41,6 +43,16 @@ LOG_MODULE_REGISTER(spi_nrfx_spim, CONFIG_SPI_LOG_LEVEL); #define SPI_BUFFER_IN_RAM 1 #endif +#if defined(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL) && \ + (defined(CONFIG_HAS_HW_NRF_SPIM120) || \ + defined(CONFIG_HAS_HW_NRF_SPIM121)) +#define SPIM_REQUESTS_CLOCK(idx) UTIL_OR(IS_EQ(idx, 120), \ + IS_EQ(idx, 121)) +#define USE_CLOCK_REQUESTS 1 +#else +#define SPIM_REQUESTS_CLOCK(idx) 0 +#endif + struct spi_nrfx_data { struct spi_context ctx; const struct device *dev; @@ -56,6 +68,9 @@ struct spi_nrfx_data { uint8_t ppi_ch; uint8_t gpiote_ch; #endif +#ifdef USE_CLOCK_REQUESTS + bool clock_requested; +#endif }; struct spi_nrfx_config { @@ -73,10 +88,59 @@ struct spi_nrfx_config { #ifdef CONFIG_DCACHE uint32_t mem_attr; #endif +#ifdef USE_CLOCK_REQUESTS + const struct device *clk_dev; + struct nrf_clock_spec clk_spec; +#endif }; static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context); +static inline int request_clock(const struct device *dev) +{ +#ifdef USE_CLOCK_REQUESTS + struct spi_nrfx_data *dev_data = dev->data; + const struct spi_nrfx_config *dev_config = dev->config; + int error; + + if (!dev_config->clk_dev) { + return 0; + } + + error = nrf_clock_control_request_sync( + dev_config->clk_dev, &dev_config->clk_spec, + K_MSEC(CONFIG_SPI_COMPLETION_TIMEOUT_TOLERANCE)); + if (error < 0) { + LOG_ERR("Failed to request clock: %d", error); + return error; + } + + dev_data->clock_requested = true; +#else + ARG_UNUSED(dev); +#endif + + return 0; +} + +static inline void release_clock(const struct device *dev) +{ +#ifdef USE_CLOCK_REQUESTS + struct spi_nrfx_data *dev_data = dev->data; + const struct spi_nrfx_config *dev_config = dev->config; + + if (!dev_data->clock_requested) { + return; + } + + dev_data->clock_requested = false; + + nrf_clock_control_release(dev_config->clk_dev, &dev_config->clk_spec); +#else + ARG_UNUSED(dev); +#endif +} + static inline void finalize_spi_transaction(const struct device *dev, bool deactivate_cs) { struct spi_nrfx_data *dev_data = dev->data; @@ -90,6 +154,12 @@ static inline void finalize_spi_transaction(const struct device *dev, bool deact if (NRF_SPIM_IS_320MHZ_SPIM(reg) && !(dev_data->ctx.config->operation & SPI_HOLD_ON_CS)) { nrfy_spim_disable(reg); } + + if (!IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + release_clock(dev); + } + + pm_device_runtime_put_async(dev, K_NO_WAIT); } static inline uint32_t get_nrf_spim_frequency(uint32_t frequency) @@ -152,6 +222,7 @@ static int configure(const struct device *dev, uint32_t max_freq = dev_config->max_freq; nrfx_spim_config_t config; nrfx_err_t result; + uint32_t sck_pin; if (dev_data->initialized && spi_context_configured(ctx, spi_cfg)) { /* Already configured. No need to do it again. */ @@ -208,8 +279,11 @@ static int configure(const struct device *dev, config.mode = get_nrf_spim_mode(spi_cfg->operation); config.bit_order = get_nrf_spim_bit_order(spi_cfg->operation); - nrfy_gpio_pin_write(nrfy_spim_sck_pin_get(dev_config->spim.p_reg), - spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0); + sck_pin = nrfy_spim_sck_pin_get(dev_config->spim.p_reg); + + if (sck_pin != NRF_SPIM_PIN_NOT_CONNECTED) { + nrfy_gpio_pin_write(sck_pin, spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0); + } if (dev_data->initialized) { nrfx_spim_uninit(&dev_config->spim); @@ -460,9 +534,15 @@ static int transceive(const struct device *dev, void *reg = dev_config->spim.p_reg; int error; + pm_device_runtime_get(dev); spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); error = configure(dev, spi_cfg); + + if (error == 0 && !IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + error = request_clock(dev); + } + if (error == 0) { dev_data->busy = true; @@ -514,6 +594,8 @@ static int transceive(const struct device *dev, } else if (error) { finalize_spi_transaction(dev, true); } + } else { + pm_device_runtime_put(dev); } spi_context_release(&dev_data->ctx, error); @@ -571,56 +653,55 @@ static DEVICE_API(spi, spi_nrfx_driver_api) = { .release = spi_nrfx_release, }; -#ifdef CONFIG_PM_DEVICE -static int spim_nrfx_pm_action(const struct device *dev, - enum pm_device_action action) +static int spim_resume(const struct device *dev) { - int ret = 0; - struct spi_nrfx_data *dev_data = dev->data; const struct spi_nrfx_config *dev_config = dev->config; - switch (action) { - case PM_DEVICE_ACTION_RESUME: - ret = pinctrl_apply_state(dev_config->pcfg, - PINCTRL_STATE_DEFAULT); - if (ret < 0) { - return ret; - } - /* nrfx_spim_init() will be called at configuration before - * the next transfer. - */ + (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + /* nrfx_spim_init() will be called at configuration before + * the next transfer. + */ #ifdef CONFIG_SOC_NRF54H20_GPD - nrf_gpd_retain_pins_set(dev_config->pcfg, false); + nrf_gpd_retain_pins_set(dev_config->pcfg, false); #endif - break; + return IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) ? request_clock(dev) : 0; +} - case PM_DEVICE_ACTION_SUSPEND: - if (dev_data->initialized) { - nrfx_spim_uninit(&dev_config->spim); - dev_data->initialized = false; - } +static void spim_suspend(const struct device *dev) +{ + const struct spi_nrfx_config *dev_config = dev->config; + struct spi_nrfx_data *dev_data = dev->data; + + if (dev_data->initialized) { + nrfx_spim_uninit(&dev_config->spim); + dev_data->initialized = false; + } + + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + release_clock(dev); + } #ifdef CONFIG_SOC_NRF54H20_GPD - nrf_gpd_retain_pins_set(dev_config->pcfg, true); + nrf_gpd_retain_pins_set(dev_config->pcfg, true); #endif - ret = pinctrl_apply_state(dev_config->pcfg, - PINCTRL_STATE_SLEEP); - if (ret < 0) { - return ret; - } - break; + (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); +} - default: - ret = -ENOTSUP; +static int spim_nrfx_pm_action(const struct device *dev, enum pm_device_action action) +{ + if (action == PM_DEVICE_ACTION_RESUME) { + return spim_resume(dev); + } else if (IS_ENABLED(CONFIG_PM_DEVICE) && (action == PM_DEVICE_ACTION_SUSPEND)) { + spim_suspend(dev); + } else { + return -ENOTSUP; } - return ret; + return 0; } -#endif /* CONFIG_PM_DEVICE */ - static int spi_nrfx_init(const struct device *dev) { @@ -655,10 +736,12 @@ static int spi_nrfx_init(const struct device *dev) spi_context_unlock_unconditionally(&dev_data->ctx); #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 - return anomaly_58_workaround_init(dev); -#else - return 0; + err = anomaly_58_workaround_init(dev); + if (err < 0) { + return err; + } #endif + return pm_device_driver_init(dev, spim_nrfx_pm_action); } /* * We use NODELABEL here because the nrfx API requires us to call @@ -686,6 +769,21 @@ static int spi_nrfx_init(const struct device *dev) (0))), \ (0)) +/* Fast instances depend on the global HSFLL clock controller (as they need + * to request the highest frequency from it to operate correctly), so they + * must be initialized after that controller driver, hence the default SPI + * initialization priority may be too early for them. + */ +#if defined(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY) && \ + CONFIG_SPI_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY +#define SPIM_INIT_PRIORITY(idx) \ + COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), \ + (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \ + (CONFIG_SPI_INIT_PRIORITY)) +#else +#define SPIM_INIT_PRIORITY(idx) CONFIG_SPI_INIT_PRIORITY +#endif + #define SPI_NRFX_SPIM_DEFINE(idx) \ NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ static void irq_connect##idx(void) \ @@ -736,17 +834,24 @@ static int spi_nrfx_init(const struct device *dev) .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \ IF_ENABLED(CONFIG_DCACHE, \ (.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \ + IF_ENABLED(USE_CLOCK_REQUESTS, \ + (.clk_dev = SPIM_REQUESTS_CLOCK(idx) \ + ? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \ + : NULL, \ + .clk_spec = { \ + .frequency = NRF_CLOCK_CONTROL_FREQUENCY_MAX, \ + },)) \ }; \ BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \ !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ "WAKE line must be configured as active high"); \ PM_DEVICE_DT_DEFINE(SPIM(idx), spim_nrfx_pm_action); \ - DEVICE_DT_DEFINE(SPIM(idx), \ + SPI_DEVICE_DT_DEFINE(SPIM(idx), \ spi_nrfx_init, \ PM_DEVICE_DT_GET(SPIM(idx)), \ &spi_##idx##_data, \ &spi_##idx##z_config, \ - POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + POST_KERNEL, SPIM_INIT_PRIORITY(idx), \ &spi_nrfx_driver_api) #define SPIM_MEMORY_SECTION(idx) \ diff --git a/drivers/spi/spi_nrfx_spis.c b/drivers/spi/spi_nrfx_spis.c index fe8e338c0eecd..431d011433f59 100644 --- a/drivers/spi/spi_nrfx_spis.c +++ b/drivers/spi/spi_nrfx_spis.c @@ -394,7 +394,7 @@ static int spi_nrfx_init(const struct device *dev) BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIS(idx), wake_gpios) || \ !(DT_GPIO_FLAGS(SPIS(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ "WAKE line must be configured as active high"); \ - DEVICE_DT_DEFINE(SPIS(idx), \ + SPI_DEVICE_DT_DEFINE(SPIS(idx), \ spi_nrfx_init, \ NULL, \ &spi_##idx##_data, \ diff --git a/drivers/spi/spi_numaker.c b/drivers/spi/spi_numaker.c index b140c99e4a0d5..46901ecad6850 100644 --- a/drivers/spi/spi_numaker.c +++ b/drivers/spi/spi_numaker.c @@ -360,7 +360,7 @@ static int spi_numaker_init(const struct device *dev) .clk_dev = DEVICE_DT_GET(DT_PARENT(DT_INST_CLOCKS_CTLR(inst))), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ }; \ - DEVICE_DT_INST_DEFINE(inst, spi_numaker_init, NULL, &spi_numaker_data_##inst, \ + SPI_DEVICE_DT_INST_DEFINE(inst, spi_numaker_init, NULL, &spi_numaker_data_##inst, \ &spi_numaker_config_##inst, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &spi_numaker_driver_api); diff --git a/drivers/spi/spi_nxp_lpspi/CMakeLists.txt b/drivers/spi/spi_nxp_lpspi/CMakeLists.txt new file mode 100644 index 0000000000000..49d1616421819 --- /dev/null +++ b/drivers/spi/spi_nxp_lpspi/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright 2024 NXP + +zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_LPSPI spi_nxp_lpspi_common.c) +zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_LPSPI_NORMAL spi_nxp_lpspi.c) +zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_LPSPI_DMA spi_nxp_lpspi_dma.c) diff --git a/drivers/spi/spi_nxp_lpspi/Kconfig b/drivers/spi/spi_nxp_lpspi/Kconfig new file mode 100644 index 0000000000000..5897daf3655ca --- /dev/null +++ b/drivers/spi/spi_nxp_lpspi/Kconfig @@ -0,0 +1,30 @@ +# Copyright 2018, 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SPI_MCUX_LPSPI + bool "NXP LPSPI peripheral" + default y + depends on DT_HAS_NXP_LPSPI_ENABLED + depends on CLOCK_CONTROL + select PINCTRL + help + Enable support for NXP LPSPI. + +if SPI_MCUX_LPSPI + +config SPI_MCUX_LPSPI_DMA + bool "MCUX LPSPI SPI DMA Support" + select DMA + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_NXP_LPSPI),dmas) + help + Enable the SPI DMA mode for SPI instances + that enable dma channels in their device tree node. + +config SPI_MCUX_LPSPI_NORMAL + bool "NXP MCUX LPSPI driver" + default y + depends on $(dt_compat_any_not_has_prop,$(DT_COMPAT_NXP_LPSPI),dmas) || !SPI_MCUX_LPSPI_DMA + help + Use the traditional (non-RTIO) SPI driver for NXP LPSPI. + +endif # SPI_MCUX_LPSPI diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c new file mode 100644 index 0000000000000..da6305e3e0bd7 --- /dev/null +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c @@ -0,0 +1,365 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_lpspi + +#include +LOG_MODULE_REGISTER(spi_mcux_lpspi, CONFIG_SPI_LOG_LEVEL); + +#include "spi_nxp_lpspi_priv.h" + +struct lpspi_driver_data { + size_t fill_len; + size_t tx_total_len; + size_t rx_total_len; + uint8_t word_size_bytes; +}; + +static inline void lpspi_wait_tx_fifo_empty(const struct device *dev) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + + while (LPSPI_GetTxFifoCount(base) != 0) { + } +} + +/* Reads a word from the RX fifo and handles writing it into the RX spi buf */ +static inline void lpspi_rx_word_write_bytes(const struct device *dev, size_t offset) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + struct spi_context *ctx = &data->ctx; + uint8_t num_bytes = MIN(lpspi_data->word_size_bytes, ctx->rx_len); + uint8_t *buf = ctx->rx_buf + offset; + uint32_t word = LPSPI_ReadData(base); + + if (!spi_context_rx_buf_on(ctx) && spi_context_rx_on(ctx)) { + /* receive no actual data if rx buf is NULL */ + return; + } + + for (uint8_t i = 0; i < num_bytes; i++) { + buf[i] = (uint8_t)(word >> (BITS_PER_BYTE * i)); + } +} + +/* Reads a maximum number of words from RX fifo and writes them to the remainder of the RX buf */ +static inline size_t lpspi_rx_buf_write_words(const struct device *dev, uint8_t max_read) +{ + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + struct spi_context *ctx = &data->ctx; + size_t buf_len = ctx->rx_len / lpspi_data->word_size_bytes; + uint8_t words_read = 0; + size_t offset = 0; + + while (buf_len-- > 0 && max_read-- > 0) { + lpspi_rx_word_write_bytes(dev, offset); + offset += lpspi_data->word_size_bytes; + words_read++; + } + + return words_read; +} + +static inline uint8_t rx_fifo_cur_len(LPSPI_Type *base) +{ + return (base->FSR & LPSPI_FSR_RXCOUNT_MASK) >> LPSPI_FSR_RXCOUNT_SHIFT; +} + +static inline void lpspi_handle_rx_irq(const struct device *dev) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + struct spi_context *ctx = &data->ctx; + uint8_t total_words_written = 0; + uint8_t total_words_read = 0; + uint8_t words_read; + uint8_t rx_fsr; + + LPSPI_ClearStatusFlags(base, kLPSPI_RxDataReadyFlag); + + LOG_DBG("RX FIFO: %d, RX BUF: %p", rx_fsr, ctx->rx_buf); + + while ((rx_fsr = rx_fifo_cur_len(base)) > 0 && spi_context_rx_on(ctx)) { + words_read = lpspi_rx_buf_write_words(dev, rx_fsr); + total_words_read += words_read; + total_words_written += (spi_context_rx_buf_on(ctx) ? words_read : 0); + spi_context_update_rx(ctx, lpspi_data->word_size_bytes, words_read); + } + + LOG_DBG("RX done %d words to spi buf", total_words_written); + + if (!spi_context_rx_on(ctx)) { + LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable); + LPSPI_FlushFifo(base, false, true); + } +} + +static inline uint32_t lpspi_next_tx_word(const struct device *dev, int offset) +{ + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + struct spi_context *ctx = &data->ctx; + const uint8_t *byte = ctx->tx_buf + offset; + uint32_t num_bytes = MIN(lpspi_data->word_size_bytes, ctx->tx_len); + uint32_t next_word = 0; + + for (uint8_t i = 0; i < num_bytes; i++) { + next_word |= *byte << (BITS_PER_BYTE * i); + } + + return next_word; +} + +static inline void lpspi_fill_tx_fifo(const struct device *dev) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + size_t bytes_in_xfer = lpspi_data->fill_len * lpspi_data->word_size_bytes; + size_t offset; + + for (offset = 0; offset < bytes_in_xfer; offset += lpspi_data->word_size_bytes) { + LPSPI_WriteData(base, lpspi_next_tx_word(dev, offset)); + } + + LOG_DBG("Filled TX FIFO to %d words (%d bytes)", lpspi_data->fill_len, offset); +} + +static inline void lpspi_fill_tx_fifo_nop(const struct device *dev) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + + for (int i = 0; i < lpspi_data->fill_len; i++) { + LPSPI_WriteData(base, 0); + } + + LOG_DBG("Filled TX fifo with %d NOPs", lpspi_data->fill_len); +} + +static void lpspi_next_tx_fill(const struct device *dev) +{ + const struct spi_mcux_config *config = dev->config; + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + struct spi_context *ctx = &data->ctx; + size_t max_chunk; + + /* Convert bytes to words for this xfer */ + max_chunk = ctx->tx_len / lpspi_data->word_size_bytes; + max_chunk = MIN(max_chunk, config->tx_fifo_size); + lpspi_data->fill_len = max_chunk; + + if (spi_context_tx_buf_on(ctx)) { + lpspi_fill_tx_fifo(dev); + } else { + lpspi_fill_tx_fifo_nop(dev); + } +} + +static inline void lpspi_handle_tx_irq(const struct device *dev) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + struct spi_context *ctx = &data->ctx; + + spi_context_update_tx(ctx, lpspi_data->word_size_bytes, lpspi_data->fill_len); + + LPSPI_ClearStatusFlags(base, kLPSPI_TxDataRequestFlag); + + /* Having no buffer length left indicates transfer is done, if there + * was RX to do left, the TX buf would be null but + * ctx still tracks length of dummy data + */ + if (!spi_context_tx_on(ctx)) { + /* Disable chip select and end transfer clocks last word */ + base->TCR = 0; + lpspi_wait_tx_fifo_empty(dev); + spi_context_cs_control(ctx, false); + LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable); + return; + } + + lpspi_next_tx_fill(data->dev); +} + +static inline bool lpspi_is_rx_done(const struct device *dev) +{ + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + struct spi_context *ctx = &data->ctx; + size_t tx_total = lpspi_data->tx_total_len; + size_t rx_total = lpspi_data->rx_total_len; + + if (tx_total >= rx_total) { + return (spi_context_total_rx_len(ctx) == 0); + } else { + return (tx_total <= (rx_total - spi_context_rx_len_left(ctx))); + } +} + +static inline void lpspi_clear_remaining_rx(struct spi_context *ctx) +{ + size_t remaining_len; + + while ((remaining_len = spi_context_rx_len_left(ctx)) > 0) { + for (int i = 0; i < ctx->rx_len; i++) { + ctx->rx_buf[i] = 0; + } + spi_context_update_rx(ctx, 1, ctx->rx_len); + } +} + +static void lpspi_isr(const struct device *dev) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + const struct spi_mcux_config *config = dev->config; + uint32_t status_flags = LPSPI_GetStatusFlags(base); + struct spi_mcux_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + if (status_flags & kLPSPI_RxDataReadyFlag) { + lpspi_handle_rx_irq(dev); + } + + if (status_flags & kLPSPI_TxDataRequestFlag) { + lpspi_handle_tx_irq(dev); + } + + if (!spi_context_tx_on(ctx) && lpspi_is_rx_done(dev)) { + spi_context_complete(ctx, dev, 0); + NVIC_ClearPendingIRQ(config->irqn); + lpspi_clear_remaining_rx(ctx); + } +} + +static int transceive(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, + bool asynchronous, spi_callback_t cb, void *userdata) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; + int ret; + + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); + + lpspi_data->word_size_bytes = SPI_WORD_SIZE_GET(spi_cfg->operation) / BITS_PER_BYTE; + if (lpspi_data->word_size_bytes > 4) { + LOG_ERR("Maximum 4 byte word size"); + ret = -EINVAL; + goto out; + } + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, lpspi_data->word_size_bytes); + + lpspi_data->tx_total_len = spi_context_total_tx_len(&data->ctx); + lpspi_data->rx_total_len = spi_context_total_rx_len(&data->ctx); + + ret = spi_mcux_configure(dev, spi_cfg); + if (ret) { + goto out; + } + + LPSPI_FlushFifo(base, true, true); + LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag); + LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); + + LOG_DBG("Starting LPSPI transfer"); + spi_context_cs_control(&data->ctx, true); + + LPSPI_SetFifoWatermarks(base, 0, 0); + LPSPI_Enable(base, true); + + /* keep the chip select asserted until the end of the zephyr xfer */ + base->TCR |= LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK; + /* tcr is written to tx fifo */ + lpspi_wait_tx_fifo_empty(dev); + + /* start the transfer sequence which are handled by irqs */ + lpspi_next_tx_fill(dev); + + LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | + (uint32_t)kLPSPI_RxInterruptEnable); + + ret = spi_context_wait_for_completion(&data->ctx); +out: + spi_context_release(&data->ctx, ret); + + return ret; +} + +static int spi_mcux_transceive_sync(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); +} + +#ifdef CONFIG_SPI_ASYNC +static int spi_mcux_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, spi_callback_t cb, + void *userdata) +{ + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif /* CONFIG_SPI_ASYNC */ + +static DEVICE_API(spi, spi_mcux_driver_api) = { + .transceive = spi_mcux_transceive_sync, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = spi_mcux_transceive_async, +#endif +#ifdef CONFIG_SPI_RTIO + .iodev_submit = spi_rtio_iodev_default_submit, +#endif + .release = spi_mcux_release, +}; + +static int spi_mcux_init(const struct device *dev) +{ + struct spi_mcux_data *data = dev->data; + int err = 0; + + err = spi_nxp_init_common(dev); + if (err) { + return err; + } + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +#define LPSPI_INIT(n) \ + SPI_NXP_LPSPI_COMMON_INIT(n) \ + SPI_MCUX_LPSPI_CONFIG_INIT(n) \ + \ + static struct lpspi_driver_data lpspi_##n##_driver_data; \ + \ + static struct spi_mcux_data spi_mcux_data_##n = { \ + SPI_NXP_LPSPI_COMMON_DATA_INIT(n) \ + .driver_data = &lpspi_##n##_driver_data, \ + }; \ + \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, &spi_mcux_data_##n, \ + &spi_mcux_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &spi_mcux_driver_api); + +#define SPI_MCUX_LPSPI_INIT_IF_DMA(n) IF_DISABLED(SPI_NXP_LPSPI_HAS_DMAS(n), (LPSPI_INIT(n))) + +#define SPI_MCUX_LPSPI_INIT(n) \ + COND_CODE_1(CONFIG_SPI_MCUX_LPSPI_DMA, \ + (SPI_MCUX_LPSPI_INIT_IF_DMA(n)), (LPSPI_INIT(n))) + +DT_INST_FOREACH_STATUS_OKAY(SPI_MCUX_LPSPI_INIT) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c new file mode 100644 index 0000000000000..f1edead9e6c33 --- /dev/null +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c @@ -0,0 +1,133 @@ +/* + * Copyright 2018, 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(spi_mcux_lpspi_common, CONFIG_SPI_LOG_LEVEL); + +#include "spi_nxp_lpspi_priv.h" + +int spi_mcux_release(const struct device *dev, const struct spi_config *spi_cfg) +{ + struct spi_mcux_data *data = dev->data; + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cfg) +{ + const struct spi_mcux_config *config = dev->config; + struct spi_mcux_data *data = dev->data; + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + uint32_t word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); + lpspi_master_config_t master_config; + uint32_t clock_freq; + int ret; + + if (spi_cfg->operation & SPI_HALF_DUPLEX) { + /* the IP DOES support half duplex, need to implement driver support */ + LOG_ERR("Half-duplex not supported"); + return -ENOTSUP; + } + + if (word_size < 8 || (word_size % 32 == 1)) { + /* Zephyr word size == hardware FRAME size (not word size) + * Max frame size: 4096 bits + * (zephyr field is 6 bit wide for max 64 bit size, no need to check) + * Min frame size: 8 bits. + * Minimum hardware word size is 2. Since this driver is intended to work + * for 32 bit platforms, and 64 bits is max size, then only 33 and 1 are invalid. + */ + LOG_ERR("Word size %d not allowed", word_size); + return -EINVAL; + } + + if (spi_cfg->slave > LPSPI_CHIP_SELECT_COUNT) { + LOG_ERR("Peripheral %d select exceeds max %d", spi_cfg->slave, + LPSPI_CHIP_SELECT_COUNT - 1); + return -EINVAL; + } + + ret = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_freq); + if (ret) { + return ret; + } + + if (data->ctx.config != NULL) { + /* Setting the baud rate in LPSPI_MasterInit requires module to be disabled. Only + * disable if already configured, otherwise the clock is not enabled and the + * CR register cannot be written. + */ + LPSPI_Enable(base, false); + while ((base->CR & LPSPI_CR_MEN_MASK) != 0U) { + /* Wait until LPSPI is disabled. Datasheet: + * After writing 0, MEN (Module Enable) remains set until the LPSPI has + * completed the current transfer and is idle. + */ + } + } + + data->ctx.config = spi_cfg; + + LPSPI_MasterGetDefaultConfig(&master_config); + + master_config.bitsPerFrame = word_size; + master_config.cpol = (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) + ? kLPSPI_ClockPolarityActiveLow + : kLPSPI_ClockPolarityActiveHigh; + master_config.cpha = (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) + ? kLPSPI_ClockPhaseSecondEdge + : kLPSPI_ClockPhaseFirstEdge; + master_config.direction = + (spi_cfg->operation & SPI_TRANSFER_LSB) ? kLPSPI_LsbFirst : kLPSPI_MsbFirst; + master_config.baudRate = spi_cfg->frequency; + master_config.pcsToSckDelayInNanoSec = config->pcs_sck_delay; + master_config.lastSckToPcsDelayInNanoSec = config->sck_pcs_delay; + master_config.betweenTransferDelayInNanoSec = config->transfer_delay; + master_config.pinCfg = config->data_pin_config; + master_config.dataOutConfig = config->output_config ? kLpspiDataOutTristate : + kLpspiDataOutRetained; + + LPSPI_MasterInit(base, &master_config, clock_freq); + LPSPI_SetDummyData(base, 0); + + if (IS_ENABLED(CONFIG_DEBUG)) { + base->CR |= LPSPI_CR_DBGEN_MASK; + } + + return 0; +} + +int spi_nxp_init_common(const struct device *dev) +{ + const struct spi_mcux_config *config = dev->config; + struct spi_mcux_data *data = dev->data; + int err = 0; + + DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + + data->dev = dev; + + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + + err = spi_context_cs_configure_all(&data->ctx); + if (err < 0) { + return err; + } + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + return err; + } + + config->irq_config_func(dev); + + return err; +} diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c new file mode 100644 index 0000000000000..7ad3a3206de7f --- /dev/null +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c @@ -0,0 +1,440 @@ +/* + * Copyright 2018, 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_lpspi + +#include +LOG_MODULE_REGISTER(spi_mcux_lpspi_dma, CONFIG_SPI_LOG_LEVEL); + +#include +#include "spi_nxp_lpspi_priv.h" + +struct spi_dma_stream { + const struct device *dma_dev; + uint32_t channel; /* stores the channel for dma */ + struct dma_config dma_cfg; + struct dma_block_config dma_blk_cfg; +}; + +struct spi_nxp_dma_data { + volatile uint32_t status_flags; + struct spi_dma_stream dma_rx; + struct spi_dma_stream dma_tx; + /* dummy value used for transferring NOP when tx buf is null */ + uint32_t dummy_buffer; +}; + +/* These flags are arbitrary */ +#define LPSPI_DMA_ERROR_FLAG BIT(0) +#define LPSPI_DMA_RX_DONE_FLAG BIT(1) +#define LPSPI_DMA_TX_DONE_FLAG BIT(2) +#define LPSPI_DMA_DONE_FLAG (LPSPI_DMA_RX_DONE_FLAG | LPSPI_DMA_TX_DONE_FLAG) + +/* This function is executed in the interrupt context */ +static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t channel, int status) +{ + /* arg directly holds the spi device */ + const struct device *spi_dev = arg; + struct spi_mcux_data *data = (struct spi_mcux_data *)spi_dev->data; + struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; + char debug_char; + + if (status < 0) { + goto error; + } + + /* identify the origin of this callback */ + if (channel == dma_data->dma_tx.channel) { + /* this part of the transfer ends */ + dma_data->status_flags |= LPSPI_DMA_TX_DONE_FLAG; + debug_char = 'T'; + } else if (channel == dma_data->dma_rx.channel) { + /* this part of the transfer ends */ + dma_data->status_flags |= LPSPI_DMA_RX_DONE_FLAG; + debug_char = 'R'; + } else { + goto error; + } + + LOG_DBG("DMA %cX Block Complete", debug_char); + +#if CONFIG_SPI_ASYNC + if (data->ctx.asynchronous && (dma_data->status_flags & LPSPI_DMA_DONE_FLAG)) { + /* Load dma blocks of equal length */ + size_t dma_size = spi_context_max_continuous_chunk(data->ctx); + + if (dma_size != 0) { + return; + } + + spi_context_update_tx(&data->ctx, 1, dma_size); + spi_context_update_rx(&data->ctx, 1, dma_size); + } +#endif + + goto done; +error: + LOG_ERR("DMA callback error with channel %d.", channel); + dma_data->status_flags |= LPSPI_DMA_ERROR_FLAG; +done: + spi_context_complete(&data->ctx, spi_dev, 0); +} + +static struct dma_block_config *spi_mcux_dma_common_load(struct spi_dma_stream *stream, + const struct device *dev, + const uint8_t *buf, size_t len) +{ + struct spi_mcux_data *data = dev->data; + struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; + struct dma_block_config *blk_cfg = &stream->dma_blk_cfg; + + /* prepare the block for this TX DMA channel */ + memset(blk_cfg, 0, sizeof(struct dma_block_config)); + + blk_cfg->block_size = len; + + if (buf == NULL) { + blk_cfg->source_address = (uint32_t)&dma_data->dummy_buffer; + blk_cfg->dest_address = (uint32_t)&dma_data->dummy_buffer; + /* pretend it is peripheral xfer so DMA just xfer to dummy buf */ + stream->dma_cfg.channel_direction = PERIPHERAL_TO_PERIPHERAL; + } else { + blk_cfg->source_address = (uint32_t)buf; + blk_cfg->dest_address = (uint32_t)buf; + } + + /* Transfer 1 byte each DMA loop */ + stream->dma_cfg.source_burst_length = 1; + stream->dma_cfg.user_data = (void *)dev; + stream->dma_cfg.head_block = blk_cfg; + + return blk_cfg; +} + +static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, size_t len) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; + /* remember active TX DMA channel (used in callback) */ + struct spi_dma_stream *stream = &dma_data->dma_tx; + struct dma_block_config *blk_cfg = spi_mcux_dma_common_load(stream, dev, buf, len); + + if (buf != NULL) { + /* tx direction has memory as source and periph as dest. */ + stream->dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + } + + /* Dest is LPSPI tx fifo */ + blk_cfg->dest_address = LPSPI_GetTxRegisterAddress(base); + + /* give the client dev as arg, as the callback comes from the dma */ + /* pass our client origin to the dma: data->dma_tx.dma_channel */ + return dma_config(stream->dma_dev, stream->channel, &stream->dma_cfg); +} + +static int spi_mcux_dma_rx_load(const struct device *dev, uint8_t *buf, size_t len) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; + /* retrieve active RX DMA channel (used in callback) */ + struct spi_dma_stream *stream = &dma_data->dma_rx; + struct dma_block_config *blk_cfg = spi_mcux_dma_common_load(stream, dev, buf, len); + + if (buf != NULL) { + /* rx direction has periph as source and mem as dest. */ + stream->dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + } + + /* Source is LPSPI rx fifo */ + blk_cfg->source_address = LPSPI_GetRxRegisterAddress(base); + + /* pass our client origin to the dma: data->dma_rx.channel */ + return dma_config(stream->dma_dev, stream->channel, &stream->dma_cfg); +} + +static int wait_dma_rx_tx_done(const struct device *dev) +{ + struct spi_mcux_data *data = dev->data; + struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; + int ret; + + do { + ret = spi_context_wait_for_completion(&data->ctx); + if (ret) { + LOG_DBG("Timed out waiting for SPI context to complete"); + return ret; + } else if (dma_data->status_flags & LPSPI_DMA_ERROR_FLAG) { + return -EIO; + } + } while (!((dma_data->status_flags & LPSPI_DMA_DONE_FLAG) == LPSPI_DMA_DONE_FLAG)); + + LOG_DBG("DMA block completed"); + return 0; +} + +static inline int spi_mcux_dma_rxtx_load(const struct device *dev, size_t *dma_size) +{ + struct spi_mcux_data *data = dev->data; + struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; + struct spi_context *ctx = &data->ctx; + int ret = 0; + + /* Clear status flags */ + dma_data->status_flags = 0U; + + /* Load dma blocks of equal length */ + *dma_size = spi_context_max_continuous_chunk(ctx); + + ret = spi_mcux_dma_tx_load(dev, ctx->tx_buf, *dma_size); + if (ret != 0) { + return ret; + } + + ret = spi_mcux_dma_rx_load(dev, ctx->rx_buf, *dma_size); + if (ret != 0) { + return ret; + } + + /* Start DMA */ + ret = dma_start(dma_data->dma_tx.dma_dev, dma_data->dma_tx.channel); + if (ret != 0) { + return ret; + } + + ret = dma_start(dma_data->dma_rx.dma_dev, dma_data->dma_rx.channel); + return ret; +} + +#ifdef CONFIG_SPI_ASYNC +static int transceive_dma_async(const struct device *dev, spi_callback_t cb, void *userdata) +{ + struct spi_mcux_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + size_t dma_size; + int ret; + + ctx->asynchronous = true; + ctx->callback = cb; + ctx->callback_data = userdata; + + ret = spi_mcux_dma_rxtx_load(dev, &dma_size); + if (ret) { + return ret; + } + + /* Enable DMA Requests */ + LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); + + return 0; +} +#else +#define transceive_dma_async(...) 0 +#endif /* CONFIG_SPI_ASYNC */ + +static int transceive_dma_sync(const struct device *dev) +{ + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + struct spi_mcux_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + size_t dma_size; + int ret; + + spi_context_cs_control(ctx, true); + + /* Send each spi buf via DMA, updating context as DMA completes */ + while (ctx->rx_len > 0 || ctx->tx_len > 0) { + /* Load dma block */ + ret = spi_mcux_dma_rxtx_load(dev, &dma_size); + if (ret) { + return ret; + } + +#ifdef CONFIG_SOC_SERIES_MCXN + while (!(LPSPI_GetStatusFlags(base) & kLPSPI_TxDataRequestFlag)) { + /* wait until previous tx finished */ + } +#endif + + /* Enable DMA Requests */ + LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); + + /* Wait for DMA to finish */ + ret = wait_dma_rx_tx_done(dev); + if (ret) { + return ret; + } + +#ifndef CONFIG_SOC_SERIES_MCXN + while ((LPSPI_GetStatusFlags(base) & kLPSPI_ModuleBusyFlag)) { + /* wait until module is idle */ + } +#endif + + /* Disable DMA */ + LPSPI_DisableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); + + /* Update SPI contexts with amount of data we just sent */ + spi_context_update_tx(ctx, 1, dma_size); + spi_context_update_rx(ctx, 1, dma_size); + } + + spi_context_cs_control(ctx, false); + + base->TCR = 0; + + return 0; +} + +static int transceive_dma(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, + bool asynchronous, spi_callback_t cb, void *userdata) +{ + struct spi_mcux_data *data = dev->data; + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + int ret; + + if (!asynchronous) { + spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); + } + + ret = spi_mcux_configure(dev, spi_cfg); + if (ret && !asynchronous) { + goto out; + } else if (ret) { + return ret; + } + +#ifdef CONFIG_SOC_SERIES_MCXN + base->TCR |= LPSPI_TCR_CONT_MASK; +#endif + + /* DMA is fast enough watermarks are not required */ + LPSPI_SetFifoWatermarks(base, 0U, 0U); + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + if (asynchronous) { + ret = transceive_dma_async(dev, cb, userdata); + } else { + ret = transceive_dma_sync(dev); + } + +out: + spi_context_release(&data->ctx, ret); + return ret; +} + +static int lpspi_dma_dev_ready(const struct device *dma_dev) +{ + if (!device_is_ready(dma_dev)) { + LOG_ERR("%s device is not ready", dma_dev->name); + return -ENODEV; + } + + return 0; +} + +static int lpspi_dma_devs_ready(struct spi_mcux_data *data) +{ + struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; + + return lpspi_dma_dev_ready(dma_data->dma_tx.dma_dev) | + lpspi_dma_dev_ready(dma_data->dma_rx.dma_dev); +} + +static int spi_mcux_dma_init(const struct device *dev) +{ + struct spi_mcux_data *data = dev->data; + int err = 0; + + err = lpspi_dma_devs_ready(data); + if (err < 0) { + return err; + } + + err = spi_nxp_init_common(dev); + if (err) { + return err; + } + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static int spi_nxp_dma_transceive_sync(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); +} + +#ifdef CONFIG_SPI_ASYNC +static int spi_nxp_dma_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, spi_callback_t cb, + void *userdata) +{ + return transceive_dma(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif /* CONFIG_SPI_ASYNC */ + +static DEVICE_API(spi, spi_mcux_driver_api) = { + .transceive = spi_nxp_dma_transceive_sync, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = spi_nxp_dma_transceive_async, +#endif +#ifdef CONFIG_SPI_RTIO + .iodev_submit = spi_rtio_iodev_default_submit, +#endif + .release = spi_mcux_release, +}; + +static void lpspi_isr(const struct device *dev) +{ + /* ISR not used for DMA based LPSPI driver */ +} + +#define SPI_DMA_CHANNELS(n) \ + IF_ENABLED( \ + DT_INST_DMAS_HAS_NAME(n, tx), \ + (.dma_tx = {.dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, tx)), \ + .channel = DT_INST_DMAS_CELL_BY_NAME(n, tx, mux), \ + .dma_cfg = {.channel_direction = MEMORY_TO_PERIPHERAL, \ + .dma_callback = spi_mcux_dma_callback, \ + .source_data_size = 1, \ + .dest_data_size = 1, \ + .block_count = 1, \ + .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, tx, source)}},)) \ + IF_ENABLED( \ + DT_INST_DMAS_HAS_NAME(n, rx), \ + (.dma_rx = {.dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, rx)), \ + .channel = DT_INST_DMAS_CELL_BY_NAME(n, rx, mux), \ + .dma_cfg = {.channel_direction = PERIPHERAL_TO_MEMORY, \ + .dma_callback = spi_mcux_dma_callback, \ + .source_data_size = 1, \ + .dest_data_size = 1, \ + .block_count = 1, \ + .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, rx, source)}},)) + +#define LPSPI_DMA_INIT(n) \ + SPI_NXP_LPSPI_COMMON_INIT(n) \ + SPI_MCUX_LPSPI_CONFIG_INIT(n) \ + \ + static struct spi_nxp_dma_data lpspi_dma_data##n = {SPI_DMA_CHANNELS(n)}; \ + \ + static struct spi_mcux_data spi_mcux_data_##n = {.driver_data = &lpspi_dma_data##n, \ + SPI_NXP_LPSPI_COMMON_DATA_INIT(n)}; \ + \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_mcux_dma_init, NULL, &spi_mcux_data_##n, \ + &spi_mcux_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &spi_mcux_driver_api); + +#define SPI_NXP_LPSPI_DMA_INIT(n) IF_ENABLED(SPI_NXP_LPSPI_HAS_DMAS(n), (LPSPI_DMA_INIT(n))) + +DT_INST_FOREACH_STATUS_OKAY(SPI_NXP_LPSPI_DMA_INIT) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h new file mode 100644 index 0000000000000..5108f6ebbc9c1 --- /dev/null +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h @@ -0,0 +1,128 @@ +/* + * Copyright 2018, 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "../spi_context.h" + +#if CONFIG_NXP_LP_FLEXCOMM +#include +#endif + +#include + +/* If any hardware revisions change this, make it into a DT property. + * DONT'T make #ifdefs here by platform. + */ +#define LPSPI_CHIP_SELECT_COUNT 4 +#define LPSPI_MIN_FRAME_SIZE_BITS 8 + +/* Required by DEVICE_MMIO_NAMED_* macros */ +#define DEV_CFG(_dev) ((const struct spi_mcux_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct spi_mcux_data *)(_dev)->data) + +/* flag for SDK API for master transfers */ +#define LPSPI_MASTER_XFER_CFG_FLAGS(slave) \ + kLPSPI_MasterPcsContinuous | (slave << LPSPI_MASTER_PCS_SHIFT) + +struct spi_mcux_config { + DEVICE_MMIO_NAMED_ROM(reg_base); + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + void (*irq_config_func)(const struct device *dev); + uint32_t pcs_sck_delay; + uint32_t sck_pcs_delay; + uint32_t transfer_delay; + const struct pinctrl_dev_config *pincfg; + lpspi_pin_config_t data_pin_config; + bool output_config; + uint8_t tx_fifo_size; + uint8_t rx_fifo_size; + uint8_t irqn; +}; + +struct spi_mcux_data { + DEVICE_MMIO_NAMED_RAM(reg_base); + const struct device *dev; + struct spi_context ctx; + void *driver_data; + size_t transfer_len; +}; + +/* common configure function that verifies spi_cfg validity and set up configuration parameters */ +int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cfg); + +/* Does these things: + * Set data.dev + * Check clocks device is ready + * Configure cs gpio pin if needed + * Mux pinctrl to lpspi + * Enable LPSPI IRQ at system level + */ +int spi_nxp_init_common(const struct device *dev); + +/* common api function for now */ +int spi_mcux_release(const struct device *dev, const struct spi_config *spi_cfg); + +/* Argument to MCUX SDK IRQ handler */ +#define LPSPI_IRQ_HANDLE_ARG COND_CODE_1(CONFIG_NXP_LP_FLEXCOMM, (LPSPI_GetInstance(base)), (base)) + +#define SPI_MCUX_LPSPI_IRQ_FUNC_LP_FLEXCOMM(n) \ + nxp_lp_flexcomm_setirqhandler(DEVICE_DT_GET(DT_INST_PARENT(n)), DEVICE_DT_INST_GET(n), \ + LP_FLEXCOMM_PERIPH_LPSPI, lpspi_isr); + +#define SPI_MCUX_LPSPI_IRQ_FUNC_DISTINCT(n) \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), lpspi_isr, DEVICE_DT_INST_GET(n), \ + 0); \ + irq_enable(DT_INST_IRQN(n)); + +#define SPI_MCUX_LPSPI_IRQ_FUNC(n) COND_CODE_1(DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), \ + nxp_lp_flexcomm), \ + (SPI_MCUX_LPSPI_IRQ_FUNC_LP_FLEXCOMM(n)), \ + (SPI_MCUX_LPSPI_IRQ_FUNC_DISTINCT(n))) + +#define LPSPI_IRQN(n) COND_CODE_1(DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), nxp_lp_flexcomm), \ + (DT_IRQN(DT_INST_PARENT(n))), (DT_INST_IRQN(n))) + +#define SPI_MCUX_LPSPI_CONFIG_INIT(n) \ + static const struct spi_mcux_config spi_mcux_config_##n = { \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ + .irq_config_func = spi_mcux_config_func_##n, \ + .pcs_sck_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, pcs_sck_delay), \ + DT_INST_PROP(n, pcs_sck_delay)), \ + .sck_pcs_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, sck_pcs_delay), \ + DT_INST_PROP(n, sck_pcs_delay)), \ + .transfer_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, transfer_delay), \ + DT_INST_PROP(n, transfer_delay)), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .data_pin_config = DT_INST_ENUM_IDX(n, data_pin_config), \ + .output_config = DT_INST_PROP(n, tristate_output), \ + .rx_fifo_size = (uint8_t)DT_INST_PROP(n, rx_fifo_size), \ + .tx_fifo_size = (uint8_t)DT_INST_PROP(n, tx_fifo_size), \ + .irqn = (uint8_t)LPSPI_IRQN(n), \ + }; + +#define SPI_NXP_LPSPI_COMMON_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static void spi_mcux_config_func_##n(const struct device *dev) \ + { \ + SPI_MCUX_LPSPI_IRQ_FUNC(n) \ + } + +#define SPI_NXP_LPSPI_COMMON_DATA_INIT(n) \ + SPI_CONTEXT_INIT_LOCK(spi_mcux_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_mcux_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) + +#define SPI_NXP_LPSPI_HAS_DMAS(n) \ + UTIL_AND(DT_INST_DMAS_HAS_NAME(n, tx), DT_INST_DMAS_HAS_NAME(n, rx)) diff --git a/drivers/spi/spi_nxp_s32.c b/drivers/spi/spi_nxp_s32.c index 5f0236f86432d..48445335c760c 100644 --- a/drivers/spi/spi_nxp_s32.c +++ b/drivers/spi/spi_nxp_s32.c @@ -703,7 +703,7 @@ static DEVICE_API(spi, spi_nxp_s32_driver_api) = { SPI_CONTEXT_INIT_SYNC(spi_nxp_s32_data_##n, ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ }; \ - DEVICE_DT_INST_DEFINE(n, \ + SPI_DEVICE_DT_INST_DEFINE(n, \ spi_nxp_s32_init, NULL, \ &spi_nxp_s32_data_##n, &spi_nxp_s32_config_##n, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ diff --git a/drivers/spi/spi_oc_simple.c b/drivers/spi/spi_oc_simple.c index 94febe5691fff..d3069366bf715 100644 --- a/drivers/spi/spi_oc_simple.c +++ b/drivers/spi/spi_oc_simple.c @@ -231,7 +231,7 @@ int spi_oc_simple_init(const struct device *dev) SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), ctx) \ }; \ \ - DEVICE_DT_INST_DEFINE(inst, \ + SPI_DEVICE_DT_INST_DEFINE(inst, \ spi_oc_simple_init, \ NULL, \ &spi_oc_simple_data_##inst, \ diff --git a/drivers/spi/spi_opentitan.c b/drivers/spi/spi_opentitan.c index fa8dc66f5d1c5..efcf4d0298c4f 100644 --- a/drivers/spi/spi_opentitan.c +++ b/drivers/spi/spi_opentitan.c @@ -323,7 +323,7 @@ static DEVICE_API(spi, spi_opentitan_api) = { .base = DT_INST_REG_ADDR(n), \ .f_input = DT_INST_PROP(n, clock_frequency), \ }; \ - DEVICE_DT_INST_DEFINE(n, \ + SPI_DEVICE_DT_INST_DEFINE(n, \ spi_opentitan_init, \ NULL, \ &spi_opentitan_data_##n, \ diff --git a/drivers/spi/spi_pl022.c b/drivers/spi/spi_pl022.c index 82632e8040d65..375b4df468145 100644 --- a/drivers/spi/spi_pl022.c +++ b/drivers/spi/spi_pl022.c @@ -1031,7 +1031,7 @@ static int spi_pl022_init(const struct device *dev) (.dma_enabled = false,)) \ IF_ENABLED(CONFIG_SPI_PL022_INTERRUPT, \ (.irq_config = spi_pl022_irq_config_##idx,))}; \ - DEVICE_DT_INST_DEFINE(idx, spi_pl022_init, NULL, &spi_pl022_data_##idx, \ + SPI_DEVICE_DT_INST_DEFINE(idx, spi_pl022_init, NULL, &spi_pl022_data_##idx, \ &spi_pl022_cfg_##idx, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &spi_pl022_api); diff --git a/drivers/spi/spi_psoc6.c b/drivers/spi/spi_psoc6.c index 35b2af8eb73e8..cfbc2880d7f8b 100644 --- a/drivers/spi/spi_psoc6.c +++ b/drivers/spi/spi_psoc6.c @@ -430,7 +430,7 @@ static DEVICE_API(spi, spi_psoc6_driver_api) = { SPI_CONTEXT_INIT_SYNC(spi_psoc6_dev_data_##n, ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ }; \ - DEVICE_DT_INST_DEFINE(n, spi_psoc6_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_psoc6_init, NULL, \ &spi_psoc6_dev_data_##n, \ &spi_psoc6_config_##n, POST_KERNEL, \ CONFIG_SPI_INIT_PRIORITY, \ diff --git a/drivers/spi/spi_pw.c b/drivers/spi/spi_pw.c index 671a0483516d0..aa8f2828927af 100644 --- a/drivers/spi/spi_pw.c +++ b/drivers/spi/spi_pw.c @@ -871,7 +871,7 @@ static int spi_pw_init(const struct device *dev) .clock_freq = DT_INST_PROP(n, clock_frequency), \ INIT_PCIE(n) \ }; \ - DEVICE_DT_INST_DEFINE(n, spi_pw_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_pw_init, NULL, \ &spi_##n##_data, &spi_##n##_config, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &pw_spi_api); @@ -891,7 +891,7 @@ static int spi_pw_init(const struct device *dev) .clock_freq = DT_INST_PROP(n, clock_frequency), \ INIT_PCIE(n) \ }; \ - DEVICE_DT_INST_DEFINE(n, spi_pw_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_pw_init, NULL, \ &spi_##n##_data, &spi_##n##_config, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &pw_spi_api); diff --git a/drivers/spi/spi_rpi_pico_pio.c b/drivers/spi/spi_rpi_pico_pio.c index b3d89ad0ef3d1..1da7cc33cfa5e 100644 --- a/drivers/spi/spi_rpi_pico_pio.c +++ b/drivers/spi/spi_rpi_pico_pio.c @@ -68,6 +68,22 @@ RPI_PICO_PIO_DEFINE_PROGRAM(spi_mode_0_0, SPI_MODE_0_0_WRAP_TARGET, SPI_MODE_0_0 /* .wrap */ ); +/* ------------ */ +/* spi_mode_0_1 */ +/* ------------ */ + +#define SPI_MODE_0_1_WRAP_TARGET 0 +#define SPI_MODE_0_1_WRAP 2 +#define SPI_MODE_0_1_CYCLES 4 + +RPI_PICO_PIO_DEFINE_PROGRAM(spi_mode_0_1, SPI_MODE_0_1_WRAP_TARGET, SPI_MODE_0_1_WRAP, + /* .wrap_target */ + 0x6021, /* 0: out x, 1 side 0 */ + 0xb101, /* 1: mov pins, x side 1 [1] */ + 0x4001, /* 2: in pins, 1 side 0 */ + /* .wrap */ +); + /* ------------ */ /* spi_mode_1_1 */ /* ------------ */ @@ -365,8 +381,13 @@ static int spi_pico_pio_configure(const struct spi_pico_pio_config *dev_cfg, wrap_target = RPI_PICO_PIO_GET_WRAP_TARGET(spi_mode_1_1); wrap = RPI_PICO_PIO_GET_WRAP(spi_mode_1_1); cycles = SPI_MODE_1_1_CYCLES; + } else if ((cpol == 0) && (cpha == 1)) { + program = RPI_PICO_PIO_GET_PROGRAM(spi_mode_0_1); + wrap_target = RPI_PICO_PIO_GET_WRAP_TARGET(spi_mode_0_1); + wrap = RPI_PICO_PIO_GET_WRAP(spi_mode_0_1); + cycles = SPI_MODE_0_1_CYCLES; } else { - LOG_ERR("Not supported: cpol=%d, cpha=%d\n", cpol, cpha); + LOG_ERR("Not supported: cpol=%d, cpha=%d", cpol, cpha); return -ENOTSUP; } @@ -759,7 +780,7 @@ int spi_pico_pio_init(const struct device *dev) SPI_CONTEXT_INIT_LOCK(spi_pico_pio_data_##inst, spi_ctx), \ SPI_CONTEXT_INIT_SYNC(spi_pico_pio_data_##inst, spi_ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), spi_ctx)}; \ - DEVICE_DT_INST_DEFINE(inst, spi_pico_pio_init, NULL, &spi_pico_pio_data_##inst, \ + SPI_DEVICE_DT_INST_DEFINE(inst, spi_pico_pio_init, NULL, &spi_pico_pio_data_##inst, \ &spi_pico_pio_config_##inst, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ &spi_pico_pio_api); \ BUILD_ASSERT(DT_INST_NODE_HAS_PROP(inst, clk_gpios), "Missing clock GPIO"); \ diff --git a/drivers/spi/spi_rtio.c b/drivers/spi/spi_rtio.c index 975636a098ab4..ff12f3ea6b724 100644 --- a/drivers/spi/spi_rtio.c +++ b/drivers/spi/spi_rtio.c @@ -12,7 +12,7 @@ #include #include -LOG_MODULE_DECLARE(spi_rtio, CONFIG_SPI_LOG_LEVEL); +LOG_MODULE_REGISTER(spi_rtio, CONFIG_SPI_LOG_LEVEL); const struct rtio_iodev_api spi_iodev_api = { .submit = spi_iodev_submit, diff --git a/drivers/spi/spi_rv32m1_lpspi.c b/drivers/spi/spi_rv32m1_lpspi.c index 05ea490557345..16f5d52e7a4fa 100644 --- a/drivers/spi/spi_rv32m1_lpspi.c +++ b/drivers/spi/spi_rv32m1_lpspi.c @@ -330,7 +330,7 @@ static DEVICE_API(spi, spi_mcux_driver_api) = { SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ }; \ \ - DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, \ &spi_mcux_data_##n, \ &spi_mcux_config_##n, \ POST_KERNEL, \ diff --git a/drivers/spi/spi_sam.c b/drivers/spi/spi_sam.c index 7104ee2d257be..1ff399503c228 100644 --- a/drivers/spi/spi_sam.c +++ b/drivers/spi/spi_sam.c @@ -890,7 +890,7 @@ static DEVICE_API(spi, spi_sam_driver_api) = { SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ IF_ENABLED(CONFIG_SPI_RTIO, (.rtio_ctx = &spi_sam_rtio_##n)) \ }; \ - DEVICE_DT_INST_DEFINE(n, &spi_sam_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(n, &spi_sam_init, NULL, \ &spi_sam_dev_data_##n, \ &spi_sam_config_##n, POST_KERNEL, \ CONFIG_SPI_INIT_PRIORITY, &spi_sam_driver_api); diff --git a/drivers/spi/spi_sam0.c b/drivers/spi/spi_sam0.c index 207312dda9e6c..6dd2d64fad5b5 100644 --- a/drivers/spi/spi_sam0.c +++ b/drivers/spi/spi_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +10,8 @@ #include LOG_MODULE_REGISTER(spi_sam0); +/* clang-format off */ + #include "spi_context.h" #include #include @@ -27,14 +30,12 @@ struct spi_sam0_config { SercomSpi *regs; uint32_t pads; const struct pinctrl_dev_config *pcfg; -#ifdef MCLK + volatile uint32_t *mclk; uint32_t mclk_mask; - uint16_t gclk_core_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif + uint32_t gclk_gen; + uint16_t gclk_id; + #ifdef CONFIG_SPI_ASYNC const struct device *dma_dev; uint8_t tx_dma_request; @@ -645,20 +646,15 @@ static int spi_sam0_init(const struct device *dev) struct spi_sam0_data *data = dev->data; SercomSpi *regs = cfg->regs; -#ifdef MCLK - /* Enable the GCLK */ - GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 | - GCLK_PCHCTRL_CHEN; - - /* Enable the MCLK */ *cfg->mclk |= cfg->mclk_mask; -#else - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - /* Enable SERCOM clock in PM */ - PM->APBCMASK.reg |= cfg->pm_apbcmask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif /* Disable all SPI interrupts */ @@ -717,13 +713,17 @@ static DEVICE_API(spi, spi_sam0_driver_api) = { SERCOM_SPI_CTRLA_DIPO(DT_INST_PROP(n, dipo)) | \ SERCOM_SPI_CTRLA_DOPO(DT_INST_PROP(n, dopo)) +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + #ifdef MCLK #define SPI_SAM0_DEFINE_CONFIG(n) \ static const struct spi_sam0_config spi_sam0_config_##n = { \ .regs = (SercomSpi *)DT_INST_REG_ADDR(n), \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .pads = SPI_SAM0_SERCOM_PADS(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ SPI_SAM0_DMA_CHANNELS(n) \ @@ -732,8 +732,10 @@ static const struct spi_sam0_config spi_sam0_config_##n = { \ #define SPI_SAM0_DEFINE_CONFIG(n) \ static const struct spi_sam0_config spi_sam0_config_##n = { \ .regs = (SercomSpi *)DT_INST_REG_ADDR(n), \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .pads = SPI_SAM0_SERCOM_PADS(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ SPI_SAM0_DMA_CHANNELS(n) \ @@ -748,10 +750,12 @@ static const struct spi_sam0_config spi_sam0_config_##n = { \ SPI_CONTEXT_INIT_SYNC(spi_sam0_dev_data_##n, ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ }; \ - DEVICE_DT_INST_DEFINE(n, spi_sam0_init, NULL, \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_sam0_init, NULL, \ &spi_sam0_dev_data_##n, \ &spi_sam0_config_##n, POST_KERNEL, \ CONFIG_SPI_INIT_PRIORITY, \ &spi_sam0_driver_api); DT_INST_FOREACH_STATUS_OKAY(SPI_SAM0_DEVICE_INIT) + +/* clang-format on */ diff --git a/drivers/spi/spi_sedi.c b/drivers/spi/spi_sedi.c index 35639c1e1ef4e..ed4c2b5cc01e4 100644 --- a/drivers/spi/spi_sedi.c +++ b/drivers/spi/spi_sedi.c @@ -406,10 +406,10 @@ static int spi_sedi_device_ctrl(const struct device *dev, DEVICE_MMIO_ROM_INIT(DT_DRV_INST(num)), \ .spi_device = num, .irq_config = spi_##num##_irq_init, \ }; \ - PM_DEVICE_DEFINE(spi_##num, spi_sedi_device_ctrl); \ - DEVICE_DT_INST_DEFINE(num, \ + PM_DEVICE_DT_INST_DEFINE(spi_##num, spi_sedi_device_ctrl); \ + SPI_DEVICE_DT_INST_DEFINE(num, \ spi_sedi_init, \ - PM_DEVICE_GET(spi_##num), \ + PM_DEVICE_DT_INST_GET(spi_##num), \ &spi_##num##_data, \ &spi_##num##_config, \ POST_KERNEL, \ diff --git a/drivers/spi/spi_shell.c b/drivers/spi/spi_shell.c index 0c2c11af3f7fa..9ca6bc5bffb04 100644 --- a/drivers/spi/spi_shell.c +++ b/drivers/spi/spi_shell.c @@ -17,6 +17,10 @@ #define CONF_ARGV_FREQUENCY (2) #define CONF_ARGV_SETTINGS (3) +#define CS_ARGV_GPIO_DEV (1) +#define CS_ARGV_GPIO_PIN (2) +#define CS_ARGV_GPIO_FLAGS (3) + /* Maximum bytes we can write and read at once */ #define MAX_SPI_BYTES MIN((CONFIG_SHELL_ARGC_MAX - TXRX_ARGV_BYTES), 32) @@ -24,9 +28,14 @@ static struct device *spi_device; static struct spi_config config = {.frequency = 1000000, .operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8)}; +static bool device_is_spi(const struct device *dev) +{ + return DEVICE_API_IS(spi, dev); +} + static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, "spi"); + const struct device *dev = shell_device_filter(idx, device_is_spi); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; @@ -80,7 +89,7 @@ static int cmd_spi_conf(const struct shell *ctx, size_t argc, char **argv) /* warning: initialization discards 'const' qualifier from pointer */ /* target type */ - struct device *dev = (struct device *)device_get_binding(argv[CONF_ARGV_DEV]); + struct device *dev = (struct device *)shell_device_get_binding(argv[CONF_ARGV_DEV]); if (dev == NULL) { shell_error(ctx, "device %s not found.", argv[CONF_ARGV_DEV]); @@ -135,6 +144,41 @@ static int cmd_spi_conf(const struct shell *ctx, size_t argc, char **argv) return 0; } +static int cmd_spi_conf_cs(const struct shell *ctx, size_t argc, char **argv) +{ + struct device *dev = (struct device *)shell_device_get_binding(argv[CS_ARGV_GPIO_DEV]); + char *endptr = NULL; + + if (dev == NULL) { + shell_error(ctx, "device %s not found.", argv[CS_ARGV_GPIO_DEV]); + return -ENODEV; + } + + int pin = strtol(argv[CS_ARGV_GPIO_PIN], &endptr, 10); + + if (endptr == argv[CS_ARGV_GPIO_PIN] || (pin < 0)) { + shell_error(ctx, "invalid pin number: %s", argv[CS_ARGV_GPIO_PIN]); + return -EINVAL; + } + + config.cs.gpio.port = dev; + config.cs.gpio.pin = pin; + + /* Include flags if provided */ + if (argc == (CS_ARGV_GPIO_FLAGS + 1)) { + uint32_t flags = strtol(argv[CS_ARGV_GPIO_FLAGS], &endptr, 16); + + if (endptr == argv[CS_ARGV_GPIO_FLAGS]) { + shell_error(ctx, "invalid gpio flags: %s", argv[CS_ARGV_GPIO_FLAGS]); + return -EINVAL; + } + + config.cs.gpio.dt_flags = flags; + } + + return 0; +} + SHELL_STATIC_SUBCMD_SET_CREATE(sub_spi_cmds, SHELL_CMD_ARG(conf, &dsub_device_name, "Configure SPI\n" @@ -146,6 +190,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_spi_cmds, "T - SPI_FRAME_FORMAT_TI\n" "example: spi conf spi1 1000000 ol", cmd_spi_conf, 3, 1), + SHELL_CMD_ARG(cs, &dsub_device_name, + "Assign CS GPIO to SPI device\n" + "Usage: spi cs []" + "example: spi conf gpio1 3 0x01", + cmd_spi_conf_cs, 3, 1), SHELL_CMD_ARG(transceive, NULL, "Transceive data to and from an SPI device\n" "Usage: spi transceive [ ...]", diff --git a/drivers/spi/spi_sifive.c b/drivers/spi/spi_sifive.c index afaba024a380a..fa6121d316f58 100644 --- a/drivers/spi/spi_sifive.c +++ b/drivers/spi/spi_sifive.c @@ -292,7 +292,7 @@ static DEVICE_API(spi, spi_sifive_api) = { .f_sys = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY, \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ }; \ - DEVICE_DT_INST_DEFINE(n, \ + SPI_DEVICE_DT_INST_DEFINE(n, \ spi_sifive_init, \ NULL, \ &spi_sifive_data_##n, \ diff --git a/drivers/spi/spi_silabs_eusart.c b/drivers/spi/spi_silabs_eusart.c new file mode 100644 index 0000000000000..947265d101861 --- /dev/null +++ b/drivers/spi/spi_silabs_eusart.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2024 Daikin Comfort Technologies North America, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT silabs_eusart_spi + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +LOG_MODULE_REGISTER(spi_silabs_eusart, CONFIG_SPI_LOG_LEVEL); + +#include "spi_context.h" + +#define SPI_WORD_SIZE 8 + +/* Structure Declarations */ + +struct spi_silabs_eusart_data { + struct spi_context ctx; +}; + +struct spi_silabs_eusart_config { + EUSART_TypeDef *base; + const struct device *clock_dev; + const struct silabs_clock_control_cmu_config clock_cfg; + uint32_t clock_frequency; + const struct pinctrl_dev_config *pcfg; +}; + +/* Helper Functions */ +static int spi_silabs_eusart_configure(const struct device *dev, const struct spi_config *config, + uint16_t *control) +{ + struct spi_silabs_eusart_data *data = dev->data; + const struct spi_silabs_eusart_config *eusart_config = dev->config; + uint32_t spi_frequency; + + EUSART_SpiAdvancedInit_TypeDef eusartAdvancedSpiInit = EUSART_SPI_ADVANCED_INIT_DEFAULT; + EUSART_SpiInit_TypeDef eusartInit = EUSART_SPI_MASTER_INIT_DEFAULT_HF; + + int err; + + err = clock_control_get_rate(eusart_config->clock_dev, + (clock_control_subsys_t)&eusart_config->clock_cfg, + &spi_frequency); + if (err) { + return err; + } + /* Max supported SPI frequency is half the source clock */ + spi_frequency /= 2; + + if (spi_context_configured(&data->ctx, config)) { + /* Already configured. No need to do it again, but must re-enable in case + * TXEN/RXEN were cleared due to deep sleep. + */ + EUSART_Enable(eusart_config->base, eusartEnable); + + return 0; + } + + if (config->operation & SPI_HALF_DUPLEX) { + LOG_ERR("Half-duplex not supported"); + return -ENOTSUP; + } + + if (SPI_WORD_SIZE_GET(config->operation) != SPI_WORD_SIZE) { + LOG_ERR("Word size must be %d", SPI_WORD_SIZE); + return -ENOTSUP; + } + + if (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES) && + (config->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { + LOG_ERR("Only supports single mode"); + return -ENOTSUP; + } + + if (config->operation & SPI_OP_MODE_SLAVE) { + LOG_ERR("Slave mode not supported"); + return -ENOTSUP; + } + + /* Set frequency to the minimum of what the device supports, what the + * user has configured the controller to, and the max frequency for the + * transaction. + */ + if (eusart_config->clock_frequency > spi_frequency) { + LOG_ERR("SPI clock-frequency too high"); + return -EINVAL; + } + spi_frequency = MIN(eusart_config->clock_frequency, spi_frequency); + if (config->frequency) { + spi_frequency = MIN(config->frequency, spi_frequency); + } + eusartInit.bitRate = spi_frequency; + + if (config->operation & SPI_MODE_LOOP) { + eusartInit.loopbackEnable = eusartLoopbackEnable; + } else { + eusartInit.loopbackEnable = eusartLoopbackDisable; + } + + /* Set Clock Mode */ + if (config->operation & SPI_MODE_CPOL) { + if (config->operation & SPI_MODE_CPHA) { + eusartInit.clockMode = eusartClockMode3; + } else { + eusartInit.clockMode = eusartClockMode2; + } + } else { + if (config->operation & SPI_MODE_CPHA) { + eusartInit.clockMode = eusartClockMode1; + } else { + eusartInit.clockMode = eusartClockMode0; + } + } + + if (config->operation & SPI_CS_ACTIVE_HIGH) { + eusartAdvancedSpiInit.csPolarity = eusartCsActiveHigh; + } else { + eusartAdvancedSpiInit.csPolarity = eusartCsActiveLow; + } + + eusartAdvancedSpiInit.msbFirst = !(config->operation & SPI_TRANSFER_LSB); + eusartAdvancedSpiInit.autoCsEnable = !spi_cs_is_gpio(config); + eusartInit.databits = eusartDataBits8; + eusartInit.advancedSettings = &eusartAdvancedSpiInit; + + /* Enable EUSART clock */ + err = clock_control_on(eusart_config->clock_dev, + (clock_control_subsys_t)&eusart_config->clock_cfg); + if (err < 0) { + return err; + } + + /* Initialize the EUSART */ + EUSART_SpiInit(eusart_config->base, &eusartInit); + + data->ctx.config = config; + + return 0; +} + +static void spi_silabs_eusart_send(EUSART_TypeDef *eusart, uint8_t frame) +{ + /* Write frame to register */ + EUSART_Tx(eusart, frame); + + /* Wait until the transfer ends */ + while (!(eusart->STATUS & EUSART_STATUS_TXC)) { + } +} + +static uint8_t spi_silabs_eusart_recv(EUSART_TypeDef *eusart) +{ + /* Return data inside rx register */ + return EUSART_Rx(eusart); +} + +static bool spi_silabs_eusart_transfer_ongoing(struct spi_silabs_eusart_data *data) +{ + return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); +} + +static inline uint8_t spi_silabs_eusart_next_tx(struct spi_silabs_eusart_data *data) +{ + uint8_t tx_frame = 0; + + if (spi_context_tx_buf_on(&data->ctx)) { + tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)); + } + + return tx_frame; +} + +static int spi_silabs_eusart_shift_frames(EUSART_TypeDef *eusart, + struct spi_silabs_eusart_data *data) +{ + uint8_t tx_frame; + uint8_t rx_frame; + + tx_frame = spi_silabs_eusart_next_tx(data); + spi_silabs_eusart_send(eusart, tx_frame); + spi_context_update_tx(&data->ctx, 1, 1); + + rx_frame = spi_silabs_eusart_recv(eusart); + + if (spi_context_rx_buf_on(&data->ctx)) { + UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf); + } + spi_context_update_rx(&data->ctx, 1, 1); + return 0; +} + +static void spi_silabs_eusart_xfer(const struct device *dev, const struct spi_config *config) +{ + int ret; + struct spi_silabs_eusart_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + const struct spi_silabs_eusart_config *eusart_config = dev->config; + + spi_context_cs_control(ctx, true); + + do { + ret = spi_silabs_eusart_shift_frames(eusart_config->base, data); + } while (!ret && spi_silabs_eusart_transfer_ongoing(data)); + + spi_context_cs_control(ctx, false); + spi_context_complete(ctx, dev, 0); +} + +/* API Functions */ +static int spi_silabs_eusart_init(const struct device *dev) +{ + int err; + const struct spi_silabs_eusart_config *eusart_config = dev->config; + struct spi_silabs_eusart_data *data = dev->data; + + err = pinctrl_apply_state(eusart_config->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + err = spi_context_cs_configure_all(&data->ctx); + if (err < 0) { + return err; + } + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static int spi_silabs_eusart_transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + struct spi_silabs_eusart_data *data = dev->data; + uint16_t control = 0; + int ret; + + spi_context_lock(&data->ctx, false, NULL, NULL, config); + + ret = spi_silabs_eusart_configure(dev, config, &control); + if (ret < 0) { + spi_context_release(&data->ctx, ret); + return ret; + } + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + spi_silabs_eusart_xfer(dev, config); + + spi_context_release(&data->ctx, ret); + + return 0; +} + +#ifdef CONFIG_SPI_ASYNC +static int spi_silabs_eusart_transceive_async(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + struct k_poll_signal *async) +{ + return -ENOTSUP; +} +#endif /* CONFIG_SPI_ASYNC */ + +static int spi_silabs_eusart_release(const struct device *dev, const struct spi_config *config) +{ + const struct spi_silabs_eusart_config *eusart_config = dev->config; + struct spi_silabs_eusart_data *data = dev->data; + + spi_context_unlock_unconditionally(&data->ctx); + + if (!(eusart_config->base->STATUS & EUSART_STATUS_TXIDLE)) { + return -EBUSY; + } + return 0; +} + +/* Device Instantiation */ +static DEVICE_API(spi, spi_silabs_eusart_api) = { + .transceive = spi_silabs_eusart_transceive, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = spi_silabs_eusart_transceive_async, +#endif /* CONFIG_SPI_ASYNC */ + .release = spi_silabs_eusart_release, +}; + +#define SPI_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct spi_silabs_eusart_data spi_silabs_eusart_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(spi_silabs_eusart_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_silabs_eusart_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)}; \ + static struct spi_silabs_eusart_config spi_silabs_eusart_cfg_##n = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .base = (EUSART_TypeDef *)DT_INST_REG_ADDR(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_cfg = SILABS_DT_INST_CLOCK_CFG(n), \ + .clock_frequency = DT_INST_PROP_OR(n, clock_frequency, 1000000) \ + }; \ + SPI_DEVICE_DT_INST_DEFINE(n, spi_silabs_eusart_init, NULL, &spi_silabs_eusart_data_##n, \ + &spi_silabs_eusart_cfg_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,\ + &spi_silabs_eusart_api); + +DT_INST_FOREACH_STATUS_OKAY(SPI_INIT) diff --git a/drivers/spi/spi_silabs_usart.c b/drivers/spi/spi_silabs_usart.c new file mode 100644 index 0000000000000..1c7e0365956b2 --- /dev/null +++ b/drivers/spi/spi_silabs_usart.c @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2019 Christian Taedcke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT silabs_usart_spi + +#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL +#include +LOG_MODULE_REGISTER(spi_silabs_usart); +#include "spi_context.h" + +#include +#include +#include +#include +#include + +#include "em_cmu.h" +#include "em_usart.h" + +#include + +#ifdef CONFIG_PINCTRL +#include +#else +#ifndef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION +#error "Individual pin location support is required" +#endif +#endif /* CONFIG_PINCTRL */ + +#ifdef CONFIG_CLOCK_CONTROL +#include +#include +#define GET_USART_CLOCK(idx) \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ + .clock_cfg = SILABS_DT_INST_CLOCK_CFG(idx), +#elif DT_NODE_HAS_PROP(n, peripheral_id) +#define CLOCK_USART(id) _CONCAT(cmuClock_USART, id) +#define GET_USART_CLOCK(n) \ + .clock = CLOCK_USART(DT_INST_PROP(n, peripheral_id)), +#else +#if (USART_COUNT == 1) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : -1) +#elif (USART_COUNT == 2) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : -1) +#elif (USART_COUNT == 3) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : ((ref) == USART2) ? cmuClock_USART2 \ + : -1) +#elif (USART_COUNT == 4) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : ((ref) == USART2) ? cmuClock_USART2 \ + : ((ref) == USART3) ? cmuClock_USART3 \ + : -1) +#elif (USART_COUNT == 5) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : ((ref) == USART2) ? cmuClock_USART2 \ + : ((ref) == USART3) ? cmuClock_USART3 \ + : ((ref) == USART4) ? cmuClock_USART4 \ + : -1) +#elif (USART_COUNT == 6) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : ((ref) == USART2) ? cmuClock_USART2 \ + : ((ref) == USART3) ? cmuClock_USART3 \ + : ((ref) == USART4) ? cmuClock_USART4 \ + : ((ref) == USART5) ? cmuClock_USART5 \ + : -1) +#else +#error "Undefined number of USARTs." +#endif /* USART_COUNT */ +#define GET_USART_CLOCK(id) \ + .clock = CLOCK_USART((USART_TypeDef *)DT_INST_REG_ADDR(id)), +#endif /* DT_NODE_HAS_PROP(n, peripheral_id) */ + + +#define SPI_WORD_SIZE 8 + +/* Structure Declarations */ + +struct spi_silabs_usart_data { + struct spi_context ctx; +}; + +struct spi_silabs_usart_config { + USART_TypeDef *base; +#ifdef CONFIG_CLOCK_CONTROL + const struct device *clock_dev; + const struct silabs_clock_control_cmu_config clock_cfg; +#else + CMU_Clock_TypeDef clock; +#endif + uint32_t clock_frequency; +#ifdef CONFIG_PINCTRL + const struct pinctrl_dev_config *pcfg; +#else + struct soc_gpio_pin pin_rx; + struct soc_gpio_pin pin_tx; + struct soc_gpio_pin pin_clk; + uint8_t loc_rx; + uint8_t loc_tx; + uint8_t loc_clk; +#endif /* CONFIG_PINCTRL */ +}; + + +/* Helper Functions */ +static int spi_config(const struct device *dev, + const struct spi_config *config, + uint16_t *control) +{ + const struct spi_silabs_usart_config *usart_config = dev->config; + struct spi_silabs_usart_data *data = dev->data; + mem_addr_t ctrl_reg = (mem_addr_t)&usart_config->base->CTRL; + uint32_t spi_frequency; + +#ifdef CONFIG_CLOCK_CONTROL + int err; + + err = clock_control_get_rate(usart_config->clock_dev, + (clock_control_subsys_t)&usart_config->clock_cfg, + &spi_frequency); + if (err) { + return err; + } + /* Max supported SPI frequency is half the source clock */ + spi_frequency /= 2; +#else + spi_frequency = CMU_ClockFreqGet(usart_config->clock) / 2; +#endif + + if (config->operation & SPI_HALF_DUPLEX) { + LOG_ERR("Half-duplex not supported"); + return -ENOTSUP; + } + + if (SPI_WORD_SIZE_GET(config->operation) != SPI_WORD_SIZE) { + LOG_ERR("Word size must be %d", SPI_WORD_SIZE); + return -ENOTSUP; + } + + if (config->operation & SPI_CS_ACTIVE_HIGH) { + sys_set_bit(ctrl_reg, _USART_CTRL_CSINV_SHIFT); + } else { + sys_clear_bit(ctrl_reg, _USART_CTRL_CSINV_SHIFT); + } + + if (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES) && + (config->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { + LOG_ERR("Only supports single mode"); + return -ENOTSUP; + } + + if (config->operation & SPI_TRANSFER_LSB) { + sys_clear_bit(ctrl_reg, _USART_CTRL_MSBF_SHIFT); + } else { + sys_set_bit(ctrl_reg, _USART_CTRL_MSBF_SHIFT); + } + + if (config->operation & SPI_OP_MODE_SLAVE) { + LOG_ERR("Slave mode not supported"); + return -ENOTSUP; + } + + /* Set frequency to the minimum of what the device supports, what the + * user has configured the controller to, and the max frequency for the + * transaction. + */ + if (usart_config->clock_frequency > spi_frequency) { + LOG_ERR("SPI clock-frequency too high"); + return -EINVAL; + } + spi_frequency = MIN(usart_config->clock_frequency, spi_frequency); + if (config->frequency) { + spi_frequency = MIN(config->frequency, spi_frequency); + } + USART_BaudrateSyncSet(usart_config->base, 0, spi_frequency); + + /* Set Loopback */ + if (config->operation & SPI_MODE_LOOP) { + usart_config->base->CTRL |= USART_CTRL_LOOPBK; + } else { + usart_config->base->CTRL &= ~USART_CTRL_LOOPBK; + } + + /* Set CPOL */ + if (config->operation & SPI_MODE_CPOL) { + usart_config->base->CTRL |= USART_CTRL_CLKPOL; + } else { + usart_config->base->CTRL &= ~USART_CTRL_CLKPOL; + } + + /* Set CPHA */ + if (config->operation & SPI_MODE_CPHA) { + usart_config->base->CTRL |= USART_CTRL_CLKPHA; + } else { + usart_config->base->CTRL &= ~USART_CTRL_CLKPHA; + } + + /* Set word size */ + usart_config->base->FRAME = usartDatabits8 + | USART_FRAME_STOPBITS_DEFAULT + | USART_FRAME_PARITY_DEFAULT; + + /* At this point, it's mandatory to set this on the context! */ + data->ctx.config = config; + + return 0; +} + +static void spi_silabs_usart_send(USART_TypeDef *usart, uint8_t frame) +{ + /* Write frame to register */ + USART_Tx(usart, frame); + + /* Wait until the transfer ends */ + while (!(usart->STATUS & USART_STATUS_TXC)) { + } +} + +static uint8_t spi_silabs_usart_recv(USART_TypeDef *usart) +{ + /* Return data inside rx register */ + return (uint8_t)usart->RXDATA; +} + +static bool spi_silabs_usart_transfer_ongoing(struct spi_silabs_usart_data *data) +{ + return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); +} + +static inline uint8_t spi_silabs_usart_next_tx(struct spi_silabs_usart_data *data) +{ + uint8_t tx_frame = 0; + + if (spi_context_tx_buf_on(&data->ctx)) { + tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)); + } + + return tx_frame; +} + +static int spi_silabs_usart_shift_frames(USART_TypeDef *usart, + struct spi_silabs_usart_data *data) +{ + uint8_t tx_frame; + uint8_t rx_frame; + + tx_frame = spi_silabs_usart_next_tx(data); + spi_silabs_usart_send(usart, tx_frame); + spi_context_update_tx(&data->ctx, 1, 1); + + rx_frame = spi_silabs_usart_recv(usart); + + if (spi_context_rx_buf_on(&data->ctx)) { + UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf); + } + spi_context_update_rx(&data->ctx, 1, 1); + return 0; +} + + +static void spi_silabs_usart_xfer(const struct device *dev, + const struct spi_config *config) +{ + int ret; + struct spi_silabs_usart_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + const struct spi_silabs_usart_config *usart_config = dev->config; + + spi_context_cs_control(ctx, true); + + do { + ret = spi_silabs_usart_shift_frames(usart_config->base, data); + } while (!ret && spi_silabs_usart_transfer_ongoing(data)); + + spi_context_cs_control(ctx, false); + spi_context_complete(ctx, dev, 0); +} + +#ifndef CONFIG_PINCTRL +static void spi_silabs_usart_init_pins(const struct device *dev) +{ + const struct spi_silabs_usart_config *config = dev->config; + + GPIO_PinModeSet(config->pin_rx.port, config->pin_rx.pin, + config->pin_rx.mode, config->pin_rx.out); + GPIO_PinModeSet(config->pin_tx.port, config->pin_tx.pin, + config->pin_tx.mode, config->pin_tx.out); + GPIO_PinModeSet(config->pin_clk.port, config->pin_clk.pin, + config->pin_clk.mode, config->pin_clk.out); + + /* disable all pins while configuring */ + config->base->ROUTEPEN = 0; + + config->base->ROUTELOC0 = + (config->loc_tx << _USART_ROUTELOC0_TXLOC_SHIFT) | + (config->loc_rx << _USART_ROUTELOC0_RXLOC_SHIFT) | + (config->loc_clk << _USART_ROUTELOC0_CLKLOC_SHIFT); + + config->base->ROUTELOC1 = _USART_ROUTELOC1_RESETVALUE; + + config->base->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN | + USART_ROUTEPEN_CLKPEN; +} +#endif /* !CONFIG_PINCTRL */ + + +/* API Functions */ + +static int spi_silabs_usart_init(const struct device *dev) +{ + int err; + const struct spi_silabs_usart_config *config = dev->config; + struct spi_silabs_usart_data *data = dev->data; + USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT; + + /* The peripheral and gpio clock are already enabled from soc and gpio + * driver + */ + + usartInit.enable = usartDisable; + usartInit.baudrate = 1000000; + usartInit.databits = usartDatabits8; + usartInit.master = 1; + usartInit.msbf = 1; + usartInit.clockMode = usartClockMode0; +#if defined(USART_INPUT_RXPRS) && defined(USART_TRIGCTRL_AUTOTXTEN) + usartInit.prsRxEnable = 0; + usartInit.prsRxCh = 0; + usartInit.autoTx = 0; +#endif + + /* Enable USART clock */ +#ifdef CONFIG_CLOCK_CONTROL + err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg); + if (err < 0) { + return err; + } +#else + CMU_ClockEnable(config->clock, true); +#endif + + /* Init USART */ + USART_InitSync(config->base, &usartInit); + +#ifdef CONFIG_PINCTRL + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } +#else + /* Initialize USART pins */ + spi_silabs_usart_init_pins(dev); +#endif /* CONFIG_PINCTRL */ + + err = spi_context_cs_configure_all(&data->ctx); + if (err < 0) { + return err; + } + + /* Enable the peripheral */ + config->base->CMD = (uint32_t) usartEnable; + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static int spi_silabs_usart_transceive(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + struct spi_silabs_usart_data *data = dev->data; + uint16_t control = 0; + int ret; + + spi_context_lock(&data->ctx, false, NULL, NULL, config); + + ret = spi_config(dev, config, &control); + if (ret < 0) { + spi_context_release(&data->ctx, ret); + return ret; + } + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + spi_silabs_usart_xfer(dev, config); + + spi_context_release(&data->ctx, ret); + + return 0; +} + +#ifdef CONFIG_SPI_ASYNC +static int spi_silabs_usart_transceive_async(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + struct k_poll_signal *async) +{ + return -ENOTSUP; +} +#endif /* CONFIG_SPI_ASYNC */ + +static int spi_silabs_usart_release(const struct device *dev, + const struct spi_config *config) +{ + struct spi_silabs_usart_data *data = dev->data; + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +/* Device Instantiation */ +static DEVICE_API(spi, spi_silabs_usart_api) = { + .transceive = spi_silabs_usart_transceive, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = spi_silabs_usart_transceive_async, +#endif /* CONFIG_SPI_ASYNC */ +#ifdef CONFIG_SPI_RTIO + .iodev_submit = spi_rtio_iodev_default_submit, +#endif + .release = spi_silabs_usart_release, +}; + +#ifdef CONFIG_PINCTRL +#define SPI_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct spi_silabs_usart_data spi_silabs_usart_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(spi_silabs_usart_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_silabs_usart_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ + }; \ + static struct spi_silabs_usart_config spi_silabs_usart_cfg_##n = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .base = (USART_TypeDef *) \ + DT_INST_REG_ADDR(n), \ + GET_USART_CLOCK(n) \ + .clock_frequency = DT_INST_PROP_OR(n, clock_frequency, 1000000) \ + }; \ + SPI_DEVICE_DT_INST_DEFINE(n, \ + spi_silabs_usart_init, \ + NULL, \ + &spi_silabs_usart_data_##n, \ + &spi_silabs_usart_cfg_##n, \ + POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, \ + &spi_silabs_usart_api); +#else +#define SPI_INIT(n) \ + static struct spi_silabs_usart_data spi_silabs_usart_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(spi_silabs_usart_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_silabs_usart_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ + }; \ + static struct spi_silabs_usart_config spi_silabs_usart_cfg_##n = { \ + .base = (USART_TypeDef *) \ + DT_INST_REG_ADDR(n), \ + GET_USART_CLOCK(n) \ + .clock_frequency = DT_INST_PROP_OR(n, clock_frequency, 1000000), \ + .pin_rx = { DT_INST_PROP_BY_IDX(n, location_rx, 1), \ + DT_INST_PROP_BY_IDX(n, location_rx, 2), \ + gpioModeInput, 1}, \ + .pin_tx = { DT_INST_PROP_BY_IDX(n, location_tx, 1), \ + DT_INST_PROP_BY_IDX(n, location_tx, 2), \ + gpioModePushPull, 1}, \ + .pin_clk = { DT_INST_PROP_BY_IDX(n, location_clk, 1), \ + DT_INST_PROP_BY_IDX(n, location_clk, 2), \ + gpioModePushPull, 1}, \ + .loc_rx = DT_INST_PROP_BY_IDX(n, location_rx, 0), \ + .loc_tx = DT_INST_PROP_BY_IDX(n, location_tx, 0), \ + .loc_clk = DT_INST_PROP_BY_IDX(n, location_clk, 0), \ + }; \ + SPI_DEVICE_DT_INST_DEFINE(n, \ + spi_silabs_usart_init, \ + NULL, \ + &spi_silabs_usart_data_##n, \ + &spi_silabs_usart_cfg_##n, \ + POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, \ + &spi_silabs_usart_api); +#endif /* CONFIG_PINCTRL */ + +DT_INST_FOREACH_STATUS_OKAY(SPI_INIT) diff --git a/drivers/spi/spi_smartbond.c b/drivers/spi/spi_smartbond.c index b1ea336ff4010..cadd01e270e93 100644 --- a/drivers/spi/spi_smartbond.c +++ b/drivers/spi/spi_smartbond.c @@ -1328,7 +1328,7 @@ static int spi_smartbond_init(const struct device *dev) SPI_CONTEXT_INIT_SYNC(spi_smartbond_##id##_data, ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(id), ctx)}; \ PM_DEVICE_DT_INST_DEFINE(id, spi_smartbond_pm_action); \ - DEVICE_DT_INST_DEFINE(id, \ + SPI_DEVICE_DT_INST_DEFINE(id, \ spi_smartbond_init, \ PM_DEVICE_DT_INST_GET(id), \ &spi_smartbond_##id##_data, \ diff --git a/drivers/spi/spi_test.c b/drivers/spi/spi_test.c index c15de8883b8ae..081aa6bfbf5e9 100644 --- a/drivers/spi/spi_test.c +++ b/drivers/spi/spi_test.c @@ -52,9 +52,8 @@ static DEVICE_API(spi, vnd_spi_api) = { .release = vnd_spi_release, }; -#define VND_SPI_INIT(n) \ - DEVICE_DT_INST_DEFINE(n, NULL, NULL, NULL, NULL, POST_KERNEL, \ - CONFIG_SPI_INIT_PRIORITY, \ - &vnd_spi_api); +#define VND_SPI_INIT(n) \ + SPI_DEVICE_DT_INST_DEFINE(n, NULL, NULL, NULL, NULL, POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, &vnd_spi_api); DT_INST_FOREACH_STATUS_OKAY(VND_SPI_INIT) diff --git a/drivers/spi/spi_xec_qmspi.c b/drivers/spi/spi_xec_qmspi.c index 78327be9bccd8..c552377ba1c26 100644 --- a/drivers/spi/spi_xec_qmspi.c +++ b/drivers/spi/spi_xec_qmspi.c @@ -703,7 +703,7 @@ static struct spi_qmspi_data spi_qmspi_0_dev_data = { SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(0), ctx) }; -DEVICE_DT_INST_DEFINE(0, +SPI_DEVICE_DT_INST_DEFINE(0, qmspi_init, NULL, &spi_qmspi_0_dev_data, &spi_qmspi_0_config, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_qmspi_driver_api); diff --git a/drivers/spi/spi_xec_qmspi_ldma.c b/drivers/spi/spi_xec_qmspi_ldma.c index 6d3b0b590ddb1..f3f9a77a26e3d 100644 --- a/drivers/spi/spi_xec_qmspi_ldma.c +++ b/drivers/spi/spi_xec_qmspi_ldma.c @@ -1071,7 +1071,7 @@ static DEVICE_API(spi, spi_qmspi_xec_driver_api) = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(i), \ }; \ PM_DEVICE_DT_INST_DEFINE(i, qmspi_xec_pm_action); \ - DEVICE_DT_INST_DEFINE(i, qmspi_xec_init, \ + SPI_DEVICE_DT_INST_DEFINE(i, qmspi_xec_init, \ PM_DEVICE_DT_INST_GET(i), \ &qmspi_xec_data_##i, &qmspi_xec_config_##i, \ POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ diff --git a/drivers/spi/spi_xlnx_axi_quadspi.c b/drivers/spi/spi_xlnx_axi_quadspi.c index 0686a69ee74e1..33918728e8ca9 100644 --- a/drivers/spi/spi_xlnx_axi_quadspi.c +++ b/drivers/spi/spi_xlnx_axi_quadspi.c @@ -601,38 +601,31 @@ static DEVICE_API(spi, xlnx_quadspi_driver_api) = { #define STARTUP_BLOCK_INIT(n) #endif -#define XLNX_QUADSPI_INIT(n) \ - static void xlnx_quadspi_config_func_##n(const struct device *dev); \ - \ - static const struct xlnx_quadspi_config xlnx_quadspi_config_##n = { \ - .base = DT_INST_REG_ADDR(n), \ - .irq_config_func = xlnx_quadspi_config_func_##n, \ - .num_ss_bits = DT_INST_PROP(n, xlnx_num_ss_bits), \ - .num_xfer_bytes = \ - DT_INST_PROP(n, xlnx_num_transfer_bits) / 8, \ - .fifo_size = DT_INST_PROP_OR(n, fifo_size, 0), \ - STARTUP_BLOCK_INIT(n) \ - }; \ - \ - static struct xlnx_quadspi_data xlnx_quadspi_data_##n = { \ - SPI_CONTEXT_INIT_LOCK(xlnx_quadspi_data_##n, ctx), \ - SPI_CONTEXT_INIT_SYNC(xlnx_quadspi_data_##n, ctx), \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ - }; \ - \ - DEVICE_DT_INST_DEFINE(n, &xlnx_quadspi_init, \ - NULL, \ - &xlnx_quadspi_data_##n, \ - &xlnx_quadspi_config_##n, POST_KERNEL, \ - CONFIG_SPI_INIT_PRIORITY, \ - &xlnx_quadspi_driver_api); \ - \ - static void xlnx_quadspi_config_func_##n(const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ - xlnx_quadspi_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQN(n)); \ +#define XLNX_QUADSPI_INIT(n) \ + static void xlnx_quadspi_config_func_##n(const struct device *dev); \ + \ + static const struct xlnx_quadspi_config xlnx_quadspi_config_##n = { \ + .base = DT_INST_REG_ADDR(n), \ + .irq_config_func = xlnx_quadspi_config_func_##n, \ + .num_ss_bits = DT_INST_PROP(n, xlnx_num_ss_bits), \ + .num_xfer_bytes = DT_INST_PROP(n, xlnx_num_transfer_bits) / 8, \ + .fifo_size = DT_INST_PROP_OR(n, fifo_size, 0), \ + STARTUP_BLOCK_INIT(n)}; \ + \ + static struct xlnx_quadspi_data xlnx_quadspi_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(xlnx_quadspi_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(xlnx_quadspi_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)}; \ + \ + SPI_DEVICE_DT_INST_DEFINE(n, &xlnx_quadspi_init, NULL, &xlnx_quadspi_data_##n, \ + &xlnx_quadspi_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &xlnx_quadspi_driver_api); \ + \ + static void xlnx_quadspi_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), xlnx_quadspi_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ } DT_INST_FOREACH_STATUS_OKAY(XLNX_QUADSPI_INIT) diff --git a/drivers/spi/spi_xmc4xxx.c b/drivers/spi/spi_xmc4xxx.c index 7e170bba3fe8b..7d48c5cacedb0 100644 --- a/drivers/spi/spi_xmc4xxx.c +++ b/drivers/spi/spi_xmc4xxx.c @@ -679,17 +679,16 @@ static DEVICE_API(spi, spi_xmc4xxx_driver_api) = { SPI_CONTEXT_INIT_LOCK(xmc4xxx_data_##index, ctx), \ SPI_CONTEXT_INIT_SYNC(xmc4xxx_data_##index, ctx), \ SPI_DMA_CHANNEL(index, tx, MEMORY_TO_PERIPHERAL, 8, 1) \ - SPI_DMA_CHANNEL(index, rx, PERIPHERAL_TO_MEMORY, 1, 8)}; \ + SPI_DMA_CHANNEL(index, rx, PERIPHERAL_TO_MEMORY, 1, 8)}; \ \ static const struct spi_xmc4xxx_config xmc4xxx_config_##index = { \ .spi = (XMC_USIC_CH_t *)DT_INST_REG_ADDR(index), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ .miso_src = DT_INST_ENUM_IDX(index, miso_src), \ - XMC4XXX_IRQ_HANDLER_STRUCT_INIT(index) \ - XMC4XXX_IRQ_DMA_STRUCT_INIT(index)}; \ + XMC4XXX_IRQ_HANDLER_STRUCT_INIT(index) XMC4XXX_IRQ_DMA_STRUCT_INIT(index)}; \ \ - DEVICE_DT_INST_DEFINE(index, spi_xmc4xxx_init, NULL, &xmc4xxx_data_##index, \ - &xmc4xxx_config_##index, POST_KERNEL, \ - CONFIG_SPI_INIT_PRIORITY, &spi_xmc4xxx_driver_api); + SPI_DEVICE_DT_INST_DEFINE(index, spi_xmc4xxx_init, NULL, &xmc4xxx_data_##index, \ + &xmc4xxx_config_##index, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &spi_xmc4xxx_driver_api); DT_INST_FOREACH_STATUS_OKAY(XMC4XXX_INIT) diff --git a/drivers/stepper/CMakeLists.txt b/drivers/stepper/CMakeLists.txt index a73875a285ce0..7f135001497c0 100644 --- a/drivers/stepper/CMakeLists.txt +++ b/drivers/stepper/CMakeLists.txt @@ -5,6 +5,8 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/stepper.h) # zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_STEPPER_ADI_TMC adi_tmc) +add_subdirectory_ifdef(CONFIG_STEPPER_TI ti) +add_subdirectory_ifdef(CONFIG_STEP_DIR_STEPPER step_dir) # zephyr-keep-sorted-stop zephyr_library() diff --git a/drivers/stepper/Kconfig b/drivers/stepper/Kconfig index bdfb63cfd6315..f8dd4a43b1b07 100644 --- a/drivers/stepper/Kconfig +++ b/drivers/stepper/Kconfig @@ -24,10 +24,17 @@ config STEPPER_SHELL help Enable stepper shell for testing. +comment "Stepper Driver Common" + +rsource "step_dir/Kconfig" + comment "Stepper Drivers" -rsource "adi_tmc/Kconfig" +# zephyr-keep-sorted-start rsource "Kconfig.fake" rsource "Kconfig.gpio" +rsource "adi_tmc/Kconfig" +rsource "ti/Kconfig" +# zephyr-keep-sorted-stop endif diff --git a/drivers/stepper/Kconfig.stepper_event_template b/drivers/stepper/Kconfig.stepper_event_template new file mode 100644 index 0000000000000..fb29a1e91e0e2 --- /dev/null +++ b/drivers/stepper/Kconfig.stepper_event_template @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +config STEPPER_$(module)_GENERATE_ISR_SAFE_EVENTS + bool "$(module-str) guarantee non ISR callbacks upon stepper events" + help + Enable the dispatch of stepper generated events via + a message queue to guarantee that the event handler + code is not run inside of an ISR. Can be disabled, but + then registered stepper event callback must be ISR safe. + +config STEPPER_$(module)_EVENT_QUEUE_LEN + int "$(module-str) maximum number of pending stepper events" + default 4 + depends on STEPPER_$(module)_GENERATE_ISR_SAFE_EVENTS + help + The maximum number of stepper events that can be pending before new events + are dropped. diff --git a/drivers/stepper/adi_tmc/CMakeLists.txt b/drivers/stepper/adi_tmc/CMakeLists.txt index a261deef90802..51281754394a0 100644 --- a/drivers/stepper/adi_tmc/CMakeLists.txt +++ b/drivers/stepper/adi_tmc/CMakeLists.txt @@ -5,4 +5,5 @@ zephyr_library() zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC_SPI adi_tmc_spi.c) -zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC5041 adi_tmc5041_stepper_controller.c) +zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC2209 adi_tmc22xx_stepper_controller.c) +zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC50XX adi_tmc50xx_stepper_controller.c) diff --git a/drivers/stepper/adi_tmc/Kconfig b/drivers/stepper/adi_tmc/Kconfig index 7a88ec598fe17..b214be92963bf 100644 --- a/drivers/stepper/adi_tmc/Kconfig +++ b/drivers/stepper/adi_tmc/Kconfig @@ -10,13 +10,6 @@ menuconfig STEPPER_ADI_TMC if STEPPER_ADI_TMC -config STEPPER_ADI_TMC_RAMP_GEN - bool "Use Trinamic Stepper Controller with Ramp Generator" - depends on STEPPER_ADI_TMC - default y - help - Enable ramp generator for trinamic stepper controller - config STEPPER_ADI_TMC_SPI bool "Use Trinamic Stepper Controller with SPI" depends on STEPPER_ADI_TMC @@ -26,30 +19,7 @@ config STEPPER_ADI_TMC_SPI comment "Trinamic Stepper Drivers" -config STEPPER_ADI_TMC5041 - bool "Activate trinamic tmc5041 stepper driver" - depends on DT_HAS_ADI_TMC5041_ENABLED && STEPPER_ADI_TMC - select STEPPER_ADI_TMC_SPI - default y - help - Stepper driver for TMC5041. - -config STEPPER_ADI_TMC5041_RAMPSTAT_POLL - bool "TMC5041 poll ramp status" - depends on STEPPER_ADI_TMC5041 - default y - help - When enabled, the ramp status will be polled on TMC5041, to check for events: - - TMC5041_POS_REACHED_EVENT - - TMC5041_STOP_SG_EVENT - - TMC5041_STOP_LEFT_EVENT - - TMC5041_STOP_RIGHT_EVENT - -config STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC - int "TMC5041 poll ramp status interval in ms" - depends on STEPPER_ADI_TMC5041_RAMPSTAT_POLL - default 100 - help - The interval in ms to poll the ramp status on TMC5041. +rsource "Kconfig.tmc22xx" +rsource "Kconfig.tmc50xx" endif # STEPPER_ADI_TMC diff --git a/drivers/stepper/adi_tmc/Kconfig.tmc22xx b/drivers/stepper/adi_tmc/Kconfig.tmc22xx new file mode 100644 index 0000000000000..081d4f5a52e7e --- /dev/null +++ b/drivers/stepper/adi_tmc/Kconfig.tmc22xx @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +config STEPPER_ADI_TMC2209 + bool "Activate trinamic tmc2209 stepper driver" + depends on DT_HAS_ADI_TMC2209_ENABLED + select STEP_DIR_STEPPER + default y + help + Stepper driver for TMC2209. diff --git a/drivers/stepper/adi_tmc/Kconfig.tmc50xx b/drivers/stepper/adi_tmc/Kconfig.tmc50xx new file mode 100644 index 0000000000000..eeb17293456a5 --- /dev/null +++ b/drivers/stepper/adi_tmc/Kconfig.tmc50xx @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +config STEPPER_ADI_TMC50XX + bool "Activate trinamic tmc50xx stepper driver" + depends on DT_HAS_ADI_TMC50XX_ENABLED && STEPPER_ADI_TMC + select STEPPER_ADI_TMC_SPI + default y + +module = TMC50XX +module-str = tmc50xx +rsource "Kconfig.tmc_rampgen_template" diff --git a/drivers/stepper/adi_tmc/Kconfig.tmc_rampgen_template b/drivers/stepper/adi_tmc/Kconfig.tmc_rampgen_template new file mode 100644 index 0000000000000..34064f73b227b --- /dev/null +++ b/drivers/stepper/adi_tmc/Kconfig.tmc_rampgen_template @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +config STEPPER_ADI_$(module)_RAMPSTAT_POLL + bool "$(module-str) poll ramp status" + depends on STEPPER_ADI_$(module) + default y + help + When enabled, the ramp status will be polled on TMC, to check for events: + - TMC_POS_REACHED_EVENT + - TMC_STOP_SG_EVENT + - TMC_STOP_LEFT_EVENT + - TMC_STOP_RIGHT_EVENT + +config STEPPER_ADI_$(module)_RAMPSTAT_POLL_INTERVAL_IN_MSEC + int "$(module-str) poll ramp status interval in ms" + depends on STEPPER_ADI_$(module)_RAMPSTAT_POLL + default 100 + help + The interval in ms to poll the ramp status on TMC. + +config STEPPER_ADI_$(module)_RAMP_GEN + bool "Use $(module-str) with Ramp Generator" + depends on STEPPER_ADI_$(module) + default y + help + Enable ramp generator for trinamic stepper controller diff --git a/drivers/stepper/adi_tmc/adi_tmc22xx_stepper_controller.c b/drivers/stepper/adi_tmc/adi_tmc22xx_stepper_controller.c new file mode 100644 index 0000000000000..df2daa691810d --- /dev/null +++ b/drivers/stepper/adi_tmc/adi_tmc22xx_stepper_controller.c @@ -0,0 +1,195 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../step_dir/step_dir_stepper_common.h" + +#include +LOG_MODULE_REGISTER(tmc22xx, CONFIG_STEPPER_LOG_LEVEL); + +#define MSX_PIN_COUNT 2 +#define MSX_PIN_STATE_COUNT 4 + +struct tmc22xx_config { + struct step_dir_stepper_common_config common; + const struct gpio_dt_spec enable_pin; + const struct gpio_dt_spec *msx_pins; + enum stepper_micro_step_resolution *msx_resolutions; +}; + +struct tmc22xx_data { + struct step_dir_stepper_common_data common; + enum stepper_micro_step_resolution resolution; +}; + +STEP_DIR_STEPPER_STRUCT_CHECK(struct tmc22xx_config, struct tmc22xx_data); + +static int tmc22xx_stepper_enable(const struct device *dev, const bool enable) +{ + const struct tmc22xx_config *config = dev->config; + + LOG_DBG("Stepper motor controller %s %s", dev->name, enable ? "enabled" : "disabled"); + if (enable) { + return gpio_pin_set_dt(&config->enable_pin, 1); + } else { + return gpio_pin_set_dt(&config->enable_pin, 0); + } +} + +static int tmc22xx_stepper_set_micro_step_res(const struct device *dev, + enum stepper_micro_step_resolution micro_step_res) +{ + struct tmc22xx_data *data = dev->data; + const struct tmc22xx_config *config = dev->config; + int ret; + + if (!config->msx_pins) { + LOG_ERR("Microstep resolution pins are not configured"); + return -ENODEV; + } + + for (uint8_t i = 0; i < MSX_PIN_STATE_COUNT; i++) { + if (micro_step_res != config->msx_resolutions[i]) { + continue; + } + + ret = gpio_pin_set_dt(&config->msx_pins[0], i & 0x01); + if (ret < 0) { + LOG_ERR("Failed to set MS1 pin: %d", ret); + return ret; + } + + ret = gpio_pin_set_dt(&config->msx_pins[1], (i & 0x02) >> 1); + if (ret < 0) { + LOG_ERR("Failed to set MS2 pin: %d", ret); + return ret; + } + + data->resolution = micro_step_res; + return 0; + } + + LOG_ERR("Unsupported microstep resolution: %d", micro_step_res); + return -EINVAL; +} + +static int tmc22xx_stepper_get_micro_step_res(const struct device *dev, + enum stepper_micro_step_resolution *micro_step_res) +{ + struct tmc22xx_data *data = dev->data; + + *micro_step_res = data->resolution; + return 0; +} + +static int tmc22xx_stepper_configure_msx_pins(const struct device *dev) +{ + const struct tmc22xx_config *config = dev->config; + int ret; + + for (uint8_t i = 0; i < MSX_PIN_COUNT; i++) { + if (!gpio_is_ready_dt(&config->msx_pins[i])) { + LOG_ERR("MSX pin %u are not ready", i); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->msx_pins[i], GPIO_OUTPUT); + if (ret < 0) { + LOG_ERR("Failed to configure msx pin %u", i); + return ret; + } + } + return 0; +} + +static int tmc22xx_stepper_init(const struct device *dev) +{ + const struct tmc22xx_config *config = dev->config; + struct tmc22xx_data *data = dev->data; + int ret; + + if (!gpio_is_ready_dt(&config->enable_pin)) { + LOG_ERR("GPIO pins are not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->enable_pin, GPIO_OUTPUT); + if (ret < 0) { + LOG_ERR("Failed to configure enable pin: %d", ret); + return ret; + } + + if (config->msx_pins) { + ret = tmc22xx_stepper_configure_msx_pins(dev); + if (ret < 0) { + LOG_ERR("Failed to configure MSX pins: %d", ret); + return ret; + } + + ret = tmc22xx_stepper_set_micro_step_res(dev, data->resolution); + if (ret < 0) { + LOG_ERR("Failed to set microstep resolution: %d", ret); + return ret; + } + } + + ret = step_dir_stepper_common_init(dev); + if (ret < 0) { + LOG_ERR("Failed to init step dir common stepper: %d", ret); + return ret; + } + + return 0; +} + +static DEVICE_API(stepper, tmc22xx_stepper_api) = { + .enable = tmc22xx_stepper_enable, + .move_by = step_dir_stepper_common_move_by, + .is_moving = step_dir_stepper_common_is_moving, + .set_reference_position = step_dir_stepper_common_set_reference_position, + .get_actual_position = step_dir_stepper_common_get_actual_position, + .move_to = step_dir_stepper_common_move_to, + .set_microstep_interval = step_dir_stepper_common_set_microstep_interval, + .run = step_dir_stepper_common_run, + .set_event_callback = step_dir_stepper_common_set_event_callback, + .set_micro_step_res = tmc22xx_stepper_set_micro_step_res, + .get_micro_step_res = tmc22xx_stepper_get_micro_step_res, +}; + +#define TMC22XX_STEPPER_DEFINE(inst, msx_table) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, msx_gpios), ( \ + static const struct gpio_dt_spec tmc22xx_stepper_msx_pins_##inst[] = { \ + DT_INST_FOREACH_PROP_ELEM_SEP( \ + inst, msx_gpios, GPIO_DT_SPEC_GET_BY_IDX, (,) \ + ), \ + }; \ + BUILD_ASSERT( \ + ARRAY_SIZE(tmc22xx_stepper_msx_pins_##inst) == MSX_PIN_COUNT, \ + "Two microstep config pins needed"); \ + )) \ + \ + static const struct tmc22xx_config tmc22xx_config_##inst = { \ + .common = STEP_DIR_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst), \ + .enable_pin = GPIO_DT_SPEC_INST_GET(inst, en_gpios), \ + .msx_resolutions = msx_table, \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, msx_gpios), \ + (.msx_pins = tmc22xx_stepper_msx_pins_##inst)) \ + }; \ + static struct tmc22xx_data tmc22xx_data_##inst = { \ + .common = STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst), \ + .resolution = DT_INST_PROP(inst, micro_step_res), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, tmc22xx_stepper_init, NULL, &tmc22xx_data_##inst, \ + &tmc22xx_config_##inst, POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY, \ + &tmc22xx_stepper_api); + +#define DT_DRV_COMPAT adi_tmc2209 +static enum stepper_micro_step_resolution tmc2209_msx_resolutions[MSX_PIN_STATE_COUNT] = { + STEPPER_MICRO_STEP_8, + STEPPER_MICRO_STEP_32, + STEPPER_MICRO_STEP_64, + STEPPER_MICRO_STEP_16, +}; +DT_INST_FOREACH_STATUS_OKAY_VARGS(TMC22XX_STEPPER_DEFINE, tmc2209_msx_resolutions) +#undef DT_DRV_COMPAT diff --git a/drivers/stepper/adi_tmc/adi_tmc5041_stepper_controller.c b/drivers/stepper/adi_tmc/adi_tmc5041_stepper_controller.c deleted file mode 100644 index d8bdd4e2bd01c..0000000000000 --- a/drivers/stepper/adi_tmc/adi_tmc5041_stepper_controller.c +++ /dev/null @@ -1,763 +0,0 @@ -/* - * SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG - * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT adi_tmc5041 - -#include - -#include -#include - -#include "adi_tmc_spi.h" -#include "adi_tmc5xxx_common.h" - -#include - -LOG_MODULE_REGISTER(tmc5041, CONFIG_STEPPER_LOG_LEVEL); - -struct tmc5041_data { - struct k_sem sem; -}; - -struct tmc5041_config { - const uint32_t gconf; - struct spi_dt_spec spi; - const uint32_t clock_frequency; -}; - -struct tmc5041_stepper_data { - struct k_work_delayable stallguard_dwork; - /* Work item to run the callback in a thread context. */ -#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL - struct k_work_delayable rampstat_callback_dwork; -#endif - /* device pointer required to access config in k_work */ - const struct device *stepper; - stepper_event_callback_t callback; - void *event_cb_user_data; -}; - -struct tmc5041_stepper_config { - const uint8_t index; - const uint16_t default_micro_step_res; - const int8_t sg_threshold; - const bool is_sg_enabled; - const uint32_t sg_velocity_check_interval_ms; - const uint32_t sg_threshold_velocity; - /* parent controller required for bus communication */ - const struct device *controller; -#ifdef CONFIG_STEPPER_ADI_TMC_RAMP_GEN - const struct tmc_ramp_generator_data default_ramp_config; -#endif -}; - -static int tmc5041_write(const struct device *dev, const uint8_t reg_addr, const uint32_t reg_val) -{ - const struct tmc5041_config *config = dev->config; - struct tmc5041_data *data = dev->data; - const struct spi_dt_spec bus = config->spi; - int err; - - k_sem_take(&data->sem, K_FOREVER); - - err = tmc_spi_write_register(&bus, TMC5XXX_WRITE_BIT, reg_addr, reg_val); - - k_sem_give(&data->sem); - - if (err) { - LOG_ERR("Failed to write register 0x%x with value 0x%x", reg_addr, reg_val); - return err; - } - return 0; -} - -static int tmc5041_read(const struct device *dev, const uint8_t reg_addr, uint32_t *reg_val) -{ - const struct tmc5041_config *config = dev->config; - struct tmc5041_data *data = dev->data; - const struct spi_dt_spec bus = config->spi; - int err; - - k_sem_take(&data->sem, K_FOREVER); - - err = tmc_spi_read_register(&bus, TMC5XXX_ADDRESS_MASK, reg_addr, reg_val); - - k_sem_give(&data->sem); - - if (err) { - LOG_ERR("Failed to read register 0x%x", reg_addr); - return err; - } - return 0; -} - -static int tmc5041_stepper_set_event_callback(const struct device *dev, - stepper_event_callback_t callback, void *user_data) -{ - struct tmc5041_stepper_data *data = dev->data; - - data->callback = callback; - data->event_cb_user_data = user_data; - return 0; -} - -static int stallguard_enable(const struct device *dev, const bool enable) -{ - const struct tmc5041_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc5041_read(config->controller, TMC5041_SWMODE(config->index), ®_value); - if (err) { - LOG_ERR("Failed to read SWMODE register"); - return -EIO; - } - - if (enable) { - reg_value |= TMC5XXX_SW_MODE_SG_STOP_ENABLE; - - int32_t actual_velocity; - - err = tmc5041_read(config->controller, TMC5041_VACTUAL(config->index), - &actual_velocity); - if (err) { - LOG_ERR("Failed to read VACTUAL register"); - return -EIO; - } - - actual_velocity = (actual_velocity << (31 - TMC_RAMP_VACTUAL_SHIFT)) >> - (31 - TMC_RAMP_VACTUAL_SHIFT); - LOG_DBG("actual velocity: %d", actual_velocity); - - if (abs(actual_velocity) < config->sg_threshold_velocity) { - return -EAGAIN; - } - } else { - reg_value &= ~TMC5XXX_SW_MODE_SG_STOP_ENABLE; - } - err = tmc5041_write(config->controller, TMC5041_SWMODE(config->index), reg_value); - if (err) { - LOG_ERR("Failed to write SWMODE register"); - return -EIO; - } - return 0; -} - -static void stallguard_work_handler(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct tmc5041_stepper_data *stepper_data = - CONTAINER_OF(dwork, struct tmc5041_stepper_data, stallguard_dwork); - int err; - const struct tmc5041_stepper_config *stepper_config = stepper_data->stepper->config; - - err = stallguard_enable(stepper_data->stepper, true); - if (err == -EAGAIN) { - LOG_ERR("retrying stallguard activation"); - k_work_reschedule(dwork, K_MSEC(stepper_config->sg_velocity_check_interval_ms)); - } - if (err == -EIO) { - LOG_ERR("Failed to enable stallguard because of I/O error"); - return; - } -} - -#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL - -static void execute_callback(const struct device *dev, const enum stepper_event event) -{ - struct tmc5041_stepper_data *data = dev->data; - - if (!data->callback) { - LOG_WRN_ONCE("No callback registered"); - return; - } - data->callback(dev, event, data->event_cb_user_data); -} - -static void rampstat_work_handler(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - - struct tmc5041_stepper_data *stepper_data = - CONTAINER_OF(dwork, struct tmc5041_stepper_data, rampstat_callback_dwork); - const struct tmc5041_stepper_config *stepper_config = stepper_data->stepper->config; - - __ASSERT_NO_MSG(stepper_config->controller != NULL); - - uint32_t drv_status; - int err; - - err = tmc5041_read(stepper_config->controller, TMC5041_DRVSTATUS(stepper_config->index), - &drv_status); - if (err != 0) { - LOG_ERR("%s: Failed to read DRVSTATUS register", stepper_data->stepper->name); - return; - } - - if (FIELD_GET(TMC5XXX_DRV_STATUS_SG_STATUS_MASK, drv_status) == 1U) { - LOG_INF("%s: Stall detected", stepper_data->stepper->name); - err = tmc5041_write(stepper_config->controller, - TMC5041_RAMPMODE(stepper_config->index), - TMC5XXX_RAMPMODE_HOLD_MODE); - if (err != 0) { - LOG_ERR("%s: Failed to stop motor", stepper_data->stepper->name); - return; - } - } - - uint32_t rampstat_value; - - err = tmc5041_read(stepper_config->controller, TMC5041_RAMPSTAT(stepper_config->index), - &rampstat_value); - if (err != 0) { - LOG_ERR("%s: Failed to read RAMPSTAT register", stepper_data->stepper->name); - return; - } - - const uint8_t ramp_stat_values = FIELD_GET(TMC5XXX_RAMPSTAT_INT_MASK, rampstat_value); - - if (ramp_stat_values > 0) { - switch (ramp_stat_values) { - - case TMC5XXX_STOP_LEFT_EVENT: - LOG_DBG("RAMPSTAT %s:Left end-stop detected", stepper_data->stepper->name); - execute_callback(stepper_data->stepper, - STEPPER_EVENT_LEFT_END_STOP_DETECTED); - break; - - case TMC5XXX_STOP_RIGHT_EVENT: - LOG_DBG("RAMPSTAT %s:Right end-stop detected", stepper_data->stepper->name); - execute_callback(stepper_data->stepper, - STEPPER_EVENT_RIGHT_END_STOP_DETECTED); - break; - - case TMC5XXX_POS_REACHED_EVENT: - LOG_DBG("RAMPSTAT %s:Position reached", stepper_data->stepper->name); - execute_callback(stepper_data->stepper, STEPPER_EVENT_STEPS_COMPLETED); - break; - - case TMC5XXX_STOP_SG_EVENT: - LOG_DBG("RAMPSTAT %s:Stall detected", stepper_data->stepper->name); - stallguard_enable(stepper_data->stepper, false); - execute_callback(stepper_data->stepper, STEPPER_EVENT_STALL_DETECTED); - break; - default: - LOG_ERR("Illegal ramp stat bit field"); - break; - } - } else { - k_work_reschedule( - &stepper_data->rampstat_callback_dwork, - K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); - } -} - -#endif - -static int tmc5041_stepper_enable(const struct device *dev, const bool enable) -{ - LOG_DBG("Stepper motor controller %s %s", dev->name, enable ? "enabled" : "disabled"); - const struct tmc5041_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc5041_read(config->controller, TMC5041_CHOPCONF(config->index), ®_value); - if (err != 0) { - return -EIO; - } - - if (enable) { - reg_value |= TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; - } else { - reg_value &= ~TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; - } - - err = tmc5041_write(config->controller, TMC5041_CHOPCONF(config->index), reg_value); - if (err != 0) { - return -EIO; - } - return 0; -} - -static int tmc5041_stepper_is_moving(const struct device *dev, bool *is_moving) -{ - const struct tmc5041_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc5041_read(config->controller, TMC5041_DRVSTATUS(config->index), ®_value); - - if (err != 0) { - LOG_ERR("%s: Failed to read DRVSTATUS register", dev->name); - return -EIO; - } - - *is_moving = (FIELD_GET(TMC5XXX_DRV_STATUS_STST_BIT, reg_value) != 1U); - LOG_DBG("Stepper motor controller %s is moving: %d", dev->name, *is_moving); - return 0; -} - -static int tmc5041_stepper_move(const struct device *dev, const int32_t steps) -{ - const struct tmc5041_stepper_config *config = dev->config; - struct tmc5041_stepper_data *data = dev->data; - int err; - - if (config->is_sg_enabled) { - err = stallguard_enable(dev, false); - if (err != 0) { - return -EIO; - } - } - - int32_t position; - - err = stepper_get_actual_position(dev, &position); - if (err != 0) { - return -EIO; - } - int32_t target_position = position + steps; - - err = tmc5041_write(config->controller, TMC5041_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_POSITIONING_MODE); - if (err != 0) { - return -EIO; - } - LOG_DBG("Stepper motor controller %s moved to %d by steps: %d", dev->name, target_position, - steps); - err = tmc5041_write(config->controller, TMC5041_XTARGET(config->index), target_position); - if (err != 0) { - return -EIO; - } - - if (config->is_sg_enabled) { - k_work_reschedule(&data->stallguard_dwork, - K_MSEC(config->sg_velocity_check_interval_ms)); - } -#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL - if (data->callback) { - k_work_reschedule( - &data->rampstat_callback_dwork, - K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); - } -#endif - return 0; -} - -static int tmc5041_stepper_set_max_velocity(const struct device *dev, uint32_t velocity) -{ - const struct tmc5041_stepper_config *config = dev->config; - const struct tmc5041_config *tmc5041_config = config->controller->config; - const uint32_t clock_frequency = tmc5041_config->clock_frequency; - uint32_t velocity_fclk; - int err; - - velocity_fclk = tmc5xxx_calculate_velocity_from_hz_to_fclk(velocity, clock_frequency); - - err = tmc5041_write(config->controller, TMC5041_VMAX(config->index), velocity_fclk); - if (err != 0) { - LOG_ERR("%s: Failed to set max velocity", dev->name); - return -EIO; - } - return 0; -} - -static int tmc5041_stepper_set_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution res) -{ - const struct tmc5041_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc5041_read(config->controller, TMC5041_CHOPCONF(config->index), ®_value); - if (err != 0) { - return -EIO; - } - - reg_value &= ~TMC5XXX_CHOPCONF_MRES_MASK; - reg_value |= ((MICRO_STEP_RES_INDEX(STEPPER_MICRO_STEP_256) - LOG2(res)) - << TMC5XXX_CHOPCONF_MRES_SHIFT); - - err = tmc5041_write(config->controller, TMC5041_CHOPCONF(config->index), reg_value); - if (err != 0) { - return -EIO; - } - - LOG_DBG("Stepper motor controller %s set micro step resolution to 0x%x", dev->name, - reg_value); - return 0; -} - -static int tmc5041_stepper_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *res) -{ - const struct tmc5041_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc5041_read(config->controller, TMC5041_CHOPCONF(config->index), ®_value); - if (err != 0) { - return -EIO; - } - reg_value &= TMC5XXX_CHOPCONF_MRES_MASK; - reg_value >>= TMC5XXX_CHOPCONF_MRES_SHIFT; - *res = (1 << (MICRO_STEP_RES_INDEX(STEPPER_MICRO_STEP_256) - reg_value)); - LOG_DBG("Stepper motor controller %s get micro step resolution: %d", dev->name, *res); - return 0; -} - -static int tmc5041_stepper_set_reference_position(const struct device *dev, const int32_t position) -{ - const struct tmc5041_stepper_config *config = dev->config; - int err; - - err = tmc5041_write(config->controller, TMC5041_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_HOLD_MODE); - if (err != 0) { - return -EIO; - } - - err = tmc5041_write(config->controller, TMC5041_XACTUAL(config->index), position); - if (err != 0) { - return -EIO; - } - LOG_DBG("Stepper motor controller %s set actual position to %d", dev->name, position); - return 0; -} - -static int tmc5041_stepper_get_actual_position(const struct device *dev, int32_t *position) -{ - const struct tmc5041_stepper_config *config = dev->config; - int err; - - err = tmc5041_read(config->controller, TMC5041_XACTUAL(config->index), position); - if (err != 0) { - return -EIO; - } - LOG_DBG("%s actual position: %d", dev->name, *position); - return 0; -} - -static int tmc5041_stepper_set_target_position(const struct device *dev, const int32_t position) -{ - LOG_DBG("Stepper motor controller %s set target position to %d", dev->name, position); - const struct tmc5041_stepper_config *config = dev->config; - struct tmc5041_stepper_data *data = dev->data; - int err; - - if (config->is_sg_enabled) { - stallguard_enable(dev, false); - } - - err = tmc5041_write(config->controller, TMC5041_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_POSITIONING_MODE); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_XTARGET(config->index), position); - if (err != 0) { - return -EIO; - } - - if (config->is_sg_enabled) { - k_work_reschedule(&data->stallguard_dwork, - K_MSEC(config->sg_velocity_check_interval_ms)); - } -#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL - if (data->callback) { - k_work_reschedule( - &data->rampstat_callback_dwork, - K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); - } -#endif - return 0; -} - -static int tmc5041_stepper_run(const struct device *dev, const enum stepper_direction direction, - const uint32_t velocity) -{ - LOG_DBG("Stepper motor controller %s run with velocity %d", dev->name, velocity); - const struct tmc5041_stepper_config *config = dev->config; - const struct tmc5041_config *tmc5041_config = config->controller->config; - struct tmc5041_stepper_data *data = dev->data; - const uint32_t clock_frequency = tmc5041_config->clock_frequency; - uint32_t velocity_fclk; - int err; - - velocity_fclk = tmc5xxx_calculate_velocity_from_hz_to_fclk(velocity, clock_frequency); - - if (config->is_sg_enabled) { - err = stallguard_enable(dev, false); - if (err != 0) { - return -EIO; - } - } - - switch (direction) { - case STEPPER_DIRECTION_POSITIVE: - err = tmc5041_write(config->controller, TMC5041_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_VMAX(config->index), velocity_fclk); - if (err != 0) { - return -EIO; - } - break; - - case STEPPER_DIRECTION_NEGATIVE: - err = tmc5041_write(config->controller, TMC5041_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_NEGATIVE_VELOCITY_MODE); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_VMAX(config->index), velocity_fclk); - if (err != 0) { - return -EIO; - } - break; - } - - if (config->is_sg_enabled) { - k_work_reschedule(&data->stallguard_dwork, - K_MSEC(config->sg_velocity_check_interval_ms)); - } -#ifdef CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL - if (data->callback) { - k_work_reschedule( - &data->rampstat_callback_dwork, - K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); - } -#endif - return 0; -} - -#ifdef CONFIG_STEPPER_ADI_TMC_RAMP_GEN - -int tmc5041_stepper_set_ramp(const struct device *dev, - const struct tmc_ramp_generator_data *ramp_data) -{ - LOG_DBG("Stepper motor controller %s set ramp", dev->name); - const struct tmc5041_stepper_config *config = dev->config; - int err; - - err = tmc5041_write(config->controller, TMC5041_VSTART(config->index), ramp_data->vstart); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_A1(config->index), ramp_data->a1); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_AMAX(config->index), ramp_data->amax); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_D1(config->index), ramp_data->d1); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_DMAX(config->index), ramp_data->dmax); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_V1(config->index), ramp_data->v1); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_VMAX(config->index), ramp_data->vmax); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_VSTOP(config->index), ramp_data->vstop); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_TZEROWAIT(config->index), - ramp_data->tzerowait); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_VHIGH(config->index), ramp_data->vhigh); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_VCOOLTHRS(config->index), - ramp_data->vcoolthrs); - if (err != 0) { - return -EIO; - } - err = tmc5041_write(config->controller, TMC5041_IHOLD_IRUN(config->index), - ramp_data->iholdrun); - if (err != 0) { - return -EIO; - } - return 0; -} - -#endif - -static int tmc5041_init(const struct device *dev) -{ - LOG_DBG("TMC5041 stepper motor controller %s initialized", dev->name); - struct tmc5041_data *data = dev->data; - const struct tmc5041_config *config = dev->config; - int err; - - k_sem_init(&data->sem, 1, 1); - - if (!spi_is_ready_dt(&config->spi)) { - LOG_ERR("SPI bus is not ready"); - return -ENODEV; - } - - /* Init non motor-index specific registers here. */ - LOG_DBG("GCONF: %d", config->gconf); - err = tmc5041_write(dev, TMC5XXX_GCONF, config->gconf); - if (err != 0) { - return -EIO; - } - - /* Read GSTAT register values to clear any errors SPI Datagram. */ - uint32_t gstat_value; - - err = tmc5041_read(dev, TMC5XXX_GSTAT, &gstat_value); - if (err != 0) { - return -EIO; - } - - LOG_DBG("Device %s initialized", dev->name); - return 0; -} - -static int tmc5041_stepper_init(const struct device *dev) -{ - const struct tmc5041_stepper_config *stepper_config = dev->config; - struct tmc5041_stepper_data *data = dev->data; - int err; - - LOG_DBG("Controller: %s, Stepper: %s", stepper_config->controller->name, dev->name); - - if (stepper_config->is_sg_enabled) { - k_work_init_delayable(&data->stallguard_dwork, stallguard_work_handler); - - err = tmc5041_write(stepper_config->controller, - TMC5041_SWMODE(stepper_config->index), BIT(10)); - if (err != 0) { - return -EIO; - } - - LOG_DBG("Setting stall guard to %d with delay %d ms", stepper_config->sg_threshold, - stepper_config->sg_velocity_check_interval_ms); - if (!IN_RANGE(stepper_config->sg_threshold, TMC5XXX_SG_MIN_VALUE, - TMC5XXX_SG_MAX_VALUE)) { - LOG_ERR("Stallguard threshold out of range"); - return -EINVAL; - } - - int32_t stall_guard_threshold = (int32_t)stepper_config->sg_threshold; - - err = tmc5041_write( - stepper_config->controller, TMC5041_COOLCONF(stepper_config->index), - stall_guard_threshold << TMC5XXX_COOLCONF_SG2_THRESHOLD_VALUE_SHIFT); - if (err != 0) { - return -EIO; - } - err = stallguard_enable(dev, true); - if (err == -EAGAIN) { - LOG_ERR("retrying stallguard activation"); - k_work_reschedule(&data->stallguard_dwork, - K_MSEC(stepper_config->sg_velocity_check_interval_ms)); - } - } - -#ifdef CONFIG_STEPPER_ADI_TMC_RAMP_GEN - err = tmc5041_stepper_set_ramp(dev, &stepper_config->default_ramp_config); - if (err != 0) { - return -EIO; - } -#endif - -#if CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL - k_work_init_delayable(&data->rampstat_callback_dwork, rampstat_work_handler); - k_work_reschedule(&data->rampstat_callback_dwork, - K_MSEC(CONFIG_STEPPER_ADI_TMC5041_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); -#endif - err = tmc5041_stepper_set_micro_step_res(dev, stepper_config->default_micro_step_res); - if (err != 0) { - return -EIO; - } - return 0; -} - -#define TMC5041_SHAFT_CONFIG(child) \ - (DT_PROP(child, invert_direction) << TMC5041_GCONF_SHAFT_SHIFT(DT_REG_ADDR(child))) | - -#define TMC5041_STEPPER_CONFIG_DEFINE(child) \ - COND_CODE_1(DT_PROP_EXISTS(child, stallguard_threshold_velocity), \ - BUILD_ASSERT(DT_PROP(child, stallguard_threshold_velocity), \ - "stallguard threshold velocity must be a positive value"), ()); \ - IF_ENABLED(CONFIG_STEPPER_ADI_TMC_RAMP_GEN, (CHECK_RAMP_DT_DATA(child))); \ - static const struct tmc5041_stepper_config tmc5041_stepper_config_##child = { \ - .controller = DEVICE_DT_GET(DT_PARENT(child)), \ - .default_micro_step_res = DT_PROP(child, micro_step_res), \ - .index = DT_REG_ADDR(child), \ - .sg_threshold = DT_PROP(child, stallguard2_threshold), \ - .sg_threshold_velocity = DT_PROP(child, stallguard_threshold_velocity), \ - .sg_velocity_check_interval_ms = DT_PROP(child, \ - stallguard_velocity_check_interval_ms), \ - .is_sg_enabled = DT_PROP(child, activate_stallguard2), \ - IF_ENABLED(CONFIG_STEPPER_ADI_TMC_RAMP_GEN, \ - (.default_ramp_config = TMC_RAMP_DT_SPEC_GET(child))) }; - -#define TMC5041_STEPPER_DATA_DEFINE(child) \ - static struct tmc5041_stepper_data tmc5041_stepper_data_##child = { \ - .stepper = DEVICE_DT_GET(child),}; - -#define TMC5041_STEPPER_API_DEFINE(child) \ - static DEVICE_API(stepper, tmc5041_stepper_api_##child) = { \ - .enable = tmc5041_stepper_enable, \ - .is_moving = tmc5041_stepper_is_moving, \ - .move = tmc5041_stepper_move, \ - .set_max_velocity = tmc5041_stepper_set_max_velocity, \ - .set_micro_step_res = tmc5041_stepper_set_micro_step_res, \ - .get_micro_step_res = tmc5041_stepper_get_micro_step_res, \ - .set_reference_position = tmc5041_stepper_set_reference_position, \ - .get_actual_position = tmc5041_stepper_get_actual_position, \ - .set_target_position = tmc5041_stepper_set_target_position, \ - .run = tmc5041_stepper_run, \ - .set_event_callback = tmc5041_stepper_set_event_callback, }; - -#define TMC5041_STEPPER_DEFINE(child) \ - DEVICE_DT_DEFINE(child, tmc5041_stepper_init, NULL, &tmc5041_stepper_data_##child, \ - &tmc5041_stepper_config_##child, POST_KERNEL, \ - CONFIG_STEPPER_INIT_PRIORITY, &tmc5041_stepper_api_##child); - -#define TMC5041_DEFINE(inst) \ - BUILD_ASSERT(DT_INST_CHILD_NUM(inst) <= 2, "tmc5041 can drive two steppers at max"); \ - BUILD_ASSERT((DT_INST_PROP(inst, clock_frequency) > 0), \ - "clock frequency must be non-zero positive value"); \ - static struct tmc5041_data tmc5041_data_##inst; \ - static const struct tmc5041_config tmc5041_config_##inst = { \ - .gconf = ( \ - (DT_INST_PROP(inst, poscmp_enable) << TMC5041_GCONF_POSCMP_ENABLE_SHIFT) | \ - (DT_INST_PROP(inst, test_mode) << TMC5041_GCONF_TEST_MODE_SHIFT) | \ - DT_INST_FOREACH_CHILD(inst, TMC5041_SHAFT_CONFIG) \ - (DT_INST_PROP(inst, lock_gconf) << TMC5041_LOCK_GCONF_SHIFT)), \ - .spi = SPI_DT_SPEC_INST_GET(inst, (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \ - SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8)), 0), \ - .clock_frequency = DT_INST_PROP(inst, clock_frequency),}; \ - DT_INST_FOREACH_CHILD(inst, TMC5041_STEPPER_CONFIG_DEFINE); \ - DT_INST_FOREACH_CHILD(inst, TMC5041_STEPPER_DATA_DEFINE); \ - DT_INST_FOREACH_CHILD(inst, TMC5041_STEPPER_API_DEFINE); \ - DT_INST_FOREACH_CHILD(inst, TMC5041_STEPPER_DEFINE); \ - DEVICE_DT_INST_DEFINE(inst, tmc5041_init, NULL, &tmc5041_data_##inst, \ - &tmc5041_config_##inst, POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY,\ - NULL); - -DT_INST_FOREACH_STATUS_OKAY(TMC5041_DEFINE) diff --git a/drivers/stepper/adi_tmc/adi_tmc50xx_stepper_controller.c b/drivers/stepper/adi_tmc/adi_tmc50xx_stepper_controller.c new file mode 100644 index 0000000000000..ccc97b8f12840 --- /dev/null +++ b/drivers/stepper/adi_tmc/adi_tmc50xx_stepper_controller.c @@ -0,0 +1,748 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_tmc50xx + +#include + +#include +#include + +#include "adi_tmc_spi.h" +#include "adi_tmc5xxx_common.h" + +#include + +LOG_MODULE_REGISTER(tmc50xx, CONFIG_STEPPER_LOG_LEVEL); + +struct tmc50xx_data { + struct k_sem sem; +}; + +struct tmc50xx_config { + const uint32_t gconf; + struct spi_dt_spec spi; + const uint32_t clock_frequency; +}; + +struct tmc50xx_stepper_data { + struct k_work_delayable stallguard_dwork; + /* Work item to run the callback in a thread context. */ +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL + struct k_work_delayable rampstat_callback_dwork; +#endif + /* device pointer required to access config in k_work */ + const struct device *stepper; + stepper_event_callback_t callback; + void *event_cb_user_data; +}; + +struct tmc50xx_stepper_config { + const uint8_t index; + const uint16_t default_micro_step_res; + const int8_t sg_threshold; + const bool is_sg_enabled; + const uint32_t sg_velocity_check_interval_ms; + const uint32_t sg_threshold_velocity; + /* parent controller required for bus communication */ + const struct device *controller; +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN + const struct tmc_ramp_generator_data default_ramp_config; +#endif +}; + +static int tmc50xx_write(const struct device *dev, const uint8_t reg_addr, const uint32_t reg_val) +{ + const struct tmc50xx_config *config = dev->config; + struct tmc50xx_data *data = dev->data; + const struct spi_dt_spec bus = config->spi; + int err; + + k_sem_take(&data->sem, K_FOREVER); + + err = tmc_spi_write_register(&bus, TMC5XXX_WRITE_BIT, reg_addr, reg_val); + + k_sem_give(&data->sem); + + if (err) { + LOG_ERR("Failed to write register 0x%x with value 0x%x", reg_addr, reg_val); + return err; + } + return 0; +} + +static int tmc50xx_read(const struct device *dev, const uint8_t reg_addr, uint32_t *reg_val) +{ + const struct tmc50xx_config *config = dev->config; + struct tmc50xx_data *data = dev->data; + const struct spi_dt_spec bus = config->spi; + int err; + + k_sem_take(&data->sem, K_FOREVER); + + err = tmc_spi_read_register(&bus, TMC5XXX_ADDRESS_MASK, reg_addr, reg_val); + + k_sem_give(&data->sem); + + if (err) { + LOG_ERR("Failed to read register 0x%x", reg_addr); + return err; + } + return 0; +} + +static int tmc50xx_stepper_set_event_callback(const struct device *dev, + stepper_event_callback_t callback, void *user_data) +{ + struct tmc50xx_stepper_data *data = dev->data; + + data->callback = callback; + data->event_cb_user_data = user_data; + return 0; +} + +static int stallguard_enable(const struct device *dev, const bool enable) +{ + const struct tmc50xx_stepper_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_SWMODE(config->index), ®_value); + if (err) { + LOG_ERR("Failed to read SWMODE register"); + return -EIO; + } + + if (enable) { + reg_value |= TMC5XXX_SW_MODE_SG_STOP_ENABLE; + + int32_t actual_velocity; + + err = tmc50xx_read(config->controller, TMC50XX_VACTUAL(config->index), + &actual_velocity); + if (err) { + LOG_ERR("Failed to read VACTUAL register"); + return -EIO; + } + + actual_velocity = (actual_velocity << (31 - TMC_RAMP_VACTUAL_SHIFT)) >> + (31 - TMC_RAMP_VACTUAL_SHIFT); + LOG_DBG("actual velocity: %d", actual_velocity); + + if (abs(actual_velocity) < config->sg_threshold_velocity) { + return -EAGAIN; + } + } else { + reg_value &= ~TMC5XXX_SW_MODE_SG_STOP_ENABLE; + } + err = tmc50xx_write(config->controller, TMC50XX_SWMODE(config->index), reg_value); + if (err) { + LOG_ERR("Failed to write SWMODE register"); + return -EIO; + } + return 0; +} + +static void stallguard_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct tmc50xx_stepper_data *stepper_data = + CONTAINER_OF(dwork, struct tmc50xx_stepper_data, stallguard_dwork); + int err; + const struct tmc50xx_stepper_config *stepper_config = stepper_data->stepper->config; + + err = stallguard_enable(stepper_data->stepper, true); + if (err == -EAGAIN) { + LOG_ERR("retrying stallguard activation"); + k_work_reschedule(dwork, K_MSEC(stepper_config->sg_velocity_check_interval_ms)); + } + if (err == -EIO) { + LOG_ERR("Failed to enable stallguard because of I/O error"); + return; + } +} + +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL + +static void execute_callback(const struct device *dev, const enum stepper_event event) +{ + struct tmc50xx_stepper_data *data = dev->data; + + if (!data->callback) { + LOG_WRN_ONCE("No callback registered"); + return; + } + data->callback(dev, event, data->event_cb_user_data); +} + +static void rampstat_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + + struct tmc50xx_stepper_data *stepper_data = + CONTAINER_OF(dwork, struct tmc50xx_stepper_data, rampstat_callback_dwork); + const struct tmc50xx_stepper_config *stepper_config = stepper_data->stepper->config; + + __ASSERT_NO_MSG(stepper_config->controller != NULL); + + uint32_t drv_status; + int err; + + err = tmc50xx_read(stepper_config->controller, TMC50XX_DRVSTATUS(stepper_config->index), + &drv_status); + if (err != 0) { + LOG_ERR("%s: Failed to read DRVSTATUS register", stepper_data->stepper->name); + return; + } + + if (FIELD_GET(TMC5XXX_DRV_STATUS_SG_STATUS_MASK, drv_status) == 1U) { + LOG_INF("%s: Stall detected", stepper_data->stepper->name); + err = tmc50xx_write(stepper_config->controller, + TMC50XX_RAMPMODE(stepper_config->index), + TMC5XXX_RAMPMODE_HOLD_MODE); + if (err != 0) { + LOG_ERR("%s: Failed to stop motor", stepper_data->stepper->name); + return; + } + } + + uint32_t rampstat_value; + + err = tmc50xx_read(stepper_config->controller, TMC50XX_RAMPSTAT(stepper_config->index), + &rampstat_value); + if (err != 0) { + LOG_ERR("%s: Failed to read RAMPSTAT register", stepper_data->stepper->name); + return; + } + + const uint8_t ramp_stat_values = FIELD_GET(TMC5XXX_RAMPSTAT_INT_MASK, rampstat_value); + + if (ramp_stat_values > 0) { + switch (ramp_stat_values) { + + case TMC5XXX_STOP_LEFT_EVENT: + LOG_DBG("RAMPSTAT %s:Left end-stop detected", stepper_data->stepper->name); + execute_callback(stepper_data->stepper, + STEPPER_EVENT_LEFT_END_STOP_DETECTED); + break; + + case TMC5XXX_STOP_RIGHT_EVENT: + LOG_DBG("RAMPSTAT %s:Right end-stop detected", stepper_data->stepper->name); + execute_callback(stepper_data->stepper, + STEPPER_EVENT_RIGHT_END_STOP_DETECTED); + break; + + case TMC5XXX_POS_REACHED_EVENT: + LOG_DBG("RAMPSTAT %s:Position reached", stepper_data->stepper->name); + execute_callback(stepper_data->stepper, STEPPER_EVENT_STEPS_COMPLETED); + break; + + case TMC5XXX_STOP_SG_EVENT: + LOG_DBG("RAMPSTAT %s:Stall detected", stepper_data->stepper->name); + stallguard_enable(stepper_data->stepper, false); + execute_callback(stepper_data->stepper, STEPPER_EVENT_STALL_DETECTED); + break; + default: + LOG_ERR("Illegal ramp stat bit field"); + break; + } + } else { + k_work_reschedule( + &stepper_data->rampstat_callback_dwork, + K_MSEC(CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); + } +} + +#endif + +static int tmc50xx_stepper_enable(const struct device *dev, const bool enable) +{ + LOG_DBG("Stepper motor controller %s %s", dev->name, enable ? "enabled" : "disabled"); + const struct tmc50xx_stepper_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); + if (err != 0) { + return -EIO; + } + + if (enable) { + reg_value |= TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; + } else { + reg_value &= ~TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; + } + + err = tmc50xx_write(config->controller, TMC50XX_CHOPCONF(config->index), reg_value); + if (err != 0) { + return -EIO; + } + return 0; +} + +static int tmc50xx_stepper_is_moving(const struct device *dev, bool *is_moving) +{ + const struct tmc50xx_stepper_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_DRVSTATUS(config->index), ®_value); + + if (err != 0) { + LOG_ERR("%s: Failed to read DRVSTATUS register", dev->name); + return -EIO; + } + + *is_moving = (FIELD_GET(TMC5XXX_DRV_STATUS_STST_BIT, reg_value) != 1U); + LOG_DBG("Stepper motor controller %s is moving: %d", dev->name, *is_moving); + return 0; +} + +static int tmc50xx_stepper_move_by(const struct device *dev, const int32_t micro_steps) +{ + const struct tmc50xx_stepper_config *config = dev->config; + struct tmc50xx_stepper_data *data = dev->data; + int err; + + if (config->is_sg_enabled) { + err = stallguard_enable(dev, false); + if (err != 0) { + return -EIO; + } + } + + int32_t position; + + err = stepper_get_actual_position(dev, &position); + if (err != 0) { + return -EIO; + } + int32_t target_position = position + micro_steps; + + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_POSITIONING_MODE); + if (err != 0) { + return -EIO; + } + LOG_DBG("Stepper motor controller %s moved to %d by steps: %d", dev->name, target_position, + micro_steps); + err = tmc50xx_write(config->controller, TMC50XX_XTARGET(config->index), target_position); + if (err != 0) { + return -EIO; + } + + if (config->is_sg_enabled) { + k_work_reschedule(&data->stallguard_dwork, + K_MSEC(config->sg_velocity_check_interval_ms)); + } +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL + if (data->callback) { + k_work_reschedule( + &data->rampstat_callback_dwork, + K_MSEC(CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); + } +#endif + return 0; +} + +int tmc50xx_stepper_set_max_velocity(const struct device *dev, uint32_t velocity) +{ + const struct tmc50xx_stepper_config *config = dev->config; + const struct tmc50xx_config *tmc50xx_config = config->controller->config; + const uint32_t clock_frequency = tmc50xx_config->clock_frequency; + uint32_t velocity_fclk; + int err; + + velocity_fclk = tmc5xxx_calculate_velocity_from_hz_to_fclk(velocity, clock_frequency); + + err = tmc50xx_write(config->controller, TMC50XX_VMAX(config->index), velocity_fclk); + if (err != 0) { + LOG_ERR("%s: Failed to set max velocity", dev->name); + return -EIO; + } + return 0; +} + +static int tmc50xx_stepper_set_micro_step_res(const struct device *dev, + enum stepper_micro_step_resolution res) +{ + const struct tmc50xx_stepper_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); + if (err != 0) { + return -EIO; + } + + reg_value &= ~TMC5XXX_CHOPCONF_MRES_MASK; + reg_value |= ((MICRO_STEP_RES_INDEX(STEPPER_MICRO_STEP_256) - LOG2(res)) + << TMC5XXX_CHOPCONF_MRES_SHIFT); + + err = tmc50xx_write(config->controller, TMC50XX_CHOPCONF(config->index), reg_value); + if (err != 0) { + return -EIO; + } + + LOG_DBG("Stepper motor controller %s set micro step resolution to 0x%x", dev->name, + reg_value); + return 0; +} + +static int tmc50xx_stepper_get_micro_step_res(const struct device *dev, + enum stepper_micro_step_resolution *res) +{ + const struct tmc50xx_stepper_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); + if (err != 0) { + return -EIO; + } + reg_value &= TMC5XXX_CHOPCONF_MRES_MASK; + reg_value >>= TMC5XXX_CHOPCONF_MRES_SHIFT; + *res = (1 << (MICRO_STEP_RES_INDEX(STEPPER_MICRO_STEP_256) - reg_value)); + LOG_DBG("Stepper motor controller %s get micro step resolution: %d", dev->name, *res); + return 0; +} + +static int tmc50xx_stepper_set_reference_position(const struct device *dev, const int32_t position) +{ + const struct tmc50xx_stepper_config *config = dev->config; + int err; + + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_HOLD_MODE); + if (err != 0) { + return -EIO; + } + + err = tmc50xx_write(config->controller, TMC50XX_XACTUAL(config->index), position); + if (err != 0) { + return -EIO; + } + LOG_DBG("Stepper motor controller %s set actual position to %d", dev->name, position); + return 0; +} + +static int tmc50xx_stepper_get_actual_position(const struct device *dev, int32_t *position) +{ + const struct tmc50xx_stepper_config *config = dev->config; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_XACTUAL(config->index), position); + if (err != 0) { + return -EIO; + } + LOG_DBG("%s actual position: %d", dev->name, *position); + return 0; +} + +static int tmc50xx_stepper_move_to(const struct device *dev, const int32_t micro_steps) +{ + LOG_DBG("Stepper motor controller %s set target position to %d", dev->name, micro_steps); + const struct tmc50xx_stepper_config *config = dev->config; + struct tmc50xx_stepper_data *data = dev->data; + int err; + + if (config->is_sg_enabled) { + stallguard_enable(dev, false); + } + + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_POSITIONING_MODE); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_XTARGET(config->index), micro_steps); + if (err != 0) { + return -EIO; + } + + if (config->is_sg_enabled) { + k_work_reschedule(&data->stallguard_dwork, + K_MSEC(config->sg_velocity_check_interval_ms)); + } +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL + if (data->callback) { + k_work_reschedule( + &data->rampstat_callback_dwork, + K_MSEC(CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); + } +#endif + return 0; +} + +static int tmc50xx_stepper_run(const struct device *dev, const enum stepper_direction direction) +{ + LOG_DBG("Stepper motor controller %s run", dev->name); + const struct tmc50xx_stepper_config *config = dev->config; + struct tmc50xx_stepper_data *data = dev->data; + int err; + + if (config->is_sg_enabled) { + err = stallguard_enable(dev, false); + if (err != 0) { + return -EIO; + } + } + + switch (direction) { + case STEPPER_DIRECTION_POSITIVE: + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); + if (err != 0) { + return -EIO; + } + break; + + case STEPPER_DIRECTION_NEGATIVE: + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_NEGATIVE_VELOCITY_MODE); + if (err != 0) { + return -EIO; + } + break; + } + + if (config->is_sg_enabled) { + k_work_reschedule(&data->stallguard_dwork, + K_MSEC(config->sg_velocity_check_interval_ms)); + } +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL + if (data->callback) { + k_work_reschedule( + &data->rampstat_callback_dwork, + K_MSEC(CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); + } +#endif + return 0; +} + +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN + +int tmc50xx_stepper_set_ramp(const struct device *dev, + const struct tmc_ramp_generator_data *ramp_data) +{ + LOG_DBG("Stepper motor controller %s set ramp", dev->name); + const struct tmc50xx_stepper_config *config = dev->config; + int err; + + err = tmc50xx_write(config->controller, TMC50XX_VSTART(config->index), ramp_data->vstart); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_A1(config->index), ramp_data->a1); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_AMAX(config->index), ramp_data->amax); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_D1(config->index), ramp_data->d1); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_DMAX(config->index), ramp_data->dmax); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_V1(config->index), ramp_data->v1); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_VMAX(config->index), ramp_data->vmax); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_VSTOP(config->index), ramp_data->vstop); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_TZEROWAIT(config->index), + ramp_data->tzerowait); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_VHIGH(config->index), ramp_data->vhigh); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_VCOOLTHRS(config->index), + ramp_data->vcoolthrs); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_IHOLD_IRUN(config->index), + ramp_data->iholdrun); + if (err != 0) { + return -EIO; + } + return 0; +} + +#endif + +static int tmc50xx_init(const struct device *dev) +{ + LOG_DBG("TMC50XX stepper motor controller %s initialized", dev->name); + struct tmc50xx_data *data = dev->data; + const struct tmc50xx_config *config = dev->config; + int err; + + k_sem_init(&data->sem, 1, 1); + + if (!spi_is_ready_dt(&config->spi)) { + LOG_ERR("SPI bus is not ready"); + return -ENODEV; + } + + /* Init non motor-index specific registers here. */ + LOG_DBG("GCONF: %d", config->gconf); + err = tmc50xx_write(dev, TMC5XXX_GCONF, config->gconf); + if (err != 0) { + return -EIO; + } + + /* Read GSTAT register values to clear any errors SPI Datagram. */ + uint32_t gstat_value; + + err = tmc50xx_read(dev, TMC5XXX_GSTAT, &gstat_value); + if (err != 0) { + return -EIO; + } + + LOG_DBG("Device %s initialized", dev->name); + return 0; +} + +static int tmc50xx_stepper_init(const struct device *dev) +{ + const struct tmc50xx_stepper_config *stepper_config = dev->config; + struct tmc50xx_stepper_data *data = dev->data; + int err; + + LOG_DBG("Controller: %s, Stepper: %s", stepper_config->controller->name, dev->name); + + if (stepper_config->is_sg_enabled) { + k_work_init_delayable(&data->stallguard_dwork, stallguard_work_handler); + + err = tmc50xx_write(stepper_config->controller, + TMC50XX_SWMODE(stepper_config->index), BIT(10)); + if (err != 0) { + return -EIO; + } + + LOG_DBG("Setting stall guard to %d with delay %d ms", stepper_config->sg_threshold, + stepper_config->sg_velocity_check_interval_ms); + if (!IN_RANGE(stepper_config->sg_threshold, TMC5XXX_SG_MIN_VALUE, + TMC5XXX_SG_MAX_VALUE)) { + LOG_ERR("Stallguard threshold out of range"); + return -EINVAL; + } + + int32_t stall_guard_threshold = (int32_t)stepper_config->sg_threshold; + + err = tmc50xx_write( + stepper_config->controller, TMC50XX_COOLCONF(stepper_config->index), + stall_guard_threshold << TMC5XXX_COOLCONF_SG2_THRESHOLD_VALUE_SHIFT); + if (err != 0) { + return -EIO; + } + err = stallguard_enable(dev, true); + if (err == -EAGAIN) { + LOG_ERR("retrying stallguard activation"); + k_work_reschedule(&data->stallguard_dwork, + K_MSEC(stepper_config->sg_velocity_check_interval_ms)); + } + } + +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN + err = tmc50xx_stepper_set_ramp(dev, &stepper_config->default_ramp_config); + if (err != 0) { + return -EIO; + } +#endif + +#if CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL + k_work_init_delayable(&data->rampstat_callback_dwork, rampstat_work_handler); + k_work_reschedule(&data->rampstat_callback_dwork, + K_MSEC(CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); +#endif + err = tmc50xx_stepper_set_micro_step_res(dev, stepper_config->default_micro_step_res); + if (err != 0) { + return -EIO; + } + return 0; +} + +#define TMC50XX_SHAFT_CONFIG(child) \ + (DT_PROP(child, invert_direction) << TMC50XX_GCONF_SHAFT_SHIFT(DT_REG_ADDR(child))) | + +#define TMC50XX_STEPPER_CONFIG_DEFINE(child) \ + COND_CODE_1(DT_PROP_EXISTS(child, stallguard_threshold_velocity), \ + BUILD_ASSERT(DT_PROP(child, stallguard_threshold_velocity), \ + "stallguard threshold velocity must be a positive value"), ()); \ + IF_ENABLED(CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN, (CHECK_RAMP_DT_DATA(child))); \ + static const struct tmc50xx_stepper_config tmc50xx_stepper_config_##child = { \ + .controller = DEVICE_DT_GET(DT_PARENT(child)), \ + .default_micro_step_res = DT_PROP(child, micro_step_res), \ + .index = DT_REG_ADDR(child), \ + .sg_threshold = DT_PROP(child, stallguard2_threshold), \ + .sg_threshold_velocity = DT_PROP(child, stallguard_threshold_velocity), \ + .sg_velocity_check_interval_ms = DT_PROP(child, \ + stallguard_velocity_check_interval_ms), \ + .is_sg_enabled = DT_PROP(child, activate_stallguard2), \ + IF_ENABLED(CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN, \ + (.default_ramp_config = TMC_RAMP_DT_SPEC_GET(child))) }; + +#define TMC50XX_STEPPER_DATA_DEFINE(child) \ + static struct tmc50xx_stepper_data tmc50xx_stepper_data_##child = { \ + .stepper = DEVICE_DT_GET(child),}; + +#define TMC50XX_STEPPER_API_DEFINE(child) \ + static DEVICE_API(stepper, tmc50xx_stepper_api_##child) = { \ + .enable = tmc50xx_stepper_enable, \ + .is_moving = tmc50xx_stepper_is_moving, \ + .move_by = tmc50xx_stepper_move_by, \ + .set_micro_step_res = tmc50xx_stepper_set_micro_step_res, \ + .get_micro_step_res = tmc50xx_stepper_get_micro_step_res, \ + .set_reference_position = tmc50xx_stepper_set_reference_position, \ + .get_actual_position = tmc50xx_stepper_get_actual_position, \ + .move_to = tmc50xx_stepper_move_to, \ + .run = tmc50xx_stepper_run, \ + .set_event_callback = tmc50xx_stepper_set_event_callback, }; + +#define TMC50XX_STEPPER_DEFINE(child) \ + DEVICE_DT_DEFINE(child, tmc50xx_stepper_init, NULL, &tmc50xx_stepper_data_##child, \ + &tmc50xx_stepper_config_##child, POST_KERNEL, \ + CONFIG_STEPPER_INIT_PRIORITY, &tmc50xx_stepper_api_##child); + +#define TMC50XX_DEFINE(inst) \ + BUILD_ASSERT(DT_INST_CHILD_NUM(inst) <= 2, "tmc50xx can drive two steppers at max"); \ + BUILD_ASSERT((DT_INST_PROP(inst, clock_frequency) > 0), \ + "clock frequency must be non-zero positive value"); \ + static struct tmc50xx_data tmc50xx_data_##inst; \ + static const struct tmc50xx_config tmc50xx_config_##inst = { \ + .gconf = ( \ + (DT_INST_PROP(inst, poscmp_enable) << TMC50XX_GCONF_POSCMP_ENABLE_SHIFT) | \ + (DT_INST_PROP(inst, test_mode) << TMC50XX_GCONF_TEST_MODE_SHIFT) | \ + DT_INST_FOREACH_CHILD(inst, TMC50XX_SHAFT_CONFIG) \ + (DT_INST_PROP(inst, lock_gconf) << TMC50XX_LOCK_GCONF_SHIFT)), \ + .spi = SPI_DT_SPEC_INST_GET(inst, (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \ + SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8)), 0), \ + .clock_frequency = DT_INST_PROP(inst, clock_frequency),}; \ + DT_INST_FOREACH_CHILD(inst, TMC50XX_STEPPER_CONFIG_DEFINE); \ + DT_INST_FOREACH_CHILD(inst, TMC50XX_STEPPER_DATA_DEFINE); \ + DT_INST_FOREACH_CHILD(inst, TMC50XX_STEPPER_API_DEFINE); \ + DT_INST_FOREACH_CHILD(inst, TMC50XX_STEPPER_DEFINE); \ + DEVICE_DT_INST_DEFINE(inst, tmc50xx_init, NULL, &tmc50xx_data_##inst, \ + &tmc50xx_config_##inst, POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY,\ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(TMC50XX_DEFINE) diff --git a/drivers/stepper/adi_tmc/adi_tmc_reg.h b/drivers/stepper/adi_tmc/adi_tmc_reg.h index eff9f86cea8d0..7dc3fc665335a 100644 --- a/drivers/stepper/adi_tmc/adi_tmc_reg.h +++ b/drivers/stepper/adi_tmc/adi_tmc_reg.h @@ -17,8 +17,8 @@ extern "C" { #endif -/** Common Registers for TMC5041 and TMC51XX */ -#if defined(CONFIG_STEPPER_ADI_TMC5041) +/** Common Registers for TMC50XX and TMC51XX */ +#if defined(CONFIG_STEPPER_ADI_TMC50XX) #define TMC5XXX_WRITE_BIT 0x80U #define TMC5XXX_ADDRESS_MASK 0x7FU @@ -81,64 +81,64 @@ extern "C" { #endif -#ifdef CONFIG_STEPPER_ADI_TMC5041 +#ifdef CONFIG_STEPPER_ADI_TMC50XX -#define TMC5041_MOTOR_ADDR(m) (0x20 << (m)) -#define TMC5041_MOTOR_ADDR_DRV(m) ((m) << 4) -#define TMC5041_MOTOR_ADDR_PWM(m) ((m) << 3) +#define TMC50XX_MOTOR_ADDR(m) (0x20 << (m)) +#define TMC50XX_MOTOR_ADDR_DRV(m) ((m) << 4) +#define TMC50XX_MOTOR_ADDR_PWM(m) ((m) << 3) /** - * @name TMC5041 module registers - * @anchor TMC5041_REGISTERS + * @name TMC50XX module registers + * @anchor TMC50XX_REGISTERS * * @{ */ -#define TMC5041_GCONF_POSCMP_ENABLE_SHIFT 3 -#define TMC5041_GCONF_TEST_MODE_SHIFT 7 -#define TMC5041_GCONF_SHAFT_SHIFT(n) ((n) ? 8 : 9) -#define TMC5041_LOCK_GCONF_SHIFT 10 - -#define TMC5041_PWMCONF(motor) (0x10 | TMC5041_MOTOR_ADDR_PWM(motor)) -#define TMC5041_PWM_STATUS(motor) (0x11 | TMC5041_MOTOR_ADDR_PWM(motor)) - -#define TMC5041_RAMPMODE(motor) (0x00 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_XACTUAL(motor) (0x01 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_VACTUAL(motor) (0x02 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_VSTART(motor) (0x03 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_A1(motor) (0x04 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_V1(motor) (0x05 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_AMAX(motor) (0x06 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_VMAX(motor) (0x07 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_DMAX(motor) (0x08 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_D1(motor) (0x0A | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_VSTOP(motor) (0x0B | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_TZEROWAIT(motor) (0x0C | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_XTARGET(motor) (0x0D | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_IHOLD_IRUN(motor) (0x10 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_VCOOLTHRS(motor) (0x11 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_VHIGH(motor) (0x12 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_SWMODE(motor) (0x14 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_RAMPSTAT(motor) (0x15 | TMC5041_MOTOR_ADDR(motor)) -#define TMC5041_XLATCH(motor) (0x16 | TMC5041_MOTOR_ADDR(motor)) - -#define TMC5041_MSLUT0(motor) (0x60 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUT1(motor) (0x61 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUT2(motor) (0x62 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUT3(motor) (0x63 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUT4(motor) (0x64 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUT5(motor) (0x65 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUT6(motor) (0x66 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUT7(motor) (0x67 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUTSEL(motor) (0x68 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSLUTSTART(motor) (0x69 | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSCNT(motor) (0x6A | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_MSCURACT(motor) (0x6B | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_CHOPCONF(motor) (0x6C | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_COOLCONF(motor) (0x6D | TMC5041_MOTOR_ADDR_DRV(motor)) -#define TMC5041_DRVSTATUS(motor) (0x6F | TMC5041_MOTOR_ADDR_DRV(motor)) - -#endif +#define TMC50XX_GCONF_POSCMP_ENABLE_SHIFT 3 +#define TMC50XX_GCONF_TEST_MODE_SHIFT 7 +#define TMC50XX_GCONF_SHAFT_SHIFT(n) ((n) ? 8 : 9) +#define TMC50XX_LOCK_GCONF_SHIFT 10 + +#define TMC50XX_PWMCONF(motor) (0x10 | TMC50XX_MOTOR_ADDR_PWM(motor)) +#define TMC50XX_PWM_STATUS(motor) (0x11 | TMC50XX_MOTOR_ADDR_PWM(motor)) + +#define TMC50XX_RAMPMODE(motor) (0x00 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_XACTUAL(motor) (0x01 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_VACTUAL(motor) (0x02 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_VSTART(motor) (0x03 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_A1(motor) (0x04 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_V1(motor) (0x05 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_AMAX(motor) (0x06 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_VMAX(motor) (0x07 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_DMAX(motor) (0x08 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_D1(motor) (0x0A | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_VSTOP(motor) (0x0B | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_TZEROWAIT(motor) (0x0C | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_XTARGET(motor) (0x0D | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_IHOLD_IRUN(motor) (0x10 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_VCOOLTHRS(motor) (0x11 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_VHIGH(motor) (0x12 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_SWMODE(motor) (0x14 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_RAMPSTAT(motor) (0x15 | TMC50XX_MOTOR_ADDR(motor)) +#define TMC50XX_XLATCH(motor) (0x16 | TMC50XX_MOTOR_ADDR(motor)) + +#define TMC50XX_MSLUT0(motor) (0x60 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUT1(motor) (0x61 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUT2(motor) (0x62 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUT3(motor) (0x63 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUT4(motor) (0x64 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUT5(motor) (0x65 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUT6(motor) (0x66 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUT7(motor) (0x67 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUTSEL(motor) (0x68 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSLUTSTART(motor) (0x69 | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSCNT(motor) (0x6A | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_MSCURACT(motor) (0x6B | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_CHOPCONF(motor) (0x6C | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_COOLCONF(motor) (0x6D | TMC50XX_MOTOR_ADDR_DRV(motor)) +#define TMC50XX_DRVSTATUS(motor) (0x6F | TMC50XX_MOTOR_ADDR_DRV(motor)) + +#endif /* CONFIG_STEPPER_ADI_TMC50XX */ /** * @} diff --git a/drivers/stepper/fake_stepper_controller.c b/drivers/stepper/fake_stepper_controller.c index 9520272ad5ab0..1633b4c038009 100644 --- a/drivers/stepper/fake_stepper_controller.c +++ b/drivers/stepper/fake_stepper_controller.c @@ -23,9 +23,9 @@ DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_enable, const struct device *, bool); DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_is_moving, const struct device *, bool *); -DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move, const struct device *, int32_t); +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move_by, const struct device *, int32_t); -DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_max_velocity, const struct device *, uint32_t); +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_microstep_interval, const struct device *, uint64_t); DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_micro_step_res, const struct device *, enum stepper_micro_step_resolution); @@ -37,10 +37,9 @@ DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_reference_position, const struct de DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_get_actual_position, const struct device *, int32_t *); -DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_target_position, const struct device *, int32_t); +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move_to, const struct device *, int32_t); -DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_run, const struct device *, enum stepper_direction, - uint32_t); +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_run, const struct device *, enum stepper_direction); DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_event_callback, const struct device *, stepper_event_callback_t, void *); @@ -90,14 +89,14 @@ static void fake_stepper_reset_rule_before(const struct ztest_unit_test *test, v ARG_UNUSED(fixture); RESET_FAKE(fake_stepper_enable); - RESET_FAKE(fake_stepper_move); + RESET_FAKE(fake_stepper_move_by); RESET_FAKE(fake_stepper_is_moving); - RESET_FAKE(fake_stepper_set_max_velocity); + RESET_FAKE(fake_stepper_set_microstep_interval); RESET_FAKE(fake_stepper_set_micro_step_res); RESET_FAKE(fake_stepper_get_micro_step_res); RESET_FAKE(fake_stepper_set_reference_position); RESET_FAKE(fake_stepper_get_actual_position); - RESET_FAKE(fake_stepper_set_target_position); + RESET_FAKE(fake_stepper_move_to); RESET_FAKE(fake_stepper_run); /* Install custom fakes for the setter and getter functions */ @@ -126,14 +125,14 @@ static int fake_stepper_init(const struct device *dev) static DEVICE_API(stepper, fake_stepper_driver_api) = { .enable = fake_stepper_enable, - .move = fake_stepper_move, + .move_by = fake_stepper_move_by, .is_moving = fake_stepper_is_moving, - .set_max_velocity = fake_stepper_set_max_velocity, + .set_microstep_interval = fake_stepper_set_microstep_interval, .set_micro_step_res = fake_stepper_set_micro_step_res, .get_micro_step_res = fake_stepper_get_micro_step_res, .set_reference_position = fake_stepper_set_reference_position, .get_actual_position = fake_stepper_get_actual_position, - .set_target_position = fake_stepper_set_target_position, + .move_to = fake_stepper_move_to, .run = fake_stepper_run, .set_event_callback = fake_stepper_set_event_callback, }; diff --git a/drivers/stepper/gpio_stepper_controller.c b/drivers/stepper/gpio_stepper_controller.c index ce7eb9ed74acd..404b685aac7ff 100644 --- a/drivers/stepper/gpio_stepper_controller.c +++ b/drivers/stepper/gpio_stepper_controller.c @@ -37,8 +37,9 @@ struct gpio_stepper_data { uint8_t coil_charge; struct k_work_delayable stepper_dwork; int32_t actual_position; - uint32_t delay_in_us; + uint64_t delay_in_ns; int32_t step_count; + bool is_enabled; stepper_event_callback_t callback; void *event_cb_user_data; }; @@ -110,10 +111,10 @@ static void update_remaining_steps(struct gpio_stepper_data *data) { if (data->step_count > 0) { data->step_count--; - (void)k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us)); + (void)k_work_reschedule(&data->stepper_dwork, K_NSEC(data->delay_in_ns)); } else if (data->step_count < 0) { data->step_count++; - (void)k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us)); + (void)k_work_reschedule(&data->stepper_dwork, K_NSEC(data->delay_in_ns)); } else { if (!data->callback) { LOG_WRN_ONCE("No callback set"); @@ -153,7 +154,7 @@ static void velocity_mode_task(const struct device *dev) (void)stepper_motor_set_coil_charge(dev); update_coil_charge(dev); - (void)k_work_reschedule(&data->stepper_dwork, K_USEC(data->delay_in_us)); + (void)k_work_reschedule(&data->stepper_dwork, K_NSEC(data->delay_in_ns)); } static void stepper_work_step_handler(struct k_work *work) @@ -177,12 +178,17 @@ static void stepper_work_step_handler(struct k_work *work) } } -static int gpio_stepper_move(const struct device *dev, int32_t micro_steps) +static int gpio_stepper_move_by(const struct device *dev, int32_t micro_steps) { struct gpio_stepper_data *data = dev->data; - if (data->delay_in_us == 0) { - LOG_ERR("Velocity not set or invalid velocity set"); + if (!data->is_enabled) { + LOG_ERR("Stepper motor is not enabled"); + return -ECANCELED; + } + + if (data->delay_in_ns == 0) { + LOG_ERR("Step interval not set or invalid step interval set"); return -EINVAL; } K_SPINLOCK(&data->lock) { @@ -214,17 +220,22 @@ static int gpio_stepper_get_actual_position(const struct device *dev, int32_t *p return 0; } -static int gpio_stepper_set_target_position(const struct device *dev, int32_t position) +static int gpio_stepper_move_to(const struct device *dev, int32_t micro_steps) { struct gpio_stepper_data *data = dev->data; - if (data->delay_in_us == 0) { - LOG_ERR("Velocity not set or invalid velocity set"); + if (!data->is_enabled) { + LOG_ERR("Stepper motor is not enabled"); + return -ECANCELED; + } + + if (data->delay_in_ns == 0) { + LOG_ERR("Step interval not set or invalid step interval set"); return -EINVAL; } K_SPINLOCK(&data->lock) { data->run_mode = STEPPER_RUN_MODE_POSITION; - data->step_count = position - data->actual_position; + data->step_count = micro_steps - data->actual_position; update_direction_from_step_count(dev); (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); } @@ -240,41 +251,36 @@ static int gpio_stepper_is_moving(const struct device *dev, bool *is_moving) return 0; } -static int gpio_stepper_set_max_velocity(const struct device *dev, uint32_t velocity) +static int gpio_stepper_set_microstep_interval(const struct device *dev, + uint64_t microstep_interval_ns) { struct gpio_stepper_data *data = dev->data; - if (velocity == 0) { - LOG_ERR("Velocity cannot be zero"); - return -EINVAL; - } - - if (velocity > USEC_PER_SEC) { - LOG_ERR("Velocity cannot be greater than %d micro_steps_per_second", USEC_PER_SEC); + if (microstep_interval_ns == 0) { + LOG_ERR("Step interval is invalid."); return -EINVAL; } K_SPINLOCK(&data->lock) { - data->delay_in_us = USEC_PER_SEC / velocity; + data->delay_in_ns = microstep_interval_ns; } - LOG_DBG("Setting Motor Speed to %d", velocity); + LOG_DBG("Setting Motor step interval to %llu", microstep_interval_ns); return 0; } -static int gpio_stepper_run(const struct device *dev, const enum stepper_direction direction, - const uint32_t velocity) +static int gpio_stepper_run(const struct device *dev, const enum stepper_direction direction) { struct gpio_stepper_data *data = dev->data; + if (!data->is_enabled) { + LOG_ERR("Stepper motor is not enabled"); + return -ECANCELED; + } + K_SPINLOCK(&data->lock) { data->run_mode = STEPPER_RUN_MODE_VELOCITY; data->direction = direction; - if (velocity != 0) { - data->delay_in_us = USEC_PER_SEC / velocity; - (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); - } else { - (void)k_work_cancel_delayable(&data->stepper_dwork); - } + (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); } return 0; } @@ -323,6 +329,9 @@ static int gpio_stepper_enable(const struct device *dev, bool enable) struct gpio_stepper_data *data = dev->data; K_SPINLOCK(&data->lock) { + + data->is_enabled = enable; + if (enable) { (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); } else { @@ -353,12 +362,12 @@ static int gpio_stepper_init(const struct device *dev) static DEVICE_API(stepper, gpio_stepper_api) = { .enable = gpio_stepper_enable, - .move = gpio_stepper_move, + .move_by = gpio_stepper_move_by, .is_moving = gpio_stepper_is_moving, .set_reference_position = gpio_stepper_set_reference_position, .get_actual_position = gpio_stepper_get_actual_position, - .set_target_position = gpio_stepper_set_target_position, - .set_max_velocity = gpio_stepper_set_max_velocity, + .move_to = gpio_stepper_move_to, + .set_microstep_interval = gpio_stepper_set_microstep_interval, .run = gpio_stepper_run, .set_micro_step_res = gpio_stepper_set_micro_step_res, .get_micro_step_res = gpio_stepper_get_micro_step_res, diff --git a/drivers/stepper/step_dir/CMakeLists.txt b/drivers/stepper/step_dir/CMakeLists.txt new file mode 100644 index 0000000000000..7daa4cc04d5b2 --- /dev/null +++ b/drivers/stepper/step_dir/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(step_dir_stepper_common.c) +zephyr_library_sources(step_dir_stepper_work_timing.c) +zephyr_library_sources_ifdef(CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING step_dir_stepper_counter_timing.c) diff --git a/drivers/stepper/step_dir/Kconfig b/drivers/stepper/step_dir/Kconfig new file mode 100644 index 0000000000000..d8629c649ffd2 --- /dev/null +++ b/drivers/stepper/step_dir/Kconfig @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +config STEP_DIR_STEPPER + bool + help + Enable library used for step direction stepper drivers. + +if STEP_DIR_STEPPER + +config STEP_DIR_STEPPER_COUNTER_TIMING + bool "Counter use for stepping" + select COUNTER + default y + help + Enable usage of a counter device for accurate stepping. + +module = STEP_DIR +module-str = step_dir +rsource "../Kconfig.stepper_event_template" + +endif # STEP_DIR_STEPPER diff --git a/drivers/stepper/step_dir/step_dir_stepper_common.c b/drivers/stepper/step_dir/step_dir_stepper_common.c new file mode 100644 index 0000000000000..a7ad2a2d35b76 --- /dev/null +++ b/drivers/stepper/step_dir/step_dir_stepper_common.c @@ -0,0 +1,340 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "step_dir_stepper_common.h" + +#include +LOG_MODULE_REGISTER(step_dir_stepper, CONFIG_STEPPER_LOG_LEVEL); + +static inline int step_dir_stepper_perform_step(const struct device *dev) +{ + const struct step_dir_stepper_common_config *config = dev->config; + struct step_dir_stepper_common_data *data = dev->data; + int ret; + + switch (data->direction) { + case STEPPER_DIRECTION_POSITIVE: + ret = gpio_pin_set_dt(&config->dir_pin, 1); + break; + case STEPPER_DIRECTION_NEGATIVE: + ret = gpio_pin_set_dt(&config->dir_pin, 0); + break; + default: + LOG_ERR("Unsupported direction: %d", data->direction); + return -ENOTSUP; + } + if (ret < 0) { + LOG_ERR("Failed to set direction: %d", ret); + return ret; + } + + ret = gpio_pin_toggle_dt(&config->step_pin); + if (ret < 0) { + LOG_ERR("Failed to toggle step pin: %d", ret); + return ret; + } + + if (!config->dual_edge) { + ret = gpio_pin_toggle_dt(&config->step_pin); + if (ret < 0) { + LOG_ERR("Failed to toggle step pin: %d", ret); + return ret; + } + } + + if (data->direction == STEPPER_DIRECTION_POSITIVE) { + data->actual_position++; + } else { + data->actual_position--; + } + + return 0; +} + +static void stepper_trigger_callback(const struct device *dev, enum stepper_event event) +{ + struct step_dir_stepper_common_data *data = dev->data; + + if (!data->callback) { + LOG_WRN_ONCE("No callback set"); + return; + } + + if (!k_is_in_isr()) { + data->callback(dev, event, data->event_cb_user_data); + return; + } + +#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS + /* Dispatch to msgq instead of raising directly */ + int ret = k_msgq_put(&data->event_msgq, &event, K_NO_WAIT); + + if (ret != 0) { + LOG_WRN("Failed to put event in msgq: %d", ret); + } + + ret = k_work_submit(&data->event_callback_work); + if (ret < 0) { + LOG_ERR("Failed to submit work item: %d", ret); + } +#else + LOG_WRN_ONCE("Event callback called from ISR context without ISR safe events enabled"); +#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */ +} + +#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS +static void stepper_work_event_handler(struct k_work *work) +{ + struct step_dir_stepper_common_data *data = + CONTAINER_OF(work, struct step_dir_stepper_common_data, event_callback_work); + enum stepper_event event; + int ret; + + ret = k_msgq_get(&data->event_msgq, &event, K_NO_WAIT); + if (ret != 0) { + return; + } + + /* Run the callback */ + if (data->callback != NULL) { + data->callback(data->dev, event, data->event_cb_user_data); + } + + /* If there are more pending events, resubmit this work item to handle them */ + if (k_msgq_num_used_get(&data->event_msgq) > 0) { + k_work_submit(work); + } +} +#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */ + +static void update_remaining_steps(struct step_dir_stepper_common_data *data) +{ + const struct step_dir_stepper_common_config *config = data->dev->config; + + if (data->step_count > 0) { + data->step_count--; + } else if (data->step_count < 0) { + data->step_count++; + } else { + stepper_trigger_callback(data->dev, STEPPER_EVENT_STEPS_COMPLETED); + config->timing_source->stop(data->dev); + } +} + +static void update_direction_from_step_count(const struct device *dev) +{ + struct step_dir_stepper_common_data *data = dev->data; + + if (data->step_count > 0) { + data->direction = STEPPER_DIRECTION_POSITIVE; + } else if (data->step_count < 0) { + data->direction = STEPPER_DIRECTION_NEGATIVE; + } else { + LOG_ERR("Step count is zero"); + } +} + +static void position_mode_task(const struct device *dev) +{ + struct step_dir_stepper_common_data *data = dev->data; + const struct step_dir_stepper_common_config *config = dev->config; + + if (data->step_count) { + (void)step_dir_stepper_perform_step(dev); + } + + update_remaining_steps(dev->data); + + if (config->timing_source->needs_reschedule(dev) && data->step_count != 0) { + (void)config->timing_source->start(dev); + } +} + +static void velocity_mode_task(const struct device *dev) +{ + const struct step_dir_stepper_common_config *config = dev->config; + + (void)step_dir_stepper_perform_step(dev); + + if (config->timing_source->needs_reschedule(dev)) { + (void)config->timing_source->start(dev); + } +} + +void stepper_handle_timing_signal(const struct device *dev) +{ + struct step_dir_stepper_common_data *data = dev->data; + + K_SPINLOCK(&data->lock) { + switch (data->run_mode) { + case STEPPER_RUN_MODE_POSITION: + position_mode_task(dev); + break; + case STEPPER_RUN_MODE_VELOCITY: + velocity_mode_task(dev); + break; + default: + LOG_WRN("Unsupported run mode: %d", data->run_mode); + break; + } + } +} + +int step_dir_stepper_common_init(const struct device *dev) +{ + const struct step_dir_stepper_common_config *config = dev->config; + int ret; + + if (!gpio_is_ready_dt(&config->step_pin) || !gpio_is_ready_dt(&config->dir_pin)) { + LOG_ERR("GPIO pins are not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->step_pin, GPIO_OUTPUT); + if (ret < 0) { + LOG_ERR("Failed to configure step pin: %d", ret); + return ret; + } + + ret = gpio_pin_configure_dt(&config->dir_pin, GPIO_OUTPUT); + if (ret < 0) { + LOG_ERR("Failed to configure dir pin: %d", ret); + return ret; + } + + if (config->timing_source->init) { + ret = config->timing_source->init(dev); + if (ret < 0) { + LOG_ERR("Failed to initialize timing source: %d", ret); + return ret; + } + } + +#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS + struct step_dir_stepper_common_data *data = dev->data; + + k_msgq_init(&data->event_msgq, data->event_msgq_buffer, sizeof(enum stepper_event), + CONFIG_STEPPER_STEP_DIR_EVENT_QUEUE_LEN); + k_work_init(&data->event_callback_work, stepper_work_event_handler); +#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */ + + return 0; +} + +int step_dir_stepper_common_move_by(const struct device *dev, const int32_t micro_steps) +{ + struct step_dir_stepper_common_data *data = dev->data; + const struct step_dir_stepper_common_config *config = dev->config; + + if (data->microstep_interval_ns == 0) { + LOG_ERR("Step interval not set or invalid step interval set"); + return -EINVAL; + } + + K_SPINLOCK(&data->lock) { + data->run_mode = STEPPER_RUN_MODE_POSITION; + data->step_count = micro_steps; + config->timing_source->update(dev, data->microstep_interval_ns); + update_direction_from_step_count(dev); + config->timing_source->start(dev); + } + + return 0; +} + +int step_dir_stepper_common_set_microstep_interval(const struct device *dev, + const uint64_t microstep_interval_ns) +{ + struct step_dir_stepper_common_data *data = dev->data; + const struct step_dir_stepper_common_config *config = dev->config; + + if (microstep_interval_ns == 0) { + LOG_ERR("Step interval cannot be zero"); + return -EINVAL; + } + + K_SPINLOCK(&data->lock) { + data->microstep_interval_ns = microstep_interval_ns; + config->timing_source->update(dev, microstep_interval_ns); + } + + return 0; +} + +int step_dir_stepper_common_set_reference_position(const struct device *dev, const int32_t value) +{ + struct step_dir_stepper_common_data *data = dev->data; + + K_SPINLOCK(&data->lock) { + data->actual_position = value; + } + + return 0; +} + +int step_dir_stepper_common_get_actual_position(const struct device *dev, int32_t *value) +{ + struct step_dir_stepper_common_data *data = dev->data; + + K_SPINLOCK(&data->lock) { + *value = data->actual_position; + } + + return 0; +} + +int step_dir_stepper_common_move_to(const struct device *dev, const int32_t value) +{ + struct step_dir_stepper_common_data *data = dev->data; + const struct step_dir_stepper_common_config *config = dev->config; + + if (data->microstep_interval_ns == 0) { + LOG_ERR("Step interval not set or invalid step interval set"); + return -EINVAL; + } + + K_SPINLOCK(&data->lock) { + data->run_mode = STEPPER_RUN_MODE_POSITION; + data->step_count = value - data->actual_position; + config->timing_source->update(dev, data->microstep_interval_ns); + update_direction_from_step_count(dev); + config->timing_source->start(dev); + } + + return 0; +} + +int step_dir_stepper_common_is_moving(const struct device *dev, bool *is_moving) +{ + const struct step_dir_stepper_common_config *config = dev->config; + + *is_moving = config->timing_source->is_running(dev); + return 0; +} + +int step_dir_stepper_common_run(const struct device *dev, const enum stepper_direction direction) +{ + struct step_dir_stepper_common_data *data = dev->data; + const struct step_dir_stepper_common_config *config = dev->config; + + K_SPINLOCK(&data->lock) { + data->run_mode = STEPPER_RUN_MODE_VELOCITY; + data->direction = direction; + config->timing_source->update(dev, data->microstep_interval_ns); + config->timing_source->start(dev); + } + + return 0; +} + +int step_dir_stepper_common_set_event_callback(const struct device *dev, + stepper_event_callback_t callback, void *user_data) +{ + struct step_dir_stepper_common_data *data = dev->data; + + data->callback = callback; + data->event_cb_user_data = user_data; + return 0; +} diff --git a/drivers/stepper/step_dir/step_dir_stepper_common.h b/drivers/stepper/step_dir/step_dir_stepper_common.h new file mode 100644 index 0000000000000..d84a9b30e3fc5 --- /dev/null +++ b/drivers/stepper/step_dir/step_dir_stepper_common.h @@ -0,0 +1,220 @@ +/* + * Copyright 2024 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_ +#define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_ + +/** + * @brief Stepper Driver APIs + * @defgroup step_dir_stepper Stepper Driver APIs + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include +#include + +#include "step_dir_stepper_timing_source.h" + +/** + * @brief Common step direction stepper config. + * + * This structure **must** be placed first in the driver's config structure. + */ +struct step_dir_stepper_common_config { + const struct gpio_dt_spec step_pin; + const struct gpio_dt_spec dir_pin; + bool dual_edge; + const struct stepper_timing_source_api *timing_source; + const struct device *counter; +}; + +/** + * @brief Initialize common step direction stepper config from devicetree instance. + * If the counter property is set, the timing source will be set to the counter timing + * source. + * + * @param node_id The devicetree node identifier. + */ +#define STEP_DIR_STEPPER_DT_COMMON_CONFIG_INIT(node_id) \ + { \ + .step_pin = GPIO_DT_SPEC_GET(node_id, step_gpios), \ + .dir_pin = GPIO_DT_SPEC_GET(node_id, dir_gpios), \ + .dual_edge = DT_PROP_OR(node_id, dual_edge_step, false), \ + .counter = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, counter)), \ + .timing_source = COND_CODE_1(DT_NODE_HAS_PROP(node_id, counter), \ + (&step_counter_timing_source_api), \ + (&step_work_timing_source_api)), \ + } + +/** + * @brief Initialize common step direction stepper config from devicetree instance. + * @param inst Instance. + */ +#define STEP_DIR_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst) \ + STEP_DIR_STEPPER_DT_COMMON_CONFIG_INIT(DT_DRV_INST(inst)) + +/** + * @brief Common step direction stepper data. + * + * This structure **must** be placed first in the driver's data structure. + */ +struct step_dir_stepper_common_data { + const struct device *dev; + struct k_spinlock lock; + enum stepper_direction direction; + enum stepper_run_mode run_mode; + int32_t actual_position; + uint64_t microstep_interval_ns; + int32_t step_count; + stepper_event_callback_t callback; + void *event_cb_user_data; + + struct k_work_delayable stepper_dwork; + +#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING + struct counter_top_cfg counter_top_cfg; + bool counter_running; +#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */ + +#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS + struct k_work event_callback_work; + struct k_msgq event_msgq; + uint8_t event_msgq_buffer[CONFIG_STEPPER_STEP_DIR_EVENT_QUEUE_LEN * + sizeof(enum stepper_event)]; +#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */ +}; + +/** + * @brief Initialize common step direction stepper data from devicetree instance. + * + * @param node_id The devicetree node identifier. + */ +#define STEP_DIR_STEPPER_DT_COMMON_DATA_INIT(node_id) \ + { \ + .dev = DEVICE_DT_GET(node_id), \ + } + +/** + * @brief Initialize common step direction stepper data from devicetree instance. + * @param inst Instance. + */ +#define STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst) \ + STEP_DIR_STEPPER_DT_COMMON_DATA_INIT(DT_DRV_INST(inst)) + +/** + * @brief Validate the offset of the common data structures. + * + * @param config Name of the config structure. + * @param data Name of the data structure. + */ +#define STEP_DIR_STEPPER_STRUCT_CHECK(config, data) \ + BUILD_ASSERT(offsetof(config, common) == 0, \ + "struct step_dir_stepper_common_config must be placed first"); \ + BUILD_ASSERT(offsetof(data, common) == 0, \ + "struct step_dir_stepper_common_data must be placed first"); + +/** + * @brief Common function to initialize a step direction stepper device at init time. + * + * This function must be called at the end of the device init function. + * + * @param dev Step direction stepper device instance. + * + * @retval 0 If initialized successfully. + * @retval -errno Negative errno in case of failure. + */ +int step_dir_stepper_common_init(const struct device *dev); + +/** + * @brief Move the stepper motor by a given number of micro_steps. + * + * @param dev Pointer to the device structure. + * @param micro_steps Number of micro_steps to move. Can be positive or negative. + * @return 0 on success, or a negative error code on failure. + */ +int step_dir_stepper_common_move_by(const struct device *dev, const int32_t micro_steps); + +/** + * @brief Set the step interval of the stepper motor. + * + * @param dev Pointer to the device structure. + * @param microstep_interval_ns The step interval in nanoseconds. + * @return 0 on success, or a negative error code on failure. + */ +int step_dir_stepper_common_set_microstep_interval(const struct device *dev, + const uint64_t microstep_interval_ns); + +/** + * @brief Set the reference position of the stepper motor. + * + * @param dev Pointer to the device structure. + * @param value The reference position value to set. + * @return 0 on success, or a negative error code on failure. + */ +int step_dir_stepper_common_set_reference_position(const struct device *dev, const int32_t value); + +/** + * @brief Get the actual (reference) position of the stepper motor. + * + * @param dev Pointer to the device structure. + * @param value Pointer to a variable where the position value will be stored. + * @return 0 on success, or a negative error code on failure. + */ +int step_dir_stepper_common_get_actual_position(const struct device *dev, int32_t *value); + +/** + * @brief Set the absolute target position of the stepper motor. + * + * @param dev Pointer to the device structure. + * @param value The target position to set. + * @return 0 on success, or a negative error code on failure. + */ +int step_dir_stepper_common_move_to(const struct device *dev, const int32_t value); + +/** + * @brief Check if the stepper motor is still moving. + * + * @param dev Pointer to the device structure. + * @param is_moving Pointer to a boolean where the movement status will be stored. + * @return 0 on success, or a negative error code on failure. + */ +int step_dir_stepper_common_is_moving(const struct device *dev, bool *is_moving); + +/** + * @brief Run the stepper with a given direction and step interval. + * + * @param dev Pointer to the device structure. + * @param direction The direction of movement (positive or negative). + * @return 0 on success, or a negative error code on failure. + */ +int step_dir_stepper_common_run(const struct device *dev, const enum stepper_direction direction); + +/** + * @brief Set a callback function for stepper motor events. + * + * This function sets a user-defined callback that will be invoked when a stepper motor event + * occurs. + * + * @param dev Pointer to the device structure. + * @param callback The callback function to set. + * @param user_data Pointer to user-defined data that will be passed to the callback. + * @return 0 on success, or a negative error code on failure. + */ +int step_dir_stepper_common_set_event_callback(const struct device *dev, + stepper_event_callback_t callback, void *user_data); + +/** + * @brief Handle a timing signal and update the stepper position. + * @param dev Pointer to the device structure. + */ +void stepper_handle_timing_signal(const struct device *dev); + +/** @} */ + +#endif /* ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_ */ diff --git a/drivers/stepper/step_dir/step_dir_stepper_counter_timing.c b/drivers/stepper/step_dir/step_dir_stepper_counter_timing.c new file mode 100644 index 0000000000000..bad216961e575 --- /dev/null +++ b/drivers/stepper/step_dir/step_dir_stepper_counter_timing.c @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "step_dir_stepper_common.h" + +#include +LOG_MODULE_DECLARE(step_dir_stepper); + +static void step_counter_top_interrupt(const struct device *dev, void *user_data) +{ + ARG_UNUSED(dev); + struct step_dir_stepper_common_data *data = user_data; + + stepper_handle_timing_signal(data->dev); +} + +int step_counter_timing_source_update(const struct device *dev, + const uint64_t microstep_interval_ns) +{ + const struct step_dir_stepper_common_config *config = dev->config; + struct step_dir_stepper_common_data *data = dev->data; + int ret; + + if (microstep_interval_ns == 0) { + return -EINVAL; + } + + data->counter_top_cfg.ticks = DIV_ROUND_UP( + counter_get_frequency(config->counter) * microstep_interval_ns, NSEC_PER_SEC); + + /* Lock interrupts while modifying counter settings */ + int key = irq_lock(); + + ret = counter_set_top_value(config->counter, &data->counter_top_cfg); + + irq_unlock(key); + + if (ret != 0) { + LOG_ERR("%s: Failed to set counter top value (error: %d)", dev->name, ret); + return ret; + } + + return 0; +} + +int step_counter_timing_source_start(const struct device *dev) +{ + const struct step_dir_stepper_common_config *config = dev->config; + struct step_dir_stepper_common_data *data = dev->data; + int ret; + + ret = counter_start(config->counter); + if (ret < 0 && ret != -EALREADY) { + LOG_ERR("Failed to start counter: %d", ret); + return ret; + } + + data->counter_running = true; + + return 0; +} + +int step_counter_timing_source_stop(const struct device *dev) +{ + const struct step_dir_stepper_common_config *config = dev->config; + struct step_dir_stepper_common_data *data = dev->data; + int ret; + + ret = counter_stop(config->counter); + if (ret < 0 && ret != -EALREADY) { + LOG_ERR("Failed to stop counter: %d", ret); + return ret; + } + + data->counter_running = false; + + return 0; +} + +bool step_counter_timing_source_needs_reschedule(const struct device *dev) +{ + ARG_UNUSED(dev); + return false; +} + +bool step_counter_timing_source_is_running(const struct device *dev) +{ + struct step_dir_stepper_common_data *data = dev->data; + + return data->counter_running; +} + +int step_counter_timing_source_init(const struct device *dev) +{ + const struct step_dir_stepper_common_config *config = dev->config; + struct step_dir_stepper_common_data *data = dev->data; + + if (!device_is_ready(config->counter)) { + LOG_ERR("Counter device is not ready"); + return -ENODEV; + } + + data->counter_top_cfg.callback = step_counter_top_interrupt; + data->counter_top_cfg.user_data = data; + data->counter_top_cfg.flags = 0; + data->counter_top_cfg.ticks = counter_us_to_ticks(config->counter, 1000000); + + return 0; +} + +const struct stepper_timing_source_api step_counter_timing_source_api = { + .init = step_counter_timing_source_init, + .update = step_counter_timing_source_update, + .start = step_counter_timing_source_start, + .needs_reschedule = step_counter_timing_source_needs_reschedule, + .stop = step_counter_timing_source_stop, + .is_running = step_counter_timing_source_is_running, +}; diff --git a/drivers/stepper/step_dir/step_dir_stepper_timing_source.h b/drivers/stepper/step_dir/step_dir_stepper_timing_source.h new file mode 100644 index 0000000000000..4c77993614afc --- /dev/null +++ b/drivers/stepper/step_dir/step_dir_stepper_timing_source.h @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_ +#define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_ + +#include + +/** + * @brief Initialize the stepper timing source. + * + * @param dev Pointer to the device structure. + * @return 0 on success, or a negative error code on failure. + */ +typedef int (*stepper_timing_source_init)(const struct device *dev); + +/** + * @brief Update the stepper timing source. + * + * @param dev Pointer to the device structure. + * @param microstep_interval_ns Step interval in nanoseconds. + * @return 0 on success, or a negative error code on failure. + */ +typedef int (*stepper_timing_source_update)(const struct device *dev, + uint64_t microstep_interval_ns); + +/** + * @brief Start the stepper timing source. + * + * @param dev Pointer to the device structure. + * @return 0 on success, or a negative error code on failure. + */ +typedef int (*stepper_timing_source_start)(const struct device *dev); + +/** + * @brief Whether the stepper timing source requires rescheduling (keeps running + * after the initial start). + * + * @param dev Pointer to the device structure. + * @return true if the timing source requires rescheduling, false otherwise. + */ +typedef bool (*stepper_timing_sources_requires_reschedule)(const struct device *dev); + +/** + * @brief Stop the stepper timing source. + * + * @param dev Pointer to the device structure. + * @return 0 on success, or a negative error code on failure. + */ +typedef int (*stepper_timing_source_stop)(const struct device *dev); + +/** + * @brief Check if the stepper timing source is running. + * + * @param dev Pointer to the device structure. + * @return true if the timing source is running, false otherwise. + */ +typedef bool (*stepper_timing_source_is_running)(const struct device *dev); + +/** + * @brief Stepper timing source API. + */ +struct stepper_timing_source_api { + stepper_timing_source_init init; + stepper_timing_source_update update; + stepper_timing_source_start start; + stepper_timing_sources_requires_reschedule needs_reschedule; + stepper_timing_source_stop stop; + stepper_timing_source_is_running is_running; +}; + +extern const struct stepper_timing_source_api step_work_timing_source_api; +#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING +extern const struct stepper_timing_source_api step_counter_timing_source_api; +#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */ + +#endif /* ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_ */ diff --git a/drivers/stepper/step_dir/step_dir_stepper_work_timing.c b/drivers/stepper/step_dir/step_dir_stepper_work_timing.c new file mode 100644 index 0000000000000..ac605f1f49727 --- /dev/null +++ b/drivers/stepper/step_dir/step_dir_stepper_work_timing.c @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "step_dir_stepper_timing_source.h" +#include "step_dir_stepper_common.h" + +static k_timeout_t stepper_movement_delay(const struct device *dev) +{ + const struct step_dir_stepper_common_data *data = dev->data; + + if (data->microstep_interval_ns == 0) { + return K_FOREVER; + } + + return K_NSEC(data->microstep_interval_ns); +} + +static void stepper_work_step_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct step_dir_stepper_common_data *data = + CONTAINER_OF(dwork, struct step_dir_stepper_common_data, stepper_dwork); + + stepper_handle_timing_signal(data->dev); +} + +int step_work_timing_source_init(const struct device *dev) +{ + struct step_dir_stepper_common_data *data = dev->data; + + k_work_init_delayable(&data->stepper_dwork, stepper_work_step_handler); + + return 0; +} + +int step_work_timing_source_update(const struct device *dev, const uint64_t microstep_interval_ns) +{ + ARG_UNUSED(dev); + ARG_UNUSED(microstep_interval_ns); + return 0; +} + +int step_work_timing_source_start(const struct device *dev) +{ + struct step_dir_stepper_common_data *data = dev->data; + + return k_work_reschedule(&data->stepper_dwork, stepper_movement_delay(dev)); +} + +int step_work_timing_source_stop(const struct device *dev) +{ + struct step_dir_stepper_common_data *data = dev->data; + + return k_work_cancel_delayable(&data->stepper_dwork); +} + +bool step_work_timing_source_needs_reschedule(const struct device *dev) +{ + ARG_UNUSED(dev); + return true; +} + +bool step_work_timing_source_is_running(const struct device *dev) +{ + struct step_dir_stepper_common_data *data = dev->data; + + return k_work_delayable_is_pending(&data->stepper_dwork); +} + +const struct stepper_timing_source_api step_work_timing_source_api = { + .init = step_work_timing_source_init, + .update = step_work_timing_source_update, + .start = step_work_timing_source_start, + .needs_reschedule = step_work_timing_source_needs_reschedule, + .stop = step_work_timing_source_stop, + .is_running = step_work_timing_source_is_running, +}; diff --git a/drivers/stepper/stepper_shell.c b/drivers/stepper/stepper_shell.c index 76217cba9da3a..6b5d8035f906c 100644 --- a/drivers/stepper/stepper_shell.c +++ b/drivers/stepper/stepper_shell.c @@ -67,6 +67,11 @@ static void print_callback(const struct device *dev, const enum stepper_event ev } } +static bool device_is_stepper(const struct device *dev) +{ + return DEVICE_API_IS(stepper, dev); +} + static const struct stepper_direction_map stepper_direction_map[] = { STEPPER_DIRECTION_MAP_ENTRY("positive", STEPPER_DIRECTION_POSITIVE), STEPPER_DIRECTION_MAP_ENTRY("negative", STEPPER_DIRECTION_NEGATIVE), @@ -114,7 +119,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_stepper_microstep, cmd_stepper_microstep); static void cmd_pos_stepper_motor_name(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_stepper); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; @@ -126,7 +131,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_pos_stepper_motor_name, cmd_pos_stepper_motor_name static void cmd_pos_stepper_motor_name_dir(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_stepper); if (dev != NULL) { entry->syntax = dev->name; @@ -142,7 +147,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_pos_stepper_motor_name_dir, cmd_pos_stepper_motor_ static void cmd_pos_stepper_motor_name_microstep(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_stepper); if (dev != NULL) { entry->syntax = dev->name; @@ -159,7 +164,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_pos_stepper_motor_name_microstep, static int parse_device_arg(const struct shell *sh, char **argv, const struct device **dev) { - *dev = device_get_binding(argv[ARG_IDX_DEV]); + *dev = shell_device_get_binding(argv[ARG_IDX_DEV]); if (!*dev) { shell_error(sh, "Stepper device %s not found", argv[ARG_IDX_DEV]); return -ENODEV; @@ -190,7 +195,7 @@ static int cmd_stepper_enable(const struct shell *sh, size_t argc, char **argv) return err; } -static int cmd_stepper_move(const struct shell *sh, size_t argc, char **argv) +static int cmd_stepper_move_by(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; int err = 0; @@ -211,7 +216,7 @@ static int cmd_stepper_move(const struct shell *sh, size_t argc, char **argv) shell_error(sh, "Failed to set callback: %d", err); } - err = stepper_move(dev, micro_steps); + err = stepper_move_by(dev, micro_steps); if (err) { shell_error(sh, "Error: %d", err); } @@ -219,11 +224,11 @@ static int cmd_stepper_move(const struct shell *sh, size_t argc, char **argv) return err; } -static int cmd_stepper_set_max_velocity(const struct shell *sh, size_t argc, char **argv) +static int cmd_stepper_set_microstep_interval(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; int err = 0; - uint32_t velocity = shell_strtoul(argv[ARG_IDX_PARAM], 10, &err); + uint64_t step_interval = shell_strtoull(argv[ARG_IDX_PARAM], 10, &err); if (err < 0) { return err; @@ -234,7 +239,7 @@ static int cmd_stepper_set_max_velocity(const struct shell *sh, size_t argc, cha return err; } - err = stepper_set_max_velocity(dev, velocity); + err = stepper_set_microstep_interval(dev, step_interval); if (err) { shell_error(sh, "Error: %d", err); } @@ -338,7 +343,7 @@ static int cmd_stepper_get_actual_position(const struct shell *sh, size_t argc, return err; } -static int cmd_stepper_set_target_position(const struct shell *sh, size_t argc, char **argv) +static int cmd_stepper_move_to(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; int err = 0; @@ -358,7 +363,7 @@ static int cmd_stepper_set_target_position(const struct shell *sh, size_t argc, shell_error(sh, "Failed to set callback: %d", err); } - err = stepper_set_target_position(dev, position); + err = stepper_move_to(dev, position); if (err) { shell_error(sh, "Error: %d", err); } @@ -384,12 +389,6 @@ static int cmd_stepper_run(const struct shell *sh, size_t argc, char **argv) return err; } - uint32_t velocity = shell_strtoul(argv[ARG_IDX_VALUE], 10, &err); - - if (err < 0) { - return err; - } - err = parse_device_arg(sh, argv, &dev); if (err < 0) { return err; @@ -400,7 +399,7 @@ static int cmd_stepper_run(const struct shell *sh, size_t argc, char **argv) shell_error(sh, "Failed to set callback: %d", err); } - err = stepper_run(dev, direction, velocity); + err = stepper_run(dev, direction); if (err) { shell_error(sh, "Error: %d", err); return err; @@ -453,10 +452,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE( stepper_cmds, SHELL_CMD_ARG(enable, &dsub_pos_stepper_motor_name, " ", cmd_stepper_enable, 3, 0), - SHELL_CMD_ARG(move, &dsub_pos_stepper_motor_name, " ", - cmd_stepper_move, 3, 0), - SHELL_CMD_ARG(set_max_velocity, &dsub_pos_stepper_motor_name, " ", - cmd_stepper_set_max_velocity, 3, 0), + SHELL_CMD_ARG(move_by, &dsub_pos_stepper_motor_name, " ", + cmd_stepper_move_by, 3, 0), + SHELL_CMD_ARG(set_microstep_interval, &dsub_pos_stepper_motor_name, + " ", cmd_stepper_set_microstep_interval, 3, 0), SHELL_CMD_ARG(set_micro_step_res, &dsub_pos_stepper_motor_name_microstep, " ", cmd_stepper_set_micro_step_res, 3, 0), SHELL_CMD_ARG(get_micro_step_res, &dsub_pos_stepper_motor_name, "", @@ -465,10 +464,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE( cmd_stepper_set_reference_position, 3, 0), SHELL_CMD_ARG(get_actual_position, &dsub_pos_stepper_motor_name, "", cmd_stepper_get_actual_position, 2, 0), - SHELL_CMD_ARG(set_target_position, &dsub_pos_stepper_motor_name, " ", - cmd_stepper_set_target_position, 3, 0), - SHELL_CMD_ARG(run, &dsub_pos_stepper_motor_name_dir, " ", - cmd_stepper_run, 4, 0), + SHELL_CMD_ARG(move_to, &dsub_pos_stepper_motor_name, " ", + cmd_stepper_move_to, 3, 0), + SHELL_CMD_ARG(run, &dsub_pos_stepper_motor_name_dir, " ", + cmd_stepper_run, 3, 0), SHELL_CMD_ARG(info, &dsub_pos_stepper_motor_name, "", cmd_stepper_info, 2, 0), SHELL_SUBCMD_SET_END); diff --git a/drivers/stepper/ti/CMakeLists.txt b/drivers/stepper/ti/CMakeLists.txt new file mode 100644 index 0000000000000..8594fb8e1ed9c --- /dev/null +++ b/drivers/stepper/ti/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Navimatix GmbH +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_property(ALLOW_EMPTY TRUE) + +zephyr_library_sources_ifdef(CONFIG_DRV8424 drv8424.c) diff --git a/drivers/stepper/ti/Kconfig b/drivers/stepper/ti/Kconfig new file mode 100644 index 0000000000000..99c989f6e75fb --- /dev/null +++ b/drivers/stepper/ti/Kconfig @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Navimatix GmbH +# SPDX-License-Identifier: Apache-2.0 + +config STEPPER_TI + bool + depends on STEPPER + +rsource "Kconfig.drv8424" diff --git a/drivers/stepper/ti/Kconfig.drv8424 b/drivers/stepper/ti/Kconfig.drv8424 new file mode 100644 index 0000000000000..f359cdf7c0598 --- /dev/null +++ b/drivers/stepper/ti/Kconfig.drv8424 @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Navimatix GmbH +# SPDX-License-Identifier: Apache-2.0 + +config DRV8424 + bool "TI DRV8424 stepper motor driver" + default y + depends on DT_HAS_TI_DRV8424_ENABLED + select STEPPER_TI + select STEP_DIR_STEPPER + select STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS + help + Enable driver for TI DRV8424 stepper motor driver. diff --git a/drivers/stepper/ti/drv8424.c b/drivers/stepper/ti/drv8424.c new file mode 100644 index 0000000000000..9fd172fc0ecc5 --- /dev/null +++ b/drivers/stepper/ti/drv8424.c @@ -0,0 +1,368 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Navimatix GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_drv8424 + +#include +#include +#include +#include +#include "../step_dir/step_dir_stepper_common.h" + +#include +LOG_MODULE_REGISTER(drv8424, CONFIG_STEPPER_LOG_LEVEL); + +/** + * @brief DRV8424 stepper driver configuration data. + * + * This structure contains all of the devicetree specifications for the pins + * needed by a given DRV8424 stepper driver. + */ +struct drv8424_config { + struct step_dir_stepper_common_config common; + struct gpio_dt_spec sleep_pin; + struct gpio_dt_spec en_pin; + struct gpio_dt_spec m0_pin; + struct gpio_dt_spec m1_pin; +}; + +/* Struct for storing the states of output pins. */ +struct drv8424_pin_states { + uint8_t sleep: 1; + uint8_t en: 1; + uint8_t m0: 2; + uint8_t m1: 2; +}; + +/** + * @brief DRV8424 stepper driver data. + * + * This structure contains mutable data used by a DRV8424 stepper driver. + */ +struct drv8424_data { + const struct step_dir_stepper_common_data common; + bool enabled; + struct drv8424_pin_states pin_states; + enum stepper_micro_step_resolution ustep_res; +}; + +STEP_DIR_STEPPER_STRUCT_CHECK(struct drv8424_config, struct drv8424_data); + +static int drv8424_set_microstep_pin(const struct device *dev, const struct gpio_dt_spec *pin, + int value) +{ + int ret; + + /* Reset microstep pin as it may have been disconnected. */ + ret = gpio_pin_configure_dt(pin, GPIO_OUTPUT_INACTIVE); + if (ret != 0) { + LOG_ERR("%s: Failed to reset micro-step pin (error: %d)", dev->name, ret); + return ret; + } + + /* Set microstep pin */ + switch (value) { + case 0: + ret = gpio_pin_set_dt(pin, 0); + break; + case 1: + ret = gpio_pin_set_dt(pin, 1); + break; + case 2: + /* Hi-Z is set by configuring pin as disconnected, not + * all gpio controllers support this. + */ + ret = gpio_pin_configure_dt(pin, GPIO_DISCONNECTED); + break; + default: + break; + } + + if (ret != 0) { + LOG_ERR("%s: Failed to set micro-step pin (error: %d)", dev->name, ret); + return ret; + } + return 0; +} + +/* + * If microstep setter fails, attempt to recover into previous state. + */ +int drv8424_microstep_recovery(const struct device *dev) +{ + const struct drv8424_config *config = dev->config; + struct drv8424_data *data = dev->data; + int ret; + + uint8_t m0_value = data->pin_states.m0; + uint8_t m1_value = data->pin_states.m1; + + ret = drv8424_set_microstep_pin(dev, &config->m0_pin, m0_value); + if (ret != 0) { + LOG_ERR("%s: Failed to restore microstep configuration (error: %d)", dev->name, + ret); + return ret; + } + + ret = drv8424_set_microstep_pin(dev, &config->m1_pin, m1_value); + if (ret != 0) { + LOG_ERR("%s: Failed to restore microstep configuration (error: %d)", dev->name, + ret); + return ret; + } + + return 0; +} + +static int drv8424_enable(const struct device *dev, bool enable) +{ + int ret; + const struct drv8424_config *config = dev->config; + struct drv8424_data *data = dev->data; + bool has_enable_pin = config->en_pin.port != NULL; + bool has_sleep_pin = config->sleep_pin.port != NULL; + + /* Check availability of sleep and enable pins, as these might be hardwired. */ + if (!has_sleep_pin && !has_enable_pin) { + LOG_ERR("%s: Failed to enable/disable device, neither sleep pin nor enable pin are " + "available. The device is always on.", + dev->name); + return -ENOTSUP; + } + + if (has_sleep_pin) { + ret = gpio_pin_set_dt(&config->sleep_pin, !enable); + if (ret != 0) { + LOG_ERR("%s: Failed to set sleep_pin (error: %d)", dev->name, ret); + return ret; + } + data->pin_states.sleep = enable ? 0U : 1U; + } + + if (has_enable_pin) { + ret = gpio_pin_set_dt(&config->en_pin, enable); + if (ret != 0) { + LOG_ERR("%s: Failed to set en_pin (error: %d)", dev->name, ret); + return ret; + } + data->pin_states.en = enable ? 1U : 0U; + } + + data->enabled = enable; + if (!enable) { + config->common.timing_source->stop(dev); + gpio_pin_set_dt(&config->common.step_pin, 0); + } + + return 0; +} + +static int drv8424_set_micro_step_res(const struct device *dev, + enum stepper_micro_step_resolution micro_step_res) +{ + const struct drv8424_config *config = dev->config; + struct drv8424_data *data = dev->data; + int ret; + + uint8_t m0_value = 0; + uint8_t m1_value = 0; + + /* 0: low + * 1: high + * 2: Hi-Z + * 3: 330kΊ + */ + switch (micro_step_res) { + case STEPPER_MICRO_STEP_1: + m0_value = 0; + m1_value = 0; + break; + case STEPPER_MICRO_STEP_2: + m0_value = 2; + m1_value = 0; + break; + case STEPPER_MICRO_STEP_4: + m0_value = 0; + m1_value = 1; + break; + case STEPPER_MICRO_STEP_8: + m0_value = 1; + m1_value = 1; + break; + case STEPPER_MICRO_STEP_16: + m0_value = 2; + m1_value = 1; + break; + case STEPPER_MICRO_STEP_32: + m0_value = 0; + m1_value = 2; + break; + case STEPPER_MICRO_STEP_64: + m0_value = 2; + m1_value = 3; + break; + case STEPPER_MICRO_STEP_128: + m0_value = 2; + m1_value = 2; + break; + case STEPPER_MICRO_STEP_256: + m0_value = 1; + m1_value = 2; + break; + default: + return -EINVAL; + }; + + ret = drv8424_set_microstep_pin(dev, &config->m0_pin, m0_value); + if (ret != 0) { + return ret; + } + + ret = drv8424_set_microstep_pin(dev, &config->m1_pin, m1_value); + if (ret != 0) { + return ret; + } + + data->ustep_res = micro_step_res; + data->pin_states.m0 = m0_value; + data->pin_states.m1 = m1_value; + + return 0; +} + +static int drv8424_get_micro_step_res(const struct device *dev, + enum stepper_micro_step_resolution *micro_step_res) +{ + struct drv8424_data *data = dev->data; + *micro_step_res = data->ustep_res; + return 0; +} + +static int drv8424_move_to(const struct device *dev, int32_t target) +{ + struct drv8424_data *data = dev->data; + + if (!data->enabled) { + LOG_ERR("Failed to move to target position, device is not enabled"); + return -ECANCELED; + } + + return step_dir_stepper_common_move_to(dev, target); +} + +static int drv8424_move_by(const struct device *dev, int32_t steps) +{ + struct drv8424_data *data = dev->data; + + if (!data->enabled) { + LOG_ERR("Failed to move by delta, device is not enabled"); + return -ECANCELED; + } + + return step_dir_stepper_common_move_by(dev, steps); +} + +static int drv8424_run(const struct device *dev, enum stepper_direction direction) +{ + struct drv8424_data *data = dev->data; + + if (!data->enabled) { + LOG_ERR("Failed to run stepper, device is not enabled"); + return -ECANCELED; + } + + return step_dir_stepper_common_run(dev, direction); +} + +static int drv8424_init(const struct device *dev) +{ + const struct drv8424_config *const config = dev->config; + struct drv8424_data *const data = dev->data; + int ret; + + /* Configure sleep pin if it is available */ + if (config->sleep_pin.port != NULL) { + ret = gpio_pin_configure_dt(&config->sleep_pin, GPIO_OUTPUT_ACTIVE); + if (ret != 0) { + LOG_ERR("%s: Failed to configure sleep_pin (error: %d)", dev->name, ret); + return ret; + } + data->pin_states.sleep = 1U; + } + + /* Configure enable pin if it is available */ + if (config->en_pin.port != NULL) { + ret = gpio_pin_configure_dt(&config->en_pin, GPIO_OUTPUT_INACTIVE); + if (ret != 0) { + LOG_ERR("%s: Failed to configure en_pin (error: %d)", dev->name, ret); + return ret; + } + data->pin_states.en = 0U; + } + + /* Configure microstep pin 0 */ + ret = gpio_pin_configure_dt(&config->m0_pin, GPIO_OUTPUT_INACTIVE); + if (ret != 0) { + LOG_ERR("%s: Failed to configure m0_pin (error: %d)", dev->name, ret); + return ret; + } + data->pin_states.m0 = 0U; + + /* Configure microstep pin 1 */ + ret = gpio_pin_configure_dt(&config->m1_pin, GPIO_OUTPUT_INACTIVE); + if (ret != 0) { + LOG_ERR("%s: Failed to configure m1_pin (error: %d)", dev->name, ret); + return ret; + } + data->pin_states.m1 = 0U; + + ret = drv8424_set_micro_step_res(dev, data->ustep_res); + if (ret != 0) { + return ret; + } + + ret = step_dir_stepper_common_init(dev); + if (ret != 0) { + LOG_ERR("Failed to initialize common step direction stepper (error: %d)", ret); + return ret; + } + + return 0; +} + +static DEVICE_API(stepper, drv8424_stepper_api) = { + .enable = drv8424_enable, + .move_by = drv8424_move_by, + .move_to = drv8424_move_to, + .is_moving = step_dir_stepper_common_is_moving, + .set_reference_position = step_dir_stepper_common_set_reference_position, + .get_actual_position = step_dir_stepper_common_get_actual_position, + .set_microstep_interval = step_dir_stepper_common_set_microstep_interval, + .run = drv8424_run, + .set_micro_step_res = drv8424_set_micro_step_res, + .get_micro_step_res = drv8424_get_micro_step_res, + .set_event_callback = step_dir_stepper_common_set_event_callback, +}; + +#define DRV8424_DEVICE(inst) \ + \ + static const struct drv8424_config drv8424_config_##inst = { \ + .common = STEP_DIR_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst), \ + .sleep_pin = GPIO_DT_SPEC_INST_GET_OR(inst, sleep_gpios, {0}), \ + .en_pin = GPIO_DT_SPEC_INST_GET_OR(inst, en_gpios, {0}), \ + .m0_pin = GPIO_DT_SPEC_INST_GET(inst, m0_gpios), \ + .m1_pin = GPIO_DT_SPEC_INST_GET(inst, m1_gpios), \ + }; \ + \ + static struct drv8424_data drv8424_data_##inst = { \ + .common = STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst), \ + .ustep_res = DT_INST_PROP(inst, micro_step_res), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &drv8424_init, NULL, &drv8424_data_##inst, \ + &drv8424_config_##inst, POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY, \ + &drv8424_stepper_api); + +DT_INST_FOREACH_STATUS_OKAY(DRV8424_DEVICE) diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index cacc2a08736cb..9a6b2697e988c 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -2,6 +2,7 @@ zephyr_library() zephyr_library_sources(sys_clock_init.c) +zephyr_library_sources_ifdef(CONFIG_LLEXT export.c) zephyr_library_sources_ifdef(CONFIG_ALTERA_AVALON_TIMER altera_avalon_timer_hal.c) zephyr_library_sources_ifdef(CONFIG_AMBIQ_STIMER_TIMER ambiq_stimer.c) zephyr_library_sources_ifdef(CONFIG_APIC_TIMER apic_timer.c) @@ -11,6 +12,7 @@ zephyr_library_sources_ifdef(CONFIG_ARCV2_TIMER arcv2_timer0.c) zephyr_library_sources_ifdef(CONFIG_ARM_ARCH_TIMER arm_arch_timer.c) zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_TIMER intel_adsp_timer.c) zephyr_library_sources_ifdef(CONFIG_CC13XX_CC26XX_RTC_TIMER cc13xx_cc26xx_rtc_timer.c) +zephyr_library_sources_ifdef(CONFIG_CC23X0_SYSTIM_TIMER cc23x0_systim_timer.c) zephyr_library_sources_ifdef(CONFIG_CH32V00X_SYSTICK wch_systick_ch32v00x.c) zephyr_library_sources_ifdef(CONFIG_CORTEX_M_SYSTICK cortex_m_systick.c) zephyr_library_sources_ifdef(CONFIG_ESP32_SYS_TIMER esp32_sys_timer.c) @@ -32,6 +34,7 @@ zephyr_library_sources_ifdef(CONFIG_NRF_RTC_TIMER nrf_rtc_timer.c) zephyr_library_sources_ifdef(CONFIG_RCAR_CMT_TIMER rcar_cmt_timer.c) zephyr_library_sources_ifdef(CONFIG_RISCV_MACHINE_TIMER riscv_machine_timer.c) zephyr_library_sources_ifdef(CONFIG_RV32M1_LPTMR_TIMER rv32m1_lptmr_timer.c) +zephyr_library_sources_ifdef(CONFIG_REALTEK_RTS5912_RTMR realtek_rts5912_rtmr.c) zephyr_library_sources_ifdef(CONFIG_SAM0_RTC_TIMER sam0_rtc_timer.c) zephyr_library_sources_ifdef(CONFIG_SILABS_SLEEPTIMER_TIMER silabs_sleeptimer_timer.c) zephyr_library_sources_ifdef(CONFIG_STM32_LPTIM_TIMER stm32_lptim_timer.c) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index a43e666349c13..839dec71fa26b 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -70,6 +70,7 @@ source "drivers/timer/Kconfig.arcv2" source "drivers/timer/Kconfig.arm_arch" source "drivers/timer/Kconfig.cavs" source "drivers/timer/Kconfig.cc13xx_cc26xx_rtc" +source "drivers/timer/Kconfig.cc23x0_systim" source "drivers/timer/Kconfig.wch_ch32v00x" source "drivers/timer/Kconfig.cortex_m_systick" source "drivers/timer/Kconfig.esp32" @@ -91,6 +92,7 @@ source "drivers/timer/Kconfig.nrf_xrtc" source "drivers/timer/Kconfig.rcar_cmt" source "drivers/timer/Kconfig.riscv_machine" source "drivers/timer/Kconfig.rv32m1_lptmr" +source "drivers/timer/Kconfig.realtek_rts5912_rtmr" source "drivers/timer/Kconfig.sam0_rtc" source "drivers/timer/Kconfig.silabs" source "drivers/timer/Kconfig.smartbond" diff --git a/drivers/timer/Kconfig.cc23x0_systim b/drivers/timer/Kconfig.cc23x0_systim new file mode 100644 index 0000000000000..41db73e6d52c6 --- /dev/null +++ b/drivers/timer/Kconfig.cc23x0_systim @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config CC23X0_SYSTIM_TIMER + bool "TI SimpleLink CC23X0 system clock timer" + default y + depends on HAS_CC23X0_SDK + select TICKLESS_CAPABLE + help + This module provides the "system clock driver" interfaces + for the TI Simplelink CC23X0 devices. diff --git a/drivers/timer/Kconfig.mtk_adsp b/drivers/timer/Kconfig.mtk_adsp index d3b7501e3071e..46052395a1367 100644 --- a/drivers/timer/Kconfig.mtk_adsp +++ b/drivers/timer/Kconfig.mtk_adsp @@ -3,6 +3,7 @@ config MTK_ADSP_TIMER bool "MediaTek Audio DSP timer" + depends on SOC_FAMILY_MTK select TICKLESS_CAPABLE select TIMER_HAS_64BIT_CYCLE_COUNTER select SYSTEM_CLOCK_LOCK_FREE_COUNT diff --git a/drivers/timer/Kconfig.realtek_rts5912_rtmr b/drivers/timer/Kconfig.realtek_rts5912_rtmr new file mode 100644 index 0000000000000..a41e0649591d9 --- /dev/null +++ b/drivers/timer/Kconfig.realtek_rts5912_rtmr @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config REALTEK_RTS5912_RTMR + bool "Realtek RTS5912 RTOS Timer" + depends on SOC_SERIES_RTS5912 + default y if DT_HAS_REALTEK_RTS5912_RTMR_ENABLED + select TICKLESS_CAPABLE + select SYSTEM_TIMER_HAS_DISABLE_SUPPORT + help + This module implements a kernel device driver for the Realtek + RTS5912 series RTOS timer. diff --git a/drivers/timer/Kconfig.riscv_machine b/drivers/timer/Kconfig.riscv_machine index efbd4d322f731..be90604da30ea 100644 --- a/drivers/timer/Kconfig.riscv_machine +++ b/drivers/timer/Kconfig.riscv_machine @@ -6,13 +6,8 @@ config RISCV_MACHINE_TIMER bool "RISCV Machine Timer" default y - depends on DT_HAS_ANDESTECH_MACHINE_TIMER_ENABLED || \ - DT_HAS_NEORV32_MACHINE_TIMER_ENABLED || \ - DT_HAS_NUCLEI_SYSTIMER_ENABLED || \ - DT_HAS_SIFIVE_CLINT0_ENABLED || \ - DT_HAS_TELINK_MACHINE_TIMER_ENABLED || \ - DT_HAS_LOWRISC_MACHINE_TIMER_ENABLED || \ - DT_HAS_NIOSV_MACHINE_TIMER_ENABLED + depends on DT_HAS_RISCV_MACHINE_TIMER_ENABLED || \ + DT_HAS_NUCLEI_SYSTIMER_ENABLED select TICKLESS_CAPABLE select TIMER_HAS_64BIT_CYCLE_COUNTER help diff --git a/drivers/timer/Kconfig.sam0_rtc b/drivers/timer/Kconfig.sam0_rtc index 14c4ee73939fd..6d97d16c564f9 100644 --- a/drivers/timer/Kconfig.sam0_rtc +++ b/drivers/timer/Kconfig.sam0_rtc @@ -1,12 +1,14 @@ # Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2016 Cadence Design Systems, Inc. # Copyright (c) 2019 Intel Corp. +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 config SAM0_RTC_TIMER bool "Atmel SAM0 series RTC timer" default y - depends on DT_HAS_ATMEL_SAM0_RTC_ENABLED + depends on DT_HAS_ATMEL_SAM0_RTC_ENABLED \ + && $(dt_nodelabel_bool_prop,rtc,systimer) select PINCTRL select TICKLESS_CAPABLE help diff --git a/drivers/timer/ambiq_stimer.c b/drivers/timer/ambiq_stimer.c index 516b3f3839d2c..f7748cce25a70 100644 --- a/drivers/timer/ambiq_stimer.c +++ b/drivers/timer/ambiq_stimer.c @@ -27,14 +27,21 @@ #define CYC_PER_TICK (sys_clock_hw_cycles_per_sec() / CONFIG_SYS_CLOCK_TICKS_PER_SEC) #define MAX_TICKS ((k_ticks_t)(COUNTER_MAX / CYC_PER_TICK) - 1) #define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK) -#define MIN_DELAY 1 +#if defined(CONFIG_SOC_SERIES_APOLLO3X) +#define MIN_DELAY 1 +#elif defined(CONFIG_SOC_SERIES_APOLLO4X) +#define MIN_DELAY 4 +#endif -#define TIMER_IRQ (DT_INST_IRQN(0)) +#define COMPARE_INTERRUPT (AM_HAL_STIMER_INT_COMPAREA | AM_HAL_STIMER_INT_COMPAREB) + +#define COMPAREA_IRQ (DT_INST_IRQN(0)) +#define COMPAREB_IRQ (COMPAREA_IRQ + 1) #define TIMER_CLKSRC (DT_INST_PROP(0, clk_source)) #if defined(CONFIG_TEST) -const int32_t z_sys_timer_irq_for_test = TIMER_IRQ; +const int32_t z_sys_timer_irq_for_test = COMPAREA_IRQ; #endif /* Elapsed ticks since the previous kernel tick was announced, It will get accumulated every time @@ -72,14 +79,20 @@ static void update_tick_counter(void) g_tick_elapsed += dticks; } +static void ambiq_stimer_delta_set(uint32_t ui32Delta) +{ + am_hal_stimer_compare_delta_set(0, ui32Delta); + am_hal_stimer_compare_delta_set(1, ui32Delta + 1); +} + static void stimer_isr(const void *arg) { ARG_UNUSED(arg); uint32_t irq_status = am_hal_stimer_int_status_get(false); - if (irq_status & AM_HAL_STIMER_INT_COMPAREA) { - am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREA); + if (irq_status & COMPARE_INTERRUPT) { + am_hal_stimer_int_clear(COMPARE_INTERRUPT); k_spinlock_key_t key = k_spin_lock(&g_lock); @@ -104,7 +117,7 @@ static void stimer_isr(const void *arg) uint32_t delta = (now_64 + MIN_DELAY < next) ? (next - now_64) : MIN_DELAY; /* Set delta. */ - am_hal_stimer_compare_delta_set(0, delta); + ambiq_stimer_delta_set(delta); } k_spin_unlock(&g_lock, key); @@ -152,9 +165,9 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) if (delta <= MIN_DELAY) { /*If the delta value is smaller than MIN_DELAY, trigger a interrupt immediately*/ - am_hal_stimer_int_set(AM_HAL_STIMER_INT_COMPAREA); + am_hal_stimer_int_set(COMPARE_INTERRUPT); } else { - am_hal_stimer_compare_delta_set(0, delta); + ambiq_stimer_delta_set(delta); } k_spin_unlock(&g_lock, key); @@ -182,25 +195,33 @@ static int stimer_init(void) { uint32_t oldCfg; - oldCfg = am_hal_stimer_config(AM_HAL_STIMER_CFG_FREEZE); + oldCfg = am_hal_stimer_config(TIMER_CLKSRC | AM_HAL_STIMER_CFG_FREEZE); #if defined(CONFIG_SOC_SERIES_APOLLO3X) am_hal_stimer_config((oldCfg & ~(AM_HAL_STIMER_CFG_FREEZE | CTIMER_STCFG_CLKSEL_Msk)) | - TIMER_CLKSRC | AM_HAL_STIMER_CFG_COMPARE_A_ENABLE); + TIMER_CLKSRC | AM_HAL_STIMER_CFG_COMPARE_A_ENABLE | + AM_HAL_STIMER_CFG_COMPARE_B_ENABLE); #else am_hal_stimer_config((oldCfg & ~(AM_HAL_STIMER_CFG_FREEZE | STIMER_STCFG_CLKSEL_Msk)) | - TIMER_CLKSRC | AM_HAL_STIMER_CFG_COMPARE_A_ENABLE); + TIMER_CLKSRC | AM_HAL_STIMER_CFG_COMPARE_A_ENABLE | + AM_HAL_STIMER_CFG_COMPARE_B_ENABLE); #endif g_last_time_stamp = am_hal_stimer_counter_get(); - NVIC_ClearPendingIRQ(TIMER_IRQ); - IRQ_CONNECT(TIMER_IRQ, 0, stimer_isr, 0, 0); - irq_enable(TIMER_IRQ); - - am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREA); + /* A Possible clock glitch could rarely cause the Stimer interrupt to be lost. + * Set up a backup comparator to handle this case + */ + NVIC_ClearPendingIRQ(COMPAREA_IRQ); + NVIC_ClearPendingIRQ(COMPAREB_IRQ); + IRQ_CONNECT(COMPAREA_IRQ, 0, stimer_isr, 0, 0); + IRQ_CONNECT(COMPAREB_IRQ, 0, stimer_isr, 0, 0); + irq_enable(COMPAREA_IRQ); + irq_enable(COMPAREB_IRQ); + + am_hal_stimer_int_enable(COMPARE_INTERRUPT); /* Start timer with period CYC_PER_TICK if tickless is not enabled */ if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { - am_hal_stimer_compare_delta_set(0, CYC_PER_TICK); + ambiq_stimer_delta_set(CYC_PER_TICK); } return 0; } diff --git a/drivers/timer/cc23x0_systim_timer.c b/drivers/timer/cc23x0_systim_timer.c new file mode 100644 index 0000000000000..1bc264ba179b2 --- /dev/null +++ b/drivers/timer/cc23x0_systim_timer.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_systim_timer + +/* + * TI SimpleLink CC23X0 timer driver based on SYSTIM + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Kernel tick period in microseconds (same timebase as systim) */ +#define TICK_PERIOD_MICRO_SEC (1000000 / CONFIG_SYS_CLOCK_TICKS_PER_SEC) + +/* + * Max number of systim ticks into the future + * + * Under the hood, the kernel timer uses the SysTimer whose events trigger + * immediately if the compare value is less than 2^22 systimer ticks in the past + * (4.194sec at 1us resolution). Therefore, the max number of SysTimer ticks you + * can schedule into the future is 2^32 - 2^22 - 1 ticks (~= 4290 sec at 1us + * resolution). + */ +#define SYSTIM_TIMEOUT_MAX 0xFFBFFFFFU + +/* Set systim interrupt to lowest priority */ +#define SYSTIM_ISR_PRIORITY 3U + +/* Keep track of systim counter at previous announcement to the kernel */ +static uint32_t last_systim_count; + +static void systim_isr(const void *arg); +static int sys_clock_driver_init(void); + +/* + * Set system clock timeout. + */ +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + ARG_UNUSED(idle); + + /* If timeout is necessary */ + if (ticks != K_TICKS_FOREVER) { + /* Get current value as early as possible */ + uint32_t now_tick = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + uint32_t timeout = ticks * TICK_PERIOD_MICRO_SEC; + + if (timeout > SYSTIM_TIMEOUT_MAX) { + timeout = SYSTIM_TIMEOUT_MAX; + } + /* This should wrap around */ + HWREG(SYSTIM_BASE + SYSTIM_O_CH0CC) = now_tick + timeout; + } +} + +uint32_t sys_clock_elapsed(void) +{ + /* Get current value as early as possible */ + uint32_t current_systim_count = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + uint32_t elapsed_systim; + + if (current_systim_count >= last_systim_count) { + elapsed_systim = current_systim_count - last_systim_count; + } else { + elapsed_systim = (UINT32_MAX - last_systim_count) + current_systim_count; + } + + int32_t elapsed_ticks = elapsed_systim / TICK_PERIOD_MICRO_SEC; + + return elapsed_ticks; +} + +uint32_t sys_clock_cycle_get_32(void) +{ + return HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); +} + +void systim_isr(const void *arg) +{ + /* Get current value as early as possible */ + uint32_t current_systim_count = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + uint32_t elapsed_systim; + + if (current_systim_count >= last_systim_count) { + elapsed_systim = current_systim_count - last_systim_count; + } else { + elapsed_systim = (UINT32_MAX - last_systim_count) + current_systim_count; + } + + int32_t elapsed_ticks = elapsed_systim / TICK_PERIOD_MICRO_SEC; + + sys_clock_announce(elapsed_ticks); + + last_systim_count = current_systim_count; + + /* Do not re-arm systim. Zephyr will do so through sys_clock_set_timeout */ +} + +static int sys_clock_driver_init(void) +{ + uint32_t now_tick; + + /* Get current value as early as possible */ + now_tick = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + last_systim_count = now_tick; + + /* Clear any pending interrupts on SysTimer channel 0 */ + HWREG(SYSTIM_BASE + SYSTIM_O_ICLR) = SYSTIM_ICLR_EV0_CLR; + + /* + * Configure SysTimer channel 0 to compare mode with timer + * resolution of 1 us. + */ + HWREG(SYSTIM_BASE + SYSTIM_O_CH0CFG) = 0; + + /* Make SysTimer halt on CPU debug halt */ + HWREG(SYSTIM_BASE + SYSTIM_O_EMU) = SYSTIM_EMU_HALT_STOP; + + HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ16SEL) = EVTSVT_CPUIRQ16SEL_PUBID_SYSTIM0; + + /* + * Set IMASK for channel 0. IMASK is used by the power driver to know + * which systimer channels are active. + */ + HWREG(SYSTIM_BASE + SYSTIM_O_IMSET) = SYSTIM_IMSET_EV0_SET; + + /* This should wrap around and set a maximum timeout */ + HWREG(SYSTIM_BASE + SYSTIM_O_CH0CC) = now_tick + SYSTIM_TIMEOUT_MAX; + + /* Take configurable interrupt IRQ16 for systimer */ + IRQ_CONNECT(CPUIRQ16_IRQn, SYSTIM_ISR_PRIORITY, systim_isr, 0, 0); + irq_enable(CPUIRQ16_IRQn); + + return 0; +} + +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index 1a3183af5e704..7f72a5051c2f1 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -169,6 +169,10 @@ static uint32_t elapsed(void) ARCH_ISR_DIAG_OFF __attribute__((interrupt("IRQ"))) void sys_clock_isr(void) { +#ifdef CONFIG_TRACING_ISR + sys_trace_isr_enter(); +#endif /* CONFIG_TRACING_ISR */ + uint32_t dcycles; uint32_t dticks; @@ -217,6 +221,11 @@ __attribute__((interrupt("IRQ"))) void sys_clock_isr(void) } ISR_DIRECT_PM(); + +#ifdef CONFIG_TRACING_ISR + sys_trace_isr_exit(); +#endif /* CONFIG_TRACING_ISR */ + z_arm_int_exit(); } ARCH_ISR_DIAG_ON diff --git a/drivers/timer/export.c b/drivers/timer/export.c new file mode 100644 index 0000000000000..a68c4ae41f069 --- /dev/null +++ b/drivers/timer/export.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#ifdef CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER +EXPORT_SYMBOL(sys_clock_cycle_get_64); +#endif diff --git a/drivers/timer/ite_it8xxx2_timer.c b/drivers/timer/ite_it8xxx2_timer.c index 3d2426a748dbf..fc9ddae02d048 100644 --- a/drivers/timer/ite_it8xxx2_timer.c +++ b/drivers/timer/ite_it8xxx2_timer.c @@ -150,6 +150,8 @@ void timer_5ms_one_shot(void) #ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT void arch_busy_wait(uint32_t usec_to_wait) { + uint32_t start = IT8XXX2_EXT_CNTOX(BUSY_WAIT_H_TIMER); + if (!usec_to_wait) { return; } @@ -157,16 +159,8 @@ void arch_busy_wait(uint32_t usec_to_wait) /* Decrease 1us here to calibrate our access registers latency */ usec_to_wait--; - /* - * We want to set the bit(1) re-start busy wait timer as soon - * as possible, so we directly write 0xb instead of | bit(1). - */ - IT8XXX2_EXT_CTRLX(BUSY_WAIT_L_TIMER) = IT8XXX2_EXT_ETX_COMB_RST_EN; - for (;;) { - uint32_t curr = IT8XXX2_EXT_CNTOX(BUSY_WAIT_H_TIMER); - - if (curr >= usec_to_wait) { + if ((IT8XXX2_EXT_CNTOX(BUSY_WAIT_H_TIMER) - start) >= usec_to_wait) { break; } } diff --git a/drivers/timer/mcux_os_timer.c b/drivers/timer/mcux_os_timer.c index c6eb776e43abf..1402f696c5595 100644 --- a/drivers/timer/mcux_os_timer.c +++ b/drivers/timer/mcux_os_timer.c @@ -22,6 +22,8 @@ #define CYC_PER_TICK ((uint32_t)((uint64_t)sys_clock_hw_cycles_per_sec() \ / (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC)) +#define CYC_PER_US ((uint32_t)((uint64_t)sys_clock_hw_cycles_per_sec() \ + / (uint64_t)USEC_PER_SEC)) #define MAX_CYC INT_MAX #define MAX_TICKS ((MAX_CYC - CYC_PER_TICK) / CYC_PER_TICK) #define MIN_DELAY 1000 @@ -37,7 +39,12 @@ static OSTIMER_Type *base; */ static uint64_t cyc_sys_compensated; #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(standby)) && CONFIG_PM +/* This is the counter device used when OS timer is not available in + * standby mode. + */ static const struct device *counter_dev; +/* Indicates if the counter is running. */ +bool counter_running; #endif static uint64_t mcux_lpc_ostick_get_compensated_timer_value(void) @@ -86,8 +93,7 @@ static uint32_t mcux_lpc_ostick_set_counter_timeout(int32_t curr_timeout) uint32_t timeout; int32_t ticks; struct counter_top_cfg top_cfg = { 0 }; - - timeout = k_ticks_to_us_ceil32(curr_timeout); + timeout = k_ticks_to_us_near32(curr_timeout); ticks = counter_us_to_ticks(counter_dev, timeout); ticks = CLAMP(ticks, 1, counter_get_max_top_value(counter_dev)); @@ -111,17 +117,18 @@ static uint32_t mcux_lpc_ostick_set_counter_timeout(int32_t curr_timeout) } } + /* Counter is set to wakeup the system after the requested time */ + if (counter_start(counter_dev) != 0) { + ret = 1; + goto done; + } + counter_running = true; #if CONFIG_MCUX_OS_TIMER_PM_POWERED_OFF /* Capture the current timer value for cases where it loses its state * in low power modes. */ cyc_sys_compensated += OSTIMER_GetCurrentTimerValue(base); #endif - - /* Counter is set to wakeup the system after the requested time */ - if (counter_start(counter_dev) != 0) { - ret = 1; - } } else { ret = 1; } @@ -137,34 +144,37 @@ static uint32_t mcux_lpc_ostick_set_counter_timeout(int32_t curr_timeout) */ static uint32_t mcux_lpc_ostick_compensate_system_timer(void) { - uint32_t ret = 0; - - if (counter_dev) { - uint32_t slept_time_ticks; - uint32_t slept_time_us; + uint32_t slept_time_ticks; + uint32_t slept_time_us; - counter_stop(counter_dev); + if (!counter_dev) { + return 1; + } - counter_get_value(counter_dev, &slept_time_ticks); + if (!counter_running) { + return 0; + } - if (!(counter_is_counting_up(counter_dev))) { - slept_time_ticks = counter_get_top_value(counter_dev) - slept_time_ticks; - } - slept_time_us = counter_ticks_to_us(counter_dev, slept_time_ticks); - cyc_sys_compensated += (k_us_to_ticks_floor32(slept_time_us) * CYC_PER_TICK); + counter_stop(counter_dev); + counter_running = false; + counter_get_value(counter_dev, &slept_time_ticks); + if (!(counter_is_counting_up(counter_dev))) { + slept_time_ticks = counter_get_top_value(counter_dev) - + slept_time_ticks; + } + slept_time_us = counter_ticks_to_us(counter_dev, slept_time_ticks); + cyc_sys_compensated += CYC_PER_US * slept_time_us; #if CONFIG_MCUX_OS_TIMER_PM_POWERED_OFF - /* Reactivate os_timer for cases where it loses its state */ - OSTIMER_Init(base); + /* Reset the OS Timer to a known state */ + RESET_PeripheralReset(kOSEVENT_TIMER_RST_SHIFT_RSTn); + /* Reactivate os_timer for cases where it loses its state */ + OSTIMER_Init(base); #endif + /* Announce the time slept to the kernel*/ + mcux_lpc_ostick_isr(NULL); - /* Announce the time slept to the kernel*/ - mcux_lpc_ostick_isr(NULL); - } else { - ret = 1; - } - - return ret; + return 0; } #endif diff --git a/drivers/timer/npcx_itim_timer.c b/drivers/timer/npcx_itim_timer.c index eb0436c8a6e8f..5960df666e404 100644 --- a/drivers/timer/npcx_itim_timer.c +++ b/drivers/timer/npcx_itim_timer.c @@ -140,8 +140,6 @@ static inline void npcx_itim_evt_disable(void) /* ITIM local functions */ static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks) { - k_spinlock_key_t key = k_spin_lock(&lock); - /* * Get desired cycles of event timer from the requested ticks which * round up to next tick boundary. @@ -152,7 +150,7 @@ static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks) } else { uint64_t next_cycs; uint64_t curr = npcx_itim_get_sys_cyc64(); - uint32_t dcycles; + uint64_t dcycles; if (ticks <= 0) { ticks = 1; @@ -162,11 +160,13 @@ static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks) if (unlikely(next_cycs <= curr)) { cyc_evt_timeout = 1; } else { + uint32_t dticks; + dcycles = next_cycs - curr; - cyc_evt_timeout = - CLAMP((dcycles / SYS_CYC_PER_EVT_CYC), 1, NPCX_ITIM32_MAX_CNT); + dticks = DIV_ROUND_UP(dcycles * EVT_CYCLES_PER_SEC, + sys_clock_hw_cycles_per_sec()); + cyc_evt_timeout = CLAMP(dticks, 1, NPCX_ITIM32_MAX_CNT); } - } LOG_DBG("ticks %x, cyc_evt_timeout %x", ticks, cyc_evt_timeout); @@ -178,7 +178,6 @@ static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks) /* Upload counter of event timer */ evt_tmr->ITCNT32 = MAX(cyc_evt_timeout - 1, 1); - k_spin_unlock(&lock, key); /* Enable event timer and start ticking */ return npcx_itim_evt_enable(); } @@ -218,15 +217,18 @@ static inline uint32_t npcx_itim_get_evt_cyc32(void) { uint32_t cnt1, cnt2; - cnt1 = evt_tmr->ITCNT32; - /* - * Wait for two consecutive equal values are read since the source clock - * of event timer is 32KHz. - */ - while ((cnt2 = evt_tmr->ITCNT32) != cnt1) { - cnt1 = cnt2; - } - + __asm__ volatile( + "ldr %[c2], [%[tmr], %[itcnt32_off]]\n\t" + ".read_itim_cnt_loop_%=:\n\t" + "mov %[c1], %[c2]\n\t" + "ldr %[c2], [%[tmr], %[itcnt32_off]]\n\t" + "nop\n\t" + "nop\n\t" + "cmp %[c1], %[c2]\n\t" + "bne .read_itim_cnt_loop_%=\n\t" + : [c1] "=&r"(cnt1), [c2] "=&r"(cnt2) + : [tmr] "r"(evt_tmr), [itcnt32_off] "i"(offsetof(struct itim32_reg, ITCNT32)) + : "memory"); /* Return current value of 32-bit counter of event timer */ return cnt2; } @@ -235,13 +237,13 @@ static uint32_t npcx_itim_evt_elapsed_cyc32(void) { uint32_t cnt1 = npcx_itim_get_evt_cyc32(); uint8_t sys_cts = evt_tmr->ITCTS32; - uint16_t cnt2 = npcx_itim_get_evt_cyc32(); + uint32_t cnt2 = npcx_itim_get_evt_cyc32(); /* Event has been triggered but timer ISR doesn't handle it */ if (IS_BIT_SET(sys_cts, NPCX_ITCTSXX_TO_STS) || (cnt2 > cnt1)) { cnt2 = cyc_evt_timeout; } else { - cnt2 = cyc_evt_timeout - cnt2; + cnt2 = cyc_evt_timeout - cnt2 - 1; } /* Return elapsed cycles of 32-bit counter of event timer */ @@ -261,7 +263,10 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) LOG_DBG("timeout is %d", ticks); /* Start a event timer in ticks */ + + k_spinlock_key_t key = k_spin_lock(&lock); npcx_itim_start_evt_tmr_by_tick(ticks); + k_spin_unlock(&lock, key); } uint32_t sys_clock_elapsed(void) @@ -273,7 +278,7 @@ uint32_t sys_clock_elapsed(void) k_spinlock_key_t key = k_spin_lock(&lock); uint64_t delta_cycle = npcx_itim_get_sys_cyc64() - cyc_sys_announced; - uint32_t delta_ticks = (uint32_t)delta_cycle / SYS_CYCLES_PER_TICK; + uint32_t delta_ticks = (uint32_t)(delta_cycle / SYS_CYCLES_PER_TICK); last_elapsed = delta_ticks; k_spin_unlock(&lock, key); diff --git a/drivers/timer/nrf_grtc_timer.c b/drivers/timer/nrf_grtc_timer.c index ee3f35e09d0c7..c75d9dc80a9e0 100644 --- a/drivers/timer/nrf_grtc_timer.c +++ b/drivers/timer/nrf_grtc_timer.c @@ -10,12 +10,15 @@ #if defined(CONFIG_CLOCK_CONTROL_NRF) #include #endif +#include #include #include #include #include #define GRTC_NODE DT_NODELABEL(grtc) +#define HFCLK_NODE DT_PHANDLE_BY_NAME(GRTC_NODE, clocks, hfclock) +#define LFCLK_NODE DT_PHANDLE_BY_NAME(GRTC_NODE, clocks, lfclock) /* Ensure that GRTC properties in devicetree are defined correctly. */ #if !DT_NODE_HAS_PROP(GRTC_NODE, owned_channels) @@ -49,7 +52,7 @@ #define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK) -#define LFCLK_FREQUENCY_HZ 32768 +#define LFCLK_FREQUENCY_HZ DT_PROP(LFCLK_NODE, clock_frequency) #if defined(CONFIG_TEST) const int32_t z_sys_timer_irq_for_test = DT_IRQN(GRTC_NODE); @@ -518,7 +521,35 @@ static int sys_clock_driver_init(void) #if defined(CONFIG_NRF_GRTC_ALWAYS_ON) nrfx_grtc_active_request_set(true); #endif + +#if DT_PROP(GRTC_NODE, clkout_32k) + nrfy_grtc_clkout_set(NRF_GRTC, NRF_GRTC_CLKOUT_32K, true); +#endif + +#if DT_NODE_HAS_PROP(GRTC_NODE, clkout_fast_frequency_hz) +#if !DT_NODE_HAS_PROP(HFCLK_NODE, clock_frequency) +#error "hfclock reference required when fast clock output is enabled." +#endif + +#if DT_PROP(GRTC_NODE, clkout_fast_frequency_hz) > (DT_PROP(HFCLK_NODE, clock_frequency) / 2) +#error "Invalid frequency value for fast clock output." +#endif + uint32_t base_frequency = DT_PROP(HFCLK_NODE, clock_frequency); + uint32_t requested_frequency = DT_PROP(GRTC_NODE, clkout_fast_frequency_hz); + uint32_t grtc_div = base_frequency / (requested_frequency * 2); + + nrfy_grtc_clkout_divider_set(NRF_GRTC, (uint8_t)grtc_div); + nrfy_grtc_clkout_set(NRF_GRTC, NRF_GRTC_CLKOUT_FAST, true); +#endif + +#if DT_PROP(GRTC_NODE, clkout_32k) || DT_NODE_HAS_PROP(GRTC_NODE, clkout_fast_frequency_hz) + PINCTRL_DT_DEFINE(GRTC_NODE); + const struct pinctrl_dev_config *pcfg = PINCTRL_DT_DEV_CONFIG_GET(GRTC_NODE); + + return pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT); +#else return 0; +#endif } void sys_clock_set_timeout(int32_t ticks, bool idle) diff --git a/drivers/timer/realtek_rts5912_rtmr.c b/drivers/timer/realtek_rts5912_rtmr.c new file mode 100644 index 0000000000000..3476e73099941 --- /dev/null +++ b/drivers/timer/realtek_rts5912_rtmr.c @@ -0,0 +1,251 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#define DT_DRV_COMPAT realtek_rts5912_rtmr + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define RTS5912_SCCON_REG_BASE ((SYSTEM_Type *)(DT_REG_ADDR(DT_NODELABEL(sccon)))) + +#define CYCLES_PER_TICK (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC) + +BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, + "Realtek RTOS timer is not supported multiple instances"); + +#define RTMR_REG ((RTOSTMR_Type *)DT_INST_REG_ADDR(0)) + +#define SLWTMR_REG \ + ((RTOSTMR_Type *)(DT_REG_ADDR(DT_COMPAT_GET_ANY_STATUS_OKAY(realtek_rts5912_slwtimer)))) + +#define SSCON_REG ((SYSTEM_Type *)(DT_REG_ADDR(DT_NODELABEL(sccon)))) + +#define RTMR_COUNTER_MAX 0x0ffffffful +#define RTMR_COUNTER_MSK 0x0ffffffful +#define RTMR_TIMER_STOPPED 0xf0000000ul + +#define MAX_TICKS ((k_ticks_t)(RTMR_COUNTER_MAX / CYCLES_PER_TICK) - 1) + +#define RTMR_ADJUST_LIMIT 2 +#define RTMR_ADJUST_CYCLES 1 + +static struct k_spinlock lock; +static uint32_t accumulated_cycles; +static uint32_t previous_cnt; /* Record the counter set into RTMR */ +static uint32_t last_announcement; /* Record the last tick announced to system */ + +static void rtmr_restart(uint32_t counter) +{ + RTMR_REG->CTRL = 0ul; + RTMR_REG->LDCNT = counter; + RTMR_REG->CTRL = RTOSTMR_CTRL_INTEN_Msk | RTOSTMR_CTRL_EN_Msk; +} + +static uint32_t rtmr_get_counter(void) +{ + uint32_t counter = RTMR_REG->CNT; + + if ((counter == 0) && (RTMR_REG->CTRL & RTOSTMR_CTRL_EN_Msk)) { + counter = previous_cnt; + } + + return counter; +} + +static void rtmr_isr(const void *arg) +{ + ARG_UNUSED(arg); + + uint32_t cycles; + int32_t ticks; + + k_spinlock_key_t key = k_spin_lock(&lock); + + rtmr_restart(RTMR_COUNTER_MAX * CYCLES_PER_TICK); + + cycles = previous_cnt; + previous_cnt = RTMR_COUNTER_MAX * CYCLES_PER_TICK; + + accumulated_cycles += cycles; + + if (accumulated_cycles > RTMR_COUNTER_MSK) { + accumulated_cycles &= RTMR_COUNTER_MSK; + } + + ticks = accumulated_cycles - last_announcement; + ticks &= RTMR_COUNTER_MSK; + ticks /= CYCLES_PER_TICK; + + last_announcement = accumulated_cycles; + + k_spin_unlock(&lock, key); + + sys_clock_announce(ticks); +} + +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + ARG_UNUSED(idle); + + uint32_t cur_cnt, temp; + int full_ticks; + uint32_t full_cycles; + uint32_t partial_cycles; + + if (idle && (ticks == K_TICKS_FOREVER)) { + RTMR_REG->CTRL = 0U; + previous_cnt = RTMR_TIMER_STOPPED; + return; + } + + if (ticks < 1) { + full_ticks = 0; + } else if ((ticks == K_TICKS_FOREVER) || (ticks > MAX_TICKS)) { + full_ticks = MAX_TICKS - 1; + } else { + full_ticks = ticks - 1; + } + + full_cycles = full_ticks * CYCLES_PER_TICK; + + k_spinlock_key_t key = k_spin_lock(&lock); + + cur_cnt = rtmr_get_counter(); + + RTMR_REG->CTRL = 0U; + + temp = accumulated_cycles; + temp += previous_cnt - cur_cnt; + temp &= RTMR_COUNTER_MSK; + accumulated_cycles = temp; + + partial_cycles = CYCLES_PER_TICK - (accumulated_cycles % CYCLES_PER_TICK); + previous_cnt = full_cycles + partial_cycles; + + temp = previous_cnt; + if (temp > RTMR_ADJUST_LIMIT) { + temp -= RTMR_ADJUST_CYCLES; + } + rtmr_restart(temp); + + k_spin_unlock(&lock, key); +} + +uint32_t sys_clock_elapsed(void) +{ + uint32_t cur_cnt; + uint32_t ticks; + int32_t elapsed; + + k_spinlock_key_t key = k_spin_lock(&lock); + + cur_cnt = rtmr_get_counter(); + + elapsed = (int32_t)accumulated_cycles - (int32_t)last_announcement; + if (elapsed < 0) { + elapsed = -1 * elapsed; + } + ticks = (uint32_t)elapsed; + ticks += previous_cnt - cur_cnt; + ticks /= CYCLES_PER_TICK; + ticks &= RTMR_COUNTER_MSK; + + k_spin_unlock(&lock, key); + + return ticks; +} + +void sys_clock_idle_exit(void) +{ + if (previous_cnt == RTMR_TIMER_STOPPED) { + previous_cnt = CYCLES_PER_TICK; + rtmr_restart(previous_cnt); + } +} + +void sys_clock_disable(void) +{ + /* Disable RTMR. */ + RTMR_REG->CTRL = 0ul; +} + +uint32_t sys_clock_cycle_get_32(void) +{ + uint32_t ret; + uint32_t cur_cnt; + + k_spinlock_key_t key = k_spin_lock(&lock); + + cur_cnt = rtmr_get_counter(); + ret = (accumulated_cycles + (previous_cnt - cur_cnt)) & RTMR_COUNTER_MSK; + + k_spin_unlock(&lock, key); + + return ret; +} + +#ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT + +void arch_busy_wait(uint32_t n_usec) +{ + if (n_usec == 0) { + return; + } + + uint32_t start = SLWTMR_REG->CNT; + + for (;;) { + uint32_t curr = SLWTMR_REG->CNT; + + if ((start - curr) >= n_usec) { + break; + } + } +} +#endif + +static int sys_clock_driver_init(void) +{ + /* Enable RTMR clock power */ + + SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE; + + sys_reg->PERICLKPWR1 |= SYSTEM_PERICLKPWR1_RTMRCLKPWR_Msk; + + /* Enable RTMR interrupt. */ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), rtmr_isr, 0, 0); + irq_enable(DT_INST_IRQN(0)); + + /* Trigger RTMR and wait it start to counting */ + previous_cnt = RTMR_COUNTER_MAX; + + rtmr_restart(previous_cnt); + while (RTMR_REG->CNT == 0) { + }; + +#ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT + /* Enable SLWTMR0 clock power */ + SSCON_REG->PERICLKPWR1 |= BIT(SYSTEM_PERICLKPWR1_SLWTMR0CLKPWR_Pos); + + /* Enable SLWTMR0 */ + SLWTMR_REG->LDCNT = UINT32_MAX; + SLWTMR_REG->CTRL = RTOSTMR_CTRL_MDSEL_Msk | RTOSTMR_CTRL_EN_Msk; +#endif + + return 0; +} + +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/drivers/timer/riscv_machine_timer.c b/drivers/timer/riscv_machine_timer.c index 36e29c6aadb31..2d0f0703508dd 100644 --- a/drivers/timer/riscv_machine_timer.c +++ b/drivers/timer/riscv_machine_timer.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 MASSDRIVER EI (massdriver.space) * Copyright (c) 2018-2023 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 @@ -13,71 +14,16 @@ #include #include -/* andestech,machine-timer */ -#if DT_HAS_COMPAT_STATUS_OKAY(andestech_machine_timer) -#define DT_DRV_COMPAT andestech_machine_timer - -#define MTIME_REG DT_INST_REG_ADDR(0) -#define MTIMECMP_REG (DT_INST_REG_ADDR(0) + 8) -#define TIMER_IRQN DT_INST_IRQN(0) -/* neorv32-machine-timer */ -#elif DT_HAS_COMPAT_STATUS_OKAY(neorv32_machine_timer) -#define DT_DRV_COMPAT neorv32_machine_timer - -#define MTIME_REG DT_INST_REG_ADDR(0) -#define MTIMECMP_REG (DT_INST_REG_ADDR(0) + 8) -#define TIMER_IRQN DT_INST_IRQN(0) -/* nuclei,systimer */ -#elif DT_HAS_COMPAT_STATUS_OKAY(nuclei_systimer) -#define DT_DRV_COMPAT nuclei_systimer - -#define MTIME_REG DT_INST_REG_ADDR(0) -#define MTIMECMP_REG (DT_INST_REG_ADDR(0) + 8) -#define TIMER_IRQN DT_INST_IRQ_BY_IDX(0, 1, irq) -/* sifive,clint0 */ -#elif DT_HAS_COMPAT_STATUS_OKAY(sifive_clint0) -#define DT_DRV_COMPAT sifive_clint0 - -#define MTIME_REG (DT_INST_REG_ADDR(0) + 0xbff8U) -#define MTIMECMP_REG (DT_INST_REG_ADDR(0) + 0x4000U) -#define TIMER_IRQN DT_INST_IRQ_BY_IDX(0, 1, irq) -/* telink,machine-timer */ -#elif DT_HAS_COMPAT_STATUS_OKAY(telink_machine_timer) -#define DT_DRV_COMPAT telink_machine_timer - -#define MTIME_REG DT_INST_REG_ADDR(0) -#define MTIMECMP_REG (DT_INST_REG_ADDR(0) + 8) -#define TIMER_IRQN DT_INST_IRQN(0) -/* lowrisc,machine-timer */ -#elif DT_HAS_COMPAT_STATUS_OKAY(lowrisc_machine_timer) -#define DT_DRV_COMPAT lowrisc_machine_timer - -#define MTIME_REG (DT_INST_REG_ADDR(0) + 0x110) -#define MTIMECMP_REG (DT_INST_REG_ADDR(0) + 0x118) -#define TIMER_IRQN DT_INST_IRQN(0) -/* niosv-machine-timer */ -#elif DT_HAS_COMPAT_STATUS_OKAY(niosv_machine_timer) -#define DT_DRV_COMPAT niosv_machine_timer - -#define MTIMECMP_REG DT_INST_REG_ADDR(0) -#define MTIME_REG (DT_INST_REG_ADDR(0) + 8) -#define TIMER_IRQN DT_INST_IRQN(0) -/* scr,machine-timer*/ -#elif DT_HAS_COMPAT_STATUS_OKAY(scr_machine_timer) -#define DT_DRV_COMPAT scr_machine_timer -#define MTIMER_HAS_DIVIDER - -#define MTIMEDIV_REG (DT_INST_REG_ADDR_U64(0) + 4) -#define MTIME_REG (DT_INST_REG_ADDR_U64(0) + 8) -#define MTIMECMP_REG (DT_INST_REG_ADDR_U64(0) + 16) -#define TIMER_IRQN DT_INST_IRQN(0) -#endif +#define DT_DRV_COMPAT riscv_machine_timer + +#define MTIME_REG DT_INST_REG_ADDR_BY_IDX(0, 0) +#define MTIMECMP_REG DT_INST_REG_ADDR_BY_IDX(0, 1) +#define TIMER_IRQN DT_INST_IRQN(0) -#define CYC_PER_TICK (uint32_t)(sys_clock_hw_cycles_per_sec() \ - / CONFIG_SYS_CLOCK_TICKS_PER_SEC) +#define CYC_PER_TICK (uint32_t)(sys_clock_hw_cycles_per_sec() / CONFIG_SYS_CLOCK_TICKS_PER_SEC) /* the unsigned long cast limits divisions to native CPU register width */ -#define cycle_diff_t unsigned long +#define cycle_diff_t unsigned long #define CYCLE_DIFF_MAX (~(cycle_diff_t)0) /* @@ -99,11 +45,11 @@ * consecutive set bits coming from the original max values to produce a * nicer literal for assembly generation. */ -#define CYCLES_MAX_1 ((uint64_t)INT32_MAX * (uint64_t)CYC_PER_TICK) -#define CYCLES_MAX_2 ((uint64_t)CYCLE_DIFF_MAX) -#define CYCLES_MAX_3 MIN(CYCLES_MAX_1, CYCLES_MAX_2) -#define CYCLES_MAX_4 (CYCLES_MAX_3 / 2 + CYCLES_MAX_3 / 4) -#define CYCLES_MAX (CYCLES_MAX_4 + LSB_GET(CYCLES_MAX_4)) +#define CYCLES_MAX_1 ((uint64_t)INT32_MAX * (uint64_t)CYC_PER_TICK) +#define CYCLES_MAX_2 ((uint64_t)CYCLE_DIFF_MAX) +#define CYCLES_MAX_3 MIN(CYCLES_MAX_1, CYCLES_MAX_2) +#define CYCLES_MAX_4 (CYCLES_MAX_3 / 2 + CYCLES_MAX_3 / 4) +#define CYCLES_MAX (CYCLES_MAX_4 + LSB_GET(CYCLES_MAX_4)) static struct k_spinlock lock; static uint64_t last_count; @@ -138,14 +84,6 @@ static void set_mtimecmp(uint64_t time) #endif } -static void set_divider(void) -{ -#ifdef MTIMER_HAS_DIVIDER - *(volatile uint32_t *)MTIMEDIV_REG = - CONFIG_RISCV_MACHINE_TIMER_SYSTEM_CLOCK_DIVIDER; -#endif -} - static uint64_t mtime(void) { #ifdef CONFIG_64BIT @@ -240,9 +178,6 @@ uint64_t sys_clock_cycle_get_64(void) static int sys_clock_driver_init(void) { - - set_divider(); - IRQ_CONNECT(TIMER_IRQN, 0, timer_isr, NULL, 0); last_ticks = mtime() / CYC_PER_TICK; last_count = last_ticks * CYC_PER_TICK; @@ -259,5 +194,4 @@ void smp_timer_init(void) } #endif -SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, - CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/drivers/timer/sam0_rtc_timer.c b/drivers/timer/sam0_rtc_timer.c index 8e87b1848bb30..1ad978aa2bc73 100644 --- a/drivers/timer/sam0_rtc_timer.c +++ b/drivers/timer/sam0_rtc_timer.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 omSquare s.r.o. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,6 +26,8 @@ #include #include +/* clang-format off */ + /* RTC registers. */ #define RTC0 ((RtcMode0 *) DT_INST_REG_ADDR(0)) @@ -66,10 +69,6 @@ BUILD_ASSERT(CYCLES_PER_TICK > 1, #endif /* CONFIG_TICKLESS_KERNEL */ -/* Helper macro to get the correct GCLK GEN based on configuration. */ -#define GCLK_GEN(n) GCLK_EVAL(n) -#define GCLK_EVAL(n) GCLK_CLKCTRL_GEN_GCLK##n - /* Tick/cycle count of the last announce call. */ static volatile uint32_t rtc_last; @@ -245,29 +244,35 @@ uint32_t sys_clock_cycle_get_32(void) return rtc_count(); } +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + static int sys_clock_driver_init(void) { - int retval; + volatile uint32_t *mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(0); + uint32_t mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(0, bit); + *cfg->mclk |= cfg->mclk_mask; #ifdef MCLK - MCLK->APBAMASK.reg |= MCLK_APBAMASK_RTC; OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_ULP32K; #else - /* Set up bus clock and GCLK generator. */ - PM->APBAMASK.reg |= PM_APBAMASK_RTC; - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(RTC_GCLK_ID) | GCLK_CLKCTRL_CLKEN - | GCLK_GEN(DT_INST_PROP(0, clock_generator)); + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(ASSIGNED_CLOCKS_CELL_BY_NAME(0, gclk, gen)) + | GCLK_CLKCTRL_ID(DT_INST_CLOCKS_CELL_BY_NAME(0, gclk, id)); /* Synchronize GCLK. */ while (GCLK->STATUS.bit.SYNCBUSY) { } #endif - retval = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT); - if (retval < 0) { +#ifndef CONFIG_TICKLESS_KERNEL + int retval = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT); + + if (retval < 0 && retval != -ENOENT) { return retval; } +#endif /* Reset module to hardware defaults. */ rtc_reset(); @@ -330,3 +335,5 @@ static int sys_clock_driver_init(void) SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); + +/* clang-format on */ diff --git a/drivers/timer/smartbond_timer.c b/drivers/timer/smartbond_timer.c index afa86617e0e50..0e4e0a021fad1 100644 --- a/drivers/timer/smartbond_timer.c +++ b/drivers/timer/smartbond_timer.c @@ -103,7 +103,7 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) * as soon as system is awaken. Following code makes sure that * system never goes to sleep for longer time that watchdog reload value. */ - if (!IS_ENABLED(CONFIG_WDT_SMARTBOND) && IS_ENABLED(CONFIG_PM)) { + if (IS_ENABLED(CONFIG_PM)) { uint32_t watchdog_expire_ticks; if (CRG_TOP->CLK_RCX_REG & CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Msk) { @@ -120,7 +120,8 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) * RC32K maximum frequency. */ watchdog_expire_ticks = SYS_WDOG->WATCHDOG_REG * - CONFIG_SYS_CLOCK_TICKS_PER_SEC / (get_rc32k_max_frequency() / 320); + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / + (get_rc32k_max_frequency() / 320); } if (watchdog_expire_ticks - 2 < ticks) { ticks = watchdog_expire_ticks - 2; diff --git a/drivers/timer/ti_dmtimer.c b/drivers/timer/ti_dmtimer.c index e19db1dd69f58..37b8ebe14d5ab 100644 --- a/drivers/timer/ti_dmtimer.c +++ b/drivers/timer/ti_dmtimer.c @@ -17,30 +17,36 @@ #define DT_DRV_COMPAT ti_am654_timer -#define TIMER_BASE_ADDR DT_INST_REG_ADDR(0) - #define TIMER_IRQ_NUM DT_INST_IRQN(0) #define TIMER_IRQ_PRIO DT_INST_IRQ(0, priority) #define TIMER_IRQ_FLAGS DT_INST_IRQ(0, flags) -#define CYC_PER_TICK ((uint32_t)(sys_clock_hw_cycles_per_sec() \ - / CONFIG_SYS_CLOCK_TICKS_PER_SEC)) +#define CYC_PER_TICK ((uint32_t)(sys_clock_hw_cycles_per_sec() / CONFIG_SYS_CLOCK_TICKS_PER_SEC)) #define MAX_TICKS ((k_ticks_t)(UINT32_MAX / CYC_PER_TICK) - 1) -static struct k_spinlock lock; +#define DEV_CFG(_dev) ((const struct ti_dm_timer_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct ti_dm_timer_data *)(_dev)->data) + +struct ti_dm_timer_config { + DEVICE_MMIO_NAMED_ROM(reg_base); +}; -static uint32_t last_cycle; +struct ti_dm_timer_data { + DEVICE_MMIO_NAMED_RAM(reg_base); + struct k_spinlock lock; + uint32_t last_cycle; +}; -#define TI_DM_TIMER_READ(reg) sys_read32(TIMER_BASE_ADDR + TI_DM_TIMER_ ## reg) +static const struct device *systick_timer_dev; -#define TI_DM_TIMER_MASK(reg) TI_DM_TIMER_ ## reg ## _MASK -#define TI_DM_TIMER_SHIFT(reg) TI_DM_TIMER_ ## reg ## _SHIFT -#define TI_DM_TIMER_WRITE(data, reg, bits) \ - ti_dm_timer_write_masks(data, \ - TIMER_BASE_ADDR + TI_DM_TIMER_ ## reg, \ - TI_DM_TIMER_MASK(reg ## _ ## bits), \ - TI_DM_TIMER_SHIFT(reg ## _ ## bits)) +#define TI_DM_TIMER_MASK(reg) TI_DM_TIMER_##reg##_MASK +#define TI_DM_TIMER_SHIFT(reg) TI_DM_TIMER_##reg##_SHIFT + +#define TI_DM_TIMER_READ(dev, reg) sys_read32(DEVICE_MMIO_GET(dev) + TI_DM_TIMER_##reg) +#define TI_DM_TIMER_WRITE(dev, data, reg, bits) \ + ti_dm_timer_write_masks(data, DEVICE_MMIO_GET(dev) + TI_DM_TIMER_##reg, \ + TI_DM_TIMER_MASK(reg##_##bits), TI_DM_TIMER_SHIFT(reg##_##bits)) static void ti_dm_timer_write_masks(uint32_t data, uint32_t reg, uint32_t mask, uint32_t shift) { @@ -51,32 +57,36 @@ static void ti_dm_timer_write_masks(uint32_t data, uint32_t reg, uint32_t mask, sys_write32(reg_val, reg); } -static void ti_dmtimer_isr(void *data) +static void ti_dmtimer_isr(void *param) { + ARG_UNUSED(param); + + struct ti_dm_timer_data *data = systick_timer_dev->data; + /* If no pending event */ - if (!TI_DM_TIMER_READ(IRQSTATUS)) { + if (!TI_DM_TIMER_READ(systick_timer_dev, IRQSTATUS)) { return; } - k_spinlock_key_t key = k_spin_lock(&lock); + k_spinlock_key_t key = k_spin_lock(&data->lock); - uint32_t curr_cycle = TI_DM_TIMER_READ(TCRR); - uint32_t delta_cycles = curr_cycle - last_cycle; + uint32_t curr_cycle = TI_DM_TIMER_READ(systick_timer_dev, TCRR); + uint32_t delta_cycles = curr_cycle - data->last_cycle; uint32_t delta_ticks = delta_cycles / CYC_PER_TICK; - last_cycle = curr_cycle; + data->last_cycle = curr_cycle; /* ACK match interrupt */ - TI_DM_TIMER_WRITE(1, IRQSTATUS, MAT_IT_FLAG); + TI_DM_TIMER_WRITE(systick_timer_dev, 1, IRQSTATUS, MAT_IT_FLAG); if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { /* Setup next match time */ uint64_t next_cycle = curr_cycle + CYC_PER_TICK; - TI_DM_TIMER_WRITE(next_cycle, TMAR, COMPARE_VALUE); + TI_DM_TIMER_WRITE(systick_timer_dev, next_cycle, TMAR, COMPARE_VALUE); } - k_spin_unlock(&lock, key); + k_spin_unlock(&data->lock, key); sys_clock_announce(delta_ticks); } @@ -84,6 +94,9 @@ static void ti_dmtimer_isr(void *data) void sys_clock_set_timeout(int32_t ticks, bool idle) { ARG_UNUSED(idle); + + struct ti_dm_timer_data *data = systick_timer_dev->data; + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { /* Not supported on tickful kernels */ return; @@ -92,80 +105,101 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks; ticks = CLAMP(ticks, 1, (int32_t)MAX_TICKS); - k_spinlock_key_t key = k_spin_lock(&lock); + k_spinlock_key_t key = k_spin_lock(&data->lock); /* Setup next match time */ - uint32_t curr_cycle = TI_DM_TIMER_READ(TCRR); + uint32_t curr_cycle = TI_DM_TIMER_READ(systick_timer_dev, TCRR); uint32_t next_cycle = curr_cycle + (ticks * CYC_PER_TICK); - TI_DM_TIMER_WRITE(next_cycle, TMAR, COMPARE_VALUE); + TI_DM_TIMER_WRITE(systick_timer_dev, next_cycle, TMAR, COMPARE_VALUE); - k_spin_unlock(&lock, key); + k_spin_unlock(&data->lock, key); } uint32_t sys_clock_cycle_get_32(void) { - k_spinlock_key_t key = k_spin_lock(&lock); + struct ti_dm_timer_data *data = systick_timer_dev->data; + + k_spinlock_key_t key = k_spin_lock(&data->lock); - uint32_t curr_cycle = TI_DM_TIMER_READ(TCRR); + uint32_t curr_cycle = TI_DM_TIMER_READ(systick_timer_dev, TCRR); - k_spin_unlock(&lock, key); + k_spin_unlock(&data->lock, key); return curr_cycle; } unsigned int sys_clock_elapsed(void) { + struct ti_dm_timer_data *data = systick_timer_dev->data; + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { /* Always return 0 for tickful kernel system */ return 0; } - k_spinlock_key_t key = k_spin_lock(&lock); + k_spinlock_key_t key = k_spin_lock(&data->lock); - uint32_t curr_cycle = TI_DM_TIMER_READ(TCRR); - uint32_t delta_cycles = curr_cycle - last_cycle; + uint32_t curr_cycle = TI_DM_TIMER_READ(systick_timer_dev, TCRR); + uint32_t delta_cycles = curr_cycle - data->last_cycle; uint32_t delta_ticks = delta_cycles / CYC_PER_TICK; - k_spin_unlock(&lock, key); + k_spin_unlock(&data->lock, key); return delta_ticks; } static int sys_clock_driver_init(void) { - last_cycle = 0; + struct ti_dm_timer_data *data; + + systick_timer_dev = DEVICE_DT_GET(DT_NODELABEL(systick_timer)); + + data = systick_timer_dev->data; + + data->last_cycle = 0; + + DEVICE_MMIO_NAMED_MAP(systick_timer_dev, reg_base, K_MEM_CACHE_NONE); IRQ_CONNECT(TIMER_IRQ_NUM, TIMER_IRQ_PRIO, ti_dmtimer_isr, NULL, TIMER_IRQ_FLAGS); /* Disable prescalar */ - TI_DM_TIMER_WRITE(0, TCLR, PRE); + TI_DM_TIMER_WRITE(systick_timer_dev, 0, TCLR, PRE); /* Select autoreload mode */ - TI_DM_TIMER_WRITE(1, TCLR, AR); + TI_DM_TIMER_WRITE(systick_timer_dev, 1, TCLR, AR); /* Enable match interrupt */ - TI_DM_TIMER_WRITE(1, IRQENABLE_SET, MAT_EN_FLAG); + TI_DM_TIMER_WRITE(systick_timer_dev, 1, IRQENABLE_SET, MAT_EN_FLAG); /* Load timer counter value */ - TI_DM_TIMER_WRITE(0, TCRR, TIMER_COUNTER); + TI_DM_TIMER_WRITE(systick_timer_dev, 0, TCRR, TIMER_COUNTER); /* Load timer load value */ - TI_DM_TIMER_WRITE(0, TLDR, LOAD_VALUE); + TI_DM_TIMER_WRITE(systick_timer_dev, 0, TLDR, LOAD_VALUE); /* Load timer compare value */ - TI_DM_TIMER_WRITE(CYC_PER_TICK, TMAR, COMPARE_VALUE); + TI_DM_TIMER_WRITE(systick_timer_dev, CYC_PER_TICK, TMAR, COMPARE_VALUE); /* Enable compare mode */ - TI_DM_TIMER_WRITE(1, TCLR, CE); + TI_DM_TIMER_WRITE(systick_timer_dev, 1, TCLR, CE); /* Start the timer */ - TI_DM_TIMER_WRITE(1, TCLR, ST); + TI_DM_TIMER_WRITE(systick_timer_dev, 1, TCLR, ST); irq_enable(TIMER_IRQ_NUM); return 0; } -SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, - CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); +#define TI_DM_TIMER(n) \ + static struct ti_dm_timer_data ti_dm_timer_data_##n; \ + static const struct ti_dm_timer_config ti_dm_timer_config_##n = { \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ + }; \ + DEVICE_DT_INST_DEFINE(n, NULL, NULL, &ti_dm_timer_data_##n, &ti_dm_timer_config_##n, \ + PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(TI_DM_TIMER); + +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/drivers/usb/common/Kconfig b/drivers/usb/common/Kconfig index 7f6a02614b8f0..d5a0d4dc1b4a6 100644 --- a/drivers/usb/common/Kconfig +++ b/drivers/usb/common/Kconfig @@ -1,4 +1,8 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 +menu "USB common" + rsource "nrf_usbd_common/Kconfig" + +endmenu diff --git a/drivers/usb/common/usb_dwc2_hw.h b/drivers/usb/common/usb_dwc2_hw.h index fcb35489a0443..fcd0d2a00607f 100644 --- a/drivers/usb/common/usb_dwc2_hw.h +++ b/drivers/usb/common/usb_dwc2_hw.h @@ -338,6 +338,9 @@ USB_DWC2_SET_FIELD_DEFINE(gnptxfsiz_nptxfstaddr, GNPTXFSIZ_NPTXFSTADDR) #define USB_DWC2_GGPIO_STM32_PWRDWN_POS 16UL #define USB_DWC2_GGPIO_STM32_PWRDWN BIT(USB_DWC2_GGPIO_STM32_PWRDWN_POS) +/* GSNPSID register */ +#define USB_DWC2_GSNPSID_REV_5_00A 0x4F54500AUL + /* GHWCFG1 register */ #define USB_DWC2_GHWCFG1 0x0044UL #define USB_DWC2_GHWCFG1_EPDIR_POS(i) (i * 2) @@ -997,6 +1000,33 @@ USB_DWC2_SET_FIELD_DEFINE(doeptsizn_xfersize, DOEPTSIZN_XFERSIZE) /* Power and Clock Gating Control Register */ #define USB_DWC2_PCGCCTL 0x0E00UL +#define USB_DWC2_PCGCCTL_IF_DEV_MODE_POS 31UL +#define USB_DWC2_PCGCCTL_IF_DEV_MODE BIT(USB_DWC2_PCGCCTL_IF_DEV_MODE_POS) +#define USB_DWC2_PCGCCTL_P2HD_PRT_SPD_POS 29UL +#define USB_DWC2_PCGCCTL_P2HD_PRT_SPD_MASK (0x3UL << USB_DWC2_PCGCCTL_P2HD_PRT_SPD_POS) +#define USB_DWC2_PCGCCTL_P2HD_PRT_SPD_LS 2 +#define USB_DWC2_PCGCCTL_P2HD_PRT_SPD_FS 1 +#define USB_DWC2_PCGCCTL_P2HD_PRT_SPD_HS 0 +#define USB_DWC2_PCGCCTL_P2HD_DEV_ENUM_SPD_POS 27UL +#define USB_DWC2_PCGCCTL_P2HD_DEV_ENUM_SPD_MASK (0x3UL << USB_DWC2_PCGCCTL_P2HD_DEV_ENUM_SPD_POS) +#define USB_DWC2_PCGCCTL_P2HD_DEV_ENUM_SPD_FS48 3 +#define USB_DWC2_PCGCCTL_P2HD_DEV_ENUM_SPD_LS 2 +#define USB_DWC2_PCGCCTL_P2HD_DEV_ENUM_SPD_FS 1 +#define USB_DWC2_PCGCCTL_P2HD_DEV_ENUM_SPD_HS 0 +#define USB_DWC2_PCGCCTL_MAC_DEV_ADDR_POS 20UL +#define USB_DWC2_PCGCCTL_MAC_DEV_ADDR_MASK (0x7FUL << USB_DWC2_PCGCCTL_MAC_DEV_ADDR_POS) +#define USB_DWC2_PCGCCTL_MAX_TERMSELECT_POS 19UL +#define USB_DWC2_PCGCCTL_MAX_TERMSELECT BIT(USB_DWC2_PCGCCTL_MAX_TERMSELECT_POS) +#define USB_DWC2_PCGCCTL_MAC_XCVRSELECT_POS 17UL +#define USB_DWC2_PCGCCTL_MAC_XCVRSELECT_MASK (0x3UL << USB_DWC2_PCGCCTL_MAC_XCVRSELECT_POS) +#define USB_DWC2_PCGCCTL_MAC_XCVRSELECT_LFS 3 +#define USB_DWC2_PCGCCTL_MAC_XCVRSELECT_LS 2 +#define USB_DWC2_PCGCCTL_MAC_XCVRSELECT_FS 1 +#define USB_DWC2_PCGCCTL_MAC_XCVRSELECT_HS 0 +#define USB_DWC2_PCGCCTL_SH2PL_PRT_CTL0_POS 16UL +#define USB_DWC2_PCGCCTL_SH2PL_PRT_CTL0 BIT(USB_DWC2_PCGCCTL_SH2PL_PRT_CTL0_POS) +#define USB_DWC2_PCGCCTL_PRT_CLK_SEL_POS 14UL +#define USB_DWC2_PCGCCTL_PRT_CLK_SEL_MASK (0x3UL << USB_DWC2_PCGCCTL_PRT_CLK_SEL_POS) #define USB_DWC2_PCGCCTL_RESTOREVALUE_POS 14UL #define USB_DWC2_PCGCCTL_RESTOREVALUE_MASK (0x3FFFFUL << USB_DWC2_PCGCCTL_RESTOREVALUE_POS) #define USB_DWC2_PCGCCTL_ESSREGRESTORED_POS 13UL @@ -1016,6 +1046,11 @@ USB_DWC2_SET_FIELD_DEFINE(doeptsizn_xfersize, DOEPTSIZN_XFERSIZE) #define USB_DWC2_PCGCCTL_STOPPCLK_POS 0UL #define USB_DWC2_PCGCCTL_STOPPCLK BIT(USB_DWC2_PCGCCTL_STOPPCLK_POS) +USB_DWC2_GET_FIELD_DEFINE(pcgcctl_p2hd_prt_spd, PCGCCTL_P2HD_PRT_SPD) +USB_DWC2_GET_FIELD_DEFINE(pcgcctl_p2hd_dev_enum_spd, PCGCCTL_P2HD_DEV_ENUM_SPD) +USB_DWC2_GET_FIELD_DEFINE(pcgcctl_mac_dev_addr, PCGCCTL_MAC_DEV_ADDR) +USB_DWC2_GET_FIELD_DEFINE(pcgcctl_mac_xcvrselect, PCGCCTL_MAC_XCVRSELECT) +USB_DWC2_GET_FIELD_DEFINE(pcgcctl_prt_clk_sel, PCGCCTL_PRT_CLK_SEL) USB_DWC2_GET_FIELD_DEFINE(pcgcctl_restorevalue, PCGCCTL_RESTOREVALUE) USB_DWC2_SET_FIELD_DEFINE(pcgcctl_restorevalue, PCGCCTL_RESTOREVALUE) diff --git a/drivers/usb/device/Kconfig b/drivers/usb/device/Kconfig index c286fa39cf2af..4cdd0710cdad3 100644 --- a/drivers/usb/device/Kconfig +++ b/drivers/usb/device/Kconfig @@ -62,7 +62,7 @@ config USB_DC_STM32 config USB_DC_STM32_CLOCK_CHECK bool "Runtime USB 48MHz clock check" depends on USB_DC_STM32 - default y if !(SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X) + default y if !(SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32U5X) help Enable USB clock 48MHz configuration runtime check. In specific cases, this check might provide wrong verdict and should diff --git a/drivers/usb/device/usb_dc_kinetis.c b/drivers/usb/device/usb_dc_kinetis.c index c6ff25aabde50..0bdbb0cbde397 100644 --- a/drivers/usb/device/usb_dc_kinetis.c +++ b/drivers/usb/device/usb_dc_kinetis.c @@ -40,6 +40,13 @@ LOG_MODULE_REGISTER(usb_dc_kinetis); #define KINETIS_EP_NUMOF_MASK 0xf #define KINETIS_ADDR2IDX(addr) ((addr) & (KINETIS_EP_NUMOF_MASK)) +/* + * In some SoC USB0 base register is defined as USBFS0 + */ +#if !defined(USB0) && defined(USBFS0) +#define USB0 USBFS0 +#endif + /* * Buffer Descriptor (BD) entry provides endpoint buffer control * information for USBFS controller. Every endpoint direction requires diff --git a/drivers/usb/device/usb_dc_mcux.c b/drivers/usb/device/usb_dc_mcux.c index 14a8918d10679..75b0f8061faa0 100644 --- a/drivers/usb/device/usb_dc_mcux.c +++ b/drivers/usb/device/usb_dc_mcux.c @@ -90,6 +90,7 @@ BUILD_ASSERT(NUM_INSTS <= 1, "Only one USB device supported"); #define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0 #endif /* LPC55s69 */ #elif defined(CONFIG_SOC_SERIES_IMXRT11XX) || \ + defined(CONFIG_SOC_SERIES_IMXRT118X) || \ defined(CONFIG_SOC_SERIES_IMXRT10XX) || \ defined(CONFIG_SOC_SERIES_MCXN) #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb1)) diff --git a/drivers/usb/device/usb_dc_stm32.c b/drivers/usb/device/usb_dc_stm32.c index b5fc75c3c2ea6..509bffdd2a3b6 100644 --- a/drivers/usb/device/usb_dc_stm32.c +++ b/drivers/usb/device/usb_dc_stm32.c @@ -75,7 +75,10 @@ PINCTRL_DT_INST_DEFINE(0); static const struct pinctrl_dev_config *usb_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0); -#define USB_OTG_HS_EMB_PHY (DT_HAS_COMPAT_STATUS_OKAY(st_stm32_usbphyc) && \ +#define USB_OTG_HS_EMB_PHYC (DT_HAS_COMPAT_STATUS_OKAY(st_stm32_usbphyc) && \ + DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs)) + +#define USB_OTG_HS_EMB_PHY (DT_HAS_COMPAT_STATUS_OKAY(st_stm32u5_otghs_phy) && \ DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs)) #define USB_OTG_HS_ULPI_PHY (DT_HAS_COMPAT_STATUS_OKAY(usb_ulpi_phy) && \ @@ -208,16 +211,67 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) } #endif -static int usb_dc_stm32_clock_enable(void) +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32u5_otghs_phy) + +static const struct stm32_pclken phy_pclken[] = STM32_DT_CLOCKS(DT_INST_PHANDLE(0, phys)); + +static int usb_dc_stm32u5_phy_clock_select(const struct device *const clk) { - const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + static const struct { + uint32_t freq; + uint32_t ref_clk; + } clk_select[] = { + { MHZ(16), SYSCFG_OTG_HS_PHY_CLK_SELECT_1 }, + { KHZ(19200), SYSCFG_OTG_HS_PHY_CLK_SELECT_2 }, + { MHZ(20), SYSCFG_OTG_HS_PHY_CLK_SELECT_3 }, + { MHZ(24), SYSCFG_OTG_HS_PHY_CLK_SELECT_4 }, + { MHZ(26), SYSCFG_OTG_HS_PHY_CLK_SELECT_5 }, + { MHZ(32), SYSCFG_OTG_HS_PHY_CLK_SELECT_6 }, + }; + uint32_t freq; + + if (clock_control_get_rate(clk, + (clock_control_subsys_t)&phy_pclken[1], + &freq) != 0) { + LOG_ERR("Failed to get USB_PHY clock source rate"); + return -EIO; + } - if (!device_is_ready(clk)) { - LOG_ERR("clock control device not ready"); - return -ENODEV; + for (size_t i = 0; ARRAY_SIZE(clk_select); i++) { + if (clk_select[i].freq == freq) { + HAL_SYSCFG_SetOTGPHYReferenceClockSelection(clk_select[i].ref_clk); + return 0; + } + } + + LOG_ERR("Unsupported PHY clock source frequency (%"PRIu32")", freq); + + return -EINVAL; +} + +static int usb_dc_stm32u5_phy_clock_enable(const struct device *const clk) +{ + int err; + + err = clock_control_configure(clk, (clock_control_subsys_t)&phy_pclken[1], NULL); + if (err) { + LOG_ERR("Could not select USB_PHY clock source"); + return -EIO; + } + + err = clock_control_on(clk, (clock_control_subsys_t)&phy_pclken[0]); + if (err) { + LOG_ERR("Unable to enable USB_PHY clock"); + return -EIO; } -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) && defined(CONFIG_SOC_SERIES_STM32U5X) + return usb_dc_stm32u5_phy_clock_select(clk); +} + +static int usb_dc_stm32_phy_specific_clock_enable(const struct device *const clk) +{ + int err; + /* Sequence to enable the power of the OTG HS on a stm32U5 serie : Enable VDDUSB */ bool pwr_clk = LL_AHB3_GRP1_IsEnabledClock(LL_AHB3_GRP1_PERIPH_PWR); @@ -246,10 +300,28 @@ static int usb_dc_stm32_clock_enable(void) /* Set the OTG PHY reference clock selection (through SYSCFG) block */ LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_SYSCFG); - HAL_SYSCFG_SetOTGPHYReferenceClockSelection(SYSCFG_OTG_HS_PHY_CLK_SELECT_1); + + err = usb_dc_stm32u5_phy_clock_enable(clk); + if (err) { + return err; + } + /* Configuring the SYSCFG registers OTG_HS PHY : OTG_HS PHY enable*/ HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE); -#elif defined(PWR_USBSCR_USB33SV) || defined(PWR_SVMCR_USV) + + if (clock_control_on(clk, (clock_control_subsys_t)&pclken[0]) != 0) { + LOG_ERR("Unable to enable USB clock"); + return -EIO; + } + + return 0; +} + +#else /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32u5_otghs_phy) */ + +static int usb_dc_stm32_phy_specific_clock_enable(const struct device *const clk) +{ +#if defined(PWR_USBSCR_USB33SV) || defined(PWR_SVMCR_USV) /* * VDDUSB independent USB supply (PWR clock is on) * with LL_PWR_EnableVDDUSB function (higher case) @@ -286,6 +358,26 @@ static int usb_dc_stm32_clock_enable(void) } } + return 0; +} + +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32u5_otghs_phy) */ + +static int usb_dc_stm32_clock_enable(void) +{ + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + int err; + + if (!device_is_ready(clk)) { + LOG_ERR("clock control device not ready"); + return -ENODEV; + } + + err = usb_dc_stm32_phy_specific_clock_enable(clk); + if (err) { + return err; + } + /* Previous check won't work in case of F1/F3. Add build time check */ #if defined(RCC_CFGR_OTGFSPRE) || defined(RCC_CFGR_USBPRE) @@ -317,7 +409,7 @@ static int usb_dc_stm32_clock_enable(void) LL_AHB1_GRP1_DisableClockLowPower(LL_AHB1_GRP1_PERIPH_OTGHSULPI); #endif -#if USB_OTG_HS_EMB_PHY +#if USB_OTG_HS_EMB_PHYC LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_OTGPHYC); #endif #endif /* USB_OTG_HS_ULPI_PHY */ @@ -333,8 +425,8 @@ static int usb_dc_stm32_clock_disable(void) LOG_ERR("Unable to disable USB clock"); return -EIO; } -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) && defined(CONFIG_SOC_SERIES_STM32U5X) - LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_USBPHY); +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32u5_otghs_phy) + clock_control_off(clk, (clock_control_subsys_t)&phy_pclken[0]); #endif return 0; @@ -347,7 +439,7 @@ static uint32_t usb_dc_stm32_get_maximum_speed(void) * If max-speed is not passed via DT, set it to USB controller's * maximum hardware capability. */ -#if USB_OTG_HS_EMB_PHY || USB_OTG_HS_ULPI_PHY +#if USB_OTG_HS_EMB_PHYC || USB_OTG_HS_EMB_PHY || USB_OTG_HS_ULPI_PHY uint32_t speed = USB_OTG_SPEED_HIGH; #else uint32_t speed = USB_OTG_SPEED_FULL; @@ -358,7 +450,8 @@ static uint32_t usb_dc_stm32_get_maximum_speed(void) if (!strncmp(USB_MAXIMUM_SPEED, "high-speed", 10)) { speed = USB_OTG_SPEED_HIGH; } else if (!strncmp(USB_MAXIMUM_SPEED, "full-speed", 10)) { -#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(USB_OTG_HS_EMB_PHY) +#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(USB_OTG_HS_EMB_PHYC) || \ + defined(USB_OTG_HS_EMB_PHY) speed = USB_OTG_SPEED_HIGH_IN_FULL; #else speed = USB_OTG_SPEED_FULL; @@ -399,7 +492,7 @@ static int usb_dc_stm32_init(void) #endif usb_dc_stm32_state.pcd.Init.dev_endpoints = USB_NUM_BIDIR_ENDPOINTS; usb_dc_stm32_state.pcd.Init.speed = usb_dc_stm32_get_maximum_speed(); -#if USB_OTG_HS_EMB_PHY +#if USB_OTG_HS_EMB_PHYC || USB_OTG_HS_EMB_PHY usb_dc_stm32_state.pcd.Init.phy_itface = USB_OTG_HS_EMBEDDED_PHY; #elif USB_OTG_HS_ULPI_PHY usb_dc_stm32_state.pcd.Init.phy_itface = USB_OTG_ULPI_PHY; @@ -1188,6 +1281,19 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) } } +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + uint8_t ep_idx = USB_EP_GET_IDX(epnum); + uint8_t ep = ep_idx | USB_EP_DIR_IN; + struct usb_dc_stm32_ep_state *ep_state = usb_dc_stm32_get_ep_state(ep); + + LOG_DBG("epnum 0x%02x", epnum); + + __ASSERT(ep_state, "No corresponding ep_state for ep"); + + k_sem_give(&ep_state->write_sem); +} + #if (defined(USB) || defined(USB_DRD_FS)) && DT_INST_NODE_HAS_PROP(0, disconnect_gpios) void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) { diff --git a/drivers/usb/udc/CMakeLists.txt b/drivers/usb/udc/CMakeLists.txt index 883b8fc13d813..0fdc321a3141a 100644 --- a/drivers/usb/udc/CMakeLists.txt +++ b/drivers/usb/udc/CMakeLists.txt @@ -19,3 +19,4 @@ zephyr_library_sources_ifdef(CONFIG_UDC_NXP_IP3511 udc_mcux_ip3511.c) zephyr_library_sources_ifdef(CONFIG_UDC_NUMAKER udc_numaker.c) zephyr_library_sources_ifdef(CONFIG_UDC_RPI_PICO udc_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_UDC_AMBIQ udc_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_UDC_RENESAS_RA udc_renesas_ra.c) diff --git a/drivers/usb/udc/Kconfig b/drivers/usb/udc/Kconfig index a88c5a1ddd94f..fd5e25cf11344 100644 --- a/drivers/usb/udc/Kconfig +++ b/drivers/usb/udc/Kconfig @@ -66,5 +66,6 @@ source "drivers/usb/udc/Kconfig.mcux" source "drivers/usb/udc/Kconfig.numaker" source "drivers/usb/udc/Kconfig.rpi_pico" source "drivers/usb/udc/Kconfig.ambiq" +source "drivers/usb/udc/Kconfig.renesas_ra" endif # UDC_DRIVER diff --git a/drivers/usb/udc/Kconfig.renesas_ra b/drivers/usb/udc/Kconfig.renesas_ra new file mode 100644 index 0000000000000..9b2a784e3929c --- /dev/null +++ b/drivers/usb/udc/Kconfig.renesas_ra @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config UDC_RENESAS_RA + bool "Renesas RA family UDC driver" + default y + depends on DT_HAS_RENESAS_RA_UDC_ENABLED + select USE_RA_FSP_USB_DEVICE + select PINCTRL + help + Enable Renesas RA family UDC driver. + +if UDC_RENESAS_RA + +config UDC_RENESAS_RA_STACK_SIZE + int "UDC controller driver internal thread stack size" + default 512 + help + Renesas RA device controller driver internal thread stack size. + +config UDC_RENESAS_RA_THREAD_PRIORITY + int "Renesas RA family UDC driver thread priority" + default 8 + help + Renesas RA device controller driver thread priority. + +config UDC_RENESAS_RA_MAX_QMESSAGES + int "Renesas RA family UDC driver maximum number of ISR event messages" + range 4 64 + default 8 + help + Maximum number of messages for handling of Renesas RA USBD ISR events. + +endif diff --git a/drivers/usb/udc/Kconfig.stm32 b/drivers/usb/udc/Kconfig.stm32 index 3afe6b15e3f27..2d7684469a9fc 100644 --- a/drivers/usb/udc/Kconfig.stm32 +++ b/drivers/usb/udc/Kconfig.stm32 @@ -13,3 +13,34 @@ config UDC_STM32 default y help STM32 USB device controller driver. + +if UDC_STM32 + +config UDC_STM32_STACK_SIZE + int "UDC controller driver internal thread stack size" + default 512 + help + STM32 USB device controller driver internal thread stack size. + +config UDC_STM32_THREAD_PRIORITY + int "STM32 USB controller driver thread priority" + default 8 + help + STM32 USB device controller driver thread priority. + +config UDC_STM32_MAX_QMESSAGES + int "STM32 UDC driver maximum number of ISR event messages" + range 4 64 + default 8 + help + Maximum number of messages for handling of STM32 USBD ISR events. + +config UDC_STM32_CLOCK_CHECK + bool "Runtime USB 48MHz clock check" + default y if !(SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32U5X) + help + Enable USB clock 48MHz configuration runtime check. + In specific cases, this check might provide wrong verdict and should + be disabled. + +endif diff --git a/drivers/usb/udc/udc_ambiq.c b/drivers/usb/udc/udc_ambiq.c index ffc84c0413d8f..f6f342fc21cdc 100644 --- a/drivers/usb/udc/udc_ambiq.c +++ b/drivers/usb/udc/udc_ambiq.c @@ -594,14 +594,14 @@ static int udc_ambiq_shutdown(const struct device *dev) return 0; } -static int udc_ambiq_lock(const struct device *dev) +static void udc_ambiq_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_ambiq_unlock(const struct device *dev) +static void udc_ambiq_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static void ambiq_handle_evt_setup(const struct device *dev) diff --git a/drivers/usb/udc/udc_common.c b/drivers/usb/udc/udc_common.c index 86f5a7f854a4b..9429c404ad609 100644 --- a/drivers/usb/udc/udc_common.c +++ b/drivers/usb/udc/udc_common.c @@ -592,6 +592,11 @@ int udc_ep_enqueue(const struct device *dev, struct net_buf *const buf) goto ep_enqueue_error; } + if (!cfg->stat.enabled) { + ret = -ENODEV; + goto ep_enqueue_error; + } + LOG_DBG("Queue ep 0x%02x %p len %u", cfg->addr, buf, USB_EP_DIR_IS_IN(cfg->addr) ? buf->len : buf->size); @@ -660,7 +665,6 @@ struct net_buf *udc_ep_buf_alloc(const struct device *dev, } bi = udc_get_buf_info(buf); - memset(bi, 0, sizeof(struct udc_buf_info)); bi->ep = ep; LOG_DBG("Allocate net_buf, ep 0x%02x, size %zd", ep, size); diff --git a/drivers/usb/udc/udc_common.h b/drivers/usb/udc/udc_common.h index 76614ac8c4775..19cad23bd39e1 100644 --- a/drivers/usb/udc/udc_common.h +++ b/drivers/usb/udc/udc_common.h @@ -325,7 +325,7 @@ bool udc_ctrl_stage_is_status_in(const struct device *dev); * * @param[in] dev Pointer to device struct of the driver instance * - * @return true if stage is Data Stage IN + * @return true if stage is Data Stage OUT */ bool udc_ctrl_stage_is_status_out(const struct device *dev); diff --git a/drivers/usb/udc/udc_dwc2.c b/drivers/usb/udc/udc_dwc2.c index 7f1256a10f044..13aa6c1738a11 100644 --- a/drivers/usb/udc/udc_dwc2.c +++ b/drivers/usb/udc/udc_dwc2.c @@ -25,6 +25,8 @@ LOG_MODULE_REGISTER(udc_dwc2, CONFIG_UDC_DRIVER_LOG_LEVEL); #include "udc_dwc2_vendor_quirks.h" enum dwc2_drv_event_type { + /* USB connection speed determined after bus reset */ + DWC2_DRV_EVT_ENUM_DONE, /* Trigger next transfer, must not be used for control OUT */ DWC2_DRV_EVT_XFER, /* Setup packet received */ @@ -121,6 +123,8 @@ struct udc_dwc2_data { unsigned int dynfifosizing : 1; unsigned int bufferdma : 1; unsigned int syncrst : 1; + /* Defect workarounds */ + unsigned int wa_essregrestored : 1; /* Runtime state flags */ unsigned int hibernated : 1; unsigned int enumdone : 1; @@ -201,6 +205,20 @@ static void dwc2_wait_for_bit(const struct device *dev, } } +static inline bool dwc2_in_completer_mode(const struct device *dev) +{ + struct udc_dwc2_data *const priv = udc_get_private(dev); + + return !IS_ENABLED(CONFIG_UDC_DWC2_DMA) || !priv->bufferdma; +} + +static inline bool dwc2_in_buffer_dma_mode(const struct device *dev) +{ + struct udc_dwc2_data *const priv = udc_get_private(dev); + + return IS_ENABLED(CONFIG_UDC_DWC2_DMA) && priv->bufferdma; +} + /* Get DOEPCTLn or DIEPCTLn register address */ static mem_addr_t dwc2_get_dxepctl_reg(const struct device *dev, const uint8_t ep) { @@ -248,6 +266,28 @@ static uint32_t dwc2_get_iept_xfersize(const struct device *dev, const uint32_t } } +static uint32_t dwc2_get_oept_pktctn(const struct device *dev, const uint32_t idx) +{ + struct udc_dwc2_data *const priv = udc_get_private(dev); + + if (idx == 0) { + return usb_dwc2_get_doeptsiz0_pktcnt(UINT32_MAX); + } else { + return priv->max_pktcnt; + } +} + +static uint32_t dwc2_get_oept_xfersize(const struct device *dev, const uint32_t idx) +{ + struct udc_dwc2_data *const priv = udc_get_private(dev); + + if (idx == 0) { + return usb_dwc2_get_doeptsiz0_xfersize(UINT32_MAX); + } else { + return priv->max_xfersize; + } +} + static void dwc2_flush_rx_fifo(const struct device *dev) { struct usb_dwc2_reg *const base = dwc2_get_base(dev); @@ -345,6 +385,42 @@ static bool dwc2_ep_is_iso(struct udc_ep_config *const cfg) return (cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) == USB_EP_TYPE_ISO; } +static int dwc2_ctrl_feed_dout(const struct device *dev, const size_t length) +{ + struct udc_dwc2_data *const priv = udc_get_private(dev); + struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); + struct net_buf *buf; + size_t alloc_len = length; + + if (dwc2_in_buffer_dma_mode(dev)) { + /* Control OUT buffers must be multiple of bMaxPacketSize0 */ + alloc_len = ROUND_UP(length, 64); + } + + buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, alloc_len); + if (buf == NULL) { + return -ENOMEM; + } + + udc_buf_put(ep_cfg, buf); + k_event_post(&priv->xfer_new, BIT(16)); + k_event_post(&priv->drv_evt, BIT(DWC2_DRV_EVT_XFER)); + + return 0; +} + +static void dwc2_ensure_setup_ready(const struct device *dev) +{ + if (dwc2_in_completer_mode(dev)) { + /* In Completer mode EP0 can always receive SETUP data */ + return; + } + + if (!udc_buf_peek(dev, USB_CONTROL_EP_OUT)) { + dwc2_ctrl_feed_dout(dev, 8); + } +} + static bool dwc2_dma_buffer_ok_to_use(const struct device *dev, void *buf, uint32_t xfersize, uint16_t mps) { @@ -398,7 +474,7 @@ static int dwc2_tx_fifo_write(const struct device *dev, len = buf->len; } - if (!priv->bufferdma) { + if (dwc2_in_completer_mode(dev)) { uint32_t spcavail = dwc2_ftx_avail(dev, ep_idx); uint32_t spcperpkt = ROUND_UP(udc_mps_ep_size(cfg), 4); uint32_t max_pkts, max_transfer; @@ -463,7 +539,7 @@ static int dwc2_tx_fifo_write(const struct device *dev, usb_dwc2_set_dieptsizn_pktcnt(pktcnt) | usb_dwc2_set_dieptsizn_xfersize(len), dieptsiz_reg); - if (priv->bufferdma) { + if (dwc2_in_buffer_dma_mode(dev)) { if (!dwc2_dma_buffer_ok_to_use(dev, buf->data, len, cfg->mps)) { /* Cannot continue unless buffer is bounced. Device will * cease to function. Is fatal error appropriate here? @@ -506,7 +582,7 @@ static int dwc2_tx_fifo_write(const struct device *dev, /* Clear IN Endpoint NAK Effective interrupt in case it was set */ sys_write32(USB_DWC2_DIEPINT_INEPNAKEFF, diepint_reg); - if (!priv->bufferdma) { + if (dwc2_in_completer_mode(dev)) { const uint8_t *src = buf->data; while (pktcnt > 0) { @@ -580,18 +656,23 @@ static void dwc2_prep_rx(const struct device *dev, struct net_buf *buf, uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr); mem_addr_t doeptsiz_reg = (mem_addr_t)&base->out_ep[ep_idx].doeptsiz; mem_addr_t doepctl_reg = dwc2_get_dxepctl_reg(dev, ep_idx); + uint32_t max_xfersize, max_pktcnt; + const uint32_t addnl = USB_MPS_ADDITIONAL_TRANSACTIONS(cfg->mps); uint32_t pktcnt; uint32_t doeptsiz; uint32_t doepctl; uint32_t xfersize; + max_xfersize = dwc2_get_oept_xfersize(dev, ep_idx); + max_pktcnt = dwc2_get_oept_pktctn(dev, ep_idx); + /* Clear NAK and set endpoint enable */ doepctl = sys_read32(doepctl_reg); doepctl |= USB_DWC2_DEPCTL_EPENA | USB_DWC2_DEPCTL_CNAK; if (dwc2_ep_is_iso(cfg)) { xfersize = USB_MPS_TO_TPL(cfg->mps); - pktcnt = 1 + USB_MPS_ADDITIONAL_TRANSACTIONS(cfg->mps); + pktcnt = 1 + addnl; if (xfersize > net_buf_tailroom(buf)) { LOG_ERR("ISO RX buffer too small"); @@ -608,36 +689,41 @@ static void dwc2_prep_rx(const struct device *dev, struct net_buf *buf, xfersize = net_buf_tailroom(buf); /* Do as many packets in a single transfer as possible */ - if (xfersize > priv->max_xfersize) { - xfersize = ROUND_DOWN(priv->max_xfersize, USB_MPS_TO_TPL(cfg->mps)); + if (xfersize > max_xfersize) { + xfersize = ROUND_DOWN(max_xfersize, USB_MPS_TO_TPL(cfg->mps)); } pktcnt = DIV_ROUND_UP(xfersize, USB_MPS_EP_SIZE(cfg->mps)); } - pktcnt = DIV_ROUND_UP(xfersize, udc_mps_ep_size(cfg)); + if (pktcnt > max_pktcnt) { + pktcnt = ROUND_DOWN(max_pktcnt, (1 + addnl)); + xfersize = pktcnt * udc_mps_ep_size(cfg); + } + doeptsiz = usb_dwc2_set_doeptsizn_pktcnt(pktcnt) | usb_dwc2_set_doeptsizn_xfersize(xfersize); if (cfg->addr == USB_CONTROL_EP_OUT) { - /* Use 1 to allow 8 byte long buffers for SETUP data */ - doeptsiz |= (1 << USB_DWC2_DOEPTSIZ0_SUPCNT_POS); + doeptsiz |= (3 << USB_DWC2_DOEPTSIZ0_SUPCNT_POS); } priv->rx_siz[ep_idx] = doeptsiz; sys_write32(doeptsiz, doeptsiz_reg); - if (priv->bufferdma) { - if (!dwc2_dma_buffer_ok_to_use(dev, buf->data, xfersize, cfg->mps)) { + if (dwc2_in_buffer_dma_mode(dev)) { + void *data = net_buf_tail(buf); + + if (!dwc2_dma_buffer_ok_to_use(dev, data, xfersize, cfg->mps)) { /* Cannot continue unless buffer is bounced. Device will * cease to function. Is fatal error appropriate here? */ return; } - sys_write32((uint32_t)buf->data, + sys_write32((uint32_t)data, (mem_addr_t)&base->out_ep[ep_idx].doepdma); - sys_cache_data_invd_range(buf->data, xfersize); + sys_cache_data_invd_range(data, xfersize); } sys_write32(doepctl, doepctl_reg); @@ -660,6 +746,26 @@ static void dwc2_handle_xfer_next(const struct device *dev, } else { int err = dwc2_tx_fifo_write(dev, cfg, buf); + if (cfg->addr == USB_CONTROL_EP_IN) { + /* Feed a buffer for the next setup packet after arming + * IN endpoint with the data. This is necessary both in + * IN Data Stage (Control Read Transfer) and IN Status + * Stage (Control Write Transfers and Control Transfers + * without Data Stage). + * + * The buffer must be fed here in Buffer DMA mode to + * allow receiving premature SETUP. This inevitably does + * automatically arm the buffer for OUT Status Stage. + * + * The buffer MUST NOT be fed here in Completer mode to + * avoid race condition where the next Control Write + * Transfer Data Stage is received into the buffer. + */ + if (dwc2_in_buffer_dma_mode(dev)) { + dwc2_ctrl_feed_dout(dev, 8); + } + } + if (err) { LOG_ERR("Failed to start write to TX FIFO, ep 0x%02x (err: %d)", cfg->addr, err); @@ -676,32 +782,35 @@ static void dwc2_handle_xfer_next(const struct device *dev, udc_ep_set_busy(dev, cfg->addr, true); } -static int dwc2_ctrl_feed_dout(const struct device *dev, const size_t length) +static int dwc2_handle_evt_setup(const struct device *dev) { - struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); + struct udc_dwc2_data *const priv = udc_get_private(dev); struct net_buf *buf; + int err; - buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, length); - if (buf == NULL) { - return -ENOMEM; - } + /* In Completer mode SETUP data is received without preparing endpoint 0 + * transfer beforehand. In Buffer DMA the SETUP can be copied to any EP0 + * OUT buffer. If there is any buffer queued, it is obsolete now. + */ + k_event_clear(&priv->xfer_finished, BIT(0) | BIT(16)); - udc_buf_put(ep_cfg, buf); - dwc2_prep_rx(dev, buf, ep_cfg); - LOG_DBG("feed buf %p", buf); + buf = udc_buf_get_all(dev, USB_CONTROL_EP_OUT); + if (buf) { + net_buf_unref(buf); + } - return 0; -} + buf = udc_buf_get_all(dev, USB_CONTROL_EP_IN); + if (buf) { + net_buf_unref(buf); + } -static int dwc2_handle_evt_setup(const struct device *dev) -{ - struct udc_dwc2_data *const priv = udc_get_private(dev); - struct net_buf *buf; - int err; + udc_ep_set_busy(dev, USB_CONTROL_EP_OUT, false); + udc_ep_set_busy(dev, USB_CONTROL_EP_IN, false); - buf = udc_buf_get(dev, USB_CONTROL_EP_OUT); + /* Allocate buffer and copy received SETUP for processing */ + buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, 8); if (buf == NULL) { - LOG_ERR("No buffer queued for control ep"); + LOG_ERR("No buffer available for control ep"); return -ENODATA; } @@ -718,30 +827,17 @@ static int dwc2_handle_evt_setup(const struct device *dev) /* Allocate and feed buffer for data OUT stage */ LOG_DBG("s:%p|feed for -out-", buf); - /* Allocate at least 8 bytes in case the host decides to send - * SETUP DATA instead of OUT DATA packet. - */ - err = dwc2_ctrl_feed_dout(dev, MAX(udc_data_stage_length(buf), 8)); + err = dwc2_ctrl_feed_dout(dev, udc_data_stage_length(buf)); if (err == -ENOMEM) { err = udc_submit_ep_event(dev, buf, err); } } else if (udc_ctrl_stage_is_data_in(dev)) { LOG_DBG("s:%p|feed for -in-status", buf); - err = dwc2_ctrl_feed_dout(dev, 8); - if (err == -ENOMEM) { - err = udc_submit_ep_event(dev, buf, err); - } - err = udc_ctrl_submit_s_in_status(dev); } else { LOG_DBG("s:%p|feed >setup", buf); - err = dwc2_ctrl_feed_dout(dev, 8); - if (err == -ENOMEM) { - err = udc_submit_ep_event(dev, buf, err); - } - err = udc_ctrl_submit_s_status(dev); } @@ -751,6 +847,7 @@ static int dwc2_handle_evt_setup(const struct device *dev) static inline int dwc2_handle_evt_dout(const struct device *dev, struct udc_ep_config *const cfg) { + struct udc_data *data = dev->data; struct net_buf *buf; int err = 0; @@ -767,25 +864,14 @@ static inline int dwc2_handle_evt_dout(const struct device *dev, /* s-in-status finished */ LOG_DBG("dout:%p| status, feed >s", buf); - /* Feed a buffer for the next setup packet */ - err = dwc2_ctrl_feed_dout(dev, 8); - if (err == -ENOMEM) { - err = udc_submit_ep_event(dev, buf, err); - } - /* Status stage finished, notify upper layer */ udc_ctrl_submit_status(dev, buf); - } else { - /* - * For all other cases we feed with a buffer - * large enough for setup packet. - */ - LOG_DBG("dout:%p| data, feed >s", buf); - err = dwc2_ctrl_feed_dout(dev, 8); - if (err == -ENOMEM) { - err = udc_submit_ep_event(dev, buf, err); + if (dwc2_in_buffer_dma_mode(dev)) { + dwc2_ctrl_feed_dout(dev, 8); } + } else { + LOG_DBG("dout:%p| data, feed >s", buf); } /* Update to next stage of control transfer */ @@ -794,6 +880,13 @@ static inline int dwc2_handle_evt_dout(const struct device *dev, if (udc_ctrl_stage_is_status_in(dev)) { err = udc_ctrl_submit_s_out_status(dev, buf); } + + if (data->stage == CTRL_PIPE_STAGE_ERROR) { + /* Allow receiving next SETUP. USB stack won't queue any + * buffer because it has no clue about this transfer. + */ + dwc2_ensure_setup_ready(dev); + } } else { err = udc_submit_ep_event(dev, buf, 0); } @@ -837,10 +930,12 @@ static int dwc2_handle_evt_din(const struct device *dev, udc_ctrl_update_stage(dev, buf); if (udc_ctrl_stage_is_status_out(dev)) { - /* - * IN transfer finished, release buffer, - * control OUT buffer should be already fed. - */ + if (dwc2_in_completer_mode(dev)) { + /* Allow OUT status stage */ + dwc2_ctrl_feed_dout(dev, 8); + } + + /* IN transfer finished, release buffer. */ net_buf_unref(buf); } @@ -915,6 +1010,11 @@ static void dwc2_restore_essential_registers(const struct device *dev, struct dwc2_reg_backup *backup = &priv->backup; uint32_t pcgcctl = backup->pcgcctl & USB_DWC2_PCGCCTL_RESTOREVALUE_MASK; + if (usb_dwc2_get_pcgcctl_p2hd_dev_enum_spd(pcgcctl) == + USB_DWC2_PCGCCTL_P2HD_DEV_ENUM_SPD_HS) { + pcgcctl |= BIT(17); + } + sys_write32(backup->glpmcfg, (mem_addr_t)&base->glpmcfg); sys_write32(backup->gi2cctl, (mem_addr_t)&base->gi2cctl); sys_write32(pcgcctl, (mem_addr_t)&base->pcgcctl); @@ -940,6 +1040,21 @@ static void dwc2_restore_essential_registers(const struct device *dev, pcgcctl |= USB_DWC2_PCGCCTL_ESSREGRESTORED; sys_write32(pcgcctl, (mem_addr_t)&base->pcgcctl); + + /* Note: in Remote Wakeup case 15 ms max signaling time starts now */ + + /* Wait for Restore Done Interrupt */ + dwc2_wait_for_bit(dev, (mem_addr_t)&base->gintsts, USB_DWC2_GINTSTS_RSTRDONEINT); + + if (priv->wa_essregrestored) { + pcgcctl &= ~USB_DWC2_PCGCCTL_ESSREGRESTORED; + sys_write32(pcgcctl, (mem_addr_t)&base->pcgcctl); + k_busy_wait(1); + } + + if (!bus_reset) { + sys_write32(0xFFFFFFFFUL, (mem_addr_t)&base->gintsts); + } } static void dwc2_restore_device_registers(const struct device *dev, bool rwup) @@ -1076,14 +1191,6 @@ static void dwc2_exit_hibernation(const struct device *dev, dwc2_restore_essential_registers(dev, rwup, bus_reset); - /* Note: in Remote Wakeup case 15 ms max signaling time starts now */ - - /* Wait for Restore Done Interrupt */ - dwc2_wait_for_bit(dev, (mem_addr_t)&base->gintsts, USB_DWC2_GINTSTS_RSTRDONEINT); - if (!bus_reset) { - sys_write32(0xFFFFFFFFUL, (mem_addr_t)&base->gintsts); - } - /* Disable restore from PMU */ sys_clear_bits(gpwrdn_reg, USB_DWC2_GPWRDN_RESTORE); k_busy_wait(1); @@ -1164,7 +1271,7 @@ static int dwc2_set_dedicated_fifo(const struct device *dev, tmp = *diepctl & ~USB_DWC2_DEPCTL_TXFNUM_MASK; reqdep = DIV_ROUND_UP(udc_mps_ep_size(cfg), 4U); - if (priv->bufferdma) { + if (dwc2_in_buffer_dma_mode(dev)) { /* In DMA mode, TxFIFO capable of holding 2 packets is enough */ reqdep *= MIN(2, (1 + addnl)); } else { @@ -1255,13 +1362,7 @@ static int dwc2_ep_control_enable(const struct device *dev, dxepctl0 |= USB_DWC2_DEPCTL_USBACTEP; if (cfg->addr == USB_CONTROL_EP_OUT) { - int ret; - dwc2_flush_rx_fifo(dev); - ret = dwc2_ctrl_feed_dout(dev, 8); - if (ret) { - return ret; - } } else { dwc2_flush_tx_fifo(dev, 0); } @@ -1546,6 +1647,9 @@ static int udc_dwc2_ep_set_halt(const struct device *dev, LOG_DBG("Set halt ep 0x%02x", cfg->addr); if (ep_idx != 0) { cfg->stat.halted = true; + } else { + /* Data/Status stage is STALLed, allow receiving next SETUP */ + dwc2_ensure_setup_ready(dev); } return 0; @@ -1752,6 +1856,7 @@ static int udc_dwc2_init_controller(const struct device *dev) mem_addr_t gahbcfg_reg = (mem_addr_t)&base->gahbcfg; mem_addr_t gusbcfg_reg = (mem_addr_t)&base->gusbcfg; mem_addr_t dcfg_reg = (mem_addr_t)&base->dcfg; + uint32_t gsnpsid; uint32_t dcfg; uint32_t gusbcfg; uint32_t gahbcfg; @@ -1767,6 +1872,10 @@ static int udc_dwc2_init_controller(const struct device *dev) return ret; } + /* Enable RTL workarounds based on controller revision */ + gsnpsid = sys_read32((mem_addr_t)&base->gsnpsid); + priv->wa_essregrestored = gsnpsid < USB_DWC2_GSNPSID_REV_5_00A; + priv->ghwcfg1 = sys_read32((mem_addr_t)&base->ghwcfg1); ghwcfg2 = sys_read32((mem_addr_t)&base->ghwcfg2); ghwcfg3 = sys_read32((mem_addr_t)&base->ghwcfg3); @@ -2207,14 +2316,14 @@ static int dwc2_driver_preinit(const struct device *dev) return 0; } -static int udc_dwc2_lock(const struct device *dev) +static void udc_dwc2_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_dwc2_unlock(const struct device *dev) +static void udc_dwc2_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static void dwc2_on_bus_reset(const struct device *dev) @@ -2237,7 +2346,7 @@ static void dwc2_on_bus_reset(const struct device *dev) } doepmsk = USB_DWC2_DOEPINT_SETUP | USB_DWC2_DOEPINT_XFERCOMPL; - if (priv->bufferdma) { + if (dwc2_in_buffer_dma_mode(dev)) { doepmsk |= USB_DWC2_DOEPINT_STSPHSERCVD; } @@ -2245,7 +2354,7 @@ static void dwc2_on_bus_reset(const struct device *dev) sys_set_bits((mem_addr_t)&base->diepmsk, USB_DWC2_DIEPINT_XFERCOMPL); /* Software has to handle RxFLvl interrupt only in Completer mode */ - if (!priv->bufferdma) { + if (dwc2_in_completer_mode(dev)) { sys_set_bits((mem_addr_t)&base->gintmsk, USB_DWC2_GINTSTS_RXFLVL); } @@ -2266,6 +2375,8 @@ static void dwc2_handle_enumdone(const struct device *dev) dsts = sys_read32((mem_addr_t)&base->dsts); priv->enumspd = usb_dwc2_get_dsts_enumspd(dsts); priv->enumdone = 1; + + k_event_post(&priv->drv_evt, BIT(DWC2_DRV_EVT_ENUM_DONE)); } static inline int dwc2_read_fifo_setup(const struct device *dev, uint8_t ep, @@ -2451,7 +2562,7 @@ static inline void dwc2_handle_out_xfercompl(const struct device *dev, } if (!valid) { - if (!priv->bufferdma) { + if (dwc2_in_completer_mode(dev)) { /* RxFlvl added data to net buf, rollback */ net_buf_remove_mem(buf, bcnt); } @@ -2460,12 +2571,12 @@ static inline void dwc2_handle_out_xfercompl(const struct device *dev, } } - if (priv->bufferdma && bcnt) { - sys_cache_data_invd_range(buf->data, bcnt); + if (dwc2_in_buffer_dma_mode(dev) && bcnt) { + sys_cache_data_invd_range(net_buf_tail(buf), bcnt); net_buf_add(buf, bcnt); } - if (!is_iso && (bcnt % udc_mps_ep_size(ep_cfg)) == 0 && + if (!is_iso && bcnt && (bcnt % udc_mps_ep_size(ep_cfg)) == 0 && net_buf_tailroom(buf)) { dwc2_prep_rx(dev, buf, ep_cfg); } else { @@ -2504,7 +2615,8 @@ static inline void dwc2_handle_oepint(const struct device *dev) /* StupPktRcvd is not enabled for interrupt, but must be checked * when XferComp hits to determine if SETUP token was received. */ - if (priv->bufferdma && (status & USB_DWC2_DOEPINT_XFERCOMPL) && + if (dwc2_in_buffer_dma_mode(dev) && + (status & USB_DWC2_DOEPINT_XFERCOMPL) && (doepint & USB_DWC2_DOEPINT_STUPPKTRCVD)) { uint32_t addr; @@ -2965,6 +3077,12 @@ static ALWAYS_INLINE void dwc2_thread_handler(void *const arg) config->irq_enable_func(dev); } + if (evt & BIT(DWC2_DRV_EVT_ENUM_DONE)) { + k_event_clear(&priv->drv_evt, BIT(DWC2_DRV_EVT_ENUM_DONE)); + + dwc2_ensure_setup_ready(dev); + } + udc_unlock_internal(dev); } diff --git a/drivers/usb/udc/udc_it82xx2.c b/drivers/usb/udc/udc_it82xx2.c index 6affd349e7226..0c61b7b17db87 100644 --- a/drivers/usb/udc/udc_it82xx2.c +++ b/drivers/usb/udc/udc_it82xx2.c @@ -1495,14 +1495,14 @@ static int it82xx2_shutdown(const struct device *dev) return 0; } -static int it82xx2_lock(const struct device *dev) +static void it82xx2_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int it82xx2_unlock(const struct device *dev) +static void it82xx2_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static const struct udc_api it82xx2_api = { diff --git a/drivers/usb/udc/udc_kinetis.c b/drivers/usb/udc/udc_kinetis.c index c471fb15ebda6..70fae41b48718 100644 --- a/drivers/usb/udc/udc_kinetis.c +++ b/drivers/usb/udc/udc_kinetis.c @@ -1069,14 +1069,14 @@ static int usbfsotg_shutdown(const struct device *dev) return 0; } -static int usbfsotg_lock(const struct device *dev) +static void usbfsotg_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int usbfsotg_unlock(const struct device *dev) +static void usbfsotg_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static int usbfsotg_driver_preinit(const struct device *dev) diff --git a/drivers/usb/udc/udc_mcux_ehci.c b/drivers/usb/udc/udc_mcux_ehci.c index 3379a3b88e0b7..9055905634ee3 100644 --- a/drivers/usb/udc/udc_mcux_ehci.c +++ b/drivers/usb/udc/udc_mcux_ehci.c @@ -64,14 +64,14 @@ struct udc_mcux_event { K_MEM_SLAB_DEFINE(udc_event_slab, sizeof(struct udc_mcux_event), CONFIG_UDC_NXP_EVENT_COUNT, sizeof(void *)); -static int udc_mcux_lock(const struct device *dev) +static void udc_mcux_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_mcux_unlock(const struct device *dev) +static void udc_mcux_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static int udc_mcux_control(const struct device *dev, usb_device_control_type_t command, @@ -359,7 +359,7 @@ static bool udc_mcux_handler_zlt(const struct device *dev, uint8_t ep, struct ne usb_status_t status; udc_ep_buf_clear_zlp(buf); - status = mcux_if->deviceRecv(priv->mcux_device.controllerHandle, + status = mcux_if->deviceSend(priv->mcux_device.controllerHandle, ep, NULL, 0); if (status != kStatus_USB_Success) { udc_submit_event(dev, UDC_EVT_ERROR, -EIO); @@ -695,8 +695,7 @@ static int udc_mcux_init(const struct device *dev) #ifdef CONFIG_DT_HAS_NXP_USBPHY_ENABLED if (config->phy_config != NULL) { - USB_EhciPhyInit(priv->controller_id, 0u, - (usb_phy_config_struct_t *)&config->phy_config); + USB_EhciPhyInit(priv->controller_id, 0u, config->phy_config); } #endif diff --git a/drivers/usb/udc/udc_mcux_ip3511.c b/drivers/usb/udc/udc_mcux_ip3511.c index d30438319b0e7..f8db1221e0743 100644 --- a/drivers/usb/udc/udc_mcux_ip3511.c +++ b/drivers/usb/udc/udc_mcux_ip3511.c @@ -64,14 +64,14 @@ struct udc_mcux_event { K_MEM_SLAB_DEFINE(udc_event_slab, sizeof(struct udc_mcux_event), CONFIG_UDC_NXP_EVENT_COUNT, sizeof(void *)); -static int udc_mcux_lock(const struct device *dev) +static void udc_mcux_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_mcux_unlock(const struct device *dev) +static void udc_mcux_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static int udc_mcux_control(const struct device *dev, usb_device_control_type_t command, @@ -695,8 +695,7 @@ static int udc_mcux_init(const struct device *dev) #ifdef CONFIG_DT_HAS_NXP_USBPHY_ENABLED if (config->phy_config != NULL) { - USB_EhciPhyInit(priv->controller_id, 0u, - (usb_phy_config_struct_t *)&config->phy_config); + USB_EhciPhyInit(priv->controller_id, 0u, config->phy_config); } #endif diff --git a/drivers/usb/udc/udc_nrf.c b/drivers/usb/udc/udc_nrf.c index e72291744633f..9eead90dfbc60 100644 --- a/drivers/usb/udc/udc_nrf.c +++ b/drivers/usb/udc/udc_nrf.c @@ -116,7 +116,6 @@ static void udc_event_xfer_in_next(const struct device *dev, const uint8_t ep) if (err != NRFX_SUCCESS) { LOG_ERR("ep 0x%02x nrfx error: %x", ep, err); /* REVISE: remove from endpoint queue? ASSERT? */ - udc_submit_ep_event(dev, buf, -ECONNREFUSED); } else { udc_ep_set_busy(dev, ep, true); } @@ -245,7 +244,6 @@ static void udc_event_xfer_out_next(const struct device *dev, const uint8_t ep) if (err != NRFX_SUCCESS) { LOG_ERR("ep 0x%02x nrfx error: %x", ep, err); /* REVISE: remove from endpoint queue? ASSERT? */ - udc_submit_ep_event(dev, buf, -ECONNREFUSED); } else { udc_ep_set_busy(dev, ep, true); } @@ -913,14 +911,14 @@ static int udc_nrf_driver_init(const struct device *dev) return 0; } -static int udc_nrf_lock(const struct device *dev) +static void udc_nrf_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_nrf_unlock(const struct device *dev) +static void udc_nrf_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static const struct udc_nrf_config udc_nrf_cfg = { diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index 2fba252371f4e..5545132944d21 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -1622,14 +1622,14 @@ static int udc_numaker_shutdown(const struct device *dev) return 0; } -static int udc_numaker_lock(const struct device *dev) +static void udc_numaker_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_numaker_unlock(const struct device *dev) +static void udc_numaker_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static int udc_numaker_driver_preinit(const struct device *dev) diff --git a/drivers/usb/udc/udc_renesas_ra.c b/drivers/usb/udc/udc_renesas_ra.c new file mode 100644 index 0000000000000..a113bcad8a3dd --- /dev/null +++ b/drivers/usb/udc/udc_renesas_ra.c @@ -0,0 +1,831 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "udc_common.h" + +#include +#include +#include +#include +#include "r_usb_device.h" + +#include +LOG_MODULE_REGISTER(udc_renesas_ra, CONFIG_UDC_DRIVER_LOG_LEVEL); + +struct udc_renesas_ra_config { + const struct pinctrl_dev_config *pcfg; + const struct device **clocks; + size_t num_of_clocks; + size_t num_of_eps; + struct udc_ep_config *ep_cfg_in; + struct udc_ep_config *ep_cfg_out; + void (*make_thread)(const struct device *dev); + int speed_idx; +}; + +struct udc_renesas_ra_data { + struct k_thread thread_data; + struct st_usbd_instance_ctrl udc; + struct st_usbd_cfg udc_cfg; +}; + +enum udc_renesas_ra_event_type { + /* An event generated by the HAL driver */ + UDC_RENESAS_RA_EVT_HAL, + /* Shim driver event to trigger next transfer */ + UDC_RENESAS_RA_EVT_XFER, + /* Let controller perform status stage */ + UDC_RENESAS_RA_EVT_STATUS, +}; + +struct udc_renesas_ra_evt { + enum udc_renesas_ra_event_type type; + usbd_event_t hal_evt; + uint8_t ep; +}; + +K_MSGQ_DEFINE(drv_msgq, sizeof(struct udc_renesas_ra_evt), CONFIG_UDC_RENESAS_RA_MAX_QMESSAGES, + sizeof(uint32_t)); + +extern void usb_device_isr(void); + +static void udc_renesas_ra_event_handler(usbd_callback_arg_t *p_args) +{ + const struct device *dev = p_args->p_context; + struct udc_renesas_ra_evt evt; + + switch (p_args->event.event_id) { + case USBD_EVENT_BUS_RESET: + udc_submit_event(dev, UDC_EVT_RESET, 0); + break; + + case USBD_EVENT_VBUS_RDY: + udc_submit_event(dev, UDC_EVT_VBUS_READY, 0); + break; + + case USBD_EVENT_VBUS_REMOVED: + udc_submit_event(dev, UDC_EVT_VBUS_REMOVED, 0); + break; + + case USBD_EVENT_SUSPEND: + udc_submit_event(dev, UDC_EVT_SUSPEND, 0); + break; + + case USBD_EVENT_RESUME: + udc_submit_event(dev, UDC_EVT_RESUME, 0); + break; + + case USBD_EVENT_SOF: + udc_submit_event(dev, UDC_EVT_SOF, 0); + break; + + default: + evt.type = UDC_RENESAS_RA_EVT_HAL; + evt.hal_evt = p_args->event; + k_msgq_put(&drv_msgq, &evt, K_NO_WAIT); + break; + } +} + +static void udc_renesas_ra_interrupt_handler(void *arg) +{ + ARG_UNUSED(arg); + usb_device_isr(); +} + +static void udc_event_xfer_next(const struct device *dev, const uint8_t ep) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + struct net_buf *buf; + + if (udc_ep_is_busy(dev, ep)) { + return; + } + + buf = udc_buf_peek(dev, ep); + if (buf != NULL) { + int err; + + if (USB_EP_DIR_IS_IN(ep)) { + err = R_USBD_XferStart(&data->udc, ep, buf->data, buf->len); + } else { + err = R_USBD_XferStart(&data->udc, ep, buf->data, buf->size); + } + + if (err != FSP_SUCCESS) { + LOG_ERR("ep 0x%02x error", ep); + udc_submit_ep_event(dev, buf, -ECONNREFUSED); + } else { + udc_ep_set_busy(dev, ep, true); + } + } +} + +static int usbd_ctrl_feed_dout(const struct device *dev, const size_t length) +{ + struct udc_ep_config *cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); + struct net_buf *buf; + struct udc_renesas_ra_data *data = udc_get_private(dev); + + buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, length); + if (buf == NULL) { + return -ENOMEM; + } + + k_fifo_put(&cfg->fifo, buf); + + if (FSP_SUCCESS != R_USBD_XferStart(&data->udc, cfg->addr, buf->data, buf->size)) { + return -EIO; + } + + return 0; +} + +static int udc_event_xfer_setup(const struct device *dev, struct udc_renesas_ra_evt *evt) +{ + struct net_buf *buf; + int err; + + struct usb_setup_packet *setup_packet = + (struct usb_setup_packet *)&evt->hal_evt.setup_received; + + buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, sizeof(struct usb_setup_packet)); + if (buf == NULL) { + LOG_ERR("Failed to allocate for setup"); + return -ENOMEM; + } + + udc_ep_buf_set_setup(buf); + net_buf_add_mem(buf, setup_packet, sizeof(struct usb_setup_packet)); + + /* Update to next stage of control transfer */ + udc_ctrl_update_stage(dev, buf); + + if (udc_ctrl_stage_is_data_out(dev)) { + /* Allocate and feed buffer for data OUT stage */ + LOG_DBG("s:%p|feed for -out-", buf); + err = usbd_ctrl_feed_dout(dev, udc_data_stage_length(buf)); + if (err == -ENOMEM) { + err = udc_submit_ep_event(dev, buf, err); + } + } else if (udc_ctrl_stage_is_data_in(dev)) { + err = udc_ctrl_submit_s_in_status(dev); + } else { + err = udc_ctrl_submit_s_status(dev); + } + + return err; +} + +static void udc_event_xfer_ctrl_in(const struct device *dev, struct net_buf *const buf) +{ + if (udc_ctrl_stage_is_status_in(dev) || udc_ctrl_stage_is_no_data(dev)) { + /* Status stage finished, notify upper layer */ + udc_ctrl_submit_status(dev, buf); + } + + /* Update to next stage of control transfer */ + udc_ctrl_update_stage(dev, buf); + + if (udc_ctrl_stage_is_status_out(dev)) { + /* IN transfer finished, perform status stage OUT and release buffer */ + usbd_ctrl_feed_dout(dev, 0); + net_buf_unref(buf); + } +} + +static void udc_event_status_in(const struct device *dev) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + struct net_buf *buf; + + buf = udc_buf_get(dev, USB_CONTROL_EP_IN); + if (unlikely(buf == NULL)) { + LOG_DBG("ep 0x%02x queue is empty", USB_CONTROL_EP_IN); + return; + } + + /* Perform status stage IN */ + R_USBD_XferStart(&data->udc, USB_CONTROL_EP_IN, NULL, 0); + + udc_event_xfer_ctrl_in(dev, buf); +} + +static void udc_event_xfer_ctrl_out(const struct device *dev, struct net_buf *const buf, + uint32_t len) +{ + net_buf_add(buf, len); + + if (udc_ctrl_stage_is_status_out(dev)) { + /* Status stage finished, notify upper layer */ + udc_ctrl_submit_status(dev, buf); + } + + /* Update to next stage of control transfer */ + udc_ctrl_update_stage(dev, buf); + + if (udc_ctrl_stage_is_status_in(dev)) { + udc_ctrl_submit_s_out_status(dev, buf); + } +} + +static void udc_event_xfer_complete(const struct device *dev, struct udc_renesas_ra_evt *evt) +{ + struct net_buf *buf; + struct udc_renesas_ra_data *data = udc_get_private(dev); + + uint8_t ep = evt->hal_evt.xfer_complete.ep_addr; + usbd_xfer_result_t result = evt->hal_evt.xfer_complete.result; + uint32_t len = evt->hal_evt.xfer_complete.len; + + udc_ep_set_busy(dev, ep, false); + + buf = udc_buf_peek(dev, ep); + if (buf == NULL) { + return; + } + + if (result != USBD_XFER_RESULT_SUCCESS) { + goto error; + } + + if (USB_EP_DIR_IS_IN(ep) && udc_ep_buf_has_zlp(buf)) { + /* Send ZLP, notification about transfer complete should come again */ + udc_ep_buf_clear_zlp(buf); + if (FSP_SUCCESS != R_USBD_XferStart(&data->udc, ep, NULL, 0)) { + goto error; + } + + return; + } + + buf = udc_buf_get(dev, ep); + + if (ep == USB_CONTROL_EP_IN) { + udc_event_xfer_ctrl_in(dev, buf); + } else if (ep == USB_CONTROL_EP_OUT) { + udc_event_xfer_ctrl_out(dev, buf, len); + } else { + if (USB_EP_DIR_IS_OUT(ep)) { + net_buf_add(buf, len); + } + udc_submit_ep_event(dev, buf, 0); + } + + return; +error: + udc_submit_ep_event(dev, buf, -EIO); +} + +static ALWAYS_INLINE void renesas_ra_thread_handler(void *const arg) +{ + const struct device *dev = (const struct device *)arg; + + LOG_DBG("Driver %p thread started", dev); + while (true) { + struct udc_renesas_ra_evt evt; + + k_msgq_get(&drv_msgq, &evt, K_FOREVER); + switch (evt.type) { + case UDC_RENESAS_RA_EVT_HAL: { + switch (evt.hal_evt.event_id) { + case USBD_EVENT_SETUP_RECEIVED: + udc_event_xfer_setup(dev, &evt); + break; + + case USBD_EVENT_XFER_COMPLETE: + udc_event_xfer_complete(dev, &evt); + break; + + default: + break; + } + break; + } + + case UDC_RENESAS_RA_EVT_XFER: + udc_event_xfer_next(dev, evt.ep); + break; + + case UDC_RENESAS_RA_EVT_STATUS: + udc_event_status_in(dev); + break; + + default: + break; + } + } +} + +static int udc_renesas_ra_ep_enqueue(const struct device *dev, struct udc_ep_config *const cfg, + struct net_buf *buf) +{ + struct udc_renesas_ra_evt evt = {}; + + LOG_DBG("%p enqueue %p", dev, buf); + + udc_buf_put(cfg, buf); + + evt.ep = cfg->addr; + if (cfg->addr == USB_CONTROL_EP_IN && buf->len == 0) { + evt.type = UDC_RENESAS_RA_EVT_STATUS; + } else { + evt.type = UDC_RENESAS_RA_EVT_XFER; + } + + k_msgq_put(&drv_msgq, &evt, K_NO_WAIT); + + if (cfg->stat.halted) { + LOG_DBG("ep 0x%02x halted", cfg->addr); + } + + return 0; +} + +static int udc_renesas_ra_ep_dequeue(const struct device *dev, struct udc_ep_config *const cfg) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + unsigned int lock_key; + struct net_buf *buf; + + lock_key = irq_lock(); + + buf = udc_buf_get_all(dev, cfg->addr); + if (buf != NULL) { + udc_submit_ep_event(dev, buf, -ECONNABORTED); + } + + if (FSP_SUCCESS != R_USBD_XferAbort(&data->udc, cfg->addr)) { + return -EIO; + } + + udc_ep_set_busy(dev, cfg->addr, false); + + irq_unlock(lock_key); + + return 0; +} + +static int udc_renesas_ra_ep_enable(const struct device *dev, struct udc_ep_config *const cfg) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + usbd_desc_endpoint_t ep_desc; + + if (USB_EP_GET_IDX(cfg->addr) == 0) { + return 0; + } + + ep_desc.bLength = sizeof(struct usb_ep_descriptor); + ep_desc.bDescriptorType = USB_DESC_ENDPOINT; + ep_desc.bEndpointAddress = cfg->addr; + ep_desc.bmAttributes = cfg->attributes; + ep_desc.wMaxPacketSize = cfg->mps; + ep_desc.bInterval = cfg->interval; + + if (FSP_SUCCESS != R_USBD_EdptOpen(&data->udc, &ep_desc)) { + return -EIO; + } + + LOG_DBG("Enable ep 0x%02x", cfg->addr); + + return 0; +} + +static int udc_renesas_ra_ep_disable(const struct device *dev, struct udc_ep_config *const cfg) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + + if (USB_EP_GET_IDX(cfg->addr) == 0) { + return 0; + } + + if (FSP_SUCCESS != R_USBD_EdptClose(&data->udc, cfg->addr)) { + return -EIO; + } + + LOG_DBG("Disable ep 0x%02x", cfg->addr); + + return 0; +} + +static int udc_renesas_ra_ep_set_halt(const struct device *dev, struct udc_ep_config *const cfg) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + + LOG_DBG("Set halt ep 0x%02x", cfg->addr); + + if (FSP_SUCCESS != R_USBD_EdptStall(&data->udc, cfg->addr)) { + return -EIO; + } + + cfg->stat.halted = true; + + return 0; +} + +static int udc_renesas_ra_ep_clear_halt(const struct device *dev, struct udc_ep_config *const cfg) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + + LOG_DBG("Clear halt ep 0x%02x", cfg->addr); + + if (FSP_SUCCESS != R_USBD_EdptClearStall(&data->udc, cfg->addr)) { + return -EIO; + } + + cfg->stat.halted = false; + + return 0; +} + +static int udc_renesas_ra_set_address(const struct device *dev, const uint8_t addr) +{ + /* The USB controller will automatically perform a response to the SET_ADRRESS request. */ + LOG_DBG("Set new address %u for %p", addr, dev); + + return 0; +} + +static int udc_renesas_ra_host_wakeup(const struct device *dev) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + + if (FSP_SUCCESS != R_USBD_RemoteWakeup(&data->udc)) { + return -EIO; + } + + LOG_DBG("Remote wakeup from %p", dev); + + return 0; +} + +static enum udc_bus_speed udc_renesas_ra_device_speed(const struct device *dev) +{ + struct udc_data *data = dev->data; + + return data->caps.hs ? UDC_BUS_SPEED_HS : UDC_BUS_SPEED_FS; +} + +static int udc_renesas_ra_enable(const struct device *dev) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + + if (FSP_SUCCESS != R_USBD_Connect(&data->udc)) { + return -EIO; + } + + LOG_DBG("Enable device %p", dev); + + return 0; +} + +static int udc_renesas_ra_disable(const struct device *dev) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + + if (FSP_SUCCESS != R_USBD_Disconnect(&data->udc)) { + return -EIO; + } + + LOG_DBG("Enable device %p", dev); + + return 0; +} + +static int udc_renesas_ra_init(const struct device *dev) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + + if (FSP_SUCCESS != R_USBD_Open(&data->udc, &data->udc_cfg)) { + return -EIO; + } + + if (udc_ep_enable_internal(dev, USB_CONTROL_EP_OUT, USB_EP_TYPE_CONTROL, 64, 0)) { + LOG_ERR("Failed to enable control endpoint"); + return -EIO; + } + + if (udc_ep_enable_internal(dev, USB_CONTROL_EP_IN, USB_EP_TYPE_CONTROL, 64, 0)) { + LOG_ERR("Failed to enable control endpoint"); + return -EIO; + } + +#if DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_usbhs) + if (data->udc_cfg.hs_irq != (IRQn_Type)BSP_IRQ_DISABLED) { + irq_enable(data->udc_cfg.hs_irq); + } +#endif + + if (data->udc_cfg.irq != (IRQn_Type)BSP_IRQ_DISABLED) { + irq_enable(data->udc_cfg.irq); + } + + if (data->udc_cfg.irq_r != (IRQn_Type)BSP_IRQ_DISABLED) { + irq_enable(data->udc_cfg.irq_r); + } + + return 0; +} + +static int udc_renesas_ra_shutdown(const struct device *dev) +{ + struct udc_renesas_ra_data *data = udc_get_private(dev); + + if (udc_ep_disable_internal(dev, USB_CONTROL_EP_OUT)) { + LOG_ERR("Failed to disable control endpoint"); + return -EIO; + } + + if (udc_ep_disable_internal(dev, USB_CONTROL_EP_IN)) { + LOG_ERR("Failed to disable control endpoint"); + return -EIO; + } + + if (FSP_SUCCESS != R_USBD_Close(&data->udc)) { + return -EIO; + } + + return 0; +} + +static int udc_renesas_ra_clock_check(const struct device *dev) +{ + const struct udc_renesas_ra_config *config = dev->config; + +#if USBHS_PHY_CLOCK_SOURCE_IS_XTAL + if (config->speed_idx == UDC_BUS_SPEED_HS) { + if (BSP_CFG_XTAL_HZ == 0) { + LOG_ERR("XTAL clock should be provided"); + return -EINVAL; + } + + return 0; + } +#endif + + for (size_t i = 0; i < config->num_of_clocks; i++) { + const struct device *clock_dev = *(config->clocks + i); + const struct clock_control_ra_pclk_cfg *clock_cfg = clock_dev->config; + uint32_t clk_src_rate; + uint32_t clock_rate; + + if (!device_is_ready(clock_dev)) { + LOG_ERR("%s is not ready", clock_dev->name); + return -ENODEV; + } + + clk_src_rate = R_BSP_SourceClockHzGet(clock_cfg->clk_src); + clock_rate = clk_src_rate / clock_cfg->clk_div; + + if (strcmp(clock_dev->name, "uclk") == 0 && clock_rate != MHZ(48)) { + LOG_ERR("Setting for uclk should be 48Mhz"); + return -ENOTSUP; + } + +#if DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_usbhs) + if (strcmp(clock_dev->name, "u60clk") == 0 && clock_rate != MHZ(60)) { + LOG_ERR("Setting for u60clk should be 60Mhz"); + return -ENOTSUP; + } +#endif + } + + return 0; +} + +static int udc_renesas_ra_driver_preinit(const struct device *dev) +{ + const struct udc_renesas_ra_config *config = dev->config; + struct udc_renesas_ra_data *priv = udc_get_private(dev); + struct udc_data *data = dev->data; + uint16_t mps = 1023; + int err; + +#if !USBHS_PHY_CLOCK_SOURCE_IS_XTAL + if (priv->udc_cfg.usb_speed == USBD_SPEED_HS) { + LOG_ERR("High-speed operation is not supported in case PHY clock source is not " + "XTAL"); + return -ENOTSUP; + } +#endif + + if (config->speed_idx == UDC_BUS_SPEED_HS) { + if (!(priv->udc_cfg.usb_speed == USBD_SPEED_HS || + priv->udc_cfg.usb_speed == USBD_SPEED_FS)) { + LOG_ERR("USBHS module only support high-speed and full-speed device"); + return -ENOTSUP; + } + } else { + /* config->speed_idx == UDC_BUS_SPEED_FS */ + if (priv->udc_cfg.usb_speed != USBD_SPEED_FS) { + LOG_ERR("USBFS module only support full-speed device"); + return -ENOTSUP; + } + } + + err = udc_renesas_ra_clock_check(dev); + if (err < 0) { + return err; + } + + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + k_mutex_init(&data->mutex); + + data->caps.rwup = true; + data->caps.mps0 = UDC_MPS0_64; + if (priv->udc_cfg.usb_speed == USBD_SPEED_HS) { + data->caps.hs = true; + mps = 1024; + } + + for (int i = 0; i < config->num_of_eps; i++) { + config->ep_cfg_out[i].caps.out = 1; + if (i == 0) { + config->ep_cfg_out[i].caps.control = 1; + config->ep_cfg_out[i].caps.mps = 64; + } else { + config->ep_cfg_out[i].caps.bulk = 1; + config->ep_cfg_out[i].caps.interrupt = 1; + config->ep_cfg_out[i].caps.iso = 1; + config->ep_cfg_out[i].caps.mps = mps; + } + + config->ep_cfg_out[i].addr = USB_EP_DIR_OUT | i; + err = udc_register_ep(dev, &config->ep_cfg_out[i]); + if (err != 0) { + LOG_ERR("Failed to register endpoint"); + return err; + } + } + + for (int i = 0; i < config->num_of_eps; i++) { + config->ep_cfg_in[i].caps.in = 1; + if (i == 0) { + config->ep_cfg_in[i].caps.control = 1; + config->ep_cfg_in[i].caps.mps = 64; + } else { + config->ep_cfg_in[i].caps.bulk = 1; + config->ep_cfg_in[i].caps.interrupt = 1; + config->ep_cfg_in[i].caps.iso = 1; + config->ep_cfg_in[i].caps.mps = mps; + } + + config->ep_cfg_in[i].addr = USB_EP_DIR_IN | i; + err = udc_register_ep(dev, &config->ep_cfg_in[i]); + if (err != 0) { + LOG_ERR("Failed to register endpoint"); + return err; + } + } + +#if DT_HAS_COMPAT_STATUS_OKAY(renesas_ra_usbhs) + if (priv->udc_cfg.hs_irq != (IRQn_Type)BSP_IRQ_DISABLED) { + R_ICU->IELSR[priv->udc_cfg.hs_irq] = ELC_EVENT_USBHS_USB_INT_RESUME; + } +#endif + + if (priv->udc_cfg.irq != (IRQn_Type)BSP_IRQ_DISABLED) { + R_ICU->IELSR[priv->udc_cfg.irq] = ELC_EVENT_USBFS_INT; + } + + if (priv->udc_cfg.irq_r != (IRQn_Type)BSP_IRQ_DISABLED) { + R_ICU->IELSR[priv->udc_cfg.irq_r] = ELC_EVENT_USBFS_RESUME; + } + + config->make_thread(dev); + LOG_INF("Device %p (max. speed %d)", dev, priv->udc_cfg.usb_speed); + + return 0; +} + +static void udc_renesas_ra_lock(const struct device *dev) +{ + udc_lock_internal(dev, K_FOREVER); +} + +static void udc_renesas_ra_unlock(const struct device *dev) +{ + udc_unlock_internal(dev); +} + +static const struct udc_api udc_renesas_ra_api = { + .lock = udc_renesas_ra_lock, + .unlock = udc_renesas_ra_unlock, + .device_speed = udc_renesas_ra_device_speed, + .init = udc_renesas_ra_init, + .enable = udc_renesas_ra_enable, + .disable = udc_renesas_ra_disable, + .shutdown = udc_renesas_ra_shutdown, + .set_address = udc_renesas_ra_set_address, + .host_wakeup = udc_renesas_ra_host_wakeup, + .ep_enable = udc_renesas_ra_ep_enable, + .ep_disable = udc_renesas_ra_ep_disable, + .ep_set_halt = udc_renesas_ra_ep_set_halt, + .ep_clear_halt = udc_renesas_ra_ep_clear_halt, + .ep_enqueue = udc_renesas_ra_ep_enqueue, + .ep_dequeue = udc_renesas_ra_ep_dequeue, +}; + +#define DT_DRV_COMPAT renesas_ra_udc + +#define USB_RENESAS_RA_MODULE_NUMBER(id) (DT_REG_ADDR(id) == R_USB_FS0_BASE ? 0 : 1) + +#define USB_RENESAS_RA_IRQ_GET(id, name, cell) \ + COND_CODE_1(DT_IRQ_HAS_NAME(id, name), (DT_IRQ_BY_NAME(id, name, cell)), \ + ((IRQn_Type) BSP_IRQ_DISABLED)) + +#define USB_RENESAS_RA_MAX_SPEED_IDX(id) \ + (DT_NODE_HAS_COMPAT(id, renesas_ra_usbhs) ? UDC_BUS_SPEED_HS : UDC_BUS_SPEED_FS) + +#define USB_RENESAS_RA_SPEED_IDX(id) \ + (DT_NODE_HAS_COMPAT(id, renesas_ra_usbhs) \ + ? DT_ENUM_IDX_OR(id, maximum_speed, UDC_BUS_SPEED_HS) \ + : DT_ENUM_IDX_OR(id, maximum_speed, UDC_BUS_SPEED_FS)) + +#define USB_RENESAS_RA_IRQ_CONNECT(idx, n) \ + IRQ_CONNECT(DT_IRQ_BY_IDX(DT_INST_PARENT(n), idx, irq), \ + DT_IRQ_BY_IDX(DT_INST_PARENT(n), idx, priority), \ + udc_renesas_ra_interrupt_handler, DEVICE_DT_INST_GET(n), 0) + +#define USB_RENESAS_RA_CLOCKS_GET(idx, id) \ + DEVICE_DT_GET_OR_NULL(DT_PHANDLE_BY_IDX(id, phys_clock, idx)) + +#define UDC_RENESAS_RA_DEVICE_DEFINE(n) \ + PINCTRL_DT_DEFINE(DT_INST_PARENT(n)); \ + K_THREAD_STACK_DEFINE(udc_renesas_ra_stack_##n, CONFIG_UDC_RENESAS_RA_STACK_SIZE); \ + \ + static const struct device *udc_renesas_ra_clock_dev_##n[] = { \ + LISTIFY(DT_PROP_LEN_OR(DT_INST_PARENT(n), phys_clock, 0), \ + USB_RENESAS_RA_CLOCKS_GET, (,), DT_INST_PARENT(n)) \ + }; \ + \ + static void udc_renesas_ra_thread_##n(void *dev, void *arg1, void *arg2) \ + { \ + renesas_ra_thread_handler(dev); \ + } \ + \ + static void udc_renesas_ra_make_thread_##n(const struct device *dev) \ + { \ + struct udc_renesas_ra_data *priv = udc_get_private(dev); \ + \ + k_thread_create(&priv->thread_data, udc_renesas_ra_stack_##n, \ + K_THREAD_STACK_SIZEOF(udc_renesas_ra_stack_##n), \ + udc_renesas_ra_thread_##n, (void *)dev, NULL, NULL, \ + K_PRIO_COOP(CONFIG_UDC_RENESAS_RA_THREAD_PRIORITY), K_ESSENTIAL, \ + K_NO_WAIT); \ + k_thread_name_set(&priv->thread_data, dev->name); \ + } \ + \ + static struct udc_ep_config ep_cfg_in##n[DT_PROP(DT_INST_PARENT(n), num_bidir_endpoints)]; \ + static struct udc_ep_config \ + ep_cfg_out##n[DT_PROP(DT_INST_PARENT(n), num_bidir_endpoints)]; \ + \ + static const struct udc_renesas_ra_config udc_renesas_ra_config_##n = { \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(n)), \ + .clocks = udc_renesas_ra_clock_dev_##n, \ + .num_of_clocks = DT_PROP_LEN_OR(DT_INST_PARENT(n), phys_clock, 0), \ + .num_of_eps = DT_PROP(DT_INST_PARENT(n), num_bidir_endpoints), \ + .ep_cfg_in = ep_cfg_in##n, \ + .ep_cfg_out = ep_cfg_out##n, \ + .make_thread = udc_renesas_ra_make_thread_##n, \ + .speed_idx = USB_RENESAS_RA_MAX_SPEED_IDX(DT_INST_PARENT(n)), \ + }; \ + \ + static struct udc_renesas_ra_data udc_priv_##n = { \ + .udc_cfg = { \ + .module_number = USB_RENESAS_RA_MODULE_NUMBER(DT_INST_PARENT(n)), \ + .usb_speed = USB_RENESAS_RA_SPEED_IDX(DT_INST_PARENT(n)), \ + .irq = USB_RENESAS_RA_IRQ_GET(DT_INST_PARENT(n), usbfs_i, irq), \ + .irq_r = USB_RENESAS_RA_IRQ_GET(DT_INST_PARENT(n), usbfs_r, irq), \ + .hs_irq = USB_RENESAS_RA_IRQ_GET(DT_INST_PARENT(n), usbhs_ir, irq), \ + .ipl = USB_RENESAS_RA_IRQ_GET(DT_INST_PARENT(n), usbfs_i, priority), \ + .ipl_r = USB_RENESAS_RA_IRQ_GET(DT_INST_PARENT(n), usbfs_r, priority), \ + .hsipl = USB_RENESAS_RA_IRQ_GET(DT_INST_PARENT(n), usbhs_ir, priority), \ + .p_context = DEVICE_DT_INST_GET(n), \ + .p_callback = udc_renesas_ra_event_handler, \ + }, \ + }; \ + \ + static struct udc_data udc_data_##n = { \ + .mutex = Z_MUTEX_INITIALIZER(udc_data_##n.mutex), \ + .priv = &udc_priv_##n, \ + }; \ + \ + int udc_renesas_ra_driver_preinit##n(const struct device *dev) \ + { \ + LISTIFY(DT_NUM_IRQS(DT_INST_PARENT(n)), USB_RENESAS_RA_IRQ_CONNECT, (;), n); \ + return udc_renesas_ra_driver_preinit(dev); \ + } \ + \ + DEVICE_DT_INST_DEFINE(n, udc_renesas_ra_driver_preinit##n, NULL, &udc_data_##n, \ + &udc_renesas_ra_config_##n, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &udc_renesas_ra_api); + +DT_INST_FOREACH_STATUS_OKAY(UDC_RENESAS_RA_DEVICE_DEFINE) diff --git a/drivers/usb/udc/udc_rpi_pico.c b/drivers/usb/udc/udc_rpi_pico.c index f109418baa98a..4065f4555b151 100644 --- a/drivers/usb/udc/udc_rpi_pico.c +++ b/drivers/usb/udc/udc_rpi_pico.c @@ -1050,14 +1050,14 @@ static int udc_rpi_pico_driver_preinit(const struct device *dev) return 0; } -static int udc_rpi_pico_lock(const struct device *dev) +static void udc_rpi_pico_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_rpi_pico_unlock(const struct device *dev) +static void udc_rpi_pico_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static const struct udc_api udc_rpi_pico_api = { diff --git a/drivers/usb/udc/udc_skeleton.c b/drivers/usb/udc/udc_skeleton.c index f8870c87f58be..cba2016572cad 100644 --- a/drivers/usb/udc/udc_skeleton.c +++ b/drivers/usb/udc/udc_skeleton.c @@ -323,14 +323,14 @@ static int udc_skeleton_driver_preinit(const struct device *dev) return 0; } -static int udc_skeleton_lock(const struct device *dev) +static void udc_skeleton_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_skeleton_unlock(const struct device *dev) +static void udc_skeleton_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } /* diff --git a/drivers/usb/udc/udc_smartbond.c b/drivers/usb/udc/udc_smartbond.c index 3a214e1b60f29..dd5a2aa782a5c 100644 --- a/drivers/usb/udc/udc_smartbond.c +++ b/drivers/usb/udc/udc_smartbond.c @@ -1695,14 +1695,14 @@ static int udc_smartbond_init(const struct device *dev) return 0; } -static int udc_smartbond_lock(const struct device *dev) +static void udc_smartbond_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_smartbond_unlock(const struct device *dev) +static void udc_smartbond_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static const struct udc_api udc_smartbond_api = { diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index 627d229975600..8f8bdb10a8e9d 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -23,8 +23,6 @@ #include "udc_common.h" -#include "stm32_hsem.h" - #include LOG_MODULE_REGISTER(udc_stm32, CONFIG_UDC_DRIVER_LOG_LEVEL); @@ -50,6 +48,8 @@ struct udc_stm32_data { void (*pcd_prepare)(const struct device *dev); int (*clk_enable)(void); int (*clk_disable)(void); + struct k_thread thread_data; + struct k_msgq msgq_data; }; struct udc_stm32_config { @@ -58,16 +58,29 @@ struct udc_stm32_config { uint32_t dram_size; uint16_t ep0_mps; uint16_t ep_mps; + int speed_idx; +}; + +enum udc_stm32_msg_type { + UDC_STM32_MSG_SETUP, + UDC_STM32_MSG_DATA_OUT, + UDC_STM32_MSG_DATA_IN, +}; + +struct udc_stm32_msg { + uint8_t type; + uint8_t ep; + uint16_t rx_count; }; -static int udc_stm32_lock(const struct device *dev) +static void udc_stm32_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_stm32_unlock(const struct device *dev) +static void udc_stm32_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } #define hpcd2data(hpcd) CONTAINER_OF(hpcd, struct udc_stm32_data, pcd); @@ -125,6 +138,26 @@ void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) udc_submit_event(priv->dev, UDC_EVT_RESUME, 0); } +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + struct udc_stm32_data *priv = hpcd2data(hpcd); + struct udc_stm32_msg msg = {.type = UDC_STM32_MSG_SETUP}; + int err; + + err = k_msgq_put(&priv->msgq_data, &msg, K_NO_WAIT); + + if (err < 0) { + LOG_ERR("UDC Message queue overrun"); + } +} + +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + struct udc_stm32_data *priv = hpcd2data(hpcd); + + udc_submit_event(priv->dev, UDC_EVT_SOF, 0); +} + static int usbd_ctrl_feed_dout(const struct device *dev, const size_t length) { struct udc_stm32_data *priv = udc_get_private(dev); @@ -143,55 +176,12 @@ static int usbd_ctrl_feed_dout(const struct device *dev, const size_t length) return 0; } -void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +static void udc_stm32_flush_tx_fifo(const struct device *dev) { - struct udc_stm32_data *priv = hpcd2data(hpcd); - struct usb_setup_packet *setup = (void *)priv->pcd.Setup; - const struct device *dev = priv->dev; - struct net_buf *buf; - int err; - - buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, - sizeof(struct usb_setup_packet)); - if (buf == NULL) { - LOG_ERR("Failed to allocate for setup"); - return; - } - - udc_ep_buf_set_setup(buf); - memcpy(buf->data, setup, 8); - net_buf_add(buf, 8); - - udc_ctrl_update_stage(dev, buf); - - if (!buf->len) { - return; - } - - if ((setup->bmRequestType == 0) && - (setup->bRequest == USB_SREQ_SET_ADDRESS)) { - /* HAL requires we set the address before submitting status */ - HAL_PCD_SetAddress(&priv->pcd, setup->wValue); - } - - if (udc_ctrl_stage_is_data_out(dev)) { - /* Allocate and feed buffer for data OUT stage */ - err = usbd_ctrl_feed_dout(dev, udc_data_stage_length(buf)); - if (err == -ENOMEM) { - udc_submit_ep_event(dev, buf, err); - } - } else if (udc_ctrl_stage_is_data_in(dev)) { - udc_ctrl_submit_s_in_status(dev); - } else { - udc_ctrl_submit_s_status(dev); - } -} - -void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) -{ - struct udc_stm32_data *priv = hpcd2data(hpcd); + struct udc_stm32_data *priv = udc_get_private(dev); + struct udc_ep_config *cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); - udc_submit_event(priv->dev, UDC_EVT_SOF, 0); + HAL_PCD_EP_Receive(&priv->pcd, cfg->addr, NULL, 0); } static int udc_stm32_tx(const struct device *dev, uint8_t ep, @@ -230,7 +220,11 @@ static int udc_stm32_tx(const struct device *dev, uint8_t ep, /* Wait for an empty package from the host. * This also flushes the TX FIFO to the host. */ - usbd_ctrl_feed_dout(dev, 0); + if (DT_HAS_COMPAT_STATUS_OKAY(st_stm32_usb)) { + udc_stm32_flush_tx_fifo(dev); + } else { + usbd_ctrl_feed_dout(dev, 0); + } } return 0; @@ -263,6 +257,36 @@ void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { uint32_t rx_count = HAL_PCD_EP_GetRxCount(hpcd, epnum); struct udc_stm32_data *priv = hpcd2data(hpcd); + struct udc_stm32_msg msg = { + .type = UDC_STM32_MSG_DATA_OUT, + .ep = epnum, + .rx_count = rx_count, + }; + int err; + + err = k_msgq_put(&priv->msgq_data, &msg, K_NO_WAIT); + if (err != 0) { + LOG_ERR("UDC Message queue overrun"); + } +} + +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + struct udc_stm32_data *priv = hpcd2data(hpcd); + struct udc_stm32_msg msg = { + .type = UDC_STM32_MSG_DATA_IN, + .ep = epnum, + }; + int err; + + err = k_msgq_put(&priv->msgq_data, &msg, K_NO_WAIT); + if (err != 0) { + LOG_ERR("UDC Message queue overrun"); + } +} + +static void handle_msg_data_out(struct udc_stm32_data *priv, uint8_t epnum, uint16_t rx_count) +{ const struct device *dev = priv->dev; uint8_t ep = epnum | USB_EP_DIR_OUT; struct net_buf *buf; @@ -300,9 +324,8 @@ void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) } } -void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +static void handle_msg_data_in(struct udc_stm32_data *priv, uint8_t epnum) { - struct udc_stm32_data *priv = hpcd2data(hpcd); const struct device *dev = priv->dev; uint8_t ep = epnum | USB_EP_DIR_IN; struct net_buf *buf; @@ -366,6 +389,69 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) } } +static void handle_msg_setup(struct udc_stm32_data *priv) +{ + struct usb_setup_packet *setup = (void *)priv->pcd.Setup; + const struct device *dev = priv->dev; + struct net_buf *buf; + int err; + + buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, sizeof(struct usb_setup_packet)); + if (buf == NULL) { + LOG_ERR("Failed to allocate for setup"); + return; + } + + udc_ep_buf_set_setup(buf); + memcpy(buf->data, setup, 8); + net_buf_add(buf, 8); + + udc_ctrl_update_stage(dev, buf); + + if (!buf->len) { + return; + } + + if ((setup->bmRequestType == 0) && (setup->bRequest == USB_SREQ_SET_ADDRESS)) { + /* HAL requires we set the address before submitting status */ + HAL_PCD_SetAddress(&priv->pcd, setup->wValue); + } + + if (udc_ctrl_stage_is_data_out(dev)) { + /* Allocate and feed buffer for data OUT stage */ + err = usbd_ctrl_feed_dout(dev, udc_data_stage_length(buf)); + if (err == -ENOMEM) { + udc_submit_ep_event(dev, buf, err); + } + } else if (udc_ctrl_stage_is_data_in(dev)) { + udc_ctrl_submit_s_in_status(dev); + } else { + udc_ctrl_submit_s_status(dev); + } +} + +static void udc_stm32_thread_handler(void *arg1, void *arg2, void *arg3) +{ + const struct device *dev = arg1; + struct udc_stm32_data *priv = udc_get_private(dev); + struct udc_stm32_msg msg; + + while (true) { + k_msgq_get(&priv->msgq_data, &msg, K_FOREVER); + switch (msg.type) { + case UDC_STM32_MSG_SETUP: + handle_msg_setup(priv); + break; + case UDC_STM32_MSG_DATA_IN: + handle_msg_data_in(priv, msg.ep); + break; + case UDC_STM32_MSG_DATA_OUT: + handle_msg_data_out(priv, msg.ep, msg.rx_count); + break; + } + } +} + #if DT_INST_NODE_HAS_PROP(0, disconnect_gpios) void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) { @@ -460,9 +546,9 @@ static void udc_stm32_mem_init(const struct device *dev) } /* The documentation is not clear at all about RX FiFo size requirement, - * Allocate a minimum of 0x40 words, which seems to work reliably. + * 160 has been selected through trial and error. */ - words = MAX(0x40, cfg->ep_mps / 4); + words = MAX(160, cfg->ep_mps / 4); HAL_PCDEx_SetRxFiFo(&priv->pcd, words); priv->occupied_mem = words * 4; @@ -875,6 +961,7 @@ static const struct udc_stm32_config udc0_cfg = { .pma_offset = USB_BTABLE_SIZE, .ep0_mps = EP0_MPS, .ep_mps = EP_MPS, + .speed_idx = DT_ENUM_IDX_OR(DT_DRV_INST(0), maximum_speed, 1), }; #if defined(USB_OTG_FS) || defined(USB_OTG_HS) @@ -1029,7 +1116,7 @@ static int priv_clock_enable(void) return -EIO; } - if (IS_ENABLED(CONFIG_USB_DC_STM32_CLOCK_CHECK)) { + if (IS_ENABLED(CONFIG_UDC_STM32_CLOCK_CHECK)) { uint32_t usb_clock_rate; if (clock_control_get_rate(clk, @@ -1116,6 +1203,10 @@ static const struct gpio_dt_spec ulpi_reset = GPIO_DT_SPEC_GET_OR(DT_PHANDLE(DT_INST(0, st_stm32_otghs), phys), reset_gpios, {0}); #endif +static char udc_msgq_buf_0[CONFIG_UDC_STM32_MAX_QMESSAGES * sizeof(struct udc_stm32_msg)]; + +K_THREAD_STACK_DEFINE(udc_stm32_stack_0, CONFIG_UDC_STM32_STACK_SIZE); + static int udc_stm32_driver_init0(const struct device *dev) { struct udc_stm32_data *priv = udc_get_private(dev); @@ -1166,6 +1257,9 @@ static int udc_stm32_driver_init0(const struct device *dev) data->caps.rwup = true; data->caps.out_ack = false; data->caps.mps0 = UDC_MPS0_64; + if (cfg->speed_idx == 2) { + data->caps.hs = true; + } priv->dev = dev; priv->irq = UDC_STM32_IRQ; @@ -1173,6 +1267,15 @@ static int udc_stm32_driver_init0(const struct device *dev) priv->clk_disable = priv_clock_disable; priv->pcd_prepare = priv_pcd_prepare; + k_msgq_init(&priv->msgq_data, udc_msgq_buf_0, sizeof(struct udc_stm32_msg), + CONFIG_UDC_STM32_MAX_QMESSAGES); + + k_thread_create(&priv->thread_data, udc_stm32_stack_0, + K_THREAD_STACK_SIZEOF(udc_stm32_stack_0), udc_stm32_thread_handler, + (void *)dev, NULL, NULL, K_PRIO_COOP(CONFIG_UDC_STM32_THREAD_PRIORITY), + K_ESSENTIAL, K_NO_WAIT); + k_thread_name_set(&priv->thread_data, dev->name); + IRQ_CONNECT(UDC_STM32_IRQ, UDC_STM32_IRQ_PRI, udc_stm32_irq, DEVICE_DT_INST_GET(0), 0); diff --git a/drivers/usb/udc/udc_virtual.c b/drivers/usb/udc/udc_virtual.c index cc21649ad672e..c729aa08cd753 100644 --- a/drivers/usb/udc/udc_virtual.c +++ b/drivers/usb/udc/udc_virtual.c @@ -612,14 +612,14 @@ static int udc_vrt_driver_preinit(const struct device *dev) return 0; } -static int udc_vrt_lock(const struct device *dev) +static void udc_vrt_lock(const struct device *dev) { - return udc_lock_internal(dev, K_FOREVER); + udc_lock_internal(dev, K_FOREVER); } -static int udc_vrt_unlock(const struct device *dev) +static void udc_vrt_unlock(const struct device *dev) { - return udc_unlock_internal(dev); + udc_unlock_internal(dev); } static const struct udc_api udc_vrt_api = { diff --git a/drivers/usb/uhc/uhc_common.c b/drivers/usb/uhc/uhc_common.c index 15377500a664d..097d4a01457e0 100644 --- a/drivers/usb/uhc/uhc_common.c +++ b/drivers/usb/uhc/uhc_common.c @@ -92,16 +92,15 @@ void uhc_xfer_buf_free(const struct device *dev, struct net_buf *const buf) } struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, - const uint8_t addr, const uint8_t ep, - const uint8_t attrib, - const uint16_t mps, - const uint16_t timeout, - void *const udev, - void *const cb) + struct usb_device *const udev, + void *const cb, + void *const cb_priv) { + uint8_t ep_idx = USB_EP_GET_IDX(ep) & 0xF; const struct uhc_api *api = dev->api; struct uhc_transfer *xfer = NULL; + uint16_t mps; api->lock(dev); @@ -109,8 +108,26 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, goto xfer_alloc_error; } - LOG_DBG("Allocate xfer, ep 0x%02x attrib 0x%02x cb %p", - ep, attrib, cb); + if (ep_idx == 0) { + mps = udev->dev_desc.bMaxPacketSize0; + } else { + struct usb_ep_descriptor *ep_desc; + + if (USB_EP_DIR_IS_IN(ep)) { + ep_desc = udev->ep_in[ep_idx].desc; + } else { + ep_desc = udev->ep_out[ep_idx].desc; + } + + if (ep_desc == NULL) { + LOG_ERR("Endpoint 0x%02x is not configured", ep); + goto xfer_alloc_error; + } + + mps = ep_desc->wMaxPacketSize; + } + + LOG_DBG("Allocate xfer, ep 0x%02x mps %u cb %p", ep, mps, cb); if (k_mem_slab_alloc(&uhc_xfer_pool, (void **)&xfer, K_NO_WAIT)) { LOG_ERR("Failed to allocate transfer"); @@ -118,13 +135,11 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, } memset(xfer, 0, sizeof(struct uhc_transfer)); - xfer->addr = addr; xfer->ep = ep; - xfer->attrib = attrib; xfer->mps = mps; - xfer->timeout = timeout; xfer->udev = udev; xfer->cb = cb; + xfer->priv = cb_priv; xfer_alloc_error: api->unlock(dev); @@ -133,13 +148,10 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, } struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev, - const uint8_t addr, const uint8_t ep, - const uint8_t attrib, - const uint16_t mps, - const uint16_t timeout, - void *const udev, + struct usb_device *const udev, void *const cb, + void *const cb_priv, size_t size) { struct uhc_transfer *xfer; @@ -150,7 +162,7 @@ struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev, return NULL; } - xfer = uhc_xfer_alloc(dev, addr, ep, attrib, mps, timeout, udev, cb); + xfer = uhc_xfer_alloc(dev, ep, udev, cb, cb_priv); if (xfer == NULL) { net_buf_unref(buf); return NULL; @@ -298,7 +310,8 @@ int uhc_disable(const struct device *dev) return ret; } -int uhc_init(const struct device *dev, uhc_event_cb_t event_cb) +int uhc_init(const struct device *dev, + uhc_event_cb_t event_cb, const void *const event_ctx) { const struct uhc_api *api = dev->api; struct uhc_data *data = dev->data; @@ -316,6 +329,7 @@ int uhc_init(const struct device *dev, uhc_event_cb_t event_cb) } data->event_cb = event_cb; + data->event_ctx = event_ctx; sys_dlist_init(&data->ctrl_xfers); sys_dlist_init(&data->bulk_xfers); diff --git a/drivers/usb/uhc/uhc_max3421e.c b/drivers/usb/uhc/uhc_max3421e.c index ac9aa2a526dff..64a6e167cbf26 100644 --- a/drivers/usb/uhc/uhc_max3421e.c +++ b/drivers/usb/uhc/uhc_max3421e.c @@ -377,12 +377,14 @@ static int max3421e_xfer_bulk(const struct device *dev, static int max3421e_schedule_xfer(const struct device *dev) { struct max3421e_data *priv = uhc_get_private(dev); - const uint8_t hirq = priv->hirq; - const uint8_t hrsl = priv->hrsl; + uint8_t hrsl = priv->hrsl; if (priv->last_xfer == NULL) { int ret; + /* Do not restart last transfer */ + hrsl = 0; + priv->last_xfer = uhc_xfer_get_next(dev); if (priv->last_xfer == NULL) { LOG_DBG("Nothing to transfer"); @@ -390,20 +392,12 @@ static int max3421e_schedule_xfer(const struct device *dev) } LOG_DBG("Next transfer %p", priv->last_xfer); - ret = max3421e_peraddr(dev, priv->last_xfer->addr); + ret = max3421e_peraddr(dev, priv->last_xfer->udev->addr); if (ret) { return ret; } } - if (hirq & MAX3421E_FRAME) { - if (priv->last_xfer->timeout) { - priv->last_xfer->timeout--; - } else { - LOG_INF("Transfer timeout"); - } - } - /* * TODO: currently we only support control transfers and * treat all others as bulk. @@ -425,6 +419,23 @@ static void max3421e_xfer_drop_active(const struct device *dev, int err) } } +static void max3421e_xfer_cleanup_cancelled(const struct device *dev) +{ + struct max3421e_data *priv = uhc_get_private(dev); + struct uhc_data *data = dev->data; + struct uhc_transfer *tmp; + + if (priv->last_xfer != NULL && priv->last_xfer->err == -ECONNRESET) { + max3421e_xfer_drop_active(dev, -ECONNRESET); + } + + SYS_DLIST_FOR_EACH_CONTAINER(&data->ctrl_xfers, tmp, node) { + if (tmp->err == -ECONNRESET) { + uhc_xfer_return(dev, tmp, -ECONNRESET); + } + } +} + static int max3421e_hrslt_success(const struct device *dev) { struct max3421e_data *priv = uhc_get_private(dev); @@ -527,17 +538,6 @@ static int max3421e_handle_hxfrdn(const struct device *dev) switch (MAX3421E_HRSLT(hrsl)) { case MAX3421E_HR_NAK: - /* - * The transfer did not take place within - * the specified number of frames. - * - * TODO: Transfer cancel request (xfer->cancel) - * can be handled here as well. - */ - if (xfer->timeout == 0) { - max3421e_xfer_drop_active(dev, -ETIMEDOUT); - } - break; case MAX3421E_HR_STALL: max3421e_xfer_drop_active(dev, -EPIPE); @@ -682,7 +682,9 @@ static void uhc_max3421e_thread(void *p1, void *p2, void *p3) /* Host Transfer Done Interrupt */ if (priv->hirq & MAX3421E_HXFRDN) { err = max3421e_handle_hxfrdn(dev); - schedule = true; + if (unlikely(err)) { + uhc_submit_event(dev, UHC_EVT_ERROR, err); + } } /* Frame Generator Interrupt */ @@ -704,6 +706,8 @@ static void uhc_max3421e_thread(void *p1, void *p2, void *p3) uhc_submit_event(dev, UHC_EVT_ERROR, err); } + max3421e_xfer_cleanup_cancelled(dev); + if (schedule) { err = max3421e_schedule_xfer(dev); if (unlikely(err)) { @@ -797,7 +801,19 @@ static int max3421e_enqueue(const struct device *dev, static int max3421e_dequeue(const struct device *dev, struct uhc_transfer *const xfer) { - /* TODO */ + struct uhc_data *data = dev->data; + struct uhc_transfer *tmp; + unsigned int key; + + key = irq_lock(); + SYS_DLIST_FOR_EACH_CONTAINER(&data->ctrl_xfers, tmp, node) { + if (xfer == tmp) { + tmp->err = -ECONNRESET; + } + } + + irq_unlock(key); + return 0; } diff --git a/drivers/usb/uhc/uhc_virtual.c b/drivers/usb/uhc/uhc_virtual.c index 9e33f75557391..c582cfe1e7a27 100644 --- a/drivers/usb/uhc/uhc_virtual.c +++ b/drivers/usb/uhc/uhc_virtual.c @@ -24,23 +24,36 @@ #include LOG_MODULE_REGISTER(uhc_vrt, CONFIG_UHC_DRIVER_LOG_LEVEL); +#define FRAME_MAX_TRANSFERS 16 + struct uhc_vrt_config { }; +struct uhc_vrt_slot { + sys_dnode_t node; + struct uhc_transfer *xfer; +}; + +struct uhc_vrt_frame { + struct uhc_vrt_slot slots[FRAME_MAX_TRANSFERS]; + sys_dnode_t *ptr; + sys_dlist_t list; + uint8_t count; +}; + struct uhc_vrt_data { const struct device *dev; struct uvb_node *host_node; struct k_work work; struct k_fifo fifo; struct uhc_transfer *last_xfer; + struct uhc_vrt_frame frame; struct k_timer sof_timer; - bool busy; + uint16_t frame_number; uint8_t req; }; enum uhc_vrt_event_type { - /* Trigger next transfer */ - UHC_VRT_EVT_XFER, /* SoF generator event */ UHC_VRT_EVT_SOF, /* Request reply received */ @@ -86,7 +99,7 @@ static int vrt_xfer_control(const struct device *dev, if (xfer->stage == UHC_CONTROL_STAGE_SETUP) { LOG_DBG("Handle SETUP stage"); uvb_pkt = uvb_alloc_pkt(UVB_REQUEST_SETUP, - xfer->addr, USB_CONTROL_EP_OUT, + xfer->udev->addr, USB_CONTROL_EP_OUT, xfer->setup_pkt, sizeof(xfer->setup_pkt)); if (uvb_pkt == NULL) { LOG_ERR("Failed to allocate UVB packet"); @@ -94,7 +107,6 @@ static int vrt_xfer_control(const struct device *dev, } priv->req = UVB_REQUEST_SETUP; - priv->busy = true; return uvb_advert_pkt(priv->host_node, uvb_pkt); } @@ -110,7 +122,7 @@ static int vrt_xfer_control(const struct device *dev, LOG_DBG("Handle DATA stage"); uvb_pkt = uvb_alloc_pkt(UVB_REQUEST_DATA, - xfer->addr, xfer->ep, + xfer->udev->addr, xfer->ep, data, length); if (uvb_pkt == NULL) { LOG_ERR("Failed to allocate UVB packet"); @@ -118,7 +130,6 @@ static int vrt_xfer_control(const struct device *dev, } priv->req = UVB_REQUEST_DATA; - priv->busy = true; return uvb_advert_pkt(priv->host_node, uvb_pkt); } @@ -134,7 +145,7 @@ static int vrt_xfer_control(const struct device *dev, } uvb_pkt = uvb_alloc_pkt(UVB_REQUEST_DATA, - xfer->addr, ep, + xfer->udev->addr, ep, NULL, 0); if (uvb_pkt == NULL) { LOG_ERR("Failed to allocate UVB packet"); @@ -142,7 +153,6 @@ static int vrt_xfer_control(const struct device *dev, } priv->req = UVB_REQUEST_DATA; - priv->busy = true; return uvb_advert_pkt(priv->host_node, uvb_pkt); } @@ -167,7 +177,7 @@ static int vrt_xfer_bulk(const struct device *dev, data = buf->data; } - uvb_pkt = uvb_alloc_pkt(UVB_REQUEST_DATA, xfer->addr, xfer->ep, + uvb_pkt = uvb_alloc_pkt(UVB_REQUEST_DATA, xfer->udev->addr, xfer->ep, data, length); if (uvb_pkt == NULL) { LOG_ERR("Failed to allocate UVB packet"); @@ -177,25 +187,97 @@ static int vrt_xfer_bulk(const struct device *dev, return uvb_advert_pkt(priv->host_node, uvb_pkt); } -static int vrt_schedule_xfer(const struct device *dev) +static inline uint8_t get_xfer_ep_idx(const uint8_t ep) { - struct uhc_vrt_data *priv = uhc_get_private(dev); + /* We do not need to differentiate the direction for the control + * transfers because they are handled as a whole. + */ + if (USB_EP_DIR_IS_OUT(ep) || USB_EP_GET_IDX(ep) == 0) { + return USB_EP_GET_IDX(ep & BIT_MASK(4)); + } + + return USB_EP_GET_IDX(ep & BIT_MASK(4)) + 16U; +} + +static void vrt_assemble_frame(const struct device *dev) +{ + struct uhc_vrt_data *const priv = uhc_get_private(dev); + struct uhc_vrt_frame *const frame = &priv->frame; + struct uhc_data *const data = dev->data; + struct uhc_transfer *tmp; + unsigned int n = 0; + unsigned int key; + uint32_t bm = 0; + + sys_dlist_init(&frame->list); + frame->ptr = NULL; + frame->count = 0; + key = irq_lock(); + + /* TODO: add periodic transfers up to 90% */ + SYS_DLIST_FOR_EACH_CONTAINER(&data->ctrl_xfers, tmp, node) { + uint8_t idx = get_xfer_ep_idx(tmp->ep); + + /* There could be multiple transfers queued for the same + * endpoint, for now we only allow one to be scheduled per frame. + */ + if (bm & BIT(idx)) { + continue; + } + + if (tmp->interval) { + if (tmp->start_frame != priv->frame_number) { + continue; + } + + tmp->start_frame = priv->frame_number + tmp->interval; + LOG_DBG("Interrupt transfer s.f. %u f.n. %u interval %u", + tmp->start_frame, priv->frame_number, tmp->interval); + } + + bm |= BIT(idx); + frame->slots[n].xfer = tmp; + sys_dlist_append(&frame->list, &frame->slots[n].node); + n++; + + if (n >= FRAME_MAX_TRANSFERS) { + /* No more free slots */ + break; + } + } + + irq_unlock(key); +} + +static int vrt_schedule_frame(const struct device *dev) +{ + struct uhc_vrt_data *const priv = uhc_get_private(dev); + struct uhc_vrt_frame *const frame = &priv->frame; + struct uhc_vrt_slot *slot; if (priv->last_xfer == NULL) { - priv->last_xfer = uhc_xfer_get_next(dev); - if (priv->last_xfer == NULL) { - LOG_DBG("Nothing to transfer"); + if (frame->count >= FRAME_MAX_TRANSFERS) { + LOG_DBG("Frame finished"); + return 0; + } + + frame->ptr = sys_dlist_get(&frame->list); + slot = SYS_DLIST_CONTAINER(frame->ptr, slot, node); + if (slot == NULL) { + LOG_DBG("No more transfers for the frame"); return 0; } - LOG_DBG("Next transfer is %p", priv->last_xfer); + priv->last_xfer = slot->xfer; + frame->count++; + LOG_DBG("Next transfer is %p (count %u)", + (void *)priv->last_xfer, frame->count); } if (USB_EP_GET_IDX(priv->last_xfer->ep) == 0) { return vrt_xfer_control(dev, priv->last_xfer); } - /* TODO: Isochronous transfers */ return vrt_xfer_bulk(dev, priv->last_xfer); } @@ -276,6 +358,7 @@ static int vrt_handle_reply(const struct device *dev, struct uvb_packet *const pkt) { struct uhc_vrt_data *priv = uhc_get_private(dev); + struct uhc_vrt_frame *const frame = &priv->frame; struct uhc_transfer *const xfer = priv->last_xfer; int ret = 0; @@ -285,11 +368,12 @@ static int vrt_handle_reply(const struct device *dev, goto handle_reply_err; } - priv->busy = false; - switch (pkt->reply) { case UVB_REPLY_NACK: - /* Restart last transaction */ + /* Move the transfer back to the list. */ + sys_dlist_append(&frame->list, frame->ptr); + priv->last_xfer = NULL; + LOG_DBG("NACK 0x%02x count %u", xfer->ep, frame->count); break; case UVB_REPLY_STALL: vrt_xfer_drop_active(dev, -EPIPE); @@ -308,6 +392,23 @@ static int vrt_handle_reply(const struct device *dev, return ret; } +static void vrt_xfer_cleanup_cancelled(const struct device *dev) +{ + struct uhc_vrt_data *priv = uhc_get_private(dev); + struct uhc_data *data = dev->data; + struct uhc_transfer *tmp; + + if (priv->last_xfer != NULL && priv->last_xfer->err == -ECONNRESET) { + vrt_xfer_drop_active(dev, -ECONNRESET); + } + + SYS_DLIST_FOR_EACH_CONTAINER(&data->ctrl_xfers, tmp, node) { + if (tmp->err == -ECONNRESET) { + uhc_xfer_return(dev, tmp, -ECONNRESET); + } + } +} + static void xfer_work_handler(struct k_work *work) { struct uhc_vrt_data *priv = CONTAINER_OF(work, struct uhc_vrt_data, work); @@ -319,6 +420,12 @@ static void xfer_work_handler(struct k_work *work) int err; switch (ev->type) { + case UHC_VRT_EVT_SOF: + priv->frame_number++; + vrt_xfer_cleanup_cancelled(dev); + vrt_assemble_frame(dev); + schedule = true; + break; case UHC_VRT_EVT_REPLY: err = vrt_handle_reply(dev, ev->pkt); if (unlikely(err)) { @@ -327,30 +434,16 @@ static void xfer_work_handler(struct k_work *work) schedule = true; break; - case UHC_VRT_EVT_XFER: - LOG_DBG("Transfer triggered for %p", dev); - schedule = true; - break; - case UHC_VRT_EVT_SOF: - if (priv->last_xfer != NULL) { - if (priv->last_xfer->timeout) { - priv->last_xfer->timeout--; - } else { - vrt_xfer_drop_active(dev, -ETIMEDOUT); - priv->busy = false; - LOG_WRN("Transfer timeout"); - } - } - break; default: break; } - if (schedule && !priv->busy) { - err = vrt_schedule_xfer(dev); + if (schedule) { + err = vrt_schedule_frame(dev); if (unlikely(err)) { uhc_submit_event(dev, UHC_EVT_ERROR, err); } + } k_mem_slab_free(&uhc_vrt_slab, (void *)ev); @@ -367,6 +460,7 @@ static void sof_timer_handler(struct k_timer *timer) static void vrt_device_act(const struct device *dev, const enum uvb_device_act act) { + struct uhc_vrt_data *priv = uhc_get_private(dev); enum uhc_event_type type; switch (act) { @@ -375,9 +469,11 @@ static void vrt_device_act(const struct device *dev, break; case UVB_DEVICE_ACT_FS: type = UHC_EVT_DEV_CONNECTED_FS; + k_timer_start(&priv->sof_timer, K_MSEC(1), K_MSEC(1)); break; case UVB_DEVICE_ACT_HS: type = UHC_EVT_DEV_CONNECTED_HS; + k_timer_start(&priv->sof_timer, K_MSEC(1), K_USEC(125)); break; case UVB_DEVICE_ACT_REMOVED: type = UHC_EVT_DEV_REMOVED; @@ -406,7 +502,10 @@ static void uhc_vrt_uvb_cb(const void *const vrt_priv, static int uhc_vrt_sof_enable(const struct device *dev) { - /* TODO */ + struct uhc_vrt_data *priv = uhc_get_private(dev); + + k_timer_start(&priv->sof_timer, K_MSEC(1), K_MSEC(1)); + return 0; } @@ -423,17 +522,21 @@ static int uhc_vrt_bus_suspend(const struct device *dev) static int uhc_vrt_bus_reset(const struct device *dev) { struct uhc_vrt_data *priv = uhc_get_private(dev); + int ret; k_timer_stop(&priv->sof_timer); + ret = uvb_advert(priv->host_node, UVB_EVT_RESET, NULL); + /* TDRSTR */ + k_msleep(50); + k_timer_start(&priv->sof_timer, K_MSEC(1), K_MSEC(1)); - return uvb_advert(priv->host_node, UVB_EVT_RESET, NULL); + return ret; } static int uhc_vrt_bus_resume(const struct device *dev) { struct uhc_vrt_data *priv = uhc_get_private(dev); - k_timer_init(&priv->sof_timer, sof_timer_handler, NULL); k_timer_start(&priv->sof_timer, K_MSEC(1), K_MSEC(1)); return uvb_advert(priv->host_node, UVB_EVT_RESUME, NULL); @@ -442,8 +545,15 @@ static int uhc_vrt_bus_resume(const struct device *dev) static int uhc_vrt_enqueue(const struct device *dev, struct uhc_transfer *const xfer) { + struct uhc_vrt_data *priv = uhc_get_private(dev); + + if (xfer->interval) { + xfer->start_frame = priv->frame_number + xfer->interval; + LOG_DBG("New interrupt transfer s.f. %u f.n. %u interval %u", + xfer->start_frame, priv->frame_number, xfer->interval); + } + uhc_xfer_append(dev, xfer); - vrt_event_submit(dev, UHC_VRT_EVT_XFER, NULL); return 0; } @@ -451,7 +561,20 @@ static int uhc_vrt_enqueue(const struct device *dev, static int uhc_vrt_dequeue(const struct device *dev, struct uhc_transfer *const xfer) { - /* TODO */ + struct uhc_data *data = dev->data; + struct uhc_transfer *tmp; + unsigned int key; + + key = irq_lock(); + + SYS_DLIST_FOR_EACH_CONTAINER(&data->ctrl_xfers, tmp, node) { + if (xfer == tmp) { + tmp->err = -ECONNRESET; + } + } + + irq_unlock(key); + return 0; } diff --git a/drivers/usb_c/ppc/shell.c b/drivers/usb_c/ppc/shell.c index 09763e488f7f9..092f9e633b50a 100644 --- a/drivers/usb_c/ppc/shell.c +++ b/drivers/usb_c/ppc/shell.c @@ -10,7 +10,7 @@ /** Macro used to iterate over USB-C connector and call a function if the node has PPC property */ #define CALL_IF_HAS_PPC(usb_node, func) \ COND_CODE_1(DT_NODE_HAS_PROP(usb_node, ppc), \ - (ret |= func(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(usb_node, ppc, 0)));), ()) + (ret |= func(DEVICE_DT_GET_BY_IDX(usb_node, ppc, 0));), ()) /** * @brief Command that dumps registers of one or all of the PPCs @@ -27,7 +27,7 @@ static int cmd_ppc_dump(const struct shell *sh, size_t argc, char **argv) if (argc <= 1) { DT_FOREACH_STATUS_OKAY_VARGS(usb_c_connector, CALL_IF_HAS_PPC, ppc_dump_regs); } else { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); ret = ppc_dump_regs(dev); } @@ -66,7 +66,7 @@ static int cmd_ppc_status(const struct shell *sh, size_t argc, char **argv) if (argc <= 1) { DT_FOREACH_STATUS_OKAY_VARGS(usb_c_connector, CALL_IF_HAS_PPC, print_status); } else { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); ret = print_status(dev); } @@ -90,7 +90,7 @@ static int cmd_ppc_exit_db(const struct shell *sh, size_t argc, char **argv) DT_FOREACH_STATUS_OKAY_VARGS(usb_c_connector, CALL_IF_HAS_PPC, ppc_exit_dead_battery_mode); } else { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); ret = ppc_exit_dead_battery_mode(dev); } diff --git a/drivers/usb_c/tcpc/CMakeLists.txt b/drivers/usb_c/tcpc/CMakeLists.txt index 7bf2ff781c943..d1a428fceb078 100644 --- a/drivers/usb_c/tcpc/CMakeLists.txt +++ b/drivers/usb_c/tcpc/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_STM32 ucpd_stm32.c) zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_NUMAKER ucpd_numaker.c) zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_TCPCI tcpci.c) zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_PS8XXX ps8xxx.c) +zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_RT1715 rt1715.c) diff --git a/drivers/usb_c/tcpc/Kconfig b/drivers/usb_c/tcpc/Kconfig index b4fdd64f09083..3b1a9ccc2840a 100644 --- a/drivers/usb_c/tcpc/Kconfig +++ b/drivers/usb_c/tcpc/Kconfig @@ -29,6 +29,7 @@ source "drivers/usb_c/tcpc/Kconfig.tcpc_stm32" source "drivers/usb_c/tcpc/Kconfig.tcpc_numaker" source "drivers/usb_c/tcpc/Kconfig.tcpc_tcpci" source "drivers/usb_c/tcpc/Kconfig.tcpc_ps8xxx" +source "drivers/usb_c/tcpc/Kconfig.tcpc_rt1715" module = USBC module-str = usbc diff --git a/drivers/usb_c/tcpc/Kconfig.tcpc_rt1715 b/drivers/usb_c/tcpc/Kconfig.tcpc_rt1715 new file mode 100644 index 0000000000000..d61dfb3bad464 --- /dev/null +++ b/drivers/usb_c/tcpc/Kconfig.tcpc_rt1715 @@ -0,0 +1,28 @@ +# USB-C RT1715 TCPC configuration options + +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +config USBC_TCPC_RT1715 + bool "USB-C TCPC device controller driver" + select USBC_TCPC_TCPCI + default y + depends on DT_HAS_RICHTEK_RT1715_ENABLED + help + Enable USB-C TCPC support for the Richtek RT1715 + +if USBC_TCPC_RT1715 + +config USBC_TCPC_RT1715_INIT_DELAY + int "RT1715 init delay" + default 5 + help + Delay between each try of the TCPC initialization + +config USBC_TCPC_RT1715_INIT_RETRIES + int "RT1715 init retries" + default 10 + help + Number of initialization tries that will be performed + +endif diff --git a/drivers/usb_c/tcpc/ps8xxx.c b/drivers/usb_c/tcpc/ps8xxx.c index 70c1d229860f0..3373de3a0fdd8 100644 --- a/drivers/usb_c/tcpc/ps8xxx.c +++ b/drivers/usb_c/tcpc/ps8xxx.c @@ -67,18 +67,12 @@ struct ps8xxx_cfg { static int tcpci_init_alert_mask(const struct device *dev) { const struct ps8xxx_cfg *cfg = dev->config; - int ret; uint16_t mask = TCPC_REG_ALERT_TX_COMPLETE | TCPC_REG_ALERT_RX_STATUS | TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS | TCPC_REG_ALERT_FAULT | TCPC_REG_ALERT_POWER_STATUS; - ret = tcpci_write_reg16(&cfg->bus, TCPC_REG_ALERT_MASK, mask); - if (ret != 0) { - return ret; - } - - return 0; + return tcpci_tcpm_mask_status_register(&cfg->bus, TCPC_ALERT_STATUS, mask); } static int ps8xxx_tcpc_init(const struct device *dev) @@ -136,20 +130,14 @@ int ps8xxx_tcpc_select_rp_value(const struct device *dev, enum tc_rp_value rp) data->cc_changed = true; - return tcpci_update_reg8(&cfg->bus, TCPC_REG_ROLE_CTRL, TCPC_REG_ROLE_CTRL_RP_MASK, - TCPC_REG_ROLE_CTRL_SET(0, rp, 0, 0)); + return tcpci_tcpm_select_rp_value(&cfg->bus, rp); } int ps8xxx_tcpc_get_rp_value(const struct device *dev, enum tc_rp_value *rp) { const struct ps8xxx_cfg *cfg = dev->config; - uint8_t reg_value = 0; - int ret; - ret = tcpci_read_reg8(&cfg->bus, TCPC_REG_ROLE_CTRL, ®_value); - *rp = TCPC_REG_ROLE_CTRL_RP(reg_value); - - return ret; + return tcpci_tcpm_get_rp_value(&cfg->bus, rp); } int ps8xxx_tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull) @@ -163,9 +151,7 @@ int ps8xxx_tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull) data->cc_changed = true; - return tcpci_update_reg8(&cfg->bus, TCPC_REG_ROLE_CTRL, - TCPC_REG_ROLE_CTRL_CC1_MASK | TCPC_REG_ROLE_CTRL_CC2_MASK, - TCPC_REG_ROLE_CTRL_SET(0, 0, pull, pull)); + return tcpci_tcpm_set_cc(&cfg->bus, pull); } void ps8xxx_tcpc_set_vconn_discharge_cb(const struct device *dev, tcpc_vconn_discharge_cb_t cb) @@ -202,8 +188,7 @@ int ps8xxx_tcpc_set_vconn(const struct device *dev, bool enable) } data->cc_changed = true; - ret = tcpci_update_reg8(&cfg->bus, TCPC_REG_POWER_CTRL, TCPC_REG_POWER_CTRL_VCONN_EN, - enable ? TCPC_REG_POWER_CTRL_VCONN_EN : 0); + ret = tcpci_tcpm_set_vconn(&cfg->bus, enable); if (ret != 0) { return ret; @@ -221,8 +206,7 @@ int ps8xxx_tcpc_set_roles(const struct device *dev, enum tc_power_role power_rol { const struct ps8xxx_cfg *cfg = dev->config; - return tcpci_update_reg8(&cfg->bus, TCPC_REG_MSG_HDR_INFO, TCPC_REG_MSG_HDR_INFO_ROLES_MASK, - TCPC_REG_MSG_HDR_INFO_SET(PD_REV30, data_role, power_role)); + return tcpci_tcpm_set_roles(&cfg->bus, PD_REV30, power_role, data_role); } int ps8xxx_tcpc_get_rx_pending_msg(const struct device *dev, struct pd_msg *msg) @@ -263,7 +247,7 @@ int ps8xxx_tcpc_get_rx_pending_msg(const struct device *dev, struct pd_msg *msg) buf[1].len = 1; buf[1].flags = I2C_MSG_RESTART | I2C_MSG_READ; - buf[2].buf = &msg->type; + buf[2].buf = (uint8_t *)&msg->type; buf[2].len = 1; buf[2].flags = I2C_MSG_RESTART | I2C_MSG_READ; @@ -302,7 +286,7 @@ int ps8xxx_tcpc_set_rx_enable(const struct device *dev, bool enable) const struct ps8xxx_cfg *cfg = dev->config; int detect_sop_en = enable ? TCPC_REG_RX_DETECT_SOP_HRST_MASK : 0; - return tcpci_write_reg8(&cfg->bus, TCPC_REG_RX_DETECT, detect_sop_en); + return tcpci_tcpm_set_rx_type(&cfg->bus, detect_sop_en); } int ps8xxx_tcpc_set_cc_polarity(const struct device *dev, enum tc_cc_polarity polarity) @@ -315,9 +299,7 @@ int ps8xxx_tcpc_set_cc_polarity(const struct device *dev, enum tc_cc_polarity po return -EIO; } - ret = tcpci_update_reg8( - &cfg->bus, TCPC_REG_TCPC_CTRL, TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION, - (polarity == TC_POLARITY_CC1) ? 0 : TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION); + ret = tcpci_tcpm_set_cc_polarity(&cfg->bus, polarity); if (ret != 0) { return ret; @@ -332,90 +314,16 @@ int ps8xxx_tcpc_transmit_data(const struct device *dev, struct pd_msg *msg) { const struct ps8xxx_cfg *cfg = dev->config; - int reg = TCPC_REG_TX_BUFFER; - int rv; - int cnt = 4 * msg->header.number_of_data_objects; - - /* If not SOP* transmission, just write to the transmit register */ - if (msg->header.message_type >= NUM_SOP_STAR_TYPES) { - /* - * Per TCPCI spec, do not specify retry (although the TCPC - * should ignore retry field for these 3 types). - */ - return tcpci_write_reg8( - &cfg->bus, TCPC_REG_TRANSMIT, - TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(msg->header.message_type)); - } - - if (cnt > 0) { - reg = TCPC_REG_TX_BUFFER; - /* TX_BYTE_CNT includes extra bytes for message header */ - cnt += sizeof(msg->header.raw_value); - - struct i2c_msg buf[3]; - - uint8_t tmp[2] = {TCPC_REG_TX_BUFFER, cnt}; - - buf[0].buf = tmp; - buf[0].len = 2; - buf[0].flags = I2C_MSG_WRITE; - - buf[1].buf = (uint8_t *)&msg->header.raw_value; - buf[1].len = sizeof(msg->header.raw_value); - buf[1].flags = I2C_MSG_WRITE; - - buf[2].buf = (uint8_t *)msg->data; - buf[2].len = msg->len; - buf[2].flags = I2C_MSG_WRITE | I2C_MSG_STOP; - - if (cnt > sizeof(msg->header.raw_value)) { - rv = i2c_transfer(cfg->bus.bus, buf, 3, cfg->bus.addr); - } else { - buf[1].flags |= I2C_MSG_STOP; - rv = i2c_transfer(cfg->bus.bus, buf, 2, cfg->bus.addr); - } - - /* If tcpc write fails, return error */ - if (rv) { - return rv; - } - } - - /* - * We always retry in TCPC hardware since the TCPM is too slow to - * respond within tRetry (~195 usec). - * - * The retry count used is dependent on the maximum PD revision - * supported at build time. - */ - rv = tcpci_write_reg8(&cfg->bus, TCPC_REG_TRANSMIT, - TCPC_REG_TRANSMIT_SET_WITH_RETRY(cfg->transmit_retries, msg->type)); - - return rv; + return tcpci_tcpm_transmit_data(&cfg->bus, msg, cfg->transmit_retries); } int ps8xxx_tcpc_dump_std_reg(const struct device *dev) { const struct ps8xxx_cfg *cfg = dev->config; - uint16_t value; LOG_INF("TCPC %s:%s registers:", cfg->bus.bus->name, dev->name); - for (unsigned int a = 0; a < TCPCI_STD_REGS_SIZE; a++) { - switch (tcpci_std_regs[a].size) { - case 1: - tcpci_read_reg8(&cfg->bus, tcpci_std_regs[a].addr, (uint8_t *)&value); - LOG_INF("- %-30s(0x%02x) = 0x%02x", tcpci_std_regs[a].name, - tcpci_std_regs[a].addr, (uint8_t)value); - break; - case 2: - tcpci_read_reg16(&cfg->bus, tcpci_std_regs[a].addr, &value); - LOG_INF("- %-30s(0x%02x) = 0x%04x", tcpci_std_regs[a].name, - tcpci_std_regs[a].addr, value); - break; - } - } - return 0; + return tcpci_tcpm_dump_std_reg(&cfg->bus); } void ps8xxx_tcpc_alert_handler_cb(const struct device *dev, void *data, enum tcpc_alert alert) @@ -423,7 +331,7 @@ void ps8xxx_tcpc_alert_handler_cb(const struct device *dev, void *data, enum tcp } int ps8xxx_tcpc_get_status_register(const struct device *dev, enum tcpc_status_reg reg, - int32_t *status) + uint32_t *status) { return -ENOSYS; } @@ -490,9 +398,7 @@ int ps8xxx_tcpc_get_chip_info(const struct device *dev, struct tcpc_chip_info *c return -EIO; } - ret |= tcpci_read_reg16(&cfg->bus, TCPC_REG_VENDOR_ID, &chip_info->vendor_id); - ret |= tcpci_read_reg16(&cfg->bus, TCPC_REG_PRODUCT_ID, &chip_info->product_id); - ret |= tcpci_read_reg16(&cfg->bus, TCPC_REG_BCD_DEV, &chip_info->device_id); + ret = tcpci_tcpm_get_chip_info(&cfg->bus, chip_info); /* Vendor specific register for PS8815 model only */ if (chip_info->product_id == PS8815_PRODUCT_ID) { @@ -596,7 +502,7 @@ void ps8xxx_alert_work_cb(struct k_work *work) return; } - tcpci_read_reg16(&cfg->bus, TCPC_REG_ALERT, &alert_reg); + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_ALERT_STATUS, &alert_reg); while (alert_reg != 0) { enum tcpc_alert alert_type = tcpci_alert_reg_to_enum(alert_reg); @@ -608,30 +514,38 @@ void ps8xxx_alert_work_cb(struct k_work *work) } else if (alert_type == TCPC_ALERT_FAULT_STATUS) { uint8_t fault; - tcpci_read_reg8(&cfg->bus, TCPC_REG_FAULT_STATUS, &fault); - tcpci_write_reg8(&cfg->bus, TCPC_REG_FAULT_STATUS, fault); + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_FAULT_STATUS, + (uint16_t *)&fault); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_FAULT_STATUS, + (uint16_t)fault); LOG_DBG("PS8xxx fault: %02x", fault); } else if (alert_type == TCPC_ALERT_EXTENDED_STATUS) { uint8_t ext_status; - tcpci_read_reg8(&cfg->bus, TCPC_REG_EXT_STATUS, &ext_status); - tcpci_write_reg8(&cfg->bus, TCPC_REG_EXT_STATUS, ext_status); + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_EXTENDED_STATUS, + (uint16_t *)&ext_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_EXTENDED_STATUS, + (uint16_t)ext_status); data->cc_changed = true; LOG_DBG("PS8xxx ext status: %02x", ext_status); } else if (alert_type == TCPC_ALERT_POWER_STATUS) { uint8_t pwr_status; - tcpci_read_reg8(&cfg->bus, TCPC_REG_POWER_STATUS, &pwr_status); - tcpci_write_reg8(&cfg->bus, TCPC_REG_POWER_STATUS, pwr_status); + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_POWER_STATUS, + (uint16_t *)&pwr_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_POWER_STATUS, + (uint16_t)pwr_status); LOG_DBG("PS8xxx power status: %02x", pwr_status); } else if (alert_type == TCPC_ALERT_EXTENDED) { uint8_t alert_status; - tcpci_read_reg8(&cfg->bus, TCPC_REG_ALERT_EXT, &alert_status); - tcpci_write_reg8(&cfg->bus, TCPC_REG_ALERT_EXT, alert_status); + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_EXTENDED_ALERT_STATUS, + (uint16_t *)&alert_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_EXTENDED_ALERT_STATUS, + (uint16_t)alert_status); LOG_DBG("PS8xxx ext alert: %02x", alert_status); } else if (alert_type == TCPC_ALERT_MSG_STATUS) { @@ -641,16 +555,16 @@ void ps8xxx_alert_work_cb(struct k_work *work) } if (data->alert_handler != NULL) { - data->alert_handler(data->dev, data->alert_handler_data, alert_type); + data->alert_handler(dev, data->alert_handler_data, alert_type); } clear_flags |= BIT(alert_type); alert_reg &= ~BIT(alert_type); } - tcpci_write_reg16(&cfg->bus, TCPC_REG_ALERT, clear_flags); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_ALERT_STATUS, clear_flags); + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_ALERT_STATUS, &alert_reg); - tcpci_read_reg16(&cfg->bus, TCPC_REG_ALERT, &alert_reg); if (alert_reg != 0) { k_work_submit(work); } @@ -663,14 +577,12 @@ void ps8xxx_init_work_cb(struct k_work *work) const struct ps8xxx_cfg *cfg = data->dev->config; uint8_t power_reg = 0; - uint16_t idVendor = 0; - uint16_t idProduct = 0; - uint16_t idDevice = 0; - int res; + struct tcpc_chip_info chip_info; + int ret; LOG_INF("Initializing PS8xxx chip: %s", data->dev->name); - res = tcpci_read_reg8(&cfg->bus, TCPC_REG_POWER_STATUS, &power_reg); - if (res != 0 || (power_reg & TCPC_REG_POWER_STATUS_UNINIT)) { + ret = tcpci_tcpm_get_status_register(&cfg->bus, TCPC_POWER_STATUS, (uint16_t *)&power_reg); + if (ret != 0 || (power_reg & TCPC_REG_POWER_STATUS_UNINIT)) { data->init_retries++; if (data->init_retries > CONFIG_USBC_TCPC_PS8XXX_INIT_RETRIES) { @@ -679,16 +591,14 @@ void ps8xxx_init_work_cb(struct k_work *work) } LOG_DBG("Postpone chip initialization %d", data->init_retries); - k_work_schedule_for_queue(&k_sys_work_q, &data->init_dwork, - K_MSEC(CONFIG_USBC_TCPC_PS8XXX_INIT_DELAY)); + k_work_schedule(&data->init_dwork, K_MSEC(CONFIG_USBC_TCPC_PS8XXX_INIT_DELAY)); return; } - tcpci_read_reg16(&cfg->bus, TCPC_REG_VENDOR_ID, &idVendor); - tcpci_read_reg16(&cfg->bus, TCPC_REG_PRODUCT_ID, &idProduct); - tcpci_read_reg16(&cfg->bus, TCPC_REG_BCD_DEV, &idDevice); - LOG_INF("Initialized chip is: %04x:%04x:%04x", idVendor, idProduct, idDevice); + ps8xxx_tcpc_get_chip_info(data->dev, &chip_info); + LOG_INF("Initialized chip is: %04x:%04x:%04x", chip_info.vendor_id, chip_info.product_id, + chip_info.device_id); /* Initialize alert interrupt */ gpio_pin_configure_dt(&cfg->alert_gpio, GPIO_INPUT); @@ -718,8 +628,7 @@ static int ps8xxx_dev_init(const struct device *dev) } k_work_init_delayable(&data->init_dwork, ps8xxx_init_work_cb); - k_work_schedule_for_queue(&k_sys_work_q, &data->init_dwork, - K_MSEC(CONFIG_USBC_TCPC_PS8XXX_INIT_DELAY)); + k_work_schedule(&data->init_dwork, K_MSEC(CONFIG_USBC_TCPC_PS8XXX_INIT_DELAY)); k_work_init(&data->alert_work, ps8xxx_alert_work_cb); diff --git a/drivers/usb_c/tcpc/rt1715.c b/drivers/usb_c/tcpc/rt1715.c new file mode 100644 index 0000000000000..219850d43a485 --- /dev/null +++ b/drivers/usb_c/tcpc/rt1715.c @@ -0,0 +1,726 @@ +/* + * Copyright (c) 2024 Jianxiong Gu + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "rt1715.h" + +#define DT_DRV_COMPAT richtek_rt1715 +LOG_MODULE_REGISTER(rt1715, CONFIG_USBC_LOG_LEVEL); + +/** Data structure for device instances */ +struct rt1715_data { + /** Device structure used to retrieve it in k_work functions */ + const struct device *const dev; + /** Delayable work item for chip initialization */ + struct k_work_delayable init_dwork; + /** Initialization retries counter */ + int init_retries; + /** Boolean value if chip was successfully initialized */ + bool initialized; + + /** Callback for alert GPIO */ + struct gpio_callback alert_cb; + /** Work item for alert handling out of interrupt context */ + struct k_work alert_work; + + /** Boolean value if there is a message pending */ + bool msg_pending; + /** One-slot Rx FIFO */ + struct pd_msg rx_msg; + + /** Alert handler set by USB-C stack */ + tcpc_alert_handler_cb_t alert_handler; + /** Alert handler data set by USB-C stack */ + void *alert_handler_data; + + /** VCONN discharge callback set by USB-C stack */ + tcpc_vconn_discharge_cb_t vconn_discharge_cb; + /** VCONN discharge callback data set by USB-C stack */ + tcpc_vconn_control_cb_t vconn_cb; + /** Polarity of CC lines for PD and VCONN */ + enum tc_cc_polarity cc_polarity; + + /** Boolean value if there was a change on the CC lines since last check */ + bool cc_changed; + /** State of CC1 line */ + enum tc_cc_voltage_state cc1; + /** State of CC2 line */ + enum tc_cc_voltage_state cc2; + + /* Flag to receive or ignore SOP Prime messages */ + bool rx_sop_prime_enable; +}; + +/** Configuration structure for device instances */ +struct rt1715_cfg { + /** I2C bus and address used for communication */ + const struct i2c_dt_spec bus; + /** GPIO specification for alert pin */ + const struct gpio_dt_spec alert_gpio; + /** GPIO specification for VCONN power control pin */ + const struct gpio_dt_spec vconn_ctrl_gpio; + /** GPIO specification for VCONN discharge control pin */ + const struct gpio_dt_spec vconn_disc_gpio; + /** Maximum number of packet retransmissions done by TCPC */ + const uint8_t transmit_retries; +}; + +static int tcpci_init_alert_mask(const struct device *dev) +{ + const struct rt1715_cfg *cfg = dev->config; + + uint16_t mask = TCPC_REG_ALERT_TX_COMPLETE | TCPC_REG_ALERT_RX_STATUS | + TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS | + TCPC_REG_ALERT_POWER_STATUS | TCPC_REG_ALERT_FAULT | + TCPC_REG_ALERT_RX_BUF_OVF; + + return tcpci_tcpm_mask_status_register(&cfg->bus, TCPC_ALERT_STATUS, mask); +} + +static int rt1715_tcpc_init(const struct device *dev) +{ + struct rt1715_data *data = dev->data; + + if (!data->initialized) { + if (data->init_retries > CONFIG_USBC_TCPC_RT1715_INIT_RETRIES) { + LOG_ERR("TCPC was not initialized correctly"); + return -EIO; + } + + return -EAGAIN; + } + + data->rx_sop_prime_enable = false; + data->msg_pending = false; + memset(&data->rx_msg, 0x00, sizeof(data->rx_msg)); + + LOG_INF("RT1715 TCPC initialized"); + return 0; +} + +static int rt1715_tcpc_get_cc(const struct device *dev, enum tc_cc_voltage_state *cc1, + enum tc_cc_voltage_state *cc2) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + int ret; + + if (!data->initialized) { + return -EIO; + } + + if (IS_ENABLED(CONFIG_USBC_CSM_SINK_ONLY) && !data->cc_changed) { + *cc1 = data->cc1; + *cc2 = data->cc2; + + return 0; + } + + data->cc_changed = false; + + ret = tcpci_tcpm_get_cc(&cfg->bus, cc1, cc2); + + if (IS_ENABLED(CONFIG_USBC_CSM_SINK_ONLY) || *cc1 != data->cc1 || *cc2 != data->cc2) { + LOG_DBG("CC changed values: %d->%d, %d->%d", data->cc1, *cc1, data->cc2, *cc2); + data->cc1 = *cc1; + data->cc2 = *cc2; + } + + return ret; +} + +static int rt1715_tcpc_select_rp_value(const struct device *dev, enum tc_rp_value rp) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + + data->cc_changed = true; + + return tcpci_tcpm_select_rp_value(&cfg->bus, rp); +} + +static int rt1715_tcpc_get_rp_value(const struct device *dev, enum tc_rp_value *rp) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_get_rp_value(&cfg->bus, rp); +} + +static int rt1715_tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + + if (!data->initialized) { + return -EIO; + } + + data->cc_changed = true; + + return tcpci_tcpm_set_cc(&cfg->bus, pull); +} + +static void rt1715_tcpc_set_vconn_discharge_cb(const struct device *dev, + tcpc_vconn_discharge_cb_t cb) +{ + struct rt1715_data *data = dev->data; + + data->vconn_discharge_cb = cb; +} + +static void rt1715_tcpc_set_vconn_cb(const struct device *dev, tcpc_vconn_control_cb_t vconn_cb) +{ + struct rt1715_data *data = dev->data; + + data->vconn_cb = vconn_cb; +} + +static int rt1715_tcpc_vconn_discharge(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (cfg->vconn_disc_gpio.port == NULL) { + /* RT1715 does not have built-in VCONN discharge path */ + LOG_ERR("VCONN discharge GPIO is not defined"); + return -EIO; + } + + return gpio_pin_set_dt(&cfg->vconn_disc_gpio, enable); +} + +static int rt1715_tcpc_set_vconn(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + int ret; + + if (!data->initialized) { + return -EIO; + } + + if (enable == true && cfg->vconn_ctrl_gpio.port != NULL) { + /* Enable external VCONN power supply */ + gpio_pin_set_dt(&cfg->vconn_ctrl_gpio, true); + } + + data->cc_changed = true; + ret = tcpci_tcpm_set_vconn(&cfg->bus, enable); + + if (ret != 0) { + return ret; + } + + if (enable == false && cfg->vconn_ctrl_gpio.port != NULL) { + /* Disable external VCONN power supply */ + gpio_pin_set_dt(&cfg->vconn_ctrl_gpio, false); + } + + if (data->vconn_cb != NULL) { + ret = data->vconn_cb(dev, data->cc_polarity, enable); + } + + return ret; +} + +static int rt1715_tcpc_set_roles(const struct device *dev, enum tc_power_role power_role, + enum tc_data_role data_role) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_set_roles(&cfg->bus, PD_REV30, power_role, data_role); +} + +static int rt1715_tcpc_get_rx_pending_msg(const struct device *dev, struct pd_msg *msg) +{ + struct rt1715_data *data = dev->data; + + /* Rx message pending? */ + if (!data->msg_pending) { + return -ENODATA; + } + + /* Query status only? */ + if (msg == NULL) { + return 0; + } + + /* Dequeue Rx FIFO */ + *msg = data->rx_msg; + data->msg_pending = false; + + /* Indicate Rx message returned */ + return 1; +} + +static int rt1715_tcpc_rx_fifo_enqueue(const struct device *dev) +{ + const struct rt1715_cfg *const cfg = dev->config; + struct rt1715_data *data = dev->data; + struct i2c_msg buf[5]; + uint8_t reg = TCPC_REG_RX_BUFFER; + uint8_t rxbcnt; + uint8_t rxftype; + uint16_t rxhead; + uint8_t rx_data_size; + struct pd_msg *msg = &data->rx_msg; + int ret = 0; + + buf[0].buf = ® + buf[0].len = 1; + buf[0].flags = I2C_MSG_WRITE; + + buf[1].buf = &rxbcnt; + buf[1].len = 1; + buf[1].flags = I2C_MSG_RESTART | I2C_MSG_READ; + + buf[2].buf = &rxftype; + buf[2].len = 1; + buf[2].flags = I2C_MSG_RESTART | I2C_MSG_READ; + + buf[3].buf = (uint8_t *)&rxhead; + buf[3].len = 2; + buf[3].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP; + + ret = i2c_transfer(cfg->bus.bus, buf, 5, cfg->bus.addr); + if (ret != 0) { + return ret; + } + + /* rxbcnt = 1 (frame type) + 2 (Message Header) + Rx data byte count */ + if (rxbcnt < 3) { + LOG_ERR("Invalid RXBCNT: %d", rxbcnt); + return -EIO; + } + rx_data_size = rxbcnt - 3; + + /* Not support Unchunked Extended Message exceeding PD_CONVERT_PD_HEADER_COUNT_TO_BYTES */ + if (rx_data_size > (PD_MAX_EXTENDED_MSG_LEGACY_LEN + 2)) { + LOG_ERR("Not support Unchunked Extended Message exceeding " + "PD_CONVERT_PD_HEADER_COUNT_TO_BYTES: %d", + rx_data_size); + return -EIO; + } + + /* Rx frame type */ + msg->type = rxftype; + + /* Rx header */ + msg->header.raw_value = (uint16_t)rxhead; + + /* Rx data size */ + msg->len = rx_data_size; + + /* Rx data */ + if (rx_data_size > 0) { + ret = i2c_burst_read_dt(&cfg->bus, TCPC_REG_RX_BUFFER + 4, msg->data, rx_data_size); + if (ret) { + LOG_ERR("Failed to read Rx data: %d", ret); + } + } + + return ret; +} + +static int rt1715_tcpc_set_rx_enable(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + + if (!enable) { + return tcpci_tcpm_set_rx_type(&cfg->bus, 0); + } + + if (data->rx_sop_prime_enable) { + return tcpci_tcpm_set_rx_type(&cfg->bus, + TCPC_REG_RX_DETECT_SOP_SOPP_SOPPP_HRST_MASK); + } else { + return tcpci_tcpm_set_rx_type(&cfg->bus, TCPC_REG_RX_DETECT_SOP_HRST_MASK); + } +} + +static int rt1715_tcpc_set_cc_polarity(const struct device *dev, enum tc_cc_polarity polarity) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + int ret; + + if (!data->initialized) { + return -EIO; + } + + ret = tcpci_tcpm_set_cc_polarity(&cfg->bus, polarity); + + if (ret != 0) { + return ret; + } + + data->cc_changed = true; + data->cc_polarity = polarity; + return 0; +} + +static int rt1715_tcpc_transmit_data(const struct device *dev, struct pd_msg *msg) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_transmit_data(&cfg->bus, msg, cfg->transmit_retries); +} + +static int rt1715_tcpc_dump_std_reg(const struct device *dev) +{ + const struct rt1715_cfg *cfg = dev->config; + + LOG_INF("TCPC %s:%s registers:", cfg->bus.bus->name, dev->name); + + return tcpci_tcpm_dump_std_reg(&cfg->bus); +} + +void rt1715_tcpc_alert_handler_cb(const struct device *dev, void *data, enum tcpc_alert alert) +{ +} + +static int rt1715_tcpc_get_status_register(const struct device *dev, enum tcpc_status_reg reg, + uint32_t *status) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (reg == TCPC_VENDOR_DEFINED_STATUS) { + return tcpci_read_reg8(&cfg->bus, RT1715_REG_RT_INT, (uint8_t *)status); + } + + return tcpci_tcpm_get_status_register(&cfg->bus, reg, (uint16_t *)status); +} + +static int rt1715_tcpc_clear_status_register(const struct device *dev, enum tcpc_status_reg reg, + uint32_t mask) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (reg == TCPC_VENDOR_DEFINED_STATUS) { + return tcpci_write_reg8(&cfg->bus, RT1715_REG_RT_INT, (uint8_t)mask); + } + + return tcpci_tcpm_clear_status_register(&cfg->bus, reg, (uint16_t)mask); +} + +static int rt1715_tcpc_mask_status_register(const struct device *dev, enum tcpc_status_reg reg, + uint32_t mask) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (reg == TCPC_VENDOR_DEFINED_STATUS) { + return tcpci_write_reg8(&cfg->bus, RT1715_REG_RT_INT_MASK, (uint8_t)mask); + } + + return tcpci_tcpm_mask_status_register(&cfg->bus, reg, (uint16_t)mask); +} + +static int rt1715_tcpc_set_drp_toggle(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_set_drp_toggle(&cfg->bus, enable); +} + +static int rt1715_tcpc_get_chip_info(const struct device *dev, struct tcpc_chip_info *chip_info) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (chip_info == NULL) { + return -EIO; + } + + chip_info->fw_version_number = 0; + chip_info->min_req_fw_version_number = 0; + + return tcpci_tcpm_get_chip_info(&cfg->bus, chip_info); +} + +static int rt1715_tcpc_set_low_power_mode(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + int ret; + + ret = tcpci_write_reg8(&cfg->bus, RT1715_REG_SYS_WAKEUP, RT1715_REG_SYS_WAKEUP_EN); + if (ret < 0) { + return ret; + } + + return tcpci_update_reg8(&cfg->bus, RT1715_REG_SYS_CTRL_1, + RT1715_REG_SYS_CTRL_1_BMCIO_LP_EN, + enable ? RT1715_REG_SYS_CTRL_1_BMCIO_LP_EN : 0); +} + +static int rt1715_tcpc_sop_prime_enable(const struct device *dev, bool enable) +{ + struct rt1715_data *data = dev->data; + + data->rx_sop_prime_enable = enable; + + return 0; +} + +static int rt1715_tcpc_set_bist_test_mode(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_set_bist_test_mode(&cfg->bus, enable); +} + +static int rt1715_tcpc_set_alert_handler_cb(const struct device *dev, + tcpc_alert_handler_cb_t handler, void *handler_data) +{ + struct rt1715_data *data = dev->data; + + if (data->alert_handler == handler && data->alert_handler_data == handler_data) { + return 0; + } + + data->alert_handler = handler; + data->alert_handler_data = handler_data; + + return 0; +} + +static DEVICE_API(tcpc, rt1715_driver_api) = { + .init = rt1715_tcpc_init, + .get_cc = rt1715_tcpc_get_cc, + .select_rp_value = rt1715_tcpc_select_rp_value, + .get_rp_value = rt1715_tcpc_get_rp_value, + .set_cc = rt1715_tcpc_set_cc, + .set_vconn_discharge_cb = rt1715_tcpc_set_vconn_discharge_cb, + .set_vconn_cb = rt1715_tcpc_set_vconn_cb, + .vconn_discharge = rt1715_tcpc_vconn_discharge, + .set_vconn = rt1715_tcpc_set_vconn, + .set_roles = rt1715_tcpc_set_roles, + .get_rx_pending_msg = rt1715_tcpc_get_rx_pending_msg, + .set_rx_enable = rt1715_tcpc_set_rx_enable, + .set_cc_polarity = rt1715_tcpc_set_cc_polarity, + .transmit_data = rt1715_tcpc_transmit_data, + .dump_std_reg = rt1715_tcpc_dump_std_reg, + .alert_handler_cb = rt1715_tcpc_alert_handler_cb, + .get_status_register = rt1715_tcpc_get_status_register, + .clear_status_register = rt1715_tcpc_clear_status_register, + .mask_status_register = rt1715_tcpc_mask_status_register, + .set_drp_toggle = rt1715_tcpc_set_drp_toggle, + .get_chip_info = rt1715_tcpc_get_chip_info, + .set_low_power_mode = rt1715_tcpc_set_low_power_mode, + .sop_prime_enable = rt1715_tcpc_sop_prime_enable, + .set_bist_test_mode = rt1715_tcpc_set_bist_test_mode, + .set_alert_handler_cb = rt1715_tcpc_set_alert_handler_cb, +}; + +void rt1715_alert_cb(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins) +{ + struct rt1715_data *data = CONTAINER_OF(cb, struct rt1715_data, alert_cb); + + k_work_submit(&data->alert_work); +} + +void rt1715_alert_work_cb(struct k_work *work) +{ + struct rt1715_data *data = CONTAINER_OF(work, struct rt1715_data, alert_work); + const struct device *dev = data->dev; + const struct rt1715_cfg *cfg = dev->config; + uint16_t alert_reg = 0; + uint16_t clear_flags = 0; + + if (!data->initialized) { + return; + } + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_ALERT_STATUS, &alert_reg); + + while (alert_reg != 0) { + enum tcpc_alert alert_type = tcpci_alert_reg_to_enum(alert_reg); + + if (alert_type == TCPC_ALERT_HARD_RESET_RECEIVED) { + LOG_DBG("hard rst received"); + tcpci_init_alert_mask(dev); + data->cc_changed = true; + } else if (alert_type == TCPC_ALERT_FAULT_STATUS) { + uint8_t fault; + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_FAULT_STATUS, + (uint16_t *)&fault); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_FAULT_STATUS, + (uint16_t)fault); + + LOG_DBG("fault: %02x", fault); + } else if (alert_type == TCPC_ALERT_EXTENDED_STATUS) { + uint8_t ext_status; + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_EXTENDED_STATUS, + (uint16_t *)&ext_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_EXTENDED_STATUS, + (uint16_t)ext_status); + + data->cc_changed = true; + LOG_DBG("ext status: %02x", ext_status); + } else if (alert_type == TCPC_ALERT_POWER_STATUS) { + uint8_t pwr_status; + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_POWER_STATUS, + (uint16_t *)&pwr_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_POWER_STATUS, + (uint16_t)pwr_status); + + LOG_DBG("power status: %02x", pwr_status); + } else if (alert_type == TCPC_ALERT_EXTENDED) { + uint8_t alert_status; + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_EXTENDED_ALERT_STATUS, + (uint16_t *)&alert_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_EXTENDED_ALERT_STATUS, + (uint16_t)alert_status); + + LOG_DBG("ext alert: %02x", alert_status); + } else if (alert_type == TCPC_ALERT_MSG_STATUS) { + LOG_DBG("MSG pending"); + + if (rt1715_tcpc_rx_fifo_enqueue(dev) == 0) { + data->msg_pending = true; + } + } else if (alert_type == TCPC_ALERT_CC_STATUS) { + data->cc_changed = true; + } + + if (data->alert_handler != NULL) { + data->alert_handler(dev, data->alert_handler_data, alert_type); + } + + clear_flags |= BIT(alert_type); + alert_reg &= ~BIT(alert_type); + } + + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_ALERT_STATUS, clear_flags); + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_ALERT_STATUS, &alert_reg); + + /* If alert_reg is not 0 or the interrupt signal is still active */ + if ((alert_reg != 0) || gpio_pin_get_dt(&cfg->alert_gpio)) { + k_work_submit(work); + } +} + +void rt1715_init_work_cb(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct rt1715_data *data = CONTAINER_OF(dwork, struct rt1715_data, init_dwork); + + const struct rt1715_cfg *cfg = data->dev->config; + uint8_t power_reg, lp_reg = 0; + struct tcpc_chip_info chip_info; + int ret; + + LOG_INF("Initializing RT1715 chip: %s", data->dev->name); + + ret = tcpci_tcpm_get_status_register(&cfg->bus, TCPC_POWER_STATUS, (uint16_t *)&power_reg); + if (ret != 0 || (power_reg & TCPC_REG_POWER_STATUS_UNINIT)) { + data->init_retries++; + + if (data->init_retries > CONFIG_USBC_TCPC_RT1715_INIT_RETRIES) { + LOG_ERR("Chip didn't respond"); + return; + } + + LOG_DBG("Postpone chip initialization %d", data->init_retries); + k_work_schedule(&data->init_dwork, K_MSEC(CONFIG_USBC_TCPC_RT1715_INIT_DELAY)); + + return; + } + + rt1715_tcpc_get_chip_info(data->dev, &chip_info); + LOG_INF("Initialized chip is: %04x:%04x:%04x", chip_info.vendor_id, chip_info.product_id, + chip_info.device_id); + + /* Exit shutdown mode & Enable ext messages */ + lp_reg = RT1715_REG_LP_CTRL_SHUTDOWN_OFF | RT1715_REG_LP_CTRL_ENEXTMSG; + /* Disable idle mode */ + lp_reg &= ~RT1715_REG_LP_CTRL_AUTOIDLE_EN; + tcpci_write_reg8(&cfg->bus, RT1715_REG_LP_CTRL, lp_reg); + + /* Initialize alert interrupt */ + gpio_pin_configure_dt(&cfg->alert_gpio, GPIO_INPUT); + + gpio_init_callback(&data->alert_cb, rt1715_alert_cb, BIT(cfg->alert_gpio.pin)); + gpio_add_callback(cfg->alert_gpio.port, &data->alert_cb); + gpio_pin_interrupt_configure_dt(&cfg->alert_gpio, GPIO_INT_EDGE_TO_ACTIVE); + + tcpci_init_alert_mask(data->dev); + data->initialized = true; + + /* Disable the vconn and open CC lines to reinitialize the communication with partner */ + rt1715_tcpc_set_vconn(data->dev, false); + rt1715_tcpc_set_cc(data->dev, TC_CC_OPEN); + + /* Check and clear any alert set after initialization */ + k_work_submit(&data->alert_work); +} + +static int rt1715_dev_init(const struct device *dev) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + int ret; + + if (!device_is_ready(cfg->bus.bus)) { + return -EIO; + } + + /* Resets the chip */ + ret = tcpci_write_reg8(&cfg->bus, RT1715_REG_SW_RST, RT1715_REG_SW_RST_EN); + if (ret != 0) { + LOG_ERR("Failed to reset chip: %d", ret); + return ret; + } + + k_work_init_delayable(&data->init_dwork, rt1715_init_work_cb); + k_work_schedule(&data->init_dwork, K_MSEC(CONFIG_USBC_TCPC_RT1715_INIT_DELAY)); + + k_work_init(&data->alert_work, rt1715_alert_work_cb); + + return 0; +} + +#define RT1715_DRIVER_DATA_INIT(node) \ + { \ + .dev = DEVICE_DT_GET(node), \ + .init_retries = 0, \ + .cc_changed = true, \ + } + +#define VCONN_CTRL_GPIO(node) \ + .vconn_ctrl_gpio = COND_CODE_1(DT_INST_NODE_HAS_PROP(node, vconn_ctrl_gpios), \ + (GPIO_DT_SPEC_INST_GET(node, vconn_ctrl_gpios)), ({0})) + +#define VCONN_DISC_GPIO(node) \ + .vconn_disc_gpio = COND_CODE_1(DT_INST_NODE_HAS_PROP(node, vconn_disc_gpios), \ + (GPIO_DT_SPEC_INST_GET(node, vconn_disc_gpios)), ({0})) + +#define RT1715_DRIVER_CFG_INIT(node) \ + { \ + .bus = I2C_DT_SPEC_GET(node), \ + .alert_gpio = GPIO_DT_SPEC_GET(node, irq_gpios), \ + .transmit_retries = DT_PROP(node, transmit_retries), \ + VCONN_CTRL_GPIO(node), \ + VCONN_DISC_GPIO(node), \ + } + +#define RT1715_DRIVER_INIT(inst) \ + static struct rt1715_data drv_data_rt1715##inst = \ + RT1715_DRIVER_DATA_INIT(DT_DRV_INST(inst)); \ + static struct rt1715_cfg drv_cfg_rt1715##inst = RT1715_DRIVER_CFG_INIT(DT_DRV_INST(inst)); \ + DEVICE_DT_INST_DEFINE(inst, &rt1715_dev_init, NULL, &drv_data_rt1715##inst, \ + &drv_cfg_rt1715##inst, POST_KERNEL, CONFIG_USBC_TCPC_INIT_PRIORITY, \ + &rt1715_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RT1715_DRIVER_INIT) diff --git a/drivers/usb_c/tcpc/rt1715.h b/drivers/usb_c/tcpc/rt1715.h new file mode 100644 index 0000000000000..823aa5f5326aa --- /dev/null +++ b/drivers/usb_c/tcpc/rt1715.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024 Jianxiong Gu + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_USBC_TCPC_RT1715_H_ +#define ZEPHYR_DRIVERS_USBC_TCPC_RT1715_H_ + +#define RT1715_REG_SYS_CTRL_1 0x90 +/** VCONN OVP occurs and discharge path turn-on */ +#define RT1715_REG_SYS_CTRL_1_VCONN_DISCHARGE_EN BIT(5) +/** Low power mode Rd or Rp */ +#define RT1715_REG_SYS_CTRL_1_BMCIO_LPR_PRD BIT(4) +/** Low power mode enable */ +#define RT1715_REG_SYS_CTRL_1_BMCIO_LP_EN BIT(3) +/** BMCIO BandGap enable */ +#define RT1715_REG_SYS_CTRL_1_BMCIO_BG_EN BIT(2) +/** VBUS detection enable */ +#define RT1715_REG_SYS_CTRL_1_VBUS_DETECT_EN BIT(1) +/** 24M oscillator for BMC communication */ +#define RT1715_REG_SYS_CTRL_1_BMCIO_OSC_EN BIT(0) + +#define RT1715_REG_OCP 0x93 +/** VCONN over-current control selection */ +#define RT1715_REG_OCP_BMCIO_VCON_OCP GENMASK(7, 5) +#define RT1715_VCON_OCP_200MA (0 << 5) +#define RT1715_VCON_OCP_300MA (1 << 5) +#define RT1715_VCON_OCP_400MA (2 << 5) +#define RT1715_VCON_OCP_500MA (3 << 5) +#define RT1715_VCON_OCP_600MA (4 << 5) + +#define RT1715_REG_RT_ST 0x97 +/** If VBUS under 0.8V */ +#define RT1715_REG_RT_ST_VBUS_80 BIT(1) + +#define RT1715_REG_RT_INT 0x98 +/** Ra detach */ +#define RT1715_REG_RT_INT_RA_DETACH BIT(5) +/** VBUS under 0.8V */ +#define RT1715_REG_RT_INT_VBUS_80 BIT(1) +/** Low power mode exited */ +#define RT1715_REG_RT_INT_WAKEUP BIT(0) + +#define RT1715_REG_RT_INT_MASK 0x99 + +#define RT1715_REG_LP_CTRL 0x9B +/** Clock_300K divided from Clock_24M */ +#define RT1715_REG_LP_CTRL_CK_300K_SEL BIT(7) +/** Non-Shutdown mode */ +#define RT1715_REG_LP_CTRL_SHUTDOWN_OFF BIT(5) +/** Enable PD3.0 Extended message */ +#define RT1715_REG_LP_CTRL_ENEXTMSG BIT(4) +/** Auto enter idle mode enable */ +#define RT1715_REG_LP_CTRL_AUTOIDLE_EN BIT(3) +/** Enter idle mode timeout time */ +#define RT1715_REG_LP_CTRL_AUTOIDLE_TIMEOUT GENMASK(2, 0) +#define RT1715_AUTOIDLE_TIMEOUT_96P0_MS 7 +#define RT1715_AUTOIDLE_TIMEOUT_83P2_MS 6 +#define RT1715_AUTOIDLE_TIMEOUT_70P4_MS 5 +#define RT1715_AUTOIDLE_TIMEOUT_57P6_MS 4 +#define RT1715_AUTOIDLE_TIMEOUT_44P8_MS 3 +#define RT1715_AUTOIDLE_TIMEOUT_32P0_MS 2 +#define RT1715_AUTOIDLE_TIMEOUT_19P2_MS 1 +#define RT1715_AUTOIDLE_TIMEOUT_6P4_MS 0 + +#define RT1715_REG_SYS_WAKEUP 0x9F +/** Wakeup function enable */ +#define RT1715_REG_SYS_WAKEUP_EN BIT(7) + +#define RT1715_REG_SW_RST 0xA0 +/** Write 1 to trigger software reset */ +#define RT1715_REG_SW_RST_EN BIT(0) + +#define RT1715_REG_DRP_CTRL_1 0xA2 +/** + * The period a DRP will complete a Source to Sink and back advertisement. + * (Period = TDRP * 6.4 + 51.2ms) + */ +#define RT1715_REG_DRP_CTRL_1_TDRP GENMASK(3, 0) + +#define RT1715_REG_DRP_CTRL_2 0xA3 +/** + * The percent of time that a DRP will advertise Source during tDRP. + * (DUTY = (DCSRCDRP[9:0] + 1) / 1024) + */ +#define RT1715_REG_DRP_CTRL_2_DCSRCDRP GENMASK(9, 0) + +#endif /* ZEPHYR_DRIVERS_USBC_TCPC_UCPD_NUMAKER_H_ */ diff --git a/drivers/usb_c/tcpc/shell.c b/drivers/usb_c/tcpc/shell.c index 43ea2a9077cb7..85175392ed76f 100644 --- a/drivers/usb_c/tcpc/shell.c +++ b/drivers/usb_c/tcpc/shell.c @@ -54,7 +54,7 @@ static int cmd_tcpc_dump(const struct shell *sh, size_t argc, char **argv) if (argc <= 1) { DT_FOREACH_STATUS_OKAY(usb_c_connector, TCPC_DUMP_CONN_NODE); } else { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); if (dev != NULL) { TCPC_DUMP_DEV(dev); @@ -81,7 +81,7 @@ static int cmd_tcpc_vbus(const struct shell *sh, size_t argc, char **argv) if (argc <= 1) { DT_FOREACH_STATUS_OKAY(usb_c_connector, TCPC_VBUS_CONN_NODE); } else { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); if (dev != NULL) { TCPC_VBUS_DEV(dev); @@ -109,7 +109,7 @@ static int cmd_tcpc_chip_info(const struct shell *sh, size_t argc, char **argv) if (argc <= 1) { DT_FOREACH_STATUS_OKAY(usb_c_connector, TCPC_GET_CHIP_CONN_NODE); } else { - const struct device *dev = device_get_binding(argv[1]); + const struct device *dev = shell_device_get_binding(argv[1]); if (dev != NULL) { TCPC_GET_CHIP_DEV(dev); diff --git a/drivers/usb_c/tcpc/tcpci.c b/drivers/usb_c/tcpc/tcpci.c index ffac0bc8195db..8a356159843f9 100644 --- a/drivers/usb_c/tcpc/tcpci.c +++ b/drivers/usb_c/tcpc/tcpci.c @@ -446,3 +446,239 @@ int tcpci_tcpm_get_cc(const struct i2c_dt_spec *bus, enum tc_cc_voltage_state *c return 0; } + +int tcpci_tcpm_get_chip_info(const struct i2c_dt_spec *bus, struct tcpc_chip_info *chip_info) +{ + int ret; + + if (chip_info == NULL) { + return -EIO; + } + + ret = tcpci_read_reg16(bus, TCPC_REG_VENDOR_ID, &chip_info->vendor_id); + if (ret != 0) { + return ret; + } + + ret = tcpci_read_reg16(bus, TCPC_REG_PRODUCT_ID, &chip_info->product_id); + if (ret != 0) { + return ret; + } + + return tcpci_read_reg16(bus, TCPC_REG_BCD_DEV, &chip_info->device_id); +} + +int tcpci_tcpm_dump_std_reg(const struct i2c_dt_spec *bus) +{ + uint16_t value; + + for (unsigned int a = 0; a < ARRAY_SIZE(tcpci_std_regs); a++) { + switch (tcpci_std_regs[a].size) { + case 1: + tcpci_read_reg8(bus, tcpci_std_regs[a].addr, (uint8_t *)&value); + LOG_INF("- %-30s(0x%02x) = 0x%02x", tcpci_std_regs[a].name, + tcpci_std_regs[a].addr, (uint8_t)value); + break; + case 2: + tcpci_read_reg16(bus, tcpci_std_regs[a].addr, &value); + LOG_INF("- %-30s(0x%02x) = 0x%04x", tcpci_std_regs[a].name, + tcpci_std_regs[a].addr, value); + break; + } + } + + return 0; +} + +int tcpci_tcpm_set_bist_test_mode(const struct i2c_dt_spec *bus, bool enable) +{ + return tcpci_update_reg8(bus, TCPC_REG_TCPC_CTRL, TCPC_REG_TCPC_CTRL_BIST_TEST_MODE, + enable ? TCPC_REG_TCPC_CTRL_BIST_TEST_MODE : 0); +} + +int tcpci_tcpm_transmit_data(const struct i2c_dt_spec *bus, struct pd_msg *msg, + const uint8_t retries) +{ + int reg = TCPC_REG_TX_BUFFER; + int rv; + int cnt = 4 * msg->header.number_of_data_objects; + + /* If not SOP* transmission, just write to the transmit register */ + if (msg->header.message_type >= NUM_SOP_STAR_TYPES) { + /* + * Per TCPCI spec, do not specify retry (although the TCPC + * should ignore retry field for these 3 types). + */ + return tcpci_write_reg8( + bus, TCPC_REG_TRANSMIT, + TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(msg->header.message_type)); + } + + if (cnt > 0) { + reg = TCPC_REG_TX_BUFFER; + /* TX_BYTE_CNT includes extra bytes for message header */ + cnt += sizeof(msg->header.raw_value); + + struct i2c_msg buf[3]; + + uint8_t tmp[2] = {TCPC_REG_TX_BUFFER, cnt}; + + buf[0].buf = tmp; + buf[0].len = 2; + buf[0].flags = I2C_MSG_WRITE; + + buf[1].buf = (uint8_t *)&msg->header.raw_value; + buf[1].len = sizeof(msg->header.raw_value); + buf[1].flags = I2C_MSG_WRITE; + + buf[2].buf = (uint8_t *)msg->data; + buf[2].len = msg->len; + buf[2].flags = I2C_MSG_WRITE | I2C_MSG_STOP; + + if (cnt > sizeof(msg->header.raw_value)) { + rv = i2c_transfer(bus->bus, buf, 3, bus->addr); + } else { + buf[1].flags |= I2C_MSG_STOP; + rv = i2c_transfer(bus->bus, buf, 2, bus->addr); + } + + /* If tcpc write fails, return error */ + if (rv) { + return rv; + } + } + + /* + * We always retry in TCPC hardware since the TCPM is too slow to + * respond within tRetry (~195 usec). + * + * The retry count used is dependent on the maximum PD revision + * supported at build time. + */ + rv = tcpci_write_reg8(bus, TCPC_REG_TRANSMIT, + TCPC_REG_TRANSMIT_SET_WITH_RETRY(retries, msg->type)); + + return rv; +} + +int tcpci_tcpm_select_rp_value(const struct i2c_dt_spec *bus, enum tc_rp_value rp) +{ + return tcpci_update_reg8(bus, TCPC_REG_ROLE_CTRL, TCPC_REG_ROLE_CTRL_RP_MASK, + TCPC_REG_ROLE_CTRL_SET(0, rp, 0, 0)); +} + +int tcpci_tcpm_get_rp_value(const struct i2c_dt_spec *bus, enum tc_rp_value *rp) +{ + uint8_t reg_value = 0; + int ret; + + ret = tcpci_read_reg8(bus, TCPC_REG_ROLE_CTRL, ®_value); + *rp = TCPC_REG_ROLE_CTRL_RP(reg_value); + + return ret; +} + +int tcpci_tcpm_set_cc(const struct i2c_dt_spec *bus, enum tc_cc_pull pull) +{ + return tcpci_update_reg8(bus, TCPC_REG_ROLE_CTRL, + TCPC_REG_ROLE_CTRL_CC1_MASK | TCPC_REG_ROLE_CTRL_CC2_MASK, + TCPC_REG_ROLE_CTRL_SET(0, 0, pull, pull)); +} + +int tcpci_tcpm_set_vconn(const struct i2c_dt_spec *bus, bool enable) +{ + return tcpci_update_reg8(bus, TCPC_REG_POWER_CTRL, TCPC_REG_POWER_CTRL_VCONN_EN, + enable ? TCPC_REG_POWER_CTRL_VCONN_EN : 0); +} + +int tcpci_tcpm_set_roles(const struct i2c_dt_spec *bus, enum pd_rev_type pd_rev, + enum tc_power_role power_role, enum tc_data_role data_role) +{ + return tcpci_update_reg8(bus, TCPC_REG_MSG_HDR_INFO, TCPC_REG_MSG_HDR_INFO_ROLES_MASK, + TCPC_REG_MSG_HDR_INFO_SET(pd_rev, data_role, power_role)); +} + +int tcpci_tcpm_set_drp_toggle(const struct i2c_dt_spec *bus, bool enable) +{ + return tcpci_update_reg8(bus, TCPC_REG_ROLE_CTRL, TCPC_REG_ROLE_CTRL_DRP_MASK, + TCPC_REG_ROLE_CTRL_SET(enable, 0, 0, 0)); +} + +int tcpci_tcpm_set_rx_type(const struct i2c_dt_spec *bus, uint8_t rx_type) +{ + return tcpci_write_reg8(bus, TCPC_REG_RX_DETECT, rx_type); +} + +int tcpci_tcpm_set_cc_polarity(const struct i2c_dt_spec *bus, enum tc_cc_polarity polarity) +{ + return tcpci_update_reg8( + bus, TCPC_REG_TCPC_CTRL, TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION, + (polarity == TC_POLARITY_CC1) ? 0 : TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION); +} + +int tcpci_tcpm_get_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t *status) +{ + switch (reg) { + case TCPC_ALERT_STATUS: + return tcpci_read_reg16(bus, TCPC_REG_ALERT, status); + case TCPC_CC_STATUS: + return tcpci_read_reg16(bus, TCPC_REG_CC_STATUS, status); + case TCPC_POWER_STATUS: + return tcpci_read_reg8(bus, TCPC_REG_POWER_STATUS, (uint8_t *)status); + case TCPC_FAULT_STATUS: + return tcpci_read_reg8(bus, TCPC_REG_FAULT_STATUS, (uint8_t *)status); + case TCPC_EXTENDED_STATUS: + return tcpci_read_reg8(bus, TCPC_REG_EXT_STATUS, (uint8_t *)status); + case TCPC_EXTENDED_ALERT_STATUS: + return tcpci_read_reg8(bus, TCPC_REG_ALERT_EXT, (uint8_t *)status); + default: + LOG_ERR("Not a TCPCI-specified reg address"); + return -EINVAL; + } +} + +int tcpci_tcpm_clear_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t mask) +{ + switch (reg) { + case TCPC_ALERT_STATUS: + return tcpci_write_reg16(bus, TCPC_REG_ALERT, mask); + case TCPC_CC_STATUS: + return tcpci_write_reg16(bus, TCPC_REG_CC_STATUS, mask); + case TCPC_POWER_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_POWER_STATUS, (uint8_t)mask); + case TCPC_FAULT_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_FAULT_STATUS, (uint8_t)mask); + case TCPC_EXTENDED_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_EXT_STATUS, (uint8_t)mask); + case TCPC_EXTENDED_ALERT_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_ALERT_EXT, (uint8_t)mask); + default: + LOG_ERR("Not a TCPCI-specified reg address"); + return -EINVAL; + } +} + +int tcpci_tcpm_mask_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t mask) +{ + switch (reg) { + case TCPC_ALERT_STATUS: + return tcpci_write_reg16(bus, TCPC_REG_ALERT_MASK, mask); + case TCPC_CC_STATUS: + LOG_ERR("CC_STATUS does not have a corresponding mask register"); + return -EINVAL; + case TCPC_POWER_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_POWER_STATUS_MASK, (uint8_t)mask); + case TCPC_FAULT_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_FAULT_STATUS_MASK, (uint8_t)mask); + case TCPC_EXTENDED_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_EXT_STATUS_MASK, (uint8_t)mask); + case TCPC_EXTENDED_ALERT_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_ALERT_EXT_MASK, (uint8_t)mask); + default: + LOG_ERR("Not a TCPCI-specified reg address"); + return -EINVAL; + } +} diff --git a/drivers/video/CMakeLists.txt b/drivers/video/CMakeLists.txt index e678071bdeca8..6210f8d881d07 100644 --- a/drivers/video/CMakeLists.txt +++ b/drivers/video/CMakeLists.txt @@ -16,3 +16,5 @@ zephyr_library_sources_ifdef(CONFIG_VIDEO_OV5640 ov5640.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_OV7670 ov7670.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_ESP32 video_esp32_dvp.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_MCUX_SDMA video_mcux_smartdma.c) +zephyr_library_sources_ifdef(CONFIG_VIDEO_EMUL_IMAGER video_emul_imager.c) +zephyr_library_sources_ifdef(CONFIG_VIDEO_EMUL_RX video_emul_rx.c) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6ff70bbcfca8d..a3b1634436282 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -74,4 +74,8 @@ source "drivers/video/Kconfig.gc2145" source "drivers/video/Kconfig.mcux_sdma" +source "drivers/video/Kconfig.emul_imager" + +source "drivers/video/Kconfig.emul_rx" + endif # VIDEO diff --git a/drivers/video/Kconfig.emul_imager b/drivers/video/Kconfig.emul_imager new file mode 100644 index 0000000000000..d2752fdd53b47 --- /dev/null +++ b/drivers/video/Kconfig.emul_imager @@ -0,0 +1,18 @@ +# Copyright (c) 2024 tinyVision.ai Inc. +# SPDX-License-Identifier: Apache-2.0 + +config VIDEO_EMUL_IMAGER + bool "Software implementation of an imager" + depends on DT_HAS_ZEPHYR_VIDEO_EMUL_IMAGER_ENABLED + default y + help + Enable driver for the emulated Imager. + +config VIDEO_EMUL_IMAGER_FRAMEBUFFER_SIZE + int "Internal framebuffer size used for link emulation purpose" + default 4096 + help + Configure the size of the internal framebuffer the emulated Imager + driver uses to simulate MIPI transfers. This is the first field of + dev->data, and the emulated video MIPI driver will `memcpy()` it + into the video buffer. diff --git a/drivers/video/Kconfig.emul_rx b/drivers/video/Kconfig.emul_rx new file mode 100644 index 0000000000000..39425d9b136bc --- /dev/null +++ b/drivers/video/Kconfig.emul_rx @@ -0,0 +1,10 @@ +# Copyright (c) 2024 tinyVision.ai Inc. +# SPDX-License-Identifier: Apache-2.0 + +config VIDEO_EMUL_RX + bool "Software implementation of video frame RX core" + depends on DT_HAS_ZEPHYR_VIDEO_EMUL_RX_ENABLED + depends on VIDEO_EMUL_IMAGER + default y + help + Enable driver for the MIPI RX emulated DMA engine. diff --git a/drivers/video/gc2145.c b/drivers/video/gc2145.c index f7c779f7fc8f0..cb3efbfb585d2 100644 --- a/drivers/video/gc2145.c +++ b/drivers/video/gc2145.c @@ -20,7 +20,9 @@ LOG_MODULE_REGISTER(video_gc2145, CONFIG_VIDEO_LOG_LEVEL); #define GC2145_AMODE1_WINDOW_MASK 0xFC #define GC2145_REG_AMODE1_DEF 0x14 #define GC2145_REG_OUTPUT_FMT 0x84 +#define GC2145_REG_OUTPUT_FMT_MASK 0x1F #define GC2145_REG_OUTPUT_FMT_RGB565 0x06 +#define GC2145_REG_OUTPUT_FMT_YCBYCR 0x02 #define GC2145_REG_SYNC_MODE 0x86 #define GC2145_REG_SYNC_MODE_DEF 0x23 #define GC2145_REG_SYNC_MODE_COL_SWITCH 0x10 @@ -79,8 +81,8 @@ static const struct gc2145_reg default_regs[] = { {0x9a, 0x0E}, /* Subsample mode */ {0x12, 0x2e}, - {GC2145_REG_OUTPUT_FMT, 0x14}, /* Analog Mode 1 (vflip/mirror[1:0]) */ - {0x18, 0x22}, /* Analog Mode 2 */ + {0x17, 0x14}, /* Analog Mode 1 (vflip/mirror[1:0]) */ + {0x18, 0x22}, /* Analog Mode 2 */ {0x19, 0x0e}, {0x1a, 0x01}, {0x1b, 0x4b}, @@ -681,6 +683,9 @@ static const struct gc2145_reg default_regs[] = { struct gc2145_config { struct i2c_dt_spec i2c; +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) + struct gpio_dt_spec pwdn_gpio; +#endif #if DT_INST_NODE_HAS_PROP(0, reset_gpios) struct gpio_dt_spec reset_gpio; #endif @@ -696,18 +701,22 @@ struct gc2145_data { .height_min = height, .height_max = height, .width_step = 0, .height_step = 0, \ } -enum resolutions { - QVGA_RESOLUTION = 0, - VGA_RESOLUTION, - UXGA_RESOLUTION, - RESOLUTIONS_MAX, -}; +#define RESOLUTION_QVGA_W 320 +#define RESOLUTION_QVGA_H 240 + +#define RESOLUTION_VGA_W 640 +#define RESOLUTION_VGA_H 480 + +#define RESOLUTION_UXGA_W 1600 +#define RESOLUTION_UXGA_H 1200 static const struct video_format_cap fmts[] = { - [QVGA_RESOLUTION] = GC2145_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_RGB565), /* QVGA */ - [VGA_RESOLUTION] = GC2145_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_RGB565), /* VGA */ - [UXGA_RESOLUTION] = GC2145_VIDEO_FORMAT_CAP(1600, 1200, VIDEO_PIX_FMT_RGB565), /* UXGA */ - [RESOLUTIONS_MAX] = {0}, + GC2145_VIDEO_FORMAT_CAP(RESOLUTION_QVGA_W, RESOLUTION_QVGA_H, VIDEO_PIX_FMT_RGB565), + GC2145_VIDEO_FORMAT_CAP(RESOLUTION_VGA_W, RESOLUTION_VGA_H, VIDEO_PIX_FMT_RGB565), + GC2145_VIDEO_FORMAT_CAP(RESOLUTION_UXGA_W, RESOLUTION_UXGA_H, VIDEO_PIX_FMT_RGB565), + GC2145_VIDEO_FORMAT_CAP(RESOLUTION_QVGA_W, RESOLUTION_QVGA_H, VIDEO_PIX_FMT_YUYV), + GC2145_VIDEO_FORMAT_CAP(RESOLUTION_VGA_W, RESOLUTION_VGA_H, VIDEO_PIX_FMT_YUYV), + GC2145_VIDEO_FORMAT_CAP(RESOLUTION_UXGA_W, RESOLUTION_UXGA_H, VIDEO_PIX_FMT_YUYV), }; static int gc2145_write_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint8_t value) @@ -728,8 +737,7 @@ static int gc2145_write_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr, ui } /* If writing failed wait 5ms before next attempt */ k_msleep(5); - - } while (tries--); + } while (tries-- > 0); LOG_ERR("failed to write 0x%x to 0x%x,", value, reg_addr); return ret; @@ -753,8 +761,7 @@ static int gc2145_read_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr, uin } /* If writing failed wait 5ms before next attempt */ k_msleep(5); - - } while (tries--); + } while (tries-- > 0); LOG_ERR("failed to read 0x%x register", reg_addr); return ret; @@ -883,6 +890,7 @@ static int gc2145_set_window(const struct device *dev, uint16_t reg, uint16_t x, static int gc2145_set_output_format(const struct device *dev, int output_format) { int ret; + uint8_t old_value; const struct gc2145_config *cfg = dev->config; ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_RESET, GC2145_SET_P0_REGS); @@ -890,13 +898,23 @@ static int gc2145_set_output_format(const struct device *dev, int output_format) return ret; } - if (output_format != VIDEO_PIX_FMT_RGB565) { + /* Map format to sensor format */ + if (output_format == VIDEO_PIX_FMT_RGB565) { + output_format = GC2145_REG_OUTPUT_FMT_RGB565; + } else if (output_format == VIDEO_PIX_FMT_YUYV) { + output_format = GC2145_REG_OUTPUT_FMT_YCBYCR; + } else { LOG_ERR("Image format not supported"); return -ENOTSUP; } - /* Disable JPEG compression and set output to RGB565 */ - ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_OUTPUT_FMT, GC2145_REG_OUTPUT_FMT_RGB565); + ret = gc2145_read_reg(&cfg->i2c, GC2145_REG_OUTPUT_FMT, &old_value); + if (ret < 0) { + return ret; + } + + ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_OUTPUT_FMT, + (old_value & ~GC2145_REG_OUTPUT_FMT_MASK) | output_format); if (ret < 0) { return ret; } @@ -906,13 +924,11 @@ static int gc2145_set_output_format(const struct device *dev, int output_format) return 0; } -static int gc2145_set_resolution(const struct device *dev, enum resolutions res) +static int gc2145_set_resolution(const struct device *dev, uint32_t w, uint32_t h) { int ret; const struct gc2145_config *cfg = dev->config; - uint16_t w; - uint16_t h; uint16_t win_w; uint16_t win_h; uint16_t c_ratio; @@ -922,29 +938,22 @@ static int gc2145_set_resolution(const struct device *dev, enum resolutions res) uint16_t win_x; uint16_t win_y; - if (res >= RESOLUTIONS_MAX) { - return -EIO; - } - - w = fmts[res].width_min; - h = fmts[res].height_min; - /* Add the subsampling factor depending on resolution */ - switch (res) { - case QVGA_RESOLUTION: + switch (w) { + case RESOLUTION_QVGA_W: c_ratio = 3; r_ratio = 3; break; - case VGA_RESOLUTION: + case RESOLUTION_VGA_W: c_ratio = 2; r_ratio = 2; break; - case UXGA_RESOLUTION: + case RESOLUTION_UXGA_W: c_ratio = 1; r_ratio = 1; break; default: - LOG_ERR("Unsupported resolution %d", res); + LOG_ERR("Unsupported resolution %d %d", w, h); return -EIO; }; @@ -1024,29 +1033,23 @@ static int gc2145_set_fmt(const struct device *dev, enum video_endpoint_id ep, struct video_format *fmt) { struct gc2145_data *drv_data = dev->data; - enum resolutions res = RESOLUTIONS_MAX; + size_t res = ARRAY_SIZE(fmts); int ret; - /* We only support RGB565 formats */ - if (fmt->pixelformat != VIDEO_PIX_FMT_RGB565) { - LOG_ERR("gc2145 camera supports only RGB565"); - return -ENOTSUP; - } - if (memcmp(&drv_data->fmt, fmt, sizeof(drv_data->fmt)) == 0) { /* nothing to do */ return 0; } /* Check if camera is capable of handling given format */ - for (int i = 0; i < RESOLUTIONS_MAX; i++) { + for (int i = 0; i < ARRAY_SIZE(fmts); i++) { if (fmts[i].width_min == fmt->width && fmts[i].height_min == fmt->height && fmts[i].pixelformat == fmt->pixelformat) { - res = (enum resolutions)i; + res = i; break; } } - if (res == RESOLUTIONS_MAX) { + if (res == ARRAY_SIZE(fmts)) { LOG_ERR("Image format not supported"); return -ENOTSUP; } @@ -1061,7 +1064,8 @@ static int gc2145_set_fmt(const struct device *dev, enum video_endpoint_id ep, } /* Set window size */ - ret = gc2145_set_resolution(dev, res); + ret = gc2145_set_resolution(dev, fmt->width, fmt->height); + if (ret < 0) { LOG_ERR("Failed to set the resolution"); return ret; @@ -1080,18 +1084,12 @@ static int gc2145_get_fmt(const struct device *dev, enum video_endpoint_id ep, return 0; } -static int gc2145_stream_start(const struct device *dev) +static int gc2145_set_stream(const struct device *dev, bool enable) { const struct gc2145_config *cfg = dev->config; - return gc2145_write_reg(&cfg->i2c, 0xf2, 0x0f); -} - -static int gc2145_stream_stop(const struct device *dev) -{ - const struct gc2145_config *cfg = dev->config; - - return gc2145_write_reg(&cfg->i2c, 0xf2, 0x00); + return enable ? gc2145_write_reg(&cfg->i2c, 0xf2, 0x0f) + : gc2145_write_reg(&cfg->i2c, 0xf2, 0x00); } static int gc2145_get_caps(const struct device *dev, enum video_endpoint_id ep, @@ -1117,8 +1115,7 @@ static DEVICE_API(video, gc2145_driver_api) = { .set_format = gc2145_set_fmt, .get_format = gc2145_get_fmt, .get_caps = gc2145_get_caps, - .stream_start = gc2145_stream_start, - .stream_stop = gc2145_stream_stop, + .set_stream = gc2145_set_stream, .set_ctrl = gc2145_set_ctrl, }; @@ -1126,10 +1123,18 @@ static int gc2145_init(const struct device *dev) { struct video_format fmt; int ret; - -#if DT_INST_NODE_HAS_PROP(0, reset_gpios) const struct gc2145_config *cfg = dev->config; + (void) cfg; + +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) + ret = gpio_pin_configure_dt(&cfg->pwdn_gpio, GPIO_OUTPUT_INACTIVE); + if (ret) { + return ret; + } + k_sleep(K_MSEC(10)); +#endif +#if DT_INST_NODE_HAS_PROP(0, reset_gpios) ret = gpio_pin_configure_dt(&cfg->reset_gpio, GPIO_OUTPUT_ACTIVE); if (ret) { return ret; @@ -1150,9 +1155,9 @@ static int gc2145_init(const struct device *dev) /* set default/init format QVGA RGB565 */ fmt.pixelformat = VIDEO_PIX_FMT_RGB565; - fmt.width = fmts[QVGA_RESOLUTION].width_min; - fmt.height = fmts[QVGA_RESOLUTION].height_min; - fmt.pitch = fmts[QVGA_RESOLUTION].width_min * 2; + fmt.width = RESOLUTION_QVGA_W; + fmt.height = RESOLUTION_QVGA_H; + fmt.pitch = RESOLUTION_QVGA_W * 2; ret = gc2145_set_fmt(dev, VIDEO_EP_OUT, &fmt); if (ret) { @@ -1166,6 +1171,9 @@ static int gc2145_init(const struct device *dev) /* Unique Instance */ static const struct gc2145_config gc2145_cfg_0 = { .i2c = I2C_DT_SPEC_INST_GET(0), +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) + .pwdn_gpio = GPIO_DT_SPEC_INST_GET(0, pwdn_gpios), +#endif #if DT_INST_NODE_HAS_PROP(0, reset_gpios) .reset_gpio = GPIO_DT_SPEC_INST_GET(0, reset_gpios), #endif @@ -1181,6 +1189,12 @@ static int gc2145_init_0(const struct device *dev) return -ENODEV; } +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) + if (!gpio_is_ready_dt(&cfg->pwdn_gpio)) { + LOG_ERR("%s: device %s is not ready", dev->name, cfg->pwdn_gpio.port->name); + return -ENODEV; + } +#endif #if DT_INST_NODE_HAS_PROP(0, reset_gpios) if (!gpio_is_ready_dt(&cfg->reset_gpio)) { LOG_ERR("%s: device %s is not ready", dev->name, cfg->reset_gpio.port->name); diff --git a/drivers/video/mt9m114.c b/drivers/video/mt9m114.c index 5fb079f1cf67f..663fa422201e7 100644 --- a/drivers/video/mt9m114.c +++ b/drivers/video/mt9m114.c @@ -12,6 +12,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(video_mt9m114, CONFIG_VIDEO_LOG_LEVEL); @@ -31,6 +32,7 @@ LOG_MODULE_REGISTER(video_mt9m114, CONFIG_VIDEO_LOG_LEVEL); #define MT9M114_CAM_SENSOR_CFG_Y_ADDR_END 0xC804 #define MT9M114_CAM_SENSOR_CFG_X_ADDR_END 0xC806 #define MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW 0xC818 +#define MT9M114_CAM_SENSOR_CTRL_READ_MODE 0xC834 #define MT9M114_CAM_CROP_WINDOW_WIDTH 0xC858 #define MT9M114_CAM_CROP_WINDOW_HEIGHT 0xC85A #define MT9M114_CAM_OUTPUT_WIDTH 0xC868 @@ -53,6 +55,10 @@ LOG_MODULE_REGISTER(video_mt9m114, CONFIG_VIDEO_LOG_LEVEL); #define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV (0 << 8) #define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB (1 << 8) +/* Camera control masks */ +#define MT9M114_CAM_SENSOR_CTRL_HORZ_FLIP_EN BIT(0) +#define MT9M114_CAM_SENSOR_CTRL_VERT_FLIP_EN BIT(1) + struct mt9m114_config { struct i2c_dt_spec i2c; }; @@ -261,12 +267,13 @@ static int mt9m114_read_reg(const struct device *dev, uint16_t reg_addr, uint8_t return 0; } -static int mt9m114_modify_reg(const struct device *dev, const uint16_t addr, const uint8_t mask, - const uint8_t val) +static int mt9m114_modify_reg(const struct device *dev, const uint16_t addr, + uint8_t reg_size, const uint32_t mask, const uint32_t val) { - uint8_t oldVal; - uint8_t newVal; - int ret = mt9m114_read_reg(dev, addr, sizeof(oldVal), &oldVal); + uint32_t oldVal = 0; + uint32_t newVal = 0; + + int ret = mt9m114_read_reg(dev, addr, reg_size, &oldVal); if (ret) { return ret; @@ -274,7 +281,7 @@ static int mt9m114_modify_reg(const struct device *dev, const uint16_t addr, con newVal = (oldVal & ~mask) | (val & mask); - return mt9m114_write_reg(dev, addr, sizeof(newVal), &newVal); + return mt9m114_write_reg(dev, addr, reg_size, &newVal); } static int mt9m114_write_all(const struct device *dev, struct mt9m114_reg *reg) @@ -297,7 +304,7 @@ static int mt9m114_write_all(const struct device *dev, struct mt9m114_reg *reg) static int mt9m114_software_reset(const struct device *dev) { - int ret = mt9m114_modify_reg(dev, MT9M114_RST_AND_MISC_CONTROL, 0x01, 0x01); + int ret = mt9m114_modify_reg(dev, MT9M114_RST_AND_MISC_CONTROL, 2, 0x01, 0x01); if (ret) { return ret; @@ -305,7 +312,7 @@ static int mt9m114_software_reset(const struct device *dev) k_sleep(K_MSEC(1)); - ret = mt9m114_modify_reg(dev, MT9M114_RST_AND_MISC_CONTROL, 0x01, 0x00); + ret = mt9m114_modify_reg(dev, MT9M114_RST_AND_MISC_CONTROL, 2, 0x01, 0x00); if (ret) { return ret; } @@ -444,14 +451,10 @@ static int mt9m114_get_fmt(const struct device *dev, enum video_endpoint_id ep, return 0; } -static int mt9m114_stream_start(const struct device *dev) -{ - return mt9m114_set_state(dev, MT9M114_SYS_STATE_START_STREAMING); -} - -static int mt9m114_stream_stop(const struct device *dev) +static int mt9m114_set_stream(const struct device *dev, bool enable) { - return mt9m114_set_state(dev, MT9M114_SYS_STATE_ENTER_SUSPEND); + return enable ? mt9m114_set_state(dev, MT9M114_SYS_STATE_START_STREAMING) + : mt9m114_set_state(dev, MT9M114_SYS_STATE_ENTER_SUSPEND); } static int mt9m114_get_caps(const struct device *dev, enum video_endpoint_id ep, @@ -461,12 +464,39 @@ static int mt9m114_get_caps(const struct device *dev, enum video_endpoint_id ep, return 0; } +static int mt9m114_set_ctrl(const struct device *dev, unsigned int cid, void *value) +{ + int ret = 0; + + switch (cid) { + case VIDEO_CID_HFLIP: + ret = mt9m114_modify_reg(dev, MT9M114_CAM_SENSOR_CTRL_READ_MODE, 2, + MT9M114_CAM_SENSOR_CTRL_HORZ_FLIP_EN, + (int)value ? MT9M114_CAM_SENSOR_CTRL_HORZ_FLIP_EN : 0); + break; + case VIDEO_CID_VFLIP: + ret = mt9m114_modify_reg(dev, MT9M114_CAM_SENSOR_CTRL_READ_MODE, 2, + MT9M114_CAM_SENSOR_CTRL_VERT_FLIP_EN, + (int)value ? MT9M114_CAM_SENSOR_CTRL_VERT_FLIP_EN : 0); + break; + default: + return -ENOTSUP; + } + + if (ret < 0) { + return ret; + } + + /* Apply Config */ + return mt9m114_set_state(dev, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); +} + static DEVICE_API(video, mt9m114_driver_api) = { .set_format = mt9m114_set_fmt, .get_format = mt9m114_get_fmt, .get_caps = mt9m114_get_caps, - .stream_start = mt9m114_stream_start, - .stream_stop = mt9m114_stream_stop, + .set_stream = mt9m114_set_stream, + .set_ctrl = mt9m114_set_ctrl, }; static int mt9m114_init(const struct device *dev) diff --git a/drivers/video/ov2640.c b/drivers/video/ov2640.c index 987d97aa3051a..f89e73dbd9f83 100644 --- a/drivers/video/ov2640.c +++ b/drivers/video/ov2640.c @@ -490,7 +490,7 @@ static int ov2640_write_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr, * just to be sure that the connection error is not caused by driver * itself. */ - while (tries--) { + while (tries-- > 0) { if (!i2c_reg_write_byte_dt(spec, reg_addr, value)) { return 0; } @@ -513,7 +513,7 @@ static int ov2640_read_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr) * just to be sure that the connection error is not caused by driver * itself. */ - while (tries--) { + while (tries-- > 0) { if (!i2c_reg_read_byte_dt(spec, reg_addr, &value)) { return value; } @@ -910,12 +910,7 @@ static int ov2640_get_fmt(const struct device *dev, return 0; } -static int ov2640_stream_start(const struct device *dev) -{ - return 0; -} - -static int ov2640_stream_stop(const struct device *dev) +static int ov2640_set_stream(const struct device *dev, bool enable) { return 0; } @@ -975,8 +970,7 @@ static DEVICE_API(video, ov2640_driver_api) = { .set_format = ov2640_set_fmt, .get_format = ov2640_get_fmt, .get_caps = ov2640_get_caps, - .stream_start = ov2640_stream_start, - .stream_stop = ov2640_stream_stop, + .set_stream = ov2640_set_stream, .set_ctrl = ov2640_set_ctrl, }; diff --git a/drivers/video/ov5640.c b/drivers/video/ov5640.c index 7b871fb5e281d..768d0d9ffa1bd 100644 --- a/drivers/video/ov5640.c +++ b/drivers/video/ov5640.c @@ -1,5 +1,6 @@ /* * Copyright 2024 NXP + * Copyright (c) 2025, Charles Dias * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +17,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(video_ov5640, CONFIG_VIDEO_LOG_LEVEL); @@ -114,6 +116,7 @@ struct ov5640_config { struct i2c_dt_spec i2c; struct gpio_dt_spec reset_gpio; struct gpio_dt_spec powerdown_gpio; + int bus_type; }; struct ov5640_reg { @@ -131,6 +134,7 @@ struct ov5640_mipi_frmrate_config { struct ov5640_mode_config { uint16_t width; uint16_t height; + uint16_t array_size_res_params; const struct ov5640_reg *res_params; const struct ov5640_mipi_frmrate_config *mipi_frmrate_config; uint16_t max_frmrate; @@ -144,7 +148,7 @@ struct ov5640_data { const struct ov5640_mode_config *cur_mode; }; -static const struct ov5640_reg init_params[] = { +static const struct ov5640_reg init_params_common[] = { /* Power down */ {SYS_CTRL0_REG, SYS_CTRL0_SW_PWDN}, @@ -359,14 +363,117 @@ static const struct ov5640_reg init_params[] = { {0x5000, 0xa7}, }; -static const struct ov5640_reg low_res_params[] = { +static const struct ov5640_reg init_params_dvp[] = { + {0x4740, 0x21}, + {0x4050, 0x6e}, + {0x4051, 0x8f}, + {0x3017, 0xff}, + {0x3018, 0xff}, + {0x302c, 0x02}, + {0x3108, 0x01}, + {0x3630, 0x2e}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x1c}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x08}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {TIMING_TC_REG20_REG, 0x47}, + {TIMING_TC_REG21_REG, 0x01}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0x9b}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x03}, + {0x380b, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x06}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3034, 0x1a}, + {0x3035, 0x11}, + {0x3036, 0x64}, + {0x3037, 0x13}, + {0x3038, 0x00}, + {0x3039, 0x00}, + {0x380c, 0x07}, + {0x380d, 0x68}, + {0x380e, 0x03}, + {0x380f, 0xd8}, + {0x3c01, 0xb4}, + {0x3c00, 0x04}, + {0x3a08, 0x00}, + {0x3a09, 0x93}, + {0x3a0e, 0x06}, + {0x3a0a, 0x00}, + {0x3a0b, 0x7b}, + {0x3a0d, 0x08}, + {0x3a00, 0x38}, + {0x3a02, 0x05}, + {0x3a03, 0xc4}, + {0x3a14, 0x05}, + {0x3a15, 0xc4}, + {0x300e, 0x58}, + {0x302e, 0x00}, + {0x4300, 0x30}, + {0x501f, 0x00}, + {0x4713, 0x04}, + {0x4407, 0x04}, + {0x460b, 0x35}, + {0x460c, 0x22}, + {0x3824, 0x02}, + {0x3406, 0x01}, + {0x3400, 0x06}, + {0x3401, 0x80}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x06}, + {0x3405, 0x00}, + {0x5688, 0x22}, + {0x5689, 0x22}, + {0x568a, 0x42}, + {0x568b, 0x24}, + {0x568c, 0x42}, + {0x568d, 0x24}, + {0x568e, 0x22}, + {0x568f, 0x22}, + {0x5025, 0x00}, + {0x3406, 0x00}, + {0x3503, 0x00}, + {0x3008, 0x02}, + {0x3a02, 0x07}, + {0x3a03, 0xae}, + {0x3a08, 0x01}, + {0x3a09, 0x27}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xae}, +}; + +static const struct ov5640_reg csi2_low_res_params[] = { {0x3800, 0x00}, {0x3801, 0x00}, {0x3802, 0x00}, {0x3803, 0x04}, {0x3804, 0x0a}, {0x3805, 0x3f}, {0x3806, 0x07}, {0x3807, 0x9b}, {0x3808, 0x02}, {0x3809, 0x80}, {0x380a, 0x01}, {0x380b, 0xe0}, {0x380c, 0x07}, {0x380d, 0x68}, {0x380e, 0x03}, {0x380f, 0xd8}, {0x3810, 0x00}, {0x3811, 0x10}, {0x3812, 0x00}, {0x3813, 0x06}, {0x3814, 0x31}, {0x3815, 0x31}, {0x3824, 0x02}, {0x460c, 0x22}}; -static const struct ov5640_reg hd_res_params[] = { +static const struct ov5640_reg csi2_hd_res_params[] = { {0x3800, 0x00}, {0x3801, 0x00}, {0x3802, 0x00}, {0x3803, 0xfa}, {0x3804, 0x0a}, {0x3805, 0x3f}, {0x3806, 0x06}, {0x3807, 0xa9}, {0x3808, 0x05}, {0x3809, 0x00}, {0x380a, 0x02}, {0x380b, 0xd0}, {0x380c, 0x07}, {0x380d, 0x64}, {0x380e, 0x02}, @@ -379,11 +486,12 @@ static const struct ov5640_mipi_frmrate_config mipi_hd_frmrate_params[] = { static const struct ov5640_mipi_frmrate_config mipi_vga_frmrate_params[] = { {15, 0x22, 0x38, 24000000}, {30, 0x14, 0x38, 24000000}, {60, 0x14, 0x70, 48000000}}; -static const struct ov5640_mode_config modes[] = { +static const struct ov5640_mode_config csi2_modes[] = { { .width = 640, .height = 480, - .res_params = low_res_params, + .array_size_res_params = ARRAY_SIZE(csi2_low_res_params), + .res_params = csi2_low_res_params, .mipi_frmrate_config = mipi_vga_frmrate_params, .max_frmrate = OV5640_60_FPS, .def_frmrate = OV5640_30_FPS, @@ -391,7 +499,8 @@ static const struct ov5640_mode_config modes[] = { { .width = 1280, .height = 720, - .res_params = hd_res_params, + .array_size_res_params = ARRAY_SIZE(csi2_hd_res_params), + .res_params = csi2_hd_res_params, .mipi_frmrate_config = mipi_hd_frmrate_params, .max_frmrate = OV5640_60_FPS, .def_frmrate = OV5640_30_FPS, @@ -399,19 +508,88 @@ static const struct ov5640_mode_config modes[] = { static const int ov5640_frame_rates[] = {OV5640_15_FPS, OV5640_30_FPS, OV5640_60_FPS}; -#define OV5640_VIDEO_FORMAT_CAP(width, height, format) \ - { \ - .pixelformat = (format), .width_min = (width), .width_max = (width), \ - .height_min = (height), .height_max = (height), .width_step = 0, .height_step = 0 \ - } +/* Initialization sequence for QQVGA resolution (160x120) */ +static const struct ov5640_reg dvp_160x120_res_params[] = { + {0x3800, 0x00}, {0x3801, 0x08}, {0x3802, 0x00}, {0x3803, 0x02}, {0x3804, 0x0a}, + {0x3805, 0x37}, {0x3806, 0x07}, {0x3807, 0xa1}, {0x3808, 0x00}, {0x3809, 0xa0}, + {0x380a, 0x00}, {0x380b, 0x78}, {0x380c, 0x06}, {0x380d, 0x14}, {0x380e, 0x03}, + {0x380f, 0xe8}, {0x3810, 0x00}, {0x3811, 0x04}, {0x3812, 0x00}, {0x3813, 0x02}, + {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0x47}, {0x3821, 0x01}, {0x4602, 0x00}, + {0x4603, 0xa0}, {0x4604, 0x00}, {0x4605, 0x78}}; + +/* Initialization sequence for QVGA resolution (320x240) */ +static const struct ov5640_reg dvp_320x240_res_params[] = { + {0x3800, 0x00}, {0x3801, 0x08}, {0x3802, 0x00}, {0x3803, 0x02}, {0x3804, 0x0a}, + {0x3805, 0x37}, {0x3806, 0x07}, {0x3807, 0xa1}, {0x3808, 0x01}, {0x3809, 0x40}, + {0x380a, 0x00}, {0x380b, 0xf0}, {0x380c, 0x06}, {0x380d, 0x14}, {0x380e, 0x03}, + {0x380f, 0xe8}, {0x3810, 0x00}, {0x3811, 0x04}, {0x3812, 0x00}, {0x3813, 0x02}, + {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0x47}, {0x3821, 0x01}, {0x4602, 0x01}, + {0x4603, 0x40}, {0x4604, 0x00}, {0x4605, 0xf0}}; + +/* Initialization sequence for WQVGA resolution (480x272) */ +static const struct ov5640_reg dvp_480x272_res_params[] = { + {0x3800, 0x00}, {0x3801, 0x08}, {0x3802, 0x00}, {0x3803, 0x02}, {0x3804, 0x0a}, + {0x3805, 0x37}, {0x3806, 0x07}, {0x3807, 0xa1}, {0x3808, 0x01}, {0x3809, 0xe0}, + {0x380a, 0x01}, {0x380b, 0x10}, {0x380c, 0x06}, {0x380d, 0x14}, {0x380e, 0x03}, + {0x380f, 0xe8}, {0x3810, 0x00}, {0x3811, 0x04}, {0x3812, 0x00}, {0x3813, 0x79}, + {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0x47}, {0x3821, 0x01}, {0x4602, 0x01}, + {0x4603, 0xe0}, {0x4604, 0x01}, {0x4605, 0x10}}; + +static const struct ov5640_mode_config dvp_modes[] = { + { + .width = 160, + .height = 120, + .array_size_res_params = ARRAY_SIZE(dvp_160x120_res_params), + .res_params = dvp_160x120_res_params, + .max_frmrate = OV5640_60_FPS, + .def_frmrate = OV5640_30_FPS, + }, + { + .width = 320, + .height = 240, + .array_size_res_params = ARRAY_SIZE(dvp_320x240_res_params), + .res_params = dvp_320x240_res_params, + .max_frmrate = OV5640_60_FPS, + .def_frmrate = OV5640_30_FPS, + }, + { + .width = 480, + .height = 272, + .array_size_res_params = ARRAY_SIZE(dvp_480x272_res_params), + .res_params = dvp_480x272_res_params, + .max_frmrate = OV5640_60_FPS, + .def_frmrate = OV5640_30_FPS, + }}; -static const struct video_format_cap fmts[] = { +#define OV5640_VIDEO_FORMAT_CAP(width, height, format) \ + {.pixelformat = (format), \ + .width_min = (width), \ + .width_max = (width), \ + .height_min = (height), \ + .height_max = (height), \ + .width_step = 0, \ + .height_step = 0} + +static const struct video_format_cap csi2_fmts[] = { OV5640_VIDEO_FORMAT_CAP(1280, 720, VIDEO_PIX_FMT_RGB565), OV5640_VIDEO_FORMAT_CAP(1280, 720, VIDEO_PIX_FMT_YUYV), OV5640_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_RGB565), OV5640_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_YUYV), {0}}; +static const struct video_format_cap dvp_fmts[] = { + OV5640_VIDEO_FORMAT_CAP(160, 120, VIDEO_PIX_FMT_RGB565), + OV5640_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_RGB565), + OV5640_VIDEO_FORMAT_CAP(480, 272, VIDEO_PIX_FMT_RGB565), + {0}}; + +static inline bool ov5640_is_dvp(const struct device *dev) +{ + const struct ov5640_config *cfg = dev->config; + + return cfg->bus_type == VIDEO_BUS_TYPE_PARALLEL; +} + static int ov5640_read_reg(const struct i2c_dt_spec *spec, const uint16_t addr, void *val, const uint8_t val_size) { @@ -500,6 +678,34 @@ static int ov5640_write_multi_regs(const struct i2c_dt_spec *spec, const struct return 0; } +static int ov5640_set_fmt_dvp(const struct ov5640_config *cfg) +{ + int ret = 0; + + ret = ov5640_modify_reg(&cfg->i2c, TIMING_TC_REG21_REG, 0x20, 0x00); + + if (ret) { + LOG_ERR("Unable to configure REG: %d on DVP", TIMING_TC_REG21_REG); + return ret; + } + + ret = ov5640_modify_reg(&cfg->i2c, SYS_RESET02_REG, 0x1C, 0x1C); + + if (ret) { + LOG_ERR("Unable to configure REG: %d on DVP", SYS_RESET02_REG); + return ret; + } + + ret = ov5640_modify_reg(&cfg->i2c, SYS_CLK_ENABLE02_REG, 0x28, 0x00); + + if (ret) { + LOG_ERR("Unable to configure REG: %d on DVP", SYS_CLK_ENABLE02_REG); + return ret; + } + + return 0; +} + static int ov5640_set_frmival(const struct device *dev, enum video_endpoint_id ep, struct video_frmival *frmival) { @@ -509,6 +715,10 @@ static int ov5640_set_frmival(const struct device *dev, enum video_endpoint_id e uint8_t i, ind = 0; uint32_t desired_frmrate, best_match = ov5640_frame_rates[ind]; + if (ov5640_is_dvp(dev)) { + return -ENOTSUP; + } + desired_frmrate = DIV_ROUND_CLOSEST(frmival->denominator, frmival->numerator); /* Find the supported frame rate closest to the desired one */ @@ -556,8 +766,24 @@ static int ov5640_set_fmt(const struct device *dev, enum video_endpoint_id ep, const struct ov5640_config *cfg = dev->config; int ret, i; struct video_frmival def_frmival; + const struct video_format_cap *fmts; + const struct ov5640_mode_config *modes; + size_t num_fmts; + size_t array_size_modes; + + if (ov5640_is_dvp(dev)) { + fmts = dvp_fmts; + modes = dvp_modes; + num_fmts = ARRAY_SIZE(dvp_fmts); + array_size_modes = ARRAY_SIZE(dvp_modes); + } else { + fmts = csi2_fmts; + modes = csi2_modes; + num_fmts = ARRAY_SIZE(csi2_fmts); + array_size_modes = ARRAY_SIZE(csi2_modes); + } - for (i = 0; i < ARRAY_SIZE(fmts); ++i) { + for (i = 0; i < num_fmts; ++i) { if (fmt->pixelformat == fmts[i].pixelformat && fmt->width >= fmts[i].width_min && fmt->width <= fmts[i].width_max && fmt->height >= fmts[i].height_min && fmt->height <= fmts[i].height_max) { @@ -565,7 +791,7 @@ static int ov5640_set_fmt(const struct device *dev, enum video_endpoint_id ep, } } - if (i == ARRAY_SIZE(fmts)) { + if (i == num_fmts) { LOG_ERR("Unsupported pixel format or resolution"); return -ENOTSUP; } @@ -577,12 +803,10 @@ static int ov5640_set_fmt(const struct device *dev, enum video_endpoint_id ep, drv_data->fmt = *fmt; /* Set resolution */ - for (i = 0; i < ARRAY_SIZE(modes); i++) { + for (i = 0; i < array_size_modes; i++) { if (fmt->width == modes[i].width && fmt->height == modes[i].height) { ret = ov5640_write_multi_regs(&cfg->i2c, modes[i].res_params, - modes[i].res_params == hd_res_params - ? ARRAY_SIZE(hd_res_params) - : ARRAY_SIZE(low_res_params)); + modes[i].array_size_res_params); if (ret) { LOG_ERR("Unable to set resolution parameters"); return ret; @@ -610,6 +834,10 @@ static int ov5640_set_fmt(const struct device *dev, enum video_endpoint_id ep, return ret; } + if (ov5640_is_dvp(dev)) { + return ov5640_set_fmt_dvp(cfg); + } + /* Set frame rate */ def_frmival.denominator = drv_data->cur_mode->def_frmrate; def_frmival.numerator = 1; @@ -630,34 +858,25 @@ static int ov5640_get_fmt(const struct device *dev, enum video_endpoint_id ep, static int ov5640_get_caps(const struct device *dev, enum video_endpoint_id ep, struct video_caps *caps) { - caps->format_caps = fmts; + caps->format_caps = ov5640_is_dvp(dev) ? dvp_fmts : csi2_fmts; return 0; } -static int ov5640_stream_start(const struct device *dev) +static int ov5640_set_stream(const struct device *dev, bool enable) { const struct ov5640_config *cfg = dev->config; - /* Power up MIPI PHY HS Tx & LP Rx in 2 data lanes mode */ - int ret = ov5640_write_reg(&cfg->i2c, IO_MIPI_CTRL00_REG, 0x45); - if (ret) { - LOG_ERR("Unable to power up MIPI PHY"); - return ret; + if (!ov5640_is_dvp(dev)) { + /* Power up / down MIPI PHY HS Tx & LP Rx in 2 data lanes mode */ + int ret = ov5640_write_reg(&cfg->i2c, IO_MIPI_CTRL00_REG, enable ? 0x45 : 0x40); + if (ret) { + LOG_ERR("Unable to power up / down MIPI PHY"); + return ret; + } } - return ov5640_write_reg(&cfg->i2c, SYS_CTRL0_REG, SYS_CTRL0_SW_PWUP); -} - -static int ov5640_stream_stop(const struct device *dev) -{ - const struct ov5640_config *cfg = dev->config; - /* Power down MIPI PHY HS Tx & LP Rx */ - int ret = ov5640_write_reg(&cfg->i2c, IO_MIPI_CTRL00_REG, 0x40); - if (ret) { - LOG_ERR("Unable to power down MIPI PHY"); - return ret; - } - return ov5640_write_reg(&cfg->i2c, SYS_CTRL0_REG, SYS_CTRL0_SW_PWDN); + return ov5640_write_reg(&cfg->i2c, SYS_CTRL0_REG, + enable ? SYS_CTRL0_SW_PWUP : SYS_CTRL0_SW_PWDN); } #define TEST_PATTERN_ENABLE BIT(7) @@ -886,6 +1105,10 @@ static int ov5640_get_frmival(const struct device *dev, enum video_endpoint_id e { struct ov5640_data *drv_data = dev->data; + if (ov5640_is_dvp(dev)) { + return -ENOTSUP; + } + frmival->numerator = 1; frmival->denominator = drv_data->cur_frmrate; @@ -897,14 +1120,19 @@ static int ov5640_enum_frmival(const struct device *dev, enum video_endpoint_id { uint8_t i = 0; - for (i = 0; i < ARRAY_SIZE(modes); i++) { - if (fie->format->width == modes[i].width && - fie->format->height == modes[i].height) { + if (ov5640_is_dvp(dev)) { + return -ENOTSUP; + } + + for (i = 0; i < ARRAY_SIZE(csi2_modes); i++) { + if (fie->format->width == csi2_modes[i].width && + fie->format->height == csi2_modes[i].height) { break; } } - if (i == ARRAY_SIZE(modes) || fie->index >= ARRAY_SIZE(ov5640_frame_rates) || - ov5640_frame_rates[fie->index] > modes[i].max_frmrate) { + + if (i == ARRAY_SIZE(csi2_modes) || fie->index >= ARRAY_SIZE(ov5640_frame_rates) || + ov5640_frame_rates[fie->index] > csi2_modes[i].max_frmrate) { return -EINVAL; } @@ -919,8 +1147,7 @@ static DEVICE_API(video, ov5640_driver_api) = { .set_format = ov5640_set_fmt, .get_format = ov5640_get_fmt, .get_caps = ov5640_get_caps, - .stream_start = ov5640_stream_start, - .stream_stop = ov5640_stream_stop, + .set_stream = ov5640_set_stream, .set_ctrl = ov5640_set_ctrl, .get_ctrl = ov5640_get_ctrl, .set_frmival = ov5640_set_frmival, @@ -979,6 +1206,13 @@ static int ov5640_init(const struct device *dev) k_sleep(K_MSEC(20)); + /* Reset all registers */ + ret = ov5640_write_reg(&cfg->i2c, SCCB_SYS_CTRL1_REG, 0x11); + if (ret) { + LOG_ERR("Unable to write to reset all registers"); + return -EIO; + } + /* Software reset */ ret = ov5640_write_reg(&cfg->i2c, SYS_CTRL0_REG, SYS_CTRL0_SW_RST); if (ret) { @@ -989,17 +1223,29 @@ static int ov5640_init(const struct device *dev) k_sleep(K_MSEC(5)); /* Initialize register values */ - ret = ov5640_write_multi_regs(&cfg->i2c, init_params, ARRAY_SIZE(init_params)); + ret = ov5640_write_multi_regs(&cfg->i2c, init_params_common, + ARRAY_SIZE(init_params_common)); if (ret) { LOG_ERR("Unable to initialize the sensor"); return -EIO; } - /* Set virtual channel */ - ret = ov5640_modify_reg(&cfg->i2c, 0x4814, 3U << 6, (uint8_t)(DEFAULT_MIPI_CHANNEL) << 6); - if (ret) { - LOG_ERR("Unable to set virtual channel"); - return -EIO; + if (ov5640_is_dvp(dev)) { + ret = ov5640_write_multi_regs(&cfg->i2c, init_params_dvp, + ARRAY_SIZE(init_params_dvp)); + + if (ret) { + LOG_ERR("Unable to initialize the sensor with DVP parameters"); + return -EIO; + } + } else { + /* Set virtual channel */ + ret = ov5640_modify_reg(&cfg->i2c, 0x4814, 3U << 6, + (uint8_t)(DEFAULT_MIPI_CHANNEL) << 6); + if (ret) { + LOG_ERR("Unable to set virtual channel"); + return -EIO; + } } /* Check sensor chip id */ @@ -1016,8 +1262,15 @@ static int ov5640_init(const struct device *dev) /* Set default format */ fmt.pixelformat = VIDEO_PIX_FMT_RGB565; - fmt.width = 1280; - fmt.height = 720; + if (ov5640_is_dvp(dev)) { + /* Set default resolution to QQVGA (160x120) */ + fmt.width = 160; + fmt.height = 120; + } else { + /* Set default resolution to 720p */ + fmt.width = 1280; + fmt.height = 720; + } fmt.pitch = fmt.width * 2; ret = ov5640_set_fmt(dev, VIDEO_EP_OUT, &fmt); if (ret) { @@ -1035,6 +1288,8 @@ static int ov5640_init(const struct device *dev) .i2c = I2C_DT_SPEC_INST_GET(n), \ .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \ .powerdown_gpio = GPIO_DT_SPEC_INST_GET_OR(n, powerdown_gpios, {0}), \ + .bus_type = DT_PROP_OR(DT_CHILD(DT_INST_CHILD(n, port), endpoint), bus_type, \ + VIDEO_BUS_TYPE_CSI2_DPHY), \ }; \ \ DEVICE_DT_INST_DEFINE(n, &ov5640_init, NULL, &ov5640_data_##n, &ov5640_cfg_##n, \ diff --git a/drivers/video/ov7670.c b/drivers/video/ov7670.c index 84107a8bac596..37be06a762589 100644 --- a/drivers/video/ov7670.c +++ b/drivers/video/ov7670.c @@ -9,6 +9,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(video_ov7670, CONFIG_VIDEO_LOG_LEVEL); @@ -181,6 +182,8 @@ const struct ov7670_resolution_cfg OV7670_RESOLUTION_VGA = { /* OV7670 definitions */ #define OV7670_PROD_ID 0x76 +#define OV7670_MVFP_HFLIP 0x20 +#define OV7670_MVFP_VFLIP 0x10 #define OV7670_VIDEO_FORMAT_CAP(width, height, format) \ { \ @@ -204,11 +207,11 @@ static const struct video_format_cap fmts[] = { * Note that this table assumes the camera is fed a 6MHz XCLK signal */ static const struct ov7670_reg ov7670_init_regtbl[] = { - {OV7670_MVFP, 0x20}, /* MVFP: Mirror/VFlip,Normal image */ + {OV7670_MVFP, 0x00}, /* MVFP: Mirror/VFlip,Normal image */ /* configure the output timing */ - /* PCLK does not toggle during horizontal blank, one PCLK, one pixel */ - {OV7670_COM10, 0x20}, /* COM10 */ + /* Free running PCLK, default VSYNC, HSYNC and PCLK */ + {OV7670_COM10, 0x00}, /* COM10 */ {OV7670_COM12, 0x00}, /* COM12,No HREF when VSYNC is low */ /* Brightness Control, with signal -128 to +128, 0x00 is middle value */ {OV7670_BRIGHT, 0x2f}, @@ -253,7 +256,7 @@ static const struct ov7670_reg ov7670_init_regtbl[] = { /* display , need retain */ {OV7670_COM15, 0xD0}, /* Common Control 15 */ - {OV7670_TSLB, 0x0C}, /* Line Buffer Test Option */ + {OV7670_TSLB, 0x04}, /* Reserved */ {OV7670_COM13, 0x80}, /* Common Control 13 */ {OV7670_MANU, 0x11}, /* Manual U Value */ {OV7670_MANV, 0xFF}, /* Manual V Value */ @@ -547,10 +550,33 @@ static int ov7670_init(const struct device *dev) return 0; } +static int ov7670_set_stream(const struct device *dev, bool enable) +{ + return 0; +} + +static int ov7670_set_ctrl(const struct device *dev, unsigned int cid, void *value) +{ + const struct ov7670_config *config = dev->config; + + switch (cid) { + case VIDEO_CID_HFLIP: + return i2c_reg_update_byte_dt(&config->bus, OV7670_MVFP, + OV7670_MVFP_HFLIP, ((int)value) ? OV7670_MVFP_HFLIP : 0); + case VIDEO_CID_VFLIP: + return i2c_reg_update_byte_dt(&config->bus, OV7670_MVFP, + OV7670_MVFP_VFLIP, ((int)value) ? OV7670_MVFP_VFLIP : 0); + default: + return -ENOTSUP; + } +} + static DEVICE_API(video, ov7670_api) = { .set_format = ov7670_set_fmt, .get_format = ov7670_get_fmt, .get_caps = ov7670_get_caps, + .set_stream = ov7670_set_stream, + .set_ctrl = ov7670_set_ctrl, }; #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) diff --git a/drivers/video/ov7725.c b/drivers/video/ov7725.c index efcd8ab14d9b2..74d1d83401724 100644 --- a/drivers/video/ov7725.c +++ b/drivers/video/ov7725.c @@ -517,12 +517,7 @@ static int ov7725_get_fmt(const struct device *dev, return 0; } -static int ov7725_stream_start(const struct device *dev) -{ - return 0; -} - -static int ov7725_stream_stop(const struct device *dev) +static int ov7725_set_stream(const struct device *dev, bool enable) { return 0; } @@ -552,8 +547,7 @@ static DEVICE_API(video, ov7725_driver_api) = { .set_format = ov7725_set_fmt, .get_format = ov7725_get_fmt, .get_caps = ov7725_get_caps, - .stream_start = ov7725_stream_start, - .stream_stop = ov7725_stream_stop, + .set_stream = ov7725_set_stream, }; static int ov7725_init(const struct device *dev) diff --git a/drivers/video/video_common.c b/drivers/video/video_common.c index 6ff4c7b933858..5028a5f67a1a3 100644 --- a/drivers/video/video_common.c +++ b/drivers/video/video_common.c @@ -1,9 +1,12 @@ /* * Copyright (c) 2019, Linaro Limited + * Copyright (c) 2024, tinyVision.ai Inc. * * SPDX-License-Identifier: Apache-2.0 */ +#include + #include #include @@ -28,7 +31,7 @@ struct mem_block { static struct mem_block video_block[CONFIG_VIDEO_BUFFER_POOL_NUM_MAX]; -struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align) +struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_timeout_t timeout) { struct video_buffer *vbuf = NULL; struct mem_block *block; @@ -48,7 +51,7 @@ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align) } /* Alloc buffer memory */ - block->data = VIDEO_COMMON_HEAP_ALLOC(align, size, K_FOREVER); + block->data = VIDEO_COMMON_HEAP_ALLOC(align, size, timeout); if (block->data == NULL) { return NULL; } @@ -60,9 +63,9 @@ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align) return vbuf; } -struct video_buffer *video_buffer_alloc(size_t size) +struct video_buffer *video_buffer_alloc(size_t size, k_timeout_t timeout) { - return video_buffer_aligned_alloc(size, sizeof(void *)); + return video_buffer_aligned_alloc(size, sizeof(void *), timeout); } void video_buffer_release(struct video_buffer *vbuf) @@ -83,3 +86,81 @@ void video_buffer_release(struct video_buffer *vbuf) VIDEO_COMMON_FREE(block->data); } } + +int video_format_caps_index(const struct video_format_cap *fmts, const struct video_format *fmt, + size_t *idx) +{ + for (int i = 0; fmts[i].pixelformat != 0; i++) { + if (fmts[i].pixelformat == fmt->pixelformat && + IN_RANGE(fmt->width, fmts[i].width_min, fmts[i].width_max) && + IN_RANGE(fmt->height, fmts[i].height_min, fmts[i].height_max)) { + *idx = i; + return 0; + } + } + return -ENOENT; +} + +void video_closest_frmival_stepwise(const struct video_frmival_stepwise *stepwise, + const struct video_frmival *desired, + struct video_frmival *match) +{ + uint64_t min = stepwise->min.numerator; + uint64_t max = stepwise->max.numerator; + uint64_t step = stepwise->step.numerator; + uint64_t goal = desired->numerator; + + /* Set a common denominator to all values */ + min *= stepwise->max.denominator * stepwise->step.denominator * desired->denominator; + max *= stepwise->min.denominator * stepwise->step.denominator * desired->denominator; + step *= stepwise->min.denominator * stepwise->max.denominator * desired->denominator; + goal *= stepwise->min.denominator * stepwise->max.denominator * stepwise->step.denominator; + + /* Saturate the desired value to the min/max supported */ + goal = CLAMP(goal, min, max); + + /* Compute a numerator and denominator */ + match->numerator = min + DIV_ROUND_CLOSEST(goal - min, step) * step; + match->denominator = stepwise->min.denominator * stepwise->max.denominator * + stepwise->step.denominator * desired->denominator; +} + +void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival_enum *match) +{ + uint64_t best_diff_nsec = INT32_MAX; + struct video_frmival desired = match->discrete; + struct video_frmival_enum fie = {.format = match->format}; + + __ASSERT(match->type != VIDEO_FRMIVAL_TYPE_STEPWISE, + "cannot find range matching the range, only a value matching the range"); + + while (video_enum_frmival(dev, ep, &fie) == 0) { + struct video_frmival tmp = {0}; + uint64_t diff_nsec = 0, a, b; + + switch (fie.type) { + case VIDEO_FRMIVAL_TYPE_DISCRETE: + tmp = fie.discrete; + break; + case VIDEO_FRMIVAL_TYPE_STEPWISE: + video_closest_frmival_stepwise(&fie.stepwise, &desired, &tmp); + break; + default: + __ASSERT(false, "invalid answer from the queried video device"); + } + + a = video_frmival_nsec(&desired); + b = video_frmival_nsec(&tmp); + diff_nsec = a > b ? a - b : b - a; + if (diff_nsec < best_diff_nsec) { + best_diff_nsec = diff_nsec; + memcpy(&match->discrete, &tmp, sizeof(tmp)); + + /* The video_enum_frmival() function will increment fie.index every time. + * Compensate for it to get the current index, not the next index. + */ + match->index = fie.index - 1; + } + } +} diff --git a/drivers/video/video_emul_imager.c b/drivers/video/video_emul_imager.c new file mode 100644 index 0000000000000..c85c821472fa6 --- /dev/null +++ b/drivers/video/video_emul_imager.c @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2024 tinyVision.ai Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_video_emul_imager + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(video_emul_imager, CONFIG_VIDEO_LOG_LEVEL); + +#define EMUL_IMAGER_REG_SENSOR_ID 0x0000 +#define EMUL_IMAGER_SENSOR_ID 0x99 +#define EMUL_IMAGER_REG_CTRL 0x0001 +#define EMUL_IMAGER_REG_INIT1 0x0002 +#define EMUL_IMAGER_REG_INIT2 0x0003 +#define EMUL_IMAGER_REG_TIMING1 0x0004 +#define EMUL_IMAGER_REG_TIMING2 0x0005 +#define EMUL_IMAGER_REG_TIMING3 0x0006 +#define EMUL_IMAGER_REG_EXPOSURE 0x0007 +#define EMUL_IMAGER_REG_GAIN 0x0008 +#define EMUL_IMAGER_REG_PATTERN 0x0009 +#define EMUL_IMAGER_PATTERN_OFF 0x00 +#define EMUL_IMAGER_PATTERN_BARS1 0x01 +#define EMUL_IMAGER_PATTERN_BARS2 0x02 + +/* Emulated register bank */ +uint8_t emul_imager_fake_regs[10]; + +enum emul_imager_fmt_id { + RGB565_64x20, + YUYV_64x20, +}; + +struct emul_imager_reg { + uint16_t addr; + uint8_t value; +}; + +struct emul_imager_mode { + uint8_t fps; + /* List of registers lists to configure the various properties of the sensor. + * This permits to deduplicate the list of registers in case some lare sections + * are repeated across modes, such as the resolution for different FPS. + */ + const struct emul_imager_reg *regs[2]; + /* More fields can be added according to the needs of the sensor driver */ +}; + +struct emul_imager_config { + struct i2c_dt_spec i2c; +}; + +struct emul_imager_data { + /* First field is a framebuffer for I/O emulation purpose */ + uint8_t framebuffer[CONFIG_VIDEO_EMUL_IMAGER_FRAMEBUFFER_SIZE]; + /* Other fields are shared with real hardware drivers */ + const struct emul_imager_mode *mode; + enum emul_imager_fmt_id fmt_id; + struct video_format fmt; +}; + +/* Initial parameters of the sensors common to all modes. */ +static const struct emul_imager_reg emul_imager_init_regs[] = { + {EMUL_IMAGER_REG_CTRL, 0x00}, + /* Example comment about REG_INIT1 */ + {EMUL_IMAGER_REG_INIT1, 0x10}, + {EMUL_IMAGER_REG_INIT2, 0x00}, + {0}, +}; + +/* List of registers aggregated together in "modes" that can be applied + * to set the timing parameters and other mode-dependent configuration. + */ + +static const struct emul_imager_reg emul_imager_rgb565_64x20[] = { + {EMUL_IMAGER_REG_TIMING1, 0x64}, + {EMUL_IMAGER_REG_TIMING2, 0x20}, + {0}, +}; +static const struct emul_imager_reg emul_imager_rgb565_64x20_15fps[] = { + {EMUL_IMAGER_REG_TIMING3, 15}, + {0}, +}; +static const struct emul_imager_reg emul_imager_rgb565_64x20_30fps[] = { + {EMUL_IMAGER_REG_TIMING3, 30}, + {0}, +}; +static const struct emul_imager_reg emul_imager_rgb565_64x20_60fps[] = { + {EMUL_IMAGER_REG_TIMING3, 60}, + {0}, +}; +struct emul_imager_mode emul_imager_rgb565_64x20_modes[] = { + {.fps = 15, .regs = {emul_imager_rgb565_64x20, emul_imager_rgb565_64x20_15fps}}, + {.fps = 30, .regs = {emul_imager_rgb565_64x20, emul_imager_rgb565_64x20_30fps}}, + {.fps = 60, .regs = {emul_imager_rgb565_64x20, emul_imager_rgb565_64x20_60fps}}, + {0}, +}; + +static const struct emul_imager_reg emul_imager_yuyv_64x20[] = { + {EMUL_IMAGER_REG_TIMING1, 0x64}, + {EMUL_IMAGER_REG_TIMING2, 0x20}, + {0}, +}; +static const struct emul_imager_reg emul_imager_yuyv_64x20_15fps[] = { + {EMUL_IMAGER_REG_TIMING3, 15}, + {0}, +}; +static const struct emul_imager_reg emul_imager_yuyv_64x20_30fps[] = { + {EMUL_IMAGER_REG_TIMING3, 30}, + {0}, +}; +struct emul_imager_mode emul_imager_yuyv_64x20_modes[] = { + {.fps = 15, .regs = {emul_imager_yuyv_64x20, emul_imager_yuyv_64x20_15fps}}, + {.fps = 30, .regs = {emul_imager_yuyv_64x20, emul_imager_yuyv_64x20_30fps}}, + {0}, +}; + +/* Summary of all the modes of all the frame formats, with the format ID as + * index, matching fmts[]. + */ +static const struct emul_imager_mode *emul_imager_modes[] = { + [RGB565_64x20] = emul_imager_rgb565_64x20_modes, + [YUYV_64x20] = emul_imager_yuyv_64x20_modes, +}; + +/* Video device capabilities where the supported resolutions and pixel formats are listed. + * The format ID is used as index to fetch the matching mode from the list above. + */ +#define EMUL_IMAGER_VIDEO_FORMAT_CAP(width, height, format) \ + { \ + .pixelformat = (format), \ + .width_min = (width), \ + .width_max = (width), \ + .height_min = (height), \ + .height_max = (height), \ + .width_step = 0, \ + .height_step = 0, \ + } +static const struct video_format_cap fmts[] = { + [RGB565_64x20] = EMUL_IMAGER_VIDEO_FORMAT_CAP(64, 20, VIDEO_PIX_FMT_RGB565), + [YUYV_64x20] = EMUL_IMAGER_VIDEO_FORMAT_CAP(64, 20, VIDEO_PIX_FMT_YUYV), + {0}, +}; + +/* Emulated I2C register interface, to replace with actual I2C calls for real hardware */ +static int emul_imager_read_reg(const struct device *const dev, uint8_t reg_addr, uint8_t *value) +{ + LOG_DBG("%s placeholder for I2C read from 0x%02x", dev->name, reg_addr); + switch (reg_addr) { + case EMUL_IMAGER_REG_SENSOR_ID: + *value = EMUL_IMAGER_SENSOR_ID; + break; + default: + *value = emul_imager_fake_regs[reg_addr]; + } + return 0; +} + +/* Helper to read a full integer directly from a register */ +static int emul_imager_read_int(const struct device *const dev, uint8_t reg_addr, int *value) +{ + uint8_t val8; + int ret; + + ret = emul_imager_read_reg(dev, reg_addr, &val8); + *value = val8; + return ret; +} + +/* Some sensors will need reg8 or reg16 variants. */ +static int emul_imager_write_reg(const struct device *const dev, uint8_t reg_addr, uint8_t value) +{ + LOG_DBG("%s placeholder for I2C write 0x%08x to 0x%02x", dev->name, value, reg_addr); + emul_imager_fake_regs[reg_addr] = value; + return 0; +} + +static int emul_imager_write_multi(const struct device *const dev, + const struct emul_imager_reg *regs) +{ + int ret; + + for (int i = 0; regs[i].addr != 0; i++) { + ret = emul_imager_write_reg(dev, regs[i].addr, regs[i].value); + if (ret < 0) { + return ret; + } + } + return 0; +} + +static int emul_imager_set_ctrl(const struct device *dev, unsigned int cid, void *value) +{ + switch (cid) { + case VIDEO_CID_EXPOSURE: + return emul_imager_write_reg(dev, EMUL_IMAGER_REG_EXPOSURE, (int)value); + case VIDEO_CID_GAIN: + return emul_imager_write_reg(dev, EMUL_IMAGER_REG_GAIN, (int)value); + case VIDEO_CID_TEST_PATTERN: + return emul_imager_write_reg(dev, EMUL_IMAGER_REG_PATTERN, (int)value); + default: + return -ENOTSUP; + } +} + +static int emul_imager_get_ctrl(const struct device *dev, unsigned int cid, void *value) +{ + struct emul_imager_data *data = dev->data; + + switch (cid) { + case VIDEO_CID_EXPOSURE: + return emul_imager_read_int(dev, EMUL_IMAGER_REG_EXPOSURE, value); + case VIDEO_CID_GAIN: + return emul_imager_read_int(dev, EMUL_IMAGER_REG_GAIN, value); + case VIDEO_CID_TEST_PATTERN: + return emul_imager_read_int(dev, EMUL_IMAGER_REG_PATTERN, value); + case VIDEO_CID_PIXEL_RATE: + *(int64_t *)value = (int64_t)data->fmt.width * data->fmt.pitch * data->mode->fps; + return 0; + default: + return -ENOTSUP; + } +} + +/* Customize this function according to your "struct emul_imager_mode". */ +static int emul_imager_set_mode(const struct device *dev, const struct emul_imager_mode *mode) +{ + struct emul_imager_data *data = dev->data; + int ret; + + if (data->mode == mode) { + return 0; + } + + LOG_DBG("Applying mode %p at %d FPS", mode, mode->fps); + + /* Apply all the configuration registers for that mode */ + for (int i = 0; i < 2; i++) { + ret = emul_imager_write_multi(dev, mode->regs[i]); + if (ret < 0) { + goto err; + } + } + + data->mode = mode; + return 0; +err: + LOG_ERR("Could not apply %s mode %p (%u FPS)", dev->name, mode, mode->fps); + return ret; +} + +static int emul_imager_set_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival *frmival) +{ + struct emul_imager_data *data = dev->data; + struct video_frmival_enum fie = {.format = &data->fmt, .discrete = *frmival}; + + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + video_closest_frmival(dev, ep, &fie); + LOG_DBG("Applying frame interval number %u", fie.index); + return emul_imager_set_mode(dev, &emul_imager_modes[data->fmt_id][fie.index]); +} + +static int emul_imager_get_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival *frmival) +{ + struct emul_imager_data *data = dev->data; + + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + frmival->numerator = 1; + frmival->denominator = data->mode->fps; + return 0; +} + +static int emul_imager_enum_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival_enum *fie) +{ + const struct emul_imager_mode *mode; + size_t fmt_id; + int ret; + + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + ret = video_format_caps_index(fmts, fie->format, &fmt_id); + if (ret < 0) { + return ret; + } + + mode = &emul_imager_modes[fmt_id][fie->index]; + + fie->type = VIDEO_FRMIVAL_TYPE_DISCRETE; + fie->discrete.numerator = 1; + fie->discrete.denominator = mode->fps; + fie->index++; + + return mode->fps == 0; +} + +/* White, Yellow, Cyan, Green, Magenta, Red, Blue, Black */ +static const uint16_t pattern_8bars_yuv[8][3] = { + {0xFF, 0x7F, 0x7F}, {0xFF, 0x00, 0xFF}, {0xFF, 0xFF, 0x00}, {0x7F, 0x00, 0x00}, + {0x00, 0xFF, 0xFF}, {0x00, 0x00, 0xFF}, {0x00, 0xFF, 0x00}, {0x00, 0x7F, 0x7F}}; +static const uint16_t pattern_8bars_rgb[8][3] = { + {0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0x00}, {0x00, 0xFF, 0xFF}, {0x00, 0xFF, 0x00}, + {0xFF, 0x00, 0xFF}, {0xFF, 0x00, 0x00}, {0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00}}; +static void emul_imager_fill_framebuffer(const struct device *const dev, struct video_format *fmt) +{ + struct emul_imager_data *data = dev->data; + uint16_t *fb16 = (uint16_t *)data->framebuffer; + uint16_t r, g, b, y, uv; + + /* Fill the first row of the emulated framebuffer */ + switch (fmt->pixelformat) { + case VIDEO_PIX_FMT_YUYV: + for (size_t i = 0; i < fmt->width; i++) { + y = pattern_8bars_yuv[i * 8 / fmt->width][0]; + uv = pattern_8bars_yuv[i * 8 / fmt->width][1 + i % 2]; + fb16[i] = sys_cpu_to_be16(y << 8 | uv << 0); + } + break; + case VIDEO_PIX_FMT_RGB565: + for (size_t i = 0; i < fmt->width; i++) { + r = pattern_8bars_rgb[i * 8 / fmt->width][0] >> (8 - 5); + g = pattern_8bars_rgb[i * 8 / fmt->width][1] >> (8 - 6); + b = pattern_8bars_rgb[i * 8 / fmt->width][2] >> (8 - 5); + fb16[i] = sys_cpu_to_le16((r << 11) | (g << 6) | (b << 0)); + } + break; + default: + LOG_WRN("Unsupported pixel format %x, supported: %x, %x", fmt->pixelformat, + VIDEO_PIX_FMT_YUYV, VIDEO_PIX_FMT_RGB565); + memset(fb16, 0, fmt->pitch); + } + + /* Duplicate the first row over the whole frame */ + for (size_t i = 1; i < fmt->height; i++) { + memcpy(data->framebuffer + fmt->pitch * i, data->framebuffer, fmt->pitch); + } +} + +static int emul_imager_set_fmt(const struct device *const dev, enum video_endpoint_id ep, + struct video_format *fmt) +{ + struct emul_imager_data *data = dev->data; + size_t fmt_id; + int ret; + + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + if (fmt->pitch * fmt->height > CONFIG_VIDEO_EMUL_IMAGER_FRAMEBUFFER_SIZE) { + LOG_ERR("%s has %u bytes of memory, unable to support %x %ux%u (%u bytes)", + dev->name, CONFIG_VIDEO_EMUL_IMAGER_FRAMEBUFFER_SIZE, fmt->pixelformat, + fmt->width, fmt->height, fmt->pitch * fmt->height); + return -ENOMEM; + } + + if (memcmp(&data->fmt, fmt, sizeof(data->fmt)) == 0) { + return 0; + } + + ret = video_format_caps_index(fmts, fmt, &fmt_id); + if (ret < 0) { + LOG_ERR("Format %x %ux%u not found for %s", fmt->pixelformat, fmt->width, + fmt->height, dev->name); + return ret; + } + + ret = emul_imager_set_mode(dev, &emul_imager_modes[fmt_id][0]); + if (ret < 0) { + return ret; + } + + /* Change the image pattern on the framebuffer */ + emul_imager_fill_framebuffer(dev, fmt); + + data->fmt_id = fmt_id; + data->fmt = *fmt; + return 0; +} + +static int emul_imager_get_fmt(const struct device *dev, enum video_endpoint_id ep, + struct video_format *fmt) +{ + struct emul_imager_data *data = dev->data; + + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + *fmt = data->fmt; + return 0; +} + +static int emul_imager_get_caps(const struct device *dev, enum video_endpoint_id ep, + struct video_caps *caps) +{ + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + caps->format_caps = fmts; + return 0; +} + +static int emul_imager_set_stream(const struct device *dev, bool enable) +{ + return emul_imager_write_reg(dev, EMUL_IMAGER_REG_CTRL, enable ? 1 : 0); +} + +static DEVICE_API(video, emul_imager_driver_api) = { + .set_ctrl = emul_imager_set_ctrl, + .get_ctrl = emul_imager_get_ctrl, + .set_frmival = emul_imager_set_frmival, + .get_frmival = emul_imager_get_frmival, + .enum_frmival = emul_imager_enum_frmival, + .set_format = emul_imager_set_fmt, + .get_format = emul_imager_get_fmt, + .get_caps = emul_imager_get_caps, + .set_stream = emul_imager_set_stream, +}; + +int emul_imager_init(const struct device *dev) +{ + struct video_format fmt; + uint8_t sensor_id; + int ret; + + if (/* !i2c_is_ready_dt(&cfg->i2c) */ false) { + /* LOG_ERR("Bus %s is not ready", cfg->i2c.bus->name); */ + return -ENODEV; + } + + ret = emul_imager_read_reg(dev, EMUL_IMAGER_REG_SENSOR_ID, &sensor_id); + if (ret < 0 || sensor_id != EMUL_IMAGER_SENSOR_ID) { + LOG_ERR("Failed to get %s correct sensor ID (0x%x", dev->name, sensor_id); + return ret; + } + + ret = emul_imager_write_multi(dev, emul_imager_init_regs); + if (ret < 0) { + LOG_ERR("Could not set %s initial registers", dev->name); + return ret; + } + + fmt.pixelformat = fmts[0].pixelformat; + fmt.width = fmts[0].width_min; + fmt.height = fmts[0].height_min; + fmt.pitch = fmt.width * 2; + + ret = emul_imager_set_fmt(dev, VIDEO_EP_OUT, &fmt); + if (ret < 0) { + LOG_ERR("Failed to set %s to default format %x %ux%u", dev->name, fmt.pixelformat, + fmt.width, fmt.height); + } + + return 0; +} + +#define EMUL_IMAGER_DEFINE(inst) \ + static struct emul_imager_data emul_imager_data_##inst; \ + \ + static const struct emul_imager_config emul_imager_cfg_##inst = { \ + .i2c = /* I2C_DT_SPEC_INST_GET(inst) */ {0}, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &emul_imager_init, NULL, &emul_imager_data_##inst, \ + &emul_imager_cfg_##inst, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \ + &emul_imager_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(EMUL_IMAGER_DEFINE) diff --git a/drivers/video/video_emul_rx.c b/drivers/video/video_emul_rx.c new file mode 100644 index 0000000000000..3965416812204 --- /dev/null +++ b/drivers/video/video_emul_rx.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2024 tinyVision.ai Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_video_emul_rx + +#include + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(video_emul_rx, CONFIG_VIDEO_LOG_LEVEL); + +struct emul_rx_config { + const struct device *source_dev; +}; + +struct emul_rx_data { + const struct device *dev; + struct video_format fmt; + struct k_work work; + struct k_fifo fifo_in; + struct k_fifo fifo_out; +}; + +static int emul_rx_set_ctrl(const struct device *dev, unsigned int cid, void *value) +{ + const struct emul_rx_config *cfg = dev->config; + + /* Forward all controls to the source */ + return video_set_ctrl(cfg->source_dev, cid, value); +} + +static int emul_rx_get_ctrl(const struct device *dev, unsigned int cid, void *value) +{ + const struct emul_rx_config *cfg = dev->config; + + /* Forward all controls to the source */ + return video_get_ctrl(cfg->source_dev, cid, value); +} + +static int emul_rx_set_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival *frmival) +{ + const struct emul_rx_config *cfg = dev->config; + + /* Input/output timing is driven by the source */ + if (ep != VIDEO_EP_IN && ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + return video_set_frmival(cfg->source_dev, VIDEO_EP_OUT, frmival); +} + +static int emul_rx_get_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival *frmival) +{ + const struct emul_rx_config *cfg = dev->config; + + /* Input/output timing is driven by the source */ + if (ep != VIDEO_EP_IN && ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + return video_get_frmival(cfg->source_dev, VIDEO_EP_OUT, frmival); +} + +static int emul_rx_enum_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival_enum *fie) +{ + const struct emul_rx_config *cfg = dev->config; + + /* Input/output timing is driven by the source */ + if (ep != VIDEO_EP_IN && ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + return video_enum_frmival(cfg->source_dev, VIDEO_EP_OUT, fie); +} + +static int emul_rx_set_fmt(const struct device *const dev, enum video_endpoint_id ep, + struct video_format *fmt) +{ + const struct emul_rx_config *cfg = dev->config; + struct emul_rx_data *data = dev->data; + int ret; + + /* The same format is shared between input and output: data is just passed through */ + if (ep != VIDEO_EP_IN && ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + /* Propagate the format selection to the source */ + ret = video_set_format(cfg->source_dev, VIDEO_EP_OUT, fmt); + if (ret < 0) { + LOG_DBG("Failed to set %s format to %x %ux%u", cfg->source_dev->name, + fmt->pixelformat, fmt->width, fmt->height); + return -EINVAL; + } + + /* Cache the format selected locally to use it for getting the size of the buffer */ + data->fmt = *fmt; + return 0; +} + +static int emul_rx_get_fmt(const struct device *dev, enum video_endpoint_id ep, + struct video_format *fmt) +{ + struct emul_rx_data *data = dev->data; + + /* Input/output caps are the same as the source: data is just passed through */ + if (ep != VIDEO_EP_IN && ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + *fmt = data->fmt; + return 0; +} + +static int emul_rx_get_caps(const struct device *dev, enum video_endpoint_id ep, + struct video_caps *caps) +{ + const struct emul_rx_config *cfg = dev->config; + + /* Input/output caps are the same as the source: data is just passed through */ + if (ep != VIDEO_EP_IN && ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + return video_get_caps(cfg->source_dev, VIDEO_EP_OUT, caps); +} + +static int emul_rx_set_stream(const struct device *dev, bool enable) +{ + const struct emul_rx_config *cfg = dev->config; + + /* A real hardware driver would first start / stop its own peripheral */ + return enable ? video_stream_start(cfg->source_dev) : video_stream_stop(cfg->source_dev); +} + +static void emul_rx_worker(struct k_work *work) +{ + struct emul_rx_data *data = CONTAINER_OF(work, struct emul_rx_data, work); + const struct device *dev = data->dev; + const struct emul_rx_config *cfg = dev->config; + struct video_format *fmt = &data->fmt; + struct video_buffer *vbuf = vbuf; + + LOG_DBG("Queueing a frame of %u bytes in format %x %ux%u", fmt->pitch * fmt->height, + fmt->pixelformat, fmt->width, fmt->height); + + while ((vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT)) != NULL) { + vbuf->bytesused = fmt->pitch * fmt->height; + vbuf->line_offset = 0; + + LOG_DBG("Inserting %u bytes into buffer %p", vbuf->bytesused, vbuf->buffer); + + /* Simulate the MIPI/DVP hardware transferring image data from the imager to the + * video buffer memory using DMA. The vbuf->size is checked in emul_rx_enqueue(). + */ + memcpy(vbuf->buffer, cfg->source_dev->data, vbuf->bytesused); + + /* Once the buffer is completed, submit it to the video buffer */ + k_fifo_put(&data->fifo_out, vbuf); + } +} + +static int emul_rx_enqueue(const struct device *dev, enum video_endpoint_id ep, + struct video_buffer *vbuf) +{ + struct emul_rx_data *data = dev->data; + struct video_format *fmt = &data->fmt; + + /* Can only enqueue a buffer to get data out, data input is from hardware */ + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + if (vbuf->size < fmt->pitch * fmt->height) { + LOG_ERR("Buffer too small for a full frame"); + return -ENOMEM; + } + + /* The buffer has not been filled yet: flag as emtpy */ + vbuf->bytesused = 0; + + /* Submit the buffer for processing in the worker, where everything happens */ + k_fifo_put(&data->fifo_in, vbuf); + k_work_submit(&data->work); + + return 0; +} + +static int emul_rx_dequeue(const struct device *dev, enum video_endpoint_id ep, + struct video_buffer **vbufp, k_timeout_t timeout) +{ + struct emul_rx_data *data = dev->data; + + /* Can only dequeue a buffer to get data out, data input is from hardware */ + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + /* All the processing is expected to happen in the worker */ + *vbufp = k_fifo_get(&data->fifo_out, timeout); + if (*vbufp == NULL) { + return -EAGAIN; + } + + return 0; +} + +static int emul_rx_flush(const struct device *dev, enum video_endpoint_id ep, bool cancel) +{ + struct emul_rx_data *data = dev->data; + struct k_work_sync sync; + + /* Can only flush the buffer going out, data input is from hardware */ + if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL) { + return -EINVAL; + } + + if (cancel) { + struct video_buffer *vbuf; + + /* Cancel the jobs that were not running */ + k_work_cancel(&data->work); + + /* Flush the jobs that were still running */ + k_work_flush(&data->work, &sync); + + /* Empty all the cancelled items */ + while ((vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT))) { + k_fifo_put(&data->fifo_out, vbuf); + } + } else { + /* Process all the remaining items from the queue */ + k_work_flush(&data->work, &sync); + } + + return 0; +} + +static DEVICE_API(video, emul_rx_driver_api) = { + .set_ctrl = emul_rx_set_ctrl, + .get_ctrl = emul_rx_get_ctrl, + .set_frmival = emul_rx_set_frmival, + .get_frmival = emul_rx_get_frmival, + .enum_frmival = emul_rx_enum_frmival, + .set_format = emul_rx_set_fmt, + .get_format = emul_rx_get_fmt, + .get_caps = emul_rx_get_caps, + .set_stream = emul_rx_set_stream, + .enqueue = emul_rx_enqueue, + .dequeue = emul_rx_dequeue, + .flush = emul_rx_flush, +}; + +int emul_rx_init(const struct device *dev) +{ + struct emul_rx_data *data = dev->data; + const struct emul_rx_config *cfg = dev->config; + int ret; + + data->dev = dev; + + if (!device_is_ready(cfg->source_dev)) { + LOG_ERR("Source device %s is not ready", cfg->source_dev->name); + return -ENODEV; + } + + ret = video_get_format(cfg->source_dev, VIDEO_EP_OUT, &data->fmt); + if (ret < 0) { + return ret; + } + + k_fifo_init(&data->fifo_in); + k_fifo_init(&data->fifo_out); + k_work_init(&data->work, &emul_rx_worker); + + return 0; +} + +#define EMUL_RX_DEFINE(n) \ + static const struct emul_rx_config emul_rx_cfg_##n = { \ + .source_dev = \ + DEVICE_DT_GET(DT_NODE_REMOTE_DEVICE(DT_INST_ENDPOINT_BY_ID(n, 0, 0))), \ + }; \ + \ + static struct emul_rx_data emul_rx_data_##n = { \ + .dev = DEVICE_DT_INST_GET(n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, &emul_rx_init, NULL, &emul_rx_data_##n, &emul_rx_cfg_##n, \ + POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &emul_rx_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(EMUL_RX_DEFINE) diff --git a/drivers/video/video_esp32_dvp.c b/drivers/video/video_esp32_dvp.c index b93f81dc5cec9..a4e243f46b6e9 100644 --- a/drivers/video/video_esp32_dvp.c +++ b/drivers/video/video_esp32_dvp.c @@ -133,7 +133,7 @@ void video_esp32_dma_rx_done(const struct device *dev, void *user_data, uint32_t video_esp32_reload_dma(data); } -static int video_esp32_stream_start(const struct device *dev) +static int video_esp32_set_stream(const struct device *dev, bool enable) { const struct video_esp32_config *cfg = dev->config; struct video_esp32_data *data = dev->data; @@ -143,6 +143,25 @@ static int video_esp32_stream_start(const struct device *dev) uint32_t buffer_size = 0; int error = 0; + if (!enable) { + LOG_DBG("Stop streaming"); + + if (video_stream_stop(cfg->source_dev)) { + return -EIO; + } + + data->is_streaming = false; + error = dma_stop(cfg->dma_dev, cfg->rx_dma_channel); + if (error) { + LOG_ERR("Unable to stop DMA (%d)", error); + return error; + } + + cam_hal_stop_streaming(&data->hal); + + return 0; + } + if (data->is_streaming) { return -EBUSY; } @@ -219,29 +238,6 @@ static int video_esp32_stream_start(const struct device *dev) return 0; } -static int video_esp32_stream_stop(const struct device *dev) -{ - const struct video_esp32_config *cfg = dev->config; - struct video_esp32_data *data = dev->data; - int ret = 0; - - LOG_DBG("Stop streaming"); - - if (video_stream_stop(cfg->source_dev)) { - return -EIO; - } - - data->is_streaming = false; - ret = dma_stop(cfg->dma_dev, cfg->rx_dma_channel); - if (ret) { - LOG_ERR("Unable to stop DMA (%d)", ret); - return ret; - } - - cam_hal_stop_streaming(&data->hal); - return 0; -} - static int video_esp32_get_caps(const struct device *dev, enum video_endpoint_id ep, struct video_caps *caps) { @@ -400,8 +396,7 @@ static DEVICE_API(video, esp32_driver_api) = { /* mandatory callbacks */ .set_format = video_esp32_set_fmt, .get_format = video_esp32_get_fmt, - .stream_start = video_esp32_stream_start, - .stream_stop = video_esp32_stream_stop, + .set_stream = video_esp32_set_stream, .get_caps = video_esp32_get_caps, /* optional callbacks */ .enqueue = video_esp32_enqueue, diff --git a/drivers/video/video_mcux_csi.c b/drivers/video/video_mcux_csi.c index a9224145e1c0c..34f80b8e2c06f 100644 --- a/drivers/video/video_mcux_csi.c +++ b/drivers/video/video_mcux_csi.c @@ -18,16 +18,6 @@ #include #endif -#if defined(CONFIG_VIDEO_MCUX_MIPI_CSI2RX) -#define DEVICE_DT_INST_GET_SOURCE_DEV(n) \ - DEVICE_DT_GET(DT_PARENT(DT_GPARENT(DT_NODELABEL(DT_STRING_TOKEN( \ - DT_CHILD(DT_INST_CHILD(n, port), endpoint), remote_endpoint_label))))) -#else -#define DEVICE_DT_INST_GET_SOURCE_DEV(n) \ - DEVICE_DT_GET(DT_GPARENT(DT_NODELABEL(DT_STRING_TOKEN( \ - DT_CHILD(DT_INST_CHILD(n, port), endpoint), remote_endpoint_label)))) -#endif - struct video_mcux_csi_config { CSI_Type *base; const struct device *source_dev; @@ -133,7 +123,7 @@ static inline void video_pix_fmt_convert(struct video_format *fmt, bool isGetFmt break; } - fmt->pitch = fmt->width * video_pix_fmt_bpp(fmt->pixelformat); + fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE; } #endif @@ -142,7 +132,7 @@ static int video_mcux_csi_set_fmt(const struct device *dev, enum video_endpoint_ { const struct video_mcux_csi_config *config = dev->config; struct video_mcux_csi_data *data = dev->data; - unsigned int bpp = video_pix_fmt_bpp(fmt->pixelformat); + unsigned int bpp = video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE; status_t ret; struct video_format format = *fmt; @@ -204,37 +194,30 @@ static int video_mcux_csi_get_fmt(const struct device *dev, enum video_endpoint_ return -EIO; } -static int video_mcux_csi_stream_start(const struct device *dev) +static int video_mcux_csi_set_stream(const struct device *dev, bool enable) { const struct video_mcux_csi_config *config = dev->config; struct video_mcux_csi_data *data = dev->data; status_t ret; - ret = CSI_TransferStart(config->base, &data->csi_handle); - if (ret != kStatus_Success) { - return -EIO; - } - - if (config->source_dev && video_stream_start(config->source_dev)) { - return -EIO; - } - - return 0; -} - -static int video_mcux_csi_stream_stop(const struct device *dev) -{ - const struct video_mcux_csi_config *config = dev->config; - struct video_mcux_csi_data *data = dev->data; - status_t ret; + if (enable) { + ret = CSI_TransferStart(config->base, &data->csi_handle); + if (ret != kStatus_Success) { + return -EIO; + } - if (config->source_dev && video_stream_stop(config->source_dev)) { - return -EIO; - } + if (config->source_dev && video_stream_start(config->source_dev)) { + return -EIO; + } + } else { + if (config->source_dev && video_stream_stop(config->source_dev)) { + return -EIO; + } - ret = CSI_TransferStop(config->base, &data->csi_handle); - if (ret != kStatus_Success) { - return -EIO; + ret = CSI_TransferStop(config->base, &data->csi_handle); + if (ret != kStatus_Success) { + return -EIO; + } } return 0; @@ -481,8 +464,7 @@ static int video_mcux_csi_enum_frmival(const struct device *dev, enum video_endp static DEVICE_API(video, video_mcux_csi_driver_api) = { .set_format = video_mcux_csi_set_fmt, .get_format = video_mcux_csi_get_fmt, - .stream_start = video_mcux_csi_stream_start, - .stream_stop = video_mcux_csi_stream_stop, + .set_stream = video_mcux_csi_set_stream, .flush = video_mcux_csi_flush, .enqueue = video_mcux_csi_enqueue, .dequeue = video_mcux_csi_dequeue, @@ -502,7 +484,7 @@ PINCTRL_DT_INST_DEFINE(0); static const struct video_mcux_csi_config video_mcux_csi_config_0 = { .base = (CSI_Type *)DT_INST_REG_ADDR(0), - .source_dev = DEVICE_DT_INST_GET_SOURCE_DEV(0), + .source_dev = DEVICE_DT_GET(DT_NODE_REMOTE_DEVICE(DT_INST_ENDPOINT_BY_ID(0, 0, 0))), .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), }; diff --git a/drivers/video/video_mcux_mipi_csi2rx.c b/drivers/video/video_mcux_mipi_csi2rx.c index e625fe7adb0ba..4c9dfa6135ee7 100644 --- a/drivers/video/video_mcux_mipi_csi2rx.c +++ b/drivers/video/video_mcux_mipi_csi2rx.c @@ -21,11 +21,6 @@ LOG_MODULE_REGISTER(video_mipi_csi2rx, CONFIG_VIDEO_LOG_LEVEL); #define ABS(a, b) (a > b ? a - b : b - a) -#define DEVICE_DT_INST_GET_SENSOR_DEV(n) \ - DEVICE_DT_GET(DT_GPARENT(DT_NODELABEL( \ - DT_STRING_TOKEN(DT_CHILD(DT_CHILD(DT_INST_CHILD(n, ports), port_1), endpoint), \ - remote_endpoint_label)))) - struct mipi_csi2rx_config { const MIPI_CSI2RX_Type *base; const struct device *sensor_dev; @@ -78,8 +73,8 @@ static int mipi_csi2rx_update_settings(const struct device *dev, enum video_endp return -ENOTSUP; } - bpp = video_pix_fmt_bpp(fmt.pixelformat) * 8; - sensor_byte_clk = sensor_pixel_rate * bpp / drv_data->csi2rxConfig.laneNum / 8; + bpp = video_bits_per_pixel(fmt.pixelformat); + sensor_byte_clk = sensor_pixel_rate * bpp / drv_data->csi2rxConfig.laneNum / BITS_PER_BYTE; ret = clock_control_get_rate(drv_data->clock_dev, drv_data->clock_root, &root_clk_rate); if (ret) { @@ -151,30 +146,24 @@ static int mipi_csi2rx_get_fmt(const struct device *dev, enum video_endpoint_id return 0; } -static int mipi_csi2rx_stream_start(const struct device *dev) +static int mipi_csi2rx_set_stream(const struct device *dev, bool enable) { const struct mipi_csi2rx_config *config = dev->config; - struct mipi_csi2rx_data *drv_data = dev->data; - - CSI2RX_Init((MIPI_CSI2RX_Type *)config->base, &drv_data->csi2rxConfig); - - if (video_stream_start(config->sensor_dev)) { - return -EIO; - } - - return 0; -} -static int mipi_csi2rx_stream_stop(const struct device *dev) -{ - const struct mipi_csi2rx_config *config = dev->config; + if (enable) { + struct mipi_csi2rx_data *drv_data = dev->data; - if (video_stream_stop(config->sensor_dev)) { - return -EIO; + CSI2RX_Init((MIPI_CSI2RX_Type *)config->base, &drv_data->csi2rxConfig); + if (video_stream_start(config->sensor_dev)) { + return -EIO; + } + } else { + if (video_stream_stop(config->sensor_dev)) { + return -EIO; + } + CSI2RX_Deinit((MIPI_CSI2RX_Type *)config->base); } - CSI2RX_Deinit((MIPI_CSI2RX_Type *)config->base); - return 0; } @@ -229,7 +218,7 @@ static int mipi_csi2rx_get_frmival(const struct device *dev, enum video_endpoint static uint64_t mipi_csi2rx_cal_frame_size(const struct video_format *fmt) { - return fmt->height * fmt->width * video_pix_fmt_bpp(fmt->pixelformat) * 8; + return fmt->height * fmt->width * video_bits_per_pixel(fmt->pixelformat); } static uint64_t mipi_csi2rx_estimate_pixel_rate(const struct video_frmival *cur_fmival, @@ -315,8 +304,7 @@ static DEVICE_API(video, mipi_csi2rx_driver_api) = { .get_caps = mipi_csi2rx_get_caps, .get_format = mipi_csi2rx_get_fmt, .set_format = mipi_csi2rx_set_fmt, - .stream_start = mipi_csi2rx_stream_start, - .stream_stop = mipi_csi2rx_stream_stop, + .set_stream = mipi_csi2rx_set_stream, .set_ctrl = mipi_csi2rx_set_ctrl, .set_frmival = mipi_csi2rx_set_frmival, .get_frmival = mipi_csi2rx_get_frmival, @@ -349,9 +337,7 @@ static int mipi_csi2rx_init(const struct device *dev) #define MIPI_CSI2RX_INIT(n) \ static struct mipi_csi2rx_data mipi_csi2rx_data_##n = { \ - .csi2rxConfig.laneNum = \ - DT_PROP_LEN(DT_CHILD(DT_CHILD(DT_INST_CHILD(n, ports), port_1), endpoint), \ - data_lanes), \ + .csi2rxConfig.laneNum = DT_PROP_LEN(DT_INST_ENDPOINT_BY_ID(n, 1, 0), data_lanes), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_root = (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(n, 0, name), \ .clock_ui = (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(n, 1, name), \ @@ -360,7 +346,8 @@ static int mipi_csi2rx_init(const struct device *dev) \ static const struct mipi_csi2rx_config mipi_csi2rx_config_##n = { \ .base = (MIPI_CSI2RX_Type *)DT_INST_REG_ADDR(n), \ - .sensor_dev = DEVICE_DT_INST_GET_SENSOR_DEV(n), \ + .sensor_dev = \ + DEVICE_DT_GET(DT_NODE_REMOTE_DEVICE(DT_INST_ENDPOINT_BY_ID(n, 1, 0))), \ }; \ \ DEVICE_DT_INST_DEFINE(n, &mipi_csi2rx_init, NULL, &mipi_csi2rx_data_##n, \ diff --git a/drivers/video/video_mcux_smartdma.c b/drivers/video/video_mcux_smartdma.c index 7cf200b11cfd9..d6f04ad81d368 100644 --- a/drivers/video/video_mcux_smartdma.c +++ b/drivers/video/video_mcux_smartdma.c @@ -93,13 +93,17 @@ static void nxp_video_sdma_callback(const struct device *dev, void *user_data, data->buf_reload_flag = !data->buf_reload_flag; } -static int nxp_video_sdma_stream_start(const struct device *dev) +static int nxp_video_sdma_set_stream(const struct device *dev, bool enable) { const struct nxp_video_sdma_config *config = dev->config; struct nxp_video_sdma_data *data = dev->data; struct dma_config sdma_config = {0}; int ret; + if (!enable) { + return dma_stop(config->dma_dev, 0); + } + /* Setup dma configuration for SmartDMA */ sdma_config.dma_slot = kSMARTDMA_CameraDiv16FrameQVGA; sdma_config.dma_callback = nxp_video_sdma_callback; @@ -142,14 +146,6 @@ static int nxp_video_sdma_stream_start(const struct device *dev) return 0; } -static int nxp_video_sdma_stream_stop(const struct device *dev) -{ - const struct nxp_video_sdma_config *config = dev->config; - - /* Stop DMA engine */ - return dma_stop(config->dma_dev, 0); -} - static int nxp_video_sdma_enqueue(const struct device *dev, enum video_endpoint_id ep, struct video_buffer *vbuf) @@ -170,7 +166,7 @@ static int nxp_video_sdma_enqueue(const struct device *dev, k_fifo_put(&data->fifo_in, vbuf); if (data->stream_starved) { /* Kick SmartDMA off */ - nxp_video_sdma_stream_start(dev); + nxp_video_sdma_set_stream(dev, true); } return 0; } @@ -361,8 +357,7 @@ static DEVICE_API(video, nxp_video_sdma_api) = { .get_format = nxp_video_sdma_get_format, .set_format = nxp_video_sdma_set_format, .get_caps = nxp_video_sdma_get_caps, - .stream_start = nxp_video_sdma_stream_start, - .stream_stop = nxp_video_sdma_stream_stop, + .set_stream = nxp_video_sdma_set_stream, .enqueue = nxp_video_sdma_enqueue, .dequeue = nxp_video_sdma_dequeue, .flush = nxp_video_sdma_flush diff --git a/drivers/video/video_stm32_dcmi.c b/drivers/video/video_stm32_dcmi.c index 599d1a5d5a1bd..7369b3a39f577 100644 --- a/drivers/video/video_stm32_dcmi.c +++ b/drivers/video/video_stm32_dcmi.c @@ -22,7 +22,9 @@ LOG_MODULE_REGISTER(video_stm32_dcmi, CONFIG_VIDEO_LOG_LEVEL); -K_HEAP_DEFINE(video_stm32_buffer_pool, CONFIG_VIDEO_BUFFER_POOL_SZ_MAX); +#if CONFIG_VIDEO_BUFFER_POOL_NUM_MAX < 2 +#error "The minimum required number of buffers for video_stm32 is 2" +#endif typedef void (*irq_config_func_t)(const struct device *dev); @@ -43,7 +45,7 @@ struct video_stm32_dcmi_data { uint32_t height; uint32_t width; uint32_t pitch; - uint8_t *buffer; + struct video_buffer *vbuf; }; struct video_stm32_dcmi_config { @@ -75,7 +77,7 @@ void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) } vbuf->timestamp = k_uptime_get_32(); - memcpy(vbuf->buffer, dev_data->buffer, vbuf->bytesused); + memcpy(vbuf->buffer, dev_data->vbuf->buffer, vbuf->bytesused); k_fifo_put(&dev_data->fifo_out, vbuf); @@ -198,12 +200,16 @@ static int video_stm32_dcmi_set_fmt(const struct device *dev, { const struct video_stm32_dcmi_config *config = dev->config; struct video_stm32_dcmi_data *data = dev->data; - unsigned int bpp = video_pix_fmt_bpp(fmt->pixelformat); + unsigned int bpp = video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE; if (bpp == 0 || (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL)) { return -EINVAL; } + if ((fmt->pitch * fmt->height) > CONFIG_VIDEO_BUFFER_POOL_SZ_MAX) { + return -EINVAL; + } + data->pixel_format = fmt->pixelformat; data->pitch = fmt->pitch; data->height = fmt->height; @@ -240,48 +246,44 @@ static int video_stm32_dcmi_get_fmt(const struct device *dev, return 0; } -static int video_stm32_dcmi_stream_start(const struct device *dev) +static int video_stm32_dcmi_set_stream(const struct device *dev, bool enable) { + int err; struct video_stm32_dcmi_data *data = dev->data; const struct video_stm32_dcmi_config *config = dev->config; - size_t buffer_size = data->pitch * data->height; - data->buffer = k_heap_alloc(&video_stm32_buffer_pool, buffer_size, K_NO_WAIT); - if (data->buffer == NULL) { - LOG_ERR("Failed to allocate DCMI buffer for image. Size %d bytes", buffer_size); - return -ENOMEM; - } + if (!enable) { + if (video_stream_stop(config->sensor_dev)) { + return -EIO; + } - int err = HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS, - (uint32_t)data->buffer, buffer_size / 4); - if (err != HAL_OK) { - LOG_ERR("Failed to start DCMI DMA"); - return -EIO; - } + err = HAL_DCMI_Stop(&data->hdcmi); + if (err != HAL_OK) { + LOG_ERR("Failed to stop DCMI"); + return -EIO; + } - if (video_stream_start(config->sensor_dev)) { - return -EIO; + /* Release the video buffer allocated when start streaming */ + k_fifo_put(&data->fifo_in, data->vbuf); + + return 0; } - return 0; -} + data->vbuf = k_fifo_get(&data->fifo_in, K_NO_WAIT); -static int video_stm32_dcmi_stream_stop(const struct device *dev) -{ - struct video_stm32_dcmi_data *data = dev->data; - const struct video_stm32_dcmi_config *config = dev->config; - int err; + if (data->vbuf == NULL) { + LOG_ERR("Failed to dequeue a DCMI buffer."); + return -ENOMEM; + } - if (video_stream_stop(config->sensor_dev)) { + err = HAL_DCMI_Start_DMA(&data->hdcmi, DCMI_MODE_CONTINUOUS, + (uint32_t)data->vbuf->buffer, data->vbuf->bytesused / 4); + if (err != HAL_OK) { + LOG_ERR("Failed to start DCMI DMA"); return -EIO; } - /* Release the buffer allocated in stream_start */ - k_heap_free(&video_stm32_buffer_pool, data->buffer); - - err = HAL_DCMI_Stop(&data->hdcmi); - if (err != HAL_OK) { - LOG_ERR("Failed to stop DCMI"); + if (video_stream_start(config->sensor_dev)) { return -EIO; } @@ -375,8 +377,7 @@ static inline int video_stm32_dcmi_get_ctrl(const struct device *dev, unsigned i static DEVICE_API(video, video_stm32_dcmi_driver_api) = { .set_format = video_stm32_dcmi_set_fmt, .get_format = video_stm32_dcmi_get_fmt, - .stream_start = video_stm32_dcmi_stream_start, - .stream_stop = video_stm32_dcmi_stream_stop, + .set_stream = video_stm32_dcmi_set_stream, .enqueue = video_stm32_dcmi_enqueue, .dequeue = video_stm32_dcmi_dequeue, .get_caps = video_stm32_dcmi_get_caps, diff --git a/drivers/video/video_sw_generator.c b/drivers/video/video_sw_generator.c index c786d9c26b5eb..d9f0d90e8e0ee 100644 --- a/drivers/video/video_sw_generator.c +++ b/drivers/video/video_sw_generator.c @@ -99,20 +99,15 @@ static int video_sw_generator_get_fmt(const struct device *dev, enum video_endpo return 0; } -static int video_sw_generator_stream_start(const struct device *dev) +static int video_sw_generator_set_stream(const struct device *dev, bool enable) { struct video_sw_generator_data *data = dev->data; - k_work_schedule(&data->buf_work, K_MSEC(1000 / data->frame_rate)); - - return 0; -} - -static int video_sw_generator_stream_stop(const struct device *dev) -{ - struct video_sw_generator_data *data = dev->data; - - k_work_cancel_delayable_sync(&data->buf_work, &data->work_sync); + if (enable) { + k_work_schedule(&data->buf_work, K_MSEC(1000 / data->frame_rate)); + } else { + k_work_cancel_delayable_sync(&data->buf_work, &data->work_sync); + } return 0; } @@ -340,8 +335,7 @@ static int video_sw_generator_enum_frmival(const struct device *dev, enum video_ static DEVICE_API(video, video_sw_generator_driver_api) = { .set_format = video_sw_generator_set_fmt, .get_format = video_sw_generator_get_fmt, - .stream_start = video_sw_generator_stream_start, - .stream_stop = video_sw_generator_stream_stop, + .set_stream = video_sw_generator_set_stream, .flush = video_sw_generator_flush, .enqueue = video_sw_generator_enqueue, .dequeue = video_sw_generator_dequeue, diff --git a/drivers/w1/w1_shell.c b/drivers/w1/w1_shell.c index 2526258c2f23e..2f2674edd3f69 100644 --- a/drivers/w1/w1_shell.c +++ b/drivers/w1/w1_shell.c @@ -52,7 +52,7 @@ static int cmd_w1_reset_bus(const struct shell *sh, size_t argc, char **argv) const struct device *dev; int ret; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[1]); return -EINVAL; @@ -74,7 +74,7 @@ static int cmd_w1_read_bit(const struct shell *sh, size_t argc, char **argv) const struct device *dev; int ret; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[1]); return -EINVAL; @@ -98,7 +98,7 @@ static int cmd_w1_read_byte(const struct shell *sh, size_t argc, char **argv) const struct device *dev; int ret; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[1]); return -EINVAL; @@ -124,7 +124,7 @@ static int cmd_w1_read_block(const struct shell *sh, size_t argc, char **argv) size_t read_len; int ret; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[1]); return -EINVAL; @@ -165,7 +165,7 @@ static int cmd_w1_write_bit(const struct shell *sh, size_t argc, char **argv) unsigned long input = strtoul(argv[2], NULL, 0); int ret; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[1]); return -EINVAL; @@ -194,7 +194,7 @@ static int cmd_w1_write_byte(const struct shell *sh, size_t argc, char **argv) bool reset = false; int ret; - dev = device_get_binding(argv[pos]); + dev = shell_device_get_binding(argv[pos]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[pos]); return -EINVAL; @@ -243,7 +243,7 @@ static int cmd_w1_write_block(const struct shell *sh, size_t argc, char **argv) bool reset = false; int ret; - dev = device_get_binding(argv[pos]); + dev = shell_device_get_binding(argv[pos]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[1]); return -EINVAL; @@ -297,7 +297,7 @@ static int cmd_w1_configure(const struct shell *sh, size_t argc, char **argv) uint32_t type = strtoul(type_name, &type_endptr, 0); uint32_t value = strtoul(argv[3], NULL, 0); - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[1]); return -EINVAL; @@ -350,7 +350,7 @@ static int cmd_w1_search(const struct shell *sh, size_t argc, char **argv) const struct device *dev; int ret; - dev = device_get_binding(argv[1]); + dev = shell_device_get_binding(argv[1]); if (!dev) { shell_error(sh, W1DEV_X_NOT_FOUND, argv[1]); return -EINVAL; diff --git a/drivers/watchdog/CMakeLists.txt b/drivers/watchdog/CMakeLists.txt index e2ebb95cc76d9..79c715d4bce5f 100644 --- a/drivers/watchdog/CMakeLists.txt +++ b/drivers/watchdog/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_WDT_ITE_IT8XXX2 wdt_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_WDT_LITEX wdt_litex.c) zephyr_library_sources_ifdef(CONFIG_WDT_MAX32 wdt_max32.c) zephyr_library_sources_ifdef(CONFIG_WDT_MCUX_IMX_WDOG wdt_mcux_imx_wdog.c) +zephyr_library_sources_ifdef(CONFIG_WDT_MCUX_RTWDOG wdt_mcux_rtwdog.c) zephyr_library_sources_ifdef(CONFIG_WDT_MCUX_WDOG wdt_mcux_wdog.c) zephyr_library_sources_ifdef(CONFIG_WDT_MCUX_WDOG32 wdt_mcux_wdog32.c) zephyr_library_sources_ifdef(CONFIG_WDT_MCUX_WWDT wdt_mcux_wwdt.c) @@ -31,6 +32,7 @@ zephyr_library_sources_ifdef(CONFIG_WDT_NPM6001 wdt_npm6001.c) zephyr_library_sources_ifdef(CONFIG_WDT_NRFX wdt_nrfx.c) zephyr_library_sources_ifdef(CONFIG_WDT_RPI_PICO wdt_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_WDT_SAM wdt_sam.c) +zephyr_library_sources_ifdef(CONFIG_WDT_SAM4L wdt_sam4l.c) zephyr_library_sources_ifdef(CONFIG_WDT_SAM0 wdt_sam0.c) zephyr_library_sources_ifdef(CONFIG_WDT_SIFIVE wdt_sifive.c) zephyr_library_sources_ifdef(CONFIG_WDT_TCO wdt_tco.c) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 36515a1f7e464..0bc9652ebc93f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -20,6 +20,11 @@ config WDT_DISABLE_AT_BOOT help Disable watchdog at Zephyr system startup. +config HAS_WDT_NO_CALLBACKS + bool + help + Watchdog driver does not support callbacks. + module = WDT module-str = watchdog source "subsys/logging/Kconfig.template.log_config" @@ -64,9 +69,11 @@ source "drivers/watchdog/Kconfig.stm32" source "drivers/watchdog/Kconfig.cmsdk_apb" +source "drivers/watchdog/Kconfig.esp32" + source "drivers/watchdog/Kconfig.sam" -source "drivers/watchdog/Kconfig.esp32" +source "drivers/watchdog/Kconfig.sam4l" source "drivers/watchdog/Kconfig.sam0" diff --git a/drivers/watchdog/Kconfig.gd32 b/drivers/watchdog/Kconfig.gd32 index 7d149f17b50ae..17c4e4a42618e 100644 --- a/drivers/watchdog/Kconfig.gd32 +++ b/drivers/watchdog/Kconfig.gd32 @@ -14,6 +14,7 @@ config WWDGT_GD32 bool "GD32 Window watchdog timer (WWDGT) Driver" default y depends on DT_HAS_GD_GD32_WWDGT_ENABLED + select HAS_WDT_NO_CALLBACKS select USE_GD32_WWDGT help Enable the Window watchdog timer (WWDGT) driver for GD32 SoCs. diff --git a/drivers/watchdog/Kconfig.mcux b/drivers/watchdog/Kconfig.mcux index 32ccd4c782234..a604bdd3c69bf 100644 --- a/drivers/watchdog/Kconfig.mcux +++ b/drivers/watchdog/Kconfig.mcux @@ -37,3 +37,10 @@ config WDT_MCUX_WWDT_WARNING_INTERRUPT_CFG the number of watchdog counter ticks before timeout. endif # WDT_MCUX_WWDT + +config WDT_MCUX_RTWDOG + bool "MCUX RTWDOG driver" + default y + depends on DT_HAS_NXP_RTWDOG_ENABLED + help + Enable the mcux rtwdog driver. diff --git a/drivers/watchdog/Kconfig.rpi_pico b/drivers/watchdog/Kconfig.rpi_pico index a48d1c49fef1b..cc12dc4f837fc 100644 --- a/drivers/watchdog/Kconfig.rpi_pico +++ b/drivers/watchdog/Kconfig.rpi_pico @@ -6,6 +6,7 @@ config WDT_RPI_PICO default y depends on DT_HAS_RASPBERRYPI_PICO_WATCHDOG_ENABLED select HAS_WDT_DISABLE_AT_BOOT + select HAS_WDT_NO_CALLBACKS config WDT_RPI_PICO_INITIAL_TIMEOUT int "Default watchdog timeout in us" diff --git a/drivers/watchdog/Kconfig.sam4l b/drivers/watchdog/Kconfig.sam4l new file mode 100644 index 0000000000000..5a212c163bd86 --- /dev/null +++ b/drivers/watchdog/Kconfig.sam4l @@ -0,0 +1,10 @@ +# Copyright (C) 2024-2025, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +config WDT_SAM4L + bool "Atmel SAM4L MCU Family Watchdog (WDT) Driver" + default y + depends on DT_HAS_ATMEL_SAM4L_WATCHDOG_ENABLED + select HAS_WDT_DISABLE_AT_BOOT + help + Enable WDT driver for Atmel SAM4L MCUs. diff --git a/drivers/watchdog/Kconfig.smartbond b/drivers/watchdog/Kconfig.smartbond index 9978a8332cbbe..ba0da834ddc21 100644 --- a/drivers/watchdog/Kconfig.smartbond +++ b/drivers/watchdog/Kconfig.smartbond @@ -8,6 +8,7 @@ config WDT_SMARTBOND default y depends on DT_HAS_RENESAS_SMARTBOND_WATCHDOG_ENABLED select HAS_WDT_DISABLE_AT_BOOT + select HAS_WDT_NO_CALLBACKS if !WDT_SMARTBOND_NMI help Enable watchdog driver for Smartbond line of MCUs diff --git a/drivers/watchdog/Kconfig.stm32 b/drivers/watchdog/Kconfig.stm32 index b35a4c7b97d76..35ad0e4b9c224 100644 --- a/drivers/watchdog/Kconfig.stm32 +++ b/drivers/watchdog/Kconfig.stm32 @@ -10,6 +10,7 @@ menuconfig IWDG_STM32 default y depends on DT_HAS_ST_STM32_WATCHDOG_ENABLED select HAS_WDT_DISABLE_AT_BOOT + select HAS_WDT_NO_CALLBACKS help Enable IWDG driver for STM32 line of MCUs diff --git a/drivers/watchdog/Kconfig.tco b/drivers/watchdog/Kconfig.tco index 7439ffbc8918c..e3e235552d99f 100644 --- a/drivers/watchdog/Kconfig.tco +++ b/drivers/watchdog/Kconfig.tco @@ -8,5 +8,6 @@ config WDT_TCO default y depends on DT_HAS_INTEL_TCO_WDT_ENABLED select HAS_WDT_DISABLE_AT_BOOT + select HAS_WDT_NO_CALLBACKS help Enable support for Intel TCO WDT driver. diff --git a/drivers/watchdog/Kconfig.ti_tps382x b/drivers/watchdog/Kconfig.ti_tps382x index 9ff0400af3ef9..31eeb566afe6b 100644 --- a/drivers/watchdog/Kconfig.ti_tps382x +++ b/drivers/watchdog/Kconfig.ti_tps382x @@ -7,6 +7,7 @@ config WDT_TI_TPS382X default y depends on DT_HAS_TI_TPS382X_ENABLED depends on GPIO + select HAS_WDT_NO_CALLBACKS help Enable WDT driver for TI TPS382x. This is an external IC and requires a GPIO connection from the processor. diff --git a/drivers/watchdog/wdt_iwdg_stm32.c b/drivers/watchdog/wdt_iwdg_stm32.c index da045de447c74..f472d03eb481f 100644 --- a/drivers/watchdog/wdt_iwdg_stm32.c +++ b/drivers/watchdog/wdt_iwdg_stm32.c @@ -84,8 +84,8 @@ static void iwdg_stm32_convert_timeout(uint32_t timeout, static int iwdg_stm32_setup(const struct device *dev, uint8_t options) { - struct iwdg_stm32_data *data = IWDG_STM32_DATA(dev); - IWDG_TypeDef *iwdg = IWDG_STM32_STRUCT(dev); + const struct iwdg_stm32_config *cfg = dev->config; + struct iwdg_stm32_data *data = dev->data; uint32_t tickstart; /* Deactivate running when debugger is attached. */ @@ -111,23 +111,23 @@ static int iwdg_stm32_setup(const struct device *dev, uint8_t options) } /* Enable the IWDG now and write IWDG registers at the same time */ - LL_IWDG_Enable(iwdg); - LL_IWDG_EnableWriteAccess(iwdg); + LL_IWDG_Enable(cfg->instance); + LL_IWDG_EnableWriteAccess(cfg->instance); /* Write the prescaler and reload counter to the IWDG registers*/ - LL_IWDG_SetPrescaler(iwdg, data->prescaler); - LL_IWDG_SetReloadCounter(iwdg, data->reload); + LL_IWDG_SetPrescaler(cfg->instance, data->prescaler); + LL_IWDG_SetReloadCounter(cfg->instance, data->reload); tickstart = k_uptime_get_32(); /* Wait for the update operation completed */ - while (LL_IWDG_IsReady(iwdg) == 0) { + while (LL_IWDG_IsReady(cfg->instance) == 0) { if ((k_uptime_get_32() - tickstart) > IWDG_SR_UPDATE_TIMEOUT) { return -ENODEV; } } /* Reload counter just before leaving */ - LL_IWDG_ReloadCounter(iwdg); + LL_IWDG_ReloadCounter(cfg->instance); return 0; } @@ -143,7 +143,7 @@ static int iwdg_stm32_disable(const struct device *dev) static int iwdg_stm32_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *config) { - struct iwdg_stm32_data *data = IWDG_STM32_DATA(dev); + struct iwdg_stm32_data *data = dev->data; uint32_t timeout = config->window.max * USEC_PER_MSEC; uint32_t prescaler = 0U; uint32_t reload = 0U; @@ -151,6 +151,10 @@ static int iwdg_stm32_install_timeout(const struct device *dev, if (config->callback != NULL) { return -ENOTSUP; } + if (data->reload) { + /* Timeout has already been configured */ + return -ENOMEM; + } /* Calculating parameters to be applied later, on setup */ iwdg_stm32_convert_timeout(timeout, &prescaler, &reload); @@ -171,10 +175,10 @@ static int iwdg_stm32_install_timeout(const struct device *dev, static int iwdg_stm32_feed(const struct device *dev, int channel_id) { - IWDG_TypeDef *iwdg = IWDG_STM32_STRUCT(dev); + const struct iwdg_stm32_config *cfg = dev->config; ARG_UNUSED(channel_id); - LL_IWDG_ReloadCounter(iwdg); + LL_IWDG_ReloadCounter(cfg->instance); return 0; } @@ -210,11 +214,12 @@ static int iwdg_stm32_init(const struct device *dev) return 0; } -static struct iwdg_stm32_data iwdg_stm32_dev_data = { - .Instance = (IWDG_TypeDef *)DT_INST_REG_ADDR(0) +static const struct iwdg_stm32_config iwdg_stm32_dev_cfg = { + .instance = (IWDG_TypeDef *)DT_INST_REG_ADDR(0), }; +static struct iwdg_stm32_data iwdg_stm32_dev_data; DEVICE_DT_INST_DEFINE(0, iwdg_stm32_init, NULL, - &iwdg_stm32_dev_data, NULL, + &iwdg_stm32_dev_data, &iwdg_stm32_dev_cfg, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &iwdg_stm32_api); diff --git a/drivers/watchdog/wdt_iwdg_stm32.h b/drivers/watchdog/wdt_iwdg_stm32.h index d953f61b99df3..2d3e5a81570b4 100644 --- a/drivers/watchdog/wdt_iwdg_stm32.h +++ b/drivers/watchdog/wdt_iwdg_stm32.h @@ -20,18 +20,14 @@ * */ -/* driver data */ -struct iwdg_stm32_data { +struct iwdg_stm32_config { /* IWDG peripheral instance. */ - IWDG_TypeDef *Instance; + IWDG_TypeDef *instance; +}; + +struct iwdg_stm32_data { uint32_t prescaler; uint32_t reload; }; -#define IWDG_STM32_DATA(dev) \ - ((struct iwdg_stm32_data * const)(dev)->data) - -#define IWDG_STM32_STRUCT(dev) \ - ((IWDG_TypeDef *)(IWDG_STM32_DATA(dev))->Instance) - #endif /* ZEPHYR_DRIVERS_WATCHDOG_IWDG_STM32_H_ */ diff --git a/drivers/watchdog/wdt_mcux_rtwdog.c b/drivers/watchdog/wdt_mcux_rtwdog.c new file mode 100644 index 0000000000000..57a026917dc3a --- /dev/null +++ b/drivers/watchdog/wdt_mcux_rtwdog.c @@ -0,0 +1,225 @@ +/* + * Copyright 2024, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_rtwdog + +#include +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL +#include +#include +LOG_MODULE_REGISTER(wdt_mcux_rtwdog); + +#define MSEC_TO_RTWDOG_TICKS(clock_freq, divider, msec) \ + ((uint32_t)(clock_freq * msec / 1000U / divider)) + +#define RTWDOG_MIN_TIMEOUT 1U + +struct mcux_rtwdog_config { + RTWDOG_Type *base; + uint32_t clock_frequency; + rtwdog_clock_source_t clk_source; + rtwdog_clock_prescaler_t clk_divider; + void (*irq_config_func)(const struct device *dev); +}; + +struct mcux_rtwdog_data { + wdt_callback_t callback; + rtwdog_config_t wdog_config; + bool timeout_valid; + bool enabled; +}; + +static int mcux_rtwdog_setup(const struct device *dev, uint8_t options) +{ + const struct mcux_rtwdog_config *config = dev->config; + struct mcux_rtwdog_data *data = dev->data; + RTWDOG_Type *base = config->base; + + if (!data->timeout_valid) { + LOG_ERR("No valid timeouts installed"); + return -EINVAL; + } + + if (data->enabled) { + LOG_ERR("This watchdog has been enabled"); + return -EBUSY; + } + + if ((options & WDT_OPT_PAUSE_IN_SLEEP) != 0U) { + LOG_ERR("Not support WDT_OPT_PAUSE_IN_SLEEP"); + return -ENOTSUP; + } + + data->wdog_config.workMode.enableDebug = ((options & WDT_OPT_PAUSE_HALTED_BY_DBG) == 0U); + + RTWDOG_Init(base, &data->wdog_config); + data->enabled = true; + LOG_DBG("Setup the watchdog"); + + return 0; +} + +static int mcux_rtwdog_disable(const struct device *dev) +{ + const struct mcux_rtwdog_config *config = dev->config; + struct mcux_rtwdog_data *data = dev->data; + RTWDOG_Type *base = config->base; + + data->timeout_valid = false; + + if (!data->enabled) { + LOG_ERR("Disabled when watchdog is not enabled"); + return -EFAULT; + } + + RTWDOG_Deinit(base); + data->enabled = false; + LOG_DBG("Disabled the watchdog"); + + return 0; +} + +static int mcux_rtwdog_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *cfg) +{ + const struct mcux_rtwdog_config *config = dev->config; + struct mcux_rtwdog_data *data = dev->data; + uint32_t clock_freq; + uint32_t clk_divider; + + if (data->enabled) { + LOG_ERR("Timeout can not be installed while watchdog has already been setup"); + return -EBUSY; + } + + if (data->timeout_valid) { + LOG_ERR("No more timeouts can be installed"); + return -ENOMEM; + } + + if (cfg->flags == WDT_FLAG_RESET_NONE) { + LOG_ERR("Not support WDT_FLAG_RESET_NONE"); + return -ENOTSUP; + } + + RTWDOG_GetDefaultConfig(&data->wdog_config); + + clock_freq = config->clock_frequency; + clk_divider = config->clk_divider == kRTWDOG_ClockPrescalerDivide1 ? 1U : 256U; + + data->wdog_config.clockSource = config->clk_source; + data->wdog_config.prescaler = config->clk_divider; + data->wdog_config.timeoutValue = + MSEC_TO_RTWDOG_TICKS(clock_freq, clk_divider, cfg->window.max); + + if (data->wdog_config.timeoutValue > UINT16_MAX) { + LOG_ERR("Invalid window max"); + return -EINVAL; + } + + if (cfg->window.min != 0U) { + data->wdog_config.enableWindowMode = true; + data->wdog_config.windowValue = + MSEC_TO_RTWDOG_TICKS(clock_freq, clk_divider, cfg->window.min); + } else { + data->wdog_config.enableWindowMode = false; + data->wdog_config.windowValue = 0; + } + + if ((data->wdog_config.timeoutValue < RTWDOG_MIN_TIMEOUT) || + (data->wdog_config.timeoutValue <= data->wdog_config.windowValue)) { + LOG_ERR("Invalid timeout"); + return -EINVAL; + } + + data->wdog_config.enableInterrupt = cfg->callback != NULL; + data->callback = cfg->callback; + data->timeout_valid = true; + + return 0; +} + +static int mcux_rtwdog_feed(const struct device *dev, int channel_id) +{ + const struct mcux_rtwdog_config *config = dev->config; + struct mcux_rtwdog_data *data = dev->data; + RTWDOG_Type *base = config->base; + + if (channel_id != 0) { + LOG_ERR("Invalid channel id"); + return -EINVAL; + } + + if (!data->enabled) { + LOG_ERR("Feed disabled watchdog"); + return -EINVAL; + } + + RTWDOG_Refresh(base); + LOG_DBG("Fed the watchdog"); + + return 0; +} + +static void mcux_rtwdog_isr(const struct device *dev) +{ + const struct mcux_rtwdog_config *config = dev->config; + struct mcux_rtwdog_data *data = dev->data; + RTWDOG_Type *base = config->base; + + RTWDOG_ClearStatusFlags(base, kRTWDOG_InterruptFlag); + + if (data->callback) { + data->callback(dev, 0); + } +} + +static int mcux_rtwdog_init(const struct device *dev) +{ + const struct mcux_rtwdog_config *config = dev->config; + + config->irq_config_func(dev); + + return 0; +} + +static DEVICE_API(wdt, mcux_rtwdog_api) = { + .setup = mcux_rtwdog_setup, + .disable = mcux_rtwdog_disable, + .install_timeout = mcux_rtwdog_install_timeout, + .feed = mcux_rtwdog_feed, +}; + +#define TO_RTWDOG_CLK_SRC(val) _DO_CONCAT(kRTWDOG_ClockSource, val) +#define TO_RTWDOG_CLK_DIV(val) _DO_CONCAT(kRTWDOG_ClockPrescalerDivide, val) + +#define MCUX_RTWDOG_INIT(n) \ + \ + static struct mcux_rtwdog_data mcux_rtwdog_data_##n; \ + static void mcux_rtwdog_config_func_##n(const struct device *dev); \ + \ + static const struct mcux_rtwdog_config mcux_rtwdog_config_##n = { \ + .base = (RTWDOG_Type *)DT_INST_REG_ADDR(n), \ + .irq_config_func = mcux_rtwdog_config_func_##n, \ + .clock_frequency = DT_INST_PROP_BY_PHANDLE(n, clocks, clock_frequency), \ + .clk_source = TO_RTWDOG_CLK_SRC(DT_INST_PROP(n, clk_source)), \ + .clk_divider = TO_RTWDOG_CLK_DIV(DT_INST_PROP(n, clk_divider)), \ + }; \ + static void mcux_rtwdog_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), mcux_rtwdog_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + }; \ + DEVICE_DT_INST_DEFINE(n, &mcux_rtwdog_init, NULL, &mcux_rtwdog_data_##n, \ + &mcux_rtwdog_config_##n, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &mcux_rtwdog_api); + +DT_INST_FOREACH_STATUS_OKAY(MCUX_RTWDOG_INIT) diff --git a/drivers/watchdog/wdt_mcux_wwdt.c b/drivers/watchdog/wdt_mcux_wwdt.c index 1673c7c308c29..015f331e978ef 100644 --- a/drivers/watchdog/wdt_mcux_wwdt.c +++ b/drivers/watchdog/wdt_mcux_wwdt.c @@ -87,6 +87,8 @@ static int mcux_wwdt_install_timeout(const struct device *dev, clock_freq = CLOCK_GetWdtClkFreq(0); #elif defined(CONFIG_SOC_SERIES_RW6XX) clock_freq = CLOCK_GetWdtClkFreq(); +#elif defined(CONFIG_SOC_SERIES_MCXA) + clock_freq = CLOCK_GetWwdtClkFreq(); #else const struct mcux_wwdt_config *config = dev->config; diff --git a/drivers/watchdog/wdt_npcx.c b/drivers/watchdog/wdt_npcx.c index 24979ce88defb..c3245a50b7898 100644 --- a/drivers/watchdog/wdt_npcx.c +++ b/drivers/watchdog/wdt_npcx.c @@ -61,7 +61,8 @@ LOG_MODULE_REGISTER(wdt_npcx, CONFIG_WDT_LOG_LEVEL); #define NPCX_WDT_MIN_WND_TIME 100UL /* Timeout for reloading and restarting Timer 0. (Unit:ms) */ -#define NPCX_T0CSR_RST_TIMEOUT 2 +#define NPCX_T0CSR_RST_CLEAR_TIMEOUT 2 +#define NPCX_T0CSR_RST_SET_TIMEOUT 1 /* Timeout for stopping watchdog. (Unit:ms) */ #define NPCX_WATCHDOG_STOP_TIMEOUT 1 @@ -100,10 +101,22 @@ static inline int wdt_t0out_reload(const struct device *dev) /* Reload and restart T0 timer */ inst->T0CSR = (inst->T0CSR & ~BIT(NPCX_T0CSR_WDRST_STS)) | BIT(NPCX_T0CSR_RST); + /* + * Wait for the T0CSR_RST bit to change from 0 to 1. This transition is expected to occur + * over multiple LFCLK cycles. If a timeout occurs, we can assume that the bit has changed + * from 0 -> 1 -> 0, but the polling thread missed it because it was preempted by + * higher-priority threads. In this case, we can simply return. + */ + st = k_uptime_get(); + while (!IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) { + if (k_uptime_get() - st > NPCX_T0CSR_RST_SET_TIMEOUT) { + return 0; + } + } /* Wait for timer is loaded and restart */ st = k_uptime_get(); while (IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) { - if (k_uptime_get() - st > NPCX_T0CSR_RST_TIMEOUT) { + if (k_uptime_get() - st > NPCX_T0CSR_RST_CLEAR_TIMEOUT) { /* RST bit is still set? */ if (IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) { LOG_ERR("Timeout: reload T0 timer!"); diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index 8ad72a7cca41f..4459b7fac6d0f 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include @@ -13,11 +14,18 @@ #include LOG_MODULE_REGISTER(wdt_nrfx); +#if !CONFIG_WDT_NRFX_NO_IRQ && NRF_WDT_HAS_STOP +#define WDT_NRFX_SYNC_STOP 1 +#endif + struct wdt_nrfx_data { wdt_callback_t m_callbacks[NRF_WDT_CHANNEL_NUMBER]; uint32_t m_timeout; uint8_t m_allocated_channels; bool enabled; +#if defined(WDT_NRFX_SYNC_STOP) + struct k_sem sync_stop; +#endif }; struct wdt_nrfx_config { @@ -73,6 +81,10 @@ static int wdt_nrf_disable(const struct device *dev) return -EFAULT; } +#if defined(WDT_NRFX_SYNC_STOP) + k_sem_take(&data->sync_stop, K_FOREVER); +#endif + nrfx_wdt_channels_free(&config->wdt); for (channel_id = 0; channel_id < data->m_allocated_channels; channel_id++) { @@ -170,11 +182,17 @@ static DEVICE_API(wdt, wdt_nrfx_driver_api) = { static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_type, uint32_t requests, void *p_context) { + struct wdt_nrfx_data *data = dev->data; + +#if defined(WDT_NRFX_SYNC_STOP) + if (event_type == NRF_WDT_EVENT_STOPPED) { + k_sem_give(&data->sync_stop); + } +#else (void)event_type; +#endif (void)p_context; - struct wdt_nrfx_data *data = dev->data; - while (requests) { uint8_t i = u32_count_trailing_zeros(requests); @@ -217,7 +235,11 @@ static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_ty } \ return 0; \ } \ - static struct wdt_nrfx_data wdt_##idx##_data; \ + static struct wdt_nrfx_data wdt_##idx##_data = { \ + IF_ENABLED(WDT_NRFX_SYNC_STOP, \ + (.sync_stop = Z_SEM_INITIALIZER( \ + wdt_##idx##_data.sync_stop, 0, 1),)) \ + }; \ static const struct wdt_nrfx_config wdt_##idx##z_config = { \ .wdt = NRFX_WDT_INSTANCE(idx), \ }; \ diff --git a/drivers/watchdog/wdt_rpi_pico.c b/drivers/watchdog/wdt_rpi_pico.c index 03d4a0a50fbe9..eadce28c65e01 100644 --- a/drivers/watchdog/wdt_rpi_pico.c +++ b/drivers/watchdog/wdt_rpi_pico.c @@ -7,6 +7,7 @@ #define DT_DRV_COMPAT raspberrypi_pico_watchdog #include +#include #include #include #include @@ -15,9 +16,13 @@ #include LOG_MODULE_REGISTER(wdt_rpi_pico, CONFIG_WDT_LOG_LEVEL); +#ifdef CONFIG_SOC_RP2040 /* Maximum watchdog time is halved due to errata RP2040-E1 */ -#define RPI_PICO_MAX_WDT_TIME (0xffffff / 2) #define RPI_PICO_WDT_TIME_MULTIPLICATION_FACTOR 2 +#else +#define RPI_PICO_WDT_TIME_MULTIPLICATION_FACTOR 1 +#endif +#define RPI_PICO_MAX_WDT_TIME (0xffffff / RPI_PICO_WDT_TIME_MULTIPLICATION_FACTOR) /* Watchdog requires a 1MHz clock source, divided from the crystal oscillator */ #define RPI_PICO_CLK_REF_FREQ_WDT_TICK_DIVISOR 1000000 @@ -89,8 +94,13 @@ static int wdt_rpi_pico_setup(const struct device *dev, uint8_t options) return err; } +#ifdef CONFIG_SOC_RP2040 watchdog_hw->tick = (ref_clk / RPI_PICO_CLK_REF_FREQ_WDT_TICK_DIVISOR) | WATCHDOG_TICK_ENABLE_BITS; +#else + ticks_hw->ticks[TICK_WATCHDOG].cycles = ref_clk / RPI_PICO_CLK_REF_FREQ_WDT_TICK_DIVISOR; + ticks_hw->ticks[TICK_WATCHDOG].ctrl = TICKS_WATCHDOG_CTRL_ENABLE_BITS; +#endif return 0; } diff --git a/drivers/watchdog/wdt_sam4l.c b/drivers/watchdog/wdt_sam4l.c new file mode 100644 index 0000000000000..22eab06f1555c --- /dev/null +++ b/drivers/watchdog/wdt_sam4l.c @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2024-2025, Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT atmel_sam4l_watchdog + +/** + * @brief Watchdog (WDT) Driver for Atmel SAM4L MCUs + * + * Note: + * - SAM4L watchdog has a fuse bit to automatically enable the watchdog at boot. + * It should be enabled to keep compatibility with SAM family. + * - Since the MCU boots with WDT enabled, the CONFIG_WDT_DISABLE_AT_BOOT + * is set default at boot and watchdog module is disabled in the MCU for + * systems that don't need watchdog functionality. + * - If the application needs to use the watchdog in the system, then + * CONFIG_WDT_DISABLE_AT_BOOT must be unset in the app's config file + */ + +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL +#include +LOG_MODULE_REGISTER(wdt_sam4l); + +#define WDT_FIRST_KEY 0x55ul +#define WDT_SECOND_KEY 0xAAul + +enum wdt_sam4l_clock_src { + WDT_SAM4L_CLK_SRC_RCSYS = 0, + WDT_SAM4L_CLK_SRC_OSC32K = 1, +}; + +struct wdt_sam4l_dev_cfg { + Wdt *regs; + void (*irq_cfg_func)(const struct device *dev); + const struct atmel_sam_pmc_config clock_cfg; + enum wdt_sam4l_clock_src clock_src; + bool lock; +}; + +struct wdt_sam4l_dev_data { + wdt_callback_t cb; + uint32_t flags; +}; + +/** + * @brief Sets the Watchdog Timer Control register to the @a ctrl value. + * + * @param ctrl Value to set the WatchDog Timer Control register to. + */ +static void wdt_sam4l_set_ctrl(const struct wdt_sam4l_dev_cfg *cfg, + const uint32_t ctrl) +{ + Wdt *const wdt = cfg->regs; + volatile uint32_t delay; + + /* Calculate delay for internal synchronization, see 45.1.3 WDT errata */ + if (cfg->clock_src == WDT_SAM4L_CLK_SRC_OSC32K) { + delay = DIV_ROUND_UP(SOC_ATMEL_SAM_MCK_FREQ_HZ * 2, SOC_ATMEL_SAM_RC32K_NOMINAL_HZ); + } else { + delay = DIV_ROUND_UP(SOC_ATMEL_SAM_MCK_FREQ_HZ * 2, SOC_ATMEL_SAM_RCSYS_NOMINAL_HZ); + } + /* ~8 cycles for one while loop */ + delay >>= 3; + while (delay--) { + } + wdt->CTRL = WDT_CTRL_KEY(WDT_FIRST_KEY) + | ctrl; + wdt->CTRL = WDT_CTRL_KEY(WDT_SECOND_KEY) + | ctrl; +} + +/** + * @brief Calculate timeout scale factor based on a input in milliseconds + * + * timeout(ms) = (2pow(scale + 1) * 1000) / wdt_clk + * + * @param cfg Configuration + * @param time Timeout value in milliseconds + */ +static int wdt_sam4l_calc_timeout(const struct wdt_sam4l_dev_cfg *cfg, + uint32_t time) +{ + uint32_t wdt_clk = cfg->clock_src == WDT_SAM4L_CLK_SRC_OSC32K + ? SOC_ATMEL_SAM_RC32K_NOMINAL_HZ + : SOC_ATMEL_SAM_RCSYS_NOMINAL_HZ; + + for (int scale = 7; scale <= 31; ++scale) { + uint32_t timeout = (BIT64(scale + 1) * 1000ull) / wdt_clk; + + if (time <= timeout) { + return scale; + } + } + + return -EINVAL; +} + +/** + * @brief Calculate both the Banned and Prescale Select timeout to be installed + * in the watchdog timer. + * + * The config->min value will define the banned timeout. The prescaler timeout + * then should be defined by the interval of (config->max - config-min). + * + * @param config Timeout Window configuration value in milliseconds. + * @param tban Pointer to the banned timeout + * @param psel Pointer to the timeout perscaller selection + */ +static int wdt_sam4l_convert_timeout(const struct wdt_sam4l_dev_cfg *cfg, + const struct wdt_timeout_cfg *config, + uint32_t *tban, uint32_t *psel) +{ + int scale; + + if (config->window.max < config->window.min || config->window.max == 0) { + LOG_ERR("The watchdog window should have a valid period"); + return -EINVAL; + } + + scale = wdt_sam4l_calc_timeout(cfg, config->window.min); + if (scale < 0) { + LOG_ERR("Window minimal value is too big"); + return -EINVAL; + } + *tban = scale; + + scale = wdt_sam4l_calc_timeout(cfg, config->window.max - config->window.min); + if (scale < 0) { + LOG_ERR("Window maximal value is too big"); + return -EINVAL; + } + *psel = scale; + + return 0; +} + +static int wdt_sam4l_setup(const struct device *dev, uint8_t options) +{ + const struct wdt_sam4l_dev_cfg *cfg = dev->config; + Wdt *const wdt = cfg->regs; + volatile uint32_t reg; + + if (options & WDT_OPT_PAUSE_IN_SLEEP) { + LOG_ERR("Pause in Sleep is an invalid option"); + return -ENOTSUP; + } + + if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) { + LOG_ERR("Pause on CPU halted by debug is an invalid option"); + return -ENOTSUP; + } + + reg = wdt->CTRL; + + if (reg & WDT_CTRL_EN) { + LOG_ERR("Watchdog is running and can not be changed"); + return -EPERM; + } + + if (reg & WDT_CTRL_SFV) { + LOG_ERR("Watchdog is locked and can not be changed"); + return -EPERM; + } + + if (!(reg & WDT_CTRL_PSEL_Msk)) { + LOG_ERR("No valid timeouts installed"); + return -EINVAL; + } + + reg = wdt->CTRL + | (cfg->lock ? WDT_CTRL_SFV : 0) + | WDT_CTRL_EN; + + wdt_sam4l_set_ctrl(cfg, reg); + while ((wdt->CTRL & WDT_CTRL_EN) != WDT_CTRL_EN) { + } + + return 0; +} + +static int wdt_sam4l_disable(const struct device *dev) +{ + const struct wdt_sam4l_dev_cfg *cfg = dev->config; + Wdt *const wdt = cfg->regs; + + if (wdt->CTRL & WDT_CTRL_SFV) { + LOG_ERR("Watchdog is already locked"); + return -EPERM; + } + + wdt_sam4l_set_ctrl(cfg, wdt->CTRL & ~WDT_CTRL_EN); + while (wdt->CTRL & WDT_CTRL_EN) { + } + + wdt_sam4l_set_ctrl(cfg, wdt->CTRL & ~WDT_CTRL_CEN); + while (wdt->CTRL & WDT_CTRL_CEN) { + } + + return 0; +} + +static int wdt_sam4l_install_timeout(const struct device *dev, + const struct wdt_timeout_cfg *config) +{ + const struct wdt_sam4l_dev_cfg *cfg = dev->config; + struct wdt_sam4l_dev_data *const data = dev->data; + Wdt *const wdt = cfg->regs; + volatile uint32_t reg; + uint32_t tban, psel; + + if (wdt->CTRL & WDT_CTRL_MODE) { + LOG_ERR("No more timeouts can be installed"); + return -ENOMEM; + } + + if (config->flags & WDT_FLAG_RESET_CPU_CORE) { + LOG_ERR("The SAM4L watchdog does not support reset CPU core"); + return -ENOTSUP; + } + + if (wdt_sam4l_convert_timeout(cfg, config, &tban, &psel)) { + return -EINVAL; + } + + reg = wdt->CTRL; + + if (reg & WDT_CTRL_EN) { + LOG_ERR("Watchdog is running and can not be changed"); + return -EPERM; + } + + if (reg & WDT_CTRL_SFV) { + LOG_ERR("Watchdog is locked and can not be changed"); + return -EPERM; + } + + data->cb = config->callback; + data->flags = config->flags; + reg = (cfg->clock_src == WDT_SAM4L_CLK_SRC_OSC32K ? WDT_CTRL_CSSEL : 0) + | (config->callback ? WDT_CTRL_IM : 0) + | (config->window.min ? WDT_CTRL_MODE : 0) + | (config->window.min ? WDT_CTRL_TBAN(tban) : 0) + | WDT_CTRL_PSEL(psel); + wdt_sam4l_set_ctrl(cfg, reg); + + wdt_sam4l_set_ctrl(cfg, wdt->CTRL | WDT_CTRL_CEN); + while (!(wdt->CTRL & WDT_CTRL_CEN)) { + } + + return 0; +} + +static int wdt_sam4l_feed(const struct device *dev, int channel_id) +{ + const struct wdt_sam4l_dev_cfg *cfg = dev->config; + Wdt *const wdt = cfg->regs; + + ARG_UNUSED(channel_id); + + while ((wdt->SR & WDT_SR_CLEARED) != WDT_SR_CLEARED) { + } + wdt->CLR = WDT_CLR_WDTCLR + | WDT_CLR_KEY(WDT_FIRST_KEY); + wdt->CLR = WDT_CLR_WDTCLR + | WDT_CLR_KEY(WDT_SECOND_KEY); + + return 0; +} + +/* If the callback blocks or ISR do not clear flags the system will trigger a + * CPU reset on the next watchdog timeout, see 20.5.3 Interrupt Mode + */ +static void wdt_sam4l_isr(const struct device *dev) +{ + const struct wdt_sam4l_dev_cfg *cfg = dev->config; + struct wdt_sam4l_dev_data *const data = dev->data; + Wdt *const wdt = cfg->regs; + + wdt->ICR = WDT_ICR_WINT; + data->cb(dev, 0); +} + +static DEVICE_API(wdt, wdt_sam4l_driver_api) = { + .setup = wdt_sam4l_setup, + .disable = wdt_sam4l_disable, + .install_timeout = wdt_sam4l_install_timeout, + .feed = wdt_sam4l_feed, +}; + +static int wdt_sam4l_init(const struct device *dev) +{ + const struct wdt_sam4l_dev_cfg *const cfg = dev->config; + Wdt *const wdt = cfg->regs; + + /* Enable WDT clock in PMC */ + (void)clock_control_on(SAM_DT_PMC_CONTROLLER, + (clock_control_subsys_t)&cfg->clock_cfg); + + if (IS_ENABLED(CONFIG_WDT_DISABLE_AT_BOOT)) { + wdt_sam4l_disable(dev); + return 0; + } + + wdt->IDR = WDT_IDR_MASK; + cfg->irq_cfg_func(dev); + wdt->IER = WDT_IER_WINT; + + return 0; +} + +#define WDT_SAM4L_INIT(n) \ + static void wdt##n##_sam4l_irq_cfg(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + wdt_sam4l_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + \ + static const struct wdt_sam4l_dev_cfg wdt##n##_sam4l_cfg = { \ + .regs = (Wdt *)DT_INST_REG_ADDR(n), \ + .irq_cfg_func = wdt##n##_sam4l_irq_cfg, \ + .clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(n), \ + .clock_src = DT_INST_ENUM_IDX(n, clk_source), \ + .lock = DT_INST_PROP(n, lock_mode), \ + }; \ + \ + static struct wdt_sam4l_dev_data wdt##n##_sam4l_data; \ + \ + DEVICE_DT_INST_DEFINE(n, wdt_sam4l_init, \ + NULL, \ + &wdt##n##_sam4l_data, \ + &wdt##n##_sam4l_cfg, \ + PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &wdt_sam4l_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(WDT_SAM4L_INIT) diff --git a/drivers/watchdog/wdt_shell.c b/drivers/watchdog/wdt_shell.c index ce0b624843aa9..f0433205264c4 100644 --- a/drivers/watchdog/wdt_shell.c +++ b/drivers/watchdog/wdt_shell.c @@ -72,7 +72,7 @@ static int cmd_setup(const struct shell *sh, size_t argc, char *argv[]) { const struct device *dev; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "WDT device not found"); return -ENODEV; @@ -85,7 +85,7 @@ static int cmd_disable(const struct shell *sh, size_t argc, char *argv[]) { const struct device *dev; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "WDT device not found"); return -ENODEV; @@ -103,7 +103,7 @@ static int cmd_timeout(const struct shell *sh, size_t argc, char *argv[]) struct wdt_timeout_cfg cfg; int rc; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "WDT device not found"); return -ENODEV; @@ -145,7 +145,7 @@ static int cmd_feed(const struct shell *sh, size_t argc, char *argv[]) const struct device *dev; int channel_id; - dev = device_get_binding(argv[args_indx.device]); + dev = shell_device_get_binding(argv[args_indx.device]); if (!dev) { shell_error(sh, "WDT device not found"); return -ENODEV; @@ -160,10 +160,15 @@ static int cmd_feed(const struct shell *sh, size_t argc, char *argv[]) return wdt_feed(dev, channel_id); } +static bool device_is_wdt(const struct device *dev) +{ + return DEVICE_API_IS(wdt, dev); +} + /* Device name autocompletion support */ static void device_name_get(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_lookup(idx, NULL); + const struct device *dev = shell_device_filter(idx, device_is_wdt); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; diff --git a/drivers/wifi/CMakeLists.txt b/drivers/wifi/CMakeLists.txt index 94038b0c3e9ea..96c24d245b68f 100644 --- a/drivers/wifi/CMakeLists.txt +++ b/drivers/wifi/CMakeLists.txt @@ -3,14 +3,27 @@ zephyr_library() zephyr_library_property(ALLOW_EMPTY TRUE) -add_subdirectory_ifdef(CONFIG_WIFI_ESP_AT esp_at) -add_subdirectory_ifdef(CONFIG_WIFI_ESP32 esp32) +if (CONFIG_BUILD_ONLY_NO_BLOBS) + message(WARNING " + --------------------------------------------------------------------------- + Building only the Wi-Fi driver without binary blobs and patches. + This is only for building (CI) purposes and will not work on a real device. + --------------------------------------------------------------------------- + ") +else() + if(CONFIG_DT_HAS_ESPRESSIF_ESP32_WIFI_ENABLED) zephyr_blobs_verify(MODULE hal_espressif REQUIRED) endif() + +endif() # CONFIG_BUILD_ONLY_NO_BLOBS + +add_subdirectory_ifdef(CONFIG_WIFI_ESP_AT esp_at) +add_subdirectory_ifdef(CONFIG_WIFI_ESP32 esp32) add_subdirectory_ifdef(CONFIG_WIFI_ESWIFI eswifi) add_subdirectory_ifdef(CONFIG_WIFI_SIMPLELINK simplelink) add_subdirectory_ifdef(CONFIG_WIFI_WINC1500 winc1500) add_subdirectory_ifdef(CONFIG_WIFI_NXP nxp) add_subdirectory_ifdef(CONFIG_WIFI_AIROC infineon) add_subdirectory_ifdef(CONFIG_WIFI_NRF70 nrf_wifi) +add_subdirectory_ifdef(CONFIG_WIFI_SILABS_SIWX91X siwx91x) diff --git a/drivers/wifi/Kconfig b/drivers/wifi/Kconfig index 55b2a943ff2e9..b6f7cfcb84c65 100644 --- a/drivers/wifi/Kconfig +++ b/drivers/wifi/Kconfig @@ -43,5 +43,6 @@ source "drivers/wifi/esp32/Kconfig.esp32" source "drivers/wifi/nxp/Kconfig.nxp" source "drivers/wifi/infineon/Kconfig.airoc" source "drivers/wifi/nrf_wifi/Kconfig.nrfwifi" +source "drivers/wifi/siwx91x/Kconfig.siwx91x" endif # WIFI diff --git a/drivers/wifi/esp32/Kconfig.esp32 b/drivers/wifi/esp32/Kconfig.esp32 index 0da3e58c62ae4..9be2a64fb33f3 100644 --- a/drivers/wifi/esp32/Kconfig.esp32 +++ b/drivers/wifi/esp32/Kconfig.esp32 @@ -4,7 +4,7 @@ menuconfig WIFI_ESP32 bool "ESP32 SoC WiFi support" default y depends on DT_HAS_ESPRESSIF_ESP32_WIFI_ENABLED - depends on ZEPHYR_HAL_ESPRESSIF_MODULE_BLOBS + depends on ZEPHYR_HAL_ESPRESSIF_MODULE_BLOBS || BUILD_ONLY_NO_BLOBS depends on !SMP select THREAD_CUSTOM_DATA select NET_L2_WIFI_MGMT @@ -20,12 +20,22 @@ menuconfig WIFI_ESP32 if WIFI_ESP32 -config HEAP_MEM_POOL_ADD_SIZE_WIFI +config HEAP_MEM_POOL_ADD_SIZE_ESP_WIFI int - default 4096 + default 40960 if ESP_WIFI_HEAP_SYSTEM + default 0 help Make sure there is a minimal heap available for Wi-Fi driver. +choice ESP_WIFI_HEAP + prompt "Wi-Fi adapter heap memory" + default ESP_WIFI_HEAP_SYSTEM + + config ESP_WIFI_HEAP_SYSTEM + bool "Wi-Fi adapter use kernel mempool heap (k_malloc)" + +endchoice # ESP_WIFI_HEAP + config NET_TCP_WORKQ_STACK_SIZE default 2048 @@ -54,10 +64,12 @@ config ESP32_WIFI_STA_RECONNECT help Set auto WiFI reconnection when disconnected. -config ESP32_WIFI_SW_COEXIST_ENABLE - bool +config ESP32_WIFI_STA_SCAN_ALL + bool "Scan all available APs when connecting in station mode" help - Software controls WiFi/Bluetooth coexistence. Not supported yet. + When connecting in station mode, scan all channels and connect to the channel with the + highest RSSI. Without this, a fast scan is performed which connects to the first AP + found. config ESP32_WIFI_NET_ALLOC_SPIRAM bool "Allocate memory of WiFi and NET in SPIRAM" @@ -210,7 +222,6 @@ config ESP32_WIFI_RX_MGMT_BUF_NUM_DEF config ESP32_WIFI_CSI_ENABLED bool "WiFi CSI(Channel State Information)" - default n help Select this option to enable CSI(Channel State Information) feature. CSI takes about CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM KB of RAM. @@ -263,7 +274,6 @@ config ESP32_WIFI_RX_BA_WIN config ESP32_WIFI_AMSDU_TX_ENABLED bool "WiFi AMSDU TX" depends on ESP_SPIRAM - default n help Select this option to enable AMSDU TX feature @@ -276,8 +286,6 @@ config ESP32_WIFI_MGMT_SBUF_NUM config ESP32_WIFI_IRAM_OPT bool "WiFi IRAM speed optimization" - default n if (BT && ESP_SPIRAM && SOC_SERIES_ESP32) - default y help Select this option to place frequently called Wi-Fi library functions in IRAM. When this option is disabled, more than 10Kbytes of IRAM memory will be saved @@ -285,7 +293,6 @@ config ESP32_WIFI_IRAM_OPT config ESP32_WIFI_RX_IRAM_OPT bool "WiFi RX IRAM speed optimization" - default n if (BT && ESP_SPIRAM && SOC_SERIES_ESP32) help Select this option to place frequently called Wi-Fi library RX functions in IRAM. When this option is disabled, more than 17Kbytes of IRAM memory will be saved @@ -326,26 +333,8 @@ config ESP32_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME before entering the sleep process. If a broadcast packet is received with more data bits, the time will refreshed. unit: milliseconds. -choice ESP_WIFI_HEAP - prompt "Wifi adapter heap in use" - default ESP_WIFI_HEAP_RUNTIME - - config ESP_WIFI_HEAP_RUNTIME - bool "Wifi adapter use ESP runtime heap" - depends on ESP_HEAP_RUNTIME - - config ESP_WIFI_HEAP_SPIRAM - bool "Wifi adapter use SPIRAM heap" - depends on ESP_SPIRAM - - config ESP_WIFI_HEAP_SYSTEM - bool "Wifi adapter use system heap" - -endchoice # ESP_WIFI_HEAP - config ESP32_WIFI_FTM_ENABLE bool "WiFi FTM" - default n depends on SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 || SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3 help Enable feature Fine Timing Measurement for calculating WiFi Round-Trip-Time (RTT). @@ -368,7 +357,6 @@ config ESP32_WIFI_SOFTAP_SUPPORT config ESP32_WIFI_MBEDTLS_CRYPTO bool "Use MbedTLS crypto APIs" - default n select MBEDTLS_ECP_C select MBEDTLS_ECDH_C select MBEDTLS_ECDSA_C @@ -382,7 +370,6 @@ config ESP32_WIFI_MBEDTLS_CRYPTO config ESP32_WIFI_ENABLE_WPA3_SAE bool "WPA3-Personal" - default n select ESP32_WIFI_MBEDTLS_CRYPTO help Select this option to allow the device to establish a WPA3-Personal connection. @@ -403,7 +390,6 @@ config ESP32_WIFI_ENABLE_SAE_PK config ESP32_WIFI_DEBUG_PRINT bool "Print debug messages from WPA Supplicant" - default n help Select this option to print logging information from WPA supplicant, this includes handshake information and key hex dumps depending diff --git a/drivers/wifi/esp32/src/esp_wifi_drv.c b/drivers/wifi/esp32/src/esp_wifi_drv.c index 56f8b92e51e2b..392df1b65e8b3 100644 --- a/drivers/wifi/esp32/src/esp_wifi_drv.c +++ b/drivers/wifi/esp32/src/esp_wifi_drv.c @@ -354,10 +354,35 @@ static void esp_wifi_handle_ap_connect_event(void *event_data) LOG_DBG("Station " MACSTR " join, AID=%d", MAC2STR(event->mac), event->aid); + wifi_sta_list_t sta_list; struct wifi_ap_sta_info sta_info; + sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN; + sta_info.twt_capable = false; /* Only support in 802.11ax */ sta_info.mac_length = WIFI_MAC_ADDR_LEN; memcpy(sta_info.mac, event->mac, WIFI_MAC_ADDR_LEN); + + /* Expect the return value to always be ESP_OK, + * since it is called in esp_wifi_event_handler() + */ + (void)esp_wifi_ap_get_sta_list(&sta_list); + for (int i = 0; i < sta_list.num; i++) { + wifi_sta_info_t *sta = &sta_list.sta[i]; + + if (memcmp(event->mac, sta->mac, 6) == 0) { + if (sta->phy_11n) { + sta_info.link_mode = WIFI_4; + } else if (sta->phy_11g) { + sta_info.link_mode = WIFI_3; + } else if (sta->phy_11b) { + sta_info.link_mode = WIFI_1; + } else { + sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN; + } + break; + } + } + wifi_mgmt_raise_ap_sta_connected_event(iface, &sta_info); if (!(esp32_data.ap_connection_cnt++)) { @@ -377,6 +402,8 @@ static void esp_wifi_handle_ap_disconnect_event(void *event_data) LOG_DBG("station " MACSTR " leave, AID=%d", MAC2STR(event->mac), event->aid); struct wifi_ap_sta_info sta_info; + sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN; + sta_info.twt_capable = false; /* Only support in 802.11ax */ sta_info.mac_length = WIFI_MAC_ADDR_LEN; memcpy(sta_info.mac, event->mac, WIFI_MAC_ADDR_LEN); wifi_mgmt_raise_ap_sta_disconnected_event(iface, &sta_info); @@ -541,6 +568,11 @@ static int esp32_wifi_connect(const struct device *dev, return -EIO; } +#if defined(CONFIG_ESP32_WIFI_STA_SCAN_ALL) + wifi_config.sta.scan_method = WIFI_ALL_CHANNEL_SCAN; + wifi_config.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; +#endif + if (params->channel == WIFI_CHANNEL_ANY) { wifi_config.sta.channel = 0U; data->status.channel = 0U; @@ -741,6 +773,13 @@ static int esp32_wifi_status(const struct device *dev, struct wifi_iface_status status->mfp = WIFI_MFP_DISABLE; if (esp_wifi_get_mode(&mode) == ESP_OK) { +#if defined(CONFIG_ESP32_WIFI_AP_STA_MODE) + if (mode == ESP32_WIFI_MODE_APSTA && data == &esp32_data) { + mode = ESP32_WIFI_MODE_STA; + } else if (mode == ESP32_WIFI_MODE_APSTA && data == &esp32_ap_sta_data) { + mode = ESP32_WIFI_MODE_AP; + } +#endif if (mode == ESP32_WIFI_MODE_STA) { wifi_phy_mode_t phy_mode; esp_err_t err; @@ -810,21 +849,14 @@ static void esp32_wifi_init(struct net_if *iface) #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE) struct wifi_nm_instance *nm = wifi_nm_get_instance("esp32_wifi_nm"); - if (!esp32_wifi_iface_ap) { - esp32_wifi_iface_ap = iface; - dev_data->state = ESP32_AP_STOPPED; + esp32_wifi_iface = iface; + dev_data->state = ESP32_STA_STOPPED; - esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_SOFTAP); - wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_SAP, esp32_wifi_iface_ap); - } else { - esp32_wifi_iface = iface; - dev_data->state = ESP32_STA_STOPPED; + /* Start interface when we are actually connected with Wi-Fi network */ + esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA); + esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx); + wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_STA, esp32_wifi_iface); - /* Start interface when we are actually connected with Wi-Fi network */ - esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA); - esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx); - wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_STA, esp32_wifi_iface); - } #else esp32_wifi_iface = iface; @@ -843,6 +875,31 @@ static void esp32_wifi_init(struct net_if *iface) net_if_carrier_off(iface); } +#if defined(CONFIG_ESP32_WIFI_AP_STA_MODE) +static void esp32_wifi_init_ap(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct esp32_wifi_runtime *dev_data = dev->data; + struct ethernet_context *eth_ctx = net_if_l2_data(iface); + + eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI; + + struct wifi_nm_instance *nm = wifi_nm_get_instance("esp32_wifi_nm"); + + esp32_wifi_iface_ap = iface; + dev_data->state = ESP32_AP_STOPPED; + + esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_SOFTAP); + wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_SAP, esp32_wifi_iface_ap); + + /* Assign link local address. */ + net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET); + + ethernet_init(iface); + net_if_carrier_off(iface); +} +#endif + #if defined(CONFIG_NET_STATISTICS_WIFI) static int esp32_wifi_stats(const struct device *dev, struct net_stats_wifi *stats) { @@ -873,6 +930,7 @@ static int esp32_wifi_dev_init(const struct device *dev) wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); esp_err_t ret = esp_wifi_init(&config); + esp_wifi_set_mode(ESP32_WIFI_MODE_NULL); if (ret == ESP_ERR_NO_MEM) { LOG_ERR("Not enough memory to initialize Wi-Fi."); @@ -907,6 +965,13 @@ static const struct net_wifi_mgmt_offload esp32_api = { .wifi_iface.send = esp32_wifi_send, .wifi_mgmt_api = &esp32_wifi_mgmt, }; +#if defined(CONFIG_ESP32_WIFI_AP_STA_MODE) +static const struct net_wifi_mgmt_offload esp32_api_ap = { + .wifi_iface.iface_api.init = esp32_wifi_init_ap, + .wifi_iface.send = esp32_wifi_send, + .wifi_mgmt_api = &esp32_wifi_mgmt, +}; +#endif NET_DEVICE_DT_INST_DEFINE(0, esp32_wifi_dev_init, NULL, @@ -918,7 +983,7 @@ NET_DEVICE_DT_INST_DEFINE(0, NET_DEVICE_DT_INST_DEFINE(1, NULL, NULL, &esp32_ap_sta_data, NULL, CONFIG_WIFI_INIT_PRIORITY, - &esp32_api, ETHERNET_L2, + &esp32_api_ap, ETHERNET_L2, NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU); DEFINE_WIFI_NM_INSTANCE(esp32_wifi_nm, &esp32_wifi_mgmt); diff --git a/drivers/wifi/esp_at/Kconfig.esp_at b/drivers/wifi/esp_at/Kconfig.esp_at index 1b611e8ba3fdb..f3714bcb8a73d 100644 --- a/drivers/wifi/esp_at/Kconfig.esp_at +++ b/drivers/wifi/esp_at/Kconfig.esp_at @@ -163,6 +163,7 @@ config WIFI_ESP_AT_DNS_USE config WIFI_ESP_AT_CIPDINFO_USE bool "Use CIPDINFO to get peer ip and port" + default y if DNS_RESOLVER help Enable AT+CIPDINFO to get peer ip-address and port. diff --git a/drivers/wifi/esp_at/esp.c b/drivers/wifi/esp_at/esp.c index 0dfe0bfb9d439..c68ea98ee0f96 100644 --- a/drivers/wifi/esp_at/esp.c +++ b/drivers/wifi/esp_at/esp.c @@ -811,9 +811,11 @@ static int cmd_ipd_parse_hdr(struct esp_data *dev, } *sock = esp_socket_ref_from_link_id(dev, link_id); - if (!sock) { + + if (!*sock) { LOG_ERR("No socket for link %ld", link_id); - return str - ipd_buf; + *data_offset = (str - ipd_buf); + return -ENOTCONN; } if (!ESP_PROTO_PASSIVE(esp_socket_ip_proto(*sock)) && @@ -823,7 +825,13 @@ static int cmd_ipd_parse_hdr(struct esp_data *dev, char *remote_ip; long port; - err = esp_pull_quoted(&str, str_end, &remote_ip); + if (IS_ENABLED(CONFIG_WIFI_ESP_AT_VERSION_1_7)) { + /* NOT quoted per AT version 1.7.0 */ + err = esp_pull_raw(&str, str_end, &remote_ip); + } else { + /* Quoted per AT version 2.1.0/2.2.0 */ + err = esp_pull_quoted(&str, str_end, &remote_ip); + } if (err) { if (err == -EAGAIN && match_len >= MAX_IPD_LEN) { LOG_ERR("Failed to pull remote_ip"); diff --git a/drivers/wifi/esp_at/esp_offload.c b/drivers/wifi/esp_at/esp_offload.c index ba4400ec2a845..9b4eae8bd9e5c 100644 --- a/drivers/wifi/esp_at/esp_offload.c +++ b/drivers/wifi/esp_at/esp_offload.c @@ -37,6 +37,7 @@ static int _sock_connect(struct esp_data *dev, struct esp_socket *sock) struct sockaddr src; struct sockaddr dst; int ret; + int mode; if (!esp_flags_are_set(dev, EDF_STA_CONNECTED | EDF_AP_ENABLED)) { return -ENETUNREACH; @@ -65,11 +66,39 @@ static int _sock_connect(struct esp_data *dev, struct esp_socket *sock) net_addr_ntop(src.sa_family, &net_sin(&src)->sin_addr, src_addr_str, sizeof(src_addr_str)); + /* : In the UDP Wi-Fi passthrough + * + * 0: After UDP data is received, the parameters <"remote host"> + * and will stay unchanged (default). + * 1: Only the first time that UDP data is received from an IP + * address and port that are different from the initially set + * value of parameters and , will + * they be changed to the IP address and port of the device that + * sends the data. + * 2: Each time UDP data is received, the <"remote host"> and + * will be changed to the IP address and port of the + * device that sends the data. + * + * When remote IP and port are both 0, it means that the socket is + * being used as a server, and you need to set the connection mode + * to 2. + */ + if ((net_sin(&dst)->sin_addr.s_addr == 0) && + (ntohs(net_sin(&dst)->sin_port) == 0)) { + mode = 2; + /* Port 0 is reserved and a valid port needs to be provided when + * connecting. + */ + net_sin(&dst)->sin_port = 65535; + } else { + mode = 0; + } + snprintk(connect_msg, sizeof(connect_msg), - "AT+CIPSTART=%d,\"UDP\",\"%s\",%d,%d,0,\"%s\"", + "AT+CIPSTART=%d,\"UDP\",\"%s\",%d,%d,%d,\"%s\"", sock->link_id, dst_addr_str, ntohs(net_sin(&dst)->sin_port), ntohs(net_sin(&src)->sin_port), - src_addr_str); + mode, src_addr_str); } else { snprintk(connect_msg, sizeof(connect_msg), "AT+CIPSTART=%d,\"UDP\",\"%s\",%d", diff --git a/drivers/wifi/eswifi/eswifi.h b/drivers/wifi/eswifi/eswifi.h index 0bf4fddb2066a..54bf00f0f7896 100644 --- a/drivers/wifi/eswifi/eswifi.h +++ b/drivers/wifi/eswifi/eswifi.h @@ -92,9 +92,9 @@ static inline int eswifi_request(struct eswifi_dev *eswifi, char *cmd, static inline void eswifi_lock(struct eswifi_dev *eswifi) { /* Nested locking */ - if (atomic_get(&eswifi->mutex_owner) != (atomic_t)(uintptr_t)arch_current_thread()) { + if (atomic_get(&eswifi->mutex_owner) != (atomic_t)(uintptr_t)_current) { k_mutex_lock(&eswifi->mutex, K_FOREVER); - atomic_set(&eswifi->mutex_owner, (atomic_t)(uintptr_t)arch_current_thread()); + atomic_set(&eswifi->mutex_owner, (atomic_t)(uintptr_t)_current); eswifi->mutex_depth = 1; } else { eswifi->mutex_depth++; diff --git a/drivers/wifi/infineon/CMakeLists.txt b/drivers/wifi/infineon/CMakeLists.txt index 20f69f181117f..ebca6fdc44666 100644 --- a/drivers/wifi/infineon/CMakeLists.txt +++ b/drivers/wifi/infineon/CMakeLists.txt @@ -4,8 +4,12 @@ zephyr_include_directories(./) -zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_wifi.c) -zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_whd_hal.c) +zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC + airoc_wifi.c + airoc_whd_hal_common.c +) +zephyr_library_sources_ifdef(CONFIG_AIROC_WIFI_BUS_SDIO airoc_whd_hal_sdio.c) +zephyr_library_sources_ifdef(CONFIG_AIROC_WIFI_BUS_SPI airoc_whd_hal_spi.c) zephyr_compile_definitions(CYBSP_WIFI_CAPABLE) zephyr_compile_definitions(CY_RTOS_AWARE) diff --git a/drivers/wifi/infineon/Kconfig.airoc b/drivers/wifi/infineon/Kconfig.airoc index 775396fb24579..db83d57b7348b 100644 --- a/drivers/wifi/infineon/Kconfig.airoc +++ b/drivers/wifi/infineon/Kconfig.airoc @@ -4,20 +4,37 @@ menuconfig WIFI_AIROC bool "Infineon AIROC SoC Wi-Fi support" + depends on DT_HAS_INFINEON_AIROC_WIFI_ENABLED + default y select THREAD_CUSTOM_DATA select WIFI_OFFLOAD + select NET_L2_ETHERNET select NET_L2_WIFI_MGMT - select SDIO_STACK - select SDHC select GPIO select WIFI_USE_NATIVE_NETWORKING select USE_INFINEON_ABSTRACTION_RTOS - depends on DT_HAS_INFINEON_AIROC_WIFI_ENABLED help Enable Infineon AIROC SoC Wi-Fi support. if WIFI_AIROC +config AIROC_WIFI_BUS_SDIO + bool + default y + depends on $(dt_compat_on_bus,$(DT_COMPAT_INFINEON_AIROC_WIFI),sd) + select SDHC + select SDIO_STACK + help + Enable SDIO bus support. + +config AIROC_WIFI_BUS_SPI + bool + default y + depends on $(dt_compat_on_bus,$(DT_COMPAT_INFINEON_AIROC_WIFI),spi) + select SPI + help + Enable SPI bus support + config AIROC_WIFI_EVENT_TASK_STACK_SIZE int "Event Task Stack Size" default 4096 diff --git a/drivers/wifi/infineon/airoc_whd_hal.c b/drivers/wifi/infineon/airoc_whd_hal.c deleted file mode 100644 index b3a68102851f1..0000000000000 --- a/drivers/wifi/infineon/airoc_whd_hal.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or - * an affiliate of Cypress Semiconductor Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include -#include -#include -#include - -#define DT_DRV_COMPAT infineon_airoc_wifi - -LOG_MODULE_REGISTER(infineon_airoc, CONFIG_WIFI_LOG_LEVEL); - -#ifdef __cplusplus -extern "C" { -#endif - -/** Defines the amount of stack memory available for the wifi thread. */ -#if !defined(CY_WIFI_THREAD_STACK_SIZE) -#define CY_WIFI_THREAD_STACK_SIZE (5120) -#endif - -/** Defines the priority of the thread that services wifi packets. Legal values are defined by the - * RTOS being used. - */ -#if !defined(CY_WIFI_THREAD_PRIORITY) -#define CY_WIFI_THREAD_PRIORITY (CY_RTOS_PRIORITY_HIGH) -#endif - -/** Defines the country this will operate in for wifi initialization parameters. See the - * wifi-host-driver's whd_country_code_t for legal options. - */ -#if !defined(CY_WIFI_COUNTRY) -#define CY_WIFI_COUNTRY (WHD_COUNTRY_AUSTRALIA) -#endif - -/** Defines the priority of the interrupt that handles out-of-band notifications from the wifi - * chip. Legal values are defined by the MCU running this code. - */ -#if !defined(CY_WIFI_OOB_INTR_PRIORITY) -#define CY_WIFI_OOB_INTR_PRIORITY (2) -#endif - -/** Defines whether to use the out-of-band pin to allow the WIFI chip to wake up the MCU. */ -#if defined(CY_WIFI_HOST_WAKE_SW_FORCE) -#define CY_USE_OOB_INTR (CY_WIFI_HOST_WAKE_SW_FORCE) -#else -#define CY_USE_OOB_INTR (1u) -#endif /* defined(CY_WIFI_HOST_WAKE_SW_FORCE) */ - -#define CY_WIFI_HOST_WAKE_IRQ_EVENT GPIO_INT_TRIG_LOW -#define DEFAULT_OOB_PIN (0) -#define WLAN_POWER_UP_DELAY_MS (250) -#define WLAN_CBUCK_DISCHARGE_MS (10) - -extern whd_resource_source_t resource_ops; - -struct whd_bus_priv { - whd_sdio_config_t sdio_config; - whd_bus_stats_t whd_bus_stats; - whd_sdio_t sdio_obj; -}; - -static whd_init_config_t init_config_default = { - .thread_stack_size = CY_WIFI_THREAD_STACK_SIZE, - .thread_stack_start = NULL, - .thread_priority = (uint32_t)CY_WIFI_THREAD_PRIORITY, - .country = CY_WIFI_COUNTRY -}; - -/****************************************************** - * Function - ******************************************************/ - -int airoc_wifi_power_on(const struct device *dev) -{ -#if DT_INST_NODE_HAS_PROP(0, wifi_reg_on_gpios) - int ret; - const struct airoc_wifi_config *config = dev->config; - - /* Check WIFI REG_ON gpio instance */ - if (!device_is_ready(config->wifi_reg_on_gpio.port)) { - LOG_ERR("Error: failed to configure wifi_reg_on %s pin %d", - config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin); - return -EIO; - } - - /* Configure wifi_reg_on as output */ - ret = gpio_pin_configure_dt(&config->wifi_reg_on_gpio, GPIO_OUTPUT); - if (ret) { - LOG_ERR("Error %d: failed to configure wifi_reg_on %s pin %d", ret, - config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin); - return ret; - } - ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 0); - if (ret) { - return ret; - } - - /* Allow CBUCK regulator to discharge */ - (void)k_msleep(WLAN_CBUCK_DISCHARGE_MS); - - /* WIFI power on */ - ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 1); - if (ret) { - return ret; - } - (void)k_msleep(WLAN_POWER_UP_DELAY_MS); -#endif /* DT_INST_NODE_HAS_PROP(0, reg_on_gpios) */ - - return 0; -} - -int airoc_wifi_init_primary(const struct device *dev, whd_interface_t *interface, - whd_netif_funcs_t *netif_funcs, whd_buffer_funcs_t *buffer_if) -{ - int ret; - struct airoc_wifi_data *data = dev->data; - const struct airoc_wifi_config *config = dev->config; - - whd_sdio_config_t whd_sdio_config = { - .sdio_1bit_mode = WHD_FALSE, - .high_speed_sdio_clock = WHD_FALSE, - }; - -#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) - whd_oob_config_t oob_config = { - .host_oob_pin = (void *)&config->wifi_host_wake_gpio, - .dev_gpio_sel = DEFAULT_OOB_PIN, - .is_falling_edge = - (CY_WIFI_HOST_WAKE_IRQ_EVENT == GPIO_INT_TRIG_LOW) ? WHD_TRUE : WHD_FALSE, - .intr_priority = CY_WIFI_OOB_INTR_PRIORITY}; - whd_sdio_config.oob_config = oob_config; -#endif - - if (airoc_wifi_power_on(dev)) { - LOG_ERR("airoc_wifi_power_on retuens fail"); - return -ENODEV; - } - - if (!device_is_ready(config->sdhc_dev)) { - LOG_ERR("SDHC device is not ready"); - return -ENODEV; - } - - ret = sd_init(config->sdhc_dev, &data->card); - if (ret) { - return ret; - } - - /* Init SDIO functions */ - ret = sdio_init_func(&data->card, &data->sdio_func1, BACKPLANE_FUNCTION); - if (ret) { - LOG_ERR("sdio_enable_func BACKPLANE_FUNCTION, error: %x", ret); - return ret; - } - ret = sdio_init_func(&data->card, &data->sdio_func2, WLAN_FUNCTION); - if (ret) { - LOG_ERR("sdio_enable_func WLAN_FUNCTION, error: %x", ret); - return ret; - } - ret = sdio_set_block_size(&data->sdio_func1, SDIO_64B_BLOCK); - if (ret) { - LOG_ERR("Can't set block size for BACKPLANE_FUNCTION, error: %x", ret); - return ret; - } - ret = sdio_set_block_size(&data->sdio_func2, SDIO_64B_BLOCK); - if (ret) { - LOG_ERR("Can't set block size for WLAN_FUNCTION, error: %x", ret); - return ret; - } - - /* Init wifi host driver (whd) */ - cy_rslt_t whd_ret = whd_init(&data->whd_drv, &init_config_default, &resource_ops, buffer_if, - netif_funcs); - if (whd_ret == CY_RSLT_SUCCESS) { - whd_ret = whd_bus_sdio_attach(data->whd_drv, &whd_sdio_config, - (whd_sdio_t)&data->card); - - if (whd_ret == CY_RSLT_SUCCESS) { - whd_ret = whd_wifi_on(data->whd_drv, interface); - } - - if (whd_ret != CY_RSLT_SUCCESS) { - whd_deinit(*interface); - return -ENODEV; - } - } - return 0; -} - -/* - * Implement SDIO CMD52/53 wrappers - */ - -static struct sdio_func *airoc_wifi_get_sdio_func(struct sd_card *sd, whd_bus_function_t function) -{ - struct airoc_wifi_data *data = CONTAINER_OF(sd, struct airoc_wifi_data, card); - struct sdio_func *func[] = {&sd->func0, &data->sdio_func1, &data->sdio_func2}; - - if (function > WLAN_FUNCTION) { - return NULL; - } - - return func[function]; -} - -whd_result_t whd_bus_sdio_cmd52(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint8_t value, - sdio_response_needed_t response_expected, uint8_t *response) -{ - int ret; - struct sd_card *sd = whd_driver->bus_priv->sdio_obj; - struct sdio_func *func = airoc_wifi_get_sdio_func(sd, function); - - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd52); - - if (direction == BUS_WRITE) { - ret = sdio_rw_byte(func, address, value, response); - } else { - ret = sdio_read_byte(func, address, response); - } - WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, (ret != WHD_SUCCESS), - cmd52_fail); - - /* Possibly device might not respond to this cmd. So, don't check return value here */ - if ((ret != WHD_SUCCESS) && (address == SDIO_SLEEP_CSR)) { - return ret; - } - - CHECK_RETURN(ret); - return WHD_SUCCESS; -} - -whd_result_t whd_bus_sdio_cmd53(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, sdio_transfer_mode_t mode, - uint32_t address, uint16_t data_size, uint8_t *data, - sdio_response_needed_t response_expected, uint32_t *response) -{ - whd_result_t ret; - struct sd_card *sd = whd_driver->bus_priv->sdio_obj; - struct sdio_func *func = airoc_wifi_get_sdio_func(sd, function); - - if (direction == BUS_WRITE) { - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_write); - ret = sdio_write_addr(func, address, data, data_size); - } else { - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_read); - ret = sdio_read_addr(func, address, data, data_size); - } - - WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE( - whd_driver->bus_priv, ((ret != WHD_SUCCESS) && (direction == BUS_READ)), - cmd53_read_fail); - WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE( - whd_driver->bus_priv, ((ret != WHD_SUCCESS) && (direction == BUS_WRITE)), - cmd53_write_fail); - - CHECK_RETURN(ret); - return WHD_SUCCESS; -} - -/* - * Implement SDIO Card interrupt - */ - -void whd_bus_sdio_irq_handler(const struct device *dev, int reason, const void *user_data) -{ - if (reason == SDHC_INT_SDIO) { - whd_driver_t whd_driver = (whd_driver_t)user_data; - - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, sdio_intrs); - - /* call thread notify to wake up WHD thread */ - whd_thread_notify_irq(whd_driver); - } -} - -whd_result_t whd_bus_sdio_irq_register(whd_driver_t whd_driver) -{ - /* Nothing to do here, all handles by whd_bus_sdio_irq_enable function */ - return WHD_SUCCESS; -} - -whd_result_t whd_bus_sdio_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) -{ - int ret; - struct sd_card *sd = whd_driver->bus_priv->sdio_obj; - - /* Enable/disable SDIO Card interrupts */ - if (enable) { - ret = sdhc_enable_interrupt(sd->sdhc, whd_bus_sdio_irq_handler, SDHC_INT_SDIO, - whd_driver); - } else { - ret = sdhc_disable_interrupt(sd->sdhc, SDHC_INT_SDIO); - } - return ret; -} - -/* - * Implement OOB functionality - */ - -void whd_bus_sdio_oob_irq_handler(const struct device *port, struct gpio_callback *cb, - gpio_port_pins_t pins) -{ -#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) - struct airoc_wifi_data *data = CONTAINER_OF(cb, struct airoc_wifi_data, host_oob_pin_cb); - - /* Get OOB pin info */ - const whd_oob_config_t *oob_config = &data->whd_drv->bus_priv->sdio_config.oob_config; - const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; - - /* Check OOB state is correct */ - int expected_event = (oob_config->is_falling_edge == WHD_TRUE) ? 0 : 1; - - if (!(pins & BIT(host_oob_pin->pin)) || (gpio_pin_get_dt(host_oob_pin) != expected_event)) { - WPRINT_WHD_ERROR(("Unexpected interrupt event %d\n", expected_event)); - WHD_BUS_STATS_INCREMENT_VARIABLE(data->whd_drv->bus_priv, error_intrs); - return; - } - - WHD_BUS_STATS_INCREMENT_VARIABLE(data->whd_drv->bus_priv, oob_intrs); - - /* Call thread notify to wake up WHD thread */ - whd_thread_notify_irq(data->whd_drv); - -#endif /* DT_INST_NODE_HAS_PROP(0, wifi-host-wake-gpios) */ -} - -whd_result_t whd_bus_sdio_register_oob_intr(whd_driver_t whd_driver) -{ -#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) - int ret; - const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); - struct airoc_wifi_data *data = dev->data; - - /* Get OOB pin info */ - const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; - const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; - - /* Check if OOB pin is ready */ - if (!gpio_is_ready_dt(host_oob_pin)) { - WPRINT_WHD_ERROR(("%s: Failed at gpio_is_ready_dt for host_oob_pin\n", __func__)); - return WHD_HAL_ERROR; - } - - /* Configure OOB pin as output */ - ret = gpio_pin_configure_dt(host_oob_pin, GPIO_INPUT); - if (ret != 0) { - WPRINT_WHD_ERROR(( - " %s: Failed at gpio_pin_configure_dt for host_oob_pin, result code = %d\n", - __func__, ret)); - return WHD_HAL_ERROR; - } - - /* Initialize/add OOB pin callback */ - gpio_init_callback(&data->host_oob_pin_cb, whd_bus_sdio_oob_irq_handler, - BIT(host_oob_pin->pin)); - - ret = gpio_add_callback_dt(host_oob_pin, &data->host_oob_pin_cb); - if (ret != 0) { - WPRINT_WHD_ERROR( - ("%s: Failed at gpio_add_callback_dt for host_oob_pin, result code = %d\n", - __func__, ret)); - return WHD_HAL_ERROR; - } -#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ - - return WHD_SUCCESS; -} - -whd_result_t whd_bus_sdio_unregister_oob_intr(whd_driver_t whd_driver) -{ -#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) - int ret; - const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; - - /* Disable OOB pin interrupts */ - ret = gpio_pin_interrupt_configure_dt(oob_config->host_oob_pin, GPIO_INT_DISABLE); - if (ret != 0) { - WPRINT_WHD_ERROR(("%s: Failed at gpio_pin_interrupt_configure_dt for host_oob_pin, " - "result code = %d\n", - __func__, ret)); - return WHD_HAL_ERROR; - } -#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ - return WHD_SUCCESS; -} - -whd_result_t whd_bus_sdio_enable_oob_intr(whd_driver_t whd_driver, whd_bool_t enable) -{ -#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) - int ret; - const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; - uint32_t trig_conf = - (oob_config->is_falling_edge == WHD_TRUE) ? GPIO_INT_TRIG_LOW : GPIO_INT_TRIG_HIGH; - - /* Enable OOB pin interrupts */ - ret = gpio_pin_interrupt_configure_dt(oob_config->host_oob_pin, - GPIO_INT_ENABLE | GPIO_INT_EDGE | trig_conf); - if (ret != 0) { - WPRINT_WHD_ERROR(("%s: Failed at gpio_pin_interrupt_configure_dt for host_oob_pin, " - "result code = %d\n", - __func__, ret)); - return WHD_HAL_ERROR; - } -#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ - return WHD_SUCCESS; -} - -/* - * Implement WHD memory wrappers - */ - -void *whd_mem_malloc(size_t size) -{ - return k_malloc(size); -} - -void *whd_mem_calloc(size_t nitems, size_t size) -{ - return k_calloc(nitems, size); -} - -void whd_mem_free(void *ptr) -{ - k_free(ptr); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/drivers/wifi/infineon/airoc_whd_hal_common.c b/drivers/wifi/infineon/airoc_whd_hal_common.c new file mode 100644 index 0000000000000..d98c6532bbbc1 --- /dev/null +++ b/drivers/wifi/infineon/airoc_whd_hal_common.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "airoc_whd_hal_common.h" +#include "airoc_wifi.h" + +#include +#include + +LOG_MODULE_DECLARE(infineon_airoc_wifi, CONFIG_WIFI_LOG_LEVEL); + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** + * Function + ******************************************************/ + +int airoc_wifi_power_on(const struct device *dev) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_reg_on_gpios) + int ret; + const struct airoc_wifi_config *config = dev->config; + + /* Check WIFI REG_ON gpio instance */ + if (!device_is_ready(config->wifi_reg_on_gpio.port)) { + LOG_ERR("Error: failed to configure wifi_reg_on %s pin %d", + config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin); + return -EIO; + } + + /* Configure wifi_reg_on as output */ + ret = gpio_pin_configure_dt(&config->wifi_reg_on_gpio, GPIO_OUTPUT); + if (ret) { + LOG_ERR("Error %d: failed to configure wifi_reg_on %s pin %d", ret, + config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin); + return ret; + } + ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 0); + if (ret) { + return ret; + } + + /* Allow CBUCK regulator to discharge */ + k_msleep(WLAN_CBUCK_DISCHARGE_MS); + + /* WIFI power on */ + ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 1); + if (ret) { + return ret; + } + k_msleep(WLAN_POWER_UP_DELAY_MS); +#endif /* DT_INST_NODE_HAS_PROP(0, reg_on_gpios) */ + + return 0; +} + +/* + * Implement WHD memory wrappers + */ + +void *whd_mem_malloc(size_t size) +{ + return k_malloc(size); +} + +void *whd_mem_calloc(size_t nitems, size_t size) +{ + return k_calloc(nitems, size); +} + +void whd_mem_free(void *ptr) +{ + k_free(ptr); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/drivers/wifi/infineon/airoc_whd_hal_common.h b/drivers/wifi/infineon/airoc_whd_hal_common.h new file mode 100644 index 0000000000000..588073d5a39f0 --- /dev/null +++ b/drivers/wifi/infineon/airoc_whd_hal_common.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/** Defines the amount of stack memory available for the wifi thread. */ +#if !defined(CY_WIFI_THREAD_STACK_SIZE) +#define CY_WIFI_THREAD_STACK_SIZE (5120) +#endif + +/** Defines the priority of the thread that services wifi packets. Legal values are defined by the + * RTOS being used. + */ +#if !defined(CY_WIFI_THREAD_PRIORITY) +#define CY_WIFI_THREAD_PRIORITY (CY_RTOS_PRIORITY_HIGH) +#endif + +/** Defines the country this will operate in for wifi initialization parameters. See the + * wifi-host-driver's whd_country_code_t for legal options. + */ +#if !defined(CY_WIFI_COUNTRY) +#define CY_WIFI_COUNTRY (WHD_COUNTRY_AUSTRALIA) +#endif + +/** Defines the priority of the interrupt that handles out-of-band notifications from the wifi + * chip. Legal values are defined by the MCU running this code. + */ +#if !defined(CY_WIFI_OOB_INTR_PRIORITY) +#define CY_WIFI_OOB_INTR_PRIORITY (2) +#endif + +/** Defines whether to use the out-of-band pin to allow the WIFI chip to wake up the MCU. */ +#if defined(CY_WIFI_HOST_WAKE_SW_FORCE) +#define CY_USE_OOB_INTR (CY_WIFI_HOST_WAKE_SW_FORCE) +#else +#define CY_USE_OOB_INTR (1u) +#endif /* defined(CY_WIFI_HOST_WAKE_SW_FORCE) */ + +#define CY_WIFI_HOST_WAKE_IRQ_EVENT GPIO_INT_TRIG_LOW +#define DEFAULT_OOB_PIN (0) +#define WLAN_POWER_UP_DELAY_MS (250) +#define WLAN_CBUCK_DISCHARGE_MS (10) + +extern whd_resource_source_t resource_ops; + +int airoc_wifi_power_on(const struct device *dev); diff --git a/drivers/wifi/infineon/airoc_whd_hal_sdio.c b/drivers/wifi/infineon/airoc_whd_hal_sdio.c new file mode 100644 index 0000000000000..4cc522c03198d --- /dev/null +++ b/drivers/wifi/infineon/airoc_whd_hal_sdio.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "airoc_wifi.h" +#include "airoc_whd_hal_common.h" + +#include +#include +#include +#include + +LOG_MODULE_DECLARE(infineon_airoc_wifi, CONFIG_WIFI_LOG_LEVEL); + +#ifdef __cplusplus +extern "C" { +#endif + +struct whd_bus_priv { + whd_sdio_config_t sdio_config; + whd_bus_stats_t whd_bus_stats; + whd_sdio_t sdio_obj; +}; + +static whd_init_config_t init_config_default = {.thread_stack_size = CY_WIFI_THREAD_STACK_SIZE, + .thread_stack_start = NULL, + .thread_priority = + (uint32_t)CY_WIFI_THREAD_PRIORITY, + .country = CY_WIFI_COUNTRY}; + +/****************************************************** + * Function + ******************************************************/ + +int airoc_wifi_init_primary(const struct device *dev, whd_interface_t *interface, + whd_netif_funcs_t *netif_funcs, whd_buffer_funcs_t *buffer_if) +{ + int ret; + struct airoc_wifi_data *data = dev->data; + const struct airoc_wifi_config *config = dev->config; + + whd_sdio_config_t whd_sdio_config = { + .sdio_1bit_mode = WHD_FALSE, + .high_speed_sdio_clock = WHD_FALSE, + }; + +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + whd_oob_config_t oob_config = { + .host_oob_pin = (void *)&config->wifi_host_wake_gpio, + .dev_gpio_sel = DEFAULT_OOB_PIN, + .is_falling_edge = + (CY_WIFI_HOST_WAKE_IRQ_EVENT == GPIO_INT_TRIG_LOW) ? WHD_TRUE : WHD_FALSE, + .intr_priority = CY_WIFI_OOB_INTR_PRIORITY}; + whd_sdio_config.oob_config = oob_config; +#endif + + if (airoc_wifi_power_on(dev)) { + LOG_ERR("airoc_wifi_power_on retuens fail"); + return -ENODEV; + } + + if (!device_is_ready(config->bus_dev.bus_sdio)) { + LOG_ERR("SDHC device is not ready"); + return -ENODEV; + } + + ret = sd_init(config->bus_dev.bus_sdio, &data->card); + if (ret) { + return ret; + } + + /* Init SDIO functions */ + ret = sdio_init_func(&data->card, &data->sdio_func1, BACKPLANE_FUNCTION); + if (ret) { + LOG_ERR("sdio_enable_func BACKPLANE_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_init_func(&data->card, &data->sdio_func2, WLAN_FUNCTION); + if (ret) { + LOG_ERR("sdio_enable_func WLAN_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_set_block_size(&data->sdio_func1, SDIO_64B_BLOCK); + if (ret) { + LOG_ERR("Can't set block size for BACKPLANE_FUNCTION, error: %x", ret); + return ret; + } + ret = sdio_set_block_size(&data->sdio_func2, SDIO_64B_BLOCK); + if (ret) { + LOG_ERR("Can't set block size for WLAN_FUNCTION, error: %x", ret); + return ret; + } + + /* Init wifi host driver (whd) */ + cy_rslt_t whd_ret = whd_init(&data->whd_drv, &init_config_default, &resource_ops, buffer_if, + netif_funcs); + if (whd_ret == CY_RSLT_SUCCESS) { + whd_ret = whd_bus_sdio_attach(data->whd_drv, &whd_sdio_config, + (whd_sdio_t)&data->card); + + if (whd_ret == CY_RSLT_SUCCESS) { + whd_ret = whd_wifi_on(data->whd_drv, interface); + } + + if (whd_ret != CY_RSLT_SUCCESS) { + whd_deinit(*interface); + return -ENODEV; + } + } + return 0; +} + +/* + * Implement SDIO CMD52/53 wrappers + */ + +static struct sdio_func *airoc_wifi_get_sdio_func(struct sd_card *sd, whd_bus_function_t function) +{ + struct airoc_wifi_data *data = CONTAINER_OF(sd, struct airoc_wifi_data, card); + struct sdio_func *func[] = {&sd->func0, &data->sdio_func1, &data->sdio_func2}; + + if (function > WLAN_FUNCTION) { + return NULL; + } + + return func[function]; +} + +whd_result_t whd_bus_sdio_cmd52(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, uint8_t value, + sdio_response_needed_t response_expected, uint8_t *response) +{ + int ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + struct sdio_func *func = airoc_wifi_get_sdio_func(sd, function); + + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd52); + + if (direction == BUS_WRITE) { + ret = sdio_rw_byte(func, address, value, response); + } else { + ret = sdio_read_byte(func, address, response); + } + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, (ret != WHD_SUCCESS), + cmd52_fail); + + /* Possibly device might not respond to this cmd. So, don't check return value here */ + if ((ret != WHD_SUCCESS) && (address == SDIO_SLEEP_CSR)) { + return ret; + } + + CHECK_RETURN(ret); + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_cmd53(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, sdio_transfer_mode_t mode, + uint32_t address, uint16_t data_size, uint8_t *data, + sdio_response_needed_t response_expected, uint32_t *response) +{ + whd_result_t ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + struct sdio_func *func = airoc_wifi_get_sdio_func(sd, function); + + if (direction == BUS_WRITE) { + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_write); + ret = sdio_write_addr(func, address, data, data_size); + } else { + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_read); + ret = sdio_read_addr(func, address, data, data_size); + } + + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE( + whd_driver->bus_priv, ((ret != WHD_SUCCESS) && (direction == BUS_READ)), + cmd53_read_fail); + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE( + whd_driver->bus_priv, ((ret != WHD_SUCCESS) && (direction == BUS_WRITE)), + cmd53_write_fail); + + CHECK_RETURN(ret); + return WHD_SUCCESS; +} + +/* + * Implement SDIO Card interrupt + */ + +void whd_bus_sdio_irq_handler(const struct device *dev, int reason, const void *user_data) +{ + if (reason == SDHC_INT_SDIO) { + whd_driver_t whd_driver = (whd_driver_t)user_data; + + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, sdio_intrs); + + /* call thread notify to wake up WHD thread */ + whd_thread_notify_irq(whd_driver); + } +} + +whd_result_t whd_bus_sdio_irq_register(whd_driver_t whd_driver) +{ + /* Nothing to do here, all handles by whd_bus_sdio_irq_enable function */ + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) +{ + int ret; + struct sd_card *sd = whd_driver->bus_priv->sdio_obj; + + /* Enable/disable SDIO Card interrupts */ + if (enable) { + ret = sdhc_enable_interrupt(sd->sdhc, whd_bus_sdio_irq_handler, SDHC_INT_SDIO, + whd_driver); + } else { + ret = sdhc_disable_interrupt(sd->sdhc, SDHC_INT_SDIO); + } + return ret; +} + +/* + * Implement OOB functionality + */ + +void whd_bus_sdio_oob_irq_handler(const struct device *port, struct gpio_callback *cb, + gpio_port_pins_t pins) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + struct airoc_wifi_data *data = CONTAINER_OF(cb, struct airoc_wifi_data, host_oob_pin_cb); + + /* Get OOB pin info */ + const whd_oob_config_t *oob_config = &data->whd_drv->bus_priv->sdio_config.oob_config; + const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; + + /* Check OOB state is correct */ + int expected_event = (oob_config->is_falling_edge == WHD_TRUE) ? 0 : 1; + + if (!(pins & BIT(host_oob_pin->pin)) || (gpio_pin_get_dt(host_oob_pin) != expected_event)) { + WPRINT_WHD_ERROR(("Unexpected interrupt event %d\n", expected_event)); + WHD_BUS_STATS_INCREMENT_VARIABLE(data->whd_drv->bus_priv, error_intrs); + return; + } + + WHD_BUS_STATS_INCREMENT_VARIABLE(data->whd_drv->bus_priv, oob_intrs); + + /* Call thread notify to wake up WHD thread */ + whd_thread_notify_irq(data->whd_drv); + +#endif /* DT_INST_NODE_HAS_PROP(0, wifi-host-wake-gpios) */ +} + +whd_result_t whd_bus_sdio_register_oob_intr(whd_driver_t whd_driver) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct airoc_wifi_data *data = dev->data; + + /* Get OOB pin info */ + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; + + /* Check if OOB pin is ready */ + if (!gpio_is_ready_dt(host_oob_pin)) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_is_ready_dt for host_oob_pin\n", __func__)); + return WHD_HAL_ERROR; + } + + /* Configure OOB pin as output */ + ret = gpio_pin_configure_dt(host_oob_pin, GPIO_INPUT); + if (ret != 0) { + WPRINT_WHD_ERROR(( + " %s: Failed at gpio_pin_configure_dt for host_oob_pin, result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } + + /* Initialize/add OOB pin callback */ + gpio_init_callback(&data->host_oob_pin_cb, whd_bus_sdio_oob_irq_handler, + BIT(host_oob_pin->pin)); + + ret = gpio_add_callback_dt(host_oob_pin, &data->host_oob_pin_cb); + if (ret != 0) { + WPRINT_WHD_ERROR( + ("%s: Failed at gpio_add_callback_dt for host_oob_pin, result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_unregister_oob_intr(whd_driver_t whd_driver) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + + /* Disable OOB pin interrupts */ + ret = gpio_pin_interrupt_configure_dt(oob_config->host_oob_pin, GPIO_INT_DISABLE); + if (ret != 0) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_pin_interrupt_configure_dt for host_oob_pin, " + "result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + return WHD_SUCCESS; +} + +whd_result_t whd_bus_sdio_enable_oob_intr(whd_driver_t whd_driver, whd_bool_t enable) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->sdio_config.oob_config; + uint32_t trig_conf = + (oob_config->is_falling_edge == WHD_TRUE) ? GPIO_INT_TRIG_LOW : GPIO_INT_TRIG_HIGH; + + /* Enable OOB pin interrupts */ + ret = gpio_pin_interrupt_configure_dt(oob_config->host_oob_pin, + GPIO_INT_ENABLE | GPIO_INT_EDGE | trig_conf); + if (ret != 0) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_pin_interrupt_configure_dt for host_oob_pin, " + "result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + return WHD_SUCCESS; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/drivers/wifi/infineon/airoc_whd_hal_spi.c b/drivers/wifi/infineon/airoc_whd_hal_spi.c new file mode 100644 index 0000000000000..d5a631a0f1d65 --- /dev/null +++ b/drivers/wifi/infineon/airoc_whd_hal_spi.c @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2024 Stephen Boylan (stephen.boylan@beechwoods.com) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "airoc_whd_hal_common.h" + +#include +#include +#include +#include + +LOG_MODULE_DECLARE(infineon_airoc_wifi, CONFIG_WIFI_LOG_LEVEL); + +#ifdef __cplusplus +extern "C" { +#endif + +struct whd_bus_priv { + whd_spi_config_t spi_config; + whd_spi_t spi_obj; +}; + +static whd_init_config_t init_config_default = {.thread_stack_size = CY_WIFI_THREAD_STACK_SIZE, + .thread_stack_start = NULL, + .thread_priority = + (uint32_t)CY_WIFI_THREAD_PRIORITY, + .country = CY_WIFI_COUNTRY}; + +/****************************************************** + * Function + ******************************************************/ + +int airoc_wifi_init_primary(const struct device *dev, whd_interface_t *interface, + whd_netif_funcs_t *netif_funcs, + whd_buffer_funcs_t *buffer_if) +{ + struct airoc_wifi_data *data = dev->data; + const struct airoc_wifi_config *config = dev->config; + + whd_spi_config_t whd_spi_config = { + .is_spi_normal_mode = WHD_FALSE, + }; + +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + whd_oob_config_t oob_config = { + .host_oob_pin = (void *)&config->wifi_host_wake_gpio, + .dev_gpio_sel = DEFAULT_OOB_PIN, + .is_falling_edge = + (CY_WIFI_HOST_WAKE_IRQ_EVENT == GPIO_INT_TRIG_LOW) ? WHD_TRUE : WHD_FALSE, + .intr_priority = CY_WIFI_OOB_INTR_PRIORITY}; + whd_spi_config.oob_config = oob_config; +#endif +#if defined(SPI_DATA_IRQ_SHARED) + data->prev_irq_state = 0; +#endif + + /* Pull bus select line low before enabling WiFi chip */ + gpio_pin_configure_dt(&config->bus_select_gpio, GPIO_OUTPUT_INACTIVE); + + if (airoc_wifi_power_on(dev)) { + LOG_ERR("airoc_wifi_power_on returns fail"); + return -ENODEV; + } + + if (!spi_is_ready_dt(&config->bus_dev.bus_spi)) { + LOG_ERR("SPI device is not ready"); + return -ENODEV; + } + + /* Init wifi host driver (whd) */ + cy_rslt_t whd_ret = whd_init(&data->whd_drv, &init_config_default, + &resource_ops, buffer_if, netif_funcs); + if (whd_ret == CY_RSLT_SUCCESS) { + whd_ret = whd_bus_spi_attach(data->whd_drv, &whd_spi_config, + (whd_spi_t)&config->bus_dev.bus_spi); + + if (whd_ret == CY_RSLT_SUCCESS) { + whd_ret = whd_wifi_on(data->whd_drv, interface); + } + + if (whd_ret != CY_RSLT_SUCCESS) { + whd_deinit(*interface); + return -ENODEV; + } + } + return 0; +} + +/* + * Implement SPI Transfer wrapper + */ + +whd_result_t whd_bus_spi_transfer(whd_driver_t whd_driver, const uint8_t *tx, size_t tx_length, + uint8_t *rx, size_t rx_length, uint8_t write_fill) +{ + const struct spi_dt_spec *spi_obj = whd_driver->bus_priv->spi_obj; + int ret; + whd_result_t whd_ret = WHD_SUCCESS; + +#if defined(SPI_DATA_IRQ_SHARED) + ret = whd_bus_spi_irq_enable(whd_driver, false); + if (ret) { + LOG_ERR("whd_bus_spi_irq_enable FAIL %d\n", ret); + whd_ret = WHD_WLAN_SDIO_ERROR; + } +#endif + + /* In some cases whd_bus_spi_protocol.c places the command at */ + /* the start of the rx buffer and passes NULL as the tx address, */ + /* reusing the same buffer (and overwriting the tx data). */ + if (tx == NULL && tx_length > 0 && rx_length >= tx_length) { + tx = rx; + } + + const struct spi_buf tx_buf = {.buf = (uint8_t *)tx, .len = tx_length}; + const struct spi_buf_set tx_set = {.buffers = &tx_buf, .count = 1}; + struct spi_buf rx_buf[2]; + struct spi_buf_set rx_set = {.buffers = rx_buf, .count = 2}; + + if (rx != NULL) { + rx += tx_length; + } + + if (rx_length >= tx_length) { + rx_length -= tx_length; + } else { + rx_length = 0; + } + + if (spi_obj->config.operation & SPI_HALF_DUPLEX) { + rx_buf[0].buf = rx; + rx_buf[0].len = rx_length; + rx_set.count = 1; + } else { + /* Talking to a half-duplex device via a full-duplex SPI driver, */ + /* it's necessary to ignore the data returned during send. The */ + /* SPI driver should not copy out the data if the buffer is NULL. */ + rx_buf[0].buf = NULL; + rx_buf[0].len = tx_length; + rx_buf[1].buf = rx; + rx_buf[1].len = rx_length; + } + + ret = spi_transceive_dt(spi_obj, &tx_set, &rx_set); + if (ret) { + LOG_ERR("spi_transceive FAIL %d\n", ret); + whd_ret = WHD_WLAN_SDIO_ERROR; + } + +#if defined(SPI_DATA_IRQ_SHARED) + ret = whd_bus_spi_irq_enable(whd_driver, true); + if (ret) { + LOG_ERR("whd_bus_spi_irq_enable FAIL %d\n", ret); + whd_ret = WHD_WLAN_SDIO_ERROR; + } +#endif + + return whd_ret; +} + +/* + * Implement OOB functionality + */ + +void whd_bus_spi_oob_irq_handler(const struct device *port, struct gpio_callback *cb, + gpio_port_pins_t pins) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + struct airoc_wifi_data *data = CONTAINER_OF(cb, struct airoc_wifi_data, host_oob_pin_cb); + + /* Get OOB pin info */ + const whd_oob_config_t *oob_config = &data->whd_drv->bus_priv->spi_config.oob_config; + const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; + + /* Check OOB state is correct */ + int expected_event = (oob_config->is_falling_edge == WHD_TRUE) ? 0 : 1; + + if (!(pins & BIT(host_oob_pin->pin)) || (gpio_pin_get_dt(host_oob_pin) != expected_event)) { + WPRINT_WHD_ERROR(("Unexpected interrupt event %d\n", expected_event)); + return; + } + + /* Call thread notify to wake up WHD thread */ + whd_thread_notify_irq(data->whd_drv); + +#endif /* DT_INST_NODE_HAS_PROP(0, wifi-host-wake-gpios) */ +} + +whd_result_t whd_bus_spi_irq_register(whd_driver_t whd_driver) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct airoc_wifi_data *data = dev->data; + + /* Get OOB pin info */ + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->spi_config.oob_config; + const struct gpio_dt_spec *host_oob_pin = oob_config->host_oob_pin; + + /* Check if OOB pin is ready */ + if (!gpio_is_ready_dt(host_oob_pin)) { + WPRINT_WHD_ERROR(("%s: Failed at gpio_is_ready_dt for host_oob_pin\n", __func__)); + return WHD_HAL_ERROR; + } + + /* Configure OOB pin as input */ + ret = gpio_pin_configure_dt(host_oob_pin, GPIO_INPUT); + if (ret != 0) { + WPRINT_WHD_ERROR(( + " %s: Failed at gpio_pin_configure_dt for host_oob_pin, result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } + + /* Initialize/add OOB pin callback */ + gpio_init_callback(&data->host_oob_pin_cb, whd_bus_spi_oob_irq_handler, + BIT(host_oob_pin->pin)); + + ret = gpio_add_callback_dt(host_oob_pin, &data->host_oob_pin_cb); + if (ret != 0) { + WPRINT_WHD_ERROR( + ("%s: Failed at gpio_add_callback_dt for host_oob_pin, result code = %d\n", + __func__, ret)); + return WHD_HAL_ERROR; + } +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + + return WHD_SUCCESS; +} + +whd_result_t whd_bus_spi_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) +{ +#if DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) + int ret; + const whd_oob_config_t *oob_config = &whd_driver->bus_priv->spi_config.oob_config; + struct gpio_dt_spec *gpio = (struct gpio_dt_spec *)oob_config->host_oob_pin; + +#if defined(SPI_DATA_IRQ_SHARED) + const struct device *dev = DEVICE_DT_INST_GET(0); + const struct airoc_wifi_config *config = dev->config; + struct airoc_wifi_data *data = dev->data; + + if (enable) { + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_HOST_WAKE); + __ASSERT(ret == 0, "could not apply pinconfig, return code %d", ret); + ret = gpio_pin_interrupt_configure_dt( + gpio, (oob_config->is_falling_edge == WHD_TRUE) ? GPIO_INT_EDGE_FALLING + : GPIO_INT_EDGE_RISING); + __ASSERT(ret == 0, "gpio_pin_interrupt_configure_dt failed, return code %d", ret); + + int state = gpio_pin_get_dt(gpio); + int expected_event = (oob_config->is_falling_edge == WHD_TRUE) ? 0 : 1; + + /* Notify only if interrupt wasn't assert before. This code assumes that if */ + /* the interrupt was previously asserted, then the thread has already been */ + /* notified. */ + if (state == expected_event && state != data->prev_irq_state) { + whd_thread_notify_irq(whd_driver); + } + } else { + data->prev_irq_state = gpio_pin_get_dt(gpio); + ret = gpio_pin_interrupt_configure_dt(gpio, GPIO_INT_DISABLE); + __ASSERT(ret == 0, "gpio_pin_interrupt_configure_dt failed, return code %d", ret); + pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + } +#else + if (enable) { + ret = gpio_pin_interrupt_configure_dt( + gpio, (oob_config->is_falling_edge == WHD_TRUE) ? GPIO_INT_EDGE_FALLING + : GPIO_INT_EDGE_RISING); + __ASSERT(ret == 0, "gpio_pin_interrupt_configure_dt failed, return code %d", ret); + } else { + ret = gpio_pin_interrupt_configure_dt(gpio, GPIO_INT_DISABLE); + __ASSERT(ret == 0, "gpio_pin_interrupt_configure_dt failed, return code %d", ret); + } +#endif /* defined(SPI_DATA_IRQ_SHARED) */ + +#endif /* DT_INST_NODE_HAS_PROP(0, wifi_host_wake_gpios) */ + + return WHD_SUCCESS; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/drivers/wifi/infineon/airoc_wifi.c b/drivers/wifi/infineon/airoc_wifi.c index 330227fd359c2..7960dee75bed1 100644 --- a/drivers/wifi/infineon/airoc_wifi.c +++ b/drivers/wifi/infineon/airoc_wifi.c @@ -9,11 +9,10 @@ * @brief AIROC Wi-Fi driver. */ -#define DT_DRV_COMPAT infineon_airoc_wifi - #include #include #include +#include LOG_MODULE_REGISTER(infineon_airoc_wifi, CONFIG_WIFI_LOG_LEVEL); @@ -76,8 +75,20 @@ static uint16_t sta_event_handler_index = 0xFF; static void airoc_event_task(void); static struct airoc_wifi_data airoc_wifi_data = {0}; +#if defined(SPI_DATA_IRQ_SHARED) +PINCTRL_DT_INST_DEFINE(0); +#endif + static struct airoc_wifi_config airoc_wifi_config = { - .sdhc_dev = DEVICE_DT_GET(DT_INST_PARENT(0)), +#if defined(CONFIG_AIROC_WIFI_BUS_SDIO) + .bus_dev.bus_sdio = DEVICE_DT_GET(DT_INST_PARENT(0)), +#elif defined(CONFIG_AIROC_WIFI_BUS_SPI) + .bus_dev.bus_spi = SPI_DT_SPEC_GET(DT_DRV_INST(0), AIROC_WIFI_SPI_OPERATION, 0), + .bus_select_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), bus_select_gpios, {0}), +#if defined(SPI_DATA_IRQ_SHARED) + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), +#endif +#endif .wifi_reg_on_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_reg_on_gpios, {0}), .wifi_host_wake_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_host_wake_gpios, {0}), .wifi_dev_wake_gpio = GPIO_DT_SPEC_GET_OR(DT_DRV_INST(0), wifi_dev_wake_gpios, {0}), diff --git a/drivers/wifi/infineon/airoc_wifi.h b/drivers/wifi/infineon/airoc_wifi.h index 1bf688e5d72c1..8b308e364140e 100644 --- a/drivers/wifi/infineon/airoc_wifi.h +++ b/drivers/wifi/infineon/airoc_wifi.h @@ -6,16 +6,44 @@ */ #include -#include -#include #include #include + +#ifdef CONFIG_AIROC_WIFI_BUS_SDIO +#include +#include +#endif +#ifdef CONFIG_AIROC_WIFI_BUS_SPI +#include +#endif + #include +#define DT_DRV_COMPAT infineon_airoc_wifi + +#if DT_PROP(DT_DRV_INST(0), spi_data_irq_shared) +#define SPI_DATA_IRQ_SHARED +#include + +#define PINCTRL_STATE_HOST_WAKE PINCTRL_STATE_PRIV_START +#endif + +#if defined(CONFIG_AIROC_WIFI_BUS_SPI) +#define AIROC_WIFI_SPI_OPERATION (SPI_WORD_SET(DT_PROP_OR(DT_DRV_INST(0), spi_word_size, 8)) \ + | (DT_PROP(DT_DRV_INST(0), spi_half_duplex) \ + ? SPI_HALF_DUPLEX : SPI_FULL_DUPLEX) \ + | SPI_TRANSFER_MSB) +#endif + struct airoc_wifi_data { +#if defined(CONFIG_AIROC_WIFI_BUS_SDIO) struct sd_card card; struct sdio_func sdio_func1; struct sdio_func sdio_func2; +#endif +#if defined(SPI_DATA_IRQ_SHARED) + uint8_t prev_irq_state; +#endif struct net_if *iface; bool second_interface_init; bool is_ap_up; @@ -34,11 +62,26 @@ struct airoc_wifi_data { uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE]; }; +union airoc_wifi_bus { +#if defined(CONFIG_AIROC_WIFI_BUS_SDIO) + const struct device *bus_sdio; +#endif +#if defined(CONFIG_AIROC_WIFI_BUS_SPI) + const struct spi_dt_spec bus_spi; +#endif +}; + struct airoc_wifi_config { - const struct device *sdhc_dev; + const union airoc_wifi_bus bus_dev; struct gpio_dt_spec wifi_reg_on_gpio; struct gpio_dt_spec wifi_host_wake_gpio; struct gpio_dt_spec wifi_dev_wake_gpio; +#if defined(CONFIG_AIROC_WIFI_BUS_SPI) + struct gpio_dt_spec bus_select_gpio; +#if defined(SPI_DATA_IRQ_SHARED) + const struct pinctrl_dev_config *pcfg; +#endif +#endif }; /** diff --git a/drivers/wifi/infineon/cybsp.h b/drivers/wifi/infineon/cybsp.h index dfa23ffbae53f..ef3712443d79d 100644 --- a/drivers/wifi/infineon/cybsp.h +++ b/drivers/wifi/infineon/cybsp.h @@ -5,4 +5,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -/* This is enpty/stub file used in WHD */ +/* required by whd_* header files. */ + +/* See cybsp_types.h, which is usually required by this file, but not available */ +/* here unless we pull in board-specific headers from the upstream driver. */ +#define CYBSP_SDIO_INTERFACE (0) +#define CYBSP_SPI_INTERFACE (1) + +#ifdef CONFIG_AIROC_WIFI_BUS_SDIO +#define CYBSP_WIFI_INTERFACE_TYPE CYBSP_SDIO_INTERFACE +#elif CONFIG_AIROC_WIFI_BUS_SPI +#define CYBSP_WIFI_INTERFACE_TYPE CYBSP_SPI_INTERFACE +#endif diff --git a/drivers/wifi/nrf_wifi/CMakeLists.txt b/drivers/wifi/nrf_wifi/CMakeLists.txt index 27d8ba8081c75..41a06e912f8ed 100644 --- a/drivers/wifi/nrf_wifi/CMakeLists.txt +++ b/drivers/wifi/nrf_wifi/CMakeLists.txt @@ -41,7 +41,7 @@ zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_MGMT src/wifi_mgmt_scan.c ) -zephyr_library_sources_ifdef(CONFIG_NRF70_SYSTEM_MODE_COMMON +zephyr_library_sources_ifdef(CONFIG_NRF70_SYSTEM_MODE src/wifi_mgmt.c ) @@ -73,26 +73,21 @@ zephyr_compile_definitions_ifdef(CONFIG_NRF70_ON_QSPI -DNRF53_ERRATA_159_ENABLE_WORKAROUND=0 ) -target_link_libraries(nrf_wifi PRIVATE nrf70-buslib) +zephyr_library_link_libraries(nrf70-buslib nrf-wifi-shim) -if (CONFIG_NRF_WIFI_BUILD_ONLY_MODE) - message(WARNING " - ------------------------------------------------------------------------ - Building only the nRF70 driver, skipping firmware patch. - This is only for building (CI) purposes and will not work on a real device. - ------------------------------------------------------------------------ - ") -elseif(CONFIG_NRF_WIFI_PATCHES_BUILTIN) +if (CONFIG_NRF_WIFI_PATCHES_BUILTIN) zephyr_blobs_verify(MODULE nrf_wifi REQUIRED) # RPU FW patch binaries based on the selected configuration if(CONFIG_NRF70_SYSTEM_MODE) - set(NRF70_PATCH ${FW_BINS_BASE}/default/nrf70.bin) + if (CONFIG_NRF70_SYSTEM_WITH_RAW_MODES) + set(NRF70_PATCH ${FW_BINS_BASE}/system_with_raw/nrf70.bin) + else() + set(NRF70_PATCH ${FW_BINS_BASE}/default/nrf70.bin) + endif() elseif(CONFIG_NRF70_RADIO_TEST) set(NRF70_PATCH ${FW_BINS_BASE}/radio_test/nrf70.bin) elseif(CONFIG_NRF70_SCAN_ONLY) set(NRF70_PATCH ${FW_BINS_BASE}/scan_only/nrf70.bin) - elseif (CONFIG_NRF70_SYSTEM_WITH_RAW_MODES) - set(NRF70_PATCH ${FW_BINS_BASE}/system_with_raw/nrf70.bin) elseif(CONFIG_NRF70_OFFLOADED_RAW_TX) set(NRF70_PATCH ${FW_BINS_BASE}/offloaded_raw_tx/nrf70.bin) else() diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index 6542dc2d0989a..613709b5e6e1f 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -40,43 +40,29 @@ config NRF70_QSPI_LOW_POWER choice NRF70_OPER_MODES bool "nRF70 operating modes" - default NRF70_SYSTEM_WITH_RAW_MODES if !WIFI_NRF7000 && \ - (NRF70_RAW_DATA_TX || NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX) default NRF70_SYSTEM_MODE if !WIFI_NRF7000 default NRF70_SCAN_ONLY if WIFI_NRF7000 help Select the operating mode of the nRF70 driver -config NRF70_SYSTEM_MODE - bool "nRF70 system mode" - depends on WIFI_NRF7002 || WIFI_NRF7001 - select WIFI_NM_WPA_SUPPLICANT - help - Select this option to enable system mode of the nRF70 driver - config NRF70_SCAN_ONLY bool "nRF70 scan only mode" help Select this option to enable scan only mode of the nRF70 driver +config NRF70_SYSTEM_MODE + bool "System mode of the nRF70 driver" + help + Select this option to enable system mode of the nRF70 driver + config NRF70_RADIO_TEST bool "Radio test mode of the nRF70 driver" config NRF70_OFFLOADED_RAW_TX bool "Offloaded raw TX mode of the nRF70 driver" -config NRF70_SYSTEM_WITH_RAW_MODES - bool "nRF70 system mode with raw modes" - depends on WIFI_NRF7002 || WIFI_NRF7001 - select WIFI_NM_WPA_SUPPLICANT - help - Select this option to enable system mode of the nRF70 driver with raw modes. endchoice -config NRF70_SYSTEM_MODE_COMMON - bool - default y if NRF70_SYSTEM_MODE || NRF70_SYSTEM_WITH_RAW_MODES - config NET_L2_ETHERNET default y if (!NRF70_RADIO_TEST && !NRF70_OFFLOADED_RAW_TX) @@ -86,20 +72,31 @@ config HEAP_MEM_POOL_ADD_SIZE_NRF70 def_int 25000 if NRF70_SCAN_ONLY def_int 150000 -if NRF70_SYSTEM_MODE || NRF70_SYSTEM_WITH_RAW_MODES +if NRF70_SYSTEM_MODE config NRF70_STA_MODE bool "nRF70 STA mode" default y + depends on WIFI_NRF7002 || WIFI_NRF7001 + select WIFI_NM_WPA_SUPPLICANT + select NRF70_DATA_TX help Select this option to enable STA mode of the nRF70 driver. - config NRF70_AP_MODE bool "Access point mode" + depends on WIFI_NRF7002 || WIFI_NRF7001 + select NRF70_DATA_TX depends on WIFI_NM_WPA_SUPPLICANT_AP + default y if WIFI_NM_WPA_SUPPLICANT_AP config NRF70_P2P_MODE bool "P2P support in driver" -endif # NRF70_SYSTEM_MODE || NRF70_SYSTEM_WITH_RAW_MODES + +config NRF70_SYSTEM_WITH_RAW_MODES + bool + default y if (NRF70_RAW_DATA_TX || NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX) + depends on WIFI_NRF7002 || WIFI_NRF7001 + help + Select this option to enable system mode of the nRF70 driver with raw modes. config NRF70_RAW_DATA_TX bool "RAW TX data path in the driver" @@ -116,8 +113,8 @@ config NRF70_PROMISC_DATA_RX select NET_PROMISCUOUS_MODE config NRF70_DATA_TX - bool "TX data path in the driver" - default y if NRF70_SYSTEM_MODE || NRF70_SYSTEM_WITH_RAW_MODES + bool +endif # NRF70_SYSTEM_MODE config NRF_WIFI_IF_AUTO_START bool "Wi-Fi interface auto start on boot" @@ -125,15 +122,9 @@ config NRF_WIFI_IF_AUTO_START choice NRF_WIFI_FW_BLOB_HANDLING prompt "nRF70 Firmware blob handling" + depends on !BUILD_ONLY_NO_BLOBS default NRF_WIFI_PATCHES_BUILTIN -config NRF_WIFI_BUILD_ONLY_MODE - bool "Build only mode" - help - Enable this option to build the driver without firmware loading, removes - dependency on firmware binary and patches. - This is useful to check the build and link errors. - config NRF_WIFI_PATCHES_BUILTIN bool "Store nRF70 FW patches as part of the driver" help @@ -180,18 +171,6 @@ config WIFI_NRF70_LOG_LEVEL # Enable error by default default 1 -config NRF70_ON_QSPI - def_bool DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || \ - DT_HAS_NORDIC_NRF7001_QSPI_ENABLED || \ - DT_HAS_NORDIC_NRF7000_QSPI_ENABLED - select NRFX_QSPI - -config NRF70_ON_SPI - def_bool DT_HAS_NORDIC_NRF7002_SPI_ENABLED || \ - DT_HAS_NORDIC_NRF7001_SPI_ENABLED || \ - DT_HAS_NORDIC_NRF7000_SPI_ENABLED - select SPI - config NRF70_2_4G_ONLY def_bool y if WIFI_NRF7001 @@ -201,6 +180,12 @@ config NRF70_SR_COEX config NRF70_SR_COEX_RF_SWITCH bool "GPIO configuration to control SR side RF switch position" + depends on $(dt_node_has_prop,nrf70, srrf-switch-gpios) + depends on NRF70_SR_COEX + help + Select this option to enable GPIO configuration to control SR side RF switch position. + If this GPIO is asserted (1), the SR side RF switch is connected to the Wi-Fi side (shared antenna). + If this GPIO is de-asserted (0), the SR side RF switch is connected to the SR side (separate antenna). config NRF70_WORKQ_STACK_SIZE int "Stack size for workqueue" @@ -560,6 +545,12 @@ config NET_TC_TX_COUNT endif # NETWORKING +# nRF70 now uses variable buffers as default to optimize RAM usage. Default pool sizes are used, samples/apps can override +# for higher performance. +choice NET_PKT_DATA_ALLOC_TYPE + default NET_BUF_VARIABLE_DATA_SIZE +endchoice + config MAIN_STACK_SIZE default 4096 @@ -801,4 +792,21 @@ config NRF70_PASSIVE_SCAN_ONLY help Enable this configuration to force passive scan on all channels. This will override application-specified scan type. + +config NRF_WIFI_DISPLAY_SCAN_BSS_LIMIT + # Display scan BSS entries limit + # By default, the limit is 250 in scan-only mode and 150 in regular mode. + int "Display scan bss limit" + range 1 450 if NRF70_SCAN_ONLY + def_int 250 if NRF70_SCAN_ONLY + range 1 160 + def_int 150 + help + Number of BSS entries in scan result. + +config NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN + bool "Force disable priority window for scan in the case of coexistence with Short Range radio" + help + Enable this configuration to disable priority window for scan + in the case of coexistence with Short Range radio. endif # WIFI_NRF70 diff --git a/drivers/wifi/nrf_wifi/inc/fmac_main.h b/drivers/wifi/nrf_wifi/inc/fmac_main.h index de6780069b045..0d37a2f23710d 100644 --- a/drivers/wifi/nrf_wifi/inc/fmac_main.h +++ b/drivers/wifi/nrf_wifi/inc/fmac_main.h @@ -27,9 +27,11 @@ #ifdef CONFIG_NRF70_STA_MODE #include #endif /* CONFIG_NRF70_STA_MODE */ +#include +#else +#include #endif /* !CONFIG_NRF70_RADIO_TEST */ -#include #include #define NRF70_DRIVER_VERSION "1."KERNEL_VERSION_STRING @@ -142,7 +144,7 @@ void nrf_wifi_rpu_recovery_cb(void *vif_ctx, unsigned int event_len); #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */ #endif /* !CONFIG_NRF70_OFFLOADED_RAW_TX */ -#ifdef CONFIG_NRF_WIFI_BUILD_ONLY_MODE +#ifdef CONFIG_BUILD_ONLY_NO_BLOBS inline enum nrf_wifi_status nrf_wifi_fw_load(void *rpu_ctx) { (void)rpu_ctx; @@ -151,5 +153,5 @@ inline enum nrf_wifi_status nrf_wifi_fw_load(void *rpu_ctx) } #else enum nrf_wifi_status nrf_wifi_fw_load(void *rpu_ctx); -#endif /* CONFIG_NRF_WIFI_BUILD_ONLY_MODE */ +#endif /* CONFIG_BUILD_ONLY_NO_BLOBS */ #endif /* __ZEPHYR_FMAC_MAIN_H__ */ diff --git a/drivers/wifi/nrf_wifi/inc/net_if.h b/drivers/wifi/nrf_wifi/inc/net_if.h index 8d97802ba65c8..315740ac5d9df 100644 --- a/drivers/wifi/nrf_wifi/inc/net_if.h +++ b/drivers/wifi/nrf_wifi/inc/net_if.h @@ -15,8 +15,8 @@ #include #include #include -#include #include +#include #define UNICAST_MASK GENMASK(7, 1) #define LOCAL_BIT BIT(1) diff --git a/drivers/wifi/nrf_wifi/off_raw_tx/inc/off_raw_tx.h b/drivers/wifi/nrf_wifi/off_raw_tx/inc/off_raw_tx.h index 1cb6e25846213..68c31f24e4f7a 100644 --- a/drivers/wifi/nrf_wifi/off_raw_tx/inc/off_raw_tx.h +++ b/drivers/wifi/nrf_wifi/off_raw_tx/inc/off_raw_tx.h @@ -8,7 +8,7 @@ * @brief File containing internal structures for the offloaded raw TX feature in the driver. */ -#include "fmac_structs_common.h" +#include "offload_raw_tx/fmac_structs.h" #include "osal_api.h" struct nrf_wifi_ctx_zep { diff --git a/drivers/wifi/nrf_wifi/off_raw_tx/src/off_raw_tx_api.c b/drivers/wifi/nrf_wifi/off_raw_tx/src/off_raw_tx_api.c index 16bad4d50cf80..17825511787ba 100644 --- a/drivers/wifi/nrf_wifi/off_raw_tx/src/off_raw_tx_api.c +++ b/drivers/wifi/nrf_wifi/off_raw_tx/src/off_raw_tx_api.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #define DT_DRV_COMPAT nordic_wlan LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); @@ -146,7 +146,7 @@ int nrf70_off_raw_tx_init(uint8_t *mac_addr, unsigned char *country_code) key = k_spin_lock(&off_raw_tx_drv_priv.lock); - off_raw_tx_drv_priv.fmac_priv = nrf_wifi_fmac_off_raw_tx_init(); + off_raw_tx_drv_priv.fmac_priv = nrf_wifi_off_raw_tx_fmac_init(); if (off_raw_tx_drv_priv.fmac_priv == NULL) { LOG_ERR("%s: Failed to initialize nRF70 driver", @@ -158,8 +158,8 @@ int nrf70_off_raw_tx_init(uint8_t *mac_addr, unsigned char *country_code) rpu_ctx_zep->drv_priv_zep = &off_raw_tx_drv_priv; - rpu_ctx = nrf_wifi_fmac_dev_add(off_raw_tx_drv_priv.fmac_priv, - rpu_ctx_zep); + rpu_ctx = nrf_wifi_off_raw_tx_fmac_dev_add(off_raw_tx_drv_priv.fmac_priv, + rpu_ctx_zep); if (!rpu_ctx) { LOG_ERR("%s: Failed to add nRF70 device", __func__); rpu_ctx_zep = NULL; @@ -197,7 +197,7 @@ int nrf70_off_raw_tx_init(uint8_t *mac_addr, unsigned char *country_code) configure_board_dep_params(&board_params); - status = nrf_wifi_fmac_off_raw_tx_dev_init(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_off_raw_tx_fmac_dev_init(rpu_ctx_zep->rpu_ctx, #ifdef CONFIG_NRF_WIFI_LOW_POWER HW_SLEEP_ENABLE, #endif /* CONFIG_NRF_WIFI_LOW_POWER */ @@ -257,7 +257,7 @@ int nrf70_off_raw_tx_init(uint8_t *mac_addr, unsigned char *country_code) return 0; err: if (rpu_ctx) { - nrf_wifi_fmac_off_raw_tx_dev_rem(rpu_ctx); + nrf_wifi_fmac_dev_rem(rpu_ctx); rpu_ctx_zep->rpu_ctx = NULL; } @@ -278,8 +278,7 @@ void nrf70_off_raw_tx_deinit(void) return; } - nrf_wifi_fmac_off_raw_tx_deinit(off_raw_tx_drv_priv.fmac_priv); - nrf_wifi_osal_deinit(); + nrf_wifi_fmac_deinit(off_raw_tx_drv_priv.fmac_priv); k_spin_unlock(&off_raw_tx_drv_priv.lock, key); } @@ -362,7 +361,7 @@ int nrf70_off_raw_tx_conf_update(struct nrf_wifi_off_raw_tx_conf *conf) goto out; } - status = nrf_wifi_fmac_off_raw_tx_conf(fmac_dev_ctx, + status = nrf_wifi_off_raw_tx_fmac_conf(fmac_dev_ctx, off_ctrl_params, off_tx_params); if (status != NRF_WIFI_STATUS_SUCCESS) { @@ -399,7 +398,7 @@ int nrf70_off_raw_tx_start(struct nrf_wifi_off_raw_tx_conf *conf) goto out; } - status = nrf_wifi_fmac_off_raw_tx_start(off_raw_tx_drv_priv.rpu_ctx_zep.rpu_ctx); + status = nrf_wifi_off_raw_tx_fmac_start(off_raw_tx_drv_priv.rpu_ctx_zep.rpu_ctx); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nRF70 offloaded raw TX start failed", __func__); @@ -426,7 +425,7 @@ int nrf70_off_raw_tx_stop(void) goto out; } - status = nrf_wifi_fmac_off_raw_tx_stop(off_raw_tx_drv_priv.rpu_ctx_zep.rpu_ctx); + status = nrf_wifi_off_raw_tx_fmac_stop(off_raw_tx_drv_priv.rpu_ctx_zep.rpu_ctx); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nRF70 offloaded raw TX stop failed", __func__); @@ -455,10 +454,10 @@ int nrf70_off_raw_tx_stats(struct nrf_wifi_off_raw_tx_stats *off_raw_tx_stats) { int ret = -1; enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; - struct rpu_op_stats stats; + struct rpu_off_raw_tx_op_stats stats; k_spinlock_key_t key; - memset(&stats, 0, sizeof(struct rpu_op_stats)); + memset(&stats, 0, sizeof(stats)); key = k_spin_lock(&off_raw_tx_drv_priv.lock); @@ -467,14 +466,16 @@ int nrf70_off_raw_tx_stats(struct nrf_wifi_off_raw_tx_stats *off_raw_tx_stats) goto out; } - status = nrf_wifi_fmac_stats_get(off_raw_tx_drv_priv.rpu_ctx_zep.rpu_ctx, 0, &stats); + status = nrf_wifi_off_raw_tx_fmac_stats_get(off_raw_tx_drv_priv.rpu_ctx_zep.rpu_ctx, + 0, + &stats); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nRF70 offloaded raw TX stats failed", __func__); goto out; } - off_raw_tx_stats->off_raw_tx_pkt_sent = stats.fw.offloaded_raw_tx.offload_raw_tx_cnt; + off_raw_tx_stats->off_raw_tx_pkt_sent = stats.fw.offload_raw_tx_cnt; ret = 0; out: diff --git a/drivers/wifi/nrf_wifi/src/coex.c b/drivers/wifi/nrf_wifi/src/coex.c index 7bb89a07e9ed8..947bf8511a25d 100644 --- a/drivers/wifi/nrf_wifi/src/coex.c +++ b/drivers/wifi/nrf_wifi/src/coex.c @@ -247,10 +247,8 @@ int nrf_wifi_config_sr_switch(bool separate_antennas) if (separate_antennas) { gpio_pin_set_dt(&sr_rf_switch_spec, 0x0); - LOG_INF("GPIO P1.10 set to 0"); } else { gpio_pin_set_dt(&sr_rf_switch_spec, 0x1); - LOG_INF("GPIO P1.10 set to 1"); } return 0; diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index 470be6c805578..fa3e621697521 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -23,8 +23,7 @@ #include -#include -#include "fmac_util.h" +#include "common/fmac_util.h" #include #ifndef CONFIG_NRF70_RADIO_TEST @@ -37,8 +36,11 @@ #include #include #endif /* CONFIG_NRF70_STA_MODE */ -#include +#include +#include +#else +#include #endif /* !CONFIG_NRF70_RADIO_TEST */ #define DT_DRV_COMPAT nordic_wlan @@ -582,7 +584,11 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_add_zep(struct nrf_wifi_drv_priv_zep *drv rpu_ctx_zep->drv_priv_zep = drv_priv_zep; - rpu_ctx = nrf_wifi_fmac_dev_add(drv_priv_zep->fmac_priv, rpu_ctx_zep); +#ifdef CONFIG_NRF70_RADIO_TEST + rpu_ctx = nrf_wifi_rt_fmac_dev_add(drv_priv_zep->fmac_priv, rpu_ctx_zep); +#else + rpu_ctx = nrf_wifi_sys_fmac_dev_add(drv_priv_zep->fmac_priv, rpu_ctx_zep); +#endif /* CONFIG_NRF70_RADIO_TEST */ if (!rpu_ctx) { LOG_ERR("%s: nrf_wifi_fmac_dev_add failed", __func__); @@ -618,7 +624,7 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_add_zep(struct nrf_wifi_drv_priv_zep *drv configure_board_dep_params(&board_params); #ifdef CONFIG_NRF70_RADIO_TEST - status = nrf_wifi_fmac_dev_init_rt(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_rt_fmac_dev_init(rpu_ctx_zep->rpu_ctx, #ifdef CONFIG_NRF_WIFI_LOW_POWER sleep_type, #endif /* CONFIG_NRF_WIFI_LOW_POWER */ @@ -630,7 +636,7 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_add_zep(struct nrf_wifi_drv_priv_zep *drv &board_params, STRINGIFY(CONFIG_NRF70_REG_DOMAIN)); #else - status = nrf_wifi_fmac_dev_init(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_dev_init(rpu_ctx_zep->rpu_ctx, #ifdef CONFIG_NRF_WIFI_LOW_POWER sleep_type, #endif /* CONFIG_NRF_WIFI_LOW_POWER */ @@ -645,18 +651,14 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_add_zep(struct nrf_wifi_drv_priv_zep *drv if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_dev_init failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_dev_init failed", __func__); goto err; } return status; err: if (rpu_ctx) { -#ifdef CONFIG_NRF70_RADIO_TEST - nrf_wifi_fmac_dev_rem_rt(rpu_ctx); -#else nrf_wifi_fmac_dev_rem(rpu_ctx); -#endif /* CONFIG_NRF70_RADIO_TEST */ rpu_ctx_zep->rpu_ctx = NULL; } return status; @@ -668,13 +670,13 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_rem_zep(struct nrf_wifi_drv_priv_zep *drv rpu_ctx_zep = &drv_priv_zep->rpu_ctx_zep; #ifdef CONFIG_NRF70_RADIO_TEST - nrf_wifi_fmac_dev_deinit_rt(rpu_ctx_zep->rpu_ctx); - nrf_wifi_fmac_dev_rem_rt(rpu_ctx_zep->rpu_ctx); + nrf_wifi_rt_fmac_dev_deinit(rpu_ctx_zep->rpu_ctx); #else - nrf_wifi_fmac_dev_deinit(rpu_ctx_zep->rpu_ctx); - nrf_wifi_fmac_dev_rem(rpu_ctx_zep->rpu_ctx); + nrf_wifi_sys_fmac_dev_deinit(rpu_ctx_zep->rpu_ctx); #endif /* CONFIG_NRF70_RADIO_TEST */ + nrf_wifi_fmac_dev_rem(rpu_ctx_zep->rpu_ctx); + k_free(rpu_ctx_zep->extended_capa); rpu_ctx_zep->extended_capa = NULL; k_free(rpu_ctx_zep->extended_capa_mask); @@ -730,7 +732,7 @@ static int nrf_wifi_drv_main_zep(const struct device *dev) #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS callbk_fns.rx_bcn_prb_resp_callbk_fn = nrf_wifi_rx_bcn_prb_resp_frm; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ -#if defined(CONFIG_NRF70_SYSTEM_MODE) || defined(CONFIG_NRF70_SYSTEM_WITH_RAW_MODES) +#ifdef CONFIG_NRF70_SYSTEM_MODE callbk_fns.set_if_callbk_fn = nrf_wifi_set_iface_event_handler; #endif /* CONFIG_NRF70_SYSTEM_MODE */ #ifdef CONFIG_NRF70_STA_MODE @@ -760,9 +762,9 @@ static int nrf_wifi_drv_main_zep(const struct device *dev) */ nrf_wifi_osal_init(&nrf_wifi_os_zep_ops); - rpu_drv_priv_zep.fmac_priv = nrf_wifi_fmac_init(&data_config, - rx_buf_pools, - &callbk_fns); + rpu_drv_priv_zep.fmac_priv = nrf_wifi_sys_fmac_init(&data_config, + rx_buf_pools, + &callbk_fns); #else /* !CONFIG_NRF70_RADIO_TEST */ enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; @@ -771,7 +773,7 @@ static int nrf_wifi_drv_main_zep(const struct device *dev) */ nrf_wifi_osal_init(&nrf_wifi_os_zep_ops); - rpu_drv_priv_zep.fmac_priv = nrf_wifi_fmac_init_rt(); + rpu_drv_priv_zep.fmac_priv = nrf_wifi_rt_fmac_init(); #endif /* CONFIG_NRF70_RADIO_TEST */ if (rpu_drv_priv_zep.fmac_priv == NULL) { @@ -781,18 +783,18 @@ static int nrf_wifi_drv_main_zep(const struct device *dev) } #ifdef CONFIG_NRF70_DATA_TX - struct nrf_wifi_fmac_priv_def *def_priv = NULL; + struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL; - def_priv = wifi_fmac_priv(rpu_drv_priv_zep.fmac_priv); - def_priv->max_ampdu_len_per_token = + sys_fpriv = wifi_fmac_priv(rpu_drv_priv_zep.fmac_priv); + sys_fpriv->max_ampdu_len_per_token = (RPU_PKTRAM_SIZE - (CONFIG_NRF70_RX_NUM_BUFS * CONFIG_NRF70_RX_MAX_DATA_SIZE)) / CONFIG_NRF70_MAX_TX_TOKENS; /* Align to 4-byte */ - def_priv->max_ampdu_len_per_token &= ~0x3; + sys_fpriv->max_ampdu_len_per_token &= ~0x3; /* Alignment overhead for size based coalesce */ - def_priv->avail_ampdu_len_per_token = - def_priv->max_ampdu_len_per_token - + sys_fpriv->avail_ampdu_len_per_token = + sys_fpriv->max_ampdu_len_per_token - (MAX_PKT_RAM_TX_ALIGN_OVERHEAD * max_tx_aggregation); #endif /* CONFIG_NRF70_DATA_TX */ @@ -811,7 +813,7 @@ static int nrf_wifi_drv_main_zep(const struct device *dev) return 0; #ifdef CONFIG_NRF70_RADIO_TEST fmac_deinit: - nrf_wifi_fmac_deinit_rt(rpu_drv_priv_zep.fmac_priv); + nrf_wifi_fmac_deinit(rpu_drv_priv_zep.fmac_priv); nrf_wifi_osal_deinit(); #endif /* CONFIG_NRF70_RADIO_TEST */ err: @@ -934,7 +936,7 @@ DEVICE_DT_INST_DEFINE(0, POST_KERNEL, CONFIG_WIFI_INIT_PRIORITY, /* prio */ NULL); /* api */ -#endif /* CONFIG_NRF70_STA_MODE */ +#endif /* CONFIG_NET_L2_ETHERNET */ #ifdef CONFIG_NET_CONNECTION_MANAGER_CONNECTIVITY_WIFI_MGMT CONNECTIVITY_WIFI_MGMT_BIND(Z_DEVICE_DT_DEV_ID(DT_DRV_INST(0))); diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index 5c7fb9759f77a..7433ee1353579 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -23,8 +23,7 @@ LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); #include "net_private.h" #include "util.h" -#include "fmac_api.h" -#include "fmac_util.h" +#include "common/fmac_util.h" #include "shim.h" #include "fmac_main.h" #include "wpa_supp_if.h" @@ -178,7 +177,7 @@ void nrf_wifi_rpu_recovery_cb(void *vif_ctx_handle, { struct nrf_wifi_fmac_vif_ctx *vif_ctx = vif_ctx_handle; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; if (!vif_ctx) { @@ -188,9 +187,9 @@ void nrf_wifi_rpu_recovery_cb(void *vif_ctx_handle, } fmac_dev_ctx = vif_ctx->fmac_dev_ctx; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); - if (!def_dev_ctx) { - LOG_ERR("%s: def_dev_ctx is NULL", + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + if (!sys_dev_ctx) { + LOG_ERR("%s: sys_dev_ctx is NULL", __func__); goto out; } @@ -238,10 +237,10 @@ void nrf_wifi_if_sniffer_rx_frm(void *os_vif_ctx, void *frm, struct net_pkt *pkt; struct nrf_wifi_ctx_zep *rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; int ret; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); pkt = net_raw_pkt_from_nbuf(iface, frm, sizeof(struct raw_rx_pkt_header), raw_rx_hdr, @@ -269,11 +268,11 @@ void nrf_wifi_if_rx_frm(void *os_vif_ctx, void *frm) int status; struct nrf_wifi_ctx_zep *rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; struct rpu_host_stats *host_stats = NULL; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); - host_stats = &def_dev_ctx->host_stats; + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + host_stats = &sys_dev_ctx->host_stats; host_stats->total_rx_pkts++; pkt = net_pkt_from_nbuf(iface, frm); @@ -356,7 +355,7 @@ int nrf_wifi_if_send(const struct device *dev, #ifdef CONFIG_NRF70_DATA_TX struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; struct rpu_host_stats *host_stats = NULL; void *nbuf = NULL; @@ -383,8 +382,8 @@ int nrf_wifi_if_send(const struct device *dev, goto unlock; } - def_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); - host_stats = &def_dev_ctx->host_stats; + sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); + host_stats = &sys_dev_ctx->host_stats; nbuf = net_pkt_to_nbuf(pkt); if (!nbuf) { LOG_DBG("Failed to allocate net_pkt"); @@ -490,7 +489,7 @@ static void ip_maddr_event_handler(struct net_if *iface, &mac_addr, NRF_WIFI_ETH_ADDR_LEN); - status = nrf_wifi_fmac_set_mcast_addr(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_set_mcast_addr(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, mcast_info); if (status == NRF_WIFI_STATUS_FAIL) { @@ -751,7 +750,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) dev->name, strlen(dev->name)); - vif_ctx_zep->vif_idx = nrf_wifi_fmac_add_vif(fmac_dev_ctx, + vif_ctx_zep->vif_idx = nrf_wifi_sys_fmac_add_vif(fmac_dev_ctx, vif_ctx_zep, &add_vif_info); if (vif_ctx_zep->vif_idx >= MAX_NUM_VIFS) { @@ -785,7 +784,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) mac_addr_len = WIFI_MAC_ADDR_LEN; } - status = nrf_wifi_fmac_set_vif_macaddr(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_set_vif_macaddr(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, mac_addr); @@ -806,12 +805,12 @@ int nrf_wifi_if_start_zep(const struct device *dev) dev->name, strlen(dev->name)); - status = nrf_wifi_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &vif_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_chg_vif_state failed", + LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif_state failed", __func__); goto del_vif; } @@ -820,12 +819,12 @@ int nrf_wifi_if_start_zep(const struct device *dev) nrf_wifi_wpa_supp_event_mac_chgd(vif_ctx_zep); #ifdef CONFIG_NRF_WIFI_LOW_POWER - status = nrf_wifi_fmac_set_power_save(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_set_power_save(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, NRF_WIFI_PS_ENABLED); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_set_power_save failed", + LOG_ERR("%s: nrf_wifi_sys_fmac_set_power_save failed", __func__); goto dev_rem; } @@ -838,9 +837,9 @@ int nrf_wifi_if_start_zep(const struct device *dev) goto out; del_vif: - status = nrf_wifi_fmac_del_vif(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); + status = nrf_wifi_sys_fmac_del_vif(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_del_vif failed", + LOG_ERR("%s: nrf_wifi_sys_fmac_del_vif failed", __func__); } dev_rem: @@ -891,12 +890,12 @@ int nrf_wifi_if_stop_zep(const struct device *dev) #ifdef CONFIG_NRF70_STA_MODE #ifdef CONFIG_NRF_WIFI_LOW_POWER - status = nrf_wifi_fmac_set_power_save(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_set_power_save(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, NRF_WIFI_PS_DISABLED); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_set_power_save failed", + LOG_ERR("%s: nrf_wifi_sys_fmac_set_power_save failed", __func__); } #endif /* CONFIG_NRF_WIFI_LOW_POWER */ @@ -909,20 +908,20 @@ int nrf_wifi_if_stop_zep(const struct device *dev) vif_info.state = NRF_WIFI_FMAC_IF_OP_STATE_DOWN; vif_info.if_index = vif_ctx_zep->vif_idx; - status = nrf_wifi_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &vif_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_chg_vif_state failed", + LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif_state failed", __func__); } - status = nrf_wifi_fmac_del_vif(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_del_vif(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_del_vif failed", + LOG_ERR("%s: nrf_wifi_sys_fmac_del_vif failed", __func__); } @@ -951,7 +950,7 @@ int nrf_wifi_if_get_config_zep(const struct device *dev, struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; if (!dev || !config) { LOG_ERR("%s: Invalid parameters", @@ -979,9 +978,9 @@ int nrf_wifi_if_get_config_zep(const struct device *dev, goto unlock; } fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); - if (!def_dev_ctx) { - LOG_ERR("%s: def_dev_ctx is NULL", + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + if (!sys_dev_ctx) { + LOG_ERR("%s: sys_dev_ctx is NULL", __func__); goto unlock; } @@ -990,7 +989,7 @@ int nrf_wifi_if_get_config_zep(const struct device *dev, if (type == ETHERNET_CONFIG_TYPE_TXINJECTION_MODE) { config->txinjection_mode = - def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->txinjection_mode; + sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->txinjection_mode; } #ifdef CONFIG_NRF70_TCP_IP_CHECKSUM_OFFLOAD if (type == ETHERNET_CONFIG_TYPE_TX_CHECKSUM_SUPPORT || @@ -1018,7 +1017,7 @@ int nrf_wifi_if_set_config_zep(const struct device *dev, struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; int ret = -1; if (!dev) { @@ -1067,9 +1066,9 @@ int nrf_wifi_if_set_config_zep(const struct device *dev, } fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); - if (!def_dev_ctx) { - LOG_ERR("%s: def_dev_ctx is NULL", + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + if (!sys_dev_ctx) { + LOG_ERR("%s: sys_dev_ctx is NULL", __func__); goto unlock; } @@ -1078,7 +1077,7 @@ int nrf_wifi_if_set_config_zep(const struct device *dev, if (type == ETHERNET_CONFIG_TYPE_TXINJECTION_MODE) { unsigned char mode; - if (def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->txinjection_mode == + if (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->txinjection_mode == config->txinjection_mode) { LOG_INF("%s: Driver TX injection setting is same as configured setting", __func__); @@ -1091,15 +1090,15 @@ int nrf_wifi_if_set_config_zep(const struct device *dev, * as is */ if (config->txinjection_mode) { - mode = (def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) | + mode = (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) | (NRF_WIFI_TX_INJECTION_MODE); } else { - mode = (def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) ^ + mode = (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) ^ (NRF_WIFI_TX_INJECTION_MODE); } - ret = nrf_wifi_fmac_set_mode(rpu_ctx_zep->rpu_ctx, - vif_ctx_zep->vif_idx, mode); + ret = nrf_wifi_sys_fmac_set_mode(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, mode); if (ret != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: Mode set operation failed", __func__); @@ -1111,7 +1110,7 @@ int nrf_wifi_if_set_config_zep(const struct device *dev, else if (type == ETHERNET_CONFIG_TYPE_PROMISC_MODE) { unsigned char mode; - if (def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->promisc_mode == + if (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->promisc_mode == config->promisc_mode) { LOG_ERR("%s: Driver promisc mode setting is same as configured setting", __func__); @@ -1119,15 +1118,15 @@ int nrf_wifi_if_set_config_zep(const struct device *dev, } if (config->promisc_mode) { - mode = (def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) | + mode = (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) | (NRF_WIFI_PROMISCUOUS_MODE); } else { - mode = (def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) ^ + mode = (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) ^ (NRF_WIFI_PROMISCUOUS_MODE); } - ret = nrf_wifi_fmac_set_mode(rpu_ctx_zep->rpu_ctx, - vif_ctx_zep->vif_idx, mode); + ret = nrf_wifi_sys_fmac_set_mode(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, mode); if (ret != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: mode set operation failed", __func__); @@ -1171,9 +1170,9 @@ int nrf_wifi_stats_get(const struct device *dev, struct net_stats_wifi *zstats) struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; #ifdef CONFIG_NRF70_RAW_DATA_TX - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; #endif /* CONFIG_NRF70_RAW_DATA_TX */ - struct rpu_op_stats stats; + struct rpu_sys_op_stats stats; int ret = -1; if (!dev) { @@ -1204,8 +1203,8 @@ int nrf_wifi_stats_get(const struct device *dev, struct net_stats_wifi *zstats) goto unlock; } - memset(&stats, 0, sizeof(struct rpu_op_stats)); - status = nrf_wifi_fmac_stats_get(rpu_ctx_zep->rpu_ctx, 0, &stats); + memset(&stats, 0, sizeof(struct rpu_sys_op_stats)); + status = nrf_wifi_sys_fmac_stats_get(rpu_ctx_zep->rpu_ctx, 0, &stats); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nrf_wifi_fmac_stats_get failed", __func__); goto unlock; @@ -1229,8 +1228,8 @@ int nrf_wifi_stats_get(const struct device *dev, struct net_stats_wifi *zstats) zstats->overrun_count = stats.host.total_tx_drop_pkts + stats.host.total_rx_drop_pkts; #ifdef CONFIG_NRF70_RAW_DATA_TX - def_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); - zstats->errors.tx += def_dev_ctx->raw_pkt_stats.raw_pkt_send_failure; + sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); + zstats->errors.tx += sys_dev_ctx->raw_pkt_stats.raw_pkt_send_failure; #endif /* CONFIG_NRF70_RAW_DATA_TX */ ret = 0; unlock: @@ -1244,7 +1243,7 @@ int nrf_wifi_stats_reset(const struct device *dev) enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; int ret = -1; if (!dev) { @@ -1277,8 +1276,8 @@ int nrf_wifi_stats_reset(const struct device *dev) goto unlock; } - def_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); - memset(&def_dev_ctx->host_stats, 0, sizeof(struct rpu_host_stats)); + sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); + memset(&sys_dev_ctx->host_stats, 0, sizeof(struct rpu_host_stats)); ret = 0; unlock: diff --git a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c index 5effb759fa428..875ce786b5702 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c +++ b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c @@ -15,9 +15,9 @@ #include #include "util.h" -#include "fmac_api.h" -#include "fmac_tx.h" -#include "fmac_util.h" +#include "system/fmac_api.h" +#include "system/fmac_tx.h" +#include "common/fmac_util.h" #include "fmac_main.h" #include "wifi_mgmt.h" @@ -69,7 +69,7 @@ int nrf_wifi_set_power_save(const struct device *dev, WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID; return -EINVAL; } - status = nrf_wifi_fmac_set_listen_interval( + status = nrf_wifi_sys_fmac_set_listen_interval( rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, params->listen_interval); @@ -90,7 +90,7 @@ int nrf_wifi_set_power_save(const struct device *dev, goto out; } - status = nrf_wifi_fmac_set_power_save_timeout( + status = nrf_wifi_sys_fmac_set_power_save_timeout( rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, params->timeout_ms); @@ -100,17 +100,17 @@ int nrf_wifi_set_power_save(const struct device *dev, uapsd_queue = UAPSD_Q_MAX; /* WMM mode */ } - status = nrf_wifi_fmac_set_uapsd_queue(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_set_uapsd_queue(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, uapsd_queue); break; case WIFI_PS_PARAM_STATE: - status = nrf_wifi_fmac_set_power_save(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_set_power_save(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, params->enabled); break; case WIFI_PS_PARAM_WAKEUP_MODE: - status = nrf_wifi_fmac_set_ps_wakeup_mode( + status = nrf_wifi_sys_fmac_set_ps_wakeup_mode( rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, params->wakeup_mode); @@ -128,7 +128,7 @@ int nrf_wifi_set_power_save(const struct device *dev, return -EINVAL; } - status = nrf_wifi_fmac_set_ps_exit_strategy( + status = nrf_wifi_sys_fmac_set_ps_exit_strategy( rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, exit_strategy); @@ -211,11 +211,11 @@ int nrf_wifi_get_power_save_config(const struct device *dev, vif_ctx_zep->ps_config_info_evnt = false; - status = nrf_wifi_fmac_get_power_save_info(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_get_power_save_info(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_get_power_save_info failed", + LOG_ERR("%s: nrf_wifi_sys_fmac_get_power_save_info failed", __func__); goto out; } @@ -468,7 +468,7 @@ int nrf_wifi_twt_teardown_flows(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, continue; } twt_info.twt_flow_id = flow_id; - status = nrf_wifi_fmac_twt_teardown(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_twt_teardown(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &twt_info); if (status != NRF_WIFI_STATUS_SUCCESS) { @@ -569,7 +569,7 @@ int nrf_wifi_set_twt(const struct device *dev, twt_info.dialog_token = twt_params->dialog_token; twt_info.twt_wake_ahead_duration = twt_params->setup.twt_wake_ahead_duration; - status = nrf_wifi_fmac_twt_setup(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_twt_setup(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &twt_info); @@ -620,8 +620,8 @@ void nrf_wifi_event_proc_twt_setup_zep(void *vif_ctx, unsigned int event_len) { struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; - struct wifi_twt_params twt_params; - struct twt_interval_float twt_interval_fp; + struct wifi_twt_params twt_params = { 0 }; + struct twt_interval_float twt_interval_fp = { 0 }; if (!vif_ctx || !twt_setup_info) { return; @@ -682,8 +682,8 @@ void nrf_wifi_event_proc_twt_sleep_zep(void *vif_ctx, struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; - struct nrf_wifi_fmac_priv_def *def_priv = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL; #ifdef CONFIG_NRF70_DATA_TX int desc = 0; int ac = 0; @@ -708,8 +708,8 @@ void nrf_wifi_event_proc_twt_sleep_zep(void *vif_ctx, } fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); - def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv); if (!sleep_evnt) { LOG_ERR("%s: sleep_evnt is NULL", __func__); @@ -718,29 +718,29 @@ void nrf_wifi_event_proc_twt_sleep_zep(void *vif_ctx, switch (sleep_evnt->info.type) { case TWT_BLOCK_TX: - nrf_wifi_osal_spinlock_take(def_dev_ctx->tx_config.tx_lock); + nrf_wifi_osal_spinlock_take(sys_dev_ctx->tx_config.tx_lock); - def_dev_ctx->twt_sleep_status = NRF_WIFI_FMAC_TWT_STATE_SLEEP; + sys_dev_ctx->twt_sleep_status = NRF_WIFI_FMAC_TWT_STATE_SLEEP; wifi_mgmt_raise_twt_sleep_state(vif_ctx_zep->zep_net_if_ctx, WIFI_TWT_STATE_SLEEP); - nrf_wifi_osal_spinlock_rel(def_dev_ctx->tx_config.tx_lock); + nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock); break; case TWT_UNBLOCK_TX: - nrf_wifi_osal_spinlock_take(def_dev_ctx->tx_config.tx_lock); - def_dev_ctx->twt_sleep_status = NRF_WIFI_FMAC_TWT_STATE_AWAKE; + nrf_wifi_osal_spinlock_take(sys_dev_ctx->tx_config.tx_lock); + sys_dev_ctx->twt_sleep_status = NRF_WIFI_FMAC_TWT_STATE_AWAKE; wifi_mgmt_raise_twt_sleep_state(vif_ctx_zep->zep_net_if_ctx, WIFI_TWT_STATE_AWAKE); #ifdef CONFIG_NRF70_DATA_TX for (ac = NRF_WIFI_FMAC_AC_BE; ac <= NRF_WIFI_FMAC_AC_MAX; ++ac) { desc = tx_desc_get(fmac_dev_ctx, ac); - if (desc < def_priv->num_tx_tokens) { + if (desc < sys_fpriv->num_tx_tokens) { tx_pending_process(fmac_dev_ctx, desc, ac); } } #endif - nrf_wifi_osal_spinlock_rel(def_dev_ctx->tx_config.tx_lock); + nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock); break; default: break; @@ -757,7 +757,7 @@ int nrf_wifi_mode(const struct device *dev, struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; int ret = -1; if (!dev || !mode) { @@ -784,7 +784,7 @@ int nrf_wifi_mode(const struct device *dev, } fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); if (!device_is_ready(dev)) { LOG_ERR("%s: Device %s is not ready", @@ -811,26 +811,27 @@ int nrf_wifi_mode(const struct device *dev, * context maps the correct network interface index to current driver * interface index. */ - status = nrf_wifi_fmac_set_mode(rpu_ctx_zep->rpu_ctx, - vif_ctx_zep->vif_idx, mode->mode); + status = nrf_wifi_sys_fmac_set_mode(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, + mode->mode); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: mode set operation failed", __func__); goto out; } } else { - mode->mode = def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode; + mode->mode = sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode; /** * This is a work-around to handle current UMAC mode handling. * This might be removed in future versions when UMAC has more space. */ #ifdef CONFIG_NRF70_RAW_DATA_TX - if (def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->txinjection_mode == true) { + if (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->txinjection_mode == true) { mode->mode ^= NRF_WIFI_TX_INJECTION_MODE; } #endif /* CONFIG_NRF70_RAW_DATA_TX */ #ifdef CONFIG_NRF70_PROMISC_DATA_RX - if (def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->promisc_mode == true) { + if (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->promisc_mode == true) { mode->mode ^= NRF_WIFI_PROMISCUOUS_MODE; } #endif /* CONFIG_NRF70_PROMISC_DATA_RX */ @@ -849,7 +850,7 @@ int nrf_wifi_channel(const struct device *dev, enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; int ret = -1; @@ -882,7 +883,7 @@ int nrf_wifi_channel(const struct device *dev, } fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); if (channel->oper == WIFI_MGMT_SET) { /** @@ -891,15 +892,16 @@ int nrf_wifi_channel(const struct device *dev, * context maps the correct network interface index to current driver * interface index. */ - status = nrf_wifi_fmac_set_channel(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, - channel->channel); + status = nrf_wifi_sys_fmac_set_channel(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, + channel->channel); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: set channel failed", __func__); goto out; } } else { - channel->channel = def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->channel; + channel->channel = sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->channel; } ret = 0; out: @@ -916,7 +918,7 @@ int nrf_wifi_filter(const struct device *dev, struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; int ret = -1; if (!dev || !filter) { @@ -932,7 +934,7 @@ int nrf_wifi_filter(const struct device *dev, rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); if (filter->oper == WIFI_MGMT_SET) { /** @@ -942,9 +944,9 @@ int nrf_wifi_filter(const struct device *dev, * driver and filter packet type on packet receive by * checking the 802.11 header in the packet */ - if (((def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) & + if (((sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) & (NRF_WIFI_PROMISCUOUS_MODE)) == NRF_WIFI_PROMISCUOUS_MODE) { - def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->packet_filter = + sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->packet_filter = filter->filter; ret = 0; goto out; @@ -963,7 +965,7 @@ int nrf_wifi_filter(const struct device *dev, filter->filter = 1; } else if (filter->filter == 0) { filter->filter = - def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->packet_filter; + sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->packet_filter; } /** @@ -972,14 +974,16 @@ int nrf_wifi_filter(const struct device *dev, * context maps the correct network interface index to current driver * interface index */ - status = nrf_wifi_fmac_set_packet_filter(rpu_ctx_zep->rpu_ctx, filter->filter, - vif_ctx_zep->vif_idx, filter->buffer_size); + status = nrf_wifi_sys_fmac_set_packet_filter(rpu_ctx_zep->rpu_ctx, + filter->filter, + vif_ctx_zep->vif_idx, + filter->buffer_size); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: Set filter operation failed\n", __func__); goto out; } } else { - filter->filter = def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->packet_filter; + filter->filter = sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->packet_filter; } ret = 0; out: @@ -1036,7 +1040,7 @@ int nrf_wifi_set_rts_threshold(const struct device *dev, k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER); - status = nrf_wifi_fmac_set_wiphy_params(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_set_wiphy_params(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &wiphy_info); diff --git a/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c b/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c index e30f572aeb326..ceabdcf7f0191 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c +++ b/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c @@ -15,8 +15,8 @@ #include #include "util.h" -#include "fmac_api.h" -#include "fmac_tx.h" +#include "system/fmac_api.h" +#include "system/fmac_tx.h" #include "fmac_main.h" #include "wifi_mgmt_scan.h" @@ -210,10 +210,10 @@ int nrf_wifi_disp_scan_zep(const struct device *dev, struct wifi_scan_params *pa scan_info->scan_params.passive_scan = 1; #endif /* CONFIG_NRF70_PASSIVE_SCAN_ONLY */ - status = nrf_wifi_fmac_scan(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, scan_info); + status = nrf_wifi_sys_fmac_scan(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, scan_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_scan failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_scan failed", __func__); goto out; } @@ -249,12 +249,12 @@ enum nrf_wifi_status nrf_wifi_disp_scan_res_get_zep(struct nrf_wifi_vif_ctx_zep goto out; } - status = nrf_wifi_fmac_scan_res_get(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_scan_res_get(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, SCAN_DISPLAY); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_scan failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_scan failed", __func__); goto out; } diff --git a/drivers/wifi/nrf_wifi/src/wifi_util.c b/drivers/wifi/nrf_wifi/src/wifi_util.c index 2d2ca2a2b5bca..70b64da4e2ec8 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_util.c +++ b/drivers/wifi/nrf_wifi/src/wifi_util.c @@ -9,8 +9,8 @@ */ #include #include "host_rpu_umac_if.h" -#include "fmac_api.h" -#include "fmac_util.h" +#include "common/fmac_util.h" +#include "system/fmac_api.h" #include "fmac_main.h" #include "wifi_util.h" @@ -161,10 +161,10 @@ static int nrf_wifi_util_set_he_ltf_gi(const struct shell *sh, return -ENOEXEC; } - status = nrf_wifi_fmac_conf_ltf_gi(ctx->rpu_ctx, - ctx->conf_params.he_ltf, - ctx->conf_params.he_gi, - val); + status = nrf_wifi_sys_fmac_conf_ltf_gi(ctx->rpu_ctx, + ctx->conf_params.he_ltf, + ctx->conf_params.he_gi, + val); if (status != NRF_WIFI_STATUS_SUCCESS) { shell_fprintf(sh, @@ -199,7 +199,7 @@ static int nrf_wifi_util_set_uapsd_queue(const struct shell *sh, } if (ctx->conf_params.uapsd_queue != val) { - status = nrf_wifi_fmac_set_uapsd_queue(ctx->rpu_ctx, + status = nrf_wifi_sys_fmac_set_uapsd_queue(ctx->rpu_ctx, 0, val); @@ -272,7 +272,7 @@ static int nrf_wifi_util_tx_stats(const struct shell *sh, struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; void *queue = NULL; unsigned int tx_pending_pkts = 0; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; int ret; vif_index = atoi(argv[1]); @@ -295,7 +295,7 @@ static int nrf_wifi_util_tx_stats(const struct shell *sh, } fmac_dev_ctx = ctx->rpu_ctx; - def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); /* TODO: Get peer_index from shell once AP mode is supported */ shell_fprintf(sh, @@ -304,7 +304,7 @@ static int nrf_wifi_util_tx_stats(const struct shell *sh, vif_index); for (int i = 0; i < NRF_WIFI_FMAC_AC_MAX ; i++) { - queue = def_dev_ctx->tx_config.data_pending_txq[peer_index][i]; + queue = sys_dev_ctx->tx_config.data_pending_txq[peer_index][i]; tx_pending_pkts = nrf_wifi_utils_q_len(queue); shell_fprintf( @@ -312,7 +312,7 @@ static int nrf_wifi_util_tx_stats(const struct shell *sh, SHELL_INFO, "Outstanding tokens: ac: %d -> %d (pending_q_len: %d)\n", i, - def_dev_ctx->tx_config.outstanding_descs[i], + sys_dev_ctx->tx_config.outstanding_descs[i], tx_pending_pkts); } @@ -373,9 +373,9 @@ static int nrf_wifi_util_tx_rate(const struct shell *sh, } - status = nrf_wifi_fmac_set_tx_rate(ctx->rpu_ctx, - rate_flag, - data_rate); + status = nrf_wifi_sys_fmac_set_tx_rate(ctx->rpu_ctx, + rate_flag, + data_rate); if (status != NRF_WIFI_STATUS_SUCCESS) { shell_fprintf(sh, @@ -399,8 +399,8 @@ static int nrf_wifi_util_show_host_rpu_ps_ctrl_state(const struct shell *sh, enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; int rpu_ps_state = -1; - status = nrf_wifi_fmac_get_host_rpu_ps_ctrl_state(ctx->rpu_ctx, - &rpu_ps_state); + status = nrf_wifi_sys_fmac_get_host_rpu_ps_ctrl_state(ctx->rpu_ctx, + &rpu_ps_state); if (status != NRF_WIFI_STATUS_SUCCESS) { shell_fprintf(sh, @@ -456,7 +456,7 @@ static int nrf_wifi_util_dump_rpu_stats(const struct shell *sh, { enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; - struct rpu_op_stats stats; + struct rpu_sys_op_stats stats; enum rpu_stats_type stats_type = RPU_STATS_TYPE_ALL; int ret; @@ -490,8 +490,8 @@ static int nrf_wifi_util_dump_rpu_stats(const struct shell *sh, } fmac_dev_ctx = ctx->rpu_ctx; - memset(&stats, 0, sizeof(struct rpu_op_stats)); - status = nrf_wifi_fmac_stats_get(fmac_dev_ctx, 0, &stats); + memset(&stats, 0, sizeof(struct rpu_sys_op_stats)); + status = nrf_wifi_sys_fmac_stats_get(fmac_dev_ctx, 0, &stats); if (status != NRF_WIFI_STATUS_SUCCESS) { shell_fprintf(sh, @@ -898,7 +898,7 @@ static int nrf_wifi_util_trigger_rpu_recovery(const struct shell *sh, fmac_dev_ctx = ctx->rpu_ctx; - status = nrf_wifi_fmac_rpu_recovery_callback(fmac_dev_ctx, NULL, 0); + status = nrf_wifi_sys_fmac_rpu_recovery_callback(fmac_dev_ctx, NULL, 0); if (status != NRF_WIFI_STATUS_SUCCESS) { shell_fprintf(sh, SHELL_ERROR, diff --git a/drivers/wifi/nrf_wifi/src/wifi_util.h b/drivers/wifi/nrf_wifi/src/wifi_util.h index 2ab188efed4bf..303d5feac99fb 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_util.h +++ b/drivers/wifi/nrf_wifi/src/wifi_util.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include struct nrf_wifi_ctx_zep_rt { diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 292c1b9117a6d..4b28c7bb24e91 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -14,7 +14,7 @@ #include #include "fmac_main.h" -#include "fmac_util.h" +#include "common/fmac_util.h" #include "wifi_mgmt.h" #include "wpa_supp_if.h" @@ -563,7 +563,7 @@ int nrf_wifi_wpa_supp_scan2(void *if_priv, struct wpa_driver_scan_params *params goto out; } - status = nrf_wifi_fmac_scan(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, scan_info); + status = nrf_wifi_sys_fmac_scan(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, scan_info); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: Scan trigger failed", __func__); @@ -614,10 +614,10 @@ int nrf_wifi_wpa_supp_scan_abort(void *if_priv) goto out; } - status = nrf_wifi_fmac_abort_scan(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); + status = nrf_wifi_sys_fmac_abort_scan(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_abort_scan failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_abort_scan failed", __func__); goto out; } @@ -660,11 +660,11 @@ int nrf_wifi_wpa_supp_scan_results_get(void *if_priv) goto out; } - status = nrf_wifi_fmac_scan_res_get(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, + status = nrf_wifi_sys_fmac_scan_res_get(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, SCAN_CONNECT); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_scan_res_get failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_scan_res_get failed", __func__); goto out; } @@ -706,10 +706,10 @@ int nrf_wifi_wpa_supp_deauthenticate(void *if_priv, const char *addr, unsigned s memcpy(deauth_info.mac_addr, addr, sizeof(deauth_info.mac_addr)); - status = nrf_wifi_fmac_deauth(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &deauth_info); + status = nrf_wifi_sys_fmac_deauth(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &deauth_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_deauth failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_deauth failed", __func__); goto out; } @@ -850,7 +850,7 @@ int nrf_wifi_wpa_supp_authenticate(void *if_priv, struct wpa_driver_auth_params auth_info.nrf_wifi_flags |= NRF_WIFI_CMD_AUTHENTICATE_LOCAL_STATE_CHANGE; } - status = nrf_wifi_fmac_auth(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &auth_info); + status = nrf_wifi_sys_fmac_auth(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &auth_info); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: MLME command failed (auth): count=%d ret=%d", __func__, count, ret); @@ -931,7 +931,7 @@ int nrf_wifi_wpa_supp_associate(void *if_priv, struct wpa_driver_associate_param assoc_info.bss_max_idle_time = params->bss_max_idle_period; } - status = nrf_wifi_fmac_assoc(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &assoc_info); + status = nrf_wifi_sys_fmac_assoc(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &assoc_info); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: MLME command failed (assoc)", __func__); @@ -1025,20 +1025,20 @@ int nrf_wifi_wpa_supp_set_key(void *if_priv, const unsigned char *ifname, enum w key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID; if (alg == WPA_ALG_NONE) { - status = nrf_wifi_fmac_del_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, + status = nrf_wifi_sys_fmac_del_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &key_info, mac_addr); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_del_key failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_del_key failed", __func__); } else { ret = 0; } } else { - status = nrf_wifi_fmac_add_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, + status = nrf_wifi_sys_fmac_add_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &key_info, mac_addr); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_add_key failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_add_key failed", __func__); } else { ret = 0; } @@ -1071,10 +1071,10 @@ int nrf_wifi_wpa_supp_set_key(void *if_priv, const unsigned char *ifname, enum w key_info.nrf_wifi_flags |= NRF_WIFI_KEY_DEFAULT_TYPE_UNICAST; } - status = nrf_wifi_fmac_set_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &key_info); + status = nrf_wifi_sys_fmac_set_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &key_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_set_key failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_set_key failed", __func__); ret = -1; } else { ret = 0; @@ -1129,10 +1129,12 @@ int nrf_wifi_wpa_set_supp_port(void *if_priv, int authorized, char *bssid) chg_sta_info.sta_flags2.nrf_wifi_set = 1 << 1; } - status = nrf_wifi_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &chg_sta_info); + status = nrf_wifi_sys_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, + &chg_sta_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_chg_sta failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_chg_sta failed", __func__); ret = -1; goto out; } @@ -1178,7 +1180,9 @@ int nrf_wifi_wpa_supp_signal_poll(void *if_priv, struct wpa_signal_info *si, uns nrf_wifi_osal_time_elapsed_us(vif_ctx_zep->rssi_record_timestamp_us) / 1000; if (rssi_record_elapsed_time_ms > CONFIG_NRF70_RSSI_STALE_TIMEOUT_MS) { - ret = nrf_wifi_fmac_get_station(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, bssid); + ret = nrf_wifi_sys_fmac_get_station(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, + bssid); if (ret != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: Failed to send get station info command", __func__); goto out; @@ -1191,10 +1195,10 @@ int nrf_wifi_wpa_supp_signal_poll(void *if_priv, struct wpa_signal_info *si, uns goto out; } } else { - si->current_signal = (int)vif_ctx_zep->rssi; + si->data.signal = (int)vif_ctx_zep->rssi; } - ret = nrf_wifi_fmac_get_interface(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); + ret = nrf_wifi_sys_fmac_get_interface(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); if (ret != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: Failed to send get interface info command", __func__); goto out; @@ -1242,28 +1246,28 @@ void nrf_wifi_wpa_supp_event_proc_get_sta(void *if_priv, } if (info->sta_info.valid_fields & NRF_WIFI_STA_INFO_SIGNAL_VALID) { - signal_info->current_signal = info->sta_info.signal; + signal_info->data.signal = info->sta_info.signal; } else { - signal_info->current_signal = -WPA_INVALID_NOISE; + signal_info->data.signal = 0; } if (info->sta_info.valid_fields & NRF_WIFI_STA_INFO_SIGNAL_AVG_VALID) { - signal_info->avg_signal = info->sta_info.signal_avg; + signal_info->data.avg_signal = info->sta_info.signal_avg; } else { - signal_info->avg_signal = -WPA_INVALID_NOISE; + signal_info->data.avg_signal = 0; } if (info->sta_info.valid_fields & NRF_WIFI_STA_INFO_RX_BEACON_SIGNAL_AVG_VALID) { - signal_info->avg_beacon_signal = info->sta_info.rx_beacon_signal_avg; + signal_info->data.avg_beacon_signal = info->sta_info.rx_beacon_signal_avg; } else { - signal_info->avg_beacon_signal = -WPA_INVALID_NOISE; + signal_info->data.avg_beacon_signal = 0; } - signal_info->current_txrate = 0; + signal_info->data.current_tx_rate = 0; if (info->sta_info.valid_fields & NRF_WIFI_STA_INFO_TX_BITRATE_VALID) { if (info->sta_info.tx_bitrate.valid_fields & NRF_WIFI_RATE_INFO_BITRATE_VALID) { - signal_info->current_txrate = info->sta_info.tx_bitrate.bitrate * 100; + signal_info->data.current_tx_rate = info->sta_info.tx_bitrate.bitrate * 100; } } out: @@ -1454,12 +1458,12 @@ int nrf_wifi_nl80211_send_mlme(void *if_priv, const u8 *data, LOG_DBG("%s: Sending frame to RPU: cookie=%d wait_time=%d no_ack=%d", __func__, cookie, wait_time, noack); - status = nrf_wifi_fmac_mgmt_tx(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_mgmt_tx(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, mgmt_tx_info); if (status == NRF_WIFI_STATUS_FAIL) { - LOG_ERR("%s: nrf_wifi_fmac_mgmt_tx failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_mgmt_tx failed", __func__); goto out; } @@ -1656,10 +1660,10 @@ int nrf_wifi_supp_get_wiphy(void *if_priv) goto out; } - status = nrf_wifi_fmac_get_wiphy(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); + status = nrf_wifi_sys_fmac_get_wiphy(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_get_wiphy failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_get_wiphy failed", __func__); goto out; } out: @@ -1700,11 +1704,11 @@ int nrf_wifi_supp_register_frame(void *if_priv, frame_info.frame_match.frame_match_len = match_len; memcpy(frame_info.frame_match.frame_match, match, match_len); - status = nrf_wifi_fmac_register_frame(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, + status = nrf_wifi_sys_fmac_register_frame(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &frame_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_register_frame failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_register_frame failed", __func__); goto out; } out: @@ -1843,9 +1847,9 @@ int nrf_wifi_supp_get_conn_info(void *if_priv, struct wpa_conn_info *info) fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; vif_ctx_zep->conn_info = info; - ret = nrf_wifi_fmac_get_conn_info(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); + ret = nrf_wifi_sys_fmac_get_conn_info(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); if (ret != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_get_conn_info failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_get_conn_info failed", __func__); goto out; } @@ -1965,7 +1969,7 @@ static int nrf_wifi_vif_state_change(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, unsigned int timeout = 0; struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; - struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; int ret = -1; if (!vif_ctx_zep) { @@ -1984,18 +1988,18 @@ static int nrf_wifi_vif_state_change(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, goto out; } - def_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); - vif_ctx = def_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]; + sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); + vif_ctx = sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]; vif_state_info.state = state; vif_state_info.if_index = vif_ctx_zep->vif_idx; vif_ctx->ifflags = false; - status = nrf_wifi_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &vif_state_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_chg_vif_state failed", + LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif_state failed", __func__); goto out; } @@ -2047,9 +2051,11 @@ static int nrf_wifi_iftype_change(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, int chg_vif_info.iftype = iftype; vif_ctx_zep->set_if_event_received = false; vif_ctx_zep->set_if_status = 0; - status = nrf_wifi_fmac_chg_vif(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &chg_vif_info); + status = nrf_wifi_sys_fmac_chg_vif(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, + &chg_vif_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_chg_vif failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif failed", __func__); goto out; } @@ -2261,11 +2267,11 @@ int nrf_wifi_supp_register_mgmt_frame(void *if_priv, } memcpy(mgmt_frame_info.frame_match.frame_match, match, match_len); - status = nrf_wifi_fmac_mgmt_frame_reg(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_mgmt_frame_reg(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &mgmt_frame_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_mgmt_frame_reg failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_mgmt_frame_reg failed", __func__); goto out; } @@ -2324,9 +2330,9 @@ static int nrf_wifi_set_bss(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, bss_info.nrf_wifi_slot = params->short_slot_time; bss_info.ap_isolate = params->isolate; - status = nrf_wifi_fmac_set_bss(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &bss_info); + status = nrf_wifi_sys_fmac_set_bss(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &bss_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_set_bss failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_set_bss failed", __func__); goto out; } @@ -2423,9 +2429,11 @@ int nrf_wifi_wpa_supp_start_ap(void *if_priv, struct wpa_driver_ap_params *param NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID; vif_ctx_zep->if_carr_state = NRF_WIFI_FMAC_IF_CARR_STATE_OFF; - status = nrf_wifi_fmac_start_ap(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &start_ap_info); + status = nrf_wifi_sys_fmac_start_ap(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, + &start_ap_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_start_ap failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_start_ap failed", __func__); goto out; } @@ -2474,9 +2482,11 @@ int nrf_wifi_wpa_supp_change_beacon(void *if_priv, struct wpa_driver_ap_params * nrf_wifi_set_beacon_data(params, &chg_bcn_info.beacon_data); - status = nrf_wifi_fmac_chg_bcn(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &chg_bcn_info); + status = nrf_wifi_sys_fmac_chg_bcn(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, + &chg_bcn_info); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_chg_bcn failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_chg_bcn failed", __func__); goto out; } @@ -2511,10 +2521,10 @@ int nrf_wifi_wpa_supp_stop_ap(void *if_priv) goto out; } - status = nrf_wifi_fmac_stop_ap(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); + status = nrf_wifi_sys_fmac_stop_ap(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_stop_ap failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_stop_ap failed", __func__); goto out; } @@ -2593,7 +2603,7 @@ int nrf_wifi_sta_flags_to_nrf(int wpas_sta_flags) nrf_sta_flags |= NRF_WIFI_STA_FLAG_TDLS_PEER; } /* Note: Do not set flags > NRF_WIFI_STA_FLAG_TDLS_PEER, else - * nrf_wifi_fmac_chg_sta will fail. This is equivalent to not + * nrf_wifi_sys_fmac_chg_sta will fail. This is equivalent to not * setting WPA_DRIVER_FLAGS_FULL_AP_CLIENT_STATE flag. */ @@ -2685,16 +2695,16 @@ int nrf_wifi_wpa_supp_sta_add(void *if_priv, struct hostapd_sta_add_params *para sta_info.sta_flags2.nrf_wifi_set, sta_info.sta_flags2.nrf_wifi_mask); if (params->set) { - status = nrf_wifi_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, (struct nrf_wifi_umac_chg_sta_info *)&sta_info); } else { - status = nrf_wifi_fmac_add_sta(rpu_ctx_zep->rpu_ctx, + status = nrf_wifi_sys_fmac_add_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &sta_info); } if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_add_sta failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_add_sta failed", __func__); goto out; } @@ -2732,9 +2742,9 @@ int nrf_wifi_wpa_supp_sta_remove(void *if_priv, const u8 *addr) memcpy(del_sta.mac_addr, addr, sizeof(del_sta.mac_addr)); - status = nrf_wifi_fmac_del_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &del_sta); + status = nrf_wifi_sys_fmac_del_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &del_sta); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_del_sta failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_del_sta failed", __func__); goto out; } @@ -2781,9 +2791,9 @@ int nrf_wifi_wpa_supp_sta_set_flags(void *if_priv, const u8 *addr, LOG_DBG("%s %x, %x", __func__, chg_sta.sta_flags2.nrf_wifi_set, chg_sta.sta_flags2.nrf_wifi_mask); - status = nrf_wifi_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &chg_sta); + status = nrf_wifi_sys_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &chg_sta); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_chg_sta failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_chg_sta failed", __func__); goto out; } @@ -2820,10 +2830,11 @@ int nrf_wifi_wpa_supp_sta_get_inact_sec(void *if_priv, const u8 *addr) goto out; } - status = nrf_wifi_fmac_get_station(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, - (unsigned char *) addr); + status = nrf_wifi_sys_fmac_get_station(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, + (unsigned char *) addr); if (status != NRF_WIFI_STATUS_SUCCESS) { - LOG_ERR("%s: nrf_wifi_fmac_get_station failed", __func__); + LOG_ERR("%s: nrf_wifi_sys_fmac_get_station failed", __func__); goto out; } diff --git a/drivers/wifi/nxp/Kconfig.nxp b/drivers/wifi/nxp/Kconfig.nxp index 3b5ecdc8603e6..a84d4fcde79fc 100644 --- a/drivers/wifi/nxp/Kconfig.nxp +++ b/drivers/wifi/nxp/Kconfig.nxp @@ -8,7 +8,7 @@ menuconfig WIFI_NXP select NET_L2_ETHERNET_MGMT if NETWORKING && NET_L2_ETHERNET select SDHC if !SOC_SERIES_RW6XX select SDIO_STACK if !SOC_SERIES_RW6XX - select WIFI_NM if WIFI_NM_WPA_SUPPLICANT + select WIFI_NM depends on DT_HAS_NXP_WIFI_ENABLED help Enable NXP SoC Wi-Fi support. @@ -17,16 +17,13 @@ if WIFI_NXP module = WIFI_NXP +config HEAP_MEM_POOL_ADD_SIZE_NXP_WIFI + def_int 25984 if WIFI_NM_WPA_SUPPLICANT + def_int 51200 + config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL default 50 -config NXP_WIFI_BUILD_ONLY_MODE - bool "Build only mode (do not link wireless firmware blob)" - help - Skip linking the firmware blob into the Wi-Fi build. This will - not result in a functional application, but allows the Wi-Fi - driver to be built without binary blobs - config NXP_WIFI_CUSTOM bool "Custom NXP Wi-Fi part" help @@ -316,7 +313,8 @@ menu "Wi-Fi driver Stack configurations" config NXP_WIFI_MON_TASK_STACK_SIZE int "Mon thread stack size" - default 1152 + depends on NXP_RW610 + default 3072 help This option specifies the size of the stack used by the mon task. @@ -328,7 +326,7 @@ config NXP_WIFI_WLCMGR_TASK_STACK_SIZE config NXP_WIFI_POWERSAVE_TASK_STACK_SIZE int "Wifi powersave task stack size" - default 512 + default 1024 help This option specifies the size of the stack used by the wifi powersave task. @@ -353,6 +351,51 @@ config NXP_WIFI_SCAN_TASK_STACK_SIZE endmenu +menu "Wi-Fi thread priority configurations" + +config NXP_WIFI_MON_TASK_PRIO + int "Mon task priority" + depends on NXP_RW610 + default 4 + help + This option specifies the priority of the mon task. + +config NXP_WIFI_WLCMGR_TASK_PRIO + int "Wlcmgr task priority" + default 2 + help + This option specifies the priority of the wlcmgr task. + +config NXP_WIFI_POWERSAVE_TASK_PRIO + int "Wifi powersave task priority" + default 4 + help + This option specifies the priority of the wifi powersave task. + +config NXP_WIFI_TX_TASK_PRIO + int "Wifi driver TX task priority" + default 3 + depends on NXP_WIFI_WMM + help + This option specifies the priority of the wifi driver TX task, + and better to keep all the TX/RX tasks having same priority to + get higher throughput. The relative priorities of different tasks + need to remain the same as the current ones, which are tuned. + +config NXP_WIFI_DRIVER_TASK_PRIO + int "Wifi driver task priority" + default 2 + help + This option specifies the priority of the wifi driver task. + +config NXP_WIFI_SCAN_TASK_PRIO + int "Wifi scan task priority" + default 4 + help + This option specifies the priority of the wifi scan task. + +endmenu + menu "Wi-Fi Station Support" config NXP_WIFI_STA_AUTO_CONN @@ -442,6 +485,8 @@ config NXP_WIFI_WMM_UAPSD config NXP_WIFI_ROAMING bool "Wi-Fi Soft Roaming" default y + select WIFI_NM_WPA_SUPPLICANT_ROAMING if WIFI_NM_WPA_SUPPLICANT + select WIFI_NM_WPA_SUPPLICANT_SKIP_DHCP_ON_ROAMING if WIFI_NM_WPA_SUPPLICANT help This option enables Soft Roaming support in the Wi-Fi driver. @@ -464,11 +509,18 @@ config NXP_WIFI_11V config NXP_WIFI_11R bool "802.11R Support" + default n if (NXP_RW610 && !WIFI_NM_WPA_SUPPLICANT) default y depends on NXP_88W8987 || NXP_IW416 || NXP_RW610 || NXP_WIFI_CUSTOM help This option enables the use of 802.11r support. +config NXP_WIFI_RTS_THRESHOLD + bool "Set RTS Threshold Support" + default y + help + This option enables the set of rts threshold support. + config NXP_WIFI_INACTIVITY_TIMEOUT_EXT bool "Inactivity Timeout Ext Support" default y @@ -487,6 +539,8 @@ config NXP_WIFI_SOFTAP_SUPPORT bool "Wi-Fi SoftAP Support" select NET_DHCPV4_SERVER select WIFI_NM_HOSTAPD_AP if WIFI_NM_WPA_SUPPLICANT + imply WIFI_NM_HOSTAPD_WPS if WIFI_NM_HOSTAPD_AP && WIFI_NM_WPA_SUPPLICANT_WPS + imply WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE if WIFI_NM_HOSTAPD_AP && WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE default y help Option to enable Wi-Fi SoftAP functions in the Wi-Fi driver. @@ -668,6 +722,7 @@ config NXP_WIFI_RESET config NXP_WIFI_ECSA bool "ECSA" default y + depends on NXP_WIFI_SOFTAP_SUPPORT help This option is used to do channel switch according to spec. @@ -783,6 +838,11 @@ config NXP_WIFI_WLAN_CALDATA_3ANT_DIVERSITY help This option is used to enable three antenna diversity. +config NXP_OVERRIDE_CALIBRATION_DATA + bool "override default calibriation data" + help + This option is used to override default calibration data. + endif # NXP_RW610 config NXP_WIFI_11AX_TWT @@ -792,6 +852,13 @@ config NXP_WIFI_11AX_TWT help This option enables 11ax TWT in the Wi-Fi driver. +config NXP_WIFI_PKT_FWD + bool "Wi-Fi packet forward" + default y if NXP_RW610 + depends on NXP_WIFI_SOFTAP_SUPPORT + help + This option enables Wi-Fi packet forward on SoftAP. + config NXP_WIFI_DTIM_PERIOD bool "Wi-Fi DTIM period" default y diff --git a/drivers/wifi/nxp/nxp_wifi_drv.c b/drivers/wifi/nxp/nxp_wifi_drv.c index 171aa74dcc8d3..a78791778ff7b 100644 --- a/drivers/wifi/nxp/nxp_wifi_drv.c +++ b/drivers/wifi/nxp/nxp_wifi_drv.c @@ -49,14 +49,19 @@ LOG_MODULE_REGISTER(nxp_wifi, CONFIG_WIFI_LOG_LEVEL); ******************************************************************************/ static int s_nxp_wifi_State = NXP_WIFI_NOT_INITIALIZED; static bool s_nxp_wifi_StaConnected; +#ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT static bool s_nxp_wifi_UapActivated; +#endif static struct k_event s_nxp_wifi_SyncEvent; static struct nxp_wifi_dev nxp_wifi0; /* static instance */ static struct wlan_network nxp_wlan_network; +#ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT +static struct wlan_network nxp_wlan_uap_network; +#endif -#ifndef CONFIG_WIFI_NM_HOSTAPD_AP +#if defined(CONFIG_NXP_WIFI_SOFTAP_SUPPORT) && !defined(CONFIG_WIFI_NM_HOSTAPD_AP) static char uap_ssid[IEEEtypes_SSID_SIZE + 1]; #endif @@ -100,9 +105,9 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) struct in_addr dhcps_addr4; struct in_addr base_addr; struct in_addr netmask_addr; -#endif struct wifi_iface_status status = { 0 }; struct wifi_ap_sta_info ap_sta_info = { 0 }; +#endif LOG_DBG("WLAN: received event %d", reason); @@ -138,11 +143,20 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) LOG_ERR("WLAN: initialization failed"); break; case WLAN_REASON_AUTH_SUCCESS: +#ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT + net_if_dormant_off(g_mlan.netif); +#endif LOG_DBG("WLAN: authenticated to nxp_wlan_network"); break; case WLAN_REASON_ASSOC_SUCCESS: +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT net_if_dormant_off(g_mlan.netif); +#endif LOG_DBG("WLAN: associated to nxp_wlan_network"); +#ifdef CONFIG_NET_STATISTICS_WIFI + g_mlan.stats.sta_mgmt.beacons_rx = 0; + g_mlan.stats.sta_mgmt.beacons_miss = 0; +#endif break; case WLAN_REASON_SUCCESS: LOG_DBG("WLAN: connected to nxp_wlan_network"); @@ -186,15 +200,16 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) wifi_mgmt_raise_connect_result_event(g_mlan.netif, 0); break; case WLAN_REASON_CONNECT_FAILED: - net_eth_carrier_off(g_mlan.netif); + net_if_dormant_on(g_mlan.netif); LOG_WRN("WLAN: connect failed"); + wifi_mgmt_raise_connect_result_event(g_mlan.netif, WIFI_STATUS_CONN_FAIL); break; case WLAN_REASON_NETWORK_NOT_FOUND: - net_eth_carrier_off(g_mlan.netif); + net_if_dormant_on(g_mlan.netif); LOG_WRN("WLAN: nxp_wlan_network not found"); + wifi_mgmt_raise_connect_result_event(g_mlan.netif, WIFI_STATUS_CONN_AP_NOT_FOUND); break; case WLAN_REASON_NETWORK_AUTH_FAILED: - net_eth_carrier_off(g_mlan.netif); LOG_WRN("WLAN: nxp_wlan_network authentication failed"); auth_fail++; if (auth_fail >= 3) { @@ -202,6 +217,8 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) wlan_disconnect(); auth_fail = 0; } + net_if_dormant_on(g_mlan.netif); + wifi_mgmt_raise_connect_result_event(g_mlan.netif, WIFI_STATUS_CONN_WRONG_PASSWORD); break; case WLAN_REASON_ADDRESS_SUCCESS: LOG_DBG("wlan_network mgr: DHCP new lease"); @@ -210,7 +227,7 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) LOG_WRN("failed to obtain an IP address"); break; case WLAN_REASON_USER_DISCONNECT: - net_eth_carrier_off(g_mlan.netif); + net_if_dormant_on(g_mlan.netif); LOG_DBG("disconnected"); auth_fail = 0; s_nxp_wifi_StaConnected = false; @@ -229,7 +246,6 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) break; #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT case WLAN_REASON_UAP_SUCCESS: - net_eth_carrier_on(g_uap.netif); LOG_DBG("WLAN: UAP Started"); #ifndef CONFIG_WIFI_NM_HOSTAPD_AP ret = wlan_get_current_uap_network_ssid(uap_ssid); @@ -252,7 +268,7 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) return 0; } net_if_ipv4_set_netmask_by_addr(g_uap.netif, &dhcps_addr4, &netmask_addr); - net_if_up(g_uap.netif); + net_if_dormant_off(g_uap.netif); if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_BASE, &base_addr) < 0) { LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_BASE"); @@ -268,24 +284,18 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) s_nxp_wifi_UapActivated = true; break; case WLAN_REASON_UAP_CLIENT_ASSOC: - LOG_DBG("WLAN: UAP a Client Associated"); - LOG_DBG("Client => "); - print_mac((const char *)data); - LOG_DBG("Associated with Soft AP"); - break; - case WLAN_REASON_UAP_CLIENT_CONN: - wlan_get_current_uap_network(&nxp_wlan_network); + wlan_get_current_uap_network(&nxp_wlan_uap_network); #ifdef CONFIG_NXP_WIFI_11AX - if (nxp_wlan_network.dot11ax) { + if (nxp_wlan_uap_network.dot11ax) { ap_sta_info.link_mode = WIFI_6; } else #endif #ifdef CONFIG_NXP_WIFI_11AC - if (nxp_wlan_network.dot11ac) { + if (nxp_wlan_uap_network.dot11ac) { ap_sta_info.link_mode = WIFI_5; } else #endif - if (nxp_wlan_network.dot11n) { + if (nxp_wlan_uap_network.dot11n) { ap_sta_info.link_mode = WIFI_4; } else { ap_sta_info.link_mode = WIFI_3; @@ -296,6 +306,12 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) ap_sta_info.twt_capable = status.twt_capable; wifi_mgmt_raise_ap_sta_connected_event(g_uap.netif, &ap_sta_info); + LOG_DBG("WLAN: UAP a Client Associated"); + LOG_DBG("Client => "); + print_mac((const char *)data); + LOG_DBG("Associated with Soft AP"); + break; + case WLAN_REASON_UAP_CLIENT_CONN: LOG_DBG("WLAN: UAP a Client Connected"); LOG_DBG("Client => "); print_mac((const char *)data); @@ -312,9 +328,15 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) LOG_DBG("%d", disassoc_resp->reason_code); break; case WLAN_REASON_UAP_STOPPED: - net_eth_carrier_off(g_uap.netif); + net_if_dormant_on(g_uap.netif); LOG_DBG("WLAN: UAP Stopped"); + if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS, &dhcps_addr4) < 0) { + LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS"); + } else { + net_if_ipv4_addr_rm(g_uap.netif, &dhcps_addr4); + } + net_dhcpv4_server_stop(g_uap.netif); LOG_DBG("DHCP Server stopped successfully"); s_nxp_wifi_UapActivated = false; @@ -340,6 +362,10 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) case WLAN_REASON_PRE_BEACON_LOST: break; #endif + case WLAN_REASON_FW_HANG: + case WLAN_REASON_FW_RESET: + LOG_DBG("WLAN: FW hang"); + break; default: LOG_WRN("WLAN: Unknown Event: %d", reason); } @@ -421,6 +447,14 @@ static int nxp_wifi_wlan_start(void) /* L1 network layer (physical layer) is up */ net_eth_carrier_on(g_mlan.netif); +#ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT + /* Initialize device as dormant */ + net_if_dormant_on(g_uap.netif); + + /* L1 network layer (physical layer) is up */ + net_eth_carrier_on(g_uap.netif); +#endif + return 0; } @@ -431,6 +465,7 @@ static int nxp_wifi_start_ap(const struct device *dev, struct wifi_connect_req_p int status = NXP_WIFI_RET_SUCCESS; int ret; struct interface *if_handle = (struct interface *)&g_uap; + struct ipv4_config *ap_addr4 = &nxp_wlan_uap_network.ip.ipv4; if (if_handle->state.interface != WLAN_BSS_TYPE_UAP) { LOG_ERR("Wi-Fi not in uAP mode"); @@ -448,48 +483,68 @@ static int nxp_wifi_start_ap(const struct device *dev, struct wifi_connect_req_p } if (status == NXP_WIFI_RET_SUCCESS) { - wlan_remove_network(nxp_wlan_network.name); + wlan_remove_network(nxp_wlan_uap_network.name); - wlan_initialize_uap_network(&nxp_wlan_network); + wlan_initialize_uap_network(&nxp_wlan_uap_network); - memcpy(nxp_wlan_network.name, NXP_WIFI_UAP_NETWORK_NAME, + memcpy(nxp_wlan_uap_network.name, NXP_WIFI_UAP_NETWORK_NAME, strlen(NXP_WIFI_UAP_NETWORK_NAME)); - memcpy(nxp_wlan_network.ssid, params->ssid, params->ssid_length); + memcpy(nxp_wlan_uap_network.ssid, params->ssid, params->ssid_length); if (params->channel == WIFI_CHANNEL_ANY) { - nxp_wlan_network.channel = 0; + nxp_wlan_uap_network.channel = 0; } else { - nxp_wlan_network.channel = params->channel; + nxp_wlan_uap_network.channel = params->channel; + } + + if (nxp_wlan_uap_network.channel == 0) { + nxp_wlan_uap_network.acs_band = + (params->band == WIFI_FREQ_BAND_5_GHZ) ? 1 : 0; } if (params->mfp == WIFI_MFP_REQUIRED) { - nxp_wlan_network.security.mfpc = true; - nxp_wlan_network.security.mfpr = true; + nxp_wlan_uap_network.security.mfpc = true; + nxp_wlan_uap_network.security.mfpr = true; } else if (params->mfp == WIFI_MFP_OPTIONAL) { - nxp_wlan_network.security.mfpc = true; - nxp_wlan_network.security.mfpr = false; + nxp_wlan_uap_network.security.mfpc = true; + nxp_wlan_uap_network.security.mfpr = false; } if (params->security == WIFI_SECURITY_TYPE_NONE) { - nxp_wlan_network.security.type = WLAN_SECURITY_NONE; + nxp_wlan_uap_network.security.type = WLAN_SECURITY_NONE; } else if (params->security == WIFI_SECURITY_TYPE_PSK) { - nxp_wlan_network.security.type = WLAN_SECURITY_WPA2; - nxp_wlan_network.security.psk_len = params->psk_length; - strncpy(nxp_wlan_network.security.psk, params->psk, params->psk_length); - } -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT - else if (params->security == WIFI_SECURITY_TYPE_PSK_SHA256) { - nxp_wlan_network.security.type = WLAN_SECURITY_WPA2; - nxp_wlan_network.security.key_mgmt |= WLAN_KEY_MGMT_PSK_SHA256; - nxp_wlan_network.security.psk_len = params->psk_length; - strncpy(nxp_wlan_network.security.psk, params->psk, params->psk_length); - } -#endif - else if (params->security == WIFI_SECURITY_TYPE_SAE) { - nxp_wlan_network.security.type = WLAN_SECURITY_WPA3_SAE; - nxp_wlan_network.security.password_len = params->psk_length; - strncpy(nxp_wlan_network.security.password, params->psk, + nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA2; + nxp_wlan_uap_network.security.psk_len = params->psk_length; + strncpy(nxp_wlan_uap_network.security.psk, params->psk, params->psk_length); + } else if (params->security == WIFI_SECURITY_TYPE_PSK_SHA256) { + nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA2; + nxp_wlan_uap_network.security.key_mgmt = WLAN_KEY_MGMT_PSK_SHA256; + nxp_wlan_uap_network.security.psk_len = params->psk_length; + strncpy(nxp_wlan_uap_network.security.psk, params->psk, params->psk_length); + } else if (params->security == WIFI_SECURITY_TYPE_SAE) { + nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA3_SAE; + nxp_wlan_uap_network.security.password_len = params->psk_length; + strncpy(nxp_wlan_uap_network.security.password, params->psk, + params->psk_length); + } else if (params->security == WIFI_SECURITY_TYPE_SAE_H2E) { + nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA3_SAE; + nxp_wlan_uap_network.security.pwe_derivation = 1; + nxp_wlan_uap_network.security.password_len = params->psk_length; + strncpy(nxp_wlan_uap_network.security.password, params->psk, + params->psk_length); + } else if (params->security == WIFI_SECURITY_TYPE_SAE_AUTO) { + nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA3_SAE; + nxp_wlan_uap_network.security.pwe_derivation = 2; + nxp_wlan_uap_network.security.password_len = params->psk_length; + strncpy(nxp_wlan_uap_network.security.password, params->psk, + params->psk_length); + } else if (params->security == WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL) { + nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA2_WPA3_SAE_MIXED; + nxp_wlan_uap_network.security.psk_len = params->psk_length; + strncpy(nxp_wlan_uap_network.security.psk, params->psk, params->psk_length); + nxp_wlan_uap_network.security.password_len = params->psk_length; + strncpy(nxp_wlan_uap_network.security.password, params->psk, params->psk_length); } else { status = NXP_WIFI_RET_BAD_PARAM; @@ -505,14 +560,39 @@ static int nxp_wifi_start_ap(const struct device *dev, struct wifi_connect_req_p wlan_uap_set_hidden_ssid(params->ignore_broadcast_ssid); } - ret = wlan_add_network(&nxp_wlan_network); + switch (params->bandwidth) { + case WIFI_FREQ_BANDWIDTH_20MHZ: + case WIFI_FREQ_BANDWIDTH_40MHZ: + case WIFI_FREQ_BANDWIDTH_80MHZ: + wlan_uap_set_bandwidth(params->bandwidth); + break; + default: + LOG_ERR("Invalid bandwidth"); + return -EAGAIN; + } + + if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS, &ap_addr4->address) < 0) { + LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS"); + return -ENOENT; + } + ap_addr4->gw = ap_addr4->address; + + if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_MASK, &ap_addr4->netmask) < 0) { + LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_MASK"); + return -ENOENT; + } + + nxp_wlan_uap_network.beacon_period = NXP_WIFI_SAP_BEACON_PERIOD_DEFAULT; + nxp_wlan_uap_network.dtim_period = NXP_WIFI_SAP_DTIM_PERIOD_DEFAULT; + + ret = wlan_add_network(&nxp_wlan_uap_network); if (ret != WM_SUCCESS) { status = NXP_WIFI_RET_FAIL; } - ret = wlan_start_network(nxp_wlan_network.name); + ret = wlan_start_network(nxp_wlan_uap_network.name); if (ret != WM_SUCCESS) { - wlan_remove_network(nxp_wlan_network.name); + wlan_remove_network(nxp_wlan_uap_network.name); status = NXP_WIFI_RET_FAIL; } @@ -569,9 +649,31 @@ static int nxp_wifi_ap_config_params(const struct device *dev, struct wifi_ap_co ret = wlan_uap_set_sta_ageout_timer(params->max_inactivity * 10); if (ret != WM_SUCCESS) { status = NXP_WIFI_RET_FAIL; + LOG_ERR("Failed to set maximum inactivity duration for stations"); + } else { + LOG_INF("Set maximum inactivity duration for stations: %d (s)", + params->max_inactivity); + } + } + + if (params->type & WIFI_AP_CONFIG_PARAM_MAX_NUM_STA) { + ret = wlan_set_uap_max_clients(params->max_num_sta); + if (ret != WM_SUCCESS) { + status = NXP_WIFI_RET_FAIL; + LOG_ERR("Failed to set maximum number of stations"); + } else { + LOG_INF("Set maximum number of stations: %d", params->max_num_sta); + } + } + + if (params->type & WIFI_AP_CONFIG_PARAM_BANDWIDTH) { + ret = wlan_uap_set_bandwidth(params->bandwidth); + if (ret != WM_SUCCESS) { + status = NXP_WIFI_RET_FAIL; + LOG_ERR("Failed to set Wi-Fi AP bandwidth"); + } else { + LOG_INF("Set Wi-Fi AP bandwidth: %d", params->bandwidth); } - } else { - return -EINVAL; } } @@ -619,15 +721,24 @@ static int nxp_wifi_process_results(unsigned int count) if (scan_result.wpa2) { res.security = WIFI_SECURITY_TYPE_PSK; } -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT if (scan_result.wpa2_sha256) { res.security = WIFI_SECURITY_TYPE_PSK_SHA256; } -#endif if (scan_result.wpa3_sae) { res.security = WIFI_SECURITY_TYPE_SAE; } + if (scan_result.wpa3_entp) { + res.wpa3_ent_type = WIFI_WPA3_ENTERPRISE_ONLY; + res.security = WIFI_SECURITY_TYPE_EAP_TLS; + } else if (scan_result.wpa3_1x_sha256) { + res.wpa3_ent_type = WIFI_WPA3_ENTERPRISE_SUITEB; + res.security = WIFI_SECURITY_TYPE_EAP_TLS; + } else if (scan_result.wpa3_1x_sha384) { + res.wpa3_ent_type = WIFI_WPA3_ENTERPRISE_SUITEB_192; + res.security = WIFI_SECURITY_TYPE_EAP_TLS; + } + if (scan_result.ap_mfpr) { res.mfp = WIFI_MFP_REQUIRED; } else if (scan_result.ap_mfpc) { @@ -829,20 +940,35 @@ static int nxp_wifi_connect(const struct device *dev, struct wifi_connect_req_pa nxp_wlan_network.security.type = WLAN_SECURITY_WPA2; nxp_wlan_network.security.psk_len = params->psk_length; strncpy(nxp_wlan_network.security.psk, params->psk, params->psk_length); - } -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT - else if (params->security == WIFI_SECURITY_TYPE_PSK_SHA256) { + } else if (params->security == WIFI_SECURITY_TYPE_PSK_SHA256) { nxp_wlan_network.security.type = WLAN_SECURITY_WPA2; - nxp_wlan_network.security.key_mgmt |= WLAN_KEY_MGMT_PSK_SHA256; + nxp_wlan_network.security.key_mgmt = WLAN_KEY_MGMT_PSK_SHA256; nxp_wlan_network.security.psk_len = params->psk_length; strncpy(nxp_wlan_network.security.psk, params->psk, params->psk_length); - } -#endif - else if (params->security == WIFI_SECURITY_TYPE_SAE) { + } else if (params->security == WIFI_SECURITY_TYPE_SAE) { nxp_wlan_network.security.type = WLAN_SECURITY_WPA3_SAE; nxp_wlan_network.security.password_len = params->psk_length; strncpy(nxp_wlan_network.security.password, params->psk, params->psk_length); + } else if (params->security == WIFI_SECURITY_TYPE_SAE_H2E) { + nxp_wlan_network.security.type = WLAN_SECURITY_WPA3_SAE; + nxp_wlan_network.security.pwe_derivation = 1; + nxp_wlan_network.security.password_len = params->psk_length; + strncpy(nxp_wlan_network.security.password, params->psk, + params->psk_length); + } else if (params->security == WIFI_SECURITY_TYPE_SAE_AUTO) { + nxp_wlan_network.security.type = WLAN_SECURITY_WPA3_SAE; + nxp_wlan_network.security.pwe_derivation = 2; + nxp_wlan_network.security.password_len = params->psk_length; + strncpy(nxp_wlan_network.security.password, params->psk, + params->psk_length); + } else if (params->security == WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL) { + nxp_wlan_network.security.type = WLAN_SECURITY_WPA2_WPA3_SAE_MIXED; + nxp_wlan_network.security.psk_len = params->psk_length; + strncpy(nxp_wlan_network.security.psk, params->psk, params->psk_length); + nxp_wlan_network.security.password_len = params->psk_length; + strncpy(nxp_wlan_network.security.password, params->psk, + params->psk_length); } else { status = NXP_WIFI_RET_BAD_PARAM; } @@ -907,20 +1033,116 @@ static int nxp_wifi_disconnect(const struct device *dev) return 0; } -static inline enum wifi_security_type nxp_wifi_security_type(enum wlan_security_type type) +static inline enum wifi_security_type nxp_wifi_key_mgmt_to_zephyr(int key_mgmt, int pwe) { - switch (type) { - case WLAN_SECURITY_NONE: + switch (key_mgmt) { + case WLAN_KEY_MGMT_NONE: return WIFI_SECURITY_TYPE_NONE; - case WLAN_SECURITY_WPA2: + case WLAN_KEY_MGMT_PSK: return WIFI_SECURITY_TYPE_PSK; - case WLAN_SECURITY_WPA3_SAE: + case WLAN_KEY_MGMT_PSK_SHA256: + return WIFI_SECURITY_TYPE_PSK_SHA256; + case WLAN_KEY_MGMT_SAE: + if (pwe == 1) { + return WIFI_SECURITY_TYPE_SAE_H2E; + } else if (pwe == 2) { + return WIFI_SECURITY_TYPE_SAE_AUTO; + } else { + return WIFI_SECURITY_TYPE_SAE_HNP; + } return WIFI_SECURITY_TYPE_SAE; + case WLAN_KEY_MGMT_SAE | WLAN_KEY_MGMT_PSK: + return WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL; default: return WIFI_SECURITY_TYPE_UNKNOWN; } } +#ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT +static int nxp_wifi_uap_status(const struct device *dev, struct wifi_iface_status *status) +{ + enum wlan_connection_state connection_state = WLAN_UAP_STOPPED; + struct interface *if_handle = (struct interface *)&g_uap; + + wlan_get_uap_connection_state(&connection_state); + + switch (connection_state) { + case WLAN_UAP_STARTED: + status->state = WIFI_SAP_IFACE_ENABLED; + break; + case WLAN_UAP_STOPPED: + status->state = WIFI_SAP_IFACE_DISABLED; + break; + default: + status->state = WIFI_SAP_IFACE_DISABLED; + break; + } + + if (connection_state == WLAN_UAP_STARTED) { + + if (!wlan_get_current_uap_network(&nxp_wlan_uap_network)) { + strncpy(status->ssid, nxp_wlan_uap_network.ssid, WIFI_SSID_MAX_LEN); + status->ssid[WIFI_SSID_MAX_LEN - 1] = 0; + status->ssid_len = strlen(status->ssid); + + memcpy(status->bssid, nxp_wlan_uap_network.bssid, WIFI_MAC_ADDR_LEN); + + status->rssi = nxp_wlan_uap_network.rssi; + + wlan_get_uap_channel(&status->channel); + + status->beacon_interval = nxp_wlan_uap_network.beacon_period; + + status->dtim_period = nxp_wlan_uap_network.dtim_period; + +#ifdef CONFIG_NXP_WIFI_11AX_TWT + status->twt_capable = true; +#endif + + if (if_handle->state.interface == WLAN_BSS_TYPE_STA) { + status->iface_mode = WIFI_MODE_INFRA; + } else if (if_handle->state.interface == WLAN_BSS_TYPE_UAP) { + status->iface_mode = WIFI_MODE_AP; + } + +#ifdef CONFIG_NXP_WIFI_11AX + if (nxp_wlan_uap_network.dot11ax) { + status->link_mode = WIFI_6; + } +#endif +#ifdef CONFIG_NXP_WIFI_11AC + else if (nxp_wlan_uap_network.dot11ac) { + status->link_mode = WIFI_5; + } +#endif + else if (nxp_wlan_uap_network.dot11n) { + status->link_mode = WIFI_4; + } else { + status->link_mode = WIFI_3; + } + + if (nxp_wlan_uap_network.channel != 0) { + status->band = nxp_wlan_uap_network.channel > 14 ? + WIFI_FREQ_BAND_5_GHZ : WIFI_FREQ_BAND_2_4_GHZ; + } else { + status->band = nxp_wlan_uap_network.acs_band; + } + + status->security = nxp_wifi_key_mgmt_to_zephyr( + nxp_wlan_uap_network.security.key_mgmt, + nxp_wlan_uap_network.security.pwe_derivation); + status->mfp = + nxp_wlan_uap_network.security.mfpr + ? WIFI_MFP_REQUIRED + : (nxp_wlan_uap_network.security.mfpc ? WIFI_MFP_OPTIONAL + : 0); + } + } + + return 0; +} +#endif + static int nxp_wifi_status(const struct device *dev, struct wifi_iface_status *status) { enum wlan_connection_state connection_state = WLAN_DISCONNECTED; @@ -942,8 +1164,10 @@ static int nxp_wifi_status(const struct device *dev, struct wifi_iface_status *s status->state = WIFI_STATE_ASSOCIATING; } else if (connection_state == WLAN_ASSOCIATED) { status->state = WIFI_STATE_ASSOCIATED; - } else if (connection_state == WLAN_CONNECTED) { + } else if (connection_state == WLAN_AUTHENTICATED + || connection_state == WLAN_CONNECTED) { status->state = WIFI_STATE_COMPLETED; + wlan_ds_rate ds_rate = {0}; if (!wlan_get_current_network(&nxp_wlan_network)) { strncpy(status->ssid, nxp_wlan_network.ssid, WIFI_SSID_MAX_LEN - 1); @@ -987,19 +1211,58 @@ static int nxp_wifi_status(const struct device *dev, struct wifi_iface_status *s status->band = nxp_wlan_network.channel > 14 ? WIFI_FREQ_BAND_5_GHZ : WIFI_FREQ_BAND_2_4_GHZ; - status->security = nxp_wifi_security_type(nxp_wlan_network.security.type); + status->security = nxp_wifi_key_mgmt_to_zephyr( + nxp_wlan_network.security.key_mgmt, + nxp_wlan_network.security.pwe_derivation); status->mfp = nxp_wlan_network.security.mfpr ? WIFI_MFP_REQUIRED : (nxp_wlan_network.security.mfpc ? WIFI_MFP_OPTIONAL : 0); } + ds_rate.sub_command = WIFI_DS_GET_DATA_RATE; + if (!wlan_get_data_rate(&ds_rate, WLAN_BSS_TYPE_STA)) { + wifi_data_rate_t *datarate = (wifi_data_rate_t *)&ds_rate.param.data_rate; + int lg_rate[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54}; + + if (datarate->tx_rate_format == MLAN_RATE_FORMAT_LG && + datarate->tx_data_rate < 12) { + /* Legacy rates (in bps) */ + /* Need to feed Zephyr L2 Wi-Fi with rate value in unit of Mbps*/ + status->current_phy_tx_rate = lg_rate[datarate->tx_data_rate]; + } else if (datarate->tx_rate_format <= 3) { + /* HT, VHT, HE rates (in bps) */ + /* Need to feed Zephyr L2 Wi-Fi with rate value in unit of Mbps*/ + status->current_phy_tx_rate = (datarate->tx_data_rate >> 1); + } + } } return 0; } #if defined(CONFIG_NET_STATISTICS_WIFI) +#ifdef CONFIG_NXP_WIFI_GET_LOG +static int nxp_wifi_get_detail_stats(int bss_type, wlan_pkt_stats_t *stats) +{ + int ret = -ENODEV; + + if (bss_type == WLAN_BSS_TYPE_STA) { + ret = wlan_get_log(stats); + } +#ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT + else if (bss_type == WLAN_BSS_TYPE_UAP) { + ret = wlan_uap_get_log(stats); + } +#endif + return ret; +} +#endif + static int nxp_wifi_stats(const struct device *dev, struct net_stats_wifi *stats) { struct interface *if_handle = (struct interface *)dev->data; +#ifdef CONFIG_NXP_WIFI_GET_LOG + int ret; + wlan_pkt_stats_t *wifi_stats; +#endif stats->bytes.received = if_handle->stats.bytes.received; stats->bytes.sent = if_handle->stats.bytes.sent; @@ -1011,8 +1274,87 @@ static int nxp_wifi_stats(const struct device *dev, struct net_stats_wifi *stats stats->broadcast.tx = if_handle->stats.broadcast.tx; stats->multicast.rx = if_handle->stats.multicast.rx; stats->multicast.tx = if_handle->stats.multicast.tx; - stats->sta_mgmt.beacons_rx = if_handle->stats.sta_mgmt.beacons_rx; - stats->sta_mgmt.beacons_miss = if_handle->stats.sta_mgmt.beacons_miss; + stats->unicast.rx = if_handle->stats.unicast.rx; + stats->unicast.tx = if_handle->stats.unicast.tx; + stats->overrun_count = if_handle->stats.errors.rx + if_handle->stats.errors.tx; + + if (!net_if_is_admin_up(net_if_lookup_by_dev(dev))) { + return 0; + } + +#ifdef CONFIG_NXP_WIFI_GET_LOG + wifi_stats = k_malloc(sizeof(wlan_pkt_stats_t)); + if (!wifi_stats) { + LOG_WRN("No mem for detailed statistics"); + return 0; + } + + memset(wifi_stats, 0, sizeof(wlan_pkt_stats_t)); + ret = nxp_wifi_get_detail_stats(if_handle->state.interface, wifi_stats); + if (ret != 0) { + LOG_ERR("Get detailed statistics from Wi-Fi failed ret %d", ret); + k_free(wifi_stats); + return ret; + } + + if (wifi_stats->bcn_rcv_cnt >= if_handle->stats.sta_mgmt.beacons_rx) { + stats->sta_mgmt.beacons_rx = wifi_stats->bcn_rcv_cnt - + if_handle->stats.sta_mgmt.beacons_rx; + } else { + /** we might have a new connection since last stats reset, + * so stored stats is invalid + */ + stats->sta_mgmt.beacons_rx = wifi_stats->bcn_rcv_cnt; + } + + if (wifi_stats->bcn_miss_cnt >= if_handle->stats.sta_mgmt.beacons_miss) { + stats->sta_mgmt.beacons_miss = wifi_stats->bcn_miss_cnt - + if_handle->stats.sta_mgmt.beacons_miss; + } else { + stats->sta_mgmt.beacons_miss = wifi_stats->bcn_miss_cnt; + } + + k_free(wifi_stats); +#endif + return 0; +} + +int nxp_wifi_reset_stats(const struct device *dev) +{ + struct interface *if_handle = (struct interface *)dev->data; +#ifdef CONFIG_NXP_WIFI_GET_LOG + int ret; + wlan_pkt_stats_t *wifi_stats; +#endif + + /* clear local statistics */ + memset(&if_handle->stats, 0, sizeof(if_handle->stats)); + + if (!net_if_is_admin_up(net_if_lookup_by_dev(dev))) { + return 0; + } + +#ifdef CONFIG_NXP_WIFI_GET_LOG + /* store firmware statistics */ + wifi_stats = k_malloc(sizeof(wlan_pkt_stats_t)); + if (!wifi_stats) { + LOG_WRN("No mem to reset detailed statistics"); + return 0; + } + + memset(wifi_stats, 0, sizeof(wlan_pkt_stats_t)); + ret = nxp_wifi_get_detail_stats(if_handle->state.interface, wifi_stats); + if (ret != 0) { + LOG_ERR("Reset detailed statistics from Wi-Fi failed ret %d", ret); + k_free(wifi_stats); + return ret; + } + + if_handle->stats.sta_mgmt.beacons_rx = wifi_stats->bcn_rcv_cnt; + if_handle->stats.sta_mgmt.beacons_miss = wifi_stats->bcn_miss_cnt; + + k_free(wifi_stats); +#endif return 0; } @@ -1059,6 +1401,7 @@ static void nxp_wifi_auto_connect(void) } #endif +#ifdef CONFIG_NXP_WIFI_11K static int nxp_wifi_11k_cfg(const struct device *dev, struct wifi_11k_params *params) { if (params->oper == WIFI_MGMT_GET) { @@ -1070,6 +1413,34 @@ static int nxp_wifi_11k_cfg(const struct device *dev, struct wifi_11k_params *pa return 0; } +static int nxp_wifi_11k_neighbor_request(const struct device *dev, struct wifi_11k_params *params) +{ + int ret = WM_SUCCESS; + + if (params != NULL) { + if (strlen(params->ssid) > WIFI_SSID_MAX_LEN) { + LOG_ERR("ssid too long"); + return -EINVAL; + } + + ret = wlan_host_11k_neighbor_req(params->ssid); + if (ret != WM_SUCCESS) { + LOG_ERR("send neighbor report request fail"); + return -EAGAIN; + } + } + + return 0; +} +#endif + +#ifdef CONFIG_NXP_WIFI_11V +static int nxp_wifi_btm_query(const struct device *dev, uint8_t reason) +{ + return wlan_host_11v_bss_trans_query(reason); +} +#endif + static int nxp_wifi_power_save(const struct device *dev, struct wifi_ps_params *params) { int status = NXP_WIFI_RET_SUCCESS; @@ -1356,11 +1727,13 @@ static int nxp_wifi_set_twt(const struct device *dev, struct wifi_twt_params *pa twt_setup_conf.implicit = params->setup.implicit; twt_setup_conf.announced = params->setup.announce; twt_setup_conf.trigger_enabled = params->setup.trigger; + twt_setup_conf.twt_info_disabled = params->setup.twt_info_disable; twt_setup_conf.negotiation_type = params->negotiation_type; twt_setup_conf.twt_wakeup_duration = params->setup.twt_wake_interval; twt_setup_conf.flow_identifier = params->flow_id; twt_setup_conf.hard_constraint = 1; - twt_setup_conf.twt_mantissa = params->setup.twt_interval; + twt_setup_conf.twt_exponent = params->setup.twt_exponent; + twt_setup_conf.twt_mantissa = params->setup.twt_mantissa; twt_setup_conf.twt_request = params->setup.responder; ret = wlan_set_twt_setup_cfg(&twt_setup_conf); } else if (params->operation == WIFI_TWT_TEARDOWN) { @@ -1372,6 +1745,56 @@ static int nxp_wifi_set_twt(const struct device *dev, struct wifi_twt_params *pa return ret; } + +#ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT +static int nxp_wifi_set_btwt(const struct device *dev, struct wifi_twt_params *params) +{ + wlan_btwt_config_t btwt_config; + + btwt_config.action = 1; + btwt_config.sub_id = params->btwt.sub_id; + btwt_config.nominal_wake = params->btwt.nominal_wake; + btwt_config.max_sta_support = params->btwt.max_sta_support; + btwt_config.twt_mantissa = params->btwt.twt_mantissa; + btwt_config.twt_offset = params->btwt.twt_offset; + btwt_config.twt_exponent = params->btwt.twt_exponent; + btwt_config.sp_gap = params->btwt.sp_gap; + + return wlan_set_btwt_cfg(&btwt_config); +} +#endif +#endif + +static int nxp_wifi_set_rts_threshold(const struct device *dev, unsigned int rts_threshold) +{ + int ret = -1; + +#if CONFIG_NXP_WIFI_RTS_THRESHOLD + if (rts_threshold == -1) { + rts_threshold = MLAN_RTS_MAX_VALUE; + } + + ret = wlan_set_rts(rts_threshold); +#endif + + return ret; +} + +#ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT +static int nxp_wifi_ap_set_rts_threshold(const struct device *dev, unsigned int rts_threshold) +{ + int ret = -1; + +#if CONFIG_NXP_WIFI_RTS_THRESHOLD + if (rts_threshold == -1) { + rts_threshold = MLAN_RTS_MAX_VALUE; + } + + ret = wlan_set_uap_rts(rts_threshold); +#endif + + return ret; +} #endif static void nxp_wifi_sta_init(struct net_if *iface) @@ -1383,8 +1806,13 @@ static void nxp_wifi_sta_init(struct net_if *iface) eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI; intf->netif = iface; #ifdef CONFIG_WIFI_NM +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT wifi_nm_register_mgd_type_iface(wifi_nm_get_instance("wifi_supplicant"), WIFI_TYPE_STA, iface); +#else + wifi_nm_register_mgd_type_iface(wifi_nm_get_instance("wifi_sta"), + WIFI_TYPE_STA, iface); +#endif #endif g_mlan.state.interface = WLAN_BSS_TYPE_STA; @@ -1418,9 +1846,15 @@ static void nxp_wifi_uap_init(struct net_if *iface) eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI; intf->netif = iface; + #ifdef CONFIG_WIFI_NM +#ifdef CONFIG_WIFI_NM_HOSTAPD_AP wifi_nm_register_mgd_type_iface(wifi_nm_get_instance("hostapd"), WIFI_TYPE_SAP, iface); +#else + wifi_nm_register_mgd_type_iface(wifi_nm_get_instance("wifi_sap"), + WIFI_TYPE_SAP, iface); +#endif #endif g_uap.state.interface = WLAN_BSS_TYPE_UAP; @@ -1462,6 +1896,8 @@ static NXP_WIFI_SET_FUNC_ATTR int nxp_wifi_send(const struct device *dev, struct if_handle->stats.multicast.tx++; } else if (net_eth_is_addr_broadcast(&hdr->dst)) { if_handle->stats.broadcast.tx++; + } else { + if_handle->stats.unicast.tx++; } #endif @@ -1491,6 +1927,8 @@ static NXP_WIFI_SET_FUNC_ATTR int nxp_wifi_recv(struct net_if *iface, struct net if_handle->stats.broadcast.rx++; } else if (net_eth_is_addr_multicast(&hdr->dst)) { if_handle->stats.multicast.rx++; + } else { + if_handle->stats.unicast.rx++; } if_handle->stats.bytes.received += pkt_len; @@ -1656,15 +2094,27 @@ static const struct wifi_mgmt_ops nxp_wifi_sta_mgmt = { .iface_status = nxp_wifi_status, #if defined(CONFIG_NET_STATISTICS_WIFI) .get_stats = nxp_wifi_stats, + .reset_stats = nxp_wifi_reset_stats, #endif +#ifdef CONFIG_NXP_WIFI_11K .cfg_11k = nxp_wifi_11k_cfg, + .send_11k_neighbor_request = nxp_wifi_11k_neighbor_request, +#endif +#ifdef CONFIG_NXP_WIFI_11V + .btm_query = nxp_wifi_btm_query, +#endif .set_power_save = nxp_wifi_power_save, .get_power_save_config = nxp_wifi_get_power_save, #ifdef CONFIG_NXP_WIFI_11AX_TWT .set_twt = nxp_wifi_set_twt, #endif + .set_rts_threshold = nxp_wifi_set_rts_threshold, }; +#if defined(CONFIG_WIFI_NM) && !defined(CONFIG_WIFI_NM_WPA_SUPPLICANT) +DEFINE_WIFI_NM_INSTANCE(wifi_sta, &nxp_wifi_sta_mgmt); +#endif + #if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT) static const struct zep_wpa_supp_dev_ops nxp_wifi_drv_ops = { .init = wifi_nxp_wpa_supp_dev_init, @@ -1699,6 +2149,7 @@ static const struct zep_wpa_supp_dev_ops nxp_wifi_drv_ops = { .dpp_listen = wifi_nxp_wpa_dpp_listen, .remain_on_channel = wifi_nxp_wpa_supp_remain_on_channel, .cancel_remain_on_channel = wifi_nxp_wpa_supp_cancel_remain_on_channel, + .send_action_cancel_wait = wifi_nxp_wpa_supp_cancel_action_wait, }; #endif @@ -1726,15 +2177,24 @@ NET_DEVICE_INIT_INSTANCE(wifi_nxp_sta, "ml", 0, nxp_wifi_dev_init, PM_DEVICE_DT_ static const struct wifi_mgmt_ops nxp_wifi_uap_mgmt = { .ap_enable = nxp_wifi_start_ap, .ap_disable = nxp_wifi_stop_ap, - .iface_status = nxp_wifi_status, + .iface_status = nxp_wifi_uap_status, #if defined(CONFIG_NET_STATISTICS_WIFI) .get_stats = nxp_wifi_stats, + .reset_stats = nxp_wifi_reset_stats, #endif .set_power_save = nxp_wifi_power_save, .get_power_save_config = nxp_wifi_get_power_save, .ap_config_params = nxp_wifi_ap_config_params, +#ifdef CONFIG_NXP_WIFI_11AX_TWT + .set_btwt = nxp_wifi_set_btwt, +#endif + .set_rts_threshold = nxp_wifi_ap_set_rts_threshold, }; +#if defined(CONFIG_WIFI_NM) && !defined(CONFIG_WIFI_NM_HOSTAPD_AP) +DEFINE_WIFI_NM_INSTANCE(wifi_sap, &nxp_wifi_uap_mgmt); +#endif + static const struct net_wifi_mgmt_offload nxp_wifi_uap_apis = { .wifi_iface.iface_api.init = nxp_wifi_uap_init, .wifi_iface.set_config = nxp_wifi_set_config, diff --git a/drivers/wifi/nxp/nxp_wifi_drv.h b/drivers/wifi/nxp/nxp_wifi_drv.h index d4c1620e8ad84..f7dd195578328 100644 --- a/drivers/wifi/nxp/nxp_wifi_drv.h +++ b/drivers/wifi/nxp/nxp_wifi_drv.h @@ -48,6 +48,9 @@ #define NXP_WIFI_SYNC_PS_GROUP \ NXP_WIFI_EVENT_BIT(WLAN_REASON_PS_ENTER) | NXP_WIFI_EVENT_BIT(WLAN_REASON_PS_EXIT) +#define NXP_WIFI_SAP_BEACON_PERIOD_DEFAULT 100 +#define NXP_WIFI_SAP_DTIM_PERIOD_DEFAULT 1 + enum nxp_wifi_ret { NXP_WIFI_RET_SUCCESS, NXP_WIFI_RET_FAIL, diff --git a/drivers/wifi/siwx91x/CMakeLists.txt b/drivers/wifi/siwx91x/CMakeLists.txt new file mode 100644 index 0000000000000..4085341bca096 --- /dev/null +++ b/drivers/wifi/siwx91x/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Silicon Laboratories Inc. + +if(CONFIG_WIFI_SILABS_SIWX91X) + zephyr_library_sources(siwx91x_wifi.c) + + if(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD) + zephyr_library_sources(siwx91x_wifi_socket.c) + endif() +endif() diff --git a/drivers/wifi/siwx91x/Kconfig.siwx91x b/drivers/wifi/siwx91x/Kconfig.siwx91x new file mode 100644 index 0000000000000..80e312d0f9e5e --- /dev/null +++ b/drivers/wifi/siwx91x/Kconfig.siwx91x @@ -0,0 +1,53 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config WIFI_SILABS_SIWX91X + bool "Silabs SiWx91x SoC series WiFi driver" + default y + depends on DT_HAS_SILABS_SIWX91X_WIFI_ENABLED + depends on NETWORKING + select WISECONNECT_NETWORK_STACK + select EVENTS + select NET_L2_WIFI_MGMT + help + Enable WiFi driver for the Silabs SiWx91x SoC series. + +if WIFI_SILABS_SIWX91X + +choice + prompt "Network stack" + default WIFI_SILABS_SIWX91X_NET_STACK_NATIVE + help + Choose "Native" stack if you want a better compatibility with Zephyr + features. "Offloaded" stack may provide better resource (power and + memory) consumption. + +config WIFI_SILABS_SIWX91X_NET_STACK_NATIVE + bool "Native" + select WIFI_USE_NATIVE_NETWORKING + select NET_L2_ETHERNET + +config WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD + bool "Offloaded" + select WIFI_OFFLOAD + +endchoice + +config NET_TCP_WORKQ_STACK_SIZE + default 2048 + +config NET_RX_STACK_SIZE + default 2048 + +config NET_MGMT_EVENT_STACK_SIZE + default 2048 + +config NET_MGMT_EVENT_QUEUE_SIZE + default 10 + +# Override the WIFI_MGMT_SCAN_SSID_FILT_MAX parameter for the Wi-Fi subsystem. +# This device supports filtering scan results for only one SSID. +config WIFI_MGMT_SCAN_SSID_FILT_MAX + default 1 + +endif diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.c b/drivers/wifi/siwx91x/siwx91x_wifi.c new file mode 100644 index 0000000000000..0e6b210acd1bb --- /dev/null +++ b/drivers/wifi/siwx91x/siwx91x_wifi.c @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT silabs_siwx91x_wifi + +#include +#include + +#include "siwx91x_wifi.h" +#include "siwx91x_wifi_socket.h" + +#include "sl_rsi_utility.h" +#include "sl_net_constants.h" +#include "sl_wifi_types.h" +#include "sl_wifi_callback_framework.h" +#include "sl_wifi.h" +#include "sl_net.h" + +LOG_MODULE_REGISTER(siwx91x_wifi); + +NET_BUF_POOL_FIXED_DEFINE(siwx91x_tx_pool, 1, _NET_ETH_MAX_FRAME_SIZE, 0, NULL); + +static unsigned int siwx91x_on_join(sl_wifi_event_t event, + char *result, uint32_t result_size, void *arg) +{ + struct siwx91x_dev *sidev = arg; + + if (*result != 'C') { + /* TODO: report the real reason of failure */ + wifi_mgmt_raise_connect_result_event(sidev->iface, WIFI_STATUS_CONN_FAIL); + sidev->state = WIFI_STATE_INACTIVE; + return 0; + } + + wifi_mgmt_raise_connect_result_event(sidev->iface, WIFI_STATUS_CONN_SUCCESS); + sidev->state = WIFI_STATE_COMPLETED; + + if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE)) { + net_if_dormant_off(sidev->iface); + } + + siwx91x_on_join_ipv4(sidev); + siwx91x_on_join_ipv6(sidev); + + return 0; +} + +static int siwx91x_connect(const struct device *dev, struct wifi_connect_req_params *params) +{ + sl_wifi_client_configuration_t wifi_config = { + .bss_type = SL_WIFI_BSS_TYPE_INFRASTRUCTURE, + }; + int ret; + + switch (params->security) { + case WIFI_SECURITY_TYPE_NONE: + wifi_config.security = SL_WIFI_OPEN; + wifi_config.encryption = SL_WIFI_NO_ENCRYPTION; + break; + case WIFI_SECURITY_TYPE_WPA_PSK: + wifi_config.security = SL_WIFI_WPA; + wifi_config.encryption = SL_WIFI_DEFAULT_ENCRYPTION; + wifi_config.credential_id = SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID; + break; + case WIFI_SECURITY_TYPE_PSK: + wifi_config.security = SL_WIFI_WPA2; + wifi_config.encryption = SL_WIFI_TKIP_ENCRYPTION; + wifi_config.credential_id = SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID; + break; + case WIFI_SECURITY_TYPE_PSK_SHA256: + wifi_config.security = SL_WIFI_WPA2; + wifi_config.encryption = SL_WIFI_CCMP_ENCRYPTION; + wifi_config.credential_id = SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID; + break; + case WIFI_SECURITY_TYPE_SAE: + /* TODO: Support the case where MFP is not required */ + wifi_config.security = SL_WIFI_WPA3; + wifi_config.credential_id = SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID; + break; + case WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL: + wifi_config.security = SL_WIFI_WPA2; + wifi_config.encryption = SL_WIFI_DEFAULT_ENCRYPTION; + wifi_config.credential_id = SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID; + break; + /* Zephyr WiFi shell doesn't specify how to pass credential for these + * key managements. + */ + case WIFI_SECURITY_TYPE_WEP: /* SL_WIFI_WEP/SL_WIFI_WEP_ENCRYPTION */ + case WIFI_SECURITY_TYPE_EAP: /* SL_WIFI_WPA2_ENTERPRISE/ */ + case WIFI_SECURITY_TYPE_WAPI: + default: + return -ENOTSUP; + } + + if (params->band != WIFI_FREQ_BAND_UNKNOWN && params->band != WIFI_FREQ_BAND_2_4_GHZ) { + return -ENOTSUP; + } + + if (params->psk_length) { + sl_net_set_credential(SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID, SL_NET_WIFI_PSK, + params->psk, params->psk_length); + } + + if (params->sae_password_length) { + sl_net_set_credential(SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID, SL_NET_WIFI_PSK, + params->sae_password, params->sae_password_length); + } + + if (params->channel != WIFI_CHANNEL_ANY) { + wifi_config.channel.channel = params->channel; + } + + wifi_config.ssid.length = params->ssid_length, + memcpy(wifi_config.ssid.value, params->ssid, params->ssid_length); + + ret = sl_wifi_connect(SL_WIFI_CLIENT_INTERFACE, &wifi_config, 0); + if (ret != SL_STATUS_IN_PROGRESS) { + return -EIO; + } + + return 0; +} + +static int siwx91x_disconnect(const struct device *dev) +{ + struct siwx91x_dev *sidev = dev->data; + int ret; + + ret = sl_wifi_disconnect(SL_WIFI_CLIENT_INTERFACE); + if (ret) { + return -EIO; + } + if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE)) { + net_if_dormant_on(sidev->iface); + } + sidev->state = WIFI_STATE_INACTIVE; + return 0; +} + +static void siwx91x_report_scan_res(struct siwx91x_dev *sidev, sl_wifi_scan_result_t *result, + int item) +{ + static const struct { + int sl_val; + int z_val; + } security_convert[] = { + { SL_WIFI_OPEN, WIFI_SECURITY_TYPE_NONE }, + { SL_WIFI_WEP, WIFI_SECURITY_TYPE_WEP }, + { SL_WIFI_WPA, WIFI_SECURITY_TYPE_WPA_PSK }, + { SL_WIFI_WPA2, WIFI_SECURITY_TYPE_PSK }, + { SL_WIFI_WPA3, WIFI_SECURITY_TYPE_SAE }, + { SL_WIFI_WPA3_TRANSITION, WIFI_SECURITY_TYPE_SAE }, + { SL_WIFI_WPA_ENTERPRISE, WIFI_SECURITY_TYPE_EAP }, + { SL_WIFI_WPA2_ENTERPRISE, WIFI_SECURITY_TYPE_EAP }, + }; + + struct wifi_scan_result tmp = { + .channel = result->scan_info[item].rf_channel, + .rssi = result->scan_info[item].rssi_val, + .ssid_length = strlen(result->scan_info[item].ssid), + .mac_length = sizeof(result->scan_info[item].bssid), + .security = WIFI_SECURITY_TYPE_UNKNOWN, + .mfp = WIFI_MFP_UNKNOWN, + .band = WIFI_FREQ_BAND_2_4_GHZ, + }; + + if (result->scan_count == 0) { + return; + } + + if (result->scan_info[item].rf_channel <= 0 || result->scan_info[item].rf_channel > 14) { + LOG_WRN("Unexpected scan result"); + tmp.band = WIFI_FREQ_BAND_UNKNOWN; + } + + memcpy(tmp.ssid, result->scan_info[item].ssid, tmp.ssid_length); + memcpy(tmp.mac, result->scan_info[item].bssid, tmp.mac_length); + + ARRAY_FOR_EACH(security_convert, i) { + if (security_convert[i].sl_val == result->scan_info[item].security_mode) { + tmp.security = security_convert[i].z_val; + } + } + + sidev->scan_res_cb(sidev->iface, 0, &tmp); +} + +static unsigned int siwx91x_on_scan(sl_wifi_event_t event, sl_wifi_scan_result_t *result, + uint32_t result_size, void *arg) +{ + struct siwx91x_dev *sidev = arg; + int i, scan_count; + + if (!sidev->scan_res_cb) { + return -EFAULT; + } + + if (event & SL_WIFI_EVENT_FAIL_INDICATION) { + memset(result, 0, sizeof(*result)); + } + + if (sidev->scan_max_bss_cnt) { + scan_count = MIN(result->scan_count, sidev->scan_max_bss_cnt); + } else { + scan_count = result->scan_count; + } + + for (i = 0; i < scan_count; i++) { + siwx91x_report_scan_res(sidev, result, i); + } + + sidev->scan_res_cb(sidev->iface, 0, NULL); + sidev->state = WIFI_STATE_INACTIVE; + + return 0; +} + +static int siwx91x_scan(const struct device *dev, struct wifi_scan_params *z_scan_config, + scan_result_cb_t cb) +{ + sl_wifi_scan_configuration_t sl_scan_config = { }; + struct siwx91x_dev *sidev = dev->data; + sl_wifi_ssid_t ssid = {}; + int ret; + + __ASSERT(z_scan_config, "z_scan_config cannot be NULL"); + + if (sidev->state != WIFI_STATE_INACTIVE) { + return -EBUSY; + } + + if (z_scan_config->scan_type == WIFI_SCAN_TYPE_ACTIVE) { + sl_scan_config.type = SL_WIFI_SCAN_TYPE_ACTIVE; + if (!z_scan_config->dwell_time_active) { + ret = sl_si91x_configure_timeout(SL_SI91X_CHANNEL_ACTIVE_SCAN_TIMEOUT, + SL_WIFI_DEFAULT_ACTIVE_CHANNEL_SCAN_TIME); + } else { + ret = sl_si91x_configure_timeout(SL_SI91X_CHANNEL_ACTIVE_SCAN_TIMEOUT, + z_scan_config->dwell_time_active); + } + + if (ret) { + return -EINVAL; + } + } else { + sl_scan_config.type = SL_WIFI_SCAN_TYPE_PASSIVE; + ret = sl_si91x_configure_timeout(SL_SI91X_CHANNEL_PASSIVE_SCAN_TIMEOUT, + z_scan_config->dwell_time_passive); + if (ret) { + return -EINVAL; + } + } + + for (int i = 0; i < WIFI_MGMT_SCAN_CHAN_MAX_MANUAL; i++) { + sl_scan_config.channel_bitmap_2g4 |= BIT(z_scan_config->band_chan[i].channel - 1); + } + + memset(sl_scan_config.channel_bitmap_5g, 0xFF, sizeof(sl_scan_config.channel_bitmap_5g)); + if (IS_ENABLED(CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX)) { + if (z_scan_config->ssids[0]) { + strncpy(ssid.value, z_scan_config->ssids[0], WIFI_SSID_MAX_LEN); + ssid.length = strlen(z_scan_config->ssids[0]); + } + } + + sidev->scan_max_bss_cnt = z_scan_config->max_bss_cnt; + sidev->scan_res_cb = cb; + ret = sl_wifi_start_scan(SL_WIFI_CLIENT_2_4GHZ_INTERFACE, (ssid.length > 0) ? &ssid : NULL, + &sl_scan_config); + if (ret != SL_STATUS_IN_PROGRESS) { + return -EIO; + } + sidev->state = WIFI_STATE_SCANNING; + + return 0; +} + +static int siwx91x_status(const struct device *dev, struct wifi_iface_status *status) +{ + struct siwx91x_dev *sidev = dev->data; + int32_t rssi = -1; + + memset(status, 0, sizeof(*status)); + status->state = sidev->state; + sl_wifi_get_signal_strength(SL_WIFI_CLIENT_INTERFACE, &rssi); + status->rssi = rssi; + return 0; +} + +#ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE + +static int siwx91x_send(const struct device *dev, struct net_pkt *pkt) +{ + size_t pkt_len = net_pkt_get_len(pkt); + struct net_buf *buf = NULL; + int ret; + + if (net_pkt_get_len(pkt) > _NET_ETH_MAX_FRAME_SIZE) { + LOG_ERR("unexpected buffer size"); + return -ENOBUFS; + } + buf = net_buf_alloc(&siwx91x_tx_pool, K_FOREVER); + if (!buf) { + return -ENOBUFS; + } + if (net_pkt_read(pkt, buf->data, pkt_len)) { + net_buf_unref(buf); + return -ENOBUFS; + } + net_buf_add(buf, pkt_len); + + ret = sl_wifi_send_raw_data_frame(SL_WIFI_CLIENT_INTERFACE, buf->data, pkt_len); + if (ret) { + return -EIO; + } + + net_pkt_unref(pkt); + net_buf_unref(buf); + + return 0; +} + +/* Receive callback. Keep the name as it is declared weak in WiseConnect */ +sl_status_t sl_si91x_host_process_data_frame(sl_wifi_interface_t interface, + sl_wifi_buffer_t *buffer) +{ + sl_si91x_packet_t *si_pkt = sl_si91x_host_get_buffer_data(buffer, 0, NULL); + struct net_if *iface = net_if_get_first_wifi(); + struct net_pkt *pkt; + int ret; + + pkt = net_pkt_rx_alloc_with_buffer(iface, buffer->length, AF_UNSPEC, 0, K_NO_WAIT); + if (!pkt) { + LOG_ERR("net_pkt_rx_alloc_with_buffer() failed"); + return SL_STATUS_FAIL; + } + ret = net_pkt_write(pkt, si_pkt->data, si_pkt->length); + if (ret < 0) { + LOG_ERR("net_pkt_write(): %d", ret); + goto unref; + } + ret = net_recv_data(iface, pkt); + if (ret < 0) { + LOG_ERR("net_recv_data((): %d", ret); + goto unref; + } + return 0; + +unref: + net_pkt_unref(pkt); + return SL_STATUS_FAIL; +} + +#endif + +static void siwx91x_ethernet_init(struct net_if *iface) +{ + struct ethernet_context *eth_ctx; + + if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE)) { + eth_ctx = net_if_l2_data(iface); + eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI; + ethernet_init(iface); + } +} + +static void siwx91x_iface_init(struct net_if *iface) +{ + struct siwx91x_dev *sidev = iface->if_dev->dev->data; + sl_status_t status; + + sidev->state = WIFI_STATE_INTERFACE_DISABLED; + sidev->iface = iface; + + sl_wifi_set_scan_callback(siwx91x_on_scan, sidev); + sl_wifi_set_join_callback(siwx91x_on_join, sidev); + + status = sl_wifi_get_mac_address(SL_WIFI_CLIENT_INTERFACE, &sidev->macaddr); + if (status) { + LOG_ERR("sl_wifi_get_mac_address(): %#04x", status); + return; + } + net_if_set_link_addr(iface, sidev->macaddr.octet, sizeof(sidev->macaddr.octet), + NET_LINK_ETHERNET); + siwx91x_sock_init(iface); + siwx91x_ethernet_init(iface); + + sidev->state = WIFI_STATE_INACTIVE; +} + +static int siwx91x_dev_init(const struct device *dev) +{ + return 0; +} + +static const struct wifi_mgmt_ops siwx91x_mgmt = { + .scan = siwx91x_scan, + .connect = siwx91x_connect, + .disconnect = siwx91x_disconnect, + .iface_status = siwx91x_status, +}; + +static const struct net_wifi_mgmt_offload siwx91x_api = { + .wifi_iface.iface_api.init = siwx91x_iface_init, +#ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE + .wifi_iface.send = siwx91x_send, +#else + .wifi_iface.get_type = siwx91x_get_type, +#endif + .wifi_mgmt_api = &siwx91x_mgmt, +}; + +static struct siwx91x_dev sidev; + +#ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE +ETH_NET_DEVICE_DT_INST_DEFINE(0, siwx91x_dev_init, NULL, &sidev, NULL, + CONFIG_WIFI_INIT_PRIORITY, &siwx91x_api, NET_ETH_MTU); +#else +NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, siwx91x_dev_init, NULL, &sidev, NULL, + CONFIG_WIFI_INIT_PRIORITY, &siwx91x_api, NET_ETH_MTU); +#endif diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.h b/drivers/wifi/siwx91x/siwx91x_wifi.h new file mode 100644 index 0000000000000..30e740e280112 --- /dev/null +++ b/drivers/wifi/siwx91x/siwx91x_wifi.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef SIWX91X_WIFI_H +#define SIWX91X_WIFI_H + +#include +#include +#include +#include + +#include "sl_ieee802_types.h" +#include "sl_si91x_types.h" +#include "sl_si91x_protocol_types.h" + +struct siwx91x_dev { + struct net_if *iface; + sl_mac_address_t macaddr; + enum wifi_iface_state state; + scan_result_cb_t scan_res_cb; + uint16_t scan_max_bss_cnt; + +#ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD + struct k_event fds_recv_event; + sl_si91x_fd_set fds_watch; + struct { + net_context_recv_cb_t cb; + void *user_data; + struct net_context *context; + } fds_cb[NUMBER_OF_SOCKETS]; +#endif +}; + +#endif diff --git a/drivers/wifi/siwx91x/siwx91x_wifi_socket.c b/drivers/wifi/siwx91x/siwx91x_wifi_socket.c new file mode 100644 index 0000000000000..47440176becf5 --- /dev/null +++ b/drivers/wifi/siwx91x/siwx91x_wifi_socket.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +#include "siwx91x_wifi.h" +#include "siwx91x_wifi_socket.h" + +#include "sl_status.h" +#include "sl_net_ip_types.h" +#include "sl_net_si91x.h" +#include "sl_si91x_types.h" +#include "sl_si91x_socket.h" +#include "sl_si91x_socket_utility.h" + +LOG_MODULE_DECLARE(siwx91x_wifi); + +BUILD_ASSERT(NUMBER_OF_SOCKETS < sizeof(uint32_t) * 8); +BUILD_ASSERT(NUMBER_OF_SOCKETS < SIZEOF_FIELD(sl_si91x_fd_set, __fds_bits) * 8); + +NET_BUF_POOL_FIXED_DEFINE(siwx91x_tx_pool, 1, NET_ETH_MTU, 0, NULL); +NET_BUF_POOL_FIXED_DEFINE(siwx91x_rx_pool, 10, NET_ETH_MTU, 0, NULL); + +enum offloaded_net_if_types siwx91x_get_type(void) +{ + return L2_OFFLOADED_NET_IF_TYPE_WIFI; +} + +/* SiWx91x does not use the standard struct sockaddr (despite it uses the same + * name): + * - uses Little Endian for port number while Posix uses big endian + * - IPv6 addresses are bytes swapped + * Note: this function allows to have in == out. + */ +static void siwx91x_sockaddr_swap_bytes(struct sockaddr *out, + const struct sockaddr *in, socklen_t in_len) +{ + const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)in; + struct sockaddr_in6 *out6 = (struct sockaddr_in6 *)out; + + /* In Zephyr, size of sockaddr == size of sockaddr_storage + * (while in Posix sockaddr is smaller than sockaddr_storage). + */ + memcpy(out, in, in_len); + if (in->sa_family == AF_INET6) { + ARRAY_FOR_EACH(in6->sin6_addr.s6_addr32, i) { + out6->sin6_addr.s6_addr32[i] = ntohl(in6->sin6_addr.s6_addr32[i]); + } + out6->sin6_port = ntohs(in6->sin6_port); + } else if (in->sa_family == AF_INET) { + out6->sin6_port = ntohs(in6->sin6_port); + } +} + +void siwx91x_on_join_ipv4(struct siwx91x_dev *sidev) +{ + sl_net_ip_configuration_t ip_config4 = { + .mode = SL_IP_MANAGEMENT_DHCP, + .type = SL_IPV4, + }; + struct in_addr addr4 = { }; + int ret; + + if (!IS_ENABLED(CONFIG_NET_IPV4)) { + return; + } + /* FIXME: support for static IP configuration */ + ret = sl_si91x_configure_ip_address(&ip_config4, SL_SI91X_WIFI_CLIENT_VAP_ID); + if (!ret) { + memcpy(addr4.s4_addr, ip_config4.ip.v4.ip_address.bytes, sizeof(addr4.s4_addr)); + /* FIXME: also report gateway (net_if_ipv4_router_add()) */ + net_if_ipv4_addr_add(sidev->iface, &addr4, NET_ADDR_DHCP, 0); + } else { + LOG_ERR("sl_si91x_configure_ip_address(): %#04x", ret); + } +} + +void siwx91x_on_join_ipv6(struct siwx91x_dev *sidev) +{ + sl_net_ip_configuration_t ip_config6 = { + .mode = SL_IP_MANAGEMENT_DHCP, + .type = SL_IPV6, + }; + struct in6_addr addr6 = { }; + int ret; + + if (!IS_ENABLED(CONFIG_NET_IPV6)) { + return; + } + /* FIXME: support for static IP configuration */ + ret = sl_si91x_configure_ip_address(&ip_config6, SL_SI91X_WIFI_CLIENT_VAP_ID); + if (!ret) { + ARRAY_FOR_EACH(addr6.s6_addr32, i) { + addr6.s6_addr32[i] = ntohl(ip_config6.ip.v6.global_address.value[i]); + } + /* SiWx91x already take care of DAD and sending ND is not + * supported anyway. + */ + net_if_flag_set(sidev->iface, NET_IF_IPV6_NO_ND); + /* FIXME: also report gateway and link local address */ + net_if_ipv6_addr_add(sidev->iface, &addr6, NET_ADDR_AUTOCONF, 0); + } else { + LOG_ERR("sl_si91x_configure_ip_address(): %#04x", ret); + } +} + +static int siwx91x_sock_recv_sync(struct net_context *context, + net_context_recv_cb_t cb, void *user_data) +{ + struct net_if *iface = net_context_get_iface(context); + int sockfd = (int)context->offload_context; + struct net_pkt *pkt; + struct net_buf *buf; + int ret; + + pkt = net_pkt_rx_alloc_on_iface(iface, K_MSEC(100)); + if (!pkt) { + return -ENOBUFS; + } + buf = net_buf_alloc(&siwx91x_rx_pool, K_MSEC(100)); + if (!buf) { + net_pkt_unref(pkt); + return -ENOBUFS; + } + net_pkt_append_buffer(pkt, buf); + + ret = sl_si91x_recvfrom(sockfd, buf->data, NET_ETH_MTU, 0, NULL, NULL); + if (ret < 0) { + net_pkt_unref(pkt); + ret = -errno; + } else { + net_buf_add(buf, ret); + net_pkt_cursor_init(pkt); + ret = 0; + } + if (cb) { + cb(context, pkt, NULL, NULL, ret, user_data); + } + return ret; +} + +static void siwx91x_sock_on_recv(sl_si91x_fd_set *read_fd, sl_si91x_fd_set *write_fd, + sl_si91x_fd_set *except_fd, int status) +{ + /* When CONFIG_NET_SOCKETS_OFFLOAD is set, only one interface exist */ + struct siwx91x_dev *sidev = net_if_get_first_wifi()->if_dev->dev->data; + + ARRAY_FOR_EACH(sidev->fds_cb, i) { + if (SL_SI91X_FD_ISSET(i, read_fd)) { + if (sidev->fds_cb[i].cb) { + siwx91x_sock_recv_sync(sidev->fds_cb[i].context, + sidev->fds_cb[i].cb, + sidev->fds_cb[i].user_data); + } else { + SL_SI91X_FD_CLR(i, &sidev->fds_watch); + k_event_post(&sidev->fds_recv_event, 1U << i); + } + } + } + + sl_si91x_select(NUMBER_OF_SOCKETS, &sidev->fds_watch, NULL, NULL, NULL, + siwx91x_sock_on_recv); +} + +static int siwx91x_sock_get(sa_family_t family, enum net_sock_type type, + enum net_ip_protocol ip_proto, struct net_context **context) +{ + struct siwx91x_dev *sidev = net_if_get_first_wifi()->if_dev->dev->data; + int sockfd; + + sockfd = sl_si91x_socket(family, type, ip_proto); + if (sockfd < 0) { + return -errno; + } + assert(!sidev->fds_cb[sockfd].cb); + (*context)->offload_context = (void *)sockfd; + return sockfd; +} + +static int siwx91x_sock_put(struct net_context *context) +{ + struct siwx91x_dev *sidev = net_context_get_iface(context)->if_dev->dev->data; + int sockfd = (int)context->offload_context; + int ret; + + SL_SI91X_FD_CLR(sockfd, &sidev->fds_watch); + memset(&sidev->fds_cb[sockfd], 0, sizeof(sidev->fds_cb[sockfd])); + sl_si91x_select(NUMBER_OF_SOCKETS, &sidev->fds_watch, NULL, NULL, NULL, + siwx91x_sock_on_recv); + ret = sl_si91x_shutdown(sockfd, 0); + if (ret < 0) { + ret = -errno; + } + return ret; +} + +static int siwx91x_sock_bind(struct net_context *context, + const struct sockaddr *addr, socklen_t addrlen) +{ + struct siwx91x_dev *sidev = net_context_get_iface(context)->if_dev->dev->data; + int sockfd = (int)context->offload_context; + struct sockaddr addr_le; + int ret; + + /* Zephyr tends to call bind() even if the TCP socket is a client. 917 + * return an error in this case. + */ + if (net_context_get_proto(context) == IPPROTO_TCP && + !((struct sockaddr_in *)addr)->sin_port) { + return 0; + } + siwx91x_sockaddr_swap_bytes(&addr_le, addr, addrlen); + ret = sl_si91x_bind(sockfd, &addr_le, addrlen); + if (ret) { + return -errno; + } + /* WiseConnect refuses to run select on TCP listening sockets */ + if (net_context_get_proto(context) == IPPROTO_UDP) { + SL_SI91X_FD_SET(sockfd, &sidev->fds_watch); + sl_si91x_select(NUMBER_OF_SOCKETS, &sidev->fds_watch, NULL, NULL, NULL, + siwx91x_sock_on_recv); + } + return 0; +} + +static int siwx91x_sock_connect(struct net_context *context, + const struct sockaddr *addr, socklen_t addrlen, + net_context_connect_cb_t cb, int32_t timeout, void *user_data) +{ + struct siwx91x_dev *sidev = net_context_get_iface(context)->if_dev->dev->data; + int sockfd = (int)context->offload_context; + struct sockaddr addr_le; + int ret; + + /* sl_si91x_connect() always return immediately, so we ignore timeout */ + siwx91x_sockaddr_swap_bytes(&addr_le, addr, addrlen); + ret = sl_si91x_connect(sockfd, &addr_le, addrlen); + if (ret) { + ret = -errno; + } + SL_SI91X_FD_SET(sockfd, &sidev->fds_watch); + sl_si91x_select(NUMBER_OF_SOCKETS, &sidev->fds_watch, NULL, NULL, NULL, + siwx91x_sock_on_recv); + net_context_set_state(context, NET_CONTEXT_CONNECTED); + if (cb) { + cb(context, ret, user_data); + } + return ret; +} + +static int siwx91x_sock_listen(struct net_context *context, int backlog) +{ + int sockfd = (int)context->offload_context; + int ret; + + ret = sl_si91x_listen(sockfd, backlog); + if (ret) { + return -errno; + } + net_context_set_state(context, NET_CONTEXT_LISTENING); + return 0; +} + +static int siwx91x_sock_accept(struct net_context *context, + net_tcp_accept_cb_t cb, int32_t timeout, void *user_data) +{ + struct siwx91x_dev *sidev = net_context_get_iface(context)->if_dev->dev->data; + int sockfd = (int)context->offload_context; + struct net_context *newcontext; + struct sockaddr addr_le; + int ret; + + /* TODO: support timeout != K_FOREVER */ + assert(timeout < 0); + + ret = net_context_get(net_context_get_family(context), + net_context_get_type(context), + net_context_get_proto(context), &newcontext); + if (ret < 0) { + return ret; + } + /* net_context_get() calls siwx91x_sock_get() but sl_si91x_accept() also + * allocates a socket. + */ + ret = siwx91x_sock_put(newcontext); + if (ret < 0) { + return ret; + } + /* The iface is reset when getting a new context. */ + newcontext->iface = context->iface; + ret = sl_si91x_accept(sockfd, &addr_le, sizeof(addr_le)); + if (ret < 0) { + return -errno; + } + newcontext->flags |= NET_CONTEXT_REMOTE_ADDR_SET; + newcontext->offload_context = (void *)ret; + siwx91x_sockaddr_swap_bytes(&newcontext->remote, &addr_le, sizeof(addr_le)); + + SL_SI91X_FD_SET(ret, &sidev->fds_watch); + sl_si91x_select(NUMBER_OF_SOCKETS, &sidev->fds_watch, NULL, NULL, NULL, + siwx91x_sock_on_recv); + if (cb) { + cb(newcontext, &addr_le, sizeof(addr_le), 0, user_data); + } + + return 0; +} + +static int siwx91x_sock_sendto(struct net_pkt *pkt, + const struct sockaddr *addr, socklen_t addrlen, + net_context_send_cb_t cb, int32_t timeout, void *user_data) +{ + struct net_context *context = pkt->context; + int sockfd = (int)context->offload_context; + struct sockaddr addr_le; + struct net_buf *buf; + int ret; + + /* struct net_pkt use fragmented buffers while SiWx91x API need a + * continuous buffer. + */ + if (net_pkt_get_len(pkt) > NET_ETH_MTU) { + LOG_ERR("unexpected buffer size"); + ret = -ENOBUFS; + goto out_cb; + } + buf = net_buf_alloc(&siwx91x_tx_pool, K_FOREVER); + if (!buf) { + ret = -ENOBUFS; + goto out_cb; + } + if (net_pkt_read(pkt, buf->data, net_pkt_get_len(pkt))) { + ret = -ENOBUFS; + goto out_release_buf; + } + net_buf_add(buf, net_pkt_get_len(pkt)); + + /* sl_si91x_sendto() always return immediately, so we ignore timeout */ + siwx91x_sockaddr_swap_bytes(&addr_le, addr, addrlen); + ret = sl_si91x_sendto(sockfd, buf->data, net_pkt_get_len(pkt), 0, &addr_le, addrlen); + if (ret < 0) { + ret = -errno; + goto out_release_buf; + } + net_pkt_unref(pkt); + +out_release_buf: + net_buf_unref(buf); + +out_cb: + if (cb) { + cb(pkt->context, ret, user_data); + } + return ret; +} + +static int siwx91x_sock_send(struct net_pkt *pkt, + net_context_send_cb_t cb, int32_t timeout, void *user_data) +{ + return siwx91x_sock_sendto(pkt, NULL, 0, cb, timeout, user_data); +} + +static int siwx91x_sock_recv(struct net_context *context, + net_context_recv_cb_t cb, int32_t timeout, void *user_data) +{ + struct net_if *iface = net_context_get_iface(context); + struct siwx91x_dev *sidev = iface->if_dev->dev->data; + int sockfd = (int)context->offload_context; + int ret; + + ret = k_event_wait(&sidev->fds_recv_event, 1U << sockfd, false, + timeout < 0 ? K_FOREVER : K_MSEC(timeout)); + if (timeout == 0) { + sidev->fds_cb[sockfd].context = context; + sidev->fds_cb[sockfd].cb = cb; + sidev->fds_cb[sockfd].user_data = user_data; + } else { + memset(&sidev->fds_cb[sockfd], 0, sizeof(sidev->fds_cb[sockfd])); + } + + if (ret) { + k_event_clear(&sidev->fds_recv_event, 1U << sockfd); + ret = siwx91x_sock_recv_sync(context, cb, user_data); + SL_SI91X_FD_SET(sockfd, &sidev->fds_watch); + } + + sl_si91x_select(NUMBER_OF_SOCKETS, &sidev->fds_watch, NULL, NULL, NULL, + siwx91x_sock_on_recv); + return ret; +} + +static struct net_offload siwx91x_offload = { + .get = siwx91x_sock_get, + .put = siwx91x_sock_put, + .bind = siwx91x_sock_bind, + .listen = siwx91x_sock_listen, + .connect = siwx91x_sock_connect, + .accept = siwx91x_sock_accept, + .sendto = siwx91x_sock_sendto, + .send = siwx91x_sock_send, + .recv = siwx91x_sock_recv, +}; + +void siwx91x_sock_init(struct net_if *iface) +{ + struct siwx91x_dev *sidev = iface->if_dev->dev->data; + + iface->if_dev->offload = &siwx91x_offload; + k_event_init(&sidev->fds_recv_event); +} diff --git a/drivers/wifi/siwx91x/siwx91x_wifi_socket.h b/drivers/wifi/siwx91x/siwx91x_wifi_socket.h new file mode 100644 index 0000000000000..6ae06aaee4eb3 --- /dev/null +++ b/drivers/wifi/siwx91x/siwx91x_wifi_socket.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef SIWX91X_WIFI_SOCKET_H +#define SIWX91X_WIFI_SOCKET_H + +#include +#include +#include + +struct siwx91x_dev; + +#ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD + +enum offloaded_net_if_types siwx91x_get_type(void); +void siwx91x_on_join_ipv4(struct siwx91x_dev *sidev); +void siwx91x_on_join_ipv6(struct siwx91x_dev *sidev); +void siwx91x_sock_init(struct net_if *iface); + +#else /* CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD */ + +enum offloaded_net_if_types siwx91x_get_type(void) +{ + assert(0); +} + +void siwx91x_on_join_ipv4(struct siwx91x_dev *sidev) +{ +} + +void siwx91x_on_join_ipv6(struct siwx91x_dev *sidev) +{ +} + +void siwx91x_sock_init(struct net_if *iface) +{ +} + +#endif /* CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD */ + +#endif diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index 8ef41f71215eb..b0788a04c5605 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -42,16 +42,16 @@ typedef void (*tpfAppSocketCb) (SOCKET sock, uint8 u8Msg, void *pvMsg); typedef void (*tpfAppResolveCb) (uint8 *pu8DomainName, uint32 u32ServerIP); NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb resolve_cb); -NMI_API SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Flags); -NMI_API sint8 bind(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen); -NMI_API sint8 listen(SOCKET sock, uint8 backlog); -NMI_API sint8 accept(SOCKET sock, struct sockaddr *addr, uint8 *addrlen); -NMI_API sint8 connect(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen); -NMI_API sint16 recv(SOCKET sock, void *pvRecvBuf, +NMI_API SOCKET winc1500_socket(uint16 u16Domain, uint8 u8Type, uint8 u8Flags); +NMI_API sint8 winc1500_socket_bind(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen); +NMI_API sint8 winc1500_socket_listen(SOCKET sock, uint8 backlog); +NMI_API sint8 winc1500_socket_accept(SOCKET sock, struct sockaddr *addr, uint8 *addrlen); +NMI_API sint8 winc1500_socket_connect(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen); +NMI_API sint16 winc1500_socket_recv(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32Timeoutmsec); -NMI_API sint16 send(SOCKET sock, void *pvSendBuffer, +NMI_API sint16 winc1500_socket_send(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 u16Flags); -NMI_API sint16 sendto(SOCKET sock, void *pvSendBuffer, +NMI_API sint16 winc1500_socket_sendto(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 flags, struct sockaddr *pstrDestAddr, uint8 u8AddrLen); NMI_API sint8 winc1500_close(SOCKET sock); @@ -306,7 +306,7 @@ static int winc1500_get(sa_family_t family, * we have checked if family is AF_INET so we can hardcode this * for now. */ - sock = socket(2, type, 0); + sock = winc1500_socket(2, type, 0); if (sock < 0) { LOG_ERR("socket error!"); return -1; @@ -337,7 +337,8 @@ static int winc1500_bind(struct net_context *context, return 0; } - ret = bind((intptr_t)context->offload_context, (struct sockaddr *)addr, addrlen); + ret = winc1500_socket_bind((intptr_t)context->offload_context, (struct sockaddr *)addr, + addrlen); if (ret) { LOG_ERR("bind error %d %s!", ret, socket_message_to_string(ret)); @@ -362,7 +363,7 @@ static int winc1500_listen(struct net_context *context, int backlog) SOCKET socket = (intptr_t)context->offload_context; int ret; - ret = listen((intptr_t)context->offload_context, backlog); + ret = winc1500_socket_listen((intptr_t)context->offload_context, backlog); if (ret) { LOG_ERR("listen error %d %s!", ret, socket_error_string(ret)); @@ -395,7 +396,7 @@ static int winc1500_connect(struct net_context *context, w1500_data.socket_data[socket].connect_user_data = user_data; w1500_data.socket_data[socket].ret_code = 0; - ret = connect(socket, (struct sockaddr *)addr, addrlen); + ret = winc1500_socket_connect(socket, (struct sockaddr *)addr, addrlen); if (ret) { LOG_ERR("connect error %d %s!", ret, socket_error_string(ret)); @@ -425,7 +426,7 @@ static int winc1500_accept(struct net_context *context, w1500_data.socket_data[socket].accept_cb = cb; w1500_data.socket_data[socket].accept_user_data = user_data; - ret = accept(socket, NULL, 0); + ret = winc1500_socket_accept(socket, NULL, 0); if (ret) { LOG_ERR("accept error %d %s!", ret, socket_error_string(ret)); @@ -467,7 +468,7 @@ static int winc1500_send(struct net_pkt *pkt, net_buf_add(buf, net_pkt_get_len(pkt)); - ret = send(socket, buf->data, buf->len, 0); + ret = winc1500_socket_send(socket, buf->data, buf->len, 0); if (ret) { LOG_ERR("send error %d %s!", ret, socket_error_string(ret)); goto out; @@ -507,7 +508,7 @@ static int winc1500_sendto(struct net_pkt *pkt, net_buf_add(buf, net_pkt_get_len(pkt)); - ret = sendto(socket, buf->data, buf->len, 0, + ret = winc1500_socket_sendto(socket, buf->data, buf->len, 0, (struct sockaddr *)dst_addr, addrlen); if (ret) { LOG_ERR("sendto error %d %s!", ret, socket_error_string(ret)); @@ -571,7 +572,7 @@ static int winc1500_recv(struct net_context *context, } - ret = recv(socket, w1500_data.socket_data[socket].pkt_buf->data, + ret = winc1500_socket_recv(socket, w1500_data.socket_data[socket].pkt_buf->data, CONFIG_WIFI_WINC1500_MAX_PACKET_SIZE, timeout); if (ret) { LOG_ERR("recv error %d %s!", @@ -682,7 +683,7 @@ static void reset_scan_data(void) static void handle_scan_result(void *pvMsg) { tstrM2mWifiscanResult *pstrScanResult = (tstrM2mWifiscanResult *)pvMsg; - struct wifi_scan_result result; + struct wifi_scan_result result = { 0 }; if (!w1500_data.scan_cb) { return; @@ -816,6 +817,8 @@ static bool handle_socket_msg_recv(SOCKET sock, } } else if (pstrRx->pu8Buffer == NULL) { if (pstrRx->s16BufferSize == SOCK_ERR_CONN_ABORTED) { + winc1500_close(sock); + net_pkt_unref(sd->rx_pkt); return false; } @@ -904,6 +907,8 @@ static void handle_socket_msg_accept(struct socket_data *sd, void *pvMsg) /** The iface is reset when getting a new context. */ a_sd->context->iface = sd->context->iface; + net_context_set_state(a_sd->context, NET_CONTEXT_CONNECTED); + /** Setup remote */ a_sd->context->remote.sa_family = AF_INET; net_sin(&a_sd->context->remote)->sin_port = @@ -1066,7 +1071,8 @@ static int winc1500_mgmt_ap_enable(const struct device *dev, tstrM2MAPConfig strM2MAPConfig; memset(&strM2MAPConfig, 0x00, sizeof(tstrM2MAPConfig)); - strcpy((char *)&strM2MAPConfig.au8SSID, params->ssid); + strncpy((char *)&strM2MAPConfig.au8SSID, params->ssid, + params->ssid_length); strM2MAPConfig.u8ListenChannel = params->channel; /** security is hardcoded as open for now */ strM2MAPConfig.u8SecType = M2M_WIFI_SEC_OPEN; diff --git a/drivers/wifi/winc1500/wifi_winc1500_nm_bsp.c b/drivers/wifi/winc1500/wifi_winc1500_nm_bsp.c index 4872ddab7cf01..94f118e747ab6 100644 --- a/drivers/wifi/winc1500/wifi_winc1500_nm_bsp.c +++ b/drivers/wifi/winc1500/wifi_winc1500_nm_bsp.c @@ -52,13 +52,13 @@ int8_t nm_bsp_deinit(void) void nm_bsp_reset(void) { gpio_pin_set_dt(&winc1500_config.chip_en_gpio, 0); - gpio_pin_set_dt(&winc1500_config.reset_gpio, 0); + gpio_pin_set_dt(&winc1500_config.reset_gpio, 1); nm_bsp_sleep(100); gpio_pin_set_dt(&winc1500_config.chip_en_gpio, 1); nm_bsp_sleep(10); - gpio_pin_set_dt(&winc1500_config.reset_gpio, 1); + gpio_pin_set_dt(&winc1500_config.reset_gpio, 0); nm_bsp_sleep(10); } diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 361c71a3538d0..99ad113887b12 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -1,5 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2022-2023 EPAM Systems +# Copyright (c) 2022-2024 EPAM Systems if XEN @@ -20,6 +20,15 @@ config XEN_GRANT_TABLE_INIT_PRIORITY depends on XEN_GRANT_TABLE default 50 +config NR_GRANT_FRAMES + int "Number of grant frames mapped to Zephyr" + depends on XEN_GRANT_TABLE + default 1 + help + This value configures how much grant frames will be supported by Zephyr + grant table driver in runtime. This value should be <= max_grant_frames + configured for domain in Xen hypervisor. + endmenu endif # XEN diff --git a/drivers/xen/gnttab.c b/drivers/xen/gnttab.c index 8ceb97e2db125..ccf1b888e17a6 100644 --- a/drivers/xen/gnttab.c +++ b/drivers/xen/gnttab.c @@ -2,7 +2,7 @@ /* **************************************************************************** * (C) 2006 - Cambridge University - * (C) 2021-2022 - EPAM Systems + * (C) 2021-2024 - EPAM Systems **************************************************************************** * * File: gnttab.c @@ -35,16 +35,13 @@ LOG_MODULE_REGISTER(xen_gnttab); /* Timeout for grant table ops retrying */ #define GOP_RETRY_DELAY 200 -#define GNTTAB_SIZE DT_REG_SIZE_BY_IDX(DT_INST(0, xen_xen), 0) -BUILD_ASSERT(!(GNTTAB_SIZE % XEN_PAGE_SIZE), "Size of gnttab have to be aligned on XEN_PAGE_SIZE"); - -/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */ -#define NR_GRANT_FRAMES (GNTTAB_SIZE / XEN_PAGE_SIZE) -#define NR_GRANT_ENTRIES \ - (NR_GRANT_FRAMES * XEN_PAGE_SIZE / sizeof(grant_entry_v1_t)) +#define GNTTAB_GREF_USED (UINT32_MAX - 1) +#define GNTTAB_SIZE (CONFIG_NR_GRANT_FRAMES * XEN_PAGE_SIZE) +#define NR_GRANT_ENTRIES (GNTTAB_SIZE / sizeof(grant_entry_v1_t)) +BUILD_ASSERT(GNTTAB_SIZE <= DT_REG_SIZE_BY_IDX(DT_INST(0, xen_xen), 0), + "Number of grant frames is bigger than grant table DT region!"); BUILD_ASSERT(GNTTAB_SIZE <= CONFIG_KERNEL_VM_SIZE); -DEVICE_MMIO_TOPLEVEL_STATIC(grant_tables, DT_INST(0, xen_xen)); static struct gnttab { struct k_sem sem; @@ -64,6 +61,7 @@ static grant_ref_t get_free_entry(void) __ASSERT((gref >= GNTTAB_NR_RESERVED_ENTRIES && gref < NR_GRANT_ENTRIES), "Invalid gref = %d", gref); gnttab.gref_list[0] = gnttab.gref_list[gref]; + gnttab.gref_list[gref] = GNTTAB_GREF_USED; irq_unlock(flags); return gref; @@ -74,6 +72,12 @@ static void put_free_entry(grant_ref_t gref) unsigned int flags; flags = irq_lock(); + if (gnttab.gref_list[gref] != GNTTAB_GREF_USED) { + LOG_WRN("Trying to put already free gref = %u", gref); + + return; + } + gnttab.gref_list[gref] = gnttab.gref_list[0]; gnttab.gref_list[0] = gref; @@ -277,7 +281,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, unsigned int count) return 0; } -int gnttab_unmap_refs(struct gnttab_map_grant_ref *unmap_ops, unsigned int count) +int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, unsigned int count) { return HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); } @@ -295,44 +299,68 @@ const char *gnttabop_error(int16_t status) } } +/* Picked from Linux implementation */ +#define LEGACY_MAX_GNT_FRAMES_SUPPORTED 4 +static unsigned long gnttab_get_max_frames(void) +{ + int ret; + struct gnttab_query_size q = { + .dom = DOMID_SELF, + }; + + ret = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &q, 1); + if ((ret < 0) || (q.status != GNTST_okay)) { + return LEGACY_MAX_GNT_FRAMES_SUPPORTED; + } + + return q.max_nr_frames; +} + static int gnttab_init(void) { grant_ref_t gref; struct xen_add_to_physmap xatp; - struct gnttab_setup_table setup; - xen_pfn_t frames[NR_GRANT_FRAMES]; int rc = 0, i; + unsigned long xen_max_grant_frames; + uintptr_t gnttab_base = DT_REG_ADDR_BY_IDX(DT_INST(0, xen_xen), 0); + mm_reg_t gnttab_reg; + + xen_max_grant_frames = gnttab_get_max_frames(); + if (xen_max_grant_frames < CONFIG_NR_GRANT_FRAMES) { + LOG_ERR("Xen max_grant_frames is less than CONFIG_NR_GRANT_FRAMES!"); + k_panic(); + } /* Will be taken/given during gnt_refs allocation/release */ - k_sem_init(&gnttab.sem, 0, NR_GRANT_ENTRIES - GNTTAB_NR_RESERVED_ENTRIES); - - for ( - gref = GNTTAB_NR_RESERVED_ENTRIES; - gref < NR_GRANT_ENTRIES; - gref++ - ) { - put_free_entry(gref); + k_sem_init(&gnttab.sem, NR_GRANT_ENTRIES - GNTTAB_NR_RESERVED_ENTRIES, + NR_GRANT_ENTRIES - GNTTAB_NR_RESERVED_ENTRIES); + + /* Initialize O(1) allocator, gnttab.gref_list[0] always shows first free entry */ + gnttab.gref_list[0] = GNTTAB_NR_RESERVED_ENTRIES; + gnttab.gref_list[NR_GRANT_ENTRIES - 1] = 0; + for (gref = GNTTAB_NR_RESERVED_ENTRIES; gref < NR_GRANT_ENTRIES - 1; gref++) { + gnttab.gref_list[gref] = gref + 1; } - for (i = 0; i < NR_GRANT_FRAMES; i++) { + for (i = CONFIG_NR_GRANT_FRAMES - 1; i >= 0; i--) { xatp.domid = DOMID_SELF; xatp.size = 0; xatp.space = XENMAPSPACE_grant_table; xatp.idx = i; - xatp.gpfn = xen_virt_to_gfn(Z_TOPLEVEL_ROM_NAME(grant_tables).phys_addr) + i; + xatp.gpfn = xen_virt_to_gfn(gnttab_base) + i; rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp); __ASSERT(!rc, "add_to_physmap failed; status = %d\n", rc); } - setup.dom = DOMID_SELF; - setup.nr_frames = NR_GRANT_FRAMES; - set_xen_guest_handle(setup.frame_list, frames); - rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1); - __ASSERT((!rc) && (!setup.status), "Table setup failed; status = %s\n", - gnttabop_error(setup.status)); - - DEVICE_MMIO_TOPLEVEL_MAP(grant_tables, K_MEM_CACHE_WB | K_MEM_PERM_RW); - gnttab.table = (grant_entry_v1_t *)DEVICE_MMIO_TOPLEVEL_GET(grant_tables); + /* + * Xen DT region reserved for grant table (first reg in hypervisor node) + * may be much bigger than CONFIG_NR_GRANT_FRAMES multiplied by page size. + * Thus, we need to map only part of region, that is limited by config. + * The size of this part is calculated in GNTTAB_SIZE macro and used as + * parameter for device_map() + */ + device_map(&gnttab_reg, gnttab_base, GNTTAB_SIZE, K_MEM_CACHE_WB | K_MEM_PERM_RW); + gnttab.table = (grant_entry_v1_t *)gnttab_reg; LOG_DBG("%s: grant table mapped\n", __func__); diff --git a/dts/arc/synopsys/arc_hs4xd.dtsi b/dts/arc/synopsys/arc_hs4xd.dtsi index d6650e651a956..c39c754e32c92 100644 --- a/dts/arc/synopsys/arc_hs4xd.dtsi +++ b/dts/arc/synopsys/arc_hs4xd.dtsi @@ -135,9 +135,9 @@ compatible = "snps,creg-gpio"; reg = <0xf00014b0 0x4>; ngpios = <12>; - bit_per_gpio = <2>; - off_val = <0>; - on_val = <2>; + bit-per-gpio = <2>; + off-val = <0>; + on-val = <2>; gpio-controller; #gpio-cells = <2>; diff --git a/dts/arc/synopsys/arc_hsdk.dtsi b/dts/arc/synopsys/arc_hsdk.dtsi index 6388db825a016..4168df99db85d 100644 --- a/dts/arc/synopsys/arc_hsdk.dtsi +++ b/dts/arc/synopsys/arc_hsdk.dtsi @@ -135,9 +135,9 @@ compatible = "snps,creg-gpio"; reg = <0xf00014b0 0x4>; ngpios = <12>; - bit_per_gpio = <2>; - off_val = <0>; - on_val = <2>; + bit-per-gpio = <2>; + off-val = <0>; + on-val = <2>; gpio-controller; #gpio-cells = <2>; diff --git a/dts/arm/adi/max32/max32650-pinctrl.dtsi b/dts/arm/adi/max32/max32650-pinctrl.dtsi new file mode 100644 index 0000000000000..eaf39132953a2 --- /dev/null +++ b/dts/arm/adi/max32/max32650-pinctrl.dtsi @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + pinctrl: pin-controller@40008000 { + /omit-if-no-ref/ spixr_sdio0_p0_1: spixr_sdio0_p0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sdio2_p0_2: spixr_sdio2_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sck_p0_3: spixr_sck_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sdio3_p0_4: spixr_sdio3_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sdio1_p0_5: spixr_sdio1_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_ss0_p0_6: spixr_ss0_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_ss0_p0_7: spixf_ss0_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sck_p0_8: spixf_sck_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sdio1_p0_9: spixf_sdio1_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sdio0_p0_10: spixf_sdio0_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sdio2_p0_11: spixf_sdio2_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sdio3_p0_12: spixf_sdio3_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_ss1_p0_13: spi3_ss1_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_g0_p0_13: clcd_g0_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_ss2_p0_14: spi3_ss2_p0_14 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_g1_p0_14: clcd_g1_p0_14 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_sdio3_p0_15: spi3_sdio3_p0_15 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_g2_p0_15: clcd_g2_p0_15 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_sck_p0_16: spi3_sck_p0_16 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_g3_p0_16: clcd_g3_p0_16 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_sdio2_p0_17: spi3_sdio2_p0_17 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_g4_p0_17: clcd_g4_p0_17 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_ss3_p0_18: spi3_ss3_p0_18 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_g5_p0_18: clcd_g5_p0_18 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_ss0_p0_19: spi3_ss0_p0_19 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_g6_p0_19: clcd_g6_p0_19 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_sdio1_p0_20: spi3_sdio1_p0_20 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_g7_p0_20: clcd_g7_p0_20 { + pinmux = ; + }; + + /omit-if-no-ref/ spi3_sdio0_p0_21: spi3_sdio0_p0_21 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_ss0_p0_22: spi0_ss0_p0_22 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_vden_p0_22: clcd_vden_p0_22 { + pinmux = ; + }; + + /omit-if-no-ref/ pt15_p0_23: pt15_p0_23 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_clk_p0_23: clcd_clk_p0_23 { + pinmux = ; + }; + + /omit-if-no-ref/ rxev_p0_24: rxev_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_hsync_p0_24: clcd_hsync_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ txev_p0_25: txev_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b0_p0_25: clcd_b0_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ tdi_p0_26: tdi_p0_26 { + pinmux = ; + }; + + /omit-if-no-ref/ tdo_p0_27: tdo_p0_27 { + pinmux = ; + }; + + /omit-if-no-ref/ tms_p0_28: tms_p0_28 { + pinmux = ; + }; + + /omit-if-no-ref/ tck_p0_29: tck_p0_29 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b0_p0_30: clcd_b0_p0_30 { + pinmux = ; + }; + + /omit-if-no-ref/ kcal32_p0_31: kcal32_p0_31 { + pinmux = ; + }; + + /omit-if-no-ref/ sdhc_cdn_p0_31: sdhc_cdn_p0_31 { + pinmux = ; + }; + + /omit-if-no-ref/ sdhc_cmd_p1_0: sdhc_cmd_p1_0 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sdio3_p1_0: spixf_sdio3_p1_0 { + pinmux = ; + }; + + /omit-if-no-ref/ sdhc_dat2_p1_1: sdhc_dat2_p1_1 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sdio1_p1_1: spixf_sdio1_p1_1 { + pinmux = ; + }; + + /omit-if-no-ref/ sdhc_wp_p1_2: sdhc_wp_p1_2 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_ss0_p1_2: spixf_ss0_p1_2 { + pinmux = ; + }; + + /omit-if-no-ref/ sdhc_dat3_p1_3: sdhc_dat3_p1_3 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_clk_p1_3: clcd_clk_p1_3 { + pinmux = ; + }; + + /omit-if-no-ref/ sdhc_dat0_p1_4: sdhc_dat0_p1_4 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sdio0_p1_4: spixf_sdio0_p1_4 { + pinmux = ; + }; + + /omit-if-no-ref/ sdhc_clk_p1_5: sdhc_clk_p1_5 { + pinmux = ; + }; + + /omit-if-no-ref/ spixf_sck_p1_5: spixf_sck_p1_5 { + pinmux = ; + }; + + /omit-if-no-ref/ sdhc_dat1_p1_6: sdhc_dat1_p1_6 { + pinmux = ; + }; + + /omit-if-no-ref/ pt0_p1_6: pt0_p1_6 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2_cts_p1_7: uart2_cts_p1_7 { + pinmux = ; + }; + + /omit-if-no-ref/ pt1_p1_7: pt1_p1_7 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2_rts_p1_8: uart2_rts_p1_8 { + pinmux = ; + }; + + /omit-if-no-ref/ pt2_p1_8: pt2_p1_8 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2_rx_p1_9: uart2_rx_p1_9 { + pinmux = ; + }; + + /omit-if-no-ref/ pt3_p1_9: pt3_p1_9 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2_tx_p1_10: uart2_tx_p1_10 { + pinmux = ; + }; + + /omit-if-no-ref/ pt4_p1_10: pt4_p1_10 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_cs0_p1_11: hyp_cs0_p1_11 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sdio_p1_11: spixr_sdio_p1_11 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_d0_p1_12: hyp_d0_p1_12 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sdio1_p1_12: spixr_sdio1_p1_12 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_d4_p1_13: hyp_d4_p1_13 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_ss0_p1_13: spixr_ss0_p1_13 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_rwds_p1_14: hyp_rwds_p1_14 { + pinmux = ; + }; + + /omit-if-no-ref/ pt5_p1_14: pt5_p1_14 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_d1_p1_15: hyp_d1_p1_15 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sdio2_p1_15: spixr_sdio2_p1_15 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_d5_p1_16: hyp_d5_p1_16 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sck_p1_16: spixr_sck_p1_16 { + pinmux = ; + }; + + /omit-if-no-ref/ pt9_p1_17: pt9_p1_17 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_d6_p1_18: hyp_d6_p1_18 { + pinmux = ; + }; + + /omit-if-no-ref/ pt6_p1_18: pt6_p1_18 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_d2_p1_19: hyp_d2_p1_19 { + pinmux = ; + }; + + /omit-if-no-ref/ pt7_p1_19: pt7_p1_19 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_d3_p1_20: hyp_d3_p1_20 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_hsync_p1_20: clcd_hsync_p1_20 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_d7_p1_21: hyp_d7_p1_21 { + pinmux = ; + }; + + /omit-if-no-ref/ pt8_p1_21: pt8_p1_21 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss0_p1_23: spi1_ss0_p1_23 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b1_p1_23: clcd_b1_p1_23 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss2_p1_24: spi1_ss2_p1_24 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b2_p1_24: clcd_b2_p1_24 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss1_p1_25: spi1_ss1_p1_25 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b3_p1_25: clcd_b3_p1_25 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sck_p1_26: spi1_sck_p1_26 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b4_p1_26: clcd_b4_p1_26 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss3_p1_27: spi1_ss3_p1_27 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b5_p1_27: clcd_b5_p1_27 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_miso_p1_28: spi1_miso_p1_28 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b6_p1_28: clcd_b6_p1_28 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_mosi_p1_29: spi1_mosi_p1_29 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_b7_p1_29: clcd_b7_p1_29 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_pupen_p1_30: owm_pupen_p1_30 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_r0_p1_30: clcd_r0_p1_30 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_io_p1_31: owm_io_p1_31 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_r1_p1_31: clcd_r1_p1_31 { + pinmux = ; + }; + + /omit-if-no-ref/ spi2_ss2_p2_0: spi2_ss2_p2_0 { + pinmux = ; + }; + + /omit-if-no-ref/ pt9_p2_0: pt9_p2_0 { + pinmux = ; + }; + + /omit-if-no-ref/ spi2_ss1_p2_1: spi2_ss1_p2_1 { + pinmux = ; + }; + + /omit-if-no-ref/ pt10_p2_1: pt10_p2_1 { + pinmux = ; + }; + + /omit-if-no-ref/ spi2_sck_p2_2: spi2_sck_p2_2 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_lend_p2_2: clcd_lend_p2_2 { + pinmux = ; + }; + + /omit-if-no-ref/ spi2_miso_p2_3: spi2_miso_p2_3 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_pwren_p2_3: clcd_pwren_p2_3 { + pinmux = ; + }; + + /omit-if-no-ref/ spi2_mosi_p2_4: spi2_mosi_p2_4 { + pinmux = ; + }; + + /omit-if-no-ref/ spi2_ss0_p2_5: spi2_ss0_p2_5 { + pinmux = ; + }; + + /omit-if-no-ref/ pt11_p2_5: pt11_p2_5 { + pinmux = ; + }; + + /omit-if-no-ref/ spi2_ss3_p2_6: spi2_ss3_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_vsync_p2_6: clcd_vsync_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0_sda_p2_7: i2c0_sda_p2_7 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0_scl_p2_8: i2c0_scl_p2_8 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_cts_p2_9: uart0_cts_p2_9 { + pinmux = ; + }; + + /omit-if-no-ref/ pt12_p2_9: pt12_p2_9 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_rts_p2_10: uart0_rts_p2_10 { + pinmux = ; + }; + + /omit-if-no-ref/ pt14_p2_10: pt14_p2_10 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_rx_p2_11: uart0_rx_p2_11 { + pinmux = ; + }; + + /omit-if-no-ref/ pt13_p2_11: pt13_p2_11 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_tx_p2_12: uart0_tx_p2_12 { + pinmux = ; + }; + + /omit-if-no-ref/ pt15_p2_12: pt15_p2_12 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_cts_p2_13: uart1_cts_p2_13 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_r2_p2_13: clcd_r2_p2_13 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rx_p2_14: uart1_rx_p2_14 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_r3_p2_14: clcd_r3_p2_14 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rts_p2_15: uart1_rts_p2_15 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_r4_p2_15: clcd_r4_p2_15 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_tx_p2_16: uart1_tx_p2_16 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_r5_p2_16: clcd_r5_p2_16 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1_sda_p2_17: i2c1_sda_p2_17 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_r6_p2_17: clcd_r6_p2_17 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1_scl_p2_18: i2c1_scl_p2_18 { + pinmux = ; + }; + + /omit-if-no-ref/ clcd_r7_p2_18: clcd_r7_p2_18 { + pinmux = ; + }; + + /omit-if-no-ref/ pt6_p2_23: pt6_p2_23 { + pinmux = ; + }; + + /omit-if-no-ref/ spixr_sdio3_p2_23: spixr_sdio3_p2_23 { + pinmux = ; + }; + + /omit-if-no-ref/ pt11_p2_25: pt11_p2_25 { + pinmux = ; + }; + + /omit-if-no-ref/ pt12_p2_26: pt12_p2_26 { + pinmux = ; + }; + + /omit-if-no-ref/ pt14_p2_28: pt14_p2_28 { + pinmux = ; + }; + + /omit-if-no-ref/ pt1_p2_30: pt1_p2_30 { + pinmux = ; + }; + + /omit-if-no-ref/ pdown_p3_0: pdown_p3_0 { + pinmux = ; + }; + + /omit-if-no-ref/ hyp_cs1_p3_0: hyp_cs1_p3_0 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_miso_p3_1: spi0_miso_p3_1 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_mosi_p3_2: spi0_mosi_p3_2 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_sck_p3_3: spi0_sck_p3_3 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0_p3_4: tmr0_p3_4 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2_p3_5: tmr2_p3_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr4_p3_6: tmr4_p3_6 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1_p3_7: tmr1_p3_7 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3_p3_8: tmr3_p3_8 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr5_p3_9: tmr5_p3_9 { + pinmux = ; + }; + }; + }; +}; diff --git a/dts/arm/adi/max32/max32650.dtsi b/dts/arm/adi/max32/max32650.dtsi new file mode 100644 index 0000000000000..e2447636d1517 --- /dev/null +++ b/dts/arm/adi/max32/max32650.dtsi @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&sram0 { + reg = <0x20000000 DT_SIZE_M(1)>; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(3)>; + erase-block-size = <16384>; +}; + +&clk_ipo { + clock-frequency = ; +}; + +&clk_iso { + clock-frequency = ; +}; + +/delete-node/ &clk_erfo; + +/delete-node/ &i2c2; + +/delete-node/ &trng; + +&pinctrl { + reg = <0x40008000 0x4000>; + + gpio2: gpio@4000a000 { + reg = <0x4000a000 0x1000>; + compatible = "adi,max32-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupts = <26 0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 2>; + status = "disabled"; + }; + + gpio3: gpio@4000b000 { + reg = <0x4000b000 0x1000>; + compatible = "adi,max32-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupts = <58 0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS1 6>; + status = "disabled"; + }; +}; + +/* MAX32650 extra peripherals. */ +/ { + soc { + trng: trng@400b5000 { + compatible = "adi,max32-trng"; + reg = <0x400b5000 0x1000>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS1 2>; + status = "disabled"; + }; + + timer4: timer@40014000 { + compatible = "adi,max32-timer"; + reg = <0x40014000 0x1000>; + interrupts = <9 0>; + status = "disabled"; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 19>; + clock-source = ; + prescaler = <1>; + + counter { + compatible = "adi,max32-counter"; + status = "disabled"; + }; + + pwm { + compatible = "adi,max32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + + timer5: timer@40015000 { + compatible = "adi,max32-timer"; + reg = <0x40015000 0x1000>; + interrupts = <10 0>; + status = "disabled"; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 20>; + clock-source = ; + prescaler = <1>; + + counter { + compatible = "adi,max32-counter"; + status = "disabled"; + }; + + pwm { + compatible = "adi,max32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + }; +}; diff --git a/dts/arm/adi/max32/max32655.dtsi b/dts/arm/adi/max32/max32655.dtsi index 71bbc485fad33..fd148a6ac8d3d 100644 --- a/dts/arm/adi/max32/max32655.dtsi +++ b/dts/arm/adi/max32/max32655.dtsi @@ -6,6 +6,7 @@ #include #include +#include &pinctrl { reg = <0x40008000 0x2400>; diff --git a/dts/arm/adi/max32/max32660-pinctrl.dtsi b/dts/arm/adi/max32/max32660-pinctrl.dtsi new file mode 100644 index 0000000000000..cfb872c11d315 --- /dev/null +++ b/dts/arm/adi/max32/max32660-pinctrl.dtsi @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + pinctrl: pin-controller@40008000 { + /omit-if-no-ref/ swdio_p0_0: swdio_p0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_miso_p0_0: spi1_miso_p0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_tx_p0_0: uart1_tx_p0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ swdclk_p0_1: swdclk_p0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_mosi_p0_1: spi1_mosi_p0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rx_p0_1: uart1_rx_p0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1_scl_p0_2: i2c1_scl_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sck_p0_2: spi1_sck_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ cal32k_p0_2: cal32k_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1_sda_p0_3: i2c1_sda_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss0_p0_3: spi1_ss0_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0_p0_3: tmr0_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_miso_p0_4: spi0_miso_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_tx_p0_4: uart0_tx_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_mosi_p0_5: spi0_mosi_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_rx_p0_5: uart0_rx_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_sck_p0_6: spi0_sck_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_cts_p0_6: uart0_cts_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_tx_p0_6: uart1_tx_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_ss0_p0_7: spi0_ss0_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0_rts_p0_7: uart0_rts_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rx_p0_7: uart1_rx_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0_scl_p0_8: i2c0_scl_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ swdio_p0_8: swdio_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0_sda_p0_9: i2c0_sda_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ swdclk_p0_9: swdclk_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_miso_p0_10: spi1_miso_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_tx_p0_10: uart1_tx_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_mosi_p0_11: spi1_mosi_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rx_p0_11: uart1_rx_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sck_p0_12: spi1_sck_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_cts_p0_12: uart1_cts_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss0_p0_13: spi1_ss0_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rts_p0_13: uart1_rts_p0_13 { + pinmux = ; + }; + }; + }; +}; diff --git a/dts/arm/adi/max32/max32660.dtsi b/dts/arm/adi/max32/max32660.dtsi new file mode 100644 index 0000000000000..b93b451ffd885 --- /dev/null +++ b/dts/arm/adi/max32/max32660.dtsi @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&clk_ipo { + clock-frequency = ; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(16)>; +}; + +/delete-node/ &clk_iso; +/delete-node/ &clk_ibro; +/delete-node/ &clk_erfo; +/delete-node/ &adc; +/delete-node/ &gpio1; +/delete-node/ &i2c2; +/delete-node/ &uart2; +/delete-node/ &timer3; +/delete-node/ &trng; +/delete-node/ &flash0; + +&flc0 { + flash0: flash@0{ + compatible = "soc-nv-flash"; + reg = <0x00000000 DT_SIZE_K(256)>; + write-block-size = <16>; + erase-block-size = <8192>; + }; +}; + +/* MAX32660 extra peripherals. */ +/ { + chosen { + /delete-property/ zephyr,entropy; + }; + + soc { + sram1: memory@20004000 { + compatible = "mmio-sram"; + reg = <0x20004000 DT_SIZE_K(16)>; + }; + + sram2: memory@20008000 { + compatible = "mmio-sram"; + reg = <0x20008000 DT_SIZE_K(32)>; + }; + + sram3: memory@20010000 { + compatible = "mmio-sram"; + reg = <0x20010000 DT_SIZE_K(32)>; + }; + + dma0: dma@40028000 { + compatible = "adi,max32-dma"; + reg = <0x40028000 0x1000>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 5>; + interrupts = <28 0>, <29 0>, <30 0>, <31 0>; + dma-channels = <4>; + status = "disabled"; + #dma-cells = <2>; + }; + + spi0: spi@40046000 { + compatible = "adi,max32-spi"; + reg = <0x40046000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 6>; + interrupts = <16 0>; + status = "disabled"; + }; + + spi1: spi@40019000 { + compatible = "adi,max32-spi"; + reg = <0x40019000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 7>; + interrupts = <17 0>; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/adi/max32/max32662.dtsi b/dts/arm/adi/max32/max32662.dtsi index 51a4e8201eba2..4c8c99cf637fb 100644 --- a/dts/arm/adi/max32/max32662.dtsi +++ b/dts/arm/adi/max32/max32662.dtsi @@ -24,6 +24,8 @@ /delete-node/ &timer3; +/delete-node/ &rtc_counter; + &adc { compatible = "adi,max32-adc-sar", "adi,max32-adc"; clock-source = ; @@ -116,5 +118,12 @@ status = "disabled"; }; }; + + rtc_counter: rtc_counter@40106000 { + compatible = "adi,max32-rtc-counter"; + reg = <0x40106000 0x400>; + interrupts = <3 0>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/adi/max32/max32666.dtsi b/dts/arm/adi/max32/max32666.dtsi index e697a912b411f..d49cb6c49216f 100644 --- a/dts/arm/adi/max32/max32666.dtsi +++ b/dts/arm/adi/max32/max32666.dtsi @@ -174,5 +174,19 @@ interrupts = <67 0>; status = "disabled"; }; + + sdhc0: sdhc@400b6000 { + compatible = "adi,max32-sdhc"; + reg = <0x400b6000 0x1000>; + interrupts = <66 0>; + status = "disabled"; + mmc { + compatible = "zephyr,sdmmc-disk"; + status = "disabled"; + disk-name = "SD"; + }; + power-delay-ms = <1500>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS1 10>; + }; }; }; diff --git a/dts/arm/adi/max32/max32670.dtsi b/dts/arm/adi/max32/max32670.dtsi index c15e860ea9a21..1168bd2187f38 100644 --- a/dts/arm/adi/max32/max32670.dtsi +++ b/dts/arm/adi/max32/max32670.dtsi @@ -20,6 +20,8 @@ clock-frequency = ; }; +/delete-node/ &rtc_counter; + /* MAX32670 extra peripherals. */ / { soc { @@ -143,5 +145,12 @@ status = "disabled"; }; }; + + rtc_counter: rtc_counter@40106000 { + compatible = "adi,max32-rtc-counter"; + reg = <0x40106000 0x400>; + interrupts = <3 0>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/adi/max32/max32672.dtsi b/dts/arm/adi/max32/max32672.dtsi index 6fbd471ad9cca..1531f4b2f6b6b 100644 --- a/dts/arm/adi/max32/max32672.dtsi +++ b/dts/arm/adi/max32/max32672.dtsi @@ -22,6 +22,8 @@ /delete-node/ &clk_iso; +/delete-node/ &rtc_counter; + &adc { compatible = "adi,max32-adc-sar", "adi,max32-adc"; clock-source = ; @@ -173,5 +175,12 @@ status = "disabled"; }; }; + + rtc_counter: rtc_counter@40106000 { + compatible = "adi,max32-rtc-counter"; + reg = <0x40106000 0x400>; + interrupts = <3 0>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/adi/max32/max32675.dtsi b/dts/arm/adi/max32/max32675.dtsi index 6bb2562771d0a..12950c4d98edb 100644 --- a/dts/arm/adi/max32/max32675.dtsi +++ b/dts/arm/adi/max32/max32675.dtsi @@ -22,6 +22,7 @@ /delete-node/ &clk_iso; /delete-node/ &uart1; +/delete-node/ &rtc_counter; /* MAX32675 extra peripherals. */ / { @@ -90,5 +91,12 @@ clock-source = ; prescaler = <1>; }; + + rtc_counter: rtc_counter@40106000 { + compatible = "adi,max32-rtc-counter"; + reg = <0x40106000 0x400>; + interrupts = <3 0>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/adi/max32/max78000-pinctrl.dtsi b/dts/arm/adi/max32/max78000-pinctrl.dtsi new file mode 100644 index 0000000000000..0cc2d876d8b79 --- /dev/null +++ b/dts/arm/adi/max32/max78000-pinctrl.dtsi @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + pinctrl: pin-controller@40008000 { + /omit-if-no-ref/ uart0a_rx_p0_0: uart0a_rx_p0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0a_tx_p0_1: uart0a_tx_p0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0a_ioa_p0_2: tmr0a_ioa_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0b_cts_p0_2: uart0b_cts_p0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ ext_clk_p0_3: ext_clk_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0a_iob_p0_3: tmr0a_iob_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ uart0b_rts_p0_3: uart0b_rts_p0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_ss0_p0_4: spi0_ss0_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_ioan_p0_4: tmr0b_ioan_p0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_mosi_p0_5: spi0_mosi_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_iobn_p0_5: tmr0b_iobn_p0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_miso_p0_6: spi0_miso_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_io_p0_6: owm_io_p0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_sck_p0_7: spi0_sck_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_pe_p0_7: owm_pe_p0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_sdio2_p0_8: spi0_sdio2_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_ioa_p0_8: tmr0b_ioa_p0_8 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_sdio3_p0_9: spi0_sdio3_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr0b_iob_p0_9: tmr0b_iob_p0_9 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0_scl_p0_10: i2c0_scl_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_ss2_p0_10: spi0_ss2_p0_10 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c0_sda_p0_11: i2c0_sda_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ spi0_ss1_p0_11: spi0_ss1_p0_11 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_rx_p0_12: uart1_rx_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_ioan_p0_12: tmr1b_ioan_p0_12 { + pinmux = ; + }; + + /omit-if-no-ref/ uart1_tx_p0_13: uart1_tx_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1b_iobn_p0_13: tmr1b_iobn_p0_13 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1a_ioa_p0_14: tmr1a_ioa_p0_14 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_clkext_p0_14: i2s_clkext_p0_14 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr1a_iob_p0_15: tmr1a_iob_p0_15 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_vsync_p0_15: pcif_vsync_p0_15 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1_scl_p0_16: i2c1_scl_p0_16 { + pinmux = ; + }; + + /omit-if-no-ref/ pt2_p0_16: pt2_p0_16 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c1_sda_p0_17: i2c1_sda_p0_17 { + pinmux = ; + }; + + /omit-if-no-ref/ pt3_p0_17: pt3_p0_17 { + pinmux = ; + }; + + /omit-if-no-ref/ pt0_p0_18: pt0_p0_18 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_io_p0_18: owm_io_p0_18 { + pinmux = ; + }; + + /omit-if-no-ref/ pt1_p0_19: pt1_p0_19 { + pinmux = ; + }; + + /omit-if-no-ref/ owm_pe_p0_19: owm_pe_p0_19 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_ss0_p0_20: spi1_ss0_p0_20 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d0_p0_20: pcif_d0_p0_20 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_mosi_p0_21: spi1_mosi_p0_21 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d1_p0_21: pcif_d1_p0_21 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_miso_p0_22: spi1_miso_p0_22 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d2_p0_22: pcif_d2_p0_22 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sck_p0_23: spi1_sck_p0_23 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d3_p0_23: pcif_d3_p0_23 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sdio2_p0_24: spi1_sdio2_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d4_p0_24: pcif_d4_p0_24 { + pinmux = ; + }; + + /omit-if-no-ref/ spi1_sdio3_p0_25: spi1_sdio3_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d5_p0_25: pcif_d5_p0_25 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2_ioa_p0_26: tmr2_ioa_p0_26 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d6_p0_26: pcif_d6_p0_26 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr2_iob_p0_27: tmr2_iob_p0_27 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d7_p0_27: pcif_d7_p0_27 { + pinmux = ; + }; + + /omit-if-no-ref/ swdio_p0_28: swdio_p0_28 { + pinmux = ; + }; + + /omit-if-no-ref/ swclk_p0_29: swclk_p0_29 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c2_scl_p0_30: i2c2_scl_p0_30 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d8_p0_30: pcif_d8_p0_30 { + pinmux = ; + }; + + /omit-if-no-ref/ i2c2_sda_p0_31: i2c2_sda_p0_31 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d9_p0_31: pcif_d9_p0_31 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2_rx_p1_0: uart2_rx_p1_0 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tck_p1_0: rv_tck_p1_0 { + pinmux = ; + }; + + /omit-if-no-ref/ uart2_tx_p1_1: uart2_tx_p1_1 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tms_p1_1: rv_tms_p1_1 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_sck_p1_2: i2s_sck_p1_2 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tdi_p1_2: rv_tdi_p1_2 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_ws_p1_3: i2s_ws_p1_3 { + pinmux = ; + }; + + /omit-if-no-ref/ rv_tdo_p1_3: rv_tdo_p1_3 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_sdi_p1_4: i2s_sdi_p1_4 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3b_ioa_p1_4: tmr3b_ioa_p1_4 { + pinmux = ; + }; + + /omit-if-no-ref/ i2s_sdo_p1_5: i2s_sdo_p1_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3b_iob_p1_5: tmr3b_iob_p1_5 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3a_ioa_p1_6: tmr3a_ioa_p1_6 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d10_p1_6: pcif_d10_p1_6 { + pinmux = ; + }; + + /omit-if-no-ref/ tmr3a_iob_p1_7: tmr3a_iob_p1_7 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_d11_p1_7: pcif_d11_p1_7 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_hsync_p1_8: pcif_hsync_p1_8 { + pinmux = ; + }; + + /omit-if-no-ref/ rxev0_p1_8: rxev0_p1_8 { + pinmux = ; + }; + + /omit-if-no-ref/ pcif_pclk_p1_9: pcif_pclk_p1_9 { + pinmux = ; + }; + + /omit-if-no-ref/ txev0_p1_9: txev0_p1_9 { + pinmux = ; + }; + + /omit-if-no-ref/ ain0_p2_0: ain0_p2_0 { + pinmux = ; + }; + + /omit-if-no-ref/ ain1_p2_1: ain1_p2_1 { + pinmux = ; + }; + + /omit-if-no-ref/ ain2_p2_2: ain2_p2_2 { + pinmux = ; + }; + + /omit-if-no-ref/ ain3_p2_3: ain3_p2_3 { + pinmux = ; + }; + + /omit-if-no-ref/ ain4_p2_4: ain4_p2_4 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr0b_ioa_p2_4: lptmr0b_ioa_p2_4 { + pinmux = ; + }; + + /omit-if-no-ref/ ain5_p2_5: ain5_p2_5 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr1b_ioa_p2_5: lptmr1b_ioa_p2_5 { + pinmux = ; + }; + + /omit-if-no-ref/ ain6_p2_6: ain6_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr0_clk_p2_6: lptmr0_clk_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ lpuartb_rx_p2_6: lpuartb_rx_p2_6 { + pinmux = ; + }; + + /omit-if-no-ref/ ain7_p2_7: ain7_p2_7 { + pinmux = ; + }; + + /omit-if-no-ref/ lptmr1_clk_p2_7: lptmr1_clk_p2_7 { + pinmux = ; + }; + + /omit-if-no-ref/ lpuartb_tx_p2_7: lpuartb_tx_p2_7 { + pinmux = ; + }; + + /omit-if-no-ref/ pdown_p3_0: pdown_p3_0 { + pinmux = ; + }; + + /omit-if-no-ref/ wakeup_p3_0: wakeup_p3_0 { + pinmux = ; + }; + + /omit-if-no-ref/ sqwout_p3_1: sqwout_p3_1 { + pinmux = ; + }; + + /omit-if-no-ref/ wakeup_p3_1: wakeup_p3_1 { + pinmux = ; + }; + }; + }; +}; diff --git a/dts/arm/adi/max32/max78000.dtsi b/dts/arm/adi/max32/max78000.dtsi new file mode 100644 index 0000000000000..f20b0f73f0772 --- /dev/null +++ b/dts/arm/adi/max32/max78000.dtsi @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&clk_ipo { + clock-frequency = ; +}; + +&clk_inro { + clock-frequency = ; +}; + +/delete-node/ &clk_erfo; + +&pinctrl { + reg = <0x40008000 0x2200>; + + gpio2: gpio@40080400 { + reg = <0x40080400 0x200>; + compatible = "adi,max32-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupts = <26 0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 0>; + status = "disabled"; + }; + + gpio3: gpio@40080600 { + reg = <0x40080600 0x200>; // Address and size are dummy. + compatible = "adi,max32-gpio"; + gpio-controller; + #gpio-cells = <2>; + interrupts = <54 0>; + status = "disabled"; + }; +}; + +/* MAX78000 extra peripherals. */ +/ { + soc { + sram1: memory@20008000 { + compatible = "mmio-sram"; + reg = <0x20008000 DT_SIZE_K(32)>; + }; + + sram2: memory@20010000 { + compatible = "mmio-sram"; + reg = <0x20010000 DT_SIZE_K(48)>; + }; + + sram3: memory@2001c000 { + compatible = "mmio-sram"; + reg = <0x2001c000 DT_SIZE_K(16)>; + }; + + uart3: serial@40081400 { + compatible = "adi,max32-uart"; + reg = <0x40081400 0x400>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 4>; + clock-source = ; + interrupts = <88 0>; + status = "disabled"; + }; + + spi0: spi@400be000 { + compatible = "adi,max32-spi"; + reg = <0x400be000 0x400>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS1 16>; + interrupts = <56 0>; + status = "disabled"; + }; + + spi1: spi@40046000 { + compatible = "adi,max32-spi"; + reg = <0x40046000 0x2000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 6>; + interrupts = <16 0>; + status = "disabled"; + }; + + dma0: dma@40028000 { + compatible = "adi,max32-dma"; + reg = <0x40028000 0x1000>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS0 5>; + interrupts = <28 0>, <29 0>, <30 0>, <31 0>; + dma-channels = <4>; + status = "disabled"; + #dma-cells = <2>; + }; + + w1: w1@4003d000 { + compatible = "adi,max32-w1"; + reg = <0x4003d000 0x1000>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS1 13>; + interrupts = <67 0>; + status = "disabled"; + }; + + wdt1: watchdog@40080800 { + compatible = "adi,max32-watchdog"; + reg = <0x40080800 0x400>; + interrupts = <57 0>; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 1>; + clock-source = ; + status = "disabled"; + }; + + lptimer0: timer@40080c00 { + compatible = "adi,max32-timer"; + reg = <0x40080c00 0x400>; + interrupts = <9 0>; + status = "disabled"; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 2>; + clock-source = ; + prescaler = <1>; + + pwm { + compatible = "adi,max32-pwm"; + status = "disabled"; + pinctrl-0 = <&lptmr0b_ioa_p2_4>; + pinctrl-names = "default"; + #pwm-cells = <3>; + }; + + counter { + compatible = "adi,max32-counter"; + status = "disabled"; + }; + }; + + lptimer1: timer@40081000 { + compatible = "adi,max32-timer"; + reg = <0x40081000 0x400>; + interrupts = <10 0>; + status = "disabled"; + clocks = <&gcr ADI_MAX32_CLOCK_BUS2 3>; + clock-source = ; + prescaler = <1>; + + pwm { + compatible = "adi,max32-pwm"; + status = "disabled"; + pinctrl-0 = <&lptmr1b_ioa_p2_5>; + pinctrl-names = "default"; + #pwm-cells = <3>; + }; + + counter { + compatible = "adi,max32-counter"; + status = "disabled"; + }; + }; + }; +}; diff --git a/dts/arm/ambiq/ambiq_apollo3_blue.dtsi b/dts/arm/ambiq/ambiq_apollo3_blue.dtsi index bc936a37040da..cf764f1109e21 100644 --- a/dts/arm/ambiq/ambiq_apollo3_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo3_blue.dtsi @@ -76,17 +76,17 @@ soc { compatible = "ambiq,apollo3-blue", "ambiq,apollo3x", "simple-bus"; - flash: flash-controller@c000 { + flash: flash-controller@0 { compatible = "ambiq,flash-controller"; - reg = <0x0000c000 0xf4000>; + reg = <0x00000000 0x100000>; #address-cells = <1>; #size-cells = <1>; /* Flash region */ - flash0: flash@c000 { + flash0: flash@0 { compatible = "soc-nv-flash"; - reg = <0x0000c000 0xf4000>; + reg = <0x00000000 0x100000>; }; }; @@ -209,6 +209,7 @@ }; spi0: spi@50004000 { + compatible = "ambiq,spi"; reg = <0x50004000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -219,6 +220,7 @@ }; spi1: spi@50005000 { + compatible = "ambiq,spi"; reg = <0x50005000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -229,6 +231,7 @@ }; spi2: spi@50006000 { + compatible = "ambiq,spi"; reg = <0x50006000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -239,6 +242,7 @@ }; spi3: spi@50007000 { + compatible = "ambiq,spi"; reg = <0x50007000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -249,6 +253,7 @@ }; spi4: spi@50008000 { + compatible = "ambiq,spi"; reg = <0x50008000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -259,6 +264,7 @@ }; spi5: spi@50009000 { + compatible = "ambiq,spi"; reg = <0x50009000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -269,6 +275,7 @@ }; i2c0: i2c@50004000 { + compatible = "ambiq,i2c"; reg = <0x50004000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -279,6 +286,7 @@ }; i2c1: i2c@50005000 { + compatible = "ambiq,i2c"; reg = <0x50005000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -289,6 +297,7 @@ }; i2c2: i2c@50006000 { + compatible = "ambiq,i2c"; reg = <0x50006000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -299,6 +308,7 @@ }; i2c3: i2c@50007000 { + compatible = "ambiq,i2c"; reg = <0x50007000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -309,6 +319,7 @@ }; i2c4: i2c@50008000 { + compatible = "ambiq,i2c"; reg = <0x50008000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -319,6 +330,7 @@ }; i2c5: i2c@50009000 { + compatible = "ambiq,i2c"; reg = <0x50009000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -329,6 +341,7 @@ }; adc0: adc@50010000 { + compatible = "ambiq,adc"; reg = <0x50010000 0x400>; interrupts = <18 0>; interrupt-names = "ADC"; @@ -349,6 +362,14 @@ ambiq,pwrcfg = <&pwrcfg 0x8 0x800>; }; + rtc0: rtc@40004240 { + compatible = "ambiq,rtc"; + reg = <0x40004240 0xD0>; + interrupts = <2 0>; + alarms-count = <1>; + status = "disabled"; + }; + bleif: spi@5000c000 { compatible = "ambiq,spi-bleif"; reg = <0x5000c000 0x414>; diff --git a/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi index 35656ac898dbb..10ae31820382c 100644 --- a/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo3p_blue.dtsi @@ -227,6 +227,7 @@ }; spi0: spi@50004000 { + compatible = "ambiq,spi"; reg = <0x50004000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -237,6 +238,7 @@ }; spi1: spi@50005000 { + compatible = "ambiq,spi"; reg = <0x50005000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -247,6 +249,7 @@ }; spi2: spi@50006000 { + compatible = "ambiq,spi"; reg = <0x50006000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -257,6 +260,7 @@ }; spi3: spi@50007000 { + compatible = "ambiq,spi"; reg = <0x50007000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -267,6 +271,7 @@ }; spi4: spi@50008000 { + compatible = "ambiq,spi"; reg = <0x50008000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -277,6 +282,7 @@ }; spi5: spi@50009000 { + compatible = "ambiq,spi"; reg = <0x50009000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -287,6 +293,7 @@ }; i2c0: i2c@50004000 { + compatible = "ambiq,i2c"; reg = <0x50004000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -297,6 +304,7 @@ }; i2c1: i2c@50005000 { + compatible = "ambiq,i2c"; reg = <0x50005000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -307,6 +315,7 @@ }; i2c2: i2c@50006000 { + compatible = "ambiq,i2c"; reg = <0x50006000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -317,6 +326,7 @@ }; i2c3: i2c@50007000 { + compatible = "ambiq,i2c"; reg = <0x50007000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -327,6 +337,7 @@ }; i2c4: i2c@50008000 { + compatible = "ambiq,i2c"; reg = <0x50008000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -337,6 +348,7 @@ }; i2c5: i2c@50009000 { + compatible = "ambiq,i2c"; reg = <0x50009000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -347,6 +359,7 @@ }; adc0: adc@50010000 { + compatible = "ambiq,adc"; reg = <0x50010000 0x400>; interrupts = <18 0>; interrupt-names = "ADC"; @@ -390,6 +403,14 @@ ambiq,pwrcfg = <&pwrcfg 0x8 0x2000>; }; + rtc0: rtc@40004240 { + compatible = "ambiq,rtc"; + reg = <0x40004240 0xD0>; + interrupts = <2 0>; + alarms-count = <1>; + status = "disabled"; + }; + bleif: spi@5000c000 { compatible = "ambiq,spi-bleif"; reg = <0x5000c000 0x414>; diff --git a/dts/arm/ambiq/ambiq_apollo4p.dtsi b/dts/arm/ambiq/ambiq_apollo4p.dtsi index c5641cfd352dc..b40744a663908 100644 --- a/dts/arm/ambiq/ambiq_apollo4p.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p.dtsi @@ -154,6 +154,7 @@ }; iom0_spi: spi@40050000 { + compatible = "ambiq,spi"; reg = <0x40050000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -163,6 +164,7 @@ }; iom0_i2c: i2c@40050000 { + compatible = "ambiq,i2c"; reg = <0x40050000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -172,6 +174,7 @@ }; iom1_spi: spi@40051000 { + compatible = "ambiq,spi"; reg = <0x40051000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -181,6 +184,7 @@ }; iom1_i2c: i2c@40051000 { + compatible = "ambiq,i2c"; reg = <0x40051000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -190,6 +194,7 @@ }; iom2_spi: spi@40052000 { + compatible = "ambiq,spi"; reg = <0x40052000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -199,6 +204,7 @@ }; iom2_i2c: i2c@40052000 { + compatible = "ambiq,i2c"; reg = <0x40052000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -208,6 +214,7 @@ }; iom3_spi: spi@40053000 { + compatible = "ambiq,spi"; reg = <0x40053000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -217,6 +224,7 @@ }; iom3_i2c: i2c@40053000 { + compatible = "ambiq,i2c"; reg = <0x40053000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -226,6 +234,7 @@ }; iom4_spi: spi@40054000 { + compatible = "ambiq,spi"; reg = <0x40054000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -235,6 +244,7 @@ }; iom4_i2c: i2c@40054000 { + compatible = "ambiq,i2c"; reg = <0x40054000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -244,6 +254,7 @@ }; iom5_spi: spi@40055000 { + compatible = "ambiq,spi"; reg = <0x40055000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -253,6 +264,7 @@ }; iom5_i2c: i2c@40055000 { + compatible = "ambiq,i2c"; reg = <0x40055000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -262,6 +274,7 @@ }; iom6_spi: spi@40056000 { + compatible = "ambiq,spi"; reg = <0x40056000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -271,6 +284,7 @@ }; iom6_i2c: i2c@40056000 { + compatible = "ambiq,i2c"; reg = <0x40056000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -280,6 +294,7 @@ }; iom7_spi: spi@40057000 { + compatible = "ambiq,spi"; reg = <0x40057000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -289,6 +304,7 @@ }; iom7_i2c: i2c@40057000 { + compatible = "ambiq,i2c"; reg = <0x40057000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -298,6 +314,7 @@ }; adc0: adc@40038000 { + compatible = "ambiq,adc"; reg = <0x40038000 0x400>; interrupts = <19 0>; interrupt-names = "ADC"; diff --git a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi index 70f13bda5e94f..cf9c2bf4a7cda 100644 --- a/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi +++ b/dts/arm/ambiq/ambiq_apollo4p_blue.dtsi @@ -135,6 +135,7 @@ }; spi0: spi@40050000 { + compatible = "ambiq,spi"; reg = <0x40050000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -144,6 +145,7 @@ }; spi1: spi@40051000 { + compatible = "ambiq,spi"; reg = <0x40051000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -153,6 +155,7 @@ }; spi2: spi@40052000 { + compatible = "ambiq,spi"; reg = <0x40052000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -162,6 +165,7 @@ }; spi3: spi@40053000 { + compatible = "ambiq,spi"; reg = <0x40053000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -193,6 +197,7 @@ }; spi5: spi@40055000 { + compatible = "ambiq,spi"; reg = <0x40055000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -202,6 +207,7 @@ }; spi6: spi@40056000 { + compatible = "ambiq,spi"; reg = <0x40056000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -211,6 +217,7 @@ }; spi7: spi@40057000 { + compatible = "ambiq,spi"; reg = <0x40057000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -220,6 +227,7 @@ }; i2c0: i2c@40050000 { + compatible = "ambiq,i2c"; reg = <0x40050000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -229,6 +237,7 @@ }; i2c1: i2c@40051000 { + compatible = "ambiq,i2c"; reg = <0x40051000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -238,6 +247,7 @@ }; i2c2: i2c@40052000 { + compatible = "ambiq,i2c"; reg = <0x40052000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -247,6 +257,7 @@ }; i2c3: i2c@40053000 { + compatible = "ambiq,i2c"; reg = <0x40053000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -256,6 +267,7 @@ }; i2c4: i2c@40054000 { + compatible = "ambiq,i2c"; reg = <0x40054000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -265,6 +277,7 @@ }; i2c5: i2c@40055000 { + compatible = "ambiq,i2c"; reg = <0x40055000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -274,6 +287,7 @@ }; i2c6: i2c@40056000 { + compatible = "ambiq,i2c"; reg = <0x40056000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -283,6 +297,7 @@ }; i2c7: i2c@40057000 { + compatible = "ambiq,i2c"; reg = <0x40057000 0x1000>; #address-cells = <1>; #size-cells = <0>; @@ -331,6 +346,14 @@ ambiq,pwrcfg = <&pwrcfg 0x4 0x400000>; }; + rtc0: rtc@40004800 { + compatible = "ambiq,rtc"; + reg = <0x40004800 0x210>; + interrupts = <2 0>; + alarms-count = <1>; + status = "disabled"; + }; + pinctrl: pin-controller@40010000 { compatible = "ambiq,apollo4-pinctrl"; reg = <0x40010000 0x800>; diff --git a/dts/arm/antmicro/myra.dtsi b/dts/arm/antmicro/myra.dtsi new file mode 100644 index 0000000000000..70f8beabecfd0 --- /dev/null +++ b/dts/arm/antmicro/myra.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +&spi2 { + pinctrl-0 = <&spi2_nss_pb12 &spi2_sck_pb13 + &spi2_miso_pb14 &spi2_mosi_pb15>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/dts/arm/atmel/dma_atmel_same70.h b/dts/arm/atmel/dma_atmel_same70.h deleted file mode 100644 index debe04256d18d..0000000000000 --- a/dts/arm/atmel/dma_atmel_same70.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2020 Linaro Limited - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef DMA_ATMEL_SAME70_H_ -#define DMA_ATMEL_SAME70_H_ - -/** Peripheral Hardware Request Line Identifier */ -#define DMA_PERID_HSMCI_TX_RX 0 -#define DMA_PERID_SPI0_TX 1 -#define DMA_PERID_SPI0_RX 2 -#define DMA_PERID_SPI1_TX 3 -#define DMA_PERID_SPI1_RX 4 -#define DMA_PERID_QSPI_TX 5 -#define DMA_PERID_QSPI_RX 6 -#define DMA_PERID_USART0_TX 7 -#define DMA_PERID_USART0_RX 8 -#define DMA_PERID_USART1_TX 9 -#define DMA_PERID_USART1_RX 10 -#define DMA_PERID_USART2_TX 11 -#define DMA_PERID_USART2_RX 12 -#define DMA_PERID_PWM0_TX 13 -#define DMA_PERID_TWIHS0_TX 14 -#define DMA_PERID_TWIHS0_RX 15 -#define DMA_PERID_TWIHS1_TX 16 -#define DMA_PERID_TWIHS1_RX 17 -#define DMA_PERID_TWIHS2_TX 18 -#define DMA_PERID_TWIHS2_RX 19 -#define DMA_PERID_UART0_TX 20 -#define DMA_PERID_UART0_RX 21 -#define DMA_PERID_UART1_TX 22 -#define DMA_PERID_UART1_RX 23 -#define DMA_PERID_UART2_TX 24 -#define DMA_PERID_UART2_RX 25 -#define DMA_PERID_UART3_TX 26 -#define DMA_PERID_UART3_RX 27 -#define DMA_PERID_UART4_TX 28 -#define DMA_PERID_UART4_RX 29 -#define DMA_PERID_DACC_TX 30 -#define DMA_PERID_SSC_TX 32 -#define DMA_PERID_SSC_RX 33 -#define DMA_PERID_PIOA_RX 34 -#define DMA_PERID_AFEC0_RX 35 -#define DMA_PERID_AFEC1_RX 36 -#define DMA_PERID_AES_TX 37 -#define DMA_PERID_AES_RX 38 -#define DMA_PERID_PWM1_TX 39 -#define DMA_PERID_TC0_RX 40 -#define DMA_PERID_TC1_RX 41 -#define DMA_PERID_TC2_RX 42 -#define DMA_PERID_TC3_RX 43 - -#endif /* DMA_ATMEL_SAME70_H_ */ diff --git a/dts/arm/atmel/dma_atmel_samv71.h b/dts/arm/atmel/dma_atmel_samv71.h deleted file mode 100644 index af346081fa4c1..0000000000000 --- a/dts/arm/atmel/dma_atmel_samv71.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2020 Linaro Limited - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef DMA_ATMEL_SAMV71_H_ -#define DMA_ATMEL_SAMV71_H_ - -/** Peripheral Hardware Request Line Identifier */ -#define DMA_PERID_HSMCI_TX_RX 0 -#define DMA_PERID_SPI0_TX 1 -#define DMA_PERID_SPI0_RX 2 -#define DMA_PERID_SPI1_TX 3 -#define DMA_PERID_SPI1_RX 4 -#define DMA_PERID_QSPI_TX 5 -#define DMA_PERID_QSPI_RX 6 -#define DMA_PERID_USART0_TX 7 -#define DMA_PERID_USART0_RX 8 -#define DMA_PERID_USART1_TX 9 -#define DMA_PERID_USART1_RX 10 -#define DMA_PERID_USART2_TX 11 -#define DMA_PERID_USART2_RX 12 -#define DMA_PERID_PWM0_TX 13 -#define DMA_PERID_TWIHS0_TX 14 -#define DMA_PERID_TWIHS0_RX 15 -#define DMA_PERID_TWIHS1_TX 16 -#define DMA_PERID_TWIHS1_RX 17 -#define DMA_PERID_TWIHS2_TX 18 -#define DMA_PERID_TWIHS2_RX 19 -#define DMA_PERID_UART0_TX 20 -#define DMA_PERID_UART0_RX 21 -#define DMA_PERID_UART1_TX 22 -#define DMA_PERID_UART1_RX 23 -#define DMA_PERID_UART2_TX 24 -#define DMA_PERID_UART2_RX 25 -#define DMA_PERID_UART3_TX 26 -#define DMA_PERID_UART3_RX 27 -#define DMA_PERID_UART4_TX 28 -#define DMA_PERID_UART4_RX 29 -#define DMA_PERID_DACC0_TX 30 -#define DMA_PERID_DACC1_TX 31 -#define DMA_PERID_SSC_TX 32 -#define DMA_PERID_SSC_RX 33 -#define DMA_PERID_PIOA_RX 34 -#define DMA_PERID_AFEC0_RX 35 -#define DMA_PERID_AFEC1_RX 36 -#define DMA_PERID_AES_TX 37 -#define DMA_PERID_AES_RX 38 -#define DMA_PERID_PWM1_TX 39 -#define DMA_PERID_TC0_RX 40 -#define DMA_PERID_TC3_RX 41 -#define DMA_PERID_TC6_RX 42 -#define DMA_PERID_TC9_RX 43 -#define DMA_PERID_I2SC0_TX_L 44 -#define DMA_PERID_I2SC0_RX_L 45 -#define DMA_PERID_I2SC1_TX_L 46 -#define DMA_PERID_I2SC1_RX_L 47 -#define DMA_PERID_I2SC0_TX_R 48 -#define DMA_PERID_I2SC0_RX_R 49 -#define DMA_PERID_I2SC1_TX_R 50 -#define DMA_PERID_I2SC1_RX_R 51 - -#endif /* DMA_ATMEL_SAMV71_H_ */ diff --git a/dts/arm/atmel/sam4l.dtsi b/dts/arm/atmel/sam4l.dtsi index 7f19f8d21a482..a15dc81d39c64 100644 --- a/dts/arm/atmel/sam4l.dtsi +++ b/dts/arm/atmel/sam4l.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Gerson Fernando Budke + * Copyright (c) 2020-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,10 @@ #include / { + aliases { + watchdog0 = &wdt; + }; + chosen { zephyr,flash-controller = &flashcalw; zephyr,entropy = &trng; @@ -237,6 +241,14 @@ reg = <0x80020c 0xf>; status = "okay"; }; + + wdt: watchdog@400f0c00 { + compatible = "atmel,sam4l-watchdog"; + reg = <0x400f0c00 0x400>; + interrupts = <44 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 99>; + status = "okay"; + }; }; }; diff --git a/dts/arm/atmel/sam4s.dtsi b/dts/arm/atmel/sam4s.dtsi index 64828f3a7d50c..3e2dcb2172643 100644 --- a/dts/arm/atmel/sam4s.dtsi +++ b/dts/arm/atmel/sam4s.dtsi @@ -55,7 +55,7 @@ status = "okay"; }; - sram0: memory@20100000 { + sram0: memory@20000000 { compatible = "mmio-sram"; }; @@ -232,6 +232,15 @@ status = "disabled"; }; + dacc: dacc@4003c000 { + compatible = "atmel,sam-dac"; + reg = <0x4003c000 0x4000>; + interrupts = <30 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 30>; + status = "disabled"; + #io-channel-cells = <1>; + }; + rstc: rstc@400e1400 { compatible = "atmel,sam-rstc"; reg = <0x400e1400 0x10>; diff --git a/dts/arm/atmel/sam4s16b.dtsi b/dts/arm/atmel/sam4s16b.dtsi index f671f6fccc48e..ca158cfd915cf 100644 --- a/dts/arm/atmel/sam4s16b.dtsi +++ b/dts/arm/atmel/sam4s16b.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(128)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(128)>; }; }; }; diff --git a/dts/arm/atmel/sam4s16c.dtsi b/dts/arm/atmel/sam4s16c.dtsi index f671f6fccc48e..ca158cfd915cf 100644 --- a/dts/arm/atmel/sam4s16c.dtsi +++ b/dts/arm/atmel/sam4s16c.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(128)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(128)>; }; }; }; diff --git a/dts/arm/atmel/sam4s2a.dtsi b/dts/arm/atmel/sam4s2a.dtsi index b57ddb0cec65a..3855a903a4556 100644 --- a/dts/arm/atmel/sam4s2a.dtsi +++ b/dts/arm/atmel/sam4s2a.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(64)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(64)>; }; }; }; diff --git a/dts/arm/atmel/sam4s2b.dtsi b/dts/arm/atmel/sam4s2b.dtsi index b57ddb0cec65a..3855a903a4556 100644 --- a/dts/arm/atmel/sam4s2b.dtsi +++ b/dts/arm/atmel/sam4s2b.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(64)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(64)>; }; }; }; diff --git a/dts/arm/atmel/sam4s2c.dtsi b/dts/arm/atmel/sam4s2c.dtsi index b57ddb0cec65a..3855a903a4556 100644 --- a/dts/arm/atmel/sam4s2c.dtsi +++ b/dts/arm/atmel/sam4s2c.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(64)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(64)>; }; }; }; diff --git a/dts/arm/atmel/sam4s4a.dtsi b/dts/arm/atmel/sam4s4a.dtsi index 1ea079b054caf..16d6a850f83c0 100644 --- a/dts/arm/atmel/sam4s4a.dtsi +++ b/dts/arm/atmel/sam4s4a.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(64)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(64)>; }; }; }; diff --git a/dts/arm/atmel/sam4s4b.dtsi b/dts/arm/atmel/sam4s4b.dtsi index 959c4d591e203..b265de356ea53 100644 --- a/dts/arm/atmel/sam4s4b.dtsi +++ b/dts/arm/atmel/sam4s4b.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(64)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(64)>; }; }; }; diff --git a/dts/arm/atmel/sam4s4c.dtsi b/dts/arm/atmel/sam4s4c.dtsi index 1ea079b054caf..16d6a850f83c0 100644 --- a/dts/arm/atmel/sam4s4c.dtsi +++ b/dts/arm/atmel/sam4s4c.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(64)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(64)>; }; }; }; diff --git a/dts/arm/atmel/sam4s8b.dtsi b/dts/arm/atmel/sam4s8b.dtsi index 2e00a78b4d6da..44f376020091d 100644 --- a/dts/arm/atmel/sam4s8b.dtsi +++ b/dts/arm/atmel/sam4s8b.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(128)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(128)>; }; }; }; diff --git a/dts/arm/atmel/sam4s8c.dtsi b/dts/arm/atmel/sam4s8c.dtsi index 2e00a78b4d6da..44f376020091d 100644 --- a/dts/arm/atmel/sam4s8c.dtsi +++ b/dts/arm/atmel/sam4s8c.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(128)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(128)>; }; }; }; diff --git a/dts/arm/atmel/sam4sa16c.dtsi b/dts/arm/atmel/sam4sa16c.dtsi index 789e482b0f666..a413672ba1b50 100644 --- a/dts/arm/atmel/sam4sa16c.dtsi +++ b/dts/arm/atmel/sam4sa16c.dtsi @@ -16,8 +16,8 @@ }; }; - sram0: memory@20100000 { - reg = <0x20100000 DT_SIZE_K(160)>; + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(160)>; }; }; }; diff --git a/dts/arm/atmel/samc21.dtsi b/dts/arm/atmel/samc21.dtsi index 095e98437f05b..0e91f58e34125 100644 --- a/dts/arm/atmel/samc21.dtsi +++ b/dts/arm/atmel/samc21.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Kamil Serwus + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +9,8 @@ / { aliases { + adc-1 = &adc1; + sercom-4 = &sercom4; sercom-5 = &sercom5; }; @@ -15,15 +18,18 @@ soc { adc1: adc@42004800 { compatible = "atmel,sam0-adc"; - status = "disabled"; reg = <0x42004800 0x30>; interrupts = <26 0>; interrupt-names = "resrdy"; clocks = <&gclk 34>, <&mclk 0x1c 18>; clock-names = "GCLK", "MCLK"; - gclk = <0>; - prescaler = <4>; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + #io-channel-cells = <1>; + + prescaler = <4>; }; sercom4: sercom@42001400 { @@ -32,6 +38,8 @@ interrupts = <13 0>; clocks = <&gclk 23>, <&mclk 0x1c 5>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -41,6 +49,8 @@ interrupts = <14 0>; clocks = <&gclk 25>, <&mclk 0x1c 6>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -51,9 +61,12 @@ interrupt-names = "int0"; clocks = <&gclk 26>, <&mclk 0x10 8>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; divider = <12>; - status = "disabled"; }; can1: can@42002000 { @@ -63,9 +76,12 @@ interrupt-names = "int0"; clocks = <&gclk 27>, <&mclk 0x10 9>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; divider = <12>; - status = "disabled"; }; }; }; diff --git a/dts/arm/atmel/samc2x.dtsi b/dts/arm/atmel/samc2x.dtsi index a0e57c5c75f19..d6ba356b3de83 100644 --- a/dts/arm/atmel/samc2x.dtsi +++ b/dts/arm/atmel/samc2x.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Kamil Serwus + * Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +14,23 @@ / { aliases { + adc-0 = &adc0; + + port-a = &porta; + port-b = &portb; + port-c = &portc; + + rtc = &rtc; + + sercom-0 = &sercom0; + sercom-1 = &sercom1; + sercom-2 = &sercom2; + sercom-3 = &sercom3; + + tcc-0 = &tcc0; + tcc-1 = &tcc1; + tcc-2 = &tcc2; + watchdog0 = &wdog; }; @@ -25,9 +43,10 @@ #size-cells = <0>; cpu0: cpu@0 { - device_type = "cpu"; compatible = "arm,cortex-m0+"; reg = <0>; + + device_type = "cpu"; }; }; @@ -43,47 +62,43 @@ <0x0080A048 0x4>; }; - aliases { - port-a = &porta; - port-b = &portb; - port-c = &portc; - - sercom-0 = &sercom0; - sercom-1 = &sercom1; - sercom-2 = &sercom2; - sercom-3 = &sercom3; - - tcc-0 = &tcc0; - tcc-1 = &tcc1; - tcc-2 = &tcc2; - }; - soc { nvmctrl: nvmctrl@41004000 { compatible = "atmel,sam0-nvmctrl"; reg = <0x41004000 0x22>; interrupts = <6 0>; - lock-regions = <16>; - #address-cells = <1>; #size-cells = <1>; + lock-regions = <16>; + flash0: flash@0 { compatible = "soc-nv-flash"; + write-block-size = <4>; }; }; mclk: mclk@40000800 { - compatible = "atmel,samc2x-mclk"; + compatible = "atmel,sam0-mclk"; reg = <0x40000800 0x400>; + #clock-cells = <2>; }; + osc32kctrl: osc32kctrl@40001400 { + compatible = "atmel,sam0-osc32kctrl"; + reg = <0x40001400 0x400>; + #clock-cells = <0>; + #atmel,assigned-clock-cells = <1>; + }; + gclk: gclk@40001c00 { - compatible = "atmel,samc2x-gclk"; + compatible = "atmel,sam0-gclk"; reg = <0x40001c00 0x400>; + #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; }; eic: eic@40002800 { @@ -107,20 +122,25 @@ compatible = "atmel,sam0-dmac"; reg = <0x41006000 0x50>; interrupts = <7 0>; + status = "disabled"; + #dma-cells = <2>; }; adc0: adc@42004400 { compatible = "atmel,sam0-adc"; - status = "disabled"; reg = <0x42004400 0x30>; interrupts = <25 0>; interrupt-names = "resrdy"; clocks = <&gclk 33>, <&mclk 0x1c 17>; clock-names = "GCLK", "MCLK"; - gclk = <0>; - prescaler = <4>; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + #io-channel-cells = <1>; + + prescaler = <4>; }; sercom0: sercom@42000400 { @@ -129,6 +149,8 @@ interrupts = <9 0>; clocks = <&gclk 19>, <&mclk 0x1c 1>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -138,6 +160,8 @@ interrupts = <10 0>; clocks = <&gclk 20>, <&mclk 0x1c 2>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -147,6 +171,8 @@ interrupts = <11 0>; clocks = <&gclk 21>, <&mclk 0x1c 3>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -156,6 +182,8 @@ interrupts = <12 0>; clocks = <&gclk 22>, <&mclk 0x1c 4>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -165,6 +193,9 @@ interrupts = <17 0>; clocks = <&gclk 28>, <&mclk 0x1c 9>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <4>; counter-size = <24>; @@ -176,6 +207,9 @@ interrupts = <18 0>; clocks = <&gclk 28>, <&mclk 0x1c 10>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <4>; counter-size = <24>; @@ -187,6 +221,9 @@ interrupts = <19 0>; clocks = <&gclk 29>, <&mclk 0x1c 11>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <2>; counter-size = <16>; @@ -194,41 +231,54 @@ pinctrl: pinctrl@41000000 { compatible = "atmel,sam0-pinctrl"; + ranges = <0x41000000 0x41000000 0x180>; + #address-cells = <1>; #size-cells = <1>; - ranges = <0x41000000 0x41000000 0x180>; porta: gpio@41000000 { compatible = "atmel,sam0-gpio"; reg = <0x41000000 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; portb: gpio@41000080 { compatible = "atmel,sam0-gpio"; reg = <0x41000080 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; portc: gpio@41000100 { compatible = "atmel,sam0-gpio"; reg = <0x41000100 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; }; rtc: rtc@40002400 { compatible = "atmel,sam0-rtc"; - reg = <0x40002400 0x1C>; - interrupts = <3 0>; - clock-generator = <0>; + reg = <0x40002400 0x24>; + interrupts = <2 0>; + clocks = <&osc32kctrl>, <&mclk 0x14 9>; + clock-names = "OSC32KCTRL", "MCLK"; + atmel,assigned-clocks = <&osc32kctrl 0>; + atmel,assigned-clock-names = "OSC32KCTRL"; status = "disabled"; + + alarms-count = <1>; + cal-constant = <(4096 * 240)>; }; }; }; diff --git a/dts/arm/atmel/samd20.dtsi b/dts/arm/atmel/samd20.dtsi index 01af6c4e4503d..26c16e36e2d94 100644 --- a/dts/arm/atmel/samd20.dtsi +++ b/dts/arm/atmel/samd20.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Sean Nyekjaer + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +21,9 @@ interrupts = <13 0>; clocks = <&gclk 0x13>, <&pm 0x20 8>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; tc2: tc@42002800 { @@ -28,6 +32,9 @@ interrupts = <15 0>; clocks = <&gclk 0x14>, <&pm 0x20 10>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; tc6: tc@42003800 { @@ -36,6 +43,9 @@ interrupts = <19 0>; clocks = <&gclk 0x16>, <&pm 0x20 14>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; }; }; @@ -44,48 +54,71 @@ interrupts = <23 0>; clocks = <&gclk 26>, <&pm 0x20 18>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; +}; + +&rtc { + clocks = <&gclk 2>, <&pm 0x18 5>; + clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 4>; + atmel,assigned-clock-names = "GCLK"; }; &sercom0 { interrupts = <7 0>; clocks = <&gclk 0xd>, <&pm 0x20 2>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom1 { interrupts = <8 0>; clocks = <&gclk 0xe>, <&pm 0x20 3>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom2 { interrupts = <9 0>; clocks = <&gclk 0xf>, <&pm 0x20 4>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom3 { interrupts = <10 0>; clocks = <&gclk 0x10>, <&pm 0x20 5>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom4 { interrupts = <11 0>; clocks = <&gclk 0x11>, <&pm 0x20 6>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom5 { interrupts = <12 0>; clocks = <&gclk 0x12>, <&pm 0x20 7>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &tc4 { interrupts = <17 0>; clocks = <&gclk 0x15>, <&pm 0x20 12>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &adc { @@ -93,4 +126,11 @@ interrupt-names = "resrdy"; clocks = <&gclk 0x17>, <&pm 0x20 16>; clock-names = "GCLK", "PM"; + /* + * 2.1 MHz is ADC max clock + * 8 MHz GCLK / 4 = 2 MHz + * Generator 3: DFLL48M / 8MHz + */ + atmel,assigned-clocks = <&gclk 3>; + atmel,assigned-clock-names = "GCLK"; }; diff --git a/dts/arm/atmel/samd21.dtsi b/dts/arm/atmel/samd21.dtsi index f8b12ed570ae9..790bfe007a686 100644 --- a/dts/arm/atmel/samd21.dtsi +++ b/dts/arm/atmel/samd21.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,14 +10,19 @@ / { aliases { tc-6 = &tc6; + + tcc-0 = &tcc0; + tcc-1 = &tcc1; + tcc-2 = &tcc2; }; soc { usb0: usb@41005000 { compatible = "atmel,sam0-usb"; - status = "disabled"; reg = <0x41005000 0x1000>; interrupts = <7 0>; + status = "disabled"; + num-bidir-endpoints = <8>; }; @@ -24,6 +30,8 @@ compatible = "atmel,sam0-dmac"; reg = <0x41004800 0x50>; interrupts = <6 0>; + status = "disabled"; + #dma-cells = <2>; }; @@ -33,6 +41,9 @@ interrupts = <21 0>; clocks = <&gclk 0x1d>, <&pm 0x20 14>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; tcc0: tcc@42002000 { @@ -41,6 +52,9 @@ interrupts = <15 0>; clocks = <&gclk 26>, <&pm 0x20 8>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <4>; counter-size = <24>; @@ -52,6 +66,9 @@ interrupts = <16 0>; clocks = <&gclk 26>, <&pm 0x20 9>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <2>; counter-size = <24>; @@ -63,6 +80,9 @@ interrupts = <17 0>; clocks = <&gclk 27>, <&pm 0x20 10>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <2>; counter-size = <16>; @@ -74,53 +94,83 @@ interrupts = <25 0>; clocks = <&gclk 33>, <&pm 0x20 18>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; +}; + +&rtc { + clocks = <&gclk 4>, <&pm 0x18 5>; + clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 4>; + atmel,assigned-clock-names = "GCLK"; }; &sercom0 { interrupts = <9 0>; clocks = <&gclk 0x14>, <&pm 0x20 2>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom1 { interrupts = <10 0>; clocks = <&gclk 0x15>, <&pm 0x20 3>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom2 { interrupts = <11 0>; clocks = <&gclk 0x16>, <&pm 0x20 4>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom3 { interrupts = <12 0>; clocks = <&gclk 0x17>, <&pm 0x20 5>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom4 { interrupts = <13 0>; clocks = <&gclk 0x18>, <&pm 0x20 6>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom5 { interrupts = <14 0>; clocks = <&gclk 0x19>, <&pm 0x20 7>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &tc4 { interrupts = <19 0>; clocks = <&gclk 0x1c>, <&pm 0x20 12>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &adc { - clocks = <&gclk 0x1e>, <&pm 0x20 16>; - clock-names = "GCLK", "PM"; interrupts = <23 0>; interrupt-names = "resrdy"; + clocks = <&gclk 0x1e>, <&pm 0x20 16>; + clock-names = "GCLK", "PM"; + /* + * 2.1 MHz is ADC max clock + * 8 MHz GCLK / 4 = 2 MHz + * Generator 3: DFLL48M / 8MHz + */ + atmel,assigned-clocks = <&gclk 3>; + atmel,assigned-clock-names = "GCLK"; }; diff --git a/dts/arm/atmel/samd2x.dtsi b/dts/arm/atmel/samd2x.dtsi index c247daffc1a51..b889c1a6cdd3c 100644 --- a/dts/arm/atmel/samd2x.dtsi +++ b/dts/arm/atmel/samd2x.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Google LLC. + * Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +14,22 @@ / { aliases { + adc-0 = &adc; + + port-a = &porta; + port-b = &portb; + + rtc = &rtc; + + sercom-0 = &sercom0; + sercom-1 = &sercom1; + sercom-2 = &sercom2; + sercom-3 = &sercom3; + sercom-4 = &sercom4; + sercom-5 = &sercom5; + + tc-4 = &tc4; + watchdog0 = &wdog; }; @@ -25,9 +42,10 @@ #size-cells = <0>; cpu0: cpu@0 { - device_type = "cpu"; compatible = "arm,cortex-m0+"; reg = <0>; + + device_type = "cpu"; }; }; @@ -43,48 +61,38 @@ <0x0080A048 0x4>; }; - aliases { - port-a = &porta; - port-b = &portb; - adc-0 = &adc; - - sercom-0 = &sercom0; - sercom-1 = &sercom1; - sercom-2 = &sercom2; - sercom-3 = &sercom3; - sercom-4 = &sercom4; - sercom-5 = &sercom5; - - tc-4 = &tc4; - }; - soc { nvmctrl: nvmctrl@41004000 { compatible = "atmel,sam0-nvmctrl"; reg = <0x41004000 0x22>; interrupts = <5 0>; - lock-regions = <16>; #address-cells = <1>; #size-cells = <1>; + lock-regions = <16>; + flash0: flash@0 { compatible = "soc-nv-flash"; + write-block-size = <4>; }; }; pm: pm@40000400 { - compatible = "atmel,samd2x-pm"; + compatible = "atmel,sam0-mclk"; reg = <0x40000400 0x400>; interrupts = <0 0>; + #clock-cells = <2>; }; gclk: gclk@40000c00 { - compatible = "atmel,samd2x-gclk"; + compatible = "atmel,sam0-gclk"; reg = <0x40000c00 0x400>; + #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; }; eic: eic@40001800 { @@ -148,29 +156,34 @@ tc4: tc@42003000 { compatible = "atmel,sam0-tc32"; reg = <0x42003000 0x20>; + status = "disabled"; }; pinctrl: pinctrl@41004400 { compatible = "atmel,sam0-pinctrl"; + ranges = <0x41004400 0x41004400 0x100>; + #address-cells = <1>; #size-cells = <1>; - ranges = <0x41004400 0x41004400 0x100>; porta: gpio@41004400 { compatible = "atmel,sam0-gpio"; reg = <0x41004400 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + gpio-controller; }; portb: gpio@41004480 { compatible = "atmel,sam0-gpio"; reg = <0x41004480 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; }; @@ -178,27 +191,29 @@ compatible = "atmel,sam0-rtc"; reg = <0x40001400 0x1C>; interrupts = <3 0>; - clock-generator = <0>; + clocks = <&gclk 4 4>, <&pm 0x18 5>; + clock-names = "GCLK", "PM"; status = "disabled"; + + alarms-count = <1>; + cal-constant = <(1024 * 976)>; }; adc: adc@42004000 { compatible = "atmel,sam0-adc"; reg = <0x42004000 0x2B>; + status = "disabled"; - /* - * 2.1 MHz max, so clock it with the - * 8 MHz GCLK / 4 = 2 MHz - */ - gclk = <3>; - prescaler = <4>; #io-channel-cells = <1>; + + prescaler = <4>; }; dac0: dac@42004800 { compatible = "atmel,sam0-dac"; - status = "disabled"; reg = <0x42004800 0x10>; + status = "disabled"; + #io-channel-cells = <0>; }; }; diff --git a/dts/arm/atmel/samd5x.dtsi b/dts/arm/atmel/samd5x.dtsi index b64abc5de4554..65123ef0e1dad 100644 --- a/dts/arm/atmel/samd5x.dtsi +++ b/dts/arm/atmel/samd5x.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 ML!PA Consulting GmbH + * Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,28 +12,6 @@ #include / { - chosen { - zephyr,flash-controller = &nvmctrl; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-m4f"; - reg = <0>; - #address-cells = <1>; - #size-cells = <1>; - - mpu: mpu@e000ed90 { - compatible = "arm,armv7m-mpu"; - reg = <0xe000ed90 0x40>; - }; - }; - }; - aliases { adc-0 = &adc0; adc-1 = &adc1; @@ -42,6 +21,8 @@ port-c = &portc; port-d = &portd; + rtc = &rtc; + sercom-0 = &sercom0; sercom-1 = &sercom1; sercom-2 = &sercom2; @@ -66,7 +47,29 @@ }; chosen { + zephyr,flash-controller = &nvmctrl; zephyr,entropy = &trng; + zephyr,flash-controller = &nvmctrl; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m4f"; + reg = <0>; + + #address-cells = <1>; + #size-cells = <1>; + + device_type = "cpu"; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; }; soc { @@ -89,28 +92,40 @@ }; mclk: mclk@40000800 { - compatible = "atmel,samd5x-mclk"; + compatible = "atmel,sam0-mclk"; reg = <0x40000800 0x400>; + #clock-cells = <2>; }; + osc32kctrl: osc32kctrl@40001400 { + compatible = "atmel,sam0-osc32kctrl"; + reg = <0x40001400 0x400>; + #clock-cells = <0>; + #atmel,assigned-clock-cells = <1>; + }; + gclk: gclk@40001c00 { - compatible = "atmel,samd5x-gclk"; + compatible = "atmel,sam0-gclk"; reg = <0x40001c00 0x400>; + #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; }; nvmctrl: nvmctrl@41004000 { compatible = "atmel,sam0-nvmctrl"; reg = <0x41004000 0x22>; interrupts = <29 0>, <30 0>; - lock-regions = <32>; #address-cells = <1>; #size-cells = <1>; + lock-regions = <32>; + flash0: flash@0 { compatible = "soc-nv-flash"; + write-block-size = <8>; }; }; @@ -119,6 +134,8 @@ compatible = "atmel,sam0-dmac"; reg = <0x4100A000 0x50>; interrupts = <31 0>, <32 0>, <33 0>, <34 0>, <35 0>; + status = "disabled"; + #dma-cells = <2>; }; @@ -161,118 +178,144 @@ compatible = "atmel,sam0-sercom"; reg = <0x40003000 0x40>; interrupts = <46 0>, <47 0>, <48 0>, <49 0>; - status = "disabled"; clocks = <&gclk 7>, <&mclk 0x14 12>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; sercom1: sercom@40003400 { compatible = "atmel,sam0-sercom"; reg = <0x40003400 0x40>; interrupts = <50 0>, <51 0>, <52 0>, <53 0>; - status = "disabled"; clocks = <&gclk 8>, <&mclk 0x14 13>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; sercom2: sercom@41012000 { compatible = "atmel,sam0-sercom"; reg = <0x41012000 0x40>; interrupts = <54 0>, <55 0>, <56 0>, <57 0>; - status = "disabled"; clocks = <&gclk 23>, <&mclk 0x18 9>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; sercom3: sercom@41014000 { compatible = "atmel,sam0-sercom"; reg = <0x41014000 0x40>; interrupts = <58 0>, <59 0>, <60 0>, <61 0>; - status = "disabled"; clocks = <&gclk 24>, <&mclk 0x18 10>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; sercom4: sercom@43000000 { compatible = "atmel,sam0-sercom"; reg = <0x43000000 0x40>; interrupts = <62 0>, <63 0>, <64 0>, <65 0>; - status = "disabled"; clocks = <&gclk 34>, <&mclk 0x20 0>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; sercom5: sercom@43000400 { compatible = "atmel,sam0-sercom"; reg = <0x43000400 0x40>; interrupts = <66 0>, <67 0>, <68 0>, <69 0>; - status = "disabled"; clocks = <&gclk 35>, <&mclk 0x20 1>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; sercom6: sercom@43000800 { compatible = "atmel,sam0-sercom"; reg = <0x43000800 0x40>; interrupts = <70 0>, <71 0>, <72 0>, <73 0>; - status = "disabled"; clocks = <&gclk 36>, <&mclk 0x20 2>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; sercom7: sercom@43000c00 { compatible = "atmel,sam0-sercom"; reg = <0x43000C00 0x40>; interrupts = <74 0>, <75 0>, <76 0>, <77 0>; - status = "disabled"; clocks = <&gclk 37>, <&mclk 0x20 3>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; pinctrl: pinctrl@41008000 { compatible = "atmel,sam0-pinctrl"; + ranges = <0x41008000 0x41008000 0x200>; + #address-cells = <1>; #size-cells = <1>; - ranges = <0x41008000 0x41008000 0x200>; porta: gpio@41008000 { compatible = "atmel,sam0-gpio"; reg = <0x41008000 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; portb: gpio@41008080 { compatible = "atmel,sam0-gpio"; reg = <0x41008080 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; portc: gpio@41008100 { compatible = "atmel,sam0-gpio"; reg = <0x41008100 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; portd: gpio@41008180 { compatible = "atmel,sam0-gpio"; reg = <0x41008180 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; }; usb0: usb@41000000 { compatible = "atmel,sam0-usb"; - status = "disabled"; reg = <0x41000000 0x1000>; interrupts = <80 0>, <81 0>, <82 0>, <83 0>; + status = "disabled"; + num-bidir-endpoints = <8>; }; @@ -284,10 +327,16 @@ rtc: rtc@40002400 { compatible = "atmel,sam0-rtc"; - reg = <0x40002400 0x1C>; + reg = <0x40002400 0x40>; interrupts = <11 0>; - clock-generator = <0>; + clocks = <&osc32kctrl>, <&mclk 0x14 9>; + clock-names = "OSC32KCTRL", "MCLK"; + atmel,assigned-clocks = <&osc32kctrl 0>; + atmel,assigned-clock-names = "OSC32KCTRL"; status = "disabled"; + + alarms-count = <2>; + cal-constant = <(8192 * 128)>; }; adc0: adc@43001c00 { @@ -295,18 +344,23 @@ reg = <0x43001C00 0x4A>; interrupts = <118 0>, <119 0>; interrupt-names = "overrun", "resrdy"; - + clocks = <&gclk 40>, <&mclk 0x20 7>; + clock-names = "GCLK", "MCLK"; /* - * 16 MHz max, source clock must not exceed 100 MHz. + * 16 MHz is ADC max clock, source clock must not exceed 100 MHz. * - table 54-8, section 54.6, page 2020 * - table 54-24, section 54.10.4, page 2031 - * -> 48 MHz GCLK(2) / 4 = 12 MHz + * 48 MHz GCLK / 4 = 12 MHz + * Generator 2: DFLL48M / 4 */ - gclk = <2>; - prescaler = <4>; + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + + status = "disabled"; + #io-channel-cells = <1>; - clocks = <&gclk 40>, <&mclk 0x20 7>; - clock-names = "GCLK", "MCLK"; + + prescaler = <4>; calib-offset = <0>; }; @@ -315,18 +369,22 @@ reg = <0x43002000 0x4A>; interrupts = <120 0>, <121 0>; interrupt-names = "overrun", "resrdy"; - + clocks = <&gclk 41>, <&mclk 0x20 8>; + clock-names = "GCLK", "MCLK"; /* - * 16 MHz max, source clock must not exceed 100 MHz. + * 16 MHz is ADC max clock, source clock must not exceed 100 MHz. * - table 54-8, section 54.6, page 2020 * - table 54-24, section 54.10.4, page 2031 - * -> 48 MHz GCLK(2) / 4 = 12 MHz + * 48 MHz GCLK / 4 = 12 MHz + * Generator 2: DFLL48M / 4 */ - gclk = <2>; - prescaler = <4>; + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + #io-channel-cells = <1>; - clocks = <&gclk 41>, <&mclk 0x20 8>; - clock-names = "GCLK", "MCLK"; + + prescaler = <4>; calib-offset = <14>; }; @@ -336,6 +394,9 @@ interrupts = <107 0>; clocks = <&gclk 9>, <&mclk 0x14 14>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; tc2: tc@4101a000 { @@ -344,6 +405,9 @@ interrupts = <109 0>; clocks = <&gclk 26>, <&mclk 0x18 13>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; tc4: tc@42001400 { @@ -352,6 +416,9 @@ interrupts = <111 0>; clocks = <&gclk 30>, <&mclk 0x1c 5>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; tc6: tc@43001400 { @@ -360,6 +427,9 @@ interrupts = <113 0>; clocks = <&gclk 39>, <&mclk 0x20 5>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; }; tcc0: tcc@41016000 { @@ -369,6 +439,10 @@ <90 0>, <91 0>; clocks = <&gclk 25>, <&mclk 0x18 11>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <6>; counter-size = <24>; }; @@ -379,6 +453,10 @@ interrupts = <92 0>, <93 0>, <94 0>, <95 0>, <96 0>; clocks = <&gclk 25>, <&mclk 0x18 12>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <4>; counter-size = <24>; }; @@ -389,6 +467,10 @@ interrupts = <97 0>, <98 0>, <99 0>, <100 0>; clocks = <&gclk 29>, <&mclk 0x1c 3>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <3>; counter-size = <16>; }; @@ -399,6 +481,10 @@ interrupts = <101 0>, <102 0>, <103 0>; clocks = <&gclk 29>, <&mclk 0x1c 4>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <2>; counter-size = <16>; }; @@ -409,6 +495,10 @@ interrupts = <104 0>, <105 0>, <106 0>; clocks = <&gclk 38>, <&mclk 0x20 4>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <2>; counter-size = <16>; }; diff --git a/dts/arm/atmel/same5x.dtsi b/dts/arm/atmel/same5x.dtsi index 750094cfafef9..f7b0418c4c142 100644 --- a/dts/arm/atmel/same5x.dtsi +++ b/dts/arm/atmel/same5x.dtsi @@ -1,6 +1,7 @@ /* * Copyright (c) 2020 Stephanos Ioannidis * Copyright (c) 2023 Sebastian Schlupp + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,15 +15,17 @@ reg = <0x42000800 0x400>; interrupts = <84 0>; interrupt-names = "gmac"; + status = "disabled"; + num-queues = <1>; local-mac-address = [00 00 00 00 00 00]; - status = "disabled"; }; mdio: mdio@42000800 { compatible = "atmel,sam-mdio"; reg = <0x42000800 0x400>; status = "disabled"; + #address-cells = <1>; #size-cells = <0>; }; @@ -34,9 +37,12 @@ interrupt-names = "int0", "int1"; clocks = <&gclk 27>, <&mclk 0x10 17>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; divider = <12>; - status = "disabled"; }; can1: can@42000400 { @@ -46,9 +52,12 @@ interrupt-names = "int0", "int1"; clocks = <&gclk 28>, <&mclk 0x10 18>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; divider = <12>; - status = "disabled"; }; }; }; diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index fa954af21f5ca..3896a1cacba58 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -5,480 +5,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include -#include -#include - -/ { - aliases { - watchdog0 = &wdt; - }; - - chosen { - zephyr,flash-controller = &eefc; - }; - - chosen { - zephyr,entropy = &trng; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-m7"; - reg = <0>; - #address-cells = <1>; - #size-cells = <1>; - - mpu: mpu@e000ed90 { - compatible = "arm,armv7m-mpu"; - reg = <0xe000ed90 0x40>; - }; - }; - }; - - sram0: memory@20400000 { - compatible = "mmio-sram"; - }; - - soc { - pmc: pmc@400e0600 { - compatible = "atmel,sam-pmc"; - reg = <0x400e0600 0x200>; - interrupts = <5 0>; - #clock-cells = <2>; - status = "okay"; - }; - - supc: supc@400e1810 { - compatible = "atmel,sam-supc"; - reg = <0x400e1810 0x20>; - #wakeup-source-id-cells = <1>; - status = "okay"; - }; - - eefc: flash-controller@400e0c00 { - compatible = "atmel,sam-flash-controller"; - reg = <0x400e0c00 0x200>; - interrupts = <6 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 6>; - - #address-cells = <1>; - #size-cells = <1>; - #erase-block-cells = <2>; - - flash0: flash@400000 { - compatible = "atmel,sam-flash", "soc-nv-flash"; - write-block-size = <16>; - erase-block-size = <8192>; - }; - }; - - wdt: watchdog@400e1850 { - compatible = "atmel,sam-watchdog"; - reg = <0x400e1850 0xc>; - interrupts = <4 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 4>; - status = "disabled"; - }; - - twihs0: i2c@40018000 { - compatible = "atmel,sam-i2c-twihs"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x40018000 0x12B>; - interrupts = <19 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 19>; - status = "disabled"; - }; - - twihs1: i2c@4001c000 { - compatible = "atmel,sam-i2c-twihs"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x4001c000 0x12B>; - interrupts = <20 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 20>; - status = "disabled"; - }; - - twihs2: i2c@40060000 { - compatible = "atmel,sam-i2c-twihs"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x40060000 0x12B>; - interrupts = <41 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 41>; - status = "disabled"; - }; - - spi0: spi@40008000 { - compatible = "atmel,sam-spi"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x40008000 0x4000>; - interrupts = <21 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 21>; - status = "disabled"; - }; - - spi1: spi@40058000 { - compatible = "atmel,sam-spi"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x40058000 0x4000>; - interrupts = <42 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 42>; - status = "disabled"; - }; - - uart0: uart@400e0800 { - compatible = "atmel,sam-uart"; - reg = <0x400e0800 0x100>; - interrupts = <7 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 7>; - status = "disabled"; - }; - - uart1: uart@400e0a00 { - compatible = "atmel,sam-uart"; - reg = <0x400e0a00 0x100>; - interrupts = <8 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 8>; - status = "disabled"; - }; - - uart2: uart@400e1a00 { - compatible = "atmel,sam-uart"; - reg = <0x400e1a00 0x100>; - interrupts = <44 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 44>; - status = "disabled"; - }; - - uart3: uart@400e1c00 { - compatible = "atmel,sam-uart"; - reg = <0x400e1c00 0x100>; - interrupts = <45 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 45>; - status = "disabled"; - }; - - uart4: uart@400e1e00 { - compatible = "atmel,sam-uart"; - reg = <0x400e1e00 0x100>; - interrupts = <46 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 46>; - status = "disabled"; - }; - - usart0: usart@40024000 { - compatible = "atmel,sam-usart"; - reg = <0x40024000 0x100>; - interrupts = <13 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 13>; - status = "disabled"; - }; - - usart1: usart@40028000 { - compatible = "atmel,sam-usart"; - reg = <0x40028000 0x100>; - interrupts = <14 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 14>; - status = "disabled"; - }; - - usart2: usart@4002c000 { - compatible = "atmel,sam-usart"; - reg = <0x4002c000 0x100>; - interrupts = <15 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 15>; - status = "disabled"; - }; - - afec0: adc@4003c000 { - compatible = "atmel,sam-afec"; - reg = <0x4003c000 0x100>; - interrupts = <29 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 29>; - status = "disabled"; - #io-channel-cells = <1>; - }; - - afec1: adc@40064000 { - compatible = "atmel,sam-afec"; - reg = <0x40064000 0x100>; - interrupts = <40 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 40>; - status = "disabled"; - #io-channel-cells = <1>; - }; - - dacc: dacc@40040000 { - compatible = "atmel,sam-dac"; - reg = <0x40040000 0x100>; - interrupts = <30 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 30>; - status = "disabled"; - #io-channel-cells = <1>; - }; - - pinctrl: pinctrl@400e0e00 { - compatible = "atmel,sam-pinctrl"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x400e0e00 0x400e0e00 0xa00>; - - pioa: gpio@400e0e00 { - compatible = "atmel,sam-gpio"; - reg = <0x400e0e00 0x190>; - interrupts = <10 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 10>; - gpio-controller; - #gpio-cells = <2>; - #atmel,pin-cells = <2>; - }; - - piob: gpio@400e1000 { - compatible = "atmel,sam-gpio"; - reg = <0x400e1000 0x190>; - interrupts = <11 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 11>; - gpio-controller; - #gpio-cells = <2>; - #atmel,pin-cells = <2>; - }; - - pioc: gpio@400e1200 { - compatible = "atmel,sam-gpio"; - reg = <0x400e1200 0x190>; - interrupts = <12 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 12>; - gpio-controller; - #gpio-cells = <2>; - #atmel,pin-cells = <2>; - }; - - piod: gpio@400e1400 { - compatible = "atmel,sam-gpio"; - reg = <0x400e1400 0x190>; - interrupts = <16 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 16>; - gpio-controller; - #gpio-cells = <2>; - #atmel,pin-cells = <2>; - }; - - pioe: gpio@400e1600 { - compatible = "atmel,sam-gpio"; - reg = <0x400e1600 0x190>; - interrupts = <17 1>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 17>; - gpio-controller; - #gpio-cells = <2>; - #atmel,pin-cells = <2>; - }; - }; - - pwm0: pwm0@40020000 { - compatible = "atmel,sam-pwm"; - reg = <0x40020000 0x4000>; - interrupts = <31 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 31>; - status = "disabled"; - prescaler = <10>; - divider = <1>; - #pwm-cells = <3>; - }; - - pwm1: pwm1@4005c000 { - compatible = "atmel,sam-pwm"; - reg = <0x4005c000 0x4000>; - interrupts = <60 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 60>; - status = "disabled"; - prescaler = <10>; - divider = <1>; - #pwm-cells = <3>; - }; - - usbhs: usbd@40038000 { - compatible = "atmel,sam-usbhs"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x40038000 0x4000>; - interrupts = <34 0>; - interrupt-names = "usbhs"; - maximum-speed = "high-speed"; - num-bidir-endpoints = <10>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 34>; - status = "disabled"; - }; - - gmac: ethernet@40050000 { - compatible = "atmel,sam-gmac"; - reg = <0x40050000 0x4000>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; - interrupts = <39 0>, <66 0>, <67 0>; - interrupt-names = "gmac", "q1", "q2"; - num-queues = <3>; - local-mac-address = [00 00 00 00 00 00]; - status = "disabled"; - }; - - mdio: mdio@40050000 { - compatible = "atmel,sam-mdio"; - reg = <0x40050000 0x4000>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; - status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; - }; - - tc0: tc@4000c000 { - compatible = "atmel,sam-tc"; - reg = <0x4000c000 0x100>; - interrupts = <23 0 - 24 0 - 25 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 23>, - <&pmc PMC_TYPE_PERIPHERAL 24>, - <&pmc PMC_TYPE_PERIPHERAL 25>; - status = "disabled"; - - qdec { - compatible = "atmel,sam-tc-qdec"; - status = "disabled"; - }; - }; - - tc1: tc@40010000 { - compatible = "atmel,sam-tc"; - reg = <0x40010000 0x100>; - interrupts = <26 0 - 27 0 - 28 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 26>, - <&pmc PMC_TYPE_PERIPHERAL 27>, - <&pmc PMC_TYPE_PERIPHERAL 28>; - status = "disabled"; - - qdec { - compatible = "atmel,sam-tc-qdec"; - status = "disabled"; - }; - }; - - tc2: tc@40014000 { - compatible = "atmel,sam-tc"; - reg = <0x40014000 0x100>; - interrupts = <47 0 - 48 0 - 49 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 47>, - <&pmc PMC_TYPE_PERIPHERAL 48>, - <&pmc PMC_TYPE_PERIPHERAL 49>; - status = "disabled"; - - qdec { - compatible = "atmel,sam-tc-qdec"; - status = "disabled"; - }; - }; - - tc3: tc@40054000 { - compatible = "atmel,sam-tc"; - reg = <0x40054000 0x100>; - interrupts = <50 0 - 51 0 - 52 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 50>, - <&pmc PMC_TYPE_PERIPHERAL 51>, - <&pmc PMC_TYPE_PERIPHERAL 52>; - status = "disabled"; - - qdec { - compatible = "atmel,sam-tc-qdec"; - status = "disabled"; - }; - }; - - trng: random@40070000 { - compatible = "atmel,sam-trng"; - reg = <0x40070000 0x4000>; - interrupts = <57 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 57>; - status = "okay"; - }; - - xdmac: dma0: dma-controller@40078000 { - compatible = "atmel,sam-xdmac"; - reg = <0x40078000 0x400>; - interrupts = <58 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 58>; - #dma-cells = <2>; - status = "disabled"; - }; - - ssc: ssc@40004000 { - compatible = "atmel,sam-ssc"; - reg = <0x40004000 0x4000>; - interrupts = <22 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 22>; - status = "disabled"; - }; - - can0: can@40030000 { - compatible = "atmel,sam-can"; - reg = <0x40030000 0x100>, <0x40088110 0x04>; - reg-names = "m_can", "dma_base"; - interrupts = <35 0>, <36 0>; - interrupt-names = "int0", "int1"; - clocks = <&pmc PMC_TYPE_PERIPHERAL 35>; - divider = <6>; - bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; - status = "disabled"; - }; - - can1: can@40034000 { - compatible = "atmel,sam-can"; - reg = <0x40034000 0x100>, <0x40088114 0x4>; - reg-names = "m_can", "dma_base"; - interrupts = <37 0>, <38 0>; - interrupt-names = "int0", "int1"; - clocks = <&pmc PMC_TYPE_PERIPHERAL 37>; - divider = <6>; - bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; - status = "disabled"; - }; - - rstc: rstc@400e1800 { - compatible = "atmel,sam-rstc"; - reg = <0x400e1800 0x10>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 1>; - user-nrst; - }; - - rtc: rtc@400e1860 { - compatible = "atmel,sam-rtc"; - reg = <0x400e1860 0x100>; - interrupts = <2 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 2>; - alarms-count = <1>; - status = "disabled"; - }; - }; -}; - -&nvic { - arm,num-irq-priority-bits = <3>; -}; +#include diff --git a/dts/arm/atmel/same70b.dtsi b/dts/arm/atmel/same70b.dtsi index 9f222f8d2acf2..7e250e2c250c2 100644 --- a/dts/arm/atmel/same70b.dtsi +++ b/dts/arm/atmel/same70b.dtsi @@ -4,10 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - -&gmac { - interrupts = <39 0>, <66 0>, <67 0>, <71 0>, <72 0>, <73 0>; - interrupt-names = "gmac", "q1", "q2", "q3", "q4", "q5"; - num-queues = <6>; -}; +#include diff --git a/dts/arm/atmel/same70q19.dtsi b/dts/arm/atmel/same70q19.dtsi deleted file mode 100644 index abf0e5b67e5a5..0000000000000 --- a/dts/arm/atmel/same70q19.dtsi +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2018 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "dma_atmel_same70.h" - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(256)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(512)>; - erase-blocks = <&eefc 8 2048>, <&eefc 62 8192>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/same70q19b.dtsi b/dts/arm/atmel/same70q19b.dtsi deleted file mode 100644 index cc97dc64458b3..0000000000000 --- a/dts/arm/atmel/same70q19b.dtsi +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2018 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "dma_atmel_same70.h" - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(256)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(512)>; - erase-blocks = <&eefc 8 2048>, <&eefc 62 8192>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/same70q21.dtsi b/dts/arm/atmel/same70q21.dtsi deleted file mode 100644 index 4138d6ca0667f..0000000000000 --- a/dts/arm/atmel/same70q21.dtsi +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2018 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "dma_atmel_same70.h" - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(384)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(2048)>; - erase-blocks = <&eefc 8 2048>, <&eefc 252 8192>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/same70q21b.dtsi b/dts/arm/atmel/same70q21b.dtsi deleted file mode 100644 index d6fe0fa4a2e74..0000000000000 --- a/dts/arm/atmel/same70q21b.dtsi +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018 Linaro Limited - * Copyright (c) 2020 Stephanos Ioannidis - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "dma_atmel_same70.h" - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(384)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(2048)>; - erase-blocks = <&eefc 8 2048>, <&eefc 252 8192>; - }; - }; - }; -}; diff --git a/dts/arm/atmel/same70x19.dtsi b/dts/arm/atmel/same70x19.dtsi new file mode 100644 index 0000000000000..9326ce68abd1a --- /dev/null +++ b/dts/arm/atmel/same70x19.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2018 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/dts/arm/atmel/same70x19b.dtsi b/dts/arm/atmel/same70x19b.dtsi new file mode 100644 index 0000000000000..93977b80b1eaa --- /dev/null +++ b/dts/arm/atmel/same70x19b.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2018 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/dts/arm/atmel/same70x20.dtsi b/dts/arm/atmel/same70x20.dtsi new file mode 100644 index 0000000000000..f7e248374fae9 --- /dev/null +++ b/dts/arm/atmel/same70x20.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2018 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/dts/arm/atmel/same70x20b.dtsi b/dts/arm/atmel/same70x20b.dtsi new file mode 100644 index 0000000000000..2fdb011e0be22 --- /dev/null +++ b/dts/arm/atmel/same70x20b.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2018 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/dts/arm/atmel/same70x21.dtsi b/dts/arm/atmel/same70x21.dtsi new file mode 100644 index 0000000000000..f76769a471003 --- /dev/null +++ b/dts/arm/atmel/same70x21.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2018 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/dts/arm/atmel/same70x21b.dtsi b/dts/arm/atmel/same70x21b.dtsi new file mode 100644 index 0000000000000..ec646fecb7511 --- /dev/null +++ b/dts/arm/atmel/same70x21b.dtsi @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2018 Linaro Limited + * Copyright (c) 2020 Stephanos Ioannidis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/dts/arm/atmel/saml21.dtsi b/dts/arm/atmel/saml21.dtsi index 524c28d3d2def..de2f456e200a1 100644 --- a/dts/arm/atmel/saml21.dtsi +++ b/dts/arm/atmel/saml21.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Argentum Systems Ltd. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,28 +8,22 @@ #include / { - soc { - usb0: usb@41000000 { - compatible = "atmel,sam0-usb"; - status = "disabled"; - reg = <0x41000000 0x1000>; - interrupts = <6 0>; - num-bidir-endpoints = <8>; - }; - - dmac: dmac@44000400 { - compatible = "atmel,sam0-dmac"; - reg = <0x44000400 0x50>; - interrupts = <5 0>; - #dma-cells = <2>; - }; + aliases { + tcc-0 = &tcc0; + tcc-1 = &tcc1; + tcc-2 = &tcc2; + }; + soc { tcc0: tcc@42001400 { compatible = "atmel,sam0-tcc"; reg = <0x42001400 0x80>; interrupts = <14 0>; clocks = <&gclk 25>, <&mclk 0x1c 5>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <4>; counter-size = <24>; @@ -40,6 +35,9 @@ interrupts = <15 0>; clocks = <&gclk 25>, <&mclk 0x1c 6>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <4>; counter-size = <24>; @@ -51,6 +49,9 @@ interrupts = <16 0>; clocks = <&gclk 26>, <&mclk 0x1c 7>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; channels = <2>; counter-size = <16>; @@ -62,48 +63,64 @@ interrupts = <24 0>; clocks = <&gclk 32>, <&mclk 0x1c 12>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom0 { interrupts = <8 0>; clocks = <&gclk 18>, <&mclk 0x1c 0>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom1 { interrupts = <9 0>; clocks = <&gclk 19>, <&mclk 0x1c 1>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom2 { interrupts = <10 0>; clocks = <&gclk 20>, <&mclk 0x1c 2>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom3 { interrupts = <11 0>; clocks = <&gclk 21>, <&mclk 0x1c 3>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom4 { interrupts = <12 0>; clocks = <&gclk 22>, <&mclk 0x1c 4>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom5 { interrupts = <13 0>; clocks = <&gclk 24>, <&mclk 0x20 1>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &tc4 { interrupts = <21 0>; clocks = <&gclk 29>, <&mclk 0x20 2>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &adc { @@ -111,4 +128,11 @@ interrupt-names = "resrdy"; clocks = <&gclk 30>, <&mclk 0x20 3>; clock-names = "GCLK", "MCLK"; + /* + * 16 MHz is ADC max clock + * 48 MHz DFLL / 2 / 2 = 12 MHz + * Generator 3: 48MHz + */ + atmel,assigned-clocks = <&gclk 3>; + atmel,assigned-clock-names = "GCLK"; }; diff --git a/dts/arm/atmel/saml2x.dtsi b/dts/arm/atmel/saml2x.dtsi index 2bad616c81af9..f682ac0126aa2 100644 --- a/dts/arm/atmel/saml2x.dtsi +++ b/dts/arm/atmel/saml2x.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Argentum Systems Ltd. + * Copyright (c) 2024-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,12 +14,28 @@ / { aliases { + adc-0 = &adc; + + port-a = &porta; + port-b = &portb; + + sercom-0 = &sercom0; + sercom-1 = &sercom1; + sercom-2 = &sercom2; + sercom-3 = &sercom3; + sercom-4 = &sercom4; + sercom-5 = &sercom5; + + rtc = &rtc; + + tc-4 = &tc4; + watchdog0 = &wdog; }; chosen { - zephyr,flash-controller = &nvmctrl; zephyr,entropy = &trng; + zephyr,flash-controller = &nvmctrl; }; cpus { @@ -26,9 +43,10 @@ #size-cells = <0>; cpu0: cpu@0 { - device_type = "cpu"; compatible = "arm,cortex-m0+"; reg = <0>; + + device_type = "cpu"; }; }; @@ -50,41 +68,49 @@ compatible = "atmel,sam0-nvmctrl"; reg = <0x41004000 0x22>; interrupts = <4 0>; - lock-regions = <16>; #address-cells = <1>; #size-cells = <1>; + lock-regions = <16>; + flash0: flash@0 { compatible = "soc-nv-flash"; reg = <0 0x40000>; + write-block-size = <4>; }; }; - pm: pm@40000400 { - compatible = "atmel,saml2x-pm"; + mclk: mclk@40000400 { + compatible = "atmel,sam0-mclk"; reg = <0x40000400 0x400>; - interrupts = <0 0>; + #clock-cells = <2>; }; - mclk: mclk@40000400 { - compatible = "atmel,saml2x-mclk"; - reg = <0x40000400 0x400>; - #clock-cells = <2>; + osc32kctrl: osc32kctrl@40001000 { + compatible = "atmel,sam0-osc32kctrl"; + reg = <0x40001000 0x400>; + + #clock-cells = <0>; + #atmel,assigned-clock-cells = <1>; }; gclk: gclk@40001800 { - compatible = "atmel,saml2x-gclk"; + compatible = "atmel,sam0-gclk"; reg = <0x40001800 0x400>; + #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; }; dmac: dmac@44000400 { compatible = "atmel,sam0-dmac"; reg = <0x44000400 0x400>; interrupts = <5 0>; + status = "disabled"; + #dma-cells = <2>; }; @@ -139,57 +165,66 @@ tc4: tc@43000800 { compatible = "atmel,sam0-tc32"; reg = <0x43000800 0x34>; + status = "disabled"; }; pinctrl: pinctrl@40002800 { compatible = "atmel,sam0-pinctrl"; + ranges = <0x40002800 0x40002800 0x100>; + #address-cells = <1>; #size-cells = <1>; - ranges = <0x40002800 0x40002800 0x100>; porta: gpio@40002800 { compatible = "atmel,sam0-gpio"; reg = <0x40002800 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + gpio-controller; }; portb: gpio@40002880 { compatible = "atmel,sam0-gpio"; reg = <0x40002880 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; }; rtc: rtc@40002000 { compatible = "atmel,sam0-rtc"; - reg = <0x40002000 0x1c>; + reg = <0x40002000 0x44>; interrupts = <2 0>; - clock-generator = <0>; + clocks = <&osc32kctrl>, <&mclk 0x14 8>; + clock-names = "OSC32KCTRL", "MCLK"; + atmel,assigned-clocks = <&osc32kctrl 0>; + atmel,assigned-clock-names = "OSC32KCTRL"; status = "disabled"; + + alarms-count = <1>; + cal-constant = <(8192 * 128)>; }; adc: adc@43000c00 { compatible = "atmel,sam0-adc"; reg = <0x43000c00 0x30>; + status = "disabled"; - /* - * 16 MHz max, so clock it with the - * 48 MHz DFLL / 2 / 2 = 12 MHz - */ - gclk = <3>; - prescaler = <2>; #io-channel-cells = <1>; + + prescaler = <2>; }; dac: dac@42003000 { compatible = "atmel,sam0-dac"; - status = "disabled"; reg = <0x42003000 0x1a>; + status = "disabled"; + #io-channel-cells = <0>; }; @@ -198,6 +233,15 @@ reg = <0x42003800 0x24>; interrupts = <27 0>; }; + + usb0: usb@41000000 { + compatible = "atmel,sam0-usb"; + reg = <0x41000000 0x1000>; + interrupts = <6 0>; + status = "disabled"; + + num-bidir-endpoints = <8>; + }; }; }; diff --git a/dts/arm/atmel/samr21.dtsi b/dts/arm/atmel/samr21.dtsi index 786597c3ca31f..85686c1d37bc6 100644 --- a/dts/arm/atmel/samr21.dtsi +++ b/dts/arm/atmel/samr21.dtsi @@ -1,10 +1,11 @@ /* * Copyright (c) 2019 Benjamin Valentin + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ -#include +#include / { aliases { @@ -12,30 +13,17 @@ }; soc { - usb0: usb@41005000 { - compatible = "atmel,sam0-usb"; - status = "disabled"; - reg = <0x41005000 0x1000>; - interrupts = <7 0>; - num-bidir-endpoints = <8>; - }; - - dmac: dmac@41004800 { - compatible = "atmel,sam0-dmac"; - reg = <0x41004800 0x50>; - interrupts = <6 0>; - #dma-cells = <2>; - }; - pinctrl: pinctrl@41004400 { ranges = <0x41004400 0x41004400 0x180>; portc: gpio@41004500 { compatible = "atmel,sam0-gpio"; reg = <0x41004500 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; }; @@ -43,87 +31,5 @@ compatible = "atmel,sam0-pinmux"; reg = <0x41004500 0x80>; }; - - tcc0: tcc@42002000 { - compatible = "atmel,sam0-tcc"; - reg = <0x42002000 0x80>; - interrupts = <15 0>; - clocks = <&gclk 26>, <&pm 0x20 8>; - clock-names = "GCLK", "PM"; - - channels = <4>; - counter-size = <24>; - }; - - tcc1: tcc@42002400 { - compatible = "atmel,sam0-tcc"; - reg = <0x42002400 0x80>; - interrupts = <16 0>; - clocks = <&gclk 26>, <&pm 0x20 9>; - clock-names = "GCLK", "PM"; - - channels = <2>; - counter-size = <24>; - }; - - tcc2: tcc@42002800 { - compatible = "atmel,sam0-tcc"; - reg = <0x42002800 0x80>; - interrupts = <17 0>; - clocks = <&gclk 27>, <&pm 0x20 10>; - clock-names = "GCLK", "PM"; - - channels = <2>; - counter-size = <16>; - }; }; }; - -&sercom0 { - interrupts = <9 0>; - clocks = <&gclk 0x14>, <&pm 0x20 2>; - clock-names = "GCLK", "PM"; -}; - -&sercom1 { - interrupts = <10 0>; - clocks = <&gclk 0x15>, <&pm 0x20 3>; - clock-names = "GCLK", "PM"; -}; - -&sercom2 { - interrupts = <11 0>; - clocks = <&gclk 0x16>, <&pm 0x20 4>; - clock-names = "GCLK", "PM"; -}; - -&sercom3 { - interrupts = <12 0>; - clocks = <&gclk 0x17>, <&pm 0x20 5>; - clock-names = "GCLK", "PM"; -}; - -&sercom4 { - interrupts = <13 0>; - clocks = <&gclk 0x18>, <&pm 0x20 6>; - clock-names = "GCLK", "PM"; -}; - -&sercom5 { - interrupts = <14 0>; - clocks = <&gclk 0x19>, <&pm 0x20 7>; - clock-names = "GCLK", "PM"; -}; - -&tc4 { - interrupts = <19 0>; - clocks = <&gclk 0x1c>, <&pm 0x20 12>; - clock-names = "GCLK", "PM"; -}; - -&adc { - clocks = <&gclk 0x1e>, <&pm 0x20 16>; - clock-names = "GCLK", "PM"; - interrupts = <23 0>; - interrupt-names = "resrdy"; -}; diff --git a/dts/arm/atmel/samr34.dtsi b/dts/arm/atmel/samr34.dtsi index 17164005d9939..c14a08b28cfc4 100644 --- a/dts/arm/atmel/samr34.dtsi +++ b/dts/arm/atmel/samr34.dtsi @@ -13,6 +13,8 @@ / { aliases { + port-c = &portc; + lora0 = &lora; }; @@ -23,9 +25,11 @@ portc: gpio@40002900 { compatible = "atmel,sam0-gpio"; reg = <0x40002900 0x80>; - gpio-controller; - #gpio-cells = <2>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + + gpio-controller; }; }; }; @@ -37,19 +41,22 @@ /* SERCOM4 is used to interface with the internal LoRa radio */ compatible = "atmel,sam0-spi"; status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + dipo = <0>; dopo = <1>; cs-gpios = <&portb 31 GPIO_ACTIVE_LOW>; - #address-cells = <1>; - #size-cells = <0>; pinctrl-0 = <&sercom4_default>; pinctrl-names = "default"; lora: sx1276@0 { compatible = "semtech,sx1276"; - status = "disabled"; reg = <0>; + status = "disabled"; + reset-gpios = <&portb 15 GPIO_ACTIVE_LOW>; /* nRST */ dio-gpios = <&portb 16 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>, /* DIO0 */ diff --git a/dts/arm/atmel/samv71.dtsi b/dts/arm/atmel/samv71.dtsi index 1b98c7674cbdc..a1a20fd8e07fb 100644 --- a/dts/arm/atmel/samv71.dtsi +++ b/dts/arm/atmel/samv71.dtsi @@ -4,6 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - -#include "dma_atmel_samv71.h" +#include diff --git a/dts/arm/atmel/samv71b.dtsi b/dts/arm/atmel/samv71b.dtsi index af84f625d840f..7e250e2c250c2 100644 --- a/dts/arm/atmel/samv71b.dtsi +++ b/dts/arm/atmel/samv71b.dtsi @@ -4,6 +4,4 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - -#include "dma_atmel_samv71.h" +#include diff --git a/dts/arm/atmel/samv71q21.dtsi b/dts/arm/atmel/samv71q21.dtsi deleted file mode 100644 index 8c76e658ab219..0000000000000 --- a/dts/arm/atmel/samv71q21.dtsi +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2019 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/dts/arm/atmel/samv71q21b.dtsi b/dts/arm/atmel/samv71q21b.dtsi deleted file mode 100644 index bc975414fd128..0000000000000 --- a/dts/arm/atmel/samv71q21b.dtsi +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2020 Stephanos Ioannidis - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/dts/arm/atmel/samv71x19.dtsi b/dts/arm/atmel/samv71x19.dtsi index 46c1d7a875693..67d497bec791d 100644 --- a/dts/arm/atmel/samv71x19.dtsi +++ b/dts/arm/atmel/samv71x19.dtsi @@ -4,20 +4,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(256)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(512)>; - erase-blocks = <&eefc 8 2048>, <&eefc 62 8192>; - }; - }; - }; -}; +#include diff --git a/dts/arm/atmel/samv71x19b.dtsi b/dts/arm/atmel/samv71x19b.dtsi index 520c939815177..e9bd1cc2ab2ed 100644 --- a/dts/arm/atmel/samv71x19b.dtsi +++ b/dts/arm/atmel/samv71x19b.dtsi @@ -5,20 +5,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(256)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(512)>; - erase-blocks = <&eefc 8 2048>, <&eefc 62 8192>; - }; - }; - }; -}; +#include diff --git a/dts/arm/atmel/samv71x20.dtsi b/dts/arm/atmel/samv71x20.dtsi index 10228d242a239..7ccbb3fd557c3 100644 --- a/dts/arm/atmel/samv71x20.dtsi +++ b/dts/arm/atmel/samv71x20.dtsi @@ -4,20 +4,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(384)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(1024)>; - erase-blocks = <&eefc 8 2048>, <&eefc 126 8192>; - }; - }; - }; -}; +#include diff --git a/dts/arm/atmel/samv71x20b.dtsi b/dts/arm/atmel/samv71x20b.dtsi index d425e524aa854..3856ac0e46d1e 100644 --- a/dts/arm/atmel/samv71x20b.dtsi +++ b/dts/arm/atmel/samv71x20b.dtsi @@ -5,20 +5,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(384)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(1024)>; - erase-blocks = <&eefc 8 2048>, <&eefc 126 8192>; - }; - }; - }; -}; +#include diff --git a/dts/arm/atmel/samv71x21.dtsi b/dts/arm/atmel/samv71x21.dtsi index d59fa5be59063..4a04410e2f3d4 100644 --- a/dts/arm/atmel/samv71x21.dtsi +++ b/dts/arm/atmel/samv71x21.dtsi @@ -4,20 +4,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(384)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(2048)>; - erase-blocks = <&eefc 8 2048>, <&eefc 252 8192>; - }; - }; - }; -}; +#include diff --git a/dts/arm/atmel/samv71x21b.dtsi b/dts/arm/atmel/samv71x21b.dtsi index c55ac8b128437..b4c87d2ab6358 100644 --- a/dts/arm/atmel/samv71x21b.dtsi +++ b/dts/arm/atmel/samv71x21b.dtsi @@ -5,20 +5,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include - -/ { - sram0: memory@20400000 { - reg = <0x20400000 DT_SIZE_K(384)>; - }; - - soc { - flash-controller@400e0c00 { - flash0: flash@400000 { - reg = <0x00400000 DT_SIZE_K(2048)>; - erase-blocks = <&eefc 8 2048>, <&eefc 252 8192>; - }; - }; - }; -}; +#include diff --git a/dts/arm/atmel/samx7x.dtsi b/dts/arm/atmel/samx7x.dtsi new file mode 100644 index 0000000000000..23f43b9292647 --- /dev/null +++ b/dts/arm/atmel/samx7x.dtsi @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2017 Piotr Mienkowski + * Copyright (c) 2017 Justin Watson + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/ { + aliases { + watchdog0 = &wdt; + }; + + chosen { + zephyr,flash-controller = &eefc; + zephyr,entropy = &trng; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m7"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + sram0: memory@20400000 { + compatible = "mmio-sram"; + }; + + soc { + ssc: ssc@40004000 { + compatible = "atmel,sam-ssc"; + reg = <0x40004000 0x4000>; + interrupts = <22 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 22>; + status = "disabled"; + }; + + spi0: spi@40008000 { + compatible = "atmel,sam-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40008000 0x4000>; + interrupts = <21 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 21>; + status = "disabled"; + }; + + tc0: tc@4000c000 { + compatible = "atmel,sam-tc"; + reg = <0x4000c000 0x100>; + interrupts = <23 0 + 24 0 + 25 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 23>, + <&pmc PMC_TYPE_PERIPHERAL 24>, + <&pmc PMC_TYPE_PERIPHERAL 25>; + status = "disabled"; + + qdec { + compatible = "atmel,sam-tc-qdec"; + status = "disabled"; + }; + }; + + tc1: tc@40010000 { + compatible = "atmel,sam-tc"; + reg = <0x40010000 0x100>; + interrupts = <26 0 + 27 0 + 28 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 26>, + <&pmc PMC_TYPE_PERIPHERAL 27>, + <&pmc PMC_TYPE_PERIPHERAL 28>; + status = "disabled"; + + qdec { + compatible = "atmel,sam-tc-qdec"; + status = "disabled"; + }; + }; + + tc2: tc@40014000 { + compatible = "atmel,sam-tc"; + reg = <0x40014000 0x100>; + interrupts = <47 0 + 48 0 + 49 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 47>, + <&pmc PMC_TYPE_PERIPHERAL 48>, + <&pmc PMC_TYPE_PERIPHERAL 49>; + status = "disabled"; + + qdec { + compatible = "atmel,sam-tc-qdec"; + status = "disabled"; + }; + }; + + twihs0: i2c@40018000 { + compatible = "atmel,sam-i2c-twihs"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40018000 0x12B>; + interrupts = <19 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 19>; + status = "disabled"; + }; + + twihs1: i2c@4001c000 { + compatible = "atmel,sam-i2c-twihs"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4001c000 0x12B>; + interrupts = <20 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 20>; + status = "disabled"; + }; + + pwm0: pwm0@40020000 { + compatible = "atmel,sam-pwm"; + reg = <0x40020000 0x4000>; + interrupts = <31 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 31>; + status = "disabled"; + prescaler = <10>; + divider = <1>; + #pwm-cells = <3>; + }; + + usart0: usart@40024000 { + compatible = "atmel,sam-usart"; + reg = <0x40024000 0x100>; + interrupts = <13 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 13>; + status = "disabled"; + }; + + usart1: usart@40028000 { + compatible = "atmel,sam-usart"; + reg = <0x40028000 0x100>; + interrupts = <14 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 14>; + status = "disabled"; + }; + + usart2: usart@4002c000 { + compatible = "atmel,sam-usart"; + reg = <0x4002c000 0x100>; + interrupts = <15 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 15>; + status = "disabled"; + }; + + can0: can@40030000 { + compatible = "atmel,sam-can"; + reg = <0x40030000 0x100>, <0x40088110 0x04>; + reg-names = "m_can", "dma_base"; + interrupts = <35 0>, <36 0>; + interrupt-names = "int0", "int1"; + clocks = <&pmc PMC_TYPE_PERIPHERAL 35>; + divider = <6>; + bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; + status = "disabled"; + }; + + can1: can@40034000 { + compatible = "atmel,sam-can"; + reg = <0x40034000 0x100>, <0x40088114 0x4>; + reg-names = "m_can", "dma_base"; + interrupts = <37 0>, <38 0>; + interrupt-names = "int0", "int1"; + clocks = <&pmc PMC_TYPE_PERIPHERAL 37>; + divider = <6>; + bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; + status = "disabled"; + }; + + usbhs: usbd@40038000 { + compatible = "atmel,sam-usbhs"; + reg = <0x40038000 0x4000>; + interrupts = <34 0>; + interrupt-names = "usbhs"; + maximum-speed = "high-speed"; + num-bidir-endpoints = <10>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 34>; + status = "disabled"; + }; + + afec0: adc@4003c000 { + compatible = "atmel,sam-afec"; + reg = <0x4003c000 0x100>; + interrupts = <29 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 29>; + status = "disabled"; + #io-channel-cells = <1>; + }; + + dacc: dacc@40040000 { + compatible = "atmel,sam-dac"; + reg = <0x40040000 0x100>; + interrupts = <30 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 30>; + status = "disabled"; + #io-channel-cells = <1>; + }; + + gmac: ethernet@40050000 { + compatible = "atmel,sam-gmac"; + reg = <0x40050000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; + interrupts = <39 0>, <66 0>, <67 0>; + interrupt-names = "gmac", "q1", "q2"; + num-queues = <3>; + local-mac-address = [00 00 00 00 00 00]; + status = "disabled"; + }; + + mdio: mdio@40050000 { + compatible = "atmel,sam-mdio"; + reg = <0x40050000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + tc3: tc@40054000 { + compatible = "atmel,sam-tc"; + reg = <0x40054000 0x100>; + interrupts = <50 0 + 51 0 + 52 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 50>, + <&pmc PMC_TYPE_PERIPHERAL 51>, + <&pmc PMC_TYPE_PERIPHERAL 52>; + status = "disabled"; + + qdec { + compatible = "atmel,sam-tc-qdec"; + status = "disabled"; + }; + }; + + spi1: spi@40058000 { + compatible = "atmel,sam-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40058000 0x4000>; + interrupts = <42 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 42>; + status = "disabled"; + }; + + pwm1: pwm1@4005c000 { + compatible = "atmel,sam-pwm"; + reg = <0x4005c000 0x4000>; + interrupts = <60 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 60>; + status = "disabled"; + prescaler = <10>; + divider = <1>; + #pwm-cells = <3>; + }; + + twihs2: i2c@40060000 { + compatible = "atmel,sam-i2c-twihs"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40060000 0x12B>; + interrupts = <41 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 41>; + status = "disabled"; + }; + + afec1: adc@40064000 { + compatible = "atmel,sam-afec"; + reg = <0x40064000 0x100>; + interrupts = <40 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 40>; + status = "disabled"; + #io-channel-cells = <1>; + }; + + trng: random@40070000 { + compatible = "atmel,sam-trng"; + reg = <0x40070000 0x4000>; + interrupts = <57 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 57>; + status = "okay"; + }; + + xdmac: dma0: dma-controller@40078000 { + compatible = "atmel,sam-xdmac"; + reg = <0x40078000 0x400>; + interrupts = <58 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 58>; + #dma-cells = <2>; + status = "disabled"; + }; + + pmc: pmc@400e0600 { + compatible = "atmel,sam-pmc"; + reg = <0x400e0600 0x200>; + interrupts = <5 0>; + #clock-cells = <2>; + status = "okay"; + }; + + uart0: uart@400e0800 { + compatible = "atmel,sam-uart"; + reg = <0x400e0800 0x100>; + interrupts = <7 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 7>; + status = "disabled"; + }; + + uart1: uart@400e0a00 { + compatible = "atmel,sam-uart"; + reg = <0x400e0a00 0x100>; + interrupts = <8 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 8>; + status = "disabled"; + }; + + eefc: flash-controller@400e0c00 { + compatible = "atmel,sam-flash-controller"; + reg = <0x400e0c00 0x200>; + interrupts = <6 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 6>; + + #address-cells = <1>; + #size-cells = <1>; + #erase-block-cells = <2>; + + flash0: flash@400000 { + compatible = "atmel,sam-flash", "soc-nv-flash"; + write-block-size = <16>; + erase-block-size = <8192>; + }; + }; + + pinctrl: pinctrl@400e0e00 { + compatible = "atmel,sam-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x400e0e00 0x400e0e00 0xa00>; + + pioa: gpio@400e0e00 { + compatible = "atmel,sam-gpio"; + reg = <0x400e0e00 0x190>; + interrupts = <10 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 10>; + gpio-controller; + #gpio-cells = <2>; + #atmel,pin-cells = <2>; + }; + + piob: gpio@400e1000 { + compatible = "atmel,sam-gpio"; + reg = <0x400e1000 0x190>; + interrupts = <11 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 11>; + gpio-controller; + #gpio-cells = <2>; + #atmel,pin-cells = <2>; + }; + + pioc: gpio@400e1200 { + compatible = "atmel,sam-gpio"; + reg = <0x400e1200 0x190>; + interrupts = <12 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 12>; + gpio-controller; + #gpio-cells = <2>; + #atmel,pin-cells = <2>; + }; + + piod: gpio@400e1400 { + compatible = "atmel,sam-gpio"; + reg = <0x400e1400 0x190>; + interrupts = <16 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 16>; + gpio-controller; + #gpio-cells = <2>; + #atmel,pin-cells = <2>; + }; + + pioe: gpio@400e1600 { + compatible = "atmel,sam-gpio"; + reg = <0x400e1600 0x190>; + interrupts = <17 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 17>; + gpio-controller; + #gpio-cells = <2>; + #atmel,pin-cells = <2>; + }; + }; + + rstc: rstc@400e1800 { + compatible = "atmel,sam-rstc"; + reg = <0x400e1800 0x10>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 1>; + user-nrst; + }; + + supc: supc@400e1810 { + compatible = "atmel,sam-supc"; + reg = <0x400e1810 0x20>; + #wakeup-source-id-cells = <1>; + status = "okay"; + }; + + wdt: watchog@400e1850 { + compatible = "atmel,sam-watchdog"; + reg = <0x400e1850 0xc>; + interrupts = <4 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 4>; + status = "disabled"; + }; + + rtc: rtc@400e1860 { + compatible = "atmel,sam-rtc"; + reg = <0x400e1860 0x100>; + interrupts = <2 0>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 2>; + alarms-count = <1>; + status = "disabled"; + }; + + uart2: uart@400e1a00 { + compatible = "atmel,sam-uart"; + reg = <0x400e1a00 0x100>; + interrupts = <44 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 44>; + status = "disabled"; + }; + + uart3: uart@400e1c00 { + compatible = "atmel,sam-uart"; + reg = <0x400e1c00 0x100>; + interrupts = <45 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 45>; + status = "disabled"; + }; + + uart4: uart@400e1e00 { + compatible = "atmel,sam-uart"; + reg = <0x400e1e00 0x100>; + interrupts = <46 1>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 46>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/dts/arm/atmel/samx7xb.dtsi b/dts/arm/atmel/samx7xb.dtsi new file mode 100644 index 0000000000000..9f430a7db4666 --- /dev/null +++ b/dts/arm/atmel/samx7xb.dtsi @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020 Stephanos Ioannidis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gmac { + interrupts = <39 0>, <66 0>, <67 0>, <71 0>, <72 0>, <73 0>; + interrupt-names = "gmac", "q1", "q2", "q3", "q4", "q5"; + num-queues = <6>; +}; diff --git a/dts/arm/atmel/samx7xx19.dtsi b/dts/arm/atmel/samx7xx19.dtsi new file mode 100644 index 0000000000000..434409d1e97b5 --- /dev/null +++ b/dts/arm/atmel/samx7xx19.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 Gerson Fernando Budke + * Copyright (c) 2020 Stephanos Ioannidis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + sram0: memory@20400000 { + reg = <0x20400000 DT_SIZE_K(256)>; + }; + + soc { + flash-controller@400e0c00 { + flash0: flash@400000 { + reg = <0x00400000 DT_SIZE_K(512)>; + erase-blocks = <&eefc 8 2048>, <&eefc 62 8192>; + }; + }; + }; +}; diff --git a/dts/arm/atmel/samx7xx20.dtsi b/dts/arm/atmel/samx7xx20.dtsi new file mode 100644 index 0000000000000..4578cdb3e0779 --- /dev/null +++ b/dts/arm/atmel/samx7xx20.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 Gerson Fernando Budke + * Copyright (c) 2020 Stephanos Ioannidis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + sram0: memory@20400000 { + reg = <0x20400000 DT_SIZE_K(384)>; + }; + + soc { + flash-controller@400e0c00 { + flash0: flash@400000 { + reg = <0x00400000 DT_SIZE_K(1024)>; + erase-blocks = <&eefc 8 2048>, <&eefc 126 8192>; + }; + }; + }; +}; diff --git a/dts/arm/atmel/samx7xx21.dtsi b/dts/arm/atmel/samx7xx21.dtsi new file mode 100644 index 0000000000000..9433e3063aaf8 --- /dev/null +++ b/dts/arm/atmel/samx7xx21.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 Gerson Fernando Budke + * Copyright (c) 2020 Stephanos Ioannidis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + sram0: memory@20400000 { + reg = <0x20400000 DT_SIZE_K(384)>; + }; + + soc { + flash-controller@400e0c00 { + flash0: flash@400000 { + reg = <0x00400000 DT_SIZE_K(2048)>; + erase-blocks = <&eefc 8 2048>, <&eefc 252 8192>; + }; + }; + }; +}; diff --git a/dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi b/dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi index 56957dddab031..59f462ee85ff3 100644 --- a/dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi +++ b/dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi @@ -544,5 +544,29 @@ interrupts = <164 6>; status = "disabled"; }; + + dma0: dw@40280000 { + #dma-cells = <1>; + compatible = "infineon,cat1-dma"; + reg = <0x40280000 0x8700>; + dma-channels = <16>; + interrupts = <50 6>, /* CH0 */ + <51 6>, /* CH1 */ + <52 6>, /* CH2 */ + <53 6>, /* CH3 */ + <54 6>, /* CH4 */ + <55 6>, /* CH5 */ + <56 6>, /* CH6 */ + <57 6>, /* CH7 */ + <58 6>, /* CH8 */ + <59 6>, /* CH9 */ + <60 6>, /* CH10 */ + <61 6>, /* CH11 */ + <62 6>, /* CH12 */ + <63 6>, /* CH13 */ + <64 6>, /* CH14 */ + <65 6>; /* CH15 */ + status = "disabled"; + }; }; }; diff --git a/dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi b/dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi index c61ba9e0ca423..8a54c3be4b887 100644 --- a/dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi +++ b/dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi @@ -548,5 +548,80 @@ interrupts = <164 6>; status = "disabled"; }; + + dma0: dw@40280000 { + #dma-cells = <1>; + compatible = "infineon,cat1-dma"; + reg = <0x40280000 0x8700>; + dma-channels = <29>; + interrupts = <56 6>, /* CH0 */ + <57 6>, /* CH1 */ + <58 6>, /* CH2 */ + <59 6>, /* CH3 */ + <60 6>, /* CH4 */ + <61 6>, /* CH5 */ + <62 6>, /* CH6 */ + <63 6>, /* CH7 */ + <64 6>, /* CH8 */ + <65 6>, /* CH9 */ + <66 6>, /* CH10 */ + <67 6>, /* CH11 */ + <68 6>, /* CH12 */ + <69 6>, /* CH13 */ + <70 6>, /* CH14 */ + <71 6>, /* CH15 */ + <72 6>, /* CH16 */ + <73 6>, /* CH17 */ + <74 6>, /* CH18 */ + <75 6>, /* CH19 */ + <76 6>, /* CH20 */ + <77 6>, /* CH21 */ + <78 6>, /* CH22 */ + <79 6>, /* CH23 */ + <80 6>, /* CH24 */ + <81 6>, /* CH25 */ + <82 6>, /* CH26 */ + <83 6>, /* CH27 */ + <84 6>; /* CH28 */ + status = "disabled"; + }; + + dma1: dw@40290000 { + #dma-cells = <1>; + compatible = "infineon,cat1-dma"; + reg = <0x40290000 0x8700>; + dma-channels = <29>; + interrupts = <85 6>, /* CH0 */ + <86 6>, /* CH1 */ + <87 6>, /* CH2 */ + <88 6>, /* CH3 */ + <89 6>, /* CH4 */ + <90 6>, /* CH5 */ + <91 6>, /* CH6 */ + <92 6>, /* CH7 */ + <93 6>, /* CH8 */ + <94 6>, /* CH9 */ + <95 6>, /* CH10 */ + <96 6>, /* CH11 */ + <97 6>, /* CH12 */ + <98 6>, /* CH13 */ + <99 6>, /* CH14 */ + <100 6>, /* CH15 */ + <101 6>, /* CH16 */ + <102 6>, /* CH17 */ + <103 6>, /* CH18 */ + <104 6>, /* CH19 */ + <105 6>, /* CH20 */ + <106 6>, /* CH21 */ + <107 6>, /* CH22 */ + <108 6>, /* CH23 */ + <109 6>, /* CH24 */ + <110 6>, /* CH25 */ + <111 6>, /* CH26 */ + <112 6>, /* CH27 */ + <113 6>; /* CH28 */ + status = "disabled"; + }; + }; }; diff --git a/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi b/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi index 763eca835d21d..69ef3d0fbf668 100644 --- a/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi +++ b/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi @@ -113,6 +113,14 @@ #gpio-cells = <2>; }; + adc0: adc@40520000 { + compatible = "infineon,cat1-adc"; + reg = <0x40520000 0x10000>; + interrupts = <67 6>; + status = "disabled"; + #io-channel-cells = <1>; + }; + ipc0: ipc@401d0000 { compatible = "infineon,cat1-ipc"; reg = <0x401d0000 0x10000>; diff --git a/dts/arm/infineon/cat3/xmc/xmc4500_F100x1024.dtsi b/dts/arm/infineon/cat3/xmc/xmc4500_F100x1024.dtsi index ff64b9bd9c19d..01756ff766e1e 100644 --- a/dts/arm/infineon/cat3/xmc/xmc4500_F100x1024.dtsi +++ b/dts/arm/infineon/cat3/xmc/xmc4500_F100x1024.dtsi @@ -26,7 +26,7 @@ }; &flash0 { - reg = <0xc000000 DT_SIZE_M(1)>; + reg = <0x8000000 DT_SIZE_M(1)>; pages_layout: pages_layout { pages_layout_16k: pages_layout_16k { pages-count = <8>; diff --git a/dts/arm/infineon/cat3/xmc/xmc4700_F144x2048.dtsi b/dts/arm/infineon/cat3/xmc/xmc4700_F144x2048.dtsi index 7a1d6f4db6e69..069b841d7f6c8 100644 --- a/dts/arm/infineon/cat3/xmc/xmc4700_F144x2048.dtsi +++ b/dts/arm/infineon/cat3/xmc/xmc4700_F144x2048.dtsi @@ -20,7 +20,7 @@ }; &flash0 { - reg = <0xc000000 DT_SIZE_M(2)>; + reg = <0x8000000 DT_SIZE_M(2)>; pages_layout: pages_layout { pages_layout_16k: pages_layout_16k { pages-count = <8>; diff --git a/dts/arm/infineon/cat3/xmc/xmc4xxx.dtsi b/dts/arm/infineon/cat3/xmc/xmc4xxx.dtsi index d2ea0e1314e14..f757dd8328eb6 100644 --- a/dts/arm/infineon/cat3/xmc/xmc4xxx.dtsi +++ b/dts/arm/infineon/cat3/xmc/xmc4xxx.dtsi @@ -26,7 +26,7 @@ reg = <0x58001000 0x1400>; #address-cells = <1>; #size-cells = <1>; - flash0: flash@c000000 { + flash0: flash@8000000 { compatible = "infineon,xmc4xxx-nv-flash","soc-nv-flash"; write-block-size = <256>; }; diff --git a/dts/arm/microchip/mec1501hsz.dtsi b/dts/arm/microchip/mec1501hsz.dtsi index 1c34f16c468b8..e4b4d74cb3119 100644 --- a/dts/arm/microchip/mec1501hsz.dtsi +++ b/dts/arm/microchip/mec1501hsz.dtsi @@ -442,6 +442,7 @@ status = "disabled"; #io-channel-cells = <1>; clktime = <32>; + channels = <8>; }; kbd0: kbd@40009c00 { compatible = "microchip,xec-kbd"; diff --git a/dts/arm/microchip/mec172x_common.dtsi b/dts/arm/microchip/mec172x_common.dtsi index a7bf2aa8f71a4..9462c1b47c2db 100644 --- a/dts/arm/microchip/mec172x_common.dtsi +++ b/dts/arm/microchip/mec172x_common.dtsi @@ -650,6 +650,7 @@ adc0: adc@40007c00 { status = "disabled"; #io-channel-cells = <1>; clktime = <32>; + channels = <16>; }; kbd0: kbd@40009c00 { compatible = "microchip,xec-kbd"; diff --git a/dts/arm/microchip/mec172xnsz.dtsi b/dts/arm/microchip/mec172xnsz.dtsi index cbb84f218779f..54103e9bcdeee 100644 --- a/dts/arm/microchip/mec172xnsz.dtsi +++ b/dts/arm/microchip/mec172xnsz.dtsi @@ -75,3 +75,7 @@ &systick { status = "disabled"; }; + +&adc0 { + channels = <8>; +}; diff --git a/dts/arm/microchip/mec5.dtsi b/dts/arm/microchip/mec5.dtsi index e105bea6bafe2..ad79ca5ecdac6 100644 --- a/dts/arm/microchip/mec5.dtsi +++ b/dts/arm/microchip/mec5.dtsi @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -142,57 +144,51 @@ reg = <0x40081000 0x1000>; gpio_000_036: gpio@40081000 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081000 0x80 0x40081300 0x04 0x40081380 0x04 0x400813fc 0x04>; interrupts = <3 2>; gpio-controller; - port-id = <0>; - girq-id = <11>; #gpio-cells=<2>; }; gpio_040_076: gpio@40081080 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081080 0x80 0x40081304 0x04 0x40081384 0x04 0x400813f8 0x4>; interrupts = <2 2>; gpio-controller; - port-id = <1>; - girq-id = <10>; #gpio-cells=<2>; }; gpio_100_136: gpio@40081100 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081100 0x80 0x40081308 0x04 0x40081388 0x04 0x400813f4 0x04>; gpio-controller; interrupts = <1 2>; - port-id = <2>; - girq-id = <9>; #gpio-cells=<2>; }; gpio_140_176: gpio@40081180 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081180 0x80 0x4008130c 0x04 0x4008138c 0x04 0x400813f0 0x04>; gpio-controller; interrupts = <0 2>; - port-id = <3>; - girq-id = <8>; #gpio-cells=<2>; }; gpio_200_236: gpio@40081200 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081200 0x80 0x40081310 0x04 0x40081390 0x04 0x400813ec 0x04>; gpio-controller; interrupts = <4 2>; - port-id = <4>; - girq-id = <12>; #gpio-cells=<2>; }; gpio_240_276: gpio@40081280 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081280 0x80 0x40081314 0x04 0x40081394 0x04 0x400813e8 0x04>; gpio-controller; interrupts = <17 2>; - port-id = <5>; - girq-id = <26>; #gpio-cells=<2>; }; }; diff --git a/dts/arm/nordic/nrf52805.dtsi b/dts/arm/nordic/nrf52805.dtsi index e1c8e6a2efbc8..ef47f4e5273fa 100644 --- a/dts/arm/nordic/nrf52805.dtsi +++ b/dts/arm/nordic/nrf52805.dtsi @@ -165,6 +165,7 @@ interrupts = <7 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; timer0: timer@40008000 { diff --git a/dts/arm/nordic/nrf52810.dtsi b/dts/arm/nordic/nrf52810.dtsi index 40d872dda4463..0da4d7ccf94c4 100644 --- a/dts/arm/nordic/nrf52810.dtsi +++ b/dts/arm/nordic/nrf52810.dtsi @@ -169,6 +169,7 @@ interrupts = <7 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; timer0: timer@40008000 { compatible = "nordic,nrf-timer"; diff --git a/dts/arm/nordic/nrf52811.dtsi b/dts/arm/nordic/nrf52811.dtsi index 735bfee427b26..8e65445cf5f96 100644 --- a/dts/arm/nordic/nrf52811.dtsi +++ b/dts/arm/nordic/nrf52811.dtsi @@ -200,6 +200,7 @@ interrupts = <7 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; timer0: timer@40008000 { diff --git a/dts/arm/nordic/nrf52832.dtsi b/dts/arm/nordic/nrf52832.dtsi index abb1aed468cb5..7e2dae5faff3d 100644 --- a/dts/arm/nordic/nrf52832.dtsi +++ b/dts/arm/nordic/nrf52832.dtsi @@ -212,6 +212,7 @@ interrupts = <7 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; timer0: timer@40008000 { diff --git a/dts/arm/nordic/nrf52833.dtsi b/dts/arm/nordic/nrf52833.dtsi index e8a033b40021b..93fac4a04b88d 100644 --- a/dts/arm/nordic/nrf52833.dtsi +++ b/dts/arm/nordic/nrf52833.dtsi @@ -226,6 +226,7 @@ interrupts = <7 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; timer0: timer@40008000 { diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index e2265c130b0d1..9624ae12dfbd0 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -214,6 +214,7 @@ interrupts = <7 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; timer0: timer@40008000 { diff --git a/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi b/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi index 3e2eb31054262..f5cda20e9613f 100644 --- a/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi @@ -5,14 +5,12 @@ */ ipc0: ipc0 { - compatible = "zephyr,ipc-icbmsg"; - status = "okay"; + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&sram0_shared>; mboxes = <&mbox 0>, <&mbox 1>; mbox-names = "tx", "rx"; - tx-region = <&cpuapp_cpunet_ipc_shm>; - rx-region = <&cpunet_cpuapp_ipc_shm>; - tx-blocks = <32>; - rx-blocks = <32>; + role = "host"; + status = "okay"; bt_hci_ipc0: bt_hci_ipc0 { compatible = "zephyr,bt-hci-ipc"; diff --git a/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi b/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi index 75c2eb9f99f28..244459a0f16a5 100644 --- a/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi @@ -287,6 +287,7 @@ adc: adc@e000 { interrupts = <14 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; timer0: timer@f000 { diff --git a/dts/arm/nordic/nrf5340_cpunet.dtsi b/dts/arm/nordic/nrf5340_cpunet.dtsi index 4916703310945..acf95077669d5 100644 --- a/dts/arm/nordic/nrf5340_cpunet.dtsi +++ b/dts/arm/nordic/nrf5340_cpunet.dtsi @@ -347,14 +347,12 @@ /* Default IPC description */ ipc { ipc0: ipc0 { - compatible = "zephyr,ipc-icbmsg"; - status = "okay"; + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&sram0_shared>; mboxes = <&mbox 0>, <&mbox 1>; mbox-names = "rx", "tx"; - tx-region = <&cpunet_cpuapp_ipc_shm>; - rx-region = <&cpuapp_cpunet_ipc_shm>; - tx-blocks = <32>; - rx-blocks = <32>; + role = "remote"; + status = "okay"; }; }; }; diff --git a/dts/arm/nordic/nrf54l09_enga_cpuapp.dtsi b/dts/arm/nordic/nrf54l09_enga_cpuapp.dtsi new file mode 100644 index 0000000000000..fc359cdb0ac97 --- /dev/null +++ b/dts/arm/nordic/nrf54l09_enga_cpuapp.dtsi @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpuapp {}; +systick: &cpuapp_systick {}; +nvic: &cpuapp_nvic {}; + +/delete-node/ &cpuflpr; +/delete-node/ &cpuflpr_rram; +/delete-node/ &cpuflpr_sram; +/delete-node/ &cpuflpr_clic; + +/ { + chosen { + zephyr,bt-hci = &bt_hci_controller; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpuapp_nvic>; + ranges; + }; + + psa_rng: psa-rng { + compatible = "zephyr,psa-crypto-rng"; + status = "disabled"; + }; +}; + +&bt_hci_controller { + status = "okay"; +}; + +&cpuflpr_vpr { + cpuapp_vevif_rx: mailbox@1 { + compatible = "nordic,nrf-vevif-event-rx"; + reg = <0x1 0x1000>; + status = "disabled"; + interrupts = <76 NRF_DEFAULT_IRQ_PRIORITY>; + #mbox-cells = <1>; + nordic,events = <1>; + nordic,events-mask = <0x00100000>; + }; + + cpuapp_vevif_tx: mailbox@0 { + compatible = "nordic,nrf-vevif-task-tx"; + reg = <0x0 0x1000>; + #mbox-cells = <1>; + nordic,tasks = <7>; + nordic,tasks-mask = <0x007f0000>; + status = "disabled"; + }; +}; + +&cpuapp_ppb { + compatible = "simple-bus"; + ranges; +}; + +&grtc { +#ifdef USE_NON_SECURE_ADDRESS_MAP + interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>, +#else + interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>, +#endif + <229 NRF_DEFAULT_IRQ_PRIORITY>; /* reserved for Zero Latency IRQs */ +}; + +&gpiote20 { +#ifdef USE_NON_SECURE_ADDRESS_MAP + interrupts = <218 NRF_DEFAULT_IRQ_PRIORITY>; +#else + interrupts = <219 NRF_DEFAULT_IRQ_PRIORITY>; +#endif +}; + +&gpiote30 { +#ifdef USE_NON_SECURE_ADDRESS_MAP + interrupts = <268 NRF_DEFAULT_IRQ_PRIORITY>; +#else + interrupts = <269 NRF_DEFAULT_IRQ_PRIORITY>; +#endif +}; + +&dppic00 { + status = "okay"; +}; + +&dppic10 { + status = "okay"; +}; + +&dppic20 { + status = "okay"; +}; + +&dppic30 { + status = "okay"; +}; + +&ppib00 { + status = "okay"; +}; + +&ppib01 { + status = "okay"; +}; + +&ppib10 { + status = "okay"; +}; + +&ppib11 { + status = "okay"; +}; + +&ppib20 { + status = "okay"; +}; + +&ppib21 { + status = "okay"; +}; + +&ppib22 { + status = "okay"; +}; + +&ppib30 { + status = "okay"; +}; diff --git a/dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi b/dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi index 6a02234136f13..3f1fe655b6e50 100644 --- a/dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi @@ -16,6 +16,7 @@ nvic: &cpuapp_nvic {}; / { chosen { zephyr,bt-hci = &bt_hci_controller; + zephyr,entropy = &rng; }; soc { @@ -24,6 +25,11 @@ nvic: &cpuapp_nvic {}; ranges; }; + rng: rng { + status = "okay"; + compatible = "nordic,nrf-cracen-ctrdrbg"; + }; + psa_rng: psa-rng { compatible = "zephyr,psa-crypto-rng"; status = "disabled"; @@ -37,7 +43,7 @@ nvic: &cpuapp_nvic {}; &cpuflpr_vpr { cpuapp_vevif_rx: mailbox@1 { compatible = "nordic,nrf-vevif-event-rx"; - reg = <0x0 0x1000>; + reg = <0x1 0x1000>; status = "disabled"; interrupts = <76 NRF_DEFAULT_IRQ_PRIORITY>; #mbox-cells = <1>; diff --git a/dts/arm/nordic/nrf91_peripherals.dtsi b/dts/arm/nordic/nrf91_peripherals.dtsi index 58cc3142bcf27..476f8415853a4 100644 --- a/dts/arm/nordic/nrf91_peripherals.dtsi +++ b/dts/arm/nordic/nrf91_peripherals.dtsi @@ -26,6 +26,7 @@ adc: adc@e000 { interrupts = <14 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; dppic0: dppic: dppic@17000 { diff --git a/dts/arm/nuvoton/npcx/npcx-miwus-wui-map.dtsi b/dts/arm/nuvoton/npcx/npcx-miwus-wui-map.dtsi index ec82dd71a86fa..200f765026c1d 100644 --- a/dts/arm/nuvoton/npcx/npcx-miwus-wui-map.dtsi +++ b/dts/arm/nuvoton/npcx/npcx-miwus-wui-map.dtsi @@ -89,12 +89,6 @@ wui_iob0: wui0-4-2 { miwus = <&miwu0 3 2>; /* GPIOB0 */ }; - wui_smb0_2: wui0-4-3 { - miwus = <&miwu0 3 3>; /* SMB0/2 */ - }; - wui_smb1_3: wui0-4-4 { - miwus = <&miwu0 3 4>; /* SMB1/3 */ - }; wui_iob1: wui0-4-5 { miwus = <&miwu0 3 5>; /* GPIOB1 */ }; diff --git a/dts/arm/nuvoton/npcx/npcx.dtsi b/dts/arm/nuvoton/npcx/npcx.dtsi index 125ebb6563348..aaaca78d02675 100644 --- a/dts/arm/nuvoton/npcx/npcx.dtsi +++ b/dts/arm/nuvoton/npcx/npcx.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -384,71 +385,6 @@ <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL5 7>; }; - /* I2c Controllers - Do not use them as i2c node directly */ - i2c_ctrl0: i2c@40009000 { - compatible = "nuvoton,npcx-i2c-ctrl"; - reg = <0x40009000 0x1000>; - interrupts = <13 3>; - clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 0>; - status = "disabled"; - }; - - i2c_ctrl1: i2c@4000b000 { - compatible = "nuvoton,npcx-i2c-ctrl"; - reg = <0x4000b000 0x1000>; - interrupts = <14 3>; - clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 1>; - status = "disabled"; - }; - - i2c_ctrl2: i2c@400c0000 { - compatible = "nuvoton,npcx-i2c-ctrl"; - reg = <0x400c0000 0x1000>; - interrupts = <36 3>; - clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL3 2>; - status = "disabled"; - }; - - i2c_ctrl3: i2c@400c2000 { - compatible = "nuvoton,npcx-i2c-ctrl"; - reg = <0x400c2000 0x1000>; - interrupts = <37 3>; - clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL3 3>; - status = "disabled"; - }; - - i2c_ctrl4: i2c@40008000 { - compatible = "nuvoton,npcx-i2c-ctrl"; - reg = <0x40008000 0x1000>; - interrupts = <19 3>; - clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 4>; - status = "disabled"; - }; - - i2c_ctrl5: i2c@40017000 { - compatible = "nuvoton,npcx-i2c-ctrl"; - reg = <0x40017000 0x1000>; - interrupts = <20 3>; - clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 0>; - status = "disabled"; - }; - - i2c_ctrl6: i2c@40018000 { - compatible = "nuvoton,npcx-i2c-ctrl"; - reg = <0x40018000 0x1000>; - interrupts = <16 3>; - clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 1>; - status = "disabled"; - }; - - i2c_ctrl7: i2c@40019000 { - compatible = "nuvoton,npcx-i2c-ctrl"; - reg = <0x40019000 0x1000>; - interrupts = <8 3>; - clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 2>; - status = "disabled"; - }; - tach1: tach@400e1000 { compatible = "nuvoton,npcx-tach"; reg = <0x400e1000 0x2000>; @@ -549,7 +485,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x00>; + port = ; controller = <&i2c_ctrl0>; status = "disabled"; }; @@ -558,7 +494,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x10>; + port = ; controller = <&i2c_ctrl1>; status = "disabled"; }; @@ -567,7 +503,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x20>; + port = ; controller = <&i2c_ctrl2>; status = "disabled"; }; @@ -576,7 +512,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x30>; + port = ; controller = <&i2c_ctrl3>; status = "disabled"; }; @@ -585,7 +521,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x41>; + port = ; controller = <&i2c_ctrl4>; status = "disabled"; }; @@ -594,7 +530,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x50>; + port = ; controller = <&i2c_ctrl5>; status = "disabled"; }; @@ -603,7 +539,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x51>; + port = ; controller = <&i2c_ctrl5>; status = "disabled"; }; @@ -612,7 +548,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x60>; + port = ; controller = <&i2c_ctrl6>; status = "disabled"; }; @@ -621,7 +557,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x61>; + port = ; controller = <&i2c_ctrl6>; status = "disabled"; }; @@ -630,7 +566,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x70>; + port = ; controller = <&i2c_ctrl7>; status = "disabled"; }; diff --git a/dts/arm/nuvoton/npcx/npcx4.dtsi b/dts/arm/nuvoton/npcx/npcx4.dtsi index 6bc44daae1d25..ab83adda7927b 100644 --- a/dts/arm/nuvoton/npcx/npcx4.dtsi +++ b/dts/arm/nuvoton/npcx/npcx4.dtsi @@ -296,6 +296,79 @@ &lvol_iof4 &lvol_iof5 &lvol_none &lvol_none>; }; + /* I2c Controllers - Do not use them as i2c node directly */ + i2c_ctrl0: i2c@40009000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40009000 0x1000>; + interrupts = <13 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 0>; + smb-wui = <&wui_smb0>; + status = "disabled"; + }; + + i2c_ctrl1: i2c@4000b000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x4000b000 0x1000>; + interrupts = <14 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 1>; + smb-wui = <&wui_smb1>; + status = "disabled"; + }; + + i2c_ctrl2: i2c@400c0000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x400c0000 0x1000>; + interrupts = <36 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL3 2>; + smb-wui = <&wui_smb2>; + status = "disabled"; + }; + + i2c_ctrl3: i2c@400c2000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x400c2000 0x1000>; + interrupts = <37 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL3 3>; + smb-wui = <&wui_smb3>; + status = "disabled"; + }; + + i2c_ctrl4: i2c@40008000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40008000 0x1000>; + interrupts = <19 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 4>; + smb-wui = <&wui_smb4>; + status = "disabled"; + }; + + i2c_ctrl5: i2c@40017000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40017000 0x1000>; + interrupts = <20 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 0>; + smb-wui = <&wui_smb5>; + status = "disabled"; + }; + + i2c_ctrl6: i2c@40018000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40018000 0x1000>; + interrupts = <16 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 1>; + smb-wui = <&wui_smb6>; + status = "disabled"; + }; + + i2c_ctrl7: i2c@40019000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40019000 0x1000>; + interrupts = <8 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 2>; + smb-wui = <&wui_smb7>; + status = "disabled"; + }; + /* ADC0 comparator configuration in npcx4 series */ adc0: adc@400d1000 { channel-count = <26>; @@ -449,7 +522,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x40>; + port = ; controller = <&i2c_ctrl4>; status = "disabled"; }; @@ -458,7 +531,7 @@ compatible = "nuvoton,npcx-i2c-port"; #address-cells = <1>; #size-cells = <0>; - port = <0x71>; + port = ; controller = <&i2c_ctrl7>; status = "disabled"; }; diff --git a/dts/arm/nuvoton/npcx/npcx4/npcx4-miwus-wui-map.dtsi b/dts/arm/nuvoton/npcx/npcx4/npcx4-miwus-wui-map.dtsi index ace5d4b1562e7..4faef5898c204 100644 --- a/dts/arm/nuvoton/npcx/npcx4/npcx4-miwus-wui-map.dtsi +++ b/dts/arm/nuvoton/npcx/npcx4/npcx4-miwus-wui-map.dtsi @@ -19,6 +19,14 @@ miwus = <&miwu0 7 7>; /* GPIOE7 */ }; + /* MIWU group D */ + wui_smb0: wui0-4-3 { + miwus = <&miwu0 3 3>; /* SMB0 */ + }; + wui_smb1: wui0-4-4 { + miwus = <&miwu0 3 4>; /* SMB1 */ + }; + /* MIWU table 1 */ /* MIWU group B */ wui_io13: wui1-2-3 { @@ -82,7 +90,7 @@ miwus = <&miwu2 6 7>; /* I3C1_RSTW */ }; - /* MIWU group G */ + /* MIWU group H */ wui_i3c2_addrw: wui2-8-0 { miwus = <&miwu2 7 0>; /* I3C2_ADDRW */ }; diff --git a/dts/arm/nuvoton/npcx/npcx7.dtsi b/dts/arm/nuvoton/npcx/npcx7.dtsi index 5b5b033a54c8c..3496e454d8b4b 100644 --- a/dts/arm/nuvoton/npcx/npcx7.dtsi +++ b/dts/arm/nuvoton/npcx/npcx7.dtsi @@ -263,6 +263,79 @@ &lvol_iof4 &lvol_iof5 &lvol_none &lvol_none>; }; + /* I2c Controllers - Do not use them as i2c node directly */ + i2c_ctrl0: i2c@40009000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40009000 0x1000>; + interrupts = <13 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 0>; + smb-wui = <&wui_smb0_2>; + status = "disabled"; + }; + + i2c_ctrl1: i2c@4000b000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x4000b000 0x1000>; + interrupts = <14 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 1>; + smb-wui = <&wui_smb1_3>; + status = "disabled"; + }; + + i2c_ctrl2: i2c@400c0000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x400c0000 0x1000>; + interrupts = <36 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL3 2>; + smb-wui = <&wui_smb0_2>; + status = "disabled"; + }; + + i2c_ctrl3: i2c@400c2000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x400c2000 0x1000>; + interrupts = <37 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL3 3>; + smb-wui = <&wui_smb1_3>; + status = "disabled"; + }; + + i2c_ctrl4: i2c@40008000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40008000 0x1000>; + interrupts = <19 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 4>; + smb-wui = <&wui_smb4>; + status = "disabled"; + }; + + i2c_ctrl5: i2c@40017000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40017000 0x1000>; + interrupts = <20 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 0>; + smb-wui = <&wui_smb5>; + status = "disabled"; + }; + + i2c_ctrl6: i2c@40018000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40018000 0x1000>; + interrupts = <16 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 1>; + smb-wui = <&wui_smb6>; + status = "disabled"; + }; + + i2c_ctrl7: i2c@40019000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40019000 0x1000>; + interrupts = <8 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 2>; + smb-wui = <&wui_smb7>; + status = "disabled"; + }; + /* ADC0 comparator configuration in npcx7 series */ adc0: adc@400d1000 { channel-count = <10>; diff --git a/dts/arm/nuvoton/npcx/npcx7/npcx7-miwus-wui-map.dtsi b/dts/arm/nuvoton/npcx/npcx7/npcx7-miwus-wui-map.dtsi index 700cfd0ce4cc8..3a0e4153dbb67 100644 --- a/dts/arm/nuvoton/npcx/npcx7/npcx7-miwus-wui-map.dtsi +++ b/dts/arm/nuvoton/npcx/npcx7/npcx7-miwus-wui-map.dtsi @@ -18,12 +18,18 @@ wui_cr_sin2: wui0-1-6-2 { miwus = <&miwu0 0 6>; /* CR_SIN2 */ }; - - /* MIWU group A */ wui_io86: wui0-1-6 { miwus = <&miwu0 0 6>; /* GPIO86 */ }; + /* MIWU group D */ + wui_smb0_2: wui0-4-3 { + miwus = <&miwu0 3 3>; /* SMB0/2 */ + }; + wui_smb1_3: wui0-4-4 { + miwus = <&miwu0 3 4>; /* SMB1/3 */ + }; + /* MIWU group G */ wui_iod7: wui0-7-6 { miwus = <&miwu0 6 6>; /* GPIOD7 */ diff --git a/dts/arm/nuvoton/npcx/npcx9.dtsi b/dts/arm/nuvoton/npcx/npcx9.dtsi index dd991f8fd5727..c6cde81c38d0d 100644 --- a/dts/arm/nuvoton/npcx/npcx9.dtsi +++ b/dts/arm/nuvoton/npcx/npcx9.dtsi @@ -296,6 +296,79 @@ &lvol_iof4 &lvol_iof5 &lvol_none &lvol_none>; }; + /* I2c Controllers - Do not use them as i2c node directly */ + i2c_ctrl0: i2c@40009000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40009000 0x1000>; + interrupts = <13 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 0>; + smb-wui = <&wui_smb0_2>; + status = "disabled"; + }; + + i2c_ctrl1: i2c@4000b000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x4000b000 0x1000>; + interrupts = <14 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 1>; + smb-wui = <&wui_smb1_3>; + status = "disabled"; + }; + + i2c_ctrl2: i2c@400c0000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x400c0000 0x1000>; + interrupts = <36 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL3 2>; + smb-wui = <&wui_smb0_2>; + status = "disabled"; + }; + + i2c_ctrl3: i2c@400c2000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x400c2000 0x1000>; + interrupts = <37 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL3 3>; + smb-wui = <&wui_smb1_3>; + status = "disabled"; + }; + + i2c_ctrl4: i2c@40008000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40008000 0x1000>; + interrupts = <19 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL3 4>; + smb-wui = <&wui_smb4>; + status = "disabled"; + }; + + i2c_ctrl5: i2c@40017000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40017000 0x1000>; + interrupts = <20 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 0>; + smb-wui = <&wui_smb5>; + status = "disabled"; + }; + + i2c_ctrl6: i2c@40018000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40018000 0x1000>; + interrupts = <16 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 1>; + smb-wui = <&wui_smb6>; + status = "disabled"; + }; + + i2c_ctrl7: i2c@40019000 { + compatible = "nuvoton,npcx-i2c-ctrl"; + reg = <0x40019000 0x1000>; + interrupts = <8 3>; + clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL7 2>; + smb-wui = <&wui_smb7>; + status = "disabled"; + }; + /* ADC0 comparator configuration in npcx9 series */ adc0: adc@400d1000 { channel-count = <12>; diff --git a/dts/arm/nuvoton/npcx/npcx9/npcx9-miwus-wui-map.dtsi b/dts/arm/nuvoton/npcx/npcx9/npcx9-miwus-wui-map.dtsi index 6d280e75cb043..a1b711a1da45f 100644 --- a/dts/arm/nuvoton/npcx/npcx9/npcx9-miwus-wui-map.dtsi +++ b/dts/arm/nuvoton/npcx/npcx9/npcx9-miwus-wui-map.dtsi @@ -13,12 +13,21 @@ npcx-miwus-wui-map { compatible = "nuvoton,npcx-miwu-wui-map"; - /* MIWU table 1 */ + /* MIWU table 0 */ /* MIWU group A */ wui_cr_sin2: wui0-1-6-2 { miwus = <&miwu0 0 6>; /* CR_SIN2 */ }; + /* MIWU group D */ + wui_smb0_2: wui0-4-3 { + miwus = <&miwu0 3 3>; /* SMB0/2 */ + }; + wui_smb1_3: wui0-4-4 { + miwus = <&miwu0 3 4>; /* SMB1/3 */ + }; + + /* MIWU table 1 */ /* MIWU group G */ wui_io66: wui1-7-6 { miwus = <&miwu1 6 6>; /* GPIO66 */ diff --git a/dts/arm/nuvoton/npcx9m7fb.dtsi b/dts/arm/nuvoton/npcx9m7fb.dtsi index 7c17ff099345a..1b01eb53db632 100644 --- a/dts/arm/nuvoton/npcx9m7fb.dtsi +++ b/dts/arm/nuvoton/npcx9m7fb.dtsi @@ -16,7 +16,7 @@ reg = <0x64000000 DT_SIZE_K(512)>; }; - sram0: memory@200c0000 { + sram0: memory@200b0000 { compatible = "mmio-sram"; reg = <0x200B0000 DT_SIZE_K(128)>; }; diff --git a/dts/arm/nxp/nxp_imx93_m33.dtsi b/dts/arm/nxp/nxp_imx93_m33.dtsi index 22a87c62d04b9..e7a67f7599b88 100644 --- a/dts/arm/nxp/nxp_imx93_m33.dtsi +++ b/dts/arm/nxp/nxp_imx93_m33.dtsi @@ -89,7 +89,7 @@ }; lpuart2: serial@44390000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x44390000 DT_SIZE_K(64)>; interrupts = <20 3>; clocks = <&ccm IMX_CCM_LPUART2_CLK 0x6c 24>; diff --git a/dts/arm/nxp/nxp_imx95_m7.dtsi b/dts/arm/nxp/nxp_imx95_m7.dtsi index 33fa0ea0d2c1d..f06d2cfcee464 100644 --- a/dts/arm/nxp/nxp_imx95_m7.dtsi +++ b/dts/arm/nxp/nxp_imx95_m7.dtsi @@ -148,8 +148,32 @@ status = "disabled"; }; + lpspi3: spi@42550000 { + compatible = "nxp,lpspi"; + reg = <0x42550000 0x4000>; + interrupts = <61 3>; + clocks = <&scmi_clk IMX95_CLK_LPSPI3>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + }; + + lpspi4: spi@42560000 { + compatible = "nxp,lpspi"; + reg = <0x42560000 0x4000>; + interrupts = <62 3>; + clocks = <&scmi_clk IMX95_CLK_LPSPI4>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + }; + lpuart3: serial@42570000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x42570000 DT_SIZE_K(64)>; interrupts = <64 3>; clocks = <&scmi_clk IMX95_CLK_LPUART3>; @@ -157,7 +181,7 @@ }; lpuart4: serial@42580000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x42580000 DT_SIZE_K(64)>; interrupts = <65 3>; clocks = <&scmi_clk IMX95_CLK_LPUART4>; @@ -165,7 +189,7 @@ }; lpuart5: serial@42590000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x42590000 DT_SIZE_K(64)>; interrupts = <66 3>; clocks = <&scmi_clk IMX95_CLK_LPUART5>; @@ -173,7 +197,7 @@ }; lpuart6: serial@425a0000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x425a0000 DT_SIZE_K(64)>; interrupts = <67 3>; clocks = <&scmi_clk IMX95_CLK_LPUART6>; @@ -194,7 +218,7 @@ }; lpuart7: serial@42690000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x42690000 DT_SIZE_K(64)>; interrupts = <68 3>; clocks = <&scmi_clk IMX95_CLK_LPUART7>; @@ -202,7 +226,7 @@ }; lpuart8: serial@426a0000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x426a0000 DT_SIZE_K(64)>; interrupts = <69 3>; clocks = <&scmi_clk IMX95_CLK_LPUART8>; @@ -253,6 +277,54 @@ status = "disabled"; }; + lpspi5: spi@426f0000 { + compatible = "nxp,lpspi"; + reg = <0x426f0000 0x4000>; + interrupts = <177 3>; + clocks = <&scmi_clk IMX95_CLK_LPSPI5>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + }; + + lpspi6: spi@42700000 { + compatible = "nxp,lpspi"; + reg = <0x42700000 0x4000>; + interrupts = <178 3>; + clocks = <&scmi_clk IMX95_CLK_LPSPI6>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + }; + + lpspi7: spi@42710000 { + compatible = "nxp,lpspi"; + reg = <0x42710000 0x4000>; + interrupts = <179 3>; + clocks = <&scmi_clk IMX95_CLK_LPSPI7>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + }; + + lpspi8: spi@42720000 { + compatible = "nxp,lpspi"; + reg = <0x42720000 0x4000>; + interrupts = <180 3>; + clocks = <&scmi_clk IMX95_CLK_LPSPI8>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + }; + tpm1: pwm@44310000 { compatible = "nxp,kinetis-tpm"; reg = <0x44310000 0x88>; @@ -295,8 +367,32 @@ status = "disabled"; }; + lpspi1: spi@44360000 { + compatible = "nxp,lpspi"; + reg = <0x44360000 0x4000>; + interrupts = <16 3>; + clocks = <&scmi_clk IMX95_CLK_LPSPI1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + }; + + lpspi2: spi@44370000 { + compatible = "nxp,lpspi"; + reg = <0x44370000 0x4000>; + interrupts = <17 3>; + clocks = <&scmi_clk IMX95_CLK_LPSPI2>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + }; + lpuart1: serial@44380000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x44380000 DT_SIZE_K(64)>; interrupts = <19 3>; clocks = <&scmi_clk IMX95_CLK_LPUART1>; @@ -304,7 +400,7 @@ }; lpuart2: serial@44390000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x44390000 DT_SIZE_K(64)>; interrupts = <20 3>; clocks = <&scmi_clk IMX95_CLK_LPUART2>; diff --git a/dts/arm/nxp/nxp_k2x.dtsi b/dts/arm/nxp/nxp_k2x.dtsi index 82f594e84e126..0df1010f8b54e 100644 --- a/dts/arm/nxp/nxp_k2x.dtsi +++ b/dts/arm/nxp/nxp_k2x.dtsi @@ -274,7 +274,7 @@ }; spi0: spi@4002c000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002c000 0x88>; interrupts = <26 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 12>; @@ -284,7 +284,7 @@ }; spi1: spi@4002d000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002d000 0x88>; interrupts = <27 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 13>; @@ -301,7 +301,7 @@ }; ftm0: ftm@40038000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40038000 0x98>; interrupts = <42 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>, @@ -311,7 +311,7 @@ }; ftm1: ftm@40039000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40039000 0x98>; interrupts = <43 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>, @@ -321,7 +321,7 @@ }; ftm2: ftm@4003a000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4003a000 0x98>; interrupts = <44 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>, @@ -331,7 +331,7 @@ }; ftm3: ftm@400b9000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x400b9000 0x98>; interrupts = <71 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>, diff --git a/dts/arm/nxp/nxp_k66.dtsi b/dts/arm/nxp/nxp_k66.dtsi index f5595674c906c..e598bd1d217c0 100644 --- a/dts/arm/nxp/nxp_k66.dtsi +++ b/dts/arm/nxp/nxp_k66.dtsi @@ -14,7 +14,7 @@ / { soc { lpuart0: lpuart@400c4000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x400c4000 0x14>; interrupts = <86 0>; clocks = <&sim KINETIS_SIM_CORESYS_CLK 0x1038 20>; diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index f478e1eb1a828..8be5ed81e06ef 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -101,7 +101,7 @@ }; rtc: rtc@4003d000 { - compatible = "nxp,kinetis-rtc"; + compatible = "nxp,rtc"; reg = <0x4003d000 0x1000>; interrupts = <46 0>, <47 0>; interrupt-names = "alarm", "seconds"; @@ -335,7 +335,7 @@ }; spi0: spi@4002c000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002c000 0x88>; interrupts = <26 3>; dmas = <&edma0 0 14>, <&edma0 0 15>; @@ -349,7 +349,7 @@ }; spi1: spi@4002d000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002d000 0x88>; interrupts = <27 3>; dmas = <&edma0 0 16>, <&edma0 0 16>; @@ -364,7 +364,7 @@ }; spi2: spi@400ac000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x400ac000 0x88>; interrupts = <65 3>; dmas = <&edma0 0 38>, <&edma0 0 39>; @@ -386,7 +386,7 @@ }; ftm0: ftm@40038000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40038000 0x98>; interrupts = <42 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -395,7 +395,7 @@ }; ftm1: ftm@40039000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40039000 0x98>; interrupts = <43 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -404,7 +404,7 @@ }; ftm2: ftm@4003a000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4003a000 0x98>; interrupts = <44 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -413,7 +413,7 @@ }; ftm3: ftm@400b9000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x400b9000 0x98>; interrupts = <71 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; diff --git a/dts/arm/nxp/nxp_k8x.dtsi b/dts/arm/nxp/nxp_k8x.dtsi index 7270656fd0693..53a023b7ebd58 100644 --- a/dts/arm/nxp/nxp_k8x.dtsi +++ b/dts/arm/nxp/nxp_k8x.dtsi @@ -40,7 +40,7 @@ soc { mpu: mpu@4000d000 { - compatible = "nxp,kinetis-mpu"; + compatible = "nxp,sysmpu"; reg = <0x4000d000 0x1000>; status = "disabled"; }; @@ -210,7 +210,7 @@ }; lpuart0: lpuart@400c4000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x400c4000 0x1000>; interrupts = <30 0>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x102c 4>; @@ -220,7 +220,7 @@ }; lpuart1: lpuart@400c5000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x400c5000 0x1000>; interrupts = <31 0>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x102c 5>; @@ -230,7 +230,7 @@ }; lpuart2: lpuart@400c6000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x400c6000 0x1000>; interrupts = <32 0>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x102c 6>; @@ -240,7 +240,7 @@ }; lpuart3: lpuart@400c7000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x400c7000 0x1000>; interrupts = <33 0>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x102c 7>; @@ -250,7 +250,7 @@ }; lpuart4: lpuart@400d6000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x400d6000 0x1000>; interrupts = <34 0>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x102c 22>; @@ -290,7 +290,7 @@ }; ftm0: ftm@40038000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40038000 0x1000>; interrupts = <42 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -299,7 +299,7 @@ }; ftm1: ftm@40039000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40039000 0x1000>; interrupts = <43 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -308,7 +308,7 @@ }; ftm2: ftm@4003a000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4003a000 0x1000>; interrupts = <44 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -317,7 +317,7 @@ }; ftm3: ftm@400b9000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x400b9000 0x1000>; interrupts = <71 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -326,7 +326,7 @@ }; rtc: rtc@4003d000 { - compatible = "nxp,kinetis-rtc"; + compatible = "nxp,rtc"; reg = <0x4003d000 0x1000>; interrupts = <46 0>, <47 0>; interrupt-names = "alarm", "seconds"; @@ -335,7 +335,7 @@ }; spi0: spi@4002c000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002c000 0x1000>; interrupts = <26 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103c 12>; @@ -345,7 +345,7 @@ }; spi1: spi@4002d000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002d000 0x1000>; interrupts = <27 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103c 13>; @@ -355,7 +355,7 @@ }; spi2: spi@400ac000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x400ac000 0x1000>; interrupts = <65 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x1030 12>; diff --git a/dts/arm/nxp/nxp_ke1xf.dtsi b/dts/arm/nxp/nxp_ke1xf.dtsi index d3dc6e96dcca3..db59687903291 100644 --- a/dts/arm/nxp/nxp_ke1xf.dtsi +++ b/dts/arm/nxp/nxp_ke1xf.dtsi @@ -114,7 +114,7 @@ }; mpu: mpu@4000d000 { - compatible = "nxp,kinetis-mpu"; + compatible = "nxp,sysmpu"; reg = <0x4000d000 0x1000>; status = "disabled"; }; @@ -265,7 +265,7 @@ }; rtc: rtc@4003d000 { - compatible = "nxp,kinetis-rtc"; + compatible = "nxp,rtc"; reg = <0x4003d000 0x1000>; interrupts = <46 0>, <47 0>; interrupt-names = "alarm", "seconds"; @@ -325,7 +325,7 @@ }; lpuart0: uart@4006a000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006a000 0x1000>; interrupts = <31 0>, <32 0>; interrupt-names = "transmit", "receive"; @@ -336,7 +336,7 @@ }; lpuart1: uart@4006b000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006b000 0x1000>; interrupts = <33 0>, <34 0>; interrupt-names = "transmit", "receive"; @@ -347,7 +347,7 @@ }; lpuart2: uart@4006c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006c000 0x1000>; interrupts = <35 0>, <36 0>; interrupt-names = "transmit", "receive"; @@ -387,6 +387,8 @@ status = "disabled"; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; }; lpspi1: spi@4002d000 { @@ -397,6 +399,8 @@ status = "disabled"; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; }; flexcan0: can@40024000 { @@ -535,7 +539,7 @@ }; ftm0: ftm@40038000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40038000 0x1000>; interrupts = <42 0>; clocks = <&pcc 0xe0 KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -544,7 +548,7 @@ }; ftm1: ftm@40039000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40039000 0x1000>; interrupts = <43 0>; clocks = <&pcc 0xe4 KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -553,7 +557,7 @@ }; ftm2: ftm@4003a000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4003a000 0x1000>; interrupts = <44 0>; clocks = <&pcc 0xe8 KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -562,7 +566,7 @@ }; ftm3: ftm@40026000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40026000 0x1000>; interrupts = <71 0>; clocks = <&pcc 0x98 KINETIS_PCC_SRC_FIRC_ASYNC>; diff --git a/dts/arm/nxp/nxp_ke1xz.dtsi b/dts/arm/nxp/nxp_ke1xz.dtsi index 731bdeff60abc..fe6b93c28764a 100644 --- a/dts/arm/nxp/nxp_ke1xz.dtsi +++ b/dts/arm/nxp/nxp_ke1xz.dtsi @@ -153,7 +153,7 @@ }; lpuart0: uart@4006a000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006a000 0x1000>; interrupts = <12 0>; clocks = <&pcc 0x1a8 KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -161,7 +161,7 @@ }; lpuart1: uart@4006b000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006b000 0x1000>; interrupts = <13 0>; clocks = <&pcc 0x1ac KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -169,7 +169,7 @@ }; lpuart2: uart@4006c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006c000 0x1000>; interrupts = <14 0>; clocks = <&pcc 0x1b0 KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -345,7 +345,7 @@ }; ftm0: ftm@40038000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40038000 0x1000>; interrupts = <17 0>; clocks = <&pcc 0xe0 KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -354,7 +354,7 @@ }; ftm1: ftm@40039000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40039000 0x1000>; interrupts = <18 0>; clocks = <&pcc 0xe4 KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -363,7 +363,7 @@ }; ftm2: ftm@4003a000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4003a000 0x1000>; interrupts = <19 0>; clocks = <&pcc 0xe8 KINETIS_PCC_SRC_FIRC_ASYNC>; @@ -405,7 +405,7 @@ }; rtc: rtc@4003d000 { - compatible = "nxp,kinetis-rtc"; + compatible = "nxp,rtc"; reg = <0x4003d000 0x1000>; interrupts = <20 0>; clock-frequency = <32768>; @@ -429,6 +429,8 @@ status = "disabled"; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; }; lpspi1: spi@4002d000 { @@ -439,6 +441,8 @@ status = "disabled"; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; }; edma: dma-controller@40008000 { diff --git a/dts/arm/nxp/nxp_kv5x.dtsi b/dts/arm/nxp/nxp_kv5x.dtsi index 230e0dccf62f6..ae21073034355 100644 --- a/dts/arm/nxp/nxp_kv5x.dtsi +++ b/dts/arm/nxp/nxp_kv5x.dtsi @@ -35,7 +35,7 @@ soc { mpu: mpu@4000d000 { - compatible = "nxp,kinetis-mpu"; + compatible = "nxp,sysmpu"; reg = <0x4000d000 0x1000>; status = "disabled"; }; @@ -207,7 +207,7 @@ }; ftm0: ftm@40038000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40038000 0x1000>; interrupts = <42 0>; prescaler = <16>; @@ -215,7 +215,7 @@ }; ftm1: ftm@40039000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40039000 0x1000>; interrupts = <43 0>; prescaler = <16>; @@ -223,7 +223,7 @@ }; ftm2: ftm@4003a000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4003a000 0x1000>; interrupts = <53 0>; prescaler = <16>; @@ -231,7 +231,7 @@ }; ftm3: ftm@40026000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40026000 0x1000>; interrupts = <71 0>; prescaler = <16>; @@ -239,7 +239,7 @@ }; spi0: spi@4002c000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002c000 0x1000>; interrupts = <26 3>; status = "disabled"; @@ -249,7 +249,7 @@ }; spi1: spi@4002d000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002d000 0x1000>; interrupts = <27 3>; status = "disabled"; @@ -259,7 +259,7 @@ }; spi2: spi@400ac000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x400ac000 0x1000>; interrupts = <65 3>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_kw2xd.dtsi b/dts/arm/nxp/nxp_kw2xd.dtsi index e394885aa8a50..31738e068c48a 100644 --- a/dts/arm/nxp/nxp_kw2xd.dtsi +++ b/dts/arm/nxp/nxp_kw2xd.dtsi @@ -256,7 +256,7 @@ }; spi0: spi@4002c000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002c000 0x88>; interrupts = <26 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 12>; @@ -266,7 +266,7 @@ }; spi1: spi@4002d000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002d000 0x88>; interrupts = <27 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 13>; @@ -295,7 +295,7 @@ }; ftm0: ftm@40038000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40038000 0x98>; interrupts = <42 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -304,7 +304,7 @@ }; ftm1: ftm@40039000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40039000 0x98>; interrupts = <43 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; @@ -313,7 +313,7 @@ }; ftm2: ftm@4003a000{ - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4003a000 0x98>; interrupts = <44 0>; clocks = <&mcg KINETIS_MCG_FIXED_FREQ_CLK>; diff --git a/dts/arm/nxp/nxp_kw40z.dtsi b/dts/arm/nxp/nxp_kw40z.dtsi index 9046fe56a880d..3e32348ac4b2f 100644 --- a/dts/arm/nxp/nxp_kw40z.dtsi +++ b/dts/arm/nxp/nxp_kw40z.dtsi @@ -115,7 +115,7 @@ }; lpuart0: lpuart@40054000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40054000 0x18>; interrupts = <12 0>; clocks = <&sim KINETIS_SIM_CORESYS_CLK 0x1038 20>; @@ -171,7 +171,7 @@ }; spi0: spi@4002c000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002c000 0x9C>; interrupts = <10 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 12>; @@ -182,7 +182,7 @@ }; spi1: spi@4002d000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002d000 0x9C>; interrupts = <29 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 13>; diff --git a/dts/arm/nxp/nxp_kw41z.dtsi b/dts/arm/nxp/nxp_kw41z.dtsi index b927e198077e8..1d7fa4fdbbd78 100644 --- a/dts/arm/nxp/nxp_kw41z.dtsi +++ b/dts/arm/nxp/nxp_kw41z.dtsi @@ -55,7 +55,7 @@ }; rtc: rtc@4003d000 { - compatible = "nxp,kinetis-rtc"; + compatible = "nxp,rtc"; reg = <0x4003d000 0x20>; interrupts = <20 0>; clock-frequency = <32768>; @@ -122,7 +122,7 @@ }; lpuart0: lpuart@40054000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40054000 0x18>; interrupts = <12 0>; clocks = <&sim KINETIS_SIM_CORESYS_CLK 0x1038 20>; @@ -178,7 +178,7 @@ }; spi0: spi@4002c000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002c000 0x9C>; interrupts = <10 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 12>; @@ -189,7 +189,7 @@ }; spi1: spi@4002d000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x4002d000 0x9C>; interrupts = <29 3>; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 13>; diff --git a/dts/arm/nxp/nxp_mcxa156.dtsi b/dts/arm/nxp/nxp_mcxa156.dtsi index f6b0bca6fbf12..c44cedf0e4595 100644 --- a/dts/arm/nxp/nxp_mcxa156.dtsi +++ b/dts/arm/nxp/nxp_mcxa156.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include / { cpus { @@ -129,10 +130,23 @@ }; lpuart0: lpuart@4009f000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4009f000 0x1000>; interrupts = <31 0>; clocks = <&syscon MCUX_LPUART0_CLK>; + /* DMA channels 0 and 1, muxed to LPUART0 RX and TX */ + dmas = <&edma0 0 21>, <&edma0 1 22>; + dma-names = "rx", "tx"; + }; + + lpuart1: lpuart@400a0000 { + compatible = "nxp,lpuart"; + reg = <0x400a0000 0x1000>; + interrupts = <32 0>; + clocks = <&syscon MCUX_LPUART1_CLK>; + /* DMA channels 2 and 3, muxed to LPUART1 RX and TX */ + dmas = <&edma0 2 23>, <&edma0 3 24>; + dma-names = "rx", "tx"; }; fmu: flash-controller@40095000 { @@ -151,6 +165,66 @@ }; }; + ctimer0: ctimer@40004000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x40004000 0x1000>; + interrupts = <39 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER0_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer1: ctimer@40005000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x40005000 0x1000>; + interrupts = <40 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER1_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer2: ctimer@40006000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x40006000 0x1000>; + interrupts = <41 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER2_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer3: ctimer@40007000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x40007000 0x1000>; + interrupts = <42 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER3_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer4: ctimer@40008000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x40008000 0x1000>; + interrupts = <43 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER4_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + dac0: dac@400b4000 { compatible = "nxp,lpdac"; reg = <0x400b4000 0x1000>; @@ -160,6 +234,42 @@ #io-channel-cells = <1>; }; + edma0: dma-controller@40080000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + nxp,version = <4>; + dma-channels = <8>; + dma-requests = <86>; + + reg = <0x40080000 0x1000>; + interrupts = <2 0>, <3 0>, <4 0>, <5 0>, + <6 0>, <7 0>, <8 0>, <9 0>; + no-error-irq; + status = "disabled"; + }; + + flexcan0: can@400cc000 { + compatible = "nxp,flexcan"; + reg = <0x400cc000 0x1000>; + interrupts = <19 0>; + interrupt-names = "common"; + clocks = <&syscon MCUX_FLEXCAN0_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + flexio0: flexio@40099000 { + compatible = "nxp,flexio"; + reg = <0x40099000 0x1000>; + status = "disabled"; + interrupts = <23 0>; + clocks = <&syscon MCUX_FLEXIO0_CLK>; + flexio0_lcd: flexio0-lcd { + compatible = "nxp,mipi-dbi-flexio-lcdif"; + status = "disabled"; + }; + }; + flexpwm0: flexpwm@400a9000 { compatible = "nxp,flexpwm"; reg = <0x400a9000 0x1000>; @@ -237,6 +347,151 @@ run-in-wait; }; }; + + lpadc0: lpadc@400af000 { + compatible = "nxp,lpc-lpadc"; + reg = <0x400af000 0x1000>; + interrupts = <62 0>; + status = "disabled"; + clk-divider = <1>; + clk-source = <0>; + voltage-ref= <2>; + calibration-average = <128>; + power-level = <0>; + offset-value-a = <0>; + offset-value-b = <0>; + #io-channel-cells = <1>; + clocks = <&syscon MCUX_LPADC1_CLK>; + }; + + lpadc1: lpadc@400b0000 { + compatible = "nxp,lpc-lpadc"; + reg = <0x400b0000 0x1000>; + interrupts = <63 0>; + status = "disabled"; + clk-divider = <1>; + clk-source = <0>; + voltage-ref= <2>; + calibration-average = <128>; + power-level = <1>; + offset-value-a = <0>; + offset-value-b = <0>; + #io-channel-cells = <1>; + clocks = <&syscon MCUX_LPADC2_CLK>; + }; + + lpcmp0: lpcmp@400b1000 { + compatible = "nxp,lpcmp"; + reg = <0x400b1000 0x1000>; + interrupts = <64 0>; + status = "disabled"; + #io-channel-cells = <2>; + }; + + lpcmp1: lpcmp@400b2000 { + compatible = "nxp,lpcmp"; + reg = <0x400b2000 0x1000>; + interrupts = <65 0>; + status = "disabled"; + #io-channel-cells = <2>; + }; + + lpi2c0: i2c@4009a000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4009a000 0x1000>; + interrupts = <26 0>; + clocks = <&syscon MCUX_LPI2C0_CLK>; + status = "disabled"; + }; + + lpi2c1: i2c@4009b000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4009b000 0x1000>; + interrupts = <27 0>; + clocks = <&syscon MCUX_LPI2C1_CLK>; + status = "disabled"; + }; + + lpi2c2: i2c@400d4000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x400d4000 0x1000>; + interrupts = <77 0>; + clocks = <&syscon MCUX_LPI2C2_CLK>; + status = "disabled"; + }; + + lpi2c3: i2c@400d5000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x400d5000 0x1000>; + interrupts = <78 0>; + clocks = <&syscon MCUX_LPI2C3_CLK>; + status = "disabled"; + }; + + lpspi0: spi@4009c000 { + compatible = "nxp,lpspi"; + reg = <0x4009c000 0x1000>; + interrupts = <28 0>; + clocks = <&syscon MCUX_LPSPI0_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi1: spi@4009d000 { + compatible = "nxp,lpspi"; + reg = <0x4009d000 0x1000>; + interrupts = <29 0>; + clocks = <&syscon MCUX_LPSPI1_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lptmr0: lptmr@400ab000 { + compatible = "nxp,lptmr"; + reg = <0x400ab000 0x1000>; + interrupts = <55 0>; + clock-frequency = <16000>; + prescaler = <1>; + clk-source = <1>; + resolution = <32>; + status = "disabled"; + }; + + usb: usbd@400a4000 { + compatible = "nxp,kinetis-usbd"; + reg = <0x400a4000 0x1000>; + interrupts = <36 1>; + interrupt-names = "usb"; + num-bidir-endpoints = <16>; + status = "disabled"; + no-voltage-regulator; + }; + + wwdt0: watchdog@4000c000 { + compatible = "nxp,lpc-wwdt"; + reg = <0x4000c000 0x1000>; + interrupts = <60 0>; + status = "disabled"; + clk-divider = <1>; + }; }; }; diff --git a/dts/arm/nxp/nxp_mcxc141.dtsi b/dts/arm/nxp/nxp_mcxc141.dtsi index a8918a521e79a..7518beaa4713d 100644 --- a/dts/arm/nxp/nxp_mcxc141.dtsi +++ b/dts/arm/nxp/nxp_mcxc141.dtsi @@ -7,7 +7,7 @@ #include &sram0 { - reg = <0x1FFFF000 DT_SIZE_K(8)>; + reg = <0x1FFFF800 DT_SIZE_K(8)>; }; &flash0 { diff --git a/dts/arm/nxp/nxp_mcxc_common.dtsi b/dts/arm/nxp/nxp_mcxc_common.dtsi index 416caf77e1530..ed5ddf8d77c4e 100644 --- a/dts/arm/nxp/nxp_mcxc_common.dtsi +++ b/dts/arm/nxp/nxp_mcxc_common.dtsi @@ -67,7 +67,7 @@ status = "disabled"; #address-cells = <1>; #size-cells = <1>; - fsec = <0xff>; + fsec = <0xfe>; fopt = <0x3d>; config-field-offset = <0x400>; @@ -223,7 +223,7 @@ }; lpuart0: uart@40054000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40054000 0x1000>; interrupts = <12 0>; clocks = <&sim KINETIS_SIM_MCGPCLK 0x1038 20>; @@ -231,7 +231,7 @@ }; lpuart1: uart@40055000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40055000 0x1000>; interrupts = <13 0>; clocks = <&sim KINETIS_SIM_MCGPCLK 0x1038 21>; @@ -290,7 +290,7 @@ }; rtc: rtc@4003d000 { - compatible = "nxp,kinetis-rtc"; + compatible = "nxp,rtc"; reg = <0x4003d000 0x1000>; interrupts = <20 0>, <21 0>; interrupt-names = "alarm", "seconds"; diff --git a/dts/arm/nxp/nxp_mcxn23x_common.dtsi b/dts/arm/nxp/nxp_mcxn23x_common.dtsi index a396ca9dfed57..ff64cf09d0e42 100644 --- a/dts/arm/nxp/nxp_mcxn23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn23x_common.dtsi @@ -180,7 +180,7 @@ #size-cells = <1>; flexcomm0_lpuart0: lpuart@92000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x92000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM0_CLK>; status = "disabled"; @@ -192,6 +192,8 @@ #address-cells = <1>; #size-cells = <0>; status = "disabled"; + tx-fifo-size = <16>; + rx-fifo-size = <16>; }; flexcomm0_lpi2c0: lpi2c@92800 { compatible = "nxp,lpi2c"; @@ -214,7 +216,7 @@ #size-cells = <1>; flexcomm1_lpuart1: lpuart@93000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x93000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM1_CLK>; /* DMA channels 0 and 1, muxed to LPUART1 RX and TX */ @@ -231,6 +233,8 @@ /* DMA channels 0 and 1, muxed to LPSPI1 RX and TX */ dmas = <&edma0 0 71>, <&edma0 1 72>; dma-names = "rx", "tx"; + tx-fifo-size = <16>; + rx-fifo-size = <16>; status = "disabled"; }; flexcomm1_lpi2c1: lpi2c@93800 { @@ -254,7 +258,7 @@ #size-cells = <1>; flexcomm2_lpuart2: lpuart@94000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x94000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM2_CLK>; /* DMA channels 4 and 5, muxed to LPUART2 RX and TX */ @@ -271,6 +275,8 @@ /* DMA channels 4 and 5, muxed to LPSPI2 RX and TX */ dmas = <&edma0 4 73>, <&edma0 5 74>; dma-names = "rx", "tx"; + tx-fifo-size = <16>; + rx-fifo-size = <16>; status = "disabled"; }; flexcomm2_lpi2c2: lpi2c@94800 { @@ -294,7 +300,7 @@ #size-cells = <1>; flexcomm3_lpuart3: lpuart@95000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x95000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM3_CLK>; status = "disabled"; @@ -305,6 +311,8 @@ clocks = <&syscon MCUX_FLEXCOMM3_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; status = "disabled"; }; flexcomm3_lpi2c3: lpi2c@95800 { @@ -328,7 +336,7 @@ #size-cells = <1>; flexcomm4_lpuart4: lpuart@b4000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb4000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM4_CLK>; /* DMA channels 2 and 3, muxed to LPUART4 RX and TX */ @@ -345,6 +353,8 @@ /* DMA channels 2 and 3, muxed to LPSPI4 RX and TX */ dmas = <&edma0 2 77>, <&edma0 3 78>; dma-names = "rx", "tx"; + tx-fifo-size = <16>; + rx-fifo-size = <16>; status = "disabled"; }; flexcomm4_lpi2c4: lpi2c@b4800 { @@ -368,7 +378,7 @@ #size-cells = <1>; flexcomm5_lpuart5: lpuart@b5000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb5000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM5_CLK>; status = "disabled"; @@ -379,6 +389,8 @@ clocks = <&syscon MCUX_FLEXCOMM5_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; status = "disabled"; }; flexcomm5_lpi2c5: lpi2c@b5800 { @@ -402,7 +414,7 @@ #size-cells = <1>; flexcomm6_lpuart6: lpuart@b6000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb6000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM6_CLK>; status = "disabled"; @@ -413,6 +425,8 @@ clocks = <&syscon MCUX_FLEXCOMM6_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; status = "disabled"; }; flexcomm6_lpi2c6: lpi2c@b6800 { @@ -436,7 +450,7 @@ #size-cells = <1>; flexcomm7_lpuart7: lpuart@b7000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb7000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM7_CLK>; status = "disabled"; @@ -447,6 +461,8 @@ clocks = <&syscon MCUX_FLEXCOMM7_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; status = "disabled"; }; flexcomm7_lpi2c7: lpi2c@b7800 { @@ -786,6 +802,32 @@ }; }; + i3c0: i3c@21000 { + compatible = "nxp,mcux-i3c"; + reg = <0x21000 0x1000>; + interrupts = <95 0>; + clocks = <&syscon MCUX_I3C_CLK>; + clk-divider = <6>; + clk-divider-slow = <1>; + clk-divider-tc = <1>; + status = "disabled"; + #address-cells = <3>; + #size-cells = <0>; + }; + + i3c1: i3c@22000 { + compatible = "nxp,mcux-i3c"; + reg = <0x22000 0x1000>; + interrupts = <96 0>; + clocks = <&syscon MCUX_I3C2_CLK>; + clk-divider = <6>; + clk-divider-slow = <1>; + clk-divider-tc = <1>; + status = "disabled"; + #address-cells = <3>; + #size-cells = <0>; + }; + lptmr0: lptmr@4a000 { compatible = "nxp,lptmr"; reg = <0x4a000 0x1000>; @@ -838,6 +880,17 @@ status = "disabled"; }; }; + + rtc: rtc@4c000 { + compatible = "nxp,irtc"; + reg = <0x4c000 0x1000>; + status = "disabled"; + interrupts = <52 0>; + prescaler = <1>; + clock-frequency = <16384>; + clock-src = <0>; + alarms-count = <1>; + }; }; &systick { diff --git a/dts/arm/nxp/nxp_mcxn94x_common.dtsi b/dts/arm/nxp/nxp_mcxn94x_common.dtsi index 5fc209b3f7681..195725a53c9d7 100644 --- a/dts/arm/nxp/nxp_mcxn94x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn94x_common.dtsi @@ -187,7 +187,7 @@ #size-cells = <1>; flexcomm0_lpuart0: lpuart@92000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x92000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM0_CLK>; status = "disabled"; @@ -198,6 +198,8 @@ clocks = <&syscon MCUX_FLEXCOMM0_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm0_lpi2c0: lpi2c@92800 { @@ -221,7 +223,7 @@ #size-cells = <1>; flexcomm1_lpuart1: lpuart@93000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x93000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM1_CLK>; /* DMA channels 0 and 1, muxed to LPUART1 RX and TX */ @@ -238,6 +240,8 @@ /* DMA channels 0 and 1, muxed to LPSPI1 RX and TX */ dmas = <&edma0 0 71>, <&edma0 1 72>; dma-names = "rx", "tx"; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm1_lpi2c1: lpi2c@93800 { @@ -261,7 +265,7 @@ #size-cells = <1>; flexcomm2_lpuart2: lpuart@94000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x94000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM2_CLK>; /* DMA channels 4 and 5, muxed to LPUART2 RX and TX */ @@ -278,6 +282,8 @@ /* DMA channels 4 and 5, muxed to LPSPI2 RX and TX */ dmas = <&edma0 4 73>, <&edma0 5 74>; dma-names = "rx", "tx"; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm2_lpi2c2: lpi2c@94800 { @@ -301,7 +307,7 @@ #size-cells = <1>; flexcomm3_lpuart3: lpuart@95000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x95000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM3_CLK>; status = "disabled"; @@ -312,6 +318,8 @@ clocks = <&syscon MCUX_FLEXCOMM3_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm3_lpi2c3: lpi2c@95800 { @@ -335,7 +343,7 @@ #size-cells = <1>; flexcomm4_lpuart4: lpuart@b4000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb4000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM4_CLK>; /* DMA channels 2 and 3, muxed to LPUART4 RX and TX */ @@ -352,6 +360,8 @@ /* DMA channels 2 and 3, muxed to LPSPI4 RX and TX */ dmas = <&edma0 2 77>, <&edma0 3 78>; dma-names = "rx", "tx"; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm4_lpi2c4: lpi2c@b4800 { @@ -375,7 +385,7 @@ #size-cells = <1>; flexcomm5_lpuart5: lpuart@b5000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb5000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM5_CLK>; status = "disabled"; @@ -386,6 +396,8 @@ clocks = <&syscon MCUX_FLEXCOMM5_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm5_lpi2c5: lpi2c@b5800 { @@ -409,7 +421,7 @@ #size-cells = <1>; flexcomm6_lpuart6: lpuart@b6000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb6000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM6_CLK>; status = "disabled"; @@ -420,6 +432,8 @@ clocks = <&syscon MCUX_FLEXCOMM6_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm6_lpi2c6: lpi2c@b6800 { @@ -443,7 +457,7 @@ #size-cells = <1>; flexcomm7_lpuart7: lpuart@b7000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb7000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM7_CLK>; status = "disabled"; @@ -454,6 +468,8 @@ clocks = <&syscon MCUX_FLEXCOMM7_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm7_lpi2c7: lpi2c@b7800 { @@ -477,7 +493,7 @@ #size-cells = <1>; flexcomm8_lpuart8: lpuart@b8000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb8000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM8_CLK>; status = "disabled"; @@ -488,6 +504,8 @@ clocks = <&syscon MCUX_FLEXCOMM8_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm8_lpi2c8: lpi2c@b8800 { @@ -511,7 +529,7 @@ #size-cells = <1>; flexcomm9_lpuart9: lpuart@b9000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0xb9000 0x1000>; clocks = <&syscon MCUX_FLEXCOMM9_CLK>; status = "disabled"; @@ -522,6 +540,8 @@ clocks = <&syscon MCUX_FLEXCOMM9_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; status = "disabled"; }; flexcomm9_lpi2c9: lpi2c@b9800 { @@ -534,6 +554,15 @@ }; }; + mbox: mbox@b2000 { + compatible = "nxp,mbox-mailbox"; + reg = <0xb2000 0xec>; + interrupts = <54 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "disabled"; + }; + edma0: dma-controller@80000 { #dma-cells = <2>; compatible = "nxp,mcux-edma"; @@ -582,6 +611,11 @@ /* MCXN94x ROM Flash API supports writing of 128B pages. */ write-block-size = <128>; }; + + uuid: uuid@1100000 { + compatible = "nxp,lpc-uid"; + reg = <0x1100000 0x10>; + }; }; os_timer: timers@49000 { @@ -866,6 +900,16 @@ clocks = <&syscon MCUX_LPADC2_CLK>; }; + usb0: usbd@dd000 { + compatible = "nxp,kinetis-usbd"; + reg = <0xdd000 0x1000>; + interrupts = <50 1>; + interrupt-names = "usbfs0"; + num-bidir-endpoints = <16>; + no-voltage-regulator; + status = "disabled"; + }; + usb1: usbd@10b000 { compatible = "nxp,ehci"; reg = <0x10b000 0x1000>; @@ -875,6 +919,12 @@ status = "disabled"; }; + usbphy1: usbphy@10a000 { + compatible = "nxp,usbphy"; + reg = <0x10a000 0x1000>; + status = "disabled"; + }; + lpcmp0: lpcmp@51000 { compatible = "nxp,lpcmp"; reg = <0x51000 0x1000>; @@ -1020,6 +1070,39 @@ clock-src = <0>; alarms-count = <1>; }; + + sai0: sai@106000 { + compatible = "nxp,mcux-i2s"; + #address-cells = <1>; + #size-cells = <0>; + #pinmux-cells = <2>; + reg = < 0x106000 0x1000>; + clocks = <&syscon MCUX_SAI0_CLK>; + pinmuxes = <&sai0 0x100 0x40000000>; + interrupts = <59 0>; + dmas = <&edma0 0 99>, <&edma0 0 100>; + dma-names = "rx", "tx"; + nxp,tx-channel = <1>; + nxp,tx-dma-channel = <0>; + nxp,rx-dma-channel = <1>; + status = "disabled"; + }; + sai1: sai@107000 { + compatible = "nxp,mcux-i2s"; + #address-cells = <1>; + #size-cells = <0>; + #pinmux-cells = <2>; + reg = < 0x107000 0x1000>; + clocks = <&syscon MCUX_SAI1_CLK>; + pinmuxes = <&sai1 0x100 0x40000000>; + interrupts = <60 0>; + dmas = <&edma0 0 101>, <&edma0 0 102>; + dma-names = "rx", "tx"; + nxp,tx-channel = <1>; + nxp,tx-dma-channel = <2>; + nxp,rx-dma-channel = <3>; + status = "disabled"; + }; }; &systick { diff --git a/dts/arm/nxp/nxp_mcxw71.dtsi b/dts/arm/nxp/nxp_mcxw71.dtsi index 1d5a55bec50ec..ba0d6e263b7e2 100644 --- a/dts/arm/nxp/nxp_mcxw71.dtsi +++ b/dts/arm/nxp/nxp_mcxw71.dtsi @@ -1,384 +1,66 @@ /* - * Copyright 2023-2024 NXP + * Copyright 2023-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include -#include -#include -#include +#include "nxp_mcxw7x_common.dtsi" -/ { - aliases { - watchdog0 = &wdog0; - }; - - chosen { - zephyr,bt-hci = &hci; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - compatible = "arm,cortex-m33f"; - reg = <0>; - #address-cells = <1>; - #size-cells = <1>; - - mpu: mpu@e000ed90 { - compatible = "arm,armv8m-mpu"; - reg = <0xe000ed90 0x40>; - }; - }; - }; - - soc { - fmu: memory-controller@50020000 { - ranges = <0x0 0x10000000 DT_SIZE_M(1)>; - #address-cells = <1>; - #size-cells = <1>; - compatible = "nxp,msf1"; - reg = <0x50020000 0x1000>; - interrupts = <27 0>; - status = "disabled"; - - flash: flash@0 { - reg = <0x0 DT_SIZE_M(1)>; - compatible = "soc-nv-flash"; - write-block-size = <16>; - erase-block-size = <8192>; - }; - }; - - ctcm: sram@14000000 { - ranges = <0x0 0x14000000 DT_SIZE_K(16)>; - #address-cells = <1>; - #size-cells = <1>; - - ctcm0: code_memory@0 { - compatible = "mmio-sram"; - reg = <0x0 DT_SIZE_K(16)>; - }; - }; - - stcm: sram@30000000 { - ranges = <0x0 0x30000000 DT_SIZE_K(112)>; - #address-cells = <1>; - #size-cells = <1>; - - stcm0: system_memory@0 { - compatible = "mmio-sram"; - /* With only the first 64KB having ECC */ - reg = <0x0 DT_SIZE_K(104)>; - }; - - stcm1: system_memory@1a000 { - compatible = "zephyr,memory-region","mmio-sram"; - reg = <0x1a000 DT_SIZE_K(8)>; - zephyr,memory-region = "RetainedMem"; - }; - }; - - smu2: sram@489c0000 { - ranges = <0x0 0x489c0000 DT_SIZE_K(40)>; - }; - - peripheral: peripheral@50000000 { - ranges = <0x0 0x50000000 0x10000000>; - #address-cells = <1>; - #size-cells = <1>; - - pbridge2: pbridge2@0 { - ranges = <>; - reg = <0x0 0x4b000>; - #address-cells = <1>; - #size-cells = <1>; - }; - - fast_peripheral0: fast_peripherals0@8000000 { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x8000000 0x40000>; - }; +&fmu { + ranges = <0x0 0x10000000 DT_SIZE_M(1)>; +}; - fast_peripheral1: fast_peripherals1@8800000 { - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x8800000 0x210000>; - }; - }; - }; +&flash { + reg = <0x0 DT_SIZE_M(1)>; +}; - pinctrl: pinctrl { - compatible = "nxp,port-pinctrl"; - }; +&ctcm { + ranges = <0x0 0x14000000 DT_SIZE_K(16)>; }; -&nvic { - arm,num-irq-priority-bits = <3>; +&ctcm0 { + reg = <0x0 DT_SIZE_K(16)>; }; -&smu2 { - #address-cells = <1>; - #size-cells = <1>; +&stcm { + ranges = <0x0 0x30000000 DT_SIZE_K(112)>; - rpmsgmem: memory@8800 { + stcm1: system_memory@1a000 { compatible = "zephyr,memory-region","mmio-sram"; - reg = <0x8800 DT_SIZE_K(6)>; - zephyr,memory-region = "rpmsg_sh_mem"; - zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; + reg = <0x1a000 DT_SIZE_K(8)>; + zephyr,memory-region = "RetainedMem"; }; }; -&pbridge2 { - #address-cells = <1>; - #size-cells = <1>; - - scg: clock-controller@1e000 { - compatible = "nxp,scg-k4"; - reg = <0x1e000 0x404>; - #clock-cells = <2>; - }; - - porta: pinctrl@42000 { - compatible = "nxp,port-pinmux"; - reg = <0x42000 0xe0>; - clocks = <&scg SCG_K4_SLOW_CLK 0x108>; - }; - - portb: pinctrl@43000 { - compatible = "nxp,port-pinmux"; - reg = <0x43000 0xe0>; - clocks = <&scg SCG_K4_SLOW_CLK 0x10c>; - }; - - portc: pinctrl@44000 { - compatible = "nxp,port-pinmux"; - reg = <0x44000 0xe0>; - clocks = <&scg SCG_K4_SLOW_CLK 0x110>; - }; - - portd: pinctrl@45000 { - compatible = "nxp,port-pinmux"; - reg = <0x45000 0xe0>; - clocks = <&scg SCG_K4_SLOW_CLK 0>; - }; - - lpuart0: serial@38000 { - compatible = "nxp,kinetis-lpuart"; - reg = <0x38000 0x34>; - interrupts = <44 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0xe0>; - status = "disabled"; - }; - - lpuart1: serial@39000 { - compatible = "nxp,kinetis-lpuart"; - reg = <0x39000 0x34>; - interrupts = <45 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0xe4>; - status = "disabled"; - }; - - lpi2c0: i2c@33000 { - compatible = "nxp,lpi2c"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x33000 0x200>; - interrupts = <39 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0xe0>; - status = "disabled"; - }; - - lpi2c1: i2c@34000 { - compatible = "nxp,lpi2c"; - clock-frequency = ; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x34000 0x200>; - interrupts = <40 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0xe4>; - status = "disabled"; - }; - - lpspi0: spi@36000 { - compatible = "nxp,lpspi"; - reg = <0x36000 0x800>; - interrupts = <42 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0xd8>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - lpspi1: spi@37000 { - compatible = "nxp,lpspi"; - reg = <0x37000 0x800>; - interrupts = <43 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0xdc>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - - gpiod: gpio@46000{ - compatible = "nxp,kinetis-gpio"; - status = "disabled"; - gpio-controller; - #gpio-cells = <2>; - nxp,kinetis-port = <&portd>; - reg = <0x46000 0x128>; - interrupts = <65 0>, <66 0>; - }; - - vbat: vbat@2b000 { - reg = <0x2b000 0x400>; - interrupts = <74 0>; - }; - - tpm0: pwm@31000 { - compatible = "nxp,kinetis-tpm"; - reg = <0x31000 0x100>; - interrupts = <37 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0xc4>; - prescaler = <16>; - status = "disabled"; - #pwm-cells = <3>; - }; - - tpm1: pwm@32000 { - compatible = "nxp,kinetis-tpm"; - reg = <0x32000 0x100>; - interrupts = <38 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0xc8>; - prescaler = <16>; - status = "disabled"; - #pwm-cells = <3>; - }; - - wdog0: watchdog@1a000 { - compatible = "nxp,wdog32"; - reg = <0x1a000 16>; - interrupts = <23 0>; - clocks = <&scg SCG_K4_SYSOSC_CLK 0x68>; - clk-source = <1>; - clk-divider = <256>; - status = "okay"; - }; - - wdog1: watchdog@1b000 { - compatible = "nxp,wdog32"; - reg = <0x1b000 16>; - interrupts = <24 0>; - clocks = <&scg SCG_K4_SYSOSC_CLK 0x6c>; - clk-source = <1>; - clk-divider = <256>; - status = "disabled"; - }; - - lptmr0: timer@2d000 { - compatible = "nxp,lptmr"; - reg = <0x2d000 0x10>; - interrupts = <34 0>; - clock-frequency = <32000>; - clk-source = <2>; - prescaler = <1>; - resolution = <32>; - status = "disabled"; - }; - - lptmr1: timer@2e000 { - compatible = "nxp,lptmr"; - reg = <0x2e000 0x10>; - interrupts = <35 0>; - clock-frequency = <32000>; - clk-source = <2>; - prescaler = <1>; - resolution = <32>; - status = "disabled"; - }; +&stcm0 { + /* With only the first 64KB having ECC */ + reg = <0x0 DT_SIZE_K(104)>; +}; - hci: hci_ble { - compatible = "nxp,hci-ble"; - interrupts = <48 2>; - interrupt-names = "hci_int"; - }; +&pbridge2 { + reg = <0x0 0x4b000>; +}; - flexcan0: can@3b000 { - compatible = "nxp,flexcan"; - reg = <0x3b000 0x3080>; - interrupts = <47 0>; - interrupt-names = "common"; - clocks = <&scg SCG_K4_FIRC_CLK 0xec>; - clk-source = <2>; - status = "disabled"; - }; +&porta { + reg = <0x42000 0xdc>; +}; - adc0: adc@47000 { - compatible = "nxp,lpc-lpadc"; - reg = <0x47000 0x1000>; - interrupts = <71 0>; - clocks = <&scg SCG_K4_FIRC_CLK 0x11c>; - voltage-ref= <1>; - calibration-average = <128>; - /* pwrlvl 0 is slow speed low power, 1 is opposite */ - power-level = <0>; - offset-value-a = <0>; - offset-value-b = <0>; - #io-channel-cells = <1>; - nxp,references = <&vref 1800>; - status = "disabled"; - }; +&portb { + reg = <0x43000 0xdc>; +}; - vref: regulator@4a000 { - compatible = "nxp,vref"; - regulator-name = "mcxw71-vref"; - reg = <0x4a000 0x20>; - #nxp,reference-cells = <1>; - nxp,buffer-startup-delay-us = <400>; - nxp,bandgap-startup-time-us = <20>; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <2100000>; - nxp,current-compensation-en; - status = "disabled"; - }; +&portc { + reg = <0x44000 0xdc>; }; -&fast_peripheral0 { - gpioa: gpio@10000{ - compatible = "nxp,kinetis-gpio"; - status = "disabled"; - gpio-controller; - #gpio-cells = <2>; - nxp,kinetis-port = <&porta>; - reg = <0x10000 0x128>; - interrupts = <59 0>, <60 0>; - }; +&portd { + reg = <0x45000 0xdc>; +}; - gpiob: gpio@20000{ - compatible = "nxp,kinetis-gpio"; - status = "disabled"; - gpio-controller; - #gpio-cells = <2>; - nxp,kinetis-port = <&portb>; - reg = <0x20000 0x128>; - interrupts = <61 0>, <62 0>; - }; +&smu2 { + ranges = <0x0 0x1c0000 DT_SIZE_K(40)>; +}; - gpioc: gpio@30000{ - compatible = "nxp,kinetis-gpio"; - status = "disabled"; - gpio-controller; - #gpio-cells = <2>; - nxp,kinetis-port = <&portc>; - reg = <0x30000 0x128>; - interrupts = <63 0>, <64 0>; - }; +&rtc { + reg = <0x4002c000 0x50>; }; diff --git a/dts/arm/nxp/nxp_mcxw72.dtsi b/dts/arm/nxp/nxp_mcxw72.dtsi new file mode 100644 index 0000000000000..80c0fe1378858 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxw72.dtsi @@ -0,0 +1,59 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nxp_mcxw7x_common.dtsi" + +&fmu { + ranges = <0x0 0x10000000 DT_SIZE_M(2)>; +}; + +&flash { + reg = <0x0 DT_SIZE_M(2)>; +}; + +&ctcm { + ranges = <0x0 0x14000000 DT_SIZE_K(32)>; +}; + +&ctcm0 { + reg = <0x0 DT_SIZE_K(32)>; +}; + +&stcm { + ranges = <0x0 0x30000000 DT_SIZE_K(232)>; +}; + +&stcm0 { + reg = <0x0 DT_SIZE_K(232)>; +}; + +&pbridge2 { + reg = <0x0 0x54000>; +}; + +&porta { + reg = <0x42000 0xF0>; +}; + +&portb { + reg = <0x43000 0xF0>; +}; + +&portc { + reg = <0x44000 0xF0>; +}; + +&portd { + reg = <0x45000 0xF0>; +}; + +&smu2 { + ranges = <0x0 0x1c0000 DT_SIZE_K(80)>; +}; + +&rtc { + reg = <0x4002c000 0x60>; +}; diff --git a/dts/arm/nxp/nxp_mcxw7x_common.dtsi b/dts/arm/nxp/nxp_mcxw7x_common.dtsi new file mode 100644 index 0000000000000..7e0a42c405726 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxw7x_common.dtsi @@ -0,0 +1,392 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/ { + aliases { + watchdog0 = &wdog0; + }; + + chosen { + zephyr,bt-hci = &hci; + zephyr,ieee802154 = &ieee802154; + zephyr,entropy = &trng; + zephyr,nbu = &nbu; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m33f"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv8m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + soc { + fmu: memory-controller@50020000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nxp,msf1"; + reg = <0x50020000 0x30>; + interrupts = <27 0>; + status = "disabled"; + + flash: flash@0 { + compatible = "soc-nv-flash"; + write-block-size = <16>; + erase-block-size = <8192>; + }; + }; + + ctcm: sram@14000000 { + #address-cells = <1>; + #size-cells = <1>; + + ctcm0: code_memory@0 { + compatible = "mmio-sram"; + }; + }; + + stcm: sram@30000000 { + #address-cells = <1>; + #size-cells = <1>; + + stcm0: system_memory@0 { + compatible = "mmio-sram"; + }; + }; + + peripheral: peripheral@50000000 { + ranges = <0x0 0x50000000 0x10000000>; + #address-cells = <1>; + #size-cells = <1>; + + pbridge2: pbridge2@0 { + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + }; + + fast_peripheral0: fast_peripherals0@8000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x8000000 0x40000>; + }; + + fast_peripheral1: fast_peripherals1@8800000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x8800000 0x20a000>; + }; + }; + }; + + pinctrl: pinctrl { + compatible = "nxp,port-pinctrl"; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; + +&pbridge2 { + #address-cells = <1>; + #size-cells = <1>; + + scg: clock-controller@1e000 { + compatible = "nxp,scg-k4"; + reg = <0x1e000 0x404>; + #clock-cells = <2>; + }; + + porta: pinctrl@42000 { + compatible = "nxp,port-pinmux"; + clocks = <&scg SCG_K4_SLOW_CLK 0x108>; + }; + + portb: pinctrl@43000 { + compatible = "nxp,port-pinmux"; + clocks = <&scg SCG_K4_SLOW_CLK 0x10c>; + }; + + portc: pinctrl@44000 { + compatible = "nxp,port-pinmux"; + clocks = <&scg SCG_K4_SLOW_CLK 0x110>; + }; + + portd: pinctrl@45000 { + compatible = "nxp,port-pinmux"; + clocks = <&scg SCG_K4_SLOW_CLK 0>; + }; + + lpuart0: serial@38000 { + compatible = "nxp,lpuart"; + reg = <0x38000 0x34>; + interrupts = <44 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0xe0>; + status = "disabled"; + }; + + lpuart1: serial@39000 { + compatible = "nxp,lpuart"; + reg = <0x39000 0x34>; + interrupts = <45 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0xe4>; + status = "disabled"; + }; + + lpi2c0: i2c@33000 { + compatible = "nxp,lpi2c"; + reg = <0x33000 0x17c>; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <39 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0xe0>; + status = "disabled"; + }; + + lpi2c1: i2c@34000 { + compatible = "nxp,lpi2c"; + reg = <0x34000 0x17c>; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <40 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0xe4>; + status = "disabled"; + }; + + lpspi0: spi@36000 { + compatible = "nxp,lpspi"; + reg = <0x36000 0x800>; + interrupts = <42 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0xd8>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi1: spi@37000 { + compatible = "nxp,lpspi"; + reg = <0x37000 0x800>; + interrupts = <43 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0xdc>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + gpiod: gpio@46000{ + compatible = "nxp,kinetis-gpio"; + reg = <0x46000 0x128>; + interrupts = <65 0>, <66 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portd>; + status = "disabled"; + }; + + vbat: vbat@2b000 { + reg = <0x2b000 0x33c>; + interrupts = <74 0>; + }; + + tpm0: pwm@31000 { + compatible = "nxp,kinetis-tpm"; + reg = <0x31000 0x88>; + interrupts = <37 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0xc4>; + prescaler = <16>; + status = "disabled"; + #pwm-cells = <3>; + }; + + tpm1: pwm@32000 { + compatible = "nxp,kinetis-tpm"; + reg = <0x32000 0x88>; + interrupts = <38 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0xc8>; + prescaler = <16>; + status = "disabled"; + #pwm-cells = <3>; + }; + + wdog0: watchdog@1a000 { + compatible = "nxp,wdog32"; + reg = <0x1a000 10>; + interrupts = <23 0>; + clocks = <&scg SCG_K4_SYSOSC_CLK 0x68>; + clk-source = <1>; + clk-divider = <256>; + status = "okay"; + }; + + wdog1: watchdog@1b000 { + compatible = "nxp,wdog32"; + reg = <0x1b000 10>; + interrupts = <24 0>; + clocks = <&scg SCG_K4_SYSOSC_CLK 0x6c>; + clk-source = <1>; + clk-divider = <256>; + status = "disabled"; + }; + + lptmr0: timer@2d000 { + compatible = "nxp,lptmr"; + reg = <0x2d000 0x10>; + interrupts = <34 0>; + clock-frequency = <32000>; + clk-source = <2>; + prescaler = <1>; + resolution = <32>; + status = "disabled"; + }; + + lptmr1: timer@2e000 { + compatible = "nxp,lptmr"; + reg = <0x2e000 0x10>; + interrupts = <35 0>; + clock-frequency = <32000>; + clk-source = <2>; + prescaler = <1>; + resolution = <32>; + status = "disabled"; + }; + + nbu: nbu { + compatible = "nxp,nbu"; + interrupts = <48 2>; + interrupt-names = "nbu_rx_int"; + }; + + hci: hci_ble { + compatible = "nxp,hci-ble"; + }; + + ieee802154: ieee802154 { + compatible = "nxp,mcxw-ieee802154"; + }; + + trng: trng { + compatible = "nxp,ele-trng"; + }; + + flexcan0: can@3b000 { + compatible = "nxp,flexcan"; + reg = <0x3b000 0x3080>; + interrupts = <47 0>; + interrupt-names = "common"; + clocks = <&scg SCG_K4_FIRC_CLK 0xec>; + clk-source = <2>; + status = "disabled"; + }; + + adc0: adc@47000 { + compatible = "nxp,lpc-lpadc"; + reg = <0x47000 0x584>; + interrupts = <71 0>; + clocks = <&scg SCG_K4_FIRC_CLK 0x11c>; + voltage-ref= <1>; + calibration-average = <128>; + /* pwrlvl 0 is slow speed low power, 1 is opposite */ + power-level = <0>; + offset-value-a = <0>; + offset-value-b = <0>; + #io-channel-cells = <1>; + nxp,references = <&vref 1800>; + status = "disabled"; + }; + + vref: regulator@4a000 { + compatible = "nxp,vref"; + reg = <0x4a000 0x14>; + regulator-name = "mcxw71-vref"; + #nxp,reference-cells = <1>; + nxp,buffer-startup-delay-us = <400>; + nxp,bandgap-startup-time-us = <20>; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <2100000>; + nxp,current-compensation-en; + status = "disabled"; + }; + + rtc: rtc@4002c000 { + compatible = "nxp,rtc"; + status = "disabled"; + interrupts = <32 0>, <33 0>; + interrupt-names = "alarm", "seconds"; + clock-frequency = <32768>; + prescaler = <32768>; + }; +}; + +&fast_peripheral0 { + gpioa: gpio@10000{ + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&porta>; + reg = <0x10000 0x128>; + interrupts = <59 0>, <60 0>; + }; + + gpiob: gpio@20000{ + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portb>; + reg = <0x20000 0x128>; + interrupts = <61 0>, <62 0>; + }; + + gpioc: gpio@30000{ + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portc>; + reg = <0x30000 0x128>; + interrupts = <63 0>, <64 0>; + }; +}; + +&fast_peripheral1 { + smu2: smu2@1c0000 { + #address-cells = <1>; + #size-cells = <1>; + + rpmsgmem: memory@8800 { + compatible = "zephyr,memory-region","mmio-sram"; + reg = <0x8800 DT_SIZE_K(6)>; + zephyr,memory-region = "rpmsg_sh_mem"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; + }; + }; +}; diff --git a/dts/arm/nxp/nxp_rt1010.dtsi b/dts/arm/nxp/nxp_rt1010.dtsi index 8433d92a7e2bf..d077d331a07da 100644 --- a/dts/arm/nxp/nxp_rt1010.dtsi +++ b/dts/arm/nxp/nxp_rt1010.dtsi @@ -164,6 +164,8 @@ clocks = <&ccm IMX_CCM_LPSPI_CLK 0x6c 0>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; }; lpspi2: spi@40198000 { @@ -174,6 +176,8 @@ clocks = <&ccm IMX_CCM_LPSPI_CLK 0x6c 2>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; }; /* Remove LPUART5-8, they don't exist on RT1010 */ diff --git a/dts/arm/nxp/nxp_rt1060.dtsi b/dts/arm/nxp/nxp_rt1060.dtsi index 8d308a27509f4..2bf3395b18b5d 100644 --- a/dts/arm/nxp/nxp_rt1060.dtsi +++ b/dts/arm/nxp/nxp_rt1060.dtsi @@ -57,7 +57,7 @@ interrupts = <152 0>; interrupt-names = "COMMON"; nxp,mdio = <&enet2_mdio>; - nxp,ptp-clock = <&enet_ptp_clock>; + nxp,ptp-clock = <&enet2_ptp_clock>; status = "disabled"; }; enet2_mdio: mdio { diff --git a/dts/arm/nxp/nxp_rt10xx.dtsi b/dts/arm/nxp/nxp_rt10xx.dtsi index cb1f741e81fde..c2f55fba8724b 100644 --- a/dts/arm/nxp/nxp_rt10xx.dtsi +++ b/dts/arm/nxp/nxp_rt10xx.dtsi @@ -458,6 +458,8 @@ interrupts = <32 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI_CLK 0x6c 0>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; @@ -468,6 +470,8 @@ interrupts = <33 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI_CLK 0x6c 2>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; @@ -478,6 +482,8 @@ interrupts = <34 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI_CLK 0x6c 4>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; @@ -488,12 +494,14 @@ interrupts = <35 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI_CLK 0x6c 6>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; lpuart1: uart@40184000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40184000 0x4000>; interrupts = <20 0>; clocks = <&ccm IMX_CCM_LPUART_CLK 0x7c 24>; @@ -503,7 +511,7 @@ }; lpuart2: uart@40188000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40188000 0x4000>; interrupts = <21 0>; clocks = <&ccm IMX_CCM_LPUART_CLK 0x68 28>; @@ -513,7 +521,7 @@ }; lpuart3: uart@4018c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4018c000 0x4000>; interrupts = <22 0>; clocks = <&ccm IMX_CCM_LPUART_CLK 0x68 12>; @@ -523,7 +531,7 @@ }; lpuart4: uart@40190000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40190000 0x4000>; interrupts = <23 0>; clocks = <&ccm IMX_CCM_LPUART_CLK 0x6c 24>; @@ -533,7 +541,7 @@ }; lpuart5: uart@40194000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40194000 0x4000>; interrupts = <24 0>; clocks = <&ccm IMX_CCM_LPUART_CLK 0x74 2>; @@ -543,7 +551,7 @@ }; lpuart6: uart@40198000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40198000 0x4000>; interrupts = <25 0>; clocks = <&ccm IMX_CCM_LPUART_CLK 0x74 6>; @@ -553,7 +561,7 @@ }; lpuart7: uart@4019c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4019c000 0x4000>; interrupts = <26 0>; clocks = <&ccm IMX_CCM_LPUART_CLK 0x7c 26>; @@ -563,7 +571,7 @@ }; lpuart8: uart@401a0000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x401a0000 0x4000>; interrupts = <27 0>; clocks = <&ccm IMX_CCM_LPUART_CLK 0x80 14>; diff --git a/dts/arm/nxp/nxp_rt118x.dtsi b/dts/arm/nxp/nxp_rt118x.dtsi index 845554c4c6af1..dc25cfb24ecb4 100644 --- a/dts/arm/nxp/nxp_rt118x.dtsi +++ b/dts/arm/nxp/nxp_rt118x.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,10 @@ #include / { + aliases { + watchdog0 = &rtwdog0; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -22,6 +26,7 @@ #address-cells = <1>; #size-cells = <1>; + d-cache-line-size = <32>; mpu: mpu@e000ed90 { compatible = "arm,armv8m-mpu"; @@ -35,8 +40,21 @@ #address-cells = <1>; #size-cells = <1>; + d-cache-line-size = <32>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + }; }; }; + + /* USB PLL */ + usbclk: usbpll-clock { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + #clock-cells = <0>; + }; }; &peripheral { @@ -67,101 +85,131 @@ compatible = "nxp,imx-ccm-rev2"; reg = <0x4450000 0x4000>; #clock-cells = <3>; + + lpo: lpo32k { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; }; lpuart1: uart@4380000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4380000 0x4000>; interrupts = <19 0>; clocks = <&ccm IMX_CCM_LPUART0102_CLK 0x7c 24>; + dmas = <&edma3 0 16>, <&edma3 1 17>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart2: uart@4390000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4390000 0x4000>; interrupts = <20 0>; clocks = <&ccm IMX_CCM_LPUART0102_CLK 0x68 28>; + dmas = <&edma3 2 18>, <&edma3 3 19>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart3: uart@2570000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x2570000 0x4000>; interrupts = <68 0>; clocks = <&ccm IMX_CCM_LPUART0304_CLK 0x68 12>; + dmas = <&edma4 0 17>, <&edma4 1 18>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart4: uart@2580000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x2580000 0x4000>; interrupts = <69 0>; clocks = <&ccm IMX_CCM_LPUART0304_CLK 0x6c 24>; + dmas = <&edma4 2 19>, <&edma4 3 20>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart5: uart@2590000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x2590000 0x4000>; interrupts = <70 0>; clocks = <&ccm IMX_CCM_LPUART0506_CLK 0x74 2>; + dmas = <&edma4 4 21>, <&edma4 5 22>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart6: uart@25A0000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x25A0000 0x4000>; interrupts = <71 0>; clocks = <&ccm IMX_CCM_LPUART0506_CLK 0x74 6>; + dmas = <&edma4 6 23>, <&edma4 7 24>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart7: uart@4570000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4570000 0x4000>; interrupts = <196 0>; clocks = <&ccm IMX_CCM_LPUART0708_CLK 0x7c 26>; + dmas = <&edma3 4 29>, <&edma3 5 30>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart8: uart@2DA0000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x2DA0000 0x4000>; interrupts = <197 0>; clocks = <&ccm IMX_CCM_LPUART0708_CLK 0x80 14>; + dmas = <&edma4 8 178>, <&edma4 9 179>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart9: uart@2D70000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x2D70000 0x4000>; interrupts = <156 0>; clocks = <&ccm IMX_CCM_LPUART0910_CLK 0x80 14>; + dmas = <&edma4 10 172>, <&edma4 11 173>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart10: uart@2D80000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x2D80000 0x4000>; interrupts = <157 0>; clocks = <&ccm IMX_CCM_LPUART0910_CLK 0x80 14>; + dmas = <&edma4 12 174>, <&edma4 13 175>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart11: uart@2D90000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x2D90000 0x4000>; interrupts = <158 0>; clocks = <&ccm IMX_CCM_LPUART1112_CLK 0x80 14>; + dmas = <&edma4 14 176>, <&edma4 15 177>; + dma-names = "tx", "rx"; status = "disabled"; }; lpuart12: uart@4580000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4580000 0x4000>; interrupts = <159 0>; clocks = <&ccm IMX_CCM_LPUART1112_CLK 0x80 14>; + dmas = <&edma3 6 31>, <&edma3 7 32>; + dma-names = "tx", "rx"; status = "disabled"; }; @@ -589,6 +637,7 @@ reg = <0x60b40000 0x10000>; mac-index = <1>; si-index = <1>; + phy-connection-type = "internal"; status = "disabled"; }; @@ -600,6 +649,41 @@ #size-cells = <0>; status = "disabled"; }; + + switch: dsa { + compatible = "nxp,netc-switch"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + + switch_port0: switch_port@0 { + reg = <0>; + status = "disabled"; + }; + + switch_port1: switch_port@1 { + reg = <1>; + status = "disabled"; + }; + + switch_port2: switch_port@2 { + reg = <2>; + status = "disabled"; + }; + + switch_port3: switch_port@3 { + reg = <3>; + status = "disabled"; + }; + + /* Internal port */ + switch_port4: switch_port@4 { + reg = <4>; + ethernet = <&enetc_psi1>; + phy-connection-type = "internal"; + status = "disabled"; + }; + }; }; flexcan1: can@43a0000 { @@ -848,15 +932,324 @@ status = "disabled"; }; }; -}; -&flexspi { - compatible = "nxp,imx-flexspi"; - interrupts = <55 0>; + tpm1: pwm@4310000 { + compatible = "nxp,kinetis-tpm"; + reg = <0x4310000 0x88>; + interrupts = <36 0>; + clocks = <&ccm IMX_CCM_TPM1_CLK 0x3b 0>; + prescaler = <16>; + status = "disabled"; + #pwm-cells = <3>; + }; + + tpm2: pwm@4320000 { + compatible = "nxp,kinetis-tpm"; + reg = <0x4320000 0x88>; + interrupts = <37 0>; + clocks = <&ccm IMX_CCM_TPM2_CLK 0x3c 0>; + prescaler = <16>; + status = "disabled"; + #pwm-cells = <3>; + }; + + tpm3: pwm@24E0000 { + compatible = "nxp,kinetis-tpm"; + reg = <0x24E0000 0x88>; + interrupts = <75 0>; + clocks = <&ccm IMX_CCM_TPM3_CLK 0x3d 0>; + prescaler = <16>; + status = "disabled"; + #pwm-cells = <3>; + }; + + tpm4: pwm@24F0000 { + compatible = "nxp,kinetis-tpm"; + reg = <0x24F0000 0x88>; + interrupts = <76 0>; + clocks = <&ccm IMX_CCM_TPM4_CLK 0x3e 0>; + prescaler = <16>; + status = "disabled"; + #pwm-cells = <3>; + }; + + tpm5: pwm@2500000 { + compatible = "nxp,kinetis-tpm"; + reg = <0x2500000 0x88>; + interrupts = <77 0>; + clocks = <&ccm IMX_CCM_TPM5_CLK 0x3f 0>; + prescaler = <16>; + status = "disabled"; + #pwm-cells = <3>; + }; + + tpm6: pwm@42510000 { + compatible = "nxp,kinetis-tpm"; + reg = <0x42510000 0x88>; + interrupts = <78 0>; + clocks = <&ccm IMX_CCM_TPM6_CLK 0x40 0>; + prescaler = <16>; + status = "disabled"; + #pwm-cells = <3>; + }; + + i3c1: i3c@4330000 { + compatible = "nxp,mcux-i3c"; + reg = <0x4330000 0x1000>; + interrupts = <12 0>; + clocks = <&ccm IMX_CCM_I3C1_CLK 0x67 0>; + clk-divider = <2>; + clk-divider-slow = <1>; + clk-divider-tc = <1>; + status = "disabled"; + #address-cells = <3>; + #size-cells = <0>; + }; + + i3c2: i3c@2520000 { + compatible = "nxp,mcux-i3c"; + reg = <0x2520000 0x1000>; + interrupts = <61 0>; + clocks = <&ccm IMX_CCM_I3C2_CLK 0x68 0>; + clk-divider = <2>; + clk-divider-slow = <1>; + clk-divider-tc = <1>; + status = "disabled"; + #address-cells = <3>; + #size-cells = <0>; + }; + + usdhc1: usdhc@2850000 { + compatible = "nxp,imx-usdhc"; + reg = <0x2850000 0x4000>; + status = "disabled"; + interrupts = <86 0>; + clocks = <&ccm IMX_CCM_USDHC1_CLK 0 0>; + max-current-330 = <1020>; + max-current-180 = <1020>; + max-bus-freq = <208000000>; + min-bus-freq = <400000>; + }; + + usdhc2: usdhc@2860000 { + compatible = "nxp,imx-usdhc"; + reg = <0x2860000 0x4000>; + status = "disabled"; + interrupts = <87 0>; + clocks = <&ccm IMX_CCM_USDHC2_CLK 0 0>; + max-current-330 = <1020>; + max-current-180 = <1020>; + max-bus-freq = <208000000>; + min-bus-freq = <400000>; + }; + + edma3: dma-controller@4000000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + nxp,version = <4>; + reg = <0x4000000 0x210000>; + dma-channels = <32>; + dma-requests = <39>; + no-error-irq; + interrupts = <95 0>, <96 0>, <97 0>, + <98 0>, <99 0>, <100 0>, <101 0>, + <102 0>, <103 0>, <104 0>, <105 0>, + <106 0>, <107 0>, <108 0>, <109 0>, + <110 0>, <111 0>, <112 0>, <113 0>, + <114 0>, <115 0>, <116 0>, <117 0>, + <118 0>, <119 0>, <120 0>, <121 0>, + <122 0>, <123 0>, <124 0>, <125 0>, + <126 0>, <94 0>; + status = "disabled"; + }; + + edma4: dma-controller@2000000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + nxp,version = <4>; + dma-channels = <64>; + dma-requests = <222>; + reg = <0x2000000 0x4000>; + no-error-irq; + interrupts = <128 0>, <129 0>, <130 0>, + <131 0>, <132 0>, <133 0>, <134 0>, + <135 0>, <136 0>, <137 0>, <138 0>, + <139 0>, <140 0>, <141 0>, <142 0>, + <143 0>, <127 0>; + channels-shared-irq-mask = <0x00000003 0x00000003 + 0x0000000C 0x0000000C 0x00000030 0x00000030 + 0x000000C0 0x000000C0 0x00000300 0x00000300 + 0x00000C00 0x00000C00 0x00003000 0x00003000 + 0x0000C000 0x0000C000 0x00030000 0x00030000 + 0x000C0000 0x000C0000 0x00300000 0x00300000 + 0x00C00000 0x00C00000 0x03000000 0x03000000 + 0x0C000000 0x0C000000 0x30000000 0x30000000 + 0xC0000000 0xC0000000>; + status = "disabled"; + }; + + lpspi1: spi@4360000 { + compatible = "nxp,lpspi"; + reg = <0x4360000 0x4000>; + interrupts = <16 3>; + status = "disabled"; + clocks = <&ccm IMX_CCM_LPSPI0102_CLK 0x6c 0>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + #address-cells = <1>; + #size-cells = <0>; + }; + + lpspi2: spi@4370000 { + compatible = "nxp,lpspi"; + reg = <0x4370000 0x4000>; + interrupts = <17 3>; + status = "disabled"; + clocks = <&ccm IMX_CCM_LPSPI0102_CLK 0x6c 2>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; + }; + + lpspi3: spi@2550000 { + compatible = "nxp,lpspi"; + reg = <0x2550000 0x4000>; + interrupts = <65 3>; + status = "disabled"; + clocks = <&ccm IMX_CCM_LPSPI0304_CLK 0x6c 4>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + #address-cells = <1>; + #size-cells = <0>; + }; + + lpspi4: spi@2560000 { + compatible = "nxp,lpspi"; + reg = <0x2560000 0x4000>; + interrupts = <66 3>; + status = "disabled"; + clocks = <&ccm IMX_CCM_LPSPI0304_CLK 0x6c 6>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + #address-cells = <1>; + #size-cells = <0>; + }; + + lpspi5: spi@2d50000 { + compatible = "nxp,lpspi"; + reg = <0x2d50000 0x4000>; + interrupts = <194 3>; + status = "disabled"; + clocks = <&ccm IMX_CCM_LPSPI0506_CLK 0x6c 6>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + #address-cells = <1>; + #size-cells = <0>; + }; + + lpspi6: spi@2d60000 { + compatible = "nxp,lpspi"; + reg = <0x2d60000 0x4000>; + interrupts = <195 3>; + status = "disabled"; + clocks = <&ccm IMX_CCM_LPSPI0506_CLK 0x6c 6>; + tx-fifo-size = <16>; + rx-fifo-size = <16>; + #address-cells = <1>; + #size-cells = <0>; + }; + + rtwdog0: wdog@42d0000 { + compatible = "nxp,rtwdog"; + reg = <0x42d0000 0x10>; + status = "okay"; + interrupts = <38 0>; + clocks = <&lpo>; + clk-source = <1>; + clk-divider = <1>; + }; + + rtwdog1: wdog@42e0000 { + compatible = "nxp,rtwdog"; + reg = <0x42e0000 0x10>; + status = "disabled"; + interrupts = <39 0>; + clocks = <&lpo>; + clk-source = <1>; + clk-divider = <1>; + }; + + rtwdog2: wdog@2490000 { + compatible = "nxp,rtwdog"; + reg = <0x2490000 0x10>; + status = "disabled"; + interrupts = <79 0>; + clocks = <&lpo>; + clk-source = <1>; + clk-divider = <1>; + }; + + rtwdog3: wdog@24a0000 { + compatible = "nxp,rtwdog"; + reg = <0x24a0000 0x10>; status = "disabled"; - clocks = <&ccm IMX_CCM_FLEXSPI_CLK 0x0 0>; + interrupts = <80 0>; + clocks = <&lpo>; + clk-source = <1>; + clk-divider = <1>; + }; + + rtwdog4: wdog@24b0000 { + compatible = "nxp,rtwdog"; + reg = <0x24b0000 0x10>; + status = "disabled"; + interrupts = <81 0>; + clocks = <&lpo>; + clk-source = <1>; + clk-divider = <1>; + }; + + usb1: usbd@2c80000 { + compatible = "nxp,ehci"; + reg = <0x2c80000 0x1000>; + interrupts = <215 0>; + interrupt-names = "usb_otg"; + clocks = <&usbclk>; + num-bidir-endpoints = <8>; + status = "disabled"; + }; + + usb2: usbd@2c90000 { + compatible = "nxp,ehci"; + reg = <0x2c90000 0x1000>; + interrupts = <214 0>; + interrupt-names = "usb_otg"; + clocks = <&usbclk>; + num-bidir-endpoints = <8>; + status = "disabled"; + }; + + usbphy1: usbphy@2ca0000 { + compatible = "nxp,usbphy"; + reg = <0x2ca0000 0x1000>; + status = "disabled"; + }; + + usbphy2: usbphy@2cb0000 { + compatible = "nxp,usbphy"; + reg = <0x2cb0000 0x1000>; + status = "disabled"; + }; +}; + +&flexspi { + compatible = "nxp,imx-flexspi"; + interrupts = <55 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + clocks = <&ccm IMX_CCM_FLEXSPI_CLK 0x0 0>; }; &flexspi2 { @@ -871,16 +1264,16 @@ &memory { #address-cells = <1>; #size-cells = <1>; - ocram1: ocram@484000 { + ocram1: ocram@0 { compatible = "zephyr,memory-region", "mmio-sram"; zephyr,memory-region = "OCRAM1"; /* OCRAM1 first 16K access is blocked by TRDC */ - reg = <0x484000 DT_SIZE_K(496)>; + reg = <0x0 DT_SIZE_K(496)>; }; - ocram2: ocram@500000 { + ocram2: ocram@7c000 { compatible = "zephyr,memory-region", "mmio-sram"; zephyr,memory-region = "OCRAM2"; - reg = <0x500000 DT_SIZE_K(256)>; + reg = <0x7c000 DT_SIZE_K(256)>; }; }; diff --git a/dts/arm/nxp/nxp_rt118x_cm33.dtsi b/dts/arm/nxp/nxp_rt118x_cm33.dtsi index 706be1b04a855..b77431936d915 100644 --- a/dts/arm/nxp/nxp_rt118x_cm33.dtsi +++ b/dts/arm/nxp/nxp_rt118x_cm33.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,8 +22,14 @@ zephyr,memory-region = "DTCM"; }; - memory: memory@30000000 { - ranges = <0x0 0x30000000 0x10000000>; + memory: memory@30484000 { + ranges = <0x0 0x30484000 0x10000000>; + }; + + m7_itcm: itcm@303c0000 { + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "M7_ITCM"; + reg = <0x303c0000 DT_SIZE_K(256)>; }; peripheral: peripheral@50000000 { @@ -48,6 +54,26 @@ }; }; +&peripheral { + mbox1_a: mbox@4220000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x4220000 0x4000>; + interrupts = <21 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + + mbox2_a: mbox@2430000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x2430000 0x4000>; + interrupts = <22 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; +}; + &nvic { arm,num-irq-priority-bits = <3>; }; @@ -60,7 +86,7 @@ &gpio1{ pinmux = <&iomuxc_aon_gpio_aon_00_gpio1_io00>, - <&iomuxc_aon_gpio_aon_01_gpio1_io01>, + <&iomuxc_aon_gpio_aon_01_gpio1_io01>, <&iomuxc_aon_gpio_aon_02_gpio1_io02>, <&iomuxc_aon_gpio_aon_03_gpio1_io03>, <&iomuxc_aon_gpio_aon_04_gpio1_io04>, @@ -91,7 +117,7 @@ &gpio2{ pinmux = <&iomuxc_gpio_emc_b1_00_gpio2_io00>, - <&iomuxc_gpio_emc_b1_01_gpio2_io01>, + <&iomuxc_gpio_emc_b1_01_gpio2_io01>, <&iomuxc_gpio_emc_b1_02_gpio2_io02>, <&iomuxc_gpio_emc_b1_03_gpio2_io03>, <&iomuxc_gpio_emc_b1_04_gpio2_io04>, @@ -126,7 +152,7 @@ &gpio3{ pinmux = <&iomuxc_gpio_emc_b1_32_gpio3_io00>, - <&iomuxc_gpio_emc_b1_33_gpio3_io01>, + <&iomuxc_gpio_emc_b1_33_gpio3_io01>, <&iomuxc_gpio_emc_b1_34_gpio3_io02>, <&iomuxc_gpio_emc_b1_35_gpio3_io03>, <&iomuxc_gpio_emc_b1_36_gpio3_io04>, diff --git a/dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi b/dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi index 480e376330fb6..5bd64f0ea6053 100644 --- a/dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi +++ b/dts/arm/nxp/nxp_rt118x_cm33_ns.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,8 +22,14 @@ zephyr,memory-region = "DTCM"; }; - memory: memory@20000000 { - ranges = <0x0 0x20000000 0x10000000>; + memory: memory@20484000 { + ranges = <0x0 0x20484000 0x10000000>; + }; + + m7_itcm: itcm@203c0000 { + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "M7_ITCM"; + reg = <0x203c0000 DT_SIZE_K(256)>; }; peripheral: peripheral@40000000 { @@ -48,6 +54,26 @@ }; }; +&peripheral { + mbox1_a: mbox@4220000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x4220000 0x4000>; + interrupts = <21 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + + mbox2_a: mbox@2430000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x2430000 0x4000>; + interrupts = <22 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; +}; + &nvic { arm,num-irq-priority-bits = <3>; }; @@ -60,7 +86,7 @@ &gpio1{ pinmux = <&iomuxc_aon_gpio_aon_00_gpio1_io00>, - <&iomuxc_aon_gpio_aon_01_gpio1_io01>, + <&iomuxc_aon_gpio_aon_01_gpio1_io01>, <&iomuxc_aon_gpio_aon_02_gpio1_io02>, <&iomuxc_aon_gpio_aon_03_gpio1_io03>, <&iomuxc_aon_gpio_aon_04_gpio1_io04>, @@ -91,7 +117,7 @@ &gpio2{ pinmux = <&iomuxc_gpio_emc_b1_00_gpio2_io00>, - <&iomuxc_gpio_emc_b1_01_gpio2_io01>, + <&iomuxc_gpio_emc_b1_01_gpio2_io01>, <&iomuxc_gpio_emc_b1_02_gpio2_io02>, <&iomuxc_gpio_emc_b1_03_gpio2_io03>, <&iomuxc_gpio_emc_b1_04_gpio2_io04>, @@ -126,7 +152,7 @@ &gpio3{ pinmux = <&iomuxc_gpio_emc_b1_32_gpio3_io00>, - <&iomuxc_gpio_emc_b1_33_gpio3_io01>, + <&iomuxc_gpio_emc_b1_33_gpio3_io01>, <&iomuxc_gpio_emc_b1_34_gpio3_io02>, <&iomuxc_gpio_emc_b1_35_gpio3_io03>, <&iomuxc_gpio_emc_b1_36_gpio3_io04>, diff --git a/dts/arm/nxp/nxp_rt118x_cm7.dtsi b/dts/arm/nxp/nxp_rt118x_cm7.dtsi index 4b2e60a52a23c..1b9cde67f4ced 100644 --- a/dts/arm/nxp/nxp_rt118x_cm7.dtsi +++ b/dts/arm/nxp/nxp_rt118x_cm7.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,17 +10,19 @@ / { soc { itcm: itcm@0{ - compatible = "nxp,imx-itcm"; + compatible = "zephyr,memory-region", "nxp,imx-itcm"; reg = <0x00000000 DT_SIZE_K(256)>; + zephyr,memory-region = "ITCM"; }; dtcm: dtcm@20000000 { - compatible = "nxp,imx-dtcm"; + compatible = "zephyr,memory-region", "nxp,imx-dtcm"; reg = <0x20000000 DT_SIZE_K(256)>; + zephyr,memory-region = "DTCM"; }; - memory: memory@20000000 { - ranges = <0x0 0x20000000 0x10000000>; + memory: memory@20484000 { + ranges = <0x0 0x20484000 0x10000000>; }; peripheral: peripheral@40000000 { @@ -45,6 +47,26 @@ }; }; +&peripheral { + mbox1_b: mbox@4230000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x4230000 0x4000>; + interrupts = <21 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + + mbox2_b: mbox@2440000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x2440000 0x4000>; + interrupts = <22 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; +}; + &nvic { arm,num-irq-priority-bits = <4>; }; @@ -57,7 +79,7 @@ &gpio1{ pinmux = <&iomuxc_aon_gpio_aon_00_gpio1_io00>, - <&iomuxc_aon_gpio_aon_01_gpio1_io01>, + <&iomuxc_aon_gpio_aon_01_gpio1_io01>, <&iomuxc_aon_gpio_aon_02_gpio1_io02>, <&iomuxc_aon_gpio_aon_03_gpio1_io03>, <&iomuxc_aon_gpio_aon_04_gpio1_io04>, @@ -88,7 +110,7 @@ &gpio2{ pinmux = <&iomuxc_gpio_emc_b1_00_gpio2_io00>, - <&iomuxc_gpio_emc_b1_01_gpio2_io01>, + <&iomuxc_gpio_emc_b1_01_gpio2_io01>, <&iomuxc_gpio_emc_b1_02_gpio2_io02>, <&iomuxc_gpio_emc_b1_03_gpio2_io03>, <&iomuxc_gpio_emc_b1_04_gpio2_io04>, @@ -123,7 +145,7 @@ &gpio3{ pinmux = <&iomuxc_gpio_emc_b1_32_gpio3_io00>, - <&iomuxc_gpio_emc_b1_33_gpio3_io01>, + <&iomuxc_gpio_emc_b1_33_gpio3_io01>, <&iomuxc_gpio_emc_b1_34_gpio3_io02>, <&iomuxc_gpio_emc_b1_35_gpio3_io03>, <&iomuxc_gpio_emc_b1_36_gpio3_io04>, diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index 54dfddb94a3a4..fba564e434614 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -416,6 +416,8 @@ interrupts = <38 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI1_CLK 0x6c 0>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; @@ -426,6 +428,8 @@ interrupts = <39 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI2_CLK 0x6c 2>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; @@ -436,6 +440,8 @@ interrupts = <40 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI3_CLK 0x6c 4>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; @@ -446,6 +452,8 @@ interrupts = <41 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI4_CLK 0x6c 6>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; @@ -456,6 +464,8 @@ interrupts = <42 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI5_CLK 0x6c 6>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; @@ -466,12 +476,14 @@ interrupts = <43 3>; status = "disabled"; clocks = <&ccm IMX_CCM_LPSPI6_CLK 0x6c 6>; + rx-fifo-size = <16>; + tx-fifo-size = <16>; #address-cells = <1>; #size-cells = <0>; }; lpuart1: uart@4007c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4007c000 0x4000>; interrupts = <20 0>; clocks = <&ccm IMX_CCM_LPUART1_CLK 0x7c 24>; @@ -479,7 +491,7 @@ }; lpuart2: uart@40080000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40080000 0x4000>; interrupts = <21 0>; clocks = <&ccm IMX_CCM_LPUART2_CLK 0x68 28>; @@ -487,7 +499,7 @@ }; lpuart3: uart@40084000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40084000 0x4000>; interrupts = <22 0>; clocks = <&ccm IMX_CCM_LPUART3_CLK 0x68 12>; @@ -495,7 +507,7 @@ }; lpuart4: uart@40088000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40088000 0x4000>; interrupts = <23 0>; clocks = <&ccm IMX_CCM_LPUART4_CLK 0x6c 24>; @@ -503,7 +515,7 @@ }; lpuart5: uart@4008c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4008c000 0x4000>; interrupts = <24 0>; clocks = <&ccm IMX_CCM_LPUART5_CLK 0x74 2>; @@ -511,7 +523,7 @@ }; lpuart6: uart@40090000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40090000 0x4000>; interrupts = <25 0>; clocks = <&ccm IMX_CCM_LPUART6_CLK 0x74 6>; @@ -519,7 +531,7 @@ }; lpuart7: uart@40094000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40094000 0x4000>; interrupts = <26 0>; clocks = <&ccm IMX_CCM_LPUART7_CLK 0x7c 26>; @@ -527,7 +539,7 @@ }; lpuart8: uart@40098000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40098000 0x4000>; interrupts = <27 0>; clocks = <&ccm IMX_CCM_LPUART8_CLK 0x80 14>; @@ -535,7 +547,7 @@ }; lpuart9: uart@4009c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4009c000 0x4000>; interrupts = <28 0>; clocks = <&ccm IMX_CCM_LPUART9_CLK 0x80 14>; @@ -543,7 +555,7 @@ }; lpuart10: uart@400a0000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x400a0000 0x4000>; interrupts = <29 0>; clocks = <&ccm IMX_CCM_LPUART10_CLK 0x80 14>; @@ -551,7 +563,7 @@ }; lpuart11: uart@40c24000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40c24000 0x4000>; interrupts = <30 0>; clocks = <&ccm IMX_CCM_LPUART11_CLK 0x80 14>; @@ -559,7 +571,7 @@ }; lpuart12: uart@40c28000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40c28000 0x4000>; interrupts = <31 0>; clocks = <&ccm IMX_CCM_LPUART12_CLK 0x80 14>; diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index aa9db51f12552..3d988f260118f 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -438,56 +438,48 @@ clocks = <&clkctl0 MCUX_DMIC_CLK>; pdmc0: dmic-channel@0 { - compatible = "nxp,dmic-channel"; reg = <0>; dmas = <&dma0 16>; status = "disabled"; }; pdmc1: dmic-channel@1 { - compatible = "nxp,dmic-channel"; reg = <1>; dmas = <&dma0 17>; status = "disabled"; }; pdmc2: dmic-channel@2 { - compatible = "nxp,dmic-channel"; reg = <2>; dmas = <&dma0 18>; status = "disabled"; }; pdmc3: dmic-channel@3 { - compatible = "nxp,dmic-channel"; reg = <3>; dmas = <&dma0 19>; status = "disabled"; }; pdmc4: dmic-channel@4 { - compatible = "nxp,dmic-channel"; reg = <4>; dmas = <&dma0 20>; status = "disabled"; }; pdmc5: dmic-channel@5 { - compatible = "nxp,dmic-channel"; reg = <5>; dmas = <&dma0 21>; status = "disabled"; }; pdmc6: dmic-channel@6 { - compatible = "nxp,dmic-channel"; reg = <6>; dmas = <&dma0 22>; status = "disabled"; }; pdmc7: dmic-channel@7 { - compatible = "nxp,dmic-channel"; reg = <7>; dmas = <&dma0 23>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_rt6xx_common.dtsi b/dts/arm/nxp/nxp_rt6xx_common.dtsi index bf2dc2daccd91..bca82a2a6f418 100644 --- a/dts/arm/nxp/nxp_rt6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_common.dtsi @@ -345,56 +345,48 @@ clocks = <&clkctl0 MCUX_DMIC_CLK>; pdmc0: dmic-channel@0 { - compatible = "nxp,dmic-channel"; reg = <0>; dmas = <&dma0 16>; status = "disabled"; }; pdmc1: dmic-channel@1 { - compatible = "nxp,dmic-channel"; reg = <1>; dmas = <&dma0 17>; status = "disabled"; }; pdmc2: dmic-channel@2 { - compatible = "nxp,dmic-channel"; reg = <2>; dmas = <&dma0 18>; status = "disabled"; }; pdmc3: dmic-channel@3 { - compatible = "nxp,dmic-channel"; reg = <3>; dmas = <&dma0 19>; status = "disabled"; }; pdmc4: dmic-channel@4 { - compatible = "nxp,dmic-channel"; reg = <4>; dmas = <&dma0 20>; status = "disabled"; }; pdmc5: dmic-channel@5 { - compatible = "nxp,dmic-channel"; reg = <5>; dmas = <&dma0 21>; status = "disabled"; }; pdmc6: dmic-channel@6 { - compatible = "nxp,dmic-channel"; reg = <6>; dmas = <&dma0 22>; status = "disabled"; }; pdmc7: dmic-channel@7 { - compatible = "nxp,dmic-channel"; reg = <7>; dmas = <&dma0 23>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi b/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi new file mode 100644 index 0000000000000..6413efbfda7f8 --- /dev/null +++ b/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi @@ -0,0 +1,1042 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m33f"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv8m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + soc { + sram: sram@10000000 { + ranges = <0x0 0x10000000 0x780000 + 0x20000000 0x30000000 0x780000>; + }; + + peripheral: peripheral@50000000 { + ranges = <0x0 0x50000000 0x10000000>; + }; + + xspi0: spi@50184000 { + reg = <0x50184000 0x1000>, <0x38000000 DT_SIZE_M(128)>; + }; + + xspi1: spi@50185000 { + reg = <0x50185000 0x1000>, <0x18000000 DT_SIZE_M(128)>; + }; + + xspi2: spi@50411000 { + reg = <0x50411000 0x1000>, <0x70000000 DT_SIZE_M(128)>; + }; + + }; + + pinctrl: pinctrl { + compatible = "nxp,rt-iocon-pinctrl"; + }; +}; + + +&sram { + #address-cells = <1>; + #size-cells = <1>; + + /* RT7XX SRAM partitions are shared between code and data. Boards can override + * the reg properties of either sram0 or sram_code nodes to change the balance + * of SRAM allocation. + * + * The SRAM region [0x000000-0x017FFF] is reserved for ROM bootloader execution. + * Can be reused after boot. + * The SRAM region [0x018000-0x17FFFF] is reserved for Non-cached shared memory + * or application data. + * The SRAM region [0x180000-0x1FFFFF] is reserved for CPU0 application, last + * 2MB non-cacheable data for NPU/GPU/Display etc. + * The SRAM region [0x200000-0x400000] is reserved for HiFi4 application. + */ + + sram4rom: memory@20000000{ + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(96)>; + }; + + /* This partition is shared with code in RAM */ + sram_shared_code: memory@20018000{ + compatible = "mmio-sram"; + reg = <0x20018000 DT_SIZE_K(1024+512-96)>; + }; + + sram0: memory@20180000 { + compatible = "mmio-sram"; + reg = <0x20180000 DT_SIZE_K(512)>; + }; + + sram1: memory@20200000 { + compatible = "mmio-sram"; + reg = <0x20200000 DT_SIZE_K(2048)>; + }; +}; + +&peripheral { + #address-cells = <1>; + #size-cells = <1>; + /* + * Note that the offsets here are relative to the base address. + * The base addresses differ between non-secure (0x40000000) + * and secure modes (0x50000000). + */ + + lpadc0: adc@20c000 { + compatible = "nxp,lpc-lpadc"; + reg = <0x20c000 0x304>; + interrupts = <15 0>; + status = "disabled"; + clk-divider = <1>; + clk-source = <0>; + voltage-ref= <1>; + calibration-average = <128>; + power-level = <0>; + offset-value-a = <10>; + offset-value-b = <10>; + #io-channel-cells = <1>; + clocks = <&clkctl3 MCUX_LPADC1_CLK>; + }; + + rstctl0: reset@0 { + compatible = "nxp,rstctl"; + reg = <0x0 0x1000>; + #reset-cells = <1>; + }; + + rstctl2: reset@67000 { + compatible = "nxp,rstctl"; + reg = <0x67000 0x1000>; + #reset-cells = <1>; + }; + + rstctl3: reset@60000 { + compatible = "nxp,rstctl"; + reg = <0x60000 0x1000>; + #reset-cells = <1>; + }; + + rstctl4: reset@a0000 { + compatible = "nxp,rstctl"; + reg = <0xa0000 0x1000>; + #reset-cells = <1>; + }; + + clkctl0: clkctl@1000 { + compatible = "nxp,lpc-syscon"; + reg = <0x1000 0x1000>; + #clock-cells = <1>; + }; + + clkctl2: clkctl@65000 { + compatible = "nxp,lpc-syscon"; + reg = <0x65000 0x1000>; + #clock-cells = <1>; + }; + + clkctl3: clkctl@61000 { + compatible = "nxp,lpc-syscon"; + reg = <0x61000 0x1000>; + #clock-cells = <1>; + }; + + clkctl4: clkctl@a1000 { + compatible = "nxp,lpc-syscon"; + reg = <0xa1000 0x1000>; + #clock-cells = <1>; + }; + + ctimer0: ctimer@28000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x28000 0x1000>; + interrupts = <3 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&clkctl0 MCUX_CTIMER0_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer1: ctimer@29000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x29000 0x1000>; + interrupts = <4 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&clkctl0 MCUX_CTIMER1_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer2: ctimer@2a000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x2a000 0x1000>; + interrupts = <32 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&clkctl0 MCUX_CTIMER2_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer3: ctimer@2b000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x2b000 0x1000>; + interrupts = <6 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&clkctl0 MCUX_CTIMER3_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer4: ctimer@2c000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x2c000 0x1000>; + interrupts = <33 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&clkctl0 MCUX_CTIMER4_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + edma0: dma-controller@140000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + nxp,version = <4>; + dma-channels = <16>; + dma-requests = <105>; + reg = <0x140000 0x1000>; + interrupts = <59 0>, <60 0>, <61 0>, <62 0>, + <63 0>, <64 0>, <65 0>, <66 0>, + <67 0>, <68 0>, <69 0>, <70 0>, + <71 0>, <72 0>, <73 0>, <74 0>; + no-error-irq; + status = "disabled"; + }; + + edma1: dma-controller@160000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + nxp,version = <4>; + dma-channels = <16>; + dma-requests = <105>; + reg = <0x160000 0x1000>; + interrupts = <75 0>, <76 0>, <77 0>, <78 0>, + <79 0>, <80 0>, <81 0>, <82 0>, + <83 0>, <84 0>, <85 0>, <86 0>, + <87 0>, <88 0>, <89 0>, <90 0>; + no-error-irq; + status = "disabled"; + }; + + syscon0: syscon@2000 { + compatible = "nxp,lpc-syscon"; + reg = <0x2000 0x1000>; + #clock-cells = <1>; + }; + + syscon2: syscon@66000 { + compatible = "nxp,lpc-syscon"; + reg = <0x66000 0x1000>; + #clock-cells = <1>; + }; + + syscon3: syscon@62000 { + compatible = "nxp,lpc-syscon"; + reg = <0x62000 0x1000>; + #clock-cells = <1>; + }; + + syscon4: syscon@a2000 { + compatible = "nxp,lpc-syscon"; + reg = <0xa2000 0x1000>; + #clock-cells = <1>; + }; + + iocon: iocon@4000 { + compatible = "nxp,lpc-iocon"; + reg = <0x4000 0x1000>; + status = "okay"; + }; + + iocon1: iocon@64000 { + compatible = "nxp,lpc-iocon"; + reg = <0x64000 0x1000>; + status = "okay"; + }; + + iocon2: iocon@a5000 { + compatible = "nxp,lpc-iocon"; + reg = <0xa5000 0x1000>; + status = "okay"; + }; + + gpio0: gpio@100000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x100000 0x1000>; + interrupts = <91 0>,<92 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio0>; + }; + + gpio1: gpio@102000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x102000 0x1000>; + interrupts = <93 0>,<94 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio1>; + }; + + gpio2: gpio@104000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x104000 0x1000>; + interrupts = <95 0>,<96 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio2>; + }; + + gpio3: gpio@106000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x106000 0x1000>; + interrupts = <97 0>,<98 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio3>; + }; + + gpio4: gpio@108000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x108000 0x1000>; + interrupts = <99 0>,<100 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio4>; + }; + + gpio5: gpio@10a000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x10a000 0x1000>; + interrupts = <101 0>,<102 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio5>; + }; + + gpio6: gpio@10c000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x10c000 0x1000>; + interrupts = <103 0>,<104 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio6>; + }; + + gpio7: gpio@10e000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x10e000 0x1000>; + interrupts = <105 0>,<106 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio7>; + }; + + flexcomm0: flexcomm@110000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x110000 0x1000>; + interrupts = <7 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm0_lpuart0: uart@110000 { + compatible = "nxp,lpuart"; + reg = <0x110000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM0_CLK>; + status = "disabled"; + }; + + flexcomm0_lpspi0: spi@110000 { + compatible = "nxp,lpspi"; + reg = <0x110000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM0_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm0_lpi2c0: lpi2c@110800 { + compatible = "nxp,lpi2c"; + reg = <0x110800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM0_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm1: flexcomm@111000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x111000 0x1000>; + interrupts = <8 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm1_lpuart1: uart@111000 { + compatible = "nxp,lpuart"; + reg = <0x111000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM1_CLK>; + status = "disabled"; + }; + + flexcomm1_lpspi1: spi@111000 { + compatible = "nxp,lpspi"; + reg = <0x111000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM1_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm1_lpi2c1: lpi2c@111800 { + compatible = "nxp,lpi2c"; + reg = <0x111800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM1_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm2: flexcomm@112000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x112000 0x1000>; + interrupts = <9 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm2_lpuart2: uart@112000 { + compatible = "nxp,lpuart"; + reg = <0x112000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM2_CLK>; + status = "disabled"; + }; + + flexcomm2_lpspi2: spi@112000 { + compatible = "nxp,lpspi"; + reg = <0x112000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM2_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm2_lpi2c2: lpi2c@112800 { + compatible = "nxp,lpi2c"; + reg = <0x112800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM2_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm3: flexcomm@113000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x113000 0x1000>; + interrupts = <10 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm3_lpuart3: uart@113000 { + compatible = "nxp,lpuart"; + reg = <0x113000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM3_CLK>; + status = "disabled"; + }; + + flexcomm3_lpspi3: spi@113000 { + compatible = "nxp,lpspi"; + reg = <0x113000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM3_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm3_lpi2c3: lpi2c@113800 { + compatible = "nxp,lpi2c"; + reg = <0x113800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM3_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm4: flexcomm@171000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x171000 0x1000>; + interrupts = <11 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm4_lpuart4: uart@171000 { + compatible = "nxp,lpuart"; + reg = <0x171000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM4_CLK>; + status = "disabled"; + }; + + flexcomm4_lpspi4: spi@171000 { + compatible = "nxp,lpspi"; + reg = <0x171000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM4_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm4_lpi2c4: lpi2c@171800 { + compatible = "nxp,lpi2c"; + reg = <0x171800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM4_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm5: flexcomm@172000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x172000 0x1000>; + interrupts = <12 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm5_lpuart5: uart@172000 { + compatible = "nxp,lpuart"; + reg = <0x172000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM5_CLK>; + status = "disabled"; + }; + + flexcomm5_lpspi5: spi@172000 { + compatible = "nxp,lpspi"; + reg = <0x172000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM5_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm5_lpi2c5: lpi2c@172800 { + compatible = "nxp,lpi2c"; + reg = <0x172800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM5_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm6: flexcomm@173000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x173000 0x1000>; + interrupts = <35 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm6_lpuart6: uart@173000 { + compatible = "nxp,lpuart"; + reg = <0x173000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM6_CLK>; + status = "disabled"; + }; + + flexcomm6_lpspi6: spi@173000 { + compatible = "nxp,lpspi"; + reg = <0x173000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM6_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm6_lpi2c6: lpi2c@173800 { + compatible = "nxp,lpi2c"; + reg = <0x173800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM6_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm7: flexcomm@174000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x174000 0x1000>; + interrupts = <36 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm7_lpuart7: uart@174000 { + compatible = "nxp,lpuart"; + reg = <0x174000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM7_CLK>; + status = "disabled"; + }; + + flexcomm7_lpspi7: spi@174000 { + compatible = "nxp,lpspi"; + reg = <0x174000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM7_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm7_lpi2c7: lpi2c@174800 { + compatible = "nxp,lpi2c"; + reg = <0x174800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM7_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm8: flexcomm@199000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x199000 0x1000>; + interrupts = <47 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm8_lpuart8: uart@199000 { + compatible = "nxp,lpuart"; + reg = <0x199000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM8_CLK>; + status = "disabled"; + }; + + flexcomm8_lpspi8: spi@199000 { + compatible = "nxp,lpspi"; + reg = <0x199000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM8_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm8_lpi2c8: lpi2c@199800 { + compatible = "nxp,lpi2c"; + reg = <0x199800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM8_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm9: flexcomm@19a000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x19a000 0x1000>; + interrupts = <48 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm9_lpuart9: uart@19a000 { + compatible = "nxp,lpuart"; + reg = <0x19a000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM9_CLK>; + status = "disabled"; + }; + + flexcomm9_lpspi9: spi@19a000 { + compatible = "nxp,lpspi"; + reg = <0x19a000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM9_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm9_lpi2c9: lpi2c@19a800 { + compatible = "nxp,lpi2c"; + reg = <0x19a800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM9_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm10: flexcomm@19b000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x19b000 0x1000>; + interrupts = <49 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm10_lpuart10: uart@19b000 { + compatible = "nxp,lpuart"; + reg = <0x19b000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM10_CLK>; + status = "disabled"; + }; + + flexcomm10_lpspi10: spi@19b000 { + compatible = "nxp,lpspi"; + reg = <0x19b000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM10_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm10_lpi2c10: lpi2c@19b800 { + compatible = "nxp,lpi2c"; + reg = <0x19b800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM10_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm11: flexcomm@19c000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x19c000 0x1000>; + interrupts = <50 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm11_lpuart11: uart@19c000 { + compatible = "nxp,lpuart"; + reg = <0x19c000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM11_CLK>; + status = "disabled"; + }; + + flexcomm11_lpspi11: spi@19c000 { + compatible = "nxp,lpspi"; + reg = <0x19c000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM11_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm11_lpi2c11: lpi2c@19c800 { + compatible = "nxp,lpi2c"; + reg = <0x19c800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM11_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm12: flexcomm@19d000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x19d000 0x1000>; + interrupts = <51 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm12_lpuart12: uart@19d000 { + compatible = "nxp,lpuart"; + reg = <0x19d000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM12_CLK>; + status = "disabled"; + }; + + flexcomm12_lpspi12: spi@19d000 { + compatible = "nxp,lpspi"; + reg = <0x19d000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM12_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm12_lpi2c12: lpi2c@19d800 { + compatible = "nxp,lpi2c"; + reg = <0x19d800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM12_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm13: flexcomm@19e000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x19e000 0x1000>; + interrupts = <52 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm13_lpuart13: uart@19e000 { + compatible = "nxp,lpuart"; + reg = <0x19e000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM13_CLK>; + status = "disabled"; + }; + + flexcomm13_lpspi13: spi@19e000 { + compatible = "nxp,lpspi"; + reg = <0x19e000 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM13_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + flexcomm13_lpi2c13: lpi2c@19e800 { + compatible = "nxp,lpi2c"; + reg = <0x19e800 0x1000>; + clocks = <&clkctl0 MCUX_FLEXCOMM13_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + /* LPFlexcomm14/16 only support LPSPI function */ + lpspi14: spi@484000 { + compatible = "nxp,lpspi"; + reg = <0x484000 0x1000>; + interrupts = <13 0>; + clocks = <&clkctl4 MCUX_LPSPI14_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + + /* LPFlexcomm15 only support LPI2C function. */ + lpi2c15: i2c@213000 { + compatible = "nxp,lpi2c"; + reg = <0x213000 0x1000>; + interrupts = <14 0>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkctl4 MCUX_LPI2C15_CLK>; + status = "disabled"; + }; + + /* LPFlexcomm14/16 only support LPSPI function */ + lpspi16: spi@405000 { + compatible = "nxp,lpspi"; + reg = <0x405000 0x1000>; + interrupts = <53 0>; + clocks = <&clkctl4 MCUX_LPSPI16_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + + mrt0: mrt@2d000 { + compatible = "nxp,mrt"; + reg = <0x2d000 0x100>; + interrupts = <2 0>; + num-channels = <4>; + num-bits = <24>; + clocks = <&clkctl2 MCUX_MRT_CLK>; + resets = <&rstctl0 NXP_SYSCON_RESET(3, 26)>; + #address-cells = <1>; + #size-cells = <0>; + + mrt0_channel0: mrt_channel@0 { + compatible = "nxp,mrt-channel"; + reg = <0>; + status = "disabled"; + }; + + mrt0_channel1: mrt_channel@1 { + compatible = "nxp,mrt-channel"; + reg = <1>; + status = "disabled"; + }; + + mrt0_channel2: mrt_channel@2 { + compatible = "nxp,mrt-channel"; + reg = <2>; + status = "disabled"; + }; + + mrt0_channel3: mrt_channel@3 { + compatible = "nxp,mrt-channel"; + reg = <3>; + status = "disabled"; + }; + }; + + flexio: flexio@416000 { + compatible = "nxp,flexio"; + reg = <0x416000 0x1000>; + status = "disabled"; + interrupts = <55 0>; + clocks = <&clkctl4 MCUX_FLEXIO0_CLK>; + }; + + os_timer_cpu0: timers@207000 { + compatible = "nxp,os-timer"; + reg = <0x207000 0x1000>; + interrupts = <34 0>; + status = "disabled"; + }; +}; + +&systick { + /* + * RT700 cm33_cpu0 relies by default on the OS Timer for system + * clock implementation, so the SysTick node is not to be enabled. + */ + status = "disabled"; +}; + +&xspi0 { + compatible = "nxp,xspi"; + status = "disabled"; + interrupts = <42 0>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkctl0 MCUX_XSPI_CLK>; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/dts/arm/nxp/nxp_rt7xx_cm33_cpu1.dtsi b/dts/arm/nxp/nxp_rt7xx_cm33_cpu1.dtsi new file mode 100644 index 0000000000000..23baca895d4ec --- /dev/null +++ b/dts/arm/nxp/nxp_rt7xx_cm33_cpu1.dtsi @@ -0,0 +1,440 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu1: cpu@0 { + compatible = "arm,cortex-m33f"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv8m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + soc { + sram: sram@10000000 { + ranges = <0x0 0x10000000 0x780000 + 0x20000000 0x30000000 0x780000>; + }; + + peripheral: peripheral@50000000 { + ranges = <0x0 0x50000000 0x10000000>; + }; + + xspi2: spi@50411000 { + reg = <0x50411000 0x1000>, <0x70000000 DT_SIZE_M(128)>; + }; + + }; + + pinctrl: pinctrl { + compatible = "nxp,rt-iocon-pinctrl"; + }; +}; + +&sram { + #address-cells = <1>; + #size-cells = <1>; + + /* RT7XX SRAM partitions are shared between code and data. Boards can + * override the reg properties of either sram0 or sram_code nodes to + * change the balance of SRAM allocation. + * + * The SRAM region [0x580000-0x5BFFFF] is reserved for shared memory or application data. + * The SRAM region [0x5C0000-0x67FFFF] is reserved for CPU1 application. + * The SRAM region [0x680000-0x77FFFF] is reserved for HiFi1 application. + */ + + sram_code: memory@600000{ + compatible = "mmio-sram"; + reg = <0x600000 DT_SIZE_K(512)>; + }; + + /* This partition is shared with code in RAM */ + sram_shared_code: memory@20058000{ + compatible = "mmio-sram"; + reg = <0x20058000 DT_SIZE_K(256)>; + }; + + sram0: memory@205C0000 { + compatible = "mmio-sram"; + /* Only use 256K, align with SDK */ + reg = <0x205C0000 DT_SIZE_K(256)>; + }; +}; + +&peripheral { + #address-cells = <1>; + #size-cells = <1>; + /* + * Note that the offsets here are relative to the base address. + * The base addresses differ between non-secure (0x40000000) + * and secure modes (0x50000000). + */ + + lpadc0: adc@20c000 { + compatible = "nxp,lpc-lpadc"; + reg = <0x20c000 0x304>; + interrupts = <15 0>; + status = "disabled"; + clk-divider = <1>; + clk-source = <0>; + voltage-ref= <1>; + calibration-average = <128>; + power-level = <0>; + offset-value-a = <10>; + offset-value-b = <10>; + #io-channel-cells = <1>; + clocks = <&clkctl3 MCUX_LPADC1_CLK>; + }; + + rstctl1: reset@40000 { + compatible = "nxp,rstctl"; + reg = <0x40000 0x1000>; + #reset-cells = <1>; + }; + + rstctl2: reset@67000 { + compatible = "nxp,rstctl"; + reg = <0x67000 0x1000>; + #reset-cells = <1>; + }; + + rstctl3: reset@60000 { + compatible = "nxp,rstctl"; + reg = <0x60000 0x1000>; + #reset-cells = <1>; + }; + + rstctl4: reset@a0000 { + compatible = "nxp,rstctl"; + reg = <0xa0000 0x1000>; + #reset-cells = <1>; + }; + + clkctl1: clkctl@41000 { + compatible = "nxp,lpc-syscon"; + reg = <0x41000 0x1000>; + #clock-cells = <1>; + }; + + clkctl2: clkctl@65000 { + compatible = "nxp,lpc-syscon"; + reg = <0x65000 0x1000>; + #clock-cells = <1>; + }; + + clkctl3: clkctl@61000 { + compatible = "nxp,lpc-syscon"; + reg = <0x61000 0x1000>; + #clock-cells = <1>; + }; + + clkctl4: clkctl@a1000 { + compatible = "nxp,lpc-syscon"; + reg = <0xa1000 0x1000>; + #clock-cells = <1>; + }; + + ctimer5: ctimer@48000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x48000 0x1000>; + interrupts = <7 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&clkctl1 MCUX_CTIMER5_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer6: ctimer@49000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x49000 0x1000>; + interrupts = <8 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&clkctl1 MCUX_CTIMER6_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer7: ctimer@4a000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x4a000 0x1000>; + interrupts = <9 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&clkctl1 MCUX_CTIMER7_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + syscon1: syscon@42000 { + compatible = "nxp,lpc-syscon"; + reg = <0x42000 0x1000>; + #clock-cells = <1>; + }; + + syscon2: syscon@66000 { + compatible = "nxp,lpc-syscon"; + reg = <0x66000 0x1000>; + #clock-cells = <1>; + }; + + syscon3: syscon@62000 { + compatible = "nxp,lpc-syscon"; + reg = <0x62000 0x1000>; + #clock-cells = <1>; + }; + + syscon4: syscon@a2000 { + compatible = "nxp,lpc-syscon"; + reg = <0xa2000 0x1000>; + #clock-cells = <1>; + }; + + iocon1: iocon@64000 { + compatible = "nxp,lpc-iocon"; + reg = <0x64000 0x1000>; + status = "okay"; + }; + + iocon2: iocon@a5000 { + compatible = "nxp,lpc-iocon"; + reg = <0xa5000 0x1000>; + status = "okay"; + }; + + gpio8: gpio@320000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x320000 0x1000>; + interrupts = <61 0>,<62 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio8>; + gpio-port-offest = <8>; + }; + + gpio9: gpio@322000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x322000 0x1000>; + interrupts = <63 0>,<64 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio9>; + gpio-port-offest = <8>; + }; + + gpio10: gpio@324000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x324000 0x1000>; + interrupts = <65 0>,<66 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&gpio10>; + gpio-port-offest = <8>; + }; + + flexcomm17: flexcomm@326000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x326000 0x1000>; + interrupts = <11 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm17_lpuart17: uart@326000 { + compatible = "nxp,lpuart"; + reg = <0x326000 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM17_CLK>; + status = "disabled"; + }; + flexcomm17_lpspi17: lpspi@326000 { + compatible = "nxp,lpspi"; + reg = <0x326000 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM17_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + flexcomm17_lpi2c17: lpi2c@326800 { + compatible = "nxp,lpi2c"; + reg = <0x326800 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM17_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm18: flexcomm@327000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x327000 0x1000>; + interrupts = <12 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm18_lpuart18: uart@327000 { + compatible = "nxp,lpuart"; + reg = <0x327000 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM18_CLK>; + status = "disabled"; + }; + flexcomm18_lpspi18: lpspi@327000 { + compatible = "nxp,lpspi"; + reg = <0x327000 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM18_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + flexcomm18_lpi2c18: lpi2c@327800 { + compatible = "nxp,lpi2c"; + reg = <0x327800 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM18_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm19: flexcomm@328000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x328000 0x1000>; + interrupts = <13 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm19_lpuart19: uart@328000 { + compatible = "nxp,lpuart"; + reg = <0x328000 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM19_CLK>; + status = "disabled"; + }; + flexcomm19_lpspi19: lpspi@328000 { + compatible = "nxp,lpspi"; + reg = <0x328000 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM19_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + flexcomm19_lpi2c19: lpi2c@328800 { + compatible = "nxp,lpi2c"; + reg = <0x328800 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM19_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + flexcomm20: flexcomm@329000 { + compatible = "nxp,lp-flexcomm"; + reg = <0x329000 0x1000>; + interrupts = <14 0>; + status = "disabled"; + + /* Empty ranges property implies parent and child address space is identical */ + ranges = <>; + #address-cells = <1>; + #size-cells = <1>; + + flexcomm20_lpuart20: uart@329000 { + compatible = "nxp,lpuart"; + reg = <0x329000 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM20_CLK>; + status = "disabled"; + }; + flexcomm20_lpspi20: lpspi@329000 { + compatible = "nxp,lpspi"; + reg = <0x329000 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM20_CLK>; + #address-cells = <1>; + #size-cells = <0>; + tx-fifo-size = <8>; + rx-fifo-size = <8>; + status = "disabled"; + }; + flexcomm20_lpi2c20: lpi2c@329800 { + compatible = "nxp,lpi2c"; + reg = <0x329800 0x1000>; + clocks = <&clkctl1 MCUX_FLEXCOMM20_CLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; + + /* LPFlexcomm15 only support LPI2C function. */ + lpi2c15: i2c@213000 { + compatible = "nxp,lpi2c"; + reg = <0x213000 0x1000>; + interrupts = <14 0>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clkctl4 MCUX_LPI2C15_CLK>; + status = "disabled"; + }; + + os_timer_cpu1: timers@209000 { + compatible = "nxp,os-timer"; + reg = <0x209000 0x1000>; + interrupts = <30 0>; + status = "disabled"; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; + +&systick { + /* + * RT700 cm33_cpu1 relies by default on the OS Timer for system + * clock implementation, so the SysTick node is not to be enabled. + */ + status = "disabled"; +}; diff --git a/dts/arm/nxp/nxp_rw6xx_common.dtsi b/dts/arm/nxp/nxp_rw6xx_common.dtsi index 2d436173c4d29..3923a14211438 100644 --- a/dts/arm/nxp/nxp_rw6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rw6xx_common.dtsi @@ -16,6 +16,7 @@ / { chosen { zephyr,entropy = &trng; + zephyr,nbu = &nbu; zephyr,bt-hci = &hci; zephyr,hdlc-rcp-if = &hdlc_rcp_if; }; @@ -74,6 +75,11 @@ #address-cells = <1>; #size-cells = <1>; + /* RW6XX SRAM can be access by either code or data bus, determined + * by the address used to access the memory. + * Applications can override the reg properties of either + * sram_data or sram_code nodes to change the balance of SRAM access partitioning. + */ sram_data: memory@40000 { compatible = "mmio-sram"; reg = <0x40000 DT_SIZE_K(960)>; @@ -451,28 +457,24 @@ pdmc0: dmic-channel@0 { reg = <0>; - compatible = "nxp,dmic-channel"; dmas = <&dma0 16>; status = "disabled"; }; pdmc1: dmic-channel@1 { reg = <1>; - compatible = "nxp,dmic-channel"; dmas = <&dma0 17>; status = "disabled"; }; pdmc2: dmic-channel@2 { reg = <2>; - compatible = "nxp,dmic-channel"; dmas = <&dma0 18>; status = "disabled"; }; pdmc3: dmic-channel@3 { reg = <3>; - compatible = "nxp,dmic-channel"; dmas = <&dma0 19>; status = "disabled"; }; @@ -515,17 +517,18 @@ status = "disabled"; }; + nbu: nbu { + compatible = "nxp,nbu"; + interrupts = <90 2>, <82 2>; + interrupt-names = "nbu_rx_int", "wakeup_int"; + }; + hci: hci_ble { compatible = "nxp,hci-ble"; - /* first index is the hci interrupt, the second is the wake up done interrupt */ - interrupts = <90 2>, <82 2>; - interrupt-names = "hci_int", "wakeup_int"; }; hdlc_rcp_if: hdlc_rcp_if { compatible = "nxp,hdlc-rcp-if"; - /* first index is the hdlc_rcp_if interrupt */ - /* the second is the wake up done interrupt */ interrupts = <90 2>, <82 2>; interrupt-names = "hdlc_rcp_if_int", "wakeup_int"; }; diff --git a/dts/arm/nxp/nxp_s32k1xx.dtsi b/dts/arm/nxp/nxp_s32k1xx.dtsi index 2a06e1ae6f328..093914b3553a1 100644 --- a/dts/arm/nxp/nxp_s32k1xx.dtsi +++ b/dts/arm/nxp/nxp_s32k1xx.dtsi @@ -33,7 +33,7 @@ interrupt-parent = <&nvic>; mpu: mpu@4000d000 { - compatible = "nxp,kinetis-mpu"; + compatible = "nxp,sysmpu"; reg = <0x4000d000 0x1000>; status = "disabled"; }; @@ -77,6 +77,8 @@ clocks = <&clock NXP_S32_LPSPI0_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; @@ -86,6 +88,8 @@ interrupts = <27 0>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; @@ -95,6 +99,8 @@ interrupts = <28 0>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; @@ -166,7 +172,7 @@ }; lpuart0: uart@4006a000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006a000 0x1000>; interrupts = <31 0>; clocks = <&clock NXP_S32_LPUART0_CLK>; @@ -174,7 +180,7 @@ }; lpuart1: uart@4006b000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006b000 0x1000>; interrupts = <33 0>; clocks = <&clock NXP_S32_LPUART1_CLK>; @@ -182,7 +188,7 @@ }; lpuart2: uart@4006c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4006c000 0x1000>; interrupts = <35 0>; status = "disabled"; @@ -239,7 +245,7 @@ }; ftm0: ftm@40038000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40038000 0x1000>; interrupts = <99 0>, <100 0>, <101 0>, <102 0>, <104 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; @@ -249,7 +255,7 @@ }; ftm1: ftm@40039000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40039000 0x1000>; interrupts = <105 0>, <106 0>, <107 0>, <108 0>, <110 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; @@ -259,7 +265,7 @@ }; ftm2: ftm@4003a000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4003a000 0x1000>; interrupts = <111 0>, <112 0>, <113 0>, <114 0>, <116 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; @@ -269,7 +275,7 @@ }; ftm3: ftm@40026000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40026000 0x1000>; interrupts = <117 0>, <118 0>, <119 0>, <120 0>, <122 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; @@ -279,7 +285,7 @@ }; ftm4: ftm@4006e000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4006e000 0x1000>; interrupts = <123 0>, <124 0>, <125 0>, <126 0>, <128 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; @@ -289,7 +295,7 @@ }; ftm5: ftm@4006f000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x4006f000 0x1000>; interrupts = <129 0>, <130 0>, <131 0>, <132 0>, <134 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; @@ -299,7 +305,7 @@ }; ftm6: ftm@40070000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40070000 0x1000>; interrupts = <135 0>, <136 0>, <137 0>, <138 0>, <140 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; @@ -309,7 +315,7 @@ }; ftm7: ftm@40071000 { - compatible = "nxp,kinetis-ftm"; + compatible = "nxp,ftm"; reg = <0x40071000 0x1000>; interrupts = <141 0>, <142 0>, <143 0>, <144 0>, <146 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; @@ -319,7 +325,7 @@ }; rtc: rtc@4003d000 { - compatible = "nxp,kinetis-rtc"; + compatible = "nxp,rtc"; reg = <0x4003d000 0x1000>; interrupts = <46 0>, <47 0>; interrupt-names = "alarm", "seconds"; diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index c1152076d4d8b..91628a3dad4cc 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -90,6 +90,7 @@ eirq0: eirq@40290010 { compatible = "nxp,s32-siul2-eirq"; reg = <0x40290010 0xb4>; + #address-cells = <0>; interrupts = <53 0>, <54 0>, <55 0>, <56 0>; interrupt-controller; #interrupt-cells = <2>; @@ -323,7 +324,7 @@ }; lpuart0: uart@40328000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40328000 0x4000>; interrupts = <141 0>; clocks = <&clock NXP_S32_LPUART0_CLK>; @@ -331,7 +332,7 @@ }; lpuart1: uart@4032c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4032c000 0x4000>; interrupts = <142 0>; clocks = <&clock NXP_S32_LPUART1_CLK>; @@ -339,7 +340,7 @@ }; lpuart2: uart@40330000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40330000 0x4000>; interrupts = <143 0>; clocks = <&clock NXP_S32_LPUART2_CLK>; @@ -347,7 +348,7 @@ }; lpuart3: uart@40334000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40334000 0x4000>; interrupts = <144 0>; clocks = <&clock NXP_S32_LPUART3_CLK>; @@ -355,7 +356,7 @@ }; lpuart4: uart@40338000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40338000 0x4000>; interrupts = <145 0>; clocks = <&clock NXP_S32_LPUART4_CLK>; @@ -363,7 +364,7 @@ }; lpuart5: uart@4033c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4033c000 0x4000>; interrupts = <146 0>; clocks = <&clock NXP_S32_LPUART5_CLK>; @@ -371,7 +372,7 @@ }; lpuart6: uart@40340000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40340000 0x4000>; interrupts = <147 0>; clocks = <&clock NXP_S32_LPUART6_CLK>; @@ -379,7 +380,7 @@ }; lpuart7: uart@40344000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40344000 0x4000>; interrupts = <148 0>; clocks = <&clock NXP_S32_LPUART7_CLK>; @@ -387,7 +388,7 @@ }; lpuart8: uart@4048c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4048c000 0x4000>; interrupts = <149 0>; clocks = <&clock NXP_S32_LPUART8_CLK>; @@ -395,7 +396,7 @@ }; lpuart9: uart@40490000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40490000 0x4000>; interrupts = <150 0>; clocks = <&clock NXP_S32_LPUART9_CLK>; @@ -403,7 +404,7 @@ }; lpuart10: uart@40494000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40494000 0x4000>; interrupts = <151 0>; clocks = <&clock NXP_S32_LPUART10_CLK>; @@ -411,7 +412,7 @@ }; lpuart11: uart@40498000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x40498000 0x4000>; interrupts = <152 0>; clocks = <&clock NXP_S32_LPUART11_CLK>; @@ -419,7 +420,7 @@ }; lpuart12: uart@4049c000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x4049c000 0x4000>; interrupts = <153 0>; clocks = <&clock NXP_S32_LPUART12_CLK>; @@ -427,7 +428,7 @@ }; lpuart13: uart@404a0000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x404a0000 0x4000>; interrupts = <154 0>; clocks = <&clock NXP_S32_LPUART13_CLK>; @@ -435,7 +436,7 @@ }; lpuart14: uart@404a4000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x404a4000 0x4000>; interrupts = <155 0>; clocks = <&clock NXP_S32_LPUART14_CLK>; @@ -443,7 +444,7 @@ }; lpuart15: uart@404a8000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x404a8000 0x4000>; interrupts = <156 0>; clocks = <&clock NXP_S32_LPUART15_CLK>; @@ -570,6 +571,8 @@ clocks = <&clock NXP_S32_LPSPI0_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; @@ -580,6 +583,8 @@ clocks = <&clock NXP_S32_LPSPI1_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; @@ -590,6 +595,8 @@ clocks = <&clock NXP_S32_LPSPI2_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; @@ -600,6 +607,8 @@ clocks = <&clock NXP_S32_LPSPI3_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; @@ -610,6 +619,8 @@ clocks = <&clock NXP_S32_LPSPI4_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; @@ -620,6 +631,8 @@ clocks = <&clock NXP_S32_LPSPI5_CLK>; #address-cells = <1>; #size-cells = <0>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index f4814538990f3..974ee633e1513 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -105,6 +105,7 @@ compatible = "arm,gic-v3", "arm,gic"; reg = <0x47800000 0x10000>, <0x47900000 0x80000>; + #address-cells = <0>; interrupt-controller; #interrupt-cells = <4>; status = "okay"; @@ -219,6 +220,7 @@ eirq0: eirq0@40520010 { compatible = "nxp,s32-siul2-eirq"; reg = <0x40520010 0xb4>; + #address-cells = <0>; interrupts = ; interrupt-controller; #interrupt-cells = <2>; @@ -270,6 +272,7 @@ eirq1: eirq1@40d20010 { compatible = "nxp,s32-siul2-eirq"; reg = <0x40d20010 0xb4>; + #address-cells = <0>; interrupts = ; interrupt-controller; #interrupt-cells = <2>; @@ -345,6 +348,7 @@ eirq4: eirq4@42520010 { compatible = "nxp,s32-siul2-eirq"; reg = <0x42520010 0xb4>; + #address-cells = <0>; interrupts = ; interrupt-controller; #interrupt-cells = <2>; @@ -418,6 +422,7 @@ eirq5: eirq5@42d20010 { compatible = "nxp,s32-siul2-eirq"; reg = <0x42d20010 0xb4>; + #address-cells = <0>; interrupts = ; interrupt-controller; #interrupt-cells = <2>; @@ -561,7 +566,7 @@ }; dspi0: spi@40340000 { - compatible = "nxp,kinetis-dspi"; + compatible = "nxp,dspi"; reg = <0x40340000 0x10000>; interrupts = ; clocks = <&clock NXP_S32_MSCDSPI_CLK>; @@ -1259,5 +1264,193 @@ status = "disabled"; }; + emios0: emios@420b0000 { + compatible = "nxp,s32-emios"; + reg = <0x420b0000 0x4000>; + clocks = <&clock NXP_S32_P4_REG_INTF_CLK>; + internal-cnt = <0xFFFFFFFF>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "0_CH0", "0_CH1", "0_CH2", "0_CH3", "0_CH4", + "0_CH5", "0_CH6", "0_CH7", "0_CH8", "0_CH9", + "0_CH10", "0_CH12", "0_CH14", "0_CH16", + "0_CH17", "0_CH18", "0_CH19", "0_CH20", + "0_CH21", "0_CH22", "0_CH23", "0_CH24", + "0_CH25", "0_CH26", "0_CH27", "0_CH28", + "0_CH29", "0_CH30", "0_CH31"; + status = "disabled"; + + master_bus { + emios0_bus_a: emios0_bus_a { + channel = <23>; + bus-type = "BUS_A"; + channel-mask = <0xFF7FFFFF>; + status = "disabled"; + }; + + emios0_bus_b: emios0_bus_b { + channel = <0>; + bus-type = "BUS_B"; + channel-mask = <0x000000FE>; + status = "disabled"; + }; + + emios0_bus_c: emios0_bus_c { + channel = <8>; + bus-type = "BUS_C"; + channel-mask = <0x0000FE00>; + status = "disabled"; + }; + + emios0_bus_d: emios0_bus_d { + channel = <16>; + bus-type = "BUS_D"; + channel-mask = <0x00FE0000>; + status = "disabled"; + }; + + emios0_bus_e: emios0_bus_e { + channel = <24>; + bus-type = "BUS_E"; + channel-mask = <0xFE000000>; + status = "disabled"; + }; + }; + + pwm { + compatible = "nxp,s32-emios-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + emios1: emios@400b0000 { + compatible = "nxp,s32-emios"; + reg = <0x400b0000 0x4000>; + clocks = <&clock NXP_S32_P0_REG_INTF_CLK>; + internal-cnt = <0xFFFFFFFF>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "1_CH0", "1_CH1", "1_CH2", "1_CH3", "1_CH4", + "1_CH5", "1_CH6", "1_CH7", "1_CH8", "1_CH10", + "1_CH12", "1_CH14", "1_CH16", "1_CH17", + "1_CH18", "1_CH19", "1_CH20", "1_CH21", + "1_CH22", "1_CH23", "1_CH24", "1_CH25", + "1_CH26", "1_CH27", "1_CH28", "1_CH29", + "1_CH30", "1_CH31"; + status = "disabled"; + + master_bus { + emios1_bus_a: emios1_bus_a { + channel = <23>; + bus-type = "BUS_A"; + channel-mask = <0xFF7FFFFF>; + status = "disabled"; + }; + + emios1_bus_b: emios1_bus_b { + channel = <0>; + bus-type = "BUS_B"; + channel-mask = <0x000000FE>; + status = "disabled"; + }; + + emios1_bus_c: emios1_bus_c { + channel = <8>; + bus-type = "BUS_C"; + channel-mask = <0x0000FE00>; + status = "disabled"; + }; + + emios1_bus_d: emios1_bus_d { + channel = <16>; + bus-type = "BUS_D"; + channel-mask = <0x00FE0000>; + status = "disabled"; + }; + + emios1_bus_e: emios1_bus_e { + channel = <24>; + channel-mask = <0xFE000000>; + bus-type = "BUS_E"; + status = "disabled"; + }; + }; + + pwm { + compatible = "nxp,s32-emios-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + qspi0: qspi@42320000 { + compatible = "nxp,s32-qspi"; + reg = <0x42320000 0x4000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + qspi1: qspi@42340000 { + compatible = "nxp,s32-qspi"; + reg = <0x42340000 0x4000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/raspberrypi/rpi_pico/m33.dtsi b/dts/arm/raspberrypi/rpi_pico/m33.dtsi new file mode 100644 index 0000000000000..3f8ff861aad84 --- /dev/null +++ b/dts/arm/raspberrypi/rpi_pico/m33.dtsi @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* Model in the device tree a Cortex-M33 core being 'plugged' into each + * 'socket' within the SoC. Within the datasheet these are core 0 and core 1. + */ +&cpu0 { + compatible = "arm,cortex-m33"; +}; + +&cpu1 { + compatible = "arm,cortex-m33"; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/raspberrypi/rpi_pico/rp2040.dtsi b/dts/arm/raspberrypi/rpi_pico/rp2040.dtsi index ae449e3b7cc54..6398674e0e020 100644 --- a/dts/arm/raspberrypi/rpi_pico/rp2040.dtsi +++ b/dts/arm/raspberrypi/rpi_pico/rp2040.dtsi @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -168,7 +168,6 @@ xosc: xosc { compatible = "raspberrypi,pico-xosc"; clock-frequency = <12000000>; - startup-delay-multiplier = <64>; #clock-cells = <0>; }; diff --git a/dts/arm/raspberrypi/rpi_pico/rp2350.dtsi b/dts/arm/raspberrypi/rpi_pico/rp2350.dtsi new file mode 100644 index 0000000000000..687cafc19aade --- /dev/null +++ b/dts/arm/raspberrypi/rpi_pico/rp2350.dtsi @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef RPI_PICO_DEFAULT_IRQ_PRIORITY +#define RPI_PICO_DEFAULT_IRQ_PRIORITY 7 +#endif + +/ { + aliases { + die-temp0 = &die_temp; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + /* There are two CPU sockets in the RP2350-series SoCs. + * Represent the sockets in the device tree as these two + * partially-defined CPU instances. Use a separate DTSI file to + * define what kind of CPU cores they are. + */ + cpu0: cpu@0 { + reg = <0>; + }; + + cpu1: cpu@1 { + reg = <1>; + }; + }; + + clocks { + clk_gpout0: clk-gpout0 { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <150000000>; + #clock-cells = <0>; + #address-cells = <0>; + }; + + clk_gpout1: clk-gpout1 { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <150000000>; + #clock-cells = <0>; + }; + + clk_gpout2: clk-gpout2 { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <150000000>; + #clock-cells = <0>; + }; + + clk_gpout3: clk-gpout3 { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <150000000>; + #clock-cells = <0>; + }; + + clk_hstx: clk-hstx { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <150000000>; + #clock-cells = <0>; + }; + + clk_ref: clk-ref { + compatible = "raspberrypi,pico-clock"; + clocks = <&xosc>; + clock-names = "xosc"; + clock-frequency = <12000000>; + #clock-cells = <0>; + }; + + clk_sys: clk-sys { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <150000000>; + #clock-cells = <0>; + }; + + clk_usb: clk-usb { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_usb>; + clock-names = "pll_usb"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + + clk_adc: clk-adc { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_usb>; + clock-names = "pll_usb"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + + clk_peri: clk-peri { + compatible = "raspberrypi,pico-clock"; + clocks = <&clk_sys>; + clock-names = "clk_sys"; + clock-frequency = <150000000>; + #clock-cells = <0>; + }; + + pll_sys: pll-sys { + compatible = "raspberrypi,pico-pll"; + clocks = <&xosc>; + clock-names = "xosc"; + clock-div= <1>; + fb-div= <125>; + post-div1 = <5>; + post-div2 = <2>; + #clock-cells = <0>; + }; + + pll_usb: pll-usb { + compatible = "raspberrypi,pico-pll"; + clocks = <&xosc>; + clock-names = "xosc"; + clock-div= <1>; + fb-div = <100>; + post-div1 = <5>; + post-div2 = <5>; + #clock-cells = <0>; + }; + + rosc: rosc { + compatible = "raspberrypi,pico-rosc"; + clock-frequency = <6500000>; + range = ; + stage-drive-strength = <0>, <0>, <0>, <0>, <0>, <0>, <0>, <0>; + clock-div = <16>; + phase = <0>; + #clock-cells = <0>; + }; + + rosc_ph: rosc-ph { + compatible = "raspberrypi,pico-clock"; + clock-frequency = <6500000>; + clocks = <&rosc>; + clock-names = "rosc"; + #clock-cells = <0>; + }; + + xosc: xosc { + compatible = "raspberrypi,pico-xosc"; + clock-frequency = <12000000>; + #clock-cells = <0>; + }; + + gpin0: gpin0 { + compatible = "raspberrypi,pico-clock"; + status = "disabled"; + clock-frequency = <0>; + #clock-cells = <0>; + }; + + gpin1: gpin1 { + compatible = "raspberrypi,pico-clock"; + status = "disabled"; + clock-frequency = <0>; + #clock-cells = <0>; + }; + }; + + soc { + compatible = "raspberrypi,rp2350", "simple-bus"; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(520)>; + }; + + qmi: flash-controller@400d0000 { + compatible = "raspberrypi,pico-flash-controller"; + reg = <0x400d0000 0xfc>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@10000000 { + compatible = "soc-nv-flash"; + write-block-size = <1>; + erase-block-size = ; + }; + status = "disabled"; + }; + + reset: reset-controller@40020000 { + compatible = "raspberrypi,pico-reset"; + reg = <0x40020000 DT_SIZE_K(4)>; + reg-width = <4>; + active-low = <0>; + #reset-cells = <1>; + }; + + clocks: clock-controller@40010000 { + compatible = "raspberrypi,pico-clock-controller"; + reg = <0x40010000 DT_SIZE_K(4) + 0x40048000 DT_SIZE_K(4) + 0x40050000 DT_SIZE_K(4) + 0x40058000 DT_SIZE_K(4) + 0x400e8000 DT_SIZE_K(4)>; + reg-names = "clocks", "xosc", "pll_sys", "pll_usb", "rosc"; + #clock-cells = <1>; + status = "okay"; + clocks = <&clk_gpout0>, <&clk_gpout1>, <&clk_gpout2>, <&clk_gpout3>, + <&clk_hstx>, <&clk_ref>, <&clk_sys>, <&clk_peri>, + <&clk_usb>, <&clk_adc>, + <&pll_sys>, <&pll_usb>, <&xosc>, <&rosc>, <&rosc_ph>, + <&gpin0>, <&gpin1>; + clock-names = "clk_gpout0", "clk_gpout1", "clk_gpout2", "clk_gpout3", + "clk_hstx", "clk_ref", "clk_sys", "clk_peri", + "clk_usb", "clk_adc", + "pll_sys", "pll_usb", "xosc", "rosc", "rosc_ph", + "gpin0", "gpin1"; + }; + + gpio0: gpio@40028000 { + compatible = "raspberrypi,pico-gpio"; + reg = <0x40028000 DT_SIZE_K(4)>; + interrupts = <21 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + uart0: uart@40070000 { + compatible = "raspberrypi,pico-uart", "arm,pl011"; + reg = <0x40070000 DT_SIZE_K(4)>; + clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>; + resets = <&reset RPI_PICO_RESETS_RESET_UART0>; + interrupts = <33 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "uart0"; + status = "disabled"; + }; + + uart1: uart@40078000 { + compatible = "raspberrypi,pico-uart", "arm,pl011"; + reg = <0x40078000 DT_SIZE_K(4)>; + clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>; + resets = <&reset RPI_PICO_RESETS_RESET_UART1>; + interrupts = <34 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "uart1"; + status = "disabled"; + }; + + spi0: spi@40080000 { + compatible = "raspberrypi,pico-spi", "arm,pl022"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40080000 DT_SIZE_K(4)>; + clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>; + resets = <&reset RPI_PICO_RESETS_RESET_SPI0>; + interrupts = <31 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "spi0"; + status = "disabled"; + }; + + spi1: spi@40088000 { + compatible = "raspberrypi,pico-spi", "arm,pl022"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40088000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_SPI1>; + clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>; + interrupts = <32 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "spi1"; + status = "disabled"; + }; + + i2c0: i2c@40090000 { + compatible = "raspberrypi,pico-i2c", "snps,designware-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40090000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_I2C0>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; + interrupts = <36 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "i2c0"; + status = "disabled"; + }; + + i2c1: i2c@40098000 { + compatible = "raspberrypi,pico-i2c", "snps,designware-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40098000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_I2C1>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; + interrupts = <37 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "i2c1"; + status = "disabled"; + }; + + adc: adc@400a0000 { + compatible = "raspberrypi,pico-adc"; + reg = <0x400a0000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_ADC>; + clocks = <&clocks RPI_PICO_CLKID_CLK_ADC>; + interrupts = <35 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "adc0"; + status = "disabled"; + #io-channel-cells = <1>; + }; + + pwm: pwm@400a8000 { + compatible = "raspberrypi,pico-pwm"; + reg = <0x400a8000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_PWM>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; + interrupts = <8 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <9 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "PWM_IRQ_WRAP_0", + "PWM_IRQ_WRAP_1"; + status = "disabled"; + #pwm-cells = <3>; + }; + + timer0: timer@400b0000 { + compatible = "raspberrypi,pico-timer"; + reg = <0x400b0000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_TIMER0>; + clocks = <&clocks RPI_PICO_CLKID_CLK_REF>; + interrupts = <0 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <1 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <2 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <3 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "TIMER0_IRQ_0", + "TIMER0_IRQ_1", + "TIMER0_IRQ_2", + "TIMER0_IRQ_3"; + status = "disabled"; + }; + + timer1: timer@400b8000 { + compatible = "raspberrypi,pico-timer"; + reg = <0x400b8000 DT_SIZE_K(4)>; + resets = <&reset RPI_PICO_RESETS_RESET_TIMER1>; + clocks = <&clocks RPI_PICO_CLKID_CLK_REF>; + interrupts = <4 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <5 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <6 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <7 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "TIMER1_IRQ_0", + "TIMER1_IRQ_1", + "TIMER1_IRQ_2", + "TIMER1_IRQ_3"; + status = "disabled"; + }; + + wdt0: watchdog@400d8000 { + compatible = "raspberrypi,pico-watchdog"; + reg = <0x400d8000 DT_SIZE_K(4)>; + clocks = <&clocks RPI_PICO_CLKID_CLK_REF>; + status = "disabled"; + }; + + dma: dma@50000000 { + compatible = "raspberrypi,pico-dma"; + reg = <0x50000000 DT_SIZE_K(64)>; + resets = <&reset RPI_PICO_RESETS_RESET_DMA>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; + interrupts = <10 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <11 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <12 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <13 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "dma0", "dma1", "dma2", "dma3"; + dma-channels = <16>; + status = "disabled"; + #dma-cells = <3>; + }; + + usbd: usbd@50100000 { + compatible = "raspberrypi,pico-usbd"; + reg = <0x50100000 0x10000>; + resets = <&reset RPI_PICO_RESETS_RESET_USBCTRL>; + clocks = <&clocks RPI_PICO_CLKID_CLK_USB>; + interrupts = <14 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "usbctrl"; + num-bidir-endpoints = <16>; + status = "disabled"; + }; + + pio0: pio@50200000 { + compatible = "raspberrypi,pico-pio"; + reg = <0x50200000 DT_SIZE_K(4)>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; + resets = <&reset RPI_PICO_RESETS_RESET_PIO0>; + status = "disabled"; + }; + + pio1: pio@50300000 { + compatible = "raspberrypi,pico-pio"; + reg = <0x50300000 DT_SIZE_K(4)>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; + resets = <&reset RPI_PICO_RESETS_RESET_PIO1>; + status = "disabled"; + }; + + pio2: pio@50400000 { + compatible = "raspberrypi,pico-pio"; + reg = <0x50400000 DT_SIZE_K(4)>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; + resets = <&reset RPI_PICO_RESETS_RESET_PIO2>; + status = "disabled"; + }; + }; + + pinctrl: pin-controller { + compatible = "raspberrypi,pico-pinctrl"; + status = "okay"; + }; + + die_temp: dietemp { + compatible = "raspberrypi,pico-temp"; + status = "disabled"; + }; +}; diff --git a/dts/arm/raspberrypi/rpi_pico/rp2350a.dtsi b/dts/arm/raspberrypi/rpi_pico/rp2350a.dtsi new file mode 100644 index 0000000000000..762af8d82c3a7 --- /dev/null +++ b/dts/arm/raspberrypi/rpi_pico/rp2350a.dtsi @@ -0,0 +1,9 @@ +#include + +&gpio0 { + ngpios = <30>; +}; + +&die_temp { + io-channels = <&adc 4>; +}; diff --git a/dts/arm/realtek/ec/rts5912-pinctrl.dtsi b/dts/arm/realtek/ec/rts5912-pinctrl.dtsi new file mode 100644 index 0000000000000..3ac81a3486263 --- /dev/null +++ b/dts/arm/realtek/ec/rts5912-pinctrl.dtsi @@ -0,0 +1,645 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * + */ + +#include + +&pinctrl +{ + /* ADC PINCTRL SETTING START */ + /omit-if-no-ref/ adc0_gpio074: adc0_gpio074 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc1_gpio075: adc1_gpio075 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc2_gpio076: adc2_gpio076 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc3_gpio077: adc3_gpio077 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ adc4_gpio078: adc4_gpio078 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc5_gpio079: adc5_gpio079 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc6_gpio080: adc6_gpio080 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc7_gpio081: adc7_gpio081 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ adc8_gpio082: adc8_gpio082 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc9_gpio054: adc9_gpio054 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc10_gpio098: adc10_gpio098 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ adc11_gpio024: adc11_gpio024 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* ADC PINCTRL SETTING END */ + /* ESPI PINCTRL SETTING START */ + /omit-if-no-ref/ espi_alert_gpio003: espi_alert_gpio003 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ espi_cs_gpio004: espi_cs_gpio004 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ espi_io3_gpio005: espi_io3_gpio005 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ espi_io2_gpio006: espi_io2_gpio006 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ espi_io1_gpio007: espi_io1_gpio007 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ espi_io0_gpio008: espi_io0_gpio008 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ espi_clk_gpio009: espi_clk_gpio009 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ espi_reset_gpio020: espi_reset_gpio020 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* ESPI PINCTRL SETTING END */ + /* I2C PINCTRL SETTING START */ + /omit-if-no-ref/ i2c00_clk_gpio094: i2c00_clk_gpio094 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c00_data_gpio095: i2c00_data_gpio095 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c00_clk_gpio115: i2c00_clk_gpio115 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c00_data_gpio131: i2c00_data_gpio131 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c01_clk_gpio118: i2c01_clk_gpio118 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c01_data_gpio119: i2c01_data_gpio119 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c02_clk_gpio014: i2c02_clk_gpio014 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c02_data_gpio121: i2c02_data_gpio121 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c03_clk_gpio100: i2c03_clk_gpio100 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c03_data_gpio101: i2c03_data_gpio101 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c04_clk_gpio017: i2c04_clk_gpio017 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c04_data_gpio018: i2c04_data_gpio018 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c05_clk_gpio027: i2c05_clk_gpio027 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c05_data_gpio028: i2c05_data_gpio028 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c05_clk_gpio128: i2c05_clk_gpio128 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c05_data_gpio130: i2c05_data_gpio130 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c06_clk_gpio036: i2c06_clk_gpio036 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c06_data_gpio037: i2c06_data_gpio037 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ i2c07_clk_gpio038: i2c07_clk_gpio038 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ i2c07_data_gpio039: i2c07_data_gpio039 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* I2C PINCTRL SETTING END */ + /* JTAG PINCTRL SETTING START */ + /omit-if-no-ref/ jtag_tdi_gpio87: jtag_tdi_gpio87 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ jtag_tdo_gpio88: jtag_tdo_gpio88 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ jtag_rst_gpio89: jtag_rst_gpio89 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ jtag_clk_gpio90: jtag_clk_gpio90 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ jtag_tms_gpio91: jtag_tms_gpio91 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* JTAG PINCTRL SETTING END */ + /* KSM PINCTRL SETTING START */ + /* KSO PINCTRL SETTING START */ + /omit-if-no-ref/ kso0_gpio041: kso0_gpio041 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso1_gpio042: kso1_gpio042 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso2_gpio043: kso2_gpio043 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso3_gpio044: kso3_gpio044 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ kso4_gpio045: kso4_gpio045 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso5_gpio046: kso5_gpio046 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso6_gpio047: kso6_gpio047 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso7_gpio048: kso7_gpio048 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ kso8_gpio049: kso8_gpio049 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso9_gpio050: kso9_gpio050 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso10_gpio051: kso10_gpio051 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso11_gpio055: kso11_gpio055 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ kso12_gpio056: kso12_gpio056 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso13_gpio057: kso13_gpio057 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso14_gpio058: kso14_gpio058 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso15_gpio059: kso15_gpio059 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ kso16_gpio060: kso16_gpio060 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso17_gpio061: kso17_gpio061 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso18_gpio092: kso18_gpio092 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ kso19_gpio093: kso19_gpio093 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* KSO PINCTRL SETTING END */ + /* KSI PINCTRL SETTING START */ + /omit-if-no-ref/ ksi0_gpio064: ksi0_gpio064 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ksi1_gpio065: ksi1_gpio065 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ksi2_gpio066: ksi2_gpio066 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ksi3_gpio067: ksi3_gpio067 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ ksi4_gpio068: ksi4_gpio068 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ksi5_gpio069: ksi5_gpio069 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ksi6_gpio070: ksi6_gpio070 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ksi7_gpio071: ksi7_gpio071 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ ksi8_gpio054: ksi8_gpio054 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ksi9_gpio098: ksi9_gpio098 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* KSO PINCTRL SETTING END */ + /* KSM PINCTRL SETTING END */ + /* PS2 PINCTRL SETTING START */ + /omit-if-no-ref/ ps2clk0_gpio092: ps2clk0_gpio092 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ps2data0_gpio093: ps2data0_gpio093 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ps2clk0_gpio096: ps2clk0_gpio096 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ ps2data0_gpio097: ps2data0_gpio097 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* PS2 PINCTRL SETTING END */ + /* PWM PINCTRL SETTING START */ + /omit-if-no-ref/ pwm0_gpio022: pwm0_gpio022 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm1_gpio023: pwm1_gpio023 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm2_gpio025: pwm2_gpio025 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm3_gpio026: pwm3_gpio026 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ pwm4_gpio027: pwm4_gpio027 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm5_gpio028: pwm5_gpio028 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm6_gpio029: pwm6_gpio029 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm7_gpio031: pwm7_gpio031 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ pwm8_gpio032: pwm8_gpio032 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm9_gpio033: pwm9_gpio033 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm10_gpio034: pwm10_gpio034 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ pwm11_gpio035: pwm11_gpio035 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* PWM PINCTRL SETTING END */ + /* SPIC PINCTRL SETTING START */ + /omit-if-no-ref/ spic_cs_gpio107: spic_cs_gpio107 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ spic_si_gpio108: spic_si_gpio108 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ spic_so_gpio109: spic_so_gpio109 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ spic_clk_gpio111: spic_clk_gpio111 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ spic_io2_gpio124: spic_io2_gpio124 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ spic_io3_gpio122: spic_io3_gpio122 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* SPIC PINCTRL SETTING END */ + /* TACHO PINCTRL SETTING START */ + /omit-if-no-ref/ tacho0_gpio052: tacho0_gpio052 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ tacho1_gpio053: tacho1_gpio053 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ tacho1_gpio086: tacho1_gpio086 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ tacho2_gpio085: tacho2_gpio085 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ tacho3_gpio083: tacho3_gpio083 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ tacho3_gpio084: tacho3_gpio084 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* TACHO PINCTRL SETTING END */ + /* UART PINCTRL SETTING START */ + /omit-if-no-ref/ uart_rx_gpio113: uart0_rx_gpio113 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_tx_gpio114: uart0_tx_gpio114 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ uart_rx_gpio014: uart1_rx_gpio014 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_tx_gpio015: uart1_tx_gpio015 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ uart_rx_gpio100: uart_rx_gpio100 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_tx_gpio101: uart_tx_gpio101 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + /omit-if-no-ref/ uart_dtr_gpio039: uart_dtr_gpio039 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_rts_gpio040: uart_rts_gpio040 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_dcd_gpio079: uart_dcd_gpio079 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_dsr_gpio080: uart_dsr_gpio080 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_cts_gpio081: uart_cts_gpio081 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_ri_gpio088: uart_ri_gpio088 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /omit-if-no-ref/ uart_dtr_gpio124: uart_dtr_gpio124 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + /* UART PINCTRL SETTING END */ +}; diff --git a/dts/arm/realtek/ec/rts5912.dtsi b/dts/arm/realtek/ec/rts5912.dtsi new file mode 100644 index 0000000000000..aa994898109a6 --- /dev/null +++ b/dts/arm/realtek/ec/rts5912.dtsi @@ -0,0 +1,252 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * + */ + +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m33f"; + reg = <0>; + cpu-power-states = <&idle &suspend_to_ram>; + }; + + power-states { + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <100000>; + }; + + suspend_to_ram: suspend_to_ram { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + min-residency-us = <250000>; + }; + }; + }; + + flash0: flash@20000400 { + reg = <0x20000400 0x4FC00>; + }; + + sram0: memory@20050000 { + compatible = "mmio-sram"; + reg = <0x20050000 0x8000>; + }; + + clocks { + rc25m: rc25m { + compatible = "fixed-clock"; + clock-frequency = <25000000>; + #clock-cells = <0>; + }; + + pll: pll { + compatible = "fixed-clock"; + clock-frequency = <100000000>; + #clock-cells = <0>; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&nvic>; + ranges; + + sccon: clock-controller@40020000 { + compatible = "realtek,rts5912-sccon"; + reg = <0x40020000 0xf0>; + #clock-cells = <2>; + clocks = <&rc25m>, <&pll>; + clock-names = "rc25m", "pll"; + }; + + slwtmr0: slwtmr0@4000c200 { + compatible = "realtek,rts5912-slwtimer"; + reg = <0x4000c200 0x10>; + interrupts = <202 0>; + clocks = <&sccon RTS5912_SCCON_PERIPH_GRP1 PERIPH_GRP1_SLWTMR0_CLKPWR>; + clock-names = "slwtmr"; + max-value = <0xFFFFFFFF>; + clock-frequency = <1000000>; + prescaler = <0>; + status = "okay"; + }; + + rtmr: rtmr@4000c500 { + compatible = "realtek,rts5912-rtmr"; + reg = <0x4000c500 0x10>; + interrupts = <204 0>; + status = "okay"; + }; + + uart0: uart@40010100 { + compatible = "ns16550"; + reg = <0x40010100 0x100>; + reg-shift = <2>; + clock-frequency = <25000000>; + interrupts = <191 0>; + status = "disabled"; + }; + + uart0_wrapper: uart_wrapper@40010200 { + compatible = "realtek,rts5912-uart"; + reg = <0x40010200 0x0020>; + port = <0>; + clocks = <&sccon RTS5912_SCCON_UART UART0_CLKPWR>; + clock-names = "uart0"; + status = "disabled"; + }; + + pinctrl: pin-controller@40090000 { + compatible = "realtek,rts5912-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x40090000 0x300>; + + /* GPIO0-GPIO15 */ + gpioa: gpio@40090000 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40090000 0x40>; + ngpios = <16>; + interrupts = <0 0 1 0 2 0 3 0 + 4 0 5 0 6 0 7 0 + 8 0 9 0 10 0 11 0 + 12 0 13 0 14 0 15 0>; + }; + + /* GPIO16-GPIO31 */ + gpiob: gpio@40090040 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40090040 0x40>; + ngpios = <16>; + interrupts = <16 0 17 0 18 0 19 0 + 20 0 21 0 22 0 23 0 + 24 0 25 0 26 0 27 0 + 28 0 29 0 30 0 31 0>; + }; + + /* GPIO32-GPIO47 */ + gpioc: gpio@40090080 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40090080 0x40>; + ngpios = <16>; + interrupts = <32 0 33 0 34 0 35 0 + 36 0 37 0 38 0 39 0 + 40 0 41 0 42 0 43 0 + 44 0 45 0 46 0 47 0>; + }; + + /* GPIO48-GPIO63 */ + gpiod: gpio@400900c0 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x400900c0 0x40>; + ngpios = <16>; + interrupts = <48 0 49 0 50 0 51 0 + 52 0 53 0 54 0 55 0 + 56 0 57 0 58 0 59 0 + 60 0 61 0 62 0 63 0>; + }; + + /* GPIO64-GPIO79 */ + gpioe: gpio@40090100 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40090100 0x40>; + ngpios = <16>; + interrupts = <64 0 65 0 66 0 67 0 + 68 0 69 0 70 0 71 0 + 72 0 73 0 74 0 75 0 + 76 0 77 0 78 0 79 0>; + }; + + /* GPIO80-GPIO95 */ + gpiof: gpio@40090140 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40090140 0x40>; + ngpios = <16>; + interrupts = <80 0 81 0 82 0 83 0 + 84 0 85 0 86 0 87 0 + 88 0 89 0 90 0 91 0 + 92 0 93 0 94 0 95 0>; + }; + + /* GPIO96-GPIO111 */ + gpiog: gpio@40090180 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40090180 0x40>; + ngpios = <16>; + interrupts = <96 0 97 0 98 0 99 0 + 100 0 101 0 102 0 103 0 + 104 0 105 0 106 0 107 0 + 108 0 109 0 110 0 111 0>; + }; + + /* GPIO112-GPIO127 */ + gpioh: gpio@400901c0 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x400901c0 0x40>; + ngpios = <16>; + interrupts = <112 0 113 0 114 0 115 0 + 116 0 117 0 118 0 119 0 + 120 0 121 0 122 0 123 0 + 124 0 125 0 126 0 127 0>; + }; + + /* GPIO128-GPIO131 */ + gpioi: gpio@40090200 { + compatible = "realtek,rts5912-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40090200 0x10>; + ngpios = <4>; + interrupts = <128 0 129 0 130 0 131 0 + 132 0 133 0 134 0 135 0 + 136 0 137 0 138 0 139 0 + 140 0 141 0 142 0 143 0>; + }; + }; + }; + + swj_port: swj-port { + compatible = "swj-connector"; + pinctrl-0 = <&jtag_tdi_gpio87 &jtag_tdo_gpio88 &jtag_rst_gpio89 + &jtag_clk_gpio90 &jtag_tms_gpio91>; + pinctrl-names = "default"; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; + +&systick { + status = "disabled"; +}; diff --git a/dts/arm/renesas/ra/ra2/r7fa2a1xh.dtsi b/dts/arm/renesas/ra/ra2/r7fa2a1xh.dtsi index fc6c4d20f1e41..511355a8d93f7 100644 --- a/dts/arm/renesas/ra/ra2/r7fa2a1xh.dtsi +++ b/dts/arm/renesas/ra/ra2/r7fa2a1xh.dtsi @@ -6,6 +6,7 @@ #include #include +#include /delete-node/ &sci2; /delete-node/ &sci3; @@ -25,6 +26,71 @@ interrupts = <16 1>, <17 1>, <18 1>, <19 1>; interrupt-names = "rxi", "txi", "tei", "eri"; }; + + pwm1: pwm1@40078100 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078100 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm2@40078200 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078200 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40078300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm4: pwm4@40078400 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm5@40078500 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078500 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm6@40078600 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078600 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-trng"; + status = "disabled"; + }; }; clocks: clocks { @@ -75,6 +141,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <48000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -107,12 +174,91 @@ status = "disabled"; }; - sdadcclk: sdadcclk { compatible = "renesas,ra-cgc-pclk"; #clock-cells = <2>; status = "disabled"; }; + + uclk: uclk { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; }; }; }; + +&ioport0 { + port-irqs = <&port_irq0 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq4"; + port-irq0-pins = <1>; + port-irq4-pins = <0>; +}; + +&ioport1 { + port-irqs = <&port_irq2 &port_irq3 &port_irq4 + &port_irq5 &port_irq6 &port_irq7>; + port-irq-names = "port-irq2", + "port-irq3", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7"; + port-irq2-pins = <10>; + port-irq3-pins = <9>; + port-irq4-pins = <0>; + port-irq5-pins = <1>; + port-irq6-pins = <4 11>; + port-irq7-pins = <5 12>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq2 &port_irq3 + &port_irq6>; + port-irq-names = "port-irq0", + "port-irq2", + "port-irq3", + "port-irq6"; + port-irq0-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; + port-irq6-pins = <6>; +}; + +&ioport3 { + port-irqs = <&port_irq4 &port_irq5>; + port-irq-names = "port-irq4", + "port-irq5"; + port-irq4-pins = <2>; + port-irq5-pins = <1>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq1 &port_irq5 + &port_irq7>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq5", + "port-irq7"; + port-irq0-pins = <0>; + port-irq1-pins = <7 8>; + port-irq5-pins = <1>; + port-irq7-pins = <9>; +}; + +&ioport5 { + port-irqs = <&port_irq1 &port_irq2 &port_irq3>; + port-irq-names = "port-irq1", + "port-irq2", + "port-irq3"; + port-irq1-pins = <2>; + port-irq2-pins = <1>; + port-irq3-pins = <0>; +}; + +&dac_global { + has-chargepump; + has-davrefcr; +}; diff --git a/dts/arm/renesas/ra/ra2/r7fa2l1x9.dtsi b/dts/arm/renesas/ra/ra2/r7fa2l1x9.dtsi new file mode 100644 index 0000000000000..e20c050133579 --- /dev/null +++ b/dts/arm/renesas/ra/ra2/r7fa2l1x9.dtsi @@ -0,0 +1,12 @@ +/** + * Copyright (c) 2024 MUNIC SA + * + * Renesas R7FA2AL1x9 MCU device tree + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +&flash0 { + reg = <0x0 DT_SIZE_K(128)>; +}; diff --git a/dts/arm/renesas/ra/ra2/r7fa2l1xb.dtsi b/dts/arm/renesas/ra/ra2/r7fa2l1xb.dtsi new file mode 100644 index 0000000000000..b148a4337eb80 --- /dev/null +++ b/dts/arm/renesas/ra/ra2/r7fa2l1xb.dtsi @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2024 MUNIC SA + * + * Renesas R7FA2AL1AB MCU device tree + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&flash0 { + reg = <0x0 DT_SIZE_K(256)>; +}; diff --git a/dts/arm/renesas/ra/ra2/r7fa2l1xxxxfp.dtsi b/dts/arm/renesas/ra/ra2/r7fa2l1xxxxfp.dtsi new file mode 100644 index 0000000000000..a55ae8fa6f9d4 --- /dev/null +++ b/dts/arm/renesas/ra/ra2/r7fa2l1xxxxfp.dtsi @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2024 MUNIC SA + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * + * Renesas R7FA2AL1AxxxFP MCU device tree for 100 pins socket + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/ { + clocks: clocks { + #address-cells = <1>; + #size-cells = <1>; + + xtal: clock-main-osc { + compatible = "renesas,ra-cgc-external-clock"; + clock-frequency = ; + #clock-cells = <0>; + status = "disabled"; + }; + + hoco: clock-hoco { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + moco: clock-moco { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + loco: clock-loco { + compatible = "fixed-clock"; + clock-frequency = <32768>; + #clock-cells = <0>; + }; + + subclk: clock-subclk { + compatible = "renesas,ra-cgc-subclk"; + clock-frequency = <32768>; + #clock-cells = <0>; + status = "disabled"; + }; + + pclkblock: pclkblock@4001e01c { + compatible = "renesas,ra-cgc-pclk-block"; + reg = <0x4001e01c 4>, <0x40047000 4>, <0x40047004 4>, + <0x40047008 4>; + reg-names = "MSTPA", "MSTPB","MSTPC", + "MSTPD"; + #clock-cells = <0>; + clocks = <&hoco>; + status = "okay"; + + iclk: iclk { + compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <48000000>; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkb: pclkb { + compatible = "renesas,ra-cgc-pclk"; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkd: pclkd { + compatible = "renesas,ra-cgc-pclk"; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + clkout: clkout { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + + }; + }; +}; diff --git a/dts/arm/renesas/ra/ra2/ra2l1.dtsi b/dts/arm/renesas/ra/ra2/ra2l1.dtsi new file mode 100644 index 0000000000000..91a19de082583 --- /dev/null +++ b/dts/arm/renesas/ra/ra2/ra2l1.dtsi @@ -0,0 +1,234 @@ +/** + * Copyright (c) 2021-2024 MUNIC SA + * Copyright (c) 2024 Renesas Electronics Corporation + * + * Renesas RA2L1 MCU series device tree + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m23"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv8m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + soc { + interrupt-parent = <&nvic>; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x8000>; + }; + + system: system@4001e000 { + compatible = "renesas,ra-system"; + reg = <0x4001e000 0x1000>; + status = "okay"; + }; + + flcn: flash-controller@407ec000 { + reg = <0x407ec000 0x10000>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: code@0 { + compatible = "soc-nv-flash"; + /* "reg" property should be defined in the + * chip specific .dtsi file + */ + }; + + flash1: data@40100000 { + compatible = "soc-nv-flash"; + reg = <0x40100000 DT_SIZE_K(8)>; + }; + }; + + ioport0: gpio@40040000 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x40040000 0x20>; + port = <0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport1: gpio@40040020 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x40040020 0x20>; + port = <1>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport2: gpio@40040040 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x40040040 0x20>; + port = <2>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport3: gpio@40040060 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x40040060 0x20>; + port = <3>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport4: gpio@40040080 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x40040080 0x20>; + port = <4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport5: gpio@400400a0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x400400a0 0x20>; + port = <5>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport6: gpio@400400c0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x400400c0 0x20>; + port = <6>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport7: gpio@400400e0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x400400e0 0x20>; + port = <7>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + pinctrl: pin-controller@40040800 { + compatible = "renesas,ra-pinctrl-pfs"; + reg = <0x40040800 0x3c0>; + status = "okay"; + }; + + sci0: sci0@40070000 { + compatible = "renesas,ra-sci"; + interrupts = <0 1>, <1 1>, <2 1>, <3 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + reg = <0x40070000 0x100>; + clocks = <&pclkb MSTPB 31>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <0>; + status = "disabled"; + }; + }; + + sci1: sci1@40070020 { + compatible = "renesas,ra-sci"; + reg = <0x40070020 0x100>; + clocks = <&pclkb MSTPB 30>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <1>; + status = "disabled"; + }; + }; + + sci2: sci2@40070040 { + compatible = "renesas,ra-sci"; + reg = <0x40070040 0x100>; + clocks = <&pclkb MSTPB 29>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <2>; + status = "disabled"; + }; + }; + + sci3: sci3@40070060 { + compatible = "renesas,ra-sci"; + reg = <0x40070060 0x100>; + clocks = <&pclkb MSTPB 28>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <3>; + status = "disabled"; + }; + }; + + sci9: sci9@40070120 { + compatible = "renesas,ra-sci"; + interrupts = <4 1>, <5 1>, <6 1>, <7 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + reg = <0x40070120 0x100>; + clocks = <&pclkb MSTPB 22>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <9>; + status = "disabled"; + }; + }; + + id_code: id_code@1010018 { + compatible = "zephyr,memory-region"; + reg = <0x01010018 0x20>; + zephyr,memory-region = "ID_CODE"; + status = "okay"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <2>; +}; diff --git a/dts/arm/renesas/ra/ra2/ra2xx.dtsi b/dts/arm/renesas/ra/ra2/ra2xx.dtsi index 523e370c9a283..2d9807c278796 100644 --- a/dts/arm/renesas/ra/ra2/ra2xx.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2xx.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include / { @@ -225,6 +226,20 @@ status = "disabled"; }; + iic0: iic0@40053000 { + compatible = "renesas,ra-iic"; + channel = <0>; + reg = <0x40053000 0x100>; + status = "disabled"; + }; + + iic1: iic1@40053100 { + compatible = "renesas,ra-iic"; + channel = <1>; + reg = <0x40053100 0x100>; + status = "disabled"; + }; + flash-controller@407e0000 { reg = <0x407e0000 0x10000>; #address-cells = <1>; @@ -267,6 +282,102 @@ zephyr,memory-region = "ID_CODE"; status = "okay"; }; + + port_irq0: external-interrupt@40006000 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006000 0x1>; + channel = <0>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq1: external-interrupt@40006001 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006001 0x1>; + channel = <1>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq2: external-interrupt@40006002 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006002 0x1>; + channel = <2>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq3: external-interrupt@40006003 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006003 0x1>; + channel = <3>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq4: external-interrupt@40006004 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006004 0x1>; + channel = <4>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq5: external-interrupt@40006005 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006005 0x1>; + channel = <5>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq6: external-interrupt@40006006 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006006 0x1>; + channel = <6>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq7: external-interrupt@40006007 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006007 0x1>; + channel = <7>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + pwm0: pwm0@40078000 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078000 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + dac_global: dac_global@4005e000 { + compatible = "renesas,ra-dac-global"; + reg = <0x4005e000 0x10c4>; + #address-cells = <1>; + #size-cells = <0>; + + dac0: dac@0 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <0>; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/renesas/ra/ra4/r7fa4e10d2cfm.dtsi b/dts/arm/renesas/ra/ra4/r7fa4e10d2cfm.dtsi new file mode 100644 index 0000000000000..becb0cf5baf62 --- /dev/null +++ b/dts/arm/renesas/ra/ra4/r7fa4e10d2cfm.dtsi @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + flash-controller@407e0000 { + block-32kb-linear-end = <21>; + + flash0: flash@0 { + compatible = "renesas,ra-nv-flash"; + reg = <0x0 DT_SIZE_K(512)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(8)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; + }; + }; + }; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4e10d2cne.dtsi b/dts/arm/renesas/ra/ra4/r7fa4e10d2cne.dtsi new file mode 100644 index 0000000000000..becb0cf5baf62 --- /dev/null +++ b/dts/arm/renesas/ra/ra4/r7fa4e10d2cne.dtsi @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + flash-controller@407e0000 { + block-32kb-linear-end = <21>; + + flash0: flash@0 { + compatible = "renesas,ra-nv-flash"; + reg = <0x0 DT_SIZE_K(512)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(8)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; + }; + }; + }; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi b/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi new file mode 100644 index 0000000000000..8f07b048332d9 --- /dev/null +++ b/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/delete-node/ &spi1; +/delete-node/ &agt4; +/delete-node/ &adc1; +/delete-node/ &iic1; +/delete-node/ &pwm0; + +/ { + soc { + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(128)>; + }; + + sci3: sci3@40118300 { + compatible = "renesas,ra-sci"; + reg = <0x40118300 0x100>; + clocks = <&pclka MSTPB 28>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <3>; + status = "disabled"; + }; + }; + + sci4: sci4@40118400 { + compatible = "renesas,ra-sci"; + reg = <0x40118400 0x100>; + clocks = <&pclka MSTPB 27>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <4>; + status = "disabled"; + }; + }; + + adc@40170000 { + channel-count = <9>; + channel-available-mask = <0x1381f>; + }; + + pwm2: pwm2@40169200 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 29>; + reg = <0x40169200 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-sce9-rng"; + status = "disabled"; + }; + }; + + clocks: clocks { + #address-cells = <1>; + #size-cells = <1>; + + xtal: clock-main-osc { + compatible = "renesas,ra-cgc-external-clock"; + clock-frequency = ; + #clock-cells = <0>; + status = "disabled"; + }; + + hoco: clock-hoco { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + moco: clock-moco { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + loco: clock-loco { + compatible = "fixed-clock"; + clock-frequency = <32768>; + #clock-cells = <0>; + }; + + subclk: clock-subclk { + compatible = "renesas,ra-cgc-subclk"; + clock-frequency = <32768>; + #clock-cells = <0>; + status = "disabled"; + }; + + pll: pll { + compatible = "renesas,ra-cgc-pll"; + #clock-cells = <0>; + + /* PLL */ + clocks = <&hoco>; + div = <2>; + mul = <20 0>; + status = "disabled"; + }; + + pll2: pll2 { + compatible = "renesas,ra-cgc-pll"; + #clock-cells = <0>; + + /* PLL2 */ + div = <2>; + mul = <20 0>; + status = "disabled"; + }; + + pclkblock: pclkblock@40084000 { + compatible = "renesas,ra-cgc-pclk-block"; + reg = <0x40084000 4>, <0x40084004 4>, <0x40084008 4>, + <0x4008400c 4>, <0x40084010 4>; + reg-names = "MSTPA", "MSTPB", "MSTPC", + "MSTPD", "MSTPE"; + #clock-cells = <0>; + clocks = <&pll>; + status = "okay"; + + iclk: iclk { + compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <100000000>; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + pclka: pclka { + compatible = "renesas,ra-cgc-pclk"; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkb: pclkb { + compatible = "renesas,ra-cgc-pclk"; + div = <4>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkc: pclkc { + compatible = "renesas,ra-cgc-pclk"; + div = <4>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkd: pclkd { + compatible = "renesas,ra-cgc-pclk"; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + fclk: fclk { + compatible = "renesas,ra-cgc-pclk"; + div = <4>; + #clock-cells = <2>; + status = "okay"; + }; + + clkout: clkout { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + + uclk: uclk { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + }; + }; +}; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq13-pins = <15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4e2b93cfm.dtsi b/dts/arm/renesas/ra/ra4/r7fa4e2b93cfm.dtsi index e52347b1db6e3..848309f5e2425 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4e2b93cfm.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4e2b93cfm.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,13 @@ /delete-node/ &agt3; /delete-node/ &agt4; /delete-node/ &agt5; +/delete-node/ &iic0; +/delete-node/ &iic1; +/delete-node/ &usbfs; +/delete-node/ &usbfs_phy; + +/delete-node/ &adc1; +/delete-node/ &dac1; / { soc { @@ -32,21 +39,61 @@ }; flash-controller@407e0000 { - reg = <0x407e0000 0x10000>; - #address-cells = <1>; - #size-cells = <1>; + block-32kb-linear-end = <9>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_K(128)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(4)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; + adc@40170000 { + channel-count = <12>; + channel-available-mask = <0x139f7>; + }; + id_code: id_code@100a120 { compatible = "zephyr,memory-region"; reg = <0x0100a120 0x10>; zephyr,memory-region = "ID_CODE"; status = "okay"; }; + + canfd_global: canfd_global@400b0000 { + compatible = "renesas,ra-canfd-global"; + interrupts = <40 1>, <41 1>; + interrupt-names = "rxf", "glerr"; + clocks = <&pclkb 0 0>, <&pclka 0 0>; + clock-names = "opclk", "ramclk"; + dll-max-freq = ; + reg = <0x400b0000 0x2000>; + status = "disabled"; + + canfd0: canfd0 { + compatible = "renesas,ra-canfd"; + channel = <0>; + interrupts = <43 12>, <44 12>, <45 12>; + interrupt-names = "err", "tx", "rx"; + clocks = <&canfdclk MSTPC 27>; + clock-names = "dllclk"; + status = "disabled"; + }; + }; + + trng: trng { + compatible = "renesas,ra-trng"; + status = "disabled"; + }; }; clocks: clocks { @@ -108,6 +155,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <100000000>; div = <2>; #clock-cells = <2>; status = "okay"; @@ -180,3 +228,90 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq14>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq14"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq14-pins = <3>; +}; + +&ioport8 { + port-irqs = <&port_irq11>; + port-irq-names = "port-irq11"; + port-irq11-pins = <14>; +}; + +&dac_global { + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4l1bd4cfp.dtsi b/dts/arm/renesas/ra/ra4/r7fa4l1bd4cfp.dtsi new file mode 100644 index 0000000000000..af5aa03a53dac --- /dev/null +++ b/dts/arm/renesas/ra/ra4/r7fa4l1bd4cfp.dtsi @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + flash-controller@407e0000 { + reg = <0x407e0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "renesas,ra-nv-flash"; + reg = <0x0 DT_SIZE_K(512)>; + write-block-size = <8>; + erase-block-size = <2048>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(8)>; + write-block-size = <1>; + erase-block-size = <256>; + renesas,programming-enable; + }; + }; + }; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi new file mode 100644 index 0000000000000..197144ab337be --- /dev/null +++ b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi @@ -0,0 +1,746 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m33"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv8m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + soc { + interrupt-parent = <&nvic>; + + system: system@4001e000 { + compatible = "renesas,ra-system"; + reg = <0x4001e000 0x1000>; + status = "okay"; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(64)>; + }; + + ioport0: gpio@4001f000 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f000 0x20>; + port = <0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport1: gpio@4001f020 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f020 0x20>; + port = <1>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport2: gpio@4001f040 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f040 0x20>; + port = <2>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport3: gpio@4001f060 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f060 0x20>; + port = <3>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport4: gpio@4001f080 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f080 0x20>; + port = <4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport5: gpio@4001f0a0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f0a0 0x20>; + port = <5>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport6: gpio@4001f0c0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f0c0 0x20>; + port = <6>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport7: gpio@4001f0e0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f0e0 0x20>; + port = <7>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport8: gpio@4001f100 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x4001f100 0x20>; + port = <8>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + pinctrl: pin-controller@4001F800 { + compatible = "renesas,ra-pinctrl-pfs"; + reg = <0x4001F800 0x3c0>; + status = "okay"; + }; + + sci0: sci@40118000 { + compatible = "renesas,ra-sci"; + reg = <0x40118000 0x100>; + clocks = <&pclka MSTPB 31>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <0>; + status = "disabled"; + }; + }; + + sci1: sci@40118100 { + compatible = "renesas,ra-sci"; + reg = <0x40118100 0x100>; + clocks = <&pclka MSTPB 30>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <1>; + status = "disabled"; + }; + }; + + sci3: sci@40118300 { + compatible = "renesas,ra-sci"; + reg = <0x40118300 0x100>; + clocks = <&pclka MSTPB 38>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <3>; + status = "disabled"; + }; + }; + + sci4: sci@40118400 { + compatible = "renesas,ra-sci"; + reg = <0x40118400 0x100>; + clocks = <&pclka MSTPB 27>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <4>; + status = "disabled"; + }; + }; + + sci5: sci@40118500 { + compatible = "renesas,ra-sci"; + interrupts = <4 1>, <5 1>, <6 1>, <7 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + reg = <0x40118500 0x100>; + clocks = <&pclka MSTPB 26>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <5>; + status = "disabled"; + }; + }; + + sci9: sci@40118900 { + compatible = "renesas,ra-sci"; + interrupts = <24 1>, <25 1>, <26 1>, <27 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + reg = <0x40118900 0x100>; + clocks = <&pclka MSTPB 22>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <9>; + status = "disabled"; + }; + }; + + spi0: spi@4011a000 { + compatible = "renesas,ra-spi"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + interrupts = <28 1>, <29 1>, <30 1>, <31 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; + reg = <0x4011a000 0x100>; + status = "disabled"; + }; + + adc0: adc@40170000 { + compatible = "renesas,ra-adc"; + interrupts = <38 1>; + interrupt-names = "scanend"; + reg = <0x40170000 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + channel-count = <16>; + channel-available-mask = <0x3fe007f>; + status = "disabled"; + }; + + iic0: iic0@4009f000 { + compatible = "renesas,ra-iic"; + channel = <0>; + reg = <0x4009f000 0x100>; + status = "disabled"; + }; + + pwm0: pwm0@40169000 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 31>; + reg = <0x40169000 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm1@40169100 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 30>; + reg = <0x40169100 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm2@40169200 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 29>; + reg = <0x40169200 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40169300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 28>; + reg = <0x40169300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm4: pwm4@40169400 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 27>; + reg = <0x40169400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm5@40169500 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 26>; + reg = <0x40169500 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + canfd_global: canfd_global@400b0000 { + compatible = "renesas,ra-canfd-global"; + interrupts = <40 1>, <41 1>; + interrupt-names = "rxf", "glerr"; + clocks = <&pclkb 0 0>, <&pclka 0 0>; + clock-names = "opclk", "ramclk"; + reg = <0x400b0000 0x2000>; + status = "disabled"; + + canfd0: canfd0 { + compatible = "renesas,ra-canfd"; + channel = <0>; + interrupts = <43 12>, <44 12>, <45 12>; + interrupt-names = "err", "tx", "rx"; + clocks = <&canfdclk MSTPC 27>; + clock-names = "dllclk"; + status = "disabled"; + }; + }; + + option_setting_ofs: option_setting_ofs@100a100 { + compatible = "zephyr,memory-region"; + reg = <0x0100a100 0x18>; + zephyr,memory-region = "OPTION_SETTING_OFS"; + status = "okay"; + }; + + option_setting_sas: option_setting_sas@100a134 { + compatible = "zephyr,memory-region"; + reg = <0x0100a134 0xcc>; + zephyr,memory-region = "OPTION_SETTING_SAS"; + status = "okay"; + }; + + option_setting_s: option_setting_s@100a200 { + compatible = "zephyr,memory-region"; + reg = <0x0100a200 0x100>; + zephyr,memory-region = "OPTION_SETTING_S"; + status = "okay"; + }; + + port_irq0: external-interrupt@40006000 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006000 0x1>; + channel = <0>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq1: external-interrupt@40006001 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006001 0x1>; + channel = <1>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq2: external-interrupt@40006002 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006002 0x1>; + channel = <2>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq3: external-interrupt@40006003 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006003 0x1>; + channel = <3>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq4: external-interrupt@40006004 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006004 0x1>; + channel = <4>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq5: external-interrupt@40006005 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006005 0x1>; + channel = <5>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq6: external-interrupt@40006006 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006006 0x1>; + channel = <6>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq7: external-interrupt@40006007 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006007 0x1>; + channel = <7>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq8: external-interrupt@40006008 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006008 0x1>; + channel = <8>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq9: external-interrupt@40006009 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006009 0x1>; + channel = <9>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq10: external-interrupt@4000600a { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600a 0x1>; + channel = <10>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq11: external-interrupt@4000600b { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600b 0x1>; + channel = <11>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq12: external-interrupt@4000600c { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600c 0x1>; + channel = <12>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq13: external-interrupt@4000600d { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600d 0x1>; + channel = <13>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq14: external-interrupt@4000600e { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600e 0x1>; + channel = <14>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq15: external-interrupt@4000600f { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600f 0x1>; + channel = <15>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + }; + + clocks: clocks { + #address-cells = <1>; + #size-cells = <1>; + + xtal: clock-main-osc { + compatible = "renesas,ra-cgc-external-clock"; + clock-frequency = ; + #clock-cells = <0>; + status = "disabled"; + }; + + hoco: clock-hoco { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + loco: clock-loco { + compatible = "fixed-clock"; + clock-frequency = <32768>; + #clock-cells = <0>; + }; + + moco: clock-moco { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + subclk: clock-subclk { + compatible = "renesas,ra-cgc-subclk"; + clock-frequency = <32768>; + #clock-cells = <0>; + status = "disabled"; + }; + + pll: pll { + compatible = "renesas,ra-cgc-pll"; + #clock-cells = <0>; + + /* PLL */ + clocks = <&xtal>; + div = <1>; + mul = <10 0>; + status = "disabled"; + }; + + pclkblock: pclkblock@40084000 { + compatible = "renesas,ra-cgc-pclk-block"; + reg = <0x40084000 4>, <0x40084004 4>, <0x40084008 4>, + <0x4008400c 4>, <0x40084010 4>; + reg-names = "MSTPA", "MSTPB","MSTPC", + "MSTPD", "MSTPE"; + #clock-cells = <0>; + clocks = <&pll>; + status = "okay"; + + iclk: iclk { + compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <80000000>; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + pclka: pclka { + compatible = "renesas,ra-cgc-pclk"; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkb: pclkb { + compatible = "renesas,ra-cgc-pclk"; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkc: pclkc { + compatible = "renesas,ra-cgc-pclk"; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkd: pclkd { + compatible = "renesas,ra-cgc-pclk"; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + fclk: fclk { + compatible = "renesas,ra-cgc-pclk"; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + clkout: clkout { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + + uclk: uclk { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + + canfdclk: canfdclk { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + + i3cclk: i3cclk { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + + uarta0: uarta0 { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + + uarta1: uarta1 { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <10>; + port-irq11-pins = <11>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq12>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq12"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; + port-irq12-pins = <8>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq13 + &port_irq14>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq13", + "port-irq14"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq13-pins = <6>; + port-irq14-pins = <5>; +}; + +&ioport7 { + port-irqs = <&port_irq11>; + port-irq-names = "port-irq11"; + port-irq11-pins = <8>; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4m1ab3cfp.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m1ab3cfp.dtsi new file mode 100644 index 0000000000000..4c9c5428c412d --- /dev/null +++ b/dts/arm/renesas/ra/ra4/r7fa4m1ab3cfp.dtsi @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(32)>; + }; + + flash-controller@407e0000 { + reg = <0x407e0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x0 DT_SIZE_K(256)>; + }; + }; + + ioport6: gpio@400400c0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x400400c0 0x20>; + port = <6>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport7: gpio@400400e0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x400400e0 0x20>; + port = <7>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport8: gpio@40040100 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x40040100 0x20>; + port = <8>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + sci2: sci2@40070040 { + compatible = "renesas,ra-sci"; + reg = <0x40070040 0x20>; + clocks = <&pclka MSTPB 29>; + status = "disabled"; + + uart { + compatible = "renesas,ra-sci-uart"; + channel = <2>; + status = "disabled"; + }; + }; + + adc@4005c000 { + interrupts = <20 1>; + channel-count = <25>; + channel-available-mask = <0x3ff7fff>; + }; + + port_irq5: external-interrupt@40006005 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006005 0x1>; + channel = <5>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq8: external-interrupt@40006008 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006008 0x1>; + channel = <8>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq10: external-interrupt@4000600a { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600a 0x1>; + channel = <10>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq12: external-interrupt@4000600c { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600c 0x1>; + channel = <12>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-sce5-rng"; + status = "disabled"; + }; + + pwm6: pwm6@40078600 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078600 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm7@40078700 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078700 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + clocks: clocks { + #address-cells = <1>; + #size-cells = <1>; + + xtal: clock-main-osc { + compatible = "renesas,ra-cgc-external-clock"; + clock-frequency = ; + #clock-cells = <0>; + status = "disabled"; + }; + + hoco: clock-hoco { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + moco: clock-moco { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + loco: clock-loco { + compatible = "fixed-clock"; + clock-frequency = <32768>; + #clock-cells = <0>; + }; + + subclk: clock-subclk { + compatible = "renesas,ra-cgc-subclk"; + clock-frequency = <32768>; + #clock-cells = <0>; + status = "disabled"; + }; + + pll: pll { + compatible = "renesas,ra-cgc-pll"; + #clock-cells = <0>; + + clocks = <&xtal>; + div = <2>; + mul = <8 0>; + status = "disabled"; + }; + + pclkblock: pclkblock@40047000 { + compatible = "renesas,ra-cgc-pclk-block"; + reg = <0x40047000 4>, + <0x40047004 4>, + <0x40047008 4>; + reg-names = "MSTPB", "MSTPC", "MSTPD"; + #clock-cells = <0>; + clocks = <&pll>; + status = "okay"; + + iclk: iclk { + compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <48000000>; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + pclka: pclka { + compatible = "renesas,ra-cgc-pclk"; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkb: pclkb { + compatible = "renesas,ra-cgc-pclk"; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkc: pclkc { + compatible = "renesas,ra-cgc-pclk"; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + pclkd: pclkd { + compatible = "renesas,ra-cgc-pclk"; + div = <1>; + #clock-cells = <2>; + status = "okay"; + }; + + fclk: fclk { + compatible = "renesas,ra-cgc-pclk"; + div = <2>; + #clock-cells = <2>; + status = "okay"; + }; + + clkout: clkout { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + + uclk: uclk { + compatible = "renesas,ra-cgc-pclk"; + #clock-cells = <2>; + status = "disabled"; + }; + }; + }; +}; + +&ioport0 { + port-irqs = <&port_irq2 &port_irq3 &port_irq6 + &port_irq7 &port_irq10 &port_irq15>; + port-irq-names = "port-irq2", + "port-irq3", + "port-irq6", + "port-irq7", + "port-irq10", + "port-irq15"; + port-irq2-pins = <2>; + port-irq3-pins = <4>; + port-irq6-pins = <0>; + port-irq7-pins = <1 15>; + port-irq10-pins = <5>; + port-irq15-pins = <11>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 &port_irq8 + &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq14>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq14"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5>; +}; + +&pwm2 { + clocks = <&pclkd MSTPD 6>; +}; + +&pwm3 { + clocks = <&pclkd MSTPD 6>; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4m2ad3cfp.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m2ad3cfp.dtsi index 37b1961111c73..9c48c70b544d4 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m2ad3cfp.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m2ad3cfp.dtsi @@ -10,12 +10,21 @@ / { soc { flash-controller@407e0000 { - reg = <0x407e0000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; + block-32kb-linear-end = <21>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_K(512)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(8)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; }; diff --git a/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi index 2adf6ee248432..a6dc48199e19a 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi @@ -6,9 +6,12 @@ #include #include +#include /delete-node/ &spi1; +/delete-node/ &adc1; + / { soc { sram0: memory@20000000 { @@ -91,6 +94,56 @@ status = "disabled"; }; }; + + adc@40170000 { + channel-count = <13>; + channel-available-mask = <0x139ff>; + }; + + pwm2: pwm2@40169200 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 29>; + reg = <0x40169200 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40169300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 28>; + reg = <0x40169300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm6@40169600 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 25>; + reg = <0x40169600 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm7@40169700 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 24>; + reg = <0x40169700 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-sce9-rng"; + status = "disabled"; + }; }; clocks: clocks { @@ -162,6 +215,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <100000000>; div = <2>; #clock-cells = <2>; status = "okay"; @@ -216,3 +270,110 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq14>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq14"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5>; +}; + +&ioport7 { + port-irqs = <&port_irq11>; + port-irq-names = "port-irq11"; + port-irq11-pins = <8>; +}; + +&dac_global { + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4m3af3cfb.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m3af3cfb.dtsi index 7d0d8b908d51c..642649e1a210d 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m3af3cfb.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m3af3cfb.dtsi @@ -10,12 +10,21 @@ / { soc { flash-controller@407e0000 { - reg = <0x407e0000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; + block-32kb-linear-end = <37>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_M(1)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(8)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; }; diff --git a/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi index 7cb371f9157e9..6ed9030387f47 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi @@ -6,6 +6,7 @@ #include #include +#include /delete-node/ &spi1; @@ -101,6 +102,61 @@ status = "disabled"; }; }; + + adc@40170000 { + channel-count = <12>; + channel-available-mask = <0x33ff>; + }; + + adc@40170200 { + channel-count = <10>; + channel-available-mask = <0x7f0007>; + }; + + pwm2: pwm2@40169200 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 29>; + reg = <0x40169200 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40169300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 28>; + reg = <0x40169300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm6@40169600 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 25>; + reg = <0x40169600 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm7@40169700 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 24>; + reg = <0x40169700 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-sce9-rng"; + status = "disabled"; + }; }; clocks: clocks { @@ -170,6 +226,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <100000000>; div = <2>; #clock-cells = <2>; status = "okay"; @@ -224,3 +281,115 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <9 15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <3 13>; + port-irq3-pins = <2 12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq14 + &port_irq15>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq14", + "port-irq15"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5 12>; + port-irq15-pins = <6 11>; +}; + +&ioport7 { + port-irqs = <&port_irq10 &port_irq11>; + port-irq-names = "port-irq10", + "port-irq11"; + port-irq10-pins = <9>; + port-irq11-pins = <8>; +}; + +&dac_global { + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi b/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi index cc6d4dbe9009b..dbecb5edb786f 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi @@ -6,6 +6,7 @@ #include #include +#include / { soc { @@ -35,10 +36,25 @@ }; }; - spi1: spi@40072100 { - compatible = "renesas,ra-spi"; - interrupts = <28 1>, <29 1>, <30 1>, <31 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; + trng: trng { + compatible = "renesas,ra-sce5-rng"; + status = "disabled"; + }; + + adc@4005c000 { + interrupts = <20 1>; + channel-count = <8>; + channel-available-mask = <0x1a0670>; + }; + + pwm8: pwm8@40078800 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078800 0x100>; + #pwm-cells = <3>; + status = "disabled"; }; }; @@ -101,6 +117,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <48000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -156,3 +173,68 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq3 &port_irq7 &port_irq14 + &port_irq15>; + port-irq-names = "port-irq3", + "port-irq7", + "port-irq14", + "port-irq15"; + port-irq3-pins = <4>; + port-irq7-pins = <15>; + port-irq14-pins = <10>; + port-irq15-pins = <11>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; +}; + +&ioport4 { + port-irqs = <&port_irq4 &port_irq6 &port_irq9>; + port-irq-names = "port-irq4", + "port-irq6", + "port-irq9"; + port-irq4-pins = <2>; + port-irq6-pins = <9>; + port-irq9-pins = <14>; +}; + +&ioport5 { + port-irqs = <&port_irq11>; + port-irq-names = "port-irq11"; + port-irq11-pins = <1>; +}; + +&pwm2 { + clocks = <&pclkd MSTPD 5>; +}; + +&pwm3 { + clocks = <&pclkd MSTPD 5>; +}; diff --git a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi index 32e30013960ae..86669aa57dc06 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #include #include #include +#include #include / { @@ -37,10 +38,13 @@ status = "okay"; }; - flash-controller@407e0000 { + flash: flash-controller@407e0000 { + compatible = "renesas,ra-flash-hp-controller"; reg = <0x407e0000 0x10000>; #address-cells = <1>; #size-cells = <1>; + interrupts = <49 1>, <50 1>; + interrupt-names = "frdyi", "fiferr"; }; ioport0: gpio@40080000 { @@ -125,7 +129,7 @@ sci9: sci9@40118900 { compatible = "renesas,ra-sci"; - interrupts = <36 1>, <37 1>, <38 1>, <39 1>; + interrupts = <24 1>, <25 1>, <26 1>, <27 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40118900 0x100>; clocks = <&pclka MSTPB 22>; @@ -247,6 +251,77 @@ }; }; + adc0: adc@40170000 { + compatible = "renesas,ra-adc"; + interrupts = <38 1>; + interrupt-names = "scanend"; + reg = <0x40170000 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + status = "disabled"; + }; + + adc1: adc@40170200 { + compatible = "renesas,ra-adc"; + interrupts = <39 1>; + interrupt-names = "scanend"; + reg = <0x40170200 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + status = "disabled"; + }; + + dac_global: dac_global@40171000 { + compatible = "renesas,ra-dac-global"; + reg = <0x40171000 0x10c4>; + #address-cells = <1>; + #size-cells = <0>; + + dac0: dac@0 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <0>; + status = "disabled"; + }; + + dac1: dac@1 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <1>; + status = "disabled"; + }; + }; + + iic0: iic0@4009f000 { + compatible = "renesas,ra-iic"; + channel = <0>; + reg = <0x4009f000 0x100>; + status = "disabled"; + }; + + iic1: iic1@4009f100 { + compatible = "renesas,ra-iic"; + channel = <1>; + reg = <0x4009f100 0x100>; + status = "disabled"; + }; + + usbfs: usbfs@40090000 { + compatible = "renesas,ra-usbfs"; + reg = <0x40090000 0x2000>; + interrupts = <32 1>, <33 1>; + interrupt-names = "usbfs-i", "usbfs-r"; + num-bidir-endpoints = <10>; + phys = <&usbfs_phy>; + phys-clock = <&uclk>; + status = "disabled"; + + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + option_setting_ofs: option_setting_ofs@100a100 { compatible = "zephyr,memory-region"; reg = <0x0100a100 0x18>; @@ -267,6 +342,195 @@ zephyr,memory-region = "OPTION_SETTING_S"; status = "okay"; }; + + port_irq0: external-interrupt@40006000 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006000 0x1>; + channel = <0>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq1: external-interrupt@40006001 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006001 0x1>; + channel = <1>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq2: external-interrupt@40006002 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006002 0x1>; + channel = <2>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq3: external-interrupt@40006003 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006003 0x1>; + channel = <3>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq4: external-interrupt@40006004 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006004 0x1>; + channel = <4>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq5: external-interrupt@40006005 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006005 0x1>; + channel = <5>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq6: external-interrupt@40006006 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006006 0x1>; + channel = <6>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq7: external-interrupt@40006007 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006007 0x1>; + channel = <7>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq8: external-interrupt@40006008 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006008 0x1>; + channel = <8>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq9: external-interrupt@40006009 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006009 0x1>; + channel = <9>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq10: external-interrupt@4000600a { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600a 0x1>; + channel = <10>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq11: external-interrupt@4000600b { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600b 0x1>; + channel = <11>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq12: external-interrupt@4000600c { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600c 0x1>; + channel = <12>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq13: external-interrupt@4000600d { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600d 0x1>; + channel = <13>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq14: external-interrupt@4000600e { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600e 0x1>; + channel = <14>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq15: external-interrupt@4000600f { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600f 0x1>; + channel = <15>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + pwm0: pwm0@40169000 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 31>; + reg = <0x40169000 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm1@40169100 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 30>; + reg = <0x40169100 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm4: pwm4@40169400 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 27>; + reg = <0x40169400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm5@40169500 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 26>; + reg = <0x40169500 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + usbfs_phy: usbfs-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; }; }; diff --git a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi index ab52b5d6e95cc..1be403e71df4f 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include / { @@ -148,8 +149,6 @@ sci9: sci9@40070120 { compatible = "renesas,ra-sci"; - interrupts = <36 1>, <37 1>, <38 1>, <39 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40070120 0x20>; clocks = <&pclka MSTPB 22>; status = "disabled"; @@ -174,7 +173,7 @@ #address-cells = <1>; #size-cells = <0>; channel = <1>; - interrupts = <32 1>, <33 1>, <34 1>, <35 1>; + interrupts = <28 1>, <29 1>, <30 1>, <31 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40072100 0x100>; status = "disabled"; @@ -210,12 +209,211 @@ }; }; + adc0: adc@4005c000 { + compatible = "renesas,ra-adc"; + interrupt-names = "scanend"; + reg = <0x4005c000 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + status = "disabled"; + }; + + iic0: iic0@40053000 { + compatible = "renesas,ra-iic"; + channel = <0>; + reg = <0x40053000 0x100>; + status = "disabled"; + }; + + iic1: iic1@40053100 { + compatible = "renesas,ra-iic"; + channel = <1>; + reg = <0x40053100 0x100>; + status = "disabled"; + }; + + usbfs: usbfs@40090000 { + compatible = "renesas,ra-usbfs"; + reg = <0x40090000 0x2000>; + num-bidir-endpoints = <10>; + phys = <&usbfs_phy>; + phys-clock = <&uclk>; + status = "disabled"; + + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + id_code: id_code@1010018 { compatible = "zephyr,memory-region"; reg = <0x01010018 0x20>; zephyr,memory-region = "ID_CODE"; status = "okay"; }; + + port_irq0: external-interrupt@40006000 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006000 0x1>; + channel = <0>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq1: external-interrupt@40006001 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006001 0x1>; + channel = <1>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq2: external-interrupt@40006002 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006002 0x1>; + channel = <2>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq3: external-interrupt@40006003 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006003 0x1>; + channel = <3>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq4: external-interrupt@40006004 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006004 0x1>; + channel = <4>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq6: external-interrupt@40006006 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006006 0x1>; + channel = <6>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq7: external-interrupt@40006007 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006007 0x1>; + channel = <7>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq9: external-interrupt@40006009 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006009 0x1>; + channel = <9>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq11: external-interrupt@4000600b { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600b 0x1>; + channel = <11>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq14: external-interrupt@4000600e { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600e 0x1>; + channel = <14>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq15: external-interrupt@4000600f { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600f 0x1>; + channel = <15>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + pwm0: pwm0@40078000 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078000 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm1@40078100 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078100 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm2@40078200 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + reg = <0x40078200 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40078300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + reg = <0x40078300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm4: pwm4@40078400 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm5@40078500 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078500 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + usbfs_phy: usbfs-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; }; }; diff --git a/dts/arm/renesas/ra/ra6/r7fa6e10f2cfp.dtsi b/dts/arm/renesas/ra/ra6/r7fa6e10f2cfp.dtsi index f8a45b5b0e251..d21af8002e8df 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6e10f2cfp.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6e10f2cfp.dtsi @@ -9,13 +9,24 @@ / { soc { flash-controller@407e0000 { - reg = <0x407e0000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - + reserved-area-num = <48>; + block-32kb-linear-end = <37>; + block-32kb-dual-low-end = <21>; + block-32kb-dual-high-end = <91>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_M(1)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(8)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; }; diff --git a/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi b/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi index d8d31ceb55af1..3332ce1d6d7d9 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi @@ -1,11 +1,15 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include + +/delete-node/ &adc1; +/delete-node/ &dac1; / { soc { @@ -89,6 +93,36 @@ status = "disabled"; }; }; + + adc@40170000 { + channel-count = <11>; + channel-available-mask = <0x31ff>; + }; + + pwm6: pwm6@40169600 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 25>; + reg = <0x40169600 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm7@40169700 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 24>; + reg = <0x40169700 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-sce9-rng"; + status = "disabled"; + }; }; clocks: clocks { @@ -160,6 +194,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <200000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -214,3 +249,110 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq14>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq14"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5>; +}; + +&ioport7 { + port-irqs = <&port_irq11>; + port-irq-names = "port-irq11"; + port-irq11-pins = <8>; +}; + +&dac_global { + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra6/r7fa6e2bb3cfm.dtsi b/dts/arm/renesas/ra/ra6/r7fa6e2bb3cfm.dtsi index 8ccb1e3bb3a04..e45ebadd6c96c 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6e2bb3cfm.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6e2bb3cfm.dtsi @@ -9,13 +9,21 @@ / { soc { flash-controller@407e0000 { - reg = <0x407e0000 0x10000>; - #address-cells = <1>; - #size-cells = <1>; - + block-32kb-linear-end = <13>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_K(256)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(4)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; }; diff --git a/dts/arm/renesas/ra/ra6/r7fa6e2bx.dtsi b/dts/arm/renesas/ra/ra6/r7fa6e2bx.dtsi index d61096eb2aca0..4998e1034b1f8 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6e2bx.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6e2bx.dtsi @@ -6,6 +6,7 @@ #include #include +#include /delete-node/ &agt0; /delete-node/ &agt1; @@ -13,6 +14,9 @@ /delete-node/ &agt3; /delete-node/ &agt4; /delete-node/ &agt5; +/delete-node/ &adc1; +/delete-node/ &usbfs; +/delete-node/ &usbfs_phy; / { soc { @@ -31,12 +35,63 @@ status = "disabled"; }; + adc@40170000 { + channel-count = <12>; + channel-available-mask = <0x139f7>; + }; + id_code: id_code@100a120 { compatible = "zephyr,memory-region"; reg = <0x0100a120 0x10>; zephyr,memory-region = "ID_CODE"; status = "okay"; }; + + canfd_global: canfd_global@400b0000 { + compatible = "renesas,ra-canfd-global"; + interrupts = <40 1>, <41 1>; + interrupt-names = "rxf", "glerr"; + clocks = <&pclkb 0 0>, <&pclka 0 0>; + clock-names = "opclk", "ramclk"; + dll-max-freq = ; + reg = <0x400b0000 0x2000>; + status = "disabled"; + + canfd0: canfd0 { + compatible = "renesas,ra-canfd"; + channel = <0>; + interrupts = <43 12>, <44 12>, <45 12>; + interrupt-names = "err", "tx", "rx"; + clocks = <&canfdclk MSTPC 27>; + clock-names = "dllclk"; + status = "disabled"; + }; + }; + + pwm0: pwm0@40169000 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 31>; + reg = <0x40169000 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40169300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 28>; + reg = <0x40169300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-trng"; + status = "disabled"; + }; }; clocks: clocks { @@ -98,6 +153,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <200000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -170,3 +226,90 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq14>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq14"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq14-pins = <3>; +}; + +&ioport8 { + port-irqs = <&port_irq11>; + port-irq-names = "port-irq11"; + port-irq11-pins = <14>; +}; + +&dac_global { + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m1ad3cfp.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m1ad3cfp.dtsi index 2415350363beb..c04daf4a985a0 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m1ad3cfp.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m1ad3cfp.dtsi @@ -15,15 +15,38 @@ }; flash-controller@407e0000 { - reg = <0x407e0000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - + block-32kb-linear-end = <21>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_K(512)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@40100000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x40100000 DT_SIZE_K(8)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; + + trng: trng { + compatible = "renesas,ra-sce7-rng"; + status = "disabled"; + }; + + adc@4005c000 { + channel-count = <11>; + channel-available-mask = <0x1700ef>; + }; + + adc@4005c200 { + channel-count = <8>; + channel-available-mask = <0x300e7>; + }; }; clocks: clocks { @@ -85,6 +108,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <120000000>; div = <2>; #clock-cells = <2>; status = "okay"; @@ -153,3 +177,104 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <13>; + port-irq3-pins = <12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12>; + port-irq-names = "port-irq11", + "port-irq12"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; +}; + +&ioport7 { + port-irqs = <&port_irq11>; + port-irq-names = "port-irq11"; + port-irq11-pins = <8>; +}; + +&dac_global { + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m2af3cfb.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m2af3cfb.dtsi index 4a3320b2bbb9a..577927a342ea6 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m2af3cfb.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m2af3cfb.dtsi @@ -9,19 +9,27 @@ / { soc { flash-controller@407e0000 { - compatible = "renesas,ra6-flash-controller"; - reg = <0x407e0000 0x10000>; - #address-cells = <1>; - #size-cells = <1>; - interrupts = <4 1>, <5 1>; - interrupt-names = "frdyi", "fiferr"; - + block-32kb-linear-end = <37>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_M(1)>; write-block-size = <128>; erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@40100000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x40100000 DT_SIZE_K(32)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; + + trng: trng { + compatible = "renesas,ra-sce7-rng"; + status = "disabled"; + }; }; }; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi index b1f93eed62e40..ad78df1ddf250 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi @@ -6,6 +6,7 @@ #include #include +#include / { soc { @@ -16,8 +17,6 @@ sci5: sci5@400700a0 { compatible = "renesas,ra-sci"; - interrupts = <20 1>, <21 1>, <22 1>, <23 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700a0 0x20>; clocks = <&pclka MSTPB 26>; status = "disabled"; @@ -30,8 +29,6 @@ sci6: sci6@400700c0 { compatible = "renesas,ra-sci"; - interrupts = <24 1>, <25 1>, <26 1>, <27 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700c0 0x20>; clocks = <&pclka MSTPB 25>; status = "disabled"; @@ -44,7 +41,7 @@ sci7: sci7@400700e0 { compatible = "renesas,ra-sci"; - interrupts = <28 1>, <29 1>, <30 1>, <31 1>; + interrupts = <16 1>, <17 1>, <18 1>, <19 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700e0 0x20>; clocks = <&pclka MSTPB 24>; @@ -62,6 +59,26 @@ reg = <0x40053200 0x100>; status = "disabled"; }; + + adc@4005c000 { + channel-count = <13>; + channel-available-mask = <0x1f00ff>; + }; + + adc@4005c200 { + channel-count = <9>; + channel-available-mask = <0x700e7>; + }; + + pwm13: pwm13@40078d00 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078d00 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; }; clocks: clocks { @@ -123,6 +140,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <120000000>; div = <2>; #clock-cells = <2>; status = "okay"; @@ -191,3 +209,111 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <9 15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <3 13>; + port-irq3-pins = <2 12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq14 + &port_irq15>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq14", + "port-irq15"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5 12>; + port-irq15-pins = <6 11>; +}; + +&ioport7 { + port-irqs = <&port_irq10 &port_irq11>; + port-irq-names = "port-irq10", + "port-irq11"; + port-irq10-pins = <9>; + port-irq11-pins = <8>; +}; + +&dac_global { + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m3ah3cfc.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m3ah3cfc.dtsi index f6ed09902d460..f1eb419234aa5 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m3ah3cfc.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m3ah3cfc.dtsi @@ -9,13 +9,27 @@ / { soc { flash-controller@407e0000 { - reg = <0x407e0000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; + block-32kb-linear-end = <69>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_M(2)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; }; + + flash1: flash@40100000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x40100000 DT_SIZE_K(64)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; + }; + }; + + trng: trng { + compatible = "renesas,ra-sce7-rng"; + status = "disabled"; }; }; }; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi index 1dbb4385519c6..f9dd42e405c89 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi @@ -6,6 +6,7 @@ #include #include +#include / { soc { @@ -102,6 +103,41 @@ reg = <0x40053200 0x100>; status = "disabled"; }; + + usbhs: usbhs@40060000 { + compatible = "renesas,ra-usbhs"; + reg = <0x40060000 0x2000>; + interrupts = <54 12>; + interrupt-names = "usbhs-ir"; + num-bidir-endpoints = <10>; + phys = <&usbhs_phy>; + phys-clock = <&uclk>; + status = "disabled"; + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + + adc@4005c000 { + channel-count = <13>; + channel-available-mask = <0x1f00ff>; + }; + + adc@4005c200 { + channel-count = <11>; + channel-available-mask = <0xf00ef>; + }; + + pwm13: pwm13@40078d00 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078d00 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; }; clocks: clocks { @@ -163,6 +199,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <120000000>; div = <2>; #clock-cells = <2>; status = "okay"; @@ -230,4 +267,124 @@ }; }; }; + + usbhs_phy: usbhs-phy { + compatible = "renesas,ra-usbphyc"; + #phy-cells = <0>; + }; +}; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13 &port_irq14>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13", + "port-irq14"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <9 15>; + port-irq14-pins = <10>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <3 13>; + port-irq3-pins = <2 12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq14 + &port_irq15>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq14", + "port-irq15"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5 12>; + port-irq15-pins = <6 11>; +}; + +&ioport7 { + port-irqs = <&port_irq7 &port_irq8 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq7", + "port-irq8", + "port-irq10", + "port-irq11"; + port-irq7-pins = <6>; + port-irq8-pins = <7>; + port-irq10-pins = <9>; + port-irq11-pins = <8>; +}; + +&dac_global { + has-output-amplifier; }; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m4af3cfb.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m4af3cfb.dtsi index 50810cdb5f1d5..eea2341f18dd1 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m4af3cfb.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m4af3cfb.dtsi @@ -9,44 +9,25 @@ / { soc { flash-controller@407e0000 { - reg = <0x407e0000 0x10000>; - #address-cells = <1>; - #size-cells = <1>; - + reserved-area-num = <48>; + block-32kb-linear-end = <37>; + block-32kb-dual-low-end = <21>; + block-32kb-dual-high-end = <91>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_M(1)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; }; - }; - - ioport6: gpio@400800c0 { - compatible = "renesas,ra-gpio-ioport"; - reg = <0x400800c0 0x20>; - port = <6>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <16>; - status = "disabled"; - }; - ioport7: gpio@400800e0 { - compatible = "renesas,ra-gpio-ioport"; - reg = <0x400800e0 0x20>; - port = <7>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <16>; - status = "disabled"; - }; - - ioport8: gpio@40080100 { - compatible = "renesas,ra-gpio-ioport"; - reg = <0x40080100 0x20>; - port = <8>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <16>; - status = "disabled"; + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(8)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; + }; }; }; }; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi index da8000713620f..1b568b5c5a8a3 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi @@ -6,6 +6,7 @@ #include #include +#include / { soc { @@ -125,6 +126,111 @@ status = "disabled"; }; }; + + adc@40170000 { + channel-count = <12>; + channel-available-mask = <0x33ff>; + }; + + adc@40170200 { + channel-count = <10>; + channel-available-mask = <0x7f0007>; + }; + + ioport6: gpio@400800c0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x400800c0 0x20>; + port = <6>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport7: gpio@400800e0 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x400800e0 0x20>; + port = <7>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + ioport8: gpio@40080100 { + compatible = "renesas,ra-gpio-ioport"; + reg = <0x40080100 0x20>; + port = <8>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + pwm0: pwm0@40169000 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 31>; + reg = <0x40169000 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40169300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 28>; + reg = <0x40169300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm6@40169600 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 25>; + reg = <0x40169600 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm7@40169700 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 24>; + reg = <0x40169700 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm8: pwm8@40169800 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 23>; + reg = <0x40169800 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm9: pwm9@40169900 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 22>; + reg = <0x40169900 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-sce9-rng"; + status = "disabled"; + }; }; clocks: clocks { @@ -196,6 +302,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <200000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -269,3 +376,115 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <9 15>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <3 13>; + port-irq3-pins = <2 12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq14 + &port_irq15>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq14", + "port-irq15"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5 12>; + port-irq15-pins = <6 11>; +}; + +&ioport7 { + port-irqs = <&port_irq10 &port_irq11>; + port-irq-names = "port-irq10", + "port-irq11"; + port-irq10-pins = <9>; + port-irq11-pins = <8>; +}; + +&dac_global { + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m5bh3cfc.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m5bh3cfc.dtsi index cf75071f3ad4e..63e357cda83bb 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m5bh3cfc.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m5bh3cfc.dtsi @@ -9,12 +9,24 @@ / { soc { flash-controller@407e0000 { - reg = <0x407e0000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; + reserved-area-num = <32>; + block-32kb-linear-end = <69>; + block-32kb-dual-low-end = <37>; + block-32kb-dual-high-end = <107>; flash0: flash@0 { - compatible = "soc-nv-flash"; + compatible = "renesas,ra-nv-flash"; reg = <0x0 DT_SIZE_M(2)>; + write-block-size = <128>; + erase-block-size = <8192>; + renesas,programming-enable; + }; + + flash1: flash@8000000 { + compatible = "renesas,ra-nv-flash"; + reg = <0x8000000 DT_SIZE_K(8)>; + write-block-size = <4>; + erase-block-size = <64>; + renesas,programming-enable; }; }; }; diff --git a/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi index 742d8cfc23468..d889317fd74ca 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi @@ -6,6 +6,7 @@ #include #include +#include / { soc { @@ -192,6 +193,96 @@ reg = <0x4009f200 0x100>; status = "disabled"; }; + + usbhs: usbhs@40111000 { + compatible = "renesas,ra-usbhs"; + reg = <0x40111000 0x2000>; + interrupts = <54 12>; + interrupt-names = "usbhs-ir"; + num-bidir-endpoints = <10>; + phys = <&usbhs_phy>; + phys-clock = <&uclk>, <&u60clk>; + status = "disabled"; + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + + adc@40170000 { + channel-count = <13>; + channel-available-mask = <0x37ff>; + }; + + adc@40170200 { + channel-count = <16>; + channel-available-mask = <0x1fff0007>; + }; + + pwm0: pwm0@40169000 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 31>; + reg = <0x40169000 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40169300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 28>; + reg = <0x40169300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm6@40169600 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 25>; + reg = <0x40169600 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm7@40169700 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 24>; + reg = <0x40169700 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm8: pwm8@40169800 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 23>; + reg = <0x40169800 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm9: pwm9@40169900 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 22>; + reg = <0x40169900 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + trng: trng { + compatible = "renesas,ra-sce9-rng"; + status = "disabled"; + }; }; clocks: clocks { @@ -263,6 +354,7 @@ iclk: iclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <200000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -353,4 +445,170 @@ }; }; }; + + usbhs_phy: usbhs-phy { + compatible = "renesas,ra-usbphyc"; + #phy-cells = <0>; + }; +}; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13 &port_irq14>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13", + "port-irq14"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <9 15>; + port-irq14-pins = <10>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; + port-irq3-pins = <10>; + port-irq4-pins = <11>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <3 13>; + port-irq3-pins = <2 12>; +}; + +&ioport3 { + port-irqs = <&port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq11 &port_irq12 &port_irq14 + &port_irq15>; + port-irq-names = "port-irq11", + "port-irq12", + "port-irq14", + "port-irq15"; + port-irq11-pins = <1>; + port-irq12-pins = <2>; + port-irq14-pins = <5 12>; + port-irq15-pins = <6 11>; +}; + +&ioport6 { + port-irqs = <&port_irq7>; + port-irq-names = "port-irq7"; + port-irq7-pins = <15>; +}; + +&ioport7 { + port-irqs = <&port_irq7 &port_irq8 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq7", + "port-irq8", + "port-irq10", + "port-irq11"; + port-irq7-pins = <6>; + port-irq8-pins = <7>; + port-irq10-pins = <9>; + port-irq11-pins = <8>; +}; + +&ioport8 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <4>; + port-irq2-pins = <3>; + port-irq3-pins = <2>; +}; + +&ioport9 { + port-irqs = <&port_irq8 &port_irq9 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11"; + port-irq8-pins = <5>; + port-irq9-pins = <6>; + port-irq10-pins = <7>; + port-irq11-pins = <8>; +}; + +&ioporta { + port-irqs = <&port_irq4 &port_irq5 &port_irq6>; + port-irq-names = "port-irq4", + "port-irq5", + "port-irq6"; + port-irq4-pins = <10>; + port-irq5-pins = <9>; + port-irq6-pins = <8>; +}; + +&dac_global { + has-output-amplifier; }; diff --git a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi index 2b94dcb4ff93d..aaf1020a755c3 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include #include #include +#include #include / { @@ -120,7 +121,7 @@ sci9: sci9@40118900 { compatible = "renesas,ra-sci"; - interrupts = <36 1>, <37 1>, <38 1>, <39 1>; + interrupts = <24 1>, <25 1>, <26 1>, <27 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40118900 0x100>; clocks = <&pclka MSTPB 22>; @@ -258,6 +259,63 @@ }; }; + adc0: adc@40170000 { + compatible = "renesas,ra-adc"; + interrupts = <38 1>; + interrupt-names = "scanend"; + reg = <0x40170000 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + status = "disabled"; + }; + + adc1: adc@40170200 { + compatible = "renesas,ra-adc"; + interrupts = <39 1>; + interrupt-names = "scanend"; + reg = <0x40170200 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + status = "disabled"; + }; + + dac_global: dac_global@40171000 { + compatible = "renesas,ra-dac-global"; + reg = <0x40171000 0x10c4>; + #address-cells = <1>; + #size-cells = <0>; + + dac0: dac@0 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <0>; + status = "disabled"; + }; + + dac1: dac@1 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <1>; + status = "disabled"; + }; + }; + + usbfs: usbfs@40090000 { + compatible = "renesas,ra-usbfs"; + reg = <0x40090000 0x2000>; + interrupts = <55 12>, <56 12>; + interrupt-names = "usbfs-i", "usbfs-r"; + num-bidir-endpoints = <10>; + phys = <&usbfs_phy>; + phys-clock = <&uclk>; + status = "disabled"; + + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + option_setting_ofs: option_setting_ofs@100a100 { compatible = "zephyr,memory-region"; reg = <0x0100a100 0x18>; @@ -265,6 +323,15 @@ status = "okay"; }; + flash: flash-controller@407e0000 { + compatible = "renesas,ra-flash-hp-controller"; + reg = <0x407e0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = <49 1>, <50 1>; + interrupt-names = "frdyi", "fiferr"; + }; + option_setting_sas: option_setting_sas@100a134 { compatible = "zephyr,memory-region"; reg = <0x0100a134 0xcc>; @@ -278,6 +345,195 @@ zephyr,memory-region = "OPTION_SETTING_S"; status = "okay"; }; + + port_irq0: external-interrupt@40006000 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006000 0x1>; + channel = <0>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq1: external-interrupt@40006001 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006001 0x1>; + channel = <1>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq2: external-interrupt@40006002 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006002 0x1>; + channel = <2>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq3: external-interrupt@40006003 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006003 0x1>; + channel = <3>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq4: external-interrupt@40006004 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006004 0x1>; + channel = <4>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq5: external-interrupt@40006005 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006005 0x1>; + channel = <5>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq6: external-interrupt@40006006 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006006 0x1>; + channel = <6>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq7: external-interrupt@40006007 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006007 0x1>; + channel = <7>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq8: external-interrupt@40006008 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006008 0x1>; + channel = <8>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq9: external-interrupt@40006009 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006009 0x1>; + channel = <9>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq10: external-interrupt@4000600a { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600a 0x1>; + channel = <10>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq11: external-interrupt@4000600b { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600b 0x1>; + channel = <11>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq12: external-interrupt@4000600c { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600c 0x1>; + channel = <12>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq13: external-interrupt@4000600d { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600d 0x1>; + channel = <13>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq14: external-interrupt@4000600e { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600e 0x1>; + channel = <14>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq15: external-interrupt@4000600f { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600f 0x1>; + channel = <15>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + pwm1: pwm1@40169100 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 30>; + reg = <0x40169100 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm2@40169200 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 29>; + reg = <0x40169200 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm4: pwm4@40169400 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 27>; + reg = <0x40169400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm5@40169500 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPE 26>; + reg = <0x40169500 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + usbfs_phy: usbfs-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; }; }; diff --git a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi index c671f77a536b9..b388b28c7ceba 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include #include #include +#include #include / { @@ -139,8 +140,6 @@ sci1: sci1@40070020 { compatible = "renesas,ra-sci"; - interrupts = <4 1>, <5 1>, <6 1>, <7 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40070020 0x20>; clocks = <&pclka MSTPB 30>; status = "disabled"; @@ -153,8 +152,6 @@ sci2: sci2@40070040 { compatible = "renesas,ra-sci"; - interrupts = <8 1>, <9 1>, <10 1>, <11 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40070040 0x20>; clocks = <&pclka MSTPB 29>; status = "disabled"; @@ -167,8 +164,6 @@ sci3: sci3@40070060 { compatible = "renesas,ra-sci"; - interrupts = <12 1>, <13 1>, <14 1>, <15 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40070060 0x20>; clocks = <&pclka MSTPB 27>; status = "disabled"; @@ -181,8 +176,6 @@ sci4: sci4@40070080 { compatible = "renesas,ra-sci"; - interrupts = <16 1>, <17 1>, <18 1>, <19 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40070080 0x20>; clocks = <&pclka MSTPB 26>; status = "disabled"; @@ -195,7 +188,7 @@ sci8: sci8@40070100 { compatible = "renesas,ra-sci"; - interrupts = <32 1>, <33 1>, <34 1>, <35 1>; + interrupts = <20 1>, <21 1>, <22 1>, <23 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40070100 0x20>; clocks = <&pclka MSTPB 23>; @@ -209,7 +202,7 @@ sci9: sci9@40070120 { compatible = "renesas,ra-sci"; - interrupts = <36 1>, <37 1>, <38 1>, <39 1>; + interrupts = <24 1>, <25 1>, <26 1>, <27 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40070120 0x20>; clocks = <&pclka MSTPB 22>; @@ -240,7 +233,7 @@ #address-cells = <1>; #size-cells = <0>; channel = <0>; - interrupts = <40 1>, <41 1>, <42 1>, <43 1>; + interrupts = <28 1>, <29 1>, <30 1>, <31 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40072000 0x100>; status = "disabled"; @@ -251,8 +244,6 @@ #address-cells = <1>; #size-cells = <0>; channel = <1>; - interrupts = <44 1>, <45 1>, <46 1>, <47 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x40072100 0x100>; status = "disabled"; }; @@ -287,12 +278,357 @@ }; }; + adc0: adc@4005c000 { + compatible = "renesas,ra-adc"; + interrupts = <38 1>; + interrupt-names = "scanend"; + reg = <0x4005c000 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + status = "disabled"; + }; + + adc1: adc@4005c200 { + compatible = "renesas,ra-adc"; + interrupts = <39 1>; + interrupt-names = "scanend"; + reg = <0x4005c200 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + status = "disabled"; + }; + + dac_global: dac_global@4005e000 { + compatible = "renesas,ra-dac-global"; + reg = <0x4005e000 0x10c4>; + #address-cells = <1>; + #size-cells = <0>; + + dac0: dac@0 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <0>; + status = "disabled"; + }; + + dac1: dac@1 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <1>; + status = "disabled"; + }; + }; + + usbfs: usbfs@40090000 { + compatible = "renesas,ra-usbfs"; + reg = <0x40090000 0x2000>; + interrupts = <55 12>, <56 12>; + interrupt-names = "usbfs-i", "usbfs-r"; + num-bidir-endpoints = <10>; + phys = <&usbfs_phy>; + phys-clock = <&uclk>; + status = "disabled"; + + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + id_code: id_code@100a150 { compatible = "zephyr,memory-region"; reg = <0x0100a150 0x10>; zephyr,memory-region = "ID_CODE"; status = "okay"; }; + + port_irq0: external-interrupt@40006000 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006000 0x1>; + channel = <0>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq1: external-interrupt@40006001 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006001 0x1>; + channel = <1>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq2: external-interrupt@40006002 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006002 0x1>; + channel = <2>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq3: external-interrupt@40006003 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006003 0x1>; + channel = <3>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq4: external-interrupt@40006004 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006004 0x1>; + channel = <4>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq5: external-interrupt@40006005 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006005 0x1>; + channel = <5>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq6: external-interrupt@40006006 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006006 0x1>; + channel = <6>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq7: external-interrupt@40006007 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006007 0x1>; + channel = <7>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq8: external-interrupt@40006008 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006008 0x1>; + channel = <8>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq9: external-interrupt@40006009 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006009 0x1>; + channel = <9>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq10: external-interrupt@4000600a { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600a 0x1>; + channel = <10>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq11: external-interrupt@4000600b { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600b 0x1>; + channel = <11>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq12: external-interrupt@4000600c { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600c 0x1>; + channel = <12>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq13: external-interrupt@4000600d { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600d 0x1>; + channel = <13>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq14: external-interrupt@4000600e { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600e 0x1>; + channel = <14>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq15: external-interrupt@4000600f { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600f 0x1>; + channel = <15>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + pwm0: pwm0@40078000 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078000 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm1@40078100 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078100 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm2@40078200 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078200 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm3@40078300 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078300 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm4: pwm4@40078400 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm5@40078500 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078500 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm6@40078600 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078600 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm7@40078700 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 5>; + reg = <0x40078700 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm8: pwm8@40078800 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078800 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm9: pwm9@40078900 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078900 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm10: pwm10@40078a00 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078a00 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm11: pwm11@40078b00 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078b00 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm12: pwm12@40078c00 { + compatible = "renesas,ra-pwm"; + divider = ; + channel = ; + clocks = <&pclkd MSTPD 6>; + reg = <0x40078c00 0x100>; + #pwm-cells = <3>; + status = "disabled"; + }; + + flash: flash-controller@407e0000 { + compatible = "renesas,ra-flash-hp-controller"; + reg = <0x407e0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = <49 1>, <50 1>; + interrupt-names = "frdyi", "fiferr"; + }; + }; + + usbfs_phy: usbfs-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; }; }; diff --git a/dts/arm/renesas/ra/ra8/r7fa8d1bhecbd.dtsi b/dts/arm/renesas/ra/ra8/r7fa8d1bhecbd.dtsi index f4a67c63dcbc2..f6aeede336e0e 100644 --- a/dts/arm/renesas/ra/ra8/r7fa8d1bhecbd.dtsi +++ b/dts/arm/renesas/ra/ra8/r7fa8d1bhecbd.dtsi @@ -5,6 +5,7 @@ */ #include +#include / { soc { diff --git a/dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi b/dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi index cd2b62c0924a7..629908e00e48d 100644 --- a/dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi +++ b/dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi @@ -8,6 +8,36 @@ #include / { + soc { + sdram: sdram-controller@40002000 { + compatible = "renesas,ra-sdram"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40002000 0xFFF>; + status = "disabled"; + }; + + lcdif: display-controller@40342000 { + compatible = "renesas,ra-glcdc"; + reg = <0x40342000 0x1454>; + clocks = <&lcdclk MSTPC 4>; + interrupts = <71 1>; + interrupt-names = "line"; + status = "disabled"; + }; + + mipi_dsi: dsihost@40346000 { + compatible = "renesas,ra-mipi-dsi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40346000 0x2000>; + interrupts = <72 12>, <73 12>, <74 12>, <75 12>, <76 12>, <77 12>; + interrupt-names = "sq0", "sq1", "vm", "rcv", "ferr", "ppi"; + clocks = <&lcdclk MSTPC 10>; + status = "disabled"; + }; + }; + clocks: clocks { #address-cells = <1>; #size-cells = <1>; @@ -125,6 +155,7 @@ cpuclk: cpuclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <480000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -247,4 +278,189 @@ }; }; }; + + soc { + usbhs: usbhs@40351000 { + compatible = "renesas,ra-usbhs"; + reg = <0x40351000 0x2000>; + interrupts = <54 12>; + interrupt-names = "usbhs-ir"; + num-bidir-endpoints = <10>; + phys = <&usbhs_phy>; + phys-clock = <&uclk>, <&u60clk>; + status = "disabled"; + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + }; + + usbhs_phy: usbhs-phy { + compatible = "renesas,ra-usbphyc"; + #phy-cells = <0>; + }; +}; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13 &port_irq14>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13", + "port-irq14"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <9 15>; + port-irq14-pins = <10>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <3 13>; + port-irq3-pins = <2 8 12>; +}; + +&ioport3 { + port-irqs = <&port_irq4 &port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq4", + "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq4-pins = <0>; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq1 &port_irq2 &port_irq3 + &port_irq14 &port_irq15>; + port-irq-names = "port-irq1", + "port-irq2", + "port-irq3", + "port-irq14", + "port-irq15"; + port-irq1-pins = <8>; + port-irq2-pins = <9>; + port-irq3-pins = <10>; + port-irq14-pins = <12>; + port-irq15-pins = <11>; +}; + +&ioport6 { + port-irqs = <&port_irq7>; + port-irq-names = "port-irq7"; + port-irq7-pins = <15>; +}; + +&ioport7 { + port-irqs = <&port_irq7 &port_irq8 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq7", + "port-irq8", + "port-irq10", + "port-irq11"; + port-irq7-pins = <6>; + port-irq8-pins = <7>; + port-irq10-pins = <9>; + port-irq11-pins = <8>; +}; + +&ioport8 { + port-irqs = <&port_irq0 &port_irq11 &port_irq12 + &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq11", + "port-irq12", + "port-irq14", + "port-irq15"; + port-irq0-pins = <6>; + port-irq11-pins = <0>; + port-irq12-pins = <1>; + port-irq14-pins = <4>; + port-irq15-pins = <8>; +}; + +&ioport9 { + port-irqs = <&port_irq8 &port_irq9 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11"; + port-irq8-pins = <5>; + port-irq9-pins = <6>; + port-irq10-pins = <7>; + port-irq11-pins = <8>; +}; + +&ioporta { + port-irqs = <&port_irq4 &port_irq5 &port_irq6>; + port-irq-names = "port-irq4", + "port-irq5", + "port-irq6"; + port-irq4-pins = <10>; + port-irq5-pins = <9>; + port-irq6-pins = <8>; +}; + +&dac_global { + has-internal-output; + has-output-amplifier; }; diff --git a/dts/arm/renesas/ra/ra8/r7fa8m1xh.dtsi b/dts/arm/renesas/ra/ra8/r7fa8m1xh.dtsi index aedecdd38ff93..88661e3abfe85 100644 --- a/dts/arm/renesas/ra/ra8/r7fa8m1xh.dtsi +++ b/dts/arm/renesas/ra/ra8/r7fa8m1xh.dtsi @@ -125,6 +125,7 @@ cpuclk: cpuclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <480000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -241,4 +242,189 @@ }; }; }; + + soc { + usbhs: usbhs@40351000 { + compatible = "renesas,ra-usbhs"; + reg = <0x40351000 0x2000>; + interrupts = <54 12>; + interrupt-names = "usbhs-ir"; + num-bidir-endpoints = <10>; + phys = <&usbhs_phy>; + phys-clock = <&uclk>, <&u60clk>; + status = "disabled"; + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + }; + + usbhs_phy: usbhs-phy { + compatible = "renesas,ra-usbphyc"; + #phy-cells = <0>; + }; +}; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13 &port_irq14>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13", + "port-irq14"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <9 15>; + port-irq14-pins = <10>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <3 13>; + port-irq3-pins = <2 8 12>; +}; + +&ioport3 { + port-irqs = <&port_irq4 &port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq4", + "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq4-pins = <0>; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq1 &port_irq2 &port_irq3 + &port_irq14 &port_irq15>; + port-irq-names = "port-irq1", + "port-irq2", + "port-irq3", + "port-irq14", + "port-irq15"; + port-irq1-pins = <8>; + port-irq2-pins = <9>; + port-irq3-pins = <10>; + port-irq14-pins = <12>; + port-irq15-pins = <11>; +}; + +&ioport6 { + port-irqs = <&port_irq7>; + port-irq-names = "port-irq7"; + port-irq7-pins = <15>; +}; + +&ioport7 { + port-irqs = <&port_irq7 &port_irq8 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq7", + "port-irq8", + "port-irq10", + "port-irq11"; + port-irq7-pins = <6>; + port-irq8-pins = <7>; + port-irq10-pins = <9>; + port-irq11-pins = <8>; +}; + +&ioport8 { + port-irqs = <&port_irq0 &port_irq11 &port_irq12 + &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq11", + "port-irq12", + "port-irq14", + "port-irq15"; + port-irq0-pins = <6>; + port-irq11-pins = <0>; + port-irq12-pins = <1>; + port-irq14-pins = <4>; + port-irq15-pins = <8>; +}; + +&ioport9 { + port-irqs = <&port_irq8 &port_irq9 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11"; + port-irq8-pins = <5>; + port-irq9-pins = <6>; + port-irq10-pins = <7>; + port-irq11-pins = <8>; +}; + +&ioporta { + port-irqs = <&port_irq4 &port_irq5 &port_irq6>; + port-irq-names = "port-irq4", + "port-irq5", + "port-irq6"; + port-irq4-pins = <10>; + port-irq5-pins = <9>; + port-irq6-pins = <8>; +}; + +&dac_global { + has-internal-output; + has-output-amplifier; }; diff --git a/dts/arm/renesas/ra/ra8/r7fa8t1xh.dtsi b/dts/arm/renesas/ra/ra8/r7fa8t1xh.dtsi index a2013deab2592..9c45b7709516b 100644 --- a/dts/arm/renesas/ra/ra8/r7fa8t1xh.dtsi +++ b/dts/arm/renesas/ra/ra8/r7fa8t1xh.dtsi @@ -122,6 +122,7 @@ cpuclk: cpuclk { compatible = "renesas,ra-cgc-pclk"; + clock-frequency = <480000000>; div = <1>; #clock-cells = <2>; status = "okay"; @@ -245,3 +246,166 @@ }; }; }; + +&ioport0 { + port-irqs = <&port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq10 &port_irq11 + &port_irq12 &port_irq13 &port_irq14>; + port-irq-names = "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11", + "port-irq12", + "port-irq13", + "port-irq14"; + port-irq6-pins = <0>; + port-irq7-pins = <1>; + port-irq8-pins = <2>; + port-irq9-pins = <4>; + port-irq10-pins = <5>; + port-irq11-pins = <6>; + port-irq12-pins = <8>; + port-irq13-pins = <9 15>; + port-irq14-pins = <10>; +}; + +&ioport1 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2"; + port-irq0-pins = <5>; + port-irq1-pins = <1 4>; + port-irq2-pins = <0>; +}; + +&ioport2 { + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3"; + port-irq0-pins = <6>; + port-irq1-pins = <5>; + port-irq2-pins = <3 13>; + port-irq3-pins = <2 8 12>; +}; + +&ioport3 { + port-irqs = <&port_irq4 &port_irq5 &port_irq6 + &port_irq8 &port_irq9>; + port-irq-names = "port-irq4", + "port-irq5", + "port-irq6", + "port-irq8", + "port-irq9"; + port-irq4-pins = <0>; + port-irq5-pins = <2>; + port-irq6-pins = <1>; + port-irq8-pins = <5>; + port-irq9-pins = <4>; +}; + +&ioport4 { + port-irqs = <&port_irq0 &port_irq4 &port_irq5 + &port_irq6 &port_irq7 &port_irq8 + &port_irq9 &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7", + "port-irq8", + "port-irq9", + "port-irq14", + "port-irq15"; + port-irq0-pins = <0>; + port-irq4-pins = <2 11>; + port-irq5-pins = <1 10>; + port-irq6-pins = <9>; + port-irq7-pins = <8>; + port-irq8-pins = <15>; + port-irq9-pins = <14>; + port-irq14-pins = <3>; + port-irq15-pins = <4>; +}; + +&ioport5 { + port-irqs = <&port_irq1 &port_irq2 &port_irq3 + &port_irq14 &port_irq15>; + port-irq-names = "port-irq1", + "port-irq2", + "port-irq3", + "port-irq14", + "port-irq15"; + port-irq1-pins = <8>; + port-irq2-pins = <9>; + port-irq3-pins = <10>; + port-irq14-pins = <12>; + port-irq15-pins = <11>; +}; + +&ioport6 { + port-irqs = <&port_irq7>; + port-irq-names = "port-irq7"; + port-irq7-pins = <15>; +}; + +&ioport7 { + port-irqs = <&port_irq7 &port_irq8 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq7", + "port-irq8", + "port-irq10", + "port-irq11"; + port-irq7-pins = <6>; + port-irq8-pins = <7>; + port-irq10-pins = <9>; + port-irq11-pins = <8>; +}; + +&ioport8 { + port-irqs = <&port_irq0 &port_irq11 &port_irq12 + &port_irq14 &port_irq15>; + port-irq-names = "port-irq0", + "port-irq11", + "port-irq12", + "port-irq14", + "port-irq15"; + port-irq0-pins = <6>; + port-irq11-pins = <0>; + port-irq12-pins = <1>; + port-irq14-pins = <4>; + port-irq15-pins = <8>; +}; + +&ioport9 { + port-irqs = <&port_irq8 &port_irq9 &port_irq10 + &port_irq11>; + port-irq-names = "port-irq8", + "port-irq9", + "port-irq10", + "port-irq11"; + port-irq8-pins = <5>; + port-irq9-pins = <6>; + port-irq10-pins = <7>; + port-irq11-pins = <8>; +}; + +&ioporta { + port-irqs = <&port_irq4 &port_irq5 &port_irq6>; + port-irq-names = "port-irq4", + "port-irq5", + "port-irq6"; + port-irq4-pins = <10>; + port-irq5-pins = <9>; + port-irq6-pins = <8>; +}; + +&dac_global { + has-internal-output; + has-output-amplifier; +}; diff --git a/dts/arm/renesas/ra/ra8/ra8x1.dtsi b/dts/arm/renesas/ra/ra8/ra8x1.dtsi index 3d9ad95ec08aa..cf1957b5ad88f 100644 --- a/dts/arm/renesas/ra/ra8/ra8x1.dtsi +++ b/dts/arm/renesas/ra/ra8/ra8x1.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -97,7 +97,7 @@ gpio-controller; #gpio-cells = <2>; ngpios = <16>; - vbatts_pins = <2 3 4>; + vbatts-pins = <2 3 4>; status = "disabled"; }; @@ -174,8 +174,6 @@ iic0: iic0@4025e000 { compatible = "renesas,ra-iic"; channel = <0>; - interrupts = <87 1>, <88 1>, <89 1>, <90 1>; - interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x4025E000 0x100>; status = "disabled"; }; @@ -279,6 +277,10 @@ #size-cells = <1>; interrupts = <49 1>, <50 1>; interrupt-names = "frdyi", "fiferr"; + reserved-area-num = <33>; + block-32kb-linear-end = <68>; + block-32kb-dual-low-end = <36>; + block-32kb-dual-high-end = <106>; }; adc0: adc@40332000 { @@ -289,6 +291,7 @@ #io-channel-cells = <1>; vref-mv = <3300>; channel-count = <12>; + channel-available-mask = <0xf01f7>; status = "disabled"; }; @@ -300,9 +303,31 @@ #io-channel-cells = <1>; vref-mv = <3300>; channel-count = <13>; + channel-available-mask = <0x7f0077>; status = "disabled"; }; + dac_global: dac_global@40333000 { + compatible = "renesas,ra-dac-global"; + reg = <0x40333000 0x10c4>; + #address-cells = <1>; + #size-cells = <0>; + + dac0: dac@0 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <0>; + status = "disabled"; + }; + + dac1: dac@1 { + compatible = "renesas,ra-dac"; + #io-channel-cells = <1>; + reg = <1>; + status = "disabled"; + }; + }; + trng: trng { compatible = "renesas,ra-rsip-e51a-trng"; }; @@ -334,7 +359,7 @@ }; pwm0: pwm0@40322000 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 31>; @@ -344,7 +369,7 @@ }; pwm1: pwm1@40322100 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 30>; @@ -354,7 +379,7 @@ }; pwm2: pwm2@40322200 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 29>; @@ -364,7 +389,7 @@ }; pwm3: pwm3@40322300 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 28>; @@ -374,7 +399,7 @@ }; pwm4: pwm4@40322400 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 27>; @@ -384,7 +409,7 @@ }; pwm5: pwm5@40322500 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 26>; @@ -394,7 +419,7 @@ }; pwm6: pwm6@40322600 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 25>; @@ -404,7 +429,7 @@ }; pwm7: pwm7@40322700 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 24>; @@ -414,7 +439,7 @@ }; pwm8: pwm8@40322800 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 23>; @@ -424,7 +449,7 @@ }; pwm9: pwm9@40322900 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 22>; @@ -434,7 +459,7 @@ }; pwm10: pwm10@40322a00 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 21>; @@ -444,7 +469,7 @@ }; pwm11: pwm11@40322b00 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 20>; @@ -454,7 +479,7 @@ }; pwm12: pwm12@40322c00 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 19>; @@ -464,7 +489,7 @@ }; pwm13: pwm13@40322d00 { - compatible = "renesas,ra8-pwm"; + compatible = "renesas,ra-pwm"; divider = ; channel = ; clocks = <&pclkd MSTPE 18>; @@ -534,6 +559,8 @@ interrupt-names = "rxf", "glerr"; clocks = <&pclka 0 0>, <&pclke 0 0>; clock-names = "opclk", "ramclk"; + dll-min-freq = ; + dll-max-freq = ; reg = <0x40380000 0x4000>; status = "disabled"; @@ -573,6 +600,199 @@ #size-cells = <0>; status = "disabled"; }; + + port_irq0: external-interrupt@40006000 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006000 0x1>; + channel = <0>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq1: external-interrupt@40006001 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006001 0x1>; + channel = <1>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq2: external-interrupt@40006002 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006002 0x1>; + channel = <2>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq3: external-interrupt@40006003 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006003 0x1>; + channel = <3>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq4: external-interrupt@40006004 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006004 0x1>; + channel = <4>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq5: external-interrupt@40006005 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006005 0x1>; + channel = <5>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq6: external-interrupt@40006006 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006006 0x1>; + channel = <6>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq7: external-interrupt@40006007 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006007 0x1>; + channel = <7>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq8: external-interrupt@40006008 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006008 0x1>; + channel = <8>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq9: external-interrupt@40006009 { + compatible = "renesas,ra-external-interrupt"; + reg = <0x40006009 0x1>; + channel = <9>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq10: external-interrupt@4000600a { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600a 0x1>; + channel = <10>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq11: external-interrupt@4000600b { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600b 0x1>; + channel = <11>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq12: external-interrupt@4000600c { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600c 0x1>; + channel = <12>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq13: external-interrupt@4000600d { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600d 0x1>; + channel = <13>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq14: external-interrupt@4000600e { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600e 0x1>; + channel = <14>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq15: external-interrupt@4000600f { + compatible = "renesas,ra-external-interrupt"; + reg = <0x4000600f 0x1>; + channel = <15>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + sdhc0: sdhc@40252000 { + compatible = "renesas,ra-sdhc"; + channel = <0>; + bus-width = <4>; + sd-support; + mmc-support; + card-detect; + max-bus-freq = ; + clocks = <&pclkb MSTPC 12>; + reg = <0x40252000 0x0400>; + interrupt-names = "accs", "card", "dma-req"; + interrupts = <57 12>, <58 12>, <59 12>; + status = "disabled"; + }; + + sdhc1: sdhc@40252400 { + compatible = "renesas,ra-sdhc"; + channel = <1>; + bus-width = <4>; + sd-support; + mmc-support; + card-detect; + max-bus-freq = ; + clocks = <&pclkb MSTPC 11>; + reg = <0x40252400 0x0400>; + status = "disabled"; + }; + + usbfs: usbfs@40250000 { + compatible = "renesas,ra-usbfs"; + reg = <0x40250000 0x2000>; + interrupts = <55 12>, <56 12>; + interrupt-names = "usbfs-i", "usbfs-r"; + num-bidir-endpoints = <10>; + phys = <&usbfs_phy>; + phys-clock = <&uclk>; + status = "disabled"; + + udc { + compatible = "renesas,ra-udc"; + status = "disabled"; + }; + }; + }; + + usbfs_phy: usbfs-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; }; }; diff --git a/dts/arm/renesas/rz/rzg/r9a08g045.dtsi b/dts/arm/renesas/rz/rzg/r9a08g045.dtsi new file mode 100644 index 0000000000000..14614b4d22c19 --- /dev/null +++ b/dts/arm/renesas/rz/rzg/r9a08g045.dtsi @@ -0,0 +1,753 @@ +/* + * Copyright (c) 2024 EPAM Systems + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + compatible = "renesas,r9a08g045"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m33"; + reg = <0>; + clock-frequency = <250000000>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv8m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + osc: osc { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + soc { + cpg: clock-controller@41010000 { + compatible = "renesas,rz-cpg"; + reg = <0x41010000 0x10000>; + clocks = <&osc>; + #clock-cells = <1>; + status = "okay"; + + iclk: iclk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + p0clk: p0clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + p4clk: p4clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + p5clk: p5clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + tsuclk: tsuclk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + sd0clk: sd0clk { + compatible = "fixed-clock"; + clock-frequency = <133333333>; + #clock-cells = <0>; + }; + + sd1clk: sd1clk { + compatible = "fixed-clock"; + clock-frequency = <133333333>; + #clock-cells = <0>; + }; + + sd2clk: sd2clk { + compatible = "fixed-clock"; + clock-frequency = <133333333>; + #clock-cells = <0>; + }; + + m0clk: m0clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + p1clk: p1clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + p2clk: p2clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + p3clk: p3clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + atclk: atclk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + ztclk: ztclk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + oc0clk: oc0clk { + compatible = "fixed-clock"; + clock-frequency = <33333333>; + #clock-cells = <0>; + }; + + oc1clk: oc1clk { + compatible = "fixed-clock"; + clock-frequency = <16666666>; + #clock-cells = <0>; + }; + + spi0clk: spi0clk { + compatible = "fixed-clock"; + clock-frequency = <33333333>; + #clock-cells = <0>; + }; + + spi1clk: spi1clk { + compatible = "fixed-clock"; + clock-frequency = <16666666>; + #clock-cells = <0>; + }; + + s0clk: s0clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + i2clk: i2clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + i3clk: i3clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + hpclk: hpclk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + oscclk: oscclk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + osc2clk: osc2clk { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + }; + + pinctrl: pin-controller@41030000 { + compatible = "renesas,rzg-pinctrl"; + reg = <0x41030000 DT_SIZE_K(64)>; + reg-names = "pinctrl"; + + gpio: gpio-common { + compatible = "renesas,rz-gpio-int"; + interrupts = + <429 10>, <430 10>, <431 10>, <432 10>, + <433 10>, <434 10>, <435 10>, <436 10>, + <437 10>, <438 10>, <439 10>, <440 10>, + <441 10>, <442 10>, <443 10>, <444 10>, + <445 10>, <446 10>, <447 10>, <448 10>, + <449 10>, <450 10>, <451 10>, <452 10>, + <453 10>, <454 10>, <455 10>, <456 10>, + <457 10>, <458 10>, <459 10>, <460 10>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@1000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <5>; + reg = <0x1000>; + status = "disabled"; + }; + + gpio2: gpio@1100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <4>; + reg = <0x1100>; + status = "disabled"; + }; + + gpio3: gpio@1200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <4>; + reg = <0x1200>; + status = "disabled"; + }; + + gpio4: gpio@1300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <6>; + reg = <0x1300>; + status = "disabled"; + }; + + gpio5: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <5>; + reg = <0x100>; + status = "disabled"; + }; + + gpio6: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <5>; + reg = <0x200>; + status = "disabled"; + }; + + gpio7: gpio@1400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <5>; + reg = <0x1400>; + status = "disabled"; + }; + + gpio8: gpio@1500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <5>; + reg = <0x1500>; + status = "disabled"; + }; + + gpio9: gpio@1600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <4>; + reg = <0x1600>; + status = "disabled"; + }; + + gpio10: gpio@1700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <5>; + reg = <0x1700>; + status = "disabled"; + }; + + gpio11: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <4>; + reg = <0x300>; + status = "disabled"; + }; + + gpio12: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <2>; + reg = <0x400>; + status = "disabled"; + }; + + gpio13: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <5>; + reg = <0x500>; + status = "disabled"; + }; + + gpio14: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <3>; + reg = <0x600>; + status = "disabled"; + }; + + gpio15: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <4>; + reg = <0x700>; + status = "disabled"; + }; + + gpio16: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <2>; + reg = <0x800>; + status = "disabled"; + }; + + gpio17: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells= <2>; + ngpios = <4>; + reg = <0x900>; + status = "disabled"; + }; + + gpio18: gpio@A00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells=<2>; + ngpios = <6>; + reg = <0xA00>; + status = "disabled"; + }; + }; + }; + + scif0: serial@4004b800 { + compatible = "renesas,rz-scif-uart"; + channel = <0>; + reg = <0x4004b800 0x18>; + interrupts = <320 1>, <321 1>, <322 1>, <323 1>, <324 1>; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + scif1: serial@4004bc00 { + compatible = "renesas,rz-scif-uart"; + channel = <1>; + reg = <0x4004bc00 0x18>; + interrupts = <325 1>, <326 1>, <327 1>, <328 1>, <329 1>; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + scif2: serial@4004c000 { + compatible = "renesas,rz-scif-uart"; + channel = <2>; + reg = <0x4004c000 0x18>; + interrupts = <330 1>, <331 1>, <332 1>, <333 1>, <334 1>; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + scif3: serial@4004c400 { + compatible = "renesas,rz-scif-uart"; + channel = <3>; + reg = <0x4004c400 0x18>; + interrupts = <335 1>, <336 1>, <337 1>, <338 1>, <339 1>; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + scif4: serial@4004c800 { + compatible = "renesas,rz-scif-uart"; + channel = <4>; + reg = <0x4004c800 0x18>; + interrupts = <340 1>, <341 1>, <342 1>, <343 1>, <344 1>; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + scif5: serial@4004e000 { + compatible = "renesas,rz-scif-uart"; + channel = <5>; + reg = <0x4004e000 0x18>; + interrupts = <345 1>, <346 1>, <347 1>, <348 1>, <349 1>; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + + gtm0: gtm@42801000 { + compatible = "renesas,rz-gtm"; + reg = <0x42801000 0x30>; + channel = <0>; + interrupts = <44 1>; + interrupt-names = "overflow"; + status = "disabled"; + + counter { + compatible = "renesas,rz-gtm-counter"; + status = "disabled"; + }; + }; + gtm1: gtm@42801400 { + compatible = "renesas,rz-gtm"; + reg = <0x42801400 0x30>; + channel = <1>; + interrupts = <45 1>; + interrupt-names = "overflow"; + status = "disabled"; + + counter { + compatible = "renesas,rz-gtm-counter"; + status = "disabled"; + }; + }; + gtm2: gtm@42801800 { + compatible = "renesas,rz-gtm"; + reg = <0x42801800 0x30>; + channel = <2>; + interrupts = <46 1>; + interrupt-names = "overflow"; + status = "disabled"; + + counter { + compatible = "renesas,rz-gtm-counter"; + status = "disabled"; + }; + }; + gtm3: gtm@42801c00 { + compatible = "renesas,rz-gtm"; + reg = <0x42801c00 0x30>; + channel = <3>; + interrupts = <47 1>; + interrupt-names = "overflow"; + status = "disabled"; + + counter { + compatible = "renesas,rz-gtm-counter"; + status = "disabled"; + }; + }; + gtm4: gtm@42802000 { + compatible = "renesas,rz-gtm"; + reg = <0x42802000 0x30>; + channel = <4>; + interrupts = <48 1>; + interrupt-names = "overflow"; + status = "disabled"; + + counter { + compatible = "renesas,rz-gtm-counter"; + status = "disabled"; + }; + }; + gtm5: gtm@42802400 { + compatible = "renesas,rz-gtm"; + reg = <0x42802400 0x30>; + channel = <5>; + interrupts = <49 1>; + interrupt-names = "overflow"; + status = "disabled"; + + counter { + compatible = "renesas,rz-gtm-counter"; + status = "disabled"; + }; + }; + gtm6: gtm@42802800 { + compatible = "renesas,rz-gtm"; + reg = <0x42802800 0x30>; + channel = <6>; + interrupts = <50 1>; + interrupt-names = "overflow"; + status = "disabled"; + + counter { + compatible = "renesas,rz-gtm-counter"; + status = "disabled"; + }; + }; + gtm7: gtm@42802c00 { + compatible = "renesas,rz-gtm"; + reg = <0x42802c00 0x30>; + channel = <7>; + interrupts = <51 1>; + interrupt-names = "overflow"; + status = "disabled"; + + counter { + compatible = "renesas,rz-gtm-counter"; + status = "disabled"; + }; + }; + + gpt32e0: gpt32e@50048000 { + compatible = "renesas,rz-gpt"; + reg = <0x50048000 0xa4>; + channel = <0>; + interrupts = <128 1>, <129 1>, <130 1>, <131 1>, <132 1>, + <133 1>, <134 1>, <135 1>, <136 1>, <137 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + gpt32e1: gpt32e@50048100 { + compatible = "renesas,rz-gpt"; + reg = <0x50048100 0xa4>; + channel = <1>; + interrupts = <141 1>, <142 1>, <143 1>, <144 1>, <145 1>, + <146 1>, <147 1>, <148 1>, <149 1>, <150 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + gpt32e2: gpt32e@50048200 { + compatible = "renesas,rz-gpt"; + reg = <0x50048200 0xa4>; + channel = <2>; + interrupts = <154 1>, <155 1>, <156 1>, <157 1>, <158 1>, + <159 1>, <160 1>, <161 1>, <162 1>, <163 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + gpt32e3: gpt32e@50048300 { + compatible = "renesas,rz-gpt"; + reg = <0x50048300 0xa4>; + channel = <3>; + interrupts = <167 1>, <168 1>, <169 1>, <170 1>, <171 1>, + <172 1>, <173 1>, <174 1>, <175 1>, <176 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + gpt32e4: gpt32e@50048400 { + compatible = "renesas,rz-gpt"; + reg = <0x50048400 0xa4>; + channel = <4>; + interrupts = <180 1>, <181 1>, <182 1>, <183 1>, <184 1>, + <185 1>, <186 1>, <187 1>, <188 1>, <189 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + gpt32e5: gpt32e@50048500 { + compatible = "renesas,rz-gpt"; + reg = <0x50048500 0xa4>; + channel = <5>; + interrupts = <193 1>, <194 1>, <195 1>, <196 1>, <197 1>, + <198 1>, <199 1>, <200 1>, <201 1>, <202 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + gpt32e6: gpt32e@50048600 { + compatible = "renesas,rz-gpt"; + reg = <0x50048600 0xa4>; + channel = <6>; + interrupts = <206 1>, <207 1>, <208 1>, <209 1>, <210 1>, + <211 1>, <212 1>, <213 1>, <214 1>, <215 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + gpt32e7: gpt32e@50048700 { + compatible = "renesas,rz-gpt"; + reg = <0x50048700 0xa4>; + channel = <7>; + interrupts = <219 1>, <220 1>, <221 1>, <222 1>, <223 1>, + <224 1>, <225 1>, <226 1>, <227 1>, <228 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + intc: interrupt-controller@41060000 { + reg = <0x41060000 0x18>; + #address-cells = <0>; + interrupt-parent = <&nvic>; + + nmi: nmi { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 1>; //NMI + status = "disabled"; + }; + + irq0: irq0 { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <1 1>; + status = "disabled"; + }; + irq1: irq1 { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <2 1>; + status = "disabled"; + }; + irq2: irq2 { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <3 1>; + status = "disabled"; + }; + irq3: irq3 { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <4 1>; + status = "disabled"; + }; + irq4: irq4 { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <5 1>; + status = "disabled"; + }; + irq5: irq5 { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <6 1>; + status = "disabled"; + }; + irq6: irq6 { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <7 1>; + status = "disabled"; + }; + irq7: irq7 { + compatible = "renesas,rz-ext-irq"; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <8 1>; + status = "disabled"; + }; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <7>; +}; diff --git a/dts/arm/silabs/efr32bg22.dtsi b/dts/arm/silabs/efr32bg22.dtsi index 87b1420693693..5bf1c7b584a9a 100644 --- a/dts/arm/silabs/efr32bg22.dtsi +++ b/dts/arm/silabs/efr32bg22.dtsi @@ -6,6 +6,7 @@ #include "efr32bg2x.dtsi" #include +#include #include / { @@ -54,6 +55,10 @@ clocks = <&cmu CLOCK_GPIO CLOCK_BRANCH_PCLK>; }; +&dma0 { + interrupts = <21 0>; +}; + &i2c0 { interrupts = <27 0>; clocks = <&cmu CLOCK_I2C0 CLOCK_BRANCH_LSPCLK>; @@ -88,3 +93,11 @@ &dcdc { interrupts = <61 0>; }; + +&radio { + interrupts = <31 0>, <32 0>, <33 0>, <34 0>, <35 0>, <36 0>, + <37 0>, <38 0>, <39 0>, <40 0>, <41 0>, <42 0>; + interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", + "rac_rsm", "rac_seq", "rdmailbox", "rfsense", "prortc", + "synth"; +}; diff --git a/dts/arm/silabs/efr32bg27.dtsi b/dts/arm/silabs/efr32bg27.dtsi index 3a3b7e181affb..d40bda0223ccd 100644 --- a/dts/arm/silabs/efr32bg27.dtsi +++ b/dts/arm/silabs/efr32bg27.dtsi @@ -6,6 +6,7 @@ #include "efr32bg2x.dtsi" #include +#include #include / { @@ -34,6 +35,13 @@ reg = <0x5003c460 0x4>; clock-frequency = ; }; + acmp0: acmp@5a008000 { + compatible = "silabs,acmp"; + reg = <0x5a008000 0x4000>; + interrupts = <48 0>; + clocks = <&cmu CLOCK_ACMP0 CLOCK_BRANCH_EM01GRPACLK>; + status = "disabled"; + }; }; }; @@ -103,3 +111,15 @@ &dcdc { interrupts = <8 0>; }; + +&dma0 { + interrupts = <26 0>; +}; + +&radio { + interrupts = <36 0>, <37 0>, <38 0>, <39 0>, <40 0>, <41 0>, + <42 0>, <43 0>, <44 0>, <45 0>, <46 0>, <47 0>; + interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", + "rac_rsm", "rac_seq", "rdmailbox", "rfsense", "synth", + "prortc"; +}; diff --git a/dts/arm/silabs/efr32bg2x.dtsi b/dts/arm/silabs/efr32bg2x.dtsi index b5104346e65aa..c2a4d642781d1 100644 --- a/dts/arm/silabs/efr32bg2x.dtsi +++ b/dts/arm/silabs/efr32bg2x.dtsi @@ -118,6 +118,9 @@ * Using BURTC as sys_clock instead of SysTick * has implications on system performance. Read * KConfig documentation entry before enabling it. + * + * The minimum residency and exit latency is + * managed by sl_power_manager on S2 devices. */ cpu-power-states = <&pstate_em1 &pstate_em2 &pstate_em3>; }; @@ -130,9 +133,7 @@ pstate_em1: em1 { compatible = "zephyr,power-state"; power-state-name = "runtime-idle"; - min-residency-us = <4>; /* HFXO remains active */ - exit-latency-us = <2>; }; /* @@ -142,8 +143,6 @@ pstate_em2: em2 { compatible = "zephyr,power-state"; power-state-name = "suspend-to-idle"; - min-residency-us = <260>; - exit-latency-us = <250>; }; /* @@ -155,8 +154,6 @@ pstate_em3: em3 { compatible = "zephyr,power-state"; power-state-name = "standby"; - min-residency-us = <20000>; - exit-latency-us = <2000>; }; }; }; @@ -233,7 +230,7 @@ }; usart0: usart@5005c000 { - compatible = "silabs,gecko-spi-usart"; + compatible = "silabs,usart-spi"; reg = <0x5005C000 0x400>; interrupt-names = "rx", "tx"; #address-cells = <1>; @@ -242,7 +239,7 @@ }; usart1: usart@50060000 { - compatible = "silabs,gecko-usart"; + compatible = "silabs,usart-uart"; reg = <0x50060000 0x400>; interrupt-names = "rx", "tx"; status = "disabled"; @@ -340,7 +337,16 @@ pinctrl: pin-controller@5003c440 { compatible = "silabs,dbus-pinctrl"; - reg = <0x5003c440 0xbc0>; + reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>; + reg-names = "dbus", "abus"; + }; + + dma0: dma@40040000{ + compatible = "silabs,ldma"; + reg = <0x40040000 0x4000>; + #dma-cells = <1>; + dma_channels = <8>; + status = "disabled"; }; wdog0: wdog@4a018000 { @@ -364,11 +370,20 @@ reg = <0x50094000 0x4000>; status = "disabled"; }; - }; - bt_hci_silabs: bt_hci_silabs { - compatible = "silabs,bt-hci-efr32"; - status = "disabled"; + radio: radio@b0000000 { + compatible = "silabs,series2-radio"; + reg = <0xb0000000 0x1000000>; + pa-initial-power-dbm = <10>; + pa-ramp-time-us = <2>; + pa-voltage-mv = <3300>; + pa-2p4ghz = "highest"; + + bt_hci_silabs: bt_hci_silabs { + compatible = "silabs,bt-hci-efr32"; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/silabs/efr32mg21.dtsi b/dts/arm/silabs/efr32mg21.dtsi index 8bf0900a9bf7f..716f83c251047 100644 --- a/dts/arm/silabs/efr32mg21.dtsi +++ b/dts/arm/silabs/efr32mg21.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include / { @@ -206,31 +207,28 @@ }; usart0: usart@50058000 { /* USART0 */ - compatible = "silabs,gecko-usart"; + compatible = "silabs,usart-uart"; reg = <0x50058000 0x400>; interrupts = <11 0>, <12 0>; interrupt-names = "rx", "tx"; - peripheral-id = <0>; clocks = <&cmu CLOCK_AUTO CLOCK_BRANCH_PCLK>; status = "disabled"; }; usart1: usart@5005c000 { /* USART1 */ - compatible = "silabs,gecko-usart"; + compatible = "silabs,usart-uart"; reg = <0x5005c000 0x400>; interrupts = <13 0>, <14 0>; interrupt-names = "rx", "tx"; - peripheral-id = <1>; clocks = <&cmu CLOCK_AUTO CLOCK_BRANCH_PCLK>; status = "disabled"; }; usart2: usart@50060000 { /* USART2 */ - compatible = "silabs,gecko-usart"; + compatible = "silabs,usart-uart"; reg = <0x50060000 0x400>; interrupts = <15 0>, <16 0>; interrupt-names = "rx", "tx"; - peripheral-id = <2>; clocks = <&cmu CLOCK_AUTO CLOCK_BRANCH_PCLK>; status = "disabled"; }; @@ -318,7 +316,8 @@ pinctrl: pin-controller@5003c440 { compatible = "silabs,dbus-pinctrl"; - reg = <0x5003c440 0xbc0>; + reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>; + reg-names = "dbus", "abus"; }; se: semailbox@5c000000 { @@ -329,6 +328,15 @@ status = "okay"; }; + dma0: dma@40040000{ + compatible = "silabs,ldma"; + reg = <0x40040000 0x4000>; + interrupts = <21 0>; + #dma-cells = <1>; + dma_channels = <8>; + status = "disabled"; + }; + wdog0: wdog@5a018000 { compatible = "silabs,gecko-wdog"; reg = <0x5a018000 0x2C>; @@ -346,6 +354,27 @@ clocks = <&cmu CLOCK_AUTO CLOCK_BRANCH_WDOG1CLK>; status = "disabled"; }; + + acmp0: acmp@5a008000 { + compatible = "silabs,acmp"; + reg = <0x5a008000 0x4000>; + interrupts = <41 0>; + clocks = <&cmu CLOCK_AUTO CLOCK_BRANCH_EM01GRPACLK>; + status = "disabled"; + }; + + radio: radio@b0000000 { + compatible = "silabs,series2-radio"; + reg = <0xb0000000 0x1000000>; + interrupts = <31 0>, <32 0>, <33 0>, <34 0>, <35 0>, <36 0>, + <37 0>, <38 0>, <39 0>, <40 0>; + interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", + "rac_rsm", "rac_seq", "prortc", "synth"; + pa-initial-power-dbm = <10>; + pa-ramp-time-us = <10>; + pa-voltage-mv = <3300>; + pa-2p4ghz = "highest"; + }; }; }; diff --git a/dts/arm/silabs/efr32mg24.dtsi b/dts/arm/silabs/efr32mg24.dtsi index bf40ebc507866..0531277d0b0ad 100644 --- a/dts/arm/silabs/efr32mg24.dtsi +++ b/dts/arm/silabs/efr32mg24.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include / { @@ -139,6 +140,10 @@ compatible = "arm,cortex-m33"; reg = <0>; cpu-power-states = <&pstate_em1 &pstate_em2 &pstate_em3>; + /* + * The minimum residency and exit latency is + * managed by sl_power_manager on S2 devices. + */ }; power-states { @@ -149,9 +154,7 @@ pstate_em1: em1 { compatible = "zephyr,power-state"; power-state-name = "runtime-idle"; - min-residency-us = <4>; /* HFXO remains active */ - exit-latency-us = <2>; }; /* @@ -161,8 +164,6 @@ pstate_em2: em2 { compatible = "zephyr,power-state"; power-state-name = "suspend-to-idle"; - min-residency-us = <260>; - exit-latency-us = <250>; }; /* @@ -174,8 +175,6 @@ pstate_em3: em3 { compatible = "zephyr,power-state"; power-state-name = "standby"; - min-residency-us = <20000>; - exit-latency-us = <2000>; }; }; }; @@ -268,7 +267,7 @@ #address-cells = <1>; #size-cells = <1>; - flash0: flash@0 { + flash0: flash@8000000 { compatible = "soc-nv-flash"; write-block-size = <4>; erase-block-size = <8192>; @@ -276,17 +275,16 @@ }; usart0: usart@5005c000 { - compatible = "silabs,gecko-usart"; + compatible = "silabs,usart-uart"; reg = <0x5005C000 0x306c>; interrupts = <9 0>, <10 0>; interrupt-names = "rx", "tx"; - peripheral-id = <0>; clocks = <&cmu CLOCK_USART0 CLOCK_BRANCH_PCLK>; status = "disabled"; }; eusart0: eusart@5b010000 { - compatible = "silabs,gecko-spi-eusart"; + compatible = "silabs,eusart-spi"; reg = <0x5B010000 0x4000>; interrupts = <11 0>, <12 0>; interrupt-names = "rx", "tx"; @@ -295,7 +293,7 @@ }; eusart1: eusart@500a0000 { - compatible = "silabs,gecko-spi-eusart"; + compatible = "silabs,eusart-spi"; reg = <0x500A0000 0x4000>; interrupts = <13 0>, <14 0>; interrupt-names = "rx", "tx"; @@ -391,7 +389,17 @@ pinctrl: pin-controller@5003c440 { compatible = "silabs,dbus-pinctrl"; - reg = <0x5003c440 0xbc0>; + reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>; + reg-names = "dbus", "abus"; + }; + + dma0: dma@40040000 { + compatible = "silabs,ldma"; + reg = <0x40040000 0x4000>; + interrupts = <21 0>; + #dma-cells = <1>; + dma_channels = <8>; + status = "disabled"; }; wdog0: wdog@5b004000 { @@ -427,12 +435,33 @@ interrupts = <53 0>; status = "disabled"; }; - }; + acmp0: acmp@59008000 { + compatible = "silabs,acmp"; + reg = <0x59008000 0x4000>; + interrupts = <40 0>; + clocks = <&cmu CLOCK_ACMP0 CLOCK_BRANCH_EM01GRPACLK>; + status = "disabled"; + }; - bt_hci_silabs: bt_hci_silabs { - compatible = "silabs,bt-hci-efr32"; - status = "disabled"; + radio: radio@b0000000 { + compatible = "silabs,series2-radio"; + reg = <0xb0000000 0x1000000>; + interrupts = <30 0>, <31 0>, <32 0>, <33 0>, <34 0>, <35 0>, + <36 0>, <37 0>, <38 0>, <39 0>, <70 0>, <71 0>; + interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", + "rac_rsm", "rac_seq", "hostmailbox", "synth", + "rfeca0", "rfeca1"; + pa-initial-power-dbm = <10>; + pa-ramp-time-us = <10>; + pa-voltage-mv = <3300>; + pa-2p4ghz = "highest"; + + bt_hci_silabs: bt_hci_silabs { + compatible = "silabs,bt-hci-efr32"; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/silabs/efr32mg24b020f1536im40.dtsi b/dts/arm/silabs/efr32mg24b020f1536im40.dtsi index 4ce3234d1b03b..cd1b7767172eb 100644 --- a/dts/arm/silabs/efr32mg24b020f1536im40.dtsi +++ b/dts/arm/silabs/efr32mg24b020f1536im40.dtsi @@ -16,11 +16,9 @@ compatible = "silabs,efr32mg24b020f1536im40", "silabs,efr32mg24", "silabs,efr32", "simple-bus"; - - flash-controller@50030000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(1536)>; - }; - }; }; }; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1536)>; +}; diff --git a/dts/arm/silabs/efr32mg24b210f1536im48.dtsi b/dts/arm/silabs/efr32mg24b210f1536im48.dtsi new file mode 100644 index 0000000000000..211aff8f42568 --- /dev/null +++ b/dts/arm/silabs/efr32mg24b210f1536im48.dtsi @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019 Steven Lemaire + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(256)>; + }; + + soc { + compatible = "silabs,efr32mg24b210f1536im48", + "silabs,efr32mg24", + "silabs,efr32", + "simple-bus"; + }; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1536)>; +}; diff --git a/dts/arm/silabs/efr32mg24b220f1536im48.dtsi b/dts/arm/silabs/efr32mg24b220f1536im48.dtsi index a7c2859b0a180..3035598eede98 100644 --- a/dts/arm/silabs/efr32mg24b220f1536im48.dtsi +++ b/dts/arm/silabs/efr32mg24b220f1536im48.dtsi @@ -16,11 +16,9 @@ compatible = "silabs,efr32mg24b220f1536im48", "silabs,efr32mg24", "silabs,efr32", "simple-bus"; - - flash-controller@50030000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(1536)>; - }; - }; }; }; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1536)>; +}; diff --git a/dts/arm/silabs/efr32mg24b310f1536im48.dtsi b/dts/arm/silabs/efr32mg24b310f1536im48.dtsi index c25171eafbea4..f9154086b0195 100644 --- a/dts/arm/silabs/efr32mg24b310f1536im48.dtsi +++ b/dts/arm/silabs/efr32mg24b310f1536im48.dtsi @@ -16,11 +16,9 @@ compatible = "silabs,efr32mg24b310f1536im48", "silabs,efr32mg24", "silabs,efr32", "simple-bus"; - - flash-controller@50030000 { - flash0: flash@0 { - reg = <0 DT_SIZE_K(1536)>; - }; - }; }; }; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1536)>; +}; diff --git a/dts/arm/silabs/efr32xg23.dtsi b/dts/arm/silabs/efr32xg23.dtsi new file mode 100644 index 0000000000000..cdf33f4e5b7d6 --- /dev/null +++ b/dts/arm/silabs/efr32xg23.dtsi @@ -0,0 +1,500 @@ +/* + * Copyright (c) 2024 Yishai Jaffe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/ { + chosen { + zephyr,flash-controller = &msc; + zephyr,entropy = &se; + }; + + clocks { + hfxort: hfxort { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfxo>; + }; + hfrcodpllrt: hfrcodpllrt { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + sysclk: sysclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + hclk: hclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sysclk>; + /* Divider 1, 2, 4, 8, or 16 */ + clock-div = <1>; + }; + pclk: pclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hclk>; + /* Divider 1 or 2 */ + clock-div = <2>; + }; + lspclk: lspclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&pclk>; + /* Fixed divider of 2 */ + clock-div = <2>; + }; + hclkdiv1024: hclkdiv1024 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hclk>; + /* Fixed divider of 1024 */ + clock-div = <1024>; + }; + traceclk: traceclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sysclk>; + /* Divider 1, 2 or 4 */ + clock-div = <1>; + }; + em01grpaclk: em01grpaclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + em01grpcclk: em01grpcclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + iadcclk: iadcclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&em01grpaclk>; + }; + lesensehfclk: lesensehfclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&fsrco>; + }; + em23grpaclk: em23grpaclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + em4grpaclk: em4grpaclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + sysrtcclk: sysrtcclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + wdog0clk: wdog0clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + wdog1clk: wdog1clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + lcdclk: lcdclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + pcnt0clk: pcnt0clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&em23grpaclk>; + }; + eusart0clk: eusart0clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&em01grpcclk>; + }; + systickclk: systickclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hclk>; + }; + vdac0clk: vdac0clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&em01grpaclk>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m33"; + reg = <0>; + cpu-power-states = <&pstate_em1 &pstate_em2 &pstate_em3>; + /* + * The minimum residency and exit latency is + * managed by sl_power_manager on S2 devices. + */ + }; + + power-states { + /* + * EM1 is a basic "CPU WFI idle", all high-freq clocks remain + * enabled. + */ + pstate_em1: em1 { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + /* HFXO remains active */ + }; + + /* + * EM2 is a deepsleep with HF clocks disabled by HW, voltages + * scaled down, etc. + */ + pstate_em2: em2 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + }; + + /* + * EM3 seems to be exactly the same as EM2 except that + * LFXO & LFRCO should be disabled, so you must use ULFRCO + * as BURTC clock for the system to not lose track of time and + * wake up. + */ + pstate_em3: em3 { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + }; + }; + }; + + sram0: memory@20000000 { + device_type = "memory"; + compatible = "mmio-sram"; + }; + + soc { + cmu: clock@50008000 { + compatible = "silabs,series-clock"; + reg = <0x50008000 0x4000>; + interrupts = <48 0>; + interrupt-names = "cmu"; + status = "okay"; + #clock-cells = <2>; + }; + + fsrco: fsrco@50018000 { + #clock-cells = <0>; + compatible = "fixed-clock"; + reg = <0x50018000 0x4000>; + clock-frequency = ; + }; + + clk_hfxo: hfxo: hfxo@5a004000 { + #clock-cells = <0>; + compatible = "silabs,hfxo"; + reg = <0x5a004000 0x4000>; + interrupts = <45 0>; + interrupt-names = "hfxo"; + clock-frequency = ; + ctune = <140>; + precision = <50>; + status = "disabled"; + }; + + lfxo: lfxo@50020000 { + #clock-cells = <0>; + compatible = "silabs,series2-lfxo"; + reg = <0x50020000 0x4000>; + clock-frequency = <32768>; + ctune = <63>; + precision = <50>; + timeout = <4096>; + status = "disabled"; + }; + + hfrcodpll: hfrcodpll@50010000 { + #clock-cells = <0>; + compatible = "silabs,series2-hfrcodpll"; + reg = <0x50010000 0x4000>; + clock-frequency = ; + }; + + hfrcoem23: hfrcoem23@5a000000 { + #clock-cells = <0>; + compatible = "silabs,series2-hfrcoem23"; + reg = <0x5a000000 0x4000>; + clock-frequency = ; + }; + + lfrco: lfrco@50024000 { + #clock-cells = <0>; + compatible = "silabs,series2-lfrco"; + reg = <0x50024000 0x4000>; + clock-frequency = <32768>; + }; + + ulfrco: ulfrco@50028000 { + #clock-cells = <0>; + compatible = "fixed-clock"; + reg = <0x50028000 0x4000>; + clock-frequency = <1000>; + }; + + clkin0: clkin0@5003c49c { + #clock-cells = <0>; + compatible = "fixed-clock"; + reg = <0x5003c49c 0x4>; + clock-frequency = ; + }; + + msc: flash-controller@50030000 { + compatible = "silabs,gecko-flash-controller"; + reg = <0x50030000 0x4000>; + interrupts = <51 0>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@8000000 { + compatible = "soc-nv-flash"; + write-block-size = <4>; + erase-block-size = <8192>; + }; + }; + + usart0: usart@5005c000 { + compatible = "silabs,usart-uart"; + reg = <0x5005C000 0x4000>; + interrupts = <9 0>, <10 0>; + interrupt-names = "rx", "tx"; + clocks = <&cmu CLOCK_USART0 CLOCK_BRANCH_PCLK>; + status = "disabled"; + }; + + eusart0: eusart@5b010000 { + compatible = "silabs,eusart-spi"; + reg = <0x5B010000 0x4000>; + interrupts = <11 0>, <12 0>; + interrupt-names = "rx", "tx"; + clocks = <&cmu CLOCK_EUSART0 CLOCK_BRANCH_EUSART0CLK>; + status = "disabled"; + }; + + eusart1: eusart@500a0000 { + compatible = "silabs,eusart-spi"; + reg = <0x500A0000 0x4000>; + interrupts = <13 0>, <14 0>; + interrupt-names = "rx", "tx"; + clocks = <&cmu CLOCK_EUSART1 CLOCK_BRANCH_EM01GRPCCLK>; + status = "disabled"; + }; + + eusart2: eusart@500a4000 { + compatible = "silabs,eusart-spi"; + reg = <0x500A4000 0x4000>; + interrupts = <15 0>, <16 0>; + interrupt-names = "rx", "tx"; + clocks = <&cmu CLOCK_EUSART2 CLOCK_BRANCH_EM01GRPCCLK>; + status = "disabled"; + }; + + burtc0: burtc@50064000 { + compatible = "silabs,gecko-burtc"; + reg = <0x50064000 0x4000>; + interrupts = <18 0>; + clocks = <&cmu CLOCK_BURTC CLOCK_BRANCH_EM4GRPACLK>; + status = "disabled"; + }; + + se: semailbox@5c000000 { + compatible = "silabs,gecko-semailbox"; + reg = <0x5c000000 0x80>; + interrupts = <66 3>, <67 3>, <68 3>; + interrupt-names = "SETAMPERHOST", "SEMBRX", "SEMBTX"; + status = "disabled"; + }; + + i2c0: i2c@5b000000 { + compatible = "silabs,gecko-i2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x5b000000 0x4000>; + interrupts = <28 0>; + clocks = <&cmu CLOCK_I2C0 CLOCK_BRANCH_LSPCLK>; + status = "disabled"; + }; + + i2c1: i2c@50068000 { + compatible = "silabs,gecko-i2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x50068000 0x4000>; + interrupts = <29 0>; + clocks = <&cmu CLOCK_I2C1 CLOCK_BRANCH_PCLK>; + status = "disabled"; + }; + + sysrtc0: stimer0: sysrtc@500a8000 { + compatible = "silabs,gecko-stimer"; + reg = <0x500a8000 0x4000>; + interrupts = <70 0>, <71 0>; + interrupt-names = "sysrtc_app", "sysrtc_seq"; + clock-frequency = <32768>; + prescaler = <1>; + clocks = <&cmu CLOCK_SYSRTC0 CLOCK_BRANCH_SYSRTCCLK>; + status = "disabled"; + }; + + gpio: gpio@5003c000 { + compatible = "silabs,gecko-gpio"; + reg = <0x5003c000 0x4000>; + interrupts = <27 2>, <26 2>; + interrupt-names = "GPIO_EVEN", "GPIO_ODD"; + clocks = <&cmu CLOCK_GPIO CLOCK_BRANCH_PCLK>; + + ranges; + #address-cells = <1>; + #size-cells = <1>; + + gpioa: gpio@5003c030 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003c030 0x30>; + peripheral-id = <0>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiob: gpio@5003c060 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003c060 0x30>; + peripheral-id = <1>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpioc: gpio@5003c090 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003c090 0x30>; + peripheral-id = <2>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiod: gpio@5003c0C0 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003c0C0 0x30>; + peripheral-id = <3>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + }; + + pinctrl: pin-controller@5003c440 { + compatible = "silabs,dbus-pinctrl"; + reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>; + reg-names = "dbus", "abus"; + }; + + dma0: dma@50040000{ + compatible = "silabs,ldma"; + reg = <0x50040000 0x4000>; + interrupts = <22 0>; + #dma-cells = <1>; + dma_channels = <8>; + status = "disabled"; + }; + + wdog0: wdog@5b004000 { + compatible = "silabs,gecko-wdog"; + reg = <0x5b004000 0x4000>; + peripheral-id = <0>; + interrupts = <43 0>; + clocks = <&cmu CLOCK_WDOG0 CLOCK_BRANCH_WDOG0CLK>; + status = "disabled"; + }; + + wdog1: wdog@5b008000 { + compatible = "silabs,gecko-wdog"; + reg = <0x5b008000 0x4000>; + peripheral-id = <1>; + interrupts = <44 0>; + clocks = <&cmu CLOCK_WDOG1 CLOCK_BRANCH_WDOG1CLK>; + status = "disabled"; + }; + + adc0: adc@59004000 { + compatible = "silabs,gecko-iadc"; + reg = <0x59004000 0x4000>; + interrupts = <50 0>; + clocks = <&cmu CLOCK_IADC0 CLOCK_BRANCH_IADCCLK>; + status = "disabled"; + #io-channel-cells = <1>; + }; + + dcdc: dcdc@50094000 { + compatible = "silabs,series2-dcdc"; + reg = <0x50094000 0x4000>; + interrupts = <54 0>; + status = "disabled"; + }; + + acmp0: acmp@59008000 { + compatible = "silabs,acmp"; + reg = <0x59008000 0x4000>; + interrupts = <41 0>; + clocks = <&cmu CLOCK_ACMP0 CLOCK_BRANCH_EM01GRPACLK>; + status = "disabled"; + }; + + radio: radio@b0000000 { + compatible = "silabs,series2-radio"; + reg = <0xb0000000 0x1000000>; + interrupts = <31 0>, <32 0>, <33 0>, <34 0>, <35 0>, <36 0>, + <37 0>, <38 0>, <39 0>, <40 0>, <74 0>, <75 0>; + interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", + "rac_rsm", "rac_seq", "hostmailbox", "synth", + "rfeca0", "rfeca1"; + pa-initial-power-dbm = <10>; + pa-ramp-time-us = <10>; + pa-voltage-mv = <3300>; + pa-subghz = "highest"; + }; + }; + + hwinfo: hwinfo { + compatible = "silabs,gecko-hwinfo"; + status = "disabled"; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/silabs/efr32zg23b020f512im48.dtsi b/dts/arm/silabs/efr32zg23b020f512im48.dtsi new file mode 100644 index 0000000000000..cd1d708e91be8 --- /dev/null +++ b/dts/arm/silabs/efr32zg23b020f512im48.dtsi @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Yishai Jaffe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(64)>; + }; + + soc { + compatible = "silabs,efr32zg23b020f512im48", + "silabs,efr32zg23", "silabs,efr32", + "simple-bus"; + }; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(512)>; +}; diff --git a/dts/arm/silabs/siwg917.dtsi b/dts/arm/silabs/siwg917.dtsi new file mode 100644 index 0000000000000..dfa80e4cde397 --- /dev/null +++ b/dts/arm/silabs/siwg917.dtsi @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2024-2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + chosen { + zephyr,entropy = &rng0; + zephyr,flash = &flash0; + zephyr,flash-controller = &flashctrl0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m4f"; + reg = <0>; + }; + }; + + sram0: memory@0 { + compatible = "mmio-sram"; + reg = <0x00000000 DT_SIZE_K(191)>; + }; + + bt_hci0: bt_hci { + compatible = "silabs,siwx91x-bt-hci"; + status = "disabled"; + }; + + wifi0: wifi { + compatible = "silabs,siwx91x-wifi"; + status = "disabled"; + }; + + soc { + clock0: clock@46000000 { + compatible = "silabs,siwx91x-clock"; + reg = <0x46000000 0x100>, + <0x46000800 0x100>, + <0x24041400 0x100>, + <0x24048000 0x200>; + #clock-cells = <1>; + status = "okay"; + }; + + pinctrl0: pinctrl@46130000 { + compatible = "silabs,siwx91x-pinctrl"; + reg = <0x46130000 0x1000>; + }; + + flashctrl0: flash-controller@12000000 { + compatible = "silabs,siwx91x-flash-controller"; + reg = <0x12000000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@8202000 { + compatible = "soc-nv-flash"; + write-block-size = <1>; + erase-block-size = <4096>; + }; + }; + + ulpuart: uart@24041800 { + compatible = "ns16550"; + reg = <0x24041800 0x1000>; + interrupts = <12 0>; + reg-shift = <2>; + clocks = <&clock0 SIWX91X_CLK_ULP_UART>; + current-speed = <115200>; + status = "disabled"; + }; + + uart1: uart@44000000 { + compatible = "ns16550"; + reg = <0x44000000 0x1000>; + interrupts = <38 0>; + reg-shift = <2>; + clocks = <&clock0 SIWX91X_CLK_UART1>; + current-speed = <115200>; + status = "disabled"; + }; + + uart2: uart@45020000 { + compatible = "ns16550"; + reg = <0x45020000 0x1000>; + interrupts = <39 0>; + reg-shift = <2>; + clocks = <&clock0 SIWX91X_CLK_UART2>; + current-speed = <115200>; + status = "disabled"; + }; + + rng0: rng@45090000 { + compatible = "silabs,siwx91x-rng"; + reg = <0x45090000 0x8>; + }; + + egpio0: egpio@46130000 { + compatible = "silabs,siwx91x-gpio"; + reg = <0x46130000 0x1260>; + interrupts = <52 0>, <53 0>, <54 0>, <55 0>, + <56 0>, <57 0>, <58 0>, <59 0>; + interrupt-names = "PIN0", "PIN1", "PIN2", "PIN3", + "PIN4", "PIN5", "PIN6", "PIN7"; + + #address-cells = <1>; + #size-cells = <0>; + + gpioa: gpio@0 { + compatible = "silabs,siwx91x-gpio-port"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + gpio-reserved-ranges = <0 6>; + silabs,pads = [ + ff ff ff ff ff ff 01 02 03 04 05 06 07 ff ff 08 + ]; + status = "okay"; + }; + + gpiob: gpio@1 { + compatible = "silabs,siwx91x-gpio-port"; + reg = <1>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + silabs,pads = [ + ff ff ff ff ff ff ff ff ff 00 00 00 00 00 00 09 + ]; + status = "okay"; + }; + + gpioc: gpio@2 { + compatible = "silabs,siwx91x-gpio-port"; + reg = <2>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + silabs,pads = [ + 09 09 09 ff ff ff ff ff ff ff ff ff ff ff 0a 0b + ]; + status = "okay"; + }; + + gpiod: gpio@3 { + compatible = "silabs,siwx91x-gpio-port"; + reg = <3>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <10>; + silabs,pads = [ + 0c 0d 0e 0f 10 11 12 13 14 15 ff ff ff ff ff ff + ]; + status = "okay"; + }; + }; + + egpio1: egpio@2404c000 { + compatible = "silabs,siwx91x-gpio"; + reg = <0x2404C000 0x1260>; + interrupts = <18 0>; + interrupt-names = "ULP"; + silabs,ulp; + + #address-cells = <1>; + #size-cells = <0>; + + ulpgpio: ulpgpio@0 { + compatible = "silabs,siwx91x-gpio-port"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <12>; + gpio-reserved-ranges = <3 1>; + silabs,pads = [ + 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 ff ff ff ff + ]; + status = "okay"; + }; + }; + + uulpgpio: uulpgpio@24048600 { + compatible = "silabs,siwx91x-gpio-uulp"; + reg = <0x24048600 0x30>, <0x12080000 0x18>; + reg-names = "ret", "int"; + interrupts = <21 0>; + interrupt-names = "UULP"; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + status = "okay"; + }; + + ulpi2c: i2c@24040000 { + compatible = "snps,designware-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x24040000 0x100>; + interrupts = <13 0>; + interrupt-names = "i2c2"; + clocks = <&clock0 SIWX91X_CLK_ULP_I2C>; + status = "disabled"; + }; + + i2c0: i2c@44010000 { + compatible = "snps,designware-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44010000 0x100>; + interrupts = <42 0>; + interrupt-names = "i2c0"; + clocks = <&clock0 SIWX91X_CLK_I2C0>; + status = "disabled"; + }; + + i2c1: i2c@47040000 { + compatible = "snps,designware-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x47040000 0x100>; + interrupts = <61 0>; + interrupt-names = "i2c1"; + clocks = <&clock0 SIWX91X_CLK_I2C1>; + status = "disabled"; + }; + + dma0: dma@44030000 { + compatible = "silabs,siwx91x-dma"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44030000 0x82C>; + interrupts = <33 0>; + interrupt-names = "dma0"; + clocks = <&clock0 SIWX91X_CLK_DMA0>; + silabs,sram-desc-addr = <0x2fc00>; + #dma-cells = < 1>; + dma-channels = <32>; + status = "disabled"; + }; + + ulpdma: dma@24078000 { + compatible = "silabs,siwx91x-dma"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x24078000 0x82C>; + interrupts = <10 0>; + interrupt-names = "ulpdma"; + clocks = <&clock0 SIWX91X_CLK_ULP_DMA>; + silabs,sram-desc-addr = <0x24061c00>; + #dma-cells = < 1>; + dma-channels = <12>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <6>; +}; diff --git a/dts/arm/silabs/siwg917m111mgtba.dtsi b/dts/arm/silabs/siwg917m111mgtba.dtsi new file mode 100644 index 0000000000000..b2c7d3a1b5cd2 --- /dev/null +++ b/dts/arm/silabs/siwg917m111mgtba.dtsi @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + compatible = "silabs,siwg917m111mgtba", "silabs,siwg917", + "silabs,siwx91x", "simple-bus"; + }; +}; + +&flash0 { + reg = <0x08202000 DT_SIZE_K(2048-8)>; +}; diff --git a/dts/arm/silabs/xg29/efr32bg29b140f1024im40.dtsi b/dts/arm/silabs/xg29/efr32bg29b140f1024im40.dtsi new file mode 100644 index 0000000000000..fd458ea3c4e31 --- /dev/null +++ b/dts/arm/silabs/xg29/efr32bg29b140f1024im40.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + compatible = "silabs,efr32bg29b140f1024im40", "silabs,efr32bg29", "silabs,xg29", + "silabs,efr32", "simple-bus"; + }; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1024)>; +}; diff --git a/dts/arm/silabs/xg29/efr32bg29b220f1024cj45.dtsi b/dts/arm/silabs/xg29/efr32bg29b220f1024cj45.dtsi new file mode 100644 index 0000000000000..ec744a27f35b7 --- /dev/null +++ b/dts/arm/silabs/xg29/efr32bg29b220f1024cj45.dtsi @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + soc { + compatible = "silabs,efr32bg29b220f1024cj45", "silabs,efr32bg29", "silabs,xg29", + "silabs,efr32", "simple-bus"; + }; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1024)>; +}; + +&dcdc { + regulator-boot-on; + regulator-initial-mode = ; + regulator-init-microvolt = <1800000>; + status = "okay"; +}; diff --git a/dts/arm/silabs/xg29/efr32bg29b221f1024cj45.dtsi b/dts/arm/silabs/xg29/efr32bg29b221f1024cj45.dtsi new file mode 100644 index 0000000000000..b3fea2edd7916 --- /dev/null +++ b/dts/arm/silabs/xg29/efr32bg29b221f1024cj45.dtsi @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + soc { + compatible = "silabs,efr32bg29b221f1024cj45", "silabs,efr32bg29", "silabs,xg29", + "silabs,efr32", "simple-bus"; + }; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(192)>; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1024)>; +}; + +&dcdc { + regulator-boot-on; + regulator-initial-mode = ; + regulator-init-microvolt = <1800000>; + status = "okay"; +}; diff --git a/dts/arm/silabs/xg29/efr32bg29b230f1024cm40.dtsi b/dts/arm/silabs/xg29/efr32bg29b230f1024cm40.dtsi new file mode 100644 index 0000000000000..0acadabcbdc3f --- /dev/null +++ b/dts/arm/silabs/xg29/efr32bg29b230f1024cm40.dtsi @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + soc { + compatible = "silabs,efr32bg29b230f1024cm40", "silabs,efr32bg29", "silabs,xg29", + "silabs,efr32", "simple-bus"; + }; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1024)>; +}; + +&dcdc { + regulator-boot-on; + regulator-initial-mode = ; + regulator-init-microvolt = <1800000>; + status = "okay"; +}; diff --git a/dts/arm/silabs/xg29/efr32mg29b140f1024im40.dtsi b/dts/arm/silabs/xg29/efr32mg29b140f1024im40.dtsi new file mode 100644 index 0000000000000..84fdecb94b28f --- /dev/null +++ b/dts/arm/silabs/xg29/efr32mg29b140f1024im40.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + compatible = "silabs,efr32mg29b140f1024im40", "silabs,efr32mg29", "silabs,xg29", + "silabs,efr32", "simple-bus"; + }; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1024)>; +}; diff --git a/dts/arm/silabs/xg29/efr32mg29b230f1024cm40.dtsi b/dts/arm/silabs/xg29/efr32mg29b230f1024cm40.dtsi new file mode 100644 index 0000000000000..60e2d9f74659e --- /dev/null +++ b/dts/arm/silabs/xg29/efr32mg29b230f1024cm40.dtsi @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + soc { + compatible = "silabs,efr32mg29b230f1024cm40", "silabs,efr32mg29", "silabs,xg29", + "silabs,efr32", "simple-bus"; + }; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +&flash0 { + reg = <0x08000000 DT_SIZE_K(1024)>; +}; + +&dcdc { + regulator-boot-on; + regulator-initial-mode = ; + regulator-init-microvolt = <1800000>; + status = "okay"; +}; diff --git a/dts/arm/silabs/xg29/xg29.dtsi b/dts/arm/silabs/xg29/xg29.dtsi new file mode 100644 index 0000000000000..1d3a4cd911581 --- /dev/null +++ b/dts/arm/silabs/xg29/xg29.dtsi @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/ { + chosen { + zephyr,flash-controller = &msc; + zephyr,entropy = &se; + }; + + clocks { + hfxort: hfxort { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfxo>; + }; + + hfrcodpllrt: hfrcodpllrt { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + + sysclk: sysclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + + hclk: hclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sysclk>; + /* Divisors 1, 2, 4, 8, 16 allowed */ + clock-div = <1>; + }; + + pclk: pclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hclk>; + /* Divisors 1, 2 allowed */ + clock-div = <2>; + }; + + lspclk: lspclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&pclk>; + /* Fixed divisor of 2 */ + clock-div = <2>; + }; + + hclkdiv1024: hclkdiv1024 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hclk>; + /* Fixed divisor of 1024 */ + clock-div = <1024>; + }; + + traceclk: traceclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&sysclk>; + /* Divisors 1, 2, 3, 4 allowed */ + clock-div = <1>; + }; + + em01grpaclk: em01grpaclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + + em01grpbclk: em01grpbclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + + em01grpcclk: em01grpcclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hfrcodpll>; + }; + + iadcclk: iadcclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&em01grpaclk>; + }; + + em23grpaclk: em23grpaclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + + em4grpaclk: em4grpaclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + + rtccclk: rtccclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + + wdog0clk: wdog0clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&lfrco>; + }; + + systickclk: systickclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&hclk>; + }; + + eusart0clk: eusart0clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&em01grpaclk>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m33"; + reg = <0>; + cpu-power-states = <&pstate_em1 &pstate_em2>; + /* + * The minimum residency and exit latency is + * managed by sl_power_manager on S2 devices. + */ + }; + + power-states { + /* + * EM1 is a basic "CPU WFI idle", all high-freq clocks remain + * enabled. + */ + pstate_em1: em1 { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + /* HFXO remains active */ + }; + + /* + * EM2 is a deepsleep with HF clocks disabled by HW, voltages + * scaled down, etc. + */ + pstate_em2: em2 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + }; + }; + }; + + sram0: memory@20000000 { + device_type = "memory"; + compatible = "mmio-sram"; + }; + + soc { + cmu: clock@50008000 { + compatible = "silabs,series-clock"; + reg = <0x50008000 0x4000>; + interrupts = <52 0>; + interrupt-names = "cmu"; + status = "okay"; + #clock-cells = <2>; + }; + + hfxo: hfxo@5000c000 { + #clock-cells = <0>; + compatible = "silabs,hfxo"; + reg = <0x5000c000 0x4000>; + interrupts = <50 0>; + interrupt-names = "hfxo0"; + clock-frequency = ; + ctune = <140>; + precision = <50>; + status = "disabled"; + }; + + hfrcodpll: hfrcodpll@50010000 { + #clock-cells = <0>; + compatible = "silabs,series2-hfrcodpll"; + reg = <0x50010000 0x4000>; + interrupts = <51 0>, <56 0>; + interrupt-names = "hfrco0", "dpll0"; + clock-frequency = ; + }; + + fsrco: fsrco@50018000 { + #clock-cells = <0>; + compatible = "fixed-clock"; + reg = <0x50018000 0x4000>; + clock-frequency = ; + }; + + lfxo: lfxo@50020000 { + #clock-cells = <0>; + compatible = "silabs,series2-lfxo"; + reg = <0x50020000 0x4000>; + interrupts = <27 0>; + interrupt-names = "lfxo"; + clock-frequency = <32768>; + ctune = <63>; + precision = <50>; + timeout = <4096>; + status = "disabled"; + }; + + lfrco: lfrco@50024000 { + #clock-cells = <0>; + compatible = "silabs,series2-lfrco"; + reg = <0x50024000 0x4000>; + interrupts = <28 0>; + interrupt-names = "lfrco"; + clock-frequency = <32768>; + }; + + ulfrco: ulfrco@50028000 { + #clock-cells = <0>; + compatible = "fixed-clock"; + reg = <0x50028000 0x4000>; + interrupts = <29 0>; + interrupt-names = "ulfrco"; + clock-frequency = <1000>; + }; + + clkin0: clkin0@5003c460 { + #clock-cells = <0>; + compatible = "fixed-clock"; + reg = <0x5003c460 0x4>; + clock-frequency = ; + }; + + msc: flash-controller@50030000 { + compatible = "silabs,gecko-flash-controller"; + reg = <0x50030000 0x4000>; + interrupts = <55 0>; + interrupt-names = "msc"; + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@8000000 { + compatible = "soc-nv-flash"; + write-block-size = <4>; + erase-block-size = <8192>; + }; + }; + + gpio: gpio@5003c000 { + compatible = "silabs,gecko-gpio"; + reg = <0x5003C000 0x440>; + interrupts = <31 0>, <30 0>; + interrupt-names = "GPIO_EVEN", "GPIO_ODD"; + clocks = <&cmu CLOCK_GPIO CLOCK_BRANCH_PCLK>; + ranges; + #address-cells = <1>; + #size-cells = <1>; + + gpioa: gpio@5003c000 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C000 0x30>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiob: gpio@5003c030 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C030 0x30>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpioc: gpio@5003c060 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C060 0x30>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiod: gpio@5003c090 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C090 0x30>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + }; + + pinctrl: pin-controller@5003c440 { + compatible = "silabs,dbus-pinctrl"; + reg = <0x5003c440 0xbc0>, <0x5003c320 0x40>; + reg-names = "dbus", "abus"; + }; + + dma0: dma@40040000{ + compatible = "silabs,ldma"; + reg = <0x40040000 0x4000>; + interrupts = <26 0>; + interrupt-names = "ldma"; + #dma-cells = <1>; + dma_channels = <8>; + status = "disabled"; + }; + + usart0: usart@5005c000 { + compatible = "silabs,usart-uart"; + reg = <0x5005C000 0x400>; + interrupts = <16 0>, <17 0>; + interrupt-names = "rx", "tx"; + clocks = <&cmu CLOCK_USART0 CLOCK_BRANCH_PCLK>; + status = "disabled"; + }; + + usart1: usart@50060000 { + compatible = "silabs,usart-uart"; + reg = <0x50060000 0x400>; + interrupts = <18 0>, <19 0>; + interrupt-names = "rx", "tx"; + clocks = <&cmu CLOCK_USART1 CLOCK_BRANCH_PCLK>; + status = "disabled"; + }; + + burtc0: burtc@50064000 { + compatible = "silabs,gecko-burtc"; + reg = <0x50064000 0x4000>; + interrupts = <23 0>; + interrupt-names = "burtc"; + clocks = <&cmu CLOCK_BURTC CLOCK_BRANCH_EM4GRPACLK>; + status = "disabled"; + }; + + i2c0: i2c@5a010000 { + compatible = "silabs,gecko-i2c"; + clock-frequency = ; + reg = <0x5a010000 0x4000>; + interrupts = <32 0>; + interrupt-names = "i2c0"; + clocks = <&cmu CLOCK_I2C0 CLOCK_BRANCH_LSPCLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@50068000 { + compatible = "silabs,gecko-i2c"; + clock-frequency = ; + reg = <0x50068000 0x4000>; + interrupts = <33 0>; + interrupt-names = "i2c1"; + clocks = <&cmu CLOCK_I2C1 CLOCK_BRANCH_PCLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + dcdc: dcdc@50094000 { + compatible = "silabs,series2-dcdc"; + reg = <0x50094000 0x4000>; + interrupts = <8 0>; + interrupt-names = "dcdc"; + status = "disabled"; + }; + + eusart0: eusart@5a040000 { + compatible = "silabs,eusart-spi"; + reg = <0x5A040000 0x4000>; + interrupts = <20 0>, <21 0>; + interrupt-names = "rx", "tx"; + clocks = <&cmu CLOCK_EUSART0 CLOCK_BRANCH_EUSART0CLK>; + status = "disabled"; + }; + + eusart1: eusart@500b4000 { + compatible = "silabs,eusart-spi"; + reg = <0x500B4000 0x4000>; + interrupts = <68 0>, <69 0>; + interrupt-names = "rx", "tx"; + clocks = <&cmu CLOCK_EUSART1 CLOCK_BRANCH_EM01GRPCCLK>; + status = "disabled"; + }; + + rtcc0: rtcc@58000000 { + compatible = "silabs,gecko-stimer"; + reg = <0x58000000 0x4000>; + interrupts = <15 0>; + interrupt-names = "rtcc"; + clocks = <&cmu CLOCK_RTCC CLOCK_BRANCH_RTCCCLK>; + clock-frequency = <32768>; + prescaler = <1>; + status = "disabled"; + }; + + wdog0: wdog@58018000 { + compatible = "silabs,gecko-wdog"; + reg = <0x58018000 0x4000>; + peripheral-id = <0>; + interrupts = <49 0>; + interrupt-names = "wdog0"; + clocks = <&cmu CLOCK_WDOG0 CLOCK_BRANCH_WDOG0CLK>; + status = "disabled"; + }; + + adc0: adc@5a004000 { + compatible = "silabs,gecko-iadc"; + reg = <0x5a004000 0x4000>; + interrupts = <54 0>; + interrupt-names = "iadc0"; + clocks = <&cmu CLOCK_IADC0 CLOCK_BRANCH_IADCCLK>; + status = "disabled"; + #io-channel-cells = <1>; + }; + + acmp0: acmp@5a008000 { + compatible = "silabs,acmp"; + reg = <0x5a008000 0x4000>; + interrupts = <48 0>; + clocks = <&cmu CLOCK_ACMP0 CLOCK_BRANCH_EM01GRPACLK>; + status = "disabled"; + }; + + se: semailbox@4c000000 { + compatible = "silabs,gecko-semailbox"; + reg = <0x4c000000 0x1000>; + interrupts = <0 3>, <1 3>, <2 3>; + interrupt-names = "SETAMPERHOST", "SEMBRX", "SEMBTX"; + status = "disabled"; + }; + + radio: radio@b0000000 { + compatible = "silabs,series2-radio"; + reg = <0xb0000000 0x1000000>; + interrupts = <36 0>, <37 0>, <38 0>, <39 0>, <40 0>, <41 0>, + <42 0>, <43 0>, <44 0>, <45 0>, <46 0>, <47 0>; + interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", + "rac_rsm", "rac_seq", "rdmailbox", "rfsense", "synth", + "prortc"; + pa-initial-power-dbm = <10>; + pa-ramp-time-us = <2>; + pa-voltage-mv = <3300>; + pa-2p4ghz = "highest"; + + bt_hci_silabs: bt_hci_silabs { + compatible = "silabs,bt-hci-efr32"; + status = "disabled"; + }; + }; + }; + + hwinfo: hwinfo { + compatible = "silabs,series2-hwinfo"; + status = "disabled"; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/st/c0/stm32c0.dtsi b/dts/arm/st/c0/stm32c0.dtsi index 5c474e4a04986..3014abd7b5ffe 100644 --- a/dts/arm/st/c0/stm32c0.dtsi +++ b/dts/arm/st/c0/stm32c0.dtsi @@ -82,7 +82,7 @@ soc { flash: flash-controller@40022000 { - compatible = "st,stm32-flash-controller"; + compatible = "st,stm32-flash-controller" , "st,stm32g0-flash-controller"; reg = <0x40022000 0x400>; interrupts = <3 0>; clocks = <&rcc STM32_CLOCK(AHB1, 8U)>; @@ -325,7 +325,8 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 161>; num-sampling-time-common-channels = <2>; - st,adc-sequencer = ; + st,adc-sequencer = "NOT_FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; dma1: dma@40020000 { diff --git a/dts/arm/st/c0/stm32c071.dtsi b/dts/arm/st/c0/stm32c071.dtsi new file mode 100644 index 0000000000000..dac77befe50cb --- /dev/null +++ b/dts/arm/st/c0/stm32c071.dtsi @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + compatible = "st,stm32c071", "st,stm32c0", "simple-bus"; + + timers2: timers@40000000 { + compatible = "st,stm32-timers"; + reg = <0x40000000 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 0U)>; + resets = <&rctl STM32_RESET(APB1L, 0U)>; + interrupts = <15 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + i2c2: i2c@40005800 { + compatible = "st,stm32-i2c-v2"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40005800 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 22U)>; + interrupts = <24 0>; + interrupt-names = "global"; + status = "disabled"; + }; + + spi2: spi@40003800 { + compatible = "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40003800 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 14U)>; + interrupts = <26 0>; + interrupt-names = "global"; + status = "disabled"; + }; + + dma1: dma@40020000 { + interrupts = <9 0 10 0 10 0 11 0 11 0>; + dma-requests = <5>; + }; + + dmamux1: dmamux@40020800 { + dma-channels = <5>; + }; + }; +}; diff --git a/dts/arm/st/c0/stm32c071X8.dtsi b/dts/arm/st/c0/stm32c071X8.dtsi new file mode 100644 index 0000000000000..0a9d4001f5d6a --- /dev/null +++ b/dts/arm/st/c0/stm32c071X8.dtsi @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(24)>; + }; + + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(64)>; + }; + }; + }; +}; diff --git a/dts/arm/st/c0/stm32c071Xb.dtsi b/dts/arm/st/c0/stm32c071Xb.dtsi new file mode 100644 index 0000000000000..909b588d1dc88 --- /dev/null +++ b/dts/arm/st/c0/stm32c071Xb.dtsi @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(24)>; + }; + + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(128)>; + }; + }; + }; +}; diff --git a/dts/arm/st/f0/stm32f0.dtsi b/dts/arm/st/f0/stm32f0.dtsi index 96b9e907b6549..e332de1e3feae 100644 --- a/dts/arm/st/f0/stm32f0.dtsi +++ b/dts/arm/st/f0/stm32f0.dtsi @@ -348,7 +348,8 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 8 14 29 42 56 72 240>; num-sampling-time-common-channels = <1>; - st,adc-sequencer = ; + st,adc-sequencer = "NOT_FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; dma1: dma@40020000 { diff --git a/dts/arm/st/f1/stm32f1.dtsi b/dts/arm/st/f1/stm32f1.dtsi index 5e5077069b697..1f1eca739bc77 100644 --- a/dts/arm/st/f1/stm32f1.dtsi +++ b/dts/arm/st/f1/stm32f1.dtsi @@ -348,7 +348,8 @@ #io-channel-cells = <1>; resolutions = ; sampling-times = <2 8 14 29 42 56 72 240>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; dma1: dma@40020000 { diff --git a/dts/arm/st/f1/stm32f105.dtsi b/dts/arm/st/f1/stm32f105.dtsi index d4f05930a80e2..053ef6b2db60d 100644 --- a/dts/arm/st/f1/stm32f105.dtsi +++ b/dts/arm/st/f1/stm32f105.dtsi @@ -49,7 +49,7 @@ interrupts = <63 0>, <64 0>, <65 0>, <66 0>; interrupt-names = "TX", "RX0", "RX1", "SCE"; /* also enabling clock for can1 (master instance) */ - clocks = <&rcc STM32_CLOCK(APB1, 26U)>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x06000000>; status = "disabled"; }; diff --git a/dts/arm/st/f2/stm32f2.dtsi b/dts/arm/st/f2/stm32f2.dtsi index a00519dd4dcc4..fda619ece4b2a 100644 --- a/dts/arm/st/f2/stm32f2.dtsi +++ b/dts/arm/st/f2/stm32f2.dtsi @@ -374,8 +374,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 58 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; dma1: dma@40026000 { diff --git a/dts/arm/st/f3/stm32f302.dtsi b/dts/arm/st/f3/stm32f302.dtsi index de7a1c202b03d..05afa351c473b 100644 --- a/dts/arm/st/f3/stm32f302.dtsi +++ b/dts/arm/st/f3/stm32f302.dtsi @@ -114,7 +114,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <2 3 5 8 20 62 182 602>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; }; diff --git a/dts/arm/st/f3/stm32f303.dtsi b/dts/arm/st/f3/stm32f303.dtsi index 9122ee4cf01bc..e59b366de2878 100644 --- a/dts/arm/st/f3/stm32f303.dtsi +++ b/dts/arm/st/f3/stm32f303.dtsi @@ -153,7 +153,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <2 3 5 8 20 62 182 602>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; adc2: adc@50000100 { @@ -169,7 +170,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <2 3 5 8 20 62 182 602>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; }; diff --git a/dts/arm/st/f3/stm32f334.dtsi b/dts/arm/st/f3/stm32f334.dtsi index 77786fada02e0..84211d513fb95 100644 --- a/dts/arm/st/f3/stm32f334.dtsi +++ b/dts/arm/st/f3/stm32f334.dtsi @@ -40,7 +40,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <2 3 5 8 20 62 182 602>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; rtc@40002800 { diff --git a/dts/arm/st/f3/stm32f373.dtsi b/dts/arm/st/f3/stm32f373.dtsi index b06356312d120..231aeedb26837 100644 --- a/dts/arm/st/f3/stm32f373.dtsi +++ b/dts/arm/st/f3/stm32f373.dtsi @@ -193,7 +193,8 @@ #io-channel-cells = <1>; resolutions = ; sampling-times = <2 8 14 29 42 56 72 240>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; rtc@40002800 { diff --git a/dts/arm/st/f4/stm32f4.dtsi b/dts/arm/st/f4/stm32f4.dtsi index 4a85aabc5ada8..e05aaf7b09017 100644 --- a/dts/arm/st/f4/stm32f4.dtsi +++ b/dts/arm/st/f4/stm32f4.dtsi @@ -551,8 +551,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; dma1: dma@40026000 { @@ -592,7 +593,7 @@ ts-cal1-temp = <30>; ts-cal2-temp = <110>; ts-cal-vrefanalog = <3300>; - io-channels = <&adc1 18>; + io-channels = <&adc1 16>; status = "disabled"; }; diff --git a/dts/arm/st/f4/stm32f401.dtsi b/dts/arm/st/f4/stm32f401.dtsi index eda9b1e4a9824..e113144d2e1ee 100644 --- a/dts/arm/st/f4/stm32f401.dtsi +++ b/dts/arm/st/f4/stm32f401.dtsi @@ -55,8 +55,8 @@ reg = <0x40003800 0x400>; clocks = <&rcc STM32_CLOCK(APB1, 14U)>; interrupts = <36 5>; - dmas = <&dma1 4 0 0x400 0x3 - &dma1 3 0 0x400 0x3>; + dmas = <&dma1 4 0 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma1 3 0 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -68,8 +68,8 @@ reg = <0x40003c00 0x400>; clocks = <&rcc STM32_CLOCK(APB1, 15U)>; interrupts = <51 5>; - dmas = <&dma1 5 0 0x400 0x3 - &dma1 0 0 0x400 0x3>; + dmas = <&dma1 5 0 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma1 0 0 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; diff --git a/dts/arm/st/f4/stm32f405.dtsi b/dts/arm/st/f4/stm32f405.dtsi index 9dbc4af8c57ef..76a19b808dae7 100644 --- a/dts/arm/st/f4/stm32f405.dtsi +++ b/dts/arm/st/f4/stm32f405.dtsi @@ -220,7 +220,7 @@ interrupts = <63 0>, <64 0>, <65 0>, <66 0>; interrupt-names = "TX", "RX0", "RX1", "SCE"; /* also enabling clock for can1 (master instance) */ - clocks = <&rcc STM32_CLOCK(APB1, 26U)>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x06000000>; master-can-reg = <0x40006400>; status = "disabled"; }; @@ -253,8 +253,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; adc3: adc@40012200 { @@ -269,8 +270,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; dac1: dac@40007400 { diff --git a/dts/arm/st/f4/stm32f410.dtsi b/dts/arm/st/f4/stm32f410.dtsi index 9593affa63aef..0f149a98e8cc0 100644 --- a/dts/arm/st/f4/stm32f410.dtsi +++ b/dts/arm/st/f4/stm32f410.dtsi @@ -42,8 +42,8 @@ reg = <0x40013000 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 12U)>; interrupts = <35 5>; - dmas = <&dma2 3 3 0x400 0x3 - &dma2 2 3 0x400 0x3>; + dmas = <&dma2 3 3 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma2 2 3 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -55,8 +55,8 @@ reg = <0x40003800 0x400>; clocks = <&rcc STM32_CLOCK(APB1, 14U)>; interrupts = <36 5>; - dmas = <&dma1 4 0 0x400 0x3 - &dma1 3 0 0x400 0x3>; + dmas = <&dma1 4 0 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma1 3 0 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -68,8 +68,8 @@ reg = <0x40015000 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 20U)>; interrupts = <85 5>; - dmas = <&dma2 6 7 0x400 0x3 - &dma2 5 7 0x400 0x3>; + dmas = <&dma2 6 7 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma2 5 7 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -106,8 +106,4 @@ status = "disabled"; }; }; - - die_temp: dietemp { - io-channels = <&adc1 18>; - }; }; diff --git a/dts/arm/st/f4/stm32f411.dtsi b/dts/arm/st/f4/stm32f411.dtsi index 846b5d6b74eb2..b0dfddd40ef67 100644 --- a/dts/arm/st/f4/stm32f411.dtsi +++ b/dts/arm/st/f4/stm32f411.dtsi @@ -7,6 +7,14 @@ #include / { + clocks { + plli2s: plli2s { + #clock-cells = <0>; + compatible = "st,stm32f411-plli2s-clock"; + status = "disabled"; + }; + }; + soc { compatible = "st,stm32f411", "st,stm32f4", "simple-bus"; @@ -27,8 +35,8 @@ reg = <0x40013000 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 12U)>; interrupts = <35 5>; - dmas = <&dma2 3 3 0x400 0x3 - &dma2 2 3 0x400 0x3>; + dmas = <&dma2 3 3 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma2 2 3 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -40,8 +48,8 @@ reg = <0x40013400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 13U)>; interrupts = <84 5>; - dmas = <&dma2 1 4 0x400 0x3 - &dma2 0 4 0x400 0x3>; + dmas = <&dma2 1 4 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma2 0 4 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -53,8 +61,8 @@ reg = <0x40015000 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 20U)>; interrupts = <85 5>; - dmas = <&dma2 6 7 0x400 0x3 - &dma2 5 7 0x400 0x3>; + dmas = <&dma2 6 7 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma2 5 7 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; diff --git a/dts/arm/st/f4/stm32f412.dtsi b/dts/arm/st/f4/stm32f412.dtsi index d250d167259d8..899a9325bfdbe 100644 --- a/dts/arm/st/f4/stm32f412.dtsi +++ b/dts/arm/st/f4/stm32f412.dtsi @@ -13,7 +13,14 @@ clocks { plli2s: plli2s { #clock-cells = <0>; - compatible = "st,stm32f412-plli2s-clock"; + compatible = "st,stm32f411-plli2s-clock"; + status = "disabled"; + }; + + clk48: clk48 { + #clock-cells = <0>; + compatible = "st,stm32-clock-mux"; + clocks = <&rcc STM32_SRC_PLL_Q CK48M_SEL(0)>; status = "disabled"; }; }; @@ -77,8 +84,8 @@ reg = <0x40013400 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 13U)>; interrupts = <84 5>; - dmas = <&dma2 1 4 0x400 0x3 - &dma2 0 4 0x400 0x3>; + dmas = <&dma2 1 4 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma2 0 4 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -202,10 +209,10 @@ sdmmc1: sdmmc@40012c00 { clocks = <&rcc STM32_CLOCK(APB2, 11U)>, - <&rcc STM32_SRC_SYSCLK SDIO_SEL(1)>; + <&rcc STM32_SRC_CK48 SDIO_SEL(0)>; }; - quadspi: quadspi@a0001000 { + quadspi: spi@a0001000 { compatible = "st,stm32-qspi"; #address-cells = <0x1>; #size-cells = <0x0>; @@ -230,9 +237,13 @@ interrupts = <63 0>, <64 0>, <65 0>, <66 0>; interrupt-names = "TX", "RX0", "RX1", "SCE"; /* also enabling clock for can1 (master instance) */ - clocks = <&rcc STM32_CLOCK(APB1, 26U)>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x06000000>; master-can-reg = <0x40006400>; status = "disabled"; }; }; + + die_temp: dietemp { + io-channels = <&adc1 18>; + }; }; diff --git a/dts/arm/st/f4/stm32f446.dtsi b/dts/arm/st/f4/stm32f446.dtsi index 4aea609df1fcb..a015b1d87b4f1 100644 --- a/dts/arm/st/f4/stm32f446.dtsi +++ b/dts/arm/st/f4/stm32f446.dtsi @@ -11,7 +11,7 @@ / { clocks { plli2s: plli2s { - compatible = "st,stm32f412-plli2s-clock"; + compatible = "st,stm32f411-plli2s-clock"; }; }; @@ -25,8 +25,8 @@ reg = <0x40013000 0x400>; clocks = <&rcc STM32_CLOCK(APB2, 12U)>; interrupts = <35 5>; - dmas = <&dma2 3 3 0x400 0x3 - &dma2 2 3 0x400 0x3>; + dmas = <&dma2 3 3 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL + &dma2 2 3 STM32_DMA_MEM_INC STM32_DMA_FIFO_FULL>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -73,7 +73,7 @@ interrupts = <63 0>, <64 0>, <65 0>, <66 0>; interrupt-names = "TX", "RX0", "RX1", "SCE"; /* also enabling clock for can1 (master instance) */ - clocks = <&rcc STM32_CLOCK(APB1, 26U)>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x06000000>; master-can-reg = <0x40006400>; status = "disabled"; }; @@ -118,8 +118,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; adc3: adc@40012200 { @@ -134,8 +135,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; dac1: dac@40007400 { diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index fd847fb8f4bd9..891afcf10c4da 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -761,8 +761,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; adc2: adc@40012100 { @@ -777,8 +778,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; adc3: adc@40012200 { @@ -793,8 +795,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 15 28 56 84 112 144 480>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; dac1: dac@40007400 { @@ -851,7 +854,7 @@ status = "disabled"; }; - quadspi: quadspi@a0001000 { + quadspi: spi@a0001000 { compatible = "st,stm32-qspi"; #address-cells = <0x1>; #size-cells = <0x0>; diff --git a/dts/arm/st/g0/stm32g0.dtsi b/dts/arm/st/g0/stm32g0.dtsi index e8cd8a8d30a20..69a6c8863da93 100644 --- a/dts/arm/st/g0/stm32g0.dtsi +++ b/dts/arm/st/g0/stm32g0.dtsi @@ -422,7 +422,8 @@ */ sampling-times = <3 5 8 13 20 40 80 161>; num-sampling-time-common-channels = <2>; - st,adc-sequencer = ; + st,adc-sequencer = "NOT_FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; dma1: dma@40020000 { diff --git a/dts/arm/st/g4/stm32g4.dtsi b/dts/arm/st/g4/stm32g4.dtsi index 79e44bada0b6f..20d3d38df39b8 100644 --- a/dts/arm/st/g4/stm32g4.dtsi +++ b/dts/arm/st/g4/stm32g4.dtsi @@ -115,7 +115,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; adc2: adc@50000100 { @@ -130,7 +131,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; dac1: dac@50000800 { diff --git a/dts/arm/st/g4/stm32g473.dtsi b/dts/arm/st/g4/stm32g473.dtsi index be945b5e4fdb9..5b46d11ed23a8 100644 --- a/dts/arm/st/g4/stm32g473.dtsi +++ b/dts/arm/st/g4/stm32g473.dtsi @@ -39,7 +39,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; adc5: adc@50000600 { @@ -54,7 +55,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; spi4: spi@40013c00 { diff --git a/dts/arm/st/g4/stm32g491.dtsi b/dts/arm/st/g4/stm32g491.dtsi index 03875473b58ce..44667b15acabe 100644 --- a/dts/arm/st/g4/stm32g491.dtsi +++ b/dts/arm/st/g4/stm32g491.dtsi @@ -65,7 +65,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; uart5: serial@40005000 { diff --git a/dts/arm/st/h5/stm32h5.dtsi b/dts/arm/st/h5/stm32h5.dtsi index 6f14e2369bf50..3dc4237933c1e 100644 --- a/dts/arm/st/h5/stm32h5.dtsi +++ b/dts/arm/st/h5/stm32h5.dtsi @@ -39,6 +39,15 @@ reg = <0xe000ed90 0x40>; }; }; + + power-states { + stop: state0 { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + substate-id = <1>; + min-residency-us = <20>; + }; + }; }; clocks { @@ -137,15 +146,6 @@ status = "disabled"; }; - power-states { - stop: state0 { - compatible = "zephyr,power-state"; - power-state-name = "suspend-to-idle"; - substate-id = <1>; - min-residency-us = <20>; - }; - }; - rcc: rcc@44020c00 { compatible = "st,stm32u5-rcc"; clocks-controller; @@ -319,7 +319,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; rtc: rtc@44007800 { @@ -457,6 +458,32 @@ status = "disabled"; }; + i3c1: i3c@40005c00 { + compatible = "st,stm32-i3c"; + reg = <0x40005c00 0x400>; + interrupts = <123 0>, <124 0>; + interrupt-names = "event", "error"; + #address-cells = <3>; + #size-cells = <0>; + clocks = <&rcc STM32_CLOCK(APB1, 23U)>; + resets = <&rctl STM32_RESET(APB1L, 23U)>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; + + i3c2: i3c@44003000 { + compatible = "st,stm32-i3c"; + reg = <0x44003000 0x400>; + interrupts = <131 0>, <132 0>; + interrupt-names = "event", "error"; + #address-cells = <3>; + #size-cells = <0>; + clocks = <&rcc STM32_CLOCK(APB3, 9U)>; + resets = <&rctl STM32_RESET(APB3, 9U)>; + zephyr,pm-device-runtime-auto; + status = "disabled"; + }; + spi1: spi@40013000 { compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; #address-cells = <1>; diff --git a/dts/arm/st/h5/stm32h562.dtsi b/dts/arm/st/h5/stm32h562.dtsi index 6ffb287593e39..384a8ff76d544 100644 --- a/dts/arm/st/h5/stm32h562.dtsi +++ b/dts/arm/st/h5/stm32h562.dtsi @@ -258,7 +258,7 @@ status = "disabled"; }; - xspi1: xspi@47001400 { + xspi1: spi@47001400 { compatible = "st,stm32-xspi"; reg = <0x47001400 0x400>; interrupts = <78 0>; @@ -283,7 +283,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; timers4: timers@40000800 { @@ -328,6 +329,22 @@ }; }; + timers8: timers@40013400 { + compatible = "st,stm32-timers"; + reg = <0x40013400 0x400>; + clocks = <&rcc STM32_CLOCK(APB2, 13)>; + resets = <&rctl STM32_RESET(APB2, 13)>; + interrupts = <65 0>, <66 0>, <67 0>, <68 0>; + interrupt-names = "brk", "up", "trgcom", "cc"; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + }; + timers12: timers@40001800 { compatible = "st,stm32-timers"; reg = <0x40001800 0x400>; diff --git a/dts/arm/st/h5/stm32h562Xg.dtsi b/dts/arm/st/h5/stm32h562Xg.dtsi new file mode 100644 index 0000000000000..969c61d5d9c7f --- /dev/null +++ b/dts/arm/st/h5/stm32h562Xg.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Kacper Brzostowski + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +/ { + soc { + flash-controller@40022000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_M(1)>; + }; + }; + }; +}; diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index 3858f8f97ea44..d2b9bd1bcb2e7 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -66,6 +66,7 @@ clk_hsi: clk-hsi { #clock-cells = <0>; compatible = "st,stm32h7-hsi-clock"; + hsi-div = <1>; /* HSI RC: 64MHz, hsi_clk = 64MHz */ clock-frequency = ; status = "disabled"; }; @@ -861,7 +862,8 @@ STM32_ADC_RES(10, 0x03) STM32_ADC_RES(8, 0x07)>; sampling-times = <2 3 9 17 33 65 388 811>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; }; adc2: adc@40022100 { @@ -877,7 +879,8 @@ STM32_ADC_RES(10, 0x03) STM32_ADC_RES(8, 0x07)>; sampling-times = <2 3 9 17 33 65 388 811>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; }; /* dual mode: adc1 and adc2 coupled */ @@ -894,7 +897,8 @@ STM32_ADC_RES(10, 0x03) STM32_ADC_RES(8, 0x07)>; sampling-times = <2 3 9 17 33 65 388 811>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; }; adc3: adc@58026000 { @@ -910,7 +914,8 @@ STM32_ADC_RES(10, 0x03) STM32_ADC_RES(8, 0x07)>; sampling-times = <2 3 9 17 33 65 388 811>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; }; dac1: dac@40007400 { @@ -1060,7 +1065,7 @@ status = "disabled"; }; - quadspi: quadspi@52005000 { + quadspi: spi@52005000 { compatible = "st,stm32-qspi"; #address-cells = <0x1>; #size-cells = <0x0>; @@ -1102,6 +1107,7 @@ compatible = "st,stm32-vref"; vrefint-cal-addr = <0x1FF1E860>; vrefint-cal-mv = <3300>; + vrefint-cal-resolution = <16>; status = "disabled"; }; diff --git a/dts/arm/st/h7/stm32h723.dtsi b/dts/arm/st/h7/stm32h723.dtsi index e4e7e4ee7acc4..bf8712608c66e 100644 --- a/dts/arm/st/h7/stm32h723.dtsi +++ b/dts/arm/st/h7/stm32h723.dtsi @@ -52,7 +52,8 @@ STM32H72X_ADC3_RES(8, 0x02) STM32H72X_ADC3_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; dmamux1: dmamux@40020800 { @@ -88,11 +89,11 @@ interrupts = <88 0>, <89 0>; interrupt-names = "ltdc", "ltdc_er"; clocks = <&rcc STM32_CLOCK(APB3, 3U)>; - resets = <&rctl STM32_RESET(APB3, 4U)>; + resets = <&rctl STM32_RESET(APB3, 3U)>; status = "disabled"; }; - octospi1: octospi@52005000 { + octospi1: spi@52005000 { compatible = "st,stm32-ospi"; reg = <0x52005000 0x1000>; interrupts = <92 0>; @@ -104,7 +105,7 @@ status = "disabled"; }; - octospi2: octospi@5200a000 { + octospi2: spi@5200a000 { compatible = "st,stm32-ospi"; reg = <0x5200a000 0x1000>; interrupts = <150 0>; diff --git a/dts/arm/st/h7/stm32h743.dtsi b/dts/arm/st/h7/stm32h743.dtsi index 114db6e7c1ece..f6b285dd18acb 100644 --- a/dts/arm/st/h7/stm32h743.dtsi +++ b/dts/arm/st/h7/stm32h743.dtsi @@ -49,7 +49,7 @@ interrupts = <88 0>, <89 0>; interrupt-names = "ltdc", "ltdc_er"; clocks = <&rcc STM32_CLOCK(APB3, 3U)>; - resets = <&rctl STM32_RESET(APB3, 4U)>; + resets = <&rctl STM32_RESET(APB3, 3U)>; status = "disabled"; }; diff --git a/dts/arm/st/h7/stm32h743Xg.dtsi b/dts/arm/st/h7/stm32h743Xg.dtsi new file mode 100644 index 0000000000000..d90a2e01512e6 --- /dev/null +++ b/dts/arm/st/h7/stm32h743Xg.dtsi @@ -0,0 +1,18 @@ +/* + * Copyright 2024 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + flash-controller@52002000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(1024)>; + }; + }; + }; +}; diff --git a/dts/arm/st/h7/stm32h745.dtsi b/dts/arm/st/h7/stm32h745.dtsi index 294fd02c502c0..0eb82817506d7 100644 --- a/dts/arm/st/h7/stm32h745.dtsi +++ b/dts/arm/st/h7/stm32h745.dtsi @@ -42,7 +42,7 @@ interrupts = <88 0>, <89 0>; interrupt-names = "ltdc", "ltdc_er"; clocks = <&rcc STM32_CLOCK(APB3, 3U)>; - resets = <&rctl STM32_RESET(APB3, 4U)>; + resets = <&rctl STM32_RESET(APB3, 3U)>; status = "disabled"; }; diff --git a/dts/arm/st/h7/stm32h757.dtsi b/dts/arm/st/h7/stm32h757.dtsi new file mode 100644 index 0000000000000..09f038dd9b149 --- /dev/null +++ b/dts/arm/st/h7/stm32h757.dtsi @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 Grinn sp. z o.o. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + compatible = "st,stm32h757", "st,stm32h7", "simple-bus"; + + cryp: cryp@48021000 { + compatible = "st,stm32-cryp"; + reg = <0x48021000 0x400>; + clocks = <&rcc STM32_CLOCK(AHB2, 4U)>; + interrupts = <79 0>; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/st/h7/stm32h757Xi_m4.dtsi b/dts/arm/st/h7/stm32h757Xi_m4.dtsi new file mode 100644 index 0000000000000..0d9909a83c664 --- /dev/null +++ b/dts/arm/st/h7/stm32h757Xi_m4.dtsi @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Grinn sp. z o.o. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/delete-node/ &flash0; + +/ { + cpus { + /delete-node/ cpu@0; + }; + + soc { + flash-controller@52002000 { + flash1: flash@8100000 { + reg = <0x08100000 DT_SIZE_K(1024)>; + bank2-flash-size = <1024>; + }; + }; + + mailbox@58026400 { + interrupts = <126 0>; + }; + }; +}; diff --git a/dts/arm/st/h7/stm32h757Xi_m7.dtsi b/dts/arm/st/h7/stm32h757Xi_m7.dtsi new file mode 100644 index 0000000000000..bf23d7687b3fb --- /dev/null +++ b/dts/arm/st/h7/stm32h757Xi_m7.dtsi @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Grinn sp. z o.o. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/delete-node/ &flash1; + +/ { + cpus { + /delete-node/ cpu@1; + }; + + dtcm: memory@20000000 { + compatible = "zephyr,memory-region", "arm,dtcm"; + reg = <0x20000000 DT_SIZE_K(128)>; + zephyr,memory-region = "DTCM"; + }; + + soc { + flash-controller@52002000 { + flash0: flash@8000000 { + reg = <0x08000000 DT_SIZE_K(1024)>; + }; + }; + + mailbox@58026400 { + interrupts = <125 0>; + }; + }; +}; diff --git a/dts/arm/st/h7/stm32h7a3.dtsi b/dts/arm/st/h7/stm32h7a3.dtsi index 4721872a3b1d0..72879a8713695 100644 --- a/dts/arm/st/h7/stm32h7a3.dtsi +++ b/dts/arm/st/h7/stm32h7a3.dtsi @@ -52,11 +52,11 @@ interrupts = <88 0>, <89 0>; interrupt-names = "ltdc", "ltdc_er"; clocks = <&rcc STM32_CLOCK(APB3, 3U)>; - resets = <&rctl STM32_RESET(APB3, 4U)>; + resets = <&rctl STM32_RESET(APB3, 3U)>; status = "disabled"; }; - octospi1: octospi@52005000 { + octospi1: spi@52005000 { compatible = "st,stm32-ospi"; reg = <0x52005000 0x1000>; interrupts = <92 0>; @@ -68,7 +68,7 @@ status = "disabled"; }; - octospi2: octospi@5200a000 { + octospi2: spi@5200a000 { compatible = "st,stm32-ospi"; reg = <0x5200a000 0x1000>; interrupts = <150 0>; @@ -87,7 +87,8 @@ reg = <0x58001400 0x400>; clocks = <&rcc STM32_CLOCK(APB4, 5U)>, <&rcc STM32_SRC_PLL1_Q SPI6_SEL(0)>; - dmas = <&dmamux2 0 12 0x20440 &dmamux2 1 11 0x20480>; + dmas = <&dmamux2 0 12 (STM32_DMA_PERIPH_TX | STM32_DMA_PRIORITY_HIGH) + &dmamux2 1 11 (STM32_DMA_PERIPH_RX | STM32_DMA_PRIORITY_HIGH)>; dma-names = "tx", "rx"; interrupts = <86 0>; status = "disabled"; diff --git a/dts/arm/st/h7rs/stm32h7rs.dtsi b/dts/arm/st/h7rs/stm32h7rs.dtsi index 8f17428ff00ba..e41e465c7ebfa 100644 --- a/dts/arm/st/h7rs/stm32h7rs.dtsi +++ b/dts/arm/st/h7rs/stm32h7rs.dtsi @@ -97,6 +97,7 @@ clk_hsi: clk-hsi { #clock-cells = <0>; compatible = "st,stm32h7-hsi-clock"; + hsi-div = <1>; /* HSI RC: 64MHz, hsi_clk = 64MHz */ clock-frequency = ; status = "disabled"; }; @@ -748,7 +749,8 @@ STM32_ADC_RES(8, 0x2) STM32_ADC_RES(6, 0x3)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; adc2: adc@40022100 { @@ -763,7 +765,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; rng: rng@48020000 { @@ -773,6 +776,25 @@ interrupts = <37 0>; status = "disabled"; }; + + usbotg_fs: usb@40080000 { + compatible = "st,stm32-otgfs"; + reg = <0x40080000 0x40000>; + interrupts = <112 0>; + interrupt-names = "otgfs"; + num-bidir-endpoints = <6>; + ram-size = <1280>; + maximum-speed = "full-speed"; + phys = <&otgfs_phy>; + clocks = <&rcc STM32_CLOCK(AHB1, 27U)>, + <&rcc STM32_SRC_HSI48 OTGFS_SEL(0)>; + status = "disabled"; + }; + }; + + otgfs_phy: otgfs_phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; }; die_temp: dietemp { diff --git a/dts/arm/st/l0/stm32l0.dtsi b/dts/arm/st/l0/stm32l0.dtsi index 4ac1ccb56a175..c594d23665de0 100644 --- a/dts/arm/st/l0/stm32l0.dtsi +++ b/dts/arm/st/l0/stm32l0.dtsi @@ -318,7 +318,8 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 161>; num-sampling-time-common-channels = <1>; - st,adc-sequencer = ; + st,adc-sequencer = "NOT_FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; dma1: dma@40020000 { diff --git a/dts/arm/st/l1/stm32l1.dtsi b/dts/arm/st/l1/stm32l1.dtsi index 2b138621f0264..375d97d1c5ead 100644 --- a/dts/arm/st/l1/stm32l1.dtsi +++ b/dts/arm/st/l1/stm32l1.dtsi @@ -226,8 +226,9 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <4 9 16 24 48 96 192 384>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "ASYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_NONE"; }; dac1: dac@40007400 { diff --git a/dts/arm/st/l4/stm32l4.dtsi b/dts/arm/st/l4/stm32l4.dtsi index 5ddee7107d93b..f8f3fafd4d010 100644 --- a/dts/arm/st/l4/stm32l4.dtsi +++ b/dts/arm/st/l4/stm32l4.dtsi @@ -263,7 +263,7 @@ status = "disabled"; }; - quadspi: quadspi@a0001000 { + quadspi: spi@a0001000 { compatible = "st,stm32-qspi"; #address-cells = <1>; #size-cells = <0>; @@ -406,7 +406,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; adc2: adc@50040100 { @@ -421,7 +422,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; dma1: dma@40020000 { diff --git a/dts/arm/st/l4/stm32l4p5.dtsi b/dts/arm/st/l4/stm32l4p5.dtsi index 3746f46eceb68..64be1f15c92a8 100644 --- a/dts/arm/st/l4/stm32l4p5.dtsi +++ b/dts/arm/st/l4/stm32l4p5.dtsi @@ -363,7 +363,7 @@ #io-channel-cells = <1>; }; - octospi1: octospi@a0001000 { + octospi1: spi@a0001000 { compatible = "st,stm32-ospi"; reg = <0xa0001000 0x400>; interrupts = <71 0>; @@ -377,7 +377,7 @@ status = "disabled"; }; - octospi2: octospi@a0001400 { + octospi2: spi@a0001400 { compatible = "st,stm32-ospi"; reg = <0xa0001400 0x400>; interrupts = <76 0>; diff --git a/dts/arm/st/l5/stm32l5.dtsi b/dts/arm/st/l5/stm32l5.dtsi index 07c68b12fffa9..fc4da297c194f 100644 --- a/dts/arm/st/l5/stm32l5.dtsi +++ b/dts/arm/st/l5/stm32l5.dtsi @@ -432,7 +432,7 @@ status = "disabled"; }; - octospi1: octospi@44021000 { + octospi1: spi@44021000 { compatible = "st,stm32-ospi"; reg = <0x44021000 0x400>; interrupts = <76 0>; @@ -666,7 +666,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; adc2: adc@42028100 { @@ -681,7 +682,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; usb: usb@4000d400 { diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi new file mode 100644 index 0000000000000..47a24f4811685 --- /dev/null +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -0,0 +1,648 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m55"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv8.1m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + axisram1: memory@34000000 { + compatible = "mmio-sram"; + }; + + axisram2: memory@34180400 { + compatible = "mmio-sram"; + }; + + clocks { + clk_hse: clk-hse { + #clock-cells = <0>; + compatible = "st,stm32n6-hse-clock"; + status = "disabled"; + }; + + clk_hsi: clk-hsi { + #clock-cells = <0>; + compatible = "st,stm32h7-hsi-clock"; + clock-frequency = ; + status = "disabled"; + }; + + clk_lse: clk-lse { + #clock-cells = <0>; + compatible = "st,stm32-lse-clock"; + clock-frequency = <32768>; + driving-capability = <2>; + status = "disabled"; + }; + + clk_lsi: clk-lsi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + status = "disabled"; + }; + + pll1: pll: pll { + #clock-cells = <0>; + compatible = "st,stm32n6-pll-clock"; + status = "disabled"; + }; + + pll2: pll2 { + #clock-cells = <0>; + compatible = "st,stm32n6-pll-clock"; + status = "disabled"; + }; + + pll3: pll3 { + #clock-cells = <0>; + compatible = "st,stm32n6-pll-clock"; + status = "disabled"; + }; + + pll4: pll4 { + #clock-cells = <0>; + compatible = "st,stm32n6-pll-clock"; + status = "disabled"; + }; + + cpusw: cpusw { + #clock-cells = <0>; + compatible = "st,stm32n6-cpu-clock-mux", "st,stm32-clock-mux"; + status = "disabled"; + }; + + perck: perck { + #clock-cells = <0>; + compatible = "st,stm32-clock-mux"; + status = "disabled"; + }; + + ic1: ic1 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic2: ic2 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic3: ic3 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic4: ic4 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic5: ic5 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic6: ic6 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic7: ic7 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic8: ic8 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic9: ic9 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic10: ic10 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic11: ic11 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic12: ic12 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic13: ic13 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic14: ic14 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic15: ic15 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic16: ic16 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic17: ic17 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic18: ic18 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic19: ic19 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + + ic20: ic20 { + #clock-cells = <0>; + compatible = "st,stm32n6-ic-clock-mux"; + status = "disabled"; + }; + }; + + soc { + rcc: rcc@56028000 { + compatible = "st,stm32n6-rcc"; + clocks-controller; + #clock-cells = <2>; + reg = <0x56028000 0x2000>; + + rctl: reset-controller { + compatible = "st,stm32-rcc-rctl"; + #reset-cells = <1>; + }; + }; + + exti: interrupt-controller@56025000 { + compatible = "st,stm32g0-exti", "st,stm32-exti"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + reg = <0x56025000 0x400>; + num-lines = <16>; + interrupts = <20 0>, <21 0>, <22 0>, <23 0>, + <24 0>, <25 0>, <26 0>, <27 0>, + <28 0>, <29 0>, <30 0>, <31 0>, + <32 0>, <33 0>, <34 0>, <35 0>; + interrupt-names = "line0", "line1", "line2", "line3", + "line4", "line5", "line6", "line7", + "line8", "line9", "line10", "line11", + "line12", "line13", "line14", "line15"; + line-ranges = <0 1>, <1 1>, <2 1>, <3 1>, + <4 1>, <5 1>, <6 1>, <7 1>, + <8 1>, <9 1>, <10 1>, <11 1>, + <12 1>, <13 1>, <14 1>, <15 1>; + }; + + pinctrl: pin-controller@56020000 { + compatible = "st,stm32-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x56020000 0x2000>; + + gpioa: gpio@56020000 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56020000 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 0)>; + }; + + gpiob: gpio@56020400 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56020400 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 1)>; + }; + + gpioc: gpio@56020800 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56020800 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 2)>; + }; + + gpiod: gpio@56020c00 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56020c00 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 3)>; + }; + + gpioe: gpio@56021000 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56021000 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 4)>; + }; + + gpiof: gpio@56021400 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56021400 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 5)>; + }; + + gpiog: gpio@56021800 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56021800 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 6)>; + }; + + gpioh: gpio@56021c00 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56021c00 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 7)>; + }; + + gpion: gpio@56023400 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56023400 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 13)>; + }; + + gpioo: gpio@56023800 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56023800 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 14)>; + }; + + gpiop: gpio@56023c00 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56023C00 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 15)>; + }; + + gpioq: gpio@56024000 { + compatible = "st,stm32-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x56024000 0x400>; + clocks = <&rcc STM32_CLOCK(AHB4, 16)>; + }; + }; + + adc1: adc@50022000 { + compatible = "st,stm32n6-adc", "st,stm32-adc"; + reg = <0x50022000 0x400>; + clocks = <&rcc STM32_CLOCK(AHB1, 5)>; + interrupts = <46 0>; + status = "disabled"; + #io-channel-cells = <1>; + resolutions = ; + sampling-times = <2 3 7 12 14 47 247 1500>; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; + }; + + adc2: adc@50022100 { + compatible = "st,stm32n6-adc", "st,stm32-adc"; + reg = <0x50022100 0x300>; + clocks = <&rcc STM32_CLOCK(AHB1, 5)>; + interrupts = <46 0>; + status = "disabled"; + #io-channel-cells = <1>; + resolutions = ; + sampling-times = <2 3 7 12 14 47 247 1500>; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; + }; + + fdcan1: can@5000a000 { + compatible = "st,stm32h7-fdcan"; + reg = <0x5000A000 0x400>, <0x5000C000 0xd54>; + reg-names = "m_can", "message_ram"; + clocks = <&rcc STM32_CLOCK(APB1_2, 8)>; + interrupts = <180 0>, <181 0>, <186 0>; + interrupt-names = "int0", "int1", "calib"; + bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>; + status = "disabled"; + }; + + fdcan2: can@5000a400 { + compatible = "st,stm32h7-fdcan"; + reg = <0x5000A400 0x400>, <0x5000C000 0x1aa8>; + reg-names = "m_can", "message_ram"; + clocks = <&rcc STM32_CLOCK(APB1_2, 8)>; + interrupts = <182 0>, <183 0>; + interrupt-names = "int0", "int1"; + bosch,mram-cfg = <0xd54 28 8 3 3 0 3 3>; + status = "disabled"; + }; + + fdcan3: can@5000e800 { + compatible = "st,stm32h7-fdcan"; + reg = <0x5000E800 0x400>, <0x5000C000 0x2800>; + reg-names = "m_can", "message_ram"; + clocks = <&rcc STM32_CLOCK(APB1_2, 8)>; + interrupts = <184 0>, <185 0>; + interrupt-names = "int0", "int1"; + bosch,mram-cfg = <0x1aa8 28 8 3 3 0 3 3>; + status = "disabled"; + }; + + usart1: serial@52001000 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x52001000 0x400>; + clocks = <&rcc STM32_CLOCK(APB2, 4)>; + resets = <&rctl STM32_RESET(APB2, 4)>; + interrupts = <159 0>; + status = "disabled"; + }; + + usart2: serial@50004400 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x50004400 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 17)>; + resets = <&rctl STM32_RESET(APB1L, 17)>; + interrupts = <160 0>; + status = "disabled"; + }; + + usart3: serial@50004800 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x50004800 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 18)>; + resets = <&rctl STM32_RESET(APB1L, 18)>; + interrupts = <161 0>; + status = "disabled"; + }; + + uart4: serial@50004c00 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x50004C00 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 19)>; + resets = <&rctl STM32_RESET(APB1L, 19)>; + interrupts = <162 0>; + status = "disabled"; + }; + + uart5: serial@50005000 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x50005000 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 20)>; + resets = <&rctl STM32_RESET(APB1L, 20)>; + interrupts = <163 0>; + status = "disabled"; + }; + + usart6: serial@52001400 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x52001400 0x400>; + clocks = <&rcc STM32_CLOCK(APB2, 5)>; + resets = <&rctl STM32_RESET(APB2, 5)>; + interrupts = <164 0>; + status = "disabled"; + }; + + uart7: serial@50007800 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x50007800 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 30)>; + resets = <&rctl STM32_RESET(APB1L, 30)>; + interrupts = <165 0>; + status = "disabled"; + }; + + uart8: serial@50007c00 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x50007C00 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1L, 31)>; + interrupts = <166 0>; + status = "disabled"; + }; + + uart9: serial@52001800 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x52001800 0x400>; + clocks = <&rcc STM32_CLOCK(APB2, 6)>; + resets = <&rctl STM32_RESET(APB2, 6)>; + interrupts = <167 0>; + status = "disabled"; + }; + + usart10: serial@52001c00 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x52001C00 0x400>; + clocks = <&rcc STM32_CLOCK(APB2, 7)>; + resets = <&rctl STM32_RESET(APB2, 7)>; + interrupts = <168 0>; + status = "disabled"; + }; + + i2c1: i2c@50005400 { + compatible = "st,stm32-i2c-v2"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x50005400 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 21)>; + interrupts = <100 0>, <101 0>; + interrupt-names = "event", "error"; + status = "disabled"; + }; + + i2c2: i2c@50005800 { + compatible = "st,stm32-i2c-v2"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x50005800 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 22)>; + interrupts = <102 0>, <103 0>; + interrupt-names = "event", "error"; + status = "disabled"; + }; + + i2c3: i2c@50005c00 { + compatible = "st,stm32-i2c-v2"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x50005C00 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 23)>; + interrupts = <104 0>, <105 0>; + interrupt-names = "event", "error"; + status = "disabled"; + }; + + i2c4: i2c@56001c00 { + compatible = "st,stm32-i2c-v2"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x56001C00 0x400>; + clocks = <&rcc STM32_CLOCK(APB4, 7)>; + interrupts = <106 0>, <107 0>; + interrupt-names = "event", "error"; + status = "disabled"; + }; + + spi1: spi@52003000 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x52003000 0x400>; + interrupts = <153 0>; + clocks = <&rcc STM32_CLOCK(APB2, 12)>; + status = "disabled"; + }; + + spi2: spi@50003800 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x50003800 0x400>; + interrupts = <154 0>; + clocks = <&rcc STM32_CLOCK(APB1, 14)>; + status = "disabled"; + }; + + spi3: spi@50003c00 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x50003C00 0x400>; + interrupts = <155 0>; + clocks = <&rcc STM32_CLOCK(APB1, 15)>; + status = "disabled"; + }; + + spi4: spi@52003400 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x52003400 0x400>; + interrupts = <156 0>; + clocks = <&rcc STM32_CLOCK(APB2, 13)>; + status = "disabled"; + }; + + spi5: spi@52005000 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x52005000 0x400>; + interrupts = <157 0>; + clocks = <&rcc STM32_CLOCK(APB2, 20)>; + status = "disabled"; + }; + + spi6: spi@56001400 { + compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x56001400 0x400>; + interrupts = <158 0>; + clocks = <&rcc STM32_CLOCK(APB4, 5)>; + status = "disabled"; + }; + + gpdma1: dma@50021000 { + compatible = "st,stm32u5-dma"; + #dma-cells = <3>; + reg = <0x50021000 0x1000>; + clocks = <&rcc STM32_CLOCK(AHB1, 4)>; + interrupts = <84 0 85 0 86 0 87 0 88 0 89 0 90 0 91 0 + 92 0 93 0 94 0 95 0 96 0 97 0 98 0 99 0>; + dma-channels = <16>; + dma-requests = <144>; + dma-offset = <0>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/st/n6/stm32n657.dtsi b/dts/arm/st/n6/stm32n657.dtsi new file mode 100644 index 0000000000000..7cc6f02b17081 --- /dev/null +++ b/dts/arm/st/n6/stm32n657.dtsi @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + + +/ { + soc { + compatible = "st,stm32n657", "st,stm32n6", "simple-bus"; + }; +}; diff --git a/dts/arm/st/n6/stm32n657X0.dtsi b/dts/arm/st/n6/stm32n657X0.dtsi new file mode 100644 index 0000000000000..613c3ee443eb1 --- /dev/null +++ b/dts/arm/st/n6/stm32n657X0.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +/ { + axisram1: memory@34000000 { + reg = <0x34000000 DT_SIZE_K(624)>; + }; + + axisram2: memory@34180400 { + reg = <0x34180400 DT_SIZE_K(511)>; + }; +}; diff --git a/dts/arm/st/u0/stm32u0.dtsi b/dts/arm/st/u0/stm32u0.dtsi index 62edce08afb1b..4d0b1e871280b 100644 --- a/dts/arm/st/u0/stm32u0.dtsi +++ b/dts/arm/st/u0/stm32u0.dtsi @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ / { chosen { zephyr,flash-controller = &flash; + zephyr,entropy = &rng; }; cpus { @@ -213,6 +215,47 @@ status = "disabled"; }; + usart4: serial@40004c00 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x40004c00 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 19U)>; + resets = <&rctl STM32_RESET(APB1L, 19U)>; + interrupts = <30 0>; + status = "disabled"; + }; + + lpuart1: serial@40008000 { + compatible = "st,stm32-lpuart", "st,stm32-uart"; + reg = <0x40008000 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 20U)>; + resets = <&rctl STM32_RESET(APB1L, 20U)>; + interrupts = <28 0>; + status = "disabled"; + }; + + lpuart2: serial@40008400 { + compatible = "st,stm32-lpuart", "st,stm32-uart"; + reg = <0x40008400 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 7U)>; + resets = <&rctl STM32_RESET(APB1L, 7U)>; + interrupts = <29 0>; + status = "disabled"; + }; + + iwdg: watchdog@40003000 { + compatible = "st,stm32-watchdog"; + reg = <0x40003000 0x400>; + status = "disabled"; + }; + + wwdg: watchdog@40002c00 { + compatible = "st,stm32-window-watchdog"; + reg = <0x40002c00 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 11U)>; + interrupts = <0 7>; + status = "disabled"; + }; + adc1: adc@40012400 { compatible = "st,stm32-adc"; reg = <0x40012400 0x400>; @@ -226,7 +269,8 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 161>; num-sampling-time-common-channels = <2>; - st,adc-sequencer = ; + st,adc-sequencer = "NOT_FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; dac1: dac@40007400 { @@ -273,6 +317,86 @@ status = "disabled"; }; + dma1: dma@40020000 { + compatible = "st,stm32-dma-v2"; + #dma-cells = <3>; + reg = <0x40020000 0x400>; + interrupts = <9 0 10 0 10 0 11 0 11 0 11 0 11 0>; + clocks = <&rcc STM32_CLOCK(AHB1, 0U)>; + dma-requests = <7>; + dma-offset = <0>; + status = "disabled"; + }; + + dmamux1: dmamux@40020800 { + compatible = "st,stm32-dmamux"; + #dma-cells = <3>; + reg = <0x40020800 0x400>; + interrupts = <11 0>; + dma-channels = <7>; + dma-generators = <4>; + dma-requests= <76>; + status = "disabled"; + }; + + spi1: spi@40013000 { + compatible = "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40013000 0x400>; + clocks = <&rcc STM32_CLOCK(APB1_2, 12U)>; + interrupts = <25 0>; + status = "disabled"; + }; + + spi2: spi@40003800 { + compatible = "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40003800 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 14U)>; + interrupts = <26 0>; + status = "disabled"; + }; + + spi3: spi@40003c00 { + compatible = "st,stm32-spi-fifo", "st,stm32-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40003c00 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 15U)>; + interrupts = <26 0>; + status = "disabled"; + }; + + rng: rng@40025000 { + compatible = "st,stm32-rng"; + reg = <0x40025000 0x400>; + clocks = <&rcc STM32_CLOCK(AHB1, 18U)>; + interrupts = <31 0>; + status = "disabled"; + }; + + aes: aes@40026000 { + compatible = "st,stm32-aes"; + reg = <0x40026000 0x400>; + clocks = <&rcc STM32_CLOCK(AHB1, 16U)>; + resets = <&rctl STM32_RESET(AHB1, 16U)>; + interrupts = <31 0>; + interrupt-names = "aes"; + status = "disabled"; + }; + + rtc: rtc@40002800 { + compatible = "st,stm32-rtc"; + reg = <0x40002800 0x400>; + interrupts = <2 0>; + clocks = <&rcc STM32_CLOCK(APB1, 10U)>; + prescaler = <32768>; + alarms-count = <2>; + alrm-exti-line = <28>; + status = "disabled"; + }; timers1: timers@40012c00 { compatible = "st,stm32-timers"; @@ -405,6 +529,29 @@ status = "disabled"; }; }; + + lptim1: timers@40007c00 { + compatible = "st,stm32-lptim"; + clocks = <&rcc STM32_CLOCK(APB1, 31U)>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40007c00 0x400>; + interrupts = <17 1>; + interrupt-names = "combined"; + status = "disabled"; + + }; + + lptim2: timers@40009400 { + compatible = "st,stm32-lptim"; + clocks = <&rcc STM32_CLOCK(APB1, 30U)>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40009400 0x400>; + interrupts = <18 1>; + interrupt-names = "combined"; + status = "disabled"; + }; }; }; diff --git a/dts/arm/st/u0/stm32u073.dtsi b/dts/arm/st/u0/stm32u073.dtsi index 35284d536c5e1..5e6388f8a7d26 100644 --- a/dts/arm/st/u0/stm32u073.dtsi +++ b/dts/arm/st/u0/stm32u073.dtsi @@ -21,6 +21,44 @@ interrupt-names = "combined"; status = "disabled"; }; + + lptim3: timers@40009000 { + compatible = "st,stm32-lptim"; + clocks = <&rcc STM32_CLOCK(APB1, 26U)>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40009000 0x400>; + interrupts = <19 1>; + interrupt-names = "combined"; + status = "disabled"; + }; + + dma2: dma@40020400 { + compatible = "st,stm32-dma-v2"; + #dma-cells = <3>; + reg = <0x40020400 0x400>; + interrupts = <11 0 11 0 11 0 11 0 11 0>; + clocks = <&rcc STM32_CLOCK(AHB1, 1U)>; + dma-requests = <5>; + dma-offset = <7>; + status = "disabled"; + }; + + dmamux1: dmamux@40020800 { + dma-channels = <12>; + }; + + usb: usb@40005c00 { + compatible = "st,stm32-usb"; + reg = <0x40005c00 0x400>; + interrupts = <8 0>; + interrupt-names = "usb"; + num-bidir-endpoints = <8>; + ram-size = <1024>; + phys = <&usb_fs_phy>; + clocks = <&rcc STM32_CLOCK(APB1, 13U)>; + status = "disabled"; + }; }; sram1: memory@20000000 { @@ -32,4 +70,9 @@ compatible = "zephyr,memory-region", "mmio-sram"; zephyr,memory-region = "SRAM2"; }; + + usb_fs_phy: usbphy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; }; diff --git a/dts/arm/st/u0/stm32u083.dtsi b/dts/arm/st/u0/stm32u083.dtsi index 3fb84c5d590a9..ac430ca0a8d6e 100644 --- a/dts/arm/st/u0/stm32u083.dtsi +++ b/dts/arm/st/u0/stm32u083.dtsi @@ -9,5 +9,14 @@ / { soc { compatible = "st,stm32u083", "st,stm32u0", "simple-bus"; + + lpuart3: serial@40008c00 { + compatible = "st,stm32-lpuart", "st,stm32-uart"; + reg = <0x40008c00 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 12U)>; + resets = <&rctl STM32_RESET(APB1L, 12U)>; + interrupts = <30 0>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index 9f694d600a3fd..6c3260e1fb408 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -696,7 +696,7 @@ }; }; - octospi1: octospi@420d1400 { + octospi1: spi@420d1400 { compatible = "st,stm32-ospi"; reg = <0x420d1400 0x400>; interrupts = <76 0>; @@ -709,7 +709,7 @@ status = "disabled"; }; - octospi2: octospi@420d2400 { + octospi2: spi@420d2400 { compatible = "st,stm32-ospi"; reg = <0x420d2400 0x400>; interrupts = <120 0>; @@ -791,8 +791,9 @@ STM32_ADC_RES(10, 0x02) STM32_ADC_RES(8, 0x03)>; sampling-times = <5 6 12 20 36 68 391 814>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "ASYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; }; adc4: adc@46021000 { @@ -809,8 +810,9 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 815>; num-sampling-time-common-channels = <2>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "ASYNC"; + st,adc-sequencer = "NOT_FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; fdcan1: can@4000a400 { @@ -957,6 +959,7 @@ compatible = "st,stm32-vref"; vrefint-cal-addr = <0x0BFA07A5>; vrefint-cal-mv = <3000>; + vrefint-cal-resolution = <14>; io-channels = <&adc1 0>; status = "disabled"; }; @@ -965,6 +968,7 @@ compatible = "st,stm32-vref"; vrefint-cal-addr = <0x0BFA07A5>; vrefint-cal-mv = <3000>; + vrefint-cal-resolution = <14>; io-channels = <&adc4 0>; status = "disabled"; }; diff --git a/dts/arm/st/u5/stm32u595.dtsi b/dts/arm/st/u5/stm32u595.dtsi index c0c856dc27384..5ca3f66d7d5be 100644 --- a/dts/arm/st/u5/stm32u595.dtsi +++ b/dts/arm/st/u5/stm32u595.dtsi @@ -74,8 +74,9 @@ STM32_ADC_RES(10, 0x02) STM32_ADC_RES(8, 0x03)>; sampling-times = <5 6 12 20 36 68 391 814>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "ASYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; }; /* @@ -94,8 +95,9 @@ STM32_ADC_RES(10, 0x02) STM32_ADC_RES(8, 0x03)>; sampling-times = <5 6 12 20 36 68 391 814>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "ASYNC"; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_EXTENDED"; }; usbotg_hs: otghs@42040000 { @@ -106,16 +108,16 @@ num-bidir-endpoints = <9>; ram-size = <4096>; maximum-speed = "high-speed"; - clocks = <&rcc STM32_CLOCK(AHB2, 15U)>, - <&rcc STM32_SRC_HSI48 ICKLK_SEL(0)>; + clocks = <&rcc STM32_CLOCK(AHB2, 14U)>; phys = <&otghs_phy>; status = "disabled"; }; }; otghs_phy: otghs_phy { - /* Clock source defined by USBPHYC_SEL in */ - compatible = "usb-nop-xceiv"; + compatible = "st,stm32u5-otghs-phy"; + clocks = <&rcc STM32_CLOCK(AHB2, 15U)>, + <&rcc STM32_SRC_HSE OTGHS_SEL(0)>; #phy-cells = <0>; }; diff --git a/dts/arm/st/wb/stm32wb.dtsi b/dts/arm/st/wb/stm32wb.dtsi index 90ff2423dc91f..b0a51d6be4619 100644 --- a/dts/arm/st/wb/stm32wb.dtsi +++ b/dts/arm/st/wb/stm32wb.dtsi @@ -425,7 +425,8 @@ STM32_ADC_RES(8, 0x02) STM32_ADC_RES(6, 0x03)>; sampling-times = <3 7 13 25 48 93 248 641>; - st,adc-sequencer = ; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; iwdg: watchdog@40003000 { @@ -492,7 +493,7 @@ status = "disabled"; }; - quadspi: quadspi@a0001000 { + quadspi: spi@a0001000 { compatible = "st,stm32-qspi"; #address-cells = <0x1>; #size-cells = <0x0>; diff --git a/dts/arm/st/wb0/stm32wb0.dtsi b/dts/arm/st/wb0/stm32wb0.dtsi index c1dcd6ef68c18..e9ff28aa22ec5 100644 --- a/dts/arm/st/wb0/stm32wb0.dtsi +++ b/dts/arm/st/wb0/stm32wb0.dtsi @@ -259,6 +259,22 @@ dma-requests= <25>; status = "disabled"; }; + + /** + * This node is valid for STM32WB05, STM32WB06 and + * STM32WB07, all equipped with the same IRQ-less + * TRNG instance. Since all those properties are + * also valid on STM32SWB09, except "compatible", + * we pretend this node is valid for all SoCs of + * the series and clean up in `stm32wb09.dtsi`. + */ + rng: rng@48600000 { + compatible = "st,stm32-rng-noirq"; + reg = <0x48600000 DT_SIZE_K(4)>; + clocks = <&rcc STM32_CLOCK(AHB0, 18)>; + generation-delay-ns = <1250>; /* 1.25us */ + status = "disabled"; + }; }; bt_hci_wb0: bt_hci_wb0 { diff --git a/dts/arm/st/wb0/stm32wb05.dtsi b/dts/arm/st/wb0/stm32wb05.dtsi index 15dfabf83b920..e44aad6770a6e 100644 --- a/dts/arm/st/wb0/stm32wb05.dtsi +++ b/dts/arm/st/wb0/stm32wb05.dtsi @@ -9,5 +9,71 @@ / { soc { compatible = "st,stm32wb05", "st,stm32wb0", "simple-bus"; + + timers2: timers@40002000 { + compatible = "st,stm32-timers"; + reg = <0x40002000 DT_SIZE_K(1)>; + clocks = <&rcc STM32_CLOCK(APB0, 0)>; + resets = <&rctl STM32_RESET(APB0, 0)>; + interrupts = <10 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers16: timers@40005000 { + compatible = "st,stm32-timers"; + reg = <0x40005000 DT_SIZE_K(1)>; + clocks = <&rcc STM32_CLOCK(APB0, 1)>; + resets = <&rctl STM32_RESET(APB0, 1)>; + interrupts = <26 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; + + timers17: timers@40006000 { + compatible = "st,stm32-timers"; + reg = <0x40006000 DT_SIZE_K(1)>; + clocks = <&rcc STM32_CLOCK(APB0, 2)>; + resets = <&rctl STM32_RESET(APB0, 2)>; + interrupts = <27 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/st/wb0/stm32wb07.dtsi b/dts/arm/st/wb0/stm32wb07.dtsi index dec050b680e0b..5e8e2ed2fa0ea 100644 --- a/dts/arm/st/wb0/stm32wb07.dtsi +++ b/dts/arm/st/wb0/stm32wb07.dtsi @@ -47,5 +47,27 @@ interrupts = <6 0>; status = "disabled"; }; + + timers1: timers@40002000 { + compatible = "st,stm32-timers"; + reg = <0x40002000 DT_SIZE_K(1)>; + clocks = <&rcc STM32_CLOCK(APB0, 0)>; + resets = <&rctl STM32_RESET(APB0, 0)>; + interrupts = <10 0>; + interrupt-names = "global"; + st,prescaler = <0>; + status = "disabled"; + + pwm { + compatible = "st,stm32-pwm"; + status = "disabled"; + #pwm-cells = <3>; + }; + + counter { + compatible = "st,stm32-counter"; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/st/wb0/stm32wb09.dtsi b/dts/arm/st/wb0/stm32wb09.dtsi index 604ac43322baf..9b3c54e27a79f 100644 --- a/dts/arm/st/wb0/stm32wb09.dtsi +++ b/dts/arm/st/wb0/stm32wb09.dtsi @@ -14,5 +14,17 @@ / { soc { compatible = "st,stm32wb09", "st,stm32wb0", "simple-bus"; + + rng: rng@48600000 { + /** + * STM32WB09 TRNG has an interrupt line. + * Switch to proper compatible, delete property + * that doesn't apply to it, and add the interrupt + * line as property. + */ + /delete-property/ generation-delay-ns; + compatible = "st,stm32-rng"; + interrupts = <28 0>; + }; }; }; diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index 6d12ca8c8dda2..697d7789b03c4 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -118,6 +118,13 @@ }; }; + mcos { + mco1: mco1 { + compatible = "st,stm32-clock-mco"; + status = "disabled"; + }; + }; + soc { flash: flash-controller@40022000 { compatible = "st,stm32-flash-controller", "st,stm32wba-flash-controller"; @@ -424,8 +431,9 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 815>; num-sampling-time-common-channels = <2>; - st,adc-clock-source = ; - st,adc-sequencer = ; + st,adc-clock-source = "ASYNC"; + st,adc-sequencer = "NOT_FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; lptim1: timers@46004400 { diff --git a/dts/arm/st/wl/stm32wl.dtsi b/dts/arm/st/wl/stm32wl.dtsi index b5df0b9070f89..6c0e71876f3a4 100644 --- a/dts/arm/st/wl/stm32wl.dtsi +++ b/dts/arm/st/wl/stm32wl.dtsi @@ -354,7 +354,8 @@ STM32_ADC_RES(6, 0x03)>; sampling-times = <2 4 8 13 20 40 80 161>; num-sampling-time-common-channels = <2>; - st,adc-sequencer = ; + st,adc-sequencer = "NOT_FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; }; dac1: dac@40007400 { diff --git a/dts/arm/ti/am62x_m4.dtsi b/dts/arm/ti/am62x_m4.dtsi index b310c19b170a2..80fb438acd6e2 100644 --- a/dts/arm/ti/am62x_m4.dtsi +++ b/dts/arm/ti/am62x_m4.dtsi @@ -39,6 +39,15 @@ #clock-cells = <0>; }; + mbox0: mailbox0@29000000 { + compatible = "ti,omap-mailbox"; + reg = <0x29000000 0x200>; + interrupts = <50 4>; + interrupt-parent = <&nvic>; + usr-id = <2>; + #mbox-cells = <1>; + }; + pinctrl: pinctrl@4084000 { compatible = "ti,k3-pinctrl"; reg = <0x04084000 0x88>; diff --git a/dts/arm/ti/cc2340r5.dtsi b/dts/arm/ti/cc2340r5.dtsi new file mode 100644 index 0000000000000..c275b2e1de8a9 --- /dev/null +++ b/dts/arm/ti/cc2340r5.dtsi @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(36)>; + }; +}; + +/* Main flash */ +&flash0 { + reg = <0x0 DT_SIZE_K(512)>; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x0 DT_SIZE_K(512)>; + }; +}; + +/* CCFG */ +&flash1 { + reg = <0x4e020000 DT_SIZE_K(2)>; + ti,bldr-vtor-flash = <0>; + ti,serial-io-cfg-index = <0>; + ti,debug-port; + ti,energy-trace; + ti,flash-verify; + ti,flash-program; + ti,chip-erase; + ti,ret-to-factory; + ti,wr-er-prot-sect0-31 = <0xffffffff>; + ti,wr-er-prot-sect32-255 = <0xffffffff>; + ti,wr-er-prot-ccfg-sect = <0>; + ti,wr-er-prot-fcfg-sect = <0>; + ti,wr-er-prot-engr-sect = <0>; + ti,chip-er-retain-sect0-31 = <0>; + ti,chip-er-retain-sect32-255 = <0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + ti_ccfg_partition: partition@4e020000 { + compatible = "zephyr,memory-region"; + reg = <0x4e020000 0x800>; + zephyr,memory-region = "FLASH_CCFG"; + }; + }; +}; diff --git a/dts/arm/ti/cc23x0.dtsi b/dts/arm/ti/cc23x0.dtsi new file mode 100644 index 0000000000000..6b307980ce3e7 --- /dev/null +++ b/dts/arm/ti/cc23x0.dtsi @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + chosen { + zephyr,flash-controller = &flash_controller; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m0+"; + clock-frequency = ; + reg = <0>; + }; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + soc { + flash_controller: flash-controller@40021000 { + compatible = "ti,cc23x0-flash-controller"; + reg = <0x40021000 0x408>; + #address-cells = <1>; + #size-cells = <1>; + + /* Main flash sector */ + flash0: flash@0 { + compatible = "soc-nv-flash"; + erase-block-size = ; + write-block-size = <0x10>; + }; + + /* CCFG flash sector */ + flash1: flash@4e020000 { + compatible = "ti,cc23x0-ccfg-flash", "soc-nv-flash"; + erase-block-size = ; + write-block-size = <0x10>; + }; + }; + + pinctrl: pinctrl@40003000 { + compatible = "ti,cc23x0-pinctrl"; + reg = <0x40003000 0xc14>; + }; + + gpio0: gpio@40023000 { + compatible = "ti,cc23x0-gpio"; + reg = <0x40023000 0x804>; + interrupts = <5 0>; /* GPIO combined on CPUIRQ5 */ + status = "disabled"; + gpio-controller; + #gpio-cells = <2>; /* Pin (ID), and flags */ + ngpios = <26>; /* Only [DIO0, DIO25] are available */ + }; + + uart0: uart@40034000 { + compatible = "ti,cc23x0-uart"; + reg = <0x40034000 0x52>; + interrupts = <11 0>; + clocks = <&sysclk>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <2>; /* Interrupt levels are 0-192 in steps of 64 */ +}; + +&systick { + status = "disabled"; +}; diff --git a/dts/arm/ti/j721e_main_r5.dtsi b/dts/arm/ti/j721e_main_r5.dtsi index 7b8f72ba5aed1..e088321e9664d 100644 --- a/dts/arm/ti/j721e_main_r5.dtsi +++ b/dts/arm/ti/j721e_main_r5.dtsi @@ -55,6 +55,83 @@ status = "okay"; }; + i2c0: i2c0@2000000 { + compatible = "ti,omap-i2c"; + reg = <0x02000000 0x1000>; + interrupts = <0 150 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c1@2010000 { + compatible = "ti,omap-i2c"; + reg = <0x02010000 0x1000>; + interrupts = <0 151 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c2@2020000 { + compatible = "ti,omap-i2c"; + reg = <0x02020000 0x1000>; + interrupts = <0 183 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c3@2030000 { + compatible = "ti,omap-i2c"; + reg = <0x02030000 0x1000>; + interrupts = <0 184 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c4@2040000 { + compatible = "ti,omap-i2c"; + reg = <0x02040000 0x1000>; + interrupts = <0 185 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c5@2050000 { + compatible = "ti,omap-i2c"; + reg = <0x02050000 0x1000>; + interrupts = <0 186 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c6: i2c@2060000 { + compatible = "ti,omap-i2c"; + reg = <0x02060000 0x1000>; + interrupts = <0 187 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + uart1: uart@2810000 { compatible = "ns16550"; reg = <0x02810000 0x100>; diff --git a/dts/arm/ti/j722s_main.dtsi b/dts/arm/ti/j722s_main.dtsi new file mode 100644 index 0000000000000..4ed66cde145c0 --- /dev/null +++ b/dts/arm/ti/j722s_main.dtsi @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Andrew Davis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + pinctrl: pinctrl@f4000 { + compatible = "ti,k3-pinctrl"; + reg = <0x000f4000 0x2ac>; + status = "okay"; + }; + + gpio0: gpio@600010 { + compatible = "ti,davinci-gpio"; + reg = <0x00600010 0x100>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <92>; + status = "disabled"; + }; + + gpio1: gpio@601010 { + compatible = "ti,davinci-gpio"; + reg = <0x00601010 0x100>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <52>; + status = "disabled"; + }; + + uart0: uart@2800000 { + compatible = "ns16550"; + reg = <0x02800000 0x100>; + clock-frequency = <48000000>; + interrupts = <0 210 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + reg-shift = <2>; + status = "disabled"; + }; + + uart1: uart@2810000 { + compatible = "ns16550"; + reg = <0x02810000 0x100>; + clock-frequency = <48000000>; + interrupts = <0 211 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + reg-shift = <2>; + status = "disabled"; + }; + + uart2: uart@2820000 { + compatible = "ns16550"; + reg = <0x02820000 0x100>; + clock-frequency = <48000000>; + interrupts = <0 212 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + reg-shift = <2>; + status = "disabled"; + }; + + uart3: uart@2830000 { + compatible = "ns16550"; + reg = <0x02830000 0x100>; + clock-frequency = <48000000>; + interrupts = <0 213 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + reg-shift = <2>; + status = "disabled"; + }; + + uart4: uart@2840000 { + compatible = "ns16550"; + reg = <0x02840000 0x100>; + clock-frequency = <48000000>; + interrupts = <0 214 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + reg-shift = <2>; + status = "disabled"; + }; + + uart5: uart@2850000 { + compatible = "ns16550"; + reg = <0x02850000 0x100>; + clock-frequency = <48000000>; + interrupts = <0 215 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + reg-shift = <2>; + status = "disabled"; + }; + + uart6: uart@2860000 { + compatible = "ns16550"; + reg = <0x02860000 0x100>; + clock-frequency = <48000000>; + interrupts = <0 216 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + reg-shift = <2>; + status = "disabled"; + }; +}; diff --git a/dts/arm/ti/j722s_main_r5.dtsi b/dts/arm/ti/j722s_main_r5.dtsi new file mode 100644 index 0000000000000..fe1457780de64 --- /dev/null +++ b/dts/arm/ti/j722s_main_r5.dtsi @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Andrew Davis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "j722s_mcu.dtsi" +#include "j722s_main.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-r5"; + reg = <0>; + }; + }; + + atcm: memory@0 { + device_type = "memory"; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x00000000 DT_SIZE_K(32)>; + zephyr,memory-region = "ATCM"; + }; + + btcm: memory@41010000 { + device_type = "memory"; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x41010000 DT_SIZE_K(32)>; + zephyr,memory-region = "BTCM"; + }; + + vim: interrupt-controller@2fff0000 { + #address-cells = <1>; + compatible = "ti,vim"; + reg = <0x2fff0000 0x2800>; + interrupt-controller; + #interrupt-cells = <4>; /* {IRQ/FIQ, IRQ_NUM, IRQ_TYPE, IRQ_PRIO} */ + status = "okay"; + }; + + systick_timer: timer@2470000 { + compatible = "ti,am654-timer"; + reg = <0x02470000 0x70>; + interrupts = <0 35 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + status = "disabled"; + }; +}; diff --git a/dts/arm/ti/j722s_mcu.dtsi b/dts/arm/ti/j722s_mcu.dtsi new file mode 100644 index 0000000000000..df67bb8b279ff --- /dev/null +++ b/dts/arm/ti/j722s_mcu.dtsi @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Andrew Davis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + mcu_gpio0: gpio@4201010 { + compatible = "ti,davinci-gpio"; + reg = <0x4201010 0x100>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <24>; + status = "disabled"; + }; + + mcu_uart0: uart@4a00000 { + compatible = "ns16550"; + reg = <0x04a00000 0x100>; + clock-frequency = <48000000>; + interrupts = <0 217 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + reg-shift = <2>; + status = "disabled"; + }; +}; diff --git a/dts/arm/ti/j722s_mcu_r5.dtsi b/dts/arm/ti/j722s_mcu_r5.dtsi new file mode 100644 index 0000000000000..a348c2dc43dba --- /dev/null +++ b/dts/arm/ti/j722s_mcu_r5.dtsi @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Andrew Davis + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "j722s_mcu.dtsi" +#include "j722s_main.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-r5"; + reg = <0>; + }; + }; + + atcm: memory@0 { + device_type = "memory"; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x00000000 DT_SIZE_K(32)>; + zephyr,memory-region = "ATCM"; + }; + + btcm: memory@41010000 { + device_type = "memory"; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x41010000 DT_SIZE_K(32)>; + zephyr,memory-region = "BTCM"; + }; + + vim: interrupt-controller@7ff0000 { + #address-cells = <1>; + compatible = "ti,vim"; + reg = <0x07ff0000 0x2800>; + interrupt-controller; + #interrupt-cells = <4>; /* {IRQ/FIQ, IRQ_NUM, IRQ_TYPE, IRQ_PRIO} */ + status = "okay"; + }; + + systick_timer: timer@4800000 { + compatible = "ti,am654-timer"; + reg = <0x04800000 0x70>; + interrupts = <0 28 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; + interrupt-parent = <&vim>; + status = "disabled"; + }; +}; diff --git a/dts/arm/we/oceanus1.dtsi b/dts/arm/we/oceanus1.dtsi new file mode 100644 index 0000000000000..e7b5d1e4c38d6 --- /dev/null +++ b/dts/arm/we/oceanus1.dtsi @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 WĂźrth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&clk_lse { + clock-frequency = <32768>; + driving-capability = <1>; + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + hse-tcxo; + status = "okay"; +}; + +&subghzspi { + status = "okay"; + lora: radio@0 { + status = "okay"; + antenna-enable-gpios = <&gpiob 12 GPIO_ACTIVE_HIGH>; /* RF_SW_VCC */ + tx-enable-gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; /* RF_SW_CTRL1 */ + rx-enable-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; /* RF_SW_CTRL1 */ + dio3-tcxo-voltage = ; + tcxo-power-startup-delay-ms = <1>; + power-amplifier-output = "rfo-lp"; + rfo-lp-max-power = <14>; + }; +}; diff --git a/dts/arm64/broadcom/bcm2712.dtsi b/dts/arm64/broadcom/bcm2712.dtsi index 9249cb3622c0b..e99a640eb2efb 100644 --- a/dts/arm64/broadcom/bcm2712.dtsi +++ b/dts/arm64/broadcom/bcm2712.dtsi @@ -87,4 +87,76 @@ #clock-cells = <0>; }; }; + + axi { + #address-cells = <2>; + #size-cells = <1>; + + pcie1: pcie@1000110000 { + compatible = "brcm,brcmstb-pcie"; + reg = <0x10 0x110000 0x9310>, + <0x0 0x0 0x8000000>, + <0x0 0x8000000 0x10000>, + <0x0 0x0 0x10>; + #address-cells = <3>; + #size-cells = <2>; + status = "okay"; + ranges = <0x02000000 0x0 0x0 0x1b 0x0 0x00 0xfffffffc>, + <0x43000000 0x4 0x0 0x18 0x0 0x03 0x00000000>, + <0x03000000 0x0 0x0 0x10 0x0 0x10 0x00000000>; + }; + + pcie2: pcie@1000120000 { + compatible = "brcm,brcmstb-pcie"; + reg = <0x10 0x120000 0x9310>, + <0x0 0x410000 0x4000>, + <0x0 0x0 0x400000>, + <0x0 0x400000 0x4000>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x02000000 0x0 0x0 0x1f 0x0 0x00 0xfffffffc>, + <0x43000000 0x4 0x0 0x1c 0x0 0x03 0x00000000>, + <0x02000000 0x0 0x0 0x1f 0x0 0x00 0x00400000>; + status = "okay"; + + rp1 { + #address-cells = <2>; + #size-cells = <1>; + + gpio0: gpio@1f000d0000 { + compatible = "simple-bus"; + reg = <0x1f 0xd0000 0x30000>; + #address-cells = <1>; + #size-cells = <0>; + + gpio0_0: gpio@0 { + compatible = "raspberrypi,rp1-gpio"; + reg = <0x0 0x10000 0x20000>; + #gpio-cells = <2>; + gpio-controller; + ngpios = <28>; + status = "disabled"; + }; + + gpio0_1: gpio@4000 { + compatible = "raspberrypi,rp1-gpio"; + reg = <0x4000 0x14000 0x24000>; + #gpio-cells = <2>; + gpio-controller; + ngpios = <6>; + status = "disabled"; + }; + + gpio0_2: gpio@8000 { + compatible = "raspberrypi,rp1-gpio"; + reg = <0x8000 0x18000 0x28000>; + #gpio-cells = <2>; + gpio-controller; + ngpios = <20>; + status = "disabled"; + }; + }; + }; + }; + }; }; diff --git a/dts/arm64/intel/intel_socfpga_agilex5.dtsi b/dts/arm64/intel/intel_socfpga_agilex5.dtsi index 9dafdcdd713b3..ed62369c9269d 100644 --- a/dts/arm64/intel/intel_socfpga_agilex5.dtsi +++ b/dts/arm64/intel/intel_socfpga_agilex5.dtsi @@ -1,13 +1,14 @@ /* * SPDX-License-Identifier: Apache-2.0 * - * Copyright (C) 2024, Intel Corporation + * Copyright (C) 2023, Intel Corporation * */ #include #include #include +#include #include / { @@ -108,7 +109,7 @@ interrupt-parent = <&gic>; interrupts = ; interrupt-names = "irq_0"; - clock-frequency = <100000000>; + clocks = <&clock INTEL_SOCFPGA_CLOCK_UART>; resets = <&reset RSTMGR_UART0_RSTLINE>; status = "disabled"; }; @@ -127,7 +128,7 @@ <0x10B92000 0x1000>; reg-names = "reg_base", "combo_phy"; clock-frequency = <200000000>; - power_delay_ms = <1000>; + power-delay-ms = <1000>; resets = <&reset RSTMGR_SDMMC_RSTLINE>, <&reset RSTMGR_SDMMCECC_RSTLINE>, <&reset RSTMGR_SOFTPHY_RSTLINE>; @@ -140,7 +141,7 @@ interrupts = ; reg = <0x10c03000 0x100>; - clock-frequency = <100000000>; + clocks = <&clock INTEL_SOCFPGA_CLOCK_TIMER>; resets = <&reset RSTMGR_SPTIMER0_RSTLINE>; status = "disabled"; }; @@ -151,7 +152,7 @@ interrupts = ; reg = <0x10c03100 0x100>; - clock-frequency = <100000000>; + clocks = <&clock INTEL_SOCFPGA_CLOCK_TIMER>; resets = <&reset RSTMGR_SPTIMER1_RSTLINE>; status = "disabled"; }; @@ -162,7 +163,7 @@ interrupts = ; reg = <0x10D00000 0x100>; - clock-frequency = <100000000>; + clocks = <&clock INTEL_SOCFPGA_CLOCK_TIMER>; resets = <&reset RSTMGR_L4SYSTIMER0_RSTLINE>; status = "disabled"; }; @@ -173,7 +174,7 @@ interrupts = ; reg = <0x10D00100 0x100>; - clock-frequency = <100000000>; + clocks = <&clock INTEL_SOCFPGA_CLOCK_TIMER>; resets = <&reset RSTMGR_L4SYSTIMER1_RSTLINE>; }; diff --git a/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi index 9c3c7c35d1773..7d53dc6a6bddb 100644 --- a/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mm_a53.dtsi @@ -72,6 +72,76 @@ status = "okay"; }; + gpio1: gpio@30200000 { + compatible = "nxp,imx-gpio"; + reg = <0x30200000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <30>; + status = "disabled"; + }; + + gpio2: gpio@30210000 { + compatible = "nxp,imx-gpio"; + reg = <0x30210000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <21>; + status = "disabled"; + }; + + gpio3: gpio@30220000 { + compatible = "nxp,imx-gpio"; + reg = <0x30220000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <26>; + status = "disabled"; + }; + + gpio4: gpio@30230000 { + compatible = "nxp,imx-gpio"; + reg = <0x30230000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + status = "disabled"; + }; + + gpio5: gpio@30240000 { + compatible = "nxp,imx-gpio"; + reg = <0x30240000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <30>; + status = "disabled"; + }; + gpt1: gpt@302d0000 { compatible = "nxp,imx-gpt"; reg = <0x302d0000 DT_SIZE_K(64)>; @@ -139,6 +209,54 @@ status = "disabled"; }; + i2c1: i2c@30a20000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a20000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C1_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c2: i2c@30a30000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a30000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C2_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c3: i2c@30a40000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a40000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C3_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c4: i2c@30a50000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a50000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C4_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + rdc: rdc@303d0000 { compatible = "nxp,rdc"; reg = <0x303d0000 DT_SIZE_K(64)>; @@ -176,3 +294,163 @@ }; }; + +/* + * GPIO pinmux options. These options define the pinmux settings + * for GPIO ports on the package, so that the GPIO driver can + * select GPIO mux options during GPIO configuration. + */ + +&gpio1{ + pinmux = <&iomuxc_gpio1_io00_gpio_io_gpio1_io00>, + <&iomuxc_gpio1_io01_gpio_io_gpio1_io01>, + <&iomuxc_gpio1_io02_gpio_io_gpio1_io02>, + <&iomuxc_gpio1_io03_gpio_io_gpio1_io03>, + <&iomuxc_gpio1_io04_gpio_io_gpio1_io04>, + <&iomuxc_gpio1_io05_gpio_io_gpio1_io05>, + <&iomuxc_gpio1_io06_gpio_io_gpio1_io06>, + <&iomuxc_gpio1_io07_gpio_io_gpio1_io07>, + <&iomuxc_gpio1_io08_gpio_io_gpio1_io08>, + <&iomuxc_gpio1_io09_gpio_io_gpio1_io09>, + <&iomuxc_gpio1_io10_gpio_io_gpio1_io10>, + <&iomuxc_gpio1_io11_gpio_io_gpio1_io11>, + <&iomuxc_gpio1_io12_gpio_io_gpio1_io12>, + <&iomuxc_gpio1_io13_gpio_io_gpio1_io13>, + <&iomuxc_gpio1_io14_gpio_io_gpio1_io14>, + <&iomuxc_gpio1_io15_gpio_io_gpio1_io15>, + <&iomuxc_enet_mdc_gpio_io_gpio1_io16>, + <&iomuxc_enet_mdio_gpio_io_gpio1_io17>, + <&iomuxc_enet_td3_gpio_io_gpio1_io18>, + <&iomuxc_enet_td2_gpio_io_gpio1_io19>, + <&iomuxc_enet_td1_gpio_io_gpio1_io20>, + <&iomuxc_enet_td0_gpio_io_gpio1_io21>, + <&iomuxc_enet_tx_ctl_gpio_io_gpio1_io22>, + <&iomuxc_enet_txc_gpio_io_gpio1_io23>, + <&iomuxc_enet_rx_ctl_gpio_io_gpio1_io24>, + <&iomuxc_enet_rxc_gpio_io_gpio1_io25>, + <&iomuxc_enet_rd0_gpio_io_gpio1_io26>, + <&iomuxc_enet_rd1_gpio_io_gpio1_io27>, + <&iomuxc_enet_rd2_gpio_io_gpio1_io28>, + <&iomuxc_enet_rd3_gpio_io_gpio1_io29>; +}; + +&gpio2{ + pinmux = <&iomuxc_sd1_clk_gpio_io_gpio2_io00>, + <&iomuxc_sd1_cmd_gpio_io_gpio2_io01>, + <&iomuxc_sd1_data0_gpio_io_gpio2_io02>, + <&iomuxc_sd1_data1_gpio_io_gpio2_io03>, + <&iomuxc_sd1_data2_gpio_io_gpio2_io04>, + <&iomuxc_sd1_data3_gpio_io_gpio2_io05>, + <&iomuxc_sd1_data4_gpio_io_gpio2_io06>, + <&iomuxc_sd1_data5_gpio_io_gpio2_io07>, + <&iomuxc_sd1_data6_gpio_io_gpio2_io08>, + <&iomuxc_sd1_data7_gpio_io_gpio2_io09>, + <&iomuxc_sd1_reset_b_gpio_io_gpio2_io10>, + <&iomuxc_sd1_strobe_gpio_io_gpio2_io11>, + <&iomuxc_sd2_cd_b_gpio_io_gpio2_io12>, + <&iomuxc_sd2_clk_gpio_io_gpio2_io13>, + <&iomuxc_sd2_cmd_gpio_io_gpio2_io14>, + <&iomuxc_sd2_data0_gpio_io_gpio2_io15>, + <&iomuxc_sd2_data1_gpio_io_gpio2_io16>, + <&iomuxc_sd2_data2_gpio_io_gpio2_io17>, + <&iomuxc_sd2_data3_gpio_io_gpio2_io18>, + <&iomuxc_sd2_reset_b_gpio_io_gpio2_io19>, + <&iomuxc_sd2_wp_gpio_io_gpio2_io20>; +}; + +&gpio3{ + pinmux = <&iomuxc_nand_ale_gpio_io_gpio3_io00>, + <&iomuxc_nand_ce0_b_gpio_io_gpio3_io01>, + <&iomuxc_nand_ce1_b_gpio_io_gpio3_io02>, + <&iomuxc_nand_ce2_b_gpio_io_gpio3_io03>, + <&iomuxc_nand_ce3_b_gpio_io_gpio3_io04>, + <&iomuxc_nand_cle_gpio_io_gpio3_io05>, + <&iomuxc_nand_data00_gpio_io_gpio3_io06>, + <&iomuxc_nand_data01_gpio_io_gpio3_io07>, + <&iomuxc_nand_data02_gpio_io_gpio3_io08>, + <&iomuxc_nand_data03_gpio_io_gpio3_io09>, + <&iomuxc_nand_data04_gpio_io_gpio3_io10>, + <&iomuxc_nand_data05_gpio_io_gpio3_io11>, + <&iomuxc_nand_data06_gpio_io_gpio3_io12>, + <&iomuxc_nand_data07_gpio_io_gpio3_io13>, + <&iomuxc_nand_dqs_gpio_io_gpio3_io14>, + <&iomuxc_nand_re_b_gpio_io_gpio3_io15>, + <&iomuxc_nand_ready_b_gpio_io_gpio3_io16>, + <&iomuxc_nand_we_b_gpio_io_gpio3_io17>, + <&iomuxc_nand_wp_b_gpio_io_gpio3_io18>, + <&iomuxc_sai5_rxfs_gpio_io_gpio3_io19>, + <&iomuxc_sai5_rxc_gpio_io_gpio3_io20>, + <&iomuxc_sai5_rxd0_gpio_io_gpio3_io21>, + <&iomuxc_sai5_rxd1_gpio_io_gpio3_io22>, + <&iomuxc_sai5_rxd2_gpio_io_gpio3_io23>, + <&iomuxc_sai5_rxd3_gpio_io_gpio3_io24>, + <&iomuxc_sai5_mclk_gpio_io_gpio3_io25>; +}; + +&gpio4{ + pinmux = <&iomuxc_sai1_rxfs_gpio_io_gpio4_io00>, + <&iomuxc_sai1_rxc_gpio_io_gpio4_io01>, + <&iomuxc_sai1_rxd0_gpio_io_gpio4_io02>, + <&iomuxc_sai1_rxd1_gpio_io_gpio4_io03>, + <&iomuxc_sai1_rxd2_gpio_io_gpio4_io04>, + <&iomuxc_sai1_rxd3_gpio_io_gpio4_io05>, + <&iomuxc_sai1_rxd4_gpio_io_gpio4_io06>, + <&iomuxc_sai1_rxd5_gpio_io_gpio4_io07>, + <&iomuxc_sai1_rxd6_gpio_io_gpio4_io08>, + <&iomuxc_sai1_rxd7_gpio_io_gpio4_io09>, + <&iomuxc_sai1_txfs_gpio_io_gpio4_io10>, + <&iomuxc_sai1_txc_gpio_io_gpio4_io11>, + <&iomuxc_sai1_txd0_gpio_io_gpio4_io12>, + <&iomuxc_sai1_txd1_gpio_io_gpio4_io13>, + <&iomuxc_sai1_txd2_gpio_io_gpio4_io14>, + <&iomuxc_sai1_txd3_gpio_io_gpio4_io15>, + <&iomuxc_sai1_txd4_gpio_io_gpio4_io16>, + <&iomuxc_sai1_txd5_gpio_io_gpio4_io17>, + <&iomuxc_sai1_txd6_gpio_io_gpio4_io18>, + <&iomuxc_sai1_txd7_gpio_io_gpio4_io19>, + <&iomuxc_sai1_mclk_gpio_io_gpio4_io20>, + <&iomuxc_sai2_rxfs_gpio_io_gpio4_io21>, + <&iomuxc_sai2_rxc_gpio_io_gpio4_io22>, + <&iomuxc_sai2_rxd0_gpio_io_gpio4_io23>, + <&iomuxc_sai2_txfs_gpio_io_gpio4_io24>, + <&iomuxc_sai2_txc_gpio_io_gpio4_io25>, + <&iomuxc_sai2_txd0_gpio_io_gpio4_io26>, + <&iomuxc_sai2_mclk_gpio_io_gpio4_io27>, + <&iomuxc_sai3_rxfs_gpio_io_gpio4_io28>, + <&iomuxc_sai3_rxc_gpio_io_gpio4_io29>, + <&iomuxc_sai3_rxd_gpio_io_gpio4_io30>, + <&iomuxc_sai3_txfs_gpio_io_gpio4_io31>; +}; + +&gpio5{ + pinmux = <&iomuxc_sai3_txc_gpio_io_gpio5_io00>, + <&iomuxc_sai3_txd_gpio_io_gpio5_io01>, + <&iomuxc_sai3_mclk_gpio_io_gpio5_io02>, + <&iomuxc_spdif_tx_gpio_io_gpio5_io03>, + <&iomuxc_spdif_rx_gpio_io_gpio5_io04>, + <&iomuxc_spdif_ext_clk_gpio_io_gpio5_io05>, + <&iomuxc_ecspi1_sclk_gpio_io_gpio5_io06>, + <&iomuxc_ecspi1_mosi_gpio_io_gpio5_io07>, + <&iomuxc_ecspi1_miso_gpio_io_gpio5_io08>, + <&iomuxc_ecspi1_ss0_gpio_io_gpio5_io09>, + <&iomuxc_ecspi2_sclk_gpio_io_gpio5_io10>, + <&iomuxc_ecspi2_mosi_gpio_io_gpio5_io11>, + <&iomuxc_ecspi2_miso_gpio_io_gpio5_io12>, + <&iomuxc_ecspi2_ss0_gpio_io_gpio5_io13>, + <&iomuxc_i2c1_scl_gpio_io_gpio5_io14>, + <&iomuxc_i2c1_sda_gpio_io_gpio5_io15>, + <&iomuxc_i2c2_scl_gpio_io_gpio5_io16>, + <&iomuxc_i2c2_sda_gpio_io_gpio5_io17>, + <&iomuxc_i2c3_scl_gpio_io_gpio5_io18>, + <&iomuxc_i2c3_sda_gpio_io_gpio5_io19>, + <&iomuxc_i2c4_scl_gpio_io_gpio5_io20>, + <&iomuxc_i2c4_sda_gpio_io_gpio5_io21>, + <&iomuxc_uart1_rxd_gpio_io_gpio5_io22>, + <&iomuxc_uart1_txd_gpio_io_gpio5_io23>, + <&iomuxc_uart2_rxd_gpio_io_gpio5_io24>, + <&iomuxc_uart2_txd_gpio_io_gpio5_io25>, + <&iomuxc_uart3_rxd_gpio_io_gpio5_io26>, + <&iomuxc_uart3_txd_gpio_io_gpio5_io27>, + <&iomuxc_uart4_rxd_gpio_io_gpio5_io28>, + <&iomuxc_uart4_txd_gpio_io_gpio5_io29>; +}; diff --git a/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi index e0b0992928c23..a734b9912ab16 100644 --- a/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mn_a53.dtsi @@ -72,6 +72,77 @@ status = "okay"; }; + gpio1: gpio@30200000 { + compatible = "nxp,imx-gpio"; + reg = <0x30200000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <30>; + status = "disabled"; + }; + + gpio2: gpio@30210000 { + compatible = "nxp,imx-gpio"; + reg = <0x30210000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <21>; + status = "disabled"; + }; + + gpio3: gpio@30220000 { + compatible = "nxp,imx-gpio"; + reg = <0x30220000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <26>; + status = "disabled"; + }; + + gpio4: gpio@30230000 { + compatible = "nxp,imx-gpio"; + reg = <0x30230000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + gpio-reserved-ranges = <0 21>; + status = "disabled"; + }; + + gpio5: gpio@30240000 { + compatible = "nxp,imx-gpio"; + reg = <0x30240000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + ngpios = <30>; + status = "disabled"; + }; + gpt1: gpt@302d0000 { compatible = "nxp,imx-gpt"; reg = <0x302d0000 DT_SIZE_K(64)>; @@ -139,6 +210,54 @@ status = "disabled"; }; + i2c1: i2c@30a20000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a20000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C1_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c2: i2c@30a30000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a30000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C2_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c3: i2c@30a40000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a40000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C3_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c4: i2c@30a50000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a50000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C4_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + rdc: rdc@303d0000 { compatible = "nxp,rdc"; reg = <0x303d0000 DT_SIZE_K(64)>; @@ -175,3 +294,173 @@ }; }; }; + +/* + * GPIO pinmux options. These options define the pinmux settings + * for GPIO ports on the package, so that the GPIO driver can + * select GPIO mux options during GPIO configuration. + */ + +&gpio1{ + pinmux = <&iomuxc_gpio1_io00_gpio_io_gpio1_io0>, + <&iomuxc_gpio1_io01_gpio_io_gpio1_io1>, + <&iomuxc_gpio1_io02_gpio_io_gpio1_io2>, + <&iomuxc_gpio1_io03_gpio_io_gpio1_io3>, + <&iomuxc_gpio1_io04_gpio_io_gpio1_io4>, + <&iomuxc_gpio1_io05_gpio_io_gpio1_io5>, + <&iomuxc_gpio1_io06_gpio_io_gpio1_io6>, + <&iomuxc_gpio1_io07_gpio_io_gpio1_io7>, + <&iomuxc_gpio1_io08_gpio_io_gpio1_io8>, + <&iomuxc_gpio1_io09_gpio_io_gpio1_io9>, + <&iomuxc_gpio1_io10_gpio_io_gpio1_io10>, + <&iomuxc_gpio1_io11_gpio_io_gpio1_io11>, + <&iomuxc_gpio1_io12_gpio_io_gpio1_io12>, + <&iomuxc_gpio1_io13_gpio_io_gpio1_io13>, + <&iomuxc_gpio1_io14_gpio_io_gpio1_io14>, + <&iomuxc_gpio1_io15_gpio_io_gpio1_io15>, + <&iomuxc_enet_mdc_gpio_io_gpio1_io16>, + <&iomuxc_enet_mdio_gpio_io_gpio1_io17>, + <&iomuxc_enet_td3_gpio_io_gpio1_io18>, + <&iomuxc_enet_td2_gpio_io_gpio1_io19>, + <&iomuxc_enet_td1_gpio_io_gpio1_io20>, + <&iomuxc_enet_td0_gpio_io_gpio1_io21>, + <&iomuxc_enet_tx_ctl_gpio_io_gpio1_io22>, + <&iomuxc_enet_txc_gpio_io_gpio1_io23>, + <&iomuxc_enet_rx_ctl_gpio_io_gpio1_io24>, + <&iomuxc_enet_rxc_gpio_io_gpio1_io25>, + <&iomuxc_enet_rd0_gpio_io_gpio1_io26>, + <&iomuxc_enet_rd1_gpio_io_gpio1_io27>, + <&iomuxc_enet_rd2_gpio_io_gpio1_io28>, + <&iomuxc_enet_rd3_gpio_io_gpio1_io29>; +}; + +&gpio2{ + pinmux = <&iomuxc_sd1_clk_gpio_io_gpio2_io0>, + <&iomuxc_sd1_cmd_gpio_io_gpio2_io1>, + <&iomuxc_sd1_data0_gpio_io_gpio2_io2>, + <&iomuxc_sd1_data1_gpio_io_gpio2_io3>, + <&iomuxc_sd1_data2_gpio_io_gpio2_io4>, + <&iomuxc_sd1_data3_gpio_io_gpio2_io5>, + <&iomuxc_sd1_data4_gpio_io_gpio2_io6>, + <&iomuxc_sd1_data5_gpio_io_gpio2_io7>, + <&iomuxc_sd1_data6_gpio_io_gpio2_io8>, + <&iomuxc_sd1_data7_gpio_io_gpio2_io9>, + <&iomuxc_sd1_reset_b_gpio_io_gpio2_io10>, + <&iomuxc_sd1_strobe_gpio_io_gpio2_io11>, + <&iomuxc_sd2_cd_b_gpio_io_gpio2_io12>, + <&iomuxc_sd2_clk_gpio_io_gpio2_io13>, + <&iomuxc_sd2_cmd_gpio_io_gpio2_io14>, + <&iomuxc_sd2_data0_gpio_io_gpio2_io15>, + <&iomuxc_sd2_data1_gpio_io_gpio2_io16>, + <&iomuxc_sd2_data2_gpio_io_gpio2_io17>, + <&iomuxc_sd2_data3_gpio_io_gpio2_io18>, + <&iomuxc_sd2_reset_b_gpio_io_gpio2_io19>, + <&iomuxc_sd2_wp_gpio_io_gpio2_io20>; +}; + +&gpio3{ + pinmux = <&iomuxc_nand_ale_gpio_io_gpio3_io0>, + <&iomuxc_nand_ce0_b_gpio_io_gpio3_io1>, + <&iomuxc_nand_ce1_b_gpio_io_gpio3_io2>, + <&iomuxc_nand_ce2_b_gpio_io_gpio3_io3>, + <&iomuxc_nand_ce3_b_gpio_io_gpio3_io4>, + <&iomuxc_nand_cle_gpio_io_gpio3_io5>, + <&iomuxc_nand_data00_gpio_io_gpio3_io6>, + <&iomuxc_nand_data01_gpio_io_gpio3_io7>, + <&iomuxc_nand_data02_gpio_io_gpio3_io8>, + <&iomuxc_nand_data03_gpio_io_gpio3_io9>, + <&iomuxc_nand_data04_gpio_io_gpio3_io10>, + <&iomuxc_nand_data05_gpio_io_gpio3_io11>, + <&iomuxc_nand_data06_gpio_io_gpio3_io12>, + <&iomuxc_nand_data07_gpio_io_gpio3_io13>, + <&iomuxc_nand_dqs_gpio_io_gpio3_io14>, + <&iomuxc_nand_re_b_gpio_io_gpio3_io15>, + <&iomuxc_nand_ready_b_gpio_io_gpio3_io16>, + <&iomuxc_nand_we_b_gpio_io_gpio3_io17>, + <&iomuxc_nand_wp_b_gpio_io_gpio3_io18>, + <&iomuxc_sai5_rxfs_gpio_io_gpio3_io19>, + <&iomuxc_sai5_rxc_gpio_io_gpio3_io20>, + <&iomuxc_sai5_rxd0_gpio_io_gpio3_io21>, + <&iomuxc_sai5_rxd1_gpio_io_gpio3_io22>, + <&iomuxc_sai5_rxd2_gpio_io_gpio3_io23>, + <&iomuxc_sai5_rxd3_gpio_io_gpio3_io24>, + <&iomuxc_sai5_mclk_gpio_io_gpio3_io25>; +}; + +/* + * Use the NULL pinmux for the GPIO io port which is not available to + * make the driver to be easy. + */ +&iomuxc { + /omit-if-no-ref/ null_pinmux: NULL_PINMUX { + pinmux = <0x0 0 0x0 0 0x0>; + }; +}; + +&gpio4{ + pinmux = <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&null_pinmux>, + <&iomuxc_sai2_rxfs_gpio_io_gpio4_io21>, + <&iomuxc_sai2_rxc_gpio_io_gpio4_io22>, + <&iomuxc_sai2_rxd0_gpio_io_gpio4_io23>, + <&iomuxc_sai2_txfs_gpio_io_gpio4_io24>, + <&iomuxc_sai2_txc_gpio_io_gpio4_io25>, + <&iomuxc_sai2_txd0_gpio_io_gpio4_io26>, + <&iomuxc_sai2_mclk_gpio_io_gpio4_io27>, + <&iomuxc_sai3_rxfs_gpio_io_gpio4_io28>, + <&iomuxc_sai3_rxc_gpio_io_gpio4_io29>, + <&iomuxc_sai3_rxd_gpio_io_gpio4_io30>, + <&iomuxc_sai3_txfs_gpio_io_gpio4_io31>; +}; + +&gpio5{ + pinmux = <&iomuxc_sai3_txc_gpio_io_gpio5_io0>, + <&iomuxc_sai3_txd_gpio_io_gpio5_io1>, + <&iomuxc_sai3_mclk_gpio_io_gpio5_io2>, + <&iomuxc_spdif_tx_gpio_io_gpio5_io3>, + <&iomuxc_spdif_rx_gpio_io_gpio5_io4>, + <&iomuxc_spdif_ext_clk_gpio_io_gpio5_io5>, + <&iomuxc_ecspi1_sclk_gpio_io_gpio5_io6>, + <&iomuxc_ecspi1_mosi_gpio_io_gpio5_io7>, + <&iomuxc_ecspi1_miso_gpio_io_gpio5_io8>, + <&iomuxc_ecspi1_ss0_gpio_io_gpio5_io9>, + <&iomuxc_ecspi2_sclk_gpio_io_gpio5_io10>, + <&iomuxc_ecspi2_mosi_gpio_io_gpio5_io11>, + <&iomuxc_ecspi2_miso_gpio_io_gpio5_io12>, + <&iomuxc_ecspi2_ss0_gpio_io_gpio5_io13>, + <&iomuxc_i2c1_scl_gpio_io_gpio5_io14>, + <&iomuxc_i2c1_sda_gpio_io_gpio5_io15>, + <&iomuxc_i2c2_scl_gpio_io_gpio5_io16>, + <&iomuxc_i2c2_sda_gpio_io_gpio5_io17>, + <&iomuxc_i2c3_scl_gpio_io_gpio5_io18>, + <&iomuxc_i2c3_sda_gpio_io_gpio5_io19>, + <&iomuxc_i2c4_scl_gpio_io_gpio5_io20>, + <&iomuxc_i2c4_sda_gpio_io_gpio5_io21>, + <&iomuxc_uart1_rxd_gpio_io_gpio5_io22>, + <&iomuxc_uart1_txd_gpio_io_gpio5_io23>, + <&iomuxc_uart2_rxd_gpio_io_gpio5_io24>, + <&iomuxc_uart2_txd_gpio_io_gpio5_io25>, + <&iomuxc_uart3_rxd_gpio_io_gpio5_io26>, + <&iomuxc_uart3_txd_gpio_io_gpio5_io27>, + <&iomuxc_uart4_rxd_gpio_io_gpio5_io28>, + <&iomuxc_uart4_txd_gpio_io_gpio5_io29>; +}; diff --git a/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi index 5913da254486c..b61daa8701023 100644 --- a/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi @@ -78,6 +78,71 @@ #clock-cells = <3>; }; + gpio1: gpio@30200000 { + compatible = "nxp,imx-gpio"; + reg = <0x30200000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpio2: gpio@30210000 { + compatible = "nxp,imx-gpio"; + reg = <0x30210000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpio3: gpio@30220000 { + compatible = "nxp,imx-gpio"; + reg = <0x30220000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpio4: gpio@30230000 { + compatible = "nxp,imx-gpio"; + reg = <0x30230000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpio5: gpio@30240000 { + compatible = "nxp,imx-gpio"; + reg = <0x30240000 DT_SIZE_K(64)>; + interrupts = , + ; + interrupt-names = "irq_0", "irq_1"; + interrupt-parent = <&gic>; + rdc = ; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + gpt1: gpt@302d0000 { compatible = "nxp,imx-gpt"; reg = <0x302d0000 DT_SIZE_K(64)>; @@ -124,6 +189,78 @@ status = "disabled"; }; + i2c1: i2c@30a20000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a20000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C1_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c2: i2c@30a30000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a30000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C2_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c3: i2c@30a40000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a40000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C3_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c4: i2c@30a50000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30a50000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C4_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c5: i2c@30ad0000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30ad0000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C5_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + + i2c6: i2c@30ae0000 { + compatible = "nxp,ii2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30ae0000 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_I2C6_CLK 0 0>; + rdc = ; + status = "disabled"; + }; + enet: enet@30be0000 { compatible = "nxp,enet1g"; reg = <0x30be0000 DT_SIZE_K(64)>; @@ -171,3 +308,167 @@ }; }; }; + +/* + * GPIO pinmux options. These options define the pinmux settings + * for GPIO ports on the package, so that the GPIO driver can + * select GPIO mux options during GPIO configuration. + */ + +&gpio1{ + pinmux = <&iomuxc_gpio1_io00_gpio_io_gpio1_io0>, + <&iomuxc_gpio1_io01_gpio_io_gpio1_io1>, + <&iomuxc_gpio1_io02_gpio_io_gpio1_io2>, + <&iomuxc_gpio1_io03_gpio_io_gpio1_io3>, + <&iomuxc_gpio1_io04_gpio_io_gpio1_io4>, + <&iomuxc_gpio1_io05_gpio_io_gpio1_io5>, + <&iomuxc_gpio1_io06_gpio_io_gpio1_io6>, + <&iomuxc_gpio1_io07_gpio_io_gpio1_io7>, + <&iomuxc_gpio1_io08_gpio_io_gpio1_io8>, + <&iomuxc_gpio1_io09_gpio_io_gpio1_io9>, + <&iomuxc_gpio1_io10_gpio_io_gpio1_io10>, + <&iomuxc_gpio1_io11_gpio_io_gpio1_io11>, + <&iomuxc_gpio1_io12_gpio_io_gpio1_io12>, + <&iomuxc_gpio1_io13_gpio_io_gpio1_io13>, + <&iomuxc_gpio1_io14_gpio_io_gpio1_io14>, + <&iomuxc_gpio1_io15_gpio_io_gpio1_io15>, + <&iomuxc_enet_mdc_gpio_io_gpio1_io16>, + <&iomuxc_enet_mdio_gpio_io_gpio1_io17>, + <&iomuxc_enet_td3_gpio_io_gpio1_io18>, + <&iomuxc_enet_td2_gpio_io_gpio1_io19>, + <&iomuxc_enet_td1_gpio_io_gpio1_io20>, + <&iomuxc_enet_td0_gpio_io_gpio1_io21>, + <&iomuxc_enet_tx_ctl_gpio_io_gpio1_io22>, + <&iomuxc_enet_txc_gpio_io_gpio1_io23>, + <&iomuxc_enet_rx_ctl_gpio_io_gpio1_io24>, + <&iomuxc_enet_rxc_gpio_io_gpio1_io25>, + <&iomuxc_enet_rd0_gpio_io_gpio1_io26>, + <&iomuxc_enet_rd1_gpio_io_gpio1_io27>, + <&iomuxc_enet_rd2_gpio_io_gpio1_io28>, + <&iomuxc_enet_rd3_gpio_io_gpio1_io29>; +}; + +&gpio2{ + pinmux = <&iomuxc_sd1_clk_gpio_io_gpio2_io0>, + <&iomuxc_sd1_cmd_gpio_io_gpio2_io1>, + <&iomuxc_sd1_data0_gpio_io_gpio2_io2>, + <&iomuxc_sd1_data1_gpio_io_gpio2_io3>, + <&iomuxc_sd1_data2_gpio_io_gpio2_io4>, + <&iomuxc_sd1_data3_gpio_io_gpio2_io5>, + <&iomuxc_sd1_data4_gpio_io_gpio2_io6>, + <&iomuxc_sd1_data5_gpio_io_gpio2_io7>, + <&iomuxc_sd1_data6_gpio_io_gpio2_io8>, + <&iomuxc_sd1_data7_gpio_io_gpio2_io9>, + <&iomuxc_sd1_reset_b_gpio_io_gpio2_io10>, + <&iomuxc_sd1_strobe_gpio_io_gpio2_io11>, + <&iomuxc_sd2_cd_b_gpio_io_gpio2_io12>, + <&iomuxc_sd2_clk_gpio_io_gpio2_io13>, + <&iomuxc_sd2_cmd_gpio_io_gpio2_io14>, + <&iomuxc_sd2_data0_gpio_io_gpio2_io15>, + <&iomuxc_sd2_data1_gpio_io_gpio2_io16>, + <&iomuxc_sd2_data2_gpio_io_gpio2_io17>, + <&iomuxc_sd2_data3_gpio_io_gpio2_io18>, + <&iomuxc_sd2_reset_b_gpio_io_gpio2_io19>, + <&iomuxc_sd2_wp_gpio_io_gpio2_io20>; +}; + +&gpio3{ + pinmux = <&iomuxc_nand_ale_gpio_io_gpio3_io0>, + <&iomuxc_nand_ce0_b_gpio_io_gpio3_io1>, + <&iomuxc_nand_ce1_b_gpio_io_gpio3_io2>, + <&iomuxc_nand_ce2_b_gpio_io_gpio3_io3>, + <&iomuxc_nand_ce3_b_gpio_io_gpio3_io4>, + <&iomuxc_nand_cle_gpio_io_gpio3_io5>, + <&iomuxc_nand_data00_gpio_io_gpio3_io6>, + <&iomuxc_nand_data01_gpio_io_gpio3_io7>, + <&iomuxc_nand_data02_gpio_io_gpio3_io8>, + <&iomuxc_nand_data03_gpio_io_gpio3_io9>, + <&iomuxc_nand_data04_gpio_io_gpio3_io10>, + <&iomuxc_nand_data05_gpio_io_gpio3_io11>, + <&iomuxc_nand_data06_gpio_io_gpio3_io12>, + <&iomuxc_nand_data07_gpio_io_gpio3_io13>, + <&iomuxc_nand_dqs_gpio_io_gpio3_io14>, + <&iomuxc_nand_re_b_gpio_io_gpio3_io15>, + <&iomuxc_nand_ready_b_gpio_io_gpio3_io16>, + <&iomuxc_nand_we_b_gpio_io_gpio3_io17>, + <&iomuxc_nand_wp_b_gpio_io_gpio3_io18>, + <&iomuxc_sai5_rxfs_gpio_io_gpio3_io19>, + <&iomuxc_sai5_rxc_gpio_io_gpio3_io20>, + <&iomuxc_sai5_rxd0_gpio_io_gpio3_io21>, + <&iomuxc_sai5_rxd1_gpio_io_gpio3_io22>, + <&iomuxc_sai5_rxd2_gpio_io_gpio3_io23>, + <&iomuxc_sai5_rxd3_gpio_io_gpio3_io24>, + <&iomuxc_sai5_mclk_gpio_io_gpio3_io25>, + <&iomuxc_hdmi_ddc_scl_gpio_io_gpio3_io26>, + <&iomuxc_hdmi_ddc_sda_gpio_io_gpio3_io27>, + <&iomuxc_hdmi_cec_gpio_io_gpio3_io28>, + <&iomuxc_hdmi_hpd_gpio_io_gpio3_io29>; +}; + +&gpio4{ + pinmux = <&iomuxc_sai1_rxfs_gpio_io_gpio4_io0>, + <&iomuxc_sai1_rxc_gpio_io_gpio4_io1>, + <&iomuxc_sai1_rxd0_gpio_io_gpio4_io2>, + <&iomuxc_sai1_rxd1_gpio_io_gpio4_io3>, + <&iomuxc_sai1_rxd2_gpio_io_gpio4_io4>, + <&iomuxc_sai1_rxd3_gpio_io_gpio4_io5>, + <&iomuxc_sai1_rxd4_gpio_io_gpio4_io6>, + <&iomuxc_sai1_rxd5_gpio_io_gpio4_io7>, + <&iomuxc_sai1_rxd6_gpio_io_gpio4_io8>, + <&iomuxc_sai1_rxd7_gpio_io_gpio4_io9>, + <&iomuxc_sai1_txfs_gpio_io_gpio4_io10>, + <&iomuxc_sai1_txc_gpio_io_gpio4_io11>, + <&iomuxc_sai1_txd0_gpio_io_gpio4_io12>, + <&iomuxc_sai1_txd1_gpio_io_gpio4_io13>, + <&iomuxc_sai1_txd2_gpio_io_gpio4_io14>, + <&iomuxc_sai1_txd3_gpio_io_gpio4_io15>, + <&iomuxc_sai1_txd4_gpio_io_gpio4_io16>, + <&iomuxc_sai1_txd5_gpio_io_gpio4_io17>, + <&iomuxc_sai1_txd6_gpio_io_gpio4_io18>, + <&iomuxc_sai1_txd7_gpio_io_gpio4_io19>, + <&iomuxc_sai1_mclk_gpio_io_gpio4_io20>, + <&iomuxc_sai2_rxfs_gpio_io_gpio4_io21>, + <&iomuxc_sai2_rxc_gpio_io_gpio4_io22>, + <&iomuxc_sai2_rxd0_gpio_io_gpio4_io23>, + <&iomuxc_sai2_txfs_gpio_io_gpio4_io24>, + <&iomuxc_sai2_txc_gpio_io_gpio4_io25>, + <&iomuxc_sai2_txd0_gpio_io_gpio4_io26>, + <&iomuxc_sai2_mclk_gpio_io_gpio4_io27>, + <&iomuxc_sai3_rxfs_gpio_io_gpio4_io28>, + <&iomuxc_sai3_rxc_gpio_io_gpio4_io29>, + <&iomuxc_sai3_rxd_gpio_io_gpio4_io30>, + <&iomuxc_sai3_txfs_gpio_io_gpio4_io31>; +}; + +&gpio5{ + pinmux = <&iomuxc_sai3_txc_gpio_io_gpio5_io0>, + <&iomuxc_sai3_txd_gpio_io_gpio5_io1>, + <&iomuxc_sai3_mclk_gpio_io_gpio5_io2>, + <&iomuxc_spdif_tx_gpio_io_gpio5_io3>, + <&iomuxc_spdif_rx_gpio_io_gpio5_io4>, + <&iomuxc_spdif_ext_clk_gpio_io_gpio5_io5>, + <&iomuxc_ecspi1_sclk_gpio_io_gpio5_io6>, + <&iomuxc_ecspi1_mosi_gpio_io_gpio5_io7>, + <&iomuxc_ecspi1_miso_gpio_io_gpio5_io8>, + <&iomuxc_ecspi1_ss0_gpio_io_gpio5_io9>, + <&iomuxc_ecspi2_sclk_gpio_io_gpio5_io10>, + <&iomuxc_ecspi2_mosi_gpio_io_gpio5_io11>, + <&iomuxc_ecspi2_miso_gpio_io_gpio5_io12>, + <&iomuxc_ecspi2_ss0_gpio_io_gpio5_io13>, + <&iomuxc_i2c1_scl_gpio_io_gpio5_io14>, + <&iomuxc_i2c1_sda_gpio_io_gpio5_io15>, + <&iomuxc_i2c2_scl_gpio_io_gpio5_io16>, + <&iomuxc_i2c2_sda_gpio_io_gpio5_io17>, + <&iomuxc_i2c3_scl_gpio_io_gpio5_io18>, + <&iomuxc_i2c3_sda_gpio_io_gpio5_io19>, + <&iomuxc_i2c4_scl_gpio_io_gpio5_io20>, + <&iomuxc_i2c4_sda_gpio_io_gpio5_io21>, + <&iomuxc_uart1_rxd_gpio_io_gpio5_io22>, + <&iomuxc_uart1_txd_gpio_io_gpio5_io23>, + <&iomuxc_uart2_rxd_gpio_io_gpio5_io24>, + <&iomuxc_uart2_txd_gpio_io_gpio5_io25>, + <&iomuxc_uart3_rxd_gpio_io_gpio5_io26>, + <&iomuxc_uart3_txd_gpio_io_gpio5_io27>, + <&iomuxc_uart4_rxd_gpio_io_gpio5_io28>, + <&iomuxc_uart4_txd_gpio_io_gpio5_io29>; +}; diff --git a/dts/arm64/nxp/nxp_mimx91.dtsi b/dts/arm64/nxp/nxp_mimx91.dtsi new file mode 100644 index 0000000000000..872205719bf1f --- /dev/null +++ b/dts/arm64/nxp/nxp_mimx91.dtsi @@ -0,0 +1,95 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0>; + }; + }; + + arch_timer: timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + interrupt-parent = <&gic>; + }; + + psci: psci { + compatible = "arm,psci-1.1"; + method = "smc"; + }; + + gic: interrupt-controller@48000000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x48000000 0x10000>, /* GIC Dist */ + <0x48040000 0xc0000>; /* GICR (RD_base + SGI_base) */ + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; + + iomuxc: iomuxc@443c0000 { + compatible = "nxp,imx-iomuxc"; + reg = <0x443c0000 DT_SIZE_K(64)>; + status = "okay"; + pinctrl: pinctrl { + status = "okay"; + compatible = "nxp,imx93-pinctrl"; + }; + }; + + ana_pll: ana_pll@44480000 { + compatible = "nxp,imx-ana"; + reg = <0x44480000 DT_SIZE_K(64)>; + }; + + ccm: ccm@44450000 { + compatible = "nxp,imx-ccm-rev2"; + reg = <0x44450000 DT_SIZE_K(64)>; + #clock-cells = <3>; + }; + + lpuart1: serial@44380000 { + compatible = "nxp,imx-lpuart", "nxp,lpuart"; + reg = <0x44380000 DT_SIZE_K(64)>; + interrupts = ; + interrupt-names = "irq_0"; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_LPUART1_CLK 0x6c 24>; + status = "disabled"; + }; + + lpuart2: serial@44390000 { + compatible = "nxp,imx-lpuart", "nxp,lpuart"; + reg = <0x44390000 DT_SIZE_K(64)>; + interrupts = ; + interrupt-names = "irq_0"; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_LPUART2_CLK 0x6c 24>; + status = "disabled"; + }; +}; diff --git a/dts/arm64/nxp/nxp_mimx93_a55.dtsi b/dts/arm64/nxp/nxp_mimx93_a55.dtsi index dabdbe12772b2..6af6bdfffc95f 100644 --- a/dts/arm64/nxp/nxp_mimx93_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx93_a55.dtsi @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -124,7 +123,7 @@ }; lpuart1: serial@44380000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x44380000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -134,7 +133,7 @@ }; lpuart2: serial@44390000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x44390000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -346,7 +345,7 @@ interrupts = , ; interrupt-names = "common", "error"; - clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; + clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 14>; clk-source = <0>; status = "disabled"; }; diff --git a/dts/arm64/nxp/nxp_mimx95_a55.dtsi b/dts/arm64/nxp/nxp_mimx95_a55.dtsi index 11f8b07dbcd37..a5edbd0f87e0a 100644 --- a/dts/arm64/nxp/nxp_mimx95_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx95_a55.dtsi @@ -116,7 +116,7 @@ }; lpuart3: serial@42570000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x42570000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -125,7 +125,7 @@ }; lpuart4: serial@42580000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x42580000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -134,7 +134,7 @@ }; lpuart5: serial@42590000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x42590000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -143,7 +143,7 @@ }; lpuart6: serial@425a0000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x425a0000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -152,7 +152,7 @@ }; lpuart7: serial@42690000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x42690000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -161,7 +161,7 @@ }; lpuart8: serial@426a0000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x426a0000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -179,7 +179,7 @@ }; lpuart1: serial@44380000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x44380000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -188,7 +188,7 @@ }; lpuart2: serial@44390000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x44390000 DT_SIZE_K(64)>; interrupts = ; interrupt-names = "irq_0"; @@ -239,4 +239,70 @@ #mbox-cells = <1>; status = "disabled"; }; + + tpm1: tpm@44310000 { + compatible = "nxp,tpm-timer"; + reg = <0x44310000 DT_SIZE_K(64)>; + interrupts = ; + interrupt-names = "irq_0"; + interrupt-parent = <&gic>; + clocks = <&scmi_clk IMX95_CLK_BUSAON>; + prescaler = <1>; + status = "disabled"; + }; + + tpm2: tpm@44320000 { + compatible = "nxp,tpm-timer"; + reg = <0x44320000 DT_SIZE_K(64)>; + interrupts = ; + interrupt-names = "irq_0"; + interrupt-parent = <&gic>; + clocks = <&scmi_clk IMX95_CLK_TPM2>; + prescaler = <1>; + status = "disabled"; + }; + + tpm3: tpm@424e0000 { + compatible = "nxp,tpm-timer"; + reg = <0x424e0000 DT_SIZE_K(64)>; + interrupts = ; + interrupt-names = "irq_0"; + interrupt-parent = <&gic>; + clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>; + prescaler = <1>; + status = "disabled"; + }; + + tpm4: tpm@424f0000 { + compatible = "nxp,tpm-timer"; + reg = <0x424f0000 DT_SIZE_K(64)>; + interrupts = ; + interrupt-names = "irq_0"; + interrupt-parent = <&gic>; + clocks = <&scmi_clk IMX95_CLK_TPM4>; + prescaler = <1>; + status = "disabled"; + }; + + tpm5: tpm@42500000 { + compatible = "nxp,tpm-timer"; + reg = <0x42500000 DT_SIZE_K(64)>; + interrupts = ; + interrupt-names = "irq_0"; + interrupt-parent = <&gic>; + clocks = <&scmi_clk IMX95_CLK_TPM5>; + prescaler = <1>; + status = "disabled"; + }; + + tpm6: tpm@42510000 { + compatible = "nxp,tpm-timer"; + reg = <0x42510000 DT_SIZE_K(64)>; + interrupts = ; + interrupt-names = "irq_0"; + interrupt-parent = <&gic>; + clocks = <&scmi_clk IMX95_CLK_TPM6>; + prescaler = <1>; + status = "disabled"; + }; }; diff --git a/dts/arm64/rockchip/rk3588s.dtsi b/dts/arm64/rockchip/rk3588s.dtsi new file mode 100644 index 0000000000000..4fb37a3113c63 --- /dev/null +++ b/dts/arm64/rockchip/rk3588s.dtsi @@ -0,0 +1,103 @@ +/* + * Copyright 2024 UniversitĂŠ Gustave Eiffel + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x100>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x200>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x300>; + }; + + cpu@4 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x400>; + }; + + cpu@5 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x500>; + }; + + cpu@6 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x600>; + }; + + cpu@7 { + device_type = "cpu"; + compatible = "arm,cortex-a76"; + reg = <0x700>; + }; + }; + + gic: interrupt-controller@fe600000 { + #address-cells = <1>; + compatible = "arm,gic-v3", "arm,gic"; + reg = <0xfe600000 0x10000>, /* GICD */ + <0xfe680000 0x100000>; /* GICR */ + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; + + sram0: memory@10000000 { + reg = <0x10000000 DT_SIZE_M(128)>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + uart2: serial@feb50000 { + compatible = "rockchip,rk3588s-uart", "ns16550"; + reg = <0xfeb50000 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + reg-shift = <2>; + clock-frequency = <350000000>; + }; +}; diff --git a/dts/arm64/ti/ti_am62x_a53.dtsi b/dts/arm64/ti/ti_am62x_a53.dtsi index 183095dd8d0e6..0050c4a937042 100644 --- a/dts/arm64/ti/ti_am62x_a53.dtsi +++ b/dts/arm64/ti/ti_am62x_a53.dtsi @@ -133,4 +133,13 @@ reg-shift = <2>; status = "disabled"; }; + + mbox0: mailbox0@29000000 { + compatible = "ti,omap-mailbox"; + reg = <0x29000000 0x200>; + interrupts = ; + interrupt-parent = <&gic>; + usr-id = <0>; + #mbox-cells = <1>; + }; }; diff --git a/dts/bindings/adc/adc-controller.yaml b/dts/bindings/adc/adc-controller.yaml index c52c913d52206..8f38ccf3e4fb0 100644 --- a/dts/bindings/adc/adc-controller.yaml +++ b/dts/bindings/adc/adc-controller.yaml @@ -41,6 +41,7 @@ child-binding: - ADC_GAIN_1_6: x 1/6 - ADC_GAIN_1_5: x 1/5 - ADC_GAIN_1_4: x 1/4 + - ADC_GAIN_2_7: x 2/7 - ADC_GAIN_1_3: x 1/3 - ADC_GAIN_2_5: x 2/5 - ADC_GAIN_1_2: x 1/2 @@ -62,6 +63,7 @@ child-binding: - "ADC_GAIN_1_6" - "ADC_GAIN_1_5" - "ADC_GAIN_1_4" + - "ADC_GAIN_2_7" - "ADC_GAIN_1_3" - "ADC_GAIN_2_5" - "ADC_GAIN_1_2" diff --git a/dts/bindings/adc/adi,ad4114-adc.yaml b/dts/bindings/adc/adi,ad4114-adc.yaml new file mode 100644 index 0000000000000..3c9f6aa58ef1e --- /dev/null +++ b/dts/bindings/adc/adi,ad4114-adc.yaml @@ -0,0 +1,12 @@ +include: [adc-controller.yaml, spi-device.yaml] + +compatible: "adi,ad4114-adc" + +description: Binding for the ADI AD4114 ADC. + +properties: + map-inputs: + type: array + required: true + description: | + Array of 16 values corresponding to CHANNEL REGISTER 0 TO CHANNEL REGISTER 15. diff --git a/dts/bindings/adc/adi,ad7124-adc.yaml b/dts/bindings/adc/adi,ad7124-adc.yaml new file mode 100644 index 0000000000000..fa79018db3c4c --- /dev/null +++ b/dts/bindings/adc/adi,ad7124-adc.yaml @@ -0,0 +1,119 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Bindings for the ADI AD7124 Analog-to-Digital Converter. + +compatible: adi,ad7124-adc + +include: [adc-controller.yaml, spi-device.yaml] + +properties: + + reference-enable: + type: boolean + description: | + Enable internal reference for AD7124 + - true: Enable internal reference + - false: Disable internal reference + + filter-type-mask: + type: int + default: 0 + description: | + Filter type for AD7124: + Each bit set in this mask enables the filter type, + with the 0th bit corresponding to the 0th channel, + the 1st bit to the 1st channel, and so on. + - 0 means AD7124_FILTER_SINC4 + - 1 means AD7124_FILTER_SINC3 + The default is set to 0 because the filter type is set to SINC4 + for all filter setups upon power-up or after reset. + Therefore, this setting is considered the default for all channels. + + bipolar-mask: + type: int + default: 0xFFFF + description: | + Bipolar configuration for AD7124 + Each bit set in this mask enables the polarity, + with the 0th bit corresponding to the 0th channel, + the 1st bit to the 1st channel, and so on. + - 0 Unipolar operation selection + - 1 Bipolar operation selection + The default is set to 0xFFFF because the bipolar configuration + is activated for all configuration setups upon power-up or after reset. + Therefore, this setting is considered the default for all channels. + + inbuf-enable-mask: + type: int + default: 0xFFFF + description: | + Input buffer configuration for AD7124 + Each bit set in this mask enables the input buffer, + with the 0th bit corresponding to the 0th channel, + the 1st bit to the 1st channel, and so on. + - 0 Analog input pin is unbuffered + - 1 Analog input pin is buffered + The default is set to 0xFFFF because the analog input buffer + is enabled for all configuration setups upon power-up or after reset. + Therefore, this setting is considered the default for all channels. + + refbuf-enable-mask: + type: int + default: 0 + description: | + Reference buffer configuration for AD7124 + Each bit set in this mask enables the reference buffer, + with the 0th bit corresponding to the 0th channel, + the 1st bit to the 1st channel, and so on. + - 0 Reference input pin is unbuffered + - 1 Reference input pin is buffered + The default is set to 0 because the reference input buffer + is enabled for all configuration setups upon power-up or after reset. + Therefore, this setting is considered the default for all channels. + + adc-mode: + type: int + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8] + default: 0 + description: | + ADC operating mode for AD7124 + - 0 AD7124_CONTINUOUS + - 1 AD7124_SINGLE + - 2 AD7124_STANDBY + - 3 AD7124_POWER_DOWN + - 4 AD7124_IDLE + - 5 AD7124_IN_ZERO_SCALE_OFF + - 6 AD7124_IN_FULL_SCALE_GAIN + - 7 AD7124_SYS_ZERO_SCALE_OFF + - 8 AD7124_SYS_ZERO_SCALE_GAIN + The default is set to 0 because the continuous conversion mode + is enabled for control setup upon power-up or after reset. + + power-mode: + type: int + enum: [0, 1, 2] + default: 0 + description: | + Power mode of the ADC for AD7124 + - 0 AD7124_LOW_POWER_MODE + - 1 AD7124_MID_POWER_MODE + - 2 AD7124_HIGH_POWER_MODE + The default is set to 0 because the low power mode + is enabled for control setup upon power-up or after reset. + + active-device: + type: int + enum: [0, 1] + required: true + description: | + Active device for AD7124 + - 0 ID_AD7124_4 + - 1 ID_AD7124_8 + + "#io-channel-cells": + const: 1 + +io-channel-cells: + - input diff --git a/dts/bindings/adc/atmel,sam0-adc.yaml b/dts/bindings/adc/atmel,sam0-adc.yaml index e403b2316b6b7..71c7941bcba66 100644 --- a/dts/bindings/adc/atmel,sam0-adc.yaml +++ b/dts/bindings/adc/atmel,sam0-adc.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2019 Derek Hageman +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 family ADC @@ -8,6 +9,7 @@ compatible: "atmel,sam0-adc" include: - name: adc-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -22,10 +24,11 @@ properties: clock-names: required: true - gclk: - type: int + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: required: true - description: generic clock generator source prescaler: type: int diff --git a/dts/bindings/adc/microchip,xec-adc.yaml b/dts/bindings/adc/microchip,xec-adc.yaml index d642e11130c02..25087cc553ca8 100644 --- a/dts/bindings/adc/microchip,xec-adc.yaml +++ b/dts/bindings/adc/microchip,xec-adc.yaml @@ -33,6 +33,11 @@ properties: required: true description: ADC clock high & low time count value <1:255> + channels: + type: int + required: true + description: Number of ADC channels supported by SoC + pinctrl-0: required: true diff --git a/dts/bindings/adc/renesas,ra-adc.yaml b/dts/bindings/adc/renesas,ra-adc.yaml index c5228a480ab1b..1e5f4315ab0b6 100644 --- a/dts/bindings/adc/renesas,ra-adc.yaml +++ b/dts/bindings/adc/renesas,ra-adc.yaml @@ -24,5 +24,18 @@ properties: "#io-channel-cells": const: 1 + channel-available-mask: + type: int + required: true + description: Mask for ADC channels existed in each board + + average-count: + type: int + default: 1 + enum: [1, 2, 4, 8, 16] + description: The conversion count of the average mode + The ADC module will take multiple samples of an analog signal + and averages them to reduce noise and enhance accuracy + io-channel-cells: - input diff --git a/dts/bindings/adc/silabs,gecko-iadc.yaml b/dts/bindings/adc/silabs,gecko-iadc.yaml index ac0f66847cdb6..73b24f8583d40 100644 --- a/dts/bindings/adc/silabs,gecko-iadc.yaml +++ b/dts/bindings/adc/silabs,gecko-iadc.yaml @@ -5,7 +5,7 @@ description: Silicon Labs Gecko Family IADC compatible: "silabs,gecko-iadc" -include: adc-controller.yaml +include: [adc-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/adc/st,stm32-adc.yaml b/dts/bindings/adc/st,stm32-adc.yaml index b1209142b4ce9..7df14029cc59f 100644 --- a/dts/bindings/adc/st,stm32-adc.yaml +++ b/dts/bindings/adc/st,stm32-adc.yaml @@ -22,15 +22,15 @@ properties: const: 1 st,adc-clock-source: - type: int + type: string required: true enum: - - 1 # SYNC for synchronous ADC clock source - - 2 # ASYNC for asynchronous ADC clock source + - "SYNC" + - "ASYNC" description: | Type of ADC clock source : - - : derived from the bus clock. - - : independent and asynchronous with the bus clock + - "SYNC": derived from the bus clock. + - "ASYNC" : independent and asynchronous with the bus clock One of the two values may not apply to some series. Refer to the RefMan. If an asynchronous clock is selected, a domain clock in the clock property has to be defined explicitly. @@ -94,15 +94,28 @@ properties: Number of sampling time common channels for this ADC instance, if any. st,adc-sequencer: - type: int + type: string required: true enum: - - 0 # NOT_FULLY_CONFIGURABLE - - 1 # FULLY_CONFIGURABLE + - "NOT_FULLY_CONFIGURABLE" + - "FULLY_CONFIGURABLE" description: | Type of ADC sequencer: - - : Not fully configurable sequencer - - : Fully configurable sequencer + - "NOT_FULLY_CONFIGURABLE": Not fully configurable sequencer + - "FULLY_CONFIGURABLE": Fully configurable sequencer + + st,adc-oversampler: + type: string + required: true + enum: + - "OVERSAMPLER_NONE" + - "OVERSAMPLER_MINIMAL" + - "OVERSAMPLER_EXTENDED" + description: | + Type of ADC oversampler: + - "OVERSAMPLER_NONE": No oversampler + - "OVERSAMPLER_MINIMAL": Oversampler with 8 possible oversampling values (2, 4, 8, ..., 256) + - "OVERSAMPLER_EXTENDED": Oversampler with 1024 possible oversampling values (1..1024) io-channel-cells: - input diff --git a/dts/bindings/adc/st,stm32n6-adc.yaml b/dts/bindings/adc/st,stm32n6-adc.yaml new file mode 100644 index 0000000000000..dd791bdcc6729 --- /dev/null +++ b/dts/bindings/adc/st,stm32n6-adc.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 STMicroelectronics + +# SPDX-License-Identifier: Apache-2.0 + +description: | + ST STM32N6 ADC + This compatible stands for STM32N6 ADC. + +compatible: "st,stm32n6-adc" + +include: + - name: st,stm32-adc.yaml + property-blocklist: + - st,adc-clock-source + - st,adc-prescaler diff --git a/dts/bindings/adc/ti,ads114s06.yaml b/dts/bindings/adc/ti,ads114s06.yaml new file mode 100644 index 0000000000000..7a9d65e126916 --- /dev/null +++ b/dts/bindings/adc/ti,ads114s06.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instrument 6 channels 16 bit SPI ADC + +compatible: "ti,ads114s06" + +include: ti,ads1x4s0x-base.yaml diff --git a/dts/bindings/adc/ti,ads114s08.yaml b/dts/bindings/adc/ti,ads114s08.yaml index cf91c11652b7a..45a376e50e37b 100644 --- a/dts/bindings/adc/ti,ads114s08.yaml +++ b/dts/bindings/adc/ti,ads114s08.yaml @@ -5,54 +5,4 @@ description: Texas Instrument 12 channels 16 bit SPI ADC compatible: "ti,ads114s08" -include: [adc-controller.yaml, spi-device.yaml] - -bus: ads114s0x - -properties: - "#io-channel-cells": - const: 1 - - reset-gpios: - type: phandle-array - description: "GPIO for reset" - - drdy-gpios: - type: phandle-array - required: true - description: | - GPIO for data ready, becomes active when a conversion result is ready - - start-sync-gpios: - type: phandle-array - description: | - GPIO for start/sync, used to signal the ADC that a conversion should be started - - idac-current: - type: int - enum: - - 0 - - 10 - - 50 - - 100 - - 250 - - 500 - - 750 - - 1000 - - 1500 - - 2000 - default: 0 - description: | - IDAC current in microampere, the default value turns the current source off - - vbias-level: - type: int - enum: - - 0 - - 1 - default: 0 - description: | - bias voltage level: 0 - (AVDD+AVSS)/2, 1 - (AVDD+AVSS)/12 - -io-channel-cells: - - input +include: ti,ads1x4s0x-base.yaml diff --git a/dts/bindings/adc/ti,ads124s06.yaml b/dts/bindings/adc/ti,ads124s06.yaml new file mode 100644 index 0000000000000..ca113e746264c --- /dev/null +++ b/dts/bindings/adc/ti,ads124s06.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instrument 6 channels 24 bit SPI ADC + +compatible: "ti,ads124s06" + +include: ti,ads1x4s0x-base.yaml diff --git a/dts/bindings/adc/ti,ads124s08.yaml b/dts/bindings/adc/ti,ads124s08.yaml new file mode 100644 index 0000000000000..ab38b3f89258c --- /dev/null +++ b/dts/bindings/adc/ti,ads124s08.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instrument 12 channels 24 bit SPI ADC + +compatible: "ti,ads124s08" + +include: ti,ads1x4s0x-base.yaml diff --git a/dts/bindings/adc/ti,ads131m02.yaml b/dts/bindings/adc/ti,ads131m02.yaml new file mode 100644 index 0000000000000..bc58c5e60daf8 --- /dev/null +++ b/dts/bindings/adc/ti,ads131m02.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Linumiz +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instrument 2 channels SPI ADC + +compatible: "ti,ads131m02" + +include: [adc-controller.yaml, spi-device.yaml] + +properties: + "#io-channel-cells": + const: 1 + + drdy-gpios: + type: phandle-array + required: true + description: | + GPIO for data ready, becomes active when a conversion result is ready. + By default, it is active low signal. + +io-channel-cells: + - input diff --git a/dts/bindings/adc/ti,ads1x4s0x-base.yaml b/dts/bindings/adc/ti,ads1x4s0x-base.yaml new file mode 100644 index 0000000000000..be1070a76ee5c --- /dev/null +++ b/dts/bindings/adc/ti,ads1x4s0x-base.yaml @@ -0,0 +1,54 @@ +# Copyright (c) 2023 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +include: [adc-controller.yaml, spi-device.yaml] + +bus: ads1x4s0x + +properties: + "#io-channel-cells": + const: 1 + + reset-gpios: + type: phandle-array + description: "GPIO for reset" + + drdy-gpios: + type: phandle-array + required: true + description: | + GPIO for data ready, becomes active when a conversion result is ready + + start-sync-gpios: + type: phandle-array + description: | + GPIO for start/sync, used to signal the ADC that a conversion should be started + + idac-current: + type: int + enum: + - 0 + - 10 + - 50 + - 100 + - 250 + - 500 + - 750 + - 1000 + - 1500 + - 2000 + default: 0 + description: | + IDAC current in microampere, the default value turns the current source off + + vbias-level: + type: int + enum: + - 0 + - 1 + default: 0 + description: | + bias voltage level: 0 - (AVDD+AVSS)/2, 1 - (AVDD+AVSS)/12 + +io-channel-cells: + - input diff --git a/dts/bindings/adc/ti,tla2021.yaml b/dts/bindings/adc/ti,tla2021.yaml index 4b3ad6b637922..a1297d60febb4 100644 --- a/dts/bindings/adc/ti,tla2021.yaml +++ b/dts/bindings/adc/ti,tla2021.yaml @@ -5,11 +5,4 @@ description: Texas Instruments TLA2021 Low-Power ADC compatible: "ti,tla2021" -include: [i2c-device.yaml, adc-controller.yaml] - -properties: - "#io-channel-cells": - const: 1 - -io-channel-cells: - - input +include: ti,tla202x-base.yaml diff --git a/dts/bindings/adc/ti,tla2022.yaml b/dts/bindings/adc/ti,tla2022.yaml new file mode 100644 index 0000000000000..15b4dfe1ae630 --- /dev/null +++ b/dts/bindings/adc/ti,tla2022.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Securiton AG +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instruments TLA2022 Low-Power ADC with PGA + +compatible: "ti,tla2022" + +include: ti,tla202x-base.yaml diff --git a/dts/bindings/adc/ti,tla2024.yaml b/dts/bindings/adc/ti,tla2024.yaml new file mode 100644 index 0000000000000..3db0fe7efba1d --- /dev/null +++ b/dts/bindings/adc/ti,tla2024.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Securiton AG +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instruments TLA2024 Low-Power 4 CH ADC with PGA + +compatible: "ti,tla2024" + +include: ti,tla202x-base.yaml diff --git a/dts/bindings/adc/ti,tla202x-base.yaml b/dts/bindings/adc/ti,tla202x-base.yaml new file mode 100644 index 0000000000000..ada49acf82fba --- /dev/null +++ b/dts/bindings/adc/ti,tla202x-base.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Caspar Friedrich +# SPDX-License-Identifier: Apache-2.0 + +include: [i2c-device.yaml, adc-controller.yaml] + +properties: + "#io-channel-cells": + const: 1 + +io-channel-cells: + - input diff --git a/dts/bindings/arm/atmel,sam0-sercom.yaml b/dts/bindings/arm/atmel,sam0-sercom.yaml index 30fb3b59176f2..f3aa21cc281d0 100644 --- a/dts/bindings/arm/atmel,sam0-sercom.yaml +++ b/dts/bindings/arm/atmel,sam0-sercom.yaml @@ -1,8 +1,13 @@ +# Copyright (c) 2024, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + description: Atmel SAM0 multi-protocol (UART, SPI, I2C) SERCOM unit compatible: "atmel,sam0-sercom" -include: base.yaml +include: + - name: base.yaml + - name: atmel,assigned-clocks.yaml properties: reg: diff --git a/dts/bindings/arm/atmel,samd2x-pm.yaml b/dts/bindings/arm/atmel,samd2x-pm.yaml deleted file mode 100644 index 7fa232b815d1a..0000000000000 --- a/dts/bindings/arm/atmel,samd2x-pm.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMD2x Power Manager (PM) - -compatible: "atmel,samd2x-pm" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 2 - -clock-cells: - - offset - - bit diff --git a/dts/bindings/arm/nxp,kinetis-ftm.yaml b/dts/bindings/arm/nxp,kinetis-ftm.yaml deleted file mode 100644 index d0d90e1274d1f..0000000000000 --- a/dts/bindings/arm/nxp,kinetis-ftm.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2017, NXP -# SPDX-License-Identifier: Apache-2.0 - -description: Kinetis FTM - -compatible: "nxp,kinetis-ftm" - -include: base.yaml - -properties: - reg: - required: true - - interrupts: - required: true - - prescaler: - type: int - required: true - enum: - - 1 - - 2 - - 4 - - 8 - - 16 - - 32 - - 64 - - 128 - description: Input clock prescaler diff --git a/dts/bindings/arm/nxp,nbu.yaml b/dts/bindings/arm/nxp,nbu.yaml new file mode 100644 index 0000000000000..789c9a4f63cda --- /dev/null +++ b/dts/bindings/arm/nxp,nbu.yaml @@ -0,0 +1,16 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP NBU interruption information + +include: base.yaml + +compatible: "nxp,nbu" + +properties: + interrupts: + required: true + nbu-name: + default: "NBU NXP" + type: string + description: Name of the Narrow Band Unit interruption initialization diff --git a/dts/bindings/audio/cirrus,c43l22.yaml b/dts/bindings/audio/cirrus,c43l22.yaml new file mode 100644 index 0000000000000..59c5795856567 --- /dev/null +++ b/dts/bindings/audio/cirrus,c43l22.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Titouan Christophe +# SPDX-License-Identifier: Apache-2.0 + +description: Cirrus CS43L22 audio DAC + +include: [i2c-device.yaml] + +compatible: "cirrus,cs43l22" + +properties: + reg: + required: true + + reset-gpios: + required: true + type: phandle-array + description: | + RESET pin diff --git a/dts/bindings/audio/intel,mic-privacy.yaml b/dts/bindings/audio/intel,mic-privacy.yaml new file mode 100644 index 0000000000000..1747479ffef95 --- /dev/null +++ b/dts/bindings/audio/intel,mic-privacy.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Intel ADSP Microphone Privacy + +compatible: "intel,adsp-mic-privacy" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/audio/nordic,nrf-pdm.yaml b/dts/bindings/audio/nordic,nrf-pdm.yaml index c18d9ceebe810..78b08567b7d2b 100644 --- a/dts/bindings/audio/nordic,nrf-pdm.yaml +++ b/dts/bindings/audio/nordic,nrf-pdm.yaml @@ -5,7 +5,7 @@ description: Nordic PDM (Pulse Density Modulation interface) compatible: "nordic,nrf-pdm" -include: [base.yaml, pinctrl-device.yaml] +include: ["base.yaml", "pinctrl-device.yaml", "memory-region.yaml", "nordic-clockpin.yaml"] properties: reg: diff --git a/dts/bindings/audio/nxp,dmic.yaml b/dts/bindings/audio/nxp,dmic.yaml index 77f1d0e74a7c8..eae9bf61c1265 100644 --- a/dts/bindings/audio/nxp,dmic.yaml +++ b/dts/bindings/audio/nxp,dmic.yaml @@ -32,8 +32,11 @@ child-binding: description: | NXP DMIC channel. Can be used to configure filtering and gain attributes of each channel - include: base.yaml - compatible: "nxp,dmic-channel" + include: + - name: base.yaml + property-allowlist: + - reg + - dmas properties: reg: required: true diff --git a/dts/bindings/base/base.yaml b/dts/bindings/base/base.yaml index 485c4dfe7d122..dbc2feb148399 100644 --- a/dts/bindings/base/base.yaml +++ b/dts/bindings/base/base.yaml @@ -5,7 +5,16 @@ include: [pm.yaml] properties: status: type: string - description: indicates the operational status of a device + description: | + Indicates the operational status of the hardware or other + resource that the node represents. In particular: + + - "okay" means the resource is operational and, for example, + can be used by device drivers + - "disabled" means the resource is not operational and the system + should treat it as if it is not present + + For details, see "2.3.4 status" in Devicetree Specification v0.4. enum: - "ok" # Deprecated form - "okay" @@ -17,93 +26,189 @@ properties: compatible: type: string-array required: true - description: compatible strings + description: | + This property is a list of strings that essentially define what + type of hardware or other resource this devicetree node + represents. Each device driver checks for specific compatible + property values to find the devicetree nodes that represent + resources that the driver should manage. + + The recommended format is "vendor,device", The "vendor" part is + an abbreviated name of the vendor. The "device" is usually from + the datasheet. + + The compatible property can have multiple values, ordered from + most- to least-specific. Having additional values is useful when the + device is a specific instance of a more general family, to allow the + system to match the most specific driver available. + + For details, see "2.3.1 compatible" in Devicetree Specification v0.4. reg: type: array - description: register space + description: | + Information used to address the device. The value is specific to + the device (i.e. is different depending on the compatible + property). + + The "reg" property is typically a sequence of (address, length) pairs. + Each pair is called a "register block". Values are + conventionally written in hex. + + For details, see "2.3.6 reg" in Devicetree Specification v0.4. reg-names: type: string-array - description: name of each register space + description: | + Optional names given to each register block in the "reg" property. + For example: + + / { + soc { + #address-cells = <1>; + #size-cells = <1>; + + uart@1000 { + reg = <0x1000 0x2000>, <0x3000 0x4000>; + reg-names = "foo", "bar"; + }; + }; + }; + + The uart@1000 node has two register blocks: + + - one with base address 0x1000, size 0x2000, and name "foo" + - another with base address 0x3000, size 0x4000, and name "bar" interrupts: type: array - description: interrupts for device + description: | + Information about interrupts generated by the device, encoded as an array + of one or more interrupt specifiers. The format of the data in this property + varies by where the device appears in the interrupt tree. Devices with the same + "interrupt-parent" will use the same format in their interrupts properties. + + For details, see "2.4 Interrupts and Interrupt Mapping" in + Devicetree Specification v0.4. # Does not follow the 'type: phandle-array' scheme, but gets type-checked # by the code. Declare it here just so that other bindings can make it # 'required: true' easily if they want to. interrupts-extended: type: compound - description: extended interrupt specifier for device + description: | + Extended interrupt specifier for device, used as an alternative to + the "interrupts" property. + + For details, see "2.4 Interrupts and Interrupt Mapping" in + Devicetree Specification v0.4. interrupt-names: type: string-array - description: name of each interrupt + description: | + Optional names given to each interrupt generated by a device. + The interrupts themselves are defined in either "interrupts" or + "interrupts-extended" properties. + + For details, see "2.4 Interrupts and Interrupt Mapping" in + Devicetree Specification v0.4. interrupt-parent: type: phandle - description: phandle to interrupt controller node + description: | + If present, this refers to the node which handles interrupts generated + by this device. + + For details, see "2.4 Interrupts and Interrupt Mapping" in + Devicetree Specification v0.4. # description of label should be given in bindings inheriting base.yaml # label property is included here to help enforce its type being string label: type: string - description: No description provided for this label + description: | + Human readable string describing the device. Use of this property is + deprecated except as needed on a case-by-case basis. + + For details, see "4.1.2 Miscellaneous Properties" in Devicetree + Specification v0.4. clocks: type: phandle-array - description: Clock gate information + description: | + Information about the device's clock providers. In general, this property + should follow conventions established in the dt-schema binding: + + https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/clock/clock.yaml clock-names: type: string-array - description: name of each clock + description: | + Optional names given to each clock provider in the "clocks" property. "#address-cells": type: int - description: number of address cells in reg property + description: | + This property encodes the number of cells used by address fields + in "reg" properties in this node's children. + + For details, see "2.3.5 #address-cells and #size-cells" in Devicetree + Specification v0.4. "#size-cells": type: int - description: number of size cells in reg property + description: | + This property encodes the number of cells used by size fields in + "reg" properties in this node's children. + + For details, see "2.3.5 #address-cells and #size-cells" in Devicetree + Specification v0.4. dmas: type: phandle-array - description: DMA channels specifiers + description: | + DMA channel specifiers relevant to the device. dma-names: type: string-array - description: Provided names of DMA channel specifiers + description: | + Optional names given to the DMA channel specifiers in the "dmas" property. io-channels: type: phandle-array - description: IO channels specifiers + description: | + IO channel specifiers relevant to the device. io-channel-names: type: string-array - description: Provided names of IO channel specifiers + description: | + Optional names given to the IO channel specifiers in the "io-channels" property. mboxes: type: phandle-array - description: mailbox / IPM channels specifiers + description: | + Mailbox / IPM channel specifiers relevant to the device. specifier-space: mbox mbox-names: type: string-array - description: Provided names of mailbox / IPM channel specifiers + description: | + Optional names given to the mbox specifiers in the "mboxes" property. power-domains: type: phandle-array - description: Power domain specifiers + description: | + Power domain specifiers relevant to the device. power-domain-names: type: string-array - description: Provided names of power domain specifiers + description: | + Optional names given to the power domain specifiers in the "power-domains" property. "#power-domain-cells": type: int - description: Number of cells in power-domains property + description: | + Number of cells in power-domains property zephyr,deferred-init: type: boolean diff --git a/dts/bindings/bluetooth/infineon,cyw43xxx-bt-hci.yaml b/dts/bindings/bluetooth/infineon,cyw43xxx-bt-hci.yaml index 4dcc1f418736a..9f447f89e6f01 100644 --- a/dts/bindings/bluetooth/infineon,cyw43xxx-bt-hci.yaml +++ b/dts/bindings/bluetooth/infineon,cyw43xxx-bt-hci.yaml @@ -21,12 +21,17 @@ description: | /* HW Flow control must be enabled for HCI H4 */ hw-flow-control; - bt-hci { + bt_hci_uart: bt_hci_uart { + compatible = "zephyr,bt-hci-uart"; status = "okay"; - compatible = "infineon,cyw43xxx-bt-hci"; - bt-reg-on-gpios = <&gpio_prt3 4 (GPIO_ACTIVE_HIGH)>; - fw-download-speed = <3000000>; + bt-hci { + status = "okay"; + compatible = "infineon,cyw43xxx-bt-hci"; + bt-reg-on-gpios = <&gpio_prt3 4 (GPIO_ACTIVE_HIGH)>; + + fw-download-speed = <3000000>; + }; }; }; diff --git a/dts/bindings/bluetooth/nxp,hci-ble.yaml b/dts/bindings/bluetooth/nxp,hci-ble.yaml index f6994ebbb212b..529e238b6ba67 100644 --- a/dts/bindings/bluetooth/nxp,hci-ble.yaml +++ b/dts/bindings/bluetooth/nxp,hci-ble.yaml @@ -8,8 +8,6 @@ compatible: "nxp,hci-ble" include: bt-hci.yaml properties: - interrupts: - required: true bt-hci-name: default: "BT NXP" bt-hci-bus: diff --git a/dts/bindings/bluetooth/silabs,siwx91x-bt-hci.yaml b/dts/bindings/bluetooth/silabs,siwx91x-bt-hci.yaml new file mode 100644 index 0000000000000..082005e91882e --- /dev/null +++ b/dts/bindings/bluetooth/silabs,siwx91x-bt-hci.yaml @@ -0,0 +1,13 @@ +description: Bluetooth HCI on Silabs boards + +compatible: "silabs,siwx91x-bt-hci" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "sl:bt:siwx91x" + bt-hci-bus: + default: "virtual" + bt-hci-quirks: + default: ["no-reset"] diff --git a/dts/bindings/can/atmel,sam0-can.yaml b/dts/bindings/can/atmel,sam0-can.yaml index 7002386c9228d..25e8eede7071e 100644 --- a/dts/bindings/can/atmel,sam0-can.yaml +++ b/dts/bindings/can/atmel,sam0-can.yaml @@ -1,3 +1,6 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + description: Specialization of Bosch m_can CAN FD controller for Atmel SAM0 compatible: "atmel,sam0-can" @@ -5,6 +8,7 @@ compatible: "atmel,sam0-can" include: - name: bosch,m_can-base.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -22,6 +26,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + divider: type: int required: true diff --git a/dts/bindings/can/infineon,xmc4xxx-can-node.yaml b/dts/bindings/can/infineon,xmc4xxx-can-node.yaml index 8fa50922aced0..82286874657e6 100644 --- a/dts/bindings/can/infineon,xmc4xxx-can-node.yaml +++ b/dts/bindings/can/infineon,xmc4xxx-can-node.yaml @@ -16,7 +16,7 @@ properties: interrupts: required: true - clock_div8: + clock-div8: description: Option enables clock divide by a factor of 8. type: boolean diff --git a/dts/bindings/can/nordic,nrf-can.yaml b/dts/bindings/can/nordic,nrf-can.yaml index 3834b6763f5eb..805ddf3320cfd 100644 --- a/dts/bindings/can/nordic,nrf-can.yaml +++ b/dts/bindings/can/nordic,nrf-can.yaml @@ -17,6 +17,9 @@ properties: clocks: required: true + clock-names: + required: true + pinctrl-0: required: true diff --git a/dts/bindings/can/renesas,ra-canfd-global.yaml b/dts/bindings/can/renesas,ra-canfd-global.yaml index a737b571ee257..c22688eac29d7 100644 --- a/dts/bindings/can/renesas,ra-canfd-global.yaml +++ b/dts/bindings/can/renesas,ra-canfd-global.yaml @@ -13,3 +13,13 @@ properties: clocks: required: true + + dll-min-freq: + type: int + description: | + Specifies the Data Link Layer clock limit on this device: DLL clock frequency > dll-min-freq. + + dll-max-freq: + type: int + description: | + Specifies the Data Link Layer clock limit on this device: DLL clock frequency < dll-max-freq. diff --git a/dts/bindings/charger/nxp,pf1550-charger.yaml b/dts/bindings/charger/nxp,pf1550-charger.yaml new file mode 100644 index 0000000000000..c149221143857 --- /dev/null +++ b/dts/bindings/charger/nxp,pf1550-charger.yaml @@ -0,0 +1,58 @@ +# Copyright (c), 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +description: NXP PF1550 battery charger + +include: battery.yaml + +compatible: "nxp,pf1550-charger" + +properties: + constant-charge-voltage-max-microvolt: + required: true + + constant-charge-current-max-microamp: + required: true + + pf1550,vbus-current-limit-microamp: + type: int + required: true + description: | + VBUS current limit in microamperes. + + pf1550,system-voltage-min-threshold-microvolt: + type: int + required: true + enum: + - 3500000 + - 3700000 + - 4300000 + description: | + System voltage minimum threshold. + + pf1550,thermistor-monitoring-mode: + type: string + required: true + enum: + - "disabled" + - "thermistor" + - "JEITA-1" + - "JEITA-2" + description: | + Thermistor monitoring mode. + Refer to ThrmCfg register description and Table 2 for details. + + pf1550,int-gpios: + type: phandle-array + required: true + description: Interrupt pin + + pf1550,led-behaviour: + type: string + required: true + enum: + - "on-in-charging-flash-in-fault" + - "flash-in-charging-on-in-fault" + - "manual-off" + description: | + Behaviour for charger LED. diff --git a/dts/bindings/charger/ti,bq24190.yaml b/dts/bindings/charger/ti,bq24190.yaml index 6ff662c9c5850..1b1ad9e97cac7 100644 --- a/dts/bindings/charger/ti,bq24190.yaml +++ b/dts/bindings/charger/ti,bq24190.yaml @@ -13,3 +13,7 @@ properties: constant-charge-voltage-max-microvolt: required: true + + ce-gpios: + type: phandle-array + description: Active low, charge enable pin diff --git a/dts/bindings/clock/atmel,assigned-clocks.yaml b/dts/bindings/clock/atmel,assigned-clocks.yaml new file mode 100644 index 0000000000000..be8c01779be1d --- /dev/null +++ b/dts/bindings/clock/atmel,assigned-clocks.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2024, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +properties: + atmel,assigned-clocks: + type: phandle-array + description: Assigned-clock information + + atmel,assigned-clock-names: + type: string-array + description: Name of each assigned-clock diff --git a/dts/bindings/clock/atmel,sam0-gclk.yaml b/dts/bindings/clock/atmel,sam0-gclk.yaml new file mode 100644 index 0000000000000..9d1059e50c69a --- /dev/null +++ b/dts/bindings/clock/atmel,sam0-gclk.yaml @@ -0,0 +1,66 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Atmel SAMD0 Generic Clock Controller (GCLK) + +compatible: "atmel,sam0-gclk" + +include: + - base.yaml + - clock-controller.yaml + - atmel,assigned-clocks.yaml + +properties: + reg: + required: true + + "#clock-cells": + const: 1 + description: | + - The ID cell is the peripheral identification. + + These information are used on GCLK->CLKCTRL register to select the + clock for an specific peripheral. + + Example 1: Connect the XOSC32K to RTC on SAMD2x + Assuming that generator 2 have the following configuration: + GLKC->GENCTRL: + SRC: 5 (XOSC32K) + ID: 2 (Generator 2) + + Then to enable the clock to the peripheral + Generator: 2 + Identificator: 4 (GCLK_RTC) + + &rtc { + /* The peripheral is fixed and it is defined at soc devictree + * clocks property + */ + clocks = <&gclk 4>, <&pm 0x18 5>; + clock-names = "GCLK", "PM"; + + /* The generator is user selectable and because of that it is + * defined at board + */ + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + }; + + Example 2: Connect the XOSC32K to RTC on SAMD5x + In the SAMD5x the RTC is direct connected on the OSC32KCTRL and no + generator is used. See atmel,sam0-osc32kctrl.yaml for reference. + + "#atmel,assigned-clock-cells": + required: true + type: int + const: 1 + description: | + - The GEN cell is an integer number that represents the index of + the generic clock generator. It is usually a number between 0~8 + but could be more depending of the SoC. + +clock-cells: + - id + +atmel,assigned-clock-cells: + - gen diff --git a/dts/bindings/clock/atmel,sam0-mclk.yaml b/dts/bindings/clock/atmel,sam0-mclk.yaml new file mode 100644 index 0000000000000..b71d81baa3e2f --- /dev/null +++ b/dts/bindings/clock/atmel,sam0-mclk.yaml @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Atmel SAM0 Main Clock Controller (MCLK) + +compatible: "atmel,sam0-mclk" + +include: + - base.yaml + - clock-controller.yaml + +properties: + reg: + required: true + + "#clock-cells": + const: 2 + description: | + - The OFFSET cell is an address of a bus mask. The buses can be + AHB and APB[A-D]. Each bus mask can enable a paripheral clock + selecting the BIT position in the mask. + - The BIT cell is the peripheral bit mask. + + These information are used on PM and MCLK register to select the + clock for an specific peripheral. The generator 2 is used on this + example and can be defined by the user at board. + + Example: Enable SERCOM0 on SAMD21 + &sercom0 { + clocks = <&gclk 0x14>, <&pm 0x20 2>; + clock-names = "GCLK", "PM"; + + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + }; + + Example: Enable SERCOM0 on SAME54 + &sercom0 { + clocks = <&gclk 7>, <&mclk 0x14 12>; + clock-names = "GCLK", "MCLK"; + + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + }; + +clock-cells: + - offset + - bit diff --git a/dts/bindings/clock/atmel,sam0-osc32kctrl.yaml b/dts/bindings/clock/atmel,sam0-osc32kctrl.yaml new file mode 100644 index 0000000000000..e2f25565d911c --- /dev/null +++ b/dts/bindings/clock/atmel,sam0-osc32kctrl.yaml @@ -0,0 +1,38 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Atmel SAM0 32kHz Oscillator Controller (OSC32KCTRL) + +compatible: "atmel,sam0-osc32kctrl" + +include: + - base.yaml + - clock-controller.yaml + - atmel,assigned-clocks.yaml + +properties: + reg: + required: true + + "#clock-cells": + const: 0 + + "#atmel,assigned-clock-cells": + required: true + type: int + const: 1 + description: | + It selects the OSC32CTRL clock to be routed to RTC peripheral + + Example: Connect the XOSC32K to RTC on SAMD5x + + &rtc { + clocks = <&mclk 0x14 9 &osc32kctrl>; + clock-names = "MCLK", "OSC32KCTRL"; + + atmel,assigned-clocks = <&osc32kctrl 4>; + atmel,assigned-clock-names = "OSC32KCTRL"; + }; + +atmel,assigned-clock-cells: + - src diff --git a/dts/bindings/clock/atmel,samc2x-gclk.yaml b/dts/bindings/clock/atmel,samc2x-gclk.yaml deleted file mode 100644 index d1e97272df72f..0000000000000 --- a/dts/bindings/clock/atmel,samc2x-gclk.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2022 Kamil Serwus -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMC2x Generic Clock Controller (GCLK) - -compatible: "atmel,samc2x-gclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 1 - -clock-cells: - - periph_ch diff --git a/dts/bindings/clock/atmel,samc2x-mclk.yaml b/dts/bindings/clock/atmel,samc2x-mclk.yaml deleted file mode 100644 index 227fa5246c015..0000000000000 --- a/dts/bindings/clock/atmel,samc2x-mclk.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2022, Kamil Serwus -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMC2x Generic Clock Controller (MCLK) - -compatible: "atmel,samc2x-mclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 2 - -clock-cells: - - offset - - bit diff --git a/dts/bindings/clock/atmel,samd2x-gclk.yaml b/dts/bindings/clock/atmel,samd2x-gclk.yaml deleted file mode 100644 index f5188aef05f90..0000000000000 --- a/dts/bindings/clock/atmel,samd2x-gclk.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMD2x Generic Clock Controller (GCLK) - -compatible: "atmel,samd2x-gclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 1 - -clock-cells: - - clkctrl_id diff --git a/dts/bindings/clock/atmel,samd5x-gclk.yaml b/dts/bindings/clock/atmel,samd5x-gclk.yaml deleted file mode 100644 index 68fd94b44eb82..0000000000000 --- a/dts/bindings/clock/atmel,samd5x-gclk.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMD5x Generic Clock Controller (GCLK) - -compatible: "atmel,samd5x-gclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 1 - -clock-cells: - - periph_ch diff --git a/dts/bindings/clock/atmel,samd5x-mclk.yaml b/dts/bindings/clock/atmel,samd5x-mclk.yaml deleted file mode 100644 index 603196570daea..0000000000000 --- a/dts/bindings/clock/atmel,samd5x-mclk.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMD5x Generic Clock Controller (MCLK) - -compatible: "atmel,samd5x-mclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 2 - -clock-cells: - - offset - - bit diff --git a/dts/bindings/clock/atmel,saml2x-gclk.yaml b/dts/bindings/clock/atmel,saml2x-gclk.yaml deleted file mode 100644 index 3c9020d505237..0000000000000 --- a/dts/bindings/clock/atmel,saml2x-gclk.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2021 Argentum Systems Ltd. -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAML2x Generic Clock Controller (GCLK) - -compatible: "atmel,saml2x-gclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 1 - -clock-cells: - - periph_ch diff --git a/dts/bindings/clock/atmel,saml2x-mclk.yaml b/dts/bindings/clock/atmel,saml2x-mclk.yaml deleted file mode 100644 index ed89ba36f12e3..0000000000000 --- a/dts/bindings/clock/atmel,saml2x-mclk.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2021 Argentum Systems Ltd. -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAML2x Generic Clock Controller (MCLK) - -compatible: "atmel,saml2x-mclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 2 - -clock-cells: - - offset - - bit diff --git a/dts/bindings/clock/mediatek,mt8195_cpuclk.yaml b/dts/bindings/clock/mediatek,mt8195_cpuclk.yaml index ea85d99580a1c..75d4cb1ed3e10 100644 --- a/dts/bindings/clock/mediatek,mt8195_cpuclk.yaml +++ b/dts/bindings/clock/mediatek,mt8195_cpuclk.yaml @@ -4,13 +4,13 @@ description: MediaTek Audio DSP CPU Frequency Control compatible: "mediatek,mt8195_cpuclk" properties: - freqs_mhz: + freqs-mhz: type: array description: Available frequencies in ascending order required: true reg: type: array - cg_reg: + cg-reg: type: int - pll_ctrl_reg: + pll-ctrl-reg: type: int diff --git a/dts/bindings/clock/nordic,nrf-hsfll-global.yaml b/dts/bindings/clock/nordic,nrf-hsfll-global.yaml new file mode 100644 index 0000000000000..d743cd7667982 --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-hsfll-global.yaml @@ -0,0 +1,44 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic Global HSFLL clock. + + The lowest supported clock frequency is the default + clock frequency. + + Example: + + global_hsfll: global_hsfll { + compatible = "nordic,nrf-hsfll-global"; + clocks = <&fll16>; + #clock-cells = <0>; + clock-frequency = <320000000>; + supported-clock-frequencies = <64000000 + 128000000 + 256000000 + 320000000>; + }; + +compatible: "nordic,nrf-hsfll-global" + +include: + - "base.yaml" + - "clock-controller.yaml" + +properties: + clocks: + required: true + + "#clock-cells": + const: 0 + + supported-clock-frequencies: + type: array + description: Supported clock frequencies in ascending order + + clock-frequency: + type: int + description: | + Optional fixed frequency specified if used in fixed + frequency mode. diff --git a/dts/bindings/clock/nordic,nrf-hsfll-local.yaml b/dts/bindings/clock/nordic,nrf-hsfll-local.yaml new file mode 100644 index 0000000000000..01d0dd7aa3ae6 --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-hsfll-local.yaml @@ -0,0 +1,59 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic nRF local HSFLL + + The local HSFLL mixed-mode IP generates several clock frequencies in the range + from 64 MHz to 400 MHz (in steps of 16 MHz). + + Usage example: + + hsfll: clock@deadbeef { + compatible = "nordic,nrf-hsfll-local"; + reg = <0xdeadbeef 0x1000>; + clocks = <&fll16m>; + clock-frequency = ; + nordic,ficrs = <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_VSUP>, + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_0>, + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_0>; + nordic,ficr-names = "vsup", "coarse", "fine"; + }; + + Required FICR entries are for VSUP, COARSE and FINE trim values. + +compatible: "nordic,nrf-hsfll-local" + +include: [base.yaml, fixed-clock.yaml, nordic-nrf-ficr-client.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + clock-frequency: + enum: + - 64000000 + - 80000000 + - 96000000 + - 112000000 + - 128000000 + - 144000000 + - 160000000 + - 176000000 + - 192000000 + - 208000000 + - 224000000 + - 240000000 + - 256000000 + - 272000000 + - 288000000 + - 304000000 + - 320000000 + - 336000000 + - 352000000 + - 368000000 + - 384000000 + - 400000000 diff --git a/dts/bindings/clock/nordic,nrf-hsfll.yaml b/dts/bindings/clock/nordic,nrf-hsfll.yaml deleted file mode 100644 index f1077dbc4f0e9..0000000000000 --- a/dts/bindings/clock/nordic,nrf-hsfll.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: | - Nordic nRF HSFLL - - The HSFLL mixed-mode IP generates several clock frequencies in the range from - 64 MHz to 400 MHz (in steps of 16 MHz). - - Usage example: - - hsfll: clock@deadbeef { - compatible = "nordic,nrf-hsfll"; - reg = <0xdeadbeef 0x1000>; - clocks = <&fll16m>; - clock-frequency = ; - nordic,ficrs = <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_VSUP>, - <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_0>, - <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_0>; - nordic,ficr-names = "vsup", "coarse", "fine"; - }; - - Required FICR entries are for VSUP, COARSE and FINE trim values. - -compatible: "nordic,nrf-hsfll" - -include: [base.yaml, fixed-clock.yaml, nordic-nrf-ficr-client.yaml] - -properties: - reg: - required: true - - clocks: - required: true - - clock-frequency: - enum: - - 64000000 - - 80000000 - - 96000000 - - 112000000 - - 128000000 - - 144000000 - - 160000000 - - 176000000 - - 192000000 - - 208000000 - - 224000000 - - 240000000 - - 256000000 - - 272000000 - - 288000000 - - 304000000 - - 320000000 - - 336000000 - - 352000000 - - 368000000 - - 384000000 - - 400000000 diff --git a/dts/bindings/clock/nordic,nrf54h-hfxo.yaml b/dts/bindings/clock/nordic,nrf54h-hfxo.yaml index 1dab8b99cf868..26280e770315a 100644 --- a/dts/bindings/clock/nordic,nrf54h-hfxo.yaml +++ b/dts/bindings/clock/nordic,nrf54h-hfxo.yaml @@ -15,16 +15,3 @@ properties: type: int description: Clock accuracy in parts per million required: true - - startup-time-us: - type: int - description: Clock startup time in micro seconds - required: true - - mode: - type: string - description: HFXO operational mode - required: true - enum: - - "crystal" - - "external-square" diff --git a/dts/bindings/clock/nordic,nrf54h-lfxo.yaml b/dts/bindings/clock/nordic,nrf54h-lfxo.yaml index 3a85f27972d82..705c2483ecd12 100644 --- a/dts/bindings/clock/nordic,nrf54h-lfxo.yaml +++ b/dts/bindings/clock/nordic,nrf54h-lfxo.yaml @@ -10,22 +10,3 @@ include: fixed-clock.yaml properties: clock-frequency: const: 32768 - - accuracy-ppm: - type: int - description: Clock accuracy in parts per million - required: true - - startup-time-us: - type: int - description: Clock startup time in micro seconds - required: true - - mode: - type: string - description: LFXO operational mode - required: true - enum: - - "crystal" - - "external-sine" - - "external-square" diff --git a/dts/bindings/clock/realtek,rts5912-sccon.yaml b/dts/bindings/clock/realtek,rts5912-sccon.yaml new file mode 100644 index 0000000000000..594c009523553 --- /dev/null +++ b/dts/bindings/clock/realtek,rts5912-sccon.yaml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +description: Realtek RTS5912 System Clock Controller (SCCON) + +compatible: "realtek,rts5912-sccon" + +include: [clock-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#clock-cells": + const: 2 + +clock-cells: + - clk-grp + - clk-idx diff --git a/dts/bindings/clock/renesas,ra-cgc-pclk.yaml b/dts/bindings/clock/renesas,ra-cgc-pclk.yaml index 798b1d3569f52..c36589d19e17d 100644 --- a/dts/bindings/clock/renesas,ra-cgc-pclk.yaml +++ b/dts/bindings/clock/renesas,ra-cgc-pclk.yaml @@ -8,6 +8,10 @@ compatible: "renesas,ra-cgc-pclk" include: [clock-controller.yaml, base.yaml] properties: + clock-frequency: + type: int + description: clock frequency (Hz) + div: type: int required: true diff --git a/dts/bindings/clock/renesas,rz-cpg.yml b/dts/bindings/clock/renesas,rz-cpg.yml new file mode 100644 index 0000000000000..5124cd3cb12db --- /dev/null +++ b/dts/bindings/clock/renesas,rz-cpg.yml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Renesas Electronics Corporation24 +# SPDX-License-Identifier: Apache-2.0 + +description: RZ Clock Pulse Generator +compatible: "renesas,rz-cpg" + +include: [base.yaml, clock-controller.yaml] + +properties: + + "#clock-cells": + const: 1 + +clock-cells: + - clk-id diff --git a/dts/bindings/clock/silabs,siwx91x-clock.yaml b/dts/bindings/clock/silabs,siwx91x-clock.yaml new file mode 100644 index 0000000000000..80bf83aadb010 --- /dev/null +++ b/dts/bindings/clock/silabs,siwx91x-clock.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Clocks embedded on Silabs SiWx91x chips + +compatible: "silabs,siwx91x-clock" + +include: [clock-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#clock-cells": + const: 1 + +clock-cells: + - clkid diff --git a/dts/bindings/clock/st,stm32-clock-mco.yaml b/dts/bindings/clock/st,stm32-clock-mco.yaml index 6e27ebccf7519..a8c16085ca741 100644 --- a/dts/bindings/clock/st,stm32-clock-mco.yaml +++ b/dts/bindings/clock/st,stm32-clock-mco.yaml @@ -15,7 +15,7 @@ description: | Example: &mco1 { clocks = <&rcc STM32_SRC_LSE MCO1_SEL(7)>; - prescaler = ; + prescaler = ; pinctrl-0 = <&rcc_mco_pa8>; pinctrl-names = "default"; status = "okay"; diff --git a/dts/bindings/clock/st,stm32-clock-mux.yaml b/dts/bindings/clock/st,stm32-clock-mux.yaml index 1798ee686d2ce..a6a1409c69fe3 100644 --- a/dts/bindings/clock/st,stm32-clock-mux.yaml +++ b/dts/bindings/clock/st,stm32-clock-mux.yaml @@ -4,7 +4,7 @@ description: | STM32 Clock multiplexer Describes a clock multiplexer, such as per_ck on STM32H7 or - CLK48 on STM32L5. + CLK48 on STM32WB. The only property of this node is to select a clock input. For instance: &perck { @@ -20,3 +20,8 @@ include: - status - compatible - clocks + +properties: + + clocks: + required: true diff --git a/dts/bindings/clock/st,stm32-rcc.yaml b/dts/bindings/clock/st,stm32-rcc.yaml index ebc6b7e84e3f1..4d7aa666cc34d 100644 --- a/dts/bindings/clock/st,stm32-rcc.yaml +++ b/dts/bindings/clock/st,stm32-rcc.yaml @@ -20,8 +20,8 @@ description: | clocks = <&pll>; /* Select 80MHz pll as SYSCLK source */ ahb-prescaler = <2>; clock-frequency = ; /* = SYSCLK / AHB prescaler */ - apb1-presacler = <1>; - apb2-presacler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; } Specifying a gated clock: @@ -67,6 +67,17 @@ description: | should be the one matching SoC reset state. Confere reference manual to check what is the reset value of the clock source for each peripheral. + Specifying a divided domain clock source: + + Some peripherals are sourced through fixed clock dividers. For such cases there is + STM32_CLOCK_DIV() macro, which allows to specify such divider value. Selecting HSE/2 (HSE + frequency divided by 2) is done with following clock property: + ... { + ... + clocks = <&rcc (STM32_SRC_HSE | STM32_CLOCK_DIV(2)) ...>; + ... + } + compatible: "st,stm32-rcc" include: [clock-controller.yaml, base.yaml] diff --git a/dts/bindings/clock/st,stm32f411-plli2s-clock.yaml b/dts/bindings/clock/st,stm32f411-plli2s-clock.yaml new file mode 100644 index 0000000000000..459e990422dd9 --- /dev/null +++ b/dts/bindings/clock/st,stm32f411-plli2s-clock.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2023, Linaro ltd +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32F411 PLL I2S node binding: + + Fully configurable I2S dedicated PLL. + + 1 output clocks supported, the frequency can be computed with the following formula: + + f(PLLI2S_R) = f(VCO clock) / PLLI2S R --> PLLI2S + + with f(VCO clock) = f(PLL I2S clock input) × (PLLI2S N / PLLI2S M) + + +compatible: "st,stm32f411-plli2s-clock" + +include: st,stm32f4-plli2s-clock.yaml + +properties: + div-m: + type: int + required: true + description: | + Division factor for the PLL input clock + Valid range: 2 - 63 + + div-q: + type: int + description: | + PLLI2S division factor for I2S Clocks to supply USB/SDIO/RNG + enum: + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + - 13 + - 14 + - 15 diff --git a/dts/bindings/clock/st,stm32f412-plli2s-clock.yaml b/dts/bindings/clock/st,stm32f412-plli2s-clock.yaml deleted file mode 100644 index fbe6c78682c27..0000000000000 --- a/dts/bindings/clock/st,stm32f412-plli2s-clock.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2023, Linaro ltd -# SPDX-License-Identifier: Apache-2.0 - -description: | - STM32F412 PLL I2S node binding: - - Fully configurable I2S dedicated PLL. - - 1 output clocks supported, the frequency can be computed with the following formula: - - f(PLLI2S_R) = f(VCO clock) / PLLI2S R --> PLLI2S - - with f(VCO clock) = f(PLL I2S clock input) × (PLLI2S N / PLLI2S M) - - -compatible: "st,stm32f412-plli2s-clock" - -include: st,stm32f4-plli2s-clock.yaml - -properties: - div-m: - type: int - required: true - description: | - Division factor for the PLL input clock - Valid range: 2 - 63 diff --git a/dts/bindings/clock/st,stm32n6-cpu-clock-mux.yaml b/dts/bindings/clock/st,stm32n6-cpu-clock-mux.yaml new file mode 100644 index 0000000000000..653a0b0a15a5b --- /dev/null +++ b/dts/bindings/clock/st,stm32n6-cpu-clock-mux.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2025, STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32N6 CPU Clock + Describes the STM32N6 CPU clock multiplexer. On STM32N6, this is the CPU + clock that feeds the SysTick. + For instance: + &cpusw { + clocks = <&rcc STM32_SRC_IC1 CPU_SEL(3)>; + clock-frequency = ; + status = "okay"; + }; + +compatible: "st,stm32n6-cpu-clock-mux" + +include: + - name: base.yaml + property-allowlist: + - status + - compatible + - clocks + +properties: + clock-frequency: + required: true + type: int + description: | + default frequency in Hz for CPU clock (sysa_ck/sys_cpu_ck) diff --git a/dts/bindings/clock/st,stm32n6-hse-clock.yaml b/dts/bindings/clock/st,stm32n6-hse-clock.yaml new file mode 100644 index 0000000000000..36234050230f7 --- /dev/null +++ b/dts/bindings/clock/st,stm32n6-hse-clock.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: STM32N6 HSE Clock + +compatible: "st,stm32n6-hse-clock" + +include: [fixed-clock.yaml] + +properties: + hse-bypass: + type: boolean + description: | + HSE crystal oscillator bypass + Set to the property to by-pass the oscillator with an external clock. + + hse-div2: + type: boolean + description: | + When set HSE output clock is divided by 2. + Otherwise, no prescaler is used. diff --git a/dts/bindings/clock/st,stm32n6-ic-clock-mux.yaml b/dts/bindings/clock/st,stm32n6-ic-clock-mux.yaml new file mode 100644 index 0000000000000..2462d3166b751 --- /dev/null +++ b/dts/bindings/clock/st,stm32n6-ic-clock-mux.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32N6 Divider IC multiplexer + This node select a clock input and a divider. + For instance: + &ic6 { + pll-src = <2>; + div = <16>; + status = "okay"; + }; + +compatible: "st,stm32n6-ic-clock-mux" + +properties: + pll-src: + type: int + required: true + description: | + PLL clock source + enum: + - 1 + - 2 + - 3 + - 4 + + ic-div: + type: int + description: | + ICx integer division factor + The input ICx frequency is divided by the specified value + Valid range: 1 - 256 diff --git a/dts/bindings/clock/st,stm32n6-pll-clock.yaml b/dts/bindings/clock/st,stm32n6-pll-clock.yaml new file mode 100644 index 0000000000000..b445304aa7d79 --- /dev/null +++ b/dts/bindings/clock/st,stm32n6-pll-clock.yaml @@ -0,0 +1,62 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + PLL node binding for STM32N6 devices + + It can be used to describe 4 different PLLs: PLL1, PLL2, PLL3 and PLL4. + + These PLLs can take one of clk_hse, clk_hsi or clk_msi as input clock, with + an input frequency from 5 to 50 MHz. PLLM factor is used to set the input + clock in this acceptable range. + + Each PLL has one output clock whose frequency can be computed with the + following formula: + + f(PLL_P) = f(VCO clock) / (PLLP1 × PLLP2) + + with f(VCO clock) = f(PLL clock input) × (PLLN / PLLM) + + Note: To reduce the power consumption, it is recommended to configure the VCOx + clock output to the lowest frequency. + + The PLL output frequency must not exceed 3200 MHz. + +compatible: "st,stm32n6-pll-clock" + +include: [clock-controller.yaml, base.yaml] + +properties: + + "#clock-cells": + const: 0 + + clocks: + required: true + + div-m: + type: int + required: true + description: | + Prescaler for PLLx + input clock + Valid range: 1 - 63 + + mul-n: + type: int + required: true + description: | + PLLx multiplication factor for VCO + Valid range: 16 - 2500 + + div-p1: + type: int + description: | + PLLx DIVP1 division factor + Valid range: 1 - 7 + + div-p2: + type: int + description: | + PLLx DIVP2 division factor + Valid range: 1 - 7 diff --git a/dts/bindings/clock/st,stm32n6-rcc.yaml b/dts/bindings/clock/st,stm32n6-rcc.yaml new file mode 100644 index 0000000000000..b3e1750e42a83 --- /dev/null +++ b/dts/bindings/clock/st,stm32n6-rcc.yaml @@ -0,0 +1,125 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32 Reset and Clock controller node for STM32N6 devices + This node is in charge of system clock ('SYSCLK') source selection and + System Clock Generation. + + Configuring STM32 Reset and Clock controller node: + + System clock source should be selected amongst the clock nodes available in "clocks" + node (typically 'clk_hse, clk_csi', 'pll', ...). + As part of this node configuration, SYSCLK frequency should also be defined, using + "clock-frequency" property. + Last, bus clocks (typically HCLK, PCLK1, PCLK2) should be configured using matching + prescaler properties. + Here is an example of correctly configured rcc node: + &rcc { + clocks = <&ic2>; + clock-frequency = ; + ahb-prescaler = <2>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; + apb4-prescaler = <1>; + apb5-prescaler = <1>; + } + + Confere st,stm32-rcc binding for information about domain clocks configuration. + +compatible: "st,stm32n6-rcc" + +include: [clock-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#clock-cells": + const: 2 + + clock-frequency: + required: true + type: int + description: | + default frequency in Hz for clock output + + ahb-prescaler: + type: int + required: true + description: | + AHB clock prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + + apb1-prescaler: + type: int + required: true + description: | + CPU domain APB1 prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + + apb2-prescaler: + type: int + required: true + description: | + CPU domain APB2 prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + + apb4-prescaler: + type: int + required: true + description: | + CPU domain APB4 prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + + apb5-prescaler: + type: int + required: true + description: | + CPU domain APB5 prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + + +clock-cells: + - bus + - bits diff --git a/dts/bindings/comparator/nordic,nrf-comp.yaml b/dts/bindings/comparator/nordic,nrf-comp.yaml index a6f7f32db5fc7..e4f6838d20496 100644 --- a/dts/bindings/comparator/nordic,nrf-comp.yaml +++ b/dts/bindings/comparator/nordic,nrf-comp.yaml @@ -30,7 +30,7 @@ description: | sp-mode = "NORMAL"; th-up = <36>; th-down = <30>; - isource = "OFF"; + isource = "DISABLED"; }; To select an external reference, select the "AREF" @@ -52,8 +52,8 @@ description: | psel = "AIN0"; extrefsel = "AIN1"; sp-mode = "NORMAL"; - hyst = "50MV"; - isource = "OFF"; + enable-hyst; + isource = "DISABLED"; }; compatible: "nordic,nrf-comp" diff --git a/dts/bindings/comparator/nordic,nrf-lpcomp.yaml b/dts/bindings/comparator/nordic,nrf-lpcomp.yaml index 8f9cd91a6b795..64a30b330d8b5 100644 --- a/dts/bindings/comparator/nordic,nrf-lpcomp.yaml +++ b/dts/bindings/comparator/nordic,nrf-lpcomp.yaml @@ -23,7 +23,7 @@ description: | status = "okay"; psel = "AIN0"; refsel = "VDD_4_8"; - hyst = "ENABLED"; + enable-hyst; }; To select an external reference, select the "AREF" diff --git a/dts/bindings/comparator/silabs,acmp.yaml b/dts/bindings/comparator/silabs,acmp.yaml new file mode 100644 index 0000000000000..ccd63b5053b0d --- /dev/null +++ b/dts/bindings/comparator/silabs,acmp.yaml @@ -0,0 +1,124 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 +description: | + Silabs ACMP (Analog Comparator) + + The minimal default configuration for the silabs acmp node is as follows: + + #include + + &acmp0 { + status = "okay"; + + input-positive = ; + input-negative = ; + }; + + Note that there are bindings to retrieve the values for `input-positive` and + `input-negative` properties. See the included bindings in the example above. + + When using the minimal default configuration in the snippet above, some + properties will be implicitly configured with default values. An equivalent + device tree node is therefore as follows: + + #include + + &acmp0 { + status = "okay"; + + bias = <0>; + hysteresis-mode = "disabled"; + accuracy-mode = "low"; + input-range = "full"; + input-positive = ; + input-negative = ; + vref-divider = <63>; + }; + + It is also possible to select a GPIO pin for either/both of the + `input-positive` or `input-negative` properties. In those cases, the + `pinctrl` driver must be configured to allocate an analog bus corresponding + to the port and pin of each GPIO input selected. The following is an example + of how that can be configured: + + #include + #include + + &pinctrl { + acmp0_default: acmp0_default { + group0 { + silabs,analog-bus = ; + }; + }; + }; + + &acmp0 { + pinctrl-0 = <&acmp0_default>; + pinctrl-names = "default"; + status = "okay"; + + bias = <0>; + hysteresis-mode = "disabled"; + accuracy-mode = "low"; + input-range = "full"; + input-positive = ; + input-negative = ; + vref-divider = <63>; + }; + + In the above example, note that the device specific bindings for pinctrl + were included. This header defines the set of analog bus allocations possible + for xg24 parts, and similar headers exist for other parts. + + +compatible: "silabs,acmp" + +include: + - base.yaml + - pinctrl-device.yaml + +properties: + bias: + type: int + default: 0 + + hysteresis-mode: + type: string + enum: + - "disabled" + - "sym10mv" + - "sym20mv" + - "sym30mv" + - "pos10mv" + - "pos20mv" + - "pos30mv" + - "neg10mv" + - "neg20mv" + - "neg30mv" + default: "disabled" + + accuracy-mode: + type: string + enum: + - "low" + - "high" + default: "low" + + input-range: + type: string + enum: + - "full" + - "reduced" + default: "full" + + input-positive: + type: int + required: true + + input-negative: + type: int + required: true + + vref-divider: + type: int + default: 63 diff --git a/dts/bindings/counter/atmel,sam0-tc32.yaml b/dts/bindings/counter/atmel,sam0-tc32.yaml index c523e6e410498..3a9b49f2f3fed 100644 --- a/dts/bindings/counter/atmel,sam0-tc32.yaml +++ b/dts/bindings/counter/atmel,sam0-tc32.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2019 Derek Hageman +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 basic timer counter (TC) operating in 32-bit wide mode @@ -8,6 +9,7 @@ compatible: "atmel,sam0-tc32" include: - name: base.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -22,6 +24,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + prescaler: type: int description: Timer prescaler diff --git a/dts/bindings/rtc/maxim,ds3231.yaml b/dts/bindings/counter/maxim,ds3231.yaml similarity index 100% rename from dts/bindings/rtc/maxim,ds3231.yaml rename to dts/bindings/counter/maxim,ds3231.yaml diff --git a/dts/bindings/counter/nordic,nrf-timer.yaml b/dts/bindings/counter/nordic,nrf-timer.yaml index 9f8395003a85c..8a961f34f8834 100644 --- a/dts/bindings/counter/nordic,nrf-timer.yaml +++ b/dts/bindings/counter/nordic,nrf-timer.yaml @@ -24,20 +24,10 @@ properties: interrupts: required: true - max-frequency: - type: int - default: 16000000 - description: | - Maximum timer frequency in Hz. - - The default value is 16MHz which was the maximum frequency for all nRF TIMER peripherals - up to the nRF54 series, and still remains the most typical maximum frequency for nRF54 - TIMERs. - prescaler: type: int required: true - description: Prescaler value determines frequency (max-frequency/2^prescaler) + description: Prescaler value determines frequency (base_frequency/2^prescaler) zli: type: boolean diff --git a/dts/bindings/counter/nxp,imx-tmr.yaml b/dts/bindings/counter/nxp,imx-tmr.yaml index b61fe6766a406..27c7ae76b297f 100644 --- a/dts/bindings/counter/nxp,imx-tmr.yaml +++ b/dts/bindings/counter/nxp,imx-tmr.yaml @@ -33,7 +33,7 @@ properties: - "kQTMR_SecSrcTrigPriCnt" - "kQTMR_CascadeCount" - primary_source: + primary-source: type: string required: true description: Primary source of the timer, see qtmr_primary_count_source_t enumerator type @@ -56,7 +56,7 @@ properties: - "kQTMR_ClockDivide_64" - "kQTMR_ClockDivide_128" - secondary_source: + secondary-source: type: string description: Secondary source of the timer, see qtmr_input_source_t enumerator type of the MCUXpresso SDK @@ -66,11 +66,11 @@ properties: - "kQTMR_Counter2InputPin" - "kQTMR_Counter3InputPin" - filter_count: + filter-count: type: int description: Fault filter count (0-255). - filter_period: + filter-period: type: int description: Fault filter period (0-255). diff --git a/dts/bindings/counter/renesas,rz-gtm-counter.yaml b/dts/bindings/counter/renesas,rz-gtm-counter.yaml new file mode 100644 index 0000000000000..99c885db5f096 --- /dev/null +++ b/dts/bindings/counter/renesas,rz-gtm-counter.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ GTM Counter + +compatible: "renesas,rz-gtm-counter" + +include: [base.yaml] diff --git a/dts/bindings/cpu/espressif,xtensa-lx6.yaml b/dts/bindings/cpu/espressif,xtensa-lx6.yaml index 24dd830cb010d..bf6d93f26ef87 100644 --- a/dts/bindings/cpu/espressif,xtensa-lx6.yaml +++ b/dts/bindings/cpu/espressif,xtensa-lx6.yaml @@ -32,3 +32,4 @@ properties: enum: - 40000000 - 32000000 + - 26000000 diff --git a/dts/bindings/cpu/espressif,xtensa-lx7.yaml b/dts/bindings/cpu/espressif,xtensa-lx7.yaml index 33c6503122bb8..3a2e33ff393cd 100644 --- a/dts/bindings/cpu/espressif,xtensa-lx7.yaml +++ b/dts/bindings/cpu/espressif,xtensa-lx7.yaml @@ -31,4 +31,3 @@ properties: description: Value of the external XTAL connected to ESP32. enum: - 40000000 - - 32000000 diff --git a/dts/bindings/cpu/wch,qingke-v2.yaml b/dts/bindings/cpu/wch,qingke-v2.yaml index 0386a78fb8c17..da04a18e29b79 100644 --- a/dts/bindings/cpu/wch,qingke-v2.yaml +++ b/dts/bindings/cpu/wch,qingke-v2.yaml @@ -5,4 +5,4 @@ description: WCH QingKe V2 RISC-V MCU compatible: "wch,qingke-v2" -include: cpu.yaml +include: riscv,cpus.yaml diff --git a/dts/bindings/dac/adi,max22017-dac.yaml b/dts/bindings/dac/adi,max22017-dac.yaml new file mode 100644 index 0000000000000..3497791c079e9 --- /dev/null +++ b/dts/bindings/dac/adi,max22017-dac.yaml @@ -0,0 +1,74 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +include: dac-controller.yaml + +description: Analog Devices MAX22017 16bit DAC + +properties: + "#io-channel-cells": + const: 2 + + num-channels: + type: int + description: Number of DAC output channels. + default: 2 + + resolution: + type: int + description: DAC resolution. + default: 16 + + busy-gpios: + description: Busy line indicating the DAC is calculating next sample. + type: phandle-array + + ldac-gpios: + description: Load both DAC latches at the same time. + type: phandle-array + + polarity-mode: + description: | + Unipolar/bipolar mode selection for channels. + 0 Indicates bipolar mode and 1 unipolar mode. + The default settings to bipolar here align with the default mode of the device. + default: [0, 0] + type: uint8-array + + dac-mode: + description: | + Voltage/current mode selection for channels. + 0 indicates voltage mode and 1 indicates current mode. + The default settings to voltage mode here align with the default mode of the device. + default: [0, 0] + type: uint8-array + + latch-mode: + description: | + Latch mode selection for channels. + 0 means the channel is not latched, 1 means latched. + The default settings to non latched should be more straightforward to use than the latched + mode. The latch mode can be used eitheir with the ldac-gpios to load both channels at the + same time or if no ldac-gpios property is set, latching will be done per channel with a + register write. + default: [0, 0] + type: uint8-array + + overcurrent-mode: + description: | + Overcurrent mode selection for channels. + 0 for current limiting mode + 1 for short circuit protection auto power up mode + 2 for short circuit protection shutdown mode + The default setting to current limiting mode here aligns with the default mode of the device. + default: [0, 0] + type: uint8-array + + timeout: + description: | + Timeout in ms. + The value should be between 100 and 1600ms in increments of 100ms. + type: int + +compatible: "adi,max22017-dac" diff --git a/dts/bindings/dac/atmel,sam0-dac.yaml b/dts/bindings/dac/atmel,sam0-dac.yaml index 05ffd62d33742..8a0f92f0fe5e0 100644 --- a/dts/bindings/dac/atmel,sam0-dac.yaml +++ b/dts/bindings/dac/atmel,sam0-dac.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2020 Google LLC. +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 family DAC @@ -8,6 +9,7 @@ compatible: "atmel,sam0-dac" include: - name: dac-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -19,6 +21,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + reference: type: string description: Reference voltage source diff --git a/dts/bindings/dac/microchip,mcp4728.yaml b/dts/bindings/dac/microchip,mcp4728.yaml index 0a0d8d291c72b..f3fb95a3379b5 100644 --- a/dts/bindings/dac/microchip,mcp4728.yaml +++ b/dts/bindings/dac/microchip,mcp4728.yaml @@ -8,7 +8,7 @@ properties: "#io-channel-cells": const: 1 - voltage_reference: + voltage-reference: type: array required: true description: | @@ -17,7 +17,7 @@ properties: 1 - Internal voltage reference (2.048V) Note: array entries correspond to the successive channels - power_down_mode: + power-down-mode: type: array required: true description: | diff --git a/dts/bindings/dac/renesas,ra-dac-global.yaml b/dts/bindings/dac/renesas,ra-dac-global.yaml new file mode 100644 index 0000000000000..d6d4286ead4d5 --- /dev/null +++ b/dts/bindings/dac/renesas,ra-dac-global.yaml @@ -0,0 +1,25 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA DAC Controller Global + +compatible: "renesas,ra-dac-global" + +include: [base.yaml] + +properties: + has-internal-output: + type: boolean + description: True if the SoC supports the internal output feature in the DAC HWIP + + has-output-amplifier: + type: boolean + description: True if the SoC supports the output amplifier feature in the DAC HWIP + + has-chargepump: + type: boolean + description: True if the SoC supports the chargepump feature in the DAC HWIP + + has-davrefcr: + type: boolean + description: True if the SoC supports the D/A VREF configuration in the DAC HWIP diff --git a/dts/bindings/dac/renesas,ra-dac.yaml b/dts/bindings/dac/renesas,ra-dac.yaml new file mode 100644 index 0000000000000..aabb8a976c9b8 --- /dev/null +++ b/dts/bindings/dac/renesas,ra-dac.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA DAC Controller + +compatible: "renesas,ra-dac" + +include: [dac-controller.yaml, pinctrl-device.yaml] + +properties: + "#io-channel-cells": + const: 1 + +io-channel-cells: + - output diff --git a/dts/bindings/dai/mediatek,afe.yaml b/dts/bindings/dai/mediatek,afe.yaml new file mode 100644 index 0000000000000..53a6d9fe78872 --- /dev/null +++ b/dts/bindings/dai/mediatek,afe.yaml @@ -0,0 +1,63 @@ +description: Mediatek Audio Front End + +compatible: "mediatek,afe" + +include: base.yaml + +properties: + dai_id: + type: int + required: true + description: Host-defined SOF DAI index. Must match the Linux kernel driver. + afe_name: + type: string + required: true + downlink: + type: boolean + description: True/present for downlink (capture) channels + + # These three are two-register arrays defining the DSP registers + # that store the hi and low words of a 64 bit bus/host address. + # + base: + type: array + end: + type: array + cur: + type: array + + # The remaining registers below are three-cell arrays describing a + # bit field as . Most of them are defaultable by + # the driver and can be eliminated from DTS for hardware that does + # not support the feature. See the driver source for details. + # + enable: + type: array + description: Channel enable flag + agent_disable: + type: array + description: Channel disable flag + fs: + type: array + description: Sample rate register + hd: + type: array + description: Sample format register + ch_num: + type: array + description: Channel count register + mono: + type: array + description: Mono flag register + mono_invert: + type: boolean + description: Sense/meaning of mono flag + quad_ch: + type: array + description: Quad channel flag register + int_odd: + type: array + msb: + type: array + msb2: + type: array diff --git a/dts/bindings/dai/nxp,dai-micfil.yaml b/dts/bindings/dai/nxp,dai-micfil.yaml new file mode 100644 index 0000000000000..3c0f5bf7f2178 --- /dev/null +++ b/dts/bindings/dai/nxp,dai-micfil.yaml @@ -0,0 +1,25 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP PDM MICFIL node + +compatible: "nxp,dai-micfil" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + dai-index: + type: int + description: | + Use this property to specify the index of the DAI. At the + moment, this is only used by SOF to fetch the "struct device" + associated with the DAI whose index Linux passes to SOF + through an IPC. If this property is not specified, the DAI + index will be considered 0. + fifo-depth: + type: int + required: true + description: | + Depth (in words) for each channel's FIFO. diff --git a/dts/bindings/dai/nxp,dai-sai.yaml b/dts/bindings/dai/nxp,dai-sai.yaml index 2d9f7e34997a2..082cdb9eef689 100644 --- a/dts/bindings/dai/nxp,dai-sai.yaml +++ b/dts/bindings/dai/nxp,dai-sai.yaml @@ -1,7 +1,47 @@ # Copyright 2023 NXP # SPDX-License-Identifier: Apache-2.0 -description: NXP Synchronous Audio Interface (SAI) node +description: | + NXP Synchronous Audio Interface (SAI) node + + Below you may find some configuration examples: + + 1) Configuring SAI1 for i.MX8QM MEK board + + #include + + dai@59050000 { + compatible = "nxp,dai-sai"; + reg = <0x59050000 DT_SIZE_K(64)>; + interrupt-parent = <&master5>; + interrupts = <28>; + clocks = <&ccm IMX_CCM_SAI1_CLK 0x0 0x0>; + clock-names = "bus"; + dai-index = <1>; + dmas = <&edma0 15 0>, <&edma0 14 0>; + dma-names = "tx", "rx"; + rx-fifo-watermark = <48>; + tx-fifo-watermark = <2>; + fifo-depth = <48>; + rx-sync-mode = <1>; + }; + + 2) Configuring SAI6 for i.MX8ULP EVK9 board + + dai@2da90000 { + compatible = "nxp,dai-sai"; + reg = <0x2da90000 DT_SIZE_K(4)>; + interrupt-parent = <&clic>; + interrupts = <24 0 0>; + dmas = <&edma2 0 72>, <&edma2 1 71>; + dma-names = "tx", "rx"; + dai-index = <6>; + rx-fifo-watermark = <8>; + tx-fifo-watermark = <1>; + fifo-depth = <8>; + rx-sync-mode = <1>; + tx-dataline = <2>; + }; compatible: "nxp,dai-sai" @@ -12,100 +52,46 @@ properties: required: true mclk-is-output: type: boolean - description: | - Use this property to set the SAI MCLK as output or as input. - By default, if this property is not specified, MCLK will be - set as input. Setting the MCLK as output for SAIs which don't - support MCLK configuration will result in a BUILD_ASSERT() - failure. + description: MCLK is configured as output. rx-fifo-watermark: type: int - description: | - Use this property to specify the watermark value for the TX - FIFO. This value needs to be in FIFO words (NOT BYTES). This - value needs to be in the following interval: (0, DEFAULT_FIFO_DEPTH], - otherwise a BUILD_ASSERT() failure will be raised. + description: Watermark value (in FIFO words) of RX FIFO. tx-fifo-watermark: type: int - description: | - Use this property to specify the watermark value for the RX - FIFO. This value needs to be in FIFO words (NOT BYTES). This - value needs to be in the following interval: (0, DEFAULT_FIFO_DEPTH], - otherwise a BUILD_ASSERT() failure will be raised. + description: Watermark value (in FIFO words) of TX FIFO. interrupts: required: true fifo-depth: type: int - description: | - Use this property to set the FIFO depth that will be reported - to other applications calling dai_get_properties(). This value - should be in the following interval: (0, DEFAULT_FIFO_DEPTH], - otherwise a BUILD_ASSERT() failure will be raised. - By DEFAULT_FIFO_DEPTH we mean the actual (hardware) value of - the FIFO depth. This is needed because some applications (e.g: SOF) - use this value to compute the DMA burst size, in which case - DEFAULT_FIFO_DEPTH cannot be used. Generally, reporting a false - FIFO depth should be avoided. Please note that the sanity check - for tx/rx-fifo-watermark uses DEFAULT_FIFO_DEPTH instead of this - value so use with caution. If unsure, it's better to simply not - use this property, in which case the reported value will be - DEFAULT_FIFO_DEPTH. + description: Size (in FIFO words) of the TX/RX FIFO. dai-index: type: int - description: | - Use this property to specify the index of the DAI. At the - moment, this is only used by SOF to fetch the "struct device" - associated with the DAI whose index Linux passes to SOF - through an IPC. If this property is not specified, the DAI - index will be considered 0. + description: Index of the DAI instance. Must match Linux side. tx-sync-mode: type: int enum: - 0 - 1 description: | - Use this property to specify which synchronization mode to use - for the transmitter. At the moment, the only supported modes are: - 1) The transmitter is ASYNC (0) - 2) The transmitter is in SYNC with the receiver (1) - If this property is not specified, the transmitter will be set to ASYNC. - If one side is SYNC then the other MUST be ASYNC. Failing to meet this - condition will result in a failed BUILD_ASSERT(). + Transmitter synchronization mode. + + 0: transmitter is ASYNC to receiver + 1: transmitter is SYNC with receiver rx-sync-mode: type: int enum: - 0 - 1 description: | - Use this property to specify which synchronization mode to use - for the receiver. At the moment, the only supported modes are: - 1) The receiver is ASYNC (0) - 2) The receiver is in SYNC with the transmitter (1) - If this property is not specified, the receiver will be set to ASYNC. - If one side is SYNC then the other MUST be ASYNC. Failing to meet this - condition will result in a failed BUILD_ASSERT(). + Receiver synchronization mode. + + 0: receiver is ASYNC to transmitter + 1: receiver is SYNC with transmitter tx-dataline: type: int description: | - Use this property to specify which transmission data line the SAI should - use. To find out which transmission line you should use you can: - 1) Check the TRM and see if your SAI instance is multiline. If not then - you're going to use transmission line 0. - 2) If your SAI is multiline then you need to check the datasheet and see - the index of the transmission line that's connected to your consumer - (e.g: the codec). - The indexing of the data line starts at 0. If this property is not specified - then the index of the transmission data line will be 0. - Please note that "channel" and "data line" are synnonyms in this context. + Index of the data line to transmit data on in multiline SAI instances. rx-dataline: type: int description: | - Use this property to specify which receive transmission data line the SAI should - use. To find out which receive line you should use you can: - 1) Check the TRM and see if your SAI instance is multiline. If not then - you're going to use receive line 0. - 2) If your SAI is multiline then you need to check the datasheet and see - the index of the receive line that's connected to your consumer (e.g: the codec). - The indexing of the data line starts at 0. If this property is not specified - then the index of the receive data line will be 0. - Please note that "channel" and "data line" are synnonyms in this context. + Index of the data line to receive data on in multiline SAI instances. diff --git a/dts/bindings/display/ftdi,ft800.yaml b/dts/bindings/display/ftdi,ft800.yaml index a0753bef98c37..d09b24e1fc746 100644 --- a/dts/bindings/display/ftdi,ft800.yaml +++ b/dts/bindings/display/ftdi,ft800.yaml @@ -20,7 +20,7 @@ properties: typical main clock was 48MHz and this value is 5, the PCLK will be 9.6 MHz. Must be positive value to enable the screen - pclk_pol: + pclk-pol: type: int required: true description: | diff --git a/dts/bindings/display/galaxycore,gc9x01x.yaml b/dts/bindings/display/galaxycore,gc9x01x.yaml index 7867de55a0dea..e4bf6cd5e4a9b 100644 --- a/dts/bindings/display/galaxycore,gc9x01x.yaml +++ b/dts/bindings/display/galaxycore,gc9x01x.yaml @@ -13,17 +13,26 @@ description: | Here is an example to define a display interface: - &spi2 { - gc9a01a_lcd: gc9a01a_lcd@0 { - compatible = "galaxycore,gc9x01x"; - reg = <0>; - spi-max-frequency = <100000000>; - cmd-data-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; - pixel-format = ; - width = <240>; - height = <240>; - }; + / { + my_mipi_dbi { + compatible = "zephyr,mipi-dbi-spi"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + spi-dev = <&spi2>; + dc-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; + + gc9x01x_lcd: gc9x01x_lcd@0 { + compatible = "galaxycore,gc9x01x"; + reg = <0>; + mipi-max-frequency = ; + pixel-format = ; + width = <240>; + height = <240>; + display-inversion; + }; + }; }; diff --git a/dts/bindings/display/ilitek,ili9806e.yaml b/dts/bindings/display/ilitek,ili9806e.yaml new file mode 100644 index 0000000000000..979394b1cfc9b --- /dev/null +++ b/dts/bindings/display/ilitek,ili9806e.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: ILITEK ILI9806E display controller + +compatible: "ilitek,ili9806e-dsi" + +include: [mipi-dsi-device.yaml, display-controller.yaml] + +properties: + reset-gpios: + type: phandle-array + description: | + The RESETn pin is asserted to disable the sensor causing a hard + reset. The sensor receives this as an active-low signal. + + bl-gpios: + type: phandle-array + description: | + The BLn pin is asserted to control the backlight of the panel. + The sensor receives this as an active-high signal. diff --git a/dts/bindings/display/renesas,ra-glcdc.yaml b/dts/bindings/display/renesas,ra-glcdc.yaml new file mode 100644 index 0000000000000..c57816709c12d --- /dev/null +++ b/dts/bindings/display/renesas,ra-glcdc.yaml @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas Graphic LCD controller + +compatible: "renesas,ra-glcdc" + +include: [display-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + interrupts: + required: true + + interrupt-names: + type: string-array + required: true + description: name of each interrupt + + backlight-gpios: + type: phandle-array + required: true + description: | + The BLn pin is asserted to control the backlight of the panel. + The sensor receives this as an active-high signal. + + input-pixel-format: + type: int + required: true + description: | + Initial input Pixel format for Graphic LCD controller. + + output-pixel-format: + type: int + required: true + description: | + Initial output Pixel format for Graphic LCD controller. diff --git a/dts/bindings/display/sinowealth,sh1106-spi.yaml b/dts/bindings/display/sinowealth,sh1106-spi.yaml index 5fe3a2cf0f57f..5bb843c365d7a 100644 --- a/dts/bindings/display/sinowealth,sh1106-spi.yaml +++ b/dts/bindings/display/sinowealth,sh1106-spi.yaml @@ -8,7 +8,7 @@ compatible: "sinowealth,sh1106" include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] properties: - data_cmd-gpios: + data-cmd-gpios: type: phandle-array required: true description: D/C# pin. diff --git a/dts/bindings/display/sitronix,st7789v.yaml b/dts/bindings/display/sitronix,st7789v.yaml index 9b503eb86bafa..7230eb92a2e32 100644 --- a/dts/bindings/display/sitronix,st7789v.yaml +++ b/dts/bindings/display/sitronix,st7789v.yaml @@ -96,5 +96,13 @@ properties: required: true description: RGB Interface Control Parameter + ready-time-ms: + type: int + default: 40 + description: | + Time it takes for the device from power up to become responsive and + accepting commands. Defaults to 40ms (found by trial and error) if not + provided. + mipi-mode: required: true diff --git a/dts/bindings/display/solomon,ssd1306fb-spi.yaml b/dts/bindings/display/solomon,ssd1306fb-spi.yaml index e382a1a53194d..3d3d5ecde2a62 100644 --- a/dts/bindings/display/solomon,ssd1306fb-spi.yaml +++ b/dts/bindings/display/solomon,ssd1306fb-spi.yaml @@ -8,7 +8,7 @@ compatible: "solomon,ssd1306fb" include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] properties: - data_cmd-gpios: + data-cmd-gpios: type: phandle-array required: true description: D/C# pin. diff --git a/dts/bindings/display/solomon,ssd1309fb-i2c.yaml b/dts/bindings/display/solomon,ssd1309fb-i2c.yaml new file mode 100644 index 0000000000000..ee953a07cc49b --- /dev/null +++ b/dts/bindings/display/solomon,ssd1309fb-i2c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025, Marcio Ribeiro +# SPDX-License-Identifier: Apache-2.0 + +description: SSD1309 128x64 dot-matrix display controller on I2C bus + +compatible: "solomon,ssd1309fb" + +include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/solomon,ssd1309fb-spi.yaml b/dts/bindings/display/solomon,ssd1309fb-spi.yaml new file mode 100644 index 0000000000000..4a24a35d7cdc1 --- /dev/null +++ b/dts/bindings/display/solomon,ssd1309fb-spi.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2025, Marcio Ribeiro +# SPDX-License-Identifier: Apache-2.0 + +description: SSD1309 128x64 dot-matrix display controller on SPI bus + +compatible: "solomon,ssd1309fb" + +include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] + +properties: + data_cmd-gpios: + type: phandle-array + required: true + description: D/C# pin. diff --git a/dts/bindings/dma/infineon,cat1-dma.yaml b/dts/bindings/dma/infineon,cat1-dma.yaml new file mode 100644 index 0000000000000..12cab4b804184 --- /dev/null +++ b/dts/bindings/dma/infineon,cat1-dma.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or +# an affiliate of Cypress Semiconductor Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: Infineon CAT1 DMA node + +compatible: "infineon,cat1-dma" + +include: dma-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + "#dma-cells": + const: 1 + +dma-cells: + - channel diff --git a/dts/bindings/dma/nxp,mcux-edma.yaml b/dts/bindings/dma/nxp,mcux-edma.yaml index 57e79378c0450..17c8b3c3d22b0 100644 --- a/dts/bindings/dma/nxp,mcux-edma.yaml +++ b/dts/bindings/dma/nxp,mcux-edma.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2020, NXP +# Copyright (c) 2020,2024 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP MCUX EDMA controller @@ -65,6 +65,19 @@ properties: description: | eDMA IP revision number. + channels-shared-irq-mask: + type: array + description: | + Describes channel enabled mask value on every IRQ. + The channel number is mapped to the bit value of array element value. + If the interrupt is shared on one channel number, the correspongding + bit is set to 1. + Please note each element of the array must be 32-bit. If there are more + than 32 channels, add one or more 32-bit elements in array(elements + should be contiguous). The software will determine the mask value of + several elements corresponding to the same interrupt according to the + number of channels. + "#dma-cells": type: int required: true diff --git a/dts/bindings/dma/nxp,sdma.yaml b/dts/bindings/dma/nxp,sdma.yaml new file mode 100644 index 0000000000000..817e9528a49f4 --- /dev/null +++ b/dts/bindings/dma/nxp,sdma.yaml @@ -0,0 +1,18 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP SDMA node + +compatible: "nxp,sdma" + +include: [dma-controller.yaml, base.yaml] + +properties: + reg: + required: true + "#dma-cells": + const: 2 + +dma-cells: + - channel + - mux diff --git a/dts/bindings/dma/raspberrypi,pico-dma.yaml b/dts/bindings/dma/raspberrypi,pico-dma.yaml index 10263958b1372..8c74377d199e4 100644 --- a/dts/bindings/dma/raspberrypi,pico-dma.yaml +++ b/dts/bindings/dma/raspberrypi,pico-dma.yaml @@ -7,7 +7,8 @@ description: | channel: Select channel for data transmitting slot: Select peripheral data request - Use the definitions defined in `zephyr/dt-bindings/dma/rpi_pico_dma.h`. + Use the definitions defined in `zephyr/dt-bindings/dma/rpi-pico-dma-rp2040.h`, + or `zephyr/dt-bindings/dma/rpi-pico-dma-rp2350.h` channel-config: A 32bit mask specifying the DMA channel configuration - bit 3: Enable Quiet IRQ diff --git a/dts/bindings/dma/silabs,ldma.yaml b/dts/bindings/dma/silabs,ldma.yaml new file mode 100644 index 0000000000000..88715805d9813 --- /dev/null +++ b/dts/bindings/dma/silabs,ldma.yaml @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Silabs LDMA controller + + The Silabs LDMA is a general-purpose direct memory access controller + capable of supporting 8 independent DMA channels. It supports specific + functions like scatter-gather. + + It is present on silabs radio board devices like EFR32xG21 + +compatible: "silabs,ldma" + +include: dma-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + dma_channels: + type: int + required: true + + "#dma-cells": + const: 1 + +dma-cells: + - slot diff --git a/dts/bindings/dma/silabs,siwx91x-dma.yaml b/dts/bindings/dma/silabs,siwx91x-dma.yaml new file mode 100644 index 0000000000000..c8138e56ff755 --- /dev/null +++ b/dts/bindings/dma/silabs,siwx91x-dma.yaml @@ -0,0 +1,26 @@ +description: Silabs SiWx91x DMA node + +compatible: "silabs,siwx91x-dma" + +include: dma-controller.yaml + +properties: + reg: + required: true + + silabs,sram-desc-addr: + type: int + required: true + description: | + SRAM Address for UDMA Descriptor Storage. This address must correspond to the location + of the udma_addr0 section in the linker script for the dma0 node, and the udma_addr1 + section for the ulpdma node. Ensure that the value specified for the SRAM address matches + the respective section defined in the linker file for each UDMA node, as this alignment + is critical for proper descriptor management and data transfer. + + "#dma-cells": + const: 1 + +# Parameter syntax +dma-cells: + - channel diff --git a/dts/bindings/dma/st,stm32-bdma.yaml b/dts/bindings/dma/st,stm32-bdma.yaml index f8ae5bc68f53e..0e6bf40c7f75d 100644 --- a/dts/bindings/dma/st,stm32-bdma.yaml +++ b/dts/bindings/dma/st,stm32-bdma.yaml @@ -90,7 +90,7 @@ properties: # Parameter syntax of stm32 follows the dma client dts syntax # in the Linux kernel declared in -# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/st,stm32-dma.yaml +# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/stm32/st,stm32-dma.yaml dma-cells: - channel diff --git a/dts/bindings/dma/st,stm32-dma-v1.yaml b/dts/bindings/dma/st,stm32-dma-v1.yaml index 22e1d862ea5da..9d5c9b40a952d 100644 --- a/dts/bindings/dma/st,stm32-dma-v1.yaml +++ b/dts/bindings/dma/st,stm32-dma-v1.yaml @@ -84,7 +84,7 @@ properties: # Parameter syntax of stm32 follows the dma client dts syntax # in the Linux kernel declared in -# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/st,stm32-dma.yaml +# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/stm32/st,stm32-dma.yaml dma-cells: - channel diff --git a/dts/bindings/dma/st,stm32-dma-v2.yaml b/dts/bindings/dma/st,stm32-dma-v2.yaml index 632ff53a90b3b..ed753b8b3df8e 100644 --- a/dts/bindings/dma/st,stm32-dma-v2.yaml +++ b/dts/bindings/dma/st,stm32-dma-v2.yaml @@ -83,7 +83,7 @@ properties: # Parameter syntax of stm32 follows the dma client dts syntax # in the Linux kernel declared in -# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/st,stm32-dma.yaml +# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/stm32/st,stm32-dma.yaml dma-cells: - channel diff --git a/dts/bindings/dma/st,stm32-dma-v2bis.yaml b/dts/bindings/dma/st,stm32-dma-v2bis.yaml index eeda4e94fb6c4..9245c918835b5 100644 --- a/dts/bindings/dma/st,stm32-dma-v2bis.yaml +++ b/dts/bindings/dma/st,stm32-dma-v2bis.yaml @@ -78,7 +78,7 @@ properties: # Parameter syntax of stm32 follows the dma client dts syntax # in the Linux kernel declared in -# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/st,stm32-dma.yaml +# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/stm32/st,stm32-dma.yaml dma-cells: - channel diff --git a/dts/bindings/dma/st,stm32-dmamux.yaml b/dts/bindings/dma/st,stm32-dmamux.yaml index 8fa07a9c053d9..047f925f1e6b9 100644 --- a/dts/bindings/dma/st,stm32-dmamux.yaml +++ b/dts/bindings/dma/st,stm32-dmamux.yaml @@ -71,7 +71,7 @@ properties: # Parameter syntax of stm32 follows the dma client dts syntax # in the Linux kernel declared in -# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/st,stm32-dmamux.yaml +# https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/plain/Bindings/dma/stm32/st,stm32-dmamux.yaml dma-cells: - channel diff --git a/dts/bindings/dsa/microchip,ksz8463.yaml b/dts/bindings/dsa/microchip,ksz8463.yaml new file mode 100644 index 0000000000000..06df462ad4cb9 --- /dev/null +++ b/dts/bindings/dsa/microchip,ksz8463.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Aleksandr Senin +# SPDX-License-Identifier: Apache-2.0 + +description: | + KSZ8463 ethernet switch + +compatible: "microchip,ksz8463" + +include: [microchip_dsa.yaml] diff --git a/dts/bindings/dsa/nxp,netc-switch.yaml b/dts/bindings/dsa/nxp,netc-switch.yaml new file mode 100644 index 0000000000000..11dab38a8f995 --- /dev/null +++ b/dts/bindings/dsa/nxp,netc-switch.yaml @@ -0,0 +1,25 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP NETC ethernet switch + +compatible: "nxp,netc-switch" + +child-binding: + description: Properties of slave port + + include: + - name: pinctrl-device.yaml + - name: ethernet-controller.yaml + property-allowlist: + - reg + - local-mac-address + - phy-handle + - phy-connection-type + + properties: + ethernet: + type: phandle + description: + A phandle to a valid Ethernet device node. This host + device is what the switch port is connected to. diff --git a/dts/bindings/ethernet/davicom,dm8806-phy.yaml b/dts/bindings/ethernet/davicom,dm8806-phy.yaml new file mode 100644 index 0000000000000..13fe82c1e9301 --- /dev/null +++ b/dts/bindings/ethernet/davicom,dm8806-phy.yaml @@ -0,0 +1,61 @@ +# Copyright 2024 Robert Slawinski +# SPDX-License-Identifier: Apache-2.0 + +description: Davicom DM8806 Ethernet MAC and PHY with RMII interface + +compatible: "davicom,dm8806-phy" + +include: [ethernet-phy.yaml] + +on-bus: mdio + +properties: + reg: + required: true + description: | + 5-bit PHY address for Internal PHY Registers group of Davicom DM8806 MAC + PHY Ethernet Switch Controller, separate for each MAC PHY, build in DM8806 + and correlate with Ethenet port. DM8806 has five MAC PHY inside, but it is + not mandatory to define all of them in device tree if there is no need to + communicate with all of them. Each MAC PHY has its own PHY address, which + together with Register address creates the absolute address of the + concrete register in conrete MAC PHY acoring to Clause 22 MDIO + communication standard. Below example shows how the PHY address and + Register address are glued together in Internal PHY Registers group: + + Internal PHY Registers + Port0: (5-bit PHY Address) + (5-bit Register address) = Absolute address + + Absolute address is the address of the concrete register in MAC PHY0 + which is responsible for Ethernet Port0 in Davicom DM8806 + reg-switch: + required: true + description: | + 5-bit PHY address for Switch Per-Port Registers group of Davicom DM8806 + MAC PHY Ethernet Switch Controller, separate for each MAC PHY, build in + DM8806 and correlate with Ethenet port. DM8806 has five MAC PHY inside, + but it is not mandatory to define all of them in device tree if there is + no need to communicate with all of them. Each MAC PHY has its own PHY + address, which together with Register address creates the absolute address + of the concrete register in conrete MAC PHY acoring to Clause 22 MDIO + communication standard. Below example shows how the PHY address and + Register address are glued together in Switch Per-Port Registers group: + + Switch Per-Port Registers + Port0: (5bit PHY Address) + (5bit Register address) = Absolute address + + Absolute address is the address of the concrete register in MAC PHY0 + which is responsible for Ethernet Port0 in Davicom DM8806 + reset-gpios: + type: phandle-array + description: GPIO connected to MAC PHY reset signal pin. Reset is active low. + int-gpios: + type: phandle-array + description: GPIO for upt signal indicating MAC PHY state change. + davicom,interface-type: + type: string + required: true + description: Which type of phy connection the mac phy is set up for + enum: + - "mii" + - "rmii" diff --git a/dts/bindings/ethernet/ethernet-controller.yaml b/dts/bindings/ethernet/ethernet-controller.yaml index bb4fa794152be..ea19d106fe24b 100644 --- a/dts/bindings/ethernet/ethernet-controller.yaml +++ b/dts/bindings/ethernet/ethernet-controller.yaml @@ -37,3 +37,4 @@ properties: - "rmii" - "gmii" - "rgmii" + - "internal" diff --git a/dts/bindings/ethernet/microchip,lan865x.yaml b/dts/bindings/ethernet/microchip,lan865x.yaml index 699bfca7dc600..b0852fd30a26e 100644 --- a/dts/bindings/ethernet/microchip,lan865x.yaml +++ b/dts/bindings/ethernet/microchip,lan865x.yaml @@ -15,24 +15,6 @@ properties: rx-cut-through-mode: type: boolean description: Enable RX cut through mode - plca-enable: - type: boolean - description: Enable or disable PLCA support - plca-node-id: - type: int - description: Specify the PLCA node ID number - plca-node-count: - type: int - description: Specify the PLCA node count - plca-burst-count: - type: int - description: Specify the PLCA burst count - plca-burst-timer: - type: int - description: Specify the PLCA burst timer value - plca-to-timer: - type: int - description: Specify the PLCA to timer value int-gpios: type: phandle-array required: true diff --git a/dts/bindings/ethernet/microchip,lan9250.yaml b/dts/bindings/ethernet/microchip,lan9250.yaml new file mode 100644 index 0000000000000..5f64875994474 --- /dev/null +++ b/dts/bindings/ethernet/microchip,lan9250.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024, Mario Paja +# SPDX-License-Identifier: Apache-2.0 + +description: | + LAN9250 standalone 10/100BASE-T Ethernet controller with SPI interface + +compatible: "microchip,lan9250" + +include: [spi-device.yaml, ethernet-controller.yaml] + +properties: + int-gpios: + type: phandle-array + required: true + description: | + The interrupt pin of LAN9250 is active low. + If connected directly the MCU pin should be configured + as active low. diff --git a/dts/bindings/ethernet/microchip,t1s-phy.yaml b/dts/bindings/ethernet/microchip,t1s-phy.yaml new file mode 100644 index 0000000000000..eba95092f10b2 --- /dev/null +++ b/dts/bindings/ethernet/microchip,t1s-phy.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2024 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip's 10BASE-T1S PHYs support + +compatible: "microchip,t1s-phy" + +include: phy.yaml + +properties: + reg: + required: true + description: PHY address + plca-enable: + type: boolean + description: Enable or disable PLCA support + plca-node-id: + type: int + description: Specify the PLCA node ID number + plca-node-count: + type: int + description: Specify the PLCA node count + plca-burst-count: + type: int + description: Specify the PLCA burst count + plca-burst-timer: + type: int + description: Specify the PLCA burst timer value + plca-to-timer: + type: int + description: Specify the PLCA to timer value diff --git a/dts/bindings/ethernet/microchip,vsc8541-phy.yaml b/dts/bindings/ethernet/microchip,vsc8541-phy.yaml new file mode 100644 index 0000000000000..b283884bd2702 --- /dev/null +++ b/dts/bindings/ethernet/microchip,vsc8541-phy.yaml @@ -0,0 +1,30 @@ +# Copyright (c) 2024 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +description: Single Port Gigabit Ethernet Copper PHY with GMII/RGMII/MII/RMII Interfaces + +compatible: "microchip,vsc8541" + +include: [ethernet-phy.yaml] + +on-bus: mdio + +properties: + reg: + required: true + description: | + 5-bit MDIO PHY address for the attached PHY. + + reset-gpios: + type: phandle-array + description: GPIO connected to MAC PHY reset signal pin. Reset is active low. + + microchip,interface-type: + type: string + required: true + description: Which type of phy connection the phy is set up for + enum: + - "mii" + - "rmii" + - "gmii" + - "rgmii" diff --git a/dts/bindings/ethernet/nxp,enet-qos-mac.yaml b/dts/bindings/ethernet/nxp,enet-qos-mac.yaml index 5e43070fa5fdb..a37e3f83541b2 100644 --- a/dts/bindings/ethernet/nxp,enet-qos-mac.yaml +++ b/dts/bindings/ethernet/nxp,enet-qos-mac.yaml @@ -13,3 +13,15 @@ properties: interrupt-names: required: true + + nxp,unique-mac: + type: boolean + description: | + Use part of the unique silicon ID to generate the MAC. + This property will be overridden if the node has + zephyr,random-mac-address or local-mac-address also. + This option is intended for cases where a very low likelihood + that the mac address is the same as another on the network + is sufficient, such as, testing, bringup, demos, etc. + The first 3 bytes will be the freescale OUI and the next + 3 bytes will come from the chip's unique ID. diff --git a/dts/bindings/ethernet/nxp,imx-netc-psi.yaml b/dts/bindings/ethernet/nxp,imx-netc-psi.yaml index 913df707d2b0c..7aba10df1e35d 100644 --- a/dts/bindings/ethernet/nxp,imx-netc-psi.yaml +++ b/dts/bindings/ethernet/nxp,imx-netc-psi.yaml @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP i.MX NETC Physical Station Interface (PSI) @@ -11,9 +11,6 @@ properties: reg: required: true - phy-handle: - required: true - mac-index: required: true type: int diff --git a/dts/bindings/ethernet/sensry,sy1xx-mac.yaml b/dts/bindings/ethernet/sensry,sy1xx-mac.yaml new file mode 100644 index 0000000000000..412c405bccebe --- /dev/null +++ b/dts/bindings/ethernet/sensry,sy1xx-mac.yaml @@ -0,0 +1,28 @@ +# Copyright (c) 2024 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +compatible: "sensry,sy1xx-mac" + +include: [ethernet-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + reg: + required: true + + reg-names: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + phy-handle: + required: true + + promiscuous-mode: + type: boolean + description: | + Optional feature flag - Enable promiscuous mode. When set, all valid + frames will be accepted. diff --git a/dts/bindings/ethernet/silabs,gecko-ethernet.yaml b/dts/bindings/ethernet/silabs,gecko-ethernet.yaml index 136e4cc6280f4..6a1328962d531 100644 --- a/dts/bindings/ethernet/silabs,gecko-ethernet.yaml +++ b/dts/bindings/ethernet/silabs,gecko-ethernet.yaml @@ -36,66 +36,66 @@ properties: description: location of MDC and MDIO pins, configuration defined as # PHY management pins - location-phy_mdc: + location-phy-mdc: type: array required: true description: PHY MDC individual pin configuration defined as - location-phy_mdio: + location-phy-mdio: type: array required: true description: PHY MDIO individual pin configuration defined as # RMII interface pins - location-rmii_refclk: + location-rmii-refclk: type: array required: true description: Reference clock individual pin configuration defined as - location-rmii_crs_dv: + location-rmii-crs-dv: type: array required: true description: Receive data valid individual pin configuration defined as - location-rmii_txd0: + location-rmii-txd0: type: array required: true description: Transmit data 0 individual pin configuration defined as - location-rmii_txd1: + location-rmii-txd1: type: array required: true description: Transmit data 1 individual pin configuration defined as - location-rmii_tx_en: + location-rmii-tx-en: type: array required: true description: Transmit enable individual pin configuration defined as - location-rmii_rxd0: + location-rmii-rxd0: type: array required: true description: Receive data 0 individual pin configuration defined as - location-rmii_rxd1: + location-rmii-rxd1: type: array required: true description: Receive data 1 individual pin configuration defined as - location-rmii_rx_er: + location-rmii-rx-er: type: array required: true description: Receive error individual pin configuration defined as # PHY control pins - location-phy_pwr_enable: + location-phy-pwr-enable: type: array description: PHY power enable individual pin configuration defined as - location-phy_reset: + location-phy-reset: type: array description: PHY reset individual pin configuration defined as - location-phy_interrupt: + location-phy-interrupt: type: array description: PHY interrupt individual pin configuration defined as diff --git a/dts/bindings/firmware/arm,scmi-power.yaml b/dts/bindings/firmware/arm,scmi-power.yaml new file mode 100644 index 0000000000000..41ad234681d01 --- /dev/null +++ b/dts/bindings/firmware/arm,scmi-power.yaml @@ -0,0 +1,21 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: System Control and Management Interface (SCMI) power domain protocol + +compatible: "arm,scmi-power" + +include: [base.yaml] + +properties: + reg: + required: true + const: [0x11] + + "#power-domain-cells": + type: int + required: true + const: 1 + +power-domain-cells: + - name diff --git a/dts/bindings/flash_controller/nuvoton,npcx-fiu-nor.yaml b/dts/bindings/flash_controller/nuvoton,npcx-fiu-nor.yaml index 86c8e57a36293..48be99535c06d 100644 --- a/dts/bindings/flash_controller/nuvoton,npcx-fiu-nor.yaml +++ b/dts/bindings/flash_controller/nuvoton,npcx-fiu-nor.yaml @@ -47,3 +47,17 @@ properties: - "NPCX_RD_MODE_NORMAL" # Direct read access by command code 03h - "NPCX_RD_MODE_FAST" # Direct read access by command code 0bh - "NPCX_RD_MODE_FAST_DUAL" # Direct read access by command code bbh + spi-dev-size: + type: string + description: | + Select the size of the address space allocated for SPI device. This affects + the address space for any direct flash access. + enum: + - "NPCX_SPI_DEV_SIZE_1M" + - "NPCX_SPI_DEV_SIZE_2M" + - "NPCX_SPI_DEV_SIZE_4M" + - "NPCX_SPI_DEV_SIZE_8M" + - "NPCX_SPI_DEV_SIZE_16M" + - "NPCX_SPI_DEV_SIZE_32M" + - "NPCX_SPI_DEV_SIZE_64M" + - "NPCX_SPI_DEV_SIZE_128M" diff --git a/dts/bindings/flash_controller/nuvoton,npcx-fiu-qspi.yaml b/dts/bindings/flash_controller/nuvoton,npcx-fiu-qspi.yaml index 3e8627faf2379..23504268e1a4e 100644 --- a/dts/bindings/flash_controller/nuvoton,npcx-fiu-qspi.yaml +++ b/dts/bindings/flash_controller/nuvoton,npcx-fiu-qspi.yaml @@ -38,3 +38,7 @@ properties: type: boolean description: | Two external SPI devices are supported for Direct Read Access (DRA) on QSPI bus. + flash-dev-inv: + type: boolean + description: | + Inverse the device connected to the base address. diff --git a/dts/bindings/flash_controller/renesas,ra-flash-hp-controller.yaml b/dts/bindings/flash_controller/renesas,ra-flash-hp-controller.yaml index cefba7e4486af..f5813ff55256c 100644 --- a/dts/bindings/flash_controller/renesas,ra-flash-hp-controller.yaml +++ b/dts/bindings/flash_controller/renesas,ra-flash-hp-controller.yaml @@ -6,3 +6,21 @@ description: Renesas RA family flash high-performance controller compatible: "renesas,ra-flash-hp-controller" include: flash-controller.yaml + +properties: + block-32kb-linear-end: + type: int + required: true + description: The final 32kb block index of the code-flash in the linear mode. + + block-32kb-dual-low-end: + type: int + description: The final 32kb block index of the code-flash's lower Bank in the dual mode + + block-32kb-dual-high-end: + type: int + description: The final 32kb block index of the code-flash's higher Bank in the dual mode + + reserved-area-num: + type: int + description: The number of the code-flash's reserved blocks in the dual mode diff --git a/dts/bindings/flash_controller/silabs,siwx91x-flash-controller.yaml b/dts/bindings/flash_controller/silabs,siwx91x-flash-controller.yaml new file mode 100644 index 0000000000000..c12753253a04e --- /dev/null +++ b/dts/bindings/flash_controller/silabs,siwx91x-flash-controller.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Silicon Labs SiWx91x flash controller + +compatible: "silabs,siwx91x-flash-controller" + +include: flash-controller.yaml diff --git a/dts/bindings/flash_controller/ti,cc23x0-flash-controller.yaml b/dts/bindings/flash_controller/ti,cc23x0-flash-controller.yaml new file mode 100644 index 0000000000000..538e75aa16d89 --- /dev/null +++ b/dts/bindings/flash_controller/ti,cc23x0-flash-controller.yaml @@ -0,0 +1,5 @@ +description: Texas Instruments CC23X0 flash controller + +compatible: "ti,cc23x0-flash-controller" + +include: flash-controller.yaml diff --git a/dts/bindings/fs/zephyr,fstab,littlefs.yaml b/dts/bindings/fs/zephyr,fstab,littlefs.yaml index b557f4f83f389..92e667712b15e 100644 --- a/dts/bindings/fs/zephyr,fstab,littlefs.yaml +++ b/dts/bindings/fs/zephyr,fstab,littlefs.yaml @@ -76,3 +76,13 @@ properties: leveling. This corresponds to CONFIG_FS_LITTLEFS_BLOCK_CYCLES. + + disk-version: + type: int + description: | + The littlefs disk version. + + To maintain backward compatibility with existing littlefs + with the same major disk version. + + The default version is LFS_DISK_VERSION. diff --git a/dts/bindings/gpio/adi,max22017-gpio.yaml b/dts/bindings/gpio/adi,max22017-gpio.yaml new file mode 100644 index 0000000000000..81a243ea7af22 --- /dev/null +++ b/dts/bindings/gpio/adi,max22017-gpio.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +description: MAX22017 GPIO + +compatible: "adi,max22017-gpio" + +include: gpio-controller.yaml + +properties: + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/adi,max22190-gpio.yaml b/dts/bindings/gpio/adi,max22190-gpio.yaml new file mode 100644 index 0000000000000..29e263fbd9269 --- /dev/null +++ b/dts/bindings/gpio/adi,max22190-gpio.yaml @@ -0,0 +1,118 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +description: | + ADI MAX22190 octal industrial Input with advanced diagnostic + capabilities like Wire break and over/under volatage. + Fiter configuration could be done on per channel bases, which + mean WB functionality and filters could be set. Reffering to: + filter-wbes = for wire break + To enable wire break set 1 else 0. Same principle is followed for: + filter-fbps and filter-delays. + Sample binding + &sdp_spi { + status = "okay"; + pinctrl-names = "default"; + max22190_gpio0: max22190_gpio@0 { + compatible = "adi,max22190-gpio"; + reg = <0>; + + spi-max-frequency = <1000000>; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + status = "okay"; + + max22190-mode = <1>; // modes range from 0-4 + + drdy-gpios = <&gpioj 12 GPIO_ACTIVE_LOW>; /* SDP-GPIO5 - PMOD-PIN8 */ + fault-gpios = <&gpioc 11 GPIO_ACTIVE_LOW>; /* SDP-SERIAL_INT - PMOD-PIN7 */ + latch-gpios = <&gpioj 13 GPIO_ACTIVE_LOW>; /* SDP-GPIO6 - PMOD-PIN9 */ + + filter-wbes = <1 0 0 0 0 0 0 0>; // wirebreak WBEx + filter-fbps = <0 0 0 0 0 0 0 0>; // programmable filter INx + filter-delays = <50 100 400 800 1600 3200 12800 20000>; // 1000 us == 1ms + }; + }; + +compatible: "adi,max22190-gpio" + +properties: + "#gpio-cells": + const: 2 + ngpios: + type: int + required: true + const: 8 + description: Number of gpios supported + drdy-gpios: + description: Ready pin which show when chip is ready + type: phandle-array + fault-gpios: + description: | + Fault pin indicates when there is Fault state in either FAULT1 or FAULT2 + bothe of which are cleaned on read once problem is not persistent + type: phandle-array + latch-gpios: + description: | + Latch the data so it could be read (partially duplicate CS) + type: phandle-array + max22190-mode: + type: int + required: true + enum: + - 0 + - 1 + - 2 + - 3 + description: | + Default mode set to 1, because in MAX22190PMB devkit this is hardwired + mode set by manufacturer. + max22190 mode is configured from M0 and M1 pins with + pull up or down resistors. + MODE| M1| M0| FRAME | CRC | DAISY CHAIN + ----+---+---+--------+-----+------------ + 0 | 0 | 0 | 24-bit | yes | no + 1 | 0 | 1 | 16-bit | no | no + 2 | 1 | 0 | 24-bit | yes | yes + 3 | 1 | 1 | 16-bit | no | yes + filter-wbes: + type: array + default: [0, 0, 0, 0, 0, 0, 0, 0] + description: | + The default value corresponds to the default value of the hardware. + Wire break is disabled in all channels. + WBE bit in all Filter registers stand for wire break enable on each + channel, so to enable WB functionality set 1. + If WB on specific channel is disabled , FAULT will not be rised in case + wire is cut. + - 1 wire break enable + - 0 wire break disable + channels indentation start from CH0...CH7 + filter-fbps: + type: array + default: [1, 1, 1, 1, 1, 1, 1, 1] + description: | + The default value corresponds to the default value of the hardware. + All channels are in bypass. + Enable or disable filter + - 1 mean bypass + - 0 mean filter is used + channels indentation start from CH0...CH7 + filter-delays: + type: array + default: [50, 50, 50, 50, 50, 50, 50, 50] + description: | + The default value corresponds to the default value of the hardware. + Used to setup filter delay. Values are set in us. Default value is 50 = 50 us. + Value : 50, 100, 400, 800, 1600, 3200, 12800, 20000 + channels indentation start from CH0...CH7 + +gpio-cells: + - pin + - flags + +include: [gpio-controller.yaml, spi-device.yaml] diff --git a/dts/bindings/gpio/arm,mmio32-gpio.yaml b/dts/bindings/gpio/arm,mmio32-gpio.yaml new file mode 100644 index 0000000000000..0a8692adef4e0 --- /dev/null +++ b/dts/bindings/gpio/arm,mmio32-gpio.yaml @@ -0,0 +1,22 @@ +description: ARM MMIO32 GPIO + +compatible: "arm,mmio32-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + ngpios: + required: true + + "#gpio-cells": + const: 1 + + direction-input: + type: boolean + description: Marks this pin set as all input pins. + +gpio-cells: + - pin diff --git a/dts/bindings/gpio/arm,mps2-fpgaio-gpio.yaml b/dts/bindings/gpio/arm,mps2-fpgaio-gpio.yaml deleted file mode 100644 index 1c91ef9ca2a5a..0000000000000 --- a/dts/bindings/gpio/arm,mps2-fpgaio-gpio.yaml +++ /dev/null @@ -1,18 +0,0 @@ -description: GPIO controller on ARM MPS2 FPGA - -compatible: "arm,mps2-fpgaio-gpio" - -include: [gpio-controller.yaml, base.yaml] - -properties: - reg: - required: true - - ngpios: - required: true - - "#gpio-cells": - const: 1 - -gpio-cells: - - pin diff --git a/dts/bindings/gpio/arm,mps3-fpgaio-gpio.yaml b/dts/bindings/gpio/arm,mps3-fpgaio-gpio.yaml deleted file mode 100644 index 8d93742f9edc7..0000000000000 --- a/dts/bindings/gpio/arm,mps3-fpgaio-gpio.yaml +++ /dev/null @@ -1,18 +0,0 @@ -description: GPIO controller on ARM MPS3 FPGA - -compatible: "arm,mps3-fpgaio-gpio" - -include: [gpio-controller.yaml, base.yaml] - -properties: - reg: - required: true - - ngpios: - required: true - - "#gpio-cells": - const: 1 - -gpio-cells: - - pin diff --git a/dts/bindings/gpio/microchip,mec5-gpio.yaml b/dts/bindings/gpio/microchip,mec5-gpio.yaml new file mode 100644 index 0000000000000..c29ecb3466a47 --- /dev/null +++ b/dts/bindings/gpio/microchip,mec5-gpio.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip MEC5 GPIO node + +compatible: "microchip,mec5-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/nuvoton,nct38xx-gpio-port.yaml b/dts/bindings/gpio/nuvoton,nct38xx-gpio-port.yaml index af2d5eff20040..d1158b75927e7 100644 --- a/dts/bindings/gpio/nuvoton,nct38xx-gpio-port.yaml +++ b/dts/bindings/gpio/nuvoton,nct38xx-gpio-port.yaml @@ -11,7 +11,7 @@ properties: reg: required: true - pin_mask: + pin-mask: type: int required: true description: | @@ -21,7 +21,7 @@ properties: NCT3808: <0xdc> others: <0xff> - pinmux_mask: + pinmux-mask: type: int description: | NCT38XX series port 0 has Pin Multiplexing functionality. However, not diff --git a/dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml b/dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml index 5b9afbbc89201..8f10d4b98ed34 100644 --- a/dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml +++ b/dts/bindings/gpio/nuvoton,nct38xx-gpio.yaml @@ -23,8 +23,8 @@ description: | gpio-controller; #gpio-cells = <2>; ngpios = <8>; - pin_mask = <0xff>; - pinmux_mask = <0xf7>; + pin-mask = <0xff>; + pinmux-mask = <0xf7>; }; gpio@1 { @@ -33,7 +33,7 @@ description: | gpio-controller; #gpio-cells = <2>; ngpios = <8>; - pin_mask = <0xff>; + pin-mask = <0xff>; }; }; }; @@ -53,8 +53,8 @@ description: | gpio-controller; #gpio-cells = <2>; ngpios = <8>; - pin_mask = <0xdc>; - pinmux_mask = <0xff>; + pin-mask = <0xdc>; + pinmux-mask = <0xff>; }; }; }; @@ -74,8 +74,8 @@ description: | gpio-controller; #gpio-cells = <2>; ngpios = <8>; - pin_mask = <0xdc>; - pinmux_mask = <0xff>; + pin-mask = <0xdc>; + pinmux-mask = <0xff>; }; }; }; diff --git a/dts/bindings/gpio/nxp,kinetis-gpio.yaml b/dts/bindings/gpio/nxp,kinetis-gpio.yaml index 845a13714e0d8..1ee1c8db0ddf3 100644 --- a/dts/bindings/gpio/nxp,kinetis-gpio.yaml +++ b/dts/bindings/gpio/nxp,kinetis-gpio.yaml @@ -18,6 +18,12 @@ properties: A phandle reference to the device tree node that contains the pinmux port associated with this GPIO controller. + gpio-port-offest: + type: int + default: 0 + description: | + Describes an offset between inst index and actual GPIO port number. + gpio-cells: - pin - flags diff --git a/dts/bindings/gpio/nxp,pca6416.yaml b/dts/bindings/gpio/nxp,pca6416.yaml new file mode 100644 index 0000000000000..359bf68837947 --- /dev/null +++ b/dts/bindings/gpio/nxp,pca6416.yaml @@ -0,0 +1,23 @@ +# Copyright 2024-2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: Base binding for PCA6416 I2C-based GPIO expander + +compatible: "nxp,pca6416" + +include: [gpio-controller.yaml, i2c-device.yaml] + +properties: + interrupt-gpios: + type: phandle-array + description: + Interrupt GPIO pin (active-low open-drain) + Left blank if the pin is not connected in your + application. + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/raspberrypi,rp1-gpio.yaml b/dts/bindings/gpio/raspberrypi,rp1-gpio.yaml new file mode 100644 index 0000000000000..5702c23183955 --- /dev/null +++ b/dts/bindings/gpio/raspberrypi,rp1-gpio.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Junho Lee +# SPDX-License-Identifier: Apache-2.0 + +description: GPIO Banks on RP1 peripheral controller + +compatible: "raspberrypi,rp1-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/realtek,rts5912-gpio.yaml b/dts/bindings/gpio/realtek,rts5912-gpio.yaml new file mode 100644 index 0000000000000..4bf4d44e42fb4 --- /dev/null +++ b/dts/bindings/gpio/realtek,rts5912-gpio.yaml @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +description: Realtek RTS5912 GPIO + +compatible: "realtek,rts5912-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/renesas,mipi-header.yaml b/dts/bindings/gpio/renesas,mipi-header.yaml new file mode 100644 index 0000000000000..6906f26550f3c --- /dev/null +++ b/dts/bindings/gpio/renesas,mipi-header.yaml @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + GPIO pins exposed on Renesas MIPI lcd display headers. + + The Renesas MIPI lcd display layout provides 2 columns of 13 pins headers + + This binding provides a mapping for the default 26 pins as depicted below: + + 1 GND IIC_SDA 14 + 2 GND DISP_BLEN 15 + 3 MIPI_DL0_P IIC_SCL 16 + 4 MIPI_DL1_P DISP_INT 17 + 5 MIPI_DL0_N DISP_RST 18 + 6 MIPI_DL1_N GND 19 + 7 GND GND 20 + 8 GND 1V8 21 + 9 MIPI_CL_P 1V8 22 + 10 GND 3V3 23 + 11 MIPI_CL_N 3V3 24 + 12 GND 5V0 25 + 13 GND 5V0 26 + +compatible: "renesas,ra-gpio-mipi-header" + +include: [gpio-nexus.yaml, base.yaml] diff --git a/dts/bindings/gpio/renesas,ra-gpio-ioport.yaml b/dts/bindings/gpio/renesas,ra-gpio-ioport.yaml index bdf53054ec1d8..fa015bac6de4a 100644 --- a/dts/bindings/gpio/renesas,ra-gpio-ioport.yaml +++ b/dts/bindings/gpio/renesas,ra-gpio-ioport.yaml @@ -15,10 +15,82 @@ properties: type: int required: true - vbatts_pins: + vbatts-pins: type: array description: Array of vbatt pin on port + port-irqs: + type: phandle-array + description: Port irq which this port can be use + + port-irq-names: + type: string-array + description: The name of port irq + + port-irq0-pins: + type: array + description: Pins allow to assign port-irq0 + + port-irq1-pins: + type: array + description: Pins allow to assign port-irq1 + + port-irq2-pins: + type: array + description: Pins allow to assign port-irq2 + + port-irq3-pins: + type: array + description: Pins allow to assign port-irq3 + + port-irq4-pins: + type: array + description: Pins allow to assign port-irq4 + + port-irq5-pins: + type: array + description: Pins allow to assign port-irq5 + + port-irq6-pins: + type: array + description: Pins allow to assign port-irq6 + + port-irq7-pins: + type: array + description: Pins allow to assign port-irq7 + + port-irq8-pins: + type: array + description: Pins allow to assign port-irq8 + + port-irq9-pins: + type: array + description: Pins allow to assign port-irq9 + + port-irq10-pins: + type: array + description: Pins allow to assign port-irq10 + + port-irq11-pins: + type: array + description: Pins allow to assign port-irq11 + + port-irq12-pins: + type: array + description: Pins allow to assign port-irq12 + + port-irq13-pins: + type: array + description: Pins allow to assign port-irq13 + + port-irq14-pins: + type: array + description: Pins allow to assign port-irq14 + + port-irq15-pins: + type: array + description: Pins allow to assign port-irq15 + "#gpio-cells": const: 2 diff --git a/dts/bindings/gpio/renesas,rz-gpio-int.yaml b/dts/bindings/gpio/renesas,rz-gpio-int.yaml new file mode 100644 index 0000000000000..bffe75c2d7b50 --- /dev/null +++ b/dts/bindings/gpio/renesas,rz-gpio-int.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ GPIO Interrupt + +compatible: "renesas,rz-gpio-int" + +include: base.yaml + +properties: + interrupts: + required: true + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 diff --git a/dts/bindings/gpio/renesas,rz-gpio.yaml b/dts/bindings/gpio/renesas,rz-gpio.yaml new file mode 100644 index 0000000000000..9b4a37e6c1748 --- /dev/null +++ b/dts/bindings/gpio/renesas,rz-gpio.yaml @@ -0,0 +1,43 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + Reneses RZ GPIO controller node. + Sample of usage: + gpio-consumer{ + out-gpio = <&gpio8 2 (GPIO_PULL_UP); + }; + &gpio8{ + irq = <2 10>, <9 1>; + status = "okay"; + }; + Example above will configure pin 2 port 8: + - Using interrupt TINT10 + - Set Pullup + + +compatible: "renesas,rz-gpio" + +include: +- name: base.yaml + property-allowlist: + - status + - reg + - label +- name: gpio-controller.yaml + +properties: + reg: + required: true + description: GPIO port number + + irqs: + type: array + description: pin-irq pairs + + "#gpio-cells": + const: 2 + +gpio-cells: +- pin +- flags diff --git a/dts/bindings/gpio/sensry,sy1xx-gpio.yaml b/dts/bindings/gpio/sensry,sy1xx-gpio.yaml new file mode 100644 index 0000000000000..a66d8d7d83ae8 --- /dev/null +++ b/dts/bindings/gpio/sensry,sy1xx-gpio.yaml @@ -0,0 +1,25 @@ +# Copyright (c) 2024 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +description: Sensry SY1XX GPIO PORT node + +compatible: "sensry,sy1xx-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + description: Base address for the gpio configuration. + + "#gpio-cells": + const: 2 + + pad-cfg: + type: int + required: true + description: Offset for gpio pad ctrl registers. + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/silabs,siwx91x-gpio-port.yaml b/dts/bindings/gpio/silabs,siwx91x-gpio-port.yaml new file mode 100644 index 0000000000000..4cc40af3323aa --- /dev/null +++ b/dts/bindings/gpio/silabs,siwx91x-gpio-port.yaml @@ -0,0 +1,25 @@ +description: Silabs SiWx91x GPIO port node + +compatible: "silabs,siwx91x-gpio-port" + +include: [gpio-controller.yaml, base.yaml] + +properties: + + reg: + required: true + + "#gpio-cells": + const: 2 + + silabs,pads: + type: uint8-array + required: true + description: | + Contains the map of what pad number is used for each GPIO. + 0xFF if a GPIO has no pad. + 0 if the pad is directly configured using port and pin number. + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/silabs,siwx91x-gpio-uulp.yaml b/dts/bindings/gpio/silabs,siwx91x-gpio-uulp.yaml new file mode 100644 index 0000000000000..2c6cc44a38170 --- /dev/null +++ b/dts/bindings/gpio/silabs,siwx91x-gpio-uulp.yaml @@ -0,0 +1,17 @@ +description: Silabs SiWx91x UULP (ultra ultra low power) GPIO port node + +compatible: "silabs,siwx91x-gpio-uulp" + +include: [gpio-controller.yaml, base.yaml] + +properties: + + reg: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/silabs,siwx91x-gpio.yaml b/dts/bindings/gpio/silabs,siwx91x-gpio.yaml new file mode 100644 index 0000000000000..a7e1535916b6a --- /dev/null +++ b/dts/bindings/gpio/silabs,siwx91x-gpio.yaml @@ -0,0 +1,17 @@ +description: Silabs SiWx91x GPIO node + +compatible: "silabs,siwx91x-gpio" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + silabs,ulp: + type: boolean + description: | + If this property is set, the GPIO controller uses ULP (ultra low power) pads. diff --git a/dts/bindings/gpio/snps,creg-gpio.yaml b/dts/bindings/gpio/snps,creg-gpio.yaml index 954a9ae10d7ca..d73b2f54fef8f 100644 --- a/dts/bindings/gpio/snps,creg-gpio.yaml +++ b/dts/bindings/gpio/snps,creg-gpio.yaml @@ -11,15 +11,15 @@ properties: reg: required: true - bit_per_gpio: + bit-per-gpio: type: int required: true - off_val: + off-val: type: int required: true - on_val: + on-val: type: int required: true diff --git a/dts/bindings/gpio/st,dcmi-camera-fpu-330zh.yaml b/dts/bindings/gpio/st,dcmi-camera-fpu-330zh.yaml new file mode 100644 index 0000000000000..e6b74dfd3d5dd --- /dev/null +++ b/dts/bindings/gpio/st,dcmi-camera-fpu-330zh.yaml @@ -0,0 +1,40 @@ +# Copyright (c) 2025 Charles Dias +# SPDX-License-Identifier: Apache-2.0 + +description: | + GPIO pins exposed on the 30-pin ZIF connector (CN5) of the B-CAMS-OMV. + Connector layout: + (1) 3V3 + (2) GND + (3) I2C_SCL + (4) I2C_SDA + (5) RESET# + (6) PWR_EN / LED1 + (7) SHUTTER + (8) GND + (9) PULLDOWN / LED2 + (10) Camera_CLK + (11) 3V3 + (12) DCMI_VSYNC + (13) 5V (RSU) + (14) DCMI_HSYNC + (15) GND + (16) DCMI_PIXCK + (17) GND + (18) SPI_MISO + (19) SPI_CS + (20) DCMI_D7 + (21) DCMI_D6 + (22) DCMI_D5 + (23) DCMI_D4 + (24) DCMI_D3 + (25) DCMI_D2 + (26) DCMI_D1 + (27) DCMI_D0 + (28) SPI_MOSI + (29) SPI_CLK + (30) GND + +compatible: "st,dcmi-camera-fpu-330zh" + +include: [gpio-nexus.yaml, base.yaml] diff --git a/dts/bindings/gpio/st,mfxstm32l152.yaml b/dts/bindings/gpio/st,mfxstm32l152.yaml new file mode 100644 index 0000000000000..b01137043c307 --- /dev/null +++ b/dts/bindings/gpio/st,mfxstm32l152.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: MFXSTM32L152 I2C-based GPIO expander + +compatible: "st,mfxstm32l152" + +include: [gpio-controller.yaml, i2c-device.yaml] + +properties: + int-gpios: + type: phandle-array + description: | + GPIO connected to the controller INT pin. This pin is active-low + and open-drain. + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/ti,ads114s0x-gpio.yaml b/dts/bindings/gpio/ti,ads114s0x-gpio.yaml deleted file mode 100644 index 62a7a483aa138..0000000000000 --- a/dts/bindings/gpio/ti,ads114s0x-gpio.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2022 SILA Embedded Solutions GmbH -# -# SPDX-License-Identifier: Apache-2.0 -# - -description: TI ADS114S0x GPIO controller binding - -compatible: "ti,ads114s0x-gpio" - -include: [gpio-controller.yaml, base.yaml] - -on-bus: ads114s0x - -properties: - "#gpio-cells": - const: 2 - - ngpios: - type: int - required: true - const: 4 - description: Number of gpios supported - -gpio-cells: - - pin - - flags diff --git a/dts/bindings/gpio/ti,ads1x4s0x-gpio.yaml b/dts/bindings/gpio/ti,ads1x4s0x-gpio.yaml new file mode 100644 index 0000000000000..b7ec4e3daffd6 --- /dev/null +++ b/dts/bindings/gpio/ti,ads1x4s0x-gpio.yaml @@ -0,0 +1,27 @@ +# +# Copyright (c) 2022 SILA Embedded Solutions GmbH +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: TI ADS114S0x GPIO controller binding + +compatible: "ti,ads1x4s0x-gpio" + +include: [gpio-controller.yaml, base.yaml] + +on-bus: ads1x4s0x + +properties: + "#gpio-cells": + const: 2 + + ngpios: + type: int + required: true + const: 4 + description: Number of gpios supported + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/gpio/ti,cc23x0-gpio.yaml b/dts/bindings/gpio/ti,cc23x0-gpio.yaml new file mode 100644 index 0000000000000..ced5e1352d97a --- /dev/null +++ b/dts/bindings/gpio/ti,cc23x0-gpio.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +description: TI SimpleLink CC23X0 GPIO node + +compatible: "ti,cc23x0-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/hdlc_rcp_if/uart,hdlc-rcp-if.yaml b/dts/bindings/hdlc_rcp_if/uart,hdlc-rcp-if.yaml new file mode 100644 index 0000000000000..bb8d96596403b --- /dev/null +++ b/dts/bindings/hdlc_rcp_if/uart,hdlc-rcp-if.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2024, DENX Software Engineering GmbH +# Lukasz Majewski +# SPDX-License-Identifier: Apache-2.0 + +description: UART HDLC RCP interface node + +compatible: "uart,hdlc-rcp-if" + +include: base.yaml diff --git a/dts/bindings/hwspinlock/sqn,hwspinlock.yaml b/dts/bindings/hwspinlock/sqn,hwspinlock.yaml index 179d3d4449c33..c4c7b3056c701 100644 --- a/dts/bindings/hwspinlock/sqn,hwspinlock.yaml +++ b/dts/bindings/hwspinlock/sqn,hwspinlock.yaml @@ -11,6 +11,6 @@ properties: reg: required: true - num_locks: + num-locks: type: int required: true diff --git a/dts/bindings/i2c/atmel,sam0-i2c.yaml b/dts/bindings/i2c/atmel,sam0-i2c.yaml index 9f8d34e95f95a..db0610b785fef 100644 --- a/dts/bindings/i2c/atmel,sam0-i2c.yaml +++ b/dts/bindings/i2c/atmel,sam0-i2c.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2019 Derek Hageman +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 series SERCOM I2C node @@ -8,6 +9,7 @@ compatible: "atmel,sam0-i2c" include: - name: i2c-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -22,6 +24,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + dmas: description: | Optional TX & RX dma specifiers. Each specifier will have a phandle diff --git a/dts/bindings/i2c/microchip,xec-i2c-v2.yaml b/dts/bindings/i2c/microchip,xec-i2c-v2.yaml index 619e8e86231d3..b1f686a2905c1 100644 --- a/dts/bindings/i2c/microchip,xec-i2c-v2.yaml +++ b/dts/bindings/i2c/microchip,xec-i2c-v2.yaml @@ -11,7 +11,7 @@ properties: reg: required: true - port_sel: + port-sel: type: int description: soc block mapping to pin required: true diff --git a/dts/bindings/i2c/microchip,xec-i2c.yaml b/dts/bindings/i2c/microchip,xec-i2c.yaml index 3cb2d0fc7a03f..5fd5697969480 100644 --- a/dts/bindings/i2c/microchip,xec-i2c.yaml +++ b/dts/bindings/i2c/microchip,xec-i2c.yaml @@ -11,7 +11,7 @@ properties: reg: required: true - port_sel: + port-sel: type: int description: soc block mapping to pin required: true diff --git a/dts/bindings/i2c/nordic,nrf-twis.yaml b/dts/bindings/i2c/nordic,nrf-twis.yaml index cd024c108a7a1..137af0dbe620e 100644 --- a/dts/bindings/i2c/nordic,nrf-twis.yaml +++ b/dts/bindings/i2c/nordic,nrf-twis.yaml @@ -1,39 +1,46 @@ -# Copyright (c) 2019 Nordic Semiconductor ASA +# Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 description: | - Nordic nRF family TWIS (TWI slave with EasyDMA). - - Note: for Zephyr users, the I2C slave API is not available for - these devices. See this issue for more details and a HAL-based - workaround: - - https://github.com/zephyrproject-rtos/zephyr/issues/21445 - - This binding can be used for nodes which can represent TWIS - peripherals. A single SoC peripheral ID is often associated with - multiple I2C peripherals, like a TWIM and a TWIS. You can choose - TWIS by setting the node's "compatible" to "nordic,nrf-twis" - and its "status" to "okay", e.g. using an overlay file like this: - - /* This is for TWIS0 -- change to "i2c1" for TWIS1, etc. */ - &i2c0 { - compatible = "nordic,nrf-twis"; - status = "okay"; - /* other property settings can go here */ - }; - - This works on any supported SoC, for all TWIS instances. + Nordic nRF family TWIS + + The TWIS peripheral is an I2C controller which supports the I2C + peripheral role, and EasyDMA. TWIS shares resources with TWIM and TWI, + only one of them can be enabled for each peripheral instance. + Overwrite the compatible of the i2c node to select between TWIM/TWI + and TWIS, along with the pinctrl instances to select between TWIM/TWI + and TWIS pin functions. + + Example: + + &pinctrl { + i2c2_default: i2c2_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c2_sleep: i2c2_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + }; + + &i2c2 { + compatible = "nordic,nrf-twis"; + pinctrl-0 = <&i2c2_default>; + pinctrl-1 = <&i2c2_sleep>; + pinctrl-names = "default", "sleep"; + status = "okay"; + }; compatible: "nordic,nrf-twis" -include: ["nordic,nrf-twi-common.yaml", "memory-region.yaml"] - -properties: - address-0: - type: int - description: TWI slave address 0 - - address-1: - type: int - description: TWI slave address 1 +include: + - "nordic,nrf-twi-common.yaml" + - "memory-region.yaml" diff --git a/dts/bindings/i2c/nuvoton,npcx-i2c-ctrl.yaml b/dts/bindings/i2c/nuvoton,npcx-i2c-ctrl.yaml index e14ce0ae236b7..4ee9c5f2bcdfe 100644 --- a/dts/bindings/i2c/nuvoton,npcx-i2c-ctrl.yaml +++ b/dts/bindings/i2c/nuvoton,npcx-i2c-ctrl.yaml @@ -12,3 +12,11 @@ properties: required: true clocks: required: true + smb-wui: + type: phandle + required: true + description: | + Mapping table between Wake-Up Input (WUI) and SMB module. + + For example the WUI mapping on SMB 4 module would be + smb-wui = <&wui_smb4>; diff --git a/dts/bindings/i2c/nuvoton,npcx-i2c-port.yaml b/dts/bindings/i2c/nuvoton,npcx-i2c-port.yaml index 8f5f288705e87..76304f57374b7 100644 --- a/dts/bindings/i2c/nuvoton,npcx-i2c-port.yaml +++ b/dts/bindings/i2c/nuvoton,npcx-i2c-port.yaml @@ -11,7 +11,13 @@ properties: port: type: int required: true - description: index of i2c port + description: | + Index of i2c port + This property is used to differentiate between multiple I2C ports controlled by the same + or different I2C controllers. + Bit[7:4] module id (controller). + Bit[3:0] port id. + Use the macro NPCX_I2C_CTRL_PORT(ctrl, port) to set this property. controller: type: phandle diff --git a/dts/bindings/i2c/nxp,ii2c.yaml b/dts/bindings/i2c/nxp,ii2c.yaml new file mode 100644 index 0000000000000..6c493ea2e5385 --- /dev/null +++ b/dts/bindings/i2c/nxp,ii2c.yaml @@ -0,0 +1,15 @@ +# Copyright 2024-2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP II2C node + +compatible: "nxp,ii2c" + +include: [i2c-controller.yaml, pinctrl-device.yaml, "nxp,rdc-policy.yaml"] + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/dts/bindings/i2c/nxp,lpc-i2c.yaml b/dts/bindings/i2c/nxp,lpc-i2c.yaml index 4c2ceb77a8b1b..54aa4b7fb5805 100644 --- a/dts/bindings/i2c/nxp,lpc-i2c.yaml +++ b/dts/bindings/i2c/nxp,lpc-i2c.yaml @@ -6,3 +6,16 @@ description: LPC I2C node compatible: "nxp,lpc-i2c" include: [i2c-controller.yaml, "nxp,lpc-flexcomm.yaml"] + +properties: + scl-gpios: + type: phandle-array + description: | + GPIO to which the I2C SCL signal is routed. This is only needed for I2C bus recovery + support. + + sda-gpios: + type: phandle-array + description: | + GPIO to which the I2C SDA signal is routed. This is only needed for I2C bus recovery + support. diff --git a/dts/bindings/i2c/snps,designware-i2c.yaml b/dts/bindings/i2c/snps,designware-i2c.yaml index 596558cec0b5f..770ff98b5fc15 100644 --- a/dts/bindings/i2c/snps,designware-i2c.yaml +++ b/dts/bindings/i2c/snps,designware-i2c.yaml @@ -10,3 +10,13 @@ include: [i2c-controller.yaml, pinctrl-device.yaml, pcie-device.yaml] properties: interrupts: required: true + + lcnt-offset: + type: int + description: | + A fixed offset to apply to the SCL lcnt setting. + + hcnt-offset: + type: int + description: | + A fixed offset to apply to the SCL hcnt setting. diff --git a/dts/bindings/i2c/ti,omap-i2c.yaml b/dts/bindings/i2c/ti,omap-i2c.yaml new file mode 100644 index 0000000000000..b9c976d08816c --- /dev/null +++ b/dts/bindings/i2c/ti,omap-i2c.yaml @@ -0,0 +1,20 @@ +description: TI OMAP I2C Controller +compatible: "ti,omap-i2c" +include: [i2c-controller.yaml, pinctrl-device.yaml] +properties: + reg: + description: Base address and size of the I2C registers. + required: true + interrupts: + description: Interrupt specifier for the I2C controller. + required: true + pinctrl-0: + description: Pin control groups for this I2C instance. + required: true + pinctrl-names: + description: Names for the pin control groups. + required: true + clock-frequency: + description: The frequency of the I2C bus. + default: 100000 + required: true diff --git a/dts/bindings/i2s/i2s-device.yaml b/dts/bindings/i2s/i2s-device.yaml index d4cb0abb47ffd..5ee3aa5f47cb6 100644 --- a/dts/bindings/i2s/i2s-device.yaml +++ b/dts/bindings/i2s/i2s-device.yaml @@ -3,7 +3,7 @@ # Common fields for I2S devices -include: base.yaml +include: [base.yaml, power.yaml] on-bus: i2s diff --git a/dts/bindings/i2s/litex,i2s.yaml b/dts/bindings/i2s/litex,i2s.yaml index 9259e02250af4..60031781e03fe 100644 --- a/dts/bindings/i2s/litex,i2s.yaml +++ b/dts/bindings/i2s/litex,i2s.yaml @@ -13,6 +13,6 @@ properties: reg: required: true - fifo_depth: + fifo-depth: type: int required: true diff --git a/dts/bindings/i2s/nxp,mcux-i2s.yaml b/dts/bindings/i2s/nxp,mcux-i2s.yaml index 25295432874a7..d657edf2df606 100644 --- a/dts/bindings/i2s/nxp,mcux-i2s.yaml +++ b/dts/bindings/i2s/nxp,mcux-i2s.yaml @@ -1,4 +1,4 @@ -# Copyright 2021,2023 NXP +# Copyright 2021,2023-2024 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP mcux SAI-I2S controller @@ -62,6 +62,9 @@ properties: description: tx channel the maximum number is SOC dependent clock-mux: - required: true type: int description: Clock mux source for SAI root clock + +pinmux-cells: + - offset + - mask diff --git a/dts/bindings/i3c/snps,designware-i3c.yaml b/dts/bindings/i3c/snps,designware-i3c.yaml new file mode 100644 index 0000000000000..b323ebd5e6b9c --- /dev/null +++ b/dts/bindings/i3c/snps,designware-i3c.yaml @@ -0,0 +1,30 @@ +# Copyright (C) 2020 Samsung Electronics Co., Ltd. +# Copyright (C) 2023 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +description: > + This is a binding for the Synopsys I3C interface + +compatible: "snps,designware-i3c" + +include: i3c-controller.yaml + +properties: + clocks: + required: true + + od-thigh-max-ns: + type: int + default: 41 + description: | + Maximum high clock pulse length (ns) in Open-Drain mode. + The default is value from Section 6.2 of the I3C + Specifiction. + + od-tlow-min-ns: + type: int + default: 200 + description: | + Minimum low clock pulse length (ns) in Open-Drain mode. + The default is value from Section 6.2 of the I3C + Specifiction. diff --git a/dts/bindings/i3c/st,stm32-i3c.yaml b/dts/bindings/i3c/st,stm32-i3c.yaml new file mode 100644 index 0000000000000..75395c31487cd --- /dev/null +++ b/dts/bindings/i3c/st,stm32-i3c.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2024 EXALT Technologies. +# +# SPDX-License-Identifier: Apache-2.0 + +description: STM32H5 I3C controller + +compatible: "st,stm32-i3c" + +include: [i3c-controller.yaml, pinctrl-device.yaml, reset-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + pinctrl-names: + required: true + + resets: + required: true + + dmas: + description: | + Optional DMA channel specifier, required for DMA transactions. + + dma-names: + description: | + DMA channel name. If DMA should be used, expected value is "rx" "tx" "tc" "rs". + + For example + dma-names = "rx", "tx", "tc", "rs"; diff --git a/dts/bindings/ieee802154/nxp,mcxw-ieee802154.yaml b/dts/bindings/ieee802154/nxp,mcxw-ieee802154.yaml new file mode 100644 index 0000000000000..cb76bf63ac8ce --- /dev/null +++ b/dts/bindings/ieee802154/nxp,mcxw-ieee802154.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025, NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP MCXW71 IEEE 802.15.4 node + +compatible: "nxp,mcxw-ieee802154" + +include: base.yaml diff --git a/dts/bindings/input/cypress,cy8cmbr3xxx.yaml b/dts/bindings/input/cypress,cy8cmbr3xxx.yaml new file mode 100644 index 0000000000000..3b62b5b043f95 --- /dev/null +++ b/dts/bindings/input/cypress,cy8cmbr3xxx.yaml @@ -0,0 +1,35 @@ +# Copyright (c) 2025 Basalte bv +# SPDX-License-Identifier: Apache-2.0 + +description: | + Cypress CY8CMBR3002/3102/3106S/3108/3110/3116 capacitive touch sensor + +compatible: "cypress,cy8cmbr3xxx" + +include: i2c-device.yaml + +properties: + int-gpios: + type: phandle-array + required: true + description: | + The interrupt pin generates an active low pulse signal on + any change in the CapSense sensor's status. + + rst-gpios: + type: phandle-array + required: true + description: | + The reset pin resets the capsense controller with an active + low reset pulse. + + input-codes: + type: array + required: true + description: | + Array of input event key codes (INPUT_KEY_* or INPUT_BTN_*). + + proximity-codes: + type: array + description: | + Array of input event key codes (INPUT_KEY_* or INPUT_BTN_*). diff --git a/dts/bindings/input/microchip,cap1203.yaml b/dts/bindings/input/microchip,cap1203.yaml deleted file mode 100644 index e6c9ed1fc3ed8..0000000000000 --- a/dts/bindings/input/microchip,cap1203.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2022 Keiya Nobuta -# SPDX-License-Identifier: Apache-2.0 - -description: CAP1203 3-channel capacitive touch sensor - -compatible: "microchip,cap1203" - -include: i2c-device.yaml - -properties: - int-gpios: - type: phandle-array - - input-codes: - type: array - required: true - description: | - Array of input event key codes (INPUT_KEY_* or INPUT_BTN_*). diff --git a/dts/bindings/input/microchip,cap12xx.yaml b/dts/bindings/input/microchip,cap12xx.yaml new file mode 100644 index 0000000000000..8e5eefcfb4d82 --- /dev/null +++ b/dts/bindings/input/microchip,cap12xx.yaml @@ -0,0 +1,30 @@ +# Copyright (c) 2022 Keiya Nobuta +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip CAP12xx family of 3, 6 and 8-channel capacitive touch sensors. + +compatible: "microchip,cap12xx" + +include: i2c-device.yaml + +properties: + int-gpios: + type: phandle-array + description: | + Interrupt GPIO when not using polling mode. + + repeat: + type: boolean + description: | + Property to enable the interrupt repeat mode for prolonged touch events. + + poll-interval-ms: + type: int + description: | + Polling interval in ms when not using interrupt mode. + + input-codes: + type: array + required: true + description: | + Array of input event key codes (INPUT_KEY_* or INPUT_BTN_*). diff --git a/dts/bindings/input/nintendo,nunchuk.yaml b/dts/bindings/input/nintendo,nunchuk.yaml new file mode 100644 index 0000000000000..9318e54a7e805 --- /dev/null +++ b/dts/bindings/input/nintendo,nunchuk.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Bootlin +# SPDX-License-Identifier: Apache-2.0 + +description: Nintendo Nunchuk joystick through I2C + +compatible: "nintendo,nunchuk" + +include: i2c-device.yaml + +properties: + polling-interval-ms: + type: int + default: 50 + description: | + Interval between two reads, in ms. The interval must be greater than 21 ms. Default to 50 ms. diff --git a/dts/bindings/interrupt-controller/arm,gic-v3.yaml b/dts/bindings/interrupt-controller/arm,gic-v3.yaml index 8fc5851d62cf6..fed263f62733f 100644 --- a/dts/bindings/interrupt-controller/arm,gic-v3.yaml +++ b/dts/bindings/interrupt-controller/arm,gic-v3.yaml @@ -1,7 +1,53 @@ +# +# Copyright 2025 Arm Limited and/or its affiliates +# # SPDX-License-Identifier: Apache-2.0 +# -description: ARM Generic Interrupt Controller v3 +description: | + ARM Generic Interrupt Controller v3 + + Examples for GICv3 devicetree nodes: + + gic: interrupt-controller@2cf00000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x2f000000 0x10000>, /* GICD */ + <0x2f100000 0x200000>; /* GICR */ + interrupt-controller; + #interrupt-cells = <3>; + status = "okay"; + }; + + gic: interrupt-controller@2c010000 { + compatible = "arm,gic-v3", "arm,gic"; + redistributor-stride = <0x40000>; /* 256kB stride */ + redistributor-regions = <2>; + reg = <0x2c010000 0x10000>, /* GICD */ + <0x2d000000 0x800000>, /* GICR 1: CPUs 0-31 */ + <0x2e000000 0x800000>; /* GICR 2: CPUs 32-63 */ + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; compatible: arm,gic-v3 include: arm,gic.yaml + +properties: + redistributor-stride: + type: int + description: + If using padding pages, specifies the stride of consecutive + redistributors which is the distance between consecutive redistributors in + memory. Must be a multiple of 64kB. Required if the distance between + redistributors is not the default 128kB. + + redistributor-regions: + type: int + description: + The number of independent contiguous regions occupied by the redistributors. + The term "regions" refers to distinct memory segments or areas allocated + for redistributors within the system memory. The number of redistributor + regions and their sizes are hardware-specific. Required if more than one + such region is present. diff --git a/dts/bindings/interrupt-controller/renesas,rz-ext-irq.yaml b/dts/bindings/interrupt-controller/renesas,rz-ext-irq.yaml new file mode 100644 index 0000000000000..91c833cbef705 --- /dev/null +++ b/dts/bindings/interrupt-controller/renesas,rz-ext-irq.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZG external interrupt controller + +compatible: "renesas,rz-ext-irq" + +include: [interrupt-controller.yaml, base.yaml, pinctrl-device.yaml] + +properties: + "#address-cells": + const: 0 + + "#interrupt-cells": + const: 2 + + trigger-type: + required: true + type: string + description: | + Indicates the condition that will trigger an interrupt when detected. + enum: + - "falling" + - "rising" + - "both_edges" + - "low_level" diff --git a/dts/bindings/timer/sifive,clint0.yaml b/dts/bindings/interrupt-controller/sifive,clint0.yaml similarity index 100% rename from dts/bindings/timer/sifive,clint0.yaml rename to dts/bindings/interrupt-controller/sifive,clint0.yaml diff --git a/dts/bindings/ipc/zephyr,ipc-icmsg.yaml b/dts/bindings/ipc/zephyr,ipc-icmsg.yaml index 13a9e2b84b69c..d1730dddb0f09 100644 --- a/dts/bindings/ipc/zephyr,ipc-icmsg.yaml +++ b/dts/bindings/ipc/zephyr,ipc-icmsg.yaml @@ -21,6 +21,21 @@ properties: required: true type: phandle + unbound: + type: string + enum: + - disable + - enable + - detect + default: disable + description: | + Select unbound() callback mode. The callback can be enabled or disabled with the + "enable" and "disable" option respectively. This functionality requires session + number handshake procedure on both sides, so you cannot set "enable" on one side + and "disable" on the other. The "detect" mode detects if the remote side + supports handshake procedure and adjusts its behavior accordingly. The + "detect" mode is possible only if "dcache-alignment" is at least 8 bytes. + dcache-alignment: type: int description: | diff --git a/dts/bindings/led/ti,lp50xx.yaml b/dts/bindings/led/ti,lp50xx.yaml index fb06d59f7f92c..91511dbd30399 100644 --- a/dts/bindings/led/ti,lp50xx.yaml +++ b/dts/bindings/led/ti,lp50xx.yaml @@ -8,7 +8,7 @@ properties: type: phandle-array description: | GPIO to use to enable/disable the controller. - max_curr_opt: + max-curr-opt: type: boolean description: | If enabled the maximum current output is set to 35 mA (25.5 mA else). diff --git a/dts/bindings/led_strip/worldsemi,ws2812-i2s.yaml b/dts/bindings/led_strip/worldsemi,ws2812-i2s.yaml index cd698dbe9e644..341708e2d3ce0 100644 --- a/dts/bindings/led_strip/worldsemi,ws2812-i2s.yaml +++ b/dts/bindings/led_strip/worldsemi,ws2812-i2s.yaml @@ -9,15 +9,10 @@ description: | compatible: "worldsemi,ws2812-i2s" -include: [base.yaml, ws2812.yaml] +include: [i2s-device.yaml, ws2812.yaml] properties: - i2s-dev: - type: phandle - required: true - description: Pointer to the I2S instance. - out-active-low: type: boolean description: True if the output pin is active low. diff --git a/dts/bindings/mbox/ti,omap-mailbox.yaml b/dts/bindings/mbox/ti,omap-mailbox.yaml new file mode 100644 index 0000000000000..1dd6d64b5520b --- /dev/null +++ b/dts/bindings/mbox/ti,omap-mailbox.yaml @@ -0,0 +1,23 @@ +# Copyright 2024 Texas Instruments Incorporated. +# SPDX-License-Identifier: Apache-2.0 + +description: TI OMAP MAILBOX + +compatible: "ti,omap-mailbox" + +include: [base.yaml, mailbox-controller.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + usr-id: + type: int + required: true + description: User ID for processor + +mbox-cells: + - channel diff --git a/dts/bindings/mdio/microchip,lan865x-mdio.yaml b/dts/bindings/mdio/microchip,lan865x-mdio.yaml new file mode 100644 index 0000000000000..9940354b1e141 --- /dev/null +++ b/dts/bindings/mdio/microchip,lan865x-mdio.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: LAN865X MDIO Driver node + +compatible: "microchip,lan865x-mdio" + +include: mdio-controller.yaml + +on-bus: lan865x diff --git a/dts/bindings/mdio/sensry,sy1xx-mdio.yaml b/dts/bindings/mdio/sensry,sy1xx-mdio.yaml new file mode 100644 index 0000000000000..978d6b167c97a --- /dev/null +++ b/dts/bindings/mdio/sensry,sy1xx-mdio.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +description: Sensry SY1XX MDIO Driver node + +compatible: "sensry,sy1xx-mdio" + +include: [base.yaml, mdio-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true diff --git a/dts/bindings/memory-controllers/renesas,ra-sdram.yaml b/dts/bindings/memory-controllers/renesas,ra-sdram.yaml new file mode 100644 index 0000000000000..c4dcfec4745bb --- /dev/null +++ b/dts/bindings/memory-controllers/renesas,ra-sdram.yaml @@ -0,0 +1,130 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + Renesas RA SDRAM controller. + sdram { + pinctrl-0 = <&sdram_default>; + pinctrl-names = "default"; + status = "okay"; + auto-refresh-interval = <10>; + auto-refresh-count = <8>; + precharge-cycle-count = <3>; + multiplex-addr-shift = "10-bit"; + edian-mode = "little-endian"; + continuous-access; + bus-width = "16-bit"; + bank@0 { + reg = <0>; + renesas,ra-sdram-timing = ; + }; + + Note that you will find definitions for the renesas,ra-sdram-control field at + dt-bindings/memory-controller/renesas,ra-sdram.h. This file is already included + in the SoC DeviceTree files. + + Finally, in order to make the memory available you will need to define new + memory device/s in DeviceTree: + + sdram1: sdram@68000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + device_type = "memory"; + reg = <0x68000000 DT_SIZE_M(X)>; + zephyr,memory-region = "SDRAM"; + }; + +compatible: "renesas,ra-sdram" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + "#address-cells": + required: true + const: 1 + + "#size-cells": + required: true + const: 0 + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + auto-refresh-interval: + type: int + default: 10 + description: Number of auto-refresh-interval. + + auto-refresh-count: + type: int + default: 8 + description: Number of auto-refresh-count. + + precharge-cycle-count: + type: int + default: 3 + description: Number of precharge-cycle-count. + + multiplex-addr-shift: + type: string + default: "10-bit" + enum: + - "8-bit" + - "9-bit" + - "10-bit" + - "11-bit" + description: | + Select the size of the shift towards the lower half of the row address in row address/column + address multiplexing. + + edian-mode: + type: string + default: "little-endian" + enum: + - "little-endian" + - "big-endian" + description: Specifies the endianness for the SDRAM address space. + + continuous-access: + type: boolean + description: Enables or disables continuous access to the SDRAM access space. + + bus-width: + type: string + default: "16-bit" + enum: + - "16-bit" + - "32-bit" + - "8-bit" + description: Specify the data bus width for SDRAM + +child-binding: + description: SDRAM bank. + + properties: + reg: + type: int + required: true + + renesas,ra-sdram-timing: + type: array + required: true + description: | + SDRAM timing configuration. Expected fields, in order, are, + + - TRAS: Row active interval. The effective value from 1 to 7 cycles + - TRCD: Row column latency. The effective value from 1 to 4 cycles + - TRP: Row precharge interval. The effective value from 1 to 8 cycles + - TWR: Write recovery interval. The effective value from 1 to 2 cycles + - TCL: Column latency. The effective value from 1 to 3 cycles + - TRFC: Auto-Refresh Request Interval Setting. + - TREFW: Auto-Refresh Cycle/Self-Refresh Clearing Cycle Count Setting. + The effective value from 1 to 16 cycles diff --git a/dts/bindings/memory-controllers/st,stm32-fmc-sdram.yaml b/dts/bindings/memory-controllers/st,stm32-fmc-sdram.yaml index 71c41673e645f..080c9e6446069 100644 --- a/dts/bindings/memory-controllers/st,stm32-fmc-sdram.yaml +++ b/dts/bindings/memory-controllers/st,stm32-fmc-sdram.yaml @@ -58,14 +58,14 @@ description: | sdram1: sdram@c0000000 { compatible = "zephyr,memory-region", "mmio-sram"; device_type = "memory"; - reg = <0xc000000 DT_SIZE_M(X)>; + reg = <0xc0000000 DT_SIZE_M(X)>; zephyr,memory-region = "SDRAM1"; }; sdram2: sdram@d0000000 { compatible = "zephyr,memory-region", "mmio-sram"; device_type = "memory"; - reg = <0xd000000 DT_SIZE_M(X)>; + reg = <0xd0000000 DT_SIZE_M(X)>; zephyr,memory-region = "SDRAM2"; }; diff --git a/dts/bindings/mfd/adi,max22017.yaml b/dts/bindings/mfd/adi,max22017.yaml new file mode 100644 index 0000000000000..06bf2d8a63978 --- /dev/null +++ b/dts/bindings/mfd/adi,max22017.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +include: spi-device.yaml + +description: Analog MAX22017 DAC/GPIO chip common properties + +properties: + rst-gpios: + description: Reset pin for max22017. + type: phandle-array + + crc-mode: + description: Enables CRC over SPI. + type: boolean + + int-gpios: + description: Interrupt gpio + type: phandle-array + +compatible: "adi,max22017" diff --git a/dts/bindings/mfd/ite,it8801-mfd.yaml b/dts/bindings/mfd/ite,it8801-mfd.yaml index 99d7c45e07351..fd69ec5a35088 100644 --- a/dts/bindings/mfd/ite,it8801-mfd.yaml +++ b/dts/bindings/mfd/ite,it8801-mfd.yaml @@ -5,15 +5,9 @@ description: | ITE IT8801 ioexpander multi-function device drivers. This ioexpander provides a GPIO/PWM/Keyboard function via I2C bus. - An example configuration: + An example configuration using the it8801-common-cfg.dtsi template: &i2c4 { - status = "okay"; - clock-frequency = ; - pinctrl-0 = <&i2c4_clk_gpe0_default - &i2c4_data_gpe7_default>; - pinctrl-names = "default"; - it8801_mfd: it8801@38 { compatible = "ite,it8801-mfd"; /* @@ -23,74 +17,27 @@ description: | */ reg = <0x38>; irq-gpios = <&gpioa 1 0>; /* SMB_INT# */ - #address-cells = <1>; - #size-cells = <1>; - - ioex_it8801_port0: it8801_port@0 { - compatible = "ite,it8801-gpio"; - reg = <0x00 1 /* GPIPSR */ - 0x05 1 /* GPSOVR */ - 0x0a 8 /* GPCR */ - 0x32 1 /* GPISR */ - 0x37 1>; /* GPIER */ - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin-mask = <0xdb>; - }; - - ioex_it8801_port1: it8801_port@1 { - compatible = "ite,it8801-gpio"; - reg = <0x01 1 /* GPIPSR */ - 0x06 1 /* GPSOVR */ - 0x12 8 /* GPCR */ - 0x33 1 /* GPISR */ - 0x38 1>; /* GPIER */ - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin-mask = <0x3f>; - }; - - ioex_it8801_port2: it8801_port@2 { - compatible = "ite,it8801-gpio"; - reg = <0x02 1 /* GPIPSR */ - 0x07 1 /* GPSOVR */ - 0x1a 8 /* GPCR */ - 0x34 1 /* GPISR */ - 0x39 1>; /* GPIER */ - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - pin-mask = <0x0f>; - }; - - ioex_it8801_kbd: it8801_kbd@40 { - compatible = "ite,it8801-kbd"; - reg = <0x40 1 /* KSOMCR */ - 0x41 1 /* KSIDR */ - 0x42 1 /* KSIEER */ - 0x43 1>; /* KSIIER */ - kso-mapping = <0 1 20 3 4 5 6 - 17 18 16 15 11 12>; - mfdctrl = <&kso18_gp01_default - &kso20_gp23_default>; - row-size = <8>; - col-size = <13>; - - kscan_input: kscan-input { - compatible = "zephyr,kscan-input"; - }; - }; + } + + #include + + /* sub-devices available at nodelabels: + * - ioex_it8801_port0 + * - ioex_it8801_port1 + * - ioex_it8801_port2 + * - ioex_it8801_kbd + * - ioex_it8801_pwm + */ + + &ioex_it8801_kbd { + kso-mapping = <0 1 20 3 4 5 6 17 18 16 15 11 12>; + mfdctrl = <&kso18_gp01_default &kso20_gp23_default>; + row-size = <8>; + col-size = <13>; + }; - ioex_it8801_pwm: it8801_pwm@90 { - compatible = "ite,it8801-pwm"; - mfdctrl = <&pwm7_gp20_default>; - reg = <0x90 1 /* PWMMCR */ - 0x94 1>; /* PWMDCR */ - channel = <7>; - #pwm-cells = <3>; - }; + &ioex_it8801_pwm { + status = "okay"; }; }; @@ -104,6 +51,7 @@ properties: irq-gpios: type: phandle-array + required: true description: | An interrupt can be asserted on SMB_INT# pin to notify the host-side since an effective interrupt occurs. diff --git a/dts/bindings/mfd/maxim,ds3231-mfd.yaml b/dts/bindings/mfd/maxim,ds3231-mfd.yaml new file mode 100644 index 0000000000000..666e936621c23 --- /dev/null +++ b/dts/bindings/mfd/maxim,ds3231-mfd.yaml @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Gergo Vari +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: | + Maxim DS3231 I2C MFD + + The following example displays the node layout + with every possible partial driver included. + + ds3231: ds3231@68 { + compatible = "maxim,ds3231-mfd"; + reg = <0x68>; + status = "okay"; + + ds3231_sensor: ds3231_sensor { + compatible = "maxim,ds3231-sensor"; + status = "okay"; + }; + + ds3231_rtc: ds3231_rtc { + compatible = "maxim,ds3231-rtc"; + status = "okay"; + + isw-gpios = <&gpio0 25 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + freq-32khz-gpios = <&gpio0 33 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + }; + +compatible: "maxim,ds3231-mfd" + +include: + - name: i2c-device.yaml diff --git a/dts/bindings/mfd/nxp,pf1550.yaml b/dts/bindings/mfd/nxp,pf1550.yaml new file mode 100644 index 0000000000000..53f6cdf2e2399 --- /dev/null +++ b/dts/bindings/mfd/nxp,pf1550.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +description: NXP PF1550 + +compatible: "nxp,pf1550" + +include: i2c-device.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/mipi-dbi/mipi-dbi-device.yaml b/dts/bindings/mipi-dbi/mipi-dbi-device.yaml index c7e11745d837f..57e2f42770b42 100644 --- a/dts/bindings/mipi-dbi/mipi-dbi-device.yaml +++ b/dts/bindings/mipi-dbi/mipi-dbi-device.yaml @@ -26,3 +26,21 @@ properties: - "MIPI_DBI_MODE_8080_BUS_16_BIT" - "MIPI_DBI_MODE_8080_BUS_9_BIT" - "MIPI_DBI_MODE_8080_BUS_8_BIT" + + te-mode: + type: string + default: "MIPI_DBI_TE_NO_EDGE" + description: | + MIPI DBI tearing enable signal mode. Defaults to disabled. + enum: + - "MIPI_DBI_TE_NO_EDGE" + - "MIPI_DBI_TE_RISING_EDGE" + - "MIPI_DBI_TE_FALLING_EDGE" + + te-delay: + type: int + default: 0 + description: | + Delay in microseconds to wait before transmitting display data after a + tearing enable synchronization signal is seen. Defaults to 0 since most + controllers will not need a delay. diff --git a/dts/bindings/mipi-dbi/mipi-dbi-spi-device.yaml b/dts/bindings/mipi-dbi/mipi-dbi-spi-device.yaml index 7bc2df4957f8e..96ff1405c7d8a 100644 --- a/dts/bindings/mipi-dbi/mipi-dbi-spi-device.yaml +++ b/dts/bindings/mipi-dbi/mipi-dbi-spi-device.yaml @@ -14,7 +14,7 @@ properties: as this is, by far, the most common mode. Selecting half duplex allows to use SPI MOSI as a bidirectional line, typically used when only one data line is connected. - Use the macros not the actual enum value, here is the concordance + Use the macros, not the actual enum value. Here is the concordance list (see dt-bindings/spi/spi.h) 0 SPI_FULL_DUPLEX 2048 SPI_HALF_DUPLEX diff --git a/dts/bindings/mipi-dbi/zephyr,mipi-dbi-spi.yaml b/dts/bindings/mipi-dbi/zephyr,mipi-dbi-spi.yaml index 023da2eb651c9..e3e292fefa5b5 100644 --- a/dts/bindings/mipi-dbi/zephyr,mipi-dbi-spi.yaml +++ b/dts/bindings/mipi-dbi/zephyr,mipi-dbi-spi.yaml @@ -27,6 +27,18 @@ properties: description: | Reset GPIO pin. Set high to reset the display + xfr-min-bits: + type: string + default: "MIPI_DBI_SPI_XFR_8BIT" + description: + On rare types of SPI interfaces, discrete shift registers can be found + whose task is to convert the serial SPI bit stream to the parallel MCU + interface with clock and bit accuracy. Typically, these are 16 bits wide. + These definitions should match those in dt-bindings/mipi_dbi/mipi_dbi.h + enum: + - "MIPI_DBI_SPI_XFR_8BIT" + - "MIPI_DBI_SPI_XFR_16BIT" + write-only: type: boolean description: | diff --git a/dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml b/dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml index 02871f29641bc..1e5458c570186 100644 --- a/dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml +++ b/dts/bindings/mipi-dsi/nxp,mipi-dsi-2l.yaml @@ -76,3 +76,8 @@ properties: description: Enable non-contiuous high speed clock. Saves power but introduces latency when transitioning to high speed mode. + + ulps-control: + type: boolean + description: + The IP supports ULPS between transfer. diff --git a/dts/bindings/mipi-dsi/renesas,ra-mipi-dsi.yaml b/dts/bindings/mipi-dsi/renesas,ra-mipi-dsi.yaml new file mode 100644 index 0000000000000..6f0f572aced1c --- /dev/null +++ b/dts/bindings/mipi-dsi/renesas,ra-mipi-dsi.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA MIPI DSI host + +compatible: "renesas,ra-mipi-dsi" + +include: [mipi-dsi-host.yaml] + +properties: + clocks: + required: true + + interrupts: + required: true + + interrupt-names: + type: string-array + required: true + description: name of each interrupt diff --git a/dts/bindings/misc/nordic,nrf-bicr.yaml b/dts/bindings/misc/nordic,nrf-bicr.yaml new file mode 100644 index 0000000000000..f5c127e6cf126 --- /dev/null +++ b/dts/bindings/misc/nordic,nrf-bicr.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic BICR (Board Information Configuration Registers) + +compatible: "nordic,nrf-bicr" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/misc/nxp,s32-emios.yaml b/dts/bindings/misc/nxp,s32-emios.yaml index 61c831a01a066..f795746f2ead0 100644 --- a/dts/bindings/misc/nxp,s32-emios.yaml +++ b/dts/bindings/misc/nxp,s32-emios.yaml @@ -52,7 +52,6 @@ child-binding: bus-type = "BUS_A"; channel-mask = <0x07FFFFF>; prescaler = <1>; - period = <65535>; mode = ; freeze; status = "okay"; @@ -104,13 +103,6 @@ child-binding: - "MCB_UP_COUNTER" - "MCB_UP_DOWN_COUNTER" - period: - type: int - required: true - description: | - Default period (in ticks) for master bus at boot time. This determines PWM period - for channels use this bus as reference timebase. Could be in range [2 ... 65535] - freeze: type: boolean description: Freeze internal counter when the chip enters Debug mode. diff --git a/dts/bindings/misc/renesas,ra-external-interrupt.yaml b/dts/bindings/misc/renesas,ra-external-interrupt.yaml new file mode 100644 index 0000000000000..b16ef44f666a3 --- /dev/null +++ b/dts/bindings/misc/renesas,ra-external-interrupt.yaml @@ -0,0 +1,44 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA External Interrupt + +compatible: "renesas,ra-external-interrupt" + +include: [base.yaml] + +properties: + interrupts: + required: true + + reg: + required: true + + channel: + type: int + required: true + + renesas,trigger: + type: string + enum: + - "falling" + - "rising" + - "both-edges" + - "low-level" + description: | + Select the signal edge or state that triggers an interrupt + + renesas,digital-filtering: + type: boolean + description: | + Select if data noise filter should be enabled. + + renesas,sample-clock-div: + type: int + enum: + - 1 + - 8 + - 32 + - 64 + description: | + Select the clock divider for the digital noise filter. Clock source is system clock. diff --git a/dts/bindings/mmc/st,stm32-sdmmc.yaml b/dts/bindings/mmc/st,stm32-sdmmc.yaml index 7071b44be163b..7daf115520d4f 100644 --- a/dts/bindings/mmc/st,stm32-sdmmc.yaml +++ b/dts/bindings/mmc/st,stm32-sdmmc.yaml @@ -5,6 +5,11 @@ compatible: "st,stm32-sdmmc" include: [mmc.yaml, pinctrl-device.yaml, reset-device.yaml] properties: + disk-name: + type: string + description: | + Disk name. + clocks: required: true diff --git a/dts/bindings/mmu_mpu/nxp,sysmpu.yaml b/dts/bindings/mmu_mpu/nxp,sysmpu.yaml new file mode 100644 index 0000000000000..4cf5e6d54f06d --- /dev/null +++ b/dts/bindings/mmu_mpu/nxp,sysmpu.yaml @@ -0,0 +1,12 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP System Memory Protection Unit (SYSMPU) + +compatible: "nxp,sysmpu" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/mtd/nxp,s32-qspi-device.yaml b/dts/bindings/mtd/nxp,s32-qspi-device.yaml index 23de077121ec1..889c3995f0117 100644 --- a/dts/bindings/mtd/nxp,s32-qspi-device.yaml +++ b/dts/bindings/mtd/nxp,s32-qspi-device.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 NXP +# Copyright 2023-2024 NXP # SPDX-License-Identifier: Apache-2.0 description: | @@ -14,9 +14,15 @@ properties: reg: required: true - memory-alignment: + max-program-buffer-size: type: int + required: true + description: | + The maximum of programming page buffer size of the flash memory device, + as specified in the flash memory device datasheet. + + write-block-size: + type: int + required: true description: | - Memory alignment in bytes, used to calculate padding when performing - unaligned accesses. - If not provided, 1 byte alignment will be selected. + The number of bytes used in write operations. diff --git a/dts/bindings/mtd/nxp,s32-qspi-hyperflash.yaml b/dts/bindings/mtd/nxp,s32-qspi-hyperflash.yaml new file mode 100644 index 0000000000000..3fe64dd9aba03 --- /dev/null +++ b/dts/bindings/mtd/nxp,s32-qspi-hyperflash.yaml @@ -0,0 +1,99 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + QSPI hyperflash connected to the NXP S32 QSPI bus. + +compatible: "nxp,s32-qspi-hyperflash" + +include: "nxp,s32-qspi-device.yaml" + +properties: + device-id-word-addr: + required: true + type: int + description: | + The word address of the device ID in ASO (Application-Specific Object). + This address specifies the exact location within the memory where the device ID is stored. + + rwds-low-dual-error: + type: boolean + description: | + Enable Read-Write Data Strobe (RWDS) dual error detect. + + secure-region-locked: + type: boolean + description: | + The secure region is locked and cannot be accessed or modified. + This is particularly useful in scenarios where sensitive data needs protection from + unauthorized access, such as in financial applications or secure communication systems. + If it is disable, having access to all memory regions is beneficial during development + or debugging phases. + + vcc-mv: + type: int + required: true + enum: + - 1800 + - 3000 + description: | + The memory operating voltage supply in mV. + + drive-strength-ohm: + type: int + required: true + enum: + - 12 + - 14 + - 16 + - 20 + - 24 + - 27 + - 34 + - 40 + - 45 + - 68 + - 71 + - 117 + description: | + Specifies the output drive strength in ohm, which based on the operating device VCC. + The supported typical impedance settings: + For 1.8V: 117 Ohm, 68 Ohm, 45 Ohm, 34 Ohm, 27 Ohm, 24 Ohm, 20 Ohm + For 3V: 71 Ohm, 40 Ohm, 27 Ohm, 20 Ohm, 16 Ohm, 14 Ohm, 12 Ohm + See the xVCR[14:12] field in VCR configuration register in the memory device datasheet. + + read-latency-cycles: + type: int + required: true + enum: + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + - 13 + - 14 + - 15 + - 16 + description: | + Specifies the read latency in cycles, which is determined based on the operating frequency + as specified in the memory device datasheet. + + support-only-uniform-sectors: + type: boolean + description: | + The memory device supports only uniform (256KB) sectors. + + ppw-sectors-addr-mapping: + type: string + required: true + enum: + - LOW + - HIGH + description: | + The mapping of the parameter and read password sectors: + - LOW: Parameter and read password sectors mapped into lowest addresses + - HIGH: Parameter and read password sectors mapped into highest addresses diff --git a/dts/bindings/mtd/nxp,xspi-device.yaml b/dts/bindings/mtd/nxp,xspi-device.yaml new file mode 100644 index 0000000000000..d067b878c9306 --- /dev/null +++ b/dts/bindings/mtd/nxp,xspi-device.yaml @@ -0,0 +1,6 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP XSPI device + +include: [spi-device.yaml, "jedec,jesd216.yaml"] diff --git a/dts/bindings/mtd/nxp,xspi-mx25um51345g.yaml b/dts/bindings/mtd/nxp,xspi-mx25um51345g.yaml new file mode 100644 index 0000000000000..6554d5d61afd5 --- /dev/null +++ b/dts/bindings/mtd/nxp,xspi-mx25um51345g.yaml @@ -0,0 +1,8 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP XSPI MX25UM51345G + +compatible: "nxp,xspi-mx25um51345g" + +include: ["nxp,xspi-device.yaml", soc-nv-flash.yaml] diff --git a/dts/bindings/mtd/ti,cc23x0-ccfg-flash.yaml b/dts/bindings/mtd/ti,cc23x0-ccfg-flash.yaml new file mode 100644 index 0000000000000..0786ec7c478cd --- /dev/null +++ b/dts/bindings/mtd/ti,cc23x0-ccfg-flash.yaml @@ -0,0 +1,161 @@ +# Copyright (c) 2024 BayLibre, SAS +# SPDX-License-Identifier: Apache-2.0 + +description: | + This binding describes the TI CC23X0 flash CCFG (custom configuration) + area content. + + Notes: + The flash CCFG sector node (e.g. flash1) should have both + "ti,cc23x0-ccfg-flash" and the "soc-nv-flash" compatibles. + The latter is used from mcuboot and other modules to identify + the flash area. + +compatible: "ti,cc23x0-ccfg-flash" + +include: soc-nv-flash.yaml + +properties: + ti,bldr-vtor-flash: + type: int + description: | + Bootloader entry point when a boot from flash is selected. + Valid range: 0 - 0x0effffff + Default is 0, which is the standard initial configuration. + default: 0 + + ti,serial-io-cfg-index: + type: int + description: | + Index of which I/O mapping to use for UART/SPI. + Valid range: 0 - 2 + Default is 0, which is the standard initial configuration. Other values can be + used depending on I/O availability. + default: 0 + + ti,pin-trigger: + type: boolean + description: | + If not present, then bootloader unconditionally triggers. + Else normal pin trigger check is performed. + + ti,pin-trigger-dio: + type: int + description: | + Index of DIO pin to use for pin trigger check. + Valid range: 0 - 25 + Default is 0, which is the standard initial configuration. Other values can be + used depending on DIO availability. + default: 0 + + ti,pin-trigger-level-hi: + type: boolean + description: | + If not present, then the level on trigger pin that triggers bootloader is low. + Else level that triggers bootloader is high. + + ti,debug-port: + type: boolean + description: | + If not present, then the SWD port is disabled altogether at a certain point in boot + before invoking either bootloader or application. + + ti,energy-trace: + type: boolean + description: | + Allows using EnergyTrace power analyzer tool. + EnergyTrace software is an energy-based code analysis tool that measures + and displays the energy profile of an application and helps optimize it for + ultra-low-power consumption. + + ti,flash-verify: + type: boolean + description: | + Determines whether flash verifying SACI commands are allowed. These commands only check + integrity against a provided CRC32 value, never return any flash contents. Flash verify + commands are always allowed after a chip erase and until the first reset after the CCFG + sector has been programmed. + + ti,flash-program: + type: boolean + description: | + Determines whether flash programming SACI commands are allowed. + Reset to allowed after a chip erase. + + ti,chip-erase: + type: boolean + description: | + Determines whether chip erasing SACI commands are allowed. + + ti,ret-to-factory: + type: boolean + description: | + Allows return-to-factory procedure by SACI. + To do full failure analysis including flash, a return to factory procedure is supported. + + ti,wr-er-prot-sect0-31: + type: int + description: | + Bitmask for write/erase protection of individual sectors in sector range [0, 31]. + Controls whether flash programming is allowed through SACI. The same mechanism + controls whether the application is allowed to program these sectors. + 0 = protected. + Valid range: 0 - 0xffffffff + Default is 0xffffffff to allow programming these sectors. + default: 0xffffffff + + ti,wr-er-prot-sect32-255: + type: int + description: | + Bitmask for write/erase protection of groups of 8 sectors, in sector range [32, 255]. + Bit i protects sectors [32 + 8i, 39 + 8i]. + 0 = protected. + Valid range: 0 - 0xffffffff + Default is 0xffffffff to allow programming these sectors. + default: 0xffffffff + + ti,wr-er-prot-ccfg-sect: + type: int + description: | + Bitmask for write/erase protection of CCFG sectors. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 + + ti,wr-er-prot-fcfg-sect: + type: int + description: | + Bitmask for write/erase protection of FCFG sectors. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 + + ti,wr-er-prot-engr-sect: + type: int + description: | + Bitmask for write/erase protection of ENGR sectors. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 + + ti,chip-er-retain-sect0-31: + type: int + description: | + Bitmask for chip erase protection of individual sectors in sector range [0, 31]. + Controls whether a chip erase affects a sector or not. The mechanism is intended + to allow flash sectors devoted to logging or runtime state/configuration to survive + the chip erase during a FW update. + 0 = protected. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 + + ti,chip-er-retain-sect32-255: + type: int + description: | + Bitmask for chip erase protection of groups of 8 sectors, in sector range [32, 255]. + Bit i protects sectors [32 + 8i, 39 + 8i]. + 0 = protected. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 diff --git a/dts/bindings/net/wireless/silabs,series2-radio.yaml b/dts/bindings/net/wireless/silabs,series2-radio.yaml new file mode 100644 index 0000000000000..7d2d1606406b1 --- /dev/null +++ b/dts/bindings/net/wireless/silabs,series2-radio.yaml @@ -0,0 +1,59 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Silicon Labs Series 2 radio interface. + + This controls the radio transceiver on Silicon Labs Series 2 + SoCs. + +compatible: "silabs,series2-radio" + +include: [base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + pa-initial-power-dbm: + type: int + required: true + description: | + Initial Power Amplifier power in dBm. + + pa-ramp-time-us: + type: int + required: true + description: | + Power Amplifier ramp time in microseconds. + + pa-voltage-mv: + type: int + required: true + description: | + Voltage on PAVDD supply pin in millivolts. + + pa-2p4ghz: + type: string + description: | + Power Amplifier selection for 2.4 GHz. A value of 'highest' selects the highest + available PA on the given device. Other values explicitly select a specific PA. + Not all PAs are available on all devices, check device specific documentation. + If this property is not set, no 2.4 GHz PA is enabled. + enum: + - highest + - hp + - mp + - lp + + pa-subghz: + type: string + description: | + Power Amplifier selection for sub-GHz. A value of 'highest' selects the highest + available PA on the given device. This is the only available option. If this + property is not set, no sub-GHz PA is enabled. + enum: + - highest diff --git a/dts/bindings/pcie/controller/brcm,brcmstb-pcie.yaml b/dts/bindings/pcie/controller/brcm,brcmstb-pcie.yaml new file mode 100644 index 0000000000000..850260c09e65e --- /dev/null +++ b/dts/bindings/pcie/controller/brcm,brcmstb-pcie.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Junho Lee +# SPDX-License-Identifier: Apache-2.0 + +description: BRCMSTB PCIe controller + +compatible: "brcm,brcmstb-pcie" + +include: [base.yaml, pcie-controller.yaml] + +properties: + reg: + required: true diff --git a/dts/bindings/phy/renesas,ra-usbphyc.yaml b/dts/bindings/phy/renesas,ra-usbphyc.yaml new file mode 100644 index 0000000000000..45806d2e1d94b --- /dev/null +++ b/dts/bindings/phy/renesas,ra-usbphyc.yaml @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA USBHS internal PHY controller + +compatible: "renesas,ra-usbphyc" + +include: phy-controller.yaml + +properties: + clock: + type: phandle + description: | + Clock source for PHY clock in case internal clock is using + + phys-clock-src: + type: string + enum: + - "internal" + - "xtal" + description: | + Select clock source for PHY clock as XTAL or use internal clock + + "#phy-cells": + const: 0 diff --git a/dts/bindings/phy/st,stm32u5-otghs-phy.yaml b/dts/bindings/phy/st,stm32u5-otghs-phy.yaml new file mode 100644 index 0000000000000..f844d813a9929 --- /dev/null +++ b/dts/bindings/phy/st,stm32u5-otghs-phy.yaml @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Marcin Niestroj +# Copyright (c) 2024 Meta +# SPDX-License-Identifier: Apache-2.0 + +description: | + This binding is to be used by the STM32U5xx transceivers which are built-in + with USB HS PHY IP and a configurable HSE clock source. + +compatible: "st,stm32u5-otghs-phy" + +include: phy-controller.yaml + +properties: + "#phy-cells": + const: 0 + + clocks: + required: true + description: | + Supported configurations: + + /* HSE */ + clocks = <&rcc STM32_CLOCK(AHB2, 15U)>, + <&rcc STM32_SRC_HSE OTGHS_SEL(0)>; + + /* HSE/2 */ + clocks = <&rcc STM32_CLOCK(AHB2, 15U)>, + <&rcc (STM32_SRC_HSE | STM32_CLOCK_DIV(2)) OTGHS_SEL(2)>; + + /* PLL1_P_CK */ + clocks = <&rcc STM32_CLOCK(AHB2, 15U)>, + <&rcc STM32_SRC_PLL1_P OTGHS_SEL(1)>; + + /* PLL1_P_CK/2 */ + clocks = <&rcc STM32_CLOCK(AHB2, 15U)>, + <&rcc (STM32_SRC_PLL1_P | STM32_CLOCK_DIV(2)) OTGHS_SEL(3)>; diff --git a/dts/bindings/pinctrl/nxp,imx-gpr.yaml b/dts/bindings/pinctrl/nxp,imx-gpr.yaml index f6944de8860b3..dbc8cd946147d 100644 --- a/dts/bindings/pinctrl/nxp,imx-gpr.yaml +++ b/dts/bindings/pinctrl/nxp,imx-gpr.yaml @@ -1,7 +1,14 @@ # Copyright (c) 2021, NXP # SPDX-License-Identifier: Apache-2.0 -description: i.MX IOMUXC node +description: | + i.MX IOMUXC node + + The specifier space "pinmux" of this binding should have two cells describing + the resources needed from the GPR registers. + For each specifier, the first cell should be the offset of the GPR register in bytes + from the base address of the GPR device base address. The second cell should be a + bitmask indicating which bits in the specified register are relevant to the referencing device. compatible: "nxp,imx-gpr" @@ -12,5 +19,5 @@ properties: required: true pinmux-cells: - - pin - - function + - offset + - mask diff --git a/dts/bindings/pinctrl/realtek,rts5912-pinctrl.yaml b/dts/bindings/pinctrl/realtek,rts5912-pinctrl.yaml new file mode 100644 index 0000000000000..c5b00ae822a93 --- /dev/null +++ b/dts/bindings/pinctrl/realtek,rts5912-pinctrl.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +description: | + This binding gives a base representation of the pins configuration + +compatible: "realtek,rts5912-pinctrl" + +include: [base.yaml, pinctrl-device.yaml, pincfg-node.yaml] + +properties: + reg: + required: true + +child-binding: + description: | + This binding gives a base representation of the pins configuration + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-pull-down + - bias-pull-up + - drive-push-pull + - drive-open-drain + - input-enable + - output-enable + - output-high + - output-low + - input-schmitt-enable + + properties: + pinmux: + type: int + required: true + description: Pinmux selection + drive-strength: + type: string + enum: + - "low" + - "high" + description: | + "low" — 4mA/8mA drive strength + "high" — 8mA/12mA drive strength + slew-rate: + type: string + enum: + - "fast" + - "low" + description: | + "fast" — Fast Frequency Slew Rate + "slow" — Slow Frequency Slew Rate diff --git a/dts/bindings/pinctrl/renesas,rzg-pinctrl.yaml b/dts/bindings/pinctrl/renesas,rzg-pinctrl.yaml new file mode 100644 index 0000000000000..2b17a67857cfa --- /dev/null +++ b/dts/bindings/pinctrl/renesas,rzg-pinctrl.yaml @@ -0,0 +1,95 @@ +# Copyright (c) 2024 Epam Systems +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + Below generic example shows of supported pinctrl definitions: + + #include + example_pins: device_pin { + device-pinmux { + pinmux = , + ; + bias_pull_up; + renesas,filter = RZG_FILTER_SET(RZG_FILNUM_8_STAGE,RZG_FILCLKSEL_DIV_18000); + drive-strength = <1>; + }; + + device-spins { + pins = , ; + input-enable; + renesas,filter = RZG_FILTER_SET(RZG_FILNUM_8_STAGE,RZG_FILCLKSEL_DIV_18000); + drive-strength = <2>; + }; + }; + + +compatible: renesas,rzg-pinctrl + +include: base.yaml +properties: + reg: + required: true + + reg-names: + required: true + +child-binding: + description: | + This RZG pins mux/cfg nodes description. + + child-binding: + description: | + The RZG pinmux/pincfg configuration nodes description. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-disable + - bias-high-impedance + - bias-pull-down + - bias-pull-up + - bias-pull-pin-default + - drive-strength + - input-enable + - input-disable + - output-enable + - power-source + - low-power-enable + - low-power-disable + + properties: + pinmux: + type: array + description: | + Pinmux configuration node. + Values are constructed from GPIO port number, pin number, and + alternate function configuration number using the RZG_PINMUX() + helper macro in pinctrl_rzg.h + + pins: + type: array + description: | + Special Purpose pins configuration node. + Values are define in pinctrl_rzg.h. + Ex: BSP_IO_XSPI_IO0,BSP_IO_I3C_SCL,... + + drive-strength: + type: int + default: 0 + description: | + Maximum sink or source current in mA for pin which shell be selected + depending on device and pin group. + + renesas,filter: + type: int + default: 0 + description: | + Digital Noise Filter configuration for a pin which shell be defined + using RZG_FILTER_SET() helper macro in pinctrl_rzg.h to specify + FILNUM_m and FILCLKSEL_m. With 24Mhz external clock: + - min debounce time will be 166.666ns for FILNUM_m=0 and FILCLKSEL_m=0 + - max debounce time will be 24ms for FILNUM_m=3 and FILCLKSEL_m=3. + This property intentionally redefined to avoid unnecessary conversation from usec to + FILNUM_m and FILCLKSEL_m values depending on external clock value as this configuration + is static. diff --git a/dts/bindings/pinctrl/sensry,sy1xx-pinctrl.yaml b/dts/bindings/pinctrl/sensry,sy1xx-pinctrl.yaml new file mode 100644 index 0000000000000..776f561f4c43a --- /dev/null +++ b/dts/bindings/pinctrl/sensry,sy1xx-pinctrl.yaml @@ -0,0 +1,74 @@ +# Copyright (c) 2024 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +description: | + The sensry SY1xx pin controller is a single node responsible for controlling + pin configuration, such as pull-up, pull-down, tri-state, ... + + The node has the 'pinctrl0' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl0 { + /* your modifications go here */ + }; + + For example: + &pinctrl0 { + + /* UART0 */ + uart0_tx: uart0_tx { + pinmux = ; + }; + + uart0_rx: uart0_rx { + pinmux = ; + input-enable; + }; + } + + Then define the uart: + &uart0 { + pinctrl-0 = <&uart0_tx &uart0_rx>; + pinctrl-names = "default"; + }; + + Every pin configuration will be configured in a 32bit register. The configuration + itself is 8bit wide. So we have a number of 4 pin configurations per 32bit register. + + The pinmux describes the registers address and the offset [0, 8, 16, 24] for + the individual configuration. + + Allowed modifiers for each pin are: + - bias-high-impedance + - bias-pull-down + - bias-pull-up + - input-enable + - input-schmitt-enable + +compatible: "sensry,sy1xx-pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: Each child node defines the configuration of a particular state. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-high-impedance + - bias-pull-down + - bias-pull-up + - input-enable + - input-schmitt-enable + + properties: + pinmux: + required: true + type: array + description: | + Pin mux selection. See the SOC level pinctrl header + for a defined list of these options. diff --git a/dts/bindings/pinctrl/silabs,dbus-pinctrl.yaml b/dts/bindings/pinctrl/silabs,dbus-pinctrl.yaml index 410edd4cf5e08..d0229c72a3349 100644 --- a/dts/bindings/pinctrl/silabs,dbus-pinctrl.yaml +++ b/dts/bindings/pinctrl/silabs,dbus-pinctrl.yaml @@ -6,7 +6,8 @@ description: | pin function selection and pin properties. For example, you can use this node to route USART0 RX to pin PA1 and enable the pull-up resistor on the pin. This pin controller is used for devices that use DBUS (Digital Bus) - for alternate function configuration, including Series 2 devices. + for alternate function configuration, including Series 2 devices. It is + also capable of ABUS (Analog Bus) allocation. The pinctrl settings are referenced in a device tree peripheral node. For example when configuring a USART: @@ -81,6 +82,24 @@ description: | Allowed in drive-push-pull and drive-open-drain modes. + ABUS allocation is performed using the 'silabs,analog-bus' property. This + property takes an array of buses to allocate. Example: + + &pinctrl { + iadc0_default: iadc0_default { + group0 { + /* Allocate even bus 0 and odd bus 1 from GPIO port A for ADC use */ + silabs,analog-bus = , ; + } + }; + }; + + A given group may contain a mix of analog bus allocations and digital pin + selections. Digital pin properties only apply to digital pins. Analog input + selection is not done through the pin controller, this is done in the devicetree + node for the respective peripheral using properties such as 'zephyr,input-positive' + for ADC. + compatible: "silabs,dbus-pinctrl" include: base.yaml @@ -107,7 +126,6 @@ child-binding: properties: pins: - required: true type: array description: | An array of pins sharing the same group properties. The pins should be @@ -126,3 +144,10 @@ child-binding: for this pin. May be used in drive-push-pull and drive-open-drain modes. type: boolean + + silabs,analog-bus: + type: array + description: | + Assign one or more analog buses to the given GPIO port. The bus should + be defined using the ABUS__ macros available from the + SoC DeviceTree files. diff --git a/dts/bindings/pinctrl/silabs,siwx91x-pinctrl.yaml b/dts/bindings/pinctrl/silabs,siwx91x-pinctrl.yaml new file mode 100644 index 0000000000000..8dc8a9305acd0 --- /dev/null +++ b/dts/bindings/pinctrl/silabs,siwx91x-pinctrl.yaml @@ -0,0 +1,63 @@ +# Copyright (c) 2023 Antmicro +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + The Silabs SiWx91x pin controller is a devicetree node tasked with selecting + the proper IO function for a given pin. + + The pinctrl settings are referenced in a device tree peripheral node. For + example when configuring a UART: + + &ulpuart { + pinctrl-0 = <&ulpuart_default>; + pinctrl-names = "default"; + } + + pinctrl-0 is a phandle that stores the pin settings for the peripheral, in + this example &ulpuart_default. This phandle is defined as a child node of the + 'pinctrl' node, typically in a board-pinctrl.dtsi file in the board directory + or a device tree overlay in the application: + + &pinctrl { + ulpuart_default: ulpuart_default { + out { + pinmux = ; /* Configure ULP pin 11 as ULPUART TX */ + }; + in { + pinmux = ; /* Configure ULP pin 9 as ULPUART RX */ + }; + }; + }; + + The 'ulpuart_default' child node encodes the pin configurations for a + particular state of the device, the default (active) state. + + Pin configurations are organized in groups within each child node. The name + given to groups is arbitrary. Each group can specify a list of pin function + selections in the `pinmux` property, as well as a selection of pin properties + as given by the rest of the properties on the group. + +compatible: "silabs,siwx91x-pinctrl" + +include: base.yaml + +child-binding: + description: | + Silabs SiWx91x pin configuration. Each child node defines + the configuration for a particular group of pins. + child-binding: + description: | + Silabs SiWx91x pin configuration group. + include: + - name: pincfg-node.yaml + property-allowlist: [] + + properties: + pinmux: + required: true + type: array + description: | + An array of pins sharing the same group properties. The pins should be + defined using the __ macros available from + the SoC DeviceTree files. diff --git a/dts/bindings/pinctrl/st,stm32-pinctrl.yaml b/dts/bindings/pinctrl/st,stm32-pinctrl.yaml index a9f416026435a..26278a7370e04 100644 --- a/dts/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/dts/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -54,8 +54,8 @@ child-binding: description: | Reused from https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml - Integer array, represents gpio pin number and mux setting. - These defines are calculated as: ((port * 16 + line) << 8) | function + Integer represents gpio pin number and mux setting. + Each integer encodes a port, line and alternate function. With: - port: The gpio port index (PA = 0, PB = 1, ..., PK = 11) - line: The line offset within the port (PA0 = 0, PA1 = 1, ..., PA15 = 15) @@ -74,7 +74,7 @@ child-binding: To simplify the usage, macro is available to generate "pinmux" field. This macro is available here: - -include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h + -include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h Some examples of macro usage: GPIO A9 set as alternate function 2 ... { diff --git a/dts/bindings/pinctrl/st,stm32f1-pinctrl.yaml b/dts/bindings/pinctrl/st,stm32f1-pinctrl.yaml index 77efa78c06418..9d6cda27307c4 100644 --- a/dts/bindings/pinctrl/st,stm32f1-pinctrl.yaml +++ b/dts/bindings/pinctrl/st,stm32f1-pinctrl.yaml @@ -61,8 +61,8 @@ child-binding: description: | Adapted from https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml - Integer array, represents gpio pin number and mux setting. - These defines are calculated as: ((port * 16 + line) << 8) | (function << 6) | remap) + Integer represents gpio pin number and mux setting. + Each integer encodes a port, line, alternate function and remap. With: - port: The gpio port index (PA = 0, PB = 1, ..., PK = 11) - line: The line offset within the port (PA0 = 0, PA1 = 1, ..., PA15 = 15) diff --git a/dts/bindings/pinctrl/ti,cc23x0-pinctrl.yaml b/dts/bindings/pinctrl/ti,cc23x0-pinctrl.yaml new file mode 100644 index 0000000000000..9f3b17221b7ca --- /dev/null +++ b/dts/bindings/pinctrl/ti,cc23x0-pinctrl.yaml @@ -0,0 +1,62 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# SPDX-License-Identifier: Apache-2.0 + +description: | + TI SimpleLink CC23X0 pinctrl node. + + Device pin configuration should be placed in the child nodes of this node. + Populate the 'pinmux' field with a pair consisting of a pin number and its IO + functions. + + The node has the 'pinctrl' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the + 'pinctrl' node, as in the i2c0 example shown at the end. + + Here is a list of + supported standard pin properties: + + - bias-disable: Disable pull-up/down. + - bias-pull-down: Enable pull-down resistor. + - bias-pull-up: Enable pull-up resistor. + - drive-open-drain: Output driver is open-drain. + - drive-open-source: Output driver is open-source. + - input-enable: enable input. + - input-schmitt-enable: enable input schmitt circuit. + +compatible: "ti,cc23x0-pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + This binding gives a base representation of the CC23X0 + pins configuration. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-disable + - bias-pull-down + - bias-pull-up + - drive-open-drain + - drive-open-source + - input-enable + - input-schmitt-enable + + properties: + pinmux: + required: true + type: array + description: | + CC23X0 pin's configuration (IO pin, IO function). diff --git a/dts/bindings/power-domain/power-domain-soc-state-change.yaml b/dts/bindings/power-domain/power-domain-soc-state-change.yaml new file mode 100644 index 0000000000000..6f5955241d1bc --- /dev/null +++ b/dts/bindings/power-domain/power-domain-soc-state-change.yaml @@ -0,0 +1,23 @@ +# Copyright 2024-25 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + This power domain will Turn On and Off devices when transitioning + in and out a specified Power State. Power States that trigger this + action is specified via the onoff-power-states property. + +compatible: "power-domain-soc-state-change" + +include: power-domain.yaml + +properties: + onoff-power-states: + type: phandles + description: | + List of power management states. + The registered devices will be turned off before the PM subsystem + enters these PM states. The devices will be turned on after the + PM subsystem exits these PM states. + + "#power-domain-cells": + const: 0 diff --git a/dts/bindings/pwm/atmel,sam0-tc-pwm.yaml b/dts/bindings/pwm/atmel,sam0-tc-pwm.yaml new file mode 100644 index 0000000000000..bb486bdbff08b --- /dev/null +++ b/dts/bindings/pwm/atmel,sam0-tc-pwm.yaml @@ -0,0 +1,68 @@ +# Copyright (c) 2020 Google LLC. +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Atmel SAM0 TC in PWM mode + +compatible: "atmel,sam0-tc-pwm" + +include: + - name: base.yaml + - name: pwm-controller.yaml + - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + clock-names: + required: true + + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + + channels: + type: int + required: true + description: Number of channels this TC has + enum: + - 2 + + counter-size: + type: int + required: true + description: Width of the TC counter in bits + enum: + - 8 + - 16 + + prescaler: + type: int + required: true + description: PWM prescaler + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 64 + - 256 + - 1024 + + "#pwm-cells": + const: 2 + +pwm-cells: + - channel + - period diff --git a/dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml b/dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml index 358528f47ef22..75f4c2abd007b 100644 --- a/dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml +++ b/dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2020 Google LLC. +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 TCC in PWM mode @@ -9,6 +10,7 @@ include: - name: base.yaml - name: pwm-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -23,6 +25,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + channels: type: int required: true diff --git a/dts/bindings/pwm/espressif,esp32-ledc.yaml b/dts/bindings/pwm/espressif,esp32-ledc.yaml index 39d4c3c59fee7..e46a7c7876093 100644 --- a/dts/bindings/pwm/espressif,esp32-ledc.yaml +++ b/dts/bindings/pwm/espressif,esp32-ledc.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. # SPDX-License-Identifier: Apache-2.0 description: | @@ -64,6 +64,7 @@ description: | channel9@9 { reg = <0x9>; timer = <0>; + inverted; }; channel10@a { reg = <0xa>; @@ -71,6 +72,9 @@ description: | }; }; + For the channel to be initially inverted after the driver's init, the flag 'inverted' can + be declared, as shown above for channel 9. + Note: The channel's 'reg' property defines the ID of the channel. It must match the channel used in the 'pinmux'. @@ -130,6 +134,14 @@ child-binding: For maximum flexibility, the high-speed as well as the low-speed channels can be driven from one of four high-speed/low-speed timers. + inverted: + type: boolean + description: | + Initial channel output level. + This flag defines if the channel will remain initially inverted after driver init, + as any pwm_set() operation will re-evaluate if the output is inverted or not + according to the flag passed as parameter. + pwm-cells: - channel - period diff --git a/dts/bindings/pwm/nxp,ftm-pwm.yaml b/dts/bindings/pwm/nxp,ftm-pwm.yaml new file mode 100644 index 0000000000000..a07fe5945feef --- /dev/null +++ b/dts/bindings/pwm/nxp,ftm-pwm.yaml @@ -0,0 +1,40 @@ +# Copyright 2017, 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP FlexTimer Module (FTM) PWM controller + +compatible: "nxp,ftm-pwm" + +include: [pwm-controller.yaml, "nxp,ftm.yaml", "pinctrl-device.yaml"] + +properties: + "#pwm-cells": + const: 3 + + pinctrl-0: + required: true + + clock-source: + type: string + required: true + enum: + - "system" + - "fixed" + - "external" + description: | + Select one of three possible clock sources for the FTM counter: + * system: it's the bus interface clock driving the FTM module. Usually + provides higher timer resolution than the other two clock sources. + * fixed: it's a fixed clock defined by chip integration. + * external: it's a clock that can be accessed externally to the chip and + passes through a sychronizer clocked by the FTM bus interface clock. + + This clock source selection is independent of the bus interface clock + driving the FTM module. Refer to the chip specific documentation for + further information. + +pwm-cells: + - channel + # period in terms of nanoseconds + - period + - flags diff --git a/dts/bindings/pwm/nxp,kinetis-ftm-pwm.yaml b/dts/bindings/pwm/nxp,kinetis-ftm-pwm.yaml deleted file mode 100644 index 48509b194f80a..0000000000000 --- a/dts/bindings/pwm/nxp,kinetis-ftm-pwm.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2017, 2024 NXP -# SPDX-License-Identifier: Apache-2.0 - -description: Kinetis FTM PWM - -compatible: "nxp,kinetis-ftm-pwm" - -include: [pwm-controller.yaml, "nxp,kinetis-ftm.yaml", "pinctrl-device.yaml"] - -properties: - "#pwm-cells": - const: 3 - - pinctrl-0: - required: true - - clock-source: - type: string - required: true - enum: - - "system" - - "fixed" - - "external" - description: | - Select one of three possible clock sources for the FTM counter: - * system: it's the bus interface clock driving the FTM module. Usually - provides higher timer resolution than the other two clock sources. - * fixed: it's a fixed clock defined by chip integration. - * external: it's a clock that can be accessed externally to the chip and - passes through a sychronizer clocked by the FTM bus interface clock. - - This clock source selection is independent of the bus interface clock - driving the FTM module. Refer to the chip specific documentation for - further information. - -pwm-cells: - - channel - # period in terms of nanoseconds - - period - - flags diff --git a/dts/bindings/pwm/nxp,s32-emios-pwm.yaml b/dts/bindings/pwm/nxp,s32-emios-pwm.yaml index 0b8a2ffc674ac..c8c4a64b27dc2 100644 --- a/dts/bindings/pwm/nxp,s32-emios-pwm.yaml +++ b/dts/bindings/pwm/nxp,s32-emios-pwm.yaml @@ -18,27 +18,20 @@ description: | channel = <0>; pwm-mode = "OPWFMB"; prescaler = <8>; - period = <65534>; - duty-cycle = <32768>; - polarity = "ACTIVE_HIGH"; }; pwm_1 { channel = <1>; master-bus = <&emios1_bus_a>; pwm-mode = "OPWMB"; - duty-cycle = <32768>; phase-shift = <100>; - polarity = "ACTIVE_LOW"; }; pwm_2 { channel = <2>; master-bus = <&emios1_bus_b>; pwm-mode = "OPWMCB_LEAD_EDGE"; - duty-cycle = <32768>; dead-time = <100>; - polarity = "ACTIVE_LOW"; }; pwm_3 { @@ -50,10 +43,8 @@ description: | }; OPWMB and OPWMCB modes use reference timebase, the master bus is chosen over - phandle 'master-bus'. For OPWMB mode, PWM's period is master bus's period and - is 2 * master bus's period - 2 for OPWMCB mode. Please notice that the devicetree - node for master bus should be enabled and configured for using, please see - 'nxp,s32-emios' bindings. + phandle 'master-bus'. Please notice that the devicetree node for master bus + should be enabled and configured for using, please see 'nxp,s32-emios' bindings. compatible: "nxp,s32-emios-pwm" @@ -124,25 +115,6 @@ child-binding: - "OPWMCB_LEAD_EDGE" - "SAIC" - polarity: - type: string - description: | - Output polarity for PWM channel. - enum: - - "ACTIVE_LOW" - - "ACTIVE_HIGH" - - duty-cycle: - type: int - description: | - Duty-cycle (in ticks) for PWM channel at boot time. - - period: - type: int - description: | - Period (in ticks) for OPWFMB at boot time. Period for the rest - of PWM mode depends on period's master bus. Must be in range [2 ... 65535]. - freeze: type: boolean description: Freeze individual internal counter when the chip enters Debug mode. diff --git a/dts/bindings/pwm/renesas,ra-pwm.yaml b/dts/bindings/pwm/renesas,ra-pwm.yaml new file mode 100644 index 0000000000000..7022d08d488d5 --- /dev/null +++ b/dts/bindings/pwm/renesas,ra-pwm.yaml @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA Pulse Width Modulation + +compatible: "renesas,ra-pwm" + +include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml] + +properties: + divider: + type: int + required: true + + channel: + type: int + required: true + + clocks: + required: true + + interrupts: + required: true + + interrupt-names: + required: true + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/pwm/renesas,ra8-pwm.yaml b/dts/bindings/pwm/renesas,ra8-pwm.yaml deleted file mode 100644 index 36790afa8ada5..0000000000000 --- a/dts/bindings/pwm/renesas,ra8-pwm.yaml +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2024 Renesas Electronics Corporation -# SPDX-License-Identifier: Apache-2.0 - -description: Renesas RA8 Pulse Width Modulation - -compatible: "renesas,ra8-pwm" - -include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml] - -properties: - divider: - type: int - required: true - - channel: - type: int - required: true - - clocks: - required: true - - interrupts: - required: true - - interrupt-names: - required: true - - "#pwm-cells": - const: 3 - -pwm-cells: - - channel - - period - - flags diff --git a/dts/bindings/pwm/renesas,rz-gpt-pwm.yaml b/dts/bindings/pwm/renesas,rz-gpt-pwm.yaml new file mode 100644 index 0000000000000..b89bdb0511e0e --- /dev/null +++ b/dts/bindings/pwm/renesas,rz-gpt-pwm.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ GPT PWM + +compatible: "renesas,rz-gpt-pwm" + +include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml] + +properties: + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/pwm/zephyr,fake-pwm.yaml b/dts/bindings/pwm/zephyr,fake-pwm.yaml new file mode 100644 index 0000000000000..042bade6bf592 --- /dev/null +++ b/dts/bindings/pwm/zephyr,fake-pwm.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Kickmaker +# SPDX-License-Identifier: Apache-2.0 + +description: | + This binding provides a fake PWM for use as either a stub or a mock in Zephyr + testing. + +compatible: "zephyr,fake-pwm" + +include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml] + +properties: + "#pwm-cells": + const: 2 + description: | + Number of items to expect in a PWM + - channel of the timer used for PWM + - period to set in ns + frequency: + type: int + description: | + Frequency for the underlying timer (in Hz) + +pwm-cells: + - channel + - period diff --git a/dts/bindings/qspi/nxp,s32-qspi-sfp-frad.yaml b/dts/bindings/qspi/nxp,s32-qspi-sfp-frad.yaml new file mode 100644 index 0000000000000..368fb7f88ca6b --- /dev/null +++ b/dts/bindings/qspi/nxp,s32-qspi-sfp-frad.yaml @@ -0,0 +1,53 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP S32 Quad Serial Peripheral Interface (QSPI) Secure Flash Protection SFP FRAD. + + The SFP FRAD performs second-level checks on input flash write and erase transactions, + based on the address range of each transaction. + +compatible: "nxp,s32-qspi-sfp-frad" + +child-binding: + + properties: + reg: + type: array + required: true + + master-domain-acp-policy: + type: int + required: true + description: | + Selects the master domain access control policy, defined in dt-bindings/qspi/nxp-s32-qspi.h: + - NXP_S32_QSPI_NON_SECURE: Selects the non-secure access control policy. + - NXP_S32_QSPI_SECURE: Selects the secure access control policy. + - NXP_S32_QSPI_PRIVILEGE: Selects the privilege access control policy. + Allowed combinations: + - NXP_S32_QSPI_SECURE + - NXP_S32_QSPI_SECURE | NXP_S32_QSPI_PRIVILEGE + - NXP_S32_QSPI_NON_SECURE | NXP_S32_QSPI_PRIVILEGE + - NXP_S32_QSPI_NON_SECURE | NXP_S32_QSPI_SECURE | NXP_S32_QSPI_PRIVILEGE + + exclusive-access-lock: + type: string + enum: + - DISABLED + - OWNER + - NONE + default: DISABLED + description: | + Selects the exclusive access lock: + - DISABLED: The exclusive access lock disabled, granting write permissions for all masters + - ENABLED: The exclusive access lock enabled, granting write permissions only to the + exclusive access owner master and disabling write permissions for other masters. + - NONE: This configuration should not be used + The default corresponds to the reset value of the register field. + + exclusive-access-owner: + type: int + default: 0 + description: | + The domain master ID that owns the exclusive access lock. + Valid range: 0 - 63. The default corresponds to the reset + value of the register field. diff --git a/dts/bindings/qspi/nxp,s32-qspi-sfp-mdad.yaml b/dts/bindings/qspi/nxp,s32-qspi-sfp-mdad.yaml new file mode 100644 index 0000000000000..7a40f0f3cb60b --- /dev/null +++ b/dts/bindings/qspi/nxp,s32-qspi-sfp-mdad.yaml @@ -0,0 +1,51 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP S32 Quad Serial Peripheral Interface (QSPI) Secure Flash Protection SFP MDAD. + + The SFP MDAD performs first-level checks on input transactions, based on the secure attribute + and MGID associated with each transaction. + +compatible: "nxp,s32-qspi-sfp-mdad" + +child-binding: + + properties: + secure-attribute: + type: int + required: true + description: | + Selects the secure attribute, defined in dt-bindings/qspi/nxp-s32-qspi.h: + - NXP_S32_QSPI_NON_SECURE: Allow the bus attribute for this master to non-secure + - NXP_S32_QSPI_SECURE: Allow the bus attribute for this master to secure + Allowed combinations: + - NXP_S32_QSPI_NON_SECURE + - NXP_S32_QSPI_SECURE + - NXP_S32_QSPI_NON_SECURE | NXP_S32_QSPI_SECURE + + mask-type: + type: string + enum: + - AND + - OR + default: AND + description: | + Selects the mask type: + - AND: AND-ed mask + - OR: OR-ed mask + The default corresponds to the reset value of the register field. + + mask: + type: int + default: 0 + description: | + Defines the mask value for the ID-Match comparison. + Valid range: 0 - 63. The default corresponds to the + reset value of the register field. + + domain-id: + type: int + required: true + description: | + Domain ID Reference value of the Domain-ID (MID) for MID-comparison. + Valid range: 0 - 63. diff --git a/dts/bindings/regulator/nordic,npm1300-regulator.yaml b/dts/bindings/regulator/nordic,npm1300-regulator.yaml index cdb0999b23a96..2f514b686fc50 100644 --- a/dts/bindings/regulator/nordic,npm1300-regulator.yaml +++ b/dts/bindings/regulator/nordic,npm1300-regulator.yaml @@ -96,3 +96,12 @@ child-binding: - 50000 description: | Soft start current limit in microamps. + + nordic,ldo-disable-workaround: + type: boolean + description: | + Disable the SW workaround for LDO bug. + When nPM1300 is in ULP mode, LDO is supplied from VSYS and + then LDO is enabled, it can take long time until the LDO + output has reached its target voltage. To avoid this, an i2c + read is performed shortly after an LDO is enabled. diff --git a/dts/bindings/regulator/nxp,pf1550-regulator.yaml b/dts/bindings/regulator/nxp,pf1550-regulator.yaml new file mode 100644 index 0000000000000..8964b1857ef89 --- /dev/null +++ b/dts/bindings/regulator/nxp,pf1550-regulator.yaml @@ -0,0 +1,54 @@ +# Copyright (c), 2024 Arduino SA +# SPDX-License-Identifier: Apache-2.0 + +description: | + NXP PF1550 PMIC + + The PMIC has two buck converters and three LDOs. All need to be defined as + children nodes, strictly following the BUCK1..3, LDO1..3 node names. For + example: + + pmic@8 { + reg = <0x8>; + ... + regulators { + compatible = nxp,pf1550-regulator"; + + BUCK1 { + /* all properties for BUCK1 */ + }; + BUCK2 { + /* all properties for BUCK2 */ + }; + BUCK3 { + /* all properties for BUCK3 */ + }; + LDO1 { + /* all properties for LDO1 */ + }; + LDO2 { + /* all properties for LDO2 */ + }; + LDO3 { + /* all properties for LDO3 */ + }; + }; + }; + +compatible: "nxp,pf1550-regulator" + +include: base.yaml + +child-binding: + include: + - name: regulator.yaml + property-allowlist: + - regulator-init-microvolt + - regulator-min-microvolt + - regulator-max-microvolt + - regulator-init-microamp + - regulator-max-microamp + - regulator-always-on + - regulator-boot-on + - regulator-initial-mode + - regulator-allowed-modes diff --git a/dts/bindings/rng/nordic,nrf-cracen-ctrdrbg.yaml b/dts/bindings/rng/nordic,nrf-cracen-ctrdrbg.yaml new file mode 100644 index 0000000000000..820178b975acc --- /dev/null +++ b/dts/bindings/rng/nordic,nrf-cracen-ctrdrbg.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2025, Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic nRF CRACEN CTR_DRBG based (Random Number Generator) + + This driver is only compatible with 54L devices, and may only be used from one processor + core. This driver cannot be used in conjunction with the nRF security PSA solution, as both + would attempt to use the CRACEN HW exclusively; When that is enabled, zephyr,psa-crypto-rng + should be selected instead. + +compatible: "nordic,nrf-cracen-ctrdrbg" + +include: base.yaml diff --git a/dts/bindings/rng/nxp,ele-trng.yaml b/dts/bindings/rng/nxp,ele-trng.yaml new file mode 100644 index 0000000000000..c501461da760f --- /dev/null +++ b/dts/bindings/rng/nxp,ele-trng.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025, NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP ELE (EdgeLock secure enclave) TRNG (True Random Number Generator) + +compatible: "nxp,ele-trng" + +include: base.yaml diff --git a/dts/bindings/rng/renesas,ra-sce5-rng.yaml b/dts/bindings/rng/renesas,ra-sce5-rng.yaml new file mode 100644 index 0000000000000..f34853cef346b --- /dev/null +++ b/dts/bindings/rng/renesas,ra-sce5-rng.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA SCE5 TRNG + +compatible: "renesas,ra-sce5-rng" + +include: base.yaml diff --git a/dts/bindings/rng/renesas,ra-sce7-rng.yaml b/dts/bindings/rng/renesas,ra-sce7-rng.yaml new file mode 100644 index 0000000000000..0de6b629e481c --- /dev/null +++ b/dts/bindings/rng/renesas,ra-sce7-rng.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA SCE7 TRNG + +compatible: "renesas,ra-sce7-rng" + +include: base.yaml diff --git a/dts/bindings/rng/renesas,ra-sce9-rng.yaml b/dts/bindings/rng/renesas,ra-sce9-rng.yaml new file mode 100644 index 0000000000000..652ffbf8319ce --- /dev/null +++ b/dts/bindings/rng/renesas,ra-sce9-rng.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA SCE9 TRNG + +compatible: "renesas,ra-sce9-rng" + +include: base.yaml diff --git a/dts/bindings/rng/renesas,ra-trng.yaml b/dts/bindings/rng/renesas,ra-trng.yaml new file mode 100644 index 0000000000000..326624fe489f4 --- /dev/null +++ b/dts/bindings/rng/renesas,ra-trng.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA TRNG + +compatible: "renesas,ra-trng" + +include: base.yaml diff --git a/dts/bindings/rng/sensry,sy1xx-trng.yaml b/dts/bindings/rng/sensry,sy1xx-trng.yaml new file mode 100644 index 0000000000000..e25e0781de602 --- /dev/null +++ b/dts/bindings/rng/sensry,sy1xx-trng.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2025 sensry.io +# SPDX-License-Identifier: Apache-2.0 + +description: Sensry SY1XX TRNG node + +compatible: "sensry,sy1xx-trng" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/rng/silabs,siwx91x-rng.yaml b/dts/bindings/rng/silabs,siwx91x-rng.yaml new file mode 100644 index 0000000000000..8174a76b91292 --- /dev/null +++ b/dts/bindings/rng/silabs,siwx91x-rng.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Hardware Random Number Generator embedded on Silabs SiWx91x chips + +compatible: "silabs,siwx91x-rng" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/rng/st,stm32-rng-noirq.yaml b/dts/bindings/rng/st,stm32-rng-noirq.yaml new file mode 100644 index 0000000000000..d0cfe9622fb2e --- /dev/null +++ b/dts/bindings/rng/st,stm32-rng-noirq.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: STM32 Random Number Generator without interrupt line + +compatible: "st,stm32-rng-noirq" + +include: + - name: st,stm32-rng.yaml + property-blocklist: + - interrupts + +properties: + generation-delay-ns: + type: int + description: | + Delay between the generation of two random samples, in nanoseconds. diff --git a/dts/bindings/rtc/atmel,sam0-rtc.yaml b/dts/bindings/rtc/atmel,sam0-rtc.yaml index f2210e8bfb4e0..db3ed230884f4 100644 --- a/dts/bindings/rtc/atmel,sam0-rtc.yaml +++ b/dts/bindings/rtc/atmel,sam0-rtc.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2018 omSquare s.r.o. +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 RTC @@ -6,14 +7,124 @@ description: Atmel SAM0 RTC compatible: "atmel,sam0-rtc" include: - - name: rtc.yaml + - name: rtc-device.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: required: true - clock-generator: + clocks: + required: true + + clock-names: + required: true + + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + + systimer: + type: boolean + description: | + Selects RTC peripheral to be used as a system timer and replace + the ARM systick. When this option is selected the normal RTC + functionality is in exclusive mode and the normal RTC functions + will not be available. + + The systimer exclusive functionality can be enabled using the + following devicetree entry: + + &rtc { + status = "okay"; + systimer; + }; + + cal-constant: type: int - description: clock generator index required: true + description: | + Define the constant used to calculate the calibration. More + information can be found in the datasheet of each SoC series + at RTC Frequency Correction topic. + + Example: + Correction in ppm = (FREQCORR.VALUE * 1e6 ppm) / (8192 * 128) + + &rtc { + cal-constant = <8192 * 128>; + }; + + counter-mode: + type: string + enum: + - "count-32" + - "count-16" + - "clock" + description: | + Configure the RTC counter operating mode. In mode 0, the counter + register is configured as a 32-bit counter. In mode 1, simmilar + to mode 0, the counter register is only 16-bit counter. In mode + 2 the counter register is configured as a clock/calendar. + + &rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; + }; + + prescaler: + type: int + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + - 256 + - 512 + - 1024 + description: | + Enable CLKOUT at given frequency. When disabled, CLKOUT pin is LOW. + The default is 0 and corresponds to the disable the CLKOUT signal. + + &rtc { + status = "okay"; + counter-mode = "clock"; + prescaler = <1024>; + }; + + event-control-msk: + type: int + default: 0 + description: | + Enable peripheral event sources by bitmask. By default all the channels + are always disabled. + + Event Table: + + bit Event Source + 0 Periodic Interval 0 Event Output + 1 Periodic Interval 1 Event Output + 2 Periodic Interval 2 Event Output + 3 Periodic Interval 3 Event Output + 4 Periodic Interval 4 Event Output + 5 Periodic Interval 5 Event Output + 6 Periodic Interval 6 Event Output + 7 Periodic Interval 7 Event Output + 8 Compare/Alarm 0 Event Output + 9 Compare/Alarm 1 Event Output + 14 Tamper Event Output + 15 Overflow Event Output + 16 Tamper Event Input + + Example how to enable Compare/Alarm 0 Event Output: + &rtc { + event-control-msk = <100>; + }; diff --git a/dts/bindings/rtc/epson,rx8130ce.yaml b/dts/bindings/rtc/epson,rx8130ce.yaml new file mode 100644 index 0000000000000..04ba528265014 --- /dev/null +++ b/dts/bindings/rtc/epson,rx8130ce.yaml @@ -0,0 +1,32 @@ +# Copyright (c) 2025 Måns Ansgariusson +# SPDX-License-Identifier: Apache-2.0 + +description: RX8130CE RTC + +compatible: "epson,rx8130ce-rtc" +include: [i2c-device.yaml, rtc-device.yaml] + +properties: + irq-gpios: + type: phandle-array + + clockout-frequency: + type: int + description: | + Specify the ociillator frequency in Hz, if not specified the clockout will be disabled. + - 1 # 1 Hz oscillator + - 1024 # 1 kHz oscillator + - 32768 # 32 kHz oscillator + enum: [1, 1024, 32768] + + battery-switchover: + type: int + description: | + Enable the battery backup feature and specify the switchover mode. + If not specified the battery backup feature will be disabled. + + - 1 # Non-rechargeable battery backup i2c & FOUT are disabled when VDD is below Vdet1 + - 2 # Non-rechargeable battery backup i2c & FOUT are always on + - 3 # Rechargeable battery backup i2c & FOUT are disabled when VDD is below Vdet1 + - 4 # Rechargeable battery backup i2c & FOUT are always on + enum: [1, 2, 3, 4] diff --git a/dts/bindings/rtc/maxim,ds1307.yaml b/dts/bindings/rtc/maxim,ds1307.yaml index fc81e803cb4d7..25815a2262aea 100644 --- a/dts/bindings/rtc/maxim,ds1307.yaml +++ b/dts/bindings/rtc/maxim,ds1307.yaml @@ -1,6 +1,9 @@ # SPDX-License-Identifier: Apache-2.0 +# # Copyright (c) 2023 Arunmani Alagarsamy # Author: Arunmani Alagarsamy +# +# Copyright (c) 2025 Marcin Lyda description: Maxim DS1307 RTC @@ -9,3 +12,16 @@ compatible: "maxim,ds1307" include: - name: rtc-device.yaml - name: i2c-device.yaml + +properties: + sqw-frequency: + type: int + description: | + SQW frequency value [Hz] + This field enables to select output frequency on + SQW pin. + enum: + - 1 + - 4096 + - 8192 + - 32768 diff --git a/dts/bindings/rtc/maxim,ds1337.yaml b/dts/bindings/rtc/maxim,ds1337.yaml new file mode 100644 index 0000000000000..ac874fed276b7 --- /dev/null +++ b/dts/bindings/rtc/maxim,ds1337.yaml @@ -0,0 +1,30 @@ +# Copyright (c) 2025 Marcin Lyda +# SPDX-License-Identifier: Apache-2.0 + +description: Maxim DS1337 RTC + +compatible: "maxim,ds1337" + +include: + - name: rtc-device.yaml + - name: i2c-device.yaml + +properties: + int-gpios: + type: phandle-array + description: | + INTA interrupt output + GPIO pin to handle chip's INTA interrupt output, + used to notify about alarm events. + + sqw-frequency: + type: int + description: | + SQW/INTB frequency value [Hz] + This field enables to select output frequency at + SQW/INTB pin. + enum: + - 1 + - 4096 + - 8192 + - 32768 diff --git a/dts/bindings/rtc/maxim,ds3231-rtc.yaml b/dts/bindings/rtc/maxim,ds3231-rtc.yaml new file mode 100644 index 0000000000000..81a9cae26246d --- /dev/null +++ b/dts/bindings/rtc/maxim,ds3231-rtc.yaml @@ -0,0 +1,35 @@ +# +# Copyright (c) 2024 Gergo Vari +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Maxim DS3231 I2C RTC/TCXO + +compatible: "maxim,ds3231-rtc" + +include: [rtc-device.yaml] + +properties: + freq-32khz-gpios: + type: phandle-array + description: | + + 32 KiHz open drain output + + The DS3231 defaults to providing a 32 KiHz square wave on this + signal. The driver does not make use of this, but applications + may want access. + + isw-gpios: + type: phandle-array + description: | + + interrupt/square wave open drain output + + The DS3231 uses this signal to notify when an alarm has triggered, + and also to produce a square wave aligned to the countdown chain. + Both capabilities are used within the driver. + + This signal must be present to support time set + and read operations that preserve sub-second accuracy. diff --git a/dts/bindings/rtc/microcrystal,rv8803.yaml b/dts/bindings/rtc/microcrystal,rv8803.yaml new file mode 100644 index 0000000000000..06bf6923cd6ca --- /dev/null +++ b/dts/bindings/rtc/microcrystal,rv8803.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Marcin Lyda +# SPDX-License-Identifier: Apache-2.0 + +description: Micro Crystal RV8803 Extreme Low Power Real-Time Clock Module + +compatible: "microcrystal,rv8803" + +include: + - name: rtc-device.yaml + - name: i2c-device.yaml + +properties: + reg: + required: true + + int-gpios: + type: phandle-array + description: | + Interrupt output + Interrupt output used by the chip to notify various + events, such as alarm event, update event, external + events etc. + + clkout-frequency: + type: int + description: | + CLKOUT value [Hz] + This field enables to select output frequency on + CLKOUT pin. + enum: + - 1 + - 1024 + - 32768 diff --git a/dts/bindings/rtc/nxp,kinetis-rtc.yaml b/dts/bindings/rtc/nxp,kinetis-rtc.yaml deleted file mode 100644 index 9bcf5aa544d46..0000000000000 --- a/dts/bindings/rtc/nxp,kinetis-rtc.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2018, blik GmbH -# Copyright 2024 NXP -# SPDX-License-Identifier: Apache-2.0 - -description: Kinetis RTC - -compatible: "nxp,kinetis-rtc" - -include: rtc.yaml - -properties: - reg: - required: true - - clock-source: - type: string - default: "RTC" - enum: - - "RTC" - - "LPO" - description: | - Select one of two possible clock sources for the RTC: - * RTC: RTC prescaler increments using RTC clock. - * LPO: RTC prescaler increments using 1 kHz LPO. - The default corresponds to the reset value of the register field, - and there is no additional code configuration in the driver. diff --git a/dts/bindings/rtc/nxp,rtc.yaml b/dts/bindings/rtc/nxp,rtc.yaml new file mode 100644 index 0000000000000..f30bb0a468524 --- /dev/null +++ b/dts/bindings/rtc/nxp,rtc.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2018, blik GmbH +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP Real Time Clock (RTC) + +compatible: "nxp,rtc" + +include: rtc.yaml + +properties: + reg: + required: true + + clock-source: + type: string + default: "RTC" + enum: + - "RTC" + - "LPO" + description: | + Select one of two possible clock sources for the RTC: + * RTC: RTC prescaler increments using RTC clock. + * LPO: RTC prescaler increments using 1 kHz LPO. + The default corresponds to the reset value of the register field, + and there is no additional code configuration in the driver. diff --git a/dts/bindings/rtc/ti,bq32002.yaml b/dts/bindings/rtc/ti,bq32002.yaml new file mode 100644 index 0000000000000..ea55c59995ef7 --- /dev/null +++ b/dts/bindings/rtc/ti,bq32002.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2025 Marcin Lyda +# SPDX-License-Identifier: Apache-2.0 + +description: Texas Instruments BQ32002 Real-Time Clock + +compatible: "ti,bq32002" + +include: + - name: rtc-device.yaml + - name: i2c-device.yaml + +properties: + irq-frequency: + type: int + description: | + IRQ pin frequency + + This field enables to select output frequency on IRQ pin. + 1Hz frequency is periodically corrected by the configured calibration value, + while the 512Hz frequency is derived directly from the oscillator. + + enum: + - 1 + - 512 diff --git a/dts/bindings/sdhc/adi,max32-sdhc.yaml b/dts/bindings/sdhc/adi,max32-sdhc.yaml new file mode 100644 index 0000000000000..86d0e99d5cc73 --- /dev/null +++ b/dts/bindings/sdhc/adi,max32-sdhc.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: ADI MAX32 SDHC + +compatible: "adi,max32-sdhc" + +include: [sdhc.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true diff --git a/dts/bindings/sdhc/cdns,sdhc.yaml b/dts/bindings/sdhc/cdns,sdhc.yaml index 536b9c4bd58a4..5d3af2f4cd119 100644 --- a/dts/bindings/sdhc/cdns,sdhc.yaml +++ b/dts/bindings/sdhc/cdns,sdhc.yaml @@ -14,7 +14,7 @@ properties: reg: required: true description: register space - power_delay_ms: + power-delay-ms: type: int required: true description: delay required to switch on the SDHC diff --git a/dts/bindings/sdhc/nxp,imx-usdhc.yaml b/dts/bindings/sdhc/nxp,imx-usdhc.yaml index bccdf51d72306..4e217d0c7dbbe 100644 --- a/dts/bindings/sdhc/nxp,imx-usdhc.yaml +++ b/dts/bindings/sdhc/nxp,imx-usdhc.yaml @@ -29,7 +29,7 @@ properties: description: | Number of words used as write watermark level in FIFO queue for USDHC - max_current_330: + max-current-330: type: int default: 0 description: | diff --git a/dts/bindings/sdhc/renesas,ra-sdhc.yaml b/dts/bindings/sdhc/renesas,ra-sdhc.yaml new file mode 100644 index 0000000000000..92d6fe75ec996 --- /dev/null +++ b/dts/bindings/sdhc/renesas,ra-sdhc.yaml @@ -0,0 +1,54 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA SDHC + +compatible: "renesas,ra-sdhc" + + +include: [sdhc.yaml, pinctrl-device.yaml] + +properties: + channel: + type: int + required: true + + bus-width: + type: int + enum: + - 1 + - 4 + default: 4 + + sd-support: + type: boolean + + mmc-support: + type: boolean + + card-detect: + type: boolean + + write-protect: + type: boolean + + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + enable-gpios: + type: phandle-array + description: | + GPIO to use to enable/disable the SDHI. This GPIO is driven active when + the SDHI is enabled and inactive when the SDHI is disabled + + interrupts: + required: true + + interrupt-names: + required: true diff --git a/dts/bindings/sensor/adi,adxl345-i2c.yaml b/dts/bindings/sensor/adi,adxl345-i2c.yaml index e0a608327101c..0384924b7a56e 100644 --- a/dts/bindings/sensor/adi,adxl345-i2c.yaml +++ b/dts/bindings/sensor/adi,adxl345-i2c.yaml @@ -5,4 +5,4 @@ description: ADXL345 3-axis I2C accelerometer compatible: "adi,adxl345" -include: [sensor-device.yaml, i2c-device.yaml] +include: ["i2c-device.yaml", "adi,adxl345-common.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42370p-i2c.yaml b/dts/bindings/sensor/invensense,icm42370p-i2c.yaml new file mode 100644 index 0000000000000..6ae7b24ce50af --- /dev/null +++ b/dts/bindings/sensor/invensense,icm42370p-i2c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +description: ICM-42370-P motion tracking device + +compatible: "invensense,icm42370p" + +include: [i2c-device.yaml, "invensense,icm42x70.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42370p-spi.yaml b/dts/bindings/sensor/invensense,icm42370p-spi.yaml new file mode 100644 index 0000000000000..4f7b0ddc13461 --- /dev/null +++ b/dts/bindings/sensor/invensense,icm42370p-spi.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2022 Esco Medical ApS +# Copyright (c) 2020 TDK Invensense +# SPDX-License-Identifier: Apache-2.0 + +description: ICM-42370-P motion tracking device + +compatible: "invensense,icm42370p" + +include: [spi-device.yaml, "invensense,icm42x70.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42670-i2c.yaml b/dts/bindings/sensor/invensense,icm42670-i2c.yaml deleted file mode 100644 index 37311b44db43a..0000000000000 --- a/dts/bindings/sensor/invensense,icm42670-i2c.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. -# SPDX-License-Identifier: Apache-2.0 - -description: ICM-42670 motion tracking device - -compatible: "invensense,icm42670" - -include: [i2c-device.yaml, "invensense,icm42670.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42670-spi.yaml b/dts/bindings/sensor/invensense,icm42670-spi.yaml deleted file mode 100644 index 069a78eae1f8b..0000000000000 --- a/dts/bindings/sensor/invensense,icm42670-spi.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2022 Esco Medical ApS -# Copyright (c) 2020 TDK Invensense -# SPDX-License-Identifier: Apache-2.0 - -description: ICM-42670 motion tracking device - -compatible: "invensense,icm42670" - -include: [spi-device.yaml, "invensense,icm42670.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42670.yaml b/dts/bindings/sensor/invensense,icm42670.yaml index 39fb582e708ed..01654f1f6f867 100644 --- a/dts/bindings/sensor/invensense,icm42670.yaml +++ b/dts/bindings/sensor/invensense,icm42670.yaml @@ -1,39 +1,13 @@ +# Copyright (c) 2024 TDK Invensense # Copyright (c) 2022 Esco Medical ApS # Copyright (c) 2020 TDK Invensense # SPDX-License-Identifier: Apache-2.0 description: ICM-42670 motion tracking device -include: [sensor-device.yaml] +include: invensense,icm42x70.yaml properties: - int-gpios: - type: phandle-array - description: | - The INT signal default configuration is active-high. The - property value should ensure the flags properly describe the - signal that is presented to the driver. - - accel-hz: - type: int - required: true - description: | - Default frequency of accelerometer. (Unit - Hz) - Maps to ACCEL_ODR field in ACCEL_CONFIG0 setting - Power-on reset value is 800. - enum: - - 1 - - 3 - - 6 - - 12 - - 25 - - 50 - - 100 - - 200 - - 400 - - 800 - - 1600 - gyro-hz: type: int required: true @@ -42,27 +16,15 @@ properties: Maps to GYRO_ODR field in GYRO_CONFIG0 setting Power-on reset value is 800. enum: - - 12 - - 25 - - 50 - - 100 - - 200 - - 400 - - 800 + - 0 - 1600 - - accel-fs: - type: int - required: true - description: | - Default full scale of accelerometer. (Unit - g) - Maps to ACCEL_FS_SEL field in ACCEL_CONFIG0 setting - Power-on reset value is 16 - enum: - - 16 - - 8 - - 4 - - 2 + - 800 + - 400 + - 200 + - 100 + - 50 + - 25 + - 12 gyro-fs: type: int @@ -76,3 +38,20 @@ properties: - 1000 - 500 - 250 + + gyro-filt-bw-hz: + type: int + default: 180 + description: | + Gyroscope low pass filter bandwidth frequency (Unit - Hz). + Maps to GYRO_UI_FILT_BW field in GYRO_CONFIG1 setting. + The default corresponds to the reset value of the register field. + enum: + - 0 + - 180 + - 121 + - 73 + - 53 + - 34 + - 25 + - 16 diff --git a/dts/bindings/sensor/invensense,icm42670p-i2c.yaml b/dts/bindings/sensor/invensense,icm42670p-i2c.yaml new file mode 100644 index 0000000000000..8a0f2e86b50cf --- /dev/null +++ b/dts/bindings/sensor/invensense,icm42670p-i2c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +description: ICM-42670-P motion tracking device + +compatible: "invensense,icm42670p" + +include: [i2c-device.yaml, "invensense,icm42670.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42670p-spi.yaml b/dts/bindings/sensor/invensense,icm42670p-spi.yaml new file mode 100644 index 0000000000000..69ea42822f899 --- /dev/null +++ b/dts/bindings/sensor/invensense,icm42670p-spi.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2022 Esco Medical ApS +# Copyright (c) 2020 TDK Invensense +# SPDX-License-Identifier: Apache-2.0 + +description: ICM-42670-P motion tracking device + +compatible: "invensense,icm42670p" + +include: [spi-device.yaml, "invensense,icm42670.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42670s-i2c.yaml b/dts/bindings/sensor/invensense,icm42670s-i2c.yaml new file mode 100644 index 0000000000000..e2ff832d68e7e --- /dev/null +++ b/dts/bindings/sensor/invensense,icm42670s-i2c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +description: ICM-42670-S motion tracking device + +compatible: "invensense,icm42670s" + +include: [i2c-device.yaml, "invensense,icm42670.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42670s-spi.yaml b/dts/bindings/sensor/invensense,icm42670s-spi.yaml new file mode 100644 index 0000000000000..5df9d9157e25b --- /dev/null +++ b/dts/bindings/sensor/invensense,icm42670s-spi.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2022 Esco Medical ApS +# Copyright (c) 2020 TDK Invensense +# SPDX-License-Identifier: Apache-2.0 + +description: ICM-42670-S motion tracking device + +compatible: "invensense,icm42670s" + +include: [spi-device.yaml, "invensense,icm42670.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42688.yaml b/dts/bindings/sensor/invensense,icm42688.yaml index c3c628e959720..4cf0277aa9fe1 100644 --- a/dts/bindings/sensor/invensense,icm42688.yaml +++ b/dts/bindings/sensor/invensense,icm42688.yaml @@ -15,12 +15,12 @@ description: | icm42688: icm42688@0 { ... - accel-pwr-mode = ; - accel-fs = ; - accel-odr = ; - gyro-pwr-mode= ; - gyro-fs = ; - gyro-odr = ; + accel-pwr-mode = ; + accel-fs = ; + accel-odr = ; + gyro-pwr-mode= ; + gyro-fs = ; + gyro-odr = ; }; compatible: "invensense,icm42688" include: [sensor-device.yaml, spi-device.yaml] diff --git a/dts/bindings/sensor/invensense,icm42x70.yaml b/dts/bindings/sensor/invensense,icm42x70.yaml new file mode 100644 index 0000000000000..169b514596534 --- /dev/null +++ b/dts/bindings/sensor/invensense,icm42x70.yaml @@ -0,0 +1,114 @@ +# Copyright (c) 2024 TDK Invensense +# Copyright (c) 2022 Esco Medical ApS +# Copyright (c) 2020 TDK Invensense +# SPDX-License-Identifier: Apache-2.0 + +description: ICM-42670 motion tracking device + +include: sensor-device.yaml + +properties: + int-gpios: + type: phandle-array + description: | + The INT signal default configuration is active-high. The + property value should ensure the flags properly describe the + signal that is presented to the driver. + + accel-hz: + type: int + required: true + description: | + Default frequency of accelerometer. (Unit - Hz) + Maps to ACCEL_ODR field in ACCEL_CONFIG0 setting + Power-on reset value is 800. + enum: + - 0 + - 1600 + - 800 + - 400 + - 200 + - 100 + - 50 + - 25 + - 12 + - 6 + - 3 + - 1 + + power-mode: + type: string + default: "low-noise" + description: | + Power mode. + Low power mode is allowed for accelerometer sensor only from + 1.5625Hz to 400Hz. + The default is chosen to support both accelerometer and + gyroscope sensors. + enum: + - "low-noise" + - "low-power" + + accel-fs: + type: int + required: true + description: | + Default full scale of accelerometer. (Unit - g) + Maps to ACCEL_FS_SEL field in ACCEL_CONFIG0 setting + Power-on reset value is 16 + enum: + - 16 + - 8 + - 4 + - 2 + + accel-avg: + type: int + default: 32 + description: | + Averaging filter setting to create accelerometer output + in accelerometer low power mode. + Maps to ACCEL_UI_AVG field in ACCEL_CONFIG1 setting. + The default corresponds to the reset value of the register field. + enum: + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + + accel-filt-bw-hz: + type: int + default: 180 + description: | + Accelerometer low pass filter bandwidth frequency (Unit - Hz). + Maps to ACCEL_UI_FILT_BW field in ACCEL_CONFIG1 setting. + The default corresponds to the reset value of the register field. + enum: + - 0 + - 180 + - 121 + - 73 + - 53 + - 34 + - 25 + - 16 + + apex: + type: string + default: "none" + description: | + APEX (Advanced Pedometer and Event Detection) features. It consists of: + * Pedometer: Tracks step count, and provide details such as the cadence and + the estimated activity type (Walk, Run, Unknown). + * Tilt Detection: Detects the Tilt when tilting the board with an angle of + 30 degrees or more held for 4 seconds. + * Wake on Motion (WoM): Detects motion per axis exceeding 195 mg threshold. + * Significant Motion Detector (SMD): Detects when the user has moved significantly. + enum: + - "none" + - "pedometer" + - "tilt" + - "smd" + - "wom" diff --git a/dts/bindings/sensor/invensense,icp10125.yaml b/dts/bindings/sensor/invensense,icp10125.yaml deleted file mode 100644 index 78fa69d785175..0000000000000 --- a/dts/bindings/sensor/invensense,icp10125.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2022, Mizuki Agawa -# SPDX-License-Identifier: Apache-2.0 - -description: ICP10125 barometric pressure/temperature sensor - -compatible: "invensense,icp10125" - -include: [sensor-device.yaml, i2c-device.yaml] - -properties: - temperature-measurement-mode: - type: string - required: true - description: Mode of ambient temperature measurement - enum: - - "low-power" - - "normal" - - "low-noise" - - "ultra-low-noise" - - pressure-measurement-mode: - type: string - required: true - description: Mode of barometric pressure measurement - enum: - - "low-power" - - "normal" - - "low-noise" - - "ultra-low-noise" diff --git a/dts/bindings/sensor/invensense,icp101xx.yaml b/dts/bindings/sensor/invensense,icp101xx.yaml new file mode 100644 index 0000000000000..c723187a792fb --- /dev/null +++ b/dts/bindings/sensor/invensense,icp101xx.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 TDK Invensense +# SPDX-License-Identifier: Apache-2.0 + +description: ICP101xx High Accuracy, Low Power, Barometric Pressure and Temperature Sensors IC + +compatible: "invensense,icp101xx" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + mode: + type: string + default: "normal" + description: Mode of pressure and temperature measurement + enum: + - "low-power" + - "normal" + - "low-noise" + - "ultra-low-noise" diff --git a/dts/bindings/sensor/maxim,ds3231-sensor.yaml b/dts/bindings/sensor/maxim,ds3231-sensor.yaml new file mode 100644 index 0000000000000..5d57d3e8fbb79 --- /dev/null +++ b/dts/bindings/sensor/maxim,ds3231-sensor.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Gergo Vari +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Maxim DS3231 I2C temperature sensor + +compatible: "maxim,ds3231-sensor" + +include: [sensor-device.yaml] diff --git a/dts/bindings/sensor/melexis,mlx90394.yaml b/dts/bindings/sensor/melexis,mlx90394.yaml new file mode 100644 index 0000000000000..367e43134043c --- /dev/null +++ b/dts/bindings/sensor/melexis,mlx90394.yaml @@ -0,0 +1,10 @@ +# Copyright (c) Florian Weber +# SPDX-License-Identifier: Apache-2.0 + +description: | + Melexis MLX90394 Magnetometer. See datasheet at + https://media.melexis.com/-/media/files/documents/datasheets/mlx90394-datasheet-melexis.pdf + +compatible: "melexis,mlx90394" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/dts/bindings/sensor/nordic,npm1300-charger.yaml b/dts/bindings/sensor/nordic,npm1300-charger.yaml index d28323bf133e5..fa5fe30ccd1b2 100644 --- a/dts/bindings/sensor/nordic,npm1300-charger.yaml +++ b/dts/bindings/sensor/nordic,npm1300-charger.yaml @@ -36,10 +36,12 @@ properties: dischg-limit-microamp: type: int required: true + enum: + - 200000 + - 1000000 description: | Discharge current limit in uA. - Available range is 270 mA to 1340 mA in 3.23 mA steps. - The value specified will be rounded down to the closest implemented value. + Available values are 200 mA and 1000 mA. vbus-limit-microamp: type: int diff --git a/dts/bindings/sensor/phosense,xbr818.yaml b/dts/bindings/sensor/phosense,xbr818.yaml new file mode 100644 index 0000000000000..9eeedba058472 --- /dev/null +++ b/dts/bindings/sensor/phosense,xbr818.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: | + Phosense XBR818 I2C-capable 10 GHz Radar Sensor + +compatible: "phosense,xbr818" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + int-gpios: + type: phandle-array + required: true + description: GPIO pin connected to IO pin (IO_VAL) + + i2c-en-gpios: + type: phandle-array + description: GPIO pin connected to I2C enable (I2C_EN) diff --git a/dts/bindings/sensor/renesas,hs400x.yaml b/dts/bindings/sensor/renesas,hs400x.yaml new file mode 100644 index 0000000000000..df44d79005794 --- /dev/null +++ b/dts/bindings/sensor/renesas,hs400x.yaml @@ -0,0 +1,10 @@ +# +# Copyright (c) 2024 Renesas Electronics Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas HS400x humidity and temperature sensor + +compatible: "renesas,hs400x" + +include: [sensor-device.yaml, i2c-device.yaml] diff --git a/dts/bindings/sensor/st,lis2duxs12-common.yaml b/dts/bindings/sensor/st,lis2duxs12-common.yaml new file mode 100644 index 0000000000000..0f428dbb482a0 --- /dev/null +++ b/dts/bindings/sensor/st,lis2duxs12-common.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + When setting the odr, power-mode, and range properties in a .dts or .dtsi file you may include + st_lis2dux12.h and use the macros defined there. + Example: + #include + lis2duxs12: lis2duxs12@0 { + ... + power-mode = ; + odr = ; + range = ; + }; + +# LIS2DUXS12 is a superset of LIS2DUX12 +include: st,lis2dux12-common.yaml diff --git a/dts/bindings/sensor/st,lis2duxs12-i2c.yaml b/dts/bindings/sensor/st,lis2duxs12-i2c.yaml new file mode 100644 index 0000000000000..43b9ae326912c --- /dev/null +++ b/dts/bindings/sensor/st,lis2duxs12-i2c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: STMicroelectronics LIS2DUXS12 3-axis accelerometer + +compatible: "st,lis2duxs12" + +include: ["i2c-device.yaml", "st,lis2duxs12-common.yaml"] diff --git a/dts/bindings/sensor/st,lis2duxs12-spi.yaml b/dts/bindings/sensor/st,lis2duxs12-spi.yaml new file mode 100644 index 0000000000000..11ab371dc3ff3 --- /dev/null +++ b/dts/bindings/sensor/st,lis2duxs12-spi.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LIS2DUXS12 3-axis accelerometer accessed through SPI bus + +compatible: "st,lis2duxs12" + +include: ["spi-device.yaml", "st,lis2duxs12-common.yaml"] diff --git a/dts/bindings/sensor/st,lsm6dsv16x-common.yaml b/dts/bindings/sensor/st,lsm6dsv16x-common.yaml index 8d8df50371091..9746012e31071 100644 --- a/dts/bindings/sensor/st,lsm6dsv16x-common.yaml +++ b/dts/bindings/sensor/st,lsm6dsv16x-common.yaml @@ -258,3 +258,41 @@ properties: - 0x3 # LSM6DSV16X_DT_TEMP_BATCHED_AT_60Hz enum: [0x00, 0x01, 0x02, 0x03] + + sflp-odr: + type: int + default: 0x3 + description: | + Specify the Sensor Fusion Low Power output data rate expressed in samples per second (Hz). + The values are taken in accordance to lsm6dsv16x_sflp_data_rate_t enumerative in hal/st + module. + Default is power-up configuration. + + - 0x0 # LSM6DSV16X_DT_SFLP_ODR_AT_15Hz + - 0x1 # LSM6DSV16X_DT_SFLP_ODR_AT_30Hz + - 0x2 # LSM6DSV16X_DT_SFLP_ODR_AT_60Hz + - 0x3 # LSM6DSV16X_DT_SFLP_ODR_AT_120Hz + - 0x4 # LSM6DSV16X_DT_SFLP_ODR_AT_240Hz + - 0x5 # LSM6DSV16X_DT_SFLP_ODR_AT_480Hz + + enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05] + + sflp-fifo-enable: + type: int + default: 0x0 + description: | + Specify what Sensor Fusion Low Power component has to be batched in FIFO. + The values are taken in accordance to lsm6dsv16x_fifo_sflp_raw_t enumerative in hal/st + module. + Default is power-up configuration. + + - 0x0 # LSM6DSV16X_DT_SFLP_FIFO_OFF + - 0x1 # LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION + - 0x2 # LSM6DSV16X_DT_SFLP_FIFO_GRAVITY + - 0x3 # LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY + - 0x4 # LSM6DSV16X_DT_SFLP_FIFO_GBIAS + - 0x5 # LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GBIAS + - 0x6 # LSM6DSV16X_DT_SFLP_FIFO_GRAVITY_GBIAS + - 0x7 # LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY_GBIAS + + enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07] diff --git a/dts/bindings/sensor/st,lsm6dsv16x-i3c.yaml b/dts/bindings/sensor/st,lsm6dsv16x-i3c.yaml new file mode 100644 index 0000000000000..416f4bd5ee862 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv16x-i3c.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSV16X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through I3C bus + +compatible: "st,lsm6dsv16x" + +include: ["i3c-device.yaml", "st,lsm6dsv16x-common.yaml"] + +properties: + int-en-i3c: + type: boolean + description: | + Enables INT pin when I3C is enabled + + bus-act-sel-us: + type: int + default: 50 + description: | + Bus available time for I3C IBI in microseconds + + enum: [50, 2, 1000, 25000] diff --git a/dts/bindings/sensor/st,stm32-vref.yaml b/dts/bindings/sensor/st,stm32-vref.yaml index 59d6d76070510..7a2987871a5b0 100644 --- a/dts/bindings/sensor/st,stm32-vref.yaml +++ b/dts/bindings/sensor/st,stm32-vref.yaml @@ -21,3 +21,18 @@ properties: description: | VDDA/VREF+ voltage in millivolts applied during manufacturing to determine the internal bandgap voltage reference VREFINT. + + vrefint-cal-resolution: + type: int + description: | + ADC resolution used for measuring calibration data + + This is usually equal to the ADC's native resolution. + + Most series have a 12-bit ADC, but 14-bit and 16-bit + also exists on e.g., STM32U5 and STM32H7 series. + default: 12 + enum: + - 12 + - 14 + - 16 diff --git a/dts/bindings/sensor/ti,hdc20xx.yaml b/dts/bindings/sensor/ti,hdc20xx.yaml index c9ffe9c9e085e..664c955bdd239 100644 --- a/dts/bindings/sensor/ti,hdc20xx.yaml +++ b/dts/bindings/sensor/ti,hdc20xx.yaml @@ -3,8 +3,6 @@ description: Texas Instruments HDC20XX Temperature and Humidity Sensor -compatible: "ti,hdc20xx" - include: [sensor-device.yaml, i2c-device.yaml] properties: diff --git a/dts/bindings/sensor/ti,tmag3001.yaml b/dts/bindings/sensor/ti,tmag3001.yaml new file mode 100644 index 0000000000000..0d0588662fb58 --- /dev/null +++ b/dts/bindings/sensor/ti,tmag3001.yaml @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 +description: | + TMAG3001 Low-Power 3D Linear and Angle Hall-Effect Sensor With I2C Interface + and Wake Up Detection in WCSP. + + See the specification for the default I2C address. + + The specification of the sensor can be found at: + https://www.ti.com/lit/ds/symlink/tmag3001.pdf + + Currently, this driver shares implementation with tmag5273. When setting the + enum properties in a .dts or .dtsi file you may include + `zephyr/dt-bindings/sensor/tmag5273.h` and use the macros defined there. + +compatible: "ti,tmag3001" + +include: ["ti,tmag5273.yaml"] diff --git a/dts/bindings/sensor/ti,tmag5273.yaml b/dts/bindings/sensor/ti,tmag5273.yaml index afe9576291073..76f5eefe8d0b8 100644 --- a/dts/bindings/sensor/ti,tmag5273.yaml +++ b/dts/bindings/sensor/ti,tmag5273.yaml @@ -8,7 +8,6 @@ description: | The specification of the sensor can be found at: https://www.ti.com/lit/ds/symlink/tmag5273.pdf - https://www.ti.com/lit/ds/symlink/tmag3001.pdf When setting the enum properties in a .dts or .dtsi file you may include tmag5273.h and use the macros defined there. diff --git a/dts/bindings/sensor/ti,tmp116.yaml b/dts/bindings/sensor/ti,tmp116.yaml index 338b259588554..a688829da41c6 100644 --- a/dts/bindings/sensor/ti,tmp116.yaml +++ b/dts/bindings/sensor/ti,tmp116.yaml @@ -13,10 +13,11 @@ properties: odr: type: int default: 0x200 + enum: [0, 0x80, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380] description: | Specify the default temperature output data rate in milliseconds (ms). Default is power-up configuration. - enum: + - 0 # TMP116_DT_ODR_15_5_MS - 0x80 # TMP116_DT_ODR_125_MS - 0x100 # TMP116_DT_ODR_250_MS @@ -25,3 +26,15 @@ properties: - 0x280 # TMP116_DT_ODR_4000_MS - 0x300 # TMP116_DT_ODR_8000_MS - 0x380 # TMP116_DT_ODR_16000_MS + oversampling: + type: int + default: 0x20 + enum: [0, 0x20, 0x40, 0x60] + description: | + Set number of sample to averaging in one readout. + Default is power-up configuration (8 samples). + + - 0 # TMP116_DT_OVERSAMPLING_1 + - 0x20 # TMP116_DT_OVERSAMPLING_8 + - 0x40 # TMP116_DT_OVERSAMPLING_32 + - 0x60 # TMP116_DT_OVERSAMPLING_64 diff --git a/dts/bindings/sensor/ti,tmp435.yaml b/dts/bindings/sensor/ti,tmp435.yaml new file mode 100644 index 0000000000000..5dc71b49f09c0 --- /dev/null +++ b/dts/bindings/sensor/ti,tmp435.yaml @@ -0,0 +1,36 @@ +# +# Copyright (c) 2024 Bittium Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Texas Instruments TMP435 temperature sensor + +compatible: "ti,tmp435" + +bus: tmp435 + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + external-channel: + description: External temperature measurement is enabled + type: boolean + resistance-correction: + description: | + Resistance correction feature for the external + temperature channel. If not enabled then conversion + is faster but with lower accuracy. + type: boolean + beta-compensation: + description: | + Beta Compensation Configuration, see Table 8 + from TMP435 data sheet, some common values. + 0x0f, Automatically selected range 7 (beta > 27.0) or + Automatically detected diode connected sensor + 0x07, Manually disabled beta correction + Default is common value for general purpose transistors. + type: int + default: 0x0f + enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] diff --git a/dts/bindings/sensor/we,wsen-pads-2511020213301-common.yaml b/dts/bindings/sensor/we,wsen-pads-2511020213301-common.yaml new file mode 100644 index 0000000000000..eb54b440c6393 --- /dev/null +++ b/dts/bindings/sensor/we,wsen-pads-2511020213301-common.yaml @@ -0,0 +1,59 @@ +# Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +include: sensor-device.yaml + +properties: + interrupt-gpios: + type: phandle-array + description: | + Interrupt pin. + Interrupt is active high by default. + + odr: + type: int + required: true + enum: + - 0 + - 1 + - 10 + - 25 + - 50 + - 75 + - 100 + - 200 + description: | + Sensor output data rate expressed in samples per second. + Data rates supported by the chip are 0 (power down), 1, + 10, 25, 50, 75, 100 and 200. + + configuration: + type: string + default: "Low_Power" + enum: + - "Low_Power" + - "Low_Noise" + description: | + Configuration of sensor to either be low power or low noise. + Maximum ODR in Low Noise configuration is 75Hz. + Defaults to Low_Power, which is the configuration at power-up. + + additional-low-pass-filter: + type: boolean + description: | + Enable or disable the addtional low pass filter of the sensor. + + additional-low-pass-filter-configuration: + type: int + default: 0 + enum: + - 0 + - 1 + description: | + Configuration of the addtional low pass filter of the sensor. + Defaults to 0, which is the configuration at power-up. + + threshold: + type: int + description: | + Threshold for the differential pressure interrupt in Pa. diff --git a/dts/bindings/sensor/we,wsen-pads-2511020213301-i2c.yaml b/dts/bindings/sensor/we,wsen-pads-2511020213301-i2c.yaml new file mode 100644 index 0000000000000..3490e3498a699 --- /dev/null +++ b/dts/bindings/sensor/we,wsen-pads-2511020213301-i2c.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +description: | + Würth Elektronik WSEN-PADS-2511020213301 absolute pressure sensor (I2C bus) + +compatible: "we,wsen-pads-2511020213301" + +include: ["i2c-device.yaml", "we,wsen-pads-2511020213301-common.yaml"] diff --git a/dts/bindings/sensor/we,wsen-pads-2511020213301-spi.yaml b/dts/bindings/sensor/we,wsen-pads-2511020213301-spi.yaml new file mode 100644 index 0000000000000..b821c32d5f8ca --- /dev/null +++ b/dts/bindings/sensor/we,wsen-pads-2511020213301-spi.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +description: | + Würth Elektronik WSEN-PADS-2511020213301 absolute pressure sensor (SPI bus) + +compatible: "we,wsen-pads-2511020213301" + +include: ["spi-device.yaml", "we,wsen-pads-2511020213301-common.yaml"] diff --git a/dts/bindings/sensor/we,wsen-pdus-25131308XXXXX.yaml b/dts/bindings/sensor/we,wsen-pdus-25131308XXXXX.yaml new file mode 100644 index 0000000000000..d6a12797bdb59 --- /dev/null +++ b/dts/bindings/sensor/we,wsen-pdus-25131308XXXXX.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Würth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +description: | + Würth Elektronik WSEN-PDUS-25131308XXXXX differential pressure sensor + +compatible: "we,wsen-pdus-25131308XXXXX" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + sensor-type: + type: int + required: true + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + description: | + PDUS sensor product variant (pressure measurement range). + 0 - order code 2513130810001, range = -0.1 to +0.1 kPa + 1 - order code 2513130810101 (5V VCC) + 2513130810102 (3.3V VCC), range = -1 to +1 kPa + 2 - order code 2513130810201, range = -10 to +10 kPa + 3 - order code 2513130810301, range = 0 to 100 kPa + 4 - order code 2513130810401 (5V VCC) + 2513130810402 (3.3V VCC), range = -100 to +1000 kPa + 5 - order code 2513130815401, range = 0 to +1500 kPa diff --git a/dts/bindings/sensor/we,wsen-tids-2521020222501.yaml b/dts/bindings/sensor/we,wsen-tids-2521020222501.yaml new file mode 100644 index 0000000000000..489c8ba3c767e --- /dev/null +++ b/dts/bindings/sensor/we,wsen-tids-2521020222501.yaml @@ -0,0 +1,42 @@ +# Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG +# SPDX-License-Identifier: Apache-2.0 + +description: | + Würth Elektronik WSEN-TIDS-2521020222501 temperature sensor + +compatible: "we,wsen-tids-2521020222501" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + interrupt-gpios: + type: phandle-array + description: Threshold interrupt pin. + Interrupt is active low by default. + + odr: + type: int + required: true + enum: + - 0 + - 25 + - 50 + - 100 + - 200 + description: | + Sensor output data rate expressed in samples per second. + Data rates supported by the chip are 0 (power down), 25, 50, 100 and 200. + + temp-high-threshold: + type: int + default: -40320 + description: | + Threshold for temperature high limit interrupt event in millidegree Celsius. + Defaults to -40320, which is the configuration at power-up. + + temp-low-threshold: + type: int + default: -40320 + description: | + Threshold for temperature low limit interrupt event in millidegree Celsius. + Defaults to -40320, which is the configuration at power-up. diff --git a/dts/bindings/serial/adi,max32-uart.yaml b/dts/bindings/serial/adi,max32-uart.yaml index c79543cf6b88e..07ebaffc80b03 100644 --- a/dts/bindings/serial/adi,max32-uart.yaml +++ b/dts/bindings/serial/adi,max32-uart.yaml @@ -34,3 +34,34 @@ properties: - 5: "ADI_MAX32_PRPH_CLK_SRC_INRO" Internal Ring Oscillator The target device might not support all option please take a look on target device user guide + + current-speed: + description: | + Initial baud rate setting for UART. Defaults to standard baudrate of 115200 if not specified. + default: 115200 + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 + + dmas: + description: | + DMA configuration used by asynchronous UART. Consists of a DMA instance, + channel number and a matching DMA slot. + + For example dmas for TX, RX on UART2 + dmas = <&dma0 1 MAX32_DMA_SLOT_UART2_TX>, <&dma0 2 MAX32_DMA_SLOT_UART2_RX>; + + dma-names: + description: | + Required if the dmas property exists. This should be "tx" and "rx" + to match the dmas property. + + For example + dma-names = "tx", "rx"; diff --git a/dts/bindings/serial/altr,uart.yaml b/dts/bindings/serial/altr,uart.yaml index 69c9ed1a94c0b..c009bedd88b77 100644 --- a/dts/bindings/serial/altr,uart.yaml +++ b/dts/bindings/serial/altr,uart.yaml @@ -13,6 +13,16 @@ properties: required: true description: Default baudrate of the uart controller. + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 + fixed-baudrate: type: boolean description: | diff --git a/dts/bindings/serial/arm,pl011.yaml b/dts/bindings/serial/arm,pl011.yaml index e823638ede049..6029b28fd4089 100644 --- a/dts/bindings/serial/arm,pl011.yaml +++ b/dts/bindings/serial/arm,pl011.yaml @@ -2,7 +2,7 @@ description: ARM PL011 UART compatible: "arm,pl011" -include: [uart-controller.yaml, pinctrl-device.yaml] +include: [uart-controller.yaml, pinctrl-device.yaml, reset-device.yaml] properties: reg: diff --git a/dts/bindings/serial/atmel,sam0-uart.yaml b/dts/bindings/serial/atmel,sam0-uart.yaml index f817137d7b69e..19dd2c35461a6 100644 --- a/dts/bindings/serial/atmel,sam0-uart.yaml +++ b/dts/bindings/serial/atmel,sam0-uart.yaml @@ -1,3 +1,6 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + description: Atmel SAM0 SERCOM UART driver compatible: "atmel,sam0-uart" @@ -5,6 +8,7 @@ compatible: "atmel,sam0-uart" include: - name: uart-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -19,6 +23,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + rxpo: type: int required: true diff --git a/dts/bindings/serial/espressif,esp32-uart.yaml b/dts/bindings/serial/espressif,esp32-uart.yaml index 49026309f34d3..f1f6abdfa3798 100644 --- a/dts/bindings/serial/espressif,esp32-uart.yaml +++ b/dts/bindings/serial/espressif,esp32-uart.yaml @@ -14,6 +14,16 @@ properties: pinctrl-names: required: true + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 + hw-rs485-hd-mode: type: boolean description: | diff --git a/dts/bindings/serial/infineon,cat1-uart.yaml b/dts/bindings/serial/infineon,cat1-uart.yaml index 2827e0b4e1a8d..32990ea68275f 100644 --- a/dts/bindings/serial/infineon,cat1-uart.yaml +++ b/dts/bindings/serial/infineon,cat1-uart.yaml @@ -39,3 +39,13 @@ properties: pinctrl-names: required: true + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 diff --git a/dts/bindings/serial/intel,lw_uart.yaml b/dts/bindings/serial/intel,lw_uart.yaml index 798dfa5322533..4687ebcfe4a24 100644 --- a/dts/bindings/serial/intel,lw_uart.yaml +++ b/dts/bindings/serial/intel,lw_uart.yaml @@ -17,3 +17,13 @@ properties: type: boolean description: | Baud rate cannot be changed by software (Divisor register is not writable) + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 diff --git a/dts/bindings/serial/microchip,mec5-uart.yaml b/dts/bindings/serial/microchip,mec5-uart.yaml new file mode 100644 index 0000000000000..d37c196d046bc --- /dev/null +++ b/dts/bindings/serial/microchip,mec5-uart.yaml @@ -0,0 +1,55 @@ +# Copyright (c) 2024 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip MEC5 UART + +compatible: "microchip,mec5-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + fifo-mode-disable: + type: boolean + description: | + Disable 16550 FIFO mode. Both 16-byte TX and RX FIFOs will be + disabled. UART will revert to a one byte holding register for + TX and RX. + + rx-fifo-trig: + type: string + default: "8" + description: | + RX FIFO byte count trigger limit. When the number of received bytes + reaches this level the UART will signal an interrupt if enabled. + enum: + - "1" + - "4" + - "8" + - "14" + + use-extclk: + type: boolean + description: | + Optional source of an external UART clock. If present the + driver will use this pin as the UART input clock source. + The pin should have a 1.8432 MHz clock waveform for normal + UART BAUD rates or 48 MHz for high speed BAUD rates. + Refer to data sheet for the pin(s) available as external UART + clock input. The pin should be added to the default PINCTRL list. + Example using external 1.8432MHz clock on MEC5 external UART clock pin. + + clock-frequency = <1843200>; + pinctrl-0 = < &uart1_tx_gpio170 &uart1_tx_gpio171 &uart_clk_gpio025>; + pinctrl-names = "default"; diff --git a/dts/bindings/serial/nordic,nrf-uart-common.yaml b/dts/bindings/serial/nordic,nrf-uart-common.yaml index d4061be7aabcb..425430deb1470 100644 --- a/dts/bindings/serial/nordic,nrf-uart-common.yaml +++ b/dts/bindings/serial/nordic,nrf-uart-common.yaml @@ -43,3 +43,6 @@ properties: - 460800 - 921600 - 1000000 + - 2000000 + - 4000000 + - 8000000 diff --git a/dts/bindings/serial/nxp,kinetis-lpuart.yaml b/dts/bindings/serial/nxp,kinetis-lpuart.yaml deleted file mode 100644 index b17723ff5ade4..0000000000000 --- a/dts/bindings/serial/nxp,kinetis-lpuart.yaml +++ /dev/null @@ -1,35 +0,0 @@ -description: Kinetis LPUART - -compatible: "nxp,kinetis-lpuart" - -include: [uart-controller.yaml, uart-controller-pin-inversion.yaml, pinctrl-device.yaml] - -properties: - reg: - required: true - - nxp,loopback: - type: boolean - description: | - Enable loopback mode on LPUART peripheral. When present, RX pin is - disconnected, and transmitter output is internally connected to - the receiver input. - - single-wire: - type: boolean - description: | - Enable the single wire half-duplex communication. - Using this mode, TX and RX lines are internally connected and - only TX pin is used afterwards and should be configured. - RX/TX conflicts must be handled on user side. - - nxp,rs485-mode: - type: boolean - description: | - Set to enable RTS signal, which can be used to enable the driver - of an external RS-485 transceiver. Note hw-flow-control should be - set to false. - - nxp,rs485-de-active-low: - type: boolean - description: RTS polarity at RS485 mode. diff --git a/dts/bindings/serial/nxp,lpuart.yaml b/dts/bindings/serial/nxp,lpuart.yaml new file mode 100644 index 0000000000000..cc6f06850e603 --- /dev/null +++ b/dts/bindings/serial/nxp,lpuart.yaml @@ -0,0 +1,35 @@ +description: NXP LPUART + +compatible: "nxp,lpuart" + +include: [uart-controller.yaml, uart-controller-pin-inversion.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + nxp,loopback: + type: boolean + description: | + Enable loopback mode on LPUART peripheral. When present, RX pin is + disconnected, and transmitter output is internally connected to + the receiver input. + + single-wire: + type: boolean + description: | + Enable the single wire half-duplex communication. + Using this mode, TX and RX lines are internally connected and + only TX pin is used afterwards and should be configured. + RX/TX conflicts must be handled on user side. + + nxp,rs485-mode: + type: boolean + description: | + Set to enable RTS signal, which can be used to enable the driver + of an external RS-485 transceiver. Note hw-flow-control should be + set to false. + + nxp,rs485-de-active-low: + type: boolean + description: RTS polarity at RS485 mode. diff --git a/dts/bindings/serial/raspberrypi,pico-uart.yaml b/dts/bindings/serial/raspberrypi,pico-uart.yaml index e9c3ef68b5581..5a217d5b4d614 100644 --- a/dts/bindings/serial/raspberrypi,pico-uart.yaml +++ b/dts/bindings/serial/raspberrypi,pico-uart.yaml @@ -2,11 +2,4 @@ description: Raspberry Pi Pico UART compatible: "raspberrypi,pico-uart" -include: [uart-controller.yaml, pinctrl-device.yaml, reset-device.yaml] - -properties: - reg: - required: true - - interrupts: - required: true +include: "arm,pl011.yaml" diff --git a/dts/bindings/serial/realtek,rts5912-uart.yaml b/dts/bindings/serial/realtek,rts5912-uart.yaml new file mode 100644 index 0000000000000..b1464900490fa --- /dev/null +++ b/dts/bindings/serial/realtek,rts5912-uart.yaml @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +description: Realtek RTS5912 UART + +compatible: "realtek,rts5912-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + port: + type: int + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true diff --git a/dts/bindings/serial/renesas,rz-scif-uart.yaml b/dts/bindings/serial/renesas,rz-scif-uart.yaml new file mode 100644 index 0000000000000..1d3ae33b1b25e --- /dev/null +++ b/dts/bindings/serial/renesas,rz-scif-uart.yaml @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ SCIF UART controller + +compatible: "renesas,rz-scif-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + current-speed: + description: | + Initial baud rate setting for UART. Defaults to standard baudrate of 115200 if not specified. + default: 115200 + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 + + channel: + type: int + required: true diff --git a/dts/bindings/serial/renesas,rzt2m-uart.yaml b/dts/bindings/serial/renesas,rzt2m-uart.yaml index 967972ac7c836..9ab38e8f63849 100644 --- a/dts/bindings/serial/renesas,rzt2m-uart.yaml +++ b/dts/bindings/serial/renesas,rzt2m-uart.yaml @@ -22,5 +22,15 @@ properties: - 9600 - 115200 + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 + interrupts: required: true diff --git a/dts/bindings/serial/sensry,sy1xx-uart.yaml b/dts/bindings/serial/sensry,sy1xx-uart.yaml index fbb98dded3c25..99007cf648d9d 100644 --- a/dts/bindings/serial/sensry,sy1xx-uart.yaml +++ b/dts/bindings/serial/sensry,sy1xx-uart.yaml @@ -5,7 +5,7 @@ description: Sensry SY1xx UART compatible: "sensry,sy1xx-uart" -include: uart-controller.yaml +include: [uart-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/serial/silabs,eusart-uart.yaml b/dts/bindings/serial/silabs,eusart-uart.yaml new file mode 100644 index 0000000000000..c546abcba7392 --- /dev/null +++ b/dts/bindings/serial/silabs,eusart-uart.yaml @@ -0,0 +1,27 @@ +description: Silabs EUSART UART + +compatible: "silabs,eusart-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + current-speed: + description: | + Initial baud rate setting for UART. Defaults to standard baudrate of 115200 if not specified. + default: 115200 + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 diff --git a/dts/bindings/serial/silabs,gecko-uart.yaml b/dts/bindings/serial/silabs,gecko-uart.yaml index ae22286e72bd4..0ed866631be9a 100644 --- a/dts/bindings/serial/silabs,gecko-uart.yaml +++ b/dts/bindings/serial/silabs,gecko-uart.yaml @@ -11,6 +11,21 @@ properties: interrupts: required: true + current-speed: + description: | + Initial baud rate setting for UART. Defaults to standard baudrate of 115200 if not specified. + default: 115200 + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 + peripheral-id: type: int required: true diff --git a/dts/bindings/serial/silabs,gecko-usart.yaml b/dts/bindings/serial/silabs,gecko-usart.yaml index 14d0fad61bd95..adefd0fddb14f 100644 --- a/dts/bindings/serial/silabs,gecko-usart.yaml +++ b/dts/bindings/serial/silabs,gecko-usart.yaml @@ -11,6 +11,21 @@ properties: interrupts: required: true + current-speed: + description: | + Initial baud rate setting for UART. Defaults to standard baudrate of 115200 if not specified. + default: 115200 + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 + peripheral-id: type: int description: peripheral ID diff --git a/dts/bindings/serial/silabs,usart-uart.yaml b/dts/bindings/serial/silabs,usart-uart.yaml new file mode 100644 index 0000000000000..9d01c3b05d54c --- /dev/null +++ b/dts/bindings/serial/silabs,usart-uart.yaml @@ -0,0 +1,27 @@ +description: Silabs USART UART + +compatible: "silabs,usart-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + current-speed: + description: | + Initial baud rate setting for UART. Defaults to standard baudrate of 115200 if not specified. + default: 115200 + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 diff --git a/dts/bindings/serial/st,stm32-uart-base.yaml b/dts/bindings/serial/st,stm32-uart-base.yaml index 37b6e66762bd6..f832311174304 100644 --- a/dts/bindings/serial/st,stm32-uart-base.yaml +++ b/dts/bindings/serial/st,stm32-uart-base.yaml @@ -25,6 +25,21 @@ properties: interrupts: required: true + current-speed: + description: | + Initial baud rate setting for UART. Defaults to standard baudrate of 115200 if not specified. + default: 115200 + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 + single-wire: type: boolean description: | diff --git a/dts/bindings/serial/ti,cc13xx-cc26xx-uart.yaml b/dts/bindings/serial/ti,cc13xx-cc26xx-uart.yaml index 5b13c83934ccb..1ba0920602d19 100644 --- a/dts/bindings/serial/ti,cc13xx-cc26xx-uart.yaml +++ b/dts/bindings/serial/ti,cc13xx-cc26xx-uart.yaml @@ -13,3 +13,16 @@ properties: interrupts: required: true + + current-speed: + required: true + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 diff --git a/dts/bindings/serial/ti,cc23x0-uart.yaml b/dts/bindings/serial/ti,cc23x0-uart.yaml new file mode 100644 index 0000000000000..f2587a0a26761 --- /dev/null +++ b/dts/bindings/serial/ti,cc23x0-uart.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +description: TI SimpleLink CC23X0 UART node + +compatible: "ti,cc23x0-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 diff --git a/dts/bindings/serial/uart-controller.yaml b/dts/bindings/serial/uart-controller.yaml index 3c4873fedef2a..81f25af21aad6 100644 --- a/dts/bindings/serial/uart-controller.yaml +++ b/dts/bindings/serial/uart-controller.yaml @@ -23,6 +23,7 @@ properties: - "none" - "odd" - "even" + default: "none" stop-bits: type: string description: | diff --git a/dts/bindings/serial/zephyr,cdc-acm-uart.yaml b/dts/bindings/serial/zephyr,cdc-acm-uart.yaml index 8e0a0030978cd..6b7ad36d1d10b 100644 --- a/dts/bindings/serial/zephyr,cdc-acm-uart.yaml +++ b/dts/bindings/serial/zephyr,cdc-acm-uart.yaml @@ -21,3 +21,8 @@ properties: default: 1024 description: | Size of the virtual CDC ACM UART RX FIFO + + label: + description: | + The string defined by the label property is also used for the USB + interface string descriptor. diff --git a/dts/bindings/spi/atmel,sam0-spi.yaml b/dts/bindings/spi/atmel,sam0-spi.yaml index 8b1c79b822086..ea5a57501112f 100644 --- a/dts/bindings/spi/atmel,sam0-spi.yaml +++ b/dts/bindings/spi/atmel,sam0-spi.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2018, Google LLC. +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 SERCOM SPI controller @@ -8,6 +9,7 @@ compatible: "atmel,sam0-spi" include: - name: spi-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -19,6 +21,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + dipo: type: int required: true diff --git a/dts/bindings/spi/nxp,dspi.yaml b/dts/bindings/spi/nxp,dspi.yaml new file mode 100644 index 0000000000000..b5b9f74c7929c --- /dev/null +++ b/dts/bindings/spi/nxp,dspi.yaml @@ -0,0 +1,83 @@ +# Copyright (c) 2018, NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP DSPI controller + +compatible: "nxp,dspi" + +include: ["spi-controller.yaml", "pinctrl-device.yaml"] + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + pcs-sck-delay: + type: int + description: | + Delay in nanoseconds from the chip select assert to the first clock + edge. If not set, the minimum supported delay is used. + + sck-pcs-delay: + type: int + description: | + Delay in nanoseconds from the last clock edge to the chip select + deassert. If not set, the minimum supported delay is used. + + transfer-delay: + type: int + description: | + Delay in nanoseconds from the chip select deassert to the next chip + select assert. If not set, the minimum supported delay is used. + + pinctrl-0: + required: true + + nxp,rx-tx-chn-share: + type: boolean + description: If the edma channel shared with tx and rx + + ctar: + type: int + description: | + ctar register selection range form 0-1 for master mode, 0 for slave mode + + sample-point: + type: int + description: | + Controls when the DSPI master samples SIN in the Modified Transfer Format. + This field is valid only when the CPHA bit in the CTAR register is 0. + + continuous-sck: + type: boolean + description: | + continuous SCK enable. Note that the continuous SCK is only + supported for CPHA = 1. + + rx-fifo-overwrite: + type: boolean + description: | + receive FIFO overflow overwrite enable. If ROOE = 0, the incoming + data is ignored and the data from the transfer that generated the overflow + is also ignored. If ROOE = 1, the incoming data is shifted to the + shift register. + + modified-timing-format: + type: boolean + description: | + Enables a modified transfer format to be used if true. + + tx-fifo-size: + type: int + description: | + tx fifo size + + rx-fifo-size: + type: int + description: | + rx fifo size diff --git a/dts/bindings/spi/nxp,kinetis-dspi.yaml b/dts/bindings/spi/nxp,kinetis-dspi.yaml deleted file mode 100644 index 61746937c396a..0000000000000 --- a/dts/bindings/spi/nxp,kinetis-dspi.yaml +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (c) 2018, NXP -# SPDX-License-Identifier: Apache-2.0 - -description: NXP Kinetis DSPI controller - -compatible: "nxp,kinetis-dspi" - -include: ["spi-controller.yaml", "pinctrl-device.yaml"] - -properties: - reg: - required: true - - interrupts: - required: true - - clocks: - required: true - - pcs-sck-delay: - type: int - description: | - Delay in nanoseconds from the chip select assert to the first clock - edge. If not set, the minimum supported delay is used. - - sck-pcs-delay: - type: int - description: | - Delay in nanoseconds from the last clock edge to the chip select - deassert. If not set, the minimum supported delay is used. - - transfer-delay: - type: int - description: | - Delay in nanoseconds from the chip select deassert to the next chip - select assert. If not set, the minimum supported delay is used. - - pinctrl-0: - required: true - - nxp,rx-tx-chn-share: - type: boolean - description: If the edma channel shared with tx and rx - - ctar: - type: int - description: | - ctar register selection range form 0-1 for master mode, 0 for slave mode - - sample-point: - type: int - description: | - Controls when the DSPI master samples SIN in the Modified Transfer Format. - This field is valid only when the CPHA bit in the CTAR register is 0. - - continuous-sck: - type: boolean - description: | - continuous SCK enable. Note that the continuous SCK is only - supported for CPHA = 1. - - rx-fifo-overwrite: - type: boolean - description: | - receive FIFO overflow overwrite enable. If ROOE = 0, the incoming - data is ignored and the data from the transfer that generated the overflow - is also ignored. If ROOE = 1, the incoming data is shifted to the - shift register. - - modified-timing-format: - type: boolean - description: | - Enables a modified transfer format to be used if true. - - tx-fifo-size: - type: int - description: | - tx fifo size - - rx-fifo-size: - type: int - description: | - rx fifo size diff --git a/dts/bindings/spi/nxp,lpspi.yaml b/dts/bindings/spi/nxp,lpspi.yaml index ec4e742a8dc7a..62a11d42ac0de 100644 --- a/dts/bindings/spi/nxp,lpspi.yaml +++ b/dts/bindings/spi/nxp,lpspi.yaml @@ -18,19 +18,22 @@ properties: type: int description: | Delay in nanoseconds from the chip select assert to the first clock - edge. If not set, the minimum supported delay is used. + edge. + If not set, the minimum supported delay is used. sck-pcs-delay: type: int description: | Delay in nanoseconds from the last clock edge to the chip select - deassert. If not set, the minimum supported delay is used. + deassert. + If not set, the minimum supported delay is used. transfer-delay: type: int description: | - Delay in nanoseconds from the chip select deassert to the next chip - select assert. If not set, the minimum supported delay is used. + Delay in nanoseconds between last SCK edge of a trasnfer word and the + first SCK edge of the next transfer word. + If not set, the minimum supported delay is used. data-pin-config: type: string @@ -43,3 +46,22 @@ properties: description: | Configures which pins (SDO and SDI) are used for input and output data during single bit transfers. + + tristate-output: + type: boolean + description: + Configures whether or not the output data is tristated between accesses + (when PCS is negated). If set, the output will be tristated when PCS is negated, + otherwise the output line retains the last value when PCS is negated. + + rx-fifo-size: + type: int + required: true + description: | + Max number of words in the RX fifo on this instance of the LPSPI. + + tx-fifo-size: + type: int + required: true + description: | + Max number of words in the TX/Command fifo on this instance of the LPSPI. diff --git a/dts/bindings/spi/nxp,xspi.yaml b/dts/bindings/spi/nxp,xspi.yaml new file mode 100644 index 0000000000000..236ad62ba4880 --- /dev/null +++ b/dts/bindings/spi/nxp,xspi.yaml @@ -0,0 +1,20 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP XSPI controller + +compatible: "nxp,xspi" + +include: [spi-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + +child-binding: + description: NXP XSPI port + + include: nxp,xspi-device.yaml diff --git a/dts/bindings/spi/silabs,eusart-spi.yaml b/dts/bindings/spi/silabs,eusart-spi.yaml new file mode 100644 index 0000000000000..59a10502e7041 --- /dev/null +++ b/dts/bindings/spi/silabs,eusart-spi.yaml @@ -0,0 +1,21 @@ +description: Silabs EUSART SPI + +compatible: "silabs,eusart-spi" + +include: [spi-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + clocks: + required: true diff --git a/dts/bindings/spi/silabs,gecko-spi-eusart.yaml b/dts/bindings/spi/silabs,gecko-spi-eusart.yaml deleted file mode 100644 index 1663c8ec8dc79..0000000000000 --- a/dts/bindings/spi/silabs,gecko-spi-eusart.yaml +++ /dev/null @@ -1,21 +0,0 @@ -description: GECKO EUSART SPI - -compatible: "silabs,gecko-spi-eusart" - -include: [spi-controller.yaml, pinctrl-device.yaml] - -properties: - reg: - required: true - - interrupts: - required: true - - pinctrl-0: - required: true - - pinctrl-names: - required: true - - clocks: - required: true diff --git a/dts/bindings/spi/silabs,gecko-spi-usart.yaml b/dts/bindings/spi/silabs,gecko-spi-usart.yaml deleted file mode 100644 index df3bcc6ccbca5..0000000000000 --- a/dts/bindings/spi/silabs,gecko-spi-usart.yaml +++ /dev/null @@ -1,31 +0,0 @@ -description: GECKO USART SPI - -compatible: "silabs,gecko-spi-usart" - -include: [spi-controller.yaml, pinctrl-device.yaml] - -properties: - reg: - required: true - - interrupts: - required: true - - peripheral-id: - type: int - description: peripheral ID - - # Note: Not all SoC series support setting individual pin location. If this - # is a case all location-* properties need to have identical value. - - location-rx: - type: array - description: RX pin configuration defined as - - location-tx: - type: array - description: TX pin configuration defined as - - location-clk: - type: array - description: CLK pin configuration defined as diff --git a/dts/bindings/spi/silabs,usart-spi.yaml b/dts/bindings/spi/silabs,usart-spi.yaml new file mode 100644 index 0000000000000..1b1490974128f --- /dev/null +++ b/dts/bindings/spi/silabs,usart-spi.yaml @@ -0,0 +1,31 @@ +description: Silabs USART SPI + +compatible: "silabs,usart-spi" + +include: [spi-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + peripheral-id: + type: int + description: peripheral ID + + # Note: Not all SoC series support setting individual pin location. If this + # is a case all location-* properties need to have identical value. + + location-rx: + type: array + description: RX pin configuration defined as + + location-tx: + type: array + description: TX pin configuration defined as + + location-clk: + type: array + description: CLK pin configuration defined as diff --git a/dts/bindings/stepper/adi/adi,tmc2209.yaml b/dts/bindings/stepper/adi/adi,tmc2209.yaml new file mode 100644 index 0000000000000..96a13bfe94d6f --- /dev/null +++ b/dts/bindings/stepper/adi/adi,tmc2209.yaml @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +description: | + Analog Devices TMC2209 stepper motor driver. + + Example: + tmc2209: tmc2209 { + compatible = "adi,tmc2209"; + enable-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + msx-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>, + <&gpio0 2 GPIO_ACTIVE_HIGH>; + step-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + dir-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + dual-edge-step; + } + +compatible: "adi,tmc2209" + +include: + - name: stepper-controller.yaml + property-allowlist: + - micro-step-res + - step-gpios + - dir-gpios + - en-gpios + - counter + +properties: + msx-gpios: + type: phandle-array + description: | + An array of GPIO pins for configuring the microstep resolution of the driver. + The pins should be listed in the following order: + - MS1 + - MS2 + + dual-edge-step: + type: boolean + description: | + If present, the stepper motor controller supports dual edge step signals. + This means that the step signal can be toggled on both the rising and falling edge. diff --git a/dts/bindings/stepper/adi/adi,tmc5041.yaml b/dts/bindings/stepper/adi/adi,tmc5041.yaml deleted file mode 100644 index ba856b7fa65b8..0000000000000 --- a/dts/bindings/stepper/adi/adi,tmc5041.yaml +++ /dev/null @@ -1,117 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG -# SPDX-License-Identifier: Apache-2.0 - -description: | - Analog Devices TMC5041 Stepper Motor Controller - - Example: - - #include - - &spi0 { - /* SPI bus options here, not shown */ - - /* Dual controller/driver for up to two 2-phase bipolar stepper motors */ - tmc5041: tmc5041@0 { - compatible = "adi,tmc5041"; - reg = <0>; - spi-max-frequency = ; /* Maximum SPI bus frequency */ - - #address-cells = <1>; - #size-cells = <0>; - - poscmp_enable; test_mode; lock_gconf; /* ADI TMC Global configuration flags */ - clock-frequency = ; /* Internal/External Clock frequency */ - - motor: motor@0 { - status = "okay"; - reg = <0>; - - /* common stepper controller settings */ - invert-direction; - micro-step-res = <256>; - - /* ADI TMC stallguard settings specific to TMC5041 */ - activate-stallguard2; - stallguard-velocity-check-interval-ms=<100>; - stallguard2-threshold=<9>; - stallguard-threshold-velocity=<500000>; - - /* ADI TMC ramp generator as well as current settings */ - vstart = <10>; - a1 = <20>; - v1 = <30>; - d1 = <40>; - vmax = <50>; - amax = <60>; - dmax = <70>; - tzerowait = <80>; - vhigh = <90>; - vcoolthrs = <100>; - ihold = <1>; - irun = <2>; - iholddelay = <3>; - }; - }; - }; - - -compatible: "adi,tmc5041" - -include: - - name: spi-device.yaml - - name: adi,trinamic-gconf.yaml - property-allowlist: - - poscmp_enable - - shaft1 - - shaft2 - - test_mode - - lock_gconf - -properties: - "#address-cells": - default: 1 - const: 1 - - "#size-cells": - default: 0 - const: 0 - - clock-frequency: - type: int - required: true - description: | - The frequency of the clock signal provided to the TMC5041. - This is used for real world conversion. - - Hint: µstep velocity v[Hz] µsteps / s v[Hz] = v[5041] * ( fCLK[Hz]/2 / 2^23 ) - where v[5041] is the value written to the TMC5041. - -child-binding: - include: - - name: stepper-controller.yaml - - name: base.yaml - property-allowlist: - - reg - - name: adi,trinamic-ramp-generator.yaml - property-allowlist: - - vstart - - a1 - - v1 - - amax - - vmax - - dmax - - d1 - - vstop - - tzerowait - - vhigh - - vcoolthrs - - ihold - - irun - - iholddelay - - name: adi,trinamic-stallguard.yaml - property-allowlist: - - activate-stallguard2 - - stallguard2-threshold - - stallguard-threshold-velocity - - stallguard-velocity-check-interval-ms diff --git a/dts/bindings/stepper/adi/adi,tmc50xx.yaml b/dts/bindings/stepper/adi/adi,tmc50xx.yaml new file mode 100644 index 0000000000000..a20e680e3aeec --- /dev/null +++ b/dts/bindings/stepper/adi/adi,tmc50xx.yaml @@ -0,0 +1,115 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG +# SPDX-License-Identifier: Apache-2.0 + +description: | + Analog Devices TMC50XX Stepper Motor Controller + + Example: + + &spi0 { + /* SPI bus options here, not shown */ + + /* Dual controller/driver for up to two 2-phase bipolar stepper motors */ + tmc50xx: tmc50xx@0 { + compatible = "adi,tmc50xx"; + reg = <0>; + spi-max-frequency = ; /* Maximum SPI bus frequency */ + + #address-cells = <1>; + #size-cells = <0>; + + poscmp-enable; test-mode; lock-gconf; /* ADI TMC Global configuration flags */ + clock-frequency = ; /* Internal/External Clock frequency */ + + motor: motor@0 { + status = "okay"; + reg = <0>; + + /* common stepper controller settings */ + invert-direction; + micro-step-res = <256>; + + /* ADI TMC stallguard settings specific to TMC50XX */ + activate-stallguard2; + stallguard-velocity-check-interval-ms=<100>; + stallguard2-threshold=<9>; + stallguard-threshold-velocity=<500000>; + + /* ADI TMC ramp generator as well as current settings */ + vstart = <10>; + a1 = <20>; + v1 = <30>; + d1 = <40>; + vmax = <50>; + amax = <60>; + dmax = <70>; + tzerowait = <80>; + vhigh = <90>; + vcoolthrs = <100>; + ihold = <1>; + irun = <2>; + iholddelay = <3>; + }; + }; + }; + + +compatible: "adi,tmc50xx" + +include: + - name: spi-device.yaml + - name: adi,trinamic-gconf.yaml + property-allowlist: + - poscmp-enable + - shaft1 + - shaft2 + - test-mode + - lock-gconf + +properties: + "#address-cells": + default: 1 + const: 1 + + "#size-cells": + default: 0 + const: 0 + + clock-frequency: + type: int + required: true + description: | + The frequency of the clock signal provided to the TMC50XX. + This is used for real world conversion. + + Hint: µstep velocity v[Hz] µsteps / s v[Hz] = v[50xx] * ( fCLK[Hz]/2 / 2^23 ) + where v[50xx] is the value written to the TMC50XX. + +child-binding: + include: + - name: stepper-controller.yaml + - name: base.yaml + property-allowlist: + - reg + - name: adi,trinamic-ramp-generator.yaml + property-allowlist: + - vstart + - a1 + - v1 + - amax + - vmax + - dmax + - d1 + - vstop + - tzerowait + - vhigh + - vcoolthrs + - ihold + - irun + - iholddelay + - name: adi,trinamic-stallguard.yaml + property-allowlist: + - activate-stallguard2 + - stallguard2-threshold + - stallguard-threshold-velocity + - stallguard-velocity-check-interval-ms diff --git a/dts/bindings/stepper/adi/adi,trinamic-gconf.yaml b/dts/bindings/stepper/adi/adi,trinamic-gconf.yaml index 404476b8ee449..906e863f84d0d 100644 --- a/dts/bindings/stepper/adi/adi,trinamic-gconf.yaml +++ b/dts/bindings/stepper/adi/adi,trinamic-gconf.yaml @@ -4,51 +4,51 @@ description: Global configuration flags for Trinamic stepper controller. properties: - en_spreadcycle: + en-spreadcycle: type: boolean description: | A high level on the pin SPREAD inverts this flag to switch between both chopper modes. 0: StealthChop mode 1: SpreadCycle mode enabled - i_scale_analog: + i-scale-analog: type: boolean description: | 0: Use internal reference derived from 5VOUT 1: Use voltage supplied to VREF as current reference - internal_rsense: + internal-rsense: type: boolean description: | 0: Operation with external sense resistors 1: Internal sense resistors. Use current supplied into VREF as reference for internal sense resistor. VREF pin internally is driven to GND in this mode. - index_otpw: + index-otpw: type: boolean description: | 0: INDEX shows the first microstep position of sequencer 1: INDEX output shows step pulses from internal pulse generator (toggle upon each step) - index_step: + index-step: type: boolean description: | - 0: INDEX output as selected by index_otpw + 0: INDEX output as selected by index-otpw 1: INDEX pin shows the current step position of sequencer - pdn_disable: + pdn-disable: type: boolean description: | 0: Normal operation 1: Power down mode - mstep_reg_select: + mstep-reg-select: type: boolean description: | 0: Microstep resolution selected by pins MS1, MS2 1: Microstep resolution selected by MRES register - poscmp_enable: + poscmp-enable: type: boolean description: | Enable position compare feature @@ -56,9 +56,9 @@ properties: 1: Position compare pulse (PP) and interrupt output (INT) are available Attention – do not leave the outputs floating in tristate condition, provide an external - pull-up or set poscmp_enable=1 + pull-up or set poscmp-enable=1 - test_mode: + test-mode: type: boolean description: | Enable test mode @@ -68,7 +68,7 @@ properties: Attention: Not for user, set to 0 for normal operation! - lock_gconf: + lock-gconf: type: boolean description: | 1: GCONF is locked against further write access. diff --git a/dts/bindings/stepper/stepper-controller.yaml b/dts/bindings/stepper/stepper-controller.yaml index 2607fc6f9915e..a73037bb6b975 100644 --- a/dts/bindings/stepper/stepper-controller.yaml +++ b/dts/bindings/stepper/stepper-controller.yaml @@ -24,3 +24,23 @@ properties: - 256 description: | micro-step resolution to be set while initializing the device driver. + + en-gpios: + type: phandle-array + description: | + GPIO pins used to control the enable signal of the motor driver. + + step-gpios: + type: phandle-array + description: | + The GPIO pins used to send step signals to the stepper motor. + + dir-gpios: + type: phandle-array + description: | + The GPIO pins used to send direction signals to the stepper motor. + Pin will be driven high for forward direction and low for reverse direction. + + counter: + type: phandle + description: Counter used for generating step-accurate pulse signals. diff --git a/dts/bindings/stepper/ti/ti,drv8424.yaml b/dts/bindings/stepper/ti/ti,drv8424.yaml new file mode 100644 index 0000000000000..e02d85e5026aa --- /dev/null +++ b/dts/bindings/stepper/ti/ti,drv8424.yaml @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Navimatix GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: | + TI DRV8424 stepper motor driver. + SAFETY: + The counter needs to support both set_top_value functionalities: Setting a new top value and + attaching an ISR to the turnaround. + SAFETY: + The step gpio pin needs to be connected directly to the SOC GPIO controller, connecting the + pin to a controller connected via a bus such as i2c or others will lead to undefined behaviour. + + Example: + drv8424: drv8424 { + status = "okay"; + compatible = "ti,drv8424"; + + dir-gpios = <&arduino_header 18 0>; + step-gpios = <&arduino_header 19 0>; + sleep-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; + en-gpios = <&arduino_header 14 0>; + m0-gpios = <&mikroe_stepper_gpios 0 0>; + m1-gpios = <&mikroe_stepper_gpios 1 0>; + counter = <&counter2>; + }; + + +compatible: "ti,drv8424" + +include: + - name: stepper-controller.yaml + property-allowlist: + - micro-step-res + - step-gpios + - dir-gpios + - en-gpios + - counter + +properties: + fault-gpios: + type: phandle-array + description: Fault pin. + + sleep-gpios: + type: phandle-array + description: Sleep pin (active low). + + m0-gpios: + required: true + type: phandle-array + description: Microstep configuration pin 0. + + m1-gpios: + required: true + type: phandle-array + description: Microstep configuration pin 1. diff --git a/dts/bindings/tcpc/richtek,rt1715.yaml b/dts/bindings/tcpc/richtek,rt1715.yaml new file mode 100644 index 0000000000000..de106484cb3ba --- /dev/null +++ b/dts/bindings/tcpc/richtek,rt1715.yaml @@ -0,0 +1,74 @@ +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +description: | + The Richtek RT1715 is a Type-C Port Controller (TCPC) chip. + + Example: + + ports { + #address-cells = <1>; + #size-cells = <0>; + port0: usbc-port@0 { + compatible = "usb-c-connector"; + reg = <0>; + tcpc = <&rt1715_tcpc0>; + vbus = <&vbus0>; + power-role = "sink"; + sink-pdos = ; + }; + }; + + vbus0: vbus { + compatible = "zephyr,usb-c-vbus-adc"; + status = "okay"; + io-channels = <&adc 2>; + output-ohms = <10000>; + full-ohms = <(100000 + 10000)>; + }; + + i2c1 { + status = "okay"; + clock-frequency = ; + rt1715_tcpc0: rt1715@4e { + compatible = "richtek,rt1715"; + reg = <0x4e>; + irq-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + }; + +compatible: "richtek,rt1715" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + irq-gpios: + type: phandle-array + required: true + description: | + Interrupt GPIO pin connected from the chip. + + transmit-retries: + type: int + default: 2 + description: | + Maximum number of packet retransmissions done by TCPC. Valid values are <0, 3>. + This value is used to fill the Retry Counter part of the TCPCI Transmit register. + + vconn-ctrl-gpios: + type: phandle-array + description: | + GPIO pin for VCONN control. RT1715 does not have built-in VCONN power supply. If the + state of the VCONN power supply need to be toggled, this pin and a switchable power + supply are required. + + vconn-disc-gpios: + type: phandle-array + description: | + GPIO pin for VCONN discharge control. RT1715 does not have VCONN discharge capability. + If VCONN discharge is not needed, this pin does not need to be defined in the device + tree. Otherwise, this pin and a discharge path are required. diff --git a/dts/bindings/test/vnd,video-multi-port.yaml b/dts/bindings/test/vnd,video-multi-port.yaml new file mode 100644 index 0000000000000..dc459b03f0c42 --- /dev/null +++ b/dts/bindings/test/vnd,video-multi-port.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2024 tinyVision.ai Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Test Video device + +compatible: "vnd,video-multi-port" + +child-binding: + child-binding: + child-binding: + include: video-interfaces.yaml + properties: + reg: + type: array diff --git a/dts/bindings/test/vnd,video-single-port.yaml b/dts/bindings/test/vnd,video-single-port.yaml new file mode 100644 index 0000000000000..2c0df5bb34a9c --- /dev/null +++ b/dts/bindings/test/vnd,video-single-port.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2024 tinyVision.ai Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Test Video device + +compatible: "vnd,video-single-port" + +child-binding: + child-binding: + include: video-interfaces.yaml + properties: + reg: + type: array diff --git a/dts/bindings/timer/andestech,machine-timer.yaml b/dts/bindings/timer/andestech,machine-timer.yaml deleted file mode 100644 index 9a1c4e891d32d..0000000000000 --- a/dts/bindings/timer/andestech,machine-timer.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2022 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: | - Andes Machine Timer - - The Andes machine timer provides RISC-V privileged mtime and mtimecmp - registers. - -compatible: "andestech,machine-timer" - -include: base.yaml - -properties: - reg: - required: true - - interrupts-extended: - required: true diff --git a/dts/bindings/timer/lowrisc,machine-timer.yaml b/dts/bindings/timer/lowrisc,machine-timer.yaml deleted file mode 100644 index 01721e22ed48c..0000000000000 --- a/dts/bindings/timer/lowrisc,machine-timer.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2023 Rivos Inc. -# SPDX-License-Identifier: Apache-2.0 - -description: | - OpenTitan Machine Timer - - The OpenTitan machine timer provides RISC-V privileged mtime and mtimecmp - registers. - -compatible: "lowrisc,machine-timer" - -include: base.yaml - -properties: - reg: - required: true - - interrupts: - required: true diff --git a/dts/bindings/timer/neorv32-machine-timer.yaml b/dts/bindings/timer/neorv32-machine-timer.yaml deleted file mode 100644 index 4c72679f6a589..0000000000000 --- a/dts/bindings/timer/neorv32-machine-timer.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2022 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: | - NEORV32 Machine Timer - - The NEORV32 machine timer provides RISC-V privileged mtime and mtimecmp - registers. - -compatible: "neorv32-machine-timer" - -include: base.yaml - -properties: - reg: - required: true - - interrupts: - required: true diff --git a/dts/bindings/timer/niosv-machine-timer.yaml b/dts/bindings/timer/niosv-machine-timer.yaml deleted file mode 100644 index 4b77d131e6ee1..0000000000000 --- a/dts/bindings/timer/niosv-machine-timer.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (C) 2023, Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -description: | - NIOSV Machine Timer - - The NIOSV machine timer provides RISC-V privileged mtime and mtimecmp - registers. - -compatible: "niosv-machine-timer" - -include: base.yaml - -properties: - reg: - required: true - - interrupts: - required: true diff --git a/dts/bindings/timer/nordic,nrf-grtc.yaml b/dts/bindings/timer/nordic,nrf-grtc.yaml index e78e57df97e29..edff2423b1190 100644 --- a/dts/bindings/timer/nordic,nrf-grtc.yaml +++ b/dts/bindings/timer/nordic,nrf-grtc.yaml @@ -4,18 +4,40 @@ # SPDX-License-Identifier: Apache-2.0 # -description: Nordic GRTC (Global RTC) +description: | + Nordic GRTC (Global RTC) + + Example of using clock outputs: + &grtc { + pinctrl-0 = <&grtc_default>; + pinctrl-1 = <&grtc_sleep>; + pinctrl-names = "default", "sleep"; + clkout-fast-frequency-hz = <8000000>; + clkout-32k; + /* In case of nRF54H20 devices: */ + nordic,clockpin-enable = ; + }; compatible: "nordic,nrf-grtc" include: - "base.yaml" - "nordic,split-channels.yaml" + - "pinctrl-device.yaml" + - "nordic-clockpin.yaml" properties: reg: required: true + clkout-fast-frequency-hz: + type: int + description: Fast output clock frequency. + + clkout-32k: + type: boolean + description: 32768 Hz output clock frequency enable. + interrupts: required: true diff --git a/dts/bindings/timer/nuclei,systimer.yaml b/dts/bindings/timer/nuclei,systimer.yaml index 5c8f319a7c51d..265b0716b4062 100644 --- a/dts/bindings/timer/nuclei,systimer.yaml +++ b/dts/bindings/timer/nuclei,systimer.yaml @@ -9,15 +9,9 @@ description: | compatible: "nuclei,systimer" -include: base.yaml +include: "riscv,machine-timer.yaml" properties: - reg: - required: true - - interrupts: - required: true - clk-divider: type: int description: | diff --git a/dts/bindings/timer/nxp,ftm.yaml b/dts/bindings/timer/nxp,ftm.yaml new file mode 100644 index 0000000000000..064f7ab9f8a24 --- /dev/null +++ b/dts/bindings/timer/nxp,ftm.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2017, NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP FlexTimer Module (FTM) + +compatible: "nxp,ftm" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + prescaler: + type: int + required: true + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + description: Input clock prescaler diff --git a/dts/bindings/timer/realtek,rts5912-rtmr.yaml b/dts/bindings/timer/realtek,rts5912-rtmr.yaml new file mode 100644 index 0000000000000..6e6c0d3a0a67a --- /dev/null +++ b/dts/bindings/timer/realtek,rts5912-rtmr.yaml @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +description: RTOS Timer on Realtek RTS5912 EC + +compatible: "realtek,rts5912-rtmr" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/dts/bindings/timer/realtek,rts5912-slwtimer.yaml b/dts/bindings/timer/realtek,rts5912-slwtimer.yaml new file mode 100644 index 0000000000000..aa8a3f4051049 --- /dev/null +++ b/dts/bindings/timer/realtek,rts5912-slwtimer.yaml @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +description: Realtek RTS5912 32-bit slow timer + +compatible: "realtek,rts5912-slwtimer" + +include: rtc.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + max-value: + type: int + required: true + description: Maximum counter value the instance can handle + + clock-frequency: + required: true + + prescaler: + type: int + required: true + description: Timer frequency equals clock-frequency divided by the prescaler value diff --git a/dts/bindings/timer/renesas,rz-gpt.yaml b/dts/bindings/timer/renesas,rz-gpt.yaml new file mode 100644 index 0000000000000..e70cda203615d --- /dev/null +++ b/dts/bindings/timer/renesas,rz-gpt.yaml @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ GPT + +compatible: "renesas,rz-gpt" + +include: [base.yaml] + +properties: + prescaler: + type: int + required: true + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + - 256 + - 512 + - 1024 + description: Input clock prescaler. For RZ/G3S, only 1, 4, 16, 64, 256, 1024 are supported. + + channel: + type: int + required: true + + interrupts: + required: true + + interrupt-names: + required: true diff --git a/dts/bindings/timer/renesas,rz-gtm.yaml b/dts/bindings/timer/renesas,rz-gtm.yaml new file mode 100644 index 0000000000000..8d193184ff35a --- /dev/null +++ b/dts/bindings/timer/renesas,rz-gtm.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ GTM Timer + +compatible: "renesas,rz-gtm" + +include: base.yaml + +properties: + reg: + required: true + + channel: + type: int + required: true + + interrupts: + required: true diff --git a/dts/bindings/timer/riscv,machine-timer.yaml b/dts/bindings/timer/riscv,machine-timer.yaml new file mode 100644 index 0000000000000..e0acc601bf19d --- /dev/null +++ b/dts/bindings/timer/riscv,machine-timer.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: RISC-V Machine Timer. + +compatible: "riscv,machine-timer" + +include: base.yaml + +properties: + reg: + required: true + interrupts-extended: + required: true diff --git a/dts/bindings/timer/starfive,jh7100-clint.yaml b/dts/bindings/timer/starfive,jh7100-clint.yaml deleted file mode 100644 index 0120e89930880..0000000000000 --- a/dts/bindings/timer/starfive,jh7100-clint.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2022 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: Starfive JH7100 RISC-V Core-Local Interruptor. - -compatible: "starfive,jh7100-clint" - -include: sifive,clint0.yaml diff --git a/dts/bindings/timer/sy1xx,sys-timer.yaml b/dts/bindings/timer/sy1xx,sys-timer.yaml index b87fbd775641a..58b6e501b6b5b 100644 --- a/dts/bindings/timer/sy1xx,sys-timer.yaml +++ b/dts/bindings/timer/sy1xx,sys-timer.yaml @@ -14,6 +14,6 @@ properties: interrupts: required: true - ticks_us: + ticks-us: type: int required: true diff --git a/dts/bindings/timer/telink,machine-timer.yaml b/dts/bindings/timer/telink,machine-timer.yaml deleted file mode 100644 index 0ee37bd6de711..0000000000000 --- a/dts/bindings/timer/telink,machine-timer.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2022 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: | - Telink Machine Timer - - The Telink machine timer provides RISC-V privileged mtime and mtimecmp - registers. - -compatible: "telink,machine-timer" - -include: base.yaml - -properties: - reg: - required: true - - interrupts: - required: true diff --git a/dts/bindings/timer/ti,cc23x0-timer.yaml b/dts/bindings/timer/ti,cc23x0-timer.yaml new file mode 100644 index 0000000000000..94b70e1a145ec --- /dev/null +++ b/dts/bindings/timer/ti,cc23x0-timer.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Baylibre SAS +# SPDX-License-Identifier: Apache-2.0 + +description: TI SimpleLink CC23x0 Timer Node + +compatible: "ti,cc23x0-systim-timer" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/dts/bindings/usb/nxp,ehci.yaml b/dts/bindings/usb/nxp,ehci.yaml index 8f1569e2060e7..de4c8f25cba03 100644 --- a/dts/bindings/usb/nxp,ehci.yaml +++ b/dts/bindings/usb/nxp,ehci.yaml @@ -8,5 +8,5 @@ compatible: nxp,ehci include: "nxp,mcux-usbd.yaml" properties: - phy_handle: + phy-handle: type: phandle diff --git a/dts/bindings/usb/nxp,lpcip3511.yaml b/dts/bindings/usb/nxp,lpcip3511.yaml index 3c799e493907d..b8681540d963a 100644 --- a/dts/bindings/usb/nxp,lpcip3511.yaml +++ b/dts/bindings/usb/nxp,lpcip3511.yaml @@ -8,5 +8,5 @@ compatible: nxp,lpcip3511 include: "nxp,mcux-usbd.yaml" properties: - phy_handle: + phy-handle: type: phandle diff --git a/dts/bindings/usb/renesas/renesas,ra-udc.yaml b/dts/bindings/usb/renesas/renesas,ra-udc.yaml new file mode 100644 index 0000000000000..495c368fcae58 --- /dev/null +++ b/dts/bindings/usb/renesas/renesas,ra-udc.yaml @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA USB device controller + +compatible: "renesas,ra-udc" diff --git a/dts/bindings/usb/renesas/renesas,ra-usbfs.yaml b/dts/bindings/usb/renesas/renesas,ra-usbfs.yaml new file mode 100644 index 0000000000000..58ec9aa344e83 --- /dev/null +++ b/dts/bindings/usb/renesas/renesas,ra-usbfs.yaml @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA USB full-speed controller + +compatible: "renesas,ra-usbfs" + +include: [pinctrl-device.yaml, usb-ep.yaml] + +properties: + phys-clock: + type: phandles + required: true + description: USBFS physical clock. + + interrupts: + required: true + description: | + IRQ number and priority to use for USBFS. + + interrupt-names: + required: true + enum: + - "usbfs-i" + - "usbfs-r" + description: | + Interrupts must be given corresponding names so that the shim driver can recognize them. + + reg: + required: true + + phys: + type: phandle + description: PHY provider specifier diff --git a/dts/bindings/usb/renesas/renesas,ra-usbhs.yaml b/dts/bindings/usb/renesas/renesas,ra-usbhs.yaml new file mode 100644 index 0000000000000..9428c2413bc5d --- /dev/null +++ b/dts/bindings/usb/renesas/renesas,ra-usbhs.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA USB high-speed controller + +compatible: "renesas,ra-usbhs" + +include: [pinctrl-device.yaml, usb-ep.yaml] + +properties: + phys-clock: + type: phandles + description: | + USBHS physical clocks. Should be provided in case internal clock source is set in phys node. + + interrupts: + required: true + description: | + IRQ number and priority to use for USBHS. + + interrupt-names: + required: true + enum: + - "usbhs-ir" + description: | + Interrupts must be given corresponding names so that the shim driver can recognize them. + + reg: + required: true + + phys: + type: phandle + description: PHY provider specifier diff --git a/dts/bindings/usb/zephyr,midi2-device.yaml b/dts/bindings/usb/zephyr,midi2-device.yaml new file mode 100644 index 0000000000000..851916e7e8775 --- /dev/null +++ b/dts/bindings/usb/zephyr,midi2-device.yaml @@ -0,0 +1,51 @@ +# Copyright (c) 2024 Titouan Christophe +# SPDX-License-Identifier: Apache-2.0 + +description: MIDI2 device + +compatible: "zephyr,midi2-device" + +properties: + "#address-cells": + type: int + const: 1 + + "#size-cells": + type: int + const: 1 + +child-binding: + description: | + MIDI2 Group terminal block. + This represent a set of contiguous MIDI2 groups through which the + device exchange Universal MIDI Packets with the host. + + properties: + reg: + type: array + required: true + description: | + First MIDI2 Group number (address) and number of Group Terminals (size) + in this MIDI2 Group Terminal Block. + The MIDI2 Groups 1 to 16 corresponds to address 0x0 to 0xf. There are + at most 16 addressable groups (of 16 chans each) per MIDI2 interface. + + protocol: + type: string + enum: + - "use-midi-ci" + - "midi1-up-to-64b" + - "midi1-up-to-128b" + - "midi2" + description: | + Default MIDI protocol of the Group Terminals in this Block. + + terminal-type: + type: string + default: "bidirectional" + enum: + - "bidirectional" + - "input-only" + - "output-only" + description: | + Type (data direction) of Group Terminals in this Block. diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index ee115b920f6fd..8243f706f1edf 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -57,6 +57,7 @@ ams AMS AG amstaos AMS-Taos Inc. analogix Analogix Semiconductor, Inc. andestech Andes Technology Corporation +antmicro Antmicro anvo Anvo-Systems Dresden GmbH aosong Guangzhou Aosong Electronic Co., Ltd. ap Angst+Pfister @@ -505,9 +506,11 @@ parade Parade Technologies Inc. parallax Parallax Inc. particle Particle.io pda Precision Design Associates, Inc. +peregrine Peregrine Consultoria e Servicos pericom Pericom Technology Inc. pervasive Pervasive Displays, Inc. phicomm PHICOMM Co., Ltd. +phosense Beijing Phosense Electronic Technology Co., Ltd. phytec PHYTEC picochip Picochip Ltd pine64 Pine64 diff --git a/dts/bindings/video/galaxycore,gc2145.yaml b/dts/bindings/video/galaxycore,gc2145.yaml index d74a4b609736d..a275023c3714a 100644 --- a/dts/bindings/video/galaxycore,gc2145.yaml +++ b/dts/bindings/video/galaxycore,gc2145.yaml @@ -13,3 +13,8 @@ properties: description: | The RESETn pin is asserted to disable the sensor causing a hard reset. The sensor receives this as an active-low signal. + pwdn-gpios: + type: phandle-array + description: | + The PWDN pin is asserted to power down the sensor. The sensor + receives this as an active high signal diff --git a/dts/bindings/video/zephyr,video-emul-imager.yaml b/dts/bindings/video/zephyr,video-emul-imager.yaml new file mode 100644 index 0000000000000..b3d1760eba45e --- /dev/null +++ b/dts/bindings/video/zephyr,video-emul-imager.yaml @@ -0,0 +1,12 @@ +# Copyright 2024 tinyVision.ai Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Emulated Imager for testing purpose + +compatible: "zephyr,video-emul-imager" + +include: i2c-device.yaml + +child-binding: + child-binding: + include: video-interfaces.yaml diff --git a/dts/bindings/video/zephyr,video-emul-rx.yaml b/dts/bindings/video/zephyr,video-emul-rx.yaml new file mode 100644 index 0000000000000..6db547604a1af --- /dev/null +++ b/dts/bindings/video/zephyr,video-emul-rx.yaml @@ -0,0 +1,18 @@ +# Copyright 2024 tinyVision.ai Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Emulated Video DMA engine for testing purpose + +compatible: "zephyr,video-emul-rx" + +include: base.yaml + +child-binding: + child-binding: + include: video-interfaces.yaml + properties: + reg: + type: int + enum: + - 0 # for input endpoint + - 1 # for output endpoint diff --git a/dts/bindings/watchdog/atmel,sam4l-watchdog.yaml b/dts/bindings/watchdog/atmel,sam4l-watchdog.yaml new file mode 100644 index 0000000000000..05916724474ab --- /dev/null +++ b/dts/bindings/watchdog/atmel,sam4l-watchdog.yaml @@ -0,0 +1,37 @@ +# Copyright (c) 2024-2025, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: ATMEL SAM4L watchdog + +compatible: "atmel,sam4l-watchdog" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + clk-source: + type: string + default: "rcsys" + enum: + - "rcsys" + - "osc32k" + description: | + Watchdog counter clock source: + - rcsys: 115kHz internal System RC oscillator + - osc32k: 32kHz clock source + Defaults to "rcsys" (hardware reset value) and always enabled source + + lock-mode: + type: boolean + description: | + Lock the watchdog when setup is executed. This provides a write protection + to the control register. This mechanism can only be released when a hardware + reset happens. diff --git a/dts/bindings/watchdog/nxp,rtwdog.yaml b/dts/bindings/watchdog/nxp,rtwdog.yaml new file mode 100644 index 0000000000000..d834dc1f4cec1 --- /dev/null +++ b/dts/bindings/watchdog/nxp,rtwdog.yaml @@ -0,0 +1,28 @@ +# Copyright 2024, NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP RT watchdog + +compatible: "nxp,rtwdog" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + clk-source: + type: int + required: true + description: Watchdog counter clock source + + clk-divider: + type: int + description: Watchdog counter clock divider + required: true diff --git a/dts/bindings/wifi/infineon,airoc-wifi-spi.yaml b/dts/bindings/wifi/infineon,airoc-wifi-spi.yaml new file mode 100644 index 0000000000000..c4e7b2a1a2b70 --- /dev/null +++ b/dts/bindings/wifi/infineon,airoc-wifi-spi.yaml @@ -0,0 +1,39 @@ +description: | + AIROC Wi-Fi Connectivity over SPI. + +compatible: "infineon,airoc-wifi" + +include: [spi-device.yaml, "infineon,airoc-wifi.yaml"] + +properties: + wifi-host-wake-gpios: + required: true + + bus-select-gpios: + required: true + description: | + Select bus mode. This gpio must be held low before + wifi-reg-on-gpios goes high to select SPI bus mode. + type: phandle-array + + spi-half-duplex: + description: + Use half-duplex communication; if not present, full- + duplex operation is assumed. + type: boolean + + spi-word-size: + description: + SPI word size in bits. Since 8-bit word size is the + most common, that is selected as the default. + type: int + enum: + - 8 + - 16 + - 32 + default: 8 + + spi-data-irq-shared: + description: + SPI data and IRQ share the same GPIO. + type: boolean diff --git a/dts/bindings/wifi/silabs,siwx91x-wifi.yaml b/dts/bindings/wifi/silabs,siwx91x-wifi.yaml new file mode 100644 index 0000000000000..fe93e4910d0f4 --- /dev/null +++ b/dts/bindings/wifi/silabs,siwx91x-wifi.yaml @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Antmicro +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Silabs SiWx91x SoC WiFi + +compatible: "silabs,siwx91x-wifi" diff --git a/dts/common/espressif/partitions_0x0_amp.dtsi b/dts/common/espressif/partitions_0x0_amp.dtsi index 024e273da1fc7..d3424efb00680 100644 --- a/dts/common/espressif/partitions_0x0_amp.dtsi +++ b/dts/common/espressif/partitions_0x0_amp.dtsi @@ -1,7 +1,7 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - #include +#include diff --git a/dts/common/espressif/partitions_0x0_amp_16M.dtsi b/dts/common/espressif/partitions_0x0_amp_16M.dtsi index 86088c3f5fe74..54eb03f738bcb 100644 --- a/dts/common/espressif/partitions_0x0_amp_16M.dtsi +++ b/dts/common/espressif/partitions_0x0_amp_16M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 16MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,42 +12,56 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(6080)>; + reg = <0x20000 DT_SIZE_K(5952)>; }; - slot0_appcpu_partition: partition@610000 { - label = "image-0-appcpu"; - reg = <0x610000 DT_SIZE_K(1920)>; + slot1_partition: partition@5f0000 { + label = "image-1"; + reg = <0x5F0000 DT_SIZE_K(5952)>; }; - slot1_partition: partition@7F0000 { - label = "image-1"; - reg = <0x7F0000 DT_SIZE_K(6080)>; + slot0_appcpu_partition: partition@bc0000 { + label = "image-0-appcpu"; + reg = <0xBC0000 DT_SIZE_K(1984)>; }; - slot1_appcpu_partition: partition@DE0000 { + slot1_appcpu_partition: partition@db0000 { label = "image-1-appcpu"; - reg = <0xDE0000 DT_SIZE_K(1920)>; + reg = <0xDB0000 DT_SIZE_K(1984)>; + }; + + slot0_lpcore_partition: partition@fa0000 { + label = "image-0-lpcore"; + reg = <0xFA0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@fa8000 { + label = "image-1-lpcore"; + reg = <0xFA8000 DT_SIZE_K(32)>; }; - storage_partition: partition@FC0000 { + storage_partition: partition@fb0000 { label = "storage"; - reg = <0xFC0000 DT_SIZE_K(128)>; + reg = <0xFB0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@FE0000 { - label = "image-scratch"; - reg = <0xFE0000 DT_SIZE_K(64)>; + scratch_partition: partition@fe0000 { + label = "image-scratch"; + reg = <0xFE0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@FF0000 { - label = "coredump-partition"; - reg = <0xFF0000 DT_SIZE_K(4)>; + coredump_partition: partition@fff000 { + label = "coredump"; + reg = <0xFFF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0xFFFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_amp_2M.dtsi b/dts/common/espressif/partitions_0x0_amp_2M.dtsi index 77c8f480a5617..adc496d577e57 100644 --- a/dts/common/espressif/partitions_0x0_amp_2M.dtsi +++ b/dts/common/espressif/partitions_0x0_amp_2M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 2MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,7 +12,7 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { @@ -21,34 +20,48 @@ reg = <0x20000 DT_SIZE_K(576)>; }; - slot0_appcpu_partition: partition@B0000 { - label = "image-0-appcpu"; - reg = <0xB0000 DT_SIZE_K(256)>; + slot1_partition: partition@b0000 { + label = "image-1"; + reg = <0xB0000 DT_SIZE_K(576)>; }; - slot1_partition: partition@F0000 { - label = "image-1"; - reg = <0xF0000 DT_SIZE_K(576)>; + slot0_appcpu_partition: partition@140000 { + label = "image-0-appcpu"; + reg = <0x140000 DT_SIZE_K(192)>; }; - slot1_appcpu_partition: partition@180000 { + slot1_appcpu_partition: partition@170000 { label = "image-1-appcpu"; - reg = <0x1a0000 DT_SIZE_K(256)>; + reg = <0x170000 DT_SIZE_K(192)>; + }; + + slot0_lpcore_partition: partition@1a0000 { + label = "image-0-lpcore"; + reg = <0x1A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@1a8000 { + label = "image-1-lpcore"; + reg = <0x1A8000 DT_SIZE_K(32)>; }; - storage_partition: partition@1C0000 { + storage_partition: partition@1b0000 { label = "storage"; - reg = <0x1C0000 DT_SIZE_K(128)>; + reg = <0x1B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@1E0000 { - label = "image-scratch"; - reg = <0x1E0000 DT_SIZE_K(64)>; + scratch_partition: partition@1e0000 { + label = "image-scratch"; + reg = <0x1E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@1F0000 { - label = "coredump-partition"; - reg = <0x1F0000 DT_SIZE_K(4)>; + coredump_partition: partition@1ff000 { + label = "coredump"; + reg = <0x1FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x1FFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_amp_32M.dtsi b/dts/common/espressif/partitions_0x0_amp_32M.dtsi index e5a95fc3bec0b..2d8c92d1b321f 100644 --- a/dts/common/espressif/partitions_0x0_amp_32M.dtsi +++ b/dts/common/espressif/partitions_0x0_amp_32M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 32MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,42 +12,56 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(12352)>; + reg = <0x20000 DT_SIZE_K(12096)>; }; - slot0_appcpu_partition: partition@C30000 { - label = "image-0-appcpu"; - reg = <0xC30000 DT_SIZE_K(3840)>; + slot1_partition: partition@bf0000 { + label = "image-1"; + reg = <0xBF0000 DT_SIZE_K(12096)>; }; - slot1_partition: partition@FF0000 { - label = "image-1"; - reg = <0xFF0000 DT_SIZE_K(12352)>; + slot0_appcpu_partition: partition@17c0000 { + label = "image-0-appcpu"; + reg = <0x17C0000 DT_SIZE_K(4032)>; }; - slot1_appcpu_partition: partition@1C00000 { + slot1_appcpu_partition: partition@1bb0000 { label = "image-1-appcpu"; - reg = <0x1C00000 DT_SIZE_K(3840)>; + reg = <0x1BB0000 DT_SIZE_K(4032)>; + }; + + slot0_lpcore_partition: partition@1fa0000 { + label = "image-0-lpcore"; + reg = <0x1FA0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@1fa8000 { + label = "image-1-lpcore"; + reg = <0x1FA8000 DT_SIZE_K(32)>; }; - storage_partition: partition@1FC0000 { + storage_partition: partition@1fb0000 { label = "storage"; - reg = <0x1FC0000 DT_SIZE_K(128)>; + reg = <0x1FB0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@1FE0000 { - label = "image-scratch"; - reg = <0x1FE0000 DT_SIZE_K(64)>; + scratch_partition: partition@1fe0000 { + label = "image-scratch"; + reg = <0x1FE0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@1FF0000 { - label = "coredump-partition"; - reg = <0x1FF0000 DT_SIZE_K(4)>; + coredump_partition: partition@1fff000 { + label = "coredump"; + reg = <0x1FFF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x1FFFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_amp_4M.dtsi b/dts/common/espressif/partitions_0x0_amp_4M.dtsi index 067615de5ddce..856e35326e07c 100644 --- a/dts/common/espressif/partitions_0x0_amp_4M.dtsi +++ b/dts/common/espressif/partitions_0x0_amp_4M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 4MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,7 +12,7 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { @@ -21,34 +20,48 @@ reg = <0x20000 DT_SIZE_K(1344)>; }; - slot0_appcpu_partition: partition@170000 { - label = "image-0-appcpu"; - reg = <0x170000 DT_SIZE_K(512)>; + slot1_partition: partition@170000 { + label = "image-1"; + reg = <0x170000 DT_SIZE_K(1344)>; }; - slot1_partition: partition@1F0000 { - label = "image-1"; - reg = <0x1F0000 DT_SIZE_K(1344)>; + slot0_appcpu_partition: partition@2c0000 { + label = "image-0-appcpu"; + reg = <0x2C0000 DT_SIZE_K(448)>; }; - slot1_appcpu_partition: partition@340000 { + slot1_appcpu_partition: partition@330000 { label = "image-1-appcpu"; - reg = <0x340000 DT_SIZE_K(512)>; + reg = <0x330000 DT_SIZE_K(448)>; + }; + + slot0_lpcore_partition: partition@3a0000 { + label = "image-0-lpcore"; + reg = <0x3A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@3a8000 { + label = "image-1-lpcore"; + reg = <0x3A8000 DT_SIZE_K(32)>; }; - storage_partition: partition@3C0000 { + storage_partition: partition@3b0000 { label = "storage"; - reg = <0x3C0000 DT_SIZE_K(128)>; + reg = <0x3B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@3E0000 { - label = "image-scratch"; - reg = <0x3E0000 DT_SIZE_K(64)>; + scratch_partition: partition@3e0000 { + label = "image-scratch"; + reg = <0x3E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@3F0000 { - label = "coredump-partition"; - reg = <0x3F0000 DT_SIZE_K(4)>; + coredump_partition: partition@3ff000 { + label = "coredump"; + reg = <0x3FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x3FFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_amp_8M.dtsi b/dts/common/espressif/partitions_0x0_amp_8M.dtsi index bbba09092e79b..e854d854780e3 100644 --- a/dts/common/espressif/partitions_0x0_amp_8M.dtsi +++ b/dts/common/espressif/partitions_0x0_amp_8M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 8MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,42 +12,56 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(3136)>; + reg = <0x20000 DT_SIZE_K(2880)>; }; - slot0_appcpu_partition: partition@330000 { - label = "image-0-appcpu"; - reg = <0x330000 DT_SIZE_K(768)>; + slot1_partition: partition@2f0000 { + label = "image-1"; + reg = <0x2F0000 DT_SIZE_K(2880)>; }; - slot1_partition: partition@3F0000 { - label = "image-1"; - reg = <0x3F0000 DT_SIZE_K(3136)>; + slot0_appcpu_partition: partition@5c0000 { + label = "image-0-appcpu"; + reg = <0x5C0000 DT_SIZE_K(960)>; }; - slot1_appcpu_partition: partition@700000 { + slot1_appcpu_partition: partition@6b0000 { label = "image-1-appcpu"; - reg = <0x700000 DT_SIZE_K(768)>; + reg = <0x6B0000 DT_SIZE_K(960)>; + }; + + slot0_lpcore_partition: partition@7a0000 { + label = "image-0-lpcore"; + reg = <0x7A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@7a8000 { + label = "image-1-lpcore"; + reg = <0x7A8000 DT_SIZE_K(32)>; }; - storage_partition: partition@7C0000 { + storage_partition: partition@7b0000 { label = "storage"; - reg = <0x7C0000 DT_SIZE_K(128)>; + reg = <0x7B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@7E0000 { - label = "image-scratch"; - reg = <0x7E0000 DT_SIZE_K(64)>; + scratch_partition: partition@7e0000 { + label = "image-scratch"; + reg = <0x7E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@7F0000 { - label = "coredump-partition"; - reg = <0x7F0000 DT_SIZE_K(4)>; + coredump_partition: partition@7ff000 { + label = "coredump"; + reg = <0x7FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x7FFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_default.dtsi b/dts/common/espressif/partitions_0x0_default.dtsi index 851fffe886b07..5f51a09260712 100644 --- a/dts/common/espressif/partitions_0x0_default.dtsi +++ b/dts/common/espressif/partitions_0x0_default.dtsi @@ -1,7 +1,7 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - #include +#include diff --git a/dts/common/espressif/partitions_0x0_default_16M.dtsi b/dts/common/espressif/partitions_0x0_default_16M.dtsi index d4b01753d0bd1..1f595c1a03005 100644 --- a/dts/common/espressif/partitions_0x0_default_16M.dtsi +++ b/dts/common/espressif/partitions_0x0_default_16M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 16MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(8000)>; + reg = <0x20000 DT_SIZE_K(7936)>; }; - slot1_partition: partition@7F0000 { + slot1_partition: partition@7e0000 { label = "image-1"; - reg = <0x7F0000 DT_SIZE_K(8000)>; + reg = <0x7E0000 DT_SIZE_K(7936)>; }; - storage_partition: partition@FC0000 { + slot0_lpcore_partition: partition@fa0000 { + label = "image-0-lpcore"; + reg = <0xFA0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@fa8000 { + label = "image-1-lpcore"; + reg = <0xFA8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@fb0000 { label = "storage"; - reg = <0xFC0000 DT_SIZE_K(128)>; + reg = <0xFB0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@FE0000 { - label = "image-scratch"; - reg = <0xFE0000 DT_SIZE_K(64)>; + scratch_partition: partition@fe0000 { + label = "image-scratch"; + reg = <0xFE0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@FF0000 { - label = "coredump-partition"; - reg = <0xFF0000 DT_SIZE_K(4)>; + coredump_partition: partition@fff000 { + label = "coredump"; + reg = <0xFFF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0xFFFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_default_2M.dtsi b/dts/common/espressif/partitions_0x0_default_2M.dtsi index 56e49951c5339..759a17c82f6ae 100644 --- a/dts/common/espressif/partitions_0x0_default_2M.dtsi +++ b/dts/common/espressif/partitions_0x0_default_2M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 2MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(832)>; + reg = <0x20000 DT_SIZE_K(768)>; }; - slot1_partition: partition@F0000 { + slot1_partition: partition@e0000 { label = "image-1"; - reg = <0xF0000 DT_SIZE_K(832)>; + reg = <0xE0000 DT_SIZE_K(768)>; }; - storage_partition: partition@1C0000 { + slot0_lpcore_partition: partition@1a0000 { + label = "image-0-lpcore"; + reg = <0x1A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@1a8000 { + label = "image-1-lpcore"; + reg = <0x1A8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@1b0000 { label = "storage"; - reg = <0x1C0000 DT_SIZE_K(128)>; + reg = <0x1B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@1E0000 { - label = "image-scratch"; - reg = <0x1E0000 DT_SIZE_K(64)>; + scratch_partition: partition@1e0000 { + label = "image-scratch"; + reg = <0x1E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@1F0000 { - label = "coredump-partition"; - reg = <0x1F0000 DT_SIZE_K(4)>; + coredump_partition: partition@1ff000 { + label = "coredump"; + reg = <0x1FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x1FFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_default_32M.dtsi b/dts/common/espressif/partitions_0x0_default_32M.dtsi index 710ea747eb91b..77fd4a6919eed 100644 --- a/dts/common/espressif/partitions_0x0_default_32M.dtsi +++ b/dts/common/espressif/partitions_0x0_default_32M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 32MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(16192)>; + reg = <0x20000 DT_SIZE_K(16128)>; }; - slot1_partition: partition@FF0000 { + slot1_partition: partition@fe0000 { label = "image-1"; - reg = <0xFF0000 DT_SIZE_K(16192)>; + reg = <0xFE0000 DT_SIZE_K(16128)>; }; - storage_partition: partition@1FC0000 { + slot0_lpcore_partition: partition@1fa0000 { + label = "image-0-lpcore"; + reg = <0x1FA0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@1fa8000 { + label = "image-1-lpcore"; + reg = <0x1FA8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@1fb0000 { label = "storage"; - reg = <0x1FC0000 DT_SIZE_K(128)>; + reg = <0x1FB0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@1FE0000 { - label = "image-scratch"; - reg = <0x1FE0000 DT_SIZE_K(64)>; + scratch_partition: partition@1fe0000 { + label = "image-scratch"; + reg = <0x1FE0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@1FF0000 { - label = "coredump-partition"; - reg = <0x1FF0000 DT_SIZE_K(4)>; + coredump_partition: partition@1fff000 { + label = "coredump"; + reg = <0x1FFF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x1FFFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_default_4M.dtsi b/dts/common/espressif/partitions_0x0_default_4M.dtsi index d72be3994c616..c82ecb50fba09 100644 --- a/dts/common/espressif/partitions_0x0_default_4M.dtsi +++ b/dts/common/espressif/partitions_0x0_default_4M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 4MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(1856)>; + reg = <0x20000 DT_SIZE_K(1792)>; }; - slot1_partition: partition@1F0000 { + slot1_partition: partition@1e0000 { label = "image-1"; - reg = <0x1F0000 DT_SIZE_K(1856)>; + reg = <0x1E0000 DT_SIZE_K(1792)>; }; - storage_partition: partition@3C0000 { + slot0_lpcore_partition: partition@3a0000 { + label = "image-0-lpcore"; + reg = <0x3A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@3a8000 { + label = "image-1-lpcore"; + reg = <0x3A8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@3b0000 { label = "storage"; - reg = <0x3C0000 DT_SIZE_K(128)>; + reg = <0x3B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@3E0000 { + scratch_partition: partition@3e0000 { label = "image-scratch"; - reg = <0x3E0000 DT_SIZE_K(64)>; + reg = <0x3E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@3F0000 { - label = "coredump-partition"; - reg = <0x3F0000 DT_SIZE_K(4)>; + coredump_partition: partition@3ff000 { + label = "coredump"; + reg = <0x3FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x3FFFFF + */ diff --git a/dts/common/espressif/partitions_0x0_default_8M.dtsi b/dts/common/espressif/partitions_0x0_default_8M.dtsi index f9b43664b870b..8087050765fbe 100644 --- a/dts/common/espressif/partitions_0x0_default_8M.dtsi +++ b/dts/common/espressif/partitions_0x0_default_8M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 8MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x0 DT_SIZE_K(64)>; + reg = <0x0 DT_SIZE_K(128)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(3904)>; + reg = <0x20000 DT_SIZE_K(3840)>; }; - slot1_partition: partition@3F0000 { + slot1_partition: partition@3e0000 { label = "image-1"; - reg = <0x3F0000 DT_SIZE_K(3904)>; + reg = <0x3E0000 DT_SIZE_K(3840)>; }; - storage_partition: partition@7C0000 { + slot0_lpcore_partition: partition@7a0000 { + label = "image-0-lpcore"; + reg = <0x7A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@7a8000 { + label = "image-1-lpcore"; + reg = <0x7A8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@7b0000 { label = "storage"; - reg = <0x7C0000 DT_SIZE_K(128)>; + reg = <0x7B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@7E0000 { - label = "image-scratch"; - reg = <0x7E0000 DT_SIZE_K(64)>; + scratch_partition: partition@7e0000 { + label = "image-scratch"; + reg = <0x7E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@7F0000 { - label = "coredump-partition"; - reg = <0x7F0000 DT_SIZE_K(4)>; + coredump_partition: partition@7ff000 { + label = "coredump"; + reg = <0x7FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x7FFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_amp.dtsi b/dts/common/espressif/partitions_0x1000_amp.dtsi index 13e950cb3cd00..8f51c547bf92f 100644 --- a/dts/common/espressif/partitions_0x1000_amp.dtsi +++ b/dts/common/espressif/partitions_0x1000_amp.dtsi @@ -1,7 +1,7 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - #include +#include diff --git a/dts/common/espressif/partitions_0x1000_amp_16M.dtsi b/dts/common/espressif/partitions_0x1000_amp_16M.dtsi index c994ddd762a67..3a6e769d919fe 100644 --- a/dts/common/espressif/partitions_0x1000_amp_16M.dtsi +++ b/dts/common/espressif/partitions_0x1000_amp_16M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 16MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,42 +12,56 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(6080)>; + reg = <0x20000 DT_SIZE_K(5952)>; }; - slot0_appcpu_partition: partition@610000 { - label = "image-0-appcpu"; - reg = <0x610000 DT_SIZE_K(1920)>; + slot1_partition: partition@5f0000 { + label = "image-1"; + reg = <0x5F0000 DT_SIZE_K(5952)>; }; - slot1_partition: partition@7F0000 { - label = "image-1"; - reg = <0x7F0000 DT_SIZE_K(6080)>; + slot0_appcpu_partition: partition@bc0000 { + label = "image-0-appcpu"; + reg = <0xBC0000 DT_SIZE_K(1984)>; }; - slot1_appcpu_partition: partition@DE0000 { + slot1_appcpu_partition: partition@db0000 { label = "image-1-appcpu"; - reg = <0xDE0000 DT_SIZE_K(1920)>; + reg = <0xDB0000 DT_SIZE_K(1984)>; + }; + + slot0_lpcore_partition: partition@fa0000 { + label = "image-0-lpcore"; + reg = <0xFA0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@fa8000 { + label = "image-1-lpcore"; + reg = <0xFA8000 DT_SIZE_K(32)>; }; - storage_partition: partition@FC0000 { + storage_partition: partition@fb0000 { label = "storage"; - reg = <0xFC0000 DT_SIZE_K(128)>; + reg = <0xFB0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@FE0000 { - label = "image-scratch"; - reg = <0xFE0000 DT_SIZE_K(64)>; + scratch_partition: partition@fe0000 { + label = "image-scratch"; + reg = <0xFE0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@FF0000 { - label = "coredump-partition"; - reg = <0xFF0000 DT_SIZE_K(4)>; + coredump_partition: partition@fff000 { + label = "coredump"; + reg = <0xFFF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0xFFFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_amp_2M.dtsi b/dts/common/espressif/partitions_0x1000_amp_2M.dtsi index 1c8e472cb0420..aba0c5be16c6d 100644 --- a/dts/common/espressif/partitions_0x1000_amp_2M.dtsi +++ b/dts/common/espressif/partitions_0x1000_amp_2M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 2MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,7 +12,7 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { @@ -21,34 +20,48 @@ reg = <0x20000 DT_SIZE_K(576)>; }; - slot0_appcpu_partition: partition@B0000 { - label = "image-0-appcpu"; - reg = <0xB0000 DT_SIZE_K(256)>; + slot1_partition: partition@b0000 { + label = "image-1"; + reg = <0xB0000 DT_SIZE_K(576)>; }; - slot1_partition: partition@F0000 { - label = "image-1"; - reg = <0xF0000 DT_SIZE_K(576)>; + slot0_appcpu_partition: partition@140000 { + label = "image-0-appcpu"; + reg = <0x140000 DT_SIZE_K(192)>; }; - slot1_appcpu_partition: partition@180000 { + slot1_appcpu_partition: partition@170000 { label = "image-1-appcpu"; - reg = <0x180000 DT_SIZE_K(256)>; + reg = <0x170000 DT_SIZE_K(192)>; + }; + + slot0_lpcore_partition: partition@1a0000 { + label = "image-0-lpcore"; + reg = <0x1A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@1a8000 { + label = "image-1-lpcore"; + reg = <0x1A8000 DT_SIZE_K(32)>; }; - storage_partition: partition@1C0000 { + storage_partition: partition@1b0000 { label = "storage"; - reg = <0x1C0000 DT_SIZE_K(128)>; + reg = <0x1B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@1E0000 { + scratch_partition: partition@1e0000 { label = "image-scratch"; - reg = <0x1E0000 DT_SIZE_K(64)>; + reg = <0x1E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@1F0000 { - label = "coredump-partition"; - reg = <0x1F0000 DT_SIZE_K(4)>; + coredump_partition: partition@1ff000 { + label = "coredump"; + reg = <0x1FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x1FFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_amp_32M.dtsi b/dts/common/espressif/partitions_0x1000_amp_32M.dtsi index 7006269f994f2..1863dc11bb80e 100644 --- a/dts/common/espressif/partitions_0x1000_amp_32M.dtsi +++ b/dts/common/espressif/partitions_0x1000_amp_32M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 32MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,42 +12,56 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(12352)>; + reg = <0x20000 DT_SIZE_K(12096)>; }; - slot0_appcpu_partition: partition@C30000 { - label = "image-0-appcpu"; - reg = <0xC24000 DT_SIZE_K(3840)>; + slot1_partition: partition@bf0000 { + label = "image-1"; + reg = <0xBF0000 DT_SIZE_K(12096)>; }; - slot1_partition: partition@FF0000 { - label = "image-1"; - reg = <0xFF0000 DT_SIZE_K(12352)>; + slot0_appcpu_partition: partition@17c0000 { + label = "image-0-appcpu"; + reg = <0x17C0000 DT_SIZE_K(4032)>; }; - slot1_appcpu_partition: partition@1C00000 { + slot1_appcpu_partition: partition@1bb0000 { label = "image-1-appcpu"; - reg = <0x1C00000 DT_SIZE_K(3840)>; + reg = <0x1BB0000 DT_SIZE_K(4032)>; + }; + + slot0_lpcore_partition: partition@1fa0000 { + label = "image-0-lpcore"; + reg = <0x1FA0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@1fa8000 { + label = "image-1-lpcore"; + reg = <0x1FA8000 DT_SIZE_K(32)>; }; - storage_partition: partition@1FC0000 { + storage_partition: partition@1fb0000 { label = "storage"; - reg = <0x1FC0000 DT_SIZE_K(128)>; + reg = <0x1FB0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@1FE0000 { - label = "image-scratch"; - reg = <0x1FE0000 DT_SIZE_K(64)>; + scratch_partition: partition@1fe0000 { + label = "image-scratch"; + reg = <0x1FE0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@1FF0000 { - label = "coredump-partition"; - reg = <0x1FF0000 DT_SIZE_K(4)>; + coredump_partition: partition@1fff000 { + label = "coredump"; + reg = <0x1FFF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x1FFFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_amp_4M.dtsi b/dts/common/espressif/partitions_0x1000_amp_4M.dtsi index 1747b52d52339..84bfe8d2e371a 100644 --- a/dts/common/espressif/partitions_0x1000_amp_4M.dtsi +++ b/dts/common/espressif/partitions_0x1000_amp_4M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 4MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,7 +12,7 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { @@ -21,34 +20,48 @@ reg = <0x20000 DT_SIZE_K(1344)>; }; - slot0_appcpu_partition: partition@170000 { - label = "image-0-appcpu"; - reg = <0x170000 DT_SIZE_K(512)>; + slot1_partition: partition@170000 { + label = "image-1"; + reg = <0x170000 DT_SIZE_K(1344)>; }; - slot1_partition: partition@1F0000 { - label = "image-1"; - reg = <0x1F0000 DT_SIZE_K(1344)>; + slot0_appcpu_partition: partition@2c0000 { + label = "image-0-appcpu"; + reg = <0x2C0000 DT_SIZE_K(448)>; }; - slot1_appcpu_partition: partition@340000 { + slot1_appcpu_partition: partition@330000 { label = "image-1-appcpu"; - reg = <0x340000 DT_SIZE_K(512)>; + reg = <0x330000 DT_SIZE_K(448)>; + }; + + slot0_lpcore_partition: partition@3a0000 { + label = "image-0-lpcore"; + reg = <0x3A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@3a8000 { + label = "image-1-lpcore"; + reg = <0x3A8000 DT_SIZE_K(32)>; }; - storage_partition: partition@3C0000 { + storage_partition: partition@3b0000 { label = "storage"; - reg = <0x3C0000 DT_SIZE_K(128)>; + reg = <0x3B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@3E0000 { - label = "image-scratch"; - reg = <0x3E0000 DT_SIZE_K(64)>; + scratch_partition: partition@3e0000 { + label = "image-scratch"; + reg = <0x3E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@3F0000 { - label = "coredump-partition"; - reg = <0x3F0000 DT_SIZE_K(4)>; + coredump_partition: partition@3ff000 { + label = "coredump"; + reg = <0x3FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x3FFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_amp_8M.dtsi b/dts/common/espressif/partitions_0x1000_amp_8M.dtsi index afdcdbc284002..87c94061d40c8 100644 --- a/dts/common/espressif/partitions_0x1000_amp_8M.dtsi +++ b/dts/common/espressif/partitions_0x1000_amp_8M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 8MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,42 +12,56 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(3136)>; + reg = <0x20000 DT_SIZE_K(2880)>; }; - slot0_appcpu_partition: partition@330000 { - label = "image-0-appcpu"; - reg = <0x330000 DT_SIZE_K(768)>; + slot1_partition: partition@2f0000 { + label = "image-1"; + reg = <0x2F0000 DT_SIZE_K(2880)>; }; - slot1_partition: partition@3F0000 { - label = "image-1"; - reg = <0x3F0000 DT_SIZE_K(3136)>; + slot0_appcpu_partition: partition@5c0000 { + label = "image-0-appcpu"; + reg = <0x5C0000 DT_SIZE_K(960)>; }; - slot1_appcpu_partition: partition@700000 { + slot1_appcpu_partition: partition@6b0000 { label = "image-1-appcpu"; - reg = <0x700000 DT_SIZE_K(768)>; + reg = <0x6B0000 DT_SIZE_K(960)>; + }; + + slot0_lpcore_partition: partition@7a0000 { + label = "image-0-lpcore"; + reg = <0x7A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@7a8000 { + label = "image-1-lpcore"; + reg = <0x7A8000 DT_SIZE_K(32)>; }; - storage_partition: partition@7C0000 { + storage_partition: partition@7b0000 { label = "storage"; - reg = <0x7C0000 DT_SIZE_K(128)>; + reg = <0x7B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@7E0000 { - label = "image-scratch"; - reg = <0x7E0000 DT_SIZE_K(64)>; + scratch_partition: partition@7e0000 { + label = "image-scratch"; + reg = <0x7E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@7F0000 { - label = "coredump-partition"; - reg = <0x7F0000 DT_SIZE_K(4)>; + coredump_partition: partition@7ff000 { + label = "coredump"; + reg = <0x7FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x7FFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_default.dtsi b/dts/common/espressif/partitions_0x1000_default.dtsi index 834bb6f736804..54fa797e6bcfc 100644 --- a/dts/common/espressif/partitions_0x1000_default.dtsi +++ b/dts/common/espressif/partitions_0x1000_default.dtsi @@ -1,7 +1,7 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - #include +#include diff --git a/dts/common/espressif/partitions_0x1000_default_16M.dtsi b/dts/common/espressif/partitions_0x1000_default_16M.dtsi index 84663ecafd187..8150760ffbe27 100644 --- a/dts/common/espressif/partitions_0x1000_default_16M.dtsi +++ b/dts/common/espressif/partitions_0x1000_default_16M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 16MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(8000)>; + reg = <0x20000 DT_SIZE_K(7936)>; }; - slot1_partition: partition@7F0000 { + slot1_partition: partition@7e0000 { label = "image-1"; - reg = <0x7F0000 DT_SIZE_K(8000)>; + reg = <0x7E0000 DT_SIZE_K(7936)>; }; - storage_partition: partition@FC0000 { + slot0_lpcore_partition: partition@fa0000 { + label = "image-0-lpcore"; + reg = <0xFA0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@fa8000 { + label = "image-1-lpcore"; + reg = <0xFA8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@fb0000 { label = "storage"; - reg = <0xFC0000 DT_SIZE_K(128)>; + reg = <0xFB0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@FE0000 { - label = "image-scratch"; - reg = <0xFE0000 DT_SIZE_K(64)>; + scratch_partition: partition@fe0000 { + label = "image-scratch"; + reg = <0xFE0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@FF0000 { - label = "coredump-partition"; - reg = <0xFF0000 DT_SIZE_K(4)>; + coredump_partition: partition@fff000 { + label = "coredump"; + reg = <0xFFF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0xFFFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_default_2M.dtsi b/dts/common/espressif/partitions_0x1000_default_2M.dtsi index 08b1caf3044ec..b32f686dd5bee 100644 --- a/dts/common/espressif/partitions_0x1000_default_2M.dtsi +++ b/dts/common/espressif/partitions_0x1000_default_2M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 2MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(832)>; + reg = <0x20000 DT_SIZE_K(768)>; }; - slot1_partition: partition@F0000 { + slot1_partition: partition@e0000 { label = "image-1"; - reg = <0xF0000 DT_SIZE_K(832)>; + reg = <0xE0000 DT_SIZE_K(768)>; }; - storage_partition: partition@1C0000 { + slot0_lpcore_partition: partition@1a0000 { + label = "image-0-lpcore"; + reg = <0x1A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@1a8000 { + label = "image-1-lpcore"; + reg = <0x1A8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@1b0000 { label = "storage"; - reg = <0x1C0000 DT_SIZE_K(128)>; + reg = <0x1B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@1E0000 { - label = "image-scratch"; - reg = <0x1E0000 DT_SIZE_K(64)>; + scratch_partition: partition@1e0000 { + label = "image-scratch"; + reg = <0x1E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@1F0000 { - label = "coredump-partition"; - reg = <0x1F0000 DT_SIZE_K(4)>; + coredump_partition: partition@1ff000 { + label = "coredump"; + reg = <0x1FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x1FFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_default_32M.dtsi b/dts/common/espressif/partitions_0x1000_default_32M.dtsi index 4e7cc4511bb96..4139d18976d9a 100644 --- a/dts/common/espressif/partitions_0x1000_default_32M.dtsi +++ b/dts/common/espressif/partitions_0x1000_default_32M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 32MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(16192)>; + reg = <0x20000 DT_SIZE_K(16128)>; }; - slot1_partition: partition@FF0000 { + slot1_partition: partition@fe0000 { label = "image-1"; - reg = <0xFF0000 DT_SIZE_K(16192)>; + reg = <0xFE0000 DT_SIZE_K(16128)>; }; - storage_partition: partition@1FC0000 { + slot0_lpcore_partition: partition@1fa0000 { + label = "image-0-lpcore"; + reg = <0x1FA0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@1fa8000 { + label = "image-1-lpcore"; + reg = <0x1FA8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@1fb0000 { label = "storage"; - reg = <0x1FC0000 DT_SIZE_K(128)>; + reg = <0x1FB0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@1FE0000 { - label = "image-scratch"; - reg = <0x1FE0000 DT_SIZE_K(64)>; + scratch_partition: partition@1fe0000 { + label = "image-scratch"; + reg = <0x1FE0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@1FF0000 { - label = "coredump-partition"; - reg = <0x1FF0000 DT_SIZE_K(4)>; + coredump_partition: partition@1fff000 { + label = "coredump"; + reg = <0x1FFF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x1FFFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_default_4M.dtsi b/dts/common/espressif/partitions_0x1000_default_4M.dtsi index bf5d09fdc4860..61282f2ae0966 100644 --- a/dts/common/espressif/partitions_0x1000_default_4M.dtsi +++ b/dts/common/espressif/partitions_0x1000_default_4M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 4MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(1856)>; + reg = <0x20000 DT_SIZE_K(1792)>; }; - slot1_partition: partition@1F0000 { + slot1_partition: partition@1e0000 { label = "image-1"; - reg = <0x1F0000 DT_SIZE_K(1856)>; + reg = <0x1E0000 DT_SIZE_K(1792)>; }; - storage_partition: partition@3C0000 { + slot0_lpcore_partition: partition@3a0000 { + label = "image-0-lpcore"; + reg = <0x3A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@3a8000 { + label = "image-1-lpcore"; + reg = <0x3A8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@3b0000 { label = "storage"; - reg = <0x3C0000 DT_SIZE_K(128)>; + reg = <0x3B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@3E0000 { - label = "image-scratch"; - reg = <0x3E0000 DT_SIZE_K(64)>; + scratch_partition: partition@3e0000 { + label = "image-scratch"; + reg = <0x3E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@3F0000 { - label = "coredump-partition"; - reg = <0x3F0000 DT_SIZE_K(4)>; + coredump_partition: partition@3ff000 { + label = "coredump"; + reg = <0x3FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x3FFFFF + */ diff --git a/dts/common/espressif/partitions_0x1000_default_8M.dtsi b/dts/common/espressif/partitions_0x1000_default_8M.dtsi index eaf0511cf272f..301644b6befbd 100644 --- a/dts/common/espressif/partitions_0x1000_default_8M.dtsi +++ b/dts/common/espressif/partitions_0x1000_default_8M.dtsi @@ -1,10 +1,9 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ - /* 8MB flash partition table */ &flash0 { partitions { compatible = "fixed-partitions"; @@ -13,32 +12,46 @@ boot_partition: partition@1000 { label = "mcuboot"; - reg = <0x1000 DT_SIZE_K(60)>; + reg = <0x1000 DT_SIZE_K(124)>; }; slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(3904)>; + reg = <0x20000 DT_SIZE_K(3840)>; }; - slot1_partition: partition@3F0000 { + slot1_partition: partition@3e0000 { label = "image-1"; - reg = <0x3F0000 DT_SIZE_K(3904)>; + reg = <0x3E0000 DT_SIZE_K(3840)>; }; - storage_partition: partition@7C0000 { + slot0_lpcore_partition: partition@7a0000 { + label = "image-0-lpcore"; + reg = <0x7A0000 DT_SIZE_K(32)>; + }; + + slot1_lpcore_partition: partition@7a8000 { + label = "image-1-lpcore"; + reg = <0x7A8000 DT_SIZE_K(32)>; + }; + + storage_partition: partition@7b0000 { label = "storage"; - reg = <0x7C0000 DT_SIZE_K(128)>; + reg = <0x7B0000 DT_SIZE_K(192)>; }; - scratch_partition: partition@7E0000 { - label = "image-scratch"; - reg = <0x7E0000 DT_SIZE_K(64)>; + scratch_partition: partition@7e0000 { + label = "image-scratch"; + reg = <0x7E0000 DT_SIZE_K(124)>; }; - coredump_partition: partition@7F0000 { - label = "coredump-partition"; - reg = <0x7F0000 DT_SIZE_K(4)>; + coredump_partition: partition@7ff000 { + label = "coredump"; + reg = <0x7FF000 DT_SIZE_K(4)>; }; }; }; + +/* Remaining flash size is 0kB + * Last used address is 0x7FFFFF + */ diff --git a/dts/common/freq.h b/dts/common/freq.h index b6e83b3771601..10522bcd175c0 100644 --- a/dts/common/freq.h +++ b/dts/common/freq.h @@ -4,10 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __DT_FREQ_H -#define __DT_FREQ_H +#ifndef ZEPHYR_DTS_COMMON_FREQ_H_ +#define ZEPHYR_DTS_COMMON_FREQ_H_ #define DT_FREQ_K(x) ((x) * 1000) -#define DT_FREQ_M(x) ((x) * 1000 * 1000) +#define DT_FREQ_M(x) (DT_FREQ_K(x) * 1000) -#endif /* __DT_FREQ_H */ +#endif /* ZEPHYR_DTS_COMMON_FREQ_H_ */ diff --git a/dts/common/mem.h b/dts/common/mem.h index 49c23c69f3270..db35f8e3770df 100644 --- a/dts/common/mem.h +++ b/dts/common/mem.h @@ -4,15 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __DT_MEM_H -#define __DT_MEM_H +#ifndef ZEPHYR_DTS_COMMON_MEM_H_ +#define ZEPHYR_DTS_COMMON_MEM_H_ #define DT_SIZE_K(x) ((x) * 1024) -#define DT_SIZE_M(x) ((x) * 1024 * 1024) +#define DT_SIZE_M(x) (DT_SIZE_K(x) * 1024) /* concatenate the values of the arguments into one */ #define _DT_DO_CONCAT(x, y) x ## y #define DT_ADDR(a) _DT_DO_CONCAT(0x, a) -#endif /* __DT_MEM_H */ +#endif /* ZEPHYR_DTS_COMMON_MEM_H_ */ diff --git a/dts/common/nordic/nrf52840_partition.dtsi b/dts/common/nordic/nrf52840_partition.dtsi index 8852ab5b15ad6..1f6894e07f6e9 100644 --- a/dts/common/nordic/nrf52840_partition.dtsi +++ b/dts/common/nordic/nrf52840_partition.dtsi @@ -22,10 +22,12 @@ label = "mcuboot"; reg = <0x00000000 0x0000C000>; }; + slot0_partition: partition@c000 { label = "image-0"; reg = <0x0000C000 0x00077000>; }; + slot1_partition: partition@83000 { label = "image-1"; reg = <0x00083000 0x00075000>; diff --git a/dts/common/nordic/nrf52840_partition_uf2_sdv6.dtsi b/dts/common/nordic/nrf52840_partition_uf2_sdv6.dtsi index 37387fd782f11..9c12d7f82f593 100644 --- a/dts/common/nordic/nrf52840_partition_uf2_sdv6.dtsi +++ b/dts/common/nordic/nrf52840_partition_uf2_sdv6.dtsi @@ -35,6 +35,7 @@ read-only; reg = <0x00000000 0x00026000>; }; + code_partition: partition@26000 { label = "Application"; reg = <0x00026000 0x000C6000>; diff --git a/dts/common/nordic/nrf52840_partition_uf2_sdv7.dtsi b/dts/common/nordic/nrf52840_partition_uf2_sdv7.dtsi index e6aaf73ca140e..c7f5e0d5e20e6 100644 --- a/dts/common/nordic/nrf52840_partition_uf2_sdv7.dtsi +++ b/dts/common/nordic/nrf52840_partition_uf2_sdv7.dtsi @@ -33,6 +33,7 @@ read-only; reg = <0x00000000 0x00027000>; }; + code_partition: partition@27000 { label = "Application"; reg = <0x00027000 0x000C5000>; diff --git a/dts/common/nordic/nrf5340_cpuapp_partition.dtsi b/dts/common/nordic/nrf5340_cpuapp_partition.dtsi index b1a1095b3553c..621c35596e3be 100644 --- a/dts/common/nordic/nrf5340_cpuapp_partition.dtsi +++ b/dts/common/nordic/nrf5340_cpuapp_partition.dtsi @@ -33,34 +33,42 @@ label = "mcuboot"; reg = <0x00000000 0x10000>; }; + slot0_partition: partition@10000 { label = "image-0"; reg = <0x00010000 0x40000>; }; + slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; reg = <0x00050000 0x30000>; }; + slot1_partition: partition@80000 { label = "image-1"; reg = <0x00080000 0x40000>; }; + slot1_ns_partition: partition@c0000 { label = "image-1-nonsecure"; reg = <0x000c0000 0x30000>; }; + tfm_ps_partition: partition@f0000 { label = "tfm-ps"; reg = <0x000f0000 0x00004000>; }; + tfm_its_partition: partition@f4000 { label = "tfm-its"; reg = <0x000f4000 0x00002000>; }; + tfm_otp_partition: partition@f6000 { label = "tfm-otp"; reg = <0x000f6000 0x00002000>; }; + storage_partition: partition@f8000 { label = "storage"; reg = <0x000f8000 0x00008000>; diff --git a/dts/common/nordic/nrf5340_shared_sram_partition.dtsi b/dts/common/nordic/nrf5340_shared_sram_partition.dtsi index 8dc217ceae9ea..a5dc3489e893e 100644 --- a/dts/common/nordic/nrf5340_shared_sram_partition.dtsi +++ b/dts/common/nordic/nrf5340_shared_sram_partition.dtsi @@ -14,9 +14,7 @@ * the memory range allocated to the non-secure image (sram0_ns). * * By default the last 64 kB of application core SRAM is allocated as shared - * memory (sram0_shared) which is divided in: - * - 32 kB CPUAPP to CPUNET communication (cpuapp_cpunet_ipc_shm) - * - 32 kB CPUNET to CPUAPP communication (cpunet_cpuapp_ipc_shm) + * memory (sram0_shared). */ / { @@ -30,18 +28,8 @@ ranges; sram0_shared: memory@20070000 { - #address-cells = <1>; - #size-cells = <1>; /* Last 64 kB of sram0 */ reg = <0x20070000 0x10000>; - - cpuapp_cpunet_ipc_shm: memory@20070000 { - reg = <0x20070000 DT_SIZE_K(32)>; - }; - - cpunet_cpuapp_ipc_shm: memory@20078000 { - reg = <0x20078000 DT_SIZE_K(32)>; - }; }; }; }; diff --git a/dts/common/nordic/nrf54h20.dtsi b/dts/common/nordic/nrf54h20.dtsi index 085aba43c86d8..3dc8afb707189 100644 --- a/dts/common/nordic/nrf54h20.dtsi +++ b/dts/common/nordic/nrf54h20.dtsi @@ -84,7 +84,7 @@ device_type = "cpu"; clock-frequency = ; riscv,isa = "rv32emc"; - nordic,bus-width = <64>; + nordic,bus-width = <32>; cpuflpr_vevif_rx: mailbox { compatible = "nordic,nrf-vevif-task-rx"; @@ -182,10 +182,14 @@ }; hsfll120: hsfll120 { - compatible = "fixed-clock"; + compatible = "nordic,nrf-hsfll-global"; clocks = <&fll16m>; #clock-cells = <0>; - clock-frequency = ; + clock-frequency = <320000000>; + supported-clock-frequencies = <64000000 + 128000000 + 256000000 + 320000000>; }; lfclk: lfclk { @@ -220,7 +224,15 @@ cpuapp_uicr: uicr@fff8000 { compatible = "nordic,nrf-uicr-v2"; reg = <0xfff8000 DT_SIZE_K(2)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xfff8000 DT_SIZE_K(2)>; domain = <2>; + + bicr: bicr@7b0 { + compatible = "nordic,nrf-bicr"; + reg = <0x7b0 48>; + }; }; cpurad_uicr: uicr@fffa000 { @@ -254,10 +266,11 @@ cpuapp_peripherals: peripheral@52000000 { #address-cells = <1>; #size-cells = <1>; + reg = <0x52000000 0x1000000>; ranges = <0x0 0x52000000 0x1000000>; cpuapp_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>; @@ -311,7 +324,7 @@ ranges = <0x0 0x53000000 0x1000000>; cpurad_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>; @@ -372,9 +385,8 @@ status = "disabled"; cc-num = <8>; interrupts = <40 NRF_DEFAULT_IRQ_PRIORITY>; - clocks = <&fll16m>; + clocks = <&hfxo>; max-bit-width = <32>; - max-frequency = ; prescaler = <0>; }; @@ -384,9 +396,8 @@ status = "disabled"; cc-num = <8>; interrupts = <41 NRF_DEFAULT_IRQ_PRIORITY>; - clocks = <&fll16m>; + clocks = <&hfxo>; max-bit-width = <32>; - max-frequency = ; prescaler = <0>; }; @@ -396,9 +407,8 @@ status = "disabled"; cc-num = <8>; interrupts = <42 NRF_DEFAULT_IRQ_PRIORITY>; - clocks = <&fll16m>; + clocks = <&hfxo>; max-bit-width = <32>; - max-frequency = ; prescaler = <0>; }; @@ -463,6 +473,7 @@ tdd_peripherals: peripheral@bf000000 { #address-cells = <1>; #size-cells = <1>; + reg = <0xbf000000 0x1000000>; ranges = <0x0 0xbf000000 0x1000000>; tbm: tbm@3000 { @@ -482,6 +493,7 @@ global_peripherals: peripheral@5f000000 { #address-cells = <1>; #size-cells = <1>; + reg = <0x5f000000 0x1000000>; ranges = <0x0 0x5f000000 0x1000000>; usbhs: usbhs@86000 { @@ -590,7 +602,8 @@ reg = <0x8d8000 0x400>, <0x2fbef800 0x800>, <0x2fbe8000 0x7800>; reg-names = "wrapper", "m_can", "message_ram"; interrupts = <216 NRF_DEFAULT_IRQ_PRIORITY>; - clocks = <&canpll>; + clocks = <&canpll>, <&hsfll120>; + clock-names = "auxpll", "hsfll"; power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; status = "disabled"; @@ -611,7 +624,7 @@ interrupts = <226 NRF_DEFAULT_IRQ_PRIORITY>; power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; max-bit-width = <32>; - max-frequency = ; + clocks = <&hsfll120>; prescaler = <0>; }; @@ -623,7 +636,7 @@ interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>; power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; max-bit-width = <32>; - max-frequency = ; + clocks = <&hsfll120>; prescaler = <0>; }; @@ -644,6 +657,7 @@ power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; easydma-maxcnt-bits = <15>; interrupts = <230 NRF_DEFAULT_IRQ_PRIORITY>; + clocks = <&hsfll120>; max-frequency = ; #address-cells = <1>; #size-cells = <0>; @@ -670,6 +684,7 @@ status = "disabled"; easydma-maxcnt-bits = <15>; interrupts = <231 NRF_DEFAULT_IRQ_PRIORITY>; + clocks = <&hsfll120>; power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>; max-frequency = ; #address-cells = <1>; @@ -861,6 +876,7 @@ status = "disabled"; #io-channel-cells = <1>; power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + zephyr,pm-device-runtime-auto; }; comp: comparator@983000 { @@ -898,6 +914,15 @@ power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; }; + pdm0: pdm@993000 { + compatible = "nordic,nrf-pdm"; + reg = <0x993000 0x1000>; + status = "disabled"; + interrupts = <403 NRF_DEFAULT_IRQ_PRIORITY>; + nordic,clockpin-enable = ; + power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; + }; + qdec130: qdec@994000 { compatible = "nordic,nrf-qdec"; reg = <0x994000 0x1000>; @@ -919,11 +944,8 @@ reg = <0x99c000 0x1000>; status = "disabled"; cc-num = <16>; - /* GRTC uses both LFCLK and FLL16M, but its accuracy and - * precision are inherited from LFCLK. that's why this - * one is linked here. - */ - clocks = <&lfclk>; + clocks = <&lfclk>, <&fll16m>; + clock-names = "lfclock", "hfclock"; power-domains = <&gpd NRF_GPD_SLOW_ACTIVE>; }; diff --git a/dts/common/nordic/nrf54l09.dtsi b/dts/common/nordic/nrf54l09.dtsi new file mode 100644 index 0000000000000..44bef74a33d2e --- /dev/null +++ b/dts/common/nordic/nrf54l09.dtsi @@ -0,0 +1,616 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +/delete-node/ &sw_pwm; + +/* Domain IDs. Can be used to specify channel links in IPCT nodes. */ +#define NRF_DOMAIN_ID_APPLICATION 0 +#define NRF_DOMAIN_ID_FLPR 1 + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpuapp: cpu@0 { + compatible = "arm,cortex-m33f"; + reg = <0>; + device_type = "cpu"; + clocks = <&hfpll>; + #address-cells = <1>; + #size-cells = <1>; + + itm: itm@e0000000 { + compatible = "arm,armv8m-itm"; + reg = <0xe0000000 0x1000>; + swo-ref-frequency = ; + }; + }; + + cpuflpr: cpu@1 { + compatible = "nordic,vpr"; + reg = <1>; + device_type = "cpu"; + clock-frequency = ; + riscv,isa = "rv32emc"; + nordic,bus-width = <32>; + }; + }; + + clocks { + lfxo: lfxo { + compatible = "nordic,nrf-lfxo"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + hfxo: hfxo { + compatible = "nordic,nrf-hfxo"; + #clock-cells = <0>; + clock-frequency = ; + }; + + hfpll: hfpll { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + + #ifdef USE_NON_SECURE_ADDRESS_MAP + /* intentionally empty because UICR is hardware fixed to Secure */ + #else + uicr: uicr@ffd000 { + compatible = "nordic,nrf-uicr"; + reg = <0xffd000 0x1000>; + }; + #endif + ficr: ficr@ffc000 { + compatible = "nordic,nrf-ficr"; + reg = <0xffc000 0x1000>; + #nordic,ficr-cells = <1>; + }; + + cpuapp_sram: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(144)>; + ranges = <0x0 0x20000000 DT_SIZE_K(144)>; + compatible = "mmio-sram"; + #address-cells = <1>; + #size-cells = <1>; + }; + + cpuflpr_sram: memory@20024000 { + compatible = "mmio-sram"; + reg = <0x20024000 DT_SIZE_K(48)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x20024000 DT_SIZE_K(48)>; + }; + + #ifdef USE_NON_SECURE_ADDRESS_MAP + global_peripherals: peripheral@40000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x40000000 0x10000000>; + #else + global_peripherals: peripheral@50000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x50000000 0x10000000>; + #endif + + dppic00: dppic@42000 { + compatible = "nordic,nrf-dppic"; + reg = <0x42000 0x808>; + status = "disabled"; + }; + + ppib00: ppib@44000 { + compatible = "nordic,nrf-ppib"; + reg = <0x44000 0x1000>; + status = "disabled"; + }; + + ppib01: ppib@45000 { + compatible = "nordic,nrf-ppib"; + reg = <0x45000 0x1000>; + status = "disabled"; + }; + + cpuflpr_vpr: vpr@4c000 { + compatible = "nordic,nrf-vpr-coprocessor"; + reg = <0x4c000 0x1000>; + ranges = <0x0 0x4c000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + + cpuflpr_clic: interrupt-controller@f0000000 { + compatible = "nordic,nrf-clic"; + reg = <0xf0000000 0x1780>; + interrupt-controller; + #interrupt-cells = <2>; + #address-cells = <1>; + status = "disabled"; + }; + }; + + timer00: timer@55000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0x55000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <85 NRF_DEFAULT_IRQ_PRIORITY>; + clocks = <&hfpll>; + prescaler = <0>; + }; + + dppic10: dppic@82000 { + compatible = "nordic,nrf-dppic"; + reg = <0x82000 0x808>; + status = "disabled"; + }; + + ppib10: ppib@83000 { + compatible = "nordic,nrf-ppib"; + reg = <0x83000 0x1000>; + status = "disabled"; + }; + + ppib11: ppib@84000 { + compatible = "nordic,nrf-ppib"; + reg = <0x84000 0x1000>; + status = "disabled"; + }; + + timer10: timer@85000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0x85000 0x1000>; + cc-num = <8>; + max-bit-width = <32>; + interrupts = <133 NRF_DEFAULT_IRQ_PRIORITY>; + clocks = <&hfxo>; + prescaler = <0>; + }; + + egu10: egu@87000 { + compatible = "nordic,nrf-egu"; + reg = <0x87000 0x1000>; + interrupts = <135 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + radio: radio@8a000 { + compatible = "nordic,nrf-radio"; + reg = <0x8a000 0x1000>; + interrupts = <138 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + dfe-supported; + ieee802154-supported; + ble-2mbps-supported; + ble-coded-phy-supported; + cs-supported; + + ieee802154: ieee802154 { + compatible = "nordic,nrf-ieee802154"; + status = "disabled"; + }; + + /* Note: In the nRF Connect SDK the SoftDevice Controller + * is added and set as the default Bluetooth Controller. + */ + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "disabled"; + }; + }; + + dppic20: dppic@c2000 { + compatible = "nordic,nrf-dppic"; + reg = <0xc2000 0x808>; + status = "disabled"; + }; + + ppib20: ppib@c3000 { + compatible = "nordic,nrf-ppib"; + reg = <0xc3000 0x1000>; + status = "disabled"; + }; + + ppib21: ppib@c4000 { + compatible = "nordic,nrf-ppib"; + reg = <0xc4000 0x1000>; + status = "disabled"; + }; + + ppib22: ppib@c5000 { + compatible = "nordic,nrf-ppib"; + reg = <0xc5000 0x1000>; + status = "disabled"; + }; + + i2c20: i2c@c6000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; + zephyr,pm-device-runtime-auto; + }; + + spi20: spi@c6000 { + /* + * This spi node can be either SPIM or SPIS, + * for the user to pick: + * compatible = "nordic,nrf-spim" or + * "nordic,nrf-spis". + */ + compatible = "nordic,nrf-spim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + uart20: uart@c6000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + i2c21: i2c@c7000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; + zephyr,pm-device-runtime-auto; + }; + + spi21: spi@c7000 { + /* + * This spi node can be either SPIM or SPIS, + * for the user to pick: + * compatible = "nordic,nrf-spim" or + * "nordic,nrf-spis". + */ + compatible = "nordic,nrf-spim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + uart21: uart@c7000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + egu20: egu@c9000 { + compatible = "nordic,nrf-egu"; + reg = <0xc9000 0x1000>; + interrupts = <201 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + timer20: timer@ca000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xca000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <202 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; + }; + + timer21: timer@cb000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xcb000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <203 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; + }; + + timer22: timer@cc000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xcc000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <204 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; + }; + + timer23: timer@cd000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xcd000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <205 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; + }; + + timer24: timer@ce000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xce000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <206 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; + }; + + adc: adc@d5000 { + compatible = "nordic,nrf-saadc"; + reg = <0xd5000 0x1000>; + interrupts = <213 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; + }; + + temp: temp@d7000 { + compatible = "nordic,nrf-temp"; + reg = <0xd7000 0x1000>; + interrupts = <215 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + gpio1: gpio@d8200 { + compatible = "nordic,nrf-gpio"; + gpio-controller; + reg = <0xd8200 0x300>; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + port = <1>; + gpiote-instance = <&gpiote20>; + }; + + gpiote20: gpiote@da000 { + compatible = "nordic,nrf-gpiote"; + reg = <0xda000 0x1000>; + status = "disabled"; + instance = <20>; + }; + + grtc: grtc@e2000 { + compatible = "nordic,nrf-grtc"; + reg = <0xe2000 0x1000>; + cc-num = <12>; + status = "disabled"; + }; + + dppic30: dppic@102000 { + compatible = "nordic,nrf-dppic"; + reg = <0x102000 0x808>; + status = "disabled"; + }; + + ppib30: ppib@103000 { + compatible = "nordic,nrf-ppib"; + reg = <0x103000 0x1000>; + status = "disabled"; + }; + + i2c30: i2c@104000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; + zephyr,pm-device-runtime-auto; + }; + + spi30: spi@104000 { + /* + * This spi node can be either SPIM or SPIS, + * for the user to pick: + * compatible = "nordic,nrf-spim" or + * "nordic,nrf-spis". + */ + compatible = "nordic,nrf-spim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + uart30: uart@104000 { + compatible = "nordic,nrf-uarte"; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + clock: clock@10e000 { + compatible = "nordic,nrf-clock"; + reg = <0x10e000 0x1000>; + interrupts = <270 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + power: power@10e000 { + compatible = "nordic,nrf-power"; + reg = <0x10e000 0x1000>; + ranges = <0x0 0x10e000 0x1000>; + interrupts = <270 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <1>; + + gpregret1: gpregret1@51c { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nordic,nrf-gpregret"; + reg = <0x51c 0x1>; + status = "disabled"; + }; + + gpregret2: gpregret2@520 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nordic,nrf-gpregret"; + reg = <0x520 0x1>; + status = "disabled"; + }; + }; + + comp: comparator@106000 { + /* + * Use compatible "nordic,nrf-comp" to configure as COMP + * Use compatible "nordic,nrf-lpcomp" to configure as LPCOMP + */ + compatible = "nordic,nrf-comp"; + reg = <0x106000 0x1000>; + status = "disabled"; + interrupts = <262 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + #ifdef USE_NON_SECURE_ADDRESS_MAP + /* intentionally empty because WDT30 is hardware fixed to Secure */ + #else + wdt30: watchdog@108000 { + compatible = "nordic,nrf-wdt"; + reg = <0x108000 0x620>; + interrupts = <264 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + #endif + + wdt31: watchdog@109000 { + compatible = "nordic,nrf-wdt"; + reg = <0x109000 0x620>; + interrupts = <265 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + gpio0: gpio@10a000 { + compatible = "nordic,nrf-gpio"; + gpio-controller; + reg = <0x10a000 0x300>; + #gpio-cells = <2>; + ngpios = <5>; + status = "disabled"; + port = <0>; + gpiote-instance = <&gpiote30>; + }; + + gpiote30: gpiote@10c000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x10c000 0x1000>; + status = "disabled"; + instance = <30>; + }; + + regulators: regulator@120000 { + compatible = "nordic,nrf54l-regulators"; + reg = <0x120000 0x1000>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <1>; + + vregmain: regulator@120600 { + compatible = "nordic,nrf5x-regulator"; + reg = <0x120600 0x1>; + status = "disabled"; + regulator-name = "VREGMAIN"; + regulator-initial-mode = ; + }; + }; + }; + + rram_controller: rram-controller@5004e000 { + compatible = "nordic,rram-controller"; + reg = <0x5004e000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = <75 NRF_DEFAULT_IRQ_PRIORITY>; + + /* 952 + 60 = 1012KB */ + cpuapp_rram: rram@0 { + compatible = "soc-nv-flash"; + erase-block-size = <4096>; + write-block-size = <16>; + reg = <0x0 DT_SIZE_K(952)>; + }; + + cpuflpr_rram: rram@ee000 { + compatible = "soc-nv-flash"; + reg = <0xee000 DT_SIZE_K(60)>; + erase-block-size = <4096>; + write-block-size = <16>; + }; + }; + + cpuapp_ppb: cpuapp-ppb-bus { + #address-cells = <1>; + #size-cells = <1>; + + cpuapp_nvic: interrupt-controller@e000e100 { + #address-cells = <1>; + compatible = "arm,v8m-nvic"; + reg = <0xe000e100 0xc00>; + arm,num-irq-priority-bits = <3>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + cpuapp_systick: timer@e000e010 { + compatible = "arm,armv8m-systick"; + reg = <0xe000e010 0x10>; + status = "disabled"; + }; + }; + }; +}; diff --git a/dts/common/nordic/nrf54l20.dtsi b/dts/common/nordic/nrf54l20.dtsi index 7f33221b0e781..0442abc35cf7e 100644 --- a/dts/common/nordic/nrf54l20.dtsi +++ b/dts/common/nordic/nrf54l20.dtsi @@ -23,9 +23,10 @@ compatible = "arm,cortex-m33f"; reg = <0>; device_type = "cpu"; - clock-frequency = ; + clocks = <&hfpll>; #address-cells = <1>; #size-cells = <1>; + itm: itm@e0000000 { compatible = "arm,armv8m-itm"; reg = <0xe0000000 0x1000>; @@ -35,6 +36,12 @@ }; clocks { + pclk: pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + lfxo: lfxo { compatible = "nordic,nrf-lfxo"; #clock-cells = <0>; @@ -146,7 +153,7 @@ cc-num = <6>; max-bit-width = <32>; interrupts = <85 NRF_DEFAULT_IRQ_PRIORITY>; - max-frequency = ; + clocks = <&hfpll>; prescaler = <0>; }; @@ -175,7 +182,7 @@ cc-num = <8>; max-bit-width = <32>; interrupts = <133 NRF_DEFAULT_IRQ_PRIORITY>; - max-frequency = ; + clocks = <&hfxo>; prescaler = <0>; }; @@ -452,6 +459,7 @@ interrupts = <213 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; nfct: nfct@d6000 { @@ -504,6 +512,8 @@ compatible = "nordic,nrf-grtc"; reg = <0xe2000 0x1000>; cc-num = <12>; + clocks = <&lfxo>, <&pclk>; + clock-names = "lfclock", "hfclock"; status = "disabled"; }; diff --git a/dts/common/nordic/nrf54l_05_10_15.dtsi b/dts/common/nordic/nrf54l_05_10_15.dtsi index 633b1d425e478..d7de7a159429b 100644 --- a/dts/common/nordic/nrf54l_05_10_15.dtsi +++ b/dts/common/nordic/nrf54l_05_10_15.dtsi @@ -27,9 +27,10 @@ compatible = "arm,cortex-m33f"; reg = <0>; device_type = "cpu"; - clock-frequency = ; + clocks = <&hfpll>; #address-cells = <1>; #size-cells = <1>; + itm: itm@e0000000 { compatible = "arm,armv8m-itm"; reg = <0xe0000000 0x1000>; @@ -41,13 +42,19 @@ compatible = "nordic,vpr"; reg = <1>; device_type = "cpu"; - clock-frequency = ; + clocks = <&hfpll>; riscv,isa = "rv32emc"; nordic,bus-width = <32>; }; }; clocks { + pclk: pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + lfxo: lfxo { compatible = "nordic,nrf-lfxo"; #clock-cells = <0>; @@ -185,7 +192,7 @@ cc-num = <6>; max-bit-width = <32>; interrupts = <85 NRF_DEFAULT_IRQ_PRIORITY>; - max-frequency = ; + clocks = <&hfpll>; prescaler = <0>; }; @@ -214,7 +221,7 @@ cc-num = <8>; max-bit-width = <32>; interrupts = <133 NRF_DEFAULT_IRQ_PRIORITY>; - max-frequency = ; + clocks = <&hfxo>; prescaler = <0>; }; @@ -492,6 +499,7 @@ interrupts = <213 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; nfct: nfct@d6000 { @@ -553,6 +561,8 @@ compatible = "nordic,nrf-grtc"; reg = <0xe2000 0x1000>; cc-num = <12>; + clocks = <&lfxo>, <&pclk>; + clock-names = "lfclock", "hfclock"; status = "disabled"; }; diff --git a/dts/common/nordic/nrf91xx_partition.dtsi b/dts/common/nordic/nrf91xx_partition.dtsi index 27557da049811..85d878ccdb93b 100644 --- a/dts/common/nordic/nrf91xx_partition.dtsi +++ b/dts/common/nordic/nrf91xx_partition.dtsi @@ -33,34 +33,42 @@ label = "mcuboot"; reg = <0x00000000 0x10000>; }; + slot0_partition: partition@10000 { label = "image-0"; reg = <0x00010000 0x40000>; }; + slot0_ns_partition: partition@50000 { label = "image-0-nonsecure"; reg = <0x00050000 0x30000>; }; + slot1_partition: partition@80000 { label = "image-1"; reg = <0x00080000 0x40000>; }; + slot1_ns_partition: partition@c0000 { label = "image-1-nonsecure"; reg = <0x000c0000 0x30000>; }; + tfm_ps_partition: partition@f0000 { label = "tfm-ps"; reg = <0x000f0000 0x00004000>; }; + tfm_its_partition: partition@f4000 { label = "tfm-its"; reg = <0x000f4000 0x00002000>; }; + tfm_otp_partition: partition@f6000 { label = "tfm-otp"; reg = <0x000f6000 0x00002000>; }; + storage_partition: partition@f8000 { label = "storage"; reg = <0x000f8000 0x00008000>; diff --git a/dts/common/nordic/nrf9280.dtsi b/dts/common/nordic/nrf9280.dtsi index 4fd64cd10be60..ee201dbacfde0 100644 --- a/dts/common/nordic/nrf9280.dtsi +++ b/dts/common/nordic/nrf9280.dtsi @@ -74,6 +74,10 @@ reserved-memory { #address-cells = <1>; #size-cells = <1>; + + suit_storage_partition: memory@e6b7000 { + reg = <0xe6b7000 DT_SIZE_K(40)>; + }; }; clocks { @@ -88,6 +92,17 @@ #clock-cells = <0>; clock-frequency = ; }; + + hsfll120: hsfll120 { + compatible = "nordic,nrf-hsfll-global"; + clocks = <&fll16m>; + #clock-cells = <0>; + clock-frequency = <320000000>; + supported-clock-frequencies = <64000000 + 128000000 + 256000000 + 320000000>; + }; }; soc { @@ -149,7 +164,7 @@ ranges = <0x0 0x52000000 0x1000000>; cpuapp_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>; @@ -201,7 +216,7 @@ ranges = <0x0 0x53000000 0x1000000>; cpurad_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll"; + compatible = "nordic,nrf-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>; @@ -261,7 +276,7 @@ cc-num = <8>; interrupts = <40 NRF_DEFAULT_IRQ_PRIORITY>; max-bit-width = <32>; - max-frequency = ; + clocks = <&hfxo>; prescaler = <0>; }; @@ -272,7 +287,7 @@ cc-num = <8>; interrupts = <41 NRF_DEFAULT_IRQ_PRIORITY>; max-bit-width = <32>; - max-frequency = ; + clocks = <&hfxo>; prescaler = <0>; }; @@ -283,7 +298,7 @@ cc-num = <8>; interrupts = <42 NRF_DEFAULT_IRQ_PRIORITY>; max-bit-width = <32>; - max-frequency = ; + clocks = <&hfxo>; prescaler = <0>; }; @@ -430,26 +445,6 @@ global-domain-id = <12>; }; - can120: can@8d8000 { - compatible = "nordic,nrf-can"; - reg = <0x8d8000 0x400>, <0x2fbef800 0x800>, <0x2fbe8000 0x7800>; - reg-names = "wrapper", "m_can", "message_ram"; - interrupts = <216 NRF_DEFAULT_IRQ_PRIORITY>; - clocks = <&canpll>; - bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; - status = "disabled"; - }; - - can121: can@8db000 { - compatible = "nordic,nrf-can"; - reg = <0x8db000 0x400>, <0x2fbf7800 0x800>, <0x2fbf0000 0x7800>; - reg-names = "wrapper", "m_can", "message_ram"; - interrupts = <219 NRF_DEFAULT_IRQ_PRIORITY>; - clocks = <&canpll>; - bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; - status = "disabled"; - }; - dppic120: dppic@8e1000 { compatible = "nordic,nrf-dppic-global"; reg = <0x8e1000 0x1000>; @@ -463,7 +458,7 @@ cc-num = <6>; interrupts = <226 NRF_DEFAULT_IRQ_PRIORITY>; max-bit-width = <32>; - max-frequency = ; + clocks = <&hsfll120>; prescaler = <0>; }; @@ -474,7 +469,7 @@ cc-num = <6>; interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>; max-bit-width = <32>; - max-frequency = ; + clocks = <&hsfll120>; prescaler = <0>; }; @@ -669,16 +664,6 @@ port = <9>; }; - gpio10: gpio@939400 { - compatible = "nordic,nrf-gpio"; - reg = <0x939400 0x200>; - status = "disabled"; - #gpio-cells = <2>; - gpio-controller; - ngpios = <8>; - port = <10>; - }; - gpio11: gpio@939600 { compatible = "nordic,nrf-gpio"; reg = <0x939600 0x200>; @@ -690,28 +675,6 @@ port = <11>; }; - gpio12: gpio@939800 { - compatible = "nordic,nrf-gpio"; - reg = <0x939800 0x200>; - status = "disabled"; - #gpio-cells = <2>; - gpio-controller; - gpiote-instance = <&gpiote131>; - ngpios = <3>; - port = <12>; - }; - - gpio13: gpio@939a00 { - compatible = "nordic,nrf-gpio"; - reg = <0x939a00 0x200>; - status = "disabled"; - #gpio-cells = <2>; - gpio-controller; - gpiote-instance = <&gpiote131>; - ngpios = <4>; - port = <13>; - }; - dppic131: dppic@981000 { compatible = "nordic,nrf-dppic-global"; reg = <0x981000 0x1000>; @@ -724,6 +687,7 @@ interrupts = <386 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; #io-channel-cells = <1>; + zephyr,pm-device-runtime-auto; }; comp: comparator@983000 { diff --git a/dts/riscv/andes/andes_v5_ae350.dtsi b/dts/riscv/andes/andes_v5_ae350.dtsi index 538de399af94b..082b599dd314e 100644 --- a/dts/riscv/andes/andes_v5_ae350.dtsi +++ b/dts/riscv/andes/andes_v5_ae350.dtsi @@ -215,8 +215,8 @@ }; mtimer: timer@e6000000 { - compatible = "andestech,machine-timer"; - reg = <0xe6000000 0x10>; + compatible = "riscv,machine-timer"; + reg = <0xe6000000 0x8 0xe6000008 0x8>; interrupts-extended = <&cpu0_intc 7 &cpu1_intc 7 &cpu2_intc 7 &cpu3_intc 7 &cpu4_intc 7 &cpu5_intc 7 diff --git a/dts/riscv/efinix/sapphire_soc.dtsi b/dts/riscv/efinix/sapphire_soc.dtsi index 72092a4bc9300..faf60931d6480 100644 --- a/dts/riscv/efinix/sapphire_soc.dtsi +++ b/dts/riscv/efinix/sapphire_soc.dtsi @@ -65,6 +65,13 @@ reg = <0xf8b00000 0x10000>; }; + mtimer: timer@f8b0bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic 7>; + reg = <0xf8b0bff8 0x8 0xf8b04000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + timer0: timer@e0002800 { compatible = "efinix,sapphire-timer0"; reg = <0xe0002800 0x40>; diff --git a/dts/riscv/espressif/esp32c2/esp32c2_common.dtsi b/dts/riscv/espressif/esp32c2/esp32c2_common.dtsi index 479e230a1817d..1d8a34e471dc4 100644 --- a/dts/riscv/espressif/esp32c2/esp32c2_common.dtsi +++ b/dts/riscv/espressif/esp32c2/esp32c2_common.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ @@ -56,9 +56,16 @@ compatible = "simple-bus"; ranges; - sram0: memory@3fc7c000 { - compatible = "mmio-sram"; - reg = <0x3fc7c000 0x50000>; + sram0: memory@4037c000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x4037c000 DT_SIZE_K(16)>; + zephyr,memory-region = "SRAM0"; + }; + + sram1: memory@3fca0000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x3fca0000 DT_SIZE_K(256)>; + zephyr,memory-region = "SRAM1"; }; intc: interrupt-controller@600c2000 { @@ -168,6 +175,7 @@ timer0: counter@6001f000 { compatible = "espressif,esp32-timer"; reg = <0x6001F000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; group = <0>; index = <0>; interrupts = ; @@ -207,5 +215,15 @@ reg = <0x60040058 0x4>; status = "disabled"; }; + + adc0: adc@60040000 { + compatible = "espressif,esp32-adc"; + reg = <0x60040000 4>; + clocks = <&rtc ESP32_SARADC_MODULE>; + unit = <1>; + channel-count = <5>; + #io-channel-cells = <1>; + status = "disabled"; + }; }; }; diff --git a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi index 35ac7d58cc2f1..7c8eee5e99aef 100644 --- a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi +++ b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi @@ -80,9 +80,16 @@ compatible = "simple-bus"; ranges; - sram0: memory@3fc7c000 { - compatible = "mmio-sram"; - reg = <0x3fc7c000 0x50000>; + sram0: memory@4037c000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x4037c000 DT_SIZE_K(16)>; + zephyr,memory-region = "SRAM0"; + }; + + sram1: memory@3fc80000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x3fc80000 DT_SIZE_K(384)>; + zephyr,memory-region = "SRAM1"; }; intc: interrupt-controller@600c2000 { @@ -224,6 +231,7 @@ timer0: counter@6001f000 { compatible = "espressif,esp32-timer"; reg = <0x6001F000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; group = <0>; index = <0>; interrupts = ; @@ -234,6 +242,7 @@ timer1: counter@60020000 { compatible = "espressif,esp32-timer"; reg = <0x60020000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG1_MODULE>; group = <1>; index = <0>; interrupts = ; @@ -295,21 +304,13 @@ adc0: adc@60040000 { compatible = "espressif,esp32-adc"; reg = <0x60040000 4>; + clocks = <&rtc ESP32_SARADC_MODULE>; unit = <1>; channel-count = <5>; #io-channel-cells = <1>; status = "disabled"; }; - adc1: adc@60040004 { - compatible = "espressif,esp32-adc"; - reg = <0x60040004 4>; - unit = <2>; - channel-count = <2>; - #io-channel-cells = <1>; - status = "disabled"; - }; - dma: dma@6003f000 { compatible = "espressif,esp32-gdma"; reg = <0x6003f000 DT_SIZE_K(4)>; diff --git a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi index c8ae394fbf95b..d61f0762e4368 100644 --- a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi +++ b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi @@ -1,11 +1,13 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include #include +#include #include #include #include @@ -67,9 +69,16 @@ compatible = "simple-bus"; ranges; - sram0: memory@40800000 { - compatible = "mmio-sram"; - reg = <0x40800000 0x50000>; + sramhp: memory@40800000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x40800000 DT_SIZE_K(512)>; + zephyr,memory-region = "SRAMHP"; + }; + + sramlp: memory@50000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x50000000 DT_SIZE_K(16)>; + zephyr,memory-region = "SRAMLP "; }; intc: interrupt-controller@60010000 { @@ -89,6 +98,28 @@ status = "okay"; }; + timer0: counter@60008000 { + compatible = "espressif,esp32-timer"; + reg = <0x60008000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; + group = <0>; + index = <0>; + interrupts = ; + interrupt-parent = <&intc>; + status = "disabled"; + }; + + timer1: counter@60009000 { + compatible = "espressif,esp32-timer"; + reg = <0x60009000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG1_MODULE>; + group = <1>; + index = <0>; + interrupts = ; + interrupt-parent = <&intc>; + status = "disabled"; + }; + rtc: rtc@600b0000 { compatible = "espressif,esp32-rtc"; reg = <0x600B0000 DT_SIZE_K(1)>; @@ -158,6 +189,16 @@ }; }; + adc0: adc@6000e000 { + compatible = "espressif,esp32-adc"; + reg = <0x6000E000 4>; + clocks = <&rtc ESP32_SARADC_MODULE>; + unit = <1>; + channel-count = <7>; + #io-channel-cells = <1>; + status = "disabled"; + }; + dma: dma@60080000 { compatible = "espressif,esp32-gdma"; reg = <0x60080000 DT_SIZE_K(4)>; @@ -186,6 +227,17 @@ ngpios = <30>; /* 0..29 */ }; + i2c0: i2c@60004000 { + compatible = "espressif,esp32-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60004000 0x1000>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&rtc ESP32_I2C0_MODULE>; + status = "disabled"; + }; + uart0: uart@60000000 { compatible = "espressif,esp32-uart"; reg = <0x60000000 DT_SIZE_K(4)>; @@ -222,5 +274,15 @@ clocks = <&rtc ESP32_LEDC_MODULE>; status = "disabled"; }; + + mcpwm0: mcpwm@60014000 { + compatible = "espressif,esp32-mcpwm"; + reg = <0x60014000 DT_SIZE_K(4)>; + interrupts = ; + interrupt-parent = <&intc>; + clocks = <&rtc ESP32_MCPWM0_MODULE>; + #pwm-cells = <3>; + status = "disabled"; + }; }; }; diff --git a/dts/riscv/gd/gd32vf103.dtsi b/dts/riscv/gd/gd32vf103.dtsi index a631cd4ab18ff..5f87ba2bfc324 100644 --- a/dts/riscv/gd/gd32vf103.dtsi +++ b/dts/riscv/gd/gd32vf103.dtsi @@ -41,9 +41,9 @@ ranges; systimer: timer@d1000000 { - compatible = "nuclei,systimer"; - reg = <0xd1000000 0x10000>; - interrupts = <3 0>, <7 0>; + compatible = "nuclei,systimer", "riscv,machine-timer"; + reg = <0xd1000000 0x8 0xd1000008 0x8>; + interrupts-extended = <&eclic 7 0>; clk-divider = ; }; diff --git a/dts/riscv/ite/it8801-common-cfg.dtsi b/dts/riscv/ite/it8801-common-cfg.dtsi new file mode 100644 index 0000000000000..714727185584a --- /dev/null +++ b/dts/riscv/ite/it8801-common-cfg.dtsi @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2024 ITE Corporation. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&it8801_mfd { + #address-cells = <1>; + #size-cells = <1>; + + /* GPIO */ + ioex_it8801_port0: it8801_port@0 { + compatible = "ite,it8801-gpio"; + reg = <0x00 1 /* GPIPSR */ + 0x05 1 /* GPSOVR */ + 0x0a 8 /* GPCR */ + 0x32 1 /* GPISR */ + 0x37 1>; /* GPIER */ + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + pin-mask = <0xdb>; + }; + + ioex_it8801_port1: it8801_port@1 { + compatible = "ite,it8801-gpio"; + reg = <0x01 1 /* GPIPSR */ + 0x06 1 /* GPSOVR */ + 0x12 6 /* GPCR */ + 0x33 1 /* GPISR */ + 0x38 1>; /* GPIER */ + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + pin-mask = <0x3f>; + }; + + ioex_it8801_port2: it8801_port@2 { + compatible = "ite,it8801-gpio"; + reg = <0x02 1 /* GPIPSR */ + 0x07 1 /* GPSOVR */ + 0x1a 4 /* GPCR */ + 0x34 1 /* GPISR */ + 0x39 1>; /* GPIER */ + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + pin-mask = <0x0f>; + }; + + /* KBD */ + ioex_it8801_kbd: it8801_kbd@40 { + compatible = "ite,it8801-kbd"; + status = "disabled"; + reg = <0x40 1 + 0x41 1 + 0x42 1 + 0x43 1>; + row-size = <8>; + col-size = <13>; + }; + + /* PWM */ + ioex_it8801_pwm1: it8801_pwm@60 { + compatible = "ite,it8801-pwm"; + status = "disabled"; + reg = <0x60 1 /* PWMMCR */ + 0x64 1 /* PWMDCR */ + 0x66 1 /* PWMPRSL */ + 0x67 1>; /* PWMPRSM */ + mfdctrl = <&pwm1_gp12_default>; + channel = <1>; + #pwm-cells = <3>; + }; + + ioex_it8801_pwm2: it8801_pwm@68 { + compatible = "ite,it8801-pwm"; + status = "disabled"; + reg = <0x68 1 /* PWMMCR */ + 0x6c 1 /* PWMDCR */ + 0x6e 1 /* PWMPRSL */ + 0x6f 1>; /* PWMPRSM */ + mfdctrl = <&pwm2_gp13_default>; + channel = <2>; + #pwm-cells = <3>; + }; + + ioex_it8801_pwm3: it8801_pwm@70 { + compatible = "ite,it8801-pwm"; + status = "disabled"; + reg = <0x70 1 /* PWMMCR */ + 0x74 1 /* PWMDCR */ + 0x76 1 /* PWMPRSL */ + 0x77 1>; /* PWMPRSM */ + mfdctrl = <&pwm3_gp14_default>; + channel = <3>; + #pwm-cells = <3>; + }; + + ioex_it8801_pwm4: it8801_pwm@78 { + compatible = "ite,it8801-pwm"; + status = "disabled"; + reg = <0x78 1 /* PWMMCR */ + 0x7c 1 /* PWMDCR */ + 0x7e 1 /* PWMPRSL */ + 0x7f 1>; /* PWMPRSM */ + mfdctrl = <&pwm4_gp15_default>; + channel = <4>; + #pwm-cells = <3>; + }; + + ioex_it8801_pwm7: it8801_pwm@90 { + compatible = "ite,it8801-pwm"; + status = "disabled"; + reg = <0x90 1 /* PWMMCR */ + 0x94 1 /* PWMDCR */ + 0x96 1 /* PWMPRSL */ + 0x97 1>; /* PWMPRSM */ + mfdctrl = <&pwm7_gp20_default>; + channel = <7>; + #pwm-cells = <3>; + + }; + + ioex_it8801_pwm8: it8801_pwm@98 { + compatible = "ite,it8801-pwm"; + status = "disabled"; + reg = <0x98 1 /* PWMMCR */ + 0x9c 1 /* PWMDCR */ + 0x9e 1 /* PWMPRSL */ + 0x9f 1>; /* PWMPRSM */ + mfdctrl = <&pwm8_gp23_default>; + channel = <8>; + #pwm-cells = <3>; + }; + + ioex_it8801_pwm9: it8801_pwm@a0 { + compatible = "ite,it8801-pwm"; + status = "disabled"; + reg = <0xa0 1 /* PWMMCR */ + 0xa4 1 /* PWMDCR */ + 0xa6 1 /* PWMPRSL */ + 0xa7 1>; /* PWMPRSM */ + mfdctrl = <&pwm9_gp22_default>; + channel = <9>; + #pwm-cells = <3>; + }; +}; diff --git a/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi b/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi index 5492f19610a00..73ec8462d4ad7 100644 --- a/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi +++ b/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi @@ -222,11 +222,11 @@ drive-open-drain; bias-pull-up; }; - kso16_gpc3_default: kso16_gpc3_default { + kso16_default: kso16_gpc3_default: kso16_default { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - kso17_gpc5_default: kso17_gpc5_default { + kso17_default: kso17_gpc5_default: kso17_default { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; @@ -304,10 +304,10 @@ kso15_sleep: kso15_sleep { pinmuxs = <&pinctrlksoh 7 IT8XXX2_ALT_DEFAULT>; }; - kso16_gpc3_sleep: kso16_gpc3_sleep { + kso16_sleep: kso16_gpc3_sleep: kso16_sleep { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_DEFAULT>; }; - kso17_gpc5_sleep: kso17_gpc5_sleep { + kso17_sleep: kso17_gpc5_sleep: kso17_sleep { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_DEFAULT>; }; diff --git a/dts/riscv/lowrisc/opentitan_earlgrey.dtsi b/dts/riscv/lowrisc/opentitan_earlgrey.dtsi index e3b79bbaf0674..11c1f784a734f 100644 --- a/dts/riscv/lowrisc/opentitan_earlgrey.dtsi +++ b/dts/riscv/lowrisc/opentitan_earlgrey.dtsi @@ -44,12 +44,11 @@ reg = <0x10000000 0x10000>; }; - mtimer: timer@40100000 { - compatible = "lowrisc,machine-timer"; - reg = <0x40100000 0x200>; - interrupts = <7 0>; - interrupt-parent = <&hlic>; - status = "disabled"; + mtimer: timer@40100110 { + compatible = "riscv,machine-timer"; + reg = <0x40100110 0x8 0x40100118 0x8>; + reg-names = "mtime", "mtimecmp"; + interrupts-extended = <&hlic 7>; }; aontimer: aontimer@40470000 { diff --git a/dts/riscv/microchip/microchip-miv.dtsi b/dts/riscv/microchip/microchip-miv.dtsi index 305145b7e44f8..aa42d989c7a21 100644 --- a/dts/riscv/microchip/microchip-miv.dtsi +++ b/dts/riscv/microchip/microchip-miv.dtsi @@ -48,6 +48,13 @@ reg = <0x44000000 0x10000>; }; + mtimer: timer@4400bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic 7>; + reg = <0x4400bff8 0x8 0x44004000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + plic: interrupt-controller@40000000 { compatible = "sifive,plic-1.0.0"; #address-cells = <0>; diff --git a/dts/riscv/microchip/mpfs.dtsi b/dts/riscv/microchip/mpfs.dtsi index f22c7604bb3a5..e3ff65dd5775d 100644 --- a/dts/riscv/microchip/mpfs.dtsi +++ b/dts/riscv/microchip/mpfs.dtsi @@ -114,6 +114,17 @@ reg = <0x2000000 0x10000>; }; + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic0 7 + &hlic1 7 + &hlic2 7 + &hlic3 7 + &hlic4 7>; + reg = <0x200bff8 0x8 0x2004000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + plic: interrupt-controller@c000000 { compatible = "sifive,plic-1.0.0"; #interrupt-cells = <2>; diff --git a/dts/riscv/neorv32.dtsi b/dts/riscv/neorv32.dtsi index 31fb06b1c49a5..53d4837075d5a 100644 --- a/dts/riscv/neorv32.dtsi +++ b/dts/riscv/neorv32.dtsi @@ -65,9 +65,9 @@ ranges; mtimer: timer@ffffff90 { - compatible = "neorv32-machine-timer"; - reg = <0xffffff90 0x10>; - interrupts = <7>; + compatible = "riscv,machine-timer"; + reg = <0xffffff90 0x8 0xffffff98 0x8>; + interrupts-extended = <&intc 7>; }; uart0: serial@ffffffa0 { diff --git a/dts/riscv/niosv/niosv-g.dtsi b/dts/riscv/niosv/niosv-g.dtsi index 2022e984ff552..e0b1435fabe05 100644 --- a/dts/riscv/niosv/niosv-g.dtsi +++ b/dts/riscv/niosv/niosv-g.dtsi @@ -44,9 +44,10 @@ }; mtimer: machine-timer@90000 { - compatible = "niosv-machine-timer"; - reg = <0x90000 0x10>; - interrupts = <7>; + compatible = "riscv,machine-timer"; + reg = <0x90000 0x8 0x90008 0x8>; + reg-names = "mtime", "mtimecmp"; + interrupts-extended = <&intc 7>; }; uart0: serial@90078 { diff --git a/dts/riscv/niosv/niosv-m.dtsi b/dts/riscv/niosv/niosv-m.dtsi index e6594a2354659..f2870921e960f 100644 --- a/dts/riscv/niosv/niosv-m.dtsi +++ b/dts/riscv/niosv/niosv-m.dtsi @@ -44,9 +44,10 @@ }; mtimer: machine-timer@90000 { - compatible = "niosv-machine-timer"; - reg = <0x90000 0x10>; - interrupts = <7>; + compatible = "riscv,machine-timer"; + reg = <0x90000 0x8 0x90008 0x8>; + reg-names = "mtime", "mtimecmp"; + interrupts-extended = <&intc 7>; }; uart0: serial@90078 { diff --git a/dts/riscv/nordic/nrf54h20_cpuppr.dtsi b/dts/riscv/nordic/nrf54h20_cpuppr.dtsi index ae24f73a9a672..05309bac7d442 100644 --- a/dts/riscv/nordic/nrf54h20_cpuppr.dtsi +++ b/dts/riscv/nordic/nrf54h20_cpuppr.dtsi @@ -9,7 +9,7 @@ cpu: &cpuppr {}; clic: &cpuppr_clic {}; cpuppr_vevif: &cpuppr_vevif_rx {}; -cpuflpr_vevif: &cpuppr_vevif_tx {}; +cpuflpr_vevif: &cpuflpr_vevif_tx {}; cpusys_vevif: &cpusys_vevif_tx {}; /delete-node/ &cpuapp; diff --git a/dts/riscv/qemu/virt-riscv.dtsi b/dts/riscv/qemu/virt-riscv.dtsi index b810f9fe7dcba..d104f44e07d2e 100644 --- a/dts/riscv/qemu/virt-riscv.dtsi +++ b/dts/riscv/qemu/virt-riscv.dtsi @@ -193,5 +193,19 @@ &hlic6 0x03 &hlic6 0x07 &hlic7 0x03 &hlic7 0x07>; }; + + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic0 7 + &hlic1 7 + &hlic2 7 + &hlic3 7 + &hlic4 7 + &hlic5 7 + &hlic6 7 + &hlic7 7>; + reg = <0x200bff8 0x8 0x2004000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; }; }; diff --git a/dts/riscv/renode_riscv32_virt.dtsi b/dts/riscv/renode_riscv32_virt.dtsi index a0db375501f7c..f819ca441b72f 100644 --- a/dts/riscv/renode_riscv32_virt.dtsi +++ b/dts/riscv/renode_riscv32_virt.dtsi @@ -50,6 +50,13 @@ reg = <0x2000000 0x10000>; }; + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic 7>; + reg = <0x200bff8 0x8 0x2004000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + plic0: interrupt-controller@c000000 { compatible = "sifive,plic-1.0.0"; #address-cells = <0>; diff --git a/dts/riscv/riscv32-litex-vexriscv.dtsi b/dts/riscv/riscv32-litex-vexriscv.dtsi index 8557d2ecb832a..3662c3695b4d5 100644 --- a/dts/riscv/riscv32-litex-vexriscv.dtsi +++ b/dts/riscv/riscv32-litex-vexriscv.dtsi @@ -298,7 +298,7 @@ "rx_stat", "rx_conf", "fifo"; - fifo_depth = <256>; + fifo-depth = <256>; status = "disabled"; }; i2s_tx: i2s_tx@e000b000 { @@ -321,7 +321,7 @@ "tx_stat", "tx_conf", "fifo"; - fifo_depth = <256>; + fifo-depth = <256>; status = "disabled"; }; clock-outputs { diff --git a/dts/riscv/sensry/ganymed-sy1xx.dtsi b/dts/riscv/sensry/ganymed-sy1xx.dtsi index ad2df617b285c..0ff791bfdc3a0 100644 --- a/dts/riscv/sensry/ganymed-sy1xx.dtsi +++ b/dts/riscv/sensry/ganymed-sy1xx.dtsi @@ -3,10 +3,16 @@ /dts-v1/; +#include + / { #address-cells = <1>; #size-cells = <0>; + chosen { + zephyr,entropy = &trng; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -38,34 +44,34 @@ soc { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; event0: interrupt-controller@1000 { compatible = "sensry,sy1xx-event-unit"; - reg = <0x1000>; + reg = <0x1000 0x40>; interrupt-controller; #interrupt-cells = <1>; }; systick: timer@1a10b040 { compatible = "sensry,sy1xx-sys-timer"; - reg = <0x1a10b040>; + reg = <0x1a10b040 0x04>; interrupt-parent = <&event0>; interrupts = <10 0>; - ticks_us = <1000>; + ticks-us = <1000>; }; timer1: timer@1a10b044 { compatible = "sensry,sy1xx-sys-timer"; - reg = <0x1a10b044>; + reg = <0x1a10b044 0x04>; interrupt-parent = <&event0>; interrupts = <11 0>; - ticks_us = <1000>; + ticks-us = <1000>; }; uart0: uart@1a102000 { compatible = "sensry,sy1xx-uart"; - reg = <0x1a102000>; + reg = <0x1a102000 0x80>; instance = <0>; current-speed = <1000000>; status = "okay"; @@ -73,7 +79,7 @@ uart1: uart@1a102080 { compatible = "sensry,sy1xx-uart"; - reg = <0x1a102080>; + reg = <0x1a102080 0x80>; instance = <1>; current-speed = <1000000>; status = "okay"; @@ -81,11 +87,50 @@ uart2: uart@1a102100 { compatible = "sensry,sy1xx-uart"; - reg = <0x1a102100>; + reg = <0x1a102100 0x80>; instance = <2>; current-speed = <1000000>; status = "okay"; }; + trng: random@1d030100 { + compatible = "sensry,sy1xx-trng"; + reg = <0x1d030100 0x100>; + status = "okay"; + }; + + gpio0: gpio@1a101000 { + compatible = "sensry,sy1xx-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x1a101000 0x20>; + pad-cfg = ; + status = "okay"; + ngpios = <32>; + }; + + pinctrl: pinctrl@1a104000 { + compatible = "sensry,sy1xx-pinctrl"; + reg = <0x1a104000 0x1000>; + status = "okay"; + }; + + mdio0: mdio@1a120020 { + compatible = "sensry,sy1xx-mdio"; + reg = <0x1a120020 0x20>; + status = "disabled"; + + clock-frequency = <450000>; + + #address-cells = <1>; + #size-cells = <0>; + }; + + eth0: ethernet@1a120000 { + compatible = "sensry,sy1xx-mac"; + reg = <0x1a120000 0x1000>, <0x1a102a00 0x100>; + reg-names = "ctrl", "data"; + status = "disabled"; + }; }; }; diff --git a/dts/riscv/sifive/riscv32-fe310.dtsi b/dts/riscv/sifive/riscv32-fe310.dtsi index f2128e1d37bfb..9bcd00c900784 100644 --- a/dts/riscv/sifive/riscv32-fe310.dtsi +++ b/dts/riscv/sifive/riscv32-fe310.dtsi @@ -65,6 +65,12 @@ interrupts-extended = <&hlic 3 &hlic 7>; reg = <0x2000000 0x10000>; }; + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic 7>; + reg = <0x200bff8 0x8 0x2004000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; debug: debug-controller@0 { compatible = "sifive,debug-013", "riscv,debug-013"; interrupts-extended = <&hlic 65535>; diff --git a/dts/riscv/sifive/riscv64-fu540.dtsi b/dts/riscv/sifive/riscv64-fu540.dtsi index 065870fac61bf..a730157bcec26 100644 --- a/dts/riscv/sifive/riscv64-fu540.dtsi +++ b/dts/riscv/sifive/riscv64-fu540.dtsi @@ -182,6 +182,17 @@ reg = <0x2000000 0x10000>; }; + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic0 7 + &hlic1 7 + &hlic2 7 + &hlic3 7 + &hlic4 7>; + reg = <0x200bff8 0x8 0x2004000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + l2lim: l2lim@8000000 { compatible = "sifive,l2lim0"; reg = <0x8000000 0x2000000>; diff --git a/dts/riscv/sifive/riscv64-fu740.dtsi b/dts/riscv/sifive/riscv64-fu740.dtsi index 4b82d6338bc55..db9a60e970a4c 100644 --- a/dts/riscv/sifive/riscv64-fu740.dtsi +++ b/dts/riscv/sifive/riscv64-fu740.dtsi @@ -137,13 +137,23 @@ reg = <0x0 0x2000000 0x0 0x10000>; }; + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic0 7 + &hlic1 7 + &hlic2 7 + &hlic3 7 + &hlic4 7>; + reg = <0x0 0x200bff8 0x0 0x8 0x0 0x2004000 0x0 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + l2lim: l2lim@8000000 { compatible = "sifive,l2lim0"; reg = <0x0 0x8000000 0x0 0x200000>; reg-names = "mem"; }; - plic: interrupt-controller@c000000 { compatible = "sifive,plic-1.0.0"; #address-cells = <0>; diff --git a/dts/riscv/starfive/jh7110-visionfive-v2.dtsi b/dts/riscv/starfive/jh7110-visionfive-v2.dtsi index c3382bca86f2b..49c231f78870d 100644 --- a/dts/riscv/starfive/jh7110-visionfive-v2.dtsi +++ b/dts/riscv/starfive/jh7110-visionfive-v2.dtsi @@ -145,8 +145,8 @@ compatible = "starfive,jh7110", "simple-bus"; ranges; - clint: timer@2000000 { - compatible = "starfive,jh7110-clint", "sifive,clint0"; + clint: clint@2000000 { + compatible = "sifive,clint0"; interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 &cpu1_intc 3 &cpu1_intc 7 &cpu2_intc 3 &cpu2_intc 7 @@ -155,6 +155,17 @@ reg = <0x0 0x2000000 0x0 0x10000>; }; + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&cpu0_intc 7 + &cpu1_intc 7 + &cpu2_intc 7 + &cpu3_intc 7 + &cpu4_intc 7>; + reg = <0x0 0x200bff8 0x0 0x8 0x0 0x2004000 0x0 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + ccache: cache-controller@2010000 { cache-block-size = <64>; cache-level = <2>; diff --git a/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi b/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi index c36ea625b02fe..fec2afc9f3fe6 100644 --- a/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi +++ b/dts/riscv/starfive/starfive_jh7100_beagle_v.dtsi @@ -115,12 +115,19 @@ }; clint: clint@2000000 { - compatible = "starfive,jh7100-clint", "sifive,clint0"; + compatible = "sifive,clint0"; interrupts-extended = <&cpu0intctrl 3 &cpu0intctrl 7 &cpu1intctrl 3 &cpu1intctrl 7>; reg = <0x0 0x2000000 0x0 0x10000>; }; + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&cpu0intctrl 7 &cpu1intctrl 7>; + reg = <0x0 0x200bff8 0x0 0x8 0x0 0x2004000 0x0 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + plic: plic@c000000 { compatible = "sifive,plic-1.0.0"; #address-cells = <0>; diff --git a/dts/riscv/telink/telink_b91.dtsi b/dts/riscv/telink/telink_b91.dtsi index a75929f2814ad..e6f7079d45aa8 100644 --- a/dts/riscv/telink/telink_b91.dtsi +++ b/dts/riscv/telink/telink_b91.dtsi @@ -48,10 +48,10 @@ }; mtimer: timer@e6000000 { - compatible = "telink,machine-timer"; - reg = <0xe6000000 0x10000>; - interrupts = <7 0>; - interrupt-parent = <&plic0>; + compatible = "riscv,machine-timer"; + reg = <0xe6000000 0x8 0xe6000008 0x8>; + reg-names = "mtime", "mtimecmp"; + interrupts-extended = <&plic0 7 0>; }; flash_mspi: flash-controller@80140100 { diff --git a/dts/riscv/wch/ch32v0/ch32v003.dtsi b/dts/riscv/wch/ch32v0/ch32v003.dtsi new file mode 100644 index 0000000000000..e0a90b855e9ab --- /dev/null +++ b/dts/riscv/wch/ch32v0/ch32v003.dtsi @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +/ { + clocks { + clk_hse: clk-hse { + #clock-cells = <0>; + compatible = "wch,ch32v00x-hse-clock"; + status = "disabled"; + }; + + clk_hsi: clk-hsi { + #clock-cells = <0>; + compatible = "wch,ch32v00x-hsi-clock"; + clock-frequency = ; + status = "disabled"; + }; + + clk_lsi: clk-lsi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + status = "disabled"; + }; + + pll: pll { + #clock-cells = <0>; + compatible = "wch,ch32v00x-pll-clock"; + status = "disabled"; + }; + }; + + soc { + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(2)>; + }; + + flash: flash-controller@40022000 { + compatible = "wch,ch32v00x-flash-controller"; + reg = <0x40022000 0x400>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_K(16)>; + }; + }; + + pwr: pwr@40007000 { + compatible = "wch,pwr"; + reg = <0x40007000 0x10>; + }; + + pinctrl: pin-controller@40010000 { + compatible = "wch,afio"; + reg = <0x40010000 0x10>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + gpioa: gpio@40010800 { + compatible = "wch,gpio"; + reg = <0x40010800 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + gpio-reserved-ranges = <0 1>, <3 5>; + clocks = <&rcc CH32V00X_CLOCK_IOPA>; + }; + + gpioc: gpio@40011000 { + compatible = "wch,gpio"; + reg = <0x40011000 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + clocks = <&rcc CH32V00X_CLOCK_IOPC>; + }; + + gpiod: gpio@40011400 { + compatible = "wch,gpio"; + reg = <0x40011400 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + clocks = <&rcc CH32V00X_CLOCK_IOPD>; + }; + }; + + usart1: uart@40013800 { + compatible = "wch,usart"; + reg = <0x40013800 0x10>; + clocks = <&rcc CH32V00X_CLOCK_USART1>; + interrupt-parent = <&pfic>; + interrupts = <32>; + }; + + rcc: rcc@40021000 { + compatible = "wch,rcc"; + reg = <0x40021000 0x10>; + #clock-cells = <1>; + status = "okay"; + }; + }; +}; + +&cpu0 { + clock-frequency = ; +}; diff --git a/dts/riscv/wch/ch32v0/ch32v003a4m.dtsi b/dts/riscv/wch/ch32v0/ch32v003a4m.dtsi new file mode 100644 index 0000000000000..62e16a8f0ab93 --- /dev/null +++ b/dts/riscv/wch/ch32v0/ch32v003a4m.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gpioc { + gpio-reserved-ranges = <5 1>; +}; + +&gpiod { + gpio-reserved-ranges = <0 1>, <2 2>; +}; diff --git a/dts/riscv/wch/ch32v0/ch32v003f4p.dtsi b/dts/riscv/wch/ch32v0/ch32v003f4p.dtsi new file mode 100644 index 0000000000000..005a5e9257dab --- /dev/null +++ b/dts/riscv/wch/ch32v0/ch32v003f4p.dtsi @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/dts/riscv/wch/ch32v0/ch32v003f4u.dtsi b/dts/riscv/wch/ch32v0/ch32v003f4u.dtsi new file mode 100644 index 0000000000000..005a5e9257dab --- /dev/null +++ b/dts/riscv/wch/ch32v0/ch32v003f4u.dtsi @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/dts/riscv/wch/ch32v0/ch32v003j4m.dtsi b/dts/riscv/wch/ch32v0/ch32v003j4m.dtsi new file mode 100644 index 0000000000000..573a863247316 --- /dev/null +++ b/dts/riscv/wch/ch32v0/ch32v003j4m.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gpioc { + gpio-reserved-ranges = <0 1>, <3 1>, <5 3>; +}; + +&gpiod { + gpio-reserved-ranges = <0 1>, <2 2>, <7 1>; +}; diff --git a/dts/riscv/wch/ch32v00x.dtsi b/dts/riscv/wch/ch32v00x.dtsi deleted file mode 100644 index 0066dc1992d29..0000000000000 --- a/dts/riscv/wch/ch32v00x.dtsi +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2024 Michael Hope - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -/ { - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "wch,qingke-v2"; - reg = <0>; - clock-frequency = ; - }; - }; - - clocks { - clk_hse: clk-hse { - #clock-cells = <0>; - compatible = "wch,ch32v00x-hse-clock"; - status = "disabled"; - }; - - clk_hsi: clk-hsi { - #clock-cells = <0>; - compatible = "wch,ch32v00x-hsi-clock"; - clock-frequency = ; - status = "disabled"; - }; - - clk_lsi: clk-lsi { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = ; - status = "disabled"; - }; - - pll: pll { - #clock-cells = <0>; - compatible = "wch,ch32v00x-pll-clock"; - status = "disabled"; - }; - }; - - soc { - #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - ranges; - - sram0: memory@20000000 { - compatible = "mmio-sram"; - reg = <0x20000000 0x800>; - }; - - flash: flash-controller@40022000 { - compatible = "wch,ch32v00x-flash-controller"; - reg = <0x40022000 0x400>; - - #address-cells = <1>; - #size-cells = <1>; - - flash0: flash@0 { - compatible = "soc-nv-flash"; - reg = <0 0x4000>; - }; - }; - - pfic: interrupt-controller@e000e000 { - compatible = "wch,pfic"; - #address-cells = <0>; - #interrupt-cells = <1>; - interrupt-controller; - reg = <0xe000e000 16>; - status = "okay"; - }; - - systick: systimer@e000f000 { - compatible = "wch,systick"; - reg = <0xe000f000 16>; - status = "okay"; - interrupt-parent = <&pfic>; - interrupts = <12>; - }; - - pwr: pwr@40007000 { - compatible = "wch,pwr"; - reg = <0x40007000 16>; - }; - - pinctrl: pin-controller@40010000 { - compatible = "wch,afio"; - reg = <0x40010000 16>; - #address-cells = <1>; - #size-cells = <1>; - status = "okay"; - - gpioa: gpio@40010800 { - compatible = "wch,gpio"; - reg = <0x40010800 32>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - clocks = <&rcc CH32V00X_CLOCK_IOPA>; - }; - - gpioc: gpio@40011000 { - compatible = "wch,gpio"; - reg = <0x40011000 32>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - clocks = <&rcc CH32V00X_CLOCK_IOPC>; - }; - - gpiod: gpio@40011400 { - compatible = "wch,gpio"; - reg = <0x40011400 32>; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - clocks = <&rcc CH32V00X_CLOCK_IOPD>; - }; - }; - - usart1: uart@40013800 { - compatible = "wch,usart"; - reg = <0x40013800 16>; - clocks = <&rcc CH32V00X_CLOCK_USART1>; - interrupt-parent = <&pfic>; - interrupts = <32>; - }; - - rcc: rcc@40021000 { - compatible = "wch,rcc"; - reg = <0x40021000 16>; - #clock-cells = <1>; - status = "okay"; - }; - }; -}; diff --git a/dts/riscv/wch/qingke-v2.dtsi b/dts/riscv/wch/qingke-v2.dtsi new file mode 100644 index 0000000000000..a82ce935a53bd --- /dev/null +++ b/dts/riscv/wch/qingke-v2.dtsi @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "wch,qingke-v2"; + reg = <0>; + riscv,isa = "rv32ec_zicsr_zifencei"; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + pfic: interrupt-controller@e000e000 { + compatible = "wch,pfic"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0xe000e000 0x10>; + status = "okay"; + }; + + systick: systimer@e000f000 { + compatible = "wch,systick"; + reg = <0xe000f000 0x10>; + status = "okay"; + interrupt-parent = <&pfic>; + interrupts = <12>; + }; + }; +}; diff --git a/dts/x86/intel/alder_lake.dtsi b/dts/x86/intel/alder_lake.dtsi index 78df9c3cc52da..110cc23872911 100644 --- a/dts/x86/intel/alder_lake.dtsi +++ b/dts/x86/intel/alder_lake.dtsi @@ -25,7 +25,7 @@ cpu@1 { device_type = "cpu"; - compatible = "intel,alder-lake"; + compatible = "intel,alder-lake", "intel,x86_64"; d-cache-line-size = <64>; reg = <1>; }; diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi index 6a47843b9998e..b0eb83690494c 100644 --- a/dts/xtensa/espressif/esp32/esp32_common.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi @@ -94,19 +94,57 @@ }; soc { - sram0: memory@3ffb0000 { - compatible = "mmio-sram"; - reg = <0x3FFB0000 0x2c200>; + sram0: memory@40070000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x40070000 DT_SIZE_K(192)>; + zephyr,memory-region = "SRAM0"; + }; + + sram1: memory@3ffe0000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x3ffe0000 DT_SIZE_K(128)>; + zephyr,memory-region = "SRAM1"; + }; + + sram2: memory@3ffae000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x3ffae000 DT_SIZE_K(200)>; + zephyr,memory-region = "SRAM2"; }; ipmmem0: memory@3ffe5230 { compatible = "mmio-sram"; - reg = <0x3FFE5230 0x400>; + reg = <0x3ffe5230 0x400>; }; shm0: memory@3ffe5630 { compatible = "mmio-sram"; - reg = <0x3FFE5630 0x3C00>; + reg = <0x3ffe5630 0x4000>; + }; + + ipm0: ipm@3ffe9630 { + compatible = "espressif,esp32-ipm"; + reg = <0x3ffe9630 0x8>; + status = "disabled"; + shared-memory = <&ipmmem0>; + shared-memory-size = <0x400>; + interrupts = + , + ; + interrupt-parent = <&intc>; + }; + + mbox0: mbox@3ffe9638 { + compatible = "espressif,mbox-esp32"; + reg = <0x3ffe9638 0x8>; + status = "disabled"; + shared-memory = <&ipmmem0>; + shared-memory-size = <0x400>; + interrupts = + , + ; + interrupt-parent = <&intc>; + #mbox-cells = <1>; }; intc: interrupt-controller@3ff00104 { @@ -159,31 +197,6 @@ status = "disabled"; }; - ipm0: ipm@3ffed238 { - compatible = "espressif,esp32-ipm"; - reg = <0x3FFED238 0x8>; - status = "disabled"; - shared-memory = <&ipmmem0>; - shared-memory-size = <0x400>; - interrupts = - , - ; - interrupt-parent = <&intc>; - }; - - mbox0: mbox@3ffed240 { - compatible = "espressif,mbox-esp32"; - reg = <0x3FFED240 0x8>; - status = "disabled"; - shared-memory = <&ipmmem0>; - shared-memory-size = <0x400>; - interrupts = - , - ; - interrupt-parent = <&intc>; - #mbox-cells = <1>; - }; - ipi0: ipi@3f4c0058 { compatible = "espressif,crosscore-interrupt"; reg = <0x3f4c0058 0x4>; @@ -389,6 +402,7 @@ timer0: counter@3ff5f000 { compatible = "espressif,esp32-timer"; reg = <0x3ff5f000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; group = <0>; index = <0>; interrupts = ; @@ -399,6 +413,7 @@ timer1: counter@3ff5f024 { compatible = "espressif,esp32-timer"; reg = <0x3ff5f024 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; group = <0>; index = <1>; interrupts = ; @@ -409,6 +424,7 @@ timer2: counter@3ff60000 { compatible = "espressif,esp32-timer"; reg = <0x3ff60000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG1_MODULE>; group = <1>; index = <0>; interrupts = ; @@ -419,6 +435,7 @@ timer3: counter@3ff60024 { compatible = "espressif,esp32-timer"; reg = <0x3ff60024 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG1_MODULE>; group = <1>; index = <1>; interrupts = ; @@ -439,6 +456,7 @@ adc0: adc@3ff48800 { compatible = "espressif,esp32-adc"; reg = <0x3ff48800 10>; + clocks = <&rtc ESP32_SARADC_MODULE>; unit = <1>; channel-count = <8>; #io-channel-cells = <1>; @@ -448,6 +466,7 @@ adc1: adc@3ff48890 { compatible = "espressif,esp32-adc"; reg = <0x3ff48890 10>; + clocks = <&rtc ESP32_SARADC_MODULE>; unit = <2>; channel-count = <10>; #io-channel-cells = <1>; diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi index 43ce14117a51c..7551364f3f1c6 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n16.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi index 8f5f3d9dd1094..9773b62f99e96 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n4.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi index 42813aa6e6882..143cf1cc098e8 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_32ue_n8.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 8MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi index f9f3bd8120105..f86f7c520639e 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_da_n16.dtsi @@ -14,7 +14,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi index 98f6d9dc9b2d5..da7f73036ead8 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_da_n4.dtsi @@ -14,7 +14,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi b/dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi index 7beeda4e13659..157c21048e681 100644 --- a/dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wroom_da_n8.dtsi @@ -14,7 +14,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 8MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi index 393dfa7b95133..4aa681336ac52 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r2.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi index 160800afdca8c..37e2b62a0041f 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r4.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi index acac866076fff..73ec91dca44ba 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n16r8.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 16MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi index 8e463a3b3a747..b0ab013feb3b2 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r2.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 1>, <7 1>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi index 0197755fba564..87a2f8930ecd9 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n4r8.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 1>, <7 1>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 4MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi index 5bc98caf70688..6b74a725ed401 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r2.dtsi @@ -13,7 +13,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 8MB flash */ diff --git a/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi b/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi index 0f73058de082e..e5a12caae0c5f 100644 --- a/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_wrover_e_n8r8.dtsi @@ -14,7 +14,7 @@ }; &gpio1 { - gpio-reserved-ranges = <6 2>; // GPIO37-38 NC + gpio-reserved-ranges = <5 2>; // GPIO37-38 NC }; /* 8MB flash */ diff --git a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi index fcedeab665bfa..32c2b92b763a1 100644 --- a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi +++ b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi @@ -80,8 +80,15 @@ ranges; sram0: memory@3ffb0000 { - compatible = "mmio-sram"; - reg = <0x3ffb0000 0x50000>; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x3ffb0000 DT_SIZE_K(32)>; + zephyr,memory-region = "SRAM0"; + }; + + sram1: memory@3ffb8000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x3ffb8000 DT_SIZE_K(288)>; + zephyr,memory-region = "SRAM1"; }; intc: interrupt-controller@3f4c2000 { @@ -238,6 +245,7 @@ timer0: counter@3f41f000 { compatible = "espressif,esp32-timer"; reg = <0x3f41f000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; group = <0>; index = <0>; interrupts = ; @@ -248,6 +256,7 @@ timer1: counter@3f41f024 { compatible = "espressif,esp32-timer"; reg = <0x3f41f024 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; group = <0>; index = <1>; interrupts = ; @@ -258,6 +267,7 @@ timer2: counter@3f420000 { compatible = "espressif,esp32-timer"; reg = <0x3f420000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG1_MODULE>; group = <1>; index = <0>; interrupts = ; @@ -268,6 +278,7 @@ timer3: counter@3f420024 { compatible = "espressif,esp32-timer"; reg = <0x3f420024 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG1_MODULE>; group = <1>; index = <1>; interrupts = ; @@ -339,6 +350,7 @@ adc0: adc@3f440018 { compatible = "espressif,esp32-adc"; reg = <0x3f440018 100>; + clocks = <&rtc ESP32_PERIPH_SARADC_MODULE>; unit = <1>; channel-count = <10>; #io-channel-cells = <1>; @@ -348,6 +360,7 @@ adc1: adc@3f440028 { compatible = "espressif,esp32-adc"; reg = <0x3f440028 100>; + clocks = <&rtc ESP32_PERIPH_SARADC_MODULE>; unit = <2>; channel-count = <10>; #io-channel-cells = <1>; diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi index 3ed7a5b6508c5..dca04dc5f8966 100644 --- a/dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi +++ b/dts/xtensa/espressif/esp32s3/esp32s3_appcpu.dtsi @@ -6,7 +6,7 @@ #include "esp32s3_common.dtsi" -&sram0 { - reg = <0x3fc88000 DT_SIZE_K(10)>; +&sram1 { + reg = <0x3fc88000 DT_SIZE_K(416)>; status = "okay"; }; diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi index ece4bad2be389..95c935a1de6df 100644 --- a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi +++ b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi @@ -86,24 +86,49 @@ compatible = "simple-bus"; ranges; - sram0: memory@3fc88000 { - compatible = "mmio-sram"; - reg = <0x3fc88000 0x77FFF>; + icache0: memory@42000000 { + compatible = "zephyr,memory-region"; + reg = <0x42000000 DT_SIZE_M(32)>; + zephyr,memory-region = "ICACHE"; + }; + + dcache0: memory@3c000000 { + compatible = "zephyr,memory-region"; + reg = <0x3c000000 DT_SIZE_M(32)>; + zephyr,memory-region = "DCACHE"; + }; + + sram0: memory@40370000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x40370000 DT_SIZE_K(32)>; + zephyr,memory-region = "SRAM0"; + }; + + sram1: memory@3fc88000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x3fc88000 DT_SIZE_K(416)>; + zephyr,memory-region = "SRAM1"; }; - ipmmem0: memory@3fcb2000 { + sram2: memory@3fcf0000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x3fcf0000 DT_SIZE_K(64)>; + zephyr,memory-region = "SRAM2"; + }; + + ipmmem0: memory@3fce5000 { compatible = "mmio-sram"; - reg = <0x3fcb2000 0x400>; + reg = <0x3fce5000 0x400>; }; - shm0: memory@3fcb2400 { + shm0: memory@3fce5400 { compatible = "mmio-sram"; - reg = <0x3fcb2400 0x3c00>; + reg = <0x3fce5400 0x4000>; }; - ipm0: ipm@3fcb6000 { + ipm0: ipm@3fce9400 { compatible = "espressif,esp32-ipm"; - reg = <0x3fcb6000 0x8>; + reg = <0x3fce9400 0x8>; status = "disabled"; shared-memory = <&ipmmem0>; shared-memory-size = <0x400>; @@ -113,9 +138,9 @@ interrupt-parent = <&intc>; }; - mbox0: mbox@3fcb6008 { + mbox0: mbox@3fce9408 { compatible = "espressif,mbox-esp32"; - reg = <0x3fcb6008 0x8>; + reg = <0x3fce9408 0x8>; status = "disabled"; shared-memory = <&ipmmem0>; shared-memory-size = <0x400>; @@ -340,6 +365,7 @@ adc0: adc@60040000 { compatible = "espressif,esp32-adc"; reg = <0x60040000 4>; + clocks = <&rtc ESP32_SARADC_MODULE>; unit = <1>; channel-count = <10>; #io-channel-cells = <1>; @@ -349,6 +375,7 @@ adc1: adc@60040004 { compatible = "espressif,esp32-adc"; reg = <0x60040004 4>; + clocks = <&rtc ESP32_SARADC_MODULE>; unit = <2>; channel-count = <10>; #io-channel-cells = <1>; @@ -385,6 +412,7 @@ timer0: counter@6001f000 { compatible = "espressif,esp32-timer"; reg = <0x6001f000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; group = <0>; index = <0>; interrupts = ; @@ -395,6 +423,7 @@ timer1: counter@6001f024 { compatible = "espressif,esp32-timer"; reg = <0x6001f024 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG0_MODULE>; group = <0>; index = <1>; interrupts = ; @@ -405,6 +434,7 @@ timer2: counter@60020000 { compatible = "espressif,esp32-timer"; reg = <0x60020000 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG1_MODULE>; group = <1>; index = <0>; interrupts = ; @@ -415,6 +445,7 @@ timer3: counter@60020024 { compatible = "espressif,esp32-timer"; reg = <0x60020024 DT_SIZE_K(4)>; + clocks = <&rtc ESP32_TIMG1_MODULE>; group = <1>; index = <1>; interrupts = ; diff --git a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi index da00cf53a4ed2..ea44a6211ab93 100644 --- a/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace15_mtpm.dtsi @@ -156,6 +156,7 @@ interrupts = <0x08 0 0>; interrupt-parent = <&ace_intc>; power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; }; dmic1: dmic1@10000 { @@ -166,6 +167,7 @@ interrupts = <0x09 0 0>; interrupt-parent = <&ace_intc>; power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; }; /* @@ -290,12 +292,13 @@ dmas = <&lpgpdma0 2 &lpgpdma0 3>; dma-names = "tx", "rx"; - power-domains = <&io0_domain>; ssp-index = <0>; status = "okay"; ssp00: ssp@0 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0>; }; @@ -312,12 +315,13 @@ dmas = <&lpgpdma0 4 &lpgpdma0 5>; dma-names = "tx", "rx"; - power-domains = <&io0_domain>; ssp-index = <1>; status = "okay"; ssp10: ssp@10 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x10>; }; @@ -334,12 +338,13 @@ dmas = <&lpgpdma0 6 &lpgpdma0 7>; dma-names = "tx", "rx"; - power-domains = <&io0_domain>; ssp-index = <2>; status = "okay"; ssp20: ssp@20 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x20>; }; @@ -478,7 +483,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <16>; - power-domains = <&io0_domain>; + power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -490,7 +496,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <16>; - power-domains = <&io0_domain>; + power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -503,6 +510,7 @@ dma-buf-size-alignment = <32>; dma-copy-alignment = <16>; power-domains = <&hst_domain>; + zephyr,pm-device-runtime-auto; interrupts = <13 0 0>; interrupt-parent = <&ace_intc>; status = "okay"; @@ -517,6 +525,7 @@ dma-buf-size-alignment = <32>; dma-copy-alignment = <16>; power-domains = <&hst_domain>; + zephyr,pm-device-runtime-auto; interrupts = <12 0 0>; interrupt-parent = <&ace_intc>; status = "okay"; @@ -612,96 +621,134 @@ hda0: hda@0 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0>; }; hda1: hda@1 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <1>; }; hda2: hda@2 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <2>; }; hda3: hda@3 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <3>; }; hda4: hda@4 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <4>; }; hda5: hda@5 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <5>; }; hda6: hda@6 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <6>; }; hda7: hda@7 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <7>; }; hda8: hda@8 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <8>; }; hda9: hda@9 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <9>; }; hda10: hda@a { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0a>; }; hda11: hda@b { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0b>; }; hda12: hda@c { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0c>; }; hda13: hda@d { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0d>; }; hda14: hda@e { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0e>; }; hda15: hda@f { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0f>; }; hda16: hda@10 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x10>; }; hda17: hda@11 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x11>; }; hda18: hda@12 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x12>; }; diff --git a/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi b/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi index 66a5784185097..bb53fe74f331e 100644 --- a/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace20_lnl.dtsi @@ -180,6 +180,7 @@ fifo = <0x0008>; interrupts = <0x08 0 0>; interrupt-parent = <&ace_intc>; + zephyr,pm-device-runtime-auto; }; dmic1: dai-dmic1@10100 { @@ -189,6 +190,7 @@ fifo = <0x0108>; interrupts = <0x08 0 0>; interrupt-parent = <&ace_intc>; + zephyr,pm-device-runtime-auto; }; dmicvss: dmicvss@16000 { @@ -220,12 +222,13 @@ dmas = <&hda_link_out 1 &hda_link_in 1>; dma-names = "tx", "rx"; - power-domains = <&io0_domain>; ssp-index = <0>; status = "okay"; ssp00: ssp@0 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0>; }; @@ -243,12 +246,13 @@ dmas = <&hda_link_out 2 &hda_link_in 2>; dma-names = "tx", "rx"; - power-domains = <&io0_domain>; ssp-index = <1>; status = "okay"; ssp10: ssp@10 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x10>; }; @@ -266,12 +270,13 @@ dmas = <&hda_link_out 3 &hda_link_in 3>; dma-names = "tx", "rx"; - power-domains = <&io0_domain>; ssp-index = <2>; status = "okay"; ssp20: ssp@20 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x20>; }; @@ -383,6 +388,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <16>; + power-domains = <&hst_domain>; + zephyr,pm-device-runtime-auto; interrupts = <13 0 0>; interrupt-parent = <&ace_intc>; status = "okay"; @@ -396,6 +403,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <16>; + power-domains = <&hst_domain>; + zephyr,pm-device-runtime-auto; interrupts = <12 0 0>; interrupt-parent = <&ace_intc>; status = "okay"; @@ -417,6 +426,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <16>; + power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -428,6 +439,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <16>; + power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -466,96 +479,134 @@ hda0: hda@0 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0>; }; hda1: hda@1 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <1>; }; hda2: hda@2 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <2>; }; hda3: hda@3 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <3>; }; hda4: hda@4 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <4>; }; hda5: hda@5 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <5>; }; hda6: hda@6 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <6>; }; hda7: hda@7 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <7>; }; hda8: hda@8 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <8>; }; hda9: hda@9 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <9>; }; hda10: hda@a { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0a>; }; hda11: hda@b { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0b>; }; hda12: hda@c { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0c>; }; hda13: hda@d { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0d>; }; hda14: hda@e { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0e>; }; hda15: hda@f { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0f>; }; hda16: hda@10 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x10>; }; hda17: hda@11 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x11>; }; hda18: hda@12 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x12>; }; diff --git a/dts/xtensa/intel/intel_adsp_ace30.dtsi b/dts/xtensa/intel/intel_adsp_ace30.dtsi index 26ae1c47f560f..78574b49553bb 100644 --- a/dts/xtensa/intel/intel_adsp_ace30.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace30.dtsi @@ -170,6 +170,7 @@ interrupts = <0x08 0 0>; interrupt-parent = <&ace_intc>; power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; }; dmic1: dai-dmic1@10100 { @@ -180,6 +181,7 @@ interrupts = <0x08 0 0>; interrupt-parent = <&ace_intc>; power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; }; dmicvss: dmicvss@16000 { @@ -212,53 +214,68 @@ &hda_link_in 1>; dma-names = "tx", "rx"; ssp-index = <0>; - power-domains = <&io0_domain>; status = "okay"; ssp00: ssp@0 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x0>; status = "okay"; }; ssp01: ssp@1 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x1>; status = "okay"; }; ssp02: ssp@2 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x2>; status = "okay"; }; ssp03: ssp@3 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x3>; status = "okay"; }; ssp04: ssp@4 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x4>; status = "okay"; }; ssp05: ssp@5 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x5>; status = "okay"; }; ssp06: ssp@6 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x6>; status = "okay"; }; ssp07: ssp@7 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x7>; status = "okay"; }; @@ -277,53 +294,68 @@ &hda_link_in 2>; dma-names = "tx", "rx"; ssp-index = <1>; - power-domains = <&io0_domain>; status = "okay"; ssp10: ssp@10 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x10>; status = "okay"; }; ssp11: ssp@11 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x11>; status = "okay"; }; ssp12: ssp@12 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x12>; status = "okay"; }; ssp13: ssp@13 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x13>; status = "okay"; }; ssp14: ssp@14 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x14>; status = "okay"; }; ssp15: ssp@15 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x15>; status = "okay"; }; ssp16: ssp@16 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x16>; status = "okay"; }; ssp17: ssp@17 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x17>; status = "okay"; }; @@ -342,53 +374,68 @@ &hda_link_in 3>; dma-names = "tx", "rx"; ssp-index = <2>; - power-domains = <&io0_domain>; status = "okay"; ssp20: ssp@20 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x20>; status = "okay"; }; ssp21: ssp@21 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x21>; status = "okay"; }; ssp22: ssp@22 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x22>; status = "okay"; }; ssp23: ssp@23 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x23>; status = "okay"; }; ssp24: ssp@24 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x24>; status = "okay"; }; ssp25: ssp@25 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x25>; status = "okay"; }; ssp26: ssp@26 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x26>; status = "okay"; }; ssp27: ssp@27 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x27>; status = "okay"; }; @@ -505,6 +552,7 @@ dma-buf-size-alignment = <32>; dma-copy-alignment = <32>; power-domains = <&hst_domain>; + zephyr,pm-device-runtime-auto; interrupts = <13 0 0>; interrupt-parent = <&ace_intc>; status = "okay"; @@ -519,6 +567,7 @@ dma-buf-size-alignment = <32>; dma-copy-alignment = <32>; power-domains = <&hst_domain>; + zephyr,pm-device-runtime-auto; interrupts = <12 0 0>; interrupt-parent = <&ace_intc>; status = "okay"; @@ -540,7 +589,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <32>; - power-domains = <&io0_domain>; + power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -552,7 +602,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <32>; - power-domains = <&io0_domain>; + power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -591,96 +642,134 @@ hda0: hda@0 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0>; }; hda1: hda@1 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <1>; }; hda2: hda@2 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <2>; }; hda3: hda@3 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <3>; }; hda4: hda@4 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <4>; }; hda5: hda@5 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <5>; }; hda6: hda@6 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <6>; }; hda7: hda@7 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <7>; }; hda8: hda@8 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <8>; }; hda9: hda@9 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <9>; }; hda10: hda@a { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0a>; }; hda11: hda@b { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0b>; }; hda12: hda@c { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0c>; }; hda13: hda@d { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0d>; }; hda14: hda@e { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0e>; }; hda15: hda@f { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0f>; }; hda16: hda@10 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x10>; }; hda17: hda@11 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x11>; }; hda18: hda@12 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x12>; }; diff --git a/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi b/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi index a7c39cceac9c1..d28ef58ec4d17 100644 --- a/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi +++ b/dts/xtensa/intel/intel_adsp_ace30_ptl.dtsi @@ -175,6 +175,7 @@ interrupts = <0x08 0 0>; interrupt-parent = <&ace_intc>; power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; }; dmic1: dai-dmic1@10100 { @@ -185,6 +186,7 @@ interrupts = <0x08 0 0>; interrupt-parent = <&ace_intc>; power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; }; dmicvss: dmicvss@16000 { @@ -217,53 +219,68 @@ &hda_link_in 1>; dma-names = "tx", "rx"; ssp-index = <0>; - power-domains = <&io0_domain>; status = "okay"; ssp00: ssp@0 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x0>; status = "okay"; }; ssp01: ssp@1 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x1>; status = "okay"; }; ssp02: ssp@2 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x2>; status = "okay"; }; ssp03: ssp@3 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x3>; status = "okay"; }; ssp04: ssp@4 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x4>; status = "okay"; }; ssp05: ssp@5 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x5>; status = "okay"; }; ssp06: ssp@6 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x6>; status = "okay"; }; ssp07: ssp@7 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x7>; status = "okay"; }; @@ -282,53 +299,68 @@ &hda_link_in 2>; dma-names = "tx", "rx"; ssp-index = <1>; - power-domains = <&io0_domain>; status = "okay"; ssp10: ssp@10 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x10>; status = "okay"; }; ssp11: ssp@11 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x11>; status = "okay"; }; ssp12: ssp@12 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x12>; status = "okay"; }; ssp13: ssp@13 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x13>; status = "okay"; }; ssp14: ssp@14 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x14>; status = "okay"; }; ssp15: ssp@15 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x15>; status = "okay"; }; ssp16: ssp@16 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x16>; status = "okay"; }; ssp17: ssp@17 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x17>; status = "okay"; }; @@ -347,58 +379,81 @@ &hda_link_in 3>; dma-names = "tx", "rx"; ssp-index = <2>; - power-domains = <&io0_domain>; status = "okay"; ssp20: ssp@20 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x20>; status = "okay"; }; ssp21: ssp@21 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x21>; status = "okay"; }; ssp22: ssp@22 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x22>; status = "okay"; }; ssp23: ssp@23 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x23>; status = "okay"; }; ssp24: ssp@24 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x24>; status = "okay"; }; ssp25: ssp@25 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x25>; status = "okay"; }; ssp26: ssp@26 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x26>; status = "okay"; }; ssp27: ssp@27 { compatible = "intel,ssp-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; reg = <0x27>; status = "okay"; }; }; + mic_privacy: mic-prv@71a40 { + compatible = "intel,adsp-mic-privacy"; + reg = <0x71a40 0x8000>; + interrupts = <29 0 0>; + interrupt-parent = <&ace_intc>; + status = "okay"; + }; + mem_window0: mem_window@70200 { compatible = "intel,adsp-mem-window"; reg = <0x70200 0x8>; @@ -510,6 +565,7 @@ dma-buf-size-alignment = <32>; dma-copy-alignment = <32>; power-domains = <&hst_domain>; + zephyr,pm-device-runtime-auto; interrupts = <13 0 0>; interrupt-parent = <&ace_intc>; status = "okay"; @@ -524,6 +580,7 @@ dma-buf-size-alignment = <32>; dma-copy-alignment = <32>; power-domains = <&hst_domain>; + zephyr,pm-device-runtime-auto; interrupts = <12 0 0>; interrupt-parent = <&ace_intc>; status = "okay"; @@ -545,7 +602,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <32>; - power-domains = <&io0_domain>; + power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -557,7 +615,8 @@ dma-buf-addr-alignment = <128>; dma-buf-size-alignment = <32>; dma-copy-alignment = <32>; - power-domains = <&io0_domain>; + power-domains = <&hub_ulp_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; }; @@ -572,7 +631,7 @@ interrupt-controller; #interrupt-cells = <3>; interrupts = <4 0 0>; - num-irqs = <28>; + num-irqs = <30>; interrupt-parent = <&core_intc>; }; @@ -596,96 +655,134 @@ hda0: hda@0 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0>; }; hda1: hda@1 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <1>; }; hda2: hda@2 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <2>; }; hda3: hda@3 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <3>; }; hda4: hda@4 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <4>; }; hda5: hda@5 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <5>; }; hda6: hda@6 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <6>; }; hda7: hda@7 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <7>; }; hda8: hda@8 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <8>; }; hda9: hda@9 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <9>; }; hda10: hda@a { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0a>; }; hda11: hda@b { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0b>; }; hda12: hda@c { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0c>; }; hda13: hda@d { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0d>; }; hda14: hda@e { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0e>; }; hda15: hda@f { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x0f>; }; hda16: hda@10 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x10>; }; hda17: hda@11 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x11>; }; hda18: hda@12 { compatible = "intel,hda-dai"; + power-domains = <&io0_domain>; + zephyr,pm-device-runtime-auto; status = "okay"; reg = <0x12>; }; diff --git a/dts/xtensa/nxp/nxp_imx8.dtsi b/dts/xtensa/nxp/nxp_imx8.dtsi index 5402e678525f9..bb522072fb59b 100644 --- a/dts/xtensa/nxp/nxp_imx8.dtsi +++ b/dts/xtensa/nxp/nxp_imx8.dtsi @@ -32,76 +32,85 @@ }; }; - irqsteer: interrupt-controller@510a0000 { - compatible = "nxp,irqsteer-intc"; - reg = <0x510a0000 DT_SIZE_K(64)>; - power-domains = <&irqstr_pd>; - - #size-cells = <0>; - #address-cells = <1>; - - master0: interrupt-controller@0 { - compatible = "nxp,irqsteer-master"; - reg = <0>; - interrupt-controller; - #interrupt-cells = <1>; - interrupts-extended = <&clic 19 0 0>; + scu: system-controller { + ccm: clock-controller { + compatible = "nxp,imx-ccm"; + #clock-cells = <3>; }; - master1: interrupt-controller@1 { - compatible = "nxp,irqsteer-master"; - reg = <1>; - interrupt-controller; - #interrupt-cells = <1>; - interrupts-extended = <&clic 20 0 0>; + iomuxc: iomuxc { + compatible = "nxp,imx-iomuxc-scu"; + pinctrl: pinctrl { + compatible = "nxp,imx8-pinctrl"; + }; }; - master2: interrupt-controller@2 { - compatible = "nxp,irqsteer-master"; - reg = <2>; - interrupt-controller; - #interrupt-cells = <1>; - interrupts-extended = <&clic 21 0 0>; - }; + power-domains { + #address-cells = <1>; + #size-cells = <0>; - master3: interrupt-controller@3 { - compatible = "nxp,irqsteer-master"; - reg = <3>; - interrupt-controller; - #interrupt-cells = <1>; - interrupts-extended = <&clic 22 0 0>; - }; + irqstr_pd: pd@0 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <0>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; - master4: interrupt-controller@4 { - compatible = "nxp,irqsteer-master"; - reg = <4>; - interrupt-controller; - #interrupt-cells = <1>; - interrupts-extended = <&clic 23 0 0>; - }; + edma0_ch6_pd: pd@1 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <1>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; - master5: interrupt-controller@5 { - compatible = "nxp,irqsteer-master"; - reg = <5>; - interrupt-controller; - #interrupt-cells = <1>; - interrupts-extended = <&clic 24 0 0>; - }; + edma0_ch7_pd: pd@2 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <2>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; - master6: interrupt-controller@6 { - compatible = "nxp,irqsteer-master"; - reg = <6>; - interrupt-controller; - #interrupt-cells = <1>; - interrupts-extended = <&clic 25 0 0>; - }; + edma0_ch14_pd: pd@3 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <3>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; + + edma0_ch15_pd: pd@4 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <4>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; - master7: interrupt-controller@7 { - compatible = "nxp,irqsteer-master"; - reg = <7>; - interrupt-controller; - #interrupt-cells = <1>; - interrupts-extended = <&clic 26 0 0>; + edma2_ch6_pd: pd@5 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <5>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; + + edma2_ch7_pd: pd@6 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <6>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; + + edma2_ch14_pd: pd@7 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <7>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; + + edma2_ch15_pd: pd@8 { + compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; + reg = <8>; + nxp,resource-id = ; + #power-domain-cells = <0>; + }; }; }; @@ -121,6 +130,8 @@ compatible = "nxp,edma"; reg = <0x591f0000 (DT_SIZE_K(64) * 33)>; valid-channels = <6>, <7>, <14>, <15>; + power-domains = <&edma0_ch6_pd>, <&edma0_ch7_pd>, + <&edma0_ch14_pd>, <&edma0_ch15_pd>; interrupts-extended = <&master6 58>, <&master6 58>, <&master5 29>, <&master5 29>; #dma-cells = <2>; @@ -159,34 +170,8 @@ reg = <0x5d1d0000 DT_SIZE_K(64)>; }; - scu: system-controller { - ccm: clock-controller { - compatible = "nxp,imx-ccm"; - #clock-cells = <3>; - }; - - iomuxc: iomuxc { - compatible = "nxp,imx-iomuxc-scu"; - pinctrl: pinctrl { - compatible = "nxp,imx8-pinctrl"; - }; - }; - - power-domains { - #address-cells = <1>; - #size-cells = <0>; - - irqstr_pd: pd@0 { - compatible = "nxp,imx8qm-scu-pd", "nxp,scu-pd"; - reg = <0>; - nxp,resource-id = ; - #power-domain-cells = <0>; - }; - }; - }; - lpuart2: serial@5a080000 { - compatible = "nxp,imx-lpuart", "nxp,kinetis-lpuart"; + compatible = "nxp,imx-lpuart", "nxp,lpuart"; reg = <0x5a080000 DT_SIZE_K(4)>; interrupt-parent = <&master4>; interrupts = <3>; diff --git a/dts/xtensa/nxp/nxp_imx8m.dtsi b/dts/xtensa/nxp/nxp_imx8m.dtsi index 76052836917b9..036d1ef07e3da 100644 --- a/dts/xtensa/nxp/nxp_imx8m.dtsi +++ b/dts/xtensa/nxp/nxp_imx8m.dtsi @@ -42,6 +42,12 @@ reg = <0x92c00000 DT_SIZE_K(512)>; }; + mclk1: mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <12288000>; + }; + soc { irqsteer: interrupt-controller@30a80000 { compatible = "nxp,irqsteer-intc"; @@ -81,6 +87,41 @@ #clock-cells = <3>; }; + sdma3: dma@30e00000 { + compatible = "nxp,sdma"; + reg = <0x30e00000 DT_SIZE_K(64)>; + interrupt-parent = <&master1>; + interrupts = <2 0 0>; + #dma-cells = <2>; + status = "disabled"; + }; + + sai3: dai@30c30000 { + compatible = "nxp,dai-sai"; + reg = <0x30c30000 DT_SIZE_K(64)>; + + mclk-is-output; + clocks = <&mclk1>; + clock-names = "mclk1"; + + interrupt-parent = <&master1>; + interrupts = <18>; + dai-index = <3>; + /* DMA event source, peripheral type */ + dmas = <&sdma3 5 5>, <&sdma3 4 5>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + micfil: micfil@30ca0000 { + compatible = "nxp,dai-micfil"; + reg = <0x30ca0000 DT_SIZE_K(64)>; + dai-index = <2>; + dmas = <&sdma3 24 6>; + fifo-depth = <32>; + status = "disabled"; + }; + iomuxc: iomuxc@30330000 { compatible = "nxp,imx-iomuxc"; reg = <0x30330000 DT_SIZE_K(64)>; diff --git a/dts/xtensa/nxp/nxp_imx8qm.dtsi b/dts/xtensa/nxp/nxp_imx8qm.dtsi new file mode 100644 index 0000000000000..a5ecb74a2051b --- /dev/null +++ b/dts/xtensa/nxp/nxp_imx8qm.dtsi @@ -0,0 +1,88 @@ +/* + * Copyright 2021, 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include + +/ { + irqsteer: interrupt-controller@510a0000 { + compatible = "nxp,irqsteer-intc"; + reg = <0x510a0000 DT_SIZE_K(64)>; + power-domains = <&irqstr_pd>; + + #size-cells = <0>; + #address-cells = <1>; + + master0: interrupt-controller@0 { + compatible = "nxp,irqsteer-master"; + reg = <0>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 19 0 0>; + }; + + master1: interrupt-controller@1 { + compatible = "nxp,irqsteer-master"; + reg = <1>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 20 0 0>; + }; + + master2: interrupt-controller@2 { + compatible = "nxp,irqsteer-master"; + reg = <2>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 21 0 0>; + }; + + master3: interrupt-controller@3 { + compatible = "nxp,irqsteer-master"; + reg = <3>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 22 0 0>; + }; + + master4: interrupt-controller@4 { + compatible = "nxp,irqsteer-master"; + reg = <4>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 23 0 0>; + }; + + master5: interrupt-controller@5 { + compatible = "nxp,irqsteer-master"; + reg = <5>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 24 0 0>; + }; + + master6: interrupt-controller@6 { + compatible = "nxp,irqsteer-master"; + reg = <6>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 25 0 0>; + }; + + master7: interrupt-controller@7 { + compatible = "nxp,irqsteer-master"; + reg = <7>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 26 0 0>; + }; + }; +}; + +&edma0 { + power-domains = <&edma2_ch6_pd>, <&edma2_ch7_pd>, + <&edma2_ch14_pd>, <&edma2_ch15_pd>; +}; diff --git a/dts/xtensa/nxp/nxp_imx8qxp.dtsi b/dts/xtensa/nxp/nxp_imx8qxp.dtsi new file mode 100644 index 0000000000000..ff3e30a297abf --- /dev/null +++ b/dts/xtensa/nxp/nxp_imx8qxp.dtsi @@ -0,0 +1,82 @@ +/* + * Copyright 2021, 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + irqsteer: interrupt-controller@51080000 { + compatible = "nxp,irqsteer-intc"; + reg = <0x51080000 DT_SIZE_K(64)>; + power-domains = <&irqstr_pd>; + + #size-cells = <0>; + #address-cells = <1>; + + master0: interrupt-controller@0 { + compatible = "nxp,irqsteer-master"; + reg = <0>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 19 0 0>; + }; + + master1: interrupt-controller@1 { + compatible = "nxp,irqsteer-master"; + reg = <1>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 20 0 0>; + }; + + master2: interrupt-controller@2 { + compatible = "nxp,irqsteer-master"; + reg = <2>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 21 0 0>; + }; + + master3: interrupt-controller@3 { + compatible = "nxp,irqsteer-master"; + reg = <3>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 22 0 0>; + }; + + master4: interrupt-controller@4 { + compatible = "nxp,irqsteer-master"; + reg = <4>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 23 0 0>; + }; + + master5: interrupt-controller@5 { + compatible = "nxp,irqsteer-master"; + reg = <5>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 24 0 0>; + }; + + master6: interrupt-controller@6 { + compatible = "nxp,irqsteer-master"; + reg = <6>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 25 0 0>; + }; + + master7: interrupt-controller@7 { + compatible = "nxp,irqsteer-master"; + reg = <7>; + interrupt-controller; + #interrupt-cells = <1>; + interrupts-extended = <&clic 26 0 0>; + }; + }; +}; diff --git a/dts/xtensa/nxp/nxp_imx8ulp.dtsi b/dts/xtensa/nxp/nxp_imx8ulp.dtsi index 1dafde51fd123..816a72f9cc181 100644 --- a/dts/xtensa/nxp/nxp_imx8ulp.dtsi +++ b/dts/xtensa/nxp/nxp_imx8ulp.dtsi @@ -30,16 +30,16 @@ }; }; - sram0: memory@8e000000 { + sram0: memory@1a000000 { device_type = "memory"; compatible = "mmio-sram"; - reg = <0x8e000000 DT_SIZE_K(512)>; + reg = <0x1a000000 DT_SIZE_K(512)>; }; - sram1: memory@8e800000 { + sram1: memory@1a800000 { device_type = "memory"; compatible = "mmio-sram"; - reg = <0x8e800000 DT_SIZE_K(512)>; + reg = <0x1a800000 DT_SIZE_K(512)>; }; pcc4: clock-controller@29800000 { @@ -61,7 +61,7 @@ * from LPUART7. */ lpuart7: serial@29870000 { - compatible = "nxp,kinetis-lpuart"; + compatible = "nxp,lpuart"; reg = <0x29870000 DT_SIZE_K(4)>; clocks = <&pcc4 IMX8ULP_CLOCK_LPUART7 0x0>; status = "disabled"; diff --git a/include/zephyr/arch/arch_inlines.h b/include/zephyr/arch/arch_inlines.h index 04c4a649f1e14..0f32159e2f1bf 100644 --- a/include/zephyr/arch/arch_inlines.h +++ b/include/zephyr/arch/arch_inlines.h @@ -34,6 +34,4 @@ #include #endif -#include - #endif /* ZEPHYR_INCLUDE_ARCH_INLINES_H_ */ diff --git a/include/zephyr/arch/arch_interface.h b/include/zephyr/arch/arch_interface.h index 0f081d06adafa..03bc27c8f16b5 100644 --- a/include/zephyr/arch/arch_interface.h +++ b/include/zephyr/arch/arch_interface.h @@ -47,8 +47,6 @@ typedef struct z_thread_stack_element k_thread_stack_t; typedef void (*k_thread_entry_t)(void *p1, void *p2, void *p3); -__deprecated typedef struct arch_esf z_arch_esf_t; - /** * @defgroup arch-timing Architecture timing APIs * @ingroup arch-interface @@ -1289,7 +1287,7 @@ typedef bool (*stack_trace_callback_fn)(void *cookie, unsigned long addr); * ============ ======= ============================================ * thread esf * ============ ======= ============================================ - * thread NULL Stack trace from thread (can be arch_current_thread()) + * thread NULL Stack trace from thread (can be _current) * thread esf Stack trace starting on esf * ============ ======= ============================================ */ diff --git a/include/zephyr/arch/arm/arch.h b/include/zephyr/arch/arm/arch.h index 2da9e7f3d81ca..9bbcc2375f1cd 100644 --- a/include/zephyr/arch/arm/arch.h +++ b/include/zephyr/arch/arm/arch.h @@ -267,9 +267,9 @@ enum k_fatal_error_reason_arch { #ifdef CONFIG_CPU_HAS_ARM_MPU #include #endif /* CONFIG_CPU_HAS_ARM_MPU */ -#ifdef CONFIG_CPU_HAS_NXP_MPU +#ifdef CONFIG_CPU_HAS_NXP_SYSMPU #include -#endif /* CONFIG_CPU_HAS_NXP_MPU */ +#endif /* CONFIG_CPU_HAS_NXP_SYSMPU */ #endif /* CONFIG_ARM_MPU */ #ifdef CONFIG_ARM_AARCH32_MMU #include diff --git a/include/zephyr/arch/arm/asm_inline.h b/include/zephyr/arch/arm/asm_inline.h index fe36fb2d0e196..54bf2a6f4594e 100644 --- a/include/zephyr/arch/arm/asm_inline.h +++ b/include/zephyr/arch/arm/asm_inline.h @@ -14,10 +14,10 @@ * Include kernel.h instead */ -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__ICCARM__) #include #else -#include +#error Unknown toolchain in asm_inline.h #endif #endif /* ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_H_ */ diff --git a/include/zephyr/arch/arm/cortex_m/cpu.h b/include/zephyr/arch/arm/cortex_m/cpu.h index 064d8f92d56e2..096f5aabba830 100644 --- a/include/zephyr/arch/arm/cortex_m/cpu.h +++ b/include/zephyr/arch/arm/cortex_m/cpu.h @@ -12,9 +12,9 @@ #define _SCS_BASE_ADDR _PPB_INT_SCS /* ICSR defines */ -#define _SCS_ICSR (_SCS_BASE_ADDR + 0xd04) -#define _SCS_ICSR_PENDSV (1 << 28) -#define _SCS_ICSR_UNPENDSV (1 << 27) +#define _SCS_ICSR (_SCS_BASE_ADDR + 0xd04) +#define _SCS_ICSR_PENDSV (1 << 28) +#define _SCS_ICSR_UNPENDSV (1 << 27) #define _SCS_ICSR_RETTOBASE (1 << 11) #define _SCS_MPU_CTRL (_SCS_BASE_ADDR + 0xd94) @@ -34,20 +34,20 @@ extern "C" { #endif /* CP10 Access Bits */ -#define CPACR_CP10_Pos 20U -#define CPACR_CP10_Msk (3UL << CPACR_CP10_Pos) -#define CPACR_CP10_NO_ACCESS (0UL << CPACR_CP10_Pos) -#define CPACR_CP10_PRIV_ACCESS (1UL << CPACR_CP10_Pos) -#define CPACR_CP10_RESERVED (2UL << CPACR_CP10_Pos) -#define CPACR_CP10_FULL_ACCESS (3UL << CPACR_CP10_Pos) +#define CPACR_CP10_Pos 20U +#define CPACR_CP10_Msk (3UL << CPACR_CP10_Pos) +#define CPACR_CP10_NO_ACCESS (0UL << CPACR_CP10_Pos) +#define CPACR_CP10_PRIV_ACCESS (1UL << CPACR_CP10_Pos) +#define CPACR_CP10_RESERVED (2UL << CPACR_CP10_Pos) +#define CPACR_CP10_FULL_ACCESS (3UL << CPACR_CP10_Pos) /* CP11 Access Bits */ -#define CPACR_CP11_Pos 22U -#define CPACR_CP11_Msk (3UL << CPACR_CP11_Pos) -#define CPACR_CP11_NO_ACCESS (0UL << CPACR_CP11_Pos) -#define CPACR_CP11_PRIV_ACCESS (1UL << CPACR_CP11_Pos) -#define CPACR_CP11_RESERVED (2UL << CPACR_CP11_Pos) -#define CPACR_CP11_FULL_ACCESS (3UL << CPACR_CP11_Pos) +#define CPACR_CP11_Pos 22U +#define CPACR_CP11_Msk (3UL << CPACR_CP11_Pos) +#define CPACR_CP11_NO_ACCESS (0UL << CPACR_CP11_Pos) +#define CPACR_CP11_PRIV_ACCESS (1UL << CPACR_CP11_Pos) +#define CPACR_CP11_RESERVED (2UL << CPACR_CP11_Pos) +#define CPACR_CP11_FULL_ACCESS (3UL << CPACR_CP11_Pos) #ifdef CONFIG_PM_S2RAM diff --git a/include/zephyr/arch/arm/cortex_m/exception.h b/include/zephyr/arch/arm/cortex_m/exception.h index 6f60317891d9a..d675efa1549d0 100644 --- a/include/zephyr/arch/arm/cortex_m/exception.h +++ b/include/zephyr/arch/arm/cortex_m/exception.h @@ -43,17 +43,17 @@ #define _EXCEPTION_RESERVED_PRIO 0 #endif -#define _EXC_FAULT_PRIO 0 +#define _EXC_FAULT_PRIO 0 #define _EXC_ZERO_LATENCY_IRQS_PRIO 0 -#define _EXC_SVC_PRIO COND_CODE_1(CONFIG_ZERO_LATENCY_IRQS, \ +#define _EXC_SVC_PRIO COND_CODE_1(CONFIG_ZERO_LATENCY_IRQS, \ (CONFIG_ZERO_LATENCY_LEVELS), (0)) -#define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO + _EXC_SVC_PRIO) -#define IRQ_PRIO_LOWEST (BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET) - 1) +#define _IRQ_PRIO_OFFSET (_EXCEPTION_RESERVED_PRIO + _EXC_SVC_PRIO) +#define IRQ_PRIO_LOWEST (BIT(NUM_IRQ_PRIO_BITS) - (_IRQ_PRIO_OFFSET) - 1) #define _EXC_IRQ_DEFAULT_PRIO Z_EXC_PRIO(_IRQ_PRIO_OFFSET) /* Use lowest possible priority level for PendSV */ -#define _EXC_PENDSV_PRIO 0xff +#define _EXC_PENDSV_PRIO 0xff #define _EXC_PENDSV_PRIO_MASK Z_EXC_PRIO(_EXC_PENDSV_PRIO) #ifdef _ASMLANGUAGE @@ -99,7 +99,10 @@ struct __extra_esf_info { #endif /* CONFIG_EXTRA_EXCEPTION_INFO */ /* ARM GPRs are often designated by two different names */ -#define sys_define_gpr_with_alias(name1, name2) union { uint32_t name1, name2; } +#define sys_define_gpr_with_alias(name1, name2) \ + union { \ + uint32_t name1, name2; \ + } struct arch_esf { struct __basic_sf { diff --git a/include/zephyr/arch/arm/cortex_m/memory_map.h b/include/zephyr/arch/arm/cortex_m/memory_map.h index 1fbec9d19d7b8..30e800daf374d 100644 --- a/include/zephyr/arch/arm/cortex_m/memory_map.h +++ b/include/zephyr/arch/arm/cortex_m/memory_map.h @@ -18,8 +18,8 @@ #include /* 0x00000000 -> 0x1fffffff: Code in ROM [0.5 GB] */ -#define _CODE_BASE_ADDR 0x00000000 -#define _CODE_END_ADDR 0x1FFFFFFF +#define _CODE_BASE_ADDR 0x00000000 +#define _CODE_END_ADDR 0x1FFFFFFF /* 0x20000000 -> 0x3fffffff: SRAM [0.5GB] */ #define _SRAM_BASE_ADDR 0x20000000 @@ -38,78 +38,77 @@ #define _PERI_END_ADDR 0x5FFFFFFF /* 0x60000000 -> 0x9fffffff: external RAM [1GB] */ -#define _ERAM_BASE_ADDR 0x60000000 -#define _ERAM_END_ADDR 0x9FFFFFFF +#define _ERAM_BASE_ADDR 0x60000000 +#define _ERAM_END_ADDR 0x9FFFFFFF /* 0xa0000000 -> 0xdfffffff: external devices [1GB] */ -#define _EDEV_BASE_ADDR 0xA0000000 -#define _EDEV_END_ADDR 0xDFFFFFFF +#define _EDEV_BASE_ADDR 0xA0000000 +#define _EDEV_END_ADDR 0xDFFFFFFF /* 0xe0000000 -> 0xffffffff: varies by processor (see below) */ /* 0xe0000000 -> 0xe00fffff: private peripheral bus */ /* 0xe0000000 -> 0xe003ffff: internal [256KB] */ -#define _PPB_INT_BASE_ADDR 0xE0000000 -#if defined(CONFIG_CPU_CORTEX_M0) || defined(CONFIG_CPU_CORTEX_M0PLUS) || \ +#define _PPB_INT_BASE_ADDR 0xE0000000 +#if defined(CONFIG_CPU_CORTEX_M0) || defined(CONFIG_CPU_CORTEX_M0PLUS) || \ defined(CONFIG_CPU_CORTEX_M1) -#define _PPB_INT_RSVD_0 0xE0000000 -#define _PPB_INT_DWT 0xE0001000 -#define _PPB_INT_BPU 0xE0002000 -#define _PPB_INT_RSVD_1 0xE0003000 -#define _PPB_INT_SCS 0xE000E000 -#define _PPB_INT_RSVD_2 0xE000F000 -#elif defined(CONFIG_CPU_CORTEX_M3) || defined(CONFIG_CPU_CORTEX_M4) || defined(CONFIG_CPU_CORTEX_M7) -#define _PPB_INT_ITM 0xE0000000 -#define _PPB_INT_DWT 0xE0001000 -#define _PPB_INT_FPB 0xE0002000 -#define _PPB_INT_RSVD_1 0xE0003000 -#define _PPB_INT_SCS 0xE000E000 -#define _PPB_INT_RSVD_2 0xE000F000 -#elif defined(CONFIG_CPU_CORTEX_M23) || \ - defined(CONFIG_CPU_CORTEX_M33) || \ - defined(CONFIG_CPU_CORTEX_M55) || \ - defined(CONFIG_CPU_CORTEX_M85) -#define _PPB_INT_RSVD_0 0xE0000000 -#define _PPB_INT_SCS 0xE000E000 -#define _PPB_INT_SCB 0xE000ED00 -#define _PPB_INT_RSVD_1 0xE002E000 +#define _PPB_INT_RSVD_0 0xE0000000 +#define _PPB_INT_DWT 0xE0001000 +#define _PPB_INT_BPU 0xE0002000 +#define _PPB_INT_RSVD_1 0xE0003000 +#define _PPB_INT_SCS 0xE000E000 +#define _PPB_INT_RSVD_2 0xE000F000 +#elif defined(CONFIG_CPU_CORTEX_M3) || defined(CONFIG_CPU_CORTEX_M4) || \ + defined(CONFIG_CPU_CORTEX_M7) +#define _PPB_INT_ITM 0xE0000000 +#define _PPB_INT_DWT 0xE0001000 +#define _PPB_INT_FPB 0xE0002000 +#define _PPB_INT_RSVD_1 0xE0003000 +#define _PPB_INT_SCS 0xE000E000 +#define _PPB_INT_RSVD_2 0xE000F000 +#elif defined(CONFIG_CPU_CORTEX_M23) || defined(CONFIG_CPU_CORTEX_M33) || \ + defined(CONFIG_CPU_CORTEX_M55) || defined(CONFIG_CPU_CORTEX_M85) +#define _PPB_INT_RSVD_0 0xE0000000 +#define _PPB_INT_SCS 0xE000E000 +#define _PPB_INT_SCB 0xE000ED00 +#define _PPB_INT_RSVD_1 0xE002E000 #else #error Unknown CPU #endif -#define _PPB_INT_END_ADDR 0xE003FFFF +#define _PPB_INT_END_ADDR 0xE003FFFF /* 0xe0000000 -> 0xe00fffff: private peripheral bus */ /* 0xe0040000 -> 0xe00fffff: external [768K] */ -#define _PPB_EXT_BASE_ADDR 0xE0040000 -#if defined(CONFIG_CPU_CORTEX_M0) || defined(CONFIG_CPU_CORTEX_M0PLUS) \ - || defined(CONFIG_CPU_CORTEX_M1) || defined(CONFIG_CPU_CORTEX_M23) +#define _PPB_EXT_BASE_ADDR 0xE0040000 +#if defined(CONFIG_CPU_CORTEX_M0) || defined(CONFIG_CPU_CORTEX_M0PLUS) || \ + defined(CONFIG_CPU_CORTEX_M1) || defined(CONFIG_CPU_CORTEX_M23) #elif defined(CONFIG_CPU_CORTEX_M3) || defined(CONFIG_CPU_CORTEX_M4) -#define _PPB_EXT_TPIU 0xE0040000 -#define _PPB_EXT_ETM 0xE0041000 -#define _PPB_EXT_PPB 0xE0042000 -#define _PPB_EXT_ROM_TABLE 0xE00FF000 -#define _PPB_EXT_END_ADDR 0xE00FFFFF -#elif defined(CONFIG_CPU_CORTEX_M33) || defined(CONFIG_CPU_CORTEX_M55) \ - || defined(CONFIG_CPU_CORTEX_M85) -#undef _PPB_EXT_BASE_ADDR -#define _PPB_EXT_BASE_ADDR 0xE0044000 -#define _PPB_EXT_ROM_TABLE 0xE00FF000 -#define _PPB_EXT_END_ADDR 0xE00FFFFF +#define _PPB_EXT_TPIU 0xE0040000 +#define _PPB_EXT_ETM 0xE0041000 +#define _PPB_EXT_PPB 0xE0042000 +#define _PPB_EXT_ROM_TABLE 0xE00FF000 +#define _PPB_EXT_END_ADDR 0xE00FFFFF +#elif defined(CONFIG_CPU_CORTEX_M33) || defined(CONFIG_CPU_CORTEX_M55) || \ + defined(CONFIG_CPU_CORTEX_M85) +#undef _PPB_EXT_BASE_ADDR +#define _PPB_EXT_BASE_ADDR 0xE0044000 +#define _PPB_EXT_ROM_TABLE 0xE00FF000 +#define _PPB_EXT_END_ADDR 0xE00FFFFF #elif defined(CONFIG_CPU_CORTEX_M7) -#define _PPB_EXT_BASE_ADDR 0xE0040000 -#define _PPB_EXT_RSVD_TPIU 0xE0040000 -#define _PPB_EXT_ETM 0xE0041000 -#define _PPB_EXT_CTI 0xE0042000 -#define _PPB_EXT_PPB 0xE0043000 -#define _PPB_EXT_PROC_ROM_TABLE 0xE00FE000 -#define _PPB_EXT_PPB_ROM_TABLE 0xE00FF000 +#define _PPB_EXT_BASE_ADDR 0xE0040000 +#define _PPB_EXT_RSVD_TPIU 0xE0040000 +#define _PPB_EXT_ETM 0xE0041000 +#define _PPB_EXT_CTI 0xE0042000 +#define _PPB_EXT_PPB 0xE0043000 +#define _PPB_EXT_PROC_ROM_TABLE 0xE00FE000 +#define _PPB_EXT_PPB_ROM_TABLE 0xE00FF000 #else #error Unknown CPU #endif -#define _PPB_EXT_END_ADDR 0xE00FFFFF +#define _PPB_EXT_END_ADDR 0xE00FFFFF /* 0xe0100000 -> 0xffffffff: vendor-specific [0.5GB-1MB or 511MB] */ -#define _VENDOR_BASE_ADDR 0xE0100000 -#define _VENDOR_END_ADDR 0xFFFFFFFF +#define _VENDOR_BASE_ADDR 0xE0100000 +#define _VENDOR_END_ADDR 0xFFFFFFFF #endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MEMORY_MAP_H_ */ diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld index 03dc59e1f50dc..f9efbb5c9eddb 100644 --- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld @@ -277,35 +277,6 @@ SECTIONS _app_smem_size = _app_smem_end - _app_smem_start; _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); - - SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) - { - /* - * For performance, BSS section is assumed to be 4 byte aligned and - * a multiple of 4 bytes - */ - . = ALIGN(4); - __bss_start = .; - __kernel_ram_start = .; - - *(.bss) - *(".bss.*") - *(COMMON) - *(".kernel_bss.*") - -#ifdef CONFIG_CODE_DATA_RELOCATION -#include -#endif - - /* - * As memory is cleared in words only, it is simpler to ensure the BSS - * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. - */ - __bss_end = ALIGN(4); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) - -#include - #endif /* CONFIG_USERSPACE */ GROUP_START(DATA_REGION) @@ -346,56 +317,6 @@ SECTIONS __data_region_end = .; -#ifndef CONFIG_USERSPACE - SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) - { - /* - * For performance, BSS section is assumed to be 4 byte aligned and - * a multiple of 4 bytes - */ - . = ALIGN(4); - __bss_start = .; - __kernel_ram_start = .; - - *(.bss) - *(".bss.*") - *(COMMON) - *(".kernel_bss.*") - -#ifdef CONFIG_CODE_DATA_RELOCATION -#include -#endif - - /* - * As memory is cleared in words only, it is simpler to ensure the BSS - * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. - */ - __bss_end = ALIGN(4); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) - - SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),) - { - /* - * This section is used for non-initialized objects that - * will not be cleared during the boot process. - */ - *(.noinit) - *(".noinit.*") - *(".kernel_noinit.*") - -/* Located in generated directory. This file is populated by the - * zephyr_linker_sources() Cmake function. - */ -#include - - } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USERSPACE */ - - /* Define linker symbols */ - - __kernel_ram_end = RAM_ADDR + RAM_SIZE; - __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; - #if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) GROUP_START(ITCM) @@ -463,10 +384,6 @@ GROUP_END(DTCM) */ #include -#include - - GROUP_END(RAMABLE_REGION) - #include /DISCARD/ : { *(.note.GNU-stack) } @@ -503,4 +420,41 @@ SECTION_PROLOGUE(.last_section,,) * calculate this value here. */ _flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start; + SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) + { + /* + * For performance, BSS section is assumed to be 4 byte aligned and + * a multiple of 4 bytes + */ + . = ALIGN(4); + __bss_start = .; + __kernel_ram_start = .; + + *(.bss) + *(".bss.*") + *(COMMON) + *(".kernel_bss.*") + +#ifdef CONFIG_CODE_DATA_RELOCATION +#include +#endif + + /* + * As memory is cleared in words only, it is simpler to ensure the BSS + * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. + */ + __bss_end = ALIGN(4); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) + +#include + + /* Define linker symbols */ + + __kernel_ram_end = RAM_ADDR + RAM_SIZE; + __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; + +#include + + GROUP_END(RAMABLE_REGION) + } diff --git a/include/zephyr/arch/arm/error.h b/include/zephyr/arch/arm/error.h index 2a158959b809c..54463bacc80c4 100644 --- a/include/zephyr/arch/arm/error.h +++ b/include/zephyr/arch/arm/error.h @@ -53,8 +53,8 @@ do {\ * z_check_stack_sentinel call if it is not stacked before the svc. */ #define ARCH_EXCEPT(reason_p) \ -register uint32_t r0 __asm__("r0") = reason_p; \ do { \ + register uint32_t r0 __asm__("r0") = reason_p; \ __asm__ volatile ( \ "push {lr}\n\t" \ "cpsie i\n\t" \ diff --git a/include/zephyr/arch/arm/mpu/arm_mpu.h b/include/zephyr/arch/arm/mpu/arm_mpu.h index e47883f1849a1..2aee4dd7efee5 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu.h @@ -6,16 +6,11 @@ #ifndef ZEPHYR_INCLUDE_ARCH_ARM_MPU_ARM_MPU_H_ #define ZEPHYR_INCLUDE_ARCH_ARM_MPU_ARM_MPU_H_ -#if defined(CONFIG_CPU_CORTEX_M0PLUS) || \ - defined(CONFIG_CPU_CORTEX_M3) || \ - defined(CONFIG_CPU_CORTEX_M4) || \ - defined(CONFIG_CPU_CORTEX_M7) || \ - defined(CONFIG_ARMV7_R) +#if defined(CONFIG_CPU_CORTEX_M0PLUS) || defined(CONFIG_CPU_CORTEX_M3) || \ + defined(CONFIG_CPU_CORTEX_M4) || defined(CONFIG_CPU_CORTEX_M7) || defined(CONFIG_ARMV7_R) #include -#elif defined(CONFIG_CPU_CORTEX_M23) || \ - defined(CONFIG_CPU_CORTEX_M33) || \ - defined(CONFIG_CPU_CORTEX_M55) || \ - defined(CONFIG_CPU_CORTEX_M85) || \ +#elif defined(CONFIG_CPU_CORTEX_M23) || defined(CONFIG_CPU_CORTEX_M33) || \ + defined(CONFIG_CPU_CORTEX_M55) || defined(CONFIG_CPU_CORTEX_M85) || \ defined(CONFIG_AARCH32_ARMV8_R) #include #else @@ -47,19 +42,19 @@ struct arm_mpu_config { }; #if defined(CONFIG_ARMV7_R) -#define MPU_REGION_ENTRY(_name, _base, _size, _attr) \ - {\ - .name = _name, \ - .base = _base, \ - .size = _size, \ - .attr = _attr, \ +#define MPU_REGION_ENTRY(_name, _base, _size, _attr) \ + { \ + .name = _name, \ + .base = _base, \ + .size = _size, \ + .attr = _attr, \ } #else -#define MPU_REGION_ENTRY(_name, _base, _attr) \ - {\ - .name = _name, \ - .base = _base, \ - .attr = _attr, \ +#define MPU_REGION_ENTRY(_name, _base, _attr) \ + { \ + .name = _name, \ + .base = _base, \ + .attr = _attr, \ } #endif diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h index 1ed8636ec50bd..c1ada0d55e5ed 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h @@ -46,73 +46,69 @@ #define NOT_EXEC MPU_RASR_XN_Msk /* The following definitions are for internal use in arm_mpu.h. */ -#define STRONGLY_ORDERED_SHAREABLE MPU_RASR_S_Msk -#define DEVICE_SHAREABLE (MPU_RASR_B_Msk | MPU_RASR_S_Msk) -#define NORMAL_OUTER_INNER_WRITE_THROUGH_SHAREABLE \ - (MPU_RASR_C_Msk | MPU_RASR_S_Msk) -#define NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE MPU_RASR_C_Msk -#define NORMAL_OUTER_INNER_WRITE_BACK_SHAREABLE \ - (MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk) -#define NORMAL_OUTER_INNER_WRITE_BACK_NON_SHAREABLE \ - (MPU_RASR_C_Msk | MPU_RASR_B_Msk) -#define NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE \ - ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk) -#define NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE \ - (1 << MPU_RASR_TEX_Pos) -#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_SHAREABLE \ - ((1 << MPU_RASR_TEX_Pos) |\ - MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk) -#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE \ +#define STRONGLY_ORDERED_SHAREABLE MPU_RASR_S_Msk +#define DEVICE_SHAREABLE (MPU_RASR_B_Msk | MPU_RASR_S_Msk) +#define NORMAL_OUTER_INNER_WRITE_THROUGH_SHAREABLE (MPU_RASR_C_Msk | MPU_RASR_S_Msk) +#define NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE MPU_RASR_C_Msk +/* clang-format off */ +#define NORMAL_OUTER_INNER_WRITE_BACK_SHAREABLE \ + (MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk) +/* clang-format on */ +#define NORMAL_OUTER_INNER_WRITE_BACK_NON_SHAREABLE (MPU_RASR_C_Msk | MPU_RASR_B_Msk) +#define NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk) +#define NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE (1 << MPU_RASR_TEX_Pos) +#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_SHAREABLE \ + ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk) +#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE \ ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk) -#define DEVICE_NON_SHAREABLE (2 << MPU_RASR_TEX_Pos) +#define DEVICE_NON_SHAREABLE (2 << MPU_RASR_TEX_Pos) /* Bit-masks to disable sub-regions. */ -#define SUB_REGION_0_DISABLED ((0x01 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) -#define SUB_REGION_1_DISABLED ((0x02 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) -#define SUB_REGION_2_DISABLED ((0x04 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) -#define SUB_REGION_3_DISABLED ((0x08 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) -#define SUB_REGION_4_DISABLED ((0x10 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) -#define SUB_REGION_5_DISABLED ((0x20 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) -#define SUB_REGION_6_DISABLED ((0x40 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) -#define SUB_REGION_7_DISABLED ((0x80 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define SUB_REGION_0_DISABLED ((0x01 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define SUB_REGION_1_DISABLED ((0x02 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define SUB_REGION_2_DISABLED ((0x04 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define SUB_REGION_3_DISABLED ((0x08 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define SUB_REGION_4_DISABLED ((0x10 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define SUB_REGION_5_DISABLED ((0x20 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define SUB_REGION_6_DISABLED ((0x40 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define SUB_REGION_7_DISABLED ((0x80 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) +#define REGION_SIZE(size) ((ARM_MPU_REGION_SIZE_##size << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) -#define REGION_SIZE(size) ((ARM_MPU_REGION_SIZE_ ## size \ - << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) +#define REGION_32B REGION_SIZE(32B) +#define REGION_64B REGION_SIZE(64B) +#define REGION_128B REGION_SIZE(128B) +#define REGION_256B REGION_SIZE(256B) +#define REGION_512B REGION_SIZE(512B) +#define REGION_1K REGION_SIZE(1KB) +#define REGION_2K REGION_SIZE(2KB) +#define REGION_4K REGION_SIZE(4KB) +#define REGION_8K REGION_SIZE(8KB) +#define REGION_16K REGION_SIZE(16KB) +#define REGION_32K REGION_SIZE(32KB) +#define REGION_64K REGION_SIZE(64KB) +#define REGION_128K REGION_SIZE(128KB) +#define REGION_256K REGION_SIZE(256KB) +#define REGION_512K REGION_SIZE(512KB) +#define REGION_1M REGION_SIZE(1MB) +#define REGION_2M REGION_SIZE(2MB) +#define REGION_4M REGION_SIZE(4MB) +#define REGION_8M REGION_SIZE(8MB) +#define REGION_16M REGION_SIZE(16MB) +#define REGION_32M REGION_SIZE(32MB) +#define REGION_64M REGION_SIZE(64MB) +#define REGION_128M REGION_SIZE(128MB) +#define REGION_256M REGION_SIZE(256MB) +#define REGION_512M REGION_SIZE(512MB) +#define REGION_1G REGION_SIZE(1GB) +#define REGION_2G REGION_SIZE(2GB) +#define REGION_4G REGION_SIZE(4GB) -#define REGION_32B REGION_SIZE(32B) -#define REGION_64B REGION_SIZE(64B) -#define REGION_128B REGION_SIZE(128B) -#define REGION_256B REGION_SIZE(256B) -#define REGION_512B REGION_SIZE(512B) -#define REGION_1K REGION_SIZE(1KB) -#define REGION_2K REGION_SIZE(2KB) -#define REGION_4K REGION_SIZE(4KB) -#define REGION_8K REGION_SIZE(8KB) -#define REGION_16K REGION_SIZE(16KB) -#define REGION_32K REGION_SIZE(32KB) -#define REGION_64K REGION_SIZE(64KB) -#define REGION_128K REGION_SIZE(128KB) -#define REGION_256K REGION_SIZE(256KB) -#define REGION_512K REGION_SIZE(512KB) -#define REGION_1M REGION_SIZE(1MB) -#define REGION_2M REGION_SIZE(2MB) -#define REGION_4M REGION_SIZE(4MB) -#define REGION_8M REGION_SIZE(8MB) -#define REGION_16M REGION_SIZE(16MB) -#define REGION_32M REGION_SIZE(32MB) -#define REGION_64M REGION_SIZE(64MB) -#define REGION_128M REGION_SIZE(128MB) -#define REGION_256M REGION_SIZE(256MB) -#define REGION_512M REGION_SIZE(512MB) -#define REGION_1G REGION_SIZE(1GB) -#define REGION_2G REGION_SIZE(2GB) -#define REGION_4G REGION_SIZE(4GB) - -#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ - { .name = p_name, \ - .base = p_base, \ - .attr = p_attr(size_to_mpu_rasr_size(p_size)), \ +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { \ + .name = p_name, \ + .base = p_base, \ + .attr = p_attr(size_to_mpu_rasr_size(p_size)), \ } /* Some helper defines for common regions */ @@ -121,33 +117,20 @@ * CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep * the SRAM region XN bit clear or the application code will not be executable. */ -#define REGION_RAM_ATTR(size) \ -{ \ - (NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE | \ - IF_ENABLED(CONFIG_XIP, (MPU_RASR_XN_Msk |)) size | P_RW_U_NA_Msk) \ -} -#define REGION_RAM_NOCACHE_ATTR(size) \ -{ \ - (NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE | \ - MPU_RASR_XN_Msk | size | P_RW_U_NA_Msk) \ -} +#define REGION_RAM_ATTR(size) \ + {(NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE | \ + IF_ENABLED(CONFIG_XIP, (MPU_RASR_XN_Msk |)) size | P_RW_U_NA_Msk)} +#define REGION_RAM_NOCACHE_ATTR(size) \ + {(NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE | MPU_RASR_XN_Msk | size | P_RW_U_NA_Msk)} #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) -#define REGION_FLASH_ATTR(size) \ -{ \ - (NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | \ - P_RW_U_RO_Msk) \ -} +#define REGION_FLASH_ATTR(size) \ + {(NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | P_RW_U_RO_Msk)} #else -#define REGION_FLASH_ATTR(size) \ -{ \ - (NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | RO_Msk) \ -} +#define REGION_FLASH_ATTR(size) {(NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | RO_Msk)} #endif -#define REGION_PPB_ATTR(size) { (STRONGLY_ORDERED_SHAREABLE | size | \ - P_RW_U_NA_Msk) } -#define REGION_IO_ATTR(size) { (DEVICE_NON_SHAREABLE | size | P_RW_U_NA_Msk) } -#define REGION_EXTMEM_ATTR(size) { (STRONGLY_ORDERED_SHAREABLE | size | \ - NO_ACCESS_Msk) } +#define REGION_PPB_ATTR(size) {(STRONGLY_ORDERED_SHAREABLE | size | P_RW_U_NA_Msk)} +#define REGION_IO_ATTR(size) {(DEVICE_NON_SHAREABLE | size | P_RW_U_NA_Msk)} +#define REGION_EXTMEM_ATTR(size) {(STRONGLY_ORDERED_SHAREABLE | size | NO_ACCESS_Msk)} struct arm_mpu_region_attr { /* Attributes belonging to RASR (including the encoded region size) */ @@ -162,12 +145,12 @@ typedef struct { } k_mem_partition_attr_t; /* Read-Write access permission attributes */ -#define _K_MEM_PARTITION_P_NA_U_NA (NO_ACCESS_Msk | NOT_EXEC) -#define _K_MEM_PARTITION_P_RW_U_RW (P_RW_U_RW_Msk | NOT_EXEC) -#define _K_MEM_PARTITION_P_RW_U_RO (P_RW_U_RO_Msk | NOT_EXEC) -#define _K_MEM_PARTITION_P_RW_U_NA (P_RW_U_NA_Msk | NOT_EXEC) -#define _K_MEM_PARTITION_P_RO_U_RO (P_RO_U_RO_Msk | NOT_EXEC) -#define _K_MEM_PARTITION_P_RO_U_NA (P_RO_U_NA_Msk | NOT_EXEC) +#define _K_MEM_PARTITION_P_NA_U_NA (NO_ACCESS_Msk | NOT_EXEC) +#define _K_MEM_PARTITION_P_RW_U_RW (P_RW_U_RW_Msk | NOT_EXEC) +#define _K_MEM_PARTITION_P_RW_U_RO (P_RW_U_RO_Msk | NOT_EXEC) +#define _K_MEM_PARTITION_P_RW_U_NA (P_RW_U_NA_Msk | NOT_EXEC) +#define _K_MEM_PARTITION_P_RO_U_RO (P_RO_U_RO_Msk | NOT_EXEC) +#define _K_MEM_PARTITION_P_RO_U_NA (P_RO_U_NA_Msk | NOT_EXEC) /* Execution-allowed attributes */ #define _K_MEM_PARTITION_P_RWX_U_RWX (P_RW_U_RW_Msk) @@ -184,35 +167,44 @@ typedef struct { */ /* Read-Write access permission attributes (default cache-ability) */ -#define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_NA_U_NA | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) -#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_RW_U_RW | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) -#define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_RW_U_RO | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) -#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_RW_U_NA | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) -#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_RO_U_RO | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) -#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_RO_U_NA | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_NA_U_NA \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_NA_U_NA | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_RW_U_RW \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_RW_U_RW | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_RW_U_RO \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_RW_U_RO | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_RW_U_NA \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_RW_U_NA | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_RO_U_RO \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_RO_U_RO | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_RO_U_NA \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_RO_U_NA | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) /* Execution-allowed attributes (default-cacheability) */ -#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_RWX_U_RWX | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) -#define K_MEM_PARTITION_P_RWX_U_RX ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_RWX_U_RX | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) -#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \ - { _K_MEM_PARTITION_P_RX_U_RX | \ - NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_RWX_U_RWX \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_RWX_U_RWX | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_RWX_U_RX \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_RWX_U_RX | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) +#define K_MEM_PARTITION_P_RX_U_RX \ + ((k_mem_partition_attr_t){ \ + _K_MEM_PARTITION_P_RX_U_RX | \ + NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE}) /* * @brief Evaluate Write-ability @@ -222,19 +214,19 @@ typedef struct { * @param attr The k_mem_partition_attr_t object holding the * MPU attributes to be checked against write-ability. */ -#define K_MEM_PARTITION_IS_WRITABLE(attr) \ - ({ \ - int __is_writable__; \ - switch (attr.rasr_attr & MPU_RASR_AP_Msk) { \ - case P_RW_U_RW_Msk: \ - case P_RW_U_RO_Msk: \ - case P_RW_U_NA_Msk: \ - __is_writable__ = 1; \ - break; \ - default: \ - __is_writable__ = 0; \ - } \ - __is_writable__; \ +#define K_MEM_PARTITION_IS_WRITABLE(attr) \ + ({ \ + int __is_writable__; \ + switch (attr.rasr_attr & MPU_RASR_AP_Msk) { \ + case P_RW_U_RW_Msk: \ + case P_RW_U_RO_Msk: \ + case P_RW_U_NA_Msk: \ + __is_writable__ = 1; \ + break; \ + default: \ + __is_writable__ = 0; \ + } \ + __is_writable__; \ }) /* @@ -246,46 +238,45 @@ typedef struct { * MPU attributes to be checked against execution * allowance. */ -#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ - (!((attr.rasr_attr) & (NOT_EXEC))) +#define K_MEM_PARTITION_IS_EXECUTABLE(attr) (!((attr.rasr_attr) & (NOT_EXEC))) /* Attributes for no-cache enabling (share-ability is selected by default) */ -#define K_MEM_PARTITION_P_NA_U_NA_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_NA_U_NA \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) -#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_RW_U_RW \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) -#define K_MEM_PARTITION_P_RW_U_RO_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_RW_U_RO \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) -#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_RW_U_NA \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) -#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_RO_U_RO \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) -#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_RO_U_NA \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_NA_U_NA_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_NA_U_NA | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_RW_U_RW | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RW_U_RO_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_RW_U_RO | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_RW_U_NA | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_RO_U_RO | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_RO_U_NA | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) -#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_RWX_U_RWX \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) -#define K_MEM_PARTITION_P_RWX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_RWX_U_RX \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) -#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ - {(_K_MEM_PARTITION_P_RX_U_RX \ - | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_RWX_U_RWX | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RWX_U_RX_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_RWX_U_RX | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) +#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE \ + ((k_mem_partition_attr_t){ \ + (_K_MEM_PARTITION_P_RX_U_RX | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)}) #endif /* _ASMLANGUAGE */ -#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ - BUILD_ASSERT(!(((size) & ((size) - 1))) && \ - (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ - !((uint32_t)(start) & ((size) - 1)), \ - "the size of the partition must be power of 2" \ - " and greater than or equal to the minimum MPU region size." \ - "start address of the partition must align with size.") +#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ + BUILD_ASSERT(!(((size) & ((size) - 1))) && \ + (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ + !((uint32_t)(start) & ((size) - 1)), \ + "The size of the partition must be power of 2 and greater than or equal to " \ + "the minimum MPU region size.\n" \ + "The start address of the partition must align with size.") diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_v8.h b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h index 77deb64beed66..0f13bee99be4c 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_v8.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h @@ -12,25 +12,25 @@ * cache-ability attribution. */ #if defined(CONFIG_AARCH32_ARMV8_R) -#define MPU_IR_REGION_Msk (0xFFU) -#define MPU_IR_REGION_Pos 8U +#define MPU_IR_REGION_Msk (0xFFU) +#define MPU_IR_REGION_Pos 8U /* MPU RBAR Register attribute msk Definitions */ -#define MPU_RBAR_BASE_Pos 6U -#define MPU_RBAR_BASE_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RBAR_BASE_Pos) -#define MPU_RBAR_SH_Pos 3U -#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) -#define MPU_RBAR_AP_Pos 1U -#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) +#define MPU_RBAR_BASE_Pos 6U +#define MPU_RBAR_BASE_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RBAR_BASE_Pos) +#define MPU_RBAR_SH_Pos 3U +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) +#define MPU_RBAR_AP_Pos 1U +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /* RBAR XN */ -#define MPU_RBAR_XN_Pos 0U -#define MPU_RBAR_XN_Msk (0x1UL << MPU_RBAR_XN_Pos) +#define MPU_RBAR_XN_Pos 0U +#define MPU_RBAR_XN_Msk (0x1UL << MPU_RBAR_XN_Pos) /* MPU PLBAR Register Definitions */ -#define MPU_RLAR_LIMIT_Pos 6U -#define MPU_RLAR_LIMIT_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RLAR_LIMIT_Pos) -#define MPU_RLAR_AttrIndx_Pos 1U -#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) -#define MPU_RLAR_EN_Msk (0x1UL) +#define MPU_RLAR_LIMIT_Pos 6U +#define MPU_RLAR_LIMIT_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RLAR_LIMIT_Pos) +#define MPU_RLAR_AttrIndx_Pos 1U +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) +#define MPU_RLAR_EN_Msk (0x1UL) #else #include #endif @@ -68,18 +68,14 @@ /* Attribute flags for share-ability */ #define NON_SHAREABLE 0x0 -#define NON_SHAREABLE_Msk \ - ((NON_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) -#define OUTER_SHAREABLE 0x2 -#define OUTER_SHAREABLE_Msk \ - ((OUTER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) -#define INNER_SHAREABLE 0x3 -#define INNER_SHAREABLE_Msk \ - ((INNER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) +#define NON_SHAREABLE_Msk ((NON_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) +#define OUTER_SHAREABLE 0x2 +#define OUTER_SHAREABLE_Msk ((OUTER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) +#define INNER_SHAREABLE 0x3 +#define INNER_SHAREABLE_Msk ((INNER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) /* Helper define to calculate the region limit address. */ -#define REGION_LIMIT_ADDR(base, size) \ - (((base & MPU_RBAR_BASE_Msk) + size - 1) & MPU_RLAR_LIMIT_Msk) +#define REGION_LIMIT_ADDR(base, size) (((base & MPU_RBAR_BASE_Msk) + size - 1) & MPU_RLAR_LIMIT_Msk) /* Attribute flags for cache-ability */ @@ -101,10 +97,10 @@ * nE: The response should come from the end slave, not buffering in * the interconnect. */ -#define DEVICE_nGnRnE 0x0U -#define DEVICE_nGnRE 0x4U -#define DEVICE_nGRE 0x8U -#define DEVICE_GRE 0xCU +#define DEVICE_nGnRnE 0x0U +#define DEVICE_nGnRE 0x4U +#define DEVICE_nGRE 0x8U +#define DEVICE_GRE 0xCU /* Read/Write Allocation Configurations for Cacheable Memory */ #define R_NON_W_NON 0x0 /* Do not allocate Read/Write */ @@ -113,36 +109,30 @@ #define R_ALLOC_W_ALLOC 0x3 /* Allocate Read/Write */ /* Memory Attributes for Normal Memory */ -#define NORMAL_O_WT_NT 0x80 /* Normal, Outer Write-through non-transient */ -#define NORMAL_O_WB_NT 0xC0 /* Normal, Outer Write-back non-transient */ -#define NORMAL_O_NON_C 0x40 /* Normal, Outer Non-Cacheable */ +#define NORMAL_O_WT_NT 0x80 /* Normal, Outer Write-through non-transient */ +#define NORMAL_O_WB_NT 0xC0 /* Normal, Outer Write-back non-transient */ +#define NORMAL_O_NON_C 0x40 /* Normal, Outer Non-Cacheable */ -#define NORMAL_I_WT_NT 0x08 /* Normal, Inner Write-through non-transient */ -#define NORMAL_I_WB_NT 0x0C /* Normal, Inner Write-back non-transient */ -#define NORMAL_I_NON_C 0x04 /* Normal, Inner Non-Cacheable */ +#define NORMAL_I_WT_NT 0x08 /* Normal, Inner Write-through non-transient */ +#define NORMAL_I_WB_NT 0x0C /* Normal, Inner Write-back non-transient */ +#define NORMAL_I_NON_C 0x04 /* Normal, Inner Non-Cacheable */ -#define NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS \ - ((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) \ - | \ - (NORMAL_I_WT_NT | R_ALLOC_W_NON)) \ +#define NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS \ + ((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) | (NORMAL_I_WT_NT | R_ALLOC_W_NON)) -#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS \ - ((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) \ - | \ - (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC)) +#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS \ + ((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) | (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC)) -#define NORMAL_OUTER_INNER_NON_CACHEABLE \ - ((NORMAL_O_NON_C | (R_NON_W_NON << 4)) \ - | \ - (NORMAL_I_NON_C | R_NON_W_NON)) +#define NORMAL_OUTER_INNER_NON_CACHEABLE \ + ((NORMAL_O_NON_C | (R_NON_W_NON << 4)) | (NORMAL_I_NON_C | R_NON_W_NON)) /* Common cache-ability configuration for Flash, SRAM regions */ -#define MPU_CACHE_ATTRIBUTES_FLASH \ - NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS -#define MPU_CACHE_ATTRIBUTES_SRAM \ +#define MPU_CACHE_ATTRIBUTES_FLASH NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS +/* clang-format off */ +#define MPU_CACHE_ATTRIBUTES_SRAM \ NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS -#define MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE \ - NORMAL_OUTER_INNER_NON_CACHEABLE +/* clang-format on */ +#define MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE NORMAL_OUTER_INNER_NON_CACHEABLE /* Global MAIR configurations */ #define MPU_MAIR_ATTR_FLASH MPU_CACHE_ATTRIBUTES_FLASH @@ -158,10 +148,10 @@ * SRAM no cache-able regions(s): Attribute-2 * DEVICE no cache-able regions(s): Attribute-3 */ -#define MPU_MAIR_ATTRS \ - ((MPU_MAIR_ATTR_FLASH << (MPU_MAIR_INDEX_FLASH * 8)) | \ - (MPU_MAIR_ATTR_SRAM << (MPU_MAIR_INDEX_SRAM * 8)) | \ - (MPU_MAIR_ATTR_SRAM_NOCACHE << (MPU_MAIR_INDEX_SRAM_NOCACHE * 8)) | \ +#define MPU_MAIR_ATTRS \ + ((MPU_MAIR_ATTR_FLASH << (MPU_MAIR_INDEX_FLASH * 8)) | \ + (MPU_MAIR_ATTR_SRAM << (MPU_MAIR_INDEX_SRAM * 8)) | \ + (MPU_MAIR_ATTR_SRAM_NOCACHE << (MPU_MAIR_INDEX_SRAM_NOCACHE * 8)) | \ (MPU_MAIR_ATTR_DEVICE << (MPU_MAIR_INDEX_DEVICE * 8))) /* Some helper defines for common regions. @@ -175,132 +165,118 @@ */ #if defined(CONFIG_AARCH32_ARMV8_R) -#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ - { .name = p_name, \ - .base = p_base, \ - .attr = p_attr(p_base + p_size), \ +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { \ + .name = p_name, \ + .base = p_base, \ + .attr = p_attr(p_base + p_size), \ } -#define REGION_RAM_ATTR(limit) \ - { \ - .rbar = NOT_EXEC | \ - P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_SRAM, \ - .r_limit = limit - 1, /* Region Limit */ \ +#define REGION_RAM_ATTR(limit) \ + { \ + .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \ + .r_limit = limit - 1, /* Region Limit */ \ } -#define REGION_RAM_TEXT_ATTR(limit) \ - { \ - .rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_SRAM, \ - .r_limit = limit - 1, /* Region Limit */ \ +#define REGION_RAM_TEXT_ATTR(limit) \ + { \ + .rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \ + .r_limit = limit - 1, /* Region Limit */ \ } -#define REGION_RAM_RO_ATTR(limit) \ - { \ - .rbar = NOT_EXEC | \ - P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_SRAM, \ - .r_limit = limit - 1, /* Region Limit */ \ +#define REGION_RAM_RO_ATTR(limit) \ + { \ + .rbar = NOT_EXEC | P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \ + .r_limit = limit - 1, /* Region Limit */ \ } -#define REGION_RAM_NOCACHE_ATTR(limit) \ - { \ - .rbar = NOT_EXEC | \ - P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, \ - .r_limit = limit - 1, /* Region Limit */ \ +#define REGION_RAM_NOCACHE_ATTR(limit) \ + { \ + .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, /* Cache-ability */ \ + .r_limit = limit - 1, /* Region Limit */ \ } #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) /* Note that the access permissions allow for un-privileged writes, contrary * to ARMv7-M where un-privileged code has Read-Only permissions. */ -#define REGION_FLASH_ATTR(limit) \ - { \ - .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_FLASH, \ - .r_limit = limit - 1, /* Region Limit */ \ +#define REGION_FLASH_ATTR(limit) \ + { \ + .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \ + .r_limit = limit - 1, /* Region Limit */ \ } #else /* CONFIG_MPU_ALLOW_FLASH_WRITE */ -#define REGION_FLASH_ATTR(limit) \ - { \ - .rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_FLASH, \ - .r_limit = limit - 1, /* Region Limit */ \ +#define REGION_FLASH_ATTR(limit) \ + { \ + .rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \ + .r_limit = limit - 1, /* Region Limit */ \ } #endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */ -#define REGION_DEVICE_ATTR(limit) \ - { \ - /* AP, XN, SH */ \ - .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_DEVICE, \ - /* Region Limit */ \ - .r_limit = limit - 1, \ +#define REGION_DEVICE_ATTR(limit) \ + { \ + .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_DEVICE, /* Cache-ability */ \ + .r_limit = limit - 1, /* Region Limit */ \ } #else -#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ - { .name = p_name, \ - .base = p_base, \ - .attr = p_attr(p_base, p_size), \ +#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \ + { \ + .name = p_name, \ + .base = p_base, \ + .attr = p_attr(p_base, p_size), \ } /* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When * CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep * the SRAM region XN bit clear or the application code will not be executable. */ -#define REGION_RAM_ATTR(base, size) \ - {\ - .rbar = IF_ENABLED(CONFIG_XIP, (NOT_EXEC |)) \ - P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_SRAM, \ - .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ +/* clang-format off */ +#define REGION_RAM_ATTR(base, size) \ + { \ + .rbar = IF_ENABLED(CONFIG_XIP, (NOT_EXEC |)) P_RW_U_NA_Msk | \ + NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \ + .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ } +/* clang-format on */ -#define REGION_RAM_NOCACHE_ATTR(base, size) \ - {\ - .rbar = NOT_EXEC | \ - P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, \ - .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ +#define REGION_RAM_NOCACHE_ATTR(base, size) \ + { \ + .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, /* Cache-ability */ \ + .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ } #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) /* Note that the access permissions allow for un-privileged writes, contrary * to ARMv7-M where un-privileged code has Read-Only permissions. */ -#define REGION_FLASH_ATTR(base, size) \ - {\ - .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_FLASH, \ - .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ +#define REGION_FLASH_ATTR(base, size) \ + { \ + .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \ + .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ } #else /* CONFIG_MPU_ALLOW_FLASH_WRITE */ -#define REGION_FLASH_ATTR(base, size) \ - {\ - .rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ - /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_FLASH, \ - .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ +#define REGION_FLASH_ATTR(base, size) \ + { \ + .rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \ + .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ } #endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */ #define REGION_DEVICE_ATTR(base, size) \ { \ - /* AP, XN, SH */ \ - .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* Cache-ability */ \ - .mair_idx = MPU_MAIR_INDEX_DEVICE, \ - .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ + .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_DEVICE, /* Cache-ability */ \ + .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ } #endif @@ -333,20 +309,18 @@ typedef struct { */ /* Read-Write access permission attributes */ -#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ - {(P_RW_U_RW_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) -#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ - {(P_RW_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) -#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ - {(P_RO_U_RO_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) -#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ - {(P_RO_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RW_U_RW \ + ((k_mem_partition_attr_t){(P_RW_U_RW_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RW_U_NA \ + ((k_mem_partition_attr_t){(P_RW_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RO_U_RO \ + ((k_mem_partition_attr_t){(P_RO_U_RO_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RO_U_NA \ + ((k_mem_partition_attr_t){(P_RO_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM}) /* Execution-allowed attributes */ -#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \ - {(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM}) -#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \ - {(P_RO_U_RO_Msk), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t){(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM}) +#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t){(P_RO_U_RO_Msk), MPU_MAIR_INDEX_SRAM}) /* * @brief Evaluate Write-ability @@ -356,18 +330,18 @@ typedef struct { * @param attr The k_mem_partition_attr_t object holding the * MPU attributes to be checked against write-ability. */ -#define K_MEM_PARTITION_IS_WRITABLE(attr) \ - ({ \ - int __is_writable__; \ - switch (attr.rbar & MPU_RBAR_AP_Msk) { \ - case P_RW_U_RW_Msk: \ - case P_RW_U_NA_Msk: \ - __is_writable__ = 1; \ - break; \ - default: \ - __is_writable__ = 0; \ - } \ - __is_writable__; \ +#define K_MEM_PARTITION_IS_WRITABLE(attr) \ + ({ \ + int __is_writable__; \ + switch (attr.rbar & MPU_RBAR_AP_Msk) { \ + case P_RW_U_RW_Msk: \ + case P_RW_U_NA_Msk: \ + __is_writable__ = 1; \ + break; \ + default: \ + __is_writable__ = 0; \ + } \ + __is_writable__; \ }) /* @@ -379,36 +353,37 @@ typedef struct { * MPU attributes to be checked against execution * allowance. */ -#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ - (!((attr.rbar) & (NOT_EXEC))) +#define K_MEM_PARTITION_IS_EXECUTABLE(attr) (!((attr.rbar) & (NOT_EXEC))) /* Attributes for no-cache enabling (share-ability is selected by default) */ /* Read-Write access permission attributes */ -#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \ - {(P_RW_U_RW_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ - MPU_MAIR_INDEX_SRAM_NOCACHE}) -#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \ - {(P_RW_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ - MPU_MAIR_INDEX_SRAM_NOCACHE}) -#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \ - {(P_RO_U_RO_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ - MPU_MAIR_INDEX_SRAM_NOCACHE}) -#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \ - {(P_RO_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ - MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE \ + ((k_mem_partition_attr_t){(P_RW_U_RW_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE \ + ((k_mem_partition_attr_t){(P_RW_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE \ + ((k_mem_partition_attr_t){(P_RO_U_RO_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE \ + ((k_mem_partition_attr_t){(P_RO_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) /* Execution-allowed attributes */ -#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \ - {(P_RW_U_RW_Msk | OUTER_SHAREABLE_Msk), MPU_MAIR_INDEX_SRAM_NOCACHE}) -#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \ - {(P_RO_U_RO_Msk | OUTER_SHAREABLE_Msk), MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE \ + ((k_mem_partition_attr_t){(P_RW_U_RW_Msk | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) +#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE \ + ((k_mem_partition_attr_t){(P_RO_U_RO_Msk | OUTER_SHAREABLE_Msk), \ + MPU_MAIR_INDEX_SRAM_NOCACHE}) #endif /* _ASMLANGUAGE */ -#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ - BUILD_ASSERT((size > 0) && ((uint32_t)start % \ - CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0U) && \ - ((size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0), \ - " the start and size of the partition must align " \ - "with the minimum MPU region size.") +#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ + BUILD_ASSERT((size > 0) && \ + ((uint32_t)start % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0U) && \ + ((size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0), \ + "The start and size of the partition must align with the minimum MPU " \ + "region size.") diff --git a/include/zephyr/arch/arm/mpu/nxp_mpu.h b/include/zephyr/arch/arm/mpu/nxp_mpu.h index b95565658027c..b1bc9c2e4510b 100644 --- a/include/zephyr/arch/arm/mpu/nxp_mpu.h +++ b/include/zephyr/arch/arm/mpu/nxp_mpu.h @@ -11,119 +11,102 @@ #define NXP_MPU_REGION_NUMBER 12 /* Bus Master User Mode Access */ -#define UM_READ 4 -#define UM_WRITE 2 -#define UM_EXEC 1 +#define UM_READ 4 +#define UM_WRITE 2 +#define UM_EXEC 1 -#define BM0_UM_SHIFT 0 -#define BM1_UM_SHIFT 6 -#define BM2_UM_SHIFT 12 -#define BM3_UM_SHIFT 18 +#define BM0_UM_SHIFT 0 +#define BM1_UM_SHIFT 6 +#define BM2_UM_SHIFT 12 +#define BM3_UM_SHIFT 18 /* Bus Master Supervisor Mode Access */ -#define SM_RWX_ALLOW 0 -#define SM_RX_ALLOW 1 -#define SM_RW_ALLOW 2 -#define SM_SAME_AS_UM 3 +#define SM_RWX_ALLOW 0 +#define SM_RX_ALLOW 1 +#define SM_RW_ALLOW 2 +#define SM_SAME_AS_UM 3 -#define BM0_SM_SHIFT 3 -#define BM1_SM_SHIFT 9 -#define BM2_SM_SHIFT 15 -#define BM3_SM_SHIFT 21 +#define BM0_SM_SHIFT 3 +#define BM1_SM_SHIFT 9 +#define BM2_SM_SHIFT 15 +#define BM3_SM_SHIFT 21 -#define BM4_WE_SHIFT 24 -#define BM4_RE_SHIFT 25 +#define BM4_WE_SHIFT 24 +#define BM4_RE_SHIFT 25 #if CONFIG_USB_KINETIS || CONFIG_UDC_KINETIS -#define BM4_PERMISSIONS ((1 << BM4_RE_SHIFT) | (1 << BM4_WE_SHIFT)) +#define BM4_PERMISSIONS ((1 << BM4_RE_SHIFT) | (1 << BM4_WE_SHIFT)) #else -#define BM4_PERMISSIONS 0 +#define BM4_PERMISSIONS 0 #endif /* Read Attribute */ -#define MPU_REGION_READ ((UM_READ << BM0_UM_SHIFT) | \ - (UM_READ << BM1_UM_SHIFT) | \ - (UM_READ << BM2_UM_SHIFT) | \ - (UM_READ << BM3_UM_SHIFT)) +#define MPU_REGION_READ \ + ((UM_READ << BM0_UM_SHIFT) | (UM_READ << BM1_UM_SHIFT) | (UM_READ << BM2_UM_SHIFT) | \ + (UM_READ << BM3_UM_SHIFT)) /* Write Attribute */ -#define MPU_REGION_WRITE ((UM_WRITE << BM0_UM_SHIFT) | \ - (UM_WRITE << BM1_UM_SHIFT) | \ - (UM_WRITE << BM2_UM_SHIFT) | \ - (UM_WRITE << BM3_UM_SHIFT)) +#define MPU_REGION_WRITE \ + ((UM_WRITE << BM0_UM_SHIFT) | (UM_WRITE << BM1_UM_SHIFT) | (UM_WRITE << BM2_UM_SHIFT) | \ + (UM_WRITE << BM3_UM_SHIFT)) /* Execute Attribute */ -#define MPU_REGION_EXEC ((UM_EXEC << BM0_UM_SHIFT) | \ - (UM_EXEC << BM1_UM_SHIFT) | \ - (UM_EXEC << BM2_UM_SHIFT) | \ - (UM_EXEC << BM3_UM_SHIFT)) +#define MPU_REGION_EXEC \ + ((UM_EXEC << BM0_UM_SHIFT) | (UM_EXEC << BM1_UM_SHIFT) | (UM_EXEC << BM2_UM_SHIFT) | \ + (UM_EXEC << BM3_UM_SHIFT)) /* Super User Attributes */ -#define MPU_REGION_SU ((SM_SAME_AS_UM << BM0_SM_SHIFT) | \ - (SM_SAME_AS_UM << BM1_SM_SHIFT) | \ - (SM_SAME_AS_UM << BM2_SM_SHIFT) | \ - (SM_SAME_AS_UM << BM3_SM_SHIFT)) - -#define MPU_REGION_SU_RX ((SM_RX_ALLOW << BM0_SM_SHIFT) | \ - (SM_RX_ALLOW << BM1_SM_SHIFT) | \ - (SM_RX_ALLOW << BM2_SM_SHIFT) | \ - (SM_RX_ALLOW << BM3_SM_SHIFT)) - -#define MPU_REGION_SU_RW ((SM_RW_ALLOW << BM0_SM_SHIFT) | \ - (SM_RW_ALLOW << BM1_SM_SHIFT) | \ - (SM_RW_ALLOW << BM2_SM_SHIFT) | \ - (SM_RW_ALLOW << BM3_SM_SHIFT)) - -#define MPU_REGION_SU_RWX ((SM_RWX_ALLOW << BM0_SM_SHIFT) | \ - (SM_RWX_ALLOW << BM1_SM_SHIFT) | \ - (SM_RWX_ALLOW << BM2_SM_SHIFT) | \ - (SM_RWX_ALLOW << BM3_SM_SHIFT)) +#define MPU_REGION_SU \ + ((SM_SAME_AS_UM << BM0_SM_SHIFT) | (SM_SAME_AS_UM << BM1_SM_SHIFT) | \ + (SM_SAME_AS_UM << BM2_SM_SHIFT) | (SM_SAME_AS_UM << BM3_SM_SHIFT)) + +#define MPU_REGION_SU_RX \ + ((SM_RX_ALLOW << BM0_SM_SHIFT) | (SM_RX_ALLOW << BM1_SM_SHIFT) | \ + (SM_RX_ALLOW << BM2_SM_SHIFT) | (SM_RX_ALLOW << BM3_SM_SHIFT)) + +#define MPU_REGION_SU_RW \ + ((SM_RW_ALLOW << BM0_SM_SHIFT) | (SM_RW_ALLOW << BM1_SM_SHIFT) | \ + (SM_RW_ALLOW << BM2_SM_SHIFT) | (SM_RW_ALLOW << BM3_SM_SHIFT)) + +#define MPU_REGION_SU_RWX \ + ((SM_RWX_ALLOW << BM0_SM_SHIFT) | (SM_RWX_ALLOW << BM1_SM_SHIFT) | \ + (SM_RWX_ALLOW << BM2_SM_SHIFT) | (SM_RWX_ALLOW << BM3_SM_SHIFT)) /* The ENDADDR field has the last 5 bit reserved and set to 1 */ #define ENDADDR_ROUND(x) (x - 0x1F) -#define REGION_USER_MODE_ATTR {(MPU_REGION_READ | \ - MPU_REGION_WRITE | \ - MPU_REGION_SU)} +#define REGION_USER_MODE_ATTR {(MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_SU)} /* Some helper defines for common regions */ #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) -#define REGION_RAM_ATTR {((MPU_REGION_SU_RWX) | \ - ((UM_READ | UM_WRITE | UM_EXEC) << BM3_UM_SHIFT) | \ - (BM4_PERMISSIONS))} +#define REGION_RAM_ATTR \ + {((MPU_REGION_SU_RWX) | ((UM_READ | UM_WRITE | UM_EXEC) << BM3_UM_SHIFT) | \ + (BM4_PERMISSIONS))} #define REGION_FLASH_ATTR {(MPU_REGION_SU_RWX)} #else -#define REGION_RAM_ATTR {((MPU_REGION_SU_RW) | \ - ((UM_READ | UM_WRITE) << BM3_UM_SHIFT) | \ - (BM4_PERMISSIONS))} +#define REGION_RAM_ATTR \ + {((MPU_REGION_SU_RW) | ((UM_READ | UM_WRITE) << BM3_UM_SHIFT) | (BM4_PERMISSIONS))} -#define REGION_FLASH_ATTR {(MPU_REGION_READ | \ - MPU_REGION_EXEC | \ - MPU_REGION_SU)} +#define REGION_FLASH_ATTR {(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU)} #endif -#define REGION_IO_ATTR {(MPU_REGION_READ | \ - MPU_REGION_WRITE | \ - MPU_REGION_EXEC | \ - MPU_REGION_SU)} +#define REGION_IO_ATTR {(MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_EXEC | MPU_REGION_SU)} -#define REGION_RO_ATTR {(MPU_REGION_READ | MPU_REGION_SU)} +#define REGION_RO_ATTR {(MPU_REGION_READ | MPU_REGION_SU)} -#define REGION_USER_RO_ATTR {(MPU_REGION_READ | \ - MPU_REGION_SU)} +#define REGION_USER_RO_ATTR {(MPU_REGION_READ | MPU_REGION_SU)} /* ENET (Master 3) and USB (Master 4) devices will not be able to access RAM when the region is dynamically disabled in NXP MPU. DEBUGGER (Master 1) can't be disabled in Region 0. */ -#define REGION_DEBUGGER_AND_DEVICE_ATTR {((MPU_REGION_SU) | \ - ((UM_READ | UM_WRITE) << BM3_UM_SHIFT) | \ - (BM4_PERMISSIONS))} +#define REGION_DEBUGGER_AND_DEVICE_ATTR \ + {((MPU_REGION_SU) | ((UM_READ | UM_WRITE) << BM3_UM_SHIFT) | (BM4_PERMISSIONS))} -#define REGION_DEBUG_ATTR {MPU_REGION_SU} +#define REGION_DEBUG_ATTR {MPU_REGION_SU} -#define REGION_BACKGROUND_ATTR {MPU_REGION_SU_RW} +#define REGION_BACKGROUND_ATTR {MPU_REGION_SU_RW} struct nxp_mpu_region_attr { /* NXP MPU region access permission attributes */ @@ -145,27 +128,22 @@ typedef struct { */ /* Read-Write access permission attributes */ -#define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t) \ - {(MPU_REGION_SU)}) -#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ - {(MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_SU)}) -#define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t) \ - {(MPU_REGION_READ | MPU_REGION_SU_RW)}) -#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ - {(MPU_REGION_SU_RW)}) -#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ - {(MPU_REGION_READ | MPU_REGION_SU)}) -#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ - {(MPU_REGION_SU_RX)}) +#define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t){(MPU_REGION_SU)}) +#define K_MEM_PARTITION_P_RW_U_RW \ + ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_SU)}) +#define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_SU_RW)}) +#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t){(MPU_REGION_SU_RW)}) +#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_SU)}) +#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t){(MPU_REGION_SU_RX)}) /* Execution-allowed attributes */ -#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \ - {(MPU_REGION_READ | MPU_REGION_WRITE | \ - MPU_REGION_EXEC | MPU_REGION_SU)}) -#define K_MEM_PARTITION_P_RWX_U_RX ((k_mem_partition_attr_t) \ - {(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU_RWX)}) -#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \ - {(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU)}) +#define K_MEM_PARTITION_P_RWX_U_RWX \ + ((k_mem_partition_attr_t){ \ + (MPU_REGION_READ | MPU_REGION_WRITE | MPU_REGION_EXEC | MPU_REGION_SU)}) +#define K_MEM_PARTITION_P_RWX_U_RX \ + ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU_RWX)}) +#define K_MEM_PARTITION_P_RX_U_RX \ + ((k_mem_partition_attr_t){(MPU_REGION_READ | MPU_REGION_EXEC | MPU_REGION_SU)}) /* * @brief Evaluate Write-ability @@ -175,18 +153,18 @@ typedef struct { * @param attr The k_mem_partition_attr_t object holding the * MPU attributes to be checked against write-ability. */ -#define K_MEM_PARTITION_IS_WRITABLE(attr) \ - ({ \ - int __is_writable__; \ - switch (attr.ap_attr) { \ - case MPU_REGION_WRITE: \ - case MPU_REGION_SU_RW: \ - __is_writable__ = 1; \ - break; \ - default: \ - __is_writable__ = 0; \ - } \ - __is_writable__; \ +#define K_MEM_PARTITION_IS_WRITABLE(attr) \ + ({ \ + int __is_writable__; \ + switch (attr.ap_attr) { \ + case MPU_REGION_WRITE: \ + case MPU_REGION_SU_RW: \ + __is_writable__ = 1; \ + break; \ + default: \ + __is_writable__ = 0; \ + } \ + __is_writable__; \ }) /* @@ -198,21 +176,20 @@ typedef struct { * MPU attributes to be checked against execution * allowance. */ -#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ - ({ \ - int __is_executable__; \ - switch (attr.ap_attr) { \ - case MPU_REGION_SU_RX: \ - case MPU_REGION_EXEC: \ - __is_executable__ = 1; \ - break; \ - default: \ - __is_executable__ = 0; \ - } \ - __is_executable__; \ +#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \ + ({ \ + int __is_executable__; \ + switch (attr.ap_attr) { \ + case MPU_REGION_SU_RX: \ + case MPU_REGION_EXEC: \ + __is_executable__ = 1; \ + break; \ + default: \ + __is_executable__ = 0; \ + } \ + __is_executable__; \ }) - /* Region definition data structure */ struct nxp_mpu_region { /* Region Base Address */ @@ -225,12 +202,12 @@ struct nxp_mpu_region { nxp_mpu_region_attr_t attr; }; -#define MPU_REGION_ENTRY(_name, _base, _end, _attr) \ - {\ - .name = _name, \ - .base = _base, \ - .end = _end, \ - .attr = _attr, \ +#define MPU_REGION_ENTRY(_name, _base, _end, _attr) \ + { \ + .name = _name, \ + .base = _base, \ + .end = _end, \ + .attr = _attr, \ } /* MPU configuration data structure */ @@ -255,15 +232,13 @@ extern const struct nxp_mpu_config mpu_config; #endif /* _ASMLANGUAGE */ -#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ - BUILD_ASSERT((size) % \ - CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0 && \ - (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ - (uint32_t)(start) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0, \ - "the size of the partition must align with minimum MPU \ - region size" \ - " and greater than or equal to minimum MPU region size." \ - "start address of the partition must align with minimum MPU \ - region size.") +#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \ + BUILD_ASSERT( \ + (size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0 && \ + (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \ + (uint32_t)(start) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0, \ + "The size of the partition must align with minimum MPU region size" \ + " and greater than or equal to minimum MPU region size.\n" \ + "The start address of the partition must align with minimum MPU region size.") #endif /* ZEPHYR_INCLUDE_ARCH_ARM_MPU_NXP_MPU_H_ */ diff --git a/include/zephyr/arch/arm/nmi.h b/include/zephyr/arch/arm/nmi.h index 33f46084248ed..1f92456fe12de 100644 --- a/include/zephyr/arch/arm/nmi.h +++ b/include/zephyr/arch/arm/nmi.h @@ -13,8 +13,16 @@ #ifndef ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_ #define ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_ +#ifdef __cplusplus +extern "C" { +#endif + #if !defined(_ASMLANGUAGE) && defined(CONFIG_RUNTIME_NMI) extern void z_arm_nmi_set_handler(void (*pHandler)(void)); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_ */ diff --git a/include/zephyr/arch/arm64/lib_helpers.h b/include/zephyr/arch/arm64/lib_helpers.h index 0f3d9d563abe2..347075af7d453 100644 --- a/include/zephyr/arch/arm64/lib_helpers.h +++ b/include/zephyr/arch/arm64/lib_helpers.h @@ -24,8 +24,9 @@ #define write_sysreg(val, reg) \ ({ \ + uint64_t reg_val = val; \ __asm__ volatile ("msr " STRINGIFY(reg) ", %0" \ - :: "r" (val) : "memory"); \ + :: "r" (reg_val) : "memory"); \ }) #define zero_sysreg(reg) \ diff --git a/include/zephyr/arch/common/arch_inlines.h b/include/zephyr/arch/common/arch_inlines.h deleted file mode 100644 index 8c0ba3343ad9f..0000000000000 --- a/include/zephyr/arch/common/arch_inlines.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2024 Meta Platforms. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_ZEPHYR_ARCH_COMMON_ARCH_INLINES_H_ -#define ZEPHYR_INCLUDE_ZEPHYR_ARCH_COMMON_ARCH_INLINES_H_ - -#ifndef ZEPHYR_INCLUDE_ARCH_INLINES_H_ -#error "This header shouldn't be included directly" -#endif /* ZEPHYR_INCLUDE_ARCH_INLINES_H_ */ - -#ifndef _ASMLANGUAGE - -#include - -#ifndef CONFIG_ARCH_HAS_CUSTOM_CURRENT_IMPL -static ALWAYS_INLINE struct k_thread *arch_current_thread(void) -{ -#ifdef CONFIG_SMP - /* In SMP, arch_current_thread() is a field read from _current_cpu, which - * can race with preemption before it is read. We must lock - * local interrupts when reading it. - */ - unsigned int k = arch_irq_lock(); - - struct k_thread *ret = _current_cpu->current; - - arch_irq_unlock(k); -#else - struct k_thread *ret = _kernel.cpus[0].current; -#endif /* CONFIG_SMP */ - return ret; -} - -static ALWAYS_INLINE void arch_current_thread_set(struct k_thread *thread) -{ - _current_cpu->current = thread; -} -#endif /* CONFIG_ARCH_HAS_CUSTOM_CURRENT_IMPL */ - -#endif /* _ASMLANGUAGE */ - -#endif /* ZEPHYR_INCLUDE_ZEPHYR_ARCH_COMMON_ARCH_INLINES_H_ */ diff --git a/include/zephyr/arch/mips/exception.h b/include/zephyr/arch/mips/exception.h index f33af4c4387d8..352ef887a518d 100644 --- a/include/zephyr/arch/mips/exception.h +++ b/include/zephyr/arch/mips/exception.h @@ -6,8 +6,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_ARCH_MIPS_EXPCEPTION_H_ -#define ZEPHYR_INCLUDE_ARCH_MIPS_EXPCEPTION_H_ +#ifndef ZEPHYR_INCLUDE_ARCH_MIPS_EXCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_MIPS_EXCEPTION_H_ #ifndef _ASMLANGUAGE #include @@ -56,4 +56,4 @@ struct arch_esf { #endif /* _ASMLANGUAGE */ -#endif /* ZEPHYR_INCLUDE_ARCH_MIPS_EXPCEPTION_H_ */ +#endif /* ZEPHYR_INCLUDE_ARCH_MIPS_EXCEPTION_H_ */ diff --git a/include/zephyr/arch/nios2/exception.h b/include/zephyr/arch/nios2/exception.h index 223fa583114e6..c2c614ae88fcb 100644 --- a/include/zephyr/arch/nios2/exception.h +++ b/include/zephyr/arch/nios2/exception.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_EXPCEPTION_H_ -#define ZEPHYR_INCLUDE_ARCH_NIOS2_EXPCEPTION_H_ +#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_EXCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_NIOS2_EXCEPTION_H_ #ifndef _ASMLANGUAGE #include @@ -41,4 +41,4 @@ struct arch_esf { #endif /* _ASMLANGUAGE */ -#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_EXPCEPTION_H_ */ +#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_EXCEPTION_H_ */ diff --git a/include/zephyr/arch/posix/exception.h b/include/zephyr/arch/posix/exception.h index 6c7962aa05799..4387a5547ee29 100644 --- a/include/zephyr/arch/posix/exception.h +++ b/include/zephyr/arch/posix/exception.h @@ -5,8 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_ARCH_POSIX_EXPCEPTION_H_ -#define ZEPHYR_INCLUDE_ARCH_POSIX_EXPCEPTION_H_ +#ifndef ZEPHYR_INCLUDE_ARCH_POSIX_EXCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_POSIX_EXCEPTION_H_ #ifndef _ASMLANGUAGE #include @@ -25,4 +25,4 @@ struct arch_esf { #endif /* _ASMLANGUAGE */ -#endif /* ZEPHYR_INCLUDE_ARCH_POSIX_EXPCEPTION_H_ */ +#endif /* ZEPHYR_INCLUDE_ARCH_POSIX_EXCEPTION_H_ */ diff --git a/include/zephyr/arch/riscv/arch_inlines.h b/include/zephyr/arch/riscv/arch_inlines.h index 2752b43d97706..022879c88d40d 100644 --- a/include/zephyr/arch/riscv/arch_inlines.h +++ b/include/zephyr/arch/riscv/arch_inlines.h @@ -28,13 +28,12 @@ static ALWAYS_INLINE _cpu_t *arch_curr_cpu(void) } #ifdef CONFIG_RISCV_CURRENT_VIA_GP + register struct k_thread *__arch_current_thread __asm__("gp"); #define arch_current_thread() __arch_current_thread -#define arch_current_thread_set(thread) \ - do { \ - _current_cpu->current = __arch_current_thread = (thread); \ - } while (0) +#define arch_current_thread_set(thread) ({ __arch_current_thread = (thread); }) + #endif /* CONFIG_RISCV_CURRENT_VIA_GP */ static ALWAYS_INLINE unsigned int arch_num_cpus(void) diff --git a/include/zephyr/arch/riscv/exception.h b/include/zephyr/arch/riscv/exception.h index 4e46417048c18..eb3cabebd419f 100644 --- a/include/zephyr/arch/riscv/exception.h +++ b/include/zephyr/arch/riscv/exception.h @@ -78,6 +78,10 @@ struct arch_esf { unsigned long a7; /* function argument */ #endif /* !CONFIG_RISCV_ISA_RV32E */ +#ifdef CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL + unsigned long mcause; /* machine cause register */ +#endif /* CONFIG_CLIC_SUPPORT_INTERRUPT_LEVEL */ + unsigned long mepc; /* machine exception program counter */ unsigned long mstatus; /* machine status register */ diff --git a/include/zephyr/arch/sparc/exception.h b/include/zephyr/arch/sparc/exception.h index a2d3fae52e203..9d6181a2947d3 100644 --- a/include/zephyr/arch/sparc/exception.h +++ b/include/zephyr/arch/sparc/exception.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_ARCH_SPARC_EXPCEPTION_H_ -#define ZEPHYR_INCLUDE_ARCH_SPARC_EXPCEPTION_H_ +#ifndef ZEPHYR_INCLUDE_ARCH_SPARC_EXCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_SPARC_EXCEPTION_H_ #ifndef _ASMLANGUAGE #include @@ -31,4 +31,4 @@ struct arch_esf { #endif /* _ASMLANGUAGE */ -#endif /* ZEPHYR_INCLUDE_ARCH_SPARC_EXPCEPTION_H_ */ +#endif /* ZEPHYR_INCLUDE_ARCH_SPARC_EXCEPTION_H_ */ diff --git a/include/zephyr/arch/x86/ia32/arch.h b/include/zephyr/arch/x86/ia32/arch.h index e2f961c817e25..b82e0db0f1733 100644 --- a/include/zephyr/arch/x86/ia32/arch.h +++ b/include/zephyr/arch/x86/ia32/arch.h @@ -305,7 +305,7 @@ static inline void arch_isr_direct_footer(int swap) * 3) Next thread to run in the ready queue is not this thread */ if (swap != 0 && _kernel.cpus[0].nested == 0 && - _kernel.ready_q.cache != arch_current_thread()) { + _kernel.ready_q.cache != _current) { unsigned int flags; /* Fetch EFLAGS argument to z_swap() */ diff --git a/include/zephyr/arch/x86/ia32/exception.h b/include/zephyr/arch/x86/ia32/exception.h index de618f4e01d43..d1acafb3fd39a 100644 --- a/include/zephyr/arch/x86/ia32/exception.h +++ b/include/zephyr/arch/x86/ia32/exception.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_ARCH_X86_IA32_EXPCEPTION_H_ -#define ZEPHYR_INCLUDE_ARCH_X86_IA32_EXPCEPTION_H_ +#ifndef ZEPHYR_INCLUDE_ARCH_X86_IA32_EXCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_X86_IA32_EXCEPTION_H_ #ifndef _ASMLANGUAGE #include @@ -67,4 +67,4 @@ struct _x86_syscall_stack_frame { #endif /* _ASMLANGUAGE */ -#endif /* ZEPHYR_INCLUDE_ARCH_X86_IA32_EXPCEPTION_H_ */ +#endif /* ZEPHYR_INCLUDE_ARCH_X86_IA32_EXCEPTION_H_ */ diff --git a/include/zephyr/arch/x86/intel64/exception.h b/include/zephyr/arch/x86/intel64/exception.h index 55c7cc2b4ee84..7a78950334e21 100644 --- a/include/zephyr/arch/x86/intel64/exception.h +++ b/include/zephyr/arch/x86/intel64/exception.h @@ -3,8 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXPCEPTION_H_ -#define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXPCEPTION_H_ +#ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXCEPTION_H_ #ifndef _ASMLANGUAGE #include @@ -72,4 +72,4 @@ struct x86_ssf { #endif /* _ASMLANGUAGE */ -#endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXPCEPTION_H_ */ +#endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_EXCEPTION_H_ */ diff --git a/include/zephyr/arch/x86/thread_stack.h b/include/zephyr/arch/x86/thread_stack.h index f22bf4d6853c4..fb5572055daa4 100644 --- a/include/zephyr/arch/x86/thread_stack.h +++ b/include/zephyr/arch/x86/thread_stack.h @@ -107,7 +107,6 @@ struct z_x86_thread_stack_header { #define ARCH_KERNEL_STACK_RESERVED CONFIG_MMU_PAGE_SIZE #define ARCH_KERNEL_STACK_OBJ_ALIGN CONFIG_MMU_PAGE_SIZE #else -#define ARCH_KERNEL_STACK_RESERVED 0 #define ARCH_KERNEL_STACK_OBJ_ALIGN ARCH_STACK_PTR_ALIGN #endif diff --git a/include/zephyr/arch/xtensa/thread_stack.h b/include/zephyr/arch/xtensa/thread_stack.h index 816eaf3b97c24..6155f0dfe0e09 100644 --- a/include/zephyr/arch/xtensa/thread_stack.h +++ b/include/zephyr/arch/xtensa/thread_stack.h @@ -68,7 +68,6 @@ struct xtensa_thread_stack_header { ROUND_UP((size), XTENSA_STACK_SIZE_ALIGN) /* kernel stack */ -#define ARCH_KERNEL_STACK_RESERVED 0 #define ARCH_KERNEL_STACK_OBJ_ALIGN ARCH_STACK_PTR_ALIGN #endif /* _ASMLANGUAGE */ diff --git a/include/zephyr/audio/midi.h b/include/zephyr/audio/midi.h new file mode 100644 index 0000000000000..d564531ecad24 --- /dev/null +++ b/include/zephyr/audio/midi.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2024 Titouan Christophe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_AUDIO_MIDI_H_ +#define ZEPHYR_INCLUDE_AUDIO_MIDI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @brief Universal MIDI Packet definitions + * @defgroup midi_ump MIDI2 Universal MIDI Packet definitions + * @ingroup audio_interface + * @since 4.1 + * @version 0.1.0 + * @see ump112: "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol" + * Document version 1.1.2 + * @{ + */ + +/** + * @brief Universal MIDI Packet container + */ +struct midi_ump { + uint32_t data[4]; /**< Raw content, in the CPU native endianness */ +}; + +/** + * @defgroup midi_ump_mt Message types + * @ingroup midi_ump + * @see ump112: 2.1.4 Message Type (MT) Allocation + * @{ + */ + +/** Utility Messages */ +#define UMP_MT_UTILITY 0x00 +/** System Real Time and System Common Messages (except System Exclusive) */ +#define UMP_MT_SYS_RT_COMMON 0x01 +/** MIDI 1.0 Channel Voice Messages */ +#define UMP_MT_MIDI1_CHANNEL_VOICE 0x02 +/** 64 bits Data Messages (including System Exclusive) */ +#define UMP_MT_DATA_64 0x03 +/** MIDI 2.0 Channel Voice Messages */ +#define UMP_MT_MIDI2_CHANNEL_VOICE 0x04 +/** 128 bits Data Messages */ +#define UMP_MT_DATA_128 0x05 +/** Flex Data Messages */ +#define UMP_MT_FLEX_DATA 0x0d +/** UMP Stream Message */ +#define UMP_MT_UMP_STREAM 0x0f +/** @} */ + +/** + * @brief Message Type field of a Universal MIDI Packet + * @param[in] ump Universal MIDI Packet + */ +#define UMP_MT(ump) \ + ((ump).data[0] >> 28) + +/** + * There are 16 UMP message types, each of which can be 1 to 4 uint32 long. + * Hence this packed representation of 16x2b array as an uint32 lookup table + */ +#define UMP_NUM_WORDS_LOOKUP_TABLE \ + ((0U << 0) | (0U << 2) | (0U << 4) | (1U << 6) | \ + (1U << 8) | (3U << 10) | (0U << 12) | (0U << 14) | \ + (1U << 16) | (1U << 18) | (1U << 20) | (2U << 22) | \ + (2U << 24) | (3U << 26) | (3U << 28) | (3U << 30)) + +/** + * @brief Size of a Universal MIDI Packet, in 32bit words + * @param[in] ump Universal MIDI Packet + * @see ump112: 2.1.4 Message Type (MT) Allocation + */ +#define UMP_NUM_WORDS(ump) \ + (1 + ((UMP_NUM_WORDS_LOOKUP_TABLE >> (2 * UMP_MT(ump))) & 3)) + +/** + * @brief MIDI group field of a Universal MIDI Packet + * @param[in] ump Universal MIDI Packet + */ +#define UMP_GROUP(ump) \ + (((ump).data[0] >> 24) & 0x0f) + +/** + * @brief Status byte of a MIDI channel voice or system message + * @param[in] ump Universal MIDI Packet (containing a MIDI1 event) + */ +#define UMP_MIDI_STATUS(ump) \ + (((ump).data[0] >> 16) & 0xff) +/** + * @brief Command of a MIDI channel voice message + * @param[in] ump Universal MIDI Packet (containing a MIDI event) + * @see midi_ump_cmd + */ +#define UMP_MIDI_COMMAND(ump) \ + (UMP_MIDI_STATUS(ump) >> 4) +/** + * @brief Channel of a MIDI channel voice message + * @param[in] ump Universal MIDI Packet (containing a MIDI event) + */ +#define UMP_MIDI_CHANNEL(ump) \ + (UMP_MIDI_STATUS(ump) & 0x0f) +/** + * @brief First parameter of a MIDI1 channel voice or system message + * @param[in] ump Universal MIDI Packet (containing a MIDI1 message) + */ +#define UMP_MIDI1_P1(ump) \ + (((ump).data[0] >> 8) & 0x7f) +/** + * @brief Second parameter of a MIDI1 channel voice or system message + * @param[in] ump Universal MIDI Packet (containing a MIDI1 message) + */ +#define UMP_MIDI1_P2(ump) \ + ((ump).data[0] & 0x7f) + +/** + * @brief Initialize a UMP with a MIDI1 channel voice message + * @remark For messages that take a single parameter, p2 is ignored by the receiver. + * @param group The UMP group + * @param command The MIDI1 command + * @param channel The MIDI1 channel number + * @param p1 The 1st MIDI1 parameter + * @param p2 The 2nd MIDI1 parameter + */ +#define UMP_MIDI1_CHANNEL_VOICE(group, command, channel, p1, p2) \ + (struct midi_ump) {.data = { \ + (UMP_MT_MIDI1_CHANNEL_VOICE << 28) \ + | (((group) & 0x0f) << 24) \ + | (((command) & 0x0f) << 20) \ + | (((channel) & 0x0f) << 16) \ + | (((p1) & 0x7f) << 8) \ + | ((p2) & 0x7f) \ + }} + +/** + * @defgroup midi_ump_cmd MIDI commands + * @ingroup midi_ump + * @see ump112: 7.3 MIDI 1.0 Channel Voice Messages + * + * When UMP_MT(x)=UMP_MT_MIDI1_CHANNEL_VOICE or UMP_MT_MIDI2_CHANNEL_VOICE, then + * UMP_MIDI_COMMAND(x) may be one of: + * @{ + */ +#define UMP_MIDI_NOTE_OFF 0x8 /**< Note Off (p1=note number, p2=velocity) */ +#define UMP_MIDI_NOTE_ON 0x9 /**< Note On (p1=note number, p2=velocity) */ +#define UMP_MIDI_AFTERTOUCH 0xa /**< Polyphonic aftertouch (p1=note number, p2=data) */ +#define UMP_MIDI_CONTROL_CHANGE 0xb /**< Control Change (p1=index, p2=data) */ +#define UMP_MIDI_PROGRAM_CHANGE 0xc /**< Control Change (p1=program) */ +#define UMP_MIDI_CHAN_AFTERTOUCH 0xd /**< Channel aftertouch (p1=data) */ +#define UMP_MIDI_PITCH_BEND 0xe /**< Pitch bend (p1=lsb, p2=msb) */ +/** @} */ + +/** + * @brief Initialize a UMP with a System Real Time and System Common Message + * @remark For messages that take only one (or no) parameter, p2 (and p1) + * are ignored by the receiver. + * @param group The UMP group + * @param status The status byte + * @param p1 The 1st parameter + * @param p2 The 2nd parameter + */ +#define UMP_SYS_RT_COMMON(group, status, p1, p2) \ + (struct midi_ump) {.data = { \ + (UMP_MT_SYS_RT_COMMON << 28) \ + | (((group) & 0x0f) << 24) \ + | ((status) << 16) \ + | (((p1) & 0x7f) << 8) \ + | ((p2) & 0x7f) \ + }} + +/** + * @defgroup midi_ump_sys System common and System Real Time message status + * @ingroup midi_ump + * @see ump112: 7.6 System Common and System Real Time Messages + * + * When UMP_MT(x)=UMP_MT_SYS_RT_COMMON, UMP_MIDI_STATUS(x) may be one of: + * @{ + */ +#define UMP_SYS_MIDI_TIME_CODE 0xf1 /**< MIDI Time Code (no param) */ +#define UMP_SYS_SONG_POSITION 0xf2 /**< Song Position Pointer (p1=lsb, p2=msb) */ +#define UMP_SYS_SONG_SELECT 0xf3 /**< Song Select (p1=song number) */ +#define UMP_SYS_TUNE_REQUEST 0xf6 /**< Tune Request (no param) */ +#define UMP_SYS_TIMING_CLOCK 0xf8 /**< Timing Clock (no param) */ +#define UMP_SYS_START 0xfa /**< Start (no param) */ +#define UMP_SYS_CONTINUE 0xfb /**< Continue (no param) */ +#define UMP_SYS_STOP 0xfc /**< Stop (no param) */ +#define UMP_SYS_ACTIVE_SENSING 0xfe /**< Active sensing (no param) */ +#define UMP_SYS_RESET 0xff /**< Reset (no param) */ +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 38356a175271b..9a97321bafa4c 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -47,13 +47,16 @@ extern "C" { #define BT_BAP_BASS_MAX_SUBGROUPS 0 #endif /* CONFIG_BT_BAP_BASS_MAX_SUBGROUPS*/ +/** Maximum size of BASE excluding service data header */ +#define BT_BASE_MAX_SIZE (UINT8_MAX - 1 /* type */ - BT_UUID_SIZE_16) + /** An invalid Broadcast ID */ #define BT_BAP_INVALID_BROADCAST_ID 0xFFFFFFFFU /** * @brief Check if a BAP BASS BIS_Sync bitfield is valid * - * Valid options are eiter a bitmask of valid BIS indices, including none (0x00000000) + * Valid options are either a bitmask of valid BIS indices, including none (0x00000000) * or @ref BT_BAP_BIS_SYNC_NO_PREF (0xFFFFFFFF). * * @param _bis_bitfield BIS_Sync bitfield (uint32) @@ -2001,6 +2004,53 @@ int bt_bap_base_subgroup_bis_codec_to_codec_cfg(const struct bt_bap_base_subgrou * @{ */ +/** + * @brief Struct to hold the Broadcast Source callbacks + * + * These can be registered for usage with bt_bap_broadcast_source_register_cb(). + */ +struct bt_bap_broadcast_source_cb { + /** + * @brief The Broadcast Source has started and all of the streams are ready for audio data + * + * @param source The started Broadcast Source + */ + void (*started)(struct bt_bap_broadcast_source *source); + + /** + * @brief The Broadcast Source has stopped and none of the streams are ready for audio data + * + * @param source The stopped Broadcast Source + * @param reason The reason why the Broadcast Source stopped (see the BT_HCI_ERR_* values) + */ + void (*stopped)(struct bt_bap_broadcast_source *source, uint8_t reason); + + /** @internal Internally used field for list handling */ + sys_snode_t _node; +}; + +/** + * @brief Registers callbacks for Broadcast Sources + * + * @param cb Pointer to the callback structure. + * + * @retval 0 on success + * @retval -EINVAL if @p cb is NULL + * @retval -EEXIST if @p cb is already registered + */ +int bt_bap_broadcast_source_register_cb(struct bt_bap_broadcast_source_cb *cb); + +/** + * @brief Unregisters callbacks for Broadcast Sources + * + * @param cb Pointer to the callback structure. + * + * @retval 0 on success + * @retval -EINVAL if @p cb is NULL + * @retval -ENOENT if @p cb is not registered + */ +int bt_bap_broadcast_source_unregister_cb(struct bt_bap_broadcast_source_cb *cb); + /** Broadcast Source stream parameters */ struct bt_bap_broadcast_source_stream_param { /** Audio stream */ @@ -2245,6 +2295,22 @@ struct bt_bap_broadcast_sink_cb { */ void (*syncable)(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo); + /** + * @brief The Broadcast Sink has started and audio data may be received from all of the + * streams + * + * @param sink The started Broadcast Sink + */ + void (*started)(struct bt_bap_broadcast_sink *sink); + + /** + * @brief The Broadcast Sink has stopped and none of the streams will receive audio data + * + * @param sink The stopped Broadcast Sink + * @param reason The reason why the Broadcast Sink stopped (see the BT_HCI_ERR_* values) + */ + void (*stopped)(struct bt_bap_broadcast_sink *sink, uint8_t reason); + /** @internal Internally used list node */ sys_snode_t _node; }; @@ -2255,11 +2321,12 @@ struct bt_bap_broadcast_sink_cb { * It is possible to register multiple struct of callbacks, but a single struct can only be * registered once. * Registering the same callback multiple times is undefined behavior and may break the stack. - * + * @param cb Broadcast sink callback structure. * - * @retval 0 in case of success + * @retval 0 on success * @retval -EINVAL if @p cb is NULL + * @retval -EALREADY if @p cb was already registered */ int bt_bap_broadcast_sink_register_cb(struct bt_bap_broadcast_sink_cb *cb); diff --git a/include/zephyr/bluetooth/audio/cap.h b/include/zephyr/bluetooth/audio/cap.h index 34b5b0f3e1cc0..b539a463c2689 100644 --- a/include/zephyr/bluetooth/audio/cap.h +++ b/include/zephyr/bluetooth/audio/cap.h @@ -128,6 +128,22 @@ struct bt_cap_initiator_cb { */ void (*unicast_stop_complete)(int err, struct bt_conn *conn); #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */ +#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) + /** + * @brief The Broadcast Source has started and all of the streams are ready for audio data + * + * @param source The started Broadcast Source + */ + void (*broadcast_started)(struct bt_cap_broadcast_source *source); + + /** + * @brief The Broadcast Source has stopped and none of the streams are ready for audio data + * + * @param source The stopped Broadcast Source + * @param reason The reason why the Broadcast Source stopped (see the BT_HCI_ERR_* values) + */ + void (*broadcast_stopped)(struct bt_cap_broadcast_source *source, uint8_t reason); +#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */ }; /** diff --git a/include/zephyr/bluetooth/audio/ccp.h b/include/zephyr/bluetooth/audio/ccp.h new file mode 100644 index 0000000000000..81965a9130402 --- /dev/null +++ b/include/zephyr/bluetooth/audio/ccp.h @@ -0,0 +1,199 @@ +/** + * @file + * @brief Bluetooth Call Control Profile (CCP) APIs. + */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_CCP_H_ +#define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_CCP_H_ + +/** + * @brief Call Control Profile (CCP) + * + * @defgroup bt_ccp Call Control Profile (CCP) + * + * @since 3.7 + * @version 0.1.0 + * + * @ingroup bluetooth + * @{ + * + * Call Control Profile (CCP) provides procedures to initiate and control calls. + * It provides the Call Control Client and the Call Control Server roles, + * where the former is usually placed on resource constrained devices like headphones, + * and the latter placed on more powerful devices like phones and PCs. + * + * The profile is not limited to carrier phone calls and can be used with common applications like + * Discord and Teams. + */ +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @defgroup bt_ccp_call_control_server CCP Call Control Server APIs + * @ingroup bt_ccp + * @{ + */ +/** @brief Abstract Call Control Server Telephone Bearer structure. */ +struct bt_ccp_call_control_server_bearer; + +/** + * @brief Register a Telephone Bearer + * + * This will register a Telephone Bearer Service (TBS) (or a Generic Telephone Bearer service + * (GTBS)) with the provided parameters. + * + * As per the TBS specification, the GTBS shall be instantiated for the feature, + * and as such a GTBS shall always be registered before any TBS can be registered. + * Similarly, all TBS shall be unregistered before the GTBS can be unregistered with + * bt_ccp_call_control_server_unregister_bearer(). + * + * @param[in] param The parameters to initialize the bearer. + * @param[out] bearer Pointer to the initialized bearer. + * + * @retval 0 Success + * @retval -EINVAL @p param contains invalid data + * @retval -EALREADY @p param.gtbs is true and GTBS has already been registered + * @retval -EAGAIN @p param.gtbs is false and GTBS has not been registered + * @retval -ENOMEM @p param.gtbs is false and no more TBS can be registered (see + * @kconfig{CONFIG_BT_TBS_BEARER_COUNT}) + * @retval -ENOEXEC The service failed to be registered + */ +int bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_param *param, + struct bt_ccp_call_control_server_bearer **bearer); + +/** + * @brief Unregister a Telephone Bearer + * + * This will unregister a Telephone Bearer Service (TBS) (or a Generic Telephone Bearer service + * (GTBS)) with the provided parameters. The bearer shall be registered first by + * bt_ccp_call_control_server_register_bearer() before it can be unregistered. + * + * All TBS shall be unregistered before the GTBS can be unregistered with. + * + * @param bearer The bearer to unregister. + * + * @retval 0 Success + * @retval -EINVAL @p bearer is NULL + * @retval -EALREADY The bearer is not registered + * @retval -ENOEXEC The service failed to be unregistered + */ +int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_server_bearer *bearer); + +/** @} */ /* End of group bt_ccp_call_control_server */ + +/** + * @defgroup bt_ccp_call_control_client CCP Call Control Client APIs + * @ingroup bt_ccp + * @{ + */ +/** Abstract Call Control Client structure. */ +struct bt_ccp_call_control_client; + +/** Abstract Call Control Client bearer structure. */ +struct bt_ccp_call_control_client_bearer; + +/** Struct with information about bearers of a client */ +struct bt_ccp_call_control_client_bearers { +#if defined(CONFIG_BT_TBS_CLIENT_GTBS) + /** The GTBS bearer. */ + struct bt_ccp_call_control_client_bearer *gtbs_bearer; +#endif /* CONFIG_BT_TBS_CLIENT_GTBS */ + +#if defined(CONFIG_BT_TBS_CLIENT_TBS) + /** Number of TBS bearers in @p tbs_bearers */ + size_t tbs_count; + + /** Array of pointers of TBS bearers */ + struct bt_ccp_call_control_client_bearer + *tbs_bearers[CONFIG_BT_CCP_CALL_CONTROL_CLIENT_BEARER_COUNT]; +#endif /* CONFIG_BT_TBS_CLIENT_TBS */ +}; + +/** + * @brief Struct to hold the Telephone Bearer Service client callbacks + * + * These can be registered for usage with bt_tbs_client_register_cb(). + */ +struct bt_ccp_call_control_client_cb { + /** + * @brief Callback function for bt_ccp_call_control_client_discover(). + * + * This callback is called once the discovery procedure is completed. + * + * @param client Call Control Client pointer. + * @param err Error value. 0 on success, GATT error on positive + * value or errno on negative value. + * @param bearers The bearers found. + */ + void (*discover)(struct bt_ccp_call_control_client *client, int err, + struct bt_ccp_call_control_client_bearers *bearers); + + /** @internal Internally used field for list handling */ + sys_snode_t _node; +}; + +/** + * @brief Discovers the Telephone Bearer Service (TBS) support on a remote device. + * + * This will discover the Telephone Bearer Service (TBS) and Generic Telephone Bearer Service (GTBS) + * on the remote device. + * + * @kconfig_dep{CONFIG_BT_CCP_CALL_CONTROL_CLIENT}. + * + * @param conn Connection to a remote server. + * @param out_client Pointer to client instance on success + * + * @retval 0 Success + * @retval -EINVAL @p conn or @p out_client is NULL + * @retval -ENOTCONN @p conn is not connected + * @retval -ENOMEM Could not allocated memory for the request + * @retval -EBUSY Already doing discovery for @p conn + * @retval -ENOEXEC Rejected by the GATT layer + */ +int bt_ccp_call_control_client_discover(struct bt_conn *conn, + struct bt_ccp_call_control_client **out_client); + +/** + * @brief Register callbacks for the Call Control Client + * + * @param cb The callback struct + * + * @retval 0 Succsss + * @retval -EINVAL @p cb is NULL + * @retval -EEXISTS @p cb is already registered + */ +int bt_ccp_call_control_client_register_cb(struct bt_ccp_call_control_client_cb *cb); + +/** + * @brief Unregister callbacks for the Call Control Client + * + * @param cb The callback struct + * + * @retval 0 Succsss + * @retval -EINVAL @p cb is NULL + * @retval -EALREADY @p cb is not registered + */ +int bt_ccp_call_control_client_unregister_cb(struct bt_ccp_call_control_client_cb *cb); +/** @} */ /* End of group bt_ccp_call_control_client */ +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_CCP_H_ */ diff --git a/include/zephyr/bluetooth/audio/gmap_lc3_preset.h b/include/zephyr/bluetooth/audio/gmap_lc3_preset.h index 73217d9d18db7..f1fab5d74bfcb 100644 --- a/include/zephyr/bluetooth/audio/gmap_lc3_preset.h +++ b/include/zephyr/bluetooth/audio/gmap_lc3_preset.h @@ -26,6 +26,7 @@ */ #include +#include #include #include diff --git a/include/zephyr/bluetooth/audio/pacs.h b/include/zephyr/bluetooth/audio/pacs.h index e956e0da7f472..1c896081ac7a0 100644 --- a/include/zephyr/bluetooth/audio/pacs.h +++ b/include/zephyr/bluetooth/audio/pacs.h @@ -45,6 +45,43 @@ struct bt_pacs_cap { sys_snode_t _node; }; +/** Structure for registering PACS */ +struct bt_pacs_register_param { +#if defined(CONFIG_BT_PAC_SNK) || defined(__DOXYGEN__) + /** + * @brief Enables or disables registration of Sink PAC Characteristic. + */ + bool snk_pac; +#endif /* CONFIG_BT_PAC_SNK */ + +#if defined(CONFIG_BT_PAC_SNK_LOC) || defined(__DOXYGEN__) + /** + * @brief Enables or disables registration of Sink Location Characteristic. + * + * Registration of Sink Location is dependent on @ref bt_pacs_register_param.snk_pac + * also being set. + */ + bool snk_loc; +#endif /* CONFIG_BT_PAC_SNK_LOC */ + +#if defined(CONFIG_BT_PAC_SRC) || defined(__DOXYGEN__) + /** + * @brief Enables or disables registration of Source PAC Characteristic. + */ + bool src_pac; +#endif /* CONFIG_BT_PAC_SRC */ + +#if defined(CONFIG_BT_PAC_SRC_LOC) || defined(__DOXYGEN__) + /** + * @brief Enables or disables registration of Source Location Characteristic. + * + * Registration of Source Location is dependent on @ref bt_pacs_register_param.src_pac + * also being set. + */ + bool src_loc; +#endif /* CONFIG_BT_PAC_SRC_LOC */ +}; + /** * @typedef bt_pacs_cap_foreach_func_t * @brief Published Audio Capability iterator callback. @@ -71,6 +108,25 @@ void bt_pacs_cap_foreach(enum bt_audio_dir dir, bt_pacs_cap_foreach_func_t func, void *user_data); +/** + * @brief Register the Published Audio Capability Service instance. + * + * @param param PACS register parameters. + * + * @retval 0 Success + * @retval -EINVAL @p param is NULL or bad combination of values in @p param + * @retval -EALREADY Already registered + * @retval -ENOEXEC Request was rejected by GATT + */ +int bt_pacs_register(const struct bt_pacs_register_param *param); + +/** + * @brief Unregister the Published Audio Capability Service instance. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_pacs_unregister(void); + /** * @brief Register Published Audio Capability. * diff --git a/include/zephyr/bluetooth/audio/pbp.h b/include/zephyr/bluetooth/audio/pbp.h index db649e523abdd..3391a52a28dfb 100644 --- a/include/zephyr/bluetooth/audio/pbp.h +++ b/include/zephyr/bluetooth/audio/pbp.h @@ -26,6 +26,8 @@ * The Public Broadcast Profile (PBP) is used for public broadcasts by providing additional * information in the advertising data. */ +#include +#include #include #include diff --git a/include/zephyr/bluetooth/audio/tmap.h b/include/zephyr/bluetooth/audio/tmap.h index ad16aead2da9d..885ae27bea3bb 100644 --- a/include/zephyr/bluetooth/audio/tmap.h +++ b/include/zephyr/bluetooth/audio/tmap.h @@ -3,7 +3,7 @@ * @brief Header for Bluetooth TMAP. * * Copyright 2023 NXP - * Copyright (c) 2024 Nordic Semiconductor ASA + * Copyright (c) 2024-2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,37 +31,6 @@ #include #include -/** Call Gateway (CG) supported */ -#define BT_TMAP_CG_SUPPORTED \ - (IS_ENABLED(CONFIG_BT_CAP_INITIATOR) && IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && \ - IS_ENABLED(CONFIG_BT_TBS) && IS_ENABLED(CONFIG_BT_VCP_VOL_CTLR)) - -/** Call Terminal (CT) supported */ -#define BT_TMAP_CT_SUPPORTED \ - (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR) && IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER) && \ - IS_ENABLED(CONFIG_BT_TBS_CLIENT) && \ - (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK) && \ - IS_ENABLED(CONFIG_BT_VCP_VOL_REND) == IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK))) - -/** Unicast Media Sender (UMS) supported */ -#define BT_TMAP_UMS_SUPPORTED \ - (IS_ENABLED(CONFIG_BT_CAP_INITIATOR) && \ - IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK) && IS_ENABLED(CONFIG_BT_VCP_VOL_CTLR) && \ - IS_ENABLED(CONFIG_BT_MCS)) - -/** Unicast Media Receiver (UMR) supported */ -#define BT_TMAP_UMR_SUPPORTED \ - (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR) && IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK) && \ - IS_ENABLED(CONFIG_BT_VCP_VOL_REND)) - -/** Broadcast Media Sender (BMS) supported */ -#define BT_TMAP_BMS_SUPPORTED \ - (IS_ENABLED(CONFIG_BT_CAP_INITIATOR) && IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SOURCE)) - -/** Broadcast Media Receiver (BMR) supported */ -#define BT_TMAP_BMR_SUPPORTED \ - (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR) && IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SINK)) - /** @brief TMAP Role characteristic */ enum bt_tmap_role { /** diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 8d2ceebf6cb6d..d1618f98a3a2c 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -268,7 +268,7 @@ bool bt_is_ready(void); * * @sa @kconfig{CONFIG_BT_DEVICE_NAME_MAX}. * - * @param name New name + * @param name New name, must be null terminated * * @return Zero on success or (negative) error code otherwise. */ @@ -784,6 +784,40 @@ enum { * @note Mutually exclusive with BT_LE_ADV_OPT_USE_IDENTITY. */ BT_LE_ADV_OPT_USE_NRPA = BIT(19), + + /** + * @brief Configures the advertiser to use the S=2 coding scheme for + * LE Coded PHY. + * + * Sets the advertiser's required coding scheme to S=2, which is one + * of the coding options available for LE Coded PHY. The S=2 coding + * scheme offers higher data rates compared to S=8, with a trade-off + * of reduced range. The coding scheme will only be set if both the + * primary and secondary advertising channels indicate LE Coded Phy. + * Additionally, the Controller must support the LE Feature Advertising + * Coding Selection. If these conditions are not met, it will default to + * no required coding scheme. + * + * @note Requires @kconfig{BT_EXT_ADV_CODING_SELECTION} + */ + BT_LE_ADV_OPT_REQUIRE_S2_CODING = BIT(20), + + /** + * @brief Configures the advertiser to use the S=8 coding scheme for + * LE Coded PHY. + * + * Sets the advertiser's required coding scheme to S=8, which is one + * of the coding options available for LE Coded PHY. The S=8 coding + * scheme offers increased range compared to S=2, with a trade-off + * of lower data rates. The coding scheme will only be set if both the + * primary and secondary advertising channels indicate LE Coded Phy. + * Additionally, the Controller must support the LE Feature Advertising + * Coding Selection. If these conditions are not met, it will default to + * no required coding scheme. + * + * @note Requires @kconfig{BT_EXT_ADV_CODING_SELECTION} + */ + BT_LE_ADV_OPT_REQUIRE_S8_CODING = BIT(21), }; /** LE Advertising Parameters. */ diff --git a/include/zephyr/bluetooth/buf.h b/include/zephyr/bluetooth/buf.h index c5ad4ddf9a8fa..dd452342ef724 100644 --- a/include/zephyr/bluetooth/buf.h +++ b/include/zephyr/bluetooth/buf.h @@ -28,22 +28,22 @@ extern "C" { #endif -/** Possible types of buffers passed around the Bluetooth stack */ +/** Possible types of buffers passed around the Bluetooth stack in a form of bitmask. */ enum bt_buf_type { /** HCI command */ - BT_BUF_CMD, + BT_BUF_CMD = BIT(0), /** HCI event */ - BT_BUF_EVT, + BT_BUF_EVT = BIT(1), /** Outgoing ACL data */ - BT_BUF_ACL_OUT, + BT_BUF_ACL_OUT = BIT(2), /** Incoming ACL data */ - BT_BUF_ACL_IN, + BT_BUF_ACL_IN = BIT(3), /** Outgoing ISO data */ - BT_BUF_ISO_OUT, + BT_BUF_ISO_OUT = BIT(4), /** Incoming ISO data */ - BT_BUF_ISO_IN, + BT_BUF_ISO_IN = BIT(5), /** H:4 data */ - BT_BUF_H4, + BT_BUF_H4 = BIT(6), }; /** @brief This is a base type for bt_buf user data. */ @@ -138,6 +138,27 @@ BUILD_ASSERT(BT_BUF_ACL_RX_COUNT <= BT_BUF_ACL_RX_COUNT_MAX, */ struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout); +/** A callback to notify about freed buffer in the incoming data pool. + * + * This callback is called when a buffer of a given type is freed and can be requested through the + * @ref bt_buf_get_rx function. However, this callback is called from the context of the buffer + * freeing operation and must not attempt to allocate a new buffer from the same pool. + * + * @warning When this callback is called, the scheduler is locked and the callee must not perform + * any action that makes the current thread unready. This callback must only be used for very + * short non-blocking operation (e.g. submitting a work item). + * + * @param type_mask A bit mask of buffer types that have been freed. + */ +typedef void (*bt_buf_rx_freed_cb_t)(enum bt_buf_type type_mask); + +/** Set the callback to notify about freed buffer in the incoming data pool. + * + * @param cb Callback to notify about freed buffer in the incoming data pool. If NULL, the callback + * is disabled. + */ +void bt_buf_rx_freed_cb_set(bt_buf_rx_freed_cb_t cb); + /** Allocate a buffer for outgoing data * * This will set the buffer type so bt_buf_set_type() does not need to diff --git a/include/zephyr/bluetooth/classic/a2dp.h b/include/zephyr/bluetooth/classic/a2dp.h index ae276caa8d03a..95b1899cebc92 100644 --- a/include/zephyr/bluetooth/classic/a2dp.h +++ b/include/zephyr/bluetooth/classic/a2dp.h @@ -21,43 +21,42 @@ extern "C" { #endif -#define BT_A2DP_STREAM_BUF_RESERVE (12u + BT_L2CAP_BUF_SIZE(0)) +#define BT_A2DP_STREAM_BUF_RESERVE (12U + BT_L2CAP_BUF_SIZE(0)) /** SBC IE length */ -#define BT_A2DP_SBC_IE_LENGTH (4u) +#define BT_A2DP_SBC_IE_LENGTH (4U) /** MPEG1,2 IE length */ -#define BT_A2DP_MPEG_1_2_IE_LENGTH (4u) +#define BT_A2DP_MPEG_1_2_IE_LENGTH (4U) /** MPEG2,4 IE length */ -#define BT_A2DP_MPEG_2_4_IE_LENGTH (6u) +#define BT_A2DP_MPEG_2_4_IE_LENGTH (6U) /** The max IE (Codec Info Element) length */ -#define A2DP_MAX_IE_LENGTH (8U) +#define BT_A2DP_MAX_IE_LENGTH (8U) /** @brief define the audio endpoint * @param _role BT_AVDTP_SOURCE or BT_AVDTP_SINK. * @param _codec value of enum bt_a2dp_codec_id. * @param _capability the codec capability. */ -#define BT_A2DP_EP_INIT(_role, _codec, _capability)\ -{\ - .codec_type = _codec,\ - .sep = {.sep_info = {.media_type = BT_AVDTP_AUDIO, .tsep = _role}},\ - .codec_cap = _capability,\ - .stream = NULL,\ -} +#define BT_A2DP_EP_INIT(_role, _codec, _capability) \ + { \ + .codec_type = _codec, \ + .sep = {.sep_info = {.media_type = BT_AVDTP_AUDIO, .tsep = _role}}, \ + .codec_cap = _capability, .stream = NULL, \ + } /** @brief define the audio sink endpoint * @param _codec value of enum bt_a2dp_codec_id. * @param _capability the codec capability. */ -#define BT_A2DP_SINK_EP_INIT(_codec, _capability)\ -BT_A2DP_EP_INIT(BT_AVDTP_SINK, _codec, _capability) +#define BT_A2DP_SINK_EP_INIT(_codec, _capability) \ + BT_A2DP_EP_INIT(BT_AVDTP_SINK, _codec, _capability) /** @brief define the audio source endpoint * @param _codec value of enum bt_a2dp_codec_id. * @param _capability the codec capability. */ -#define BT_A2DP_SOURCE_EP_INIT(_codec, _capability)\ -BT_A2DP_EP_INIT(BT_AVDTP_SOURCE, _codec, _capability) +#define BT_A2DP_SOURCE_EP_INIT(_codec, _capability) \ + BT_A2DP_EP_INIT(BT_AVDTP_SOURCE, _codec, _capability) /** @brief define the SBC sink endpoint that can be used as * bt_a2dp_register_endpoint's parameter. @@ -80,13 +79,14 @@ BT_A2DP_EP_INIT(BT_AVDTP_SOURCE, _codec, _capability) * @param _max_bitpool sbc codec max bit pool. for example: 35 * @ */ -#define BT_A2DP_SBC_SINK_EP(_name, _freq, _ch_mode, _blk_len, _subband,\ -_alloc_mthd, _min_bitpool, _max_bitpool)\ -static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name =\ -{.len = BT_A2DP_SBC_IE_LENGTH, .codec_ie = {_freq | _ch_mode,\ -_blk_len | _subband | _alloc_mthd, _min_bitpool, _max_bitpool}};\ -static struct bt_a2dp_ep _name = BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC,\ -(&bt_a2dp_ep_cap_ie##_name)) +#define BT_A2DP_SBC_SINK_EP(_name, _freq, _ch_mode, _blk_len, _subband, _alloc_mthd, _min_bitpool, \ + _max_bitpool) \ + static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = { \ + .len = BT_A2DP_SBC_IE_LENGTH, \ + .codec_ie = {_freq | _ch_mode, _blk_len | _subband | _alloc_mthd, _min_bitpool, \ + _max_bitpool}}; \ + static struct bt_a2dp_ep _name = \ + BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC, (&bt_a2dp_ep_cap_ie##_name)) /** @brief define the SBC source endpoint that can be used as bt_a2dp_register_endpoint's * parameter. @@ -108,13 +108,14 @@ static struct bt_a2dp_ep _name = BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC,\ * @param _min_bitpool sbc codec min bit pool. for example: 18 * @param _max_bitpool sbc codec max bit pool. for example: 35 */ -#define BT_A2DP_SBC_SOURCE_EP(_name, _freq, _ch_mode, _blk_len, _subband,\ -_alloc_mthd, _min_bitpool, _max_bitpool)\ -static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name =\ -{.len = BT_A2DP_SBC_IE_LENGTH, .codec_ie = {_freq | _ch_mode,\ -_blk_len | _subband | _alloc_mthd, _min_bitpool, _max_bitpool}};\ -static struct bt_a2dp_ep _name = BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC,\ -&bt_a2dp_ep_cap_ie##_name) +#define BT_A2DP_SBC_SOURCE_EP(_name, _freq, _ch_mode, _blk_len, _subband, _alloc_mthd, \ + _min_bitpool, _max_bitpool) \ + static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = { \ + .len = BT_A2DP_SBC_IE_LENGTH, \ + .codec_ie = {_freq | _ch_mode, _blk_len | _subband | _alloc_mthd, _min_bitpool, \ + _max_bitpool}}; \ + static struct bt_a2dp_ep _name = \ + BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name) /** @brief define the default SBC sink endpoint that can be used as * bt_a2dp_register_endpoint's parameter. @@ -124,14 +125,17 @@ static struct bt_a2dp_ep _name = BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC,\ * * @param _name the endpoint variable name. */ -#define BT_A2DP_SBC_SINK_EP_DEFAULT(_name)\ -static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name =\ -{.len = BT_A2DP_SBC_IE_LENGTH, .codec_ie = {A2DP_SBC_SAMP_FREQ_44100 |\ -A2DP_SBC_SAMP_FREQ_48000 | A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO |\ -A2DP_SBC_CH_MODE_JOINT, A2DP_SBC_BLK_LEN_16 |\ -A2DP_SBC_SUBBAND_8 | A2DP_SBC_ALLOC_MTHD_LOUDNESS, 18U, 35U}};\ -static struct bt_a2dp_ep _name = BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC,\ -&bt_a2dp_ep_cap_ie##_name) +#define BT_A2DP_SBC_SINK_EP_DEFAULT(_name) \ + static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = { \ + .len = BT_A2DP_SBC_IE_LENGTH, \ + .codec_ie = {A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000 | \ + A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO | \ + A2DP_SBC_CH_MODE_JOINT, \ + A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 | \ + A2DP_SBC_ALLOC_MTHD_LOUDNESS, \ + 18U, 35U}}; \ + static struct bt_a2dp_ep _name = \ + BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name) /** @brief define the default SBC source endpoint that can be used as bt_a2dp_register_endpoint's * parameter. @@ -141,14 +145,18 @@ static struct bt_a2dp_ep _name = BT_A2DP_SINK_EP_INIT(BT_A2DP_SBC,\ * * @param _name the endpoint variable name. */ -#define BT_A2DP_SBC_SOURCE_EP_DEFAULT(_name)\ -static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name =\ -{.len = BT_A2DP_SBC_IE_LENGTH, .codec_ie = {A2DP_SBC_SAMP_FREQ_44100 | \ -A2DP_SBC_SAMP_FREQ_48000 | A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO | \ -A2DP_SBC_CH_MODE_JOINT, A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 | A2DP_SBC_ALLOC_MTHD_LOUDNESS,\ -18U, 35U},};\ -static struct bt_a2dp_ep _name = BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC,\ -&bt_a2dp_ep_cap_ie##_name) +#define BT_A2DP_SBC_SOURCE_EP_DEFAULT(_name) \ + static struct bt_a2dp_codec_ie bt_a2dp_ep_cap_ie##_name = { \ + .len = BT_A2DP_SBC_IE_LENGTH, \ + .codec_ie = {A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_48000 | \ + A2DP_SBC_CH_MODE_MONO | A2DP_SBC_CH_MODE_STREO | \ + A2DP_SBC_CH_MODE_JOINT, \ + A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 | \ + A2DP_SBC_ALLOC_MTHD_LOUDNESS, \ + 18U, 35U}, \ + }; \ + static struct bt_a2dp_ep _name = \ + BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC, &bt_a2dp_ep_cap_ie##_name) /** @brief define the SBC default configuration. * @@ -166,23 +174,34 @@ static struct bt_a2dp_ep _name = BT_A2DP_SOURCE_EP_INIT(BT_A2DP_SBC,\ * @param _min_bitpool_cfg sbc codec min bit pool. for example: 18 * @param _max_bitpool_cfg sbc codec max bit pool. for example: 35 */ -#define BT_A2DP_SBC_EP_CFG(_name, _freq_cfg, _ch_mode_cfg, _blk_len_cfg, _subband_cfg,\ -_alloc_mthd_cfg, _min_bitpool_cfg, _max_bitpool_cfg)\ -static struct bt_a2dp_codec_ie bt_a2dp_codec_ie##_name = {\ -.len = BT_A2DP_SBC_IE_LENGTH, .codec_ie = {_freq_cfg | _ch_mode_cfg,\ -_blk_len_cfg | _subband_cfg | _alloc_mthd_cfg, _min_bitpool_cfg, _max_bitpool_cfg},};\ -struct bt_a2dp_codec_cfg _name = {.codec_config = &bt_a2dp_codec_ie##_name,} +#define BT_A2DP_SBC_EP_CFG(_name, _freq_cfg, _ch_mode_cfg, _blk_len_cfg, _subband_cfg, \ + _alloc_mthd_cfg, _min_bitpool_cfg, _max_bitpool_cfg) \ + static struct bt_a2dp_codec_ie bt_a2dp_codec_ie##_name = { \ + .len = BT_A2DP_SBC_IE_LENGTH, \ + .codec_ie = {_freq_cfg | _ch_mode_cfg, \ + _blk_len_cfg | _subband_cfg | _alloc_mthd_cfg, _min_bitpool_cfg, \ + _max_bitpool_cfg}, \ + }; \ + struct bt_a2dp_codec_cfg _name = { \ + .codec_config = &bt_a2dp_codec_ie##_name, \ + } /** @brief define the SBC default configuration. * * @param _name unique structure name postfix. * @param _freq_cfg the frequency to configure the remote same codec type endpoint. */ -#define BT_A2DP_SBC_EP_CFG_DEFAULT(_name, _freq_cfg)\ -static struct bt_a2dp_codec_ie bt_a2dp_codec_ie##_name = {\ -.len = BT_A2DP_SBC_IE_LENGTH, .codec_ie = {_freq_cfg | A2DP_SBC_CH_MODE_JOINT,\ -A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 | A2DP_SBC_ALLOC_MTHD_LOUDNESS, 18U, 35U},};\ -struct bt_a2dp_codec_cfg _name = {.codec_config = &bt_a2dp_codec_ie##_name,} +#define BT_A2DP_SBC_EP_CFG_DEFAULT(_name, _freq_cfg) \ + static struct bt_a2dp_codec_ie bt_a2dp_codec_ie##_name = { \ + .len = BT_A2DP_SBC_IE_LENGTH, \ + .codec_ie = {_freq_cfg | A2DP_SBC_CH_MODE_JOINT, \ + A2DP_SBC_BLK_LEN_16 | A2DP_SBC_SUBBAND_8 | \ + A2DP_SBC_ALLOC_MTHD_LOUDNESS, \ + 18U, 35U}, \ + }; \ + struct bt_a2dp_codec_cfg _name = { \ + .codec_config = &bt_a2dp_codec_ie##_name, \ + } /** * @brief A2DP error code @@ -295,7 +314,7 @@ struct bt_a2dp_codec_ie { /** Length of codec_cap */ uint8_t len; /** codec information element */ - uint8_t codec_ie[A2DP_MAX_IE_LENGTH]; + uint8_t codec_ie[BT_A2DP_MAX_IE_LENGTH]; }; /** @brief The endpoint configuration */ @@ -358,8 +377,8 @@ enum { * for next endpoint. By returning BT_A2DP_DISCOVER_EP_STOP user allows this * discovery continuation. */ -typedef uint8_t (*bt_a2dp_discover_ep_cb)(struct bt_a2dp *a2dp, - struct bt_a2dp_ep_info *info, struct bt_a2dp_ep **ep); +typedef uint8_t (*bt_a2dp_discover_ep_cb)(struct bt_a2dp *a2dp, struct bt_a2dp_ep_info *info, + struct bt_a2dp_ep **ep); struct bt_a2dp_discover_param { /** discover callback */ @@ -411,9 +430,23 @@ struct bt_a2dp_cb { * @return 0 in case of success or negative value in case of error. */ int (*config_req)(struct bt_a2dp *a2dp, struct bt_a2dp_ep *ep, - struct bt_a2dp_codec_cfg *codec_cfg, struct bt_a2dp_stream **stream, - uint8_t *rsp_err_code); - /** @brief Callback function for bt_a2dp_stream_config() + struct bt_a2dp_codec_cfg *codec_cfg, struct bt_a2dp_stream **stream, + uint8_t *rsp_err_code); + /** + * @brief Endpoint config request callback + * + * The callback is called whenever an endpoint is requested to be + * reconfigured. + * + * @param[in] stream Pointer to stream object. + * @param[out] rsp_err_code give the error code if response error. + * bt_a2dp_err_code or bt_avdtp_err_code + * + * @return 0 in case of success or negative value in case of error. + */ + int (*reconfig_req)(struct bt_a2dp_stream *stream, struct bt_a2dp_codec_cfg *codec_cfg, + uint8_t *rsp_err_code); + /** @brief Callback function for bt_a2dp_stream_config() and bt_a2dp_stream_reconfig() * * Called when the codec configure operation is completed. * @@ -423,7 +456,7 @@ struct bt_a2dp_cb { */ void (*config_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** - * @brief stream establishment request callback + * @brief Stream establishment request callback * * The callback is called whenever an stream is requested to be * established (open cmd and create the stream l2cap channel). @@ -446,7 +479,7 @@ struct bt_a2dp_cb { */ void (*establish_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** - * @brief stream release request callback + * @brief Stream release request callback * * The callback is called whenever an stream is requested to be * released (release cmd and release the l2cap channel) @@ -469,7 +502,7 @@ struct bt_a2dp_cb { */ void (*release_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** - * @brief stream start request callback + * @brief Stream start request callback * * The callback is called whenever an stream is requested to be * started. @@ -491,7 +524,7 @@ struct bt_a2dp_cb { */ void (*start_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** - * @brief Endpoint suspend request callback + * @brief Stream suspend request callback * * The callback is called whenever an stream is requested to be * suspended. @@ -513,10 +546,10 @@ struct bt_a2dp_cb { */ void (*suspend_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); /** - * @brief Endpoint config request callback + * @brief Stream abort request callback * - * The callback is called whenever an endpoint is requested to be - * reconfigured. + * The callback is called whenever an stream is requested to be + * aborted. * * @param[in] stream Pointer to stream object. * @param[out] rsp_err_code give the error code if response error. @@ -524,16 +557,16 @@ struct bt_a2dp_cb { * * @return 0 in case of success or negative value in case of error. */ - int (*reconfig_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code); - /** @brief Callback function for bt_a2dp_stream_reconfig() + int (*abort_req)(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code); + /** @brief Callback function for bt_a2dp_stream_abort() * - * Called when the reconfig operation is completed. + * Called when the abort operation is completed. * * @param[in] stream Pointer to stream object. * @param[in] rsp_err_code the remote responded error code * bt_a2dp_err_code or bt_avdtp_err_code */ - void (*reconfig_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); + void (*abort_rsp)(struct bt_a2dp_stream *stream, uint8_t rsp_err_code); }; /** @brief A2DP Connect. @@ -566,12 +599,12 @@ int bt_a2dp_disconnect(struct bt_a2dp *a2dp); /** @brief Endpoint Registration. * * @param ep Pointer to bt_a2dp_ep structure. - * @param media_type Media type that the Endpoint is. - * @param role Role of Endpoint. + * @param media_type Media type that the Endpoint is, #bt_avdtp_media_type. + * @param sep_type Stream endpoint type, #bt_avdtp_sep_type. * * @return 0 in case of success and error code in case of error. */ -int bt_a2dp_register_ep(struct bt_a2dp_ep *ep, uint8_t media_type, uint8_t role); +int bt_a2dp_register_ep(struct bt_a2dp_ep *ep, uint8_t media_type, uint8_t sep_type); /** @brief register callback. * @@ -613,7 +646,7 @@ struct bt_a2dp_stream_ops { /** * @brief Stream configured callback * - * The callback is called whenever an Audio Stream has been configured. + * The callback is called whenever an Audio Stream has been configured or reconfigured. * * @param stream Stream object that has been configured. */ @@ -630,6 +663,7 @@ struct bt_a2dp_stream_ops { * @brief Stream release callback * * The callback is called whenever an Audio Stream has been released. + * After released, the stream becomes invalid. * * @param stream Stream object that has been released. */ @@ -651,13 +685,14 @@ struct bt_a2dp_stream_ops { */ void (*suspended)(struct bt_a2dp_stream *stream); /** - * @brief Stream reconfigured callback + * @brief Stream abort callback * - * The callback is called whenever an Audio Stream has been reconfigured. + * The callback is called whenever an Audio Stream has been aborted. + * After aborted, the stream becomes invalid. * - * @param stream Stream object that has been reconfigured. + * @param stream Stream object that has been aborted. */ - void (*reconfigured)(struct bt_a2dp_stream *stream); + void (*aborted)(struct bt_a2dp_stream *stream); #if defined(CONFIG_BT_A2DP_SINK) /** @brief the media streaming data, only for sink * @@ -665,8 +700,8 @@ struct bt_a2dp_stream_ops { * @param seq_num the sequence number * @param ts the time stamp */ - void (*recv)(struct bt_a2dp_stream *stream, - struct net_buf *buf, uint16_t seq_num, uint32_t ts); + void (*recv)(struct bt_a2dp_stream *stream, struct net_buf *buf, uint16_t seq_num, + uint32_t ts); #endif #if defined(CONFIG_BT_A2DP_SOURCE) /** @@ -711,8 +746,8 @@ void bt_a2dp_stream_cb_register(struct bt_a2dp_stream *stream, struct bt_a2dp_st * @return 0 in case of success and error code in case of error. */ int bt_a2dp_stream_config(struct bt_a2dp *a2dp, struct bt_a2dp_stream *stream, - struct bt_a2dp_ep *local_ep, struct bt_a2dp_ep *remote_ep, - struct bt_a2dp_codec_cfg *config); + struct bt_a2dp_ep *local_ep, struct bt_a2dp_ep *remote_ep, + struct bt_a2dp_codec_cfg *config); /** @brief establish a2dp streamer. * @@ -727,6 +762,7 @@ int bt_a2dp_stream_establish(struct bt_a2dp_stream *stream); /** @brief release a2dp streamer. * * This function sends the AVDTP_CLOSE command and release the l2cap channel. + * After release, the stream becomes invalid. * * @param stream The stream object. * @@ -765,6 +801,17 @@ int bt_a2dp_stream_suspend(struct bt_a2dp_stream *stream); */ int bt_a2dp_stream_reconfig(struct bt_a2dp_stream *stream, struct bt_a2dp_codec_cfg *config); +/** @brief abort a2dp streamer. + * + * This function sends the AVDTP_ABORT command. + * After abort, the stream becomes invalid. + * + * @param stream The stream object. + * + * @return 0 in case of success and error code in case of error. + */ +int bt_a2dp_stream_abort(struct bt_a2dp_stream *stream); + /** @brief get the stream l2cap mtu * * @param stream The stream object. @@ -785,8 +832,8 @@ uint32_t bt_a2dp_get_mtu(struct bt_a2dp_stream *stream); * * @return 0 in case of success and error code in case of error. */ -int bt_a2dp_stream_send(struct bt_a2dp_stream *stream, struct net_buf *buf, - uint16_t seq_num, uint32_t ts); +int bt_a2dp_stream_send(struct bt_a2dp_stream *stream, struct net_buf *buf, uint16_t seq_num, + uint32_t ts); #endif #ifdef __cplusplus diff --git a/include/zephyr/bluetooth/classic/avdtp.h b/include/zephyr/bluetooth/classic/avdtp.h index cfd419239783e..dd7307ae3748f 100644 --- a/include/zephyr/bluetooth/classic/avdtp.h +++ b/include/zephyr/bluetooth/classic/avdtp.h @@ -87,11 +87,11 @@ enum bt_avdtp_media_type { */ struct bt_avdtp_sep_info { /** End Point usage status */ - uint8_t inuse:1; + uint8_t inuse: 1; /** Stream End Point ID that is the identifier of the stream endpoint */ - uint8_t id:6; + uint8_t id: 6; /** Reserved */ - uint8_t reserved:1; + uint8_t reserved: 1; /** Stream End-point Type that indicates if the stream end-point is SNK or SRC */ enum bt_avdtp_sep_type tsep; /** Media-type of the End Point @@ -127,8 +127,9 @@ struct bt_avdtp_sep { /** Media Transport Channel*/ struct bt_l2cap_br_chan chan; /** the endpoint media data */ - void (*media_data_cb)(struct bt_avdtp_sep *sep, - struct net_buf *buf); + void (*media_data_cb)(struct bt_avdtp_sep *sep, struct net_buf *buf); + /* semaphore for lock/unlock */ + struct k_sem sem_lock; /** avdtp session */ struct bt_avdtp *session; /** SEP state */ diff --git a/include/zephyr/bluetooth/classic/avrcp.h b/include/zephyr/bluetooth/classic/avrcp.h index 4c422570fb637..14678643592dd 100644 --- a/include/zephyr/bluetooth/classic/avrcp.h +++ b/include/zephyr/bluetooth/classic/avrcp.h @@ -16,6 +16,99 @@ extern "C" { #endif +/** @brief AV/C command types */ +typedef enum __packed { + BT_AVRCP_CTYPE_CONTROL = 0x0, + BT_AVRCP_CTYPE_STATUS = 0x1, + BT_AVRCP_CTYPE_SPECIFIC_INQUIRY = 0x2, + BT_AVRCP_CTYPE_NOTIFY = 0x3, + BT_AVRCP_CTYPE_GENERAL_INQUIRY = 0x4, +} bt_avrcp_ctype_t; + +/** @brief AV/C response codes */ +typedef enum __packed { + BT_AVRCP_RSP_NOT_IMPLEMENTED = 0x8, + BT_AVRCP_RSP_ACCEPTED = 0x9, + BT_AVRCP_RSP_REJECTED = 0xa, + BT_AVRCP_RSP_IN_TRANSITION = 0xb, + BT_AVRCP_RSP_IMPLEMENTED = 0xc, /**< For SPECIFIC_INQUIRY and GENERAL_INQUIRY commands */ + BT_AVRCP_RSP_STABLE = 0xc, /**< For STATUS commands */ + BT_AVRCP_RSP_CHANGED = 0xd, + BT_AVRCP_RSP_INTERIM = 0xf, +} bt_avrcp_rsp_t; + +/** @brief AV/C operation ids used in AVRCP passthrough commands */ +typedef enum __packed { + BT_AVRCP_OPID_SELECT = 0x00, + BT_AVRCP_OPID_UP = 0x01, + BT_AVRCP_OPID_DOWN = 0x02, + BT_AVRCP_OPID_LEFT = 0x03, + BT_AVRCP_OPID_RIGHT = 0x04, + BT_AVRCP_OPID_RIGHT_UP = 0x05, + BT_AVRCP_OPID_RIGHT_DOWN = 0x06, + BT_AVRCP_OPID_LEFT_UP = 0x07, + BT_AVRCP_OPID_LEFT_DOWN = 0x08, + BT_AVRCP_OPID_ROOT_MENU = 0x09, + BT_AVRCP_OPID_SETUP_MENU = 0x0a, + BT_AVRCP_OPID_CONTENTS_MENU = 0x0b, + BT_AVRCP_OPID_FAVORITE_MENU = 0x0c, + BT_AVRCP_OPID_EXIT = 0x0d, + + BT_AVRCP_OPID_0 = 0x20, + BT_AVRCP_OPID_1 = 0x21, + BT_AVRCP_OPID_2 = 0x22, + BT_AVRCP_OPID_3 = 0x23, + BT_AVRCP_OPID_4 = 0x24, + BT_AVRCP_OPID_5 = 0x25, + BT_AVRCP_OPID_6 = 0x26, + BT_AVRCP_OPID_7 = 0x27, + BT_AVRCP_OPID_8 = 0x28, + BT_AVRCP_OPID_9 = 0x29, + BT_AVRCP_OPID_DOT = 0x2a, + BT_AVRCP_OPID_ENTER = 0x2b, + BT_AVRCP_OPID_CLEAR = 0x2c, + + BT_AVRCP_OPID_CHANNEL_UP = 0x30, + BT_AVRCP_OPID_CHANNEL_DOWN = 0x31, + BT_AVRCP_OPID_PREVIOUS_CHANNEL = 0x32, + BT_AVRCP_OPID_SOUND_SELECT = 0x33, + BT_AVRCP_OPID_INPUT_SELECT = 0x34, + BT_AVRCP_OPID_DISPLAY_INFORMATION = 0x35, + BT_AVRCP_OPID_HELP = 0x36, + BT_AVRCP_OPID_PAGE_UP = 0x37, + BT_AVRCP_OPID_PAGE_DOWN = 0x38, + + BT_AVRCP_OPID_POWER = 0x40, + BT_AVRCP_OPID_VOLUME_UP = 0x41, + BT_AVRCP_OPID_VOLUME_DOWN = 0x42, + BT_AVRCP_OPID_MUTE = 0x43, + BT_AVRCP_OPID_PLAY = 0x44, + BT_AVRCP_OPID_STOP = 0x45, + BT_AVRCP_OPID_PAUSE = 0x46, + BT_AVRCP_OPID_RECORD = 0x47, + BT_AVRCP_OPID_REWIND = 0x48, + BT_AVRCP_OPID_FAST_FORWARD = 0x49, + BT_AVRCP_OPID_EJECT = 0x4a, + BT_AVRCP_OPID_FORWARD = 0x4b, + BT_AVRCP_OPID_BACKWARD = 0x4c, + + BT_AVRCP_OPID_ANGLE = 0x50, + BT_AVRCP_OPID_SUBPICTURE = 0x51, + + BT_AVRCP_OPID_F1 = 0x71, + BT_AVRCP_OPID_F2 = 0x72, + BT_AVRCP_OPID_F3 = 0x73, + BT_AVRCP_OPID_F4 = 0x74, + BT_AVRCP_OPID_F5 = 0x75, + BT_AVRCP_OPID_VENDOR_UNIQUE = 0x7e, +} bt_avrcp_opid_t; + +/** @brief AVRCP button state flag */ +typedef enum __packed { + BT_AVRCP_BUTTON_PRESSED = 0, + BT_AVRCP_BUTTON_RELEASED = 1, +} bt_avrcp_button_state_t; + /** @brief AVRCP structure */ struct bt_avrcp; @@ -28,7 +121,15 @@ struct bt_avrcp_subunit_info_rsp { uint8_t subunit_type; uint8_t max_subunit_id; const uint8_t *extended_subunit_type; /**< contains max_subunit_id items */ - const uint8_t *extended_subunit_id; /**< contains max_subunit_id items */ + const uint8_t *extended_subunit_id; /**< contains max_subunit_id items */ +}; + +struct bt_avrcp_passthrough_rsp { + uint8_t response; /**< bt_avrcp_rsp_t */ + uint8_t operation_id; /**< bt_avrcp_opid_t */ + uint8_t state; /**< bt_avrcp_button_state_t */ + uint8_t len; + const uint8_t *payload; }; struct bt_avrcp_cb { @@ -40,6 +141,7 @@ struct bt_avrcp_cb { * @param avrcp AVRCP connection object. */ void (*connected)(struct bt_avrcp *avrcp); + /** @brief An AVRCP connection has been disconnected. * * This callback notifies the application that an avrcp connection @@ -48,6 +150,7 @@ struct bt_avrcp_cb { * @param avrcp AVRCP connection object. */ void (*disconnected)(struct bt_avrcp *avrcp); + /** @brief Callback function for bt_avrcp_get_unit_info(). * * Called when the get unit info process is completed. @@ -56,6 +159,7 @@ struct bt_avrcp_cb { * @param rsp The response for UNIT INFO command. */ void (*unit_info_rsp)(struct bt_avrcp *avrcp, struct bt_avrcp_unit_info_rsp *rsp); + /** @brief Callback function for bt_avrcp_get_subunit_info(). * * Called when the get subunit info process is completed. @@ -64,6 +168,15 @@ struct bt_avrcp_cb { * @param rsp The response for SUBUNIT INFO command. */ void (*subunit_info_rsp)(struct bt_avrcp *avrcp, struct bt_avrcp_subunit_info_rsp *rsp); + + /** @brief Callback function for bt_avrcp_passthrough(). + * + * Called when a passthrough response is received. + * + * @param avrcp AVRCP connection object. + * @param rsp The response for PASS THROUGH command. + */ + void (*passthrough_rsp)(struct bt_avrcp *avrcp, struct bt_avrcp_passthrough_rsp *rsp); }; /** @brief Connect AVRCP. @@ -120,6 +233,22 @@ int bt_avrcp_get_unit_info(struct bt_avrcp *avrcp); */ int bt_avrcp_get_subunit_info(struct bt_avrcp *avrcp); +/** @brief Send AVRCP Pass Through command. + * + * This function send a pass through command to the remote device. Passsthhrough command is used + * to transfer user operation information from a CT to Panel subunit of TG. + * + * @param avrcp The AVRCP instance. + * @param operation_id The user operation id. + * @param state The button state. + * @param payload The payload of the pass through command. Should not be NULL if len is not zero. + * @param len The length of the payload. + * + * @return 0 in case of success or error code in case of error. + */ +int bt_avrcp_passthrough(struct bt_avrcp *avrcp, bt_avrcp_opid_t operation_id, + bt_avrcp_button_state_t state, const uint8_t *payload, uint8_t len); + #ifdef __cplusplus } #endif diff --git a/include/zephyr/bluetooth/classic/rfcomm.h b/include/zephyr/bluetooth/classic/rfcomm.h index 1d3056643bd0b..be2cf02b4192e 100644 --- a/include/zephyr/bluetooth/classic/rfcomm.h +++ b/include/zephyr/bluetooth/classic/rfcomm.h @@ -19,11 +19,27 @@ #include #include +#include #ifdef __cplusplus extern "C" { #endif +/** RFCOMM Maximum Header Size. The length could be 2 bytes, it depends on information length. */ +#define BT_RFCOMM_HDR_MAX_SIZE 4 +/** RFCOMM FCS Size */ +#define BT_RFCOMM_FCS_SIZE 1 + +/** @brief Helper to calculate needed buffer size for RFCOMM PDUs. + * Useful for creating buffer pools. + * + * @param mtu Needed RFCOMM PDU MTU. + * + * @return Needed buffer size to match the requested RFCOMM PDU MTU. + */ +#define BT_RFCOMM_BUF_SIZE(mtu) \ + BT_L2CAP_BUF_SIZE(BT_RFCOMM_HDR_MAX_SIZE + BT_RFCOMM_FCS_SIZE + (mtu)) + /* RFCOMM channels (1-30): pre-allocated for profiles to avoid conflicts */ enum { BT_RFCOMM_CHAN_HFP_HF = 1, @@ -31,6 +47,7 @@ enum { BT_RFCOMM_CHAN_HSP_AG, BT_RFCOMM_CHAN_HSP_HS, BT_RFCOMM_CHAN_SPP, + BT_RFCOMM_CHAN_DYNAMIC_START, }; struct bt_rfcomm_dlc; @@ -109,7 +126,16 @@ struct bt_rfcomm_dlc { }; struct bt_rfcomm_server { - /** Server Channel */ + /** Server Channel + * + * Possible values: + * 0 A dynamic value will be auto-allocated when bt_rfcomm_server_register() is + * called. + * + * 0x01 - 0x1e Dynamically allocated. May be pre-set by the application before server + * registration (not recommended however), or auto-allocated by the stack + * if the 0 is passed. + */ uint8_t channel; /** Server accept callback @@ -118,11 +144,13 @@ struct bt_rfcomm_server { * authorization. * * @param conn The connection that is requesting authorization + * @param server Pointer to the server structure this callback relates to * @param dlc Pointer to received the allocated dlc * * @return 0 in case of success or negative value in case of error. */ - int (*accept)(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc); + int (*accept)(struct bt_conn *conn, struct bt_rfcomm_server *server, + struct bt_rfcomm_dlc **dlc); struct bt_rfcomm_server *_next; }; diff --git a/include/zephyr/bluetooth/classic/sdp.h b/include/zephyr/bluetooth/classic/sdp.h index 686c0e718cb96..ac0f9d2a10e20 100644 --- a/include/zephyr/bluetooth/classic/sdp.h +++ b/include/zephyr/bluetooth/classic/sdp.h @@ -481,8 +481,6 @@ struct bt_sdp_client_result { struct net_buf *resp_buf; /** flag pointing that there are more result chunks for given UUID */ bool next_record_hint; - /** Reference to UUID object on behalf one discovery was started */ - const struct bt_uuid *uuid; }; /** @brief Helper enum to be used as return value of bt_sdp_discover_func_t. @@ -493,6 +491,8 @@ enum { BT_SDP_DISCOVER_UUID_CONTINUE, }; +struct bt_sdp_discover_params; + /** @typedef bt_sdp_discover_func_t * * @brief Callback type reporting to user that there is a resolved result @@ -514,24 +514,41 @@ enum { * * @param conn Connection object identifying connection to queried remote. * @param result Object pointing to logical unparsed SDP record collected on - * base of response driven by given UUID. + * base of response driven by given discover params. + * @param params Discover parameters. * * @return BT_SDP_DISCOVER_UUID_STOP in case of no more need to read next * record data and continue discovery for given UUID. By returning - * BT_SDP_DISCOVER_UUID_CONTINUE user allows this discovery continuation. + * @return BT_SDP_DISCOVER_UUID_CONTINUE user allows this discovery continuation. */ -typedef uint8_t (*bt_sdp_discover_func_t) - (struct bt_conn *conn, struct bt_sdp_client_result *result); +typedef uint8_t (*bt_sdp_discover_func_t)(struct bt_conn *conn, struct bt_sdp_client_result *result, + const struct bt_sdp_discover_params *params); + +/** SDP Discover types */ +enum { + /** Discover Service Search. */ + BT_SDP_DISCOVER_SERVICE_SEARCH, + /** Discover Service Attribute. */ + BT_SDP_DISCOVER_SERVICE_ATTR, + /** Discover Service Search Attribute. */ + BT_SDP_DISCOVER_SERVICE_SEARCH_ATTR, +}; /** @brief Main user structure used in SDP discovery of remote. */ struct bt_sdp_discover_params { - sys_snode_t _node; - /** UUID (service) to be discovered on remote SDP entity */ - const struct bt_uuid *uuid; + sys_snode_t _node; + union { + /** UUID (service) to be discovered on remote SDP entity */ + const struct bt_uuid *uuid; + /** Service record handle */ + uint32_t handle; + }; /** Discover callback to be called on resolved SDP record */ - bt_sdp_discover_func_t func; + bt_sdp_discover_func_t func; /** Memory buffer enabled by user for SDP query results */ - struct net_buf_pool *pool; + struct net_buf_pool *pool; + /** Discover type */ + uint8_t type; }; /** @brief Allows user to start SDP discovery session. @@ -543,6 +560,21 @@ struct bt_sdp_discover_params { * On the service discovery completion the callback function will be * called to get feedback to user about findings. * + * Service Search: The SDP Client generates an + * SDP_SERVICE_SEARCH_REQ to locate service + * records that match the service search + * pattern (`params->uuid`) given as the first + * parameter of the PDU. + * Service Attribute: The SDP Client generates an + * SDP_SERVICE_ATTR_REQ to retrieve specified + * attribute values from a specific service + * record (`params->handle`). + * Service Search Attribute: The SDP Client generates an + * SDP_SERVICE_SEARCH_ATTR_REQ to retrieve + * specified attribute values that match the + * service search pattern (`params->uuid`) + * given as the first parameter of the PDU. + * * @param conn Object identifying connection to remote. * @param params SDP discovery parameters. * diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 73a14b09ab992..070fd1ef25be9 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -4,6 +4,7 @@ /* * Copyright (c) 2015-2016 Intel Corporation + * Copyright (c) 2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -722,7 +723,7 @@ struct bt_conn *bt_conn_lookup_addr_le(uint8_t id, const bt_addr_le_t *peer); * * @param conn Connection object. * - * @return Destination address. + * @return Destination address if @p conn is a valid @ref BT_CONN_TYPE_LE connection */ const bt_addr_le_t *bt_conn_get_dst(const struct bt_conn *conn); @@ -1041,9 +1042,20 @@ enum bt_conn_auth_keypress { */ int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info); +/** @brief Function to determine the type of a connection + * + * @param conn The connection object + * @param type The types to check against. It is possible to supply multiple types, + * e.g. BT_CONN_TYPE_LE | BT_CONN_TYPE_SCO. + * + * @retval true @p conn is of type @p type + * @retval false @p conn is either NULL or not of type @p type + */ +bool bt_conn_is_type(const struct bt_conn *conn, enum bt_conn_type type); + /** @brief Get connection info for the remote device. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * @param remote_info Connection remote info object. * * @note In order to retrieve the remote version (version, manufacturer @@ -1055,51 +1067,56 @@ int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info); * * @return Zero on success or (negative) error code on failure. * @return -EBUSY The remote information is not yet available. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection. */ int bt_conn_get_remote_info(struct bt_conn *conn, struct bt_conn_remote_info *remote_info); /** @brief Get connection transmit power level. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param tx_power_level Transmit power level descriptor. * * @return Zero on success or (negative) error code on failure. * @return -ENOBUFS HCI command buffer is not available. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_get_tx_power_level(struct bt_conn *conn, struct bt_conn_le_tx_power *tx_power_level); /** @brief Get local enhanced connection transmit power level. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param tx_power Transmit power level descriptor. * * @return Zero on success or (negative) error code on failure. * @retval -ENOBUFS HCI command buffer is not available. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_enhanced_get_tx_power_level(struct bt_conn *conn, struct bt_conn_le_tx_power *tx_power); /** @brief Get remote (peer) transmit power level. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param phy PHY information. * * @return Zero on success or (negative) error code on failure. * @retval -ENOBUFS HCI command buffer is not available. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_get_remote_tx_power_level(struct bt_conn *conn, enum bt_conn_le_tx_power_phy phy); /** @brief Enable transmit power reporting. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param local_enable Enable/disable reporting for local. * @param remote_enable Enable/disable reporting for remote. * * @return Zero on success or (negative) error code on failure. * @retval -ENOBUFS HCI command buffer is not available. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_set_tx_power_report_enable(struct bt_conn *conn, bool local_enable, @@ -1111,10 +1128,11 @@ int bt_conn_le_set_tx_power_report_enable(struct bt_conn *conn, * * @note To use this API @kconfig{CONFIG_BT_PATH_LOSS_MONITORING} must be set. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param param Path Loss Monitoring parameters * * @return Zero on success or (negative) error code on failure. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_set_path_loss_mon_param(struct bt_conn *conn, const struct bt_conn_le_path_loss_reporting_param *param); @@ -1126,10 +1144,11 @@ int bt_conn_le_set_path_loss_mon_param(struct bt_conn *conn, * * @note To use this API @kconfig{CONFIG_BT_PATH_LOSS_MONITORING} must be set. * - * @param conn Connection Object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param enable Enable/disable path loss reporting. * * @return Zero on success or (negative) error code on failure. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_set_path_loss_mon_enable(struct bt_conn *conn, bool enable); @@ -1155,10 +1174,11 @@ int bt_conn_le_subrate_set_defaults(const struct bt_conn_le_subrate_param *param * * @note To use this API @kconfig{CONFIG_BT_SUBRATING} must be set. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param params Subrating parameters. * * @return Zero on success or (negative) error code on failure. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_subrate_request(struct bt_conn *conn, const struct bt_conn_le_subrate_param *params); @@ -1169,20 +1189,22 @@ int bt_conn_le_subrate_request(struct bt_conn *conn, * parameters will be delayed. This delay can be configured by through the * @kconfig{CONFIG_BT_CONN_PARAM_UPDATE_TIMEOUT} option. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param param Updated connection parameters. * * @return Zero on success or (negative) error code on failure. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_param_update(struct bt_conn *conn, const struct bt_le_conn_param *param); /** @brief Update the connection transmit data length parameters. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param param Updated data length parameters. * * @return Zero on success or (negative) error code on failure. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_data_len_update(struct bt_conn *conn, const struct bt_conn_le_data_len_param *param); @@ -1192,10 +1214,11 @@ int bt_conn_le_data_len_update(struct bt_conn *conn, * Update the preferred transmit and receive PHYs of the connection. * Use @ref BT_GAP_LE_PHY_NONE to indicate no preference. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param param Updated connection parameters. * * @return Zero on success or (negative) error code on failure. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_conn_le_phy_update(struct bt_conn *conn, const struct bt_conn_le_phy_param *param); @@ -1469,16 +1492,22 @@ __deprecated int bt_le_set_auto_conn(const bt_addr_le_t *addr, * @note When @ref BT_SECURITY_FORCE_PAIR within @p sec is enabled then the pairing * procedure will always be initiated. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * @param sec Requested minimum security level. * * @return 0 on success or negative error + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection. */ int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec); /** @brief Get security level for a connection. * - * @return Connection security level + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. + * + * @return Connection security level if @kconfig{CONFIG_BT_SMP} or @kconfig{CONFIG_BT_CLASSIC} is + * enabled, else @ref BT_SECURITY_L1 + * @return @ref BT_SECURITY_L0 @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR + * connection. */ bt_security_t bt_conn_get_security(const struct bt_conn *conn); @@ -1487,9 +1516,10 @@ bt_security_t bt_conn_get_security(const struct bt_conn *conn); * This function gets encryption key size. * If there is no security (encryption) enabled 0 will be returned. * - * @param conn Existing connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * * @return Encryption key size. + * @return 0 @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection. */ uint8_t bt_conn_enc_key_size(const struct bt_conn *conn); @@ -2013,8 +2043,13 @@ bool bt_get_bondable(void); * The default value of the global configuration is defined using * CONFIG_BT_BONDABLE Kconfig option. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * @param enable Value allowing/disallowing to be bondable. + * + * @retval 0 Success + * @retval -EALREADY Already in the requested state + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection + * @return -EINVAL @p conn is a valid @ref BT_CONN_TYPE_LE but could not get SMP context */ int bt_conn_set_bondable(struct bt_conn *conn, bool enable); @@ -2040,10 +2075,12 @@ void bt_le_oob_set_legacy_flag(bool enable); * The function should only be called in response to the oob_data_request() * callback provided that the legacy method is user pairing. * - * @param conn Connection object + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param tk Pointer to 16 byte long TK array * - * @return Zero on success or -EINVAL if NULL + * @retval 0 Success + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. + * @return -EINVAL @p tk is NULL. */ int bt_le_oob_set_legacy_tk(struct bt_conn *conn, const uint8_t *tk); @@ -2058,12 +2095,13 @@ int bt_le_oob_set_legacy_tk(struct bt_conn *conn, const uint8_t *tk); * data present, with only remote OOB data present or with both local and * remote OOB data present. * - * @param conn Connection object + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param oobd_local Local OOB data or NULL if not present * @param oobd_remote Remote OOB data or NULL if not present * * @return Zero on success or error code otherwise, positive in case of * protocol error or negative (POSIX) in case of stack internal error. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_le_oob_set_sc_data(struct bt_conn *conn, const struct bt_le_oob_sc_data *oobd_local, @@ -2077,12 +2115,13 @@ int bt_le_oob_set_sc_data(struct bt_conn *conn, * @note The OOB data will only be available as long as the connection object * associated with it is valid. * - * @param conn Connection object + * @param conn @ref BT_CONN_TYPE_LE connection object. * @param oobd_local Local OOB data or NULL if not set * @param oobd_remote Remote OOB data or NULL if not set * * @return Zero on success or error code otherwise, positive in case of * protocol error or negative (POSIX) in case of stack internal error. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. */ int bt_le_oob_get_sc_data(struct bt_conn *conn, const struct bt_le_oob_sc_data **oobd_local, @@ -2428,10 +2467,11 @@ int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb); * security procedures in the SMP module have already started. This function * can be called only once per connection. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * @param cb Callback struct. * * @return Zero on success or negative error code otherwise + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection */ int bt_conn_auth_cb_overlay(struct bt_conn *conn, const struct bt_conn_auth_cb *cb); @@ -2461,10 +2501,11 @@ int bt_conn_auth_info_cb_unregister(struct bt_conn_auth_info_cb *cb); * This function should be called only after passkey_entry callback from * bt_conn_auth_cb structure was called. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * @param passkey Entered passkey. * * @return Zero on success or negative error code otherwise + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection */ int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey); @@ -2475,13 +2516,14 @@ int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey); * * Requires @kconfig{CONFIG_BT_PASSKEY_KEYPRESS}. * - * @param conn Destination for the notification. + * @param conn @ref BT_CONN_TYPE_LE destination connection for the notification. * @param type What keypress event type to send. @see bt_conn_auth_keypress. * * @retval 0 Success * @retval -EINVAL Improper use of the API. * @retval -ENOMEM Failed to allocate. * @retval -ENOBUFS Failed to allocate. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection */ int bt_conn_auth_keypress_notify(struct bt_conn *conn, enum bt_conn_auth_keypress type); @@ -2489,9 +2531,10 @@ int bt_conn_auth_keypress_notify(struct bt_conn *conn, enum bt_conn_auth_keypres * * This function allows to cancel ongoing authenticated pairing. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * * @return Zero on success or negative error code otherwise + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection */ int bt_conn_auth_cancel(struct bt_conn *conn); @@ -2500,9 +2543,10 @@ int bt_conn_auth_cancel(struct bt_conn *conn); * This function should be called only after passkey_confirm callback from * bt_conn_auth_cb structure was called. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * * @return Zero on success or negative error code otherwise + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection */ int bt_conn_auth_passkey_confirm(struct bt_conn *conn); @@ -2511,9 +2555,10 @@ int bt_conn_auth_passkey_confirm(struct bt_conn *conn); * This function should be called only after pairing_confirm callback from * bt_conn_auth_cb structure was called if user confirmed incoming pairing. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection object. * * @return Zero on success or negative error code otherwise + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE or @ref BT_CONN_TYPE_BR connection */ int bt_conn_auth_pairing_confirm(struct bt_conn *conn); @@ -2522,10 +2567,11 @@ int bt_conn_auth_pairing_confirm(struct bt_conn *conn); * This function should be called only after PIN code callback from * bt_conn_auth_cb structure was called. It's for legacy 2.0 devices. * - * @param conn Connection object. + * @param conn @ref BT_CONN_TYPE_BR connection object. * @param pin Entered PIN code. * * @return Zero on success or negative error code otherwise + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_BR connection */ int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin); diff --git a/include/zephyr/bluetooth/gap.h b/include/zephyr/bluetooth/gap.h index 1b1569e300318..2582d9fb96c2f 100644 --- a/include/zephyr/bluetooth/gap.h +++ b/include/zephyr/bluetooth/gap.h @@ -747,8 +747,16 @@ enum { BT_GAP_LE_PHY_1M = BIT(0), /** LE 2M PHY */ BT_GAP_LE_PHY_2M = BIT(1), - /** LE Coded PHY */ + /** LE Coded PHY, coding scheme not specified */ BT_GAP_LE_PHY_CODED = BIT(2), + /** LE Coded S=8 PHY. Only used for advertising reports + * when Kconfig BT_EXT_ADV_CODING_SELECTION is enabled. + */ + BT_GAP_LE_PHY_CODED_S8 = BIT(3), + /** LE Coded S=2 PHY. Only used for advertising reports + * when Kconfig BT_EXT_ADV_CODING_SELECTION is enabled. + */ + BT_GAP_LE_PHY_CODED_S2 = BIT(4), }; /** Advertising PDU types */ diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index 5a20771e7259e..d736c95ae5fe3 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -717,7 +717,8 @@ uint16_t bt_gatt_attr_get_handle(const struct bt_gatt_attr *attr); * * @param attr A Characteristic Attribute. * - * @note The ``user_data`` of the attribute must of type @ref bt_gatt_chrc. + * @note The ``user_data`` of the attribute must of type @ref bt_gatt_chrc and the ``uuid`` shall be + * BT_UUID_GATT_CHRC * * @return the handle of the corresponding Characteristic Value. The value will * be zero (the invalid handle) if @p attr was not a characteristic diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index e7d20350f483f..1a732790077f8 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -198,6 +198,8 @@ struct bt_hci_cmd_hdr { #define BT_LE_FEAT_BIT_CONN_SUBRATING 37 #define BT_LE_FEAT_BIT_CONN_SUBRATING_HOST_SUPP 38 #define BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION 39 +#define BT_LE_FEAT_BIT_ADV_CODING_SEL 40 +#define BT_LE_FEAT_BIT_ADV_CODING_SEL_HOST 41 #define BT_LE_FEAT_BIT_PAWR_ADVERTISER 43 #define BT_LE_FEAT_BIT_PAWR_SCANNER 44 @@ -268,6 +270,10 @@ struct bt_hci_cmd_hdr { BT_LE_FEAT_BIT_CONN_SUBRATING_HOST_SUPP) #define BT_FEAT_LE_CHANNEL_CLASSIFICATION(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION) +#define BT_FEAT_LE_ADV_CODING_SEL(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_ADV_CODING_SEL) +#define BT_FEAT_LE_ADV_CODING_SEL_HOST(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_ADV_CODING_SEL_HOST) #define BT_FEAT_LE_PAWR_ADVERTISER(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_PAWR_ADVERTISER) #define BT_FEAT_LE_PAWR_SCANNER(feat) BT_LE_FEAT_TEST(feat, \ @@ -1022,7 +1028,7 @@ struct bt_hci_rp_read_encryption_key_size { uint8_t key_size; } __packed; -/* BLE */ +/* Bluetooth LE */ #define BT_HCI_OP_LE_SET_EVENT_MASK BT_OP(BT_OGF_LE, 0x0001) /* 0x2001 */ struct bt_hci_cp_le_set_event_mask { @@ -1538,6 +1544,30 @@ struct bt_hci_rp_le_set_ext_adv_param { int8_t tx_power; } __packed; +#define BT_HCI_LE_ADV_PHY_OPTION_NO_REQUIRED 0x00 +#define BT_HCI_LE_ADV_PHY_OPTION_REQUIRE_S2 0x03 +#define BT_HCI_LE_ADV_PHY_OPTION_REQUIRE_S8 0x04 + +#define BT_HCI_OP_LE_SET_EXT_ADV_PARAM_V2 BT_OP(BT_OGF_LE, 0x007F) /* 0x207F */ +struct bt_hci_cp_le_set_ext_adv_param_v2 { + uint8_t handle; + uint16_t props; + uint8_t prim_min_interval[3]; + uint8_t prim_max_interval[3]; + uint8_t prim_channel_map; + uint8_t own_addr_type; + bt_addr_le_t peer_addr; + uint8_t filter_policy; + int8_t tx_power; + uint8_t prim_adv_phy; + uint8_t sec_adv_max_skip; + uint8_t sec_adv_phy; + uint8_t sid; + uint8_t scan_req_notify_enable; + uint8_t prim_adv_phy_opt; + uint8_t sec_adv_phy_opt; +} __packed; + #define BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG 0x00 #define BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG 0x01 #define BT_HCI_LE_EXT_ADV_OP_LAST_FRAG 0x02 @@ -1714,19 +1744,19 @@ struct bt_hci_cp_le_set_pawr_subevent_data { struct bt_hci_cp_le_set_pawr_response_data { uint16_t sync_handle; uint16_t request_event; - uint8_t request_subevent; - uint8_t response_subevent; - uint8_t response_slot; - uint8_t response_data_length; - uint8_t response_data[0]; + uint8_t request_subevent; + uint8_t response_subevent; + uint8_t response_slot; + uint8_t response_data_length; + uint8_t response_data[0]; } __packed; #define BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT BT_OP(BT_OGF_LE, 0x0084) /* 0x2084 */ struct bt_hci_cp_le_set_pawr_sync_subevent { uint16_t sync_handle; uint16_t periodic_adv_properties; - uint8_t num_subevents; - uint8_t subevents[0]; + uint8_t num_subevents; + uint8_t subevents[0]; } __packed; @@ -1736,11 +1766,11 @@ struct bt_hci_cp_le_set_per_adv_param_v2 { uint16_t min_interval; uint16_t max_interval; uint16_t props; - uint8_t num_subevents; - uint8_t subevent_interval; - uint8_t response_slot_delay; - uint8_t response_slot_spacing; - uint8_t num_response_slots; + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; + uint8_t num_response_slots; } __packed; @@ -1761,7 +1791,7 @@ struct bt_hci_cp_le_set_per_adv_param_v2 { #define BT_HCI_OP_LE_PER_ADV_CREATE_SYNC BT_OP(BT_OGF_LE, 0x0044) /* 0x2044 */ struct bt_hci_cp_le_per_adv_create_sync { - uint8_t options; + uint8_t options; uint8_t sid; bt_addr_le_t addr; uint16_t skip; @@ -2406,27 +2436,27 @@ struct bt_hci_cp_le_tx_test_v4_tx_power { #define BT_HCI_OP_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES BT_OP(BT_OGF_LE, 0x0089) /* 0x2089 */ struct bt_hci_rp_le_read_local_supported_capabilities { - uint8_t status; - uint8_t num_config_supported; + uint8_t status; + uint8_t num_config_supported; uint16_t max_consecutive_procedures_supported; - uint8_t num_antennas_supported; - uint8_t max_antenna_paths_supported; - uint8_t roles_supported; - uint8_t modes_supported; - uint8_t rtt_capability; - uint8_t rtt_aa_only_n; - uint8_t rtt_sounding_n; - uint8_t rtt_random_payload_n; + uint8_t num_antennas_supported; + uint8_t max_antenna_paths_supported; + uint8_t roles_supported; + uint8_t modes_supported; + uint8_t rtt_capability; + uint8_t rtt_aa_only_n; + uint8_t rtt_sounding_n; + uint8_t rtt_random_payload_n; uint16_t nadm_sounding_capability; uint16_t nadm_random_capability; - uint8_t cs_sync_phys_supported; + uint8_t cs_sync_phys_supported; uint16_t subfeatures_supported; uint16_t t_ip1_times_supported; uint16_t t_ip2_times_supported; uint16_t t_fcs_times_supported; uint16_t t_pm_times_supported; - uint8_t t_sw_time_supported; - uint8_t tx_snr_capability; + uint8_t t_sw_time_supported; + uint8_t tx_snr_capability; } __packed; #define BT_HCI_OP_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES BT_OP(BT_OGF_LE, 0x008A) /* 0x208A */ @@ -2440,26 +2470,26 @@ struct bt_hci_cp_le_read_remote_supported_capabilities { struct bt_hci_cp_le_write_cached_remote_supported_capabilities { uint16_t handle; - uint8_t num_config_supported; + uint8_t num_config_supported; uint16_t max_consecutive_procedures_supported; - uint8_t num_antennas_supported; - uint8_t max_antenna_paths_supported; - uint8_t roles_supported; - uint8_t modes_supported; - uint8_t rtt_capability; - uint8_t rtt_aa_only_n; - uint8_t rtt_sounding_n; - uint8_t rtt_random_payload_n; + uint8_t num_antennas_supported; + uint8_t max_antenna_paths_supported; + uint8_t roles_supported; + uint8_t modes_supported; + uint8_t rtt_capability; + uint8_t rtt_aa_only_n; + uint8_t rtt_sounding_n; + uint8_t rtt_random_payload_n; uint16_t nadm_sounding_capability; uint16_t nadm_random_capability; - uint8_t cs_sync_phys_supported; + uint8_t cs_sync_phys_supported; uint16_t subfeatures_supported; uint16_t t_ip1_times_supported; uint16_t t_ip2_times_supported; uint16_t t_fcs_times_supported; uint16_t t_pm_times_supported; - uint8_t t_sw_time_supported; - uint8_t tx_snr_capability; + uint8_t t_sw_time_supported; + uint8_t tx_snr_capability; } __packed; #define BT_HCI_OP_LE_CS_SECURITY_ENABLE BT_OP(BT_OGF_LE, 0x008C) /* 0x208C */ @@ -2485,9 +2515,9 @@ struct bt_hci_cp_le_security_enable { struct bt_hci_cp_le_cs_set_default_settings { uint16_t handle; - uint8_t role_enable; - uint8_t cs_sync_antenna_selection; - int8_t max_tx_power; + uint8_t role_enable; + uint8_t cs_sync_antenna_selection; + int8_t max_tx_power; } __packed; #define BT_HCI_OP_LE_CS_READ_REMOTE_FAE_TABLE BT_OP(BT_OGF_LE, 0x008E) /* 0x208E */ @@ -2500,7 +2530,7 @@ struct bt_hci_cp_le_read_remote_fae_table { struct bt_hci_cp_le_write_cached_remote_fae_table { uint16_t handle; - int8_t remote_fae_table[72]; + int8_t remote_fae_table[72]; } __packed; #define BT_HCI_OP_LE_CS_SET_CHANNEL_CLASSIFICATION BT_OP(BT_OGF_LE, 0x0092) /* 0x2092 */ @@ -2514,19 +2544,19 @@ struct bt_hci_cp_le_write_cached_remote_fae_table { struct bt_hci_cp_le_set_procedure_parameters { uint16_t handle; - uint8_t config_id; + uint8_t config_id; uint16_t max_procedure_len; uint16_t min_procedure_interval; uint16_t max_procedure_interval; uint16_t max_procedure_count; - uint8_t min_subevent_len[3]; - uint8_t max_subevent_len[3]; - uint8_t tone_antenna_config_selection; - uint8_t phy; - uint8_t tx_power_delta; - uint8_t preferred_peer_antenna; - uint8_t snr_control_initiator; - uint8_t snr_control_reflector; + uint8_t min_subevent_len[3]; + uint8_t max_subevent_len[3]; + uint8_t tone_antenna_config_selection; + uint8_t phy; + uint8_t tx_power_delta; + uint8_t preferred_peer_antenna; + uint8_t snr_control_initiator; + uint8_t snr_control_reflector; } __packed; #define BT_HCI_OP_LE_CS_PROCEDURE_ENABLE BT_OP(BT_OGF_LE, 0x0094) /* 0x2094 */ @@ -2536,8 +2566,8 @@ struct bt_hci_cp_le_set_procedure_parameters { struct bt_hci_cp_le_procedure_enable { uint16_t handle; - uint8_t config_id; - uint8_t enable; + uint8_t config_id; + uint8_t enable; } __packed; #define BT_HCI_OP_LE_CS_TEST BT_OP(BT_OGF_LE, 0x0095) /* 0x2095 */ @@ -2650,62 +2680,62 @@ struct bt_hci_cp_le_procedure_enable { #define BT_HCI_OP_LE_CS_TEST_PAYLOAD_USER 0x80 struct bt_hci_op_le_cs_test { - uint8_t main_mode_type; - uint8_t sub_mode_type; - uint8_t main_mode_repetition; - uint8_t mode_0_steps; - uint8_t role; - uint8_t rtt_type; - uint8_t cs_sync_phy; - uint8_t cs_sync_antenna_selection; - uint8_t subevent_len[3]; + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t cs_sync_antenna_selection; + uint8_t subevent_len[3]; uint16_t subevent_interval; - uint8_t max_num_subevents; - uint8_t transmit_power_level; - uint8_t t_ip1_time; - uint8_t t_ip2_time; - uint8_t t_fcs_time; - uint8_t t_pm_time; - uint8_t t_sw_time; - uint8_t tone_antenna_config_selection; - uint8_t reserved; - uint8_t snr_control_initiator; - uint8_t snr_control_reflector; + uint8_t max_num_subevents; + uint8_t transmit_power_level; + uint8_t t_ip1_time; + uint8_t t_ip2_time; + uint8_t t_fcs_time; + uint8_t t_pm_time; + uint8_t t_sw_time; + uint8_t tone_antenna_config_selection; + uint8_t reserved; + uint8_t snr_control_initiator; + uint8_t snr_control_reflector; uint16_t drbg_nonce; - uint8_t channel_map_repetition; + uint8_t channel_map_repetition; uint16_t override_config; - uint8_t override_parameters_length; - uint8_t override_parameters_data[]; + uint8_t override_parameters_length; + uint8_t override_parameters_data[]; } __packed; #define BT_HCI_OP_LE_CS_CREATE_CONFIG BT_OP(BT_OGF_LE, 0x0090) /* 0x2090 */ struct bt_hci_cp_le_cs_create_config { uint16_t handle; - uint8_t config_id; - uint8_t create_context; - uint8_t main_mode_type; - uint8_t sub_mode_type; - uint8_t min_main_mode_steps; - uint8_t max_main_mode_steps; - uint8_t main_mode_repetition; - uint8_t mode_0_steps; - uint8_t role; - uint8_t rtt_type; - uint8_t cs_sync_phy; - uint8_t channel_map[10]; - uint8_t channel_map_repetition; - uint8_t channel_selection_type; - uint8_t ch3c_shape; - uint8_t ch3c_jump; - uint8_t reserved; + uint8_t config_id; + uint8_t create_context; + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t min_main_mode_steps; + uint8_t max_main_mode_steps; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t channel_map[10]; + uint8_t channel_map_repetition; + uint8_t channel_selection_type; + uint8_t ch3c_shape; + uint8_t ch3c_jump; + uint8_t reserved; } __packed; #define BT_HCI_OP_LE_CS_REMOVE_CONFIG BT_OP(BT_OGF_LE, 0x0091) /* 0x2091 */ struct bt_hci_cp_le_cs_remove_config { uint16_t handle; - uint8_t config_id; + uint8_t config_id; } __packed; #define BT_HCI_OP_LE_CS_TEST_END BT_OP(BT_OGF_LE, 0x0096) /* 0x2096 */ @@ -2873,47 +2903,47 @@ struct bt_hci_evt_remote_ext_features { #define BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED_V2 0x24 struct bt_hci_evt_le_per_adv_sync_established_v2 { - uint8_t status; - uint16_t handle; - uint8_t sid; + uint8_t status; + uint16_t handle; + uint8_t sid; bt_addr_le_t adv_addr; - uint8_t phy; - uint16_t interval; - uint8_t clock_accuracy; - uint8_t num_subevents; - uint8_t subevent_interval; - uint8_t response_slot_delay; - uint8_t response_slot_spacing; + uint8_t phy; + uint16_t interval; + uint8_t clock_accuracy; + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; } __packed; #define BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2 0x25 struct bt_hci_evt_le_per_advertising_report_v2 { uint16_t handle; - int8_t tx_power; - int8_t rssi; - uint8_t cte_type; + int8_t tx_power; + int8_t rssi; + uint8_t cte_type; uint16_t periodic_event_counter; - uint8_t subevent; - uint8_t data_status; - uint8_t length; - uint8_t data[0]; + uint8_t subevent; + uint8_t data_status; + uint8_t length; + uint8_t data[0]; } __packed; #define BT_HCI_EVT_LE_PAST_RECEIVED_V2 0x26 struct bt_hci_evt_le_past_received_v2 { - uint8_t status; - uint16_t conn_handle; - uint16_t service_data; - uint16_t sync_handle; - uint8_t adv_sid; + uint8_t status; + uint16_t conn_handle; + uint16_t service_data; + uint16_t sync_handle; + uint8_t adv_sid; bt_addr_le_t addr; - uint8_t phy; - uint16_t interval; - uint8_t clock_accuracy; - uint8_t num_subevents; - uint8_t subevent_interval; - uint8_t response_slot_delay; - uint8_t response_slot_spacing; + uint8_t phy; + uint16_t interval; + uint8_t clock_accuracy; + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; } __packed; #define BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST 0x27 @@ -2926,8 +2956,8 @@ struct bt_hci_evt_le_per_adv_subevent_data_request { #define BT_HCI_EVT_LE_PER_ADV_RESPONSE_REPORT 0x28 struct bt_hci_evt_le_per_adv_response { - int8_t tx_power; - int8_t rssi; + int8_t tx_power; + int8_t rssi; uint8_t cte_type; uint8_t response_slot; uint8_t data_status; @@ -2955,8 +2985,8 @@ struct bt_hci_evt_le_enh_conn_complete_v2 { uint16_t latency; uint16_t supv_timeout; uint8_t clock_accuracy; - uint8_t adv_handle; - uint16_t sync_handle; + uint8_t adv_handle; + uint16_t sync_handle; } __packed; #define BT_HCI_EVT_SYNC_CONN_COMPLETE 0x2c @@ -3173,6 +3203,14 @@ struct bt_hci_evt_le_phy_update_complete { #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE 2 #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED 0xFF +/* Advertising Coding Selection extended advertising report PHY values. + * Only used when Kconfig BT_EXT_ADV_CODING_SELECTION is enabled. + */ +#define BT_HCI_LE_ADV_EVT_PHY_1M 0x01 +#define BT_HCI_LE_ADV_EVT_PHY_2M 0x02 +#define BT_HCI_LE_ADV_EVT_PHY_CODED_S8 0x03 +#define BT_HCI_LE_ADV_EVT_PHY_CODED_S2 0x04 + struct bt_hci_evt_le_ext_advertising_info { uint16_t evt_type; bt_addr_le_t addr; @@ -3448,7 +3486,7 @@ struct bt_hci_evt_le_biginfo_adv_report { #define BT_HCI_EVT_LE_SUBRATE_CHANGE 0x23 struct bt_hci_evt_le_subrate_change { - uint8_t status; + uint8_t status; uint16_t handle; uint16_t subrate_factor; uint16_t peripheral_latency; @@ -3456,6 +3494,32 @@ struct bt_hci_evt_le_subrate_change { uint16_t supervision_timeout; } __packed; +#define BT_HCI_EVT_LE_CIS_ESTABLISHED_V2 0x2a +struct bt_hci_evt_le_cis_established_v2 { + uint8_t status; + uint16_t conn_handle; + uint8_t cig_sync_delay[3]; + uint8_t cis_sync_delay[3]; + uint8_t c_latency[3]; + uint8_t p_latency[3]; + uint8_t c_phy; + uint8_t p_phy; + uint8_t nse; + uint8_t c_bn; + uint8_t p_bn; + uint8_t c_ft; + uint8_t p_ft; + uint16_t c_max_pdu; + uint16_t p_max_pdu; + uint16_t interval; + uint8_t sub_interval[3]; + uint16_t c_max_sdu; + uint16_t p_max_sdu; + uint8_t c_sdu_interval[3]; + uint8_t p_sdu_interval[3]; + uint8_t framing; +} __packed; + #define BT_HCI_LE_CS_INITIATOR_ROLE_MASK BIT(0) #define BT_HCI_LE_CS_REFLECTOR_ROLE_MASK BIT(1) @@ -3512,35 +3576,35 @@ struct bt_hci_evt_le_subrate_change { #define BT_HCI_EVT_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE 0x2C struct bt_hci_evt_le_cs_read_remote_supported_capabilities_complete { - uint8_t status; + uint8_t status; uint16_t conn_handle; - uint8_t num_config_supported; + uint8_t num_config_supported; uint16_t max_consecutive_procedures_supported; - uint8_t num_antennas_supported; - uint8_t max_antenna_paths_supported; - uint8_t roles_supported; - uint8_t modes_supported; - uint8_t rtt_capability; - uint8_t rtt_aa_only_n; - uint8_t rtt_sounding_n; - uint8_t rtt_random_payload_n; + uint8_t num_antennas_supported; + uint8_t max_antenna_paths_supported; + uint8_t roles_supported; + uint8_t modes_supported; + uint8_t rtt_capability; + uint8_t rtt_aa_only_n; + uint8_t rtt_sounding_n; + uint8_t rtt_random_payload_n; uint16_t nadm_sounding_capability; uint16_t nadm_random_capability; - uint8_t cs_sync_phys_supported; + uint8_t cs_sync_phys_supported; uint16_t subfeatures_supported; uint16_t t_ip1_times_supported; uint16_t t_ip2_times_supported; uint16_t t_fcs_times_supported; uint16_t t_pm_times_supported; - uint8_t t_sw_time_supported; - uint8_t tx_snr_capability; + uint8_t t_sw_time_supported; + uint8_t tx_snr_capability; } __packed; #define BT_HCI_EVT_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE 0x2D struct bt_hci_evt_le_cs_read_remote_fae_table_complete { - uint8_t status; + uint8_t status; uint16_t conn_handle; - int8_t remote_fae_table[72]; + int8_t remote_fae_table[72]; } __packed; #define BT_HCI_LE_CS_CONFIG_ACTION_REMOVED 0x00 @@ -3548,35 +3612,35 @@ struct bt_hci_evt_le_cs_read_remote_fae_table_complete { #define BT_HCI_EVT_LE_CS_SECURITY_ENABLE_COMPLETE 0x2E struct bt_hci_evt_le_cs_security_enable_complete { - uint8_t status; + uint8_t status; uint16_t handle; } __packed; #define BT_HCI_EVT_LE_CS_CONFIG_COMPLETE 0x2F struct bt_hci_evt_le_cs_config_complete { - uint8_t status; + uint8_t status; uint16_t handle; - uint8_t config_id; - uint8_t action; - uint8_t main_mode_type; - uint8_t sub_mode_type; - uint8_t min_main_mode_steps; - uint8_t max_main_mode_steps; - uint8_t main_mode_repetition; - uint8_t mode_0_steps; - uint8_t role; - uint8_t rtt_type; - uint8_t cs_sync_phy; - uint8_t channel_map[10]; - uint8_t channel_map_repetition; - uint8_t channel_selection_type; - uint8_t ch3c_shape; - uint8_t ch3c_jump; - uint8_t reserved; - uint8_t t_ip1_time; - uint8_t t_ip2_time; - uint8_t t_fcs_time; - uint8_t t_pm_time; + uint8_t config_id; + uint8_t action; + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t min_main_mode_steps; + uint8_t max_main_mode_steps; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t channel_map[10]; + uint8_t channel_map_repetition; + uint8_t channel_selection_type; + uint8_t ch3c_shape; + uint8_t ch3c_jump; + uint8_t reserved; + uint8_t t_ip1_time; + uint8_t t_ip2_time; + uint8_t t_fcs_time; + uint8_t t_pm_time; } __packed; #define BT_HCI_LE_CS_TEST_CONN_HANDLE 0x0FFF @@ -3646,14 +3710,14 @@ struct bt_hci_evt_le_cs_config_complete { /** Subevent result step data format: Mode 0 Initiator */ struct bt_hci_le_cs_step_data_mode_0_initiator { #ifdef CONFIG_LITTLE_ENDIAN - uint8_t packet_quality_aa_check: 4; - uint8_t packet_quality_bit_errors: 4; + uint8_t packet_quality_aa_check: 4; + uint8_t packet_quality_bit_errors: 4; #else - uint8_t packet_quality_bit_errors: 4; - uint8_t packet_quality_aa_check: 4; + uint8_t packet_quality_bit_errors: 4; + uint8_t packet_quality_aa_check: 4; #endif /* CONFIG_LITTLE_ENDIAN */ - uint8_t packet_rssi; - uint8_t packet_antenna; + uint8_t packet_rssi; + uint8_t packet_antenna; uint16_t measured_freq_offset; } __packed; @@ -3778,42 +3842,42 @@ struct bt_hci_evt_le_cs_subevent_result_step { struct bt_hci_evt_le_cs_subevent_result { uint16_t conn_handle; - uint8_t config_id; + uint8_t config_id; uint16_t start_acl_conn_event_counter; uint16_t procedure_counter; uint16_t frequency_compensation; - uint8_t reference_power_level; - uint8_t procedure_done_status; - uint8_t subevent_done_status; + uint8_t reference_power_level; + uint8_t procedure_done_status; + uint8_t subevent_done_status; #ifdef CONFIG_LITTLE_ENDIAN - uint8_t procedure_abort_reason: 4; - uint8_t subevent_abort_reason: 4; + uint8_t procedure_abort_reason: 4; + uint8_t subevent_abort_reason: 4; #else - uint8_t subevent_abort_reason: 4; - uint8_t procedure_abort_reason: 4; + uint8_t subevent_abort_reason: 4; + uint8_t procedure_abort_reason: 4; #endif /* CONFIG_LITTLE_ENDIAN */ - uint8_t num_antenna_paths; - uint8_t num_steps_reported; - uint8_t steps[]; + uint8_t num_antenna_paths; + uint8_t num_steps_reported; + uint8_t steps[]; } __packed; #define BT_HCI_EVT_LE_CS_SUBEVENT_RESULT_CONTINUE 0x32 struct bt_hci_evt_le_cs_subevent_result_continue { uint16_t conn_handle; - uint8_t config_id; - uint8_t procedure_done_status; - uint8_t subevent_done_status; + uint8_t config_id; + uint8_t procedure_done_status; + uint8_t subevent_done_status; #ifdef CONFIG_LITTLE_ENDIAN - uint8_t procedure_abort_reason: 4; - uint8_t subevent_abort_reason: 4; + uint8_t procedure_abort_reason: 4; + uint8_t subevent_abort_reason: 4; #else - uint8_t subevent_abort_reason: 4; - uint8_t procedure_abort_reason: 4; + uint8_t subevent_abort_reason: 4; + uint8_t procedure_abort_reason: 4; #endif /* CONFIG_LITTLE_ENDIAN */ - uint8_t num_antenna_paths; - uint8_t num_steps_reported; - uint8_t steps[]; + uint8_t num_antenna_paths; + uint8_t num_steps_reported; + uint8_t steps[]; } __packed; #define BT_HCI_EVT_LE_CS_TEST_END_COMPLETE 0x33 @@ -3823,14 +3887,14 @@ struct bt_hci_evt_le_cs_test_end_complete { #define BT_HCI_EVT_LE_CS_PROCEDURE_ENABLE_COMPLETE 0x30 struct bt_hci_evt_le_cs_procedure_enable_complete { - uint8_t status; + uint8_t status; uint16_t handle; - uint8_t config_id; - uint8_t state; - uint8_t tone_antenna_config_selection; - uint8_t selected_tx_power; - uint8_t subevent_len[3]; - uint8_t subevents_per_event; + uint8_t config_id; + uint8_t state; + uint8_t tone_antenna_config_selection; + uint8_t selected_tx_power; + uint8_t subevent_len[3]; + uint8_t subevents_per_event; uint16_t subevent_interval; uint16_t event_interval; uint16_t procedure_interval; @@ -3926,6 +3990,7 @@ struct bt_hci_evt_le_cs_procedure_enable_complete { #define BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ BT_EVT_BIT(38) #define BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT BT_EVT_BIT(39) #define BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2 BT_EVT_BIT(40) +#define BT_EVT_MASK_LE_CIS_ESTABLISHED_V2 BT_EVT_BIT(41) #define BT_EVT_MASK_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE BT_EVT_BIT(43) #define BT_EVT_MASK_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE BT_EVT_BIT(44) diff --git a/include/zephyr/bluetooth/iso.h b/include/zephyr/bluetooth/iso.h index 4251a2c87cb1a..ff62661b9e8f0 100644 --- a/include/zephyr/bluetooth/iso.h +++ b/include/zephyr/bluetooth/iso.h @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -67,6 +68,8 @@ extern "C" { /** Value to set the ISO data path over HCi. */ #define BT_ISO_DATA_PATH_HCI 0x00 +/** Unknown SDU interval */ +#define BT_ISO_SDU_INTERVAL_UNKNOWN 0x000000U /** Minimum interval value in microseconds */ #define BT_ISO_SDU_INTERVAL_MIN 0x0000FFU /** Maximum interval value in microseconds */ @@ -139,6 +142,10 @@ extern "C" { #define BT_ISO_PTO_MIN 0x00U /** Maximum pre-transmission offset */ #define BT_ISO_PTO_MAX 0x0FU +/** No subinterval */ +#define BT_ISO_SUBINTERVAL_NONE 0x00000000U +/** Unknown subinterval */ +#define BT_ISO_SUBINTERVAL_UNKNOWN 0xFFFFFFFFU /** * @brief Check if ISO BIS bitfield is valid (BT_ISO_BIS_INDEX_BIT(1)|..|BT_ISO_BIS_INDEX_BIT(31)) @@ -966,6 +973,18 @@ struct bt_iso_unicast_tx_info { /** The burst number */ uint8_t bn; + + /** The maximum SDU size in octets + * + * May be set to @ref bt_iso_unicast_tx_info.max_pdu for peripherals if unknown + */ + uint16_t max_sdu; + + /** The SDU interval in microseconds + * + * May be set to @ref BT_ISO_SDU_INTERVAL_UNKNOWN for if unknown. + */ + uint32_t sdu_interval; }; /** @brief ISO Unicast Info Structure */ @@ -976,6 +995,14 @@ struct bt_iso_unicast_info { /** The maximum time in us for all PDUs of this CIS in a CIG event */ uint32_t cis_sync_delay; + /** + * @brief The subinterval in microseconds + * + * Will be @ref BT_ISO_SUBINTERVAL_NONE if there is no subinterval (NSE = 1). + * Will be @ref BT_ISO_SUBINTERVAL_UNKNOWN if unknown. + */ + uint32_t subinterval; + /** @brief TX information for the central to peripheral data path */ struct bt_iso_unicast_tx_info central; @@ -1102,6 +1129,42 @@ int bt_iso_chan_get_info(const struct bt_iso_chan *chan, struct bt_iso_info *inf */ int bt_iso_chan_get_tx_sync(const struct bt_iso_chan *chan, struct bt_iso_tx_info *info); +/** + * @brief Struct to hold the Broadcast Isochronous Group callbacks + * + * These can be registered for usage with bt_iso_big_register_cb(). + */ +struct bt_iso_big_cb { + /** + * @brief The BIG has started and all of the streams are ready for data + * + * @param big The started BIG + */ + void (*started)(struct bt_iso_big *big); + + /** + * @brief The BIG has stopped and none of the streams are ready for data + * + * @param big The stopped BIG + * @param reason The reason why the BIG stopped (see the BT_HCI_ERR_* values) + */ + void (*stopped)(struct bt_iso_big *big, uint8_t reason); + + /** @internal Internally used field for list handling */ + sys_snode_t _node; +}; + +/** + * @brief Registers callbacks for Broadcast Sources + * + * @param cb Pointer to the callback structure. + * + * @retval 0 on success + * @retval -EINVAL if @p cb is NULL + * @retval -EEXIST if @p cb is already registered + */ +int bt_iso_big_register_cb(struct bt_iso_big_cb *cb); + /** * @brief Creates a BIG as a broadcaster * diff --git a/include/zephyr/bluetooth/l2cap.h b/include/zephyr/bluetooth/l2cap.h index 8358d62c309ff..c510ac26eebe4 100644 --- a/include/zephyr/bluetooth/l2cap.h +++ b/include/zephyr/bluetooth/l2cap.h @@ -490,7 +490,7 @@ struct bt_l2cap_chan_ops { struct bt_l2cap_server { /** @brief Server PSM. * - * Possible values: + * For LE, possible values: * 0 A dynamic value will be auto-allocated when * bt_l2cap_server_register() is called. * @@ -500,6 +500,22 @@ struct bt_l2cap_server { * application before server registration (not * recommended however), or auto-allocated by the * stack if the app gave 0 as the value. + * + * For BR, possible values: + * + * The PSM field is at least two octets in length. All PSM values shall have the least + * significant bit of the most significant octet equal to 0 and the least significant bit + * of all other octets equal to 1. + * + * 0 A dynamic value will be auto-allocated when + * bt_l2cap_br_server_register() is called. + * + * 0x0001-0x0eff Standard, Bluetooth SIG-assigned fixed values. + * + * > 0x1000 Dynamically allocated. May be pre-set by the + * application before server registration (not + * recommended however), or auto-allocated by the + * stack if the app gave 0 as the value. */ uint16_t psm; @@ -556,6 +572,15 @@ int bt_l2cap_server_register(struct bt_l2cap_server *server); * the accept() callback which in case of success shall allocate the channel * structure to be used by the new connection. * + * For fixed, SIG-assigned PSMs (in the range 0x0001-0x0eff) the PSM should + * be assigned to server->psm before calling this API. For dynamic PSMs + * (in the range 0x1000-0xffff) server->psm may be pre-set to a given value + * (this is however not recommended) or be left as 0, in which case upon + * return a newly allocated value will have been assigned to it. For + * dynamically allocated values the expectation is that it's exposed through + * a SDP record, and that's how L2CAP clients discover how to connect to + * the server. + * * @param server Server structure. * * @return 0 in case of success or negative value in case of error. diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index db477ee6206bf..71aa89db0ef3c 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -628,7 +628,7 @@ struct bt_mesh_model_op { * @return Mesh transmit value that can be used e.g. for the default * values of the configuration model data. */ -#define BT_MESH_TRANSMIT(count, int_ms) ((count) | (((int_ms / 10) - 1) << 3)) +#define BT_MESH_TRANSMIT(count, int_ms) ((uint8_t)((count) | (((int_ms / 10) - 1) << 3))) /** * @brief Decode transmit count from a transmit value. diff --git a/include/zephyr/bluetooth/mesh/health_cli.h b/include/zephyr/bluetooth/mesh/health_cli.h index 2d8904ea6f279..e0ee06eb24f2c 100644 --- a/include/zephyr/bluetooth/mesh/health_cli.h +++ b/include/zephyr/bluetooth/mesh/health_cli.h @@ -99,6 +99,22 @@ struct bt_mesh_health_cli { uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count); + /** @brief Optional callback for updating the message to be sent as periodic publication. + * + * This callback is called before sending the periodic publication message. + * The callback can be used to update the message to be sent. + * + * If this callback is not implemented, periodic publication can still be enabled, + * but no messages will be sent. + * + * @param cli Health client that is sending the periodic publication message. + * @param pub_buf Publication message buffer to be updated. + * + * @return 0 if @p pub_buf is updated successfully, or (negative) error code on failure. + * The message won't be sent if an error is returned. + */ + int (*update)(struct bt_mesh_health_cli *cli, struct net_buf_simple *pub_buf); + /* Internal parameters for tracking message responses. */ struct bt_mesh_msg_ack_ctx ack_ctx; }; diff --git a/include/zephyr/bluetooth/mesh/statistic.h b/include/zephyr/bluetooth/mesh/statistic.h index c5403d2fd5462..288cd77ff8ff3 100644 --- a/include/zephyr/bluetooth/mesh/statistic.h +++ b/include/zephyr/bluetooth/mesh/statistic.h @@ -1,5 +1,5 @@ /** @file - * @brief BLE mesh statistic APIs. + * @brief Bluetooth Mesh statistic APIs. */ /* @@ -51,7 +51,7 @@ struct bt_mesh_statistic { /** @brief Get mesh frame handling statistic. * - * @param st BLE mesh statistic. + * @param st Bluetooh Mesh statistic. */ void bt_mesh_stat_get(struct bt_mesh_statistic *st); diff --git a/include/zephyr/data/navigation.h b/include/zephyr/data/navigation.h index 0759df984ea43..a091528094215 100644 --- a/include/zephyr/data/navigation.h +++ b/include/zephyr/data/navigation.h @@ -31,7 +31,7 @@ struct navigation_data { uint32_t bearing; /** Speed in millimeters per second */ uint32_t speed; - /** Altitude in millimeters */ + /** Altitude above MSL in millimeters */ int32_t altitude; }; diff --git a/include/zephyr/device.h b/include/zephyr/device.h index 13cd31f326f9b..57c628b94e94e 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -101,9 +101,35 @@ typedef int16_t device_handle_t; * The ordinal used in this name can be mapped to the path by * examining zephyr/include/generated/zephyr/devicetree_generated.h. */ -#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id)) +#define Z_DEVICE_DT_DEP_ORD(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id)) -#if defined(CONFIG_LLEXT_EXPORT_DEVICES) +/* Same as above, but uses the hash of the node path instead of the ordinal. + * + * The hash used in this name can be mapped to the path by + * examining zephyr/include/generated/zephyr/devicetree_generated.h. + */ +#define Z_DEVICE_DT_HASH(node_id) _CONCAT(dts_, DT_NODE_HASH(node_id)) + +/* By default, device identifiers are obtained using the dependency ordinal. + * When LLEXT_EXPORT_DEV_IDS_BY_HASH is defined, the main Zephyr binary exports + * DT identifiers via EXPORT_SYMBOL_NAMED as hashed versions of their paths. + * When matching extensions are built, that is what they need to look for. + * + * The ordinal or hash used in this name can be mapped to the path by + * examining zephyr/include/generated/zephyr/devicetree_generated.h. + */ +#if defined(LL_EXTENSION_BUILD) && defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH) +#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_HASH(node_id) +#else +#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_DEP_ORD(node_id) +#endif + +#if defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH) +/* Export device identifiers by hash */ +#define Z_DEVICE_EXPORT(node_id) \ + EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \ + DEVICE_NAME_GET(Z_DEVICE_DT_HASH(node_id))) +#elif defined(CONFIG_LLEXT_EXPORT_DEVICES) /* Export device identifiers using the builtin name */ #define Z_DEVICE_EXPORT(node_id) EXPORT_SYMBOL(DEVICE_DT_NAME_GET(node_id)) #endif @@ -175,8 +201,8 @@ typedef int16_t device_handle_t; * * This macro defines a @ref device that is automatically configured by the * kernel during system initialization. The global device object's name as a C - * identifier is derived from the node's dependency ordinal. @ref device.name is - * set to `DEVICE_DT_NAME(node_id)`. + * identifier is derived from the node's dependency ordinal or hash. + * @ref device.name is set to `DEVICE_DT_NAME(node_id)`. * * The device is declared with extern visibility, so a pointer to a global * device object can be obtained with `DEVICE_DT_GET(node_id)` from any source @@ -207,8 +233,7 @@ typedef int16_t device_handle_t; DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \ level, prio, api, \ &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \ - __VA_ARGS__) \ - IF_ENABLED(CONFIG_LLEXT_EXPORT_DEVICES, (Z_DEVICE_EXPORT(node_id);)) + __VA_ARGS__) /** * @brief Like DEVICE_DT_DEFINE(), but uses an instance of a `DT_DRV_COMPAT` @@ -321,6 +346,22 @@ typedef int16_t device_handle_t; COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(node_id), \ (DEVICE_DT_GET(node_id)), (NULL)) +/** + * @brief Get a @ref device reference from a devicetree phandles by idx. + * + * Returns a pointer to a device object referenced by a phandles property, by idx. + * + * @param node_id A devicetree node identifier + * @param prop lowercase-and-underscores property with type `phandle`, + * `phandles`, or `phandle-array` + * @param idx logical index into @p phs, which must be zero if @p phs + * has type `phandle` + * + * @return A pointer to the device object created for that node + */ +#define DEVICE_DT_GET_BY_IDX(node_id, prop, idx) \ + DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)) + /** * @brief Obtain a pointer to a device object by name * @@ -1172,12 +1213,15 @@ device_get_dt_nodelabels(const struct device *dev) (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\ \ Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \ - prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \ + prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \ COND_CODE_1(DEVICE_DT_DEFER(node_id), \ (Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, \ init_fn)), \ (Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, \ - level, prio))); + level, prio))); \ + IF_ENABLED(CONFIG_LLEXT_EXPORT_DEVICES, \ + (IF_ENABLED(DT_NODE_EXISTS(node_id), \ + (Z_DEVICE_EXPORT(node_id);)))) /** * @brief Declare a device for each status "okay" devicetree node. diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index 3b50512f50688..2b10eaf8d4875 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -242,6 +242,16 @@ */ #define DT_HAS_ALIAS(alias_name) DT_NODE_EXISTS(DT_ALIAS(alias_name)) +/** + * @brief Get the hash associated with a DT node + * + * Get the hash for the specified node_id. The hash is calculated on the + * full devicetree path of the node. + * @param node_id node identifier + * @return hash value as a preprocessor token + */ +#define DT_NODE_HASH(node_id) DT_CAT(node_id, _HASH) + /** * @brief Get a node identifier for an instance of a compatible * @@ -898,6 +908,17 @@ #define DT_PROP_BY_IDX(node_id, prop, idx) \ DT_CAT5(node_id, _P_, prop, _IDX_, idx) +/** + * @brief Get the last element of an array type property + * + * @param node_id node identifier + * @param prop lowercase-and-underscores property name + * + * @return a representation of the last element of the property + */ +#define DT_PROP_LAST(node_id, prop) \ + DT_PROP_BY_IDX(node_id, prop, UTIL_DEC(DT_PROP_LEN(node_id, prop))) + /** * @brief Like DT_PROP(), but with a fallback to @p default_value * @@ -2908,6 +2929,36 @@ * @defgroup devicetree-generic-foreach "For-each" macros * @ingroup devicetree * @{ + * + * IMPORTANT: you can't use the DT for-each macros in their own expansions. + * + * For example, something like this won't work the way you might expect: + * + * @code{.c} + * #define FOO(node_id) [...] DT_FOREACH_NODE(...) [...] + * DT_FOREACH_NODE(FOO) + * @endcode + * + * In this example, the C preprocessor won't expand the + * DT_FOREACH_NODE() macro inside of FOO() while it's already + * expanding DT_FOREACH_NODE() at the top level of the file. + * + * This is true of any macro, not just DT_FOREACH_NODE(). The C + * language works this way to avoid infinite recursions inside of + * macro expansions. + * + * If you need to "nest" calls to one of these macros, you can work + * around this preprocessor limitation by using a different, related + * macro instead, like this: + * + * @code{.c} + * #define BAR(node_id) [...] DT_FOREACH_NODE_VARGS(...) [...] + * DT_FOREACH_NODE(BAR) + * @endcode + * + * Here, we use DT_FOREACH_NODE_VARGS() "inside" BAR() "inside" + * DT_FOREACH_NODE(). Because of this, the preprocessor will expand + * both DT_FOREACH_NODE_VARGS() and DT_FOREACH_NODE() as expected. */ /** @@ -2964,6 +3015,55 @@ */ #define DT_FOREACH_STATUS_OKAY_NODE_VARGS(fn, ...) DT_FOREACH_OKAY_VARGS_HELPER(fn, __VA_ARGS__) +/** + * @brief Invokes @p fn for each ancestor of @p node_id + * + * The macro @p fn must take one parameter, which will be the identifier + * of a child node of @p node_id to enable traversal of all ancestor nodes. + * + * The ancestor will be iterated over in the same order as they + * appear in the final devicetree. + * + * Example devicetree fragment: + * + * @code{.dts} + * n: node1 { + * foobar = "foo1"; + * + * n_2: node2 { + * foobar = "foo2"; + * + * n_3: node3 { + * foobar = "foo3"; + * }; + * }; + * }; + * @endcode + * + * Example usage: + * + * @code{.c} + * #define GET_PROP(n) DT_PROP(n, foobar), + * + * const char *ancestor_names[] = { + * DT_FOREACH_ANCESTOR(DT_NODELABEL(n_3), GET_PROP) + * }; + * @endcode + * + * This expands to: + * + * @code{.c} + * const char *ancestor_names[] = { + * "foo2", "foo1", + * }; + * @endcode + * + * @param node_id node identifier + * @param fn macro to invoke + */ +#define DT_FOREACH_ANCESTOR(node_id, fn) \ + DT_CAT(node_id, _FOREACH_ANCESTOR)(fn) + /** * @brief Invokes @p fn for each child of @p node_id * @@ -4605,7 +4705,7 @@ #define DT_INST_STRING_UNQUOTED_OR(inst, name, default_value) \ DT_STRING_UNQUOTED_OR(DT_DRV_INST(inst), name, default_value) -/* +/** * @brief Test if any enabled node with the given compatible is on * the given bus type * @@ -5242,5 +5342,6 @@ #include #include #include +#include #endif /* ZEPHYR_INCLUDE_DEVICETREE_H_ */ diff --git a/include/zephyr/devicetree/port-endpoint.h b/include/zephyr/devicetree/port-endpoint.h new file mode 100644 index 0000000000000..08ff0ee35fa47 --- /dev/null +++ b/include/zephyr/devicetree/port-endpoint.h @@ -0,0 +1,275 @@ +/** + * @file + * @brief Port / Endpoint Devicetree macro public API header file. + */ + +/* + * Copyright 2024 NXP + * Copyright (c) 2024 tinyVision.ai Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DEVICETREE_PORT_ENDPOINT_H_ +#define ZEPHYR_INCLUDE_DEVICETREE_PORT_ENDPOINT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup devicetree-port-endpoint Devicetree Port Endpoint API + * @ingroup devicetree + * @{ + */ + +/** + * @brief Helper for @ref DT_INST_PORT_BY_ID + * + * This behaves the same way as @ref DT_INST_PORT_BY_ID but does not work if there is only + * a single port without address. + * + * @param inst instance number + * @param pid port ID + * @return port node associated with @p pid + */ +#define _DT_INST_PORT_BY_ID(inst, pid) \ + COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(inst, ports)), \ + (DT_CHILD(DT_INST_CHILD(inst, ports), port_##pid)), (DT_INST_CHILD(inst, port_##pid))) + +/** + * @brief Get a port node from its id + * + * Given a device instance number, return a port node specified by its ID. + * It handles various ways of how a port could be defined. + * + * Example usage with DT_INST_PORT_BY_ID() to get the @c port@0 or @c port node: + * + * @code{.c} + * DT_INST_PORT_BY_ID(inst, 0) + * @endcode + * + * Example devicetree fragment: + * + * @code{.dts} + * &device { + * ports { + * #address-cells = <1>; + * #size-cells = <0>; + * port@0 { + * reg = <0x0>; + * }; + * }; + * }; + * @endcode + * + * @code{.dts} + * &device { + * #address-cells = <1>; + * #size-cells = <0>; + * port@0 { + * reg = <0x0>; + * }; + * }; + * @endcode + * + * @code{.dts} + * &device { + * port { + * }; + * }; + * @endcode + * + * @param inst instance number + * @param pid port ID + * @return port node associated with @p pid + */ +#define DT_INST_PORT_BY_ID(inst, pid) \ + COND_CODE_1(DT_NODE_EXISTS(_DT_INST_PORT_BY_ID(inst, pid)), \ + (_DT_INST_PORT_BY_ID(inst, pid)), (DT_INST_CHILD(inst, port))) + +/** + * @brief Helper for @ref DT_INST_ENDPOINT_BY_ID + * + * This behaves the same way as @ref DT_INST_PORT_BY_ID but does not work if there is only + * a single endpoint without address. + * + * @param inst instance number + * @param pid port ID + * @param eid endpoint ID + * @return endpoint node associated with @p eid and @p pid + */ +#define _DT_INST_ENDPOINT_BY_ID(inst, pid, eid) \ + DT_CHILD(DT_INST_PORT_BY_ID(inst, pid), endpoint_##eid) + +/** + * @brief Get an endpoint node from its id and its parent port id + * + * Given a device instance number, a port ID and an endpoint ID, return the endpoint node. + * It handles various ways of how a port and an endpoint could be defined as described in + * @ref DT_INST_PORT_BY_ID and below. + * + * Example usage with DT_INST_ENDPOINT_BY_ID() to get the @c endpoint or @c endpoint@0 node: + * + * @code{.c} + * DT_INST_ENDPOINT_BY_ID(inst, 0, 0) + * @endcode + * + * Example devicetree fragment: + * + * @code{.dts} + * &device { + * port { + * endpoint { + * }; + * }; + * }; + * @endcode + * + * @code{.dts} + * &device { + * port { + * #address-cells = <1>; + * #size-cells = <0>; + * endpoint@0 { + * reg = <0x0>; + * }; + * }; + * }; + * @endcode + * + * @code{.dts} + * &device { + * ports { + * #address-cells = <1>; + * #size-cells = <0>; + * port@0 { + * reg = <0x0>; + * #address-cells = <1>; + * #size-cells = <0>; + * endpoint@0 { + * reg = <0x0>; + * }; + * }; + * }; + * }; + * @endcode + * + * @param inst instance number + * @param pid port ID + * @param eid endpoint ID + * @return endpoint node associated with @p eid and @p pid + */ +#define DT_INST_ENDPOINT_BY_ID(inst, pid, eid) \ + COND_CODE_1(DT_NODE_EXISTS(_DT_INST_ENDPOINT_BY_ID(inst, pid, eid)), \ + (_DT_INST_ENDPOINT_BY_ID(inst, pid, eid)), \ + (DT_CHILD(DT_INST_PORT_BY_ID(inst, pid), endpoint))) + +/** + * @brief Get the device node from its endpoint node. + * + * Given an endpoint node id, return its device node id. + * This handles various ways of how a port and an endpoint could be defined as described in + * @ref DT_NODE_BY_ENDPOINT. + * + * Example usage with DT_NODE_BY_ENDPOINT() to get the @c &device node from its @c ep0 node: + * + * @code{.c} + * DT_NODE_BY_ENDPOINT(DT_NODELABEL(ep0)) + * @endcode + * + * Example devicetree fragment: + * + * @code{.dts} + * &device { + * port { + * #address-cells = <1>; + * #size-cells = <0>; + * ep0: endpoint@0 { + * reg = <0x0>; + * }; + * }; + * }; + * @endcode + * + * @code{.dts} + * &device { + * ports { + * #address-cells = <1>; + * #size-cells = <0>; + * port@0 { + * reg = <0x0>; + * #address-cells = <1>; + * #size-cells = <0>; + * ep0: endpoint@0 { + * reg = <0x0>; + * }; + * }; + * }; + * }; + * @endcode + * + * @param ep endpoint node + * @return device node associated with @p ep + */ +#define DT_NODE_BY_ENDPOINT(ep) \ + COND_CODE_1(DT_NODE_EXISTS(DT_CHILD(DT_PARENT(DT_GPARENT(ep)), ports)), \ + (DT_PARENT(DT_GPARENT(ep))), (DT_GPARENT(ep))) + +/** + * @brief Get the remote device node from a local endpoint node. + * + * Given an endpoint node id, return the remote device node that connects to this device via this + * local endpoint. This handles various ways of how a port and an endpoint could be defined as + * described in @ref DT_INST_PORT_BY_ID and @ref DT_INST_ENDPOINT_BY_ID. + * + * Example usage with DT_NODE_REMOTE_DEVICE() to get the remote device node @c &device1 from the + * local endpoint @c endpoint@0 node of the device @c &device0 node: + * + * @code{.c} + * DT_NODE_REMOTE_DEVICE(DT_NODELABEL(device0_ep_out)) + * @endcode + * + * Example devicetree fragment: + * + * @code{.dts} + * &device0 { + * port { + * #address-cells = <1>; + * #size-cells = <0>; + * device0_ep_out: endpoint@0 { + * reg = <0x0>; + * remote-endpoint-label = "device1_ep_in"; + * }; + * }; + * }; + * + * &device1 { + * ports { + * #address-cells = <1>; + * #size-cells = <0>; + * port@0 { + * reg = <0x0>; + * device1_ep_in: endpoint { + * remote-endpoint-label = "device0_ep_out"; + * }; + * }; + * }; + * }; + * @endcode + * + * @param ep endpoint node + * @return remote device node that connects to this device via @p ep + */ +#define DT_NODE_REMOTE_DEVICE(ep) \ + DT_NODE_BY_ENDPOINT(DT_NODELABEL(DT_STRING_TOKEN(ep, remote_endpoint_label))) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DEVICETREE_PORT_ENDPOINT_H_ */ diff --git a/include/zephyr/dfu/flash_img.h b/include/zephyr/dfu/flash_img.h index 004468526093d..8ae5fe52e477f 100644 --- a/include/zephyr/dfu/flash_img.h +++ b/include/zephyr/dfu/flash_img.h @@ -111,6 +111,13 @@ int flash_img_check(struct flash_img_context *ctx, const struct flash_img_check *fic, uint8_t area_id); +/** + * @brief Get the flash area id for the image upload slot. + * + * @return flash area id for the image upload slot + */ +uint8_t flash_img_get_upload_slot(void); + #ifdef __cplusplus } #endif diff --git a/include/zephyr/dfu/mcuboot.h b/include/zephyr/dfu/mcuboot.h index fe15f769f98ee..efd8c83b26b0a 100644 --- a/include/zephyr/dfu/mcuboot.h +++ b/include/zephyr/dfu/mcuboot.h @@ -81,6 +81,8 @@ extern "C" { #define BOOT_IMG_VER_STRLEN_MAX 25 /* 255.255.65535.4294967295\0 */ +/** Sector at which firmware update should be placed by application in swap using offset mode */ +#define SWAP_USING_OFFSET_SECTOR_UPDATE_BEGIN 1 /** * @brief MCUboot image header representation for image version @@ -159,6 +161,13 @@ int boot_read_bank_header(uint8_t area_id, struct mcuboot_img_header *header, size_t header_size); +/** + * @brief Get the flash area id for the active image slot. + * + * @return flash area id for the active image slot + */ +uint8_t boot_fetch_active_slot(void); + /** * @brief Check if the currently running image is confirmed as OK. * @@ -280,6 +289,20 @@ ssize_t boot_get_area_trailer_status_offset(uint8_t area_id); */ ssize_t boot_get_trailer_status_offset(size_t area_size); +#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_USING_OFFSET) || defined(__DOXYGEN__) +/** + * @brief Get the offset of the image header, this should be used in swap using offset mode to + * account for the secondary slot data starting in the first or second sector, depending + * upon the current state + * + * @param area_id flash_area ID of image bank to get the status offset + * @return offset of the image header + */ +size_t boot_get_image_start_offset(uint8_t area_id); +#else +#define boot_get_image_start_offset(...) 0 +#endif + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/adc.h b/include/zephyr/drivers/adc.h index 1c95baa9707c5..7eabbe179371c 100644 --- a/include/zephyr/drivers/adc.h +++ b/include/zephyr/drivers/adc.h @@ -35,6 +35,7 @@ enum adc_gain { ADC_GAIN_1_6, /**< x 1/6. */ ADC_GAIN_1_5, /**< x 1/5. */ ADC_GAIN_1_4, /**< x 1/4. */ + ADC_GAIN_2_7, /**< x 2/7. */ ADC_GAIN_1_3, /**< x 1/3. */ ADC_GAIN_2_5, /**< x 2/5. */ ADC_GAIN_1_2, /**< x 1/2. */ diff --git a/include/zephyr/drivers/adc/adc_emul.h b/include/zephyr/drivers/adc/adc_emul.h index 03c2fbbb3fd0d..9c95dd8ab4dd9 100644 --- a/include/zephyr/drivers/adc/adc_emul.h +++ b/include/zephyr/drivers/adc/adc_emul.h @@ -72,6 +72,18 @@ typedef int (*adc_emul_value_func)(const struct device *dev, unsigned int chan, int adc_emul_const_value_set(const struct device *dev, unsigned int chan, uint32_t value); +/** + * @brief Set constant raw value input for emulated ADC @p chan + * + * @param dev The emulated ADC device + * @param chan The channel of ADC which input is assigned + * @param raw_value New raw value to assign to @p chan input + * + * @return 0 on success + * @return -EINVAL if an invalid argument is provided + */ +int adc_emul_const_raw_value_set(const struct device *dev, unsigned int chan, uint32_t raw_value); + /** * @brief Set function used to obtain voltage for input of emulated * ADC @p chan @@ -87,6 +99,21 @@ int adc_emul_const_value_set(const struct device *dev, unsigned int chan, int adc_emul_value_func_set(const struct device *dev, unsigned int chan, adc_emul_value_func func, void *data); +/** + * @brief Set function used to obtain voltage for raw input value of emulated + * ADC @p chan + * + * @param dev The emulated ADC device + * @param chan The channel of ADC to which @p func is assigned + * @param func New function to assign to @p chan + * @param data Pointer to data passed to @p func on call + * + * @return 0 on success + * @return -EINVAL if an invalid argument is provided + */ +int adc_emul_raw_value_func_set(const struct device *dev, unsigned int chan, + adc_emul_value_func func, void *data); + /** * @brief Set reference voltage * diff --git a/include/zephyr/drivers/adc/ads114s0x.h b/include/zephyr/drivers/adc/ads114s0x.h deleted file mode 100644 index af8cae7a96a5b..0000000000000 --- a/include/zephyr/drivers/adc/ads114s0x.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2023 SILA Embedded Solutions GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_ADS114S0X_H_ -#define ZEPHYR_INCLUDE_DRIVERS_ADC_ADS114S0X_H_ - -#include -#include - -int ads114s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value); - -int ads114s0x_gpio_set_input(const struct device *dev, uint8_t pin); - -int ads114s0x_gpio_deconfigure(const struct device *dev, uint8_t pin); - -int ads114s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin, - bool value); - -int ads114s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin, - bool *value); - -int ads114s0x_gpio_port_get_raw(const struct device *dev, - gpio_port_value_t *value); - -int ads114s0x_gpio_port_set_masked_raw(const struct device *dev, - gpio_port_pins_t mask, - gpio_port_value_t value); - -int ads114s0x_gpio_port_toggle_bits(const struct device *dev, - gpio_port_pins_t pins); - -#endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_ADS114S0X_H_ */ diff --git a/include/zephyr/drivers/adc/ads131m02.h b/include/zephyr/drivers/adc/ads131m02.h new file mode 100644 index 0000000000000..978684774025d --- /dev/null +++ b/include/zephyr/drivers/adc/ads131m02.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Linumiz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_ADS131M02_H_ +#define ZEPHYR_INCLUDE_DRIVERS_ADC_ADS131M02_H_ + +#include + +enum ads131m02_adc_mode { + ADS131M02_CONTINUOUS_MODE, /* Continuous conversion mode */ + ADS131M02_GLOBAL_CHOP_MODE /* Global chop mode */ +}; + +enum ads131m02_adc_power_mode { + ADS131M02_VLP, /* Very Low Power */ + ADS131M02_LP, /* Low Power */ + ADS131M02_HR /* High Resolution */ +}; + +enum ads131m02_gc_delay { + ADS131M02_GC_DELAY_2, + ADS131M02_GC_DELAY_4, + ADS131M02_GC_DELAY_8, + ADS131M02_GC_DELAY_16, + ADS131M02_GC_DELAY_32, + ADS131M02_GC_DELAY_64, + ADS131M02_GC_DELAY_128, + ADS131M02_GC_DELAY_256, + ADS131M02_GC_DELAY_512, + ADS131M02_GC_DELAY_1024, + ADS131M02_GC_DELAY_2048, + ADS131M02_GC_DELAY_4096, + ADS131M02_GC_DELAY_8192, + ADS131M02_GC_DELAY_16384, + ADS131M02_GC_DELAY_32768, + ADS131M02_GC_DELAY_65536 +}; + +int ads131m02_set_adc_mode(const struct device *dev, enum ads131m02_adc_mode mode, + enum ads131m02_gc_delay gc_delay); + +int ads131m02_set_power_mode(const struct device *dev, + enum ads131m02_adc_power_mode mode); + +#endif diff --git a/include/zephyr/drivers/adc/ads1x4s0x.h b/include/zephyr/drivers/adc/ads1x4s0x.h new file mode 100644 index 0000000000000..2f4c7a1482903 --- /dev/null +++ b/include/zephyr/drivers/adc/ads1x4s0x.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_ADS1X4S0X_H_ +#define ZEPHYR_INCLUDE_DRIVERS_ADC_ADS1X4S0X_H_ + +#include +#include + +int ads1x4s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value); + +int ads1x4s0x_gpio_set_input(const struct device *dev, uint8_t pin); + +int ads1x4s0x_gpio_deconfigure(const struct device *dev, uint8_t pin); + +int ads1x4s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin, + bool value); + +int ads1x4s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin, + bool *value); + +int ads1x4s0x_gpio_port_get_raw(const struct device *dev, + gpio_port_value_t *value); + +int ads1x4s0x_gpio_port_set_masked_raw(const struct device *dev, + gpio_port_pins_t mask, + gpio_port_value_t value); + +int ads1x4s0x_gpio_port_toggle_bits(const struct device *dev, + gpio_port_pins_t pins); + +#endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_ADS1X4S0X_H_ */ diff --git a/include/zephyr/drivers/clock_control/adi_max32_clock_control.h b/include/zephyr/drivers/clock_control/adi_max32_clock_control.h index cd889d370b252..0f1e7b128823e 100644 --- a/include/zephyr/drivers/clock_control/adi_max32_clock_control.h +++ b/include/zephyr/drivers/clock_control/adi_max32_clock_control.h @@ -41,7 +41,7 @@ struct max32_perclk { #define ADI_MAX32_CLK_IPO_FREQ DT_PROP(DT_NODELABEL(clk_ipo), clock_frequency) #define ADI_MAX32_CLK_ERFO_FREQ DT_PROP_OR(DT_NODELABEL(clk_erfo), clock_frequency, 0) -#define ADI_MAX32_CLK_IBRO_FREQ DT_PROP(DT_NODELABEL(clk_ibro), clock_frequency) +#define ADI_MAX32_CLK_IBRO_FREQ DT_PROP_OR(DT_NODELABEL(clk_ibro), clock_frequency, 0) #define ADI_MAX32_CLK_ISO_FREQ DT_PROP_OR(DT_NODELABEL(clk_iso), clock_frequency, 0) #define ADI_MAX32_CLK_INRO_FREQ DT_PROP(DT_NODELABEL(clk_inro), clock_frequency) #define ADI_MAX32_CLK_ERTCO_FREQ DT_PROP(DT_NODELABEL(clk_ertco), clock_frequency) diff --git a/include/zephyr/drivers/clock_control/clock_control_rts5912.h b/include/zephyr/drivers/clock_control/clock_control_rts5912.h new file mode 100644 index 0000000000000..381502bf7c1f1 --- /dev/null +++ b/include/zephyr/drivers/clock_control/clock_control_rts5912.h @@ -0,0 +1,20 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#include + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_RTS5912_H_ +#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_RTS5912_H_ + +struct rts5912_sccon_subsys { + uint32_t clk_grp; + uint32_t clk_idx; + uint32_t clk_src; + uint32_t clk_div; +}; + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_RTS591X_H_ */ diff --git a/include/zephyr/drivers/clock_control/clock_control_silabs.h b/include/zephyr/drivers/clock_control/clock_control_silabs.h index d608b1da5b084..b893c82aa5656 100644 --- a/include/zephyr/drivers/clock_control/clock_control_silabs.h +++ b/include/zephyr/drivers/clock_control/clock_control_silabs.h @@ -13,10 +13,14 @@ #include #elif defined(CONFIG_SOC_SERIES_EFR32BG22) #include +#elif defined(CONFIG_SOC_SERIES_EFR32ZG23) +#include #elif defined(CONFIG_SOC_SERIES_EFR32MG24) #include #elif defined(CONFIG_SOC_SERIES_EFR32BG27) #include +#elif defined(CONFIG_SOC_SERIES_EFR32BG29) || defined(CONFIG_SOC_SERIES_EFR32MG29) +#include #endif struct silabs_clock_control_cmu_config { diff --git a/include/zephyr/drivers/clock_control/nrf_clock_control.h b/include/zephyr/drivers/clock_control/nrf_clock_control.h index b7764b91a86f3..866b4fe2ee1bb 100644 --- a/include/zephyr/drivers/clock_control/nrf_clock_control.h +++ b/include/zephyr/drivers/clock_control/nrf_clock_control.h @@ -8,7 +8,7 @@ #define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_NRF_CLOCK_CONTROL_H_ #include -#ifdef NRF_CLOCK +#if defined(NRF_CLOCK) && !defined(NRF_LFRC) #include #endif #include @@ -117,6 +117,13 @@ int z_nrf_clock_calibration_count(void); */ int z_nrf_clock_calibration_skips_count(void); + +/** @brief Returns information if LF clock calibration is in progress. + * + * @return True if calibration is in progress, false otherwise. + */ +bool z_nrf_clock_calibration_is_in_progress(void); + /** @brief Get onoff service for given clock subsystem. * * @param sys Subsystem. @@ -235,6 +242,24 @@ int nrf_clock_control_request(const struct device *dev, return api->request(dev, spec, cli); } +/** + * @brief Synchronously request a reservation to use a given clock with specified attributes. + * + * Function can only be called from thread context as it blocks until request is completed. + * @see nrf_clock_control_request(). + * + * @param dev pointer to the clock device structure. + * @param spec See nrf_clock_control_request(). + * @param timeout Request timeout. + * + * @retval 0 if request is fulfilled. + * @retval -EWOULDBLOCK if request is called from the interrupt context. + * @retval negative See error codes returned by nrf_clock_control_request(). + */ +int nrf_clock_control_request_sync(const struct device *dev, + const struct nrf_clock_spec *spec, + k_timeout_t timeout); + /** * @brief Release a reserved use of a clock. * @@ -292,8 +317,51 @@ int nrf_clock_control_cancel_or_release(const struct device *dev, return api->cancel_or_release(dev, spec, cli); } +/** @brief Request the HFXO from Zero Latency Interrupt context. + * + * Function is optimized for use in Zero Latency Interrupt context. + * It does not give notification when the HFXO is ready, so each + * user must put the request early enough to make sure the HFXO + * ramp-up has finished on time. + * + * This function uses reference counting so the caller must ensure + * that every nrf_clock_control_hfxo_request() call has a matching + * nrf_clock_control_hfxo_release() call. + */ +void nrf_clock_control_hfxo_request(void); + +/** @brief Release the HFXO from Zero Latency Interrupt context. + * + * Function is optimized for use in Zero Latency Interrupt context. + * + * Calls to this function must be coupled with prior calls + * to nrf_clock_control_hfxo_request(), because it uses basic + * reference counting to make sure the HFXO is released when + * there are no more pending requests. + */ +void nrf_clock_control_hfxo_release(void); + #endif /* defined(CONFIG_CLOCK_CONTROL_NRF2) */ +/** @brief Get clock frequency that is used for the given node. + * + * Macro checks if node has clock property and if yes then if clock has clock_frequency property + * then it is returned. If it has supported_clock_frequency property with the list of supported + * frequencies then the last one is returned with assumption that they are ordered and the last + * one is the highest. If node does not have clock then 16 MHz is returned which is the default + * frequency. + * + * @param node Devicetree node. + * + * @return Frequency of the clock that is used for the node. + */ +#define NRF_PERIPH_GET_FREQUENCY(node) \ + COND_CODE_1(DT_CLOCKS_HAS_IDX(node, 0), \ + (COND_CODE_1(DT_NODE_HAS_PROP(DT_CLOCKS_CTLR(node), clock_frequency), \ + (DT_PROP(DT_CLOCKS_CTLR(node), clock_frequency)), \ + (DT_PROP_LAST(DT_CLOCKS_CTLR(node), supported_clock_frequency)))), \ + (NRFX_MHZ_TO_HZ(16))) + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index b03fa79002709..de1b9da289356 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -27,6 +27,7 @@ #elif defined(CONFIG_SOC_SERIES_STM32F2X) || \ defined(CONFIG_SOC_SERIES_STM32F4X) #include +#include #elif defined(CONFIG_SOC_SERIES_STM32F7X) #include #elif defined(CONFIG_SOC_SERIES_STM32G0X) @@ -52,6 +53,8 @@ #include #elif defined(CONFIG_SOC_SERIES_STM32H7RSX) #include +#elif defined(CONFIG_SOC_SERIES_STM32N6X) +#include #elif defined(CONFIG_SOC_SERIES_STM32U0X) #include #elif defined(CONFIG_SOC_SERIES_STM32U5X) @@ -71,6 +74,7 @@ #define STM32_APB1_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb1_prescaler) #define STM32_APB2_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb2_prescaler) #define STM32_APB3_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb3_prescaler) +#define STM32_APB4_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb4_prescaler) #define STM32_APB5_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb5_prescaler) #define STM32_APB7_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb7_prescaler) #define STM32_AHB3_PRESCALER DT_PROP(DT_NODELABEL(rcc), ahb3_prescaler) @@ -140,6 +144,9 @@ #if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(clk_csi)) #define STM32_SYSCLK_SRC_CSI 1 #endif +#if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(ic2)) +#define STM32_SYSCLK_SRC_IC2 1 +#endif /** PLL node related symbols */ @@ -179,10 +186,12 @@ #define STM32_PLLI2S_R_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_r, 1) #endif -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32f412_plli2s_clock, okay) +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32f411_plli2s_clock, okay) #define STM32_PLLI2S_ENABLED 1 #define STM32_PLLI2S_M_DIVISOR DT_PROP(DT_NODELABEL(plli2s), div_m) #define STM32_PLLI2S_N_MULTIPLIER DT_PROP(DT_NODELABEL(plli2s), mul_n) +#define STM32_PLLI2S_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_q) +#define STM32_PLLI2S_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_q, 1) #define STM32_PLLI2S_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_r) #define STM32_PLLI2S_R_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_r, 1) #endif @@ -249,6 +258,38 @@ #define STM32_PLL2_PREDIV DT_PROP(DT_NODELABEL(pll2), prediv) #endif +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll1), st_stm32n6_pll_clock, okay) +#define STM32_PLL1_ENABLED 1 +#define STM32_PLL1_M_DIVISOR DT_PROP(DT_NODELABEL(pll1), div_m) +#define STM32_PLL1_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll1), mul_n) +#define STM32_PLL1_P1_DIVISOR DT_PROP(DT_NODELABEL(pll1), div_p1) +#define STM32_PLL1_P2_DIVISOR DT_PROP(DT_NODELABEL(pll1), div_p2) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32n6_pll_clock, okay) +#define STM32_PLL2_ENABLED 1 +#define STM32_PLL2_M_DIVISOR DT_PROP(DT_NODELABEL(pll2), div_m) +#define STM32_PLL2_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll2), mul_n) +#define STM32_PLL2_P1_DIVISOR DT_PROP(DT_NODELABEL(pll2), div_p1) +#define STM32_PLL2_P2_DIVISOR DT_PROP(DT_NODELABEL(pll2), div_p2) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32n6_pll_clock, okay) +#define STM32_PLL3_ENABLED 1 +#define STM32_PLL3_M_DIVISOR DT_PROP(DT_NODELABEL(pll3), div_m) +#define STM32_PLL3_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll3), mul_n) +#define STM32_PLL3_P1_DIVISOR DT_PROP(DT_NODELABEL(pll3), div_p1) +#define STM32_PLL3_P2_DIVISOR DT_PROP(DT_NODELABEL(pll3), div_p2) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll4), st_stm32n6_pll_clock, okay) +#define STM32_PLL4_ENABLED 1 +#define STM32_PLL4_M_DIVISOR DT_PROP(DT_NODELABEL(pll4), div_m) +#define STM32_PLL4_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll4), mul_n) +#define STM32_PLL4_P1_DIVISOR DT_PROP(DT_NODELABEL(pll4), div_p1) +#define STM32_PLL4_P2_DIVISOR DT_PROP(DT_NODELABEL(pll4), div_p2) +#endif + /** PLL/PLL1 clock source */ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pll)) && \ DT_NODE_HAS_PROP(DT_NODELABEL(pll), clocks) @@ -278,6 +319,9 @@ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pll2)) && \ DT_NODE_HAS_PROP(DT_NODELABEL(pll2), clocks) #define DT_PLL2_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(pll2)) +#if DT_SAME_NODE(DT_PLL2_CLOCKS_CTRL, DT_NODELABEL(clk_msi)) +#define STM32_PLL2_SRC_MSI 1 +#endif #if DT_SAME_NODE(DT_PLL2_CLOCKS_CTRL, DT_NODELABEL(clk_msis)) #define STM32_PLL2_SRC_MSIS 1 #endif @@ -294,6 +338,9 @@ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pll3)) && \ DT_NODE_HAS_PROP(DT_NODELABEL(pll3), clocks) #define DT_PLL3_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(pll3)) +#if DT_SAME_NODE(DT_PLL3_CLOCKS_CTRL, DT_NODELABEL(clk_msi)) +#define STM32_PLL3_SRC_MSI 1 +#endif #if DT_SAME_NODE(DT_PLL3_CLOCKS_CTRL, DT_NODELABEL(clk_msis)) #define STM32_PLL3_SRC_MSIS 1 #endif @@ -306,6 +353,22 @@ #endif +/** PLL4 clock source */ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pll4), okay) && \ + DT_NODE_HAS_PROP(DT_NODELABEL(pll4), clocks) +#define DT_PLL4_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(pll4)) +#if DT_SAME_NODE(DT_PLL4_CLOCKS_CTRL, DT_NODELABEL(clk_msi)) +#define STM32_PLL4_SRC_MSI 1 +#endif +#if DT_SAME_NODE(DT_PLL4_CLOCKS_CTRL, DT_NODELABEL(clk_hsi)) +#define STM32_PLL4_SRC_HSI 1 +#endif +#if DT_SAME_NODE(DT_PLL4_CLOCKS_CTRL, DT_NODELABEL(clk_hse)) +#define STM32_PLL4_SRC_HSE 1 +#endif + +#endif + /** Fixed clocks related symbols */ @@ -411,6 +474,11 @@ #define STM32_HSE_ENABLED 1 #define STM32_HSE_DIV2 DT_PROP(DT_NODELABEL(clk_hse), hse_div2) #define STM32_HSE_FREQ DT_PROP(DT_NODELABEL(clk_hse), clock_frequency) +#elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hse), st_stm32n6_hse_clock, okay) +#define STM32_HSE_ENABLED 1 +#define STM32_HSE_BYPASS DT_PROP(DT_NODELABEL(clk_hse), hse_bypass) +#define STM32_HSE_DIV2 DT_PROP(DT_NODELABEL(clk_hse), hse_div2) +#define STM32_HSE_FREQ DT_PROP(DT_NODELABEL(clk_hse), clock_frequency) #else #define STM32_HSE_FREQ 0 #endif @@ -428,10 +496,135 @@ #define STM32_CKPER_ENABLED 1 #endif +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(cpusw), st_stm32_clock_mux, okay) +#define STM32_CPUSW_ENABLED 1 +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic1), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC1_ENABLED 1 +#define STM32_IC1_PLL_SRC DT_PROP(DT_NODELABEL(ic1), pll_src) +#define STM32_IC1_DIV DT_PROP(DT_NODELABEL(ic1), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic2), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC2_ENABLED 1 +#define STM32_IC2_PLL_SRC DT_PROP(DT_NODELABEL(ic2), pll_src) +#define STM32_IC2_DIV DT_PROP(DT_NODELABEL(ic2), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic3), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC3_ENABLED 1 +#define STM32_IC3_PLL_SRC DT_PROP(DT_NODELABEL(ic3), pll_src) +#define STM32_IC3_DIV DT_PROP(DT_NODELABEL(ic3), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic4), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC4_ENABLED 1 +#define STM32_IC4_PLL_SRC DT_PROP(DT_NODELABEL(ic4), pll_src) +#define STM32_IC4_DIV DT_PROP(DT_NODELABEL(ic4), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic5), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC5_ENABLED 1 +#define STM32_IC5_PLL_SRC DT_PROP(DT_NODELABEL(ic5), pll_src) +#define STM32_IC5_DIV DT_PROP(DT_NODELABEL(ic5), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic6), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC6_ENABLED 1 +#define STM32_IC6_PLL_SRC DT_PROP(DT_NODELABEL(ic6), pll_src) +#define STM32_IC6_DIV DT_PROP(DT_NODELABEL(ic6), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic7), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC7_ENABLED 1 +#define STM32_IC7_PLL_SRC DT_PROP(DT_NODELABEL(ic7), pll_src) +#define STM32_IC7_DIV DT_PROP(DT_NODELABEL(ic7), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic8), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC8_ENABLED 1 +#define STM32_IC8_PLL_SRC DT_PROP(DT_NODELABEL(ic8), pll_src) +#define STM32_IC8_DIV DT_PROP(DT_NODELABEL(ic8), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic9), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC9_ENABLED 1 +#define STM32_IC9_PLL_SRC DT_PROP(DT_NODELABEL(ic9), pll_src) +#define STM32_IC9_DIV DT_PROP(DT_NODELABEL(ic9), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic10), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC10_ENABLED 1 +#define STM32_IC10_PLL_SRC DT_PROP(DT_NODELABEL(ic10), pll_src) +#define STM32_IC10_DIV DT_PROP(DT_NODELABEL(ic10), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic11), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC11_ENABLED 1 +#define STM32_IC11_PLL_SRC DT_PROP(DT_NODELABEL(ic11), pll_src) +#define STM32_IC11_DIV DT_PROP(DT_NODELABEL(ic11), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic12), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC12_ENABLED 1 +#define STM32_IC12_PLL_SRC DT_PROP(DT_NODELABEL(ic12), pll_src) +#define STM32_IC12_DIV DT_PROP(DT_NODELABEL(ic12), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic13), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC13_ENABLED 1 +#define STM32_IC13_PLL_SRC DT_PROP(DT_NODELABEL(ic13), pll_src) +#define STM32_IC13_DIV DT_PROP(DT_NODELABEL(ic13), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic14), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC14_ENABLED 1 +#define STM32_IC14_PLL_SRC DT_PROP(DT_NODELABEL(ic14), pll_src) +#define STM32_IC14_DIV DT_PROP(DT_NODELABEL(ic14), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic15), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC15_ENABLED 1 +#define STM32_IC15_PLL_SRC DT_PROP(DT_NODELABEL(ic15), pll_src) +#define STM32_IC15_DIV DT_PROP(DT_NODELABEL(ic15), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic16), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC16_ENABLED 1 +#define STM32_IC16_PLL_SRC DT_PROP(DT_NODELABEL(ic16), pll_src) +#define STM32_IC16_DIV DT_PROP(DT_NODELABEL(ic16), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic17), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC17_ENABLED 1 +#define STM32_IC17_PLL_SRC DT_PROP(DT_NODELABEL(ic17), pll_src) +#define STM32_IC17_DIV DT_PROP(DT_NODELABEL(ic17), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic18), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC18_ENABLED 1 +#define STM32_IC18_PLL_SRC DT_PROP(DT_NODELABEL(ic18), pll_src) +#define STM32_IC18_DIV DT_PROP(DT_NODELABEL(ic18), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic19), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC19_ENABLED 1 +#define STM32_IC19_PLL_SRC DT_PROP(DT_NODELABEL(ic19), pll_src) +#define STM32_IC19_DIV DT_PROP(DT_NODELABEL(ic19), ic_div) +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ic20), st_stm32n6_ic_clock_mux, okay) +#define STM32_IC20_ENABLED 1 +#define STM32_IC20_PLL_SRC DT_PROP(DT_NODELABEL(ic20), pll_src) +#define STM32_IC20_DIV DT_PROP(DT_NODELABEL(ic20), ic_div) +#endif + /** Driver structure definition */ struct stm32_pclken { - uint32_t bus; + uint32_t bus : STM32_CLOCK_DIV_SHIFT; + uint32_t div : (32 - STM32_CLOCK_DIV_SHIFT); uint32_t enr; }; @@ -440,7 +633,10 @@ struct stm32_pclken { #define STM32_CLOCK_INFO(clk_index, node_id) \ { \ .enr = DT_CLOCKS_CELL_BY_IDX(node_id, clk_index, bits), \ - .bus = DT_CLOCKS_CELL_BY_IDX(node_id, clk_index, bus) \ + .bus = DT_CLOCKS_CELL_BY_IDX(node_id, clk_index, bus) & \ + GENMASK(STM32_CLOCK_DIV_SHIFT - 1, 0), \ + .div = DT_CLOCKS_CELL_BY_IDX(node_id, clk_index, bus) >> \ + STM32_CLOCK_DIV_SHIFT, \ } #define STM32_DT_CLOCKS(node_id) \ { \ @@ -462,68 +658,36 @@ struct stm32_pclken { /** Clock source binding accessors */ /** - * @brief Obtain register field from clock configuration. + * @brief Obtain register field from clock source selection configuration. * * @param clock clock bit field value. */ -#define STM32_CLOCK_REG_GET(clock) \ - (((clock) >> STM32_CLOCK_REG_SHIFT) & STM32_CLOCK_REG_MASK) +#define STM32_DT_CLKSEL_REG_GET(clock) \ + (((clock) >> STM32_DT_CLKSEL_REG_SHIFT) & STM32_DT_CLKSEL_REG_MASK) /** - * @brief Obtain position field from clock configuration. + * @brief Obtain position field from clock source selection configuration. * * @param clock Clock bit field value. */ -#define STM32_CLOCK_SHIFT_GET(clock) \ - (((clock) >> STM32_CLOCK_SHIFT_SHIFT) & STM32_CLOCK_SHIFT_MASK) +#define STM32_DT_CLKSEL_SHIFT_GET(clock) \ + (((clock) >> STM32_DT_CLKSEL_SHIFT_SHIFT) & STM32_DT_CLKSEL_SHIFT_MASK) /** - * @brief Obtain mask field from clock configuration. + * @brief Obtain mask field from clock source selection configuration. * * @param clock Clock bit field value. */ -#define STM32_CLOCK_MASK_GET(clock) \ - (((clock) >> STM32_CLOCK_MASK_SHIFT) & STM32_CLOCK_MASK_MASK) +#define STM32_DT_CLKSEL_MASK_GET(clock) \ + (((clock) >> STM32_DT_CLKSEL_MASK_SHIFT) & STM32_DT_CLKSEL_MASK_MASK) /** - * @brief Obtain value field from clock configuration. + * @brief Obtain value field from clock source selection configuration. * * @param clock Clock bit field value. */ -#define STM32_CLOCK_VAL_GET(clock) \ - (((clock) >> STM32_CLOCK_VAL_SHIFT) & STM32_CLOCK_VAL_MASK) - -/** - * @brief Obtain register field from MCO configuration. - * - * @param mco_cfgr MCO configuration bit field value. - */ -#define STM32_MCO_CFGR_REG_GET(mco_cfgr) \ - (((mco_cfgr) >> STM32_MCO_CFGR_REG_SHIFT) & STM32_MCO_CFGR_REG_MASK) - -/** - * @brief Obtain position field from MCO configuration. - * - * @param mco_cfgr MCO configuration bit field value. - */ -#define STM32_MCO_CFGR_SHIFT_GET(mco_cfgr) \ - (((mco_cfgr) >> STM32_MCO_CFGR_SHIFT_SHIFT) & STM32_MCO_CFGR_SHIFT_MASK) - -/** - * @brief Obtain mask field from MCO configuration. - * - * @param mco_cfgr MCO configuration bit field value. - */ -#define STM32_MCO_CFGR_MASK_GET(mco_cfgr) \ - (((mco_cfgr) >> STM32_MCO_CFGR_MASK_SHIFT) & STM32_MCO_CFGR_MASK_MASK) - -/** - * @brief Obtain value field from MCO configuration. - * - * @param mco_cfgr MCO configuration bit field value. - */ -#define STM32_MCO_CFGR_VAL_GET(mco_cfgr) \ - (((mco_cfgr) >> STM32_MCO_CFGR_VAL_SHIFT) & STM32_MCO_CFGR_VAL_MASK) +#define STM32_DT_CLKSEL_VAL_GET(clock) \ + (((clock) >> STM32_DT_CLKSEL_VAL_SHIFT) & STM32_DT_CLKSEL_VAL_MASK) #if defined(STM32_HSE_CSS) /** diff --git a/include/zephyr/drivers/dai.h b/include/zephyr/drivers/dai.h index 7af4157d442bf..6ae171105672b 100644 --- a/include/zephyr/drivers/dai.h +++ b/include/zephyr/drivers/dai.h @@ -115,6 +115,7 @@ enum dai_type { DAI_INTEL_DMIC_NHLT, /**< nhlt ssp */ DAI_INTEL_HDA_NHLT, /**< nhlt Intel HD/A */ DAI_INTEL_ALH_NHLT, /**< nhlt Intel ALH */ + DAI_IMX_MICFIL, /**< i.MX PDM MICFIL */ }; /** diff --git a/include/zephyr/drivers/dma/dma_silabs_ldma.h b/include/zephyr/drivers/dma/dma_silabs_ldma.h new file mode 100644 index 0000000000000..3a99a122e5bbf --- /dev/null +++ b/include/zephyr/drivers/dma/dma_silabs_ldma.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_DMA_SILABS_LDMA_H_ +#define ZEPHYR_INCLUDE_DRIVERS_DMA_SILABS_LDMA_H_ + +#include + +#define SILABS_LDMA_SOURCE_MASK GENMASK(21, 16) +#define SILABS_LDMA_SIG_MASK GENMASK(3, 0) + +#define SILABS_DMA_SLOT_SOURCE_MASK GENMASK(7, 3) +#define SILABS_DMA_SLOT_SIG_MASK GENMASK(2, 0) + +#define SILABS_LDMA_REQSEL_TO_SLOT(signal) \ + FIELD_PREP(SILABS_DMA_SLOT_SOURCE_MASK, FIELD_GET(SILABS_LDMA_SOURCE_MASK, signal)) | \ + FIELD_PREP(SILABS_DMA_SLOT_SIG_MASK, FIELD_GET(SILABS_LDMA_SIG_MASK, signal)) + +#define SILABS_LDMA_SLOT_TO_REQSEL(slot) \ + FIELD_PREP(SILABS_LDMA_SOURCE_MASK, FIELD_GET(SILABS_DMA_SLOT_SOURCE_MASK, slot)) | \ + FIELD_PREP(SILABS_LDMA_SIG_MASK, FIELD_GET(SILABS_DMA_SLOT_SIG_MASK, slot)) + +/** + * @brief Append a new block to the current channel + * + * This function allows to append a block to the current DMA transfer. It allows a user/driver + * to register the next DMA transfer while a transfer in being held without stopping or restarting + * DMA engine. It is very suitable for Zephyr Uart API where user gives buffers while the DMA engine + * is running. Because this function changes dynamically the link to the block that DMA engine would + * load as the next transfer, it is only working with channel that didn't have linked block list. + * + * In the case that the DMA engine naturally stopped because the previous transfer is finished, this + * function simply restart the DMA engine with the given block. If the DMA engine stopped while + * reconfiguring the next transfer, the DMA engine will restart too. + * + * @param dev: dma device + * @param channel: channel + * @param config: configuration of the channel with the block to append as the head_block. + */ +int silabs_ldma_append_block(const struct device *dev, uint32_t channel, + struct dma_config *config); + +#endif /* ZEPHYR_INCLUDE_DRIVERS_DMA_SILABS_LDMA_H_*/ diff --git a/include/zephyr/drivers/dma/dma_stm32.h b/include/zephyr/drivers/dma/dma_stm32.h index cd661f209652b..38f395b0108fc 100644 --- a/include/zephyr/drivers/dma/dma_stm32.h +++ b/include/zephyr/drivers/dma/dma_stm32.h @@ -56,6 +56,8 @@ DT_INST_DMAS_CELL_BY_IDX(id, idx, channel_config) /* macros for channel-config */ +/* enable circular buffer */ +#define STM32_DMA_CONFIG_CYCLIC(config) ((config >> 5) & 0x1) /* direction defined on bits 6-7 */ /* 0 -> MEM_TO_MEM, 1 -> MEM_TO_PERIPH, 2 -> PERIPH_TO_MEM */ #define STM32_DMA_CONFIG_DIRECTION(config) ((config >> 6) & 0x3) diff --git a/include/zephyr/drivers/ethernet/eth_lan865x.h b/include/zephyr/drivers/ethernet/eth_lan865x.h new file mode 100644 index 0000000000000..4a7e7f115562e --- /dev/null +++ b/include/zephyr/drivers/ethernet/eth_lan865x.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2024 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_ETH_LAN865X_H__ +#define ZEPHYR_INCLUDE_DRIVERS_ETH_LAN865X_H__ + +#include +#include +#include + +/** + * @brief Read C22 registers using LAN865X MDIO Bus + * + * This routine provides an interface to perform a C22 register read on the + * LAN865X MDIO bus. + * + * @param[in] dev Pointer to the device structure for the controller + * @param[in] prtad Port address + * @param[in] regad Register address + * @param data Pointer to receive read data + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if read is not supported + */ +int eth_lan865x_mdio_c22_read(const struct device *dev, uint8_t prtad, uint8_t regad, + uint16_t *data); + +/** + * @brief Write C22 registers using LAN865X MDIO Bus + * + * This routine provides an interface to perform a C22 register write on the + * LAN865X MDIO bus. + * + * @param[in] dev Pointer to the device structure for the controller + * @param[in] prtad Port address + * @param[in] regad Register address + * @param[in] data Write data + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if read is not supported + */ +int eth_lan865x_mdio_c22_write(const struct device *dev, uint8_t prtad, uint8_t regad, + uint16_t data); + +/** + * @brief Read C45 registers using LAN865X MDIO Bus + * + * This routine provides an interface to perform a C45 register read on the + * LAN865X MDIO bus. + * + * @param[in] dev Pointer to the device structure for the controller + * @param[in] prtad Port address + * @param[in] devad MMD device address + * @param[in] regad Register address + * @param data Pointer to receive read data + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if read is not supported + */ +int eth_lan865x_mdio_c45_read(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t *data); + +/** + * @brief Write C45 registers using LAN865X MDIO Bus + * + * This routine provides an interface to perform a C45 register write on the + * LAN865X MDIO bus. + * + * @param[in] dev Pointer to the device structure for the controller + * @param[in] prtad Port address + * @param[in] devad MMD device address + * @param[in] regad Register address + * @param[in] data Write data + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -ETIMEDOUT If transaction timedout on the bus + * @retval -ENOSYS if read is not supported + */ +int eth_lan865x_mdio_c45_write(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t data); + +#endif /* ZEPHYR_INCLUDE_DRIVERS_ETH_LAN865X_H__ */ diff --git a/include/zephyr/drivers/firmware/scmi/clk.h b/include/zephyr/drivers/firmware/scmi/clk.h index e56fc9df24431..d13cfd136794c 100644 --- a/include/zephyr/drivers/firmware/scmi/clk.h +++ b/include/zephyr/drivers/firmware/scmi/clk.h @@ -20,6 +20,11 @@ #define SCMI_CLK_ATTRIBUTES_CLK_NUM(x) ((x) & GENMASK(15, 0)) +#define SCMI_CLK_RATE_SET_FLAGS_ASYNC BIT(0) +#define SCMI_CLK_RATE_SET_FLAGS_IGNORE_DELEAYED_RESP BIT(1) +#define SCMI_CLK_RATE_SET_FLAGS_ROUNDS_UP_DOWN BIT(2) +#define SCMI_CLK_RATE_SET_FLAGS_ROUNDS_AUTO BIT(3) + /** * @struct scmi_clock_config * @@ -32,6 +37,18 @@ struct scmi_clock_config { uint32_t extended_cfg_val; }; +/** + * @struct scmi_clock_rate_config + * + * @brief Describes the parameters for the CLOCK_RATE_SET + * command + */ +struct scmi_clock_rate_config { + uint32_t flags; + uint32_t clk_id; + uint32_t rate[2]; +}; + /** * @brief Clock protocol command message IDs */ @@ -93,4 +110,41 @@ int scmi_clock_config_set(struct scmi_protocol *proto, int scmi_clock_rate_get(struct scmi_protocol *proto, uint32_t clk_id, uint32_t *rate); +/** + * @brief Send the CLOCK_RATE_SET command and get its reply + * + * @param proto pointer to SCMI clock protocol data + * @param cfg pointer to structure containing configuration + * to be set + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_clock_rate_set(struct scmi_protocol *proto, struct scmi_clock_rate_config *cfg); + +/** + * @brief Query the parent of a clock + * + * @param proto pointer to SCMI clock protocol data + * @param clk_id ID of the clock for which the query is done + * @param parent_id pointer to be set via this command + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_clock_parent_get(struct scmi_protocol *proto, uint32_t clk_id, uint32_t *parent_id); + +/** + * @brief Send the CLOCK_PARENT_SET command and get its reply + * + * @param proto pointer to SCMI clock protocol data + * @param clk_id ID of the clock for which the query is done + * @param parent_id to be set via this command + * to be set + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_clock_parent_set(struct scmi_protocol *proto, uint32_t clk_id, uint32_t parent_id); + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_CLK_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/power.h b/include/zephyr/drivers/firmware/scmi/power.h new file mode 100644 index 0000000000000..649209c746906 --- /dev/null +++ b/include/zephyr/drivers/firmware/scmi/power.h @@ -0,0 +1,68 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief SCMI power domain protocol helpers + */ + +#ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_POWER_H_ +#define _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_POWER_H_ + +#include + +#define SCMI_POWER_STATE_SET_FLAGS_ASYNC BIT(0) + +/** + * @struct scmi_power_state_config + * + * @brief Describes the parameters for the POWER_STATE_SET + * command + */ +struct scmi_power_state_config { + uint32_t flags; + uint32_t domain_id; + uint32_t power_state; +}; + +/** + * @brief Power domain protocol command message IDs + */ +enum scmi_power_domain_message { + SCMI_POWER_DOMAIN_MSG_PROTOCOL_VERSION = 0x0, + SCMI_POWER_DOMAIN_MSG_PROTOCOL_ATTRIBUTES = 0x1, + SCMI_POWER_DOMAIN_MSG_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2, + SCMI_POWER_DOMAIN_MSG_POWER_DOMAIN_ATTRIBUTES = 0x3, + SCMI_POWER_DOMAIN_MSG_POWER_STATE_SET = 0x4, + SCMI_POWER_DOMAIN_MSG_POWER_STATE_GET = 0x5, + SCMI_POWER_DOMAIN_MSG_POWER_STATE_NOTIFY = 0x6, + SCMI_POWER_DOMAIN_MSG_POWER_STATE_CHANGE_REQEUSTED_NOTIFY = 0x7, + SCMI_POWER_DOMAIN_MSG_POWER_DOMAIN_NAME_GET = 0x8, + SCMI_POWER_DOMAIN_MSG_NEGOTIATE_PROTOCOL_VERSION = 0x10, +}; + +/** + * @brief Send the POWER_STATE_SET command and get its reply + * + * @param cfg pointer to structure containing configuration + * to be set + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_power_state_set(struct scmi_power_state_config *cfg); +/** + * @brief Query the power domain state + * + * @param domain_id ID of the power domain for which the query is done + * @param power_state pointer to be set via this command + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_power_state_get(uint32_t domain_id, uint32_t *power_state); + +#endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_POWER_H_ */ diff --git a/include/zephyr/drivers/flash/stm32_flash_api_extensions.h b/include/zephyr/drivers/flash/stm32_flash_api_extensions.h index 0c6c8fc88ad14..0114735053647 100644 --- a/include/zephyr/drivers/flash/stm32_flash_api_extensions.h +++ b/include/zephyr/drivers/flash/stm32_flash_api_extensions.h @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef __ZEPHYR_INCLUDE_DRIVERS_FLASH_STM32_FLASH_API_EXTENSIONS_H__ +#define __ZEPHYR_INCLUDE_DRIVERS_FLASH_STM32_FLASH_API_EXTENSIONS_H__ + #include enum stm32_ex_ops { @@ -45,16 +48,30 @@ enum stm32_ex_ops { * erasing or writing. */ FLASH_STM32_EX_OP_BLOCK_CONTROL_REG, + /* + * STM32 option bytes read. + * + * Read the option bytes content, out takes a *uint32_t, in is unused. + */ + FLASH_STM32_EX_OP_OPTB_READ, + /* + * STM32 option bytes write. + * + * Write the option bytes content, in takes the new value, out is + * unused. Note that the new value only takes effect after the device + * is restarted. + */ + FLASH_STM32_EX_OP_OPTB_WRITE, }; #if defined(CONFIG_FLASH_STM32_WRITE_PROTECT) struct flash_stm32_ex_op_sector_wp_in { - uint32_t enable_mask; - uint32_t disable_mask; + uint64_t enable_mask; + uint64_t disable_mask; }; struct flash_stm32_ex_op_sector_wp_out { - uint32_t protected_mask; + uint64_t protected_mask; }; #endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */ @@ -64,3 +81,5 @@ struct flash_stm32_ex_op_rdp { bool permanent; }; #endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */ + +#endif /* __ZEPHYR_INCLUDE_DRIVERS_FLASH_STM32_FLASH_API_EXTENSIONS_H__ */ diff --git a/include/zephyr/drivers/fuel_gauge.h b/include/zephyr/drivers/fuel_gauge.h index 107b7c7869c7f..2e48b01e44511 100644 --- a/include/zephyr/drivers/fuel_gauge.h +++ b/include/zephyr/drivers/fuel_gauge.h @@ -288,15 +288,15 @@ static inline int z_impl_fuel_gauge_get_prop(const struct device *dev, fuel_gaug * @return 0 if successful, negative errno code of first failing property */ -__syscall int fuel_gauge_get_props(const struct device *dev, fuel_gauge_prop_t *props, +__syscall int fuel_gauge_get_props(const struct device *dev, const fuel_gauge_prop_t *props, union fuel_gauge_prop_val *vals, size_t len); static inline int z_impl_fuel_gauge_get_props(const struct device *dev, - fuel_gauge_prop_t *props, + const fuel_gauge_prop_t *props, union fuel_gauge_prop_val *vals, size_t len) { - const struct fuel_gauge_driver_api *api = dev->api; + const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; - for (int i = 0; i < len; i++) { + for (size_t i = 0; i < len; i++) { int ret = api->get_property(dev, props[i], vals + i); if (ret) { @@ -322,7 +322,7 @@ __syscall int fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t pr static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, fuel_gauge_prop_t prop, union fuel_gauge_prop_val val) { - const struct fuel_gauge_driver_api *api = dev->api; + const struct fuel_gauge_driver_api *api = (const struct fuel_gauge_driver_api *)dev->api; if (api->set_property == NULL) { return -ENOSYS; @@ -342,14 +342,14 @@ static inline int z_impl_fuel_gauge_set_prop(const struct device *dev, fuel_gaug * * @return return=0 if successful. Otherwise, return array index of failing property. */ -__syscall int fuel_gauge_set_props(const struct device *dev, fuel_gauge_prop_t *props, - union fuel_gauge_prop_val *vals, size_t len); +__syscall int fuel_gauge_set_props(const struct device *dev, const fuel_gauge_prop_t *props, + const union fuel_gauge_prop_val *vals, size_t len); static inline int z_impl_fuel_gauge_set_props(const struct device *dev, - fuel_gauge_prop_t *props, - union fuel_gauge_prop_val *vals, size_t len) + const fuel_gauge_prop_t *props, + const union fuel_gauge_prop_val *vals, size_t len) { - for (int i = 0; i < len; i++) { + for (size_t i = 0; i < len; i++) { int ret = fuel_gauge_set_prop(dev, props[i], vals[i]); if (ret) { diff --git a/include/zephyr/drivers/gnss.h b/include/zephyr/drivers/gnss.h index c5d2b9174cc48..3a0ba8ba1b65a 100644 --- a/include/zephyr/drivers/gnss.h +++ b/include/zephyr/drivers/gnss.h @@ -140,6 +140,8 @@ struct gnss_info { uint16_t satellites_cnt; /** Horizontal dilution of precision in 1/1000 */ uint32_t hdop; + /** Geoid separation in millimeters */ + int32_t geoid_separation; /** The fix status */ enum gnss_fix_status fix_status; /** The fix quality */ diff --git a/include/zephyr/drivers/gpio.h b/include/zephyr/drivers/gpio.h index 077a695049c26..3eed819472657 100644 --- a/include/zephyr/drivers/gpio.h +++ b/include/zephyr/drivers/gpio.h @@ -340,8 +340,8 @@ struct gpio_dt_spec { * @brief Like GPIO_DT_SPEC_GET_BY_IDX(), with a fallback to a default value * * If the devicetree node identifier 'node_id' refers to a node with a - * property 'prop', this expands to - * GPIO_DT_SPEC_GET_BY_IDX(node_id, prop, idx). The @p + * property 'prop', and the index @p idx is valid for that property, + * this expands to GPIO_DT_SPEC_GET_BY_IDX(node_id, prop, idx). The @p * default_value parameter is not expanded in this case. * * Otherwise, this expands to @p default_value. @@ -354,7 +354,7 @@ struct gpio_dt_spec { * or default_value if the node or property do not exist */ #define GPIO_DT_SPEC_GET_BY_IDX_OR(node_id, prop, idx, default_value) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \ + COND_CODE_1(DT_PROP_HAS_IDX(node_id, prop, idx), \ (GPIO_DT_SPEC_GET_BY_IDX(node_id, prop, idx)), \ (default_value)) @@ -810,7 +810,8 @@ __subsystem struct gpio_driver_api { gpio_port_pins_t pins); int (*pin_interrupt_configure)(const struct device *port, gpio_pin_t pin, - enum gpio_int_mode, enum gpio_int_trig); + enum gpio_int_mode mode, + enum gpio_int_trig trig); int (*manage_callback)(const struct device *port, struct gpio_callback *cb, bool set); diff --git a/include/zephyr/drivers/gpio/gpio_mmio32.h b/include/zephyr/drivers/gpio/gpio_mmio32.h deleted file mode 100644 index 005f72052936d..0000000000000 --- a/include/zephyr/drivers/gpio/gpio_mmio32.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016 Linaro Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_MMIO32_H_ -#define ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_MMIO32_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern const struct gpio_driver_api gpio_mmio32_api; - -struct gpio_mmio32_config { - /* gpio_driver_config needs to be first */ - struct gpio_driver_config common; - volatile uint32_t *reg; - uint32_t mask; -}; - -struct gpio_mmio32_context { - /* gpio_driver_data needs to be first */ - struct gpio_driver_data common; - const struct gpio_mmio32_config *config; -}; - -int gpio_mmio32_init(const struct device *dev); - -#ifdef CONFIG_GPIO_MMIO32 - -/** - * Create a device object for accessing a simple 32-bit i/o register using the - * same APIs as GPIO drivers. - * - * @param node_id The devicetree node identifier. - * @param _address The address of the 32-bit i/o register the device will - * provide access to. - * @param _mask Mask of bits in the register that it is valid to access. - * E.g. 0xffffffffu to allow access to all of them. - * - */ -#define GPIO_MMIO32_INIT(node_id, _address, _mask) \ -static struct gpio_mmio32_context _CONCAT(Z_DEVICE_DT_DEV_ID(node_id), _ctx); \ - \ -static const struct gpio_mmio32_config _CONCAT(Z_DEVICE_DT_DEV_ID(node_id), _cfg) = { \ - .common = { \ - .port_pin_mask = _mask, \ - }, \ - .reg = (volatile uint32_t *)_address, \ - .mask = _mask, \ -}; \ - \ -DEVICE_DT_DEFINE(node_id, \ - &gpio_mmio32_init, \ - NULL, \ - &_CONCAT(Z_DEVICE_DT_DEV_ID(node_id), _ctx), \ - &_CONCAT(Z_DEVICE_DT_DEV_ID(node_id), _cfg), \ - PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ - &gpio_mmio32_api) - - -#else /* CONFIG_GPIO_MMIO32 */ - -/* Null definition for when support not configured into kernel */ -#define GPIO_MMIO32_INIT(node_id, _address, _mask) - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_MMIO32_H_ */ diff --git a/include/zephyr/drivers/i3c.h b/include/zephyr/drivers/i3c.h index f3581663bfe44..8ca331f0675a7 100644 --- a/include/zephyr/drivers/i3c.h +++ b/include/zephyr/drivers/i3c.h @@ -23,12 +23,14 @@ #include #include +#include #include #include #include #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -291,87 +293,6 @@ enum i3c_data_rate { I3C_DATA_RATE_INVALID, }; -/** - * @brief I3C SDR Controller Error Codes - * - * These are error codes defined by the I3C specification. - * - * #I3C_ERROR_CE_UNKNOWN and #I3C_ERROR_CE_NONE are not - * official error codes according to the specification. - * These are there simply to aid in error handling during - * interactions with the I3C drivers and subsystem. - */ -enum i3c_sdr_controller_error_codes { - /** Transaction after sending CCC */ - I3C_ERROR_CE0, - - /** Monitoring Error */ - I3C_ERROR_CE1, - - /** No response to broadcast address (0x7E) */ - I3C_ERROR_CE2, - - /** Failed Controller Handoff */ - I3C_ERROR_CE3, - - /** Unknown error (not official error code) */ - I3C_ERROR_CE_UNKNOWN, - - /** No error (not official error code) */ - I3C_ERROR_CE_NONE, - - I3C_ERROR_CE_MAX = I3C_ERROR_CE_UNKNOWN, - I3C_ERROR_CE_INVALID, -}; - -/** - * @brief I3C SDR Target Error Codes - * - * These are error codes defined by the I3C specification. - * - * #I3C_ERROR_TE_UNKNOWN and #I3C_ERROR_TE_NONE are not - * official error codes according to the specification. - * These are there simply to aid in error handling during - * interactions with the I3C drivers and subsystem. - */ -enum i3c_sdr_target_error_codes { - /** - * Invalid Broadcast Address or - * Dynamic Address after DA assignment - */ - I3C_ERROR_TE0, - - /** CCC Code */ - I3C_ERROR_TE1, - - /** Write Data */ - I3C_ERROR_TE2, - - /** Assigned Address during Dynamic Address Arbitration */ - I3C_ERROR_TE3, - - /** 0x7E/R missing after RESTART during Dynamic Address Arbitration */ - I3C_ERROR_TE4, - - /** Transaction after detecting CCC */ - I3C_ERROR_TE5, - - /** Monitoring Error */ - I3C_ERROR_TE6, - - /** Dead Bus Recovery */ - I3C_ERROR_DBR, - - /** Unknown error (not official error code) */ - I3C_ERROR_TE_UNKNOWN, - - /** No error (not official error code) */ - I3C_ERROR_TE_NONE, - - I3C_ERROR_TE_MAX = I3C_ERROR_TE_UNKNOWN, - I3C_ERROR_TE_INVALID, -}; - /** * @brief I3C Transfer API * @defgroup i3c_transfer_api I3C Transfer API @@ -485,6 +406,14 @@ struct i3c_msg { */ uint32_t num_xfer; + /** + * SDR Error Type + * + * Error from I3C Specification v1.1.1 section 5.1.10.2. It is expected + * for the driver to write to this. + */ + enum i3c_sdr_controller_error_types err; + /** Flags for this message */ uint8_t flags; @@ -768,6 +697,19 @@ __subsystem struct i3c_driver_api { struct i3c_device_desc *(*i3c_device_find)(const struct device *dev, const struct i3c_device_id *id); + /** + * ACK or NACK IBI HJ Requests + * + * @see ibi_hj_response() + * + * @param dev Pointer to controller device driver instance. + * @param ack True to ack, False to nack + * + * @return See ibi_hj_response() + */ + int (*ibi_hj_response)(const struct device *dev, + bool ack); + /** * Raise In-Band Interrupt (IBI). * @@ -867,6 +809,39 @@ __subsystem struct i3c_driver_api { */ int (*target_tx_write)(const struct device *dev, uint8_t *buf, uint16_t len, uint8_t hdr_mode); + + /** + * ACK or NACK controller handoffs + * + * This will tell the target to ACK or NACK controller handoffs + * from the CCC GETACCCR + * + * Target device only API. + * + * @see i3c_target_controller_handoff() + * + * @param dev Pointer to the controller device driver instance. + * @param accept True to ACK controller handoffs, False to NACK. + * + * @return See i3c_target_controller_handoff() + */ + int (*target_controller_handoff)(const struct device *dev, + bool accept); + +#ifdef CONFIG_I3C_RTIO + /** + * RTIO + * + * @see i3c_iodev_submit() + * + * @param dev Pointer to the controller device driver instance. + * @param iodev_sqe Pointer to the + * + * @return See i3c_iodev_submit() + */ + void (*iodev_submit)(const struct device *dev, + struct rtio_iodev_sqe *iodev_sqe); +#endif }; /** @@ -920,7 +895,8 @@ struct i3c_device_desc { const struct device * const dev; /** Device Provisioned ID */ - const uint64_t pid:48; + /* TODO: bring back the bitfield */ + const uint64_t pid; /** * Static address for this target device. @@ -1018,6 +994,9 @@ struct i3c_device_desc { uint8_t max_ibi; } data_length; + /** Controller Handoff Delay Parameters */ + uint8_t crhdly1; + /** Describes advanced (Target) capabilities and features */ struct { union { @@ -1070,6 +1049,28 @@ struct i3c_device_desc { uint8_t getcap4; } getcaps; + /* Describes Controller Feature Capabilities */ + struct { + /** + * CRCAPS1 + * - Bit[0]: Hot-Join Support + * - Bit[1]: Group Management Support + * - Bit[2]: Multi-Lane Support + * - Bit[7:3]: Reserved + */ + uint8_t crcaps1; + + /** + * CRCAPS2 + * - Bit[0]: In-Band Interrupt Support + * - Bit[1]: Controller Pass-Back + * - Bit[2]: Deep Sleep Capable + * - Bit[3]: Delayed Controller Handoff + * - Bit[7:4]: Reserved + */ + uint8_t crcaps2; + } crcaps; + /** @cond INTERNAL_HIDDEN */ /** * Private data by the controller to aid in transactions. Do not modify. @@ -1202,6 +1203,12 @@ struct i3c_driver_data { /** Attached I3C/I2C devices and addresses */ struct i3c_dev_attached_list attached_dev; + + /** Received DEFTGTS Pointer */ + struct i3c_ccc_deftgts *deftgts; + + /** DEFTGTS refreshed */ + bool deftgts_refreshed; }; /** @@ -1256,6 +1263,21 @@ struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list, struct i3c_device_desc *i3c_dev_list_i3c_addr_find(const struct device *dev, uint8_t addr); +/** + * @brief Find a I3C target device descriptor by static address. + * + * This finds the I3C target device descriptor in the attached + * device list matching the static address (@p addr) + * + * @param dev Pointer to controller device driver instance. + * @param addr static address to be matched. + * + * @return Pointer to the I3C target device descriptor, or + * `NULL` if none is found. + */ +struct i3c_device_desc *i3c_dev_list_i3c_static_addr_find(const struct device *dev, + uint8_t addr); + /** * @brief Find a I2C target device descriptor by address. * @@ -1659,6 +1681,31 @@ struct i3c_device_desc *i3c_device_find(const struct device *dev, * @{ */ +/** + * @brief ACK or NACK IBI HJ Requests + * + * This tells the controller to Acknowledge or Not Acknowledge + * In-Band Interrupt Hot-Join Requests. + * + * @param dev Pointer to controller device driver instance. + * @param ack True to ack, False to nack + * + * @retval 0 if operation is successful. + * @retval -EIO General input / output error. + */ +static inline int i3c_ibi_hj_response(const struct device *dev, + bool ack) +{ + const struct i3c_driver_api *api = + (const struct i3c_driver_api *)dev->api; + + if (api->ibi_hj_response == NULL) { + return -ENOSYS; + } + + return api->ibi_hj_response(dev, ack); +} + /** * @brief Raise an In-Band Interrupt (IBI). * @@ -2090,20 +2137,75 @@ int i3c_bus_init(const struct device *dev, * This retrieves some basic information: * * Bus Characteristics Register (GETBCR) * * Device Characteristics Register (GETDCR) + * from the device and update the corresponding fields of the device + * descriptor. + * + * This only updates the field(s) in device descriptor + * only if CCC operations succeed. + * + * @param[in,out] target I3C target device descriptor. + * + * @retval 0 if successful. + * @retval -EIO General Input/Output error. + */ +int i3c_device_basic_info_get(struct i3c_device_desc *target); + +/** + * @brief Get advanced information from device and update device descriptor. + * + * This retrieves some information: * * Max Read Length (GETMRL) * * Max Write Length (GETMWL) + * * Get Capabilities (GETCAPS) + * * Max Device Speed (GETMXDS) (if applicable) * from the device and update the corresponding fields of the device * descriptor. * * This only updates the field(s) in device descriptor * only if CCC operations succeed. * + * @note This should only be called after i3c_device_basic_info_get() or + * if the BCR was already obtained through ENTDAA, DEFTGTS, or GETBCR. + * * @param[in,out] target I3C target device descriptor. * * @retval 0 if successful. * @retval -EIO General Input/Output error. */ -int i3c_device_basic_info_get(struct i3c_device_desc *target); +int i3c_device_adv_info_get(struct i3c_device_desc *target); + +/** + * @brief Get all information from device and update device descriptor. + * + * This retrieves all information: + * * Bus Characteristics Register (GETBCR) + * * Device Characteristics Register (GETDCR) + * * Max Read Length (GETMRL) + * * Max Write Length (GETMWL) + * * Get Capabilities (GETCAPS) + * * Max Device Speed (GETMXDS) (if applicable) + * from the device and update the corresponding fields of the device + * descriptor. + * + * This only updates the field(s) in device descriptor + * only if CCC operations succeed. + * + * @param[in,out] target I3C target device descriptor. + * + * @retval 0 if successful. + * @retval -EIO General Input/Output error. + */ +static inline int i3c_device_info_get(struct i3c_device_desc *target) +{ + int rc; + + rc = i3c_device_basic_info_get(target); + if (rc != 0) { + return rc; + } + + return i3c_device_adv_info_get(target); +} /** * @brief Check if the bus has a secondary controller. @@ -2130,6 +2232,226 @@ bool i3c_bus_has_sec_controller(const struct device *dev); */ int i3c_bus_deftgts(const struct device *dev); +/** + * @brief Calculate odd parity + * + * Calculate the Odd Parity of a Target Address. + * + * @param p The 7b target dynamic address + * + * @return The odd parity bit + */ +uint8_t i3c_odd_parity(uint8_t p); + +/** + * @brief Perform Controller Handoff + * + * This performs the controller handoff according to 5.1.7.1 of + * I3C v1.1.1 Specification. + * + * @param target I3C target device descriptor. + * @param requested True if the target requested the Handoff, False if + * the active controller is passing it to a secondary controller + * + * @retval 0 if successful. + * @retval -EIO General Input/Output error. + * @retval -EBUSY Target cannot accept Controller Handoff + */ +int i3c_device_controller_handoff(const struct i3c_device_desc *target, bool requested); + +#ifdef CONFIG_I3C_USE_IBI +/** + * @brief Call back for when Controllership is Handoffed to itself + * + * This reads the DEFTGTS it received earlier and processes it by reading + * the PIDs of all the devices with GETPID and then matching it with known + * PIDS. If it does not match, then it will attempt to grab a mem slab + * for i3c_device_desc. It will then obtain the standard I3C information + * from the device. + * + * @param work pointer to the work item. + */ +void i3c_sec_handoffed(struct k_work *work); +#endif + +#if CONFIG_I3C_NUM_OF_DESC_MEM_SLABS > 0 + +/** + * @brief Allocate memory for a i3c device descriptor + * + * This allocates memory from a mem slab for a i3c_device_desc + * + * @retval Pointer to allocated i3c_device_desc + * @retval NULL if no mem slabs available + */ +struct i3c_device_desc *i3c_device_desc_alloc(void); + +/** + * @brief Free memory from a i3c device descriptor + * + * This frees memory from a mem slab of a i3c_device_desc + * + * @param desc Pointer to allocated i3c_device_desc + */ +void i3c_device_desc_free(struct i3c_device_desc *desc); + +/** + * @brief Report if the i3c device descriptor was from a mem slab + * + * This reports if the i3c_device_desc was from a memory slab + * + * @param desc Pointer to a i3c_device_desc + * + * @return True if from a memory slab, False if not + */ +bool i3c_device_desc_in_pool(struct i3c_device_desc *desc); + +#else + +static inline struct i3c_device_desc *i3c_device_desc_alloc(void) +{ + return NULL; +} + +static inline void i3c_device_desc_free(struct i3c_device_desc *desc) +{ + ARG_UNUSED(desc); +} + +static inline bool i3c_device_desc_in_pool(struct i3c_device_desc *desc) +{ + ARG_UNUSED(desc); + return false; +} + +#endif /* CONFIG_I3C_NUM_OF_DESC_MEM_SLABS > 0 */ + +#if CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS > 0 + +/** + * @brief Allocate memory for a i3c i2c device descriptor + * + * This allocates memory from a mem slab for a i3c_i2c_device_desc + * + * @return Pointer to allocated i3c_i2c_device_desc, NULL if none + * available + */ +struct i3c_i2c_device_desc *i3c_i2c_device_desc_alloc(void); + +/** + * @brief Free memory from a i3c i2c device descriptor + * + * This frees memory from a mem slab of a i3c_i2c_device_desc + * + * @param desc Pointer to allocated i3c_i2c_device_desc + */ +void i3c_i2c_device_desc_free(struct i3c_i2c_device_desc *desc); + +/** + * @brief Report if the i3c i2c device descriptor was from a mem slab + * + * This reports if the i3c_i2c_device_desc was from a memory slab + * + * @param desc Pointer to a i3c_i2c_device_desc + * + * @return True if from a memory slab, False if not + */ +bool i3c_i2c_device_desc_in_pool(struct i3c_i2c_device_desc *desc); + +#else + +static inline struct i3c_i2c_device_desc *i3c_i2c_device_desc_alloc(void) +{ + return NULL; +} + +static inline void i3c_i2c_device_desc_free(struct i3c_i2c_device_desc *desc) +{ + ARG_UNUSED(desc); +} + +static inline bool i3c_i2c_device_desc_in_pool(struct i3c_i2c_device_desc *desc) +{ + ARG_UNUSED(desc); + return false; +} + +#endif /* CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS > 0 */ + +#if defined(CONFIG_I3C_RTIO) || defined(__DOXYGEN__) + +struct i3c_iodev_data { + const struct device *bus; + const struct i3c_device_id dev_id; +}; + +/** + * @brief Fallback submit implementation + * + * This implementation will schedule a blocking I3C transaction on the bus via the RTIO work + * queue. It is only used if the I3C driver did not implement the iodev_submit function. + * + * @param dev Pointer to the device structure for an I3C controller driver. + * @param iodev_sqe Prepared submissions queue entry connected to an iodev + * defined by I3C_DT_IODEV_DEFINE. + */ +void i3c_iodev_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); + +/** + * @brief Submit request(s) to an I3C device with RTIO + * + * @param iodev_sqe Prepared submissions queue entry connected to an iodev + * defined by I3C_DT_IODEV_DEFINE. + */ +static inline void i3c_iodev_submit(struct rtio_iodev_sqe *iodev_sqe) +{ + const struct i3c_iodev_data *data = + (const struct i3c_iodev_data *)iodev_sqe->sqe.iodev->data; + const struct i3c_driver_api *api = (const struct i3c_driver_api *)data->bus->api; + + if (api->iodev_submit == NULL) { + rtio_iodev_sqe_err(iodev_sqe, -ENOSYS); + return; + } + api->iodev_submit(data->bus, iodev_sqe); +} + +extern const struct rtio_iodev_api i3c_iodev_api; + +/** + * @brief Define an iodev for a given dt node on the bus + * + * These do not need to be shared globally but doing so + * will save a small amount of memory. + * + * @param name Symbolic name of the iodev to define + * @param node_id Devicetree node identifier + */ +#define I3C_DT_IODEV_DEFINE(name, node_id) \ + const struct i3c_iodev_data _i3c_iodev_data_##name = { \ + .bus = DEVICE_DT_GET(DT_BUS(node_id)), \ + .dev_id = I3C_DEVICE_ID_DT(node_id), \ + }; \ + RTIO_IODEV_DEFINE(name, &i3c_iodev_api, (void *)&_i3c_iodev_data_##name) + +/** + * @brief Copy the i3c_msgs into a set of RTIO requests + * + * @param r RTIO context + * @param iodev RTIO IODev to target for the submissions + * @param msgs Array of messages + * @param num_msgs Number of i3c msgs in array + * + * @retval sqe Last submission in the queue added + * @retval NULL Not enough memory in the context to copy the requests + */ +struct rtio_sqe *i3c_rtio_copy(struct rtio *r, + struct rtio_iodev *iodev, + const struct i3c_msg *msgs, + uint8_t num_msgs); + +#endif /* CONFIG_I3C_RTIO */ + /* * This needs to be after declaration of struct i3c_driver_api, * or else compiler complains about undefined type inside diff --git a/include/zephyr/drivers/i3c/ccc.h b/include/zephyr/drivers/i3c/ccc.h index 8d662258158b9..98a4e0f020974 100644 --- a/include/zephyr/drivers/i3c/ccc.h +++ b/include/zephyr/drivers/i3c/ccc.h @@ -259,6 +259,14 @@ struct i3c_ccc_target_payload { * write to this after the transfer. */ size_t num_xfer; + + /** + * SDR Error Type + * + * Error from I3C Specification v1.1.1 section 5.1.10.2. It is expected + * for the driver to write to this. + */ + enum i3c_sdr_controller_error_types err; }; /** @@ -289,6 +297,14 @@ struct i3c_ccc_payload { * It is expected for the driver to write to this after the transfer. */ size_t num_xfer; + + /** + * SDR Error Type + * + * Error from I3C Specification v1.1.1 section 5.1.10.2. It is expected + * for the driver to write to this. + */ + enum i3c_sdr_controller_error_types err; } ccc; struct { @@ -499,7 +515,7 @@ struct i3c_ccc_address { * @note For SETDATA, SETNEWDA and SETGRPA, * the address is left-shift by 1, and bit[0] is always 0. * - * @note Fpr SET GETACCCR, the address is left-shift by 1, + * @note For SET GETACCCR, the address is left-shift by 1, * and bit[0] is the calculated odd parity bit. */ uint8_t addr; @@ -623,6 +639,9 @@ union i3c_ccc_getstatus { #define I3C_CCC_GETSTATUS_ACTIVITY_MODE(status) \ FIELD_GET(I3C_CCC_GETSTATUS_ACTIVITY_MODE_MASK, (status)) +/** GETSTATUS Format 1 - Activity Mode Unable to participate in Controller Handoff */ +#define I3C_CCC_GETSTATUS_ACTIVITY_MODE_NCH 0x3 + /** GETSTATUS Format 1 - Number of Pending Interrupts bitmask. */ #define I3C_CCC_GETSTATUS_NUM_INT_MASK GENMASK(3U, 0U) @@ -853,7 +872,7 @@ union i3c_ccc_getmxds { * @param crhdly1 GETMXDS value. */ #define I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE(crhdly1) \ - FIELD_GET(I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE_MASK, (chrdly1)) + FIELD_GET(I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE_MASK, (crhdly1)) /** * @brief Indicate which format of GETCAPS to use. @@ -2119,6 +2138,24 @@ int i3c_ccc_do_deftgts_all(const struct device *controller, int i3c_ccc_do_setbuscon(const struct device *controller, uint8_t *context, uint16_t length); +/** + * @brief Direct GETACCCR for Controller Handoff + * + * Helper function to allow for the Active Controller to pass the + * Controller Role to a Secondary Controller. The returned address + * should match it's dynamic address along with odd parity. + * + * Note it is up to the caller to verify the correct returned address + * + * @param[in] target Pointer to the target device descriptor. + * @param[out] handoff_address Pointer to the address returned by the secondary + * controller. + * + * @return @see i3c_do_ccc + */ +int i3c_ccc_do_getacccr(const struct i3c_device_desc *target, + struct i3c_ccc_address *handoff_address); + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/i3c/error_types.h b/include/zephyr/drivers/i3c/error_types.h new file mode 100644 index 0000000000000..f2793f4133091 --- /dev/null +++ b/include/zephyr/drivers/i3c/error_types.h @@ -0,0 +1,99 @@ +/* + * Copyright 2024 Meta Platforms, Inc. and its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_I3C_ERROR_TYPES_H_ +#define ZEPHYR_INCLUDE_DRIVERS_I3C_ERROR_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief I3C SDR Controller Error Types + * + * These are error types defined by the I3C specification. + * + * #I3C_ERROR_CE_UNKNOWN and #I3C_ERROR_CE_NONE are not + * official error types according to the specification. + * These are there simply to aid in error handling during + * interactions with the I3C drivers and subsystem. + */ +enum i3c_sdr_controller_error_types { + /** Transaction after sending CCC */ + I3C_ERROR_CE0, + + /** Monitoring Error */ + I3C_ERROR_CE1, + + /** No response to broadcast address (0x7E) */ + I3C_ERROR_CE2, + + /** Failed Controller Handoff */ + I3C_ERROR_CE3, + + /** Unknown error (not official error type) */ + I3C_ERROR_CE_UNKNOWN, + + /** No error (not official error type) */ + I3C_ERROR_CE_NONE, + + I3C_ERROR_CE_MAX = I3C_ERROR_CE_UNKNOWN, + I3C_ERROR_CE_INVALID, +}; + +/** + * @brief I3C SDR Target Error Types + * + * These are error types defined by the I3C specification. + * + * #I3C_ERROR_TE_UNKNOWN and #I3C_ERROR_TE_NONE are not + * official error types according to the specification. + * These are there simply to aid in error handling during + * interactions with the I3C drivers and subsystem. + */ +enum i3c_sdr_target_error_types { + /** + * Invalid Broadcast Address or + * Dynamic Address after DA assignment + */ + I3C_ERROR_TE0, + + /** CCC type */ + I3C_ERROR_TE1, + + /** Write Data */ + I3C_ERROR_TE2, + + /** Assigned Address during Dynamic Address Arbitration */ + I3C_ERROR_TE3, + + /** 0x7E/R missing after RESTART during Dynamic Address Arbitration */ + I3C_ERROR_TE4, + + /** Transaction after detecting CCC */ + I3C_ERROR_TE5, + + /** Monitoring Error */ + I3C_ERROR_TE6, + + /** Dead Bus Recovery */ + I3C_ERROR_DBR, + + /** Unknown error (not official error type) */ + I3C_ERROR_TE_UNKNOWN, + + /** No error (not official error type) */ + I3C_ERROR_TE_NONE, + + I3C_ERROR_TE_MAX = I3C_ERROR_TE_UNKNOWN, + I3C_ERROR_TE_INVALID, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_ERROR_TYPES_H_ */ diff --git a/include/zephyr/drivers/i3c/ibi.h b/include/zephyr/drivers/i3c/ibi.h index 6020609b500fa..443d43ecb1587 100644 --- a/include/zephyr/drivers/i3c/ibi.h +++ b/include/zephyr/drivers/i3c/ibi.h @@ -184,6 +184,21 @@ int i3c_ibi_work_enqueue(struct i3c_ibi_work *ibi_work); int i3c_ibi_work_enqueue_target_irq(struct i3c_device_desc *target, uint8_t *payload, size_t payload_len); +/** + * @brief Queue a controllership request IBI for future processing. + * + * This queues up a controllership request IBI in the IBI workqueue + * for future processing. + * + * @param target Pointer to target device descriptor. + * + * @retval 0 If work item is successfully queued. + * @retval -ENOMEM If no more free internal node to + * store IBI work item. + * @retval Others @see k_work_submit_to_queue + */ +int i3c_ibi_work_enqueue_controller_request(struct i3c_device_desc *target); + /** * @brief Queue a hot join IBI for future processing. * diff --git a/include/zephyr/drivers/i3c/rtio.h b/include/zephyr/drivers/i3c/rtio.h new file mode 100644 index 0000000000000..3c5684c7290d9 --- /dev/null +++ b/include/zephyr/drivers/i3c/rtio.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2024 Intel Corporation + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_I3C_RTIO_H_ +#define ZEPHYR_DRIVERS_I3C_RTIO_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Driver context for implementing i3c with rtio + */ +struct i3c_rtio { + struct k_sem lock; + struct k_spinlock slock; + struct rtio *r; + struct mpsc io_q; + struct rtio_iodev iodev; + struct rtio_iodev_sqe *txn_head; + struct rtio_iodev_sqe *txn_curr; + struct i3c_device_desc *i3c_desc; +}; + +/** + * @brief Statically define an i3c_rtio context + * + * @param _name Symbolic name of the context + * @param _sq_sz Submission queue entry pool size + * @param _cq_sz Completion queue entry pool size + */ +#define I3C_RTIO_DEFINE(_name, _sq_sz, _cq_sz) \ + RTIO_DEFINE(CONCAT(_name, _r), _sq_sz, _cq_sz); \ + static struct i3c_rtio _name = { \ + .r = &CONCAT(_name, _r), \ + }; + +/** + * @brief Copy an array of i3c_msgs to rtio submissions and a transaction + * + * @retval sqe Last sqe setup in the copy + * @retval NULL Not enough memory to copy the transaction + */ +struct rtio_sqe *i3c_rtio_copy(struct rtio *r, struct rtio_iodev *iodev, const struct i3c_msg *msgs, + uint8_t num_msgs); + +/** + * @brief Initialize an i3c rtio context + * + * @param ctx I3C RTIO driver context + */ +void i3c_rtio_init(struct i3c_rtio *ctx); + +/** + * @brief Signal that the current (ctx->txn_curr) submission has been completed + * + * @param ctx I3C RTIO driver context + * @param status Completion status, negative values are errors + * + * @retval true Next submission is ready to start + * @retval false No more submissions to work on + */ +bool i3c_rtio_complete(struct i3c_rtio *ctx, int status); + +/** + * @brief Submit, atomically, a submission to work on at some point + * + * @retval true Next submission is ready to start + * @retval false No new submission to start or submissions are in progress already + */ +bool i3c_rtio_submit(struct i3c_rtio *ctx, struct rtio_iodev_sqe *iodev_sqe); + +/** + * @brief Configure the I3C bus controller + * + * Provides a compatible API for the existing i3c_configure API, and blocks the + * caller until the transfer completes. + * + * See i3c_configure(). + */ +int i3c_rtio_configure(struct i3c_rtio *ctx, enum i3c_config_type type, void *config); + +/** + * @brief Transfer i3c messages in a blocking call + * + * Provides a compatible API for the existing i3c_transfer API, and blocks the caller + * until the transfer completes. + * + * See i3c_transfer(). + */ +int i3c_rtio_transfer(struct i3c_rtio *ctx, struct i3c_msg *msgs, uint8_t num_msgs, + struct i3c_device_desc *desc); + +/** + * @brief Perform an I3C bus recovery in a blocking call + * + * Provides a compatible API for the existing i3c_recover API, and blocks the caller + * until the process completes. + * + * See i3c_recover(). + */ +int i3c_rtio_recover(struct i3c_rtio *ctx); + +/** + * @brief Perform an I3C CCC in a blocking call + * + * Provides a compatible API for the existing i3c_do_ccc API, and blocks the caller + * until the process completes. + * + * See i3c_do_ccc(). + */ +int i3c_rtio_ccc(struct i3c_rtio *ctx, struct i3c_ccc_payload *payload); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_DRVIERS_I3C_RTIO_H_ */ diff --git a/include/zephyr/drivers/i3c/target_device.h b/include/zephyr/drivers/i3c/target_device.h index 7d85e03b001e6..699958090bdc2 100644 --- a/include/zephyr/drivers/i3c/target_device.h +++ b/include/zephyr/drivers/i3c/target_device.h @@ -261,6 +261,22 @@ struct i3c_target_callbacks { * @return Ignored. */ int (*stop_cb)(struct i3c_target_config *config); + + /** + * @brief Function called when an active controller handoffs controlership + * to this target. + * + * This function is invoked by the active controller when it handoffs + * controllership to this target. This can happen wither the target has + * requested it or if the active controller chooses to handoff to the + * controller capable target. + * + * @param config Configuration structure associated with the + * device to which the operation is addressed. + * + * @return Ignored. + */ + int (*controller_handoff_cb)(struct i3c_target_config *config); }; __subsystem struct i3c_target_driver_api { @@ -268,6 +284,31 @@ __subsystem struct i3c_target_driver_api { int (*driver_unregister)(const struct device *dev); }; +/** + * @brief Accept or Decline Controller Handoffs + * + * This sets the target to ACK or NACK handoffs from the active + * controller from the CCC GETACCCR. + * + * @param dev Pointer to the device structure for an I3C controller + * driver configured in target mode. + * @param accept True to ACK controller handoffs, False to NACK + * + * @retval 0 Is successful + */ +static inline int i3c_target_controller_handoff(const struct device *dev, + bool accept) +{ + const struct i3c_driver_api *api = + (const struct i3c_driver_api *)dev->api; + + if (api->target_controller_handoff == NULL) { + return -ENOSYS; + } + + return api->target_controller_handoff(dev, accept); +} + /** * @brief Writes to the target's TX FIFO * diff --git a/include/zephyr/drivers/interrupt_controller/intc_rz_ext_irq.h b/include/zephyr/drivers/interrupt_controller/intc_rz_ext_irq.h new file mode 100644 index 0000000000000..4244a039dd546 --- /dev/null +++ b/include/zephyr/drivers/interrupt_controller/intc_rz_ext_irq.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RZ_EXT_IRQ_H_ +#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RZ_EXT_IRQ_H_ + +/** RZ external interrupt callback */ +typedef void (*intc_rz_ext_irq_callback_t)(void *arg); + +/** + * @brief Enable external interrupt for specified channel at NVIC. + * + * @param dev: pointer to interrupt controller instance + * @return 0 on success, or negative value on error + */ +int intc_rz_ext_irq_enable(const struct device *dev); + +/** + * @brief Disable external interrupt for specified channel at NVIC. + * + * @param dev: pointer to interrupt controller instance + * @return 0 on success, or negative value on error + */ +int intc_rz_ext_irq_disable(const struct device *dev); + +/** + * @brief Updates the user callback + * + * @param dev: pointer to interrupt controller instance + * @param cb: callback to set + * @param arg: user data passed to callback + * @return 0 on success, or negative value on error + */ +int intc_rz_ext_irq_set_callback(const struct device *dev, intc_rz_ext_irq_callback_t cb, + void *arg); + +#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RZ_EXT_IRQ_H_ */ diff --git a/include/zephyr/drivers/lora.h b/include/zephyr/drivers/lora.h index 90706595a806a..2f97deef94632 100644 --- a/include/zephyr/drivers/lora.h +++ b/include/zephyr/drivers/lora.h @@ -121,7 +121,7 @@ struct lora_modem_config { * @see lora_recv() for argument descriptions. */ typedef void (*lora_recv_cb)(const struct device *dev, uint8_t *data, uint16_t size, - int16_t rssi, int8_t snr); + int16_t rssi, int8_t snr, void *user_data); /** * @typedef lora_api_config() @@ -168,7 +168,8 @@ typedef int (*lora_api_recv)(const struct device *dev, uint8_t *data, * @param dev Modem to receive data on. * @param cb Callback to run on receiving data. */ -typedef int (*lora_api_recv_async)(const struct device *dev, lora_recv_cb cb); +typedef int (*lora_api_recv_async)(const struct device *dev, lora_recv_cb cb, + void *user_data); /** * @typedef lora_api_test_cw() @@ -286,14 +287,16 @@ static inline int lora_recv(const struct device *dev, uint8_t *data, * @param dev Modem to receive data on. * @param cb Callback to run on receiving data. If NULL, any pending * asynchronous receptions will be cancelled. + * @param user_data User data passed to callback * @return 0 when reception successfully setup, negative on error */ -static inline int lora_recv_async(const struct device *dev, lora_recv_cb cb) +static inline int lora_recv_async(const struct device *dev, lora_recv_cb cb, + void *user_data) { const struct lora_driver_api *api = (const struct lora_driver_api *)dev->api; - return api->recv_async(dev, cb); + return api->recv_async(dev, cb, user_data); } /** diff --git a/include/zephyr/drivers/mfd/ds3231.h b/include/zephyr/drivers/mfd/ds3231.h new file mode 100644 index 0000000000000..8d95703c5d056 --- /dev/null +++ b/include/zephyr/drivers/mfd/ds3231.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Gergo Vari + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_MFD_DS3231_H_ +#define ZEPHYR_INCLUDE_DRIVERS_MFD_DS3231_H_ + +#include + +/** + * @brief Get specified number of registers from an I2C device + * starting at the given register address. + * + * @param dev ds3231 mfd device + * @param start_reg The register address to start at. + * @param buf The buffer array pointer to store results in. + * @param buf_size The amount of register values to return. + * @retval 0 on success + * @retval -errno in case of any bus error + */ +int mfd_ds3231_i2c_get_registers(const struct device *dev, uint8_t start_reg, uint8_t *buf, + const size_t buf_size); + +/** + * @brief Set a register on an I2C device at the given register address. + * + * @param dev ds3231 mfd device + * @param start_reg The register address to set. + * @param buf The value to write to the given address. + * @param buf_size The size of the buffer to be written to the given address. + * @retval 0 on success + * @retval -errno in case of any bus error + */ +int mfd_ds3231_i2c_set_registers(const struct device *dev, uint8_t start_reg, const uint8_t *buf, + const size_t buf_size); + +#endif /* ZEPHYR_INCLUDE_DRIVERS_MFD_DS3231_H_ */ diff --git a/include/zephyr/drivers/mfd/max22017.h b/include/zephyr/drivers/mfd/max22017.h new file mode 100644 index 0000000000000..a8f837020ab21 --- /dev/null +++ b/include/zephyr/drivers/mfd/max22017.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_MFD_MAX22017_H_ +#define ZEPHYR_INCLUDE_DRIVERS_MFD_MAX22017_H_ + +#include + +#define MAX22017_LDAC_TOGGLE_TIME 200 +#define MAX22017_MAX_CHANNEL 2 +#define MAX22017_CRC_POLY 0x8c /* reversed 0x31 poly for crc8-maxim */ + +#define MAX22017_GEN_ID_OFF 0x00 +#define MAX22017_GEN_ID_PROD_ID GENMASK(15, 8) +#define MAX22017_GEN_ID_REV_ID GENMASK(7, 0) + +#define MAX22017_GEN_SERIAL_MSB_OFF 0x01 +#define MAX22017_GEN_SERIAL_MSB_SERIAL_MSB GENMASK(15, 0) + +#define MAX22017_GEN_SERIAL_LSB_OFF 0x02 +#define MAX22017_GEN_SERIAL_LSB_SERIAL_LSB GENMASK(15, 0) + +#define MAX22017_GEN_CNFG_OFF 0x03 +#define MAX22017_GEN_CNFG_OPENWIRE_DTCT_CNFG GENMASK(15, 14) +#define MAX22017_GEN_CNFG_TMOUT_SEL GENMASK(13, 10) +#define MAX22017_GEN_CNFG_TMOUT_CNFG BIT(9) +#define MAX22017_GEN_CNFG_TMOUT_EN BIT(8) +#define MAX22017_GEN_CNFG_THSHDN_CNFG GENMASK(7, 6) +#define MAX22017_GEN_CNFG_OVC_SHDN_CNFG GENMASK(5, 4) +#define MAX22017_GEN_CNFG_OVC_CNFG GENMASK(3, 2) +#define MAX22017_GEN_CNFG_CRC_EN BIT(1) +#define MAX22017_GEN_CNFG_DACREF_SEL BIT(0) + +#define MAX22017_GEN_GPIO_CTRL_OFF 0x04 +#define MAX22017_GEN_GPIO_CTRL_GPIO_EN GENMASK(13, 8) +#define MAX22017_GEN_GPIO_CTRL_GPIO_DIR GENMASK(5, 0) + +#define MAX22017_GEN_GPIO_DATA_OFF 0x05 +#define MAX22017_GEN_GPIO_DATA_GPO_DATA GENMASK(13, 8) +#define MAX22017_GEN_GPIO_DATA_GPI_DATA GENMASK(5, 0) + +#define MAX22017_GEN_GPI_INT_OFF 0x06 +#define MAX22017_GEN_GPI_INT_GPI_POS_EDGE_INT GENMASK(13, 8) +#define MAX22017_GEN_GPI_INT_GPI_NEG_EDGE_INT GENMASK(5, 0) + +#define MAX22017_GEN_GPI_INT_STA_OFF 0x07 +#define MAX22017_GEN_GPI_INT_STA_GPI_POS_EDGE_INT_STA GENMASK(13, 8) +#define MAX22017_GEN_GPI_INT_STA_GPI_NEG_EDGE_INT_STA GENMASK(5, 0) + +#define MAX22017_GEN_INT_OFF 0x08 +#define MAX22017_GEN_INT_FAIL_INT BIT(15) +#define MAX22017_GEN_INT_CONV_OVF_INT GENMASK(13, 12) +#define MAX22017_GEN_INT_OPENWIRE_DTCT_INT GENMASK(11, 10) +#define MAX22017_GEN_INT_HVDD_INT BIT(9) +#define MAX22017_GEN_INT_TMOUT_INT BIT(8) +#define MAX22017_GEN_INT_THSHDN_INT GENMASK(7, 6) +#define MAX22017_GEN_INT_THWRNG_INT GENMASK(5, 4) +#define MAX22017_GEN_INT_OVC_INT GENMASK(3, 2) +#define MAX22017_GEN_INT_CRC_INT BIT(1) +#define MAX22017_GEN_INT_GPI_INT BIT(0) + +#define MAX22017_GEN_INTEN_OFF 0x09 +#define MAX22017_GEN_INTEN_CONV_OVF_INTEN GENMASK(13, 12) +#define MAX22017_GEN_INTEN_OPENWIRE_DTCT_INTEN GENMASK(11, 10) +#define MAX22017_GEN_INTEN_HVDD_INTEN BIT(9) +#define MAX22017_GEN_INTEN_TMOUT_INTEN BIT(8) +#define MAX22017_GEN_INTEN_THSHDN_INTEN GENMASK(7, 6) +#define MAX22017_GEN_INTEN_THWRNG_INTEN GENMASK(5, 4) +#define MAX22017_GEN_INTEN_OVC_INTEN GENMASK(3, 2) +#define MAX22017_GEN_INTEN_CRC_INTEN BIT(1) +#define MAX22017_GEN_INTEN_GPI_INTEN BIT(0) + +#define MAX22017_GEN_RST_CTRL_OFF 0x0A +#define MAX22017_GEN_RST_CTRL_AO_COEFF_RELOAD GENMASK(15, 14) +#define MAX22017_GEN_RST_CTRL_GEN_RST BIT(9) + +#define MAX22017_AO_CMD_OFF 0x40 +#define MAX22017_AO_CMD_AO_LD_CTRL GENMASK(15, 14) + +#define MAX22017_AO_STA_OFF 0x41 +#define MAX22017_AO_STA_BUSY_STA GENMASK(15, 14) +#define MAX22017_AO_STA_SLEW_STA GENMASK(13, 12) +#define MAX22017_AO_STA_FAIL_STA BIT(0) + +#define MAX22017_AO_CNFG_OFF 0x42 +#define MAX22017_AO_CNFG_AO_LD_CNFG GENMASK(15, 14) +#define MAX22017_AO_CNFG_AO_CM_SENSE GENMASK(13, 12) +#define MAX22017_AO_CNFG_AO_UNI GENMASK(11, 10) +#define MAX22017_AO_CNFG_AO_MODE GENMASK(9, 8) +#define MAX22017_AO_CNFG_AO_OPENWIRE_DTCT_LMT GENMASK(5, 4) +#define MAX22017_AO_CNFG_AI_EN GENMASK(3, 2) +#define MAX22017_AO_CNFG_AO_EN GENMASK(1, 0) + +#define MAX22017_AO_SLEW_RATE_CHn_OFF(n) (0x43 + n) +#define MAX22017_AO_SLEW_RATE_CHn_AO_SR_EN_CHn BIT(5) +#define MAX22017_AO_SLEW_RATE_CHn_AO_SR_SEL_CHn BIT(4) +#define MAX22017_AO_SLEW_RATE_CHn_AO_SR_STEP_SIZE_CHn GENMASK(3, 2) +#define MAX22017_AO_SLEW_RATE_CHn_AO_SR_UPDATE_RATE_CHn GENMASK(1, 0) + +#define MAX22017_AO_DATA_CHn_OFF(n) (0x45 + n) +#define MAX22017_AO_DATA_CHn_AO_DATA_CH GENMASK(15, 0) + +#define MAX22017_AO_OFFSET_CORR_CHn_OFF(n) (0x47 + (2 * n)) +#define MAX22017_AO_OFFSET_CORR_CHn_AO_OFFSET_CH GENMASK(15, 0) + +#define MAX22017_AO_GAIN_CORR_CHn_OFF(n) (0x48 + (2 * n)) +#define MAX22017_AO_GAIN_CORR_CHn_AO_GAIN_CH GENMASK(15, 0) + +#define MAX22017_SPI_TRANS_ADDR GENMASK(7, 1) +#define MAX22017_SPI_TRANS_DIR BIT(0) +#define MAX22017_SPI_TRANS_PAYLOAD GENMASK(15, 0) + +/** + * @defgroup mdf_interface_max22017 MFD MAX22017 interface + * @ingroup mfd_interfaces + * @{ + */ + +/** + * @brief Read register from max22017 + * + * @param dev max22017 mfd device + * @param addr register address to read from + * @param value pointer to buffer for received data + * @retval 0 If successful + * @retval -errno In case of any error (see spi_transceive_dt()) + */ +int max22017_reg_read(const struct device *dev, uint8_t addr, uint16_t *value); + +/** + * @brief Write register to max22017 + * + * @param dev max22017 mfd device + * @param addr register address to write to + * @param value content to write + * @retval 0 If successful + * @retval -errno In case of any error (see spi_write_dt()) + */ +int max22017_reg_write(const struct device *dev, uint8_t addr, uint16_t value); + +/** + * @} + */ + +struct max22017_data { + const struct device *dev; + struct k_mutex lock; + struct k_work int_work; + struct gpio_callback callback_int; + bool crc_enabled; +#ifdef CONFIG_GPIO_MAX22017 + sys_slist_t callbacks_gpi; +#endif +}; + +#endif /* ZEPHYR_INCLUDE_DRIVERS_MFD_MAX22017_H_ */ diff --git a/include/zephyr/drivers/mfd/npm2100.h b/include/zephyr/drivers/mfd/npm2100.h index 8a45925af99c2..0344d2eed4b3d 100644 --- a/include/zephyr/drivers/mfd/npm2100.h +++ b/include/zephyr/drivers/mfd/npm2100.h @@ -92,15 +92,18 @@ int mfd_npm2100_reset(const struct device *dev); * @brief npm2100 hibernate * * Enters low power state, and wakes after specified time or "shphld" pin signal. + * Pass-through mode can be used when the battery voltage is high enough to supply the pmic directly + * without boosting. This lowers the power consumption of the pmic when hibernate mode is active. * * @param dev npm2100 mfd device * @param time_ms timer value in ms. Set to 0 to disable timer. + * @param pass_through set to use pass-through hibernate mode. * @retval 0 If successful * @retval -EINVAL if time value is too large * @retval -EBUSY if the timer is already in use. * @retval -errno In case of any bus error (see i2c_write_dt()) */ -int mfd_npm2100_hibernate(const struct device *dev, uint32_t time_ms); +int mfd_npm2100_hibernate(const struct device *dev, uint32_t time_ms, bool pass_through); /** * @brief Add npm2100 event callback diff --git a/include/zephyr/drivers/mic_privacy/intel/mic_privacy.h b/include/zephyr/drivers/mic_privacy/intel/mic_privacy.h new file mode 100644 index 0000000000000..950add9bab37b --- /dev/null +++ b/include/zephyr/drivers/mic_privacy/intel/mic_privacy.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ZEPHYR_INCLUDE_MIC_PRIVACY_H__ +#define __ZEPHYR_INCLUDE_MIC_PRIVACY_H__ + +#include +#include +#include +#include +#include +#include +#include + +enum mic_privacy_policy { + MIC_PRIVACY_DISABLED = 0, + MIC_PRIVACY_HW_MANAGED = 1, + MIC_PRIVACY_FW_MANAGED = 2, + MIC_PRIVACY_FORCE_MIC_DISABLED = 3, +}; + +/* has to match HW register definition + * (DZLS bit field in DFMICPVCP register) + */ +union mic_privacy_mask { + uint32_t value; + struct { + uint32_t sndw:7; + uint32_t dmic:1; + }; +}; + +struct intel_adsp_mic_priv_data { + uint8_t rsvd; +}; + +struct intel_adsp_mic_priv_cfg { + uint32_t base; + uint32_t regblock_size; +}; + +struct mic_privacy_api_funcs { + void (*enable_fw_managed_irq)(bool enable_irq, const void *fn); + void (*clear_fw_managed_irq)(); + void (*enable_dmic_irq)(bool enable_irq, const void *fn); + bool (*get_dmic_irq_status)(void); + void (*clear_dmic_irq_status)(void); + enum mic_privacy_policy (*get_policy)(); + uint32_t (*get_privacy_policy_register_raw_value)(); + uint32_t (*get_dma_data_zeroing_wait_time)(); + uint32_t (*get_dma_data_zeroing_link_select)(); + uint32_t (*get_dmic_mic_disable_status)(void); + uint32_t (*get_fw_managed_mic_disable_status)(); + void (*set_fw_managed_mode)(bool is_fw_managed_enabled); + void (*set_fw_mic_disable_status)(bool fw_mic_disable_status); + uint32_t (*get_fw_mic_disable_status)(); +}; + +#endif diff --git a/include/zephyr/drivers/mipi_dbi.h b/include/zephyr/drivers/mipi_dbi.h index 79f26d3d71fd8..109741e3d84b4 100644 --- a/include/zephyr/drivers/mipi_dbi.h +++ b/include/zephyr/drivers/mipi_dbi.h @@ -112,6 +112,30 @@ extern "C" { #define MIPI_DBI_CONFIG_DT_INST(inst, operation_, delay_) \ MIPI_DBI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_) +/** + * @brief Get the MIPI DBI TE mode from devicetree + * + * Gets the MIPI DBI TE mode from a devicetree property. + * @param node_id Devicetree node identifier for the MIPI DBI device with the + * TE mode property + * @param edge_prop Property name for the TE mode that should be read from + * devicetree + */ +#define MIPI_DBI_TE_MODE_DT(node_id, edge_prop) \ + DT_STRING_UPPER_TOKEN(node_id, edge_prop) + +/** + * @brief Get the MIPI DBI TE mode for device instance + * + * Gets the MIPI DBI TE mode from a devicetree property. Equivalent to + * MIPI_DBI_TE_MODE_DT(DT_DRV_INST(inst), edge_mode). + * @param inst Instance of the device to get the TE mode for + * @param edge_prop Property name for the TE mode that should be read from + * devicetree + */ +#define MIPI_DBI_TE_MODE_DT_INST(inst, edge_prop) \ + DT_STRING_UPPER_TOKEN(DT_DRV_INST(inst), edge_prop) + /** * @brief MIPI DBI controller configuration * @@ -141,6 +165,9 @@ __subsystem struct mipi_dbi_driver_api { int (*reset)(const struct device *dev, k_timeout_t delay); int (*release)(const struct device *dev, const struct mipi_dbi_config *config); + int (*configure_te)(const struct device *dev, + uint8_t edge, + k_timeout_t delay); }; /** @@ -293,6 +320,45 @@ static inline int mipi_dbi_release(const struct device *dev, return api->release(dev, config); } +/** + * @brief Configures MIPI DBI tearing effect signal + * + * Many displays provide a tearing effect signal, which can be configured + * to pulse at each vsync interval or each hsync interval. This signal can be + * used by the MCU to determine when to transmit a new frame so that the + * read pointer of the display never overlaps with the write pointer from the + * MCU. This function configures the MIPI DBI controller to delay transmitting + * display frames until the selected tearing effect signal edge occurs. + * + * The delay will occur on the on each call to @ref mipi_dbi_write_display + * where the ``frame_incomplete`` flag was set within the buffer descriptor + * provided with the prior call, as this indicates the buffer being written + * in this call is the first buffer of a new frame. + * + * Note that most display controllers will need to enable the TE signal + * using vendor specific commands before the MIPI DBI controller can react + * to it. + * + * @param dev mipi dbi controller + * @param edge which edge of the TE signal to start transmitting on + * @param delay_us how many microseconds after TE edge to start transmission + * @retval -EIO I/O error + * @retval -ENOSYS not implemented + * @retval -ENOTSUP not supported + */ +static inline int mipi_dbi_configure_te(const struct device *dev, + uint8_t edge, + uint32_t delay_us) +{ + const struct mipi_dbi_driver_api *api = + (const struct mipi_dbi_driver_api *)dev->api; + + if (api->configure_te == NULL) { + return -ENOSYS; + } + return api->configure_te(dev, edge, K_USEC(delay_us)); +} + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h b/include/zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h index 927fcba5e55e5..fae9db5eb0e72 100644 --- a/include/zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h +++ b/include/zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023,2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,4 +13,10 @@ */ #define MCUX_DSI_2L_FB_DATA BIT(0x1) +/* + * HW specific flag - user set this bit in message flag and after the + * transfer bus will enter ULPS. + */ +#define MCUX_DSI_2L_ULPS BIT(0x2) + #endif /* ZEPHYR_INCLUDE_DRIVERS_MIPI_DSI_MCUX_2L_ */ diff --git a/include/zephyr/drivers/misc/ft8xx/ft8xx.h b/include/zephyr/drivers/misc/ft8xx/ft8xx.h index 5b9dc589fbd6f..65f42e6fbb388 100644 --- a/include/zephyr/drivers/misc/ft8xx/ft8xx.h +++ b/include/zephyr/drivers/misc/ft8xx/ft8xx.h @@ -13,6 +13,7 @@ #define ZEPHYR_DRIVERS_MISC_FT8XX_FT8XX_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -45,8 +46,11 @@ struct ft8xx_touch_transform { * @brief Callback API to inform API user that FT8xx triggered interrupt * * This callback is called from IRQ context. + * + * @param dev Pointer to the device structure for the driver instance + * @param user_data Pointer to user data provided during callback registration */ -typedef void (*ft8xx_int_callback)(void); +typedef void (*ft8xx_int_callback)(const struct device *dev, void *user_data); /** * @brief Calibrate touchscreen @@ -59,9 +63,11 @@ typedef void (*ft8xx_int_callback)(void); * ft8xx_touch_transform_set() to avoid calibrating touchscreen after each * device reset. * + * @param dev Pointer to the device structure for the driver instance * @param data Pointer to touchscreen transform structure to populate */ -void ft8xx_calibrate(struct ft8xx_touch_transform *data); +void ft8xx_calibrate(const struct device *dev, + struct ft8xx_touch_transform *data); /** * @brief Set touchscreen calibration data @@ -70,16 +76,20 @@ void ft8xx_calibrate(struct ft8xx_touch_transform *data); * Data is to be obtained from calibration procedure started with * ft8xx_calibrate(). * + * @param dev Pointer to the device structure for the driver instance * @param data Pointer to touchscreen transform structure to apply */ -void ft8xx_touch_transform_set(const struct ft8xx_touch_transform *data); +void ft8xx_touch_transform_set(const struct device *dev, + const struct ft8xx_touch_transform *data); /** * @brief Get tag of recently touched element * + * @param dev Pointer to the device structure for the driver instance + * * @return Tag value 0-255 of recently touched element */ -int ft8xx_get_touch_tag(void); +int ft8xx_get_touch_tag(const struct device *dev); /** * @brief Set callback executed when FT8xx triggers interrupt @@ -91,9 +101,13 @@ int ft8xx_get_touch_tag(void); * kept active until ft8xx_get_touch_tag() is called. It results in single * execution of @p callback until ft8xx_get_touch_tag() is called. * - * @param callback Pointer to function called when FT8xx triggers interrupt + * @param dev Pointer to the device structure for the driver instance + * @param callback Pointer to function called when FT8xx triggers interrupt + * @param user_data Pointer to user data to be passed to the @p callback */ -void ft8xx_register_int(ft8xx_int_callback callback); +void ft8xx_register_int(const struct device *dev, + ft8xx_int_callback callback, + void *user_data); /** * @} diff --git a/include/zephyr/drivers/misc/ft8xx/ft8xx_common.h b/include/zephyr/drivers/misc/ft8xx/ft8xx_common.h index 2fde40e740a5d..64874d8b801ea 100644 --- a/include/zephyr/drivers/misc/ft8xx/ft8xx_common.h +++ b/include/zephyr/drivers/misc/ft8xx/ft8xx_common.h @@ -13,6 +13,7 @@ #define ZEPHYR_DRIVERS_MISC_FT8XX_FT8XX_COMMON_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -28,53 +29,59 @@ extern "C" { /** * @brief Write 1 byte (8 bits) to FT8xx memory * + * @param dev Pointer to the device structure for the driver instance * @param address Memory address to write to * @param data Byte to write */ -void ft8xx_wr8(uint32_t address, uint8_t data); +void ft8xx_wr8(const struct device *dev, uint32_t address, uint8_t data); /** * @brief Write 2 bytes (16 bits) to FT8xx memory * + * @param dev Pointer to the device structure for the driver instance * @param address Memory address to write to * @param data Value to write */ -void ft8xx_wr16(uint32_t address, uint16_t data); +void ft8xx_wr16(const struct device *dev, uint32_t address, uint16_t data); /** * @brief Write 4 bytes (32 bits) to FT8xx memory * + * @param dev Pointer to the device structure for the driver instance * @param address Memory address to write to * @param data Value to write */ -void ft8xx_wr32(uint32_t address, uint32_t data); +void ft8xx_wr32(const struct device *dev, uint32_t address, uint32_t data); /** * @brief Read 1 byte (8 bits) from FT8xx memory * + * @param dev Pointer to the device structure for the driver instance * @param address Memory address to read from * * @return Value read from memory */ -uint8_t ft8xx_rd8(uint32_t address); +uint8_t ft8xx_rd8(const struct device *dev, uint32_t address); /** * @brief Read 2 bytes (16 bits) from FT8xx memory * + * @param dev Pointer to the device structure for the driver instance * @param address Memory address to read from * * @return Value read from memory */ -uint16_t ft8xx_rd16(uint32_t address); +uint16_t ft8xx_rd16(const struct device *dev, uint32_t address); /** * @brief Read 4 bytes (32 bits) from FT8xx memory * + * @param dev Pointer to the device structure for the driver instance * @param address Memory address to read from * * @return Value read from memory */ -uint32_t ft8xx_rd32(uint32_t address); +uint32_t ft8xx_rd32(const struct device *dev, uint32_t address); /** * @} diff --git a/include/zephyr/drivers/misc/ft8xx/ft8xx_copro.h b/include/zephyr/drivers/misc/ft8xx/ft8xx_copro.h index 0913656ffde26..c6c899a0fca63 100644 --- a/include/zephyr/drivers/misc/ft8xx/ft8xx_copro.h +++ b/include/zephyr/drivers/misc/ft8xx/ft8xx_copro.h @@ -13,6 +13,7 @@ #define ZEPHYR_DRIVERS_MISC_FT8XX_FT8XX_COPRO_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -65,19 +66,24 @@ extern "C" { /** * @brief Execute a display list command by co-processor engine * + * @param dev Device structure * @param cmd Display list command to execute */ -void ft8xx_copro_cmd(uint32_t cmd); +void ft8xx_copro_cmd(const struct device *dev, uint32_t cmd); /** * @brief Start a new display list + * + * @param dev Device structure */ -void ft8xx_copro_cmd_dlstart(void); +void ft8xx_copro_cmd_dlstart(const struct device *dev); /** * @brief Swap the current display list + * + * @param dev Device structure */ -void ft8xx_copro_cmd_swap(void); +void ft8xx_copro_cmd_swap(const struct device *dev); /** * @brief Draw text @@ -88,17 +94,19 @@ void ft8xx_copro_cmd_swap(void); * the text in both directions. @ref FT8XX_OPT_RIGHTX right-justifies the text, * so that the @p x is the rightmost pixel. * + * @param dev Device structure * @param x x-coordinate of text base, in pixels * @param y y-coordinate of text base, in pixels * @param font Font to use for text, 0-31. 16-31 are ROM fonts * @param options Options to apply * @param s Character string to display, terminated with a null character */ -void ft8xx_copro_cmd_text(int16_t x, - int16_t y, - int16_t font, - uint16_t options, - const char *s); +void ft8xx_copro_cmd_text(const struct device *dev, + int16_t x, + int16_t y, + int16_t font, + uint16_t options, + const char *s); /** * @brief Draw a decimal number @@ -113,17 +121,19 @@ void ft8xx_copro_cmd_text(int16_t x, * If @ref FT8XX_OPT_SIGNED is given, the number is treated as signed, and * prefixed by a minus sign if negative. * + * @param dev Device structure * @param x x-coordinate of text base, in pixels * @param y y-coordinate of text base, in pixels * @param font Font to use for text, 0-31. 16-31 are ROM fonts * @param options Options to apply * @param n The number to display. */ -void ft8xx_copro_cmd_number(int16_t x, - int16_t y, - int16_t font, - uint16_t options, - int32_t n); +void ft8xx_copro_cmd_number(const struct device *dev, + int16_t x, + int16_t y, + int16_t font, + uint16_t options, + int32_t n); /** * @brief Execute the touch screen calibration routine @@ -134,9 +144,10 @@ void ft8xx_copro_cmd_number(int16_t x, * engine overlays the touch targets on the current display list, gathers the * calibration input and updates REG_TOUCH_TRANSFORM_A-F. * + * @param dev Device structure * @param result Calibration result, written with 0 on failure of calibration */ -void ft8xx_copro_cmd_calibrate(uint32_t *result); +void ft8xx_copro_cmd_calibrate(const struct device *dev, uint32_t *result); /** * @} diff --git a/include/zephyr/drivers/misc/ft8xx/ft8xx_reference_api.h b/include/zephyr/drivers/misc/ft8xx/ft8xx_reference_api.h index c54dcdfc1b3ed..3fb1707760875 100644 --- a/include/zephyr/drivers/misc/ft8xx/ft8xx_reference_api.h +++ b/include/zephyr/drivers/misc/ft8xx/ft8xx_reference_api.h @@ -46,7 +46,7 @@ extern "C" { */ static inline void wr8(uint32_t address, uint8_t data) { - ft8xx_wr8(address, data); + ft8xx_wr8(DEVICE_DT_GET_ONE(ftdi_ft800), address, data); } /** @@ -57,7 +57,7 @@ static inline void wr8(uint32_t address, uint8_t data) */ static inline void wr16(uint32_t address, uint16_t data) { - ft8xx_wr16(address, data); + ft8xx_wr16(DEVICE_DT_GET_ONE(ftdi_ft800), address, data); } /** @@ -68,7 +68,7 @@ static inline void wr16(uint32_t address, uint16_t data) */ static inline void wr32(uint32_t address, uint32_t data) { - ft8xx_wr32(address, data); + ft8xx_wr32(DEVICE_DT_GET_ONE(ftdi_ft800), address, data); } /** @@ -80,7 +80,7 @@ static inline void wr32(uint32_t address, uint32_t data) */ static inline uint8_t rd8(uint32_t address) { - return ft8xx_rd8(address); + return ft8xx_rd8(DEVICE_DT_GET_ONE(ftdi_ft800), address); } /** @@ -92,7 +92,7 @@ static inline uint8_t rd8(uint32_t address) */ static inline uint16_t rd16(uint32_t address) { - return ft8xx_rd16(address); + return ft8xx_rd16(DEVICE_DT_GET_ONE(ftdi_ft800), address); } /** @@ -104,7 +104,7 @@ static inline uint16_t rd16(uint32_t address) */ static inline uint32_t rd32(uint32_t address) { - return ft8xx_rd32(address); + return ft8xx_rd32(DEVICE_DT_GET_ONE(ftdi_ft800), address); } @@ -152,7 +152,7 @@ static inline uint32_t rd32(uint32_t address) */ static inline void cmd(uint32_t command) { - ft8xx_copro_cmd(command); + ft8xx_copro_cmd(DEVICE_DT_GET_ONE(ftdi_ft800), command); } /** @@ -160,7 +160,7 @@ static inline void cmd(uint32_t command) */ static inline void cmd_dlstart(void) { - ft8xx_copro_cmd_dlstart(); + ft8xx_copro_cmd_dlstart(DEVICE_DT_GET_ONE(ftdi_ft800)); } /** @@ -168,7 +168,7 @@ static inline void cmd_dlstart(void) */ static inline void cmd_swap(void) { - ft8xx_copro_cmd_swap(); + ft8xx_copro_cmd_swap(DEVICE_DT_GET_ONE(ftdi_ft800)); } /** @@ -191,7 +191,7 @@ static inline void cmd_text(int16_t x, uint16_t options, const char *s) { - ft8xx_copro_cmd_text(x, y, font, options, s); + ft8xx_copro_cmd_text(DEVICE_DT_GET_ONE(ftdi_ft800), x, y, font, options, s); } /** @@ -218,7 +218,7 @@ static inline void cmd_number(int16_t x, uint16_t options, int32_t n) { - ft8xx_copro_cmd_number(x, y, font, options, n); + ft8xx_copro_cmd_number(DEVICE_DT_GET_ONE(ftdi_ft800), x, y, font, options, n); } /** @@ -234,7 +234,7 @@ static inline void cmd_number(int16_t x, */ static inline void cmd_calibrate(uint32_t *result) { - ft8xx_copro_cmd_calibrate(result); + ft8xx_copro_cmd_calibrate(DEVICE_DT_GET_ONE(ftdi_ft800), result); } diff --git a/include/zephyr/drivers/misc/renesas_ra_external_interrupt/renesas_ra_external_interrupt.h b/include/zephyr/drivers/misc/renesas_ra_external_interrupt/renesas_ra_external_interrupt.h new file mode 100644 index 0000000000000..9876da3f31302 --- /dev/null +++ b/include/zephyr/drivers/misc/renesas_ra_external_interrupt/renesas_ra_external_interrupt.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_MISC_RENESAS_RA_EXTERNAL_INTERRUPT_H_ +#define ZEPHYR_DRIVERS_MISC_RENESAS_RA_EXTERNAL_INTERRUPT_H_ + +#include + +struct gpio_ra_callback { + struct device *port; + uint8_t port_num; + uint8_t pin; + enum gpio_int_trig trigger; + enum gpio_int_mode mode; + void (*isr)(const struct device *dev, gpio_pin_t pin); +}; + +int gpio_ra_interrupt_set(const struct device *dev, struct gpio_ra_callback *callback); +void gpio_ra_interrupt_unset(const struct device *dev, uint8_t port_num, uint8_t pin); + +#endif /* ZEPHYR_DRIVERS_MISC_RENESAS_RA_EXTERNAL_INTERRUPT_H_ */ diff --git a/include/zephyr/drivers/modem/hl7800.h b/include/zephyr/drivers/modem/hl7800.h index 6cb880e6142ab..c784a7895299c 100644 --- a/include/zephyr/drivers/modem/hl7800.h +++ b/include/zephyr/drivers/modem/hl7800.h @@ -111,6 +111,12 @@ enum mdm_hl7800_event { HL7800_EVENT_POLTE_LOCATE_STATUS, HL7800_EVENT_POLTE, HL7800_EVENT_SITE_SURVEY, + HL7800_EVENT_STATE, +}; + +enum mdm_hl7800_state { + HL7800_STATE_NOT_READY = 0, + HL7800_STATE_INITIALIZED, }; enum mdm_hl7800_startup_state { @@ -227,25 +233,26 @@ struct mdm_hl7800_polte_location_data { /** * event - The type of event - * event_data - Pointer to event specific data structure - * HL7800_EVENT_NETWORK_STATE_CHANGE - compound event + * event_data - Pointer to event specific data structure: + * HL7800_EVENT_NETWORK_STATE_CHANGE - mdm_hl7800_compound_event * HL7800_EVENT_APN_UPDATE - struct mdm_hl7800_apn * HL7800_EVENT_RSSI - int * HL7800_EVENT_SINR - int - * HL7800_EVENT_STARTUP_STATE_CHANGE - compound event - * HL7800_EVENT_SLEEP_STATE_CHANGE - compound event + * HL7800_EVENT_STARTUP_STATE_CHANGE - mdm_hl7800_compound_event + * HL7800_EVENT_SLEEP_STATE_CHANGE - mdm_hl7800_compound_event * HL7800_EVENT_RAT - int * HL7800_EVENT_BANDS - string * HL7800_EVENT_ACTIVE_BANDS - string - * HL7800_EVENT_FOTA_STATE - compound event + * HL7800_EVENT_FOTA_STATE - mdm_hl7800_compound_event * HL7800_EVENT_FOTA_COUNT - uint32_t * HL7800_EVENT_REVISION - string - * HL7800_EVENT_GPS - compound event + * HL7800_EVENT_GPS - mdm_hl7800_compound_event * HL7800_EVENT_GPS_POSITION_STATUS int * HL7800_EVENT_POLTE_REGISTRATION mdm_hl7800_polte_registration_event_data * HL7800_EVENT_POLTE mdm_hl7800_polte_location_data * HL7800_EVENT_POLTE_LOCATE_STATUS int * HL7800_EVENT_SITE_SURVEY mdm_hl7800_site_survey + * HL7800_EVENT_STATE mdm_hl7800_compound_event */ typedef void (*mdm_hl7800_event_callback_t)(enum mdm_hl7800_event event, void *event_data); @@ -265,7 +272,7 @@ int32_t mdm_hl7800_power_off(void); /** * @brief Reset the HL7800 (and allow it to reconfigure). * - * @return int32_t 0 for success + * @return int32_t >= 0 for success, < 0 for failure */ int32_t mdm_hl7800_reset(void); @@ -279,12 +286,18 @@ void mdm_hl7800_wakeup(bool awake); /** * @brief Send an AT command to the HL7800. - * @note this API should only be used for debug purposes. + * @note This API should only be used for debug purposes. + * It is possible to break the driver using this API. * * @param data AT command string + * @param resp_timeout Timeout in seconds to wait for the response + * @param resp Pointer to the response buffer. This can be NULL to ignore the response. + * @param resp_len Input: length of the response buffer, Output: length of the response. + * This can be NULL. * @return int32_t 0 for success */ -int32_t mdm_hl7800_send_at_cmd(const uint8_t *data); +int32_t mdm_hl7800_send_at_cmd(const uint8_t *data, uint8_t resp_timeout, char *resp, + uint16_t *resp_len); /** * @brief Get the signal quality of the HL7800. diff --git a/include/zephyr/drivers/pinctrl.h b/include/zephyr/drivers/pinctrl.h index 33948c3383900..cfababd114907 100644 --- a/include/zephyr/drivers/pinctrl.h +++ b/include/zephyr/drivers/pinctrl.h @@ -157,10 +157,10 @@ struct pinctrl_dev_config { #define Z_PINCTRL_STATE_INIT(state_idx, node_id) \ COND_CODE_1(Z_PINCTRL_SKIP_STATE(state_idx, node_id), (), \ ({ \ - .id = Z_PINCTRL_STATE_ID(state_idx, node_id), \ .pins = Z_PINCTRL_STATE_PINS_NAME(state_idx, node_id), \ .pin_cnt = ARRAY_SIZE(Z_PINCTRL_STATE_PINS_NAME(state_idx, \ - node_id)) \ + node_id)), \ + .id = Z_PINCTRL_STATE_ID(state_idx, node_id) \ })) /** diff --git a/include/zephyr/drivers/pwm/pwm_fake.h b/include/zephyr/drivers/pwm/pwm_fake.h new file mode 100644 index 0000000000000..4d430e75113f1 --- /dev/null +++ b/include/zephyr/drivers/pwm/pwm_fake.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024, Kickmaker + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef INCLUDE_DRIVERS_PWM_PWM_FAKE_H_ +#define INCLUDE_DRIVERS_PWM_PWM_FAKE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +DECLARE_FAKE_VALUE_FUNC(int, fake_pwm_set_cycles, const struct device *, uint32_t, uint32_t, + uint32_t, pwm_flags_t); + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_DRIVERS_PWM_PWM_FAKE_H_ */ diff --git a/include/zephyr/drivers/regulator/fake.h b/include/zephyr/drivers/regulator/fake.h index d91161dbc7a88..c52d35a56e768 100644 --- a/include/zephyr/drivers/regulator/fake.h +++ b/include/zephyr/drivers/regulator/fake.h @@ -23,6 +23,9 @@ DECLARE_FAKE_VALUE_FUNC(int, regulator_fake_set_voltage, const struct device *, int32_t, int32_t); DECLARE_FAKE_VALUE_FUNC(int, regulator_fake_get_voltage, const struct device *, int32_t *); +DECLARE_FAKE_VALUE_FUNC(unsigned int, regulator_fake_count_current_limits, const struct device *); +DECLARE_FAKE_VALUE_FUNC(int, regulator_fake_list_current_limit, const struct device *, unsigned int, + int32_t *); DECLARE_FAKE_VALUE_FUNC(int, regulator_fake_set_current_limit, const struct device *, int32_t, int32_t); DECLARE_FAKE_VALUE_FUNC(int, regulator_fake_get_current_limit, diff --git a/include/zephyr/drivers/retained_mem/nrf_retained_mem.h b/include/zephyr/drivers/retained_mem/nrf_retained_mem.h new file mode 100644 index 0000000000000..376673c92d152 --- /dev/null +++ b/include/zephyr/drivers/retained_mem/nrf_retained_mem.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_NRF_RETAINED_MEM_H +#define ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_NRF_RETAINED_MEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if defined(CONFIG_RETAINED_MEM_NRF_RAM_CTRL) || defined(__DOXYGEN__) +/** @brief Apply memory retention settings. + * + * Memory retention settings to apply are derived from devicetree configuration. + * + * @retval 0 if the retention settings were applied successfully. + * @retval -ENOTSUP if retention configuration is not present in devicetree. + */ +int z_nrf_retained_mem_retention_apply(void); +#else +static inline int z_nrf_retained_mem_retention_apply(void) +{ + return -ENOTSUP; +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_RETAINED_MEM_NRF_RETAINED_MEM_H */ diff --git a/include/zephyr/drivers/rtc/rtc_ds3231.h b/include/zephyr/drivers/rtc/rtc_ds3231.h new file mode 100644 index 0000000000000..dfe2daaae2aa5 --- /dev/null +++ b/include/zephyr/drivers/rtc/rtc_ds3231.h @@ -0,0 +1,109 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Gergo Vari + */ + +/* + * REGISTERS + */ + +/* Time registers */ +#define DS3231_REG_TIME_SECONDS 0x00 +#define DS3231_REG_TIME_MINUTES 0x01 +#define DS3231_REG_TIME_HOURS 0x02 +#define DS3231_REG_TIME_DAY_OF_WEEK 0x03 +#define DS3231_REG_TIME_DATE 0x04 +#define DS3231_REG_TIME_MONTH 0x05 +#define DS3231_REG_TIME_YEAR 0x06 + +/* Alarm 1 registers */ +#define DS3231_REG_ALARM_1_SECONDS 0x07 +#define DS3231_REG_ALARM_1_MINUTES 0x08 +#define DS3231_REG_ALARM_1_HOURS 0x09 +#define DS3231_REG_ALARM_1_DATE 0x0A + +/* Alarm 2 registers */ +/* Alarm 2 has no seconds to set, it only has minute accuracy. */ +#define DS3231_REG_ALARM_2_MINUTES 0x0B +#define DS3231_REG_ALARM_2_HOURS 0x0C +#define DS3231_REG_ALARM_2_DATE 0x0D + +/* Control registers */ +#define DS3231_REG_CTRL 0x0E +#define DS3231_REG_CTRL_STS 0x0F + +/* Aging offset register */ +#define DS3231_REG_AGING_OFFSET 0x10 + +/* + * BITMASKS + */ + +/* Time bitmasks */ +#define DS3231_BITS_TIME_SECONDS GENMASK(6, 0) +#define DS3231_BITS_TIME_MINUTES GENMASK(6, 0) +#define DS3231_BITS_TIME_HOURS GENMASK(5, 0) +#define DS3231_BITS_TIME_PM BIT(5) +#define DS3231_BITS_TIME_12HR BIT(6) +#define DS3231_BITS_TIME_DAY_OF_WEEK GENMASK(2, 0) +#define DS3231_BITS_TIME_DATE GENMASK(5, 0) +#define DS3231_BITS_TIME_MONTH GENMASK(4, 0) +#define DS3231_BITS_TIME_CENTURY BIT(7) +#define DS3231_BITS_TIME_YEAR GENMASK(7, 0) + +/* Alarm bitmasks */ +/* All alarm bitmasks match with time other than date and the alarm rate bit. */ +#define DS3231_BITS_ALARM_RATE BIT(7) +#define DS3231_BITS_ALARM_DATE_W_OR_M BIT(6) + +#define DS3231_BITS_SIGN BIT(7) +/* Control bitmasks */ +#define DS3231_BITS_CTRL_EOSC BIT(7) /* enable oscillator, active low */ +#define DS3231_BITS_CTRL_BBSQW BIT(6) /* enable battery-backed square-wave */ + +/* Setting the CONV bit to 1 forces the temperature sensor to + * convert the temperature into digital code and + * execute the TCXO algorithm to update + * the capacitance array to the oscillator. This can only + * happen when a conversion is not already in progress. + * The user should check the status bit BSY before + * forcing the controller to start a new TCXO execution. + * A user-initiated temperature conversion + * does not affect the internal 64-second update cycle. + */ +#define DS3231_BITS_CTRL_CONV BIT(6) + +/* Rate selectors */ +/* RS2 | RS1 | SQW FREQ + * 0 | 0 | 1Hz + * 0 | 1 | 1.024kHz + * 1 | 0 | 4.096kHz + * 1 | 1 | 8.192kHz + */ +#define DS3231_BITS_CTRL_RS2 BIT(4) +#define DS3231_BITS_CTRL_RS1 BIT(3) + +#define DS3231_BITS_CTRL_INTCTRL BIT(2) +#define DS3231_BITS_CTRL_ALARM_2_EN BIT(1) +#define DS3231_BITS_CTRL_ALARM_1_EN BIT(0) + +/* Control status bitmasks */ +/* For some reason you can access OSF in both control and control status registers. */ +#define DS3231_BITS_CTRL_STS_OSF BIT(7) /* oscillator stop flag */ /* read only */ +#define DS3231_BITS_CTRL_STS_32_EN BIT(3) /* 32kHz square-wave */ +/* set when TXCO is busy, see CONV flag: read only */ +#define DS3231_BITS_CTRL_STS_BSY BIT(2) +#define DS3231_BITS_CTRL_STS_ALARM_2_FLAG BIT(1) /* can only be set to 0 */ +#define DS3231_BITS_CTRL_STS_ALARM_1_FLAG BIT(0) /* can only be set to 0 */ + +/* Aging offset bitmask */ +#define DS3231_BITS_DATA BIT(6, 0) + +/* Settings bitmasks */ +#define DS3231_BITS_STS_OSC BIT(0) +#define DS3231_BITS_STS_INTCTRL BIT(1) +#define DS3231_BITS_STS_SQW BIT(2) +#define DS3231_BITS_STS_32KHZ BIT(3) +#define DS3231_BITS_STS_ALARM_1 BIT(4) +#define DS3231_BITS_STS_ALARM_2 BIT(5) diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index 6cd8cc7082797..62b765b81b420 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -156,6 +156,9 @@ enum sensor_channel { /** Revolutions per minute, in RPM. */ SENSOR_CHAN_RPM, + /** Frequency, in Hz. */ + SENSOR_CHAN_FREQUENCY, + /** Voltage, in volts **/ SENSOR_CHAN_GAUGE_VOLTAGE, /** Average current, in amps **/ @@ -192,6 +195,12 @@ enum sensor_channel { SENSOR_CHAN_GAUGE_DESIRED_VOLTAGE, /** Desired charging current in mA */ SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT, + /** Game Rotation Vector (unit quaternion components X/Y/Z/W) */ + SENSOR_CHAN_GAME_ROTATION_VECTOR, + /** Gravity Vector (X/Y/Z components in m/s^2) */ + SENSOR_CHAN_GRAVITY_VECTOR, + /** Gyroscope bias (X/Y/Z components in radians/s) */ + SENSOR_CHAN_GBIAS_XYZ, /** All channels. */ SENSOR_CHAN_ALL, @@ -1199,6 +1208,25 @@ static inline void sensor_g_to_ms2(int32_t g, struct sensor_value *ms2) ms2->val2 = ((int64_t)g * SENSOR_G) % 1000000LL; } +/** + * @brief Helper function to convert acceleration from m/s^2 to milli Gs + * + * @param ms2 A pointer to a sensor_value struct holding the acceleration, + * in m/s^2. + * + * @return The converted value, in milli Gs. + */ +static inline int32_t sensor_ms2_to_mg(const struct sensor_value *ms2) +{ + int64_t nano_ms2 = (ms2->val1 * 1000000LL + ms2->val2) * 1000LL; + + if (nano_ms2 > 0) { + return (nano_ms2 + SENSOR_G / 2) / SENSOR_G; + } else { + return (nano_ms2 - SENSOR_G / 2) / SENSOR_G; + } +} + /** * @brief Helper function to convert acceleration from m/s^2 to micro Gs * diff --git a/include/zephyr/drivers/sensor/adltc2990.h b/include/zephyr/drivers/sensor/adltc2990.h new file mode 100644 index 0000000000000..a13fe5c5d5191 --- /dev/null +++ b/include/zephyr/drivers/sensor/adltc2990.h @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_ADLTC2990_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_ADLTC2990_H_ + +#include + +#include + +enum adltc2990_acquisition_format { + ADLTC2990_REPEATED_ACQUISITION, + ADLTC2990_SINGLE_SHOT_ACQUISITION, +}; + +/** + * @brief check if adtlc2990 is busy doing conversion + * + * @param dev Pointer to the adltc2990 device + * @param is_busy Pointer to the variable to store the busy status + * + * @retval 0 if successful + * @retval -EIO General input / output error. + */ +int adltc2990_is_busy(const struct device *dev, bool *is_busy); + +/** + * @brief Trigger the adltc2990 to start a measurement + * + * @param dev Pointer to the adltc2990 device + * @param format The acquisition format to be used + * + * @retval 0 if successful + * @retval -EIO General input / output error. + */ +int adltc2990_trigger_measurement(const struct device *dev, + enum adltc2990_acquisition_format format); + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_ADLTC2990_H_ */ diff --git a/include/zephyr/drivers/sensor/icm42x70.h b/include/zephyr/drivers/sensor/icm42x70.h new file mode 100644 index 0000000000000..06c2c1ae396a1 --- /dev/null +++ b/include/zephyr/drivers/sensor/icm42x70.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM42X70_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM42X70_H_ + +#include + +/** + * @file + * @brief Extended public API for ICM42X70 MEMS sensor + * + * Some capabilities and operational requirements for this sensor + * cannot be expressed within the sensor driver abstraction. + */ + +/** ICM42X70 power mode */ +#define ICM42X70_LOW_NOISE_MODE (0) +#define ICM42X70_LOW_POWER_MODE (1) + +/** + * @brief Extended sensor attributes for ICM42X70 MEMS sensor + * + * This exposes attributes for the ICM42X70 which can be used for + * setting the signal path filtering parameters. + * + * The signal path starts with ADCs for the gyroscope and accelerometer. + * Low-Noise Mode and Low-Power Mode options are available for the + * accelerometer. Only Low-Noise Mode is available for gyroscope. + * In Low-Noise Mode, the ADC output is sent through an Anti-Alias Filter + * (AAF). The AAF is a filter with fixed coefficients (not user configurable), + * also the AAF cannot be bypassed. The AAF is followed by a 1st Order Low Pass + * Filter (LPF) with user selectable filter bandwidth options. + * In Low-Power Mode, the accelerometer ADC output is sent through an Average + * filter, with user configurable average filter setting. + * The output of 1st Order LPF in Low-Noise Mode, or Average filter in Low-Power + * Mode is subject to ODR selection, with user selectable ODR. + */ +enum sensor_attribute_icm42x70 { + /** BW filtering */ + + /** Low-pass filter configuration */ + SENSOR_ATTR_BW_FILTER_LPF = SENSOR_ATTR_PRIV_START, + /** Averaging configuration */ + SENSOR_ATTR_AVERAGING, +}; +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM42X70_H_ */ diff --git a/include/zephyr/drivers/sensor/mlx90394.h b/include/zephyr/drivers/sensor/mlx90394.h new file mode 100644 index 0000000000000..ea545bfa45012 --- /dev/null +++ b/include/zephyr/drivers/sensor/mlx90394.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Florian Weber + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Extended public API for Melexis mlx90394 Sensor + * + * Some capabilities and operational requirements for this sensor + * cannot be expressed within the sensor driver abstraction. + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_MLX90394_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_MLX90394_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +enum mlx90394_sensor_attribute { + MLX90394_SENSOR_ATTR_MAGN_LOW_NOISE = SENSOR_ATTR_PRIV_START, + MLX90394_SENSOR_ATTR_MAGN_FILTER_XY, + MLX90394_SENSOR_ATTR_MAGN_FILTER_Z, + MLX90394_SENSOR_ATTR_MAGN_OSR, + MLX90394_SENSOR_ATTR_TEMP_FILTER, + MLX90394_SENSOR_ATTR_TEMP_OSR +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_MLX90394_H_ */ diff --git a/include/zephyr/drivers/sensor/tdk_apex.h b/include/zephyr/drivers/sensor/tdk_apex.h new file mode 100644 index 0000000000000..eaa1300a5bbbe --- /dev/null +++ b/include/zephyr/drivers/sensor/tdk_apex.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_TDK_APEX_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_TDK_APEX_H_ + +#include + +/** + * @file + * @brief Extended public API for TDK MEMS sensor + * + * Some capabilities and operational requirements for this sensor + * cannot be expressed within the sensor driver abstraction. + */ + +/** TDK APEX features */ +#define TDK_APEX_PEDOMETER (1) +#define TDK_APEX_TILT (2) +#define TDK_APEX_SMD (3) +#define TDK_APEX_WOM (4) + +/** + * @brief Extended sensor channel for TDK MEMS supportintg APEX features + * + * This exposes sensor channel for the TDK MEMS which can be used for + * getting the APEX features data. + * + * The APEX (Advanced Pedometer and Event Detection – neXt gen) features of + * TDK MEMS consist of: + * ** Pedometer: Tracks step count. + * ** Tilt Detection: Detect the Tilt angle exceeds 35 degrees. + * ** Wake on Motion (WoM): Detects motion when accelerometer samples exceed + * a programmable threshold. This motion event can be used to enable device + * operation from sleep mode. + * ** Significant Motion Detector (SMD): Detects significant motion based on + * accelerometer data. + */ +enum sensor_channel_tdk_apex { + + /** APEX features */ + SENSOR_CHAN_APEX_MOTION = SENSOR_CHAN_PRIV_START, +}; +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_TDK_APEX_H_ */ diff --git a/include/zephyr/drivers/sensor/vl53l0x.h b/include/zephyr/drivers/sensor/vl53l0x.h new file mode 100644 index 0000000000000..98613f16f3132 --- /dev/null +++ b/include/zephyr/drivers/sensor/vl53l0x.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Michal Piekos + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Custom channels and values for VL53L0X ToF Sensor + * + * These channels provide additional sensor data not covered by the standard + * Zephyr sensor channels. Application must include vl53l0x.h file to gain + * access to these channels. + * + * Example usage: + * @code{c} + * #include + * + * if (sensor_channel_get(dev, SENSOR_CHAN_VL53L0X_RANGE_STATUS, &value)) { + * printk("Status: %d\n", value.val1); + * } + * @endcode + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_VL53L0X_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_VL53L0X_H_ + +#include + +/* VL53L0x specific channels */ +enum sensor_channel_vl53l0x { + SENSOR_CHAN_VL53L0X_RANGE_DMAX = SENSOR_CHAN_PRIV_START, + SENSOR_CHAN_VL53L0X_SIGNAL_RATE_RTN_CPS, + SENSOR_CHAN_VL53L0X_AMBIENT_RATE_RTN_CPS, + SENSOR_CHAN_VL53L0X_EFFECTIVE_SPAD_RTN_COUNT, + SENSOR_CHAN_VL53L0X_RANGE_STATUS, +}; + +/* VL53L0x meas status values */ +#define VL53L0X_RANGE_STATUS_RANGE_VALID (0) +#define VL53L0X_RANGE_STATUS_SIGMA_FAIL (1) +#define VL53L0X_RANGE_STATUS_SIGNAL_FAIL (2) +#define VL53L0X_RANGE_STATUS_MIN_RANGE_FAIL (3) +#define VL53L0X_RANGE_STATUS_PHASE_FAIL (4) +#define VL53L0X_RANGE_STATUS_HARDWARE_FAIL (5) +#define VL53L0X_RANGE_STATUS_NO_UPDATE (255) + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_VL53L0X_H_ */ diff --git a/include/zephyr/drivers/sensor/wsen_pads_2511020213301.h b/include/zephyr/drivers/sensor/wsen_pads_2511020213301.h new file mode 100644 index 0000000000000..44c08e6e1a7d5 --- /dev/null +++ b/include/zephyr/drivers/sensor/wsen_pads_2511020213301.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Extended public API for WSEN-PADS-2511020213301 Sensor + * + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_WSEN_PADS_2511020213301_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_WSEN_PADS_2511020213301_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +enum sensor_attribute_wsen_pads_2511020213301 { + SENSOR_ATTR_WSEN_PADS_2511020213301_REFERENCE_POINT = SENSOR_ATTR_PRIV_START, +}; + +#ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD +enum sensor_trigger_wsen_pads_2511020213301 { + SENSOR_TRIG_WSEN_PADS_2511020213301_THRESHOLD_UPPER = SENSOR_TRIG_PRIV_START, + SENSOR_TRIG_WSEN_PADS_2511020213301_THRESHOLD_LOWER, +}; +#endif /* CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_WSEN_PADS_2511020213301_H_ */ diff --git a/include/zephyr/drivers/sensor/wsen_tids_2521020222501.h b/include/zephyr/drivers/sensor/wsen_tids_2521020222501.h new file mode 100644 index 0000000000000..64eb1f48fa0e7 --- /dev/null +++ b/include/zephyr/drivers/sensor/wsen_tids_2521020222501.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Extended public API for WSEN-TIDS-2521020222501 Sensor + * + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_WSEN_TIDS_2521020222501_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_WSEN_TIDS_2521020222501_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +enum sensor_trigger_wsen_tids_2521020222501 { + SENSOR_TRIG_WSEN_TIDS_2521020222501_THRESHOLD_UPPER = SENSOR_TRIG_PRIV_START, + SENSOR_TRIG_WSEN_TIDS_2521020222501_THRESHOLD_LOWER, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_WSEN_TIDS_2521020222501_H_ */ diff --git a/include/zephyr/drivers/sensor/xbr818.h b/include/zephyr/drivers/sensor/xbr818.h new file mode 100644 index 0000000000000..06cac96cbde5d --- /dev/null +++ b/include/zephyr/drivers/sensor/xbr818.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024, MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Extended public API for Phosense XBR818 10 GHz Radar + * + * This exposes 4 additional attributes used to configure the IC + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_XBR818_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_XBR818_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum sensor_attribute_xbr818 { + /*! + * Time of received activity before output is triggered, in seconds + */ + SENSOR_ATTR_XBR818_DELAY_TIME = SENSOR_ATTR_PRIV_START, + /*! + * How long output stays triggered after no more activity is detected, in seconds + */ + SENSOR_ATTR_XBR818_LOCK_TIME, + /*! + * Noise floor Threshold for Radar, 16 first LSBs of the integer part. + */ + SENSOR_ATTR_XBR818_NOISE_FLOOR, + /*! + * RF Power for Radar, 0 to 7, LSB of the integer part. + */ + SENSOR_ATTR_XBR818_RF_POWER +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_XBR818_H_ */ diff --git a/include/zephyr/drivers/sensor_clock.h b/include/zephyr/drivers/sensor_clock.h new file mode 100644 index 0000000000000..8a67ce0a3c964 --- /dev/null +++ b/include/zephyr/drivers/sensor_clock.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Cienet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_CLOCK_H_ +#define ZEPHYR_DRIVERS_SENSOR_CLOCK_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Retrieve the current sensor clock cycles. + * + * This function obtains the current cycle count from the selected + * sensor clock source. The clock source may be the system clock or + * an external clock, depending on the configuration. + * + * @param[out] cycles Pointer to a 64-bit unsigned integer where the + * current clock cycle count will be stored. + * + * @return 0 on success, or an error code on failure. + */ +int sensor_clock_get_cycles(uint64_t *cycles); + +/** + * @brief Convert clock cycles to nanoseconds. + * + * This function converts clock cycles into nanoseconds based on the + * clock frequency. + * + * @param cycles Clock cycles to convert. + * @return Time in nanoseconds. + */ +uint64_t sensor_clock_cycles_to_ns(uint64_t cycles); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_DRIVERS_SENSOR_CLOCK_H_ */ diff --git a/include/zephyr/drivers/sensor_data_types.h b/include/zephyr/drivers/sensor_data_types.h index 604fa614e123a..4e84a8a030333 100644 --- a/include/zephyr/drivers/sensor_data_types.h +++ b/include/zephyr/drivers/sensor_data_types.h @@ -74,6 +74,38 @@ struct sensor_three_axis_data { PRIq_arg((data_).readings[(readings_offset_)].y, 6, (data_).shift), \ PRIq_arg((data_).readings[(readings_offset_)].z, 6, (data_).shift) +/** + * Data for a sensor channel which reports game rotation vector data. This is used by: + * - :c:enum:`SENSOR_CHAN_GAME_ROTATION_VECTOR` + */ +struct sensor_game_rotation_vector_data { + struct sensor_data_header header; + int8_t shift; + struct sensor_game_rotation_vector_sample_data { + uint32_t timestamp_delta; + union { + q31_t values[4]; + q31_t v[4]; + struct { + q31_t x; + q31_t y; + q31_t z; + q31_t w; + }; + }; + } readings[1]; +}; + +#define PRIsensor_game_rotation_vector_data PRIu64 \ + "ns, (%" PRIq(6) ", %" PRIq(6) ", %" PRIq(6) ", %" PRIq(6) ")" + +#define PRIsensor_game_rotation_vector_data_arg(data_, readings_offset_) \ + (data_).header.base_timestamp_ns + (data_).readings[(readings_offset_)].timestamp_delta, \ + PRIq_arg((data_).readings[(readings_offset_)].x, 6, (data_).shift), \ + PRIq_arg((data_).readings[(readings_offset_)].y, 6, (data_).shift), \ + PRIq_arg((data_).readings[(readings_offset_)].z, 6, (data_).shift), \ + PRIq_arg((data_).readings[(readings_offset_)].w, 6, (data_).shift) + /** * Data from a sensor where we only care about an event occurring. This is used to report triggers. */ diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index 3368a5312a45f..c9aaf38c72065 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -627,6 +627,17 @@ static inline void spi_transceive_stats(const struct device *dev, int error, #endif /*CONFIG_SPI_STATS*/ +/** + * @brief Like SPI_DEVICE_DT_DEFINE(), but uses an instance of a `DT_DRV_COMPAT` + * compatible instead of a node identifier. + * + * @param inst Instance number. The `node_id` argument to SPI_DEVICE_DT_DEFINE() is + * set to `DT_DRV_INST(inst)`. + * @param ... Other parameters as expected by SPI_DEVICE_DT_DEFINE(). + */ +#define SPI_DEVICE_DT_INST_DEFINE(inst, ...) \ + SPI_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__) + /** * @typedef spi_api_io * @brief Callback API for I/O @@ -1045,7 +1056,7 @@ static inline int spi_write_signal(const struct device *dev, */ static inline void spi_iodev_submit(struct rtio_iodev_sqe *iodev_sqe) { - const struct spi_dt_spec *dt_spec = iodev_sqe->sqe.iodev->data; + const struct spi_dt_spec *dt_spec = (const struct spi_dt_spec *)iodev_sqe->sqe.iodev->data; const struct device *dev = dt_spec->bus; const struct spi_driver_api *api = (const struct spi_driver_api *)dev->api; @@ -1080,7 +1091,7 @@ extern const struct rtio_iodev_api spi_iodev_api; */ static inline bool spi_is_ready_iodev(const struct rtio_iodev *spi_iodev) { - struct spi_dt_spec *spec = spi_iodev->data; + struct spi_dt_spec *spec = (struct spi_dt_spec *)spi_iodev->data; return spi_is_ready_dt(spec); } diff --git a/include/zephyr/drivers/stepper.h b/include/zephyr/drivers/stepper.h index d7013b642cebc..00c67f08df58a 100644 --- a/include/zephyr/drivers/stepper.h +++ b/include/zephyr/drivers/stepper.h @@ -29,29 +29,33 @@ extern "C" { #endif +/** + * @brief Macro to calculate the index of the microstep resolution + * @param res Microstep resolution + */ #define MICRO_STEP_RES_INDEX(res) LOG2(res) /** - * @brief Stepper Motor micro step resolution options + * @brief Stepper Motor microstep resolution options */ enum stepper_micro_step_resolution { /** Full step resolution */ STEPPER_MICRO_STEP_1 = 1, - /** 2 micro steps per full step */ + /** 2 microsteps per full step */ STEPPER_MICRO_STEP_2 = 2, - /** 4 micro steps per full step */ + /** 4 microsteps per full step */ STEPPER_MICRO_STEP_4 = 4, - /** 8 micro steps per full step */ + /** 8 microsteps per full step */ STEPPER_MICRO_STEP_8 = 8, - /** 16 micro steps per full step */ + /** 16 microsteps per full step */ STEPPER_MICRO_STEP_16 = 16, - /** 32 micro steps per full step */ + /** 32 microsteps per full step */ STEPPER_MICRO_STEP_32 = 32, - /** 64 micro steps per full step */ + /** 64 microsteps per full step */ STEPPER_MICRO_STEP_64 = 64, - /** 128 micro steps per full step */ + /** 128 microsteps per full step */ STEPPER_MICRO_STEP_128 = 128, - /** 256 micro steps per full step */ + /** 256 microsteps per full step */ STEPPER_MICRO_STEP_256 = 256, }; @@ -81,7 +85,7 @@ enum stepper_run_mode { * @brief Stepper Events */ enum stepper_event { - /** Steps set using move or set_target_position have been executed */ + /** Steps set using move_by or move_to have been executed */ STEPPER_EVENT_STEPS_COMPLETED = 0, /** Stall detected */ STEPPER_EVENT_STALL_DETECTED = 1, @@ -106,19 +110,19 @@ enum stepper_event { typedef int (*stepper_enable_t)(const struct device *dev, const bool enable); /** - * @brief Move the stepper motor by a given number of micro_steps. + * @brief Move the stepper motor relatively by a given number of microsteps. * - * @see stepper_move() for details. + * @see stepper_move_by() for details. */ -typedef int (*stepper_move_t)(const struct device *dev, const int32_t micro_steps); +typedef int (*stepper_move_by_t)(const struct device *dev, const int32_t micro_steps); /** - * @brief Set the max velocity in micro_steps per seconds. + * @brief Set the time interval between steps in nanoseconds. * - * @see stepper_set_max_velocity() for details. + * @see stepper_set_microstep_interval() for details. */ -typedef int (*stepper_set_max_velocity_t)(const struct device *dev, - const uint32_t micro_steps_per_second); +typedef int (*stepper_set_microstep_interval_t)(const struct device *dev, + const uint64_t microstep_interval_ns); /** * @brief Set the micro-step resolution @@ -150,11 +154,11 @@ typedef int (*stepper_set_reference_position_t)(const struct device *dev, const typedef int (*stepper_get_actual_position_t)(const struct device *dev, int32_t *value); /** - * @brief Set the absolute target position of the stepper + * @brief Move the stepper motor to an absolute position in microsteps. * - * @see stepper_set_target_position() for details. + * @see stepper_move_to() for details. */ -typedef int (*stepper_set_target_position_t)(const struct device *dev, const int32_t value); +typedef int (*stepper_move_to_t)(const struct device *dev, const int32_t micro_steps); /** * @brief Is the target position fo the stepper reached @@ -164,12 +168,11 @@ typedef int (*stepper_set_target_position_t)(const struct device *dev, const int typedef int (*stepper_is_moving_t)(const struct device *dev, bool *is_moving); /** - * @brief Run the stepper with a given velocity in a given direction + * @brief Run the stepper with a given step interval in a given direction * * @see stepper_run() for details. */ -typedef int (*stepper_run_t)(const struct device *dev, const enum stepper_direction direction, - const uint32_t value); +typedef int (*stepper_run_t)(const struct device *dev, const enum stepper_direction direction); /** * @brief Callback function for stepper events @@ -190,13 +193,13 @@ typedef int (*stepper_set_event_callback_t)(const struct device *dev, */ __subsystem struct stepper_driver_api { stepper_enable_t enable; - stepper_move_t move; - stepper_set_max_velocity_t set_max_velocity; + stepper_move_by_t move_by; + stepper_set_microstep_interval_t set_microstep_interval; stepper_set_micro_step_res_t set_micro_step_res; stepper_get_micro_step_res_t get_micro_step_res; stepper_set_reference_position_t set_reference_position; stepper_get_actual_position_t get_actual_position; - stepper_set_target_position_t set_target_position; + stepper_move_to_t move_to; stepper_is_moving_t is_moving; stepper_run_t run; stepper_set_event_callback_t set_event_callback; @@ -207,7 +210,7 @@ __subsystem struct stepper_driver_api { */ /** - * @brief Enable or Disable Motor Controller + * @brief Enable or disable motor controller * * @param dev pointer to the stepper motor controller instance * @param enable Input enable or disable motor controller @@ -225,47 +228,55 @@ static inline int z_impl_stepper_enable(const struct device *dev, const bool ena } /** - * @brief Set the micro_steps to be moved from the current position i.e. relative movement + * @brief Set the microsteps to be moved from the current position i.e. relative movement + * + * @details The motor will move by the given number of microsteps from the current position. + * This function is non-blocking. * * @param dev pointer to the stepper motor controller instance - * @param micro_steps target micro_steps to be moved from the current position + * @param micro_steps target microsteps to be moved from the current position * + * @retval -ECANCELED If the stepper is disabled * @retval -EIO General input / output error * @retval 0 Success */ -__syscall int stepper_move(const struct device *dev, int32_t micro_steps); +__syscall int stepper_move_by(const struct device *dev, int32_t micro_steps); -static inline int z_impl_stepper_move(const struct device *dev, const int32_t micro_steps) +static inline int z_impl_stepper_move_by(const struct device *dev, const int32_t micro_steps) { const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; - return api->move(dev, micro_steps); + return api->move_by(dev, micro_steps); } /** - * @brief Set the target velocity to be reached by the motor + * @brief Set the time interval between steps in microseconds * * @details For controllers such as DRV8825 where you * toggle the STEP Pin, the pulse_length would have to be calculated based on this parameter in the - * driver. For controllers where velocity can be set, this parameter corresponds to max_velocity - * @note Setting max velocity does not set the motor into motion, a combination of set_max_velocity - * and move is required to set the motor into motion. + * driver. + * @note Setting step interval does not set the motor into motion, a combination of + * set_microstep_interval and move is required to set the motor into motion. * * @param dev pointer to the stepper motor controller instance - * @param micro_steps_per_second speed in micro_steps per second + * @param microstep_interval_ns time interval between steps in microseconds * * @retval -EIO General input / output error - * @retval -EINVAL If the requested velocity is not supported + * @retval -EINVAL If the requested step interval is not supported * @retval 0 Success */ -__syscall int stepper_set_max_velocity(const struct device *dev, uint32_t micro_steps_per_second); +__syscall int stepper_set_microstep_interval(const struct device *dev, + uint64_t microstep_interval_ns); -static inline int z_impl_stepper_set_max_velocity(const struct device *dev, - const uint32_t micro_steps_per_second) +static inline int z_impl_stepper_set_microstep_interval(const struct device *dev, + const uint64_t microstep_interval_ns) { const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; - return api->set_max_velocity(dev, micro_steps_per_second); + if (api->set_microstep_interval == NULL) { + return -ENOSYS; + } + return api->set_microstep_interval(dev, microstep_interval_ns); } /** @@ -344,7 +355,7 @@ static inline int z_impl_stepper_set_reference_position(const struct device *dev * @brief Get the actual a.k.a reference position of the stepper * * @param dev pointer to the stepper motor controller instance - * @param value The actual position to get in micro_steps + * @param value The actual position to get in microsteps * * @retval -EIO General input / output error * @retval -ENOSYS If not implemented by device driver @@ -365,23 +376,27 @@ static inline int z_impl_stepper_get_actual_position(const struct device *dev, i /** * @brief Set the absolute target position of the stepper * + * @details The motor will move to the given microsteps position from the reference position. + * This function is non-blocking. + * * @param dev pointer to the stepper motor controller instance - * @param value target position to set in micro_steps + * @param micro_steps target position to set in microsteps * + * @retval -ECANCELED If the stepper is disabled * @retval -EIO General input / output error * @retval -ENOSYS If not implemented by device driver * @retval 0 Success */ -__syscall int stepper_set_target_position(const struct device *dev, int32_t value); +__syscall int stepper_move_to(const struct device *dev, int32_t micro_steps); -static inline int z_impl_stepper_set_target_position(const struct device *dev, const int32_t value) +static inline int z_impl_stepper_move_to(const struct device *dev, const int32_t micro_steps) { const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; - if (api->set_target_position == NULL) { + if (api->move_to == NULL) { return -ENOSYS; } - return api->set_target_position(dev, value); + return api->move_to(dev, micro_steps); } /** @@ -407,34 +422,31 @@ static inline int z_impl_stepper_is_moving(const struct device *dev, bool *is_mo } /** - * @brief Run the stepper with a given velocity in a given direction + * @brief Run the stepper with a given step interval in a given direction * - * @details If velocity > 0, motor shall be set into motion and run incessantly until and unless - * stalled or stopped using some other command, for instance, motor_enable(false). + * @details The motor shall be set into motion and run continuously until + * stalled or stopped using some other command, for instance, motor_enable(false). This + * function is non-blocking. * * @param dev pointer to the stepper motor controller instance * @param direction The direction to set - * @param velocity The velocity to set in microsteps per second - * - > 0: Run the stepper with the given velocity in a given direction - * - 0: Stop the stepper * + * @retval -ECANCELED If the stepper is disabled * @retval -EIO General input / output error * @retval -ENOSYS If not implemented by device driver * @retval 0 Success */ -__syscall int stepper_run(const struct device *dev, enum stepper_direction direction, - uint32_t velocity); +__syscall int stepper_run(const struct device *dev, enum stepper_direction direction); static inline int z_impl_stepper_run(const struct device *dev, - const enum stepper_direction direction, - const uint32_t velocity) + const enum stepper_direction direction) { const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; if (api->run == NULL) { return -ENOSYS; } - return api->run(dev, direction, velocity); + return api->run(dev, direction); } /** diff --git a/include/zephyr/drivers/stepper/stepper_drv8424.h b/include/zephyr/drivers/stepper/stepper_drv8424.h new file mode 100644 index 0000000000000..6f20774d8564d --- /dev/null +++ b/include/zephyr/drivers/stepper/stepper_drv8424.h @@ -0,0 +1,33 @@ +/** + * @file drivers/stepper/stepper_drv8424.h + * + * @brief Public API for DRV8424 Stepper Controller Specific Functions + * + */ + +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Navimatix GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief After microstep setter fails, attempt to recover into previous state. + * + * @param dev Pointer to the stepper motor controller instance + * + * @retval 0 Success + * @retval <0 Error code dependent on the gpio controller of the microstep pins + */ +int drv8424_microstep_recovery(const struct device *dev); + +#ifdef __cplusplus +} +#endif diff --git a/include/zephyr/drivers/stepper/stepper_fake.h b/include/zephyr/drivers/stepper/stepper_fake.h index 33b19edd99c9f..080698d6899fc 100644 --- a/include/zephyr/drivers/stepper/stepper_fake.h +++ b/include/zephyr/drivers/stepper/stepper_fake.h @@ -16,9 +16,9 @@ extern "C" { DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_enable, const struct device *, bool); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_move, const struct device *, int32_t); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_move_by, const struct device *, int32_t); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_max_velocity, const struct device *, uint32_t); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_microstep_interval, const struct device *, uint64_t); DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_micro_step_res, const struct device *, enum stepper_micro_step_resolution); @@ -30,12 +30,11 @@ DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_reference_position, const struct d DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_get_actual_position, const struct device *, int32_t *); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_target_position, const struct device *, int32_t); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_move_to, const struct device *, int32_t); DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_is_moving, const struct device *, bool *); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_run, const struct device *, enum stepper_direction, - uint32_t); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_run, const struct device *, enum stepper_direction); DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_event_callback, const struct device *, stepper_event_callback_t, void *); diff --git a/include/zephyr/drivers/stepper/stepper_trinamic.h b/include/zephyr/drivers/stepper/stepper_trinamic.h index 6afe8c9292fdb..f42032fe984d9 100644 --- a/include/zephyr/drivers/stepper/stepper_trinamic.h +++ b/include/zephyr/drivers/stepper/stepper_trinamic.h @@ -159,9 +159,20 @@ struct tmc_ramp_generator_data { * @retval -ENOSYS If not implemented by device driver * @retval 0 Success */ -int tmc5041_stepper_set_ramp(const struct device *dev, +int tmc50xx_stepper_set_ramp(const struct device *dev, const struct tmc_ramp_generator_data *ramp_data); +/** + * @brief Set the maximum velocity of the stepper motor + * + * @param dev Pointer to the stepper motor controller instance + * @param velocity Maximum velocity in microsteps per second. + * + * @retval -EIO General input / output error + * @retval 0 Success + */ +int tmc50xx_stepper_set_max_velocity(const struct device *dev, uint32_t velocity); + /** * @} */ diff --git a/include/zephyr/drivers/uart.h b/include/zephyr/drivers/uart.h index 5cc9d2d2bead1..d6ce894cf28d1 100644 --- a/include/zephyr/drivers/uart.h +++ b/include/zephyr/drivers/uart.h @@ -380,10 +380,11 @@ __syscall int uart_poll_in_u16(const struct device *dev, uint16_t *p_u16); /** * @brief Write a character to the device for output. * - * This routine checks if the transmitter is full. When the + * This routine checks if the transmitter is full. When the * transmitter is not full, it writes a character to the data - * register. It waits and blocks the calling thread, otherwise. This - * function is a blocking call. + * register. It waits and blocks the calling thread otherwise. This + * function is a blocking call. It blocks the calling thread until the + * character is sent. * * To send a character when hardware flow control is enabled, the handshake * signal CTS must be asserted. diff --git a/include/zephyr/drivers/usb/udc.h b/include/zephyr/drivers/usb/udc.h index cd1e03851332e..197cfe60e5575 100644 --- a/include/zephyr/drivers/usb/udc.h +++ b/include/zephyr/drivers/usb/udc.h @@ -249,8 +249,8 @@ struct udc_api { int (*disable)(const struct device *dev); int (*init)(const struct device *dev); int (*shutdown)(const struct device *dev); - int (*lock)(const struct device *dev); - int (*unlock)(const struct device *dev); + void (*lock)(const struct device *dev); + void (*unlock)(const struct device *dev); }; /** @@ -311,7 +311,7 @@ struct udc_data { */ static inline bool udc_is_initialized(const struct device *dev) { - struct udc_data *data = dev->data; + struct udc_data *data = (struct udc_data *)dev->data; return atomic_test_bit(&data->status, UDC_STATUS_INITIALIZED); } @@ -325,7 +325,7 @@ static inline bool udc_is_initialized(const struct device *dev) */ static inline bool udc_is_enabled(const struct device *dev) { - struct udc_data *data = dev->data; + struct udc_data *data = (struct udc_data *)dev->data; return atomic_test_bit(&data->status, UDC_STATUS_ENABLED); } @@ -339,7 +339,7 @@ static inline bool udc_is_enabled(const struct device *dev) */ static inline bool udc_is_suspended(const struct device *dev) { - struct udc_data *data = dev->data; + struct udc_data *data = (struct udc_data *)dev->data; return atomic_test_bit(&data->status, UDC_STATUS_SUSPENDED); } @@ -415,7 +415,7 @@ int udc_shutdown(const struct device *dev); */ static inline struct udc_device_caps udc_caps(const struct device *dev) { - struct udc_data *data = dev->data; + struct udc_data *data = (struct udc_data *)dev->data; return data->caps; } @@ -445,7 +445,7 @@ enum udc_bus_speed udc_device_speed(const struct device *dev); */ static inline int udc_set_address(const struct device *dev, const uint8_t addr) { - const struct udc_api *api = dev->api; + const struct udc_api *api = (const struct udc_api *)dev->api; int ret; if (!udc_is_enabled(dev)) { @@ -477,7 +477,7 @@ static inline int udc_set_address(const struct device *dev, const uint8_t addr) static inline int udc_test_mode(const struct device *dev, const uint8_t mode, const bool dryrun) { - const struct udc_api *api = dev->api; + const struct udc_api *api = (const struct udc_api *)dev->api; int ret; if (!udc_is_enabled(dev)) { @@ -507,7 +507,7 @@ static inline int udc_test_mode(const struct device *dev, */ static inline int udc_host_wakeup(const struct device *dev) { - const struct udc_api *api = dev->api; + const struct udc_api *api = (const struct udc_api *)dev->api; int ret; if (!udc_is_enabled(dev)) { @@ -724,7 +724,7 @@ static inline struct udc_buf_info *udc_get_buf_info(const struct net_buf *const */ static inline const void *udc_get_event_ctx(const struct device *dev) { - struct udc_data *data = dev->data; + struct udc_data *data = (struct udc_data *)dev->data; return data->event_ctx; } diff --git a/include/zephyr/drivers/usb/udc_buf.h b/include/zephyr/drivers/usb/udc_buf.h index 6e1ca15e1c3f8..5975c6d6a358f 100644 --- a/include/zephyr/drivers/usb/udc_buf.h +++ b/include/zephyr/drivers/usb/udc_buf.h @@ -34,6 +34,16 @@ #define Z_UDC_BUF_GRANULARITY sizeof(void *) #endif + +#if defined(CONFIG_UDC_BUF_FORCE_NOCACHE) +/* + * The usb transfer buffer needs to be in __nocache section + */ +#define Z_UDC_BUF_SECTION __nocache +#else +#define Z_UDC_BUF_SECTION +#endif + /** * @brief Buffer macros and definitions used in USB device support * @defgroup udc_buf Buffer macros and definitions used in USB device support @@ -59,7 +69,8 @@ * @param size Buffer size */ #define UDC_STATIC_BUF_DEFINE(name, size) \ - static uint8_t __aligned(UDC_BUF_ALIGN) name[ROUND_UP(size, UDC_BUF_GRANULARITY)]; + static uint8_t Z_UDC_BUF_SECTION __aligned(UDC_BUF_ALIGN) \ + name[ROUND_UP(size, UDC_BUF_GRANULARITY)]; /** * @brief Verify that the buffer is aligned as required by the UDC driver @@ -136,7 +147,7 @@ extern const struct net_buf_data_cb net_buf_dma_cb; _NET_BUF_ARRAY_DEFINE(pname, count, ud_size); \ BUILD_ASSERT((UDC_BUF_GRANULARITY) % (UDC_BUF_ALIGN) == 0, \ "Code assumes granurality is multiple of alignment"); \ - static uint8_t __nocache __aligned(UDC_BUF_ALIGN) \ + static uint8_t Z_UDC_BUF_SECTION __aligned(UDC_BUF_ALIGN) \ net_buf_data_##pname[count][ROUND_UP(size, UDC_BUF_GRANULARITY)];\ static const struct net_buf_pool_fixed net_buf_fixed_##pname = { \ .data_pool = (uint8_t *)net_buf_data_##pname, \ diff --git a/include/zephyr/drivers/usb/uhc.h b/include/zephyr/drivers/usb/uhc.h index a2224d24669a3..f7e357854e882 100644 --- a/include/zephyr/drivers/usb/uhc.h +++ b/include/zephyr/drivers/usb/uhc.h @@ -23,10 +23,75 @@ * @defgroup uhc_api USB host controller driver API * @ingroup io_interfaces * @since 3.3 - * @version 0.1.0 + * @version 0.1.1 * @{ */ +/** USB device state */ +enum usb_device_state { + USB_STATE_NOTCONNECTED, + USB_STATE_DEFAULT, + USB_STATE_ADDRESSED, + USB_STATE_CONFIGURED, +}; + +/** + * @brief USB device operating speed + */ +enum usb_device_speed { + /** Device is probably not connected */ + USB_SPEED_UNKNOWN, + /** Low speed */ + USB_SPEED_SPEED_LS, + /** Full speed */ + USB_SPEED_SPEED_FS, + /** High speed */ + USB_SPEED_SPEED_HS, + /** Super speed */ + USB_SPEED_SPEED_SS, +}; + +#define UHC_INTERFACES_MAX 32 + +struct usb_host_interface { + struct usb_desc_header *dhp; + uint8_t alternate; +}; + +struct usb_host_ep { + struct usb_ep_descriptor *desc; +}; + +/** + * Host representation of a USB device + */ +struct usb_device { + /** dlist node */ + sys_dnode_t node; + /** An opaque pointer to the host context to which this device belongs */ + void *ctx; + /** Device mutex */ + struct k_mutex mutex; + /** USB device descriptor */ + struct usb_device_descriptor dev_desc; + /** Device state */ + enum usb_device_state state; + /** Device speed */ + enum usb_device_speed speed; + /** Actual active device configuration */ + uint8_t actual_cfg; + /** Device address */ + uint8_t addr; + /** Pointer to actual device configuration descriptor */ + void *cfg_desc; + /** Pointers to device interfaces */ + struct usb_host_interface ifaces[UHC_INTERFACES_MAX + 1]; + /** Pointers to device OUT endpoints */ + struct usb_host_ep ep_out[16]; + /** Pointers to device IN endpoints */ + struct usb_host_ep ep_in[16]; +}; + /** * @brief USB control transfer stage */ @@ -53,24 +118,24 @@ struct uhc_transfer { uint8_t setup_pkt[8]; /** Transfer data buffer */ struct net_buf *buf; - /** Device (peripheral) address */ - uint8_t addr; /** Endpoint to which request is associated */ uint8_t ep; - /** Endpoint attributes (TBD) */ - uint8_t attrib; /** Maximum packet size */ uint16_t mps; - /** Timeout in number of frames */ - uint16_t timeout; + /** Interval, used for periodic transfers only */ + uint16_t interval; + /** Start frame, used for periodic transfers only */ + uint16_t start_frame; /** Flag marks request buffer is queued */ unsigned int queued : 1; /** Control stage status, up to the driver to use it or not */ unsigned int stage : 2; - /** Pointer to USB device (opaque for the UHC) */ - void *udev; + /** Pointer to USB device */ + struct usb_device *udev; /** Pointer to transfer completion callback (opaque for the UHC) */ void *cb; + /** Pointer to completion callback private data */ + void *priv; /** Transfer result, 0 on success, other values on error */ int err; }; @@ -177,6 +242,8 @@ struct uhc_data { sys_dlist_t bulk_xfers; /** Callback to submit an UHC event to upper layer */ uhc_event_cb_t event_cb; + /** Opaque pointer to store higher layer context */ + const void *event_ctx; /** USB host controller status */ atomic_t status; /** Driver private data */ @@ -336,24 +403,18 @@ static inline int uhc_bus_resume(const struct device *dev) * and added from different pools. * * @param[in] dev Pointer to device struct of the driver instance - * @param[in] addr Device (peripheral) address * @param[in] ep Endpoint address - * @param[in] attrib Endpoint attributes - * @param[in] mps Maximum packet size of the endpoint - * @param[in] timeout Timeout in number of frames - * @param[in] udev Opaque pointer to USB device + * @param[in] udev Pointer to USB device * @param[in] cb Transfer completion callback + * @param[in] cb_priv Completion callback callback private data * * @return pointer to allocated transfer or NULL on error. */ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, - const uint8_t addr, const uint8_t ep, - const uint8_t attrib, - const uint16_t mps, - const uint16_t timeout, - void *const udev, - void *const cb); + struct usb_device *const udev, + void *const cb, + void *const cb_priv); /** * @brief Allocate UHC transfer with buffer @@ -361,25 +422,19 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, * Allocate a new transfer from common transfer pool with buffer. * * @param[in] dev Pointer to device struct of the driver instance - * @param[in] addr Device (peripheral) address * @param[in] ep Endpoint address - * @param[in] attrib Endpoint attributes - * @param[in] mps Maximum packet size of the endpoint - * @param[in] timeout Timeout in number of frames - * @param[in] udev Opaque pointer to USB device + * @param[in] udev Pointer to USB device * @param[in] cb Transfer completion callback + * @param[in] cb_priv Completion callback callback private data * @param[in] size Size of the buffer * * @return pointer to allocated transfer or NULL on error. */ struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev, - const uint8_t addr, const uint8_t ep, - const uint8_t attrib, - const uint16_t mps, - const uint16_t timeout, - void *const udev, + struct usb_device *const udev, void *const cb, + void *const cb_priv, size_t size); /** @@ -467,12 +522,14 @@ int uhc_ep_dequeue(const struct device *dev, struct uhc_transfer *const xfer); * * @param[in] dev Pointer to device struct of the driver instance * @param[in] event_cb Event callback from the higher layer (USB host stack) + * @param[in] event_ctx Opaque pointer to higher layer context * * @return 0 on success, all other values should be treated as error. * @retval -EINVAL on parameter error (no callback is passed) * @retval -EALREADY already initialized */ -int uhc_init(const struct device *dev, uhc_event_cb_t event_cb); +int uhc_init(const struct device *dev, + uhc_event_cb_t event_cb, const void *const event_ctx); /** * @brief Enable USB host controller @@ -530,6 +587,23 @@ static inline struct uhc_device_caps uhc_caps(const struct device *dev) return data->caps; } +/** + * @brief Get pointer to higher layer context + * + * The address of the context is passed as an argument to the uhc_init() + * function and is stored in the uhc data. + * + * @param[in] dev Pointer to device struct of the driver instance + * + * @return Opaque pointer to higher layer context + */ +static inline const void *uhc_get_event_ctx(const struct device *dev) +{ + struct uhc_data *data = dev->data; + + return data->event_ctx; +} + /** * @} */ diff --git a/include/zephyr/drivers/usb_c/tcpci_priv.h b/include/zephyr/drivers/usb_c/tcpci_priv.h index 8c5d67f59e3b4..aad4fb80bbeac 100644 --- a/include/zephyr/drivers/usb_c/tcpci_priv.h +++ b/include/zephyr/drivers/usb_c/tcpci_priv.h @@ -108,12 +108,158 @@ enum tcpc_alert tcpci_alert_reg_to_enum(uint16_t reg); * representing voltages state and partner detection status. * * @param bus I2C bus - * @param cc1 pointer to variable where detected CC1 voltage state will be stored - * @param cc2 pointer to variable where detected CC2 voltage state will be stored + * @param cc1 Pointer to variable where detected CC1 voltage state will be stored + * @param cc2 Pointer to variable where detected CC2 voltage state will be stored * @return -EINVAL if cc1 or cc2 pointer is NULL * @return int Status of I2C operation, 0 in case of success */ int tcpci_tcpm_get_cc(const struct i2c_dt_spec *bus, enum tc_cc_voltage_state *cc1, enum tc_cc_voltage_state *cc2); +/** + * @brief Function to retrieve information about the TCPCI chip. + * + * @param bus I2C bus + * @param chip_info Pointer to the structure where the chip information will be stored + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_get_chip_info(const struct i2c_dt_spec *bus, struct tcpc_chip_info *chip_info); + +/** + * @brief Function to dump the standard TCPCI registers. + * + * @param bus I2C bus + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_dump_std_reg(const struct i2c_dt_spec *bus); + +/** + * @brief Function to enable or disable the BIST (Built-In Self-Test) mode. + * + * @param bus I2C bus + * @param enable Boolean flag to enable (true) or disable (false) BIST mode + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_bist_test_mode(const struct i2c_dt_spec *bus, bool enable); + +/** + * @brief Function to transmit a PD (Power Delivery) message. The message is transmitted + * with a specified number of retries in case of failure. + * + * @param bus I2C bus + * @param msg Pointer to the PD message structure to be transmitted + * @param retries Number of retries in case of transmission failure + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_transmit_data(const struct i2c_dt_spec *bus, struct pd_msg *msg, + const uint8_t retries); + +/** + * @brief Function to select the Rp (Pull-up Resistor) value. + * + * @param bus I2C bus + * @param rp Enum representing the Rp value to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_select_rp_value(const struct i2c_dt_spec *bus, enum tc_rp_value rp); + +/** + * @brief Function to get the currently selected Rp value. + * + * @param bus I2C bus + * @param rp Pointer to the variable where the Rp value will be stored + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_get_rp_value(const struct i2c_dt_spec *bus, enum tc_rp_value *rp); + +/** + * @brief Function to set the CC pull resistor and set the role as either Source or Sink. + * + * @param bus I2C bus + * @param pull Enum representing the CC pull resistor to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_cc(const struct i2c_dt_spec *bus, enum tc_cc_pull pull); + +/** + * @brief Function to enable or disable TCPC auto dual role toggle. + * + * @param bus I2C bus + * @param enable Boolean flag to enable (true) or disable (false) DRP toggle mode + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_drp_toggle(const struct i2c_dt_spec *bus, bool enable); + +/** + * @brief Function to set the power and data role of the PD message header. + * + * @param bus I2C bus + * @param pd_rev Enum representing the USB−PD Specification Revision to be set + * @param power_role Enum representing the power role to be set + * @param data_role Enum representing the data role to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_roles(const struct i2c_dt_spec *bus, enum pd_rev_type pd_rev, + enum tc_power_role power_role, enum tc_data_role data_role); + +/** + * @brief Function to set the RX type. + * + * @param bus I2C bus + * @param type Value representing the RX type to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_rx_type(const struct i2c_dt_spec *bus, uint8_t type); + +/** + * @brief Function to set the polarity of the CC lines. + * + * @param bus I2C bus + * @param polarity Enum representing the CC polarity to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_cc_polarity(const struct i2c_dt_spec *bus, enum tc_cc_polarity polarity); + +/** + * @brief Function to enable or disable VCONN. + * + * @param bus I2C bus + * @param enable Boolean flag to enable (true) or disable (false) VCONN + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_vconn(const struct i2c_dt_spec *bus, bool enable); + +/** + * @brief Function to get the status of a specific TCPCI status register. + * + * @param bus I2C bus + * @param reg Enum representing the status register to be read + * @param status Pointer to the variable where the status will be stored + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_get_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t *status); + +/** + * @brief Function to clear specific bits in a TCPCI status register. + * + * @param bus I2C bus + * @param reg Enum representing the status register to be cleared + * @param mask Bitmask specifying which bits to clear + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_clear_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t mask); + +/** + * @brief Function to set the mask of a TCPCI status register. + * + * @param bus I2C bus + * @param reg Enum representing the status register to be masked + * @param mask Bitmask specifying which bits to mask + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_mask_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t mask); + #endif /* ZEPHYR_INCLUDE_DRIVERS_USBC_TCPCI_PRIV_H_ */ diff --git a/include/zephyr/drivers/usb_c/usbc_tcpc.h b/include/zephyr/drivers/usb_c/usbc_tcpc.h index 232906d710e58..81ed04fb5bf64 100644 --- a/include/zephyr/drivers/usb_c/usbc_tcpc.h +++ b/include/zephyr/drivers/usb_c/usbc_tcpc.h @@ -83,6 +83,8 @@ enum tcpc_alert { * @brief TCPC Status register */ enum tcpc_status_reg { + /** The Altert register */ + TCPC_ALERT_STATUS, /** The CC Status register */ TCPC_CC_STATUS, /** The Power Status register */ @@ -118,17 +120,17 @@ struct tcpc_chip_info { }; }; -typedef int (*tcpc_vconn_control_cb_t)(const struct device *dev, - enum tc_cc_polarity pol, bool enable); -typedef int (*tcpc_vconn_discharge_cb_t)(const struct device *dev, - enum tc_cc_polarity pol, bool enable); +typedef int (*tcpc_vconn_control_cb_t)(const struct device *dev, enum tc_cc_polarity pol, + bool enable); +typedef int (*tcpc_vconn_discharge_cb_t)(const struct device *dev, enum tc_cc_polarity pol, + bool enable); typedef void (*tcpc_alert_handler_cb_t)(const struct device *dev, void *data, - enum tcpc_alert alert); + enum tcpc_alert alert); __subsystem struct tcpc_driver_api { int (*init)(const struct device *dev); int (*get_cc)(const struct device *dev, enum tc_cc_voltage_state *cc1, - enum tc_cc_voltage_state *cc2); + enum tc_cc_voltage_state *cc2); int (*select_rp_value)(const struct device *dev, enum tc_rp_value rp); int (*get_rp_value)(const struct device *dev, enum tc_rp_value *rp); int (*set_cc)(const struct device *dev, enum tc_cc_pull pull); @@ -137,7 +139,7 @@ __subsystem struct tcpc_driver_api { int (*vconn_discharge)(const struct device *dev, bool enable); int (*set_vconn)(const struct device *dev, bool enable); int (*set_roles)(const struct device *dev, enum tc_power_role power_role, - enum tc_data_role data_role); + enum tc_data_role data_role); int (*get_rx_pending_msg)(const struct device *dev, struct pd_msg *msg); int (*set_rx_enable)(const struct device *dev, bool enable); int (*set_cc_polarity)(const struct device *dev, enum tc_cc_polarity polarity); @@ -145,11 +147,11 @@ __subsystem struct tcpc_driver_api { int (*dump_std_reg)(const struct device *dev); void (*alert_handler_cb)(const struct device *dev, void *data, enum tcpc_alert alert); int (*get_status_register)(const struct device *dev, enum tcpc_status_reg reg, - int32_t *status); + uint32_t *status); int (*clear_status_register)(const struct device *dev, enum tcpc_status_reg reg, - uint32_t mask); + uint32_t mask); int (*mask_status_register)(const struct device *dev, enum tcpc_status_reg reg, - uint32_t mask); + uint32_t mask); int (*set_debug_accessory)(const struct device *dev, bool enable); int (*set_debug_detach)(const struct device *dev); int (*set_drp_toggle)(const struct device *dev, bool enable); @@ -162,7 +164,7 @@ __subsystem struct tcpc_driver_api { int (*sop_prime_enable)(const struct device *dev, bool enable); int (*set_bist_test_mode)(const struct device *dev, bool enable); int (*set_alert_handler_cb)(const struct device *dev, tcpc_alert_handler_cb_t handler, - void *data); + void *data); }; /** @@ -170,15 +172,13 @@ __subsystem struct tcpc_driver_api { */ static inline int tcpc_is_cc_rp(enum tc_cc_voltage_state cc) { - return (cc == TC_CC_VOLT_RP_DEF) || (cc == TC_CC_VOLT_RP_1A5) || - (cc == TC_CC_VOLT_RP_3A0); + return (cc == TC_CC_VOLT_RP_DEF) || (cc == TC_CC_VOLT_RP_1A5) || (cc == TC_CC_VOLT_RP_3A0); } /** * @brief Returns true if both CC lines are completely open */ -static inline int tcpc_is_cc_open(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_open(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return (cc1 < TC_CC_VOLT_RD) && (cc2 < TC_CC_VOLT_RD); } @@ -186,8 +186,7 @@ static inline int tcpc_is_cc_open(enum tc_cc_voltage_state cc1, /** * @brief Returns true if we detect the port partner is a snk debug accessory */ -static inline int tcpc_is_cc_snk_dbg_acc(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_snk_dbg_acc(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return cc1 == TC_CC_VOLT_RD && cc2 == TC_CC_VOLT_RD; } @@ -195,8 +194,7 @@ static inline int tcpc_is_cc_snk_dbg_acc(enum tc_cc_voltage_state cc1, /** * @brief Returns true if we detect the port partner is a src debug accessory */ -static inline int tcpc_is_cc_src_dbg_acc(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_src_dbg_acc(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return tcpc_is_cc_rp(cc1) && tcpc_is_cc_rp(cc2); } @@ -204,8 +202,7 @@ static inline int tcpc_is_cc_src_dbg_acc(enum tc_cc_voltage_state cc1, /** * @brief Returns true if the port partner is an audio accessory */ -static inline int tcpc_is_cc_audio_acc(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_audio_acc(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return cc1 == TC_CC_VOLT_RA && cc2 == TC_CC_VOLT_RA; } @@ -222,8 +219,7 @@ static inline int tcpc_is_cc_at_least_one_rd(enum tc_cc_voltage_state cc1, /** * @brief Returns true if the port partner is presenting Rd on only one CC line */ -static inline int tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return tcpc_is_cc_at_least_one_rd(cc1, cc2) && cc1 != cc2; } @@ -239,11 +235,9 @@ static inline int tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1, */ static inline int tcpc_init(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->init != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->init != NULL, "Callback pointer should not be NULL"); return api->init(dev); } @@ -259,12 +253,10 @@ static inline int tcpc_init(const struct device *dev) * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_get_cc(const struct device *dev, - enum tc_cc_voltage_state *cc1, +static inline int tcpc_get_cc(const struct device *dev, enum tc_cc_voltage_state *cc1, enum tc_cc_voltage_state *cc2) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_cc == NULL) { return -ENOSYS; @@ -285,8 +277,7 @@ static inline int tcpc_get_cc(const struct device *dev, */ static inline int tcpc_select_rp_value(const struct device *dev, enum tc_rp_value rp) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->select_rp_value == NULL) { return -ENOSYS; @@ -307,8 +298,7 @@ static inline int tcpc_select_rp_value(const struct device *dev, enum tc_rp_valu */ static inline int tcpc_get_rp_value(const struct device *dev, enum tc_rp_value *rp) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_rp_value == NULL) { return -ENOSYS; @@ -328,11 +318,9 @@ static inline int tcpc_get_rp_value(const struct device *dev, enum tc_rp_value * */ static inline int tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_cc != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_cc != NULL, "Callback pointer should not be NULL"); return api->set_cc(dev, pull); } @@ -347,14 +335,11 @@ static inline int tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull) * @param dev Runtime device structure * @param vconn_cb pointer to the callback function that controls vconn */ -static inline void tcpc_set_vconn_cb(const struct device *dev, - tcpc_vconn_control_cb_t vconn_cb) +static inline void tcpc_set_vconn_cb(const struct device *dev, tcpc_vconn_control_cb_t vconn_cb) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_vconn_cb != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_vconn_cb != NULL, "Callback pointer should not be NULL"); api->set_vconn_cb(dev, vconn_cb); } @@ -370,13 +355,11 @@ static inline void tcpc_set_vconn_cb(const struct device *dev, * @param cb pointer to the callback function that discharges vconn */ static inline void tcpc_set_vconn_discharge_cb(const struct device *dev, - tcpc_vconn_discharge_cb_t cb) + tcpc_vconn_discharge_cb_t cb) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_vconn_discharge_cb != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_vconn_discharge_cb != NULL, "Callback pointer should not be NULL"); api->set_vconn_discharge_cb(dev, cb); } @@ -396,8 +379,7 @@ static inline void tcpc_set_vconn_discharge_cb(const struct device *dev, */ static inline int tcpc_vconn_discharge(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->vconn_discharge == NULL) { return -ENOSYS; @@ -421,8 +403,7 @@ static inline int tcpc_vconn_discharge(const struct device *dev, bool enable) */ static inline int tcpc_set_vconn(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_vconn == NULL) { return -ENOSYS; @@ -444,12 +425,10 @@ static inline int tcpc_set_vconn(const struct device *dev, bool enable) * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_set_roles(const struct device *dev, - enum tc_power_role power_role, +static inline int tcpc_set_roles(const struct device *dev, enum tc_power_role power_role, enum tc_data_role data_role) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_roles == NULL) { return -ENOSYS; @@ -493,8 +472,7 @@ static inline int tcpc_get_rx_pending_msg(const struct device *dev, struct pd_ms */ static inline int tcpc_set_rx_enable(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_rx_enable == NULL) { return -ENOSYS; @@ -512,14 +490,11 @@ static inline int tcpc_set_rx_enable(const struct device *dev, bool enable) * @retval 0 on success * @retval -EIO on failure */ -static inline int tcpc_set_cc_polarity(const struct device *dev, - enum tc_cc_polarity polarity) +static inline int tcpc_set_cc_polarity(const struct device *dev, enum tc_cc_polarity polarity) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_cc_polarity != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_cc_polarity != NULL, "Callback pointer should not be NULL"); return api->set_cc_polarity(dev, polarity); } @@ -534,11 +509,9 @@ static inline int tcpc_set_cc_polarity(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_transmit_data(const struct device *dev, - struct pd_msg *msg) +static inline int tcpc_transmit_data(const struct device *dev, struct pd_msg *msg) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->transmit_data == NULL) { return -ENOSYS; @@ -558,8 +531,7 @@ static inline int tcpc_transmit_data(const struct device *dev, */ static inline int tcpc_dump_std_reg(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->dump_std_reg == NULL) { return -ENOSYS; @@ -582,14 +554,11 @@ static inline int tcpc_dump_std_reg(const struct device *dev) * @retval -EINVAL on failure */ static inline int tcpc_set_alert_handler_cb(const struct device *dev, - tcpc_alert_handler_cb_t handler, - void *data) + tcpc_alert_handler_cb_t handler, void *data) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_alert_handler_cb != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_alert_handler_cb != NULL, "Callback pointer should not be NULL"); return api->set_alert_handler_cb(dev, handler, data); } @@ -605,12 +574,10 @@ static inline int tcpc_set_alert_handler_cb(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_get_status_register(const struct device *dev, - enum tcpc_status_reg reg, - int32_t *status) +static inline int tcpc_get_status_register(const struct device *dev, enum tcpc_status_reg reg, + uint32_t *status) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_status_register == NULL) { return -ENOSYS; @@ -631,12 +598,10 @@ static inline int tcpc_get_status_register(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_clear_status_register(const struct device *dev, - enum tcpc_status_reg reg, +static inline int tcpc_clear_status_register(const struct device *dev, enum tcpc_status_reg reg, uint32_t mask) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->clear_status_register == NULL) { return -ENOSYS; @@ -657,12 +622,10 @@ static inline int tcpc_clear_status_register(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_mask_status_register(const struct device *dev, - enum tcpc_status_reg reg, +static inline int tcpc_mask_status_register(const struct device *dev, enum tcpc_status_reg reg, uint32_t mask) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->mask_status_register == NULL) { return -ENOSYS; @@ -681,11 +644,9 @@ static inline int tcpc_mask_status_register(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_set_debug_accessory(const struct device *dev, - bool enable) +static inline int tcpc_set_debug_accessory(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_debug_accessory == NULL) { return -ENOSYS; @@ -705,8 +666,7 @@ static inline int tcpc_set_debug_accessory(const struct device *dev, */ static inline int tcpc_set_debug_detach(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_debug_detach == NULL) { return -ENOSYS; @@ -727,8 +687,7 @@ static inline int tcpc_set_debug_detach(const struct device *dev) */ static inline int tcpc_set_drp_toggle(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_drp_toggle == NULL) { return -ENOSYS; @@ -748,8 +707,7 @@ static inline int tcpc_set_drp_toggle(const struct device *dev, bool enable) */ static inline int tcpc_get_snk_ctrl(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_snk_ctrl == NULL) { return -ENOSYS; @@ -788,8 +746,7 @@ static inline int tcpc_set_snk_ctrl(const struct device *dev, bool enable) */ static inline int tcpc_get_src_ctrl(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_src_ctrl == NULL) { return -ENOSYS; @@ -828,11 +785,9 @@ static inline int tcpc_set_src_ctrl(const struct device *dev, bool enable) * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_set_bist_test_mode(const struct device *dev, - bool enable) +static inline int tcpc_set_bist_test_mode(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_bist_test_mode == NULL) { return -ENOSYS; @@ -851,11 +806,9 @@ static inline int tcpc_set_bist_test_mode(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_get_chip_info(const struct device *dev, - struct tcpc_chip_info *chip_info) +static inline int tcpc_get_chip_info(const struct device *dev, struct tcpc_chip_info *chip_info) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_chip_info == NULL) { return -ENOSYS; @@ -874,11 +827,9 @@ static inline int tcpc_get_chip_info(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_set_low_power_mode(const struct device *dev, - bool enable) +static inline int tcpc_set_low_power_mode(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_low_power_mode == NULL) { return -ENOSYS; @@ -888,20 +839,19 @@ static inline int tcpc_set_low_power_mode(const struct device *dev, } /** - * @brief Enables the reception of SOP Prime messages + * @brief Enables the reception of SOP Prime and optionally SOP Double Prime messages * * @param dev Runtime device structure - * @param enable Can receive SOP Prime messages when true, else it can not + * @param enable Can receive SOP Prime messages and SOP Double Prime messages when true, + * else it can not * * @retval 0 on success * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_sop_prime_enable(const struct device *dev, - bool enable) +static inline int tcpc_sop_prime_enable(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->sop_prime_enable == NULL) { return -ENOSYS; diff --git a/include/zephyr/drivers/video.h b/include/zephyr/drivers/video.h index fb647cac70fb1..a7deb019e774d 100644 --- a/include/zephyr/drivers/video.h +++ b/include/zephyr/drivers/video.h @@ -16,7 +16,7 @@ * @brief Video Interface * @defgroup video_interface Video Interface * @since 2.1 - * @version 1.0.0 + * @version 1.1.0 * @ingroup io_interfaces * @{ */ @@ -302,20 +302,17 @@ typedef int (*video_api_dequeue_t)(const struct device *dev, enum video_endpoint typedef int (*video_api_flush_t)(const struct device *dev, enum video_endpoint_id ep, bool cancel); /** - * @typedef video_api_stream_start_t - * @brief Start the capture or output process. + * @typedef video_api_set_stream_t + * @brief Start or stop streaming on the video device. * - * See video_stream_start() for argument descriptions. - */ -typedef int (*video_api_stream_start_t)(const struct device *dev); - -/** - * @typedef video_api_stream_stop_t - * @brief Stop the capture or output process. + * Start (enable == true) or stop (enable == false) streaming on the video device. * - * See video_stream_stop() for argument descriptions. + * @param dev Pointer to the device structure. + * @param enable If true, start streaming, otherwise stop streaming. + * + * @retval 0 on success, otherwise a negative errno code. */ -typedef int (*video_api_stream_stop_t)(const struct device *dev); +typedef int (*video_api_set_stream_t)(const struct device *dev, bool enable); /** * @typedef video_api_set_ctrl_t @@ -355,8 +352,7 @@ __subsystem struct video_driver_api { /* mandatory callbacks */ video_api_set_format_t set_format; video_api_get_format_t get_format; - video_api_stream_start_t stream_start; - video_api_stream_stop_t stream_stop; + video_api_set_stream_t set_stream; video_api_get_caps_t get_caps; /* optional callbacks */ video_api_enqueue_t enqueue; @@ -598,11 +594,11 @@ static inline int video_stream_start(const struct device *dev) { const struct video_driver_api *api = (const struct video_driver_api *)dev->api; - if (api->stream_start == NULL) { + if (api->set_stream == NULL) { return -ENOSYS; } - return api->stream_start(dev); + return api->set_stream(dev, true); } /** @@ -619,11 +615,11 @@ static inline int video_stream_stop(const struct device *dev) const struct video_driver_api *api = (const struct video_driver_api *)dev->api; int ret; - if (api->stream_stop == NULL) { + if (api->set_stream == NULL) { return -ENOSYS; } - ret = api->stream_stop(dev); + ret = api->set_stream(dev, false); video_flush(dev, VIDEO_EP_ALL, true); return ret; @@ -732,19 +728,21 @@ static inline int video_set_signal(const struct device *dev, enum video_endpoint * * @param size Size of the video buffer (in bytes). * @param align Alignment of the requested memory, must be a power of two. + * @param timeout Timeout duration or K_NO_WAIT * * @retval pointer to allocated video buffer */ -struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align); +struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_timeout_t timeout); /** * @brief Allocate video buffer. * * @param size Size of the video buffer (in bytes). + * @param timeout Timeout duration or K_NO_WAIT * * @retval pointer to allocated video buffer */ -struct video_buffer *video_buffer_alloc(size_t size); +struct video_buffer *video_buffer_alloc(size_t size, k_timeout_t timeout); /** * @brief Release a video buffer. @@ -753,28 +751,127 @@ struct video_buffer *video_buffer_alloc(size_t size); */ void video_buffer_release(struct video_buffer *buf); -/* fourcc - four-character-code */ -#define video_fourcc(a, b, c, d) \ - ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) +/** + * @brief Search for a format that matches in a list of capabilities + * + * @param fmts The format capability list to search. + * @param fmt The format to find in the list. + * @param idx The pointer to a number of the first format that matches. + * + * @return 0 when a format is found. + * @return -ENOENT when no matching format is found. + */ +int video_format_caps_index(const struct video_format_cap *fmts, const struct video_format *fmt, + size_t *idx); + +/** + * @brief Compute the difference between two frame intervals + * + * @param frmival Frame interval to turn into microseconds. + * + * @return The frame interval value in microseconds. + */ +static inline uint64_t video_frmival_nsec(const struct video_frmival *frmival) +{ + return (uint64_t)NSEC_PER_SEC * frmival->numerator / frmival->denominator; +} + +/** + * @brief Find the closest match to a frame interval value within a stepwise frame interval. + * + * @param stepwise The stepwise frame interval range to search + * @param desired The frame interval for which find the closest match + * @param match The resulting frame interval closest to @p desired + */ +void video_closest_frmival_stepwise(const struct video_frmival_stepwise *stepwise, + const struct video_frmival *desired, + struct video_frmival *match); + +/** + * @brief Find the closest match to a frame interval value within a video device. + * + * To compute the closest match, fill @p match with the following fields: + * + * - @c match->format to the @ref video_format of interest. + * - @c match->type to @ref VIDEO_FRMIVAL_TYPE_DISCRETE. + * - @c match->discrete to the desired frame interval. + * + * The result will be loaded into @p match, with the following fields set: + * + * - @c match->discrete to the value of the closest frame interval. + * - @c match->index to the index of the closest frame interval. + * + * @param dev Video device to query. + * @param ep Video endpoint ID to query. + * @param match Frame interval enumerator with the query, and loaded with the result. + */ +void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival_enum *match); /** * @defgroup video_pixel_formats Video pixel formats + * The @c | characters separate the pixels, and spaces separate the bytes. + * The uppercase letter represents the most significant bit. + * The lowercase letters represent the rest of the bits. * @{ */ /** - * @name Bayer formats + * @brief Four-character-code uniquely identifying the pixel format + */ +#define VIDEO_FOURCC(a, b, c, d) \ + ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) + +/** + * @brief Convert a four-character-string to a four-character-code + * + * Convert a string literal or variable into a four-character-code + * as defined by @ref VIDEO_FOURCC. + * + * @param str String to be converted + * @return Four-character-code. + */ +#define VIDEO_FOURCC_FROM_STR(str) VIDEO_FOURCC((str)[0], (str)[1], (str)[2], (str)[3]) + +/** + * @name Bayer formats (R, G, B channels). + * + * The full color information is spread over multiple pixels. + * * @{ */ -/** BGGR8 pixel format */ -#define VIDEO_PIX_FMT_BGGR8 video_fourcc('B', 'G', 'G', 'R') /* 8 BGBG.. GRGR.. */ -/** GBRG8 pixel format */ -#define VIDEO_PIX_FMT_GBRG8 video_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ -/** GRBG8 pixel format */ -#define VIDEO_PIX_FMT_GRBG8 video_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ -/** RGGB8 pixel format */ -#define VIDEO_PIX_FMT_RGGB8 video_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ +/** + * @verbatim + * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ... + * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_BGGR8 VIDEO_FOURCC('B', 'A', '8', '1') + +/** + * @verbatim + * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | ... + * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_GBRG8 VIDEO_FOURCC('G', 'B', 'R', 'G') + +/** + * @verbatim + * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | ... + * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_GRBG8 VIDEO_FOURCC('G', 'R', 'B', 'G') + +/** + * @verbatim + * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ... + * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_RGGB8 VIDEO_FOURCC('R', 'G', 'G', 'B') /** * @} @@ -782,14 +879,40 @@ void video_buffer_release(struct video_buffer *buf); /** * @name RGB formats + * Per-color (R, G, B) channels. * @{ */ -/** RGB565 pixel format */ -#define VIDEO_PIX_FMT_RGB565 video_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ +/** + * 5 red bits [15:11], 6 green bits [10:5], 5 blue bits [4:0]. + * This 16-bit integer is then packed in big endian format over two bytes: + * + * @verbatim + * 15.....8 7......0 + * | RrrrrGgg gggBbbbb | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_RGB565X VIDEO_FOURCC('R', 'G', 'B', 'R') -/** XRGB32 pixel format */ -#define VIDEO_PIX_FMT_XRGB32 video_fourcc('B', 'X', '2', '4') /* 32 XRGB-8-8-8-8 */ +/** + * 5 red bits [15:11], 6 green bits [10:5], 5 blue bits [4:0]. + * This 16-bit integer is then packed in little endian format over two bytes: + * + * @verbatim + * 7......0 15.....8 + * | gggBbbbb RrrrrGgg | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_RGB565 VIDEO_FOURCC('R', 'G', 'B', 'P') + +/** + * The first byte is empty (X) for each pixel. + * + * @verbatim + * | Xxxxxxxx Rrrrrrrr Gggggggg Bbbbbbbb | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_XRGB32 VIDEO_FOURCC('B', 'X', '2', '4') /** * @} @@ -797,60 +920,79 @@ void video_buffer_release(struct video_buffer *buf); /** * @name YUV formats + * Luminance (Y) and chrominance (U, V) channels. * @{ */ -/** YUYV pixel format */ -#define VIDEO_PIX_FMT_YUYV video_fourcc('Y', 'U', 'Y', 'V') /* 16 Y0-Cb0 Y1-Cr0 */ - -/** XYUV32 pixel format */ -#define VIDEO_PIX_FMT_XYUV32 video_fourcc('X', 'Y', 'U', 'V') /* 32 XYUV-8-8-8-8 */ +/** + * There is either a missing channel per pixel, U or V. + * The value is to be averaged over 2 pixels to get the value of individual pixel. + * + * @verbatim + * | Yyyyyyyy Uuuuuuuu | Yyyyyyyy Vvvvvvvv | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_YUYV VIDEO_FOURCC('Y', 'U', 'Y', 'V') /** + * The first byte is empty (X) for each pixel. * + * @verbatim + * | Xxxxxxxx Yyyyyyyy Uuuuuuuu Vvvvvvvv | ... + * @endverbatim + */ +#define VIDEO_PIX_FMT_XYUV32 VIDEO_FOURCC('X', 'Y', 'U', 'V') + +/** * @} */ /** - * @name JPEG formats + * @name Compressed formats * @{ */ -/** JPEG pixel format */ -#define VIDEO_PIX_FMT_JPEG video_fourcc('J', 'P', 'E', 'G') /* 8 JPEG */ - /** - * @} + * Both JPEG (single frame) and Motion-JPEG (MJPEG, multiple JPEG frames concatenated) */ +#define VIDEO_PIX_FMT_JPEG VIDEO_FOURCC('J', 'P', 'E', 'G') /** * @} */ /** - * @brief Get number of bytes per pixel of a pixel format + * @brief Get number of bits per pixel of a pixel format + * + * @param pixfmt FourCC pixel format value (@ref video_pixel_formats). * - * @param pixfmt FourCC pixel format value (\ref video_pixel_formats). + * @retval 0 if the format is unhandled or if it is variable number of bits + * @retval bit size of one pixel for this format */ -static inline unsigned int video_pix_fmt_bpp(uint32_t pixfmt) +static inline unsigned int video_bits_per_pixel(uint32_t pixfmt) { switch (pixfmt) { case VIDEO_PIX_FMT_BGGR8: case VIDEO_PIX_FMT_GBRG8: case VIDEO_PIX_FMT_GRBG8: case VIDEO_PIX_FMT_RGGB8: - return 1; + return 8; case VIDEO_PIX_FMT_RGB565: case VIDEO_PIX_FMT_YUYV: - return 2; + return 16; case VIDEO_PIX_FMT_XRGB32: case VIDEO_PIX_FMT_XYUV32: - return 4; + return 32; default: + /* Variable number of bits per pixel or unknown format */ return 0; } } +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/zephyr/drivers/wifi/nrf_wifi/off_raw_tx/off_raw_tx_api.h b/include/zephyr/drivers/wifi/nrf_wifi/off_raw_tx/off_raw_tx_api.h index b14ae39488d94..4f9c13ece312a 100644 --- a/include/zephyr/drivers/wifi/nrf_wifi/off_raw_tx/off_raw_tx_api.h +++ b/include/zephyr/drivers/wifi/nrf_wifi/off_raw_tx/off_raw_tx_api.h @@ -16,7 +16,6 @@ #include #include -#include "osal_api.h" /* Minimum frame size for raw packet transmission */ #define NRF_WIFI_OFF_RAW_TX_FRAME_SIZE_MIN 26 diff --git a/include/zephyr/dsp/utils.h b/include/zephyr/dsp/utils.h new file mode 100644 index 0000000000000..5787e1b3fe084 --- /dev/null +++ b/include/zephyr/dsp/utils.h @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2024 OWL Services LLC. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file zephyr/dsp/utils.h + * + * @brief Extra functions and macros for DSP + */ + +#ifndef INCLUDE_ZEPHYR_DSP_UTILS_H_ +#define INCLUDE_ZEPHYR_DSP_UTILS_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup math_dsp + * @defgroup math_dsp_utils_shifts Float/Fixed point shift conversion functions + */ + +/** + * @ingroup math_dsp_utils_shifts + * @addtogroup math_dsp_basic_conv_to_float Fixed to Float point conversions + * + * Convert number Q7/Q15/Q31 to Float or Double representation with shift. + * + * There are separate functions for floating-point, Q7, Q15, and Q31 data types. + * @{ + */ + +/** + * @brief Convert a Q7 fixed-point value to a floating-point (float32_t) value with a left shift. + * + * @param src The input Q7 fixed-point value. + * @param m The number of bits to left shift the input value (0 to 7). + * @return The converted floating-point (float32_t) value. + */ +#define Z_SHIFT_Q7_TO_F32(src, m) ((float32_t)(((src << m)) / (float32_t)(1U << 7))) + +/** + * @brief Convert a Q15 fixed-point value to a floating-point (float32_t) value with a left shift. + * + * @param src The input Q15 fixed-point value. + * @param m The number of bits to left shift the input value (0 to 15). + * @return The converted floating-point (float32_t) value. + */ +#define Z_SHIFT_Q15_TO_F32(src, m) ((float32_t)((src << m) / (float32_t)(1U << 15))) + +/** + * @brief Convert a Q31 fixed-point value to a floating-point (float32_t) value with a left shift. + * + * @param src The input Q31 fixed-point value. + * @param m The number of bits to left shift the input value (0 to 31). + * @return The converted floating-point (float32_t) value. + */ +#define Z_SHIFT_Q31_TO_F32(src, m) ((float32_t)(((int64_t)src) << m) / (float32_t)(1U << 31)) + +/** + * @brief Convert a Q7 fixed-point value to a floating-point (float64_t) value with a left shift. + * + * @param src The input Q7 fixed-point value. + * @param m The number of bits to left shift the input value (0 to 7). + * @return The converted floating-point (float64_t) value. + */ +#define Z_SHIFT_Q7_TO_F64(src, m) (((float64_t)(src << m)) / (1U << 7)) + +/** + * @brief Convert a Q15 fixed-point value to a floating-point (float64_t) value with a left shift. + * + * @param src The input Q15 fixed-point value. + * @param m The number of bits to left shift the input value (0 to 15). + * @return The converted floating-point (float64_t) value. + */ +#define Z_SHIFT_Q15_TO_F64(src, m) (((float64_t)(src << m)) / (1UL << 15)) + +/** + * @brief Convert a Q31 fixed-point value to a floating-point (float64_t) value with a left shift. + * + * @param src The input Q31 fixed-point value. + * @param m The number of bits to left shift the input value (0 to 31). + * @return The converted floating-point (float64_t) value. + */ +#define Z_SHIFT_Q31_TO_F64(src, m) ((float64_t)(((int64_t)src) << m) / (1ULL << 31)) + +/** + * @} + */ + +/** + * @ingroup math_dsp_utils_shifts + * @addtogroup math_dsp_basic_conv_to_fixed Float to Fixed point conversions + * + * Convert number representation in Float or Double to Q31/Q15/Q7. + * + * There are separate functions for floating-point, Q7, Q15, and Q31 data types. + * @{ + */ + +/** + * @brief Convert a floating-point (float32_t) value to a Q7 fixed-point value with a right shift. + * + * @param src The input floating-point (float32_t) value. + * @param m The number of bits to right shift the input value (0 to 7). + * @return The converted Q7 fixed-point value. + */ +#define Z_SHIFT_F32_TO_Q7(src, m) \ + ((q7_t)Z_CLAMP((int32_t)(src * (1U << 7)) >> m, INT8_MIN, INT8_MAX)) + +/** + * @brief Convert a floating-point (float32_t) value to a Q15 fixed-point value with a right shift. + * + * @param src The input floating-point (float32_t) value. + * @param m The number of bits to right shift the input value (0 to 15). + * @return The converted Q15 fixed-point value. + */ +#define Z_SHIFT_F32_TO_Q15(src, m) \ + ((q15_t)Z_CLAMP((int32_t)(src * (1U << 15)) >> m, INT16_MIN, INT16_MAX)) + +/** + * @brief Convert a floating-point (float32_t) value to a Q31 fixed-point value with a right shift. + * + * @param src The input floating-point (float32_t) value. + * @param m The number of bits to right shift the input value (0 to 31). + * @return The converted Q31 fixed-point value. + */ +#define Z_SHIFT_F32_TO_Q31(src, m) \ + ((q31_t)Z_CLAMP((int64_t)(src * (1U << 31)) >> m, INT32_MIN, INT32_MAX)) + +/** + * @brief Convert a floating-point (float64_t) value to a Q7 fixed-point value with a right shift. + * + * @param src The input floating-point (float64_t) value. + * @param m The number of bits to right shift the input value (0 to 7). + * @return The converted Q7 fixed-point value. + */ +#define Z_SHIFT_F64_TO_Q7(src, m) \ + ((q7_t)Z_CLAMP((int32_t)(src * (1U << 7)) >> m, INT8_MIN, INT8_MAX)) + +/** + * @brief Convert a floating-point (float64_t) value to a Q15 fixed-point value with a right shift. + * + * @param src The input floating-point (float64_t) value. + * @param m The number of bits to right shift the input value (0 to 15). + * @return The converted Q15 fixed-point value. + */ +#define Z_SHIFT_F64_TO_Q15(src, m) \ + ((q15_t)Z_CLAMP((int32_t)(src * (1U << 15)) >> m, INT16_MIN, INT16_MAX)) + +/** + * @brief Convert a floating-point (float64_t) value to a Q31 fixed-point value with a right shift. + * + * @param src The input floating-point (float64_t) value. + * @param m The number of bits to right shift the input value (0 to 31). + * @return The converted Q31 fixed-point value. + */ +#define Z_SHIFT_F64_TO_Q31(src, m) \ + ((q31_t)Z_CLAMP((int64_t)(src * (1U << 31)) >> m, INT32_MIN, INT32_MAX)) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_ZEPHYR_DSP_UTILS_H_ */ diff --git a/include/zephyr/dt-bindings/adc/ad7124-adc.h b/include/zephyr/dt-bindings/adc/ad7124-adc.h new file mode 100644 index 0000000000000..d35234a409e49 --- /dev/null +++ b/include/zephyr/dt-bindings/adc/ad7124-adc.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_AD7124_ADC_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_AD7124_ADC_H_ + +#include + +#define AD7124_ADC_AIN0 0 +#define AD7124_ADC_AIN1 1 +#define AD7124_ADC_AIN2 2 +#define AD7124_ADC_AIN3 3 +#define AD7124_ADC_AIN4 4 +#define AD7124_ADC_AIN5 5 +#define AD7124_ADC_AIN6 6 +#define AD7124_ADC_AIN7 7 +#define AD7124_ADC_AIN8 8 +#define AD7124_ADC_AIN9 9 +#define AD7124_ADC_AIN10 10 +#define AD7124_ADC_AIN11 11 +#define AD7124_ADC_AIN12 12 +#define AD7124_ADC_AIN13 13 +#define AD7124_ADC_AIN14 14 +#define AD7124_ADC_AIN15 15 +#define AD7124_ADC_TEMP_SENSOR 16 +#define AD7124_ADC_AVSS 17 +#define AD7124_ADC_INTERNAL_REF 18 +#define AD7124_ADC_DGND 19 +#define AD7124_ADC_AVDD_AVSS_DIV6_PLUS 20 +#define AD7124_ADC_AVDD_AVSS_DIV6_MINUS 21 +#define AD7124_ADC_IOVDD_DGND_DIV6_PLUS 22 +#define AD7124_ADC_IOVDD_DGND_DIV6_MINUS 23 +#define AD7124_ADC_ALDO_AVSS_DIV6_PLUS 24 +#define AD7124_ADC_ALDO_AVSS_DIV6_MINUS 25 +#define AD7124_ADC_DLDO_DGND_DIV6_PLUS 26 +#define AD7124_ADC_DLDO_DGND_DIV6_MINUS 27 +#define AD7124_ADC_V_20MV_P 28 +#define AD7124_ADC_V_20MV_M 29 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_AD7124_ADC_H_ */ diff --git a/include/zephyr/dt-bindings/adc/ads114s0x_adc.h b/include/zephyr/dt-bindings/adc/ads114s0x_adc.h deleted file mode 100644 index c54b1c4c07bf1..0000000000000 --- a/include/zephyr/dt-bindings/adc/ads114s0x_adc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2023 SILA Embedded Solutions GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ADC_ADS114S0X_ADC_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_ADC_ADS114S0X_ADC_H_ - -/* - * These are the available data rates described as samples per second. They - * can be used with the time unit ticks for the acquisition time. - */ -#define ADS114S0X_CONFIG_DR_2_5 0 -#define ADS114S0X_CONFIG_DR_5 1 -#define ADS114S0X_CONFIG_DR_10 2 -#define ADS114S0X_CONFIG_DR_16_6 3 -#define ADS114S0X_CONFIG_DR_20 4 -#define ADS114S0X_CONFIG_DR_50 5 -#define ADS114S0X_CONFIG_DR_60 6 -#define ADS114S0X_CONFIG_DR_100 7 -#define ADS114S0X_CONFIG_DR_200 8 -#define ADS114S0X_CONFIG_DR_400 9 -#define ADS114S0X_CONFIG_DR_800 10 -#define ADS114S0X_CONFIG_DR_1000 11 -#define ADS114S0X_CONFIG_DR_2000 12 -#define ADS114S0X_CONFIG_DR_4000 13 - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ADC_ADS114S0X_ADC_H_ */ diff --git a/include/zephyr/dt-bindings/adc/ads1x4s0x_adc.h b/include/zephyr/dt-bindings/adc/ads1x4s0x_adc.h new file mode 100644 index 0000000000000..51367aa0447b6 --- /dev/null +++ b/include/zephyr/dt-bindings/adc/ads1x4s0x_adc.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ADC_ADS1X4S0X_ADC_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ADC_ADS1X4S0X_ADC_H_ + +/* + * These are the available data rates described as samples per second. They + * can be used with the time unit ticks for the acquisition time. + */ +#define ADS1X4S0X_CONFIG_DR_2_5 0 +#define ADS1X4S0X_CONFIG_DR_5 1 +#define ADS1X4S0X_CONFIG_DR_10 2 +#define ADS1X4S0X_CONFIG_DR_16_6 3 +#define ADS1X4S0X_CONFIG_DR_20 4 +#define ADS1X4S0X_CONFIG_DR_50 5 +#define ADS1X4S0X_CONFIG_DR_60 6 +#define ADS1X4S0X_CONFIG_DR_100 7 +#define ADS1X4S0X_CONFIG_DR_200 8 +#define ADS1X4S0X_CONFIG_DR_400 9 +#define ADS1X4S0X_CONFIG_DR_800 10 +#define ADS1X4S0X_CONFIG_DR_1000 11 +#define ADS1X4S0X_CONFIG_DR_2000 12 +#define ADS1X4S0X_CONFIG_DR_4000 13 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ADC_ADS1X4S0X_ADC_H_ */ diff --git a/include/zephyr/dt-bindings/adc/silabs-adc.h b/include/zephyr/dt-bindings/adc/silabs-adc.h new file mode 100644 index 0000000000000..367ed2627ad37 --- /dev/null +++ b/include/zephyr/dt-bindings/adc/silabs-adc.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * This file was generated by the script gen_adc.py in the hal_silabs module. + * Do not manually edit. + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ADC_SILABS_ADC_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ADC_SILABS_ADC_H_ + +#define IADC_INPUT_GND 0x0 +#define IADC_INPUT_AVDD 0x10 +#define IADC_INPUT_IOVDD 0x11 +#define IADC_INPUT_VBAT 0x12 +#define IADC_INPUT_DVDD 0x14 +#define IADC_INPUT_DECOUPLE 0x17 +#define IADC_INPUT_DAC0 0x20 +#define IADC_INPUT_DAC1 0x20 +#define IADC_INPUT_AIN0 0x40 +#define IADC_INPUT_AIN1 0x40 +#define IADC_INPUT_AIN2 0x50 +#define IADC_INPUT_AIN3 0x50 +#define IADC_INPUT_PA0 0x80 +#define IADC_INPUT_PA1 0x81 +#define IADC_INPUT_PA2 0x82 +#define IADC_INPUT_PA3 0x83 +#define IADC_INPUT_PA4 0x84 +#define IADC_INPUT_PA5 0x85 +#define IADC_INPUT_PA6 0x86 +#define IADC_INPUT_PA7 0x87 +#define IADC_INPUT_PA8 0x88 +#define IADC_INPUT_PA9 0x89 +#define IADC_INPUT_PA10 0x8a +#define IADC_INPUT_PA11 0x8b +#define IADC_INPUT_PA12 0x8c +#define IADC_INPUT_PA13 0x8d +#define IADC_INPUT_PA14 0x8e +#define IADC_INPUT_PA15 0x8f +#define IADC_INPUT_PB0 0x90 +#define IADC_INPUT_PB1 0x91 +#define IADC_INPUT_PB2 0x92 +#define IADC_INPUT_PB3 0x93 +#define IADC_INPUT_PB4 0x94 +#define IADC_INPUT_PB5 0x95 +#define IADC_INPUT_PB6 0x96 +#define IADC_INPUT_PB7 0x97 +#define IADC_INPUT_PB8 0x98 +#define IADC_INPUT_PB9 0x99 +#define IADC_INPUT_PB10 0x9a +#define IADC_INPUT_PB11 0x9b +#define IADC_INPUT_PB12 0x9c +#define IADC_INPUT_PB13 0x9d +#define IADC_INPUT_PB14 0x9e +#define IADC_INPUT_PB15 0x9f +#define IADC_INPUT_PC0 0xa0 +#define IADC_INPUT_PC1 0xa1 +#define IADC_INPUT_PC2 0xa2 +#define IADC_INPUT_PC3 0xa3 +#define IADC_INPUT_PC4 0xa4 +#define IADC_INPUT_PC5 0xa5 +#define IADC_INPUT_PC6 0xa6 +#define IADC_INPUT_PC7 0xa7 +#define IADC_INPUT_PC8 0xa8 +#define IADC_INPUT_PC9 0xa9 +#define IADC_INPUT_PC10 0xaa +#define IADC_INPUT_PC11 0xab +#define IADC_INPUT_PC12 0xac +#define IADC_INPUT_PC13 0xad +#define IADC_INPUT_PC14 0xae +#define IADC_INPUT_PC15 0xaf +#define IADC_INPUT_PD0 0xb0 +#define IADC_INPUT_PD1 0xb1 +#define IADC_INPUT_PD2 0xb2 +#define IADC_INPUT_PD3 0xb3 +#define IADC_INPUT_PD4 0xb4 +#define IADC_INPUT_PD5 0xb5 +#define IADC_INPUT_PD6 0xb6 +#define IADC_INPUT_PD7 0xb7 +#define IADC_INPUT_PD8 0xb8 +#define IADC_INPUT_PD9 0xb9 +#define IADC_INPUT_PD10 0xba +#define IADC_INPUT_PD11 0xbb +#define IADC_INPUT_PD12 0xbc +#define IADC_INPUT_PD13 0xbd +#define IADC_INPUT_PD14 0xbe +#define IADC_INPUT_PD15 0xbf + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ADC_SILABS_ADC_H_ */ diff --git a/include/zephyr/dt-bindings/adc/stm32_adc.h b/include/zephyr/dt-bindings/adc/stm32_adc.h index 20f257275e936..b2020d2142338 100644 --- a/include/zephyr/dt-bindings/adc/stm32_adc.h +++ b/include/zephyr/dt-bindings/adc/stm32_adc.h @@ -64,24 +64,4 @@ STM32_ADC(resolution, reg_val, STM32_ADC_RES_MASK, STM32_ADC_RES_SHIFT, \ STM32_ADC_RES_REG) -/** - * @name STM32 ADC clock source - * This value is to set - * One or both values may not apply to all series. Refer to the RefMan - * @{ - */ -#define SYNC 1 -#define ASYNC 2 -/** @} */ - -/** - * @name STM32 ADC sequencer type - * This value is to set - * One or both values may not apply to all series. Refer to the RefMan - * @{ - */ -#define NOT_FULLY_CONFIGURABLE 0 -#define FULLY_CONFIGURABLE 1 -/** @} */ - #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_STM32_ADC_H_ */ diff --git a/include/zephyr/dt-bindings/clock/imx_ccm.h b/include/zephyr/dt-bindings/clock/imx_ccm.h index 7a4876cc43fd6..4f2f1bb095251 100644 --- a/include/zephyr/dt-bindings/clock/imx_ccm.h +++ b/include/zephyr/dt-bindings/clock/imx_ccm.h @@ -72,4 +72,11 @@ #define IMX_CCM_GPT_IPG_CLK 0x1300UL +#define IMX_CCM_I2C1_CLK 0x1400UL +#define IMX_CCM_I2C2_CLK 0x1401UL +#define IMX_CCM_I2C3_CLK 0x1402UL +#define IMX_CCM_I2C4_CLK 0x1403UL +#define IMX_CCM_I2C5_CLK 0x1404UL +#define IMX_CCM_I2C6_CLK 0x1405UL + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_IMX_CCM_H_ */ diff --git a/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h b/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h index f7d6b7afcd164..e5035584cbec0 100644 --- a/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h +++ b/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h @@ -58,10 +58,13 @@ /* LPSPI */ #define IMX_CCM_LPSPI_CLK 0x500UL +#define IMX_CCM_LPSPI0102_CLK 0x500UL #define IMX_CCM_LPSPI1_CLK 0x500UL #define IMX_CCM_LPSPI2_CLK 0x501UL +#define IMX_CCM_LPSPI0304_CLK 0x501UL #define IMX_CCM_LPSPI3_CLK 0x502UL #define IMX_CCM_LPSPI4_CLK 0x503UL +#define IMX_CCM_LPSPI0506_CLK 0x502UL #define IMX_CCM_LPSPI5_CLK 0x504UL #define IMX_CCM_LPSPI6_CLK 0x505UL #define IMX_CCM_LPSPI7_CLK 0x506UL @@ -74,6 +77,8 @@ /* DMA */ #define IMX_CCM_EDMA_CLK 0x700UL #define IMX_CCM_EDMA_LPSR_CLK 0x701UL +#define IMX_CCM_EDMA3_CLK 0x700UL +#define IMX_CCM_EDMA4_CLK 0x701UL /* PWM */ #define IMX_CCM_PWM_CLK 0x800UL @@ -139,6 +144,11 @@ #define IMX_CCM_MIPI_CSI2RX_UI_CLK 0x2000UL #define IMX_CCM_MIPI_CSI2RX_ESC_CLK 0x2100UL +/* I3C */ +#define IMX_CCM_I3C_CLK 0x2200UL +#define IMX_CCM_I3C1_CLK 0x2200UL +#define IMX_CCM_I3C2_CLK 0x2201UL + /* QTMR */ #define IMX_CCM_QTMR_CLK 0x6000UL #define IMX_CCM_QTMR1_CLK 0x6000UL diff --git a/include/zephyr/dt-bindings/clock/intel_socfpga_clock.h b/include/zephyr/dt-bindings/clock/intel_socfpga_clock.h index 9e98057068e5a..36c7de89cb521 100644 --- a/include/zephyr/dt-bindings/clock/intel_socfpga_clock.h +++ b/include/zephyr/dt-bindings/clock/intel_socfpga_clock.h @@ -13,5 +13,8 @@ #define INTEL_SOCFPGA_CLOCK_UART 2 #define INTEL_SOCFPGA_CLOCK_MMC 3 #define INTEL_SOCFPGA_CLOCK_TIMER 4 +#define INTEL_SOCFPGA_CLOCK_QSPI 5 +#define INTEL_SOCFPGA_CLOCK_I2C 6 +#define INTEL_SOCFPGA_CLOCK_I3C 7 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_INTEL_SOCFPGA_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h index c26735174880b..b98f2a1079e9b 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -21,6 +21,9 @@ #define MCUX_CTIMER2_CLK 2 #define MCUX_CTIMER3_CLK 3 #define MCUX_CTIMER4_CLK 4 +#define MCUX_CTIMER5_CLK 5 +#define MCUX_CTIMER6_CLK 6 +#define MCUX_CTIMER7_CLK 7 #define MCUX_FLEXCOMM0_CLK MCUX_LPC_CLK_ID(0x01, 0x00) #define MCUX_FLEXCOMM1_CLK MCUX_LPC_CLK_ID(0x01, 0x01) @@ -40,9 +43,16 @@ #define MCUX_FLEXCOMM14_CLK MCUX_HS_SPI_CLK #define MCUX_PMIC_I2C_CLK MCUX_LPC_CLK_ID(0x01, 0x0F) #define MCUX_HS_SPI1_CLK MCUX_LPC_CLK_ID(0x01, 0x10) - -#define MCUX_USDHC1_CLK MCUX_LPC_CLK_ID(0x02, 0x00) -#define MCUX_USDHC2_CLK MCUX_LPC_CLK_ID(0x02, 0x01) +#define MCUX_FLEXCOMM17_CLK MCUX_LPC_CLK_ID(0x01, 0x11) +#define MCUX_FLEXCOMM18_CLK MCUX_LPC_CLK_ID(0x01, 0x12) +#define MCUX_FLEXCOMM19_CLK MCUX_LPC_CLK_ID(0x01, 0x13) +#define MCUX_FLEXCOMM20_CLK MCUX_LPC_CLK_ID(0x01, 0x14) +/* On RT7xx, flexcomm14 and 16 only can be LPSPI, flexcomm15 only can be I2C. */ +#define MCUX_LPSPI14_CLK MCUX_LPC_CLK_ID(0x01, 0x24) +#define MCUX_LPI2C15_CLK MCUX_LPC_CLK_ID(0x01, 0x25) +#define MCUX_LPSPI16_CLK MCUX_LPC_CLK_ID(0x01, 0x26) +#define MCUX_USDHC1_CLK MCUX_LPC_CLK_ID(0x02, 0x00) +#define MCUX_USDHC2_CLK MCUX_LPC_CLK_ID(0x02, 0x01) #define MCUX_MCAN_CLK MCUX_LPC_CLK_ID(0x03, 0x00) @@ -98,4 +108,20 @@ #define MCUX_LPUART3_CLK MCUX_LPC_CLK_ID(0x13, 0x03) #define MCUX_LPUART4_CLK MCUX_LPC_CLK_ID(0x13, 0x04) +#define MCUX_LPI2C0_CLK MCUX_LPC_CLK_ID(0x14, 0x00) +#define MCUX_LPI2C1_CLK MCUX_LPC_CLK_ID(0x14, 0x01) +#define MCUX_LPI2C2_CLK MCUX_LPC_CLK_ID(0x14, 0x02) +#define MCUX_LPI2C3_CLK MCUX_LPC_CLK_ID(0x14, 0x03) + +#define MCUX_XSPI_CLK MCUX_LPC_CLK_ID(0x15, 0x00) +#define MCUX_XSPI0_CLK MCUX_LPC_CLK_ID(0x15, 0x00) +#define MCUX_XSPI1_CLK MCUX_LPC_CLK_ID(0x15, 0x01) +#define MCUX_XSPI2_CLK MCUX_LPC_CLK_ID(0x15, 0x02) + +#define MCUX_SAI0_CLK MCUX_LPC_CLK_ID(0x16, 0x00) +#define MCUX_SAI1_CLK MCUX_LPC_CLK_ID(0x16, 0x01) + +#define MCUX_LPSPI0_CLK MCUX_LPC_CLK_ID(0x17, 0x00) +#define MCUX_LPSPI1_CLK MCUX_LPC_CLK_ID(0x17, 0x01) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCUX_LPC_SYSCON_H_ */ diff --git a/include/zephyr/dt-bindings/clock/renesas_rzg_clock.h b/include/zephyr/dt-bindings/clock/renesas_rzg_clock.h new file mode 100644 index 0000000000000..af94425e5334f --- /dev/null +++ b/include/zephyr/dt-bindings/clock/renesas_rzg_clock.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RENESAS_RZG_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RENESAS_RZG_CLOCK_H_ + +/** RZ clock configuration values */ +#define RZ_IP_MASK 0xFF000000UL +#define RZ_IP_SHIFT 24UL +#define RZ_IP_CH_MASK 0xFF0000UL +#define RZ_IP_CH_SHIFT 16UL +#define RZ_CLOCK_MASK 0xFF00UL +#define RZ_CLOCK_SHIFT 8UL +#define RZ_CLOCK_DIV_MASK 0xFFUL +#define RZ_CLOCK_DIV_SHIFT 0UL + +#define RZ_IP_GTM 0UL /* General Timer */ +#define RZ_IP_GPT 1UL /* General PWM Timer */ +#define RZ_IP_SCIF 2UL /* Serial Communications Interface with FIFO */ +#define RZ_IP_RIIC 3UL /* I2C Bus Interface */ +#define RZ_IP_RSPI 4UL /* Renesas Serial Peripheral Interface */ +#define RZ_IP_MHU 5UL /* Message Handling Unit */ +#define RZ_IP_DMAC 6UL /* Direct Memory Access Controller */ +#define RZ_IP_CANFD 7UL /* CANFD Interface (RS-CANFD) */ +#define RZ_IP_ADC 8UL /* A/D Converter */ + +#define RZ_CLOCK_ICLK 0UL /* Cortex-A55 Clock */ +#define RZ_CLOCK_I2CLK 1UL /* Cortex-M33 Clock */ +#define RZ_CLOCK_I3CLK 2UL /* Cortex-M33 FPU Clock */ +#define RZ_CLOCK_S0CLK 3UL /* DDR-PHY Clock */ +#define RZ_CLOCK_OC0CLK 4UL /* OCTA0 Clock */ +#define RZ_CLOCK_OC1CLK 5UL /* OCTA1 Clock */ +#define RZ_CLOCK_SPI0CLK 6UL /* SPI0 Clock */ +#define RZ_CLOCK_SPI1CLK 7UL /* SPI1 Clock */ +#define RZ_CLOCK_SD0CLK 8UL /* SDH0 Clock */ +#define RZ_CLOCK_SD1CLK 9UL /* SDH1 Clock */ +#define RZ_CLOCK_SD2CLK 10UL /* SDH2 Clock */ +#define RZ_CLOCK_M0CLK 11UL /* VCP LCDC Clock */ +#define RZ_CLOCK_HPCLK 12UL /* Ethernet Clock */ +#define RZ_CLOCK_TSUCLK 13UL /* TSU Clock */ +#define RZ_CLOCK_ZTCLK 14UL /* JAUTH Clock */ +#define RZ_CLOCK_P0CLK 15UL /* APB-BUS Clock */ +#define RZ_CLOCK_P1CLK 16UL /* AXI-BUS Clock */ +#define RZ_CLOCK_P2CLK 17UL /* P2CLK */ +#define RZ_CLOCK_P3CLK 18UL /* P3CLK */ +#define RZ_CLOCK_P4CLK 19UL /* P4CLK */ +#define RZ_CLOCK_P5CLK 20UL /* P5CLK */ +#define RZ_CLOCK_ATCLK 21UL /* ATCLK */ +#define RZ_CLOCK_OSCCLK 22UL /* OSC Clock */ +#define RZ_CLOCK_OSCCLK2 23UL /* OSC2 Clock */ + +#define RZ_CLOCK(IP, ch, clk, div) \ + ((RZ_IP_##IP << RZ_IP_SHIFT) | ((ch) << RZ_IP_CH_SHIFT) | ((clk) << RZ_CLOCK_SHIFT) | \ + ((div) << RZ_CLOCK_DIV_SHIFT)) + +/** + * Pack clock configurations in a 32-bit value + * as expected for the Device Tree `clocks` property on Renesas RZ/G. + * + * @param ch Peripheral channel/unit + */ + +/* SCIF */ +#define RZ_CLOCK_SCIF(ch) RZ_CLOCK(SCIF, ch, RZ_CLOCK_P0CLK, 1) + +/* GPT */ +#define RZ_CLOCK_GPT(ch) RZ_CLOCK(GPT, ch, RZ_CLOCK_P0CLK, 1) + +/* MHU */ +#define RZ_CLOCK_MHU(ch) RZ_CLOCK(MHU, ch, RZ_CLOCK_P1CLK, 2) + +/* ADC */ +#define RZ_CLOCK_ADC(ch) RZ_CLOCK(ADC, ch, RZ_CLOCK_TSUCLK, 1) + +/* RIIC */ +#define RZ_CLOCK_RIIC(ch) RZ_CLOCK(RIIC, ch, RZ_CLOCK_P0CLK, 1) + +/* GTM */ +#define RZ_CLOCK_GTM(ch) RZ_CLOCK(GTM, ch, RZ_CLOCK_P0CLK, 1) + +/* CAN */ +#define RZ_CLOCK_CANFD(ch) RZ_CLOCK(CANFD, ch, RZ_CLOCK_P4CLK, 2) + +/* RSPI */ +#define RZ_CLOCK_RSPI(ch) RZ_CLOCK(RSPI, ch, RZ_CLOCK_P0CLK, 1) + +/* DMAC */ +#define RZ_CLOCK_DMAC(ch) RZ_CLOCK(DMAC, ch, RZ_CLOCK_P3CLK, 1) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RENESAS_RZG_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/rpi_pico_clock.h b/include/zephyr/dt-bindings/clock/rpi_pico_clock.h deleted file mode 100644 index 07522be66329c..0000000000000 --- a/include/zephyr/dt-bindings/clock/rpi_pico_clock.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2022 Andrei-Edward Popa - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_H_ - -#define RPI_PICO_PLL_SYS 0 -#define RPI_PICO_PLL_USB 1 -#define RPI_PICO_PLL_COUNT 2 - -#define RPI_PICO_GPIN_0 0 -#define RPI_PICO_GPIN_1 1 -#define RPI_PICO_GPIN_COUNT 2 - -#define RPI_PICO_CLKID_CLK_GPOUT0 0 -#define RPI_PICO_CLKID_CLK_GPOUT1 1 -#define RPI_PICO_CLKID_CLK_GPOUT2 2 -#define RPI_PICO_CLKID_CLK_GPOUT3 3 -#define RPI_PICO_CLKID_CLK_REF 4 -#define RPI_PICO_CLKID_CLK_SYS 5 -#define RPI_PICO_CLKID_CLK_PERI 6 -#define RPI_PICO_CLKID_CLK_USB 7 -#define RPI_PICO_CLKID_CLK_ADC 8 -#define RPI_PICO_CLKID_CLK_RTC 9 - -#define RPI_PICO_CLKID_PLL_SYS 10 -#define RPI_PICO_CLKID_PLL_USB 11 -#define RPI_PICO_CLKID_XOSC 12 -#define RPI_PICO_CLKID_ROSC 13 -#define RPI_PICO_CLKID_ROSC_PH 14 -#define RPI_PICO_CLKID_GPIN0 15 -#define RPI_PICO_CLKID_GPIN1 16 - -#define RPI_PICO_ROSC_RANGE_RESET 0xAA0 -#define RPI_PICO_ROSC_RANGE_LOW 0xFA4 -#define RPI_PICO_ROSC_RANGE_MEDIUM 0xFA5 -#define RPI_PICO_ROSC_RANGE_HIGH 0xFA7 -#define RPI_PICO_ROSC_RANGE_TOOHIGH 0xFA6 - -#define RPI_PICO_CLOCK_COUNT 10 - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/rpi_pico_clock_common.h b/include/zephyr/dt-bindings/clock/rpi_pico_clock_common.h new file mode 100644 index 0000000000000..f19c9baaa645e --- /dev/null +++ b/include/zephyr/dt-bindings/clock/rpi_pico_clock_common.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Andrei-Edward Popa + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_COMMON_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_COMMON_H_ + +#define RPI_PICO_PLL_SYS 0 +#define RPI_PICO_PLL_USB 1 +#define RPI_PICO_PLL_COUNT 2 + +#define RPI_PICO_GPIN_0 0 +#define RPI_PICO_GPIN_1 1 +#define RPI_PICO_GPIN_COUNT 2 + +#define RPI_PICO_CLKID_CLK_GPOUT0 0 +#define RPI_PICO_CLKID_CLK_GPOUT1 1 +#define RPI_PICO_CLKID_CLK_GPOUT2 2 +#define RPI_PICO_CLKID_CLK_GPOUT3 3 +#define RPI_PICO_CLKID_CLK_REF 4 +#define RPI_PICO_CLKID_CLK_SYS 5 +#define RPI_PICO_CLKID_CLK_PERI 6 +/* N.b. clock ids 7-9 are defined in SoC-specific files. */ + +#define RPI_PICO_CLKID_PLL_SYS 10 +#define RPI_PICO_CLKID_PLL_USB 11 +#define RPI_PICO_CLKID_XOSC 12 +#define RPI_PICO_CLKID_ROSC 13 +#define RPI_PICO_CLKID_ROSC_PH 14 +#define RPI_PICO_CLKID_GPIN0 15 +#define RPI_PICO_CLKID_GPIN1 16 + +#define RPI_PICO_ROSC_RANGE_RESET 0xAA0 +#define RPI_PICO_ROSC_RANGE_LOW 0xFA4 +#define RPI_PICO_ROSC_RANGE_MEDIUM 0xFA5 +#define RPI_PICO_ROSC_RANGE_HIGH 0xFA7 +#define RPI_PICO_ROSC_RANGE_TOOHIGH 0xFA6 + +#define RPI_PICO_CLOCK_COUNT 10 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_COMMON_H_ */ diff --git a/include/zephyr/dt-bindings/clock/rpi_pico_rp2040_clock.h b/include/zephyr/dt-bindings/clock/rpi_pico_rp2040_clock.h new file mode 100644 index 0000000000000..e0c679b411037 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/rpi_pico_rp2040_clock.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022 Andrei-Edward Popa + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2040_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2040_CLOCK_H_ + +#include "rpi_pico_clock_common.h" + +#define RPI_PICO_CLKID_CLK_USB 7 +#define RPI_PICO_CLKID_CLK_ADC 8 +#define RPI_PICO_CLKID_CLK_RTC 9 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2040_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/rpi_pico_rp2350_clock.h b/include/zephyr/dt-bindings/clock/rpi_pico_rp2350_clock.h new file mode 100644 index 0000000000000..7a5e48c284f46 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/rpi_pico_rp2350_clock.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2350_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2350_CLOCK_H_ + +#include "rpi_pico_clock_common.h" + +#define RPI_PICO_CLKID_CLK_HSTX 7 +#define RPI_PICO_CLKID_CLK_USB 8 +#define RPI_PICO_CLKID_CLK_ADC 9 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2350_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/rts5912_clock.h b/include/zephyr/dt-bindings/clock/rts5912_clock.h new file mode 100644 index 0000000000000..ef754602dd698 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/rts5912_clock.h @@ -0,0 +1,343 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RTS5912_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RTS5912_CLOCK_H_ + +/* ====================================================================================== */ +/* ===================================== I2CCLK ======================================= */ +#define I2CCLK_I2C0CLKPWR_Pos (0) /*!< I2C0CLKPWR (Bit 0) */ +#define I2CCLK_I2C0CLKPWR_Msk (0x1) /*!< I2C0CLKPWR (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C0CLKSRC_Pos (1) /*!< I2C0CLKSRC (Bit 1) */ +#define I2CCLK_I2C0CLKSRC_Msk (0x2) /*!< I2C0CLKSRC (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C0CLKDIV_Pos (2) /*!< I2C0CLKDIV (Bit 2) */ +#define I2CCLK_I2C0CLKDIV_Msk (0xc) /*!< I2C0CLKDIV (Bitfield-Mask: 0x03) */ +#define I2CCLK_I2C1CLKPWR_Pos (4) /*!< I2C1CLKPWR (Bit 4) */ +#define I2CCLK_I2C1CLKPWR_Msk (0x10) /*!< I2C1CLKPWR (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C1CLKSRC_Pos (5) /*!< I2C1CLKSRC (Bit 5) */ +#define I2CCLK_I2C1CLKSRC_Msk (0x20) /*!< I2C1CLKSRC (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C1CLKDIV_Pos (6) /*!< I2C1CLKDIV (Bit 6) */ +#define I2CCLK_I2C1CLKDIV_Msk (0xc0) /*!< I2C1CLKDIV (Bitfield-Mask: 0x03) */ +#define I2CCLK_I2C2CLKPWR_Pos (8) /*!< I2C2CLKPWR (Bit 8) */ +#define I2CCLK_I2C2CLKPWR_Msk (0x100) /*!< I2C2CLKPWR (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C2CLKSRC_Pos (9) /*!< I2C2CLKSRC (Bit 9) */ +#define I2CCLK_I2C2CLKSRC_Msk (0x200) /*!< I2C2CLKSRC (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C2CLKDIV_Pos (10) /*!< I2C2CLKDIV (Bit 10) */ +#define I2CCLK_I2C2CLKDIV_Msk (0xc00) /*!< I2C2CLKDIV (Bitfield-Mask: 0x03) */ +#define I2CCLK_I2C3CLKPWR_Pos (12) /*!< I2C3CLKPWR (Bit 12) */ +#define I2CCLK_I2C3CLKPWR_Msk (0x1000) /*!< I2C3CLKPWR (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C3CLKSRC_Pos (13) /*!< I2C3CLKSRC (Bit 13) */ +#define I2CCLK_I2C3CLKSRC_Msk (0x2000) /*!< I2C3CLKSRC (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C3CLKDIV_Pos (14) /*!< I2C3CLKDIV (Bit 14) */ +#define I2CCLK_I2C3CLKDIV_Msk (0xc000) /*!< I2C3CLKDIV (Bitfield-Mask: 0x03) */ +#define I2CCLK_I2C4CLKPWR_Pos (16) /*!< I2C4CLKPWR (Bit 16) */ +#define I2CCLK_I2C4CLKPWR_Msk (0x10000) /*!< I2C4CLKPWR (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C4CLKSRC_Pos (17) /*!< I2C4CLKSRC (Bit 17) */ +#define I2CCLK_I2C4CLKSRC_Msk (0x20000) /*!< I2C4CLKSRC (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C4CLKDIV_Pos (18) /*!< I2C4CLKDIV (Bit 18) */ +#define I2CCLK_I2C4CLKDIV_Msk (0xc0000) /*!< I2C4CLKDIV (Bitfield-Mask: 0x03) */ +#define I2CCLK_I2C5CLKPWR_Pos (20) /*!< I2C5CLKPWR (Bit 20) */ +#define I2CCLK_I2C5CLKPWR_Msk (0x100000) /*!< I2C5CLKPWR (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C5CLKSRC_Pos (21) /*!< I2C5CLKSRC (Bit 21) */ +#define I2CCLK_I2C5CLKSRC_Msk (0x200000) /*!< I2C5CLKSRC (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C5CLKDIV_Pos (22) /*!< I2C5CLKDIV (Bit 22) */ +#define I2CCLK_I2C5CLKDIV_Msk (0xc00000) /*!< I2C5CLKDIV (Bitfield-Mask: 0x03) */ +#define I2CCLK_I2C6CLKPWR_Pos (24) /*!< I2C6CLKPWR (Bit 24) */ +#define I2CCLK_I2C6CLKPWR_Msk (0x1000000) /*!< I2C6CLKPWR (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C6CLKSRC_Pos (25) /*!< I2C6CLKSRC (Bit 25) */ +#define I2CCLK_I2C6CLKSRC_Msk (0x2000000) /*!< I2C6CLKSRC (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C6CLKDIV_Pos (26) /*!< I2C6CLKDIV (Bit 26) */ +#define I2CCLK_I2C6CLKDIV_Msk (0xc000000) /*!< I2C6CLKDIV (Bitfield-Mask: 0x03) */ +#define I2CCLK_I2C7CLKPWR_Pos (28) /*!< I2C7CLKPWR (Bit 28) */ +#define I2CCLK_I2C7CLKPWR_Msk (0x10000000) /*!< I2C7CLKPWR (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C7CLKSRC_Pos (29) /*!< I2C7CLKSRC (Bit 29) */ +#define I2CCLK_I2C7CLKSRC_Msk (0x20000000) /*!< I2C7CLKSRC (Bitfield-Mask: 0x01) */ +#define I2CCLK_I2C7CLKDIV_Pos (30) /*!< I2C7CLKDIV (Bit 30) */ +#define I2CCLK_I2C7CLKDIV_Msk (0xc0000000) /*!< I2C7CLKDIV (Bitfield-Mask: 0x03) */ +/* =================================== PERICLKPWR0 ==================================== */ +#define PERICLKPWR0_GPIOCLKPWR_Pos (0) /*!< GPIOCLKPWR (Bit 0) */ +#define PERICLKPWR0_GPIOCLKPWR_Msk (0x1) /*!< GPIOCLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_TACHO0CLKPWR_Pos (1) /*!< TACHO0CLKPWR (Bit 1) */ +#define PERICLKPWR0_TACHO0CLKPWR_Msk (0x2) /*!< TACHO0CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_TACHO1CLKPWR_Pos (2) /*!< TACHO1CLKPWR (Bit 2) */ +#define PERICLKPWR0_TACHO1CLKPWR_Msk (0x4) /*!< TACHO1CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_TACHO2CLKPWR_Pos (3) /*!< TACHO2CLKPWR (Bit 3) */ +#define PERICLKPWR0_TACHO2CLKPWR_Msk (0x8) /*!< TACHO2CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_TACHO3CLKPWR_Pos (4) /*!< TACHO3CLKPWR (Bit 4) */ +#define PERICLKPWR0_TACHO3CLKPWR_Msk (0x10) /*!< TACHO3CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PS2CLKPWR_Pos (5) /*!< PS2CLKPWR (Bit 5) */ +#define PERICLKPWR0_PS2CLKPWR_Msk (0x20) /*!< PS2CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_KBMCLKPWR_Pos (6) /*!< KBMCLKPWR (Bit 6) */ +#define PERICLKPWR0_KBMCLKPWR_Msk (0x40) /*!< KBMCLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PECICLKPWR_Pos (7) /*!< PECICLKPWR (Bit 7) */ +#define PERICLKPWR0_PECICLKPWR_Msk (0x80) /*!< PECICLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PL0CLKPWR_Pos (8) /*!< PL0CLKPWR (Bit 8) */ +#define PERICLKPWR0_PL0CLKPWR_Msk (0x100) /*!< PL0CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PL1CLKPWR_Pos (9) /*!< PL1CLKPWR (Bit 9) */ +#define PERICLKPWR0_PL1CLKPWR_Msk (0x200) /*!< PL1CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM0CLKPWR_Pos (10) /*!< PWM0CLKPWR (Bit 10) */ +#define PERICLKPWR0_PWM0CLKPWR_Msk (0x400) /*!< PWM0CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM1CLKPWR_Pos (11) /*!< PWM1CLKPWR (Bit 11) */ +#define PERICLKPWR0_PWM1CLKPWR_Msk (0x800) /*!< PWM1CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM2CLKPWR_Pos (12) /*!< PWM2CLKPWR (Bit 12) */ +#define PERICLKPWR0_PWM2CLKPWR_Msk (0x1000) /*!< PWM2CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM3CLKPWR_Pos (13) /*!< PWM3CLKPWR (Bit 13) */ +#define PERICLKPWR0_PWM3CLKPWR_Msk (0x2000) /*!< PWM3CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM4CLKPWR_Pos (14) /*!< PWM4CLKPWR (Bit 14) */ +#define PERICLKPWR0_PWM4CLKPWR_Msk (0x4000) /*!< PWM4CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM5CLKPWR_Pos (15) /*!< PWM5CLKPWR (Bit 15) */ +#define PERICLKPWR0_PWM5CLKPWR_Msk (0x8000) /*!< PWM5CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM6CLKPWR_Pos (16) /*!< PWM6CLKPWR (Bit 16) */ +#define PERICLKPWR0_PWM6CLKPWR_Msk (0x10000) /*!< PWM6CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM7CLKPWR_Pos (17) /*!< PWM7CLKPWR (Bit 17) */ +#define PERICLKPWR0_PWM7CLKPWR_Msk (0x20000) /*!< PWM7CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM8CLKPWR_Pos (18) /*!< PWM8CLKPWR (Bit 18) */ +#define PERICLKPWR0_PWM8CLKPWR_Msk (0x40000) /*!< PWM8CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM9CLKPWR_Pos (19) /*!< PWM9CLKPWR (Bit 19) */ +#define PERICLKPWR0_PWM9CLKPWR_Msk (0x80000) /*!< PWM9CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM10CLKPWR_Pos (20) /*!< PWM10CLKPWR (Bit 20) */ +#define PERICLKPWR0_PWM10CLKPWR_Msk (0x100000) /*!< PWM10CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PWM11CLKPWR_Pos (21) /*!< PWM11CLKPWR (Bit 21) */ +#define PERICLKPWR0_PWM11CLKPWR_Msk (0x200000) /*!< PWM11CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_ESPICLKPWR_Pos (22) /*!< ESPICLKPWR (Bit 22) */ +#define PERICLKPWR0_ESPICLKPWR_Msk (0x400000) /*!< ESPICLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_KBCCLKPWR_Pos (23) /*!< KBCCLKPWR (Bit 23) */ +#define PERICLKPWR0_KBCCLKPWR_Msk (0x800000) /*!< KBCCLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_ACPICLKPWR_Pos (24) /*!< ACPICLKPWR (Bit 24) */ +#define PERICLKPWR0_ACPICLKPWR_Msk (0x1000000) /*!< ACPICLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_PMPORT0CLKPWR_Pos (25) /*!< PMPORT0CLKPWR (Bit 25) */ +#define PERICLKPWR0_PMPORT0CLKPWR_Msk (0x2000000) /*!< PMPORT0CLKPWR (Bitfield-Mask: 0x01)*/ +#define PERICLKPWR0_PMPORT1CLKPWR_Pos (26) /*!< PMPORT1CLKPWR (Bit 26) */ +#define PERICLKPWR0_PMPORT1CLKPWR_Msk (0x4000000) /*!< PMPORT1CLKPWR (Bitfield-Mask: 0x01)*/ +#define PERICLKPWR0_PMPORT2CLKPWR_Pos (27) /*!< PMPORT2CLKPWR (Bit 27) */ +#define PERICLKPWR0_PMPORT2CLKPWR_Msk (0x8000000) /*!< PMPORT2CLKPWR (Bitfield-Mask: 0x01)*/ +#define PERICLKPWR0_PMPORT3CLKPWR_Pos (28) /*!< PMPORT3CLKPWR (Bit 28) */ +#define PERICLKPWR0_PMPORT3CLKPWR_Msk (0x10000000) /*!< PMPORT3CLKPWR (Bitfield-Mask: 0x01)*/ +#define PERICLKPWR0_P80CLKPWR_Pos (29) /*!< P80CLKPWR (Bit 29) */ +#define PERICLKPWR0_P80CLKPWR_Msk (0x20000000) /*!< P80CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_EMI0CLKPWR_Pos (30) /*!< EMI0CLKPWR (Bit 30) */ +#define PERICLKPWR0_EMI0CLKPWR_Msk (0x40000000) /*!< EMI0CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR0_EMI1CLKPWR_Pos (31) /*!< EMI1CLKPWR (Bit 31) */ +#define PERICLKPWR0_EMI1CLKPWR_Msk (0x80000000) /*!< EMI1CLKPWR (Bitfield-Mask: 0x01) */ +/* ===================================== UARTCLK ====================================== */ +#define UARTCLK_PWR_Pos (0) /*!< PWR (Bit 0) */ +#define UARTCLK_PWR_Msk (0x1) /*!< PWR (Bitfield-Mask: 0x01) */ +#define UARTCLK_SRC_Pos (1) /*!< SRC (Bit 1) */ +#define UARTCLK_SRC_Msk (0x2) /*!< SRC (Bitfield-Mask: 0x01) */ +#define UARTCLK_DIV_Pos (2) /*!< DIV (Bit 2) */ +#define UARTCLK_DIV_Msk (0xc) /*!< DIV (Bitfield-Mask: 0x03) */ +/* ===================================== ADCCLK ======================================= */ +#define ADCCLK_PWR_Pos (0) /*!< PWR (Bit 0) */ +#define ADCCLK_PWR_Msk (0x1) /*!< PWR (Bitfield-Mask: 0x01) */ +#define ADCCLK_SRC_Pos (1) /*!< SRC (Bit 1) */ +#define ADCCLK_SRC_Msk (0x2) /*!< SRC (Bitfield-Mask: 0x01) */ +#define ADCCLK_DIV_Pos (2) /*!< DIV (Bit 2) */ +#define ADCCLK_DIV_Msk (0x1c) /*!< DIV (Bitfield-Mask: 0x07) */ +/* =================================== PERICLKPWR1 ==================================== */ +#define PERICLKPWR1_EMI2CLKPWR_Pos (0) /*!< EMI2CLKPWR (Bit 0) */ +#define PERICLKPWR1_EMI2CLKPWR_Msk (0x1) /*!< EMI2CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_EMI3CLKPWR_Pos (1) /*!< EMI3CLKPWR (Bit 1) */ +#define PERICLKPWR1_EMI3CLKPWR_Msk (0x2) /*!< EMI3CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_EMI4CLKPWR_Pos (2) /*!< EMI4CLKPWR (Bit 2) */ +#define PERICLKPWR1_EMI4CLKPWR_Msk (0x4) /*!< EMI4CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_EMI5CLKPWR_Pos (3) /*!< EMI5CLKPWR (Bit 3) */ +#define PERICLKPWR1_EMI5CLKPWR_Msk (0x8) /*!< EMI5CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_EMI6CLKPWR_Pos (4) /*!< EMI6CLKPWR (Bit 4) */ +#define PERICLKPWR1_EMI6CLKPWR_Msk (0x10) /*!< EMI6CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_EMI7CLKPWR_Pos (5) /*!< EMI7CLKPWR (Bit 5) */ +#define PERICLKPWR1_EMI7CLKPWR_Msk (0x20) /*!< EMI7CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_I3C0CLKPWR_Pos (9) /*!< I3C0CLKPWR (Bit 9) */ +#define PERICLKPWR1_I3C0CLKPWR_Msk (0x200) /*!< I3C0CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_I3C1CLKPWR_Pos (10) /*!< I3C1CLKPWR (Bit 10) */ +#define PERICLKPWR1_I3C1CLKPWR_Msk (0x400) /*!< I3C1CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_I2CAUTOCLKPWR_Pos (11) /*!< I2CAUTOCLKPWR (Bit 11) */ +#define PERICLKPWR1_I2CAUTOCLKPWR_Msk (0x800) /*!< I2CAUTOCLKPWR (Bitfield-Mask: 0x01)*/ +#define PERICLKPWR1_MCCLKPWR_Pos (12) /*!< MCCLKPWR (Bit 12) */ +#define PERICLKPWR1_MCCLKPWR_Msk (0x1000) /*!< MCCLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_TMR0CLKPWR_Pos (13) /*!< TMR0CLKPWR (Bit 13) */ +#define PERICLKPWR1_TMR0CLKPWR_Msk (0x2000) /*!< TMR0CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_TMR1CLKPWR_Pos (14) /*!< TMR1CLKPWR (Bit 14) */ +#define PERICLKPWR1_TMR1CLKPWR_Msk (0x4000) /*!< TMR1CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_TMR2CLKPWR_Pos (15) /*!< TMR2CLKPWR (Bit 15) */ +#define PERICLKPWR1_TMR2CLKPWR_Msk (0x8000) /*!< TMR2CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_TMR3CLKPWR_Pos (16) /*!< TMR3CLKPWR (Bit 16) */ +#define PERICLKPWR1_TMR3CLKPWR_Msk (0x10000) /*!< TMR3CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_TMR4CLKPWR_Pos (17) /*!< TMR4CLKPWR (Bit 17) */ +#define PERICLKPWR1_TMR4CLKPWR_Msk (0x20000) /*!< TMR4CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_TMR5CLKPWR_Pos (18) /*!< TMR5CLKPWR (Bit 18) */ +#define PERICLKPWR1_TMR5CLKPWR_Msk (0x40000) /*!< TMR5CLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_RTMRCLKPWR_Pos (19) /*!< RTMRCLKPWR (Bit 19) */ +#define PERICLKPWR1_RTMRCLKPWR_Msk (0x80000) /*!< RTMRCLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR1_SLWTMR0CLKPWR_Pos (20) /*!< SLWTMR0CLKPWR (Bit 20) */ +#define PERICLKPWR1_SLWTMR0CLKPWR_Msk (0x100000) /*!< SLWTMR0CLKPWR (Bitfield-Mask: 0x01)*/ +#define PERICLKPWR1_SLWTMR1CLKPWR_Pos (21) /*!< SLWTMR1CLKPWR (Bit 21) */ +#define PERICLKPWR1_SLWTMR1CLKPWR_Msk (0x200000) /*!< SLWTMR1CLKPWR (Bitfield-Mask: 0x01)*/ +/* =================================== PERICLKPWR2 ==================================== */ +#define PERICLKPWR2_RTCCLKPWR_Pos (0) /*!< RTCCLKPWR (Bit 0) */ +#define PERICLKPWR2_RTCCLKPWR_Msk (0x1) /*!< RTCCLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR2_WDTCLKPWR_Pos (1) /*!< WDTCLKPWR (Bit 1) */ +#define PERICLKPWR2_WDTCLKPWR_Msk (0x2) /*!< WDTCLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR2_PWRBTNCLKPWR_Pos (2) /*!< PWRBTNCLKPWR (Bit 2) */ +#define PERICLKPWR2_PWRBTNCLKPWR_Msk (0x4) /*!< PWRBTNCLKPWR (Bitfield-Mask: 0x01) */ +#define PERICLKPWR2_RC32KSRC_Pos (30) /*!< RC32KSRC (Bit 30) */ +#define PERICLKPWR2_RC32KSRC_Msk (0xc0000000) /*!< RC32KSRC (Bitfield-Mask: 0x03) */ +/* ====================================================================================== */ + +#define RTS5912_SCCON_SYS (0) +#define RTS5912_SCCON_I2C (2) +#define RTS5912_SCCON_UART (3) +#define RTS5912_SCCON_ADC (4) +#define RTS5912_SCCON_PERIPH_GRP0 (5) +#define RTS5912_SCCON_PERIPH_GRP1 (6) +#define RTS5912_SCCON_PERIPH_GRP2 (7) + +#define I2C0_CLKPWR (I2CCLK_I2C0CLKPWR_Pos) +#define I2C1_CLKPWR (I2CCLK_I2C1CLKPWR_Pos) +#define I2C2_CLKPWR (I2CCLK_I2C2CLKPWR_Pos) +#define I2C3_CLKPWR (I2CCLK_I2C3CLKPWR_Pos) +#define I2C4_CLKPWR (I2CCLK_I2C4CLKPWR_Pos) +#define I2C5_CLKPWR (I2CCLK_I2C5CLKPWR_Pos) +#define I2C6_CLKPWR (I2CCLK_I2C6CLKPWR_Pos) +#define I2C7_CLKPWR (I2CCLK_I2C7CLKPWR_Pos) + +#define I2C0_PLL (0x0 << I2CCLK_I2C0CLKSRC_Pos) +#define I2C0_RC25M (0x1 << I2CCLK_I2C0CLKSRC_Pos) +#define I2C1_PLL (0x0 << I2CCLK_I2C1CLKSRC_Pos) +#define I2C1_RC25M (0x1 << I2CCLK_I2C1CLKSRC_Pos) +#define I2C2_PLL (0x0 << I2CCLK_I2C2CLKSRC_Pos) +#define I2C2_RC25M (0x1 << I2CCLK_I2C2CLKSRC_Pos) +#define I2C3_PLL (0x0 << I2CCLK_I2C3CLKSRC_Pos) +#define I2C3_RC25M (0x1 << I2CCLK_I2C3CLKSRC_Pos) +#define I2C4_PLL (0x0 << I2CCLK_I2C4CLKSRC_Pos) +#define I2C4_RC25M (0x1 << I2CCLK_I2C4CLKSRC_Pos) +#define I2C5_PLL (0x0 << I2CCLK_I2C5CLKSRC_Pos) +#define I2C5_RC25M (0x1 << I2CCLK_I2C5CLKSRC_Pos) +#define I2C6_PLL (0x0 << I2CCLK_I2C6CLKSRC_Pos) +#define I2C6_RC25M (0x1 << I2CCLK_I2C6CLKSRC_Pos) +#define I2C7_PLL (0x0 << I2CCLK_I2C7CLKSRC_Pos) +#define I2C7_RC25M (0x1 << I2CCLK_I2C7CLKSRC_Pos) + +#define I2C0_CLKDIV1 (0 << I2CCLK_I2C0CLKDIV_Pos) +#define I2C0_CLKDIV2 (1 << I2CCLK_I2C0CLKDIV_Pos) +#define I2C0_CLKDIV4 (2 << I2CCLK_I2C0CLKDIV_Pos) +#define I2C0_CLKDIV8 (3 << I2CCLK_I2C0CLKDIV_Pos) + +#define I2C1_CLKDIV1 (0 << I2CCLK_I2C1CLKDIV_Pos) +#define I2C1_CLKDIV2 (1 << I2CCLK_I2C1CLKDIV_Pos) +#define I2C1_CLKDIV4 (2 << I2CCLK_I2C1CLKDIV_Pos) +#define I2C1_CLKDIV8 (3 << I2CCLK_I2C1CLKDIV_Pos) + +#define I2C2_CLKDIV1 (0 << I2CCLK_I2C2CLKDIV_Pos) +#define I2C2_CLKDIV2 (1 << I2CCLK_I2C2CLKDIV_Pos) +#define I2C2_CLKDIV4 (2 << I2CCLK_I2C2CLKDIV_Pos) +#define I2C2_CLKDIV8 (3 << I2CCLK_I2C2CLKDIV_Pos) + +#define I2C3_CLKDIV1 (0 << I2CCLK_I2C3CLKDIV_Pos) +#define I2C3_CLKDIV2 (1 << I2CCLK_I2C3CLKDIV_Pos) +#define I2C3_CLKDIV4 (2 << I2CCLK_I2C3CLKDIV_Pos) +#define I2C3_CLKDIV8 (3 << I2CCLK_I2C3CLKDIV_Pos) + +#define I2C4_CLKDIV1 (0 << I2CCLK_I2C4CLKDIV_Pos) +#define I2C4_CLKDIV2 (1 << I2CCLK_I2C4CLKDIV_Pos) +#define I2C4_CLKDIV4 (2 << I2CCLK_I2C4CLKDIV_Pos) +#define I2C4_CLKDIV8 (3 << I2CCLK_I2C4CLKDIV_Pos) + +#define I2C5_CLKDIV1 (0 << I2CCLK_I2C5CLKDIV_Pos) +#define I2C5_CLKDIV2 (1 << I2CCLK_I2C5CLKDIV_Pos) +#define I2C5_CLKDIV4 (2 << I2CCLK_I2C5CLKDIV_Pos) +#define I2C5_CLKDIV8 (3 << I2CCLK_I2C5CLKDIV_Pos) + +#define I2C6_CLKDIV1 (0 << I2CCLK_I2C6CLKDIV_Pos) +#define I2C6_CLKDIV2 (1 << I2CCLK_I2C6CLKDIV_Pos) +#define I2C6_CLKDIV4 (2 << I2CCLK_I2C6CLKDIV_Pos) +#define I2C6_CLKDIV8 (3 << I2CCLK_I2C6CLKDIV_Pos) + +#define I2C7_CLKDIV1 (0 << I2CCLK_I2C7CLKDIV_Pos) +#define I2C7_CLKDIV2 (1 << I2CCLK_I2C7CLKDIV_Pos) +#define I2C7_CLKDIV4 (2 << I2CCLK_I2C7CLKDIV_Pos) +#define I2C7_CLKDIV8 (3 << I2CCLK_I2C7CLKDIV_Pos) + +#define UART0_CLKPWR (UARTCLK_PWR_Pos) + +#define UART0_RC25M (0x0 << UARTCLK_SRC_Pos) +#define UART0_PLL (0x1 << UARTCLK_SRC_Pos) + +#define UART0_CLKDIV1 (0 << UARTCLK_DIV_Pos) +#define UART0_CLKDIV2 (1 << UARTCLK_DIV_Pos) +#define UART0_CLKDIV4 (2 << UARTCLK_DIV_Pos) +#define UART0_CLKDIV8 (3 << UARTCLK_DIV_Pos) + +#define ADC0_CLKPWR (ADCCLK_PWR_Pos) + +#define ADC0_RC25M (0x0 << ADCCLK_SRC_Pos) +#define ADC0_PLL (0x1 << ADCCLK_SRC_Pos) + +#define ADC0_CLKDIV1 (0 << ADCCLK_DIV_Pos) +#define ADC0_CLKDIV2 (1 << ADCCLK_DIV_Pos) +#define ADC0_CLKDIV3 (2 << ADCCLK_DIV_Pos) +#define ADC0_CLKDIV4 (3 << ADCCLK_DIV_Pos) +#define ADC0_CLKDIV6 (4 << ADCCLK_DIV_Pos) +#define ADC0_CLKDIV8 (5 << ADCCLK_DIV_Pos) + +#define PERIPH_GRP0_GPIO_CLKPWR (PERICLKPWR0_GPIOCLKPWR_Pos) +#define PERIPH_GRP0_TACH0_CLKPWR (PERICLKPWR0_TACHO0CLKPWR_Pos) +#define PERIPH_GRP0_TACH1_CLKPWR (PERICLKPWR0_TACHO1CLKPWR_Pos) +#define PERIPH_GRP0_TACH2_CLKPWR (PERICLKPWR0_TACHO2CLKPWR_Pos) +#define PERIPH_GRP0_TACH3_CLKPWR (PERICLKPWR0_TACHO3CLKPWR_Pos) +#define PERIPH_GRP0_PS2_CLKPWR (PERICLKPWR0_PS2CLKPWR_Pos) +#define PERIPH_GRP0_KBM_CLKPWR (PERICLKPWR0_KBMCLKPWR_Pos) +#define PERIPH_GRP0_PECI_CLKPWR (PERICLKPWR0_PECICLKPWR_Pos) +#define PERIPH_GRP0_LEDPWM0_CLKPWR (PERICLKPWR0_PL0CLKPWR_Pos) +#define PERIPH_GRP0_LEDPWM1_CLKPWR (PERICLKPWR0_PL1CLKPWR_Pos) +#define PERIPH_GRP0_PWM0_CLKPWR (PERICLKPWR0_PWM0CLKPWR_Pos) +#define PERIPH_GRP0_PWM1_CLKPWR (PERICLKPWR0_PWM1CLKPWR_Pos) +#define PERIPH_GRP0_PWM2_CLKPWR (PERICLKPWR0_PWM2CLKPWR_Pos) +#define PERIPH_GRP0_PWM3_CLKPWR (PERICLKPWR0_PWM3CLKPWR_Pos) +#define PERIPH_GRP0_PWM4_CLKPWR (PERICLKPWR0_PWM4CLKPWR_Pos) +#define PERIPH_GRP0_PWM5_CLKPWR (PERICLKPWR0_PWM5CLKPWR_Pos) +#define PERIPH_GRP0_PWM6_CLKPWR (PERICLKPWR0_PWM6CLKPWR_Pos) +#define PERIPH_GRP0_PWM7_CLKPWR (PERICLKPWR0_PWM7CLKPWR_Pos) +#define PERIPH_GRP0_PWM8_CLKPWR (PERICLKPWR0_PWM8CLKPWR_Pos) +#define PERIPH_GRP0_PWM9_CLKPWR (PERICLKPWR0_PWM9CLKPWR_Pos) +#define PERIPH_GRP0_PWM10_CLKPWR (PERICLKPWR0_PWM10CLKPWR_Pos) +#define PERIPH_GRP0_PWM11_CLKPWR (PERICLKPWR0_PWM11CLKPWR_Pos) +#define PERIPH_GRP0_ESPI_CLKPWR (PERICLKPWR0_ESPICLKPWR_Pos) +#define PERIPH_GRP0_KBC_CLKPWR (PERICLKPWR0_KBCCLKPWR_Pos) +#define PERIPH_GRP0_ACPI_CLKPWR (PERICLKPWR0_ACPICLKPWR_Pos) +#define PERIPH_GRP0_PMPORT0_CLKPWR (PERICLKPWR0_PMPORT0CLKPWR_Pos) +#define PERIPH_GRP0_PMPORT1_CLKPWR (PERICLKPWR0_PMPORT1CLKPWR_Pos) +#define PERIPH_GRP0_PMPORT2_CLKPWR (PERICLKPWR0_PMPORT2CLKPWR_Pos) +#define PERIPH_GRP0_PMPORT3_CLKPWR (PERICLKPWR0_PMPORT3CLKPWR_Pos) +#define PERIPH_GRP0_P80_CLKPWR (PERICLKPWR0_P80CLKPWR_Pos) +#define PERIPH_GRP0_EMI0_CLKPWR (PERICLKPWR0_EMI0CLKPWR_Pos) +#define PERIPH_GRP0_EMI1_CLKPWR (PERICLKPWR0_EMI1CLKPWR_Pos) + +#define PERIPH_GRP1_EMI2_CLKPWR (PERICLKPWR1_EMI2CLKPWR_Pos) +#define PERIPH_GRP1_EMI3_CLKPWR (PERICLKPWR1_EMI3CLKPWR_Pos) +#define PERIPH_GRP1_EMI4_CLKPWR (PERICLKPWR1_EMI4CLKPWR_Pos) +#define PERIPH_GRP1_EMI5_CLKPWR (PERICLKPWR1_EMI5CLKPWR_Pos) +#define PERIPH_GRP1_EMI6_CLKPWR (PERICLKPWR1_EMI6CLKPWR_Pos) +#define PERIPH_GRP1_EMI7_CLKPWR (PERICLKPWR1_EMI7CLKPWR_Pos) +#define PERIPH_GRP1_I3C0_CLKPWR (PERICLKPWR1_I3C0CLKPWR_Pos) +#define PERIPH_GRP1_I3C1_CLKPWR (PERICLKPWR1_I3C1CLKPWR_Pos) +#define PERIPH_GRP1_I2CAUTO_CLKPWR (PERICLKPWR1_I2CAUTOCLKPWR_Pos) +#define PERIPH_GRP1_MC_CLKPWR (PERICLKPWR1_MCCLKPWR_Pos) +#define PERIPH_GRP1_TMR0_CLKPWR (PERICLKPWR1_TMR0CLKPWR_Pos) +#define PERIPH_GRP1_TMR1_CLKPWR (PERICLKPWR1_TMR1CLKPWR_Pos) +#define PERIPH_GRP1_TMR2_CLKPWR (PERICLKPWR1_TMR2CLKPWR_Pos) +#define PERIPH_GRP1_TMR3_CLKPWR (PERICLKPWR1_TMR3CLKPWR_Pos) +#define PERIPH_GRP1_TMR4_CLKPWR (PERICLKPWR1_TMR4CLKPWR_Pos) +#define PERIPH_GRP1_TMR5_CLKPWR (PERICLKPWR1_TMR5CLKPWR_Pos) +#define PERIPH_GRP1_RTMR_CLKPWR (PERICLKPWR1_RTMRCLKPWR_Pos) +#define PERIPH_GRP1_SLWTMR0_CLKPWR (PERICLKPWR1_SLWTMR0CLKPWR_Pos) +#define PERIPH_GRP1_SLWTMR1_CLKPWR (PERICLKPWR1_SLWTMR1CLKPWR_Pos) + +#define PERIPH_GRP2_RTC_CLKPWR (PERICLKPWR2_RTCCLKPWR_Pos) +#define PERIPH_GRP2_WDT_CLKPWR (PERICLKPWR2_WDTCLKPWR_Pos) +#define PERIPH_GRP2_WDTPWRBTN_CLKPWR (PERICLKPWR2_PWRBTNCLKPWR_Pos) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RTS5912_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/silabs/siwx91x-clock.h b/include/zephyr/dt-bindings/clock/silabs/siwx91x-clock.h new file mode 100644 index 0000000000000..06a007e82eb2d --- /dev/null +++ b/include/zephyr/dt-bindings/clock/silabs/siwx91x-clock.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_SIWX91X_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_SIWX91X_CLOCK_H_ + +#define SIWX91X_CLK_ULP_UART 0 +#define SIWX91X_CLK_ULP_I2C 1 +#define SIWX91X_CLK_ULP_DMA 2 +#define SIWX91X_CLK_UART1 3 +#define SIWX91X_CLK_UART2 4 +#define SIWX91X_CLK_I2C0 5 +#define SIWX91X_CLK_I2C1 6 +#define SIWX91X_CLK_DMA0 7 + +#endif diff --git a/include/zephyr/dt-bindings/clock/silabs/xg29-clock.h b/include/zephyr/dt-bindings/clock/silabs/xg29-clock.h new file mode 100644 index 0000000000000..20a9eb4b78347 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/silabs/xg29-clock.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * This file was generated by the script gen_clock_control.py in the hal_silabs module. + * Do not manually edit. + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_XG29_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_XG29_CLOCK_H_ + +#include +#include "common-clock.h" + +/* + * DT macros for clock tree nodes. + * Defined as: + * 0..5 - Bit within CLKEN register + * 6..8 - CLKEN register number + * Must stay in sync with equivalent SL_BUS_*_VALUE constants in the Silicon Labs HAL to be + * interpreted correctly by the clock control driver. + */ +#define CLOCK_ACMP0 (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 19)) +#define CLOCK_AGC (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 0)) +#define CLOCK_AMUXCP0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 11)) +#define CLOCK_BUFC (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 11)) +#define CLOCK_BURAM (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 28)) +#define CLOCK_BURTC (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 29)) +#define CLOCK_SEMAILBOX (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 21)) +#define CLOCK_DMEM (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 22)) +#define CLOCK_DCDC (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 31)) +#define CLOCK_DPLL0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 17)) +#define CLOCK_ETAMPDET (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 28)) +#define CLOCK_EUSART0 (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 20)) +#define CLOCK_EUSART1 (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 23)) +#define CLOCK_FRC (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 3)) +#define CLOCK_FSRCO (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 20)) +#define CLOCK_GPCRC0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 3)) +#define CLOCK_GPIO (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 26)) +#define CLOCK_HFRCO0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 18)) +#define CLOCK_HFXO0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 19)) +#define CLOCK_I2C0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 14)) +#define CLOCK_I2C1 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 15)) +#define CLOCK_IADC0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 10)) +#define CLOCK_ICACHE0 (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 16)) +#define CLOCK_IFADCDEBUG (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 12)) +#define CLOCK_LDMA0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 0)) +#define CLOCK_LDMAXBAR0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 1)) +#define CLOCK_LETIMER0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 12)) +#define CLOCK_LFRCO (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 21)) +#define CLOCK_LFXO (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 22)) +#define CLOCK_MODEM (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 1)) +#define CLOCK_MSC (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 17)) +#define CLOCK_PDM (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 25)) +#define CLOCK_PRORTC (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 10)) +#define CLOCK_PROTIMER (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 4)) +#define CLOCK_PRS (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 27)) +#define CLOCK_RAC (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 5)) +#define CLOCK_RADIOAES (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 2)) +#define CLOCK_RDMAILBOX0 (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 8)) +#define CLOCK_RDMAILBOX1 (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 9)) +#define CLOCK_RDSCRATCHPAD (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 7)) +#define CLOCK_RFCRC (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 2)) +#define CLOCK_RFSENSE (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 14)) +#define CLOCK_RTCC (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 30)) +#define CLOCK_SMU (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 15)) +#define CLOCK_SYNTH (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 6)) +#define CLOCK_SYSCFG (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 16)) +#define CLOCK_TIMER0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 4)) +#define CLOCK_TIMER1 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 5)) +#define CLOCK_TIMER2 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 6)) +#define CLOCK_TIMER3 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 7)) +#define CLOCK_TIMER4 (FIELD_PREP(CLOCK_REG_MASK, 1) | FIELD_PREP(CLOCK_BIT_MASK, 18)) +#define CLOCK_ULFRCO (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 23)) +#define CLOCK_USART0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 8)) +#define CLOCK_USART1 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 9)) +#define CLOCK_WDOG0 (FIELD_PREP(CLOCK_REG_MASK, 0) | FIELD_PREP(CLOCK_BIT_MASK, 13)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_XG29_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32_clock.h b/include/zephyr/dt-bindings/clock/stm32_clock.h index a669f49b92c60..0564c3084b155 100644 --- a/include/zephyr/dt-bindings/clock/stm32_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32_clock.h @@ -22,5 +22,11 @@ #define STM32_CLOCK_BUS_APB5 12 #define STM32_CLOCK_BUS_AXI 13 #define STM32_CLOCK_BUS_MLAHB 14 +#define STM32_CLOCK_BUS_APB4_2 15 + +#define STM32_CLOCK_DIV_SHIFT 12 + +/** Clock divider */ +#define STM32_CLOCK_DIV(div) (((div) - 1) << STM32_CLOCK_DIV_SHIFT) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32_common_clocks.h b/include/zephyr/dt-bindings/clock/stm32_common_clocks.h index 3aece1bb77573..5992fee999b80 100644 --- a/include/zephyr/dt-bindings/clock/stm32_common_clocks.h +++ b/include/zephyr/dt-bindings/clock/stm32_common_clocks.h @@ -15,35 +15,39 @@ /** Dummy: Add a specifier when no selection is possible */ #define NO_SEL 0xFF -/** STM32 MCO configuration values */ -#define STM32_MCO_CFGR_REG_MASK 0xFFFFU -#define STM32_MCO_CFGR_REG_SHIFT 0U -#define STM32_MCO_CFGR_SHIFT_MASK 0x3FU -#define STM32_MCO_CFGR_SHIFT_SHIFT 16U -#define STM32_MCO_CFGR_MASK_MASK 0x1FU -#define STM32_MCO_CFGR_MASK_SHIFT 22U -#define STM32_MCO_CFGR_VAL_MASK 0x1FU -#define STM32_MCO_CFGR_VAL_SHIFT 27U +#define STM32_CLOCK_DIV_SHIFT 12 + +/** Clock divider */ +#define STM32_CLOCK_DIV(div) (((div) - 1) << STM32_CLOCK_DIV_SHIFT) + +/** Helper macros to pack RCC clock source selection register info in the DT */ +#define STM32_DT_CLKSEL_REG_MASK 0xFFFFU +#define STM32_DT_CLKSEL_REG_SHIFT 0U +#define STM32_DT_CLKSEL_SHIFT_MASK 0x3FU +#define STM32_DT_CLKSEL_SHIFT_SHIFT 16U +#define STM32_DT_CLKSEL_MASK_MASK 0x1FU +#define STM32_DT_CLKSEL_MASK_SHIFT 22U +#define STM32_DT_CLKSEL_VAL_MASK 0x1FU +#define STM32_DT_CLKSEL_VAL_SHIFT 27U /** - * @brief STM32 MCO configuration register bit field + * @brief Pack STM32 source clock selection RCC register bit fields for the DT * - * @param reg Offset to RCC register holding MCO configuration - * @param shift Position of field within RCC register (= field LSB's index) - * @param mask Mask of register field in RCC register - * @param val Clock configuration field value (0~0x1F) + * @param val Clock configuration field value + * @param mask Mask of register field in RCC register + * @param shift Position of field within RCC register (= field LSB's index) + * @param reg Offset to target clock configuration register in RCC * - * @note 'reg' range: 0x0~0xFFFF [ 00 : 15 ] - * @note 'shift' range: 0~63 [ 16 : 21 ] - * @note 'mask' range: 0x00~0x1F [ 22 : 26 ] + * @note 'reg' range: 0x0~0xFFFF [ 00 : 15 ] + * @note 'shift' range: 0~63 [ 16 : 21 ] + * @note 'mask' range: 0x00~0x1F [ 22 : 26 ] * @note 'val' range: 0x00~0x1F [ 27 : 31 ] - * */ -#define STM32_MCO_CFGR(val, mask, shift, reg) \ - ((((reg) & STM32_MCO_CFGR_REG_MASK) << STM32_MCO_CFGR_REG_SHIFT) | \ - (((shift) & STM32_MCO_CFGR_SHIFT_MASK) << STM32_MCO_CFGR_SHIFT_SHIFT) | \ - (((mask) & STM32_MCO_CFGR_MASK_MASK) << STM32_MCO_CFGR_MASK_SHIFT) | \ - (((val) & STM32_MCO_CFGR_VAL_MASK) << STM32_MCO_CFGR_VAL_SHIFT)) +#define STM32_DT_CLOCK_SELECT(val, mask, shift, reg) \ + ((((reg) & STM32_DT_CLKSEL_REG_MASK) << STM32_DT_CLKSEL_REG_SHIFT) | \ + (((shift) & STM32_DT_CLKSEL_SHIFT_MASK) << STM32_DT_CLKSEL_SHIFT_SHIFT) | \ + (((mask) & STM32_DT_CLKSEL_MASK_MASK) << STM32_DT_CLKSEL_MASK_SHIFT) | \ + (((val) & STM32_DT_CLKSEL_VAL_MASK) << STM32_DT_CLKSEL_VAL_SHIFT)) /** * Pack RCC clock register offset and bit in two 32-bit values diff --git a/include/zephyr/dt-bindings/clock/stm32c0_clock.h b/include/zephyr/dt-bindings/clock/stm32c0_clock.h index 70438d62b6d5e..00b5078ac163d 100644 --- a/include/zephyr/dt-bindings/clock/stm32c0_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32c0_clock.h @@ -24,39 +24,11 @@ /* defined in stm32_common_clocks.h */ /** Fixed clocks */ /* Low speed clocks defined in stm32_common_clocks.h */ -#define STM32_SRC_HSI48 (STM32_SRC_LSI + 1) -#define STM32_SRC_HSE (STM32_SRC_HSI48 + 1) +#define STM32_SRC_HSI (STM32_SRC_LSI + 1) +#define STM32_SRC_HSE (STM32_SRC_HSI + 1) /** Peripheral bus clock */ #define STM32_SRC_PCLK (STM32_SRC_HSE + 1) -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPR register offset */ #define CCIPR_REG 0x54 @@ -68,17 +40,27 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR_REG) -#define I2C2_I2S1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 14, CCIPR_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 30, CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR_REG) +#define I2C2_I2S1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, CCIPR_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 30, CCIPR_REG) /** CSR1 devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CSR1_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CSR1_REG) /** CFGR1 devices */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0x7, 24, CFGR1_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0x7, 28, CFGR1_REG) -#define MCO2_SEL(val) STM32_MCO_CFGR(val, 0x7, 16, CFGR1_REG) -#define MCO2_PRE(val) STM32_MCO_CFGR(val, 0x7, 20, CFGR1_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x7, 24, CFGR1_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 28, CFGR1_REG) +#define MCO2_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x7, 16, CFGR1_REG) +#define MCO2_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 20, CFGR1_REG) + +/* MCO prescaler : division factor */ +#define MCO_PRE_DIV_1 0 +#define MCO_PRE_DIV_2 1 +#define MCO_PRE_DIV_4 2 +#define MCO_PRE_DIV_8 3 +#define MCO_PRE_DIV_16 4 +#define MCO_PRE_DIV_32 5 +#define MCO_PRE_DIV_64 6 +#define MCO_PRE_DIV_128 7 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32C0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f0_clock.h b/include/zephyr/dt-bindings/clock/stm32f0_clock.h index 7572c1c422f1c..56b87128e7128 100644 --- a/include/zephyr/dt-bindings/clock/stm32f0_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f0_clock.h @@ -30,34 +30,6 @@ /** PLL clock */ #define STM32_SRC_PLLCLK (STM32_SRC_PCLK + 1) -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CFGRx register offset - * @param shift Position within RCC_CFGRx. - * @param mask Mask for the RCC_CFGRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CFGRx register offset */ #define CFGR1_REG 0x04 #define CFGR3_REG 0x30 @@ -67,17 +39,17 @@ /** @brief Device domain clocks selection helpers */ /** CFGR3 devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CFGR3_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 4, CFGR3_REG) -#define CEC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 6, CFGR3_REG) -#define USB_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 7, CFGR3_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CFGR3_REG) -#define USART3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CFGR3_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CFGR3_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 4, CFGR3_REG) +#define CEC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 6, CFGR3_REG) +#define USB_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 7, CFGR3_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CFGR3_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CFGR3_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** CFGR1 devices */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0xF, 24, CFGR1_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0x7, 28, CFGR1_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0xF, 24, CFGR1_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 28, CFGR1_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f10x_clock.h b/include/zephyr/dt-bindings/clock/stm32f10x_clock.h index 3570327cb9f08..7fe9948521961 100644 --- a/include/zephyr/dt-bindings/clock/stm32f10x_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f10x_clock.h @@ -16,11 +16,10 @@ /* Common clocks with stm32f1x defined in stm32f1_clock.h */ #define STM32_SRC_PLL2CLK (STM32_SRC_PLLCLK + 1) #define STM32_SRC_PLL3CLK (STM32_SRC_PLL2CLK + 1) -#define STM32_SRC_EXT_HSE (STM32_SRC_PLL3CLK + 1) /** CFGR1 devices */ #undef MCO1_SEL /* Need to redefine generic F1 MCO_SEL for connectivity line devices. */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0xF, 24, CFGR1_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0xF, 24, CFGR1_REG) /* No MCO prescaler support on STM32F1 series. */ #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F10X_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f1_clock.h b/include/zephyr/dt-bindings/clock/stm32f1_clock.h index a7e16ba2f7970..83f1a0f748ed3 100644 --- a/include/zephyr/dt-bindings/clock/stm32f1_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f1_clock.h @@ -25,35 +25,8 @@ /* Low speed clocks defined in stm32_common_clocks.h */ #define STM32_SRC_HSI (STM32_SRC_LSI + 1) #define STM32_SRC_HSE (STM32_SRC_HSI + 1) -#define STM32_SRC_PLLCLK (STM32_SRC_HSE + 1) - -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CFGRx register offset - * @param shift Position within RCC_CFGRx. - * @param mask Mask for the RCC_CFGRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) +#define STM32_SRC_EXT_HSE (STM32_SRC_HSE + 1) +#define STM32_SRC_PLLCLK (STM32_SRC_EXT_HSE + 1) /** @brief RCC_CFGRx register offset */ #define CFGR1_REG 0x04 @@ -64,13 +37,13 @@ /** @brief Device domain clocks selection helpers */ /** CFGR2 devices */ -#define I2S2_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 17, CFGR2_REG) -#define I2S3_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 18, CFGR2_REG) +#define I2S2_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 17, CFGR2_REG) +#define I2S3_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 18, CFGR2_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** CFGR1 devices */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0x7, 24, CFGR1_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x7, 24, CFGR1_REG) /* No MCO prescaler support on STM32F1 series. */ #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F1_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f3_clock.h b/include/zephyr/dt-bindings/clock/stm32f3_clock.h index c00d1dd59c38a..4617d6727c24f 100644 --- a/include/zephyr/dt-bindings/clock/stm32f3_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f3_clock.h @@ -31,34 +31,6 @@ /** PLL clock */ #define STM32_SRC_PLLCLK (STM32_SRC_PCLK + 1) -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CFGRx register offset - * @param shift Position within RCC_CFGRx. - * @param mask Mask for the RCC_CFGRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CFGRx register offset */ #define CFGR_REG 0x04 #define CFGR3_REG 0x30 @@ -68,27 +40,27 @@ /** @brief Device domain clocks selection helpers) */ /** CFGR devices */ -#define I2S_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 23, CFGR_REG) -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0x7, 24, CFGR_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0x7, 28, CFGR_REG) +#define I2S_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 23, CFGR_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x7, 24, CFGR_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 28, CFGR_REG) /** CFGR3 devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CFGR3_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 4, CFGR3_REG) -#define I2C2_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 5, CFGR3_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 6, CFGR3_REG) -#define TIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 8, CFGR3_REG) -#define TIM8_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 9, CFGR3_REG) -#define TIM15_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 10, CFGR3_REG) -#define TIM16_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 11, CFGR3_REG) -#define TIM17_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 13, CFGR3_REG) -#define TIM20_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 15, CFGR3_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CFGR3_REG) -#define USART3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CFGR3_REG) -#define USART4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CFGR3_REG) -#define USART5_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CFGR3_REG) -#define TIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 24, CFGR3_REG) -#define TIM3_4_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 25, CFGR3_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CFGR3_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 4, CFGR3_REG) +#define I2C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 5, CFGR3_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 6, CFGR3_REG) +#define TIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 8, CFGR3_REG) +#define TIM8_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 9, CFGR3_REG) +#define TIM15_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 10, CFGR3_REG) +#define TIM16_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 11, CFGR3_REG) +#define TIM17_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 13, CFGR3_REG) +#define TIM20_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 15, CFGR3_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CFGR3_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CFGR3_REG) +#define USART4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CFGR3_REG) +#define USART5_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CFGR3_REG) +#define TIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 24, CFGR3_REG) +#define TIM3_4_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 25, CFGR3_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F3_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f410_clock.h b/include/zephyr/dt-bindings/clock/stm32f410_clock.h index fffd47321f6e8..eb7a39c3fb7c3 100644 --- a/include/zephyr/dt-bindings/clock/stm32f410_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f410_clock.h @@ -6,25 +6,27 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F410_CLOCK_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F410_CLOCK_H_ +#include "stm32f4_clock.h" + /** @brief RCC_DCKCFGR register offset */ #define DCKCFGR_REG 0x8C #define DCKCFGR2_REG 0x94 /** @brief Device domain clocks selection helpers */ /** DCKCFGR devices */ -#define CKDFSDM2A_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 14, DCKCFGR_REG) -#define CKDFSDM1A_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 15, DCKCFGR_REG) -#define SAI1A_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, DCKCFGR_REG) -#define SAI1B_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, DCKCFGR_REG) -#define I2S1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 25, DCKCFGR_REG) -#define I2S2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 27, DCKCFGR_REG) -#define CKDFSDM_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 31, DCKCFGR_REG) +#define CKDFSDM2A_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 14, DCKCFGR_REG) +#define CKDFSDM1A_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 15, DCKCFGR_REG) +#define SAI1A_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, DCKCFGR_REG) +#define SAI1B_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, DCKCFGR_REG) +#define I2S1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 25, DCKCFGR_REG) +#define I2S2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 27, DCKCFGR_REG) +#define CKDFSDM_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 31, DCKCFGR_REG) /** DCKCFGR2 devices */ -#define I2CFMP1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, DCKCFGR2_REG) -#define CK48M_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 27, DCKCFGR2_REG) -#define SDIO_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 28, DCKCFGR2_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 30, DCKCFGR2_REG) +#define I2CFMP1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, DCKCFGR2_REG) +#define CK48M_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 27, DCKCFGR2_REG) +#define SDIO_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 28, DCKCFGR2_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 30, DCKCFGR2_REG) /* F4 generic I2S_SEL is not compatible with F410 devices */ #ifdef I2S_SEL diff --git a/include/zephyr/dt-bindings/clock/stm32f427_clock.h b/include/zephyr/dt-bindings/clock/stm32f427_clock.h index 97d22836be512..4fb2f72325f6f 100644 --- a/include/zephyr/dt-bindings/clock/stm32f427_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f427_clock.h @@ -6,17 +6,19 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F427_CLOCK_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F427_CLOCK_H_ +#include "stm32f4_clock.h" + /** @brief RCC_DCKCFGR register offset */ #define DCKCFGR_REG 0x8C /** @brief Device domain clocks selection helpers */ /** DCKCFGR devices */ -#define CKDFSDM2A_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 14, DCKCFGR_REG) -#define CKDFSDM1A_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 15, DCKCFGR_REG) -#define SAI1A_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, DCKCFGR_REG) -#define SAI1B_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, DCKCFGR_REG) -#define CLK48M_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 27, DCKCFGR_REG) -#define SDMMC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 28, DCKCFGR_REG) -#define DSI_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 29, DCKCFGR_REG) +#define CKDFSDM2A_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 14, DCKCFGR_REG) +#define CKDFSDM1A_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 15, DCKCFGR_REG) +#define SAI1A_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, DCKCFGR_REG) +#define SAI1B_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, DCKCFGR_REG) +#define CLK48M_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 27, DCKCFGR_REG) +#define SDMMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 28, DCKCFGR_REG) +#define DSI_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 29, DCKCFGR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F427_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f4_clock.h b/include/zephyr/dt-bindings/clock/stm32f4_clock.h index 18356856ef242..98e635c4a2bc6 100644 --- a/include/zephyr/dt-bindings/clock/stm32f4_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f4_clock.h @@ -28,45 +28,21 @@ /* defined in stm32_common_clocks.h */ /** Fixed clocks */ /* Low speed clocks defined in stm32_common_clocks.h */ -#define STM32_SRC_HSI (STM32_SRC_LSI + 1) -#define STM32_SRC_HSE (STM32_SRC_HSI + 1) +#define STM32_SRC_HSI (STM32_SRC_LSI + 1) +#define STM32_SRC_HSE (STM32_SRC_HSI + 1) /** PLL clock outputs */ -#define STM32_SRC_PLL_P (STM32_SRC_HSE + 1) -#define STM32_SRC_PLL_Q (STM32_SRC_PLL_P + 1) -#define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) +#define STM32_SRC_PLL_P (STM32_SRC_HSE + 1) +#define STM32_SRC_PLL_Q (STM32_SRC_PLL_P + 1) +#define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) /** I2S sources */ -#define STM32_SRC_PLLI2S_R (STM32_SRC_PLL_R + 1) +#define STM32_SRC_PLLI2S_Q (STM32_SRC_PLL_R + 1) +#define STM32_SRC_PLLI2S_R (STM32_SRC_PLLI2S_Q + 1) +/* CLK48MHz sources */ +#define STM32_SRC_CK48 (STM32_SRC_PLLI2S_R + 1) + /* I2S_CKIN not supported yet */ /* #define STM32_SRC_I2S_CKIN TBD */ -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CFGRx register offset - * @param shift Position within RCC_CFGRx. - * @param mask Mask for the RCC_CFGRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CFGRx register offset */ #define CFGR_REG 0x08 /** @brief RCC_BDCR register offset */ @@ -74,12 +50,19 @@ /** @brief Device domain clocks selection helpers */ /** CFGR devices */ -#define I2S_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 23, CFGR_REG) -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0x3, 21, CFGR_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0x7, 24, CFGR_REG) -#define MCO2_SEL(val) STM32_MCO_CFGR(val, 0x3, 30, CFGR_REG) -#define MCO2_PRE(val) STM32_MCO_CFGR(val, 0x7, 27, CFGR_REG) +#define I2S_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 23, CFGR_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x3, 21, CFGR_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 24, CFGR_REG) +#define MCO2_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x3, 30, CFGR_REG) +#define MCO2_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 27, CFGR_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) + +/* MCO prescaler : division factor */ +#define MCO_PRE_DIV_1 0 +#define MCO_PRE_DIV_2 4 +#define MCO_PRE_DIV_3 5 +#define MCO_PRE_DIV_4 6 +#define MCO_PRE_DIV_5 7 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F4_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32f7_clock.h b/include/zephyr/dt-bindings/clock/stm32f7_clock.h index 11fbd10308a9e..4bfcfdf738647 100644 --- a/include/zephyr/dt-bindings/clock/stm32f7_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f7_clock.h @@ -40,35 +40,6 @@ #define STM32_SRC_PLLI2S_R (STM32_SRC_PCLK + 1) - -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CFGRx register offset - * @param shift Position within RCC_CFGRx. - * @param mask Mask for the RCC_CFGRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CFGRx register offset */ #define CFGR_REG 0x08 @@ -77,13 +48,21 @@ /** @brief Device domain clocks selection helpers */ /** CFGR devices */ -#define I2S_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 23, CFGR_REG) -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0x3, 21, CFGR_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0x7, 24, CFGR_REG) -#define MCO2_SEL(val) STM32_MCO_CFGR(val, 0x3, 30, CFGR_REG) -#define MCO2_PRE(val) STM32_MCO_CFGR(val, 0x7, 27, CFGR_REG) +#define I2S_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 23, CFGR_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x3, 21, CFGR_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 24, CFGR_REG) +#define MCO2_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x3, 30, CFGR_REG) +#define MCO2_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 27, CFGR_REG) + +/* MCO prescaler : division factor */ +#define MCO_PRE_DIV_1 0 +#define MCO_PRE_DIV_2 4 +#define MCO_PRE_DIV_3 5 +#define MCO_PRE_DIV_4 6 +#define MCO_PRE_DIV_5 7 + /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** @brief RCC_DKCFGR register offset */ #define DCKCFGR1_REG 0x8C @@ -91,23 +70,23 @@ /** @brief Dedicated clocks configuration register selection helpers */ /** DKCFGR2 devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, DCKCFGR2_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, DCKCFGR2_REG) -#define USART3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, DCKCFGR2_REG) -#define USART4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, DCKCFGR2_REG) -#define USART5_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, DCKCFGR2_REG) -#define USART6_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, DCKCFGR2_REG) -#define USART7_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, DCKCFGR2_REG) -#define USART8_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 14, DCKCFGR2_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, DCKCFGR2_REG) -#define I2C2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, DCKCFGR2_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, DCKCFGR2_REG) -#define I2C4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, DCKCFGR2_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 24, DCKCFGR2_REG) -#define CEC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 26, DCKCFGR2_REG) -#define CK48M_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 27, DCKCFGR2_REG) -#define SDMMC1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 28, DCKCFGR2_REG) -#define SDMMC2_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 29, DCKCFGR2_REG) -#define DSI_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 30, DCKCFGR2_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, DCKCFGR2_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, DCKCFGR2_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, DCKCFGR2_REG) +#define USART4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, DCKCFGR2_REG) +#define USART5_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, DCKCFGR2_REG) +#define USART6_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, DCKCFGR2_REG) +#define USART7_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, DCKCFGR2_REG) +#define USART8_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, DCKCFGR2_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, DCKCFGR2_REG) +#define I2C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, DCKCFGR2_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, DCKCFGR2_REG) +#define I2C4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, DCKCFGR2_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 24, DCKCFGR2_REG) +#define CEC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 26, DCKCFGR2_REG) +#define CK48M_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 27, DCKCFGR2_REG) +#define SDMMC1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 28, DCKCFGR2_REG) +#define SDMMC2_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 29, DCKCFGR2_REG) +#define DSI_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 30, DCKCFGR2_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32F7_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32g0_clock.h b/include/zephyr/dt-bindings/clock/stm32g0_clock.h index b7d7714b1b15b..944f3c022efb1 100644 --- a/include/zephyr/dt-bindings/clock/stm32g0_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32g0_clock.h @@ -35,34 +35,6 @@ #define STM32_SRC_PLL_Q (STM32_SRC_PLL_P + 1) #define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPR register offset */ #define CCIPR_REG 0x54 #define CCIPR2_REG 0x58 @@ -72,26 +44,26 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR_REG) -#define USART3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, CCIPR_REG) -#define CEC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 6, CCIPR_REG) -#define LPUART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR_REG) -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR_REG) -#define I2C2_I2S1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 14, CCIPR_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR_REG) -#define TIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 22, CCIPR_REG) -#define TIM15_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 24, CCIPR_REG) -#define RNG_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 26, CCIPR_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 30, CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR_REG) +#define CEC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 6, CCIPR_REG) +#define LPUART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR_REG) +#define I2C2_I2S1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR_REG) +#define TIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 22, CCIPR_REG) +#define TIM15_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 24, CCIPR_REG) +#define RNG_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 26, CCIPR_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 30, CCIPR_REG) /** CCIPR2 devices */ -#define I2S1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR2_REG) -#define I2S2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR2_REG) -#define FDCAN_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR2_REG) -#define USB_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR2_REG) +#define I2S1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR2_REG) +#define I2S2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR2_REG) +#define FDCAN_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR2_REG) +#define USB_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR2_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32G0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32g4_clock.h b/include/zephyr/dt-bindings/clock/stm32g4_clock.h index a7d928c801f49..f66d0313a33ca 100644 --- a/include/zephyr/dt-bindings/clock/stm32g4_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32g4_clock.h @@ -39,34 +39,6 @@ #define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) /* TODO: PLLSAI clocks */ -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPR register offset */ #define CCIPR_REG 0x88 #define CCIPR2_REG 0x9C @@ -76,26 +48,26 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR_REG) -#define USART3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, CCIPR_REG) -#define USART4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, CCIPR_REG) -#define USART5_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR_REG) -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR_REG) -#define I2C2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 14, CCIPR_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CCIPR_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR_REG) -#define SAI1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR_REG) -#define I2S23_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR_REG) -#define FDCAN_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 24, CCIPR_REG) -#define CLK48_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 26, CCIPR_REG) -#define ADC12_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 28, CCIPR_REG) -#define ADC34_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 30, CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR_REG) +#define USART4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, CCIPR_REG) +#define USART5_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR_REG) +#define I2C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, CCIPR_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR_REG) +#define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR_REG) +#define I2S23_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR_REG) +#define FDCAN_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 24, CCIPR_REG) +#define CLK48_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 26, CCIPR_REG) +#define ADC12_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, CCIPR_REG) +#define ADC34_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 30, CCIPR_REG) /** CCIPR2 devices */ -#define I2C4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR2_REG) -#define QSPI_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR2_REG) +#define I2C4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR2_REG) +#define QSPI_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR2_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32G4_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32h5_clock.h b/include/zephyr/dt-bindings/clock/stm32h5_clock.h index 0fb5d9166aa39..f3ed8289ea73c 100644 --- a/include/zephyr/dt-bindings/clock/stm32h5_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32h5_clock.h @@ -51,34 +51,6 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB3 -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32H5 clock configuration bit field. - * - * - reg (1/2/3/4/5) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPRx register offset (RM0456.pdf) */ #define CCIPR1_REG 0xD8 #define CCIPR2_REG 0xDC @@ -94,66 +66,83 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR1 devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, CCIPR1_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 3, CCIPR1_REG) -#define USART3_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 6, CCIPR1_REG) -#define USART4_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 9, CCIPR1_REG) -#define USART5_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 12, CCIPR1_REG) -#define USART6_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 15, CCIPR1_REG) -#define USART7_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 18, CCIPR1_REG) -#define USART8_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 21, CCIPR1_REG) -#define USART9_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 24, CCIPR1_REG) -#define USART10_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 27, CCIPR1_REG) -#define TIMIC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 31, CCIPR1_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR1_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 3, CCIPR1_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 6, CCIPR1_REG) +#define USART4_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 9, CCIPR1_REG) +#define USART5_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR1_REG) +#define USART6_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 15, CCIPR1_REG) +#define USART7_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 18, CCIPR1_REG) +#define USART8_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 21, CCIPR1_REG) +#define USART9_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 24, CCIPR1_REG) +#define USART10_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 27, CCIPR1_REG) +#define TIMIC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 31, CCIPR1_REG) /** CCIPR2 devices */ -#define USART11_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, CCIPR2_REG) -#define USART12_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 4, CCIPR2_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 8, CCIPR2_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 12, CCIPR2_REG) -#define LPTIM3_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 16, CCIPR2_REG) -#define LPTIM4_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 20, CCIPR2_REG) -#define LPTIM5_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 24, CCIPR2_REG) -#define LPTIM6_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 28, CCIPR2_REG) +#define USART11_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR2_REG) +#define USART12_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, CCIPR2_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR2_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR2_REG) +#define LPTIM3_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR2_REG) +#define LPTIM4_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 20, CCIPR2_REG) +#define LPTIM5_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 24, CCIPR2_REG) +#define LPTIM6_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 28, CCIPR2_REG) /** CCIPR3 devices */ -#define SPI1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, CCIPR3_REG) -#define SPI2_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 3, CCIPR3_REG) -#define SPI3_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 6, CCIPR3_REG) -#define SPI4_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 9, CCIPR3_REG) -#define SPI5_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 12, CCIPR3_REG) -#define SPI6_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 15, CCIPR2_REG) -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 24, CCIPR3_REG) +#define SPI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR3_REG) +#define SPI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 3, CCIPR3_REG) +#define SPI3_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 6, CCIPR3_REG) +#define SPI4_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 9, CCIPR3_REG) +#define SPI5_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR3_REG) +#define SPI6_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 15, CCIPR2_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 24, CCIPR3_REG) /** CCIPR4 devices */ -#define OCTOSPI1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR4_REG) -#define SYSTICK_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR4_REG) -#define USB_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, CCIPR4_REG) -#define SDMMC1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 6, CCIPR4_REG) -#define SDMMC2_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 7, CCIPR4_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CCIPR4_REG) -#define I2C2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR4_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR4_REG) -#define I2C4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR4_REG) -#define I3C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 24, CCIPR4_REG) +#define OCTOSPI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR4_REG) +#define SYSTICK_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR4_REG) +#define USB_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR4_REG) +#define SDMMC1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 6, CCIPR4_REG) +#define SDMMC2_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 7, CCIPR4_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CCIPR4_REG) +#define I2C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR4_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR4_REG) +#define I2C4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR4_REG) +#define I3C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 24, CCIPR4_REG) /** CCIPR5 devices */ -#define ADCDAC_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, CCIPR5_REG) -#define DAC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 3, CCIPR5_REG) -#define RNG_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, CCIPR5_REG) -#define CEC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, CCIPR5_REG) -#define FDCAN_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR5_REG) -#define SAI1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 16, CCIPR5_REG) -#define SAI2_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 19, CCIPR5_REG) -#define CKPER_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 30, CCIPR5_REG) +#define ADCDAC_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR5_REG) +#define DAC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 3, CCIPR5_REG) +#define RNG_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR5_REG) +#define CEC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, CCIPR5_REG) +#define FDCAN_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR5_REG) +#define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR5_REG) +#define SAI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 19, CCIPR5_REG) +#define CKPER_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 30, CCIPR5_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** CFGR1 devices */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0x7, 22, CFGR1_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0xF, 18, CFGR1_REG) -#define MCO2_SEL(val) STM32_MCO_CFGR(val, 0x7, 25, CFGR1_REG) -#define MCO2_PRE(val) STM32_MCO_CFGR(val, 0xF, 29, CFGR1_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x7, 22, CFGR1_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0xF, 18, CFGR1_REG) +#define MCO2_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x7, 25, CFGR1_REG) +#define MCO2_PRE(val) STM32_DT_CLOCK_SELECT((val), 0xF, 29, CFGR1_REG) + +/* MCO prescaler : division factor */ +#define MCO_PRE_DIV_1 1 +#define MCO_PRE_DIV_2 2 +#define MCO_PRE_DIV_3 3 +#define MCO_PRE_DIV_4 4 +#define MCO_PRE_DIV_5 5 +#define MCO_PRE_DIV_6 6 +#define MCO_PRE_DIV_7 7 +#define MCO_PRE_DIV_8 8 +#define MCO_PRE_DIV_9 9 +#define MCO_PRE_DIV_10 10 +#define MCO_PRE_DIV_11 11 +#define MCO_PRE_DIV_12 12 +#define MCO_PRE_DIV_13 13 +#define MCO_PRE_DIV_14 14 +#define MCO_PRE_DIV_15 15 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H5_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32h7_clock.h b/include/zephyr/dt-bindings/clock/stm32h7_clock.h index b844612edd4cc..aec5ffc33b91e 100644 --- a/include/zephyr/dt-bindings/clock/stm32h7_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32h7_clock.h @@ -58,34 +58,6 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB3 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB4 -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32H7 clock configuration bit field. - * - * - reg (0/1) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..3) [ 16 : 18 ] - * - * @param reg RCC_DxCCIP register offset - * @param shift Position within RCC_DxCCIP. - * @param mask Mask for the RCC_DxCCIP field. - * @param val Clock value (0, 1, 2 or 3). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_DxCCIP register offset (RM0399.pdf) */ #define D1CCIPR_REG 0x4C #define D2CCIP1R_REG 0x50 @@ -100,45 +72,62 @@ /** @brief Device domain clocks selection helpers (RM0399.pdf) */ /** D1CCIPR devices */ -#define FMC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, D1CCIPR_REG) -#define QSPI_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, D1CCIPR_REG) -#define DSI_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 8, D1CCIPR_REG) -#define SDMMC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 16, D1CCIPR_REG) -#define CKPER_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 28, D1CCIPR_REG) +#define FMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, D1CCIPR_REG) +#define QSPI_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, D1CCIPR_REG) +#define DSI_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 8, D1CCIPR_REG) +#define SDMMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 16, D1CCIPR_REG) +#define CKPER_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, D1CCIPR_REG) /* Device domain clocks selection helpers (RM0468.pdf) */ -#define OSPI_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, D1CCIPR_REG) +#define OSPI_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, D1CCIPR_REG) /** D2CCIP1R devices */ -#define SAI1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, D2CCIP1R_REG) -#define SAI23_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 6, D2CCIP1R_REG) -#define SPI123_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 12, D2CCIP1R_REG) -#define SPI45_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 16, D2CCIP1R_REG) -#define SPDIF_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, D2CCIP1R_REG) -#define DFSDM1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 24, D2CCIP1R_REG) -#define FDCAN_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 28, D2CCIP1R_REG) -#define SWP_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 31, D2CCIP1R_REG) +#define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, D2CCIP1R_REG) +#define SAI23_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 6, D2CCIP1R_REG) +#define SPI123_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, D2CCIP1R_REG) +#define SPI45_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, D2CCIP1R_REG) +#define SPDIF_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, D2CCIP1R_REG) +#define DFSDM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 24, D2CCIP1R_REG) +#define FDCAN_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, D2CCIP1R_REG) +#define SWP_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 31, D2CCIP1R_REG) /** D2CCIP2R devices */ -#define USART2345678_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, D2CCIP2R_REG) -#define USART16_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 3, D2CCIP2R_REG) -#define RNG_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, D2CCIP2R_REG) -#define I2C123_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, D2CCIP2R_REG) -#define USB_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, D2CCIP2R_REG) -#define CEC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, D2CCIP2R_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 28, D2CCIP2R_REG) +#define USART2345678_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, D2CCIP2R_REG) +#define USART16_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 3, D2CCIP2R_REG) +#define RNG_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, D2CCIP2R_REG) +#define I2C123_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, D2CCIP2R_REG) +#define USB_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, D2CCIP2R_REG) +#define CEC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, D2CCIP2R_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 28, D2CCIP2R_REG) /** D3CCIPR devices */ -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, D3CCIPR_REG) -#define I2C4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, D3CCIPR_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 10, D3CCIPR_REG) -#define LPTIM345_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 13, D3CCIPR_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, D3CCIPR_REG) -#define SAI4A_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 21, D3CCIPR_REG) -#define SAI4B_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 24, D3CCIPR_REG) -#define SPI6_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 28, D3CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, D3CCIPR_REG) +#define I2C4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, D3CCIPR_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 10, D3CCIPR_REG) +#define LPTIM345_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 13, D3CCIPR_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, D3CCIPR_REG) +#define SAI4A_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 21, D3CCIPR_REG) +#define SAI4B_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 24, D3CCIPR_REG) +#define SPI6_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 28, D3CCIPR_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** CFGR devices */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0xF, 22, CFGR_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0x7, 18, CFGR_REG) -#define MCO2_SEL(val) STM32_MCO_CFGR(val, 0xF, 29, CFGR_REG) -#define MCO2_PRE(val) STM32_MCO_CFGR(val, 0x7, 25, CFGR_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0xF, 22, CFGR_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 18, CFGR_REG) +#define MCO2_SEL(val) STM32_DT_CLOCK_SELECT((val), 0xF, 29, CFGR_REG) +#define MCO2_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 25, CFGR_REG) + +/* MCO prescaler : division factor */ +#define MCO_PRE_DIV_1 1 +#define MCO_PRE_DIV_2 2 +#define MCO_PRE_DIV_3 3 +#define MCO_PRE_DIV_4 4 +#define MCO_PRE_DIV_5 5 +#define MCO_PRE_DIV_6 6 +#define MCO_PRE_DIV_7 7 +#define MCO_PRE_DIV_8 8 +#define MCO_PRE_DIV_9 9 +#define MCO_PRE_DIV_10 10 +#define MCO_PRE_DIV_11 11 +#define MCO_PRE_DIV_12 12 +#define MCO_PRE_DIV_13 13 +#define MCO_PRE_DIV_14 14 +#define MCO_PRE_DIV_15 15 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h b/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h index 38f7d1734d31b..d7943dbe73bca 100644 --- a/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h @@ -54,34 +54,6 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB5 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_AHB3 -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32H7RS clock configuration bit field. - * - * - reg (0/1) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..3) [ 16 : 18 ] - * - * @param reg RCC_DxCCIP register offset - * @param shift Position within RCC_DxCCIP. - * @param mask Mask for the RCC_DxCCIP field. - * @param val Clock value (0, 1, 2 or 3). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_DxCCIP register offset (RM0477.pdf) */ #define D1CCIPR_REG 0x4C #define D2CCIPR_REG 0x50 @@ -99,42 +71,60 @@ /* TODO to be completed */ /** D1CCIPR devices */ -#define FMC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, D1CCIPR_REG) -#define SDMMC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 2, D1CCIPR_REG) -#define XSPI1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, D1CCIPR_REG) -#define XSPI2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, D1CCIPR_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 24, D1CCIPR_REG) -#define CKPER_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 28, D1CCIPR_REG) +#define FMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, D1CCIPR_REG) +#define SDMMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 2, D1CCIPR_REG) +#define XSPI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, D1CCIPR_REG) +#define XSPI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, D1CCIPR_REG) +#define OTGFS_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, D1CCIPR_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 24, D1CCIPR_REG) +#define CKPER_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, D1CCIPR_REG) /** D2CCIPR devices */ -#define USART234578_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, D2CCIPR_REG) -#define SPI23_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 4, D2CCIPR_REG) -#define I2C23_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, D2CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, D2CCIPR_REG) -#define I3C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, D2CCIPR_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 16, D2CCIPR_REG) -#define FDCAN_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, D2CCIPR_REG) +#define USART234578_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, D2CCIPR_REG) +#define SPI23_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, D2CCIPR_REG) +#define I2C23_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, D2CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, D2CCIPR_REG) +#define I3C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, D2CCIPR_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, D2CCIPR_REG) +#define FDCAN_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, D2CCIPR_REG) /** D3CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, D3CCIPR_REG) -#define SPI45_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 4, D3CCIPR_REG) -#define SPI1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 8, D3CCIPR_REG) -#define SAI1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 16, D3CCIPR_REG) -#define SAI2_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 20, D3CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, D3CCIPR_REG) +#define SPI45_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, D3CCIPR_REG) +#define SPI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, D3CCIPR_REG) +#define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, D3CCIPR_REG) +#define SAI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 20, D3CCIPR_REG) /** D4CCIPR devices */ -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, D4CCIPR_REG) -#define SPI6_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 4, D4CCIPR_REG) -#define LPTIM23_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 8, D4CCIPR_REG) -#define LPTIM45_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 12, D4CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, D4CCIPR_REG) +#define SPI6_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, D4CCIPR_REG) +#define LPTIM23_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, D4CCIPR_REG) +#define LPTIM45_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, D4CCIPR_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** CFGR devices */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0x7, 22, CFGR_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0xF, 18, CFGR_REG) -#define MCO2_SEL(val) STM32_MCO_CFGR(val, 0x7, 29, CFGR_REG) -#define MCO2_PRE(val) STM32_MCO_CFGR(val, 0xF, 25, CFGR_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x7, 22, CFGR_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0xF, 18, CFGR_REG) +#define MCO2_SEL(val) STM32_DT_CLOCK_SELECT((val), 0x7, 29, CFGR_REG) +#define MCO2_PRE(val) STM32_DT_CLOCK_SELECT((val), 0xF, 25, CFGR_REG) + +/* MCO prescaler : division factor */ +#define MCO_PRE_DIV_1 1 +#define MCO_PRE_DIV_2 2 +#define MCO_PRE_DIV_3 3 +#define MCO_PRE_DIV_4 4 +#define MCO_PRE_DIV_5 5 +#define MCO_PRE_DIV_6 6 +#define MCO_PRE_DIV_7 7 +#define MCO_PRE_DIV_8 8 +#define MCO_PRE_DIV_9 9 +#define MCO_PRE_DIV_10 10 +#define MCO_PRE_DIV_11 11 +#define MCO_PRE_DIV_12 12 +#define MCO_PRE_DIV_13 13 +#define MCO_PRE_DIV_14 14 +#define MCO_PRE_DIV_15 15 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32H7RS_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32l0_clock.h b/include/zephyr/dt-bindings/clock/stm32l0_clock.h index c16e367a94e32..44709e7996247 100644 --- a/include/zephyr/dt-bindings/clock/stm32l0_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32l0_clock.h @@ -31,34 +31,6 @@ /** Bus clock */ #define STM32_SRC_PCLK (STM32_SRC_HSI48 + 1) -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPR register offset */ #define CCIPR_REG 0x4C @@ -67,14 +39,14 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR_REG) -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CCIPR_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR_REG) -#define HSI48_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 26, CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR_REG) +#define HSI48_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 26, CCIPR_REG) /** CSR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CSR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CSR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32l1_clock.h b/include/zephyr/dt-bindings/clock/stm32l1_clock.h index f958f7b6bb8fa..9f94a18b8ff4a 100644 --- a/include/zephyr/dt-bindings/clock/stm32l1_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32l1_clock.h @@ -26,37 +26,9 @@ #define STM32_SRC_HSE (STM32_SRC_LSI + 1) #define STM32_SRC_HSI (STM32_SRC_HSE + 1) -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CSR register offset */ #define CSR_REG 0x34 -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CSR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CSR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L1_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32l4_clock.h b/include/zephyr/dt-bindings/clock/stm32l4_clock.h index 3e865f9a880e2..eabfffc9ed208 100644 --- a/include/zephyr/dt-bindings/clock/stm32l4_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32l4_clock.h @@ -37,34 +37,6 @@ #define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) /* TODO: PLLSAI clocks */ -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPR register offset */ #define CCIPR_REG 0x88 #define CCIPR2_REG 0x9C @@ -77,36 +49,36 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR_REG) -#define USART3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, CCIPR_REG) -#define UART4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, CCIPR_REG) -#define UART5_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR_REG) -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR_REG) -#define I2C2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 14, CCIPR_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CCIPR_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR_REG) -#define SAI1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR_REG) -#define SAI2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 24, CCIPR_REG) -#define CLK48_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 26, CCIPR_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 28, CCIPR_REG) -#define SWPMI1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 30, CCIPR_REG) -#define DFSDM1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 31, CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR_REG) +#define UART4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, CCIPR_REG) +#define UART5_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR_REG) +#define I2C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, CCIPR_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR_REG) +#define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR_REG) +#define SAI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 24, CCIPR_REG) +#define CLK48_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 26, CCIPR_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, CCIPR_REG) +#define SWPMI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 30, CCIPR_REG) +#define DFSDM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 31, CCIPR_REG) /** CCIPR2 devices */ -#define I2C4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR2_REG) -#define DFSDM_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 2, CCIPR2_REG) -#define ADFSDM_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 3, CCIPR2_REG) -/* #define SAI1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 5, CCIPR2_REG) */ -/* #define SAI2_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 8, CCIPR2_REG) */ -#define DSI_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 12, CCIPR2_REG) -#define SDMMC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 14, CCIPR2_REG) -#define OSPI_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR2_REG) +#define I2C4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR2_REG) +#define DFSDM_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 2, CCIPR2_REG) +#define ADFSDM_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 3, CCIPR2_REG) +/* #define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 5, CCIPR2_REG) */ +/* #define SAI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR2_REG) */ +#define DSI_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 12, CCIPR2_REG) +#define SDMMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 14, CCIPR2_REG) +#define OSPI_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR2_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** CFGR devices */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0xF, 24, CFGR_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0x7, 28, CFGR_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0xF, 24, CFGR_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 28, CFGR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32L4_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32n6_clock.h b/include/zephyr/dt-bindings/clock/stm32n6_clock.h new file mode 100644 index 0000000000000..f733752c2c410 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/stm32n6_clock.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32N6_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32N6_CLOCK_H_ + +#include "stm32_common_clocks.h" + +/** Domain clocks */ + +/* RM0468, Table 56 Kernel clock distribution summary */ + +/** System clock */ +/* defined in stm32_common_clocks.h */ +/** Fixed clocks */ +#define STM32_SRC_HSE (STM32_SRC_LSI + 1) +#define STM32_SRC_HSI (STM32_SRC_HSE + 1) +#define STM32_SRC_MSI (STM32_SRC_HSI + 1) +/** PLL outputs */ +#define STM32_SRC_PLL1 (STM32_SRC_MSI + 1) +#define STM32_SRC_PLL2 (STM32_SRC_PLL1 + 1) +#define STM32_SRC_PLL3 (STM32_SRC_PLL2 + 1) +#define STM32_SRC_PLL4 (STM32_SRC_PLL3 + 1) +/** Clock muxes */ +#define STM32_SRC_CKPER (STM32_SRC_PLL4 + 1) +#define STM32_SRC_IC1 (STM32_SRC_CKPER + 1) +#define STM32_SRC_IC2 (STM32_SRC_IC1 + 1) +#define STM32_SRC_IC3 (STM32_SRC_IC2 + 1) +#define STM32_SRC_IC4 (STM32_SRC_IC3 + 1) +#define STM32_SRC_IC5 (STM32_SRC_IC4 + 1) +#define STM32_SRC_IC6 (STM32_SRC_IC5 + 1) +#define STM32_SRC_IC7 (STM32_SRC_IC6 + 1) +#define STM32_SRC_IC8 (STM32_SRC_IC7 + 1) +#define STM32_SRC_IC9 (STM32_SRC_IC8 + 1) +#define STM32_SRC_IC10 (STM32_SRC_IC9 + 1) +#define STM32_SRC_IC11 (STM32_SRC_IC10 + 1) +#define STM32_SRC_IC12 (STM32_SRC_IC11 + 1) +#define STM32_SRC_IC13 (STM32_SRC_IC12 + 1) +#define STM32_SRC_IC14 (STM32_SRC_IC13 + 1) +#define STM32_SRC_IC15 (STM32_SRC_IC14 + 1) +#define STM32_SRC_IC16 (STM32_SRC_IC15 + 1) +#define STM32_SRC_IC17 (STM32_SRC_IC16 + 1) +#define STM32_SRC_IC18 (STM32_SRC_IC17 + 1) +#define STM32_SRC_IC19 (STM32_SRC_IC18 + 1) +#define STM32_SRC_IC20 (STM32_SRC_IC19 + 1) + +/** Bus clocks */ +#define STM32_CLOCK_BUS_AHB1 0x250 +#define STM32_CLOCK_BUS_AHB2 0x254 +#define STM32_CLOCK_BUS_AHB3 0x258 +#define STM32_CLOCK_BUS_AHB4 0x25C +#define STM32_CLOCK_BUS_AHB5 0x260 +#define STM32_CLOCK_BUS_APB1 0x264 +#define STM32_CLOCK_BUS_APB1_2 0x268 +#define STM32_CLOCK_BUS_APB2 0x26C +#define STM32_CLOCK_BUS_APB3 0x270 +#define STM32_CLOCK_BUS_APB4 0x274 +#define STM32_CLOCK_BUS_APB4_2 0x278 +#define STM32_CLOCK_BUS_APB5 0x27C + +#define STM32_CLOCK_LP_BUS_SHIFT 0x40 + +#define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 +#define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB5 + +/** @brief RCC_CCIPRx register offset (RM0468.pdf) */ +#define CCIPR1_REG 0x144 +#define CCIPR2_REG 0x148 +#define CCIPR3_REG 0x14C +#define CCIPR4_REG 0x150 +#define CCIPR5_REG 0x154 +#define CCIPR6_REG 0x158 +#define CCIPR7_REG 0x15C +#define CCIPR8_REG 0x160 +#define CCIPR9_REG 0x164 +#define CCIPR12_REG 0x170 +#define CCIPR13_REG 0x174 +#define CCIPR14_REG 0x178 + +/** @brief Device domain clocks selection helpers */ +/** CCIPR1 devices */ +#define ADF1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR1_REG) +#define ADC12_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, CCIPR1_REG) +#define DCMIPP_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR1_REG) +/** CCIPR2 devices */ +#define ETH1PTP_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR2_REG) +#define ETH1CLK_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR2_REG) +#define ETH1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR2_REG) +#define ETH1REFCLK_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 20, CCIPR2_REG) +#define ETH1GTXCLK_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 24, CCIPR2_REG) +/** CCIPR3 devices */ +#define FDCAN_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR3_REG) +#define FMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR3_REG) +/** CCIPR4 devices */ +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR4_REG) +#define I2C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, CCIPR4_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR4_REG) +#define I2C4_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR4_REG) +#define I3C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR4_REG) +#define I3C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 20, CCIPR4_REG) +#define LTDC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 24, CCIPR4_REG) +/** CCIPR5 devices */ +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR5_REG) +#define MCO2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR5_REG) +#define MDF1SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR5_REG) +/** CCIPR6 devices */ +#define XSPI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR6_REG) +#define XSPI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR6_REG) +#define XSPI3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR6_REG) +#define OTGPHY1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR6_REG) +#define OTGPHY1CKREF_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 16, CCIPR6_REG) +#define OTGPHY2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR6_REG) +#define OTGPHY2CKREF_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 24, CCIPR6_REG) +/** CCIPR7 devices */ +#define PER_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR7_REG) +#define PSSI_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR7_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR7_REG) +#define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 20, CCIPR7_REG) +#define SAI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 24, CCIPR7_REG) +/** CCIPR8 devices */ +#define SDMMC1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR8_REG) +#define SDMMC2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR8_REG) +/** CCIPR9 devices */ +#define SPDIFRX1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR9_REG) +#define SPI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, CCIPR9_REG) +#define SPI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR9_REG) +#define SPI3_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR9_REG) +#define SPI4_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR9_REG) +#define SPI5_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 20, CCIPR9_REG) +#define SPI6_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 24, CCIPR9_REG) +/** CCIPR12 devices */ +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR12_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR12_REG) +#define LPTIM3_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR12_REG) +#define LPTIM4_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 20, CCIPR12_REG) +#define LPTIM5_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 24, CCIPR12_REG) +/** CCIPR13 devices */ +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR13_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, CCIPR13_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR13_REG) +#define UART4_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR13_REG) +#define UART5_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR13_REG) +#define USART6_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 20, CCIPR13_REG) +#define UART7_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 24, CCIPR13_REG) +#define UART8_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 28, CCIPR13_REG) +/** CCIPR14 devices */ +#define UART9_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR14_REG) +#define USART10_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 4, CCIPR14_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR14_REG) + +/** @brief RCC_ICxCFGR register offset (RM0468.pdf) */ +#define ICxCFGR_REG(ic) (0xC4 + ((ic) - 1) * 4) + +/** @brief Divider ICx source selection */ +#define ICx_PLLy_SEL(ic, pll) STM32_DT_CLOCK_SELECT((pll) - 1, 3, 28, ICxCFGR_REG(ic)) + +/** @brief RCC_CFGR1 register offset (RM0468.pdf) */ +#define CFGR1_REG 0x20 + +/** @brief CPU clock switch selection */ +#define CPU_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CFGR1_REG) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32N6_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32u0_clock.h b/include/zephyr/dt-bindings/clock/stm32u0_clock.h index 476c423608256..50e76c573d781 100644 --- a/include/zephyr/dt-bindings/clock/stm32u0_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32u0_clock.h @@ -36,34 +36,6 @@ #define STM32_SRC_PLL_Q (STM32_SRC_PLL_P + 1) #define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPR register offset */ #define CCIPR_REG 0x88 @@ -72,21 +44,21 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR_REG) -#define LPUART3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, CCIPR_REG) -#define LPUART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR_REG) -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CCIPR_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR_REG) -#define LPTIM3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR_REG) -#define TIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 24, CCIPR_REG) -#define TIM15_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 25, CCIPR_REG) -#define CLK48_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 26, CCIPR_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 28, CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR_REG) +#define LPUART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, CCIPR_REG) +#define LPUART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR_REG) +#define LPTIM3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR_REG) +#define TIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 24, CCIPR_REG) +#define TIM15_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 25, CCIPR_REG) +#define CLK48_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 26, CCIPR_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, CCIPR_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32U0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32u5_clock.h b/include/zephyr/dt-bindings/clock/stm32u5_clock.h index 4b9b563121e9c..b284efd5d2e37 100644 --- a/include/zephyr/dt-bindings/clock/stm32u5_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32u5_clock.h @@ -52,34 +52,6 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB3 -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32U5 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPRx register offset (RM0456.pdf) */ #define CCIPR1_REG 0xE0 #define CCIPR2_REG 0xE4 @@ -93,50 +65,57 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR1 devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR1_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR1_REG) -#define USART3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 4, CCIPR1_REG) -#define UART4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, CCIPR1_REG) -#define UART5_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR1_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR1_REG) -#define I2C2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR1_REG) -#define I2C4_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 14, CCIPR1_REG) -#define SPI2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CCIPR1_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR1_REG) -#define SPI1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR1_REG) -#define SYSTICK_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR1_REG) -#define FDCAN1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 24, CCIPR1_REG) -#define ICKLK_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 26, CCIPR1_REG) -#define TIMIC_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 29, CCIPR1_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR1_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR1_REG) +#define USART3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 4, CCIPR1_REG) +#define UART4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, CCIPR1_REG) +#define UART5_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR1_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR1_REG) +#define I2C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR1_REG) +#define I2C4_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, CCIPR1_REG) +#define SPI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CCIPR1_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR1_REG) +#define SPI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR1_REG) +#define SYSTICK_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR1_REG) +#define FDCAN1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 24, CCIPR1_REG) +#define ICKLK_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 26, CCIPR1_REG) +#define TIMIC_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 29, CCIPR1_REG) /** CCIPR2 devices */ -#define MDF1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, CCIPR2_REG) -#define SAI1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 5, CCIPR2_REG) -#define SAI2_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 8, CCIPR2_REG) -#define SAE_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 11, CCIPR2_REG) -#define RNG_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR2_REG) -#define SDMMC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 14, CCIPR2_REG) -#define DSIHOST_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 15, CCIPR2_REG) -#define USART6_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 16, CCIPR2_REG) -#define LTDC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 18, CCIPR2_REG) -#define OCTOSPI_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR2_REG) -#define HSPI_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR2_REG) -#define I2C5_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 24, CCIPR2_REG) -#define I2C6_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 26, CCIPR2_REG) -#define USBPHYC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 30, CCIPR2_REG) +#define MDF1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR2_REG) +#define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 5, CCIPR2_REG) +#define SAI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 8, CCIPR2_REG) +#define SAE_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 11, CCIPR2_REG) +#define RNG_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR2_REG) +#define SDMMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 14, CCIPR2_REG) +#define DSIHOST_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 15, CCIPR2_REG) +#define USART6_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 16, CCIPR2_REG) +#define LTDC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 18, CCIPR2_REG) +#define OCTOSPI_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR2_REG) +#define HSPI_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR2_REG) +#define I2C5_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 24, CCIPR2_REG) +#define I2C6_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 26, CCIPR2_REG) +#define OTGHS_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 30, CCIPR2_REG) /** CCIPR3 devices */ -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 0, CCIPR3_REG) -#define SPI3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 3, CCIPR3_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, CCIPR3_REG) -#define LPTIM34_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR3_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR3_REG) -#define ADCDAC_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 12, CCIPR3_REG) -#define DAC1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 15, CCIPR3_REG) -#define ADF1_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 16, CCIPR3_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 0, CCIPR3_REG) +#define SPI3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 3, CCIPR3_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, CCIPR3_REG) +#define LPTIM34_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR3_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR3_REG) +#define ADCDAC_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR3_REG) +#define DAC1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 15, CCIPR3_REG) +#define ADF1_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 16, CCIPR3_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** CFGR1 devices */ -#define MCO1_SEL(val) STM32_MCO_CFGR(val, 0xF, 24, CFGR1_REG) -#define MCO1_PRE(val) STM32_MCO_CFGR(val, 0x7, 28, CFGR1_REG) +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0xF, 24, CFGR1_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 28, CFGR1_REG) + +/* MCO prescaler : division factor */ +#define MCO_PRE_DIV_1 0 +#define MCO_PRE_DIV_2 1 +#define MCO_PRE_DIV_4 2 +#define MCO_PRE_DIV_8 3 +#define MCO_PRE_DIV_16 4 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32U5_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32wb0_clock.h b/include/zephyr/dt-bindings/clock/stm32wb0_clock.h index 23ba8e996086e..d3b96b49ca4f5 100644 --- a/include/zephyr/dt-bindings/clock/stm32wb0_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32wb0_clock.h @@ -27,34 +27,6 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB0 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB2 -#define STM32_CLOCK_REG_MASK (0xFFFFU) -#define STM32_CLOCK_REG_SHIFT (0U) -#define STM32_CLOCK_SHIFT_MASK (0x3FU) -#define STM32_CLOCK_SHIFT_SHIFT (16U) -#define STM32_CLOCK_MASK_MASK (0x1FU) -#define STM32_CLOCK_MASK_SHIFT (22U) -#define STM32_CLOCK_VAL_MASK STM32_CLOCK_MASK_MASK -#define STM32_CLOCK_VAL_SHIFT (27U) - -/** - * @brief STM32 clock configuration bit field - * - * @param reg Offset to target configuration register in RCC - * @param shift Position of field within RCC register (= field LSB's index) - * @param mask Mask of field in RCC register - * @param val Field value - * - * @note 'reg' range: 0x0~0xFFFF [ 00 : 15 ] - * @note 'shift' range: 0~63 [ 16 : 21 ] - * @note 'mask' range: 0x00~0x1F [ 22 : 26 ] - * @note 'val' range: 0x00~0x1F [ 27 : 31 ] - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CFGR register offset */ #define CFGR_REG 0x08 @@ -62,9 +34,12 @@ #define APB2ENR_REG 0x60 /** @brief Device clk sources selection helpers */ -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 13, CFGR_REG) /* WB05/WB09 only */ -#define SPI2_I2S2_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 22, CFGR_REG) /* WB06/WB07 only */ + +/* WB05/WB09 only */ +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 13, CFGR_REG) +/* WB06/WB07 only */ +#define SPI2_I2S2_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 22, CFGR_REG) /* `mask` is only 0x1 for WB06/WB07, but a single definition with mask=0x3 is acceptable */ -#define SPI3_I2S3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CFGR_REG) +#define SPI3_I2S3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CFGR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WB0_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32wb_clock.h b/include/zephyr/dt-bindings/clock/stm32wb_clock.h index 31786c8675dd3..f56e70e54b9fb 100644 --- a/include/zephyr/dt-bindings/clock/stm32wb_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32wb_clock.h @@ -38,34 +38,6 @@ #define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) /* TODO: PLLSAI clocks */ -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPR register offset */ #define CCIPR_REG 0x88 @@ -77,19 +49,19 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR_REG) -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CCIPR_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR_REG) -#define SAI1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR_REG) -#define CLK48_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 26, CCIPR_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 28, CCIPR_REG) -#define RNG_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 30, CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR_REG) +#define SAI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR_REG) +#define CLK48_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 26, CCIPR_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, CCIPR_REG) +#define RNG_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 30, CCIPR_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) /** CSR devices */ -#define RFWKP_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 14, CSR_REG) +#define RFWKP_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, CSR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WB_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32wba_clock.h b/include/zephyr/dt-bindings/clock/stm32wba_clock.h index b8baaada6be88..23ceac25c0119 100644 --- a/include/zephyr/dt-bindings/clock/stm32wba_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32wba_clock.h @@ -45,35 +45,6 @@ #define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_AHB1 #define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_APB7 -/** - * @brief STM32WBA clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ - -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPRx register offset (RM0493.pdf) */ #define CCIPR1_REG 0xE0 #define CCIPR2_REG 0xE4 @@ -83,22 +54,46 @@ /** @brief Device clk sources selection helpers */ /** CCIPR1 devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR1_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR1_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR1_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR1_REG) -#define SPI1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR1_REG) -#define SYSTICK_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR1_REG) -#define TIMIC_SEL(val) STM32_DOMAIN_CLOCK(val, 1, 31, CCIPR1_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR1_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR1_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR1_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR1_REG) +#define SPI1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR1_REG) +#define SYSTICK_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR1_REG) +#define TIMIC_SEL(val) STM32_DT_CLOCK_SELECT((val), 1, 31, CCIPR1_REG) /** CCIPR2 devices */ -#define RNG_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR2_REG) +#define RNG_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR2_REG) /** CCIPR3 devices */ -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR3_REG) -#define SPI3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 3, CCIPR3_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 6, CCIPR3_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR3_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 7, 12, CCIPR3_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR3_REG) +#define SPI3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 3, CCIPR3_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 6, CCIPR3_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR3_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 7, 12, CCIPR3_REG) /** BCDR1 devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BCDR1_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BCDR1_REG) +/** @brief RCC_CFGRx register offset */ +#define CFGR1_REG 0x1C +/** CFGR1 devices */ +#define MCO1_SEL(val) STM32_DT_CLOCK_SELECT((val), 0xF, 24, CFGR1_REG) +#define MCO1_PRE(val) STM32_DT_CLOCK_SELECT((val), 0x7, 28, CFGR1_REG) + +/* MCO prescaler : division factor */ +#define MCO_PRE_DIV_1 0 +#define MCO_PRE_DIV_2 1 +#define MCO_PRE_DIV_4 2 +#define MCO_PRE_DIV_8 3 +#define MCO_PRE_DIV_16 4 + +/* MCO clock output */ +#define MCO_SEL_SYSCLKPRE 1 +#define MCO_SEL_HSI16 3 +#define MCO_SEL_HSE32 4 +#define MCO_SEL_PLL1RCLK 5 +#define MCO_SEL_LSI 6 +#define MCO_SEL_LSE 7 +#define MCO_SEL_PLL1PCLK 8 +#define MCO_SEL_PLL1QCLK 9 +#define MCO_SEL_HCLK5 10 + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WBA_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/clock/stm32wl_clock.h b/include/zephyr/dt-bindings/clock/stm32wl_clock.h index 7384703267e43..fbe007f16e0d8 100644 --- a/include/zephyr/dt-bindings/clock/stm32wl_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32wl_clock.h @@ -38,34 +38,6 @@ #define STM32_SRC_PLL_Q (STM32_SRC_PLL_P + 1) #define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) -#define STM32_CLOCK_REG_MASK 0xFFU -#define STM32_CLOCK_REG_SHIFT 0U -#define STM32_CLOCK_SHIFT_MASK 0x1FU -#define STM32_CLOCK_SHIFT_SHIFT 8U -#define STM32_CLOCK_MASK_MASK 0x7U -#define STM32_CLOCK_MASK_SHIFT 13U -#define STM32_CLOCK_VAL_MASK 0x7U -#define STM32_CLOCK_VAL_SHIFT 16U - -/** - * @brief STM32 clock configuration bit field. - * - * - reg (1/2/3) [ 0 : 7 ] - * - shift (0..31) [ 8 : 12 ] - * - mask (0x1, 0x3, 0x7) [ 13 : 15 ] - * - val (0..7) [ 16 : 18 ] - * - * @param reg RCC_CCIPRx register offset - * @param shift Position within RCC_CCIPRx. - * @param mask Mask for the RCC_CCIPRx field. - * @param val Clock value (0, 1, ... 7). - */ -#define STM32_DOMAIN_CLOCK(val, mask, shift, reg) \ - ((((reg) & STM32_CLOCK_REG_MASK) << STM32_CLOCK_REG_SHIFT) | \ - (((shift) & STM32_CLOCK_SHIFT_MASK) << STM32_CLOCK_SHIFT_SHIFT) | \ - (((mask) & STM32_CLOCK_MASK_MASK) << STM32_CLOCK_MASK_SHIFT) | \ - (((val) & STM32_CLOCK_VAL_MASK) << STM32_CLOCK_VAL_SHIFT)) - /** @brief RCC_CCIPR register offset */ #define CCIPR_REG 0x88 @@ -74,19 +46,19 @@ /** @brief Device domain clocks selection helpers */ /** CCIPR devices */ -#define USART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 0, CCIPR_REG) -#define USART2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 2, CCIPR_REG) -#define SPI2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, CCIPR_REG) -#define LPUART1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 10, CCIPR_REG) -#define I2C1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 12, CCIPR_REG) -#define I2C2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 14, CCIPR_REG) -#define I2C3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 16, CCIPR_REG) -#define LPTIM1_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 18, CCIPR_REG) -#define LPTIM2_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 20, CCIPR_REG) -#define LPTIM3_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 22, CCIPR_REG) -#define ADC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 28, CCIPR_REG) -#define RNG_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 30, CCIPR_REG) +#define USART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 0, CCIPR_REG) +#define USART2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 2, CCIPR_REG) +#define SPI2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, CCIPR_REG) +#define LPUART1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 10, CCIPR_REG) +#define I2C1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 12, CCIPR_REG) +#define I2C2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 14, CCIPR_REG) +#define I2C3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 16, CCIPR_REG) +#define LPTIM1_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 18, CCIPR_REG) +#define LPTIM2_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 20, CCIPR_REG) +#define LPTIM3_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 22, CCIPR_REG) +#define ADC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 28, CCIPR_REG) +#define RNG_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 30, CCIPR_REG) /** BDCR devices */ -#define RTC_SEL(val) STM32_DOMAIN_CLOCK(val, 3, 8, BDCR_REG) +#define RTC_SEL(val) STM32_DT_CLOCK_SELECT((val), 3, 8, BDCR_REG) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32WL_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/comparator/silabs-acmp.h b/include/zephyr/dt-bindings/comparator/silabs-acmp.h new file mode 100644 index 0000000000000..e326c2b3ebe42 --- /dev/null +++ b/include/zephyr/dt-bindings/comparator/silabs-acmp.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * This file was generated by the script gen_acmp.py in the hal_silabs module. + * Do not manually edit. + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_COMPARATOR_SILABS_ACMP_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_COMPARATOR_SILABS_ACMP_H_ + +/* ACMP Input Aliases */ +#define ACMP_INPUT_VDACOUT0 ACMP_INPUT_VDAC0OUT0 +#define ACMP_INPUT_VDACOUT1 ACMP_INPUT_VDAC0OUT1 + +/* ACMP Input Definitions */ +#define ACMP_INPUT_VSS 0x0 +#define ACMP_INPUT_VREFDIVAVDD 0x10 +#define ACMP_INPUT_VREFDIVAVDDLP 0x11 +#define ACMP_INPUT_VREFDIV1V25 0x12 +#define ACMP_INPUT_VREFDIV1V25LP 0x13 +#define ACMP_INPUT_VREFDIV2V5 0x14 +#define ACMP_INPUT_VREFDIV2V5LP 0x15 +#define ACMP_INPUT_VSENSE01DIV4 0x20 +#define ACMP_INPUT_VSENSE01DIV4LP 0x21 +#define ACMP_INPUT_VSENSE11DIV4 0x22 +#define ACMP_INPUT_VSENSE11DIV4LP 0x23 +#define ACMP_INPUT_CAPSENSE 0x30 +#define ACMP_INPUT_VDAC0OUT0 0x40 +#define ACMP_INPUT_VDAC0OUT1 0x41 +#define ACMP_INPUT_VDAC1OUT0 0x42 +#define ACMP_INPUT_VDAC1OUT1 0x43 +#define ACMP_INPUT_EXTPA 0x50 +#define ACMP_INPUT_EXTPB 0x51 +#define ACMP_INPUT_EXTPC 0x52 +#define ACMP_INPUT_EXTPD 0x53 +#define ACMP_INPUT_PA0 0x80 +#define ACMP_INPUT_PA1 0x81 +#define ACMP_INPUT_PA2 0x82 +#define ACMP_INPUT_PA3 0x83 +#define ACMP_INPUT_PA4 0x84 +#define ACMP_INPUT_PA5 0x85 +#define ACMP_INPUT_PA6 0x86 +#define ACMP_INPUT_PA7 0x87 +#define ACMP_INPUT_PA8 0x88 +#define ACMP_INPUT_PA9 0x89 +#define ACMP_INPUT_PA10 0x8a +#define ACMP_INPUT_PA11 0x8b +#define ACMP_INPUT_PA12 0x8c +#define ACMP_INPUT_PA13 0x8d +#define ACMP_INPUT_PA14 0x8e +#define ACMP_INPUT_PA15 0x8f +#define ACMP_INPUT_PB0 0x90 +#define ACMP_INPUT_PB1 0x91 +#define ACMP_INPUT_PB2 0x92 +#define ACMP_INPUT_PB3 0x93 +#define ACMP_INPUT_PB4 0x94 +#define ACMP_INPUT_PB5 0x95 +#define ACMP_INPUT_PB6 0x96 +#define ACMP_INPUT_PB7 0x97 +#define ACMP_INPUT_PB8 0x98 +#define ACMP_INPUT_PB9 0x99 +#define ACMP_INPUT_PB10 0x9a +#define ACMP_INPUT_PB11 0x9b +#define ACMP_INPUT_PB12 0x9c +#define ACMP_INPUT_PB13 0x9d +#define ACMP_INPUT_PB14 0x9e +#define ACMP_INPUT_PB15 0x9f +#define ACMP_INPUT_PC0 0xa0 +#define ACMP_INPUT_PC1 0xa1 +#define ACMP_INPUT_PC2 0xa2 +#define ACMP_INPUT_PC3 0xa3 +#define ACMP_INPUT_PC4 0xa4 +#define ACMP_INPUT_PC5 0xa5 +#define ACMP_INPUT_PC6 0xa6 +#define ACMP_INPUT_PC7 0xa7 +#define ACMP_INPUT_PC8 0xa8 +#define ACMP_INPUT_PC9 0xa9 +#define ACMP_INPUT_PC10 0xaa +#define ACMP_INPUT_PC11 0xab +#define ACMP_INPUT_PC12 0xac +#define ACMP_INPUT_PC13 0xad +#define ACMP_INPUT_PC14 0xae +#define ACMP_INPUT_PC15 0xaf +#define ACMP_INPUT_PD0 0xb0 +#define ACMP_INPUT_PD1 0xb1 +#define ACMP_INPUT_PD2 0xb2 +#define ACMP_INPUT_PD3 0xb3 +#define ACMP_INPUT_PD4 0xb4 +#define ACMP_INPUT_PD5 0xb5 +#define ACMP_INPUT_PD6 0xb6 +#define ACMP_INPUT_PD7 0xb7 +#define ACMP_INPUT_PD8 0xb8 +#define ACMP_INPUT_PD9 0xb9 +#define ACMP_INPUT_PD10 0xba +#define ACMP_INPUT_PD11 0xbb +#define ACMP_INPUT_PD12 0xbc +#define ACMP_INPUT_PD13 0xbd +#define ACMP_INPUT_PD14 0xbe +#define ACMP_INPUT_PD15 0xbf + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_COMPARATOR_SILABS_ACMP_H_ */ diff --git a/include/zephyr/dt-bindings/dma/atmel_samx7x_dma.h b/include/zephyr/dt-bindings/dma/atmel_samx7x_dma.h new file mode 100644 index 0000000000000..e0914d454ba02 --- /dev/null +++ b/include/zephyr/dt-bindings/dma/atmel_samx7x_dma.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020 Linaro Limited + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ATMEL_SAMX7X_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ATMEL_SAMX7X_DMA_H_ + +/** + * Atmel SAMx7x Peripheral Hardware Request HW Interface Number (XDMAC_CC.PERID). + * + * See table Table 35-1. Peripheral Hardware Requests in the SAM E70/S70/V70/V71 datasheet. + */ +#define DMA_PERID_HSMCI_TX_RX 0 +#define DMA_PERID_SPI0_TX 1 +#define DMA_PERID_SPI0_RX 2 +#define DMA_PERID_SPI1_TX 3 +#define DMA_PERID_SPI1_RX 4 +#define DMA_PERID_QSPI_TX 5 +#define DMA_PERID_QSPI_RX 6 +#define DMA_PERID_USART0_TX 7 +#define DMA_PERID_USART0_RX 8 +#define DMA_PERID_USART1_TX 9 +#define DMA_PERID_USART1_RX 10 +#define DMA_PERID_USART2_TX 11 +#define DMA_PERID_USART2_RX 12 +#define DMA_PERID_PWM0_TX 13 +#define DMA_PERID_TWIHS0_TX 14 +#define DMA_PERID_TWIHS0_RX 15 +#define DMA_PERID_TWIHS1_TX 16 +#define DMA_PERID_TWIHS1_RX 17 +#define DMA_PERID_TWIHS2_TX 18 +#define DMA_PERID_TWIHS2_RX 19 +#define DMA_PERID_UART0_TX 20 +#define DMA_PERID_UART0_RX 21 +#define DMA_PERID_UART1_TX 22 +#define DMA_PERID_UART1_RX 23 +#define DMA_PERID_UART2_TX 24 +#define DMA_PERID_UART2_RX 25 +#define DMA_PERID_UART3_TX 26 +#define DMA_PERID_UART3_RX 27 +#define DMA_PERID_UART4_TX 28 +#define DMA_PERID_UART4_RX 29 +#define DMA_PERID_DACC0_TX 30 +#define DMA_PERID_DACC1_TX 31 +#define DMA_PERID_SSC_TX 32 +#define DMA_PERID_SSC_RX 33 +#define DMA_PERID_PIOA_RX 34 +#define DMA_PERID_AFEC0_RX 35 +#define DMA_PERID_AFEC1_RX 36 +#define DMA_PERID_AES_TX 37 +#define DMA_PERID_AES_RX 38 +#define DMA_PERID_PWM1_TX 39 +#define DMA_PERID_TC0_RX 40 +#define DMA_PERID_TC1_RX 41 +#define DMA_PERID_TC2_RX 42 +#define DMA_PERID_TC3_RX 43 +#define DMA_PERID_I2SC0_TX_L 44 +#define DMA_PERID_I2SC0_RX_L 45 +#define DMA_PERID_I2SC1_TX_L 46 +#define DMA_PERID_I2SC1_RX_L 47 +#define DMA_PERID_I2SC0_TX_R 48 +#define DMA_PERID_I2SC0_RX_R 49 +#define DMA_PERID_I2SC1_TX_R 50 +#define DMA_PERID_I2SC1_RX_R 51 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ATMEL_SAMX7X_DMA_H_ */ diff --git a/include/zephyr/dt-bindings/dma/max32660_dma.h b/include/zephyr/dt-bindings/dma/max32660_dma.h new file mode 100644 index 0000000000000..e52805e1ab64c --- /dev/null +++ b/include/zephyr/dt-bindings/dma/max32660_dma.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_DMA_MAX32660_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_DMA_MAX32660_DMA_H_ + +#define MAX32_DMA_SLOT_MEMTOMEM 0x00U +#define MAX32_DMA_SLOT_SPI0_RX 0x01U +#define MAX32_DMA_SLOT_SPI1_RX 0x02U +#define MAX32_DMA_SLOT_UART0_RX 0x04U +#define MAX32_DMA_SLOT_UART1_RX 0x05U +#define MAX32_DMA_SLOT_I2C0_RX 0x07U +#define MAX32_DMA_SLOT_I2C1_RX 0x08U +#define MAX32_DMA_SLOT_SPI0_TX 0x21U +#define MAX32_DMA_SLOT_SPI1_TX 0x22U +#define MAX32_DMA_SLOT_UART0_TX 0x24U +#define MAX32_DMA_SLOT_UART1_TX 0x25U +#define MAX32_DMA_SLOT_I2C0_TX 0x27U +#define MAX32_DMA_SLOT_I2C1_TX 0x28U + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_DMA_MAX32660_DMA_H_ */ diff --git a/include/zephyr/dt-bindings/dma/max78000_dma.h b/include/zephyr/dt-bindings/dma/max78000_dma.h new file mode 100644 index 0000000000000..b899748e46dba --- /dev/null +++ b/include/zephyr/dt-bindings/dma/max78000_dma.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_DMA_MAX78000_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_DMA_MAX78000_DMA_H_ + +#define MAX78_DMA_SLOT_MEMTOMEM 0x00U +#define MAX78_DMA_SLOT_SPI1_RX 0x01U +#define MAX78_DMA_SLOT_UART0_RX 0x04U +#define MAX78_DMA_SLOT_UART1_RX 0x05U +#define MAX78_DMA_SLOT_I2C0_RX 0x07U +#define MAX78_DMA_SLOT_I2C1_RX 0x08U +#define MAX78_DMA_SLOT_ADC 0x09U +#define MAX78_DMA_SLOT_I2C2_RX 0x0AU +#define MAX78_DMA_SLOT_PCIF_RX 0x0DU +#define MAX78_DMA_SLOT_UART2_RX 0x0EU +#define MAX78_DMA_SLOT_SPI0_RX 0x0FU +#define MAX78_DMA_SLOT_UART3_RX 0x1CU +#define MAX78_DMA_SLOT_I2S_RX 0x1EU +#define MAX78_DMA_SLOT_SPI1_TX 0x21U +#define MAX78_DMA_SLOT_UART0_TX 0x24U +#define MAX78_DMA_SLOT_UART1_TX 0x25U +#define MAX78_DMA_SLOT_I2C0_TX 0x27U +#define MAX78_DMA_SLOT_I2C1_TX 0x28U +#define MAX78_DMA_SLOT_I2C2_TX 0x2AU +#define MAX78_DMA_SLOT_CRC 0x2CU +#define MAX78_DMA_SLOT_PCIF_TX 0x2DU +#define MAX78_DMA_SLOT_UART2_TX 0x2EU +#define MAX78_DMA_SLOT_SPI0_TX 0x2FU +#define MAX78_DMA_SLOT_UART3_TX 0x3CU +#define MAX78_DMA_SLOT_I2S_TX 0x3EU + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_DMA_MAX78000_DMA_H_ */ diff --git a/include/zephyr/dt-bindings/dma/rpi-pico-dma-common.h b/include/zephyr/dt-bindings/dma/rpi-pico-dma-common.h new file mode 100644 index 0000000000000..8a17cc830ebae --- /dev/null +++ b/include/zephyr/dt-bindings/dma/rpi-pico-dma-common.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_COMMON_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_COMMON_H_ + +/* + * Use lower 6-bit of inverted DREQ value for `slot` cell. + * Need to be able to work for memory-to-memory transfer + * with zero, which is the default value. + */ +#define RPI_PICO_DMA_SLOT_TO_DREQ(s) (~(s)&0x3F) +#define RPI_PICO_DMA_DREQ_TO_SLOT RPI_PICO_DMA_SLOT_TO_DREQ + +#define RPI_PICO_DMA_SLOT_PIO0_TX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x00) +#define RPI_PICO_DMA_SLOT_PIO0_TX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x01) +#define RPI_PICO_DMA_SLOT_PIO0_TX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x02) +#define RPI_PICO_DMA_SLOT_PIO0_TX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x03) +#define RPI_PICO_DMA_SLOT_PIO0_RX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x04) +#define RPI_PICO_DMA_SLOT_PIO0_RX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x05) +#define RPI_PICO_DMA_SLOT_PIO0_RX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x06) +#define RPI_PICO_DMA_SLOT_PIO0_RX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x07) +#define RPI_PICO_DMA_SLOT_PIO1_TX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x08) +#define RPI_PICO_DMA_SLOT_PIO1_TX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x09) +#define RPI_PICO_DMA_SLOT_PIO1_TX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x0A) +#define RPI_PICO_DMA_SLOT_PIO1_TX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x0B) +#define RPI_PICO_DMA_SLOT_PIO1_RX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x0C) +#define RPI_PICO_DMA_SLOT_PIO1_RX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x0D) +#define RPI_PICO_DMA_SLOT_PIO1_RX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x0E) +#define RPI_PICO_DMA_SLOT_PIO1_RX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x0F) + +#define RPI_PICO_DMA_SLOT_DMA_TIMER0 RPI_PICO_DMA_DREQ_TO_SLOT(0x3B) +#define RPI_PICO_DMA_SLOT_DMA_TIMER1 RPI_PICO_DMA_DREQ_TO_SLOT(0x3C) +#define RPI_PICO_DMA_SLOT_DMA_TIMER2 RPI_PICO_DMA_DREQ_TO_SLOT(0x3D) +#define RPI_PICO_DMA_SLOT_DMA_TIMER3 RPI_PICO_DMA_DREQ_TO_SLOT(0x3E) +#define RPI_PICO_DMA_SLOT_FORCE RPI_PICO_DMA_DREQ_TO_SLOT(0x3F) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_COMMON_H_ */ diff --git a/include/zephyr/dt-bindings/dma/rpi-pico-dma-rp2040.h b/include/zephyr/dt-bindings/dma/rpi-pico-dma-rp2040.h new file mode 100644 index 0000000000000..2ef5f4efa5f10 --- /dev/null +++ b/include/zephyr/dt-bindings/dma/rpi-pico-dma-rp2040.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_RP2040_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_RP2040_H_ + +#include "rpi-pico-dma-common.h" + +#define RPI_PICO_DMA_SLOT_SPI0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x10) +#define RPI_PICO_DMA_SLOT_SPI0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x11) +#define RPI_PICO_DMA_SLOT_SPI1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x12) +#define RPI_PICO_DMA_SLOT_SPI1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x13) +#define RPI_PICO_DMA_SLOT_UART0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x14) +#define RPI_PICO_DMA_SLOT_UART0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x15) +#define RPI_PICO_DMA_SLOT_UART1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x16) +#define RPI_PICO_DMA_SLOT_UART1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x17) +#define RPI_PICO_DMA_SLOT_PWM_WRAP0 RPI_PICO_DMA_DREQ_TO_SLOT(0x18) +#define RPI_PICO_DMA_SLOT_PWM_WRAP1 RPI_PICO_DMA_DREQ_TO_SLOT(0x19) +#define RPI_PICO_DMA_SLOT_PWM_WRAP2 RPI_PICO_DMA_DREQ_TO_SLOT(0x1A) +#define RPI_PICO_DMA_SLOT_PWM_WRAP3 RPI_PICO_DMA_DREQ_TO_SLOT(0x1B) +#define RPI_PICO_DMA_SLOT_PWM_WRAP4 RPI_PICO_DMA_DREQ_TO_SLOT(0x1C) +#define RPI_PICO_DMA_SLOT_PWM_WRAP5 RPI_PICO_DMA_DREQ_TO_SLOT(0x1D) +#define RPI_PICO_DMA_SLOT_PWM_WRAP6 RPI_PICO_DMA_DREQ_TO_SLOT(0x1E) +#define RPI_PICO_DMA_SLOT_PWM_WRAP7 RPI_PICO_DMA_DREQ_TO_SLOT(0x1F) +#define RPI_PICO_DMA_SLOT_I2C0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x30) +#define RPI_PICO_DMA_SLOT_I2C0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x31) +#define RPI_PICO_DMA_SLOT_I2C1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x32) +#define RPI_PICO_DMA_SLOT_I2C1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x33) +#define RPI_PICO_DMA_SLOT_ADC RPI_PICO_DMA_DREQ_TO_SLOT(0x34) +#define RPI_PICO_DMA_SLOT_XIP_STREAM RPI_PICO_DMA_DREQ_TO_SLOT(0x35) +#define RPI_PICO_DMA_SLOT_XIP_SSITX RPI_PICO_DMA_DREQ_TO_SLOT(0x36) +#define RPI_PICO_DMA_SLOT_XIP_SSIRX RPI_PICO_DMA_DREQ_TO_SLOT(0x37) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_RP2040_H_ */ diff --git a/include/zephyr/dt-bindings/dma/rpi-pico-dma-rp2350.h b/include/zephyr/dt-bindings/dma/rpi-pico-dma-rp2350.h new file mode 100644 index 0000000000000..3a507328cf231 --- /dev/null +++ b/include/zephyr/dt-bindings/dma/rpi-pico-dma-rp2350.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Manuel Aebischer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_RP2350_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_RP2350_H_ + +#include "rpi-pico-dma-common.h" + +#define RPI_PICO_DMA_SLOT_PIO2_TX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x10) +#define RPI_PICO_DMA_SLOT_PIO2_TX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x11) +#define RPI_PICO_DMA_SLOT_PIO2_TX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x12) +#define RPI_PICO_DMA_SLOT_PIO2_TX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x13) +#define RPI_PICO_DMA_SLOT_PIO2_RX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x14) +#define RPI_PICO_DMA_SLOT_PIO2_RX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x15) +#define RPI_PICO_DMA_SLOT_PIO2_RX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x16) +#define RPI_PICO_DMA_SLOT_PIO2_RX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x17) +#define RPI_PICO_DMA_SLOT_SPI0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x18) +#define RPI_PICO_DMA_SLOT_SPI0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x19) +#define RPI_PICO_DMA_SLOT_SPI1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x1A) +#define RPI_PICO_DMA_SLOT_SPI1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x1B) +#define RPI_PICO_DMA_SLOT_UART0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x1C) +#define RPI_PICO_DMA_SLOT_UART0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x1D) +#define RPI_PICO_DMA_SLOT_UART1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x1E) +#define RPI_PICO_DMA_SLOT_UART1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x1F) +#define RPI_PICO_DMA_SLOT_PWM_WRAP0 RPI_PICO_DMA_DREQ_TO_SLOT(0x20) +#define RPI_PICO_DMA_SLOT_PWM_WRAP1 RPI_PICO_DMA_DREQ_TO_SLOT(0x21) +#define RPI_PICO_DMA_SLOT_PWM_WRAP2 RPI_PICO_DMA_DREQ_TO_SLOT(0x22) +#define RPI_PICO_DMA_SLOT_PWM_WRAP3 RPI_PICO_DMA_DREQ_TO_SLOT(0x23) +#define RPI_PICO_DMA_SLOT_PWM_WRAP4 RPI_PICO_DMA_DREQ_TO_SLOT(0x24) +#define RPI_PICO_DMA_SLOT_PWM_WRAP5 RPI_PICO_DMA_DREQ_TO_SLOT(0x25) +#define RPI_PICO_DMA_SLOT_PWM_WRAP6 RPI_PICO_DMA_DREQ_TO_SLOT(0x26) +#define RPI_PICO_DMA_SLOT_PWM_WRAP7 RPI_PICO_DMA_DREQ_TO_SLOT(0x27) +#define RPI_PICO_DMA_SLOT_PWM_WRAP8 RPI_PICO_DMA_DREQ_TO_SLOT(0x28) +#define RPI_PICO_DMA_SLOT_PWM_WRAP9 RPI_PICO_DMA_DREQ_TO_SLOT(0x29) +#define RPI_PICO_DMA_SLOT_PWM_WRAP10 RPI_PICO_DMA_DREQ_TO_SLOT(0x2A) +#define RPI_PICO_DMA_SLOT_PWM_WRAP11 RPI_PICO_DMA_DREQ_TO_SLOT(0x2B) +#define RPI_PICO_DMA_SLOT_I2C0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x2C) +#define RPI_PICO_DMA_SLOT_I2C0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x2D) +#define RPI_PICO_DMA_SLOT_I2C1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x2E) +#define RPI_PICO_DMA_SLOT_I2C1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x2F) +#define RPI_PICO_DMA_SLOT_ADC RPI_PICO_DMA_DREQ_TO_SLOT(0x30) +#define RPI_PICO_DMA_SLOT_XIP_STREAM RPI_PICO_DMA_DREQ_TO_SLOT(0x31) +#define RPI_PICO_DMA_SLOT_XIP_QMITX RPI_PICO_DMA_DREQ_TO_SLOT(0x32) +#define RPI_PICO_DMA_SLOT_XIP_QMIRX RPI_PICO_DMA_DREQ_TO_SLOT(0x33) +#define RPI_PICO_DMA_SLOT_HSTX RPI_PICO_DMA_DREQ_TO_SLOT(0x34) +#define RPI_PICO_DMA_SLOT_CORESIGHT RPI_PICO_DMA_DREQ_TO_SLOT(0x35) +#define RPI_PICO_DMA_SLOT_SHA256 RPI_PICO_DMA_DREQ_TO_SLOT(0x36) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_RP2350_H_ */ diff --git a/include/zephyr/dt-bindings/dma/rpi_pico_dma.h b/include/zephyr/dt-bindings/dma/rpi_pico_dma.h deleted file mode 100644 index f181a31beba90..0000000000000 --- a/include/zephyr/dt-bindings/dma/rpi_pico_dma.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2023 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_H_ - -/* - * Use lower 6-bit of inverted DREQ value for `slot` cell. - * Need to be able to work for memory-to-memory transfer - * with zero, which is the default value. - */ -#define RPI_PICO_DMA_SLOT_TO_DREQ(s) (~(s)&0x3F) -#define RPI_PICO_DMA_DREQ_TO_SLOT RPI_PICO_DMA_SLOT_TO_DREQ - -#define RPI_PICO_DMA_SLOT_PIO0_TX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x00) -#define RPI_PICO_DMA_SLOT_PIO0_TX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x01) -#define RPI_PICO_DMA_SLOT_PIO0_TX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x02) -#define RPI_PICO_DMA_SLOT_PIO0_TX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x03) -#define RPI_PICO_DMA_SLOT_PIO0_RX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x04) -#define RPI_PICO_DMA_SLOT_PIO0_RX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x05) -#define RPI_PICO_DMA_SLOT_PIO0_RX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x06) -#define RPI_PICO_DMA_SLOT_PIO0_RX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x07) -#define RPI_PICO_DMA_SLOT_PIO1_TX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x08) -#define RPI_PICO_DMA_SLOT_PIO1_TX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x09) -#define RPI_PICO_DMA_SLOT_PIO1_TX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x0A) -#define RPI_PICO_DMA_SLOT_PIO1_TX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x0B) -#define RPI_PICO_DMA_SLOT_PIO1_RX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x0C) -#define RPI_PICO_DMA_SLOT_PIO1_RX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x0D) -#define RPI_PICO_DMA_SLOT_PIO1_RX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x0E) -#define RPI_PICO_DMA_SLOT_PIO1_RX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x0F) -#define RPI_PICO_DMA_SLOT_SPI0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x10) -#define RPI_PICO_DMA_SLOT_SPI0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x11) -#define RPI_PICO_DMA_SLOT_SPI1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x12) -#define RPI_PICO_DMA_SLOT_SPI1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x13) -#define RPI_PICO_DMA_SLOT_UART0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x14) -#define RPI_PICO_DMA_SLOT_UART0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x15) -#define RPI_PICO_DMA_SLOT_UART1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x16) -#define RPI_PICO_DMA_SLOT_UART1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x17) -#define RPI_PICO_DMA_SLOT_PWM_WRAP0 RPI_PICO_DMA_DREQ_TO_SLOT(0x18) -#define RPI_PICO_DMA_SLOT_PWM_WRAP1 RPI_PICO_DMA_DREQ_TO_SLOT(0x19) -#define RPI_PICO_DMA_SLOT_PWM_WRAP2 RPI_PICO_DMA_DREQ_TO_SLOT(0x1A) -#define RPI_PICO_DMA_SLOT_PWM_WRAP3 RPI_PICO_DMA_DREQ_TO_SLOT(0x1B) -#define RPI_PICO_DMA_SLOT_PWM_WRAP4 RPI_PICO_DMA_DREQ_TO_SLOT(0x1C) -#define RPI_PICO_DMA_SLOT_PWM_WRAP5 RPI_PICO_DMA_DREQ_TO_SLOT(0x1D) -#define RPI_PICO_DMA_SLOT_PWM_WRAP6 RPI_PICO_DMA_DREQ_TO_SLOT(0x1E) -#define RPI_PICO_DMA_SLOT_PWM_WRAP7 RPI_PICO_DMA_DREQ_TO_SLOT(0x1F) -#define RPI_PICO_DMA_SLOT_I2C0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x30) -#define RPI_PICO_DMA_SLOT_I2C0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x31) -#define RPI_PICO_DMA_SLOT_I2C1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x32) -#define RPI_PICO_DMA_SLOT_I2C1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x33) -#define RPI_PICO_DMA_SLOT_ADC RPI_PICO_DMA_DREQ_TO_SLOT(0x34) -#define RPI_PICO_DMA_SLOT_XIP_STREAM RPI_PICO_DMA_DREQ_TO_SLOT(0x35) -#define RPI_PICO_DMA_SLOT_XIP_SSITX RPI_PICO_DMA_DREQ_TO_SLOT(0x36) -#define RPI_PICO_DMA_SLOT_XIP_SSIRX RPI_PICO_DMA_DREQ_TO_SLOT(0x37) -#define RPI_PICO_DMA_SLOT_DMA_TIMER0 RPI_PICO_DMA_DREQ_TO_SLOT(0x3B) -#define RPI_PICO_DMA_SLOT_DMA_TIMER1 RPI_PICO_DMA_DREQ_TO_SLOT(0x3C) -#define RPI_PICO_DMA_SLOT_DMA_TIMER2 RPI_PICO_DMA_DREQ_TO_SLOT(0x3D) -#define RPI_PICO_DMA_SLOT_DMA_TIMER3 RPI_PICO_DMA_DREQ_TO_SLOT(0x3E) -#define RPI_PICO_DMA_SLOT_FORCE RPI_PICO_DMA_DREQ_TO_SLOT(0x3F) - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_H_ */ diff --git a/include/zephyr/dt-bindings/dma/silabs/common-dma.h b/include/zephyr/dt-bindings/dma/silabs/common-dma.h new file mode 100644 index 0000000000000..ac4c7b75f133a --- /dev/null +++ b/include/zephyr/dt-bindings/dma/silabs/common-dma.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_DMA_SILABS_COMMON_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_DMA_SILABS_COMMON_DMA_H_ + +#define DMA_SRC_MASK 0x1F0000 +#define DMA_SIG_MASK 0x7 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_DMA_SILABS_COMMON_DMA_H_ */ diff --git a/include/zephyr/dt-bindings/dma/silabs/xg21-dma.h b/include/zephyr/dt-bindings/dma/silabs/xg21-dma.h new file mode 100644 index 0000000000000..a1077a9594ae1 --- /dev/null +++ b/include/zephyr/dt-bindings/dma/silabs/xg21-dma.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_XG21_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_XG21_DMA_H_ + +#include +#include "common-dma.h" + +/** + * Definition of Silabs LDMA request signal + */ +#define DMA_REQSEL_NONE (FIELD_PREP(DMA_SRC_MASK, 0) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ0 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ1 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC0 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER0CC1 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC2 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER0UFOF (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER1CC0 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER1CC1 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER1CC2 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER1UFOF (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART0RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART0TXBL (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART0TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_USART1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART1RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART1TXBL (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART1TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART1TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_USART2RXDATAV (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART2RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART2TXBL (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART2TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART2TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_I2C0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 7) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C0TXBL (FIELD_PREP(DMA_SRC_MASK, 7) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_I2C1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 8) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C1TXBL (FIELD_PREP(DMA_SRC_MASK, 8) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_IADC0IADC_SCAN (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_IADC0IADC_SINGLE (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_MSCWDATA (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC0 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC1 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER2CC2 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER2UFOF (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER3CC0 (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER3CC1 (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER3CC2 (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER3UFOF (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 3)) + +#endif ZEPHYR_INCLUDE_DT_BINDINGS_XG21_DMA_H_ diff --git a/include/zephyr/dt-bindings/dma/silabs/xg22-dma.h b/include/zephyr/dt-bindings/dma/silabs/xg22-dma.h new file mode 100644 index 0000000000000..8cba1cc20aa56 --- /dev/null +++ b/include/zephyr/dt-bindings/dma/silabs/xg22-dma.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_XG22_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_XG22_DMA_H_ + +#include +#include "common-dma.h" + +/** + * Definition of Silabs LDMA request signal + */ +#define DMA_REQSEL_NONE (FIELD_PREP(DMA_SRC_MASK, 0) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ0 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ1 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC0 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER0CC1 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC2 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER0UFOF (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER1CC0 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER1CC1 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER1CC2 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER1UFOF (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART0RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART0TXBL (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART0TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_USART1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART1RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART1TXBL (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART1TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART1TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_I2C0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C0TXBL (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_I2C1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 7) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C1TXBL (FIELD_PREP(DMA_SRC_MASK, 7) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_IADC0IADC_SCAN (FIELD_PREP(DMA_SRC_MASK, 11) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_IADC0IADC_SINGLE (FIELD_PREP(DMA_SRC_MASK, 11) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_MSCWDATA (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC0 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC1 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER2CC2 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER2UFOF (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER3CC0 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER3CC1 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER3CC2 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER3UFOF (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_PDMRXDATAV (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUART0RXFL (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUART0TXFL (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER4CC0 (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER4CC1 (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER4CC2 (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER4UFOF (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 3)) + +#endif ZEPHYR_INCLUDE_DT_BINDINGS_XG22_DMA_H_ diff --git a/include/zephyr/dt-bindings/dma/silabs/xg23-dma.h b/include/zephyr/dt-bindings/dma/silabs/xg23-dma.h new file mode 100644 index 0000000000000..b3e041761474e --- /dev/null +++ b/include/zephyr/dt-bindings/dma/silabs/xg23-dma.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_XG23_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_XG23_DMA_H_ + +#include +#include "common-dma.h" + +/** + * Definition of Silabs LDMA request signal + */ +#define DMA_REQSEL_NONE (FIELD_PREP(DMA_SRC_MASK, 0) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ0 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ1 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC0 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER0CC1 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC2 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER0UFOF (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER1CC0 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER1CC1 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER1CC2 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER1UFOF (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART0RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART0TXBL (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART0TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_I2C0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C0TXBL (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_I2C1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C1TXBL (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_IADC0IADC_SCAN (FIELD_PREP(DMA_SRC_MASK, 10) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_IADC0IADC_SINGLE (FIELD_PREP(DMA_SRC_MASK, 10) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_MSCWDATA (FIELD_PREP(DMA_SRC_MASK, 11) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC0 (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC1 (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER2CC2 (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER2UFOF (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER3CC0 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER3CC1 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER3CC2 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER3UFOF (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER4CC0 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER4CC1 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER4CC2 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER4UFOF (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_VDAC0CH0_REQ (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_VDAC0CH1_REQ (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_EUSART0RXFL (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUSART0TXFL (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_EUSART1RXFL (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUSART1TXFL (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_EUSART2RXFL (FIELD_PREP(DMA_SRC_MASK, 18) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUSART2TXFL (FIELD_PREP(DMA_SRC_MASK, 18) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_LESENSEFIFO (FIELD_PREP(DMA_SRC_MASK, 19) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LCD (FIELD_PREP(DMA_SRC_MASK, 20) | FIELD_PREP(DMA_SIG_MASK, 0)) + +#endif ZEPHYR_INCLUDE_DT_BINDINGS_XG23_DMA_H_ diff --git a/include/zephyr/dt-bindings/dma/silabs/xg24-dma.h b/include/zephyr/dt-bindings/dma/silabs/xg24-dma.h new file mode 100644 index 0000000000000..a4067f79711a7 --- /dev/null +++ b/include/zephyr/dt-bindings/dma/silabs/xg24-dma.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_XG24_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_XG24_DMA_H_ + +#include +#include "common-dma.h" + +/** + * Definition of Silabs LDMA request signal + */ +#define DMA_REQSEL_NONE (FIELD_PREP(DMA_SRC_MASK, 0) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ0 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ1 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC0 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER0CC1 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC2 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER0UFOF (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER1CC0 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER1CC1 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER1CC2 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER1UFOF (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART0RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART0TXBL (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART0TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_I2C0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C0TXBL (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_I2C1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C1TXBL (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_IADC0IADC_SCAN (FIELD_PREP(DMA_SRC_MASK, 10) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_IADC0IADC_SINGLE (FIELD_PREP(DMA_SRC_MASK, 10) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_MSCWDATA (FIELD_PREP(DMA_SRC_MASK, 11) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC0 (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC1 (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER2CC2 (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER2UFOF (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER3CC0 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER3CC1 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER3CC2 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER3UFOF (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER4CC0 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER4CC1 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER4CC2 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER4UFOF (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_EUSART0RXFL (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUSART0TXFL (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_EUSART1RXFL (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUSART1TXFL (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_VDAC0CH0_REQ (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_VDAC0CH1_REQ (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_VDAC1CH0_REQ (FIELD_PREP(DMA_SRC_MASK, 18) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_VDAC1CH1_REQ (FIELD_PREP(DMA_SRC_MASK, 18) | FIELD_PREP(DMA_SIG_MASK, 1)) + +#endif ZEPHYR_INCLUDE_DT_BINDINGS_XG24_DMA_H_ diff --git a/include/zephyr/dt-bindings/dma/silabs/xg27-dma.h b/include/zephyr/dt-bindings/dma/silabs/xg27-dma.h new file mode 100644 index 0000000000000..1da99664edf9b --- /dev/null +++ b/include/zephyr/dt-bindings/dma/silabs/xg27-dma.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_XG27_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_XG27_DMA_H_ + +#include +#include "common-dma.h" + +/** + * Definition of Silabs LDMA request signal + */ +#define DMA_REQSEL_NONE (FIELD_PREP(DMA_SRC_MASK, 0) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ0 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ1 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC0 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER0CC1 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC2 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER0UFOF (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER1CC0 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER1CC1 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER1CC2 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER1UFOF (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART0RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART0TXBL (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART0TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_USART1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART1RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART1TXBL (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART1TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART1TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_I2C0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C0TXBL (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_I2C1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 7) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C1TXBL (FIELD_PREP(DMA_SRC_MASK, 7) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_IADC0IADC_SCAN (FIELD_PREP(DMA_SRC_MASK, 11) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_IADC0IADC_SINGLE (FIELD_PREP(DMA_SRC_MASK, 11) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_MSCWDATA (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC0 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC1 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER2CC2 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER2UFOF (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER3CC0 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER3CC1 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER3CC2 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER3UFOF (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_PDMRXDATAV (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER4CC0 (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER4CC1 (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER4CC2 (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER4UFOF (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_EUSART0RXFL (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUSART0TXFL (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 1)) + +#endif ZEPHYR_INCLUDE_DT_BINDINGS_XG27_DMA_H_ diff --git a/include/zephyr/dt-bindings/dma/silabs/xg29-dma.h b/include/zephyr/dt-bindings/dma/silabs/xg29-dma.h new file mode 100644 index 0000000000000..2622b211ca53c --- /dev/null +++ b/include/zephyr/dt-bindings/dma/silabs/xg29-dma.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_XG29_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_XG29_DMA_H_ + +#include +#include "common-dma.h" + +/** + * Definition of Silabs LDMA request signal + */ +#define DMA_REQSEL_NONE (FIELD_PREP(DMA_SRC_MASK, 0) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ0 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_LDMAXBARPRSREQ1 (FIELD_PREP(DMA_SRC_MASK, 1) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC0 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER0CC1 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER0CC2 (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER0UFOF (FIELD_PREP(DMA_SRC_MASK, 2) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER1CC0 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER1CC1 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER1CC2 (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER1UFOF (FIELD_PREP(DMA_SRC_MASK, 3) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART0RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART0TXBL (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART0TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART0TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 4) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_USART1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_USART1RXDATAVRIGHT (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_USART1TXBL (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_USART1TXBLRIGHT (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_USART1TXEMPTY (FIELD_PREP(DMA_SRC_MASK, 5) | FIELD_PREP(DMA_SIG_MASK, 4)) +#define DMA_REQSEL_I2C0RXDATAV (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C0TXBL (FIELD_PREP(DMA_SRC_MASK, 6) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_I2C1RXDATAV (FIELD_PREP(DMA_SRC_MASK, 7) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_I2C1TXBL (FIELD_PREP(DMA_SRC_MASK, 7) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_IADC0IADC_SCAN (FIELD_PREP(DMA_SRC_MASK, 11) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_IADC0IADC_SINGLE (FIELD_PREP(DMA_SRC_MASK, 11) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_MSCWDATA (FIELD_PREP(DMA_SRC_MASK, 12) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC0 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER2CC1 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER2CC2 (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER2UFOF (FIELD_PREP(DMA_SRC_MASK, 13) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_TIMER3CC0 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER3CC1 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER3CC2 (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER3UFOF (FIELD_PREP(DMA_SRC_MASK, 14) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_PDMRXDATAV (FIELD_PREP(DMA_SRC_MASK, 15) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER4CC0 (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_TIMER4CC1 (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_TIMER4CC2 (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 2)) +#define DMA_REQSEL_TIMER4UFOF (FIELD_PREP(DMA_SRC_MASK, 16) | FIELD_PREP(DMA_SIG_MASK, 3)) +#define DMA_REQSEL_EUSART0RXFL (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUSART0TXFL (FIELD_PREP(DMA_SRC_MASK, 17) | FIELD_PREP(DMA_SIG_MASK, 1)) +#define DMA_REQSEL_EUSART1RXFL (FIELD_PREP(DMA_SRC_MASK, 18) | FIELD_PREP(DMA_SIG_MASK, 0)) +#define DMA_REQSEL_EUSART1TXFL (FIELD_PREP(DMA_SRC_MASK, 18) | FIELD_PREP(DMA_SIG_MASK, 1)) + +#endif ZEPHYR_INCLUDE_DT_BINDINGS_XG29_DMA_H_ diff --git a/include/zephyr/dt-bindings/gpio/ene-kb1200-gpio.h b/include/zephyr/dt-bindings/gpio/ene-kb1200-gpio.h new file mode 100644 index 0000000000000..f6ca127081fa5 --- /dev/null +++ b/include/zephyr/dt-bindings/gpio/ene-kb1200-gpio.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 ENE Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_ENE_KB1200_GPIO_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_ENE_KB1200_GPIO_H_ + +/** + * @name GPIO pin voltage flags + * + * The voltage and driving flags are a Zephyr specific extension of the standard GPIO flags + * specified by the Linux GPIO binding for use with the ENE KB1200 SoC. + * + * @{ + * Note: Bits 15 down to 8 are reserved for SoC specific flags. + */ + +/** @cond INTERNAL_HIDDEN */ +#define KB1200_GPIO_VOLTAGE_POS 8 +#define KB1200_GPIO_VOLTAGE_MASK (1U << KB1200_GPIO_VOLTAGE_POS) + +#define KB1200_GPIO_DRIVING_POS 9 +#define KB1200_GPIO_DRIVING_MASK (1U << KB1200_GPIO_DRIVING_POS) +/** @endcond */ + +/** Set pin at the default voltage level (3.3V) */ +#define KB1200_GPIO_VOLTAGE_DEFAULT (0U << KB1200_GPIO_VOLTAGE_POS) +/** Set pin voltage level at 1.8 V */ +#define KB1200_GPIO_VOLTAGE_1P8 (1U << KB1200_GPIO_VOLTAGE_POS) + +/** Set pin at the default driving current (4mA) */ +#define KB1200_GPIO_DRIVING_DEFAULT (0U << KB1200_GPIO_DRIVING_POS) +/** Set pin driving current at 16mA */ +#define KB1200_GPIO_DRIVING_16MA (1U << KB1200_GPIO_DRIVING_POS) + + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_ENE_KB1200_GPIO_H_ */ diff --git a/include/zephyr/dt-bindings/gpio/realtek-gpio.h b/include/zephyr/dt-bindings/gpio/realtek-gpio.h new file mode 100644 index 0000000000000..9b346f4301be4 --- /dev/null +++ b/include/zephyr/dt-bindings/gpio/realtek-gpio.h @@ -0,0 +1,23 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_REALTEK_GPIO_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_REALTEK_GPIO_H_ + +#define RTS5912_GPIO_VOLTAGE_POS 11 +#define RTS5912_GPIO_VOLTAGE_MASK (3U << RTS5912_GPIO_VOLTAGE_POS) + +/** Set pin at the default voltage level */ +#define RTS5912_GPIO_VOLTAGE_DEFAULT (0U << RTS5912_GPIO_VOLTAGE_POS) +/** Set pin voltage level at 1.8 V */ +#define RTS5912_GPIO_VOLTAGE_1V8 (1U << RTS5912_GPIO_VOLTAGE_POS) +/** Set pin voltage level at 3.3 V */ +#define RTS5912_GPIO_VOLTAGE_3V3 (2U << RTS5912_GPIO_VOLTAGE_POS) +/** Set pin voltage level at 5.0 V */ +#define RTS5912_GPIO_VOLTAGE_5V0 (3U << RTS5912_GPIO_VOLTAGE_POS) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_REALTEK_GPIO_H_ */ diff --git a/include/zephyr/dt-bindings/gpio/renesas-rz-gpio.h b/include/zephyr/dt-bindings/gpio/renesas-rz-gpio.h new file mode 100644 index 0000000000000..30729af98bd3b --- /dev/null +++ b/include/zephyr/dt-bindings/gpio/renesas-rz-gpio.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZ_GPIO_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZ_GPIO_H_ + +/*********************************RZG3S*****************************************/ + +/** + * @brief RZ G3S specific GPIO Flags + * The pin driving ability flags are encoded in the 8 upper bits of @ref gpio_dt_flags_t as + * follows: + * - Bit 9..8: Pin driving ability value + * - Bit 11..10: Digital Noise Filter Clock Selection value + * - Bit 13..12: Digital Noise Filter Number value + * - Bit 14: Digital Noise Filter ON/OFF + * example: + * gpio-consumer { + * out-gpios = <&port8 2 (GPIO_PULL_UP | RZG3S_GPIO_FILTER_SET(1, 3, 3))>; + * }; + * gpio-consumer { + * out-gpios = <&port8 2 (GPIO_PULL_UP | RZG3S_GPIO_IOLH_SET(2))>; + * }; + */ + +/* GPIO drive IOLH */ +#define RZG3S_GPIO_IOLH_SHIFT 7U +#define RZG3S_GPIO_IOLH_SET(iolh_val) (iolh_val << RZG3S_GPIO_IOLH_SHIFT) + +/* GPIO filter */ +#define RZG3S_GPIO_FILTER_SHIFT 9U +#define RZG3S_GPIO_FILNUM_SHIFT 1U +#define RZG3S_GPIO_FILCLKSEL_SHIFT 3U +#define RZG3S_GPIO_FILTER_SET(fillonoff, filnum, filclksel) \ + (((fillonoff) | ((filnum) << RZG3S_GPIO_FILNUM_SHIFT) | \ + ((filclksel) << RZG3S_GPIO_FILCLKSEL_SHIFT)) \ + << RZG3S_GPIO_FILTER_SHIFT) + +/*******************************************************************************/ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZ_GPIO_H_ */ diff --git a/include/zephyr/dt-bindings/gpio/stm32-gpio.h b/include/zephyr/dt-bindings/gpio/stm32-gpio.h index f9a3a4b60af6c..3a31bbc60e0b1 100644 --- a/include/zephyr/dt-bindings/gpio/stm32-gpio.h +++ b/include/zephyr/dt-bindings/gpio/stm32-gpio.h @@ -14,6 +14,7 @@ * follows: * * - Bit 8: Configure a GPIO pin to power on the system after Poweroff. + * - Bit 10..9: Configure the output speed of a GPIO pin. * * @ingroup gpio_interface * @{ @@ -24,7 +25,24 @@ * This flag is reserved to GPIO pins that are associated with wake-up pins * in STM32 PWR devicetree node, through the property "wkup-gpios". */ -#define STM32_GPIO_WKUP (1 << 8) +#define STM32_GPIO_WKUP (1 << 8) + +/** @cond INTERNAL_HIDDEN */ +#define STM32_GPIO_SPEED_SHIFT 9 +#define STM32_GPIO_SPEED_MASK 0x3 +/** @endcond */ + +/** Configure the GPIO pin output speed to be low */ +#define STM32_GPIO_LOW_SPEED (0x0 << STM32_GPIO_SPEED_SHIFT) + +/** Configure the GPIO pin output speed to be medium */ +#define STM32_GPIO_MEDIUM_SPEED (0x1 << STM32_GPIO_SPEED_SHIFT) + +/** Configure the GPIO pin output speed to be high */ +#define STM32_GPIO_HIGH_SPEED (0x2 << STM32_GPIO_SPEED_SHIFT) + +/** Configure the GPIO pin output speed to be very high */ +#define STM32_GPIO_VERY_HIGH_SPEED (0x3 << STM32_GPIO_SPEED_SHIFT) /** @} */ diff --git a/include/zephyr/dt-bindings/i2c/npcx-i2c.h b/include/zephyr/dt-bindings/i2c/npcx-i2c.h new file mode 100644 index 0000000000000..fc46fbf55fd07 --- /dev/null +++ b/include/zephyr/dt-bindings/i2c/npcx-i2c.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_I2C_NPCX_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_I2C_NPCX_H_ + + +#define NPCX_I2C_CTRL_PORT(ctrl, port) (((ctrl & 0xf) << 4) | (port & 0xf)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_I2C_NPCX_H_ */ diff --git a/include/zephyr/dt-bindings/memory-controller/renesas,ra-sdram.h b/include/zephyr/dt-bindings/memory-controller/renesas,ra-sdram.h new file mode 100644 index 0000000000000..2e443cc8a8852 --- /dev/null +++ b/include/zephyr/dt-bindings/memory-controller/renesas,ra-sdram.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MEMORY_CONTROLLER_RENESAS_RA_SDRAM_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MEMORY_CONTROLLER_RENESAS_RA_SDRAM_H_ + +#define SDRAM_TRAS_1CYCLES (1) +#define SDRAM_TRAS_2CYCLES (2) +#define SDRAM_TRAS_3CYCLES (3) +#define SDRAM_TRAS_4CYCLES (4) +#define SDRAM_TRAS_5CYCLES (5) +#define SDRAM_TRAS_6CYCLES (6) +#define SDRAM_TRAS_7CYCLES (7) + +#define SDRAM_TRCD_1CYCLES (1) +#define SDRAM_TRCD_2CYCLES (2) +#define SDRAM_TRCD_3CYCLES (3) +#define SDRAM_TRCD_4CYCLES (4) + +#define SDRAM_TRP_1CYCLES (1) +#define SDRAM_TRP_2CYCLES (2) +#define SDRAM_TRP_3CYCLES (3) +#define SDRAM_TRP_4CYCLES (4) +#define SDRAM_TRP_5CYCLES (5) +#define SDRAM_TRP_6CYCLES (6) +#define SDRAM_TRP_7CYCLES (7) +#define SDRAM_TRP_8CYCLES (8) + +#define SDRAM_TWR_1CYCLES (1) +#define SDRAM_TWR_2CYCLES (2) + +#define SDRAM_TCL_1CYCLES (1) +#define SDRAM_TCL_2CYCLES (2) +#define SDRAM_TCL_3CYCLES (3) + +#define SDRAM_TREFW_1CYCLES (1) +#define SDRAM_TREFW_2CYCLES (2) +#define SDRAM_TREFW_3CYCLES (3) +#define SDRAM_TREFW_4CYCLES (4) +#define SDRAM_TREFW_5CYCLES (5) +#define SDRAM_TREFW_6CYCLES (6) +#define SDRAM_TREFW_7CYCLES (7) +#define SDRAM_TREFW_8CYCLES (8) +#define SDRAM_TREFW_9CYCLES (9) +#define SDRAM_TREFW_10CYCLES (10) +#define SDRAM_TREFW_11CYCLES (11) +#define SDRAM_TREFW_12CYCLES (12) +#define SDRAM_TREFW_13CYCLES (13) +#define SDRAM_TREFW_14CYCLES (14) +#define SDRAM_TREFW_15CYCLES (15) +#define SDRAM_TREFW_16CYCLES (16) + +#define SDRAM_AUTO_REFREDSH_INTERVEL_3CYCLES (3) +#define SDRAM_AUTO_REFREDSH_INTERVEL_4CYCLES (4) +#define SDRAM_AUTO_REFREDSH_INTERVEL_5CYCLES (5) +#define SDRAM_AUTO_REFREDSH_INTERVEL_6CYCLES (6) +#define SDRAM_AUTO_REFREDSH_INTERVEL_7CYCLES (7) +#define SDRAM_AUTO_REFREDSH_INTERVEL_8CYCLES (8) +#define SDRAM_AUTO_REFREDSH_INTERVEL_9CYCLES (9) +#define SDRAM_AUTO_REFREDSH_INTERVEL_10CYCLES (10) +#define SDRAM_AUTO_REFREDSH_INTERVEL_11CYCLES (11) +#define SDRAM_AUTO_REFREDSH_INTERVEL_12CYCLES (12) +#define SDRAM_AUTO_REFREDSH_INTERVEL_13CYCLES (13) +#define SDRAM_AUTO_REFREDSH_INTERVEL_14CYCLES (14) +#define SDRAM_AUTO_REFREDSH_INTERVEL_15CYCLES (15) +#define SDRAM_AUTO_REFREDSH_INTERVEL_16CYCLES (16) +#define SDRAM_AUTO_REFREDSH_INTERVEL_17CYCLES (17) +#define SDRAM_AUTO_REFREDSH_INTERVEL_18CYCLES (18) +#define SDRAM_AUTO_REFREDSH_INTERVEL_19CYCLES (19) +#define SDRAM_AUTO_REFREDSH_INTERVEL_20CYCLES (20) + +#define SDRAM_AUTO_REFREDSH_COUNT_1TIMES (1) +#define SDRAM_AUTO_REFREDSH_COUNT_2TIMES (2) +#define SDRAM_AUTO_REFREDSH_COUNT_3TIMES (3) +#define SDRAM_AUTO_REFREDSH_COUNT_4TIMES (4) +#define SDRAM_AUTO_REFREDSH_COUNT_5TIMES (5) +#define SDRAM_AUTO_REFREDSH_COUNT_6TIMES (6) +#define SDRAM_AUTO_REFREDSH_COUNT_7TIMES (7) +#define SDRAM_AUTO_REFREDSH_COUNT_8TIMES (8) +#define SDRAM_AUTO_REFREDSH_COUNT_9TIMES (9) +#define SDRAM_AUTO_REFREDSH_COUNT_10TIMES (10) +#define SDRAM_AUTO_REFREDSH_COUNT_11TIMES (11) +#define SDRAM_AUTO_REFREDSH_COUNT_12TIMES (12) +#define SDRAM_AUTO_REFREDSH_COUNT_13TIMES (13) +#define SDRAM_AUTO_REFREDSH_COUNT_14TIMES (14) +#define SDRAM_AUTO_REFREDSH_COUNT_15TIMES (15) + +#define SDRAM_AUTO_PRECHARGE_CYCLE_3CYCLES (3) +#define SDRAM_AUTO_PRECHARGE_CYCLE_4CYCLES (4) +#define SDRAM_AUTO_PRECHARGE_CYCLE_5CYCLES (5) +#define SDRAM_AUTO_PRECHARGE_CYCLE_6CYCLES (6) +#define SDRAM_AUTO_PRECHARGE_CYCLE_7CYCLES (7) +#define SDRAM_AUTO_PRECHARGE_CYCLE_8CYCLES (8) +#define SDRAM_AUTO_PRECHARGE_CYCLE_9CYCLES (9) +#define SDRAM_AUTO_PRECHARGE_CYCLE_10CYCLES (10) + +#endif diff --git a/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h b/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h index 25886635f5962..cb3eae16512db 100644 --- a/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h +++ b/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h @@ -20,15 +20,15 @@ * command or data byte * * - * .---. .---. .---. .---. .---. .---. .---. .---. - * SCK -' '---' '---' '---' '---' '---' '---' '---' '--- + * .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .- + * SCK -' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' * - * -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. + * -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.- * DOUT |D/C| D7| D6| D5| D4| D3| D2| D1| D0|D/C| D7| D6| D5| D4|...| - * -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---' + * -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'- * | Word 1 | Word n * - * -. .-- + * -. .- * CS '-----------------------------------------------------------' */ #define MIPI_DBI_MODE_SPI_3WIRE 0x1 @@ -37,15 +37,15 @@ * an additional C/D pin will be use to indicate whether the byte is a * command or data byte * - * .---. .---. .---. .---. .---. .---. .---. .---. - * SCK -' '---' '---' '---' '---' '---' '---' '---' '--- + * .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. + * SCK -' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '--- * - * -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. + * -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.- * DOUT | D7| D6| D5| D4| D3| D2| D1| D0| D7| D6| D5| D4| D3| D2| D1| D0| - * -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---' + * -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'- * | Word 1 | Word n * - * -. .-- + * -. .- * CS '---------------------------------------------------------------' * * -.-------------------------------.-------------------------------.- @@ -110,6 +110,68 @@ #define MIPI_DBI_MODE_8080_BUS_9_BIT 0x7 #define MIPI_DBI_MODE_8080_BUS_8_BIT 0x8 +/** MIPI DBI tearing enable synchronization is disabled. */ +#define MIPI_DBI_TE_NO_EDGE 0x0 + +/** + * MIPI DBI tearing enable synchronization on rising edge of TE signal. + * The controller will only send display write data on a rising edge of TE. + * This should be used when the controller can send a frame worth of data + * data to the display panel faster than the display panel can read a frame + * from its RAM + * + * .------. .------. + * TE -----' '------------------------' '------------- + * -----. .----------------------. + * CS '--------' '-------------------- + */ +#define MIPI_DBI_TE_RISING_EDGE 0x1 + +/** + * MIPI DBI tearing enable synchronization on falling edge of TE signal. + * The controller will only send display write data on a falling edge of TE. + * This should be used when the controller sends a frame worth of data + * data to the display panel slower than the display panel can read a frame + * from its RAM. TE synchronization in this mode will only work if the + * controller can complete the write before the display panel completes 2 + * read cycles, otherwise the read pointer will "catch up" with the write + * pointer. + * + * .------. .------. + * TE -----' '------------------------' '------------- + * ------------. .----- + * CS '---------------------------------------' + */ +#define MIPI_DBI_TE_FALLING_EDGE 0x2 + +/** + * SPI transfer of DBI commands as 8-bit blocks, the default behaviour in + * SPI 4 wire (Type C3) mode. The clocking diagram corresponds exactly to + * the illustration of Type C3. + */ +#define MIPI_DBI_SPI_XFR_8BIT 8 +/** + * SPI transfer of DBI commands as 16-bit blocks, a rare and seldom behaviour + * in SPI 4 wire (Type C3) mode. The corresponding clocking diagram is slightly + * different to the illustration of Type C3. + * + * .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. + * SCK -' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '--- + * + * -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.- + * DOUT |D15|D14|D13|D12|D11|D10| D9| D8| D7| D6| D5| D4| D3| D2| D1| D0| + * -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'- + * | Word 1 (stuffing) : (byte) | + * + * -. .- + * CS '---------------------------------------------------------------' + * + * -.---------------------------------------------------------------.- + * CD | D/C | + * -'---------------------------------------------------------------'- + */ +#define MIPI_DBI_SPI_XFR_16BIT 16 + /** * @} */ diff --git a/include/zephyr/dt-bindings/pinctrl/cc23x0-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/cc23x0-pinctrl.h new file mode 100644 index 0000000000000..1c365965c9df5 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/cc23x0-pinctrl.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CC23X0_PINCTRL_COMMON_H_ +#define CC23X0_PINCTRL_COMMON_H_ + +/* + * The whole TI CC23X0 pin configuration information is encoded in a 32-bit + * bitfield organized as follow: + * + * - 31: Reserved + * - 30: Input hysteresis + * - 29: Input capability of IO + * - 28..27: Reserved + * - 26..24: IO mode + * - 23..22: Reserved + * - 21..20: Wakeup configuration from shutdown + * - 19: Reserved + * - 18: Wakeup capability from standby + * - 17..16: Edge detection configuration + * - 15: Reserved + * - 14..13: Pull control + * - 12..3: Reserved + * - 2..0: Function configuration + */ + +/* TI CC23X0 function configuration */ + +#define IOC_PORTCFG_BASE 0U +#define IOC_PORTCFG_PFUNC1 1U +#define IOC_PORTCFG_PFUNC2 2U +#define IOC_PORTCFG_PFUNC3 3U +#define IOC_PORTCFG_PFUNC4 4U +#define IOC_PORTCFG_PFUNC5 5U +#define IOC_PORTCFG_ANA 6U +#define IOC_PORTCFG_DTB 7U + +/* TI CC23X0 peripheral pin mapping */ + +#define DIO0_GPIO0 IOC_PORTCFG_BASE +#define DIO0_SPI0_CSN IOC_PORTCFG_PFUNC1 +#define DIO0_I2C0_SDA IOC_PORTCFG_PFUNC2 +#define DIO0_T3_C2 IOC_PORTCFG_PFUNC3 +#define DIO0_ADC5 IOC_PORTCFG_ANA + +#define DIO1_GPIO1 IOC_PORTCFG_BASE +#define DIO1_T3_C1 IOC_PORTCFG_PFUNC1 +#define DIO1_LRFD7 IOC_PORTCFG_PFUNC2 +#define DIO1_T1_F IOC_PORTCFG_PFUNC3 +#define DIO1_UART0_RTS IOC_PORTCFG_PFUNC4 +#define DIO1_ADC4 IOC_PORTCFG_ANA +#define DIO1_DTB2 IOC_PORTCFG_DTB + +#define DIO2_GPIO2 IOC_PORTCFG_BASE +#define DIO2_T0_PE IOC_PORTCFG_PFUNC1 +#define DIO2_T2_C1N IOC_PORTCFG_PFUNC2 +#define DIO2_UART0_CTS IOC_PORTCFG_PFUNC3 +#define DIO2_ADC3 IOC_PORTCFG_ANA + +#define DIO3_GPIO3 IOC_PORTCFG_BASE +#define DIO3_LFCI IOC_PORTCFG_PFUNC1 +#define DIO3_T0_C1N IOC_PORTCFG_PFUNC2 +#define DIO3_LRFD0 IOC_PORTCFG_PFUNC3 +#define DIO3_T3_C1 IOC_PORTCFG_PFUNC4 +#define DIO3_T1_C2 IOC_PORTCFG_PFUNC5 +#define DIO3_LFXT_P IOC_PORTCFG_ANA +#define DIO3_DTB7 IOC_PORTCFG_DTB + +#define DIO4_GPIO4 IOC_PORTCFG_BASE +#define DIO4_T0_C2N IOC_PORTCFG_PFUNC1 +#define DIO4_UART0_TXD IOC_PORTCFG_PFUNC2 +#define DIO4_LRFD1 IOC_PORTCFG_PFUNC3 +#define DIO4_SPI0_MOSI IOC_PORTCFG_PFUNC4 +#define DIO4_T0_C2 IOC_PORTCFG_PFUNC5 +#define DIO4_LFXT_N IOC_PORTCFG_ANA +#define DIO4_DTB8 IOC_PORTCFG_DTB + +#define DIO5_GPIO5 IOC_PORTCFG_BASE +#define DIO5_T2_C2 IOC_PORTCFG_PFUNC1 +#define DIO5_LRFD6 IOC_PORTCFG_PFUNC3 +#define DIO5_ADC2 IOC_PORTCFG_ANA + +#define DIO6_GPIO6 IOC_PORTCFG_BASE +#define DIO6_SPI0_CSN IOC_PORTCFG_PFUNC1 +#define DIO6_I2C0_SCL IOC_PORTCFG_PFUNC2 +#define DIO6_T1_C2 IOC_PORTCFG_PFUNC3 +#define DIO6_LRFD2 IOC_PORTCFG_PFUNC4 +#define DIO6_UART0_TXD IOC_PORTCFG_PFUNC5 +#define DIO6_ADC1_AREFP IOC_PORTCFG_ANA +#define DIO6_DTB6 IOC_PORTCFG_DTB + +#define DIO7_GPIO7 IOC_PORTCFG_BASE +#define DIO7_T3_C1 IOC_PORTCFG_PFUNC1 +#define DIO7_LRFD4 IOC_PORTCFG_PFUNC3 +#define DIO7_ADC0_AREFM IOC_PORTCFG_ANA + +#define DIO8_GPIO8 IOC_PORTCFG_BASE +#define DIO8_SPI0_SCLK IOC_PORTCFG_PFUNC1 +#define DIO8_UART0_RTS IOC_PORTCFG_PFUNC2 +#define DIO8_T1_C0N IOC_PORTCFG_PFUNC3 +#define DIO8_I2C0_SDA IOC_PORTCFG_PFUNC4 +#define DIO8_T0_C0N IOC_PORTCFG_PFUNC5 +#define DIO8_DTB3 IOC_PORTCFG_DTB + +#define DIO9_GPIO9 IOC_PORTCFG_BASE +#define DIO9_T3_C0 IOC_PORTCFG_PFUNC1 +#define DIO9_LRFD3 IOC_PORTCFG_PFUNC3 + +#define DIO10_GPIO10 IOC_PORTCFG_BASE +#define DIO10_LPC0 IOC_PORTCFG_PFUNC1 +#define DIO10_T2_PE IOC_PORTCFG_PFUNC2 +#define DIO10_T3_C0N IOC_PORTCFG_PFUNC3 + +#define DIO11_GPIO11 IOC_PORTCFG_BASE +#define DIO11_SPI0_CSN IOC_PORTCFG_PFUNC1 +#define DIO11_T1_C2N IOC_PORTCFG_PFUNC2 +#define DIO11_T0_C0 IOC_PORTCFG_PFUNC3 +#define DIO11_LRFD0 IOC_PORTCFG_PFUNC4 +#define DIO11_SPI0_MISO IOC_PORTCFG_PFUNC5 +#define DIO11_DTB9 IOC_PORTCFG_DTB + +#define DIO12_GPIO12 IOC_PORTCFG_BASE +#define DIO12_SPI0_MISO IOC_PORTCFG_PFUNC1 +#define DIO12_SPI0_MOSI IOC_PORTCFG_PFUNC2 +#define DIO12_UART0_RXD IOC_PORTCFG_PFUNC3 +#define DIO12_T1_C1 IOC_PORTCFG_PFUNC4 +#define DIO12_I2C0_SDA IOC_PORTCFG_PFUNC5 +#define DIO12_DTB13 IOC_PORTCFG_DTB + +#define DIO13_GPIO13 IOC_PORTCFG_BASE +#define DIO13_SPI0_MISO IOC_PORTCFG_PFUNC1 +#define DIO13_SPI0_MOSI IOC_PORTCFG_PFUNC2 +#define DIO13_UART0_TXD IOC_PORTCFG_PFUNC3 +#define DIO13_T0_C0N IOC_PORTCFG_PFUNC4 +#define DIO13_T1_F IOC_PORTCFG_PFUNC5 +#define DIO13_DTB4 IOC_PORTCFG_DTB + +#define DIO14_GPIO14 IOC_PORTCFG_BASE +#define DIO14_T3_C2 IOC_PORTCFG_PFUNC1 +#define DIO14_T1_C2N IOC_PORTCFG_PFUNC2 +#define DIO14_LRFD5 IOC_PORTCFG_PFUNC3 +#define DIO14_T1_F IOC_PORTCFG_PFUNC4 + +#define DIO15_GPIO15 IOC_PORTCFG_BASE +#define DIO15_UART0_RXD IOC_PORTCFG_PFUNC1 +#define DIO15_T2_C0N IOC_PORTCFG_PFUNC2 +#define DIO15_CKMIN IOC_PORTCFG_PFUNC3 + +#define DIO16_GPIO16 IOC_PORTCFG_BASE +#define DIO16_SPI0_MOSI IOC_PORTCFG_PFUNC1 +#define DIO16_UART0_RXD IOC_PORTCFG_PFUNC2 +#define DIO16_I2C0_SDA IOC_PORTCFG_PFUNC3 +#define DIO16_T1_C2 IOC_PORTCFG_PFUNC4 +#define DIO16_T1_C0N IOC_PORTCFG_PFUNC5 +#define DIO16_DTB10 IOC_PORTCFG_DTB + +#define DIO17_GPIO17 IOC_PORTCFG_BASE +#define DIO17_SPI0_SCLK IOC_PORTCFG_PFUNC1 +#define DIO17_UART0_TXD IOC_PORTCFG_PFUNC2 +#define DIO17_I2C0_SCL IOC_PORTCFG_PFUNC3 +#define DIO17_T1_C1N IOC_PORTCFG_PFUNC4 +#define DIO17_T0_C2 IOC_PORTCFG_PFUNC5 +#define DIO17_DTB11 IOC_PORTCFG_DTB + +#define DIO18_GPIO18 IOC_PORTCFG_BASE +#define DIO18_T3_C0 IOC_PORTCFG_PFUNC1 +#define DIO18_LPC0 IOC_PORTCFG_PFUNC2 +#define DIO18_UART0_TXD IOC_PORTCFG_PFUNC3 +#define DIO18_SPI0_SCLK IOC_PORTCFG_PFUNC4 +#define DIO18_DTB12 IOC_PORTCFG_DTB + +#define DIO19_GPIO19 IOC_PORTCFG_BASE +#define DIO19_T3_C1 IOC_PORTCFG_PFUNC1 +#define DIO19_T2_PE IOC_PORTCFG_PFUNC2 +#define DIO19_SPI0_MOSI IOC_PORTCFG_PFUNC4 +#define DIO19_DTB0 IOC_PORTCFG_DTB + +#define DIO20_GPIO20 IOC_PORTCFG_BASE +#define DIO20_LPC0 IOC_PORTCFG_PFUNC1 +#define DIO20_UART0_TXD IOC_PORTCFG_PFUNC2 +#define DIO20_UART0_RXD IOC_PORTCFG_PFUNC3 +#define DIO20_T1_C0 IOC_PORTCFG_PFUNC4 +#define DIO20_SPI0_MISO IOC_PORTCFG_PFUNC5 +#define DIO20_ADC11 IOC_PORTCFG_ANA +#define DIO20_DTB14 IOC_PORTCFG_DTB + +#define DIO21_GPIO21 IOC_PORTCFG_BASE +#define DIO21_UART0_CTS IOC_PORTCFG_PFUNC1 +#define DIO21_T1_C1N IOC_PORTCFG_PFUNC2 +#define DIO21_T0_C1 IOC_PORTCFG_PFUNC3 +#define DIO21_SPI0_MISO IOC_PORTCFG_PFUNC4 +#define DIO21_LRFD1 IOC_PORTCFG_PFUNC5 +#define DIO21_ADC10_LPCP IOC_PORTCFG_ANA +#define DIO21_DTB15 IOC_PORTCFG_DTB + +#define DIO22_GPIO22 IOC_PORTCFG_BASE +#define DIO22_T2_C0 IOC_PORTCFG_PFUNC1 +#define DIO22_UART0_RXD IOC_PORTCFG_PFUNC2 +#define DIO22_T3_C1N IOC_PORTCFG_PFUNC3 +#define DIO22_ADC9 IOC_PORTCFG_ANA +#define DIO22_DTB1 IOC_PORTCFG_DTB + +#define DIO23_GPIO23 IOC_PORTCFG_BASE +#define DIO23_T2_C1 IOC_PORTCFG_PFUNC1 +#define DIO23_T3_C2N IOC_PORTCFG_PFUNC3 +#define DIO23_ADC8_LPCP_LPCM IOC_PORTCFG_ANA + +#define DIO24_GPIO24 IOC_PORTCFG_BASE +#define DIO24_SPI0_SCLK IOC_PORTCFG_PFUNC1 +#define DIO24_T1_C0 IOC_PORTCFG_PFUNC2 +#define DIO24_T3_C0 IOC_PORTCFG_PFUNC3 +#define DIO24_T0_PE IOC_PORTCFG_PFUNC4 +#define DIO24_I2C0_SCL IOC_PORTCFG_PFUNC5 +#define DIO24_ADC7_LPCP_LPCM IOC_PORTCFG_ANA +#define DIO24_DTB5 IOC_PORTCFG_DTB + +#define DIO25_GPIO25 IOC_PORTCFG_BASE +#define DIO25_SPI0_MISO IOC_PORTCFG_PFUNC1 +#define DIO25_I2C0_SCL IOC_PORTCFG_PFUNC2 +#define DIO25_T2_C2N IOC_PORTCFG_PFUNC3 +#define DIO25_ADC6 IOC_PORTCFG_ANA + +#endif /* CC23X0_PINCTRL_COMMON_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h index f8bb545cca15c..0c606aed6e41c 100644 --- a/include/zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h @@ -17,10 +17,11 @@ */ #define CH32V003_PINMUX_SPI1_RM 0 #define CH32V003_PINMUX_I2C1_RM 1 -#define CH32V003_PINMUX_I2C1_RM1 23 +#define CH32V003_PINMUX_I2C1_RM1 22 #define CH32V003_PINMUX_USART1_RM 2 #define CH32V003_PINMUX_USART1_RM1 21 #define CH32V003_PINMUX_TIM1_RM 6 +#define CH32V003_PINMUX_TIM1_RM1 23 #define CH32V003_PINMUX_TIM2_RM 8 /* Port number with 0-2 */ diff --git a/include/zephyr/dt-bindings/pinctrl/esp32c6-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/esp32c6-pinctrl.h index 6c80beb59d5a7..7ae822da112a0 100644 --- a/include/zephyr/dt-bindings/pinctrl/esp32c6-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/esp32c6-pinctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 * @@ -9,1976 +9,2209 @@ #ifndef INC_DT_BINDS_PINCTRL_ESP32C6_PINCTRL_HAL_H_ #define INC_DT_BINDS_PINCTRL_ESP32C6_PINCTRL_HAL_H_ +/* I2C0_SCL */ +#define I2C0_SCL_GPIO0 \ + ESP32_PINMUX(0, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO1 \ + ESP32_PINMUX(1, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO2 \ + ESP32_PINMUX(2, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO3 \ + ESP32_PINMUX(3, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO4 \ + ESP32_PINMUX(4, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO5 \ + ESP32_PINMUX(5, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO6 \ + ESP32_PINMUX(6, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO7 \ + ESP32_PINMUX(7, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO8 \ + ESP32_PINMUX(8, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO9 \ + ESP32_PINMUX(9, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO10 \ + ESP32_PINMUX(10, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO11 \ + ESP32_PINMUX(11, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO12 \ + ESP32_PINMUX(12, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO13 \ + ESP32_PINMUX(13, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO14 \ + ESP32_PINMUX(14, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO15 \ + ESP32_PINMUX(15, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO16 \ + ESP32_PINMUX(16, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO17 \ + ESP32_PINMUX(17, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO18 \ + ESP32_PINMUX(18, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO19 \ + ESP32_PINMUX(19, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO20 \ + ESP32_PINMUX(20, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO21 \ + ESP32_PINMUX(21, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO22 \ + ESP32_PINMUX(22, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +#define I2C0_SCL_GPIO23 \ + ESP32_PINMUX(23, ESP_I2CEXT0_SCL_IN, ESP_I2CEXT0_SCL_OUT) + +/* I2C0_SDA */ +#define I2C0_SDA_GPIO0 \ + ESP32_PINMUX(0, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO1 \ + ESP32_PINMUX(1, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO2 \ + ESP32_PINMUX(2, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO3 \ + ESP32_PINMUX(3, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO4 \ + ESP32_PINMUX(4, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO5 \ + ESP32_PINMUX(5, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO6 \ + ESP32_PINMUX(6, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO7 \ + ESP32_PINMUX(7, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO8 \ + ESP32_PINMUX(8, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO9 \ + ESP32_PINMUX(9, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO10 \ + ESP32_PINMUX(10, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO11 \ + ESP32_PINMUX(11, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO12 \ + ESP32_PINMUX(12, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO13 \ + ESP32_PINMUX(13, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO14 \ + ESP32_PINMUX(14, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO15 \ + ESP32_PINMUX(15, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO16 \ + ESP32_PINMUX(16, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO17 \ + ESP32_PINMUX(17, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO18 \ + ESP32_PINMUX(18, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO19 \ + ESP32_PINMUX(19, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO20 \ + ESP32_PINMUX(20, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO21 \ + ESP32_PINMUX(21, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO22 \ + ESP32_PINMUX(22, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + +#define I2C0_SDA_GPIO23 \ + ESP32_PINMUX(23, ESP_I2CEXT0_SDA_IN, ESP_I2CEXT0_SDA_OUT) + /* LEDC_CH0 */ -#define LEDC_CH0_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) -#define LEDC_CH0_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) +#define LEDC_CH0_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT0) /* LEDC_CH1 */ -#define LEDC_CH1_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) -#define LEDC_CH1_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) +#define LEDC_CH1_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT1) /* LEDC_CH2 */ -#define LEDC_CH2_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) -#define LEDC_CH2_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) +#define LEDC_CH2_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT2) /* LEDC_CH3 */ -#define LEDC_CH3_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) -#define LEDC_CH3_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) +#define LEDC_CH3_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT3) /* LEDC_CH4 */ -#define LEDC_CH4_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) -#define LEDC_CH4_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) +#define LEDC_CH4_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT4) /* LEDC_CH5 */ -#define LEDC_CH5_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define LEDC_CH5_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +#define LEDC_CH5_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) + +/* MCPWM0_CAP0 */ +#define MCPWM0_CAP0_GPIO0 ESP32_PINMUX(0, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO1 ESP32_PINMUX(1, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO2 ESP32_PINMUX(2, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO3 ESP32_PINMUX(3, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO4 ESP32_PINMUX(4, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO5 ESP32_PINMUX(5, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO6 ESP32_PINMUX(6, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO7 ESP32_PINMUX(7, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO8 ESP32_PINMUX(8, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO9 ESP32_PINMUX(9, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO10 ESP32_PINMUX(10, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO11 ESP32_PINMUX(11, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO12 ESP32_PINMUX(12, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO13 ESP32_PINMUX(13, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO14 ESP32_PINMUX(14, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO15 ESP32_PINMUX(15, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO16 ESP32_PINMUX(16, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO17 ESP32_PINMUX(17, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO18 ESP32_PINMUX(18, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO19 ESP32_PINMUX(19, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO20 ESP32_PINMUX(20, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO21 ESP32_PINMUX(21, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO22 ESP32_PINMUX(22, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +#define MCPWM0_CAP0_GPIO23 ESP32_PINMUX(23, ESP_PWM0_CAP0_IN, ESP_NOSIG) + +/* MCPWM0_CAP1 */ +#define MCPWM0_CAP1_GPIO0 ESP32_PINMUX(0, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO1 ESP32_PINMUX(1, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO2 ESP32_PINMUX(2, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO3 ESP32_PINMUX(3, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO4 ESP32_PINMUX(4, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO5 ESP32_PINMUX(5, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO6 ESP32_PINMUX(6, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO7 ESP32_PINMUX(7, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO8 ESP32_PINMUX(8, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO9 ESP32_PINMUX(9, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO10 ESP32_PINMUX(10, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO11 ESP32_PINMUX(11, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO12 ESP32_PINMUX(12, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO13 ESP32_PINMUX(13, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO14 ESP32_PINMUX(14, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO15 ESP32_PINMUX(15, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO16 ESP32_PINMUX(16, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO17 ESP32_PINMUX(17, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO18 ESP32_PINMUX(18, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO19 ESP32_PINMUX(19, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO20 ESP32_PINMUX(20, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO21 ESP32_PINMUX(21, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO22 ESP32_PINMUX(22, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +#define MCPWM0_CAP1_GPIO23 ESP32_PINMUX(23, ESP_PWM0_CAP1_IN, ESP_NOSIG) + +/* MCPWM0_CAP2 */ +#define MCPWM0_CAP2_GPIO0 ESP32_PINMUX(0, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO1 ESP32_PINMUX(1, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO2 ESP32_PINMUX(2, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO3 ESP32_PINMUX(3, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO4 ESP32_PINMUX(4, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO5 ESP32_PINMUX(5, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO6 ESP32_PINMUX(6, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO7 ESP32_PINMUX(7, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO8 ESP32_PINMUX(8, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO9 ESP32_PINMUX(9, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO10 ESP32_PINMUX(10, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO11 ESP32_PINMUX(11, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO12 ESP32_PINMUX(12, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO13 ESP32_PINMUX(13, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO14 ESP32_PINMUX(14, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO15 ESP32_PINMUX(15, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO16 ESP32_PINMUX(16, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO17 ESP32_PINMUX(17, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO18 ESP32_PINMUX(18, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO19 ESP32_PINMUX(19, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO20 ESP32_PINMUX(20, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO21 ESP32_PINMUX(21, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO22 ESP32_PINMUX(22, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +#define MCPWM0_CAP2_GPIO23 ESP32_PINMUX(23, ESP_PWM0_CAP2_IN, ESP_NOSIG) + +/* MCPWM0_FAULT0 */ +#define MCPWM0_FAULT0_GPIO0 ESP32_PINMUX(0, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO1 ESP32_PINMUX(1, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO2 ESP32_PINMUX(2, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO3 ESP32_PINMUX(3, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO4 ESP32_PINMUX(4, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO5 ESP32_PINMUX(5, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO6 ESP32_PINMUX(6, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO7 ESP32_PINMUX(7, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO8 ESP32_PINMUX(8, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO9 ESP32_PINMUX(9, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO10 ESP32_PINMUX(10, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO11 ESP32_PINMUX(11, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO12 ESP32_PINMUX(12, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO13 ESP32_PINMUX(13, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO14 ESP32_PINMUX(14, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO15 ESP32_PINMUX(15, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO16 ESP32_PINMUX(16, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO17 ESP32_PINMUX(17, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO18 ESP32_PINMUX(18, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO19 ESP32_PINMUX(19, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO20 ESP32_PINMUX(20, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO21 ESP32_PINMUX(21, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO22 ESP32_PINMUX(22, ESP_PWM0_F0_IN, ESP_NOSIG) + +#define MCPWM0_FAULT0_GPIO23 ESP32_PINMUX(23, ESP_PWM0_F0_IN, ESP_NOSIG) + +/* MCPWM0_FAULT1 */ +#define MCPWM0_FAULT1_GPIO0 ESP32_PINMUX(0, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO1 ESP32_PINMUX(1, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO2 ESP32_PINMUX(2, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO3 ESP32_PINMUX(3, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO4 ESP32_PINMUX(4, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO5 ESP32_PINMUX(5, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO6 ESP32_PINMUX(6, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO7 ESP32_PINMUX(7, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO8 ESP32_PINMUX(8, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO9 ESP32_PINMUX(9, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO10 ESP32_PINMUX(10, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO11 ESP32_PINMUX(11, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO12 ESP32_PINMUX(12, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO13 ESP32_PINMUX(13, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO14 ESP32_PINMUX(14, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO15 ESP32_PINMUX(15, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO16 ESP32_PINMUX(16, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO17 ESP32_PINMUX(17, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO18 ESP32_PINMUX(18, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO19 ESP32_PINMUX(19, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO20 ESP32_PINMUX(20, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO21 ESP32_PINMUX(21, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO22 ESP32_PINMUX(22, ESP_PWM0_F1_IN, ESP_NOSIG) + +#define MCPWM0_FAULT1_GPIO23 ESP32_PINMUX(23, ESP_PWM0_F1_IN, ESP_NOSIG) + +/* MCPWM0_FAULT2 */ +#define MCPWM0_FAULT2_GPIO0 ESP32_PINMUX(0, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO1 ESP32_PINMUX(1, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO2 ESP32_PINMUX(2, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO3 ESP32_PINMUX(3, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO4 ESP32_PINMUX(4, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO5 ESP32_PINMUX(5, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO6 ESP32_PINMUX(6, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO7 ESP32_PINMUX(7, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO8 ESP32_PINMUX(8, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO9 ESP32_PINMUX(9, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO10 ESP32_PINMUX(10, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO11 ESP32_PINMUX(11, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO12 ESP32_PINMUX(12, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO13 ESP32_PINMUX(13, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO14 ESP32_PINMUX(14, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO15 ESP32_PINMUX(15, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO16 ESP32_PINMUX(16, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO17 ESP32_PINMUX(17, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO18 ESP32_PINMUX(18, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO19 ESP32_PINMUX(19, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO20 ESP32_PINMUX(20, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO21 ESP32_PINMUX(21, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO22 ESP32_PINMUX(22, ESP_PWM0_F2_IN, ESP_NOSIG) + +#define MCPWM0_FAULT2_GPIO23 ESP32_PINMUX(23, ESP_PWM0_F2_IN, ESP_NOSIG) + +/* MCPWM0_OUT0A */ +#define MCPWM0_OUT0A_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_PWM0_OUT0A) + +#define MCPWM0_OUT0A_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_PWM0_OUT0A) + +/* MCPWM0_OUT0B */ +#define MCPWM0_OUT0B_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_PWM0_OUT0B) + +#define MCPWM0_OUT0B_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_PWM0_OUT0B) + +/* MCPWM0_OUT1A */ +#define MCPWM0_OUT1A_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_PWM0_OUT1A) + +#define MCPWM0_OUT1A_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_PWM0_OUT1A) + +/* MCPWM0_OUT1B */ +#define MCPWM0_OUT1B_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_PWM0_OUT1B) + +#define MCPWM0_OUT1B_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_PWM0_OUT1B) + +/* MCPWM0_OUT2A */ +#define MCPWM0_OUT2A_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_PWM0_OUT2A) + +#define MCPWM0_OUT2A_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_PWM0_OUT2A) + +/* MCPWM0_OUT2B */ +#define MCPWM0_OUT2B_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_PWM0_OUT2B) + +#define MCPWM0_OUT2B_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_PWM0_OUT2B) + +/* MCPWM0_SYNC0 */ +#define MCPWM0_SYNC0_GPIO0 ESP32_PINMUX(0, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO1 ESP32_PINMUX(1, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO2 ESP32_PINMUX(2, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO3 ESP32_PINMUX(3, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO4 ESP32_PINMUX(4, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO5 ESP32_PINMUX(5, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO6 ESP32_PINMUX(6, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO7 ESP32_PINMUX(7, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO8 ESP32_PINMUX(8, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO9 ESP32_PINMUX(9, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO10 ESP32_PINMUX(10, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO11 ESP32_PINMUX(11, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO12 ESP32_PINMUX(12, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO13 ESP32_PINMUX(13, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO14 ESP32_PINMUX(14, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO15 ESP32_PINMUX(15, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO16 ESP32_PINMUX(16, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO17 ESP32_PINMUX(17, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO18 ESP32_PINMUX(18, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO19 ESP32_PINMUX(19, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO20 ESP32_PINMUX(20, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO21 ESP32_PINMUX(21, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO22 ESP32_PINMUX(22, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +#define MCPWM0_SYNC0_GPIO23 ESP32_PINMUX(23, ESP_PWM0_SYNC0_IN, ESP_NOSIG) + +/* MCPWM0_SYNC1 */ +#define MCPWM0_SYNC1_GPIO0 ESP32_PINMUX(0, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO1 ESP32_PINMUX(1, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO2 ESP32_PINMUX(2, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO3 ESP32_PINMUX(3, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO4 ESP32_PINMUX(4, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO5 ESP32_PINMUX(5, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO6 ESP32_PINMUX(6, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO7 ESP32_PINMUX(7, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO8 ESP32_PINMUX(8, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO9 ESP32_PINMUX(9, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO10 ESP32_PINMUX(10, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO11 ESP32_PINMUX(11, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO12 ESP32_PINMUX(12, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO13 ESP32_PINMUX(13, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO14 ESP32_PINMUX(14, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO15 ESP32_PINMUX(15, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO16 ESP32_PINMUX(16, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO17 ESP32_PINMUX(17, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO18 ESP32_PINMUX(18, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO19 ESP32_PINMUX(19, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO20 ESP32_PINMUX(20, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO21 ESP32_PINMUX(21, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO22 ESP32_PINMUX(22, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +#define MCPWM0_SYNC1_GPIO23 ESP32_PINMUX(23, ESP_PWM0_SYNC1_IN, ESP_NOSIG) + +/* MCPWM0_SYNC2 */ +#define MCPWM0_SYNC2_GPIO0 ESP32_PINMUX(0, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO1 ESP32_PINMUX(1, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO2 ESP32_PINMUX(2, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO3 ESP32_PINMUX(3, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO4 ESP32_PINMUX(4, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO5 ESP32_PINMUX(5, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO6 ESP32_PINMUX(6, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO7 ESP32_PINMUX(7, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO8 ESP32_PINMUX(8, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO9 ESP32_PINMUX(9, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO10 ESP32_PINMUX(10, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO11 ESP32_PINMUX(11, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO12 ESP32_PINMUX(12, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO13 ESP32_PINMUX(13, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO14 ESP32_PINMUX(14, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO15 ESP32_PINMUX(15, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO16 ESP32_PINMUX(16, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO17 ESP32_PINMUX(17, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO18 ESP32_PINMUX(18, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO19 ESP32_PINMUX(19, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO20 ESP32_PINMUX(20, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO21 ESP32_PINMUX(21, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO22 ESP32_PINMUX(22, ESP_PWM0_SYNC2_IN, ESP_NOSIG) -#define LEDC_CH5_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_LEDC_LS_SIG_OUT5) +#define MCPWM0_SYNC2_GPIO23 ESP32_PINMUX(23, ESP_PWM0_SYNC2_IN, ESP_NOSIG) /* SPIM2_CSEL */ -#define SPIM2_CSEL_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS0_OUT) -#define SPIM2_CSEL_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS0_OUT) +#define SPIM2_CSEL_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS0_OUT) /* SPIM2_CSEL1 */ -#define SPIM2_CSEL1_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS1_OUT) -#define SPIM2_CSEL1_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS1_OUT) +#define SPIM2_CSEL1_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS1_OUT) /* SPIM2_CSEL2 */ -#define SPIM2_CSEL2_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS2_OUT) -#define SPIM2_CSEL2_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS2_OUT) +#define SPIM2_CSEL2_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS2_OUT) /* SPIM2_CSEL3 */ -#define SPIM2_CSEL3_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS3_OUT) -#define SPIM2_CSEL3_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS3_OUT) +#define SPIM2_CSEL3_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS3_OUT) /* SPIM2_CSEL4 */ -#define SPIM2_CSEL4_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS4_OUT) -#define SPIM2_CSEL4_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS4_OUT) +#define SPIM2_CSEL4_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS4_OUT) /* SPIM2_CSEL5 */ -#define SPIM2_CSEL5_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICS5_OUT) -#define SPIM2_CSEL5_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS5_OUT) +#define SPIM2_CSEL5_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICS5_OUT) /* SPIM2_MISO */ -#define SPIM2_MISO_GPIO0 \ - ESP32_PINMUX(0, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO0 ESP32_PINMUX(0, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO1 \ - ESP32_PINMUX(1, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO1 ESP32_PINMUX(1, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO2 \ - ESP32_PINMUX(2, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO2 ESP32_PINMUX(2, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO3 \ - ESP32_PINMUX(3, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO3 ESP32_PINMUX(3, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO4 \ - ESP32_PINMUX(4, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO4 ESP32_PINMUX(4, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO5 \ - ESP32_PINMUX(5, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO5 ESP32_PINMUX(5, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO6 \ - ESP32_PINMUX(6, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO6 ESP32_PINMUX(6, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO7 \ - ESP32_PINMUX(7, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO7 ESP32_PINMUX(7, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO8 \ - ESP32_PINMUX(8, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO8 ESP32_PINMUX(8, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO9 \ - ESP32_PINMUX(9, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO9 ESP32_PINMUX(9, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO10 \ - ESP32_PINMUX(10, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO10 ESP32_PINMUX(10, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO11 \ - ESP32_PINMUX(11, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO11 ESP32_PINMUX(11, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO12 \ - ESP32_PINMUX(12, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO12 ESP32_PINMUX(12, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO13 \ - ESP32_PINMUX(13, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO13 ESP32_PINMUX(13, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO14 \ - ESP32_PINMUX(14, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO14 ESP32_PINMUX(14, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO15 \ - ESP32_PINMUX(15, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO15 ESP32_PINMUX(15, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO16 \ - ESP32_PINMUX(16, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO16 ESP32_PINMUX(16, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO17 \ - ESP32_PINMUX(17, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO17 ESP32_PINMUX(17, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO18 \ - ESP32_PINMUX(18, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO18 ESP32_PINMUX(18, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO19 \ - ESP32_PINMUX(19, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO19 ESP32_PINMUX(19, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO20 \ - ESP32_PINMUX(20, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO20 ESP32_PINMUX(20, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO21 \ - ESP32_PINMUX(21, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO21 ESP32_PINMUX(21, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO22 \ - ESP32_PINMUX(22, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO22 ESP32_PINMUX(22, ESP_FSPIQ_IN, ESP_NOSIG) -#define SPIM2_MISO_GPIO23 \ - ESP32_PINMUX(23, ESP_FSPIQ_IN, ESP_NOSIG) +#define SPIM2_MISO_GPIO23 ESP32_PINMUX(23, ESP_FSPIQ_IN, ESP_NOSIG) /* SPIM2_MOSI */ -#define SPIM2_MOSI_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPID_OUT) -#define SPIM2_MOSI_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPID_OUT) +#define SPIM2_MOSI_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPID_OUT) /* SPIM2_SCLK */ -#define SPIM2_SCLK_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_FSPICLK_OUT) -#define SPIM2_SCLK_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICLK_OUT) +#define SPIM2_SCLK_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_FSPICLK_OUT) /* UART0_CTS */ -#define UART0_CTS_GPIO0 \ - ESP32_PINMUX(0, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO0 ESP32_PINMUX(0, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO1 \ - ESP32_PINMUX(1, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO1 ESP32_PINMUX(1, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO2 \ - ESP32_PINMUX(2, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO2 ESP32_PINMUX(2, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO3 \ - ESP32_PINMUX(3, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO3 ESP32_PINMUX(3, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO4 \ - ESP32_PINMUX(4, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO4 ESP32_PINMUX(4, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO5 \ - ESP32_PINMUX(5, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO5 ESP32_PINMUX(5, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO6 \ - ESP32_PINMUX(6, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO6 ESP32_PINMUX(6, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO7 \ - ESP32_PINMUX(7, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO7 ESP32_PINMUX(7, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO8 \ - ESP32_PINMUX(8, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO8 ESP32_PINMUX(8, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO9 \ - ESP32_PINMUX(9, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO9 ESP32_PINMUX(9, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO10 \ - ESP32_PINMUX(10, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO10 ESP32_PINMUX(10, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO11 \ - ESP32_PINMUX(11, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO11 ESP32_PINMUX(11, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO12 \ - ESP32_PINMUX(12, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO12 ESP32_PINMUX(12, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO13 \ - ESP32_PINMUX(13, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO13 ESP32_PINMUX(13, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO14 \ - ESP32_PINMUX(14, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO14 ESP32_PINMUX(14, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO15 \ - ESP32_PINMUX(15, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO15 ESP32_PINMUX(15, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO16 \ - ESP32_PINMUX(16, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO16 ESP32_PINMUX(16, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO17 \ - ESP32_PINMUX(17, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO17 ESP32_PINMUX(17, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO18 \ - ESP32_PINMUX(18, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO18 ESP32_PINMUX(18, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO19 \ - ESP32_PINMUX(19, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO19 ESP32_PINMUX(19, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO20 \ - ESP32_PINMUX(20, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO20 ESP32_PINMUX(20, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO21 \ - ESP32_PINMUX(21, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO21 ESP32_PINMUX(21, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO22 \ - ESP32_PINMUX(22, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO22 ESP32_PINMUX(22, ESP_U0CTS_IN, ESP_NOSIG) -#define UART0_CTS_GPIO23 \ - ESP32_PINMUX(23, ESP_U0CTS_IN, ESP_NOSIG) +#define UART0_CTS_GPIO23 ESP32_PINMUX(23, ESP_U0CTS_IN, ESP_NOSIG) /* UART0_DSR */ -#define UART0_DSR_GPIO0 \ - ESP32_PINMUX(0, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO0 ESP32_PINMUX(0, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO1 \ - ESP32_PINMUX(1, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO1 ESP32_PINMUX(1, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO2 \ - ESP32_PINMUX(2, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO2 ESP32_PINMUX(2, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO3 \ - ESP32_PINMUX(3, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO3 ESP32_PINMUX(3, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO4 \ - ESP32_PINMUX(4, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO4 ESP32_PINMUX(4, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO5 \ - ESP32_PINMUX(5, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO5 ESP32_PINMUX(5, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO6 \ - ESP32_PINMUX(6, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO6 ESP32_PINMUX(6, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO7 \ - ESP32_PINMUX(7, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO7 ESP32_PINMUX(7, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO8 \ - ESP32_PINMUX(8, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO8 ESP32_PINMUX(8, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO9 \ - ESP32_PINMUX(9, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO9 ESP32_PINMUX(9, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO10 \ - ESP32_PINMUX(10, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO10 ESP32_PINMUX(10, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO11 \ - ESP32_PINMUX(11, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO11 ESP32_PINMUX(11, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO12 \ - ESP32_PINMUX(12, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO12 ESP32_PINMUX(12, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO13 \ - ESP32_PINMUX(13, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO13 ESP32_PINMUX(13, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO14 \ - ESP32_PINMUX(14, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO14 ESP32_PINMUX(14, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO15 \ - ESP32_PINMUX(15, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO15 ESP32_PINMUX(15, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO16 \ - ESP32_PINMUX(16, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO16 ESP32_PINMUX(16, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO17 \ - ESP32_PINMUX(17, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO17 ESP32_PINMUX(17, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO18 \ - ESP32_PINMUX(18, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO18 ESP32_PINMUX(18, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO19 \ - ESP32_PINMUX(19, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO19 ESP32_PINMUX(19, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO20 \ - ESP32_PINMUX(20, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO20 ESP32_PINMUX(20, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO21 \ - ESP32_PINMUX(21, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO21 ESP32_PINMUX(21, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO22 \ - ESP32_PINMUX(22, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO22 ESP32_PINMUX(22, ESP_U0DSR_IN, ESP_NOSIG) -#define UART0_DSR_GPIO23 \ - ESP32_PINMUX(23, ESP_U0DSR_IN, ESP_NOSIG) +#define UART0_DSR_GPIO23 ESP32_PINMUX(23, ESP_U0DSR_IN, ESP_NOSIG) /* UART0_DTR */ -#define UART0_DTR_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0DTR_OUT) -#define UART0_DTR_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_U0DTR_OUT) +#define UART0_DTR_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0DTR_OUT) /* UART0_RTS */ -#define UART0_RTS_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0RTS_OUT) -#define UART0_RTS_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_U0RTS_OUT) +#define UART0_RTS_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0RTS_OUT) /* UART0_RX */ -#define UART0_RX_GPIO0 \ - ESP32_PINMUX(0, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO0 ESP32_PINMUX(0, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO1 \ - ESP32_PINMUX(1, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO1 ESP32_PINMUX(1, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO2 \ - ESP32_PINMUX(2, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO2 ESP32_PINMUX(2, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO3 \ - ESP32_PINMUX(3, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO3 ESP32_PINMUX(3, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO4 \ - ESP32_PINMUX(4, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO4 ESP32_PINMUX(4, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO5 \ - ESP32_PINMUX(5, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO5 ESP32_PINMUX(5, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO6 \ - ESP32_PINMUX(6, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO6 ESP32_PINMUX(6, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO7 \ - ESP32_PINMUX(7, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO7 ESP32_PINMUX(7, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO8 \ - ESP32_PINMUX(8, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO8 ESP32_PINMUX(8, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO9 \ - ESP32_PINMUX(9, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO9 ESP32_PINMUX(9, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO10 \ - ESP32_PINMUX(10, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO10 ESP32_PINMUX(10, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO11 \ - ESP32_PINMUX(11, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO11 ESP32_PINMUX(11, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO12 \ - ESP32_PINMUX(12, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO12 ESP32_PINMUX(12, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO13 \ - ESP32_PINMUX(13, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO13 ESP32_PINMUX(13, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO14 \ - ESP32_PINMUX(14, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO14 ESP32_PINMUX(14, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO15 \ - ESP32_PINMUX(15, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO15 ESP32_PINMUX(15, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO16 \ - ESP32_PINMUX(16, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO16 ESP32_PINMUX(16, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO17 \ - ESP32_PINMUX(17, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO17 ESP32_PINMUX(17, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO18 \ - ESP32_PINMUX(18, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO18 ESP32_PINMUX(18, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO19 \ - ESP32_PINMUX(19, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO19 ESP32_PINMUX(19, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO20 \ - ESP32_PINMUX(20, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO20 ESP32_PINMUX(20, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO21 \ - ESP32_PINMUX(21, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO21 ESP32_PINMUX(21, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO22 \ - ESP32_PINMUX(22, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO22 ESP32_PINMUX(22, ESP_U0RXD_IN, ESP_NOSIG) -#define UART0_RX_GPIO23 \ - ESP32_PINMUX(23, ESP_U0RXD_IN, ESP_NOSIG) +#define UART0_RX_GPIO23 ESP32_PINMUX(23, ESP_U0RXD_IN, ESP_NOSIG) /* UART0_TX */ -#define UART0_TX_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U0TXD_OUT) -#define UART0_TX_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_U0TXD_OUT) +#define UART0_TX_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U0TXD_OUT) /* UART1_CTS */ -#define UART1_CTS_GPIO0 \ - ESP32_PINMUX(0, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO0 ESP32_PINMUX(0, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO1 \ - ESP32_PINMUX(1, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO1 ESP32_PINMUX(1, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO2 \ - ESP32_PINMUX(2, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO2 ESP32_PINMUX(2, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO3 \ - ESP32_PINMUX(3, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO3 ESP32_PINMUX(3, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO4 \ - ESP32_PINMUX(4, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO4 ESP32_PINMUX(4, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO5 \ - ESP32_PINMUX(5, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO5 ESP32_PINMUX(5, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO6 \ - ESP32_PINMUX(6, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO6 ESP32_PINMUX(6, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO7 \ - ESP32_PINMUX(7, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO7 ESP32_PINMUX(7, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO8 \ - ESP32_PINMUX(8, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO8 ESP32_PINMUX(8, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO9 \ - ESP32_PINMUX(9, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO9 ESP32_PINMUX(9, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO10 \ - ESP32_PINMUX(10, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO10 ESP32_PINMUX(10, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO11 \ - ESP32_PINMUX(11, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO11 ESP32_PINMUX(11, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO12 \ - ESP32_PINMUX(12, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO12 ESP32_PINMUX(12, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO13 \ - ESP32_PINMUX(13, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO13 ESP32_PINMUX(13, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO14 \ - ESP32_PINMUX(14, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO14 ESP32_PINMUX(14, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO15 \ - ESP32_PINMUX(15, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO15 ESP32_PINMUX(15, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO16 \ - ESP32_PINMUX(16, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO16 ESP32_PINMUX(16, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO17 \ - ESP32_PINMUX(17, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO17 ESP32_PINMUX(17, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO18 \ - ESP32_PINMUX(18, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO18 ESP32_PINMUX(18, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO19 \ - ESP32_PINMUX(19, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO19 ESP32_PINMUX(19, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO20 \ - ESP32_PINMUX(20, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO20 ESP32_PINMUX(20, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO21 \ - ESP32_PINMUX(21, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO21 ESP32_PINMUX(21, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO22 \ - ESP32_PINMUX(22, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO22 ESP32_PINMUX(22, ESP_U1CTS_IN, ESP_NOSIG) -#define UART1_CTS_GPIO23 \ - ESP32_PINMUX(23, ESP_U1CTS_IN, ESP_NOSIG) +#define UART1_CTS_GPIO23 ESP32_PINMUX(23, ESP_U1CTS_IN, ESP_NOSIG) /* UART1_DSR */ -#define UART1_DSR_GPIO0 \ - ESP32_PINMUX(0, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO0 ESP32_PINMUX(0, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO1 \ - ESP32_PINMUX(1, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO1 ESP32_PINMUX(1, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO2 \ - ESP32_PINMUX(2, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO2 ESP32_PINMUX(2, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO3 \ - ESP32_PINMUX(3, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO3 ESP32_PINMUX(3, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO4 \ - ESP32_PINMUX(4, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO4 ESP32_PINMUX(4, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO5 \ - ESP32_PINMUX(5, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO5 ESP32_PINMUX(5, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO6 \ - ESP32_PINMUX(6, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO6 ESP32_PINMUX(6, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO7 \ - ESP32_PINMUX(7, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO7 ESP32_PINMUX(7, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO8 \ - ESP32_PINMUX(8, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO8 ESP32_PINMUX(8, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO9 \ - ESP32_PINMUX(9, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO9 ESP32_PINMUX(9, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO10 \ - ESP32_PINMUX(10, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO10 ESP32_PINMUX(10, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO11 \ - ESP32_PINMUX(11, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO11 ESP32_PINMUX(11, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO12 \ - ESP32_PINMUX(12, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO12 ESP32_PINMUX(12, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO13 \ - ESP32_PINMUX(13, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO13 ESP32_PINMUX(13, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO14 \ - ESP32_PINMUX(14, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO14 ESP32_PINMUX(14, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO15 \ - ESP32_PINMUX(15, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO15 ESP32_PINMUX(15, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO16 \ - ESP32_PINMUX(16, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO16 ESP32_PINMUX(16, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO17 \ - ESP32_PINMUX(17, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO17 ESP32_PINMUX(17, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO18 \ - ESP32_PINMUX(18, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO18 ESP32_PINMUX(18, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO19 \ - ESP32_PINMUX(19, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO19 ESP32_PINMUX(19, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO20 \ - ESP32_PINMUX(20, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO20 ESP32_PINMUX(20, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO21 \ - ESP32_PINMUX(21, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO21 ESP32_PINMUX(21, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO22 \ - ESP32_PINMUX(22, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO22 ESP32_PINMUX(22, ESP_U1DSR_IN, ESP_NOSIG) -#define UART1_DSR_GPIO23 \ - ESP32_PINMUX(23, ESP_U1DSR_IN, ESP_NOSIG) +#define UART1_DSR_GPIO23 ESP32_PINMUX(23, ESP_U1DSR_IN, ESP_NOSIG) /* UART1_DTR */ -#define UART1_DTR_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1DTR_OUT) -#define UART1_DTR_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_U1DTR_OUT) +#define UART1_DTR_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1DTR_OUT) /* UART1_RTS */ -#define UART1_RTS_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1RTS_OUT) -#define UART1_RTS_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_U1RTS_OUT) +#define UART1_RTS_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1RTS_OUT) /* UART1_RX */ -#define UART1_RX_GPIO0 \ - ESP32_PINMUX(0, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO0 ESP32_PINMUX(0, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO1 \ - ESP32_PINMUX(1, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO1 ESP32_PINMUX(1, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO2 \ - ESP32_PINMUX(2, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO2 ESP32_PINMUX(2, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO3 \ - ESP32_PINMUX(3, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO3 ESP32_PINMUX(3, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO4 \ - ESP32_PINMUX(4, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO4 ESP32_PINMUX(4, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO5 \ - ESP32_PINMUX(5, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO5 ESP32_PINMUX(5, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO6 \ - ESP32_PINMUX(6, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO6 ESP32_PINMUX(6, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO7 \ - ESP32_PINMUX(7, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO7 ESP32_PINMUX(7, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO8 \ - ESP32_PINMUX(8, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO8 ESP32_PINMUX(8, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO9 \ - ESP32_PINMUX(9, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO9 ESP32_PINMUX(9, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO10 \ - ESP32_PINMUX(10, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO10 ESP32_PINMUX(10, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO11 \ - ESP32_PINMUX(11, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO11 ESP32_PINMUX(11, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO12 \ - ESP32_PINMUX(12, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO12 ESP32_PINMUX(12, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO13 \ - ESP32_PINMUX(13, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO13 ESP32_PINMUX(13, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO14 \ - ESP32_PINMUX(14, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO14 ESP32_PINMUX(14, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO15 \ - ESP32_PINMUX(15, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO15 ESP32_PINMUX(15, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO16 \ - ESP32_PINMUX(16, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO16 ESP32_PINMUX(16, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO17 \ - ESP32_PINMUX(17, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO17 ESP32_PINMUX(17, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO18 \ - ESP32_PINMUX(18, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO18 ESP32_PINMUX(18, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO19 \ - ESP32_PINMUX(19, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO19 ESP32_PINMUX(19, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO20 \ - ESP32_PINMUX(20, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO20 ESP32_PINMUX(20, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO21 \ - ESP32_PINMUX(21, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO21 ESP32_PINMUX(21, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO22 \ - ESP32_PINMUX(22, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO22 ESP32_PINMUX(22, ESP_U1RXD_IN, ESP_NOSIG) -#define UART1_RX_GPIO23 \ - ESP32_PINMUX(23, ESP_U1RXD_IN, ESP_NOSIG) +#define UART1_RX_GPIO23 ESP32_PINMUX(23, ESP_U1RXD_IN, ESP_NOSIG) /* UART1_TX */ -#define UART1_TX_GPIO0 \ - ESP32_PINMUX(0, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO0 ESP32_PINMUX(0, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO1 \ - ESP32_PINMUX(1, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO1 ESP32_PINMUX(1, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO2 \ - ESP32_PINMUX(2, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO2 ESP32_PINMUX(2, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO3 \ - ESP32_PINMUX(3, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO3 ESP32_PINMUX(3, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO4 \ - ESP32_PINMUX(4, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO4 ESP32_PINMUX(4, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO5 \ - ESP32_PINMUX(5, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO5 ESP32_PINMUX(5, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO6 \ - ESP32_PINMUX(6, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO6 ESP32_PINMUX(6, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO7 \ - ESP32_PINMUX(7, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO7 ESP32_PINMUX(7, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO8 \ - ESP32_PINMUX(8, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO8 ESP32_PINMUX(8, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO9 \ - ESP32_PINMUX(9, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO9 ESP32_PINMUX(9, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO10 \ - ESP32_PINMUX(10, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO10 ESP32_PINMUX(10, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO11 \ - ESP32_PINMUX(11, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO11 ESP32_PINMUX(11, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO12 \ - ESP32_PINMUX(12, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO12 ESP32_PINMUX(12, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO13 \ - ESP32_PINMUX(13, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO13 ESP32_PINMUX(13, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO14 \ - ESP32_PINMUX(14, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO14 ESP32_PINMUX(14, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO15 \ - ESP32_PINMUX(15, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO15 ESP32_PINMUX(15, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO16 \ - ESP32_PINMUX(16, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO16 ESP32_PINMUX(16, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO17 \ - ESP32_PINMUX(17, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO17 ESP32_PINMUX(17, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO18 \ - ESP32_PINMUX(18, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO18 ESP32_PINMUX(18, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO19 \ - ESP32_PINMUX(19, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO19 ESP32_PINMUX(19, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO20 \ - ESP32_PINMUX(20, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO20 ESP32_PINMUX(20, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO21 \ - ESP32_PINMUX(21, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO21 ESP32_PINMUX(21, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO22 \ - ESP32_PINMUX(22, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO22 ESP32_PINMUX(22, ESP_NOSIG, ESP_U1TXD_OUT) -#define UART1_TX_GPIO23 \ - ESP32_PINMUX(23, ESP_NOSIG, ESP_U1TXD_OUT) +#define UART1_TX_GPIO23 ESP32_PINMUX(23, ESP_NOSIG, ESP_U1TXD_OUT) #endif /* INC_DT_BINDS_PINCTRL_ESP32C6_PINCTRL_HAL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h index 4611baef95c2b..51656a1507430 100644 --- a/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h @@ -162,6 +162,14 @@ #define NRF_FUN_CAN_TX 46U /** CAN RX */ #define NRF_FUN_CAN_RX 47U +/** TWIS SCL */ +#define NRF_FUN_TWIS_SCL 48U +/** TWIS SDA */ +#define NRF_FUN_TWIS_SDA 49U +/** GRTC fast clock output */ +#define NRF_FUN_GRTC_CLKOUT_FAST 55U +/** GRTC slow clock output */ +#define NRF_FUN_GRTC_CLKOUT_32K 56U /** @} */ diff --git a/include/zephyr/dt-bindings/pinctrl/realtek-rts5912-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/realtek-rts5912-pinctrl.h new file mode 100644 index 0000000000000..9954f4105d74f --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/realtek-rts5912-pinctrl.h @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_REALTEK_RTS5912_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_REALTEK_RTS5912_PINCTRL_H_ + +#include + +#define REALTEK_RTS5912_GPIO_INOUT BIT(0) /* IN/OUT : 0 input 1 output */ +#define REALTEK_RTS5912_GPIO_PINON BIT(1) /* Input_detect : 1 enable 0 disable */ +#define REALTEK_RTS5912_GPIO_VOLT BIT(2) /* Pin Volt : 1 1.8V 0 3.3V */ +#define REALTEK_RTS5912_FUNC0 0 /* GPIO mode */ +#define REALTEK_RTS5912_FUNC1 BIT(8) /* Function mode use BIT0~2 */ +#define REALTEK_RTS5912_FUNC2 BIT(9) +#define REALTEK_RTS5912_FUNC3 ((BIT(8)) | (BIT(9))) +#define REALTEK_RTS5912_FUNC4 BIT(10) + +#define REALTEK_RTS5912_INPUT_OUTPUT_POS 0 +#define REALTEK_RTS5912_INPUT_DETECTION_POS 1 +#define REALTEK_RTS5912_VOLTAGE_POS 2 +#define REALTEK_RTS5912_DRV_STR_POS 11 +#define REALTEK_RTS5912_SLEW_RATE_POS 12 +#define REALTEK_RTS5912_PD_POS 13 +#define REALTEK_RTS5912_PU_POS 14 +#define REALTEK_RTS5912_SCHMITTER_POS 15 +#define REALTEK_RTS5912_TYPE_POS 16 +#define REALTEK_RTS5912_HIGH_LOW_POS 17 + +#define REALTEK_RTS5912_GPIO_HIGH_POS 18 +#define REALTEK_RTS5912_GPIO_HIGH_MSK 0x3f +#define REALTEK_RTS5912_GPIO_LOW_POS 3 +#define REALTEK_RTS5912_GPIO_LOW_MSK 0x1f + +#define FUNC0 REALTEK_RTS5912_FUNC0 +#define FUNC1 REALTEK_RTS5912_FUNC1 +#define FUNC2 REALTEK_RTS5912_FUNC2 +#define FUNC3 REALTEK_RTS5912_FUNC3 +#define FUNC4 REALTEK_RTS5912_FUNC4 + +#define REALTEK_RTS5912_PINMUX(n, f) \ + (((((n) >> 5) & REALTEK_RTS5912_GPIO_HIGH_MSK) << REALTEK_RTS5912_GPIO_HIGH_POS) | \ + (((n) & REALTEK_RTS5912_GPIO_LOW_MSK) << REALTEK_RTS5912_GPIO_LOW_POS) | (f)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_REALTEK_RTS5912_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-ra.h b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-ra.h index 5d88ea6eea8c7..42b095a3d077e 100644 --- a/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-ra.h +++ b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-ra.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,8 @@ #define RA_PIN_NUM_MASK 0xf #define RA_PSEL_HIZ_JTAG_SWD 0x0 +#define RA_PSEL_ADC 0x0 +#define RA_PSEL_DAC 0x0 #define RA_PSEL_AGT 0x1 #define RA_PSEL_GPT0 0x2 #define RA_PSEL_GPT1 0x3 @@ -31,6 +33,7 @@ #define RA_PSEL_I2C 0x7 #define RA_PSEL_CLKOUT_RTC 0x9 #define RA_PSEL_CAC_ADC 0xa +#define RA_PSEL_CAC_DAC 0xa #define RA_PSEL_BUS 0xb #define RA_PSEL_CANFD 0x10 #define RA_PSEL_QSPI 0x11 @@ -42,7 +45,6 @@ #define RA_PSEL_ETH_RMII 0x17 #define RA_PSEL_GLCDC 0x19 #define RA_PSEL_OSPI 0x1c -#define RA_PSEL_ADC 0x00 #define RA_PSEL_POS 8 #define RA_PSEL_MASK 0x1f diff --git a/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rzg-common.h b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rzg-common.h new file mode 100644 index 0000000000000..da9266ac780e7 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rzg-common.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZG_COMMON_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZG_COMMON_H_ + +/* Superset list of all possible IO ports. */ +#define PORT_00 0x0000 /* IO port 0 */ +#define PORT_01 0x1000 /* IO port 1 */ +#define PORT_02 0x1100 /* IO port 2 */ +#define PORT_03 0x1200 /* IO port 3 */ +#define PORT_04 0x1300 /* IO port 4 */ +#define PORT_05 0x0100 /* IO port 5 */ +#define PORT_06 0x0200 /* IO port 6 */ +#define PORT_07 0x1400 /* IO port 7 */ +#define PORT_08 0x1500 /* IO port 8 */ +#define PORT_09 0x1600 /* IO port 9 */ +#define PORT_10 0x1700 /* IO port 10 */ +#define PORT_11 0x0300 /* IO port 11 */ +#define PORT_12 0x0400 /* IO port 12 */ +#define PORT_13 0x0500 /* IO port 13 */ +#define PORT_14 0x0600 /* IO port 14 */ +#define PORT_15 0x0700 /* IO port 15 */ +#define PORT_16 0x0800 /* IO port 16 */ +#define PORT_17 0x0900 /* IO port 17 */ +#define PORT_18 0x0A00 /* IO port 18 */ + +/* + * Create the value contain port/pin/function information + * + * port: port number BSP_IO_PORT_00..BSP_IO_PORT_18 + * pin: pin number + * func: pin function + */ +#define RZG_PINMUX(port, pin, func) (port | pin | (func << 4)) + +/* Special purpose port */ +#define BSP_IO_NMI 0xFFFF0000 /* NMI */ + +#define BSP_IO_TMS_SWDIO 0xFFFF0100 /* TMS_SWDIO */ +#define BSP_IO_TDO 0xFFFF0101 /* TDO */ + +#define BSP_IO_AUDIO_CLK1 0xFFFF0200 /* AUDIO_CLK1 */ +#define BSP_IO_AUDIO_CLK2 0xFFFF0201 /* AUDIO_CLK2 */ + +#define BSP_IO_XSPI_SPCLK 0xFFFF0400 /* XSPI_SPCLK */ +#define BSP_IO_XSPI_RESET_N 0xFFFF0401 /* XSPI_RESET_N */ +#define BSP_IO_XSPI_WP_N 0xFFFF0402 /* XSPI_WP_N */ +#define BSP_IO_XSPI_DS 0xFFFF0403 /* XSPI_DS */ +#define BSP_IO_XSPI_CS0_N 0xFFFF0404 /* XSPI_CS0_N */ +#define BSP_IO_XSPI_CS1_N 0xFFFF0405 /* XSPI_CS1_N */ + +#define BSP_IO_XSPI_IO0 0xFFFF0500 /* XSPI_IO0 */ +#define BSP_IO_XSPI_IO1 0xFFFF0501 /* XSPI_IO1 */ +#define BSP_IO_XSPI_IO2 0xFFFF0502 /* XSPI_IO2 */ +#define BSP_IO_XSPI_IO3 0xFFFF0503 /* XSPI_IO3 */ +#define BSP_IO_XSPI_IO4 0xFFFF0504 /* XSPI_IO4 */ +#define BSP_IO_XSPI_IO5 0xFFFF0505 /* XSPI_IO5 */ +#define BSP_IO_XSPI_IO6 0xFFFF0506 /* XSPI_IO6 */ +#define BSP_IO_XSPI_IO7 0xFFFF0507 /* XSPI_IO7 */ + +#define BSP_IO_WDTOVF_PERROUT 0xFFFF0600 /* WDTOVF_PERROUT */ + +#define BSP_IO_I3C_SDA 0xFFFF0900 /* I3C_SDA */ +#define BSP_IO_I3C_SCL 0xFFFF0901 /* I3C_SCL */ + +#define BSP_IO_SD0_CLK 0xFFFF1000 /* CD0_CLK */ +#define BSP_IO_SD0_CMD 0xFFFF1001 /* CD0_CMD */ +#define BSP_IO_SD0_RST_N 0xFFFF1002 /* CD0_RST_N */ + +#define BSP_IO_SD0_DATA0 0xFFFF1100 /* SD0_DATA0 */ +#define BSP_IO_SD0_DATA1 0xFFFF1101 /* SD0_DATA1 */ +#define BSP_IO_SD0_DATA2 0xFFFF1102 /* SD0_DATA2 */ +#define BSP_IO_SD0_DATA3 0xFFFF1103 /* SD0_DATA3 */ +#define BSP_IO_SD0_DATA4 0xFFFF1104 /* SD0_DATA4 */ +#define BSP_IO_SD0_DATA5 0xFFFF1105 /* SD0_DATA5 */ +#define BSP_IO_SD0_DATA6 0xFFFF1106 /* SD0_DATA6 */ +#define BSP_IO_SD0_DATA7 0xFFFF1107 /* SD0_DATA7 */ + +#define BSP_IO_SD1_CLK 0xFFFF1200 /* SD1_CLK */ +#define BSP_IO_SD1_CMD 0xFFFF1201 /* SD1_CMD */ + +#define BSP_IO_SD1_DATA0 0xFFFF1300 /* SD1_DATA0 */ +#define BSP_IO_SD1_DATA1 0xFFFF1301 /* SD1_DATA1 */ +#define BSP_IO_SD1_DATA2 0xFFFF1302 /* SD1_DATA2 */ +#define BSP_IO_SD1_DATA3 0xFFFF1303 /* SD1_DATA3 */ + +/*FILNUM*/ +#define RZG_FILNUM_4_STAGE 0 +#define RZG_FILNUM_8_STAGE 1 +#define RZG_FILNUM_12_STAGE 2 +#define RZG_FILNUM_16_STAGE 3 + +/*FILCLKSEL*/ +#define RZG_FILCLKSEL_NOT_DIV 0 +#define RZG_FILCLKSEL_DIV_9000 1 +#define RZG_FILCLKSEL_DIV_18000 2 +#define RZG_FILCLKSEL_DIV_36000 3 + +#define RZG_FILTER_SET(filnum, filclksel) (((filnum) & 0x3) << 0x2) | (filclksel & 0x3) + +#endif /*ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZG_COMMON_H_*/ diff --git a/include/zephyr/dt-bindings/pinctrl/rpi-pico-pinctrl-common.h b/include/zephyr/dt-bindings/pinctrl/rpi-pico-pinctrl-common.h new file mode 100644 index 0000000000000..059c81dcca4d1 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/rpi-pico-pinctrl-common.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2021, Yonatan Schachter + * Copyright (c) 2024, Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_PINCTRL_COMMON_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_PINCTRL_COMMON_H_ + +#define RP2_ALT_FUNC_POS 0 +#define RP2_ALT_FUNC_MASK 0xf + +#define RP2_PIN_NUM_POS 5 +#define RP2_PIN_NUM_MASK 0x1f + +#define RP2_GPIO_OVERRIDE_NORMAL 0 +#define RP2_GPIO_OVERRIDE_INVERT 1 +#define RP2_GPIO_OVERRIDE_LOW 2 +#define RP2_GPIO_OVERRIDE_HIGH 3 + +#define RP2XXX_PINMUX(pin_num, alt_func) \ + (((pin_num) << RP2_PIN_NUM_POS) | ((alt_func) << RP2_ALT_FUNC_POS)) + +/* These function are common. SoC-specific functions are defined in their + * respective header file. Refer to table 279 and 642 in the RP2040 and RP2350 + * datasheets for the source of these numbers. + */ +#define RP2_PINCTRL_GPIO_FUNC_SPI 1 +#define RP2_PINCTRL_GPIO_FUNC_UART 2 +#define RP2_PINCTRL_GPIO_FUNC_I2C 3 +#define RP2_PINCTRL_GPIO_FUNC_PWM 4 +#define RP2_PINCTRL_GPIO_FUNC_SIO 5 +#define RP2_PINCTRL_GPIO_FUNC_PIO0 6 +#define RP2_PINCTRL_GPIO_FUNC_PIO1 7 + +/* These pin assignments for each function are similarly common. */ +#define SPI0_RX_P0 RP2XXX_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_CSN_P1 RP2XXX_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_SCK_P2 RP2XXX_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_TX_P3 RP2XXX_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_RX_P4 RP2XXX_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_CSN_P5 RP2XXX_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_SCK_P6 RP2XXX_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_TX_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_RX_P8 RP2XXX_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_CSN_P9 RP2XXX_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_SCK_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_TX_P11 RP2XXX_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_RX_P12 RP2XXX_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_CSN_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_SCK_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_TX_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_RX_P16 RP2XXX_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_CSN_P17 RP2XXX_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_SCK_P18 RP2XXX_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_TX_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_RX_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_CSN_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_SCK_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_TX_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_RX_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_CSN_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_SCK_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_TX_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_RX_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_CSN_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_SPI) + +#define UART0_TX_P0 RP2XXX_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RX_P1 RP2XXX_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_CTS_P2 RP2XXX_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RTS_P3 RP2XXX_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_TX_P4 RP2XXX_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P5 RP2XXX_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_CTS_P6 RP2XXX_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RTS_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_TX_P8 RP2XXX_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P9 RP2XXX_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_CTS_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RTS_P11 RP2XXX_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_TX_P12 RP2XXX_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RX_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_CTS_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RTS_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_TX_P16 RP2XXX_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RX_P17 RP2XXX_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_CTS_P18 RP2XXX_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RTS_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_TX_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_CTS_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RTS_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_TX_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_CTS_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RTS_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_TX_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RX_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_UART) + +#define I2C0_SDA_P0 RP2XXX_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P1 RP2XXX_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P2 RP2XXX_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P3 RP2XXX_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P4 RP2XXX_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P5 RP2XXX_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P6 RP2XXX_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P8 RP2XXX_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P9 RP2XXX_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P11 RP2XXX_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P12 RP2XXX_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P16 RP2XXX_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P17 RP2XXX_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P18 RP2XXX_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_I2C) + +#define PWM_0A_P0 RP2XXX_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_0B_P1 RP2XXX_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_1A_P2 RP2XXX_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_1B_P3 RP2XXX_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_2A_P4 RP2XXX_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_2B_P5 RP2XXX_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_3A_P6 RP2XXX_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_3B_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_4A_P8 RP2XXX_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_4B_P9 RP2XXX_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_5A_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_5B_P11 RP2XXX_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_6A_P12 RP2XXX_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_6B_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_7A_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_7B_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_0A_P16 RP2XXX_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_0B_P17 RP2XXX_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_1A_P18 RP2XXX_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_1B_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_2A_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_2B_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_3A_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_3B_P22 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_4A_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_4B_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_5A_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_5B_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_6A_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_6B_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PWM) + +#define PIO0_P0 RP2XXX_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P1 RP2XXX_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P2 RP2XXX_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P3 RP2XXX_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P4 RP2XXX_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P5 RP2XXX_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P6 RP2XXX_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P8 RP2XXX_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P9 RP2XXX_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P11 RP2XXX_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P12 RP2XXX_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P16 RP2XXX_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P17 RP2XXX_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P18 RP2XXX_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PIO0) + +#define PIO1_P0 RP2XXX_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P1 RP2XXX_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P2 RP2XXX_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P3 RP2XXX_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P4 RP2XXX_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P5 RP2XXX_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P6 RP2XXX_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P8 RP2XXX_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P9 RP2XXX_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P11 RP2XXX_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P12 RP2XXX_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P16 RP2XXX_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P17 RP2XXX_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P18 RP2XXX_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PIO1) + +#define GPIN0_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPIN1_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT0_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT1_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT2_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT3_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_GPCK) + +#define USB_VBUS_DET_P1 RP2XXX_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P4 RP2XXX_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P16 RP2XXX_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_USB) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_PINCTRL_COMMON_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h index 64c3832d60e95..38d6e0420b422 100644 --- a/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h @@ -4,242 +4,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __RP2040_PINCTRL_H__ -#define __RP2040_PINCTRL_H__ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2040_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2040_PINCTRL_H_ -#define RP2_PINCTRL_GPIO_FUNC_XIP 0 -#define RP2_PINCTRL_GPIO_FUNC_SPI 1 -#define RP2_PINCTRL_GPIO_FUNC_UART 2 -#define RP2_PINCTRL_GPIO_FUNC_I2C 3 -#define RP2_PINCTRL_GPIO_FUNC_PWM 4 -#define RP2_PINCTRL_GPIO_FUNC_SIO 5 -#define RP2_PINCTRL_GPIO_FUNC_PIO0 6 -#define RP2_PINCTRL_GPIO_FUNC_PIO1 7 +#define RP2_PINCTRL_GPIO_FUNC_XIP 0 #define RP2_PINCTRL_GPIO_FUNC_GPCK 8 -#define RP2_PINCTRL_GPIO_FUNC_USB 9 +#define RP2_PINCTRL_GPIO_FUNC_USB 9 #define RP2_PINCTRL_GPIO_FUNC_NULL 0xf -#define RP2_ALT_FUNC_POS 0 -#define RP2_ALT_FUNC_MASK 0xf +#include "rpi-pico-pinctrl-common.h" -#define RP2_PIN_NUM_POS 4 -#define RP2_PIN_NUM_MASK 0x1f +#define ADC_CH0_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH1_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH2_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH3_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_NULL) -#define RP2_GPIO_OVERRIDE_NORMAL 0 -#define RP2_GPIO_OVERRIDE_INVERT 1 -#define RP2_GPIO_OVERRIDE_LOW 2 -#define RP2_GPIO_OVERRIDE_HIGH 3 - -#define RP2040_PINMUX(pin_num, alt_func) (pin_num << RP2_PIN_NUM_POS | \ - alt_func << RP2_ALT_FUNC_POS) - -#define UART0_TX_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_RX_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_CTS_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_RTS_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_TX_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_RX_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_CTS_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_RTS_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_TX_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_RX_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_CTS_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_RTS_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_TX_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_RX_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_CTS_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_RTS_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_TX_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_RX_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_CTS_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_RTS_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_TX_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_RX_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_CTS_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_RTS_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_TX_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_RX_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_CTS_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART1_RTS_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_TX_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_UART) -#define UART0_RX_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_UART) - -#define I2C0_SDA_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SCL_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SDA_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SCL_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SDA_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SCL_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SDA_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SCL_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SDA_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SCL_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SDA_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SCL_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SDA_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SCL_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SDA_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SCL_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SDA_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SCL_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SDA_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SCL_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SDA_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SCL_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SDA_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SCL_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SDA_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SCL_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SDA_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C1_SCL_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SDA_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_I2C) -#define I2C0_SCL_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_I2C) - -#define PWM_0A_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_0B_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_1A_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_1B_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_2A_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_2B_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_3A_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_3B_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_4A_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_4B_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_5A_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_5B_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_6A_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_6B_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_7A_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_7B_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_0A_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_0B_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_1A_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_1B_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_2A_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_2B_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_3A_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_3B_P22 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_4A_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_4B_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_5A_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_5B_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_6A_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PWM) -#define PWM_6B_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PWM) - -#define SPI0_RX_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_CSN_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_SCK_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_TX_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_RX_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_CSN_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_SCK_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_TX_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_RX_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_CSN_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_SCK_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_TX_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_RX_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_CSN_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_SCK_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_TX_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_RX_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_CSN_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_SCK_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_TX_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_RX_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_CSN_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_SCK_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI0_TX_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_RX_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_CSN_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_SCK_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_TX_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_RX_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_SPI) -#define SPI1_CSN_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_SPI) - -#define ADC_CH0_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_NULL) -#define ADC_CH1_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_NULL) -#define ADC_CH2_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_NULL) -#define ADC_CH3_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_NULL) - -#define PIO0_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO0) -#define PIO0_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PIO0) - -#define PIO1_P0 RP2040_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P2 RP2040_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P3 RP2040_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P5 RP2040_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P6 RP2040_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P8 RP2040_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P9 RP2040_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P11 RP2040_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P12 RP2040_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P14 RP2040_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P15 RP2040_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P17 RP2040_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P18 RP2040_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P26 RP2040_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P27 RP2040_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO1) -#define PIO1_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PIO1) - -#define GPIN0_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_GPCK) -#define GPIN1_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_GPCK) -#define GPOUT0_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_GPCK) -#define GPOUT1_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_GPCK) -#define GPOUT2_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_GPCK) -#define GPOUT3_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_GPCK) - -#define USB_VBUS_DET_P1 RP2040_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P4 RP2040_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P7 RP2040_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P10 RP2040_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P13 RP2040_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P16 RP2040_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P19 RP2040_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_USB) -#define USB_VBUS_DET_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_USB) - -#endif /* __RP2040_PINCTRL_H__ */ +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2040_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350-pinctrl-common.h b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350-pinctrl-common.h new file mode 100644 index 0000000000000..9899d55519421 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350-pinctrl-common.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024, Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350_PINCTRL_COMMON_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350_PINCTRL_COMMON_H_ + +#define RP2_PINCTRL_GPIO_FUNC_HSTX 0 + +#define RP2_PINCTRL_GPIO_FUNC_PIO2 8 +#define RP2_PINCTRL_GPIO_FUNC_GPCK 9 +#define RP2_PINCTRL_GPIO_FUNC_USB 10 +#define RP2_PINCTRL_GPIO_FUNC_UART_AUX 11 +#define RP2_PINCTRL_GPIO_FUNC_NULL 0x1f + +#include "rpi-pico-pinctrl-common.h" + +#define PIO2_P0 RP2XXX_PINMUX(0, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P1 RP2XXX_PINMUX(1, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P2 RP2XXX_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P3 RP2XXX_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P4 RP2XXX_PINMUX(4, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P5 RP2XXX_PINMUX(5, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P6 RP2XXX_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P8 RP2XXX_PINMUX(8, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P9 RP2XXX_PINMUX(9, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P11 RP2XXX_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P12 RP2XXX_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P16 RP2XXX_PINMUX(16, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P17 RP2XXX_PINMUX(17, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P18 RP2XXX_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PIO2) + +#define GPIN0_P12 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPIN1_P14 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT0_P13 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT1_P15 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_GPCK) + +#define UART0_TX_P2 RP2XXX_PINMUX(2, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_RX_P3 RP2XXX_PINMUX(3, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_TX_P6 RP2XXX_PINMUX(6, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_RX_P7 RP2XXX_PINMUX(7, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_TX_P10 RP2XXX_PINMUX(10, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_RX_P11 RP2XXX_PINMUX(11, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_TX_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_RX_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_TX_P18 RP2XXX_PINMUX(18, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_RX_P19 RP2XXX_PINMUX(19, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_TX_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_RX_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_TX_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_RX_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_UART_ALT) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350_PINCTRL_COMMON_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350a-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350a-pinctrl.h new file mode 100644 index 0000000000000..0c4f910a51b81 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350a-pinctrl.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024, Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350A_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350A_PINCTRL_H_ + +#include "rpi-pico-rp2350-pinctrl-common.h" + +/* ADC channel allocations differ between the RP2350A and RP2350B. + * Refer to Table 1115 in the datasheet. + */ +#define ADC_CH0_P26 RP2XXX_PINMUX(26, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH1_P27 RP2XXX_PINMUX(27, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH2_P28 RP2XXX_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH3_P29 RP2XXX_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_NULL) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350A_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350b-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350b-pinctrl.h new file mode 100644 index 0000000000000..7f53cf559fd62 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2350b-pinctrl.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2024, Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350B_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350B_PINCTRL_H_ + +#include "rpi-pico-rp2350-pinctrl-common.h" + +/* RP2350B is in a QFN-80 package, and extends the set of available pins + * accordingly. + */ +#define SPI1_SCK_P30 RP2XXX_PINMUX(30, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_TX_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_RX_P32 RP2XXX_PINMUX(32, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_CSN_P33 RP2XXX_PINMUX(33, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_SCK_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_TX_P35 RP2XXX_PINMUX(35, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_RX_P36 RP2XXX_PINMUX(36, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_CSN_P37 RP2XXX_PINMUX(37, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_SCK_P38 RP2XXX_PINMUX(38, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI0_TX_P39 RP2XXX_PINMUX(39, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_RX_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_CSN_P41 RP2XXX_PINMUX(41, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_SCK_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_TX_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_RX_P44 RP2XXX_PINMUX(44, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_CSN_P45 RP2XXX_PINMUX(45, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_SCK_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_SPI) +#define SPI1_TX_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_SPI) + +#define UART1_TX_P30 RP2XXX_PINMUX(30, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_TX_P32 RP2XXX_PINMUX(32, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RX_P33 RP2XXX_PINMUX(33, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_TX_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P35 RP2XXX_PINMUX(35, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_TX_P36 RP2XXX_PINMUX(36, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RX_P37 RP2XXX_PINMUX(37, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_TX_P38 RP2XXX_PINMUX(38, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P39 RP2XXX_PINMUX(39, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_TX_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RX_P41 RP2XXX_PINMUX(41, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_TX_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_TX_P44 RP2XXX_PINMUX(44, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART0_RX_P45 RP2XXX_PINMUX(45, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_TX_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_UART) +#define UART1_RX_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_UART) + +#define I2C1_SDA_P30 RP2XXX_PINMUX(30, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P32 RP2XXX_PINMUX(32, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P33 RP2XXX_PINMUX(33, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P35 RP2XXX_PINMUX(35, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P36 RP2XXX_PINMUX(36, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P37 RP2XXX_PINMUX(37, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P38 RP2XXX_PINMUX(38, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P39 RP2XXX_PINMUX(39, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P41 RP2XXX_PINMUX(41, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SDA_P44 RP2XXX_PINMUX(44, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C0_SCL_P45 RP2XXX_PINMUX(45, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SDA_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_I2C) +#define I2C1_SCL_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_I2C) + +#define PWM_7A_P30 RP2XXX_PINMUX(30, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_7B_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_8A_P32 RP2XXX_PINMUX(32, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_8B_P33 RP2XXX_PINMUX(33, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_9A_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_9B_P35 RP2XXX_PINMUX(35, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_10A_P36 RP2XXX_PINMUX(36, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_10B_P37 RP2XXX_PINMUX(37, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_11A_P38 RP2XXX_PINMUX(38, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_11B_P39 RP2XXX_PINMUX(39, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_12A_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_12B_P41 RP2XXX_PINMUX(41, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_13A_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_13B_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_14A_P44 RP2XXX_PINMUX(44, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_14B_P45 RP2XXX_PINMUX(45, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_15A_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_PWM) +#define PWM_15B_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_PWM) + +#define PIO0_P30 RP2XXX_PINMUX(30, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P32 RP2XXX_PINMUX(32, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P33 RP2XXX_PINMUX(33, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P35 RP2XXX_PINMUX(35, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P36 RP2XXX_PINMUX(36, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P37 RP2XXX_PINMUX(37, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P38 RP2XXX_PINMUX(38, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P39 RP2XXX_PINMUX(39, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P41 RP2XXX_PINMUX(41, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P44 RP2XXX_PINMUX(44, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P45 RP2XXX_PINMUX(45, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_PIO0) +#define PIO0_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_PIO0) + +#define PIO1_P30 RP2XXX_PINMUX(30, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P32 RP2XXX_PINMUX(32, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P33 RP2XXX_PINMUX(33, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P35 RP2XXX_PINMUX(35, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P36 RP2XXX_PINMUX(36, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P37 RP2XXX_PINMUX(37, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P38 RP2XXX_PINMUX(38, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P39 RP2XXX_PINMUX(39, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P41 RP2XXX_PINMUX(41, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P44 RP2XXX_PINMUX(44, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P45 RP2XXX_PINMUX(45, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define PIO1_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_PIO1) + +#define PIO2_P30 RP2XXX_PINMUX(30, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P32 RP2XXX_PINMUX(32, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P33 RP2XXX_PINMUX(33, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P35 RP2XXX_PINMUX(35, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P36 RP2XXX_PINMUX(36, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P37 RP2XXX_PINMUX(37, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P38 RP2XXX_PINMUX(38, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P39 RP2XXX_PINMUX(39, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P41 RP2XXX_PINMUX(41, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P44 RP2XXX_PINMUX(44, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P45 RP2XXX_PINMUX(45, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_PIO2) +#define PIO2_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_PIO2) + +#define GPIN0_P12 RP2XXX_PINMUX(12, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPIN1_P14 RP2XXX_PINMUX(14, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPIN0_P20 RP2XXX_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPIN1_P22 RP2XXX_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT0_P13 RP2XXX_PINMUX(13, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT1_P15 RP2XXX_PINMUX(15, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT0_P21 RP2XXX_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT1_P23 RP2XXX_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT2_P24 RP2XXX_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT3_P25 RP2XXX_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_GPCK) + +#define USB_VBUS_DET_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P37 RP2XXX_PINMUX(37, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_USB) +#define USB_VBUS_DET_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_USB) + +#define UART0_TX_P30 RP2XXX_PINMUX(30, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_RX_P31 RP2XXX_PINMUX(31, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_TX_P34 RP2XXX_PINMUX(34, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_RX_P35 RP2XXX_PINMUX(35, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_TX_P38 RP2XXX_PINMUX(38, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_RX_P39 RP2XXX_PINMUX(39, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_TX_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART1_RX_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_TX_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_UART_ALT) +#define UART0_RX_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_UART_ALT) + +/* ADC channel allocations differ between the RP2350A and RP2350B. + * Refer to Table 1116 in the datasheet. + */ +#define ADC_CH0_P40 RP2XXX_PINMUX(40, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH1_P41 RP2XXX_PINMUX(41, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH2_P42 RP2XXX_PINMUX(42, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH3_P43 RP2XXX_PINMUX(43, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH4_P44 RP2XXX_PINMUX(44, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH5_P45 RP2XXX_PINMUX(45, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH6_P46 RP2XXX_PINMUX(46, RP2_PINCTRL_GPIO_FUNC_NULL) +#define ADC_CH7_P47 RP2XXX_PINMUX(47, RP2_PINCTRL_GPIO_FUNC_NULL) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RPI_PICO_RP2350B_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs-pinctrl-dbus.h b/include/zephyr/dt-bindings/pinctrl/silabs-pinctrl-dbus.h index 9ad02a5cd0f57..e42879a91c372 100644 --- a/include/zephyr/dt-bindings/pinctrl/silabs-pinctrl-dbus.h +++ b/include/zephyr/dt-bindings/pinctrl/silabs-pinctrl-dbus.h @@ -11,7 +11,9 @@ /* * Silabs Series 2 DBUS configuration is encoded in a 32-bit bitfield organized as follows: * - * 31..29: Reserved + * 31 : Whether the configuration represents an analog pin + * If digital (bit 31 == 0): + * 30..29: Reserved * 28..24: Route register offset in words from peripheral config (offset of ROUTE * register in GPIO_ROUTE_TypeDef) * 23..19: Enable bit (offset into ROUTEEN register for given function) @@ -20,6 +22,11 @@ * register in GPIO_TypeDef minus offset of first route register [DBGROUTEPEN, 0x440]) * 7..4 : GPIO pin * 3..0 : GPIO port + * If analog (bit 31 == 1): + * 15..14: Bus selection (A, B, CD) + * 13..12: Bus selection (EVEN0, EVEN1, ODD0, ODD1) + * 11..8 : Peripheral selection (bit in GPIO_nBUSALLOC bitfield) + * 7 ..0 : Reserved */ #define SILABS_PINCTRL_GPIO_PORT_MASK 0x0000000FUL @@ -29,6 +36,14 @@ #define SILABS_PINCTRL_EN_BIT_MASK 0x00F80000UL #define SILABS_PINCTRL_ROUTE_MASK 0x1F000000UL +#define SILABS_PINCTRL_ANALOG_MASK 0x80000000UL +#define SILABS_PINCTRL_ABUS_BUS_MASK 0x0000C000UL +#define SILABS_PINCTRL_ABUS_PARITY_MASK 0x00003000UL +#define SILABS_PINCTRL_ABUS_PERIPH_MASK 0x00000F00UL + +#define SILABS_PINCTRL_UNUSED 0xFF +#define SILABS_PINCTRL_ANALOG 0xAA + #define SILABS_DBUS(port, pin, periph_base, en_present, en_bit, route) \ (FIELD_PREP(SILABS_PINCTRL_GPIO_PORT_MASK, port) | \ FIELD_PREP(SILABS_PINCTRL_GPIO_PIN_MASK, pin) | \ @@ -37,4 +52,10 @@ FIELD_PREP(SILABS_PINCTRL_EN_BIT_MASK, en_bit) | \ FIELD_PREP(SILABS_PINCTRL_ROUTE_MASK, route)) +#define SILABS_ABUS(bus, parity, peripheral) \ + (FIELD_PREP(SILABS_PINCTRL_ANALOG_MASK, 1) | \ + FIELD_PREP(SILABS_PINCTRL_ABUS_BUS_MASK, bus) | \ + FIELD_PREP(SILABS_PINCTRL_ABUS_PARITY_MASK, parity) | \ + FIELD_PREP(SILABS_PINCTRL_ABUS_PERIPH_MASK, peripheral)) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_SILABS_PINCTRL_DBUS_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs-pinctrl-siwx91x.h b/include/zephyr/dt-bindings/pinctrl/silabs-pinctrl-siwx91x.h new file mode 100644 index 0000000000000..371dbffbaf950 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/silabs-pinctrl-siwx91x.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef INCLUDE_ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_PINCTRL_SIWX91X_H_ +#define INCLUDE_ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_PINCTRL_SIWX91X_H_ + +#include + +#if !defined(FIELD_PREP) +/* Upstream does not make these macros available to DeviceTree */ +#define LSB_GET(value) ((value) & -(value)) +#define FIELD_GET(mask, value) (((value) & (mask)) / LSB_GET(mask)) +#define FIELD_PREP(mask, value) (((value) * LSB_GET(mask)) & (mask)) +#endif + +#define SIWX91X_PINCTRL_PORT_MASK 0x0000000FUL +#define SIWX91X_PINCTRL_PIN_MASK 0x000000F0UL +#define SIWX91X_PINCTRL_ULPPIN_MASK 0x00000F00UL +#define SIWX91X_PINCTRL_MODE_MASK 0x0003F000UL +#define SIWX91X_PINCTRL_ULPMODE_MASK 0x00FC0000UL +#define SIWX91X_PINCTRL_PAD_MASK 0xFF000000UL + +/* Declare an integer representing the pinctrl/gpio state of a signal on SiWx91x. + * @param mode HP GPIO mode, 0xFF if HP GPIO mux isn't used + * @param ulpmode ULP GPIO mode, 0xFF if ULP GPIO mux isn't used + * @param pad HP pad number, 0xFF if HP pad isn't used, 0 if host pad + * @param port GPIO port number (0-4) + * @param pin HP GPIO pin number, value is unused if mode is 0xFF + * @param ulppin ULP GPIO pin number, value is unused if ulpmode is 0xFF + */ +#define SIWX91X_GPIO(mode, ulpmode, pad, port, pin, ulppin) \ + (FIELD_PREP(SIWX91X_PINCTRL_PORT_MASK, port) | FIELD_PREP(SIWX91X_PINCTRL_PIN_MASK, pin) | \ + FIELD_PREP(SIWX91X_PINCTRL_ULPPIN_MASK, ulppin) | \ + FIELD_PREP(SIWX91X_PINCTRL_MODE_MASK, mode) | \ + FIELD_PREP(SIWX91X_PINCTRL_ULPMODE_MASK, ulpmode) | \ + FIELD_PREP(SIWX91X_PINCTRL_PAD_MASK, pad)) + +#endif /* INCLUDE_ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_PINCTRL_SIWX91X_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs/siwx91x-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/silabs/siwx91x-pinctrl.h new file mode 100644 index 0000000000000..c0ccda7484dc7 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/silabs/siwx91x-pinctrl.h @@ -0,0 +1,620 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef INCLUDE_ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_SIWX91X_PINCTRL_H_ +#define INCLUDE_ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_SIWX91X_PINCTRL_H_ + +#include + +/* clang-format off */ + +#define AGPIO_ULP0 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 0) +#define AGPIO_ULP1 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 1) +#define AGPIO_ULP2 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 2) +#define AGPIO_ULP4 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 4) +#define AGPIO_ULP5 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 5) +#define AGPIO_ULP6 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 6) +#define AGPIO_ULP7 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 7) +#define AGPIO_ULP8 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 8) +#define AGPIO_ULP9 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 9) +#define AGPIO_ULP10 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 10) +#define AGPIO_ULP11 SIWX91X_GPIO(0xFF, 7, 0xFF, 4, 0, 11) + +#define AUXULP_TRIG0_PA11 SIWX91X_GPIO(9, 5, 6, 0, 11, 5) +#define AUXULP_TRIG0_PB14 SIWX91X_GPIO(11, 5, 0, 1, 14, 11) +#define AUXULP_TRIG0_PD1 SIWX91X_GPIO(9, 5, 13, 3, 1, 11) +#define AUXULP_TRIG0_ULP5 SIWX91X_GPIO(0xFF, 5, 0xFF, 4, 0, 5) +#define AUXULP_TRIG0_ULP6 SIWX91X_GPIO(0xFF, 10, 0xFF, 4, 0, 6) +#define AUXULP_TRIG0_ULP11 SIWX91X_GPIO(0xFF, 5, 0xFF, 4, 0, 11) +#define AUXULP_TRIG1_ULP4 SIWX91X_GPIO(0xFF, 5, 0xFF, 4, 0, 4) +#define AUXULP_TRIG1_ULP7 SIWX91X_GPIO(0xFF, 10, 0xFF, 4, 0, 7) + +#define CLK_I2SPLL_PB11 SIWX91X_GPIO(12, 0xFF, 0, 1, 11, 0) +#define CLK_I2SPLL_PD0 SIWX91X_GPIO(10, 0xFF, 12, 3, 0, 0) +#define CLK_I2SPLL_PD6 SIWX91X_GPIO(10, 0xFF, 18, 3, 6, 0) +#define CLK_INTFPLL_PB10 SIWX91X_GPIO(12, 0xFF, 0, 1, 10, 0) +#define CLK_INTFPLL_PC15 SIWX91X_GPIO(10, 0xFF, 11, 2, 15, 0) +#define CLK_INTFPLL_PD5 SIWX91X_GPIO(10, 0xFF, 17, 3, 5, 0) +#define CLK_MCUOUT_PA11 SIWX91X_GPIO(12, 0xFF, 6, 0, 11, 0) +#define CLK_MEMSREF_PD2 SIWX91X_GPIO(10, 0xFF, 14, 3, 2, 0) +#define CLK_MEMSREF_PD8 SIWX91X_GPIO(10, 0xFF, 20, 3, 8, 0) +#define CLK_OUT_PA12 SIWX91X_GPIO(8, 0xFF, 7, 0, 12, 0) +#define CLK_OUT_PA15 SIWX91X_GPIO(8, 0xFF, 8, 0, 15, 0) +#define CLK_PLLTESTMODE_PD3 SIWX91X_GPIO(10, 0xFF, 15, 3, 3, 0) +#define CLK_SOCPLL_PB9 SIWX91X_GPIO(12, 0xFF, 0, 1, 9, 0) +#define CLK_SOCPLL_PC14 SIWX91X_GPIO(10, 0xFF, 10, 2, 14, 0) +#define CLK_SOCPLL_PD4 SIWX91X_GPIO(10, 0xFF, 16, 3, 4, 0) +#define CLK_XTALONIN_PB12 SIWX91X_GPIO(12, 0xFF, 0, 1, 12, 0) +#define CLK_XTALONIN_PD9 SIWX91X_GPIO(10, 0xFF, 21, 3, 9, 0) + +#define COMP1_OUT_PA8 SIWX91X_GPIO(9, 5, 3, 0, 8, 2) +#define COMP1_OUT_PB12 SIWX91X_GPIO(11, 5, 0, 1, 12, 9) +#define COMP1_OUT_PC15 SIWX91X_GPIO(9, 5, 11, 2, 15, 9) +#define COMP1_OUT_ULP2 SIWX91X_GPIO(0xFF, 5, 0xFF, 4, 0, 2) +#define COMP1_OUT_ULP6 SIWX91X_GPIO(0xFF, 9, 0xFF, 4, 0, 6) +#define COMP2_OUT_ULP7 SIWX91X_GPIO(0xFF, 9, 0xFF, 4, 0, 7) + +#define GSPI_CLK_PA8 SIWX91X_GPIO(4, 0xFF, 3, 0, 8, 0) +#define GSPI_CLK_PB9 SIWX91X_GPIO(4, 0xFF, 0, 1, 9, 0) +#define GSPI_CLK_PC14 SIWX91X_GPIO(4, 0xFF, 10, 2, 14, 0) +#define GSPI_CLK_PD4 SIWX91X_GPIO(4, 0xFF, 16, 3, 4, 0) +#define GSPI_CS0_PA9 SIWX91X_GPIO(4, 0xFF, 4, 0, 9, 0) +#define GSPI_CS0_PB12 SIWX91X_GPIO(4, 0xFF, 0, 1, 12, 0) +#define GSPI_CS0_PD1 SIWX91X_GPIO(4, 0xFF, 13, 3, 1, 0) +#define GSPI_CS0_PD5 SIWX91X_GPIO(4, 0xFF, 17, 3, 5, 0) +#define GSPI_CS1_PA10 SIWX91X_GPIO(4, 0xFF, 5, 0, 10, 0) +#define GSPI_CS1_PB13 SIWX91X_GPIO(4, 0xFF, 0, 1, 13, 0) +#define GSPI_CS1_PD2 SIWX91X_GPIO(4, 0xFF, 14, 3, 2, 0) +#define GSPI_CS1_PD6 SIWX91X_GPIO(4, 0xFF, 18, 3, 6, 0) +#define GSPI_CS2_PA15 SIWX91X_GPIO(4, 0xFF, 8, 0, 15, 0) +#define GSPI_CS2_PB14 SIWX91X_GPIO(4, 0xFF, 0, 1, 14, 0) +#define GSPI_CS2_PD3 SIWX91X_GPIO(4, 0xFF, 15, 3, 3, 0) +#define GSPI_CS2_PD7 SIWX91X_GPIO(4, 0xFF, 19, 3, 7, 0) +#define GSPI_MISO_PA11 SIWX91X_GPIO(4, 0xFF, 6, 0, 11, 0) +#define GSPI_MISO_PB10 SIWX91X_GPIO(4, 0xFF, 0, 1, 10, 0) +#define GSPI_MISO_PC15 SIWX91X_GPIO(4, 0xFF, 11, 2, 15, 0) +#define GSPI_MISO_PD8 SIWX91X_GPIO(4, 0xFF, 20, 3, 8, 0) +#define GSPI_MOSI_PA6 SIWX91X_GPIO(12, 0xFF, 1, 0, 6, 0) +#define GSPI_MOSI_PA12 SIWX91X_GPIO(4, 0xFF, 7, 0, 12, 0) +#define GSPI_MOSI_PB11 SIWX91X_GPIO(4, 0xFF, 0, 1, 11, 0) +#define GSPI_MOSI_PD0 SIWX91X_GPIO(4, 0xFF, 12, 3, 0, 0) +#define GSPI_MOSI_PD9 SIWX91X_GPIO(4, 0xFF, 21, 3, 9, 0) + +#define I2C0_SCL_PA7 SIWX91X_GPIO(4, 0xFF, 2, 0, 7, 0) +#define I2C0_SCL_PC0 SIWX91X_GPIO(11, 0xFF, 9, 2, 0, 0) +#define I2C0_SCL_ULP1 SIWX91X_GPIO(4, 6, 23, 4, 1, 1) +#define I2C0_SCL_ULP2 SIWX91X_GPIO(4, 6, 24, 4, 2, 2) +#define I2C0_SCL_ULP11 SIWX91X_GPIO(4, 6, 33, 4, 11, 11) +#define I2C0_SDA_PA6 SIWX91X_GPIO(4, 0xFF, 1, 0, 6, 0) +#define I2C0_SDA_PB15 SIWX91X_GPIO(11, 0xFF, 9, 1, 15, 0) +#define I2C0_SDA_ULP0 SIWX91X_GPIO(4, 6, 22, 4, 0, 0) +#define I2C0_SDA_ULP3 SIWX91X_GPIO(4, 6, 25, 4, 3, 3) +#define I2C0_SDA_ULP10 SIWX91X_GPIO(4, 6, 32, 4, 10, 10) + +#define I2C1_SCL_PA6 SIWX91X_GPIO(5, 0xFF, 1, 0, 6, 0) +#define I2C1_SCL_PB13 SIWX91X_GPIO(5, 0xFF, 0, 1, 13, 0) +#define I2C1_SCL_PC1 SIWX91X_GPIO(11, 0xFF, 9, 2, 1, 0) +#define I2C1_SCL_PD2 SIWX91X_GPIO(5, 0xFF, 14, 3, 2, 0) +#define I2C1_SCL_PD6 SIWX91X_GPIO(5, 0xFF, 18, 3, 6, 0) +#define I2C1_SCL_ULP0 SIWX91X_GPIO(5, 6, 22, 4, 0, 0) +#define I2C1_SCL_ULP2 SIWX91X_GPIO(5, 6, 24, 4, 2, 2) +#define I2C1_SCL_ULP6 SIWX91X_GPIO(5, 6, 28, 4, 6, 6) +#define I2C1_SDA_PA7 SIWX91X_GPIO(5, 0xFF, 2, 0, 7, 0) +#define I2C1_SDA_PB14 SIWX91X_GPIO(5, 0xFF, 0, 1, 14, 0) +#define I2C1_SDA_PC2 SIWX91X_GPIO(11, 0xFF, 9, 2, 2, 0) +#define I2C1_SDA_PD3 SIWX91X_GPIO(5, 0xFF, 15, 3, 3, 0) +#define I2C1_SDA_PD7 SIWX91X_GPIO(5, 0xFF, 19, 3, 7, 0) +#define I2C1_SDA_ULP1 SIWX91X_GPIO(5, 6, 23, 4, 1, 1) +#define I2C1_SDA_ULP3 SIWX91X_GPIO(5, 6, 25, 4, 3, 3) +#define I2C1_SDA_ULP7 SIWX91X_GPIO(5, 6, 29, 4, 7, 7) + +#define I2S0_CLK_PA8 SIWX91X_GPIO(7, 0xFF, 3, 0, 8, 0) +#define I2S0_CLK_PB9 SIWX91X_GPIO(7, 0xFF, 0, 1, 9, 0) +#define I2S0_CLK_PC14 SIWX91X_GPIO(7, 0xFF, 10, 2, 14, 0) +#define I2S0_CLK_PD4 SIWX91X_GPIO(7, 0xFF, 16, 3, 4, 0) +#define I2S0_DIN0_PA10 SIWX91X_GPIO(7, 0xFF, 5, 0, 10, 0) +#define I2S0_DIN0_PB11 SIWX91X_GPIO(7, 0xFF, 0, 1, 11, 0) +#define I2S0_DIN0_PD0 SIWX91X_GPIO(7, 0xFF, 12, 3, 0, 0) +#define I2S0_DIN0_PD8 SIWX91X_GPIO(7, 0xFF, 20, 3, 8, 0) +#define I2S0_DIN1_PA6 SIWX91X_GPIO(7, 0xFF, 1, 0, 6, 0) +#define I2S0_DIN1_PB13 SIWX91X_GPIO(7, 0xFF, 0, 1, 13, 0) +#define I2S0_DIN1_PD2 SIWX91X_GPIO(7, 0xFF, 14, 3, 2, 0) +#define I2S0_DIN1_PD6 SIWX91X_GPIO(7, 0xFF, 18, 3, 6, 0) +#define I2S0_DOUT0_PA11 SIWX91X_GPIO(7, 0xFF, 6, 0, 11, 0) +#define I2S0_DOUT0_PB12 SIWX91X_GPIO(7, 0xFF, 0, 1, 12, 0) +#define I2S0_DOUT0_PD1 SIWX91X_GPIO(7, 0xFF, 13, 3, 1, 0) +#define I2S0_DOUT0_PD9 SIWX91X_GPIO(7, 0xFF, 21, 3, 9, 0) +#define I2S0_DOUT1_PA7 SIWX91X_GPIO(7, 0xFF, 2, 0, 7, 0) +#define I2S0_DOUT1_PB13 SIWX91X_GPIO(7, 0xFF, 0, 1, 14, 0) +#define I2S0_DOUT1_PD3 SIWX91X_GPIO(7, 0xFF, 15, 3, 3, 0) +#define I2S0_DOUT1_PD7 SIWX91X_GPIO(7, 0xFF, 19, 3, 7, 0) +#define I2S0_WS_PA9 SIWX91X_GPIO(7, 0xFF, 4, 0, 9, 0) +#define I2S0_WS_PB10 SIWX91X_GPIO(7, 0xFF, 0, 1, 10, 0) +#define I2S0_WS_PC15 SIWX91X_GPIO(7, 0xFF, 11, 2, 15, 0) +#define I2S0_WS_PD5 SIWX91X_GPIO(7, 0xFF, 17, 3, 5, 0) + +#define IR_INPUT_PA15 SIWX91X_GPIO(9, 1, 8, 0, 15, 7) +#define IR_INPUT_PB10 SIWX91X_GPIO(11, 1, 0, 1, 10, 7) +#define IR_INPUT_PB13 SIWX91X_GPIO(11, 4, 0, 1, 13, 10) +#define IR_INPUT_PD0 SIWX91X_GPIO(9, 4, 12, 3, 0, 10) +#define IR_INPUT_ULP4 SIWX91X_GPIO(0xFF, 10, 0xFF, 4, 0, 4) +#define IR_INPUT_ULP7 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 7) +#define IR_INPUT_ULP10 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 10) +#define IR_OUTPUT_PA11 SIWX91X_GPIO(9, 1, 6, 0, 11, 5) +#define IR_OUTPUT_ULP5 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 5) + +#define PMU_TEST1_PA6 SIWX91X_GPIO(8, 0xFF, 1, 0, 6, 0) +#define PMU_TEST1_PB13 SIWX91X_GPIO(8, 0xFF, 0, 1, 13, 0) +#define PMU_TEST1_PB14 SIWX91X_GPIO(12, 0xFF, 0, 1, 14, 0) +#define PMU_TEST1_ULP0 SIWX91X_GPIO(13, 6, 22, 4, 0, 0) +#define PMU_TEST1_ULP2 SIWX91X_GPIO(10, 6, 24, 4, 2, 2) +#define PMU_TEST1_ULP6 SIWX91X_GPIO(12, 6, 28, 4, 6, 6) +#define PMU_TEST1_ULP10 SIWX91X_GPIO(10, 6, 32, 4, 10, 10) +#define PMU_TEST2_PA7 SIWX91X_GPIO(8, 0xFF, 2, 0, 7, 0) +#define PMU_TEST2_PB14 SIWX91X_GPIO(8, 0xFF, 0, 1, 14, 0) +#define PMU_TEST2_ULP1 SIWX91X_GPIO(13, 6, 23, 4, 1, 1) +#define PMU_TEST2_ULP3 SIWX91X_GPIO(10, 6, 25, 4, 3, 3) +#define PMU_TEST2_ULP7 SIWX91X_GPIO(12, 6, 29, 4, 7, 7) +#define PMU_TEST2_ULP11 SIWX91X_GPIO(10, 6, 33, 4, 11, 11) + +#define PSRAM_CLK_PC14 SIWX91X_GPIO(11, 0xFF, 10, 2, 14, 0) +#define PSRAM_CLK_PD4 SIWX91X_GPIO(12, 0xFF, 16, 3, 4, 0) +#define PSRAM_CSN0_PD1 SIWX91X_GPIO(11, 0xFF, 13, 3, 1, 0) +#define PSRAM_CSN0_PD7 SIWX91X_GPIO(12, 0xFF, 19, 3, 7, 0) +#define PSRAM_CSN1_PD5 SIWX91X_GPIO(11, 0xFF, 17, 3, 5, 0) +#define PSRAM_D0_PC15 SIWX91X_GPIO(11, 0xFF, 11, 2, 15, 0) +#define PSRAM_D0_PD5 SIWX91X_GPIO(12, 0xFF, 17, 3, 5, 0) +#define PSRAM_D1_PD0 SIWX91X_GPIO(11, 0xFF, 12, 3, 0, 0) +#define PSRAM_D1_PD6 SIWX91X_GPIO(12, 0xFF, 18, 3, 6, 0) +#define PSRAM_D2_PD2 SIWX91X_GPIO(11, 0xFF, 14, 3, 2, 0) +#define PSRAM_D2_PD8 SIWX91X_GPIO(12, 0xFF, 20, 3, 8, 0) +#define PSRAM_D3_PD3 SIWX91X_GPIO(11, 0xFF, 15, 3, 3, 0) +#define PSRAM_D3_PD9 SIWX91X_GPIO(12, 0xFF, 21, 3, 9, 0) +#define PSRAM_D4_PD6 SIWX91X_GPIO(11, 0xFF, 18, 3, 6, 0) +#define PSRAM_D5_PD7 SIWX91X_GPIO(11, 0xFF, 19, 3, 7, 0) +#define PSRAM_D6_PD8 SIWX91X_GPIO(11, 0xFF, 20, 3, 8, 0) +#define PSRAM_D7_PD9 SIWX91X_GPIO(11, 0xFF, 21, 3, 9, 0) + +#define PWM_1H_PA7 SIWX91X_GPIO(10, 0xFF, 2, 0, 7, 0) +#define PWM_1H_ULP1 SIWX91X_GPIO(12, 6, 23, 4, 1, 1) +#define PWM_1L_PA6 SIWX91X_GPIO(10, 0xFF, 1, 0, 6, 0) +#define PWM_1L_ULP0 SIWX91X_GPIO(12, 6, 22, 4, 0, 0) +#define PWM_2H_PA9 SIWX91X_GPIO(10, 0xFF, 4, 0, 9, 0) +#define PWM_2H_ULP3 SIWX91X_GPIO(8, 6, 25, 4, 3, 3) +#define PWM_2H_ULP5 SIWX91X_GPIO(12, 6, 27, 4, 5, 5) +#define PWM_2L_PA8 SIWX91X_GPIO(10, 0xFF, 3, 0, 8, 0) +#define PWM_2L_ULP2 SIWX91X_GPIO(8, 6, 24, 4, 2, 2) +#define PWM_2L_ULP4 SIWX91X_GPIO(12, 6, 26, 4, 4, 4) +#define PWM_3H_PA11 SIWX91X_GPIO(10, 0xFF, 6, 0, 11, 0) +#define PWM_3H_ULP5 SIWX91X_GPIO(8, 6, 27, 4, 5, 5) +#define PWM_3L_PA10 SIWX91X_GPIO(10, 0xFF, 5, 0, 10, 0) +#define PWM_3L_ULP4 SIWX91X_GPIO(8, 6, 26, 4, 4, 4) +#define PWM_4H_PA15 SIWX91X_GPIO(10, 0xFF, 8, 0, 15, 0) +#define PWM_4H_ULP7 SIWX91X_GPIO(8, 6, 29, 4, 7, 7) +#define PWM_4L_PA12 SIWX91X_GPIO(10, 0xFF, 7, 0, 12, 0) +#define PWM_4L_ULP6 SIWX91X_GPIO(8, 6, 28, 4, 6, 6) +#define PWM_EXTTRIG1_PB11 SIWX91X_GPIO(10, 0xFF, 0, 1, 11, 0) +#define PWM_EXTTRIG1_PD3 SIWX91X_GPIO(8, 0xFF, 15, 3, 3, 0) +#define PWM_EXTTRIG1_ULP6 SIWX91X_GPIO(10, 6, 28, 4, 6, 6) +#define PWM_EXTTRIG1_ULP11 SIWX91X_GPIO(8, 6, 33, 4, 11, 11) +#define PWM_EXTTRIG2_PB12 SIWX91X_GPIO(10, 0xFF, 0, 1, 12, 0) +#define PWM_EXTTRIG2_PD6 SIWX91X_GPIO(8, 0xFF, 18, 3, 6, 0) +#define PWM_EXTTRIG2_ULP7 SIWX91X_GPIO(10, 6, 29, 4, 7, 7) +#define PWM_EXTTRIG3_PB13 SIWX91X_GPIO(10, 0xFF, 0, 1, 13, 0) +#define PWM_EXTTRIG3_PD7 SIWX91X_GPIO(8, 0xFF, 19, 3, 7, 0) +#define PWM_EXTTRIG3_ULP8 SIWX91X_GPIO(10, 6, 30, 4, 8, 8) +#define PWM_EXTTRIG4_PB14 SIWX91X_GPIO(10, 0xFF, 0, 1, 14, 0) +#define PWM_EXTTRIG4_PD2 SIWX91X_GPIO(8, 0xFF, 14, 3, 2, 0) +#define PWM_EXTTRIG4_ULP9 SIWX91X_GPIO(10, 6, 31, 4, 9, 9) +#define PWM_FAULTA_PB9 SIWX91X_GPIO(10, 0xFF, 0, 1, 9, 0) +#define PWM_FAULTA_ULP4 SIWX91X_GPIO(10, 6, 26, 4, 4, 4) +#define PWM_FAULTA_ULP9 SIWX91X_GPIO(8, 6, 31, 4, 9, 9) +#define PWM_FAULTB_PB10 SIWX91X_GPIO(10, 0xFF, 0, 1, 10, 0) +#define PWM_FAULTB_ULP5 SIWX91X_GPIO(10, 6, 27, 4, 5, 5) +#define PWM_FAULTB_ULP10 SIWX91X_GPIO(8, 6, 32, 4, 10, 10) +#define PWM_SLEEPEVENT_ULP8 SIWX91X_GPIO(8, 6, 30, 4, 8, 8) + +#define QEI_DIR_PA11 SIWX91X_GPIO(5, 0xFF, 6, 0, 11, 0) +#define QEI_DIR_PB12 SIWX91X_GPIO(5, 0xFF, 0, 1, 12, 0) +#define QEI_DIR_PC2 SIWX91X_GPIO(13, 0xFF, 9, 2, 2, 0) +#define QEI_DIR_PD1 SIWX91X_GPIO(3, 0xFF, 13, 3, 1, 0) +#define QEI_DIR_PD9 SIWX91X_GPIO(5, 0xFF, 21, 3, 9, 0) +#define QEI_DIR_ULP3 SIWX91X_GPIO(3, 6, 25, 4, 3, 3) +#define QEI_DIR_ULP7 SIWX91X_GPIO(3, 6, 29, 4, 7, 7) +#define QEI_DIR_ULP11 SIWX91X_GPIO(3, 6, 33, 4, 11, 11) +#define QEI_IDX_PA8 SIWX91X_GPIO(5, 0xFF, 3, 0, 8, 0) +#define QEI_IDX_PB15 SIWX91X_GPIO(13, 0xFF, 9, 1, 15, 0) +#define QEI_IDX_PB9 SIWX91X_GPIO(5, 0xFF, 0, 1, 9, 0) +#define QEI_IDX_PC14 SIWX91X_GPIO(3, 0xFF, 10, 2, 14, 0) +#define QEI_IDX_PD4 SIWX91X_GPIO(5, 0xFF, 16, 3, 4, 0) +#define QEI_IDX_ULP0 SIWX91X_GPIO(3, 6, 22, 4, 0, 0) +#define QEI_IDX_ULP4 SIWX91X_GPIO(3, 6, 26, 4, 4, 4) +#define QEI_IDX_ULP8 SIWX91X_GPIO(3, 6, 30, 4, 8, 8) +#define QEI_PHA_PA9 SIWX91X_GPIO(5, 0xFF, 4, 0, 9, 0) +#define QEI_PHA_PB10 SIWX91X_GPIO(5, 0xFF, 0, 1, 10, 0) +#define QEI_PHA_PC0 SIWX91X_GPIO(13, 0xFF, 9, 2, 0, 0) +#define QEI_PHA_PC15 SIWX91X_GPIO(3, 0xFF, 11, 2, 15, 0) +#define QEI_PHA_PD5 SIWX91X_GPIO(5, 0xFF, 17, 3, 5, 0) +#define QEI_PHA_ULP1 SIWX91X_GPIO(3, 6, 23, 4, 1, 1) +#define QEI_PHA_ULP5 SIWX91X_GPIO(3, 6, 27, 4, 5, 5) +#define QEI_PHA_ULP9 SIWX91X_GPIO(3, 6, 31, 4, 9, 9) +#define QEI_PHB_PA10 SIWX91X_GPIO(5, 0xFF, 5, 0, 10, 0) +#define QEI_PHB_PB11 SIWX91X_GPIO(5, 0xFF, 0, 1, 11, 0) +#define QEI_PHB_PC1 SIWX91X_GPIO(13, 0xFF, 9, 2, 1, 0) +#define QEI_PHB_PD0 SIWX91X_GPIO(3, 0xFF, 12, 3, 0, 0) +#define QEI_PHB_PD8 SIWX91X_GPIO(5, 0xFF, 20, 3, 8, 0) +#define QEI_PHB_ULP2 SIWX91X_GPIO(3, 6, 24, 4, 2, 2) +#define QEI_PHB_ULP6 SIWX91X_GPIO(3, 6, 28, 4, 6, 6) +#define QEI_PHB_ULP10 SIWX91X_GPIO(3, 6, 32, 4, 10, 10) + +#define QSPI_CLK_PA8 SIWX91X_GPIO(11, 0xFF, 3, 0, 8, 0) +#define QSPI_CLK_PC14 SIWX91X_GPIO(1, 0xFF, 10, 2, 14, 0) +#define QSPI_CLK_PD4 SIWX91X_GPIO(9, 0xFF, 16, 3, 4, 0) +#define QSPI_CSN0_PA7 SIWX91X_GPIO(11, 0xFF, 2, 0, 7, 0) +#define QSPI_CSN0_PD1 SIWX91X_GPIO(1, 0xFF, 13, 3, 1, 0) +#define QSPI_CSN0_PD7 SIWX91X_GPIO(9, 0xFF, 19, 3, 7, 0) +#define QSPI_CSN1_PA7 SIWX91X_GPIO(12, 0xFF, 2, 0, 7, 0) +#define QSPI_CSN1_PD5 SIWX91X_GPIO(1, 0xFF, 17, 3, 5, 0) +#define QSPI_CSN9_PD1 SIWX91X_GPIO(10, 0xFF, 13, 3, 1, 0) +#define QSPI_D0_PA6 SIWX91X_GPIO(11, 0xFF, 1, 0, 6, 0) +#define QSPI_D0_PC15 SIWX91X_GPIO(1, 0xFF, 11, 2, 15, 0) +#define QSPI_D0_PD5 SIWX91X_GPIO(9, 0xFF, 17, 3, 5, 0) +#define QSPI_D1_PA9 SIWX91X_GPIO(11, 0xFF, 4, 0, 9, 0) +#define QSPI_D1_PD0 SIWX91X_GPIO(1, 0xFF, 12, 3, 0, 0) +#define QSPI_D1_PD6 SIWX91X_GPIO(9, 0xFF, 18, 3, 6, 0) +#define QSPI_D2_PA10 SIWX91X_GPIO(11, 0xFF, 5, 0, 10, 0) +#define QSPI_D2_PD2 SIWX91X_GPIO(1, 0xFF, 14, 3, 2, 0) +#define QSPI_D2_PD8 SIWX91X_GPIO(9, 0xFF, 20, 3, 8, 0) +#define QSPI_D3_PA11 SIWX91X_GPIO(11, 0xFF, 6, 0, 11, 0) +#define QSPI_D3_PD3 SIWX91X_GPIO(1, 0xFF, 15, 3, 3, 0) +#define QSPI_D3_PD9 SIWX91X_GPIO(9, 0xFF, 21, 3, 9, 0) +#define QSPI_D4_PD6 SIWX91X_GPIO(1, 0xFF, 18, 3, 6, 0) +#define QSPI_D5_PD7 SIWX91X_GPIO(1, 0xFF, 19, 3, 7, 0) +#define QSPI_D6_PD8 SIWX91X_GPIO(1, 0xFF, 20, 3, 8, 0) +#define QSPI_D7_PD9 SIWX91X_GPIO(1, 0xFF, 21, 3, 9, 0) + +#define SCT_IN0_PB9 SIWX91X_GPIO(9, 0xFF, 0, 1, 9, 0) +#define SCT_IN0_ULP0 SIWX91X_GPIO(7, 6, 22, 4, 0, 0) +#define SCT_IN0_ULP4 SIWX91X_GPIO(9, 6, 26, 4, 4, 4) +#define SCT_IN1_PB10 SIWX91X_GPIO(9, 0xFF, 0, 1, 10, 0) +#define SCT_IN1_ULP1 SIWX91X_GPIO(7, 6, 23, 4, 1, 1) +#define SCT_IN1_ULP5 SIWX91X_GPIO(9, 6, 27, 4, 5, 5) +#define SCT_IN2_PB11 SIWX91X_GPIO(9, 0xFF, 0, 1, 11, 0) +#define SCT_IN2_ULP2 SIWX91X_GPIO(7, 6, 24, 4, 2, 2) +#define SCT_IN2_ULP6 SIWX91X_GPIO(9, 6, 28, 4, 6, 6) +#define SCT_IN3_PB12 SIWX91X_GPIO(9, 0xFF, 0, 1, 12, 0) +#define SCT_IN3_ULP3 SIWX91X_GPIO(7, 6, 25, 4, 3, 3) +#define SCT_IN3_ULP7 SIWX91X_GPIO(9, 6, 29, 4, 7, 7) +#define SCT_OUT0_PB13 SIWX91X_GPIO(9, 0xFF, 0, 1, 13, 0) +#define SCT_OUT0_ULP4 SIWX91X_GPIO(7, 6, 26, 4, 4, 4) +#define SCT_OUT1_PB14 SIWX91X_GPIO(9, 0xFF, 0, 1, 14, 0) +#define SCT_OUT1_ULP5 SIWX91X_GPIO(7, 6, 27, 4, 5, 5) +#define SCT_OUT2_PA8 SIWX91X_GPIO(12, 0xFF, 3, 0, 8, 0) +#define SCT_OUT2_ULP6 SIWX91X_GPIO(7, 6, 28, 4, 6, 6) +#define SCT_OUT3_PA9 SIWX91X_GPIO(12, 0xFF, 4, 0, 9, 0) +#define SCT_OUT3_ULP7 SIWX91X_GPIO(7, 6, 29, 4, 7, 7) +#define SCT_OUT4_ULP4 SIWX91X_GPIO(13, 6, 26, 4, 4, 4) +#define SCT_OUT4_ULP8 SIWX91X_GPIO(7, 6, 30, 4, 8, 8) +#define SCT_OUT5_ULP5 SIWX91X_GPIO(13, 6, 27, 4, 5, 5) +#define SCT_OUT5_ULP9 SIWX91X_GPIO(7, 6, 31, 4, 9, 9) +#define SCT_OUT6_ULP6 SIWX91X_GPIO(13, 6, 28, 4, 6, 6) +#define SCT_OUT6_ULP10 SIWX91X_GPIO(7, 6, 32, 4, 10, 10) +#define SCT_OUT7_ULP7 SIWX91X_GPIO(13, 6, 29, 4, 7, 7) +#define SCT_OUT7_ULP11 SIWX91X_GPIO(7, 6, 33, 4, 11, 11) + +#define SIO_0_PA6 SIWX91X_GPIO(1, 0xFF, 1, 0, 6, 0) +#define SIO_0_PB9 SIWX91X_GPIO(1, 0xFF, 0, 1, 9, 0) +#define SIO_0_ULP0 SIWX91X_GPIO(1, 6, 22, 4, 0, 0) +#define SIO_0_ULP8 SIWX91X_GPIO(1, 6, 30, 4, 8, 8) +#define SIO_1_PA7 SIWX91X_GPIO(1, 0xFF, 2, 0, 7, 0) +#define SIO_1_PB10 SIWX91X_GPIO(1, 0xFF, 0, 1, 10, 0) +#define SIO_1_ULP1 SIWX91X_GPIO(1, 6, 23, 4, 1, 1) +#define SIO_1_ULP9 SIWX91X_GPIO(1, 6, 31, 4, 9, 9) +#define SIO_2_PA8 SIWX91X_GPIO(1, 0xFF, 3, 0, 8, 0) +#define SIO_2_PB11 SIWX91X_GPIO(1, 0xFF, 0, 1, 11, 0) +#define SIO_2_ULP2 SIWX91X_GPIO(1, 6, 24, 4, 2, 2) +#define SIO_2_ULP10 SIWX91X_GPIO(1, 6, 32, 4, 10, 10) +#define SIO_3_PA9 SIWX91X_GPIO(1, 0xFF, 4, 0, 9, 0) +#define SIO_3_PB12 SIWX91X_GPIO(1, 0xFF, 0, 1, 12, 0) +#define SIO_3_ULP3 SIWX91X_GPIO(1, 6, 25, 4, 3, 3) +#define SIO_3_ULP11 SIWX91X_GPIO(1, 6, 33, 4, 11, 11) +#define SIO_4_PA10 SIWX91X_GPIO(1, 0xFF, 5, 0, 10, 0) +#define SIO_4_PB13 SIWX91X_GPIO(1, 0xFF, 0, 1, 13, 0) +#define SIO_4_ULP4 SIWX91X_GPIO(1, 6, 26, 4, 4, 4) +#define SIO_5_PA11 SIWX91X_GPIO(1, 0xFF, 6, 0, 11, 0) +#define SIO_5_PB14 SIWX91X_GPIO(1, 0xFF, 0, 1, 14, 0) +#define SIO_5_ULP5 SIWX91X_GPIO(1, 6, 27, 4, 5, 5) +#define SIO_6_ULP6 SIWX91X_GPIO(1, 6, 28, 4, 6, 6) +#define SIO_7_PA15 SIWX91X_GPIO(1, 0xFF, 8, 0, 15, 0) +#define SIO_7_ULP7 SIWX91X_GPIO(1, 6, 29, 4, 7, 7) + +#define SSI_CLK_PA8 SIWX91X_GPIO(3, 0xFF, 3, 0, 8, 0) +#define SSI_CLK_PB9 SIWX91X_GPIO(3, 0xFF, 0, 1, 9, 0) +#define SSI_CLK_PD4 SIWX91X_GPIO(3, 0xFF, 16, 3, 4, 0) +#define SSI_CS0_PA9 SIWX91X_GPIO(3, 0xFF, 4, 0, 9, 0) +#define SSI_CS0_PB12 SIWX91X_GPIO(3, 0xFF, 0, 1, 12, 0) +#define SSI_CS0_PD5 SIWX91X_GPIO(3, 0xFF, 17, 3, 5, 0) +#define SSI_CS1_PA10 SIWX91X_GPIO(3, 0xFF, 5, 0, 10, 0) +#define SSI_CS2_PA15 SIWX91X_GPIO(3, 0xFF, 8, 0, 15, 0) +#define SSI_CS2_PD2 SIWX91X_GPIO(3, 0xFF, 14, 3, 2, 0) +#define SSI_CS3_PD3 SIWX91X_GPIO(3, 0xFF, 15, 3, 3, 0) +#define SSI_DATA0_PA11 SIWX91X_GPIO(3, 0xFF, 6, 0, 11, 0) +#define SSI_DATA0_PB10 SIWX91X_GPIO(3, 0xFF, 0, 1, 10, 0) +#define SSI_DATA0_PD8 SIWX91X_GPIO(3, 0xFF, 20, 3, 8, 0) +#define SSI_DATA1_PA10 SIWX91X_GPIO(12, 0xFF, 5, 0, 10, 0) +#define SSI_DATA1_PA12 SIWX91X_GPIO(3, 0xFF, 7, 0, 12, 0) +#define SSI_DATA1_PB11 SIWX91X_GPIO(3, 0xFF, 0, 1, 11, 0) +#define SSI_DATA1_PD9 SIWX91X_GPIO(3, 0xFF, 21, 3, 9, 0) +#define SSI_DATA2_PA6 SIWX91X_GPIO(3, 0xFF, 1, 0, 6, 0) +#define SSI_DATA2_PB13 SIWX91X_GPIO(3, 0xFF, 0, 1, 13, 0) +#define SSI_DATA2_PD6 SIWX91X_GPIO(3, 0xFF, 18, 3, 6, 0) +#define SSI_DATA3_PA7 SIWX91X_GPIO(3, 0xFF, 2, 0, 7, 0) +#define SSI_DATA3_PB14 SIWX91X_GPIO(3, 0xFF, 0, 1, 14, 0) +#define SSI_DATA3_PD7 SIWX91X_GPIO(3, 0xFF, 19, 3, 7, 0) + +#define SSIS_CLK_PA8 SIWX91X_GPIO(8, 0xFF, 3, 0, 8, 0) +#define SSIS_CLK_PB10 SIWX91X_GPIO(8, 0xFF, 0, 1, 10, 0) +#define SSIS_CLK_PC15 SIWX91X_GPIO(8, 0xFF, 11, 2, 15, 0) +#define SSIS_CLK_PD4 SIWX91X_GPIO(8, 0xFF, 16, 3, 4, 0) +#define SSIS_CS_PA9 SIWX91X_GPIO(8, 0xFF, 4, 0, 9, 0) +#define SSIS_CS_PB9 SIWX91X_GPIO(8, 0xFF, 0, 1, 9, 0) +#define SSIS_CS_PC14 SIWX91X_GPIO(8, 0xFF, 10, 2, 14, 0) +#define SSIS_CS_PD5 SIWX91X_GPIO(8, 0xFF, 17, 3, 5, 0) +#define SSIS_MISO_PA11 SIWX91X_GPIO(8, 0xFF, 6, 0, 11, 0) +#define SSIS_MISO_PB12 SIWX91X_GPIO(8, 0xFF, 0, 1, 12, 0) +#define SSIS_MISO_PD1 SIWX91X_GPIO(8, 0xFF, 13, 3, 1, 0) +#define SSIS_MISO_PD9 SIWX91X_GPIO(8, 0xFF, 21, 3, 9, 0) +#define SSIS_MOSI_PA10 SIWX91X_GPIO(8, 0xFF, 5, 0, 10, 0) +#define SSIS_MOSI_PB11 SIWX91X_GPIO(8, 0xFF, 0, 1, 11, 0) +#define SSIS_MOSI_PD0 SIWX91X_GPIO(8, 0xFF, 12, 3, 0, 0) +#define SSIS_MOSI_PD8 SIWX91X_GPIO(8, 0xFF, 20, 3, 8, 0) + +#define TIMER0_PA7 SIWX91X_GPIO(9, 5, 2, 0, 7, 1) +#define TIMER0_PB11 SIWX91X_GPIO(11, 5, 0, 1, 11, 8) +#define TIMER0_PC14 SIWX91X_GPIO(9, 5, 10, 2, 14, 8) +#define TIMER0_ULP4 SIWX91X_GPIO(0xFF, 9, 0xFF, 4, 0, 4) +#define TIMER0_ULP8 SIWX91X_GPIO(0xFF, 5, 0xFF, 4, 0, 8) + +#define TIMER1_PA15 SIWX91X_GPIO(9, 5, 8, 0, 15, 7) +#define TIMER1_PB10 SIWX91X_GPIO(11, 5, 0, 1, 10, 7) +#define TIMER1_ULP5 SIWX91X_GPIO(0xFF, 9, 0xFF, 4, 0, 5) +#define TIMER1_ULP7 SIWX91X_GPIO(0xFF, 5, 0xFF, 4, 0, 7) + +#define TIMER2_ULP1 SIWX91X_GPIO(0xFF, 5, 0xFF, 4, 0, 1) + +#define TRACE_CLK_PA7 SIWX91X_GPIO(13, 0xFF, 2, 0, 7, 0) +#define TRACE_CLK_PC15 SIWX91X_GPIO(6, 0xFF, 11, 2, 15, 0) +#define TRACE_CLK_PD5 SIWX91X_GPIO(6, 0xFF, 17, 3, 5, 0) +#define TRACE_CLKIN_PA6 SIWX91X_GPIO(13, 0xFF, 1, 0, 6, 0) +#define TRACE_CLKIN_PA15 SIWX91X_GPIO(6, 0xFF, 8, 0, 15, 0) +#define TRACE_CLKIN_PC14 SIWX91X_GPIO(6, 0xFF, 10, 2, 14, 0) +#define TRACE_CLKIN_PD4 SIWX91X_GPIO(6, 0xFF, 16, 3, 4, 0) +#define TRACE_D0_PA8 SIWX91X_GPIO(13, 0xFF, 3, 0, 8, 0) +#define TRACE_D0_PD0 SIWX91X_GPIO(6, 0xFF, 12, 3, 0, 0) +#define TRACE_D0_PD6 SIWX91X_GPIO(6, 0xFF, 18, 3, 6, 0) +#define TRACE_D1_PA9 SIWX91X_GPIO(13, 0xFF, 4, 0, 9, 0) +#define TRACE_D1_PD1 SIWX91X_GPIO(6, 0xFF, 13, 3, 1, 0) +#define TRACE_D1_PD7 SIWX91X_GPIO(6, 0xFF, 19, 3, 7, 0) +#define TRACE_D2_PA10 SIWX91X_GPIO(13, 0xFF, 5, 0, 10, 0) +#define TRACE_D2_PD2 SIWX91X_GPIO(6, 0xFF, 14, 3, 2, 0) +#define TRACE_D2_PD8 SIWX91X_GPIO(6, 0xFF, 20, 3, 8, 0) +#define TRACE_D3_PA11 SIWX91X_GPIO(13, 0xFF, 6, 0, 11, 0) +#define TRACE_D3_PD3 SIWX91X_GPIO(6, 0xFF, 15, 3, 3, 0) +#define TRACE_D3_PD9 SIWX91X_GPIO(6, 0xFF, 21, 3, 9, 0) + +#define UART1_CLK_PA8 SIWX91X_GPIO(2, 0xFF, 3, 0, 8, 0) +#define UART1_CLK_PB9 SIWX91X_GPIO(2, 0xFF, 0, 1, 9, 0) +#define UART1_CLK_PD4 SIWX91X_GPIO(2, 0xFF, 16, 3, 4, 0) +#define UART1_CLK_ULP0 SIWX91X_GPIO(2, 6, 22, 4, 0, 0) +#define UART1_CTS_PA6 SIWX91X_GPIO(2, 0xFF, 1, 0, 6, 0) +#define UART1_CTS_PB10 SIWX91X_GPIO(2, 0xFF, 0, 1, 10, 0) +#define UART1_CTS_PD8 SIWX91X_GPIO(2, 0xFF, 20, 3, 8, 0) +#define UART1_CTS_ULP6 SIWX91X_GPIO(2, 6, 28, 4, 6, 6) +#define UART1_DCD_PA12 SIWX91X_GPIO(2, 0xFF, 7, 0, 12, 0) +#define UART1_DCD_PB13 SIWX91X_GPIO(12, 0xFF, 0, 1, 13, 0) +#define UART1_DSR_PA11 SIWX91X_GPIO(2, 0xFF, 6, 0, 11, 0) +#define UART1_DSR_PD9 SIWX91X_GPIO(2, 0xFF, 21, 3, 9, 0) +#define UART1_DTR_PA7 SIWX91X_GPIO(2, 0xFF, 2, 0, 7, 0) +#define UART1_IRRX_PB9 SIWX91X_GPIO(13, 0xFF, 0, 1, 9, 0) +#define UART1_IRRX_PC15 SIWX91X_GPIO(2, 0xFF, 11, 2, 15, 0) +#define UART1_IRRX_ULP0 SIWX91X_GPIO(11, 6, 22, 4, 0, 0) +#define UART1_IRRX_ULP7 SIWX91X_GPIO(2, 6, 29, 4, 7, 7) +#define UART1_IRTX_PB10 SIWX91X_GPIO(13, 0xFF, 0, 1, 10, 0) +#define UART1_IRTX_PD0 SIWX91X_GPIO(2, 0xFF, 12, 3, 0, 0) +#define UART1_IRTX_ULP1 SIWX91X_GPIO(11, 6, 23, 4, 1, 1) +#define UART1_IRTX_ULP8 SIWX91X_GPIO(2, 6, 30, 4, 8, 8) +#define UART1_RI_PB11 SIWX91X_GPIO(2, 0xFF, 0, 1, 11, 0) +#define UART1_RI_PC14 SIWX91X_GPIO(2, 0xFF, 10, 2, 14, 0) +#define UART1_RI_ULP4 SIWX91X_GPIO(11, 6, 26, 4, 4, 4) +#define UART1_RS485DE_PB13 SIWX91X_GPIO(13, 0xFF, 0, 1, 13, 0) +#define UART1_RS485DE_PD3 SIWX91X_GPIO(2, 0xFF, 15, 3, 3, 0) +#define UART1_RS485DE_ULP7 SIWX91X_GPIO(11, 6, 29, 4, 7, 7) +#define UART1_RS485DE_ULP11 SIWX91X_GPIO(2, 6, 33, 4, 11, 11) +#define UART1_RS485EN_PB11 SIWX91X_GPIO(13, 0xFF, 0, 1, 11, 0) +#define UART1_RS485EN_PD1 SIWX91X_GPIO(2, 0xFF, 13, 3, 1, 0) +#define UART1_RS485EN_ULP5 SIWX91X_GPIO(11, 6, 27, 4, 5, 5) +#define UART1_RS485EN_ULP9 SIWX91X_GPIO(2, 6, 31, 4, 9, 9) +#define UART1_RS485RE_PB12 SIWX91X_GPIO(13, 0xFF, 0, 1, 12, 0) +#define UART1_RS485RE_PD2 SIWX91X_GPIO(2, 0xFF, 14, 3, 2, 0) +#define UART1_RS485RE_ULP6 SIWX91X_GPIO(11, 6, 28, 4, 6, 6) +#define UART1_RS485RE_ULP10 SIWX91X_GPIO(2, 6, 32, 4, 10, 10) +#define UART1_RTS_PA9 SIWX91X_GPIO(2, 0xFF, 4, 0, 9, 0) +#define UART1_RTS_PB12 SIWX91X_GPIO(2, 0xFF, 0, 1, 12, 0) +#define UART1_RTS_PD5 SIWX91X_GPIO(2, 0xFF, 17, 3, 5, 0) +#define UART1_RTS_ULP5 SIWX91X_GPIO(2, 6, 27, 4, 5, 5) +#define UART1_RX_PA10 SIWX91X_GPIO(2, 0xFF, 5, 0, 10, 0) +#define UART1_RX_PB13 SIWX91X_GPIO(2, 0xFF, 0, 1, 13, 0) +#define UART1_RX_PD7 SIWX91X_GPIO(2, 0xFF, 19, 3, 7, 0) +#define UART1_RX_ULP1 SIWX91X_GPIO(2, 6, 23, 4, 1, 1) +#define UART1_RX_ULP6 SIWX91X_GPIO(4, 6, 28, 4, 6, 6) +#define UART1_TX_PB14 SIWX91X_GPIO(2, 0xFF, 0, 1, 14, 0) +#define UART1_TX_PD6 SIWX91X_GPIO(2, 0xFF, 18, 3, 6, 0) +#define UART1_TX_ULP4 SIWX91X_GPIO(2, 6, 26, 4, 4, 4) +#define UART1_TX_ULP7 SIWX91X_GPIO(4, 6, 29, 4, 7, 7) + +#define UART2_CTS_PA11 SIWX91X_GPIO(6, 0xFF, 6, 0, 11, 0) +#define UART2_CTS_PC0 SIWX91X_GPIO(12, 0xFF, 9, 2, 0, 0) +#define UART2_CTS_PD3 SIWX91X_GPIO(9, 0xFF, 15, 3, 3, 0) +#define UART2_CTS_ULP1 SIWX91X_GPIO(9, 6, 23, 4, 1, 1) +#define UART2_CTS_ULP7 SIWX91X_GPIO(6, 6, 29, 4, 7, 7) +#define UART2_CTS_ULP9 SIWX91X_GPIO(9, 6, 31, 4, 9, 9) +#define UART2_RS485DE_PA9 SIWX91X_GPIO(6, 0xFF, 4, 0, 9, 0) +#define UART2_RS485DE_ULP2 SIWX91X_GPIO(6, 6, 24, 4, 2, 2) +#define UART2_RS485DE_ULP11 SIWX91X_GPIO(6, 6, 33, 4, 11, 11) +#define UART2_RS485EN_PA12 SIWX91X_GPIO(6, 0xFF, 7, 0, 12, 0) +#define UART2_RS485EN_PB10 SIWX91X_GPIO(6, 0xFF, 0, 1, 10, 0) +#define UART2_RS485EN_ULP0 SIWX91X_GPIO(6, 6, 22, 4, 0, 0) +#define UART2_RS485RE_PA8 SIWX91X_GPIO(6, 0xFF, 3, 0, 8, 0) +#define UART2_RS485RE_ULP1 SIWX91X_GPIO(6, 6, 23, 4, 1, 1) +#define UART2_RS485RE_ULP10 SIWX91X_GPIO(6, 6, 32, 4, 10, 10) +#define UART2_RTS_PA10 SIWX91X_GPIO(6, 0xFF, 5, 0, 10, 0) +#define UART2_RTS_PB11 SIWX91X_GPIO(6, 0xFF, 0, 1, 11, 0) +#define UART2_RTS_PB12 SIWX91X_GPIO(6, 0xFF, 0, 1, 12, 0) +#define UART2_RTS_PB15 SIWX91X_GPIO(12, 0xFF, 9, 1, 15, 0) +#define UART2_RTS_PD2 SIWX91X_GPIO(9, 0xFF, 14, 3, 2, 0) +#define UART2_RTS_ULP0 SIWX91X_GPIO(9, 6, 22, 4, 0, 0) +#define UART2_RTS_ULP6 SIWX91X_GPIO(6, 6, 28, 4, 6, 6) +#define UART2_RTS_ULP8 SIWX91X_GPIO(9, 6, 30, 4, 8, 8) +#define UART2_RX_PA6 SIWX91X_GPIO(6, 0xFF, 1, 0, 6, 0) +#define UART2_RX_PB13 SIWX91X_GPIO(6, 0xFF, 0, 1, 13, 0) +#define UART2_RX_PC1 SIWX91X_GPIO(12, 0xFF, 9, 2, 1, 0) +#define UART2_RX_ULP2 SIWX91X_GPIO(9, 6, 24, 4, 1, 1) +#define UART2_RX_ULP4 SIWX91X_GPIO(6, 6, 26, 4, 4, 4) +#define UART2_RX_ULP8 SIWX91X_GPIO(6, 6, 30, 4, 8, 8) +#define UART2_RX_ULP10 SIWX91X_GPIO(9, 6, 32, 4, 10, 10) +#define UART2_TX_PA15 SIWX91X_GPIO(2, 0xFF, 8, 0, 15, 0) +#define UART2_TX_PA7 SIWX91X_GPIO(6, 0xFF, 2, 0, 7, 0) +#define UART2_TX_PB14 SIWX91X_GPIO(6, 0xFF, 0, 1, 14, 0) +#define UART2_TX_PC2 SIWX91X_GPIO(12, 0xFF, 9, 2, 2, 0) +#define UART2_TX_ULP3 SIWX91X_GPIO(9, 6, 25, 4, 1, 1) +#define UART2_TX_ULP5 SIWX91X_GPIO(6, 6, 27, 4, 5, 5) +#define UART2_TX_ULP9 SIWX91X_GPIO(6, 6, 31, 4, 9, 9) +#define UART2_TX_ULP11 SIWX91X_GPIO(9, 6, 33, 4, 11, 11) + +#define ULPI2C_SCL_PA11 SIWX91X_GPIO(9, 4, 6, 0, 11, 5) +#define ULPI2C_SCL_PA15 SIWX91X_GPIO(9, 4, 8, 0, 15, 7) +#define ULPI2C_SCL_PA7 SIWX91X_GPIO(9, 4, 2, 0, 7, 1) +#define ULPI2C_SCL_PB10 SIWX91X_GPIO(11, 4, 0, 1, 10, 7) +#define ULPI2C_SCL_PB11 SIWX91X_GPIO(11, 4, 0, 1, 11, 8) +#define ULPI2C_SCL_PC14 SIWX91X_GPIO(9, 4, 10, 2, 14, 8) +#define ULPI2C_SCL_ULP1 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 1) +#define ULPI2C_SCL_ULP5 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 5) +#define ULPI2C_SCL_ULP7 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 7) +#define ULPI2C_SCL_ULP8 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 8) +#define ULPI2C_SDA_PA6 SIWX91X_GPIO(9, 4, 1, 0, 6, 0) +#define ULPI2C_SDA_PA10 SIWX91X_GPIO(9, 4, 5, 0, 10, 4) +#define ULPI2C_SDA_PA12 SIWX91X_GPIO(9, 4, 7, 0, 12, 6) +#define ULPI2C_SDA_PB9 SIWX91X_GPIO(11, 4, 0, 1, 9, 6) +#define ULPI2C_SDA_PB12 SIWX91X_GPIO(11, 4, 0, 1, 12, 9) +#define ULPI2C_SDA_PB14 SIWX91X_GPIO(11, 4, 0, 1, 14, 11) +#define ULPI2C_SDA_PC15 SIWX91X_GPIO(9, 4, 11, 2, 15, 9) +#define ULPI2C_SDA_PD1 SIWX91X_GPIO(9, 4, 13, 3, 1, 11) +#define ULPI2C_SDA_ULP0 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 0) +#define ULPI2C_SDA_ULP4 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 4) +#define ULPI2C_SDA_ULP6 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 6) +#define ULPI2C_SDA_ULP9 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 9) +#define ULPI2C_SDA_ULP11 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 11) + +#define ULPI2S_CLK_PA15 SIWX91X_GPIO(9, 2, 8, 0, 15, 7) +#define ULPI2S_CLK_PB10 SIWX91X_GPIO(11, 2, 0, 1, 10, 7) +#define ULPI2S_CLK_PB11 SIWX91X_GPIO(11, 2, 0, 1, 11, 8) +#define ULPI2S_CLK_PC14 SIWX91X_GPIO(9, 2, 10, 2, 14, 8) +#define ULPI2S_CLK_ULP7 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 7) +#define ULPI2S_CLK_ULP8 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 8) +#define ULPI2S_DIN_PA12 SIWX91X_GPIO(9, 2, 7, 0, 12, 6) +#define ULPI2S_DIN_PA6 SIWX91X_GPIO(9, 2, 1, 0, 6, 0) +#define ULPI2S_DIN_PB9 SIWX91X_GPIO(11, 2, 0, 1, 9, 6) +#define ULPI2S_DIN_PB12 SIWX91X_GPIO(11, 2, 0, 1, 12, 9) +#define ULPI2S_DIN_PC15 SIWX91X_GPIO(9, 2, 11, 2, 15, 9) +#define ULPI2S_DIN_ULP0 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 0) +#define ULPI2S_DIN_ULP6 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 6) +#define ULPI2S_DIN_ULP9 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 9) +#define ULPI2S_DOUT_PA7 SIWX91X_GPIO(9, 2, 2, 0, 7, 1) +#define ULPI2S_DOUT_PA11 SIWX91X_GPIO(9, 2, 6, 0, 11, 5) +#define ULPI2S_DOUT_PB14 SIWX91X_GPIO(11, 2, 0, 1, 14, 11) +#define ULPI2S_DOUT_PD1 SIWX91X_GPIO(9, 2, 13, 3, 1, 11) +#define ULPI2S_DOUT_ULP1 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 1) +#define ULPI2S_DOUT_ULP5 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 5) +#define ULPI2S_DOUT_ULP11 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 11) +#define ULPI2S_WS_PA8 SIWX91X_GPIO(9, 2, 3, 0, 8, 2) +#define ULPI2S_WS_PA10 SIWX91X_GPIO(9, 2, 5, 0, 10, 4) +#define ULPI2S_WS_PB13 SIWX91X_GPIO(11, 2, 0, 1, 13, 10) +#define ULPI2S_WS_PD0 SIWX91X_GPIO(9, 2, 12, 3, 0, 10) +#define ULPI2S_WS_ULP2 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 2) +#define ULPI2S_WS_ULP4 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 4) +#define ULPI2S_WS_ULP10 SIWX91X_GPIO(0xFF, 2, 0xFF, 4, 0, 10) + +#define ULPSSI_CLK_PA6 SIWX91X_GPIO(9, 1, 1, 0, 6, 0) +#define ULPSSI_CLK_PB11 SIWX91X_GPIO(11, 1, 0, 1, 11, 8) +#define ULPSSI_CLK_PC14 SIWX91X_GPIO(9, 1, 10, 2, 14, 8) +#define ULPSSI_CLK_ULP0 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 0) +#define ULPSSI_CLK_ULP4 SIWX91X_GPIO(0xFF, 8, 0xFF, 4, 0, 4) +#define ULPSSI_CLK_ULP8 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 8) +#define ULPSSI_CS0_PB13 SIWX91X_GPIO(11, 1, 0, 1, 13, 10) +#define ULPSSI_CS0_PD0 SIWX91X_GPIO(9, 1, 12, 3, 0, 10) +#define ULPSSI_CS0_ULP7 SIWX91X_GPIO(0xFF, 8, 0xFF, 4, 0, 7) +#define ULPSSI_CS0_ULP10 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 10) +#define ULPSSI_CS1_PA10 SIWX91X_GPIO(9, 1, 5, 0, 10, 4) +#define ULPSSI_CS1_ULP4 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 4) +#define ULPSSI_CS2_PA12 SIWX91X_GPIO(9, 1, 7, 0, 12, 6) +#define ULPSSI_CS2_PB9 SIWX91X_GPIO(11, 1, 0, 1, 9, 6) +#define ULPSSI_CS2_ULP6 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 6) +#define ULPSSI_DIN_PA8 SIWX91X_GPIO(9, 1, 3, 0, 8, 2) +#define ULPSSI_DIN_PB12 SIWX91X_GPIO(11, 1, 0, 1, 12, 9) +#define ULPSSI_DIN_PC15 SIWX91X_GPIO(9, 1, 11, 2, 15, 9) +#define ULPSSI_DIN_ULP2 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 2) +#define ULPSSI_DIN_ULP6 SIWX91X_GPIO(0xFF, 8, 0xFF, 4, 0, 6) +#define ULPSSI_DIN_ULP9 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 9) +#define ULPSSI_DOUT_PA7 SIWX91X_GPIO(9, 1, 2, 0, 7, 1) +#define ULPSSI_DOUT_PB14 SIWX91X_GPIO(11, 1, 0, 1, 14, 11) +#define ULPSSI_DOUT_PD1 SIWX91X_GPIO(9, 1, 13, 3, 1, 11) +#define ULPSSI_DOUT_ULP1 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 1) +#define ULPSSI_DOUT_ULP5 SIWX91X_GPIO(0xFF, 8, 0xFF, 4, 0, 5) +#define ULPSSI_DOUT_ULP11 SIWX91X_GPIO(0xFF, 1, 0xFF, 4, 0, 11) + +#define ULPUART_CTS_PA7 SIWX91X_GPIO(9, 3, 2, 0, 7, 1) +#define ULPUART_CTS_PA11 SIWX91X_GPIO(9, 3, 6, 0, 11, 5) +#define ULPUART_CTS_PB11 SIWX91X_GPIO(11, 3, 0, 1, 11, 8) +#define ULPUART_CTS_PC14 SIWX91X_GPIO(9, 3, 10, 2, 14, 8) +#define ULPUART_CTS_ULP1 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 1) +#define ULPUART_CTS_ULP5 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 5) +#define ULPUART_CTS_ULP8 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 8) +#define ULPUART_RTS_PA6 SIWX91X_GPIO(9, 3, 1, 0, 6, 0) +#define ULPUART_RTS_PA10 SIWX91X_GPIO(9, 3, 5, 0, 10, 4) +#define ULPUART_RTS_PB13 SIWX91X_GPIO(11, 3, 0, 1, 13, 10) +#define ULPUART_RTS_PD0 SIWX91X_GPIO(9, 3, 12, 3, 0, 10) +#define ULPUART_RTS_ULP0 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 0) +#define ULPUART_RTS_ULP4 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 4) +#define ULPUART_RTS_ULP10 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 10) +#define ULPUART_RX_PA8 SIWX91X_GPIO(9, 3, 3, 0, 8, 2) +#define ULPUART_RX_PA12 SIWX91X_GPIO(9, 3, 7, 0, 12, 6) +#define ULPUART_RX_PB9 SIWX91X_GPIO(11, 3, 0, 1, 9, 6) +#define ULPUART_RX_PB12 SIWX91X_GPIO(11, 3, 0, 1, 12, 9) +#define ULPUART_RX_PC15 SIWX91X_GPIO(9, 3, 11, 2, 15, 9) +#define ULPUART_RX_ULP2 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 2) +#define ULPUART_RX_ULP6 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 6) +#define ULPUART_RX_ULP9 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 9) +#define ULPUART_TX_PA15 SIWX91X_GPIO(9, 3, 8, 0, 15, 7) +#define ULPUART_TX_PB10 SIWX91X_GPIO(11, 3, 0, 1, 10, 7) +#define ULPUART_TX_PB14 SIWX91X_GPIO(11, 3, 0, 1, 14, 11) +#define ULPUART_TX_PD1 SIWX91X_GPIO(9, 3, 13, 3, 1, 11) +#define ULPUART_TX_ULP7 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 7) +#define ULPUART_TX_ULP11 SIWX91X_GPIO(0xFF, 3, 0xFF, 4, 0, 11) + +#define UULP_GPIO4_ULP2 SIWX91X_GPIO(0xFF, 4, 0xFF, 4, 0, 2) +#define UULP_TESTMODE0_ULP7 SIWX91X_GPIO(0xFF, 11, 0xFF, 4, 0, 7) +#define UULP_TESTMODE0_ULP9 SIWX91X_GPIO(0xFF, 5, 0xFF, 4, 0, 9) + +/* clang-format on */ + +/* The following definitions are duplicates of signals that are also + * available on the same pins using other GPIO modes. + * #define IR_OUTPUT_ULP5 SIWX91X_GPIO(0xFF, 10, 0xFF, 4, 0, 5) + * #define PMU_TEST2_PB14 SIWX91X_GPIO(13, 0xFF, 0, 1, 14, 0) + * #define PWM_1H_ULP1 SIWX91X_GPIO(8, 6, 23, 4, 1, 1) + * #define PWM_1L_ULP0 SIWX91X_GPIO(8, 6, 22, 4, 0, 0) + */ + +#endif /* INCLUDE_ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_SIWX91X_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs/xg21-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/silabs/xg21-pinctrl.h index 4ab1c6ab486de..cc29205712daf 100644 --- a/include/zephyr/dt-bindings/pinctrl/silabs/xg21-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/silabs/xg21-pinctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Silicon Laboratories Inc. + * Copyright (c) 2025 Silicon Laboratories Inc. * SPDX-License-Identifier: Apache-2.0 * * Pin Control for Silicon Labs XG21 devices @@ -1185,4 +1185,41 @@ #define USART2_CTS_PD3 SILABS_DBUS_USART2_CTS(0x3, 0x3) #define USART2_CTS_PD4 SILABS_DBUS_USART2_CTS(0x3, 0x4) +#define ABUS_AEVEN0_IADC0 SILABS_ABUS(0x0, 0x0, 0x1) +#define ABUS_AEVEN0_ACMP0 SILABS_ABUS(0x0, 0x0, 0x2) +#define ABUS_AEVEN0_ACMP1 SILABS_ABUS(0x0, 0x0, 0x3) +#define ABUS_AEVEN1_IADC0 SILABS_ABUS(0x0, 0x1, 0x1) +#define ABUS_AEVEN1_ACMP0 SILABS_ABUS(0x0, 0x1, 0x2) +#define ABUS_AEVEN1_ACMP1 SILABS_ABUS(0x0, 0x1, 0x3) +#define ABUS_AODD0_IADC0 SILABS_ABUS(0x0, 0x2, 0x1) +#define ABUS_AODD0_ACMP0 SILABS_ABUS(0x0, 0x2, 0x2) +#define ABUS_AODD0_ACMP1 SILABS_ABUS(0x0, 0x2, 0x3) +#define ABUS_AODD1_IADC0 SILABS_ABUS(0x0, 0x3, 0x1) +#define ABUS_AODD1_ACMP0 SILABS_ABUS(0x0, 0x3, 0x2) +#define ABUS_AODD1_ACMP1 SILABS_ABUS(0x0, 0x3, 0x3) +#define ABUS_BEVEN0_IADC0 SILABS_ABUS(0x1, 0x0, 0x1) +#define ABUS_BEVEN0_ACMP0 SILABS_ABUS(0x1, 0x0, 0x2) +#define ABUS_BEVEN0_ACMP1 SILABS_ABUS(0x1, 0x0, 0x3) +#define ABUS_BEVEN1_IADC0 SILABS_ABUS(0x1, 0x1, 0x1) +#define ABUS_BEVEN1_ACMP0 SILABS_ABUS(0x1, 0x1, 0x2) +#define ABUS_BEVEN1_ACMP1 SILABS_ABUS(0x1, 0x1, 0x3) +#define ABUS_BODD0_IADC0 SILABS_ABUS(0x1, 0x2, 0x1) +#define ABUS_BODD0_ACMP0 SILABS_ABUS(0x1, 0x2, 0x2) +#define ABUS_BODD0_ACMP1 SILABS_ABUS(0x1, 0x2, 0x3) +#define ABUS_BODD1_IADC0 SILABS_ABUS(0x1, 0x3, 0x1) +#define ABUS_BODD1_ACMP0 SILABS_ABUS(0x1, 0x3, 0x2) +#define ABUS_BODD1_ACMP1 SILABS_ABUS(0x1, 0x3, 0x3) +#define ABUS_CDEVEN0_IADC0 SILABS_ABUS(0x2, 0x0, 0x1) +#define ABUS_CDEVEN0_ACMP0 SILABS_ABUS(0x2, 0x0, 0x2) +#define ABUS_CDEVEN0_ACMP1 SILABS_ABUS(0x2, 0x0, 0x3) +#define ABUS_CDEVEN1_IADC0 SILABS_ABUS(0x2, 0x1, 0x1) +#define ABUS_CDEVEN1_ACMP0 SILABS_ABUS(0x2, 0x1, 0x2) +#define ABUS_CDEVEN1_ACMP1 SILABS_ABUS(0x2, 0x1, 0x3) +#define ABUS_CDODD0_IADC0 SILABS_ABUS(0x2, 0x2, 0x1) +#define ABUS_CDODD0_ACMP0 SILABS_ABUS(0x2, 0x2, 0x2) +#define ABUS_CDODD0_ACMP1 SILABS_ABUS(0x2, 0x2, 0x3) +#define ABUS_CDODD1_IADC0 SILABS_ABUS(0x2, 0x3, 0x1) +#define ABUS_CDODD1_ACMP0 SILABS_ABUS(0x2, 0x3, 0x2) +#define ABUS_CDODD1_ACMP1 SILABS_ABUS(0x2, 0x3, 0x3) + #endif /* ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG21_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs/xg22-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/silabs/xg22-pinctrl.h index d276d1f5989ac..900b1ea2e42b2 100644 --- a/include/zephyr/dt-bindings/pinctrl/silabs/xg22-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/silabs/xg22-pinctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Silicon Laboratories Inc. + * Copyright (c) 2025 Silicon Laboratories Inc. * SPDX-License-Identifier: Apache-2.0 * * Pin Control for Silicon Labs XG22 devices @@ -1789,4 +1789,17 @@ #define USART1_CTS_PB3 SILABS_DBUS_USART1_CTS(0x1, 0x3) #define USART1_CTS_PB4 SILABS_DBUS_USART1_CTS(0x1, 0x4) +#define ABUS_AEVEN0_IADC0 SILABS_ABUS(0x0, 0x0, 0x1) +#define ABUS_AEVEN1_IADC0 SILABS_ABUS(0x0, 0x1, 0x1) +#define ABUS_AODD0_IADC0 SILABS_ABUS(0x0, 0x2, 0x1) +#define ABUS_AODD1_IADC0 SILABS_ABUS(0x0, 0x3, 0x1) +#define ABUS_BEVEN0_IADC0 SILABS_ABUS(0x1, 0x0, 0x1) +#define ABUS_BEVEN1_IADC0 SILABS_ABUS(0x1, 0x1, 0x1) +#define ABUS_BODD0_IADC0 SILABS_ABUS(0x1, 0x2, 0x1) +#define ABUS_BODD1_IADC0 SILABS_ABUS(0x1, 0x3, 0x1) +#define ABUS_CDEVEN0_IADC0 SILABS_ABUS(0x2, 0x0, 0x1) +#define ABUS_CDEVEN1_IADC0 SILABS_ABUS(0x2, 0x1, 0x1) +#define ABUS_CDODD0_IADC0 SILABS_ABUS(0x2, 0x2, 0x1) +#define ABUS_CDODD1_IADC0 SILABS_ABUS(0x2, 0x3, 0x1) + #endif /* ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG22_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs/xg23-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/silabs/xg23-pinctrl.h new file mode 100644 index 0000000000000..b8ca05d3dd3af --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/silabs/xg23-pinctrl.h @@ -0,0 +1,3253 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + * + * Pin Control for Silicon Labs XG23 devices + * + * This file was generated by the script gen_pinctrl.py in the hal_silabs module. + * Do not manually edit. + */ + +#ifndef ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG23_PINCTRL_H_ +#define ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG23_PINCTRL_H_ + +#include + +#define SILABS_DBUS_ACMP0_ACMPOUT(port, pin) SILABS_DBUS(port, pin, 16, 1, 0, 1) + +#define SILABS_DBUS_ACMP1_ACMPOUT(port, pin) SILABS_DBUS(port, pin, 19, 1, 0, 1) + +#define SILABS_DBUS_CMU_CLKOUT0(port, pin) SILABS_DBUS(port, pin, 22, 1, 0, 2) +#define SILABS_DBUS_CMU_CLKOUT1(port, pin) SILABS_DBUS(port, pin, 22, 1, 1, 3) +#define SILABS_DBUS_CMU_CLKOUT2(port, pin) SILABS_DBUS(port, pin, 22, 1, 2, 4) +#define SILABS_DBUS_CMU_CLKIN0(port, pin) SILABS_DBUS(port, pin, 22, 0, 0, 1) + +#define SILABS_DBUS_EUSART0_CS(port, pin) SILABS_DBUS(port, pin, 33, 1, 0, 1) +#define SILABS_DBUS_EUSART0_RTS(port, pin) SILABS_DBUS(port, pin, 33, 1, 1, 3) +#define SILABS_DBUS_EUSART0_RX(port, pin) SILABS_DBUS(port, pin, 33, 1, 2, 4) +#define SILABS_DBUS_EUSART0_SCLK(port, pin) SILABS_DBUS(port, pin, 33, 1, 3, 5) +#define SILABS_DBUS_EUSART0_TX(port, pin) SILABS_DBUS(port, pin, 33, 1, 4, 6) +#define SILABS_DBUS_EUSART0_CTS(port, pin) SILABS_DBUS(port, pin, 33, 0, 0, 2) + +#define SILABS_DBUS_EUSART1_CS(port, pin) SILABS_DBUS(port, pin, 41, 1, 0, 1) +#define SILABS_DBUS_EUSART1_RTS(port, pin) SILABS_DBUS(port, pin, 41, 1, 1, 3) +#define SILABS_DBUS_EUSART1_RX(port, pin) SILABS_DBUS(port, pin, 41, 1, 2, 4) +#define SILABS_DBUS_EUSART1_SCLK(port, pin) SILABS_DBUS(port, pin, 41, 1, 3, 5) +#define SILABS_DBUS_EUSART1_TX(port, pin) SILABS_DBUS(port, pin, 41, 1, 4, 6) +#define SILABS_DBUS_EUSART1_CTS(port, pin) SILABS_DBUS(port, pin, 41, 0, 0, 2) + +#define SILABS_DBUS_EUSART2_CS(port, pin) SILABS_DBUS(port, pin, 49, 1, 0, 1) +#define SILABS_DBUS_EUSART2_RTS(port, pin) SILABS_DBUS(port, pin, 49, 1, 1, 3) +#define SILABS_DBUS_EUSART2_RX(port, pin) SILABS_DBUS(port, pin, 49, 1, 2, 4) +#define SILABS_DBUS_EUSART2_SCLK(port, pin) SILABS_DBUS(port, pin, 49, 1, 3, 5) +#define SILABS_DBUS_EUSART2_TX(port, pin) SILABS_DBUS(port, pin, 49, 1, 4, 6) +#define SILABS_DBUS_EUSART2_CTS(port, pin) SILABS_DBUS(port, pin, 49, 0, 0, 2) + +#define SILABS_DBUS_PTI_DCLK(port, pin) SILABS_DBUS(port, pin, 57, 1, 0, 1) +#define SILABS_DBUS_PTI_DFRAME(port, pin) SILABS_DBUS(port, pin, 57, 1, 1, 2) +#define SILABS_DBUS_PTI_DOUT(port, pin) SILABS_DBUS(port, pin, 57, 1, 2, 3) + +#define SILABS_DBUS_I2C0_SCL(port, pin) SILABS_DBUS(port, pin, 62, 1, 0, 1) +#define SILABS_DBUS_I2C0_SDA(port, pin) SILABS_DBUS(port, pin, 62, 1, 1, 2) + +#define SILABS_DBUS_I2C1_SCL(port, pin) SILABS_DBUS(port, pin, 66, 1, 0, 1) +#define SILABS_DBUS_I2C1_SDA(port, pin) SILABS_DBUS(port, pin, 66, 1, 1, 2) + +#define SILABS_DBUS_KEYSCAN_COLOUT0(port, pin) SILABS_DBUS(port, pin, 70, 1, 0, 1) +#define SILABS_DBUS_KEYSCAN_COLOUT1(port, pin) SILABS_DBUS(port, pin, 70, 1, 1, 2) +#define SILABS_DBUS_KEYSCAN_COLOUT2(port, pin) SILABS_DBUS(port, pin, 70, 1, 2, 3) +#define SILABS_DBUS_KEYSCAN_COLOUT3(port, pin) SILABS_DBUS(port, pin, 70, 1, 3, 4) +#define SILABS_DBUS_KEYSCAN_COLOUT4(port, pin) SILABS_DBUS(port, pin, 70, 1, 4, 5) +#define SILABS_DBUS_KEYSCAN_COLOUT5(port, pin) SILABS_DBUS(port, pin, 70, 1, 5, 6) +#define SILABS_DBUS_KEYSCAN_COLOUT6(port, pin) SILABS_DBUS(port, pin, 70, 1, 6, 7) +#define SILABS_DBUS_KEYSCAN_COLOUT7(port, pin) SILABS_DBUS(port, pin, 70, 1, 7, 8) +#define SILABS_DBUS_KEYSCAN_ROWSENSE0(port, pin) SILABS_DBUS(port, pin, 70, 0, 0, 9) +#define SILABS_DBUS_KEYSCAN_ROWSENSE1(port, pin) SILABS_DBUS(port, pin, 70, 0, 0, 10) +#define SILABS_DBUS_KEYSCAN_ROWSENSE2(port, pin) SILABS_DBUS(port, pin, 70, 0, 0, 11) +#define SILABS_DBUS_KEYSCAN_ROWSENSE3(port, pin) SILABS_DBUS(port, pin, 70, 0, 0, 12) +#define SILABS_DBUS_KEYSCAN_ROWSENSE4(port, pin) SILABS_DBUS(port, pin, 70, 0, 0, 13) +#define SILABS_DBUS_KEYSCAN_ROWSENSE5(port, pin) SILABS_DBUS(port, pin, 70, 0, 0, 14) + +#define SILABS_DBUS_LESENSE_CH0OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 0, 1) +#define SILABS_DBUS_LESENSE_CH1OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 1, 2) +#define SILABS_DBUS_LESENSE_CH2OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 2, 3) +#define SILABS_DBUS_LESENSE_CH3OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 3, 4) +#define SILABS_DBUS_LESENSE_CH4OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 4, 5) +#define SILABS_DBUS_LESENSE_CH5OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 5, 6) +#define SILABS_DBUS_LESENSE_CH6OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 6, 7) +#define SILABS_DBUS_LESENSE_CH7OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 7, 8) +#define SILABS_DBUS_LESENSE_CH8OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 8, 9) +#define SILABS_DBUS_LESENSE_CH9OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 9, 10) +#define SILABS_DBUS_LESENSE_CH10OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 10, 11) +#define SILABS_DBUS_LESENSE_CH11OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 11, 12) +#define SILABS_DBUS_LESENSE_CH12OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 12, 13) +#define SILABS_DBUS_LESENSE_CH13OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 13, 14) +#define SILABS_DBUS_LESENSE_CH14OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 14, 15) +#define SILABS_DBUS_LESENSE_CH15OUT(port, pin) SILABS_DBUS(port, pin, 86, 1, 15, 16) + +#define SILABS_DBUS_LETIMER0_OUT0(port, pin) SILABS_DBUS(port, pin, 104, 1, 0, 1) +#define SILABS_DBUS_LETIMER0_OUT1(port, pin) SILABS_DBUS(port, pin, 104, 1, 1, 2) + +#define SILABS_DBUS_MODEM_ANT0(port, pin) SILABS_DBUS(port, pin, 108, 1, 0, 1) +#define SILABS_DBUS_MODEM_ANT1(port, pin) SILABS_DBUS(port, pin, 108, 1, 1, 2) +#define SILABS_DBUS_MODEM_ANTROLLOVER(port, pin) SILABS_DBUS(port, pin, 108, 1, 2, 3) +#define SILABS_DBUS_MODEM_ANTRR0(port, pin) SILABS_DBUS(port, pin, 108, 1, 3, 4) +#define SILABS_DBUS_MODEM_ANTRR1(port, pin) SILABS_DBUS(port, pin, 108, 1, 4, 5) +#define SILABS_DBUS_MODEM_ANTRR2(port, pin) SILABS_DBUS(port, pin, 108, 1, 5, 6) +#define SILABS_DBUS_MODEM_ANTRR3(port, pin) SILABS_DBUS(port, pin, 108, 1, 6, 7) +#define SILABS_DBUS_MODEM_ANTRR4(port, pin) SILABS_DBUS(port, pin, 108, 1, 7, 8) +#define SILABS_DBUS_MODEM_ANTRR5(port, pin) SILABS_DBUS(port, pin, 108, 1, 8, 9) +#define SILABS_DBUS_MODEM_ANTSWEN(port, pin) SILABS_DBUS(port, pin, 108, 1, 9, 10) +#define SILABS_DBUS_MODEM_ANTSWUS(port, pin) SILABS_DBUS(port, pin, 108, 1, 10, 11) +#define SILABS_DBUS_MODEM_ANTTRIG(port, pin) SILABS_DBUS(port, pin, 108, 1, 11, 12) +#define SILABS_DBUS_MODEM_ANTTRIGSTOP(port, pin) SILABS_DBUS(port, pin, 108, 1, 12, 13) +#define SILABS_DBUS_MODEM_DCLK(port, pin) SILABS_DBUS(port, pin, 108, 1, 13, 14) +#define SILABS_DBUS_MODEM_DOUT(port, pin) SILABS_DBUS(port, pin, 108, 1, 14, 16) +#define SILABS_DBUS_MODEM_DIN(port, pin) SILABS_DBUS(port, pin, 108, 0, 0, 15) + +#define SILABS_DBUS_PCNT0_S0IN(port, pin) SILABS_DBUS(port, pin, 127, 0, 0, 0) +#define SILABS_DBUS_PCNT0_S1IN(port, pin) SILABS_DBUS(port, pin, 127, 0, 0, 1) + +#define SILABS_DBUS_PRS0_ASYNCH0(port, pin) SILABS_DBUS(port, pin, 130, 1, 0, 1) +#define SILABS_DBUS_PRS0_ASYNCH1(port, pin) SILABS_DBUS(port, pin, 130, 1, 1, 2) +#define SILABS_DBUS_PRS0_ASYNCH2(port, pin) SILABS_DBUS(port, pin, 130, 1, 2, 3) +#define SILABS_DBUS_PRS0_ASYNCH3(port, pin) SILABS_DBUS(port, pin, 130, 1, 3, 4) +#define SILABS_DBUS_PRS0_ASYNCH4(port, pin) SILABS_DBUS(port, pin, 130, 1, 4, 5) +#define SILABS_DBUS_PRS0_ASYNCH5(port, pin) SILABS_DBUS(port, pin, 130, 1, 5, 6) +#define SILABS_DBUS_PRS0_ASYNCH6(port, pin) SILABS_DBUS(port, pin, 130, 1, 6, 7) +#define SILABS_DBUS_PRS0_ASYNCH7(port, pin) SILABS_DBUS(port, pin, 130, 1, 7, 8) +#define SILABS_DBUS_PRS0_ASYNCH8(port, pin) SILABS_DBUS(port, pin, 130, 1, 8, 9) +#define SILABS_DBUS_PRS0_ASYNCH9(port, pin) SILABS_DBUS(port, pin, 130, 1, 9, 10) +#define SILABS_DBUS_PRS0_ASYNCH10(port, pin) SILABS_DBUS(port, pin, 130, 1, 10, 11) +#define SILABS_DBUS_PRS0_ASYNCH11(port, pin) SILABS_DBUS(port, pin, 130, 1, 11, 12) +#define SILABS_DBUS_PRS0_SYNCH0(port, pin) SILABS_DBUS(port, pin, 130, 1, 12, 13) +#define SILABS_DBUS_PRS0_SYNCH1(port, pin) SILABS_DBUS(port, pin, 130, 1, 13, 14) +#define SILABS_DBUS_PRS0_SYNCH2(port, pin) SILABS_DBUS(port, pin, 130, 1, 14, 15) +#define SILABS_DBUS_PRS0_SYNCH3(port, pin) SILABS_DBUS(port, pin, 130, 1, 15, 16) + +#define SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(port, pin) SILABS_DBUS(port, pin, 172, 0, 0, 0) + +#define SILABS_DBUS_TIMER0_CC0(port, pin) SILABS_DBUS(port, pin, 174, 1, 0, 1) +#define SILABS_DBUS_TIMER0_CC1(port, pin) SILABS_DBUS(port, pin, 174, 1, 1, 2) +#define SILABS_DBUS_TIMER0_CC2(port, pin) SILABS_DBUS(port, pin, 174, 1, 2, 3) +#define SILABS_DBUS_TIMER0_CDTI0(port, pin) SILABS_DBUS(port, pin, 174, 1, 3, 4) +#define SILABS_DBUS_TIMER0_CDTI1(port, pin) SILABS_DBUS(port, pin, 174, 1, 4, 5) +#define SILABS_DBUS_TIMER0_CDTI2(port, pin) SILABS_DBUS(port, pin, 174, 1, 5, 6) + +#define SILABS_DBUS_TIMER1_CC0(port, pin) SILABS_DBUS(port, pin, 182, 1, 0, 1) +#define SILABS_DBUS_TIMER1_CC1(port, pin) SILABS_DBUS(port, pin, 182, 1, 1, 2) +#define SILABS_DBUS_TIMER1_CC2(port, pin) SILABS_DBUS(port, pin, 182, 1, 2, 3) +#define SILABS_DBUS_TIMER1_CDTI0(port, pin) SILABS_DBUS(port, pin, 182, 1, 3, 4) +#define SILABS_DBUS_TIMER1_CDTI1(port, pin) SILABS_DBUS(port, pin, 182, 1, 4, 5) +#define SILABS_DBUS_TIMER1_CDTI2(port, pin) SILABS_DBUS(port, pin, 182, 1, 5, 6) + +#define SILABS_DBUS_TIMER2_CC0(port, pin) SILABS_DBUS(port, pin, 190, 1, 0, 1) +#define SILABS_DBUS_TIMER2_CC1(port, pin) SILABS_DBUS(port, pin, 190, 1, 1, 2) +#define SILABS_DBUS_TIMER2_CC2(port, pin) SILABS_DBUS(port, pin, 190, 1, 2, 3) +#define SILABS_DBUS_TIMER2_CDTI0(port, pin) SILABS_DBUS(port, pin, 190, 1, 3, 4) +#define SILABS_DBUS_TIMER2_CDTI1(port, pin) SILABS_DBUS(port, pin, 190, 1, 4, 5) +#define SILABS_DBUS_TIMER2_CDTI2(port, pin) SILABS_DBUS(port, pin, 190, 1, 5, 6) + +#define SILABS_DBUS_TIMER3_CC0(port, pin) SILABS_DBUS(port, pin, 198, 1, 0, 1) +#define SILABS_DBUS_TIMER3_CC1(port, pin) SILABS_DBUS(port, pin, 198, 1, 1, 2) +#define SILABS_DBUS_TIMER3_CC2(port, pin) SILABS_DBUS(port, pin, 198, 1, 2, 3) +#define SILABS_DBUS_TIMER3_CDTI0(port, pin) SILABS_DBUS(port, pin, 198, 1, 3, 4) +#define SILABS_DBUS_TIMER3_CDTI1(port, pin) SILABS_DBUS(port, pin, 198, 1, 4, 5) +#define SILABS_DBUS_TIMER3_CDTI2(port, pin) SILABS_DBUS(port, pin, 198, 1, 5, 6) + +#define SILABS_DBUS_TIMER4_CC0(port, pin) SILABS_DBUS(port, pin, 206, 1, 0, 1) +#define SILABS_DBUS_TIMER4_CC1(port, pin) SILABS_DBUS(port, pin, 206, 1, 1, 2) +#define SILABS_DBUS_TIMER4_CC2(port, pin) SILABS_DBUS(port, pin, 206, 1, 2, 3) +#define SILABS_DBUS_TIMER4_CDTI0(port, pin) SILABS_DBUS(port, pin, 206, 1, 3, 4) +#define SILABS_DBUS_TIMER4_CDTI1(port, pin) SILABS_DBUS(port, pin, 206, 1, 4, 5) +#define SILABS_DBUS_TIMER4_CDTI2(port, pin) SILABS_DBUS(port, pin, 206, 1, 5, 6) + +#define SILABS_DBUS_USART0_CS(port, pin) SILABS_DBUS(port, pin, 214, 1, 0, 1) +#define SILABS_DBUS_USART0_RTS(port, pin) SILABS_DBUS(port, pin, 214, 1, 1, 3) +#define SILABS_DBUS_USART0_RX(port, pin) SILABS_DBUS(port, pin, 214, 1, 2, 4) +#define SILABS_DBUS_USART0_CLK(port, pin) SILABS_DBUS(port, pin, 214, 1, 3, 5) +#define SILABS_DBUS_USART0_TX(port, pin) SILABS_DBUS(port, pin, 214, 1, 4, 6) +#define SILABS_DBUS_USART0_CTS(port, pin) SILABS_DBUS(port, pin, 214, 0, 0, 2) + +#define ACMP0_ACMPOUT_PA0 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x0) +#define ACMP0_ACMPOUT_PA1 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x1) +#define ACMP0_ACMPOUT_PA2 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x2) +#define ACMP0_ACMPOUT_PA3 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x3) +#define ACMP0_ACMPOUT_PA4 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x4) +#define ACMP0_ACMPOUT_PA5 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x5) +#define ACMP0_ACMPOUT_PA6 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x6) +#define ACMP0_ACMPOUT_PA7 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x7) +#define ACMP0_ACMPOUT_PA8 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x8) +#define ACMP0_ACMPOUT_PA9 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x9) +#define ACMP0_ACMPOUT_PA10 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0xa) +#define ACMP0_ACMPOUT_PB0 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x0) +#define ACMP0_ACMPOUT_PB1 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x1) +#define ACMP0_ACMPOUT_PB2 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x2) +#define ACMP0_ACMPOUT_PB3 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x3) +#define ACMP0_ACMPOUT_PB4 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x4) +#define ACMP0_ACMPOUT_PB5 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x5) +#define ACMP0_ACMPOUT_PB6 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x6) +#define ACMP0_ACMPOUT_PC0 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x0) +#define ACMP0_ACMPOUT_PC1 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x1) +#define ACMP0_ACMPOUT_PC2 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x2) +#define ACMP0_ACMPOUT_PC3 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x3) +#define ACMP0_ACMPOUT_PC4 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x4) +#define ACMP0_ACMPOUT_PC5 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x5) +#define ACMP0_ACMPOUT_PC6 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x6) +#define ACMP0_ACMPOUT_PC7 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x7) +#define ACMP0_ACMPOUT_PC8 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x8) +#define ACMP0_ACMPOUT_PC9 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x9) +#define ACMP0_ACMPOUT_PD0 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x0) +#define ACMP0_ACMPOUT_PD1 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x1) +#define ACMP0_ACMPOUT_PD2 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x2) +#define ACMP0_ACMPOUT_PD3 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x3) +#define ACMP0_ACMPOUT_PD4 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x4) +#define ACMP0_ACMPOUT_PD5 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x5) + +#define ACMP1_ACMPOUT_PA0 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x0) +#define ACMP1_ACMPOUT_PA1 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x1) +#define ACMP1_ACMPOUT_PA2 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x2) +#define ACMP1_ACMPOUT_PA3 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x3) +#define ACMP1_ACMPOUT_PA4 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x4) +#define ACMP1_ACMPOUT_PA5 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x5) +#define ACMP1_ACMPOUT_PA6 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x6) +#define ACMP1_ACMPOUT_PA7 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x7) +#define ACMP1_ACMPOUT_PA8 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x8) +#define ACMP1_ACMPOUT_PA9 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0x9) +#define ACMP1_ACMPOUT_PA10 SILABS_DBUS_ACMP1_ACMPOUT(0x0, 0xa) +#define ACMP1_ACMPOUT_PB0 SILABS_DBUS_ACMP1_ACMPOUT(0x1, 0x0) +#define ACMP1_ACMPOUT_PB1 SILABS_DBUS_ACMP1_ACMPOUT(0x1, 0x1) +#define ACMP1_ACMPOUT_PB2 SILABS_DBUS_ACMP1_ACMPOUT(0x1, 0x2) +#define ACMP1_ACMPOUT_PB3 SILABS_DBUS_ACMP1_ACMPOUT(0x1, 0x3) +#define ACMP1_ACMPOUT_PB4 SILABS_DBUS_ACMP1_ACMPOUT(0x1, 0x4) +#define ACMP1_ACMPOUT_PB5 SILABS_DBUS_ACMP1_ACMPOUT(0x1, 0x5) +#define ACMP1_ACMPOUT_PB6 SILABS_DBUS_ACMP1_ACMPOUT(0x1, 0x6) +#define ACMP1_ACMPOUT_PC0 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x0) +#define ACMP1_ACMPOUT_PC1 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x1) +#define ACMP1_ACMPOUT_PC2 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x2) +#define ACMP1_ACMPOUT_PC3 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x3) +#define ACMP1_ACMPOUT_PC4 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x4) +#define ACMP1_ACMPOUT_PC5 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x5) +#define ACMP1_ACMPOUT_PC6 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x6) +#define ACMP1_ACMPOUT_PC7 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x7) +#define ACMP1_ACMPOUT_PC8 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x8) +#define ACMP1_ACMPOUT_PC9 SILABS_DBUS_ACMP1_ACMPOUT(0x2, 0x9) +#define ACMP1_ACMPOUT_PD0 SILABS_DBUS_ACMP1_ACMPOUT(0x3, 0x0) +#define ACMP1_ACMPOUT_PD1 SILABS_DBUS_ACMP1_ACMPOUT(0x3, 0x1) +#define ACMP1_ACMPOUT_PD2 SILABS_DBUS_ACMP1_ACMPOUT(0x3, 0x2) +#define ACMP1_ACMPOUT_PD3 SILABS_DBUS_ACMP1_ACMPOUT(0x3, 0x3) +#define ACMP1_ACMPOUT_PD4 SILABS_DBUS_ACMP1_ACMPOUT(0x3, 0x4) +#define ACMP1_ACMPOUT_PD5 SILABS_DBUS_ACMP1_ACMPOUT(0x3, 0x5) + +#define CMU_CLKOUT0_PC0 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x0) +#define CMU_CLKOUT0_PC1 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x1) +#define CMU_CLKOUT0_PC2 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x2) +#define CMU_CLKOUT0_PC3 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x3) +#define CMU_CLKOUT0_PC4 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x4) +#define CMU_CLKOUT0_PC5 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x5) +#define CMU_CLKOUT0_PC6 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x6) +#define CMU_CLKOUT0_PC7 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x7) +#define CMU_CLKOUT0_PC8 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x8) +#define CMU_CLKOUT0_PC9 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x9) +#define CMU_CLKOUT0_PD0 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x0) +#define CMU_CLKOUT0_PD1 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x1) +#define CMU_CLKOUT0_PD2 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x2) +#define CMU_CLKOUT0_PD3 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x3) +#define CMU_CLKOUT0_PD4 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x4) +#define CMU_CLKOUT0_PD5 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x5) +#define CMU_CLKOUT1_PC0 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x0) +#define CMU_CLKOUT1_PC1 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x1) +#define CMU_CLKOUT1_PC2 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x2) +#define CMU_CLKOUT1_PC3 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x3) +#define CMU_CLKOUT1_PC4 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x4) +#define CMU_CLKOUT1_PC5 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x5) +#define CMU_CLKOUT1_PC6 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x6) +#define CMU_CLKOUT1_PC7 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x7) +#define CMU_CLKOUT1_PC8 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x8) +#define CMU_CLKOUT1_PC9 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x9) +#define CMU_CLKOUT1_PD0 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x0) +#define CMU_CLKOUT1_PD1 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x1) +#define CMU_CLKOUT1_PD2 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x2) +#define CMU_CLKOUT1_PD3 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x3) +#define CMU_CLKOUT1_PD4 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x4) +#define CMU_CLKOUT1_PD5 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x5) +#define CMU_CLKOUT2_PA0 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x0) +#define CMU_CLKOUT2_PA1 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x1) +#define CMU_CLKOUT2_PA2 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x2) +#define CMU_CLKOUT2_PA3 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x3) +#define CMU_CLKOUT2_PA4 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x4) +#define CMU_CLKOUT2_PA5 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x5) +#define CMU_CLKOUT2_PA6 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x6) +#define CMU_CLKOUT2_PA7 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x7) +#define CMU_CLKOUT2_PA8 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x8) +#define CMU_CLKOUT2_PA9 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x9) +#define CMU_CLKOUT2_PA10 SILABS_DBUS_CMU_CLKOUT2(0x0, 0xa) +#define CMU_CLKOUT2_PB0 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x0) +#define CMU_CLKOUT2_PB1 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x1) +#define CMU_CLKOUT2_PB2 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x2) +#define CMU_CLKOUT2_PB3 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x3) +#define CMU_CLKOUT2_PB4 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x4) +#define CMU_CLKOUT2_PB5 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x5) +#define CMU_CLKOUT2_PB6 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x6) +#define CMU_CLKIN0_PC0 SILABS_DBUS_CMU_CLKIN0(0x2, 0x0) +#define CMU_CLKIN0_PC1 SILABS_DBUS_CMU_CLKIN0(0x2, 0x1) +#define CMU_CLKIN0_PC2 SILABS_DBUS_CMU_CLKIN0(0x2, 0x2) +#define CMU_CLKIN0_PC3 SILABS_DBUS_CMU_CLKIN0(0x2, 0x3) +#define CMU_CLKIN0_PC4 SILABS_DBUS_CMU_CLKIN0(0x2, 0x4) +#define CMU_CLKIN0_PC5 SILABS_DBUS_CMU_CLKIN0(0x2, 0x5) +#define CMU_CLKIN0_PC6 SILABS_DBUS_CMU_CLKIN0(0x2, 0x6) +#define CMU_CLKIN0_PC7 SILABS_DBUS_CMU_CLKIN0(0x2, 0x7) +#define CMU_CLKIN0_PC8 SILABS_DBUS_CMU_CLKIN0(0x2, 0x8) +#define CMU_CLKIN0_PC9 SILABS_DBUS_CMU_CLKIN0(0x2, 0x9) +#define CMU_CLKIN0_PD0 SILABS_DBUS_CMU_CLKIN0(0x3, 0x0) +#define CMU_CLKIN0_PD1 SILABS_DBUS_CMU_CLKIN0(0x3, 0x1) +#define CMU_CLKIN0_PD2 SILABS_DBUS_CMU_CLKIN0(0x3, 0x2) +#define CMU_CLKIN0_PD3 SILABS_DBUS_CMU_CLKIN0(0x3, 0x3) +#define CMU_CLKIN0_PD4 SILABS_DBUS_CMU_CLKIN0(0x3, 0x4) +#define CMU_CLKIN0_PD5 SILABS_DBUS_CMU_CLKIN0(0x3, 0x5) + +#define EUSART0_CS_PA0 SILABS_DBUS_EUSART0_CS(0x0, 0x0) +#define EUSART0_CS_PA1 SILABS_DBUS_EUSART0_CS(0x0, 0x1) +#define EUSART0_CS_PA2 SILABS_DBUS_EUSART0_CS(0x0, 0x2) +#define EUSART0_CS_PA3 SILABS_DBUS_EUSART0_CS(0x0, 0x3) +#define EUSART0_CS_PA4 SILABS_DBUS_EUSART0_CS(0x0, 0x4) +#define EUSART0_CS_PA5 SILABS_DBUS_EUSART0_CS(0x0, 0x5) +#define EUSART0_CS_PA6 SILABS_DBUS_EUSART0_CS(0x0, 0x6) +#define EUSART0_CS_PA7 SILABS_DBUS_EUSART0_CS(0x0, 0x7) +#define EUSART0_CS_PA8 SILABS_DBUS_EUSART0_CS(0x0, 0x8) +#define EUSART0_CS_PA9 SILABS_DBUS_EUSART0_CS(0x0, 0x9) +#define EUSART0_CS_PA10 SILABS_DBUS_EUSART0_CS(0x0, 0xa) +#define EUSART0_CS_PB0 SILABS_DBUS_EUSART0_CS(0x1, 0x0) +#define EUSART0_CS_PB1 SILABS_DBUS_EUSART0_CS(0x1, 0x1) +#define EUSART0_CS_PB2 SILABS_DBUS_EUSART0_CS(0x1, 0x2) +#define EUSART0_CS_PB3 SILABS_DBUS_EUSART0_CS(0x1, 0x3) +#define EUSART0_CS_PB4 SILABS_DBUS_EUSART0_CS(0x1, 0x4) +#define EUSART0_CS_PB5 SILABS_DBUS_EUSART0_CS(0x1, 0x5) +#define EUSART0_CS_PB6 SILABS_DBUS_EUSART0_CS(0x1, 0x6) +#define EUSART0_RTS_PA0 SILABS_DBUS_EUSART0_RTS(0x0, 0x0) +#define EUSART0_RTS_PA1 SILABS_DBUS_EUSART0_RTS(0x0, 0x1) +#define EUSART0_RTS_PA2 SILABS_DBUS_EUSART0_RTS(0x0, 0x2) +#define EUSART0_RTS_PA3 SILABS_DBUS_EUSART0_RTS(0x0, 0x3) +#define EUSART0_RTS_PA4 SILABS_DBUS_EUSART0_RTS(0x0, 0x4) +#define EUSART0_RTS_PA5 SILABS_DBUS_EUSART0_RTS(0x0, 0x5) +#define EUSART0_RTS_PA6 SILABS_DBUS_EUSART0_RTS(0x0, 0x6) +#define EUSART0_RTS_PA7 SILABS_DBUS_EUSART0_RTS(0x0, 0x7) +#define EUSART0_RTS_PA8 SILABS_DBUS_EUSART0_RTS(0x0, 0x8) +#define EUSART0_RTS_PA9 SILABS_DBUS_EUSART0_RTS(0x0, 0x9) +#define EUSART0_RTS_PA10 SILABS_DBUS_EUSART0_RTS(0x0, 0xa) +#define EUSART0_RTS_PB0 SILABS_DBUS_EUSART0_RTS(0x1, 0x0) +#define EUSART0_RTS_PB1 SILABS_DBUS_EUSART0_RTS(0x1, 0x1) +#define EUSART0_RTS_PB2 SILABS_DBUS_EUSART0_RTS(0x1, 0x2) +#define EUSART0_RTS_PB3 SILABS_DBUS_EUSART0_RTS(0x1, 0x3) +#define EUSART0_RTS_PB4 SILABS_DBUS_EUSART0_RTS(0x1, 0x4) +#define EUSART0_RTS_PB5 SILABS_DBUS_EUSART0_RTS(0x1, 0x5) +#define EUSART0_RTS_PB6 SILABS_DBUS_EUSART0_RTS(0x1, 0x6) +#define EUSART0_RX_PA0 SILABS_DBUS_EUSART0_RX(0x0, 0x0) +#define EUSART0_RX_PA1 SILABS_DBUS_EUSART0_RX(0x0, 0x1) +#define EUSART0_RX_PA2 SILABS_DBUS_EUSART0_RX(0x0, 0x2) +#define EUSART0_RX_PA3 SILABS_DBUS_EUSART0_RX(0x0, 0x3) +#define EUSART0_RX_PA4 SILABS_DBUS_EUSART0_RX(0x0, 0x4) +#define EUSART0_RX_PA5 SILABS_DBUS_EUSART0_RX(0x0, 0x5) +#define EUSART0_RX_PA6 SILABS_DBUS_EUSART0_RX(0x0, 0x6) +#define EUSART0_RX_PA7 SILABS_DBUS_EUSART0_RX(0x0, 0x7) +#define EUSART0_RX_PA8 SILABS_DBUS_EUSART0_RX(0x0, 0x8) +#define EUSART0_RX_PA9 SILABS_DBUS_EUSART0_RX(0x0, 0x9) +#define EUSART0_RX_PA10 SILABS_DBUS_EUSART0_RX(0x0, 0xa) +#define EUSART0_RX_PB0 SILABS_DBUS_EUSART0_RX(0x1, 0x0) +#define EUSART0_RX_PB1 SILABS_DBUS_EUSART0_RX(0x1, 0x1) +#define EUSART0_RX_PB2 SILABS_DBUS_EUSART0_RX(0x1, 0x2) +#define EUSART0_RX_PB3 SILABS_DBUS_EUSART0_RX(0x1, 0x3) +#define EUSART0_RX_PB4 SILABS_DBUS_EUSART0_RX(0x1, 0x4) +#define EUSART0_RX_PB5 SILABS_DBUS_EUSART0_RX(0x1, 0x5) +#define EUSART0_RX_PB6 SILABS_DBUS_EUSART0_RX(0x1, 0x6) +#define EUSART0_SCLK_PA0 SILABS_DBUS_EUSART0_SCLK(0x0, 0x0) +#define EUSART0_SCLK_PA1 SILABS_DBUS_EUSART0_SCLK(0x0, 0x1) +#define EUSART0_SCLK_PA2 SILABS_DBUS_EUSART0_SCLK(0x0, 0x2) +#define EUSART0_SCLK_PA3 SILABS_DBUS_EUSART0_SCLK(0x0, 0x3) +#define EUSART0_SCLK_PA4 SILABS_DBUS_EUSART0_SCLK(0x0, 0x4) +#define EUSART0_SCLK_PA5 SILABS_DBUS_EUSART0_SCLK(0x0, 0x5) +#define EUSART0_SCLK_PA6 SILABS_DBUS_EUSART0_SCLK(0x0, 0x6) +#define EUSART0_SCLK_PA7 SILABS_DBUS_EUSART0_SCLK(0x0, 0x7) +#define EUSART0_SCLK_PA8 SILABS_DBUS_EUSART0_SCLK(0x0, 0x8) +#define EUSART0_SCLK_PA9 SILABS_DBUS_EUSART0_SCLK(0x0, 0x9) +#define EUSART0_SCLK_PA10 SILABS_DBUS_EUSART0_SCLK(0x0, 0xa) +#define EUSART0_SCLK_PB0 SILABS_DBUS_EUSART0_SCLK(0x1, 0x0) +#define EUSART0_SCLK_PB1 SILABS_DBUS_EUSART0_SCLK(0x1, 0x1) +#define EUSART0_SCLK_PB2 SILABS_DBUS_EUSART0_SCLK(0x1, 0x2) +#define EUSART0_SCLK_PB3 SILABS_DBUS_EUSART0_SCLK(0x1, 0x3) +#define EUSART0_SCLK_PB4 SILABS_DBUS_EUSART0_SCLK(0x1, 0x4) +#define EUSART0_SCLK_PB5 SILABS_DBUS_EUSART0_SCLK(0x1, 0x5) +#define EUSART0_SCLK_PB6 SILABS_DBUS_EUSART0_SCLK(0x1, 0x6) +#define EUSART0_TX_PA0 SILABS_DBUS_EUSART0_TX(0x0, 0x0) +#define EUSART0_TX_PA1 SILABS_DBUS_EUSART0_TX(0x0, 0x1) +#define EUSART0_TX_PA2 SILABS_DBUS_EUSART0_TX(0x0, 0x2) +#define EUSART0_TX_PA3 SILABS_DBUS_EUSART0_TX(0x0, 0x3) +#define EUSART0_TX_PA4 SILABS_DBUS_EUSART0_TX(0x0, 0x4) +#define EUSART0_TX_PA5 SILABS_DBUS_EUSART0_TX(0x0, 0x5) +#define EUSART0_TX_PA6 SILABS_DBUS_EUSART0_TX(0x0, 0x6) +#define EUSART0_TX_PA7 SILABS_DBUS_EUSART0_TX(0x0, 0x7) +#define EUSART0_TX_PA8 SILABS_DBUS_EUSART0_TX(0x0, 0x8) +#define EUSART0_TX_PA9 SILABS_DBUS_EUSART0_TX(0x0, 0x9) +#define EUSART0_TX_PA10 SILABS_DBUS_EUSART0_TX(0x0, 0xa) +#define EUSART0_TX_PB0 SILABS_DBUS_EUSART0_TX(0x1, 0x0) +#define EUSART0_TX_PB1 SILABS_DBUS_EUSART0_TX(0x1, 0x1) +#define EUSART0_TX_PB2 SILABS_DBUS_EUSART0_TX(0x1, 0x2) +#define EUSART0_TX_PB3 SILABS_DBUS_EUSART0_TX(0x1, 0x3) +#define EUSART0_TX_PB4 SILABS_DBUS_EUSART0_TX(0x1, 0x4) +#define EUSART0_TX_PB5 SILABS_DBUS_EUSART0_TX(0x1, 0x5) +#define EUSART0_TX_PB6 SILABS_DBUS_EUSART0_TX(0x1, 0x6) +#define EUSART0_CTS_PA0 SILABS_DBUS_EUSART0_CTS(0x0, 0x0) +#define EUSART0_CTS_PA1 SILABS_DBUS_EUSART0_CTS(0x0, 0x1) +#define EUSART0_CTS_PA2 SILABS_DBUS_EUSART0_CTS(0x0, 0x2) +#define EUSART0_CTS_PA3 SILABS_DBUS_EUSART0_CTS(0x0, 0x3) +#define EUSART0_CTS_PA4 SILABS_DBUS_EUSART0_CTS(0x0, 0x4) +#define EUSART0_CTS_PA5 SILABS_DBUS_EUSART0_CTS(0x0, 0x5) +#define EUSART0_CTS_PA6 SILABS_DBUS_EUSART0_CTS(0x0, 0x6) +#define EUSART0_CTS_PA7 SILABS_DBUS_EUSART0_CTS(0x0, 0x7) +#define EUSART0_CTS_PA8 SILABS_DBUS_EUSART0_CTS(0x0, 0x8) +#define EUSART0_CTS_PA9 SILABS_DBUS_EUSART0_CTS(0x0, 0x9) +#define EUSART0_CTS_PA10 SILABS_DBUS_EUSART0_CTS(0x0, 0xa) +#define EUSART0_CTS_PB0 SILABS_DBUS_EUSART0_CTS(0x1, 0x0) +#define EUSART0_CTS_PB1 SILABS_DBUS_EUSART0_CTS(0x1, 0x1) +#define EUSART0_CTS_PB2 SILABS_DBUS_EUSART0_CTS(0x1, 0x2) +#define EUSART0_CTS_PB3 SILABS_DBUS_EUSART0_CTS(0x1, 0x3) +#define EUSART0_CTS_PB4 SILABS_DBUS_EUSART0_CTS(0x1, 0x4) +#define EUSART0_CTS_PB5 SILABS_DBUS_EUSART0_CTS(0x1, 0x5) +#define EUSART0_CTS_PB6 SILABS_DBUS_EUSART0_CTS(0x1, 0x6) + +#define EUSART1_CS_PA0 SILABS_DBUS_EUSART1_CS(0x0, 0x0) +#define EUSART1_CS_PA1 SILABS_DBUS_EUSART1_CS(0x0, 0x1) +#define EUSART1_CS_PA2 SILABS_DBUS_EUSART1_CS(0x0, 0x2) +#define EUSART1_CS_PA3 SILABS_DBUS_EUSART1_CS(0x0, 0x3) +#define EUSART1_CS_PA4 SILABS_DBUS_EUSART1_CS(0x0, 0x4) +#define EUSART1_CS_PA5 SILABS_DBUS_EUSART1_CS(0x0, 0x5) +#define EUSART1_CS_PA6 SILABS_DBUS_EUSART1_CS(0x0, 0x6) +#define EUSART1_CS_PA7 SILABS_DBUS_EUSART1_CS(0x0, 0x7) +#define EUSART1_CS_PA8 SILABS_DBUS_EUSART1_CS(0x0, 0x8) +#define EUSART1_CS_PA9 SILABS_DBUS_EUSART1_CS(0x0, 0x9) +#define EUSART1_CS_PA10 SILABS_DBUS_EUSART1_CS(0x0, 0xa) +#define EUSART1_CS_PB0 SILABS_DBUS_EUSART1_CS(0x1, 0x0) +#define EUSART1_CS_PB1 SILABS_DBUS_EUSART1_CS(0x1, 0x1) +#define EUSART1_CS_PB2 SILABS_DBUS_EUSART1_CS(0x1, 0x2) +#define EUSART1_CS_PB3 SILABS_DBUS_EUSART1_CS(0x1, 0x3) +#define EUSART1_CS_PB4 SILABS_DBUS_EUSART1_CS(0x1, 0x4) +#define EUSART1_CS_PB5 SILABS_DBUS_EUSART1_CS(0x1, 0x5) +#define EUSART1_CS_PB6 SILABS_DBUS_EUSART1_CS(0x1, 0x6) +#define EUSART1_CS_PC0 SILABS_DBUS_EUSART1_CS(0x2, 0x0) +#define EUSART1_CS_PC1 SILABS_DBUS_EUSART1_CS(0x2, 0x1) +#define EUSART1_CS_PC2 SILABS_DBUS_EUSART1_CS(0x2, 0x2) +#define EUSART1_CS_PC3 SILABS_DBUS_EUSART1_CS(0x2, 0x3) +#define EUSART1_CS_PC4 SILABS_DBUS_EUSART1_CS(0x2, 0x4) +#define EUSART1_CS_PC5 SILABS_DBUS_EUSART1_CS(0x2, 0x5) +#define EUSART1_CS_PC6 SILABS_DBUS_EUSART1_CS(0x2, 0x6) +#define EUSART1_CS_PC7 SILABS_DBUS_EUSART1_CS(0x2, 0x7) +#define EUSART1_CS_PC8 SILABS_DBUS_EUSART1_CS(0x2, 0x8) +#define EUSART1_CS_PC9 SILABS_DBUS_EUSART1_CS(0x2, 0x9) +#define EUSART1_CS_PD0 SILABS_DBUS_EUSART1_CS(0x3, 0x0) +#define EUSART1_CS_PD1 SILABS_DBUS_EUSART1_CS(0x3, 0x1) +#define EUSART1_CS_PD2 SILABS_DBUS_EUSART1_CS(0x3, 0x2) +#define EUSART1_CS_PD3 SILABS_DBUS_EUSART1_CS(0x3, 0x3) +#define EUSART1_CS_PD4 SILABS_DBUS_EUSART1_CS(0x3, 0x4) +#define EUSART1_CS_PD5 SILABS_DBUS_EUSART1_CS(0x3, 0x5) +#define EUSART1_RTS_PA0 SILABS_DBUS_EUSART1_RTS(0x0, 0x0) +#define EUSART1_RTS_PA1 SILABS_DBUS_EUSART1_RTS(0x0, 0x1) +#define EUSART1_RTS_PA2 SILABS_DBUS_EUSART1_RTS(0x0, 0x2) +#define EUSART1_RTS_PA3 SILABS_DBUS_EUSART1_RTS(0x0, 0x3) +#define EUSART1_RTS_PA4 SILABS_DBUS_EUSART1_RTS(0x0, 0x4) +#define EUSART1_RTS_PA5 SILABS_DBUS_EUSART1_RTS(0x0, 0x5) +#define EUSART1_RTS_PA6 SILABS_DBUS_EUSART1_RTS(0x0, 0x6) +#define EUSART1_RTS_PA7 SILABS_DBUS_EUSART1_RTS(0x0, 0x7) +#define EUSART1_RTS_PA8 SILABS_DBUS_EUSART1_RTS(0x0, 0x8) +#define EUSART1_RTS_PA9 SILABS_DBUS_EUSART1_RTS(0x0, 0x9) +#define EUSART1_RTS_PA10 SILABS_DBUS_EUSART1_RTS(0x0, 0xa) +#define EUSART1_RTS_PB0 SILABS_DBUS_EUSART1_RTS(0x1, 0x0) +#define EUSART1_RTS_PB1 SILABS_DBUS_EUSART1_RTS(0x1, 0x1) +#define EUSART1_RTS_PB2 SILABS_DBUS_EUSART1_RTS(0x1, 0x2) +#define EUSART1_RTS_PB3 SILABS_DBUS_EUSART1_RTS(0x1, 0x3) +#define EUSART1_RTS_PB4 SILABS_DBUS_EUSART1_RTS(0x1, 0x4) +#define EUSART1_RTS_PB5 SILABS_DBUS_EUSART1_RTS(0x1, 0x5) +#define EUSART1_RTS_PB6 SILABS_DBUS_EUSART1_RTS(0x1, 0x6) +#define EUSART1_RTS_PC0 SILABS_DBUS_EUSART1_RTS(0x2, 0x0) +#define EUSART1_RTS_PC1 SILABS_DBUS_EUSART1_RTS(0x2, 0x1) +#define EUSART1_RTS_PC2 SILABS_DBUS_EUSART1_RTS(0x2, 0x2) +#define EUSART1_RTS_PC3 SILABS_DBUS_EUSART1_RTS(0x2, 0x3) +#define EUSART1_RTS_PC4 SILABS_DBUS_EUSART1_RTS(0x2, 0x4) +#define EUSART1_RTS_PC5 SILABS_DBUS_EUSART1_RTS(0x2, 0x5) +#define EUSART1_RTS_PC6 SILABS_DBUS_EUSART1_RTS(0x2, 0x6) +#define EUSART1_RTS_PC7 SILABS_DBUS_EUSART1_RTS(0x2, 0x7) +#define EUSART1_RTS_PC8 SILABS_DBUS_EUSART1_RTS(0x2, 0x8) +#define EUSART1_RTS_PC9 SILABS_DBUS_EUSART1_RTS(0x2, 0x9) +#define EUSART1_RTS_PD0 SILABS_DBUS_EUSART1_RTS(0x3, 0x0) +#define EUSART1_RTS_PD1 SILABS_DBUS_EUSART1_RTS(0x3, 0x1) +#define EUSART1_RTS_PD2 SILABS_DBUS_EUSART1_RTS(0x3, 0x2) +#define EUSART1_RTS_PD3 SILABS_DBUS_EUSART1_RTS(0x3, 0x3) +#define EUSART1_RTS_PD4 SILABS_DBUS_EUSART1_RTS(0x3, 0x4) +#define EUSART1_RTS_PD5 SILABS_DBUS_EUSART1_RTS(0x3, 0x5) +#define EUSART1_RX_PA0 SILABS_DBUS_EUSART1_RX(0x0, 0x0) +#define EUSART1_RX_PA1 SILABS_DBUS_EUSART1_RX(0x0, 0x1) +#define EUSART1_RX_PA2 SILABS_DBUS_EUSART1_RX(0x0, 0x2) +#define EUSART1_RX_PA3 SILABS_DBUS_EUSART1_RX(0x0, 0x3) +#define EUSART1_RX_PA4 SILABS_DBUS_EUSART1_RX(0x0, 0x4) +#define EUSART1_RX_PA5 SILABS_DBUS_EUSART1_RX(0x0, 0x5) +#define EUSART1_RX_PA6 SILABS_DBUS_EUSART1_RX(0x0, 0x6) +#define EUSART1_RX_PA7 SILABS_DBUS_EUSART1_RX(0x0, 0x7) +#define EUSART1_RX_PA8 SILABS_DBUS_EUSART1_RX(0x0, 0x8) +#define EUSART1_RX_PA9 SILABS_DBUS_EUSART1_RX(0x0, 0x9) +#define EUSART1_RX_PA10 SILABS_DBUS_EUSART1_RX(0x0, 0xa) +#define EUSART1_RX_PB0 SILABS_DBUS_EUSART1_RX(0x1, 0x0) +#define EUSART1_RX_PB1 SILABS_DBUS_EUSART1_RX(0x1, 0x1) +#define EUSART1_RX_PB2 SILABS_DBUS_EUSART1_RX(0x1, 0x2) +#define EUSART1_RX_PB3 SILABS_DBUS_EUSART1_RX(0x1, 0x3) +#define EUSART1_RX_PB4 SILABS_DBUS_EUSART1_RX(0x1, 0x4) +#define EUSART1_RX_PB5 SILABS_DBUS_EUSART1_RX(0x1, 0x5) +#define EUSART1_RX_PB6 SILABS_DBUS_EUSART1_RX(0x1, 0x6) +#define EUSART1_RX_PC0 SILABS_DBUS_EUSART1_RX(0x2, 0x0) +#define EUSART1_RX_PC1 SILABS_DBUS_EUSART1_RX(0x2, 0x1) +#define EUSART1_RX_PC2 SILABS_DBUS_EUSART1_RX(0x2, 0x2) +#define EUSART1_RX_PC3 SILABS_DBUS_EUSART1_RX(0x2, 0x3) +#define EUSART1_RX_PC4 SILABS_DBUS_EUSART1_RX(0x2, 0x4) +#define EUSART1_RX_PC5 SILABS_DBUS_EUSART1_RX(0x2, 0x5) +#define EUSART1_RX_PC6 SILABS_DBUS_EUSART1_RX(0x2, 0x6) +#define EUSART1_RX_PC7 SILABS_DBUS_EUSART1_RX(0x2, 0x7) +#define EUSART1_RX_PC8 SILABS_DBUS_EUSART1_RX(0x2, 0x8) +#define EUSART1_RX_PC9 SILABS_DBUS_EUSART1_RX(0x2, 0x9) +#define EUSART1_RX_PD0 SILABS_DBUS_EUSART1_RX(0x3, 0x0) +#define EUSART1_RX_PD1 SILABS_DBUS_EUSART1_RX(0x3, 0x1) +#define EUSART1_RX_PD2 SILABS_DBUS_EUSART1_RX(0x3, 0x2) +#define EUSART1_RX_PD3 SILABS_DBUS_EUSART1_RX(0x3, 0x3) +#define EUSART1_RX_PD4 SILABS_DBUS_EUSART1_RX(0x3, 0x4) +#define EUSART1_RX_PD5 SILABS_DBUS_EUSART1_RX(0x3, 0x5) +#define EUSART1_SCLK_PA0 SILABS_DBUS_EUSART1_SCLK(0x0, 0x0) +#define EUSART1_SCLK_PA1 SILABS_DBUS_EUSART1_SCLK(0x0, 0x1) +#define EUSART1_SCLK_PA2 SILABS_DBUS_EUSART1_SCLK(0x0, 0x2) +#define EUSART1_SCLK_PA3 SILABS_DBUS_EUSART1_SCLK(0x0, 0x3) +#define EUSART1_SCLK_PA4 SILABS_DBUS_EUSART1_SCLK(0x0, 0x4) +#define EUSART1_SCLK_PA5 SILABS_DBUS_EUSART1_SCLK(0x0, 0x5) +#define EUSART1_SCLK_PA6 SILABS_DBUS_EUSART1_SCLK(0x0, 0x6) +#define EUSART1_SCLK_PA7 SILABS_DBUS_EUSART1_SCLK(0x0, 0x7) +#define EUSART1_SCLK_PA8 SILABS_DBUS_EUSART1_SCLK(0x0, 0x8) +#define EUSART1_SCLK_PA9 SILABS_DBUS_EUSART1_SCLK(0x0, 0x9) +#define EUSART1_SCLK_PA10 SILABS_DBUS_EUSART1_SCLK(0x0, 0xa) +#define EUSART1_SCLK_PB0 SILABS_DBUS_EUSART1_SCLK(0x1, 0x0) +#define EUSART1_SCLK_PB1 SILABS_DBUS_EUSART1_SCLK(0x1, 0x1) +#define EUSART1_SCLK_PB2 SILABS_DBUS_EUSART1_SCLK(0x1, 0x2) +#define EUSART1_SCLK_PB3 SILABS_DBUS_EUSART1_SCLK(0x1, 0x3) +#define EUSART1_SCLK_PB4 SILABS_DBUS_EUSART1_SCLK(0x1, 0x4) +#define EUSART1_SCLK_PB5 SILABS_DBUS_EUSART1_SCLK(0x1, 0x5) +#define EUSART1_SCLK_PB6 SILABS_DBUS_EUSART1_SCLK(0x1, 0x6) +#define EUSART1_SCLK_PC0 SILABS_DBUS_EUSART1_SCLK(0x2, 0x0) +#define EUSART1_SCLK_PC1 SILABS_DBUS_EUSART1_SCLK(0x2, 0x1) +#define EUSART1_SCLK_PC2 SILABS_DBUS_EUSART1_SCLK(0x2, 0x2) +#define EUSART1_SCLK_PC3 SILABS_DBUS_EUSART1_SCLK(0x2, 0x3) +#define EUSART1_SCLK_PC4 SILABS_DBUS_EUSART1_SCLK(0x2, 0x4) +#define EUSART1_SCLK_PC5 SILABS_DBUS_EUSART1_SCLK(0x2, 0x5) +#define EUSART1_SCLK_PC6 SILABS_DBUS_EUSART1_SCLK(0x2, 0x6) +#define EUSART1_SCLK_PC7 SILABS_DBUS_EUSART1_SCLK(0x2, 0x7) +#define EUSART1_SCLK_PC8 SILABS_DBUS_EUSART1_SCLK(0x2, 0x8) +#define EUSART1_SCLK_PC9 SILABS_DBUS_EUSART1_SCLK(0x2, 0x9) +#define EUSART1_SCLK_PD0 SILABS_DBUS_EUSART1_SCLK(0x3, 0x0) +#define EUSART1_SCLK_PD1 SILABS_DBUS_EUSART1_SCLK(0x3, 0x1) +#define EUSART1_SCLK_PD2 SILABS_DBUS_EUSART1_SCLK(0x3, 0x2) +#define EUSART1_SCLK_PD3 SILABS_DBUS_EUSART1_SCLK(0x3, 0x3) +#define EUSART1_SCLK_PD4 SILABS_DBUS_EUSART1_SCLK(0x3, 0x4) +#define EUSART1_SCLK_PD5 SILABS_DBUS_EUSART1_SCLK(0x3, 0x5) +#define EUSART1_TX_PA0 SILABS_DBUS_EUSART1_TX(0x0, 0x0) +#define EUSART1_TX_PA1 SILABS_DBUS_EUSART1_TX(0x0, 0x1) +#define EUSART1_TX_PA2 SILABS_DBUS_EUSART1_TX(0x0, 0x2) +#define EUSART1_TX_PA3 SILABS_DBUS_EUSART1_TX(0x0, 0x3) +#define EUSART1_TX_PA4 SILABS_DBUS_EUSART1_TX(0x0, 0x4) +#define EUSART1_TX_PA5 SILABS_DBUS_EUSART1_TX(0x0, 0x5) +#define EUSART1_TX_PA6 SILABS_DBUS_EUSART1_TX(0x0, 0x6) +#define EUSART1_TX_PA7 SILABS_DBUS_EUSART1_TX(0x0, 0x7) +#define EUSART1_TX_PA8 SILABS_DBUS_EUSART1_TX(0x0, 0x8) +#define EUSART1_TX_PA9 SILABS_DBUS_EUSART1_TX(0x0, 0x9) +#define EUSART1_TX_PA10 SILABS_DBUS_EUSART1_TX(0x0, 0xa) +#define EUSART1_TX_PB0 SILABS_DBUS_EUSART1_TX(0x1, 0x0) +#define EUSART1_TX_PB1 SILABS_DBUS_EUSART1_TX(0x1, 0x1) +#define EUSART1_TX_PB2 SILABS_DBUS_EUSART1_TX(0x1, 0x2) +#define EUSART1_TX_PB3 SILABS_DBUS_EUSART1_TX(0x1, 0x3) +#define EUSART1_TX_PB4 SILABS_DBUS_EUSART1_TX(0x1, 0x4) +#define EUSART1_TX_PB5 SILABS_DBUS_EUSART1_TX(0x1, 0x5) +#define EUSART1_TX_PB6 SILABS_DBUS_EUSART1_TX(0x1, 0x6) +#define EUSART1_TX_PC0 SILABS_DBUS_EUSART1_TX(0x2, 0x0) +#define EUSART1_TX_PC1 SILABS_DBUS_EUSART1_TX(0x2, 0x1) +#define EUSART1_TX_PC2 SILABS_DBUS_EUSART1_TX(0x2, 0x2) +#define EUSART1_TX_PC3 SILABS_DBUS_EUSART1_TX(0x2, 0x3) +#define EUSART1_TX_PC4 SILABS_DBUS_EUSART1_TX(0x2, 0x4) +#define EUSART1_TX_PC5 SILABS_DBUS_EUSART1_TX(0x2, 0x5) +#define EUSART1_TX_PC6 SILABS_DBUS_EUSART1_TX(0x2, 0x6) +#define EUSART1_TX_PC7 SILABS_DBUS_EUSART1_TX(0x2, 0x7) +#define EUSART1_TX_PC8 SILABS_DBUS_EUSART1_TX(0x2, 0x8) +#define EUSART1_TX_PC9 SILABS_DBUS_EUSART1_TX(0x2, 0x9) +#define EUSART1_TX_PD0 SILABS_DBUS_EUSART1_TX(0x3, 0x0) +#define EUSART1_TX_PD1 SILABS_DBUS_EUSART1_TX(0x3, 0x1) +#define EUSART1_TX_PD2 SILABS_DBUS_EUSART1_TX(0x3, 0x2) +#define EUSART1_TX_PD3 SILABS_DBUS_EUSART1_TX(0x3, 0x3) +#define EUSART1_TX_PD4 SILABS_DBUS_EUSART1_TX(0x3, 0x4) +#define EUSART1_TX_PD5 SILABS_DBUS_EUSART1_TX(0x3, 0x5) +#define EUSART1_CTS_PA0 SILABS_DBUS_EUSART1_CTS(0x0, 0x0) +#define EUSART1_CTS_PA1 SILABS_DBUS_EUSART1_CTS(0x0, 0x1) +#define EUSART1_CTS_PA2 SILABS_DBUS_EUSART1_CTS(0x0, 0x2) +#define EUSART1_CTS_PA3 SILABS_DBUS_EUSART1_CTS(0x0, 0x3) +#define EUSART1_CTS_PA4 SILABS_DBUS_EUSART1_CTS(0x0, 0x4) +#define EUSART1_CTS_PA5 SILABS_DBUS_EUSART1_CTS(0x0, 0x5) +#define EUSART1_CTS_PA6 SILABS_DBUS_EUSART1_CTS(0x0, 0x6) +#define EUSART1_CTS_PA7 SILABS_DBUS_EUSART1_CTS(0x0, 0x7) +#define EUSART1_CTS_PA8 SILABS_DBUS_EUSART1_CTS(0x0, 0x8) +#define EUSART1_CTS_PA9 SILABS_DBUS_EUSART1_CTS(0x0, 0x9) +#define EUSART1_CTS_PA10 SILABS_DBUS_EUSART1_CTS(0x0, 0xa) +#define EUSART1_CTS_PB0 SILABS_DBUS_EUSART1_CTS(0x1, 0x0) +#define EUSART1_CTS_PB1 SILABS_DBUS_EUSART1_CTS(0x1, 0x1) +#define EUSART1_CTS_PB2 SILABS_DBUS_EUSART1_CTS(0x1, 0x2) +#define EUSART1_CTS_PB3 SILABS_DBUS_EUSART1_CTS(0x1, 0x3) +#define EUSART1_CTS_PB4 SILABS_DBUS_EUSART1_CTS(0x1, 0x4) +#define EUSART1_CTS_PB5 SILABS_DBUS_EUSART1_CTS(0x1, 0x5) +#define EUSART1_CTS_PB6 SILABS_DBUS_EUSART1_CTS(0x1, 0x6) +#define EUSART1_CTS_PC0 SILABS_DBUS_EUSART1_CTS(0x2, 0x0) +#define EUSART1_CTS_PC1 SILABS_DBUS_EUSART1_CTS(0x2, 0x1) +#define EUSART1_CTS_PC2 SILABS_DBUS_EUSART1_CTS(0x2, 0x2) +#define EUSART1_CTS_PC3 SILABS_DBUS_EUSART1_CTS(0x2, 0x3) +#define EUSART1_CTS_PC4 SILABS_DBUS_EUSART1_CTS(0x2, 0x4) +#define EUSART1_CTS_PC5 SILABS_DBUS_EUSART1_CTS(0x2, 0x5) +#define EUSART1_CTS_PC6 SILABS_DBUS_EUSART1_CTS(0x2, 0x6) +#define EUSART1_CTS_PC7 SILABS_DBUS_EUSART1_CTS(0x2, 0x7) +#define EUSART1_CTS_PC8 SILABS_DBUS_EUSART1_CTS(0x2, 0x8) +#define EUSART1_CTS_PC9 SILABS_DBUS_EUSART1_CTS(0x2, 0x9) +#define EUSART1_CTS_PD0 SILABS_DBUS_EUSART1_CTS(0x3, 0x0) +#define EUSART1_CTS_PD1 SILABS_DBUS_EUSART1_CTS(0x3, 0x1) +#define EUSART1_CTS_PD2 SILABS_DBUS_EUSART1_CTS(0x3, 0x2) +#define EUSART1_CTS_PD3 SILABS_DBUS_EUSART1_CTS(0x3, 0x3) +#define EUSART1_CTS_PD4 SILABS_DBUS_EUSART1_CTS(0x3, 0x4) +#define EUSART1_CTS_PD5 SILABS_DBUS_EUSART1_CTS(0x3, 0x5) + +#define EUSART2_CS_PC0 SILABS_DBUS_EUSART2_CS(0x2, 0x0) +#define EUSART2_CS_PC1 SILABS_DBUS_EUSART2_CS(0x2, 0x1) +#define EUSART2_CS_PC2 SILABS_DBUS_EUSART2_CS(0x2, 0x2) +#define EUSART2_CS_PC3 SILABS_DBUS_EUSART2_CS(0x2, 0x3) +#define EUSART2_CS_PC4 SILABS_DBUS_EUSART2_CS(0x2, 0x4) +#define EUSART2_CS_PC5 SILABS_DBUS_EUSART2_CS(0x2, 0x5) +#define EUSART2_CS_PC6 SILABS_DBUS_EUSART2_CS(0x2, 0x6) +#define EUSART2_CS_PC7 SILABS_DBUS_EUSART2_CS(0x2, 0x7) +#define EUSART2_CS_PC8 SILABS_DBUS_EUSART2_CS(0x2, 0x8) +#define EUSART2_CS_PC9 SILABS_DBUS_EUSART2_CS(0x2, 0x9) +#define EUSART2_CS_PD0 SILABS_DBUS_EUSART2_CS(0x3, 0x0) +#define EUSART2_CS_PD1 SILABS_DBUS_EUSART2_CS(0x3, 0x1) +#define EUSART2_CS_PD2 SILABS_DBUS_EUSART2_CS(0x3, 0x2) +#define EUSART2_CS_PD3 SILABS_DBUS_EUSART2_CS(0x3, 0x3) +#define EUSART2_CS_PD4 SILABS_DBUS_EUSART2_CS(0x3, 0x4) +#define EUSART2_CS_PD5 SILABS_DBUS_EUSART2_CS(0x3, 0x5) +#define EUSART2_RTS_PC0 SILABS_DBUS_EUSART2_RTS(0x2, 0x0) +#define EUSART2_RTS_PC1 SILABS_DBUS_EUSART2_RTS(0x2, 0x1) +#define EUSART2_RTS_PC2 SILABS_DBUS_EUSART2_RTS(0x2, 0x2) +#define EUSART2_RTS_PC3 SILABS_DBUS_EUSART2_RTS(0x2, 0x3) +#define EUSART2_RTS_PC4 SILABS_DBUS_EUSART2_RTS(0x2, 0x4) +#define EUSART2_RTS_PC5 SILABS_DBUS_EUSART2_RTS(0x2, 0x5) +#define EUSART2_RTS_PC6 SILABS_DBUS_EUSART2_RTS(0x2, 0x6) +#define EUSART2_RTS_PC7 SILABS_DBUS_EUSART2_RTS(0x2, 0x7) +#define EUSART2_RTS_PC8 SILABS_DBUS_EUSART2_RTS(0x2, 0x8) +#define EUSART2_RTS_PC9 SILABS_DBUS_EUSART2_RTS(0x2, 0x9) +#define EUSART2_RTS_PD0 SILABS_DBUS_EUSART2_RTS(0x3, 0x0) +#define EUSART2_RTS_PD1 SILABS_DBUS_EUSART2_RTS(0x3, 0x1) +#define EUSART2_RTS_PD2 SILABS_DBUS_EUSART2_RTS(0x3, 0x2) +#define EUSART2_RTS_PD3 SILABS_DBUS_EUSART2_RTS(0x3, 0x3) +#define EUSART2_RTS_PD4 SILABS_DBUS_EUSART2_RTS(0x3, 0x4) +#define EUSART2_RTS_PD5 SILABS_DBUS_EUSART2_RTS(0x3, 0x5) +#define EUSART2_RX_PC0 SILABS_DBUS_EUSART2_RX(0x2, 0x0) +#define EUSART2_RX_PC1 SILABS_DBUS_EUSART2_RX(0x2, 0x1) +#define EUSART2_RX_PC2 SILABS_DBUS_EUSART2_RX(0x2, 0x2) +#define EUSART2_RX_PC3 SILABS_DBUS_EUSART2_RX(0x2, 0x3) +#define EUSART2_RX_PC4 SILABS_DBUS_EUSART2_RX(0x2, 0x4) +#define EUSART2_RX_PC5 SILABS_DBUS_EUSART2_RX(0x2, 0x5) +#define EUSART2_RX_PC6 SILABS_DBUS_EUSART2_RX(0x2, 0x6) +#define EUSART2_RX_PC7 SILABS_DBUS_EUSART2_RX(0x2, 0x7) +#define EUSART2_RX_PC8 SILABS_DBUS_EUSART2_RX(0x2, 0x8) +#define EUSART2_RX_PC9 SILABS_DBUS_EUSART2_RX(0x2, 0x9) +#define EUSART2_RX_PD0 SILABS_DBUS_EUSART2_RX(0x3, 0x0) +#define EUSART2_RX_PD1 SILABS_DBUS_EUSART2_RX(0x3, 0x1) +#define EUSART2_RX_PD2 SILABS_DBUS_EUSART2_RX(0x3, 0x2) +#define EUSART2_RX_PD3 SILABS_DBUS_EUSART2_RX(0x3, 0x3) +#define EUSART2_RX_PD4 SILABS_DBUS_EUSART2_RX(0x3, 0x4) +#define EUSART2_RX_PD5 SILABS_DBUS_EUSART2_RX(0x3, 0x5) +#define EUSART2_SCLK_PC0 SILABS_DBUS_EUSART2_SCLK(0x2, 0x0) +#define EUSART2_SCLK_PC1 SILABS_DBUS_EUSART2_SCLK(0x2, 0x1) +#define EUSART2_SCLK_PC2 SILABS_DBUS_EUSART2_SCLK(0x2, 0x2) +#define EUSART2_SCLK_PC3 SILABS_DBUS_EUSART2_SCLK(0x2, 0x3) +#define EUSART2_SCLK_PC4 SILABS_DBUS_EUSART2_SCLK(0x2, 0x4) +#define EUSART2_SCLK_PC5 SILABS_DBUS_EUSART2_SCLK(0x2, 0x5) +#define EUSART2_SCLK_PC6 SILABS_DBUS_EUSART2_SCLK(0x2, 0x6) +#define EUSART2_SCLK_PC7 SILABS_DBUS_EUSART2_SCLK(0x2, 0x7) +#define EUSART2_SCLK_PC8 SILABS_DBUS_EUSART2_SCLK(0x2, 0x8) +#define EUSART2_SCLK_PC9 SILABS_DBUS_EUSART2_SCLK(0x2, 0x9) +#define EUSART2_SCLK_PD0 SILABS_DBUS_EUSART2_SCLK(0x3, 0x0) +#define EUSART2_SCLK_PD1 SILABS_DBUS_EUSART2_SCLK(0x3, 0x1) +#define EUSART2_SCLK_PD2 SILABS_DBUS_EUSART2_SCLK(0x3, 0x2) +#define EUSART2_SCLK_PD3 SILABS_DBUS_EUSART2_SCLK(0x3, 0x3) +#define EUSART2_SCLK_PD4 SILABS_DBUS_EUSART2_SCLK(0x3, 0x4) +#define EUSART2_SCLK_PD5 SILABS_DBUS_EUSART2_SCLK(0x3, 0x5) +#define EUSART2_TX_PC0 SILABS_DBUS_EUSART2_TX(0x2, 0x0) +#define EUSART2_TX_PC1 SILABS_DBUS_EUSART2_TX(0x2, 0x1) +#define EUSART2_TX_PC2 SILABS_DBUS_EUSART2_TX(0x2, 0x2) +#define EUSART2_TX_PC3 SILABS_DBUS_EUSART2_TX(0x2, 0x3) +#define EUSART2_TX_PC4 SILABS_DBUS_EUSART2_TX(0x2, 0x4) +#define EUSART2_TX_PC5 SILABS_DBUS_EUSART2_TX(0x2, 0x5) +#define EUSART2_TX_PC6 SILABS_DBUS_EUSART2_TX(0x2, 0x6) +#define EUSART2_TX_PC7 SILABS_DBUS_EUSART2_TX(0x2, 0x7) +#define EUSART2_TX_PC8 SILABS_DBUS_EUSART2_TX(0x2, 0x8) +#define EUSART2_TX_PC9 SILABS_DBUS_EUSART2_TX(0x2, 0x9) +#define EUSART2_TX_PD0 SILABS_DBUS_EUSART2_TX(0x3, 0x0) +#define EUSART2_TX_PD1 SILABS_DBUS_EUSART2_TX(0x3, 0x1) +#define EUSART2_TX_PD2 SILABS_DBUS_EUSART2_TX(0x3, 0x2) +#define EUSART2_TX_PD3 SILABS_DBUS_EUSART2_TX(0x3, 0x3) +#define EUSART2_TX_PD4 SILABS_DBUS_EUSART2_TX(0x3, 0x4) +#define EUSART2_TX_PD5 SILABS_DBUS_EUSART2_TX(0x3, 0x5) +#define EUSART2_CTS_PC0 SILABS_DBUS_EUSART2_CTS(0x2, 0x0) +#define EUSART2_CTS_PC1 SILABS_DBUS_EUSART2_CTS(0x2, 0x1) +#define EUSART2_CTS_PC2 SILABS_DBUS_EUSART2_CTS(0x2, 0x2) +#define EUSART2_CTS_PC3 SILABS_DBUS_EUSART2_CTS(0x2, 0x3) +#define EUSART2_CTS_PC4 SILABS_DBUS_EUSART2_CTS(0x2, 0x4) +#define EUSART2_CTS_PC5 SILABS_DBUS_EUSART2_CTS(0x2, 0x5) +#define EUSART2_CTS_PC6 SILABS_DBUS_EUSART2_CTS(0x2, 0x6) +#define EUSART2_CTS_PC7 SILABS_DBUS_EUSART2_CTS(0x2, 0x7) +#define EUSART2_CTS_PC8 SILABS_DBUS_EUSART2_CTS(0x2, 0x8) +#define EUSART2_CTS_PC9 SILABS_DBUS_EUSART2_CTS(0x2, 0x9) +#define EUSART2_CTS_PD0 SILABS_DBUS_EUSART2_CTS(0x3, 0x0) +#define EUSART2_CTS_PD1 SILABS_DBUS_EUSART2_CTS(0x3, 0x1) +#define EUSART2_CTS_PD2 SILABS_DBUS_EUSART2_CTS(0x3, 0x2) +#define EUSART2_CTS_PD3 SILABS_DBUS_EUSART2_CTS(0x3, 0x3) +#define EUSART2_CTS_PD4 SILABS_DBUS_EUSART2_CTS(0x3, 0x4) +#define EUSART2_CTS_PD5 SILABS_DBUS_EUSART2_CTS(0x3, 0x5) + +#define PTI_DCLK_PC0 SILABS_DBUS_PTI_DCLK(0x2, 0x0) +#define PTI_DCLK_PC1 SILABS_DBUS_PTI_DCLK(0x2, 0x1) +#define PTI_DCLK_PC2 SILABS_DBUS_PTI_DCLK(0x2, 0x2) +#define PTI_DCLK_PC3 SILABS_DBUS_PTI_DCLK(0x2, 0x3) +#define PTI_DCLK_PC4 SILABS_DBUS_PTI_DCLK(0x2, 0x4) +#define PTI_DCLK_PC5 SILABS_DBUS_PTI_DCLK(0x2, 0x5) +#define PTI_DCLK_PC6 SILABS_DBUS_PTI_DCLK(0x2, 0x6) +#define PTI_DCLK_PC7 SILABS_DBUS_PTI_DCLK(0x2, 0x7) +#define PTI_DCLK_PC8 SILABS_DBUS_PTI_DCLK(0x2, 0x8) +#define PTI_DCLK_PC9 SILABS_DBUS_PTI_DCLK(0x2, 0x9) +#define PTI_DCLK_PD0 SILABS_DBUS_PTI_DCLK(0x3, 0x0) +#define PTI_DCLK_PD1 SILABS_DBUS_PTI_DCLK(0x3, 0x1) +#define PTI_DCLK_PD2 SILABS_DBUS_PTI_DCLK(0x3, 0x2) +#define PTI_DCLK_PD3 SILABS_DBUS_PTI_DCLK(0x3, 0x3) +#define PTI_DCLK_PD4 SILABS_DBUS_PTI_DCLK(0x3, 0x4) +#define PTI_DCLK_PD5 SILABS_DBUS_PTI_DCLK(0x3, 0x5) +#define PTI_DFRAME_PC0 SILABS_DBUS_PTI_DFRAME(0x2, 0x0) +#define PTI_DFRAME_PC1 SILABS_DBUS_PTI_DFRAME(0x2, 0x1) +#define PTI_DFRAME_PC2 SILABS_DBUS_PTI_DFRAME(0x2, 0x2) +#define PTI_DFRAME_PC3 SILABS_DBUS_PTI_DFRAME(0x2, 0x3) +#define PTI_DFRAME_PC4 SILABS_DBUS_PTI_DFRAME(0x2, 0x4) +#define PTI_DFRAME_PC5 SILABS_DBUS_PTI_DFRAME(0x2, 0x5) +#define PTI_DFRAME_PC6 SILABS_DBUS_PTI_DFRAME(0x2, 0x6) +#define PTI_DFRAME_PC7 SILABS_DBUS_PTI_DFRAME(0x2, 0x7) +#define PTI_DFRAME_PC8 SILABS_DBUS_PTI_DFRAME(0x2, 0x8) +#define PTI_DFRAME_PC9 SILABS_DBUS_PTI_DFRAME(0x2, 0x9) +#define PTI_DFRAME_PD0 SILABS_DBUS_PTI_DFRAME(0x3, 0x0) +#define PTI_DFRAME_PD1 SILABS_DBUS_PTI_DFRAME(0x3, 0x1) +#define PTI_DFRAME_PD2 SILABS_DBUS_PTI_DFRAME(0x3, 0x2) +#define PTI_DFRAME_PD3 SILABS_DBUS_PTI_DFRAME(0x3, 0x3) +#define PTI_DFRAME_PD4 SILABS_DBUS_PTI_DFRAME(0x3, 0x4) +#define PTI_DFRAME_PD5 SILABS_DBUS_PTI_DFRAME(0x3, 0x5) +#define PTI_DOUT_PC0 SILABS_DBUS_PTI_DOUT(0x2, 0x0) +#define PTI_DOUT_PC1 SILABS_DBUS_PTI_DOUT(0x2, 0x1) +#define PTI_DOUT_PC2 SILABS_DBUS_PTI_DOUT(0x2, 0x2) +#define PTI_DOUT_PC3 SILABS_DBUS_PTI_DOUT(0x2, 0x3) +#define PTI_DOUT_PC4 SILABS_DBUS_PTI_DOUT(0x2, 0x4) +#define PTI_DOUT_PC5 SILABS_DBUS_PTI_DOUT(0x2, 0x5) +#define PTI_DOUT_PC6 SILABS_DBUS_PTI_DOUT(0x2, 0x6) +#define PTI_DOUT_PC7 SILABS_DBUS_PTI_DOUT(0x2, 0x7) +#define PTI_DOUT_PC8 SILABS_DBUS_PTI_DOUT(0x2, 0x8) +#define PTI_DOUT_PC9 SILABS_DBUS_PTI_DOUT(0x2, 0x9) +#define PTI_DOUT_PD0 SILABS_DBUS_PTI_DOUT(0x3, 0x0) +#define PTI_DOUT_PD1 SILABS_DBUS_PTI_DOUT(0x3, 0x1) +#define PTI_DOUT_PD2 SILABS_DBUS_PTI_DOUT(0x3, 0x2) +#define PTI_DOUT_PD3 SILABS_DBUS_PTI_DOUT(0x3, 0x3) +#define PTI_DOUT_PD4 SILABS_DBUS_PTI_DOUT(0x3, 0x4) +#define PTI_DOUT_PD5 SILABS_DBUS_PTI_DOUT(0x3, 0x5) + +#define I2C0_SCL_PA0 SILABS_DBUS_I2C0_SCL(0x0, 0x0) +#define I2C0_SCL_PA1 SILABS_DBUS_I2C0_SCL(0x0, 0x1) +#define I2C0_SCL_PA2 SILABS_DBUS_I2C0_SCL(0x0, 0x2) +#define I2C0_SCL_PA3 SILABS_DBUS_I2C0_SCL(0x0, 0x3) +#define I2C0_SCL_PA4 SILABS_DBUS_I2C0_SCL(0x0, 0x4) +#define I2C0_SCL_PA5 SILABS_DBUS_I2C0_SCL(0x0, 0x5) +#define I2C0_SCL_PA6 SILABS_DBUS_I2C0_SCL(0x0, 0x6) +#define I2C0_SCL_PA7 SILABS_DBUS_I2C0_SCL(0x0, 0x7) +#define I2C0_SCL_PA8 SILABS_DBUS_I2C0_SCL(0x0, 0x8) +#define I2C0_SCL_PA9 SILABS_DBUS_I2C0_SCL(0x0, 0x9) +#define I2C0_SCL_PA10 SILABS_DBUS_I2C0_SCL(0x0, 0xa) +#define I2C0_SCL_PB0 SILABS_DBUS_I2C0_SCL(0x1, 0x0) +#define I2C0_SCL_PB1 SILABS_DBUS_I2C0_SCL(0x1, 0x1) +#define I2C0_SCL_PB2 SILABS_DBUS_I2C0_SCL(0x1, 0x2) +#define I2C0_SCL_PB3 SILABS_DBUS_I2C0_SCL(0x1, 0x3) +#define I2C0_SCL_PB4 SILABS_DBUS_I2C0_SCL(0x1, 0x4) +#define I2C0_SCL_PB5 SILABS_DBUS_I2C0_SCL(0x1, 0x5) +#define I2C0_SCL_PB6 SILABS_DBUS_I2C0_SCL(0x1, 0x6) +#define I2C0_SCL_PC0 SILABS_DBUS_I2C0_SCL(0x2, 0x0) +#define I2C0_SCL_PC1 SILABS_DBUS_I2C0_SCL(0x2, 0x1) +#define I2C0_SCL_PC2 SILABS_DBUS_I2C0_SCL(0x2, 0x2) +#define I2C0_SCL_PC3 SILABS_DBUS_I2C0_SCL(0x2, 0x3) +#define I2C0_SCL_PC4 SILABS_DBUS_I2C0_SCL(0x2, 0x4) +#define I2C0_SCL_PC5 SILABS_DBUS_I2C0_SCL(0x2, 0x5) +#define I2C0_SCL_PC6 SILABS_DBUS_I2C0_SCL(0x2, 0x6) +#define I2C0_SCL_PC7 SILABS_DBUS_I2C0_SCL(0x2, 0x7) +#define I2C0_SCL_PC8 SILABS_DBUS_I2C0_SCL(0x2, 0x8) +#define I2C0_SCL_PC9 SILABS_DBUS_I2C0_SCL(0x2, 0x9) +#define I2C0_SCL_PD0 SILABS_DBUS_I2C0_SCL(0x3, 0x0) +#define I2C0_SCL_PD1 SILABS_DBUS_I2C0_SCL(0x3, 0x1) +#define I2C0_SCL_PD2 SILABS_DBUS_I2C0_SCL(0x3, 0x2) +#define I2C0_SCL_PD3 SILABS_DBUS_I2C0_SCL(0x3, 0x3) +#define I2C0_SCL_PD4 SILABS_DBUS_I2C0_SCL(0x3, 0x4) +#define I2C0_SCL_PD5 SILABS_DBUS_I2C0_SCL(0x3, 0x5) +#define I2C0_SDA_PA0 SILABS_DBUS_I2C0_SDA(0x0, 0x0) +#define I2C0_SDA_PA1 SILABS_DBUS_I2C0_SDA(0x0, 0x1) +#define I2C0_SDA_PA2 SILABS_DBUS_I2C0_SDA(0x0, 0x2) +#define I2C0_SDA_PA3 SILABS_DBUS_I2C0_SDA(0x0, 0x3) +#define I2C0_SDA_PA4 SILABS_DBUS_I2C0_SDA(0x0, 0x4) +#define I2C0_SDA_PA5 SILABS_DBUS_I2C0_SDA(0x0, 0x5) +#define I2C0_SDA_PA6 SILABS_DBUS_I2C0_SDA(0x0, 0x6) +#define I2C0_SDA_PA7 SILABS_DBUS_I2C0_SDA(0x0, 0x7) +#define I2C0_SDA_PA8 SILABS_DBUS_I2C0_SDA(0x0, 0x8) +#define I2C0_SDA_PA9 SILABS_DBUS_I2C0_SDA(0x0, 0x9) +#define I2C0_SDA_PA10 SILABS_DBUS_I2C0_SDA(0x0, 0xa) +#define I2C0_SDA_PB0 SILABS_DBUS_I2C0_SDA(0x1, 0x0) +#define I2C0_SDA_PB1 SILABS_DBUS_I2C0_SDA(0x1, 0x1) +#define I2C0_SDA_PB2 SILABS_DBUS_I2C0_SDA(0x1, 0x2) +#define I2C0_SDA_PB3 SILABS_DBUS_I2C0_SDA(0x1, 0x3) +#define I2C0_SDA_PB4 SILABS_DBUS_I2C0_SDA(0x1, 0x4) +#define I2C0_SDA_PB5 SILABS_DBUS_I2C0_SDA(0x1, 0x5) +#define I2C0_SDA_PB6 SILABS_DBUS_I2C0_SDA(0x1, 0x6) +#define I2C0_SDA_PC0 SILABS_DBUS_I2C0_SDA(0x2, 0x0) +#define I2C0_SDA_PC1 SILABS_DBUS_I2C0_SDA(0x2, 0x1) +#define I2C0_SDA_PC2 SILABS_DBUS_I2C0_SDA(0x2, 0x2) +#define I2C0_SDA_PC3 SILABS_DBUS_I2C0_SDA(0x2, 0x3) +#define I2C0_SDA_PC4 SILABS_DBUS_I2C0_SDA(0x2, 0x4) +#define I2C0_SDA_PC5 SILABS_DBUS_I2C0_SDA(0x2, 0x5) +#define I2C0_SDA_PC6 SILABS_DBUS_I2C0_SDA(0x2, 0x6) +#define I2C0_SDA_PC7 SILABS_DBUS_I2C0_SDA(0x2, 0x7) +#define I2C0_SDA_PC8 SILABS_DBUS_I2C0_SDA(0x2, 0x8) +#define I2C0_SDA_PC9 SILABS_DBUS_I2C0_SDA(0x2, 0x9) +#define I2C0_SDA_PD0 SILABS_DBUS_I2C0_SDA(0x3, 0x0) +#define I2C0_SDA_PD1 SILABS_DBUS_I2C0_SDA(0x3, 0x1) +#define I2C0_SDA_PD2 SILABS_DBUS_I2C0_SDA(0x3, 0x2) +#define I2C0_SDA_PD3 SILABS_DBUS_I2C0_SDA(0x3, 0x3) +#define I2C0_SDA_PD4 SILABS_DBUS_I2C0_SDA(0x3, 0x4) +#define I2C0_SDA_PD5 SILABS_DBUS_I2C0_SDA(0x3, 0x5) + +#define I2C1_SCL_PC0 SILABS_DBUS_I2C1_SCL(0x2, 0x0) +#define I2C1_SCL_PC1 SILABS_DBUS_I2C1_SCL(0x2, 0x1) +#define I2C1_SCL_PC2 SILABS_DBUS_I2C1_SCL(0x2, 0x2) +#define I2C1_SCL_PC3 SILABS_DBUS_I2C1_SCL(0x2, 0x3) +#define I2C1_SCL_PC4 SILABS_DBUS_I2C1_SCL(0x2, 0x4) +#define I2C1_SCL_PC5 SILABS_DBUS_I2C1_SCL(0x2, 0x5) +#define I2C1_SCL_PC6 SILABS_DBUS_I2C1_SCL(0x2, 0x6) +#define I2C1_SCL_PC7 SILABS_DBUS_I2C1_SCL(0x2, 0x7) +#define I2C1_SCL_PC8 SILABS_DBUS_I2C1_SCL(0x2, 0x8) +#define I2C1_SCL_PC9 SILABS_DBUS_I2C1_SCL(0x2, 0x9) +#define I2C1_SCL_PD0 SILABS_DBUS_I2C1_SCL(0x3, 0x0) +#define I2C1_SCL_PD1 SILABS_DBUS_I2C1_SCL(0x3, 0x1) +#define I2C1_SCL_PD2 SILABS_DBUS_I2C1_SCL(0x3, 0x2) +#define I2C1_SCL_PD3 SILABS_DBUS_I2C1_SCL(0x3, 0x3) +#define I2C1_SCL_PD4 SILABS_DBUS_I2C1_SCL(0x3, 0x4) +#define I2C1_SCL_PD5 SILABS_DBUS_I2C1_SCL(0x3, 0x5) +#define I2C1_SDA_PC0 SILABS_DBUS_I2C1_SDA(0x2, 0x0) +#define I2C1_SDA_PC1 SILABS_DBUS_I2C1_SDA(0x2, 0x1) +#define I2C1_SDA_PC2 SILABS_DBUS_I2C1_SDA(0x2, 0x2) +#define I2C1_SDA_PC3 SILABS_DBUS_I2C1_SDA(0x2, 0x3) +#define I2C1_SDA_PC4 SILABS_DBUS_I2C1_SDA(0x2, 0x4) +#define I2C1_SDA_PC5 SILABS_DBUS_I2C1_SDA(0x2, 0x5) +#define I2C1_SDA_PC6 SILABS_DBUS_I2C1_SDA(0x2, 0x6) +#define I2C1_SDA_PC7 SILABS_DBUS_I2C1_SDA(0x2, 0x7) +#define I2C1_SDA_PC8 SILABS_DBUS_I2C1_SDA(0x2, 0x8) +#define I2C1_SDA_PC9 SILABS_DBUS_I2C1_SDA(0x2, 0x9) +#define I2C1_SDA_PD0 SILABS_DBUS_I2C1_SDA(0x3, 0x0) +#define I2C1_SDA_PD1 SILABS_DBUS_I2C1_SDA(0x3, 0x1) +#define I2C1_SDA_PD2 SILABS_DBUS_I2C1_SDA(0x3, 0x2) +#define I2C1_SDA_PD3 SILABS_DBUS_I2C1_SDA(0x3, 0x3) +#define I2C1_SDA_PD4 SILABS_DBUS_I2C1_SDA(0x3, 0x4) +#define I2C1_SDA_PD5 SILABS_DBUS_I2C1_SDA(0x3, 0x5) + +#define KEYSCAN_COLOUT0_PA0 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x0) +#define KEYSCAN_COLOUT0_PA1 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x1) +#define KEYSCAN_COLOUT0_PA2 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x2) +#define KEYSCAN_COLOUT0_PA3 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x3) +#define KEYSCAN_COLOUT0_PA4 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x4) +#define KEYSCAN_COLOUT0_PA5 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x5) +#define KEYSCAN_COLOUT0_PA6 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x6) +#define KEYSCAN_COLOUT0_PA7 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x7) +#define KEYSCAN_COLOUT0_PA8 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x8) +#define KEYSCAN_COLOUT0_PA9 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0x9) +#define KEYSCAN_COLOUT0_PA10 SILABS_DBUS_KEYSCAN_COLOUT0(0x0, 0xa) +#define KEYSCAN_COLOUT0_PB0 SILABS_DBUS_KEYSCAN_COLOUT0(0x1, 0x0) +#define KEYSCAN_COLOUT0_PB1 SILABS_DBUS_KEYSCAN_COLOUT0(0x1, 0x1) +#define KEYSCAN_COLOUT0_PB2 SILABS_DBUS_KEYSCAN_COLOUT0(0x1, 0x2) +#define KEYSCAN_COLOUT0_PB3 SILABS_DBUS_KEYSCAN_COLOUT0(0x1, 0x3) +#define KEYSCAN_COLOUT0_PB4 SILABS_DBUS_KEYSCAN_COLOUT0(0x1, 0x4) +#define KEYSCAN_COLOUT0_PB5 SILABS_DBUS_KEYSCAN_COLOUT0(0x1, 0x5) +#define KEYSCAN_COLOUT0_PB6 SILABS_DBUS_KEYSCAN_COLOUT0(0x1, 0x6) +#define KEYSCAN_COLOUT0_PC0 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x0) +#define KEYSCAN_COLOUT0_PC1 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x1) +#define KEYSCAN_COLOUT0_PC2 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x2) +#define KEYSCAN_COLOUT0_PC3 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x3) +#define KEYSCAN_COLOUT0_PC4 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x4) +#define KEYSCAN_COLOUT0_PC5 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x5) +#define KEYSCAN_COLOUT0_PC6 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x6) +#define KEYSCAN_COLOUT0_PC7 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x7) +#define KEYSCAN_COLOUT0_PC8 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x8) +#define KEYSCAN_COLOUT0_PC9 SILABS_DBUS_KEYSCAN_COLOUT0(0x2, 0x9) +#define KEYSCAN_COLOUT0_PD0 SILABS_DBUS_KEYSCAN_COLOUT0(0x3, 0x0) +#define KEYSCAN_COLOUT0_PD1 SILABS_DBUS_KEYSCAN_COLOUT0(0x3, 0x1) +#define KEYSCAN_COLOUT0_PD2 SILABS_DBUS_KEYSCAN_COLOUT0(0x3, 0x2) +#define KEYSCAN_COLOUT0_PD3 SILABS_DBUS_KEYSCAN_COLOUT0(0x3, 0x3) +#define KEYSCAN_COLOUT0_PD4 SILABS_DBUS_KEYSCAN_COLOUT0(0x3, 0x4) +#define KEYSCAN_COLOUT0_PD5 SILABS_DBUS_KEYSCAN_COLOUT0(0x3, 0x5) +#define KEYSCAN_COLOUT1_PA0 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x0) +#define KEYSCAN_COLOUT1_PA1 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x1) +#define KEYSCAN_COLOUT1_PA2 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x2) +#define KEYSCAN_COLOUT1_PA3 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x3) +#define KEYSCAN_COLOUT1_PA4 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x4) +#define KEYSCAN_COLOUT1_PA5 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x5) +#define KEYSCAN_COLOUT1_PA6 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x6) +#define KEYSCAN_COLOUT1_PA7 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x7) +#define KEYSCAN_COLOUT1_PA8 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x8) +#define KEYSCAN_COLOUT1_PA9 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0x9) +#define KEYSCAN_COLOUT1_PA10 SILABS_DBUS_KEYSCAN_COLOUT1(0x0, 0xa) +#define KEYSCAN_COLOUT1_PB0 SILABS_DBUS_KEYSCAN_COLOUT1(0x1, 0x0) +#define KEYSCAN_COLOUT1_PB1 SILABS_DBUS_KEYSCAN_COLOUT1(0x1, 0x1) +#define KEYSCAN_COLOUT1_PB2 SILABS_DBUS_KEYSCAN_COLOUT1(0x1, 0x2) +#define KEYSCAN_COLOUT1_PB3 SILABS_DBUS_KEYSCAN_COLOUT1(0x1, 0x3) +#define KEYSCAN_COLOUT1_PB4 SILABS_DBUS_KEYSCAN_COLOUT1(0x1, 0x4) +#define KEYSCAN_COLOUT1_PB5 SILABS_DBUS_KEYSCAN_COLOUT1(0x1, 0x5) +#define KEYSCAN_COLOUT1_PB6 SILABS_DBUS_KEYSCAN_COLOUT1(0x1, 0x6) +#define KEYSCAN_COLOUT1_PC0 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x0) +#define KEYSCAN_COLOUT1_PC1 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x1) +#define KEYSCAN_COLOUT1_PC2 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x2) +#define KEYSCAN_COLOUT1_PC3 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x3) +#define KEYSCAN_COLOUT1_PC4 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x4) +#define KEYSCAN_COLOUT1_PC5 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x5) +#define KEYSCAN_COLOUT1_PC6 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x6) +#define KEYSCAN_COLOUT1_PC7 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x7) +#define KEYSCAN_COLOUT1_PC8 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x8) +#define KEYSCAN_COLOUT1_PC9 SILABS_DBUS_KEYSCAN_COLOUT1(0x2, 0x9) +#define KEYSCAN_COLOUT1_PD0 SILABS_DBUS_KEYSCAN_COLOUT1(0x3, 0x0) +#define KEYSCAN_COLOUT1_PD1 SILABS_DBUS_KEYSCAN_COLOUT1(0x3, 0x1) +#define KEYSCAN_COLOUT1_PD2 SILABS_DBUS_KEYSCAN_COLOUT1(0x3, 0x2) +#define KEYSCAN_COLOUT1_PD3 SILABS_DBUS_KEYSCAN_COLOUT1(0x3, 0x3) +#define KEYSCAN_COLOUT1_PD4 SILABS_DBUS_KEYSCAN_COLOUT1(0x3, 0x4) +#define KEYSCAN_COLOUT1_PD5 SILABS_DBUS_KEYSCAN_COLOUT1(0x3, 0x5) +#define KEYSCAN_COLOUT2_PA0 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x0) +#define KEYSCAN_COLOUT2_PA1 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x1) +#define KEYSCAN_COLOUT2_PA2 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x2) +#define KEYSCAN_COLOUT2_PA3 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x3) +#define KEYSCAN_COLOUT2_PA4 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x4) +#define KEYSCAN_COLOUT2_PA5 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x5) +#define KEYSCAN_COLOUT2_PA6 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x6) +#define KEYSCAN_COLOUT2_PA7 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x7) +#define KEYSCAN_COLOUT2_PA8 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x8) +#define KEYSCAN_COLOUT2_PA9 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0x9) +#define KEYSCAN_COLOUT2_PA10 SILABS_DBUS_KEYSCAN_COLOUT2(0x0, 0xa) +#define KEYSCAN_COLOUT2_PB0 SILABS_DBUS_KEYSCAN_COLOUT2(0x1, 0x0) +#define KEYSCAN_COLOUT2_PB1 SILABS_DBUS_KEYSCAN_COLOUT2(0x1, 0x1) +#define KEYSCAN_COLOUT2_PB2 SILABS_DBUS_KEYSCAN_COLOUT2(0x1, 0x2) +#define KEYSCAN_COLOUT2_PB3 SILABS_DBUS_KEYSCAN_COLOUT2(0x1, 0x3) +#define KEYSCAN_COLOUT2_PB4 SILABS_DBUS_KEYSCAN_COLOUT2(0x1, 0x4) +#define KEYSCAN_COLOUT2_PB5 SILABS_DBUS_KEYSCAN_COLOUT2(0x1, 0x5) +#define KEYSCAN_COLOUT2_PB6 SILABS_DBUS_KEYSCAN_COLOUT2(0x1, 0x6) +#define KEYSCAN_COLOUT2_PC0 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x0) +#define KEYSCAN_COLOUT2_PC1 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x1) +#define KEYSCAN_COLOUT2_PC2 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x2) +#define KEYSCAN_COLOUT2_PC3 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x3) +#define KEYSCAN_COLOUT2_PC4 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x4) +#define KEYSCAN_COLOUT2_PC5 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x5) +#define KEYSCAN_COLOUT2_PC6 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x6) +#define KEYSCAN_COLOUT2_PC7 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x7) +#define KEYSCAN_COLOUT2_PC8 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x8) +#define KEYSCAN_COLOUT2_PC9 SILABS_DBUS_KEYSCAN_COLOUT2(0x2, 0x9) +#define KEYSCAN_COLOUT2_PD0 SILABS_DBUS_KEYSCAN_COLOUT2(0x3, 0x0) +#define KEYSCAN_COLOUT2_PD1 SILABS_DBUS_KEYSCAN_COLOUT2(0x3, 0x1) +#define KEYSCAN_COLOUT2_PD2 SILABS_DBUS_KEYSCAN_COLOUT2(0x3, 0x2) +#define KEYSCAN_COLOUT2_PD3 SILABS_DBUS_KEYSCAN_COLOUT2(0x3, 0x3) +#define KEYSCAN_COLOUT2_PD4 SILABS_DBUS_KEYSCAN_COLOUT2(0x3, 0x4) +#define KEYSCAN_COLOUT2_PD5 SILABS_DBUS_KEYSCAN_COLOUT2(0x3, 0x5) +#define KEYSCAN_COLOUT3_PA0 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x0) +#define KEYSCAN_COLOUT3_PA1 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x1) +#define KEYSCAN_COLOUT3_PA2 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x2) +#define KEYSCAN_COLOUT3_PA3 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x3) +#define KEYSCAN_COLOUT3_PA4 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x4) +#define KEYSCAN_COLOUT3_PA5 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x5) +#define KEYSCAN_COLOUT3_PA6 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x6) +#define KEYSCAN_COLOUT3_PA7 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x7) +#define KEYSCAN_COLOUT3_PA8 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x8) +#define KEYSCAN_COLOUT3_PA9 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0x9) +#define KEYSCAN_COLOUT3_PA10 SILABS_DBUS_KEYSCAN_COLOUT3(0x0, 0xa) +#define KEYSCAN_COLOUT3_PB0 SILABS_DBUS_KEYSCAN_COLOUT3(0x1, 0x0) +#define KEYSCAN_COLOUT3_PB1 SILABS_DBUS_KEYSCAN_COLOUT3(0x1, 0x1) +#define KEYSCAN_COLOUT3_PB2 SILABS_DBUS_KEYSCAN_COLOUT3(0x1, 0x2) +#define KEYSCAN_COLOUT3_PB3 SILABS_DBUS_KEYSCAN_COLOUT3(0x1, 0x3) +#define KEYSCAN_COLOUT3_PB4 SILABS_DBUS_KEYSCAN_COLOUT3(0x1, 0x4) +#define KEYSCAN_COLOUT3_PB5 SILABS_DBUS_KEYSCAN_COLOUT3(0x1, 0x5) +#define KEYSCAN_COLOUT3_PB6 SILABS_DBUS_KEYSCAN_COLOUT3(0x1, 0x6) +#define KEYSCAN_COLOUT3_PC0 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x0) +#define KEYSCAN_COLOUT3_PC1 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x1) +#define KEYSCAN_COLOUT3_PC2 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x2) +#define KEYSCAN_COLOUT3_PC3 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x3) +#define KEYSCAN_COLOUT3_PC4 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x4) +#define KEYSCAN_COLOUT3_PC5 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x5) +#define KEYSCAN_COLOUT3_PC6 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x6) +#define KEYSCAN_COLOUT3_PC7 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x7) +#define KEYSCAN_COLOUT3_PC8 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x8) +#define KEYSCAN_COLOUT3_PC9 SILABS_DBUS_KEYSCAN_COLOUT3(0x2, 0x9) +#define KEYSCAN_COLOUT3_PD0 SILABS_DBUS_KEYSCAN_COLOUT3(0x3, 0x0) +#define KEYSCAN_COLOUT3_PD1 SILABS_DBUS_KEYSCAN_COLOUT3(0x3, 0x1) +#define KEYSCAN_COLOUT3_PD2 SILABS_DBUS_KEYSCAN_COLOUT3(0x3, 0x2) +#define KEYSCAN_COLOUT3_PD3 SILABS_DBUS_KEYSCAN_COLOUT3(0x3, 0x3) +#define KEYSCAN_COLOUT3_PD4 SILABS_DBUS_KEYSCAN_COLOUT3(0x3, 0x4) +#define KEYSCAN_COLOUT3_PD5 SILABS_DBUS_KEYSCAN_COLOUT3(0x3, 0x5) +#define KEYSCAN_COLOUT4_PA0 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x0) +#define KEYSCAN_COLOUT4_PA1 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x1) +#define KEYSCAN_COLOUT4_PA2 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x2) +#define KEYSCAN_COLOUT4_PA3 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x3) +#define KEYSCAN_COLOUT4_PA4 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x4) +#define KEYSCAN_COLOUT4_PA5 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x5) +#define KEYSCAN_COLOUT4_PA6 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x6) +#define KEYSCAN_COLOUT4_PA7 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x7) +#define KEYSCAN_COLOUT4_PA8 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x8) +#define KEYSCAN_COLOUT4_PA9 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0x9) +#define KEYSCAN_COLOUT4_PA10 SILABS_DBUS_KEYSCAN_COLOUT4(0x0, 0xa) +#define KEYSCAN_COLOUT4_PB0 SILABS_DBUS_KEYSCAN_COLOUT4(0x1, 0x0) +#define KEYSCAN_COLOUT4_PB1 SILABS_DBUS_KEYSCAN_COLOUT4(0x1, 0x1) +#define KEYSCAN_COLOUT4_PB2 SILABS_DBUS_KEYSCAN_COLOUT4(0x1, 0x2) +#define KEYSCAN_COLOUT4_PB3 SILABS_DBUS_KEYSCAN_COLOUT4(0x1, 0x3) +#define KEYSCAN_COLOUT4_PB4 SILABS_DBUS_KEYSCAN_COLOUT4(0x1, 0x4) +#define KEYSCAN_COLOUT4_PB5 SILABS_DBUS_KEYSCAN_COLOUT4(0x1, 0x5) +#define KEYSCAN_COLOUT4_PB6 SILABS_DBUS_KEYSCAN_COLOUT4(0x1, 0x6) +#define KEYSCAN_COLOUT4_PC0 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x0) +#define KEYSCAN_COLOUT4_PC1 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x1) +#define KEYSCAN_COLOUT4_PC2 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x2) +#define KEYSCAN_COLOUT4_PC3 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x3) +#define KEYSCAN_COLOUT4_PC4 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x4) +#define KEYSCAN_COLOUT4_PC5 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x5) +#define KEYSCAN_COLOUT4_PC6 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x6) +#define KEYSCAN_COLOUT4_PC7 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x7) +#define KEYSCAN_COLOUT4_PC8 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x8) +#define KEYSCAN_COLOUT4_PC9 SILABS_DBUS_KEYSCAN_COLOUT4(0x2, 0x9) +#define KEYSCAN_COLOUT4_PD0 SILABS_DBUS_KEYSCAN_COLOUT4(0x3, 0x0) +#define KEYSCAN_COLOUT4_PD1 SILABS_DBUS_KEYSCAN_COLOUT4(0x3, 0x1) +#define KEYSCAN_COLOUT4_PD2 SILABS_DBUS_KEYSCAN_COLOUT4(0x3, 0x2) +#define KEYSCAN_COLOUT4_PD3 SILABS_DBUS_KEYSCAN_COLOUT4(0x3, 0x3) +#define KEYSCAN_COLOUT4_PD4 SILABS_DBUS_KEYSCAN_COLOUT4(0x3, 0x4) +#define KEYSCAN_COLOUT4_PD5 SILABS_DBUS_KEYSCAN_COLOUT4(0x3, 0x5) +#define KEYSCAN_COLOUT5_PA0 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x0) +#define KEYSCAN_COLOUT5_PA1 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x1) +#define KEYSCAN_COLOUT5_PA2 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x2) +#define KEYSCAN_COLOUT5_PA3 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x3) +#define KEYSCAN_COLOUT5_PA4 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x4) +#define KEYSCAN_COLOUT5_PA5 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x5) +#define KEYSCAN_COLOUT5_PA6 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x6) +#define KEYSCAN_COLOUT5_PA7 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x7) +#define KEYSCAN_COLOUT5_PA8 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x8) +#define KEYSCAN_COLOUT5_PA9 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0x9) +#define KEYSCAN_COLOUT5_PA10 SILABS_DBUS_KEYSCAN_COLOUT5(0x0, 0xa) +#define KEYSCAN_COLOUT5_PB0 SILABS_DBUS_KEYSCAN_COLOUT5(0x1, 0x0) +#define KEYSCAN_COLOUT5_PB1 SILABS_DBUS_KEYSCAN_COLOUT5(0x1, 0x1) +#define KEYSCAN_COLOUT5_PB2 SILABS_DBUS_KEYSCAN_COLOUT5(0x1, 0x2) +#define KEYSCAN_COLOUT5_PB3 SILABS_DBUS_KEYSCAN_COLOUT5(0x1, 0x3) +#define KEYSCAN_COLOUT5_PB4 SILABS_DBUS_KEYSCAN_COLOUT5(0x1, 0x4) +#define KEYSCAN_COLOUT5_PB5 SILABS_DBUS_KEYSCAN_COLOUT5(0x1, 0x5) +#define KEYSCAN_COLOUT5_PB6 SILABS_DBUS_KEYSCAN_COLOUT5(0x1, 0x6) +#define KEYSCAN_COLOUT5_PC0 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x0) +#define KEYSCAN_COLOUT5_PC1 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x1) +#define KEYSCAN_COLOUT5_PC2 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x2) +#define KEYSCAN_COLOUT5_PC3 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x3) +#define KEYSCAN_COLOUT5_PC4 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x4) +#define KEYSCAN_COLOUT5_PC5 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x5) +#define KEYSCAN_COLOUT5_PC6 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x6) +#define KEYSCAN_COLOUT5_PC7 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x7) +#define KEYSCAN_COLOUT5_PC8 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x8) +#define KEYSCAN_COLOUT5_PC9 SILABS_DBUS_KEYSCAN_COLOUT5(0x2, 0x9) +#define KEYSCAN_COLOUT5_PD0 SILABS_DBUS_KEYSCAN_COLOUT5(0x3, 0x0) +#define KEYSCAN_COLOUT5_PD1 SILABS_DBUS_KEYSCAN_COLOUT5(0x3, 0x1) +#define KEYSCAN_COLOUT5_PD2 SILABS_DBUS_KEYSCAN_COLOUT5(0x3, 0x2) +#define KEYSCAN_COLOUT5_PD3 SILABS_DBUS_KEYSCAN_COLOUT5(0x3, 0x3) +#define KEYSCAN_COLOUT5_PD4 SILABS_DBUS_KEYSCAN_COLOUT5(0x3, 0x4) +#define KEYSCAN_COLOUT5_PD5 SILABS_DBUS_KEYSCAN_COLOUT5(0x3, 0x5) +#define KEYSCAN_COLOUT6_PA0 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x0) +#define KEYSCAN_COLOUT6_PA1 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x1) +#define KEYSCAN_COLOUT6_PA2 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x2) +#define KEYSCAN_COLOUT6_PA3 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x3) +#define KEYSCAN_COLOUT6_PA4 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x4) +#define KEYSCAN_COLOUT6_PA5 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x5) +#define KEYSCAN_COLOUT6_PA6 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x6) +#define KEYSCAN_COLOUT6_PA7 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x7) +#define KEYSCAN_COLOUT6_PA8 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x8) +#define KEYSCAN_COLOUT6_PA9 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0x9) +#define KEYSCAN_COLOUT6_PA10 SILABS_DBUS_KEYSCAN_COLOUT6(0x0, 0xa) +#define KEYSCAN_COLOUT6_PB0 SILABS_DBUS_KEYSCAN_COLOUT6(0x1, 0x0) +#define KEYSCAN_COLOUT6_PB1 SILABS_DBUS_KEYSCAN_COLOUT6(0x1, 0x1) +#define KEYSCAN_COLOUT6_PB2 SILABS_DBUS_KEYSCAN_COLOUT6(0x1, 0x2) +#define KEYSCAN_COLOUT6_PB3 SILABS_DBUS_KEYSCAN_COLOUT6(0x1, 0x3) +#define KEYSCAN_COLOUT6_PB4 SILABS_DBUS_KEYSCAN_COLOUT6(0x1, 0x4) +#define KEYSCAN_COLOUT6_PB5 SILABS_DBUS_KEYSCAN_COLOUT6(0x1, 0x5) +#define KEYSCAN_COLOUT6_PB6 SILABS_DBUS_KEYSCAN_COLOUT6(0x1, 0x6) +#define KEYSCAN_COLOUT6_PC0 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x0) +#define KEYSCAN_COLOUT6_PC1 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x1) +#define KEYSCAN_COLOUT6_PC2 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x2) +#define KEYSCAN_COLOUT6_PC3 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x3) +#define KEYSCAN_COLOUT6_PC4 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x4) +#define KEYSCAN_COLOUT6_PC5 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x5) +#define KEYSCAN_COLOUT6_PC6 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x6) +#define KEYSCAN_COLOUT6_PC7 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x7) +#define KEYSCAN_COLOUT6_PC8 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x8) +#define KEYSCAN_COLOUT6_PC9 SILABS_DBUS_KEYSCAN_COLOUT6(0x2, 0x9) +#define KEYSCAN_COLOUT6_PD0 SILABS_DBUS_KEYSCAN_COLOUT6(0x3, 0x0) +#define KEYSCAN_COLOUT6_PD1 SILABS_DBUS_KEYSCAN_COLOUT6(0x3, 0x1) +#define KEYSCAN_COLOUT6_PD2 SILABS_DBUS_KEYSCAN_COLOUT6(0x3, 0x2) +#define KEYSCAN_COLOUT6_PD3 SILABS_DBUS_KEYSCAN_COLOUT6(0x3, 0x3) +#define KEYSCAN_COLOUT6_PD4 SILABS_DBUS_KEYSCAN_COLOUT6(0x3, 0x4) +#define KEYSCAN_COLOUT6_PD5 SILABS_DBUS_KEYSCAN_COLOUT6(0x3, 0x5) +#define KEYSCAN_COLOUT7_PA0 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x0) +#define KEYSCAN_COLOUT7_PA1 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x1) +#define KEYSCAN_COLOUT7_PA2 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x2) +#define KEYSCAN_COLOUT7_PA3 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x3) +#define KEYSCAN_COLOUT7_PA4 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x4) +#define KEYSCAN_COLOUT7_PA5 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x5) +#define KEYSCAN_COLOUT7_PA6 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x6) +#define KEYSCAN_COLOUT7_PA7 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x7) +#define KEYSCAN_COLOUT7_PA8 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x8) +#define KEYSCAN_COLOUT7_PA9 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0x9) +#define KEYSCAN_COLOUT7_PA10 SILABS_DBUS_KEYSCAN_COLOUT7(0x0, 0xa) +#define KEYSCAN_COLOUT7_PB0 SILABS_DBUS_KEYSCAN_COLOUT7(0x1, 0x0) +#define KEYSCAN_COLOUT7_PB1 SILABS_DBUS_KEYSCAN_COLOUT7(0x1, 0x1) +#define KEYSCAN_COLOUT7_PB2 SILABS_DBUS_KEYSCAN_COLOUT7(0x1, 0x2) +#define KEYSCAN_COLOUT7_PB3 SILABS_DBUS_KEYSCAN_COLOUT7(0x1, 0x3) +#define KEYSCAN_COLOUT7_PB4 SILABS_DBUS_KEYSCAN_COLOUT7(0x1, 0x4) +#define KEYSCAN_COLOUT7_PB5 SILABS_DBUS_KEYSCAN_COLOUT7(0x1, 0x5) +#define KEYSCAN_COLOUT7_PB6 SILABS_DBUS_KEYSCAN_COLOUT7(0x1, 0x6) +#define KEYSCAN_COLOUT7_PC0 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x0) +#define KEYSCAN_COLOUT7_PC1 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x1) +#define KEYSCAN_COLOUT7_PC2 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x2) +#define KEYSCAN_COLOUT7_PC3 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x3) +#define KEYSCAN_COLOUT7_PC4 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x4) +#define KEYSCAN_COLOUT7_PC5 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x5) +#define KEYSCAN_COLOUT7_PC6 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x6) +#define KEYSCAN_COLOUT7_PC7 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x7) +#define KEYSCAN_COLOUT7_PC8 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x8) +#define KEYSCAN_COLOUT7_PC9 SILABS_DBUS_KEYSCAN_COLOUT7(0x2, 0x9) +#define KEYSCAN_COLOUT7_PD0 SILABS_DBUS_KEYSCAN_COLOUT7(0x3, 0x0) +#define KEYSCAN_COLOUT7_PD1 SILABS_DBUS_KEYSCAN_COLOUT7(0x3, 0x1) +#define KEYSCAN_COLOUT7_PD2 SILABS_DBUS_KEYSCAN_COLOUT7(0x3, 0x2) +#define KEYSCAN_COLOUT7_PD3 SILABS_DBUS_KEYSCAN_COLOUT7(0x3, 0x3) +#define KEYSCAN_COLOUT7_PD4 SILABS_DBUS_KEYSCAN_COLOUT7(0x3, 0x4) +#define KEYSCAN_COLOUT7_PD5 SILABS_DBUS_KEYSCAN_COLOUT7(0x3, 0x5) +#define KEYSCAN_ROWSENSE0_PA0 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x0) +#define KEYSCAN_ROWSENSE0_PA1 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x1) +#define KEYSCAN_ROWSENSE0_PA2 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x2) +#define KEYSCAN_ROWSENSE0_PA3 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x3) +#define KEYSCAN_ROWSENSE0_PA4 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x4) +#define KEYSCAN_ROWSENSE0_PA5 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x5) +#define KEYSCAN_ROWSENSE0_PA6 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x6) +#define KEYSCAN_ROWSENSE0_PA7 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x7) +#define KEYSCAN_ROWSENSE0_PA8 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x8) +#define KEYSCAN_ROWSENSE0_PA9 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0x9) +#define KEYSCAN_ROWSENSE0_PA10 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x0, 0xa) +#define KEYSCAN_ROWSENSE0_PB0 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x1, 0x0) +#define KEYSCAN_ROWSENSE0_PB1 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x1, 0x1) +#define KEYSCAN_ROWSENSE0_PB2 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x1, 0x2) +#define KEYSCAN_ROWSENSE0_PB3 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x1, 0x3) +#define KEYSCAN_ROWSENSE0_PB4 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x1, 0x4) +#define KEYSCAN_ROWSENSE0_PB5 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x1, 0x5) +#define KEYSCAN_ROWSENSE0_PB6 SILABS_DBUS_KEYSCAN_ROWSENSE0(0x1, 0x6) +#define KEYSCAN_ROWSENSE1_PA0 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x0) +#define KEYSCAN_ROWSENSE1_PA1 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x1) +#define KEYSCAN_ROWSENSE1_PA2 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x2) +#define KEYSCAN_ROWSENSE1_PA3 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x3) +#define KEYSCAN_ROWSENSE1_PA4 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x4) +#define KEYSCAN_ROWSENSE1_PA5 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x5) +#define KEYSCAN_ROWSENSE1_PA6 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x6) +#define KEYSCAN_ROWSENSE1_PA7 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x7) +#define KEYSCAN_ROWSENSE1_PA8 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x8) +#define KEYSCAN_ROWSENSE1_PA9 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0x9) +#define KEYSCAN_ROWSENSE1_PA10 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x0, 0xa) +#define KEYSCAN_ROWSENSE1_PB0 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x1, 0x0) +#define KEYSCAN_ROWSENSE1_PB1 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x1, 0x1) +#define KEYSCAN_ROWSENSE1_PB2 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x1, 0x2) +#define KEYSCAN_ROWSENSE1_PB3 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x1, 0x3) +#define KEYSCAN_ROWSENSE1_PB4 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x1, 0x4) +#define KEYSCAN_ROWSENSE1_PB5 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x1, 0x5) +#define KEYSCAN_ROWSENSE1_PB6 SILABS_DBUS_KEYSCAN_ROWSENSE1(0x1, 0x6) +#define KEYSCAN_ROWSENSE2_PA0 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x0) +#define KEYSCAN_ROWSENSE2_PA1 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x1) +#define KEYSCAN_ROWSENSE2_PA2 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x2) +#define KEYSCAN_ROWSENSE2_PA3 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x3) +#define KEYSCAN_ROWSENSE2_PA4 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x4) +#define KEYSCAN_ROWSENSE2_PA5 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x5) +#define KEYSCAN_ROWSENSE2_PA6 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x6) +#define KEYSCAN_ROWSENSE2_PA7 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x7) +#define KEYSCAN_ROWSENSE2_PA8 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x8) +#define KEYSCAN_ROWSENSE2_PA9 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0x9) +#define KEYSCAN_ROWSENSE2_PA10 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x0, 0xa) +#define KEYSCAN_ROWSENSE2_PB0 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x1, 0x0) +#define KEYSCAN_ROWSENSE2_PB1 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x1, 0x1) +#define KEYSCAN_ROWSENSE2_PB2 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x1, 0x2) +#define KEYSCAN_ROWSENSE2_PB3 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x1, 0x3) +#define KEYSCAN_ROWSENSE2_PB4 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x1, 0x4) +#define KEYSCAN_ROWSENSE2_PB5 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x1, 0x5) +#define KEYSCAN_ROWSENSE2_PB6 SILABS_DBUS_KEYSCAN_ROWSENSE2(0x1, 0x6) +#define KEYSCAN_ROWSENSE3_PA0 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x0) +#define KEYSCAN_ROWSENSE3_PA1 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x1) +#define KEYSCAN_ROWSENSE3_PA2 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x2) +#define KEYSCAN_ROWSENSE3_PA3 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x3) +#define KEYSCAN_ROWSENSE3_PA4 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x4) +#define KEYSCAN_ROWSENSE3_PA5 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x5) +#define KEYSCAN_ROWSENSE3_PA6 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x6) +#define KEYSCAN_ROWSENSE3_PA7 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x7) +#define KEYSCAN_ROWSENSE3_PA8 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x8) +#define KEYSCAN_ROWSENSE3_PA9 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0x9) +#define KEYSCAN_ROWSENSE3_PA10 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x0, 0xa) +#define KEYSCAN_ROWSENSE3_PB0 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x1, 0x0) +#define KEYSCAN_ROWSENSE3_PB1 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x1, 0x1) +#define KEYSCAN_ROWSENSE3_PB2 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x1, 0x2) +#define KEYSCAN_ROWSENSE3_PB3 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x1, 0x3) +#define KEYSCAN_ROWSENSE3_PB4 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x1, 0x4) +#define KEYSCAN_ROWSENSE3_PB5 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x1, 0x5) +#define KEYSCAN_ROWSENSE3_PB6 SILABS_DBUS_KEYSCAN_ROWSENSE3(0x1, 0x6) +#define KEYSCAN_ROWSENSE4_PA0 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x0) +#define KEYSCAN_ROWSENSE4_PA1 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x1) +#define KEYSCAN_ROWSENSE4_PA2 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x2) +#define KEYSCAN_ROWSENSE4_PA3 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x3) +#define KEYSCAN_ROWSENSE4_PA4 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x4) +#define KEYSCAN_ROWSENSE4_PA5 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x5) +#define KEYSCAN_ROWSENSE4_PA6 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x6) +#define KEYSCAN_ROWSENSE4_PA7 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x7) +#define KEYSCAN_ROWSENSE4_PA8 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x8) +#define KEYSCAN_ROWSENSE4_PA9 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0x9) +#define KEYSCAN_ROWSENSE4_PA10 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x0, 0xa) +#define KEYSCAN_ROWSENSE4_PB0 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x1, 0x0) +#define KEYSCAN_ROWSENSE4_PB1 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x1, 0x1) +#define KEYSCAN_ROWSENSE4_PB2 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x1, 0x2) +#define KEYSCAN_ROWSENSE4_PB3 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x1, 0x3) +#define KEYSCAN_ROWSENSE4_PB4 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x1, 0x4) +#define KEYSCAN_ROWSENSE4_PB5 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x1, 0x5) +#define KEYSCAN_ROWSENSE4_PB6 SILABS_DBUS_KEYSCAN_ROWSENSE4(0x1, 0x6) +#define KEYSCAN_ROWSENSE5_PA0 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x0) +#define KEYSCAN_ROWSENSE5_PA1 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x1) +#define KEYSCAN_ROWSENSE5_PA2 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x2) +#define KEYSCAN_ROWSENSE5_PA3 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x3) +#define KEYSCAN_ROWSENSE5_PA4 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x4) +#define KEYSCAN_ROWSENSE5_PA5 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x5) +#define KEYSCAN_ROWSENSE5_PA6 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x6) +#define KEYSCAN_ROWSENSE5_PA7 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x7) +#define KEYSCAN_ROWSENSE5_PA8 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x8) +#define KEYSCAN_ROWSENSE5_PA9 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0x9) +#define KEYSCAN_ROWSENSE5_PA10 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x0, 0xa) +#define KEYSCAN_ROWSENSE5_PB0 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x1, 0x0) +#define KEYSCAN_ROWSENSE5_PB1 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x1, 0x1) +#define KEYSCAN_ROWSENSE5_PB2 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x1, 0x2) +#define KEYSCAN_ROWSENSE5_PB3 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x1, 0x3) +#define KEYSCAN_ROWSENSE5_PB4 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x1, 0x4) +#define KEYSCAN_ROWSENSE5_PB5 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x1, 0x5) +#define KEYSCAN_ROWSENSE5_PB6 SILABS_DBUS_KEYSCAN_ROWSENSE5(0x1, 0x6) + +#define LESENSE_CH0OUT_PA0 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x0) +#define LESENSE_CH0OUT_PA1 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x1) +#define LESENSE_CH0OUT_PA2 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x2) +#define LESENSE_CH0OUT_PA3 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x3) +#define LESENSE_CH0OUT_PA4 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x4) +#define LESENSE_CH0OUT_PA5 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x5) +#define LESENSE_CH0OUT_PA6 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x6) +#define LESENSE_CH0OUT_PA7 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x7) +#define LESENSE_CH0OUT_PA8 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x8) +#define LESENSE_CH0OUT_PA9 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0x9) +#define LESENSE_CH0OUT_PA10 SILABS_DBUS_LESENSE_CH0OUT(0x0, 0xa) +#define LESENSE_CH0OUT_PB0 SILABS_DBUS_LESENSE_CH0OUT(0x1, 0x0) +#define LESENSE_CH0OUT_PB1 SILABS_DBUS_LESENSE_CH0OUT(0x1, 0x1) +#define LESENSE_CH0OUT_PB2 SILABS_DBUS_LESENSE_CH0OUT(0x1, 0x2) +#define LESENSE_CH0OUT_PB3 SILABS_DBUS_LESENSE_CH0OUT(0x1, 0x3) +#define LESENSE_CH0OUT_PB4 SILABS_DBUS_LESENSE_CH0OUT(0x1, 0x4) +#define LESENSE_CH0OUT_PB5 SILABS_DBUS_LESENSE_CH0OUT(0x1, 0x5) +#define LESENSE_CH0OUT_PB6 SILABS_DBUS_LESENSE_CH0OUT(0x1, 0x6) +#define LESENSE_CH1OUT_PA0 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x0) +#define LESENSE_CH1OUT_PA1 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x1) +#define LESENSE_CH1OUT_PA2 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x2) +#define LESENSE_CH1OUT_PA3 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x3) +#define LESENSE_CH1OUT_PA4 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x4) +#define LESENSE_CH1OUT_PA5 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x5) +#define LESENSE_CH1OUT_PA6 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x6) +#define LESENSE_CH1OUT_PA7 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x7) +#define LESENSE_CH1OUT_PA8 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x8) +#define LESENSE_CH1OUT_PA9 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0x9) +#define LESENSE_CH1OUT_PA10 SILABS_DBUS_LESENSE_CH1OUT(0x0, 0xa) +#define LESENSE_CH1OUT_PB0 SILABS_DBUS_LESENSE_CH1OUT(0x1, 0x0) +#define LESENSE_CH1OUT_PB1 SILABS_DBUS_LESENSE_CH1OUT(0x1, 0x1) +#define LESENSE_CH1OUT_PB2 SILABS_DBUS_LESENSE_CH1OUT(0x1, 0x2) +#define LESENSE_CH1OUT_PB3 SILABS_DBUS_LESENSE_CH1OUT(0x1, 0x3) +#define LESENSE_CH1OUT_PB4 SILABS_DBUS_LESENSE_CH1OUT(0x1, 0x4) +#define LESENSE_CH1OUT_PB5 SILABS_DBUS_LESENSE_CH1OUT(0x1, 0x5) +#define LESENSE_CH1OUT_PB6 SILABS_DBUS_LESENSE_CH1OUT(0x1, 0x6) +#define LESENSE_CH2OUT_PA0 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x0) +#define LESENSE_CH2OUT_PA1 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x1) +#define LESENSE_CH2OUT_PA2 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x2) +#define LESENSE_CH2OUT_PA3 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x3) +#define LESENSE_CH2OUT_PA4 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x4) +#define LESENSE_CH2OUT_PA5 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x5) +#define LESENSE_CH2OUT_PA6 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x6) +#define LESENSE_CH2OUT_PA7 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x7) +#define LESENSE_CH2OUT_PA8 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x8) +#define LESENSE_CH2OUT_PA9 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0x9) +#define LESENSE_CH2OUT_PA10 SILABS_DBUS_LESENSE_CH2OUT(0x0, 0xa) +#define LESENSE_CH2OUT_PB0 SILABS_DBUS_LESENSE_CH2OUT(0x1, 0x0) +#define LESENSE_CH2OUT_PB1 SILABS_DBUS_LESENSE_CH2OUT(0x1, 0x1) +#define LESENSE_CH2OUT_PB2 SILABS_DBUS_LESENSE_CH2OUT(0x1, 0x2) +#define LESENSE_CH2OUT_PB3 SILABS_DBUS_LESENSE_CH2OUT(0x1, 0x3) +#define LESENSE_CH2OUT_PB4 SILABS_DBUS_LESENSE_CH2OUT(0x1, 0x4) +#define LESENSE_CH2OUT_PB5 SILABS_DBUS_LESENSE_CH2OUT(0x1, 0x5) +#define LESENSE_CH2OUT_PB6 SILABS_DBUS_LESENSE_CH2OUT(0x1, 0x6) +#define LESENSE_CH3OUT_PA0 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x0) +#define LESENSE_CH3OUT_PA1 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x1) +#define LESENSE_CH3OUT_PA2 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x2) +#define LESENSE_CH3OUT_PA3 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x3) +#define LESENSE_CH3OUT_PA4 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x4) +#define LESENSE_CH3OUT_PA5 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x5) +#define LESENSE_CH3OUT_PA6 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x6) +#define LESENSE_CH3OUT_PA7 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x7) +#define LESENSE_CH3OUT_PA8 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x8) +#define LESENSE_CH3OUT_PA9 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0x9) +#define LESENSE_CH3OUT_PA10 SILABS_DBUS_LESENSE_CH3OUT(0x0, 0xa) +#define LESENSE_CH3OUT_PB0 SILABS_DBUS_LESENSE_CH3OUT(0x1, 0x0) +#define LESENSE_CH3OUT_PB1 SILABS_DBUS_LESENSE_CH3OUT(0x1, 0x1) +#define LESENSE_CH3OUT_PB2 SILABS_DBUS_LESENSE_CH3OUT(0x1, 0x2) +#define LESENSE_CH3OUT_PB3 SILABS_DBUS_LESENSE_CH3OUT(0x1, 0x3) +#define LESENSE_CH3OUT_PB4 SILABS_DBUS_LESENSE_CH3OUT(0x1, 0x4) +#define LESENSE_CH3OUT_PB5 SILABS_DBUS_LESENSE_CH3OUT(0x1, 0x5) +#define LESENSE_CH3OUT_PB6 SILABS_DBUS_LESENSE_CH3OUT(0x1, 0x6) +#define LESENSE_CH4OUT_PA0 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x0) +#define LESENSE_CH4OUT_PA1 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x1) +#define LESENSE_CH4OUT_PA2 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x2) +#define LESENSE_CH4OUT_PA3 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x3) +#define LESENSE_CH4OUT_PA4 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x4) +#define LESENSE_CH4OUT_PA5 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x5) +#define LESENSE_CH4OUT_PA6 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x6) +#define LESENSE_CH4OUT_PA7 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x7) +#define LESENSE_CH4OUT_PA8 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x8) +#define LESENSE_CH4OUT_PA9 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0x9) +#define LESENSE_CH4OUT_PA10 SILABS_DBUS_LESENSE_CH4OUT(0x0, 0xa) +#define LESENSE_CH4OUT_PB0 SILABS_DBUS_LESENSE_CH4OUT(0x1, 0x0) +#define LESENSE_CH4OUT_PB1 SILABS_DBUS_LESENSE_CH4OUT(0x1, 0x1) +#define LESENSE_CH4OUT_PB2 SILABS_DBUS_LESENSE_CH4OUT(0x1, 0x2) +#define LESENSE_CH4OUT_PB3 SILABS_DBUS_LESENSE_CH4OUT(0x1, 0x3) +#define LESENSE_CH4OUT_PB4 SILABS_DBUS_LESENSE_CH4OUT(0x1, 0x4) +#define LESENSE_CH4OUT_PB5 SILABS_DBUS_LESENSE_CH4OUT(0x1, 0x5) +#define LESENSE_CH4OUT_PB6 SILABS_DBUS_LESENSE_CH4OUT(0x1, 0x6) +#define LESENSE_CH5OUT_PA0 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x0) +#define LESENSE_CH5OUT_PA1 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x1) +#define LESENSE_CH5OUT_PA2 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x2) +#define LESENSE_CH5OUT_PA3 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x3) +#define LESENSE_CH5OUT_PA4 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x4) +#define LESENSE_CH5OUT_PA5 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x5) +#define LESENSE_CH5OUT_PA6 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x6) +#define LESENSE_CH5OUT_PA7 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x7) +#define LESENSE_CH5OUT_PA8 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x8) +#define LESENSE_CH5OUT_PA9 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0x9) +#define LESENSE_CH5OUT_PA10 SILABS_DBUS_LESENSE_CH5OUT(0x0, 0xa) +#define LESENSE_CH5OUT_PB0 SILABS_DBUS_LESENSE_CH5OUT(0x1, 0x0) +#define LESENSE_CH5OUT_PB1 SILABS_DBUS_LESENSE_CH5OUT(0x1, 0x1) +#define LESENSE_CH5OUT_PB2 SILABS_DBUS_LESENSE_CH5OUT(0x1, 0x2) +#define LESENSE_CH5OUT_PB3 SILABS_DBUS_LESENSE_CH5OUT(0x1, 0x3) +#define LESENSE_CH5OUT_PB4 SILABS_DBUS_LESENSE_CH5OUT(0x1, 0x4) +#define LESENSE_CH5OUT_PB5 SILABS_DBUS_LESENSE_CH5OUT(0x1, 0x5) +#define LESENSE_CH5OUT_PB6 SILABS_DBUS_LESENSE_CH5OUT(0x1, 0x6) +#define LESENSE_CH6OUT_PA0 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x0) +#define LESENSE_CH6OUT_PA1 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x1) +#define LESENSE_CH6OUT_PA2 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x2) +#define LESENSE_CH6OUT_PA3 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x3) +#define LESENSE_CH6OUT_PA4 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x4) +#define LESENSE_CH6OUT_PA5 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x5) +#define LESENSE_CH6OUT_PA6 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x6) +#define LESENSE_CH6OUT_PA7 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x7) +#define LESENSE_CH6OUT_PA8 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x8) +#define LESENSE_CH6OUT_PA9 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0x9) +#define LESENSE_CH6OUT_PA10 SILABS_DBUS_LESENSE_CH6OUT(0x0, 0xa) +#define LESENSE_CH6OUT_PB0 SILABS_DBUS_LESENSE_CH6OUT(0x1, 0x0) +#define LESENSE_CH6OUT_PB1 SILABS_DBUS_LESENSE_CH6OUT(0x1, 0x1) +#define LESENSE_CH6OUT_PB2 SILABS_DBUS_LESENSE_CH6OUT(0x1, 0x2) +#define LESENSE_CH6OUT_PB3 SILABS_DBUS_LESENSE_CH6OUT(0x1, 0x3) +#define LESENSE_CH6OUT_PB4 SILABS_DBUS_LESENSE_CH6OUT(0x1, 0x4) +#define LESENSE_CH6OUT_PB5 SILABS_DBUS_LESENSE_CH6OUT(0x1, 0x5) +#define LESENSE_CH6OUT_PB6 SILABS_DBUS_LESENSE_CH6OUT(0x1, 0x6) +#define LESENSE_CH7OUT_PA0 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x0) +#define LESENSE_CH7OUT_PA1 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x1) +#define LESENSE_CH7OUT_PA2 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x2) +#define LESENSE_CH7OUT_PA3 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x3) +#define LESENSE_CH7OUT_PA4 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x4) +#define LESENSE_CH7OUT_PA5 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x5) +#define LESENSE_CH7OUT_PA6 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x6) +#define LESENSE_CH7OUT_PA7 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x7) +#define LESENSE_CH7OUT_PA8 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x8) +#define LESENSE_CH7OUT_PA9 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0x9) +#define LESENSE_CH7OUT_PA10 SILABS_DBUS_LESENSE_CH7OUT(0x0, 0xa) +#define LESENSE_CH7OUT_PB0 SILABS_DBUS_LESENSE_CH7OUT(0x1, 0x0) +#define LESENSE_CH7OUT_PB1 SILABS_DBUS_LESENSE_CH7OUT(0x1, 0x1) +#define LESENSE_CH7OUT_PB2 SILABS_DBUS_LESENSE_CH7OUT(0x1, 0x2) +#define LESENSE_CH7OUT_PB3 SILABS_DBUS_LESENSE_CH7OUT(0x1, 0x3) +#define LESENSE_CH7OUT_PB4 SILABS_DBUS_LESENSE_CH7OUT(0x1, 0x4) +#define LESENSE_CH7OUT_PB5 SILABS_DBUS_LESENSE_CH7OUT(0x1, 0x5) +#define LESENSE_CH7OUT_PB6 SILABS_DBUS_LESENSE_CH7OUT(0x1, 0x6) +#define LESENSE_CH8OUT_PA0 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x0) +#define LESENSE_CH8OUT_PA1 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x1) +#define LESENSE_CH8OUT_PA2 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x2) +#define LESENSE_CH8OUT_PA3 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x3) +#define LESENSE_CH8OUT_PA4 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x4) +#define LESENSE_CH8OUT_PA5 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x5) +#define LESENSE_CH8OUT_PA6 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x6) +#define LESENSE_CH8OUT_PA7 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x7) +#define LESENSE_CH8OUT_PA8 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x8) +#define LESENSE_CH8OUT_PA9 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0x9) +#define LESENSE_CH8OUT_PA10 SILABS_DBUS_LESENSE_CH8OUT(0x0, 0xa) +#define LESENSE_CH8OUT_PB0 SILABS_DBUS_LESENSE_CH8OUT(0x1, 0x0) +#define LESENSE_CH8OUT_PB1 SILABS_DBUS_LESENSE_CH8OUT(0x1, 0x1) +#define LESENSE_CH8OUT_PB2 SILABS_DBUS_LESENSE_CH8OUT(0x1, 0x2) +#define LESENSE_CH8OUT_PB3 SILABS_DBUS_LESENSE_CH8OUT(0x1, 0x3) +#define LESENSE_CH8OUT_PB4 SILABS_DBUS_LESENSE_CH8OUT(0x1, 0x4) +#define LESENSE_CH8OUT_PB5 SILABS_DBUS_LESENSE_CH8OUT(0x1, 0x5) +#define LESENSE_CH8OUT_PB6 SILABS_DBUS_LESENSE_CH8OUT(0x1, 0x6) +#define LESENSE_CH9OUT_PA0 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x0) +#define LESENSE_CH9OUT_PA1 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x1) +#define LESENSE_CH9OUT_PA2 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x2) +#define LESENSE_CH9OUT_PA3 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x3) +#define LESENSE_CH9OUT_PA4 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x4) +#define LESENSE_CH9OUT_PA5 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x5) +#define LESENSE_CH9OUT_PA6 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x6) +#define LESENSE_CH9OUT_PA7 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x7) +#define LESENSE_CH9OUT_PA8 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x8) +#define LESENSE_CH9OUT_PA9 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0x9) +#define LESENSE_CH9OUT_PA10 SILABS_DBUS_LESENSE_CH9OUT(0x0, 0xa) +#define LESENSE_CH9OUT_PB0 SILABS_DBUS_LESENSE_CH9OUT(0x1, 0x0) +#define LESENSE_CH9OUT_PB1 SILABS_DBUS_LESENSE_CH9OUT(0x1, 0x1) +#define LESENSE_CH9OUT_PB2 SILABS_DBUS_LESENSE_CH9OUT(0x1, 0x2) +#define LESENSE_CH9OUT_PB3 SILABS_DBUS_LESENSE_CH9OUT(0x1, 0x3) +#define LESENSE_CH9OUT_PB4 SILABS_DBUS_LESENSE_CH9OUT(0x1, 0x4) +#define LESENSE_CH9OUT_PB5 SILABS_DBUS_LESENSE_CH9OUT(0x1, 0x5) +#define LESENSE_CH9OUT_PB6 SILABS_DBUS_LESENSE_CH9OUT(0x1, 0x6) +#define LESENSE_CH10OUT_PA0 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x0) +#define LESENSE_CH10OUT_PA1 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x1) +#define LESENSE_CH10OUT_PA2 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x2) +#define LESENSE_CH10OUT_PA3 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x3) +#define LESENSE_CH10OUT_PA4 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x4) +#define LESENSE_CH10OUT_PA5 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x5) +#define LESENSE_CH10OUT_PA6 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x6) +#define LESENSE_CH10OUT_PA7 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x7) +#define LESENSE_CH10OUT_PA8 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x8) +#define LESENSE_CH10OUT_PA9 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0x9) +#define LESENSE_CH10OUT_PA10 SILABS_DBUS_LESENSE_CH10OUT(0x0, 0xa) +#define LESENSE_CH10OUT_PB0 SILABS_DBUS_LESENSE_CH10OUT(0x1, 0x0) +#define LESENSE_CH10OUT_PB1 SILABS_DBUS_LESENSE_CH10OUT(0x1, 0x1) +#define LESENSE_CH10OUT_PB2 SILABS_DBUS_LESENSE_CH10OUT(0x1, 0x2) +#define LESENSE_CH10OUT_PB3 SILABS_DBUS_LESENSE_CH10OUT(0x1, 0x3) +#define LESENSE_CH10OUT_PB4 SILABS_DBUS_LESENSE_CH10OUT(0x1, 0x4) +#define LESENSE_CH10OUT_PB5 SILABS_DBUS_LESENSE_CH10OUT(0x1, 0x5) +#define LESENSE_CH10OUT_PB6 SILABS_DBUS_LESENSE_CH10OUT(0x1, 0x6) +#define LESENSE_CH11OUT_PA0 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x0) +#define LESENSE_CH11OUT_PA1 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x1) +#define LESENSE_CH11OUT_PA2 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x2) +#define LESENSE_CH11OUT_PA3 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x3) +#define LESENSE_CH11OUT_PA4 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x4) +#define LESENSE_CH11OUT_PA5 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x5) +#define LESENSE_CH11OUT_PA6 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x6) +#define LESENSE_CH11OUT_PA7 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x7) +#define LESENSE_CH11OUT_PA8 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x8) +#define LESENSE_CH11OUT_PA9 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0x9) +#define LESENSE_CH11OUT_PA10 SILABS_DBUS_LESENSE_CH11OUT(0x0, 0xa) +#define LESENSE_CH11OUT_PB0 SILABS_DBUS_LESENSE_CH11OUT(0x1, 0x0) +#define LESENSE_CH11OUT_PB1 SILABS_DBUS_LESENSE_CH11OUT(0x1, 0x1) +#define LESENSE_CH11OUT_PB2 SILABS_DBUS_LESENSE_CH11OUT(0x1, 0x2) +#define LESENSE_CH11OUT_PB3 SILABS_DBUS_LESENSE_CH11OUT(0x1, 0x3) +#define LESENSE_CH11OUT_PB4 SILABS_DBUS_LESENSE_CH11OUT(0x1, 0x4) +#define LESENSE_CH11OUT_PB5 SILABS_DBUS_LESENSE_CH11OUT(0x1, 0x5) +#define LESENSE_CH11OUT_PB6 SILABS_DBUS_LESENSE_CH11OUT(0x1, 0x6) +#define LESENSE_CH12OUT_PA0 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x0) +#define LESENSE_CH12OUT_PA1 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x1) +#define LESENSE_CH12OUT_PA2 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x2) +#define LESENSE_CH12OUT_PA3 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x3) +#define LESENSE_CH12OUT_PA4 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x4) +#define LESENSE_CH12OUT_PA5 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x5) +#define LESENSE_CH12OUT_PA6 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x6) +#define LESENSE_CH12OUT_PA7 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x7) +#define LESENSE_CH12OUT_PA8 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x8) +#define LESENSE_CH12OUT_PA9 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0x9) +#define LESENSE_CH12OUT_PA10 SILABS_DBUS_LESENSE_CH12OUT(0x0, 0xa) +#define LESENSE_CH12OUT_PB0 SILABS_DBUS_LESENSE_CH12OUT(0x1, 0x0) +#define LESENSE_CH12OUT_PB1 SILABS_DBUS_LESENSE_CH12OUT(0x1, 0x1) +#define LESENSE_CH12OUT_PB2 SILABS_DBUS_LESENSE_CH12OUT(0x1, 0x2) +#define LESENSE_CH12OUT_PB3 SILABS_DBUS_LESENSE_CH12OUT(0x1, 0x3) +#define LESENSE_CH12OUT_PB4 SILABS_DBUS_LESENSE_CH12OUT(0x1, 0x4) +#define LESENSE_CH12OUT_PB5 SILABS_DBUS_LESENSE_CH12OUT(0x1, 0x5) +#define LESENSE_CH12OUT_PB6 SILABS_DBUS_LESENSE_CH12OUT(0x1, 0x6) +#define LESENSE_CH13OUT_PA0 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x0) +#define LESENSE_CH13OUT_PA1 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x1) +#define LESENSE_CH13OUT_PA2 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x2) +#define LESENSE_CH13OUT_PA3 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x3) +#define LESENSE_CH13OUT_PA4 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x4) +#define LESENSE_CH13OUT_PA5 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x5) +#define LESENSE_CH13OUT_PA6 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x6) +#define LESENSE_CH13OUT_PA7 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x7) +#define LESENSE_CH13OUT_PA8 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x8) +#define LESENSE_CH13OUT_PA9 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0x9) +#define LESENSE_CH13OUT_PA10 SILABS_DBUS_LESENSE_CH13OUT(0x0, 0xa) +#define LESENSE_CH13OUT_PB0 SILABS_DBUS_LESENSE_CH13OUT(0x1, 0x0) +#define LESENSE_CH13OUT_PB1 SILABS_DBUS_LESENSE_CH13OUT(0x1, 0x1) +#define LESENSE_CH13OUT_PB2 SILABS_DBUS_LESENSE_CH13OUT(0x1, 0x2) +#define LESENSE_CH13OUT_PB3 SILABS_DBUS_LESENSE_CH13OUT(0x1, 0x3) +#define LESENSE_CH13OUT_PB4 SILABS_DBUS_LESENSE_CH13OUT(0x1, 0x4) +#define LESENSE_CH13OUT_PB5 SILABS_DBUS_LESENSE_CH13OUT(0x1, 0x5) +#define LESENSE_CH13OUT_PB6 SILABS_DBUS_LESENSE_CH13OUT(0x1, 0x6) +#define LESENSE_CH14OUT_PA0 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x0) +#define LESENSE_CH14OUT_PA1 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x1) +#define LESENSE_CH14OUT_PA2 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x2) +#define LESENSE_CH14OUT_PA3 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x3) +#define LESENSE_CH14OUT_PA4 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x4) +#define LESENSE_CH14OUT_PA5 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x5) +#define LESENSE_CH14OUT_PA6 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x6) +#define LESENSE_CH14OUT_PA7 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x7) +#define LESENSE_CH14OUT_PA8 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x8) +#define LESENSE_CH14OUT_PA9 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0x9) +#define LESENSE_CH14OUT_PA10 SILABS_DBUS_LESENSE_CH14OUT(0x0, 0xa) +#define LESENSE_CH14OUT_PB0 SILABS_DBUS_LESENSE_CH14OUT(0x1, 0x0) +#define LESENSE_CH14OUT_PB1 SILABS_DBUS_LESENSE_CH14OUT(0x1, 0x1) +#define LESENSE_CH14OUT_PB2 SILABS_DBUS_LESENSE_CH14OUT(0x1, 0x2) +#define LESENSE_CH14OUT_PB3 SILABS_DBUS_LESENSE_CH14OUT(0x1, 0x3) +#define LESENSE_CH14OUT_PB4 SILABS_DBUS_LESENSE_CH14OUT(0x1, 0x4) +#define LESENSE_CH14OUT_PB5 SILABS_DBUS_LESENSE_CH14OUT(0x1, 0x5) +#define LESENSE_CH14OUT_PB6 SILABS_DBUS_LESENSE_CH14OUT(0x1, 0x6) +#define LESENSE_CH15OUT_PA0 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x0) +#define LESENSE_CH15OUT_PA1 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x1) +#define LESENSE_CH15OUT_PA2 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x2) +#define LESENSE_CH15OUT_PA3 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x3) +#define LESENSE_CH15OUT_PA4 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x4) +#define LESENSE_CH15OUT_PA5 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x5) +#define LESENSE_CH15OUT_PA6 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x6) +#define LESENSE_CH15OUT_PA7 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x7) +#define LESENSE_CH15OUT_PA8 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x8) +#define LESENSE_CH15OUT_PA9 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0x9) +#define LESENSE_CH15OUT_PA10 SILABS_DBUS_LESENSE_CH15OUT(0x0, 0xa) +#define LESENSE_CH15OUT_PB0 SILABS_DBUS_LESENSE_CH15OUT(0x1, 0x0) +#define LESENSE_CH15OUT_PB1 SILABS_DBUS_LESENSE_CH15OUT(0x1, 0x1) +#define LESENSE_CH15OUT_PB2 SILABS_DBUS_LESENSE_CH15OUT(0x1, 0x2) +#define LESENSE_CH15OUT_PB3 SILABS_DBUS_LESENSE_CH15OUT(0x1, 0x3) +#define LESENSE_CH15OUT_PB4 SILABS_DBUS_LESENSE_CH15OUT(0x1, 0x4) +#define LESENSE_CH15OUT_PB5 SILABS_DBUS_LESENSE_CH15OUT(0x1, 0x5) +#define LESENSE_CH15OUT_PB6 SILABS_DBUS_LESENSE_CH15OUT(0x1, 0x6) + +#define LETIMER0_OUT0_PA0 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x0) +#define LETIMER0_OUT0_PA1 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x1) +#define LETIMER0_OUT0_PA2 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x2) +#define LETIMER0_OUT0_PA3 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x3) +#define LETIMER0_OUT0_PA4 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x4) +#define LETIMER0_OUT0_PA5 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x5) +#define LETIMER0_OUT0_PA6 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x6) +#define LETIMER0_OUT0_PA7 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x7) +#define LETIMER0_OUT0_PA8 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x8) +#define LETIMER0_OUT0_PA9 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x9) +#define LETIMER0_OUT0_PA10 SILABS_DBUS_LETIMER0_OUT0(0x0, 0xa) +#define LETIMER0_OUT0_PB0 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x0) +#define LETIMER0_OUT0_PB1 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x1) +#define LETIMER0_OUT0_PB2 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x2) +#define LETIMER0_OUT0_PB3 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x3) +#define LETIMER0_OUT0_PB4 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x4) +#define LETIMER0_OUT0_PB5 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x5) +#define LETIMER0_OUT0_PB6 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x6) +#define LETIMER0_OUT1_PA0 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x0) +#define LETIMER0_OUT1_PA1 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x1) +#define LETIMER0_OUT1_PA2 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x2) +#define LETIMER0_OUT1_PA3 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x3) +#define LETIMER0_OUT1_PA4 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x4) +#define LETIMER0_OUT1_PA5 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x5) +#define LETIMER0_OUT1_PA6 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x6) +#define LETIMER0_OUT1_PA7 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x7) +#define LETIMER0_OUT1_PA8 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x8) +#define LETIMER0_OUT1_PA9 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x9) +#define LETIMER0_OUT1_PA10 SILABS_DBUS_LETIMER0_OUT1(0x0, 0xa) +#define LETIMER0_OUT1_PB0 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x0) +#define LETIMER0_OUT1_PB1 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x1) +#define LETIMER0_OUT1_PB2 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x2) +#define LETIMER0_OUT1_PB3 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x3) +#define LETIMER0_OUT1_PB4 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x4) +#define LETIMER0_OUT1_PB5 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x5) +#define LETIMER0_OUT1_PB6 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x6) + +#define MODEM_ANT0_PA0 SILABS_DBUS_MODEM_ANT0(0x0, 0x0) +#define MODEM_ANT0_PA1 SILABS_DBUS_MODEM_ANT0(0x0, 0x1) +#define MODEM_ANT0_PA2 SILABS_DBUS_MODEM_ANT0(0x0, 0x2) +#define MODEM_ANT0_PA3 SILABS_DBUS_MODEM_ANT0(0x0, 0x3) +#define MODEM_ANT0_PA4 SILABS_DBUS_MODEM_ANT0(0x0, 0x4) +#define MODEM_ANT0_PA5 SILABS_DBUS_MODEM_ANT0(0x0, 0x5) +#define MODEM_ANT0_PA6 SILABS_DBUS_MODEM_ANT0(0x0, 0x6) +#define MODEM_ANT0_PA7 SILABS_DBUS_MODEM_ANT0(0x0, 0x7) +#define MODEM_ANT0_PA8 SILABS_DBUS_MODEM_ANT0(0x0, 0x8) +#define MODEM_ANT0_PA9 SILABS_DBUS_MODEM_ANT0(0x0, 0x9) +#define MODEM_ANT0_PA10 SILABS_DBUS_MODEM_ANT0(0x0, 0xa) +#define MODEM_ANT0_PB0 SILABS_DBUS_MODEM_ANT0(0x1, 0x0) +#define MODEM_ANT0_PB1 SILABS_DBUS_MODEM_ANT0(0x1, 0x1) +#define MODEM_ANT0_PB2 SILABS_DBUS_MODEM_ANT0(0x1, 0x2) +#define MODEM_ANT0_PB3 SILABS_DBUS_MODEM_ANT0(0x1, 0x3) +#define MODEM_ANT0_PB4 SILABS_DBUS_MODEM_ANT0(0x1, 0x4) +#define MODEM_ANT0_PB5 SILABS_DBUS_MODEM_ANT0(0x1, 0x5) +#define MODEM_ANT0_PB6 SILABS_DBUS_MODEM_ANT0(0x1, 0x6) +#define MODEM_ANT0_PC0 SILABS_DBUS_MODEM_ANT0(0x2, 0x0) +#define MODEM_ANT0_PC1 SILABS_DBUS_MODEM_ANT0(0x2, 0x1) +#define MODEM_ANT0_PC2 SILABS_DBUS_MODEM_ANT0(0x2, 0x2) +#define MODEM_ANT0_PC3 SILABS_DBUS_MODEM_ANT0(0x2, 0x3) +#define MODEM_ANT0_PC4 SILABS_DBUS_MODEM_ANT0(0x2, 0x4) +#define MODEM_ANT0_PC5 SILABS_DBUS_MODEM_ANT0(0x2, 0x5) +#define MODEM_ANT0_PC6 SILABS_DBUS_MODEM_ANT0(0x2, 0x6) +#define MODEM_ANT0_PC7 SILABS_DBUS_MODEM_ANT0(0x2, 0x7) +#define MODEM_ANT0_PC8 SILABS_DBUS_MODEM_ANT0(0x2, 0x8) +#define MODEM_ANT0_PC9 SILABS_DBUS_MODEM_ANT0(0x2, 0x9) +#define MODEM_ANT0_PD0 SILABS_DBUS_MODEM_ANT0(0x3, 0x0) +#define MODEM_ANT0_PD1 SILABS_DBUS_MODEM_ANT0(0x3, 0x1) +#define MODEM_ANT0_PD2 SILABS_DBUS_MODEM_ANT0(0x3, 0x2) +#define MODEM_ANT0_PD3 SILABS_DBUS_MODEM_ANT0(0x3, 0x3) +#define MODEM_ANT0_PD4 SILABS_DBUS_MODEM_ANT0(0x3, 0x4) +#define MODEM_ANT0_PD5 SILABS_DBUS_MODEM_ANT0(0x3, 0x5) +#define MODEM_ANT1_PA0 SILABS_DBUS_MODEM_ANT1(0x0, 0x0) +#define MODEM_ANT1_PA1 SILABS_DBUS_MODEM_ANT1(0x0, 0x1) +#define MODEM_ANT1_PA2 SILABS_DBUS_MODEM_ANT1(0x0, 0x2) +#define MODEM_ANT1_PA3 SILABS_DBUS_MODEM_ANT1(0x0, 0x3) +#define MODEM_ANT1_PA4 SILABS_DBUS_MODEM_ANT1(0x0, 0x4) +#define MODEM_ANT1_PA5 SILABS_DBUS_MODEM_ANT1(0x0, 0x5) +#define MODEM_ANT1_PA6 SILABS_DBUS_MODEM_ANT1(0x0, 0x6) +#define MODEM_ANT1_PA7 SILABS_DBUS_MODEM_ANT1(0x0, 0x7) +#define MODEM_ANT1_PA8 SILABS_DBUS_MODEM_ANT1(0x0, 0x8) +#define MODEM_ANT1_PA9 SILABS_DBUS_MODEM_ANT1(0x0, 0x9) +#define MODEM_ANT1_PA10 SILABS_DBUS_MODEM_ANT1(0x0, 0xa) +#define MODEM_ANT1_PB0 SILABS_DBUS_MODEM_ANT1(0x1, 0x0) +#define MODEM_ANT1_PB1 SILABS_DBUS_MODEM_ANT1(0x1, 0x1) +#define MODEM_ANT1_PB2 SILABS_DBUS_MODEM_ANT1(0x1, 0x2) +#define MODEM_ANT1_PB3 SILABS_DBUS_MODEM_ANT1(0x1, 0x3) +#define MODEM_ANT1_PB4 SILABS_DBUS_MODEM_ANT1(0x1, 0x4) +#define MODEM_ANT1_PB5 SILABS_DBUS_MODEM_ANT1(0x1, 0x5) +#define MODEM_ANT1_PB6 SILABS_DBUS_MODEM_ANT1(0x1, 0x6) +#define MODEM_ANT1_PC0 SILABS_DBUS_MODEM_ANT1(0x2, 0x0) +#define MODEM_ANT1_PC1 SILABS_DBUS_MODEM_ANT1(0x2, 0x1) +#define MODEM_ANT1_PC2 SILABS_DBUS_MODEM_ANT1(0x2, 0x2) +#define MODEM_ANT1_PC3 SILABS_DBUS_MODEM_ANT1(0x2, 0x3) +#define MODEM_ANT1_PC4 SILABS_DBUS_MODEM_ANT1(0x2, 0x4) +#define MODEM_ANT1_PC5 SILABS_DBUS_MODEM_ANT1(0x2, 0x5) +#define MODEM_ANT1_PC6 SILABS_DBUS_MODEM_ANT1(0x2, 0x6) +#define MODEM_ANT1_PC7 SILABS_DBUS_MODEM_ANT1(0x2, 0x7) +#define MODEM_ANT1_PC8 SILABS_DBUS_MODEM_ANT1(0x2, 0x8) +#define MODEM_ANT1_PC9 SILABS_DBUS_MODEM_ANT1(0x2, 0x9) +#define MODEM_ANT1_PD0 SILABS_DBUS_MODEM_ANT1(0x3, 0x0) +#define MODEM_ANT1_PD1 SILABS_DBUS_MODEM_ANT1(0x3, 0x1) +#define MODEM_ANT1_PD2 SILABS_DBUS_MODEM_ANT1(0x3, 0x2) +#define MODEM_ANT1_PD3 SILABS_DBUS_MODEM_ANT1(0x3, 0x3) +#define MODEM_ANT1_PD4 SILABS_DBUS_MODEM_ANT1(0x3, 0x4) +#define MODEM_ANT1_PD5 SILABS_DBUS_MODEM_ANT1(0x3, 0x5) +#define MODEM_ANTROLLOVER_PC0 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x0) +#define MODEM_ANTROLLOVER_PC1 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x1) +#define MODEM_ANTROLLOVER_PC2 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x2) +#define MODEM_ANTROLLOVER_PC3 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x3) +#define MODEM_ANTROLLOVER_PC4 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x4) +#define MODEM_ANTROLLOVER_PC5 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x5) +#define MODEM_ANTROLLOVER_PC6 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x6) +#define MODEM_ANTROLLOVER_PC7 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x7) +#define MODEM_ANTROLLOVER_PC8 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x8) +#define MODEM_ANTROLLOVER_PC9 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x9) +#define MODEM_ANTROLLOVER_PD0 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x0) +#define MODEM_ANTROLLOVER_PD1 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x1) +#define MODEM_ANTROLLOVER_PD2 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x2) +#define MODEM_ANTROLLOVER_PD3 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x3) +#define MODEM_ANTROLLOVER_PD4 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x4) +#define MODEM_ANTROLLOVER_PD5 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x5) +#define MODEM_ANTRR0_PC0 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x0) +#define MODEM_ANTRR0_PC1 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x1) +#define MODEM_ANTRR0_PC2 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x2) +#define MODEM_ANTRR0_PC3 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x3) +#define MODEM_ANTRR0_PC4 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x4) +#define MODEM_ANTRR0_PC5 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x5) +#define MODEM_ANTRR0_PC6 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x6) +#define MODEM_ANTRR0_PC7 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x7) +#define MODEM_ANTRR0_PC8 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x8) +#define MODEM_ANTRR0_PC9 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x9) +#define MODEM_ANTRR0_PD0 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x0) +#define MODEM_ANTRR0_PD1 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x1) +#define MODEM_ANTRR0_PD2 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x2) +#define MODEM_ANTRR0_PD3 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x3) +#define MODEM_ANTRR0_PD4 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x4) +#define MODEM_ANTRR0_PD5 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x5) +#define MODEM_ANTRR1_PC0 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x0) +#define MODEM_ANTRR1_PC1 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x1) +#define MODEM_ANTRR1_PC2 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x2) +#define MODEM_ANTRR1_PC3 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x3) +#define MODEM_ANTRR1_PC4 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x4) +#define MODEM_ANTRR1_PC5 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x5) +#define MODEM_ANTRR1_PC6 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x6) +#define MODEM_ANTRR1_PC7 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x7) +#define MODEM_ANTRR1_PC8 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x8) +#define MODEM_ANTRR1_PC9 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x9) +#define MODEM_ANTRR1_PD0 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x0) +#define MODEM_ANTRR1_PD1 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x1) +#define MODEM_ANTRR1_PD2 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x2) +#define MODEM_ANTRR1_PD3 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x3) +#define MODEM_ANTRR1_PD4 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x4) +#define MODEM_ANTRR1_PD5 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x5) +#define MODEM_ANTRR2_PC0 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x0) +#define MODEM_ANTRR2_PC1 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x1) +#define MODEM_ANTRR2_PC2 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x2) +#define MODEM_ANTRR2_PC3 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x3) +#define MODEM_ANTRR2_PC4 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x4) +#define MODEM_ANTRR2_PC5 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x5) +#define MODEM_ANTRR2_PC6 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x6) +#define MODEM_ANTRR2_PC7 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x7) +#define MODEM_ANTRR2_PC8 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x8) +#define MODEM_ANTRR2_PC9 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x9) +#define MODEM_ANTRR2_PD0 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x0) +#define MODEM_ANTRR2_PD1 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x1) +#define MODEM_ANTRR2_PD2 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x2) +#define MODEM_ANTRR2_PD3 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x3) +#define MODEM_ANTRR2_PD4 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x4) +#define MODEM_ANTRR2_PD5 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x5) +#define MODEM_ANTRR3_PC0 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x0) +#define MODEM_ANTRR3_PC1 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x1) +#define MODEM_ANTRR3_PC2 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x2) +#define MODEM_ANTRR3_PC3 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x3) +#define MODEM_ANTRR3_PC4 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x4) +#define MODEM_ANTRR3_PC5 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x5) +#define MODEM_ANTRR3_PC6 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x6) +#define MODEM_ANTRR3_PC7 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x7) +#define MODEM_ANTRR3_PC8 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x8) +#define MODEM_ANTRR3_PC9 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x9) +#define MODEM_ANTRR3_PD0 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x0) +#define MODEM_ANTRR3_PD1 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x1) +#define MODEM_ANTRR3_PD2 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x2) +#define MODEM_ANTRR3_PD3 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x3) +#define MODEM_ANTRR3_PD4 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x4) +#define MODEM_ANTRR3_PD5 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x5) +#define MODEM_ANTRR4_PC0 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x0) +#define MODEM_ANTRR4_PC1 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x1) +#define MODEM_ANTRR4_PC2 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x2) +#define MODEM_ANTRR4_PC3 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x3) +#define MODEM_ANTRR4_PC4 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x4) +#define MODEM_ANTRR4_PC5 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x5) +#define MODEM_ANTRR4_PC6 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x6) +#define MODEM_ANTRR4_PC7 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x7) +#define MODEM_ANTRR4_PC8 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x8) +#define MODEM_ANTRR4_PC9 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x9) +#define MODEM_ANTRR4_PD0 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x0) +#define MODEM_ANTRR4_PD1 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x1) +#define MODEM_ANTRR4_PD2 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x2) +#define MODEM_ANTRR4_PD3 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x3) +#define MODEM_ANTRR4_PD4 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x4) +#define MODEM_ANTRR4_PD5 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x5) +#define MODEM_ANTRR5_PC0 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x0) +#define MODEM_ANTRR5_PC1 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x1) +#define MODEM_ANTRR5_PC2 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x2) +#define MODEM_ANTRR5_PC3 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x3) +#define MODEM_ANTRR5_PC4 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x4) +#define MODEM_ANTRR5_PC5 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x5) +#define MODEM_ANTRR5_PC6 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x6) +#define MODEM_ANTRR5_PC7 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x7) +#define MODEM_ANTRR5_PC8 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x8) +#define MODEM_ANTRR5_PC9 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x9) +#define MODEM_ANTRR5_PD0 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x0) +#define MODEM_ANTRR5_PD1 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x1) +#define MODEM_ANTRR5_PD2 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x2) +#define MODEM_ANTRR5_PD3 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x3) +#define MODEM_ANTRR5_PD4 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x4) +#define MODEM_ANTRR5_PD5 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x5) +#define MODEM_ANTSWEN_PC0 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x0) +#define MODEM_ANTSWEN_PC1 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x1) +#define MODEM_ANTSWEN_PC2 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x2) +#define MODEM_ANTSWEN_PC3 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x3) +#define MODEM_ANTSWEN_PC4 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x4) +#define MODEM_ANTSWEN_PC5 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x5) +#define MODEM_ANTSWEN_PC6 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x6) +#define MODEM_ANTSWEN_PC7 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x7) +#define MODEM_ANTSWEN_PC8 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x8) +#define MODEM_ANTSWEN_PC9 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x9) +#define MODEM_ANTSWEN_PD0 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x0) +#define MODEM_ANTSWEN_PD1 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x1) +#define MODEM_ANTSWEN_PD2 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x2) +#define MODEM_ANTSWEN_PD3 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x3) +#define MODEM_ANTSWEN_PD4 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x4) +#define MODEM_ANTSWEN_PD5 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x5) +#define MODEM_ANTSWUS_PC0 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x0) +#define MODEM_ANTSWUS_PC1 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x1) +#define MODEM_ANTSWUS_PC2 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x2) +#define MODEM_ANTSWUS_PC3 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x3) +#define MODEM_ANTSWUS_PC4 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x4) +#define MODEM_ANTSWUS_PC5 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x5) +#define MODEM_ANTSWUS_PC6 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x6) +#define MODEM_ANTSWUS_PC7 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x7) +#define MODEM_ANTSWUS_PC8 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x8) +#define MODEM_ANTSWUS_PC9 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x9) +#define MODEM_ANTSWUS_PD0 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x0) +#define MODEM_ANTSWUS_PD1 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x1) +#define MODEM_ANTSWUS_PD2 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x2) +#define MODEM_ANTSWUS_PD3 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x3) +#define MODEM_ANTSWUS_PD4 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x4) +#define MODEM_ANTSWUS_PD5 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x5) +#define MODEM_ANTTRIG_PC0 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x0) +#define MODEM_ANTTRIG_PC1 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x1) +#define MODEM_ANTTRIG_PC2 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x2) +#define MODEM_ANTTRIG_PC3 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x3) +#define MODEM_ANTTRIG_PC4 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x4) +#define MODEM_ANTTRIG_PC5 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x5) +#define MODEM_ANTTRIG_PC6 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x6) +#define MODEM_ANTTRIG_PC7 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x7) +#define MODEM_ANTTRIG_PC8 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x8) +#define MODEM_ANTTRIG_PC9 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x9) +#define MODEM_ANTTRIG_PD0 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x0) +#define MODEM_ANTTRIG_PD1 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x1) +#define MODEM_ANTTRIG_PD2 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x2) +#define MODEM_ANTTRIG_PD3 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x3) +#define MODEM_ANTTRIG_PD4 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x4) +#define MODEM_ANTTRIG_PD5 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x5) +#define MODEM_ANTTRIGSTOP_PC0 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x0) +#define MODEM_ANTTRIGSTOP_PC1 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x1) +#define MODEM_ANTTRIGSTOP_PC2 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x2) +#define MODEM_ANTTRIGSTOP_PC3 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x3) +#define MODEM_ANTTRIGSTOP_PC4 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x4) +#define MODEM_ANTTRIGSTOP_PC5 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x5) +#define MODEM_ANTTRIGSTOP_PC6 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x6) +#define MODEM_ANTTRIGSTOP_PC7 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x7) +#define MODEM_ANTTRIGSTOP_PC8 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x8) +#define MODEM_ANTTRIGSTOP_PC9 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x9) +#define MODEM_ANTTRIGSTOP_PD0 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x0) +#define MODEM_ANTTRIGSTOP_PD1 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x1) +#define MODEM_ANTTRIGSTOP_PD2 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x2) +#define MODEM_ANTTRIGSTOP_PD3 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x3) +#define MODEM_ANTTRIGSTOP_PD4 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x4) +#define MODEM_ANTTRIGSTOP_PD5 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x5) +#define MODEM_DCLK_PA0 SILABS_DBUS_MODEM_DCLK(0x0, 0x0) +#define MODEM_DCLK_PA1 SILABS_DBUS_MODEM_DCLK(0x0, 0x1) +#define MODEM_DCLK_PA2 SILABS_DBUS_MODEM_DCLK(0x0, 0x2) +#define MODEM_DCLK_PA3 SILABS_DBUS_MODEM_DCLK(0x0, 0x3) +#define MODEM_DCLK_PA4 SILABS_DBUS_MODEM_DCLK(0x0, 0x4) +#define MODEM_DCLK_PA5 SILABS_DBUS_MODEM_DCLK(0x0, 0x5) +#define MODEM_DCLK_PA6 SILABS_DBUS_MODEM_DCLK(0x0, 0x6) +#define MODEM_DCLK_PA7 SILABS_DBUS_MODEM_DCLK(0x0, 0x7) +#define MODEM_DCLK_PA8 SILABS_DBUS_MODEM_DCLK(0x0, 0x8) +#define MODEM_DCLK_PA9 SILABS_DBUS_MODEM_DCLK(0x0, 0x9) +#define MODEM_DCLK_PA10 SILABS_DBUS_MODEM_DCLK(0x0, 0xa) +#define MODEM_DCLK_PB0 SILABS_DBUS_MODEM_DCLK(0x1, 0x0) +#define MODEM_DCLK_PB1 SILABS_DBUS_MODEM_DCLK(0x1, 0x1) +#define MODEM_DCLK_PB2 SILABS_DBUS_MODEM_DCLK(0x1, 0x2) +#define MODEM_DCLK_PB3 SILABS_DBUS_MODEM_DCLK(0x1, 0x3) +#define MODEM_DCLK_PB4 SILABS_DBUS_MODEM_DCLK(0x1, 0x4) +#define MODEM_DCLK_PB5 SILABS_DBUS_MODEM_DCLK(0x1, 0x5) +#define MODEM_DCLK_PB6 SILABS_DBUS_MODEM_DCLK(0x1, 0x6) +#define MODEM_DOUT_PA0 SILABS_DBUS_MODEM_DOUT(0x0, 0x0) +#define MODEM_DOUT_PA1 SILABS_DBUS_MODEM_DOUT(0x0, 0x1) +#define MODEM_DOUT_PA2 SILABS_DBUS_MODEM_DOUT(0x0, 0x2) +#define MODEM_DOUT_PA3 SILABS_DBUS_MODEM_DOUT(0x0, 0x3) +#define MODEM_DOUT_PA4 SILABS_DBUS_MODEM_DOUT(0x0, 0x4) +#define MODEM_DOUT_PA5 SILABS_DBUS_MODEM_DOUT(0x0, 0x5) +#define MODEM_DOUT_PA6 SILABS_DBUS_MODEM_DOUT(0x0, 0x6) +#define MODEM_DOUT_PA7 SILABS_DBUS_MODEM_DOUT(0x0, 0x7) +#define MODEM_DOUT_PA8 SILABS_DBUS_MODEM_DOUT(0x0, 0x8) +#define MODEM_DOUT_PA9 SILABS_DBUS_MODEM_DOUT(0x0, 0x9) +#define MODEM_DOUT_PA10 SILABS_DBUS_MODEM_DOUT(0x0, 0xa) +#define MODEM_DOUT_PB0 SILABS_DBUS_MODEM_DOUT(0x1, 0x0) +#define MODEM_DOUT_PB1 SILABS_DBUS_MODEM_DOUT(0x1, 0x1) +#define MODEM_DOUT_PB2 SILABS_DBUS_MODEM_DOUT(0x1, 0x2) +#define MODEM_DOUT_PB3 SILABS_DBUS_MODEM_DOUT(0x1, 0x3) +#define MODEM_DOUT_PB4 SILABS_DBUS_MODEM_DOUT(0x1, 0x4) +#define MODEM_DOUT_PB5 SILABS_DBUS_MODEM_DOUT(0x1, 0x5) +#define MODEM_DOUT_PB6 SILABS_DBUS_MODEM_DOUT(0x1, 0x6) +#define MODEM_DIN_PA0 SILABS_DBUS_MODEM_DIN(0x0, 0x0) +#define MODEM_DIN_PA1 SILABS_DBUS_MODEM_DIN(0x0, 0x1) +#define MODEM_DIN_PA2 SILABS_DBUS_MODEM_DIN(0x0, 0x2) +#define MODEM_DIN_PA3 SILABS_DBUS_MODEM_DIN(0x0, 0x3) +#define MODEM_DIN_PA4 SILABS_DBUS_MODEM_DIN(0x0, 0x4) +#define MODEM_DIN_PA5 SILABS_DBUS_MODEM_DIN(0x0, 0x5) +#define MODEM_DIN_PA6 SILABS_DBUS_MODEM_DIN(0x0, 0x6) +#define MODEM_DIN_PA7 SILABS_DBUS_MODEM_DIN(0x0, 0x7) +#define MODEM_DIN_PA8 SILABS_DBUS_MODEM_DIN(0x0, 0x8) +#define MODEM_DIN_PA9 SILABS_DBUS_MODEM_DIN(0x0, 0x9) +#define MODEM_DIN_PA10 SILABS_DBUS_MODEM_DIN(0x0, 0xa) +#define MODEM_DIN_PB0 SILABS_DBUS_MODEM_DIN(0x1, 0x0) +#define MODEM_DIN_PB1 SILABS_DBUS_MODEM_DIN(0x1, 0x1) +#define MODEM_DIN_PB2 SILABS_DBUS_MODEM_DIN(0x1, 0x2) +#define MODEM_DIN_PB3 SILABS_DBUS_MODEM_DIN(0x1, 0x3) +#define MODEM_DIN_PB4 SILABS_DBUS_MODEM_DIN(0x1, 0x4) +#define MODEM_DIN_PB5 SILABS_DBUS_MODEM_DIN(0x1, 0x5) +#define MODEM_DIN_PB6 SILABS_DBUS_MODEM_DIN(0x1, 0x6) + +#define PCNT0_S0IN_PA0 SILABS_DBUS_PCNT0_S0IN(0x0, 0x0) +#define PCNT0_S0IN_PA1 SILABS_DBUS_PCNT0_S0IN(0x0, 0x1) +#define PCNT0_S0IN_PA2 SILABS_DBUS_PCNT0_S0IN(0x0, 0x2) +#define PCNT0_S0IN_PA3 SILABS_DBUS_PCNT0_S0IN(0x0, 0x3) +#define PCNT0_S0IN_PA4 SILABS_DBUS_PCNT0_S0IN(0x0, 0x4) +#define PCNT0_S0IN_PA5 SILABS_DBUS_PCNT0_S0IN(0x0, 0x5) +#define PCNT0_S0IN_PA6 SILABS_DBUS_PCNT0_S0IN(0x0, 0x6) +#define PCNT0_S0IN_PA7 SILABS_DBUS_PCNT0_S0IN(0x0, 0x7) +#define PCNT0_S0IN_PA8 SILABS_DBUS_PCNT0_S0IN(0x0, 0x8) +#define PCNT0_S0IN_PA9 SILABS_DBUS_PCNT0_S0IN(0x0, 0x9) +#define PCNT0_S0IN_PA10 SILABS_DBUS_PCNT0_S0IN(0x0, 0xa) +#define PCNT0_S0IN_PB0 SILABS_DBUS_PCNT0_S0IN(0x1, 0x0) +#define PCNT0_S0IN_PB1 SILABS_DBUS_PCNT0_S0IN(0x1, 0x1) +#define PCNT0_S0IN_PB2 SILABS_DBUS_PCNT0_S0IN(0x1, 0x2) +#define PCNT0_S0IN_PB3 SILABS_DBUS_PCNT0_S0IN(0x1, 0x3) +#define PCNT0_S0IN_PB4 SILABS_DBUS_PCNT0_S0IN(0x1, 0x4) +#define PCNT0_S0IN_PB5 SILABS_DBUS_PCNT0_S0IN(0x1, 0x5) +#define PCNT0_S0IN_PB6 SILABS_DBUS_PCNT0_S0IN(0x1, 0x6) +#define PCNT0_S1IN_PA0 SILABS_DBUS_PCNT0_S1IN(0x0, 0x0) +#define PCNT0_S1IN_PA1 SILABS_DBUS_PCNT0_S1IN(0x0, 0x1) +#define PCNT0_S1IN_PA2 SILABS_DBUS_PCNT0_S1IN(0x0, 0x2) +#define PCNT0_S1IN_PA3 SILABS_DBUS_PCNT0_S1IN(0x0, 0x3) +#define PCNT0_S1IN_PA4 SILABS_DBUS_PCNT0_S1IN(0x0, 0x4) +#define PCNT0_S1IN_PA5 SILABS_DBUS_PCNT0_S1IN(0x0, 0x5) +#define PCNT0_S1IN_PA6 SILABS_DBUS_PCNT0_S1IN(0x0, 0x6) +#define PCNT0_S1IN_PA7 SILABS_DBUS_PCNT0_S1IN(0x0, 0x7) +#define PCNT0_S1IN_PA8 SILABS_DBUS_PCNT0_S1IN(0x0, 0x8) +#define PCNT0_S1IN_PA9 SILABS_DBUS_PCNT0_S1IN(0x0, 0x9) +#define PCNT0_S1IN_PA10 SILABS_DBUS_PCNT0_S1IN(0x0, 0xa) +#define PCNT0_S1IN_PB0 SILABS_DBUS_PCNT0_S1IN(0x1, 0x0) +#define PCNT0_S1IN_PB1 SILABS_DBUS_PCNT0_S1IN(0x1, 0x1) +#define PCNT0_S1IN_PB2 SILABS_DBUS_PCNT0_S1IN(0x1, 0x2) +#define PCNT0_S1IN_PB3 SILABS_DBUS_PCNT0_S1IN(0x1, 0x3) +#define PCNT0_S1IN_PB4 SILABS_DBUS_PCNT0_S1IN(0x1, 0x4) +#define PCNT0_S1IN_PB5 SILABS_DBUS_PCNT0_S1IN(0x1, 0x5) +#define PCNT0_S1IN_PB6 SILABS_DBUS_PCNT0_S1IN(0x1, 0x6) + +#define PRS0_ASYNCH0_PA0 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x0) +#define PRS0_ASYNCH0_PA1 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x1) +#define PRS0_ASYNCH0_PA2 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x2) +#define PRS0_ASYNCH0_PA3 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x3) +#define PRS0_ASYNCH0_PA4 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x4) +#define PRS0_ASYNCH0_PA5 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x5) +#define PRS0_ASYNCH0_PA6 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x6) +#define PRS0_ASYNCH0_PA7 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x7) +#define PRS0_ASYNCH0_PA8 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x8) +#define PRS0_ASYNCH0_PA9 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x9) +#define PRS0_ASYNCH0_PA10 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0xa) +#define PRS0_ASYNCH0_PB0 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x0) +#define PRS0_ASYNCH0_PB1 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x1) +#define PRS0_ASYNCH0_PB2 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x2) +#define PRS0_ASYNCH0_PB3 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x3) +#define PRS0_ASYNCH0_PB4 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x4) +#define PRS0_ASYNCH0_PB5 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x5) +#define PRS0_ASYNCH0_PB6 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x6) +#define PRS0_ASYNCH1_PA0 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x0) +#define PRS0_ASYNCH1_PA1 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x1) +#define PRS0_ASYNCH1_PA2 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x2) +#define PRS0_ASYNCH1_PA3 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x3) +#define PRS0_ASYNCH1_PA4 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x4) +#define PRS0_ASYNCH1_PA5 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x5) +#define PRS0_ASYNCH1_PA6 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x6) +#define PRS0_ASYNCH1_PA7 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x7) +#define PRS0_ASYNCH1_PA8 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x8) +#define PRS0_ASYNCH1_PA9 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x9) +#define PRS0_ASYNCH1_PA10 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0xa) +#define PRS0_ASYNCH1_PB0 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x0) +#define PRS0_ASYNCH1_PB1 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x1) +#define PRS0_ASYNCH1_PB2 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x2) +#define PRS0_ASYNCH1_PB3 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x3) +#define PRS0_ASYNCH1_PB4 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x4) +#define PRS0_ASYNCH1_PB5 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x5) +#define PRS0_ASYNCH1_PB6 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x6) +#define PRS0_ASYNCH2_PA0 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x0) +#define PRS0_ASYNCH2_PA1 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x1) +#define PRS0_ASYNCH2_PA2 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x2) +#define PRS0_ASYNCH2_PA3 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x3) +#define PRS0_ASYNCH2_PA4 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x4) +#define PRS0_ASYNCH2_PA5 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x5) +#define PRS0_ASYNCH2_PA6 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x6) +#define PRS0_ASYNCH2_PA7 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x7) +#define PRS0_ASYNCH2_PA8 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x8) +#define PRS0_ASYNCH2_PA9 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x9) +#define PRS0_ASYNCH2_PA10 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0xa) +#define PRS0_ASYNCH2_PB0 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x0) +#define PRS0_ASYNCH2_PB1 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x1) +#define PRS0_ASYNCH2_PB2 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x2) +#define PRS0_ASYNCH2_PB3 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x3) +#define PRS0_ASYNCH2_PB4 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x4) +#define PRS0_ASYNCH2_PB5 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x5) +#define PRS0_ASYNCH2_PB6 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x6) +#define PRS0_ASYNCH3_PA0 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x0) +#define PRS0_ASYNCH3_PA1 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x1) +#define PRS0_ASYNCH3_PA2 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x2) +#define PRS0_ASYNCH3_PA3 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x3) +#define PRS0_ASYNCH3_PA4 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x4) +#define PRS0_ASYNCH3_PA5 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x5) +#define PRS0_ASYNCH3_PA6 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x6) +#define PRS0_ASYNCH3_PA7 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x7) +#define PRS0_ASYNCH3_PA8 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x8) +#define PRS0_ASYNCH3_PA9 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x9) +#define PRS0_ASYNCH3_PA10 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0xa) +#define PRS0_ASYNCH3_PB0 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x0) +#define PRS0_ASYNCH3_PB1 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x1) +#define PRS0_ASYNCH3_PB2 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x2) +#define PRS0_ASYNCH3_PB3 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x3) +#define PRS0_ASYNCH3_PB4 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x4) +#define PRS0_ASYNCH3_PB5 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x5) +#define PRS0_ASYNCH3_PB6 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x6) +#define PRS0_ASYNCH4_PA0 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x0) +#define PRS0_ASYNCH4_PA1 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x1) +#define PRS0_ASYNCH4_PA2 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x2) +#define PRS0_ASYNCH4_PA3 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x3) +#define PRS0_ASYNCH4_PA4 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x4) +#define PRS0_ASYNCH4_PA5 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x5) +#define PRS0_ASYNCH4_PA6 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x6) +#define PRS0_ASYNCH4_PA7 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x7) +#define PRS0_ASYNCH4_PA8 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x8) +#define PRS0_ASYNCH4_PA9 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x9) +#define PRS0_ASYNCH4_PA10 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0xa) +#define PRS0_ASYNCH4_PB0 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x0) +#define PRS0_ASYNCH4_PB1 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x1) +#define PRS0_ASYNCH4_PB2 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x2) +#define PRS0_ASYNCH4_PB3 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x3) +#define PRS0_ASYNCH4_PB4 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x4) +#define PRS0_ASYNCH4_PB5 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x5) +#define PRS0_ASYNCH4_PB6 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x6) +#define PRS0_ASYNCH5_PA0 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x0) +#define PRS0_ASYNCH5_PA1 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x1) +#define PRS0_ASYNCH5_PA2 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x2) +#define PRS0_ASYNCH5_PA3 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x3) +#define PRS0_ASYNCH5_PA4 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x4) +#define PRS0_ASYNCH5_PA5 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x5) +#define PRS0_ASYNCH5_PA6 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x6) +#define PRS0_ASYNCH5_PA7 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x7) +#define PRS0_ASYNCH5_PA8 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x8) +#define PRS0_ASYNCH5_PA9 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x9) +#define PRS0_ASYNCH5_PA10 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0xa) +#define PRS0_ASYNCH5_PB0 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x0) +#define PRS0_ASYNCH5_PB1 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x1) +#define PRS0_ASYNCH5_PB2 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x2) +#define PRS0_ASYNCH5_PB3 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x3) +#define PRS0_ASYNCH5_PB4 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x4) +#define PRS0_ASYNCH5_PB5 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x5) +#define PRS0_ASYNCH5_PB6 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x6) +#define PRS0_ASYNCH6_PC0 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x0) +#define PRS0_ASYNCH6_PC1 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x1) +#define PRS0_ASYNCH6_PC2 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x2) +#define PRS0_ASYNCH6_PC3 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x3) +#define PRS0_ASYNCH6_PC4 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x4) +#define PRS0_ASYNCH6_PC5 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x5) +#define PRS0_ASYNCH6_PC6 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x6) +#define PRS0_ASYNCH6_PC7 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x7) +#define PRS0_ASYNCH6_PC8 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x8) +#define PRS0_ASYNCH6_PC9 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x9) +#define PRS0_ASYNCH6_PD0 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x0) +#define PRS0_ASYNCH6_PD1 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x1) +#define PRS0_ASYNCH6_PD2 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x2) +#define PRS0_ASYNCH6_PD3 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x3) +#define PRS0_ASYNCH6_PD4 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x4) +#define PRS0_ASYNCH6_PD5 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x5) +#define PRS0_ASYNCH7_PC0 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x0) +#define PRS0_ASYNCH7_PC1 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x1) +#define PRS0_ASYNCH7_PC2 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x2) +#define PRS0_ASYNCH7_PC3 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x3) +#define PRS0_ASYNCH7_PC4 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x4) +#define PRS0_ASYNCH7_PC5 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x5) +#define PRS0_ASYNCH7_PC6 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x6) +#define PRS0_ASYNCH7_PC7 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x7) +#define PRS0_ASYNCH7_PC8 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x8) +#define PRS0_ASYNCH7_PC9 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x9) +#define PRS0_ASYNCH7_PD0 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x0) +#define PRS0_ASYNCH7_PD1 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x1) +#define PRS0_ASYNCH7_PD2 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x2) +#define PRS0_ASYNCH7_PD3 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x3) +#define PRS0_ASYNCH7_PD4 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x4) +#define PRS0_ASYNCH7_PD5 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x5) +#define PRS0_ASYNCH8_PC0 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x0) +#define PRS0_ASYNCH8_PC1 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x1) +#define PRS0_ASYNCH8_PC2 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x2) +#define PRS0_ASYNCH8_PC3 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x3) +#define PRS0_ASYNCH8_PC4 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x4) +#define PRS0_ASYNCH8_PC5 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x5) +#define PRS0_ASYNCH8_PC6 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x6) +#define PRS0_ASYNCH8_PC7 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x7) +#define PRS0_ASYNCH8_PC8 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x8) +#define PRS0_ASYNCH8_PC9 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x9) +#define PRS0_ASYNCH8_PD0 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x0) +#define PRS0_ASYNCH8_PD1 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x1) +#define PRS0_ASYNCH8_PD2 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x2) +#define PRS0_ASYNCH8_PD3 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x3) +#define PRS0_ASYNCH8_PD4 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x4) +#define PRS0_ASYNCH8_PD5 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x5) +#define PRS0_ASYNCH9_PC0 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x0) +#define PRS0_ASYNCH9_PC1 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x1) +#define PRS0_ASYNCH9_PC2 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x2) +#define PRS0_ASYNCH9_PC3 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x3) +#define PRS0_ASYNCH9_PC4 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x4) +#define PRS0_ASYNCH9_PC5 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x5) +#define PRS0_ASYNCH9_PC6 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x6) +#define PRS0_ASYNCH9_PC7 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x7) +#define PRS0_ASYNCH9_PC8 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x8) +#define PRS0_ASYNCH9_PC9 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x9) +#define PRS0_ASYNCH9_PD0 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x0) +#define PRS0_ASYNCH9_PD1 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x1) +#define PRS0_ASYNCH9_PD2 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x2) +#define PRS0_ASYNCH9_PD3 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x3) +#define PRS0_ASYNCH9_PD4 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x4) +#define PRS0_ASYNCH9_PD5 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x5) +#define PRS0_ASYNCH10_PC0 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x0) +#define PRS0_ASYNCH10_PC1 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x1) +#define PRS0_ASYNCH10_PC2 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x2) +#define PRS0_ASYNCH10_PC3 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x3) +#define PRS0_ASYNCH10_PC4 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x4) +#define PRS0_ASYNCH10_PC5 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x5) +#define PRS0_ASYNCH10_PC6 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x6) +#define PRS0_ASYNCH10_PC7 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x7) +#define PRS0_ASYNCH10_PC8 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x8) +#define PRS0_ASYNCH10_PC9 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x9) +#define PRS0_ASYNCH10_PD0 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x0) +#define PRS0_ASYNCH10_PD1 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x1) +#define PRS0_ASYNCH10_PD2 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x2) +#define PRS0_ASYNCH10_PD3 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x3) +#define PRS0_ASYNCH10_PD4 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x4) +#define PRS0_ASYNCH10_PD5 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x5) +#define PRS0_ASYNCH11_PC0 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x0) +#define PRS0_ASYNCH11_PC1 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x1) +#define PRS0_ASYNCH11_PC2 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x2) +#define PRS0_ASYNCH11_PC3 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x3) +#define PRS0_ASYNCH11_PC4 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x4) +#define PRS0_ASYNCH11_PC5 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x5) +#define PRS0_ASYNCH11_PC6 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x6) +#define PRS0_ASYNCH11_PC7 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x7) +#define PRS0_ASYNCH11_PC8 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x8) +#define PRS0_ASYNCH11_PC9 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x9) +#define PRS0_ASYNCH11_PD0 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x0) +#define PRS0_ASYNCH11_PD1 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x1) +#define PRS0_ASYNCH11_PD2 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x2) +#define PRS0_ASYNCH11_PD3 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x3) +#define PRS0_ASYNCH11_PD4 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x4) +#define PRS0_ASYNCH11_PD5 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x5) +#define PRS0_SYNCH0_PA0 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x0) +#define PRS0_SYNCH0_PA1 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x1) +#define PRS0_SYNCH0_PA2 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x2) +#define PRS0_SYNCH0_PA3 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x3) +#define PRS0_SYNCH0_PA4 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x4) +#define PRS0_SYNCH0_PA5 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x5) +#define PRS0_SYNCH0_PA6 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x6) +#define PRS0_SYNCH0_PA7 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x7) +#define PRS0_SYNCH0_PA8 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x8) +#define PRS0_SYNCH0_PA9 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x9) +#define PRS0_SYNCH0_PA10 SILABS_DBUS_PRS0_SYNCH0(0x0, 0xa) +#define PRS0_SYNCH0_PB0 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x0) +#define PRS0_SYNCH0_PB1 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x1) +#define PRS0_SYNCH0_PB2 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x2) +#define PRS0_SYNCH0_PB3 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x3) +#define PRS0_SYNCH0_PB4 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x4) +#define PRS0_SYNCH0_PB5 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x5) +#define PRS0_SYNCH0_PB6 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x6) +#define PRS0_SYNCH0_PC0 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x0) +#define PRS0_SYNCH0_PC1 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x1) +#define PRS0_SYNCH0_PC2 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x2) +#define PRS0_SYNCH0_PC3 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x3) +#define PRS0_SYNCH0_PC4 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x4) +#define PRS0_SYNCH0_PC5 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x5) +#define PRS0_SYNCH0_PC6 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x6) +#define PRS0_SYNCH0_PC7 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x7) +#define PRS0_SYNCH0_PC8 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x8) +#define PRS0_SYNCH0_PC9 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x9) +#define PRS0_SYNCH0_PD0 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x0) +#define PRS0_SYNCH0_PD1 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x1) +#define PRS0_SYNCH0_PD2 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x2) +#define PRS0_SYNCH0_PD3 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x3) +#define PRS0_SYNCH0_PD4 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x4) +#define PRS0_SYNCH0_PD5 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x5) +#define PRS0_SYNCH1_PA0 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x0) +#define PRS0_SYNCH1_PA1 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x1) +#define PRS0_SYNCH1_PA2 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x2) +#define PRS0_SYNCH1_PA3 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x3) +#define PRS0_SYNCH1_PA4 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x4) +#define PRS0_SYNCH1_PA5 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x5) +#define PRS0_SYNCH1_PA6 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x6) +#define PRS0_SYNCH1_PA7 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x7) +#define PRS0_SYNCH1_PA8 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x8) +#define PRS0_SYNCH1_PA9 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x9) +#define PRS0_SYNCH1_PA10 SILABS_DBUS_PRS0_SYNCH1(0x0, 0xa) +#define PRS0_SYNCH1_PB0 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x0) +#define PRS0_SYNCH1_PB1 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x1) +#define PRS0_SYNCH1_PB2 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x2) +#define PRS0_SYNCH1_PB3 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x3) +#define PRS0_SYNCH1_PB4 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x4) +#define PRS0_SYNCH1_PB5 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x5) +#define PRS0_SYNCH1_PB6 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x6) +#define PRS0_SYNCH1_PC0 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x0) +#define PRS0_SYNCH1_PC1 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x1) +#define PRS0_SYNCH1_PC2 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x2) +#define PRS0_SYNCH1_PC3 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x3) +#define PRS0_SYNCH1_PC4 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x4) +#define PRS0_SYNCH1_PC5 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x5) +#define PRS0_SYNCH1_PC6 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x6) +#define PRS0_SYNCH1_PC7 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x7) +#define PRS0_SYNCH1_PC8 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x8) +#define PRS0_SYNCH1_PC9 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x9) +#define PRS0_SYNCH1_PD0 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x0) +#define PRS0_SYNCH1_PD1 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x1) +#define PRS0_SYNCH1_PD2 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x2) +#define PRS0_SYNCH1_PD3 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x3) +#define PRS0_SYNCH1_PD4 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x4) +#define PRS0_SYNCH1_PD5 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x5) +#define PRS0_SYNCH2_PA0 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x0) +#define PRS0_SYNCH2_PA1 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x1) +#define PRS0_SYNCH2_PA2 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x2) +#define PRS0_SYNCH2_PA3 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x3) +#define PRS0_SYNCH2_PA4 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x4) +#define PRS0_SYNCH2_PA5 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x5) +#define PRS0_SYNCH2_PA6 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x6) +#define PRS0_SYNCH2_PA7 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x7) +#define PRS0_SYNCH2_PA8 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x8) +#define PRS0_SYNCH2_PA9 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x9) +#define PRS0_SYNCH2_PA10 SILABS_DBUS_PRS0_SYNCH2(0x0, 0xa) +#define PRS0_SYNCH2_PB0 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x0) +#define PRS0_SYNCH2_PB1 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x1) +#define PRS0_SYNCH2_PB2 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x2) +#define PRS0_SYNCH2_PB3 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x3) +#define PRS0_SYNCH2_PB4 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x4) +#define PRS0_SYNCH2_PB5 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x5) +#define PRS0_SYNCH2_PB6 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x6) +#define PRS0_SYNCH2_PC0 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x0) +#define PRS0_SYNCH2_PC1 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x1) +#define PRS0_SYNCH2_PC2 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x2) +#define PRS0_SYNCH2_PC3 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x3) +#define PRS0_SYNCH2_PC4 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x4) +#define PRS0_SYNCH2_PC5 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x5) +#define PRS0_SYNCH2_PC6 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x6) +#define PRS0_SYNCH2_PC7 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x7) +#define PRS0_SYNCH2_PC8 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x8) +#define PRS0_SYNCH2_PC9 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x9) +#define PRS0_SYNCH2_PD0 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x0) +#define PRS0_SYNCH2_PD1 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x1) +#define PRS0_SYNCH2_PD2 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x2) +#define PRS0_SYNCH2_PD3 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x3) +#define PRS0_SYNCH2_PD4 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x4) +#define PRS0_SYNCH2_PD5 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x5) +#define PRS0_SYNCH3_PA0 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x0) +#define PRS0_SYNCH3_PA1 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x1) +#define PRS0_SYNCH3_PA2 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x2) +#define PRS0_SYNCH3_PA3 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x3) +#define PRS0_SYNCH3_PA4 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x4) +#define PRS0_SYNCH3_PA5 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x5) +#define PRS0_SYNCH3_PA6 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x6) +#define PRS0_SYNCH3_PA7 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x7) +#define PRS0_SYNCH3_PA8 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x8) +#define PRS0_SYNCH3_PA9 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x9) +#define PRS0_SYNCH3_PA10 SILABS_DBUS_PRS0_SYNCH3(0x0, 0xa) +#define PRS0_SYNCH3_PB0 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x0) +#define PRS0_SYNCH3_PB1 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x1) +#define PRS0_SYNCH3_PB2 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x2) +#define PRS0_SYNCH3_PB3 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x3) +#define PRS0_SYNCH3_PB4 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x4) +#define PRS0_SYNCH3_PB5 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x5) +#define PRS0_SYNCH3_PB6 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x6) +#define PRS0_SYNCH3_PC0 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x0) +#define PRS0_SYNCH3_PC1 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x1) +#define PRS0_SYNCH3_PC2 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x2) +#define PRS0_SYNCH3_PC3 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x3) +#define PRS0_SYNCH3_PC4 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x4) +#define PRS0_SYNCH3_PC5 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x5) +#define PRS0_SYNCH3_PC6 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x6) +#define PRS0_SYNCH3_PC7 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x7) +#define PRS0_SYNCH3_PC8 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x8) +#define PRS0_SYNCH3_PC9 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x9) +#define PRS0_SYNCH3_PD0 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x0) +#define PRS0_SYNCH3_PD1 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x1) +#define PRS0_SYNCH3_PD2 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x2) +#define PRS0_SYNCH3_PD3 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x3) +#define PRS0_SYNCH3_PD4 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x4) +#define PRS0_SYNCH3_PD5 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x5) + +#define HFXO0_BUFOUTREQINASYNC_PA0 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x0) +#define HFXO0_BUFOUTREQINASYNC_PA1 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x1) +#define HFXO0_BUFOUTREQINASYNC_PA2 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x2) +#define HFXO0_BUFOUTREQINASYNC_PA3 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x3) +#define HFXO0_BUFOUTREQINASYNC_PA4 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x4) +#define HFXO0_BUFOUTREQINASYNC_PA5 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x5) +#define HFXO0_BUFOUTREQINASYNC_PA6 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x6) +#define HFXO0_BUFOUTREQINASYNC_PA7 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x7) +#define HFXO0_BUFOUTREQINASYNC_PA8 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x8) +#define HFXO0_BUFOUTREQINASYNC_PA9 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0x9) +#define HFXO0_BUFOUTREQINASYNC_PA10 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x0, 0xa) +#define HFXO0_BUFOUTREQINASYNC_PB0 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x1, 0x0) +#define HFXO0_BUFOUTREQINASYNC_PB1 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x1, 0x1) +#define HFXO0_BUFOUTREQINASYNC_PB2 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x1, 0x2) +#define HFXO0_BUFOUTREQINASYNC_PB3 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x1, 0x3) +#define HFXO0_BUFOUTREQINASYNC_PB4 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x1, 0x4) +#define HFXO0_BUFOUTREQINASYNC_PB5 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x1, 0x5) +#define HFXO0_BUFOUTREQINASYNC_PB6 SILABS_DBUS_HFXO0_BUFOUTREQINASYNC(0x1, 0x6) + +#define TIMER0_CC0_PA0 SILABS_DBUS_TIMER0_CC0(0x0, 0x0) +#define TIMER0_CC0_PA1 SILABS_DBUS_TIMER0_CC0(0x0, 0x1) +#define TIMER0_CC0_PA2 SILABS_DBUS_TIMER0_CC0(0x0, 0x2) +#define TIMER0_CC0_PA3 SILABS_DBUS_TIMER0_CC0(0x0, 0x3) +#define TIMER0_CC0_PA4 SILABS_DBUS_TIMER0_CC0(0x0, 0x4) +#define TIMER0_CC0_PA5 SILABS_DBUS_TIMER0_CC0(0x0, 0x5) +#define TIMER0_CC0_PA6 SILABS_DBUS_TIMER0_CC0(0x0, 0x6) +#define TIMER0_CC0_PA7 SILABS_DBUS_TIMER0_CC0(0x0, 0x7) +#define TIMER0_CC0_PA8 SILABS_DBUS_TIMER0_CC0(0x0, 0x8) +#define TIMER0_CC0_PA9 SILABS_DBUS_TIMER0_CC0(0x0, 0x9) +#define TIMER0_CC0_PA10 SILABS_DBUS_TIMER0_CC0(0x0, 0xa) +#define TIMER0_CC0_PB0 SILABS_DBUS_TIMER0_CC0(0x1, 0x0) +#define TIMER0_CC0_PB1 SILABS_DBUS_TIMER0_CC0(0x1, 0x1) +#define TIMER0_CC0_PB2 SILABS_DBUS_TIMER0_CC0(0x1, 0x2) +#define TIMER0_CC0_PB3 SILABS_DBUS_TIMER0_CC0(0x1, 0x3) +#define TIMER0_CC0_PB4 SILABS_DBUS_TIMER0_CC0(0x1, 0x4) +#define TIMER0_CC0_PB5 SILABS_DBUS_TIMER0_CC0(0x1, 0x5) +#define TIMER0_CC0_PB6 SILABS_DBUS_TIMER0_CC0(0x1, 0x6) +#define TIMER0_CC0_PC0 SILABS_DBUS_TIMER0_CC0(0x2, 0x0) +#define TIMER0_CC0_PC1 SILABS_DBUS_TIMER0_CC0(0x2, 0x1) +#define TIMER0_CC0_PC2 SILABS_DBUS_TIMER0_CC0(0x2, 0x2) +#define TIMER0_CC0_PC3 SILABS_DBUS_TIMER0_CC0(0x2, 0x3) +#define TIMER0_CC0_PC4 SILABS_DBUS_TIMER0_CC0(0x2, 0x4) +#define TIMER0_CC0_PC5 SILABS_DBUS_TIMER0_CC0(0x2, 0x5) +#define TIMER0_CC0_PC6 SILABS_DBUS_TIMER0_CC0(0x2, 0x6) +#define TIMER0_CC0_PC7 SILABS_DBUS_TIMER0_CC0(0x2, 0x7) +#define TIMER0_CC0_PC8 SILABS_DBUS_TIMER0_CC0(0x2, 0x8) +#define TIMER0_CC0_PC9 SILABS_DBUS_TIMER0_CC0(0x2, 0x9) +#define TIMER0_CC0_PD0 SILABS_DBUS_TIMER0_CC0(0x3, 0x0) +#define TIMER0_CC0_PD1 SILABS_DBUS_TIMER0_CC0(0x3, 0x1) +#define TIMER0_CC0_PD2 SILABS_DBUS_TIMER0_CC0(0x3, 0x2) +#define TIMER0_CC0_PD3 SILABS_DBUS_TIMER0_CC0(0x3, 0x3) +#define TIMER0_CC0_PD4 SILABS_DBUS_TIMER0_CC0(0x3, 0x4) +#define TIMER0_CC0_PD5 SILABS_DBUS_TIMER0_CC0(0x3, 0x5) +#define TIMER0_CC1_PA0 SILABS_DBUS_TIMER0_CC1(0x0, 0x0) +#define TIMER0_CC1_PA1 SILABS_DBUS_TIMER0_CC1(0x0, 0x1) +#define TIMER0_CC1_PA2 SILABS_DBUS_TIMER0_CC1(0x0, 0x2) +#define TIMER0_CC1_PA3 SILABS_DBUS_TIMER0_CC1(0x0, 0x3) +#define TIMER0_CC1_PA4 SILABS_DBUS_TIMER0_CC1(0x0, 0x4) +#define TIMER0_CC1_PA5 SILABS_DBUS_TIMER0_CC1(0x0, 0x5) +#define TIMER0_CC1_PA6 SILABS_DBUS_TIMER0_CC1(0x0, 0x6) +#define TIMER0_CC1_PA7 SILABS_DBUS_TIMER0_CC1(0x0, 0x7) +#define TIMER0_CC1_PA8 SILABS_DBUS_TIMER0_CC1(0x0, 0x8) +#define TIMER0_CC1_PA9 SILABS_DBUS_TIMER0_CC1(0x0, 0x9) +#define TIMER0_CC1_PA10 SILABS_DBUS_TIMER0_CC1(0x0, 0xa) +#define TIMER0_CC1_PB0 SILABS_DBUS_TIMER0_CC1(0x1, 0x0) +#define TIMER0_CC1_PB1 SILABS_DBUS_TIMER0_CC1(0x1, 0x1) +#define TIMER0_CC1_PB2 SILABS_DBUS_TIMER0_CC1(0x1, 0x2) +#define TIMER0_CC1_PB3 SILABS_DBUS_TIMER0_CC1(0x1, 0x3) +#define TIMER0_CC1_PB4 SILABS_DBUS_TIMER0_CC1(0x1, 0x4) +#define TIMER0_CC1_PB5 SILABS_DBUS_TIMER0_CC1(0x1, 0x5) +#define TIMER0_CC1_PB6 SILABS_DBUS_TIMER0_CC1(0x1, 0x6) +#define TIMER0_CC1_PC0 SILABS_DBUS_TIMER0_CC1(0x2, 0x0) +#define TIMER0_CC1_PC1 SILABS_DBUS_TIMER0_CC1(0x2, 0x1) +#define TIMER0_CC1_PC2 SILABS_DBUS_TIMER0_CC1(0x2, 0x2) +#define TIMER0_CC1_PC3 SILABS_DBUS_TIMER0_CC1(0x2, 0x3) +#define TIMER0_CC1_PC4 SILABS_DBUS_TIMER0_CC1(0x2, 0x4) +#define TIMER0_CC1_PC5 SILABS_DBUS_TIMER0_CC1(0x2, 0x5) +#define TIMER0_CC1_PC6 SILABS_DBUS_TIMER0_CC1(0x2, 0x6) +#define TIMER0_CC1_PC7 SILABS_DBUS_TIMER0_CC1(0x2, 0x7) +#define TIMER0_CC1_PC8 SILABS_DBUS_TIMER0_CC1(0x2, 0x8) +#define TIMER0_CC1_PC9 SILABS_DBUS_TIMER0_CC1(0x2, 0x9) +#define TIMER0_CC1_PD0 SILABS_DBUS_TIMER0_CC1(0x3, 0x0) +#define TIMER0_CC1_PD1 SILABS_DBUS_TIMER0_CC1(0x3, 0x1) +#define TIMER0_CC1_PD2 SILABS_DBUS_TIMER0_CC1(0x3, 0x2) +#define TIMER0_CC1_PD3 SILABS_DBUS_TIMER0_CC1(0x3, 0x3) +#define TIMER0_CC1_PD4 SILABS_DBUS_TIMER0_CC1(0x3, 0x4) +#define TIMER0_CC1_PD5 SILABS_DBUS_TIMER0_CC1(0x3, 0x5) +#define TIMER0_CC2_PA0 SILABS_DBUS_TIMER0_CC2(0x0, 0x0) +#define TIMER0_CC2_PA1 SILABS_DBUS_TIMER0_CC2(0x0, 0x1) +#define TIMER0_CC2_PA2 SILABS_DBUS_TIMER0_CC2(0x0, 0x2) +#define TIMER0_CC2_PA3 SILABS_DBUS_TIMER0_CC2(0x0, 0x3) +#define TIMER0_CC2_PA4 SILABS_DBUS_TIMER0_CC2(0x0, 0x4) +#define TIMER0_CC2_PA5 SILABS_DBUS_TIMER0_CC2(0x0, 0x5) +#define TIMER0_CC2_PA6 SILABS_DBUS_TIMER0_CC2(0x0, 0x6) +#define TIMER0_CC2_PA7 SILABS_DBUS_TIMER0_CC2(0x0, 0x7) +#define TIMER0_CC2_PA8 SILABS_DBUS_TIMER0_CC2(0x0, 0x8) +#define TIMER0_CC2_PA9 SILABS_DBUS_TIMER0_CC2(0x0, 0x9) +#define TIMER0_CC2_PA10 SILABS_DBUS_TIMER0_CC2(0x0, 0xa) +#define TIMER0_CC2_PB0 SILABS_DBUS_TIMER0_CC2(0x1, 0x0) +#define TIMER0_CC2_PB1 SILABS_DBUS_TIMER0_CC2(0x1, 0x1) +#define TIMER0_CC2_PB2 SILABS_DBUS_TIMER0_CC2(0x1, 0x2) +#define TIMER0_CC2_PB3 SILABS_DBUS_TIMER0_CC2(0x1, 0x3) +#define TIMER0_CC2_PB4 SILABS_DBUS_TIMER0_CC2(0x1, 0x4) +#define TIMER0_CC2_PB5 SILABS_DBUS_TIMER0_CC2(0x1, 0x5) +#define TIMER0_CC2_PB6 SILABS_DBUS_TIMER0_CC2(0x1, 0x6) +#define TIMER0_CC2_PC0 SILABS_DBUS_TIMER0_CC2(0x2, 0x0) +#define TIMER0_CC2_PC1 SILABS_DBUS_TIMER0_CC2(0x2, 0x1) +#define TIMER0_CC2_PC2 SILABS_DBUS_TIMER0_CC2(0x2, 0x2) +#define TIMER0_CC2_PC3 SILABS_DBUS_TIMER0_CC2(0x2, 0x3) +#define TIMER0_CC2_PC4 SILABS_DBUS_TIMER0_CC2(0x2, 0x4) +#define TIMER0_CC2_PC5 SILABS_DBUS_TIMER0_CC2(0x2, 0x5) +#define TIMER0_CC2_PC6 SILABS_DBUS_TIMER0_CC2(0x2, 0x6) +#define TIMER0_CC2_PC7 SILABS_DBUS_TIMER0_CC2(0x2, 0x7) +#define TIMER0_CC2_PC8 SILABS_DBUS_TIMER0_CC2(0x2, 0x8) +#define TIMER0_CC2_PC9 SILABS_DBUS_TIMER0_CC2(0x2, 0x9) +#define TIMER0_CC2_PD0 SILABS_DBUS_TIMER0_CC2(0x3, 0x0) +#define TIMER0_CC2_PD1 SILABS_DBUS_TIMER0_CC2(0x3, 0x1) +#define TIMER0_CC2_PD2 SILABS_DBUS_TIMER0_CC2(0x3, 0x2) +#define TIMER0_CC2_PD3 SILABS_DBUS_TIMER0_CC2(0x3, 0x3) +#define TIMER0_CC2_PD4 SILABS_DBUS_TIMER0_CC2(0x3, 0x4) +#define TIMER0_CC2_PD5 SILABS_DBUS_TIMER0_CC2(0x3, 0x5) +#define TIMER0_CDTI0_PA0 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x0) +#define TIMER0_CDTI0_PA1 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x1) +#define TIMER0_CDTI0_PA2 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x2) +#define TIMER0_CDTI0_PA3 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x3) +#define TIMER0_CDTI0_PA4 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x4) +#define TIMER0_CDTI0_PA5 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x5) +#define TIMER0_CDTI0_PA6 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x6) +#define TIMER0_CDTI0_PA7 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x7) +#define TIMER0_CDTI0_PA8 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x8) +#define TIMER0_CDTI0_PA9 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x9) +#define TIMER0_CDTI0_PA10 SILABS_DBUS_TIMER0_CDTI0(0x0, 0xa) +#define TIMER0_CDTI0_PB0 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x0) +#define TIMER0_CDTI0_PB1 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x1) +#define TIMER0_CDTI0_PB2 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x2) +#define TIMER0_CDTI0_PB3 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x3) +#define TIMER0_CDTI0_PB4 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x4) +#define TIMER0_CDTI0_PB5 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x5) +#define TIMER0_CDTI0_PB6 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x6) +#define TIMER0_CDTI0_PC0 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x0) +#define TIMER0_CDTI0_PC1 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x1) +#define TIMER0_CDTI0_PC2 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x2) +#define TIMER0_CDTI0_PC3 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x3) +#define TIMER0_CDTI0_PC4 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x4) +#define TIMER0_CDTI0_PC5 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x5) +#define TIMER0_CDTI0_PC6 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x6) +#define TIMER0_CDTI0_PC7 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x7) +#define TIMER0_CDTI0_PC8 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x8) +#define TIMER0_CDTI0_PC9 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x9) +#define TIMER0_CDTI0_PD0 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x0) +#define TIMER0_CDTI0_PD1 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x1) +#define TIMER0_CDTI0_PD2 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x2) +#define TIMER0_CDTI0_PD3 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x3) +#define TIMER0_CDTI0_PD4 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x4) +#define TIMER0_CDTI0_PD5 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x5) +#define TIMER0_CDTI1_PA0 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x0) +#define TIMER0_CDTI1_PA1 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x1) +#define TIMER0_CDTI1_PA2 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x2) +#define TIMER0_CDTI1_PA3 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x3) +#define TIMER0_CDTI1_PA4 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x4) +#define TIMER0_CDTI1_PA5 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x5) +#define TIMER0_CDTI1_PA6 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x6) +#define TIMER0_CDTI1_PA7 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x7) +#define TIMER0_CDTI1_PA8 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x8) +#define TIMER0_CDTI1_PA9 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x9) +#define TIMER0_CDTI1_PA10 SILABS_DBUS_TIMER0_CDTI1(0x0, 0xa) +#define TIMER0_CDTI1_PB0 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x0) +#define TIMER0_CDTI1_PB1 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x1) +#define TIMER0_CDTI1_PB2 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x2) +#define TIMER0_CDTI1_PB3 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x3) +#define TIMER0_CDTI1_PB4 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x4) +#define TIMER0_CDTI1_PB5 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x5) +#define TIMER0_CDTI1_PB6 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x6) +#define TIMER0_CDTI1_PC0 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x0) +#define TIMER0_CDTI1_PC1 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x1) +#define TIMER0_CDTI1_PC2 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x2) +#define TIMER0_CDTI1_PC3 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x3) +#define TIMER0_CDTI1_PC4 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x4) +#define TIMER0_CDTI1_PC5 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x5) +#define TIMER0_CDTI1_PC6 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x6) +#define TIMER0_CDTI1_PC7 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x7) +#define TIMER0_CDTI1_PC8 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x8) +#define TIMER0_CDTI1_PC9 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x9) +#define TIMER0_CDTI1_PD0 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x0) +#define TIMER0_CDTI1_PD1 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x1) +#define TIMER0_CDTI1_PD2 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x2) +#define TIMER0_CDTI1_PD3 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x3) +#define TIMER0_CDTI1_PD4 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x4) +#define TIMER0_CDTI1_PD5 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x5) +#define TIMER0_CDTI2_PA0 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x0) +#define TIMER0_CDTI2_PA1 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x1) +#define TIMER0_CDTI2_PA2 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x2) +#define TIMER0_CDTI2_PA3 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x3) +#define TIMER0_CDTI2_PA4 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x4) +#define TIMER0_CDTI2_PA5 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x5) +#define TIMER0_CDTI2_PA6 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x6) +#define TIMER0_CDTI2_PA7 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x7) +#define TIMER0_CDTI2_PA8 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x8) +#define TIMER0_CDTI2_PA9 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x9) +#define TIMER0_CDTI2_PA10 SILABS_DBUS_TIMER0_CDTI2(0x0, 0xa) +#define TIMER0_CDTI2_PB0 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x0) +#define TIMER0_CDTI2_PB1 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x1) +#define TIMER0_CDTI2_PB2 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x2) +#define TIMER0_CDTI2_PB3 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x3) +#define TIMER0_CDTI2_PB4 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x4) +#define TIMER0_CDTI2_PB5 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x5) +#define TIMER0_CDTI2_PB6 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x6) +#define TIMER0_CDTI2_PC0 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x0) +#define TIMER0_CDTI2_PC1 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x1) +#define TIMER0_CDTI2_PC2 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x2) +#define TIMER0_CDTI2_PC3 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x3) +#define TIMER0_CDTI2_PC4 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x4) +#define TIMER0_CDTI2_PC5 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x5) +#define TIMER0_CDTI2_PC6 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x6) +#define TIMER0_CDTI2_PC7 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x7) +#define TIMER0_CDTI2_PC8 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x8) +#define TIMER0_CDTI2_PC9 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x9) +#define TIMER0_CDTI2_PD0 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x0) +#define TIMER0_CDTI2_PD1 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x1) +#define TIMER0_CDTI2_PD2 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x2) +#define TIMER0_CDTI2_PD3 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x3) +#define TIMER0_CDTI2_PD4 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x4) +#define TIMER0_CDTI2_PD5 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x5) + +#define TIMER1_CC0_PA0 SILABS_DBUS_TIMER1_CC0(0x0, 0x0) +#define TIMER1_CC0_PA1 SILABS_DBUS_TIMER1_CC0(0x0, 0x1) +#define TIMER1_CC0_PA2 SILABS_DBUS_TIMER1_CC0(0x0, 0x2) +#define TIMER1_CC0_PA3 SILABS_DBUS_TIMER1_CC0(0x0, 0x3) +#define TIMER1_CC0_PA4 SILABS_DBUS_TIMER1_CC0(0x0, 0x4) +#define TIMER1_CC0_PA5 SILABS_DBUS_TIMER1_CC0(0x0, 0x5) +#define TIMER1_CC0_PA6 SILABS_DBUS_TIMER1_CC0(0x0, 0x6) +#define TIMER1_CC0_PA7 SILABS_DBUS_TIMER1_CC0(0x0, 0x7) +#define TIMER1_CC0_PA8 SILABS_DBUS_TIMER1_CC0(0x0, 0x8) +#define TIMER1_CC0_PA9 SILABS_DBUS_TIMER1_CC0(0x0, 0x9) +#define TIMER1_CC0_PA10 SILABS_DBUS_TIMER1_CC0(0x0, 0xa) +#define TIMER1_CC0_PB0 SILABS_DBUS_TIMER1_CC0(0x1, 0x0) +#define TIMER1_CC0_PB1 SILABS_DBUS_TIMER1_CC0(0x1, 0x1) +#define TIMER1_CC0_PB2 SILABS_DBUS_TIMER1_CC0(0x1, 0x2) +#define TIMER1_CC0_PB3 SILABS_DBUS_TIMER1_CC0(0x1, 0x3) +#define TIMER1_CC0_PB4 SILABS_DBUS_TIMER1_CC0(0x1, 0x4) +#define TIMER1_CC0_PB5 SILABS_DBUS_TIMER1_CC0(0x1, 0x5) +#define TIMER1_CC0_PB6 SILABS_DBUS_TIMER1_CC0(0x1, 0x6) +#define TIMER1_CC0_PC0 SILABS_DBUS_TIMER1_CC0(0x2, 0x0) +#define TIMER1_CC0_PC1 SILABS_DBUS_TIMER1_CC0(0x2, 0x1) +#define TIMER1_CC0_PC2 SILABS_DBUS_TIMER1_CC0(0x2, 0x2) +#define TIMER1_CC0_PC3 SILABS_DBUS_TIMER1_CC0(0x2, 0x3) +#define TIMER1_CC0_PC4 SILABS_DBUS_TIMER1_CC0(0x2, 0x4) +#define TIMER1_CC0_PC5 SILABS_DBUS_TIMER1_CC0(0x2, 0x5) +#define TIMER1_CC0_PC6 SILABS_DBUS_TIMER1_CC0(0x2, 0x6) +#define TIMER1_CC0_PC7 SILABS_DBUS_TIMER1_CC0(0x2, 0x7) +#define TIMER1_CC0_PC8 SILABS_DBUS_TIMER1_CC0(0x2, 0x8) +#define TIMER1_CC0_PC9 SILABS_DBUS_TIMER1_CC0(0x2, 0x9) +#define TIMER1_CC0_PD0 SILABS_DBUS_TIMER1_CC0(0x3, 0x0) +#define TIMER1_CC0_PD1 SILABS_DBUS_TIMER1_CC0(0x3, 0x1) +#define TIMER1_CC0_PD2 SILABS_DBUS_TIMER1_CC0(0x3, 0x2) +#define TIMER1_CC0_PD3 SILABS_DBUS_TIMER1_CC0(0x3, 0x3) +#define TIMER1_CC0_PD4 SILABS_DBUS_TIMER1_CC0(0x3, 0x4) +#define TIMER1_CC0_PD5 SILABS_DBUS_TIMER1_CC0(0x3, 0x5) +#define TIMER1_CC1_PA0 SILABS_DBUS_TIMER1_CC1(0x0, 0x0) +#define TIMER1_CC1_PA1 SILABS_DBUS_TIMER1_CC1(0x0, 0x1) +#define TIMER1_CC1_PA2 SILABS_DBUS_TIMER1_CC1(0x0, 0x2) +#define TIMER1_CC1_PA3 SILABS_DBUS_TIMER1_CC1(0x0, 0x3) +#define TIMER1_CC1_PA4 SILABS_DBUS_TIMER1_CC1(0x0, 0x4) +#define TIMER1_CC1_PA5 SILABS_DBUS_TIMER1_CC1(0x0, 0x5) +#define TIMER1_CC1_PA6 SILABS_DBUS_TIMER1_CC1(0x0, 0x6) +#define TIMER1_CC1_PA7 SILABS_DBUS_TIMER1_CC1(0x0, 0x7) +#define TIMER1_CC1_PA8 SILABS_DBUS_TIMER1_CC1(0x0, 0x8) +#define TIMER1_CC1_PA9 SILABS_DBUS_TIMER1_CC1(0x0, 0x9) +#define TIMER1_CC1_PA10 SILABS_DBUS_TIMER1_CC1(0x0, 0xa) +#define TIMER1_CC1_PB0 SILABS_DBUS_TIMER1_CC1(0x1, 0x0) +#define TIMER1_CC1_PB1 SILABS_DBUS_TIMER1_CC1(0x1, 0x1) +#define TIMER1_CC1_PB2 SILABS_DBUS_TIMER1_CC1(0x1, 0x2) +#define TIMER1_CC1_PB3 SILABS_DBUS_TIMER1_CC1(0x1, 0x3) +#define TIMER1_CC1_PB4 SILABS_DBUS_TIMER1_CC1(0x1, 0x4) +#define TIMER1_CC1_PB5 SILABS_DBUS_TIMER1_CC1(0x1, 0x5) +#define TIMER1_CC1_PB6 SILABS_DBUS_TIMER1_CC1(0x1, 0x6) +#define TIMER1_CC1_PC0 SILABS_DBUS_TIMER1_CC1(0x2, 0x0) +#define TIMER1_CC1_PC1 SILABS_DBUS_TIMER1_CC1(0x2, 0x1) +#define TIMER1_CC1_PC2 SILABS_DBUS_TIMER1_CC1(0x2, 0x2) +#define TIMER1_CC1_PC3 SILABS_DBUS_TIMER1_CC1(0x2, 0x3) +#define TIMER1_CC1_PC4 SILABS_DBUS_TIMER1_CC1(0x2, 0x4) +#define TIMER1_CC1_PC5 SILABS_DBUS_TIMER1_CC1(0x2, 0x5) +#define TIMER1_CC1_PC6 SILABS_DBUS_TIMER1_CC1(0x2, 0x6) +#define TIMER1_CC1_PC7 SILABS_DBUS_TIMER1_CC1(0x2, 0x7) +#define TIMER1_CC1_PC8 SILABS_DBUS_TIMER1_CC1(0x2, 0x8) +#define TIMER1_CC1_PC9 SILABS_DBUS_TIMER1_CC1(0x2, 0x9) +#define TIMER1_CC1_PD0 SILABS_DBUS_TIMER1_CC1(0x3, 0x0) +#define TIMER1_CC1_PD1 SILABS_DBUS_TIMER1_CC1(0x3, 0x1) +#define TIMER1_CC1_PD2 SILABS_DBUS_TIMER1_CC1(0x3, 0x2) +#define TIMER1_CC1_PD3 SILABS_DBUS_TIMER1_CC1(0x3, 0x3) +#define TIMER1_CC1_PD4 SILABS_DBUS_TIMER1_CC1(0x3, 0x4) +#define TIMER1_CC1_PD5 SILABS_DBUS_TIMER1_CC1(0x3, 0x5) +#define TIMER1_CC2_PA0 SILABS_DBUS_TIMER1_CC2(0x0, 0x0) +#define TIMER1_CC2_PA1 SILABS_DBUS_TIMER1_CC2(0x0, 0x1) +#define TIMER1_CC2_PA2 SILABS_DBUS_TIMER1_CC2(0x0, 0x2) +#define TIMER1_CC2_PA3 SILABS_DBUS_TIMER1_CC2(0x0, 0x3) +#define TIMER1_CC2_PA4 SILABS_DBUS_TIMER1_CC2(0x0, 0x4) +#define TIMER1_CC2_PA5 SILABS_DBUS_TIMER1_CC2(0x0, 0x5) +#define TIMER1_CC2_PA6 SILABS_DBUS_TIMER1_CC2(0x0, 0x6) +#define TIMER1_CC2_PA7 SILABS_DBUS_TIMER1_CC2(0x0, 0x7) +#define TIMER1_CC2_PA8 SILABS_DBUS_TIMER1_CC2(0x0, 0x8) +#define TIMER1_CC2_PA9 SILABS_DBUS_TIMER1_CC2(0x0, 0x9) +#define TIMER1_CC2_PA10 SILABS_DBUS_TIMER1_CC2(0x0, 0xa) +#define TIMER1_CC2_PB0 SILABS_DBUS_TIMER1_CC2(0x1, 0x0) +#define TIMER1_CC2_PB1 SILABS_DBUS_TIMER1_CC2(0x1, 0x1) +#define TIMER1_CC2_PB2 SILABS_DBUS_TIMER1_CC2(0x1, 0x2) +#define TIMER1_CC2_PB3 SILABS_DBUS_TIMER1_CC2(0x1, 0x3) +#define TIMER1_CC2_PB4 SILABS_DBUS_TIMER1_CC2(0x1, 0x4) +#define TIMER1_CC2_PB5 SILABS_DBUS_TIMER1_CC2(0x1, 0x5) +#define TIMER1_CC2_PB6 SILABS_DBUS_TIMER1_CC2(0x1, 0x6) +#define TIMER1_CC2_PC0 SILABS_DBUS_TIMER1_CC2(0x2, 0x0) +#define TIMER1_CC2_PC1 SILABS_DBUS_TIMER1_CC2(0x2, 0x1) +#define TIMER1_CC2_PC2 SILABS_DBUS_TIMER1_CC2(0x2, 0x2) +#define TIMER1_CC2_PC3 SILABS_DBUS_TIMER1_CC2(0x2, 0x3) +#define TIMER1_CC2_PC4 SILABS_DBUS_TIMER1_CC2(0x2, 0x4) +#define TIMER1_CC2_PC5 SILABS_DBUS_TIMER1_CC2(0x2, 0x5) +#define TIMER1_CC2_PC6 SILABS_DBUS_TIMER1_CC2(0x2, 0x6) +#define TIMER1_CC2_PC7 SILABS_DBUS_TIMER1_CC2(0x2, 0x7) +#define TIMER1_CC2_PC8 SILABS_DBUS_TIMER1_CC2(0x2, 0x8) +#define TIMER1_CC2_PC9 SILABS_DBUS_TIMER1_CC2(0x2, 0x9) +#define TIMER1_CC2_PD0 SILABS_DBUS_TIMER1_CC2(0x3, 0x0) +#define TIMER1_CC2_PD1 SILABS_DBUS_TIMER1_CC2(0x3, 0x1) +#define TIMER1_CC2_PD2 SILABS_DBUS_TIMER1_CC2(0x3, 0x2) +#define TIMER1_CC2_PD3 SILABS_DBUS_TIMER1_CC2(0x3, 0x3) +#define TIMER1_CC2_PD4 SILABS_DBUS_TIMER1_CC2(0x3, 0x4) +#define TIMER1_CC2_PD5 SILABS_DBUS_TIMER1_CC2(0x3, 0x5) +#define TIMER1_CDTI0_PA0 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x0) +#define TIMER1_CDTI0_PA1 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x1) +#define TIMER1_CDTI0_PA2 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x2) +#define TIMER1_CDTI0_PA3 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x3) +#define TIMER1_CDTI0_PA4 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x4) +#define TIMER1_CDTI0_PA5 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x5) +#define TIMER1_CDTI0_PA6 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x6) +#define TIMER1_CDTI0_PA7 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x7) +#define TIMER1_CDTI0_PA8 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x8) +#define TIMER1_CDTI0_PA9 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x9) +#define TIMER1_CDTI0_PA10 SILABS_DBUS_TIMER1_CDTI0(0x0, 0xa) +#define TIMER1_CDTI0_PB0 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x0) +#define TIMER1_CDTI0_PB1 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x1) +#define TIMER1_CDTI0_PB2 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x2) +#define TIMER1_CDTI0_PB3 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x3) +#define TIMER1_CDTI0_PB4 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x4) +#define TIMER1_CDTI0_PB5 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x5) +#define TIMER1_CDTI0_PB6 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x6) +#define TIMER1_CDTI0_PC0 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x0) +#define TIMER1_CDTI0_PC1 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x1) +#define TIMER1_CDTI0_PC2 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x2) +#define TIMER1_CDTI0_PC3 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x3) +#define TIMER1_CDTI0_PC4 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x4) +#define TIMER1_CDTI0_PC5 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x5) +#define TIMER1_CDTI0_PC6 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x6) +#define TIMER1_CDTI0_PC7 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x7) +#define TIMER1_CDTI0_PC8 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x8) +#define TIMER1_CDTI0_PC9 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x9) +#define TIMER1_CDTI0_PD0 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x0) +#define TIMER1_CDTI0_PD1 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x1) +#define TIMER1_CDTI0_PD2 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x2) +#define TIMER1_CDTI0_PD3 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x3) +#define TIMER1_CDTI0_PD4 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x4) +#define TIMER1_CDTI0_PD5 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x5) +#define TIMER1_CDTI1_PA0 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x0) +#define TIMER1_CDTI1_PA1 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x1) +#define TIMER1_CDTI1_PA2 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x2) +#define TIMER1_CDTI1_PA3 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x3) +#define TIMER1_CDTI1_PA4 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x4) +#define TIMER1_CDTI1_PA5 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x5) +#define TIMER1_CDTI1_PA6 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x6) +#define TIMER1_CDTI1_PA7 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x7) +#define TIMER1_CDTI1_PA8 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x8) +#define TIMER1_CDTI1_PA9 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x9) +#define TIMER1_CDTI1_PA10 SILABS_DBUS_TIMER1_CDTI1(0x0, 0xa) +#define TIMER1_CDTI1_PB0 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x0) +#define TIMER1_CDTI1_PB1 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x1) +#define TIMER1_CDTI1_PB2 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x2) +#define TIMER1_CDTI1_PB3 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x3) +#define TIMER1_CDTI1_PB4 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x4) +#define TIMER1_CDTI1_PB5 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x5) +#define TIMER1_CDTI1_PB6 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x6) +#define TIMER1_CDTI1_PC0 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x0) +#define TIMER1_CDTI1_PC1 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x1) +#define TIMER1_CDTI1_PC2 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x2) +#define TIMER1_CDTI1_PC3 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x3) +#define TIMER1_CDTI1_PC4 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x4) +#define TIMER1_CDTI1_PC5 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x5) +#define TIMER1_CDTI1_PC6 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x6) +#define TIMER1_CDTI1_PC7 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x7) +#define TIMER1_CDTI1_PC8 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x8) +#define TIMER1_CDTI1_PC9 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x9) +#define TIMER1_CDTI1_PD0 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x0) +#define TIMER1_CDTI1_PD1 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x1) +#define TIMER1_CDTI1_PD2 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x2) +#define TIMER1_CDTI1_PD3 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x3) +#define TIMER1_CDTI1_PD4 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x4) +#define TIMER1_CDTI1_PD5 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x5) +#define TIMER1_CDTI2_PA0 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x0) +#define TIMER1_CDTI2_PA1 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x1) +#define TIMER1_CDTI2_PA2 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x2) +#define TIMER1_CDTI2_PA3 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x3) +#define TIMER1_CDTI2_PA4 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x4) +#define TIMER1_CDTI2_PA5 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x5) +#define TIMER1_CDTI2_PA6 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x6) +#define TIMER1_CDTI2_PA7 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x7) +#define TIMER1_CDTI2_PA8 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x8) +#define TIMER1_CDTI2_PA9 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x9) +#define TIMER1_CDTI2_PA10 SILABS_DBUS_TIMER1_CDTI2(0x0, 0xa) +#define TIMER1_CDTI2_PB0 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x0) +#define TIMER1_CDTI2_PB1 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x1) +#define TIMER1_CDTI2_PB2 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x2) +#define TIMER1_CDTI2_PB3 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x3) +#define TIMER1_CDTI2_PB4 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x4) +#define TIMER1_CDTI2_PB5 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x5) +#define TIMER1_CDTI2_PB6 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x6) +#define TIMER1_CDTI2_PC0 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x0) +#define TIMER1_CDTI2_PC1 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x1) +#define TIMER1_CDTI2_PC2 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x2) +#define TIMER1_CDTI2_PC3 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x3) +#define TIMER1_CDTI2_PC4 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x4) +#define TIMER1_CDTI2_PC5 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x5) +#define TIMER1_CDTI2_PC6 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x6) +#define TIMER1_CDTI2_PC7 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x7) +#define TIMER1_CDTI2_PC8 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x8) +#define TIMER1_CDTI2_PC9 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x9) +#define TIMER1_CDTI2_PD0 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x0) +#define TIMER1_CDTI2_PD1 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x1) +#define TIMER1_CDTI2_PD2 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x2) +#define TIMER1_CDTI2_PD3 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x3) +#define TIMER1_CDTI2_PD4 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x4) +#define TIMER1_CDTI2_PD5 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x5) + +#define TIMER2_CC0_PA0 SILABS_DBUS_TIMER2_CC0(0x0, 0x0) +#define TIMER2_CC0_PA1 SILABS_DBUS_TIMER2_CC0(0x0, 0x1) +#define TIMER2_CC0_PA2 SILABS_DBUS_TIMER2_CC0(0x0, 0x2) +#define TIMER2_CC0_PA3 SILABS_DBUS_TIMER2_CC0(0x0, 0x3) +#define TIMER2_CC0_PA4 SILABS_DBUS_TIMER2_CC0(0x0, 0x4) +#define TIMER2_CC0_PA5 SILABS_DBUS_TIMER2_CC0(0x0, 0x5) +#define TIMER2_CC0_PA6 SILABS_DBUS_TIMER2_CC0(0x0, 0x6) +#define TIMER2_CC0_PA7 SILABS_DBUS_TIMER2_CC0(0x0, 0x7) +#define TIMER2_CC0_PA8 SILABS_DBUS_TIMER2_CC0(0x0, 0x8) +#define TIMER2_CC0_PA9 SILABS_DBUS_TIMER2_CC0(0x0, 0x9) +#define TIMER2_CC0_PA10 SILABS_DBUS_TIMER2_CC0(0x0, 0xa) +#define TIMER2_CC0_PB0 SILABS_DBUS_TIMER2_CC0(0x1, 0x0) +#define TIMER2_CC0_PB1 SILABS_DBUS_TIMER2_CC0(0x1, 0x1) +#define TIMER2_CC0_PB2 SILABS_DBUS_TIMER2_CC0(0x1, 0x2) +#define TIMER2_CC0_PB3 SILABS_DBUS_TIMER2_CC0(0x1, 0x3) +#define TIMER2_CC0_PB4 SILABS_DBUS_TIMER2_CC0(0x1, 0x4) +#define TIMER2_CC0_PB5 SILABS_DBUS_TIMER2_CC0(0x1, 0x5) +#define TIMER2_CC0_PB6 SILABS_DBUS_TIMER2_CC0(0x1, 0x6) +#define TIMER2_CC1_PA0 SILABS_DBUS_TIMER2_CC1(0x0, 0x0) +#define TIMER2_CC1_PA1 SILABS_DBUS_TIMER2_CC1(0x0, 0x1) +#define TIMER2_CC1_PA2 SILABS_DBUS_TIMER2_CC1(0x0, 0x2) +#define TIMER2_CC1_PA3 SILABS_DBUS_TIMER2_CC1(0x0, 0x3) +#define TIMER2_CC1_PA4 SILABS_DBUS_TIMER2_CC1(0x0, 0x4) +#define TIMER2_CC1_PA5 SILABS_DBUS_TIMER2_CC1(0x0, 0x5) +#define TIMER2_CC1_PA6 SILABS_DBUS_TIMER2_CC1(0x0, 0x6) +#define TIMER2_CC1_PA7 SILABS_DBUS_TIMER2_CC1(0x0, 0x7) +#define TIMER2_CC1_PA8 SILABS_DBUS_TIMER2_CC1(0x0, 0x8) +#define TIMER2_CC1_PA9 SILABS_DBUS_TIMER2_CC1(0x0, 0x9) +#define TIMER2_CC1_PA10 SILABS_DBUS_TIMER2_CC1(0x0, 0xa) +#define TIMER2_CC1_PB0 SILABS_DBUS_TIMER2_CC1(0x1, 0x0) +#define TIMER2_CC1_PB1 SILABS_DBUS_TIMER2_CC1(0x1, 0x1) +#define TIMER2_CC1_PB2 SILABS_DBUS_TIMER2_CC1(0x1, 0x2) +#define TIMER2_CC1_PB3 SILABS_DBUS_TIMER2_CC1(0x1, 0x3) +#define TIMER2_CC1_PB4 SILABS_DBUS_TIMER2_CC1(0x1, 0x4) +#define TIMER2_CC1_PB5 SILABS_DBUS_TIMER2_CC1(0x1, 0x5) +#define TIMER2_CC1_PB6 SILABS_DBUS_TIMER2_CC1(0x1, 0x6) +#define TIMER2_CC2_PA0 SILABS_DBUS_TIMER2_CC2(0x0, 0x0) +#define TIMER2_CC2_PA1 SILABS_DBUS_TIMER2_CC2(0x0, 0x1) +#define TIMER2_CC2_PA2 SILABS_DBUS_TIMER2_CC2(0x0, 0x2) +#define TIMER2_CC2_PA3 SILABS_DBUS_TIMER2_CC2(0x0, 0x3) +#define TIMER2_CC2_PA4 SILABS_DBUS_TIMER2_CC2(0x0, 0x4) +#define TIMER2_CC2_PA5 SILABS_DBUS_TIMER2_CC2(0x0, 0x5) +#define TIMER2_CC2_PA6 SILABS_DBUS_TIMER2_CC2(0x0, 0x6) +#define TIMER2_CC2_PA7 SILABS_DBUS_TIMER2_CC2(0x0, 0x7) +#define TIMER2_CC2_PA8 SILABS_DBUS_TIMER2_CC2(0x0, 0x8) +#define TIMER2_CC2_PA9 SILABS_DBUS_TIMER2_CC2(0x0, 0x9) +#define TIMER2_CC2_PA10 SILABS_DBUS_TIMER2_CC2(0x0, 0xa) +#define TIMER2_CC2_PB0 SILABS_DBUS_TIMER2_CC2(0x1, 0x0) +#define TIMER2_CC2_PB1 SILABS_DBUS_TIMER2_CC2(0x1, 0x1) +#define TIMER2_CC2_PB2 SILABS_DBUS_TIMER2_CC2(0x1, 0x2) +#define TIMER2_CC2_PB3 SILABS_DBUS_TIMER2_CC2(0x1, 0x3) +#define TIMER2_CC2_PB4 SILABS_DBUS_TIMER2_CC2(0x1, 0x4) +#define TIMER2_CC2_PB5 SILABS_DBUS_TIMER2_CC2(0x1, 0x5) +#define TIMER2_CC2_PB6 SILABS_DBUS_TIMER2_CC2(0x1, 0x6) +#define TIMER2_CDTI0_PA0 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x0) +#define TIMER2_CDTI0_PA1 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x1) +#define TIMER2_CDTI0_PA2 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x2) +#define TIMER2_CDTI0_PA3 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x3) +#define TIMER2_CDTI0_PA4 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x4) +#define TIMER2_CDTI0_PA5 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x5) +#define TIMER2_CDTI0_PA6 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x6) +#define TIMER2_CDTI0_PA7 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x7) +#define TIMER2_CDTI0_PA8 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x8) +#define TIMER2_CDTI0_PA9 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x9) +#define TIMER2_CDTI0_PA10 SILABS_DBUS_TIMER2_CDTI0(0x0, 0xa) +#define TIMER2_CDTI0_PB0 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x0) +#define TIMER2_CDTI0_PB1 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x1) +#define TIMER2_CDTI0_PB2 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x2) +#define TIMER2_CDTI0_PB3 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x3) +#define TIMER2_CDTI0_PB4 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x4) +#define TIMER2_CDTI0_PB5 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x5) +#define TIMER2_CDTI0_PB6 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x6) +#define TIMER2_CDTI1_PA0 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x0) +#define TIMER2_CDTI1_PA1 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x1) +#define TIMER2_CDTI1_PA2 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x2) +#define TIMER2_CDTI1_PA3 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x3) +#define TIMER2_CDTI1_PA4 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x4) +#define TIMER2_CDTI1_PA5 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x5) +#define TIMER2_CDTI1_PA6 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x6) +#define TIMER2_CDTI1_PA7 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x7) +#define TIMER2_CDTI1_PA8 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x8) +#define TIMER2_CDTI1_PA9 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x9) +#define TIMER2_CDTI1_PA10 SILABS_DBUS_TIMER2_CDTI1(0x0, 0xa) +#define TIMER2_CDTI1_PB0 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x0) +#define TIMER2_CDTI1_PB1 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x1) +#define TIMER2_CDTI1_PB2 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x2) +#define TIMER2_CDTI1_PB3 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x3) +#define TIMER2_CDTI1_PB4 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x4) +#define TIMER2_CDTI1_PB5 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x5) +#define TIMER2_CDTI1_PB6 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x6) +#define TIMER2_CDTI2_PA0 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x0) +#define TIMER2_CDTI2_PA1 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x1) +#define TIMER2_CDTI2_PA2 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x2) +#define TIMER2_CDTI2_PA3 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x3) +#define TIMER2_CDTI2_PA4 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x4) +#define TIMER2_CDTI2_PA5 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x5) +#define TIMER2_CDTI2_PA6 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x6) +#define TIMER2_CDTI2_PA7 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x7) +#define TIMER2_CDTI2_PA8 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x8) +#define TIMER2_CDTI2_PA9 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x9) +#define TIMER2_CDTI2_PA10 SILABS_DBUS_TIMER2_CDTI2(0x0, 0xa) +#define TIMER2_CDTI2_PB0 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x0) +#define TIMER2_CDTI2_PB1 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x1) +#define TIMER2_CDTI2_PB2 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x2) +#define TIMER2_CDTI2_PB3 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x3) +#define TIMER2_CDTI2_PB4 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x4) +#define TIMER2_CDTI2_PB5 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x5) +#define TIMER2_CDTI2_PB6 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x6) + +#define TIMER3_CC0_PC0 SILABS_DBUS_TIMER3_CC0(0x2, 0x0) +#define TIMER3_CC0_PC1 SILABS_DBUS_TIMER3_CC0(0x2, 0x1) +#define TIMER3_CC0_PC2 SILABS_DBUS_TIMER3_CC0(0x2, 0x2) +#define TIMER3_CC0_PC3 SILABS_DBUS_TIMER3_CC0(0x2, 0x3) +#define TIMER3_CC0_PC4 SILABS_DBUS_TIMER3_CC0(0x2, 0x4) +#define TIMER3_CC0_PC5 SILABS_DBUS_TIMER3_CC0(0x2, 0x5) +#define TIMER3_CC0_PC6 SILABS_DBUS_TIMER3_CC0(0x2, 0x6) +#define TIMER3_CC0_PC7 SILABS_DBUS_TIMER3_CC0(0x2, 0x7) +#define TIMER3_CC0_PC8 SILABS_DBUS_TIMER3_CC0(0x2, 0x8) +#define TIMER3_CC0_PC9 SILABS_DBUS_TIMER3_CC0(0x2, 0x9) +#define TIMER3_CC0_PD0 SILABS_DBUS_TIMER3_CC0(0x3, 0x0) +#define TIMER3_CC0_PD1 SILABS_DBUS_TIMER3_CC0(0x3, 0x1) +#define TIMER3_CC0_PD2 SILABS_DBUS_TIMER3_CC0(0x3, 0x2) +#define TIMER3_CC0_PD3 SILABS_DBUS_TIMER3_CC0(0x3, 0x3) +#define TIMER3_CC0_PD4 SILABS_DBUS_TIMER3_CC0(0x3, 0x4) +#define TIMER3_CC0_PD5 SILABS_DBUS_TIMER3_CC0(0x3, 0x5) +#define TIMER3_CC1_PC0 SILABS_DBUS_TIMER3_CC1(0x2, 0x0) +#define TIMER3_CC1_PC1 SILABS_DBUS_TIMER3_CC1(0x2, 0x1) +#define TIMER3_CC1_PC2 SILABS_DBUS_TIMER3_CC1(0x2, 0x2) +#define TIMER3_CC1_PC3 SILABS_DBUS_TIMER3_CC1(0x2, 0x3) +#define TIMER3_CC1_PC4 SILABS_DBUS_TIMER3_CC1(0x2, 0x4) +#define TIMER3_CC1_PC5 SILABS_DBUS_TIMER3_CC1(0x2, 0x5) +#define TIMER3_CC1_PC6 SILABS_DBUS_TIMER3_CC1(0x2, 0x6) +#define TIMER3_CC1_PC7 SILABS_DBUS_TIMER3_CC1(0x2, 0x7) +#define TIMER3_CC1_PC8 SILABS_DBUS_TIMER3_CC1(0x2, 0x8) +#define TIMER3_CC1_PC9 SILABS_DBUS_TIMER3_CC1(0x2, 0x9) +#define TIMER3_CC1_PD0 SILABS_DBUS_TIMER3_CC1(0x3, 0x0) +#define TIMER3_CC1_PD1 SILABS_DBUS_TIMER3_CC1(0x3, 0x1) +#define TIMER3_CC1_PD2 SILABS_DBUS_TIMER3_CC1(0x3, 0x2) +#define TIMER3_CC1_PD3 SILABS_DBUS_TIMER3_CC1(0x3, 0x3) +#define TIMER3_CC1_PD4 SILABS_DBUS_TIMER3_CC1(0x3, 0x4) +#define TIMER3_CC1_PD5 SILABS_DBUS_TIMER3_CC1(0x3, 0x5) +#define TIMER3_CC2_PC0 SILABS_DBUS_TIMER3_CC2(0x2, 0x0) +#define TIMER3_CC2_PC1 SILABS_DBUS_TIMER3_CC2(0x2, 0x1) +#define TIMER3_CC2_PC2 SILABS_DBUS_TIMER3_CC2(0x2, 0x2) +#define TIMER3_CC2_PC3 SILABS_DBUS_TIMER3_CC2(0x2, 0x3) +#define TIMER3_CC2_PC4 SILABS_DBUS_TIMER3_CC2(0x2, 0x4) +#define TIMER3_CC2_PC5 SILABS_DBUS_TIMER3_CC2(0x2, 0x5) +#define TIMER3_CC2_PC6 SILABS_DBUS_TIMER3_CC2(0x2, 0x6) +#define TIMER3_CC2_PC7 SILABS_DBUS_TIMER3_CC2(0x2, 0x7) +#define TIMER3_CC2_PC8 SILABS_DBUS_TIMER3_CC2(0x2, 0x8) +#define TIMER3_CC2_PC9 SILABS_DBUS_TIMER3_CC2(0x2, 0x9) +#define TIMER3_CC2_PD0 SILABS_DBUS_TIMER3_CC2(0x3, 0x0) +#define TIMER3_CC2_PD1 SILABS_DBUS_TIMER3_CC2(0x3, 0x1) +#define TIMER3_CC2_PD2 SILABS_DBUS_TIMER3_CC2(0x3, 0x2) +#define TIMER3_CC2_PD3 SILABS_DBUS_TIMER3_CC2(0x3, 0x3) +#define TIMER3_CC2_PD4 SILABS_DBUS_TIMER3_CC2(0x3, 0x4) +#define TIMER3_CC2_PD5 SILABS_DBUS_TIMER3_CC2(0x3, 0x5) +#define TIMER3_CDTI0_PC0 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x0) +#define TIMER3_CDTI0_PC1 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x1) +#define TIMER3_CDTI0_PC2 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x2) +#define TIMER3_CDTI0_PC3 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x3) +#define TIMER3_CDTI0_PC4 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x4) +#define TIMER3_CDTI0_PC5 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x5) +#define TIMER3_CDTI0_PC6 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x6) +#define TIMER3_CDTI0_PC7 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x7) +#define TIMER3_CDTI0_PC8 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x8) +#define TIMER3_CDTI0_PC9 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x9) +#define TIMER3_CDTI0_PD0 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x0) +#define TIMER3_CDTI0_PD1 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x1) +#define TIMER3_CDTI0_PD2 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x2) +#define TIMER3_CDTI0_PD3 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x3) +#define TIMER3_CDTI0_PD4 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x4) +#define TIMER3_CDTI0_PD5 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x5) +#define TIMER3_CDTI1_PC0 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x0) +#define TIMER3_CDTI1_PC1 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x1) +#define TIMER3_CDTI1_PC2 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x2) +#define TIMER3_CDTI1_PC3 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x3) +#define TIMER3_CDTI1_PC4 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x4) +#define TIMER3_CDTI1_PC5 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x5) +#define TIMER3_CDTI1_PC6 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x6) +#define TIMER3_CDTI1_PC7 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x7) +#define TIMER3_CDTI1_PC8 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x8) +#define TIMER3_CDTI1_PC9 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x9) +#define TIMER3_CDTI1_PD0 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x0) +#define TIMER3_CDTI1_PD1 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x1) +#define TIMER3_CDTI1_PD2 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x2) +#define TIMER3_CDTI1_PD3 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x3) +#define TIMER3_CDTI1_PD4 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x4) +#define TIMER3_CDTI1_PD5 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x5) +#define TIMER3_CDTI2_PC0 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x0) +#define TIMER3_CDTI2_PC1 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x1) +#define TIMER3_CDTI2_PC2 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x2) +#define TIMER3_CDTI2_PC3 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x3) +#define TIMER3_CDTI2_PC4 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x4) +#define TIMER3_CDTI2_PC5 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x5) +#define TIMER3_CDTI2_PC6 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x6) +#define TIMER3_CDTI2_PC7 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x7) +#define TIMER3_CDTI2_PC8 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x8) +#define TIMER3_CDTI2_PC9 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x9) +#define TIMER3_CDTI2_PD0 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x0) +#define TIMER3_CDTI2_PD1 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x1) +#define TIMER3_CDTI2_PD2 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x2) +#define TIMER3_CDTI2_PD3 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x3) +#define TIMER3_CDTI2_PD4 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x4) +#define TIMER3_CDTI2_PD5 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x5) + +#define TIMER4_CC0_PA0 SILABS_DBUS_TIMER4_CC0(0x0, 0x0) +#define TIMER4_CC0_PA1 SILABS_DBUS_TIMER4_CC0(0x0, 0x1) +#define TIMER4_CC0_PA2 SILABS_DBUS_TIMER4_CC0(0x0, 0x2) +#define TIMER4_CC0_PA3 SILABS_DBUS_TIMER4_CC0(0x0, 0x3) +#define TIMER4_CC0_PA4 SILABS_DBUS_TIMER4_CC0(0x0, 0x4) +#define TIMER4_CC0_PA5 SILABS_DBUS_TIMER4_CC0(0x0, 0x5) +#define TIMER4_CC0_PA6 SILABS_DBUS_TIMER4_CC0(0x0, 0x6) +#define TIMER4_CC0_PA7 SILABS_DBUS_TIMER4_CC0(0x0, 0x7) +#define TIMER4_CC0_PA8 SILABS_DBUS_TIMER4_CC0(0x0, 0x8) +#define TIMER4_CC0_PA9 SILABS_DBUS_TIMER4_CC0(0x0, 0x9) +#define TIMER4_CC0_PA10 SILABS_DBUS_TIMER4_CC0(0x0, 0xa) +#define TIMER4_CC0_PB0 SILABS_DBUS_TIMER4_CC0(0x1, 0x0) +#define TIMER4_CC0_PB1 SILABS_DBUS_TIMER4_CC0(0x1, 0x1) +#define TIMER4_CC0_PB2 SILABS_DBUS_TIMER4_CC0(0x1, 0x2) +#define TIMER4_CC0_PB3 SILABS_DBUS_TIMER4_CC0(0x1, 0x3) +#define TIMER4_CC0_PB4 SILABS_DBUS_TIMER4_CC0(0x1, 0x4) +#define TIMER4_CC0_PB5 SILABS_DBUS_TIMER4_CC0(0x1, 0x5) +#define TIMER4_CC0_PB6 SILABS_DBUS_TIMER4_CC0(0x1, 0x6) +#define TIMER4_CC1_PA0 SILABS_DBUS_TIMER4_CC1(0x0, 0x0) +#define TIMER4_CC1_PA1 SILABS_DBUS_TIMER4_CC1(0x0, 0x1) +#define TIMER4_CC1_PA2 SILABS_DBUS_TIMER4_CC1(0x0, 0x2) +#define TIMER4_CC1_PA3 SILABS_DBUS_TIMER4_CC1(0x0, 0x3) +#define TIMER4_CC1_PA4 SILABS_DBUS_TIMER4_CC1(0x0, 0x4) +#define TIMER4_CC1_PA5 SILABS_DBUS_TIMER4_CC1(0x0, 0x5) +#define TIMER4_CC1_PA6 SILABS_DBUS_TIMER4_CC1(0x0, 0x6) +#define TIMER4_CC1_PA7 SILABS_DBUS_TIMER4_CC1(0x0, 0x7) +#define TIMER4_CC1_PA8 SILABS_DBUS_TIMER4_CC1(0x0, 0x8) +#define TIMER4_CC1_PA9 SILABS_DBUS_TIMER4_CC1(0x0, 0x9) +#define TIMER4_CC1_PA10 SILABS_DBUS_TIMER4_CC1(0x0, 0xa) +#define TIMER4_CC1_PB0 SILABS_DBUS_TIMER4_CC1(0x1, 0x0) +#define TIMER4_CC1_PB1 SILABS_DBUS_TIMER4_CC1(0x1, 0x1) +#define TIMER4_CC1_PB2 SILABS_DBUS_TIMER4_CC1(0x1, 0x2) +#define TIMER4_CC1_PB3 SILABS_DBUS_TIMER4_CC1(0x1, 0x3) +#define TIMER4_CC1_PB4 SILABS_DBUS_TIMER4_CC1(0x1, 0x4) +#define TIMER4_CC1_PB5 SILABS_DBUS_TIMER4_CC1(0x1, 0x5) +#define TIMER4_CC1_PB6 SILABS_DBUS_TIMER4_CC1(0x1, 0x6) +#define TIMER4_CC2_PA0 SILABS_DBUS_TIMER4_CC2(0x0, 0x0) +#define TIMER4_CC2_PA1 SILABS_DBUS_TIMER4_CC2(0x0, 0x1) +#define TIMER4_CC2_PA2 SILABS_DBUS_TIMER4_CC2(0x0, 0x2) +#define TIMER4_CC2_PA3 SILABS_DBUS_TIMER4_CC2(0x0, 0x3) +#define TIMER4_CC2_PA4 SILABS_DBUS_TIMER4_CC2(0x0, 0x4) +#define TIMER4_CC2_PA5 SILABS_DBUS_TIMER4_CC2(0x0, 0x5) +#define TIMER4_CC2_PA6 SILABS_DBUS_TIMER4_CC2(0x0, 0x6) +#define TIMER4_CC2_PA7 SILABS_DBUS_TIMER4_CC2(0x0, 0x7) +#define TIMER4_CC2_PA8 SILABS_DBUS_TIMER4_CC2(0x0, 0x8) +#define TIMER4_CC2_PA9 SILABS_DBUS_TIMER4_CC2(0x0, 0x9) +#define TIMER4_CC2_PA10 SILABS_DBUS_TIMER4_CC2(0x0, 0xa) +#define TIMER4_CC2_PB0 SILABS_DBUS_TIMER4_CC2(0x1, 0x0) +#define TIMER4_CC2_PB1 SILABS_DBUS_TIMER4_CC2(0x1, 0x1) +#define TIMER4_CC2_PB2 SILABS_DBUS_TIMER4_CC2(0x1, 0x2) +#define TIMER4_CC2_PB3 SILABS_DBUS_TIMER4_CC2(0x1, 0x3) +#define TIMER4_CC2_PB4 SILABS_DBUS_TIMER4_CC2(0x1, 0x4) +#define TIMER4_CC2_PB5 SILABS_DBUS_TIMER4_CC2(0x1, 0x5) +#define TIMER4_CC2_PB6 SILABS_DBUS_TIMER4_CC2(0x1, 0x6) +#define TIMER4_CDTI0_PA0 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x0) +#define TIMER4_CDTI0_PA1 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x1) +#define TIMER4_CDTI0_PA2 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x2) +#define TIMER4_CDTI0_PA3 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x3) +#define TIMER4_CDTI0_PA4 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x4) +#define TIMER4_CDTI0_PA5 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x5) +#define TIMER4_CDTI0_PA6 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x6) +#define TIMER4_CDTI0_PA7 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x7) +#define TIMER4_CDTI0_PA8 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x8) +#define TIMER4_CDTI0_PA9 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x9) +#define TIMER4_CDTI0_PA10 SILABS_DBUS_TIMER4_CDTI0(0x0, 0xa) +#define TIMER4_CDTI0_PB0 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x0) +#define TIMER4_CDTI0_PB1 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x1) +#define TIMER4_CDTI0_PB2 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x2) +#define TIMER4_CDTI0_PB3 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x3) +#define TIMER4_CDTI0_PB4 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x4) +#define TIMER4_CDTI0_PB5 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x5) +#define TIMER4_CDTI0_PB6 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x6) +#define TIMER4_CDTI1_PA0 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x0) +#define TIMER4_CDTI1_PA1 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x1) +#define TIMER4_CDTI1_PA2 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x2) +#define TIMER4_CDTI1_PA3 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x3) +#define TIMER4_CDTI1_PA4 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x4) +#define TIMER4_CDTI1_PA5 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x5) +#define TIMER4_CDTI1_PA6 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x6) +#define TIMER4_CDTI1_PA7 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x7) +#define TIMER4_CDTI1_PA8 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x8) +#define TIMER4_CDTI1_PA9 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x9) +#define TIMER4_CDTI1_PA10 SILABS_DBUS_TIMER4_CDTI1(0x0, 0xa) +#define TIMER4_CDTI1_PB0 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x0) +#define TIMER4_CDTI1_PB1 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x1) +#define TIMER4_CDTI1_PB2 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x2) +#define TIMER4_CDTI1_PB3 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x3) +#define TIMER4_CDTI1_PB4 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x4) +#define TIMER4_CDTI1_PB5 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x5) +#define TIMER4_CDTI1_PB6 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x6) +#define TIMER4_CDTI2_PA0 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x0) +#define TIMER4_CDTI2_PA1 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x1) +#define TIMER4_CDTI2_PA2 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x2) +#define TIMER4_CDTI2_PA3 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x3) +#define TIMER4_CDTI2_PA4 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x4) +#define TIMER4_CDTI2_PA5 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x5) +#define TIMER4_CDTI2_PA6 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x6) +#define TIMER4_CDTI2_PA7 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x7) +#define TIMER4_CDTI2_PA8 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x8) +#define TIMER4_CDTI2_PA9 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x9) +#define TIMER4_CDTI2_PA10 SILABS_DBUS_TIMER4_CDTI2(0x0, 0xa) +#define TIMER4_CDTI2_PB0 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x0) +#define TIMER4_CDTI2_PB1 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x1) +#define TIMER4_CDTI2_PB2 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x2) +#define TIMER4_CDTI2_PB3 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x3) +#define TIMER4_CDTI2_PB4 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x4) +#define TIMER4_CDTI2_PB5 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x5) +#define TIMER4_CDTI2_PB6 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x6) + +#define USART0_CS_PA0 SILABS_DBUS_USART0_CS(0x0, 0x0) +#define USART0_CS_PA1 SILABS_DBUS_USART0_CS(0x0, 0x1) +#define USART0_CS_PA2 SILABS_DBUS_USART0_CS(0x0, 0x2) +#define USART0_CS_PA3 SILABS_DBUS_USART0_CS(0x0, 0x3) +#define USART0_CS_PA4 SILABS_DBUS_USART0_CS(0x0, 0x4) +#define USART0_CS_PA5 SILABS_DBUS_USART0_CS(0x0, 0x5) +#define USART0_CS_PA6 SILABS_DBUS_USART0_CS(0x0, 0x6) +#define USART0_CS_PA7 SILABS_DBUS_USART0_CS(0x0, 0x7) +#define USART0_CS_PA8 SILABS_DBUS_USART0_CS(0x0, 0x8) +#define USART0_CS_PA9 SILABS_DBUS_USART0_CS(0x0, 0x9) +#define USART0_CS_PA10 SILABS_DBUS_USART0_CS(0x0, 0xa) +#define USART0_CS_PB0 SILABS_DBUS_USART0_CS(0x1, 0x0) +#define USART0_CS_PB1 SILABS_DBUS_USART0_CS(0x1, 0x1) +#define USART0_CS_PB2 SILABS_DBUS_USART0_CS(0x1, 0x2) +#define USART0_CS_PB3 SILABS_DBUS_USART0_CS(0x1, 0x3) +#define USART0_CS_PB4 SILABS_DBUS_USART0_CS(0x1, 0x4) +#define USART0_CS_PB5 SILABS_DBUS_USART0_CS(0x1, 0x5) +#define USART0_CS_PB6 SILABS_DBUS_USART0_CS(0x1, 0x6) +#define USART0_CS_PC0 SILABS_DBUS_USART0_CS(0x2, 0x0) +#define USART0_CS_PC1 SILABS_DBUS_USART0_CS(0x2, 0x1) +#define USART0_CS_PC2 SILABS_DBUS_USART0_CS(0x2, 0x2) +#define USART0_CS_PC3 SILABS_DBUS_USART0_CS(0x2, 0x3) +#define USART0_CS_PC4 SILABS_DBUS_USART0_CS(0x2, 0x4) +#define USART0_CS_PC5 SILABS_DBUS_USART0_CS(0x2, 0x5) +#define USART0_CS_PC6 SILABS_DBUS_USART0_CS(0x2, 0x6) +#define USART0_CS_PC7 SILABS_DBUS_USART0_CS(0x2, 0x7) +#define USART0_CS_PC8 SILABS_DBUS_USART0_CS(0x2, 0x8) +#define USART0_CS_PC9 SILABS_DBUS_USART0_CS(0x2, 0x9) +#define USART0_CS_PD0 SILABS_DBUS_USART0_CS(0x3, 0x0) +#define USART0_CS_PD1 SILABS_DBUS_USART0_CS(0x3, 0x1) +#define USART0_CS_PD2 SILABS_DBUS_USART0_CS(0x3, 0x2) +#define USART0_CS_PD3 SILABS_DBUS_USART0_CS(0x3, 0x3) +#define USART0_CS_PD4 SILABS_DBUS_USART0_CS(0x3, 0x4) +#define USART0_CS_PD5 SILABS_DBUS_USART0_CS(0x3, 0x5) +#define USART0_RTS_PA0 SILABS_DBUS_USART0_RTS(0x0, 0x0) +#define USART0_RTS_PA1 SILABS_DBUS_USART0_RTS(0x0, 0x1) +#define USART0_RTS_PA2 SILABS_DBUS_USART0_RTS(0x0, 0x2) +#define USART0_RTS_PA3 SILABS_DBUS_USART0_RTS(0x0, 0x3) +#define USART0_RTS_PA4 SILABS_DBUS_USART0_RTS(0x0, 0x4) +#define USART0_RTS_PA5 SILABS_DBUS_USART0_RTS(0x0, 0x5) +#define USART0_RTS_PA6 SILABS_DBUS_USART0_RTS(0x0, 0x6) +#define USART0_RTS_PA7 SILABS_DBUS_USART0_RTS(0x0, 0x7) +#define USART0_RTS_PA8 SILABS_DBUS_USART0_RTS(0x0, 0x8) +#define USART0_RTS_PA9 SILABS_DBUS_USART0_RTS(0x0, 0x9) +#define USART0_RTS_PA10 SILABS_DBUS_USART0_RTS(0x0, 0xa) +#define USART0_RTS_PB0 SILABS_DBUS_USART0_RTS(0x1, 0x0) +#define USART0_RTS_PB1 SILABS_DBUS_USART0_RTS(0x1, 0x1) +#define USART0_RTS_PB2 SILABS_DBUS_USART0_RTS(0x1, 0x2) +#define USART0_RTS_PB3 SILABS_DBUS_USART0_RTS(0x1, 0x3) +#define USART0_RTS_PB4 SILABS_DBUS_USART0_RTS(0x1, 0x4) +#define USART0_RTS_PB5 SILABS_DBUS_USART0_RTS(0x1, 0x5) +#define USART0_RTS_PB6 SILABS_DBUS_USART0_RTS(0x1, 0x6) +#define USART0_RTS_PC0 SILABS_DBUS_USART0_RTS(0x2, 0x0) +#define USART0_RTS_PC1 SILABS_DBUS_USART0_RTS(0x2, 0x1) +#define USART0_RTS_PC2 SILABS_DBUS_USART0_RTS(0x2, 0x2) +#define USART0_RTS_PC3 SILABS_DBUS_USART0_RTS(0x2, 0x3) +#define USART0_RTS_PC4 SILABS_DBUS_USART0_RTS(0x2, 0x4) +#define USART0_RTS_PC5 SILABS_DBUS_USART0_RTS(0x2, 0x5) +#define USART0_RTS_PC6 SILABS_DBUS_USART0_RTS(0x2, 0x6) +#define USART0_RTS_PC7 SILABS_DBUS_USART0_RTS(0x2, 0x7) +#define USART0_RTS_PC8 SILABS_DBUS_USART0_RTS(0x2, 0x8) +#define USART0_RTS_PC9 SILABS_DBUS_USART0_RTS(0x2, 0x9) +#define USART0_RTS_PD0 SILABS_DBUS_USART0_RTS(0x3, 0x0) +#define USART0_RTS_PD1 SILABS_DBUS_USART0_RTS(0x3, 0x1) +#define USART0_RTS_PD2 SILABS_DBUS_USART0_RTS(0x3, 0x2) +#define USART0_RTS_PD3 SILABS_DBUS_USART0_RTS(0x3, 0x3) +#define USART0_RTS_PD4 SILABS_DBUS_USART0_RTS(0x3, 0x4) +#define USART0_RTS_PD5 SILABS_DBUS_USART0_RTS(0x3, 0x5) +#define USART0_RX_PA0 SILABS_DBUS_USART0_RX(0x0, 0x0) +#define USART0_RX_PA1 SILABS_DBUS_USART0_RX(0x0, 0x1) +#define USART0_RX_PA2 SILABS_DBUS_USART0_RX(0x0, 0x2) +#define USART0_RX_PA3 SILABS_DBUS_USART0_RX(0x0, 0x3) +#define USART0_RX_PA4 SILABS_DBUS_USART0_RX(0x0, 0x4) +#define USART0_RX_PA5 SILABS_DBUS_USART0_RX(0x0, 0x5) +#define USART0_RX_PA6 SILABS_DBUS_USART0_RX(0x0, 0x6) +#define USART0_RX_PA7 SILABS_DBUS_USART0_RX(0x0, 0x7) +#define USART0_RX_PA8 SILABS_DBUS_USART0_RX(0x0, 0x8) +#define USART0_RX_PA9 SILABS_DBUS_USART0_RX(0x0, 0x9) +#define USART0_RX_PA10 SILABS_DBUS_USART0_RX(0x0, 0xa) +#define USART0_RX_PB0 SILABS_DBUS_USART0_RX(0x1, 0x0) +#define USART0_RX_PB1 SILABS_DBUS_USART0_RX(0x1, 0x1) +#define USART0_RX_PB2 SILABS_DBUS_USART0_RX(0x1, 0x2) +#define USART0_RX_PB3 SILABS_DBUS_USART0_RX(0x1, 0x3) +#define USART0_RX_PB4 SILABS_DBUS_USART0_RX(0x1, 0x4) +#define USART0_RX_PB5 SILABS_DBUS_USART0_RX(0x1, 0x5) +#define USART0_RX_PB6 SILABS_DBUS_USART0_RX(0x1, 0x6) +#define USART0_RX_PC0 SILABS_DBUS_USART0_RX(0x2, 0x0) +#define USART0_RX_PC1 SILABS_DBUS_USART0_RX(0x2, 0x1) +#define USART0_RX_PC2 SILABS_DBUS_USART0_RX(0x2, 0x2) +#define USART0_RX_PC3 SILABS_DBUS_USART0_RX(0x2, 0x3) +#define USART0_RX_PC4 SILABS_DBUS_USART0_RX(0x2, 0x4) +#define USART0_RX_PC5 SILABS_DBUS_USART0_RX(0x2, 0x5) +#define USART0_RX_PC6 SILABS_DBUS_USART0_RX(0x2, 0x6) +#define USART0_RX_PC7 SILABS_DBUS_USART0_RX(0x2, 0x7) +#define USART0_RX_PC8 SILABS_DBUS_USART0_RX(0x2, 0x8) +#define USART0_RX_PC9 SILABS_DBUS_USART0_RX(0x2, 0x9) +#define USART0_RX_PD0 SILABS_DBUS_USART0_RX(0x3, 0x0) +#define USART0_RX_PD1 SILABS_DBUS_USART0_RX(0x3, 0x1) +#define USART0_RX_PD2 SILABS_DBUS_USART0_RX(0x3, 0x2) +#define USART0_RX_PD3 SILABS_DBUS_USART0_RX(0x3, 0x3) +#define USART0_RX_PD4 SILABS_DBUS_USART0_RX(0x3, 0x4) +#define USART0_RX_PD5 SILABS_DBUS_USART0_RX(0x3, 0x5) +#define USART0_CLK_PA0 SILABS_DBUS_USART0_CLK(0x0, 0x0) +#define USART0_CLK_PA1 SILABS_DBUS_USART0_CLK(0x0, 0x1) +#define USART0_CLK_PA2 SILABS_DBUS_USART0_CLK(0x0, 0x2) +#define USART0_CLK_PA3 SILABS_DBUS_USART0_CLK(0x0, 0x3) +#define USART0_CLK_PA4 SILABS_DBUS_USART0_CLK(0x0, 0x4) +#define USART0_CLK_PA5 SILABS_DBUS_USART0_CLK(0x0, 0x5) +#define USART0_CLK_PA6 SILABS_DBUS_USART0_CLK(0x0, 0x6) +#define USART0_CLK_PA7 SILABS_DBUS_USART0_CLK(0x0, 0x7) +#define USART0_CLK_PA8 SILABS_DBUS_USART0_CLK(0x0, 0x8) +#define USART0_CLK_PA9 SILABS_DBUS_USART0_CLK(0x0, 0x9) +#define USART0_CLK_PA10 SILABS_DBUS_USART0_CLK(0x0, 0xa) +#define USART0_CLK_PB0 SILABS_DBUS_USART0_CLK(0x1, 0x0) +#define USART0_CLK_PB1 SILABS_DBUS_USART0_CLK(0x1, 0x1) +#define USART0_CLK_PB2 SILABS_DBUS_USART0_CLK(0x1, 0x2) +#define USART0_CLK_PB3 SILABS_DBUS_USART0_CLK(0x1, 0x3) +#define USART0_CLK_PB4 SILABS_DBUS_USART0_CLK(0x1, 0x4) +#define USART0_CLK_PB5 SILABS_DBUS_USART0_CLK(0x1, 0x5) +#define USART0_CLK_PB6 SILABS_DBUS_USART0_CLK(0x1, 0x6) +#define USART0_CLK_PC0 SILABS_DBUS_USART0_CLK(0x2, 0x0) +#define USART0_CLK_PC1 SILABS_DBUS_USART0_CLK(0x2, 0x1) +#define USART0_CLK_PC2 SILABS_DBUS_USART0_CLK(0x2, 0x2) +#define USART0_CLK_PC3 SILABS_DBUS_USART0_CLK(0x2, 0x3) +#define USART0_CLK_PC4 SILABS_DBUS_USART0_CLK(0x2, 0x4) +#define USART0_CLK_PC5 SILABS_DBUS_USART0_CLK(0x2, 0x5) +#define USART0_CLK_PC6 SILABS_DBUS_USART0_CLK(0x2, 0x6) +#define USART0_CLK_PC7 SILABS_DBUS_USART0_CLK(0x2, 0x7) +#define USART0_CLK_PC8 SILABS_DBUS_USART0_CLK(0x2, 0x8) +#define USART0_CLK_PC9 SILABS_DBUS_USART0_CLK(0x2, 0x9) +#define USART0_CLK_PD0 SILABS_DBUS_USART0_CLK(0x3, 0x0) +#define USART0_CLK_PD1 SILABS_DBUS_USART0_CLK(0x3, 0x1) +#define USART0_CLK_PD2 SILABS_DBUS_USART0_CLK(0x3, 0x2) +#define USART0_CLK_PD3 SILABS_DBUS_USART0_CLK(0x3, 0x3) +#define USART0_CLK_PD4 SILABS_DBUS_USART0_CLK(0x3, 0x4) +#define USART0_CLK_PD5 SILABS_DBUS_USART0_CLK(0x3, 0x5) +#define USART0_TX_PA0 SILABS_DBUS_USART0_TX(0x0, 0x0) +#define USART0_TX_PA1 SILABS_DBUS_USART0_TX(0x0, 0x1) +#define USART0_TX_PA2 SILABS_DBUS_USART0_TX(0x0, 0x2) +#define USART0_TX_PA3 SILABS_DBUS_USART0_TX(0x0, 0x3) +#define USART0_TX_PA4 SILABS_DBUS_USART0_TX(0x0, 0x4) +#define USART0_TX_PA5 SILABS_DBUS_USART0_TX(0x0, 0x5) +#define USART0_TX_PA6 SILABS_DBUS_USART0_TX(0x0, 0x6) +#define USART0_TX_PA7 SILABS_DBUS_USART0_TX(0x0, 0x7) +#define USART0_TX_PA8 SILABS_DBUS_USART0_TX(0x0, 0x8) +#define USART0_TX_PA9 SILABS_DBUS_USART0_TX(0x0, 0x9) +#define USART0_TX_PA10 SILABS_DBUS_USART0_TX(0x0, 0xa) +#define USART0_TX_PB0 SILABS_DBUS_USART0_TX(0x1, 0x0) +#define USART0_TX_PB1 SILABS_DBUS_USART0_TX(0x1, 0x1) +#define USART0_TX_PB2 SILABS_DBUS_USART0_TX(0x1, 0x2) +#define USART0_TX_PB3 SILABS_DBUS_USART0_TX(0x1, 0x3) +#define USART0_TX_PB4 SILABS_DBUS_USART0_TX(0x1, 0x4) +#define USART0_TX_PB5 SILABS_DBUS_USART0_TX(0x1, 0x5) +#define USART0_TX_PB6 SILABS_DBUS_USART0_TX(0x1, 0x6) +#define USART0_TX_PC0 SILABS_DBUS_USART0_TX(0x2, 0x0) +#define USART0_TX_PC1 SILABS_DBUS_USART0_TX(0x2, 0x1) +#define USART0_TX_PC2 SILABS_DBUS_USART0_TX(0x2, 0x2) +#define USART0_TX_PC3 SILABS_DBUS_USART0_TX(0x2, 0x3) +#define USART0_TX_PC4 SILABS_DBUS_USART0_TX(0x2, 0x4) +#define USART0_TX_PC5 SILABS_DBUS_USART0_TX(0x2, 0x5) +#define USART0_TX_PC6 SILABS_DBUS_USART0_TX(0x2, 0x6) +#define USART0_TX_PC7 SILABS_DBUS_USART0_TX(0x2, 0x7) +#define USART0_TX_PC8 SILABS_DBUS_USART0_TX(0x2, 0x8) +#define USART0_TX_PC9 SILABS_DBUS_USART0_TX(0x2, 0x9) +#define USART0_TX_PD0 SILABS_DBUS_USART0_TX(0x3, 0x0) +#define USART0_TX_PD1 SILABS_DBUS_USART0_TX(0x3, 0x1) +#define USART0_TX_PD2 SILABS_DBUS_USART0_TX(0x3, 0x2) +#define USART0_TX_PD3 SILABS_DBUS_USART0_TX(0x3, 0x3) +#define USART0_TX_PD4 SILABS_DBUS_USART0_TX(0x3, 0x4) +#define USART0_TX_PD5 SILABS_DBUS_USART0_TX(0x3, 0x5) +#define USART0_CTS_PA0 SILABS_DBUS_USART0_CTS(0x0, 0x0) +#define USART0_CTS_PA1 SILABS_DBUS_USART0_CTS(0x0, 0x1) +#define USART0_CTS_PA2 SILABS_DBUS_USART0_CTS(0x0, 0x2) +#define USART0_CTS_PA3 SILABS_DBUS_USART0_CTS(0x0, 0x3) +#define USART0_CTS_PA4 SILABS_DBUS_USART0_CTS(0x0, 0x4) +#define USART0_CTS_PA5 SILABS_DBUS_USART0_CTS(0x0, 0x5) +#define USART0_CTS_PA6 SILABS_DBUS_USART0_CTS(0x0, 0x6) +#define USART0_CTS_PA7 SILABS_DBUS_USART0_CTS(0x0, 0x7) +#define USART0_CTS_PA8 SILABS_DBUS_USART0_CTS(0x0, 0x8) +#define USART0_CTS_PA9 SILABS_DBUS_USART0_CTS(0x0, 0x9) +#define USART0_CTS_PA10 SILABS_DBUS_USART0_CTS(0x0, 0xa) +#define USART0_CTS_PB0 SILABS_DBUS_USART0_CTS(0x1, 0x0) +#define USART0_CTS_PB1 SILABS_DBUS_USART0_CTS(0x1, 0x1) +#define USART0_CTS_PB2 SILABS_DBUS_USART0_CTS(0x1, 0x2) +#define USART0_CTS_PB3 SILABS_DBUS_USART0_CTS(0x1, 0x3) +#define USART0_CTS_PB4 SILABS_DBUS_USART0_CTS(0x1, 0x4) +#define USART0_CTS_PB5 SILABS_DBUS_USART0_CTS(0x1, 0x5) +#define USART0_CTS_PB6 SILABS_DBUS_USART0_CTS(0x1, 0x6) +#define USART0_CTS_PC0 SILABS_DBUS_USART0_CTS(0x2, 0x0) +#define USART0_CTS_PC1 SILABS_DBUS_USART0_CTS(0x2, 0x1) +#define USART0_CTS_PC2 SILABS_DBUS_USART0_CTS(0x2, 0x2) +#define USART0_CTS_PC3 SILABS_DBUS_USART0_CTS(0x2, 0x3) +#define USART0_CTS_PC4 SILABS_DBUS_USART0_CTS(0x2, 0x4) +#define USART0_CTS_PC5 SILABS_DBUS_USART0_CTS(0x2, 0x5) +#define USART0_CTS_PC6 SILABS_DBUS_USART0_CTS(0x2, 0x6) +#define USART0_CTS_PC7 SILABS_DBUS_USART0_CTS(0x2, 0x7) +#define USART0_CTS_PC8 SILABS_DBUS_USART0_CTS(0x2, 0x8) +#define USART0_CTS_PC9 SILABS_DBUS_USART0_CTS(0x2, 0x9) +#define USART0_CTS_PD0 SILABS_DBUS_USART0_CTS(0x3, 0x0) +#define USART0_CTS_PD1 SILABS_DBUS_USART0_CTS(0x3, 0x1) +#define USART0_CTS_PD2 SILABS_DBUS_USART0_CTS(0x3, 0x2) +#define USART0_CTS_PD3 SILABS_DBUS_USART0_CTS(0x3, 0x3) +#define USART0_CTS_PD4 SILABS_DBUS_USART0_CTS(0x3, 0x4) +#define USART0_CTS_PD5 SILABS_DBUS_USART0_CTS(0x3, 0x5) + +#define ABUS_AEVEN0_IADC0 SILABS_ABUS(0x0, 0x0, 0x1) +#define ABUS_AEVEN0_ACMP0 SILABS_ABUS(0x0, 0x0, 0x2) +#define ABUS_AEVEN0_ACMP1 SILABS_ABUS(0x0, 0x0, 0x3) +#define ABUS_AEVEN0_VDAC0CH0 SILABS_ABUS(0x0, 0x0, 0x4) +#define ABUS_AEVEN1_IADC0 SILABS_ABUS(0x0, 0x1, 0x1) +#define ABUS_AEVEN1_ACMP0 SILABS_ABUS(0x0, 0x1, 0x2) +#define ABUS_AEVEN1_ACMP1 SILABS_ABUS(0x0, 0x1, 0x3) +#define ABUS_AEVEN1_VDAC0CH1 SILABS_ABUS(0x0, 0x1, 0x4) +#define ABUS_AODD0_IADC0 SILABS_ABUS(0x0, 0x2, 0x1) +#define ABUS_AODD0_ACMP0 SILABS_ABUS(0x0, 0x2, 0x2) +#define ABUS_AODD0_ACMP1 SILABS_ABUS(0x0, 0x2, 0x3) +#define ABUS_AODD0_VDAC0CH0 SILABS_ABUS(0x0, 0x2, 0x4) +#define ABUS_AODD1_IADC0 SILABS_ABUS(0x0, 0x3, 0x1) +#define ABUS_AODD1_ACMP0 SILABS_ABUS(0x0, 0x3, 0x2) +#define ABUS_AODD1_ACMP1 SILABS_ABUS(0x0, 0x3, 0x3) +#define ABUS_AODD1_VDAC0CH1 SILABS_ABUS(0x0, 0x3, 0x4) +#define ABUS_BEVEN0_IADC0 SILABS_ABUS(0x1, 0x0, 0x1) +#define ABUS_BEVEN0_ACMP0 SILABS_ABUS(0x1, 0x0, 0x2) +#define ABUS_BEVEN0_ACMP1 SILABS_ABUS(0x1, 0x0, 0x3) +#define ABUS_BEVEN0_VDAC0CH0 SILABS_ABUS(0x1, 0x0, 0x4) +#define ABUS_BEVEN1_IADC0 SILABS_ABUS(0x1, 0x1, 0x1) +#define ABUS_BEVEN1_ACMP0 SILABS_ABUS(0x1, 0x1, 0x2) +#define ABUS_BEVEN1_ACMP1 SILABS_ABUS(0x1, 0x1, 0x3) +#define ABUS_BEVEN1_VDAC0CH1 SILABS_ABUS(0x1, 0x1, 0x4) +#define ABUS_BODD0_IADC0 SILABS_ABUS(0x1, 0x2, 0x1) +#define ABUS_BODD0_ACMP0 SILABS_ABUS(0x1, 0x2, 0x2) +#define ABUS_BODD0_ACMP1 SILABS_ABUS(0x1, 0x2, 0x3) +#define ABUS_BODD0_VDAC0CH0 SILABS_ABUS(0x1, 0x2, 0x4) +#define ABUS_BODD1_IADC0 SILABS_ABUS(0x1, 0x3, 0x1) +#define ABUS_BODD1_ACMP0 SILABS_ABUS(0x1, 0x3, 0x2) +#define ABUS_BODD1_ACMP1 SILABS_ABUS(0x1, 0x3, 0x3) +#define ABUS_BODD1_VDAC0CH1 SILABS_ABUS(0x1, 0x3, 0x4) +#define ABUS_CDEVEN0_IADC0 SILABS_ABUS(0x2, 0x0, 0x1) +#define ABUS_CDEVEN0_ACMP0 SILABS_ABUS(0x2, 0x0, 0x2) +#define ABUS_CDEVEN0_ACMP1 SILABS_ABUS(0x2, 0x0, 0x3) +#define ABUS_CDEVEN0_VDAC0CH0 SILABS_ABUS(0x2, 0x0, 0x4) +#define ABUS_CDEVEN1_IADC0 SILABS_ABUS(0x2, 0x1, 0x1) +#define ABUS_CDEVEN1_ACMP0 SILABS_ABUS(0x2, 0x1, 0x2) +#define ABUS_CDEVEN1_ACMP1 SILABS_ABUS(0x2, 0x1, 0x3) +#define ABUS_CDEVEN1_VDAC0CH1 SILABS_ABUS(0x2, 0x1, 0x4) +#define ABUS_CDODD0_IADC0 SILABS_ABUS(0x2, 0x2, 0x1) +#define ABUS_CDODD0_ACMP0 SILABS_ABUS(0x2, 0x2, 0x2) +#define ABUS_CDODD0_ACMP1 SILABS_ABUS(0x2, 0x2, 0x3) +#define ABUS_CDODD0_VDAC0CH0 SILABS_ABUS(0x2, 0x2, 0x4) +#define ABUS_CDODD1_IADC0 SILABS_ABUS(0x2, 0x3, 0x1) +#define ABUS_CDODD1_ACMP0 SILABS_ABUS(0x2, 0x3, 0x2) +#define ABUS_CDODD1_ACMP1 SILABS_ABUS(0x2, 0x3, 0x3) +#define ABUS_CDODD1_VDAC0CH1 SILABS_ABUS(0x2, 0x3, 0x4) + +#endif /* ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG23_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs/xg24-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/silabs/xg24-pinctrl.h index 3bcbd1328914f..ff67fc06fc766 100644 --- a/include/zephyr/dt-bindings/pinctrl/silabs/xg24-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/silabs/xg24-pinctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Silicon Laboratories Inc. + * Copyright (c) 2025 Silicon Laboratories Inc. * SPDX-License-Identifier: Apache-2.0 * * Pin Control for Silicon Labs XG24 devices @@ -2700,4 +2700,65 @@ #define USART0_CTS_PD4 SILABS_DBUS_USART0_CTS(0x3, 0x4) #define USART0_CTS_PD5 SILABS_DBUS_USART0_CTS(0x3, 0x5) +#define ABUS_AEVEN0_IADC0 SILABS_ABUS(0x0, 0x0, 0x1) +#define ABUS_AEVEN0_ACMP0 SILABS_ABUS(0x0, 0x0, 0x2) +#define ABUS_AEVEN0_ACMP1 SILABS_ABUS(0x0, 0x0, 0x3) +#define ABUS_AEVEN0_VDAC0CH0 SILABS_ABUS(0x0, 0x0, 0x4) +#define ABUS_AEVEN0_VDAC1CH0 SILABS_ABUS(0x0, 0x0, 0x5) +#define ABUS_AEVEN1_IADC0 SILABS_ABUS(0x0, 0x1, 0x1) +#define ABUS_AEVEN1_ACMP0 SILABS_ABUS(0x0, 0x1, 0x2) +#define ABUS_AEVEN1_ACMP1 SILABS_ABUS(0x0, 0x1, 0x3) +#define ABUS_AEVEN1_VDAC0CH1 SILABS_ABUS(0x0, 0x1, 0x4) +#define ABUS_AEVEN1_VDAC1CH1 SILABS_ABUS(0x0, 0x1, 0x5) +#define ABUS_AODD0_IADC0 SILABS_ABUS(0x0, 0x2, 0x1) +#define ABUS_AODD0_ACMP0 SILABS_ABUS(0x0, 0x2, 0x2) +#define ABUS_AODD0_ACMP1 SILABS_ABUS(0x0, 0x2, 0x3) +#define ABUS_AODD0_VDAC0CH0 SILABS_ABUS(0x0, 0x2, 0x4) +#define ABUS_AODD0_VDAC1CH0 SILABS_ABUS(0x0, 0x2, 0x5) +#define ABUS_AODD1_IADC0 SILABS_ABUS(0x0, 0x3, 0x1) +#define ABUS_AODD1_ACMP0 SILABS_ABUS(0x0, 0x3, 0x2) +#define ABUS_AODD1_ACMP1 SILABS_ABUS(0x0, 0x3, 0x3) +#define ABUS_AODD1_VDAC0CH1 SILABS_ABUS(0x0, 0x3, 0x4) +#define ABUS_AODD1_VDAC1CH1 SILABS_ABUS(0x0, 0x3, 0x5) +#define ABUS_BEVEN0_IADC0 SILABS_ABUS(0x1, 0x0, 0x1) +#define ABUS_BEVEN0_ACMP0 SILABS_ABUS(0x1, 0x0, 0x2) +#define ABUS_BEVEN0_ACMP1 SILABS_ABUS(0x1, 0x0, 0x3) +#define ABUS_BEVEN0_VDAC0CH0 SILABS_ABUS(0x1, 0x0, 0x4) +#define ABUS_BEVEN0_VDAC1CH0 SILABS_ABUS(0x1, 0x0, 0x5) +#define ABUS_BEVEN1_IADC0 SILABS_ABUS(0x1, 0x1, 0x1) +#define ABUS_BEVEN1_ACMP0 SILABS_ABUS(0x1, 0x1, 0x2) +#define ABUS_BEVEN1_ACMP1 SILABS_ABUS(0x1, 0x1, 0x3) +#define ABUS_BEVEN1_VDAC0CH1 SILABS_ABUS(0x1, 0x1, 0x4) +#define ABUS_BEVEN1_VDAC1CH1 SILABS_ABUS(0x1, 0x1, 0x5) +#define ABUS_BODD0_IADC0 SILABS_ABUS(0x1, 0x2, 0x1) +#define ABUS_BODD0_ACMP0 SILABS_ABUS(0x1, 0x2, 0x2) +#define ABUS_BODD0_ACMP1 SILABS_ABUS(0x1, 0x2, 0x3) +#define ABUS_BODD0_VDAC0CH0 SILABS_ABUS(0x1, 0x2, 0x4) +#define ABUS_BODD0_VDAC1CH0 SILABS_ABUS(0x1, 0x2, 0x5) +#define ABUS_BODD1_IADC0 SILABS_ABUS(0x1, 0x3, 0x1) +#define ABUS_BODD1_ACMP0 SILABS_ABUS(0x1, 0x3, 0x2) +#define ABUS_BODD1_ACMP1 SILABS_ABUS(0x1, 0x3, 0x3) +#define ABUS_BODD1_VDAC0CH1 SILABS_ABUS(0x1, 0x3, 0x4) +#define ABUS_BODD1_VDAC1CH1 SILABS_ABUS(0x1, 0x3, 0x5) +#define ABUS_CDEVEN0_IADC0 SILABS_ABUS(0x2, 0x0, 0x1) +#define ABUS_CDEVEN0_ACMP0 SILABS_ABUS(0x2, 0x0, 0x2) +#define ABUS_CDEVEN0_ACMP1 SILABS_ABUS(0x2, 0x0, 0x3) +#define ABUS_CDEVEN0_VDAC0CH0 SILABS_ABUS(0x2, 0x0, 0x4) +#define ABUS_CDEVEN0_VDAC1CH0 SILABS_ABUS(0x2, 0x0, 0x5) +#define ABUS_CDEVEN1_IADC0 SILABS_ABUS(0x2, 0x1, 0x1) +#define ABUS_CDEVEN1_ACMP0 SILABS_ABUS(0x2, 0x1, 0x2) +#define ABUS_CDEVEN1_ACMP1 SILABS_ABUS(0x2, 0x1, 0x3) +#define ABUS_CDEVEN1_VDAC0CH1 SILABS_ABUS(0x2, 0x1, 0x4) +#define ABUS_CDEVEN1_VDAC1CH1 SILABS_ABUS(0x2, 0x1, 0x5) +#define ABUS_CDODD0_IADC0 SILABS_ABUS(0x2, 0x2, 0x1) +#define ABUS_CDODD0_ACMP0 SILABS_ABUS(0x2, 0x2, 0x2) +#define ABUS_CDODD0_ACMP1 SILABS_ABUS(0x2, 0x2, 0x3) +#define ABUS_CDODD0_VDAC0CH0 SILABS_ABUS(0x2, 0x2, 0x4) +#define ABUS_CDODD0_VDAC1CH0 SILABS_ABUS(0x2, 0x2, 0x5) +#define ABUS_CDODD1_IADC0 SILABS_ABUS(0x2, 0x3, 0x1) +#define ABUS_CDODD1_ACMP0 SILABS_ABUS(0x2, 0x3, 0x2) +#define ABUS_CDODD1_ACMP1 SILABS_ABUS(0x2, 0x3, 0x3) +#define ABUS_CDODD1_VDAC0CH1 SILABS_ABUS(0x2, 0x3, 0x4) +#define ABUS_CDODD1_VDAC1CH1 SILABS_ABUS(0x2, 0x3, 0x5) + #endif /* ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG24_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs/xg27-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/silabs/xg27-pinctrl.h index a111ce6cc8be4..90932d52e7444 100644 --- a/include/zephyr/dt-bindings/pinctrl/silabs/xg27-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/silabs/xg27-pinctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Silicon Laboratories Inc. + * Copyright (c) 2025 Silicon Laboratories Inc. * SPDX-License-Identifier: Apache-2.0 * * Pin Control for Silicon Labs XG27 devices @@ -1872,4 +1872,30 @@ #define USART1_CTS_PB3 SILABS_DBUS_USART1_CTS(0x1, 0x3) #define USART1_CTS_PB4 SILABS_DBUS_USART1_CTS(0x1, 0x4) +#define ABUS_AEVEN0_IADC0 SILABS_ABUS(0x0, 0x0, 0x1) +#define ABUS_AEVEN0_ACMP0 SILABS_ABUS(0x0, 0x0, 0x2) +#define ABUS_AEVEN1_IADC0 SILABS_ABUS(0x0, 0x1, 0x1) +#define ABUS_AEVEN1_ACMP0 SILABS_ABUS(0x0, 0x1, 0x2) +#define ABUS_AODD0_IADC0 SILABS_ABUS(0x0, 0x2, 0x1) +#define ABUS_AODD0_ACMP0 SILABS_ABUS(0x0, 0x2, 0x2) +#define ABUS_AODD1_IADC0 SILABS_ABUS(0x0, 0x3, 0x1) +#define ABUS_AODD1_ACMP0 SILABS_ABUS(0x0, 0x3, 0x2) +#define ABUS_BEVEN0_IADC0 SILABS_ABUS(0x1, 0x0, 0x1) +#define ABUS_BEVEN0_ACMP0 SILABS_ABUS(0x1, 0x0, 0x2) +#define ABUS_BEVEN1_IADC0 SILABS_ABUS(0x1, 0x1, 0x1) +#define ABUS_BEVEN1_ACMP0 SILABS_ABUS(0x1, 0x1, 0x2) +#define ABUS_BODD0_IADC0 SILABS_ABUS(0x1, 0x2, 0x1) +#define ABUS_BODD0_ACMP0 SILABS_ABUS(0x1, 0x2, 0x2) +#define ABUS_BODD1_IADC0 SILABS_ABUS(0x1, 0x3, 0x1) +#define ABUS_BODD1_ACMP0 SILABS_ABUS(0x1, 0x3, 0x2) +#define ABUS_CDEVEN0_IADC0 SILABS_ABUS(0x2, 0x0, 0x1) +#define ABUS_CDEVEN0_ACMP0 SILABS_ABUS(0x2, 0x0, 0x2) +#define ABUS_CDEVEN1_IADC0 SILABS_ABUS(0x2, 0x1, 0x1) +#define ABUS_CDEVEN1_ACMP0 SILABS_ABUS(0x2, 0x1, 0x2) +#define ABUS_CDODD0_IADC0 SILABS_ABUS(0x2, 0x2, 0x1) +#define ABUS_CDODD0_ACMP0 SILABS_ABUS(0x2, 0x2, 0x2) +#define ABUS_CDODD0_PMON SILABS_ABUS(0x2, 0x2, 0xc) +#define ABUS_CDODD1_IADC0 SILABS_ABUS(0x2, 0x3, 0x1) +#define ABUS_CDODD1_ACMP0 SILABS_ABUS(0x2, 0x3, 0x2) + #endif /* ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG27_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/silabs/xg29-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/silabs/xg29-pinctrl.h new file mode 100644 index 0000000000000..2bb51bb9a90f4 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/silabs/xg29-pinctrl.h @@ -0,0 +1,2064 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + * + * Pin Control for Silicon Labs XG29 devices + * + * This file was generated by the script gen_pinctrl.py in the hal_silabs module. + * Do not manually edit. + */ + +#ifndef ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG29_PINCTRL_H_ +#define ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG29_PINCTRL_H_ + +#include + +#define SILABS_DBUS_ACMP0_ACMPOUT(port, pin) SILABS_DBUS(port, pin, 4, 1, 0, 1) + +#define SILABS_DBUS_CMU_CLKOUT0(port, pin) SILABS_DBUS(port, pin, 7, 1, 0, 2) +#define SILABS_DBUS_CMU_CLKOUT1(port, pin) SILABS_DBUS(port, pin, 7, 1, 1, 3) +#define SILABS_DBUS_CMU_CLKOUT2(port, pin) SILABS_DBUS(port, pin, 7, 1, 2, 4) +#define SILABS_DBUS_CMU_CLKIN0(port, pin) SILABS_DBUS(port, pin, 7, 0, 0, 1) + +#define SILABS_DBUS_EUSART0_CS(port, pin) SILABS_DBUS(port, pin, 19, 1, 0, 1) +#define SILABS_DBUS_EUSART0_RTS(port, pin) SILABS_DBUS(port, pin, 19, 1, 1, 3) +#define SILABS_DBUS_EUSART0_RX(port, pin) SILABS_DBUS(port, pin, 19, 1, 2, 4) +#define SILABS_DBUS_EUSART0_SCLK(port, pin) SILABS_DBUS(port, pin, 19, 1, 3, 5) +#define SILABS_DBUS_EUSART0_TX(port, pin) SILABS_DBUS(port, pin, 19, 1, 4, 6) +#define SILABS_DBUS_EUSART0_CTS(port, pin) SILABS_DBUS(port, pin, 19, 0, 0, 2) + +#define SILABS_DBUS_EUSART1_CS(port, pin) SILABS_DBUS(port, pin, 27, 1, 0, 1) +#define SILABS_DBUS_EUSART1_RTS(port, pin) SILABS_DBUS(port, pin, 27, 1, 1, 3) +#define SILABS_DBUS_EUSART1_RX(port, pin) SILABS_DBUS(port, pin, 27, 1, 2, 4) +#define SILABS_DBUS_EUSART1_SCLK(port, pin) SILABS_DBUS(port, pin, 27, 1, 3, 5) +#define SILABS_DBUS_EUSART1_TX(port, pin) SILABS_DBUS(port, pin, 27, 1, 4, 6) +#define SILABS_DBUS_EUSART1_CTS(port, pin) SILABS_DBUS(port, pin, 27, 0, 0, 2) + +#define SILABS_DBUS_PTI_DCLK(port, pin) SILABS_DBUS(port, pin, 35, 1, 0, 1) +#define SILABS_DBUS_PTI_DFRAME(port, pin) SILABS_DBUS(port, pin, 35, 1, 1, 2) +#define SILABS_DBUS_PTI_DOUT(port, pin) SILABS_DBUS(port, pin, 35, 1, 2, 3) + +#define SILABS_DBUS_I2C0_SCL(port, pin) SILABS_DBUS(port, pin, 40, 1, 0, 1) +#define SILABS_DBUS_I2C0_SDA(port, pin) SILABS_DBUS(port, pin, 40, 1, 1, 2) + +#define SILABS_DBUS_I2C1_SCL(port, pin) SILABS_DBUS(port, pin, 44, 1, 0, 1) +#define SILABS_DBUS_I2C1_SDA(port, pin) SILABS_DBUS(port, pin, 44, 1, 1, 2) + +#define SILABS_DBUS_LETIMER0_OUT0(port, pin) SILABS_DBUS(port, pin, 48, 1, 0, 1) +#define SILABS_DBUS_LETIMER0_OUT1(port, pin) SILABS_DBUS(port, pin, 48, 1, 1, 2) + +#define SILABS_DBUS_MODEM_ANT0(port, pin) SILABS_DBUS(port, pin, 52, 1, 0, 1) +#define SILABS_DBUS_MODEM_ANT1(port, pin) SILABS_DBUS(port, pin, 52, 1, 1, 2) +#define SILABS_DBUS_MODEM_ANTROLLOVER(port, pin) SILABS_DBUS(port, pin, 52, 1, 2, 3) +#define SILABS_DBUS_MODEM_ANTRR0(port, pin) SILABS_DBUS(port, pin, 52, 1, 3, 4) +#define SILABS_DBUS_MODEM_ANTRR1(port, pin) SILABS_DBUS(port, pin, 52, 1, 4, 5) +#define SILABS_DBUS_MODEM_ANTRR2(port, pin) SILABS_DBUS(port, pin, 52, 1, 5, 6) +#define SILABS_DBUS_MODEM_ANTRR3(port, pin) SILABS_DBUS(port, pin, 52, 1, 6, 7) +#define SILABS_DBUS_MODEM_ANTRR4(port, pin) SILABS_DBUS(port, pin, 52, 1, 7, 8) +#define SILABS_DBUS_MODEM_ANTRR5(port, pin) SILABS_DBUS(port, pin, 52, 1, 8, 9) +#define SILABS_DBUS_MODEM_ANTSWEN(port, pin) SILABS_DBUS(port, pin, 52, 1, 9, 10) +#define SILABS_DBUS_MODEM_ANTSWUS(port, pin) SILABS_DBUS(port, pin, 52, 1, 10, 11) +#define SILABS_DBUS_MODEM_ANTTRIG(port, pin) SILABS_DBUS(port, pin, 52, 1, 11, 12) +#define SILABS_DBUS_MODEM_ANTTRIGSTOP(port, pin) SILABS_DBUS(port, pin, 52, 1, 12, 13) +#define SILABS_DBUS_MODEM_DCLK(port, pin) SILABS_DBUS(port, pin, 52, 1, 13, 14) +#define SILABS_DBUS_MODEM_DOUT(port, pin) SILABS_DBUS(port, pin, 52, 1, 14, 16) +#define SILABS_DBUS_MODEM_DIN(port, pin) SILABS_DBUS(port, pin, 52, 0, 0, 15) + +#define SILABS_DBUS_PDM_CLK(port, pin) SILABS_DBUS(port, pin, 70, 1, 0, 1) +#define SILABS_DBUS_PDM_DAT0(port, pin) SILABS_DBUS(port, pin, 70, 0, 0, 2) +#define SILABS_DBUS_PDM_DAT1(port, pin) SILABS_DBUS(port, pin, 70, 0, 0, 3) + +#define SILABS_DBUS_PRS0_ASYNCH0(port, pin) SILABS_DBUS(port, pin, 75, 1, 0, 1) +#define SILABS_DBUS_PRS0_ASYNCH1(port, pin) SILABS_DBUS(port, pin, 75, 1, 1, 2) +#define SILABS_DBUS_PRS0_ASYNCH2(port, pin) SILABS_DBUS(port, pin, 75, 1, 2, 3) +#define SILABS_DBUS_PRS0_ASYNCH3(port, pin) SILABS_DBUS(port, pin, 75, 1, 3, 4) +#define SILABS_DBUS_PRS0_ASYNCH4(port, pin) SILABS_DBUS(port, pin, 75, 1, 4, 5) +#define SILABS_DBUS_PRS0_ASYNCH5(port, pin) SILABS_DBUS(port, pin, 75, 1, 5, 6) +#define SILABS_DBUS_PRS0_ASYNCH6(port, pin) SILABS_DBUS(port, pin, 75, 1, 6, 7) +#define SILABS_DBUS_PRS0_ASYNCH7(port, pin) SILABS_DBUS(port, pin, 75, 1, 7, 8) +#define SILABS_DBUS_PRS0_ASYNCH8(port, pin) SILABS_DBUS(port, pin, 75, 1, 8, 9) +#define SILABS_DBUS_PRS0_ASYNCH9(port, pin) SILABS_DBUS(port, pin, 75, 1, 9, 10) +#define SILABS_DBUS_PRS0_ASYNCH10(port, pin) SILABS_DBUS(port, pin, 75, 1, 10, 11) +#define SILABS_DBUS_PRS0_ASYNCH11(port, pin) SILABS_DBUS(port, pin, 75, 1, 11, 12) +#define SILABS_DBUS_PRS0_SYNCH0(port, pin) SILABS_DBUS(port, pin, 75, 1, 12, 13) +#define SILABS_DBUS_PRS0_SYNCH1(port, pin) SILABS_DBUS(port, pin, 75, 1, 13, 14) +#define SILABS_DBUS_PRS0_SYNCH2(port, pin) SILABS_DBUS(port, pin, 75, 1, 14, 15) +#define SILABS_DBUS_PRS0_SYNCH3(port, pin) SILABS_DBUS(port, pin, 75, 1, 15, 16) + +#define SILABS_DBUS_TIMER0_CC0(port, pin) SILABS_DBUS(port, pin, 93, 1, 0, 1) +#define SILABS_DBUS_TIMER0_CC1(port, pin) SILABS_DBUS(port, pin, 93, 1, 1, 2) +#define SILABS_DBUS_TIMER0_CC2(port, pin) SILABS_DBUS(port, pin, 93, 1, 2, 3) +#define SILABS_DBUS_TIMER0_CDTI0(port, pin) SILABS_DBUS(port, pin, 93, 1, 3, 4) +#define SILABS_DBUS_TIMER0_CDTI1(port, pin) SILABS_DBUS(port, pin, 93, 1, 4, 5) +#define SILABS_DBUS_TIMER0_CDTI2(port, pin) SILABS_DBUS(port, pin, 93, 1, 5, 6) + +#define SILABS_DBUS_TIMER1_CC0(port, pin) SILABS_DBUS(port, pin, 101, 1, 0, 1) +#define SILABS_DBUS_TIMER1_CC1(port, pin) SILABS_DBUS(port, pin, 101, 1, 1, 2) +#define SILABS_DBUS_TIMER1_CC2(port, pin) SILABS_DBUS(port, pin, 101, 1, 2, 3) +#define SILABS_DBUS_TIMER1_CDTI0(port, pin) SILABS_DBUS(port, pin, 101, 1, 3, 4) +#define SILABS_DBUS_TIMER1_CDTI1(port, pin) SILABS_DBUS(port, pin, 101, 1, 4, 5) +#define SILABS_DBUS_TIMER1_CDTI2(port, pin) SILABS_DBUS(port, pin, 101, 1, 5, 6) + +#define SILABS_DBUS_TIMER2_CC0(port, pin) SILABS_DBUS(port, pin, 109, 1, 0, 1) +#define SILABS_DBUS_TIMER2_CC1(port, pin) SILABS_DBUS(port, pin, 109, 1, 1, 2) +#define SILABS_DBUS_TIMER2_CC2(port, pin) SILABS_DBUS(port, pin, 109, 1, 2, 3) +#define SILABS_DBUS_TIMER2_CDTI0(port, pin) SILABS_DBUS(port, pin, 109, 1, 3, 4) +#define SILABS_DBUS_TIMER2_CDTI1(port, pin) SILABS_DBUS(port, pin, 109, 1, 4, 5) +#define SILABS_DBUS_TIMER2_CDTI2(port, pin) SILABS_DBUS(port, pin, 109, 1, 5, 6) + +#define SILABS_DBUS_TIMER3_CC0(port, pin) SILABS_DBUS(port, pin, 117, 1, 0, 1) +#define SILABS_DBUS_TIMER3_CC1(port, pin) SILABS_DBUS(port, pin, 117, 1, 1, 2) +#define SILABS_DBUS_TIMER3_CC2(port, pin) SILABS_DBUS(port, pin, 117, 1, 2, 3) +#define SILABS_DBUS_TIMER3_CDTI0(port, pin) SILABS_DBUS(port, pin, 117, 1, 3, 4) +#define SILABS_DBUS_TIMER3_CDTI1(port, pin) SILABS_DBUS(port, pin, 117, 1, 4, 5) +#define SILABS_DBUS_TIMER3_CDTI2(port, pin) SILABS_DBUS(port, pin, 117, 1, 5, 6) + +#define SILABS_DBUS_TIMER4_CC0(port, pin) SILABS_DBUS(port, pin, 125, 1, 0, 1) +#define SILABS_DBUS_TIMER4_CC1(port, pin) SILABS_DBUS(port, pin, 125, 1, 1, 2) +#define SILABS_DBUS_TIMER4_CC2(port, pin) SILABS_DBUS(port, pin, 125, 1, 2, 3) +#define SILABS_DBUS_TIMER4_CDTI0(port, pin) SILABS_DBUS(port, pin, 125, 1, 3, 4) +#define SILABS_DBUS_TIMER4_CDTI1(port, pin) SILABS_DBUS(port, pin, 125, 1, 4, 5) +#define SILABS_DBUS_TIMER4_CDTI2(port, pin) SILABS_DBUS(port, pin, 125, 1, 5, 6) + +#define SILABS_DBUS_USART0_CS(port, pin) SILABS_DBUS(port, pin, 133, 1, 0, 1) +#define SILABS_DBUS_USART0_RTS(port, pin) SILABS_DBUS(port, pin, 133, 1, 1, 3) +#define SILABS_DBUS_USART0_RX(port, pin) SILABS_DBUS(port, pin, 133, 1, 2, 4) +#define SILABS_DBUS_USART0_CLK(port, pin) SILABS_DBUS(port, pin, 133, 1, 3, 5) +#define SILABS_DBUS_USART0_TX(port, pin) SILABS_DBUS(port, pin, 133, 1, 4, 6) +#define SILABS_DBUS_USART0_CTS(port, pin) SILABS_DBUS(port, pin, 133, 0, 0, 2) + +#define SILABS_DBUS_USART1_CS(port, pin) SILABS_DBUS(port, pin, 141, 1, 0, 1) +#define SILABS_DBUS_USART1_RTS(port, pin) SILABS_DBUS(port, pin, 141, 1, 1, 3) +#define SILABS_DBUS_USART1_RX(port, pin) SILABS_DBUS(port, pin, 141, 1, 2, 4) +#define SILABS_DBUS_USART1_CLK(port, pin) SILABS_DBUS(port, pin, 141, 1, 3, 5) +#define SILABS_DBUS_USART1_TX(port, pin) SILABS_DBUS(port, pin, 141, 1, 4, 6) +#define SILABS_DBUS_USART1_CTS(port, pin) SILABS_DBUS(port, pin, 141, 0, 0, 2) + +#define ACMP0_ACMPOUT_PA0 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x0) +#define ACMP0_ACMPOUT_PA1 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x1) +#define ACMP0_ACMPOUT_PA2 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x2) +#define ACMP0_ACMPOUT_PA3 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x3) +#define ACMP0_ACMPOUT_PA4 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x4) +#define ACMP0_ACMPOUT_PA5 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x5) +#define ACMP0_ACMPOUT_PA6 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x6) +#define ACMP0_ACMPOUT_PA7 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x7) +#define ACMP0_ACMPOUT_PA8 SILABS_DBUS_ACMP0_ACMPOUT(0x0, 0x8) +#define ACMP0_ACMPOUT_PB0 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x0) +#define ACMP0_ACMPOUT_PB1 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x1) +#define ACMP0_ACMPOUT_PB2 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x2) +#define ACMP0_ACMPOUT_PB3 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x3) +#define ACMP0_ACMPOUT_PB4 SILABS_DBUS_ACMP0_ACMPOUT(0x1, 0x4) +#define ACMP0_ACMPOUT_PC0 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x0) +#define ACMP0_ACMPOUT_PC1 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x1) +#define ACMP0_ACMPOUT_PC2 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x2) +#define ACMP0_ACMPOUT_PC3 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x3) +#define ACMP0_ACMPOUT_PC4 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x4) +#define ACMP0_ACMPOUT_PC5 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x5) +#define ACMP0_ACMPOUT_PC6 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x6) +#define ACMP0_ACMPOUT_PC7 SILABS_DBUS_ACMP0_ACMPOUT(0x2, 0x7) +#define ACMP0_ACMPOUT_PD0 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x0) +#define ACMP0_ACMPOUT_PD1 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x1) +#define ACMP0_ACMPOUT_PD2 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x2) +#define ACMP0_ACMPOUT_PD3 SILABS_DBUS_ACMP0_ACMPOUT(0x3, 0x3) + +#define CMU_CLKOUT0_PC0 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x0) +#define CMU_CLKOUT0_PC1 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x1) +#define CMU_CLKOUT0_PC2 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x2) +#define CMU_CLKOUT0_PC3 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x3) +#define CMU_CLKOUT0_PC4 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x4) +#define CMU_CLKOUT0_PC5 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x5) +#define CMU_CLKOUT0_PC6 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x6) +#define CMU_CLKOUT0_PC7 SILABS_DBUS_CMU_CLKOUT0(0x2, 0x7) +#define CMU_CLKOUT0_PD0 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x0) +#define CMU_CLKOUT0_PD1 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x1) +#define CMU_CLKOUT0_PD2 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x2) +#define CMU_CLKOUT0_PD3 SILABS_DBUS_CMU_CLKOUT0(0x3, 0x3) +#define CMU_CLKOUT1_PC0 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x0) +#define CMU_CLKOUT1_PC1 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x1) +#define CMU_CLKOUT1_PC2 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x2) +#define CMU_CLKOUT1_PC3 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x3) +#define CMU_CLKOUT1_PC4 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x4) +#define CMU_CLKOUT1_PC5 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x5) +#define CMU_CLKOUT1_PC6 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x6) +#define CMU_CLKOUT1_PC7 SILABS_DBUS_CMU_CLKOUT1(0x2, 0x7) +#define CMU_CLKOUT1_PD0 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x0) +#define CMU_CLKOUT1_PD1 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x1) +#define CMU_CLKOUT1_PD2 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x2) +#define CMU_CLKOUT1_PD3 SILABS_DBUS_CMU_CLKOUT1(0x3, 0x3) +#define CMU_CLKOUT2_PA0 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x0) +#define CMU_CLKOUT2_PA1 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x1) +#define CMU_CLKOUT2_PA2 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x2) +#define CMU_CLKOUT2_PA3 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x3) +#define CMU_CLKOUT2_PA4 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x4) +#define CMU_CLKOUT2_PA5 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x5) +#define CMU_CLKOUT2_PA6 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x6) +#define CMU_CLKOUT2_PA7 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x7) +#define CMU_CLKOUT2_PA8 SILABS_DBUS_CMU_CLKOUT2(0x0, 0x8) +#define CMU_CLKOUT2_PB0 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x0) +#define CMU_CLKOUT2_PB1 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x1) +#define CMU_CLKOUT2_PB2 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x2) +#define CMU_CLKOUT2_PB3 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x3) +#define CMU_CLKOUT2_PB4 SILABS_DBUS_CMU_CLKOUT2(0x1, 0x4) +#define CMU_CLKIN0_PC0 SILABS_DBUS_CMU_CLKIN0(0x2, 0x0) +#define CMU_CLKIN0_PC1 SILABS_DBUS_CMU_CLKIN0(0x2, 0x1) +#define CMU_CLKIN0_PC2 SILABS_DBUS_CMU_CLKIN0(0x2, 0x2) +#define CMU_CLKIN0_PC3 SILABS_DBUS_CMU_CLKIN0(0x2, 0x3) +#define CMU_CLKIN0_PC4 SILABS_DBUS_CMU_CLKIN0(0x2, 0x4) +#define CMU_CLKIN0_PC5 SILABS_DBUS_CMU_CLKIN0(0x2, 0x5) +#define CMU_CLKIN0_PC6 SILABS_DBUS_CMU_CLKIN0(0x2, 0x6) +#define CMU_CLKIN0_PC7 SILABS_DBUS_CMU_CLKIN0(0x2, 0x7) +#define CMU_CLKIN0_PD0 SILABS_DBUS_CMU_CLKIN0(0x3, 0x0) +#define CMU_CLKIN0_PD1 SILABS_DBUS_CMU_CLKIN0(0x3, 0x1) +#define CMU_CLKIN0_PD2 SILABS_DBUS_CMU_CLKIN0(0x3, 0x2) +#define CMU_CLKIN0_PD3 SILABS_DBUS_CMU_CLKIN0(0x3, 0x3) + +#define EUSART0_CS_PA0 SILABS_DBUS_EUSART0_CS(0x0, 0x0) +#define EUSART0_CS_PA1 SILABS_DBUS_EUSART0_CS(0x0, 0x1) +#define EUSART0_CS_PA2 SILABS_DBUS_EUSART0_CS(0x0, 0x2) +#define EUSART0_CS_PA3 SILABS_DBUS_EUSART0_CS(0x0, 0x3) +#define EUSART0_CS_PA4 SILABS_DBUS_EUSART0_CS(0x0, 0x4) +#define EUSART0_CS_PA5 SILABS_DBUS_EUSART0_CS(0x0, 0x5) +#define EUSART0_CS_PA6 SILABS_DBUS_EUSART0_CS(0x0, 0x6) +#define EUSART0_CS_PA7 SILABS_DBUS_EUSART0_CS(0x0, 0x7) +#define EUSART0_CS_PA8 SILABS_DBUS_EUSART0_CS(0x0, 0x8) +#define EUSART0_CS_PB0 SILABS_DBUS_EUSART0_CS(0x1, 0x0) +#define EUSART0_CS_PB1 SILABS_DBUS_EUSART0_CS(0x1, 0x1) +#define EUSART0_CS_PB2 SILABS_DBUS_EUSART0_CS(0x1, 0x2) +#define EUSART0_CS_PB3 SILABS_DBUS_EUSART0_CS(0x1, 0x3) +#define EUSART0_CS_PB4 SILABS_DBUS_EUSART0_CS(0x1, 0x4) +#define EUSART0_CS_PC0 SILABS_DBUS_EUSART0_CS(0x2, 0x0) +#define EUSART0_CS_PC1 SILABS_DBUS_EUSART0_CS(0x2, 0x1) +#define EUSART0_CS_PC2 SILABS_DBUS_EUSART0_CS(0x2, 0x2) +#define EUSART0_CS_PC3 SILABS_DBUS_EUSART0_CS(0x2, 0x3) +#define EUSART0_CS_PC4 SILABS_DBUS_EUSART0_CS(0x2, 0x4) +#define EUSART0_CS_PC5 SILABS_DBUS_EUSART0_CS(0x2, 0x5) +#define EUSART0_CS_PC6 SILABS_DBUS_EUSART0_CS(0x2, 0x6) +#define EUSART0_CS_PC7 SILABS_DBUS_EUSART0_CS(0x2, 0x7) +#define EUSART0_CS_PD0 SILABS_DBUS_EUSART0_CS(0x3, 0x0) +#define EUSART0_CS_PD1 SILABS_DBUS_EUSART0_CS(0x3, 0x1) +#define EUSART0_CS_PD2 SILABS_DBUS_EUSART0_CS(0x3, 0x2) +#define EUSART0_CS_PD3 SILABS_DBUS_EUSART0_CS(0x3, 0x3) +#define EUSART0_RTS_PA0 SILABS_DBUS_EUSART0_RTS(0x0, 0x0) +#define EUSART0_RTS_PA1 SILABS_DBUS_EUSART0_RTS(0x0, 0x1) +#define EUSART0_RTS_PA2 SILABS_DBUS_EUSART0_RTS(0x0, 0x2) +#define EUSART0_RTS_PA3 SILABS_DBUS_EUSART0_RTS(0x0, 0x3) +#define EUSART0_RTS_PA4 SILABS_DBUS_EUSART0_RTS(0x0, 0x4) +#define EUSART0_RTS_PA5 SILABS_DBUS_EUSART0_RTS(0x0, 0x5) +#define EUSART0_RTS_PA6 SILABS_DBUS_EUSART0_RTS(0x0, 0x6) +#define EUSART0_RTS_PA7 SILABS_DBUS_EUSART0_RTS(0x0, 0x7) +#define EUSART0_RTS_PA8 SILABS_DBUS_EUSART0_RTS(0x0, 0x8) +#define EUSART0_RTS_PB0 SILABS_DBUS_EUSART0_RTS(0x1, 0x0) +#define EUSART0_RTS_PB1 SILABS_DBUS_EUSART0_RTS(0x1, 0x1) +#define EUSART0_RTS_PB2 SILABS_DBUS_EUSART0_RTS(0x1, 0x2) +#define EUSART0_RTS_PB3 SILABS_DBUS_EUSART0_RTS(0x1, 0x3) +#define EUSART0_RTS_PB4 SILABS_DBUS_EUSART0_RTS(0x1, 0x4) +#define EUSART0_RTS_PC0 SILABS_DBUS_EUSART0_RTS(0x2, 0x0) +#define EUSART0_RTS_PC1 SILABS_DBUS_EUSART0_RTS(0x2, 0x1) +#define EUSART0_RTS_PC2 SILABS_DBUS_EUSART0_RTS(0x2, 0x2) +#define EUSART0_RTS_PC3 SILABS_DBUS_EUSART0_RTS(0x2, 0x3) +#define EUSART0_RTS_PC4 SILABS_DBUS_EUSART0_RTS(0x2, 0x4) +#define EUSART0_RTS_PC5 SILABS_DBUS_EUSART0_RTS(0x2, 0x5) +#define EUSART0_RTS_PC6 SILABS_DBUS_EUSART0_RTS(0x2, 0x6) +#define EUSART0_RTS_PC7 SILABS_DBUS_EUSART0_RTS(0x2, 0x7) +#define EUSART0_RTS_PD0 SILABS_DBUS_EUSART0_RTS(0x3, 0x0) +#define EUSART0_RTS_PD1 SILABS_DBUS_EUSART0_RTS(0x3, 0x1) +#define EUSART0_RTS_PD2 SILABS_DBUS_EUSART0_RTS(0x3, 0x2) +#define EUSART0_RTS_PD3 SILABS_DBUS_EUSART0_RTS(0x3, 0x3) +#define EUSART0_RX_PA0 SILABS_DBUS_EUSART0_RX(0x0, 0x0) +#define EUSART0_RX_PA1 SILABS_DBUS_EUSART0_RX(0x0, 0x1) +#define EUSART0_RX_PA2 SILABS_DBUS_EUSART0_RX(0x0, 0x2) +#define EUSART0_RX_PA3 SILABS_DBUS_EUSART0_RX(0x0, 0x3) +#define EUSART0_RX_PA4 SILABS_DBUS_EUSART0_RX(0x0, 0x4) +#define EUSART0_RX_PA5 SILABS_DBUS_EUSART0_RX(0x0, 0x5) +#define EUSART0_RX_PA6 SILABS_DBUS_EUSART0_RX(0x0, 0x6) +#define EUSART0_RX_PA7 SILABS_DBUS_EUSART0_RX(0x0, 0x7) +#define EUSART0_RX_PA8 SILABS_DBUS_EUSART0_RX(0x0, 0x8) +#define EUSART0_RX_PB0 SILABS_DBUS_EUSART0_RX(0x1, 0x0) +#define EUSART0_RX_PB1 SILABS_DBUS_EUSART0_RX(0x1, 0x1) +#define EUSART0_RX_PB2 SILABS_DBUS_EUSART0_RX(0x1, 0x2) +#define EUSART0_RX_PB3 SILABS_DBUS_EUSART0_RX(0x1, 0x3) +#define EUSART0_RX_PB4 SILABS_DBUS_EUSART0_RX(0x1, 0x4) +#define EUSART0_RX_PC0 SILABS_DBUS_EUSART0_RX(0x2, 0x0) +#define EUSART0_RX_PC1 SILABS_DBUS_EUSART0_RX(0x2, 0x1) +#define EUSART0_RX_PC2 SILABS_DBUS_EUSART0_RX(0x2, 0x2) +#define EUSART0_RX_PC3 SILABS_DBUS_EUSART0_RX(0x2, 0x3) +#define EUSART0_RX_PC4 SILABS_DBUS_EUSART0_RX(0x2, 0x4) +#define EUSART0_RX_PC5 SILABS_DBUS_EUSART0_RX(0x2, 0x5) +#define EUSART0_RX_PC6 SILABS_DBUS_EUSART0_RX(0x2, 0x6) +#define EUSART0_RX_PC7 SILABS_DBUS_EUSART0_RX(0x2, 0x7) +#define EUSART0_RX_PD0 SILABS_DBUS_EUSART0_RX(0x3, 0x0) +#define EUSART0_RX_PD1 SILABS_DBUS_EUSART0_RX(0x3, 0x1) +#define EUSART0_RX_PD2 SILABS_DBUS_EUSART0_RX(0x3, 0x2) +#define EUSART0_RX_PD3 SILABS_DBUS_EUSART0_RX(0x3, 0x3) +#define EUSART0_SCLK_PA0 SILABS_DBUS_EUSART0_SCLK(0x0, 0x0) +#define EUSART0_SCLK_PA1 SILABS_DBUS_EUSART0_SCLK(0x0, 0x1) +#define EUSART0_SCLK_PA2 SILABS_DBUS_EUSART0_SCLK(0x0, 0x2) +#define EUSART0_SCLK_PA3 SILABS_DBUS_EUSART0_SCLK(0x0, 0x3) +#define EUSART0_SCLK_PA4 SILABS_DBUS_EUSART0_SCLK(0x0, 0x4) +#define EUSART0_SCLK_PA5 SILABS_DBUS_EUSART0_SCLK(0x0, 0x5) +#define EUSART0_SCLK_PA6 SILABS_DBUS_EUSART0_SCLK(0x0, 0x6) +#define EUSART0_SCLK_PA7 SILABS_DBUS_EUSART0_SCLK(0x0, 0x7) +#define EUSART0_SCLK_PA8 SILABS_DBUS_EUSART0_SCLK(0x0, 0x8) +#define EUSART0_SCLK_PB0 SILABS_DBUS_EUSART0_SCLK(0x1, 0x0) +#define EUSART0_SCLK_PB1 SILABS_DBUS_EUSART0_SCLK(0x1, 0x1) +#define EUSART0_SCLK_PB2 SILABS_DBUS_EUSART0_SCLK(0x1, 0x2) +#define EUSART0_SCLK_PB3 SILABS_DBUS_EUSART0_SCLK(0x1, 0x3) +#define EUSART0_SCLK_PB4 SILABS_DBUS_EUSART0_SCLK(0x1, 0x4) +#define EUSART0_SCLK_PC0 SILABS_DBUS_EUSART0_SCLK(0x2, 0x0) +#define EUSART0_SCLK_PC1 SILABS_DBUS_EUSART0_SCLK(0x2, 0x1) +#define EUSART0_SCLK_PC2 SILABS_DBUS_EUSART0_SCLK(0x2, 0x2) +#define EUSART0_SCLK_PC3 SILABS_DBUS_EUSART0_SCLK(0x2, 0x3) +#define EUSART0_SCLK_PC4 SILABS_DBUS_EUSART0_SCLK(0x2, 0x4) +#define EUSART0_SCLK_PC5 SILABS_DBUS_EUSART0_SCLK(0x2, 0x5) +#define EUSART0_SCLK_PC6 SILABS_DBUS_EUSART0_SCLK(0x2, 0x6) +#define EUSART0_SCLK_PC7 SILABS_DBUS_EUSART0_SCLK(0x2, 0x7) +#define EUSART0_SCLK_PD0 SILABS_DBUS_EUSART0_SCLK(0x3, 0x0) +#define EUSART0_SCLK_PD1 SILABS_DBUS_EUSART0_SCLK(0x3, 0x1) +#define EUSART0_SCLK_PD2 SILABS_DBUS_EUSART0_SCLK(0x3, 0x2) +#define EUSART0_SCLK_PD3 SILABS_DBUS_EUSART0_SCLK(0x3, 0x3) +#define EUSART0_TX_PA0 SILABS_DBUS_EUSART0_TX(0x0, 0x0) +#define EUSART0_TX_PA1 SILABS_DBUS_EUSART0_TX(0x0, 0x1) +#define EUSART0_TX_PA2 SILABS_DBUS_EUSART0_TX(0x0, 0x2) +#define EUSART0_TX_PA3 SILABS_DBUS_EUSART0_TX(0x0, 0x3) +#define EUSART0_TX_PA4 SILABS_DBUS_EUSART0_TX(0x0, 0x4) +#define EUSART0_TX_PA5 SILABS_DBUS_EUSART0_TX(0x0, 0x5) +#define EUSART0_TX_PA6 SILABS_DBUS_EUSART0_TX(0x0, 0x6) +#define EUSART0_TX_PA7 SILABS_DBUS_EUSART0_TX(0x0, 0x7) +#define EUSART0_TX_PA8 SILABS_DBUS_EUSART0_TX(0x0, 0x8) +#define EUSART0_TX_PB0 SILABS_DBUS_EUSART0_TX(0x1, 0x0) +#define EUSART0_TX_PB1 SILABS_DBUS_EUSART0_TX(0x1, 0x1) +#define EUSART0_TX_PB2 SILABS_DBUS_EUSART0_TX(0x1, 0x2) +#define EUSART0_TX_PB3 SILABS_DBUS_EUSART0_TX(0x1, 0x3) +#define EUSART0_TX_PB4 SILABS_DBUS_EUSART0_TX(0x1, 0x4) +#define EUSART0_TX_PC0 SILABS_DBUS_EUSART0_TX(0x2, 0x0) +#define EUSART0_TX_PC1 SILABS_DBUS_EUSART0_TX(0x2, 0x1) +#define EUSART0_TX_PC2 SILABS_DBUS_EUSART0_TX(0x2, 0x2) +#define EUSART0_TX_PC3 SILABS_DBUS_EUSART0_TX(0x2, 0x3) +#define EUSART0_TX_PC4 SILABS_DBUS_EUSART0_TX(0x2, 0x4) +#define EUSART0_TX_PC5 SILABS_DBUS_EUSART0_TX(0x2, 0x5) +#define EUSART0_TX_PC6 SILABS_DBUS_EUSART0_TX(0x2, 0x6) +#define EUSART0_TX_PC7 SILABS_DBUS_EUSART0_TX(0x2, 0x7) +#define EUSART0_TX_PD0 SILABS_DBUS_EUSART0_TX(0x3, 0x0) +#define EUSART0_TX_PD1 SILABS_DBUS_EUSART0_TX(0x3, 0x1) +#define EUSART0_TX_PD2 SILABS_DBUS_EUSART0_TX(0x3, 0x2) +#define EUSART0_TX_PD3 SILABS_DBUS_EUSART0_TX(0x3, 0x3) +#define EUSART0_CTS_PA0 SILABS_DBUS_EUSART0_CTS(0x0, 0x0) +#define EUSART0_CTS_PA1 SILABS_DBUS_EUSART0_CTS(0x0, 0x1) +#define EUSART0_CTS_PA2 SILABS_DBUS_EUSART0_CTS(0x0, 0x2) +#define EUSART0_CTS_PA3 SILABS_DBUS_EUSART0_CTS(0x0, 0x3) +#define EUSART0_CTS_PA4 SILABS_DBUS_EUSART0_CTS(0x0, 0x4) +#define EUSART0_CTS_PA5 SILABS_DBUS_EUSART0_CTS(0x0, 0x5) +#define EUSART0_CTS_PA6 SILABS_DBUS_EUSART0_CTS(0x0, 0x6) +#define EUSART0_CTS_PA7 SILABS_DBUS_EUSART0_CTS(0x0, 0x7) +#define EUSART0_CTS_PA8 SILABS_DBUS_EUSART0_CTS(0x0, 0x8) +#define EUSART0_CTS_PB0 SILABS_DBUS_EUSART0_CTS(0x1, 0x0) +#define EUSART0_CTS_PB1 SILABS_DBUS_EUSART0_CTS(0x1, 0x1) +#define EUSART0_CTS_PB2 SILABS_DBUS_EUSART0_CTS(0x1, 0x2) +#define EUSART0_CTS_PB3 SILABS_DBUS_EUSART0_CTS(0x1, 0x3) +#define EUSART0_CTS_PB4 SILABS_DBUS_EUSART0_CTS(0x1, 0x4) +#define EUSART0_CTS_PC0 SILABS_DBUS_EUSART0_CTS(0x2, 0x0) +#define EUSART0_CTS_PC1 SILABS_DBUS_EUSART0_CTS(0x2, 0x1) +#define EUSART0_CTS_PC2 SILABS_DBUS_EUSART0_CTS(0x2, 0x2) +#define EUSART0_CTS_PC3 SILABS_DBUS_EUSART0_CTS(0x2, 0x3) +#define EUSART0_CTS_PC4 SILABS_DBUS_EUSART0_CTS(0x2, 0x4) +#define EUSART0_CTS_PC5 SILABS_DBUS_EUSART0_CTS(0x2, 0x5) +#define EUSART0_CTS_PC6 SILABS_DBUS_EUSART0_CTS(0x2, 0x6) +#define EUSART0_CTS_PC7 SILABS_DBUS_EUSART0_CTS(0x2, 0x7) +#define EUSART0_CTS_PD0 SILABS_DBUS_EUSART0_CTS(0x3, 0x0) +#define EUSART0_CTS_PD1 SILABS_DBUS_EUSART0_CTS(0x3, 0x1) +#define EUSART0_CTS_PD2 SILABS_DBUS_EUSART0_CTS(0x3, 0x2) +#define EUSART0_CTS_PD3 SILABS_DBUS_EUSART0_CTS(0x3, 0x3) + +#define EUSART1_CS_PA0 SILABS_DBUS_EUSART1_CS(0x0, 0x0) +#define EUSART1_CS_PA1 SILABS_DBUS_EUSART1_CS(0x0, 0x1) +#define EUSART1_CS_PA2 SILABS_DBUS_EUSART1_CS(0x0, 0x2) +#define EUSART1_CS_PA3 SILABS_DBUS_EUSART1_CS(0x0, 0x3) +#define EUSART1_CS_PA4 SILABS_DBUS_EUSART1_CS(0x0, 0x4) +#define EUSART1_CS_PA5 SILABS_DBUS_EUSART1_CS(0x0, 0x5) +#define EUSART1_CS_PA6 SILABS_DBUS_EUSART1_CS(0x0, 0x6) +#define EUSART1_CS_PA7 SILABS_DBUS_EUSART1_CS(0x0, 0x7) +#define EUSART1_CS_PA8 SILABS_DBUS_EUSART1_CS(0x0, 0x8) +#define EUSART1_CS_PB0 SILABS_DBUS_EUSART1_CS(0x1, 0x0) +#define EUSART1_CS_PB1 SILABS_DBUS_EUSART1_CS(0x1, 0x1) +#define EUSART1_CS_PB2 SILABS_DBUS_EUSART1_CS(0x1, 0x2) +#define EUSART1_CS_PB3 SILABS_DBUS_EUSART1_CS(0x1, 0x3) +#define EUSART1_CS_PB4 SILABS_DBUS_EUSART1_CS(0x1, 0x4) +#define EUSART1_CS_PC0 SILABS_DBUS_EUSART1_CS(0x2, 0x0) +#define EUSART1_CS_PC1 SILABS_DBUS_EUSART1_CS(0x2, 0x1) +#define EUSART1_CS_PC2 SILABS_DBUS_EUSART1_CS(0x2, 0x2) +#define EUSART1_CS_PC3 SILABS_DBUS_EUSART1_CS(0x2, 0x3) +#define EUSART1_CS_PC4 SILABS_DBUS_EUSART1_CS(0x2, 0x4) +#define EUSART1_CS_PC5 SILABS_DBUS_EUSART1_CS(0x2, 0x5) +#define EUSART1_CS_PC6 SILABS_DBUS_EUSART1_CS(0x2, 0x6) +#define EUSART1_CS_PC7 SILABS_DBUS_EUSART1_CS(0x2, 0x7) +#define EUSART1_CS_PD0 SILABS_DBUS_EUSART1_CS(0x3, 0x0) +#define EUSART1_CS_PD1 SILABS_DBUS_EUSART1_CS(0x3, 0x1) +#define EUSART1_CS_PD2 SILABS_DBUS_EUSART1_CS(0x3, 0x2) +#define EUSART1_CS_PD3 SILABS_DBUS_EUSART1_CS(0x3, 0x3) +#define EUSART1_RTS_PA0 SILABS_DBUS_EUSART1_RTS(0x0, 0x0) +#define EUSART1_RTS_PA1 SILABS_DBUS_EUSART1_RTS(0x0, 0x1) +#define EUSART1_RTS_PA2 SILABS_DBUS_EUSART1_RTS(0x0, 0x2) +#define EUSART1_RTS_PA3 SILABS_DBUS_EUSART1_RTS(0x0, 0x3) +#define EUSART1_RTS_PA4 SILABS_DBUS_EUSART1_RTS(0x0, 0x4) +#define EUSART1_RTS_PA5 SILABS_DBUS_EUSART1_RTS(0x0, 0x5) +#define EUSART1_RTS_PA6 SILABS_DBUS_EUSART1_RTS(0x0, 0x6) +#define EUSART1_RTS_PA7 SILABS_DBUS_EUSART1_RTS(0x0, 0x7) +#define EUSART1_RTS_PA8 SILABS_DBUS_EUSART1_RTS(0x0, 0x8) +#define EUSART1_RTS_PB0 SILABS_DBUS_EUSART1_RTS(0x1, 0x0) +#define EUSART1_RTS_PB1 SILABS_DBUS_EUSART1_RTS(0x1, 0x1) +#define EUSART1_RTS_PB2 SILABS_DBUS_EUSART1_RTS(0x1, 0x2) +#define EUSART1_RTS_PB3 SILABS_DBUS_EUSART1_RTS(0x1, 0x3) +#define EUSART1_RTS_PB4 SILABS_DBUS_EUSART1_RTS(0x1, 0x4) +#define EUSART1_RTS_PC0 SILABS_DBUS_EUSART1_RTS(0x2, 0x0) +#define EUSART1_RTS_PC1 SILABS_DBUS_EUSART1_RTS(0x2, 0x1) +#define EUSART1_RTS_PC2 SILABS_DBUS_EUSART1_RTS(0x2, 0x2) +#define EUSART1_RTS_PC3 SILABS_DBUS_EUSART1_RTS(0x2, 0x3) +#define EUSART1_RTS_PC4 SILABS_DBUS_EUSART1_RTS(0x2, 0x4) +#define EUSART1_RTS_PC5 SILABS_DBUS_EUSART1_RTS(0x2, 0x5) +#define EUSART1_RTS_PC6 SILABS_DBUS_EUSART1_RTS(0x2, 0x6) +#define EUSART1_RTS_PC7 SILABS_DBUS_EUSART1_RTS(0x2, 0x7) +#define EUSART1_RTS_PD0 SILABS_DBUS_EUSART1_RTS(0x3, 0x0) +#define EUSART1_RTS_PD1 SILABS_DBUS_EUSART1_RTS(0x3, 0x1) +#define EUSART1_RTS_PD2 SILABS_DBUS_EUSART1_RTS(0x3, 0x2) +#define EUSART1_RTS_PD3 SILABS_DBUS_EUSART1_RTS(0x3, 0x3) +#define EUSART1_RX_PA0 SILABS_DBUS_EUSART1_RX(0x0, 0x0) +#define EUSART1_RX_PA1 SILABS_DBUS_EUSART1_RX(0x0, 0x1) +#define EUSART1_RX_PA2 SILABS_DBUS_EUSART1_RX(0x0, 0x2) +#define EUSART1_RX_PA3 SILABS_DBUS_EUSART1_RX(0x0, 0x3) +#define EUSART1_RX_PA4 SILABS_DBUS_EUSART1_RX(0x0, 0x4) +#define EUSART1_RX_PA5 SILABS_DBUS_EUSART1_RX(0x0, 0x5) +#define EUSART1_RX_PA6 SILABS_DBUS_EUSART1_RX(0x0, 0x6) +#define EUSART1_RX_PA7 SILABS_DBUS_EUSART1_RX(0x0, 0x7) +#define EUSART1_RX_PA8 SILABS_DBUS_EUSART1_RX(0x0, 0x8) +#define EUSART1_RX_PB0 SILABS_DBUS_EUSART1_RX(0x1, 0x0) +#define EUSART1_RX_PB1 SILABS_DBUS_EUSART1_RX(0x1, 0x1) +#define EUSART1_RX_PB2 SILABS_DBUS_EUSART1_RX(0x1, 0x2) +#define EUSART1_RX_PB3 SILABS_DBUS_EUSART1_RX(0x1, 0x3) +#define EUSART1_RX_PB4 SILABS_DBUS_EUSART1_RX(0x1, 0x4) +#define EUSART1_RX_PC0 SILABS_DBUS_EUSART1_RX(0x2, 0x0) +#define EUSART1_RX_PC1 SILABS_DBUS_EUSART1_RX(0x2, 0x1) +#define EUSART1_RX_PC2 SILABS_DBUS_EUSART1_RX(0x2, 0x2) +#define EUSART1_RX_PC3 SILABS_DBUS_EUSART1_RX(0x2, 0x3) +#define EUSART1_RX_PC4 SILABS_DBUS_EUSART1_RX(0x2, 0x4) +#define EUSART1_RX_PC5 SILABS_DBUS_EUSART1_RX(0x2, 0x5) +#define EUSART1_RX_PC6 SILABS_DBUS_EUSART1_RX(0x2, 0x6) +#define EUSART1_RX_PC7 SILABS_DBUS_EUSART1_RX(0x2, 0x7) +#define EUSART1_RX_PD0 SILABS_DBUS_EUSART1_RX(0x3, 0x0) +#define EUSART1_RX_PD1 SILABS_DBUS_EUSART1_RX(0x3, 0x1) +#define EUSART1_RX_PD2 SILABS_DBUS_EUSART1_RX(0x3, 0x2) +#define EUSART1_RX_PD3 SILABS_DBUS_EUSART1_RX(0x3, 0x3) +#define EUSART1_SCLK_PA0 SILABS_DBUS_EUSART1_SCLK(0x0, 0x0) +#define EUSART1_SCLK_PA1 SILABS_DBUS_EUSART1_SCLK(0x0, 0x1) +#define EUSART1_SCLK_PA2 SILABS_DBUS_EUSART1_SCLK(0x0, 0x2) +#define EUSART1_SCLK_PA3 SILABS_DBUS_EUSART1_SCLK(0x0, 0x3) +#define EUSART1_SCLK_PA4 SILABS_DBUS_EUSART1_SCLK(0x0, 0x4) +#define EUSART1_SCLK_PA5 SILABS_DBUS_EUSART1_SCLK(0x0, 0x5) +#define EUSART1_SCLK_PA6 SILABS_DBUS_EUSART1_SCLK(0x0, 0x6) +#define EUSART1_SCLK_PA7 SILABS_DBUS_EUSART1_SCLK(0x0, 0x7) +#define EUSART1_SCLK_PA8 SILABS_DBUS_EUSART1_SCLK(0x0, 0x8) +#define EUSART1_SCLK_PB0 SILABS_DBUS_EUSART1_SCLK(0x1, 0x0) +#define EUSART1_SCLK_PB1 SILABS_DBUS_EUSART1_SCLK(0x1, 0x1) +#define EUSART1_SCLK_PB2 SILABS_DBUS_EUSART1_SCLK(0x1, 0x2) +#define EUSART1_SCLK_PB3 SILABS_DBUS_EUSART1_SCLK(0x1, 0x3) +#define EUSART1_SCLK_PB4 SILABS_DBUS_EUSART1_SCLK(0x1, 0x4) +#define EUSART1_SCLK_PC0 SILABS_DBUS_EUSART1_SCLK(0x2, 0x0) +#define EUSART1_SCLK_PC1 SILABS_DBUS_EUSART1_SCLK(0x2, 0x1) +#define EUSART1_SCLK_PC2 SILABS_DBUS_EUSART1_SCLK(0x2, 0x2) +#define EUSART1_SCLK_PC3 SILABS_DBUS_EUSART1_SCLK(0x2, 0x3) +#define EUSART1_SCLK_PC4 SILABS_DBUS_EUSART1_SCLK(0x2, 0x4) +#define EUSART1_SCLK_PC5 SILABS_DBUS_EUSART1_SCLK(0x2, 0x5) +#define EUSART1_SCLK_PC6 SILABS_DBUS_EUSART1_SCLK(0x2, 0x6) +#define EUSART1_SCLK_PC7 SILABS_DBUS_EUSART1_SCLK(0x2, 0x7) +#define EUSART1_SCLK_PD0 SILABS_DBUS_EUSART1_SCLK(0x3, 0x0) +#define EUSART1_SCLK_PD1 SILABS_DBUS_EUSART1_SCLK(0x3, 0x1) +#define EUSART1_SCLK_PD2 SILABS_DBUS_EUSART1_SCLK(0x3, 0x2) +#define EUSART1_SCLK_PD3 SILABS_DBUS_EUSART1_SCLK(0x3, 0x3) +#define EUSART1_TX_PA0 SILABS_DBUS_EUSART1_TX(0x0, 0x0) +#define EUSART1_TX_PA1 SILABS_DBUS_EUSART1_TX(0x0, 0x1) +#define EUSART1_TX_PA2 SILABS_DBUS_EUSART1_TX(0x0, 0x2) +#define EUSART1_TX_PA3 SILABS_DBUS_EUSART1_TX(0x0, 0x3) +#define EUSART1_TX_PA4 SILABS_DBUS_EUSART1_TX(0x0, 0x4) +#define EUSART1_TX_PA5 SILABS_DBUS_EUSART1_TX(0x0, 0x5) +#define EUSART1_TX_PA6 SILABS_DBUS_EUSART1_TX(0x0, 0x6) +#define EUSART1_TX_PA7 SILABS_DBUS_EUSART1_TX(0x0, 0x7) +#define EUSART1_TX_PA8 SILABS_DBUS_EUSART1_TX(0x0, 0x8) +#define EUSART1_TX_PB0 SILABS_DBUS_EUSART1_TX(0x1, 0x0) +#define EUSART1_TX_PB1 SILABS_DBUS_EUSART1_TX(0x1, 0x1) +#define EUSART1_TX_PB2 SILABS_DBUS_EUSART1_TX(0x1, 0x2) +#define EUSART1_TX_PB3 SILABS_DBUS_EUSART1_TX(0x1, 0x3) +#define EUSART1_TX_PB4 SILABS_DBUS_EUSART1_TX(0x1, 0x4) +#define EUSART1_TX_PC0 SILABS_DBUS_EUSART1_TX(0x2, 0x0) +#define EUSART1_TX_PC1 SILABS_DBUS_EUSART1_TX(0x2, 0x1) +#define EUSART1_TX_PC2 SILABS_DBUS_EUSART1_TX(0x2, 0x2) +#define EUSART1_TX_PC3 SILABS_DBUS_EUSART1_TX(0x2, 0x3) +#define EUSART1_TX_PC4 SILABS_DBUS_EUSART1_TX(0x2, 0x4) +#define EUSART1_TX_PC5 SILABS_DBUS_EUSART1_TX(0x2, 0x5) +#define EUSART1_TX_PC6 SILABS_DBUS_EUSART1_TX(0x2, 0x6) +#define EUSART1_TX_PC7 SILABS_DBUS_EUSART1_TX(0x2, 0x7) +#define EUSART1_TX_PD0 SILABS_DBUS_EUSART1_TX(0x3, 0x0) +#define EUSART1_TX_PD1 SILABS_DBUS_EUSART1_TX(0x3, 0x1) +#define EUSART1_TX_PD2 SILABS_DBUS_EUSART1_TX(0x3, 0x2) +#define EUSART1_TX_PD3 SILABS_DBUS_EUSART1_TX(0x3, 0x3) +#define EUSART1_CTS_PA0 SILABS_DBUS_EUSART1_CTS(0x0, 0x0) +#define EUSART1_CTS_PA1 SILABS_DBUS_EUSART1_CTS(0x0, 0x1) +#define EUSART1_CTS_PA2 SILABS_DBUS_EUSART1_CTS(0x0, 0x2) +#define EUSART1_CTS_PA3 SILABS_DBUS_EUSART1_CTS(0x0, 0x3) +#define EUSART1_CTS_PA4 SILABS_DBUS_EUSART1_CTS(0x0, 0x4) +#define EUSART1_CTS_PA5 SILABS_DBUS_EUSART1_CTS(0x0, 0x5) +#define EUSART1_CTS_PA6 SILABS_DBUS_EUSART1_CTS(0x0, 0x6) +#define EUSART1_CTS_PA7 SILABS_DBUS_EUSART1_CTS(0x0, 0x7) +#define EUSART1_CTS_PA8 SILABS_DBUS_EUSART1_CTS(0x0, 0x8) +#define EUSART1_CTS_PB0 SILABS_DBUS_EUSART1_CTS(0x1, 0x0) +#define EUSART1_CTS_PB1 SILABS_DBUS_EUSART1_CTS(0x1, 0x1) +#define EUSART1_CTS_PB2 SILABS_DBUS_EUSART1_CTS(0x1, 0x2) +#define EUSART1_CTS_PB3 SILABS_DBUS_EUSART1_CTS(0x1, 0x3) +#define EUSART1_CTS_PB4 SILABS_DBUS_EUSART1_CTS(0x1, 0x4) +#define EUSART1_CTS_PC0 SILABS_DBUS_EUSART1_CTS(0x2, 0x0) +#define EUSART1_CTS_PC1 SILABS_DBUS_EUSART1_CTS(0x2, 0x1) +#define EUSART1_CTS_PC2 SILABS_DBUS_EUSART1_CTS(0x2, 0x2) +#define EUSART1_CTS_PC3 SILABS_DBUS_EUSART1_CTS(0x2, 0x3) +#define EUSART1_CTS_PC4 SILABS_DBUS_EUSART1_CTS(0x2, 0x4) +#define EUSART1_CTS_PC5 SILABS_DBUS_EUSART1_CTS(0x2, 0x5) +#define EUSART1_CTS_PC6 SILABS_DBUS_EUSART1_CTS(0x2, 0x6) +#define EUSART1_CTS_PC7 SILABS_DBUS_EUSART1_CTS(0x2, 0x7) +#define EUSART1_CTS_PD0 SILABS_DBUS_EUSART1_CTS(0x3, 0x0) +#define EUSART1_CTS_PD1 SILABS_DBUS_EUSART1_CTS(0x3, 0x1) +#define EUSART1_CTS_PD2 SILABS_DBUS_EUSART1_CTS(0x3, 0x2) +#define EUSART1_CTS_PD3 SILABS_DBUS_EUSART1_CTS(0x3, 0x3) + +#define PTI_DCLK_PC0 SILABS_DBUS_PTI_DCLK(0x2, 0x0) +#define PTI_DCLK_PC1 SILABS_DBUS_PTI_DCLK(0x2, 0x1) +#define PTI_DCLK_PC2 SILABS_DBUS_PTI_DCLK(0x2, 0x2) +#define PTI_DCLK_PC3 SILABS_DBUS_PTI_DCLK(0x2, 0x3) +#define PTI_DCLK_PC4 SILABS_DBUS_PTI_DCLK(0x2, 0x4) +#define PTI_DCLK_PC5 SILABS_DBUS_PTI_DCLK(0x2, 0x5) +#define PTI_DCLK_PC6 SILABS_DBUS_PTI_DCLK(0x2, 0x6) +#define PTI_DCLK_PC7 SILABS_DBUS_PTI_DCLK(0x2, 0x7) +#define PTI_DCLK_PD0 SILABS_DBUS_PTI_DCLK(0x3, 0x0) +#define PTI_DCLK_PD1 SILABS_DBUS_PTI_DCLK(0x3, 0x1) +#define PTI_DCLK_PD2 SILABS_DBUS_PTI_DCLK(0x3, 0x2) +#define PTI_DCLK_PD3 SILABS_DBUS_PTI_DCLK(0x3, 0x3) +#define PTI_DFRAME_PC0 SILABS_DBUS_PTI_DFRAME(0x2, 0x0) +#define PTI_DFRAME_PC1 SILABS_DBUS_PTI_DFRAME(0x2, 0x1) +#define PTI_DFRAME_PC2 SILABS_DBUS_PTI_DFRAME(0x2, 0x2) +#define PTI_DFRAME_PC3 SILABS_DBUS_PTI_DFRAME(0x2, 0x3) +#define PTI_DFRAME_PC4 SILABS_DBUS_PTI_DFRAME(0x2, 0x4) +#define PTI_DFRAME_PC5 SILABS_DBUS_PTI_DFRAME(0x2, 0x5) +#define PTI_DFRAME_PC6 SILABS_DBUS_PTI_DFRAME(0x2, 0x6) +#define PTI_DFRAME_PC7 SILABS_DBUS_PTI_DFRAME(0x2, 0x7) +#define PTI_DFRAME_PD0 SILABS_DBUS_PTI_DFRAME(0x3, 0x0) +#define PTI_DFRAME_PD1 SILABS_DBUS_PTI_DFRAME(0x3, 0x1) +#define PTI_DFRAME_PD2 SILABS_DBUS_PTI_DFRAME(0x3, 0x2) +#define PTI_DFRAME_PD3 SILABS_DBUS_PTI_DFRAME(0x3, 0x3) +#define PTI_DOUT_PC0 SILABS_DBUS_PTI_DOUT(0x2, 0x0) +#define PTI_DOUT_PC1 SILABS_DBUS_PTI_DOUT(0x2, 0x1) +#define PTI_DOUT_PC2 SILABS_DBUS_PTI_DOUT(0x2, 0x2) +#define PTI_DOUT_PC3 SILABS_DBUS_PTI_DOUT(0x2, 0x3) +#define PTI_DOUT_PC4 SILABS_DBUS_PTI_DOUT(0x2, 0x4) +#define PTI_DOUT_PC5 SILABS_DBUS_PTI_DOUT(0x2, 0x5) +#define PTI_DOUT_PC6 SILABS_DBUS_PTI_DOUT(0x2, 0x6) +#define PTI_DOUT_PC7 SILABS_DBUS_PTI_DOUT(0x2, 0x7) +#define PTI_DOUT_PD0 SILABS_DBUS_PTI_DOUT(0x3, 0x0) +#define PTI_DOUT_PD1 SILABS_DBUS_PTI_DOUT(0x3, 0x1) +#define PTI_DOUT_PD2 SILABS_DBUS_PTI_DOUT(0x3, 0x2) +#define PTI_DOUT_PD3 SILABS_DBUS_PTI_DOUT(0x3, 0x3) + +#define I2C0_SCL_PA0 SILABS_DBUS_I2C0_SCL(0x0, 0x0) +#define I2C0_SCL_PA1 SILABS_DBUS_I2C0_SCL(0x0, 0x1) +#define I2C0_SCL_PA2 SILABS_DBUS_I2C0_SCL(0x0, 0x2) +#define I2C0_SCL_PA3 SILABS_DBUS_I2C0_SCL(0x0, 0x3) +#define I2C0_SCL_PA4 SILABS_DBUS_I2C0_SCL(0x0, 0x4) +#define I2C0_SCL_PA5 SILABS_DBUS_I2C0_SCL(0x0, 0x5) +#define I2C0_SCL_PA6 SILABS_DBUS_I2C0_SCL(0x0, 0x6) +#define I2C0_SCL_PA7 SILABS_DBUS_I2C0_SCL(0x0, 0x7) +#define I2C0_SCL_PA8 SILABS_DBUS_I2C0_SCL(0x0, 0x8) +#define I2C0_SCL_PB0 SILABS_DBUS_I2C0_SCL(0x1, 0x0) +#define I2C0_SCL_PB1 SILABS_DBUS_I2C0_SCL(0x1, 0x1) +#define I2C0_SCL_PB2 SILABS_DBUS_I2C0_SCL(0x1, 0x2) +#define I2C0_SCL_PB3 SILABS_DBUS_I2C0_SCL(0x1, 0x3) +#define I2C0_SCL_PB4 SILABS_DBUS_I2C0_SCL(0x1, 0x4) +#define I2C0_SCL_PC0 SILABS_DBUS_I2C0_SCL(0x2, 0x0) +#define I2C0_SCL_PC1 SILABS_DBUS_I2C0_SCL(0x2, 0x1) +#define I2C0_SCL_PC2 SILABS_DBUS_I2C0_SCL(0x2, 0x2) +#define I2C0_SCL_PC3 SILABS_DBUS_I2C0_SCL(0x2, 0x3) +#define I2C0_SCL_PC4 SILABS_DBUS_I2C0_SCL(0x2, 0x4) +#define I2C0_SCL_PC5 SILABS_DBUS_I2C0_SCL(0x2, 0x5) +#define I2C0_SCL_PC6 SILABS_DBUS_I2C0_SCL(0x2, 0x6) +#define I2C0_SCL_PC7 SILABS_DBUS_I2C0_SCL(0x2, 0x7) +#define I2C0_SCL_PD0 SILABS_DBUS_I2C0_SCL(0x3, 0x0) +#define I2C0_SCL_PD1 SILABS_DBUS_I2C0_SCL(0x3, 0x1) +#define I2C0_SCL_PD2 SILABS_DBUS_I2C0_SCL(0x3, 0x2) +#define I2C0_SCL_PD3 SILABS_DBUS_I2C0_SCL(0x3, 0x3) +#define I2C0_SDA_PA0 SILABS_DBUS_I2C0_SDA(0x0, 0x0) +#define I2C0_SDA_PA1 SILABS_DBUS_I2C0_SDA(0x0, 0x1) +#define I2C0_SDA_PA2 SILABS_DBUS_I2C0_SDA(0x0, 0x2) +#define I2C0_SDA_PA3 SILABS_DBUS_I2C0_SDA(0x0, 0x3) +#define I2C0_SDA_PA4 SILABS_DBUS_I2C0_SDA(0x0, 0x4) +#define I2C0_SDA_PA5 SILABS_DBUS_I2C0_SDA(0x0, 0x5) +#define I2C0_SDA_PA6 SILABS_DBUS_I2C0_SDA(0x0, 0x6) +#define I2C0_SDA_PA7 SILABS_DBUS_I2C0_SDA(0x0, 0x7) +#define I2C0_SDA_PA8 SILABS_DBUS_I2C0_SDA(0x0, 0x8) +#define I2C0_SDA_PB0 SILABS_DBUS_I2C0_SDA(0x1, 0x0) +#define I2C0_SDA_PB1 SILABS_DBUS_I2C0_SDA(0x1, 0x1) +#define I2C0_SDA_PB2 SILABS_DBUS_I2C0_SDA(0x1, 0x2) +#define I2C0_SDA_PB3 SILABS_DBUS_I2C0_SDA(0x1, 0x3) +#define I2C0_SDA_PB4 SILABS_DBUS_I2C0_SDA(0x1, 0x4) +#define I2C0_SDA_PC0 SILABS_DBUS_I2C0_SDA(0x2, 0x0) +#define I2C0_SDA_PC1 SILABS_DBUS_I2C0_SDA(0x2, 0x1) +#define I2C0_SDA_PC2 SILABS_DBUS_I2C0_SDA(0x2, 0x2) +#define I2C0_SDA_PC3 SILABS_DBUS_I2C0_SDA(0x2, 0x3) +#define I2C0_SDA_PC4 SILABS_DBUS_I2C0_SDA(0x2, 0x4) +#define I2C0_SDA_PC5 SILABS_DBUS_I2C0_SDA(0x2, 0x5) +#define I2C0_SDA_PC6 SILABS_DBUS_I2C0_SDA(0x2, 0x6) +#define I2C0_SDA_PC7 SILABS_DBUS_I2C0_SDA(0x2, 0x7) +#define I2C0_SDA_PD0 SILABS_DBUS_I2C0_SDA(0x3, 0x0) +#define I2C0_SDA_PD1 SILABS_DBUS_I2C0_SDA(0x3, 0x1) +#define I2C0_SDA_PD2 SILABS_DBUS_I2C0_SDA(0x3, 0x2) +#define I2C0_SDA_PD3 SILABS_DBUS_I2C0_SDA(0x3, 0x3) + +#define I2C1_SCL_PC0 SILABS_DBUS_I2C1_SCL(0x2, 0x0) +#define I2C1_SCL_PC1 SILABS_DBUS_I2C1_SCL(0x2, 0x1) +#define I2C1_SCL_PC2 SILABS_DBUS_I2C1_SCL(0x2, 0x2) +#define I2C1_SCL_PC3 SILABS_DBUS_I2C1_SCL(0x2, 0x3) +#define I2C1_SCL_PC4 SILABS_DBUS_I2C1_SCL(0x2, 0x4) +#define I2C1_SCL_PC5 SILABS_DBUS_I2C1_SCL(0x2, 0x5) +#define I2C1_SCL_PC6 SILABS_DBUS_I2C1_SCL(0x2, 0x6) +#define I2C1_SCL_PC7 SILABS_DBUS_I2C1_SCL(0x2, 0x7) +#define I2C1_SCL_PD0 SILABS_DBUS_I2C1_SCL(0x3, 0x0) +#define I2C1_SCL_PD1 SILABS_DBUS_I2C1_SCL(0x3, 0x1) +#define I2C1_SCL_PD2 SILABS_DBUS_I2C1_SCL(0x3, 0x2) +#define I2C1_SCL_PD3 SILABS_DBUS_I2C1_SCL(0x3, 0x3) +#define I2C1_SDA_PC0 SILABS_DBUS_I2C1_SDA(0x2, 0x0) +#define I2C1_SDA_PC1 SILABS_DBUS_I2C1_SDA(0x2, 0x1) +#define I2C1_SDA_PC2 SILABS_DBUS_I2C1_SDA(0x2, 0x2) +#define I2C1_SDA_PC3 SILABS_DBUS_I2C1_SDA(0x2, 0x3) +#define I2C1_SDA_PC4 SILABS_DBUS_I2C1_SDA(0x2, 0x4) +#define I2C1_SDA_PC5 SILABS_DBUS_I2C1_SDA(0x2, 0x5) +#define I2C1_SDA_PC6 SILABS_DBUS_I2C1_SDA(0x2, 0x6) +#define I2C1_SDA_PC7 SILABS_DBUS_I2C1_SDA(0x2, 0x7) +#define I2C1_SDA_PD0 SILABS_DBUS_I2C1_SDA(0x3, 0x0) +#define I2C1_SDA_PD1 SILABS_DBUS_I2C1_SDA(0x3, 0x1) +#define I2C1_SDA_PD2 SILABS_DBUS_I2C1_SDA(0x3, 0x2) +#define I2C1_SDA_PD3 SILABS_DBUS_I2C1_SDA(0x3, 0x3) + +#define LETIMER0_OUT0_PA0 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x0) +#define LETIMER0_OUT0_PA1 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x1) +#define LETIMER0_OUT0_PA2 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x2) +#define LETIMER0_OUT0_PA3 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x3) +#define LETIMER0_OUT0_PA4 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x4) +#define LETIMER0_OUT0_PA5 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x5) +#define LETIMER0_OUT0_PA6 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x6) +#define LETIMER0_OUT0_PA7 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x7) +#define LETIMER0_OUT0_PA8 SILABS_DBUS_LETIMER0_OUT0(0x0, 0x8) +#define LETIMER0_OUT0_PB0 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x0) +#define LETIMER0_OUT0_PB1 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x1) +#define LETIMER0_OUT0_PB2 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x2) +#define LETIMER0_OUT0_PB3 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x3) +#define LETIMER0_OUT0_PB4 SILABS_DBUS_LETIMER0_OUT0(0x1, 0x4) +#define LETIMER0_OUT1_PA0 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x0) +#define LETIMER0_OUT1_PA1 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x1) +#define LETIMER0_OUT1_PA2 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x2) +#define LETIMER0_OUT1_PA3 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x3) +#define LETIMER0_OUT1_PA4 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x4) +#define LETIMER0_OUT1_PA5 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x5) +#define LETIMER0_OUT1_PA6 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x6) +#define LETIMER0_OUT1_PA7 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x7) +#define LETIMER0_OUT1_PA8 SILABS_DBUS_LETIMER0_OUT1(0x0, 0x8) +#define LETIMER0_OUT1_PB0 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x0) +#define LETIMER0_OUT1_PB1 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x1) +#define LETIMER0_OUT1_PB2 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x2) +#define LETIMER0_OUT1_PB3 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x3) +#define LETIMER0_OUT1_PB4 SILABS_DBUS_LETIMER0_OUT1(0x1, 0x4) + +#define MODEM_ANT0_PA0 SILABS_DBUS_MODEM_ANT0(0x0, 0x0) +#define MODEM_ANT0_PA1 SILABS_DBUS_MODEM_ANT0(0x0, 0x1) +#define MODEM_ANT0_PA2 SILABS_DBUS_MODEM_ANT0(0x0, 0x2) +#define MODEM_ANT0_PA3 SILABS_DBUS_MODEM_ANT0(0x0, 0x3) +#define MODEM_ANT0_PA4 SILABS_DBUS_MODEM_ANT0(0x0, 0x4) +#define MODEM_ANT0_PA5 SILABS_DBUS_MODEM_ANT0(0x0, 0x5) +#define MODEM_ANT0_PA6 SILABS_DBUS_MODEM_ANT0(0x0, 0x6) +#define MODEM_ANT0_PA7 SILABS_DBUS_MODEM_ANT0(0x0, 0x7) +#define MODEM_ANT0_PA8 SILABS_DBUS_MODEM_ANT0(0x0, 0x8) +#define MODEM_ANT0_PB0 SILABS_DBUS_MODEM_ANT0(0x1, 0x0) +#define MODEM_ANT0_PB1 SILABS_DBUS_MODEM_ANT0(0x1, 0x1) +#define MODEM_ANT0_PB2 SILABS_DBUS_MODEM_ANT0(0x1, 0x2) +#define MODEM_ANT0_PB3 SILABS_DBUS_MODEM_ANT0(0x1, 0x3) +#define MODEM_ANT0_PB4 SILABS_DBUS_MODEM_ANT0(0x1, 0x4) +#define MODEM_ANT0_PC0 SILABS_DBUS_MODEM_ANT0(0x2, 0x0) +#define MODEM_ANT0_PC1 SILABS_DBUS_MODEM_ANT0(0x2, 0x1) +#define MODEM_ANT0_PC2 SILABS_DBUS_MODEM_ANT0(0x2, 0x2) +#define MODEM_ANT0_PC3 SILABS_DBUS_MODEM_ANT0(0x2, 0x3) +#define MODEM_ANT0_PC4 SILABS_DBUS_MODEM_ANT0(0x2, 0x4) +#define MODEM_ANT0_PC5 SILABS_DBUS_MODEM_ANT0(0x2, 0x5) +#define MODEM_ANT0_PC6 SILABS_DBUS_MODEM_ANT0(0x2, 0x6) +#define MODEM_ANT0_PC7 SILABS_DBUS_MODEM_ANT0(0x2, 0x7) +#define MODEM_ANT0_PD0 SILABS_DBUS_MODEM_ANT0(0x3, 0x0) +#define MODEM_ANT0_PD1 SILABS_DBUS_MODEM_ANT0(0x3, 0x1) +#define MODEM_ANT0_PD2 SILABS_DBUS_MODEM_ANT0(0x3, 0x2) +#define MODEM_ANT0_PD3 SILABS_DBUS_MODEM_ANT0(0x3, 0x3) +#define MODEM_ANT1_PA0 SILABS_DBUS_MODEM_ANT1(0x0, 0x0) +#define MODEM_ANT1_PA1 SILABS_DBUS_MODEM_ANT1(0x0, 0x1) +#define MODEM_ANT1_PA2 SILABS_DBUS_MODEM_ANT1(0x0, 0x2) +#define MODEM_ANT1_PA3 SILABS_DBUS_MODEM_ANT1(0x0, 0x3) +#define MODEM_ANT1_PA4 SILABS_DBUS_MODEM_ANT1(0x0, 0x4) +#define MODEM_ANT1_PA5 SILABS_DBUS_MODEM_ANT1(0x0, 0x5) +#define MODEM_ANT1_PA6 SILABS_DBUS_MODEM_ANT1(0x0, 0x6) +#define MODEM_ANT1_PA7 SILABS_DBUS_MODEM_ANT1(0x0, 0x7) +#define MODEM_ANT1_PA8 SILABS_DBUS_MODEM_ANT1(0x0, 0x8) +#define MODEM_ANT1_PB0 SILABS_DBUS_MODEM_ANT1(0x1, 0x0) +#define MODEM_ANT1_PB1 SILABS_DBUS_MODEM_ANT1(0x1, 0x1) +#define MODEM_ANT1_PB2 SILABS_DBUS_MODEM_ANT1(0x1, 0x2) +#define MODEM_ANT1_PB3 SILABS_DBUS_MODEM_ANT1(0x1, 0x3) +#define MODEM_ANT1_PB4 SILABS_DBUS_MODEM_ANT1(0x1, 0x4) +#define MODEM_ANT1_PC0 SILABS_DBUS_MODEM_ANT1(0x2, 0x0) +#define MODEM_ANT1_PC1 SILABS_DBUS_MODEM_ANT1(0x2, 0x1) +#define MODEM_ANT1_PC2 SILABS_DBUS_MODEM_ANT1(0x2, 0x2) +#define MODEM_ANT1_PC3 SILABS_DBUS_MODEM_ANT1(0x2, 0x3) +#define MODEM_ANT1_PC4 SILABS_DBUS_MODEM_ANT1(0x2, 0x4) +#define MODEM_ANT1_PC5 SILABS_DBUS_MODEM_ANT1(0x2, 0x5) +#define MODEM_ANT1_PC6 SILABS_DBUS_MODEM_ANT1(0x2, 0x6) +#define MODEM_ANT1_PC7 SILABS_DBUS_MODEM_ANT1(0x2, 0x7) +#define MODEM_ANT1_PD0 SILABS_DBUS_MODEM_ANT1(0x3, 0x0) +#define MODEM_ANT1_PD1 SILABS_DBUS_MODEM_ANT1(0x3, 0x1) +#define MODEM_ANT1_PD2 SILABS_DBUS_MODEM_ANT1(0x3, 0x2) +#define MODEM_ANT1_PD3 SILABS_DBUS_MODEM_ANT1(0x3, 0x3) +#define MODEM_ANTROLLOVER_PC0 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x0) +#define MODEM_ANTROLLOVER_PC1 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x1) +#define MODEM_ANTROLLOVER_PC2 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x2) +#define MODEM_ANTROLLOVER_PC3 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x3) +#define MODEM_ANTROLLOVER_PC4 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x4) +#define MODEM_ANTROLLOVER_PC5 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x5) +#define MODEM_ANTROLLOVER_PC6 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x6) +#define MODEM_ANTROLLOVER_PC7 SILABS_DBUS_MODEM_ANTROLLOVER(0x2, 0x7) +#define MODEM_ANTROLLOVER_PD0 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x0) +#define MODEM_ANTROLLOVER_PD1 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x1) +#define MODEM_ANTROLLOVER_PD2 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x2) +#define MODEM_ANTROLLOVER_PD3 SILABS_DBUS_MODEM_ANTROLLOVER(0x3, 0x3) +#define MODEM_ANTRR0_PC0 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x0) +#define MODEM_ANTRR0_PC1 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x1) +#define MODEM_ANTRR0_PC2 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x2) +#define MODEM_ANTRR0_PC3 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x3) +#define MODEM_ANTRR0_PC4 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x4) +#define MODEM_ANTRR0_PC5 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x5) +#define MODEM_ANTRR0_PC6 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x6) +#define MODEM_ANTRR0_PC7 SILABS_DBUS_MODEM_ANTRR0(0x2, 0x7) +#define MODEM_ANTRR0_PD0 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x0) +#define MODEM_ANTRR0_PD1 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x1) +#define MODEM_ANTRR0_PD2 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x2) +#define MODEM_ANTRR0_PD3 SILABS_DBUS_MODEM_ANTRR0(0x3, 0x3) +#define MODEM_ANTRR1_PC0 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x0) +#define MODEM_ANTRR1_PC1 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x1) +#define MODEM_ANTRR1_PC2 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x2) +#define MODEM_ANTRR1_PC3 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x3) +#define MODEM_ANTRR1_PC4 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x4) +#define MODEM_ANTRR1_PC5 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x5) +#define MODEM_ANTRR1_PC6 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x6) +#define MODEM_ANTRR1_PC7 SILABS_DBUS_MODEM_ANTRR1(0x2, 0x7) +#define MODEM_ANTRR1_PD0 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x0) +#define MODEM_ANTRR1_PD1 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x1) +#define MODEM_ANTRR1_PD2 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x2) +#define MODEM_ANTRR1_PD3 SILABS_DBUS_MODEM_ANTRR1(0x3, 0x3) +#define MODEM_ANTRR2_PC0 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x0) +#define MODEM_ANTRR2_PC1 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x1) +#define MODEM_ANTRR2_PC2 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x2) +#define MODEM_ANTRR2_PC3 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x3) +#define MODEM_ANTRR2_PC4 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x4) +#define MODEM_ANTRR2_PC5 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x5) +#define MODEM_ANTRR2_PC6 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x6) +#define MODEM_ANTRR2_PC7 SILABS_DBUS_MODEM_ANTRR2(0x2, 0x7) +#define MODEM_ANTRR2_PD0 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x0) +#define MODEM_ANTRR2_PD1 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x1) +#define MODEM_ANTRR2_PD2 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x2) +#define MODEM_ANTRR2_PD3 SILABS_DBUS_MODEM_ANTRR2(0x3, 0x3) +#define MODEM_ANTRR3_PC0 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x0) +#define MODEM_ANTRR3_PC1 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x1) +#define MODEM_ANTRR3_PC2 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x2) +#define MODEM_ANTRR3_PC3 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x3) +#define MODEM_ANTRR3_PC4 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x4) +#define MODEM_ANTRR3_PC5 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x5) +#define MODEM_ANTRR3_PC6 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x6) +#define MODEM_ANTRR3_PC7 SILABS_DBUS_MODEM_ANTRR3(0x2, 0x7) +#define MODEM_ANTRR3_PD0 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x0) +#define MODEM_ANTRR3_PD1 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x1) +#define MODEM_ANTRR3_PD2 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x2) +#define MODEM_ANTRR3_PD3 SILABS_DBUS_MODEM_ANTRR3(0x3, 0x3) +#define MODEM_ANTRR4_PC0 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x0) +#define MODEM_ANTRR4_PC1 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x1) +#define MODEM_ANTRR4_PC2 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x2) +#define MODEM_ANTRR4_PC3 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x3) +#define MODEM_ANTRR4_PC4 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x4) +#define MODEM_ANTRR4_PC5 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x5) +#define MODEM_ANTRR4_PC6 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x6) +#define MODEM_ANTRR4_PC7 SILABS_DBUS_MODEM_ANTRR4(0x2, 0x7) +#define MODEM_ANTRR4_PD0 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x0) +#define MODEM_ANTRR4_PD1 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x1) +#define MODEM_ANTRR4_PD2 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x2) +#define MODEM_ANTRR4_PD3 SILABS_DBUS_MODEM_ANTRR4(0x3, 0x3) +#define MODEM_ANTRR5_PC0 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x0) +#define MODEM_ANTRR5_PC1 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x1) +#define MODEM_ANTRR5_PC2 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x2) +#define MODEM_ANTRR5_PC3 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x3) +#define MODEM_ANTRR5_PC4 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x4) +#define MODEM_ANTRR5_PC5 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x5) +#define MODEM_ANTRR5_PC6 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x6) +#define MODEM_ANTRR5_PC7 SILABS_DBUS_MODEM_ANTRR5(0x2, 0x7) +#define MODEM_ANTRR5_PD0 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x0) +#define MODEM_ANTRR5_PD1 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x1) +#define MODEM_ANTRR5_PD2 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x2) +#define MODEM_ANTRR5_PD3 SILABS_DBUS_MODEM_ANTRR5(0x3, 0x3) +#define MODEM_ANTSWEN_PC0 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x0) +#define MODEM_ANTSWEN_PC1 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x1) +#define MODEM_ANTSWEN_PC2 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x2) +#define MODEM_ANTSWEN_PC3 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x3) +#define MODEM_ANTSWEN_PC4 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x4) +#define MODEM_ANTSWEN_PC5 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x5) +#define MODEM_ANTSWEN_PC6 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x6) +#define MODEM_ANTSWEN_PC7 SILABS_DBUS_MODEM_ANTSWEN(0x2, 0x7) +#define MODEM_ANTSWEN_PD0 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x0) +#define MODEM_ANTSWEN_PD1 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x1) +#define MODEM_ANTSWEN_PD2 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x2) +#define MODEM_ANTSWEN_PD3 SILABS_DBUS_MODEM_ANTSWEN(0x3, 0x3) +#define MODEM_ANTSWUS_PC0 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x0) +#define MODEM_ANTSWUS_PC1 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x1) +#define MODEM_ANTSWUS_PC2 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x2) +#define MODEM_ANTSWUS_PC3 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x3) +#define MODEM_ANTSWUS_PC4 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x4) +#define MODEM_ANTSWUS_PC5 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x5) +#define MODEM_ANTSWUS_PC6 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x6) +#define MODEM_ANTSWUS_PC7 SILABS_DBUS_MODEM_ANTSWUS(0x2, 0x7) +#define MODEM_ANTSWUS_PD0 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x0) +#define MODEM_ANTSWUS_PD1 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x1) +#define MODEM_ANTSWUS_PD2 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x2) +#define MODEM_ANTSWUS_PD3 SILABS_DBUS_MODEM_ANTSWUS(0x3, 0x3) +#define MODEM_ANTTRIG_PC0 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x0) +#define MODEM_ANTTRIG_PC1 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x1) +#define MODEM_ANTTRIG_PC2 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x2) +#define MODEM_ANTTRIG_PC3 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x3) +#define MODEM_ANTTRIG_PC4 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x4) +#define MODEM_ANTTRIG_PC5 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x5) +#define MODEM_ANTTRIG_PC6 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x6) +#define MODEM_ANTTRIG_PC7 SILABS_DBUS_MODEM_ANTTRIG(0x2, 0x7) +#define MODEM_ANTTRIG_PD0 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x0) +#define MODEM_ANTTRIG_PD1 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x1) +#define MODEM_ANTTRIG_PD2 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x2) +#define MODEM_ANTTRIG_PD3 SILABS_DBUS_MODEM_ANTTRIG(0x3, 0x3) +#define MODEM_ANTTRIGSTOP_PC0 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x0) +#define MODEM_ANTTRIGSTOP_PC1 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x1) +#define MODEM_ANTTRIGSTOP_PC2 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x2) +#define MODEM_ANTTRIGSTOP_PC3 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x3) +#define MODEM_ANTTRIGSTOP_PC4 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x4) +#define MODEM_ANTTRIGSTOP_PC5 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x5) +#define MODEM_ANTTRIGSTOP_PC6 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x6) +#define MODEM_ANTTRIGSTOP_PC7 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x2, 0x7) +#define MODEM_ANTTRIGSTOP_PD0 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x0) +#define MODEM_ANTTRIGSTOP_PD1 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x1) +#define MODEM_ANTTRIGSTOP_PD2 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x2) +#define MODEM_ANTTRIGSTOP_PD3 SILABS_DBUS_MODEM_ANTTRIGSTOP(0x3, 0x3) +#define MODEM_DCLK_PA0 SILABS_DBUS_MODEM_DCLK(0x0, 0x0) +#define MODEM_DCLK_PA1 SILABS_DBUS_MODEM_DCLK(0x0, 0x1) +#define MODEM_DCLK_PA2 SILABS_DBUS_MODEM_DCLK(0x0, 0x2) +#define MODEM_DCLK_PA3 SILABS_DBUS_MODEM_DCLK(0x0, 0x3) +#define MODEM_DCLK_PA4 SILABS_DBUS_MODEM_DCLK(0x0, 0x4) +#define MODEM_DCLK_PA5 SILABS_DBUS_MODEM_DCLK(0x0, 0x5) +#define MODEM_DCLK_PA6 SILABS_DBUS_MODEM_DCLK(0x0, 0x6) +#define MODEM_DCLK_PA7 SILABS_DBUS_MODEM_DCLK(0x0, 0x7) +#define MODEM_DCLK_PA8 SILABS_DBUS_MODEM_DCLK(0x0, 0x8) +#define MODEM_DCLK_PB0 SILABS_DBUS_MODEM_DCLK(0x1, 0x0) +#define MODEM_DCLK_PB1 SILABS_DBUS_MODEM_DCLK(0x1, 0x1) +#define MODEM_DCLK_PB2 SILABS_DBUS_MODEM_DCLK(0x1, 0x2) +#define MODEM_DCLK_PB3 SILABS_DBUS_MODEM_DCLK(0x1, 0x3) +#define MODEM_DCLK_PB4 SILABS_DBUS_MODEM_DCLK(0x1, 0x4) +#define MODEM_DOUT_PA0 SILABS_DBUS_MODEM_DOUT(0x0, 0x0) +#define MODEM_DOUT_PA1 SILABS_DBUS_MODEM_DOUT(0x0, 0x1) +#define MODEM_DOUT_PA2 SILABS_DBUS_MODEM_DOUT(0x0, 0x2) +#define MODEM_DOUT_PA3 SILABS_DBUS_MODEM_DOUT(0x0, 0x3) +#define MODEM_DOUT_PA4 SILABS_DBUS_MODEM_DOUT(0x0, 0x4) +#define MODEM_DOUT_PA5 SILABS_DBUS_MODEM_DOUT(0x0, 0x5) +#define MODEM_DOUT_PA6 SILABS_DBUS_MODEM_DOUT(0x0, 0x6) +#define MODEM_DOUT_PA7 SILABS_DBUS_MODEM_DOUT(0x0, 0x7) +#define MODEM_DOUT_PA8 SILABS_DBUS_MODEM_DOUT(0x0, 0x8) +#define MODEM_DOUT_PB0 SILABS_DBUS_MODEM_DOUT(0x1, 0x0) +#define MODEM_DOUT_PB1 SILABS_DBUS_MODEM_DOUT(0x1, 0x1) +#define MODEM_DOUT_PB2 SILABS_DBUS_MODEM_DOUT(0x1, 0x2) +#define MODEM_DOUT_PB3 SILABS_DBUS_MODEM_DOUT(0x1, 0x3) +#define MODEM_DOUT_PB4 SILABS_DBUS_MODEM_DOUT(0x1, 0x4) +#define MODEM_DIN_PA0 SILABS_DBUS_MODEM_DIN(0x0, 0x0) +#define MODEM_DIN_PA1 SILABS_DBUS_MODEM_DIN(0x0, 0x1) +#define MODEM_DIN_PA2 SILABS_DBUS_MODEM_DIN(0x0, 0x2) +#define MODEM_DIN_PA3 SILABS_DBUS_MODEM_DIN(0x0, 0x3) +#define MODEM_DIN_PA4 SILABS_DBUS_MODEM_DIN(0x0, 0x4) +#define MODEM_DIN_PA5 SILABS_DBUS_MODEM_DIN(0x0, 0x5) +#define MODEM_DIN_PA6 SILABS_DBUS_MODEM_DIN(0x0, 0x6) +#define MODEM_DIN_PA7 SILABS_DBUS_MODEM_DIN(0x0, 0x7) +#define MODEM_DIN_PA8 SILABS_DBUS_MODEM_DIN(0x0, 0x8) +#define MODEM_DIN_PB0 SILABS_DBUS_MODEM_DIN(0x1, 0x0) +#define MODEM_DIN_PB1 SILABS_DBUS_MODEM_DIN(0x1, 0x1) +#define MODEM_DIN_PB2 SILABS_DBUS_MODEM_DIN(0x1, 0x2) +#define MODEM_DIN_PB3 SILABS_DBUS_MODEM_DIN(0x1, 0x3) +#define MODEM_DIN_PB4 SILABS_DBUS_MODEM_DIN(0x1, 0x4) + +#define PDM_CLK_PA0 SILABS_DBUS_PDM_CLK(0x0, 0x0) +#define PDM_CLK_PA1 SILABS_DBUS_PDM_CLK(0x0, 0x1) +#define PDM_CLK_PA2 SILABS_DBUS_PDM_CLK(0x0, 0x2) +#define PDM_CLK_PA3 SILABS_DBUS_PDM_CLK(0x0, 0x3) +#define PDM_CLK_PA4 SILABS_DBUS_PDM_CLK(0x0, 0x4) +#define PDM_CLK_PA5 SILABS_DBUS_PDM_CLK(0x0, 0x5) +#define PDM_CLK_PA6 SILABS_DBUS_PDM_CLK(0x0, 0x6) +#define PDM_CLK_PA7 SILABS_DBUS_PDM_CLK(0x0, 0x7) +#define PDM_CLK_PA8 SILABS_DBUS_PDM_CLK(0x0, 0x8) +#define PDM_CLK_PB0 SILABS_DBUS_PDM_CLK(0x1, 0x0) +#define PDM_CLK_PB1 SILABS_DBUS_PDM_CLK(0x1, 0x1) +#define PDM_CLK_PB2 SILABS_DBUS_PDM_CLK(0x1, 0x2) +#define PDM_CLK_PB3 SILABS_DBUS_PDM_CLK(0x1, 0x3) +#define PDM_CLK_PB4 SILABS_DBUS_PDM_CLK(0x1, 0x4) +#define PDM_CLK_PC0 SILABS_DBUS_PDM_CLK(0x2, 0x0) +#define PDM_CLK_PC1 SILABS_DBUS_PDM_CLK(0x2, 0x1) +#define PDM_CLK_PC2 SILABS_DBUS_PDM_CLK(0x2, 0x2) +#define PDM_CLK_PC3 SILABS_DBUS_PDM_CLK(0x2, 0x3) +#define PDM_CLK_PC4 SILABS_DBUS_PDM_CLK(0x2, 0x4) +#define PDM_CLK_PC5 SILABS_DBUS_PDM_CLK(0x2, 0x5) +#define PDM_CLK_PC6 SILABS_DBUS_PDM_CLK(0x2, 0x6) +#define PDM_CLK_PC7 SILABS_DBUS_PDM_CLK(0x2, 0x7) +#define PDM_CLK_PD0 SILABS_DBUS_PDM_CLK(0x3, 0x0) +#define PDM_CLK_PD1 SILABS_DBUS_PDM_CLK(0x3, 0x1) +#define PDM_CLK_PD2 SILABS_DBUS_PDM_CLK(0x3, 0x2) +#define PDM_CLK_PD3 SILABS_DBUS_PDM_CLK(0x3, 0x3) +#define PDM_DAT0_PA0 SILABS_DBUS_PDM_DAT0(0x0, 0x0) +#define PDM_DAT0_PA1 SILABS_DBUS_PDM_DAT0(0x0, 0x1) +#define PDM_DAT0_PA2 SILABS_DBUS_PDM_DAT0(0x0, 0x2) +#define PDM_DAT0_PA3 SILABS_DBUS_PDM_DAT0(0x0, 0x3) +#define PDM_DAT0_PA4 SILABS_DBUS_PDM_DAT0(0x0, 0x4) +#define PDM_DAT0_PA5 SILABS_DBUS_PDM_DAT0(0x0, 0x5) +#define PDM_DAT0_PA6 SILABS_DBUS_PDM_DAT0(0x0, 0x6) +#define PDM_DAT0_PA7 SILABS_DBUS_PDM_DAT0(0x0, 0x7) +#define PDM_DAT0_PA8 SILABS_DBUS_PDM_DAT0(0x0, 0x8) +#define PDM_DAT0_PB0 SILABS_DBUS_PDM_DAT0(0x1, 0x0) +#define PDM_DAT0_PB1 SILABS_DBUS_PDM_DAT0(0x1, 0x1) +#define PDM_DAT0_PB2 SILABS_DBUS_PDM_DAT0(0x1, 0x2) +#define PDM_DAT0_PB3 SILABS_DBUS_PDM_DAT0(0x1, 0x3) +#define PDM_DAT0_PB4 SILABS_DBUS_PDM_DAT0(0x1, 0x4) +#define PDM_DAT0_PC0 SILABS_DBUS_PDM_DAT0(0x2, 0x0) +#define PDM_DAT0_PC1 SILABS_DBUS_PDM_DAT0(0x2, 0x1) +#define PDM_DAT0_PC2 SILABS_DBUS_PDM_DAT0(0x2, 0x2) +#define PDM_DAT0_PC3 SILABS_DBUS_PDM_DAT0(0x2, 0x3) +#define PDM_DAT0_PC4 SILABS_DBUS_PDM_DAT0(0x2, 0x4) +#define PDM_DAT0_PC5 SILABS_DBUS_PDM_DAT0(0x2, 0x5) +#define PDM_DAT0_PC6 SILABS_DBUS_PDM_DAT0(0x2, 0x6) +#define PDM_DAT0_PC7 SILABS_DBUS_PDM_DAT0(0x2, 0x7) +#define PDM_DAT0_PD0 SILABS_DBUS_PDM_DAT0(0x3, 0x0) +#define PDM_DAT0_PD1 SILABS_DBUS_PDM_DAT0(0x3, 0x1) +#define PDM_DAT0_PD2 SILABS_DBUS_PDM_DAT0(0x3, 0x2) +#define PDM_DAT0_PD3 SILABS_DBUS_PDM_DAT0(0x3, 0x3) +#define PDM_DAT1_PA0 SILABS_DBUS_PDM_DAT1(0x0, 0x0) +#define PDM_DAT1_PA1 SILABS_DBUS_PDM_DAT1(0x0, 0x1) +#define PDM_DAT1_PA2 SILABS_DBUS_PDM_DAT1(0x0, 0x2) +#define PDM_DAT1_PA3 SILABS_DBUS_PDM_DAT1(0x0, 0x3) +#define PDM_DAT1_PA4 SILABS_DBUS_PDM_DAT1(0x0, 0x4) +#define PDM_DAT1_PA5 SILABS_DBUS_PDM_DAT1(0x0, 0x5) +#define PDM_DAT1_PA6 SILABS_DBUS_PDM_DAT1(0x0, 0x6) +#define PDM_DAT1_PA7 SILABS_DBUS_PDM_DAT1(0x0, 0x7) +#define PDM_DAT1_PA8 SILABS_DBUS_PDM_DAT1(0x0, 0x8) +#define PDM_DAT1_PB0 SILABS_DBUS_PDM_DAT1(0x1, 0x0) +#define PDM_DAT1_PB1 SILABS_DBUS_PDM_DAT1(0x1, 0x1) +#define PDM_DAT1_PB2 SILABS_DBUS_PDM_DAT1(0x1, 0x2) +#define PDM_DAT1_PB3 SILABS_DBUS_PDM_DAT1(0x1, 0x3) +#define PDM_DAT1_PB4 SILABS_DBUS_PDM_DAT1(0x1, 0x4) +#define PDM_DAT1_PC0 SILABS_DBUS_PDM_DAT1(0x2, 0x0) +#define PDM_DAT1_PC1 SILABS_DBUS_PDM_DAT1(0x2, 0x1) +#define PDM_DAT1_PC2 SILABS_DBUS_PDM_DAT1(0x2, 0x2) +#define PDM_DAT1_PC3 SILABS_DBUS_PDM_DAT1(0x2, 0x3) +#define PDM_DAT1_PC4 SILABS_DBUS_PDM_DAT1(0x2, 0x4) +#define PDM_DAT1_PC5 SILABS_DBUS_PDM_DAT1(0x2, 0x5) +#define PDM_DAT1_PC6 SILABS_DBUS_PDM_DAT1(0x2, 0x6) +#define PDM_DAT1_PC7 SILABS_DBUS_PDM_DAT1(0x2, 0x7) +#define PDM_DAT1_PD0 SILABS_DBUS_PDM_DAT1(0x3, 0x0) +#define PDM_DAT1_PD1 SILABS_DBUS_PDM_DAT1(0x3, 0x1) +#define PDM_DAT1_PD2 SILABS_DBUS_PDM_DAT1(0x3, 0x2) +#define PDM_DAT1_PD3 SILABS_DBUS_PDM_DAT1(0x3, 0x3) + +#define PRS0_ASYNCH0_PA0 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x0) +#define PRS0_ASYNCH0_PA1 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x1) +#define PRS0_ASYNCH0_PA2 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x2) +#define PRS0_ASYNCH0_PA3 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x3) +#define PRS0_ASYNCH0_PA4 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x4) +#define PRS0_ASYNCH0_PA5 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x5) +#define PRS0_ASYNCH0_PA6 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x6) +#define PRS0_ASYNCH0_PA7 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x7) +#define PRS0_ASYNCH0_PA8 SILABS_DBUS_PRS0_ASYNCH0(0x0, 0x8) +#define PRS0_ASYNCH0_PB0 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x0) +#define PRS0_ASYNCH0_PB1 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x1) +#define PRS0_ASYNCH0_PB2 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x2) +#define PRS0_ASYNCH0_PB3 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x3) +#define PRS0_ASYNCH0_PB4 SILABS_DBUS_PRS0_ASYNCH0(0x1, 0x4) +#define PRS0_ASYNCH1_PA0 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x0) +#define PRS0_ASYNCH1_PA1 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x1) +#define PRS0_ASYNCH1_PA2 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x2) +#define PRS0_ASYNCH1_PA3 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x3) +#define PRS0_ASYNCH1_PA4 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x4) +#define PRS0_ASYNCH1_PA5 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x5) +#define PRS0_ASYNCH1_PA6 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x6) +#define PRS0_ASYNCH1_PA7 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x7) +#define PRS0_ASYNCH1_PA8 SILABS_DBUS_PRS0_ASYNCH1(0x0, 0x8) +#define PRS0_ASYNCH1_PB0 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x0) +#define PRS0_ASYNCH1_PB1 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x1) +#define PRS0_ASYNCH1_PB2 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x2) +#define PRS0_ASYNCH1_PB3 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x3) +#define PRS0_ASYNCH1_PB4 SILABS_DBUS_PRS0_ASYNCH1(0x1, 0x4) +#define PRS0_ASYNCH2_PA0 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x0) +#define PRS0_ASYNCH2_PA1 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x1) +#define PRS0_ASYNCH2_PA2 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x2) +#define PRS0_ASYNCH2_PA3 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x3) +#define PRS0_ASYNCH2_PA4 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x4) +#define PRS0_ASYNCH2_PA5 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x5) +#define PRS0_ASYNCH2_PA6 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x6) +#define PRS0_ASYNCH2_PA7 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x7) +#define PRS0_ASYNCH2_PA8 SILABS_DBUS_PRS0_ASYNCH2(0x0, 0x8) +#define PRS0_ASYNCH2_PB0 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x0) +#define PRS0_ASYNCH2_PB1 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x1) +#define PRS0_ASYNCH2_PB2 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x2) +#define PRS0_ASYNCH2_PB3 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x3) +#define PRS0_ASYNCH2_PB4 SILABS_DBUS_PRS0_ASYNCH2(0x1, 0x4) +#define PRS0_ASYNCH3_PA0 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x0) +#define PRS0_ASYNCH3_PA1 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x1) +#define PRS0_ASYNCH3_PA2 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x2) +#define PRS0_ASYNCH3_PA3 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x3) +#define PRS0_ASYNCH3_PA4 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x4) +#define PRS0_ASYNCH3_PA5 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x5) +#define PRS0_ASYNCH3_PA6 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x6) +#define PRS0_ASYNCH3_PA7 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x7) +#define PRS0_ASYNCH3_PA8 SILABS_DBUS_PRS0_ASYNCH3(0x0, 0x8) +#define PRS0_ASYNCH3_PB0 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x0) +#define PRS0_ASYNCH3_PB1 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x1) +#define PRS0_ASYNCH3_PB2 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x2) +#define PRS0_ASYNCH3_PB3 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x3) +#define PRS0_ASYNCH3_PB4 SILABS_DBUS_PRS0_ASYNCH3(0x1, 0x4) +#define PRS0_ASYNCH4_PA0 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x0) +#define PRS0_ASYNCH4_PA1 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x1) +#define PRS0_ASYNCH4_PA2 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x2) +#define PRS0_ASYNCH4_PA3 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x3) +#define PRS0_ASYNCH4_PA4 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x4) +#define PRS0_ASYNCH4_PA5 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x5) +#define PRS0_ASYNCH4_PA6 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x6) +#define PRS0_ASYNCH4_PA7 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x7) +#define PRS0_ASYNCH4_PA8 SILABS_DBUS_PRS0_ASYNCH4(0x0, 0x8) +#define PRS0_ASYNCH4_PB0 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x0) +#define PRS0_ASYNCH4_PB1 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x1) +#define PRS0_ASYNCH4_PB2 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x2) +#define PRS0_ASYNCH4_PB3 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x3) +#define PRS0_ASYNCH4_PB4 SILABS_DBUS_PRS0_ASYNCH4(0x1, 0x4) +#define PRS0_ASYNCH5_PA0 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x0) +#define PRS0_ASYNCH5_PA1 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x1) +#define PRS0_ASYNCH5_PA2 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x2) +#define PRS0_ASYNCH5_PA3 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x3) +#define PRS0_ASYNCH5_PA4 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x4) +#define PRS0_ASYNCH5_PA5 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x5) +#define PRS0_ASYNCH5_PA6 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x6) +#define PRS0_ASYNCH5_PA7 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x7) +#define PRS0_ASYNCH5_PA8 SILABS_DBUS_PRS0_ASYNCH5(0x0, 0x8) +#define PRS0_ASYNCH5_PB0 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x0) +#define PRS0_ASYNCH5_PB1 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x1) +#define PRS0_ASYNCH5_PB2 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x2) +#define PRS0_ASYNCH5_PB3 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x3) +#define PRS0_ASYNCH5_PB4 SILABS_DBUS_PRS0_ASYNCH5(0x1, 0x4) +#define PRS0_ASYNCH6_PC0 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x0) +#define PRS0_ASYNCH6_PC1 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x1) +#define PRS0_ASYNCH6_PC2 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x2) +#define PRS0_ASYNCH6_PC3 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x3) +#define PRS0_ASYNCH6_PC4 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x4) +#define PRS0_ASYNCH6_PC5 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x5) +#define PRS0_ASYNCH6_PC6 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x6) +#define PRS0_ASYNCH6_PC7 SILABS_DBUS_PRS0_ASYNCH6(0x2, 0x7) +#define PRS0_ASYNCH6_PD0 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x0) +#define PRS0_ASYNCH6_PD1 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x1) +#define PRS0_ASYNCH6_PD2 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x2) +#define PRS0_ASYNCH6_PD3 SILABS_DBUS_PRS0_ASYNCH6(0x3, 0x3) +#define PRS0_ASYNCH7_PC0 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x0) +#define PRS0_ASYNCH7_PC1 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x1) +#define PRS0_ASYNCH7_PC2 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x2) +#define PRS0_ASYNCH7_PC3 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x3) +#define PRS0_ASYNCH7_PC4 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x4) +#define PRS0_ASYNCH7_PC5 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x5) +#define PRS0_ASYNCH7_PC6 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x6) +#define PRS0_ASYNCH7_PC7 SILABS_DBUS_PRS0_ASYNCH7(0x2, 0x7) +#define PRS0_ASYNCH7_PD0 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x0) +#define PRS0_ASYNCH7_PD1 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x1) +#define PRS0_ASYNCH7_PD2 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x2) +#define PRS0_ASYNCH7_PD3 SILABS_DBUS_PRS0_ASYNCH7(0x3, 0x3) +#define PRS0_ASYNCH8_PC0 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x0) +#define PRS0_ASYNCH8_PC1 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x1) +#define PRS0_ASYNCH8_PC2 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x2) +#define PRS0_ASYNCH8_PC3 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x3) +#define PRS0_ASYNCH8_PC4 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x4) +#define PRS0_ASYNCH8_PC5 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x5) +#define PRS0_ASYNCH8_PC6 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x6) +#define PRS0_ASYNCH8_PC7 SILABS_DBUS_PRS0_ASYNCH8(0x2, 0x7) +#define PRS0_ASYNCH8_PD0 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x0) +#define PRS0_ASYNCH8_PD1 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x1) +#define PRS0_ASYNCH8_PD2 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x2) +#define PRS0_ASYNCH8_PD3 SILABS_DBUS_PRS0_ASYNCH8(0x3, 0x3) +#define PRS0_ASYNCH9_PC0 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x0) +#define PRS0_ASYNCH9_PC1 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x1) +#define PRS0_ASYNCH9_PC2 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x2) +#define PRS0_ASYNCH9_PC3 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x3) +#define PRS0_ASYNCH9_PC4 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x4) +#define PRS0_ASYNCH9_PC5 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x5) +#define PRS0_ASYNCH9_PC6 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x6) +#define PRS0_ASYNCH9_PC7 SILABS_DBUS_PRS0_ASYNCH9(0x2, 0x7) +#define PRS0_ASYNCH9_PD0 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x0) +#define PRS0_ASYNCH9_PD1 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x1) +#define PRS0_ASYNCH9_PD2 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x2) +#define PRS0_ASYNCH9_PD3 SILABS_DBUS_PRS0_ASYNCH9(0x3, 0x3) +#define PRS0_ASYNCH10_PC0 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x0) +#define PRS0_ASYNCH10_PC1 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x1) +#define PRS0_ASYNCH10_PC2 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x2) +#define PRS0_ASYNCH10_PC3 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x3) +#define PRS0_ASYNCH10_PC4 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x4) +#define PRS0_ASYNCH10_PC5 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x5) +#define PRS0_ASYNCH10_PC6 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x6) +#define PRS0_ASYNCH10_PC7 SILABS_DBUS_PRS0_ASYNCH10(0x2, 0x7) +#define PRS0_ASYNCH10_PD0 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x0) +#define PRS0_ASYNCH10_PD1 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x1) +#define PRS0_ASYNCH10_PD2 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x2) +#define PRS0_ASYNCH10_PD3 SILABS_DBUS_PRS0_ASYNCH10(0x3, 0x3) +#define PRS0_ASYNCH11_PC0 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x0) +#define PRS0_ASYNCH11_PC1 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x1) +#define PRS0_ASYNCH11_PC2 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x2) +#define PRS0_ASYNCH11_PC3 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x3) +#define PRS0_ASYNCH11_PC4 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x4) +#define PRS0_ASYNCH11_PC5 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x5) +#define PRS0_ASYNCH11_PC6 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x6) +#define PRS0_ASYNCH11_PC7 SILABS_DBUS_PRS0_ASYNCH11(0x2, 0x7) +#define PRS0_ASYNCH11_PD0 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x0) +#define PRS0_ASYNCH11_PD1 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x1) +#define PRS0_ASYNCH11_PD2 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x2) +#define PRS0_ASYNCH11_PD3 SILABS_DBUS_PRS0_ASYNCH11(0x3, 0x3) +#define PRS0_SYNCH0_PA0 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x0) +#define PRS0_SYNCH0_PA1 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x1) +#define PRS0_SYNCH0_PA2 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x2) +#define PRS0_SYNCH0_PA3 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x3) +#define PRS0_SYNCH0_PA4 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x4) +#define PRS0_SYNCH0_PA5 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x5) +#define PRS0_SYNCH0_PA6 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x6) +#define PRS0_SYNCH0_PA7 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x7) +#define PRS0_SYNCH0_PA8 SILABS_DBUS_PRS0_SYNCH0(0x0, 0x8) +#define PRS0_SYNCH0_PB0 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x0) +#define PRS0_SYNCH0_PB1 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x1) +#define PRS0_SYNCH0_PB2 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x2) +#define PRS0_SYNCH0_PB3 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x3) +#define PRS0_SYNCH0_PB4 SILABS_DBUS_PRS0_SYNCH0(0x1, 0x4) +#define PRS0_SYNCH0_PC0 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x0) +#define PRS0_SYNCH0_PC1 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x1) +#define PRS0_SYNCH0_PC2 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x2) +#define PRS0_SYNCH0_PC3 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x3) +#define PRS0_SYNCH0_PC4 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x4) +#define PRS0_SYNCH0_PC5 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x5) +#define PRS0_SYNCH0_PC6 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x6) +#define PRS0_SYNCH0_PC7 SILABS_DBUS_PRS0_SYNCH0(0x2, 0x7) +#define PRS0_SYNCH0_PD0 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x0) +#define PRS0_SYNCH0_PD1 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x1) +#define PRS0_SYNCH0_PD2 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x2) +#define PRS0_SYNCH0_PD3 SILABS_DBUS_PRS0_SYNCH0(0x3, 0x3) +#define PRS0_SYNCH1_PA0 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x0) +#define PRS0_SYNCH1_PA1 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x1) +#define PRS0_SYNCH1_PA2 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x2) +#define PRS0_SYNCH1_PA3 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x3) +#define PRS0_SYNCH1_PA4 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x4) +#define PRS0_SYNCH1_PA5 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x5) +#define PRS0_SYNCH1_PA6 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x6) +#define PRS0_SYNCH1_PA7 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x7) +#define PRS0_SYNCH1_PA8 SILABS_DBUS_PRS0_SYNCH1(0x0, 0x8) +#define PRS0_SYNCH1_PB0 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x0) +#define PRS0_SYNCH1_PB1 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x1) +#define PRS0_SYNCH1_PB2 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x2) +#define PRS0_SYNCH1_PB3 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x3) +#define PRS0_SYNCH1_PB4 SILABS_DBUS_PRS0_SYNCH1(0x1, 0x4) +#define PRS0_SYNCH1_PC0 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x0) +#define PRS0_SYNCH1_PC1 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x1) +#define PRS0_SYNCH1_PC2 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x2) +#define PRS0_SYNCH1_PC3 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x3) +#define PRS0_SYNCH1_PC4 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x4) +#define PRS0_SYNCH1_PC5 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x5) +#define PRS0_SYNCH1_PC6 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x6) +#define PRS0_SYNCH1_PC7 SILABS_DBUS_PRS0_SYNCH1(0x2, 0x7) +#define PRS0_SYNCH1_PD0 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x0) +#define PRS0_SYNCH1_PD1 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x1) +#define PRS0_SYNCH1_PD2 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x2) +#define PRS0_SYNCH1_PD3 SILABS_DBUS_PRS0_SYNCH1(0x3, 0x3) +#define PRS0_SYNCH2_PA0 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x0) +#define PRS0_SYNCH2_PA1 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x1) +#define PRS0_SYNCH2_PA2 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x2) +#define PRS0_SYNCH2_PA3 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x3) +#define PRS0_SYNCH2_PA4 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x4) +#define PRS0_SYNCH2_PA5 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x5) +#define PRS0_SYNCH2_PA6 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x6) +#define PRS0_SYNCH2_PA7 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x7) +#define PRS0_SYNCH2_PA8 SILABS_DBUS_PRS0_SYNCH2(0x0, 0x8) +#define PRS0_SYNCH2_PB0 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x0) +#define PRS0_SYNCH2_PB1 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x1) +#define PRS0_SYNCH2_PB2 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x2) +#define PRS0_SYNCH2_PB3 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x3) +#define PRS0_SYNCH2_PB4 SILABS_DBUS_PRS0_SYNCH2(0x1, 0x4) +#define PRS0_SYNCH2_PC0 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x0) +#define PRS0_SYNCH2_PC1 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x1) +#define PRS0_SYNCH2_PC2 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x2) +#define PRS0_SYNCH2_PC3 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x3) +#define PRS0_SYNCH2_PC4 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x4) +#define PRS0_SYNCH2_PC5 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x5) +#define PRS0_SYNCH2_PC6 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x6) +#define PRS0_SYNCH2_PC7 SILABS_DBUS_PRS0_SYNCH2(0x2, 0x7) +#define PRS0_SYNCH2_PD0 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x0) +#define PRS0_SYNCH2_PD1 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x1) +#define PRS0_SYNCH2_PD2 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x2) +#define PRS0_SYNCH2_PD3 SILABS_DBUS_PRS0_SYNCH2(0x3, 0x3) +#define PRS0_SYNCH3_PA0 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x0) +#define PRS0_SYNCH3_PA1 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x1) +#define PRS0_SYNCH3_PA2 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x2) +#define PRS0_SYNCH3_PA3 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x3) +#define PRS0_SYNCH3_PA4 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x4) +#define PRS0_SYNCH3_PA5 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x5) +#define PRS0_SYNCH3_PA6 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x6) +#define PRS0_SYNCH3_PA7 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x7) +#define PRS0_SYNCH3_PA8 SILABS_DBUS_PRS0_SYNCH3(0x0, 0x8) +#define PRS0_SYNCH3_PB0 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x0) +#define PRS0_SYNCH3_PB1 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x1) +#define PRS0_SYNCH3_PB2 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x2) +#define PRS0_SYNCH3_PB3 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x3) +#define PRS0_SYNCH3_PB4 SILABS_DBUS_PRS0_SYNCH3(0x1, 0x4) +#define PRS0_SYNCH3_PC0 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x0) +#define PRS0_SYNCH3_PC1 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x1) +#define PRS0_SYNCH3_PC2 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x2) +#define PRS0_SYNCH3_PC3 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x3) +#define PRS0_SYNCH3_PC4 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x4) +#define PRS0_SYNCH3_PC5 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x5) +#define PRS0_SYNCH3_PC6 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x6) +#define PRS0_SYNCH3_PC7 SILABS_DBUS_PRS0_SYNCH3(0x2, 0x7) +#define PRS0_SYNCH3_PD0 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x0) +#define PRS0_SYNCH3_PD1 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x1) +#define PRS0_SYNCH3_PD2 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x2) +#define PRS0_SYNCH3_PD3 SILABS_DBUS_PRS0_SYNCH3(0x3, 0x3) + +#define TIMER0_CC0_PA0 SILABS_DBUS_TIMER0_CC0(0x0, 0x0) +#define TIMER0_CC0_PA1 SILABS_DBUS_TIMER0_CC0(0x0, 0x1) +#define TIMER0_CC0_PA2 SILABS_DBUS_TIMER0_CC0(0x0, 0x2) +#define TIMER0_CC0_PA3 SILABS_DBUS_TIMER0_CC0(0x0, 0x3) +#define TIMER0_CC0_PA4 SILABS_DBUS_TIMER0_CC0(0x0, 0x4) +#define TIMER0_CC0_PA5 SILABS_DBUS_TIMER0_CC0(0x0, 0x5) +#define TIMER0_CC0_PA6 SILABS_DBUS_TIMER0_CC0(0x0, 0x6) +#define TIMER0_CC0_PA7 SILABS_DBUS_TIMER0_CC0(0x0, 0x7) +#define TIMER0_CC0_PA8 SILABS_DBUS_TIMER0_CC0(0x0, 0x8) +#define TIMER0_CC0_PB0 SILABS_DBUS_TIMER0_CC0(0x1, 0x0) +#define TIMER0_CC0_PB1 SILABS_DBUS_TIMER0_CC0(0x1, 0x1) +#define TIMER0_CC0_PB2 SILABS_DBUS_TIMER0_CC0(0x1, 0x2) +#define TIMER0_CC0_PB3 SILABS_DBUS_TIMER0_CC0(0x1, 0x3) +#define TIMER0_CC0_PB4 SILABS_DBUS_TIMER0_CC0(0x1, 0x4) +#define TIMER0_CC0_PC0 SILABS_DBUS_TIMER0_CC0(0x2, 0x0) +#define TIMER0_CC0_PC1 SILABS_DBUS_TIMER0_CC0(0x2, 0x1) +#define TIMER0_CC0_PC2 SILABS_DBUS_TIMER0_CC0(0x2, 0x2) +#define TIMER0_CC0_PC3 SILABS_DBUS_TIMER0_CC0(0x2, 0x3) +#define TIMER0_CC0_PC4 SILABS_DBUS_TIMER0_CC0(0x2, 0x4) +#define TIMER0_CC0_PC5 SILABS_DBUS_TIMER0_CC0(0x2, 0x5) +#define TIMER0_CC0_PC6 SILABS_DBUS_TIMER0_CC0(0x2, 0x6) +#define TIMER0_CC0_PC7 SILABS_DBUS_TIMER0_CC0(0x2, 0x7) +#define TIMER0_CC0_PD0 SILABS_DBUS_TIMER0_CC0(0x3, 0x0) +#define TIMER0_CC0_PD1 SILABS_DBUS_TIMER0_CC0(0x3, 0x1) +#define TIMER0_CC0_PD2 SILABS_DBUS_TIMER0_CC0(0x3, 0x2) +#define TIMER0_CC0_PD3 SILABS_DBUS_TIMER0_CC0(0x3, 0x3) +#define TIMER0_CC1_PA0 SILABS_DBUS_TIMER0_CC1(0x0, 0x0) +#define TIMER0_CC1_PA1 SILABS_DBUS_TIMER0_CC1(0x0, 0x1) +#define TIMER0_CC1_PA2 SILABS_DBUS_TIMER0_CC1(0x0, 0x2) +#define TIMER0_CC1_PA3 SILABS_DBUS_TIMER0_CC1(0x0, 0x3) +#define TIMER0_CC1_PA4 SILABS_DBUS_TIMER0_CC1(0x0, 0x4) +#define TIMER0_CC1_PA5 SILABS_DBUS_TIMER0_CC1(0x0, 0x5) +#define TIMER0_CC1_PA6 SILABS_DBUS_TIMER0_CC1(0x0, 0x6) +#define TIMER0_CC1_PA7 SILABS_DBUS_TIMER0_CC1(0x0, 0x7) +#define TIMER0_CC1_PA8 SILABS_DBUS_TIMER0_CC1(0x0, 0x8) +#define TIMER0_CC1_PB0 SILABS_DBUS_TIMER0_CC1(0x1, 0x0) +#define TIMER0_CC1_PB1 SILABS_DBUS_TIMER0_CC1(0x1, 0x1) +#define TIMER0_CC1_PB2 SILABS_DBUS_TIMER0_CC1(0x1, 0x2) +#define TIMER0_CC1_PB3 SILABS_DBUS_TIMER0_CC1(0x1, 0x3) +#define TIMER0_CC1_PB4 SILABS_DBUS_TIMER0_CC1(0x1, 0x4) +#define TIMER0_CC1_PC0 SILABS_DBUS_TIMER0_CC1(0x2, 0x0) +#define TIMER0_CC1_PC1 SILABS_DBUS_TIMER0_CC1(0x2, 0x1) +#define TIMER0_CC1_PC2 SILABS_DBUS_TIMER0_CC1(0x2, 0x2) +#define TIMER0_CC1_PC3 SILABS_DBUS_TIMER0_CC1(0x2, 0x3) +#define TIMER0_CC1_PC4 SILABS_DBUS_TIMER0_CC1(0x2, 0x4) +#define TIMER0_CC1_PC5 SILABS_DBUS_TIMER0_CC1(0x2, 0x5) +#define TIMER0_CC1_PC6 SILABS_DBUS_TIMER0_CC1(0x2, 0x6) +#define TIMER0_CC1_PC7 SILABS_DBUS_TIMER0_CC1(0x2, 0x7) +#define TIMER0_CC1_PD0 SILABS_DBUS_TIMER0_CC1(0x3, 0x0) +#define TIMER0_CC1_PD1 SILABS_DBUS_TIMER0_CC1(0x3, 0x1) +#define TIMER0_CC1_PD2 SILABS_DBUS_TIMER0_CC1(0x3, 0x2) +#define TIMER0_CC1_PD3 SILABS_DBUS_TIMER0_CC1(0x3, 0x3) +#define TIMER0_CC2_PA0 SILABS_DBUS_TIMER0_CC2(0x0, 0x0) +#define TIMER0_CC2_PA1 SILABS_DBUS_TIMER0_CC2(0x0, 0x1) +#define TIMER0_CC2_PA2 SILABS_DBUS_TIMER0_CC2(0x0, 0x2) +#define TIMER0_CC2_PA3 SILABS_DBUS_TIMER0_CC2(0x0, 0x3) +#define TIMER0_CC2_PA4 SILABS_DBUS_TIMER0_CC2(0x0, 0x4) +#define TIMER0_CC2_PA5 SILABS_DBUS_TIMER0_CC2(0x0, 0x5) +#define TIMER0_CC2_PA6 SILABS_DBUS_TIMER0_CC2(0x0, 0x6) +#define TIMER0_CC2_PA7 SILABS_DBUS_TIMER0_CC2(0x0, 0x7) +#define TIMER0_CC2_PA8 SILABS_DBUS_TIMER0_CC2(0x0, 0x8) +#define TIMER0_CC2_PB0 SILABS_DBUS_TIMER0_CC2(0x1, 0x0) +#define TIMER0_CC2_PB1 SILABS_DBUS_TIMER0_CC2(0x1, 0x1) +#define TIMER0_CC2_PB2 SILABS_DBUS_TIMER0_CC2(0x1, 0x2) +#define TIMER0_CC2_PB3 SILABS_DBUS_TIMER0_CC2(0x1, 0x3) +#define TIMER0_CC2_PB4 SILABS_DBUS_TIMER0_CC2(0x1, 0x4) +#define TIMER0_CC2_PC0 SILABS_DBUS_TIMER0_CC2(0x2, 0x0) +#define TIMER0_CC2_PC1 SILABS_DBUS_TIMER0_CC2(0x2, 0x1) +#define TIMER0_CC2_PC2 SILABS_DBUS_TIMER0_CC2(0x2, 0x2) +#define TIMER0_CC2_PC3 SILABS_DBUS_TIMER0_CC2(0x2, 0x3) +#define TIMER0_CC2_PC4 SILABS_DBUS_TIMER0_CC2(0x2, 0x4) +#define TIMER0_CC2_PC5 SILABS_DBUS_TIMER0_CC2(0x2, 0x5) +#define TIMER0_CC2_PC6 SILABS_DBUS_TIMER0_CC2(0x2, 0x6) +#define TIMER0_CC2_PC7 SILABS_DBUS_TIMER0_CC2(0x2, 0x7) +#define TIMER0_CC2_PD0 SILABS_DBUS_TIMER0_CC2(0x3, 0x0) +#define TIMER0_CC2_PD1 SILABS_DBUS_TIMER0_CC2(0x3, 0x1) +#define TIMER0_CC2_PD2 SILABS_DBUS_TIMER0_CC2(0x3, 0x2) +#define TIMER0_CC2_PD3 SILABS_DBUS_TIMER0_CC2(0x3, 0x3) +#define TIMER0_CDTI0_PA0 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x0) +#define TIMER0_CDTI0_PA1 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x1) +#define TIMER0_CDTI0_PA2 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x2) +#define TIMER0_CDTI0_PA3 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x3) +#define TIMER0_CDTI0_PA4 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x4) +#define TIMER0_CDTI0_PA5 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x5) +#define TIMER0_CDTI0_PA6 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x6) +#define TIMER0_CDTI0_PA7 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x7) +#define TIMER0_CDTI0_PA8 SILABS_DBUS_TIMER0_CDTI0(0x0, 0x8) +#define TIMER0_CDTI0_PB0 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x0) +#define TIMER0_CDTI0_PB1 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x1) +#define TIMER0_CDTI0_PB2 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x2) +#define TIMER0_CDTI0_PB3 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x3) +#define TIMER0_CDTI0_PB4 SILABS_DBUS_TIMER0_CDTI0(0x1, 0x4) +#define TIMER0_CDTI0_PC0 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x0) +#define TIMER0_CDTI0_PC1 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x1) +#define TIMER0_CDTI0_PC2 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x2) +#define TIMER0_CDTI0_PC3 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x3) +#define TIMER0_CDTI0_PC4 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x4) +#define TIMER0_CDTI0_PC5 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x5) +#define TIMER0_CDTI0_PC6 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x6) +#define TIMER0_CDTI0_PC7 SILABS_DBUS_TIMER0_CDTI0(0x2, 0x7) +#define TIMER0_CDTI0_PD0 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x0) +#define TIMER0_CDTI0_PD1 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x1) +#define TIMER0_CDTI0_PD2 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x2) +#define TIMER0_CDTI0_PD3 SILABS_DBUS_TIMER0_CDTI0(0x3, 0x3) +#define TIMER0_CDTI1_PA0 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x0) +#define TIMER0_CDTI1_PA1 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x1) +#define TIMER0_CDTI1_PA2 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x2) +#define TIMER0_CDTI1_PA3 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x3) +#define TIMER0_CDTI1_PA4 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x4) +#define TIMER0_CDTI1_PA5 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x5) +#define TIMER0_CDTI1_PA6 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x6) +#define TIMER0_CDTI1_PA7 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x7) +#define TIMER0_CDTI1_PA8 SILABS_DBUS_TIMER0_CDTI1(0x0, 0x8) +#define TIMER0_CDTI1_PB0 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x0) +#define TIMER0_CDTI1_PB1 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x1) +#define TIMER0_CDTI1_PB2 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x2) +#define TIMER0_CDTI1_PB3 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x3) +#define TIMER0_CDTI1_PB4 SILABS_DBUS_TIMER0_CDTI1(0x1, 0x4) +#define TIMER0_CDTI1_PC0 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x0) +#define TIMER0_CDTI1_PC1 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x1) +#define TIMER0_CDTI1_PC2 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x2) +#define TIMER0_CDTI1_PC3 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x3) +#define TIMER0_CDTI1_PC4 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x4) +#define TIMER0_CDTI1_PC5 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x5) +#define TIMER0_CDTI1_PC6 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x6) +#define TIMER0_CDTI1_PC7 SILABS_DBUS_TIMER0_CDTI1(0x2, 0x7) +#define TIMER0_CDTI1_PD0 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x0) +#define TIMER0_CDTI1_PD1 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x1) +#define TIMER0_CDTI1_PD2 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x2) +#define TIMER0_CDTI1_PD3 SILABS_DBUS_TIMER0_CDTI1(0x3, 0x3) +#define TIMER0_CDTI2_PA0 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x0) +#define TIMER0_CDTI2_PA1 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x1) +#define TIMER0_CDTI2_PA2 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x2) +#define TIMER0_CDTI2_PA3 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x3) +#define TIMER0_CDTI2_PA4 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x4) +#define TIMER0_CDTI2_PA5 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x5) +#define TIMER0_CDTI2_PA6 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x6) +#define TIMER0_CDTI2_PA7 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x7) +#define TIMER0_CDTI2_PA8 SILABS_DBUS_TIMER0_CDTI2(0x0, 0x8) +#define TIMER0_CDTI2_PB0 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x0) +#define TIMER0_CDTI2_PB1 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x1) +#define TIMER0_CDTI2_PB2 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x2) +#define TIMER0_CDTI2_PB3 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x3) +#define TIMER0_CDTI2_PB4 SILABS_DBUS_TIMER0_CDTI2(0x1, 0x4) +#define TIMER0_CDTI2_PC0 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x0) +#define TIMER0_CDTI2_PC1 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x1) +#define TIMER0_CDTI2_PC2 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x2) +#define TIMER0_CDTI2_PC3 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x3) +#define TIMER0_CDTI2_PC4 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x4) +#define TIMER0_CDTI2_PC5 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x5) +#define TIMER0_CDTI2_PC6 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x6) +#define TIMER0_CDTI2_PC7 SILABS_DBUS_TIMER0_CDTI2(0x2, 0x7) +#define TIMER0_CDTI2_PD0 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x0) +#define TIMER0_CDTI2_PD1 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x1) +#define TIMER0_CDTI2_PD2 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x2) +#define TIMER0_CDTI2_PD3 SILABS_DBUS_TIMER0_CDTI2(0x3, 0x3) + +#define TIMER1_CC0_PA0 SILABS_DBUS_TIMER1_CC0(0x0, 0x0) +#define TIMER1_CC0_PA1 SILABS_DBUS_TIMER1_CC0(0x0, 0x1) +#define TIMER1_CC0_PA2 SILABS_DBUS_TIMER1_CC0(0x0, 0x2) +#define TIMER1_CC0_PA3 SILABS_DBUS_TIMER1_CC0(0x0, 0x3) +#define TIMER1_CC0_PA4 SILABS_DBUS_TIMER1_CC0(0x0, 0x4) +#define TIMER1_CC0_PA5 SILABS_DBUS_TIMER1_CC0(0x0, 0x5) +#define TIMER1_CC0_PA6 SILABS_DBUS_TIMER1_CC0(0x0, 0x6) +#define TIMER1_CC0_PA7 SILABS_DBUS_TIMER1_CC0(0x0, 0x7) +#define TIMER1_CC0_PA8 SILABS_DBUS_TIMER1_CC0(0x0, 0x8) +#define TIMER1_CC0_PB0 SILABS_DBUS_TIMER1_CC0(0x1, 0x0) +#define TIMER1_CC0_PB1 SILABS_DBUS_TIMER1_CC0(0x1, 0x1) +#define TIMER1_CC0_PB2 SILABS_DBUS_TIMER1_CC0(0x1, 0x2) +#define TIMER1_CC0_PB3 SILABS_DBUS_TIMER1_CC0(0x1, 0x3) +#define TIMER1_CC0_PB4 SILABS_DBUS_TIMER1_CC0(0x1, 0x4) +#define TIMER1_CC0_PC0 SILABS_DBUS_TIMER1_CC0(0x2, 0x0) +#define TIMER1_CC0_PC1 SILABS_DBUS_TIMER1_CC0(0x2, 0x1) +#define TIMER1_CC0_PC2 SILABS_DBUS_TIMER1_CC0(0x2, 0x2) +#define TIMER1_CC0_PC3 SILABS_DBUS_TIMER1_CC0(0x2, 0x3) +#define TIMER1_CC0_PC4 SILABS_DBUS_TIMER1_CC0(0x2, 0x4) +#define TIMER1_CC0_PC5 SILABS_DBUS_TIMER1_CC0(0x2, 0x5) +#define TIMER1_CC0_PC6 SILABS_DBUS_TIMER1_CC0(0x2, 0x6) +#define TIMER1_CC0_PC7 SILABS_DBUS_TIMER1_CC0(0x2, 0x7) +#define TIMER1_CC0_PD0 SILABS_DBUS_TIMER1_CC0(0x3, 0x0) +#define TIMER1_CC0_PD1 SILABS_DBUS_TIMER1_CC0(0x3, 0x1) +#define TIMER1_CC0_PD2 SILABS_DBUS_TIMER1_CC0(0x3, 0x2) +#define TIMER1_CC0_PD3 SILABS_DBUS_TIMER1_CC0(0x3, 0x3) +#define TIMER1_CC1_PA0 SILABS_DBUS_TIMER1_CC1(0x0, 0x0) +#define TIMER1_CC1_PA1 SILABS_DBUS_TIMER1_CC1(0x0, 0x1) +#define TIMER1_CC1_PA2 SILABS_DBUS_TIMER1_CC1(0x0, 0x2) +#define TIMER1_CC1_PA3 SILABS_DBUS_TIMER1_CC1(0x0, 0x3) +#define TIMER1_CC1_PA4 SILABS_DBUS_TIMER1_CC1(0x0, 0x4) +#define TIMER1_CC1_PA5 SILABS_DBUS_TIMER1_CC1(0x0, 0x5) +#define TIMER1_CC1_PA6 SILABS_DBUS_TIMER1_CC1(0x0, 0x6) +#define TIMER1_CC1_PA7 SILABS_DBUS_TIMER1_CC1(0x0, 0x7) +#define TIMER1_CC1_PA8 SILABS_DBUS_TIMER1_CC1(0x0, 0x8) +#define TIMER1_CC1_PB0 SILABS_DBUS_TIMER1_CC1(0x1, 0x0) +#define TIMER1_CC1_PB1 SILABS_DBUS_TIMER1_CC1(0x1, 0x1) +#define TIMER1_CC1_PB2 SILABS_DBUS_TIMER1_CC1(0x1, 0x2) +#define TIMER1_CC1_PB3 SILABS_DBUS_TIMER1_CC1(0x1, 0x3) +#define TIMER1_CC1_PB4 SILABS_DBUS_TIMER1_CC1(0x1, 0x4) +#define TIMER1_CC1_PC0 SILABS_DBUS_TIMER1_CC1(0x2, 0x0) +#define TIMER1_CC1_PC1 SILABS_DBUS_TIMER1_CC1(0x2, 0x1) +#define TIMER1_CC1_PC2 SILABS_DBUS_TIMER1_CC1(0x2, 0x2) +#define TIMER1_CC1_PC3 SILABS_DBUS_TIMER1_CC1(0x2, 0x3) +#define TIMER1_CC1_PC4 SILABS_DBUS_TIMER1_CC1(0x2, 0x4) +#define TIMER1_CC1_PC5 SILABS_DBUS_TIMER1_CC1(0x2, 0x5) +#define TIMER1_CC1_PC6 SILABS_DBUS_TIMER1_CC1(0x2, 0x6) +#define TIMER1_CC1_PC7 SILABS_DBUS_TIMER1_CC1(0x2, 0x7) +#define TIMER1_CC1_PD0 SILABS_DBUS_TIMER1_CC1(0x3, 0x0) +#define TIMER1_CC1_PD1 SILABS_DBUS_TIMER1_CC1(0x3, 0x1) +#define TIMER1_CC1_PD2 SILABS_DBUS_TIMER1_CC1(0x3, 0x2) +#define TIMER1_CC1_PD3 SILABS_DBUS_TIMER1_CC1(0x3, 0x3) +#define TIMER1_CC2_PA0 SILABS_DBUS_TIMER1_CC2(0x0, 0x0) +#define TIMER1_CC2_PA1 SILABS_DBUS_TIMER1_CC2(0x0, 0x1) +#define TIMER1_CC2_PA2 SILABS_DBUS_TIMER1_CC2(0x0, 0x2) +#define TIMER1_CC2_PA3 SILABS_DBUS_TIMER1_CC2(0x0, 0x3) +#define TIMER1_CC2_PA4 SILABS_DBUS_TIMER1_CC2(0x0, 0x4) +#define TIMER1_CC2_PA5 SILABS_DBUS_TIMER1_CC2(0x0, 0x5) +#define TIMER1_CC2_PA6 SILABS_DBUS_TIMER1_CC2(0x0, 0x6) +#define TIMER1_CC2_PA7 SILABS_DBUS_TIMER1_CC2(0x0, 0x7) +#define TIMER1_CC2_PA8 SILABS_DBUS_TIMER1_CC2(0x0, 0x8) +#define TIMER1_CC2_PB0 SILABS_DBUS_TIMER1_CC2(0x1, 0x0) +#define TIMER1_CC2_PB1 SILABS_DBUS_TIMER1_CC2(0x1, 0x1) +#define TIMER1_CC2_PB2 SILABS_DBUS_TIMER1_CC2(0x1, 0x2) +#define TIMER1_CC2_PB3 SILABS_DBUS_TIMER1_CC2(0x1, 0x3) +#define TIMER1_CC2_PB4 SILABS_DBUS_TIMER1_CC2(0x1, 0x4) +#define TIMER1_CC2_PC0 SILABS_DBUS_TIMER1_CC2(0x2, 0x0) +#define TIMER1_CC2_PC1 SILABS_DBUS_TIMER1_CC2(0x2, 0x1) +#define TIMER1_CC2_PC2 SILABS_DBUS_TIMER1_CC2(0x2, 0x2) +#define TIMER1_CC2_PC3 SILABS_DBUS_TIMER1_CC2(0x2, 0x3) +#define TIMER1_CC2_PC4 SILABS_DBUS_TIMER1_CC2(0x2, 0x4) +#define TIMER1_CC2_PC5 SILABS_DBUS_TIMER1_CC2(0x2, 0x5) +#define TIMER1_CC2_PC6 SILABS_DBUS_TIMER1_CC2(0x2, 0x6) +#define TIMER1_CC2_PC7 SILABS_DBUS_TIMER1_CC2(0x2, 0x7) +#define TIMER1_CC2_PD0 SILABS_DBUS_TIMER1_CC2(0x3, 0x0) +#define TIMER1_CC2_PD1 SILABS_DBUS_TIMER1_CC2(0x3, 0x1) +#define TIMER1_CC2_PD2 SILABS_DBUS_TIMER1_CC2(0x3, 0x2) +#define TIMER1_CC2_PD3 SILABS_DBUS_TIMER1_CC2(0x3, 0x3) +#define TIMER1_CDTI0_PA0 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x0) +#define TIMER1_CDTI0_PA1 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x1) +#define TIMER1_CDTI0_PA2 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x2) +#define TIMER1_CDTI0_PA3 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x3) +#define TIMER1_CDTI0_PA4 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x4) +#define TIMER1_CDTI0_PA5 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x5) +#define TIMER1_CDTI0_PA6 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x6) +#define TIMER1_CDTI0_PA7 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x7) +#define TIMER1_CDTI0_PA8 SILABS_DBUS_TIMER1_CDTI0(0x0, 0x8) +#define TIMER1_CDTI0_PB0 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x0) +#define TIMER1_CDTI0_PB1 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x1) +#define TIMER1_CDTI0_PB2 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x2) +#define TIMER1_CDTI0_PB3 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x3) +#define TIMER1_CDTI0_PB4 SILABS_DBUS_TIMER1_CDTI0(0x1, 0x4) +#define TIMER1_CDTI0_PC0 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x0) +#define TIMER1_CDTI0_PC1 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x1) +#define TIMER1_CDTI0_PC2 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x2) +#define TIMER1_CDTI0_PC3 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x3) +#define TIMER1_CDTI0_PC4 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x4) +#define TIMER1_CDTI0_PC5 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x5) +#define TIMER1_CDTI0_PC6 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x6) +#define TIMER1_CDTI0_PC7 SILABS_DBUS_TIMER1_CDTI0(0x2, 0x7) +#define TIMER1_CDTI0_PD0 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x0) +#define TIMER1_CDTI0_PD1 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x1) +#define TIMER1_CDTI0_PD2 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x2) +#define TIMER1_CDTI0_PD3 SILABS_DBUS_TIMER1_CDTI0(0x3, 0x3) +#define TIMER1_CDTI1_PA0 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x0) +#define TIMER1_CDTI1_PA1 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x1) +#define TIMER1_CDTI1_PA2 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x2) +#define TIMER1_CDTI1_PA3 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x3) +#define TIMER1_CDTI1_PA4 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x4) +#define TIMER1_CDTI1_PA5 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x5) +#define TIMER1_CDTI1_PA6 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x6) +#define TIMER1_CDTI1_PA7 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x7) +#define TIMER1_CDTI1_PA8 SILABS_DBUS_TIMER1_CDTI1(0x0, 0x8) +#define TIMER1_CDTI1_PB0 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x0) +#define TIMER1_CDTI1_PB1 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x1) +#define TIMER1_CDTI1_PB2 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x2) +#define TIMER1_CDTI1_PB3 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x3) +#define TIMER1_CDTI1_PB4 SILABS_DBUS_TIMER1_CDTI1(0x1, 0x4) +#define TIMER1_CDTI1_PC0 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x0) +#define TIMER1_CDTI1_PC1 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x1) +#define TIMER1_CDTI1_PC2 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x2) +#define TIMER1_CDTI1_PC3 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x3) +#define TIMER1_CDTI1_PC4 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x4) +#define TIMER1_CDTI1_PC5 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x5) +#define TIMER1_CDTI1_PC6 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x6) +#define TIMER1_CDTI1_PC7 SILABS_DBUS_TIMER1_CDTI1(0x2, 0x7) +#define TIMER1_CDTI1_PD0 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x0) +#define TIMER1_CDTI1_PD1 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x1) +#define TIMER1_CDTI1_PD2 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x2) +#define TIMER1_CDTI1_PD3 SILABS_DBUS_TIMER1_CDTI1(0x3, 0x3) +#define TIMER1_CDTI2_PA0 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x0) +#define TIMER1_CDTI2_PA1 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x1) +#define TIMER1_CDTI2_PA2 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x2) +#define TIMER1_CDTI2_PA3 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x3) +#define TIMER1_CDTI2_PA4 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x4) +#define TIMER1_CDTI2_PA5 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x5) +#define TIMER1_CDTI2_PA6 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x6) +#define TIMER1_CDTI2_PA7 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x7) +#define TIMER1_CDTI2_PA8 SILABS_DBUS_TIMER1_CDTI2(0x0, 0x8) +#define TIMER1_CDTI2_PB0 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x0) +#define TIMER1_CDTI2_PB1 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x1) +#define TIMER1_CDTI2_PB2 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x2) +#define TIMER1_CDTI2_PB3 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x3) +#define TIMER1_CDTI2_PB4 SILABS_DBUS_TIMER1_CDTI2(0x1, 0x4) +#define TIMER1_CDTI2_PC0 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x0) +#define TIMER1_CDTI2_PC1 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x1) +#define TIMER1_CDTI2_PC2 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x2) +#define TIMER1_CDTI2_PC3 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x3) +#define TIMER1_CDTI2_PC4 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x4) +#define TIMER1_CDTI2_PC5 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x5) +#define TIMER1_CDTI2_PC6 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x6) +#define TIMER1_CDTI2_PC7 SILABS_DBUS_TIMER1_CDTI2(0x2, 0x7) +#define TIMER1_CDTI2_PD0 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x0) +#define TIMER1_CDTI2_PD1 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x1) +#define TIMER1_CDTI2_PD2 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x2) +#define TIMER1_CDTI2_PD3 SILABS_DBUS_TIMER1_CDTI2(0x3, 0x3) + +#define TIMER2_CC0_PA0 SILABS_DBUS_TIMER2_CC0(0x0, 0x0) +#define TIMER2_CC0_PA1 SILABS_DBUS_TIMER2_CC0(0x0, 0x1) +#define TIMER2_CC0_PA2 SILABS_DBUS_TIMER2_CC0(0x0, 0x2) +#define TIMER2_CC0_PA3 SILABS_DBUS_TIMER2_CC0(0x0, 0x3) +#define TIMER2_CC0_PA4 SILABS_DBUS_TIMER2_CC0(0x0, 0x4) +#define TIMER2_CC0_PA5 SILABS_DBUS_TIMER2_CC0(0x0, 0x5) +#define TIMER2_CC0_PA6 SILABS_DBUS_TIMER2_CC0(0x0, 0x6) +#define TIMER2_CC0_PA7 SILABS_DBUS_TIMER2_CC0(0x0, 0x7) +#define TIMER2_CC0_PA8 SILABS_DBUS_TIMER2_CC0(0x0, 0x8) +#define TIMER2_CC0_PB0 SILABS_DBUS_TIMER2_CC0(0x1, 0x0) +#define TIMER2_CC0_PB1 SILABS_DBUS_TIMER2_CC0(0x1, 0x1) +#define TIMER2_CC0_PB2 SILABS_DBUS_TIMER2_CC0(0x1, 0x2) +#define TIMER2_CC0_PB3 SILABS_DBUS_TIMER2_CC0(0x1, 0x3) +#define TIMER2_CC0_PB4 SILABS_DBUS_TIMER2_CC0(0x1, 0x4) +#define TIMER2_CC1_PA0 SILABS_DBUS_TIMER2_CC1(0x0, 0x0) +#define TIMER2_CC1_PA1 SILABS_DBUS_TIMER2_CC1(0x0, 0x1) +#define TIMER2_CC1_PA2 SILABS_DBUS_TIMER2_CC1(0x0, 0x2) +#define TIMER2_CC1_PA3 SILABS_DBUS_TIMER2_CC1(0x0, 0x3) +#define TIMER2_CC1_PA4 SILABS_DBUS_TIMER2_CC1(0x0, 0x4) +#define TIMER2_CC1_PA5 SILABS_DBUS_TIMER2_CC1(0x0, 0x5) +#define TIMER2_CC1_PA6 SILABS_DBUS_TIMER2_CC1(0x0, 0x6) +#define TIMER2_CC1_PA7 SILABS_DBUS_TIMER2_CC1(0x0, 0x7) +#define TIMER2_CC1_PA8 SILABS_DBUS_TIMER2_CC1(0x0, 0x8) +#define TIMER2_CC1_PB0 SILABS_DBUS_TIMER2_CC1(0x1, 0x0) +#define TIMER2_CC1_PB1 SILABS_DBUS_TIMER2_CC1(0x1, 0x1) +#define TIMER2_CC1_PB2 SILABS_DBUS_TIMER2_CC1(0x1, 0x2) +#define TIMER2_CC1_PB3 SILABS_DBUS_TIMER2_CC1(0x1, 0x3) +#define TIMER2_CC1_PB4 SILABS_DBUS_TIMER2_CC1(0x1, 0x4) +#define TIMER2_CC2_PA0 SILABS_DBUS_TIMER2_CC2(0x0, 0x0) +#define TIMER2_CC2_PA1 SILABS_DBUS_TIMER2_CC2(0x0, 0x1) +#define TIMER2_CC2_PA2 SILABS_DBUS_TIMER2_CC2(0x0, 0x2) +#define TIMER2_CC2_PA3 SILABS_DBUS_TIMER2_CC2(0x0, 0x3) +#define TIMER2_CC2_PA4 SILABS_DBUS_TIMER2_CC2(0x0, 0x4) +#define TIMER2_CC2_PA5 SILABS_DBUS_TIMER2_CC2(0x0, 0x5) +#define TIMER2_CC2_PA6 SILABS_DBUS_TIMER2_CC2(0x0, 0x6) +#define TIMER2_CC2_PA7 SILABS_DBUS_TIMER2_CC2(0x0, 0x7) +#define TIMER2_CC2_PA8 SILABS_DBUS_TIMER2_CC2(0x0, 0x8) +#define TIMER2_CC2_PB0 SILABS_DBUS_TIMER2_CC2(0x1, 0x0) +#define TIMER2_CC2_PB1 SILABS_DBUS_TIMER2_CC2(0x1, 0x1) +#define TIMER2_CC2_PB2 SILABS_DBUS_TIMER2_CC2(0x1, 0x2) +#define TIMER2_CC2_PB3 SILABS_DBUS_TIMER2_CC2(0x1, 0x3) +#define TIMER2_CC2_PB4 SILABS_DBUS_TIMER2_CC2(0x1, 0x4) +#define TIMER2_CDTI0_PA0 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x0) +#define TIMER2_CDTI0_PA1 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x1) +#define TIMER2_CDTI0_PA2 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x2) +#define TIMER2_CDTI0_PA3 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x3) +#define TIMER2_CDTI0_PA4 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x4) +#define TIMER2_CDTI0_PA5 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x5) +#define TIMER2_CDTI0_PA6 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x6) +#define TIMER2_CDTI0_PA7 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x7) +#define TIMER2_CDTI0_PA8 SILABS_DBUS_TIMER2_CDTI0(0x0, 0x8) +#define TIMER2_CDTI0_PB0 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x0) +#define TIMER2_CDTI0_PB1 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x1) +#define TIMER2_CDTI0_PB2 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x2) +#define TIMER2_CDTI0_PB3 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x3) +#define TIMER2_CDTI0_PB4 SILABS_DBUS_TIMER2_CDTI0(0x1, 0x4) +#define TIMER2_CDTI1_PA0 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x0) +#define TIMER2_CDTI1_PA1 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x1) +#define TIMER2_CDTI1_PA2 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x2) +#define TIMER2_CDTI1_PA3 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x3) +#define TIMER2_CDTI1_PA4 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x4) +#define TIMER2_CDTI1_PA5 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x5) +#define TIMER2_CDTI1_PA6 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x6) +#define TIMER2_CDTI1_PA7 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x7) +#define TIMER2_CDTI1_PA8 SILABS_DBUS_TIMER2_CDTI1(0x0, 0x8) +#define TIMER2_CDTI1_PB0 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x0) +#define TIMER2_CDTI1_PB1 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x1) +#define TIMER2_CDTI1_PB2 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x2) +#define TIMER2_CDTI1_PB3 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x3) +#define TIMER2_CDTI1_PB4 SILABS_DBUS_TIMER2_CDTI1(0x1, 0x4) +#define TIMER2_CDTI2_PA0 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x0) +#define TIMER2_CDTI2_PA1 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x1) +#define TIMER2_CDTI2_PA2 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x2) +#define TIMER2_CDTI2_PA3 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x3) +#define TIMER2_CDTI2_PA4 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x4) +#define TIMER2_CDTI2_PA5 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x5) +#define TIMER2_CDTI2_PA6 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x6) +#define TIMER2_CDTI2_PA7 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x7) +#define TIMER2_CDTI2_PA8 SILABS_DBUS_TIMER2_CDTI2(0x0, 0x8) +#define TIMER2_CDTI2_PB0 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x0) +#define TIMER2_CDTI2_PB1 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x1) +#define TIMER2_CDTI2_PB2 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x2) +#define TIMER2_CDTI2_PB3 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x3) +#define TIMER2_CDTI2_PB4 SILABS_DBUS_TIMER2_CDTI2(0x1, 0x4) + +#define TIMER3_CC0_PC0 SILABS_DBUS_TIMER3_CC0(0x2, 0x0) +#define TIMER3_CC0_PC1 SILABS_DBUS_TIMER3_CC0(0x2, 0x1) +#define TIMER3_CC0_PC2 SILABS_DBUS_TIMER3_CC0(0x2, 0x2) +#define TIMER3_CC0_PC3 SILABS_DBUS_TIMER3_CC0(0x2, 0x3) +#define TIMER3_CC0_PC4 SILABS_DBUS_TIMER3_CC0(0x2, 0x4) +#define TIMER3_CC0_PC5 SILABS_DBUS_TIMER3_CC0(0x2, 0x5) +#define TIMER3_CC0_PC6 SILABS_DBUS_TIMER3_CC0(0x2, 0x6) +#define TIMER3_CC0_PC7 SILABS_DBUS_TIMER3_CC0(0x2, 0x7) +#define TIMER3_CC0_PD0 SILABS_DBUS_TIMER3_CC0(0x3, 0x0) +#define TIMER3_CC0_PD1 SILABS_DBUS_TIMER3_CC0(0x3, 0x1) +#define TIMER3_CC0_PD2 SILABS_DBUS_TIMER3_CC0(0x3, 0x2) +#define TIMER3_CC0_PD3 SILABS_DBUS_TIMER3_CC0(0x3, 0x3) +#define TIMER3_CC1_PC0 SILABS_DBUS_TIMER3_CC1(0x2, 0x0) +#define TIMER3_CC1_PC1 SILABS_DBUS_TIMER3_CC1(0x2, 0x1) +#define TIMER3_CC1_PC2 SILABS_DBUS_TIMER3_CC1(0x2, 0x2) +#define TIMER3_CC1_PC3 SILABS_DBUS_TIMER3_CC1(0x2, 0x3) +#define TIMER3_CC1_PC4 SILABS_DBUS_TIMER3_CC1(0x2, 0x4) +#define TIMER3_CC1_PC5 SILABS_DBUS_TIMER3_CC1(0x2, 0x5) +#define TIMER3_CC1_PC6 SILABS_DBUS_TIMER3_CC1(0x2, 0x6) +#define TIMER3_CC1_PC7 SILABS_DBUS_TIMER3_CC1(0x2, 0x7) +#define TIMER3_CC1_PD0 SILABS_DBUS_TIMER3_CC1(0x3, 0x0) +#define TIMER3_CC1_PD1 SILABS_DBUS_TIMER3_CC1(0x3, 0x1) +#define TIMER3_CC1_PD2 SILABS_DBUS_TIMER3_CC1(0x3, 0x2) +#define TIMER3_CC1_PD3 SILABS_DBUS_TIMER3_CC1(0x3, 0x3) +#define TIMER3_CC2_PC0 SILABS_DBUS_TIMER3_CC2(0x2, 0x0) +#define TIMER3_CC2_PC1 SILABS_DBUS_TIMER3_CC2(0x2, 0x1) +#define TIMER3_CC2_PC2 SILABS_DBUS_TIMER3_CC2(0x2, 0x2) +#define TIMER3_CC2_PC3 SILABS_DBUS_TIMER3_CC2(0x2, 0x3) +#define TIMER3_CC2_PC4 SILABS_DBUS_TIMER3_CC2(0x2, 0x4) +#define TIMER3_CC2_PC5 SILABS_DBUS_TIMER3_CC2(0x2, 0x5) +#define TIMER3_CC2_PC6 SILABS_DBUS_TIMER3_CC2(0x2, 0x6) +#define TIMER3_CC2_PC7 SILABS_DBUS_TIMER3_CC2(0x2, 0x7) +#define TIMER3_CC2_PD0 SILABS_DBUS_TIMER3_CC2(0x3, 0x0) +#define TIMER3_CC2_PD1 SILABS_DBUS_TIMER3_CC2(0x3, 0x1) +#define TIMER3_CC2_PD2 SILABS_DBUS_TIMER3_CC2(0x3, 0x2) +#define TIMER3_CC2_PD3 SILABS_DBUS_TIMER3_CC2(0x3, 0x3) +#define TIMER3_CDTI0_PC0 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x0) +#define TIMER3_CDTI0_PC1 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x1) +#define TIMER3_CDTI0_PC2 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x2) +#define TIMER3_CDTI0_PC3 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x3) +#define TIMER3_CDTI0_PC4 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x4) +#define TIMER3_CDTI0_PC5 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x5) +#define TIMER3_CDTI0_PC6 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x6) +#define TIMER3_CDTI0_PC7 SILABS_DBUS_TIMER3_CDTI0(0x2, 0x7) +#define TIMER3_CDTI0_PD0 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x0) +#define TIMER3_CDTI0_PD1 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x1) +#define TIMER3_CDTI0_PD2 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x2) +#define TIMER3_CDTI0_PD3 SILABS_DBUS_TIMER3_CDTI0(0x3, 0x3) +#define TIMER3_CDTI1_PC0 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x0) +#define TIMER3_CDTI1_PC1 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x1) +#define TIMER3_CDTI1_PC2 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x2) +#define TIMER3_CDTI1_PC3 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x3) +#define TIMER3_CDTI1_PC4 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x4) +#define TIMER3_CDTI1_PC5 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x5) +#define TIMER3_CDTI1_PC6 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x6) +#define TIMER3_CDTI1_PC7 SILABS_DBUS_TIMER3_CDTI1(0x2, 0x7) +#define TIMER3_CDTI1_PD0 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x0) +#define TIMER3_CDTI1_PD1 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x1) +#define TIMER3_CDTI1_PD2 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x2) +#define TIMER3_CDTI1_PD3 SILABS_DBUS_TIMER3_CDTI1(0x3, 0x3) +#define TIMER3_CDTI2_PC0 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x0) +#define TIMER3_CDTI2_PC1 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x1) +#define TIMER3_CDTI2_PC2 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x2) +#define TIMER3_CDTI2_PC3 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x3) +#define TIMER3_CDTI2_PC4 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x4) +#define TIMER3_CDTI2_PC5 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x5) +#define TIMER3_CDTI2_PC6 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x6) +#define TIMER3_CDTI2_PC7 SILABS_DBUS_TIMER3_CDTI2(0x2, 0x7) +#define TIMER3_CDTI2_PD0 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x0) +#define TIMER3_CDTI2_PD1 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x1) +#define TIMER3_CDTI2_PD2 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x2) +#define TIMER3_CDTI2_PD3 SILABS_DBUS_TIMER3_CDTI2(0x3, 0x3) + +#define TIMER4_CC0_PA0 SILABS_DBUS_TIMER4_CC0(0x0, 0x0) +#define TIMER4_CC0_PA1 SILABS_DBUS_TIMER4_CC0(0x0, 0x1) +#define TIMER4_CC0_PA2 SILABS_DBUS_TIMER4_CC0(0x0, 0x2) +#define TIMER4_CC0_PA3 SILABS_DBUS_TIMER4_CC0(0x0, 0x3) +#define TIMER4_CC0_PA4 SILABS_DBUS_TIMER4_CC0(0x0, 0x4) +#define TIMER4_CC0_PA5 SILABS_DBUS_TIMER4_CC0(0x0, 0x5) +#define TIMER4_CC0_PA6 SILABS_DBUS_TIMER4_CC0(0x0, 0x6) +#define TIMER4_CC0_PA7 SILABS_DBUS_TIMER4_CC0(0x0, 0x7) +#define TIMER4_CC0_PA8 SILABS_DBUS_TIMER4_CC0(0x0, 0x8) +#define TIMER4_CC0_PB0 SILABS_DBUS_TIMER4_CC0(0x1, 0x0) +#define TIMER4_CC0_PB1 SILABS_DBUS_TIMER4_CC0(0x1, 0x1) +#define TIMER4_CC0_PB2 SILABS_DBUS_TIMER4_CC0(0x1, 0x2) +#define TIMER4_CC0_PB3 SILABS_DBUS_TIMER4_CC0(0x1, 0x3) +#define TIMER4_CC0_PB4 SILABS_DBUS_TIMER4_CC0(0x1, 0x4) +#define TIMER4_CC1_PA0 SILABS_DBUS_TIMER4_CC1(0x0, 0x0) +#define TIMER4_CC1_PA1 SILABS_DBUS_TIMER4_CC1(0x0, 0x1) +#define TIMER4_CC1_PA2 SILABS_DBUS_TIMER4_CC1(0x0, 0x2) +#define TIMER4_CC1_PA3 SILABS_DBUS_TIMER4_CC1(0x0, 0x3) +#define TIMER4_CC1_PA4 SILABS_DBUS_TIMER4_CC1(0x0, 0x4) +#define TIMER4_CC1_PA5 SILABS_DBUS_TIMER4_CC1(0x0, 0x5) +#define TIMER4_CC1_PA6 SILABS_DBUS_TIMER4_CC1(0x0, 0x6) +#define TIMER4_CC1_PA7 SILABS_DBUS_TIMER4_CC1(0x0, 0x7) +#define TIMER4_CC1_PA8 SILABS_DBUS_TIMER4_CC1(0x0, 0x8) +#define TIMER4_CC1_PB0 SILABS_DBUS_TIMER4_CC1(0x1, 0x0) +#define TIMER4_CC1_PB1 SILABS_DBUS_TIMER4_CC1(0x1, 0x1) +#define TIMER4_CC1_PB2 SILABS_DBUS_TIMER4_CC1(0x1, 0x2) +#define TIMER4_CC1_PB3 SILABS_DBUS_TIMER4_CC1(0x1, 0x3) +#define TIMER4_CC1_PB4 SILABS_DBUS_TIMER4_CC1(0x1, 0x4) +#define TIMER4_CC2_PA0 SILABS_DBUS_TIMER4_CC2(0x0, 0x0) +#define TIMER4_CC2_PA1 SILABS_DBUS_TIMER4_CC2(0x0, 0x1) +#define TIMER4_CC2_PA2 SILABS_DBUS_TIMER4_CC2(0x0, 0x2) +#define TIMER4_CC2_PA3 SILABS_DBUS_TIMER4_CC2(0x0, 0x3) +#define TIMER4_CC2_PA4 SILABS_DBUS_TIMER4_CC2(0x0, 0x4) +#define TIMER4_CC2_PA5 SILABS_DBUS_TIMER4_CC2(0x0, 0x5) +#define TIMER4_CC2_PA6 SILABS_DBUS_TIMER4_CC2(0x0, 0x6) +#define TIMER4_CC2_PA7 SILABS_DBUS_TIMER4_CC2(0x0, 0x7) +#define TIMER4_CC2_PA8 SILABS_DBUS_TIMER4_CC2(0x0, 0x8) +#define TIMER4_CC2_PB0 SILABS_DBUS_TIMER4_CC2(0x1, 0x0) +#define TIMER4_CC2_PB1 SILABS_DBUS_TIMER4_CC2(0x1, 0x1) +#define TIMER4_CC2_PB2 SILABS_DBUS_TIMER4_CC2(0x1, 0x2) +#define TIMER4_CC2_PB3 SILABS_DBUS_TIMER4_CC2(0x1, 0x3) +#define TIMER4_CC2_PB4 SILABS_DBUS_TIMER4_CC2(0x1, 0x4) +#define TIMER4_CDTI0_PA0 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x0) +#define TIMER4_CDTI0_PA1 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x1) +#define TIMER4_CDTI0_PA2 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x2) +#define TIMER4_CDTI0_PA3 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x3) +#define TIMER4_CDTI0_PA4 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x4) +#define TIMER4_CDTI0_PA5 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x5) +#define TIMER4_CDTI0_PA6 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x6) +#define TIMER4_CDTI0_PA7 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x7) +#define TIMER4_CDTI0_PA8 SILABS_DBUS_TIMER4_CDTI0(0x0, 0x8) +#define TIMER4_CDTI0_PB0 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x0) +#define TIMER4_CDTI0_PB1 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x1) +#define TIMER4_CDTI0_PB2 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x2) +#define TIMER4_CDTI0_PB3 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x3) +#define TIMER4_CDTI0_PB4 SILABS_DBUS_TIMER4_CDTI0(0x1, 0x4) +#define TIMER4_CDTI1_PA0 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x0) +#define TIMER4_CDTI1_PA1 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x1) +#define TIMER4_CDTI1_PA2 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x2) +#define TIMER4_CDTI1_PA3 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x3) +#define TIMER4_CDTI1_PA4 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x4) +#define TIMER4_CDTI1_PA5 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x5) +#define TIMER4_CDTI1_PA6 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x6) +#define TIMER4_CDTI1_PA7 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x7) +#define TIMER4_CDTI1_PA8 SILABS_DBUS_TIMER4_CDTI1(0x0, 0x8) +#define TIMER4_CDTI1_PB0 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x0) +#define TIMER4_CDTI1_PB1 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x1) +#define TIMER4_CDTI1_PB2 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x2) +#define TIMER4_CDTI1_PB3 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x3) +#define TIMER4_CDTI1_PB4 SILABS_DBUS_TIMER4_CDTI1(0x1, 0x4) +#define TIMER4_CDTI2_PA0 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x0) +#define TIMER4_CDTI2_PA1 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x1) +#define TIMER4_CDTI2_PA2 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x2) +#define TIMER4_CDTI2_PA3 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x3) +#define TIMER4_CDTI2_PA4 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x4) +#define TIMER4_CDTI2_PA5 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x5) +#define TIMER4_CDTI2_PA6 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x6) +#define TIMER4_CDTI2_PA7 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x7) +#define TIMER4_CDTI2_PA8 SILABS_DBUS_TIMER4_CDTI2(0x0, 0x8) +#define TIMER4_CDTI2_PB0 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x0) +#define TIMER4_CDTI2_PB1 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x1) +#define TIMER4_CDTI2_PB2 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x2) +#define TIMER4_CDTI2_PB3 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x3) +#define TIMER4_CDTI2_PB4 SILABS_DBUS_TIMER4_CDTI2(0x1, 0x4) + +#define USART0_CS_PA0 SILABS_DBUS_USART0_CS(0x0, 0x0) +#define USART0_CS_PA1 SILABS_DBUS_USART0_CS(0x0, 0x1) +#define USART0_CS_PA2 SILABS_DBUS_USART0_CS(0x0, 0x2) +#define USART0_CS_PA3 SILABS_DBUS_USART0_CS(0x0, 0x3) +#define USART0_CS_PA4 SILABS_DBUS_USART0_CS(0x0, 0x4) +#define USART0_CS_PA5 SILABS_DBUS_USART0_CS(0x0, 0x5) +#define USART0_CS_PA6 SILABS_DBUS_USART0_CS(0x0, 0x6) +#define USART0_CS_PA7 SILABS_DBUS_USART0_CS(0x0, 0x7) +#define USART0_CS_PA8 SILABS_DBUS_USART0_CS(0x0, 0x8) +#define USART0_CS_PB0 SILABS_DBUS_USART0_CS(0x1, 0x0) +#define USART0_CS_PB1 SILABS_DBUS_USART0_CS(0x1, 0x1) +#define USART0_CS_PB2 SILABS_DBUS_USART0_CS(0x1, 0x2) +#define USART0_CS_PB3 SILABS_DBUS_USART0_CS(0x1, 0x3) +#define USART0_CS_PB4 SILABS_DBUS_USART0_CS(0x1, 0x4) +#define USART0_CS_PC0 SILABS_DBUS_USART0_CS(0x2, 0x0) +#define USART0_CS_PC1 SILABS_DBUS_USART0_CS(0x2, 0x1) +#define USART0_CS_PC2 SILABS_DBUS_USART0_CS(0x2, 0x2) +#define USART0_CS_PC3 SILABS_DBUS_USART0_CS(0x2, 0x3) +#define USART0_CS_PC4 SILABS_DBUS_USART0_CS(0x2, 0x4) +#define USART0_CS_PC5 SILABS_DBUS_USART0_CS(0x2, 0x5) +#define USART0_CS_PC6 SILABS_DBUS_USART0_CS(0x2, 0x6) +#define USART0_CS_PC7 SILABS_DBUS_USART0_CS(0x2, 0x7) +#define USART0_CS_PD0 SILABS_DBUS_USART0_CS(0x3, 0x0) +#define USART0_CS_PD1 SILABS_DBUS_USART0_CS(0x3, 0x1) +#define USART0_CS_PD2 SILABS_DBUS_USART0_CS(0x3, 0x2) +#define USART0_CS_PD3 SILABS_DBUS_USART0_CS(0x3, 0x3) +#define USART0_RTS_PA0 SILABS_DBUS_USART0_RTS(0x0, 0x0) +#define USART0_RTS_PA1 SILABS_DBUS_USART0_RTS(0x0, 0x1) +#define USART0_RTS_PA2 SILABS_DBUS_USART0_RTS(0x0, 0x2) +#define USART0_RTS_PA3 SILABS_DBUS_USART0_RTS(0x0, 0x3) +#define USART0_RTS_PA4 SILABS_DBUS_USART0_RTS(0x0, 0x4) +#define USART0_RTS_PA5 SILABS_DBUS_USART0_RTS(0x0, 0x5) +#define USART0_RTS_PA6 SILABS_DBUS_USART0_RTS(0x0, 0x6) +#define USART0_RTS_PA7 SILABS_DBUS_USART0_RTS(0x0, 0x7) +#define USART0_RTS_PA8 SILABS_DBUS_USART0_RTS(0x0, 0x8) +#define USART0_RTS_PB0 SILABS_DBUS_USART0_RTS(0x1, 0x0) +#define USART0_RTS_PB1 SILABS_DBUS_USART0_RTS(0x1, 0x1) +#define USART0_RTS_PB2 SILABS_DBUS_USART0_RTS(0x1, 0x2) +#define USART0_RTS_PB3 SILABS_DBUS_USART0_RTS(0x1, 0x3) +#define USART0_RTS_PB4 SILABS_DBUS_USART0_RTS(0x1, 0x4) +#define USART0_RTS_PC0 SILABS_DBUS_USART0_RTS(0x2, 0x0) +#define USART0_RTS_PC1 SILABS_DBUS_USART0_RTS(0x2, 0x1) +#define USART0_RTS_PC2 SILABS_DBUS_USART0_RTS(0x2, 0x2) +#define USART0_RTS_PC3 SILABS_DBUS_USART0_RTS(0x2, 0x3) +#define USART0_RTS_PC4 SILABS_DBUS_USART0_RTS(0x2, 0x4) +#define USART0_RTS_PC5 SILABS_DBUS_USART0_RTS(0x2, 0x5) +#define USART0_RTS_PC6 SILABS_DBUS_USART0_RTS(0x2, 0x6) +#define USART0_RTS_PC7 SILABS_DBUS_USART0_RTS(0x2, 0x7) +#define USART0_RTS_PD0 SILABS_DBUS_USART0_RTS(0x3, 0x0) +#define USART0_RTS_PD1 SILABS_DBUS_USART0_RTS(0x3, 0x1) +#define USART0_RTS_PD2 SILABS_DBUS_USART0_RTS(0x3, 0x2) +#define USART0_RTS_PD3 SILABS_DBUS_USART0_RTS(0x3, 0x3) +#define USART0_RX_PA0 SILABS_DBUS_USART0_RX(0x0, 0x0) +#define USART0_RX_PA1 SILABS_DBUS_USART0_RX(0x0, 0x1) +#define USART0_RX_PA2 SILABS_DBUS_USART0_RX(0x0, 0x2) +#define USART0_RX_PA3 SILABS_DBUS_USART0_RX(0x0, 0x3) +#define USART0_RX_PA4 SILABS_DBUS_USART0_RX(0x0, 0x4) +#define USART0_RX_PA5 SILABS_DBUS_USART0_RX(0x0, 0x5) +#define USART0_RX_PA6 SILABS_DBUS_USART0_RX(0x0, 0x6) +#define USART0_RX_PA7 SILABS_DBUS_USART0_RX(0x0, 0x7) +#define USART0_RX_PA8 SILABS_DBUS_USART0_RX(0x0, 0x8) +#define USART0_RX_PB0 SILABS_DBUS_USART0_RX(0x1, 0x0) +#define USART0_RX_PB1 SILABS_DBUS_USART0_RX(0x1, 0x1) +#define USART0_RX_PB2 SILABS_DBUS_USART0_RX(0x1, 0x2) +#define USART0_RX_PB3 SILABS_DBUS_USART0_RX(0x1, 0x3) +#define USART0_RX_PB4 SILABS_DBUS_USART0_RX(0x1, 0x4) +#define USART0_RX_PC0 SILABS_DBUS_USART0_RX(0x2, 0x0) +#define USART0_RX_PC1 SILABS_DBUS_USART0_RX(0x2, 0x1) +#define USART0_RX_PC2 SILABS_DBUS_USART0_RX(0x2, 0x2) +#define USART0_RX_PC3 SILABS_DBUS_USART0_RX(0x2, 0x3) +#define USART0_RX_PC4 SILABS_DBUS_USART0_RX(0x2, 0x4) +#define USART0_RX_PC5 SILABS_DBUS_USART0_RX(0x2, 0x5) +#define USART0_RX_PC6 SILABS_DBUS_USART0_RX(0x2, 0x6) +#define USART0_RX_PC7 SILABS_DBUS_USART0_RX(0x2, 0x7) +#define USART0_RX_PD0 SILABS_DBUS_USART0_RX(0x3, 0x0) +#define USART0_RX_PD1 SILABS_DBUS_USART0_RX(0x3, 0x1) +#define USART0_RX_PD2 SILABS_DBUS_USART0_RX(0x3, 0x2) +#define USART0_RX_PD3 SILABS_DBUS_USART0_RX(0x3, 0x3) +#define USART0_CLK_PA0 SILABS_DBUS_USART0_CLK(0x0, 0x0) +#define USART0_CLK_PA1 SILABS_DBUS_USART0_CLK(0x0, 0x1) +#define USART0_CLK_PA2 SILABS_DBUS_USART0_CLK(0x0, 0x2) +#define USART0_CLK_PA3 SILABS_DBUS_USART0_CLK(0x0, 0x3) +#define USART0_CLK_PA4 SILABS_DBUS_USART0_CLK(0x0, 0x4) +#define USART0_CLK_PA5 SILABS_DBUS_USART0_CLK(0x0, 0x5) +#define USART0_CLK_PA6 SILABS_DBUS_USART0_CLK(0x0, 0x6) +#define USART0_CLK_PA7 SILABS_DBUS_USART0_CLK(0x0, 0x7) +#define USART0_CLK_PA8 SILABS_DBUS_USART0_CLK(0x0, 0x8) +#define USART0_CLK_PB0 SILABS_DBUS_USART0_CLK(0x1, 0x0) +#define USART0_CLK_PB1 SILABS_DBUS_USART0_CLK(0x1, 0x1) +#define USART0_CLK_PB2 SILABS_DBUS_USART0_CLK(0x1, 0x2) +#define USART0_CLK_PB3 SILABS_DBUS_USART0_CLK(0x1, 0x3) +#define USART0_CLK_PB4 SILABS_DBUS_USART0_CLK(0x1, 0x4) +#define USART0_CLK_PC0 SILABS_DBUS_USART0_CLK(0x2, 0x0) +#define USART0_CLK_PC1 SILABS_DBUS_USART0_CLK(0x2, 0x1) +#define USART0_CLK_PC2 SILABS_DBUS_USART0_CLK(0x2, 0x2) +#define USART0_CLK_PC3 SILABS_DBUS_USART0_CLK(0x2, 0x3) +#define USART0_CLK_PC4 SILABS_DBUS_USART0_CLK(0x2, 0x4) +#define USART0_CLK_PC5 SILABS_DBUS_USART0_CLK(0x2, 0x5) +#define USART0_CLK_PC6 SILABS_DBUS_USART0_CLK(0x2, 0x6) +#define USART0_CLK_PC7 SILABS_DBUS_USART0_CLK(0x2, 0x7) +#define USART0_CLK_PD0 SILABS_DBUS_USART0_CLK(0x3, 0x0) +#define USART0_CLK_PD1 SILABS_DBUS_USART0_CLK(0x3, 0x1) +#define USART0_CLK_PD2 SILABS_DBUS_USART0_CLK(0x3, 0x2) +#define USART0_CLK_PD3 SILABS_DBUS_USART0_CLK(0x3, 0x3) +#define USART0_TX_PA0 SILABS_DBUS_USART0_TX(0x0, 0x0) +#define USART0_TX_PA1 SILABS_DBUS_USART0_TX(0x0, 0x1) +#define USART0_TX_PA2 SILABS_DBUS_USART0_TX(0x0, 0x2) +#define USART0_TX_PA3 SILABS_DBUS_USART0_TX(0x0, 0x3) +#define USART0_TX_PA4 SILABS_DBUS_USART0_TX(0x0, 0x4) +#define USART0_TX_PA5 SILABS_DBUS_USART0_TX(0x0, 0x5) +#define USART0_TX_PA6 SILABS_DBUS_USART0_TX(0x0, 0x6) +#define USART0_TX_PA7 SILABS_DBUS_USART0_TX(0x0, 0x7) +#define USART0_TX_PA8 SILABS_DBUS_USART0_TX(0x0, 0x8) +#define USART0_TX_PB0 SILABS_DBUS_USART0_TX(0x1, 0x0) +#define USART0_TX_PB1 SILABS_DBUS_USART0_TX(0x1, 0x1) +#define USART0_TX_PB2 SILABS_DBUS_USART0_TX(0x1, 0x2) +#define USART0_TX_PB3 SILABS_DBUS_USART0_TX(0x1, 0x3) +#define USART0_TX_PB4 SILABS_DBUS_USART0_TX(0x1, 0x4) +#define USART0_TX_PC0 SILABS_DBUS_USART0_TX(0x2, 0x0) +#define USART0_TX_PC1 SILABS_DBUS_USART0_TX(0x2, 0x1) +#define USART0_TX_PC2 SILABS_DBUS_USART0_TX(0x2, 0x2) +#define USART0_TX_PC3 SILABS_DBUS_USART0_TX(0x2, 0x3) +#define USART0_TX_PC4 SILABS_DBUS_USART0_TX(0x2, 0x4) +#define USART0_TX_PC5 SILABS_DBUS_USART0_TX(0x2, 0x5) +#define USART0_TX_PC6 SILABS_DBUS_USART0_TX(0x2, 0x6) +#define USART0_TX_PC7 SILABS_DBUS_USART0_TX(0x2, 0x7) +#define USART0_TX_PD0 SILABS_DBUS_USART0_TX(0x3, 0x0) +#define USART0_TX_PD1 SILABS_DBUS_USART0_TX(0x3, 0x1) +#define USART0_TX_PD2 SILABS_DBUS_USART0_TX(0x3, 0x2) +#define USART0_TX_PD3 SILABS_DBUS_USART0_TX(0x3, 0x3) +#define USART0_CTS_PA0 SILABS_DBUS_USART0_CTS(0x0, 0x0) +#define USART0_CTS_PA1 SILABS_DBUS_USART0_CTS(0x0, 0x1) +#define USART0_CTS_PA2 SILABS_DBUS_USART0_CTS(0x0, 0x2) +#define USART0_CTS_PA3 SILABS_DBUS_USART0_CTS(0x0, 0x3) +#define USART0_CTS_PA4 SILABS_DBUS_USART0_CTS(0x0, 0x4) +#define USART0_CTS_PA5 SILABS_DBUS_USART0_CTS(0x0, 0x5) +#define USART0_CTS_PA6 SILABS_DBUS_USART0_CTS(0x0, 0x6) +#define USART0_CTS_PA7 SILABS_DBUS_USART0_CTS(0x0, 0x7) +#define USART0_CTS_PA8 SILABS_DBUS_USART0_CTS(0x0, 0x8) +#define USART0_CTS_PB0 SILABS_DBUS_USART0_CTS(0x1, 0x0) +#define USART0_CTS_PB1 SILABS_DBUS_USART0_CTS(0x1, 0x1) +#define USART0_CTS_PB2 SILABS_DBUS_USART0_CTS(0x1, 0x2) +#define USART0_CTS_PB3 SILABS_DBUS_USART0_CTS(0x1, 0x3) +#define USART0_CTS_PB4 SILABS_DBUS_USART0_CTS(0x1, 0x4) +#define USART0_CTS_PC0 SILABS_DBUS_USART0_CTS(0x2, 0x0) +#define USART0_CTS_PC1 SILABS_DBUS_USART0_CTS(0x2, 0x1) +#define USART0_CTS_PC2 SILABS_DBUS_USART0_CTS(0x2, 0x2) +#define USART0_CTS_PC3 SILABS_DBUS_USART0_CTS(0x2, 0x3) +#define USART0_CTS_PC4 SILABS_DBUS_USART0_CTS(0x2, 0x4) +#define USART0_CTS_PC5 SILABS_DBUS_USART0_CTS(0x2, 0x5) +#define USART0_CTS_PC6 SILABS_DBUS_USART0_CTS(0x2, 0x6) +#define USART0_CTS_PC7 SILABS_DBUS_USART0_CTS(0x2, 0x7) +#define USART0_CTS_PD0 SILABS_DBUS_USART0_CTS(0x3, 0x0) +#define USART0_CTS_PD1 SILABS_DBUS_USART0_CTS(0x3, 0x1) +#define USART0_CTS_PD2 SILABS_DBUS_USART0_CTS(0x3, 0x2) +#define USART0_CTS_PD3 SILABS_DBUS_USART0_CTS(0x3, 0x3) + +#define USART1_CS_PA0 SILABS_DBUS_USART1_CS(0x0, 0x0) +#define USART1_CS_PA1 SILABS_DBUS_USART1_CS(0x0, 0x1) +#define USART1_CS_PA2 SILABS_DBUS_USART1_CS(0x0, 0x2) +#define USART1_CS_PA3 SILABS_DBUS_USART1_CS(0x0, 0x3) +#define USART1_CS_PA4 SILABS_DBUS_USART1_CS(0x0, 0x4) +#define USART1_CS_PA5 SILABS_DBUS_USART1_CS(0x0, 0x5) +#define USART1_CS_PA6 SILABS_DBUS_USART1_CS(0x0, 0x6) +#define USART1_CS_PA7 SILABS_DBUS_USART1_CS(0x0, 0x7) +#define USART1_CS_PA8 SILABS_DBUS_USART1_CS(0x0, 0x8) +#define USART1_CS_PB0 SILABS_DBUS_USART1_CS(0x1, 0x0) +#define USART1_CS_PB1 SILABS_DBUS_USART1_CS(0x1, 0x1) +#define USART1_CS_PB2 SILABS_DBUS_USART1_CS(0x1, 0x2) +#define USART1_CS_PB3 SILABS_DBUS_USART1_CS(0x1, 0x3) +#define USART1_CS_PB4 SILABS_DBUS_USART1_CS(0x1, 0x4) +#define USART1_RTS_PA0 SILABS_DBUS_USART1_RTS(0x0, 0x0) +#define USART1_RTS_PA1 SILABS_DBUS_USART1_RTS(0x0, 0x1) +#define USART1_RTS_PA2 SILABS_DBUS_USART1_RTS(0x0, 0x2) +#define USART1_RTS_PA3 SILABS_DBUS_USART1_RTS(0x0, 0x3) +#define USART1_RTS_PA4 SILABS_DBUS_USART1_RTS(0x0, 0x4) +#define USART1_RTS_PA5 SILABS_DBUS_USART1_RTS(0x0, 0x5) +#define USART1_RTS_PA6 SILABS_DBUS_USART1_RTS(0x0, 0x6) +#define USART1_RTS_PA7 SILABS_DBUS_USART1_RTS(0x0, 0x7) +#define USART1_RTS_PA8 SILABS_DBUS_USART1_RTS(0x0, 0x8) +#define USART1_RTS_PB0 SILABS_DBUS_USART1_RTS(0x1, 0x0) +#define USART1_RTS_PB1 SILABS_DBUS_USART1_RTS(0x1, 0x1) +#define USART1_RTS_PB2 SILABS_DBUS_USART1_RTS(0x1, 0x2) +#define USART1_RTS_PB3 SILABS_DBUS_USART1_RTS(0x1, 0x3) +#define USART1_RTS_PB4 SILABS_DBUS_USART1_RTS(0x1, 0x4) +#define USART1_RX_PA0 SILABS_DBUS_USART1_RX(0x0, 0x0) +#define USART1_RX_PA1 SILABS_DBUS_USART1_RX(0x0, 0x1) +#define USART1_RX_PA2 SILABS_DBUS_USART1_RX(0x0, 0x2) +#define USART1_RX_PA3 SILABS_DBUS_USART1_RX(0x0, 0x3) +#define USART1_RX_PA4 SILABS_DBUS_USART1_RX(0x0, 0x4) +#define USART1_RX_PA5 SILABS_DBUS_USART1_RX(0x0, 0x5) +#define USART1_RX_PA6 SILABS_DBUS_USART1_RX(0x0, 0x6) +#define USART1_RX_PA7 SILABS_DBUS_USART1_RX(0x0, 0x7) +#define USART1_RX_PA8 SILABS_DBUS_USART1_RX(0x0, 0x8) +#define USART1_RX_PB0 SILABS_DBUS_USART1_RX(0x1, 0x0) +#define USART1_RX_PB1 SILABS_DBUS_USART1_RX(0x1, 0x1) +#define USART1_RX_PB2 SILABS_DBUS_USART1_RX(0x1, 0x2) +#define USART1_RX_PB3 SILABS_DBUS_USART1_RX(0x1, 0x3) +#define USART1_RX_PB4 SILABS_DBUS_USART1_RX(0x1, 0x4) +#define USART1_CLK_PA0 SILABS_DBUS_USART1_CLK(0x0, 0x0) +#define USART1_CLK_PA1 SILABS_DBUS_USART1_CLK(0x0, 0x1) +#define USART1_CLK_PA2 SILABS_DBUS_USART1_CLK(0x0, 0x2) +#define USART1_CLK_PA3 SILABS_DBUS_USART1_CLK(0x0, 0x3) +#define USART1_CLK_PA4 SILABS_DBUS_USART1_CLK(0x0, 0x4) +#define USART1_CLK_PA5 SILABS_DBUS_USART1_CLK(0x0, 0x5) +#define USART1_CLK_PA6 SILABS_DBUS_USART1_CLK(0x0, 0x6) +#define USART1_CLK_PA7 SILABS_DBUS_USART1_CLK(0x0, 0x7) +#define USART1_CLK_PA8 SILABS_DBUS_USART1_CLK(0x0, 0x8) +#define USART1_CLK_PB0 SILABS_DBUS_USART1_CLK(0x1, 0x0) +#define USART1_CLK_PB1 SILABS_DBUS_USART1_CLK(0x1, 0x1) +#define USART1_CLK_PB2 SILABS_DBUS_USART1_CLK(0x1, 0x2) +#define USART1_CLK_PB3 SILABS_DBUS_USART1_CLK(0x1, 0x3) +#define USART1_CLK_PB4 SILABS_DBUS_USART1_CLK(0x1, 0x4) +#define USART1_TX_PA0 SILABS_DBUS_USART1_TX(0x0, 0x0) +#define USART1_TX_PA1 SILABS_DBUS_USART1_TX(0x0, 0x1) +#define USART1_TX_PA2 SILABS_DBUS_USART1_TX(0x0, 0x2) +#define USART1_TX_PA3 SILABS_DBUS_USART1_TX(0x0, 0x3) +#define USART1_TX_PA4 SILABS_DBUS_USART1_TX(0x0, 0x4) +#define USART1_TX_PA5 SILABS_DBUS_USART1_TX(0x0, 0x5) +#define USART1_TX_PA6 SILABS_DBUS_USART1_TX(0x0, 0x6) +#define USART1_TX_PA7 SILABS_DBUS_USART1_TX(0x0, 0x7) +#define USART1_TX_PA8 SILABS_DBUS_USART1_TX(0x0, 0x8) +#define USART1_TX_PB0 SILABS_DBUS_USART1_TX(0x1, 0x0) +#define USART1_TX_PB1 SILABS_DBUS_USART1_TX(0x1, 0x1) +#define USART1_TX_PB2 SILABS_DBUS_USART1_TX(0x1, 0x2) +#define USART1_TX_PB3 SILABS_DBUS_USART1_TX(0x1, 0x3) +#define USART1_TX_PB4 SILABS_DBUS_USART1_TX(0x1, 0x4) +#define USART1_CTS_PA0 SILABS_DBUS_USART1_CTS(0x0, 0x0) +#define USART1_CTS_PA1 SILABS_DBUS_USART1_CTS(0x0, 0x1) +#define USART1_CTS_PA2 SILABS_DBUS_USART1_CTS(0x0, 0x2) +#define USART1_CTS_PA3 SILABS_DBUS_USART1_CTS(0x0, 0x3) +#define USART1_CTS_PA4 SILABS_DBUS_USART1_CTS(0x0, 0x4) +#define USART1_CTS_PA5 SILABS_DBUS_USART1_CTS(0x0, 0x5) +#define USART1_CTS_PA6 SILABS_DBUS_USART1_CTS(0x0, 0x6) +#define USART1_CTS_PA7 SILABS_DBUS_USART1_CTS(0x0, 0x7) +#define USART1_CTS_PA8 SILABS_DBUS_USART1_CTS(0x0, 0x8) +#define USART1_CTS_PB0 SILABS_DBUS_USART1_CTS(0x1, 0x0) +#define USART1_CTS_PB1 SILABS_DBUS_USART1_CTS(0x1, 0x1) +#define USART1_CTS_PB2 SILABS_DBUS_USART1_CTS(0x1, 0x2) +#define USART1_CTS_PB3 SILABS_DBUS_USART1_CTS(0x1, 0x3) +#define USART1_CTS_PB4 SILABS_DBUS_USART1_CTS(0x1, 0x4) + +#define ABUS_AEVEN0_IADC0 SILABS_ABUS(0x0, 0x0, 0x1) +#define ABUS_AEVEN0_ACMP0 SILABS_ABUS(0x0, 0x0, 0x2) +#define ABUS_AEVEN1_IADC0 SILABS_ABUS(0x0, 0x1, 0x1) +#define ABUS_AEVEN1_ACMP0 SILABS_ABUS(0x0, 0x1, 0x2) +#define ABUS_AODD0_IADC0 SILABS_ABUS(0x0, 0x2, 0x1) +#define ABUS_AODD0_ACMP0 SILABS_ABUS(0x0, 0x2, 0x2) +#define ABUS_AODD1_IADC0 SILABS_ABUS(0x0, 0x3, 0x1) +#define ABUS_AODD1_ACMP0 SILABS_ABUS(0x0, 0x3, 0x2) +#define ABUS_BEVEN0_IADC0 SILABS_ABUS(0x1, 0x0, 0x1) +#define ABUS_BEVEN0_ACMP0 SILABS_ABUS(0x1, 0x0, 0x2) +#define ABUS_BEVEN1_IADC0 SILABS_ABUS(0x1, 0x1, 0x1) +#define ABUS_BEVEN1_ACMP0 SILABS_ABUS(0x1, 0x1, 0x2) +#define ABUS_BODD0_IADC0 SILABS_ABUS(0x1, 0x2, 0x1) +#define ABUS_BODD0_ACMP0 SILABS_ABUS(0x1, 0x2, 0x2) +#define ABUS_BODD1_IADC0 SILABS_ABUS(0x1, 0x3, 0x1) +#define ABUS_BODD1_ACMP0 SILABS_ABUS(0x1, 0x3, 0x2) +#define ABUS_CDEVEN0_IADC0 SILABS_ABUS(0x2, 0x0, 0x1) +#define ABUS_CDEVEN0_ACMP0 SILABS_ABUS(0x2, 0x0, 0x2) +#define ABUS_CDEVEN1_IADC0 SILABS_ABUS(0x2, 0x1, 0x1) +#define ABUS_CDEVEN1_ACMP0 SILABS_ABUS(0x2, 0x1, 0x2) +#define ABUS_CDODD0_IADC0 SILABS_ABUS(0x2, 0x2, 0x1) +#define ABUS_CDODD0_ACMP0 SILABS_ABUS(0x2, 0x2, 0x2) +#define ABUS_CDODD1_IADC0 SILABS_ABUS(0x2, 0x3, 0x1) +#define ABUS_CDODD1_ACMP0 SILABS_ABUS(0x2, 0x3, 0x2) + +#endif /* ZEPHYR_DT_BINDINGS_PINCTRL_SILABS_XG29_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h b/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h index 0c5933c580e50..25b76bb2dd570 100644 --- a/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h +++ b/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl-common.h @@ -26,9 +26,10 @@ #define STM32_PORTN 13 #define STM32_PORTO 14 #define STM32_PORTP 15 /* IO port P (0xF) */ +#define STM32_PORTQ 16 /* IO port Q (0x10) */ #ifndef STM32_PORTS_MAX -#define STM32_PORTS_MAX (STM32_PORTP + 1) +#define STM32_PORTS_MAX (STM32_PORTQ + 1) #endif /** diff --git a/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h index 52612f6948d51..aa055a5c3f73b 100644 --- a/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/stm32-pinctrl.h @@ -55,7 +55,7 @@ * - line [ 5 : 8 ] * - port [ 9 : 13 ] * - * @param port Port ('A'..'P') + * @param port Port ('A'..'Q') * @param line Pin (0..15) * @param mode Mode (ANALOG, GPIO_IN, ALTERNATE). */ diff --git a/include/zephyr/dt-bindings/pinctrl/sy1xx-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/sy1xx-pinctrl.h new file mode 100644 index 0000000000000..deee135bd600a --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/sy1xx-pinctrl.h @@ -0,0 +1,70 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 sensry.io + */ + +#ifndef _ZEPHYR_DT_BINDINGS_PINCTRL_SY1XX_PINCTRL_ +#define _ZEPHYR_DT_BINDINGS_PINCTRL_SY1XX_PINCTRL_ + +#define SY1XX_PAD(pad) (pad * 8) + +#define SY1XX_UART0_PAD_CFG0 0x0020 +#define SY1XX_UART1_PAD_CFG0 0x0024 +#define SY1XX_UART2_PAD_CFG0 0x0028 + +#define SY1XX_SPI0_PAD_CFG0 0x002c +#define SY1XX_SPI0_PAD_CFG1 0x0030 + +#define SY1XX_SPI1_PAD_CFG0 0x0034 +#define SY1XX_SPI1_PAD_CFG1 0x0038 + +#define SY1XX_SPI2_PAD_CFG0 0x003c +#define SY1XX_SPI2_PAD_CFG1 0x0040 + +#define SY1XX_SPI3_PAD_CFG0 0x0044 +#define SY1XX_SPI3_PAD_CFG1 0x0048 + +#define SY1XX_SPI4_PAD_CFG0 0x004c +#define SY1XX_SPI4_PAD_CFG1 0x0050 + +#define SY1XX_SPI5_PAD_CFG0 0x0054 +#define SY1XX_SPI5_PAD_CFG1 0x0058 + +#define SY1XX_SPI6_PAD_CFG0 0x005c +#define SY1XX_SPI6_PAD_CFG1 0x0060 + +#define SY1XX_I2C0_PAD_CFG0 0x0100 +#define SY1XX_I2C1_PAD_CFG0 0x0104 +#define SY1XX_I2C2_PAD_CFG0 0x0108 +#define SY1XX_I2C3_PAD_CFG0 0x010c + +#define SY1XX_GPIO0_PAD_CFG0 0x0110 +#define SY1XX_GPIO0_PAD_CFG1 0x0114 +#define SY1XX_GPIO0_PAD_CFG2 0x0118 +#define SY1XX_GPIO0_PAD_CFG3 0x011c +#define SY1XX_GPIO0_PAD_CFG4 0x0120 +#define SY1XX_GPIO0_PAD_CFG5 0x0124 +#define SY1XX_GPIO0_PAD_CFG6 0x0128 +#define SY1XX_GPIO0_PAD_CFG7 0x012c + +#define SY1XX_RGMII0_PAD_CFG0 0x0130 +#define SY1XX_RGMII0_PAD_CFG1 0x0134 +#define SY1XX_RGMII0_PAD_CFG2 0x0138 +#define SY1XX_RGMII0_PAD_CFG3 0x013c + +#define SY1XX_CAN0_PAD_CFG0 0x0140 + +#define SY1XX_I2S0_PAD_CFG0 0x0144 +#define SY1XX_I2S1_PAD_CFG0 0x0148 +#define SY1XX_I2S2_PAD_CFG0 0x014c +#define SY1XX_I2S3_PAD_CFG0 0x0150 + +#define SY1XX_HBUS0_PAD_CFG0 0x0154 +#define SY1XX_HBUS0_PAD_CFG1 0x0158 +#define SY1XX_HBUS0_PAD_CFG2 0x015c +#define SY1XX_HBUS0_PAD_CFG3 0x0160 + +#define SY1XX_QSPI0_PAD_CFG0 0x0164 +#define SY1XX_QSPI0_PAD_CFG1 0x0168 + +#endif /* _ZEPHYR_DT_BINDINGS_PINCTRL_SY1XX_PINCTRL_ */ diff --git a/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h b/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h index 7f6952f6f0bcb..e4a5b83a30418 100644 --- a/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h +++ b/include/zephyr/dt-bindings/power/nordic-nrf-gpd.h @@ -8,10 +8,10 @@ #define ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD /* numbers aligned to nrfs service identifiers */ -#define NRF_GPD_SLOW_MAIN 2U -#define NRF_GPD_SLOW_ACTIVE 1U -#define NRF_GPD_FAST_MAIN 3U -#define NRF_GPD_FAST_ACTIVE1 0U -#define NRF_GPD_FAST_ACTIVE0 4U +#define NRF_GPD_FAST_ACTIVE0 0U +#define NRF_GPD_FAST_ACTIVE1 1U +#define NRF_GPD_FAST_MAIN 2U +#define NRF_GPD_SLOW_ACTIVE 3U +#define NRF_GPD_SLOW_MAIN 4U #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_POWER_NORDIC_NRF_GLOBAL_PD */ diff --git a/include/zephyr/dt-bindings/pwm/renesas_rz_pwm.h b/include/zephyr/dt-bindings/pwm/renesas_rz_pwm.h new file mode 100644 index 0000000000000..8656ce617c574 --- /dev/null +++ b/include/zephyr/dt-bindings/pwm/renesas_rz_pwm.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RENESAS_RZ_PWM_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RENESAS_RZ_PWM_H_ + +#define RZ_PWM_GPT_IO_A 0 +#define RZ_PWM_GPT_IO_B 1 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RENESAS_RZ_PWM_H_ */ diff --git a/include/zephyr/dt-bindings/qspi/nxp-s32-qspi.h b/include/zephyr/dt-bindings/qspi/nxp-s32-qspi.h new file mode 100644 index 0000000000000..3de35cec8930f --- /dev/null +++ b/include/zephyr/dt-bindings/qspi/nxp-s32-qspi.h @@ -0,0 +1,17 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_NXP_S32_QSPI_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_NXP_S32_QSPI_H_ + +#include + +/* The QSPI secure attribute and secure policy references */ +#define NXP_S32_QSPI_NON_SECURE BIT(0) +#define NXP_S32_QSPI_SECURE BIT(1) +#define NXP_S32_QSPI_PRIVILEGE BIT(2) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_NXP_S32_QSPI_H_ */ diff --git a/include/zephyr/dt-bindings/reset/rp2350_reset.h b/include/zephyr/dt-bindings/reset/rp2350_reset.h new file mode 100644 index 0000000000000..81fcfa9ff31d1 --- /dev/null +++ b/include/zephyr/dt-bindings/reset/rp2350_reset.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RESET_RP2350_RESET_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RESET_RP2350_RESET_H_ + +#define RPI_PICO_RESETS_RESET_ADC 0 +#define RPI_PICO_RESETS_RESET_BUSCTRL 1 +#define RPI_PICO_RESETS_RESET_DMA 2 +#define RPI_PICO_RESETS_RESET_HSTX 3 +#define RPI_PICO_RESETS_RESET_I2C0 4 +#define RPI_PICO_RESETS_RESET_I2C1 5 +#define RPI_PICO_RESETS_RESET_IO_BANK0 6 +#define RPI_PICO_RESETS_RESET_IO_QSPI 7 +#define RPI_PICO_RESETS_RESET_JTAG 8 +#define RPI_PICO_RESETS_RESET_PADS_BANK0 9 +#define RPI_PICO_RESETS_RESET_PADS_QSPI 10 +#define RPI_PICO_RESETS_RESET_PIO0 11 +#define RPI_PICO_RESETS_RESET_PIO1 12 +#define RPI_PICO_RESETS_RESET_PIO2 13 +#define RPI_PICO_RESETS_RESET_PLL_SYS 14 +#define RPI_PICO_RESETS_RESET_PLL_USB 15 +#define RPI_PICO_RESETS_RESET_PWM 16 +#define RPI_PICO_RESETS_RESET_SHA256 17 +#define RPI_PICO_RESETS_RESET_SPI0 18 +#define RPI_PICO_RESETS_RESET_SPI1 19 +#define RPI_PICO_RESETS_RESET_SYSCFG 20 +#define RPI_PICO_RESETS_RESET_SYSINFO 21 +#define RPI_PICO_RESETS_RESET_TBMAN 22 +#define RPI_PICO_RESETS_RESET_TIMER0 23 +#define RPI_PICO_RESETS_RESET_TIMER1 24 +#define RPI_PICO_RESETS_RESET_TRNG 25 +#define RPI_PICO_RESETS_RESET_UART0 26 +#define RPI_PICO_RESETS_RESET_UART1 27 +#define RPI_PICO_RESETS_RESET_USBCTRL 28 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RESET_RP2350_RESET_H_ */ diff --git a/include/zephyr/dt-bindings/reset/stm32n6_reset.h b/include/zephyr/dt-bindings/reset/stm32n6_reset.h new file mode 100644 index 0000000000000..0b645598f0862 --- /dev/null +++ b/include/zephyr/dt-bindings/reset/stm32n6_reset.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32N6_RESET_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32N6_RESET_H_ + +#include "stm32-common.h" + +/* RCC bus reset register offset */ +#define STM32_RESET_BUS_AHB1 0x210 +#define STM32_RESET_BUS_AHB2 0x214 +#define STM32_RESET_BUS_AHB3 0x218 +#define STM32_RESET_BUS_AHB4 0x21C +#define STM32_RESET_BUS_AHB5 0x220 +#define STM32_RESET_BUS_APB1L 0x224 +#define STM32_RESET_BUS_APB1H 0x228 +#define STM32_RESET_BUS_APB2 0x22C +#define STM32_RESET_BUS_APB4L 0x234 +#define STM32_RESET_BUS_APB4H 0x238 +#define STM32_RESET_BUS_APB5 0x23C + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32N6_RESET_H_ */ diff --git a/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h b/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h index 76caabbdb7f9d..9cb142b2ed68b 100644 --- a/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h +++ b/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h @@ -91,4 +91,23 @@ #define LSM6DSV16X_DT_TEMP_BATCHED_AT_15Hz 0x2 #define LSM6DSV16X_DT_TEMP_BATCHED_AT_60Hz 0x3 +/* Sensor Fusion Low Power Data rates */ +#define LSM6DSV16X_DT_SFLP_ODR_AT_15Hz 0x0 +#define LSM6DSV16X_DT_SFLP_ODR_AT_30Hz 0x1 +#define LSM6DSV16X_DT_SFLP_ODR_AT_60Hz 0x2 +#define LSM6DSV16X_DT_SFLP_ODR_AT_120Hz 0x3 +#define LSM6DSV16X_DT_SFLP_ODR_AT_240Hz 0x4 +#define LSM6DSV16X_DT_SFLP_ODR_AT_480Hz 0x5 + +/* Sensor Fusion Low Power FIFO enable defs */ +#define LSM6DSV16X_DT_SFLP_FIFO_OFF 0x0 +#define LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION 0x1 +#define LSM6DSV16X_DT_SFLP_FIFO_GRAVITY 0x2 +#define LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY 0x3 +#define LSM6DSV16X_DT_SFLP_FIFO_GBIAS 0x4 +#define LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GBIAS 0x5 +#define LSM6DSV16X_DT_SFLP_FIFO_GRAVITY_GBIAS 0x6 +#define LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY_GBIAS 0x7 + + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV16X_H_ */ diff --git a/include/zephyr/dt-bindings/sensor/tmp116.h b/include/zephyr/dt-bindings/sensor/tmp116.h index fa7c1363ec109..0ec8a4db7587b 100644 --- a/include/zephyr/dt-bindings/sensor/tmp116.h +++ b/include/zephyr/dt-bindings/sensor/tmp116.h @@ -26,6 +26,16 @@ #define TMP116_DT_ODR_16000_MS 0x380 /** @} */ +/** + * @defgroup TMP116_OS Temperature average sample count + * @{ + */ +#define TMP116_DT_OVERSAMPLING_1 0 +#define TMP116_DT_OVERSAMPLING_8 0x20 +#define TMP116_DT_OVERSAMPLING_32 0x40 +#define TMP116_DT_OVERSAMPLING_64 0x60 +/** @} */ + /** @} */ #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_TI_TMP116_H_ */ diff --git a/include/zephyr/fs/fs.h b/include/zephyr/fs/fs.h index 57b7c84d6835b..e2cf7dff73b40 100644 --- a/include/zephyr/fs/fs.h +++ b/include/zephyr/fs/fs.h @@ -78,7 +78,7 @@ enum { /** Flag requests file system driver to use Disk Access API. When the flag is * set to the fs_mount_t.flags prior to fs_mount call, a file system * needs to use the Disk Access API, otherwise mount callback for the driver - * should return -ENOSUP; when the flag is not set the file system driver + * should return -ENOTSUP; when the flag is not set the file system driver * should use Flash API by default, unless it only supports Disc Access API. * When file system will use Disk Access API and the flag is not set, the mount * callback for the file system should set the flag on success. diff --git a/include/zephyr/fs/littlefs.h b/include/zephyr/fs/littlefs.h index 87618b4cc85e6..59a87492ae2c3 100644 --- a/include/zephyr/fs/littlefs.h +++ b/include/zephyr/fs/littlefs.h @@ -17,6 +17,22 @@ extern "C" { #endif +/** + * @brief Get the major part of the littlefs disk version + * + * @param disk_version The disk version of littlefs partition + * @return The major part of the littlefs disk version. + */ +#define FS_LITTLEFS_DISK_VERSION_MAJOR_GET(disk_version) FIELD_GET(GENMASK(31, 16), disk_version) + +/** + * @brief Get the minor part of the littlefs disk version + * + * @param disk_version The disk version of littlefs partition + * @return The minor part of the littlefs disk version. + */ +#define FS_LITTLEFS_DISK_VERSION_MINOR_GET(disk_version) FIELD_GET(GENMASK(15, 0), disk_version) + /** @brief Filesystem info structure for LittleFS mount */ struct fs_littlefs { /* Defaulted in driver, customizable before mount. */ diff --git a/include/zephyr/input/cy8cmbr3xxx.h b/include/zephyr/input/cy8cmbr3xxx.h new file mode 100644 index 0000000000000..a2e3518f166da --- /dev/null +++ b/include/zephyr/input/cy8cmbr3xxx.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Basalte bv + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_INPUT_CY8CMBR3XXX_H_ +#define ZEPHYR_INCLUDE_INPUT_CY8CMBR3XXX_H_ + +#include + +#define CY8CMBR3XXX_EZ_CLICK_CONFIG_SIZE 128 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct cy8cmbr3xxx_config_data { + uint8_t data[CY8CMBR3XXX_EZ_CLICK_CONFIG_SIZE]; +}; + +/** + * @brief Configure the CY8CMBR3xxx device with an EZ-Click generated configuration. + * + * @param dev Pointer to the input device instance + * @param config_data Pointer to the configuration data for the device + * + * @retval 0 if successful + * @retval <0 if failed + */ +int cy8cmbr3xxx_configure(const struct device *dev, + const struct cy8cmbr3xxx_config_data *config_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ZEPHYR_INCLUDE_INPUT_CY8CMBR3XXX_H_ */ diff --git a/include/zephyr/internal/syscall_handler.h b/include/zephyr/internal/syscall_handler.h index a1264d6c28733..b48070fad6b46 100644 --- a/include/zephyr/internal/syscall_handler.h +++ b/include/zephyr/internal/syscall_handler.h @@ -62,7 +62,7 @@ static inline bool k_is_in_user_syscall(void) * calls from supervisor mode bypass everything directly to * the implementation function. */ - return !k_is_in_isr() && (arch_current_thread()->syscall_frame != NULL); + return !k_is_in_isr() && (_current->syscall_frame != NULL); } /** @@ -350,7 +350,7 @@ int k_usermode_string_copy(char *dst, const char *src, size_t maxlen); #define K_OOPS(expr) \ do { \ if (expr) { \ - arch_syscall_oops(arch_current_thread()->syscall_frame); \ + arch_syscall_oops(_current->syscall_frame); \ } \ } while (false) diff --git a/include/zephyr/ipc/icmsg.h b/include/zephyr/ipc/icmsg.h index 6e4cbaeaa86c4..41967d7515360 100644 --- a/include/zephyr/ipc/icmsg.h +++ b/include/zephyr/ipc/icmsg.h @@ -27,14 +27,58 @@ extern "C" { */ enum icmsg_state { + /** Instance is not initialized yet. In this state: sending will fail, opening allowed. + */ ICMSG_STATE_OFF, - ICMSG_STATE_BUSY, - ICMSG_STATE_READY, + + /** Instance is initializing without session handshake. In this state: sending will fail, + * opening will fail. + */ + ICMSG_STATE_INITIALIZING_SID_DISABLED, + + /** Instance is initializing with session handshake. It is waiting for remote to acknowledge + * local session id. In this state: sending will fail, opening is allowed (local session id + * will change, so the remote may get unbound() callback). + */ + ICMSG_STATE_INITIALIZING_SID_ENABLED, + + /** Instance is initializing with detection of session handshake support on remote side. + * It is waiting for remote to acknowledge local session id or to send magic bytes. + * In this state: sending will fail, opening is allowed (local session id + * will change, so the remote may get unbound() callback if it supports it). + */ + ICMSG_STATE_INITIALIZING_SID_DETECT, + + /** Instance was closed on remote side. The unbound() callback was send on local side. + * In this state: sending will be silently discarded (there may be outdated sends), + * opening is allowed. + */ + ICMSG_STATE_DISCONNECTED, + + /* Connected states must be at the end. */ + + /** Instance is connected without session handshake support. In this state: sending will be + * successful, opening will fail. + */ + ICMSG_STATE_CONNECTED_SID_DISABLED, + + /** Instance is connected with session handshake support. In this state: sending will be + * successful, opening is allowed (session will change and remote will get unbound() + * callback). + */ + ICMSG_STATE_CONNECTED_SID_ENABLED, +}; + +enum icmsg_unbound_mode { + ICMSG_UNBOUND_MODE_DISABLE = ICMSG_STATE_INITIALIZING_SID_DISABLED, + ICMSG_UNBOUND_MODE_ENABLE = ICMSG_STATE_INITIALIZING_SID_ENABLED, + ICMSG_UNBOUND_MODE_DETECT = ICMSG_STATE_INITIALIZING_SID_DETECT, }; struct icmsg_config_t { struct mbox_dt_spec mbox_tx; struct mbox_dt_spec mbox_rx; + enum icmsg_unbound_mode unbound_mode; }; struct icmsg_data_t { @@ -52,9 +96,10 @@ struct icmsg_data_t { /* General */ const struct icmsg_config_t *cfg; #ifdef CONFIG_MULTITHREADING - struct k_work_delayable notify_work; struct k_work mbox_work; #endif + uint16_t remote_sid; + uint16_t local_sid; atomic_t state; }; diff --git a/include/zephyr/ipc/ipc_service.h b/include/zephyr/ipc/ipc_service.h index 65411a6be1ca8..dbc0b8b7ee48a 100644 --- a/include/zephyr/ipc/ipc_service.h +++ b/include/zephyr/ipc/ipc_service.h @@ -151,6 +151,21 @@ struct ipc_service_cb { */ void (*bound)(void *priv); + /** @brief The endpoint unbound by the remote. + * + * This callback is called when the endpoint binding is removed. It may happen on + * different reasons, e.g. when the remote deregistered the endpoint, connection was + * lost, or remote CPU got reset. + * + * You may want to do some cleanup, resetting, e.t.c. and after that if you want to bound + * again, you can register the endpoint. When the remote becomes available again and it + * also registers the endpoint, the binding will be reestablished and the `bound()` + * callback will be called. + * + * @param[in] priv Private user data. + */ + void (*unbound)(void *priv); + /** @brief New packet arrived. * * This callback is called when new data is received. diff --git a/include/zephyr/ipc/pbuf.h b/include/zephyr/ipc/pbuf.h index 8783cdbbf1465..4bc42bfdf4509 100644 --- a/include/zephyr/ipc/pbuf.h +++ b/include/zephyr/ipc/pbuf.h @@ -47,20 +47,23 @@ extern "C" { * The structure contains configuration data. */ struct pbuf_cfg { - volatile uint32_t *rd_idx_loc; /* Address of the variable holding - * index value of the first valid byte - * in data[]. - */ - volatile uint32_t *wr_idx_loc; /* Address of the variable holding - * index value of the first free byte - * in data[]. - */ - uint32_t dcache_alignment; /* CPU data cache line size in bytes. - * Used for validation - TODO: To be - * replaced by flags. - */ - uint32_t len; /* Length of data[] in bytes. */ - uint8_t *data_loc; /* Location of the data[]. */ + volatile uint32_t *rd_idx_loc; /* Address of the variable holding + * index value of the first valid byte + * in data[]. + */ + volatile uint32_t *handshake_loc;/* Address of the variable holding + * handshake information. + */ + volatile uint32_t *wr_idx_loc; /* Address of the variable holding + * index value of the first free byte + * in data[]. + */ + uint32_t dcache_alignment; /* CPU data cache line size in bytes. + * Used for validation - TODO: To be + * replaced by flags. + */ + uint32_t len; /* Length of data[] in bytes. */ + uint8_t *data_loc; /* Location of the data[]. */ }; /** @@ -111,16 +114,21 @@ struct pbuf { * @param mem_addr Memory address for pbuf. * @param size Size of the memory. * @param dcache_align Data cache alignment. + * @param use_handshake Add handshake word inside shared memory that can be access with + * @ref pbuf_handshake_read and @ref pbuf_handshake_write. */ -#define PBUF_CFG_INIT(mem_addr, size, dcache_align) \ +#define PBUF_CFG_INIT(mem_addr, size, dcache_align, use_handshake) \ { \ .rd_idx_loc = (uint32_t *)(mem_addr), \ - .wr_idx_loc = (uint32_t *)((uint8_t *)(mem_addr) + \ - MAX(dcache_align, _PBUF_IDX_SIZE)), \ + .handshake_loc = use_handshake ? (uint32_t *)((uint8_t *)(mem_addr) + \ + _PBUF_IDX_SIZE) : NULL, \ + .wr_idx_loc = (uint32_t *)((uint8_t *)(mem_addr) + MAX(dcache_align, \ + (use_handshake ? 2 : 1) * _PBUF_IDX_SIZE)), \ .data_loc = (uint8_t *)((uint8_t *)(mem_addr) + \ - MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE), \ - .len = (uint32_t)((uint32_t)(size) - MAX(dcache_align, _PBUF_IDX_SIZE) - \ - _PBUF_IDX_SIZE), \ + MAX(dcache_align, (use_handshake ? 2 : 1) * \ + _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE), \ + .len = (uint32_t)((uint32_t)(size) - MAX(dcache_align, \ + (use_handshake ? 2 : 1) * _PBUF_IDX_SIZE) - _PBUF_IDX_SIZE), \ .dcache_alignment = (dcache_align), \ } @@ -140,9 +148,11 @@ struct pbuf { * @param name Name of the pbuf. * @param mem_addr Memory address for pbuf. * @param size Size of the memory. - * @param dcache_align Data cache line size. + * @param dcache_align Data cache line size. + * @param use_handshake Add handshake word inside shared memory that can be access with + * @ref pbuf_handshake_read and @ref pbuf_handshake_write. */ -#define PBUF_DEFINE(name, mem_addr, size, dcache_align) \ +#define PBUF_DEFINE(name, mem_addr, size, dcache_align, use_handshake, compatibility) \ BUILD_ASSERT(dcache_align >= 0, \ "Cache line size must be non negative."); \ BUILD_ASSERT((size) > 0 && IS_PTR_ALIGNED_BYTES(size, _PBUF_IDX_SIZE), \ @@ -151,8 +161,10 @@ struct pbuf { "Misaligned memory."); \ BUILD_ASSERT(size >= (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE + \ _PBUF_MIN_DATA_LEN), "Insufficient size."); \ + BUILD_ASSERT(!(compatibility) || (dcache_align) >= 8, \ + "Data cache alignment must be at least 8 if compatibility is enabled.");\ static PBUF_MAYBE_CONST struct pbuf_cfg cfg_##name = \ - PBUF_CFG_INIT(mem_addr, size, dcache_align); \ + PBUF_CFG_INIT(mem_addr, size, dcache_align, use_handshake); \ static struct pbuf name = { \ .cfg = &cfg_##name, \ } @@ -223,6 +235,40 @@ int pbuf_write(struct pbuf *pb, const char *buf, uint16_t len); */ int pbuf_read(struct pbuf *pb, char *buf, uint16_t len); +/** + * @brief Read handshake word from pbuf. + * + * The pb must be defined with "PBUF_DEFINE" with "use_handshake" set. + * + * @param pb A buffer from which data will be read. + * @retval uint32_t The handshake word value. + */ +uint32_t pbuf_handshake_read(struct pbuf *pb); + +/** + * @brief Write handshake word to pbuf. + * + * The pb must be defined with "PBUF_DEFINE" with "use_handshake" set. + * + * @param pb A buffer to which data will be written. + * @param value A handshake value. + */ +void pbuf_handshake_write(struct pbuf *pb, uint32_t value); + +/** + * @brief Get first buffer from pbuf. + * + * This function retrieves buffer located at the beginning of queue. + * It will be continuous block since it is the first buffer. + * + * @param pb A buffer from which data will be read. + * @param[out] buf A pointer to output pointer to the date of the first buffer. + * @param[out] len A pointer to output length the first buffer. + * @retval 0 on success. + * -EINVAL when there is no buffer at the beginning of queue. + */ +int pbuf_get_initial_buf(struct pbuf *pb, volatile char **buf, uint16_t *len); + /** * @} */ diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index a35c453ed8c57..65a896efedf55 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -542,8 +543,6 @@ __syscall int k_thread_join(struct k_thread *thread, k_timeout_t timeout); * This routine puts the current thread to sleep for @a duration, * specified as a k_timeout_t object. * - * @note if @a timeout is set to K_FOREVER then the thread is suspended. - * * @param timeout Desired duration of sleep. * * @return Zero if the requested time has elapsed or if the thread was woken up @@ -757,7 +756,7 @@ struct _static_thread_data { #define Z_THREAD_INIT_DELAY_INITIALIZER(ms) .init_delay_ms = (ms) #define Z_THREAD_INIT_DELAY(thread) SYS_TIMEOUT_MS((thread)->init_delay_ms) #else -#define Z_THREAD_INIT_DELAY_INITIALIZER(ms) .init_delay = SYS_TIMEOUT_MS(ms) +#define Z_THREAD_INIT_DELAY_INITIALIZER(ms) .init_delay = SYS_TIMEOUT_MS_INIT(ms) #define Z_THREAD_INIT_DELAY(thread) (thread)->init_delay #endif @@ -948,6 +947,26 @@ __syscall void k_thread_priority_set(k_tid_t thread, int prio); __syscall void k_thread_deadline_set(k_tid_t thread, int deadline); #endif +/** + * @brief Invoke the scheduler + * + * This routine invokes the scheduler to force a schedule point on the current + * CPU. If invoked from within a thread, the scheduler will be invoked + * immediately (provided interrupts were not locked when invoked). If invoked + * from within an ISR, the scheduler will be invoked upon exiting the ISR. + * + * Invoking the scheduler allows the kernel to make an immediate determination + * as to what the next thread to execute should be. Unlike yielding, this + * routine is not guaranteed to switch to a thread of equal or higher priority + * if any are available. For example, if the current thread is cooperative and + * there is a still higher priority cooperative thread that is ready, then + * yielding will switch to that higher priority thread whereas this routine + * will not. + * + * Most applications will never use this routine. + */ +__syscall void k_reschedule(void); + #ifdef CONFIG_SCHED_CPU_MASK /** * @brief Sets all CPU enable masks to zero @@ -1024,10 +1043,11 @@ int k_thread_cpu_pin(k_tid_t thread, int cpu); * This routine prevents the kernel scheduler from making @a thread * the current thread. All other internal operations on @a thread are * still performed; for example, kernel objects it is waiting on are - * still handed to it. Note that any existing timeouts - * (e.g. k_sleep(), or a timeout argument to k_sem_take() et. al.) - * will be canceled. On resume, the thread will begin running - * immediately and return from the blocked call. + * still handed to it. Thread suspension does not impact any timeout + * upon which the thread may be waiting (such as a timeout from a call + * to k_sem_take() or k_sleep()). Thus if the timeout expires while the + * thread is suspended, it is still suspended until k_thread_resume() + * is called. * * When the target thread is active on another CPU, the caller will block until * the target thread is halted (suspended or aborted). But if the caller is in @@ -1043,8 +1063,9 @@ __syscall void k_thread_suspend(k_tid_t thread); /** * @brief Resume a suspended thread. * - * This routine allows the kernel scheduler to make @a thread the current - * thread, when it is next eligible for that role. + * This routine reverses the thread suspension from k_thread_suspend() + * and allows the kernel scheduler to make @a thread the current thread + * when it is next eligible for that role. * * If @a thread is not currently suspended, the routine has no effect. * @@ -1060,14 +1081,14 @@ __syscall void k_thread_resume(k_tid_t thread); * on it. * * @note This is a legacy API for compatibility. Modern Zephyr - * threads are initialized in the "suspended" state and no not need + * threads are initialized in the "sleeping" state and do not need * special handling for "start". * * @param thread thread to start */ static inline void k_thread_start(k_tid_t thread) { - k_thread_resume(thread); + k_wakeup(thread); } /** @@ -2544,9 +2565,10 @@ struct k_fifo { */ #define k_fifo_put(fifo, data) \ ({ \ - SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_fifo, put, fifo, data); \ - k_queue_append(&(fifo)->_queue, data); \ - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_fifo, put, fifo, data); \ + void *_data = data; \ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_fifo, put, fifo, _data); \ + k_queue_append(&(fifo)->_queue, _data); \ + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_fifo, put, fifo, _data); \ }) /** @@ -2567,9 +2589,10 @@ struct k_fifo { */ #define k_fifo_alloc_put(fifo, data) \ ({ \ - SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_fifo, alloc_put, fifo, data); \ - int fap_ret = k_queue_alloc_append(&(fifo)->_queue, data); \ - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_fifo, alloc_put, fifo, data, fap_ret); \ + void *_data = data; \ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_fifo, alloc_put, fifo, _data); \ + int fap_ret = k_queue_alloc_append(&(fifo)->_queue, _data); \ + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_fifo, alloc_put, fifo, _data, fap_ret); \ fap_ret; \ }) @@ -2766,9 +2789,10 @@ struct k_lifo { */ #define k_lifo_put(lifo, data) \ ({ \ - SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_lifo, put, lifo, data); \ - k_queue_prepend(&(lifo)->_queue, data); \ - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_lifo, put, lifo, data); \ + void *_data = data; \ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_lifo, put, lifo, _data); \ + k_queue_prepend(&(lifo)->_queue, _data); \ + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_lifo, put, lifo, _data); \ }) /** @@ -2789,9 +2813,10 @@ struct k_lifo { */ #define k_lifo_alloc_put(lifo, data) \ ({ \ - SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_lifo, alloc_put, lifo, data); \ - int lap_ret = k_queue_alloc_prepend(&(lifo)->_queue, data); \ - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_lifo, alloc_put, lifo, data, lap_ret); \ + void *_data = data; \ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_lifo, alloc_put, lifo, _data); \ + int lap_ret = k_queue_alloc_prepend(&(lifo)->_queue, _data); \ + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_lifo, alloc_put, lifo, _data, lap_ret); \ lap_ret; \ }) @@ -3395,7 +3420,7 @@ int k_work_busy_get(const struct k_work *work); /** @brief Test whether a work item is currently pending. * - * Wrapper to determine whether a work item is in a non-idle dstate. + * Wrapper to determine whether a work item is in a non-idle state. * * @note This is a live snapshot of state, which may change before the result * is checked. Use locks where appropriate. @@ -3606,6 +3631,22 @@ int k_work_queue_drain(struct k_work_q *queue, bool plug); */ int k_work_queue_unplug(struct k_work_q *queue); +/** @brief Stop a work queue. + * + * Stops the work queue thread and ensures that no further work will be processed. + * This call is blocking and guarantees that the work queue thread has terminated + * cleanly if successful, no work will be processed past this point. + * + * @param queue Pointer to the queue structure. + * @param timeout Maximum time to wait for the work queue to stop. + * + * @retval 0 if the work queue was stopped + * @retval -EALREADY if the work queue was not started (or already stopped) + * @retval -EBUSY if the work queue is actively processing work items + * @retval -ETIMEDOUT if the work queue did not stop within the stipulated timeout + */ +int k_work_queue_stop(struct k_work_q *queue, k_timeout_t timeout); + /** @brief Initialize a delayable work structure. * * This must be invoked before scheduling a delayable work structure for the @@ -3915,6 +3956,8 @@ enum { K_WORK_QUEUE_DRAIN = BIT(K_WORK_QUEUE_DRAIN_BIT), K_WORK_QUEUE_PLUGGED_BIT = 3, K_WORK_QUEUE_PLUGGED = BIT(K_WORK_QUEUE_PLUGGED_BIT), + K_WORK_QUEUE_STOP_BIT = 4, + K_WORK_QUEUE_STOP = BIT(K_WORK_QUEUE_STOP_BIT), /* Static work queue flags */ K_WORK_QUEUE_NO_YIELD_BIT = 8, @@ -4949,6 +4992,18 @@ void k_mbox_data_get(struct k_mbox_msg *rx_msg, void *buffer); * @{ */ +/** + * @brief initialize a pipe + * + * This routine initializes a pipe object, prior to its first use. + * + * @param pipe Address of the pipe. + * @param buffer Address of the pipe's buffer, or NULL if no ring buffer is used. + * @param buffer_size Size of the pipe's buffer, or zero if no ring buffer is used. + */ +__syscall void k_pipe_init(struct k_pipe *pipe, uint8_t *buffer, size_t buffer_size); + +#ifdef CONFIG_PIPES /** Pipe Structure */ struct k_pipe { unsigned char *buffer; /**< Pipe buffer: may be NULL */ @@ -5019,19 +5074,7 @@ struct k_pipe { Z_PIPE_INITIALIZER(name, _k_pipe_buf_##name, pipe_buffer_size) /** - * @brief Initialize a pipe. - * - * This routine initializes a pipe object, prior to its first use. - * - * @param pipe Address of the pipe. - * @param buffer Address of the pipe's ring buffer, or NULL if no ring buffer - * is used. - * @param size Size of the pipe's ring buffer (in bytes), or zero if no ring - * buffer is used. - */ -void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size); - -/** + * @deprecated Dynamic allocation of pipe buffers will be removed in the new k_pipe API. * @brief Release a pipe's allocated buffer * * If a pipe object was given a dynamically allocated buffer via @@ -5042,9 +5085,10 @@ void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size); * @retval 0 on success * @retval -EAGAIN nothing to cleanup */ -int k_pipe_cleanup(struct k_pipe *pipe); +__deprecated int k_pipe_cleanup(struct k_pipe *pipe); /** + * @deprecated Dynamic allocation of pipe buffers will be removed in the new k_pipe API. * @brief Initialize a pipe and allocate a buffer for it * * Storage for the buffer region will be allocated from the calling thread's @@ -5059,9 +5103,10 @@ int k_pipe_cleanup(struct k_pipe *pipe); * @retval 0 on success * @retval -ENOMEM if memory couldn't be allocated */ -__syscall int k_pipe_alloc_init(struct k_pipe *pipe, size_t size); +__deprecated __syscall int k_pipe_alloc_init(struct k_pipe *pipe, size_t size); /** + * @deprecated k_pipe_put() is replaced by k_pipe_write(...) in the new k_pipe API. * @brief Write data to a pipe. * * This routine writes up to @a bytes_to_write bytes of data to @a pipe. @@ -5079,11 +5124,12 @@ __syscall int k_pipe_alloc_init(struct k_pipe *pipe, size_t size); * @retval -EAGAIN Waiting period timed out; between zero and @a min_xfer * minus one data bytes were written. */ -__syscall int k_pipe_put(struct k_pipe *pipe, const void *data, +__deprecated __syscall int k_pipe_put(struct k_pipe *pipe, const void *data, size_t bytes_to_write, size_t *bytes_written, size_t min_xfer, k_timeout_t timeout); /** + * @deprecated k_pipe_get() is replaced by k_pipe_read(...) in the new k_pipe API. * @brief Read data from a pipe. * * This routine reads up to @a bytes_to_read bytes of data from @a pipe. @@ -5102,11 +5148,12 @@ __syscall int k_pipe_put(struct k_pipe *pipe, const void *data, * @retval -EAGAIN Waiting period timed out; between zero and @a min_xfer * minus one data bytes were read. */ -__syscall int k_pipe_get(struct k_pipe *pipe, void *data, +__deprecated __syscall int k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read, size_t *bytes_read, size_t min_xfer, k_timeout_t timeout); /** + * @deprecated k_pipe_read_avail() will be removed in the new k_pipe API. * @brief Query the number of bytes that may be read from @a pipe. * * @param pipe Address of the pipe. @@ -5114,9 +5161,10 @@ __syscall int k_pipe_get(struct k_pipe *pipe, void *data, * @retval a number n such that 0 <= n <= @ref k_pipe.size; the * result is zero for unbuffered pipes. */ -__syscall size_t k_pipe_read_avail(struct k_pipe *pipe); +__deprecated __syscall size_t k_pipe_read_avail(struct k_pipe *pipe); /** + * @deprecated k_pipe_write_avail() will be removed in the new k_pipe API. * @brief Query the number of bytes that may be written to @a pipe * * @param pipe Address of the pipe. @@ -5124,9 +5172,10 @@ __syscall size_t k_pipe_read_avail(struct k_pipe *pipe); * @retval a number n such that 0 <= n <= @ref k_pipe.size; the * result is zero for unbuffered pipes. */ -__syscall size_t k_pipe_write_avail(struct k_pipe *pipe); +__deprecated __syscall size_t k_pipe_write_avail(struct k_pipe *pipe); /** + * @deprecated k_pipe_flush() will be removed in the new k_pipe API. * @brief Flush the pipe of write data * * This routine flushes the pipe. Flushing the pipe is equivalent to reading @@ -5136,9 +5185,10 @@ __syscall size_t k_pipe_write_avail(struct k_pipe *pipe); * * @param pipe Address of the pipe. */ -__syscall void k_pipe_flush(struct k_pipe *pipe); +__deprecated __syscall void k_pipe_flush(struct k_pipe *pipe); /** + * @deprecated k_pipe_buffer_flush will be removed in the new k_pipe API. * @brief Flush the pipe's internal buffer * * This routine flushes the pipe's internal buffer. This is equivalent to @@ -5149,14 +5199,129 @@ __syscall void k_pipe_flush(struct k_pipe *pipe); * * @param pipe Address of the pipe. */ -__syscall void k_pipe_buffer_flush(struct k_pipe *pipe); +__deprecated __syscall void k_pipe_buffer_flush(struct k_pipe *pipe); -/** @} */ +#else /* CONFIG_PIPES */ + +enum pipe_flags { + PIPE_FLAG_OPEN = BIT(0), + PIPE_FLAG_RESET = BIT(1), +}; + +struct k_pipe { + size_t waiting; + struct ring_buf buf; + struct k_spinlock lock; + _wait_q_t data; + _wait_q_t space; + uint8_t flags; + + Z_DECL_POLL_EVENT +#ifdef CONFIG_OBJ_CORE_PIPE + struct k_obj_core obj_core; +#endif + SYS_PORT_TRACING_TRACKING_FIELD(k_pipe) +}; /** * @cond INTERNAL_HIDDEN */ +#define Z_PIPE_INITIALIZER(obj, pipe_buffer, pipe_buffer_size) \ +{ \ + .buf = RING_BUF_INIT(pipe_buffer, pipe_buffer_size), \ + .data = Z_WAIT_Q_INIT(&obj.data), \ + .space = Z_WAIT_Q_INIT(&obj.space), \ + .flags = PIPE_FLAG_OPEN, \ + .waiting = 0, \ + Z_POLL_EVENT_OBJ_INIT(obj) \ +} +/** + * INTERNAL_HIDDEN @endcond + */ + +/** + * @brief Statically define and initialize a pipe. + * + * The pipe can be accessed outside the module where it is defined using: + * + * @code extern struct k_pipe ; @endcode + * + * @param name Name of the pipe. + * @param pipe_buffer_size Size of the pipe's ring buffer (in bytes) + * or zero if no ring buffer is used. + * @param pipe_align Alignment of the pipe's ring buffer (power of 2). + * + */ +#define K_PIPE_DEFINE(name, pipe_buffer_size, pipe_align) \ + static unsigned char __noinit __aligned(pipe_align) \ + _k_pipe_buf_##name[pipe_buffer_size]; \ + STRUCT_SECTION_ITERABLE(k_pipe, name) = \ + Z_PIPE_INITIALIZER(name, _k_pipe_buf_##name, pipe_buffer_size) + + +/** + * @brief Write data to a pipe + * + * This routine writes up to @a len bytes of data to @a pipe. + * If the pipe is full, the routine will block until the data can be written or the timeout expires. + * + * @param pipe Address of the pipe. + * @param data Address of data to write. + * @param len Size of data (in bytes). + * @param timeout Waiting period to wait for the data to be written. + * + * @retval number of bytes written on success + * @retval -EAGAIN if no data could be written before the timeout expired + * @retval -ECANCELED if the write was interrupted by k_pipe_reset(..) + * @retval -EPIPE if the pipe was closed + */ +__syscall int k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, + k_timeout_t timeout); + +/** + * @brief Read data from a pipe + * This routine reads up to @a len bytes of data from @a pipe. + * If the pipe is empty, the routine will block until the data can be read or the timeout expires. + * + * @param pipe Address of the pipe. + * @param data Address to place the data read from pipe. + * @param len Requested number of bytes to read. + * @param timeout Waiting period to wait for the data to be read. + * + * @retval number of bytes read on success + * @retval -EAGAIN if no data could be read before the timeout expired + * @retval -ECANCELED if the read was interrupted by k_pipe_reset(..) + * @retval -EPIPE if the pipe was closed + */ +__syscall int k_pipe_read(struct k_pipe *pipe, uint8_t *data, size_t len, + k_timeout_t timeout); + +/** + * @brief Reset a pipe + * This routine resets the pipe, discarding any unread data and unblocking any threads waiting to + * write or read, causing the waiting threads to return with -ECANCELED. Calling k_pipe_read(..) or + * k_pipe_write(..) when the pipe is resetting but not yet reset will return -ECANCELED. + * The pipe is left open after a reset and can be used as normal. + * + * @param pipe Address of the pipe. + */ +__syscall void k_pipe_reset(struct k_pipe *pipe); + +/** + * @brief Close a pipe + * + * This routine closes a pipe. Any threads that were blocked on the pipe + * will be unblocked and receive an error code. + * + * @param pipe Address of the pipe. + */ +__syscall void k_pipe_close(struct k_pipe *pipe); +#endif /* CONFIG_PIPES */ +/** @} */ +/** + * @cond INTERNAL_HIDDEN + */ struct k_mem_slab_info { uint32_t num_blocks; size_t block_size; @@ -5469,6 +5634,31 @@ void *k_heap_aligned_alloc(struct k_heap *h, size_t align, size_t bytes, void *k_heap_alloc(struct k_heap *h, size_t bytes, k_timeout_t timeout) __attribute_nonnull(1); +/** + * @brief Allocate and initialize memory for an array of objects from a k_heap + * + * Allocates memory for an array of num objects of size and initializes all + * bytes in the allocated storage to zero. If no memory is available + * immediately, the call will block for the specified timeout (constructed + * via the standard timeout API, or K_NO_WAIT or K_FOREVER) waiting for memory + * to be freed. If the allocation cannot be performed by the expiration of + * the timeout, NULL will be returned. + * Allocated memory is aligned on a multiple of pointer sizes. + * + * @note @a timeout must be set to K_NO_WAIT if called from ISR. + * @note When CONFIG_MULTITHREADING=n any @a timeout is treated as K_NO_WAIT. + * + * @funcprops \isr_ok + * + * @param h Heap from which to allocate + * @param num Number of objects to allocate + * @param size Desired size of each object to allocate + * @param timeout How long to wait, or K_NO_WAIT + * @return A pointer to valid heap memory, or NULL + */ +void *k_heap_calloc(struct k_heap *h, size_t num, size_t size, k_timeout_t timeout) + __attribute_nonnull(1); + /** * @brief Reallocate memory from a k_heap * @@ -5828,9 +6018,7 @@ struct k_poll_event { struct k_fifo *fifo, *typed_K_POLL_TYPE_FIFO_DATA_AVAILABLE; struct k_queue *queue, *typed_K_POLL_TYPE_DATA_AVAILABLE; struct k_msgq *msgq, *typed_K_POLL_TYPE_MSGQ_DATA_AVAILABLE; -#ifdef CONFIG_PIPES struct k_pipe *pipe, *typed_K_POLL_TYPE_PIPE_DATA_AVAILABLE; -#endif }; }; diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index 3c1df990a22d8..56df49dcb23db 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -54,6 +54,9 @@ extern "C" { /* Thread is waiting on an object */ #define _THREAD_PENDING (BIT(1)) +/* Thread is sleeping */ +#define _THREAD_SLEEPING (BIT(2)) + /* Thread has terminated */ #define _THREAD_DEAD (BIT(3)) @@ -119,6 +122,9 @@ struct _priq_rb { struct _priq_mq { sys_dlist_t queues[K_NUM_THREAD_PRIO]; unsigned long bitmask[PRIQ_BITMAP_SIZE]; +#ifndef CONFIG_SMP + unsigned int cached_queue_index; +#endif }; struct _ready_q { @@ -168,7 +174,7 @@ struct _cpu { #endif #ifdef CONFIG_SMP - /* True when arch_current_thread() is allowed to context switch */ + /* True when _current is allowed to context switch */ uint8_t swap_ok; #endif @@ -254,15 +260,27 @@ extern atomic_t _cpus_active; * another SMP CPU. */ bool z_smp_cpu_mobile(void); - #define _current_cpu ({ __ASSERT_NO_MSG(!z_smp_cpu_mobile()); \ arch_curr_cpu(); }) +__attribute_const__ struct k_thread *z_smp_current_get(void); +#define _current z_smp_current_get() + #else #define _current_cpu (&_kernel.cpus[0]) -#endif /* CONFIG_SMP */ +#define _current _kernel.cpus[0].current +#endif -#define _current arch_current_thread() __DEPRECATED_MACRO +/* This is always invoked from a context where preemption is disabled */ +#define z_current_thread_set(thread) ({ _current_cpu->current = (thread); }) + +#ifdef CONFIG_ARCH_HAS_CUSTOM_CURRENT_IMPL +#undef _current +#define _current arch_current_thread() +#undef z_current_thread_set +#define z_current_thread_set(thread) \ + arch_current_thread_set(({ _current_cpu->current = (thread); })) +#endif /* kernel wait queue record */ #ifdef CONFIG_WAITQ_SCALABLE diff --git a/include/zephyr/linker/common-rom/common-rom-logging.ld b/include/zephyr/linker/common-rom/common-rom-logging.ld index 23c8ec757c4e3..d32ddade46c5a 100644 --- a/include/zephyr/linker/common-rom/common-rom-logging.ld +++ b/include/zephyr/linker/common-rom/common-rom-logging.ld @@ -7,8 +7,22 @@ { Z_LINK_ITERABLE(log_strings); } GROUP_ROM_LINK_IN(DEVNULL_REGION, DEVNULL_REGION) + + SECTION_PROLOGUE(log_stmesp_ptr,(COPY),SUBALIGN(Z_LINK_ITERABLE_SUBALIGN)) + { + Z_LINK_ITERABLE(log_stmesp_ptr); + } GROUP_ROM_LINK_IN(DEVNULL_REGION, DEVNULL_REGION) + + SECTION_PROLOGUE(log_stmesp_str,(COPY),SUBALIGN(Z_LINK_ITERABLE_SUBALIGN)) + { + Z_LINK_ITERABLE(log_stmesp_str); + } GROUP_ROM_LINK_IN(DEVNULL_REGION, DEVNULL_REGION) #else ITERABLE_SECTION_ROM(log_strings, Z_LINK_ITERABLE_SUBALIGN) + + ITERABLE_SECTION_ROM(log_stmesp_ptr, Z_LINK_ITERABLE_SUBALIGN) + + ITERABLE_SECTION_ROM(log_stmesp_str, Z_LINK_ITERABLE_SUBALIGN) #endif ITERABLE_SECTION_ROM(log_const, Z_LINK_ITERABLE_SUBALIGN) diff --git a/include/zephyr/linker/common-rom/common-rom-net.ld b/include/zephyr/linker/common-rom/common-rom-net.ld index 5305f9cf873c2..2b779e4699394 100644 --- a/include/zephyr/linker/common-rom/common-rom-net.ld +++ b/include/zephyr/linker/common-rom/common-rom-net.ld @@ -2,6 +2,10 @@ #include +#if defined(CONFIG_NETWORKING) + ITERABLE_SECTION_ROM(net_l3_register, Z_LINK_ITERABLE_SUBALIGN) +#endif + #if defined(CONFIG_NET_SOCKETS) ITERABLE_SECTION_ROM(net_socket_register, Z_LINK_ITERABLE_SUBALIGN) #endif diff --git a/include/zephyr/linker/iterable_sections.h b/include/zephyr/linker/iterable_sections.h index 3eb4e9527b8d1..d61d73c89d04f 100644 --- a/include/zephyr/linker/iterable_sections.h +++ b/include/zephyr/linker/iterable_sections.h @@ -21,6 +21,9 @@ _CONCAT(_##struct_type, _list_start) = .; \ KEEP(*(SORT(._##struct_type.static.*_?_*))); \ KEEP(*(SORT(._##struct_type.static.*_??_*))); \ + KEEP(*(SORT(._##struct_type.static.*_???_*))); \ + KEEP(*(SORT(._##struct_type.static.*_????_*))); \ + KEEP(*(SORT(._##struct_type.static.*_?????_*))); \ _CONCAT(_##struct_type, _list_end) = . #define Z_LINK_ITERABLE_ALIGNED(struct_type, align) \ diff --git a/include/zephyr/linker/linker-defs.h b/include/zephyr/linker/linker-defs.h index 9c795ae78517a..14bbc250f4c7f 100644 --- a/include/zephyr/linker/linker-defs.h +++ b/include/zephyr/linker/linker-defs.h @@ -28,7 +28,7 @@ /* We need to dummy out DT_NODE_HAS_STATUS when building the unittests. * Including devicetree.h would require generating dummy header files * to match what gen_defines creates, so it's easier to just dummy out - * DT_NODE_HAS_STATUS. + * DT_NODE_HAS_STATUS. These are undefined at the end of the file. */ #ifdef ZTEST_UNITTEST #define DT_NODE_HAS_STATUS(node, status) 0 @@ -359,4 +359,9 @@ extern char lnkr_ondemand_rodata_size[]; #endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */ #endif /* ! _ASMLANGUAGE */ +#ifdef ZTEST_UNITTEST +#undef DT_NODE_HAS_STATUS +#undef DT_NODE_HAS_STATUS_OKAY +#endif + #endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_ */ diff --git a/include/zephyr/linker/linker-devnull.h b/include/zephyr/linker/linker-devnull.h index d5455dd6da234..12dd7b7b41df3 100644 --- a/include/zephyr/linker/linker-devnull.h +++ b/include/zephyr/linker/linker-devnull.h @@ -11,6 +11,7 @@ */ #ifndef ZEPHYR_INCLUDE_LINKER_LINKER_DEVNULL_H_ +#define ZEPHYR_INCLUDE_LINKER_LINKER_DEVNULL_H_ #if defined(CONFIG_LINKER_DEVNULL_MEMORY) diff --git a/include/zephyr/linker/utils.h b/include/zephyr/linker/utils.h index c6f9177c42bf7..5b92f5b48dd11 100644 --- a/include/zephyr/linker/utils.h +++ b/include/zephyr/linker/utils.h @@ -24,8 +24,8 @@ static inline bool linker_is_in_rodata(const void *addr) { #if defined(CONFIG_LINKER_USE_PINNED_SECTION) - extern const char lnkr_pinned_rodata_start[]; - extern const char lnkr_pinned_rodata_end[]; + extern char lnkr_pinned_rodata_start[]; + extern char lnkr_pinned_rodata_end[]; if (((const char *)addr >= (const char *)lnkr_pinned_rodata_start) && ((const char *)addr < (const char *)lnkr_pinned_rodata_end)) { diff --git a/include/zephyr/llext/inspect.h b/include/zephyr/llext/inspect.h new file mode 100644 index 0000000000000..2cba50158553e --- /dev/null +++ b/include/zephyr/llext/inspect.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LLEXT_INSPECT_H +#define ZEPHYR_LLEXT_INSPECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/** + * @file + * @brief LLEXT ELF inspection routines. + * + * This file contains routines to inspect the contents of an ELF file. It is + * intended to be used by applications that need advanced access to the ELF + * file structures of a loaded extension. + * + * @defgroup llext_inspect_apis ELF inspection APIs + * @ingroup llext_apis + * @{ + */ + +/** + * @brief Get information about a memory region for the specified extension. + * + * Retrieve information about a region (merged group of similar sections) in + * the extension. Any output parameter can be NULL if that information is not + * needed. + * + * @param[in] ldr Loader + * @param[in] ext Extension + * @param[in] region Region to get information about + * @param[out] hdr Variable storing the pointer to the region header + * @param[out] addr Variable storing the region load address + * @param[out] size Variable storing the region size + * + * @return 0 on success, -EINVAL if the region is invalid + */ +static inline int llext_get_region_info(const struct llext_loader *ldr, + const struct llext *ext, + enum llext_mem region, + const elf_shdr_t **hdr, + const void **addr, size_t *size) +{ + if ((unsigned int)region >= LLEXT_MEM_COUNT) { + return -EINVAL; + } + + if (hdr) { + *hdr = &ldr->sects[region]; + } + if (addr) { + *addr = ext->mem[region]; + } + if (size) { + *size = ext->mem_size[region]; + } + + return 0; +} + +/** + * @brief Get the index of a section with the specified name. + * + * Requires the @ref llext_load_param.keep_section_info flag to be set at + * extension load time. + * + * @param[in] ldr Loader + * @param[in] ext Extension + * @param[in] section_name Name of the section to look for + * + * @return Section index on success, -ENOENT if the section was not found, + * -ENOTSUP if section data is not available. + */ +int llext_section_shndx(const struct llext_loader *ldr, const struct llext *ext, + const char *section_name); + +/** + * @brief Get information about a section for the specified extension. + * + * Retrieve information about an ELF sections in the extension. Any output + * parameter can be @c NULL if that information is not needed. + * + * Requires the @ref llext_load_param.keep_section_info flag to be set at + * extension load time. + * + * @param[in] ldr Loader + * @param[in] ext Extension + * @param[in] shndx Section index + * @param[out] hdr Variable storing the pointer to the section header + * @param[out] region Variable storing the region the section belongs to + * @param[out] offset Variable storing the offset of the section in the region + * + * @return 0 on success, -EINVAL if the section index is invalid, + * -ENOTSUP if section data is not available. + */ +static inline int llext_get_section_info(const struct llext_loader *ldr, + const struct llext *ext, + unsigned int shndx, + const elf_shdr_t **hdr, + enum llext_mem *region, + size_t *offset) +{ + if (shndx < 0 || shndx >= ext->sect_cnt) { + return -EINVAL; + } + if (!ldr->sect_map) { + return -ENOTSUP; + } + + if (hdr) { + *hdr = &ext->sect_hdrs[shndx]; + } + if (region) { + *region = ldr->sect_map[shndx].mem_idx; + } + if (offset) { + *offset = ldr->sect_map[shndx].offset; + } + + return 0; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LLEXT_INSPECT_H */ diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 5bd16ea33564d..a77248afda144 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -146,6 +146,7 @@ static inline unsigned int llext_section_count(const struct llext *ext) struct llext_load_param { /** Perform local relocation */ bool relocate_local; + /** * Use the virtual symbol addresses from the ELF, not addresses within * the memory buffer, when calculating relocation targets. It also @@ -154,12 +155,22 @@ struct llext_load_param { * allocation and copying internally. */ bool pre_located; + /** * Extensions can implement custom ELF sections to be loaded in specific * memory regions, detached from other sections of compatible types. * This optional callback checks whether a section should be detached. */ bool (*section_detached)(const elf_shdr_t *shdr); + + /** + * Keep the ELF section data in memory after loading the extension. This + * is needed to use some of the functions in @ref llext_inspect_apis. + * + * @note Related memory must be freed by @ref llext_free_inspection_data + * before the extension can be unloaded via @ref llext_unload. + */ + bool keep_section_info; }; /** Default initializer for @ref llext_load_param */ @@ -211,6 +222,19 @@ int llext_load(struct llext_loader *loader, const char *name, struct llext **ext */ int llext_unload(struct llext **ext); +/** + * @brief Free any inspection-related memory for the specified loader and extension. + * + * This is only required if inspection data was requested at load time by + * setting @ref llext_load_param.keep_section_info; otherwise, this call will + * be a no-op. + * + * @param[in] ldr Extension loader + * @param[in] ext Extension + * @returns 0 on success, or a negative error code. + */ +int llext_free_inspection_data(struct llext_loader *ldr, struct llext *ext); + /** @brief Entry point function signature for an extension. */ typedef void (*llext_entry_fn_t)(void *user_data); @@ -377,11 +401,11 @@ int llext_get_section_header(struct llext_loader *loader, struct llext *ext, * @param[in] ext Extension to call function in * @param[in] rel Relocation data provided by elf * @param[in] sym Corresponding symbol table entry - * @param[in] got_offset Offset within a relocation table or in the code + * @param[in] rel_addr Address where relocation should be performed * @param[in] ldr_parm Loader parameters */ void arch_elf_relocate_local(struct llext_loader *loader, struct llext *ext, const elf_rela_t *rel, - const elf_sym_t *sym, size_t got_offset, + const elf_sym_t *sym, uint8_t *rel_addr, const struct llext_load_param *ldr_parm); /** @@ -391,11 +415,11 @@ void arch_elf_relocate_local(struct llext_loader *loader, struct llext *ext, con * @param[in] ext Extension to call function in * @param[in] rel Relocation data provided by elf * @param[in] sym Corresponding symbol table entry - * @param[in] got_offset Offset within a relocation table or in the code + * @param[in] rel_addr Address where relocation should be performed * @param[in] link_addr target address for table-based relocations */ void arch_elf_relocate_global(struct llext_loader *loader, struct llext *ext, const elf_rela_t *rel, - const elf_sym_t *sym, size_t got_offset, const void *link_addr); + const elf_sym_t *sym, uint8_t *rel_addr, const void *link_addr); /** * @} diff --git a/include/zephyr/llext/llext_internal.h b/include/zephyr/llext/llext_internal.h index f07dd5efd8655..b5365aa5a751d 100644 --- a/include/zephyr/llext/llext_internal.h +++ b/include/zephyr/llext/llext_internal.h @@ -21,6 +21,11 @@ extern "C" { struct llext_loader; struct llext; +struct llext_elf_sect_map { + enum llext_mem mem_idx; + size_t offset; +}; + const void *llext_loaded_sect_ptr(struct llext_loader *ldr, struct llext *ext, unsigned int sh_ndx); /** @endcond */ diff --git a/include/zephyr/llext/symbol.h b/include/zephyr/llext/symbol.h index 9eb847b97fcf0..9a1394489cb2f 100644 --- a/include/zephyr/llext/symbol.h +++ b/include/zephyr/llext/symbol.h @@ -90,18 +90,30 @@ struct llext_symtable { /** @cond ignore */ #ifdef LL_EXTENSION_BUILD /* Extension build: add exported symbols to llext table */ -#define Z_LL_EXTENSION_SYMBOL(x) \ +#define Z_LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name) \ static const struct llext_const_symbol \ - Z_GENERIC_SECTION(".exported_sym") __used \ - __llext_sym_ ## x = { \ - .name = STRINGIFY(x), .addr = (const void *)&x, \ + Z_GENERIC_SECTION(.exported_sym) __used \ + __llext_sym_ ## sym_name = { \ + .name = STRINGIFY(sym_name), .addr = (const void *)&sym_ident, \ } #else /* No-op when not building an extension */ -#define Z_LL_EXTENSION_SYMBOL(x) +#define Z_LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name) #endif /** @endcond */ +/** + * @brief Exports a symbol from an extension to the base image with a custom name + * + * Version of @ref LL_EXTENSION_SYMBOL that allows the user to specify a custom + * name for the exported symbol. + * + * @param sym_ident Extension symbol to export to the base image + * @param sym_name Name associated with the symbol + */ +#define LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name) \ + Z_LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name) + /** * @brief Exports a symbol from an extension to the base image * @@ -113,34 +125,50 @@ struct llext_symtable { * * @param x Extension symbol to export to the base image */ -#define LL_EXTENSION_SYMBOL(x) Z_LL_EXTENSION_SYMBOL(x) +#define LL_EXTENSION_SYMBOL(x) Z_LL_EXTENSION_SYMBOL_NAMED(x, x) /** @cond ignore */ #if defined(LL_EXTENSION_BUILD) /* Extension build: EXPORT_SYMBOL maps to LL_EXTENSION_SYMBOL */ -#define Z_EXPORT_SYMBOL(x) Z_LL_EXTENSION_SYMBOL(x) +#define Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name) \ + Z_LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name) #elif defined(CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) /* SLID-enabled LLEXT application: export symbols, names in separate section */ -#define Z_EXPORT_SYMBOL(x) \ - static const char Z_GENERIC_SECTION("llext_exports_strtab") __used \ - __llext_sym_name_ ## x[] = STRINGIFY(x); \ - static const STRUCT_SECTION_ITERABLE(llext_const_symbol, \ - __llext_sym_ ## x) = { \ - .name = __llext_sym_name_ ## x, .addr = (const void *)&x, \ +#define Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name) \ + static const char Z_GENERIC_SECTION(llext_exports_strtab) __used \ + __llext_sym_name_ ## sym_name[] = STRINGIFY(sym_name); \ + static const STRUCT_SECTION_ITERABLE(llext_const_symbol, \ + __llext_sym_ ## sym_name) = { \ + .name = __llext_sym_name_ ## sym_name, \ + .addr = (const void *)&sym_ident, \ } #elif defined(CONFIG_LLEXT) /* LLEXT application: export symbols */ -#define Z_EXPORT_SYMBOL(x) \ - static const STRUCT_SECTION_ITERABLE(llext_const_symbol, \ - __llext_sym_ ## x) = { \ - .name = STRINGIFY(x), .addr = (const void *)&x, \ +#define Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name) \ + static const STRUCT_SECTION_ITERABLE(llext_const_symbol, \ + __llext_sym_ ## sym_name) = { \ + .name = STRINGIFY(sym_name), .addr = (const void *)&sym_ident, \ } #else /* No extension support in this build */ -#define Z_EXPORT_SYMBOL(x) +#define Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name) #endif /** @endcond */ +/** + * @brief Export a constant symbol from the current build with a custom name + * + * Version of @ref EXPORT_SYMBOL that allows the user to specify a custom name + * for the exported symbol. + * + * When @c CONFIG_LLEXT is not enabled, this macro is a no-op. + * + * @param sym_ident Symbol to export + * @param sym_name Name associated with the symbol + */ +#define EXPORT_SYMBOL_NAMED(sym_ident, sym_name) \ + Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name) + /** * @brief Export a constant symbol from the current build * @@ -152,7 +180,7 @@ struct llext_symtable { * * @param x Symbol to export */ -#define EXPORT_SYMBOL(x) Z_EXPORT_SYMBOL(x) +#define EXPORT_SYMBOL(x) EXPORT_SYMBOL_NAMED(x, x) /** * @} diff --git a/include/zephyr/logging/log_backend.h b/include/zephyr/logging/log_backend.h index e772ad2b9c82d..c68d210af7350 100644 --- a/include/zephyr/logging/log_backend.h +++ b/include/zephyr/logging/log_backend.h @@ -83,6 +83,7 @@ struct log_backend_control_block { void *ctx; uint8_t id; bool active; + bool initialized; /* Initialization level. */ uint8_t level; @@ -140,6 +141,7 @@ static inline void log_backend_init(const struct log_backend *const backend) if (backend->api->init) { backend->api->init(backend); } + backend->cb->initialized = true; } /** diff --git a/include/zephyr/logging/log_backend_ble.h b/include/zephyr/logging/log_backend_ble.h index ea6752de747c0..b544c3e2d7727 100644 --- a/include/zephyr/logging/log_backend_ble.h +++ b/include/zephyr/logging/log_backend_ble.h @@ -9,7 +9,7 @@ #include /** - * @brief Raw adv UUID data to add the ble backend for the use with apps + * @brief Raw adv UUID data to add the Bluetooth backend for the use with apps * such as the NRF Toolbox * */ @@ -19,7 +19,7 @@ 0x6E /** - * @brief Hook for application to know when the ble backend + * @brief Hook for application to know when the Bluetooth backend * is enabled or disabled. * @param backend_status True if the backend is enabled or false if disabled * @param ctx User context @@ -28,10 +28,10 @@ typedef void (*logger_backend_ble_hook)(bool backend_status, void *ctx); /** - * @brief Allows application to add a hook for the status of the BLE + * @brief Allows application to add a hook for the status of the Bluetooth * logger backend. - * @details The BLE logger backend is enabled or disabled auomatically by - * the subscription of the notification characteristic of this BLE + * @details The Bluetooth logger backend is enabled or disabled auomatically by + * the subscription of the notification characteristic of this Bluetooth * Logger backend service. * * @param hook The hook that will be called when the status of the backend changes diff --git a/include/zephyr/logging/log_core.h b/include/zephyr/logging/log_core.h index 64cd2a6c9e573..821a6ae98e45c 100644 --- a/include/zephyr/logging/log_core.h +++ b/include/zephyr/logging/log_core.h @@ -353,13 +353,14 @@ static inline char z_log_minimal_level_to_char(int level) z_log_minimal_hexdump_print((_level), (const char *)(_data), (_len)); \ break; \ } \ - int mode; \ - Z_LOG_MSG_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), mode, \ + int _mode; \ + Z_LOG_MSG_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), _mode, \ Z_LOG_LOCAL_DOMAIN_ID, _source, _level, _data, _len, \ COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \ (), \ (COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \ ("%s", __VA_ARGS__), (__VA_ARGS__))))); \ + (void)_mode; \ } while (false) #define Z_LOG_HEXDUMP(_level, _data, _length, ...) \ diff --git a/include/zephyr/logging/log_ctrl.h b/include/zephyr/logging/log_ctrl.h index 26d09589027be..2a6b431f22118 100644 --- a/include/zephyr/logging/log_ctrl.h +++ b/include/zephyr/logging/log_ctrl.h @@ -95,6 +95,17 @@ __syscall void log_panic(void); */ __syscall bool log_process(void); +/** + * @brief Process all pending log messages + */ +#ifdef CONFIG_LOG_MODE_DEFERRED +void log_flush(void); +#else +static inline void log_flush(void) +{ +} +#endif + /** * @brief Return number of buffered log messages. * diff --git a/include/zephyr/logging/log_frontend_stmesp.h b/include/zephyr/logging/log_frontend_stmesp.h index ac9fae6957887..e2b7a2159a53b 100644 --- a/include/zephyr/logging/log_frontend_stmesp.h +++ b/include/zephyr/logging/log_frontend_stmesp.h @@ -44,7 +44,7 @@ void log_frontend_stmesp_dummy_write(void); /** @brief Trace point * * Write a trace point information using STM. Number of unique trace points is limited - * to 65536 - CONFIG_LOG_FRONTEND_STMESP_TP_CHAN_BASE per core. + * to 32768 - CONFIG_LOG_FRONTEND_STMESP_TP_CHAN_BASE per core. * * @param x Trace point ID. */ @@ -65,7 +65,7 @@ static inline void log_frontend_stmesp_tp(uint16_t x) /** @brief Trace point with 32 bit data. * * Write a trace point information using STM. Number of unique trace points is limited - * to 65536 - CONFIG_LOG_FRONTEND_STMESP_TP_CHAN_BASE per core. + * to 32768 - CONFIG_LOG_FRONTEND_STMESP_TP_CHAN_BASE per core. * * @param x Trace point ID. * @param d Data. 32 bit word. @@ -84,6 +84,57 @@ static inline void log_frontend_stmesp_tp_d32(uint16_t x, uint32_t d) #endif } +/** @brief Function called for log message with no arguments when turbo logging is enabled. + * + * @param source Pointer to the source structure. + * @param x Index of the string used for the log message. + */ +void log_frontend_stmesp_log0(const void *source, uint32_t x); + +/** @brief Function called for log message with one argument when turbo logging is enabled. + * + * @param source Pointer to the source structure. + * @param x Index of the string used for the log message. + * @param arg Argument. + */ +void log_frontend_stmesp_log1(const void *source, uint32_t x, uint32_t arg); + +TYPE_SECTION_START_EXTERN(const char *, log_stmesp_ptr); + +/** @brief Macro for handling a turbo log message with no arguments. + * + * @param _source Pointer to the source structure. + * @param ... String. + */ +#define LOG_FRONTEND_STMESP_LOG0(_source, ...) \ + do { \ + static const char _str[] __in_section(_log_stmesp_str, static, _) \ + __used __noasan __aligned(sizeof(uint32_t)) = GET_ARG_N(1, __VA_ARGS__); \ + static const char *_str_ptr __in_section(_log_stmesp_ptr, static, _) \ + __used __noasan = _str; \ + uint32_t idx = \ + ((uintptr_t)&_str_ptr - (uintptr_t)TYPE_SECTION_START(log_stmesp_ptr)) / \ + sizeof(void *); \ + log_frontend_stmesp_log0(_source, idx); \ + } while (0) + +/** @brief Macro for handling a turbo log message with one argument. + * + * @param _source Pointer to the source structure. + * @param ... String with one numeric argument. + */ +#define LOG_FRONTEND_STMESP_LOG1(_source, ...) \ + do { \ + static const char _str[] __in_section(_log_stmesp_str, static, _) \ + __used __noasan __aligned(sizeof(uint32_t)) = GET_ARG_N(1, __VA_ARGS__); \ + static const char *_str_ptr __in_section(_log_stmesp_ptr, static, _) \ + __used __noasan = _str; \ + uint32_t idx = \ + ((uintptr_t)&_str_ptr - (uintptr_t)TYPE_SECTION_START(log_stmesp_ptr)) / \ + sizeof(void *); \ + log_frontend_stmesp_log1(_source, idx, (uintptr_t)(GET_ARG_N(2, __VA_ARGS__))); \ + } while (0) + #ifdef __cplusplus } #endif diff --git a/include/zephyr/logging/log_frontend_stmesp_demux.h b/include/zephyr/logging/log_frontend_stmesp_demux.h index 058ff48ad95de..728ce4011ff33 100644 --- a/include/zephyr/logging/log_frontend_stmesp_demux.h +++ b/include/zephyr/logging/log_frontend_stmesp_demux.h @@ -121,11 +121,14 @@ struct log_frontend_stmesp_demux_trace_point { /** Flag indicating if trace point includes data. */ uint64_t has_data: 1; - /** Timestamp. */ - uint64_t timestamp: 58; + /** Timestamp. 54 bits at 40MHz is >14 years. */ + uint64_t timestamp: 54; /** Major ID. */ - uint16_t major; + uint64_t major: 4; + + /** Source ID - used for compressed logging. */ + uint16_t source_id; /** ID */ uint16_t id; @@ -180,6 +183,12 @@ struct log_frontend_stmesp_demux_config { /** Array length. Must be not bigger than @ref LOG_FRONTEND_STMESP_DEMUX_MAJOR_MAX. */ uint32_t m_ids_cnt; + + /** Buffer for storing source ID's. Used for turbo logging. */ + uint32_t *source_id_buf; + + /** It must be multiple of number of major ID's count. */ + size_t source_id_buf_len; }; /** @brief Initialize the demultiplexer. @@ -210,6 +219,19 @@ void log_frontend_stmesp_demux_channel(uint16_t id); */ int log_frontend_stmesp_demux_packet_start(uint32_t *data, uint64_t *ts); +/** @brief Indicate optimized log message with no arguments. + * + * @param source_id Source ID. + * @param ts Timestamp. Can be NULL. + */ +int log_frontend_stmesp_demux_log0(uint16_t source_id, uint64_t *ts); + +/** @brief Indicate source ID. + * + * @param source_id Source ID. + */ +void log_frontend_stmesp_demux_source_id(uint16_t source_id); + /** @brief Indicate timestamp. * * Timestamp is separated from packet start because according to STM spec (3.2.2) @@ -254,6 +276,21 @@ union log_frontend_stmesp_demux_packet log_frontend_stmesp_demux_claim(void); */ void log_frontend_stmesp_demux_free(union log_frontend_stmesp_demux_packet packet); +/** @brief Get source name for a turbo log message. + * + * During a boot cooprocessors (FLPR and PPR) are sending location in memory where + * their source data is stored. If application core is an owner of those cores + * it has access to that memory and based on chip ID and source ID it can retrieve + * the source name. + * + * @param m_id Major ID. + * @param s_id Source ID. + * + * @return Pointer to a string which is a source name or unknown name if source name + * cannot be retrieved. + */ +const char *log_frontend_stmesp_demux_sname_get(uint32_t m_id, uint16_t s_id); + /** @brief Check if there are any started but not completed log messages. * * @retval True There is no pending started log message. diff --git a/include/zephyr/mctp/mctp_uart.h b/include/zephyr/mctp/mctp_uart.h new file mode 100644 index 0000000000000..63eb1de9f2584 --- /dev/null +++ b/include/zephyr/mctp/mctp_uart.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef ZEPHYR_MCTP_UART_H_ +#define ZEPHYR_MCTP_UART_H_ + +#include +#include +#include +#include + +/** + * @brief An MCTP binding for Zephyr's asynchronous UART interface + */ +struct mctp_binding_uart { + /** @cond INTERNAL_HIDDEN */ + struct mctp_binding binding; + const struct device *dev; + + /* receive buffers and state */ + uint8_t rx_buf[2][256]; + bool rx_buf_used[2]; + struct mctp_pktbuf *rx_pkt; + uint8_t rx_exp_len; + uint16_t rx_fcs; + uint16_t rx_fcs_calc; + enum { + STATE_WAIT_SYNC_START, + STATE_WAIT_REVISION, + STATE_WAIT_LEN, + STATE_DATA, + STATE_DATA_ESCAPED, + STATE_WAIT_FCS1, + STATE_WAIT_FCS2, + STATE_WAIT_SYNC_END, + } rx_state; + int rx_res; + + /* staging buffer for tx */ + uint8_t tx_buf[256]; + int tx_res; + + /** @endcond INTERNAL_HIDDEN */ +}; + +/** + * @brief Start the receive of a single mctp message + * + * Will read a single mctp message from the uart. + * + * @param uart MCTP UART binding + */ +void mctp_uart_start_rx(struct mctp_binding_uart *uart); + +/** @cond INTERNAL_HIDDEN */ +int mctp_uart_start(struct mctp_binding *binding); +int mctp_uart_tx(struct mctp_binding *binding, struct mctp_pktbuf *pkt); +/** @endcond INTERNAL_HIDDEN */ + +/** + * @brief Statically define a MCTP bus binding for a UART + * + * @param _name Symbolic name of the bus binding variable + * @param _dev UART device + */ +#define MCTP_UART_DT_DEFINE(_name, _dev) \ + struct mctp_binding_uart _name = { \ + .binding = \ + { \ + .name = STRINGIFY(_name), .version = 1, \ + .pkt_size = MCTP_PACKET_SIZE(MCTP_BTU), \ + .pkt_header = 0, .pkt_trailer = 0, \ + .start = mctp_uart_start, .tx = mctp_uart_tx, \ + }, \ + .dev = _dev, \ + .rx_state = STATE_WAIT_SYNC_START, \ + .rx_pkt = NULL, \ + .rx_res = 0, \ + .tx_res = 0, \ + }; + +#endif /* ZEPHYR_MCTP_UART_H_ */ diff --git a/include/zephyr/mgmt/hawkbit/event.h b/include/zephyr/mgmt/hawkbit/event.h new file mode 100644 index 0000000000000..fd3ed69df60de --- /dev/null +++ b/include/zephyr/mgmt/hawkbit/event.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2024 Vogl Electronic GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief hawkBit event header file + */ + +/** + * @brief hawkBit event API. + * @defgroup hawkbit_event hawkBit event API + * @ingroup hawkbit + * @{ + */ + +#ifndef ZEPHYR_INCLUDE_MGMT_HAWKBIT_EVENT_H_ +#define ZEPHYR_INCLUDE_MGMT_HAWKBIT_EVENT_H_ + +#include +#include + +/** + * @brief hawkBit event type. + * + * @details These events are used to register the callback functions. + * + */ +enum hawkbit_event_type { + /** Event triggered when there was an error */ + HAWKBIT_EVENT_ERROR, + /** Event triggered when there was a networking error */ + HAWKBIT_EVENT_ERROR_NETWORKING, + /** Event triggered when there was a permission error */ + HAWKBIT_EVENT_ERROR_PERMISSION, + /** Event triggered when there was a metadata error */ + HAWKBIT_EVENT_ERROR_METADATA, + /** Event triggered when there was a download error */ + HAWKBIT_EVENT_ERROR_DOWNLOAD, + /** Event triggered when there was an allocation error */ + HAWKBIT_EVENT_ERROR_ALLOC, + /** Event triggered when a new update was downloaded */ + HAWKBIT_EVENT_UPDATE_DOWNLOADED, + /** Event triggered when there is no update available */ + HAWKBIT_EVENT_NO_UPDATE, + /** Event triggered when the update was canceled by the server */ + HAWKBIT_EVENT_CANCEL_UPDATE, + /** Event triggered before the download starts */ + HAWKBIT_EVENT_START_DOWNLOAD, + /** Event triggered after the download ends */ + HAWKBIT_EVENT_END_DOWNLOAD, + /** Event triggered before the hawkBit run starts */ + HAWKBIT_EVENT_START_RUN, + /** Event triggered after the hawkBit run ends */ + HAWKBIT_EVENT_END_RUN, + /** Event triggered before hawkBit does a reboot */ + HAWKBIT_EVENT_BEFORE_REBOOT, +}; + +struct hawkbit_event_callback; + +/** + * @typedef hawkbit_event_callback_handler_t + * @brief Define the application callback handler function signature + * + * @param cb Original struct hawkbit_event_callback owning this handler + * @param event The event that triggered the callback + * + * Note: cb pointer can be used to retrieve private data through + * CONTAINER_OF() if original struct hawkbit_event_callback is stored in + * another private structure. + */ +typedef void (*hawkbit_event_callback_handler_t)(struct hawkbit_event_callback *cb, + enum hawkbit_event_type event); + +/** @cond INTERNAL_HIDDEN */ + +/** + * @brief hawkBit callback structure + * + * Used to register a callback in the hawkBit callback list. + * As many callbacks as needed can be added as long as each of them + * are unique pointers of struct hawkbit_event_callback. + * Beware such structure should not be allocated on stack. + * + * Note: To help setting it, see hawkbit_event_init_callback() below + */ +struct hawkbit_event_callback { + /** This is meant to be used internally and the user should not mess with it. */ + sys_snode_t node; + + /** Actual callback function being called when relevant. */ + hawkbit_event_callback_handler_t handler; + + /** The event type this callback is attached to. */ + enum hawkbit_event_type event; +}; + +/** @endcond */ + + +/** + * @brief Macro to create and initialize a struct hawkbit_event_callback properly. + * + * @details This macro can be used instead of hawkbit_event_init_callback(). + * + * @param _callback Name of the callback structure + * @param _handler A valid handler function pointer. + * @param _event The event of ::hawkbit_event_type that will trigger the callback + */ +#define HAWKBIT_EVENT_CREATE_CALLBACK(_callback, _handler, _event) \ + struct hawkbit_event_callback _callback = { \ + .handler = _handler, \ + .event = _event, \ + } + +/** + * @brief Helper to initialize a struct hawkbit_event_callback properly + * + * @param callback A valid Application's callback structure pointer. + * @param handler A valid handler function pointer. + * @param event The event of ::hawkbit_event_type that will trigger the callback. + */ +static inline void hawkbit_event_init_callback(struct hawkbit_event_callback *callback, + hawkbit_event_callback_handler_t handler, + enum hawkbit_event_type event) +{ + __ASSERT(callback, "Callback pointer should not be NULL"); + __ASSERT(handler, "Callback handler pointer should not be NULL"); + + callback->handler = handler; + callback->event = event; +} + +/** + * @brief Add an application callback. + * + * @param cb A valid application's callback structure pointer. + * + * @return 0 if successful, negative errno code on failure. + */ +int hawkbit_event_add_callback(struct hawkbit_event_callback *cb); + +/** + * @brief Remove an application callback. + * + * @param cb A valid application's callback structure pointer. + * + * @return 0 if successful, negative errno code on failure. + */ +int hawkbit_event_remove_callback(struct hawkbit_event_callback *cb); + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_MGMT_HAWKBIT_EVENT_H_ */ diff --git a/include/zephyr/mgmt/hawkbit/hawkbit.h b/include/zephyr/mgmt/hawkbit/hawkbit.h index 6ef5952132e72..e5c8474b23ed8 100644 --- a/include/zephyr/mgmt/hawkbit/hawkbit.h +++ b/include/zephyr/mgmt/hawkbit/hawkbit.h @@ -33,6 +33,10 @@ enum hawkbit_response { /** matching events were not received within the specified time */ HAWKBIT_NO_RESPONSE, + /** an update was installed. Reboot is required to apply it */ + HAWKBIT_UPDATE_INSTALLED, + /** no update was available */ + HAWKBIT_NO_UPDATE, /** fail to connect to the hawkBit server */ HAWKBIT_NETWORKING_ERROR, /** image is unconfirmed */ @@ -43,14 +47,8 @@ enum hawkbit_response { HAWKBIT_METADATA_ERROR, /** fail while downloading the update package */ HAWKBIT_DOWNLOAD_ERROR, - /** image was already updated */ - HAWKBIT_OK, - /** an update was installed. Reboot is required to apply it */ - HAWKBIT_UPDATE_INSTALLED, - /** no update was available */ - HAWKBIT_NO_UPDATE, - /** update was cancelled by the server */ - HAWKBIT_CANCEL_UPDATE, + /** fail to allocate memory */ + HAWKBIT_ALLOC_ERROR, /** hawkBit is not initialized */ HAWKBIT_NOT_INITIALIZED, /** probe is currently running */ diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h index 49dffc6b7ca39..88ce62ca28cb0 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h @@ -9,11 +9,14 @@ #define H_IMG_MGMT_ #include -#include -#include #include #include +#ifdef CONFIG_MCUMGR_GRP_IMG_VERBOSE_ERR +#include +#include +#endif + /** * @brief MCUmgr img_mgmt API * @defgroup mcumgr_img_mgmt MCUmgr img_mgmt API diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h index 5c479fd99182d..5a1b8de034352 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h @@ -41,6 +41,16 @@ struct img_mgmt_upload_check { struct img_mgmt_upload_req *req; }; +/** + * Structure provided in the #MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED notification callback: This + * callback function is used to notify the application about an image confirmation being executed + * successfully. + */ +struct img_mgmt_image_confirmed { + /** Image number which has been confirmed */ + const uint8_t image; +}; + /** * Structure provided in the #MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE notification callback: This * callback function is used to allow applications or modules append custom fields to the image diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h index 9aef7721929dc..da4572e33da34 100644 --- a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h @@ -47,6 +47,9 @@ enum os_mgmt_err_code_t { /** RTC command failed */ OS_MGMT_ERR_RTC_COMMAND_FAILED, + + /** Query was recognized but there is no valid value for the response. */ + OS_MGMT_ERR_QUERY_RESPONSE_VALUE_NOT_VALID, }; /* Bitmask values used by the os info command handler. Note that the width of this variable is diff --git a/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h b/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h index e3cd408ea7311..c5ee05dca39ac 100644 --- a/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h +++ b/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h @@ -179,19 +179,28 @@ enum img_mgmt_group_events { /** Callback when a DFU operation has finished being transferred. */ MGMT_EVT_OP_IMG_MGMT_DFU_PENDING = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 3), - /** Callback when an image has been confirmed. */ + /** Callback when an image has been confirmed. data is img_mgmt_image_confirmed(). */ MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 4), /** Callback when an image write command has finished writing to flash. */ MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK_WRITE_COMPLETE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 5), - /** Callback when an image slot's state is encoded for a response. */ + /** + * Callback when an image slot's state is encoded for a response, data is + * img_mgmt_state_slot_encode(). + */ MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 6), - /** Callback when an slot list command outputs fields for an image. */ + /** + * Callback when a slot list command outputs fields for an image, data is + * img_mgmt_slot_info_image(). + */ MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_IMAGE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 7), - /** Callback when an slot list command outputs fields for a slot of an image. */ + /** + * Callback when a slot list command outputs fields for a slot of an image, data is + * img_mgmt_slot_info_slot(). + */ MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_SLOT = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 8), /** Used to enable all img_mgmt_group events. */ @@ -202,13 +211,13 @@ enum img_mgmt_group_events { * MGMT event opcodes for operating system management group. */ enum os_mgmt_group_events { - /** Callback when a reset command has been received, data is os_mgmt_reset_data. */ + /** Callback when a reset command has been received, data is os_mgmt_reset_data(). */ MGMT_EVT_OP_OS_MGMT_RESET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 0), - /** Callback when an info command is processed, data is os_mgmt_info_check. */ + /** Callback when an info command is processed, data is os_mgmt_info_check(). */ MGMT_EVT_OP_OS_MGMT_INFO_CHECK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 1), - /** Callback when an info command needs to output data, data is os_mgmt_info_append. */ + /** Callback when an info command needs to output data, data is os_mgmt_info_append(). */ MGMT_EVT_OP_OS_MGMT_INFO_APPEND = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 2), /** Callback when a datetime get command has been received. */ @@ -219,7 +228,7 @@ enum os_mgmt_group_events { /** * Callback when a bootloader info command has been received, data is - * os_mgmt_bootloader_info_data. + * os_mgmt_bootloader_info_data(). */ MGMT_EVT_OP_OS_MGMT_BOOTLOADER_INFO = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 5), diff --git a/include/zephyr/mgmt/mcumgr/transport/smp.h b/include/zephyr/mgmt/mcumgr/transport/smp.h index 38aa1b0e0c22c..a6542845d9409 100644 --- a/include/zephyr/mgmt/mcumgr/transport/smp.h +++ b/include/zephyr/mgmt/mcumgr/transport/smp.h @@ -42,7 +42,7 @@ typedef int (*smp_transport_out_fn)(struct net_buf *nb); * The supplied net_buf should contain a request received from the peer whose * MTU is being queried. This function takes a net_buf parameter because some * transports store connection-specific information in the net_buf user header - * (e.g., the BLE transport stores the peer address). + * (e.g., the Bluetooth transport stores the peer address). * * @param nb Contains a request from the relevant peer. * @@ -55,7 +55,7 @@ typedef uint16_t (*smp_transport_get_mtu_fn)(const struct net_buf *nb); * @brief SMP copy user_data callback * * The supplied src net_buf should contain a user_data that cannot be copied - * using regular memcpy function (e.g., the BLE transport net_buf user_data + * using regular memcpy function (e.g., the Bluetooth transport net_buf user_data * stores the connection reference that has to be incremented when is going * to be used by another buffer). * @@ -71,7 +71,7 @@ typedef int (*smp_transport_ud_copy_fn)(struct net_buf *dst, * @brief SMP free user_data callback * * This function frees net_buf user data, because some transports store - * connection-specific information in the net_buf user data (e.g., the BLE + * connection-specific information in the net_buf user data (e.g., the Bluetooth * transport stores the connection reference that has to be decreased). * * @param ud Contains a user_data pointer to be freed. diff --git a/include/zephyr/mgmt/mcumgr/transport/smp_shell.h b/include/zephyr/mgmt/mcumgr/transport/smp_shell.h index 705ec697ff701..a7c4831f58f96 100644 --- a/include/zephyr/mgmt/mcumgr/transport/smp_shell.h +++ b/include/zephyr/mgmt/mcumgr/transport/smp_shell.h @@ -11,6 +11,7 @@ #ifndef ZEPHYR_INCLUDE_MGMT_SMP_SHELL_H_ #define ZEPHYR_INCLUDE_MGMT_SMP_SHELL_H_ +#include #include #ifdef __cplusplus diff --git a/include/zephyr/net/coap_client.h b/include/zephyr/net/coap_client.h index ce09c56dd2e6c..40e856de3710e 100644 --- a/include/zephyr/net/coap_client.h +++ b/include/zephyr/net/coap_client.h @@ -24,6 +24,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** Maximum size of a CoAP message */ #define MAX_COAP_MSG_LEN (CONFIG_COAP_CLIENT_MESSAGE_HEADER_SIZE + \ CONFIG_COAP_CLIENT_MESSAGE_SIZE) @@ -153,6 +157,8 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr * * This is intended for canceling long-running requests (e.g. GETs with the OBSERVE option set) * which has gone stale for some reason. + * The function should also be called before the corresponding client socket is closed, + * to prevent the socket from being monitored by the internal polling thread. * * @param client Client instance. */ @@ -184,16 +190,11 @@ void coap_client_cancel_request(struct coap_client *client, struct coap_client_r * * @return CoAP client initial Block2 option structure */ -static inline struct coap_client_option coap_client_option_initial_block2(void) -{ - struct coap_client_option block2 = { - .code = COAP_OPTION_BLOCK2, - .len = 1, - .value[0] = coap_bytes_to_block_size(CONFIG_COAP_CLIENT_BLOCK_SIZE), - }; - - return block2; +struct coap_client_option coap_client_option_initial_block2(void); + +#ifdef __cplusplus } +#endif /** * @} diff --git a/include/zephyr/net/dns_resolve.h b/include/zephyr/net/dns_resolve.h index 33398dabdf134..3413a00839581 100644 --- a/include/zephyr/net/dns_resolve.h +++ b/include/zephyr/net/dns_resolve.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -156,13 +157,14 @@ enum dns_socket_type { struct dns_resolve_context; struct mdns_responder_context; +struct dns_socket_dispatcher; /** * @typedef dns_socket_dispatcher_cb * @brief Callback used when the DNS socket dispatcher has found a handler for * this type of socket. * - * @param ctx DNS resolve or mDNS responder context. + * @param ctx struct dns_socket_dispatcher context. * @param sock Socket which is seeing traffic. * @param addr Socket address of the peer that sent the DNS packet. * @param addrlen Length of the socket address. @@ -171,7 +173,7 @@ struct mdns_responder_context; * * @return 0 if ok, <0 if error */ -typedef int (*dns_socket_dispatcher_cb)(void *ctx, int sock, +typedef int (*dns_socket_dispatcher_cb)(struct dns_socket_dispatcher *ctx, int sock, struct sockaddr *addr, size_t addrlen, struct net_buf *buf, size_t data_len); @@ -214,13 +216,6 @@ struct dns_socket_dispatcher { k_timeout_t buf_timeout; }; -struct mdns_responder_context { - struct sockaddr server_addr; - struct dns_socket_dispatcher dispatcher; - struct zsock_pollfd fds[1]; - int sock; -}; - /** * @brief Register a DNS dispatcher socket. Each code wanting to use * the dispatcher needs to create the dispatcher context and call @@ -431,6 +426,29 @@ struct dns_resolve_context { enum dns_resolve_context_state state; }; +/** @cond INTERNAL_HIDDEN */ + +struct mdns_probe_user_data { + struct mdns_responder_context *ctx; + char query[DNS_MAX_NAME_SIZE + 1]; + uint16_t dns_id; +}; + +struct mdns_responder_context { + struct sockaddr server_addr; + struct dns_socket_dispatcher dispatcher; + struct zsock_pollfd fds[1]; + int sock; + struct net_if *iface; +#if defined(CONFIG_MDNS_RESPONDER_PROBE) + struct k_work_delayable probe_timer; + struct dns_resolve_context probe_ctx; + struct mdns_probe_user_data probe_data; +#endif +}; + +/** @endcond */ + /** * @brief Init DNS resolving context. * diff --git a/include/zephyr/net/dsa.h b/include/zephyr/net/dsa.h index db81a5e353655..8131574cd24d5 100644 --- a/include/zephyr/net/dsa.h +++ b/include/zephyr/net/dsa.h @@ -28,12 +28,8 @@ #define NET_DSA_PORT_MAX_COUNT 8 #define DSA_STATUS_PERIOD_MS K_MSEC(1000) -/* - * Size of the DSA TAG: - * - KSZ8794 - 1 byte - */ -#if defined(CONFIG_DSA_KSZ8794) && defined(CONFIG_DSA_KSZ_TAIL_TAGGING) -#define DSA_TAG_SIZE 1 +#ifdef CONFIG_DSA_TAG_SIZE +#define DSA_TAG_SIZE CONFIG_DSA_TAG_SIZE #else #define DSA_TAG_SIZE 0 #endif diff --git a/include/zephyr/net/ethernet.h b/include/zephyr/net/ethernet.h index c870525c2e9f8..85856eafa701f 100644 --- a/include/zephyr/net/ethernet.h +++ b/include/zephyr/net/ethernet.h @@ -58,57 +58,61 @@ struct net_eth_addr { #define NET_ETH_HDR(pkt) ((struct net_eth_hdr *)net_pkt_data(pkt)) +/* zephyr-keep-sorted-start */ +#define NET_ETH_PTYPE_ALL 0x0003 /* from linux/if_ether.h */ +#define NET_ETH_PTYPE_ARP 0x0806 #define NET_ETH_PTYPE_CAN 0x000C /* CAN: Controller Area Network */ #define NET_ETH_PTYPE_CANFD 0x000D /* CANFD: CAN flexible data rate*/ +#define NET_ETH_PTYPE_EAPOL 0x888e +#define NET_ETH_PTYPE_ECAT 0x88a4 #define NET_ETH_PTYPE_HDLC 0x0019 /* HDLC frames (like in PPP) */ -#define NET_ETH_PTYPE_ARP 0x0806 +#define NET_ETH_PTYPE_IEEE802154 0x00F6 /* from linux/if_ether.h: IEEE802.15.4 frame */ #define NET_ETH_PTYPE_IP 0x0800 -#define NET_ETH_PTYPE_TSN 0x22f0 /* TSN (IEEE 1722) packet */ #define NET_ETH_PTYPE_IPV6 0x86dd -#define NET_ETH_PTYPE_VLAN 0x8100 -#define NET_ETH_PTYPE_PTP 0x88f7 #define NET_ETH_PTYPE_LLDP 0x88cc -#define NET_ETH_PTYPE_ALL 0x0003 /* from linux/if_ether.h */ -#define NET_ETH_PTYPE_ECAT 0x88a4 -#define NET_ETH_PTYPE_EAPOL 0x888e -#define NET_ETH_PTYPE_IEEE802154 0x00F6 /* from linux/if_ether.h: IEEE802.15.4 frame */ +#define NET_ETH_PTYPE_PTP 0x88f7 +#define NET_ETH_PTYPE_TSN 0x22f0 /* TSN (IEEE 1722) packet */ +#define NET_ETH_PTYPE_VLAN 0x8100 +/* zephyr-keep-sorted-stop */ +/* zephyr-keep-sorted-start re(^#define) */ +#if !defined(ETH_P_8021Q) +#define ETH_P_8021Q NET_ETH_PTYPE_VLAN +#endif #if !defined(ETH_P_ALL) #define ETH_P_ALL NET_ETH_PTYPE_ALL #endif -#if !defined(ETH_P_IP) -#define ETH_P_IP NET_ETH_PTYPE_IP -#endif #if !defined(ETH_P_ARP) #define ETH_P_ARP NET_ETH_PTYPE_ARP #endif -#if !defined(ETH_P_IPV6) -#define ETH_P_IPV6 NET_ETH_PTYPE_IPV6 +#if !defined(ETH_P_CAN) +#define ETH_P_CAN NET_ETH_PTYPE_CAN #endif -#if !defined(ETH_P_8021Q) -#define ETH_P_8021Q NET_ETH_PTYPE_VLAN +#if !defined(ETH_P_CANFD) +#define ETH_P_CANFD NET_ETH_PTYPE_CANFD #endif -#if !defined(ETH_P_TSN) -#define ETH_P_TSN NET_ETH_PTYPE_TSN +#if !defined(ETH_P_EAPOL) +#define ETH_P_EAPOL NET_ETH_PTYPE_EAPOL #endif #if !defined(ETH_P_ECAT) -#define ETH_P_ECAT NET_ETH_PTYPE_ECAT +#define ETH_P_ECAT NET_ETH_PTYPE_ECAT #endif -#if !defined(ETH_P_EAPOL) -#define ETH_P_EAPOL NET_ETH_PTYPE_EAPOL +#if !defined(ETH_P_HDLC) +#define ETH_P_HDLC NET_ETH_PTYPE_HDLC #endif #if !defined(ETH_P_IEEE802154) -#define ETH_P_IEEE802154 NET_ETH_PTYPE_IEEE802154 +#define ETH_P_IEEE802154 NET_ETH_PTYPE_IEEE802154 #endif -#if !defined(ETH_P_CAN) -#define ETH_P_CAN NET_ETH_PTYPE_CAN +#if !defined(ETH_P_IP) +#define ETH_P_IP NET_ETH_PTYPE_IP #endif -#if !defined(ETH_P_CANFD) -#define ETH_P_CANFD NET_ETH_PTYPE_CANFD +#if !defined(ETH_P_IPV6) +#define ETH_P_IPV6 NET_ETH_PTYPE_IPV6 #endif -#if !defined(ETH_P_HDLC) -#define ETH_P_HDLC NET_ETH_PTYPE_HDLC +#if !defined(ETH_P_TSN) +#define ETH_P_TSN NET_ETH_PTYPE_TSN #endif +/* zephyr-keep-sorted-stop */ /** @endcond */ @@ -230,7 +234,8 @@ enum ethernet_config_type { ETHERNET_CONFIG_TYPE_T1S_PARAM, ETHERNET_CONFIG_TYPE_TXINJECTION_MODE, ETHERNET_CONFIG_TYPE_RX_CHECKSUM_SUPPORT, - ETHERNET_CONFIG_TYPE_TX_CHECKSUM_SUPPORT + ETHERNET_CONFIG_TYPE_TX_CHECKSUM_SUPPORT, + ETHERNET_CONFIG_TYPE_EXTRA_TX_PKT_HEADROOM, }; enum ethernet_qav_param_type { @@ -525,6 +530,8 @@ struct ethernet_config { enum ethernet_checksum_support chksum_support; struct ethernet_filter filter; + + uint16_t extra_tx_pkt_headroom; }; }; @@ -611,9 +618,7 @@ struct ethernet_vlan { #if defined(CONFIG_NET_VLAN_COUNT) #define NET_VLAN_MAX_COUNT CONFIG_NET_VLAN_COUNT #else -/* Even thou there are no VLAN support, the minimum count must be set to 1. - */ -#define NET_VLAN_MAX_COUNT 1 +#define NET_VLAN_MAX_COUNT 0 #endif /** @endcond */ @@ -674,7 +679,14 @@ struct ethernet_context { struct net_if *iface; #if defined(CONFIG_NET_LLDP) - struct ethernet_lldp lldp[NET_VLAN_MAX_COUNT]; +#if NET_VLAN_MAX_COUNT > 0 +#define NET_LLDP_MAX_COUNT NET_VLAN_MAX_COUNT +#else +#define NET_LLDP_MAX_COUNT 1 +#endif /* NET_VLAN_MAX_COUNT > 0 */ + + /** LLDP specific parameters */ + struct ethernet_lldp lldp[NET_LLDP_MAX_COUNT]; #endif /** @@ -981,7 +993,7 @@ int net_eth_get_hw_config(struct net_if *iface, enum ethernet_config_type type, * * @return 0 if ok, <0 if error */ -#if defined(CONFIG_NET_VLAN) +#if defined(CONFIG_NET_VLAN) && NET_VLAN_MAX_COUNT > 0 int net_eth_vlan_enable(struct net_if *iface, uint16_t tag); #else static inline int net_eth_vlan_enable(struct net_if *iface, uint16_t tag) @@ -1001,7 +1013,7 @@ static inline int net_eth_vlan_enable(struct net_if *iface, uint16_t tag) * * @return 0 if ok, <0 if error */ -#if defined(CONFIG_NET_VLAN) +#if defined(CONFIG_NET_VLAN) && NET_VLAN_MAX_COUNT > 0 int net_eth_vlan_disable(struct net_if *iface, uint16_t tag); #else static inline int net_eth_vlan_disable(struct net_if *iface, uint16_t tag) @@ -1024,7 +1036,7 @@ static inline int net_eth_vlan_disable(struct net_if *iface, uint16_t tag) * @return VLAN tag for this interface or NET_VLAN_TAG_UNSPEC if VLAN * is not configured for that interface. */ -#if defined(CONFIG_NET_VLAN) +#if defined(CONFIG_NET_VLAN) && NET_VLAN_MAX_COUNT > 0 uint16_t net_eth_get_vlan_tag(struct net_if *iface); #else static inline uint16_t net_eth_get_vlan_tag(struct net_if *iface) @@ -1066,7 +1078,7 @@ struct net_if *net_eth_get_vlan_iface(struct net_if *iface, uint16_t tag) * @return Network interface related to this tag or NULL if no such interface * exists. */ -#if defined(CONFIG_NET_VLAN) +#if defined(CONFIG_NET_VLAN) && NET_VLAN_MAX_COUNT > 0 struct net_if *net_eth_get_vlan_main(struct net_if *iface); #else static inline @@ -1112,7 +1124,7 @@ static inline bool net_eth_is_vlan_enabled(struct ethernet_context *ctx, * * @return True if VLAN is enabled for this network interface, false if not. */ -#if defined(CONFIG_NET_VLAN) +#if defined(CONFIG_NET_VLAN) && NET_VLAN_MAX_COUNT > 0 bool net_eth_get_vlan_status(struct net_if *iface); #else static inline bool net_eth_get_vlan_status(struct net_if *iface) @@ -1130,7 +1142,7 @@ static inline bool net_eth_get_vlan_status(struct net_if *iface) * * @return True if this network interface is VLAN one, false if not. */ -#if defined(CONFIG_NET_VLAN) +#if defined(CONFIG_NET_VLAN) && NET_VLAN_MAX_COUNT > 0 bool net_eth_is_vlan_interface(struct net_if *iface); #else static inline bool net_eth_is_vlan_interface(struct net_if *iface) @@ -1257,6 +1269,16 @@ static inline bool net_eth_is_vlan_interface(struct net_if *iface) #define ETH_NET_DEVICE_DT_INST_DEFINE(inst, ...) \ ETH_NET_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__) +/** + * @brief Ethernet L3 protocol register macro. + * + * @param name Name of the L3 protocol. + * @param ptype Ethernet protocol type. + * @param handler Handler function for this protocol type. + */ +#define ETH_NET_L3_REGISTER(name, ptype, handler) \ + NET_L3_REGISTER(&NET_L2_GET_NAME(ETHERNET), name, ptype, handler) + /** * @brief Inform ethernet L2 driver that ethernet carrier is detected. * This happens when cable is connected. diff --git a/include/zephyr/net/ethernet_vlan.h b/include/zephyr/net/ethernet_vlan.h index ba969954812e6..ff9f32524af05 100644 --- a/include/zephyr/net/ethernet_vlan.h +++ b/include/zephyr/net/ethernet_vlan.h @@ -31,6 +31,9 @@ extern "C" { /** Unspecified VLAN tag value */ #define NET_VLAN_TAG_UNSPEC 0x0fff +/** VLAN ID for forwarding to the native interface (priority tagging) */ +#define NET_VLAN_TAG_PRIORITY 0x0000 + /** * @brief Get VLAN identifier from TCI. * diff --git a/include/zephyr/net/http/client.h b/include/zephyr/net/http/client.h index 71eb1b32f336f..bc86ba48ab449 100644 --- a/include/zephyr/net/http/client.h +++ b/include/zephyr/net/http/client.h @@ -197,9 +197,16 @@ struct http_response { */ uint16_t http_status_code; + /** + * HTTP Content-Range response field value. Consist of range_start, + * range_end and total_size. Total is set to 0 if not supplied. + */ + struct http_content_range content_range; + uint8_t cl_present : 1; /**< Is Content-Length field present */ uint8_t body_found : 1; /**< Is message body found */ uint8_t message_complete : 1; /**< Is HTTP message parsing complete */ + uint8_t cr_present : 1; /**< Is Content-Range field present */ }; /** HTTP client internal data that the application should not touch diff --git a/include/zephyr/net/http/parser.h b/include/zephyr/net/http/parser.h index 38006f5e98551..dab7d43b6aefd 100644 --- a/include/zephyr/net/http/parser.h +++ b/include/zephyr/net/http/parser.h @@ -48,6 +48,7 @@ typedef unsigned __int64 uint64_t; #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -133,6 +134,8 @@ enum http_errno { HPE_INVALID_CONTENT_LENGTH, HPE_UNEXPECTED_CONTENT_LENGTH, HPE_INVALID_CHUNK_SIZE, + HPE_INVALID_CONTENT_RANGE, + HPE_UNEXPECTED_CONTENT_RANGE, HPE_INVALID_CONSTANT, HPE_INVALID_INTERNAL_STATE, HPE_STRICT, @@ -143,6 +146,11 @@ enum http_errno { /* Get an http_errno value from an http_parser */ #define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) +struct http_content_range { + uint64_t start; + uint64_t end; + uint64_t total; +}; struct http_parser { /** PRIVATE **/ @@ -160,6 +168,8 @@ struct http_parser { uint64_t content_length; /* # bytes in body (0 if no Content-Length * header) */ + bool content_range_present; + struct http_content_range content_range; /** READ-ONLY **/ unsigned short http_major; unsigned short http_minor; diff --git a/include/zephyr/net/http/server.h b/include/zephyr/net/http/server.h index 4cb40e52eb6de..ef2fb92e5bda5 100644 --- a/include/zephyr/net/http/server.h +++ b/include/zephyr/net/http/server.h @@ -254,6 +254,7 @@ BUILD_ASSERT(offsetof(struct http_resource_detail_dynamic, common) == 0); * reading and writing websocket data, and closing the connection. * * @param ws_socket A socket for the Websocket data. + * @param request_ctx Request context structure associated with HTTP upgrade request * @param user_data User specified data. * * @return 0 Accepting the connection, HTTP server library will no longer @@ -261,7 +262,7 @@ BUILD_ASSERT(offsetof(struct http_resource_detail_dynamic, common) == 0); * to send and receive data to/from the supplied socket. * <0 error, close the connection. */ -typedef int (*http_resource_websocket_cb_t)(int ws_socket, +typedef int (*http_resource_websocket_cb_t)(int ws_socket, struct http_request_ctx *request_ctx, void *user_data); /** @brief Representation of a websocket server resource */ @@ -399,6 +400,9 @@ struct http_client_ctx { /** Socket descriptor associated with the server. */ int fd; + /** HTTP service on which the client is connected */ + const struct http_service_desc *service; + /** Client data buffer. */ unsigned char buffer[HTTP_SERVER_CLIENT_BUFFER_SIZE]; diff --git a/include/zephyr/net/http/service.h b/include/zephyr/net/http/service.h index 6a836b7334822..574ab0a0ce845 100644 --- a/include/zephyr/net/http/service.h +++ b/include/zephyr/net/http/service.h @@ -19,6 +19,7 @@ * @{ */ +#include "zephyr/net/http/server.h" #include #include @@ -67,27 +68,33 @@ struct http_resource_desc { struct http_service_desc { const char *host; uint16_t *port; + int *fd; void *detail; size_t concurrent; size_t backlog; struct http_resource_desc *res_begin; struct http_resource_desc *res_end; + struct http_resource_detail *res_fallback; #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) const sec_tag_t *sec_tag_list; size_t sec_tag_list_size; #endif }; -#define __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, _res_begin, \ +#define __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, \ + _res_fallback, _res_begin, \ _res_end, ...) \ - const STRUCT_SECTION_ITERABLE(http_service_desc, _name) = { \ + static int _name##_fd = -1; \ + const STRUCT_SECTION_ITERABLE(http_service_desc, _name) = { \ .host = _host, \ .port = (uint16_t *)(_port), \ + .fd = &_name##_fd, \ .detail = (void *)(_detail), \ .concurrent = (_concurrent), \ .backlog = (_backlog), \ .res_begin = (_res_begin), \ .res_end = (_res_end), \ + .res_fallback = (_res_fallback), \ COND_CODE_1(CONFIG_NET_SOCKETS_SOCKOPT_TLS, \ (.sec_tag_list = COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), (NULL), \ (GET_ARG_N(1, __VA_ARGS__))),), ()) \ @@ -115,10 +122,13 @@ struct http_service_desc { * @param[inout] _port Pointer to port associated with the service. * @param _concurrent Maximum number of concurrent clients. * @param _backlog Maximum number queued connections. - * @param _detail Implementation-specific detail associated with the service. + * @param _detail User-defined detail associated with the service. + * @param _res_fallback Fallback resource to be served if no other resource matches path */ -#define HTTP_SERVICE_DEFINE_EMPTY(_name, _host, _port, _concurrent, _backlog, _detail) \ - __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, NULL, NULL) +#define HTTP_SERVICE_DEFINE_EMPTY(_name, _host, _port, _concurrent, _backlog, _detail, \ + _res_fallback) \ + __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, \ + _res_fallback, NULL, NULL) /** * @brief Define an HTTPS service without static resources. @@ -137,13 +147,15 @@ struct http_service_desc { * @param[inout] _port Pointer to port associated with the service. * @param _concurrent Maximum number of concurrent clients. * @param _backlog Maximum number queued connections. - * @param _detail Implementation-specific detail associated with the service. + * @param _detail User-defined detail associated with the service. + * @param _res_fallback Fallback resource to be served if no other resource matches path * @param _sec_tag_list TLS security tag list used to setup a HTTPS socket. * @param _sec_tag_list_size TLS security tag list size used to setup a HTTPS socket. */ #define HTTPS_SERVICE_DEFINE_EMPTY(_name, _host, _port, _concurrent, _backlog, _detail, \ - _sec_tag_list, _sec_tag_list_size) \ - __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, NULL, NULL, \ + _res_fallback, _sec_tag_list, _sec_tag_list_size) \ + __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, \ + _res_fallback, NULL, NULL, \ _sec_tag_list, _sec_tag_list_size); \ BUILD_ASSERT(IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS), \ "TLS is required for HTTP secure (CONFIG_NET_SOCKETS_SOCKOPT_TLS)") @@ -165,12 +177,14 @@ struct http_service_desc { * @param[inout] _port Pointer to port associated with the service. * @param _concurrent Maximum number of concurrent clients. * @param _backlog Maximum number queued connections. - * @param _detail Implementation-specific detail associated with the service. + * @param _detail User-defined detail associated with the service. + * @param _res_fallback Fallback resource to be served if no other resource matches path */ -#define HTTP_SERVICE_DEFINE(_name, _host, _port, _concurrent, _backlog, _detail) \ +#define HTTP_SERVICE_DEFINE(_name, _host, _port, _concurrent, _backlog, _detail, _res_fallback) \ extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_start)[]; \ extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_end)[]; \ __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, \ + _res_fallback, \ &_CONCAT(_http_resource_desc_##_name, _list_start)[0], \ &_CONCAT(_http_resource_desc_##_name, _list_end)[0]) @@ -191,15 +205,17 @@ struct http_service_desc { * @param[inout] _port Pointer to port associated with the service. * @param _concurrent Maximum number of concurrent clients. * @param _backlog Maximum number queued connections. - * @param _detail Implementation-specific detail associated with the service. + * @param _detail User-defined detail associated with the service. + * @param _res_fallback Fallback resource to be served if no other resource matches path * @param _sec_tag_list TLS security tag list used to setup a HTTPS socket. * @param _sec_tag_list_size TLS security tag list size used to setup a HTTPS socket. */ #define HTTPS_SERVICE_DEFINE(_name, _host, _port, _concurrent, _backlog, _detail, \ - _sec_tag_list, _sec_tag_list_size) \ + _res_fallback, _sec_tag_list, _sec_tag_list_size) \ extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_start)[]; \ extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_end)[]; \ __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, \ + _res_fallback, \ &_CONCAT(_http_resource_desc_##_name, _list_start)[0], \ &_CONCAT(_http_resource_desc_##_name, _list_end)[0], \ _sec_tag_list, _sec_tag_list_size); \ diff --git a/include/zephyr/net/icmp.h b/include/zephyr/net/icmp.h index 9ada9880c8749..9cfcd38cc539a 100644 --- a/include/zephyr/net/icmp.h +++ b/include/zephyr/net/icmp.h @@ -191,6 +191,30 @@ int net_icmp_send_echo_request(struct net_icmp_ctx *ctx, struct net_icmp_ping_params *params, void *user_data); +/** + * @brief Send ICMP echo request message without waiting during send. + * + * @details This function can be used to send ICMP Echo-Request from a system + * workqueue handler which should not have any sleeps or waits. + * This variant will do the net_buf allocations with K_NO_WAIT. + * This will avoid a warning message in the log about the timeout. + * + * @param ctx ICMP context used in this request. + * @param iface Network interface, can be set to NULL in which case the + * interface is selected according to destination address. + * @param dst IP address of the target host. + * @param params Echo-Request specific parameters. May be NULL in which case + * suitable default parameters are used. + * @param user_data User supplied opaque data passed to the handler. May be NULL. + * + * @return Return 0 if the sending succeed, <0 otherwise. + */ +int net_icmp_send_echo_request_no_wait(struct net_icmp_ctx *ctx, + struct net_if *iface, + struct sockaddr *dst, + struct net_icmp_ping_params *params, + void *user_data); + /** * @brief ICMP offload context structure. */ diff --git a/include/zephyr/net/lldp.h b/include/zephyr/net/lldp.h index 0d638f2783e4f..2b447653712c6 100644 --- a/include/zephyr/net/lldp.h +++ b/include/zephyr/net/lldp.h @@ -225,16 +225,6 @@ typedef enum net_verdict (*net_lldp_recv_cb_t)(struct net_if *iface, */ int net_lldp_register_callback(struct net_if *iface, net_lldp_recv_cb_t cb); -/** - * @brief Parse LLDP packet - * - * @param iface Network interface - * @param pkt Network packet - * - * @return Return the policy for network buffer - */ -enum net_verdict net_lldp_recv(struct net_if *iface, struct net_pkt *pkt); - /** * @brief Set LLDP protocol data unit (LLDPDU) for the network interface. * diff --git a/include/zephyr/net/net_core.h b/include/zephyr/net/net_core.h index 4b07aaa3e94e6..7cd9a1cb15f0f 100644 --- a/include/zephyr/net/net_core.h +++ b/include/zephyr/net/net_core.h @@ -21,6 +21,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -154,6 +155,46 @@ int net_send_data(struct net_pkt *pkt); #define NET_TC_COUNT 0 #endif /* CONFIG_NET_TC_TX_COUNT && CONFIG_NET_TC_RX_COUNT */ +/** + * @brief Registration information for a given L3 handler. Note that + * the layer number (L3) just refers to something that is on top + * of L2. So for example IPv6 is L3 and IPv4 is L3, but Ethernet + * based LLDP, gPTP are more in the layer 2.5 but we consider them + * as L3 here for simplicity. + */ +struct net_l3_register { + /** Store also the name of the L3 type in order to be able to + * print it later. + */ + const char * const name; + /** What L2 layer this is for */ + const struct net_l2 * const l2; + /** Handler function for the specified protocol type. If the handler + * has taken ownership of the pkt, it must return NET_OK. If it wants to + * continue processing at the next level (e.g. ipv4), it must return + * NET_CONTINUE. If instead something is wrong with the packet (for + * example, a multicast address that does not match the protocol type) + * it must return NET_DROP so that the statistics can be updated + * accordingly + */ + enum net_verdict (*handler)(struct net_if *iface, + uint16_t ptype, + struct net_pkt *pkt); + /** Protocol type */ + uint16_t ptype; +}; + +#define NET_L3_GET_NAME(l3_name, ptype) __net_l3_register_##l3_name##_##ptype + +#define NET_L3_REGISTER(_l2_type, _name, _ptype, _handler) \ + static const STRUCT_SECTION_ITERABLE(net_l3_register, \ + NET_L3_GET_NAME(_name, _ptype)) = { \ + .ptype = _ptype, \ + .handler = _handler, \ + .name = STRINGIFY(_name), \ + .l2 = _l2_type, \ + }; + /* @endcond */ /** diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index be6fc28418b41..c8cbd4496aeda 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -136,7 +136,10 @@ struct net_if_addr { */ uint8_t is_temporary : 1; - uint8_t _unused : 4; + /** Was this address added or not */ + uint8_t is_added : 1; + + uint8_t _unused : 3; }; /** @@ -614,6 +617,12 @@ struct net_traffic_class { /** Fifo for handling this Tx or Rx packet */ struct k_fifo fifo; +#if NET_TC_COUNT > 1 || defined(CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO) \ + || defined(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO) + /** Semaphore for tracking the available slots in the fifo */ + struct k_sem fifo_slot; +#endif + /** Traffic class handler thread */ struct k_thread handler; @@ -786,8 +795,9 @@ static inline void net_if_tx_unlock(struct net_if *iface) static inline void net_if_flag_set(struct net_if *iface, enum net_if_flag value) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return; + } atomic_set_bit(iface->if_dev->flags, value); } @@ -803,8 +813,9 @@ static inline void net_if_flag_set(struct net_if *iface, static inline bool net_if_flag_test_and_set(struct net_if *iface, enum net_if_flag value) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return false; + } return atomic_test_and_set_bit(iface->if_dev->flags, value); } @@ -818,8 +829,9 @@ static inline bool net_if_flag_test_and_set(struct net_if *iface, static inline void net_if_flag_clear(struct net_if *iface, enum net_if_flag value) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return; + } atomic_clear_bit(iface->if_dev->flags, value); } @@ -835,8 +847,9 @@ static inline void net_if_flag_clear(struct net_if *iface, static inline bool net_if_flag_test_and_clear(struct net_if *iface, enum net_if_flag value) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return false; + } return atomic_test_and_clear_bit(iface->if_dev->flags, value); } @@ -852,10 +865,7 @@ static inline bool net_if_flag_test_and_clear(struct net_if *iface, static inline bool net_if_flag_is_set(struct net_if *iface, enum net_if_flag value) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); - - if (iface == NULL) { + if (iface == NULL || iface->if_dev == NULL) { return false; } @@ -873,8 +883,9 @@ static inline bool net_if_flag_is_set(struct net_if *iface, static inline enum net_if_oper_state net_if_oper_state_set( struct net_if *iface, enum net_if_oper_state oper_state) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return NET_IF_OPER_UNKNOWN; + } BUILD_ASSERT((enum net_if_oper_state)(-1) > 0 && NET_IF_OPER_UNKNOWN == 0); if (oper_state <= NET_IF_OPER_UP) { @@ -893,8 +904,9 @@ static inline enum net_if_oper_state net_if_oper_state_set( */ static inline enum net_if_oper_state net_if_oper_state(struct net_if *iface) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return NET_IF_OPER_UNKNOWN; + } return iface->if_dev->oper_state; } @@ -918,7 +930,7 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt); */ static inline const struct net_l2 *net_if_l2(struct net_if *iface) { - if (!iface || !iface->if_dev) { + if (iface == NULL || iface->if_dev == NULL) { return NULL; } @@ -944,8 +956,9 @@ enum net_verdict net_if_recv_data(struct net_if *iface, struct net_pkt *pkt); */ static inline void *net_if_l2_data(struct net_if *iface) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return NULL; + } return iface->if_dev->l2_data; } @@ -959,8 +972,9 @@ static inline void *net_if_l2_data(struct net_if *iface) */ static inline const struct device *net_if_get_device(struct net_if *iface) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return NULL; + } return iface->if_dev->dev; } @@ -1011,8 +1025,9 @@ bool net_if_is_offloaded(struct net_if *iface); static inline struct net_offload *net_if_offload(struct net_if *iface) { #if defined(CONFIG_NET_OFFLOAD) - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return NULL; + } return iface->if_dev->offload; #else @@ -1032,8 +1047,9 @@ static inline struct net_offload *net_if_offload(struct net_if *iface) static inline bool net_if_is_socket_offloaded(struct net_if *iface) { #if defined(CONFIG_NET_SOCKETS_OFFLOAD) - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return false; + } return (iface->if_dev->socket_offload != NULL); #else @@ -1053,8 +1069,9 @@ static inline void net_if_socket_offload_set( struct net_if *iface, net_socket_create_t socket_offload) { #if defined(CONFIG_NET_SOCKETS_OFFLOAD) - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return; + } iface->if_dev->socket_offload = socket_offload; #else @@ -1073,8 +1090,9 @@ static inline void net_if_socket_offload_set( static inline net_socket_create_t net_if_socket_offload(struct net_if *iface) { #if defined(CONFIG_NET_SOCKETS_OFFLOAD) - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return NULL; + } return iface->if_dev->socket_offload; #else @@ -1093,8 +1111,9 @@ static inline net_socket_create_t net_if_socket_offload(struct net_if *iface) */ static inline struct net_linkaddr *net_if_get_link_addr(struct net_if *iface) { - NET_ASSERT(iface); - NET_ASSERT(iface->if_dev); + if (iface == NULL || iface->if_dev == NULL) { + return NULL; + } return &iface->if_dev->link_addr; } @@ -1108,7 +1127,9 @@ static inline struct net_linkaddr *net_if_get_link_addr(struct net_if *iface) */ static inline struct net_if_config *net_if_get_config(struct net_if *iface) { - NET_ASSERT(iface); + if (iface == NULL) { + return NULL; + } return &iface->config; } @@ -1199,9 +1220,10 @@ int net_if_set_link_addr_locked(struct net_if *iface, extern int net_if_addr_unref_debug(struct net_if *iface, sa_family_t family, const void *addr, + struct net_if_addr **ifaddr, const char *caller, int line); -#define net_if_addr_unref(iface, family, addr) \ - net_if_addr_unref_debug(iface, family, addr, __func__, __LINE__) +#define net_if_addr_unref(iface, family, addr, ifaddr) \ + net_if_addr_unref_debug(iface, family, addr, ifaddr, __func__, __LINE__) extern struct net_if_addr *net_if_addr_ref_debug(struct net_if *iface, sa_family_t family, @@ -1213,7 +1235,8 @@ extern struct net_if_addr *net_if_addr_ref_debug(struct net_if *iface, #else extern int net_if_addr_unref(struct net_if *iface, sa_family_t family, - const void *addr); + const void *addr, + struct net_if_addr **ifaddr); extern struct net_if_addr *net_if_addr_ref(struct net_if *iface, sa_family_t family, const void *addr); @@ -1252,12 +1275,10 @@ static inline int net_if_set_link_addr(struct net_if *iface, */ static inline uint16_t net_if_get_mtu(struct net_if *iface) { - if (iface == NULL) { + if (iface == NULL || iface->if_dev == NULL) { return 0U; } - NET_ASSERT(iface->if_dev); - return iface->if_dev->mtu; } @@ -1270,12 +1291,10 @@ static inline uint16_t net_if_get_mtu(struct net_if *iface) static inline void net_if_set_mtu(struct net_if *iface, uint16_t mtu) { - if (iface == NULL) { + if (iface == NULL || iface->if_dev == NULL) { return; } - NET_ASSERT(iface->if_dev); - iface->if_dev->mtu = mtu; } @@ -1288,7 +1307,9 @@ static inline void net_if_set_mtu(struct net_if *iface, static inline void net_if_addr_set_lf(struct net_if_addr *ifaddr, bool is_infinite) { - NET_ASSERT(ifaddr); + if (ifaddr == NULL) { + return; + } ifaddr->is_infinite = is_infinite; } @@ -1320,7 +1341,9 @@ struct net_if *net_if_lookup_by_dev(const struct device *dev); */ static inline struct net_if_config *net_if_config_get(struct net_if *iface) { - NET_ASSERT(iface); + if (iface == NULL) { + return NULL; + } return &iface->config; } @@ -1651,7 +1674,9 @@ void net_if_ipv6_maddr_join(struct net_if *iface, */ static inline bool net_if_ipv6_maddr_is_joined(struct net_if_mcast_addr *addr) { - NET_ASSERT(addr); + if (addr == NULL) { + return false; + } return addr->is_joined; } @@ -1765,7 +1790,9 @@ bool net_if_ipv6_addr_onlink(struct net_if **iface, struct in6_addr *addr); #if defined(CONFIG_NET_NATIVE_IPV6) static inline struct in6_addr *net_if_router_ipv6(struct net_if_router *router) { - NET_ASSERT(router); + if (router == NULL) { + return NULL; + } return &router->address.in6_addr; } @@ -1932,7 +1959,9 @@ static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface, uint32_t reachable_time) { #if defined(CONFIG_NET_NATIVE_IPV6) - NET_ASSERT(iface); + if (iface == NULL) { + return; + } if (!iface->config.ip.ipv6) { return; @@ -1956,7 +1985,9 @@ static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface, static inline uint32_t net_if_ipv6_get_reachable_time(struct net_if *iface) { #if defined(CONFIG_NET_NATIVE_IPV6) - NET_ASSERT(iface); + if (iface == NULL) { + return 0; + } if (!iface->config.ip.ipv6) { return 0; @@ -2007,7 +2038,9 @@ static inline void net_if_ipv6_set_retrans_timer(struct net_if *iface, uint32_t retrans_timer) { #if defined(CONFIG_NET_NATIVE_IPV6) - NET_ASSERT(iface); + if (iface == NULL) { + return; + } if (!iface->config.ip.ipv6) { return; @@ -2030,7 +2063,9 @@ static inline void net_if_ipv6_set_retrans_timer(struct net_if *iface, static inline uint32_t net_if_ipv6_get_retrans_timer(struct net_if *iface) { #if defined(CONFIG_NET_NATIVE_IPV6) - NET_ASSERT(iface); + if (iface == NULL) { + return 0; + } if (!iface->config.ip.ipv6) { return 0; @@ -2367,7 +2402,9 @@ void net_if_ipv4_maddr_join(struct net_if *iface, */ static inline bool net_if_ipv4_maddr_is_joined(struct net_if_mcast_addr *addr) { - NET_ASSERT(addr); + if (addr == NULL) { + return false; + } return addr->is_joined; } @@ -2390,7 +2427,9 @@ void net_if_ipv4_maddr_leave(struct net_if *iface, #if defined(CONFIG_NET_NATIVE_IPV4) static inline struct in_addr *net_if_router_ipv4(struct net_if_router *router) { - NET_ASSERT(router); + if (router == NULL) { + return NULL; + } return &router->address.in_addr; } @@ -2837,7 +2876,9 @@ int net_if_up(struct net_if *iface); */ static inline bool net_if_is_up(struct net_if *iface) { - NET_ASSERT(iface); + if (iface == NULL) { + return false; + } return net_if_flag_is_set(iface, NET_IF_UP) && net_if_flag_is_set(iface, NET_IF_RUNNING); @@ -2861,7 +2902,9 @@ int net_if_down(struct net_if *iface); */ static inline bool net_if_is_admin_up(struct net_if *iface) { - NET_ASSERT(iface); + if (iface == NULL) { + return false; + } return net_if_flag_is_set(iface, NET_IF_UP); } @@ -2895,7 +2938,9 @@ void net_if_carrier_off(struct net_if *iface); */ static inline bool net_if_is_carrier_ok(struct net_if *iface) { - NET_ASSERT(iface); + if (iface == NULL) { + return false; + } return net_if_flag_is_set(iface, NET_IF_LOWER_UP); } @@ -2931,7 +2976,9 @@ void net_if_dormant_off(struct net_if *iface); */ static inline bool net_if_is_dormant(struct net_if *iface) { - NET_ASSERT(iface); + if (iface == NULL) { + return false; + } return net_if_flag_is_set(iface, NET_IF_DORMANT); } @@ -3233,7 +3280,7 @@ extern int net_stats_prometheus_scrape(struct prometheus_collector *collector, }; \ static Z_DECL_ALIGN(struct net_if) \ NET_IF_GET_NAME(dev_id, sfx)[_num_configs] \ - __used __in_section(_net_if, static, \ + __used __noasan __in_section(_net_if, static, \ dev_id) = { \ [0 ... (_num_configs - 1)] = { \ .if_dev = &(NET_IF_DEV_GET_NAME(dev_id, sfx)), \ diff --git a/include/zephyr/net/net_l2.h b/include/zephyr/net/net_l2.h index 37c9b083dd4d0..a7aa8530ee293 100644 --- a/include/zephyr/net/net_l2.h +++ b/include/zephyr/net/net_l2.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -79,6 +80,13 @@ struct net_l2 { * Return L2 flags for the network interface. */ enum net_l2_flags (*get_flags)(struct net_if *iface); + + /** + * Optional function for reserving L2 header space for this technology. + */ + int (*alloc)(struct net_if *iface, struct net_pkt *pkt, + size_t size, enum net_ip_protocol proto, + k_timeout_t timeout); }; /** @cond INTERNAL_HIDDEN */ @@ -121,13 +129,16 @@ NET_L2_DECLARE_PUBLIC(CANBUS_RAW_L2); NET_L2_DECLARE_PUBLIC(CUSTOM_IEEE802154_L2); #endif /* CONFIG_NET_L2_CUSTOM_IEEE802154 */ -#define NET_L2_INIT(_name, _recv_fn, _send_fn, _enable_fn, _get_flags_fn) \ +#define NET_L2_INIT(_name, _recv_fn, _send_fn, _enable_fn, _get_flags_fn, ...) \ const STRUCT_SECTION_ITERABLE(net_l2, \ NET_L2_GET_NAME(_name)) = { \ .recv = (_recv_fn), \ .send = (_send_fn), \ .enable = (_enable_fn), \ .get_flags = (_get_flags_fn), \ + .alloc = COND_CODE_0(NUM_VA_ARGS_LESS_1(LIST_DROP_EMPTY(__VA_ARGS__, _)), \ + (NULL), \ + (GET_ARG_N(1, __VA_ARGS__))), \ } #define NET_L2_GET_DATA(name, sfx) _net_l2_data_##name##sfx diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 1a3b4a042aeec..1fc59ffc0c043 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -1257,11 +1257,6 @@ static inline void net_pkt_set_stats_tick(struct net_pkt *pkt, uint32_t tick) #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL || CONFIG_NET_PKT_RXTIME_STATS_DETAIL */ -static inline size_t net_pkt_get_len(struct net_pkt *pkt) -{ - return net_buf_frags_len(pkt->frags); -} - static inline uint8_t *net_pkt_data(struct net_pkt *pkt) { return pkt->frags->data; @@ -1907,6 +1902,18 @@ struct net_pkt *net_pkt_rx_alloc_with_buffer_debug(struct net_if *iface, net_pkt_rx_alloc_with_buffer_debug(_iface, _size, _family, \ _proto, _timeout, \ __func__, __LINE__) + +int net_pkt_alloc_buffer_with_reserve_debug(struct net_pkt *pkt, + size_t size, + size_t reserve, + enum net_ip_protocol proto, + k_timeout_t timeout, + const char *caller, + int line); +#define net_pkt_alloc_buffer_with_reserve(_pkt, _size, _reserve, _proto, _timeout) \ + net_pkt_alloc_buffer_with_reserve_debug(_pkt, _size, _reserve, _proto, \ + _timeout, __func__, __LINE__) + #endif /* NET_PKT_DEBUG_ENABLED */ /** @endcond */ @@ -2001,6 +2008,31 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt, #endif #if !defined(NET_PKT_DEBUG_ENABLED) +/** + * @brief Allocate buffer for a net_pkt and reserve some space in the first net_buf. + * + * @details: such allocator will take into account space necessary for headers, + * MTU, and existing buffer (if any). Beware that, due to all these + * criteria, the allocated size might be smaller/bigger than + * requested one. + * + * @param pkt The network packet requiring buffer to be allocated. + * @param size The size of buffer being requested. + * @param reserve The L2 header size to reserve. This can be 0, in which case + * the L2 header is placed into a separate net_buf. + * @param proto The IP protocol type (can be 0 for none). + * @param timeout Maximum time to wait for an allocation. + * + * @return 0 on success, negative errno code otherwise. + */ +#if !defined(NET_PKT_DEBUG_ENABLED) +int net_pkt_alloc_buffer_with_reserve(struct net_pkt *pkt, + size_t size, + size_t reserve, + enum net_ip_protocol proto, + k_timeout_t timeout); +#endif + /** * @brief Allocate buffer for a net_pkt, of specified size, w/o any additional * preconditions @@ -2439,6 +2471,18 @@ static inline int net_pkt_write_le16(struct net_pkt *pkt, uint16_t data) */ size_t net_pkt_remaining_data(struct net_pkt *pkt); +/** + * @brief Get the total amount of bytes stored in a packet. + * + * @param pkt Network packet + * + * @return Total amount of bytes stored in a packet. + */ +static inline size_t net_pkt_get_len(struct net_pkt *pkt) +{ + return net_buf_frags_len(pkt->frags); +} + /** * @brief Update the overall length of a packet * diff --git a/include/zephyr/net/net_stats.h b/include/zephyr/net/net_stats.h index 5b28d9941abd8..740fe33895dff 100644 --- a/include/zephyr/net/net_stats.h +++ b/include/zephyr/net/net_stats.h @@ -328,6 +328,8 @@ struct net_stats_tc { #endif /** Number of packets sent for this traffic class */ net_stats_t pkts; + /** Number of packets dropped for this traffic class */ + net_stats_t dropped; /** Number of bytes sent for this traffic class */ net_stats_t bytes; /** Priority of this traffic class */ @@ -345,6 +347,8 @@ struct net_stats_tc { #endif /** Number of packets received for this traffic class */ net_stats_t pkts; + /** Number of packets dropped for this traffic class */ + net_stats_t dropped; /** Number of bytes received for this traffic class */ net_stats_t bytes; /** Priority of this traffic class */ diff --git a/include/zephyr/net/phy.h b/include/zephyr/net/phy.h index 0cffda13b0d44..697436e4c0272 100644 --- a/include/zephyr/net/phy.h +++ b/include/zephyr/net/phy.h @@ -31,21 +31,21 @@ extern "C" { /** @brief Ethernet link speeds. */ enum phy_link_speed { /** 10Base-T Half-Duplex */ - LINK_HALF_10BASE_T = BIT(0), + LINK_HALF_10BASE_T = BIT(0), /** 10Base-T Full-Duplex */ - LINK_FULL_10BASE_T = BIT(1), + LINK_FULL_10BASE_T = BIT(1), /** 100Base-T Half-Duplex */ - LINK_HALF_100BASE_T = BIT(2), + LINK_HALF_100BASE_T = BIT(2), /** 100Base-T Full-Duplex */ - LINK_FULL_100BASE_T = BIT(3), + LINK_FULL_100BASE_T = BIT(3), /** 1000Base-T Half-Duplex */ - LINK_HALF_1000BASE_T = BIT(4), + LINK_HALF_1000BASE_T = BIT(4), /** 1000Base-T Full-Duplex */ - LINK_FULL_1000BASE_T = BIT(5), + LINK_FULL_1000BASE_T = BIT(5), /** 2.5GBase-T Full-Duplex */ - LINK_FULL_2500BASE_T = BIT(6), + LINK_FULL_2500BASE_T = BIT(6), /** 5GBase-T Full-Duplex */ - LINK_FULL_5000BASE_T = BIT(7), + LINK_FULL_5000BASE_T = BIT(7), }; /** @@ -55,7 +55,7 @@ enum phy_link_speed { * * @return True if link is full duplex, false if not. */ -#define PHY_LINK_IS_FULL_DUPLEX(x) (x & (BIT(1) | BIT(3) | BIT(5) | BIT(6) | BIT(7))) +#define PHY_LINK_IS_FULL_DUPLEX(x) (x & (BIT(1) | BIT(3) | BIT(5) | BIT(6) | BIT(7))) /** * @brief Check if phy link speed is 1 Gbit/sec. @@ -64,7 +64,7 @@ enum phy_link_speed { * * @return True if link is 1 Gbit/sec, false if not. */ -#define PHY_LINK_IS_SPEED_1000M(x) (x & (BIT(4) | BIT(5))) +#define PHY_LINK_IS_SPEED_1000M(x) (x & (BIT(4) | BIT(5))) /** * @brief Check if phy link speed is 100 Mbit/sec. @@ -73,7 +73,7 @@ enum phy_link_speed { * * @return True if link is 1 Mbit/sec, false if not. */ -#define PHY_LINK_IS_SPEED_100M(x) (x & (BIT(2) | BIT(3))) +#define PHY_LINK_IS_SPEED_100M(x) (x & (BIT(2) | BIT(3))) /** @brief Link state */ struct phy_link_state { @@ -83,6 +83,63 @@ struct phy_link_state { bool is_up; }; +/** @brief PLCA (Physical Layer Collision Avoidance) Reconciliation Sublayer configurations */ +struct phy_plca_cfg { + /** PLCA register map version */ + uint8_t version; + /** PLCA configured mode (enable/disable) */ + bool enable; + /** PLCA local node identifier */ + uint8_t node_id; + /** PLCA node count */ + uint8_t node_count; + /** Additional frames a node is allowed to send in single transmit opportunity (TO) */ + uint8_t burst_count; + /** Wait time for the MAC to send a new frame before interrupting the burst */ + uint8_t burst_timer; + /** PLCA to_timer in bit-times, which determines the PLCA transmit opportunity */ + uint8_t to_timer; +}; + +/** + * @brief Write PHY PLCA configuration + * + * This routine provides a generic interface to configure PHY PLCA settings. + * + * @param[in] dev PHY device structure + * @param[in] plca_cfg Pointer to plca configuration structure + * + * @retval 0 If successful. + * @retval -EIO If communication with PHY failed. + */ +int genphy_get_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg); + +/** + * @brief Read PHY PLCA configuration + * + * This routine provides a generic interface to get PHY PLCA settings. + * + * @param[in] dev PHY device structure + * @param plca_cfg Pointer to plca configuration structure + * + * @retval 0 If successful. + * @retval -EIO If communication with PHY failed. + */ +int genphy_set_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg); + +/** + * @brief Read PHY PLCA status + * + * This routine provides a generic interface to get PHY PLCA status. + * + * @param[in] dev PHY device structure + * @param plca_status Pointer to plca status + * + * @retval 0 If successful. + * @retval -EIO If communication with PHY failed. + */ +int genphy_get_plca_sts(const struct device *dev, bool *plca_status); + /** * @typedef phy_callback_t * @brief Define the callback function signature for @@ -92,8 +149,7 @@ struct phy_link_state { * @param state Pointer to link_state structure. * @param user_data Pointer to data specified by user */ -typedef void (*phy_callback_t)(const struct device *dev, - struct phy_link_state *state, +typedef void (*phy_callback_t)(const struct device *dev, struct phy_link_state *state, void *user_data); /** @@ -104,24 +160,34 @@ typedef void (*phy_callback_t)(const struct device *dev, */ __subsystem struct ethphy_driver_api { /** Get link state */ - int (*get_link)(const struct device *dev, - struct phy_link_state *state); + int (*get_link)(const struct device *dev, struct phy_link_state *state); /** Configure link */ - int (*cfg_link)(const struct device *dev, - enum phy_link_speed adv_speeds); + int (*cfg_link)(const struct device *dev, enum phy_link_speed adv_speeds); /** Set callback to be invoked when link state changes. */ - int (*link_cb_set)(const struct device *dev, phy_callback_t cb, - void *user_data); + int (*link_cb_set)(const struct device *dev, phy_callback_t cb, void *user_data); /** Read PHY register */ - int (*read)(const struct device *dev, uint16_t reg_addr, - uint32_t *data); + int (*read)(const struct device *dev, uint16_t reg_addr, uint32_t *data); /** Write PHY register */ - int (*write)(const struct device *dev, uint16_t reg_addr, - uint32_t data); + int (*write)(const struct device *dev, uint16_t reg_addr, uint32_t data); + + /** Read PHY C45 register */ + int (*read_c45)(const struct device *dev, uint8_t devad, uint16_t regad, uint16_t *data); + + /** Write PHY C45 register */ + int (*write_c45)(const struct device *dev, uint8_t devad, uint16_t regad, uint16_t data); + + /* Set PLCA settings */ + int (*set_plca_cfg)(const struct device *dev, struct phy_plca_cfg *plca_cfg); + + /* Get PLCA settings */ + int (*get_plca_cfg)(const struct device *dev, struct phy_plca_cfg *plca_cfg); + + /* Get PLCA status */ + int (*get_plca_sts)(const struct device *dev, bool *plca_sts); }; /** * @endcond @@ -139,11 +205,9 @@ __subsystem struct ethphy_driver_api { * @retval -EIO If communication with PHY failed. * @retval -ENOTSUP If not supported. */ -static inline int phy_configure_link(const struct device *dev, - enum phy_link_speed speeds) +static inline int phy_configure_link(const struct device *dev, enum phy_link_speed speeds) { - const struct ethphy_driver_api *api = - (const struct ethphy_driver_api *)dev->api; + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; return api->cfg_link(dev, speeds); } @@ -161,11 +225,9 @@ static inline int phy_configure_link(const struct device *dev, * @retval 0 If successful. * @retval -EIO If communication with PHY failed. */ -static inline int phy_get_link_state(const struct device *dev, - struct phy_link_state *state) +static inline int phy_get_link_state(const struct device *dev, struct phy_link_state *state) { - const struct ethphy_driver_api *api = - (const struct ethphy_driver_api *)dev->api; + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; return api->get_link(dev, state); } @@ -184,12 +246,10 @@ static inline int phy_get_link_state(const struct device *dev, * @retval 0 If successful. * @retval -ENOTSUP If not supported. */ -static inline int phy_link_callback_set(const struct device *dev, - phy_callback_t callback, +static inline int phy_link_callback_set(const struct device *dev, phy_callback_t callback, void *user_data) { - const struct ethphy_driver_api *api = - (const struct ethphy_driver_api *)dev->api; + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; return api->link_cb_set(dev, callback, user_data); } @@ -206,11 +266,9 @@ static inline int phy_link_callback_set(const struct device *dev, * @retval 0 If successful. * @retval -EIO If communication with PHY failed. */ -static inline int phy_read(const struct device *dev, uint16_t reg_addr, - uint32_t *value) +static inline int phy_read(const struct device *dev, uint16_t reg_addr, uint32_t *value) { - const struct ethphy_driver_api *api = - (const struct ethphy_driver_api *)dev->api; + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; return api->read(dev, reg_addr, value); } @@ -227,15 +285,108 @@ static inline int phy_read(const struct device *dev, uint16_t reg_addr, * @retval 0 If successful. * @retval -EIO If communication with PHY failed. */ -static inline int phy_write(const struct device *dev, uint16_t reg_addr, - uint32_t value) +static inline int phy_write(const struct device *dev, uint16_t reg_addr, uint32_t value) { - const struct ethphy_driver_api *api = - (const struct ethphy_driver_api *)dev->api; + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; return api->write(dev, reg_addr, value); } +/** + * @brief Read PHY C45 register + * + * This routine provides a generic interface to read to a PHY C45 register. + * + * @param[in] dev PHY device structure + * @param[in] devad Device address + * @param[in] regad Register address + * @param data Pointer to receive read data + * + * @retval 0 If successful. + * @retval -EIO If communication with PHY failed. + */ +static inline int phy_read_c45(const struct device *dev, uint8_t devad, uint16_t regad, + uint16_t *data) +{ + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; + + return api->read_c45(dev, devad, regad, data); +} + +/** + * @brief Write PHY C45 register + * + * This routine provides a generic interface to write to a PHY C45 register. + * + * @param[in] dev PHY device structure + * @param[in] devad Device address + * @param[in] regad Register address + * @param[in] data Data to write + * + * @retval 0 If successful. + * @retval -EIO If communication with PHY failed. + */ +static inline int phy_write_c45(const struct device *dev, uint8_t devad, uint16_t regad, + uint16_t data) +{ + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; + + return api->write_c45(dev, devad, regad, data); +} + +/** + * @brief Write PHY PLCA configuration + * + * This routine provides a generic interface to configure PHY PLCA settings. + * + * @param[in] dev PHY device structure + * @param[in] plca_cfg Pointer to plca configuration structure + * + * @retval 0 If successful. + * @retval -EIO If communication with PHY failed. + */ +static inline int phy_set_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg) +{ + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; + + return api->set_plca_cfg(dev, plca_cfg); +} + +/** + * @brief Read PHY PLCA configuration + * + * This routine provides a generic interface to get PHY PLCA settings. + * + * @param[in] dev PHY device structure + * @param plca_cfg Pointer to plca configuration structure + * + * @retval 0 If successful. + * @retval -EIO If communication with PHY failed. + */ +static inline int phy_get_plca_cfg(const struct device *dev, struct phy_plca_cfg *plca_cfg) +{ + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; + + return api->get_plca_cfg(dev, plca_cfg); +} + +/** + * @brief Read PHY PLCA status + * + * This routine provides a generic interface to get PHY PLCA status. + * + * @param[in] dev PHY device structure + * @param plca_status Pointer to plca status + * + * @retval 0 If successful. + * @retval -EIO If communication with PHY failed. + */ +static inline int phy_get_plca_sts(const struct device *dev, bool *plca_status) +{ + const struct ethphy_driver_api *api = (const struct ethphy_driver_api *)dev->api; + + return api->get_plca_sts(dev, plca_status); +} #ifdef __cplusplus } diff --git a/include/zephyr/net/tls_credentials.h b/include/zephyr/net/tls_credentials.h index 6477543f40420..2804df061018e 100644 --- a/include/zephyr/net/tls_credentials.h +++ b/include/zephyr/net/tls_credentials.h @@ -107,6 +107,7 @@ int tls_credential_add(sec_tag_t tag, enum tls_credential_type type, * @retval -EACCES Access to the TLS credential subsystem was denied. * @retval -ENOENT Requested TLS credential was not found. * @retval -EFBIG Requested TLS credential does not fit in the buffer provided. + * Check *credlen for size required. */ int tls_credential_get(sec_tag_t tag, enum tls_credential_type type, void *cred, size_t *credlen); diff --git a/include/zephyr/net/trickle.h b/include/zephyr/net/trickle.h index 98d4de8314145..9bd3e09fc7f61 100644 --- a/include/zephyr/net/trickle.h +++ b/include/zephyr/net/trickle.h @@ -136,7 +136,9 @@ void net_trickle_inconsistency(struct net_trickle *trickle); */ static inline bool net_trickle_is_running(struct net_trickle *trickle) { - NET_ASSERT(trickle); + if (trickle == NULL) { + return false; + } return trickle->I != 0U; } diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index c64ee6acac9ed..2bfa737547ad4 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -76,8 +76,6 @@ enum wifi_security_type { WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2, /** EAP PEAP security - Enterprise. */ WIFI_SECURITY_TYPE_EAP_PEAP_TLS, - /** EAP TLS SHA256 security - Enterprise. */ - WIFI_SECURITY_TYPE_EAP_TLS_SHA256, /** FT-PSK security */ WIFI_SECURITY_TYPE_FT_PSK, /** FT-SAE security */ @@ -86,6 +84,8 @@ enum wifi_security_type { WIFI_SECURITY_TYPE_FT_EAP, /** FT-EAP-SHA384 security */ WIFI_SECURITY_TYPE_FT_EAP_SHA384, + /** SAE Extended key (uses group-dependent hashing) */ + WIFI_SECURITY_TYPE_SAE_EXT_KEY, /** @cond INTERNAL_HIDDEN */ __WIFI_SECURITY_TYPE_AFTER_LAST, @@ -110,12 +110,35 @@ enum wifi_eap_type { WIFI_EAP_TYPE_MSCHAPV2 = 26, }; -/** @brief Enterprise security WPA3 suiteb types. */ -enum wifi_suiteb_type { - /** suiteb. */ - WIFI_SUITEB = 1, - /** suiteb-192. */ - WIFI_SUITEB_192, +/** @brief WPA3 Enterprise security types. + * + * See Section#3 in WFA WPA3 specification v3.4: + * https://www.wi-fi.org/file/wpa3-specification for details. + */ +enum wifi_wpa3_enterprise_type { + /** No WPA3 enterprise, either WPA2 Enterprise or personal mode */ + WIFI_WPA3_ENTERPRISE_NA = 0, + /** WPA3 enterprise Suite-B (PMFR + WPA3-Suite-B). */ + WIFI_WPA3_ENTERPRISE_SUITEB = 1, + /** WPA3 enterprise Suite-B-192 (PMFR + WPA3-Suite-B-192). */ + WIFI_WPA3_ENTERPRISE_SUITEB_192, + /** WPA3 enterprise only (PMFR + WPA2-ENT disabled). */ + WIFI_WPA3_ENTERPRISE_ONLY, + + /** @cond INTERNAL_HIDDEN */ + __WIFI_WPA3_ENTERPRISE_AFTER_LAST, + WIFI_WPA3_ENTERPRISE_MAX = __WIFI_WPA3_ENTERPRISE_AFTER_LAST - 1, + WIFI_WPA3_ENTERPRISE_UNKNOWN + /** @endcond */ +}; + +enum wifi_eap_tls_cipher_type { + /** EAP TLS with NONE */ + WIFI_EAP_TLS_NONE, + /** EAP TLS with ECDH & ECDSA with p384 */ + WIFI_EAP_TLS_ECC_P384, + /** EAP TLS with ECDH & RSA with > 3K */ + WIFI_EAP_TLS_RSA_3K, }; /** @brief Group cipher and pairwise cipher types. */ @@ -168,12 +191,12 @@ struct wifi_eap_cipher_config { struct wifi_eap_config { /** Security type. */ - unsigned int type; - /** EPA method type of phase1. */ + enum wifi_security_type type; + /** EAP method type of phase1. */ enum wifi_eap_type eap_type_phase1; - /** EPA method type of phase2. */ + /** EAP method type of phase2. */ enum wifi_eap_type eap_type_phase2; - /** EPA method string. */ + /** EAP method string. */ char *method; /** Phase2 setting string. */ char *phase2; @@ -182,6 +205,9 @@ struct wifi_eap_config { /** Helper function to get user-friendly security type name. */ const char *wifi_security_txt(enum wifi_security_type security); +/** Helper function to get user-friendly wpa3 enterprise security type name. */ +const char *wifi_wpa3_enterprise_txt(enum wifi_wpa3_enterprise_type wpa3_ent); + /** @brief IEEE 802.11w - Management frame protection. */ enum wifi_mfp_options { /** MFP disabled. */ @@ -223,6 +249,27 @@ enum wifi_frequency_bands { /** Helper function to get user-friendly frequency band name. */ const char *wifi_band_txt(enum wifi_frequency_bands band); +/** + * @brief IEEE 802.11 operational frequency bandwidths (not exhaustive). + */ +enum wifi_frequency_bandwidths { + /** 20 MHz. */ + WIFI_FREQ_BANDWIDTH_20MHZ = 1, + /** 40 MHz. */ + WIFI_FREQ_BANDWIDTH_40MHZ, + /** 80 MHz. */ + WIFI_FREQ_BANDWIDTH_80MHZ, + + /** Number of frequency bandwidths available. */ + __WIFI_FREQ_BANDWIDTH_AFTER_LAST, + /** Highest frequency bandwidth available. */ + WIFI_FREQ_BANDWIDTH_MAX = __WIFI_FREQ_BANDWIDTH_AFTER_LAST - 1, + /** Invalid frequency bandwidth */ + WIFI_FREQ_BANDWIDTH_UNKNOWN +}; + +const char *const wifi_bandwidth_txt(enum wifi_frequency_bandwidths bandwidth); + /** Max SSID length */ #define WIFI_SSID_MAX_LEN 32 /** Minimum PSK length */ @@ -586,7 +633,7 @@ enum wifi_ps_exit_strategy { }; /** Helper function to get user-friendly ps exit strategy name. */ -const char * const wifi_ps_exit_strategy_txt(enum wifi_ps_exit_strategy ps_exit_strategy); +const char *wifi_ps_exit_strategy_txt(enum wifi_ps_exit_strategy ps_exit_strategy); /** @brief Wi-Fi power save error codes. */ enum wifi_config_ps_param_fail_reason { @@ -625,7 +672,6 @@ static const char * const wifi_ps_param_config_err_code_tbl[] = { }; /** @endcond */ -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM /** IEEE 802.11v BTM (BSS transition management) Query reasons. * Refer to IEEE Std 802.11v-2011 - Table 7-43x-Transition and Transition Query reasons table. */ @@ -637,7 +683,6 @@ enum wifi_btm_query_reason { /** Leaving ESS. */ WIFI_BTM_QUERY_REASON_LEAVING_ESS = 20, }; -#endif /** Helper function to get user-friendly power save error code name. */ static inline const char *wifi_ps_get_config_err_code_str(int16_t err_no) @@ -655,6 +700,12 @@ enum wifi_ap_config_param { WIFI_AP_CONFIG_PARAM_MAX_INACTIVITY = BIT(0), /** Used for AP mode configuration parameter max_num_sta */ WIFI_AP_CONFIG_PARAM_MAX_NUM_STA = BIT(1), + /** Used for AP mode configuration parameter bandwidth */ + WIFI_AP_CONFIG_PARAM_BANDWIDTH = BIT(2), + /** Used for AP mode configuration parameter ht_capab */ + WIFI_AP_CONFIG_PARAM_HT_CAPAB = BIT(3), + /** Used for AP mode configuration parameter vht_capab */ + WIFI_AP_CONFIG_PARAM_VHT_CAPAB = BIT(4), }; #ifdef __cplusplus diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 398afea8d8c91..a467f0a8b38e1 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -75,6 +75,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_AP_ENABLE, /** Disable AP mode */ NET_REQUEST_WIFI_CMD_AP_DISABLE, + /** Set AP RTS threshold */ + NET_REQUEST_WIFI_CMD_AP_RTS_THRESHOLD, /** Get interface status */ NET_REQUEST_WIFI_CMD_IFACE_STATUS, /** Set or get 11k status */ @@ -85,6 +87,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_PS, /** Setup or teardown TWT flow */ NET_REQUEST_WIFI_CMD_TWT, + /** Setup BTWT flow */ + NET_REQUEST_WIFI_CMD_BTWT, /** Get power save config */ NET_REQUEST_WIFI_CMD_PS_CONFIG, /** Set or get regulatory domain */ @@ -107,10 +111,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_AP_CONFIG_PARAM, /** DPP actions */ NET_REQUEST_WIFI_CMD_DPP, -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM /** BSS transition management query */ NET_REQUEST_WIFI_CMD_BTM_QUERY, -#endif /** Flush PMKSA cache entries */ NET_REQUEST_WIFI_CMD_PMKSA_FLUSH, /** Set enterprise mode credential */ @@ -166,6 +168,12 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_ENABLE); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE); +/** Request a Wi-Fi RTS threshold */ +#define NET_REQUEST_WIFI_AP_RTS_THRESHOLD \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_AP_RTS_THRESHOLD) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_RTS_THRESHOLD); + /** Request a Wi-Fi network interface status */ #define NET_REQUEST_WIFI_IFACE_STATUS \ (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_IFACE_STATUS) @@ -194,6 +202,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PS); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT); +#define NET_REQUEST_WIFI_BTWT \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_BTWT) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BTWT); + /** Request a Wi-Fi power save configuration */ #define NET_REQUEST_WIFI_PS_CONFIG \ (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_PS_CONFIG) @@ -262,12 +275,10 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_CONFIG_PARAM); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_DPP); #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */ -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM /** Request a Wi-Fi BTM query */ #define NET_REQUEST_WIFI_BTM_QUERY (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_BTM_QUERY) NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BTM_QUERY); -#endif /** Request a Wi-Fi PMKSA cache entries flush */ #define NET_REQUEST_WIFI_PMKSA_FLUSH \ @@ -490,6 +501,8 @@ struct wifi_scan_result { uint8_t channel; /** Security type */ enum wifi_security_type security; + /** WPA3 enterprise type */ + enum wifi_wpa3_enterprise_type wpa3_ent_type; /** MFP options */ enum wifi_mfp_options mfp; /** RSSI */ @@ -538,8 +551,10 @@ struct wifi_connect_req_params { const uint8_t *key2_passwd; /** key2 passwd length, max 128 */ uint8_t key2_passwd_length; - /** suiteb or suiteb-192 */ - uint8_t suiteb_type; + /** wpa3 enterprise mode */ + enum wifi_wpa3_enterprise_type wpa3_ent_mode; + /** TLS cipher */ + uint8_t TLS_cipher; /** eap version */ int eap_ver; /** Identity for EAP */ @@ -550,6 +565,8 @@ struct wifi_connect_req_params { const uint8_t *eap_password; /** eap passwd length, max 128 */ uint8_t eap_passwd_length; + /** Whether verify peer with CA or not: false-not verify, true-verify. */ + bool verify_peer_cert; /** Fast BSS Transition used */ bool ft_used; /** Number of EAP users */ @@ -566,6 +583,8 @@ struct wifi_connect_req_params { * 2: clear SSID, but keep the original length and ignore probe request for broadcast SSID */ uint8_t ignore_broadcast_ssid; + /** Parameter used for frequency band */ + enum wifi_frequency_bandwidths bandwidth; }; /** @brief Wi-Fi connect result codes. To be overlaid on top of \ref wifi_status @@ -665,6 +684,8 @@ struct wifi_iface_status { enum wifi_iface_mode iface_mode; /** Link mode, see enum wifi_link_mode */ enum wifi_link_mode link_mode; + /** WPA3 enterprise type */ + enum wifi_wpa3_enterprise_type wpa3_ent_type; /** Security type, see enum wifi_security_type */ enum wifi_security_type security; /** MFP options, see enum wifi_mfp_options */ @@ -677,7 +698,7 @@ struct wifi_iface_status { unsigned short beacon_interval; /** is TWT capable? */ bool twt_capable; - /** The current 802.11 PHY TX data rate (in Kbps) */ + /** The current 802.11 PHY TX data rate (in Mbps) */ int current_phy_tx_rate; }; @@ -745,7 +766,30 @@ struct wifi_twt_params { * prepare the data before TWT SP starts. */ uint32_t twt_wake_ahead_duration; + /** TWT info enabled or disable */ + bool twt_info_disable; + /** TWT exponent */ + uint8_t twt_exponent; + /** TWT Mantissa Range: [0-sizeof(UINT16)] */ + uint16_t twt_mantissa; } setup; + /** Setup specific parameters */ + struct { + /** Broadcast TWT AP config */ + uint16_t sub_id; + /** Range 64-255 */ + uint8_t nominal_wake; + /** Max STA support */ + uint8_t max_sta_support; + /** TWT mantissa */ + uint16_t twt_mantissa; + /** TWT offset */ + uint16_t twt_offset; + /** TWT exponent */ + uint8_t twt_exponent; + /** SP gap */ + uint8_t sp_gap; + } btwt; /** Teardown specific parameters */ struct { /** Teardown all flows */ @@ -764,6 +808,7 @@ struct wifi_twt_params { /* 256 (u8) * 1TU */ #define WIFI_MAX_TWT_WAKE_INTERVAL_US 262144 #define WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US (LONG_MAX - 1) +#define WIFI_MAX_TWT_EXPONENT 31 /** @endcond */ @@ -976,6 +1021,7 @@ struct wifi_channel_info { /** @cond INTERNAL_HIDDEN */ #define WIFI_AP_STA_MAX_INACTIVITY (LONG_MAX - 1) +#define WIFI_AP_IEEE_80211_CAPAB_MAX_LEN 64 /** @endcond */ /** @brief Wi-Fi AP configuration parameter */ @@ -986,6 +1032,14 @@ struct wifi_ap_config_params { uint32_t max_inactivity; /** Parameter used for setting maximum number of stations */ uint32_t max_num_sta; + /** Parameter used for frequency band */ + enum wifi_frequency_bandwidths bandwidth; +#if defined(CONFIG_WIFI_NM_HOSTAPD_AP) + /** Parameter used for setting HT capabilities */ + char ht_capab[WIFI_AP_IEEE_80211_CAPAB_MAX_LEN + 1]; + /** Parameter used for setting VHT capabilities */ + char vht_capab[WIFI_AP_IEEE_80211_CAPAB_MAX_LEN + 1]; +#endif }; #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP @@ -1206,14 +1260,24 @@ struct wifi_wps_config_params { /** Wi-Fi AP status */ -enum wifi_hostapd_iface_state { - WIFI_HAPD_IFACE_UNINITIALIZED, - WIFI_HAPD_IFACE_DISABLED, - WIFI_HAPD_IFACE_COUNTRY_UPDATE, - WIFI_HAPD_IFACE_ACS, - WIFI_HAPD_IFACE_HT_SCAN, - WIFI_HAPD_IFACE_DFS, - WIFI_HAPD_IFACE_ENABLED +enum wifi_sap_iface_state { + WIFI_SAP_IFACE_UNINITIALIZED, + WIFI_SAP_IFACE_DISABLED, + WIFI_SAP_IFACE_COUNTRY_UPDATE, + WIFI_SAP_IFACE_ACS, + WIFI_SAP_IFACE_HT_SCAN, + WIFI_SAP_IFACE_DFS, + WIFI_SAP_IFACE_NO_IR, + WIFI_SAP_IFACE_ENABLED +}; + +/* Extended Capabilities */ +enum wifi_ext_capab { + WIFI_EXT_CAPAB_20_40_COEX = 0, + WIFI_EXT_CAPAB_GLK = 1, + WIFI_EXT_CAPAB_EXT_CHAN_SWITCH = 2, + WIFI_EXT_CAPAB_TIM_BROADCAST = 18, + WIFI_EXT_CAPAB_BSS_TRANSITION = 19, }; #include @@ -1351,6 +1415,14 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*set_twt)(const struct device *dev, struct wifi_twt_params *params); + /** Setup BTWT flow + * + * @param dev Pointer to the device structure for the driver instance. + * @param params BTWT parameters + * + * @return 0 if ok, < 0 if error + */ + int (*set_btwt)(const struct device *dev, struct wifi_twt_params *params); /** Get power save config * * @param dev Pointer to the device structure for the driver instance. @@ -1391,7 +1463,7 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*channel)(const struct device *dev, struct wifi_channel_info *channel); -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM + /** Send BTM query * * @param dev Pointer to the device structure for the driver instance. @@ -1400,7 +1472,23 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*btm_query)(const struct device *dev, uint8_t reason); -#endif + /** Judge ap whether support the capability + * + * @param dev Pointer to the device structure for the driver instance. + * @param capab is the capability to judge + * + * @return 1 if support, 0 if not support + */ + int (*bss_ext_capab)(const struct device *dev, int capab); + + /** Send legacy scan + * + * @param dev Pointer to the device structure for the driver instance. + * + * @return 0 if ok, < 0 if error + */ + int (*legacy_roam)(const struct device *dev); + /** Get Version of WiFi driver and Firmware * * The driver that implements the get_version function must not use stack to allocate the diff --git a/include/zephyr/net_buf.h b/include/zephyr/net_buf.h index 02c041e9dcaec..c349147afd77c 100644 --- a/include/zephyr/net_buf.h +++ b/include/zephyr/net_buf.h @@ -1098,6 +1098,9 @@ struct net_buf_pool { /** Total size of the pool. */ const uint16_t pool_size; + /** Maximum count of used buffers. */ + uint16_t max_used; + /** Name of the pool. Used when printing pool information. */ const char *name; #endif /* CONFIG_NET_BUF_POOL_USAGE */ @@ -1115,6 +1118,7 @@ struct net_buf_pool { /** @cond INTERNAL_HIDDEN */ #define NET_BUF_POOL_USAGE_INIT(_pool, _count) \ IF_ENABLED(CONFIG_NET_BUF_POOL_USAGE, (.avail_count = ATOMIC_INIT(_count),)) \ + IF_ENABLED(CONFIG_NET_BUF_POOL_USAGE, (.max_used = 0,)) \ IF_ENABLED(CONFIG_NET_BUF_POOL_USAGE, (.name = STRINGIFY(_pool),)) #define NET_BUF_POOL_INITIALIZER(_pool, _alloc, _bufs, _count, _ud_size, _destroy) \ @@ -1325,19 +1329,14 @@ int net_buf_id(const struct net_buf *buf); /** * @brief Allocate a new fixed buffer from a pool. * - * @note Some types of data allocators do not support - * blocking (such as the HEAP type). In this case it's still possible - * for net_buf_alloc() to fail (return NULL) even if it was given - * K_FOREVER. - * - * @note The timeout value will be overridden to K_NO_WAIT if called from the - * system workqueue. - * * @param pool Which pool to allocate the buffer from. * @param timeout Affects the action taken should the pool be empty. * If K_NO_WAIT, then return immediately. If K_FOREVER, then * wait as long as necessary. Otherwise, wait until the specified - * timeout. + * timeout. Note that some types of data allocators do not support + * blocking (such as the HEAP type). In this case it's still possible + * for net_buf_alloc() to fail (return NULL) even if it was given + * K_FOREVER. * * @return New buffer or NULL if out of buffers. */ @@ -1365,20 +1364,15 @@ static inline struct net_buf * __must_check net_buf_alloc(struct net_buf_pool *p /** * @brief Allocate a new variable length buffer from a pool. * - * @note Some types of data allocators do not support - * blocking (such as the HEAP type). In this case it's still possible - * for net_buf_alloc() to fail (return NULL) even if it was given - * K_FOREVER. - * - * @note The timeout value will be overridden to K_NO_WAIT if called from the - * system workqueue. - * * @param pool Which pool to allocate the buffer from. * @param size Amount of data the buffer must be able to fit. * @param timeout Affects the action taken should the pool be empty. * If K_NO_WAIT, then return immediately. If K_FOREVER, then * wait as long as necessary. Otherwise, wait until the specified - * timeout. + * timeout. Note that some types of data allocators do not support + * blocking (such as the HEAP type). In this case it's still possible + * for net_buf_alloc() to fail (return NULL) even if it was given + * K_FOREVER. * * @return New buffer or NULL if out of buffers. */ @@ -1402,21 +1396,16 @@ struct net_buf * __must_check net_buf_alloc_len(struct net_buf_pool *pool, * Allocate a new buffer from a pool, where the data pointer comes from the * user and not from the pool. * - * @note Some types of data allocators do not support - * blocking (such as the HEAP type). In this case it's still possible - * for net_buf_alloc() to fail (return NULL) even if it was given - * K_FOREVER. - * - * @note The timeout value will be overridden to K_NO_WAIT if called from the - * system workqueue. - * * @param pool Which pool to allocate the buffer from. * @param data External data pointer * @param size Amount of data the pointed data buffer if able to fit. * @param timeout Affects the action taken should the pool be empty. * If K_NO_WAIT, then return immediately. If K_FOREVER, then * wait as long as necessary. Otherwise, wait until the specified - * timeout. + * timeout. Note that some types of data allocators do not support + * blocking (such as the HEAP type). In this case it's still possible + * for net_buf_alloc() to fail (return NULL) even if it was given + * K_FOREVER. * * @return New buffer or NULL if out of buffers. */ diff --git a/include/zephyr/pm/pm.h b/include/zephyr/pm/pm.h index e1fb695415c16..443f5e37d8bd3 100644 --- a/include/zephyr/pm/pm.h +++ b/include/zephyr/pm/pm.h @@ -135,11 +135,6 @@ const struct pm_state_info *pm_state_next_get(uint8_t cpu); */ void pm_system_resume(void); - -/** @cond INTERNAL_HIDDEN */ -__deprecated void z_pm_save_idle_exit(void); -/** @endcond */ - /** * @} */ @@ -199,9 +194,6 @@ static inline const struct pm_state_info *pm_state_next_get(uint8_t cpu) return NULL; } -static inline void z_pm_save_idle_exit(void) -{ -} static inline void pm_system_resume(void) { diff --git a/include/zephyr/pm/policy.h b/include/zephyr/pm/policy.h index e1e910f3e0a53..057488d722d86 100644 --- a/include/zephyr/pm/policy.h +++ b/include/zephyr/pm/policy.h @@ -67,7 +67,7 @@ struct pm_policy_latency_request { struct pm_policy_event { /** @cond INTERNAL_HIDDEN */ sys_snode_t node; - uint32_t value_cyc; + int64_t uptime_ticks; /** @endcond */ }; @@ -137,7 +137,6 @@ void pm_policy_state_lock_put(enum pm_state state, uint8_t substate_id); */ bool pm_policy_state_lock_is_active(enum pm_state state, uint8_t substate_id); - /** * @brief Register an event. * @@ -145,30 +144,31 @@ bool pm_policy_state_lock_is_active(enum pm_state state, uint8_t substate_id); * will wake up the system at a known time in the future. By registering such * event, the policy manager will be able to decide whether certain power states * are worth entering or not. - * CPU is woken up before the time passed in cycle to prevent the event handling - * latency * - * @note It is mandatory to unregister events once they have happened by using - * pm_policy_event_unregister(). Not doing so is an API contract violation, - * because the system would continue to consider them as valid events in the - * *far* future, that is, after the cycle counter rollover. + * CPU is woken up before the time passed in cycle to minimize event handling + * latency. Once woken up, the CPU will be kept awake until the event has been + * handled, which is signaled by pm_policy_event_unregister() or moving event + * into the future using pm_policy_event_update(). * * @param evt Event. - * @param cycle When the event will occur, in absolute time (cycles). + * @param uptime_ticks When the event will occur, in uptime ticks. * - * @see pm_policy_event_unregister + * @see pm_policy_event_unregister() */ -void pm_policy_event_register(struct pm_policy_event *evt, uint32_t cycle); +void pm_policy_event_register(struct pm_policy_event *evt, int64_t uptime_ticks); /** * @brief Update an event. * + * This shortcut allows for moving the time an event will occur without the + * need for an unregister + register cycle. + * * @param evt Event. - * @param cycle When the event will occur, in absolute time (cycles). + * @param uptime_ticks When the event will occur, in uptime ticks. * * @see pm_policy_event_register */ -void pm_policy_event_update(struct pm_policy_event *evt, uint32_t cycle); +void pm_policy_event_update(struct pm_policy_event *evt, int64_t uptime_ticks); /** * @brief Unregister an event. @@ -208,10 +208,14 @@ void pm_policy_device_power_lock_put(const struct device *dev); /** * @brief Returns the ticks until the next event * - * If an event is registred, it will return the number of ticks until the next event as - * a positive or zero value. Otherwise it returns -1 + * If an event is registred, it will return the number of ticks until the next event, if the + * "next"/"oldest" registered event is in the past, it will return 0. Otherwise it returns -1. + * + * @retval >0 If next registered event is in the future + * @retval 0 If next registered event is now or in the past + * @retval -1 Otherwise */ -int32_t pm_policy_next_event_ticks(void); +int64_t pm_policy_next_event_ticks(void); #else static inline void pm_policy_state_lock_get(enum pm_state state, uint8_t substate_id) @@ -261,7 +265,7 @@ static inline void pm_policy_device_power_lock_put(const struct device *dev) ARG_UNUSED(dev); } -static inline int32_t pm_policy_next_event_ticks(void) +static inline int64_t pm_policy_next_event_ticks(void) { return -1; } diff --git a/include/zephyr/portability/cmsis_types.h b/include/zephyr/portability/cmsis_types.h new file mode 100644 index 0000000000000..cb73a50ffa36b --- /dev/null +++ b/include/zephyr/portability/cmsis_types.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_CMSIS_TYPES_H_ +#define ZEPHYR_INCLUDE_CMSIS_TYPES_H_ + +#include +#include +#include + +/** @brief Size for names of RTOS objects. */ +#define CMSIS_OBJ_NAME_MAX_LEN 16 + +/** + * @brief Control block for a CMSIS-RTOSv2 thread. + * + * Application can use manual user-defined allocation for RTOS objects by supplying a pointer to + * thread control block. Control block is initiazed within `osThreadNew()`. + */ +struct cmsis_rtos_thread_cb { + sys_dnode_t node; + struct k_thread z_thread; + struct k_poll_signal poll_signal; + struct k_poll_event poll_event; + uint32_t signal_results; + char name[CMSIS_OBJ_NAME_MAX_LEN]; + uint32_t attr_bits; + struct k_sem join_guard; + char has_joined; +}; + +/** + * @brief Control block for a CMSIS-RTOSv2 timer. + * + * Application can use manual user-defined allocation for RTOS objects by supplying a pointer to + * timer control block. Control block is initiazed within `osTimerNew()`. + */ +struct cmsis_rtos_timer_cb { + struct k_timer z_timer; + osTimerType_t type; + uint32_t status; + bool is_cb_dynamic_allocation; + char name[CMSIS_OBJ_NAME_MAX_LEN]; + void (*callback_function)(void *argument); + void *arg; +}; + +/** + * @brief Control block for a CMSIS-RTOSv2 mutex. + * + * Application can use manual user-defined allocation for RTOS objects by supplying a pointer to + * mutex control block. Control block is initiazed within `osMutexNew()`. + */ +struct cmsis_rtos_mutex_cb { + struct k_mutex z_mutex; + bool is_cb_dynamic_allocation; + char name[CMSIS_OBJ_NAME_MAX_LEN]; + uint32_t state; +}; + +/** + * @brief Control block for a CMSIS-RTOSv2 semaphore. + * + * Application can use manual user-defined allocation for RTOS objects by supplying a pointer to + * semaphore control block. Control block is initiazed within `osSemaphoreNew()`. + */ +struct cmsis_rtos_semaphore_cb { + struct k_sem z_semaphore; + bool is_cb_dynamic_allocation; + char name[CMSIS_OBJ_NAME_MAX_LEN]; +}; + +/** + * @brief Control block for a CMSIS-RTOSv2 memory pool. + * + * Application can use manual user-defined allocation for RTOS objects by supplying a pointer to + * memory pool control block. Control block is initiazed within `osMemoryPoolNew()`. + */ +struct cmsis_rtos_mempool_cb { + struct k_mem_slab z_mslab; + void *pool; + char is_dynamic_allocation; + bool is_cb_dynamic_allocation; + char name[CMSIS_OBJ_NAME_MAX_LEN]; +}; + +/** + * @brief Control block for a CMSIS-RTOSv2 message queue. + * + * Application can use manual user-defined allocation for RTOS objects by supplying a pointer to + * message queue control block. Control block is initiazed within `osMessageQueueNew()`. + */ +struct cmsis_rtos_msgq_cb { + struct k_msgq z_msgq; + void *pool; + char is_dynamic_allocation; + bool is_cb_dynamic_allocation; + char name[CMSIS_OBJ_NAME_MAX_LEN]; +}; + +/** + * @brief Control block for a CMSIS-RTOSv2 event flag. + * + * Application can use manual user-defined allocation for RTOS objects by supplying a pointer to + * event flag control block. Control block is initiazed within `osEventFlagsNew()`. + */ +struct cmsis_rtos_event_cb { + struct k_poll_signal poll_signal; + struct k_poll_event poll_event; + uint32_t signal_results; + bool is_cb_dynamic_allocation; + char name[CMSIS_OBJ_NAME_MAX_LEN]; +}; + +#endif diff --git a/include/zephyr/posix/dirent.h b/include/zephyr/posix/dirent.h index 0ffe875606f01..b4327ac45f936 100644 --- a/include/zephyr/posix/dirent.h +++ b/include/zephyr/posix/dirent.h @@ -1,40 +1,46 @@ /* * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2024 Tenstorrent AI ULC * * SPDX-License-Identifier: Apache-2.0 */ + #ifndef ZEPHYR_INCLUDE_POSIX_DIRENT_H_ #define ZEPHYR_INCLUDE_POSIX_DIRENT_H_ -#include - -#include - -#ifdef CONFIG_POSIX_FILE_SYSTEM -#include +#include +#include #ifdef __cplusplus extern "C" { #endif -typedef void DIR; - -struct dirent { - unsigned int d_ino; - char d_name[PATH_MAX + 1]; -}; - -/* Directory related operations */ -DIR *opendir(const char *dirname); +#if (_POSIX_C_SOURCE >= 200809L) || (_XOPEN_SOURCE >= 700) +int alphasort(const struct dirent **d1, const struct dirent **d2); +#endif int closedir(DIR *dirp); +#if (_POSIX_C_SOURCE >= 200809L) || (_XOPEN_SOURCE >= 700) +int dirfd(DIR *dirp); +#endif +DIR *fdopendir(int fd); +DIR *opendir(const char *dirname); struct dirent *readdir(DIR *dirp); +#if (_POSIX_C_SOURCE >= 199506L) || (_XOPEN_SOURCE >= 500) int readdir_r(DIR *ZRESTRICT dirp, struct dirent *ZRESTRICT entry, struct dirent **ZRESTRICT result); +#endif +void rewinddir(DIR *dirp); +#if (_POSIX_C_SOURCE >= 200809L) || (_XOPEN_SOURCE >= 700) +int scandir(const char *dir, struct dirent ***namelist, int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)); +#endif +#if defined(_XOPEN_SOURCE) +void seekdir(DIR *dirp, long loc); +long telldir(DIR *dirp); +#endif #ifdef __cplusplus } #endif -#endif /* CONFIG_POSIX_FILE_SYSTEM */ - -#endif /* ZEPHYR_INCLUDE_POSIX_DIRENT_H_ */ +#endif /* ZEPHYR_INCLUDE_POSIX_DIRENT_H_ */ diff --git a/include/zephyr/posix/fcntl.h b/include/zephyr/posix/fcntl.h index 24ed17765861f..599e96f22452a 100644 --- a/include/zephyr/posix/fcntl.h +++ b/include/zephyr/posix/fcntl.h @@ -7,28 +7,23 @@ #ifndef ZEPHYR_POSIX_FCNTL_H_ #define ZEPHYR_POSIX_FCNTL_H_ -#ifdef CONFIG_PICOLIBC -#define O_CREAT 0x0040 -#define O_TRUNC 0x0200 -#define O_APPEND 0x0400 -#else -#define O_CREAT 0x0200 -#define O_TRUNC 0x0400 -#define O_APPEND 0x0008 -#endif +#include -#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) +#define O_APPEND ZVFS_O_APPEND +#define O_CREAT ZVFS_O_CREAT +#define O_EXCL ZVFS_O_EXCL +#define O_NONBLOCK ZVFS_O_NONBLOCK +#define O_TRUNC ZVFS_O_TRUNC -#define O_RDONLY 00 -#define O_WRONLY 01 -#define O_RDWR 02 +#define O_ACCMODE (ZVFS_O_RDONLY | ZVFS_O_RDWR | ZVFS_O_WRONLY) -#define O_EXCL 0x0800 -#define O_NONBLOCK 0x4000 +#define O_RDONLY ZVFS_O_RDONLY +#define O_RDWR ZVFS_O_RDWR +#define O_WRONLY ZVFS_O_WRONLY -#define F_DUPFD 0 -#define F_GETFL 3 -#define F_SETFL 4 +#define F_DUPFD ZVFS_F_DUPFD +#define F_GETFL ZVFS_F_GETFL +#define F_SETFL ZVFS_F_SETFL #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/posix/poll.h b/include/zephyr/posix/poll.h index 4aeebeed176fe..aa2c89210dd5a 100644 --- a/include/zephyr/posix/poll.h +++ b/include/zephyr/posix/poll.h @@ -12,9 +12,12 @@ extern "C" { #endif +typedef unsigned int nfds_t; + #define pollfd zsock_pollfd #define POLLIN ZSOCK_POLLIN +#define POLLPRI ZSOCK_POLLPRI #define POLLOUT ZSOCK_POLLOUT #define POLLERR ZSOCK_POLLERR #define POLLHUP ZSOCK_POLLHUP diff --git a/include/zephyr/posix/posix_features.h b/include/zephyr/posix/posix_features.h index e4a91c6fc92ce..099484555bc2f 100644 --- a/include/zephyr/posix/posix_features.h +++ b/include/zephyr/posix/posix_features.h @@ -27,6 +27,11 @@ #define _POSIX_AEP_REALTIME_DEDICATED 200312L #endif +/* + * Subprofiling Considerations + */ +#define _POSIX_SUBPROFILE 1 + /* * POSIX System Interfaces */ @@ -201,9 +206,9 @@ /* * POSIX2 Options */ -#define _POSIX2_VERSION _POSIX_VERSION -#define _POSIX2_C_BIND _POSIX2_VERSION -#define _POSIX2_C_DEV _POSIX2_VERSION +/* #define _POSIX2_VERSION (-1) */ +#define _POSIX2_C_BIND _POSIX_VERSION +/* #define _POSIX2_C_DEV (-1) */ /* #define _POSIX2_CHAR_TERM (-1L) */ /* #define _POSIX2_FORT_DEV (-1L) */ /* #define _POSIX2_FORT_RUN (-1L) */ @@ -223,7 +228,13 @@ #define _XOPEN_VERSION 700 /* #define _XOPEN_CRYPT (-1L) */ /* #define _XOPEN_ENH_I18N (-1L) */ -/* #define _XOPEN_REALTIME (-1L) */ +#if defined(CONFIG_XSI_REALTIME) || \ + (defined(CONFIG_POSIX_FSYNC) && defined(CONFIG_POSIX_MEMLOCK) && \ + defined(CONFIG_POSIX_MEMLOCK_RANGE) && defined(CONFIG_POSIX_MESSAGE_PASSING) && \ + defined(CONFIG_POSIX_PRIORITY_SCHEDULING) && \ + defined(CONFIG_POSIX_SHARED_MEMORY_OBJECTS) && defined(CONFIG_POSIX_SYNCHRONIZED_IO)) +#define _XOPEN_REALTIME _XOPEN_VERSION +#endif /* #define _XOPEN_REALTIME_THREADS (-1L) */ /* #define _XOPEN_SHM (-1L) */ diff --git a/include/zephyr/posix/pthread.h b/include/zephyr/posix/pthread.h index 4a5e7046f17d6..685a8d9a9316e 100644 --- a/include/zephyr/posix/pthread.h +++ b/include/zephyr/posix/pthread.h @@ -429,6 +429,8 @@ int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); int pthread_once(pthread_once_t *once, void (*initFunc)(void)); #endif FUNC_NORETURN void pthread_exit(void *retval); +int pthread_timedjoin_np(pthread_t thread, void **status, const struct timespec *abstime); +int pthread_tryjoin_np(pthread_t thread, void **status); int pthread_join(pthread_t thread, void **status); int pthread_cancel(pthread_t pthread); int pthread_detach(pthread_t thread); diff --git a/include/zephyr/posix/signal.h b/include/zephyr/posix/signal.h index e106642f6f1a7..38c3be378ca90 100644 --- a/include/zephyr/posix/signal.h +++ b/include/zephyr/posix/signal.h @@ -122,7 +122,9 @@ unsigned int alarm(unsigned int seconds); int kill(pid_t pid, int sig); int pause(void); int raise(int signo); +TOOLCHAIN_IGNORE_WSHADOW_BEGIN; int sigaction(int sig, const struct sigaction *ZRESTRICT act, struct sigaction *ZRESTRICT oact); +TOOLCHAIN_IGNORE_WSHADOW_END; int sigpending(sigset_t *set); int sigsuspend(const sigset_t *sigmask); int sigwait(const sigset_t *ZRESTRICT set, int *ZRESTRICT signo); diff --git a/include/zephyr/posix/sys/dirent.h b/include/zephyr/posix/sys/dirent.h new file mode 100644 index 0000000000000..63d02dc511edc --- /dev/null +++ b/include/zephyr/posix/sys/dirent.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Tenstorrent AI ULC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_POSIX_SYS_DIRENT_H_ +#define ZEPHYR_INCLUDE_POSIX_SYS_DIRENT_H_ + +#include + +#include + +#if !defined(NAME_MAX) && defined(_XOPEN_SOURCE) +#define NAME_MAX _XOPEN_NAME_MAX +#endif + +#if !defined(NAME_MAX) && defined(_POSIX_C_SOURCE) +#define NAME_MAX _POSIX_NAME_MAX +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void DIR; + +struct dirent { + unsigned int d_ino; + char d_name[NAME_MAX + 1]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_POSIX_SYS_DIRENT_H_ */ diff --git a/include/zephyr/posix/sys/sysconf.h b/include/zephyr/posix/sys/sysconf.h index c7d8228a8cddb..67bf84bfb7558 100644 --- a/include/zephyr/posix/sys/sysconf.h +++ b/include/zephyr/posix/sys/sysconf.h @@ -233,7 +233,8 @@ enum { #define __z_posix_sysconf_SC_BC_SCALE_MAX _POSIX2_BC_SCALE_MAX #define __z_posix_sysconf_SC_BC_STRING_MAX _POSIX2_BC_STRING_MAX #define __z_posix_sysconf_SC_2_C_BIND _POSIX2_C_BIND -#define __z_posix_sysconf_SC_2_C_DEV _POSIX2_C_DEV +#define __z_posix_sysconf_SC_2_C_DEV \ + COND_CODE_1(_POSIX2_C_DEV > 0, (_POSIX2_C_DEV), (-1)) #define __z_posix_sysconf_SC_2_CHAR_TERM (-1L) #define __z_posix_sysconf_SC_COLL_WEIGHTS_MAX _POSIX2_COLL_WEIGHTS_MAX #define __z_posix_sysconf_SC_DELAYTIMER_MAX _POSIX_DELAYTIMER_MAX @@ -250,7 +251,8 @@ enum { #define __z_posix_sysconf_SC_2_PBS_TRACK (-1L) #define __z_posix_sysconf_SC_2_SW_DEV (-1L) #define __z_posix_sysconf_SC_2_UPE (-1L) -#define __z_posix_sysconf_SC_2_VERSION _POSIX2_VERSION +#define __z_posix_sysconf_SC_2_VERSION \ + COND_CODE_1(_POSIX2_VERSION > 0, (_POSIX2_VERSION), (-1)) #define __z_posix_sysconf_SC_XOPEN_CRYPT (-1L) #define __z_posix_sysconf_SC_XOPEN_ENH_I18N (-1L) #define __z_posix_sysconf_SC_XOPEN_REALTIME (-1L) diff --git a/include/zephyr/psa/key_ids.h b/include/zephyr/psa/key_ids.h new file mode 100644 index 0000000000000..851d1349812d5 --- /dev/null +++ b/include/zephyr/psa/key_ids.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2025 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_PSA_KEY_IDS_H_ +#define ZEPHYR_PSA_KEY_IDS_H_ + +/** + * @file zephyr/psa/key_ids.h + * + * @brief This file defines the key ID ranges of the existing users of the PSA Crypto API. + * + * In addition to the application, different subsystems store and use persistent keys through the + * PSA Crypto API. Because they are not aware of each other, collisions are avoided by having them + * use different ID ranges. + * This file acts as the registry of all the allocated PSA key ID ranges within Zephyr. + * + * The end-user application also has a dedicated range, `ZEPHYR_PSA_APPLICATION_KEY_ID_RANGE_BEGIN`. + * + * Some of the IDs below are based on previously existing and used values, while others + * are chosen to be somewhere in the PSA user key ID range to try to avoid collisions + * (avoiding, for example, the very beginning of the range). + */ + +#include +typedef uint32_t psa_key_id_t; + +/** PSA key ID range to be used by OpenThread. The base ID is equal to the default value upstream: + * https://github.com/openthread/openthread/blob/thread-reference-20230706/src/core/config/platform.h#L138 + */ +#define ZEPHYR_PSA_OPENTHREAD_KEY_ID_RANGE_BEGIN (psa_key_id_t)0x20000 +#define ZEPHYR_PSA_OPENTHREAD_KEY_ID_RANGE_SIZE 0x10000 /* 64 Ki */ + +/** PSA key ID range to be used by Matter. The base ID is equal to the default value upstream: + * https://github.com/project-chip/connectedhomeip/blob/v1.4.0.0/src/crypto/CHIPCryptoPALPSA.h#L55 + */ +#define ZEPHYR_PSA_MATTER_KEY_ID_RANGE_BEGIN (psa_key_id_t)0x30000 +#define ZEPHYR_PSA_MATTER_KEY_ID_RANGE_SIZE 0x10000 /* 64 Ki */ + +/** PSA key ID range to be used by Bluetooth Mesh. */ +#define ZEPHYR_PSA_BT_MESH_KEY_ID_RANGE_BEGIN (psa_key_id_t)0x20000000 +#define ZEPHYR_PSA_BT_MESH_KEY_ID_RANGE_SIZE 0xC000 /* 48 Ki */ + +/** PSA key ID range to be used by Wi-Fi credentials management. */ +#define ZEPHYR_PSA_WIFI_CREDENTIALS_KEY_ID_RANGE_BEGIN (psa_key_id_t)0x20010000 +#define ZEPHYR_PSA_WIFI_CREDENTIALS_KEY_ID_RANGE_SIZE 0x100 /* 256 */ + +/** PSA key ID range to be used by the end-user application. */ +#define ZEPHYR_PSA_APPLICATION_KEY_ID_RANGE_BEGIN (psa_key_id_t)0x30000000 +#define ZEPHYR_PSA_APPLICATION_KEY_ID_RANGE_SIZE 0x100000 /* 1 Mi */ + +#endif /* ZEPHYR_PSA_KEY_IDS_H_ */ diff --git a/include/zephyr/rtio/rtio.h b/include/zephyr/rtio/rtio.h index 228211a494871..ce5355aa52ecc 100644 --- a/include/zephyr/rtio/rtio.h +++ b/include/zephyr/rtio/rtio.h @@ -207,6 +207,60 @@ extern "C" { */ #define RTIO_IODEV_I2C_10_BITS BIT(3) +/** + * @brief Equivalent to the I3C_MSG_STOP flag + */ +#define RTIO_IODEV_I3C_STOP BIT(1) + +/** + * @brief Equivalent to the I3C_MSG_RESTART flag + */ +#define RTIO_IODEV_I3C_RESTART BIT(2) + +/** + * @brief Equivalent to the I3C_MSG_HDR + */ +#define RTIO_IODEV_I3C_HDR BIT(3) + +/** + * @brief Equivalent to the I3C_MSG_NBCH + */ +#define RTIO_IODEV_I3C_NBCH BIT(4) + +/** + * @brief I3C HDR Mode Mask + */ +#define RTIO_IODEV_I3C_HDR_MODE_MASK GENMASK(15, 8) + +/** + * @brief I3C HDR Mode Mask + */ +#define RTIO_IODEV_I3C_HDR_MODE_SET(flags) \ + FIELD_PREP(RTIO_IODEV_I3C_HDR_MODE_MASK, flags) + +/** + * @brief I3C HDR Mode Mask + */ +#define RTIO_IODEV_I3C_HDR_MODE_GET(flags) \ + FIELD_GET(RTIO_IODEV_I3C_HDR_MODE_MASK, flags) + +/** + * @brief I3C HDR 7b Command Code + */ +#define RTIO_IODEV_I3C_HDR_CMD_CODE_MASK GENMASK(22, 16) + +/** + * @brief I3C HDR 7b Command Code + */ +#define RTIO_IODEV_I3C_HDR_CMD_CODE_SET(flags) \ + FIELD_PREP(RTIO_IODEV_I3C_HDR_CMD_CODE_MASK, flags) + +/** + * @brief I3C HDR 7b Command Code + */ +#define RTIO_IODEV_I3C_HDR_CMD_CODE_GET(flags) \ + FIELD_GET(RTIO_IODEV_I3C_HDR_CMD_CODE_MASK, flags) + /** @cond ignore */ struct rtio; struct rtio_cqe; @@ -236,9 +290,7 @@ struct rtio_sqe { uint16_t flags; /**< Op Flags */ - uint16_t iodev_flags; /**< Op iodev flags */ - - uint16_t _resv0; + uint32_t iodev_flags; /**< Op iodev flags */ const struct rtio_iodev *iodev; /**< Device to operation on */ @@ -286,6 +338,17 @@ struct rtio_sqe { /** OP_I2C_CONFIGURE */ uint32_t i2c_config; + + /** OP_I3C_CONFIGURE */ + struct { + /* enum i3c_config_type type; */ + int type; + void *config; + } i3c_config; + + /** OP_I3C_CCC */ + /* struct i3c_ccc_payload *ccc_payload; */ + void *ccc_payload; }; }; @@ -483,6 +546,15 @@ struct rtio_iodev { /** An operation to configure I2C buses */ #define RTIO_OP_I2C_CONFIGURE (RTIO_OP_I2C_RECOVER+1) +/** An operation to recover I3C buses */ +#define RTIO_OP_I3C_RECOVER (RTIO_OP_I2C_CONFIGURE+1) + +/** An operation to configure I3C buses */ +#define RTIO_OP_I3C_CONFIGURE (RTIO_OP_I3C_RECOVER+1) + +/** An operation to sends I3C CCC */ +#define RTIO_OP_I3C_CCC (RTIO_OP_I3C_CONFIGURE+1) + /** * @brief Prepare a nop (no op) submission */ @@ -1065,10 +1137,14 @@ static inline uint32_t rtio_cqe_compute_flags(struct rtio_iodev_sqe *iodev_sqe) if (iodev_sqe->sqe.op == RTIO_OP_RX && iodev_sqe->sqe.flags & RTIO_SQE_MEMPOOL_BUFFER) { struct rtio *r = iodev_sqe->r; struct sys_mem_blocks *mem_pool = r->block_pool; - int blk_index = (iodev_sqe->sqe.rx.buf - mem_pool->buffer) >> - mem_pool->info.blk_sz_shift; - int blk_count = iodev_sqe->sqe.rx.buf_len >> mem_pool->info.blk_sz_shift; + unsigned int blk_index = 0; + unsigned int blk_count = 0; + if (iodev_sqe->sqe.rx.buf) { + blk_index = (iodev_sqe->sqe.rx.buf - mem_pool->buffer) >> + mem_pool->info.blk_sz_shift; + blk_count = iodev_sqe->sqe.rx.buf_len >> mem_pool->info.blk_sz_shift; + } flags = RTIO_CQE_FLAG_PREP_MEMPOOL(blk_index, blk_count); } #else @@ -1101,15 +1177,21 @@ static inline int z_impl_rtio_cqe_get_mempool_buffer(const struct rtio *r, struc { #ifdef CONFIG_RTIO_SYS_MEM_BLOCKS if (RTIO_CQE_FLAG_GET(cqe->flags) == RTIO_CQE_FLAG_MEMPOOL_BUFFER) { - int blk_idx = RTIO_CQE_FLAG_MEMPOOL_GET_BLK_IDX(cqe->flags); - int blk_count = RTIO_CQE_FLAG_MEMPOOL_GET_BLK_CNT(cqe->flags); + unsigned int blk_idx = RTIO_CQE_FLAG_MEMPOOL_GET_BLK_IDX(cqe->flags); + unsigned int blk_count = RTIO_CQE_FLAG_MEMPOOL_GET_BLK_CNT(cqe->flags); uint32_t blk_size = rtio_mempool_block_size(r); - *buff = r->block_pool->buffer + blk_idx * blk_size; *buff_len = blk_count * blk_size; - __ASSERT_NO_MSG(*buff >= r->block_pool->buffer); - __ASSERT_NO_MSG(*buff < + + if (blk_count > 0) { + *buff = r->block_pool->buffer + blk_idx * blk_size; + + __ASSERT_NO_MSG(*buff >= r->block_pool->buffer); + __ASSERT_NO_MSG(*buff < r->block_pool->buffer + blk_size * r->block_pool->info.num_blocks); + } else { + *buff = NULL; + } return 0; } return -EINVAL; @@ -1177,7 +1259,16 @@ static inline void rtio_cqe_submit(struct rtio *r, int result, void *userdata, u rtio_cqe_produce(r, cqe); } - atomic_inc(&r->cq_count); + /* atomic_t isn't guaranteed to wrap correctly as it could be signed, so + * we must resort to a cas loop. + */ + atomic_t val, new_val; + + do { + val = atomic_get(&r->cq_count); + new_val = (atomic_t)((uintptr_t)val + 1); + } while (!atomic_cas(&r->cq_count, val, new_val)); + #ifdef CONFIG_RTIO_SUBMIT_SEM if (r->submit_count > 0) { r->submit_count--; @@ -1428,6 +1519,8 @@ static inline int z_impl_rtio_cqe_copy_out(struct rtio *r, * submission chain, freeing submission queue events when done, and * producing completion queue events as submissions are completed. * + * @warning It is undefined behavior to have re-entrant calls to submit + * * @param r RTIO context * @param wait_count Number of submissions to wait for completion of. * @@ -1435,13 +1528,11 @@ static inline int z_impl_rtio_cqe_copy_out(struct rtio *r, */ __syscall int rtio_submit(struct rtio *r, uint32_t wait_count); +#ifdef CONFIG_RTIO_SUBMIT_SEM static inline int z_impl_rtio_submit(struct rtio *r, uint32_t wait_count) { int res = 0; -#ifdef CONFIG_RTIO_SUBMIT_SEM - /* TODO undefined behavior if another thread calls submit of course - */ if (wait_count > 0) { __ASSERT(!k_is_in_isr(), "expected rtio submit with wait count to be called from a thread"); @@ -1449,35 +1540,43 @@ static inline int z_impl_rtio_submit(struct rtio *r, uint32_t wait_count) k_sem_reset(r->submit_sem); r->submit_count = wait_count; } -#else - uintptr_t cq_count = (uintptr_t)atomic_get(&r->cq_count) + wait_count; -#endif - /* Submit the queue to the executor which consumes submissions - * and produces completions through ISR chains or other means. - */ rtio_executor_submit(r); - - /* TODO could be nicer if we could suspend the thread and not - * wake up on each completion here. - */ -#ifdef CONFIG_RTIO_SUBMIT_SEM - if (wait_count > 0) { res = k_sem_take(r->submit_sem, K_FOREVER); __ASSERT(res == 0, "semaphore was reset or timed out while waiting on completions!"); } + + return res; +} #else - while ((uintptr_t)atomic_get(&r->cq_count) < cq_count) { +static inline int z_impl_rtio_submit(struct rtio *r, uint32_t wait_count) +{ + + int res = 0; + uintptr_t cq_count = (uintptr_t)atomic_get(&r->cq_count); + uintptr_t cq_complete_count = cq_count + wait_count; + bool wraps = cq_complete_count < cq_count; + + rtio_executor_submit(r); + + if (wraps) { + while ((uintptr_t)atomic_get(&r->cq_count) >= cq_count) { + Z_SPIN_DELAY(10); + k_yield(); + } + } + + while ((uintptr_t)atomic_get(&r->cq_count) < cq_complete_count) { Z_SPIN_DELAY(10); k_yield(); } -#endif return res; } +#endif /* CONFIG_RTIO_SUBMIT_SEM */ /** * @} diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index e2a40b853286a..5115e35339be8 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -159,6 +159,28 @@ typedef bool (*shell_device_filter_t)(const struct device *dev); const struct device *shell_device_filter(size_t idx, shell_device_filter_t filter); +/** + * @brief Get a @ref device reference from its @ref device.name field or label. + * + * This function iterates through the devices on the system. If a device with + * the given @p name field is found, and that device initialized successfully at + * boot time, this function returns a pointer to the device. + * + * If no device has the given @p name, this function returns `NULL`. + * + * This function also returns NULL when a device is found, but it failed to + * initialize successfully at boot time. (To troubleshoot this case, set a + * breakpoint on your device driver's initialization function.) + * + * @param name device name to search for. A null pointer, or a pointer to an + * empty string, will cause NULL to be returned. + * + * @return pointer to device structure with the given name; `NULL` if the device + * is not found or if the device with that name's initialization function + * failed. + */ +const struct device *shell_device_get_binding(const char *name); + /** * @brief Shell command handler prototype. * @@ -930,7 +952,7 @@ extern void z_shell_print_stream(const void *user_ctx, const char *data, static struct shell_ctx UTIL_CAT(_name, _ctx); \ Z_SHELL_HISTORY_DEFINE(_name##_history, CONFIG_SHELL_HISTORY_BUFFER); \ Z_SHELL_FPRINTF_DEFINE(_name##_fprintf, &_name, _out_buf, CONFIG_SHELL_PRINTF_BUFF_SIZE, \ - true, z_shell_print_stream); \ + IS_ENABLED(CONFIG_SHELL_PRINTF_AUTOFLUSH), z_shell_print_stream); \ LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL); \ Z_SHELL_STATS_DEFINE(_name); \ static K_KERNEL_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE); \ diff --git a/include/zephyr/shell/shell_websocket.h b/include/zephyr/shell/shell_websocket.h index 12bd49727a249..dd93e6913bae2 100644 --- a/include/zephyr/shell/shell_websocket.h +++ b/include/zephyr/shell/shell_websocket.h @@ -62,8 +62,8 @@ struct shell_websocket { }; extern const struct shell_transport_api shell_websocket_transport_api; -extern int shell_websocket_setup(int ws_socket, void *user_data); -extern int shell_websocket_enable(const struct shell *sh); +int shell_websocket_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data); +int shell_websocket_enable(const struct shell *sh); #define GET_WS_NAME(_service) ws_ctx_##_service #define GET_WS_SHELL_NAME(_name) shell_websocket_##_name @@ -121,6 +121,7 @@ extern int shell_websocket_enable(const struct shell *sh); SHELL_WEBSOCKET_SERVICE_COUNT, \ SHELL_WEBSOCKET_SERVICE_COUNT, \ NULL, \ + NULL, \ _sec_tag_list, \ _sec_tag_list_size); \ DEFINE_WEBSOCKET_SERVICE(_service); \ @@ -136,7 +137,7 @@ extern int shell_websocket_enable(const struct shell *sh); &SHELL_WS_PORT_NAME(_service), \ SHELL_WEBSOCKET_SERVICE_COUNT, \ SHELL_WEBSOCKET_SERVICE_COUNT, \ - NULL); \ + NULL, NULL); \ DEFINE_WEBSOCKET_SERVICE(_service) #endif /* CONFIG_NET_SOCKETS_SOCKOPT_TLS */ diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index cdd9ae0075900..a0d528acfb78d 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -242,9 +242,9 @@ uint32_t flash_area_align(const struct flash_area *fa); * Retrieve info about sectors within the area. * * @param[in] fa_id Given flash area ID - * @param[out] sectors buffer for sectors data * @param[in,out] count On input Capacity of @p sectors, on output number of * sectors Retrieved. + * @param[out] sectors buffer for sectors data * * @return 0 on success, negative errno code on fail. Especially returns * -ENOMEM if There are too many flash pages on the flash_area to fit in the @@ -257,9 +257,9 @@ int flash_area_get_sectors(int fa_id, uint32_t *count, * Retrieve info about sectors within the area. * * @param[in] fa pointer to flash area object. - * @param[out] sectors buffer for sectors data * @param[in,out] count On input Capacity of @p sectors, on output number of * sectors retrieved. + * @param[out] sectors buffer for sectors data * * @return 0 on success, negative errno code on fail. Especially returns * -ENOMEM if There are too many flash pages on the flash_area to fit in the @@ -419,11 +419,21 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); * @return Pointer to flash_area type object representing partition */ #define FIXED_PARTITION(label) FIXED_PARTITION_1(DT_NODELABEL(label)) + +/** + * Get pointer to flash_area object by partition node in DTS + * + * @param node DTS node of a partition + * + * @return Pointer to flash_area type object representing partition + */ +#define FIXED_PARTITION_BY_NODE(node) FIXED_PARTITION_1(node) + +/** @cond INTERNAL_HIDDEN */ #define FIXED_PARTITION_1(node) FIXED_PARTITION_0(DT_DEP_ORD(node)) #define FIXED_PARTITION_0(ord) \ ((const struct flash_area *)&DT_CAT(global_fixed_partition_ORD_, ord)) -/** @cond INTERNAL_HIDDEN */ #define DECLARE_PARTITION(node) DECLARE_PARTITION_0(DT_DEP_ORD(node)) #define DECLARE_PARTITION_0(ord) \ extern const struct flash_area DT_CAT(global_fixed_partition_ORD_, ord); diff --git a/include/zephyr/storage/stream_flash.h b/include/zephyr/storage/stream_flash.h index b1d78af90a9f0..ab3711ee4ff6e 100644 --- a/include/zephyr/storage/stream_flash.h +++ b/include/zephyr/storage/stream_flash.h @@ -61,9 +61,13 @@ struct stream_flash_ctx { size_t bytes_written; /* Number of bytes written to flash */ size_t offset; /* Offset from base of flash device to write area */ size_t available; /* Available bytes in write area */ +#ifdef CONFIG_STREAM_FLASH_POST_WRITE_CALLBACK stream_flash_callback_t callback; /* Callback invoked after write op */ +#endif #ifdef CONFIG_STREAM_FLASH_ERASE - off_t last_erased_page_start_offset; /* Last erased offset */ + size_t erased_up_to; /* Offset of last erased byte, relative to + * offset in this context. + */ #endif size_t write_block_size; /* Offset/size device write alignment */ uint8_t erase_value; @@ -79,9 +83,9 @@ struct stream_flash_ctx { * Must be multiple of the flash device write-block-size. * @param offset Offset within flash device to start writing to * @param size Number of bytes available for performing buffered write. - * If this is '0', the size will be set to the total size - * of the flash device minus the offset. * @param cb Callback to be invoked on completed flash write operations. + * Callback is supported when CONFIG_STREAM_FLASH_POST_WRITE_CALLBACK + * is enabled. * * @return non-negative on success, negative errno code on fail */ @@ -126,6 +130,9 @@ int stream_flash_buffered_write(struct stream_flash_ctx *ctx, const uint8_t *dat /** * @brief Erase the flash page to which a given offset belongs. * + * @deprecated Use @a flash_area_erase() or flash_erase(). Note that there + * is no Stream Flash API equivalent for that. + * * This function erases a flash page to which an offset belongs if this page * is not the page previously erased by the provided ctx * (ctx->last_erased_page_start_offset). @@ -135,7 +142,7 @@ int stream_flash_buffered_write(struct stream_flash_ctx *ctx, const uint8_t *dat * * @return non-negative on success, negative errno code on fail */ -int stream_flash_erase_page(struct stream_flash_ctx *ctx, off_t off); +__deprecated int stream_flash_erase_page(struct stream_flash_ctx *ctx, off_t off); /** * @brief Load persistent stream write progress stored with key diff --git a/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index 3636f49591e8e..21bad9270d637 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -213,7 +213,7 @@ extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; #define _Z_ISR_DECLARE_C(irq, flags, func, param, counter) \ _Z_ISR_TABLE_ENTRY(irq, func, param, _MK_ISR_ELEMENT_SECTION(counter)); \ - static struct _isr_list_sname Z_GENERIC_SECTION(.intList) \ + static Z_DECL_ALIGN(struct _isr_list_sname) Z_GENERIC_SECTION(.intList) \ __used _MK_ISR_NAME(func, counter) = \ {irq, flags, _MK_ISR_ELEMENT_SECTION(counter)} @@ -247,7 +247,7 @@ extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; #define _Z_ISR_DECLARE_DIRECT_C(irq, flags, func, counter) \ _Z_ISR_DIRECT_TABLE_ENTRY(irq, func, _MK_IRQ_ELEMENT_SECTION(counter)); \ - static struct _isr_list_sname Z_GENERIC_SECTION(.intList) \ + static Z_DECL_ALIGN(struct _isr_list_sname) Z_GENERIC_SECTION(.intList) \ __used _MK_ISR_NAME(func, counter) = { \ irq, \ ISR_FLAG_DIRECT | (flags), \ diff --git a/include/zephyr/sys/byteorder.h b/include/zephyr/sys/byteorder.h index 2b987dd14fefa..6de4a3f8bad9a 100644 --- a/include/zephyr/sys/byteorder.h +++ b/include/zephyr/sys/byteorder.h @@ -13,7 +13,9 @@ #include #include +#include #include +#include #include #define BSWAP_16(x) ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) @@ -719,4 +721,132 @@ static inline void sys_mem_swap(void *buf, size_t length) } } +/** + * @brief Convert buffer from little-endian to host endianness. + * + * @param buf A valid pointer on a memory area to convert from little-endian to host endianness. + * @param length Size of buf memory area + */ +static inline void sys_le_to_cpu(void *buf, size_t length) +{ + if (IS_ENABLED(CONFIG_BIG_ENDIAN)) { + sys_mem_swap(buf, length); + } +} + +/** + * @brief Convert buffer from host endianness to little-endian. + * + * @param buf A valid pointer on a memory area to convert from host endianness to little-endian. + * @param length Size of buf memory area + */ +static inline void sys_cpu_to_le(void *buf, size_t length) +{ + if (IS_ENABLED(CONFIG_BIG_ENDIAN)) { + sys_mem_swap(buf, length); + } +} + +/** + * @brief Convert buffer from big-endian to host endianness. + * + * @param buf A valid pointer on a memory area to convert from big-endian to host endianness. + * @param length Size of buf memory area + */ +static inline void sys_be_to_cpu(void *buf, size_t length) +{ + if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { + sys_mem_swap(buf, length); + } +} + +/** + * @brief Convert buffer from host endianness to big-endian. + * + * @param buf A valid pointer on a memory area to convert from host endianness to big-endian. + * @param length Size of buf memory area + */ +static inline void sys_cpu_to_be(void *buf, size_t length) +{ + if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { + sys_mem_swap(buf, length); + } +} + +/** + * @brief Put a buffer as little-endian to arbitrary location. + * + * Put a buffer originally in host endianness, to a + * potentially unaligned memory location in little-endian format. + * + * @param dst A valid pointer on a memory area where to copy the data in + * @param src A valid pointer on a memory area where to copy the data from + * @param length Size of both dst and src memory areas + */ +static inline void sys_put_le(void *dst, const void *src, size_t length) +{ + if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { + (void)memcpy(dst, src, length); + } else { + sys_memcpy_swap(dst, src, length); + } +} + +/** + * @brief Put a buffer as big-endian to arbitrary location. + * + * Put a buffer originally in host endianness, to a + * potentially unaligned memory location in big-endian format. + * + * @param dst A valid pointer on a memory area where to copy the data in + * @param src A valid pointer on a memory area where to copy the data from + * @param length Size of both dst and src memory areas + */ +static inline void sys_put_be(void *dst, const void *src, size_t length) +{ + if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { + sys_memcpy_swap(dst, src, length); + } else { + (void)memcpy(dst, src, length); + } +} + +/** + * @brief Get a buffer stored in little-endian format. + * + * Get a buffer, stored in little-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param dst A valid pointer on a memory area where to copy the data in + * @param src A valid pointer on a memory area where to copy the data from + * @param length Size of both dst and src memory areas + */ +static inline void sys_get_le(void *dst, const void *src, size_t length) +{ + if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { + (void)memcpy(dst, src, length); + } else { + sys_memcpy_swap(dst, src, length); + } +} + +/** + * @brief Get a buffer stored in big-endian format. + * + * Get a buffer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param dst A valid pointer on a memory area where to copy the data in + * @param src A valid pointer on a memory area where to copy the data from + * @param length Size of both dst and src memory areas + */ +static inline void sys_get_be(void *dst, const void *src, size_t length) +{ + if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { + sys_memcpy_swap(dst, src, length); + } else { + (void)memcpy(dst, src, length); + } +} + #endif /* ZEPHYR_INCLUDE_SYS_BYTEORDER_H_ */ diff --git a/include/zephyr/sys/dlist.h b/include/zephyr/sys/dlist.h index c7c5c5553ad29..2e1a9e741d286 100644 --- a/include/zephyr/sys/dlist.h +++ b/include/zephyr/sys/dlist.h @@ -492,6 +492,29 @@ static inline void sys_dlist_insert_at(sys_dlist_t *list, sys_dnode_t *node, } } +/** + * @brief remove a specific node from a list + * + * Like :c:func:`sys_dlist_remove()`, this routine removes a specific node + * from a list. However, unlike :c:func:`sys_dlist_remove()`, this routine + * does not re-initialize the removed node. One significant implication of + * this difference is that the function :c:func`sys_dnode_is_linked()` will + * not work on a dequeued node. + * + * The list is implicit from the node. The node must be part of a list. + * This and other sys_dlist_*() functions are not thread safe. + * + * @param node the node to dequeue + */ +static inline void sys_dlist_dequeue(sys_dnode_t *node) +{ + sys_dnode_t *const prev = node->prev; + sys_dnode_t *const next = node->next; + + prev->next = next; + next->prev = prev; +} + /** * @brief remove a specific node from a list * diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index 3d0b71494e0d0..d4153828fbb2d 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -14,6 +14,27 @@ #include #include +#ifdef CONFIG_PICOLIBC +#define ZVFS_O_APPEND 0x0400 +#define ZVFS_O_CREAT 0x0040 +#define ZVFS_O_TRUNC 0x0200 +#else +#define ZVFS_O_APPEND 0x0008 +#define ZVFS_O_CREAT 0x0200 +#define ZVFS_O_TRUNC 0x0400 +#endif + +#define ZVFS_O_RDONLY 00 +#define ZVFS_O_WRONLY 01 +#define ZVFS_O_RDWR 02 + +#define ZVFS_O_EXCL 0x0800 +#define ZVFS_O_NONBLOCK 0x4000 + +#define ZVFS_F_DUPFD 0 +#define ZVFS_F_GETFL 3 +#define ZVFS_F_SETFL 4 + /* File mode bits */ #define ZVFS_MODE_IFMT 0170000 #define ZVFS_MODE_UNSPEC 0000000 diff --git a/include/zephyr/sys/p4wq.h b/include/zephyr/sys/p4wq.h index 8ddb8f0d7a781..967de8c877000 100644 --- a/include/zephyr/sys/p4wq.h +++ b/include/zephyr/sys/p4wq.h @@ -18,6 +18,13 @@ struct k_p4wq_work; */ typedef void (*k_p4wq_handler_t)(struct k_p4wq_work *work); +/** + * Optional P4 Queue done callback. + * Will be called after the memory structure is not used anymore by the p4wq. + * If it is not used it must be set to NULL. + */ +typedef void (*k_p4wq_done_handler_t)(struct k_p4wq_work *work); + /** * @brief P4 Queue Work Item * @@ -74,6 +81,11 @@ struct k_p4wq { /* K_P4WQ_* flags above */ uint32_t flags; + + /* done handler which is called every time after work was successfully executed + * and k_p4wq_work is not needed by p4wq anymore + */ + k_p4wq_done_handler_t done_handler; }; struct k_p4wq_initparam { @@ -83,6 +95,7 @@ struct k_p4wq_initparam { struct k_thread *threads; struct z_thread_stack_element *stacks; uint32_t flags; + k_p4wq_done_handler_t done_handler; }; /** @@ -95,8 +108,9 @@ struct k_p4wq_initparam { * @param name Symbol name of the struct k_p4wq that will be defined * @param n_threads Number of threads in the work queue pool * @param stack_sz Requested stack size of each thread, in bytes + * @param dn_handler Function pointer to handler of type k_p4wq_done_handler_t */ -#define K_P4WQ_DEFINE(name, n_threads, stack_sz) \ +#define K_P4WQ_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, dn_handler) \ static K_THREAD_STACK_ARRAY_DEFINE(_p4stacks_##name, \ n_threads, stack_sz); \ static struct k_thread _p4threads_##name[n_threads]; \ @@ -109,8 +123,19 @@ struct k_p4wq_initparam { .stacks = &(_p4stacks_##name[0][0]), \ .queue = &name, \ .flags = 0, \ + .done_handler = dn_handler, \ } +/** + * @brief Statically initialize a P4 Work Queue + * + * Same like K_P4WQ_DEFINE_WITH_DONE_HANDLER but without an + * optional handler which is called everytime when work is executed + * and not used anymore by the p4wq + */ +#define K_P4WQ_DEFINE(name, n_threads, stack_sz) \ + K_P4WQ_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, NULL) + /** * @brief Statically initialize an array of P4 Work Queues * @@ -122,8 +147,9 @@ struct k_p4wq_initparam { * @param n_threads Number of threads and work queues * @param stack_sz Requested stack size of each thread, in bytes * @param flg Flags + * @param dn_handler Function pointer to handler of type k_p4wq_done_handler_t */ -#define K_P4WQ_ARRAY_DEFINE(name, n_threads, stack_sz, flg) \ +#define K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, flg, dn_handler) \ static K_THREAD_STACK_ARRAY_DEFINE(_p4stacks_##name, \ n_threads, stack_sz); \ static struct k_thread _p4threads_##name[n_threads]; \ @@ -136,8 +162,19 @@ struct k_p4wq_initparam { .stacks = &(_p4stacks_##name[0][0]), \ .queue = name, \ .flags = K_P4WQ_QUEUE_PER_THREAD | flg, \ + .done_handler = dn_handler, \ } +/** + * @brief Statically initialize an array of P4 Work Queues + * + * Same like K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER but without an + * optional handler which is called everytime when work is executed + * and not used anymore by the p4wq + */ +#define K_P4WQ_ARRAY_DEFINE(name, n_threads, stack_sz, flg) \ + K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, flg, NULL) + /** * @brief Initialize P4 Queue * diff --git a/include/zephyr/sys/ring_buffer.h b/include/zephyr/sys/ring_buffer.h index 6bec33e9e3a90..e104fd5443e25 100644 --- a/include/zephyr/sys/ring_buffer.h +++ b/include/zephyr/sys/ring_buffer.h @@ -7,7 +7,6 @@ #ifndef ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_ #define ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_ -#include #include #include @@ -15,16 +14,6 @@ extern "C" { #endif -/** @cond INTERNAL_HIDDEN */ -/* The limit is used by algorithm for distinguishing between empty and full - * state. - */ -#define RING_BUFFER_MAX_SIZE 0x80000000U - -#define RING_BUFFER_SIZE_ASSERT_MSG \ - "Size too big" -/** @endcond */ - /** * @file * @defgroup ring_buffer_apis Ring Buffer APIs @@ -35,22 +24,38 @@ extern "C" { * @{ */ +/** @cond INTERNAL_HIDDEN */ + +/* The limit is used by algorithm for distinguishing between empty and full + * state. + */ +#define RING_BUFFER_MAX_SIZE 0x80000000U +#define RING_BUFFER_SIZE_ASSERT_MSG \ + "Size too big" + +struct ring_buf_index { int32_t head, tail, base; }; + +/** @endcond */ + /** * @brief A structure to represent a ring buffer */ struct ring_buf { /** @cond INTERNAL_HIDDEN */ uint8_t *buffer; - int32_t put_head; - int32_t put_tail; - int32_t put_base; - int32_t get_head; - int32_t get_tail; - int32_t get_base; + struct ring_buf_index put; + struct ring_buf_index get; uint32_t size; /** @endcond */ }; +/** @cond INTERNAL_HIDDEN */ + +uint32_t ring_buf_area_claim(struct ring_buf *buf, struct ring_buf_index *ring, + uint8_t **data, uint32_t size); +int ring_buf_area_finish(struct ring_buf *buf, struct ring_buf_index *ring, + uint32_t size); + /** * @brief Function to force ring_buf internal states to given value * @@ -58,8 +63,16 @@ struct ring_buf { */ static inline void ring_buf_internal_reset(struct ring_buf *buf, int32_t value) { - buf->put_head = buf->put_tail = buf->put_base = value; - buf->get_head = buf->get_tail = buf->get_base = value; + buf->put.head = buf->put.tail = buf->put.base = value; + buf->get.head = buf->get.tail = buf->get.base = value; +} + +/** @endcond */ + +#define RING_BUF_INIT(buf, size8) \ +{ \ + .buffer = buf, \ + .size = size8, \ } /** @@ -80,10 +93,7 @@ static inline void ring_buf_internal_reset(struct ring_buf *buf, int32_t value) BUILD_ASSERT(size8 < RING_BUFFER_MAX_SIZE,\ RING_BUFFER_SIZE_ASSERT_MSG); \ static uint8_t __noinit _ring_buffer_data_##name[size8]; \ - struct ring_buf name = { \ - .buffer = _ring_buffer_data_##name, \ - .size = size8 \ - } + struct ring_buf name = RING_BUF_INIT(_ring_buffer_data_##name, size8) /** * @brief Define and initialize an "item based" ring buffer. @@ -195,7 +205,7 @@ static inline void ring_buf_item_init(struct ring_buf *buf, */ static inline bool ring_buf_is_empty(struct ring_buf *buf) { - return buf->get_head == buf->put_tail; + return buf->get.head == buf->put.tail; } /** @@ -217,7 +227,7 @@ static inline void ring_buf_reset(struct ring_buf *buf) */ static inline uint32_t ring_buf_space_get(struct ring_buf *buf) { - return buf->size - (buf->put_head - buf->get_tail); + return buf->size - (buf->put.head - buf->get.tail); } /** @@ -253,7 +263,7 @@ static inline uint32_t ring_buf_capacity_get(struct ring_buf *buf) */ static inline uint32_t ring_buf_size_get(struct ring_buf *buf) { - return buf->put_tail - buf->get_head; + return buf->put.tail - buf->get.head; } /** @@ -280,9 +290,13 @@ static inline uint32_t ring_buf_size_get(struct ring_buf *buf) * @return Size of allocated buffer which can be smaller than requested if * there is not enough free space or buffer wraps. */ -uint32_t ring_buf_put_claim(struct ring_buf *buf, - uint8_t **data, - uint32_t size); +static inline uint32_t ring_buf_put_claim(struct ring_buf *buf, + uint8_t **data, + uint32_t size) +{ + return ring_buf_area_claim(buf, &buf->put, data, + MIN(size, ring_buf_space_get(buf))); +} /** * @brief Indicate number of bytes written to allocated buffers. @@ -306,7 +320,10 @@ uint32_t ring_buf_put_claim(struct ring_buf *buf, * @retval 0 Successful operation. * @retval -EINVAL Provided @a size exceeds free space in the ring buffer. */ -int ring_buf_put_finish(struct ring_buf *buf, uint32_t size); +static inline int ring_buf_put_finish(struct ring_buf *buf, uint32_t size) +{ + return ring_buf_area_finish(buf, &buf->put, size); +} /** * @brief Write (copy) data to a ring buffer. @@ -354,9 +371,13 @@ uint32_t ring_buf_put(struct ring_buf *buf, const uint8_t *data, uint32_t size); * @return Number of valid bytes in the provided buffer which can be smaller * than requested if there is not enough free space or buffer wraps. */ -uint32_t ring_buf_get_claim(struct ring_buf *buf, - uint8_t **data, - uint32_t size); +static inline uint32_t ring_buf_get_claim(struct ring_buf *buf, + uint8_t **data, + uint32_t size) +{ + return ring_buf_area_claim(buf, &buf->get, data, + MIN(size, ring_buf_size_get(buf))); +} /** * @brief Indicate number of bytes read from claimed buffer. @@ -380,7 +401,10 @@ uint32_t ring_buf_get_claim(struct ring_buf *buf, * @retval 0 Successful operation. * @retval -EINVAL Provided @a size exceeds valid bytes in the ring buffer. */ -int ring_buf_get_finish(struct ring_buf *buf, uint32_t size); +static inline int ring_buf_get_finish(struct ring_buf *buf, uint32_t size) +{ + return ring_buf_area_finish(buf, &buf->get, size); +} /** * @brief Read data from a ring buffer. diff --git a/include/zephyr/sys/sys_heap.h b/include/zephyr/sys/sys_heap.h index f01bae189e61f..33d989576a5f2 100644 --- a/include/zephyr/sys/sys_heap.h +++ b/include/zephyr/sys/sys_heap.h @@ -267,6 +267,24 @@ void sys_heap_stress(void *(*alloc_fn)(void *arg, size_t bytes), */ void sys_heap_print_info(struct sys_heap *heap, bool dump_chunks); +/** @brief Save the heap pointer + * + * The heap pointer is saved into an internal array, if there is space. + * + * @param heap Heap to save + * @return -EINVAL if null pointer or array is full, otherwise 0 + */ +int sys_heap_array_save(struct sys_heap *heap); + +/** @brief Get the array of saved heap pointers + * + * Returns the pointer to the array of heap pointers. + * + * @param heap Heap array + * @return -EINVAL if null pointer, otherwise number of saved pointers + */ +int sys_heap_array_get(struct sys_heap ***heap); + /** * @} */ diff --git a/include/zephyr/sys/time_units.h b/include/zephyr/sys/time_units.h index c02fd01288726..46679fc33acf7 100644 --- a/include/zephyr/sys/time_units.h +++ b/include/zephyr/sys/time_units.h @@ -38,10 +38,16 @@ extern "C" { */ #define SYS_FOREVER_US (-1) +/** @brief System-wide macro to initialize #k_timeout_t with a number of ticks + * converted from milliseconds. + */ +#define SYS_TIMEOUT_MS_INIT(ms) \ + Z_TIMEOUT_TICKS_INIT((ms) == SYS_FOREVER_MS ? \ + K_TICKS_FOREVER : Z_TIMEOUT_MS_TICKS(ms)) + /** @brief System-wide macro to convert milliseconds to kernel timeouts */ -#define SYS_TIMEOUT_MS(ms) Z_TIMEOUT_TICKS((ms) == SYS_FOREVER_MS ? \ - K_TICKS_FOREVER : Z_TIMEOUT_MS_TICKS(ms)) +#define SYS_TIMEOUT_MS(ms) ((k_timeout_t) SYS_TIMEOUT_MS_INIT(ms)) /* Exhaustively enumerated, highly optimized time unit conversion API */ diff --git a/include/zephyr/sys/util.h b/include/zephyr/sys/util.h index 8c648c777e402..0e38acb4aae8e 100644 --- a/include/zephyr/sys/util.h +++ b/include/zephyr/sys/util.h @@ -366,9 +366,10 @@ extern "C" { * * @return The result of @p n / @p d, rounded to the nearest integer. */ -#define DIV_ROUND_CLOSEST(n, d) \ - ((((n) < 0) ^ ((d) < 0)) ? ((n) - ((d) / 2)) / (d) : \ - ((n) + ((d) / 2)) / (d)) +#define DIV_ROUND_CLOSEST(n, d) \ + (((((__typeof__(n))-1) < 0) && (((__typeof__(d))-1) < 0) && ((n) < 0) ^ ((d) < 0)) \ + ? ((n) - ((d) / 2)) / (d) \ + : ((n) + ((d) / 2)) / (d)) #ifndef MAX /** @@ -711,7 +712,7 @@ char *utf8_lcpy(char *dst, const char *src, size_t n); * * @return ceil(log2(x)) when 1 <= x <= max(type(x)), 0 when x < 1 */ -#define LOG2CEIL(x) ((x) < 1 ? 0 : __z_log2((x)-1) + 1) +#define LOG2CEIL(x) ((x) <= 1 ? 0 : __z_log2((x)-1) + 1) /** * @brief Compute next highest power of two diff --git a/include/zephyr/sys/util_internal.h b/include/zephyr/sys/util_internal.h index d3adca6064038..1d4e0d2130fba 100644 --- a/include/zephyr/sys/util_internal.h +++ b/include/zephyr/sys/util_internal.h @@ -50,7 +50,7 @@ #define Z_IS_ENABLED3(ignore_this, val, ...) val /* Implementation of IS_EQ(). Returns 1 if _0 and _1 are the same integer from - * 0 to 4095, 0 otherwise. + * 0 to 4096, 0 otherwise. */ #define Z_IS_EQ(_0, _1) Z_HAS_COMMA(Z_CAT4(Z_IS_, _0, _EQ_, _1)()) diff --git a/include/zephyr/sys/util_internal_is_eq.h b/include/zephyr/sys/util_internal_is_eq.h index 0734cf3506ace..11657c6acf67e 100644 --- a/include/zephyr/sys/util_internal_is_eq.h +++ b/include/zephyr/sys/util_internal_is_eq.h @@ -13,4102 +13,16393 @@ #ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_ #define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_ -#define Z_IS_0_EQ_0(...) \, -#define Z_IS_1_EQ_1(...) \, -#define Z_IS_2_EQ_2(...) \, -#define Z_IS_3_EQ_3(...) \, -#define Z_IS_4_EQ_4(...) \, -#define Z_IS_5_EQ_5(...) \, -#define Z_IS_6_EQ_6(...) \, -#define Z_IS_7_EQ_7(...) \, -#define Z_IS_8_EQ_8(...) \, -#define Z_IS_9_EQ_9(...) \, -#define Z_IS_10_EQ_10(...) \, -#define Z_IS_11_EQ_11(...) \, -#define Z_IS_12_EQ_12(...) \, -#define Z_IS_13_EQ_13(...) \, -#define Z_IS_14_EQ_14(...) \, -#define Z_IS_15_EQ_15(...) \, -#define Z_IS_16_EQ_16(...) \, -#define Z_IS_17_EQ_17(...) \, -#define Z_IS_18_EQ_18(...) \, -#define Z_IS_19_EQ_19(...) \, -#define Z_IS_20_EQ_20(...) \, -#define Z_IS_21_EQ_21(...) \, -#define Z_IS_22_EQ_22(...) \, -#define Z_IS_23_EQ_23(...) \, -#define Z_IS_24_EQ_24(...) \, -#define Z_IS_25_EQ_25(...) \, -#define Z_IS_26_EQ_26(...) \, -#define Z_IS_27_EQ_27(...) \, -#define Z_IS_28_EQ_28(...) \, -#define Z_IS_29_EQ_29(...) \, -#define Z_IS_30_EQ_30(...) \, -#define Z_IS_31_EQ_31(...) \, -#define Z_IS_32_EQ_32(...) \, -#define Z_IS_33_EQ_33(...) \, -#define Z_IS_34_EQ_34(...) \, -#define Z_IS_35_EQ_35(...) \, -#define Z_IS_36_EQ_36(...) \, -#define Z_IS_37_EQ_37(...) \, -#define Z_IS_38_EQ_38(...) \, -#define Z_IS_39_EQ_39(...) \, -#define Z_IS_40_EQ_40(...) \, -#define Z_IS_41_EQ_41(...) \, -#define Z_IS_42_EQ_42(...) \, -#define Z_IS_43_EQ_43(...) \, -#define Z_IS_44_EQ_44(...) \, -#define Z_IS_45_EQ_45(...) \, -#define Z_IS_46_EQ_46(...) \, -#define Z_IS_47_EQ_47(...) \, -#define Z_IS_48_EQ_48(...) \, -#define Z_IS_49_EQ_49(...) \, -#define Z_IS_50_EQ_50(...) \, -#define Z_IS_51_EQ_51(...) \, -#define Z_IS_52_EQ_52(...) \, -#define Z_IS_53_EQ_53(...) \, -#define Z_IS_54_EQ_54(...) \, -#define Z_IS_55_EQ_55(...) \, -#define Z_IS_56_EQ_56(...) \, -#define Z_IS_57_EQ_57(...) \, -#define Z_IS_58_EQ_58(...) \, -#define Z_IS_59_EQ_59(...) \, -#define Z_IS_60_EQ_60(...) \, -#define Z_IS_61_EQ_61(...) \, -#define Z_IS_62_EQ_62(...) \, -#define Z_IS_63_EQ_63(...) \, -#define Z_IS_64_EQ_64(...) \, -#define Z_IS_65_EQ_65(...) \, -#define Z_IS_66_EQ_66(...) \, -#define Z_IS_67_EQ_67(...) \, -#define Z_IS_68_EQ_68(...) \, -#define Z_IS_69_EQ_69(...) \, -#define Z_IS_70_EQ_70(...) \, -#define Z_IS_71_EQ_71(...) \, -#define Z_IS_72_EQ_72(...) \, -#define Z_IS_73_EQ_73(...) \, -#define Z_IS_74_EQ_74(...) \, -#define Z_IS_75_EQ_75(...) \, -#define Z_IS_76_EQ_76(...) \, -#define Z_IS_77_EQ_77(...) \, -#define Z_IS_78_EQ_78(...) \, -#define Z_IS_79_EQ_79(...) \, -#define Z_IS_80_EQ_80(...) \, -#define Z_IS_81_EQ_81(...) \, -#define Z_IS_82_EQ_82(...) \, -#define Z_IS_83_EQ_83(...) \, -#define Z_IS_84_EQ_84(...) \, -#define Z_IS_85_EQ_85(...) \, -#define Z_IS_86_EQ_86(...) \, -#define Z_IS_87_EQ_87(...) \, -#define Z_IS_88_EQ_88(...) \, -#define Z_IS_89_EQ_89(...) \, -#define Z_IS_90_EQ_90(...) \, -#define Z_IS_91_EQ_91(...) \, -#define Z_IS_92_EQ_92(...) \, -#define Z_IS_93_EQ_93(...) \, -#define Z_IS_94_EQ_94(...) \, -#define Z_IS_95_EQ_95(...) \, -#define Z_IS_96_EQ_96(...) \, -#define Z_IS_97_EQ_97(...) \, -#define Z_IS_98_EQ_98(...) \, -#define Z_IS_99_EQ_99(...) \, -#define Z_IS_100_EQ_100(...) \, -#define Z_IS_101_EQ_101(...) \, -#define Z_IS_102_EQ_102(...) \, -#define Z_IS_103_EQ_103(...) \, -#define Z_IS_104_EQ_104(...) \, -#define Z_IS_105_EQ_105(...) \, -#define Z_IS_106_EQ_106(...) \, -#define Z_IS_107_EQ_107(...) \, -#define Z_IS_108_EQ_108(...) \, -#define Z_IS_109_EQ_109(...) \, -#define Z_IS_110_EQ_110(...) \, -#define Z_IS_111_EQ_111(...) \, -#define Z_IS_112_EQ_112(...) \, -#define Z_IS_113_EQ_113(...) \, -#define Z_IS_114_EQ_114(...) \, -#define Z_IS_115_EQ_115(...) \, -#define Z_IS_116_EQ_116(...) \, -#define Z_IS_117_EQ_117(...) \, -#define Z_IS_118_EQ_118(...) \, -#define Z_IS_119_EQ_119(...) \, -#define Z_IS_120_EQ_120(...) \, -#define Z_IS_121_EQ_121(...) \, -#define Z_IS_122_EQ_122(...) \, -#define Z_IS_123_EQ_123(...) \, -#define Z_IS_124_EQ_124(...) \, -#define Z_IS_125_EQ_125(...) \, -#define Z_IS_126_EQ_126(...) \, -#define Z_IS_127_EQ_127(...) \, -#define Z_IS_128_EQ_128(...) \, -#define Z_IS_129_EQ_129(...) \, -#define Z_IS_130_EQ_130(...) \, -#define Z_IS_131_EQ_131(...) \, -#define Z_IS_132_EQ_132(...) \, -#define Z_IS_133_EQ_133(...) \, -#define Z_IS_134_EQ_134(...) \, -#define Z_IS_135_EQ_135(...) \, -#define Z_IS_136_EQ_136(...) \, -#define Z_IS_137_EQ_137(...) \, -#define Z_IS_138_EQ_138(...) \, -#define Z_IS_139_EQ_139(...) \, -#define Z_IS_140_EQ_140(...) \, -#define Z_IS_141_EQ_141(...) \, -#define Z_IS_142_EQ_142(...) \, -#define Z_IS_143_EQ_143(...) \, -#define Z_IS_144_EQ_144(...) \, -#define Z_IS_145_EQ_145(...) \, -#define Z_IS_146_EQ_146(...) \, -#define Z_IS_147_EQ_147(...) \, -#define Z_IS_148_EQ_148(...) \, -#define Z_IS_149_EQ_149(...) \, -#define Z_IS_150_EQ_150(...) \, -#define Z_IS_151_EQ_151(...) \, -#define Z_IS_152_EQ_152(...) \, -#define Z_IS_153_EQ_153(...) \, -#define Z_IS_154_EQ_154(...) \, -#define Z_IS_155_EQ_155(...) \, -#define Z_IS_156_EQ_156(...) \, -#define Z_IS_157_EQ_157(...) \, -#define Z_IS_158_EQ_158(...) \, -#define Z_IS_159_EQ_159(...) \, -#define Z_IS_160_EQ_160(...) \, -#define Z_IS_161_EQ_161(...) \, -#define Z_IS_162_EQ_162(...) \, -#define Z_IS_163_EQ_163(...) \, -#define Z_IS_164_EQ_164(...) \, -#define Z_IS_165_EQ_165(...) \, -#define Z_IS_166_EQ_166(...) \, -#define Z_IS_167_EQ_167(...) \, -#define Z_IS_168_EQ_168(...) \, -#define Z_IS_169_EQ_169(...) \, -#define Z_IS_170_EQ_170(...) \, -#define Z_IS_171_EQ_171(...) \, -#define Z_IS_172_EQ_172(...) \, -#define Z_IS_173_EQ_173(...) \, -#define Z_IS_174_EQ_174(...) \, -#define Z_IS_175_EQ_175(...) \, -#define Z_IS_176_EQ_176(...) \, -#define Z_IS_177_EQ_177(...) \, -#define Z_IS_178_EQ_178(...) \, -#define Z_IS_179_EQ_179(...) \, -#define Z_IS_180_EQ_180(...) \, -#define Z_IS_181_EQ_181(...) \, -#define Z_IS_182_EQ_182(...) \, -#define Z_IS_183_EQ_183(...) \, -#define Z_IS_184_EQ_184(...) \, -#define Z_IS_185_EQ_185(...) \, -#define Z_IS_186_EQ_186(...) \, -#define Z_IS_187_EQ_187(...) \, -#define Z_IS_188_EQ_188(...) \, -#define Z_IS_189_EQ_189(...) \, -#define Z_IS_190_EQ_190(...) \, -#define Z_IS_191_EQ_191(...) \, -#define Z_IS_192_EQ_192(...) \, -#define Z_IS_193_EQ_193(...) \, -#define Z_IS_194_EQ_194(...) \, -#define Z_IS_195_EQ_195(...) \, -#define Z_IS_196_EQ_196(...) \, -#define Z_IS_197_EQ_197(...) \, -#define Z_IS_198_EQ_198(...) \, -#define Z_IS_199_EQ_199(...) \, -#define Z_IS_200_EQ_200(...) \, -#define Z_IS_201_EQ_201(...) \, -#define Z_IS_202_EQ_202(...) \, -#define Z_IS_203_EQ_203(...) \, -#define Z_IS_204_EQ_204(...) \, -#define Z_IS_205_EQ_205(...) \, -#define Z_IS_206_EQ_206(...) \, -#define Z_IS_207_EQ_207(...) \, -#define Z_IS_208_EQ_208(...) \, -#define Z_IS_209_EQ_209(...) \, -#define Z_IS_210_EQ_210(...) \, -#define Z_IS_211_EQ_211(...) \, -#define Z_IS_212_EQ_212(...) \, -#define Z_IS_213_EQ_213(...) \, -#define Z_IS_214_EQ_214(...) \, -#define Z_IS_215_EQ_215(...) \, -#define Z_IS_216_EQ_216(...) \, -#define Z_IS_217_EQ_217(...) \, -#define Z_IS_218_EQ_218(...) \, -#define Z_IS_219_EQ_219(...) \, -#define Z_IS_220_EQ_220(...) \, -#define Z_IS_221_EQ_221(...) \, -#define Z_IS_222_EQ_222(...) \, -#define Z_IS_223_EQ_223(...) \, -#define Z_IS_224_EQ_224(...) \, -#define Z_IS_225_EQ_225(...) \, -#define Z_IS_226_EQ_226(...) \, -#define Z_IS_227_EQ_227(...) \, -#define Z_IS_228_EQ_228(...) \, -#define Z_IS_229_EQ_229(...) \, -#define Z_IS_230_EQ_230(...) \, -#define Z_IS_231_EQ_231(...) \, -#define Z_IS_232_EQ_232(...) \, -#define Z_IS_233_EQ_233(...) \, -#define Z_IS_234_EQ_234(...) \, -#define Z_IS_235_EQ_235(...) \, -#define Z_IS_236_EQ_236(...) \, -#define Z_IS_237_EQ_237(...) \, -#define Z_IS_238_EQ_238(...) \, -#define Z_IS_239_EQ_239(...) \, -#define Z_IS_240_EQ_240(...) \, -#define Z_IS_241_EQ_241(...) \, -#define Z_IS_242_EQ_242(...) \, -#define Z_IS_243_EQ_243(...) \, -#define Z_IS_244_EQ_244(...) \, -#define Z_IS_245_EQ_245(...) \, -#define Z_IS_246_EQ_246(...) \, -#define Z_IS_247_EQ_247(...) \, -#define Z_IS_248_EQ_248(...) \, -#define Z_IS_249_EQ_249(...) \, -#define Z_IS_250_EQ_250(...) \, -#define Z_IS_251_EQ_251(...) \, -#define Z_IS_252_EQ_252(...) \, -#define Z_IS_253_EQ_253(...) \, -#define Z_IS_254_EQ_254(...) \, -#define Z_IS_255_EQ_255(...) \, -#define Z_IS_256_EQ_256(...) \, -#define Z_IS_257_EQ_257(...) \, -#define Z_IS_258_EQ_258(...) \, -#define Z_IS_259_EQ_259(...) \, -#define Z_IS_260_EQ_260(...) \, -#define Z_IS_261_EQ_261(...) \, -#define Z_IS_262_EQ_262(...) \, -#define Z_IS_263_EQ_263(...) \, -#define Z_IS_264_EQ_264(...) \, -#define Z_IS_265_EQ_265(...) \, -#define Z_IS_266_EQ_266(...) \, -#define Z_IS_267_EQ_267(...) \, -#define Z_IS_268_EQ_268(...) \, -#define Z_IS_269_EQ_269(...) \, -#define Z_IS_270_EQ_270(...) \, -#define Z_IS_271_EQ_271(...) \, -#define Z_IS_272_EQ_272(...) \, -#define Z_IS_273_EQ_273(...) \, -#define Z_IS_274_EQ_274(...) \, -#define Z_IS_275_EQ_275(...) \, -#define Z_IS_276_EQ_276(...) \, -#define Z_IS_277_EQ_277(...) \, -#define Z_IS_278_EQ_278(...) \, -#define Z_IS_279_EQ_279(...) \, -#define Z_IS_280_EQ_280(...) \, -#define Z_IS_281_EQ_281(...) \, -#define Z_IS_282_EQ_282(...) \, -#define Z_IS_283_EQ_283(...) \, -#define Z_IS_284_EQ_284(...) \, -#define Z_IS_285_EQ_285(...) \, -#define Z_IS_286_EQ_286(...) \, -#define Z_IS_287_EQ_287(...) \, -#define Z_IS_288_EQ_288(...) \, -#define Z_IS_289_EQ_289(...) \, -#define Z_IS_290_EQ_290(...) \, -#define Z_IS_291_EQ_291(...) \, -#define Z_IS_292_EQ_292(...) \, -#define Z_IS_293_EQ_293(...) \, -#define Z_IS_294_EQ_294(...) \, -#define Z_IS_295_EQ_295(...) \, -#define Z_IS_296_EQ_296(...) \, -#define Z_IS_297_EQ_297(...) \, -#define Z_IS_298_EQ_298(...) \, -#define Z_IS_299_EQ_299(...) \, -#define Z_IS_300_EQ_300(...) \, -#define Z_IS_301_EQ_301(...) \, -#define Z_IS_302_EQ_302(...) \, -#define Z_IS_303_EQ_303(...) \, -#define Z_IS_304_EQ_304(...) \, -#define Z_IS_305_EQ_305(...) \, -#define Z_IS_306_EQ_306(...) \, -#define Z_IS_307_EQ_307(...) \, -#define Z_IS_308_EQ_308(...) \, -#define Z_IS_309_EQ_309(...) \, -#define Z_IS_310_EQ_310(...) \, -#define Z_IS_311_EQ_311(...) \, -#define Z_IS_312_EQ_312(...) \, -#define Z_IS_313_EQ_313(...) \, -#define Z_IS_314_EQ_314(...) \, -#define Z_IS_315_EQ_315(...) \, -#define Z_IS_316_EQ_316(...) \, -#define Z_IS_317_EQ_317(...) \, -#define Z_IS_318_EQ_318(...) \, -#define Z_IS_319_EQ_319(...) \, -#define Z_IS_320_EQ_320(...) \, -#define Z_IS_321_EQ_321(...) \, -#define Z_IS_322_EQ_322(...) \, -#define Z_IS_323_EQ_323(...) \, -#define Z_IS_324_EQ_324(...) \, -#define Z_IS_325_EQ_325(...) \, -#define Z_IS_326_EQ_326(...) \, -#define Z_IS_327_EQ_327(...) \, -#define Z_IS_328_EQ_328(...) \, -#define Z_IS_329_EQ_329(...) \, -#define Z_IS_330_EQ_330(...) \, -#define Z_IS_331_EQ_331(...) \, -#define Z_IS_332_EQ_332(...) \, -#define Z_IS_333_EQ_333(...) \, -#define Z_IS_334_EQ_334(...) \, -#define Z_IS_335_EQ_335(...) \, -#define Z_IS_336_EQ_336(...) \, -#define Z_IS_337_EQ_337(...) \, -#define Z_IS_338_EQ_338(...) \, -#define Z_IS_339_EQ_339(...) \, -#define Z_IS_340_EQ_340(...) \, -#define Z_IS_341_EQ_341(...) \, -#define Z_IS_342_EQ_342(...) \, -#define Z_IS_343_EQ_343(...) \, -#define Z_IS_344_EQ_344(...) \, -#define Z_IS_345_EQ_345(...) \, -#define Z_IS_346_EQ_346(...) \, -#define Z_IS_347_EQ_347(...) \, -#define Z_IS_348_EQ_348(...) \, -#define Z_IS_349_EQ_349(...) \, -#define Z_IS_350_EQ_350(...) \, -#define Z_IS_351_EQ_351(...) \, -#define Z_IS_352_EQ_352(...) \, -#define Z_IS_353_EQ_353(...) \, -#define Z_IS_354_EQ_354(...) \, -#define Z_IS_355_EQ_355(...) \, -#define Z_IS_356_EQ_356(...) \, -#define Z_IS_357_EQ_357(...) \, -#define Z_IS_358_EQ_358(...) \, -#define Z_IS_359_EQ_359(...) \, -#define Z_IS_360_EQ_360(...) \, -#define Z_IS_361_EQ_361(...) \, -#define Z_IS_362_EQ_362(...) \, -#define Z_IS_363_EQ_363(...) \, -#define Z_IS_364_EQ_364(...) \, -#define Z_IS_365_EQ_365(...) \, -#define Z_IS_366_EQ_366(...) \, -#define Z_IS_367_EQ_367(...) \, -#define Z_IS_368_EQ_368(...) \, -#define Z_IS_369_EQ_369(...) \, -#define Z_IS_370_EQ_370(...) \, -#define Z_IS_371_EQ_371(...) \, -#define Z_IS_372_EQ_372(...) \, -#define Z_IS_373_EQ_373(...) \, -#define Z_IS_374_EQ_374(...) \, -#define Z_IS_375_EQ_375(...) \, -#define Z_IS_376_EQ_376(...) \, -#define Z_IS_377_EQ_377(...) \, -#define Z_IS_378_EQ_378(...) \, -#define Z_IS_379_EQ_379(...) \, -#define Z_IS_380_EQ_380(...) \, -#define Z_IS_381_EQ_381(...) \, -#define Z_IS_382_EQ_382(...) \, -#define Z_IS_383_EQ_383(...) \, -#define Z_IS_384_EQ_384(...) \, -#define Z_IS_385_EQ_385(...) \, -#define Z_IS_386_EQ_386(...) \, -#define Z_IS_387_EQ_387(...) \, -#define Z_IS_388_EQ_388(...) \, -#define Z_IS_389_EQ_389(...) \, -#define Z_IS_390_EQ_390(...) \, -#define Z_IS_391_EQ_391(...) \, -#define Z_IS_392_EQ_392(...) \, -#define Z_IS_393_EQ_393(...) \, -#define Z_IS_394_EQ_394(...) \, -#define Z_IS_395_EQ_395(...) \, -#define Z_IS_396_EQ_396(...) \, -#define Z_IS_397_EQ_397(...) \, -#define Z_IS_398_EQ_398(...) \, -#define Z_IS_399_EQ_399(...) \, -#define Z_IS_400_EQ_400(...) \, -#define Z_IS_401_EQ_401(...) \, -#define Z_IS_402_EQ_402(...) \, -#define Z_IS_403_EQ_403(...) \, -#define Z_IS_404_EQ_404(...) \, -#define Z_IS_405_EQ_405(...) \, -#define Z_IS_406_EQ_406(...) \, -#define Z_IS_407_EQ_407(...) \, -#define Z_IS_408_EQ_408(...) \, -#define Z_IS_409_EQ_409(...) \, -#define Z_IS_410_EQ_410(...) \, -#define Z_IS_411_EQ_411(...) \, -#define Z_IS_412_EQ_412(...) \, -#define Z_IS_413_EQ_413(...) \, -#define Z_IS_414_EQ_414(...) \, -#define Z_IS_415_EQ_415(...) \, -#define Z_IS_416_EQ_416(...) \, -#define Z_IS_417_EQ_417(...) \, -#define Z_IS_418_EQ_418(...) \, -#define Z_IS_419_EQ_419(...) \, -#define Z_IS_420_EQ_420(...) \, -#define Z_IS_421_EQ_421(...) \, -#define Z_IS_422_EQ_422(...) \, -#define Z_IS_423_EQ_423(...) \, -#define Z_IS_424_EQ_424(...) \, -#define Z_IS_425_EQ_425(...) \, -#define Z_IS_426_EQ_426(...) \, -#define Z_IS_427_EQ_427(...) \, -#define Z_IS_428_EQ_428(...) \, -#define Z_IS_429_EQ_429(...) \, -#define Z_IS_430_EQ_430(...) \, -#define Z_IS_431_EQ_431(...) \, -#define Z_IS_432_EQ_432(...) \, -#define Z_IS_433_EQ_433(...) \, -#define Z_IS_434_EQ_434(...) \, -#define Z_IS_435_EQ_435(...) \, -#define Z_IS_436_EQ_436(...) \, -#define Z_IS_437_EQ_437(...) \, -#define Z_IS_438_EQ_438(...) \, -#define Z_IS_439_EQ_439(...) \, -#define Z_IS_440_EQ_440(...) \, -#define Z_IS_441_EQ_441(...) \, -#define Z_IS_442_EQ_442(...) \, -#define Z_IS_443_EQ_443(...) \, -#define Z_IS_444_EQ_444(...) \, -#define Z_IS_445_EQ_445(...) \, -#define Z_IS_446_EQ_446(...) \, -#define Z_IS_447_EQ_447(...) \, -#define Z_IS_448_EQ_448(...) \, -#define Z_IS_449_EQ_449(...) \, -#define Z_IS_450_EQ_450(...) \, -#define Z_IS_451_EQ_451(...) \, -#define Z_IS_452_EQ_452(...) \, -#define Z_IS_453_EQ_453(...) \, -#define Z_IS_454_EQ_454(...) \, -#define Z_IS_455_EQ_455(...) \, -#define Z_IS_456_EQ_456(...) \, -#define Z_IS_457_EQ_457(...) \, -#define Z_IS_458_EQ_458(...) \, -#define Z_IS_459_EQ_459(...) \, -#define Z_IS_460_EQ_460(...) \, -#define Z_IS_461_EQ_461(...) \, -#define Z_IS_462_EQ_462(...) \, -#define Z_IS_463_EQ_463(...) \, -#define Z_IS_464_EQ_464(...) \, -#define Z_IS_465_EQ_465(...) \, -#define Z_IS_466_EQ_466(...) \, -#define Z_IS_467_EQ_467(...) \, -#define Z_IS_468_EQ_468(...) \, -#define Z_IS_469_EQ_469(...) \, -#define Z_IS_470_EQ_470(...) \, -#define Z_IS_471_EQ_471(...) \, -#define Z_IS_472_EQ_472(...) \, -#define Z_IS_473_EQ_473(...) \, -#define Z_IS_474_EQ_474(...) \, -#define Z_IS_475_EQ_475(...) \, -#define Z_IS_476_EQ_476(...) \, -#define Z_IS_477_EQ_477(...) \, -#define Z_IS_478_EQ_478(...) \, -#define Z_IS_479_EQ_479(...) \, -#define Z_IS_480_EQ_480(...) \, -#define Z_IS_481_EQ_481(...) \, -#define Z_IS_482_EQ_482(...) \, -#define Z_IS_483_EQ_483(...) \, -#define Z_IS_484_EQ_484(...) \, -#define Z_IS_485_EQ_485(...) \, -#define Z_IS_486_EQ_486(...) \, -#define Z_IS_487_EQ_487(...) \, -#define Z_IS_488_EQ_488(...) \, -#define Z_IS_489_EQ_489(...) \, -#define Z_IS_490_EQ_490(...) \, -#define Z_IS_491_EQ_491(...) \, -#define Z_IS_492_EQ_492(...) \, -#define Z_IS_493_EQ_493(...) \, -#define Z_IS_494_EQ_494(...) \, -#define Z_IS_495_EQ_495(...) \, -#define Z_IS_496_EQ_496(...) \, -#define Z_IS_497_EQ_497(...) \, -#define Z_IS_498_EQ_498(...) \, -#define Z_IS_499_EQ_499(...) \, -#define Z_IS_500_EQ_500(...) \, -#define Z_IS_501_EQ_501(...) \, -#define Z_IS_502_EQ_502(...) \, -#define Z_IS_503_EQ_503(...) \, -#define Z_IS_504_EQ_504(...) \, -#define Z_IS_505_EQ_505(...) \, -#define Z_IS_506_EQ_506(...) \, -#define Z_IS_507_EQ_507(...) \, -#define Z_IS_508_EQ_508(...) \, -#define Z_IS_509_EQ_509(...) \, -#define Z_IS_510_EQ_510(...) \, -#define Z_IS_511_EQ_511(...) \, -#define Z_IS_512_EQ_512(...) \, -#define Z_IS_513_EQ_513(...) \, -#define Z_IS_514_EQ_514(...) \, -#define Z_IS_515_EQ_515(...) \, -#define Z_IS_516_EQ_516(...) \, -#define Z_IS_517_EQ_517(...) \, -#define Z_IS_518_EQ_518(...) \, -#define Z_IS_519_EQ_519(...) \, -#define Z_IS_520_EQ_520(...) \, -#define Z_IS_521_EQ_521(...) \, -#define Z_IS_522_EQ_522(...) \, -#define Z_IS_523_EQ_523(...) \, -#define Z_IS_524_EQ_524(...) \, -#define Z_IS_525_EQ_525(...) \, -#define Z_IS_526_EQ_526(...) \, -#define Z_IS_527_EQ_527(...) \, -#define Z_IS_528_EQ_528(...) \, -#define Z_IS_529_EQ_529(...) \, -#define Z_IS_530_EQ_530(...) \, -#define Z_IS_531_EQ_531(...) \, -#define Z_IS_532_EQ_532(...) \, -#define Z_IS_533_EQ_533(...) \, -#define Z_IS_534_EQ_534(...) \, -#define Z_IS_535_EQ_535(...) \, -#define Z_IS_536_EQ_536(...) \, -#define Z_IS_537_EQ_537(...) \, -#define Z_IS_538_EQ_538(...) \, -#define Z_IS_539_EQ_539(...) \, -#define Z_IS_540_EQ_540(...) \, -#define Z_IS_541_EQ_541(...) \, -#define Z_IS_542_EQ_542(...) \, -#define Z_IS_543_EQ_543(...) \, -#define Z_IS_544_EQ_544(...) \, -#define Z_IS_545_EQ_545(...) \, -#define Z_IS_546_EQ_546(...) \, -#define Z_IS_547_EQ_547(...) \, -#define Z_IS_548_EQ_548(...) \, -#define Z_IS_549_EQ_549(...) \, -#define Z_IS_550_EQ_550(...) \, -#define Z_IS_551_EQ_551(...) \, -#define Z_IS_552_EQ_552(...) \, -#define Z_IS_553_EQ_553(...) \, -#define Z_IS_554_EQ_554(...) \, -#define Z_IS_555_EQ_555(...) \, -#define Z_IS_556_EQ_556(...) \, -#define Z_IS_557_EQ_557(...) \, -#define Z_IS_558_EQ_558(...) \, -#define Z_IS_559_EQ_559(...) \, -#define Z_IS_560_EQ_560(...) \, -#define Z_IS_561_EQ_561(...) \, -#define Z_IS_562_EQ_562(...) \, -#define Z_IS_563_EQ_563(...) \, -#define Z_IS_564_EQ_564(...) \, -#define Z_IS_565_EQ_565(...) \, -#define Z_IS_566_EQ_566(...) \, -#define Z_IS_567_EQ_567(...) \, -#define Z_IS_568_EQ_568(...) \, -#define Z_IS_569_EQ_569(...) \, -#define Z_IS_570_EQ_570(...) \, -#define Z_IS_571_EQ_571(...) \, -#define Z_IS_572_EQ_572(...) \, -#define Z_IS_573_EQ_573(...) \, -#define Z_IS_574_EQ_574(...) \, -#define Z_IS_575_EQ_575(...) \, -#define Z_IS_576_EQ_576(...) \, -#define Z_IS_577_EQ_577(...) \, -#define Z_IS_578_EQ_578(...) \, -#define Z_IS_579_EQ_579(...) \, -#define Z_IS_580_EQ_580(...) \, -#define Z_IS_581_EQ_581(...) \, -#define Z_IS_582_EQ_582(...) \, -#define Z_IS_583_EQ_583(...) \, -#define Z_IS_584_EQ_584(...) \, -#define Z_IS_585_EQ_585(...) \, -#define Z_IS_586_EQ_586(...) \, -#define Z_IS_587_EQ_587(...) \, -#define Z_IS_588_EQ_588(...) \, -#define Z_IS_589_EQ_589(...) \, -#define Z_IS_590_EQ_590(...) \, -#define Z_IS_591_EQ_591(...) \, -#define Z_IS_592_EQ_592(...) \, -#define Z_IS_593_EQ_593(...) \, -#define Z_IS_594_EQ_594(...) \, -#define Z_IS_595_EQ_595(...) \, -#define Z_IS_596_EQ_596(...) \, -#define Z_IS_597_EQ_597(...) \, -#define Z_IS_598_EQ_598(...) \, -#define Z_IS_599_EQ_599(...) \, -#define Z_IS_600_EQ_600(...) \, -#define Z_IS_601_EQ_601(...) \, -#define Z_IS_602_EQ_602(...) \, -#define Z_IS_603_EQ_603(...) \, -#define Z_IS_604_EQ_604(...) \, -#define Z_IS_605_EQ_605(...) \, -#define Z_IS_606_EQ_606(...) \, -#define Z_IS_607_EQ_607(...) \, -#define Z_IS_608_EQ_608(...) \, -#define Z_IS_609_EQ_609(...) \, -#define Z_IS_610_EQ_610(...) \, -#define Z_IS_611_EQ_611(...) \, -#define Z_IS_612_EQ_612(...) \, -#define Z_IS_613_EQ_613(...) \, -#define Z_IS_614_EQ_614(...) \, -#define Z_IS_615_EQ_615(...) \, -#define Z_IS_616_EQ_616(...) \, -#define Z_IS_617_EQ_617(...) \, -#define Z_IS_618_EQ_618(...) \, -#define Z_IS_619_EQ_619(...) \, -#define Z_IS_620_EQ_620(...) \, -#define Z_IS_621_EQ_621(...) \, -#define Z_IS_622_EQ_622(...) \, -#define Z_IS_623_EQ_623(...) \, -#define Z_IS_624_EQ_624(...) \, -#define Z_IS_625_EQ_625(...) \, -#define Z_IS_626_EQ_626(...) \, -#define Z_IS_627_EQ_627(...) \, -#define Z_IS_628_EQ_628(...) \, -#define Z_IS_629_EQ_629(...) \, -#define Z_IS_630_EQ_630(...) \, -#define Z_IS_631_EQ_631(...) \, -#define Z_IS_632_EQ_632(...) \, -#define Z_IS_633_EQ_633(...) \, -#define Z_IS_634_EQ_634(...) \, -#define Z_IS_635_EQ_635(...) \, -#define Z_IS_636_EQ_636(...) \, -#define Z_IS_637_EQ_637(...) \, -#define Z_IS_638_EQ_638(...) \, -#define Z_IS_639_EQ_639(...) \, -#define Z_IS_640_EQ_640(...) \, -#define Z_IS_641_EQ_641(...) \, -#define Z_IS_642_EQ_642(...) \, -#define Z_IS_643_EQ_643(...) \, -#define Z_IS_644_EQ_644(...) \, -#define Z_IS_645_EQ_645(...) \, -#define Z_IS_646_EQ_646(...) \, -#define Z_IS_647_EQ_647(...) \, -#define Z_IS_648_EQ_648(...) \, -#define Z_IS_649_EQ_649(...) \, -#define Z_IS_650_EQ_650(...) \, -#define Z_IS_651_EQ_651(...) \, -#define Z_IS_652_EQ_652(...) \, -#define Z_IS_653_EQ_653(...) \, -#define Z_IS_654_EQ_654(...) \, -#define Z_IS_655_EQ_655(...) \, -#define Z_IS_656_EQ_656(...) \, -#define Z_IS_657_EQ_657(...) \, -#define Z_IS_658_EQ_658(...) \, -#define Z_IS_659_EQ_659(...) \, -#define Z_IS_660_EQ_660(...) \, -#define Z_IS_661_EQ_661(...) \, -#define Z_IS_662_EQ_662(...) \, -#define Z_IS_663_EQ_663(...) \, -#define Z_IS_664_EQ_664(...) \, -#define Z_IS_665_EQ_665(...) \, -#define Z_IS_666_EQ_666(...) \, -#define Z_IS_667_EQ_667(...) \, -#define Z_IS_668_EQ_668(...) \, -#define Z_IS_669_EQ_669(...) \, -#define Z_IS_670_EQ_670(...) \, -#define Z_IS_671_EQ_671(...) \, -#define Z_IS_672_EQ_672(...) \, -#define Z_IS_673_EQ_673(...) \, -#define Z_IS_674_EQ_674(...) \, -#define Z_IS_675_EQ_675(...) \, -#define Z_IS_676_EQ_676(...) \, -#define Z_IS_677_EQ_677(...) \, -#define Z_IS_678_EQ_678(...) \, -#define Z_IS_679_EQ_679(...) \, -#define Z_IS_680_EQ_680(...) \, -#define Z_IS_681_EQ_681(...) \, -#define Z_IS_682_EQ_682(...) \, -#define Z_IS_683_EQ_683(...) \, -#define Z_IS_684_EQ_684(...) \, -#define Z_IS_685_EQ_685(...) \, -#define Z_IS_686_EQ_686(...) \, -#define Z_IS_687_EQ_687(...) \, -#define Z_IS_688_EQ_688(...) \, -#define Z_IS_689_EQ_689(...) \, -#define Z_IS_690_EQ_690(...) \, -#define Z_IS_691_EQ_691(...) \, -#define Z_IS_692_EQ_692(...) \, -#define Z_IS_693_EQ_693(...) \, -#define Z_IS_694_EQ_694(...) \, -#define Z_IS_695_EQ_695(...) \, -#define Z_IS_696_EQ_696(...) \, -#define Z_IS_697_EQ_697(...) \, -#define Z_IS_698_EQ_698(...) \, -#define Z_IS_699_EQ_699(...) \, -#define Z_IS_700_EQ_700(...) \, -#define Z_IS_701_EQ_701(...) \, -#define Z_IS_702_EQ_702(...) \, -#define Z_IS_703_EQ_703(...) \, -#define Z_IS_704_EQ_704(...) \, -#define Z_IS_705_EQ_705(...) \, -#define Z_IS_706_EQ_706(...) \, -#define Z_IS_707_EQ_707(...) \, -#define Z_IS_708_EQ_708(...) \, -#define Z_IS_709_EQ_709(...) \, -#define Z_IS_710_EQ_710(...) \, -#define Z_IS_711_EQ_711(...) \, -#define Z_IS_712_EQ_712(...) \, -#define Z_IS_713_EQ_713(...) \, -#define Z_IS_714_EQ_714(...) \, -#define Z_IS_715_EQ_715(...) \, -#define Z_IS_716_EQ_716(...) \, -#define Z_IS_717_EQ_717(...) \, -#define Z_IS_718_EQ_718(...) \, -#define Z_IS_719_EQ_719(...) \, -#define Z_IS_720_EQ_720(...) \, -#define Z_IS_721_EQ_721(...) \, -#define Z_IS_722_EQ_722(...) \, -#define Z_IS_723_EQ_723(...) \, -#define Z_IS_724_EQ_724(...) \, -#define Z_IS_725_EQ_725(...) \, -#define Z_IS_726_EQ_726(...) \, -#define Z_IS_727_EQ_727(...) \, -#define Z_IS_728_EQ_728(...) \, -#define Z_IS_729_EQ_729(...) \, -#define Z_IS_730_EQ_730(...) \, -#define Z_IS_731_EQ_731(...) \, -#define Z_IS_732_EQ_732(...) \, -#define Z_IS_733_EQ_733(...) \, -#define Z_IS_734_EQ_734(...) \, -#define Z_IS_735_EQ_735(...) \, -#define Z_IS_736_EQ_736(...) \, -#define Z_IS_737_EQ_737(...) \, -#define Z_IS_738_EQ_738(...) \, -#define Z_IS_739_EQ_739(...) \, -#define Z_IS_740_EQ_740(...) \, -#define Z_IS_741_EQ_741(...) \, -#define Z_IS_742_EQ_742(...) \, -#define Z_IS_743_EQ_743(...) \, -#define Z_IS_744_EQ_744(...) \, -#define Z_IS_745_EQ_745(...) \, -#define Z_IS_746_EQ_746(...) \, -#define Z_IS_747_EQ_747(...) \, -#define Z_IS_748_EQ_748(...) \, -#define Z_IS_749_EQ_749(...) \, -#define Z_IS_750_EQ_750(...) \, -#define Z_IS_751_EQ_751(...) \, -#define Z_IS_752_EQ_752(...) \, -#define Z_IS_753_EQ_753(...) \, -#define Z_IS_754_EQ_754(...) \, -#define Z_IS_755_EQ_755(...) \, -#define Z_IS_756_EQ_756(...) \, -#define Z_IS_757_EQ_757(...) \, -#define Z_IS_758_EQ_758(...) \, -#define Z_IS_759_EQ_759(...) \, -#define Z_IS_760_EQ_760(...) \, -#define Z_IS_761_EQ_761(...) \, -#define Z_IS_762_EQ_762(...) \, -#define Z_IS_763_EQ_763(...) \, -#define Z_IS_764_EQ_764(...) \, -#define Z_IS_765_EQ_765(...) \, -#define Z_IS_766_EQ_766(...) \, -#define Z_IS_767_EQ_767(...) \, -#define Z_IS_768_EQ_768(...) \, -#define Z_IS_769_EQ_769(...) \, -#define Z_IS_770_EQ_770(...) \, -#define Z_IS_771_EQ_771(...) \, -#define Z_IS_772_EQ_772(...) \, -#define Z_IS_773_EQ_773(...) \, -#define Z_IS_774_EQ_774(...) \, -#define Z_IS_775_EQ_775(...) \, -#define Z_IS_776_EQ_776(...) \, -#define Z_IS_777_EQ_777(...) \, -#define Z_IS_778_EQ_778(...) \, -#define Z_IS_779_EQ_779(...) \, -#define Z_IS_780_EQ_780(...) \, -#define Z_IS_781_EQ_781(...) \, -#define Z_IS_782_EQ_782(...) \, -#define Z_IS_783_EQ_783(...) \, -#define Z_IS_784_EQ_784(...) \, -#define Z_IS_785_EQ_785(...) \, -#define Z_IS_786_EQ_786(...) \, -#define Z_IS_787_EQ_787(...) \, -#define Z_IS_788_EQ_788(...) \, -#define Z_IS_789_EQ_789(...) \, -#define Z_IS_790_EQ_790(...) \, -#define Z_IS_791_EQ_791(...) \, -#define Z_IS_792_EQ_792(...) \, -#define Z_IS_793_EQ_793(...) \, -#define Z_IS_794_EQ_794(...) \, -#define Z_IS_795_EQ_795(...) \, -#define Z_IS_796_EQ_796(...) \, -#define Z_IS_797_EQ_797(...) \, -#define Z_IS_798_EQ_798(...) \, -#define Z_IS_799_EQ_799(...) \, -#define Z_IS_800_EQ_800(...) \, -#define Z_IS_801_EQ_801(...) \, -#define Z_IS_802_EQ_802(...) \, -#define Z_IS_803_EQ_803(...) \, -#define Z_IS_804_EQ_804(...) \, -#define Z_IS_805_EQ_805(...) \, -#define Z_IS_806_EQ_806(...) \, -#define Z_IS_807_EQ_807(...) \, -#define Z_IS_808_EQ_808(...) \, -#define Z_IS_809_EQ_809(...) \, -#define Z_IS_810_EQ_810(...) \, -#define Z_IS_811_EQ_811(...) \, -#define Z_IS_812_EQ_812(...) \, -#define Z_IS_813_EQ_813(...) \, -#define Z_IS_814_EQ_814(...) \, -#define Z_IS_815_EQ_815(...) \, -#define Z_IS_816_EQ_816(...) \, -#define Z_IS_817_EQ_817(...) \, -#define Z_IS_818_EQ_818(...) \, -#define Z_IS_819_EQ_819(...) \, -#define Z_IS_820_EQ_820(...) \, -#define Z_IS_821_EQ_821(...) \, -#define Z_IS_822_EQ_822(...) \, -#define Z_IS_823_EQ_823(...) \, -#define Z_IS_824_EQ_824(...) \, -#define Z_IS_825_EQ_825(...) \, -#define Z_IS_826_EQ_826(...) \, -#define Z_IS_827_EQ_827(...) \, -#define Z_IS_828_EQ_828(...) \, -#define Z_IS_829_EQ_829(...) \, -#define Z_IS_830_EQ_830(...) \, -#define Z_IS_831_EQ_831(...) \, -#define Z_IS_832_EQ_832(...) \, -#define Z_IS_833_EQ_833(...) \, -#define Z_IS_834_EQ_834(...) \, -#define Z_IS_835_EQ_835(...) \, -#define Z_IS_836_EQ_836(...) \, -#define Z_IS_837_EQ_837(...) \, -#define Z_IS_838_EQ_838(...) \, -#define Z_IS_839_EQ_839(...) \, -#define Z_IS_840_EQ_840(...) \, -#define Z_IS_841_EQ_841(...) \, -#define Z_IS_842_EQ_842(...) \, -#define Z_IS_843_EQ_843(...) \, -#define Z_IS_844_EQ_844(...) \, -#define Z_IS_845_EQ_845(...) \, -#define Z_IS_846_EQ_846(...) \, -#define Z_IS_847_EQ_847(...) \, -#define Z_IS_848_EQ_848(...) \, -#define Z_IS_849_EQ_849(...) \, -#define Z_IS_850_EQ_850(...) \, -#define Z_IS_851_EQ_851(...) \, -#define Z_IS_852_EQ_852(...) \, -#define Z_IS_853_EQ_853(...) \, -#define Z_IS_854_EQ_854(...) \, -#define Z_IS_855_EQ_855(...) \, -#define Z_IS_856_EQ_856(...) \, -#define Z_IS_857_EQ_857(...) \, -#define Z_IS_858_EQ_858(...) \, -#define Z_IS_859_EQ_859(...) \, -#define Z_IS_860_EQ_860(...) \, -#define Z_IS_861_EQ_861(...) \, -#define Z_IS_862_EQ_862(...) \, -#define Z_IS_863_EQ_863(...) \, -#define Z_IS_864_EQ_864(...) \, -#define Z_IS_865_EQ_865(...) \, -#define Z_IS_866_EQ_866(...) \, -#define Z_IS_867_EQ_867(...) \, -#define Z_IS_868_EQ_868(...) \, -#define Z_IS_869_EQ_869(...) \, -#define Z_IS_870_EQ_870(...) \, -#define Z_IS_871_EQ_871(...) \, -#define Z_IS_872_EQ_872(...) \, -#define Z_IS_873_EQ_873(...) \, -#define Z_IS_874_EQ_874(...) \, -#define Z_IS_875_EQ_875(...) \, -#define Z_IS_876_EQ_876(...) \, -#define Z_IS_877_EQ_877(...) \, -#define Z_IS_878_EQ_878(...) \, -#define Z_IS_879_EQ_879(...) \, -#define Z_IS_880_EQ_880(...) \, -#define Z_IS_881_EQ_881(...) \, -#define Z_IS_882_EQ_882(...) \, -#define Z_IS_883_EQ_883(...) \, -#define Z_IS_884_EQ_884(...) \, -#define Z_IS_885_EQ_885(...) \, -#define Z_IS_886_EQ_886(...) \, -#define Z_IS_887_EQ_887(...) \, -#define Z_IS_888_EQ_888(...) \, -#define Z_IS_889_EQ_889(...) \, -#define Z_IS_890_EQ_890(...) \, -#define Z_IS_891_EQ_891(...) \, -#define Z_IS_892_EQ_892(...) \, -#define Z_IS_893_EQ_893(...) \, -#define Z_IS_894_EQ_894(...) \, -#define Z_IS_895_EQ_895(...) \, -#define Z_IS_896_EQ_896(...) \, -#define Z_IS_897_EQ_897(...) \, -#define Z_IS_898_EQ_898(...) \, -#define Z_IS_899_EQ_899(...) \, -#define Z_IS_900_EQ_900(...) \, -#define Z_IS_901_EQ_901(...) \, -#define Z_IS_902_EQ_902(...) \, -#define Z_IS_903_EQ_903(...) \, -#define Z_IS_904_EQ_904(...) \, -#define Z_IS_905_EQ_905(...) \, -#define Z_IS_906_EQ_906(...) \, -#define Z_IS_907_EQ_907(...) \, -#define Z_IS_908_EQ_908(...) \, -#define Z_IS_909_EQ_909(...) \, -#define Z_IS_910_EQ_910(...) \, -#define Z_IS_911_EQ_911(...) \, -#define Z_IS_912_EQ_912(...) \, -#define Z_IS_913_EQ_913(...) \, -#define Z_IS_914_EQ_914(...) \, -#define Z_IS_915_EQ_915(...) \, -#define Z_IS_916_EQ_916(...) \, -#define Z_IS_917_EQ_917(...) \, -#define Z_IS_918_EQ_918(...) \, -#define Z_IS_919_EQ_919(...) \, -#define Z_IS_920_EQ_920(...) \, -#define Z_IS_921_EQ_921(...) \, -#define Z_IS_922_EQ_922(...) \, -#define Z_IS_923_EQ_923(...) \, -#define Z_IS_924_EQ_924(...) \, -#define Z_IS_925_EQ_925(...) \, -#define Z_IS_926_EQ_926(...) \, -#define Z_IS_927_EQ_927(...) \, -#define Z_IS_928_EQ_928(...) \, -#define Z_IS_929_EQ_929(...) \, -#define Z_IS_930_EQ_930(...) \, -#define Z_IS_931_EQ_931(...) \, -#define Z_IS_932_EQ_932(...) \, -#define Z_IS_933_EQ_933(...) \, -#define Z_IS_934_EQ_934(...) \, -#define Z_IS_935_EQ_935(...) \, -#define Z_IS_936_EQ_936(...) \, -#define Z_IS_937_EQ_937(...) \, -#define Z_IS_938_EQ_938(...) \, -#define Z_IS_939_EQ_939(...) \, -#define Z_IS_940_EQ_940(...) \, -#define Z_IS_941_EQ_941(...) \, -#define Z_IS_942_EQ_942(...) \, -#define Z_IS_943_EQ_943(...) \, -#define Z_IS_944_EQ_944(...) \, -#define Z_IS_945_EQ_945(...) \, -#define Z_IS_946_EQ_946(...) \, -#define Z_IS_947_EQ_947(...) \, -#define Z_IS_948_EQ_948(...) \, -#define Z_IS_949_EQ_949(...) \, -#define Z_IS_950_EQ_950(...) \, -#define Z_IS_951_EQ_951(...) \, -#define Z_IS_952_EQ_952(...) \, -#define Z_IS_953_EQ_953(...) \, -#define Z_IS_954_EQ_954(...) \, -#define Z_IS_955_EQ_955(...) \, -#define Z_IS_956_EQ_956(...) \, -#define Z_IS_957_EQ_957(...) \, -#define Z_IS_958_EQ_958(...) \, -#define Z_IS_959_EQ_959(...) \, -#define Z_IS_960_EQ_960(...) \, -#define Z_IS_961_EQ_961(...) \, -#define Z_IS_962_EQ_962(...) \, -#define Z_IS_963_EQ_963(...) \, -#define Z_IS_964_EQ_964(...) \, -#define Z_IS_965_EQ_965(...) \, -#define Z_IS_966_EQ_966(...) \, -#define Z_IS_967_EQ_967(...) \, -#define Z_IS_968_EQ_968(...) \, -#define Z_IS_969_EQ_969(...) \, -#define Z_IS_970_EQ_970(...) \, -#define Z_IS_971_EQ_971(...) \, -#define Z_IS_972_EQ_972(...) \, -#define Z_IS_973_EQ_973(...) \, -#define Z_IS_974_EQ_974(...) \, -#define Z_IS_975_EQ_975(...) \, -#define Z_IS_976_EQ_976(...) \, -#define Z_IS_977_EQ_977(...) \, -#define Z_IS_978_EQ_978(...) \, -#define Z_IS_979_EQ_979(...) \, -#define Z_IS_980_EQ_980(...) \, -#define Z_IS_981_EQ_981(...) \, -#define Z_IS_982_EQ_982(...) \, -#define Z_IS_983_EQ_983(...) \, -#define Z_IS_984_EQ_984(...) \, -#define Z_IS_985_EQ_985(...) \, -#define Z_IS_986_EQ_986(...) \, -#define Z_IS_987_EQ_987(...) \, -#define Z_IS_988_EQ_988(...) \, -#define Z_IS_989_EQ_989(...) \, -#define Z_IS_990_EQ_990(...) \, -#define Z_IS_991_EQ_991(...) \, -#define Z_IS_992_EQ_992(...) \, -#define Z_IS_993_EQ_993(...) \, -#define Z_IS_994_EQ_994(...) \, -#define Z_IS_995_EQ_995(...) \, -#define Z_IS_996_EQ_996(...) \, -#define Z_IS_997_EQ_997(...) \, -#define Z_IS_998_EQ_998(...) \, -#define Z_IS_999_EQ_999(...) \, -#define Z_IS_1000_EQ_1000(...) \, -#define Z_IS_1001_EQ_1001(...) \, -#define Z_IS_1002_EQ_1002(...) \, -#define Z_IS_1003_EQ_1003(...) \, -#define Z_IS_1004_EQ_1004(...) \, -#define Z_IS_1005_EQ_1005(...) \, -#define Z_IS_1006_EQ_1006(...) \, -#define Z_IS_1007_EQ_1007(...) \, -#define Z_IS_1008_EQ_1008(...) \, -#define Z_IS_1009_EQ_1009(...) \, -#define Z_IS_1010_EQ_1010(...) \, -#define Z_IS_1011_EQ_1011(...) \, -#define Z_IS_1012_EQ_1012(...) \, -#define Z_IS_1013_EQ_1013(...) \, -#define Z_IS_1014_EQ_1014(...) \, -#define Z_IS_1015_EQ_1015(...) \, -#define Z_IS_1016_EQ_1016(...) \, -#define Z_IS_1017_EQ_1017(...) \, -#define Z_IS_1018_EQ_1018(...) \, -#define Z_IS_1019_EQ_1019(...) \, -#define Z_IS_1020_EQ_1020(...) \, -#define Z_IS_1021_EQ_1021(...) \, -#define Z_IS_1022_EQ_1022(...) \, -#define Z_IS_1023_EQ_1023(...) \, -#define Z_IS_1024_EQ_1024(...) \, -#define Z_IS_1025_EQ_1025(...) \, -#define Z_IS_1026_EQ_1026(...) \, -#define Z_IS_1027_EQ_1027(...) \, -#define Z_IS_1028_EQ_1028(...) \, -#define Z_IS_1029_EQ_1029(...) \, -#define Z_IS_1030_EQ_1030(...) \, -#define Z_IS_1031_EQ_1031(...) \, -#define Z_IS_1032_EQ_1032(...) \, -#define Z_IS_1033_EQ_1033(...) \, -#define Z_IS_1034_EQ_1034(...) \, -#define Z_IS_1035_EQ_1035(...) \, -#define Z_IS_1036_EQ_1036(...) \, -#define Z_IS_1037_EQ_1037(...) \, -#define Z_IS_1038_EQ_1038(...) \, -#define Z_IS_1039_EQ_1039(...) \, -#define Z_IS_1040_EQ_1040(...) \, -#define Z_IS_1041_EQ_1041(...) \, -#define Z_IS_1042_EQ_1042(...) \, -#define Z_IS_1043_EQ_1043(...) \, -#define Z_IS_1044_EQ_1044(...) \, -#define Z_IS_1045_EQ_1045(...) \, -#define Z_IS_1046_EQ_1046(...) \, -#define Z_IS_1047_EQ_1047(...) \, -#define Z_IS_1048_EQ_1048(...) \, -#define Z_IS_1049_EQ_1049(...) \, -#define Z_IS_1050_EQ_1050(...) \, -#define Z_IS_1051_EQ_1051(...) \, -#define Z_IS_1052_EQ_1052(...) \, -#define Z_IS_1053_EQ_1053(...) \, -#define Z_IS_1054_EQ_1054(...) \, -#define Z_IS_1055_EQ_1055(...) \, -#define Z_IS_1056_EQ_1056(...) \, -#define Z_IS_1057_EQ_1057(...) \, -#define Z_IS_1058_EQ_1058(...) \, -#define Z_IS_1059_EQ_1059(...) \, -#define Z_IS_1060_EQ_1060(...) \, -#define Z_IS_1061_EQ_1061(...) \, -#define Z_IS_1062_EQ_1062(...) \, -#define Z_IS_1063_EQ_1063(...) \, -#define Z_IS_1064_EQ_1064(...) \, -#define Z_IS_1065_EQ_1065(...) \, -#define Z_IS_1066_EQ_1066(...) \, -#define Z_IS_1067_EQ_1067(...) \, -#define Z_IS_1068_EQ_1068(...) \, -#define Z_IS_1069_EQ_1069(...) \, -#define Z_IS_1070_EQ_1070(...) \, -#define Z_IS_1071_EQ_1071(...) \, -#define Z_IS_1072_EQ_1072(...) \, -#define Z_IS_1073_EQ_1073(...) \, -#define Z_IS_1074_EQ_1074(...) \, -#define Z_IS_1075_EQ_1075(...) \, -#define Z_IS_1076_EQ_1076(...) \, -#define Z_IS_1077_EQ_1077(...) \, -#define Z_IS_1078_EQ_1078(...) \, -#define Z_IS_1079_EQ_1079(...) \, -#define Z_IS_1080_EQ_1080(...) \, -#define Z_IS_1081_EQ_1081(...) \, -#define Z_IS_1082_EQ_1082(...) \, -#define Z_IS_1083_EQ_1083(...) \, -#define Z_IS_1084_EQ_1084(...) \, -#define Z_IS_1085_EQ_1085(...) \, -#define Z_IS_1086_EQ_1086(...) \, -#define Z_IS_1087_EQ_1087(...) \, -#define Z_IS_1088_EQ_1088(...) \, -#define Z_IS_1089_EQ_1089(...) \, -#define Z_IS_1090_EQ_1090(...) \, -#define Z_IS_1091_EQ_1091(...) \, -#define Z_IS_1092_EQ_1092(...) \, -#define Z_IS_1093_EQ_1093(...) \, -#define Z_IS_1094_EQ_1094(...) \, -#define Z_IS_1095_EQ_1095(...) \, -#define Z_IS_1096_EQ_1096(...) \, -#define Z_IS_1097_EQ_1097(...) \, -#define Z_IS_1098_EQ_1098(...) \, -#define Z_IS_1099_EQ_1099(...) \, -#define Z_IS_1100_EQ_1100(...) \, -#define Z_IS_1101_EQ_1101(...) \, -#define Z_IS_1102_EQ_1102(...) \, -#define Z_IS_1103_EQ_1103(...) \, -#define Z_IS_1104_EQ_1104(...) \, -#define Z_IS_1105_EQ_1105(...) \, -#define Z_IS_1106_EQ_1106(...) \, -#define Z_IS_1107_EQ_1107(...) \, -#define Z_IS_1108_EQ_1108(...) \, -#define Z_IS_1109_EQ_1109(...) \, -#define Z_IS_1110_EQ_1110(...) \, -#define Z_IS_1111_EQ_1111(...) \, -#define Z_IS_1112_EQ_1112(...) \, -#define Z_IS_1113_EQ_1113(...) \, -#define Z_IS_1114_EQ_1114(...) \, -#define Z_IS_1115_EQ_1115(...) \, -#define Z_IS_1116_EQ_1116(...) \, -#define Z_IS_1117_EQ_1117(...) \, -#define Z_IS_1118_EQ_1118(...) \, -#define Z_IS_1119_EQ_1119(...) \, -#define Z_IS_1120_EQ_1120(...) \, -#define Z_IS_1121_EQ_1121(...) \, -#define Z_IS_1122_EQ_1122(...) \, -#define Z_IS_1123_EQ_1123(...) \, -#define Z_IS_1124_EQ_1124(...) \, -#define Z_IS_1125_EQ_1125(...) \, -#define Z_IS_1126_EQ_1126(...) \, -#define Z_IS_1127_EQ_1127(...) \, -#define Z_IS_1128_EQ_1128(...) \, -#define Z_IS_1129_EQ_1129(...) \, -#define Z_IS_1130_EQ_1130(...) \, -#define Z_IS_1131_EQ_1131(...) \, -#define Z_IS_1132_EQ_1132(...) \, -#define Z_IS_1133_EQ_1133(...) \, -#define Z_IS_1134_EQ_1134(...) \, -#define Z_IS_1135_EQ_1135(...) \, -#define Z_IS_1136_EQ_1136(...) \, -#define Z_IS_1137_EQ_1137(...) \, -#define Z_IS_1138_EQ_1138(...) \, -#define Z_IS_1139_EQ_1139(...) \, -#define Z_IS_1140_EQ_1140(...) \, -#define Z_IS_1141_EQ_1141(...) \, -#define Z_IS_1142_EQ_1142(...) \, -#define Z_IS_1143_EQ_1143(...) \, -#define Z_IS_1144_EQ_1144(...) \, -#define Z_IS_1145_EQ_1145(...) \, -#define Z_IS_1146_EQ_1146(...) \, -#define Z_IS_1147_EQ_1147(...) \, -#define Z_IS_1148_EQ_1148(...) \, -#define Z_IS_1149_EQ_1149(...) \, -#define Z_IS_1150_EQ_1150(...) \, -#define Z_IS_1151_EQ_1151(...) \, -#define Z_IS_1152_EQ_1152(...) \, -#define Z_IS_1153_EQ_1153(...) \, -#define Z_IS_1154_EQ_1154(...) \, -#define Z_IS_1155_EQ_1155(...) \, -#define Z_IS_1156_EQ_1156(...) \, -#define Z_IS_1157_EQ_1157(...) \, -#define Z_IS_1158_EQ_1158(...) \, -#define Z_IS_1159_EQ_1159(...) \, -#define Z_IS_1160_EQ_1160(...) \, -#define Z_IS_1161_EQ_1161(...) \, -#define Z_IS_1162_EQ_1162(...) \, -#define Z_IS_1163_EQ_1163(...) \, -#define Z_IS_1164_EQ_1164(...) \, -#define Z_IS_1165_EQ_1165(...) \, -#define Z_IS_1166_EQ_1166(...) \, -#define Z_IS_1167_EQ_1167(...) \, -#define Z_IS_1168_EQ_1168(...) \, -#define Z_IS_1169_EQ_1169(...) \, -#define Z_IS_1170_EQ_1170(...) \, -#define Z_IS_1171_EQ_1171(...) \, -#define Z_IS_1172_EQ_1172(...) \, -#define Z_IS_1173_EQ_1173(...) \, -#define Z_IS_1174_EQ_1174(...) \, -#define Z_IS_1175_EQ_1175(...) \, -#define Z_IS_1176_EQ_1176(...) \, -#define Z_IS_1177_EQ_1177(...) \, -#define Z_IS_1178_EQ_1178(...) \, -#define Z_IS_1179_EQ_1179(...) \, -#define Z_IS_1180_EQ_1180(...) \, -#define Z_IS_1181_EQ_1181(...) \, -#define Z_IS_1182_EQ_1182(...) \, -#define Z_IS_1183_EQ_1183(...) \, -#define Z_IS_1184_EQ_1184(...) \, -#define Z_IS_1185_EQ_1185(...) \, -#define Z_IS_1186_EQ_1186(...) \, -#define Z_IS_1187_EQ_1187(...) \, -#define Z_IS_1188_EQ_1188(...) \, -#define Z_IS_1189_EQ_1189(...) \, -#define Z_IS_1190_EQ_1190(...) \, -#define Z_IS_1191_EQ_1191(...) \, -#define Z_IS_1192_EQ_1192(...) \, -#define Z_IS_1193_EQ_1193(...) \, -#define Z_IS_1194_EQ_1194(...) \, -#define Z_IS_1195_EQ_1195(...) \, -#define Z_IS_1196_EQ_1196(...) \, -#define Z_IS_1197_EQ_1197(...) \, -#define Z_IS_1198_EQ_1198(...) \, -#define Z_IS_1199_EQ_1199(...) \, -#define Z_IS_1200_EQ_1200(...) \, -#define Z_IS_1201_EQ_1201(...) \, -#define Z_IS_1202_EQ_1202(...) \, -#define Z_IS_1203_EQ_1203(...) \, -#define Z_IS_1204_EQ_1204(...) \, -#define Z_IS_1205_EQ_1205(...) \, -#define Z_IS_1206_EQ_1206(...) \, -#define Z_IS_1207_EQ_1207(...) \, -#define Z_IS_1208_EQ_1208(...) \, -#define Z_IS_1209_EQ_1209(...) \, -#define Z_IS_1210_EQ_1210(...) \, -#define Z_IS_1211_EQ_1211(...) \, -#define Z_IS_1212_EQ_1212(...) \, -#define Z_IS_1213_EQ_1213(...) \, -#define Z_IS_1214_EQ_1214(...) \, -#define Z_IS_1215_EQ_1215(...) \, -#define Z_IS_1216_EQ_1216(...) \, -#define Z_IS_1217_EQ_1217(...) \, -#define Z_IS_1218_EQ_1218(...) \, -#define Z_IS_1219_EQ_1219(...) \, -#define Z_IS_1220_EQ_1220(...) \, -#define Z_IS_1221_EQ_1221(...) \, -#define Z_IS_1222_EQ_1222(...) \, -#define Z_IS_1223_EQ_1223(...) \, -#define Z_IS_1224_EQ_1224(...) \, -#define Z_IS_1225_EQ_1225(...) \, -#define Z_IS_1226_EQ_1226(...) \, -#define Z_IS_1227_EQ_1227(...) \, -#define Z_IS_1228_EQ_1228(...) \, -#define Z_IS_1229_EQ_1229(...) \, -#define Z_IS_1230_EQ_1230(...) \, -#define Z_IS_1231_EQ_1231(...) \, -#define Z_IS_1232_EQ_1232(...) \, -#define Z_IS_1233_EQ_1233(...) \, -#define Z_IS_1234_EQ_1234(...) \, -#define Z_IS_1235_EQ_1235(...) \, -#define Z_IS_1236_EQ_1236(...) \, -#define Z_IS_1237_EQ_1237(...) \, -#define Z_IS_1238_EQ_1238(...) \, -#define Z_IS_1239_EQ_1239(...) \, -#define Z_IS_1240_EQ_1240(...) \, -#define Z_IS_1241_EQ_1241(...) \, -#define Z_IS_1242_EQ_1242(...) \, -#define Z_IS_1243_EQ_1243(...) \, -#define Z_IS_1244_EQ_1244(...) \, -#define Z_IS_1245_EQ_1245(...) \, -#define Z_IS_1246_EQ_1246(...) \, -#define Z_IS_1247_EQ_1247(...) \, -#define Z_IS_1248_EQ_1248(...) \, -#define Z_IS_1249_EQ_1249(...) \, -#define Z_IS_1250_EQ_1250(...) \, -#define Z_IS_1251_EQ_1251(...) \, -#define Z_IS_1252_EQ_1252(...) \, -#define Z_IS_1253_EQ_1253(...) \, -#define Z_IS_1254_EQ_1254(...) \, -#define Z_IS_1255_EQ_1255(...) \, -#define Z_IS_1256_EQ_1256(...) \, -#define Z_IS_1257_EQ_1257(...) \, -#define Z_IS_1258_EQ_1258(...) \, -#define Z_IS_1259_EQ_1259(...) \, -#define Z_IS_1260_EQ_1260(...) \, -#define Z_IS_1261_EQ_1261(...) \, -#define Z_IS_1262_EQ_1262(...) \, -#define Z_IS_1263_EQ_1263(...) \, -#define Z_IS_1264_EQ_1264(...) \, -#define Z_IS_1265_EQ_1265(...) \, -#define Z_IS_1266_EQ_1266(...) \, -#define Z_IS_1267_EQ_1267(...) \, -#define Z_IS_1268_EQ_1268(...) \, -#define Z_IS_1269_EQ_1269(...) \, -#define Z_IS_1270_EQ_1270(...) \, -#define Z_IS_1271_EQ_1271(...) \, -#define Z_IS_1272_EQ_1272(...) \, -#define Z_IS_1273_EQ_1273(...) \, -#define Z_IS_1274_EQ_1274(...) \, -#define Z_IS_1275_EQ_1275(...) \, -#define Z_IS_1276_EQ_1276(...) \, -#define Z_IS_1277_EQ_1277(...) \, -#define Z_IS_1278_EQ_1278(...) \, -#define Z_IS_1279_EQ_1279(...) \, -#define Z_IS_1280_EQ_1280(...) \, -#define Z_IS_1281_EQ_1281(...) \, -#define Z_IS_1282_EQ_1282(...) \, -#define Z_IS_1283_EQ_1283(...) \, -#define Z_IS_1284_EQ_1284(...) \, -#define Z_IS_1285_EQ_1285(...) \, -#define Z_IS_1286_EQ_1286(...) \, -#define Z_IS_1287_EQ_1287(...) \, -#define Z_IS_1288_EQ_1288(...) \, -#define Z_IS_1289_EQ_1289(...) \, -#define Z_IS_1290_EQ_1290(...) \, -#define Z_IS_1291_EQ_1291(...) \, -#define Z_IS_1292_EQ_1292(...) \, -#define Z_IS_1293_EQ_1293(...) \, -#define Z_IS_1294_EQ_1294(...) \, -#define Z_IS_1295_EQ_1295(...) \, -#define Z_IS_1296_EQ_1296(...) \, -#define Z_IS_1297_EQ_1297(...) \, -#define Z_IS_1298_EQ_1298(...) \, -#define Z_IS_1299_EQ_1299(...) \, -#define Z_IS_1300_EQ_1300(...) \, -#define Z_IS_1301_EQ_1301(...) \, -#define Z_IS_1302_EQ_1302(...) \, -#define Z_IS_1303_EQ_1303(...) \, -#define Z_IS_1304_EQ_1304(...) \, -#define Z_IS_1305_EQ_1305(...) \, -#define Z_IS_1306_EQ_1306(...) \, -#define Z_IS_1307_EQ_1307(...) \, -#define Z_IS_1308_EQ_1308(...) \, -#define Z_IS_1309_EQ_1309(...) \, -#define Z_IS_1310_EQ_1310(...) \, -#define Z_IS_1311_EQ_1311(...) \, -#define Z_IS_1312_EQ_1312(...) \, -#define Z_IS_1313_EQ_1313(...) \, -#define Z_IS_1314_EQ_1314(...) \, -#define Z_IS_1315_EQ_1315(...) \, -#define Z_IS_1316_EQ_1316(...) \, -#define Z_IS_1317_EQ_1317(...) \, -#define Z_IS_1318_EQ_1318(...) \, -#define Z_IS_1319_EQ_1319(...) \, -#define Z_IS_1320_EQ_1320(...) \, -#define Z_IS_1321_EQ_1321(...) \, -#define Z_IS_1322_EQ_1322(...) \, -#define Z_IS_1323_EQ_1323(...) \, -#define Z_IS_1324_EQ_1324(...) \, -#define Z_IS_1325_EQ_1325(...) \, -#define Z_IS_1326_EQ_1326(...) \, -#define Z_IS_1327_EQ_1327(...) \, -#define Z_IS_1328_EQ_1328(...) \, -#define Z_IS_1329_EQ_1329(...) \, -#define Z_IS_1330_EQ_1330(...) \, -#define Z_IS_1331_EQ_1331(...) \, -#define Z_IS_1332_EQ_1332(...) \, -#define Z_IS_1333_EQ_1333(...) \, -#define Z_IS_1334_EQ_1334(...) \, -#define Z_IS_1335_EQ_1335(...) \, -#define Z_IS_1336_EQ_1336(...) \, -#define Z_IS_1337_EQ_1337(...) \, -#define Z_IS_1338_EQ_1338(...) \, -#define Z_IS_1339_EQ_1339(...) \, -#define Z_IS_1340_EQ_1340(...) \, -#define Z_IS_1341_EQ_1341(...) \, -#define Z_IS_1342_EQ_1342(...) \, -#define Z_IS_1343_EQ_1343(...) \, -#define Z_IS_1344_EQ_1344(...) \, -#define Z_IS_1345_EQ_1345(...) \, -#define Z_IS_1346_EQ_1346(...) \, -#define Z_IS_1347_EQ_1347(...) \, -#define Z_IS_1348_EQ_1348(...) \, -#define Z_IS_1349_EQ_1349(...) \, -#define Z_IS_1350_EQ_1350(...) \, -#define Z_IS_1351_EQ_1351(...) \, -#define Z_IS_1352_EQ_1352(...) \, -#define Z_IS_1353_EQ_1353(...) \, -#define Z_IS_1354_EQ_1354(...) \, -#define Z_IS_1355_EQ_1355(...) \, -#define Z_IS_1356_EQ_1356(...) \, -#define Z_IS_1357_EQ_1357(...) \, -#define Z_IS_1358_EQ_1358(...) \, -#define Z_IS_1359_EQ_1359(...) \, -#define Z_IS_1360_EQ_1360(...) \, -#define Z_IS_1361_EQ_1361(...) \, -#define Z_IS_1362_EQ_1362(...) \, -#define Z_IS_1363_EQ_1363(...) \, -#define Z_IS_1364_EQ_1364(...) \, -#define Z_IS_1365_EQ_1365(...) \, -#define Z_IS_1366_EQ_1366(...) \, -#define Z_IS_1367_EQ_1367(...) \, -#define Z_IS_1368_EQ_1368(...) \, -#define Z_IS_1369_EQ_1369(...) \, -#define Z_IS_1370_EQ_1370(...) \, -#define Z_IS_1371_EQ_1371(...) \, -#define Z_IS_1372_EQ_1372(...) \, -#define Z_IS_1373_EQ_1373(...) \, -#define Z_IS_1374_EQ_1374(...) \, -#define Z_IS_1375_EQ_1375(...) \, -#define Z_IS_1376_EQ_1376(...) \, -#define Z_IS_1377_EQ_1377(...) \, -#define Z_IS_1378_EQ_1378(...) \, -#define Z_IS_1379_EQ_1379(...) \, -#define Z_IS_1380_EQ_1380(...) \, -#define Z_IS_1381_EQ_1381(...) \, -#define Z_IS_1382_EQ_1382(...) \, -#define Z_IS_1383_EQ_1383(...) \, -#define Z_IS_1384_EQ_1384(...) \, -#define Z_IS_1385_EQ_1385(...) \, -#define Z_IS_1386_EQ_1386(...) \, -#define Z_IS_1387_EQ_1387(...) \, -#define Z_IS_1388_EQ_1388(...) \, -#define Z_IS_1389_EQ_1389(...) \, -#define Z_IS_1390_EQ_1390(...) \, -#define Z_IS_1391_EQ_1391(...) \, -#define Z_IS_1392_EQ_1392(...) \, -#define Z_IS_1393_EQ_1393(...) \, -#define Z_IS_1394_EQ_1394(...) \, -#define Z_IS_1395_EQ_1395(...) \, -#define Z_IS_1396_EQ_1396(...) \, -#define Z_IS_1397_EQ_1397(...) \, -#define Z_IS_1398_EQ_1398(...) \, -#define Z_IS_1399_EQ_1399(...) \, -#define Z_IS_1400_EQ_1400(...) \, -#define Z_IS_1401_EQ_1401(...) \, -#define Z_IS_1402_EQ_1402(...) \, -#define Z_IS_1403_EQ_1403(...) \, -#define Z_IS_1404_EQ_1404(...) \, -#define Z_IS_1405_EQ_1405(...) \, -#define Z_IS_1406_EQ_1406(...) \, -#define Z_IS_1407_EQ_1407(...) \, -#define Z_IS_1408_EQ_1408(...) \, -#define Z_IS_1409_EQ_1409(...) \, -#define Z_IS_1410_EQ_1410(...) \, -#define Z_IS_1411_EQ_1411(...) \, -#define Z_IS_1412_EQ_1412(...) \, -#define Z_IS_1413_EQ_1413(...) \, -#define Z_IS_1414_EQ_1414(...) \, -#define Z_IS_1415_EQ_1415(...) \, -#define Z_IS_1416_EQ_1416(...) \, -#define Z_IS_1417_EQ_1417(...) \, -#define Z_IS_1418_EQ_1418(...) \, -#define Z_IS_1419_EQ_1419(...) \, -#define Z_IS_1420_EQ_1420(...) \, -#define Z_IS_1421_EQ_1421(...) \, -#define Z_IS_1422_EQ_1422(...) \, -#define Z_IS_1423_EQ_1423(...) \, -#define Z_IS_1424_EQ_1424(...) \, -#define Z_IS_1425_EQ_1425(...) \, -#define Z_IS_1426_EQ_1426(...) \, -#define Z_IS_1427_EQ_1427(...) \, -#define Z_IS_1428_EQ_1428(...) \, -#define Z_IS_1429_EQ_1429(...) \, -#define Z_IS_1430_EQ_1430(...) \, -#define Z_IS_1431_EQ_1431(...) \, -#define Z_IS_1432_EQ_1432(...) \, -#define Z_IS_1433_EQ_1433(...) \, -#define Z_IS_1434_EQ_1434(...) \, -#define Z_IS_1435_EQ_1435(...) \, -#define Z_IS_1436_EQ_1436(...) \, -#define Z_IS_1437_EQ_1437(...) \, -#define Z_IS_1438_EQ_1438(...) \, -#define Z_IS_1439_EQ_1439(...) \, -#define Z_IS_1440_EQ_1440(...) \, -#define Z_IS_1441_EQ_1441(...) \, -#define Z_IS_1442_EQ_1442(...) \, -#define Z_IS_1443_EQ_1443(...) \, -#define Z_IS_1444_EQ_1444(...) \, -#define Z_IS_1445_EQ_1445(...) \, -#define Z_IS_1446_EQ_1446(...) \, -#define Z_IS_1447_EQ_1447(...) \, -#define Z_IS_1448_EQ_1448(...) \, -#define Z_IS_1449_EQ_1449(...) \, -#define Z_IS_1450_EQ_1450(...) \, -#define Z_IS_1451_EQ_1451(...) \, -#define Z_IS_1452_EQ_1452(...) \, -#define Z_IS_1453_EQ_1453(...) \, -#define Z_IS_1454_EQ_1454(...) \, -#define Z_IS_1455_EQ_1455(...) \, -#define Z_IS_1456_EQ_1456(...) \, -#define Z_IS_1457_EQ_1457(...) \, -#define Z_IS_1458_EQ_1458(...) \, -#define Z_IS_1459_EQ_1459(...) \, -#define Z_IS_1460_EQ_1460(...) \, -#define Z_IS_1461_EQ_1461(...) \, -#define Z_IS_1462_EQ_1462(...) \, -#define Z_IS_1463_EQ_1463(...) \, -#define Z_IS_1464_EQ_1464(...) \, -#define Z_IS_1465_EQ_1465(...) \, -#define Z_IS_1466_EQ_1466(...) \, -#define Z_IS_1467_EQ_1467(...) \, -#define Z_IS_1468_EQ_1468(...) \, -#define Z_IS_1469_EQ_1469(...) \, -#define Z_IS_1470_EQ_1470(...) \, -#define Z_IS_1471_EQ_1471(...) \, -#define Z_IS_1472_EQ_1472(...) \, -#define Z_IS_1473_EQ_1473(...) \, -#define Z_IS_1474_EQ_1474(...) \, -#define Z_IS_1475_EQ_1475(...) \, -#define Z_IS_1476_EQ_1476(...) \, -#define Z_IS_1477_EQ_1477(...) \, -#define Z_IS_1478_EQ_1478(...) \, -#define Z_IS_1479_EQ_1479(...) \, -#define Z_IS_1480_EQ_1480(...) \, -#define Z_IS_1481_EQ_1481(...) \, -#define Z_IS_1482_EQ_1482(...) \, -#define Z_IS_1483_EQ_1483(...) \, -#define Z_IS_1484_EQ_1484(...) \, -#define Z_IS_1485_EQ_1485(...) \, -#define Z_IS_1486_EQ_1486(...) \, -#define Z_IS_1487_EQ_1487(...) \, -#define Z_IS_1488_EQ_1488(...) \, -#define Z_IS_1489_EQ_1489(...) \, -#define Z_IS_1490_EQ_1490(...) \, -#define Z_IS_1491_EQ_1491(...) \, -#define Z_IS_1492_EQ_1492(...) \, -#define Z_IS_1493_EQ_1493(...) \, -#define Z_IS_1494_EQ_1494(...) \, -#define Z_IS_1495_EQ_1495(...) \, -#define Z_IS_1496_EQ_1496(...) \, -#define Z_IS_1497_EQ_1497(...) \, -#define Z_IS_1498_EQ_1498(...) \, -#define Z_IS_1499_EQ_1499(...) \, -#define Z_IS_1500_EQ_1500(...) \, -#define Z_IS_1501_EQ_1501(...) \, -#define Z_IS_1502_EQ_1502(...) \, -#define Z_IS_1503_EQ_1503(...) \, -#define Z_IS_1504_EQ_1504(...) \, -#define Z_IS_1505_EQ_1505(...) \, -#define Z_IS_1506_EQ_1506(...) \, -#define Z_IS_1507_EQ_1507(...) \, -#define Z_IS_1508_EQ_1508(...) \, -#define Z_IS_1509_EQ_1509(...) \, -#define Z_IS_1510_EQ_1510(...) \, -#define Z_IS_1511_EQ_1511(...) \, -#define Z_IS_1512_EQ_1512(...) \, -#define Z_IS_1513_EQ_1513(...) \, -#define Z_IS_1514_EQ_1514(...) \, -#define Z_IS_1515_EQ_1515(...) \, -#define Z_IS_1516_EQ_1516(...) \, -#define Z_IS_1517_EQ_1517(...) \, -#define Z_IS_1518_EQ_1518(...) \, -#define Z_IS_1519_EQ_1519(...) \, -#define Z_IS_1520_EQ_1520(...) \, -#define Z_IS_1521_EQ_1521(...) \, -#define Z_IS_1522_EQ_1522(...) \, -#define Z_IS_1523_EQ_1523(...) \, -#define Z_IS_1524_EQ_1524(...) \, -#define Z_IS_1525_EQ_1525(...) \, -#define Z_IS_1526_EQ_1526(...) \, -#define Z_IS_1527_EQ_1527(...) \, -#define Z_IS_1528_EQ_1528(...) \, -#define Z_IS_1529_EQ_1529(...) \, -#define Z_IS_1530_EQ_1530(...) \, -#define Z_IS_1531_EQ_1531(...) \, -#define Z_IS_1532_EQ_1532(...) \, -#define Z_IS_1533_EQ_1533(...) \, -#define Z_IS_1534_EQ_1534(...) \, -#define Z_IS_1535_EQ_1535(...) \, -#define Z_IS_1536_EQ_1536(...) \, -#define Z_IS_1537_EQ_1537(...) \, -#define Z_IS_1538_EQ_1538(...) \, -#define Z_IS_1539_EQ_1539(...) \, -#define Z_IS_1540_EQ_1540(...) \, -#define Z_IS_1541_EQ_1541(...) \, -#define Z_IS_1542_EQ_1542(...) \, -#define Z_IS_1543_EQ_1543(...) \, -#define Z_IS_1544_EQ_1544(...) \, -#define Z_IS_1545_EQ_1545(...) \, -#define Z_IS_1546_EQ_1546(...) \, -#define Z_IS_1547_EQ_1547(...) \, -#define Z_IS_1548_EQ_1548(...) \, -#define Z_IS_1549_EQ_1549(...) \, -#define Z_IS_1550_EQ_1550(...) \, -#define Z_IS_1551_EQ_1551(...) \, -#define Z_IS_1552_EQ_1552(...) \, -#define Z_IS_1553_EQ_1553(...) \, -#define Z_IS_1554_EQ_1554(...) \, -#define Z_IS_1555_EQ_1555(...) \, -#define Z_IS_1556_EQ_1556(...) \, -#define Z_IS_1557_EQ_1557(...) \, -#define Z_IS_1558_EQ_1558(...) \, -#define Z_IS_1559_EQ_1559(...) \, -#define Z_IS_1560_EQ_1560(...) \, -#define Z_IS_1561_EQ_1561(...) \, -#define Z_IS_1562_EQ_1562(...) \, -#define Z_IS_1563_EQ_1563(...) \, -#define Z_IS_1564_EQ_1564(...) \, -#define Z_IS_1565_EQ_1565(...) \, -#define Z_IS_1566_EQ_1566(...) \, -#define Z_IS_1567_EQ_1567(...) \, -#define Z_IS_1568_EQ_1568(...) \, -#define Z_IS_1569_EQ_1569(...) \, -#define Z_IS_1570_EQ_1570(...) \, -#define Z_IS_1571_EQ_1571(...) \, -#define Z_IS_1572_EQ_1572(...) \, -#define Z_IS_1573_EQ_1573(...) \, -#define Z_IS_1574_EQ_1574(...) \, -#define Z_IS_1575_EQ_1575(...) \, -#define Z_IS_1576_EQ_1576(...) \, -#define Z_IS_1577_EQ_1577(...) \, -#define Z_IS_1578_EQ_1578(...) \, -#define Z_IS_1579_EQ_1579(...) \, -#define Z_IS_1580_EQ_1580(...) \, -#define Z_IS_1581_EQ_1581(...) \, -#define Z_IS_1582_EQ_1582(...) \, -#define Z_IS_1583_EQ_1583(...) \, -#define Z_IS_1584_EQ_1584(...) \, -#define Z_IS_1585_EQ_1585(...) \, -#define Z_IS_1586_EQ_1586(...) \, -#define Z_IS_1587_EQ_1587(...) \, -#define Z_IS_1588_EQ_1588(...) \, -#define Z_IS_1589_EQ_1589(...) \, -#define Z_IS_1590_EQ_1590(...) \, -#define Z_IS_1591_EQ_1591(...) \, -#define Z_IS_1592_EQ_1592(...) \, -#define Z_IS_1593_EQ_1593(...) \, -#define Z_IS_1594_EQ_1594(...) \, -#define Z_IS_1595_EQ_1595(...) \, -#define Z_IS_1596_EQ_1596(...) \, -#define Z_IS_1597_EQ_1597(...) \, -#define Z_IS_1598_EQ_1598(...) \, -#define Z_IS_1599_EQ_1599(...) \, -#define Z_IS_1600_EQ_1600(...) \, -#define Z_IS_1601_EQ_1601(...) \, -#define Z_IS_1602_EQ_1602(...) \, -#define Z_IS_1603_EQ_1603(...) \, -#define Z_IS_1604_EQ_1604(...) \, -#define Z_IS_1605_EQ_1605(...) \, -#define Z_IS_1606_EQ_1606(...) \, -#define Z_IS_1607_EQ_1607(...) \, -#define Z_IS_1608_EQ_1608(...) \, -#define Z_IS_1609_EQ_1609(...) \, -#define Z_IS_1610_EQ_1610(...) \, -#define Z_IS_1611_EQ_1611(...) \, -#define Z_IS_1612_EQ_1612(...) \, -#define Z_IS_1613_EQ_1613(...) \, -#define Z_IS_1614_EQ_1614(...) \, -#define Z_IS_1615_EQ_1615(...) \, -#define Z_IS_1616_EQ_1616(...) \, -#define Z_IS_1617_EQ_1617(...) \, -#define Z_IS_1618_EQ_1618(...) \, -#define Z_IS_1619_EQ_1619(...) \, -#define Z_IS_1620_EQ_1620(...) \, -#define Z_IS_1621_EQ_1621(...) \, -#define Z_IS_1622_EQ_1622(...) \, -#define Z_IS_1623_EQ_1623(...) \, -#define Z_IS_1624_EQ_1624(...) \, -#define Z_IS_1625_EQ_1625(...) \, -#define Z_IS_1626_EQ_1626(...) \, -#define Z_IS_1627_EQ_1627(...) \, -#define Z_IS_1628_EQ_1628(...) \, -#define Z_IS_1629_EQ_1629(...) \, -#define Z_IS_1630_EQ_1630(...) \, -#define Z_IS_1631_EQ_1631(...) \, -#define Z_IS_1632_EQ_1632(...) \, -#define Z_IS_1633_EQ_1633(...) \, -#define Z_IS_1634_EQ_1634(...) \, -#define Z_IS_1635_EQ_1635(...) \, -#define Z_IS_1636_EQ_1636(...) \, -#define Z_IS_1637_EQ_1637(...) \, -#define Z_IS_1638_EQ_1638(...) \, -#define Z_IS_1639_EQ_1639(...) \, -#define Z_IS_1640_EQ_1640(...) \, -#define Z_IS_1641_EQ_1641(...) \, -#define Z_IS_1642_EQ_1642(...) \, -#define Z_IS_1643_EQ_1643(...) \, -#define Z_IS_1644_EQ_1644(...) \, -#define Z_IS_1645_EQ_1645(...) \, -#define Z_IS_1646_EQ_1646(...) \, -#define Z_IS_1647_EQ_1647(...) \, -#define Z_IS_1648_EQ_1648(...) \, -#define Z_IS_1649_EQ_1649(...) \, -#define Z_IS_1650_EQ_1650(...) \, -#define Z_IS_1651_EQ_1651(...) \, -#define Z_IS_1652_EQ_1652(...) \, -#define Z_IS_1653_EQ_1653(...) \, -#define Z_IS_1654_EQ_1654(...) \, -#define Z_IS_1655_EQ_1655(...) \, -#define Z_IS_1656_EQ_1656(...) \, -#define Z_IS_1657_EQ_1657(...) \, -#define Z_IS_1658_EQ_1658(...) \, -#define Z_IS_1659_EQ_1659(...) \, -#define Z_IS_1660_EQ_1660(...) \, -#define Z_IS_1661_EQ_1661(...) \, -#define Z_IS_1662_EQ_1662(...) \, -#define Z_IS_1663_EQ_1663(...) \, -#define Z_IS_1664_EQ_1664(...) \, -#define Z_IS_1665_EQ_1665(...) \, -#define Z_IS_1666_EQ_1666(...) \, -#define Z_IS_1667_EQ_1667(...) \, -#define Z_IS_1668_EQ_1668(...) \, -#define Z_IS_1669_EQ_1669(...) \, -#define Z_IS_1670_EQ_1670(...) \, -#define Z_IS_1671_EQ_1671(...) \, -#define Z_IS_1672_EQ_1672(...) \, -#define Z_IS_1673_EQ_1673(...) \, -#define Z_IS_1674_EQ_1674(...) \, -#define Z_IS_1675_EQ_1675(...) \, -#define Z_IS_1676_EQ_1676(...) \, -#define Z_IS_1677_EQ_1677(...) \, -#define Z_IS_1678_EQ_1678(...) \, -#define Z_IS_1679_EQ_1679(...) \, -#define Z_IS_1680_EQ_1680(...) \, -#define Z_IS_1681_EQ_1681(...) \, -#define Z_IS_1682_EQ_1682(...) \, -#define Z_IS_1683_EQ_1683(...) \, -#define Z_IS_1684_EQ_1684(...) \, -#define Z_IS_1685_EQ_1685(...) \, -#define Z_IS_1686_EQ_1686(...) \, -#define Z_IS_1687_EQ_1687(...) \, -#define Z_IS_1688_EQ_1688(...) \, -#define Z_IS_1689_EQ_1689(...) \, -#define Z_IS_1690_EQ_1690(...) \, -#define Z_IS_1691_EQ_1691(...) \, -#define Z_IS_1692_EQ_1692(...) \, -#define Z_IS_1693_EQ_1693(...) \, -#define Z_IS_1694_EQ_1694(...) \, -#define Z_IS_1695_EQ_1695(...) \, -#define Z_IS_1696_EQ_1696(...) \, -#define Z_IS_1697_EQ_1697(...) \, -#define Z_IS_1698_EQ_1698(...) \, -#define Z_IS_1699_EQ_1699(...) \, -#define Z_IS_1700_EQ_1700(...) \, -#define Z_IS_1701_EQ_1701(...) \, -#define Z_IS_1702_EQ_1702(...) \, -#define Z_IS_1703_EQ_1703(...) \, -#define Z_IS_1704_EQ_1704(...) \, -#define Z_IS_1705_EQ_1705(...) \, -#define Z_IS_1706_EQ_1706(...) \, -#define Z_IS_1707_EQ_1707(...) \, -#define Z_IS_1708_EQ_1708(...) \, -#define Z_IS_1709_EQ_1709(...) \, -#define Z_IS_1710_EQ_1710(...) \, -#define Z_IS_1711_EQ_1711(...) \, -#define Z_IS_1712_EQ_1712(...) \, -#define Z_IS_1713_EQ_1713(...) \, -#define Z_IS_1714_EQ_1714(...) \, -#define Z_IS_1715_EQ_1715(...) \, -#define Z_IS_1716_EQ_1716(...) \, -#define Z_IS_1717_EQ_1717(...) \, -#define Z_IS_1718_EQ_1718(...) \, -#define Z_IS_1719_EQ_1719(...) \, -#define Z_IS_1720_EQ_1720(...) \, -#define Z_IS_1721_EQ_1721(...) \, -#define Z_IS_1722_EQ_1722(...) \, -#define Z_IS_1723_EQ_1723(...) \, -#define Z_IS_1724_EQ_1724(...) \, -#define Z_IS_1725_EQ_1725(...) \, -#define Z_IS_1726_EQ_1726(...) \, -#define Z_IS_1727_EQ_1727(...) \, -#define Z_IS_1728_EQ_1728(...) \, -#define Z_IS_1729_EQ_1729(...) \, -#define Z_IS_1730_EQ_1730(...) \, -#define Z_IS_1731_EQ_1731(...) \, -#define Z_IS_1732_EQ_1732(...) \, -#define Z_IS_1733_EQ_1733(...) \, -#define Z_IS_1734_EQ_1734(...) \, -#define Z_IS_1735_EQ_1735(...) \, -#define Z_IS_1736_EQ_1736(...) \, -#define Z_IS_1737_EQ_1737(...) \, -#define Z_IS_1738_EQ_1738(...) \, -#define Z_IS_1739_EQ_1739(...) \, -#define Z_IS_1740_EQ_1740(...) \, -#define Z_IS_1741_EQ_1741(...) \, -#define Z_IS_1742_EQ_1742(...) \, -#define Z_IS_1743_EQ_1743(...) \, -#define Z_IS_1744_EQ_1744(...) \, -#define Z_IS_1745_EQ_1745(...) \, -#define Z_IS_1746_EQ_1746(...) \, -#define Z_IS_1747_EQ_1747(...) \, -#define Z_IS_1748_EQ_1748(...) \, -#define Z_IS_1749_EQ_1749(...) \, -#define Z_IS_1750_EQ_1750(...) \, -#define Z_IS_1751_EQ_1751(...) \, -#define Z_IS_1752_EQ_1752(...) \, -#define Z_IS_1753_EQ_1753(...) \, -#define Z_IS_1754_EQ_1754(...) \, -#define Z_IS_1755_EQ_1755(...) \, -#define Z_IS_1756_EQ_1756(...) \, -#define Z_IS_1757_EQ_1757(...) \, -#define Z_IS_1758_EQ_1758(...) \, -#define Z_IS_1759_EQ_1759(...) \, -#define Z_IS_1760_EQ_1760(...) \, -#define Z_IS_1761_EQ_1761(...) \, -#define Z_IS_1762_EQ_1762(...) \, -#define Z_IS_1763_EQ_1763(...) \, -#define Z_IS_1764_EQ_1764(...) \, -#define Z_IS_1765_EQ_1765(...) \, -#define Z_IS_1766_EQ_1766(...) \, -#define Z_IS_1767_EQ_1767(...) \, -#define Z_IS_1768_EQ_1768(...) \, -#define Z_IS_1769_EQ_1769(...) \, -#define Z_IS_1770_EQ_1770(...) \, -#define Z_IS_1771_EQ_1771(...) \, -#define Z_IS_1772_EQ_1772(...) \, -#define Z_IS_1773_EQ_1773(...) \, -#define Z_IS_1774_EQ_1774(...) \, -#define Z_IS_1775_EQ_1775(...) \, -#define Z_IS_1776_EQ_1776(...) \, -#define Z_IS_1777_EQ_1777(...) \, -#define Z_IS_1778_EQ_1778(...) \, -#define Z_IS_1779_EQ_1779(...) \, -#define Z_IS_1780_EQ_1780(...) \, -#define Z_IS_1781_EQ_1781(...) \, -#define Z_IS_1782_EQ_1782(...) \, -#define Z_IS_1783_EQ_1783(...) \, -#define Z_IS_1784_EQ_1784(...) \, -#define Z_IS_1785_EQ_1785(...) \, -#define Z_IS_1786_EQ_1786(...) \, -#define Z_IS_1787_EQ_1787(...) \, -#define Z_IS_1788_EQ_1788(...) \, -#define Z_IS_1789_EQ_1789(...) \, -#define Z_IS_1790_EQ_1790(...) \, -#define Z_IS_1791_EQ_1791(...) \, -#define Z_IS_1792_EQ_1792(...) \, -#define Z_IS_1793_EQ_1793(...) \, -#define Z_IS_1794_EQ_1794(...) \, -#define Z_IS_1795_EQ_1795(...) \, -#define Z_IS_1796_EQ_1796(...) \, -#define Z_IS_1797_EQ_1797(...) \, -#define Z_IS_1798_EQ_1798(...) \, -#define Z_IS_1799_EQ_1799(...) \, -#define Z_IS_1800_EQ_1800(...) \, -#define Z_IS_1801_EQ_1801(...) \, -#define Z_IS_1802_EQ_1802(...) \, -#define Z_IS_1803_EQ_1803(...) \, -#define Z_IS_1804_EQ_1804(...) \, -#define Z_IS_1805_EQ_1805(...) \, -#define Z_IS_1806_EQ_1806(...) \, -#define Z_IS_1807_EQ_1807(...) \, -#define Z_IS_1808_EQ_1808(...) \, -#define Z_IS_1809_EQ_1809(...) \, -#define Z_IS_1810_EQ_1810(...) \, -#define Z_IS_1811_EQ_1811(...) \, -#define Z_IS_1812_EQ_1812(...) \, -#define Z_IS_1813_EQ_1813(...) \, -#define Z_IS_1814_EQ_1814(...) \, -#define Z_IS_1815_EQ_1815(...) \, -#define Z_IS_1816_EQ_1816(...) \, -#define Z_IS_1817_EQ_1817(...) \, -#define Z_IS_1818_EQ_1818(...) \, -#define Z_IS_1819_EQ_1819(...) \, -#define Z_IS_1820_EQ_1820(...) \, -#define Z_IS_1821_EQ_1821(...) \, -#define Z_IS_1822_EQ_1822(...) \, -#define Z_IS_1823_EQ_1823(...) \, -#define Z_IS_1824_EQ_1824(...) \, -#define Z_IS_1825_EQ_1825(...) \, -#define Z_IS_1826_EQ_1826(...) \, -#define Z_IS_1827_EQ_1827(...) \, -#define Z_IS_1828_EQ_1828(...) \, -#define Z_IS_1829_EQ_1829(...) \, -#define Z_IS_1830_EQ_1830(...) \, -#define Z_IS_1831_EQ_1831(...) \, -#define Z_IS_1832_EQ_1832(...) \, -#define Z_IS_1833_EQ_1833(...) \, -#define Z_IS_1834_EQ_1834(...) \, -#define Z_IS_1835_EQ_1835(...) \, -#define Z_IS_1836_EQ_1836(...) \, -#define Z_IS_1837_EQ_1837(...) \, -#define Z_IS_1838_EQ_1838(...) \, -#define Z_IS_1839_EQ_1839(...) \, -#define Z_IS_1840_EQ_1840(...) \, -#define Z_IS_1841_EQ_1841(...) \, -#define Z_IS_1842_EQ_1842(...) \, -#define Z_IS_1843_EQ_1843(...) \, -#define Z_IS_1844_EQ_1844(...) \, -#define Z_IS_1845_EQ_1845(...) \, -#define Z_IS_1846_EQ_1846(...) \, -#define Z_IS_1847_EQ_1847(...) \, -#define Z_IS_1848_EQ_1848(...) \, -#define Z_IS_1849_EQ_1849(...) \, -#define Z_IS_1850_EQ_1850(...) \, -#define Z_IS_1851_EQ_1851(...) \, -#define Z_IS_1852_EQ_1852(...) \, -#define Z_IS_1853_EQ_1853(...) \, -#define Z_IS_1854_EQ_1854(...) \, -#define Z_IS_1855_EQ_1855(...) \, -#define Z_IS_1856_EQ_1856(...) \, -#define Z_IS_1857_EQ_1857(...) \, -#define Z_IS_1858_EQ_1858(...) \, -#define Z_IS_1859_EQ_1859(...) \, -#define Z_IS_1860_EQ_1860(...) \, -#define Z_IS_1861_EQ_1861(...) \, -#define Z_IS_1862_EQ_1862(...) \, -#define Z_IS_1863_EQ_1863(...) \, -#define Z_IS_1864_EQ_1864(...) \, -#define Z_IS_1865_EQ_1865(...) \, -#define Z_IS_1866_EQ_1866(...) \, -#define Z_IS_1867_EQ_1867(...) \, -#define Z_IS_1868_EQ_1868(...) \, -#define Z_IS_1869_EQ_1869(...) \, -#define Z_IS_1870_EQ_1870(...) \, -#define Z_IS_1871_EQ_1871(...) \, -#define Z_IS_1872_EQ_1872(...) \, -#define Z_IS_1873_EQ_1873(...) \, -#define Z_IS_1874_EQ_1874(...) \, -#define Z_IS_1875_EQ_1875(...) \, -#define Z_IS_1876_EQ_1876(...) \, -#define Z_IS_1877_EQ_1877(...) \, -#define Z_IS_1878_EQ_1878(...) \, -#define Z_IS_1879_EQ_1879(...) \, -#define Z_IS_1880_EQ_1880(...) \, -#define Z_IS_1881_EQ_1881(...) \, -#define Z_IS_1882_EQ_1882(...) \, -#define Z_IS_1883_EQ_1883(...) \, -#define Z_IS_1884_EQ_1884(...) \, -#define Z_IS_1885_EQ_1885(...) \, -#define Z_IS_1886_EQ_1886(...) \, -#define Z_IS_1887_EQ_1887(...) \, -#define Z_IS_1888_EQ_1888(...) \, -#define Z_IS_1889_EQ_1889(...) \, -#define Z_IS_1890_EQ_1890(...) \, -#define Z_IS_1891_EQ_1891(...) \, -#define Z_IS_1892_EQ_1892(...) \, -#define Z_IS_1893_EQ_1893(...) \, -#define Z_IS_1894_EQ_1894(...) \, -#define Z_IS_1895_EQ_1895(...) \, -#define Z_IS_1896_EQ_1896(...) \, -#define Z_IS_1897_EQ_1897(...) \, -#define Z_IS_1898_EQ_1898(...) \, -#define Z_IS_1899_EQ_1899(...) \, -#define Z_IS_1900_EQ_1900(...) \, -#define Z_IS_1901_EQ_1901(...) \, -#define Z_IS_1902_EQ_1902(...) \, -#define Z_IS_1903_EQ_1903(...) \, -#define Z_IS_1904_EQ_1904(...) \, -#define Z_IS_1905_EQ_1905(...) \, -#define Z_IS_1906_EQ_1906(...) \, -#define Z_IS_1907_EQ_1907(...) \, -#define Z_IS_1908_EQ_1908(...) \, -#define Z_IS_1909_EQ_1909(...) \, -#define Z_IS_1910_EQ_1910(...) \, -#define Z_IS_1911_EQ_1911(...) \, -#define Z_IS_1912_EQ_1912(...) \, -#define Z_IS_1913_EQ_1913(...) \, -#define Z_IS_1914_EQ_1914(...) \, -#define Z_IS_1915_EQ_1915(...) \, -#define Z_IS_1916_EQ_1916(...) \, -#define Z_IS_1917_EQ_1917(...) \, -#define Z_IS_1918_EQ_1918(...) \, -#define Z_IS_1919_EQ_1919(...) \, -#define Z_IS_1920_EQ_1920(...) \, -#define Z_IS_1921_EQ_1921(...) \, -#define Z_IS_1922_EQ_1922(...) \, -#define Z_IS_1923_EQ_1923(...) \, -#define Z_IS_1924_EQ_1924(...) \, -#define Z_IS_1925_EQ_1925(...) \, -#define Z_IS_1926_EQ_1926(...) \, -#define Z_IS_1927_EQ_1927(...) \, -#define Z_IS_1928_EQ_1928(...) \, -#define Z_IS_1929_EQ_1929(...) \, -#define Z_IS_1930_EQ_1930(...) \, -#define Z_IS_1931_EQ_1931(...) \, -#define Z_IS_1932_EQ_1932(...) \, -#define Z_IS_1933_EQ_1933(...) \, -#define Z_IS_1934_EQ_1934(...) \, -#define Z_IS_1935_EQ_1935(...) \, -#define Z_IS_1936_EQ_1936(...) \, -#define Z_IS_1937_EQ_1937(...) \, -#define Z_IS_1938_EQ_1938(...) \, -#define Z_IS_1939_EQ_1939(...) \, -#define Z_IS_1940_EQ_1940(...) \, -#define Z_IS_1941_EQ_1941(...) \, -#define Z_IS_1942_EQ_1942(...) \, -#define Z_IS_1943_EQ_1943(...) \, -#define Z_IS_1944_EQ_1944(...) \, -#define Z_IS_1945_EQ_1945(...) \, -#define Z_IS_1946_EQ_1946(...) \, -#define Z_IS_1947_EQ_1947(...) \, -#define Z_IS_1948_EQ_1948(...) \, -#define Z_IS_1949_EQ_1949(...) \, -#define Z_IS_1950_EQ_1950(...) \, -#define Z_IS_1951_EQ_1951(...) \, -#define Z_IS_1952_EQ_1952(...) \, -#define Z_IS_1953_EQ_1953(...) \, -#define Z_IS_1954_EQ_1954(...) \, -#define Z_IS_1955_EQ_1955(...) \, -#define Z_IS_1956_EQ_1956(...) \, -#define Z_IS_1957_EQ_1957(...) \, -#define Z_IS_1958_EQ_1958(...) \, -#define Z_IS_1959_EQ_1959(...) \, -#define Z_IS_1960_EQ_1960(...) \, -#define Z_IS_1961_EQ_1961(...) \, -#define Z_IS_1962_EQ_1962(...) \, -#define Z_IS_1963_EQ_1963(...) \, -#define Z_IS_1964_EQ_1964(...) \, -#define Z_IS_1965_EQ_1965(...) \, -#define Z_IS_1966_EQ_1966(...) \, -#define Z_IS_1967_EQ_1967(...) \, -#define Z_IS_1968_EQ_1968(...) \, -#define Z_IS_1969_EQ_1969(...) \, -#define Z_IS_1970_EQ_1970(...) \, -#define Z_IS_1971_EQ_1971(...) \, -#define Z_IS_1972_EQ_1972(...) \, -#define Z_IS_1973_EQ_1973(...) \, -#define Z_IS_1974_EQ_1974(...) \, -#define Z_IS_1975_EQ_1975(...) \, -#define Z_IS_1976_EQ_1976(...) \, -#define Z_IS_1977_EQ_1977(...) \, -#define Z_IS_1978_EQ_1978(...) \, -#define Z_IS_1979_EQ_1979(...) \, -#define Z_IS_1980_EQ_1980(...) \, -#define Z_IS_1981_EQ_1981(...) \, -#define Z_IS_1982_EQ_1982(...) \, -#define Z_IS_1983_EQ_1983(...) \, -#define Z_IS_1984_EQ_1984(...) \, -#define Z_IS_1985_EQ_1985(...) \, -#define Z_IS_1986_EQ_1986(...) \, -#define Z_IS_1987_EQ_1987(...) \, -#define Z_IS_1988_EQ_1988(...) \, -#define Z_IS_1989_EQ_1989(...) \, -#define Z_IS_1990_EQ_1990(...) \, -#define Z_IS_1991_EQ_1991(...) \, -#define Z_IS_1992_EQ_1992(...) \, -#define Z_IS_1993_EQ_1993(...) \, -#define Z_IS_1994_EQ_1994(...) \, -#define Z_IS_1995_EQ_1995(...) \, -#define Z_IS_1996_EQ_1996(...) \, -#define Z_IS_1997_EQ_1997(...) \, -#define Z_IS_1998_EQ_1998(...) \, -#define Z_IS_1999_EQ_1999(...) \, -#define Z_IS_2000_EQ_2000(...) \, -#define Z_IS_2001_EQ_2001(...) \, -#define Z_IS_2002_EQ_2002(...) \, -#define Z_IS_2003_EQ_2003(...) \, -#define Z_IS_2004_EQ_2004(...) \, -#define Z_IS_2005_EQ_2005(...) \, -#define Z_IS_2006_EQ_2006(...) \, -#define Z_IS_2007_EQ_2007(...) \, -#define Z_IS_2008_EQ_2008(...) \, -#define Z_IS_2009_EQ_2009(...) \, -#define Z_IS_2010_EQ_2010(...) \, -#define Z_IS_2011_EQ_2011(...) \, -#define Z_IS_2012_EQ_2012(...) \, -#define Z_IS_2013_EQ_2013(...) \, -#define Z_IS_2014_EQ_2014(...) \, -#define Z_IS_2015_EQ_2015(...) \, -#define Z_IS_2016_EQ_2016(...) \, -#define Z_IS_2017_EQ_2017(...) \, -#define Z_IS_2018_EQ_2018(...) \, -#define Z_IS_2019_EQ_2019(...) \, -#define Z_IS_2020_EQ_2020(...) \, -#define Z_IS_2021_EQ_2021(...) \, -#define Z_IS_2022_EQ_2022(...) \, -#define Z_IS_2023_EQ_2023(...) \, -#define Z_IS_2024_EQ_2024(...) \, -#define Z_IS_2025_EQ_2025(...) \, -#define Z_IS_2026_EQ_2026(...) \, -#define Z_IS_2027_EQ_2027(...) \, -#define Z_IS_2028_EQ_2028(...) \, -#define Z_IS_2029_EQ_2029(...) \, -#define Z_IS_2030_EQ_2030(...) \, -#define Z_IS_2031_EQ_2031(...) \, -#define Z_IS_2032_EQ_2032(...) \, -#define Z_IS_2033_EQ_2033(...) \, -#define Z_IS_2034_EQ_2034(...) \, -#define Z_IS_2035_EQ_2035(...) \, -#define Z_IS_2036_EQ_2036(...) \, -#define Z_IS_2037_EQ_2037(...) \, -#define Z_IS_2038_EQ_2038(...) \, -#define Z_IS_2039_EQ_2039(...) \, -#define Z_IS_2040_EQ_2040(...) \, -#define Z_IS_2041_EQ_2041(...) \, -#define Z_IS_2042_EQ_2042(...) \, -#define Z_IS_2043_EQ_2043(...) \, -#define Z_IS_2044_EQ_2044(...) \, -#define Z_IS_2045_EQ_2045(...) \, -#define Z_IS_2046_EQ_2046(...) \, -#define Z_IS_2047_EQ_2047(...) \, -#define Z_IS_2048_EQ_2048(...) \, -#define Z_IS_2049_EQ_2049(...) \, -#define Z_IS_2050_EQ_2050(...) \, -#define Z_IS_2051_EQ_2051(...) \, -#define Z_IS_2052_EQ_2052(...) \, -#define Z_IS_2053_EQ_2053(...) \, -#define Z_IS_2054_EQ_2054(...) \, -#define Z_IS_2055_EQ_2055(...) \, -#define Z_IS_2056_EQ_2056(...) \, -#define Z_IS_2057_EQ_2057(...) \, -#define Z_IS_2058_EQ_2058(...) \, -#define Z_IS_2059_EQ_2059(...) \, -#define Z_IS_2060_EQ_2060(...) \, -#define Z_IS_2061_EQ_2061(...) \, -#define Z_IS_2062_EQ_2062(...) \, -#define Z_IS_2063_EQ_2063(...) \, -#define Z_IS_2064_EQ_2064(...) \, -#define Z_IS_2065_EQ_2065(...) \, -#define Z_IS_2066_EQ_2066(...) \, -#define Z_IS_2067_EQ_2067(...) \, -#define Z_IS_2068_EQ_2068(...) \, -#define Z_IS_2069_EQ_2069(...) \, -#define Z_IS_2070_EQ_2070(...) \, -#define Z_IS_2071_EQ_2071(...) \, -#define Z_IS_2072_EQ_2072(...) \, -#define Z_IS_2073_EQ_2073(...) \, -#define Z_IS_2074_EQ_2074(...) \, -#define Z_IS_2075_EQ_2075(...) \, -#define Z_IS_2076_EQ_2076(...) \, -#define Z_IS_2077_EQ_2077(...) \, -#define Z_IS_2078_EQ_2078(...) \, -#define Z_IS_2079_EQ_2079(...) \, -#define Z_IS_2080_EQ_2080(...) \, -#define Z_IS_2081_EQ_2081(...) \, -#define Z_IS_2082_EQ_2082(...) \, -#define Z_IS_2083_EQ_2083(...) \, -#define Z_IS_2084_EQ_2084(...) \, -#define Z_IS_2085_EQ_2085(...) \, -#define Z_IS_2086_EQ_2086(...) \, -#define Z_IS_2087_EQ_2087(...) \, -#define Z_IS_2088_EQ_2088(...) \, -#define Z_IS_2089_EQ_2089(...) \, -#define Z_IS_2090_EQ_2090(...) \, -#define Z_IS_2091_EQ_2091(...) \, -#define Z_IS_2092_EQ_2092(...) \, -#define Z_IS_2093_EQ_2093(...) \, -#define Z_IS_2094_EQ_2094(...) \, -#define Z_IS_2095_EQ_2095(...) \, -#define Z_IS_2096_EQ_2096(...) \, -#define Z_IS_2097_EQ_2097(...) \, -#define Z_IS_2098_EQ_2098(...) \, -#define Z_IS_2099_EQ_2099(...) \, -#define Z_IS_2100_EQ_2100(...) \, -#define Z_IS_2101_EQ_2101(...) \, -#define Z_IS_2102_EQ_2102(...) \, -#define Z_IS_2103_EQ_2103(...) \, -#define Z_IS_2104_EQ_2104(...) \, -#define Z_IS_2105_EQ_2105(...) \, -#define Z_IS_2106_EQ_2106(...) \, -#define Z_IS_2107_EQ_2107(...) \, -#define Z_IS_2108_EQ_2108(...) \, -#define Z_IS_2109_EQ_2109(...) \, -#define Z_IS_2110_EQ_2110(...) \, -#define Z_IS_2111_EQ_2111(...) \, -#define Z_IS_2112_EQ_2112(...) \, -#define Z_IS_2113_EQ_2113(...) \, -#define Z_IS_2114_EQ_2114(...) \, -#define Z_IS_2115_EQ_2115(...) \, -#define Z_IS_2116_EQ_2116(...) \, -#define Z_IS_2117_EQ_2117(...) \, -#define Z_IS_2118_EQ_2118(...) \, -#define Z_IS_2119_EQ_2119(...) \, -#define Z_IS_2120_EQ_2120(...) \, -#define Z_IS_2121_EQ_2121(...) \, -#define Z_IS_2122_EQ_2122(...) \, -#define Z_IS_2123_EQ_2123(...) \, -#define Z_IS_2124_EQ_2124(...) \, -#define Z_IS_2125_EQ_2125(...) \, -#define Z_IS_2126_EQ_2126(...) \, -#define Z_IS_2127_EQ_2127(...) \, -#define Z_IS_2128_EQ_2128(...) \, -#define Z_IS_2129_EQ_2129(...) \, -#define Z_IS_2130_EQ_2130(...) \, -#define Z_IS_2131_EQ_2131(...) \, -#define Z_IS_2132_EQ_2132(...) \, -#define Z_IS_2133_EQ_2133(...) \, -#define Z_IS_2134_EQ_2134(...) \, -#define Z_IS_2135_EQ_2135(...) \, -#define Z_IS_2136_EQ_2136(...) \, -#define Z_IS_2137_EQ_2137(...) \, -#define Z_IS_2138_EQ_2138(...) \, -#define Z_IS_2139_EQ_2139(...) \, -#define Z_IS_2140_EQ_2140(...) \, -#define Z_IS_2141_EQ_2141(...) \, -#define Z_IS_2142_EQ_2142(...) \, -#define Z_IS_2143_EQ_2143(...) \, -#define Z_IS_2144_EQ_2144(...) \, -#define Z_IS_2145_EQ_2145(...) \, -#define Z_IS_2146_EQ_2146(...) \, -#define Z_IS_2147_EQ_2147(...) \, -#define Z_IS_2148_EQ_2148(...) \, -#define Z_IS_2149_EQ_2149(...) \, -#define Z_IS_2150_EQ_2150(...) \, -#define Z_IS_2151_EQ_2151(...) \, -#define Z_IS_2152_EQ_2152(...) \, -#define Z_IS_2153_EQ_2153(...) \, -#define Z_IS_2154_EQ_2154(...) \, -#define Z_IS_2155_EQ_2155(...) \, -#define Z_IS_2156_EQ_2156(...) \, -#define Z_IS_2157_EQ_2157(...) \, -#define Z_IS_2158_EQ_2158(...) \, -#define Z_IS_2159_EQ_2159(...) \, -#define Z_IS_2160_EQ_2160(...) \, -#define Z_IS_2161_EQ_2161(...) \, -#define Z_IS_2162_EQ_2162(...) \, -#define Z_IS_2163_EQ_2163(...) \, -#define Z_IS_2164_EQ_2164(...) \, -#define Z_IS_2165_EQ_2165(...) \, -#define Z_IS_2166_EQ_2166(...) \, -#define Z_IS_2167_EQ_2167(...) \, -#define Z_IS_2168_EQ_2168(...) \, -#define Z_IS_2169_EQ_2169(...) \, -#define Z_IS_2170_EQ_2170(...) \, -#define Z_IS_2171_EQ_2171(...) \, -#define Z_IS_2172_EQ_2172(...) \, -#define Z_IS_2173_EQ_2173(...) \, -#define Z_IS_2174_EQ_2174(...) \, -#define Z_IS_2175_EQ_2175(...) \, -#define Z_IS_2176_EQ_2176(...) \, -#define Z_IS_2177_EQ_2177(...) \, -#define Z_IS_2178_EQ_2178(...) \, -#define Z_IS_2179_EQ_2179(...) \, -#define Z_IS_2180_EQ_2180(...) \, -#define Z_IS_2181_EQ_2181(...) \, -#define Z_IS_2182_EQ_2182(...) \, -#define Z_IS_2183_EQ_2183(...) \, -#define Z_IS_2184_EQ_2184(...) \, -#define Z_IS_2185_EQ_2185(...) \, -#define Z_IS_2186_EQ_2186(...) \, -#define Z_IS_2187_EQ_2187(...) \, -#define Z_IS_2188_EQ_2188(...) \, -#define Z_IS_2189_EQ_2189(...) \, -#define Z_IS_2190_EQ_2190(...) \, -#define Z_IS_2191_EQ_2191(...) \, -#define Z_IS_2192_EQ_2192(...) \, -#define Z_IS_2193_EQ_2193(...) \, -#define Z_IS_2194_EQ_2194(...) \, -#define Z_IS_2195_EQ_2195(...) \, -#define Z_IS_2196_EQ_2196(...) \, -#define Z_IS_2197_EQ_2197(...) \, -#define Z_IS_2198_EQ_2198(...) \, -#define Z_IS_2199_EQ_2199(...) \, -#define Z_IS_2200_EQ_2200(...) \, -#define Z_IS_2201_EQ_2201(...) \, -#define Z_IS_2202_EQ_2202(...) \, -#define Z_IS_2203_EQ_2203(...) \, -#define Z_IS_2204_EQ_2204(...) \, -#define Z_IS_2205_EQ_2205(...) \, -#define Z_IS_2206_EQ_2206(...) \, -#define Z_IS_2207_EQ_2207(...) \, -#define Z_IS_2208_EQ_2208(...) \, -#define Z_IS_2209_EQ_2209(...) \, -#define Z_IS_2210_EQ_2210(...) \, -#define Z_IS_2211_EQ_2211(...) \, -#define Z_IS_2212_EQ_2212(...) \, -#define Z_IS_2213_EQ_2213(...) \, -#define Z_IS_2214_EQ_2214(...) \, -#define Z_IS_2215_EQ_2215(...) \, -#define Z_IS_2216_EQ_2216(...) \, -#define Z_IS_2217_EQ_2217(...) \, -#define Z_IS_2218_EQ_2218(...) \, -#define Z_IS_2219_EQ_2219(...) \, -#define Z_IS_2220_EQ_2220(...) \, -#define Z_IS_2221_EQ_2221(...) \, -#define Z_IS_2222_EQ_2222(...) \, -#define Z_IS_2223_EQ_2223(...) \, -#define Z_IS_2224_EQ_2224(...) \, -#define Z_IS_2225_EQ_2225(...) \, -#define Z_IS_2226_EQ_2226(...) \, -#define Z_IS_2227_EQ_2227(...) \, -#define Z_IS_2228_EQ_2228(...) \, -#define Z_IS_2229_EQ_2229(...) \, -#define Z_IS_2230_EQ_2230(...) \, -#define Z_IS_2231_EQ_2231(...) \, -#define Z_IS_2232_EQ_2232(...) \, -#define Z_IS_2233_EQ_2233(...) \, -#define Z_IS_2234_EQ_2234(...) \, -#define Z_IS_2235_EQ_2235(...) \, -#define Z_IS_2236_EQ_2236(...) \, -#define Z_IS_2237_EQ_2237(...) \, -#define Z_IS_2238_EQ_2238(...) \, -#define Z_IS_2239_EQ_2239(...) \, -#define Z_IS_2240_EQ_2240(...) \, -#define Z_IS_2241_EQ_2241(...) \, -#define Z_IS_2242_EQ_2242(...) \, -#define Z_IS_2243_EQ_2243(...) \, -#define Z_IS_2244_EQ_2244(...) \, -#define Z_IS_2245_EQ_2245(...) \, -#define Z_IS_2246_EQ_2246(...) \, -#define Z_IS_2247_EQ_2247(...) \, -#define Z_IS_2248_EQ_2248(...) \, -#define Z_IS_2249_EQ_2249(...) \, -#define Z_IS_2250_EQ_2250(...) \, -#define Z_IS_2251_EQ_2251(...) \, -#define Z_IS_2252_EQ_2252(...) \, -#define Z_IS_2253_EQ_2253(...) \, -#define Z_IS_2254_EQ_2254(...) \, -#define Z_IS_2255_EQ_2255(...) \, -#define Z_IS_2256_EQ_2256(...) \, -#define Z_IS_2257_EQ_2257(...) \, -#define Z_IS_2258_EQ_2258(...) \, -#define Z_IS_2259_EQ_2259(...) \, -#define Z_IS_2260_EQ_2260(...) \, -#define Z_IS_2261_EQ_2261(...) \, -#define Z_IS_2262_EQ_2262(...) \, -#define Z_IS_2263_EQ_2263(...) \, -#define Z_IS_2264_EQ_2264(...) \, -#define Z_IS_2265_EQ_2265(...) \, -#define Z_IS_2266_EQ_2266(...) \, -#define Z_IS_2267_EQ_2267(...) \, -#define Z_IS_2268_EQ_2268(...) \, -#define Z_IS_2269_EQ_2269(...) \, -#define Z_IS_2270_EQ_2270(...) \, -#define Z_IS_2271_EQ_2271(...) \, -#define Z_IS_2272_EQ_2272(...) \, -#define Z_IS_2273_EQ_2273(...) \, -#define Z_IS_2274_EQ_2274(...) \, -#define Z_IS_2275_EQ_2275(...) \, -#define Z_IS_2276_EQ_2276(...) \, -#define Z_IS_2277_EQ_2277(...) \, -#define Z_IS_2278_EQ_2278(...) \, -#define Z_IS_2279_EQ_2279(...) \, -#define Z_IS_2280_EQ_2280(...) \, -#define Z_IS_2281_EQ_2281(...) \, -#define Z_IS_2282_EQ_2282(...) \, -#define Z_IS_2283_EQ_2283(...) \, -#define Z_IS_2284_EQ_2284(...) \, -#define Z_IS_2285_EQ_2285(...) \, -#define Z_IS_2286_EQ_2286(...) \, -#define Z_IS_2287_EQ_2287(...) \, -#define Z_IS_2288_EQ_2288(...) \, -#define Z_IS_2289_EQ_2289(...) \, -#define Z_IS_2290_EQ_2290(...) \, -#define Z_IS_2291_EQ_2291(...) \, -#define Z_IS_2292_EQ_2292(...) \, -#define Z_IS_2293_EQ_2293(...) \, -#define Z_IS_2294_EQ_2294(...) \, -#define Z_IS_2295_EQ_2295(...) \, -#define Z_IS_2296_EQ_2296(...) \, -#define Z_IS_2297_EQ_2297(...) \, -#define Z_IS_2298_EQ_2298(...) \, -#define Z_IS_2299_EQ_2299(...) \, -#define Z_IS_2300_EQ_2300(...) \, -#define Z_IS_2301_EQ_2301(...) \, -#define Z_IS_2302_EQ_2302(...) \, -#define Z_IS_2303_EQ_2303(...) \, -#define Z_IS_2304_EQ_2304(...) \, -#define Z_IS_2305_EQ_2305(...) \, -#define Z_IS_2306_EQ_2306(...) \, -#define Z_IS_2307_EQ_2307(...) \, -#define Z_IS_2308_EQ_2308(...) \, -#define Z_IS_2309_EQ_2309(...) \, -#define Z_IS_2310_EQ_2310(...) \, -#define Z_IS_2311_EQ_2311(...) \, -#define Z_IS_2312_EQ_2312(...) \, -#define Z_IS_2313_EQ_2313(...) \, -#define Z_IS_2314_EQ_2314(...) \, -#define Z_IS_2315_EQ_2315(...) \, -#define Z_IS_2316_EQ_2316(...) \, -#define Z_IS_2317_EQ_2317(...) \, -#define Z_IS_2318_EQ_2318(...) \, -#define Z_IS_2319_EQ_2319(...) \, -#define Z_IS_2320_EQ_2320(...) \, -#define Z_IS_2321_EQ_2321(...) \, -#define Z_IS_2322_EQ_2322(...) \, -#define Z_IS_2323_EQ_2323(...) \, -#define Z_IS_2324_EQ_2324(...) \, -#define Z_IS_2325_EQ_2325(...) \, -#define Z_IS_2326_EQ_2326(...) \, -#define Z_IS_2327_EQ_2327(...) \, -#define Z_IS_2328_EQ_2328(...) \, -#define Z_IS_2329_EQ_2329(...) \, -#define Z_IS_2330_EQ_2330(...) \, -#define Z_IS_2331_EQ_2331(...) \, -#define Z_IS_2332_EQ_2332(...) \, -#define Z_IS_2333_EQ_2333(...) \, -#define Z_IS_2334_EQ_2334(...) \, -#define Z_IS_2335_EQ_2335(...) \, -#define Z_IS_2336_EQ_2336(...) \, -#define Z_IS_2337_EQ_2337(...) \, -#define Z_IS_2338_EQ_2338(...) \, -#define Z_IS_2339_EQ_2339(...) \, -#define Z_IS_2340_EQ_2340(...) \, -#define Z_IS_2341_EQ_2341(...) \, -#define Z_IS_2342_EQ_2342(...) \, -#define Z_IS_2343_EQ_2343(...) \, -#define Z_IS_2344_EQ_2344(...) \, -#define Z_IS_2345_EQ_2345(...) \, -#define Z_IS_2346_EQ_2346(...) \, -#define Z_IS_2347_EQ_2347(...) \, -#define Z_IS_2348_EQ_2348(...) \, -#define Z_IS_2349_EQ_2349(...) \, -#define Z_IS_2350_EQ_2350(...) \, -#define Z_IS_2351_EQ_2351(...) \, -#define Z_IS_2352_EQ_2352(...) \, -#define Z_IS_2353_EQ_2353(...) \, -#define Z_IS_2354_EQ_2354(...) \, -#define Z_IS_2355_EQ_2355(...) \, -#define Z_IS_2356_EQ_2356(...) \, -#define Z_IS_2357_EQ_2357(...) \, -#define Z_IS_2358_EQ_2358(...) \, -#define Z_IS_2359_EQ_2359(...) \, -#define Z_IS_2360_EQ_2360(...) \, -#define Z_IS_2361_EQ_2361(...) \, -#define Z_IS_2362_EQ_2362(...) \, -#define Z_IS_2363_EQ_2363(...) \, -#define Z_IS_2364_EQ_2364(...) \, -#define Z_IS_2365_EQ_2365(...) \, -#define Z_IS_2366_EQ_2366(...) \, -#define Z_IS_2367_EQ_2367(...) \, -#define Z_IS_2368_EQ_2368(...) \, -#define Z_IS_2369_EQ_2369(...) \, -#define Z_IS_2370_EQ_2370(...) \, -#define Z_IS_2371_EQ_2371(...) \, -#define Z_IS_2372_EQ_2372(...) \, -#define Z_IS_2373_EQ_2373(...) \, -#define Z_IS_2374_EQ_2374(...) \, -#define Z_IS_2375_EQ_2375(...) \, -#define Z_IS_2376_EQ_2376(...) \, -#define Z_IS_2377_EQ_2377(...) \, -#define Z_IS_2378_EQ_2378(...) \, -#define Z_IS_2379_EQ_2379(...) \, -#define Z_IS_2380_EQ_2380(...) \, -#define Z_IS_2381_EQ_2381(...) \, -#define Z_IS_2382_EQ_2382(...) \, -#define Z_IS_2383_EQ_2383(...) \, -#define Z_IS_2384_EQ_2384(...) \, -#define Z_IS_2385_EQ_2385(...) \, -#define Z_IS_2386_EQ_2386(...) \, -#define Z_IS_2387_EQ_2387(...) \, -#define Z_IS_2388_EQ_2388(...) \, -#define Z_IS_2389_EQ_2389(...) \, -#define Z_IS_2390_EQ_2390(...) \, -#define Z_IS_2391_EQ_2391(...) \, -#define Z_IS_2392_EQ_2392(...) \, -#define Z_IS_2393_EQ_2393(...) \, -#define Z_IS_2394_EQ_2394(...) \, -#define Z_IS_2395_EQ_2395(...) \, -#define Z_IS_2396_EQ_2396(...) \, -#define Z_IS_2397_EQ_2397(...) \, -#define Z_IS_2398_EQ_2398(...) \, -#define Z_IS_2399_EQ_2399(...) \, -#define Z_IS_2400_EQ_2400(...) \, -#define Z_IS_2401_EQ_2401(...) \, -#define Z_IS_2402_EQ_2402(...) \, -#define Z_IS_2403_EQ_2403(...) \, -#define Z_IS_2404_EQ_2404(...) \, -#define Z_IS_2405_EQ_2405(...) \, -#define Z_IS_2406_EQ_2406(...) \, -#define Z_IS_2407_EQ_2407(...) \, -#define Z_IS_2408_EQ_2408(...) \, -#define Z_IS_2409_EQ_2409(...) \, -#define Z_IS_2410_EQ_2410(...) \, -#define Z_IS_2411_EQ_2411(...) \, -#define Z_IS_2412_EQ_2412(...) \, -#define Z_IS_2413_EQ_2413(...) \, -#define Z_IS_2414_EQ_2414(...) \, -#define Z_IS_2415_EQ_2415(...) \, -#define Z_IS_2416_EQ_2416(...) \, -#define Z_IS_2417_EQ_2417(...) \, -#define Z_IS_2418_EQ_2418(...) \, -#define Z_IS_2419_EQ_2419(...) \, -#define Z_IS_2420_EQ_2420(...) \, -#define Z_IS_2421_EQ_2421(...) \, -#define Z_IS_2422_EQ_2422(...) \, -#define Z_IS_2423_EQ_2423(...) \, -#define Z_IS_2424_EQ_2424(...) \, -#define Z_IS_2425_EQ_2425(...) \, -#define Z_IS_2426_EQ_2426(...) \, -#define Z_IS_2427_EQ_2427(...) \, -#define Z_IS_2428_EQ_2428(...) \, -#define Z_IS_2429_EQ_2429(...) \, -#define Z_IS_2430_EQ_2430(...) \, -#define Z_IS_2431_EQ_2431(...) \, -#define Z_IS_2432_EQ_2432(...) \, -#define Z_IS_2433_EQ_2433(...) \, -#define Z_IS_2434_EQ_2434(...) \, -#define Z_IS_2435_EQ_2435(...) \, -#define Z_IS_2436_EQ_2436(...) \, -#define Z_IS_2437_EQ_2437(...) \, -#define Z_IS_2438_EQ_2438(...) \, -#define Z_IS_2439_EQ_2439(...) \, -#define Z_IS_2440_EQ_2440(...) \, -#define Z_IS_2441_EQ_2441(...) \, -#define Z_IS_2442_EQ_2442(...) \, -#define Z_IS_2443_EQ_2443(...) \, -#define Z_IS_2444_EQ_2444(...) \, -#define Z_IS_2445_EQ_2445(...) \, -#define Z_IS_2446_EQ_2446(...) \, -#define Z_IS_2447_EQ_2447(...) \, -#define Z_IS_2448_EQ_2448(...) \, -#define Z_IS_2449_EQ_2449(...) \, -#define Z_IS_2450_EQ_2450(...) \, -#define Z_IS_2451_EQ_2451(...) \, -#define Z_IS_2452_EQ_2452(...) \, -#define Z_IS_2453_EQ_2453(...) \, -#define Z_IS_2454_EQ_2454(...) \, -#define Z_IS_2455_EQ_2455(...) \, -#define Z_IS_2456_EQ_2456(...) \, -#define Z_IS_2457_EQ_2457(...) \, -#define Z_IS_2458_EQ_2458(...) \, -#define Z_IS_2459_EQ_2459(...) \, -#define Z_IS_2460_EQ_2460(...) \, -#define Z_IS_2461_EQ_2461(...) \, -#define Z_IS_2462_EQ_2462(...) \, -#define Z_IS_2463_EQ_2463(...) \, -#define Z_IS_2464_EQ_2464(...) \, -#define Z_IS_2465_EQ_2465(...) \, -#define Z_IS_2466_EQ_2466(...) \, -#define Z_IS_2467_EQ_2467(...) \, -#define Z_IS_2468_EQ_2468(...) \, -#define Z_IS_2469_EQ_2469(...) \, -#define Z_IS_2470_EQ_2470(...) \, -#define Z_IS_2471_EQ_2471(...) \, -#define Z_IS_2472_EQ_2472(...) \, -#define Z_IS_2473_EQ_2473(...) \, -#define Z_IS_2474_EQ_2474(...) \, -#define Z_IS_2475_EQ_2475(...) \, -#define Z_IS_2476_EQ_2476(...) \, -#define Z_IS_2477_EQ_2477(...) \, -#define Z_IS_2478_EQ_2478(...) \, -#define Z_IS_2479_EQ_2479(...) \, -#define Z_IS_2480_EQ_2480(...) \, -#define Z_IS_2481_EQ_2481(...) \, -#define Z_IS_2482_EQ_2482(...) \, -#define Z_IS_2483_EQ_2483(...) \, -#define Z_IS_2484_EQ_2484(...) \, -#define Z_IS_2485_EQ_2485(...) \, -#define Z_IS_2486_EQ_2486(...) \, -#define Z_IS_2487_EQ_2487(...) \, -#define Z_IS_2488_EQ_2488(...) \, -#define Z_IS_2489_EQ_2489(...) \, -#define Z_IS_2490_EQ_2490(...) \, -#define Z_IS_2491_EQ_2491(...) \, -#define Z_IS_2492_EQ_2492(...) \, -#define Z_IS_2493_EQ_2493(...) \, -#define Z_IS_2494_EQ_2494(...) \, -#define Z_IS_2495_EQ_2495(...) \, -#define Z_IS_2496_EQ_2496(...) \, -#define Z_IS_2497_EQ_2497(...) \, -#define Z_IS_2498_EQ_2498(...) \, -#define Z_IS_2499_EQ_2499(...) \, -#define Z_IS_2500_EQ_2500(...) \, -#define Z_IS_2501_EQ_2501(...) \, -#define Z_IS_2502_EQ_2502(...) \, -#define Z_IS_2503_EQ_2503(...) \, -#define Z_IS_2504_EQ_2504(...) \, -#define Z_IS_2505_EQ_2505(...) \, -#define Z_IS_2506_EQ_2506(...) \, -#define Z_IS_2507_EQ_2507(...) \, -#define Z_IS_2508_EQ_2508(...) \, -#define Z_IS_2509_EQ_2509(...) \, -#define Z_IS_2510_EQ_2510(...) \, -#define Z_IS_2511_EQ_2511(...) \, -#define Z_IS_2512_EQ_2512(...) \, -#define Z_IS_2513_EQ_2513(...) \, -#define Z_IS_2514_EQ_2514(...) \, -#define Z_IS_2515_EQ_2515(...) \, -#define Z_IS_2516_EQ_2516(...) \, -#define Z_IS_2517_EQ_2517(...) \, -#define Z_IS_2518_EQ_2518(...) \, -#define Z_IS_2519_EQ_2519(...) \, -#define Z_IS_2520_EQ_2520(...) \, -#define Z_IS_2521_EQ_2521(...) \, -#define Z_IS_2522_EQ_2522(...) \, -#define Z_IS_2523_EQ_2523(...) \, -#define Z_IS_2524_EQ_2524(...) \, -#define Z_IS_2525_EQ_2525(...) \, -#define Z_IS_2526_EQ_2526(...) \, -#define Z_IS_2527_EQ_2527(...) \, -#define Z_IS_2528_EQ_2528(...) \, -#define Z_IS_2529_EQ_2529(...) \, -#define Z_IS_2530_EQ_2530(...) \, -#define Z_IS_2531_EQ_2531(...) \, -#define Z_IS_2532_EQ_2532(...) \, -#define Z_IS_2533_EQ_2533(...) \, -#define Z_IS_2534_EQ_2534(...) \, -#define Z_IS_2535_EQ_2535(...) \, -#define Z_IS_2536_EQ_2536(...) \, -#define Z_IS_2537_EQ_2537(...) \, -#define Z_IS_2538_EQ_2538(...) \, -#define Z_IS_2539_EQ_2539(...) \, -#define Z_IS_2540_EQ_2540(...) \, -#define Z_IS_2541_EQ_2541(...) \, -#define Z_IS_2542_EQ_2542(...) \, -#define Z_IS_2543_EQ_2543(...) \, -#define Z_IS_2544_EQ_2544(...) \, -#define Z_IS_2545_EQ_2545(...) \, -#define Z_IS_2546_EQ_2546(...) \, -#define Z_IS_2547_EQ_2547(...) \, -#define Z_IS_2548_EQ_2548(...) \, -#define Z_IS_2549_EQ_2549(...) \, -#define Z_IS_2550_EQ_2550(...) \, -#define Z_IS_2551_EQ_2551(...) \, -#define Z_IS_2552_EQ_2552(...) \, -#define Z_IS_2553_EQ_2553(...) \, -#define Z_IS_2554_EQ_2554(...) \, -#define Z_IS_2555_EQ_2555(...) \, -#define Z_IS_2556_EQ_2556(...) \, -#define Z_IS_2557_EQ_2557(...) \, -#define Z_IS_2558_EQ_2558(...) \, -#define Z_IS_2559_EQ_2559(...) \, -#define Z_IS_2560_EQ_2560(...) \, -#define Z_IS_2561_EQ_2561(...) \, -#define Z_IS_2562_EQ_2562(...) \, -#define Z_IS_2563_EQ_2563(...) \, -#define Z_IS_2564_EQ_2564(...) \, -#define Z_IS_2565_EQ_2565(...) \, -#define Z_IS_2566_EQ_2566(...) \, -#define Z_IS_2567_EQ_2567(...) \, -#define Z_IS_2568_EQ_2568(...) \, -#define Z_IS_2569_EQ_2569(...) \, -#define Z_IS_2570_EQ_2570(...) \, -#define Z_IS_2571_EQ_2571(...) \, -#define Z_IS_2572_EQ_2572(...) \, -#define Z_IS_2573_EQ_2573(...) \, -#define Z_IS_2574_EQ_2574(...) \, -#define Z_IS_2575_EQ_2575(...) \, -#define Z_IS_2576_EQ_2576(...) \, -#define Z_IS_2577_EQ_2577(...) \, -#define Z_IS_2578_EQ_2578(...) \, -#define Z_IS_2579_EQ_2579(...) \, -#define Z_IS_2580_EQ_2580(...) \, -#define Z_IS_2581_EQ_2581(...) \, -#define Z_IS_2582_EQ_2582(...) \, -#define Z_IS_2583_EQ_2583(...) \, -#define Z_IS_2584_EQ_2584(...) \, -#define Z_IS_2585_EQ_2585(...) \, -#define Z_IS_2586_EQ_2586(...) \, -#define Z_IS_2587_EQ_2587(...) \, -#define Z_IS_2588_EQ_2588(...) \, -#define Z_IS_2589_EQ_2589(...) \, -#define Z_IS_2590_EQ_2590(...) \, -#define Z_IS_2591_EQ_2591(...) \, -#define Z_IS_2592_EQ_2592(...) \, -#define Z_IS_2593_EQ_2593(...) \, -#define Z_IS_2594_EQ_2594(...) \, -#define Z_IS_2595_EQ_2595(...) \, -#define Z_IS_2596_EQ_2596(...) \, -#define Z_IS_2597_EQ_2597(...) \, -#define Z_IS_2598_EQ_2598(...) \, -#define Z_IS_2599_EQ_2599(...) \, -#define Z_IS_2600_EQ_2600(...) \, -#define Z_IS_2601_EQ_2601(...) \, -#define Z_IS_2602_EQ_2602(...) \, -#define Z_IS_2603_EQ_2603(...) \, -#define Z_IS_2604_EQ_2604(...) \, -#define Z_IS_2605_EQ_2605(...) \, -#define Z_IS_2606_EQ_2606(...) \, -#define Z_IS_2607_EQ_2607(...) \, -#define Z_IS_2608_EQ_2608(...) \, -#define Z_IS_2609_EQ_2609(...) \, -#define Z_IS_2610_EQ_2610(...) \, -#define Z_IS_2611_EQ_2611(...) \, -#define Z_IS_2612_EQ_2612(...) \, -#define Z_IS_2613_EQ_2613(...) \, -#define Z_IS_2614_EQ_2614(...) \, -#define Z_IS_2615_EQ_2615(...) \, -#define Z_IS_2616_EQ_2616(...) \, -#define Z_IS_2617_EQ_2617(...) \, -#define Z_IS_2618_EQ_2618(...) \, -#define Z_IS_2619_EQ_2619(...) \, -#define Z_IS_2620_EQ_2620(...) \, -#define Z_IS_2621_EQ_2621(...) \, -#define Z_IS_2622_EQ_2622(...) \, -#define Z_IS_2623_EQ_2623(...) \, -#define Z_IS_2624_EQ_2624(...) \, -#define Z_IS_2625_EQ_2625(...) \, -#define Z_IS_2626_EQ_2626(...) \, -#define Z_IS_2627_EQ_2627(...) \, -#define Z_IS_2628_EQ_2628(...) \, -#define Z_IS_2629_EQ_2629(...) \, -#define Z_IS_2630_EQ_2630(...) \, -#define Z_IS_2631_EQ_2631(...) \, -#define Z_IS_2632_EQ_2632(...) \, -#define Z_IS_2633_EQ_2633(...) \, -#define Z_IS_2634_EQ_2634(...) \, -#define Z_IS_2635_EQ_2635(...) \, -#define Z_IS_2636_EQ_2636(...) \, -#define Z_IS_2637_EQ_2637(...) \, -#define Z_IS_2638_EQ_2638(...) \, -#define Z_IS_2639_EQ_2639(...) \, -#define Z_IS_2640_EQ_2640(...) \, -#define Z_IS_2641_EQ_2641(...) \, -#define Z_IS_2642_EQ_2642(...) \, -#define Z_IS_2643_EQ_2643(...) \, -#define Z_IS_2644_EQ_2644(...) \, -#define Z_IS_2645_EQ_2645(...) \, -#define Z_IS_2646_EQ_2646(...) \, -#define Z_IS_2647_EQ_2647(...) \, -#define Z_IS_2648_EQ_2648(...) \, -#define Z_IS_2649_EQ_2649(...) \, -#define Z_IS_2650_EQ_2650(...) \, -#define Z_IS_2651_EQ_2651(...) \, -#define Z_IS_2652_EQ_2652(...) \, -#define Z_IS_2653_EQ_2653(...) \, -#define Z_IS_2654_EQ_2654(...) \, -#define Z_IS_2655_EQ_2655(...) \, -#define Z_IS_2656_EQ_2656(...) \, -#define Z_IS_2657_EQ_2657(...) \, -#define Z_IS_2658_EQ_2658(...) \, -#define Z_IS_2659_EQ_2659(...) \, -#define Z_IS_2660_EQ_2660(...) \, -#define Z_IS_2661_EQ_2661(...) \, -#define Z_IS_2662_EQ_2662(...) \, -#define Z_IS_2663_EQ_2663(...) \, -#define Z_IS_2664_EQ_2664(...) \, -#define Z_IS_2665_EQ_2665(...) \, -#define Z_IS_2666_EQ_2666(...) \, -#define Z_IS_2667_EQ_2667(...) \, -#define Z_IS_2668_EQ_2668(...) \, -#define Z_IS_2669_EQ_2669(...) \, -#define Z_IS_2670_EQ_2670(...) \, -#define Z_IS_2671_EQ_2671(...) \, -#define Z_IS_2672_EQ_2672(...) \, -#define Z_IS_2673_EQ_2673(...) \, -#define Z_IS_2674_EQ_2674(...) \, -#define Z_IS_2675_EQ_2675(...) \, -#define Z_IS_2676_EQ_2676(...) \, -#define Z_IS_2677_EQ_2677(...) \, -#define Z_IS_2678_EQ_2678(...) \, -#define Z_IS_2679_EQ_2679(...) \, -#define Z_IS_2680_EQ_2680(...) \, -#define Z_IS_2681_EQ_2681(...) \, -#define Z_IS_2682_EQ_2682(...) \, -#define Z_IS_2683_EQ_2683(...) \, -#define Z_IS_2684_EQ_2684(...) \, -#define Z_IS_2685_EQ_2685(...) \, -#define Z_IS_2686_EQ_2686(...) \, -#define Z_IS_2687_EQ_2687(...) \, -#define Z_IS_2688_EQ_2688(...) \, -#define Z_IS_2689_EQ_2689(...) \, -#define Z_IS_2690_EQ_2690(...) \, -#define Z_IS_2691_EQ_2691(...) \, -#define Z_IS_2692_EQ_2692(...) \, -#define Z_IS_2693_EQ_2693(...) \, -#define Z_IS_2694_EQ_2694(...) \, -#define Z_IS_2695_EQ_2695(...) \, -#define Z_IS_2696_EQ_2696(...) \, -#define Z_IS_2697_EQ_2697(...) \, -#define Z_IS_2698_EQ_2698(...) \, -#define Z_IS_2699_EQ_2699(...) \, -#define Z_IS_2700_EQ_2700(...) \, -#define Z_IS_2701_EQ_2701(...) \, -#define Z_IS_2702_EQ_2702(...) \, -#define Z_IS_2703_EQ_2703(...) \, -#define Z_IS_2704_EQ_2704(...) \, -#define Z_IS_2705_EQ_2705(...) \, -#define Z_IS_2706_EQ_2706(...) \, -#define Z_IS_2707_EQ_2707(...) \, -#define Z_IS_2708_EQ_2708(...) \, -#define Z_IS_2709_EQ_2709(...) \, -#define Z_IS_2710_EQ_2710(...) \, -#define Z_IS_2711_EQ_2711(...) \, -#define Z_IS_2712_EQ_2712(...) \, -#define Z_IS_2713_EQ_2713(...) \, -#define Z_IS_2714_EQ_2714(...) \, -#define Z_IS_2715_EQ_2715(...) \, -#define Z_IS_2716_EQ_2716(...) \, -#define Z_IS_2717_EQ_2717(...) \, -#define Z_IS_2718_EQ_2718(...) \, -#define Z_IS_2719_EQ_2719(...) \, -#define Z_IS_2720_EQ_2720(...) \, -#define Z_IS_2721_EQ_2721(...) \, -#define Z_IS_2722_EQ_2722(...) \, -#define Z_IS_2723_EQ_2723(...) \, -#define Z_IS_2724_EQ_2724(...) \, -#define Z_IS_2725_EQ_2725(...) \, -#define Z_IS_2726_EQ_2726(...) \, -#define Z_IS_2727_EQ_2727(...) \, -#define Z_IS_2728_EQ_2728(...) \, -#define Z_IS_2729_EQ_2729(...) \, -#define Z_IS_2730_EQ_2730(...) \, -#define Z_IS_2731_EQ_2731(...) \, -#define Z_IS_2732_EQ_2732(...) \, -#define Z_IS_2733_EQ_2733(...) \, -#define Z_IS_2734_EQ_2734(...) \, -#define Z_IS_2735_EQ_2735(...) \, -#define Z_IS_2736_EQ_2736(...) \, -#define Z_IS_2737_EQ_2737(...) \, -#define Z_IS_2738_EQ_2738(...) \, -#define Z_IS_2739_EQ_2739(...) \, -#define Z_IS_2740_EQ_2740(...) \, -#define Z_IS_2741_EQ_2741(...) \, -#define Z_IS_2742_EQ_2742(...) \, -#define Z_IS_2743_EQ_2743(...) \, -#define Z_IS_2744_EQ_2744(...) \, -#define Z_IS_2745_EQ_2745(...) \, -#define Z_IS_2746_EQ_2746(...) \, -#define Z_IS_2747_EQ_2747(...) \, -#define Z_IS_2748_EQ_2748(...) \, -#define Z_IS_2749_EQ_2749(...) \, -#define Z_IS_2750_EQ_2750(...) \, -#define Z_IS_2751_EQ_2751(...) \, -#define Z_IS_2752_EQ_2752(...) \, -#define Z_IS_2753_EQ_2753(...) \, -#define Z_IS_2754_EQ_2754(...) \, -#define Z_IS_2755_EQ_2755(...) \, -#define Z_IS_2756_EQ_2756(...) \, -#define Z_IS_2757_EQ_2757(...) \, -#define Z_IS_2758_EQ_2758(...) \, -#define Z_IS_2759_EQ_2759(...) \, -#define Z_IS_2760_EQ_2760(...) \, -#define Z_IS_2761_EQ_2761(...) \, -#define Z_IS_2762_EQ_2762(...) \, -#define Z_IS_2763_EQ_2763(...) \, -#define Z_IS_2764_EQ_2764(...) \, -#define Z_IS_2765_EQ_2765(...) \, -#define Z_IS_2766_EQ_2766(...) \, -#define Z_IS_2767_EQ_2767(...) \, -#define Z_IS_2768_EQ_2768(...) \, -#define Z_IS_2769_EQ_2769(...) \, -#define Z_IS_2770_EQ_2770(...) \, -#define Z_IS_2771_EQ_2771(...) \, -#define Z_IS_2772_EQ_2772(...) \, -#define Z_IS_2773_EQ_2773(...) \, -#define Z_IS_2774_EQ_2774(...) \, -#define Z_IS_2775_EQ_2775(...) \, -#define Z_IS_2776_EQ_2776(...) \, -#define Z_IS_2777_EQ_2777(...) \, -#define Z_IS_2778_EQ_2778(...) \, -#define Z_IS_2779_EQ_2779(...) \, -#define Z_IS_2780_EQ_2780(...) \, -#define Z_IS_2781_EQ_2781(...) \, -#define Z_IS_2782_EQ_2782(...) \, -#define Z_IS_2783_EQ_2783(...) \, -#define Z_IS_2784_EQ_2784(...) \, -#define Z_IS_2785_EQ_2785(...) \, -#define Z_IS_2786_EQ_2786(...) \, -#define Z_IS_2787_EQ_2787(...) \, -#define Z_IS_2788_EQ_2788(...) \, -#define Z_IS_2789_EQ_2789(...) \, -#define Z_IS_2790_EQ_2790(...) \, -#define Z_IS_2791_EQ_2791(...) \, -#define Z_IS_2792_EQ_2792(...) \, -#define Z_IS_2793_EQ_2793(...) \, -#define Z_IS_2794_EQ_2794(...) \, -#define Z_IS_2795_EQ_2795(...) \, -#define Z_IS_2796_EQ_2796(...) \, -#define Z_IS_2797_EQ_2797(...) \, -#define Z_IS_2798_EQ_2798(...) \, -#define Z_IS_2799_EQ_2799(...) \, -#define Z_IS_2800_EQ_2800(...) \, -#define Z_IS_2801_EQ_2801(...) \, -#define Z_IS_2802_EQ_2802(...) \, -#define Z_IS_2803_EQ_2803(...) \, -#define Z_IS_2804_EQ_2804(...) \, -#define Z_IS_2805_EQ_2805(...) \, -#define Z_IS_2806_EQ_2806(...) \, -#define Z_IS_2807_EQ_2807(...) \, -#define Z_IS_2808_EQ_2808(...) \, -#define Z_IS_2809_EQ_2809(...) \, -#define Z_IS_2810_EQ_2810(...) \, -#define Z_IS_2811_EQ_2811(...) \, -#define Z_IS_2812_EQ_2812(...) \, -#define Z_IS_2813_EQ_2813(...) \, -#define Z_IS_2814_EQ_2814(...) \, -#define Z_IS_2815_EQ_2815(...) \, -#define Z_IS_2816_EQ_2816(...) \, -#define Z_IS_2817_EQ_2817(...) \, -#define Z_IS_2818_EQ_2818(...) \, -#define Z_IS_2819_EQ_2819(...) \, -#define Z_IS_2820_EQ_2820(...) \, -#define Z_IS_2821_EQ_2821(...) \, -#define Z_IS_2822_EQ_2822(...) \, -#define Z_IS_2823_EQ_2823(...) \, -#define Z_IS_2824_EQ_2824(...) \, -#define Z_IS_2825_EQ_2825(...) \, -#define Z_IS_2826_EQ_2826(...) \, -#define Z_IS_2827_EQ_2827(...) \, -#define Z_IS_2828_EQ_2828(...) \, -#define Z_IS_2829_EQ_2829(...) \, -#define Z_IS_2830_EQ_2830(...) \, -#define Z_IS_2831_EQ_2831(...) \, -#define Z_IS_2832_EQ_2832(...) \, -#define Z_IS_2833_EQ_2833(...) \, -#define Z_IS_2834_EQ_2834(...) \, -#define Z_IS_2835_EQ_2835(...) \, -#define Z_IS_2836_EQ_2836(...) \, -#define Z_IS_2837_EQ_2837(...) \, -#define Z_IS_2838_EQ_2838(...) \, -#define Z_IS_2839_EQ_2839(...) \, -#define Z_IS_2840_EQ_2840(...) \, -#define Z_IS_2841_EQ_2841(...) \, -#define Z_IS_2842_EQ_2842(...) \, -#define Z_IS_2843_EQ_2843(...) \, -#define Z_IS_2844_EQ_2844(...) \, -#define Z_IS_2845_EQ_2845(...) \, -#define Z_IS_2846_EQ_2846(...) \, -#define Z_IS_2847_EQ_2847(...) \, -#define Z_IS_2848_EQ_2848(...) \, -#define Z_IS_2849_EQ_2849(...) \, -#define Z_IS_2850_EQ_2850(...) \, -#define Z_IS_2851_EQ_2851(...) \, -#define Z_IS_2852_EQ_2852(...) \, -#define Z_IS_2853_EQ_2853(...) \, -#define Z_IS_2854_EQ_2854(...) \, -#define Z_IS_2855_EQ_2855(...) \, -#define Z_IS_2856_EQ_2856(...) \, -#define Z_IS_2857_EQ_2857(...) \, -#define Z_IS_2858_EQ_2858(...) \, -#define Z_IS_2859_EQ_2859(...) \, -#define Z_IS_2860_EQ_2860(...) \, -#define Z_IS_2861_EQ_2861(...) \, -#define Z_IS_2862_EQ_2862(...) \, -#define Z_IS_2863_EQ_2863(...) \, -#define Z_IS_2864_EQ_2864(...) \, -#define Z_IS_2865_EQ_2865(...) \, -#define Z_IS_2866_EQ_2866(...) \, -#define Z_IS_2867_EQ_2867(...) \, -#define Z_IS_2868_EQ_2868(...) \, -#define Z_IS_2869_EQ_2869(...) \, -#define Z_IS_2870_EQ_2870(...) \, -#define Z_IS_2871_EQ_2871(...) \, -#define Z_IS_2872_EQ_2872(...) \, -#define Z_IS_2873_EQ_2873(...) \, -#define Z_IS_2874_EQ_2874(...) \, -#define Z_IS_2875_EQ_2875(...) \, -#define Z_IS_2876_EQ_2876(...) \, -#define Z_IS_2877_EQ_2877(...) \, -#define Z_IS_2878_EQ_2878(...) \, -#define Z_IS_2879_EQ_2879(...) \, -#define Z_IS_2880_EQ_2880(...) \, -#define Z_IS_2881_EQ_2881(...) \, -#define Z_IS_2882_EQ_2882(...) \, -#define Z_IS_2883_EQ_2883(...) \, -#define Z_IS_2884_EQ_2884(...) \, -#define Z_IS_2885_EQ_2885(...) \, -#define Z_IS_2886_EQ_2886(...) \, -#define Z_IS_2887_EQ_2887(...) \, -#define Z_IS_2888_EQ_2888(...) \, -#define Z_IS_2889_EQ_2889(...) \, -#define Z_IS_2890_EQ_2890(...) \, -#define Z_IS_2891_EQ_2891(...) \, -#define Z_IS_2892_EQ_2892(...) \, -#define Z_IS_2893_EQ_2893(...) \, -#define Z_IS_2894_EQ_2894(...) \, -#define Z_IS_2895_EQ_2895(...) \, -#define Z_IS_2896_EQ_2896(...) \, -#define Z_IS_2897_EQ_2897(...) \, -#define Z_IS_2898_EQ_2898(...) \, -#define Z_IS_2899_EQ_2899(...) \, -#define Z_IS_2900_EQ_2900(...) \, -#define Z_IS_2901_EQ_2901(...) \, -#define Z_IS_2902_EQ_2902(...) \, -#define Z_IS_2903_EQ_2903(...) \, -#define Z_IS_2904_EQ_2904(...) \, -#define Z_IS_2905_EQ_2905(...) \, -#define Z_IS_2906_EQ_2906(...) \, -#define Z_IS_2907_EQ_2907(...) \, -#define Z_IS_2908_EQ_2908(...) \, -#define Z_IS_2909_EQ_2909(...) \, -#define Z_IS_2910_EQ_2910(...) \, -#define Z_IS_2911_EQ_2911(...) \, -#define Z_IS_2912_EQ_2912(...) \, -#define Z_IS_2913_EQ_2913(...) \, -#define Z_IS_2914_EQ_2914(...) \, -#define Z_IS_2915_EQ_2915(...) \, -#define Z_IS_2916_EQ_2916(...) \, -#define Z_IS_2917_EQ_2917(...) \, -#define Z_IS_2918_EQ_2918(...) \, -#define Z_IS_2919_EQ_2919(...) \, -#define Z_IS_2920_EQ_2920(...) \, -#define Z_IS_2921_EQ_2921(...) \, -#define Z_IS_2922_EQ_2922(...) \, -#define Z_IS_2923_EQ_2923(...) \, -#define Z_IS_2924_EQ_2924(...) \, -#define Z_IS_2925_EQ_2925(...) \, -#define Z_IS_2926_EQ_2926(...) \, -#define Z_IS_2927_EQ_2927(...) \, -#define Z_IS_2928_EQ_2928(...) \, -#define Z_IS_2929_EQ_2929(...) \, -#define Z_IS_2930_EQ_2930(...) \, -#define Z_IS_2931_EQ_2931(...) \, -#define Z_IS_2932_EQ_2932(...) \, -#define Z_IS_2933_EQ_2933(...) \, -#define Z_IS_2934_EQ_2934(...) \, -#define Z_IS_2935_EQ_2935(...) \, -#define Z_IS_2936_EQ_2936(...) \, -#define Z_IS_2937_EQ_2937(...) \, -#define Z_IS_2938_EQ_2938(...) \, -#define Z_IS_2939_EQ_2939(...) \, -#define Z_IS_2940_EQ_2940(...) \, -#define Z_IS_2941_EQ_2941(...) \, -#define Z_IS_2942_EQ_2942(...) \, -#define Z_IS_2943_EQ_2943(...) \, -#define Z_IS_2944_EQ_2944(...) \, -#define Z_IS_2945_EQ_2945(...) \, -#define Z_IS_2946_EQ_2946(...) \, -#define Z_IS_2947_EQ_2947(...) \, -#define Z_IS_2948_EQ_2948(...) \, -#define Z_IS_2949_EQ_2949(...) \, -#define Z_IS_2950_EQ_2950(...) \, -#define Z_IS_2951_EQ_2951(...) \, -#define Z_IS_2952_EQ_2952(...) \, -#define Z_IS_2953_EQ_2953(...) \, -#define Z_IS_2954_EQ_2954(...) \, -#define Z_IS_2955_EQ_2955(...) \, -#define Z_IS_2956_EQ_2956(...) \, -#define Z_IS_2957_EQ_2957(...) \, -#define Z_IS_2958_EQ_2958(...) \, -#define Z_IS_2959_EQ_2959(...) \, -#define Z_IS_2960_EQ_2960(...) \, -#define Z_IS_2961_EQ_2961(...) \, -#define Z_IS_2962_EQ_2962(...) \, -#define Z_IS_2963_EQ_2963(...) \, -#define Z_IS_2964_EQ_2964(...) \, -#define Z_IS_2965_EQ_2965(...) \, -#define Z_IS_2966_EQ_2966(...) \, -#define Z_IS_2967_EQ_2967(...) \, -#define Z_IS_2968_EQ_2968(...) \, -#define Z_IS_2969_EQ_2969(...) \, -#define Z_IS_2970_EQ_2970(...) \, -#define Z_IS_2971_EQ_2971(...) \, -#define Z_IS_2972_EQ_2972(...) \, -#define Z_IS_2973_EQ_2973(...) \, -#define Z_IS_2974_EQ_2974(...) \, -#define Z_IS_2975_EQ_2975(...) \, -#define Z_IS_2976_EQ_2976(...) \, -#define Z_IS_2977_EQ_2977(...) \, -#define Z_IS_2978_EQ_2978(...) \, -#define Z_IS_2979_EQ_2979(...) \, -#define Z_IS_2980_EQ_2980(...) \, -#define Z_IS_2981_EQ_2981(...) \, -#define Z_IS_2982_EQ_2982(...) \, -#define Z_IS_2983_EQ_2983(...) \, -#define Z_IS_2984_EQ_2984(...) \, -#define Z_IS_2985_EQ_2985(...) \, -#define Z_IS_2986_EQ_2986(...) \, -#define Z_IS_2987_EQ_2987(...) \, -#define Z_IS_2988_EQ_2988(...) \, -#define Z_IS_2989_EQ_2989(...) \, -#define Z_IS_2990_EQ_2990(...) \, -#define Z_IS_2991_EQ_2991(...) \, -#define Z_IS_2992_EQ_2992(...) \, -#define Z_IS_2993_EQ_2993(...) \, -#define Z_IS_2994_EQ_2994(...) \, -#define Z_IS_2995_EQ_2995(...) \, -#define Z_IS_2996_EQ_2996(...) \, -#define Z_IS_2997_EQ_2997(...) \, -#define Z_IS_2998_EQ_2998(...) \, -#define Z_IS_2999_EQ_2999(...) \, -#define Z_IS_3000_EQ_3000(...) \, -#define Z_IS_3001_EQ_3001(...) \, -#define Z_IS_3002_EQ_3002(...) \, -#define Z_IS_3003_EQ_3003(...) \, -#define Z_IS_3004_EQ_3004(...) \, -#define Z_IS_3005_EQ_3005(...) \, -#define Z_IS_3006_EQ_3006(...) \, -#define Z_IS_3007_EQ_3007(...) \, -#define Z_IS_3008_EQ_3008(...) \, -#define Z_IS_3009_EQ_3009(...) \, -#define Z_IS_3010_EQ_3010(...) \, -#define Z_IS_3011_EQ_3011(...) \, -#define Z_IS_3012_EQ_3012(...) \, -#define Z_IS_3013_EQ_3013(...) \, -#define Z_IS_3014_EQ_3014(...) \, -#define Z_IS_3015_EQ_3015(...) \, -#define Z_IS_3016_EQ_3016(...) \, -#define Z_IS_3017_EQ_3017(...) \, -#define Z_IS_3018_EQ_3018(...) \, -#define Z_IS_3019_EQ_3019(...) \, -#define Z_IS_3020_EQ_3020(...) \, -#define Z_IS_3021_EQ_3021(...) \, -#define Z_IS_3022_EQ_3022(...) \, -#define Z_IS_3023_EQ_3023(...) \, -#define Z_IS_3024_EQ_3024(...) \, -#define Z_IS_3025_EQ_3025(...) \, -#define Z_IS_3026_EQ_3026(...) \, -#define Z_IS_3027_EQ_3027(...) \, -#define Z_IS_3028_EQ_3028(...) \, -#define Z_IS_3029_EQ_3029(...) \, -#define Z_IS_3030_EQ_3030(...) \, -#define Z_IS_3031_EQ_3031(...) \, -#define Z_IS_3032_EQ_3032(...) \, -#define Z_IS_3033_EQ_3033(...) \, -#define Z_IS_3034_EQ_3034(...) \, -#define Z_IS_3035_EQ_3035(...) \, -#define Z_IS_3036_EQ_3036(...) \, -#define Z_IS_3037_EQ_3037(...) \, -#define Z_IS_3038_EQ_3038(...) \, -#define Z_IS_3039_EQ_3039(...) \, -#define Z_IS_3040_EQ_3040(...) \, -#define Z_IS_3041_EQ_3041(...) \, -#define Z_IS_3042_EQ_3042(...) \, -#define Z_IS_3043_EQ_3043(...) \, -#define Z_IS_3044_EQ_3044(...) \, -#define Z_IS_3045_EQ_3045(...) \, -#define Z_IS_3046_EQ_3046(...) \, -#define Z_IS_3047_EQ_3047(...) \, -#define Z_IS_3048_EQ_3048(...) \, -#define Z_IS_3049_EQ_3049(...) \, -#define Z_IS_3050_EQ_3050(...) \, -#define Z_IS_3051_EQ_3051(...) \, -#define Z_IS_3052_EQ_3052(...) \, -#define Z_IS_3053_EQ_3053(...) \, -#define Z_IS_3054_EQ_3054(...) \, -#define Z_IS_3055_EQ_3055(...) \, -#define Z_IS_3056_EQ_3056(...) \, -#define Z_IS_3057_EQ_3057(...) \, -#define Z_IS_3058_EQ_3058(...) \, -#define Z_IS_3059_EQ_3059(...) \, -#define Z_IS_3060_EQ_3060(...) \, -#define Z_IS_3061_EQ_3061(...) \, -#define Z_IS_3062_EQ_3062(...) \, -#define Z_IS_3063_EQ_3063(...) \, -#define Z_IS_3064_EQ_3064(...) \, -#define Z_IS_3065_EQ_3065(...) \, -#define Z_IS_3066_EQ_3066(...) \, -#define Z_IS_3067_EQ_3067(...) \, -#define Z_IS_3068_EQ_3068(...) \, -#define Z_IS_3069_EQ_3069(...) \, -#define Z_IS_3070_EQ_3070(...) \, -#define Z_IS_3071_EQ_3071(...) \, -#define Z_IS_3072_EQ_3072(...) \, -#define Z_IS_3073_EQ_3073(...) \, -#define Z_IS_3074_EQ_3074(...) \, -#define Z_IS_3075_EQ_3075(...) \, -#define Z_IS_3076_EQ_3076(...) \, -#define Z_IS_3077_EQ_3077(...) \, -#define Z_IS_3078_EQ_3078(...) \, -#define Z_IS_3079_EQ_3079(...) \, -#define Z_IS_3080_EQ_3080(...) \, -#define Z_IS_3081_EQ_3081(...) \, -#define Z_IS_3082_EQ_3082(...) \, -#define Z_IS_3083_EQ_3083(...) \, -#define Z_IS_3084_EQ_3084(...) \, -#define Z_IS_3085_EQ_3085(...) \, -#define Z_IS_3086_EQ_3086(...) \, -#define Z_IS_3087_EQ_3087(...) \, -#define Z_IS_3088_EQ_3088(...) \, -#define Z_IS_3089_EQ_3089(...) \, -#define Z_IS_3090_EQ_3090(...) \, -#define Z_IS_3091_EQ_3091(...) \, -#define Z_IS_3092_EQ_3092(...) \, -#define Z_IS_3093_EQ_3093(...) \, -#define Z_IS_3094_EQ_3094(...) \, -#define Z_IS_3095_EQ_3095(...) \, -#define Z_IS_3096_EQ_3096(...) \, -#define Z_IS_3097_EQ_3097(...) \, -#define Z_IS_3098_EQ_3098(...) \, -#define Z_IS_3099_EQ_3099(...) \, -#define Z_IS_3100_EQ_3100(...) \, -#define Z_IS_3101_EQ_3101(...) \, -#define Z_IS_3102_EQ_3102(...) \, -#define Z_IS_3103_EQ_3103(...) \, -#define Z_IS_3104_EQ_3104(...) \, -#define Z_IS_3105_EQ_3105(...) \, -#define Z_IS_3106_EQ_3106(...) \, -#define Z_IS_3107_EQ_3107(...) \, -#define Z_IS_3108_EQ_3108(...) \, -#define Z_IS_3109_EQ_3109(...) \, -#define Z_IS_3110_EQ_3110(...) \, -#define Z_IS_3111_EQ_3111(...) \, -#define Z_IS_3112_EQ_3112(...) \, -#define Z_IS_3113_EQ_3113(...) \, -#define Z_IS_3114_EQ_3114(...) \, -#define Z_IS_3115_EQ_3115(...) \, -#define Z_IS_3116_EQ_3116(...) \, -#define Z_IS_3117_EQ_3117(...) \, -#define Z_IS_3118_EQ_3118(...) \, -#define Z_IS_3119_EQ_3119(...) \, -#define Z_IS_3120_EQ_3120(...) \, -#define Z_IS_3121_EQ_3121(...) \, -#define Z_IS_3122_EQ_3122(...) \, -#define Z_IS_3123_EQ_3123(...) \, -#define Z_IS_3124_EQ_3124(...) \, -#define Z_IS_3125_EQ_3125(...) \, -#define Z_IS_3126_EQ_3126(...) \, -#define Z_IS_3127_EQ_3127(...) \, -#define Z_IS_3128_EQ_3128(...) \, -#define Z_IS_3129_EQ_3129(...) \, -#define Z_IS_3130_EQ_3130(...) \, -#define Z_IS_3131_EQ_3131(...) \, -#define Z_IS_3132_EQ_3132(...) \, -#define Z_IS_3133_EQ_3133(...) \, -#define Z_IS_3134_EQ_3134(...) \, -#define Z_IS_3135_EQ_3135(...) \, -#define Z_IS_3136_EQ_3136(...) \, -#define Z_IS_3137_EQ_3137(...) \, -#define Z_IS_3138_EQ_3138(...) \, -#define Z_IS_3139_EQ_3139(...) \, -#define Z_IS_3140_EQ_3140(...) \, -#define Z_IS_3141_EQ_3141(...) \, -#define Z_IS_3142_EQ_3142(...) \, -#define Z_IS_3143_EQ_3143(...) \, -#define Z_IS_3144_EQ_3144(...) \, -#define Z_IS_3145_EQ_3145(...) \, -#define Z_IS_3146_EQ_3146(...) \, -#define Z_IS_3147_EQ_3147(...) \, -#define Z_IS_3148_EQ_3148(...) \, -#define Z_IS_3149_EQ_3149(...) \, -#define Z_IS_3150_EQ_3150(...) \, -#define Z_IS_3151_EQ_3151(...) \, -#define Z_IS_3152_EQ_3152(...) \, -#define Z_IS_3153_EQ_3153(...) \, -#define Z_IS_3154_EQ_3154(...) \, -#define Z_IS_3155_EQ_3155(...) \, -#define Z_IS_3156_EQ_3156(...) \, -#define Z_IS_3157_EQ_3157(...) \, -#define Z_IS_3158_EQ_3158(...) \, -#define Z_IS_3159_EQ_3159(...) \, -#define Z_IS_3160_EQ_3160(...) \, -#define Z_IS_3161_EQ_3161(...) \, -#define Z_IS_3162_EQ_3162(...) \, -#define Z_IS_3163_EQ_3163(...) \, -#define Z_IS_3164_EQ_3164(...) \, -#define Z_IS_3165_EQ_3165(...) \, -#define Z_IS_3166_EQ_3166(...) \, -#define Z_IS_3167_EQ_3167(...) \, -#define Z_IS_3168_EQ_3168(...) \, -#define Z_IS_3169_EQ_3169(...) \, -#define Z_IS_3170_EQ_3170(...) \, -#define Z_IS_3171_EQ_3171(...) \, -#define Z_IS_3172_EQ_3172(...) \, -#define Z_IS_3173_EQ_3173(...) \, -#define Z_IS_3174_EQ_3174(...) \, -#define Z_IS_3175_EQ_3175(...) \, -#define Z_IS_3176_EQ_3176(...) \, -#define Z_IS_3177_EQ_3177(...) \, -#define Z_IS_3178_EQ_3178(...) \, -#define Z_IS_3179_EQ_3179(...) \, -#define Z_IS_3180_EQ_3180(...) \, -#define Z_IS_3181_EQ_3181(...) \, -#define Z_IS_3182_EQ_3182(...) \, -#define Z_IS_3183_EQ_3183(...) \, -#define Z_IS_3184_EQ_3184(...) \, -#define Z_IS_3185_EQ_3185(...) \, -#define Z_IS_3186_EQ_3186(...) \, -#define Z_IS_3187_EQ_3187(...) \, -#define Z_IS_3188_EQ_3188(...) \, -#define Z_IS_3189_EQ_3189(...) \, -#define Z_IS_3190_EQ_3190(...) \, -#define Z_IS_3191_EQ_3191(...) \, -#define Z_IS_3192_EQ_3192(...) \, -#define Z_IS_3193_EQ_3193(...) \, -#define Z_IS_3194_EQ_3194(...) \, -#define Z_IS_3195_EQ_3195(...) \, -#define Z_IS_3196_EQ_3196(...) \, -#define Z_IS_3197_EQ_3197(...) \, -#define Z_IS_3198_EQ_3198(...) \, -#define Z_IS_3199_EQ_3199(...) \, -#define Z_IS_3200_EQ_3200(...) \, -#define Z_IS_3201_EQ_3201(...) \, -#define Z_IS_3202_EQ_3202(...) \, -#define Z_IS_3203_EQ_3203(...) \, -#define Z_IS_3204_EQ_3204(...) \, -#define Z_IS_3205_EQ_3205(...) \, -#define Z_IS_3206_EQ_3206(...) \, -#define Z_IS_3207_EQ_3207(...) \, -#define Z_IS_3208_EQ_3208(...) \, -#define Z_IS_3209_EQ_3209(...) \, -#define Z_IS_3210_EQ_3210(...) \, -#define Z_IS_3211_EQ_3211(...) \, -#define Z_IS_3212_EQ_3212(...) \, -#define Z_IS_3213_EQ_3213(...) \, -#define Z_IS_3214_EQ_3214(...) \, -#define Z_IS_3215_EQ_3215(...) \, -#define Z_IS_3216_EQ_3216(...) \, -#define Z_IS_3217_EQ_3217(...) \, -#define Z_IS_3218_EQ_3218(...) \, -#define Z_IS_3219_EQ_3219(...) \, -#define Z_IS_3220_EQ_3220(...) \, -#define Z_IS_3221_EQ_3221(...) \, -#define Z_IS_3222_EQ_3222(...) \, -#define Z_IS_3223_EQ_3223(...) \, -#define Z_IS_3224_EQ_3224(...) \, -#define Z_IS_3225_EQ_3225(...) \, -#define Z_IS_3226_EQ_3226(...) \, -#define Z_IS_3227_EQ_3227(...) \, -#define Z_IS_3228_EQ_3228(...) \, -#define Z_IS_3229_EQ_3229(...) \, -#define Z_IS_3230_EQ_3230(...) \, -#define Z_IS_3231_EQ_3231(...) \, -#define Z_IS_3232_EQ_3232(...) \, -#define Z_IS_3233_EQ_3233(...) \, -#define Z_IS_3234_EQ_3234(...) \, -#define Z_IS_3235_EQ_3235(...) \, -#define Z_IS_3236_EQ_3236(...) \, -#define Z_IS_3237_EQ_3237(...) \, -#define Z_IS_3238_EQ_3238(...) \, -#define Z_IS_3239_EQ_3239(...) \, -#define Z_IS_3240_EQ_3240(...) \, -#define Z_IS_3241_EQ_3241(...) \, -#define Z_IS_3242_EQ_3242(...) \, -#define Z_IS_3243_EQ_3243(...) \, -#define Z_IS_3244_EQ_3244(...) \, -#define Z_IS_3245_EQ_3245(...) \, -#define Z_IS_3246_EQ_3246(...) \, -#define Z_IS_3247_EQ_3247(...) \, -#define Z_IS_3248_EQ_3248(...) \, -#define Z_IS_3249_EQ_3249(...) \, -#define Z_IS_3250_EQ_3250(...) \, -#define Z_IS_3251_EQ_3251(...) \, -#define Z_IS_3252_EQ_3252(...) \, -#define Z_IS_3253_EQ_3253(...) \, -#define Z_IS_3254_EQ_3254(...) \, -#define Z_IS_3255_EQ_3255(...) \, -#define Z_IS_3256_EQ_3256(...) \, -#define Z_IS_3257_EQ_3257(...) \, -#define Z_IS_3258_EQ_3258(...) \, -#define Z_IS_3259_EQ_3259(...) \, -#define Z_IS_3260_EQ_3260(...) \, -#define Z_IS_3261_EQ_3261(...) \, -#define Z_IS_3262_EQ_3262(...) \, -#define Z_IS_3263_EQ_3263(...) \, -#define Z_IS_3264_EQ_3264(...) \, -#define Z_IS_3265_EQ_3265(...) \, -#define Z_IS_3266_EQ_3266(...) \, -#define Z_IS_3267_EQ_3267(...) \, -#define Z_IS_3268_EQ_3268(...) \, -#define Z_IS_3269_EQ_3269(...) \, -#define Z_IS_3270_EQ_3270(...) \, -#define Z_IS_3271_EQ_3271(...) \, -#define Z_IS_3272_EQ_3272(...) \, -#define Z_IS_3273_EQ_3273(...) \, -#define Z_IS_3274_EQ_3274(...) \, -#define Z_IS_3275_EQ_3275(...) \, -#define Z_IS_3276_EQ_3276(...) \, -#define Z_IS_3277_EQ_3277(...) \, -#define Z_IS_3278_EQ_3278(...) \, -#define Z_IS_3279_EQ_3279(...) \, -#define Z_IS_3280_EQ_3280(...) \, -#define Z_IS_3281_EQ_3281(...) \, -#define Z_IS_3282_EQ_3282(...) \, -#define Z_IS_3283_EQ_3283(...) \, -#define Z_IS_3284_EQ_3284(...) \, -#define Z_IS_3285_EQ_3285(...) \, -#define Z_IS_3286_EQ_3286(...) \, -#define Z_IS_3287_EQ_3287(...) \, -#define Z_IS_3288_EQ_3288(...) \, -#define Z_IS_3289_EQ_3289(...) \, -#define Z_IS_3290_EQ_3290(...) \, -#define Z_IS_3291_EQ_3291(...) \, -#define Z_IS_3292_EQ_3292(...) \, -#define Z_IS_3293_EQ_3293(...) \, -#define Z_IS_3294_EQ_3294(...) \, -#define Z_IS_3295_EQ_3295(...) \, -#define Z_IS_3296_EQ_3296(...) \, -#define Z_IS_3297_EQ_3297(...) \, -#define Z_IS_3298_EQ_3298(...) \, -#define Z_IS_3299_EQ_3299(...) \, -#define Z_IS_3300_EQ_3300(...) \, -#define Z_IS_3301_EQ_3301(...) \, -#define Z_IS_3302_EQ_3302(...) \, -#define Z_IS_3303_EQ_3303(...) \, -#define Z_IS_3304_EQ_3304(...) \, -#define Z_IS_3305_EQ_3305(...) \, -#define Z_IS_3306_EQ_3306(...) \, -#define Z_IS_3307_EQ_3307(...) \, -#define Z_IS_3308_EQ_3308(...) \, -#define Z_IS_3309_EQ_3309(...) \, -#define Z_IS_3310_EQ_3310(...) \, -#define Z_IS_3311_EQ_3311(...) \, -#define Z_IS_3312_EQ_3312(...) \, -#define Z_IS_3313_EQ_3313(...) \, -#define Z_IS_3314_EQ_3314(...) \, -#define Z_IS_3315_EQ_3315(...) \, -#define Z_IS_3316_EQ_3316(...) \, -#define Z_IS_3317_EQ_3317(...) \, -#define Z_IS_3318_EQ_3318(...) \, -#define Z_IS_3319_EQ_3319(...) \, -#define Z_IS_3320_EQ_3320(...) \, -#define Z_IS_3321_EQ_3321(...) \, -#define Z_IS_3322_EQ_3322(...) \, -#define Z_IS_3323_EQ_3323(...) \, -#define Z_IS_3324_EQ_3324(...) \, -#define Z_IS_3325_EQ_3325(...) \, -#define Z_IS_3326_EQ_3326(...) \, -#define Z_IS_3327_EQ_3327(...) \, -#define Z_IS_3328_EQ_3328(...) \, -#define Z_IS_3329_EQ_3329(...) \, -#define Z_IS_3330_EQ_3330(...) \, -#define Z_IS_3331_EQ_3331(...) \, -#define Z_IS_3332_EQ_3332(...) \, -#define Z_IS_3333_EQ_3333(...) \, -#define Z_IS_3334_EQ_3334(...) \, -#define Z_IS_3335_EQ_3335(...) \, -#define Z_IS_3336_EQ_3336(...) \, -#define Z_IS_3337_EQ_3337(...) \, -#define Z_IS_3338_EQ_3338(...) \, -#define Z_IS_3339_EQ_3339(...) \, -#define Z_IS_3340_EQ_3340(...) \, -#define Z_IS_3341_EQ_3341(...) \, -#define Z_IS_3342_EQ_3342(...) \, -#define Z_IS_3343_EQ_3343(...) \, -#define Z_IS_3344_EQ_3344(...) \, -#define Z_IS_3345_EQ_3345(...) \, -#define Z_IS_3346_EQ_3346(...) \, -#define Z_IS_3347_EQ_3347(...) \, -#define Z_IS_3348_EQ_3348(...) \, -#define Z_IS_3349_EQ_3349(...) \, -#define Z_IS_3350_EQ_3350(...) \, -#define Z_IS_3351_EQ_3351(...) \, -#define Z_IS_3352_EQ_3352(...) \, -#define Z_IS_3353_EQ_3353(...) \, -#define Z_IS_3354_EQ_3354(...) \, -#define Z_IS_3355_EQ_3355(...) \, -#define Z_IS_3356_EQ_3356(...) \, -#define Z_IS_3357_EQ_3357(...) \, -#define Z_IS_3358_EQ_3358(...) \, -#define Z_IS_3359_EQ_3359(...) \, -#define Z_IS_3360_EQ_3360(...) \, -#define Z_IS_3361_EQ_3361(...) \, -#define Z_IS_3362_EQ_3362(...) \, -#define Z_IS_3363_EQ_3363(...) \, -#define Z_IS_3364_EQ_3364(...) \, -#define Z_IS_3365_EQ_3365(...) \, -#define Z_IS_3366_EQ_3366(...) \, -#define Z_IS_3367_EQ_3367(...) \, -#define Z_IS_3368_EQ_3368(...) \, -#define Z_IS_3369_EQ_3369(...) \, -#define Z_IS_3370_EQ_3370(...) \, -#define Z_IS_3371_EQ_3371(...) \, -#define Z_IS_3372_EQ_3372(...) \, -#define Z_IS_3373_EQ_3373(...) \, -#define Z_IS_3374_EQ_3374(...) \, -#define Z_IS_3375_EQ_3375(...) \, -#define Z_IS_3376_EQ_3376(...) \, -#define Z_IS_3377_EQ_3377(...) \, -#define Z_IS_3378_EQ_3378(...) \, -#define Z_IS_3379_EQ_3379(...) \, -#define Z_IS_3380_EQ_3380(...) \, -#define Z_IS_3381_EQ_3381(...) \, -#define Z_IS_3382_EQ_3382(...) \, -#define Z_IS_3383_EQ_3383(...) \, -#define Z_IS_3384_EQ_3384(...) \, -#define Z_IS_3385_EQ_3385(...) \, -#define Z_IS_3386_EQ_3386(...) \, -#define Z_IS_3387_EQ_3387(...) \, -#define Z_IS_3388_EQ_3388(...) \, -#define Z_IS_3389_EQ_3389(...) \, -#define Z_IS_3390_EQ_3390(...) \, -#define Z_IS_3391_EQ_3391(...) \, -#define Z_IS_3392_EQ_3392(...) \, -#define Z_IS_3393_EQ_3393(...) \, -#define Z_IS_3394_EQ_3394(...) \, -#define Z_IS_3395_EQ_3395(...) \, -#define Z_IS_3396_EQ_3396(...) \, -#define Z_IS_3397_EQ_3397(...) \, -#define Z_IS_3398_EQ_3398(...) \, -#define Z_IS_3399_EQ_3399(...) \, -#define Z_IS_3400_EQ_3400(...) \, -#define Z_IS_3401_EQ_3401(...) \, -#define Z_IS_3402_EQ_3402(...) \, -#define Z_IS_3403_EQ_3403(...) \, -#define Z_IS_3404_EQ_3404(...) \, -#define Z_IS_3405_EQ_3405(...) \, -#define Z_IS_3406_EQ_3406(...) \, -#define Z_IS_3407_EQ_3407(...) \, -#define Z_IS_3408_EQ_3408(...) \, -#define Z_IS_3409_EQ_3409(...) \, -#define Z_IS_3410_EQ_3410(...) \, -#define Z_IS_3411_EQ_3411(...) \, -#define Z_IS_3412_EQ_3412(...) \, -#define Z_IS_3413_EQ_3413(...) \, -#define Z_IS_3414_EQ_3414(...) \, -#define Z_IS_3415_EQ_3415(...) \, -#define Z_IS_3416_EQ_3416(...) \, -#define Z_IS_3417_EQ_3417(...) \, -#define Z_IS_3418_EQ_3418(...) \, -#define Z_IS_3419_EQ_3419(...) \, -#define Z_IS_3420_EQ_3420(...) \, -#define Z_IS_3421_EQ_3421(...) \, -#define Z_IS_3422_EQ_3422(...) \, -#define Z_IS_3423_EQ_3423(...) \, -#define Z_IS_3424_EQ_3424(...) \, -#define Z_IS_3425_EQ_3425(...) \, -#define Z_IS_3426_EQ_3426(...) \, -#define Z_IS_3427_EQ_3427(...) \, -#define Z_IS_3428_EQ_3428(...) \, -#define Z_IS_3429_EQ_3429(...) \, -#define Z_IS_3430_EQ_3430(...) \, -#define Z_IS_3431_EQ_3431(...) \, -#define Z_IS_3432_EQ_3432(...) \, -#define Z_IS_3433_EQ_3433(...) \, -#define Z_IS_3434_EQ_3434(...) \, -#define Z_IS_3435_EQ_3435(...) \, -#define Z_IS_3436_EQ_3436(...) \, -#define Z_IS_3437_EQ_3437(...) \, -#define Z_IS_3438_EQ_3438(...) \, -#define Z_IS_3439_EQ_3439(...) \, -#define Z_IS_3440_EQ_3440(...) \, -#define Z_IS_3441_EQ_3441(...) \, -#define Z_IS_3442_EQ_3442(...) \, -#define Z_IS_3443_EQ_3443(...) \, -#define Z_IS_3444_EQ_3444(...) \, -#define Z_IS_3445_EQ_3445(...) \, -#define Z_IS_3446_EQ_3446(...) \, -#define Z_IS_3447_EQ_3447(...) \, -#define Z_IS_3448_EQ_3448(...) \, -#define Z_IS_3449_EQ_3449(...) \, -#define Z_IS_3450_EQ_3450(...) \, -#define Z_IS_3451_EQ_3451(...) \, -#define Z_IS_3452_EQ_3452(...) \, -#define Z_IS_3453_EQ_3453(...) \, -#define Z_IS_3454_EQ_3454(...) \, -#define Z_IS_3455_EQ_3455(...) \, -#define Z_IS_3456_EQ_3456(...) \, -#define Z_IS_3457_EQ_3457(...) \, -#define Z_IS_3458_EQ_3458(...) \, -#define Z_IS_3459_EQ_3459(...) \, -#define Z_IS_3460_EQ_3460(...) \, -#define Z_IS_3461_EQ_3461(...) \, -#define Z_IS_3462_EQ_3462(...) \, -#define Z_IS_3463_EQ_3463(...) \, -#define Z_IS_3464_EQ_3464(...) \, -#define Z_IS_3465_EQ_3465(...) \, -#define Z_IS_3466_EQ_3466(...) \, -#define Z_IS_3467_EQ_3467(...) \, -#define Z_IS_3468_EQ_3468(...) \, -#define Z_IS_3469_EQ_3469(...) \, -#define Z_IS_3470_EQ_3470(...) \, -#define Z_IS_3471_EQ_3471(...) \, -#define Z_IS_3472_EQ_3472(...) \, -#define Z_IS_3473_EQ_3473(...) \, -#define Z_IS_3474_EQ_3474(...) \, -#define Z_IS_3475_EQ_3475(...) \, -#define Z_IS_3476_EQ_3476(...) \, -#define Z_IS_3477_EQ_3477(...) \, -#define Z_IS_3478_EQ_3478(...) \, -#define Z_IS_3479_EQ_3479(...) \, -#define Z_IS_3480_EQ_3480(...) \, -#define Z_IS_3481_EQ_3481(...) \, -#define Z_IS_3482_EQ_3482(...) \, -#define Z_IS_3483_EQ_3483(...) \, -#define Z_IS_3484_EQ_3484(...) \, -#define Z_IS_3485_EQ_3485(...) \, -#define Z_IS_3486_EQ_3486(...) \, -#define Z_IS_3487_EQ_3487(...) \, -#define Z_IS_3488_EQ_3488(...) \, -#define Z_IS_3489_EQ_3489(...) \, -#define Z_IS_3490_EQ_3490(...) \, -#define Z_IS_3491_EQ_3491(...) \, -#define Z_IS_3492_EQ_3492(...) \, -#define Z_IS_3493_EQ_3493(...) \, -#define Z_IS_3494_EQ_3494(...) \, -#define Z_IS_3495_EQ_3495(...) \, -#define Z_IS_3496_EQ_3496(...) \, -#define Z_IS_3497_EQ_3497(...) \, -#define Z_IS_3498_EQ_3498(...) \, -#define Z_IS_3499_EQ_3499(...) \, -#define Z_IS_3500_EQ_3500(...) \, -#define Z_IS_3501_EQ_3501(...) \, -#define Z_IS_3502_EQ_3502(...) \, -#define Z_IS_3503_EQ_3503(...) \, -#define Z_IS_3504_EQ_3504(...) \, -#define Z_IS_3505_EQ_3505(...) \, -#define Z_IS_3506_EQ_3506(...) \, -#define Z_IS_3507_EQ_3507(...) \, -#define Z_IS_3508_EQ_3508(...) \, -#define Z_IS_3509_EQ_3509(...) \, -#define Z_IS_3510_EQ_3510(...) \, -#define Z_IS_3511_EQ_3511(...) \, -#define Z_IS_3512_EQ_3512(...) \, -#define Z_IS_3513_EQ_3513(...) \, -#define Z_IS_3514_EQ_3514(...) \, -#define Z_IS_3515_EQ_3515(...) \, -#define Z_IS_3516_EQ_3516(...) \, -#define Z_IS_3517_EQ_3517(...) \, -#define Z_IS_3518_EQ_3518(...) \, -#define Z_IS_3519_EQ_3519(...) \, -#define Z_IS_3520_EQ_3520(...) \, -#define Z_IS_3521_EQ_3521(...) \, -#define Z_IS_3522_EQ_3522(...) \, -#define Z_IS_3523_EQ_3523(...) \, -#define Z_IS_3524_EQ_3524(...) \, -#define Z_IS_3525_EQ_3525(...) \, -#define Z_IS_3526_EQ_3526(...) \, -#define Z_IS_3527_EQ_3527(...) \, -#define Z_IS_3528_EQ_3528(...) \, -#define Z_IS_3529_EQ_3529(...) \, -#define Z_IS_3530_EQ_3530(...) \, -#define Z_IS_3531_EQ_3531(...) \, -#define Z_IS_3532_EQ_3532(...) \, -#define Z_IS_3533_EQ_3533(...) \, -#define Z_IS_3534_EQ_3534(...) \, -#define Z_IS_3535_EQ_3535(...) \, -#define Z_IS_3536_EQ_3536(...) \, -#define Z_IS_3537_EQ_3537(...) \, -#define Z_IS_3538_EQ_3538(...) \, -#define Z_IS_3539_EQ_3539(...) \, -#define Z_IS_3540_EQ_3540(...) \, -#define Z_IS_3541_EQ_3541(...) \, -#define Z_IS_3542_EQ_3542(...) \, -#define Z_IS_3543_EQ_3543(...) \, -#define Z_IS_3544_EQ_3544(...) \, -#define Z_IS_3545_EQ_3545(...) \, -#define Z_IS_3546_EQ_3546(...) \, -#define Z_IS_3547_EQ_3547(...) \, -#define Z_IS_3548_EQ_3548(...) \, -#define Z_IS_3549_EQ_3549(...) \, -#define Z_IS_3550_EQ_3550(...) \, -#define Z_IS_3551_EQ_3551(...) \, -#define Z_IS_3552_EQ_3552(...) \, -#define Z_IS_3553_EQ_3553(...) \, -#define Z_IS_3554_EQ_3554(...) \, -#define Z_IS_3555_EQ_3555(...) \, -#define Z_IS_3556_EQ_3556(...) \, -#define Z_IS_3557_EQ_3557(...) \, -#define Z_IS_3558_EQ_3558(...) \, -#define Z_IS_3559_EQ_3559(...) \, -#define Z_IS_3560_EQ_3560(...) \, -#define Z_IS_3561_EQ_3561(...) \, -#define Z_IS_3562_EQ_3562(...) \, -#define Z_IS_3563_EQ_3563(...) \, -#define Z_IS_3564_EQ_3564(...) \, -#define Z_IS_3565_EQ_3565(...) \, -#define Z_IS_3566_EQ_3566(...) \, -#define Z_IS_3567_EQ_3567(...) \, -#define Z_IS_3568_EQ_3568(...) \, -#define Z_IS_3569_EQ_3569(...) \, -#define Z_IS_3570_EQ_3570(...) \, -#define Z_IS_3571_EQ_3571(...) \, -#define Z_IS_3572_EQ_3572(...) \, -#define Z_IS_3573_EQ_3573(...) \, -#define Z_IS_3574_EQ_3574(...) \, -#define Z_IS_3575_EQ_3575(...) \, -#define Z_IS_3576_EQ_3576(...) \, -#define Z_IS_3577_EQ_3577(...) \, -#define Z_IS_3578_EQ_3578(...) \, -#define Z_IS_3579_EQ_3579(...) \, -#define Z_IS_3580_EQ_3580(...) \, -#define Z_IS_3581_EQ_3581(...) \, -#define Z_IS_3582_EQ_3582(...) \, -#define Z_IS_3583_EQ_3583(...) \, -#define Z_IS_3584_EQ_3584(...) \, -#define Z_IS_3585_EQ_3585(...) \, -#define Z_IS_3586_EQ_3586(...) \, -#define Z_IS_3587_EQ_3587(...) \, -#define Z_IS_3588_EQ_3588(...) \, -#define Z_IS_3589_EQ_3589(...) \, -#define Z_IS_3590_EQ_3590(...) \, -#define Z_IS_3591_EQ_3591(...) \, -#define Z_IS_3592_EQ_3592(...) \, -#define Z_IS_3593_EQ_3593(...) \, -#define Z_IS_3594_EQ_3594(...) \, -#define Z_IS_3595_EQ_3595(...) \, -#define Z_IS_3596_EQ_3596(...) \, -#define Z_IS_3597_EQ_3597(...) \, -#define Z_IS_3598_EQ_3598(...) \, -#define Z_IS_3599_EQ_3599(...) \, -#define Z_IS_3600_EQ_3600(...) \, -#define Z_IS_3601_EQ_3601(...) \, -#define Z_IS_3602_EQ_3602(...) \, -#define Z_IS_3603_EQ_3603(...) \, -#define Z_IS_3604_EQ_3604(...) \, -#define Z_IS_3605_EQ_3605(...) \, -#define Z_IS_3606_EQ_3606(...) \, -#define Z_IS_3607_EQ_3607(...) \, -#define Z_IS_3608_EQ_3608(...) \, -#define Z_IS_3609_EQ_3609(...) \, -#define Z_IS_3610_EQ_3610(...) \, -#define Z_IS_3611_EQ_3611(...) \, -#define Z_IS_3612_EQ_3612(...) \, -#define Z_IS_3613_EQ_3613(...) \, -#define Z_IS_3614_EQ_3614(...) \, -#define Z_IS_3615_EQ_3615(...) \, -#define Z_IS_3616_EQ_3616(...) \, -#define Z_IS_3617_EQ_3617(...) \, -#define Z_IS_3618_EQ_3618(...) \, -#define Z_IS_3619_EQ_3619(...) \, -#define Z_IS_3620_EQ_3620(...) \, -#define Z_IS_3621_EQ_3621(...) \, -#define Z_IS_3622_EQ_3622(...) \, -#define Z_IS_3623_EQ_3623(...) \, -#define Z_IS_3624_EQ_3624(...) \, -#define Z_IS_3625_EQ_3625(...) \, -#define Z_IS_3626_EQ_3626(...) \, -#define Z_IS_3627_EQ_3627(...) \, -#define Z_IS_3628_EQ_3628(...) \, -#define Z_IS_3629_EQ_3629(...) \, -#define Z_IS_3630_EQ_3630(...) \, -#define Z_IS_3631_EQ_3631(...) \, -#define Z_IS_3632_EQ_3632(...) \, -#define Z_IS_3633_EQ_3633(...) \, -#define Z_IS_3634_EQ_3634(...) \, -#define Z_IS_3635_EQ_3635(...) \, -#define Z_IS_3636_EQ_3636(...) \, -#define Z_IS_3637_EQ_3637(...) \, -#define Z_IS_3638_EQ_3638(...) \, -#define Z_IS_3639_EQ_3639(...) \, -#define Z_IS_3640_EQ_3640(...) \, -#define Z_IS_3641_EQ_3641(...) \, -#define Z_IS_3642_EQ_3642(...) \, -#define Z_IS_3643_EQ_3643(...) \, -#define Z_IS_3644_EQ_3644(...) \, -#define Z_IS_3645_EQ_3645(...) \, -#define Z_IS_3646_EQ_3646(...) \, -#define Z_IS_3647_EQ_3647(...) \, -#define Z_IS_3648_EQ_3648(...) \, -#define Z_IS_3649_EQ_3649(...) \, -#define Z_IS_3650_EQ_3650(...) \, -#define Z_IS_3651_EQ_3651(...) \, -#define Z_IS_3652_EQ_3652(...) \, -#define Z_IS_3653_EQ_3653(...) \, -#define Z_IS_3654_EQ_3654(...) \, -#define Z_IS_3655_EQ_3655(...) \, -#define Z_IS_3656_EQ_3656(...) \, -#define Z_IS_3657_EQ_3657(...) \, -#define Z_IS_3658_EQ_3658(...) \, -#define Z_IS_3659_EQ_3659(...) \, -#define Z_IS_3660_EQ_3660(...) \, -#define Z_IS_3661_EQ_3661(...) \, -#define Z_IS_3662_EQ_3662(...) \, -#define Z_IS_3663_EQ_3663(...) \, -#define Z_IS_3664_EQ_3664(...) \, -#define Z_IS_3665_EQ_3665(...) \, -#define Z_IS_3666_EQ_3666(...) \, -#define Z_IS_3667_EQ_3667(...) \, -#define Z_IS_3668_EQ_3668(...) \, -#define Z_IS_3669_EQ_3669(...) \, -#define Z_IS_3670_EQ_3670(...) \, -#define Z_IS_3671_EQ_3671(...) \, -#define Z_IS_3672_EQ_3672(...) \, -#define Z_IS_3673_EQ_3673(...) \, -#define Z_IS_3674_EQ_3674(...) \, -#define Z_IS_3675_EQ_3675(...) \, -#define Z_IS_3676_EQ_3676(...) \, -#define Z_IS_3677_EQ_3677(...) \, -#define Z_IS_3678_EQ_3678(...) \, -#define Z_IS_3679_EQ_3679(...) \, -#define Z_IS_3680_EQ_3680(...) \, -#define Z_IS_3681_EQ_3681(...) \, -#define Z_IS_3682_EQ_3682(...) \, -#define Z_IS_3683_EQ_3683(...) \, -#define Z_IS_3684_EQ_3684(...) \, -#define Z_IS_3685_EQ_3685(...) \, -#define Z_IS_3686_EQ_3686(...) \, -#define Z_IS_3687_EQ_3687(...) \, -#define Z_IS_3688_EQ_3688(...) \, -#define Z_IS_3689_EQ_3689(...) \, -#define Z_IS_3690_EQ_3690(...) \, -#define Z_IS_3691_EQ_3691(...) \, -#define Z_IS_3692_EQ_3692(...) \, -#define Z_IS_3693_EQ_3693(...) \, -#define Z_IS_3694_EQ_3694(...) \, -#define Z_IS_3695_EQ_3695(...) \, -#define Z_IS_3696_EQ_3696(...) \, -#define Z_IS_3697_EQ_3697(...) \, -#define Z_IS_3698_EQ_3698(...) \, -#define Z_IS_3699_EQ_3699(...) \, -#define Z_IS_3700_EQ_3700(...) \, -#define Z_IS_3701_EQ_3701(...) \, -#define Z_IS_3702_EQ_3702(...) \, -#define Z_IS_3703_EQ_3703(...) \, -#define Z_IS_3704_EQ_3704(...) \, -#define Z_IS_3705_EQ_3705(...) \, -#define Z_IS_3706_EQ_3706(...) \, -#define Z_IS_3707_EQ_3707(...) \, -#define Z_IS_3708_EQ_3708(...) \, -#define Z_IS_3709_EQ_3709(...) \, -#define Z_IS_3710_EQ_3710(...) \, -#define Z_IS_3711_EQ_3711(...) \, -#define Z_IS_3712_EQ_3712(...) \, -#define Z_IS_3713_EQ_3713(...) \, -#define Z_IS_3714_EQ_3714(...) \, -#define Z_IS_3715_EQ_3715(...) \, -#define Z_IS_3716_EQ_3716(...) \, -#define Z_IS_3717_EQ_3717(...) \, -#define Z_IS_3718_EQ_3718(...) \, -#define Z_IS_3719_EQ_3719(...) \, -#define Z_IS_3720_EQ_3720(...) \, -#define Z_IS_3721_EQ_3721(...) \, -#define Z_IS_3722_EQ_3722(...) \, -#define Z_IS_3723_EQ_3723(...) \, -#define Z_IS_3724_EQ_3724(...) \, -#define Z_IS_3725_EQ_3725(...) \, -#define Z_IS_3726_EQ_3726(...) \, -#define Z_IS_3727_EQ_3727(...) \, -#define Z_IS_3728_EQ_3728(...) \, -#define Z_IS_3729_EQ_3729(...) \, -#define Z_IS_3730_EQ_3730(...) \, -#define Z_IS_3731_EQ_3731(...) \, -#define Z_IS_3732_EQ_3732(...) \, -#define Z_IS_3733_EQ_3733(...) \, -#define Z_IS_3734_EQ_3734(...) \, -#define Z_IS_3735_EQ_3735(...) \, -#define Z_IS_3736_EQ_3736(...) \, -#define Z_IS_3737_EQ_3737(...) \, -#define Z_IS_3738_EQ_3738(...) \, -#define Z_IS_3739_EQ_3739(...) \, -#define Z_IS_3740_EQ_3740(...) \, -#define Z_IS_3741_EQ_3741(...) \, -#define Z_IS_3742_EQ_3742(...) \, -#define Z_IS_3743_EQ_3743(...) \, -#define Z_IS_3744_EQ_3744(...) \, -#define Z_IS_3745_EQ_3745(...) \, -#define Z_IS_3746_EQ_3746(...) \, -#define Z_IS_3747_EQ_3747(...) \, -#define Z_IS_3748_EQ_3748(...) \, -#define Z_IS_3749_EQ_3749(...) \, -#define Z_IS_3750_EQ_3750(...) \, -#define Z_IS_3751_EQ_3751(...) \, -#define Z_IS_3752_EQ_3752(...) \, -#define Z_IS_3753_EQ_3753(...) \, -#define Z_IS_3754_EQ_3754(...) \, -#define Z_IS_3755_EQ_3755(...) \, -#define Z_IS_3756_EQ_3756(...) \, -#define Z_IS_3757_EQ_3757(...) \, -#define Z_IS_3758_EQ_3758(...) \, -#define Z_IS_3759_EQ_3759(...) \, -#define Z_IS_3760_EQ_3760(...) \, -#define Z_IS_3761_EQ_3761(...) \, -#define Z_IS_3762_EQ_3762(...) \, -#define Z_IS_3763_EQ_3763(...) \, -#define Z_IS_3764_EQ_3764(...) \, -#define Z_IS_3765_EQ_3765(...) \, -#define Z_IS_3766_EQ_3766(...) \, -#define Z_IS_3767_EQ_3767(...) \, -#define Z_IS_3768_EQ_3768(...) \, -#define Z_IS_3769_EQ_3769(...) \, -#define Z_IS_3770_EQ_3770(...) \, -#define Z_IS_3771_EQ_3771(...) \, -#define Z_IS_3772_EQ_3772(...) \, -#define Z_IS_3773_EQ_3773(...) \, -#define Z_IS_3774_EQ_3774(...) \, -#define Z_IS_3775_EQ_3775(...) \, -#define Z_IS_3776_EQ_3776(...) \, -#define Z_IS_3777_EQ_3777(...) \, -#define Z_IS_3778_EQ_3778(...) \, -#define Z_IS_3779_EQ_3779(...) \, -#define Z_IS_3780_EQ_3780(...) \, -#define Z_IS_3781_EQ_3781(...) \, -#define Z_IS_3782_EQ_3782(...) \, -#define Z_IS_3783_EQ_3783(...) \, -#define Z_IS_3784_EQ_3784(...) \, -#define Z_IS_3785_EQ_3785(...) \, -#define Z_IS_3786_EQ_3786(...) \, -#define Z_IS_3787_EQ_3787(...) \, -#define Z_IS_3788_EQ_3788(...) \, -#define Z_IS_3789_EQ_3789(...) \, -#define Z_IS_3790_EQ_3790(...) \, -#define Z_IS_3791_EQ_3791(...) \, -#define Z_IS_3792_EQ_3792(...) \, -#define Z_IS_3793_EQ_3793(...) \, -#define Z_IS_3794_EQ_3794(...) \, -#define Z_IS_3795_EQ_3795(...) \, -#define Z_IS_3796_EQ_3796(...) \, -#define Z_IS_3797_EQ_3797(...) \, -#define Z_IS_3798_EQ_3798(...) \, -#define Z_IS_3799_EQ_3799(...) \, -#define Z_IS_3800_EQ_3800(...) \, -#define Z_IS_3801_EQ_3801(...) \, -#define Z_IS_3802_EQ_3802(...) \, -#define Z_IS_3803_EQ_3803(...) \, -#define Z_IS_3804_EQ_3804(...) \, -#define Z_IS_3805_EQ_3805(...) \, -#define Z_IS_3806_EQ_3806(...) \, -#define Z_IS_3807_EQ_3807(...) \, -#define Z_IS_3808_EQ_3808(...) \, -#define Z_IS_3809_EQ_3809(...) \, -#define Z_IS_3810_EQ_3810(...) \, -#define Z_IS_3811_EQ_3811(...) \, -#define Z_IS_3812_EQ_3812(...) \, -#define Z_IS_3813_EQ_3813(...) \, -#define Z_IS_3814_EQ_3814(...) \, -#define Z_IS_3815_EQ_3815(...) \, -#define Z_IS_3816_EQ_3816(...) \, -#define Z_IS_3817_EQ_3817(...) \, -#define Z_IS_3818_EQ_3818(...) \, -#define Z_IS_3819_EQ_3819(...) \, -#define Z_IS_3820_EQ_3820(...) \, -#define Z_IS_3821_EQ_3821(...) \, -#define Z_IS_3822_EQ_3822(...) \, -#define Z_IS_3823_EQ_3823(...) \, -#define Z_IS_3824_EQ_3824(...) \, -#define Z_IS_3825_EQ_3825(...) \, -#define Z_IS_3826_EQ_3826(...) \, -#define Z_IS_3827_EQ_3827(...) \, -#define Z_IS_3828_EQ_3828(...) \, -#define Z_IS_3829_EQ_3829(...) \, -#define Z_IS_3830_EQ_3830(...) \, -#define Z_IS_3831_EQ_3831(...) \, -#define Z_IS_3832_EQ_3832(...) \, -#define Z_IS_3833_EQ_3833(...) \, -#define Z_IS_3834_EQ_3834(...) \, -#define Z_IS_3835_EQ_3835(...) \, -#define Z_IS_3836_EQ_3836(...) \, -#define Z_IS_3837_EQ_3837(...) \, -#define Z_IS_3838_EQ_3838(...) \, -#define Z_IS_3839_EQ_3839(...) \, -#define Z_IS_3840_EQ_3840(...) \, -#define Z_IS_3841_EQ_3841(...) \, -#define Z_IS_3842_EQ_3842(...) \, -#define Z_IS_3843_EQ_3843(...) \, -#define Z_IS_3844_EQ_3844(...) \, -#define Z_IS_3845_EQ_3845(...) \, -#define Z_IS_3846_EQ_3846(...) \, -#define Z_IS_3847_EQ_3847(...) \, -#define Z_IS_3848_EQ_3848(...) \, -#define Z_IS_3849_EQ_3849(...) \, -#define Z_IS_3850_EQ_3850(...) \, -#define Z_IS_3851_EQ_3851(...) \, -#define Z_IS_3852_EQ_3852(...) \, -#define Z_IS_3853_EQ_3853(...) \, -#define Z_IS_3854_EQ_3854(...) \, -#define Z_IS_3855_EQ_3855(...) \, -#define Z_IS_3856_EQ_3856(...) \, -#define Z_IS_3857_EQ_3857(...) \, -#define Z_IS_3858_EQ_3858(...) \, -#define Z_IS_3859_EQ_3859(...) \, -#define Z_IS_3860_EQ_3860(...) \, -#define Z_IS_3861_EQ_3861(...) \, -#define Z_IS_3862_EQ_3862(...) \, -#define Z_IS_3863_EQ_3863(...) \, -#define Z_IS_3864_EQ_3864(...) \, -#define Z_IS_3865_EQ_3865(...) \, -#define Z_IS_3866_EQ_3866(...) \, -#define Z_IS_3867_EQ_3867(...) \, -#define Z_IS_3868_EQ_3868(...) \, -#define Z_IS_3869_EQ_3869(...) \, -#define Z_IS_3870_EQ_3870(...) \, -#define Z_IS_3871_EQ_3871(...) \, -#define Z_IS_3872_EQ_3872(...) \, -#define Z_IS_3873_EQ_3873(...) \, -#define Z_IS_3874_EQ_3874(...) \, -#define Z_IS_3875_EQ_3875(...) \, -#define Z_IS_3876_EQ_3876(...) \, -#define Z_IS_3877_EQ_3877(...) \, -#define Z_IS_3878_EQ_3878(...) \, -#define Z_IS_3879_EQ_3879(...) \, -#define Z_IS_3880_EQ_3880(...) \, -#define Z_IS_3881_EQ_3881(...) \, -#define Z_IS_3882_EQ_3882(...) \, -#define Z_IS_3883_EQ_3883(...) \, -#define Z_IS_3884_EQ_3884(...) \, -#define Z_IS_3885_EQ_3885(...) \, -#define Z_IS_3886_EQ_3886(...) \, -#define Z_IS_3887_EQ_3887(...) \, -#define Z_IS_3888_EQ_3888(...) \, -#define Z_IS_3889_EQ_3889(...) \, -#define Z_IS_3890_EQ_3890(...) \, -#define Z_IS_3891_EQ_3891(...) \, -#define Z_IS_3892_EQ_3892(...) \, -#define Z_IS_3893_EQ_3893(...) \, -#define Z_IS_3894_EQ_3894(...) \, -#define Z_IS_3895_EQ_3895(...) \, -#define Z_IS_3896_EQ_3896(...) \, -#define Z_IS_3897_EQ_3897(...) \, -#define Z_IS_3898_EQ_3898(...) \, -#define Z_IS_3899_EQ_3899(...) \, -#define Z_IS_3900_EQ_3900(...) \, -#define Z_IS_3901_EQ_3901(...) \, -#define Z_IS_3902_EQ_3902(...) \, -#define Z_IS_3903_EQ_3903(...) \, -#define Z_IS_3904_EQ_3904(...) \, -#define Z_IS_3905_EQ_3905(...) \, -#define Z_IS_3906_EQ_3906(...) \, -#define Z_IS_3907_EQ_3907(...) \, -#define Z_IS_3908_EQ_3908(...) \, -#define Z_IS_3909_EQ_3909(...) \, -#define Z_IS_3910_EQ_3910(...) \, -#define Z_IS_3911_EQ_3911(...) \, -#define Z_IS_3912_EQ_3912(...) \, -#define Z_IS_3913_EQ_3913(...) \, -#define Z_IS_3914_EQ_3914(...) \, -#define Z_IS_3915_EQ_3915(...) \, -#define Z_IS_3916_EQ_3916(...) \, -#define Z_IS_3917_EQ_3917(...) \, -#define Z_IS_3918_EQ_3918(...) \, -#define Z_IS_3919_EQ_3919(...) \, -#define Z_IS_3920_EQ_3920(...) \, -#define Z_IS_3921_EQ_3921(...) \, -#define Z_IS_3922_EQ_3922(...) \, -#define Z_IS_3923_EQ_3923(...) \, -#define Z_IS_3924_EQ_3924(...) \, -#define Z_IS_3925_EQ_3925(...) \, -#define Z_IS_3926_EQ_3926(...) \, -#define Z_IS_3927_EQ_3927(...) \, -#define Z_IS_3928_EQ_3928(...) \, -#define Z_IS_3929_EQ_3929(...) \, -#define Z_IS_3930_EQ_3930(...) \, -#define Z_IS_3931_EQ_3931(...) \, -#define Z_IS_3932_EQ_3932(...) \, -#define Z_IS_3933_EQ_3933(...) \, -#define Z_IS_3934_EQ_3934(...) \, -#define Z_IS_3935_EQ_3935(...) \, -#define Z_IS_3936_EQ_3936(...) \, -#define Z_IS_3937_EQ_3937(...) \, -#define Z_IS_3938_EQ_3938(...) \, -#define Z_IS_3939_EQ_3939(...) \, -#define Z_IS_3940_EQ_3940(...) \, -#define Z_IS_3941_EQ_3941(...) \, -#define Z_IS_3942_EQ_3942(...) \, -#define Z_IS_3943_EQ_3943(...) \, -#define Z_IS_3944_EQ_3944(...) \, -#define Z_IS_3945_EQ_3945(...) \, -#define Z_IS_3946_EQ_3946(...) \, -#define Z_IS_3947_EQ_3947(...) \, -#define Z_IS_3948_EQ_3948(...) \, -#define Z_IS_3949_EQ_3949(...) \, -#define Z_IS_3950_EQ_3950(...) \, -#define Z_IS_3951_EQ_3951(...) \, -#define Z_IS_3952_EQ_3952(...) \, -#define Z_IS_3953_EQ_3953(...) \, -#define Z_IS_3954_EQ_3954(...) \, -#define Z_IS_3955_EQ_3955(...) \, -#define Z_IS_3956_EQ_3956(...) \, -#define Z_IS_3957_EQ_3957(...) \, -#define Z_IS_3958_EQ_3958(...) \, -#define Z_IS_3959_EQ_3959(...) \, -#define Z_IS_3960_EQ_3960(...) \, -#define Z_IS_3961_EQ_3961(...) \, -#define Z_IS_3962_EQ_3962(...) \, -#define Z_IS_3963_EQ_3963(...) \, -#define Z_IS_3964_EQ_3964(...) \, -#define Z_IS_3965_EQ_3965(...) \, -#define Z_IS_3966_EQ_3966(...) \, -#define Z_IS_3967_EQ_3967(...) \, -#define Z_IS_3968_EQ_3968(...) \, -#define Z_IS_3969_EQ_3969(...) \, -#define Z_IS_3970_EQ_3970(...) \, -#define Z_IS_3971_EQ_3971(...) \, -#define Z_IS_3972_EQ_3972(...) \, -#define Z_IS_3973_EQ_3973(...) \, -#define Z_IS_3974_EQ_3974(...) \, -#define Z_IS_3975_EQ_3975(...) \, -#define Z_IS_3976_EQ_3976(...) \, -#define Z_IS_3977_EQ_3977(...) \, -#define Z_IS_3978_EQ_3978(...) \, -#define Z_IS_3979_EQ_3979(...) \, -#define Z_IS_3980_EQ_3980(...) \, -#define Z_IS_3981_EQ_3981(...) \, -#define Z_IS_3982_EQ_3982(...) \, -#define Z_IS_3983_EQ_3983(...) \, -#define Z_IS_3984_EQ_3984(...) \, -#define Z_IS_3985_EQ_3985(...) \, -#define Z_IS_3986_EQ_3986(...) \, -#define Z_IS_3987_EQ_3987(...) \, -#define Z_IS_3988_EQ_3988(...) \, -#define Z_IS_3989_EQ_3989(...) \, -#define Z_IS_3990_EQ_3990(...) \, -#define Z_IS_3991_EQ_3991(...) \, -#define Z_IS_3992_EQ_3992(...) \, -#define Z_IS_3993_EQ_3993(...) \, -#define Z_IS_3994_EQ_3994(...) \, -#define Z_IS_3995_EQ_3995(...) \, -#define Z_IS_3996_EQ_3996(...) \, -#define Z_IS_3997_EQ_3997(...) \, -#define Z_IS_3998_EQ_3998(...) \, -#define Z_IS_3999_EQ_3999(...) \, -#define Z_IS_4000_EQ_4000(...) \, -#define Z_IS_4001_EQ_4001(...) \, -#define Z_IS_4002_EQ_4002(...) \, -#define Z_IS_4003_EQ_4003(...) \, -#define Z_IS_4004_EQ_4004(...) \, -#define Z_IS_4005_EQ_4005(...) \, -#define Z_IS_4006_EQ_4006(...) \, -#define Z_IS_4007_EQ_4007(...) \, -#define Z_IS_4008_EQ_4008(...) \, -#define Z_IS_4009_EQ_4009(...) \, -#define Z_IS_4010_EQ_4010(...) \, -#define Z_IS_4011_EQ_4011(...) \, -#define Z_IS_4012_EQ_4012(...) \, -#define Z_IS_4013_EQ_4013(...) \, -#define Z_IS_4014_EQ_4014(...) \, -#define Z_IS_4015_EQ_4015(...) \, -#define Z_IS_4016_EQ_4016(...) \, -#define Z_IS_4017_EQ_4017(...) \, -#define Z_IS_4018_EQ_4018(...) \, -#define Z_IS_4019_EQ_4019(...) \, -#define Z_IS_4020_EQ_4020(...) \, -#define Z_IS_4021_EQ_4021(...) \, -#define Z_IS_4022_EQ_4022(...) \, -#define Z_IS_4023_EQ_4023(...) \, -#define Z_IS_4024_EQ_4024(...) \, -#define Z_IS_4025_EQ_4025(...) \, -#define Z_IS_4026_EQ_4026(...) \, -#define Z_IS_4027_EQ_4027(...) \, -#define Z_IS_4028_EQ_4028(...) \, -#define Z_IS_4029_EQ_4029(...) \, -#define Z_IS_4030_EQ_4030(...) \, -#define Z_IS_4031_EQ_4031(...) \, -#define Z_IS_4032_EQ_4032(...) \, -#define Z_IS_4033_EQ_4033(...) \, -#define Z_IS_4034_EQ_4034(...) \, -#define Z_IS_4035_EQ_4035(...) \, -#define Z_IS_4036_EQ_4036(...) \, -#define Z_IS_4037_EQ_4037(...) \, -#define Z_IS_4038_EQ_4038(...) \, -#define Z_IS_4039_EQ_4039(...) \, -#define Z_IS_4040_EQ_4040(...) \, -#define Z_IS_4041_EQ_4041(...) \, -#define Z_IS_4042_EQ_4042(...) \, -#define Z_IS_4043_EQ_4043(...) \, -#define Z_IS_4044_EQ_4044(...) \, -#define Z_IS_4045_EQ_4045(...) \, -#define Z_IS_4046_EQ_4046(...) \, -#define Z_IS_4047_EQ_4047(...) \, -#define Z_IS_4048_EQ_4048(...) \, -#define Z_IS_4049_EQ_4049(...) \, -#define Z_IS_4050_EQ_4050(...) \, -#define Z_IS_4051_EQ_4051(...) \, -#define Z_IS_4052_EQ_4052(...) \, -#define Z_IS_4053_EQ_4053(...) \, -#define Z_IS_4054_EQ_4054(...) \, -#define Z_IS_4055_EQ_4055(...) \, -#define Z_IS_4056_EQ_4056(...) \, -#define Z_IS_4057_EQ_4057(...) \, -#define Z_IS_4058_EQ_4058(...) \, -#define Z_IS_4059_EQ_4059(...) \, -#define Z_IS_4060_EQ_4060(...) \, -#define Z_IS_4061_EQ_4061(...) \, -#define Z_IS_4062_EQ_4062(...) \, -#define Z_IS_4063_EQ_4063(...) \, -#define Z_IS_4064_EQ_4064(...) \, -#define Z_IS_4065_EQ_4065(...) \, -#define Z_IS_4066_EQ_4066(...) \, -#define Z_IS_4067_EQ_4067(...) \, -#define Z_IS_4068_EQ_4068(...) \, -#define Z_IS_4069_EQ_4069(...) \, -#define Z_IS_4070_EQ_4070(...) \, -#define Z_IS_4071_EQ_4071(...) \, -#define Z_IS_4072_EQ_4072(...) \, -#define Z_IS_4073_EQ_4073(...) \, -#define Z_IS_4074_EQ_4074(...) \, -#define Z_IS_4075_EQ_4075(...) \, -#define Z_IS_4076_EQ_4076(...) \, -#define Z_IS_4077_EQ_4077(...) \, -#define Z_IS_4078_EQ_4078(...) \, -#define Z_IS_4079_EQ_4079(...) \, -#define Z_IS_4080_EQ_4080(...) \, -#define Z_IS_4081_EQ_4081(...) \, -#define Z_IS_4082_EQ_4082(...) \, -#define Z_IS_4083_EQ_4083(...) \, -#define Z_IS_4084_EQ_4084(...) \, -#define Z_IS_4085_EQ_4085(...) \, -#define Z_IS_4086_EQ_4086(...) \, -#define Z_IS_4087_EQ_4087(...) \, -#define Z_IS_4088_EQ_4088(...) \, -#define Z_IS_4089_EQ_4089(...) \, -#define Z_IS_4090_EQ_4090(...) \, -#define Z_IS_4091_EQ_4091(...) \, -#define Z_IS_4092_EQ_4092(...) \, -#define Z_IS_4093_EQ_4093(...) \, -#define Z_IS_4094_EQ_4094(...) \, -#define Z_IS_4095_EQ_4095(...) \, -#define Z_IS_4096_EQ_4096(...) \, +#define Z_IS_0_EQ_0(...) \, +#define Z_IS_0U_EQ_0(...) \, +#define Z_IS_0_EQ_0U(...) \, +#define Z_IS_0U_EQ_0U(...) \, +#define Z_IS_1_EQ_1(...) \, +#define Z_IS_1U_EQ_1(...) \, +#define Z_IS_1_EQ_1U(...) \, +#define Z_IS_1U_EQ_1U(...) \, +#define Z_IS_2_EQ_2(...) \, +#define Z_IS_2U_EQ_2(...) \, +#define Z_IS_2_EQ_2U(...) \, +#define Z_IS_2U_EQ_2U(...) \, +#define Z_IS_3_EQ_3(...) \, +#define Z_IS_3U_EQ_3(...) \, +#define Z_IS_3_EQ_3U(...) \, +#define Z_IS_3U_EQ_3U(...) \, +#define Z_IS_4_EQ_4(...) \, +#define Z_IS_4U_EQ_4(...) \, +#define Z_IS_4_EQ_4U(...) \, +#define Z_IS_4U_EQ_4U(...) \, +#define Z_IS_5_EQ_5(...) \, +#define Z_IS_5U_EQ_5(...) \, +#define Z_IS_5_EQ_5U(...) \, +#define Z_IS_5U_EQ_5U(...) \, +#define Z_IS_6_EQ_6(...) \, +#define Z_IS_6U_EQ_6(...) \, +#define Z_IS_6_EQ_6U(...) \, +#define Z_IS_6U_EQ_6U(...) \, +#define Z_IS_7_EQ_7(...) \, +#define Z_IS_7U_EQ_7(...) \, +#define Z_IS_7_EQ_7U(...) \, +#define Z_IS_7U_EQ_7U(...) \, +#define Z_IS_8_EQ_8(...) \, +#define Z_IS_8U_EQ_8(...) \, +#define Z_IS_8_EQ_8U(...) \, +#define Z_IS_8U_EQ_8U(...) \, +#define Z_IS_9_EQ_9(...) \, +#define Z_IS_9U_EQ_9(...) \, +#define Z_IS_9_EQ_9U(...) \, +#define Z_IS_9U_EQ_9U(...) \, +#define Z_IS_10_EQ_10(...) \, +#define Z_IS_10U_EQ_10(...) \, +#define Z_IS_10_EQ_10U(...) \, +#define Z_IS_10U_EQ_10U(...) \, +#define Z_IS_11_EQ_11(...) \, +#define Z_IS_11U_EQ_11(...) \, +#define Z_IS_11_EQ_11U(...) \, +#define Z_IS_11U_EQ_11U(...) \, +#define Z_IS_12_EQ_12(...) \, +#define Z_IS_12U_EQ_12(...) \, +#define Z_IS_12_EQ_12U(...) \, +#define Z_IS_12U_EQ_12U(...) \, +#define Z_IS_13_EQ_13(...) \, +#define Z_IS_13U_EQ_13(...) \, +#define Z_IS_13_EQ_13U(...) \, +#define Z_IS_13U_EQ_13U(...) \, +#define Z_IS_14_EQ_14(...) \, +#define Z_IS_14U_EQ_14(...) \, +#define Z_IS_14_EQ_14U(...) \, +#define Z_IS_14U_EQ_14U(...) \, +#define Z_IS_15_EQ_15(...) \, +#define Z_IS_15U_EQ_15(...) \, +#define Z_IS_15_EQ_15U(...) \, +#define Z_IS_15U_EQ_15U(...) \, +#define Z_IS_16_EQ_16(...) \, +#define Z_IS_16U_EQ_16(...) \, +#define Z_IS_16_EQ_16U(...) \, +#define Z_IS_16U_EQ_16U(...) \, +#define Z_IS_17_EQ_17(...) \, +#define Z_IS_17U_EQ_17(...) \, +#define Z_IS_17_EQ_17U(...) \, +#define Z_IS_17U_EQ_17U(...) \, +#define Z_IS_18_EQ_18(...) \, +#define Z_IS_18U_EQ_18(...) \, +#define Z_IS_18_EQ_18U(...) \, +#define Z_IS_18U_EQ_18U(...) \, +#define Z_IS_19_EQ_19(...) \, +#define Z_IS_19U_EQ_19(...) \, +#define Z_IS_19_EQ_19U(...) \, +#define Z_IS_19U_EQ_19U(...) \, +#define Z_IS_20_EQ_20(...) \, +#define Z_IS_20U_EQ_20(...) \, +#define Z_IS_20_EQ_20U(...) \, +#define Z_IS_20U_EQ_20U(...) \, +#define Z_IS_21_EQ_21(...) \, +#define Z_IS_21U_EQ_21(...) \, +#define Z_IS_21_EQ_21U(...) \, +#define Z_IS_21U_EQ_21U(...) \, +#define Z_IS_22_EQ_22(...) \, +#define Z_IS_22U_EQ_22(...) \, +#define Z_IS_22_EQ_22U(...) \, +#define Z_IS_22U_EQ_22U(...) \, +#define Z_IS_23_EQ_23(...) \, +#define Z_IS_23U_EQ_23(...) \, +#define Z_IS_23_EQ_23U(...) \, +#define Z_IS_23U_EQ_23U(...) \, +#define Z_IS_24_EQ_24(...) \, +#define Z_IS_24U_EQ_24(...) \, +#define Z_IS_24_EQ_24U(...) \, +#define Z_IS_24U_EQ_24U(...) \, +#define Z_IS_25_EQ_25(...) \, +#define Z_IS_25U_EQ_25(...) \, +#define Z_IS_25_EQ_25U(...) \, +#define Z_IS_25U_EQ_25U(...) \, +#define Z_IS_26_EQ_26(...) \, +#define Z_IS_26U_EQ_26(...) \, +#define Z_IS_26_EQ_26U(...) \, +#define Z_IS_26U_EQ_26U(...) \, +#define Z_IS_27_EQ_27(...) \, +#define Z_IS_27U_EQ_27(...) \, +#define Z_IS_27_EQ_27U(...) \, +#define Z_IS_27U_EQ_27U(...) \, +#define Z_IS_28_EQ_28(...) \, +#define Z_IS_28U_EQ_28(...) \, +#define Z_IS_28_EQ_28U(...) \, +#define Z_IS_28U_EQ_28U(...) \, +#define Z_IS_29_EQ_29(...) \, +#define Z_IS_29U_EQ_29(...) \, +#define Z_IS_29_EQ_29U(...) \, +#define Z_IS_29U_EQ_29U(...) \, +#define Z_IS_30_EQ_30(...) \, +#define Z_IS_30U_EQ_30(...) \, +#define Z_IS_30_EQ_30U(...) \, +#define Z_IS_30U_EQ_30U(...) \, +#define Z_IS_31_EQ_31(...) \, +#define Z_IS_31U_EQ_31(...) \, +#define Z_IS_31_EQ_31U(...) \, +#define Z_IS_31U_EQ_31U(...) \, +#define Z_IS_32_EQ_32(...) \, +#define Z_IS_32U_EQ_32(...) \, +#define Z_IS_32_EQ_32U(...) \, +#define Z_IS_32U_EQ_32U(...) \, +#define Z_IS_33_EQ_33(...) \, +#define Z_IS_33U_EQ_33(...) \, +#define Z_IS_33_EQ_33U(...) \, +#define Z_IS_33U_EQ_33U(...) \, +#define Z_IS_34_EQ_34(...) \, +#define Z_IS_34U_EQ_34(...) \, +#define Z_IS_34_EQ_34U(...) \, +#define Z_IS_34U_EQ_34U(...) \, +#define Z_IS_35_EQ_35(...) \, +#define Z_IS_35U_EQ_35(...) \, +#define Z_IS_35_EQ_35U(...) \, +#define Z_IS_35U_EQ_35U(...) \, +#define Z_IS_36_EQ_36(...) \, +#define Z_IS_36U_EQ_36(...) \, +#define Z_IS_36_EQ_36U(...) \, +#define Z_IS_36U_EQ_36U(...) \, +#define Z_IS_37_EQ_37(...) \, +#define Z_IS_37U_EQ_37(...) \, +#define Z_IS_37_EQ_37U(...) \, +#define Z_IS_37U_EQ_37U(...) \, +#define Z_IS_38_EQ_38(...) \, +#define Z_IS_38U_EQ_38(...) \, +#define Z_IS_38_EQ_38U(...) \, +#define Z_IS_38U_EQ_38U(...) \, +#define Z_IS_39_EQ_39(...) \, +#define Z_IS_39U_EQ_39(...) \, +#define Z_IS_39_EQ_39U(...) \, +#define Z_IS_39U_EQ_39U(...) \, +#define Z_IS_40_EQ_40(...) \, +#define Z_IS_40U_EQ_40(...) \, +#define Z_IS_40_EQ_40U(...) \, +#define Z_IS_40U_EQ_40U(...) \, +#define Z_IS_41_EQ_41(...) \, +#define Z_IS_41U_EQ_41(...) \, +#define Z_IS_41_EQ_41U(...) \, +#define Z_IS_41U_EQ_41U(...) \, +#define Z_IS_42_EQ_42(...) \, +#define Z_IS_42U_EQ_42(...) \, +#define Z_IS_42_EQ_42U(...) \, +#define Z_IS_42U_EQ_42U(...) \, +#define Z_IS_43_EQ_43(...) \, +#define Z_IS_43U_EQ_43(...) \, +#define Z_IS_43_EQ_43U(...) \, +#define Z_IS_43U_EQ_43U(...) \, +#define Z_IS_44_EQ_44(...) \, +#define Z_IS_44U_EQ_44(...) \, +#define Z_IS_44_EQ_44U(...) \, +#define Z_IS_44U_EQ_44U(...) \, +#define Z_IS_45_EQ_45(...) \, +#define Z_IS_45U_EQ_45(...) \, +#define Z_IS_45_EQ_45U(...) \, +#define Z_IS_45U_EQ_45U(...) \, +#define Z_IS_46_EQ_46(...) \, +#define Z_IS_46U_EQ_46(...) \, +#define Z_IS_46_EQ_46U(...) \, +#define Z_IS_46U_EQ_46U(...) \, +#define Z_IS_47_EQ_47(...) \, +#define Z_IS_47U_EQ_47(...) \, +#define Z_IS_47_EQ_47U(...) \, +#define Z_IS_47U_EQ_47U(...) \, +#define Z_IS_48_EQ_48(...) \, +#define Z_IS_48U_EQ_48(...) \, +#define Z_IS_48_EQ_48U(...) \, +#define Z_IS_48U_EQ_48U(...) \, +#define Z_IS_49_EQ_49(...) \, +#define Z_IS_49U_EQ_49(...) \, +#define Z_IS_49_EQ_49U(...) \, +#define Z_IS_49U_EQ_49U(...) \, +#define Z_IS_50_EQ_50(...) \, +#define Z_IS_50U_EQ_50(...) \, +#define Z_IS_50_EQ_50U(...) \, +#define Z_IS_50U_EQ_50U(...) \, +#define Z_IS_51_EQ_51(...) \, +#define Z_IS_51U_EQ_51(...) \, +#define Z_IS_51_EQ_51U(...) \, +#define Z_IS_51U_EQ_51U(...) \, +#define Z_IS_52_EQ_52(...) \, +#define Z_IS_52U_EQ_52(...) \, +#define Z_IS_52_EQ_52U(...) \, +#define Z_IS_52U_EQ_52U(...) \, +#define Z_IS_53_EQ_53(...) \, +#define Z_IS_53U_EQ_53(...) \, +#define Z_IS_53_EQ_53U(...) \, +#define Z_IS_53U_EQ_53U(...) \, +#define Z_IS_54_EQ_54(...) \, +#define Z_IS_54U_EQ_54(...) \, +#define Z_IS_54_EQ_54U(...) \, +#define Z_IS_54U_EQ_54U(...) \, +#define Z_IS_55_EQ_55(...) \, +#define Z_IS_55U_EQ_55(...) \, +#define Z_IS_55_EQ_55U(...) \, +#define Z_IS_55U_EQ_55U(...) \, +#define Z_IS_56_EQ_56(...) \, +#define Z_IS_56U_EQ_56(...) \, +#define Z_IS_56_EQ_56U(...) \, +#define Z_IS_56U_EQ_56U(...) \, +#define Z_IS_57_EQ_57(...) \, +#define Z_IS_57U_EQ_57(...) \, +#define Z_IS_57_EQ_57U(...) \, +#define Z_IS_57U_EQ_57U(...) \, +#define Z_IS_58_EQ_58(...) \, +#define Z_IS_58U_EQ_58(...) \, +#define Z_IS_58_EQ_58U(...) \, +#define Z_IS_58U_EQ_58U(...) \, +#define Z_IS_59_EQ_59(...) \, +#define Z_IS_59U_EQ_59(...) \, +#define Z_IS_59_EQ_59U(...) \, +#define Z_IS_59U_EQ_59U(...) \, +#define Z_IS_60_EQ_60(...) \, +#define Z_IS_60U_EQ_60(...) \, +#define Z_IS_60_EQ_60U(...) \, +#define Z_IS_60U_EQ_60U(...) \, +#define Z_IS_61_EQ_61(...) \, +#define Z_IS_61U_EQ_61(...) \, +#define Z_IS_61_EQ_61U(...) \, +#define Z_IS_61U_EQ_61U(...) \, +#define Z_IS_62_EQ_62(...) \, +#define Z_IS_62U_EQ_62(...) \, +#define Z_IS_62_EQ_62U(...) \, +#define Z_IS_62U_EQ_62U(...) \, +#define Z_IS_63_EQ_63(...) \, +#define Z_IS_63U_EQ_63(...) \, +#define Z_IS_63_EQ_63U(...) \, +#define Z_IS_63U_EQ_63U(...) \, +#define Z_IS_64_EQ_64(...) \, +#define Z_IS_64U_EQ_64(...) \, +#define Z_IS_64_EQ_64U(...) \, +#define Z_IS_64U_EQ_64U(...) \, +#define Z_IS_65_EQ_65(...) \, +#define Z_IS_65U_EQ_65(...) \, +#define Z_IS_65_EQ_65U(...) \, +#define Z_IS_65U_EQ_65U(...) \, +#define Z_IS_66_EQ_66(...) \, +#define Z_IS_66U_EQ_66(...) \, +#define Z_IS_66_EQ_66U(...) \, +#define Z_IS_66U_EQ_66U(...) \, +#define Z_IS_67_EQ_67(...) \, +#define Z_IS_67U_EQ_67(...) \, +#define Z_IS_67_EQ_67U(...) \, +#define Z_IS_67U_EQ_67U(...) \, +#define Z_IS_68_EQ_68(...) \, +#define Z_IS_68U_EQ_68(...) \, +#define Z_IS_68_EQ_68U(...) \, +#define Z_IS_68U_EQ_68U(...) \, +#define Z_IS_69_EQ_69(...) \, +#define Z_IS_69U_EQ_69(...) \, +#define Z_IS_69_EQ_69U(...) \, +#define Z_IS_69U_EQ_69U(...) \, +#define Z_IS_70_EQ_70(...) \, +#define Z_IS_70U_EQ_70(...) \, +#define Z_IS_70_EQ_70U(...) \, +#define Z_IS_70U_EQ_70U(...) \, +#define Z_IS_71_EQ_71(...) \, +#define Z_IS_71U_EQ_71(...) \, +#define Z_IS_71_EQ_71U(...) \, +#define Z_IS_71U_EQ_71U(...) \, +#define Z_IS_72_EQ_72(...) \, +#define Z_IS_72U_EQ_72(...) \, +#define Z_IS_72_EQ_72U(...) \, +#define Z_IS_72U_EQ_72U(...) \, +#define Z_IS_73_EQ_73(...) \, +#define Z_IS_73U_EQ_73(...) \, +#define Z_IS_73_EQ_73U(...) \, +#define Z_IS_73U_EQ_73U(...) \, +#define Z_IS_74_EQ_74(...) \, +#define Z_IS_74U_EQ_74(...) \, +#define Z_IS_74_EQ_74U(...) \, +#define Z_IS_74U_EQ_74U(...) \, +#define Z_IS_75_EQ_75(...) \, +#define Z_IS_75U_EQ_75(...) \, +#define Z_IS_75_EQ_75U(...) \, +#define Z_IS_75U_EQ_75U(...) \, +#define Z_IS_76_EQ_76(...) \, +#define Z_IS_76U_EQ_76(...) \, +#define Z_IS_76_EQ_76U(...) \, +#define Z_IS_76U_EQ_76U(...) \, +#define Z_IS_77_EQ_77(...) \, +#define Z_IS_77U_EQ_77(...) \, +#define Z_IS_77_EQ_77U(...) \, +#define Z_IS_77U_EQ_77U(...) \, +#define Z_IS_78_EQ_78(...) \, +#define Z_IS_78U_EQ_78(...) \, +#define Z_IS_78_EQ_78U(...) \, +#define Z_IS_78U_EQ_78U(...) \, +#define Z_IS_79_EQ_79(...) \, +#define Z_IS_79U_EQ_79(...) \, +#define Z_IS_79_EQ_79U(...) \, +#define Z_IS_79U_EQ_79U(...) \, +#define Z_IS_80_EQ_80(...) \, +#define Z_IS_80U_EQ_80(...) \, +#define Z_IS_80_EQ_80U(...) \, +#define Z_IS_80U_EQ_80U(...) \, +#define Z_IS_81_EQ_81(...) \, +#define Z_IS_81U_EQ_81(...) \, +#define Z_IS_81_EQ_81U(...) \, +#define Z_IS_81U_EQ_81U(...) \, +#define Z_IS_82_EQ_82(...) \, +#define Z_IS_82U_EQ_82(...) \, +#define Z_IS_82_EQ_82U(...) \, +#define Z_IS_82U_EQ_82U(...) \, +#define Z_IS_83_EQ_83(...) \, +#define Z_IS_83U_EQ_83(...) \, +#define Z_IS_83_EQ_83U(...) \, +#define Z_IS_83U_EQ_83U(...) \, +#define Z_IS_84_EQ_84(...) \, +#define Z_IS_84U_EQ_84(...) \, +#define Z_IS_84_EQ_84U(...) \, +#define Z_IS_84U_EQ_84U(...) \, +#define Z_IS_85_EQ_85(...) \, +#define Z_IS_85U_EQ_85(...) \, +#define Z_IS_85_EQ_85U(...) \, +#define Z_IS_85U_EQ_85U(...) \, +#define Z_IS_86_EQ_86(...) \, +#define Z_IS_86U_EQ_86(...) \, +#define Z_IS_86_EQ_86U(...) \, +#define Z_IS_86U_EQ_86U(...) \, +#define Z_IS_87_EQ_87(...) \, +#define Z_IS_87U_EQ_87(...) \, +#define Z_IS_87_EQ_87U(...) \, +#define Z_IS_87U_EQ_87U(...) \, +#define Z_IS_88_EQ_88(...) \, +#define Z_IS_88U_EQ_88(...) \, +#define Z_IS_88_EQ_88U(...) \, +#define Z_IS_88U_EQ_88U(...) \, +#define Z_IS_89_EQ_89(...) \, +#define Z_IS_89U_EQ_89(...) \, +#define Z_IS_89_EQ_89U(...) \, +#define Z_IS_89U_EQ_89U(...) \, +#define Z_IS_90_EQ_90(...) \, +#define Z_IS_90U_EQ_90(...) \, +#define Z_IS_90_EQ_90U(...) \, +#define Z_IS_90U_EQ_90U(...) \, +#define Z_IS_91_EQ_91(...) \, +#define Z_IS_91U_EQ_91(...) \, +#define Z_IS_91_EQ_91U(...) \, +#define Z_IS_91U_EQ_91U(...) \, +#define Z_IS_92_EQ_92(...) \, +#define Z_IS_92U_EQ_92(...) \, +#define Z_IS_92_EQ_92U(...) \, +#define Z_IS_92U_EQ_92U(...) \, +#define Z_IS_93_EQ_93(...) \, +#define Z_IS_93U_EQ_93(...) \, +#define Z_IS_93_EQ_93U(...) \, +#define Z_IS_93U_EQ_93U(...) \, +#define Z_IS_94_EQ_94(...) \, +#define Z_IS_94U_EQ_94(...) \, +#define Z_IS_94_EQ_94U(...) \, +#define Z_IS_94U_EQ_94U(...) \, +#define Z_IS_95_EQ_95(...) \, +#define Z_IS_95U_EQ_95(...) \, +#define Z_IS_95_EQ_95U(...) \, +#define Z_IS_95U_EQ_95U(...) \, +#define Z_IS_96_EQ_96(...) \, +#define Z_IS_96U_EQ_96(...) \, +#define Z_IS_96_EQ_96U(...) \, +#define Z_IS_96U_EQ_96U(...) \, +#define Z_IS_97_EQ_97(...) \, +#define Z_IS_97U_EQ_97(...) \, +#define Z_IS_97_EQ_97U(...) \, +#define Z_IS_97U_EQ_97U(...) \, +#define Z_IS_98_EQ_98(...) \, +#define Z_IS_98U_EQ_98(...) \, +#define Z_IS_98_EQ_98U(...) \, +#define Z_IS_98U_EQ_98U(...) \, +#define Z_IS_99_EQ_99(...) \, +#define Z_IS_99U_EQ_99(...) \, +#define Z_IS_99_EQ_99U(...) \, +#define Z_IS_99U_EQ_99U(...) \, +#define Z_IS_100_EQ_100(...) \, +#define Z_IS_100U_EQ_100(...) \, +#define Z_IS_100_EQ_100U(...) \, +#define Z_IS_100U_EQ_100U(...) \, +#define Z_IS_101_EQ_101(...) \, +#define Z_IS_101U_EQ_101(...) \, +#define Z_IS_101_EQ_101U(...) \, +#define Z_IS_101U_EQ_101U(...) \, +#define Z_IS_102_EQ_102(...) \, +#define Z_IS_102U_EQ_102(...) \, +#define Z_IS_102_EQ_102U(...) \, +#define Z_IS_102U_EQ_102U(...) \, +#define Z_IS_103_EQ_103(...) \, +#define Z_IS_103U_EQ_103(...) \, +#define Z_IS_103_EQ_103U(...) \, +#define Z_IS_103U_EQ_103U(...) \, +#define Z_IS_104_EQ_104(...) \, +#define Z_IS_104U_EQ_104(...) \, +#define Z_IS_104_EQ_104U(...) \, +#define Z_IS_104U_EQ_104U(...) \, +#define Z_IS_105_EQ_105(...) \, +#define Z_IS_105U_EQ_105(...) \, +#define Z_IS_105_EQ_105U(...) \, +#define Z_IS_105U_EQ_105U(...) \, +#define Z_IS_106_EQ_106(...) \, +#define Z_IS_106U_EQ_106(...) \, +#define Z_IS_106_EQ_106U(...) \, +#define Z_IS_106U_EQ_106U(...) \, +#define Z_IS_107_EQ_107(...) \, +#define Z_IS_107U_EQ_107(...) \, +#define Z_IS_107_EQ_107U(...) \, +#define Z_IS_107U_EQ_107U(...) \, +#define Z_IS_108_EQ_108(...) \, +#define Z_IS_108U_EQ_108(...) \, +#define Z_IS_108_EQ_108U(...) \, +#define Z_IS_108U_EQ_108U(...) \, +#define Z_IS_109_EQ_109(...) \, +#define Z_IS_109U_EQ_109(...) \, +#define Z_IS_109_EQ_109U(...) \, +#define Z_IS_109U_EQ_109U(...) \, +#define Z_IS_110_EQ_110(...) \, +#define Z_IS_110U_EQ_110(...) \, +#define Z_IS_110_EQ_110U(...) \, +#define Z_IS_110U_EQ_110U(...) \, +#define Z_IS_111_EQ_111(...) \, +#define Z_IS_111U_EQ_111(...) \, +#define Z_IS_111_EQ_111U(...) \, +#define Z_IS_111U_EQ_111U(...) \, +#define Z_IS_112_EQ_112(...) \, +#define Z_IS_112U_EQ_112(...) \, +#define Z_IS_112_EQ_112U(...) \, +#define Z_IS_112U_EQ_112U(...) \, +#define Z_IS_113_EQ_113(...) \, +#define Z_IS_113U_EQ_113(...) \, +#define Z_IS_113_EQ_113U(...) \, +#define Z_IS_113U_EQ_113U(...) \, +#define Z_IS_114_EQ_114(...) \, +#define Z_IS_114U_EQ_114(...) \, +#define Z_IS_114_EQ_114U(...) \, +#define Z_IS_114U_EQ_114U(...) \, +#define Z_IS_115_EQ_115(...) \, +#define Z_IS_115U_EQ_115(...) \, +#define Z_IS_115_EQ_115U(...) \, +#define Z_IS_115U_EQ_115U(...) \, +#define Z_IS_116_EQ_116(...) \, +#define Z_IS_116U_EQ_116(...) \, +#define Z_IS_116_EQ_116U(...) \, +#define Z_IS_116U_EQ_116U(...) \, +#define Z_IS_117_EQ_117(...) \, +#define Z_IS_117U_EQ_117(...) \, +#define Z_IS_117_EQ_117U(...) \, +#define Z_IS_117U_EQ_117U(...) \, +#define Z_IS_118_EQ_118(...) \, +#define Z_IS_118U_EQ_118(...) \, +#define Z_IS_118_EQ_118U(...) \, +#define Z_IS_118U_EQ_118U(...) \, +#define Z_IS_119_EQ_119(...) \, +#define Z_IS_119U_EQ_119(...) \, +#define Z_IS_119_EQ_119U(...) \, +#define Z_IS_119U_EQ_119U(...) \, +#define Z_IS_120_EQ_120(...) \, +#define Z_IS_120U_EQ_120(...) \, +#define Z_IS_120_EQ_120U(...) \, +#define Z_IS_120U_EQ_120U(...) \, +#define Z_IS_121_EQ_121(...) \, +#define Z_IS_121U_EQ_121(...) \, +#define Z_IS_121_EQ_121U(...) \, +#define Z_IS_121U_EQ_121U(...) \, +#define Z_IS_122_EQ_122(...) \, +#define Z_IS_122U_EQ_122(...) \, +#define Z_IS_122_EQ_122U(...) \, +#define Z_IS_122U_EQ_122U(...) \, +#define Z_IS_123_EQ_123(...) \, +#define Z_IS_123U_EQ_123(...) \, +#define Z_IS_123_EQ_123U(...) \, +#define Z_IS_123U_EQ_123U(...) \, +#define Z_IS_124_EQ_124(...) \, +#define Z_IS_124U_EQ_124(...) \, +#define Z_IS_124_EQ_124U(...) \, +#define Z_IS_124U_EQ_124U(...) \, +#define Z_IS_125_EQ_125(...) \, +#define Z_IS_125U_EQ_125(...) \, +#define Z_IS_125_EQ_125U(...) \, +#define Z_IS_125U_EQ_125U(...) \, +#define Z_IS_126_EQ_126(...) \, +#define Z_IS_126U_EQ_126(...) \, +#define Z_IS_126_EQ_126U(...) \, +#define Z_IS_126U_EQ_126U(...) \, +#define Z_IS_127_EQ_127(...) \, +#define Z_IS_127U_EQ_127(...) \, +#define Z_IS_127_EQ_127U(...) \, +#define Z_IS_127U_EQ_127U(...) \, +#define Z_IS_128_EQ_128(...) \, +#define Z_IS_128U_EQ_128(...) \, +#define Z_IS_128_EQ_128U(...) \, +#define Z_IS_128U_EQ_128U(...) \, +#define Z_IS_129_EQ_129(...) \, +#define Z_IS_129U_EQ_129(...) \, +#define Z_IS_129_EQ_129U(...) \, +#define Z_IS_129U_EQ_129U(...) \, +#define Z_IS_130_EQ_130(...) \, +#define Z_IS_130U_EQ_130(...) \, +#define Z_IS_130_EQ_130U(...) \, +#define Z_IS_130U_EQ_130U(...) \, +#define Z_IS_131_EQ_131(...) \, +#define Z_IS_131U_EQ_131(...) \, +#define Z_IS_131_EQ_131U(...) \, +#define Z_IS_131U_EQ_131U(...) \, +#define Z_IS_132_EQ_132(...) \, +#define Z_IS_132U_EQ_132(...) \, +#define Z_IS_132_EQ_132U(...) \, +#define Z_IS_132U_EQ_132U(...) \, +#define Z_IS_133_EQ_133(...) \, +#define Z_IS_133U_EQ_133(...) \, +#define Z_IS_133_EQ_133U(...) \, +#define Z_IS_133U_EQ_133U(...) \, +#define Z_IS_134_EQ_134(...) \, +#define Z_IS_134U_EQ_134(...) \, +#define Z_IS_134_EQ_134U(...) \, +#define Z_IS_134U_EQ_134U(...) \, +#define Z_IS_135_EQ_135(...) \, +#define Z_IS_135U_EQ_135(...) \, +#define Z_IS_135_EQ_135U(...) \, +#define Z_IS_135U_EQ_135U(...) \, +#define Z_IS_136_EQ_136(...) \, +#define Z_IS_136U_EQ_136(...) \, +#define Z_IS_136_EQ_136U(...) \, +#define Z_IS_136U_EQ_136U(...) \, +#define Z_IS_137_EQ_137(...) \, +#define Z_IS_137U_EQ_137(...) \, +#define Z_IS_137_EQ_137U(...) \, +#define Z_IS_137U_EQ_137U(...) \, +#define Z_IS_138_EQ_138(...) \, +#define Z_IS_138U_EQ_138(...) \, +#define Z_IS_138_EQ_138U(...) \, +#define Z_IS_138U_EQ_138U(...) \, +#define Z_IS_139_EQ_139(...) \, +#define Z_IS_139U_EQ_139(...) \, +#define Z_IS_139_EQ_139U(...) \, +#define Z_IS_139U_EQ_139U(...) \, +#define Z_IS_140_EQ_140(...) \, +#define Z_IS_140U_EQ_140(...) \, +#define Z_IS_140_EQ_140U(...) \, +#define Z_IS_140U_EQ_140U(...) \, +#define Z_IS_141_EQ_141(...) \, +#define Z_IS_141U_EQ_141(...) \, +#define Z_IS_141_EQ_141U(...) \, +#define Z_IS_141U_EQ_141U(...) \, +#define Z_IS_142_EQ_142(...) \, +#define Z_IS_142U_EQ_142(...) \, +#define Z_IS_142_EQ_142U(...) \, +#define Z_IS_142U_EQ_142U(...) \, +#define Z_IS_143_EQ_143(...) \, +#define Z_IS_143U_EQ_143(...) \, +#define Z_IS_143_EQ_143U(...) \, +#define Z_IS_143U_EQ_143U(...) \, +#define Z_IS_144_EQ_144(...) \, +#define Z_IS_144U_EQ_144(...) \, +#define Z_IS_144_EQ_144U(...) \, +#define Z_IS_144U_EQ_144U(...) \, +#define Z_IS_145_EQ_145(...) \, +#define Z_IS_145U_EQ_145(...) \, +#define Z_IS_145_EQ_145U(...) \, +#define Z_IS_145U_EQ_145U(...) \, +#define Z_IS_146_EQ_146(...) \, +#define Z_IS_146U_EQ_146(...) \, +#define Z_IS_146_EQ_146U(...) \, +#define Z_IS_146U_EQ_146U(...) \, +#define Z_IS_147_EQ_147(...) \, +#define Z_IS_147U_EQ_147(...) \, +#define Z_IS_147_EQ_147U(...) \, +#define Z_IS_147U_EQ_147U(...) \, +#define Z_IS_148_EQ_148(...) \, +#define Z_IS_148U_EQ_148(...) \, +#define Z_IS_148_EQ_148U(...) \, +#define Z_IS_148U_EQ_148U(...) \, +#define Z_IS_149_EQ_149(...) \, +#define Z_IS_149U_EQ_149(...) \, +#define Z_IS_149_EQ_149U(...) \, +#define Z_IS_149U_EQ_149U(...) \, +#define Z_IS_150_EQ_150(...) \, +#define Z_IS_150U_EQ_150(...) \, +#define Z_IS_150_EQ_150U(...) \, +#define Z_IS_150U_EQ_150U(...) \, +#define Z_IS_151_EQ_151(...) \, +#define Z_IS_151U_EQ_151(...) \, +#define Z_IS_151_EQ_151U(...) \, +#define Z_IS_151U_EQ_151U(...) \, +#define Z_IS_152_EQ_152(...) \, +#define Z_IS_152U_EQ_152(...) \, +#define Z_IS_152_EQ_152U(...) \, +#define Z_IS_152U_EQ_152U(...) \, +#define Z_IS_153_EQ_153(...) \, +#define Z_IS_153U_EQ_153(...) \, +#define Z_IS_153_EQ_153U(...) \, +#define Z_IS_153U_EQ_153U(...) \, +#define Z_IS_154_EQ_154(...) \, +#define Z_IS_154U_EQ_154(...) \, +#define Z_IS_154_EQ_154U(...) \, +#define Z_IS_154U_EQ_154U(...) \, +#define Z_IS_155_EQ_155(...) \, +#define Z_IS_155U_EQ_155(...) \, +#define Z_IS_155_EQ_155U(...) \, +#define Z_IS_155U_EQ_155U(...) \, +#define Z_IS_156_EQ_156(...) \, +#define Z_IS_156U_EQ_156(...) \, +#define Z_IS_156_EQ_156U(...) \, +#define Z_IS_156U_EQ_156U(...) \, +#define Z_IS_157_EQ_157(...) \, +#define Z_IS_157U_EQ_157(...) \, +#define Z_IS_157_EQ_157U(...) \, +#define Z_IS_157U_EQ_157U(...) \, +#define Z_IS_158_EQ_158(...) \, +#define Z_IS_158U_EQ_158(...) \, +#define Z_IS_158_EQ_158U(...) \, +#define Z_IS_158U_EQ_158U(...) \, +#define Z_IS_159_EQ_159(...) \, +#define Z_IS_159U_EQ_159(...) \, +#define Z_IS_159_EQ_159U(...) \, +#define Z_IS_159U_EQ_159U(...) \, +#define Z_IS_160_EQ_160(...) \, +#define Z_IS_160U_EQ_160(...) \, +#define Z_IS_160_EQ_160U(...) \, +#define Z_IS_160U_EQ_160U(...) \, +#define Z_IS_161_EQ_161(...) \, +#define Z_IS_161U_EQ_161(...) \, +#define Z_IS_161_EQ_161U(...) \, +#define Z_IS_161U_EQ_161U(...) \, +#define Z_IS_162_EQ_162(...) \, +#define Z_IS_162U_EQ_162(...) \, +#define Z_IS_162_EQ_162U(...) \, +#define Z_IS_162U_EQ_162U(...) \, +#define Z_IS_163_EQ_163(...) \, +#define Z_IS_163U_EQ_163(...) \, +#define Z_IS_163_EQ_163U(...) \, +#define Z_IS_163U_EQ_163U(...) \, +#define Z_IS_164_EQ_164(...) \, +#define Z_IS_164U_EQ_164(...) \, +#define Z_IS_164_EQ_164U(...) \, +#define Z_IS_164U_EQ_164U(...) \, +#define Z_IS_165_EQ_165(...) \, +#define Z_IS_165U_EQ_165(...) \, +#define Z_IS_165_EQ_165U(...) \, +#define Z_IS_165U_EQ_165U(...) \, +#define Z_IS_166_EQ_166(...) \, +#define Z_IS_166U_EQ_166(...) \, +#define Z_IS_166_EQ_166U(...) \, +#define Z_IS_166U_EQ_166U(...) \, +#define Z_IS_167_EQ_167(...) \, +#define Z_IS_167U_EQ_167(...) \, +#define Z_IS_167_EQ_167U(...) \, +#define Z_IS_167U_EQ_167U(...) \, +#define Z_IS_168_EQ_168(...) \, +#define Z_IS_168U_EQ_168(...) \, +#define Z_IS_168_EQ_168U(...) \, +#define Z_IS_168U_EQ_168U(...) \, +#define Z_IS_169_EQ_169(...) \, +#define Z_IS_169U_EQ_169(...) \, +#define Z_IS_169_EQ_169U(...) \, +#define Z_IS_169U_EQ_169U(...) \, +#define Z_IS_170_EQ_170(...) \, +#define Z_IS_170U_EQ_170(...) \, +#define Z_IS_170_EQ_170U(...) \, +#define Z_IS_170U_EQ_170U(...) \, +#define Z_IS_171_EQ_171(...) \, +#define Z_IS_171U_EQ_171(...) \, +#define Z_IS_171_EQ_171U(...) \, +#define Z_IS_171U_EQ_171U(...) \, +#define Z_IS_172_EQ_172(...) \, +#define Z_IS_172U_EQ_172(...) \, +#define Z_IS_172_EQ_172U(...) \, +#define Z_IS_172U_EQ_172U(...) \, +#define Z_IS_173_EQ_173(...) \, +#define Z_IS_173U_EQ_173(...) \, +#define Z_IS_173_EQ_173U(...) \, +#define Z_IS_173U_EQ_173U(...) \, +#define Z_IS_174_EQ_174(...) \, +#define Z_IS_174U_EQ_174(...) \, +#define Z_IS_174_EQ_174U(...) \, +#define Z_IS_174U_EQ_174U(...) \, +#define Z_IS_175_EQ_175(...) \, +#define Z_IS_175U_EQ_175(...) \, +#define Z_IS_175_EQ_175U(...) \, +#define Z_IS_175U_EQ_175U(...) \, +#define Z_IS_176_EQ_176(...) \, +#define Z_IS_176U_EQ_176(...) \, +#define Z_IS_176_EQ_176U(...) \, +#define Z_IS_176U_EQ_176U(...) \, +#define Z_IS_177_EQ_177(...) \, +#define Z_IS_177U_EQ_177(...) \, +#define Z_IS_177_EQ_177U(...) \, +#define Z_IS_177U_EQ_177U(...) \, +#define Z_IS_178_EQ_178(...) \, +#define Z_IS_178U_EQ_178(...) \, +#define Z_IS_178_EQ_178U(...) \, +#define Z_IS_178U_EQ_178U(...) \, +#define Z_IS_179_EQ_179(...) \, +#define Z_IS_179U_EQ_179(...) \, +#define Z_IS_179_EQ_179U(...) \, +#define Z_IS_179U_EQ_179U(...) \, +#define Z_IS_180_EQ_180(...) \, +#define Z_IS_180U_EQ_180(...) \, +#define Z_IS_180_EQ_180U(...) \, +#define Z_IS_180U_EQ_180U(...) \, +#define Z_IS_181_EQ_181(...) \, +#define Z_IS_181U_EQ_181(...) \, +#define Z_IS_181_EQ_181U(...) \, +#define Z_IS_181U_EQ_181U(...) \, +#define Z_IS_182_EQ_182(...) \, +#define Z_IS_182U_EQ_182(...) \, +#define Z_IS_182_EQ_182U(...) \, +#define Z_IS_182U_EQ_182U(...) \, +#define Z_IS_183_EQ_183(...) \, +#define Z_IS_183U_EQ_183(...) \, +#define Z_IS_183_EQ_183U(...) \, +#define Z_IS_183U_EQ_183U(...) \, +#define Z_IS_184_EQ_184(...) \, +#define Z_IS_184U_EQ_184(...) \, +#define Z_IS_184_EQ_184U(...) \, +#define Z_IS_184U_EQ_184U(...) \, +#define Z_IS_185_EQ_185(...) \, +#define Z_IS_185U_EQ_185(...) \, +#define Z_IS_185_EQ_185U(...) \, +#define Z_IS_185U_EQ_185U(...) \, +#define Z_IS_186_EQ_186(...) \, +#define Z_IS_186U_EQ_186(...) \, +#define Z_IS_186_EQ_186U(...) \, +#define Z_IS_186U_EQ_186U(...) \, +#define Z_IS_187_EQ_187(...) \, +#define Z_IS_187U_EQ_187(...) \, +#define Z_IS_187_EQ_187U(...) \, +#define Z_IS_187U_EQ_187U(...) \, +#define Z_IS_188_EQ_188(...) \, +#define Z_IS_188U_EQ_188(...) \, +#define Z_IS_188_EQ_188U(...) \, +#define Z_IS_188U_EQ_188U(...) \, +#define Z_IS_189_EQ_189(...) \, +#define Z_IS_189U_EQ_189(...) \, +#define Z_IS_189_EQ_189U(...) \, +#define Z_IS_189U_EQ_189U(...) \, +#define Z_IS_190_EQ_190(...) \, +#define Z_IS_190U_EQ_190(...) \, +#define Z_IS_190_EQ_190U(...) \, +#define Z_IS_190U_EQ_190U(...) \, +#define Z_IS_191_EQ_191(...) \, +#define Z_IS_191U_EQ_191(...) \, +#define Z_IS_191_EQ_191U(...) \, +#define Z_IS_191U_EQ_191U(...) \, +#define Z_IS_192_EQ_192(...) \, +#define Z_IS_192U_EQ_192(...) \, +#define Z_IS_192_EQ_192U(...) \, +#define Z_IS_192U_EQ_192U(...) \, +#define Z_IS_193_EQ_193(...) \, +#define Z_IS_193U_EQ_193(...) \, +#define Z_IS_193_EQ_193U(...) \, +#define Z_IS_193U_EQ_193U(...) \, +#define Z_IS_194_EQ_194(...) \, +#define Z_IS_194U_EQ_194(...) \, +#define Z_IS_194_EQ_194U(...) \, +#define Z_IS_194U_EQ_194U(...) \, +#define Z_IS_195_EQ_195(...) \, +#define Z_IS_195U_EQ_195(...) \, +#define Z_IS_195_EQ_195U(...) \, +#define Z_IS_195U_EQ_195U(...) \, +#define Z_IS_196_EQ_196(...) \, +#define Z_IS_196U_EQ_196(...) \, +#define Z_IS_196_EQ_196U(...) \, +#define Z_IS_196U_EQ_196U(...) \, +#define Z_IS_197_EQ_197(...) \, +#define Z_IS_197U_EQ_197(...) \, +#define Z_IS_197_EQ_197U(...) \, +#define Z_IS_197U_EQ_197U(...) \, +#define Z_IS_198_EQ_198(...) \, +#define Z_IS_198U_EQ_198(...) \, +#define Z_IS_198_EQ_198U(...) \, +#define Z_IS_198U_EQ_198U(...) \, +#define Z_IS_199_EQ_199(...) \, +#define Z_IS_199U_EQ_199(...) \, +#define Z_IS_199_EQ_199U(...) \, +#define Z_IS_199U_EQ_199U(...) \, +#define Z_IS_200_EQ_200(...) \, +#define Z_IS_200U_EQ_200(...) \, +#define Z_IS_200_EQ_200U(...) \, +#define Z_IS_200U_EQ_200U(...) \, +#define Z_IS_201_EQ_201(...) \, +#define Z_IS_201U_EQ_201(...) \, +#define Z_IS_201_EQ_201U(...) \, +#define Z_IS_201U_EQ_201U(...) \, +#define Z_IS_202_EQ_202(...) \, +#define Z_IS_202U_EQ_202(...) \, +#define Z_IS_202_EQ_202U(...) \, +#define Z_IS_202U_EQ_202U(...) \, +#define Z_IS_203_EQ_203(...) \, +#define Z_IS_203U_EQ_203(...) \, +#define Z_IS_203_EQ_203U(...) \, +#define Z_IS_203U_EQ_203U(...) \, +#define Z_IS_204_EQ_204(...) \, +#define Z_IS_204U_EQ_204(...) \, +#define Z_IS_204_EQ_204U(...) \, +#define Z_IS_204U_EQ_204U(...) \, +#define Z_IS_205_EQ_205(...) \, +#define Z_IS_205U_EQ_205(...) \, +#define Z_IS_205_EQ_205U(...) \, +#define Z_IS_205U_EQ_205U(...) \, +#define Z_IS_206_EQ_206(...) \, +#define Z_IS_206U_EQ_206(...) \, +#define Z_IS_206_EQ_206U(...) \, +#define Z_IS_206U_EQ_206U(...) \, +#define Z_IS_207_EQ_207(...) \, +#define Z_IS_207U_EQ_207(...) \, +#define Z_IS_207_EQ_207U(...) \, +#define Z_IS_207U_EQ_207U(...) \, +#define Z_IS_208_EQ_208(...) \, +#define Z_IS_208U_EQ_208(...) \, +#define Z_IS_208_EQ_208U(...) \, +#define Z_IS_208U_EQ_208U(...) \, +#define Z_IS_209_EQ_209(...) \, +#define Z_IS_209U_EQ_209(...) \, +#define Z_IS_209_EQ_209U(...) \, +#define Z_IS_209U_EQ_209U(...) \, +#define Z_IS_210_EQ_210(...) \, +#define Z_IS_210U_EQ_210(...) \, +#define Z_IS_210_EQ_210U(...) \, +#define Z_IS_210U_EQ_210U(...) \, +#define Z_IS_211_EQ_211(...) \, +#define Z_IS_211U_EQ_211(...) \, +#define Z_IS_211_EQ_211U(...) \, +#define Z_IS_211U_EQ_211U(...) \, +#define Z_IS_212_EQ_212(...) \, +#define Z_IS_212U_EQ_212(...) \, +#define Z_IS_212_EQ_212U(...) \, +#define Z_IS_212U_EQ_212U(...) \, +#define Z_IS_213_EQ_213(...) \, +#define Z_IS_213U_EQ_213(...) \, +#define Z_IS_213_EQ_213U(...) \, +#define Z_IS_213U_EQ_213U(...) \, +#define Z_IS_214_EQ_214(...) \, +#define Z_IS_214U_EQ_214(...) \, +#define Z_IS_214_EQ_214U(...) \, +#define Z_IS_214U_EQ_214U(...) \, +#define Z_IS_215_EQ_215(...) \, +#define Z_IS_215U_EQ_215(...) \, +#define Z_IS_215_EQ_215U(...) \, +#define Z_IS_215U_EQ_215U(...) \, +#define Z_IS_216_EQ_216(...) \, +#define Z_IS_216U_EQ_216(...) \, +#define Z_IS_216_EQ_216U(...) \, +#define Z_IS_216U_EQ_216U(...) \, +#define Z_IS_217_EQ_217(...) \, +#define Z_IS_217U_EQ_217(...) \, +#define Z_IS_217_EQ_217U(...) \, +#define Z_IS_217U_EQ_217U(...) \, +#define Z_IS_218_EQ_218(...) \, +#define Z_IS_218U_EQ_218(...) \, +#define Z_IS_218_EQ_218U(...) \, +#define Z_IS_218U_EQ_218U(...) \, +#define Z_IS_219_EQ_219(...) \, +#define Z_IS_219U_EQ_219(...) \, +#define Z_IS_219_EQ_219U(...) \, +#define Z_IS_219U_EQ_219U(...) \, +#define Z_IS_220_EQ_220(...) \, +#define Z_IS_220U_EQ_220(...) \, +#define Z_IS_220_EQ_220U(...) \, +#define Z_IS_220U_EQ_220U(...) \, +#define Z_IS_221_EQ_221(...) \, +#define Z_IS_221U_EQ_221(...) \, +#define Z_IS_221_EQ_221U(...) \, +#define Z_IS_221U_EQ_221U(...) \, +#define Z_IS_222_EQ_222(...) \, +#define Z_IS_222U_EQ_222(...) \, +#define Z_IS_222_EQ_222U(...) \, +#define Z_IS_222U_EQ_222U(...) \, +#define Z_IS_223_EQ_223(...) \, +#define Z_IS_223U_EQ_223(...) \, +#define Z_IS_223_EQ_223U(...) \, +#define Z_IS_223U_EQ_223U(...) \, +#define Z_IS_224_EQ_224(...) \, +#define Z_IS_224U_EQ_224(...) \, +#define Z_IS_224_EQ_224U(...) \, +#define Z_IS_224U_EQ_224U(...) \, +#define Z_IS_225_EQ_225(...) \, +#define Z_IS_225U_EQ_225(...) \, +#define Z_IS_225_EQ_225U(...) \, +#define Z_IS_225U_EQ_225U(...) \, +#define Z_IS_226_EQ_226(...) \, +#define Z_IS_226U_EQ_226(...) \, +#define Z_IS_226_EQ_226U(...) \, +#define Z_IS_226U_EQ_226U(...) \, +#define Z_IS_227_EQ_227(...) \, +#define Z_IS_227U_EQ_227(...) \, +#define Z_IS_227_EQ_227U(...) \, +#define Z_IS_227U_EQ_227U(...) \, +#define Z_IS_228_EQ_228(...) \, +#define Z_IS_228U_EQ_228(...) \, +#define Z_IS_228_EQ_228U(...) \, +#define Z_IS_228U_EQ_228U(...) \, +#define Z_IS_229_EQ_229(...) \, +#define Z_IS_229U_EQ_229(...) \, +#define Z_IS_229_EQ_229U(...) \, +#define Z_IS_229U_EQ_229U(...) \, +#define Z_IS_230_EQ_230(...) \, +#define Z_IS_230U_EQ_230(...) \, +#define Z_IS_230_EQ_230U(...) \, +#define Z_IS_230U_EQ_230U(...) \, +#define Z_IS_231_EQ_231(...) \, +#define Z_IS_231U_EQ_231(...) \, +#define Z_IS_231_EQ_231U(...) \, +#define Z_IS_231U_EQ_231U(...) \, +#define Z_IS_232_EQ_232(...) \, +#define Z_IS_232U_EQ_232(...) \, +#define Z_IS_232_EQ_232U(...) \, +#define Z_IS_232U_EQ_232U(...) \, +#define Z_IS_233_EQ_233(...) \, +#define Z_IS_233U_EQ_233(...) \, +#define Z_IS_233_EQ_233U(...) \, +#define Z_IS_233U_EQ_233U(...) \, +#define Z_IS_234_EQ_234(...) \, +#define Z_IS_234U_EQ_234(...) \, +#define Z_IS_234_EQ_234U(...) \, +#define Z_IS_234U_EQ_234U(...) \, +#define Z_IS_235_EQ_235(...) \, +#define Z_IS_235U_EQ_235(...) \, +#define Z_IS_235_EQ_235U(...) \, +#define Z_IS_235U_EQ_235U(...) \, +#define Z_IS_236_EQ_236(...) \, +#define Z_IS_236U_EQ_236(...) \, +#define Z_IS_236_EQ_236U(...) \, +#define Z_IS_236U_EQ_236U(...) \, +#define Z_IS_237_EQ_237(...) \, +#define Z_IS_237U_EQ_237(...) \, +#define Z_IS_237_EQ_237U(...) \, +#define Z_IS_237U_EQ_237U(...) \, +#define Z_IS_238_EQ_238(...) \, +#define Z_IS_238U_EQ_238(...) \, +#define Z_IS_238_EQ_238U(...) \, +#define Z_IS_238U_EQ_238U(...) \, +#define Z_IS_239_EQ_239(...) \, +#define Z_IS_239U_EQ_239(...) \, +#define Z_IS_239_EQ_239U(...) \, +#define Z_IS_239U_EQ_239U(...) \, +#define Z_IS_240_EQ_240(...) \, +#define Z_IS_240U_EQ_240(...) \, +#define Z_IS_240_EQ_240U(...) \, +#define Z_IS_240U_EQ_240U(...) \, +#define Z_IS_241_EQ_241(...) \, +#define Z_IS_241U_EQ_241(...) \, +#define Z_IS_241_EQ_241U(...) \, +#define Z_IS_241U_EQ_241U(...) \, +#define Z_IS_242_EQ_242(...) \, +#define Z_IS_242U_EQ_242(...) \, +#define Z_IS_242_EQ_242U(...) \, +#define Z_IS_242U_EQ_242U(...) \, +#define Z_IS_243_EQ_243(...) \, +#define Z_IS_243U_EQ_243(...) \, +#define Z_IS_243_EQ_243U(...) \, +#define Z_IS_243U_EQ_243U(...) \, +#define Z_IS_244_EQ_244(...) \, +#define Z_IS_244U_EQ_244(...) \, +#define Z_IS_244_EQ_244U(...) \, +#define Z_IS_244U_EQ_244U(...) \, +#define Z_IS_245_EQ_245(...) \, +#define Z_IS_245U_EQ_245(...) \, +#define Z_IS_245_EQ_245U(...) \, +#define Z_IS_245U_EQ_245U(...) \, +#define Z_IS_246_EQ_246(...) \, +#define Z_IS_246U_EQ_246(...) \, +#define Z_IS_246_EQ_246U(...) \, +#define Z_IS_246U_EQ_246U(...) \, +#define Z_IS_247_EQ_247(...) \, +#define Z_IS_247U_EQ_247(...) \, +#define Z_IS_247_EQ_247U(...) \, +#define Z_IS_247U_EQ_247U(...) \, +#define Z_IS_248_EQ_248(...) \, +#define Z_IS_248U_EQ_248(...) \, +#define Z_IS_248_EQ_248U(...) \, +#define Z_IS_248U_EQ_248U(...) \, +#define Z_IS_249_EQ_249(...) \, +#define Z_IS_249U_EQ_249(...) \, +#define Z_IS_249_EQ_249U(...) \, +#define Z_IS_249U_EQ_249U(...) \, +#define Z_IS_250_EQ_250(...) \, +#define Z_IS_250U_EQ_250(...) \, +#define Z_IS_250_EQ_250U(...) \, +#define Z_IS_250U_EQ_250U(...) \, +#define Z_IS_251_EQ_251(...) \, +#define Z_IS_251U_EQ_251(...) \, +#define Z_IS_251_EQ_251U(...) \, +#define Z_IS_251U_EQ_251U(...) \, +#define Z_IS_252_EQ_252(...) \, +#define Z_IS_252U_EQ_252(...) \, +#define Z_IS_252_EQ_252U(...) \, +#define Z_IS_252U_EQ_252U(...) \, +#define Z_IS_253_EQ_253(...) \, +#define Z_IS_253U_EQ_253(...) \, +#define Z_IS_253_EQ_253U(...) \, +#define Z_IS_253U_EQ_253U(...) \, +#define Z_IS_254_EQ_254(...) \, +#define Z_IS_254U_EQ_254(...) \, +#define Z_IS_254_EQ_254U(...) \, +#define Z_IS_254U_EQ_254U(...) \, +#define Z_IS_255_EQ_255(...) \, +#define Z_IS_255U_EQ_255(...) \, +#define Z_IS_255_EQ_255U(...) \, +#define Z_IS_255U_EQ_255U(...) \, +#define Z_IS_256_EQ_256(...) \, +#define Z_IS_256U_EQ_256(...) \, +#define Z_IS_256_EQ_256U(...) \, +#define Z_IS_256U_EQ_256U(...) \, +#define Z_IS_257_EQ_257(...) \, +#define Z_IS_257U_EQ_257(...) \, +#define Z_IS_257_EQ_257U(...) \, +#define Z_IS_257U_EQ_257U(...) \, +#define Z_IS_258_EQ_258(...) \, +#define Z_IS_258U_EQ_258(...) \, +#define Z_IS_258_EQ_258U(...) \, +#define Z_IS_258U_EQ_258U(...) \, +#define Z_IS_259_EQ_259(...) \, +#define Z_IS_259U_EQ_259(...) \, +#define Z_IS_259_EQ_259U(...) \, +#define Z_IS_259U_EQ_259U(...) \, +#define Z_IS_260_EQ_260(...) \, +#define Z_IS_260U_EQ_260(...) \, +#define Z_IS_260_EQ_260U(...) \, +#define Z_IS_260U_EQ_260U(...) \, +#define Z_IS_261_EQ_261(...) \, +#define Z_IS_261U_EQ_261(...) \, +#define Z_IS_261_EQ_261U(...) \, +#define Z_IS_261U_EQ_261U(...) \, +#define Z_IS_262_EQ_262(...) \, +#define Z_IS_262U_EQ_262(...) \, +#define Z_IS_262_EQ_262U(...) \, +#define Z_IS_262U_EQ_262U(...) \, +#define Z_IS_263_EQ_263(...) \, +#define Z_IS_263U_EQ_263(...) \, +#define Z_IS_263_EQ_263U(...) \, +#define Z_IS_263U_EQ_263U(...) \, +#define Z_IS_264_EQ_264(...) \, +#define Z_IS_264U_EQ_264(...) \, +#define Z_IS_264_EQ_264U(...) \, +#define Z_IS_264U_EQ_264U(...) \, +#define Z_IS_265_EQ_265(...) \, +#define Z_IS_265U_EQ_265(...) \, +#define Z_IS_265_EQ_265U(...) \, +#define Z_IS_265U_EQ_265U(...) \, +#define Z_IS_266_EQ_266(...) \, +#define Z_IS_266U_EQ_266(...) \, +#define Z_IS_266_EQ_266U(...) \, +#define Z_IS_266U_EQ_266U(...) \, +#define Z_IS_267_EQ_267(...) \, +#define Z_IS_267U_EQ_267(...) \, +#define Z_IS_267_EQ_267U(...) \, +#define Z_IS_267U_EQ_267U(...) \, +#define Z_IS_268_EQ_268(...) \, +#define Z_IS_268U_EQ_268(...) \, +#define Z_IS_268_EQ_268U(...) \, +#define Z_IS_268U_EQ_268U(...) \, +#define Z_IS_269_EQ_269(...) \, +#define Z_IS_269U_EQ_269(...) \, +#define Z_IS_269_EQ_269U(...) \, +#define Z_IS_269U_EQ_269U(...) \, +#define Z_IS_270_EQ_270(...) \, +#define Z_IS_270U_EQ_270(...) \, +#define Z_IS_270_EQ_270U(...) \, +#define Z_IS_270U_EQ_270U(...) \, +#define Z_IS_271_EQ_271(...) \, +#define Z_IS_271U_EQ_271(...) \, +#define Z_IS_271_EQ_271U(...) \, +#define Z_IS_271U_EQ_271U(...) \, +#define Z_IS_272_EQ_272(...) \, +#define Z_IS_272U_EQ_272(...) \, +#define Z_IS_272_EQ_272U(...) \, +#define Z_IS_272U_EQ_272U(...) \, +#define Z_IS_273_EQ_273(...) \, +#define Z_IS_273U_EQ_273(...) \, +#define Z_IS_273_EQ_273U(...) \, +#define Z_IS_273U_EQ_273U(...) \, +#define Z_IS_274_EQ_274(...) \, +#define Z_IS_274U_EQ_274(...) \, +#define Z_IS_274_EQ_274U(...) \, +#define Z_IS_274U_EQ_274U(...) \, +#define Z_IS_275_EQ_275(...) \, +#define Z_IS_275U_EQ_275(...) \, +#define Z_IS_275_EQ_275U(...) \, +#define Z_IS_275U_EQ_275U(...) \, +#define Z_IS_276_EQ_276(...) \, +#define Z_IS_276U_EQ_276(...) \, +#define Z_IS_276_EQ_276U(...) \, +#define Z_IS_276U_EQ_276U(...) \, +#define Z_IS_277_EQ_277(...) \, +#define Z_IS_277U_EQ_277(...) \, +#define Z_IS_277_EQ_277U(...) \, +#define Z_IS_277U_EQ_277U(...) \, +#define Z_IS_278_EQ_278(...) \, +#define Z_IS_278U_EQ_278(...) \, +#define Z_IS_278_EQ_278U(...) \, +#define Z_IS_278U_EQ_278U(...) \, +#define Z_IS_279_EQ_279(...) \, +#define Z_IS_279U_EQ_279(...) \, +#define Z_IS_279_EQ_279U(...) \, +#define Z_IS_279U_EQ_279U(...) \, +#define Z_IS_280_EQ_280(...) \, +#define Z_IS_280U_EQ_280(...) \, +#define Z_IS_280_EQ_280U(...) \, +#define Z_IS_280U_EQ_280U(...) \, +#define Z_IS_281_EQ_281(...) \, +#define Z_IS_281U_EQ_281(...) \, +#define Z_IS_281_EQ_281U(...) \, +#define Z_IS_281U_EQ_281U(...) \, +#define Z_IS_282_EQ_282(...) \, +#define Z_IS_282U_EQ_282(...) \, +#define Z_IS_282_EQ_282U(...) \, +#define Z_IS_282U_EQ_282U(...) \, +#define Z_IS_283_EQ_283(...) \, +#define Z_IS_283U_EQ_283(...) \, +#define Z_IS_283_EQ_283U(...) \, +#define Z_IS_283U_EQ_283U(...) \, +#define Z_IS_284_EQ_284(...) \, +#define Z_IS_284U_EQ_284(...) \, +#define Z_IS_284_EQ_284U(...) \, +#define Z_IS_284U_EQ_284U(...) \, +#define Z_IS_285_EQ_285(...) \, +#define Z_IS_285U_EQ_285(...) \, +#define Z_IS_285_EQ_285U(...) \, +#define Z_IS_285U_EQ_285U(...) \, +#define Z_IS_286_EQ_286(...) \, +#define Z_IS_286U_EQ_286(...) \, +#define Z_IS_286_EQ_286U(...) \, +#define Z_IS_286U_EQ_286U(...) \, +#define Z_IS_287_EQ_287(...) \, +#define Z_IS_287U_EQ_287(...) \, +#define Z_IS_287_EQ_287U(...) \, +#define Z_IS_287U_EQ_287U(...) \, +#define Z_IS_288_EQ_288(...) \, +#define Z_IS_288U_EQ_288(...) \, +#define Z_IS_288_EQ_288U(...) \, +#define Z_IS_288U_EQ_288U(...) \, +#define Z_IS_289_EQ_289(...) \, +#define Z_IS_289U_EQ_289(...) \, +#define Z_IS_289_EQ_289U(...) \, +#define Z_IS_289U_EQ_289U(...) \, +#define Z_IS_290_EQ_290(...) \, +#define Z_IS_290U_EQ_290(...) \, +#define Z_IS_290_EQ_290U(...) \, +#define Z_IS_290U_EQ_290U(...) \, +#define Z_IS_291_EQ_291(...) \, +#define Z_IS_291U_EQ_291(...) \, +#define Z_IS_291_EQ_291U(...) \, +#define Z_IS_291U_EQ_291U(...) \, +#define Z_IS_292_EQ_292(...) \, +#define Z_IS_292U_EQ_292(...) \, +#define Z_IS_292_EQ_292U(...) \, +#define Z_IS_292U_EQ_292U(...) \, +#define Z_IS_293_EQ_293(...) \, +#define Z_IS_293U_EQ_293(...) \, +#define Z_IS_293_EQ_293U(...) \, +#define Z_IS_293U_EQ_293U(...) \, +#define Z_IS_294_EQ_294(...) \, +#define Z_IS_294U_EQ_294(...) \, +#define Z_IS_294_EQ_294U(...) \, +#define Z_IS_294U_EQ_294U(...) \, +#define Z_IS_295_EQ_295(...) \, +#define Z_IS_295U_EQ_295(...) \, +#define Z_IS_295_EQ_295U(...) \, +#define Z_IS_295U_EQ_295U(...) \, +#define Z_IS_296_EQ_296(...) \, +#define Z_IS_296U_EQ_296(...) \, +#define Z_IS_296_EQ_296U(...) \, +#define Z_IS_296U_EQ_296U(...) \, +#define Z_IS_297_EQ_297(...) \, +#define Z_IS_297U_EQ_297(...) \, +#define Z_IS_297_EQ_297U(...) \, +#define Z_IS_297U_EQ_297U(...) \, +#define Z_IS_298_EQ_298(...) \, +#define Z_IS_298U_EQ_298(...) \, +#define Z_IS_298_EQ_298U(...) \, +#define Z_IS_298U_EQ_298U(...) \, +#define Z_IS_299_EQ_299(...) \, +#define Z_IS_299U_EQ_299(...) \, +#define Z_IS_299_EQ_299U(...) \, +#define Z_IS_299U_EQ_299U(...) \, +#define Z_IS_300_EQ_300(...) \, +#define Z_IS_300U_EQ_300(...) \, +#define Z_IS_300_EQ_300U(...) \, +#define Z_IS_300U_EQ_300U(...) \, +#define Z_IS_301_EQ_301(...) \, +#define Z_IS_301U_EQ_301(...) \, +#define Z_IS_301_EQ_301U(...) \, +#define Z_IS_301U_EQ_301U(...) \, +#define Z_IS_302_EQ_302(...) \, +#define Z_IS_302U_EQ_302(...) \, +#define Z_IS_302_EQ_302U(...) \, +#define Z_IS_302U_EQ_302U(...) \, +#define Z_IS_303_EQ_303(...) \, +#define Z_IS_303U_EQ_303(...) \, +#define Z_IS_303_EQ_303U(...) \, +#define Z_IS_303U_EQ_303U(...) \, +#define Z_IS_304_EQ_304(...) \, +#define Z_IS_304U_EQ_304(...) \, +#define Z_IS_304_EQ_304U(...) \, +#define Z_IS_304U_EQ_304U(...) \, +#define Z_IS_305_EQ_305(...) \, +#define Z_IS_305U_EQ_305(...) \, +#define Z_IS_305_EQ_305U(...) \, +#define Z_IS_305U_EQ_305U(...) \, +#define Z_IS_306_EQ_306(...) \, +#define Z_IS_306U_EQ_306(...) \, +#define Z_IS_306_EQ_306U(...) \, +#define Z_IS_306U_EQ_306U(...) \, +#define Z_IS_307_EQ_307(...) \, +#define Z_IS_307U_EQ_307(...) \, +#define Z_IS_307_EQ_307U(...) \, +#define Z_IS_307U_EQ_307U(...) \, +#define Z_IS_308_EQ_308(...) \, +#define Z_IS_308U_EQ_308(...) \, +#define Z_IS_308_EQ_308U(...) \, +#define Z_IS_308U_EQ_308U(...) \, +#define Z_IS_309_EQ_309(...) \, +#define Z_IS_309U_EQ_309(...) \, +#define Z_IS_309_EQ_309U(...) \, +#define Z_IS_309U_EQ_309U(...) \, +#define Z_IS_310_EQ_310(...) \, +#define Z_IS_310U_EQ_310(...) \, +#define Z_IS_310_EQ_310U(...) \, +#define Z_IS_310U_EQ_310U(...) \, +#define Z_IS_311_EQ_311(...) \, +#define Z_IS_311U_EQ_311(...) \, +#define Z_IS_311_EQ_311U(...) \, +#define Z_IS_311U_EQ_311U(...) \, +#define Z_IS_312_EQ_312(...) \, +#define Z_IS_312U_EQ_312(...) \, +#define Z_IS_312_EQ_312U(...) \, +#define Z_IS_312U_EQ_312U(...) \, +#define Z_IS_313_EQ_313(...) \, +#define Z_IS_313U_EQ_313(...) \, +#define Z_IS_313_EQ_313U(...) \, +#define Z_IS_313U_EQ_313U(...) \, +#define Z_IS_314_EQ_314(...) \, +#define Z_IS_314U_EQ_314(...) \, +#define Z_IS_314_EQ_314U(...) \, +#define Z_IS_314U_EQ_314U(...) \, +#define Z_IS_315_EQ_315(...) \, +#define Z_IS_315U_EQ_315(...) \, +#define Z_IS_315_EQ_315U(...) \, +#define Z_IS_315U_EQ_315U(...) \, +#define Z_IS_316_EQ_316(...) \, +#define Z_IS_316U_EQ_316(...) \, +#define Z_IS_316_EQ_316U(...) \, +#define Z_IS_316U_EQ_316U(...) \, +#define Z_IS_317_EQ_317(...) \, +#define Z_IS_317U_EQ_317(...) \, +#define Z_IS_317_EQ_317U(...) \, +#define Z_IS_317U_EQ_317U(...) \, +#define Z_IS_318_EQ_318(...) \, +#define Z_IS_318U_EQ_318(...) \, +#define Z_IS_318_EQ_318U(...) \, +#define Z_IS_318U_EQ_318U(...) \, +#define Z_IS_319_EQ_319(...) \, +#define Z_IS_319U_EQ_319(...) \, +#define Z_IS_319_EQ_319U(...) \, +#define Z_IS_319U_EQ_319U(...) \, +#define Z_IS_320_EQ_320(...) \, +#define Z_IS_320U_EQ_320(...) \, +#define Z_IS_320_EQ_320U(...) \, +#define Z_IS_320U_EQ_320U(...) \, +#define Z_IS_321_EQ_321(...) \, +#define Z_IS_321U_EQ_321(...) \, +#define Z_IS_321_EQ_321U(...) \, +#define Z_IS_321U_EQ_321U(...) \, +#define Z_IS_322_EQ_322(...) \, +#define Z_IS_322U_EQ_322(...) \, +#define Z_IS_322_EQ_322U(...) \, +#define Z_IS_322U_EQ_322U(...) \, +#define Z_IS_323_EQ_323(...) \, +#define Z_IS_323U_EQ_323(...) \, +#define Z_IS_323_EQ_323U(...) \, +#define Z_IS_323U_EQ_323U(...) \, +#define Z_IS_324_EQ_324(...) \, +#define Z_IS_324U_EQ_324(...) \, +#define Z_IS_324_EQ_324U(...) \, +#define Z_IS_324U_EQ_324U(...) \, +#define Z_IS_325_EQ_325(...) \, +#define Z_IS_325U_EQ_325(...) \, +#define Z_IS_325_EQ_325U(...) \, +#define Z_IS_325U_EQ_325U(...) \, +#define Z_IS_326_EQ_326(...) \, +#define Z_IS_326U_EQ_326(...) \, +#define Z_IS_326_EQ_326U(...) \, +#define Z_IS_326U_EQ_326U(...) \, +#define Z_IS_327_EQ_327(...) \, +#define Z_IS_327U_EQ_327(...) \, +#define Z_IS_327_EQ_327U(...) \, +#define Z_IS_327U_EQ_327U(...) \, +#define Z_IS_328_EQ_328(...) \, +#define Z_IS_328U_EQ_328(...) \, +#define Z_IS_328_EQ_328U(...) \, +#define Z_IS_328U_EQ_328U(...) \, +#define Z_IS_329_EQ_329(...) \, +#define Z_IS_329U_EQ_329(...) \, +#define Z_IS_329_EQ_329U(...) \, +#define Z_IS_329U_EQ_329U(...) \, +#define Z_IS_330_EQ_330(...) \, +#define Z_IS_330U_EQ_330(...) \, +#define Z_IS_330_EQ_330U(...) \, +#define Z_IS_330U_EQ_330U(...) \, +#define Z_IS_331_EQ_331(...) \, +#define Z_IS_331U_EQ_331(...) \, +#define Z_IS_331_EQ_331U(...) \, +#define Z_IS_331U_EQ_331U(...) \, +#define Z_IS_332_EQ_332(...) \, +#define Z_IS_332U_EQ_332(...) \, +#define Z_IS_332_EQ_332U(...) \, +#define Z_IS_332U_EQ_332U(...) \, +#define Z_IS_333_EQ_333(...) \, +#define Z_IS_333U_EQ_333(...) \, +#define Z_IS_333_EQ_333U(...) \, +#define Z_IS_333U_EQ_333U(...) \, +#define Z_IS_334_EQ_334(...) \, +#define Z_IS_334U_EQ_334(...) \, +#define Z_IS_334_EQ_334U(...) \, +#define Z_IS_334U_EQ_334U(...) \, +#define Z_IS_335_EQ_335(...) \, +#define Z_IS_335U_EQ_335(...) \, +#define Z_IS_335_EQ_335U(...) \, +#define Z_IS_335U_EQ_335U(...) \, +#define Z_IS_336_EQ_336(...) \, +#define Z_IS_336U_EQ_336(...) \, +#define Z_IS_336_EQ_336U(...) \, +#define Z_IS_336U_EQ_336U(...) \, +#define Z_IS_337_EQ_337(...) \, +#define Z_IS_337U_EQ_337(...) \, +#define Z_IS_337_EQ_337U(...) \, +#define Z_IS_337U_EQ_337U(...) \, +#define Z_IS_338_EQ_338(...) \, +#define Z_IS_338U_EQ_338(...) \, +#define Z_IS_338_EQ_338U(...) \, +#define Z_IS_338U_EQ_338U(...) \, +#define Z_IS_339_EQ_339(...) \, +#define Z_IS_339U_EQ_339(...) \, +#define Z_IS_339_EQ_339U(...) \, +#define Z_IS_339U_EQ_339U(...) \, +#define Z_IS_340_EQ_340(...) \, +#define Z_IS_340U_EQ_340(...) \, +#define Z_IS_340_EQ_340U(...) \, +#define Z_IS_340U_EQ_340U(...) \, +#define Z_IS_341_EQ_341(...) \, +#define Z_IS_341U_EQ_341(...) \, +#define Z_IS_341_EQ_341U(...) \, +#define Z_IS_341U_EQ_341U(...) \, +#define Z_IS_342_EQ_342(...) \, +#define Z_IS_342U_EQ_342(...) \, +#define Z_IS_342_EQ_342U(...) \, +#define Z_IS_342U_EQ_342U(...) \, +#define Z_IS_343_EQ_343(...) \, +#define Z_IS_343U_EQ_343(...) \, +#define Z_IS_343_EQ_343U(...) \, +#define Z_IS_343U_EQ_343U(...) \, +#define Z_IS_344_EQ_344(...) \, +#define Z_IS_344U_EQ_344(...) \, +#define Z_IS_344_EQ_344U(...) \, +#define Z_IS_344U_EQ_344U(...) \, +#define Z_IS_345_EQ_345(...) \, +#define Z_IS_345U_EQ_345(...) \, +#define Z_IS_345_EQ_345U(...) \, +#define Z_IS_345U_EQ_345U(...) \, +#define Z_IS_346_EQ_346(...) \, +#define Z_IS_346U_EQ_346(...) \, +#define Z_IS_346_EQ_346U(...) \, +#define Z_IS_346U_EQ_346U(...) \, +#define Z_IS_347_EQ_347(...) \, +#define Z_IS_347U_EQ_347(...) \, +#define Z_IS_347_EQ_347U(...) \, +#define Z_IS_347U_EQ_347U(...) \, +#define Z_IS_348_EQ_348(...) \, +#define Z_IS_348U_EQ_348(...) \, +#define Z_IS_348_EQ_348U(...) \, +#define Z_IS_348U_EQ_348U(...) \, +#define Z_IS_349_EQ_349(...) \, +#define Z_IS_349U_EQ_349(...) \, +#define Z_IS_349_EQ_349U(...) \, +#define Z_IS_349U_EQ_349U(...) \, +#define Z_IS_350_EQ_350(...) \, +#define Z_IS_350U_EQ_350(...) \, +#define Z_IS_350_EQ_350U(...) \, +#define Z_IS_350U_EQ_350U(...) \, +#define Z_IS_351_EQ_351(...) \, +#define Z_IS_351U_EQ_351(...) \, +#define Z_IS_351_EQ_351U(...) \, +#define Z_IS_351U_EQ_351U(...) \, +#define Z_IS_352_EQ_352(...) \, +#define Z_IS_352U_EQ_352(...) \, +#define Z_IS_352_EQ_352U(...) \, +#define Z_IS_352U_EQ_352U(...) \, +#define Z_IS_353_EQ_353(...) \, +#define Z_IS_353U_EQ_353(...) \, +#define Z_IS_353_EQ_353U(...) \, +#define Z_IS_353U_EQ_353U(...) \, +#define Z_IS_354_EQ_354(...) \, +#define Z_IS_354U_EQ_354(...) \, +#define Z_IS_354_EQ_354U(...) \, +#define Z_IS_354U_EQ_354U(...) \, +#define Z_IS_355_EQ_355(...) \, +#define Z_IS_355U_EQ_355(...) \, +#define Z_IS_355_EQ_355U(...) \, +#define Z_IS_355U_EQ_355U(...) \, +#define Z_IS_356_EQ_356(...) \, +#define Z_IS_356U_EQ_356(...) \, +#define Z_IS_356_EQ_356U(...) \, +#define Z_IS_356U_EQ_356U(...) \, +#define Z_IS_357_EQ_357(...) \, +#define Z_IS_357U_EQ_357(...) \, +#define Z_IS_357_EQ_357U(...) \, +#define Z_IS_357U_EQ_357U(...) \, +#define Z_IS_358_EQ_358(...) \, +#define Z_IS_358U_EQ_358(...) \, +#define Z_IS_358_EQ_358U(...) \, +#define Z_IS_358U_EQ_358U(...) \, +#define Z_IS_359_EQ_359(...) \, +#define Z_IS_359U_EQ_359(...) \, +#define Z_IS_359_EQ_359U(...) \, +#define Z_IS_359U_EQ_359U(...) \, +#define Z_IS_360_EQ_360(...) \, +#define Z_IS_360U_EQ_360(...) \, +#define Z_IS_360_EQ_360U(...) \, +#define Z_IS_360U_EQ_360U(...) \, +#define Z_IS_361_EQ_361(...) \, +#define Z_IS_361U_EQ_361(...) \, +#define Z_IS_361_EQ_361U(...) \, +#define Z_IS_361U_EQ_361U(...) \, +#define Z_IS_362_EQ_362(...) \, +#define Z_IS_362U_EQ_362(...) \, +#define Z_IS_362_EQ_362U(...) \, +#define Z_IS_362U_EQ_362U(...) \, +#define Z_IS_363_EQ_363(...) \, +#define Z_IS_363U_EQ_363(...) \, +#define Z_IS_363_EQ_363U(...) \, +#define Z_IS_363U_EQ_363U(...) \, +#define Z_IS_364_EQ_364(...) \, +#define Z_IS_364U_EQ_364(...) \, +#define Z_IS_364_EQ_364U(...) \, +#define Z_IS_364U_EQ_364U(...) \, +#define Z_IS_365_EQ_365(...) \, +#define Z_IS_365U_EQ_365(...) \, +#define Z_IS_365_EQ_365U(...) \, +#define Z_IS_365U_EQ_365U(...) \, +#define Z_IS_366_EQ_366(...) \, +#define Z_IS_366U_EQ_366(...) \, +#define Z_IS_366_EQ_366U(...) \, +#define Z_IS_366U_EQ_366U(...) \, +#define Z_IS_367_EQ_367(...) \, +#define Z_IS_367U_EQ_367(...) \, +#define Z_IS_367_EQ_367U(...) \, +#define Z_IS_367U_EQ_367U(...) \, +#define Z_IS_368_EQ_368(...) \, +#define Z_IS_368U_EQ_368(...) \, +#define Z_IS_368_EQ_368U(...) \, +#define Z_IS_368U_EQ_368U(...) \, +#define Z_IS_369_EQ_369(...) \, +#define Z_IS_369U_EQ_369(...) \, +#define Z_IS_369_EQ_369U(...) \, +#define Z_IS_369U_EQ_369U(...) \, +#define Z_IS_370_EQ_370(...) \, +#define Z_IS_370U_EQ_370(...) \, +#define Z_IS_370_EQ_370U(...) \, +#define Z_IS_370U_EQ_370U(...) \, +#define Z_IS_371_EQ_371(...) \, +#define Z_IS_371U_EQ_371(...) \, +#define Z_IS_371_EQ_371U(...) \, +#define Z_IS_371U_EQ_371U(...) \, +#define Z_IS_372_EQ_372(...) \, +#define Z_IS_372U_EQ_372(...) \, +#define Z_IS_372_EQ_372U(...) \, +#define Z_IS_372U_EQ_372U(...) \, +#define Z_IS_373_EQ_373(...) \, +#define Z_IS_373U_EQ_373(...) \, +#define Z_IS_373_EQ_373U(...) \, +#define Z_IS_373U_EQ_373U(...) \, +#define Z_IS_374_EQ_374(...) \, +#define Z_IS_374U_EQ_374(...) \, +#define Z_IS_374_EQ_374U(...) \, +#define Z_IS_374U_EQ_374U(...) \, +#define Z_IS_375_EQ_375(...) \, +#define Z_IS_375U_EQ_375(...) \, +#define Z_IS_375_EQ_375U(...) \, +#define Z_IS_375U_EQ_375U(...) \, +#define Z_IS_376_EQ_376(...) \, +#define Z_IS_376U_EQ_376(...) \, +#define Z_IS_376_EQ_376U(...) \, +#define Z_IS_376U_EQ_376U(...) \, +#define Z_IS_377_EQ_377(...) \, +#define Z_IS_377U_EQ_377(...) \, +#define Z_IS_377_EQ_377U(...) \, +#define Z_IS_377U_EQ_377U(...) \, +#define Z_IS_378_EQ_378(...) \, +#define Z_IS_378U_EQ_378(...) \, +#define Z_IS_378_EQ_378U(...) \, +#define Z_IS_378U_EQ_378U(...) \, +#define Z_IS_379_EQ_379(...) \, +#define Z_IS_379U_EQ_379(...) \, +#define Z_IS_379_EQ_379U(...) \, +#define Z_IS_379U_EQ_379U(...) \, +#define Z_IS_380_EQ_380(...) \, +#define Z_IS_380U_EQ_380(...) \, +#define Z_IS_380_EQ_380U(...) \, +#define Z_IS_380U_EQ_380U(...) \, +#define Z_IS_381_EQ_381(...) \, +#define Z_IS_381U_EQ_381(...) \, +#define Z_IS_381_EQ_381U(...) \, +#define Z_IS_381U_EQ_381U(...) \, +#define Z_IS_382_EQ_382(...) \, +#define Z_IS_382U_EQ_382(...) \, +#define Z_IS_382_EQ_382U(...) \, +#define Z_IS_382U_EQ_382U(...) \, +#define Z_IS_383_EQ_383(...) \, +#define Z_IS_383U_EQ_383(...) \, +#define Z_IS_383_EQ_383U(...) \, +#define Z_IS_383U_EQ_383U(...) \, +#define Z_IS_384_EQ_384(...) \, +#define Z_IS_384U_EQ_384(...) \, +#define Z_IS_384_EQ_384U(...) \, +#define Z_IS_384U_EQ_384U(...) \, +#define Z_IS_385_EQ_385(...) \, +#define Z_IS_385U_EQ_385(...) \, +#define Z_IS_385_EQ_385U(...) \, +#define Z_IS_385U_EQ_385U(...) \, +#define Z_IS_386_EQ_386(...) \, +#define Z_IS_386U_EQ_386(...) \, +#define Z_IS_386_EQ_386U(...) \, +#define Z_IS_386U_EQ_386U(...) \, +#define Z_IS_387_EQ_387(...) \, +#define Z_IS_387U_EQ_387(...) \, +#define Z_IS_387_EQ_387U(...) \, +#define Z_IS_387U_EQ_387U(...) \, +#define Z_IS_388_EQ_388(...) \, +#define Z_IS_388U_EQ_388(...) \, +#define Z_IS_388_EQ_388U(...) \, +#define Z_IS_388U_EQ_388U(...) \, +#define Z_IS_389_EQ_389(...) \, +#define Z_IS_389U_EQ_389(...) \, +#define Z_IS_389_EQ_389U(...) \, +#define Z_IS_389U_EQ_389U(...) \, +#define Z_IS_390_EQ_390(...) \, +#define Z_IS_390U_EQ_390(...) \, +#define Z_IS_390_EQ_390U(...) \, +#define Z_IS_390U_EQ_390U(...) \, +#define Z_IS_391_EQ_391(...) \, +#define Z_IS_391U_EQ_391(...) \, +#define Z_IS_391_EQ_391U(...) \, +#define Z_IS_391U_EQ_391U(...) \, +#define Z_IS_392_EQ_392(...) \, +#define Z_IS_392U_EQ_392(...) \, +#define Z_IS_392_EQ_392U(...) \, +#define Z_IS_392U_EQ_392U(...) \, +#define Z_IS_393_EQ_393(...) \, +#define Z_IS_393U_EQ_393(...) \, +#define Z_IS_393_EQ_393U(...) \, +#define Z_IS_393U_EQ_393U(...) \, +#define Z_IS_394_EQ_394(...) \, +#define Z_IS_394U_EQ_394(...) \, +#define Z_IS_394_EQ_394U(...) \, +#define Z_IS_394U_EQ_394U(...) \, +#define Z_IS_395_EQ_395(...) \, +#define Z_IS_395U_EQ_395(...) \, +#define Z_IS_395_EQ_395U(...) \, +#define Z_IS_395U_EQ_395U(...) \, +#define Z_IS_396_EQ_396(...) \, +#define Z_IS_396U_EQ_396(...) \, +#define Z_IS_396_EQ_396U(...) \, +#define Z_IS_396U_EQ_396U(...) \, +#define Z_IS_397_EQ_397(...) \, +#define Z_IS_397U_EQ_397(...) \, +#define Z_IS_397_EQ_397U(...) \, +#define Z_IS_397U_EQ_397U(...) \, +#define Z_IS_398_EQ_398(...) \, +#define Z_IS_398U_EQ_398(...) \, +#define Z_IS_398_EQ_398U(...) \, +#define Z_IS_398U_EQ_398U(...) \, +#define Z_IS_399_EQ_399(...) \, +#define Z_IS_399U_EQ_399(...) \, +#define Z_IS_399_EQ_399U(...) \, +#define Z_IS_399U_EQ_399U(...) \, +#define Z_IS_400_EQ_400(...) \, +#define Z_IS_400U_EQ_400(...) \, +#define Z_IS_400_EQ_400U(...) \, +#define Z_IS_400U_EQ_400U(...) \, +#define Z_IS_401_EQ_401(...) \, +#define Z_IS_401U_EQ_401(...) \, +#define Z_IS_401_EQ_401U(...) \, +#define Z_IS_401U_EQ_401U(...) \, +#define Z_IS_402_EQ_402(...) \, +#define Z_IS_402U_EQ_402(...) \, +#define Z_IS_402_EQ_402U(...) \, +#define Z_IS_402U_EQ_402U(...) \, +#define Z_IS_403_EQ_403(...) \, +#define Z_IS_403U_EQ_403(...) \, +#define Z_IS_403_EQ_403U(...) \, +#define Z_IS_403U_EQ_403U(...) \, +#define Z_IS_404_EQ_404(...) \, +#define Z_IS_404U_EQ_404(...) \, +#define Z_IS_404_EQ_404U(...) \, +#define Z_IS_404U_EQ_404U(...) \, +#define Z_IS_405_EQ_405(...) \, +#define Z_IS_405U_EQ_405(...) \, +#define Z_IS_405_EQ_405U(...) \, +#define Z_IS_405U_EQ_405U(...) \, +#define Z_IS_406_EQ_406(...) \, +#define Z_IS_406U_EQ_406(...) \, +#define Z_IS_406_EQ_406U(...) \, +#define Z_IS_406U_EQ_406U(...) \, +#define Z_IS_407_EQ_407(...) \, +#define Z_IS_407U_EQ_407(...) \, +#define Z_IS_407_EQ_407U(...) \, +#define Z_IS_407U_EQ_407U(...) \, +#define Z_IS_408_EQ_408(...) \, +#define Z_IS_408U_EQ_408(...) \, +#define Z_IS_408_EQ_408U(...) \, +#define Z_IS_408U_EQ_408U(...) \, +#define Z_IS_409_EQ_409(...) \, +#define Z_IS_409U_EQ_409(...) \, +#define Z_IS_409_EQ_409U(...) \, +#define Z_IS_409U_EQ_409U(...) \, +#define Z_IS_410_EQ_410(...) \, +#define Z_IS_410U_EQ_410(...) \, +#define Z_IS_410_EQ_410U(...) \, +#define Z_IS_410U_EQ_410U(...) \, +#define Z_IS_411_EQ_411(...) \, +#define Z_IS_411U_EQ_411(...) \, +#define Z_IS_411_EQ_411U(...) \, +#define Z_IS_411U_EQ_411U(...) \, +#define Z_IS_412_EQ_412(...) \, +#define Z_IS_412U_EQ_412(...) \, +#define Z_IS_412_EQ_412U(...) \, +#define Z_IS_412U_EQ_412U(...) \, +#define Z_IS_413_EQ_413(...) \, +#define Z_IS_413U_EQ_413(...) \, +#define Z_IS_413_EQ_413U(...) \, +#define Z_IS_413U_EQ_413U(...) \, +#define Z_IS_414_EQ_414(...) \, +#define Z_IS_414U_EQ_414(...) \, +#define Z_IS_414_EQ_414U(...) \, +#define Z_IS_414U_EQ_414U(...) \, +#define Z_IS_415_EQ_415(...) \, +#define Z_IS_415U_EQ_415(...) \, +#define Z_IS_415_EQ_415U(...) \, +#define Z_IS_415U_EQ_415U(...) \, +#define Z_IS_416_EQ_416(...) \, +#define Z_IS_416U_EQ_416(...) \, +#define Z_IS_416_EQ_416U(...) \, +#define Z_IS_416U_EQ_416U(...) \, +#define Z_IS_417_EQ_417(...) \, +#define Z_IS_417U_EQ_417(...) \, +#define Z_IS_417_EQ_417U(...) \, +#define Z_IS_417U_EQ_417U(...) \, +#define Z_IS_418_EQ_418(...) \, +#define Z_IS_418U_EQ_418(...) \, +#define Z_IS_418_EQ_418U(...) \, +#define Z_IS_418U_EQ_418U(...) \, +#define Z_IS_419_EQ_419(...) \, +#define Z_IS_419U_EQ_419(...) \, +#define Z_IS_419_EQ_419U(...) \, +#define Z_IS_419U_EQ_419U(...) \, +#define Z_IS_420_EQ_420(...) \, +#define Z_IS_420U_EQ_420(...) \, +#define Z_IS_420_EQ_420U(...) \, +#define Z_IS_420U_EQ_420U(...) \, +#define Z_IS_421_EQ_421(...) \, +#define Z_IS_421U_EQ_421(...) \, +#define Z_IS_421_EQ_421U(...) \, +#define Z_IS_421U_EQ_421U(...) \, +#define Z_IS_422_EQ_422(...) \, +#define Z_IS_422U_EQ_422(...) \, +#define Z_IS_422_EQ_422U(...) \, +#define Z_IS_422U_EQ_422U(...) \, +#define Z_IS_423_EQ_423(...) \, +#define Z_IS_423U_EQ_423(...) \, +#define Z_IS_423_EQ_423U(...) \, +#define Z_IS_423U_EQ_423U(...) \, +#define Z_IS_424_EQ_424(...) \, +#define Z_IS_424U_EQ_424(...) \, +#define Z_IS_424_EQ_424U(...) \, +#define Z_IS_424U_EQ_424U(...) \, +#define Z_IS_425_EQ_425(...) \, +#define Z_IS_425U_EQ_425(...) \, +#define Z_IS_425_EQ_425U(...) \, +#define Z_IS_425U_EQ_425U(...) \, +#define Z_IS_426_EQ_426(...) \, +#define Z_IS_426U_EQ_426(...) \, +#define Z_IS_426_EQ_426U(...) \, +#define Z_IS_426U_EQ_426U(...) \, +#define Z_IS_427_EQ_427(...) \, +#define Z_IS_427U_EQ_427(...) \, +#define Z_IS_427_EQ_427U(...) \, +#define Z_IS_427U_EQ_427U(...) \, +#define Z_IS_428_EQ_428(...) \, +#define Z_IS_428U_EQ_428(...) \, +#define Z_IS_428_EQ_428U(...) \, +#define Z_IS_428U_EQ_428U(...) \, +#define Z_IS_429_EQ_429(...) \, +#define Z_IS_429U_EQ_429(...) \, +#define Z_IS_429_EQ_429U(...) \, +#define Z_IS_429U_EQ_429U(...) \, +#define Z_IS_430_EQ_430(...) \, +#define Z_IS_430U_EQ_430(...) \, +#define Z_IS_430_EQ_430U(...) \, +#define Z_IS_430U_EQ_430U(...) \, +#define Z_IS_431_EQ_431(...) \, +#define Z_IS_431U_EQ_431(...) \, +#define Z_IS_431_EQ_431U(...) \, +#define Z_IS_431U_EQ_431U(...) \, +#define Z_IS_432_EQ_432(...) \, +#define Z_IS_432U_EQ_432(...) \, +#define Z_IS_432_EQ_432U(...) \, +#define Z_IS_432U_EQ_432U(...) \, +#define Z_IS_433_EQ_433(...) \, +#define Z_IS_433U_EQ_433(...) \, +#define Z_IS_433_EQ_433U(...) \, +#define Z_IS_433U_EQ_433U(...) \, +#define Z_IS_434_EQ_434(...) \, +#define Z_IS_434U_EQ_434(...) \, +#define Z_IS_434_EQ_434U(...) \, +#define Z_IS_434U_EQ_434U(...) \, +#define Z_IS_435_EQ_435(...) \, +#define Z_IS_435U_EQ_435(...) \, +#define Z_IS_435_EQ_435U(...) \, +#define Z_IS_435U_EQ_435U(...) \, +#define Z_IS_436_EQ_436(...) \, +#define Z_IS_436U_EQ_436(...) \, +#define Z_IS_436_EQ_436U(...) \, +#define Z_IS_436U_EQ_436U(...) \, +#define Z_IS_437_EQ_437(...) \, +#define Z_IS_437U_EQ_437(...) \, +#define Z_IS_437_EQ_437U(...) \, +#define Z_IS_437U_EQ_437U(...) \, +#define Z_IS_438_EQ_438(...) \, +#define Z_IS_438U_EQ_438(...) \, +#define Z_IS_438_EQ_438U(...) \, +#define Z_IS_438U_EQ_438U(...) \, +#define Z_IS_439_EQ_439(...) \, +#define Z_IS_439U_EQ_439(...) \, +#define Z_IS_439_EQ_439U(...) \, +#define Z_IS_439U_EQ_439U(...) \, +#define Z_IS_440_EQ_440(...) \, +#define Z_IS_440U_EQ_440(...) \, +#define Z_IS_440_EQ_440U(...) \, +#define Z_IS_440U_EQ_440U(...) \, +#define Z_IS_441_EQ_441(...) \, +#define Z_IS_441U_EQ_441(...) \, +#define Z_IS_441_EQ_441U(...) \, +#define Z_IS_441U_EQ_441U(...) \, +#define Z_IS_442_EQ_442(...) \, +#define Z_IS_442U_EQ_442(...) \, +#define Z_IS_442_EQ_442U(...) \, +#define Z_IS_442U_EQ_442U(...) \, +#define Z_IS_443_EQ_443(...) \, +#define Z_IS_443U_EQ_443(...) \, +#define Z_IS_443_EQ_443U(...) \, +#define Z_IS_443U_EQ_443U(...) \, +#define Z_IS_444_EQ_444(...) \, +#define Z_IS_444U_EQ_444(...) \, +#define Z_IS_444_EQ_444U(...) \, +#define Z_IS_444U_EQ_444U(...) \, +#define Z_IS_445_EQ_445(...) \, +#define Z_IS_445U_EQ_445(...) \, +#define Z_IS_445_EQ_445U(...) \, +#define Z_IS_445U_EQ_445U(...) \, +#define Z_IS_446_EQ_446(...) \, +#define Z_IS_446U_EQ_446(...) \, +#define Z_IS_446_EQ_446U(...) \, +#define Z_IS_446U_EQ_446U(...) \, +#define Z_IS_447_EQ_447(...) \, +#define Z_IS_447U_EQ_447(...) \, +#define Z_IS_447_EQ_447U(...) \, +#define Z_IS_447U_EQ_447U(...) \, +#define Z_IS_448_EQ_448(...) \, +#define Z_IS_448U_EQ_448(...) \, +#define Z_IS_448_EQ_448U(...) \, +#define Z_IS_448U_EQ_448U(...) \, +#define Z_IS_449_EQ_449(...) \, +#define Z_IS_449U_EQ_449(...) \, +#define Z_IS_449_EQ_449U(...) \, +#define Z_IS_449U_EQ_449U(...) \, +#define Z_IS_450_EQ_450(...) \, +#define Z_IS_450U_EQ_450(...) \, +#define Z_IS_450_EQ_450U(...) \, +#define Z_IS_450U_EQ_450U(...) \, +#define Z_IS_451_EQ_451(...) \, +#define Z_IS_451U_EQ_451(...) \, +#define Z_IS_451_EQ_451U(...) \, +#define Z_IS_451U_EQ_451U(...) \, +#define Z_IS_452_EQ_452(...) \, +#define Z_IS_452U_EQ_452(...) \, +#define Z_IS_452_EQ_452U(...) \, +#define Z_IS_452U_EQ_452U(...) \, +#define Z_IS_453_EQ_453(...) \, +#define Z_IS_453U_EQ_453(...) \, +#define Z_IS_453_EQ_453U(...) \, +#define Z_IS_453U_EQ_453U(...) \, +#define Z_IS_454_EQ_454(...) \, +#define Z_IS_454U_EQ_454(...) \, +#define Z_IS_454_EQ_454U(...) \, +#define Z_IS_454U_EQ_454U(...) \, +#define Z_IS_455_EQ_455(...) \, +#define Z_IS_455U_EQ_455(...) \, +#define Z_IS_455_EQ_455U(...) \, +#define Z_IS_455U_EQ_455U(...) \, +#define Z_IS_456_EQ_456(...) \, +#define Z_IS_456U_EQ_456(...) \, +#define Z_IS_456_EQ_456U(...) \, +#define Z_IS_456U_EQ_456U(...) \, +#define Z_IS_457_EQ_457(...) \, +#define Z_IS_457U_EQ_457(...) \, +#define Z_IS_457_EQ_457U(...) \, +#define Z_IS_457U_EQ_457U(...) \, +#define Z_IS_458_EQ_458(...) \, +#define Z_IS_458U_EQ_458(...) \, +#define Z_IS_458_EQ_458U(...) \, +#define Z_IS_458U_EQ_458U(...) \, +#define Z_IS_459_EQ_459(...) \, +#define Z_IS_459U_EQ_459(...) \, +#define Z_IS_459_EQ_459U(...) \, +#define Z_IS_459U_EQ_459U(...) \, +#define Z_IS_460_EQ_460(...) \, +#define Z_IS_460U_EQ_460(...) \, +#define Z_IS_460_EQ_460U(...) \, +#define Z_IS_460U_EQ_460U(...) \, +#define Z_IS_461_EQ_461(...) \, +#define Z_IS_461U_EQ_461(...) \, +#define Z_IS_461_EQ_461U(...) \, +#define Z_IS_461U_EQ_461U(...) \, +#define Z_IS_462_EQ_462(...) \, +#define Z_IS_462U_EQ_462(...) \, +#define Z_IS_462_EQ_462U(...) \, +#define Z_IS_462U_EQ_462U(...) \, +#define Z_IS_463_EQ_463(...) \, +#define Z_IS_463U_EQ_463(...) \, +#define Z_IS_463_EQ_463U(...) \, +#define Z_IS_463U_EQ_463U(...) \, +#define Z_IS_464_EQ_464(...) \, +#define Z_IS_464U_EQ_464(...) \, +#define Z_IS_464_EQ_464U(...) \, +#define Z_IS_464U_EQ_464U(...) \, +#define Z_IS_465_EQ_465(...) \, +#define Z_IS_465U_EQ_465(...) \, +#define Z_IS_465_EQ_465U(...) \, +#define Z_IS_465U_EQ_465U(...) \, +#define Z_IS_466_EQ_466(...) \, +#define Z_IS_466U_EQ_466(...) \, +#define Z_IS_466_EQ_466U(...) \, +#define Z_IS_466U_EQ_466U(...) \, +#define Z_IS_467_EQ_467(...) \, +#define Z_IS_467U_EQ_467(...) \, +#define Z_IS_467_EQ_467U(...) \, +#define Z_IS_467U_EQ_467U(...) \, +#define Z_IS_468_EQ_468(...) \, +#define Z_IS_468U_EQ_468(...) \, +#define Z_IS_468_EQ_468U(...) \, +#define Z_IS_468U_EQ_468U(...) \, +#define Z_IS_469_EQ_469(...) \, +#define Z_IS_469U_EQ_469(...) \, +#define Z_IS_469_EQ_469U(...) \, +#define Z_IS_469U_EQ_469U(...) \, +#define Z_IS_470_EQ_470(...) \, +#define Z_IS_470U_EQ_470(...) \, +#define Z_IS_470_EQ_470U(...) \, +#define Z_IS_470U_EQ_470U(...) \, +#define Z_IS_471_EQ_471(...) \, +#define Z_IS_471U_EQ_471(...) \, +#define Z_IS_471_EQ_471U(...) \, +#define Z_IS_471U_EQ_471U(...) \, +#define Z_IS_472_EQ_472(...) \, +#define Z_IS_472U_EQ_472(...) \, +#define Z_IS_472_EQ_472U(...) \, +#define Z_IS_472U_EQ_472U(...) \, +#define Z_IS_473_EQ_473(...) \, +#define Z_IS_473U_EQ_473(...) \, +#define Z_IS_473_EQ_473U(...) \, +#define Z_IS_473U_EQ_473U(...) \, +#define Z_IS_474_EQ_474(...) \, +#define Z_IS_474U_EQ_474(...) \, +#define Z_IS_474_EQ_474U(...) \, +#define Z_IS_474U_EQ_474U(...) \, +#define Z_IS_475_EQ_475(...) \, +#define Z_IS_475U_EQ_475(...) \, +#define Z_IS_475_EQ_475U(...) \, +#define Z_IS_475U_EQ_475U(...) \, +#define Z_IS_476_EQ_476(...) \, +#define Z_IS_476U_EQ_476(...) \, +#define Z_IS_476_EQ_476U(...) \, +#define Z_IS_476U_EQ_476U(...) \, +#define Z_IS_477_EQ_477(...) \, +#define Z_IS_477U_EQ_477(...) \, +#define Z_IS_477_EQ_477U(...) \, +#define Z_IS_477U_EQ_477U(...) \, +#define Z_IS_478_EQ_478(...) \, +#define Z_IS_478U_EQ_478(...) \, +#define Z_IS_478_EQ_478U(...) \, +#define Z_IS_478U_EQ_478U(...) \, +#define Z_IS_479_EQ_479(...) \, +#define Z_IS_479U_EQ_479(...) \, +#define Z_IS_479_EQ_479U(...) \, +#define Z_IS_479U_EQ_479U(...) \, +#define Z_IS_480_EQ_480(...) \, +#define Z_IS_480U_EQ_480(...) \, +#define Z_IS_480_EQ_480U(...) \, +#define Z_IS_480U_EQ_480U(...) \, +#define Z_IS_481_EQ_481(...) \, +#define Z_IS_481U_EQ_481(...) \, +#define Z_IS_481_EQ_481U(...) \, +#define Z_IS_481U_EQ_481U(...) \, +#define Z_IS_482_EQ_482(...) \, +#define Z_IS_482U_EQ_482(...) \, +#define Z_IS_482_EQ_482U(...) \, +#define Z_IS_482U_EQ_482U(...) \, +#define Z_IS_483_EQ_483(...) \, +#define Z_IS_483U_EQ_483(...) \, +#define Z_IS_483_EQ_483U(...) \, +#define Z_IS_483U_EQ_483U(...) \, +#define Z_IS_484_EQ_484(...) \, +#define Z_IS_484U_EQ_484(...) \, +#define Z_IS_484_EQ_484U(...) \, +#define Z_IS_484U_EQ_484U(...) \, +#define Z_IS_485_EQ_485(...) \, +#define Z_IS_485U_EQ_485(...) \, +#define Z_IS_485_EQ_485U(...) \, +#define Z_IS_485U_EQ_485U(...) \, +#define Z_IS_486_EQ_486(...) \, +#define Z_IS_486U_EQ_486(...) \, +#define Z_IS_486_EQ_486U(...) \, +#define Z_IS_486U_EQ_486U(...) \, +#define Z_IS_487_EQ_487(...) \, +#define Z_IS_487U_EQ_487(...) \, +#define Z_IS_487_EQ_487U(...) \, +#define Z_IS_487U_EQ_487U(...) \, +#define Z_IS_488_EQ_488(...) \, +#define Z_IS_488U_EQ_488(...) \, +#define Z_IS_488_EQ_488U(...) \, +#define Z_IS_488U_EQ_488U(...) \, +#define Z_IS_489_EQ_489(...) \, +#define Z_IS_489U_EQ_489(...) \, +#define Z_IS_489_EQ_489U(...) \, +#define Z_IS_489U_EQ_489U(...) \, +#define Z_IS_490_EQ_490(...) \, +#define Z_IS_490U_EQ_490(...) \, +#define Z_IS_490_EQ_490U(...) \, +#define Z_IS_490U_EQ_490U(...) \, +#define Z_IS_491_EQ_491(...) \, +#define Z_IS_491U_EQ_491(...) \, +#define Z_IS_491_EQ_491U(...) \, +#define Z_IS_491U_EQ_491U(...) \, +#define Z_IS_492_EQ_492(...) \, +#define Z_IS_492U_EQ_492(...) \, +#define Z_IS_492_EQ_492U(...) \, +#define Z_IS_492U_EQ_492U(...) \, +#define Z_IS_493_EQ_493(...) \, +#define Z_IS_493U_EQ_493(...) \, +#define Z_IS_493_EQ_493U(...) \, +#define Z_IS_493U_EQ_493U(...) \, +#define Z_IS_494_EQ_494(...) \, +#define Z_IS_494U_EQ_494(...) \, +#define Z_IS_494_EQ_494U(...) \, +#define Z_IS_494U_EQ_494U(...) \, +#define Z_IS_495_EQ_495(...) \, +#define Z_IS_495U_EQ_495(...) \, +#define Z_IS_495_EQ_495U(...) \, +#define Z_IS_495U_EQ_495U(...) \, +#define Z_IS_496_EQ_496(...) \, +#define Z_IS_496U_EQ_496(...) \, +#define Z_IS_496_EQ_496U(...) \, +#define Z_IS_496U_EQ_496U(...) \, +#define Z_IS_497_EQ_497(...) \, +#define Z_IS_497U_EQ_497(...) \, +#define Z_IS_497_EQ_497U(...) \, +#define Z_IS_497U_EQ_497U(...) \, +#define Z_IS_498_EQ_498(...) \, +#define Z_IS_498U_EQ_498(...) \, +#define Z_IS_498_EQ_498U(...) \, +#define Z_IS_498U_EQ_498U(...) \, +#define Z_IS_499_EQ_499(...) \, +#define Z_IS_499U_EQ_499(...) \, +#define Z_IS_499_EQ_499U(...) \, +#define Z_IS_499U_EQ_499U(...) \, +#define Z_IS_500_EQ_500(...) \, +#define Z_IS_500U_EQ_500(...) \, +#define Z_IS_500_EQ_500U(...) \, +#define Z_IS_500U_EQ_500U(...) \, +#define Z_IS_501_EQ_501(...) \, +#define Z_IS_501U_EQ_501(...) \, +#define Z_IS_501_EQ_501U(...) \, +#define Z_IS_501U_EQ_501U(...) \, +#define Z_IS_502_EQ_502(...) \, +#define Z_IS_502U_EQ_502(...) \, +#define Z_IS_502_EQ_502U(...) \, +#define Z_IS_502U_EQ_502U(...) \, +#define Z_IS_503_EQ_503(...) \, +#define Z_IS_503U_EQ_503(...) \, +#define Z_IS_503_EQ_503U(...) \, +#define Z_IS_503U_EQ_503U(...) \, +#define Z_IS_504_EQ_504(...) \, +#define Z_IS_504U_EQ_504(...) \, +#define Z_IS_504_EQ_504U(...) \, +#define Z_IS_504U_EQ_504U(...) \, +#define Z_IS_505_EQ_505(...) \, +#define Z_IS_505U_EQ_505(...) \, +#define Z_IS_505_EQ_505U(...) \, +#define Z_IS_505U_EQ_505U(...) \, +#define Z_IS_506_EQ_506(...) \, +#define Z_IS_506U_EQ_506(...) \, +#define Z_IS_506_EQ_506U(...) \, +#define Z_IS_506U_EQ_506U(...) \, +#define Z_IS_507_EQ_507(...) \, +#define Z_IS_507U_EQ_507(...) \, +#define Z_IS_507_EQ_507U(...) \, +#define Z_IS_507U_EQ_507U(...) \, +#define Z_IS_508_EQ_508(...) \, +#define Z_IS_508U_EQ_508(...) \, +#define Z_IS_508_EQ_508U(...) \, +#define Z_IS_508U_EQ_508U(...) \, +#define Z_IS_509_EQ_509(...) \, +#define Z_IS_509U_EQ_509(...) \, +#define Z_IS_509_EQ_509U(...) \, +#define Z_IS_509U_EQ_509U(...) \, +#define Z_IS_510_EQ_510(...) \, +#define Z_IS_510U_EQ_510(...) \, +#define Z_IS_510_EQ_510U(...) \, +#define Z_IS_510U_EQ_510U(...) \, +#define Z_IS_511_EQ_511(...) \, +#define Z_IS_511U_EQ_511(...) \, +#define Z_IS_511_EQ_511U(...) \, +#define Z_IS_511U_EQ_511U(...) \, +#define Z_IS_512_EQ_512(...) \, +#define Z_IS_512U_EQ_512(...) \, +#define Z_IS_512_EQ_512U(...) \, +#define Z_IS_512U_EQ_512U(...) \, +#define Z_IS_513_EQ_513(...) \, +#define Z_IS_513U_EQ_513(...) \, +#define Z_IS_513_EQ_513U(...) \, +#define Z_IS_513U_EQ_513U(...) \, +#define Z_IS_514_EQ_514(...) \, +#define Z_IS_514U_EQ_514(...) \, +#define Z_IS_514_EQ_514U(...) \, +#define Z_IS_514U_EQ_514U(...) \, +#define Z_IS_515_EQ_515(...) \, +#define Z_IS_515U_EQ_515(...) \, +#define Z_IS_515_EQ_515U(...) \, +#define Z_IS_515U_EQ_515U(...) \, +#define Z_IS_516_EQ_516(...) \, +#define Z_IS_516U_EQ_516(...) \, +#define Z_IS_516_EQ_516U(...) \, +#define Z_IS_516U_EQ_516U(...) \, +#define Z_IS_517_EQ_517(...) \, +#define Z_IS_517U_EQ_517(...) \, +#define Z_IS_517_EQ_517U(...) \, +#define Z_IS_517U_EQ_517U(...) \, +#define Z_IS_518_EQ_518(...) \, +#define Z_IS_518U_EQ_518(...) \, +#define Z_IS_518_EQ_518U(...) \, +#define Z_IS_518U_EQ_518U(...) \, +#define Z_IS_519_EQ_519(...) \, +#define Z_IS_519U_EQ_519(...) \, +#define Z_IS_519_EQ_519U(...) \, +#define Z_IS_519U_EQ_519U(...) \, +#define Z_IS_520_EQ_520(...) \, +#define Z_IS_520U_EQ_520(...) \, +#define Z_IS_520_EQ_520U(...) \, +#define Z_IS_520U_EQ_520U(...) \, +#define Z_IS_521_EQ_521(...) \, +#define Z_IS_521U_EQ_521(...) \, +#define Z_IS_521_EQ_521U(...) \, +#define Z_IS_521U_EQ_521U(...) \, +#define Z_IS_522_EQ_522(...) \, +#define Z_IS_522U_EQ_522(...) \, +#define Z_IS_522_EQ_522U(...) \, +#define Z_IS_522U_EQ_522U(...) \, +#define Z_IS_523_EQ_523(...) \, +#define Z_IS_523U_EQ_523(...) \, +#define Z_IS_523_EQ_523U(...) \, +#define Z_IS_523U_EQ_523U(...) \, +#define Z_IS_524_EQ_524(...) \, +#define Z_IS_524U_EQ_524(...) \, +#define Z_IS_524_EQ_524U(...) \, +#define Z_IS_524U_EQ_524U(...) \, +#define Z_IS_525_EQ_525(...) \, +#define Z_IS_525U_EQ_525(...) \, +#define Z_IS_525_EQ_525U(...) \, +#define Z_IS_525U_EQ_525U(...) \, +#define Z_IS_526_EQ_526(...) \, +#define Z_IS_526U_EQ_526(...) \, +#define Z_IS_526_EQ_526U(...) \, +#define Z_IS_526U_EQ_526U(...) \, +#define Z_IS_527_EQ_527(...) \, +#define Z_IS_527U_EQ_527(...) \, +#define Z_IS_527_EQ_527U(...) \, +#define Z_IS_527U_EQ_527U(...) \, +#define Z_IS_528_EQ_528(...) \, +#define Z_IS_528U_EQ_528(...) \, +#define Z_IS_528_EQ_528U(...) \, +#define Z_IS_528U_EQ_528U(...) \, +#define Z_IS_529_EQ_529(...) \, +#define Z_IS_529U_EQ_529(...) \, +#define Z_IS_529_EQ_529U(...) \, +#define Z_IS_529U_EQ_529U(...) \, +#define Z_IS_530_EQ_530(...) \, +#define Z_IS_530U_EQ_530(...) \, +#define Z_IS_530_EQ_530U(...) \, +#define Z_IS_530U_EQ_530U(...) \, +#define Z_IS_531_EQ_531(...) \, +#define Z_IS_531U_EQ_531(...) \, +#define Z_IS_531_EQ_531U(...) \, +#define Z_IS_531U_EQ_531U(...) \, +#define Z_IS_532_EQ_532(...) \, +#define Z_IS_532U_EQ_532(...) \, +#define Z_IS_532_EQ_532U(...) \, +#define Z_IS_532U_EQ_532U(...) \, +#define Z_IS_533_EQ_533(...) \, +#define Z_IS_533U_EQ_533(...) \, +#define Z_IS_533_EQ_533U(...) \, +#define Z_IS_533U_EQ_533U(...) \, +#define Z_IS_534_EQ_534(...) \, +#define Z_IS_534U_EQ_534(...) \, +#define Z_IS_534_EQ_534U(...) \, +#define Z_IS_534U_EQ_534U(...) \, +#define Z_IS_535_EQ_535(...) \, +#define Z_IS_535U_EQ_535(...) \, +#define Z_IS_535_EQ_535U(...) \, +#define Z_IS_535U_EQ_535U(...) \, +#define Z_IS_536_EQ_536(...) \, +#define Z_IS_536U_EQ_536(...) \, +#define Z_IS_536_EQ_536U(...) \, +#define Z_IS_536U_EQ_536U(...) \, +#define Z_IS_537_EQ_537(...) \, +#define Z_IS_537U_EQ_537(...) \, +#define Z_IS_537_EQ_537U(...) \, +#define Z_IS_537U_EQ_537U(...) \, +#define Z_IS_538_EQ_538(...) \, +#define Z_IS_538U_EQ_538(...) \, +#define Z_IS_538_EQ_538U(...) \, +#define Z_IS_538U_EQ_538U(...) \, +#define Z_IS_539_EQ_539(...) \, +#define Z_IS_539U_EQ_539(...) \, +#define Z_IS_539_EQ_539U(...) \, +#define Z_IS_539U_EQ_539U(...) \, +#define Z_IS_540_EQ_540(...) \, +#define Z_IS_540U_EQ_540(...) \, +#define Z_IS_540_EQ_540U(...) \, +#define Z_IS_540U_EQ_540U(...) \, +#define Z_IS_541_EQ_541(...) \, +#define Z_IS_541U_EQ_541(...) \, +#define Z_IS_541_EQ_541U(...) \, +#define Z_IS_541U_EQ_541U(...) \, +#define Z_IS_542_EQ_542(...) \, +#define Z_IS_542U_EQ_542(...) \, +#define Z_IS_542_EQ_542U(...) \, +#define Z_IS_542U_EQ_542U(...) \, +#define Z_IS_543_EQ_543(...) \, +#define Z_IS_543U_EQ_543(...) \, +#define Z_IS_543_EQ_543U(...) \, +#define Z_IS_543U_EQ_543U(...) \, +#define Z_IS_544_EQ_544(...) \, +#define Z_IS_544U_EQ_544(...) \, +#define Z_IS_544_EQ_544U(...) \, +#define Z_IS_544U_EQ_544U(...) \, +#define Z_IS_545_EQ_545(...) \, +#define Z_IS_545U_EQ_545(...) \, +#define Z_IS_545_EQ_545U(...) \, +#define Z_IS_545U_EQ_545U(...) \, +#define Z_IS_546_EQ_546(...) \, +#define Z_IS_546U_EQ_546(...) \, +#define Z_IS_546_EQ_546U(...) \, +#define Z_IS_546U_EQ_546U(...) \, +#define Z_IS_547_EQ_547(...) \, +#define Z_IS_547U_EQ_547(...) \, +#define Z_IS_547_EQ_547U(...) \, +#define Z_IS_547U_EQ_547U(...) \, +#define Z_IS_548_EQ_548(...) \, +#define Z_IS_548U_EQ_548(...) \, +#define Z_IS_548_EQ_548U(...) \, +#define Z_IS_548U_EQ_548U(...) \, +#define Z_IS_549_EQ_549(...) \, +#define Z_IS_549U_EQ_549(...) \, +#define Z_IS_549_EQ_549U(...) \, +#define Z_IS_549U_EQ_549U(...) \, +#define Z_IS_550_EQ_550(...) \, +#define Z_IS_550U_EQ_550(...) \, +#define Z_IS_550_EQ_550U(...) \, +#define Z_IS_550U_EQ_550U(...) \, +#define Z_IS_551_EQ_551(...) \, +#define Z_IS_551U_EQ_551(...) \, +#define Z_IS_551_EQ_551U(...) \, +#define Z_IS_551U_EQ_551U(...) \, +#define Z_IS_552_EQ_552(...) \, +#define Z_IS_552U_EQ_552(...) \, +#define Z_IS_552_EQ_552U(...) \, +#define Z_IS_552U_EQ_552U(...) \, +#define Z_IS_553_EQ_553(...) \, +#define Z_IS_553U_EQ_553(...) \, +#define Z_IS_553_EQ_553U(...) \, +#define Z_IS_553U_EQ_553U(...) \, +#define Z_IS_554_EQ_554(...) \, +#define Z_IS_554U_EQ_554(...) \, +#define Z_IS_554_EQ_554U(...) \, +#define Z_IS_554U_EQ_554U(...) \, +#define Z_IS_555_EQ_555(...) \, +#define Z_IS_555U_EQ_555(...) \, +#define Z_IS_555_EQ_555U(...) \, +#define Z_IS_555U_EQ_555U(...) \, +#define Z_IS_556_EQ_556(...) \, +#define Z_IS_556U_EQ_556(...) \, +#define Z_IS_556_EQ_556U(...) \, +#define Z_IS_556U_EQ_556U(...) \, +#define Z_IS_557_EQ_557(...) \, +#define Z_IS_557U_EQ_557(...) \, +#define Z_IS_557_EQ_557U(...) \, +#define Z_IS_557U_EQ_557U(...) \, +#define Z_IS_558_EQ_558(...) \, +#define Z_IS_558U_EQ_558(...) \, +#define Z_IS_558_EQ_558U(...) \, +#define Z_IS_558U_EQ_558U(...) \, +#define Z_IS_559_EQ_559(...) \, +#define Z_IS_559U_EQ_559(...) \, +#define Z_IS_559_EQ_559U(...) \, +#define Z_IS_559U_EQ_559U(...) \, +#define Z_IS_560_EQ_560(...) \, +#define Z_IS_560U_EQ_560(...) \, +#define Z_IS_560_EQ_560U(...) \, +#define Z_IS_560U_EQ_560U(...) \, +#define Z_IS_561_EQ_561(...) \, +#define Z_IS_561U_EQ_561(...) \, +#define Z_IS_561_EQ_561U(...) \, +#define Z_IS_561U_EQ_561U(...) \, +#define Z_IS_562_EQ_562(...) \, +#define Z_IS_562U_EQ_562(...) \, +#define Z_IS_562_EQ_562U(...) \, +#define Z_IS_562U_EQ_562U(...) \, +#define Z_IS_563_EQ_563(...) \, +#define Z_IS_563U_EQ_563(...) \, +#define Z_IS_563_EQ_563U(...) \, +#define Z_IS_563U_EQ_563U(...) \, +#define Z_IS_564_EQ_564(...) \, +#define Z_IS_564U_EQ_564(...) \, +#define Z_IS_564_EQ_564U(...) \, +#define Z_IS_564U_EQ_564U(...) \, +#define Z_IS_565_EQ_565(...) \, +#define Z_IS_565U_EQ_565(...) \, +#define Z_IS_565_EQ_565U(...) \, +#define Z_IS_565U_EQ_565U(...) \, +#define Z_IS_566_EQ_566(...) \, +#define Z_IS_566U_EQ_566(...) \, +#define Z_IS_566_EQ_566U(...) \, +#define Z_IS_566U_EQ_566U(...) \, +#define Z_IS_567_EQ_567(...) \, +#define Z_IS_567U_EQ_567(...) \, +#define Z_IS_567_EQ_567U(...) \, +#define Z_IS_567U_EQ_567U(...) \, +#define Z_IS_568_EQ_568(...) \, +#define Z_IS_568U_EQ_568(...) \, +#define Z_IS_568_EQ_568U(...) \, +#define Z_IS_568U_EQ_568U(...) \, +#define Z_IS_569_EQ_569(...) \, +#define Z_IS_569U_EQ_569(...) \, +#define Z_IS_569_EQ_569U(...) \, +#define Z_IS_569U_EQ_569U(...) \, +#define Z_IS_570_EQ_570(...) \, +#define Z_IS_570U_EQ_570(...) \, +#define Z_IS_570_EQ_570U(...) \, +#define Z_IS_570U_EQ_570U(...) \, +#define Z_IS_571_EQ_571(...) \, +#define Z_IS_571U_EQ_571(...) \, +#define Z_IS_571_EQ_571U(...) \, +#define Z_IS_571U_EQ_571U(...) \, +#define Z_IS_572_EQ_572(...) \, +#define Z_IS_572U_EQ_572(...) \, +#define Z_IS_572_EQ_572U(...) \, +#define Z_IS_572U_EQ_572U(...) \, +#define Z_IS_573_EQ_573(...) \, +#define Z_IS_573U_EQ_573(...) \, +#define Z_IS_573_EQ_573U(...) \, +#define Z_IS_573U_EQ_573U(...) \, +#define Z_IS_574_EQ_574(...) \, +#define Z_IS_574U_EQ_574(...) \, +#define Z_IS_574_EQ_574U(...) \, +#define Z_IS_574U_EQ_574U(...) \, +#define Z_IS_575_EQ_575(...) \, +#define Z_IS_575U_EQ_575(...) \, +#define Z_IS_575_EQ_575U(...) \, +#define Z_IS_575U_EQ_575U(...) \, +#define Z_IS_576_EQ_576(...) \, +#define Z_IS_576U_EQ_576(...) \, +#define Z_IS_576_EQ_576U(...) \, +#define Z_IS_576U_EQ_576U(...) \, +#define Z_IS_577_EQ_577(...) \, +#define Z_IS_577U_EQ_577(...) \, +#define Z_IS_577_EQ_577U(...) \, +#define Z_IS_577U_EQ_577U(...) \, +#define Z_IS_578_EQ_578(...) \, +#define Z_IS_578U_EQ_578(...) \, +#define Z_IS_578_EQ_578U(...) \, +#define Z_IS_578U_EQ_578U(...) \, +#define Z_IS_579_EQ_579(...) \, +#define Z_IS_579U_EQ_579(...) \, +#define Z_IS_579_EQ_579U(...) \, +#define Z_IS_579U_EQ_579U(...) \, +#define Z_IS_580_EQ_580(...) \, +#define Z_IS_580U_EQ_580(...) \, +#define Z_IS_580_EQ_580U(...) \, +#define Z_IS_580U_EQ_580U(...) \, +#define Z_IS_581_EQ_581(...) \, +#define Z_IS_581U_EQ_581(...) \, +#define Z_IS_581_EQ_581U(...) \, +#define Z_IS_581U_EQ_581U(...) \, +#define Z_IS_582_EQ_582(...) \, +#define Z_IS_582U_EQ_582(...) \, +#define Z_IS_582_EQ_582U(...) \, +#define Z_IS_582U_EQ_582U(...) \, +#define Z_IS_583_EQ_583(...) \, +#define Z_IS_583U_EQ_583(...) \, +#define Z_IS_583_EQ_583U(...) \, +#define Z_IS_583U_EQ_583U(...) \, +#define Z_IS_584_EQ_584(...) \, +#define Z_IS_584U_EQ_584(...) \, +#define Z_IS_584_EQ_584U(...) \, +#define Z_IS_584U_EQ_584U(...) \, +#define Z_IS_585_EQ_585(...) \, +#define Z_IS_585U_EQ_585(...) \, +#define Z_IS_585_EQ_585U(...) \, +#define Z_IS_585U_EQ_585U(...) \, +#define Z_IS_586_EQ_586(...) \, +#define Z_IS_586U_EQ_586(...) \, +#define Z_IS_586_EQ_586U(...) \, +#define Z_IS_586U_EQ_586U(...) \, +#define Z_IS_587_EQ_587(...) \, +#define Z_IS_587U_EQ_587(...) \, +#define Z_IS_587_EQ_587U(...) \, +#define Z_IS_587U_EQ_587U(...) \, +#define Z_IS_588_EQ_588(...) \, +#define Z_IS_588U_EQ_588(...) \, +#define Z_IS_588_EQ_588U(...) \, +#define Z_IS_588U_EQ_588U(...) \, +#define Z_IS_589_EQ_589(...) \, +#define Z_IS_589U_EQ_589(...) \, +#define Z_IS_589_EQ_589U(...) \, +#define Z_IS_589U_EQ_589U(...) \, +#define Z_IS_590_EQ_590(...) \, +#define Z_IS_590U_EQ_590(...) \, +#define Z_IS_590_EQ_590U(...) \, +#define Z_IS_590U_EQ_590U(...) \, +#define Z_IS_591_EQ_591(...) \, +#define Z_IS_591U_EQ_591(...) \, +#define Z_IS_591_EQ_591U(...) \, +#define Z_IS_591U_EQ_591U(...) \, +#define Z_IS_592_EQ_592(...) \, +#define Z_IS_592U_EQ_592(...) \, +#define Z_IS_592_EQ_592U(...) \, +#define Z_IS_592U_EQ_592U(...) \, +#define Z_IS_593_EQ_593(...) \, +#define Z_IS_593U_EQ_593(...) \, +#define Z_IS_593_EQ_593U(...) \, +#define Z_IS_593U_EQ_593U(...) \, +#define Z_IS_594_EQ_594(...) \, +#define Z_IS_594U_EQ_594(...) \, +#define Z_IS_594_EQ_594U(...) \, +#define Z_IS_594U_EQ_594U(...) \, +#define Z_IS_595_EQ_595(...) \, +#define Z_IS_595U_EQ_595(...) \, +#define Z_IS_595_EQ_595U(...) \, +#define Z_IS_595U_EQ_595U(...) \, +#define Z_IS_596_EQ_596(...) \, +#define Z_IS_596U_EQ_596(...) \, +#define Z_IS_596_EQ_596U(...) \, +#define Z_IS_596U_EQ_596U(...) \, +#define Z_IS_597_EQ_597(...) \, +#define Z_IS_597U_EQ_597(...) \, +#define Z_IS_597_EQ_597U(...) \, +#define Z_IS_597U_EQ_597U(...) \, +#define Z_IS_598_EQ_598(...) \, +#define Z_IS_598U_EQ_598(...) \, +#define Z_IS_598_EQ_598U(...) \, +#define Z_IS_598U_EQ_598U(...) \, +#define Z_IS_599_EQ_599(...) \, +#define Z_IS_599U_EQ_599(...) \, +#define Z_IS_599_EQ_599U(...) \, +#define Z_IS_599U_EQ_599U(...) \, +#define Z_IS_600_EQ_600(...) \, +#define Z_IS_600U_EQ_600(...) \, +#define Z_IS_600_EQ_600U(...) \, +#define Z_IS_600U_EQ_600U(...) \, +#define Z_IS_601_EQ_601(...) \, +#define Z_IS_601U_EQ_601(...) \, +#define Z_IS_601_EQ_601U(...) \, +#define Z_IS_601U_EQ_601U(...) \, +#define Z_IS_602_EQ_602(...) \, +#define Z_IS_602U_EQ_602(...) \, +#define Z_IS_602_EQ_602U(...) \, +#define Z_IS_602U_EQ_602U(...) \, +#define Z_IS_603_EQ_603(...) \, +#define Z_IS_603U_EQ_603(...) \, +#define Z_IS_603_EQ_603U(...) \, +#define Z_IS_603U_EQ_603U(...) \, +#define Z_IS_604_EQ_604(...) \, +#define Z_IS_604U_EQ_604(...) \, +#define Z_IS_604_EQ_604U(...) \, +#define Z_IS_604U_EQ_604U(...) \, +#define Z_IS_605_EQ_605(...) \, +#define Z_IS_605U_EQ_605(...) \, +#define Z_IS_605_EQ_605U(...) \, +#define Z_IS_605U_EQ_605U(...) \, +#define Z_IS_606_EQ_606(...) \, +#define Z_IS_606U_EQ_606(...) \, +#define Z_IS_606_EQ_606U(...) \, +#define Z_IS_606U_EQ_606U(...) \, +#define Z_IS_607_EQ_607(...) \, +#define Z_IS_607U_EQ_607(...) \, +#define Z_IS_607_EQ_607U(...) \, +#define Z_IS_607U_EQ_607U(...) \, +#define Z_IS_608_EQ_608(...) \, +#define Z_IS_608U_EQ_608(...) \, +#define Z_IS_608_EQ_608U(...) \, +#define Z_IS_608U_EQ_608U(...) \, +#define Z_IS_609_EQ_609(...) \, +#define Z_IS_609U_EQ_609(...) \, +#define Z_IS_609_EQ_609U(...) \, +#define Z_IS_609U_EQ_609U(...) \, +#define Z_IS_610_EQ_610(...) \, +#define Z_IS_610U_EQ_610(...) \, +#define Z_IS_610_EQ_610U(...) \, +#define Z_IS_610U_EQ_610U(...) \, +#define Z_IS_611_EQ_611(...) \, +#define Z_IS_611U_EQ_611(...) \, +#define Z_IS_611_EQ_611U(...) \, +#define Z_IS_611U_EQ_611U(...) \, +#define Z_IS_612_EQ_612(...) \, +#define Z_IS_612U_EQ_612(...) \, +#define Z_IS_612_EQ_612U(...) \, +#define Z_IS_612U_EQ_612U(...) \, +#define Z_IS_613_EQ_613(...) \, +#define Z_IS_613U_EQ_613(...) \, +#define Z_IS_613_EQ_613U(...) \, +#define Z_IS_613U_EQ_613U(...) \, +#define Z_IS_614_EQ_614(...) \, +#define Z_IS_614U_EQ_614(...) \, +#define Z_IS_614_EQ_614U(...) \, +#define Z_IS_614U_EQ_614U(...) \, +#define Z_IS_615_EQ_615(...) \, +#define Z_IS_615U_EQ_615(...) \, +#define Z_IS_615_EQ_615U(...) \, +#define Z_IS_615U_EQ_615U(...) \, +#define Z_IS_616_EQ_616(...) \, +#define Z_IS_616U_EQ_616(...) \, +#define Z_IS_616_EQ_616U(...) \, +#define Z_IS_616U_EQ_616U(...) \, +#define Z_IS_617_EQ_617(...) \, +#define Z_IS_617U_EQ_617(...) \, +#define Z_IS_617_EQ_617U(...) \, +#define Z_IS_617U_EQ_617U(...) \, +#define Z_IS_618_EQ_618(...) \, +#define Z_IS_618U_EQ_618(...) \, +#define Z_IS_618_EQ_618U(...) \, +#define Z_IS_618U_EQ_618U(...) \, +#define Z_IS_619_EQ_619(...) \, +#define Z_IS_619U_EQ_619(...) \, +#define Z_IS_619_EQ_619U(...) \, +#define Z_IS_619U_EQ_619U(...) \, +#define Z_IS_620_EQ_620(...) \, +#define Z_IS_620U_EQ_620(...) \, +#define Z_IS_620_EQ_620U(...) \, +#define Z_IS_620U_EQ_620U(...) \, +#define Z_IS_621_EQ_621(...) \, +#define Z_IS_621U_EQ_621(...) \, +#define Z_IS_621_EQ_621U(...) \, +#define Z_IS_621U_EQ_621U(...) \, +#define Z_IS_622_EQ_622(...) \, +#define Z_IS_622U_EQ_622(...) \, +#define Z_IS_622_EQ_622U(...) \, +#define Z_IS_622U_EQ_622U(...) \, +#define Z_IS_623_EQ_623(...) \, +#define Z_IS_623U_EQ_623(...) \, +#define Z_IS_623_EQ_623U(...) \, +#define Z_IS_623U_EQ_623U(...) \, +#define Z_IS_624_EQ_624(...) \, +#define Z_IS_624U_EQ_624(...) \, +#define Z_IS_624_EQ_624U(...) \, +#define Z_IS_624U_EQ_624U(...) \, +#define Z_IS_625_EQ_625(...) \, +#define Z_IS_625U_EQ_625(...) \, +#define Z_IS_625_EQ_625U(...) \, +#define Z_IS_625U_EQ_625U(...) \, +#define Z_IS_626_EQ_626(...) \, +#define Z_IS_626U_EQ_626(...) \, +#define Z_IS_626_EQ_626U(...) \, +#define Z_IS_626U_EQ_626U(...) \, +#define Z_IS_627_EQ_627(...) \, +#define Z_IS_627U_EQ_627(...) \, +#define Z_IS_627_EQ_627U(...) \, +#define Z_IS_627U_EQ_627U(...) \, +#define Z_IS_628_EQ_628(...) \, +#define Z_IS_628U_EQ_628(...) \, +#define Z_IS_628_EQ_628U(...) \, +#define Z_IS_628U_EQ_628U(...) \, +#define Z_IS_629_EQ_629(...) \, +#define Z_IS_629U_EQ_629(...) \, +#define Z_IS_629_EQ_629U(...) \, +#define Z_IS_629U_EQ_629U(...) \, +#define Z_IS_630_EQ_630(...) \, +#define Z_IS_630U_EQ_630(...) \, +#define Z_IS_630_EQ_630U(...) \, +#define Z_IS_630U_EQ_630U(...) \, +#define Z_IS_631_EQ_631(...) \, +#define Z_IS_631U_EQ_631(...) \, +#define Z_IS_631_EQ_631U(...) \, +#define Z_IS_631U_EQ_631U(...) \, +#define Z_IS_632_EQ_632(...) \, +#define Z_IS_632U_EQ_632(...) \, +#define Z_IS_632_EQ_632U(...) \, +#define Z_IS_632U_EQ_632U(...) \, +#define Z_IS_633_EQ_633(...) \, +#define Z_IS_633U_EQ_633(...) \, +#define Z_IS_633_EQ_633U(...) \, +#define Z_IS_633U_EQ_633U(...) \, +#define Z_IS_634_EQ_634(...) \, +#define Z_IS_634U_EQ_634(...) \, +#define Z_IS_634_EQ_634U(...) \, +#define Z_IS_634U_EQ_634U(...) \, +#define Z_IS_635_EQ_635(...) \, +#define Z_IS_635U_EQ_635(...) \, +#define Z_IS_635_EQ_635U(...) \, +#define Z_IS_635U_EQ_635U(...) \, +#define Z_IS_636_EQ_636(...) \, +#define Z_IS_636U_EQ_636(...) \, +#define Z_IS_636_EQ_636U(...) \, +#define Z_IS_636U_EQ_636U(...) \, +#define Z_IS_637_EQ_637(...) \, +#define Z_IS_637U_EQ_637(...) \, +#define Z_IS_637_EQ_637U(...) \, +#define Z_IS_637U_EQ_637U(...) \, +#define Z_IS_638_EQ_638(...) \, +#define Z_IS_638U_EQ_638(...) \, +#define Z_IS_638_EQ_638U(...) \, +#define Z_IS_638U_EQ_638U(...) \, +#define Z_IS_639_EQ_639(...) \, +#define Z_IS_639U_EQ_639(...) \, +#define Z_IS_639_EQ_639U(...) \, +#define Z_IS_639U_EQ_639U(...) \, +#define Z_IS_640_EQ_640(...) \, +#define Z_IS_640U_EQ_640(...) \, +#define Z_IS_640_EQ_640U(...) \, +#define Z_IS_640U_EQ_640U(...) \, +#define Z_IS_641_EQ_641(...) \, +#define Z_IS_641U_EQ_641(...) \, +#define Z_IS_641_EQ_641U(...) \, +#define Z_IS_641U_EQ_641U(...) \, +#define Z_IS_642_EQ_642(...) \, +#define Z_IS_642U_EQ_642(...) \, +#define Z_IS_642_EQ_642U(...) \, +#define Z_IS_642U_EQ_642U(...) \, +#define Z_IS_643_EQ_643(...) \, +#define Z_IS_643U_EQ_643(...) \, +#define Z_IS_643_EQ_643U(...) \, +#define Z_IS_643U_EQ_643U(...) \, +#define Z_IS_644_EQ_644(...) \, +#define Z_IS_644U_EQ_644(...) \, +#define Z_IS_644_EQ_644U(...) \, +#define Z_IS_644U_EQ_644U(...) \, +#define Z_IS_645_EQ_645(...) \, +#define Z_IS_645U_EQ_645(...) \, +#define Z_IS_645_EQ_645U(...) \, +#define Z_IS_645U_EQ_645U(...) \, +#define Z_IS_646_EQ_646(...) \, +#define Z_IS_646U_EQ_646(...) \, +#define Z_IS_646_EQ_646U(...) \, +#define Z_IS_646U_EQ_646U(...) \, +#define Z_IS_647_EQ_647(...) \, +#define Z_IS_647U_EQ_647(...) \, +#define Z_IS_647_EQ_647U(...) \, +#define Z_IS_647U_EQ_647U(...) \, +#define Z_IS_648_EQ_648(...) \, +#define Z_IS_648U_EQ_648(...) \, +#define Z_IS_648_EQ_648U(...) \, +#define Z_IS_648U_EQ_648U(...) \, +#define Z_IS_649_EQ_649(...) \, +#define Z_IS_649U_EQ_649(...) \, +#define Z_IS_649_EQ_649U(...) \, +#define Z_IS_649U_EQ_649U(...) \, +#define Z_IS_650_EQ_650(...) \, +#define Z_IS_650U_EQ_650(...) \, +#define Z_IS_650_EQ_650U(...) \, +#define Z_IS_650U_EQ_650U(...) \, +#define Z_IS_651_EQ_651(...) \, +#define Z_IS_651U_EQ_651(...) \, +#define Z_IS_651_EQ_651U(...) \, +#define Z_IS_651U_EQ_651U(...) \, +#define Z_IS_652_EQ_652(...) \, +#define Z_IS_652U_EQ_652(...) \, +#define Z_IS_652_EQ_652U(...) \, +#define Z_IS_652U_EQ_652U(...) \, +#define Z_IS_653_EQ_653(...) \, +#define Z_IS_653U_EQ_653(...) \, +#define Z_IS_653_EQ_653U(...) \, +#define Z_IS_653U_EQ_653U(...) \, +#define Z_IS_654_EQ_654(...) \, +#define Z_IS_654U_EQ_654(...) \, +#define Z_IS_654_EQ_654U(...) \, +#define Z_IS_654U_EQ_654U(...) \, +#define Z_IS_655_EQ_655(...) \, +#define Z_IS_655U_EQ_655(...) \, +#define Z_IS_655_EQ_655U(...) \, +#define Z_IS_655U_EQ_655U(...) \, +#define Z_IS_656_EQ_656(...) \, +#define Z_IS_656U_EQ_656(...) \, +#define Z_IS_656_EQ_656U(...) \, +#define Z_IS_656U_EQ_656U(...) \, +#define Z_IS_657_EQ_657(...) \, +#define Z_IS_657U_EQ_657(...) \, +#define Z_IS_657_EQ_657U(...) \, +#define Z_IS_657U_EQ_657U(...) \, +#define Z_IS_658_EQ_658(...) \, +#define Z_IS_658U_EQ_658(...) \, +#define Z_IS_658_EQ_658U(...) \, +#define Z_IS_658U_EQ_658U(...) \, +#define Z_IS_659_EQ_659(...) \, +#define Z_IS_659U_EQ_659(...) \, +#define Z_IS_659_EQ_659U(...) \, +#define Z_IS_659U_EQ_659U(...) \, +#define Z_IS_660_EQ_660(...) \, +#define Z_IS_660U_EQ_660(...) \, +#define Z_IS_660_EQ_660U(...) \, +#define Z_IS_660U_EQ_660U(...) \, +#define Z_IS_661_EQ_661(...) \, +#define Z_IS_661U_EQ_661(...) \, +#define Z_IS_661_EQ_661U(...) \, +#define Z_IS_661U_EQ_661U(...) \, +#define Z_IS_662_EQ_662(...) \, +#define Z_IS_662U_EQ_662(...) \, +#define Z_IS_662_EQ_662U(...) \, +#define Z_IS_662U_EQ_662U(...) \, +#define Z_IS_663_EQ_663(...) \, +#define Z_IS_663U_EQ_663(...) \, +#define Z_IS_663_EQ_663U(...) \, +#define Z_IS_663U_EQ_663U(...) \, +#define Z_IS_664_EQ_664(...) \, +#define Z_IS_664U_EQ_664(...) \, +#define Z_IS_664_EQ_664U(...) \, +#define Z_IS_664U_EQ_664U(...) \, +#define Z_IS_665_EQ_665(...) \, +#define Z_IS_665U_EQ_665(...) \, +#define Z_IS_665_EQ_665U(...) \, +#define Z_IS_665U_EQ_665U(...) \, +#define Z_IS_666_EQ_666(...) \, +#define Z_IS_666U_EQ_666(...) \, +#define Z_IS_666_EQ_666U(...) \, +#define Z_IS_666U_EQ_666U(...) \, +#define Z_IS_667_EQ_667(...) \, +#define Z_IS_667U_EQ_667(...) \, +#define Z_IS_667_EQ_667U(...) \, +#define Z_IS_667U_EQ_667U(...) \, +#define Z_IS_668_EQ_668(...) \, +#define Z_IS_668U_EQ_668(...) \, +#define Z_IS_668_EQ_668U(...) \, +#define Z_IS_668U_EQ_668U(...) \, +#define Z_IS_669_EQ_669(...) \, +#define Z_IS_669U_EQ_669(...) \, +#define Z_IS_669_EQ_669U(...) \, +#define Z_IS_669U_EQ_669U(...) \, +#define Z_IS_670_EQ_670(...) \, +#define Z_IS_670U_EQ_670(...) \, +#define Z_IS_670_EQ_670U(...) \, +#define Z_IS_670U_EQ_670U(...) \, +#define Z_IS_671_EQ_671(...) \, +#define Z_IS_671U_EQ_671(...) \, +#define Z_IS_671_EQ_671U(...) \, +#define Z_IS_671U_EQ_671U(...) \, +#define Z_IS_672_EQ_672(...) \, +#define Z_IS_672U_EQ_672(...) \, +#define Z_IS_672_EQ_672U(...) \, +#define Z_IS_672U_EQ_672U(...) \, +#define Z_IS_673_EQ_673(...) \, +#define Z_IS_673U_EQ_673(...) \, +#define Z_IS_673_EQ_673U(...) \, +#define Z_IS_673U_EQ_673U(...) \, +#define Z_IS_674_EQ_674(...) \, +#define Z_IS_674U_EQ_674(...) \, +#define Z_IS_674_EQ_674U(...) \, +#define Z_IS_674U_EQ_674U(...) \, +#define Z_IS_675_EQ_675(...) \, +#define Z_IS_675U_EQ_675(...) \, +#define Z_IS_675_EQ_675U(...) \, +#define Z_IS_675U_EQ_675U(...) \, +#define Z_IS_676_EQ_676(...) \, +#define Z_IS_676U_EQ_676(...) \, +#define Z_IS_676_EQ_676U(...) \, +#define Z_IS_676U_EQ_676U(...) \, +#define Z_IS_677_EQ_677(...) \, +#define Z_IS_677U_EQ_677(...) \, +#define Z_IS_677_EQ_677U(...) \, +#define Z_IS_677U_EQ_677U(...) \, +#define Z_IS_678_EQ_678(...) \, +#define Z_IS_678U_EQ_678(...) \, +#define Z_IS_678_EQ_678U(...) \, +#define Z_IS_678U_EQ_678U(...) \, +#define Z_IS_679_EQ_679(...) \, +#define Z_IS_679U_EQ_679(...) \, +#define Z_IS_679_EQ_679U(...) \, +#define Z_IS_679U_EQ_679U(...) \, +#define Z_IS_680_EQ_680(...) \, +#define Z_IS_680U_EQ_680(...) \, +#define Z_IS_680_EQ_680U(...) \, +#define Z_IS_680U_EQ_680U(...) \, +#define Z_IS_681_EQ_681(...) \, +#define Z_IS_681U_EQ_681(...) \, +#define Z_IS_681_EQ_681U(...) \, +#define Z_IS_681U_EQ_681U(...) \, +#define Z_IS_682_EQ_682(...) \, +#define Z_IS_682U_EQ_682(...) \, +#define Z_IS_682_EQ_682U(...) \, +#define Z_IS_682U_EQ_682U(...) \, +#define Z_IS_683_EQ_683(...) \, +#define Z_IS_683U_EQ_683(...) \, +#define Z_IS_683_EQ_683U(...) \, +#define Z_IS_683U_EQ_683U(...) \, +#define Z_IS_684_EQ_684(...) \, +#define Z_IS_684U_EQ_684(...) \, +#define Z_IS_684_EQ_684U(...) \, +#define Z_IS_684U_EQ_684U(...) \, +#define Z_IS_685_EQ_685(...) \, +#define Z_IS_685U_EQ_685(...) \, +#define Z_IS_685_EQ_685U(...) \, +#define Z_IS_685U_EQ_685U(...) \, +#define Z_IS_686_EQ_686(...) \, +#define Z_IS_686U_EQ_686(...) \, +#define Z_IS_686_EQ_686U(...) \, +#define Z_IS_686U_EQ_686U(...) \, +#define Z_IS_687_EQ_687(...) \, +#define Z_IS_687U_EQ_687(...) \, +#define Z_IS_687_EQ_687U(...) \, +#define Z_IS_687U_EQ_687U(...) \, +#define Z_IS_688_EQ_688(...) \, +#define Z_IS_688U_EQ_688(...) \, +#define Z_IS_688_EQ_688U(...) \, +#define Z_IS_688U_EQ_688U(...) \, +#define Z_IS_689_EQ_689(...) \, +#define Z_IS_689U_EQ_689(...) \, +#define Z_IS_689_EQ_689U(...) \, +#define Z_IS_689U_EQ_689U(...) \, +#define Z_IS_690_EQ_690(...) \, +#define Z_IS_690U_EQ_690(...) \, +#define Z_IS_690_EQ_690U(...) \, +#define Z_IS_690U_EQ_690U(...) \, +#define Z_IS_691_EQ_691(...) \, +#define Z_IS_691U_EQ_691(...) \, +#define Z_IS_691_EQ_691U(...) \, +#define Z_IS_691U_EQ_691U(...) \, +#define Z_IS_692_EQ_692(...) \, +#define Z_IS_692U_EQ_692(...) \, +#define Z_IS_692_EQ_692U(...) \, +#define Z_IS_692U_EQ_692U(...) \, +#define Z_IS_693_EQ_693(...) \, +#define Z_IS_693U_EQ_693(...) \, +#define Z_IS_693_EQ_693U(...) \, +#define Z_IS_693U_EQ_693U(...) \, +#define Z_IS_694_EQ_694(...) \, +#define Z_IS_694U_EQ_694(...) \, +#define Z_IS_694_EQ_694U(...) \, +#define Z_IS_694U_EQ_694U(...) \, +#define Z_IS_695_EQ_695(...) \, +#define Z_IS_695U_EQ_695(...) \, +#define Z_IS_695_EQ_695U(...) \, +#define Z_IS_695U_EQ_695U(...) \, +#define Z_IS_696_EQ_696(...) \, +#define Z_IS_696U_EQ_696(...) \, +#define Z_IS_696_EQ_696U(...) \, +#define Z_IS_696U_EQ_696U(...) \, +#define Z_IS_697_EQ_697(...) \, +#define Z_IS_697U_EQ_697(...) \, +#define Z_IS_697_EQ_697U(...) \, +#define Z_IS_697U_EQ_697U(...) \, +#define Z_IS_698_EQ_698(...) \, +#define Z_IS_698U_EQ_698(...) \, +#define Z_IS_698_EQ_698U(...) \, +#define Z_IS_698U_EQ_698U(...) \, +#define Z_IS_699_EQ_699(...) \, +#define Z_IS_699U_EQ_699(...) \, +#define Z_IS_699_EQ_699U(...) \, +#define Z_IS_699U_EQ_699U(...) \, +#define Z_IS_700_EQ_700(...) \, +#define Z_IS_700U_EQ_700(...) \, +#define Z_IS_700_EQ_700U(...) \, +#define Z_IS_700U_EQ_700U(...) \, +#define Z_IS_701_EQ_701(...) \, +#define Z_IS_701U_EQ_701(...) \, +#define Z_IS_701_EQ_701U(...) \, +#define Z_IS_701U_EQ_701U(...) \, +#define Z_IS_702_EQ_702(...) \, +#define Z_IS_702U_EQ_702(...) \, +#define Z_IS_702_EQ_702U(...) \, +#define Z_IS_702U_EQ_702U(...) \, +#define Z_IS_703_EQ_703(...) \, +#define Z_IS_703U_EQ_703(...) \, +#define Z_IS_703_EQ_703U(...) \, +#define Z_IS_703U_EQ_703U(...) \, +#define Z_IS_704_EQ_704(...) \, +#define Z_IS_704U_EQ_704(...) \, +#define Z_IS_704_EQ_704U(...) \, +#define Z_IS_704U_EQ_704U(...) \, +#define Z_IS_705_EQ_705(...) \, +#define Z_IS_705U_EQ_705(...) \, +#define Z_IS_705_EQ_705U(...) \, +#define Z_IS_705U_EQ_705U(...) \, +#define Z_IS_706_EQ_706(...) \, +#define Z_IS_706U_EQ_706(...) \, +#define Z_IS_706_EQ_706U(...) \, +#define Z_IS_706U_EQ_706U(...) \, +#define Z_IS_707_EQ_707(...) \, +#define Z_IS_707U_EQ_707(...) \, +#define Z_IS_707_EQ_707U(...) \, +#define Z_IS_707U_EQ_707U(...) \, +#define Z_IS_708_EQ_708(...) \, +#define Z_IS_708U_EQ_708(...) \, +#define Z_IS_708_EQ_708U(...) \, +#define Z_IS_708U_EQ_708U(...) \, +#define Z_IS_709_EQ_709(...) \, +#define Z_IS_709U_EQ_709(...) \, +#define Z_IS_709_EQ_709U(...) \, +#define Z_IS_709U_EQ_709U(...) \, +#define Z_IS_710_EQ_710(...) \, +#define Z_IS_710U_EQ_710(...) \, +#define Z_IS_710_EQ_710U(...) \, +#define Z_IS_710U_EQ_710U(...) \, +#define Z_IS_711_EQ_711(...) \, +#define Z_IS_711U_EQ_711(...) \, +#define Z_IS_711_EQ_711U(...) \, +#define Z_IS_711U_EQ_711U(...) \, +#define Z_IS_712_EQ_712(...) \, +#define Z_IS_712U_EQ_712(...) \, +#define Z_IS_712_EQ_712U(...) \, +#define Z_IS_712U_EQ_712U(...) \, +#define Z_IS_713_EQ_713(...) \, +#define Z_IS_713U_EQ_713(...) \, +#define Z_IS_713_EQ_713U(...) \, +#define Z_IS_713U_EQ_713U(...) \, +#define Z_IS_714_EQ_714(...) \, +#define Z_IS_714U_EQ_714(...) \, +#define Z_IS_714_EQ_714U(...) \, +#define Z_IS_714U_EQ_714U(...) \, +#define Z_IS_715_EQ_715(...) \, +#define Z_IS_715U_EQ_715(...) \, +#define Z_IS_715_EQ_715U(...) \, +#define Z_IS_715U_EQ_715U(...) \, +#define Z_IS_716_EQ_716(...) \, +#define Z_IS_716U_EQ_716(...) \, +#define Z_IS_716_EQ_716U(...) \, +#define Z_IS_716U_EQ_716U(...) \, +#define Z_IS_717_EQ_717(...) \, +#define Z_IS_717U_EQ_717(...) \, +#define Z_IS_717_EQ_717U(...) \, +#define Z_IS_717U_EQ_717U(...) \, +#define Z_IS_718_EQ_718(...) \, +#define Z_IS_718U_EQ_718(...) \, +#define Z_IS_718_EQ_718U(...) \, +#define Z_IS_718U_EQ_718U(...) \, +#define Z_IS_719_EQ_719(...) \, +#define Z_IS_719U_EQ_719(...) \, +#define Z_IS_719_EQ_719U(...) \, +#define Z_IS_719U_EQ_719U(...) \, +#define Z_IS_720_EQ_720(...) \, +#define Z_IS_720U_EQ_720(...) \, +#define Z_IS_720_EQ_720U(...) \, +#define Z_IS_720U_EQ_720U(...) \, +#define Z_IS_721_EQ_721(...) \, +#define Z_IS_721U_EQ_721(...) \, +#define Z_IS_721_EQ_721U(...) \, +#define Z_IS_721U_EQ_721U(...) \, +#define Z_IS_722_EQ_722(...) \, +#define Z_IS_722U_EQ_722(...) \, +#define Z_IS_722_EQ_722U(...) \, +#define Z_IS_722U_EQ_722U(...) \, +#define Z_IS_723_EQ_723(...) \, +#define Z_IS_723U_EQ_723(...) \, +#define Z_IS_723_EQ_723U(...) \, +#define Z_IS_723U_EQ_723U(...) \, +#define Z_IS_724_EQ_724(...) \, +#define Z_IS_724U_EQ_724(...) \, +#define Z_IS_724_EQ_724U(...) \, +#define Z_IS_724U_EQ_724U(...) \, +#define Z_IS_725_EQ_725(...) \, +#define Z_IS_725U_EQ_725(...) \, +#define Z_IS_725_EQ_725U(...) \, +#define Z_IS_725U_EQ_725U(...) \, +#define Z_IS_726_EQ_726(...) \, +#define Z_IS_726U_EQ_726(...) \, +#define Z_IS_726_EQ_726U(...) \, +#define Z_IS_726U_EQ_726U(...) \, +#define Z_IS_727_EQ_727(...) \, +#define Z_IS_727U_EQ_727(...) \, +#define Z_IS_727_EQ_727U(...) \, +#define Z_IS_727U_EQ_727U(...) \, +#define Z_IS_728_EQ_728(...) \, +#define Z_IS_728U_EQ_728(...) \, +#define Z_IS_728_EQ_728U(...) \, +#define Z_IS_728U_EQ_728U(...) \, +#define Z_IS_729_EQ_729(...) \, +#define Z_IS_729U_EQ_729(...) \, +#define Z_IS_729_EQ_729U(...) \, +#define Z_IS_729U_EQ_729U(...) \, +#define Z_IS_730_EQ_730(...) \, +#define Z_IS_730U_EQ_730(...) \, +#define Z_IS_730_EQ_730U(...) \, +#define Z_IS_730U_EQ_730U(...) \, +#define Z_IS_731_EQ_731(...) \, +#define Z_IS_731U_EQ_731(...) \, +#define Z_IS_731_EQ_731U(...) \, +#define Z_IS_731U_EQ_731U(...) \, +#define Z_IS_732_EQ_732(...) \, +#define Z_IS_732U_EQ_732(...) \, +#define Z_IS_732_EQ_732U(...) \, +#define Z_IS_732U_EQ_732U(...) \, +#define Z_IS_733_EQ_733(...) \, +#define Z_IS_733U_EQ_733(...) \, +#define Z_IS_733_EQ_733U(...) \, +#define Z_IS_733U_EQ_733U(...) \, +#define Z_IS_734_EQ_734(...) \, +#define Z_IS_734U_EQ_734(...) \, +#define Z_IS_734_EQ_734U(...) \, +#define Z_IS_734U_EQ_734U(...) \, +#define Z_IS_735_EQ_735(...) \, +#define Z_IS_735U_EQ_735(...) \, +#define Z_IS_735_EQ_735U(...) \, +#define Z_IS_735U_EQ_735U(...) \, +#define Z_IS_736_EQ_736(...) \, +#define Z_IS_736U_EQ_736(...) \, +#define Z_IS_736_EQ_736U(...) \, +#define Z_IS_736U_EQ_736U(...) \, +#define Z_IS_737_EQ_737(...) \, +#define Z_IS_737U_EQ_737(...) \, +#define Z_IS_737_EQ_737U(...) \, +#define Z_IS_737U_EQ_737U(...) \, +#define Z_IS_738_EQ_738(...) \, +#define Z_IS_738U_EQ_738(...) \, +#define Z_IS_738_EQ_738U(...) \, +#define Z_IS_738U_EQ_738U(...) \, +#define Z_IS_739_EQ_739(...) \, +#define Z_IS_739U_EQ_739(...) \, +#define Z_IS_739_EQ_739U(...) \, +#define Z_IS_739U_EQ_739U(...) \, +#define Z_IS_740_EQ_740(...) \, +#define Z_IS_740U_EQ_740(...) \, +#define Z_IS_740_EQ_740U(...) \, +#define Z_IS_740U_EQ_740U(...) \, +#define Z_IS_741_EQ_741(...) \, +#define Z_IS_741U_EQ_741(...) \, +#define Z_IS_741_EQ_741U(...) \, +#define Z_IS_741U_EQ_741U(...) \, +#define Z_IS_742_EQ_742(...) \, +#define Z_IS_742U_EQ_742(...) \, +#define Z_IS_742_EQ_742U(...) \, +#define Z_IS_742U_EQ_742U(...) \, +#define Z_IS_743_EQ_743(...) \, +#define Z_IS_743U_EQ_743(...) \, +#define Z_IS_743_EQ_743U(...) \, +#define Z_IS_743U_EQ_743U(...) \, +#define Z_IS_744_EQ_744(...) \, +#define Z_IS_744U_EQ_744(...) \, +#define Z_IS_744_EQ_744U(...) \, +#define Z_IS_744U_EQ_744U(...) \, +#define Z_IS_745_EQ_745(...) \, +#define Z_IS_745U_EQ_745(...) \, +#define Z_IS_745_EQ_745U(...) \, +#define Z_IS_745U_EQ_745U(...) \, +#define Z_IS_746_EQ_746(...) \, +#define Z_IS_746U_EQ_746(...) \, +#define Z_IS_746_EQ_746U(...) \, +#define Z_IS_746U_EQ_746U(...) \, +#define Z_IS_747_EQ_747(...) \, +#define Z_IS_747U_EQ_747(...) \, +#define Z_IS_747_EQ_747U(...) \, +#define Z_IS_747U_EQ_747U(...) \, +#define Z_IS_748_EQ_748(...) \, +#define Z_IS_748U_EQ_748(...) \, +#define Z_IS_748_EQ_748U(...) \, +#define Z_IS_748U_EQ_748U(...) \, +#define Z_IS_749_EQ_749(...) \, +#define Z_IS_749U_EQ_749(...) \, +#define Z_IS_749_EQ_749U(...) \, +#define Z_IS_749U_EQ_749U(...) \, +#define Z_IS_750_EQ_750(...) \, +#define Z_IS_750U_EQ_750(...) \, +#define Z_IS_750_EQ_750U(...) \, +#define Z_IS_750U_EQ_750U(...) \, +#define Z_IS_751_EQ_751(...) \, +#define Z_IS_751U_EQ_751(...) \, +#define Z_IS_751_EQ_751U(...) \, +#define Z_IS_751U_EQ_751U(...) \, +#define Z_IS_752_EQ_752(...) \, +#define Z_IS_752U_EQ_752(...) \, +#define Z_IS_752_EQ_752U(...) \, +#define Z_IS_752U_EQ_752U(...) \, +#define Z_IS_753_EQ_753(...) \, +#define Z_IS_753U_EQ_753(...) \, +#define Z_IS_753_EQ_753U(...) \, +#define Z_IS_753U_EQ_753U(...) \, +#define Z_IS_754_EQ_754(...) \, +#define Z_IS_754U_EQ_754(...) \, +#define Z_IS_754_EQ_754U(...) \, +#define Z_IS_754U_EQ_754U(...) \, +#define Z_IS_755_EQ_755(...) \, +#define Z_IS_755U_EQ_755(...) \, +#define Z_IS_755_EQ_755U(...) \, +#define Z_IS_755U_EQ_755U(...) \, +#define Z_IS_756_EQ_756(...) \, +#define Z_IS_756U_EQ_756(...) \, +#define Z_IS_756_EQ_756U(...) \, +#define Z_IS_756U_EQ_756U(...) \, +#define Z_IS_757_EQ_757(...) \, +#define Z_IS_757U_EQ_757(...) \, +#define Z_IS_757_EQ_757U(...) \, +#define Z_IS_757U_EQ_757U(...) \, +#define Z_IS_758_EQ_758(...) \, +#define Z_IS_758U_EQ_758(...) \, +#define Z_IS_758_EQ_758U(...) \, +#define Z_IS_758U_EQ_758U(...) \, +#define Z_IS_759_EQ_759(...) \, +#define Z_IS_759U_EQ_759(...) \, +#define Z_IS_759_EQ_759U(...) \, +#define Z_IS_759U_EQ_759U(...) \, +#define Z_IS_760_EQ_760(...) \, +#define Z_IS_760U_EQ_760(...) \, +#define Z_IS_760_EQ_760U(...) \, +#define Z_IS_760U_EQ_760U(...) \, +#define Z_IS_761_EQ_761(...) \, +#define Z_IS_761U_EQ_761(...) \, +#define Z_IS_761_EQ_761U(...) \, +#define Z_IS_761U_EQ_761U(...) \, +#define Z_IS_762_EQ_762(...) \, +#define Z_IS_762U_EQ_762(...) \, +#define Z_IS_762_EQ_762U(...) \, +#define Z_IS_762U_EQ_762U(...) \, +#define Z_IS_763_EQ_763(...) \, +#define Z_IS_763U_EQ_763(...) \, +#define Z_IS_763_EQ_763U(...) \, +#define Z_IS_763U_EQ_763U(...) \, +#define Z_IS_764_EQ_764(...) \, +#define Z_IS_764U_EQ_764(...) \, +#define Z_IS_764_EQ_764U(...) \, +#define Z_IS_764U_EQ_764U(...) \, +#define Z_IS_765_EQ_765(...) \, +#define Z_IS_765U_EQ_765(...) \, +#define Z_IS_765_EQ_765U(...) \, +#define Z_IS_765U_EQ_765U(...) \, +#define Z_IS_766_EQ_766(...) \, +#define Z_IS_766U_EQ_766(...) \, +#define Z_IS_766_EQ_766U(...) \, +#define Z_IS_766U_EQ_766U(...) \, +#define Z_IS_767_EQ_767(...) \, +#define Z_IS_767U_EQ_767(...) \, +#define Z_IS_767_EQ_767U(...) \, +#define Z_IS_767U_EQ_767U(...) \, +#define Z_IS_768_EQ_768(...) \, +#define Z_IS_768U_EQ_768(...) \, +#define Z_IS_768_EQ_768U(...) \, +#define Z_IS_768U_EQ_768U(...) \, +#define Z_IS_769_EQ_769(...) \, +#define Z_IS_769U_EQ_769(...) \, +#define Z_IS_769_EQ_769U(...) \, +#define Z_IS_769U_EQ_769U(...) \, +#define Z_IS_770_EQ_770(...) \, +#define Z_IS_770U_EQ_770(...) \, +#define Z_IS_770_EQ_770U(...) \, +#define Z_IS_770U_EQ_770U(...) \, +#define Z_IS_771_EQ_771(...) \, +#define Z_IS_771U_EQ_771(...) \, +#define Z_IS_771_EQ_771U(...) \, +#define Z_IS_771U_EQ_771U(...) \, +#define Z_IS_772_EQ_772(...) \, +#define Z_IS_772U_EQ_772(...) \, +#define Z_IS_772_EQ_772U(...) \, +#define Z_IS_772U_EQ_772U(...) \, +#define Z_IS_773_EQ_773(...) \, +#define Z_IS_773U_EQ_773(...) \, +#define Z_IS_773_EQ_773U(...) \, +#define Z_IS_773U_EQ_773U(...) \, +#define Z_IS_774_EQ_774(...) \, +#define Z_IS_774U_EQ_774(...) \, +#define Z_IS_774_EQ_774U(...) \, +#define Z_IS_774U_EQ_774U(...) \, +#define Z_IS_775_EQ_775(...) \, +#define Z_IS_775U_EQ_775(...) \, +#define Z_IS_775_EQ_775U(...) \, +#define Z_IS_775U_EQ_775U(...) \, +#define Z_IS_776_EQ_776(...) \, +#define Z_IS_776U_EQ_776(...) \, +#define Z_IS_776_EQ_776U(...) \, +#define Z_IS_776U_EQ_776U(...) \, +#define Z_IS_777_EQ_777(...) \, +#define Z_IS_777U_EQ_777(...) \, +#define Z_IS_777_EQ_777U(...) \, +#define Z_IS_777U_EQ_777U(...) \, +#define Z_IS_778_EQ_778(...) \, +#define Z_IS_778U_EQ_778(...) \, +#define Z_IS_778_EQ_778U(...) \, +#define Z_IS_778U_EQ_778U(...) \, +#define Z_IS_779_EQ_779(...) \, +#define Z_IS_779U_EQ_779(...) \, +#define Z_IS_779_EQ_779U(...) \, +#define Z_IS_779U_EQ_779U(...) \, +#define Z_IS_780_EQ_780(...) \, +#define Z_IS_780U_EQ_780(...) \, +#define Z_IS_780_EQ_780U(...) \, +#define Z_IS_780U_EQ_780U(...) \, +#define Z_IS_781_EQ_781(...) \, +#define Z_IS_781U_EQ_781(...) \, +#define Z_IS_781_EQ_781U(...) \, +#define Z_IS_781U_EQ_781U(...) \, +#define Z_IS_782_EQ_782(...) \, +#define Z_IS_782U_EQ_782(...) \, +#define Z_IS_782_EQ_782U(...) \, +#define Z_IS_782U_EQ_782U(...) \, +#define Z_IS_783_EQ_783(...) \, +#define Z_IS_783U_EQ_783(...) \, +#define Z_IS_783_EQ_783U(...) \, +#define Z_IS_783U_EQ_783U(...) \, +#define Z_IS_784_EQ_784(...) \, +#define Z_IS_784U_EQ_784(...) \, +#define Z_IS_784_EQ_784U(...) \, +#define Z_IS_784U_EQ_784U(...) \, +#define Z_IS_785_EQ_785(...) \, +#define Z_IS_785U_EQ_785(...) \, +#define Z_IS_785_EQ_785U(...) \, +#define Z_IS_785U_EQ_785U(...) \, +#define Z_IS_786_EQ_786(...) \, +#define Z_IS_786U_EQ_786(...) \, +#define Z_IS_786_EQ_786U(...) \, +#define Z_IS_786U_EQ_786U(...) \, +#define Z_IS_787_EQ_787(...) \, +#define Z_IS_787U_EQ_787(...) \, +#define Z_IS_787_EQ_787U(...) \, +#define Z_IS_787U_EQ_787U(...) \, +#define Z_IS_788_EQ_788(...) \, +#define Z_IS_788U_EQ_788(...) \, +#define Z_IS_788_EQ_788U(...) \, +#define Z_IS_788U_EQ_788U(...) \, +#define Z_IS_789_EQ_789(...) \, +#define Z_IS_789U_EQ_789(...) \, +#define Z_IS_789_EQ_789U(...) \, +#define Z_IS_789U_EQ_789U(...) \, +#define Z_IS_790_EQ_790(...) \, +#define Z_IS_790U_EQ_790(...) \, +#define Z_IS_790_EQ_790U(...) \, +#define Z_IS_790U_EQ_790U(...) \, +#define Z_IS_791_EQ_791(...) \, +#define Z_IS_791U_EQ_791(...) \, +#define Z_IS_791_EQ_791U(...) \, +#define Z_IS_791U_EQ_791U(...) \, +#define Z_IS_792_EQ_792(...) \, +#define Z_IS_792U_EQ_792(...) \, +#define Z_IS_792_EQ_792U(...) \, +#define Z_IS_792U_EQ_792U(...) \, +#define Z_IS_793_EQ_793(...) \, +#define Z_IS_793U_EQ_793(...) \, +#define Z_IS_793_EQ_793U(...) \, +#define Z_IS_793U_EQ_793U(...) \, +#define Z_IS_794_EQ_794(...) \, +#define Z_IS_794U_EQ_794(...) \, +#define Z_IS_794_EQ_794U(...) \, +#define Z_IS_794U_EQ_794U(...) \, +#define Z_IS_795_EQ_795(...) \, +#define Z_IS_795U_EQ_795(...) \, +#define Z_IS_795_EQ_795U(...) \, +#define Z_IS_795U_EQ_795U(...) \, +#define Z_IS_796_EQ_796(...) \, +#define Z_IS_796U_EQ_796(...) \, +#define Z_IS_796_EQ_796U(...) \, +#define Z_IS_796U_EQ_796U(...) \, +#define Z_IS_797_EQ_797(...) \, +#define Z_IS_797U_EQ_797(...) \, +#define Z_IS_797_EQ_797U(...) \, +#define Z_IS_797U_EQ_797U(...) \, +#define Z_IS_798_EQ_798(...) \, +#define Z_IS_798U_EQ_798(...) \, +#define Z_IS_798_EQ_798U(...) \, +#define Z_IS_798U_EQ_798U(...) \, +#define Z_IS_799_EQ_799(...) \, +#define Z_IS_799U_EQ_799(...) \, +#define Z_IS_799_EQ_799U(...) \, +#define Z_IS_799U_EQ_799U(...) \, +#define Z_IS_800_EQ_800(...) \, +#define Z_IS_800U_EQ_800(...) \, +#define Z_IS_800_EQ_800U(...) \, +#define Z_IS_800U_EQ_800U(...) \, +#define Z_IS_801_EQ_801(...) \, +#define Z_IS_801U_EQ_801(...) \, +#define Z_IS_801_EQ_801U(...) \, +#define Z_IS_801U_EQ_801U(...) \, +#define Z_IS_802_EQ_802(...) \, +#define Z_IS_802U_EQ_802(...) \, +#define Z_IS_802_EQ_802U(...) \, +#define Z_IS_802U_EQ_802U(...) \, +#define Z_IS_803_EQ_803(...) \, +#define Z_IS_803U_EQ_803(...) \, +#define Z_IS_803_EQ_803U(...) \, +#define Z_IS_803U_EQ_803U(...) \, +#define Z_IS_804_EQ_804(...) \, +#define Z_IS_804U_EQ_804(...) \, +#define Z_IS_804_EQ_804U(...) \, +#define Z_IS_804U_EQ_804U(...) \, +#define Z_IS_805_EQ_805(...) \, +#define Z_IS_805U_EQ_805(...) \, +#define Z_IS_805_EQ_805U(...) \, +#define Z_IS_805U_EQ_805U(...) \, +#define Z_IS_806_EQ_806(...) \, +#define Z_IS_806U_EQ_806(...) \, +#define Z_IS_806_EQ_806U(...) \, +#define Z_IS_806U_EQ_806U(...) \, +#define Z_IS_807_EQ_807(...) \, +#define Z_IS_807U_EQ_807(...) \, +#define Z_IS_807_EQ_807U(...) \, +#define Z_IS_807U_EQ_807U(...) \, +#define Z_IS_808_EQ_808(...) \, +#define Z_IS_808U_EQ_808(...) \, +#define Z_IS_808_EQ_808U(...) \, +#define Z_IS_808U_EQ_808U(...) \, +#define Z_IS_809_EQ_809(...) \, +#define Z_IS_809U_EQ_809(...) \, +#define Z_IS_809_EQ_809U(...) \, +#define Z_IS_809U_EQ_809U(...) \, +#define Z_IS_810_EQ_810(...) \, +#define Z_IS_810U_EQ_810(...) \, +#define Z_IS_810_EQ_810U(...) \, +#define Z_IS_810U_EQ_810U(...) \, +#define Z_IS_811_EQ_811(...) \, +#define Z_IS_811U_EQ_811(...) \, +#define Z_IS_811_EQ_811U(...) \, +#define Z_IS_811U_EQ_811U(...) \, +#define Z_IS_812_EQ_812(...) \, +#define Z_IS_812U_EQ_812(...) \, +#define Z_IS_812_EQ_812U(...) \, +#define Z_IS_812U_EQ_812U(...) \, +#define Z_IS_813_EQ_813(...) \, +#define Z_IS_813U_EQ_813(...) \, +#define Z_IS_813_EQ_813U(...) \, +#define Z_IS_813U_EQ_813U(...) \, +#define Z_IS_814_EQ_814(...) \, +#define Z_IS_814U_EQ_814(...) \, +#define Z_IS_814_EQ_814U(...) \, +#define Z_IS_814U_EQ_814U(...) \, +#define Z_IS_815_EQ_815(...) \, +#define Z_IS_815U_EQ_815(...) \, +#define Z_IS_815_EQ_815U(...) \, +#define Z_IS_815U_EQ_815U(...) \, +#define Z_IS_816_EQ_816(...) \, +#define Z_IS_816U_EQ_816(...) \, +#define Z_IS_816_EQ_816U(...) \, +#define Z_IS_816U_EQ_816U(...) \, +#define Z_IS_817_EQ_817(...) \, +#define Z_IS_817U_EQ_817(...) \, +#define Z_IS_817_EQ_817U(...) \, +#define Z_IS_817U_EQ_817U(...) \, +#define Z_IS_818_EQ_818(...) \, +#define Z_IS_818U_EQ_818(...) \, +#define Z_IS_818_EQ_818U(...) \, +#define Z_IS_818U_EQ_818U(...) \, +#define Z_IS_819_EQ_819(...) \, +#define Z_IS_819U_EQ_819(...) \, +#define Z_IS_819_EQ_819U(...) \, +#define Z_IS_819U_EQ_819U(...) \, +#define Z_IS_820_EQ_820(...) \, +#define Z_IS_820U_EQ_820(...) \, +#define Z_IS_820_EQ_820U(...) \, +#define Z_IS_820U_EQ_820U(...) \, +#define Z_IS_821_EQ_821(...) \, +#define Z_IS_821U_EQ_821(...) \, +#define Z_IS_821_EQ_821U(...) \, +#define Z_IS_821U_EQ_821U(...) \, +#define Z_IS_822_EQ_822(...) \, +#define Z_IS_822U_EQ_822(...) \, +#define Z_IS_822_EQ_822U(...) \, +#define Z_IS_822U_EQ_822U(...) \, +#define Z_IS_823_EQ_823(...) \, +#define Z_IS_823U_EQ_823(...) \, +#define Z_IS_823_EQ_823U(...) \, +#define Z_IS_823U_EQ_823U(...) \, +#define Z_IS_824_EQ_824(...) \, +#define Z_IS_824U_EQ_824(...) \, +#define Z_IS_824_EQ_824U(...) \, +#define Z_IS_824U_EQ_824U(...) \, +#define Z_IS_825_EQ_825(...) \, +#define Z_IS_825U_EQ_825(...) \, +#define Z_IS_825_EQ_825U(...) \, +#define Z_IS_825U_EQ_825U(...) \, +#define Z_IS_826_EQ_826(...) \, +#define Z_IS_826U_EQ_826(...) \, +#define Z_IS_826_EQ_826U(...) \, +#define Z_IS_826U_EQ_826U(...) \, +#define Z_IS_827_EQ_827(...) \, +#define Z_IS_827U_EQ_827(...) \, +#define Z_IS_827_EQ_827U(...) \, +#define Z_IS_827U_EQ_827U(...) \, +#define Z_IS_828_EQ_828(...) \, +#define Z_IS_828U_EQ_828(...) \, +#define Z_IS_828_EQ_828U(...) \, +#define Z_IS_828U_EQ_828U(...) \, +#define Z_IS_829_EQ_829(...) \, +#define Z_IS_829U_EQ_829(...) \, +#define Z_IS_829_EQ_829U(...) \, +#define Z_IS_829U_EQ_829U(...) \, +#define Z_IS_830_EQ_830(...) \, +#define Z_IS_830U_EQ_830(...) \, +#define Z_IS_830_EQ_830U(...) \, +#define Z_IS_830U_EQ_830U(...) \, +#define Z_IS_831_EQ_831(...) \, +#define Z_IS_831U_EQ_831(...) \, +#define Z_IS_831_EQ_831U(...) \, +#define Z_IS_831U_EQ_831U(...) \, +#define Z_IS_832_EQ_832(...) \, +#define Z_IS_832U_EQ_832(...) \, +#define Z_IS_832_EQ_832U(...) \, +#define Z_IS_832U_EQ_832U(...) \, +#define Z_IS_833_EQ_833(...) \, +#define Z_IS_833U_EQ_833(...) \, +#define Z_IS_833_EQ_833U(...) \, +#define Z_IS_833U_EQ_833U(...) \, +#define Z_IS_834_EQ_834(...) \, +#define Z_IS_834U_EQ_834(...) \, +#define Z_IS_834_EQ_834U(...) \, +#define Z_IS_834U_EQ_834U(...) \, +#define Z_IS_835_EQ_835(...) \, +#define Z_IS_835U_EQ_835(...) \, +#define Z_IS_835_EQ_835U(...) \, +#define Z_IS_835U_EQ_835U(...) \, +#define Z_IS_836_EQ_836(...) \, +#define Z_IS_836U_EQ_836(...) \, +#define Z_IS_836_EQ_836U(...) \, +#define Z_IS_836U_EQ_836U(...) \, +#define Z_IS_837_EQ_837(...) \, +#define Z_IS_837U_EQ_837(...) \, +#define Z_IS_837_EQ_837U(...) \, +#define Z_IS_837U_EQ_837U(...) \, +#define Z_IS_838_EQ_838(...) \, +#define Z_IS_838U_EQ_838(...) \, +#define Z_IS_838_EQ_838U(...) \, +#define Z_IS_838U_EQ_838U(...) \, +#define Z_IS_839_EQ_839(...) \, +#define Z_IS_839U_EQ_839(...) \, +#define Z_IS_839_EQ_839U(...) \, +#define Z_IS_839U_EQ_839U(...) \, +#define Z_IS_840_EQ_840(...) \, +#define Z_IS_840U_EQ_840(...) \, +#define Z_IS_840_EQ_840U(...) \, +#define Z_IS_840U_EQ_840U(...) \, +#define Z_IS_841_EQ_841(...) \, +#define Z_IS_841U_EQ_841(...) \, +#define Z_IS_841_EQ_841U(...) \, +#define Z_IS_841U_EQ_841U(...) \, +#define Z_IS_842_EQ_842(...) \, +#define Z_IS_842U_EQ_842(...) \, +#define Z_IS_842_EQ_842U(...) \, +#define Z_IS_842U_EQ_842U(...) \, +#define Z_IS_843_EQ_843(...) \, +#define Z_IS_843U_EQ_843(...) \, +#define Z_IS_843_EQ_843U(...) \, +#define Z_IS_843U_EQ_843U(...) \, +#define Z_IS_844_EQ_844(...) \, +#define Z_IS_844U_EQ_844(...) \, +#define Z_IS_844_EQ_844U(...) \, +#define Z_IS_844U_EQ_844U(...) \, +#define Z_IS_845_EQ_845(...) \, +#define Z_IS_845U_EQ_845(...) \, +#define Z_IS_845_EQ_845U(...) \, +#define Z_IS_845U_EQ_845U(...) \, +#define Z_IS_846_EQ_846(...) \, +#define Z_IS_846U_EQ_846(...) \, +#define Z_IS_846_EQ_846U(...) \, +#define Z_IS_846U_EQ_846U(...) \, +#define Z_IS_847_EQ_847(...) \, +#define Z_IS_847U_EQ_847(...) \, +#define Z_IS_847_EQ_847U(...) \, +#define Z_IS_847U_EQ_847U(...) \, +#define Z_IS_848_EQ_848(...) \, +#define Z_IS_848U_EQ_848(...) \, +#define Z_IS_848_EQ_848U(...) \, +#define Z_IS_848U_EQ_848U(...) \, +#define Z_IS_849_EQ_849(...) \, +#define Z_IS_849U_EQ_849(...) \, +#define Z_IS_849_EQ_849U(...) \, +#define Z_IS_849U_EQ_849U(...) \, +#define Z_IS_850_EQ_850(...) \, +#define Z_IS_850U_EQ_850(...) \, +#define Z_IS_850_EQ_850U(...) \, +#define Z_IS_850U_EQ_850U(...) \, +#define Z_IS_851_EQ_851(...) \, +#define Z_IS_851U_EQ_851(...) \, +#define Z_IS_851_EQ_851U(...) \, +#define Z_IS_851U_EQ_851U(...) \, +#define Z_IS_852_EQ_852(...) \, +#define Z_IS_852U_EQ_852(...) \, +#define Z_IS_852_EQ_852U(...) \, +#define Z_IS_852U_EQ_852U(...) \, +#define Z_IS_853_EQ_853(...) \, +#define Z_IS_853U_EQ_853(...) \, +#define Z_IS_853_EQ_853U(...) \, +#define Z_IS_853U_EQ_853U(...) \, +#define Z_IS_854_EQ_854(...) \, +#define Z_IS_854U_EQ_854(...) \, +#define Z_IS_854_EQ_854U(...) \, +#define Z_IS_854U_EQ_854U(...) \, +#define Z_IS_855_EQ_855(...) \, +#define Z_IS_855U_EQ_855(...) \, +#define Z_IS_855_EQ_855U(...) \, +#define Z_IS_855U_EQ_855U(...) \, +#define Z_IS_856_EQ_856(...) \, +#define Z_IS_856U_EQ_856(...) \, +#define Z_IS_856_EQ_856U(...) \, +#define Z_IS_856U_EQ_856U(...) \, +#define Z_IS_857_EQ_857(...) \, +#define Z_IS_857U_EQ_857(...) \, +#define Z_IS_857_EQ_857U(...) \, +#define Z_IS_857U_EQ_857U(...) \, +#define Z_IS_858_EQ_858(...) \, +#define Z_IS_858U_EQ_858(...) \, +#define Z_IS_858_EQ_858U(...) \, +#define Z_IS_858U_EQ_858U(...) \, +#define Z_IS_859_EQ_859(...) \, +#define Z_IS_859U_EQ_859(...) \, +#define Z_IS_859_EQ_859U(...) \, +#define Z_IS_859U_EQ_859U(...) \, +#define Z_IS_860_EQ_860(...) \, +#define Z_IS_860U_EQ_860(...) \, +#define Z_IS_860_EQ_860U(...) \, +#define Z_IS_860U_EQ_860U(...) \, +#define Z_IS_861_EQ_861(...) \, +#define Z_IS_861U_EQ_861(...) \, +#define Z_IS_861_EQ_861U(...) \, +#define Z_IS_861U_EQ_861U(...) \, +#define Z_IS_862_EQ_862(...) \, +#define Z_IS_862U_EQ_862(...) \, +#define Z_IS_862_EQ_862U(...) \, +#define Z_IS_862U_EQ_862U(...) \, +#define Z_IS_863_EQ_863(...) \, +#define Z_IS_863U_EQ_863(...) \, +#define Z_IS_863_EQ_863U(...) \, +#define Z_IS_863U_EQ_863U(...) \, +#define Z_IS_864_EQ_864(...) \, +#define Z_IS_864U_EQ_864(...) \, +#define Z_IS_864_EQ_864U(...) \, +#define Z_IS_864U_EQ_864U(...) \, +#define Z_IS_865_EQ_865(...) \, +#define Z_IS_865U_EQ_865(...) \, +#define Z_IS_865_EQ_865U(...) \, +#define Z_IS_865U_EQ_865U(...) \, +#define Z_IS_866_EQ_866(...) \, +#define Z_IS_866U_EQ_866(...) \, +#define Z_IS_866_EQ_866U(...) \, +#define Z_IS_866U_EQ_866U(...) \, +#define Z_IS_867_EQ_867(...) \, +#define Z_IS_867U_EQ_867(...) \, +#define Z_IS_867_EQ_867U(...) \, +#define Z_IS_867U_EQ_867U(...) \, +#define Z_IS_868_EQ_868(...) \, +#define Z_IS_868U_EQ_868(...) \, +#define Z_IS_868_EQ_868U(...) \, +#define Z_IS_868U_EQ_868U(...) \, +#define Z_IS_869_EQ_869(...) \, +#define Z_IS_869U_EQ_869(...) \, +#define Z_IS_869_EQ_869U(...) \, +#define Z_IS_869U_EQ_869U(...) \, +#define Z_IS_870_EQ_870(...) \, +#define Z_IS_870U_EQ_870(...) \, +#define Z_IS_870_EQ_870U(...) \, +#define Z_IS_870U_EQ_870U(...) \, +#define Z_IS_871_EQ_871(...) \, +#define Z_IS_871U_EQ_871(...) \, +#define Z_IS_871_EQ_871U(...) \, +#define Z_IS_871U_EQ_871U(...) \, +#define Z_IS_872_EQ_872(...) \, +#define Z_IS_872U_EQ_872(...) \, +#define Z_IS_872_EQ_872U(...) \, +#define Z_IS_872U_EQ_872U(...) \, +#define Z_IS_873_EQ_873(...) \, +#define Z_IS_873U_EQ_873(...) \, +#define Z_IS_873_EQ_873U(...) \, +#define Z_IS_873U_EQ_873U(...) \, +#define Z_IS_874_EQ_874(...) \, +#define Z_IS_874U_EQ_874(...) \, +#define Z_IS_874_EQ_874U(...) \, +#define Z_IS_874U_EQ_874U(...) \, +#define Z_IS_875_EQ_875(...) \, +#define Z_IS_875U_EQ_875(...) \, +#define Z_IS_875_EQ_875U(...) \, +#define Z_IS_875U_EQ_875U(...) \, +#define Z_IS_876_EQ_876(...) \, +#define Z_IS_876U_EQ_876(...) \, +#define Z_IS_876_EQ_876U(...) \, +#define Z_IS_876U_EQ_876U(...) \, +#define Z_IS_877_EQ_877(...) \, +#define Z_IS_877U_EQ_877(...) \, +#define Z_IS_877_EQ_877U(...) \, +#define Z_IS_877U_EQ_877U(...) \, +#define Z_IS_878_EQ_878(...) \, +#define Z_IS_878U_EQ_878(...) \, +#define Z_IS_878_EQ_878U(...) \, +#define Z_IS_878U_EQ_878U(...) \, +#define Z_IS_879_EQ_879(...) \, +#define Z_IS_879U_EQ_879(...) \, +#define Z_IS_879_EQ_879U(...) \, +#define Z_IS_879U_EQ_879U(...) \, +#define Z_IS_880_EQ_880(...) \, +#define Z_IS_880U_EQ_880(...) \, +#define Z_IS_880_EQ_880U(...) \, +#define Z_IS_880U_EQ_880U(...) \, +#define Z_IS_881_EQ_881(...) \, +#define Z_IS_881U_EQ_881(...) \, +#define Z_IS_881_EQ_881U(...) \, +#define Z_IS_881U_EQ_881U(...) \, +#define Z_IS_882_EQ_882(...) \, +#define Z_IS_882U_EQ_882(...) \, +#define Z_IS_882_EQ_882U(...) \, +#define Z_IS_882U_EQ_882U(...) \, +#define Z_IS_883_EQ_883(...) \, +#define Z_IS_883U_EQ_883(...) \, +#define Z_IS_883_EQ_883U(...) \, +#define Z_IS_883U_EQ_883U(...) \, +#define Z_IS_884_EQ_884(...) \, +#define Z_IS_884U_EQ_884(...) \, +#define Z_IS_884_EQ_884U(...) \, +#define Z_IS_884U_EQ_884U(...) \, +#define Z_IS_885_EQ_885(...) \, +#define Z_IS_885U_EQ_885(...) \, +#define Z_IS_885_EQ_885U(...) \, +#define Z_IS_885U_EQ_885U(...) \, +#define Z_IS_886_EQ_886(...) \, +#define Z_IS_886U_EQ_886(...) \, +#define Z_IS_886_EQ_886U(...) \, +#define Z_IS_886U_EQ_886U(...) \, +#define Z_IS_887_EQ_887(...) \, +#define Z_IS_887U_EQ_887(...) \, +#define Z_IS_887_EQ_887U(...) \, +#define Z_IS_887U_EQ_887U(...) \, +#define Z_IS_888_EQ_888(...) \, +#define Z_IS_888U_EQ_888(...) \, +#define Z_IS_888_EQ_888U(...) \, +#define Z_IS_888U_EQ_888U(...) \, +#define Z_IS_889_EQ_889(...) \, +#define Z_IS_889U_EQ_889(...) \, +#define Z_IS_889_EQ_889U(...) \, +#define Z_IS_889U_EQ_889U(...) \, +#define Z_IS_890_EQ_890(...) \, +#define Z_IS_890U_EQ_890(...) \, +#define Z_IS_890_EQ_890U(...) \, +#define Z_IS_890U_EQ_890U(...) \, +#define Z_IS_891_EQ_891(...) \, +#define Z_IS_891U_EQ_891(...) \, +#define Z_IS_891_EQ_891U(...) \, +#define Z_IS_891U_EQ_891U(...) \, +#define Z_IS_892_EQ_892(...) \, +#define Z_IS_892U_EQ_892(...) \, +#define Z_IS_892_EQ_892U(...) \, +#define Z_IS_892U_EQ_892U(...) \, +#define Z_IS_893_EQ_893(...) \, +#define Z_IS_893U_EQ_893(...) \, +#define Z_IS_893_EQ_893U(...) \, +#define Z_IS_893U_EQ_893U(...) \, +#define Z_IS_894_EQ_894(...) \, +#define Z_IS_894U_EQ_894(...) \, +#define Z_IS_894_EQ_894U(...) \, +#define Z_IS_894U_EQ_894U(...) \, +#define Z_IS_895_EQ_895(...) \, +#define Z_IS_895U_EQ_895(...) \, +#define Z_IS_895_EQ_895U(...) \, +#define Z_IS_895U_EQ_895U(...) \, +#define Z_IS_896_EQ_896(...) \, +#define Z_IS_896U_EQ_896(...) \, +#define Z_IS_896_EQ_896U(...) \, +#define Z_IS_896U_EQ_896U(...) \, +#define Z_IS_897_EQ_897(...) \, +#define Z_IS_897U_EQ_897(...) \, +#define Z_IS_897_EQ_897U(...) \, +#define Z_IS_897U_EQ_897U(...) \, +#define Z_IS_898_EQ_898(...) \, +#define Z_IS_898U_EQ_898(...) \, +#define Z_IS_898_EQ_898U(...) \, +#define Z_IS_898U_EQ_898U(...) \, +#define Z_IS_899_EQ_899(...) \, +#define Z_IS_899U_EQ_899(...) \, +#define Z_IS_899_EQ_899U(...) \, +#define Z_IS_899U_EQ_899U(...) \, +#define Z_IS_900_EQ_900(...) \, +#define Z_IS_900U_EQ_900(...) \, +#define Z_IS_900_EQ_900U(...) \, +#define Z_IS_900U_EQ_900U(...) \, +#define Z_IS_901_EQ_901(...) \, +#define Z_IS_901U_EQ_901(...) \, +#define Z_IS_901_EQ_901U(...) \, +#define Z_IS_901U_EQ_901U(...) \, +#define Z_IS_902_EQ_902(...) \, +#define Z_IS_902U_EQ_902(...) \, +#define Z_IS_902_EQ_902U(...) \, +#define Z_IS_902U_EQ_902U(...) \, +#define Z_IS_903_EQ_903(...) \, +#define Z_IS_903U_EQ_903(...) \, +#define Z_IS_903_EQ_903U(...) \, +#define Z_IS_903U_EQ_903U(...) \, +#define Z_IS_904_EQ_904(...) \, +#define Z_IS_904U_EQ_904(...) \, +#define Z_IS_904_EQ_904U(...) \, +#define Z_IS_904U_EQ_904U(...) \, +#define Z_IS_905_EQ_905(...) \, +#define Z_IS_905U_EQ_905(...) \, +#define Z_IS_905_EQ_905U(...) \, +#define Z_IS_905U_EQ_905U(...) \, +#define Z_IS_906_EQ_906(...) \, +#define Z_IS_906U_EQ_906(...) \, +#define Z_IS_906_EQ_906U(...) \, +#define Z_IS_906U_EQ_906U(...) \, +#define Z_IS_907_EQ_907(...) \, +#define Z_IS_907U_EQ_907(...) \, +#define Z_IS_907_EQ_907U(...) \, +#define Z_IS_907U_EQ_907U(...) \, +#define Z_IS_908_EQ_908(...) \, +#define Z_IS_908U_EQ_908(...) \, +#define Z_IS_908_EQ_908U(...) \, +#define Z_IS_908U_EQ_908U(...) \, +#define Z_IS_909_EQ_909(...) \, +#define Z_IS_909U_EQ_909(...) \, +#define Z_IS_909_EQ_909U(...) \, +#define Z_IS_909U_EQ_909U(...) \, +#define Z_IS_910_EQ_910(...) \, +#define Z_IS_910U_EQ_910(...) \, +#define Z_IS_910_EQ_910U(...) \, +#define Z_IS_910U_EQ_910U(...) \, +#define Z_IS_911_EQ_911(...) \, +#define Z_IS_911U_EQ_911(...) \, +#define Z_IS_911_EQ_911U(...) \, +#define Z_IS_911U_EQ_911U(...) \, +#define Z_IS_912_EQ_912(...) \, +#define Z_IS_912U_EQ_912(...) \, +#define Z_IS_912_EQ_912U(...) \, +#define Z_IS_912U_EQ_912U(...) \, +#define Z_IS_913_EQ_913(...) \, +#define Z_IS_913U_EQ_913(...) \, +#define Z_IS_913_EQ_913U(...) \, +#define Z_IS_913U_EQ_913U(...) \, +#define Z_IS_914_EQ_914(...) \, +#define Z_IS_914U_EQ_914(...) \, +#define Z_IS_914_EQ_914U(...) \, +#define Z_IS_914U_EQ_914U(...) \, +#define Z_IS_915_EQ_915(...) \, +#define Z_IS_915U_EQ_915(...) \, +#define Z_IS_915_EQ_915U(...) \, +#define Z_IS_915U_EQ_915U(...) \, +#define Z_IS_916_EQ_916(...) \, +#define Z_IS_916U_EQ_916(...) \, +#define Z_IS_916_EQ_916U(...) \, +#define Z_IS_916U_EQ_916U(...) \, +#define Z_IS_917_EQ_917(...) \, +#define Z_IS_917U_EQ_917(...) \, +#define Z_IS_917_EQ_917U(...) \, +#define Z_IS_917U_EQ_917U(...) \, +#define Z_IS_918_EQ_918(...) \, +#define Z_IS_918U_EQ_918(...) \, +#define Z_IS_918_EQ_918U(...) \, +#define Z_IS_918U_EQ_918U(...) \, +#define Z_IS_919_EQ_919(...) \, +#define Z_IS_919U_EQ_919(...) \, +#define Z_IS_919_EQ_919U(...) \, +#define Z_IS_919U_EQ_919U(...) \, +#define Z_IS_920_EQ_920(...) \, +#define Z_IS_920U_EQ_920(...) \, +#define Z_IS_920_EQ_920U(...) \, +#define Z_IS_920U_EQ_920U(...) \, +#define Z_IS_921_EQ_921(...) \, +#define Z_IS_921U_EQ_921(...) \, +#define Z_IS_921_EQ_921U(...) \, +#define Z_IS_921U_EQ_921U(...) \, +#define Z_IS_922_EQ_922(...) \, +#define Z_IS_922U_EQ_922(...) \, +#define Z_IS_922_EQ_922U(...) \, +#define Z_IS_922U_EQ_922U(...) \, +#define Z_IS_923_EQ_923(...) \, +#define Z_IS_923U_EQ_923(...) \, +#define Z_IS_923_EQ_923U(...) \, +#define Z_IS_923U_EQ_923U(...) \, +#define Z_IS_924_EQ_924(...) \, +#define Z_IS_924U_EQ_924(...) \, +#define Z_IS_924_EQ_924U(...) \, +#define Z_IS_924U_EQ_924U(...) \, +#define Z_IS_925_EQ_925(...) \, +#define Z_IS_925U_EQ_925(...) \, +#define Z_IS_925_EQ_925U(...) \, +#define Z_IS_925U_EQ_925U(...) \, +#define Z_IS_926_EQ_926(...) \, +#define Z_IS_926U_EQ_926(...) \, +#define Z_IS_926_EQ_926U(...) \, +#define Z_IS_926U_EQ_926U(...) \, +#define Z_IS_927_EQ_927(...) \, +#define Z_IS_927U_EQ_927(...) \, +#define Z_IS_927_EQ_927U(...) \, +#define Z_IS_927U_EQ_927U(...) \, +#define Z_IS_928_EQ_928(...) \, +#define Z_IS_928U_EQ_928(...) \, +#define Z_IS_928_EQ_928U(...) \, +#define Z_IS_928U_EQ_928U(...) \, +#define Z_IS_929_EQ_929(...) \, +#define Z_IS_929U_EQ_929(...) \, +#define Z_IS_929_EQ_929U(...) \, +#define Z_IS_929U_EQ_929U(...) \, +#define Z_IS_930_EQ_930(...) \, +#define Z_IS_930U_EQ_930(...) \, +#define Z_IS_930_EQ_930U(...) \, +#define Z_IS_930U_EQ_930U(...) \, +#define Z_IS_931_EQ_931(...) \, +#define Z_IS_931U_EQ_931(...) \, +#define Z_IS_931_EQ_931U(...) \, +#define Z_IS_931U_EQ_931U(...) \, +#define Z_IS_932_EQ_932(...) \, +#define Z_IS_932U_EQ_932(...) \, +#define Z_IS_932_EQ_932U(...) \, +#define Z_IS_932U_EQ_932U(...) \, +#define Z_IS_933_EQ_933(...) \, +#define Z_IS_933U_EQ_933(...) \, +#define Z_IS_933_EQ_933U(...) \, +#define Z_IS_933U_EQ_933U(...) \, +#define Z_IS_934_EQ_934(...) \, +#define Z_IS_934U_EQ_934(...) \, +#define Z_IS_934_EQ_934U(...) \, +#define Z_IS_934U_EQ_934U(...) \, +#define Z_IS_935_EQ_935(...) \, +#define Z_IS_935U_EQ_935(...) \, +#define Z_IS_935_EQ_935U(...) \, +#define Z_IS_935U_EQ_935U(...) \, +#define Z_IS_936_EQ_936(...) \, +#define Z_IS_936U_EQ_936(...) \, +#define Z_IS_936_EQ_936U(...) \, +#define Z_IS_936U_EQ_936U(...) \, +#define Z_IS_937_EQ_937(...) \, +#define Z_IS_937U_EQ_937(...) \, +#define Z_IS_937_EQ_937U(...) \, +#define Z_IS_937U_EQ_937U(...) \, +#define Z_IS_938_EQ_938(...) \, +#define Z_IS_938U_EQ_938(...) \, +#define Z_IS_938_EQ_938U(...) \, +#define Z_IS_938U_EQ_938U(...) \, +#define Z_IS_939_EQ_939(...) \, +#define Z_IS_939U_EQ_939(...) \, +#define Z_IS_939_EQ_939U(...) \, +#define Z_IS_939U_EQ_939U(...) \, +#define Z_IS_940_EQ_940(...) \, +#define Z_IS_940U_EQ_940(...) \, +#define Z_IS_940_EQ_940U(...) \, +#define Z_IS_940U_EQ_940U(...) \, +#define Z_IS_941_EQ_941(...) \, +#define Z_IS_941U_EQ_941(...) \, +#define Z_IS_941_EQ_941U(...) \, +#define Z_IS_941U_EQ_941U(...) \, +#define Z_IS_942_EQ_942(...) \, +#define Z_IS_942U_EQ_942(...) \, +#define Z_IS_942_EQ_942U(...) \, +#define Z_IS_942U_EQ_942U(...) \, +#define Z_IS_943_EQ_943(...) \, +#define Z_IS_943U_EQ_943(...) \, +#define Z_IS_943_EQ_943U(...) \, +#define Z_IS_943U_EQ_943U(...) \, +#define Z_IS_944_EQ_944(...) \, +#define Z_IS_944U_EQ_944(...) \, +#define Z_IS_944_EQ_944U(...) \, +#define Z_IS_944U_EQ_944U(...) \, +#define Z_IS_945_EQ_945(...) \, +#define Z_IS_945U_EQ_945(...) \, +#define Z_IS_945_EQ_945U(...) \, +#define Z_IS_945U_EQ_945U(...) \, +#define Z_IS_946_EQ_946(...) \, +#define Z_IS_946U_EQ_946(...) \, +#define Z_IS_946_EQ_946U(...) \, +#define Z_IS_946U_EQ_946U(...) \, +#define Z_IS_947_EQ_947(...) \, +#define Z_IS_947U_EQ_947(...) \, +#define Z_IS_947_EQ_947U(...) \, +#define Z_IS_947U_EQ_947U(...) \, +#define Z_IS_948_EQ_948(...) \, +#define Z_IS_948U_EQ_948(...) \, +#define Z_IS_948_EQ_948U(...) \, +#define Z_IS_948U_EQ_948U(...) \, +#define Z_IS_949_EQ_949(...) \, +#define Z_IS_949U_EQ_949(...) \, +#define Z_IS_949_EQ_949U(...) \, +#define Z_IS_949U_EQ_949U(...) \, +#define Z_IS_950_EQ_950(...) \, +#define Z_IS_950U_EQ_950(...) \, +#define Z_IS_950_EQ_950U(...) \, +#define Z_IS_950U_EQ_950U(...) \, +#define Z_IS_951_EQ_951(...) \, +#define Z_IS_951U_EQ_951(...) \, +#define Z_IS_951_EQ_951U(...) \, +#define Z_IS_951U_EQ_951U(...) \, +#define Z_IS_952_EQ_952(...) \, +#define Z_IS_952U_EQ_952(...) \, +#define Z_IS_952_EQ_952U(...) \, +#define Z_IS_952U_EQ_952U(...) \, +#define Z_IS_953_EQ_953(...) \, +#define Z_IS_953U_EQ_953(...) \, +#define Z_IS_953_EQ_953U(...) \, +#define Z_IS_953U_EQ_953U(...) \, +#define Z_IS_954_EQ_954(...) \, +#define Z_IS_954U_EQ_954(...) \, +#define Z_IS_954_EQ_954U(...) \, +#define Z_IS_954U_EQ_954U(...) \, +#define Z_IS_955_EQ_955(...) \, +#define Z_IS_955U_EQ_955(...) \, +#define Z_IS_955_EQ_955U(...) \, +#define Z_IS_955U_EQ_955U(...) \, +#define Z_IS_956_EQ_956(...) \, +#define Z_IS_956U_EQ_956(...) \, +#define Z_IS_956_EQ_956U(...) \, +#define Z_IS_956U_EQ_956U(...) \, +#define Z_IS_957_EQ_957(...) \, +#define Z_IS_957U_EQ_957(...) \, +#define Z_IS_957_EQ_957U(...) \, +#define Z_IS_957U_EQ_957U(...) \, +#define Z_IS_958_EQ_958(...) \, +#define Z_IS_958U_EQ_958(...) \, +#define Z_IS_958_EQ_958U(...) \, +#define Z_IS_958U_EQ_958U(...) \, +#define Z_IS_959_EQ_959(...) \, +#define Z_IS_959U_EQ_959(...) \, +#define Z_IS_959_EQ_959U(...) \, +#define Z_IS_959U_EQ_959U(...) \, +#define Z_IS_960_EQ_960(...) \, +#define Z_IS_960U_EQ_960(...) \, +#define Z_IS_960_EQ_960U(...) \, +#define Z_IS_960U_EQ_960U(...) \, +#define Z_IS_961_EQ_961(...) \, +#define Z_IS_961U_EQ_961(...) \, +#define Z_IS_961_EQ_961U(...) \, +#define Z_IS_961U_EQ_961U(...) \, +#define Z_IS_962_EQ_962(...) \, +#define Z_IS_962U_EQ_962(...) \, +#define Z_IS_962_EQ_962U(...) \, +#define Z_IS_962U_EQ_962U(...) \, +#define Z_IS_963_EQ_963(...) \, +#define Z_IS_963U_EQ_963(...) \, +#define Z_IS_963_EQ_963U(...) \, +#define Z_IS_963U_EQ_963U(...) \, +#define Z_IS_964_EQ_964(...) \, +#define Z_IS_964U_EQ_964(...) \, +#define Z_IS_964_EQ_964U(...) \, +#define Z_IS_964U_EQ_964U(...) \, +#define Z_IS_965_EQ_965(...) \, +#define Z_IS_965U_EQ_965(...) \, +#define Z_IS_965_EQ_965U(...) \, +#define Z_IS_965U_EQ_965U(...) \, +#define Z_IS_966_EQ_966(...) \, +#define Z_IS_966U_EQ_966(...) \, +#define Z_IS_966_EQ_966U(...) \, +#define Z_IS_966U_EQ_966U(...) \, +#define Z_IS_967_EQ_967(...) \, +#define Z_IS_967U_EQ_967(...) \, +#define Z_IS_967_EQ_967U(...) \, +#define Z_IS_967U_EQ_967U(...) \, +#define Z_IS_968_EQ_968(...) \, +#define Z_IS_968U_EQ_968(...) \, +#define Z_IS_968_EQ_968U(...) \, +#define Z_IS_968U_EQ_968U(...) \, +#define Z_IS_969_EQ_969(...) \, +#define Z_IS_969U_EQ_969(...) \, +#define Z_IS_969_EQ_969U(...) \, +#define Z_IS_969U_EQ_969U(...) \, +#define Z_IS_970_EQ_970(...) \, +#define Z_IS_970U_EQ_970(...) \, +#define Z_IS_970_EQ_970U(...) \, +#define Z_IS_970U_EQ_970U(...) \, +#define Z_IS_971_EQ_971(...) \, +#define Z_IS_971U_EQ_971(...) \, +#define Z_IS_971_EQ_971U(...) \, +#define Z_IS_971U_EQ_971U(...) \, +#define Z_IS_972_EQ_972(...) \, +#define Z_IS_972U_EQ_972(...) \, +#define Z_IS_972_EQ_972U(...) \, +#define Z_IS_972U_EQ_972U(...) \, +#define Z_IS_973_EQ_973(...) \, +#define Z_IS_973U_EQ_973(...) \, +#define Z_IS_973_EQ_973U(...) \, +#define Z_IS_973U_EQ_973U(...) \, +#define Z_IS_974_EQ_974(...) \, +#define Z_IS_974U_EQ_974(...) \, +#define Z_IS_974_EQ_974U(...) \, +#define Z_IS_974U_EQ_974U(...) \, +#define Z_IS_975_EQ_975(...) \, +#define Z_IS_975U_EQ_975(...) \, +#define Z_IS_975_EQ_975U(...) \, +#define Z_IS_975U_EQ_975U(...) \, +#define Z_IS_976_EQ_976(...) \, +#define Z_IS_976U_EQ_976(...) \, +#define Z_IS_976_EQ_976U(...) \, +#define Z_IS_976U_EQ_976U(...) \, +#define Z_IS_977_EQ_977(...) \, +#define Z_IS_977U_EQ_977(...) \, +#define Z_IS_977_EQ_977U(...) \, +#define Z_IS_977U_EQ_977U(...) \, +#define Z_IS_978_EQ_978(...) \, +#define Z_IS_978U_EQ_978(...) \, +#define Z_IS_978_EQ_978U(...) \, +#define Z_IS_978U_EQ_978U(...) \, +#define Z_IS_979_EQ_979(...) \, +#define Z_IS_979U_EQ_979(...) \, +#define Z_IS_979_EQ_979U(...) \, +#define Z_IS_979U_EQ_979U(...) \, +#define Z_IS_980_EQ_980(...) \, +#define Z_IS_980U_EQ_980(...) \, +#define Z_IS_980_EQ_980U(...) \, +#define Z_IS_980U_EQ_980U(...) \, +#define Z_IS_981_EQ_981(...) \, +#define Z_IS_981U_EQ_981(...) \, +#define Z_IS_981_EQ_981U(...) \, +#define Z_IS_981U_EQ_981U(...) \, +#define Z_IS_982_EQ_982(...) \, +#define Z_IS_982U_EQ_982(...) \, +#define Z_IS_982_EQ_982U(...) \, +#define Z_IS_982U_EQ_982U(...) \, +#define Z_IS_983_EQ_983(...) \, +#define Z_IS_983U_EQ_983(...) \, +#define Z_IS_983_EQ_983U(...) \, +#define Z_IS_983U_EQ_983U(...) \, +#define Z_IS_984_EQ_984(...) \, +#define Z_IS_984U_EQ_984(...) \, +#define Z_IS_984_EQ_984U(...) \, +#define Z_IS_984U_EQ_984U(...) \, +#define Z_IS_985_EQ_985(...) \, +#define Z_IS_985U_EQ_985(...) \, +#define Z_IS_985_EQ_985U(...) \, +#define Z_IS_985U_EQ_985U(...) \, +#define Z_IS_986_EQ_986(...) \, +#define Z_IS_986U_EQ_986(...) \, +#define Z_IS_986_EQ_986U(...) \, +#define Z_IS_986U_EQ_986U(...) \, +#define Z_IS_987_EQ_987(...) \, +#define Z_IS_987U_EQ_987(...) \, +#define Z_IS_987_EQ_987U(...) \, +#define Z_IS_987U_EQ_987U(...) \, +#define Z_IS_988_EQ_988(...) \, +#define Z_IS_988U_EQ_988(...) \, +#define Z_IS_988_EQ_988U(...) \, +#define Z_IS_988U_EQ_988U(...) \, +#define Z_IS_989_EQ_989(...) \, +#define Z_IS_989U_EQ_989(...) \, +#define Z_IS_989_EQ_989U(...) \, +#define Z_IS_989U_EQ_989U(...) \, +#define Z_IS_990_EQ_990(...) \, +#define Z_IS_990U_EQ_990(...) \, +#define Z_IS_990_EQ_990U(...) \, +#define Z_IS_990U_EQ_990U(...) \, +#define Z_IS_991_EQ_991(...) \, +#define Z_IS_991U_EQ_991(...) \, +#define Z_IS_991_EQ_991U(...) \, +#define Z_IS_991U_EQ_991U(...) \, +#define Z_IS_992_EQ_992(...) \, +#define Z_IS_992U_EQ_992(...) \, +#define Z_IS_992_EQ_992U(...) \, +#define Z_IS_992U_EQ_992U(...) \, +#define Z_IS_993_EQ_993(...) \, +#define Z_IS_993U_EQ_993(...) \, +#define Z_IS_993_EQ_993U(...) \, +#define Z_IS_993U_EQ_993U(...) \, +#define Z_IS_994_EQ_994(...) \, +#define Z_IS_994U_EQ_994(...) \, +#define Z_IS_994_EQ_994U(...) \, +#define Z_IS_994U_EQ_994U(...) \, +#define Z_IS_995_EQ_995(...) \, +#define Z_IS_995U_EQ_995(...) \, +#define Z_IS_995_EQ_995U(...) \, +#define Z_IS_995U_EQ_995U(...) \, +#define Z_IS_996_EQ_996(...) \, +#define Z_IS_996U_EQ_996(...) \, +#define Z_IS_996_EQ_996U(...) \, +#define Z_IS_996U_EQ_996U(...) \, +#define Z_IS_997_EQ_997(...) \, +#define Z_IS_997U_EQ_997(...) \, +#define Z_IS_997_EQ_997U(...) \, +#define Z_IS_997U_EQ_997U(...) \, +#define Z_IS_998_EQ_998(...) \, +#define Z_IS_998U_EQ_998(...) \, +#define Z_IS_998_EQ_998U(...) \, +#define Z_IS_998U_EQ_998U(...) \, +#define Z_IS_999_EQ_999(...) \, +#define Z_IS_999U_EQ_999(...) \, +#define Z_IS_999_EQ_999U(...) \, +#define Z_IS_999U_EQ_999U(...) \, +#define Z_IS_1000_EQ_1000(...) \, +#define Z_IS_1000U_EQ_1000(...) \, +#define Z_IS_1000_EQ_1000U(...) \, +#define Z_IS_1000U_EQ_1000U(...) \, +#define Z_IS_1001_EQ_1001(...) \, +#define Z_IS_1001U_EQ_1001(...) \, +#define Z_IS_1001_EQ_1001U(...) \, +#define Z_IS_1001U_EQ_1001U(...) \, +#define Z_IS_1002_EQ_1002(...) \, +#define Z_IS_1002U_EQ_1002(...) \, +#define Z_IS_1002_EQ_1002U(...) \, +#define Z_IS_1002U_EQ_1002U(...) \, +#define Z_IS_1003_EQ_1003(...) \, +#define Z_IS_1003U_EQ_1003(...) \, +#define Z_IS_1003_EQ_1003U(...) \, +#define Z_IS_1003U_EQ_1003U(...) \, +#define Z_IS_1004_EQ_1004(...) \, +#define Z_IS_1004U_EQ_1004(...) \, +#define Z_IS_1004_EQ_1004U(...) \, +#define Z_IS_1004U_EQ_1004U(...) \, +#define Z_IS_1005_EQ_1005(...) \, +#define Z_IS_1005U_EQ_1005(...) \, +#define Z_IS_1005_EQ_1005U(...) \, +#define Z_IS_1005U_EQ_1005U(...) \, +#define Z_IS_1006_EQ_1006(...) \, +#define Z_IS_1006U_EQ_1006(...) \, +#define Z_IS_1006_EQ_1006U(...) \, +#define Z_IS_1006U_EQ_1006U(...) \, +#define Z_IS_1007_EQ_1007(...) \, +#define Z_IS_1007U_EQ_1007(...) \, +#define Z_IS_1007_EQ_1007U(...) \, +#define Z_IS_1007U_EQ_1007U(...) \, +#define Z_IS_1008_EQ_1008(...) \, +#define Z_IS_1008U_EQ_1008(...) \, +#define Z_IS_1008_EQ_1008U(...) \, +#define Z_IS_1008U_EQ_1008U(...) \, +#define Z_IS_1009_EQ_1009(...) \, +#define Z_IS_1009U_EQ_1009(...) \, +#define Z_IS_1009_EQ_1009U(...) \, +#define Z_IS_1009U_EQ_1009U(...) \, +#define Z_IS_1010_EQ_1010(...) \, +#define Z_IS_1010U_EQ_1010(...) \, +#define Z_IS_1010_EQ_1010U(...) \, +#define Z_IS_1010U_EQ_1010U(...) \, +#define Z_IS_1011_EQ_1011(...) \, +#define Z_IS_1011U_EQ_1011(...) \, +#define Z_IS_1011_EQ_1011U(...) \, +#define Z_IS_1011U_EQ_1011U(...) \, +#define Z_IS_1012_EQ_1012(...) \, +#define Z_IS_1012U_EQ_1012(...) \, +#define Z_IS_1012_EQ_1012U(...) \, +#define Z_IS_1012U_EQ_1012U(...) \, +#define Z_IS_1013_EQ_1013(...) \, +#define Z_IS_1013U_EQ_1013(...) \, +#define Z_IS_1013_EQ_1013U(...) \, +#define Z_IS_1013U_EQ_1013U(...) \, +#define Z_IS_1014_EQ_1014(...) \, +#define Z_IS_1014U_EQ_1014(...) \, +#define Z_IS_1014_EQ_1014U(...) \, +#define Z_IS_1014U_EQ_1014U(...) \, +#define Z_IS_1015_EQ_1015(...) \, +#define Z_IS_1015U_EQ_1015(...) \, +#define Z_IS_1015_EQ_1015U(...) \, +#define Z_IS_1015U_EQ_1015U(...) \, +#define Z_IS_1016_EQ_1016(...) \, +#define Z_IS_1016U_EQ_1016(...) \, +#define Z_IS_1016_EQ_1016U(...) \, +#define Z_IS_1016U_EQ_1016U(...) \, +#define Z_IS_1017_EQ_1017(...) \, +#define Z_IS_1017U_EQ_1017(...) \, +#define Z_IS_1017_EQ_1017U(...) \, +#define Z_IS_1017U_EQ_1017U(...) \, +#define Z_IS_1018_EQ_1018(...) \, +#define Z_IS_1018U_EQ_1018(...) \, +#define Z_IS_1018_EQ_1018U(...) \, +#define Z_IS_1018U_EQ_1018U(...) \, +#define Z_IS_1019_EQ_1019(...) \, +#define Z_IS_1019U_EQ_1019(...) \, +#define Z_IS_1019_EQ_1019U(...) \, +#define Z_IS_1019U_EQ_1019U(...) \, +#define Z_IS_1020_EQ_1020(...) \, +#define Z_IS_1020U_EQ_1020(...) \, +#define Z_IS_1020_EQ_1020U(...) \, +#define Z_IS_1020U_EQ_1020U(...) \, +#define Z_IS_1021_EQ_1021(...) \, +#define Z_IS_1021U_EQ_1021(...) \, +#define Z_IS_1021_EQ_1021U(...) \, +#define Z_IS_1021U_EQ_1021U(...) \, +#define Z_IS_1022_EQ_1022(...) \, +#define Z_IS_1022U_EQ_1022(...) \, +#define Z_IS_1022_EQ_1022U(...) \, +#define Z_IS_1022U_EQ_1022U(...) \, +#define Z_IS_1023_EQ_1023(...) \, +#define Z_IS_1023U_EQ_1023(...) \, +#define Z_IS_1023_EQ_1023U(...) \, +#define Z_IS_1023U_EQ_1023U(...) \, +#define Z_IS_1024_EQ_1024(...) \, +#define Z_IS_1024U_EQ_1024(...) \, +#define Z_IS_1024_EQ_1024U(...) \, +#define Z_IS_1024U_EQ_1024U(...) \, +#define Z_IS_1025_EQ_1025(...) \, +#define Z_IS_1025U_EQ_1025(...) \, +#define Z_IS_1025_EQ_1025U(...) \, +#define Z_IS_1025U_EQ_1025U(...) \, +#define Z_IS_1026_EQ_1026(...) \, +#define Z_IS_1026U_EQ_1026(...) \, +#define Z_IS_1026_EQ_1026U(...) \, +#define Z_IS_1026U_EQ_1026U(...) \, +#define Z_IS_1027_EQ_1027(...) \, +#define Z_IS_1027U_EQ_1027(...) \, +#define Z_IS_1027_EQ_1027U(...) \, +#define Z_IS_1027U_EQ_1027U(...) \, +#define Z_IS_1028_EQ_1028(...) \, +#define Z_IS_1028U_EQ_1028(...) \, +#define Z_IS_1028_EQ_1028U(...) \, +#define Z_IS_1028U_EQ_1028U(...) \, +#define Z_IS_1029_EQ_1029(...) \, +#define Z_IS_1029U_EQ_1029(...) \, +#define Z_IS_1029_EQ_1029U(...) \, +#define Z_IS_1029U_EQ_1029U(...) \, +#define Z_IS_1030_EQ_1030(...) \, +#define Z_IS_1030U_EQ_1030(...) \, +#define Z_IS_1030_EQ_1030U(...) \, +#define Z_IS_1030U_EQ_1030U(...) \, +#define Z_IS_1031_EQ_1031(...) \, +#define Z_IS_1031U_EQ_1031(...) \, +#define Z_IS_1031_EQ_1031U(...) \, +#define Z_IS_1031U_EQ_1031U(...) \, +#define Z_IS_1032_EQ_1032(...) \, +#define Z_IS_1032U_EQ_1032(...) \, +#define Z_IS_1032_EQ_1032U(...) \, +#define Z_IS_1032U_EQ_1032U(...) \, +#define Z_IS_1033_EQ_1033(...) \, +#define Z_IS_1033U_EQ_1033(...) \, +#define Z_IS_1033_EQ_1033U(...) \, +#define Z_IS_1033U_EQ_1033U(...) \, +#define Z_IS_1034_EQ_1034(...) \, +#define Z_IS_1034U_EQ_1034(...) \, +#define Z_IS_1034_EQ_1034U(...) \, +#define Z_IS_1034U_EQ_1034U(...) \, +#define Z_IS_1035_EQ_1035(...) \, +#define Z_IS_1035U_EQ_1035(...) \, +#define Z_IS_1035_EQ_1035U(...) \, +#define Z_IS_1035U_EQ_1035U(...) \, +#define Z_IS_1036_EQ_1036(...) \, +#define Z_IS_1036U_EQ_1036(...) \, +#define Z_IS_1036_EQ_1036U(...) \, +#define Z_IS_1036U_EQ_1036U(...) \, +#define Z_IS_1037_EQ_1037(...) \, +#define Z_IS_1037U_EQ_1037(...) \, +#define Z_IS_1037_EQ_1037U(...) \, +#define Z_IS_1037U_EQ_1037U(...) \, +#define Z_IS_1038_EQ_1038(...) \, +#define Z_IS_1038U_EQ_1038(...) \, +#define Z_IS_1038_EQ_1038U(...) \, +#define Z_IS_1038U_EQ_1038U(...) \, +#define Z_IS_1039_EQ_1039(...) \, +#define Z_IS_1039U_EQ_1039(...) \, +#define Z_IS_1039_EQ_1039U(...) \, +#define Z_IS_1039U_EQ_1039U(...) \, +#define Z_IS_1040_EQ_1040(...) \, +#define Z_IS_1040U_EQ_1040(...) \, +#define Z_IS_1040_EQ_1040U(...) \, +#define Z_IS_1040U_EQ_1040U(...) \, +#define Z_IS_1041_EQ_1041(...) \, +#define Z_IS_1041U_EQ_1041(...) \, +#define Z_IS_1041_EQ_1041U(...) \, +#define Z_IS_1041U_EQ_1041U(...) \, +#define Z_IS_1042_EQ_1042(...) \, +#define Z_IS_1042U_EQ_1042(...) \, +#define Z_IS_1042_EQ_1042U(...) \, +#define Z_IS_1042U_EQ_1042U(...) \, +#define Z_IS_1043_EQ_1043(...) \, +#define Z_IS_1043U_EQ_1043(...) \, +#define Z_IS_1043_EQ_1043U(...) \, +#define Z_IS_1043U_EQ_1043U(...) \, +#define Z_IS_1044_EQ_1044(...) \, +#define Z_IS_1044U_EQ_1044(...) \, +#define Z_IS_1044_EQ_1044U(...) \, +#define Z_IS_1044U_EQ_1044U(...) \, +#define Z_IS_1045_EQ_1045(...) \, +#define Z_IS_1045U_EQ_1045(...) \, +#define Z_IS_1045_EQ_1045U(...) \, +#define Z_IS_1045U_EQ_1045U(...) \, +#define Z_IS_1046_EQ_1046(...) \, +#define Z_IS_1046U_EQ_1046(...) \, +#define Z_IS_1046_EQ_1046U(...) \, +#define Z_IS_1046U_EQ_1046U(...) \, +#define Z_IS_1047_EQ_1047(...) \, +#define Z_IS_1047U_EQ_1047(...) \, +#define Z_IS_1047_EQ_1047U(...) \, +#define Z_IS_1047U_EQ_1047U(...) \, +#define Z_IS_1048_EQ_1048(...) \, +#define Z_IS_1048U_EQ_1048(...) \, +#define Z_IS_1048_EQ_1048U(...) \, +#define Z_IS_1048U_EQ_1048U(...) \, +#define Z_IS_1049_EQ_1049(...) \, +#define Z_IS_1049U_EQ_1049(...) \, +#define Z_IS_1049_EQ_1049U(...) \, +#define Z_IS_1049U_EQ_1049U(...) \, +#define Z_IS_1050_EQ_1050(...) \, +#define Z_IS_1050U_EQ_1050(...) \, +#define Z_IS_1050_EQ_1050U(...) \, +#define Z_IS_1050U_EQ_1050U(...) \, +#define Z_IS_1051_EQ_1051(...) \, +#define Z_IS_1051U_EQ_1051(...) \, +#define Z_IS_1051_EQ_1051U(...) \, +#define Z_IS_1051U_EQ_1051U(...) \, +#define Z_IS_1052_EQ_1052(...) \, +#define Z_IS_1052U_EQ_1052(...) \, +#define Z_IS_1052_EQ_1052U(...) \, +#define Z_IS_1052U_EQ_1052U(...) \, +#define Z_IS_1053_EQ_1053(...) \, +#define Z_IS_1053U_EQ_1053(...) \, +#define Z_IS_1053_EQ_1053U(...) \, +#define Z_IS_1053U_EQ_1053U(...) \, +#define Z_IS_1054_EQ_1054(...) \, +#define Z_IS_1054U_EQ_1054(...) \, +#define Z_IS_1054_EQ_1054U(...) \, +#define Z_IS_1054U_EQ_1054U(...) \, +#define Z_IS_1055_EQ_1055(...) \, +#define Z_IS_1055U_EQ_1055(...) \, +#define Z_IS_1055_EQ_1055U(...) \, +#define Z_IS_1055U_EQ_1055U(...) \, +#define Z_IS_1056_EQ_1056(...) \, +#define Z_IS_1056U_EQ_1056(...) \, +#define Z_IS_1056_EQ_1056U(...) \, +#define Z_IS_1056U_EQ_1056U(...) \, +#define Z_IS_1057_EQ_1057(...) \, +#define Z_IS_1057U_EQ_1057(...) \, +#define Z_IS_1057_EQ_1057U(...) \, +#define Z_IS_1057U_EQ_1057U(...) \, +#define Z_IS_1058_EQ_1058(...) \, +#define Z_IS_1058U_EQ_1058(...) \, +#define Z_IS_1058_EQ_1058U(...) \, +#define Z_IS_1058U_EQ_1058U(...) \, +#define Z_IS_1059_EQ_1059(...) \, +#define Z_IS_1059U_EQ_1059(...) \, +#define Z_IS_1059_EQ_1059U(...) \, +#define Z_IS_1059U_EQ_1059U(...) \, +#define Z_IS_1060_EQ_1060(...) \, +#define Z_IS_1060U_EQ_1060(...) \, +#define Z_IS_1060_EQ_1060U(...) \, +#define Z_IS_1060U_EQ_1060U(...) \, +#define Z_IS_1061_EQ_1061(...) \, +#define Z_IS_1061U_EQ_1061(...) \, +#define Z_IS_1061_EQ_1061U(...) \, +#define Z_IS_1061U_EQ_1061U(...) \, +#define Z_IS_1062_EQ_1062(...) \, +#define Z_IS_1062U_EQ_1062(...) \, +#define Z_IS_1062_EQ_1062U(...) \, +#define Z_IS_1062U_EQ_1062U(...) \, +#define Z_IS_1063_EQ_1063(...) \, +#define Z_IS_1063U_EQ_1063(...) \, +#define Z_IS_1063_EQ_1063U(...) \, +#define Z_IS_1063U_EQ_1063U(...) \, +#define Z_IS_1064_EQ_1064(...) \, +#define Z_IS_1064U_EQ_1064(...) \, +#define Z_IS_1064_EQ_1064U(...) \, +#define Z_IS_1064U_EQ_1064U(...) \, +#define Z_IS_1065_EQ_1065(...) \, +#define Z_IS_1065U_EQ_1065(...) \, +#define Z_IS_1065_EQ_1065U(...) \, +#define Z_IS_1065U_EQ_1065U(...) \, +#define Z_IS_1066_EQ_1066(...) \, +#define Z_IS_1066U_EQ_1066(...) \, +#define Z_IS_1066_EQ_1066U(...) \, +#define Z_IS_1066U_EQ_1066U(...) \, +#define Z_IS_1067_EQ_1067(...) \, +#define Z_IS_1067U_EQ_1067(...) \, +#define Z_IS_1067_EQ_1067U(...) \, +#define Z_IS_1067U_EQ_1067U(...) \, +#define Z_IS_1068_EQ_1068(...) \, +#define Z_IS_1068U_EQ_1068(...) \, +#define Z_IS_1068_EQ_1068U(...) \, +#define Z_IS_1068U_EQ_1068U(...) \, +#define Z_IS_1069_EQ_1069(...) \, +#define Z_IS_1069U_EQ_1069(...) \, +#define Z_IS_1069_EQ_1069U(...) \, +#define Z_IS_1069U_EQ_1069U(...) \, +#define Z_IS_1070_EQ_1070(...) \, +#define Z_IS_1070U_EQ_1070(...) \, +#define Z_IS_1070_EQ_1070U(...) \, +#define Z_IS_1070U_EQ_1070U(...) \, +#define Z_IS_1071_EQ_1071(...) \, +#define Z_IS_1071U_EQ_1071(...) \, +#define Z_IS_1071_EQ_1071U(...) \, +#define Z_IS_1071U_EQ_1071U(...) \, +#define Z_IS_1072_EQ_1072(...) \, +#define Z_IS_1072U_EQ_1072(...) \, +#define Z_IS_1072_EQ_1072U(...) \, +#define Z_IS_1072U_EQ_1072U(...) \, +#define Z_IS_1073_EQ_1073(...) \, +#define Z_IS_1073U_EQ_1073(...) \, +#define Z_IS_1073_EQ_1073U(...) \, +#define Z_IS_1073U_EQ_1073U(...) \, +#define Z_IS_1074_EQ_1074(...) \, +#define Z_IS_1074U_EQ_1074(...) \, +#define Z_IS_1074_EQ_1074U(...) \, +#define Z_IS_1074U_EQ_1074U(...) \, +#define Z_IS_1075_EQ_1075(...) \, +#define Z_IS_1075U_EQ_1075(...) \, +#define Z_IS_1075_EQ_1075U(...) \, +#define Z_IS_1075U_EQ_1075U(...) \, +#define Z_IS_1076_EQ_1076(...) \, +#define Z_IS_1076U_EQ_1076(...) \, +#define Z_IS_1076_EQ_1076U(...) \, +#define Z_IS_1076U_EQ_1076U(...) \, +#define Z_IS_1077_EQ_1077(...) \, +#define Z_IS_1077U_EQ_1077(...) \, +#define Z_IS_1077_EQ_1077U(...) \, +#define Z_IS_1077U_EQ_1077U(...) \, +#define Z_IS_1078_EQ_1078(...) \, +#define Z_IS_1078U_EQ_1078(...) \, +#define Z_IS_1078_EQ_1078U(...) \, +#define Z_IS_1078U_EQ_1078U(...) \, +#define Z_IS_1079_EQ_1079(...) \, +#define Z_IS_1079U_EQ_1079(...) \, +#define Z_IS_1079_EQ_1079U(...) \, +#define Z_IS_1079U_EQ_1079U(...) \, +#define Z_IS_1080_EQ_1080(...) \, +#define Z_IS_1080U_EQ_1080(...) \, +#define Z_IS_1080_EQ_1080U(...) \, +#define Z_IS_1080U_EQ_1080U(...) \, +#define Z_IS_1081_EQ_1081(...) \, +#define Z_IS_1081U_EQ_1081(...) \, +#define Z_IS_1081_EQ_1081U(...) \, +#define Z_IS_1081U_EQ_1081U(...) \, +#define Z_IS_1082_EQ_1082(...) \, +#define Z_IS_1082U_EQ_1082(...) \, +#define Z_IS_1082_EQ_1082U(...) \, +#define Z_IS_1082U_EQ_1082U(...) \, +#define Z_IS_1083_EQ_1083(...) \, +#define Z_IS_1083U_EQ_1083(...) \, +#define Z_IS_1083_EQ_1083U(...) \, +#define Z_IS_1083U_EQ_1083U(...) \, +#define Z_IS_1084_EQ_1084(...) \, +#define Z_IS_1084U_EQ_1084(...) \, +#define Z_IS_1084_EQ_1084U(...) \, +#define Z_IS_1084U_EQ_1084U(...) \, +#define Z_IS_1085_EQ_1085(...) \, +#define Z_IS_1085U_EQ_1085(...) \, +#define Z_IS_1085_EQ_1085U(...) \, +#define Z_IS_1085U_EQ_1085U(...) \, +#define Z_IS_1086_EQ_1086(...) \, +#define Z_IS_1086U_EQ_1086(...) \, +#define Z_IS_1086_EQ_1086U(...) \, +#define Z_IS_1086U_EQ_1086U(...) \, +#define Z_IS_1087_EQ_1087(...) \, +#define Z_IS_1087U_EQ_1087(...) \, +#define Z_IS_1087_EQ_1087U(...) \, +#define Z_IS_1087U_EQ_1087U(...) \, +#define Z_IS_1088_EQ_1088(...) \, +#define Z_IS_1088U_EQ_1088(...) \, +#define Z_IS_1088_EQ_1088U(...) \, +#define Z_IS_1088U_EQ_1088U(...) \, +#define Z_IS_1089_EQ_1089(...) \, +#define Z_IS_1089U_EQ_1089(...) \, +#define Z_IS_1089_EQ_1089U(...) \, +#define Z_IS_1089U_EQ_1089U(...) \, +#define Z_IS_1090_EQ_1090(...) \, +#define Z_IS_1090U_EQ_1090(...) \, +#define Z_IS_1090_EQ_1090U(...) \, +#define Z_IS_1090U_EQ_1090U(...) \, +#define Z_IS_1091_EQ_1091(...) \, +#define Z_IS_1091U_EQ_1091(...) \, +#define Z_IS_1091_EQ_1091U(...) \, +#define Z_IS_1091U_EQ_1091U(...) \, +#define Z_IS_1092_EQ_1092(...) \, +#define Z_IS_1092U_EQ_1092(...) \, +#define Z_IS_1092_EQ_1092U(...) \, +#define Z_IS_1092U_EQ_1092U(...) \, +#define Z_IS_1093_EQ_1093(...) \, +#define Z_IS_1093U_EQ_1093(...) \, +#define Z_IS_1093_EQ_1093U(...) \, +#define Z_IS_1093U_EQ_1093U(...) \, +#define Z_IS_1094_EQ_1094(...) \, +#define Z_IS_1094U_EQ_1094(...) \, +#define Z_IS_1094_EQ_1094U(...) \, +#define Z_IS_1094U_EQ_1094U(...) \, +#define Z_IS_1095_EQ_1095(...) \, +#define Z_IS_1095U_EQ_1095(...) \, +#define Z_IS_1095_EQ_1095U(...) \, +#define Z_IS_1095U_EQ_1095U(...) \, +#define Z_IS_1096_EQ_1096(...) \, +#define Z_IS_1096U_EQ_1096(...) \, +#define Z_IS_1096_EQ_1096U(...) \, +#define Z_IS_1096U_EQ_1096U(...) \, +#define Z_IS_1097_EQ_1097(...) \, +#define Z_IS_1097U_EQ_1097(...) \, +#define Z_IS_1097_EQ_1097U(...) \, +#define Z_IS_1097U_EQ_1097U(...) \, +#define Z_IS_1098_EQ_1098(...) \, +#define Z_IS_1098U_EQ_1098(...) \, +#define Z_IS_1098_EQ_1098U(...) \, +#define Z_IS_1098U_EQ_1098U(...) \, +#define Z_IS_1099_EQ_1099(...) \, +#define Z_IS_1099U_EQ_1099(...) \, +#define Z_IS_1099_EQ_1099U(...) \, +#define Z_IS_1099U_EQ_1099U(...) \, +#define Z_IS_1100_EQ_1100(...) \, +#define Z_IS_1100U_EQ_1100(...) \, +#define Z_IS_1100_EQ_1100U(...) \, +#define Z_IS_1100U_EQ_1100U(...) \, +#define Z_IS_1101_EQ_1101(...) \, +#define Z_IS_1101U_EQ_1101(...) \, +#define Z_IS_1101_EQ_1101U(...) \, +#define Z_IS_1101U_EQ_1101U(...) \, +#define Z_IS_1102_EQ_1102(...) \, +#define Z_IS_1102U_EQ_1102(...) \, +#define Z_IS_1102_EQ_1102U(...) \, +#define Z_IS_1102U_EQ_1102U(...) \, +#define Z_IS_1103_EQ_1103(...) \, +#define Z_IS_1103U_EQ_1103(...) \, +#define Z_IS_1103_EQ_1103U(...) \, +#define Z_IS_1103U_EQ_1103U(...) \, +#define Z_IS_1104_EQ_1104(...) \, +#define Z_IS_1104U_EQ_1104(...) \, +#define Z_IS_1104_EQ_1104U(...) \, +#define Z_IS_1104U_EQ_1104U(...) \, +#define Z_IS_1105_EQ_1105(...) \, +#define Z_IS_1105U_EQ_1105(...) \, +#define Z_IS_1105_EQ_1105U(...) \, +#define Z_IS_1105U_EQ_1105U(...) \, +#define Z_IS_1106_EQ_1106(...) \, +#define Z_IS_1106U_EQ_1106(...) \, +#define Z_IS_1106_EQ_1106U(...) \, +#define Z_IS_1106U_EQ_1106U(...) \, +#define Z_IS_1107_EQ_1107(...) \, +#define Z_IS_1107U_EQ_1107(...) \, +#define Z_IS_1107_EQ_1107U(...) \, +#define Z_IS_1107U_EQ_1107U(...) \, +#define Z_IS_1108_EQ_1108(...) \, +#define Z_IS_1108U_EQ_1108(...) \, +#define Z_IS_1108_EQ_1108U(...) \, +#define Z_IS_1108U_EQ_1108U(...) \, +#define Z_IS_1109_EQ_1109(...) \, +#define Z_IS_1109U_EQ_1109(...) \, +#define Z_IS_1109_EQ_1109U(...) \, +#define Z_IS_1109U_EQ_1109U(...) \, +#define Z_IS_1110_EQ_1110(...) \, +#define Z_IS_1110U_EQ_1110(...) \, +#define Z_IS_1110_EQ_1110U(...) \, +#define Z_IS_1110U_EQ_1110U(...) \, +#define Z_IS_1111_EQ_1111(...) \, +#define Z_IS_1111U_EQ_1111(...) \, +#define Z_IS_1111_EQ_1111U(...) \, +#define Z_IS_1111U_EQ_1111U(...) \, +#define Z_IS_1112_EQ_1112(...) \, +#define Z_IS_1112U_EQ_1112(...) \, +#define Z_IS_1112_EQ_1112U(...) \, +#define Z_IS_1112U_EQ_1112U(...) \, +#define Z_IS_1113_EQ_1113(...) \, +#define Z_IS_1113U_EQ_1113(...) \, +#define Z_IS_1113_EQ_1113U(...) \, +#define Z_IS_1113U_EQ_1113U(...) \, +#define Z_IS_1114_EQ_1114(...) \, +#define Z_IS_1114U_EQ_1114(...) \, +#define Z_IS_1114_EQ_1114U(...) \, +#define Z_IS_1114U_EQ_1114U(...) \, +#define Z_IS_1115_EQ_1115(...) \, +#define Z_IS_1115U_EQ_1115(...) \, +#define Z_IS_1115_EQ_1115U(...) \, +#define Z_IS_1115U_EQ_1115U(...) \, +#define Z_IS_1116_EQ_1116(...) \, +#define Z_IS_1116U_EQ_1116(...) \, +#define Z_IS_1116_EQ_1116U(...) \, +#define Z_IS_1116U_EQ_1116U(...) \, +#define Z_IS_1117_EQ_1117(...) \, +#define Z_IS_1117U_EQ_1117(...) \, +#define Z_IS_1117_EQ_1117U(...) \, +#define Z_IS_1117U_EQ_1117U(...) \, +#define Z_IS_1118_EQ_1118(...) \, +#define Z_IS_1118U_EQ_1118(...) \, +#define Z_IS_1118_EQ_1118U(...) \, +#define Z_IS_1118U_EQ_1118U(...) \, +#define Z_IS_1119_EQ_1119(...) \, +#define Z_IS_1119U_EQ_1119(...) \, +#define Z_IS_1119_EQ_1119U(...) \, +#define Z_IS_1119U_EQ_1119U(...) \, +#define Z_IS_1120_EQ_1120(...) \, +#define Z_IS_1120U_EQ_1120(...) \, +#define Z_IS_1120_EQ_1120U(...) \, +#define Z_IS_1120U_EQ_1120U(...) \, +#define Z_IS_1121_EQ_1121(...) \, +#define Z_IS_1121U_EQ_1121(...) \, +#define Z_IS_1121_EQ_1121U(...) \, +#define Z_IS_1121U_EQ_1121U(...) \, +#define Z_IS_1122_EQ_1122(...) \, +#define Z_IS_1122U_EQ_1122(...) \, +#define Z_IS_1122_EQ_1122U(...) \, +#define Z_IS_1122U_EQ_1122U(...) \, +#define Z_IS_1123_EQ_1123(...) \, +#define Z_IS_1123U_EQ_1123(...) \, +#define Z_IS_1123_EQ_1123U(...) \, +#define Z_IS_1123U_EQ_1123U(...) \, +#define Z_IS_1124_EQ_1124(...) \, +#define Z_IS_1124U_EQ_1124(...) \, +#define Z_IS_1124_EQ_1124U(...) \, +#define Z_IS_1124U_EQ_1124U(...) \, +#define Z_IS_1125_EQ_1125(...) \, +#define Z_IS_1125U_EQ_1125(...) \, +#define Z_IS_1125_EQ_1125U(...) \, +#define Z_IS_1125U_EQ_1125U(...) \, +#define Z_IS_1126_EQ_1126(...) \, +#define Z_IS_1126U_EQ_1126(...) \, +#define Z_IS_1126_EQ_1126U(...) \, +#define Z_IS_1126U_EQ_1126U(...) \, +#define Z_IS_1127_EQ_1127(...) \, +#define Z_IS_1127U_EQ_1127(...) \, +#define Z_IS_1127_EQ_1127U(...) \, +#define Z_IS_1127U_EQ_1127U(...) \, +#define Z_IS_1128_EQ_1128(...) \, +#define Z_IS_1128U_EQ_1128(...) \, +#define Z_IS_1128_EQ_1128U(...) \, +#define Z_IS_1128U_EQ_1128U(...) \, +#define Z_IS_1129_EQ_1129(...) \, +#define Z_IS_1129U_EQ_1129(...) \, +#define Z_IS_1129_EQ_1129U(...) \, +#define Z_IS_1129U_EQ_1129U(...) \, +#define Z_IS_1130_EQ_1130(...) \, +#define Z_IS_1130U_EQ_1130(...) \, +#define Z_IS_1130_EQ_1130U(...) \, +#define Z_IS_1130U_EQ_1130U(...) \, +#define Z_IS_1131_EQ_1131(...) \, +#define Z_IS_1131U_EQ_1131(...) \, +#define Z_IS_1131_EQ_1131U(...) \, +#define Z_IS_1131U_EQ_1131U(...) \, +#define Z_IS_1132_EQ_1132(...) \, +#define Z_IS_1132U_EQ_1132(...) \, +#define Z_IS_1132_EQ_1132U(...) \, +#define Z_IS_1132U_EQ_1132U(...) \, +#define Z_IS_1133_EQ_1133(...) \, +#define Z_IS_1133U_EQ_1133(...) \, +#define Z_IS_1133_EQ_1133U(...) \, +#define Z_IS_1133U_EQ_1133U(...) \, +#define Z_IS_1134_EQ_1134(...) \, +#define Z_IS_1134U_EQ_1134(...) \, +#define Z_IS_1134_EQ_1134U(...) \, +#define Z_IS_1134U_EQ_1134U(...) \, +#define Z_IS_1135_EQ_1135(...) \, +#define Z_IS_1135U_EQ_1135(...) \, +#define Z_IS_1135_EQ_1135U(...) \, +#define Z_IS_1135U_EQ_1135U(...) \, +#define Z_IS_1136_EQ_1136(...) \, +#define Z_IS_1136U_EQ_1136(...) \, +#define Z_IS_1136_EQ_1136U(...) \, +#define Z_IS_1136U_EQ_1136U(...) \, +#define Z_IS_1137_EQ_1137(...) \, +#define Z_IS_1137U_EQ_1137(...) \, +#define Z_IS_1137_EQ_1137U(...) \, +#define Z_IS_1137U_EQ_1137U(...) \, +#define Z_IS_1138_EQ_1138(...) \, +#define Z_IS_1138U_EQ_1138(...) \, +#define Z_IS_1138_EQ_1138U(...) \, +#define Z_IS_1138U_EQ_1138U(...) \, +#define Z_IS_1139_EQ_1139(...) \, +#define Z_IS_1139U_EQ_1139(...) \, +#define Z_IS_1139_EQ_1139U(...) \, +#define Z_IS_1139U_EQ_1139U(...) \, +#define Z_IS_1140_EQ_1140(...) \, +#define Z_IS_1140U_EQ_1140(...) \, +#define Z_IS_1140_EQ_1140U(...) \, +#define Z_IS_1140U_EQ_1140U(...) \, +#define Z_IS_1141_EQ_1141(...) \, +#define Z_IS_1141U_EQ_1141(...) \, +#define Z_IS_1141_EQ_1141U(...) \, +#define Z_IS_1141U_EQ_1141U(...) \, +#define Z_IS_1142_EQ_1142(...) \, +#define Z_IS_1142U_EQ_1142(...) \, +#define Z_IS_1142_EQ_1142U(...) \, +#define Z_IS_1142U_EQ_1142U(...) \, +#define Z_IS_1143_EQ_1143(...) \, +#define Z_IS_1143U_EQ_1143(...) \, +#define Z_IS_1143_EQ_1143U(...) \, +#define Z_IS_1143U_EQ_1143U(...) \, +#define Z_IS_1144_EQ_1144(...) \, +#define Z_IS_1144U_EQ_1144(...) \, +#define Z_IS_1144_EQ_1144U(...) \, +#define Z_IS_1144U_EQ_1144U(...) \, +#define Z_IS_1145_EQ_1145(...) \, +#define Z_IS_1145U_EQ_1145(...) \, +#define Z_IS_1145_EQ_1145U(...) \, +#define Z_IS_1145U_EQ_1145U(...) \, +#define Z_IS_1146_EQ_1146(...) \, +#define Z_IS_1146U_EQ_1146(...) \, +#define Z_IS_1146_EQ_1146U(...) \, +#define Z_IS_1146U_EQ_1146U(...) \, +#define Z_IS_1147_EQ_1147(...) \, +#define Z_IS_1147U_EQ_1147(...) \, +#define Z_IS_1147_EQ_1147U(...) \, +#define Z_IS_1147U_EQ_1147U(...) \, +#define Z_IS_1148_EQ_1148(...) \, +#define Z_IS_1148U_EQ_1148(...) \, +#define Z_IS_1148_EQ_1148U(...) \, +#define Z_IS_1148U_EQ_1148U(...) \, +#define Z_IS_1149_EQ_1149(...) \, +#define Z_IS_1149U_EQ_1149(...) \, +#define Z_IS_1149_EQ_1149U(...) \, +#define Z_IS_1149U_EQ_1149U(...) \, +#define Z_IS_1150_EQ_1150(...) \, +#define Z_IS_1150U_EQ_1150(...) \, +#define Z_IS_1150_EQ_1150U(...) \, +#define Z_IS_1150U_EQ_1150U(...) \, +#define Z_IS_1151_EQ_1151(...) \, +#define Z_IS_1151U_EQ_1151(...) \, +#define Z_IS_1151_EQ_1151U(...) \, +#define Z_IS_1151U_EQ_1151U(...) \, +#define Z_IS_1152_EQ_1152(...) \, +#define Z_IS_1152U_EQ_1152(...) \, +#define Z_IS_1152_EQ_1152U(...) \, +#define Z_IS_1152U_EQ_1152U(...) \, +#define Z_IS_1153_EQ_1153(...) \, +#define Z_IS_1153U_EQ_1153(...) \, +#define Z_IS_1153_EQ_1153U(...) \, +#define Z_IS_1153U_EQ_1153U(...) \, +#define Z_IS_1154_EQ_1154(...) \, +#define Z_IS_1154U_EQ_1154(...) \, +#define Z_IS_1154_EQ_1154U(...) \, +#define Z_IS_1154U_EQ_1154U(...) \, +#define Z_IS_1155_EQ_1155(...) \, +#define Z_IS_1155U_EQ_1155(...) \, +#define Z_IS_1155_EQ_1155U(...) \, +#define Z_IS_1155U_EQ_1155U(...) \, +#define Z_IS_1156_EQ_1156(...) \, +#define Z_IS_1156U_EQ_1156(...) \, +#define Z_IS_1156_EQ_1156U(...) \, +#define Z_IS_1156U_EQ_1156U(...) \, +#define Z_IS_1157_EQ_1157(...) \, +#define Z_IS_1157U_EQ_1157(...) \, +#define Z_IS_1157_EQ_1157U(...) \, +#define Z_IS_1157U_EQ_1157U(...) \, +#define Z_IS_1158_EQ_1158(...) \, +#define Z_IS_1158U_EQ_1158(...) \, +#define Z_IS_1158_EQ_1158U(...) \, +#define Z_IS_1158U_EQ_1158U(...) \, +#define Z_IS_1159_EQ_1159(...) \, +#define Z_IS_1159U_EQ_1159(...) \, +#define Z_IS_1159_EQ_1159U(...) \, +#define Z_IS_1159U_EQ_1159U(...) \, +#define Z_IS_1160_EQ_1160(...) \, +#define Z_IS_1160U_EQ_1160(...) \, +#define Z_IS_1160_EQ_1160U(...) \, +#define Z_IS_1160U_EQ_1160U(...) \, +#define Z_IS_1161_EQ_1161(...) \, +#define Z_IS_1161U_EQ_1161(...) \, +#define Z_IS_1161_EQ_1161U(...) \, +#define Z_IS_1161U_EQ_1161U(...) \, +#define Z_IS_1162_EQ_1162(...) \, +#define Z_IS_1162U_EQ_1162(...) \, +#define Z_IS_1162_EQ_1162U(...) \, +#define Z_IS_1162U_EQ_1162U(...) \, +#define Z_IS_1163_EQ_1163(...) \, +#define Z_IS_1163U_EQ_1163(...) \, +#define Z_IS_1163_EQ_1163U(...) \, +#define Z_IS_1163U_EQ_1163U(...) \, +#define Z_IS_1164_EQ_1164(...) \, +#define Z_IS_1164U_EQ_1164(...) \, +#define Z_IS_1164_EQ_1164U(...) \, +#define Z_IS_1164U_EQ_1164U(...) \, +#define Z_IS_1165_EQ_1165(...) \, +#define Z_IS_1165U_EQ_1165(...) \, +#define Z_IS_1165_EQ_1165U(...) \, +#define Z_IS_1165U_EQ_1165U(...) \, +#define Z_IS_1166_EQ_1166(...) \, +#define Z_IS_1166U_EQ_1166(...) \, +#define Z_IS_1166_EQ_1166U(...) \, +#define Z_IS_1166U_EQ_1166U(...) \, +#define Z_IS_1167_EQ_1167(...) \, +#define Z_IS_1167U_EQ_1167(...) \, +#define Z_IS_1167_EQ_1167U(...) \, +#define Z_IS_1167U_EQ_1167U(...) \, +#define Z_IS_1168_EQ_1168(...) \, +#define Z_IS_1168U_EQ_1168(...) \, +#define Z_IS_1168_EQ_1168U(...) \, +#define Z_IS_1168U_EQ_1168U(...) \, +#define Z_IS_1169_EQ_1169(...) \, +#define Z_IS_1169U_EQ_1169(...) \, +#define Z_IS_1169_EQ_1169U(...) \, +#define Z_IS_1169U_EQ_1169U(...) \, +#define Z_IS_1170_EQ_1170(...) \, +#define Z_IS_1170U_EQ_1170(...) \, +#define Z_IS_1170_EQ_1170U(...) \, +#define Z_IS_1170U_EQ_1170U(...) \, +#define Z_IS_1171_EQ_1171(...) \, +#define Z_IS_1171U_EQ_1171(...) \, +#define Z_IS_1171_EQ_1171U(...) \, +#define Z_IS_1171U_EQ_1171U(...) \, +#define Z_IS_1172_EQ_1172(...) \, +#define Z_IS_1172U_EQ_1172(...) \, +#define Z_IS_1172_EQ_1172U(...) \, +#define Z_IS_1172U_EQ_1172U(...) \, +#define Z_IS_1173_EQ_1173(...) \, +#define Z_IS_1173U_EQ_1173(...) \, +#define Z_IS_1173_EQ_1173U(...) \, +#define Z_IS_1173U_EQ_1173U(...) \, +#define Z_IS_1174_EQ_1174(...) \, +#define Z_IS_1174U_EQ_1174(...) \, +#define Z_IS_1174_EQ_1174U(...) \, +#define Z_IS_1174U_EQ_1174U(...) \, +#define Z_IS_1175_EQ_1175(...) \, +#define Z_IS_1175U_EQ_1175(...) \, +#define Z_IS_1175_EQ_1175U(...) \, +#define Z_IS_1175U_EQ_1175U(...) \, +#define Z_IS_1176_EQ_1176(...) \, +#define Z_IS_1176U_EQ_1176(...) \, +#define Z_IS_1176_EQ_1176U(...) \, +#define Z_IS_1176U_EQ_1176U(...) \, +#define Z_IS_1177_EQ_1177(...) \, +#define Z_IS_1177U_EQ_1177(...) \, +#define Z_IS_1177_EQ_1177U(...) \, +#define Z_IS_1177U_EQ_1177U(...) \, +#define Z_IS_1178_EQ_1178(...) \, +#define Z_IS_1178U_EQ_1178(...) \, +#define Z_IS_1178_EQ_1178U(...) \, +#define Z_IS_1178U_EQ_1178U(...) \, +#define Z_IS_1179_EQ_1179(...) \, +#define Z_IS_1179U_EQ_1179(...) \, +#define Z_IS_1179_EQ_1179U(...) \, +#define Z_IS_1179U_EQ_1179U(...) \, +#define Z_IS_1180_EQ_1180(...) \, +#define Z_IS_1180U_EQ_1180(...) \, +#define Z_IS_1180_EQ_1180U(...) \, +#define Z_IS_1180U_EQ_1180U(...) \, +#define Z_IS_1181_EQ_1181(...) \, +#define Z_IS_1181U_EQ_1181(...) \, +#define Z_IS_1181_EQ_1181U(...) \, +#define Z_IS_1181U_EQ_1181U(...) \, +#define Z_IS_1182_EQ_1182(...) \, +#define Z_IS_1182U_EQ_1182(...) \, +#define Z_IS_1182_EQ_1182U(...) \, +#define Z_IS_1182U_EQ_1182U(...) \, +#define Z_IS_1183_EQ_1183(...) \, +#define Z_IS_1183U_EQ_1183(...) \, +#define Z_IS_1183_EQ_1183U(...) \, +#define Z_IS_1183U_EQ_1183U(...) \, +#define Z_IS_1184_EQ_1184(...) \, +#define Z_IS_1184U_EQ_1184(...) \, +#define Z_IS_1184_EQ_1184U(...) \, +#define Z_IS_1184U_EQ_1184U(...) \, +#define Z_IS_1185_EQ_1185(...) \, +#define Z_IS_1185U_EQ_1185(...) \, +#define Z_IS_1185_EQ_1185U(...) \, +#define Z_IS_1185U_EQ_1185U(...) \, +#define Z_IS_1186_EQ_1186(...) \, +#define Z_IS_1186U_EQ_1186(...) \, +#define Z_IS_1186_EQ_1186U(...) \, +#define Z_IS_1186U_EQ_1186U(...) \, +#define Z_IS_1187_EQ_1187(...) \, +#define Z_IS_1187U_EQ_1187(...) \, +#define Z_IS_1187_EQ_1187U(...) \, +#define Z_IS_1187U_EQ_1187U(...) \, +#define Z_IS_1188_EQ_1188(...) \, +#define Z_IS_1188U_EQ_1188(...) \, +#define Z_IS_1188_EQ_1188U(...) \, +#define Z_IS_1188U_EQ_1188U(...) \, +#define Z_IS_1189_EQ_1189(...) \, +#define Z_IS_1189U_EQ_1189(...) \, +#define Z_IS_1189_EQ_1189U(...) \, +#define Z_IS_1189U_EQ_1189U(...) \, +#define Z_IS_1190_EQ_1190(...) \, +#define Z_IS_1190U_EQ_1190(...) \, +#define Z_IS_1190_EQ_1190U(...) \, +#define Z_IS_1190U_EQ_1190U(...) \, +#define Z_IS_1191_EQ_1191(...) \, +#define Z_IS_1191U_EQ_1191(...) \, +#define Z_IS_1191_EQ_1191U(...) \, +#define Z_IS_1191U_EQ_1191U(...) \, +#define Z_IS_1192_EQ_1192(...) \, +#define Z_IS_1192U_EQ_1192(...) \, +#define Z_IS_1192_EQ_1192U(...) \, +#define Z_IS_1192U_EQ_1192U(...) \, +#define Z_IS_1193_EQ_1193(...) \, +#define Z_IS_1193U_EQ_1193(...) \, +#define Z_IS_1193_EQ_1193U(...) \, +#define Z_IS_1193U_EQ_1193U(...) \, +#define Z_IS_1194_EQ_1194(...) \, +#define Z_IS_1194U_EQ_1194(...) \, +#define Z_IS_1194_EQ_1194U(...) \, +#define Z_IS_1194U_EQ_1194U(...) \, +#define Z_IS_1195_EQ_1195(...) \, +#define Z_IS_1195U_EQ_1195(...) \, +#define Z_IS_1195_EQ_1195U(...) \, +#define Z_IS_1195U_EQ_1195U(...) \, +#define Z_IS_1196_EQ_1196(...) \, +#define Z_IS_1196U_EQ_1196(...) \, +#define Z_IS_1196_EQ_1196U(...) \, +#define Z_IS_1196U_EQ_1196U(...) \, +#define Z_IS_1197_EQ_1197(...) \, +#define Z_IS_1197U_EQ_1197(...) \, +#define Z_IS_1197_EQ_1197U(...) \, +#define Z_IS_1197U_EQ_1197U(...) \, +#define Z_IS_1198_EQ_1198(...) \, +#define Z_IS_1198U_EQ_1198(...) \, +#define Z_IS_1198_EQ_1198U(...) \, +#define Z_IS_1198U_EQ_1198U(...) \, +#define Z_IS_1199_EQ_1199(...) \, +#define Z_IS_1199U_EQ_1199(...) \, +#define Z_IS_1199_EQ_1199U(...) \, +#define Z_IS_1199U_EQ_1199U(...) \, +#define Z_IS_1200_EQ_1200(...) \, +#define Z_IS_1200U_EQ_1200(...) \, +#define Z_IS_1200_EQ_1200U(...) \, +#define Z_IS_1200U_EQ_1200U(...) \, +#define Z_IS_1201_EQ_1201(...) \, +#define Z_IS_1201U_EQ_1201(...) \, +#define Z_IS_1201_EQ_1201U(...) \, +#define Z_IS_1201U_EQ_1201U(...) \, +#define Z_IS_1202_EQ_1202(...) \, +#define Z_IS_1202U_EQ_1202(...) \, +#define Z_IS_1202_EQ_1202U(...) \, +#define Z_IS_1202U_EQ_1202U(...) \, +#define Z_IS_1203_EQ_1203(...) \, +#define Z_IS_1203U_EQ_1203(...) \, +#define Z_IS_1203_EQ_1203U(...) \, +#define Z_IS_1203U_EQ_1203U(...) \, +#define Z_IS_1204_EQ_1204(...) \, +#define Z_IS_1204U_EQ_1204(...) \, +#define Z_IS_1204_EQ_1204U(...) \, +#define Z_IS_1204U_EQ_1204U(...) \, +#define Z_IS_1205_EQ_1205(...) \, +#define Z_IS_1205U_EQ_1205(...) \, +#define Z_IS_1205_EQ_1205U(...) \, +#define Z_IS_1205U_EQ_1205U(...) \, +#define Z_IS_1206_EQ_1206(...) \, +#define Z_IS_1206U_EQ_1206(...) \, +#define Z_IS_1206_EQ_1206U(...) \, +#define Z_IS_1206U_EQ_1206U(...) \, +#define Z_IS_1207_EQ_1207(...) \, +#define Z_IS_1207U_EQ_1207(...) \, +#define Z_IS_1207_EQ_1207U(...) \, +#define Z_IS_1207U_EQ_1207U(...) \, +#define Z_IS_1208_EQ_1208(...) \, +#define Z_IS_1208U_EQ_1208(...) \, +#define Z_IS_1208_EQ_1208U(...) \, +#define Z_IS_1208U_EQ_1208U(...) \, +#define Z_IS_1209_EQ_1209(...) \, +#define Z_IS_1209U_EQ_1209(...) \, +#define Z_IS_1209_EQ_1209U(...) \, +#define Z_IS_1209U_EQ_1209U(...) \, +#define Z_IS_1210_EQ_1210(...) \, +#define Z_IS_1210U_EQ_1210(...) \, +#define Z_IS_1210_EQ_1210U(...) \, +#define Z_IS_1210U_EQ_1210U(...) \, +#define Z_IS_1211_EQ_1211(...) \, +#define Z_IS_1211U_EQ_1211(...) \, +#define Z_IS_1211_EQ_1211U(...) \, +#define Z_IS_1211U_EQ_1211U(...) \, +#define Z_IS_1212_EQ_1212(...) \, +#define Z_IS_1212U_EQ_1212(...) \, +#define Z_IS_1212_EQ_1212U(...) \, +#define Z_IS_1212U_EQ_1212U(...) \, +#define Z_IS_1213_EQ_1213(...) \, +#define Z_IS_1213U_EQ_1213(...) \, +#define Z_IS_1213_EQ_1213U(...) \, +#define Z_IS_1213U_EQ_1213U(...) \, +#define Z_IS_1214_EQ_1214(...) \, +#define Z_IS_1214U_EQ_1214(...) \, +#define Z_IS_1214_EQ_1214U(...) \, +#define Z_IS_1214U_EQ_1214U(...) \, +#define Z_IS_1215_EQ_1215(...) \, +#define Z_IS_1215U_EQ_1215(...) \, +#define Z_IS_1215_EQ_1215U(...) \, +#define Z_IS_1215U_EQ_1215U(...) \, +#define Z_IS_1216_EQ_1216(...) \, +#define Z_IS_1216U_EQ_1216(...) \, +#define Z_IS_1216_EQ_1216U(...) \, +#define Z_IS_1216U_EQ_1216U(...) \, +#define Z_IS_1217_EQ_1217(...) \, +#define Z_IS_1217U_EQ_1217(...) \, +#define Z_IS_1217_EQ_1217U(...) \, +#define Z_IS_1217U_EQ_1217U(...) \, +#define Z_IS_1218_EQ_1218(...) \, +#define Z_IS_1218U_EQ_1218(...) \, +#define Z_IS_1218_EQ_1218U(...) \, +#define Z_IS_1218U_EQ_1218U(...) \, +#define Z_IS_1219_EQ_1219(...) \, +#define Z_IS_1219U_EQ_1219(...) \, +#define Z_IS_1219_EQ_1219U(...) \, +#define Z_IS_1219U_EQ_1219U(...) \, +#define Z_IS_1220_EQ_1220(...) \, +#define Z_IS_1220U_EQ_1220(...) \, +#define Z_IS_1220_EQ_1220U(...) \, +#define Z_IS_1220U_EQ_1220U(...) \, +#define Z_IS_1221_EQ_1221(...) \, +#define Z_IS_1221U_EQ_1221(...) \, +#define Z_IS_1221_EQ_1221U(...) \, +#define Z_IS_1221U_EQ_1221U(...) \, +#define Z_IS_1222_EQ_1222(...) \, +#define Z_IS_1222U_EQ_1222(...) \, +#define Z_IS_1222_EQ_1222U(...) \, +#define Z_IS_1222U_EQ_1222U(...) \, +#define Z_IS_1223_EQ_1223(...) \, +#define Z_IS_1223U_EQ_1223(...) \, +#define Z_IS_1223_EQ_1223U(...) \, +#define Z_IS_1223U_EQ_1223U(...) \, +#define Z_IS_1224_EQ_1224(...) \, +#define Z_IS_1224U_EQ_1224(...) \, +#define Z_IS_1224_EQ_1224U(...) \, +#define Z_IS_1224U_EQ_1224U(...) \, +#define Z_IS_1225_EQ_1225(...) \, +#define Z_IS_1225U_EQ_1225(...) \, +#define Z_IS_1225_EQ_1225U(...) \, +#define Z_IS_1225U_EQ_1225U(...) \, +#define Z_IS_1226_EQ_1226(...) \, +#define Z_IS_1226U_EQ_1226(...) \, +#define Z_IS_1226_EQ_1226U(...) \, +#define Z_IS_1226U_EQ_1226U(...) \, +#define Z_IS_1227_EQ_1227(...) \, +#define Z_IS_1227U_EQ_1227(...) \, +#define Z_IS_1227_EQ_1227U(...) \, +#define Z_IS_1227U_EQ_1227U(...) \, +#define Z_IS_1228_EQ_1228(...) \, +#define Z_IS_1228U_EQ_1228(...) \, +#define Z_IS_1228_EQ_1228U(...) \, +#define Z_IS_1228U_EQ_1228U(...) \, +#define Z_IS_1229_EQ_1229(...) \, +#define Z_IS_1229U_EQ_1229(...) \, +#define Z_IS_1229_EQ_1229U(...) \, +#define Z_IS_1229U_EQ_1229U(...) \, +#define Z_IS_1230_EQ_1230(...) \, +#define Z_IS_1230U_EQ_1230(...) \, +#define Z_IS_1230_EQ_1230U(...) \, +#define Z_IS_1230U_EQ_1230U(...) \, +#define Z_IS_1231_EQ_1231(...) \, +#define Z_IS_1231U_EQ_1231(...) \, +#define Z_IS_1231_EQ_1231U(...) \, +#define Z_IS_1231U_EQ_1231U(...) \, +#define Z_IS_1232_EQ_1232(...) \, +#define Z_IS_1232U_EQ_1232(...) \, +#define Z_IS_1232_EQ_1232U(...) \, +#define Z_IS_1232U_EQ_1232U(...) \, +#define Z_IS_1233_EQ_1233(...) \, +#define Z_IS_1233U_EQ_1233(...) \, +#define Z_IS_1233_EQ_1233U(...) \, +#define Z_IS_1233U_EQ_1233U(...) \, +#define Z_IS_1234_EQ_1234(...) \, +#define Z_IS_1234U_EQ_1234(...) \, +#define Z_IS_1234_EQ_1234U(...) \, +#define Z_IS_1234U_EQ_1234U(...) \, +#define Z_IS_1235_EQ_1235(...) \, +#define Z_IS_1235U_EQ_1235(...) \, +#define Z_IS_1235_EQ_1235U(...) \, +#define Z_IS_1235U_EQ_1235U(...) \, +#define Z_IS_1236_EQ_1236(...) \, +#define Z_IS_1236U_EQ_1236(...) \, +#define Z_IS_1236_EQ_1236U(...) \, +#define Z_IS_1236U_EQ_1236U(...) \, +#define Z_IS_1237_EQ_1237(...) \, +#define Z_IS_1237U_EQ_1237(...) \, +#define Z_IS_1237_EQ_1237U(...) \, +#define Z_IS_1237U_EQ_1237U(...) \, +#define Z_IS_1238_EQ_1238(...) \, +#define Z_IS_1238U_EQ_1238(...) \, +#define Z_IS_1238_EQ_1238U(...) \, +#define Z_IS_1238U_EQ_1238U(...) \, +#define Z_IS_1239_EQ_1239(...) \, +#define Z_IS_1239U_EQ_1239(...) \, +#define Z_IS_1239_EQ_1239U(...) \, +#define Z_IS_1239U_EQ_1239U(...) \, +#define Z_IS_1240_EQ_1240(...) \, +#define Z_IS_1240U_EQ_1240(...) \, +#define Z_IS_1240_EQ_1240U(...) \, +#define Z_IS_1240U_EQ_1240U(...) \, +#define Z_IS_1241_EQ_1241(...) \, +#define Z_IS_1241U_EQ_1241(...) \, +#define Z_IS_1241_EQ_1241U(...) \, +#define Z_IS_1241U_EQ_1241U(...) \, +#define Z_IS_1242_EQ_1242(...) \, +#define Z_IS_1242U_EQ_1242(...) \, +#define Z_IS_1242_EQ_1242U(...) \, +#define Z_IS_1242U_EQ_1242U(...) \, +#define Z_IS_1243_EQ_1243(...) \, +#define Z_IS_1243U_EQ_1243(...) \, +#define Z_IS_1243_EQ_1243U(...) \, +#define Z_IS_1243U_EQ_1243U(...) \, +#define Z_IS_1244_EQ_1244(...) \, +#define Z_IS_1244U_EQ_1244(...) \, +#define Z_IS_1244_EQ_1244U(...) \, +#define Z_IS_1244U_EQ_1244U(...) \, +#define Z_IS_1245_EQ_1245(...) \, +#define Z_IS_1245U_EQ_1245(...) \, +#define Z_IS_1245_EQ_1245U(...) \, +#define Z_IS_1245U_EQ_1245U(...) \, +#define Z_IS_1246_EQ_1246(...) \, +#define Z_IS_1246U_EQ_1246(...) \, +#define Z_IS_1246_EQ_1246U(...) \, +#define Z_IS_1246U_EQ_1246U(...) \, +#define Z_IS_1247_EQ_1247(...) \, +#define Z_IS_1247U_EQ_1247(...) \, +#define Z_IS_1247_EQ_1247U(...) \, +#define Z_IS_1247U_EQ_1247U(...) \, +#define Z_IS_1248_EQ_1248(...) \, +#define Z_IS_1248U_EQ_1248(...) \, +#define Z_IS_1248_EQ_1248U(...) \, +#define Z_IS_1248U_EQ_1248U(...) \, +#define Z_IS_1249_EQ_1249(...) \, +#define Z_IS_1249U_EQ_1249(...) \, +#define Z_IS_1249_EQ_1249U(...) \, +#define Z_IS_1249U_EQ_1249U(...) \, +#define Z_IS_1250_EQ_1250(...) \, +#define Z_IS_1250U_EQ_1250(...) \, +#define Z_IS_1250_EQ_1250U(...) \, +#define Z_IS_1250U_EQ_1250U(...) \, +#define Z_IS_1251_EQ_1251(...) \, +#define Z_IS_1251U_EQ_1251(...) \, +#define Z_IS_1251_EQ_1251U(...) \, +#define Z_IS_1251U_EQ_1251U(...) \, +#define Z_IS_1252_EQ_1252(...) \, +#define Z_IS_1252U_EQ_1252(...) \, +#define Z_IS_1252_EQ_1252U(...) \, +#define Z_IS_1252U_EQ_1252U(...) \, +#define Z_IS_1253_EQ_1253(...) \, +#define Z_IS_1253U_EQ_1253(...) \, +#define Z_IS_1253_EQ_1253U(...) \, +#define Z_IS_1253U_EQ_1253U(...) \, +#define Z_IS_1254_EQ_1254(...) \, +#define Z_IS_1254U_EQ_1254(...) \, +#define Z_IS_1254_EQ_1254U(...) \, +#define Z_IS_1254U_EQ_1254U(...) \, +#define Z_IS_1255_EQ_1255(...) \, +#define Z_IS_1255U_EQ_1255(...) \, +#define Z_IS_1255_EQ_1255U(...) \, +#define Z_IS_1255U_EQ_1255U(...) \, +#define Z_IS_1256_EQ_1256(...) \, +#define Z_IS_1256U_EQ_1256(...) \, +#define Z_IS_1256_EQ_1256U(...) \, +#define Z_IS_1256U_EQ_1256U(...) \, +#define Z_IS_1257_EQ_1257(...) \, +#define Z_IS_1257U_EQ_1257(...) \, +#define Z_IS_1257_EQ_1257U(...) \, +#define Z_IS_1257U_EQ_1257U(...) \, +#define Z_IS_1258_EQ_1258(...) \, +#define Z_IS_1258U_EQ_1258(...) \, +#define Z_IS_1258_EQ_1258U(...) \, +#define Z_IS_1258U_EQ_1258U(...) \, +#define Z_IS_1259_EQ_1259(...) \, +#define Z_IS_1259U_EQ_1259(...) \, +#define Z_IS_1259_EQ_1259U(...) \, +#define Z_IS_1259U_EQ_1259U(...) \, +#define Z_IS_1260_EQ_1260(...) \, +#define Z_IS_1260U_EQ_1260(...) \, +#define Z_IS_1260_EQ_1260U(...) \, +#define Z_IS_1260U_EQ_1260U(...) \, +#define Z_IS_1261_EQ_1261(...) \, +#define Z_IS_1261U_EQ_1261(...) \, +#define Z_IS_1261_EQ_1261U(...) \, +#define Z_IS_1261U_EQ_1261U(...) \, +#define Z_IS_1262_EQ_1262(...) \, +#define Z_IS_1262U_EQ_1262(...) \, +#define Z_IS_1262_EQ_1262U(...) \, +#define Z_IS_1262U_EQ_1262U(...) \, +#define Z_IS_1263_EQ_1263(...) \, +#define Z_IS_1263U_EQ_1263(...) \, +#define Z_IS_1263_EQ_1263U(...) \, +#define Z_IS_1263U_EQ_1263U(...) \, +#define Z_IS_1264_EQ_1264(...) \, +#define Z_IS_1264U_EQ_1264(...) \, +#define Z_IS_1264_EQ_1264U(...) \, +#define Z_IS_1264U_EQ_1264U(...) \, +#define Z_IS_1265_EQ_1265(...) \, +#define Z_IS_1265U_EQ_1265(...) \, +#define Z_IS_1265_EQ_1265U(...) \, +#define Z_IS_1265U_EQ_1265U(...) \, +#define Z_IS_1266_EQ_1266(...) \, +#define Z_IS_1266U_EQ_1266(...) \, +#define Z_IS_1266_EQ_1266U(...) \, +#define Z_IS_1266U_EQ_1266U(...) \, +#define Z_IS_1267_EQ_1267(...) \, +#define Z_IS_1267U_EQ_1267(...) \, +#define Z_IS_1267_EQ_1267U(...) \, +#define Z_IS_1267U_EQ_1267U(...) \, +#define Z_IS_1268_EQ_1268(...) \, +#define Z_IS_1268U_EQ_1268(...) \, +#define Z_IS_1268_EQ_1268U(...) \, +#define Z_IS_1268U_EQ_1268U(...) \, +#define Z_IS_1269_EQ_1269(...) \, +#define Z_IS_1269U_EQ_1269(...) \, +#define Z_IS_1269_EQ_1269U(...) \, +#define Z_IS_1269U_EQ_1269U(...) \, +#define Z_IS_1270_EQ_1270(...) \, +#define Z_IS_1270U_EQ_1270(...) \, +#define Z_IS_1270_EQ_1270U(...) \, +#define Z_IS_1270U_EQ_1270U(...) \, +#define Z_IS_1271_EQ_1271(...) \, +#define Z_IS_1271U_EQ_1271(...) \, +#define Z_IS_1271_EQ_1271U(...) \, +#define Z_IS_1271U_EQ_1271U(...) \, +#define Z_IS_1272_EQ_1272(...) \, +#define Z_IS_1272U_EQ_1272(...) \, +#define Z_IS_1272_EQ_1272U(...) \, +#define Z_IS_1272U_EQ_1272U(...) \, +#define Z_IS_1273_EQ_1273(...) \, +#define Z_IS_1273U_EQ_1273(...) \, +#define Z_IS_1273_EQ_1273U(...) \, +#define Z_IS_1273U_EQ_1273U(...) \, +#define Z_IS_1274_EQ_1274(...) \, +#define Z_IS_1274U_EQ_1274(...) \, +#define Z_IS_1274_EQ_1274U(...) \, +#define Z_IS_1274U_EQ_1274U(...) \, +#define Z_IS_1275_EQ_1275(...) \, +#define Z_IS_1275U_EQ_1275(...) \, +#define Z_IS_1275_EQ_1275U(...) \, +#define Z_IS_1275U_EQ_1275U(...) \, +#define Z_IS_1276_EQ_1276(...) \, +#define Z_IS_1276U_EQ_1276(...) \, +#define Z_IS_1276_EQ_1276U(...) \, +#define Z_IS_1276U_EQ_1276U(...) \, +#define Z_IS_1277_EQ_1277(...) \, +#define Z_IS_1277U_EQ_1277(...) \, +#define Z_IS_1277_EQ_1277U(...) \, +#define Z_IS_1277U_EQ_1277U(...) \, +#define Z_IS_1278_EQ_1278(...) \, +#define Z_IS_1278U_EQ_1278(...) \, +#define Z_IS_1278_EQ_1278U(...) \, +#define Z_IS_1278U_EQ_1278U(...) \, +#define Z_IS_1279_EQ_1279(...) \, +#define Z_IS_1279U_EQ_1279(...) \, +#define Z_IS_1279_EQ_1279U(...) \, +#define Z_IS_1279U_EQ_1279U(...) \, +#define Z_IS_1280_EQ_1280(...) \, +#define Z_IS_1280U_EQ_1280(...) \, +#define Z_IS_1280_EQ_1280U(...) \, +#define Z_IS_1280U_EQ_1280U(...) \, +#define Z_IS_1281_EQ_1281(...) \, +#define Z_IS_1281U_EQ_1281(...) \, +#define Z_IS_1281_EQ_1281U(...) \, +#define Z_IS_1281U_EQ_1281U(...) \, +#define Z_IS_1282_EQ_1282(...) \, +#define Z_IS_1282U_EQ_1282(...) \, +#define Z_IS_1282_EQ_1282U(...) \, +#define Z_IS_1282U_EQ_1282U(...) \, +#define Z_IS_1283_EQ_1283(...) \, +#define Z_IS_1283U_EQ_1283(...) \, +#define Z_IS_1283_EQ_1283U(...) \, +#define Z_IS_1283U_EQ_1283U(...) \, +#define Z_IS_1284_EQ_1284(...) \, +#define Z_IS_1284U_EQ_1284(...) \, +#define Z_IS_1284_EQ_1284U(...) \, +#define Z_IS_1284U_EQ_1284U(...) \, +#define Z_IS_1285_EQ_1285(...) \, +#define Z_IS_1285U_EQ_1285(...) \, +#define Z_IS_1285_EQ_1285U(...) \, +#define Z_IS_1285U_EQ_1285U(...) \, +#define Z_IS_1286_EQ_1286(...) \, +#define Z_IS_1286U_EQ_1286(...) \, +#define Z_IS_1286_EQ_1286U(...) \, +#define Z_IS_1286U_EQ_1286U(...) \, +#define Z_IS_1287_EQ_1287(...) \, +#define Z_IS_1287U_EQ_1287(...) \, +#define Z_IS_1287_EQ_1287U(...) \, +#define Z_IS_1287U_EQ_1287U(...) \, +#define Z_IS_1288_EQ_1288(...) \, +#define Z_IS_1288U_EQ_1288(...) \, +#define Z_IS_1288_EQ_1288U(...) \, +#define Z_IS_1288U_EQ_1288U(...) \, +#define Z_IS_1289_EQ_1289(...) \, +#define Z_IS_1289U_EQ_1289(...) \, +#define Z_IS_1289_EQ_1289U(...) \, +#define Z_IS_1289U_EQ_1289U(...) \, +#define Z_IS_1290_EQ_1290(...) \, +#define Z_IS_1290U_EQ_1290(...) \, +#define Z_IS_1290_EQ_1290U(...) \, +#define Z_IS_1290U_EQ_1290U(...) \, +#define Z_IS_1291_EQ_1291(...) \, +#define Z_IS_1291U_EQ_1291(...) \, +#define Z_IS_1291_EQ_1291U(...) \, +#define Z_IS_1291U_EQ_1291U(...) \, +#define Z_IS_1292_EQ_1292(...) \, +#define Z_IS_1292U_EQ_1292(...) \, +#define Z_IS_1292_EQ_1292U(...) \, +#define Z_IS_1292U_EQ_1292U(...) \, +#define Z_IS_1293_EQ_1293(...) \, +#define Z_IS_1293U_EQ_1293(...) \, +#define Z_IS_1293_EQ_1293U(...) \, +#define Z_IS_1293U_EQ_1293U(...) \, +#define Z_IS_1294_EQ_1294(...) \, +#define Z_IS_1294U_EQ_1294(...) \, +#define Z_IS_1294_EQ_1294U(...) \, +#define Z_IS_1294U_EQ_1294U(...) \, +#define Z_IS_1295_EQ_1295(...) \, +#define Z_IS_1295U_EQ_1295(...) \, +#define Z_IS_1295_EQ_1295U(...) \, +#define Z_IS_1295U_EQ_1295U(...) \, +#define Z_IS_1296_EQ_1296(...) \, +#define Z_IS_1296U_EQ_1296(...) \, +#define Z_IS_1296_EQ_1296U(...) \, +#define Z_IS_1296U_EQ_1296U(...) \, +#define Z_IS_1297_EQ_1297(...) \, +#define Z_IS_1297U_EQ_1297(...) \, +#define Z_IS_1297_EQ_1297U(...) \, +#define Z_IS_1297U_EQ_1297U(...) \, +#define Z_IS_1298_EQ_1298(...) \, +#define Z_IS_1298U_EQ_1298(...) \, +#define Z_IS_1298_EQ_1298U(...) \, +#define Z_IS_1298U_EQ_1298U(...) \, +#define Z_IS_1299_EQ_1299(...) \, +#define Z_IS_1299U_EQ_1299(...) \, +#define Z_IS_1299_EQ_1299U(...) \, +#define Z_IS_1299U_EQ_1299U(...) \, +#define Z_IS_1300_EQ_1300(...) \, +#define Z_IS_1300U_EQ_1300(...) \, +#define Z_IS_1300_EQ_1300U(...) \, +#define Z_IS_1300U_EQ_1300U(...) \, +#define Z_IS_1301_EQ_1301(...) \, +#define Z_IS_1301U_EQ_1301(...) \, +#define Z_IS_1301_EQ_1301U(...) \, +#define Z_IS_1301U_EQ_1301U(...) \, +#define Z_IS_1302_EQ_1302(...) \, +#define Z_IS_1302U_EQ_1302(...) \, +#define Z_IS_1302_EQ_1302U(...) \, +#define Z_IS_1302U_EQ_1302U(...) \, +#define Z_IS_1303_EQ_1303(...) \, +#define Z_IS_1303U_EQ_1303(...) \, +#define Z_IS_1303_EQ_1303U(...) \, +#define Z_IS_1303U_EQ_1303U(...) \, +#define Z_IS_1304_EQ_1304(...) \, +#define Z_IS_1304U_EQ_1304(...) \, +#define Z_IS_1304_EQ_1304U(...) \, +#define Z_IS_1304U_EQ_1304U(...) \, +#define Z_IS_1305_EQ_1305(...) \, +#define Z_IS_1305U_EQ_1305(...) \, +#define Z_IS_1305_EQ_1305U(...) \, +#define Z_IS_1305U_EQ_1305U(...) \, +#define Z_IS_1306_EQ_1306(...) \, +#define Z_IS_1306U_EQ_1306(...) \, +#define Z_IS_1306_EQ_1306U(...) \, +#define Z_IS_1306U_EQ_1306U(...) \, +#define Z_IS_1307_EQ_1307(...) \, +#define Z_IS_1307U_EQ_1307(...) \, +#define Z_IS_1307_EQ_1307U(...) \, +#define Z_IS_1307U_EQ_1307U(...) \, +#define Z_IS_1308_EQ_1308(...) \, +#define Z_IS_1308U_EQ_1308(...) \, +#define Z_IS_1308_EQ_1308U(...) \, +#define Z_IS_1308U_EQ_1308U(...) \, +#define Z_IS_1309_EQ_1309(...) \, +#define Z_IS_1309U_EQ_1309(...) \, +#define Z_IS_1309_EQ_1309U(...) \, +#define Z_IS_1309U_EQ_1309U(...) \, +#define Z_IS_1310_EQ_1310(...) \, +#define Z_IS_1310U_EQ_1310(...) \, +#define Z_IS_1310_EQ_1310U(...) \, +#define Z_IS_1310U_EQ_1310U(...) \, +#define Z_IS_1311_EQ_1311(...) \, +#define Z_IS_1311U_EQ_1311(...) \, +#define Z_IS_1311_EQ_1311U(...) \, +#define Z_IS_1311U_EQ_1311U(...) \, +#define Z_IS_1312_EQ_1312(...) \, +#define Z_IS_1312U_EQ_1312(...) \, +#define Z_IS_1312_EQ_1312U(...) \, +#define Z_IS_1312U_EQ_1312U(...) \, +#define Z_IS_1313_EQ_1313(...) \, +#define Z_IS_1313U_EQ_1313(...) \, +#define Z_IS_1313_EQ_1313U(...) \, +#define Z_IS_1313U_EQ_1313U(...) \, +#define Z_IS_1314_EQ_1314(...) \, +#define Z_IS_1314U_EQ_1314(...) \, +#define Z_IS_1314_EQ_1314U(...) \, +#define Z_IS_1314U_EQ_1314U(...) \, +#define Z_IS_1315_EQ_1315(...) \, +#define Z_IS_1315U_EQ_1315(...) \, +#define Z_IS_1315_EQ_1315U(...) \, +#define Z_IS_1315U_EQ_1315U(...) \, +#define Z_IS_1316_EQ_1316(...) \, +#define Z_IS_1316U_EQ_1316(...) \, +#define Z_IS_1316_EQ_1316U(...) \, +#define Z_IS_1316U_EQ_1316U(...) \, +#define Z_IS_1317_EQ_1317(...) \, +#define Z_IS_1317U_EQ_1317(...) \, +#define Z_IS_1317_EQ_1317U(...) \, +#define Z_IS_1317U_EQ_1317U(...) \, +#define Z_IS_1318_EQ_1318(...) \, +#define Z_IS_1318U_EQ_1318(...) \, +#define Z_IS_1318_EQ_1318U(...) \, +#define Z_IS_1318U_EQ_1318U(...) \, +#define Z_IS_1319_EQ_1319(...) \, +#define Z_IS_1319U_EQ_1319(...) \, +#define Z_IS_1319_EQ_1319U(...) \, +#define Z_IS_1319U_EQ_1319U(...) \, +#define Z_IS_1320_EQ_1320(...) \, +#define Z_IS_1320U_EQ_1320(...) \, +#define Z_IS_1320_EQ_1320U(...) \, +#define Z_IS_1320U_EQ_1320U(...) \, +#define Z_IS_1321_EQ_1321(...) \, +#define Z_IS_1321U_EQ_1321(...) \, +#define Z_IS_1321_EQ_1321U(...) \, +#define Z_IS_1321U_EQ_1321U(...) \, +#define Z_IS_1322_EQ_1322(...) \, +#define Z_IS_1322U_EQ_1322(...) \, +#define Z_IS_1322_EQ_1322U(...) \, +#define Z_IS_1322U_EQ_1322U(...) \, +#define Z_IS_1323_EQ_1323(...) \, +#define Z_IS_1323U_EQ_1323(...) \, +#define Z_IS_1323_EQ_1323U(...) \, +#define Z_IS_1323U_EQ_1323U(...) \, +#define Z_IS_1324_EQ_1324(...) \, +#define Z_IS_1324U_EQ_1324(...) \, +#define Z_IS_1324_EQ_1324U(...) \, +#define Z_IS_1324U_EQ_1324U(...) \, +#define Z_IS_1325_EQ_1325(...) \, +#define Z_IS_1325U_EQ_1325(...) \, +#define Z_IS_1325_EQ_1325U(...) \, +#define Z_IS_1325U_EQ_1325U(...) \, +#define Z_IS_1326_EQ_1326(...) \, +#define Z_IS_1326U_EQ_1326(...) \, +#define Z_IS_1326_EQ_1326U(...) \, +#define Z_IS_1326U_EQ_1326U(...) \, +#define Z_IS_1327_EQ_1327(...) \, +#define Z_IS_1327U_EQ_1327(...) \, +#define Z_IS_1327_EQ_1327U(...) \, +#define Z_IS_1327U_EQ_1327U(...) \, +#define Z_IS_1328_EQ_1328(...) \, +#define Z_IS_1328U_EQ_1328(...) \, +#define Z_IS_1328_EQ_1328U(...) \, +#define Z_IS_1328U_EQ_1328U(...) \, +#define Z_IS_1329_EQ_1329(...) \, +#define Z_IS_1329U_EQ_1329(...) \, +#define Z_IS_1329_EQ_1329U(...) \, +#define Z_IS_1329U_EQ_1329U(...) \, +#define Z_IS_1330_EQ_1330(...) \, +#define Z_IS_1330U_EQ_1330(...) \, +#define Z_IS_1330_EQ_1330U(...) \, +#define Z_IS_1330U_EQ_1330U(...) \, +#define Z_IS_1331_EQ_1331(...) \, +#define Z_IS_1331U_EQ_1331(...) \, +#define Z_IS_1331_EQ_1331U(...) \, +#define Z_IS_1331U_EQ_1331U(...) \, +#define Z_IS_1332_EQ_1332(...) \, +#define Z_IS_1332U_EQ_1332(...) \, +#define Z_IS_1332_EQ_1332U(...) \, +#define Z_IS_1332U_EQ_1332U(...) \, +#define Z_IS_1333_EQ_1333(...) \, +#define Z_IS_1333U_EQ_1333(...) \, +#define Z_IS_1333_EQ_1333U(...) \, +#define Z_IS_1333U_EQ_1333U(...) \, +#define Z_IS_1334_EQ_1334(...) \, +#define Z_IS_1334U_EQ_1334(...) \, +#define Z_IS_1334_EQ_1334U(...) \, +#define Z_IS_1334U_EQ_1334U(...) \, +#define Z_IS_1335_EQ_1335(...) \, +#define Z_IS_1335U_EQ_1335(...) \, +#define Z_IS_1335_EQ_1335U(...) \, +#define Z_IS_1335U_EQ_1335U(...) \, +#define Z_IS_1336_EQ_1336(...) \, +#define Z_IS_1336U_EQ_1336(...) \, +#define Z_IS_1336_EQ_1336U(...) \, +#define Z_IS_1336U_EQ_1336U(...) \, +#define Z_IS_1337_EQ_1337(...) \, +#define Z_IS_1337U_EQ_1337(...) \, +#define Z_IS_1337_EQ_1337U(...) \, +#define Z_IS_1337U_EQ_1337U(...) \, +#define Z_IS_1338_EQ_1338(...) \, +#define Z_IS_1338U_EQ_1338(...) \, +#define Z_IS_1338_EQ_1338U(...) \, +#define Z_IS_1338U_EQ_1338U(...) \, +#define Z_IS_1339_EQ_1339(...) \, +#define Z_IS_1339U_EQ_1339(...) \, +#define Z_IS_1339_EQ_1339U(...) \, +#define Z_IS_1339U_EQ_1339U(...) \, +#define Z_IS_1340_EQ_1340(...) \, +#define Z_IS_1340U_EQ_1340(...) \, +#define Z_IS_1340_EQ_1340U(...) \, +#define Z_IS_1340U_EQ_1340U(...) \, +#define Z_IS_1341_EQ_1341(...) \, +#define Z_IS_1341U_EQ_1341(...) \, +#define Z_IS_1341_EQ_1341U(...) \, +#define Z_IS_1341U_EQ_1341U(...) \, +#define Z_IS_1342_EQ_1342(...) \, +#define Z_IS_1342U_EQ_1342(...) \, +#define Z_IS_1342_EQ_1342U(...) \, +#define Z_IS_1342U_EQ_1342U(...) \, +#define Z_IS_1343_EQ_1343(...) \, +#define Z_IS_1343U_EQ_1343(...) \, +#define Z_IS_1343_EQ_1343U(...) \, +#define Z_IS_1343U_EQ_1343U(...) \, +#define Z_IS_1344_EQ_1344(...) \, +#define Z_IS_1344U_EQ_1344(...) \, +#define Z_IS_1344_EQ_1344U(...) \, +#define Z_IS_1344U_EQ_1344U(...) \, +#define Z_IS_1345_EQ_1345(...) \, +#define Z_IS_1345U_EQ_1345(...) \, +#define Z_IS_1345_EQ_1345U(...) \, +#define Z_IS_1345U_EQ_1345U(...) \, +#define Z_IS_1346_EQ_1346(...) \, +#define Z_IS_1346U_EQ_1346(...) \, +#define Z_IS_1346_EQ_1346U(...) \, +#define Z_IS_1346U_EQ_1346U(...) \, +#define Z_IS_1347_EQ_1347(...) \, +#define Z_IS_1347U_EQ_1347(...) \, +#define Z_IS_1347_EQ_1347U(...) \, +#define Z_IS_1347U_EQ_1347U(...) \, +#define Z_IS_1348_EQ_1348(...) \, +#define Z_IS_1348U_EQ_1348(...) \, +#define Z_IS_1348_EQ_1348U(...) \, +#define Z_IS_1348U_EQ_1348U(...) \, +#define Z_IS_1349_EQ_1349(...) \, +#define Z_IS_1349U_EQ_1349(...) \, +#define Z_IS_1349_EQ_1349U(...) \, +#define Z_IS_1349U_EQ_1349U(...) \, +#define Z_IS_1350_EQ_1350(...) \, +#define Z_IS_1350U_EQ_1350(...) \, +#define Z_IS_1350_EQ_1350U(...) \, +#define Z_IS_1350U_EQ_1350U(...) \, +#define Z_IS_1351_EQ_1351(...) \, +#define Z_IS_1351U_EQ_1351(...) \, +#define Z_IS_1351_EQ_1351U(...) \, +#define Z_IS_1351U_EQ_1351U(...) \, +#define Z_IS_1352_EQ_1352(...) \, +#define Z_IS_1352U_EQ_1352(...) \, +#define Z_IS_1352_EQ_1352U(...) \, +#define Z_IS_1352U_EQ_1352U(...) \, +#define Z_IS_1353_EQ_1353(...) \, +#define Z_IS_1353U_EQ_1353(...) \, +#define Z_IS_1353_EQ_1353U(...) \, +#define Z_IS_1353U_EQ_1353U(...) \, +#define Z_IS_1354_EQ_1354(...) \, +#define Z_IS_1354U_EQ_1354(...) \, +#define Z_IS_1354_EQ_1354U(...) \, +#define Z_IS_1354U_EQ_1354U(...) \, +#define Z_IS_1355_EQ_1355(...) \, +#define Z_IS_1355U_EQ_1355(...) \, +#define Z_IS_1355_EQ_1355U(...) \, +#define Z_IS_1355U_EQ_1355U(...) \, +#define Z_IS_1356_EQ_1356(...) \, +#define Z_IS_1356U_EQ_1356(...) \, +#define Z_IS_1356_EQ_1356U(...) \, +#define Z_IS_1356U_EQ_1356U(...) \, +#define Z_IS_1357_EQ_1357(...) \, +#define Z_IS_1357U_EQ_1357(...) \, +#define Z_IS_1357_EQ_1357U(...) \, +#define Z_IS_1357U_EQ_1357U(...) \, +#define Z_IS_1358_EQ_1358(...) \, +#define Z_IS_1358U_EQ_1358(...) \, +#define Z_IS_1358_EQ_1358U(...) \, +#define Z_IS_1358U_EQ_1358U(...) \, +#define Z_IS_1359_EQ_1359(...) \, +#define Z_IS_1359U_EQ_1359(...) \, +#define Z_IS_1359_EQ_1359U(...) \, +#define Z_IS_1359U_EQ_1359U(...) \, +#define Z_IS_1360_EQ_1360(...) \, +#define Z_IS_1360U_EQ_1360(...) \, +#define Z_IS_1360_EQ_1360U(...) \, +#define Z_IS_1360U_EQ_1360U(...) \, +#define Z_IS_1361_EQ_1361(...) \, +#define Z_IS_1361U_EQ_1361(...) \, +#define Z_IS_1361_EQ_1361U(...) \, +#define Z_IS_1361U_EQ_1361U(...) \, +#define Z_IS_1362_EQ_1362(...) \, +#define Z_IS_1362U_EQ_1362(...) \, +#define Z_IS_1362_EQ_1362U(...) \, +#define Z_IS_1362U_EQ_1362U(...) \, +#define Z_IS_1363_EQ_1363(...) \, +#define Z_IS_1363U_EQ_1363(...) \, +#define Z_IS_1363_EQ_1363U(...) \, +#define Z_IS_1363U_EQ_1363U(...) \, +#define Z_IS_1364_EQ_1364(...) \, +#define Z_IS_1364U_EQ_1364(...) \, +#define Z_IS_1364_EQ_1364U(...) \, +#define Z_IS_1364U_EQ_1364U(...) \, +#define Z_IS_1365_EQ_1365(...) \, +#define Z_IS_1365U_EQ_1365(...) \, +#define Z_IS_1365_EQ_1365U(...) \, +#define Z_IS_1365U_EQ_1365U(...) \, +#define Z_IS_1366_EQ_1366(...) \, +#define Z_IS_1366U_EQ_1366(...) \, +#define Z_IS_1366_EQ_1366U(...) \, +#define Z_IS_1366U_EQ_1366U(...) \, +#define Z_IS_1367_EQ_1367(...) \, +#define Z_IS_1367U_EQ_1367(...) \, +#define Z_IS_1367_EQ_1367U(...) \, +#define Z_IS_1367U_EQ_1367U(...) \, +#define Z_IS_1368_EQ_1368(...) \, +#define Z_IS_1368U_EQ_1368(...) \, +#define Z_IS_1368_EQ_1368U(...) \, +#define Z_IS_1368U_EQ_1368U(...) \, +#define Z_IS_1369_EQ_1369(...) \, +#define Z_IS_1369U_EQ_1369(...) \, +#define Z_IS_1369_EQ_1369U(...) \, +#define Z_IS_1369U_EQ_1369U(...) \, +#define Z_IS_1370_EQ_1370(...) \, +#define Z_IS_1370U_EQ_1370(...) \, +#define Z_IS_1370_EQ_1370U(...) \, +#define Z_IS_1370U_EQ_1370U(...) \, +#define Z_IS_1371_EQ_1371(...) \, +#define Z_IS_1371U_EQ_1371(...) \, +#define Z_IS_1371_EQ_1371U(...) \, +#define Z_IS_1371U_EQ_1371U(...) \, +#define Z_IS_1372_EQ_1372(...) \, +#define Z_IS_1372U_EQ_1372(...) \, +#define Z_IS_1372_EQ_1372U(...) \, +#define Z_IS_1372U_EQ_1372U(...) \, +#define Z_IS_1373_EQ_1373(...) \, +#define Z_IS_1373U_EQ_1373(...) \, +#define Z_IS_1373_EQ_1373U(...) \, +#define Z_IS_1373U_EQ_1373U(...) \, +#define Z_IS_1374_EQ_1374(...) \, +#define Z_IS_1374U_EQ_1374(...) \, +#define Z_IS_1374_EQ_1374U(...) \, +#define Z_IS_1374U_EQ_1374U(...) \, +#define Z_IS_1375_EQ_1375(...) \, +#define Z_IS_1375U_EQ_1375(...) \, +#define Z_IS_1375_EQ_1375U(...) \, +#define Z_IS_1375U_EQ_1375U(...) \, +#define Z_IS_1376_EQ_1376(...) \, +#define Z_IS_1376U_EQ_1376(...) \, +#define Z_IS_1376_EQ_1376U(...) \, +#define Z_IS_1376U_EQ_1376U(...) \, +#define Z_IS_1377_EQ_1377(...) \, +#define Z_IS_1377U_EQ_1377(...) \, +#define Z_IS_1377_EQ_1377U(...) \, +#define Z_IS_1377U_EQ_1377U(...) \, +#define Z_IS_1378_EQ_1378(...) \, +#define Z_IS_1378U_EQ_1378(...) \, +#define Z_IS_1378_EQ_1378U(...) \, +#define Z_IS_1378U_EQ_1378U(...) \, +#define Z_IS_1379_EQ_1379(...) \, +#define Z_IS_1379U_EQ_1379(...) \, +#define Z_IS_1379_EQ_1379U(...) \, +#define Z_IS_1379U_EQ_1379U(...) \, +#define Z_IS_1380_EQ_1380(...) \, +#define Z_IS_1380U_EQ_1380(...) \, +#define Z_IS_1380_EQ_1380U(...) \, +#define Z_IS_1380U_EQ_1380U(...) \, +#define Z_IS_1381_EQ_1381(...) \, +#define Z_IS_1381U_EQ_1381(...) \, +#define Z_IS_1381_EQ_1381U(...) \, +#define Z_IS_1381U_EQ_1381U(...) \, +#define Z_IS_1382_EQ_1382(...) \, +#define Z_IS_1382U_EQ_1382(...) \, +#define Z_IS_1382_EQ_1382U(...) \, +#define Z_IS_1382U_EQ_1382U(...) \, +#define Z_IS_1383_EQ_1383(...) \, +#define Z_IS_1383U_EQ_1383(...) \, +#define Z_IS_1383_EQ_1383U(...) \, +#define Z_IS_1383U_EQ_1383U(...) \, +#define Z_IS_1384_EQ_1384(...) \, +#define Z_IS_1384U_EQ_1384(...) \, +#define Z_IS_1384_EQ_1384U(...) \, +#define Z_IS_1384U_EQ_1384U(...) \, +#define Z_IS_1385_EQ_1385(...) \, +#define Z_IS_1385U_EQ_1385(...) \, +#define Z_IS_1385_EQ_1385U(...) \, +#define Z_IS_1385U_EQ_1385U(...) \, +#define Z_IS_1386_EQ_1386(...) \, +#define Z_IS_1386U_EQ_1386(...) \, +#define Z_IS_1386_EQ_1386U(...) \, +#define Z_IS_1386U_EQ_1386U(...) \, +#define Z_IS_1387_EQ_1387(...) \, +#define Z_IS_1387U_EQ_1387(...) \, +#define Z_IS_1387_EQ_1387U(...) \, +#define Z_IS_1387U_EQ_1387U(...) \, +#define Z_IS_1388_EQ_1388(...) \, +#define Z_IS_1388U_EQ_1388(...) \, +#define Z_IS_1388_EQ_1388U(...) \, +#define Z_IS_1388U_EQ_1388U(...) \, +#define Z_IS_1389_EQ_1389(...) \, +#define Z_IS_1389U_EQ_1389(...) \, +#define Z_IS_1389_EQ_1389U(...) \, +#define Z_IS_1389U_EQ_1389U(...) \, +#define Z_IS_1390_EQ_1390(...) \, +#define Z_IS_1390U_EQ_1390(...) \, +#define Z_IS_1390_EQ_1390U(...) \, +#define Z_IS_1390U_EQ_1390U(...) \, +#define Z_IS_1391_EQ_1391(...) \, +#define Z_IS_1391U_EQ_1391(...) \, +#define Z_IS_1391_EQ_1391U(...) \, +#define Z_IS_1391U_EQ_1391U(...) \, +#define Z_IS_1392_EQ_1392(...) \, +#define Z_IS_1392U_EQ_1392(...) \, +#define Z_IS_1392_EQ_1392U(...) \, +#define Z_IS_1392U_EQ_1392U(...) \, +#define Z_IS_1393_EQ_1393(...) \, +#define Z_IS_1393U_EQ_1393(...) \, +#define Z_IS_1393_EQ_1393U(...) \, +#define Z_IS_1393U_EQ_1393U(...) \, +#define Z_IS_1394_EQ_1394(...) \, +#define Z_IS_1394U_EQ_1394(...) \, +#define Z_IS_1394_EQ_1394U(...) \, +#define Z_IS_1394U_EQ_1394U(...) \, +#define Z_IS_1395_EQ_1395(...) \, +#define Z_IS_1395U_EQ_1395(...) \, +#define Z_IS_1395_EQ_1395U(...) \, +#define Z_IS_1395U_EQ_1395U(...) \, +#define Z_IS_1396_EQ_1396(...) \, +#define Z_IS_1396U_EQ_1396(...) \, +#define Z_IS_1396_EQ_1396U(...) \, +#define Z_IS_1396U_EQ_1396U(...) \, +#define Z_IS_1397_EQ_1397(...) \, +#define Z_IS_1397U_EQ_1397(...) \, +#define Z_IS_1397_EQ_1397U(...) \, +#define Z_IS_1397U_EQ_1397U(...) \, +#define Z_IS_1398_EQ_1398(...) \, +#define Z_IS_1398U_EQ_1398(...) \, +#define Z_IS_1398_EQ_1398U(...) \, +#define Z_IS_1398U_EQ_1398U(...) \, +#define Z_IS_1399_EQ_1399(...) \, +#define Z_IS_1399U_EQ_1399(...) \, +#define Z_IS_1399_EQ_1399U(...) \, +#define Z_IS_1399U_EQ_1399U(...) \, +#define Z_IS_1400_EQ_1400(...) \, +#define Z_IS_1400U_EQ_1400(...) \, +#define Z_IS_1400_EQ_1400U(...) \, +#define Z_IS_1400U_EQ_1400U(...) \, +#define Z_IS_1401_EQ_1401(...) \, +#define Z_IS_1401U_EQ_1401(...) \, +#define Z_IS_1401_EQ_1401U(...) \, +#define Z_IS_1401U_EQ_1401U(...) \, +#define Z_IS_1402_EQ_1402(...) \, +#define Z_IS_1402U_EQ_1402(...) \, +#define Z_IS_1402_EQ_1402U(...) \, +#define Z_IS_1402U_EQ_1402U(...) \, +#define Z_IS_1403_EQ_1403(...) \, +#define Z_IS_1403U_EQ_1403(...) \, +#define Z_IS_1403_EQ_1403U(...) \, +#define Z_IS_1403U_EQ_1403U(...) \, +#define Z_IS_1404_EQ_1404(...) \, +#define Z_IS_1404U_EQ_1404(...) \, +#define Z_IS_1404_EQ_1404U(...) \, +#define Z_IS_1404U_EQ_1404U(...) \, +#define Z_IS_1405_EQ_1405(...) \, +#define Z_IS_1405U_EQ_1405(...) \, +#define Z_IS_1405_EQ_1405U(...) \, +#define Z_IS_1405U_EQ_1405U(...) \, +#define Z_IS_1406_EQ_1406(...) \, +#define Z_IS_1406U_EQ_1406(...) \, +#define Z_IS_1406_EQ_1406U(...) \, +#define Z_IS_1406U_EQ_1406U(...) \, +#define Z_IS_1407_EQ_1407(...) \, +#define Z_IS_1407U_EQ_1407(...) \, +#define Z_IS_1407_EQ_1407U(...) \, +#define Z_IS_1407U_EQ_1407U(...) \, +#define Z_IS_1408_EQ_1408(...) \, +#define Z_IS_1408U_EQ_1408(...) \, +#define Z_IS_1408_EQ_1408U(...) \, +#define Z_IS_1408U_EQ_1408U(...) \, +#define Z_IS_1409_EQ_1409(...) \, +#define Z_IS_1409U_EQ_1409(...) \, +#define Z_IS_1409_EQ_1409U(...) \, +#define Z_IS_1409U_EQ_1409U(...) \, +#define Z_IS_1410_EQ_1410(...) \, +#define Z_IS_1410U_EQ_1410(...) \, +#define Z_IS_1410_EQ_1410U(...) \, +#define Z_IS_1410U_EQ_1410U(...) \, +#define Z_IS_1411_EQ_1411(...) \, +#define Z_IS_1411U_EQ_1411(...) \, +#define Z_IS_1411_EQ_1411U(...) \, +#define Z_IS_1411U_EQ_1411U(...) \, +#define Z_IS_1412_EQ_1412(...) \, +#define Z_IS_1412U_EQ_1412(...) \, +#define Z_IS_1412_EQ_1412U(...) \, +#define Z_IS_1412U_EQ_1412U(...) \, +#define Z_IS_1413_EQ_1413(...) \, +#define Z_IS_1413U_EQ_1413(...) \, +#define Z_IS_1413_EQ_1413U(...) \, +#define Z_IS_1413U_EQ_1413U(...) \, +#define Z_IS_1414_EQ_1414(...) \, +#define Z_IS_1414U_EQ_1414(...) \, +#define Z_IS_1414_EQ_1414U(...) \, +#define Z_IS_1414U_EQ_1414U(...) \, +#define Z_IS_1415_EQ_1415(...) \, +#define Z_IS_1415U_EQ_1415(...) \, +#define Z_IS_1415_EQ_1415U(...) \, +#define Z_IS_1415U_EQ_1415U(...) \, +#define Z_IS_1416_EQ_1416(...) \, +#define Z_IS_1416U_EQ_1416(...) \, +#define Z_IS_1416_EQ_1416U(...) \, +#define Z_IS_1416U_EQ_1416U(...) \, +#define Z_IS_1417_EQ_1417(...) \, +#define Z_IS_1417U_EQ_1417(...) \, +#define Z_IS_1417_EQ_1417U(...) \, +#define Z_IS_1417U_EQ_1417U(...) \, +#define Z_IS_1418_EQ_1418(...) \, +#define Z_IS_1418U_EQ_1418(...) \, +#define Z_IS_1418_EQ_1418U(...) \, +#define Z_IS_1418U_EQ_1418U(...) \, +#define Z_IS_1419_EQ_1419(...) \, +#define Z_IS_1419U_EQ_1419(...) \, +#define Z_IS_1419_EQ_1419U(...) \, +#define Z_IS_1419U_EQ_1419U(...) \, +#define Z_IS_1420_EQ_1420(...) \, +#define Z_IS_1420U_EQ_1420(...) \, +#define Z_IS_1420_EQ_1420U(...) \, +#define Z_IS_1420U_EQ_1420U(...) \, +#define Z_IS_1421_EQ_1421(...) \, +#define Z_IS_1421U_EQ_1421(...) \, +#define Z_IS_1421_EQ_1421U(...) \, +#define Z_IS_1421U_EQ_1421U(...) \, +#define Z_IS_1422_EQ_1422(...) \, +#define Z_IS_1422U_EQ_1422(...) \, +#define Z_IS_1422_EQ_1422U(...) \, +#define Z_IS_1422U_EQ_1422U(...) \, +#define Z_IS_1423_EQ_1423(...) \, +#define Z_IS_1423U_EQ_1423(...) \, +#define Z_IS_1423_EQ_1423U(...) \, +#define Z_IS_1423U_EQ_1423U(...) \, +#define Z_IS_1424_EQ_1424(...) \, +#define Z_IS_1424U_EQ_1424(...) \, +#define Z_IS_1424_EQ_1424U(...) \, +#define Z_IS_1424U_EQ_1424U(...) \, +#define Z_IS_1425_EQ_1425(...) \, +#define Z_IS_1425U_EQ_1425(...) \, +#define Z_IS_1425_EQ_1425U(...) \, +#define Z_IS_1425U_EQ_1425U(...) \, +#define Z_IS_1426_EQ_1426(...) \, +#define Z_IS_1426U_EQ_1426(...) \, +#define Z_IS_1426_EQ_1426U(...) \, +#define Z_IS_1426U_EQ_1426U(...) \, +#define Z_IS_1427_EQ_1427(...) \, +#define Z_IS_1427U_EQ_1427(...) \, +#define Z_IS_1427_EQ_1427U(...) \, +#define Z_IS_1427U_EQ_1427U(...) \, +#define Z_IS_1428_EQ_1428(...) \, +#define Z_IS_1428U_EQ_1428(...) \, +#define Z_IS_1428_EQ_1428U(...) \, +#define Z_IS_1428U_EQ_1428U(...) \, +#define Z_IS_1429_EQ_1429(...) \, +#define Z_IS_1429U_EQ_1429(...) \, +#define Z_IS_1429_EQ_1429U(...) \, +#define Z_IS_1429U_EQ_1429U(...) \, +#define Z_IS_1430_EQ_1430(...) \, +#define Z_IS_1430U_EQ_1430(...) \, +#define Z_IS_1430_EQ_1430U(...) \, +#define Z_IS_1430U_EQ_1430U(...) \, +#define Z_IS_1431_EQ_1431(...) \, +#define Z_IS_1431U_EQ_1431(...) \, +#define Z_IS_1431_EQ_1431U(...) \, +#define Z_IS_1431U_EQ_1431U(...) \, +#define Z_IS_1432_EQ_1432(...) \, +#define Z_IS_1432U_EQ_1432(...) \, +#define Z_IS_1432_EQ_1432U(...) \, +#define Z_IS_1432U_EQ_1432U(...) \, +#define Z_IS_1433_EQ_1433(...) \, +#define Z_IS_1433U_EQ_1433(...) \, +#define Z_IS_1433_EQ_1433U(...) \, +#define Z_IS_1433U_EQ_1433U(...) \, +#define Z_IS_1434_EQ_1434(...) \, +#define Z_IS_1434U_EQ_1434(...) \, +#define Z_IS_1434_EQ_1434U(...) \, +#define Z_IS_1434U_EQ_1434U(...) \, +#define Z_IS_1435_EQ_1435(...) \, +#define Z_IS_1435U_EQ_1435(...) \, +#define Z_IS_1435_EQ_1435U(...) \, +#define Z_IS_1435U_EQ_1435U(...) \, +#define Z_IS_1436_EQ_1436(...) \, +#define Z_IS_1436U_EQ_1436(...) \, +#define Z_IS_1436_EQ_1436U(...) \, +#define Z_IS_1436U_EQ_1436U(...) \, +#define Z_IS_1437_EQ_1437(...) \, +#define Z_IS_1437U_EQ_1437(...) \, +#define Z_IS_1437_EQ_1437U(...) \, +#define Z_IS_1437U_EQ_1437U(...) \, +#define Z_IS_1438_EQ_1438(...) \, +#define Z_IS_1438U_EQ_1438(...) \, +#define Z_IS_1438_EQ_1438U(...) \, +#define Z_IS_1438U_EQ_1438U(...) \, +#define Z_IS_1439_EQ_1439(...) \, +#define Z_IS_1439U_EQ_1439(...) \, +#define Z_IS_1439_EQ_1439U(...) \, +#define Z_IS_1439U_EQ_1439U(...) \, +#define Z_IS_1440_EQ_1440(...) \, +#define Z_IS_1440U_EQ_1440(...) \, +#define Z_IS_1440_EQ_1440U(...) \, +#define Z_IS_1440U_EQ_1440U(...) \, +#define Z_IS_1441_EQ_1441(...) \, +#define Z_IS_1441U_EQ_1441(...) \, +#define Z_IS_1441_EQ_1441U(...) \, +#define Z_IS_1441U_EQ_1441U(...) \, +#define Z_IS_1442_EQ_1442(...) \, +#define Z_IS_1442U_EQ_1442(...) \, +#define Z_IS_1442_EQ_1442U(...) \, +#define Z_IS_1442U_EQ_1442U(...) \, +#define Z_IS_1443_EQ_1443(...) \, +#define Z_IS_1443U_EQ_1443(...) \, +#define Z_IS_1443_EQ_1443U(...) \, +#define Z_IS_1443U_EQ_1443U(...) \, +#define Z_IS_1444_EQ_1444(...) \, +#define Z_IS_1444U_EQ_1444(...) \, +#define Z_IS_1444_EQ_1444U(...) \, +#define Z_IS_1444U_EQ_1444U(...) \, +#define Z_IS_1445_EQ_1445(...) \, +#define Z_IS_1445U_EQ_1445(...) \, +#define Z_IS_1445_EQ_1445U(...) \, +#define Z_IS_1445U_EQ_1445U(...) \, +#define Z_IS_1446_EQ_1446(...) \, +#define Z_IS_1446U_EQ_1446(...) \, +#define Z_IS_1446_EQ_1446U(...) \, +#define Z_IS_1446U_EQ_1446U(...) \, +#define Z_IS_1447_EQ_1447(...) \, +#define Z_IS_1447U_EQ_1447(...) \, +#define Z_IS_1447_EQ_1447U(...) \, +#define Z_IS_1447U_EQ_1447U(...) \, +#define Z_IS_1448_EQ_1448(...) \, +#define Z_IS_1448U_EQ_1448(...) \, +#define Z_IS_1448_EQ_1448U(...) \, +#define Z_IS_1448U_EQ_1448U(...) \, +#define Z_IS_1449_EQ_1449(...) \, +#define Z_IS_1449U_EQ_1449(...) \, +#define Z_IS_1449_EQ_1449U(...) \, +#define Z_IS_1449U_EQ_1449U(...) \, +#define Z_IS_1450_EQ_1450(...) \, +#define Z_IS_1450U_EQ_1450(...) \, +#define Z_IS_1450_EQ_1450U(...) \, +#define Z_IS_1450U_EQ_1450U(...) \, +#define Z_IS_1451_EQ_1451(...) \, +#define Z_IS_1451U_EQ_1451(...) \, +#define Z_IS_1451_EQ_1451U(...) \, +#define Z_IS_1451U_EQ_1451U(...) \, +#define Z_IS_1452_EQ_1452(...) \, +#define Z_IS_1452U_EQ_1452(...) \, +#define Z_IS_1452_EQ_1452U(...) \, +#define Z_IS_1452U_EQ_1452U(...) \, +#define Z_IS_1453_EQ_1453(...) \, +#define Z_IS_1453U_EQ_1453(...) \, +#define Z_IS_1453_EQ_1453U(...) \, +#define Z_IS_1453U_EQ_1453U(...) \, +#define Z_IS_1454_EQ_1454(...) \, +#define Z_IS_1454U_EQ_1454(...) \, +#define Z_IS_1454_EQ_1454U(...) \, +#define Z_IS_1454U_EQ_1454U(...) \, +#define Z_IS_1455_EQ_1455(...) \, +#define Z_IS_1455U_EQ_1455(...) \, +#define Z_IS_1455_EQ_1455U(...) \, +#define Z_IS_1455U_EQ_1455U(...) \, +#define Z_IS_1456_EQ_1456(...) \, +#define Z_IS_1456U_EQ_1456(...) \, +#define Z_IS_1456_EQ_1456U(...) \, +#define Z_IS_1456U_EQ_1456U(...) \, +#define Z_IS_1457_EQ_1457(...) \, +#define Z_IS_1457U_EQ_1457(...) \, +#define Z_IS_1457_EQ_1457U(...) \, +#define Z_IS_1457U_EQ_1457U(...) \, +#define Z_IS_1458_EQ_1458(...) \, +#define Z_IS_1458U_EQ_1458(...) \, +#define Z_IS_1458_EQ_1458U(...) \, +#define Z_IS_1458U_EQ_1458U(...) \, +#define Z_IS_1459_EQ_1459(...) \, +#define Z_IS_1459U_EQ_1459(...) \, +#define Z_IS_1459_EQ_1459U(...) \, +#define Z_IS_1459U_EQ_1459U(...) \, +#define Z_IS_1460_EQ_1460(...) \, +#define Z_IS_1460U_EQ_1460(...) \, +#define Z_IS_1460_EQ_1460U(...) \, +#define Z_IS_1460U_EQ_1460U(...) \, +#define Z_IS_1461_EQ_1461(...) \, +#define Z_IS_1461U_EQ_1461(...) \, +#define Z_IS_1461_EQ_1461U(...) \, +#define Z_IS_1461U_EQ_1461U(...) \, +#define Z_IS_1462_EQ_1462(...) \, +#define Z_IS_1462U_EQ_1462(...) \, +#define Z_IS_1462_EQ_1462U(...) \, +#define Z_IS_1462U_EQ_1462U(...) \, +#define Z_IS_1463_EQ_1463(...) \, +#define Z_IS_1463U_EQ_1463(...) \, +#define Z_IS_1463_EQ_1463U(...) \, +#define Z_IS_1463U_EQ_1463U(...) \, +#define Z_IS_1464_EQ_1464(...) \, +#define Z_IS_1464U_EQ_1464(...) \, +#define Z_IS_1464_EQ_1464U(...) \, +#define Z_IS_1464U_EQ_1464U(...) \, +#define Z_IS_1465_EQ_1465(...) \, +#define Z_IS_1465U_EQ_1465(...) \, +#define Z_IS_1465_EQ_1465U(...) \, +#define Z_IS_1465U_EQ_1465U(...) \, +#define Z_IS_1466_EQ_1466(...) \, +#define Z_IS_1466U_EQ_1466(...) \, +#define Z_IS_1466_EQ_1466U(...) \, +#define Z_IS_1466U_EQ_1466U(...) \, +#define Z_IS_1467_EQ_1467(...) \, +#define Z_IS_1467U_EQ_1467(...) \, +#define Z_IS_1467_EQ_1467U(...) \, +#define Z_IS_1467U_EQ_1467U(...) \, +#define Z_IS_1468_EQ_1468(...) \, +#define Z_IS_1468U_EQ_1468(...) \, +#define Z_IS_1468_EQ_1468U(...) \, +#define Z_IS_1468U_EQ_1468U(...) \, +#define Z_IS_1469_EQ_1469(...) \, +#define Z_IS_1469U_EQ_1469(...) \, +#define Z_IS_1469_EQ_1469U(...) \, +#define Z_IS_1469U_EQ_1469U(...) \, +#define Z_IS_1470_EQ_1470(...) \, +#define Z_IS_1470U_EQ_1470(...) \, +#define Z_IS_1470_EQ_1470U(...) \, +#define Z_IS_1470U_EQ_1470U(...) \, +#define Z_IS_1471_EQ_1471(...) \, +#define Z_IS_1471U_EQ_1471(...) \, +#define Z_IS_1471_EQ_1471U(...) \, +#define Z_IS_1471U_EQ_1471U(...) \, +#define Z_IS_1472_EQ_1472(...) \, +#define Z_IS_1472U_EQ_1472(...) \, +#define Z_IS_1472_EQ_1472U(...) \, +#define Z_IS_1472U_EQ_1472U(...) \, +#define Z_IS_1473_EQ_1473(...) \, +#define Z_IS_1473U_EQ_1473(...) \, +#define Z_IS_1473_EQ_1473U(...) \, +#define Z_IS_1473U_EQ_1473U(...) \, +#define Z_IS_1474_EQ_1474(...) \, +#define Z_IS_1474U_EQ_1474(...) \, +#define Z_IS_1474_EQ_1474U(...) \, +#define Z_IS_1474U_EQ_1474U(...) \, +#define Z_IS_1475_EQ_1475(...) \, +#define Z_IS_1475U_EQ_1475(...) \, +#define Z_IS_1475_EQ_1475U(...) \, +#define Z_IS_1475U_EQ_1475U(...) \, +#define Z_IS_1476_EQ_1476(...) \, +#define Z_IS_1476U_EQ_1476(...) \, +#define Z_IS_1476_EQ_1476U(...) \, +#define Z_IS_1476U_EQ_1476U(...) \, +#define Z_IS_1477_EQ_1477(...) \, +#define Z_IS_1477U_EQ_1477(...) \, +#define Z_IS_1477_EQ_1477U(...) \, +#define Z_IS_1477U_EQ_1477U(...) \, +#define Z_IS_1478_EQ_1478(...) \, +#define Z_IS_1478U_EQ_1478(...) \, +#define Z_IS_1478_EQ_1478U(...) \, +#define Z_IS_1478U_EQ_1478U(...) \, +#define Z_IS_1479_EQ_1479(...) \, +#define Z_IS_1479U_EQ_1479(...) \, +#define Z_IS_1479_EQ_1479U(...) \, +#define Z_IS_1479U_EQ_1479U(...) \, +#define Z_IS_1480_EQ_1480(...) \, +#define Z_IS_1480U_EQ_1480(...) \, +#define Z_IS_1480_EQ_1480U(...) \, +#define Z_IS_1480U_EQ_1480U(...) \, +#define Z_IS_1481_EQ_1481(...) \, +#define Z_IS_1481U_EQ_1481(...) \, +#define Z_IS_1481_EQ_1481U(...) \, +#define Z_IS_1481U_EQ_1481U(...) \, +#define Z_IS_1482_EQ_1482(...) \, +#define Z_IS_1482U_EQ_1482(...) \, +#define Z_IS_1482_EQ_1482U(...) \, +#define Z_IS_1482U_EQ_1482U(...) \, +#define Z_IS_1483_EQ_1483(...) \, +#define Z_IS_1483U_EQ_1483(...) \, +#define Z_IS_1483_EQ_1483U(...) \, +#define Z_IS_1483U_EQ_1483U(...) \, +#define Z_IS_1484_EQ_1484(...) \, +#define Z_IS_1484U_EQ_1484(...) \, +#define Z_IS_1484_EQ_1484U(...) \, +#define Z_IS_1484U_EQ_1484U(...) \, +#define Z_IS_1485_EQ_1485(...) \, +#define Z_IS_1485U_EQ_1485(...) \, +#define Z_IS_1485_EQ_1485U(...) \, +#define Z_IS_1485U_EQ_1485U(...) \, +#define Z_IS_1486_EQ_1486(...) \, +#define Z_IS_1486U_EQ_1486(...) \, +#define Z_IS_1486_EQ_1486U(...) \, +#define Z_IS_1486U_EQ_1486U(...) \, +#define Z_IS_1487_EQ_1487(...) \, +#define Z_IS_1487U_EQ_1487(...) \, +#define Z_IS_1487_EQ_1487U(...) \, +#define Z_IS_1487U_EQ_1487U(...) \, +#define Z_IS_1488_EQ_1488(...) \, +#define Z_IS_1488U_EQ_1488(...) \, +#define Z_IS_1488_EQ_1488U(...) \, +#define Z_IS_1488U_EQ_1488U(...) \, +#define Z_IS_1489_EQ_1489(...) \, +#define Z_IS_1489U_EQ_1489(...) \, +#define Z_IS_1489_EQ_1489U(...) \, +#define Z_IS_1489U_EQ_1489U(...) \, +#define Z_IS_1490_EQ_1490(...) \, +#define Z_IS_1490U_EQ_1490(...) \, +#define Z_IS_1490_EQ_1490U(...) \, +#define Z_IS_1490U_EQ_1490U(...) \, +#define Z_IS_1491_EQ_1491(...) \, +#define Z_IS_1491U_EQ_1491(...) \, +#define Z_IS_1491_EQ_1491U(...) \, +#define Z_IS_1491U_EQ_1491U(...) \, +#define Z_IS_1492_EQ_1492(...) \, +#define Z_IS_1492U_EQ_1492(...) \, +#define Z_IS_1492_EQ_1492U(...) \, +#define Z_IS_1492U_EQ_1492U(...) \, +#define Z_IS_1493_EQ_1493(...) \, +#define Z_IS_1493U_EQ_1493(...) \, +#define Z_IS_1493_EQ_1493U(...) \, +#define Z_IS_1493U_EQ_1493U(...) \, +#define Z_IS_1494_EQ_1494(...) \, +#define Z_IS_1494U_EQ_1494(...) \, +#define Z_IS_1494_EQ_1494U(...) \, +#define Z_IS_1494U_EQ_1494U(...) \, +#define Z_IS_1495_EQ_1495(...) \, +#define Z_IS_1495U_EQ_1495(...) \, +#define Z_IS_1495_EQ_1495U(...) \, +#define Z_IS_1495U_EQ_1495U(...) \, +#define Z_IS_1496_EQ_1496(...) \, +#define Z_IS_1496U_EQ_1496(...) \, +#define Z_IS_1496_EQ_1496U(...) \, +#define Z_IS_1496U_EQ_1496U(...) \, +#define Z_IS_1497_EQ_1497(...) \, +#define Z_IS_1497U_EQ_1497(...) \, +#define Z_IS_1497_EQ_1497U(...) \, +#define Z_IS_1497U_EQ_1497U(...) \, +#define Z_IS_1498_EQ_1498(...) \, +#define Z_IS_1498U_EQ_1498(...) \, +#define Z_IS_1498_EQ_1498U(...) \, +#define Z_IS_1498U_EQ_1498U(...) \, +#define Z_IS_1499_EQ_1499(...) \, +#define Z_IS_1499U_EQ_1499(...) \, +#define Z_IS_1499_EQ_1499U(...) \, +#define Z_IS_1499U_EQ_1499U(...) \, +#define Z_IS_1500_EQ_1500(...) \, +#define Z_IS_1500U_EQ_1500(...) \, +#define Z_IS_1500_EQ_1500U(...) \, +#define Z_IS_1500U_EQ_1500U(...) \, +#define Z_IS_1501_EQ_1501(...) \, +#define Z_IS_1501U_EQ_1501(...) \, +#define Z_IS_1501_EQ_1501U(...) \, +#define Z_IS_1501U_EQ_1501U(...) \, +#define Z_IS_1502_EQ_1502(...) \, +#define Z_IS_1502U_EQ_1502(...) \, +#define Z_IS_1502_EQ_1502U(...) \, +#define Z_IS_1502U_EQ_1502U(...) \, +#define Z_IS_1503_EQ_1503(...) \, +#define Z_IS_1503U_EQ_1503(...) \, +#define Z_IS_1503_EQ_1503U(...) \, +#define Z_IS_1503U_EQ_1503U(...) \, +#define Z_IS_1504_EQ_1504(...) \, +#define Z_IS_1504U_EQ_1504(...) \, +#define Z_IS_1504_EQ_1504U(...) \, +#define Z_IS_1504U_EQ_1504U(...) \, +#define Z_IS_1505_EQ_1505(...) \, +#define Z_IS_1505U_EQ_1505(...) \, +#define Z_IS_1505_EQ_1505U(...) \, +#define Z_IS_1505U_EQ_1505U(...) \, +#define Z_IS_1506_EQ_1506(...) \, +#define Z_IS_1506U_EQ_1506(...) \, +#define Z_IS_1506_EQ_1506U(...) \, +#define Z_IS_1506U_EQ_1506U(...) \, +#define Z_IS_1507_EQ_1507(...) \, +#define Z_IS_1507U_EQ_1507(...) \, +#define Z_IS_1507_EQ_1507U(...) \, +#define Z_IS_1507U_EQ_1507U(...) \, +#define Z_IS_1508_EQ_1508(...) \, +#define Z_IS_1508U_EQ_1508(...) \, +#define Z_IS_1508_EQ_1508U(...) \, +#define Z_IS_1508U_EQ_1508U(...) \, +#define Z_IS_1509_EQ_1509(...) \, +#define Z_IS_1509U_EQ_1509(...) \, +#define Z_IS_1509_EQ_1509U(...) \, +#define Z_IS_1509U_EQ_1509U(...) \, +#define Z_IS_1510_EQ_1510(...) \, +#define Z_IS_1510U_EQ_1510(...) \, +#define Z_IS_1510_EQ_1510U(...) \, +#define Z_IS_1510U_EQ_1510U(...) \, +#define Z_IS_1511_EQ_1511(...) \, +#define Z_IS_1511U_EQ_1511(...) \, +#define Z_IS_1511_EQ_1511U(...) \, +#define Z_IS_1511U_EQ_1511U(...) \, +#define Z_IS_1512_EQ_1512(...) \, +#define Z_IS_1512U_EQ_1512(...) \, +#define Z_IS_1512_EQ_1512U(...) \, +#define Z_IS_1512U_EQ_1512U(...) \, +#define Z_IS_1513_EQ_1513(...) \, +#define Z_IS_1513U_EQ_1513(...) \, +#define Z_IS_1513_EQ_1513U(...) \, +#define Z_IS_1513U_EQ_1513U(...) \, +#define Z_IS_1514_EQ_1514(...) \, +#define Z_IS_1514U_EQ_1514(...) \, +#define Z_IS_1514_EQ_1514U(...) \, +#define Z_IS_1514U_EQ_1514U(...) \, +#define Z_IS_1515_EQ_1515(...) \, +#define Z_IS_1515U_EQ_1515(...) \, +#define Z_IS_1515_EQ_1515U(...) \, +#define Z_IS_1515U_EQ_1515U(...) \, +#define Z_IS_1516_EQ_1516(...) \, +#define Z_IS_1516U_EQ_1516(...) \, +#define Z_IS_1516_EQ_1516U(...) \, +#define Z_IS_1516U_EQ_1516U(...) \, +#define Z_IS_1517_EQ_1517(...) \, +#define Z_IS_1517U_EQ_1517(...) \, +#define Z_IS_1517_EQ_1517U(...) \, +#define Z_IS_1517U_EQ_1517U(...) \, +#define Z_IS_1518_EQ_1518(...) \, +#define Z_IS_1518U_EQ_1518(...) \, +#define Z_IS_1518_EQ_1518U(...) \, +#define Z_IS_1518U_EQ_1518U(...) \, +#define Z_IS_1519_EQ_1519(...) \, +#define Z_IS_1519U_EQ_1519(...) \, +#define Z_IS_1519_EQ_1519U(...) \, +#define Z_IS_1519U_EQ_1519U(...) \, +#define Z_IS_1520_EQ_1520(...) \, +#define Z_IS_1520U_EQ_1520(...) \, +#define Z_IS_1520_EQ_1520U(...) \, +#define Z_IS_1520U_EQ_1520U(...) \, +#define Z_IS_1521_EQ_1521(...) \, +#define Z_IS_1521U_EQ_1521(...) \, +#define Z_IS_1521_EQ_1521U(...) \, +#define Z_IS_1521U_EQ_1521U(...) \, +#define Z_IS_1522_EQ_1522(...) \, +#define Z_IS_1522U_EQ_1522(...) \, +#define Z_IS_1522_EQ_1522U(...) \, +#define Z_IS_1522U_EQ_1522U(...) \, +#define Z_IS_1523_EQ_1523(...) \, +#define Z_IS_1523U_EQ_1523(...) \, +#define Z_IS_1523_EQ_1523U(...) \, +#define Z_IS_1523U_EQ_1523U(...) \, +#define Z_IS_1524_EQ_1524(...) \, +#define Z_IS_1524U_EQ_1524(...) \, +#define Z_IS_1524_EQ_1524U(...) \, +#define Z_IS_1524U_EQ_1524U(...) \, +#define Z_IS_1525_EQ_1525(...) \, +#define Z_IS_1525U_EQ_1525(...) \, +#define Z_IS_1525_EQ_1525U(...) \, +#define Z_IS_1525U_EQ_1525U(...) \, +#define Z_IS_1526_EQ_1526(...) \, +#define Z_IS_1526U_EQ_1526(...) \, +#define Z_IS_1526_EQ_1526U(...) \, +#define Z_IS_1526U_EQ_1526U(...) \, +#define Z_IS_1527_EQ_1527(...) \, +#define Z_IS_1527U_EQ_1527(...) \, +#define Z_IS_1527_EQ_1527U(...) \, +#define Z_IS_1527U_EQ_1527U(...) \, +#define Z_IS_1528_EQ_1528(...) \, +#define Z_IS_1528U_EQ_1528(...) \, +#define Z_IS_1528_EQ_1528U(...) \, +#define Z_IS_1528U_EQ_1528U(...) \, +#define Z_IS_1529_EQ_1529(...) \, +#define Z_IS_1529U_EQ_1529(...) \, +#define Z_IS_1529_EQ_1529U(...) \, +#define Z_IS_1529U_EQ_1529U(...) \, +#define Z_IS_1530_EQ_1530(...) \, +#define Z_IS_1530U_EQ_1530(...) \, +#define Z_IS_1530_EQ_1530U(...) \, +#define Z_IS_1530U_EQ_1530U(...) \, +#define Z_IS_1531_EQ_1531(...) \, +#define Z_IS_1531U_EQ_1531(...) \, +#define Z_IS_1531_EQ_1531U(...) \, +#define Z_IS_1531U_EQ_1531U(...) \, +#define Z_IS_1532_EQ_1532(...) \, +#define Z_IS_1532U_EQ_1532(...) \, +#define Z_IS_1532_EQ_1532U(...) \, +#define Z_IS_1532U_EQ_1532U(...) \, +#define Z_IS_1533_EQ_1533(...) \, +#define Z_IS_1533U_EQ_1533(...) \, +#define Z_IS_1533_EQ_1533U(...) \, +#define Z_IS_1533U_EQ_1533U(...) \, +#define Z_IS_1534_EQ_1534(...) \, +#define Z_IS_1534U_EQ_1534(...) \, +#define Z_IS_1534_EQ_1534U(...) \, +#define Z_IS_1534U_EQ_1534U(...) \, +#define Z_IS_1535_EQ_1535(...) \, +#define Z_IS_1535U_EQ_1535(...) \, +#define Z_IS_1535_EQ_1535U(...) \, +#define Z_IS_1535U_EQ_1535U(...) \, +#define Z_IS_1536_EQ_1536(...) \, +#define Z_IS_1536U_EQ_1536(...) \, +#define Z_IS_1536_EQ_1536U(...) \, +#define Z_IS_1536U_EQ_1536U(...) \, +#define Z_IS_1537_EQ_1537(...) \, +#define Z_IS_1537U_EQ_1537(...) \, +#define Z_IS_1537_EQ_1537U(...) \, +#define Z_IS_1537U_EQ_1537U(...) \, +#define Z_IS_1538_EQ_1538(...) \, +#define Z_IS_1538U_EQ_1538(...) \, +#define Z_IS_1538_EQ_1538U(...) \, +#define Z_IS_1538U_EQ_1538U(...) \, +#define Z_IS_1539_EQ_1539(...) \, +#define Z_IS_1539U_EQ_1539(...) \, +#define Z_IS_1539_EQ_1539U(...) \, +#define Z_IS_1539U_EQ_1539U(...) \, +#define Z_IS_1540_EQ_1540(...) \, +#define Z_IS_1540U_EQ_1540(...) \, +#define Z_IS_1540_EQ_1540U(...) \, +#define Z_IS_1540U_EQ_1540U(...) \, +#define Z_IS_1541_EQ_1541(...) \, +#define Z_IS_1541U_EQ_1541(...) \, +#define Z_IS_1541_EQ_1541U(...) \, +#define Z_IS_1541U_EQ_1541U(...) \, +#define Z_IS_1542_EQ_1542(...) \, +#define Z_IS_1542U_EQ_1542(...) \, +#define Z_IS_1542_EQ_1542U(...) \, +#define Z_IS_1542U_EQ_1542U(...) \, +#define Z_IS_1543_EQ_1543(...) \, +#define Z_IS_1543U_EQ_1543(...) \, +#define Z_IS_1543_EQ_1543U(...) \, +#define Z_IS_1543U_EQ_1543U(...) \, +#define Z_IS_1544_EQ_1544(...) \, +#define Z_IS_1544U_EQ_1544(...) \, +#define Z_IS_1544_EQ_1544U(...) \, +#define Z_IS_1544U_EQ_1544U(...) \, +#define Z_IS_1545_EQ_1545(...) \, +#define Z_IS_1545U_EQ_1545(...) \, +#define Z_IS_1545_EQ_1545U(...) \, +#define Z_IS_1545U_EQ_1545U(...) \, +#define Z_IS_1546_EQ_1546(...) \, +#define Z_IS_1546U_EQ_1546(...) \, +#define Z_IS_1546_EQ_1546U(...) \, +#define Z_IS_1546U_EQ_1546U(...) \, +#define Z_IS_1547_EQ_1547(...) \, +#define Z_IS_1547U_EQ_1547(...) \, +#define Z_IS_1547_EQ_1547U(...) \, +#define Z_IS_1547U_EQ_1547U(...) \, +#define Z_IS_1548_EQ_1548(...) \, +#define Z_IS_1548U_EQ_1548(...) \, +#define Z_IS_1548_EQ_1548U(...) \, +#define Z_IS_1548U_EQ_1548U(...) \, +#define Z_IS_1549_EQ_1549(...) \, +#define Z_IS_1549U_EQ_1549(...) \, +#define Z_IS_1549_EQ_1549U(...) \, +#define Z_IS_1549U_EQ_1549U(...) \, +#define Z_IS_1550_EQ_1550(...) \, +#define Z_IS_1550U_EQ_1550(...) \, +#define Z_IS_1550_EQ_1550U(...) \, +#define Z_IS_1550U_EQ_1550U(...) \, +#define Z_IS_1551_EQ_1551(...) \, +#define Z_IS_1551U_EQ_1551(...) \, +#define Z_IS_1551_EQ_1551U(...) \, +#define Z_IS_1551U_EQ_1551U(...) \, +#define Z_IS_1552_EQ_1552(...) \, +#define Z_IS_1552U_EQ_1552(...) \, +#define Z_IS_1552_EQ_1552U(...) \, +#define Z_IS_1552U_EQ_1552U(...) \, +#define Z_IS_1553_EQ_1553(...) \, +#define Z_IS_1553U_EQ_1553(...) \, +#define Z_IS_1553_EQ_1553U(...) \, +#define Z_IS_1553U_EQ_1553U(...) \, +#define Z_IS_1554_EQ_1554(...) \, +#define Z_IS_1554U_EQ_1554(...) \, +#define Z_IS_1554_EQ_1554U(...) \, +#define Z_IS_1554U_EQ_1554U(...) \, +#define Z_IS_1555_EQ_1555(...) \, +#define Z_IS_1555U_EQ_1555(...) \, +#define Z_IS_1555_EQ_1555U(...) \, +#define Z_IS_1555U_EQ_1555U(...) \, +#define Z_IS_1556_EQ_1556(...) \, +#define Z_IS_1556U_EQ_1556(...) \, +#define Z_IS_1556_EQ_1556U(...) \, +#define Z_IS_1556U_EQ_1556U(...) \, +#define Z_IS_1557_EQ_1557(...) \, +#define Z_IS_1557U_EQ_1557(...) \, +#define Z_IS_1557_EQ_1557U(...) \, +#define Z_IS_1557U_EQ_1557U(...) \, +#define Z_IS_1558_EQ_1558(...) \, +#define Z_IS_1558U_EQ_1558(...) \, +#define Z_IS_1558_EQ_1558U(...) \, +#define Z_IS_1558U_EQ_1558U(...) \, +#define Z_IS_1559_EQ_1559(...) \, +#define Z_IS_1559U_EQ_1559(...) \, +#define Z_IS_1559_EQ_1559U(...) \, +#define Z_IS_1559U_EQ_1559U(...) \, +#define Z_IS_1560_EQ_1560(...) \, +#define Z_IS_1560U_EQ_1560(...) \, +#define Z_IS_1560_EQ_1560U(...) \, +#define Z_IS_1560U_EQ_1560U(...) \, +#define Z_IS_1561_EQ_1561(...) \, +#define Z_IS_1561U_EQ_1561(...) \, +#define Z_IS_1561_EQ_1561U(...) \, +#define Z_IS_1561U_EQ_1561U(...) \, +#define Z_IS_1562_EQ_1562(...) \, +#define Z_IS_1562U_EQ_1562(...) \, +#define Z_IS_1562_EQ_1562U(...) \, +#define Z_IS_1562U_EQ_1562U(...) \, +#define Z_IS_1563_EQ_1563(...) \, +#define Z_IS_1563U_EQ_1563(...) \, +#define Z_IS_1563_EQ_1563U(...) \, +#define Z_IS_1563U_EQ_1563U(...) \, +#define Z_IS_1564_EQ_1564(...) \, +#define Z_IS_1564U_EQ_1564(...) \, +#define Z_IS_1564_EQ_1564U(...) \, +#define Z_IS_1564U_EQ_1564U(...) \, +#define Z_IS_1565_EQ_1565(...) \, +#define Z_IS_1565U_EQ_1565(...) \, +#define Z_IS_1565_EQ_1565U(...) \, +#define Z_IS_1565U_EQ_1565U(...) \, +#define Z_IS_1566_EQ_1566(...) \, +#define Z_IS_1566U_EQ_1566(...) \, +#define Z_IS_1566_EQ_1566U(...) \, +#define Z_IS_1566U_EQ_1566U(...) \, +#define Z_IS_1567_EQ_1567(...) \, +#define Z_IS_1567U_EQ_1567(...) \, +#define Z_IS_1567_EQ_1567U(...) \, +#define Z_IS_1567U_EQ_1567U(...) \, +#define Z_IS_1568_EQ_1568(...) \, +#define Z_IS_1568U_EQ_1568(...) \, +#define Z_IS_1568_EQ_1568U(...) \, +#define Z_IS_1568U_EQ_1568U(...) \, +#define Z_IS_1569_EQ_1569(...) \, +#define Z_IS_1569U_EQ_1569(...) \, +#define Z_IS_1569_EQ_1569U(...) \, +#define Z_IS_1569U_EQ_1569U(...) \, +#define Z_IS_1570_EQ_1570(...) \, +#define Z_IS_1570U_EQ_1570(...) \, +#define Z_IS_1570_EQ_1570U(...) \, +#define Z_IS_1570U_EQ_1570U(...) \, +#define Z_IS_1571_EQ_1571(...) \, +#define Z_IS_1571U_EQ_1571(...) \, +#define Z_IS_1571_EQ_1571U(...) \, +#define Z_IS_1571U_EQ_1571U(...) \, +#define Z_IS_1572_EQ_1572(...) \, +#define Z_IS_1572U_EQ_1572(...) \, +#define Z_IS_1572_EQ_1572U(...) \, +#define Z_IS_1572U_EQ_1572U(...) \, +#define Z_IS_1573_EQ_1573(...) \, +#define Z_IS_1573U_EQ_1573(...) \, +#define Z_IS_1573_EQ_1573U(...) \, +#define Z_IS_1573U_EQ_1573U(...) \, +#define Z_IS_1574_EQ_1574(...) \, +#define Z_IS_1574U_EQ_1574(...) \, +#define Z_IS_1574_EQ_1574U(...) \, +#define Z_IS_1574U_EQ_1574U(...) \, +#define Z_IS_1575_EQ_1575(...) \, +#define Z_IS_1575U_EQ_1575(...) \, +#define Z_IS_1575_EQ_1575U(...) \, +#define Z_IS_1575U_EQ_1575U(...) \, +#define Z_IS_1576_EQ_1576(...) \, +#define Z_IS_1576U_EQ_1576(...) \, +#define Z_IS_1576_EQ_1576U(...) \, +#define Z_IS_1576U_EQ_1576U(...) \, +#define Z_IS_1577_EQ_1577(...) \, +#define Z_IS_1577U_EQ_1577(...) \, +#define Z_IS_1577_EQ_1577U(...) \, +#define Z_IS_1577U_EQ_1577U(...) \, +#define Z_IS_1578_EQ_1578(...) \, +#define Z_IS_1578U_EQ_1578(...) \, +#define Z_IS_1578_EQ_1578U(...) \, +#define Z_IS_1578U_EQ_1578U(...) \, +#define Z_IS_1579_EQ_1579(...) \, +#define Z_IS_1579U_EQ_1579(...) \, +#define Z_IS_1579_EQ_1579U(...) \, +#define Z_IS_1579U_EQ_1579U(...) \, +#define Z_IS_1580_EQ_1580(...) \, +#define Z_IS_1580U_EQ_1580(...) \, +#define Z_IS_1580_EQ_1580U(...) \, +#define Z_IS_1580U_EQ_1580U(...) \, +#define Z_IS_1581_EQ_1581(...) \, +#define Z_IS_1581U_EQ_1581(...) \, +#define Z_IS_1581_EQ_1581U(...) \, +#define Z_IS_1581U_EQ_1581U(...) \, +#define Z_IS_1582_EQ_1582(...) \, +#define Z_IS_1582U_EQ_1582(...) \, +#define Z_IS_1582_EQ_1582U(...) \, +#define Z_IS_1582U_EQ_1582U(...) \, +#define Z_IS_1583_EQ_1583(...) \, +#define Z_IS_1583U_EQ_1583(...) \, +#define Z_IS_1583_EQ_1583U(...) \, +#define Z_IS_1583U_EQ_1583U(...) \, +#define Z_IS_1584_EQ_1584(...) \, +#define Z_IS_1584U_EQ_1584(...) \, +#define Z_IS_1584_EQ_1584U(...) \, +#define Z_IS_1584U_EQ_1584U(...) \, +#define Z_IS_1585_EQ_1585(...) \, +#define Z_IS_1585U_EQ_1585(...) \, +#define Z_IS_1585_EQ_1585U(...) \, +#define Z_IS_1585U_EQ_1585U(...) \, +#define Z_IS_1586_EQ_1586(...) \, +#define Z_IS_1586U_EQ_1586(...) \, +#define Z_IS_1586_EQ_1586U(...) \, +#define Z_IS_1586U_EQ_1586U(...) \, +#define Z_IS_1587_EQ_1587(...) \, +#define Z_IS_1587U_EQ_1587(...) \, +#define Z_IS_1587_EQ_1587U(...) \, +#define Z_IS_1587U_EQ_1587U(...) \, +#define Z_IS_1588_EQ_1588(...) \, +#define Z_IS_1588U_EQ_1588(...) \, +#define Z_IS_1588_EQ_1588U(...) \, +#define Z_IS_1588U_EQ_1588U(...) \, +#define Z_IS_1589_EQ_1589(...) \, +#define Z_IS_1589U_EQ_1589(...) \, +#define Z_IS_1589_EQ_1589U(...) \, +#define Z_IS_1589U_EQ_1589U(...) \, +#define Z_IS_1590_EQ_1590(...) \, +#define Z_IS_1590U_EQ_1590(...) \, +#define Z_IS_1590_EQ_1590U(...) \, +#define Z_IS_1590U_EQ_1590U(...) \, +#define Z_IS_1591_EQ_1591(...) \, +#define Z_IS_1591U_EQ_1591(...) \, +#define Z_IS_1591_EQ_1591U(...) \, +#define Z_IS_1591U_EQ_1591U(...) \, +#define Z_IS_1592_EQ_1592(...) \, +#define Z_IS_1592U_EQ_1592(...) \, +#define Z_IS_1592_EQ_1592U(...) \, +#define Z_IS_1592U_EQ_1592U(...) \, +#define Z_IS_1593_EQ_1593(...) \, +#define Z_IS_1593U_EQ_1593(...) \, +#define Z_IS_1593_EQ_1593U(...) \, +#define Z_IS_1593U_EQ_1593U(...) \, +#define Z_IS_1594_EQ_1594(...) \, +#define Z_IS_1594U_EQ_1594(...) \, +#define Z_IS_1594_EQ_1594U(...) \, +#define Z_IS_1594U_EQ_1594U(...) \, +#define Z_IS_1595_EQ_1595(...) \, +#define Z_IS_1595U_EQ_1595(...) \, +#define Z_IS_1595_EQ_1595U(...) \, +#define Z_IS_1595U_EQ_1595U(...) \, +#define Z_IS_1596_EQ_1596(...) \, +#define Z_IS_1596U_EQ_1596(...) \, +#define Z_IS_1596_EQ_1596U(...) \, +#define Z_IS_1596U_EQ_1596U(...) \, +#define Z_IS_1597_EQ_1597(...) \, +#define Z_IS_1597U_EQ_1597(...) \, +#define Z_IS_1597_EQ_1597U(...) \, +#define Z_IS_1597U_EQ_1597U(...) \, +#define Z_IS_1598_EQ_1598(...) \, +#define Z_IS_1598U_EQ_1598(...) \, +#define Z_IS_1598_EQ_1598U(...) \, +#define Z_IS_1598U_EQ_1598U(...) \, +#define Z_IS_1599_EQ_1599(...) \, +#define Z_IS_1599U_EQ_1599(...) \, +#define Z_IS_1599_EQ_1599U(...) \, +#define Z_IS_1599U_EQ_1599U(...) \, +#define Z_IS_1600_EQ_1600(...) \, +#define Z_IS_1600U_EQ_1600(...) \, +#define Z_IS_1600_EQ_1600U(...) \, +#define Z_IS_1600U_EQ_1600U(...) \, +#define Z_IS_1601_EQ_1601(...) \, +#define Z_IS_1601U_EQ_1601(...) \, +#define Z_IS_1601_EQ_1601U(...) \, +#define Z_IS_1601U_EQ_1601U(...) \, +#define Z_IS_1602_EQ_1602(...) \, +#define Z_IS_1602U_EQ_1602(...) \, +#define Z_IS_1602_EQ_1602U(...) \, +#define Z_IS_1602U_EQ_1602U(...) \, +#define Z_IS_1603_EQ_1603(...) \, +#define Z_IS_1603U_EQ_1603(...) \, +#define Z_IS_1603_EQ_1603U(...) \, +#define Z_IS_1603U_EQ_1603U(...) \, +#define Z_IS_1604_EQ_1604(...) \, +#define Z_IS_1604U_EQ_1604(...) \, +#define Z_IS_1604_EQ_1604U(...) \, +#define Z_IS_1604U_EQ_1604U(...) \, +#define Z_IS_1605_EQ_1605(...) \, +#define Z_IS_1605U_EQ_1605(...) \, +#define Z_IS_1605_EQ_1605U(...) \, +#define Z_IS_1605U_EQ_1605U(...) \, +#define Z_IS_1606_EQ_1606(...) \, +#define Z_IS_1606U_EQ_1606(...) \, +#define Z_IS_1606_EQ_1606U(...) \, +#define Z_IS_1606U_EQ_1606U(...) \, +#define Z_IS_1607_EQ_1607(...) \, +#define Z_IS_1607U_EQ_1607(...) \, +#define Z_IS_1607_EQ_1607U(...) \, +#define Z_IS_1607U_EQ_1607U(...) \, +#define Z_IS_1608_EQ_1608(...) \, +#define Z_IS_1608U_EQ_1608(...) \, +#define Z_IS_1608_EQ_1608U(...) \, +#define Z_IS_1608U_EQ_1608U(...) \, +#define Z_IS_1609_EQ_1609(...) \, +#define Z_IS_1609U_EQ_1609(...) \, +#define Z_IS_1609_EQ_1609U(...) \, +#define Z_IS_1609U_EQ_1609U(...) \, +#define Z_IS_1610_EQ_1610(...) \, +#define Z_IS_1610U_EQ_1610(...) \, +#define Z_IS_1610_EQ_1610U(...) \, +#define Z_IS_1610U_EQ_1610U(...) \, +#define Z_IS_1611_EQ_1611(...) \, +#define Z_IS_1611U_EQ_1611(...) \, +#define Z_IS_1611_EQ_1611U(...) \, +#define Z_IS_1611U_EQ_1611U(...) \, +#define Z_IS_1612_EQ_1612(...) \, +#define Z_IS_1612U_EQ_1612(...) \, +#define Z_IS_1612_EQ_1612U(...) \, +#define Z_IS_1612U_EQ_1612U(...) \, +#define Z_IS_1613_EQ_1613(...) \, +#define Z_IS_1613U_EQ_1613(...) \, +#define Z_IS_1613_EQ_1613U(...) \, +#define Z_IS_1613U_EQ_1613U(...) \, +#define Z_IS_1614_EQ_1614(...) \, +#define Z_IS_1614U_EQ_1614(...) \, +#define Z_IS_1614_EQ_1614U(...) \, +#define Z_IS_1614U_EQ_1614U(...) \, +#define Z_IS_1615_EQ_1615(...) \, +#define Z_IS_1615U_EQ_1615(...) \, +#define Z_IS_1615_EQ_1615U(...) \, +#define Z_IS_1615U_EQ_1615U(...) \, +#define Z_IS_1616_EQ_1616(...) \, +#define Z_IS_1616U_EQ_1616(...) \, +#define Z_IS_1616_EQ_1616U(...) \, +#define Z_IS_1616U_EQ_1616U(...) \, +#define Z_IS_1617_EQ_1617(...) \, +#define Z_IS_1617U_EQ_1617(...) \, +#define Z_IS_1617_EQ_1617U(...) \, +#define Z_IS_1617U_EQ_1617U(...) \, +#define Z_IS_1618_EQ_1618(...) \, +#define Z_IS_1618U_EQ_1618(...) \, +#define Z_IS_1618_EQ_1618U(...) \, +#define Z_IS_1618U_EQ_1618U(...) \, +#define Z_IS_1619_EQ_1619(...) \, +#define Z_IS_1619U_EQ_1619(...) \, +#define Z_IS_1619_EQ_1619U(...) \, +#define Z_IS_1619U_EQ_1619U(...) \, +#define Z_IS_1620_EQ_1620(...) \, +#define Z_IS_1620U_EQ_1620(...) \, +#define Z_IS_1620_EQ_1620U(...) \, +#define Z_IS_1620U_EQ_1620U(...) \, +#define Z_IS_1621_EQ_1621(...) \, +#define Z_IS_1621U_EQ_1621(...) \, +#define Z_IS_1621_EQ_1621U(...) \, +#define Z_IS_1621U_EQ_1621U(...) \, +#define Z_IS_1622_EQ_1622(...) \, +#define Z_IS_1622U_EQ_1622(...) \, +#define Z_IS_1622_EQ_1622U(...) \, +#define Z_IS_1622U_EQ_1622U(...) \, +#define Z_IS_1623_EQ_1623(...) \, +#define Z_IS_1623U_EQ_1623(...) \, +#define Z_IS_1623_EQ_1623U(...) \, +#define Z_IS_1623U_EQ_1623U(...) \, +#define Z_IS_1624_EQ_1624(...) \, +#define Z_IS_1624U_EQ_1624(...) \, +#define Z_IS_1624_EQ_1624U(...) \, +#define Z_IS_1624U_EQ_1624U(...) \, +#define Z_IS_1625_EQ_1625(...) \, +#define Z_IS_1625U_EQ_1625(...) \, +#define Z_IS_1625_EQ_1625U(...) \, +#define Z_IS_1625U_EQ_1625U(...) \, +#define Z_IS_1626_EQ_1626(...) \, +#define Z_IS_1626U_EQ_1626(...) \, +#define Z_IS_1626_EQ_1626U(...) \, +#define Z_IS_1626U_EQ_1626U(...) \, +#define Z_IS_1627_EQ_1627(...) \, +#define Z_IS_1627U_EQ_1627(...) \, +#define Z_IS_1627_EQ_1627U(...) \, +#define Z_IS_1627U_EQ_1627U(...) \, +#define Z_IS_1628_EQ_1628(...) \, +#define Z_IS_1628U_EQ_1628(...) \, +#define Z_IS_1628_EQ_1628U(...) \, +#define Z_IS_1628U_EQ_1628U(...) \, +#define Z_IS_1629_EQ_1629(...) \, +#define Z_IS_1629U_EQ_1629(...) \, +#define Z_IS_1629_EQ_1629U(...) \, +#define Z_IS_1629U_EQ_1629U(...) \, +#define Z_IS_1630_EQ_1630(...) \, +#define Z_IS_1630U_EQ_1630(...) \, +#define Z_IS_1630_EQ_1630U(...) \, +#define Z_IS_1630U_EQ_1630U(...) \, +#define Z_IS_1631_EQ_1631(...) \, +#define Z_IS_1631U_EQ_1631(...) \, +#define Z_IS_1631_EQ_1631U(...) \, +#define Z_IS_1631U_EQ_1631U(...) \, +#define Z_IS_1632_EQ_1632(...) \, +#define Z_IS_1632U_EQ_1632(...) \, +#define Z_IS_1632_EQ_1632U(...) \, +#define Z_IS_1632U_EQ_1632U(...) \, +#define Z_IS_1633_EQ_1633(...) \, +#define Z_IS_1633U_EQ_1633(...) \, +#define Z_IS_1633_EQ_1633U(...) \, +#define Z_IS_1633U_EQ_1633U(...) \, +#define Z_IS_1634_EQ_1634(...) \, +#define Z_IS_1634U_EQ_1634(...) \, +#define Z_IS_1634_EQ_1634U(...) \, +#define Z_IS_1634U_EQ_1634U(...) \, +#define Z_IS_1635_EQ_1635(...) \, +#define Z_IS_1635U_EQ_1635(...) \, +#define Z_IS_1635_EQ_1635U(...) \, +#define Z_IS_1635U_EQ_1635U(...) \, +#define Z_IS_1636_EQ_1636(...) \, +#define Z_IS_1636U_EQ_1636(...) \, +#define Z_IS_1636_EQ_1636U(...) \, +#define Z_IS_1636U_EQ_1636U(...) \, +#define Z_IS_1637_EQ_1637(...) \, +#define Z_IS_1637U_EQ_1637(...) \, +#define Z_IS_1637_EQ_1637U(...) \, +#define Z_IS_1637U_EQ_1637U(...) \, +#define Z_IS_1638_EQ_1638(...) \, +#define Z_IS_1638U_EQ_1638(...) \, +#define Z_IS_1638_EQ_1638U(...) \, +#define Z_IS_1638U_EQ_1638U(...) \, +#define Z_IS_1639_EQ_1639(...) \, +#define Z_IS_1639U_EQ_1639(...) \, +#define Z_IS_1639_EQ_1639U(...) \, +#define Z_IS_1639U_EQ_1639U(...) \, +#define Z_IS_1640_EQ_1640(...) \, +#define Z_IS_1640U_EQ_1640(...) \, +#define Z_IS_1640_EQ_1640U(...) \, +#define Z_IS_1640U_EQ_1640U(...) \, +#define Z_IS_1641_EQ_1641(...) \, +#define Z_IS_1641U_EQ_1641(...) \, +#define Z_IS_1641_EQ_1641U(...) \, +#define Z_IS_1641U_EQ_1641U(...) \, +#define Z_IS_1642_EQ_1642(...) \, +#define Z_IS_1642U_EQ_1642(...) \, +#define Z_IS_1642_EQ_1642U(...) \, +#define Z_IS_1642U_EQ_1642U(...) \, +#define Z_IS_1643_EQ_1643(...) \, +#define Z_IS_1643U_EQ_1643(...) \, +#define Z_IS_1643_EQ_1643U(...) \, +#define Z_IS_1643U_EQ_1643U(...) \, +#define Z_IS_1644_EQ_1644(...) \, +#define Z_IS_1644U_EQ_1644(...) \, +#define Z_IS_1644_EQ_1644U(...) \, +#define Z_IS_1644U_EQ_1644U(...) \, +#define Z_IS_1645_EQ_1645(...) \, +#define Z_IS_1645U_EQ_1645(...) \, +#define Z_IS_1645_EQ_1645U(...) \, +#define Z_IS_1645U_EQ_1645U(...) \, +#define Z_IS_1646_EQ_1646(...) \, +#define Z_IS_1646U_EQ_1646(...) \, +#define Z_IS_1646_EQ_1646U(...) \, +#define Z_IS_1646U_EQ_1646U(...) \, +#define Z_IS_1647_EQ_1647(...) \, +#define Z_IS_1647U_EQ_1647(...) \, +#define Z_IS_1647_EQ_1647U(...) \, +#define Z_IS_1647U_EQ_1647U(...) \, +#define Z_IS_1648_EQ_1648(...) \, +#define Z_IS_1648U_EQ_1648(...) \, +#define Z_IS_1648_EQ_1648U(...) \, +#define Z_IS_1648U_EQ_1648U(...) \, +#define Z_IS_1649_EQ_1649(...) \, +#define Z_IS_1649U_EQ_1649(...) \, +#define Z_IS_1649_EQ_1649U(...) \, +#define Z_IS_1649U_EQ_1649U(...) \, +#define Z_IS_1650_EQ_1650(...) \, +#define Z_IS_1650U_EQ_1650(...) \, +#define Z_IS_1650_EQ_1650U(...) \, +#define Z_IS_1650U_EQ_1650U(...) \, +#define Z_IS_1651_EQ_1651(...) \, +#define Z_IS_1651U_EQ_1651(...) \, +#define Z_IS_1651_EQ_1651U(...) \, +#define Z_IS_1651U_EQ_1651U(...) \, +#define Z_IS_1652_EQ_1652(...) \, +#define Z_IS_1652U_EQ_1652(...) \, +#define Z_IS_1652_EQ_1652U(...) \, +#define Z_IS_1652U_EQ_1652U(...) \, +#define Z_IS_1653_EQ_1653(...) \, +#define Z_IS_1653U_EQ_1653(...) \, +#define Z_IS_1653_EQ_1653U(...) \, +#define Z_IS_1653U_EQ_1653U(...) \, +#define Z_IS_1654_EQ_1654(...) \, +#define Z_IS_1654U_EQ_1654(...) \, +#define Z_IS_1654_EQ_1654U(...) \, +#define Z_IS_1654U_EQ_1654U(...) \, +#define Z_IS_1655_EQ_1655(...) \, +#define Z_IS_1655U_EQ_1655(...) \, +#define Z_IS_1655_EQ_1655U(...) \, +#define Z_IS_1655U_EQ_1655U(...) \, +#define Z_IS_1656_EQ_1656(...) \, +#define Z_IS_1656U_EQ_1656(...) \, +#define Z_IS_1656_EQ_1656U(...) \, +#define Z_IS_1656U_EQ_1656U(...) \, +#define Z_IS_1657_EQ_1657(...) \, +#define Z_IS_1657U_EQ_1657(...) \, +#define Z_IS_1657_EQ_1657U(...) \, +#define Z_IS_1657U_EQ_1657U(...) \, +#define Z_IS_1658_EQ_1658(...) \, +#define Z_IS_1658U_EQ_1658(...) \, +#define Z_IS_1658_EQ_1658U(...) \, +#define Z_IS_1658U_EQ_1658U(...) \, +#define Z_IS_1659_EQ_1659(...) \, +#define Z_IS_1659U_EQ_1659(...) \, +#define Z_IS_1659_EQ_1659U(...) \, +#define Z_IS_1659U_EQ_1659U(...) \, +#define Z_IS_1660_EQ_1660(...) \, +#define Z_IS_1660U_EQ_1660(...) \, +#define Z_IS_1660_EQ_1660U(...) \, +#define Z_IS_1660U_EQ_1660U(...) \, +#define Z_IS_1661_EQ_1661(...) \, +#define Z_IS_1661U_EQ_1661(...) \, +#define Z_IS_1661_EQ_1661U(...) \, +#define Z_IS_1661U_EQ_1661U(...) \, +#define Z_IS_1662_EQ_1662(...) \, +#define Z_IS_1662U_EQ_1662(...) \, +#define Z_IS_1662_EQ_1662U(...) \, +#define Z_IS_1662U_EQ_1662U(...) \, +#define Z_IS_1663_EQ_1663(...) \, +#define Z_IS_1663U_EQ_1663(...) \, +#define Z_IS_1663_EQ_1663U(...) \, +#define Z_IS_1663U_EQ_1663U(...) \, +#define Z_IS_1664_EQ_1664(...) \, +#define Z_IS_1664U_EQ_1664(...) \, +#define Z_IS_1664_EQ_1664U(...) \, +#define Z_IS_1664U_EQ_1664U(...) \, +#define Z_IS_1665_EQ_1665(...) \, +#define Z_IS_1665U_EQ_1665(...) \, +#define Z_IS_1665_EQ_1665U(...) \, +#define Z_IS_1665U_EQ_1665U(...) \, +#define Z_IS_1666_EQ_1666(...) \, +#define Z_IS_1666U_EQ_1666(...) \, +#define Z_IS_1666_EQ_1666U(...) \, +#define Z_IS_1666U_EQ_1666U(...) \, +#define Z_IS_1667_EQ_1667(...) \, +#define Z_IS_1667U_EQ_1667(...) \, +#define Z_IS_1667_EQ_1667U(...) \, +#define Z_IS_1667U_EQ_1667U(...) \, +#define Z_IS_1668_EQ_1668(...) \, +#define Z_IS_1668U_EQ_1668(...) \, +#define Z_IS_1668_EQ_1668U(...) \, +#define Z_IS_1668U_EQ_1668U(...) \, +#define Z_IS_1669_EQ_1669(...) \, +#define Z_IS_1669U_EQ_1669(...) \, +#define Z_IS_1669_EQ_1669U(...) \, +#define Z_IS_1669U_EQ_1669U(...) \, +#define Z_IS_1670_EQ_1670(...) \, +#define Z_IS_1670U_EQ_1670(...) \, +#define Z_IS_1670_EQ_1670U(...) \, +#define Z_IS_1670U_EQ_1670U(...) \, +#define Z_IS_1671_EQ_1671(...) \, +#define Z_IS_1671U_EQ_1671(...) \, +#define Z_IS_1671_EQ_1671U(...) \, +#define Z_IS_1671U_EQ_1671U(...) \, +#define Z_IS_1672_EQ_1672(...) \, +#define Z_IS_1672U_EQ_1672(...) \, +#define Z_IS_1672_EQ_1672U(...) \, +#define Z_IS_1672U_EQ_1672U(...) \, +#define Z_IS_1673_EQ_1673(...) \, +#define Z_IS_1673U_EQ_1673(...) \, +#define Z_IS_1673_EQ_1673U(...) \, +#define Z_IS_1673U_EQ_1673U(...) \, +#define Z_IS_1674_EQ_1674(...) \, +#define Z_IS_1674U_EQ_1674(...) \, +#define Z_IS_1674_EQ_1674U(...) \, +#define Z_IS_1674U_EQ_1674U(...) \, +#define Z_IS_1675_EQ_1675(...) \, +#define Z_IS_1675U_EQ_1675(...) \, +#define Z_IS_1675_EQ_1675U(...) \, +#define Z_IS_1675U_EQ_1675U(...) \, +#define Z_IS_1676_EQ_1676(...) \, +#define Z_IS_1676U_EQ_1676(...) \, +#define Z_IS_1676_EQ_1676U(...) \, +#define Z_IS_1676U_EQ_1676U(...) \, +#define Z_IS_1677_EQ_1677(...) \, +#define Z_IS_1677U_EQ_1677(...) \, +#define Z_IS_1677_EQ_1677U(...) \, +#define Z_IS_1677U_EQ_1677U(...) \, +#define Z_IS_1678_EQ_1678(...) \, +#define Z_IS_1678U_EQ_1678(...) \, +#define Z_IS_1678_EQ_1678U(...) \, +#define Z_IS_1678U_EQ_1678U(...) \, +#define Z_IS_1679_EQ_1679(...) \, +#define Z_IS_1679U_EQ_1679(...) \, +#define Z_IS_1679_EQ_1679U(...) \, +#define Z_IS_1679U_EQ_1679U(...) \, +#define Z_IS_1680_EQ_1680(...) \, +#define Z_IS_1680U_EQ_1680(...) \, +#define Z_IS_1680_EQ_1680U(...) \, +#define Z_IS_1680U_EQ_1680U(...) \, +#define Z_IS_1681_EQ_1681(...) \, +#define Z_IS_1681U_EQ_1681(...) \, +#define Z_IS_1681_EQ_1681U(...) \, +#define Z_IS_1681U_EQ_1681U(...) \, +#define Z_IS_1682_EQ_1682(...) \, +#define Z_IS_1682U_EQ_1682(...) \, +#define Z_IS_1682_EQ_1682U(...) \, +#define Z_IS_1682U_EQ_1682U(...) \, +#define Z_IS_1683_EQ_1683(...) \, +#define Z_IS_1683U_EQ_1683(...) \, +#define Z_IS_1683_EQ_1683U(...) \, +#define Z_IS_1683U_EQ_1683U(...) \, +#define Z_IS_1684_EQ_1684(...) \, +#define Z_IS_1684U_EQ_1684(...) \, +#define Z_IS_1684_EQ_1684U(...) \, +#define Z_IS_1684U_EQ_1684U(...) \, +#define Z_IS_1685_EQ_1685(...) \, +#define Z_IS_1685U_EQ_1685(...) \, +#define Z_IS_1685_EQ_1685U(...) \, +#define Z_IS_1685U_EQ_1685U(...) \, +#define Z_IS_1686_EQ_1686(...) \, +#define Z_IS_1686U_EQ_1686(...) \, +#define Z_IS_1686_EQ_1686U(...) \, +#define Z_IS_1686U_EQ_1686U(...) \, +#define Z_IS_1687_EQ_1687(...) \, +#define Z_IS_1687U_EQ_1687(...) \, +#define Z_IS_1687_EQ_1687U(...) \, +#define Z_IS_1687U_EQ_1687U(...) \, +#define Z_IS_1688_EQ_1688(...) \, +#define Z_IS_1688U_EQ_1688(...) \, +#define Z_IS_1688_EQ_1688U(...) \, +#define Z_IS_1688U_EQ_1688U(...) \, +#define Z_IS_1689_EQ_1689(...) \, +#define Z_IS_1689U_EQ_1689(...) \, +#define Z_IS_1689_EQ_1689U(...) \, +#define Z_IS_1689U_EQ_1689U(...) \, +#define Z_IS_1690_EQ_1690(...) \, +#define Z_IS_1690U_EQ_1690(...) \, +#define Z_IS_1690_EQ_1690U(...) \, +#define Z_IS_1690U_EQ_1690U(...) \, +#define Z_IS_1691_EQ_1691(...) \, +#define Z_IS_1691U_EQ_1691(...) \, +#define Z_IS_1691_EQ_1691U(...) \, +#define Z_IS_1691U_EQ_1691U(...) \, +#define Z_IS_1692_EQ_1692(...) \, +#define Z_IS_1692U_EQ_1692(...) \, +#define Z_IS_1692_EQ_1692U(...) \, +#define Z_IS_1692U_EQ_1692U(...) \, +#define Z_IS_1693_EQ_1693(...) \, +#define Z_IS_1693U_EQ_1693(...) \, +#define Z_IS_1693_EQ_1693U(...) \, +#define Z_IS_1693U_EQ_1693U(...) \, +#define Z_IS_1694_EQ_1694(...) \, +#define Z_IS_1694U_EQ_1694(...) \, +#define Z_IS_1694_EQ_1694U(...) \, +#define Z_IS_1694U_EQ_1694U(...) \, +#define Z_IS_1695_EQ_1695(...) \, +#define Z_IS_1695U_EQ_1695(...) \, +#define Z_IS_1695_EQ_1695U(...) \, +#define Z_IS_1695U_EQ_1695U(...) \, +#define Z_IS_1696_EQ_1696(...) \, +#define Z_IS_1696U_EQ_1696(...) \, +#define Z_IS_1696_EQ_1696U(...) \, +#define Z_IS_1696U_EQ_1696U(...) \, +#define Z_IS_1697_EQ_1697(...) \, +#define Z_IS_1697U_EQ_1697(...) \, +#define Z_IS_1697_EQ_1697U(...) \, +#define Z_IS_1697U_EQ_1697U(...) \, +#define Z_IS_1698_EQ_1698(...) \, +#define Z_IS_1698U_EQ_1698(...) \, +#define Z_IS_1698_EQ_1698U(...) \, +#define Z_IS_1698U_EQ_1698U(...) \, +#define Z_IS_1699_EQ_1699(...) \, +#define Z_IS_1699U_EQ_1699(...) \, +#define Z_IS_1699_EQ_1699U(...) \, +#define Z_IS_1699U_EQ_1699U(...) \, +#define Z_IS_1700_EQ_1700(...) \, +#define Z_IS_1700U_EQ_1700(...) \, +#define Z_IS_1700_EQ_1700U(...) \, +#define Z_IS_1700U_EQ_1700U(...) \, +#define Z_IS_1701_EQ_1701(...) \, +#define Z_IS_1701U_EQ_1701(...) \, +#define Z_IS_1701_EQ_1701U(...) \, +#define Z_IS_1701U_EQ_1701U(...) \, +#define Z_IS_1702_EQ_1702(...) \, +#define Z_IS_1702U_EQ_1702(...) \, +#define Z_IS_1702_EQ_1702U(...) \, +#define Z_IS_1702U_EQ_1702U(...) \, +#define Z_IS_1703_EQ_1703(...) \, +#define Z_IS_1703U_EQ_1703(...) \, +#define Z_IS_1703_EQ_1703U(...) \, +#define Z_IS_1703U_EQ_1703U(...) \, +#define Z_IS_1704_EQ_1704(...) \, +#define Z_IS_1704U_EQ_1704(...) \, +#define Z_IS_1704_EQ_1704U(...) \, +#define Z_IS_1704U_EQ_1704U(...) \, +#define Z_IS_1705_EQ_1705(...) \, +#define Z_IS_1705U_EQ_1705(...) \, +#define Z_IS_1705_EQ_1705U(...) \, +#define Z_IS_1705U_EQ_1705U(...) \, +#define Z_IS_1706_EQ_1706(...) \, +#define Z_IS_1706U_EQ_1706(...) \, +#define Z_IS_1706_EQ_1706U(...) \, +#define Z_IS_1706U_EQ_1706U(...) \, +#define Z_IS_1707_EQ_1707(...) \, +#define Z_IS_1707U_EQ_1707(...) \, +#define Z_IS_1707_EQ_1707U(...) \, +#define Z_IS_1707U_EQ_1707U(...) \, +#define Z_IS_1708_EQ_1708(...) \, +#define Z_IS_1708U_EQ_1708(...) \, +#define Z_IS_1708_EQ_1708U(...) \, +#define Z_IS_1708U_EQ_1708U(...) \, +#define Z_IS_1709_EQ_1709(...) \, +#define Z_IS_1709U_EQ_1709(...) \, +#define Z_IS_1709_EQ_1709U(...) \, +#define Z_IS_1709U_EQ_1709U(...) \, +#define Z_IS_1710_EQ_1710(...) \, +#define Z_IS_1710U_EQ_1710(...) \, +#define Z_IS_1710_EQ_1710U(...) \, +#define Z_IS_1710U_EQ_1710U(...) \, +#define Z_IS_1711_EQ_1711(...) \, +#define Z_IS_1711U_EQ_1711(...) \, +#define Z_IS_1711_EQ_1711U(...) \, +#define Z_IS_1711U_EQ_1711U(...) \, +#define Z_IS_1712_EQ_1712(...) \, +#define Z_IS_1712U_EQ_1712(...) \, +#define Z_IS_1712_EQ_1712U(...) \, +#define Z_IS_1712U_EQ_1712U(...) \, +#define Z_IS_1713_EQ_1713(...) \, +#define Z_IS_1713U_EQ_1713(...) \, +#define Z_IS_1713_EQ_1713U(...) \, +#define Z_IS_1713U_EQ_1713U(...) \, +#define Z_IS_1714_EQ_1714(...) \, +#define Z_IS_1714U_EQ_1714(...) \, +#define Z_IS_1714_EQ_1714U(...) \, +#define Z_IS_1714U_EQ_1714U(...) \, +#define Z_IS_1715_EQ_1715(...) \, +#define Z_IS_1715U_EQ_1715(...) \, +#define Z_IS_1715_EQ_1715U(...) \, +#define Z_IS_1715U_EQ_1715U(...) \, +#define Z_IS_1716_EQ_1716(...) \, +#define Z_IS_1716U_EQ_1716(...) \, +#define Z_IS_1716_EQ_1716U(...) \, +#define Z_IS_1716U_EQ_1716U(...) \, +#define Z_IS_1717_EQ_1717(...) \, +#define Z_IS_1717U_EQ_1717(...) \, +#define Z_IS_1717_EQ_1717U(...) \, +#define Z_IS_1717U_EQ_1717U(...) \, +#define Z_IS_1718_EQ_1718(...) \, +#define Z_IS_1718U_EQ_1718(...) \, +#define Z_IS_1718_EQ_1718U(...) \, +#define Z_IS_1718U_EQ_1718U(...) \, +#define Z_IS_1719_EQ_1719(...) \, +#define Z_IS_1719U_EQ_1719(...) \, +#define Z_IS_1719_EQ_1719U(...) \, +#define Z_IS_1719U_EQ_1719U(...) \, +#define Z_IS_1720_EQ_1720(...) \, +#define Z_IS_1720U_EQ_1720(...) \, +#define Z_IS_1720_EQ_1720U(...) \, +#define Z_IS_1720U_EQ_1720U(...) \, +#define Z_IS_1721_EQ_1721(...) \, +#define Z_IS_1721U_EQ_1721(...) \, +#define Z_IS_1721_EQ_1721U(...) \, +#define Z_IS_1721U_EQ_1721U(...) \, +#define Z_IS_1722_EQ_1722(...) \, +#define Z_IS_1722U_EQ_1722(...) \, +#define Z_IS_1722_EQ_1722U(...) \, +#define Z_IS_1722U_EQ_1722U(...) \, +#define Z_IS_1723_EQ_1723(...) \, +#define Z_IS_1723U_EQ_1723(...) \, +#define Z_IS_1723_EQ_1723U(...) \, +#define Z_IS_1723U_EQ_1723U(...) \, +#define Z_IS_1724_EQ_1724(...) \, +#define Z_IS_1724U_EQ_1724(...) \, +#define Z_IS_1724_EQ_1724U(...) \, +#define Z_IS_1724U_EQ_1724U(...) \, +#define Z_IS_1725_EQ_1725(...) \, +#define Z_IS_1725U_EQ_1725(...) \, +#define Z_IS_1725_EQ_1725U(...) \, +#define Z_IS_1725U_EQ_1725U(...) \, +#define Z_IS_1726_EQ_1726(...) \, +#define Z_IS_1726U_EQ_1726(...) \, +#define Z_IS_1726_EQ_1726U(...) \, +#define Z_IS_1726U_EQ_1726U(...) \, +#define Z_IS_1727_EQ_1727(...) \, +#define Z_IS_1727U_EQ_1727(...) \, +#define Z_IS_1727_EQ_1727U(...) \, +#define Z_IS_1727U_EQ_1727U(...) \, +#define Z_IS_1728_EQ_1728(...) \, +#define Z_IS_1728U_EQ_1728(...) \, +#define Z_IS_1728_EQ_1728U(...) \, +#define Z_IS_1728U_EQ_1728U(...) \, +#define Z_IS_1729_EQ_1729(...) \, +#define Z_IS_1729U_EQ_1729(...) \, +#define Z_IS_1729_EQ_1729U(...) \, +#define Z_IS_1729U_EQ_1729U(...) \, +#define Z_IS_1730_EQ_1730(...) \, +#define Z_IS_1730U_EQ_1730(...) \, +#define Z_IS_1730_EQ_1730U(...) \, +#define Z_IS_1730U_EQ_1730U(...) \, +#define Z_IS_1731_EQ_1731(...) \, +#define Z_IS_1731U_EQ_1731(...) \, +#define Z_IS_1731_EQ_1731U(...) \, +#define Z_IS_1731U_EQ_1731U(...) \, +#define Z_IS_1732_EQ_1732(...) \, +#define Z_IS_1732U_EQ_1732(...) \, +#define Z_IS_1732_EQ_1732U(...) \, +#define Z_IS_1732U_EQ_1732U(...) \, +#define Z_IS_1733_EQ_1733(...) \, +#define Z_IS_1733U_EQ_1733(...) \, +#define Z_IS_1733_EQ_1733U(...) \, +#define Z_IS_1733U_EQ_1733U(...) \, +#define Z_IS_1734_EQ_1734(...) \, +#define Z_IS_1734U_EQ_1734(...) \, +#define Z_IS_1734_EQ_1734U(...) \, +#define Z_IS_1734U_EQ_1734U(...) \, +#define Z_IS_1735_EQ_1735(...) \, +#define Z_IS_1735U_EQ_1735(...) \, +#define Z_IS_1735_EQ_1735U(...) \, +#define Z_IS_1735U_EQ_1735U(...) \, +#define Z_IS_1736_EQ_1736(...) \, +#define Z_IS_1736U_EQ_1736(...) \, +#define Z_IS_1736_EQ_1736U(...) \, +#define Z_IS_1736U_EQ_1736U(...) \, +#define Z_IS_1737_EQ_1737(...) \, +#define Z_IS_1737U_EQ_1737(...) \, +#define Z_IS_1737_EQ_1737U(...) \, +#define Z_IS_1737U_EQ_1737U(...) \, +#define Z_IS_1738_EQ_1738(...) \, +#define Z_IS_1738U_EQ_1738(...) \, +#define Z_IS_1738_EQ_1738U(...) \, +#define Z_IS_1738U_EQ_1738U(...) \, +#define Z_IS_1739_EQ_1739(...) \, +#define Z_IS_1739U_EQ_1739(...) \, +#define Z_IS_1739_EQ_1739U(...) \, +#define Z_IS_1739U_EQ_1739U(...) \, +#define Z_IS_1740_EQ_1740(...) \, +#define Z_IS_1740U_EQ_1740(...) \, +#define Z_IS_1740_EQ_1740U(...) \, +#define Z_IS_1740U_EQ_1740U(...) \, +#define Z_IS_1741_EQ_1741(...) \, +#define Z_IS_1741U_EQ_1741(...) \, +#define Z_IS_1741_EQ_1741U(...) \, +#define Z_IS_1741U_EQ_1741U(...) \, +#define Z_IS_1742_EQ_1742(...) \, +#define Z_IS_1742U_EQ_1742(...) \, +#define Z_IS_1742_EQ_1742U(...) \, +#define Z_IS_1742U_EQ_1742U(...) \, +#define Z_IS_1743_EQ_1743(...) \, +#define Z_IS_1743U_EQ_1743(...) \, +#define Z_IS_1743_EQ_1743U(...) \, +#define Z_IS_1743U_EQ_1743U(...) \, +#define Z_IS_1744_EQ_1744(...) \, +#define Z_IS_1744U_EQ_1744(...) \, +#define Z_IS_1744_EQ_1744U(...) \, +#define Z_IS_1744U_EQ_1744U(...) \, +#define Z_IS_1745_EQ_1745(...) \, +#define Z_IS_1745U_EQ_1745(...) \, +#define Z_IS_1745_EQ_1745U(...) \, +#define Z_IS_1745U_EQ_1745U(...) \, +#define Z_IS_1746_EQ_1746(...) \, +#define Z_IS_1746U_EQ_1746(...) \, +#define Z_IS_1746_EQ_1746U(...) \, +#define Z_IS_1746U_EQ_1746U(...) \, +#define Z_IS_1747_EQ_1747(...) \, +#define Z_IS_1747U_EQ_1747(...) \, +#define Z_IS_1747_EQ_1747U(...) \, +#define Z_IS_1747U_EQ_1747U(...) \, +#define Z_IS_1748_EQ_1748(...) \, +#define Z_IS_1748U_EQ_1748(...) \, +#define Z_IS_1748_EQ_1748U(...) \, +#define Z_IS_1748U_EQ_1748U(...) \, +#define Z_IS_1749_EQ_1749(...) \, +#define Z_IS_1749U_EQ_1749(...) \, +#define Z_IS_1749_EQ_1749U(...) \, +#define Z_IS_1749U_EQ_1749U(...) \, +#define Z_IS_1750_EQ_1750(...) \, +#define Z_IS_1750U_EQ_1750(...) \, +#define Z_IS_1750_EQ_1750U(...) \, +#define Z_IS_1750U_EQ_1750U(...) \, +#define Z_IS_1751_EQ_1751(...) \, +#define Z_IS_1751U_EQ_1751(...) \, +#define Z_IS_1751_EQ_1751U(...) \, +#define Z_IS_1751U_EQ_1751U(...) \, +#define Z_IS_1752_EQ_1752(...) \, +#define Z_IS_1752U_EQ_1752(...) \, +#define Z_IS_1752_EQ_1752U(...) \, +#define Z_IS_1752U_EQ_1752U(...) \, +#define Z_IS_1753_EQ_1753(...) \, +#define Z_IS_1753U_EQ_1753(...) \, +#define Z_IS_1753_EQ_1753U(...) \, +#define Z_IS_1753U_EQ_1753U(...) \, +#define Z_IS_1754_EQ_1754(...) \, +#define Z_IS_1754U_EQ_1754(...) \, +#define Z_IS_1754_EQ_1754U(...) \, +#define Z_IS_1754U_EQ_1754U(...) \, +#define Z_IS_1755_EQ_1755(...) \, +#define Z_IS_1755U_EQ_1755(...) \, +#define Z_IS_1755_EQ_1755U(...) \, +#define Z_IS_1755U_EQ_1755U(...) \, +#define Z_IS_1756_EQ_1756(...) \, +#define Z_IS_1756U_EQ_1756(...) \, +#define Z_IS_1756_EQ_1756U(...) \, +#define Z_IS_1756U_EQ_1756U(...) \, +#define Z_IS_1757_EQ_1757(...) \, +#define Z_IS_1757U_EQ_1757(...) \, +#define Z_IS_1757_EQ_1757U(...) \, +#define Z_IS_1757U_EQ_1757U(...) \, +#define Z_IS_1758_EQ_1758(...) \, +#define Z_IS_1758U_EQ_1758(...) \, +#define Z_IS_1758_EQ_1758U(...) \, +#define Z_IS_1758U_EQ_1758U(...) \, +#define Z_IS_1759_EQ_1759(...) \, +#define Z_IS_1759U_EQ_1759(...) \, +#define Z_IS_1759_EQ_1759U(...) \, +#define Z_IS_1759U_EQ_1759U(...) \, +#define Z_IS_1760_EQ_1760(...) \, +#define Z_IS_1760U_EQ_1760(...) \, +#define Z_IS_1760_EQ_1760U(...) \, +#define Z_IS_1760U_EQ_1760U(...) \, +#define Z_IS_1761_EQ_1761(...) \, +#define Z_IS_1761U_EQ_1761(...) \, +#define Z_IS_1761_EQ_1761U(...) \, +#define Z_IS_1761U_EQ_1761U(...) \, +#define Z_IS_1762_EQ_1762(...) \, +#define Z_IS_1762U_EQ_1762(...) \, +#define Z_IS_1762_EQ_1762U(...) \, +#define Z_IS_1762U_EQ_1762U(...) \, +#define Z_IS_1763_EQ_1763(...) \, +#define Z_IS_1763U_EQ_1763(...) \, +#define Z_IS_1763_EQ_1763U(...) \, +#define Z_IS_1763U_EQ_1763U(...) \, +#define Z_IS_1764_EQ_1764(...) \, +#define Z_IS_1764U_EQ_1764(...) \, +#define Z_IS_1764_EQ_1764U(...) \, +#define Z_IS_1764U_EQ_1764U(...) \, +#define Z_IS_1765_EQ_1765(...) \, +#define Z_IS_1765U_EQ_1765(...) \, +#define Z_IS_1765_EQ_1765U(...) \, +#define Z_IS_1765U_EQ_1765U(...) \, +#define Z_IS_1766_EQ_1766(...) \, +#define Z_IS_1766U_EQ_1766(...) \, +#define Z_IS_1766_EQ_1766U(...) \, +#define Z_IS_1766U_EQ_1766U(...) \, +#define Z_IS_1767_EQ_1767(...) \, +#define Z_IS_1767U_EQ_1767(...) \, +#define Z_IS_1767_EQ_1767U(...) \, +#define Z_IS_1767U_EQ_1767U(...) \, +#define Z_IS_1768_EQ_1768(...) \, +#define Z_IS_1768U_EQ_1768(...) \, +#define Z_IS_1768_EQ_1768U(...) \, +#define Z_IS_1768U_EQ_1768U(...) \, +#define Z_IS_1769_EQ_1769(...) \, +#define Z_IS_1769U_EQ_1769(...) \, +#define Z_IS_1769_EQ_1769U(...) \, +#define Z_IS_1769U_EQ_1769U(...) \, +#define Z_IS_1770_EQ_1770(...) \, +#define Z_IS_1770U_EQ_1770(...) \, +#define Z_IS_1770_EQ_1770U(...) \, +#define Z_IS_1770U_EQ_1770U(...) \, +#define Z_IS_1771_EQ_1771(...) \, +#define Z_IS_1771U_EQ_1771(...) \, +#define Z_IS_1771_EQ_1771U(...) \, +#define Z_IS_1771U_EQ_1771U(...) \, +#define Z_IS_1772_EQ_1772(...) \, +#define Z_IS_1772U_EQ_1772(...) \, +#define Z_IS_1772_EQ_1772U(...) \, +#define Z_IS_1772U_EQ_1772U(...) \, +#define Z_IS_1773_EQ_1773(...) \, +#define Z_IS_1773U_EQ_1773(...) \, +#define Z_IS_1773_EQ_1773U(...) \, +#define Z_IS_1773U_EQ_1773U(...) \, +#define Z_IS_1774_EQ_1774(...) \, +#define Z_IS_1774U_EQ_1774(...) \, +#define Z_IS_1774_EQ_1774U(...) \, +#define Z_IS_1774U_EQ_1774U(...) \, +#define Z_IS_1775_EQ_1775(...) \, +#define Z_IS_1775U_EQ_1775(...) \, +#define Z_IS_1775_EQ_1775U(...) \, +#define Z_IS_1775U_EQ_1775U(...) \, +#define Z_IS_1776_EQ_1776(...) \, +#define Z_IS_1776U_EQ_1776(...) \, +#define Z_IS_1776_EQ_1776U(...) \, +#define Z_IS_1776U_EQ_1776U(...) \, +#define Z_IS_1777_EQ_1777(...) \, +#define Z_IS_1777U_EQ_1777(...) \, +#define Z_IS_1777_EQ_1777U(...) \, +#define Z_IS_1777U_EQ_1777U(...) \, +#define Z_IS_1778_EQ_1778(...) \, +#define Z_IS_1778U_EQ_1778(...) \, +#define Z_IS_1778_EQ_1778U(...) \, +#define Z_IS_1778U_EQ_1778U(...) \, +#define Z_IS_1779_EQ_1779(...) \, +#define Z_IS_1779U_EQ_1779(...) \, +#define Z_IS_1779_EQ_1779U(...) \, +#define Z_IS_1779U_EQ_1779U(...) \, +#define Z_IS_1780_EQ_1780(...) \, +#define Z_IS_1780U_EQ_1780(...) \, +#define Z_IS_1780_EQ_1780U(...) \, +#define Z_IS_1780U_EQ_1780U(...) \, +#define Z_IS_1781_EQ_1781(...) \, +#define Z_IS_1781U_EQ_1781(...) \, +#define Z_IS_1781_EQ_1781U(...) \, +#define Z_IS_1781U_EQ_1781U(...) \, +#define Z_IS_1782_EQ_1782(...) \, +#define Z_IS_1782U_EQ_1782(...) \, +#define Z_IS_1782_EQ_1782U(...) \, +#define Z_IS_1782U_EQ_1782U(...) \, +#define Z_IS_1783_EQ_1783(...) \, +#define Z_IS_1783U_EQ_1783(...) \, +#define Z_IS_1783_EQ_1783U(...) \, +#define Z_IS_1783U_EQ_1783U(...) \, +#define Z_IS_1784_EQ_1784(...) \, +#define Z_IS_1784U_EQ_1784(...) \, +#define Z_IS_1784_EQ_1784U(...) \, +#define Z_IS_1784U_EQ_1784U(...) \, +#define Z_IS_1785_EQ_1785(...) \, +#define Z_IS_1785U_EQ_1785(...) \, +#define Z_IS_1785_EQ_1785U(...) \, +#define Z_IS_1785U_EQ_1785U(...) \, +#define Z_IS_1786_EQ_1786(...) \, +#define Z_IS_1786U_EQ_1786(...) \, +#define Z_IS_1786_EQ_1786U(...) \, +#define Z_IS_1786U_EQ_1786U(...) \, +#define Z_IS_1787_EQ_1787(...) \, +#define Z_IS_1787U_EQ_1787(...) \, +#define Z_IS_1787_EQ_1787U(...) \, +#define Z_IS_1787U_EQ_1787U(...) \, +#define Z_IS_1788_EQ_1788(...) \, +#define Z_IS_1788U_EQ_1788(...) \, +#define Z_IS_1788_EQ_1788U(...) \, +#define Z_IS_1788U_EQ_1788U(...) \, +#define Z_IS_1789_EQ_1789(...) \, +#define Z_IS_1789U_EQ_1789(...) \, +#define Z_IS_1789_EQ_1789U(...) \, +#define Z_IS_1789U_EQ_1789U(...) \, +#define Z_IS_1790_EQ_1790(...) \, +#define Z_IS_1790U_EQ_1790(...) \, +#define Z_IS_1790_EQ_1790U(...) \, +#define Z_IS_1790U_EQ_1790U(...) \, +#define Z_IS_1791_EQ_1791(...) \, +#define Z_IS_1791U_EQ_1791(...) \, +#define Z_IS_1791_EQ_1791U(...) \, +#define Z_IS_1791U_EQ_1791U(...) \, +#define Z_IS_1792_EQ_1792(...) \, +#define Z_IS_1792U_EQ_1792(...) \, +#define Z_IS_1792_EQ_1792U(...) \, +#define Z_IS_1792U_EQ_1792U(...) \, +#define Z_IS_1793_EQ_1793(...) \, +#define Z_IS_1793U_EQ_1793(...) \, +#define Z_IS_1793_EQ_1793U(...) \, +#define Z_IS_1793U_EQ_1793U(...) \, +#define Z_IS_1794_EQ_1794(...) \, +#define Z_IS_1794U_EQ_1794(...) \, +#define Z_IS_1794_EQ_1794U(...) \, +#define Z_IS_1794U_EQ_1794U(...) \, +#define Z_IS_1795_EQ_1795(...) \, +#define Z_IS_1795U_EQ_1795(...) \, +#define Z_IS_1795_EQ_1795U(...) \, +#define Z_IS_1795U_EQ_1795U(...) \, +#define Z_IS_1796_EQ_1796(...) \, +#define Z_IS_1796U_EQ_1796(...) \, +#define Z_IS_1796_EQ_1796U(...) \, +#define Z_IS_1796U_EQ_1796U(...) \, +#define Z_IS_1797_EQ_1797(...) \, +#define Z_IS_1797U_EQ_1797(...) \, +#define Z_IS_1797_EQ_1797U(...) \, +#define Z_IS_1797U_EQ_1797U(...) \, +#define Z_IS_1798_EQ_1798(...) \, +#define Z_IS_1798U_EQ_1798(...) \, +#define Z_IS_1798_EQ_1798U(...) \, +#define Z_IS_1798U_EQ_1798U(...) \, +#define Z_IS_1799_EQ_1799(...) \, +#define Z_IS_1799U_EQ_1799(...) \, +#define Z_IS_1799_EQ_1799U(...) \, +#define Z_IS_1799U_EQ_1799U(...) \, +#define Z_IS_1800_EQ_1800(...) \, +#define Z_IS_1800U_EQ_1800(...) \, +#define Z_IS_1800_EQ_1800U(...) \, +#define Z_IS_1800U_EQ_1800U(...) \, +#define Z_IS_1801_EQ_1801(...) \, +#define Z_IS_1801U_EQ_1801(...) \, +#define Z_IS_1801_EQ_1801U(...) \, +#define Z_IS_1801U_EQ_1801U(...) \, +#define Z_IS_1802_EQ_1802(...) \, +#define Z_IS_1802U_EQ_1802(...) \, +#define Z_IS_1802_EQ_1802U(...) \, +#define Z_IS_1802U_EQ_1802U(...) \, +#define Z_IS_1803_EQ_1803(...) \, +#define Z_IS_1803U_EQ_1803(...) \, +#define Z_IS_1803_EQ_1803U(...) \, +#define Z_IS_1803U_EQ_1803U(...) \, +#define Z_IS_1804_EQ_1804(...) \, +#define Z_IS_1804U_EQ_1804(...) \, +#define Z_IS_1804_EQ_1804U(...) \, +#define Z_IS_1804U_EQ_1804U(...) \, +#define Z_IS_1805_EQ_1805(...) \, +#define Z_IS_1805U_EQ_1805(...) \, +#define Z_IS_1805_EQ_1805U(...) \, +#define Z_IS_1805U_EQ_1805U(...) \, +#define Z_IS_1806_EQ_1806(...) \, +#define Z_IS_1806U_EQ_1806(...) \, +#define Z_IS_1806_EQ_1806U(...) \, +#define Z_IS_1806U_EQ_1806U(...) \, +#define Z_IS_1807_EQ_1807(...) \, +#define Z_IS_1807U_EQ_1807(...) \, +#define Z_IS_1807_EQ_1807U(...) \, +#define Z_IS_1807U_EQ_1807U(...) \, +#define Z_IS_1808_EQ_1808(...) \, +#define Z_IS_1808U_EQ_1808(...) \, +#define Z_IS_1808_EQ_1808U(...) \, +#define Z_IS_1808U_EQ_1808U(...) \, +#define Z_IS_1809_EQ_1809(...) \, +#define Z_IS_1809U_EQ_1809(...) \, +#define Z_IS_1809_EQ_1809U(...) \, +#define Z_IS_1809U_EQ_1809U(...) \, +#define Z_IS_1810_EQ_1810(...) \, +#define Z_IS_1810U_EQ_1810(...) \, +#define Z_IS_1810_EQ_1810U(...) \, +#define Z_IS_1810U_EQ_1810U(...) \, +#define Z_IS_1811_EQ_1811(...) \, +#define Z_IS_1811U_EQ_1811(...) \, +#define Z_IS_1811_EQ_1811U(...) \, +#define Z_IS_1811U_EQ_1811U(...) \, +#define Z_IS_1812_EQ_1812(...) \, +#define Z_IS_1812U_EQ_1812(...) \, +#define Z_IS_1812_EQ_1812U(...) \, +#define Z_IS_1812U_EQ_1812U(...) \, +#define Z_IS_1813_EQ_1813(...) \, +#define Z_IS_1813U_EQ_1813(...) \, +#define Z_IS_1813_EQ_1813U(...) \, +#define Z_IS_1813U_EQ_1813U(...) \, +#define Z_IS_1814_EQ_1814(...) \, +#define Z_IS_1814U_EQ_1814(...) \, +#define Z_IS_1814_EQ_1814U(...) \, +#define Z_IS_1814U_EQ_1814U(...) \, +#define Z_IS_1815_EQ_1815(...) \, +#define Z_IS_1815U_EQ_1815(...) \, +#define Z_IS_1815_EQ_1815U(...) \, +#define Z_IS_1815U_EQ_1815U(...) \, +#define Z_IS_1816_EQ_1816(...) \, +#define Z_IS_1816U_EQ_1816(...) \, +#define Z_IS_1816_EQ_1816U(...) \, +#define Z_IS_1816U_EQ_1816U(...) \, +#define Z_IS_1817_EQ_1817(...) \, +#define Z_IS_1817U_EQ_1817(...) \, +#define Z_IS_1817_EQ_1817U(...) \, +#define Z_IS_1817U_EQ_1817U(...) \, +#define Z_IS_1818_EQ_1818(...) \, +#define Z_IS_1818U_EQ_1818(...) \, +#define Z_IS_1818_EQ_1818U(...) \, +#define Z_IS_1818U_EQ_1818U(...) \, +#define Z_IS_1819_EQ_1819(...) \, +#define Z_IS_1819U_EQ_1819(...) \, +#define Z_IS_1819_EQ_1819U(...) \, +#define Z_IS_1819U_EQ_1819U(...) \, +#define Z_IS_1820_EQ_1820(...) \, +#define Z_IS_1820U_EQ_1820(...) \, +#define Z_IS_1820_EQ_1820U(...) \, +#define Z_IS_1820U_EQ_1820U(...) \, +#define Z_IS_1821_EQ_1821(...) \, +#define Z_IS_1821U_EQ_1821(...) \, +#define Z_IS_1821_EQ_1821U(...) \, +#define Z_IS_1821U_EQ_1821U(...) \, +#define Z_IS_1822_EQ_1822(...) \, +#define Z_IS_1822U_EQ_1822(...) \, +#define Z_IS_1822_EQ_1822U(...) \, +#define Z_IS_1822U_EQ_1822U(...) \, +#define Z_IS_1823_EQ_1823(...) \, +#define Z_IS_1823U_EQ_1823(...) \, +#define Z_IS_1823_EQ_1823U(...) \, +#define Z_IS_1823U_EQ_1823U(...) \, +#define Z_IS_1824_EQ_1824(...) \, +#define Z_IS_1824U_EQ_1824(...) \, +#define Z_IS_1824_EQ_1824U(...) \, +#define Z_IS_1824U_EQ_1824U(...) \, +#define Z_IS_1825_EQ_1825(...) \, +#define Z_IS_1825U_EQ_1825(...) \, +#define Z_IS_1825_EQ_1825U(...) \, +#define Z_IS_1825U_EQ_1825U(...) \, +#define Z_IS_1826_EQ_1826(...) \, +#define Z_IS_1826U_EQ_1826(...) \, +#define Z_IS_1826_EQ_1826U(...) \, +#define Z_IS_1826U_EQ_1826U(...) \, +#define Z_IS_1827_EQ_1827(...) \, +#define Z_IS_1827U_EQ_1827(...) \, +#define Z_IS_1827_EQ_1827U(...) \, +#define Z_IS_1827U_EQ_1827U(...) \, +#define Z_IS_1828_EQ_1828(...) \, +#define Z_IS_1828U_EQ_1828(...) \, +#define Z_IS_1828_EQ_1828U(...) \, +#define Z_IS_1828U_EQ_1828U(...) \, +#define Z_IS_1829_EQ_1829(...) \, +#define Z_IS_1829U_EQ_1829(...) \, +#define Z_IS_1829_EQ_1829U(...) \, +#define Z_IS_1829U_EQ_1829U(...) \, +#define Z_IS_1830_EQ_1830(...) \, +#define Z_IS_1830U_EQ_1830(...) \, +#define Z_IS_1830_EQ_1830U(...) \, +#define Z_IS_1830U_EQ_1830U(...) \, +#define Z_IS_1831_EQ_1831(...) \, +#define Z_IS_1831U_EQ_1831(...) \, +#define Z_IS_1831_EQ_1831U(...) \, +#define Z_IS_1831U_EQ_1831U(...) \, +#define Z_IS_1832_EQ_1832(...) \, +#define Z_IS_1832U_EQ_1832(...) \, +#define Z_IS_1832_EQ_1832U(...) \, +#define Z_IS_1832U_EQ_1832U(...) \, +#define Z_IS_1833_EQ_1833(...) \, +#define Z_IS_1833U_EQ_1833(...) \, +#define Z_IS_1833_EQ_1833U(...) \, +#define Z_IS_1833U_EQ_1833U(...) \, +#define Z_IS_1834_EQ_1834(...) \, +#define Z_IS_1834U_EQ_1834(...) \, +#define Z_IS_1834_EQ_1834U(...) \, +#define Z_IS_1834U_EQ_1834U(...) \, +#define Z_IS_1835_EQ_1835(...) \, +#define Z_IS_1835U_EQ_1835(...) \, +#define Z_IS_1835_EQ_1835U(...) \, +#define Z_IS_1835U_EQ_1835U(...) \, +#define Z_IS_1836_EQ_1836(...) \, +#define Z_IS_1836U_EQ_1836(...) \, +#define Z_IS_1836_EQ_1836U(...) \, +#define Z_IS_1836U_EQ_1836U(...) \, +#define Z_IS_1837_EQ_1837(...) \, +#define Z_IS_1837U_EQ_1837(...) \, +#define Z_IS_1837_EQ_1837U(...) \, +#define Z_IS_1837U_EQ_1837U(...) \, +#define Z_IS_1838_EQ_1838(...) \, +#define Z_IS_1838U_EQ_1838(...) \, +#define Z_IS_1838_EQ_1838U(...) \, +#define Z_IS_1838U_EQ_1838U(...) \, +#define Z_IS_1839_EQ_1839(...) \, +#define Z_IS_1839U_EQ_1839(...) \, +#define Z_IS_1839_EQ_1839U(...) \, +#define Z_IS_1839U_EQ_1839U(...) \, +#define Z_IS_1840_EQ_1840(...) \, +#define Z_IS_1840U_EQ_1840(...) \, +#define Z_IS_1840_EQ_1840U(...) \, +#define Z_IS_1840U_EQ_1840U(...) \, +#define Z_IS_1841_EQ_1841(...) \, +#define Z_IS_1841U_EQ_1841(...) \, +#define Z_IS_1841_EQ_1841U(...) \, +#define Z_IS_1841U_EQ_1841U(...) \, +#define Z_IS_1842_EQ_1842(...) \, +#define Z_IS_1842U_EQ_1842(...) \, +#define Z_IS_1842_EQ_1842U(...) \, +#define Z_IS_1842U_EQ_1842U(...) \, +#define Z_IS_1843_EQ_1843(...) \, +#define Z_IS_1843U_EQ_1843(...) \, +#define Z_IS_1843_EQ_1843U(...) \, +#define Z_IS_1843U_EQ_1843U(...) \, +#define Z_IS_1844_EQ_1844(...) \, +#define Z_IS_1844U_EQ_1844(...) \, +#define Z_IS_1844_EQ_1844U(...) \, +#define Z_IS_1844U_EQ_1844U(...) \, +#define Z_IS_1845_EQ_1845(...) \, +#define Z_IS_1845U_EQ_1845(...) \, +#define Z_IS_1845_EQ_1845U(...) \, +#define Z_IS_1845U_EQ_1845U(...) \, +#define Z_IS_1846_EQ_1846(...) \, +#define Z_IS_1846U_EQ_1846(...) \, +#define Z_IS_1846_EQ_1846U(...) \, +#define Z_IS_1846U_EQ_1846U(...) \, +#define Z_IS_1847_EQ_1847(...) \, +#define Z_IS_1847U_EQ_1847(...) \, +#define Z_IS_1847_EQ_1847U(...) \, +#define Z_IS_1847U_EQ_1847U(...) \, +#define Z_IS_1848_EQ_1848(...) \, +#define Z_IS_1848U_EQ_1848(...) \, +#define Z_IS_1848_EQ_1848U(...) \, +#define Z_IS_1848U_EQ_1848U(...) \, +#define Z_IS_1849_EQ_1849(...) \, +#define Z_IS_1849U_EQ_1849(...) \, +#define Z_IS_1849_EQ_1849U(...) \, +#define Z_IS_1849U_EQ_1849U(...) \, +#define Z_IS_1850_EQ_1850(...) \, +#define Z_IS_1850U_EQ_1850(...) \, +#define Z_IS_1850_EQ_1850U(...) \, +#define Z_IS_1850U_EQ_1850U(...) \, +#define Z_IS_1851_EQ_1851(...) \, +#define Z_IS_1851U_EQ_1851(...) \, +#define Z_IS_1851_EQ_1851U(...) \, +#define Z_IS_1851U_EQ_1851U(...) \, +#define Z_IS_1852_EQ_1852(...) \, +#define Z_IS_1852U_EQ_1852(...) \, +#define Z_IS_1852_EQ_1852U(...) \, +#define Z_IS_1852U_EQ_1852U(...) \, +#define Z_IS_1853_EQ_1853(...) \, +#define Z_IS_1853U_EQ_1853(...) \, +#define Z_IS_1853_EQ_1853U(...) \, +#define Z_IS_1853U_EQ_1853U(...) \, +#define Z_IS_1854_EQ_1854(...) \, +#define Z_IS_1854U_EQ_1854(...) \, +#define Z_IS_1854_EQ_1854U(...) \, +#define Z_IS_1854U_EQ_1854U(...) \, +#define Z_IS_1855_EQ_1855(...) \, +#define Z_IS_1855U_EQ_1855(...) \, +#define Z_IS_1855_EQ_1855U(...) \, +#define Z_IS_1855U_EQ_1855U(...) \, +#define Z_IS_1856_EQ_1856(...) \, +#define Z_IS_1856U_EQ_1856(...) \, +#define Z_IS_1856_EQ_1856U(...) \, +#define Z_IS_1856U_EQ_1856U(...) \, +#define Z_IS_1857_EQ_1857(...) \, +#define Z_IS_1857U_EQ_1857(...) \, +#define Z_IS_1857_EQ_1857U(...) \, +#define Z_IS_1857U_EQ_1857U(...) \, +#define Z_IS_1858_EQ_1858(...) \, +#define Z_IS_1858U_EQ_1858(...) \, +#define Z_IS_1858_EQ_1858U(...) \, +#define Z_IS_1858U_EQ_1858U(...) \, +#define Z_IS_1859_EQ_1859(...) \, +#define Z_IS_1859U_EQ_1859(...) \, +#define Z_IS_1859_EQ_1859U(...) \, +#define Z_IS_1859U_EQ_1859U(...) \, +#define Z_IS_1860_EQ_1860(...) \, +#define Z_IS_1860U_EQ_1860(...) \, +#define Z_IS_1860_EQ_1860U(...) \, +#define Z_IS_1860U_EQ_1860U(...) \, +#define Z_IS_1861_EQ_1861(...) \, +#define Z_IS_1861U_EQ_1861(...) \, +#define Z_IS_1861_EQ_1861U(...) \, +#define Z_IS_1861U_EQ_1861U(...) \, +#define Z_IS_1862_EQ_1862(...) \, +#define Z_IS_1862U_EQ_1862(...) \, +#define Z_IS_1862_EQ_1862U(...) \, +#define Z_IS_1862U_EQ_1862U(...) \, +#define Z_IS_1863_EQ_1863(...) \, +#define Z_IS_1863U_EQ_1863(...) \, +#define Z_IS_1863_EQ_1863U(...) \, +#define Z_IS_1863U_EQ_1863U(...) \, +#define Z_IS_1864_EQ_1864(...) \, +#define Z_IS_1864U_EQ_1864(...) \, +#define Z_IS_1864_EQ_1864U(...) \, +#define Z_IS_1864U_EQ_1864U(...) \, +#define Z_IS_1865_EQ_1865(...) \, +#define Z_IS_1865U_EQ_1865(...) \, +#define Z_IS_1865_EQ_1865U(...) \, +#define Z_IS_1865U_EQ_1865U(...) \, +#define Z_IS_1866_EQ_1866(...) \, +#define Z_IS_1866U_EQ_1866(...) \, +#define Z_IS_1866_EQ_1866U(...) \, +#define Z_IS_1866U_EQ_1866U(...) \, +#define Z_IS_1867_EQ_1867(...) \, +#define Z_IS_1867U_EQ_1867(...) \, +#define Z_IS_1867_EQ_1867U(...) \, +#define Z_IS_1867U_EQ_1867U(...) \, +#define Z_IS_1868_EQ_1868(...) \, +#define Z_IS_1868U_EQ_1868(...) \, +#define Z_IS_1868_EQ_1868U(...) \, +#define Z_IS_1868U_EQ_1868U(...) \, +#define Z_IS_1869_EQ_1869(...) \, +#define Z_IS_1869U_EQ_1869(...) \, +#define Z_IS_1869_EQ_1869U(...) \, +#define Z_IS_1869U_EQ_1869U(...) \, +#define Z_IS_1870_EQ_1870(...) \, +#define Z_IS_1870U_EQ_1870(...) \, +#define Z_IS_1870_EQ_1870U(...) \, +#define Z_IS_1870U_EQ_1870U(...) \, +#define Z_IS_1871_EQ_1871(...) \, +#define Z_IS_1871U_EQ_1871(...) \, +#define Z_IS_1871_EQ_1871U(...) \, +#define Z_IS_1871U_EQ_1871U(...) \, +#define Z_IS_1872_EQ_1872(...) \, +#define Z_IS_1872U_EQ_1872(...) \, +#define Z_IS_1872_EQ_1872U(...) \, +#define Z_IS_1872U_EQ_1872U(...) \, +#define Z_IS_1873_EQ_1873(...) \, +#define Z_IS_1873U_EQ_1873(...) \, +#define Z_IS_1873_EQ_1873U(...) \, +#define Z_IS_1873U_EQ_1873U(...) \, +#define Z_IS_1874_EQ_1874(...) \, +#define Z_IS_1874U_EQ_1874(...) \, +#define Z_IS_1874_EQ_1874U(...) \, +#define Z_IS_1874U_EQ_1874U(...) \, +#define Z_IS_1875_EQ_1875(...) \, +#define Z_IS_1875U_EQ_1875(...) \, +#define Z_IS_1875_EQ_1875U(...) \, +#define Z_IS_1875U_EQ_1875U(...) \, +#define Z_IS_1876_EQ_1876(...) \, +#define Z_IS_1876U_EQ_1876(...) \, +#define Z_IS_1876_EQ_1876U(...) \, +#define Z_IS_1876U_EQ_1876U(...) \, +#define Z_IS_1877_EQ_1877(...) \, +#define Z_IS_1877U_EQ_1877(...) \, +#define Z_IS_1877_EQ_1877U(...) \, +#define Z_IS_1877U_EQ_1877U(...) \, +#define Z_IS_1878_EQ_1878(...) \, +#define Z_IS_1878U_EQ_1878(...) \, +#define Z_IS_1878_EQ_1878U(...) \, +#define Z_IS_1878U_EQ_1878U(...) \, +#define Z_IS_1879_EQ_1879(...) \, +#define Z_IS_1879U_EQ_1879(...) \, +#define Z_IS_1879_EQ_1879U(...) \, +#define Z_IS_1879U_EQ_1879U(...) \, +#define Z_IS_1880_EQ_1880(...) \, +#define Z_IS_1880U_EQ_1880(...) \, +#define Z_IS_1880_EQ_1880U(...) \, +#define Z_IS_1880U_EQ_1880U(...) \, +#define Z_IS_1881_EQ_1881(...) \, +#define Z_IS_1881U_EQ_1881(...) \, +#define Z_IS_1881_EQ_1881U(...) \, +#define Z_IS_1881U_EQ_1881U(...) \, +#define Z_IS_1882_EQ_1882(...) \, +#define Z_IS_1882U_EQ_1882(...) \, +#define Z_IS_1882_EQ_1882U(...) \, +#define Z_IS_1882U_EQ_1882U(...) \, +#define Z_IS_1883_EQ_1883(...) \, +#define Z_IS_1883U_EQ_1883(...) \, +#define Z_IS_1883_EQ_1883U(...) \, +#define Z_IS_1883U_EQ_1883U(...) \, +#define Z_IS_1884_EQ_1884(...) \, +#define Z_IS_1884U_EQ_1884(...) \, +#define Z_IS_1884_EQ_1884U(...) \, +#define Z_IS_1884U_EQ_1884U(...) \, +#define Z_IS_1885_EQ_1885(...) \, +#define Z_IS_1885U_EQ_1885(...) \, +#define Z_IS_1885_EQ_1885U(...) \, +#define Z_IS_1885U_EQ_1885U(...) \, +#define Z_IS_1886_EQ_1886(...) \, +#define Z_IS_1886U_EQ_1886(...) \, +#define Z_IS_1886_EQ_1886U(...) \, +#define Z_IS_1886U_EQ_1886U(...) \, +#define Z_IS_1887_EQ_1887(...) \, +#define Z_IS_1887U_EQ_1887(...) \, +#define Z_IS_1887_EQ_1887U(...) \, +#define Z_IS_1887U_EQ_1887U(...) \, +#define Z_IS_1888_EQ_1888(...) \, +#define Z_IS_1888U_EQ_1888(...) \, +#define Z_IS_1888_EQ_1888U(...) \, +#define Z_IS_1888U_EQ_1888U(...) \, +#define Z_IS_1889_EQ_1889(...) \, +#define Z_IS_1889U_EQ_1889(...) \, +#define Z_IS_1889_EQ_1889U(...) \, +#define Z_IS_1889U_EQ_1889U(...) \, +#define Z_IS_1890_EQ_1890(...) \, +#define Z_IS_1890U_EQ_1890(...) \, +#define Z_IS_1890_EQ_1890U(...) \, +#define Z_IS_1890U_EQ_1890U(...) \, +#define Z_IS_1891_EQ_1891(...) \, +#define Z_IS_1891U_EQ_1891(...) \, +#define Z_IS_1891_EQ_1891U(...) \, +#define Z_IS_1891U_EQ_1891U(...) \, +#define Z_IS_1892_EQ_1892(...) \, +#define Z_IS_1892U_EQ_1892(...) \, +#define Z_IS_1892_EQ_1892U(...) \, +#define Z_IS_1892U_EQ_1892U(...) \, +#define Z_IS_1893_EQ_1893(...) \, +#define Z_IS_1893U_EQ_1893(...) \, +#define Z_IS_1893_EQ_1893U(...) \, +#define Z_IS_1893U_EQ_1893U(...) \, +#define Z_IS_1894_EQ_1894(...) \, +#define Z_IS_1894U_EQ_1894(...) \, +#define Z_IS_1894_EQ_1894U(...) \, +#define Z_IS_1894U_EQ_1894U(...) \, +#define Z_IS_1895_EQ_1895(...) \, +#define Z_IS_1895U_EQ_1895(...) \, +#define Z_IS_1895_EQ_1895U(...) \, +#define Z_IS_1895U_EQ_1895U(...) \, +#define Z_IS_1896_EQ_1896(...) \, +#define Z_IS_1896U_EQ_1896(...) \, +#define Z_IS_1896_EQ_1896U(...) \, +#define Z_IS_1896U_EQ_1896U(...) \, +#define Z_IS_1897_EQ_1897(...) \, +#define Z_IS_1897U_EQ_1897(...) \, +#define Z_IS_1897_EQ_1897U(...) \, +#define Z_IS_1897U_EQ_1897U(...) \, +#define Z_IS_1898_EQ_1898(...) \, +#define Z_IS_1898U_EQ_1898(...) \, +#define Z_IS_1898_EQ_1898U(...) \, +#define Z_IS_1898U_EQ_1898U(...) \, +#define Z_IS_1899_EQ_1899(...) \, +#define Z_IS_1899U_EQ_1899(...) \, +#define Z_IS_1899_EQ_1899U(...) \, +#define Z_IS_1899U_EQ_1899U(...) \, +#define Z_IS_1900_EQ_1900(...) \, +#define Z_IS_1900U_EQ_1900(...) \, +#define Z_IS_1900_EQ_1900U(...) \, +#define Z_IS_1900U_EQ_1900U(...) \, +#define Z_IS_1901_EQ_1901(...) \, +#define Z_IS_1901U_EQ_1901(...) \, +#define Z_IS_1901_EQ_1901U(...) \, +#define Z_IS_1901U_EQ_1901U(...) \, +#define Z_IS_1902_EQ_1902(...) \, +#define Z_IS_1902U_EQ_1902(...) \, +#define Z_IS_1902_EQ_1902U(...) \, +#define Z_IS_1902U_EQ_1902U(...) \, +#define Z_IS_1903_EQ_1903(...) \, +#define Z_IS_1903U_EQ_1903(...) \, +#define Z_IS_1903_EQ_1903U(...) \, +#define Z_IS_1903U_EQ_1903U(...) \, +#define Z_IS_1904_EQ_1904(...) \, +#define Z_IS_1904U_EQ_1904(...) \, +#define Z_IS_1904_EQ_1904U(...) \, +#define Z_IS_1904U_EQ_1904U(...) \, +#define Z_IS_1905_EQ_1905(...) \, +#define Z_IS_1905U_EQ_1905(...) \, +#define Z_IS_1905_EQ_1905U(...) \, +#define Z_IS_1905U_EQ_1905U(...) \, +#define Z_IS_1906_EQ_1906(...) \, +#define Z_IS_1906U_EQ_1906(...) \, +#define Z_IS_1906_EQ_1906U(...) \, +#define Z_IS_1906U_EQ_1906U(...) \, +#define Z_IS_1907_EQ_1907(...) \, +#define Z_IS_1907U_EQ_1907(...) \, +#define Z_IS_1907_EQ_1907U(...) \, +#define Z_IS_1907U_EQ_1907U(...) \, +#define Z_IS_1908_EQ_1908(...) \, +#define Z_IS_1908U_EQ_1908(...) \, +#define Z_IS_1908_EQ_1908U(...) \, +#define Z_IS_1908U_EQ_1908U(...) \, +#define Z_IS_1909_EQ_1909(...) \, +#define Z_IS_1909U_EQ_1909(...) \, +#define Z_IS_1909_EQ_1909U(...) \, +#define Z_IS_1909U_EQ_1909U(...) \, +#define Z_IS_1910_EQ_1910(...) \, +#define Z_IS_1910U_EQ_1910(...) \, +#define Z_IS_1910_EQ_1910U(...) \, +#define Z_IS_1910U_EQ_1910U(...) \, +#define Z_IS_1911_EQ_1911(...) \, +#define Z_IS_1911U_EQ_1911(...) \, +#define Z_IS_1911_EQ_1911U(...) \, +#define Z_IS_1911U_EQ_1911U(...) \, +#define Z_IS_1912_EQ_1912(...) \, +#define Z_IS_1912U_EQ_1912(...) \, +#define Z_IS_1912_EQ_1912U(...) \, +#define Z_IS_1912U_EQ_1912U(...) \, +#define Z_IS_1913_EQ_1913(...) \, +#define Z_IS_1913U_EQ_1913(...) \, +#define Z_IS_1913_EQ_1913U(...) \, +#define Z_IS_1913U_EQ_1913U(...) \, +#define Z_IS_1914_EQ_1914(...) \, +#define Z_IS_1914U_EQ_1914(...) \, +#define Z_IS_1914_EQ_1914U(...) \, +#define Z_IS_1914U_EQ_1914U(...) \, +#define Z_IS_1915_EQ_1915(...) \, +#define Z_IS_1915U_EQ_1915(...) \, +#define Z_IS_1915_EQ_1915U(...) \, +#define Z_IS_1915U_EQ_1915U(...) \, +#define Z_IS_1916_EQ_1916(...) \, +#define Z_IS_1916U_EQ_1916(...) \, +#define Z_IS_1916_EQ_1916U(...) \, +#define Z_IS_1916U_EQ_1916U(...) \, +#define Z_IS_1917_EQ_1917(...) \, +#define Z_IS_1917U_EQ_1917(...) \, +#define Z_IS_1917_EQ_1917U(...) \, +#define Z_IS_1917U_EQ_1917U(...) \, +#define Z_IS_1918_EQ_1918(...) \, +#define Z_IS_1918U_EQ_1918(...) \, +#define Z_IS_1918_EQ_1918U(...) \, +#define Z_IS_1918U_EQ_1918U(...) \, +#define Z_IS_1919_EQ_1919(...) \, +#define Z_IS_1919U_EQ_1919(...) \, +#define Z_IS_1919_EQ_1919U(...) \, +#define Z_IS_1919U_EQ_1919U(...) \, +#define Z_IS_1920_EQ_1920(...) \, +#define Z_IS_1920U_EQ_1920(...) \, +#define Z_IS_1920_EQ_1920U(...) \, +#define Z_IS_1920U_EQ_1920U(...) \, +#define Z_IS_1921_EQ_1921(...) \, +#define Z_IS_1921U_EQ_1921(...) \, +#define Z_IS_1921_EQ_1921U(...) \, +#define Z_IS_1921U_EQ_1921U(...) \, +#define Z_IS_1922_EQ_1922(...) \, +#define Z_IS_1922U_EQ_1922(...) \, +#define Z_IS_1922_EQ_1922U(...) \, +#define Z_IS_1922U_EQ_1922U(...) \, +#define Z_IS_1923_EQ_1923(...) \, +#define Z_IS_1923U_EQ_1923(...) \, +#define Z_IS_1923_EQ_1923U(...) \, +#define Z_IS_1923U_EQ_1923U(...) \, +#define Z_IS_1924_EQ_1924(...) \, +#define Z_IS_1924U_EQ_1924(...) \, +#define Z_IS_1924_EQ_1924U(...) \, +#define Z_IS_1924U_EQ_1924U(...) \, +#define Z_IS_1925_EQ_1925(...) \, +#define Z_IS_1925U_EQ_1925(...) \, +#define Z_IS_1925_EQ_1925U(...) \, +#define Z_IS_1925U_EQ_1925U(...) \, +#define Z_IS_1926_EQ_1926(...) \, +#define Z_IS_1926U_EQ_1926(...) \, +#define Z_IS_1926_EQ_1926U(...) \, +#define Z_IS_1926U_EQ_1926U(...) \, +#define Z_IS_1927_EQ_1927(...) \, +#define Z_IS_1927U_EQ_1927(...) \, +#define Z_IS_1927_EQ_1927U(...) \, +#define Z_IS_1927U_EQ_1927U(...) \, +#define Z_IS_1928_EQ_1928(...) \, +#define Z_IS_1928U_EQ_1928(...) \, +#define Z_IS_1928_EQ_1928U(...) \, +#define Z_IS_1928U_EQ_1928U(...) \, +#define Z_IS_1929_EQ_1929(...) \, +#define Z_IS_1929U_EQ_1929(...) \, +#define Z_IS_1929_EQ_1929U(...) \, +#define Z_IS_1929U_EQ_1929U(...) \, +#define Z_IS_1930_EQ_1930(...) \, +#define Z_IS_1930U_EQ_1930(...) \, +#define Z_IS_1930_EQ_1930U(...) \, +#define Z_IS_1930U_EQ_1930U(...) \, +#define Z_IS_1931_EQ_1931(...) \, +#define Z_IS_1931U_EQ_1931(...) \, +#define Z_IS_1931_EQ_1931U(...) \, +#define Z_IS_1931U_EQ_1931U(...) \, +#define Z_IS_1932_EQ_1932(...) \, +#define Z_IS_1932U_EQ_1932(...) \, +#define Z_IS_1932_EQ_1932U(...) \, +#define Z_IS_1932U_EQ_1932U(...) \, +#define Z_IS_1933_EQ_1933(...) \, +#define Z_IS_1933U_EQ_1933(...) \, +#define Z_IS_1933_EQ_1933U(...) \, +#define Z_IS_1933U_EQ_1933U(...) \, +#define Z_IS_1934_EQ_1934(...) \, +#define Z_IS_1934U_EQ_1934(...) \, +#define Z_IS_1934_EQ_1934U(...) \, +#define Z_IS_1934U_EQ_1934U(...) \, +#define Z_IS_1935_EQ_1935(...) \, +#define Z_IS_1935U_EQ_1935(...) \, +#define Z_IS_1935_EQ_1935U(...) \, +#define Z_IS_1935U_EQ_1935U(...) \, +#define Z_IS_1936_EQ_1936(...) \, +#define Z_IS_1936U_EQ_1936(...) \, +#define Z_IS_1936_EQ_1936U(...) \, +#define Z_IS_1936U_EQ_1936U(...) \, +#define Z_IS_1937_EQ_1937(...) \, +#define Z_IS_1937U_EQ_1937(...) \, +#define Z_IS_1937_EQ_1937U(...) \, +#define Z_IS_1937U_EQ_1937U(...) \, +#define Z_IS_1938_EQ_1938(...) \, +#define Z_IS_1938U_EQ_1938(...) \, +#define Z_IS_1938_EQ_1938U(...) \, +#define Z_IS_1938U_EQ_1938U(...) \, +#define Z_IS_1939_EQ_1939(...) \, +#define Z_IS_1939U_EQ_1939(...) \, +#define Z_IS_1939_EQ_1939U(...) \, +#define Z_IS_1939U_EQ_1939U(...) \, +#define Z_IS_1940_EQ_1940(...) \, +#define Z_IS_1940U_EQ_1940(...) \, +#define Z_IS_1940_EQ_1940U(...) \, +#define Z_IS_1940U_EQ_1940U(...) \, +#define Z_IS_1941_EQ_1941(...) \, +#define Z_IS_1941U_EQ_1941(...) \, +#define Z_IS_1941_EQ_1941U(...) \, +#define Z_IS_1941U_EQ_1941U(...) \, +#define Z_IS_1942_EQ_1942(...) \, +#define Z_IS_1942U_EQ_1942(...) \, +#define Z_IS_1942_EQ_1942U(...) \, +#define Z_IS_1942U_EQ_1942U(...) \, +#define Z_IS_1943_EQ_1943(...) \, +#define Z_IS_1943U_EQ_1943(...) \, +#define Z_IS_1943_EQ_1943U(...) \, +#define Z_IS_1943U_EQ_1943U(...) \, +#define Z_IS_1944_EQ_1944(...) \, +#define Z_IS_1944U_EQ_1944(...) \, +#define Z_IS_1944_EQ_1944U(...) \, +#define Z_IS_1944U_EQ_1944U(...) \, +#define Z_IS_1945_EQ_1945(...) \, +#define Z_IS_1945U_EQ_1945(...) \, +#define Z_IS_1945_EQ_1945U(...) \, +#define Z_IS_1945U_EQ_1945U(...) \, +#define Z_IS_1946_EQ_1946(...) \, +#define Z_IS_1946U_EQ_1946(...) \, +#define Z_IS_1946_EQ_1946U(...) \, +#define Z_IS_1946U_EQ_1946U(...) \, +#define Z_IS_1947_EQ_1947(...) \, +#define Z_IS_1947U_EQ_1947(...) \, +#define Z_IS_1947_EQ_1947U(...) \, +#define Z_IS_1947U_EQ_1947U(...) \, +#define Z_IS_1948_EQ_1948(...) \, +#define Z_IS_1948U_EQ_1948(...) \, +#define Z_IS_1948_EQ_1948U(...) \, +#define Z_IS_1948U_EQ_1948U(...) \, +#define Z_IS_1949_EQ_1949(...) \, +#define Z_IS_1949U_EQ_1949(...) \, +#define Z_IS_1949_EQ_1949U(...) \, +#define Z_IS_1949U_EQ_1949U(...) \, +#define Z_IS_1950_EQ_1950(...) \, +#define Z_IS_1950U_EQ_1950(...) \, +#define Z_IS_1950_EQ_1950U(...) \, +#define Z_IS_1950U_EQ_1950U(...) \, +#define Z_IS_1951_EQ_1951(...) \, +#define Z_IS_1951U_EQ_1951(...) \, +#define Z_IS_1951_EQ_1951U(...) \, +#define Z_IS_1951U_EQ_1951U(...) \, +#define Z_IS_1952_EQ_1952(...) \, +#define Z_IS_1952U_EQ_1952(...) \, +#define Z_IS_1952_EQ_1952U(...) \, +#define Z_IS_1952U_EQ_1952U(...) \, +#define Z_IS_1953_EQ_1953(...) \, +#define Z_IS_1953U_EQ_1953(...) \, +#define Z_IS_1953_EQ_1953U(...) \, +#define Z_IS_1953U_EQ_1953U(...) \, +#define Z_IS_1954_EQ_1954(...) \, +#define Z_IS_1954U_EQ_1954(...) \, +#define Z_IS_1954_EQ_1954U(...) \, +#define Z_IS_1954U_EQ_1954U(...) \, +#define Z_IS_1955_EQ_1955(...) \, +#define Z_IS_1955U_EQ_1955(...) \, +#define Z_IS_1955_EQ_1955U(...) \, +#define Z_IS_1955U_EQ_1955U(...) \, +#define Z_IS_1956_EQ_1956(...) \, +#define Z_IS_1956U_EQ_1956(...) \, +#define Z_IS_1956_EQ_1956U(...) \, +#define Z_IS_1956U_EQ_1956U(...) \, +#define Z_IS_1957_EQ_1957(...) \, +#define Z_IS_1957U_EQ_1957(...) \, +#define Z_IS_1957_EQ_1957U(...) \, +#define Z_IS_1957U_EQ_1957U(...) \, +#define Z_IS_1958_EQ_1958(...) \, +#define Z_IS_1958U_EQ_1958(...) \, +#define Z_IS_1958_EQ_1958U(...) \, +#define Z_IS_1958U_EQ_1958U(...) \, +#define Z_IS_1959_EQ_1959(...) \, +#define Z_IS_1959U_EQ_1959(...) \, +#define Z_IS_1959_EQ_1959U(...) \, +#define Z_IS_1959U_EQ_1959U(...) \, +#define Z_IS_1960_EQ_1960(...) \, +#define Z_IS_1960U_EQ_1960(...) \, +#define Z_IS_1960_EQ_1960U(...) \, +#define Z_IS_1960U_EQ_1960U(...) \, +#define Z_IS_1961_EQ_1961(...) \, +#define Z_IS_1961U_EQ_1961(...) \, +#define Z_IS_1961_EQ_1961U(...) \, +#define Z_IS_1961U_EQ_1961U(...) \, +#define Z_IS_1962_EQ_1962(...) \, +#define Z_IS_1962U_EQ_1962(...) \, +#define Z_IS_1962_EQ_1962U(...) \, +#define Z_IS_1962U_EQ_1962U(...) \, +#define Z_IS_1963_EQ_1963(...) \, +#define Z_IS_1963U_EQ_1963(...) \, +#define Z_IS_1963_EQ_1963U(...) \, +#define Z_IS_1963U_EQ_1963U(...) \, +#define Z_IS_1964_EQ_1964(...) \, +#define Z_IS_1964U_EQ_1964(...) \, +#define Z_IS_1964_EQ_1964U(...) \, +#define Z_IS_1964U_EQ_1964U(...) \, +#define Z_IS_1965_EQ_1965(...) \, +#define Z_IS_1965U_EQ_1965(...) \, +#define Z_IS_1965_EQ_1965U(...) \, +#define Z_IS_1965U_EQ_1965U(...) \, +#define Z_IS_1966_EQ_1966(...) \, +#define Z_IS_1966U_EQ_1966(...) \, +#define Z_IS_1966_EQ_1966U(...) \, +#define Z_IS_1966U_EQ_1966U(...) \, +#define Z_IS_1967_EQ_1967(...) \, +#define Z_IS_1967U_EQ_1967(...) \, +#define Z_IS_1967_EQ_1967U(...) \, +#define Z_IS_1967U_EQ_1967U(...) \, +#define Z_IS_1968_EQ_1968(...) \, +#define Z_IS_1968U_EQ_1968(...) \, +#define Z_IS_1968_EQ_1968U(...) \, +#define Z_IS_1968U_EQ_1968U(...) \, +#define Z_IS_1969_EQ_1969(...) \, +#define Z_IS_1969U_EQ_1969(...) \, +#define Z_IS_1969_EQ_1969U(...) \, +#define Z_IS_1969U_EQ_1969U(...) \, +#define Z_IS_1970_EQ_1970(...) \, +#define Z_IS_1970U_EQ_1970(...) \, +#define Z_IS_1970_EQ_1970U(...) \, +#define Z_IS_1970U_EQ_1970U(...) \, +#define Z_IS_1971_EQ_1971(...) \, +#define Z_IS_1971U_EQ_1971(...) \, +#define Z_IS_1971_EQ_1971U(...) \, +#define Z_IS_1971U_EQ_1971U(...) \, +#define Z_IS_1972_EQ_1972(...) \, +#define Z_IS_1972U_EQ_1972(...) \, +#define Z_IS_1972_EQ_1972U(...) \, +#define Z_IS_1972U_EQ_1972U(...) \, +#define Z_IS_1973_EQ_1973(...) \, +#define Z_IS_1973U_EQ_1973(...) \, +#define Z_IS_1973_EQ_1973U(...) \, +#define Z_IS_1973U_EQ_1973U(...) \, +#define Z_IS_1974_EQ_1974(...) \, +#define Z_IS_1974U_EQ_1974(...) \, +#define Z_IS_1974_EQ_1974U(...) \, +#define Z_IS_1974U_EQ_1974U(...) \, +#define Z_IS_1975_EQ_1975(...) \, +#define Z_IS_1975U_EQ_1975(...) \, +#define Z_IS_1975_EQ_1975U(...) \, +#define Z_IS_1975U_EQ_1975U(...) \, +#define Z_IS_1976_EQ_1976(...) \, +#define Z_IS_1976U_EQ_1976(...) \, +#define Z_IS_1976_EQ_1976U(...) \, +#define Z_IS_1976U_EQ_1976U(...) \, +#define Z_IS_1977_EQ_1977(...) \, +#define Z_IS_1977U_EQ_1977(...) \, +#define Z_IS_1977_EQ_1977U(...) \, +#define Z_IS_1977U_EQ_1977U(...) \, +#define Z_IS_1978_EQ_1978(...) \, +#define Z_IS_1978U_EQ_1978(...) \, +#define Z_IS_1978_EQ_1978U(...) \, +#define Z_IS_1978U_EQ_1978U(...) \, +#define Z_IS_1979_EQ_1979(...) \, +#define Z_IS_1979U_EQ_1979(...) \, +#define Z_IS_1979_EQ_1979U(...) \, +#define Z_IS_1979U_EQ_1979U(...) \, +#define Z_IS_1980_EQ_1980(...) \, +#define Z_IS_1980U_EQ_1980(...) \, +#define Z_IS_1980_EQ_1980U(...) \, +#define Z_IS_1980U_EQ_1980U(...) \, +#define Z_IS_1981_EQ_1981(...) \, +#define Z_IS_1981U_EQ_1981(...) \, +#define Z_IS_1981_EQ_1981U(...) \, +#define Z_IS_1981U_EQ_1981U(...) \, +#define Z_IS_1982_EQ_1982(...) \, +#define Z_IS_1982U_EQ_1982(...) \, +#define Z_IS_1982_EQ_1982U(...) \, +#define Z_IS_1982U_EQ_1982U(...) \, +#define Z_IS_1983_EQ_1983(...) \, +#define Z_IS_1983U_EQ_1983(...) \, +#define Z_IS_1983_EQ_1983U(...) \, +#define Z_IS_1983U_EQ_1983U(...) \, +#define Z_IS_1984_EQ_1984(...) \, +#define Z_IS_1984U_EQ_1984(...) \, +#define Z_IS_1984_EQ_1984U(...) \, +#define Z_IS_1984U_EQ_1984U(...) \, +#define Z_IS_1985_EQ_1985(...) \, +#define Z_IS_1985U_EQ_1985(...) \, +#define Z_IS_1985_EQ_1985U(...) \, +#define Z_IS_1985U_EQ_1985U(...) \, +#define Z_IS_1986_EQ_1986(...) \, +#define Z_IS_1986U_EQ_1986(...) \, +#define Z_IS_1986_EQ_1986U(...) \, +#define Z_IS_1986U_EQ_1986U(...) \, +#define Z_IS_1987_EQ_1987(...) \, +#define Z_IS_1987U_EQ_1987(...) \, +#define Z_IS_1987_EQ_1987U(...) \, +#define Z_IS_1987U_EQ_1987U(...) \, +#define Z_IS_1988_EQ_1988(...) \, +#define Z_IS_1988U_EQ_1988(...) \, +#define Z_IS_1988_EQ_1988U(...) \, +#define Z_IS_1988U_EQ_1988U(...) \, +#define Z_IS_1989_EQ_1989(...) \, +#define Z_IS_1989U_EQ_1989(...) \, +#define Z_IS_1989_EQ_1989U(...) \, +#define Z_IS_1989U_EQ_1989U(...) \, +#define Z_IS_1990_EQ_1990(...) \, +#define Z_IS_1990U_EQ_1990(...) \, +#define Z_IS_1990_EQ_1990U(...) \, +#define Z_IS_1990U_EQ_1990U(...) \, +#define Z_IS_1991_EQ_1991(...) \, +#define Z_IS_1991U_EQ_1991(...) \, +#define Z_IS_1991_EQ_1991U(...) \, +#define Z_IS_1991U_EQ_1991U(...) \, +#define Z_IS_1992_EQ_1992(...) \, +#define Z_IS_1992U_EQ_1992(...) \, +#define Z_IS_1992_EQ_1992U(...) \, +#define Z_IS_1992U_EQ_1992U(...) \, +#define Z_IS_1993_EQ_1993(...) \, +#define Z_IS_1993U_EQ_1993(...) \, +#define Z_IS_1993_EQ_1993U(...) \, +#define Z_IS_1993U_EQ_1993U(...) \, +#define Z_IS_1994_EQ_1994(...) \, +#define Z_IS_1994U_EQ_1994(...) \, +#define Z_IS_1994_EQ_1994U(...) \, +#define Z_IS_1994U_EQ_1994U(...) \, +#define Z_IS_1995_EQ_1995(...) \, +#define Z_IS_1995U_EQ_1995(...) \, +#define Z_IS_1995_EQ_1995U(...) \, +#define Z_IS_1995U_EQ_1995U(...) \, +#define Z_IS_1996_EQ_1996(...) \, +#define Z_IS_1996U_EQ_1996(...) \, +#define Z_IS_1996_EQ_1996U(...) \, +#define Z_IS_1996U_EQ_1996U(...) \, +#define Z_IS_1997_EQ_1997(...) \, +#define Z_IS_1997U_EQ_1997(...) \, +#define Z_IS_1997_EQ_1997U(...) \, +#define Z_IS_1997U_EQ_1997U(...) \, +#define Z_IS_1998_EQ_1998(...) \, +#define Z_IS_1998U_EQ_1998(...) \, +#define Z_IS_1998_EQ_1998U(...) \, +#define Z_IS_1998U_EQ_1998U(...) \, +#define Z_IS_1999_EQ_1999(...) \, +#define Z_IS_1999U_EQ_1999(...) \, +#define Z_IS_1999_EQ_1999U(...) \, +#define Z_IS_1999U_EQ_1999U(...) \, +#define Z_IS_2000_EQ_2000(...) \, +#define Z_IS_2000U_EQ_2000(...) \, +#define Z_IS_2000_EQ_2000U(...) \, +#define Z_IS_2000U_EQ_2000U(...) \, +#define Z_IS_2001_EQ_2001(...) \, +#define Z_IS_2001U_EQ_2001(...) \, +#define Z_IS_2001_EQ_2001U(...) \, +#define Z_IS_2001U_EQ_2001U(...) \, +#define Z_IS_2002_EQ_2002(...) \, +#define Z_IS_2002U_EQ_2002(...) \, +#define Z_IS_2002_EQ_2002U(...) \, +#define Z_IS_2002U_EQ_2002U(...) \, +#define Z_IS_2003_EQ_2003(...) \, +#define Z_IS_2003U_EQ_2003(...) \, +#define Z_IS_2003_EQ_2003U(...) \, +#define Z_IS_2003U_EQ_2003U(...) \, +#define Z_IS_2004_EQ_2004(...) \, +#define Z_IS_2004U_EQ_2004(...) \, +#define Z_IS_2004_EQ_2004U(...) \, +#define Z_IS_2004U_EQ_2004U(...) \, +#define Z_IS_2005_EQ_2005(...) \, +#define Z_IS_2005U_EQ_2005(...) \, +#define Z_IS_2005_EQ_2005U(...) \, +#define Z_IS_2005U_EQ_2005U(...) \, +#define Z_IS_2006_EQ_2006(...) \, +#define Z_IS_2006U_EQ_2006(...) \, +#define Z_IS_2006_EQ_2006U(...) \, +#define Z_IS_2006U_EQ_2006U(...) \, +#define Z_IS_2007_EQ_2007(...) \, +#define Z_IS_2007U_EQ_2007(...) \, +#define Z_IS_2007_EQ_2007U(...) \, +#define Z_IS_2007U_EQ_2007U(...) \, +#define Z_IS_2008_EQ_2008(...) \, +#define Z_IS_2008U_EQ_2008(...) \, +#define Z_IS_2008_EQ_2008U(...) \, +#define Z_IS_2008U_EQ_2008U(...) \, +#define Z_IS_2009_EQ_2009(...) \, +#define Z_IS_2009U_EQ_2009(...) \, +#define Z_IS_2009_EQ_2009U(...) \, +#define Z_IS_2009U_EQ_2009U(...) \, +#define Z_IS_2010_EQ_2010(...) \, +#define Z_IS_2010U_EQ_2010(...) \, +#define Z_IS_2010_EQ_2010U(...) \, +#define Z_IS_2010U_EQ_2010U(...) \, +#define Z_IS_2011_EQ_2011(...) \, +#define Z_IS_2011U_EQ_2011(...) \, +#define Z_IS_2011_EQ_2011U(...) \, +#define Z_IS_2011U_EQ_2011U(...) \, +#define Z_IS_2012_EQ_2012(...) \, +#define Z_IS_2012U_EQ_2012(...) \, +#define Z_IS_2012_EQ_2012U(...) \, +#define Z_IS_2012U_EQ_2012U(...) \, +#define Z_IS_2013_EQ_2013(...) \, +#define Z_IS_2013U_EQ_2013(...) \, +#define Z_IS_2013_EQ_2013U(...) \, +#define Z_IS_2013U_EQ_2013U(...) \, +#define Z_IS_2014_EQ_2014(...) \, +#define Z_IS_2014U_EQ_2014(...) \, +#define Z_IS_2014_EQ_2014U(...) \, +#define Z_IS_2014U_EQ_2014U(...) \, +#define Z_IS_2015_EQ_2015(...) \, +#define Z_IS_2015U_EQ_2015(...) \, +#define Z_IS_2015_EQ_2015U(...) \, +#define Z_IS_2015U_EQ_2015U(...) \, +#define Z_IS_2016_EQ_2016(...) \, +#define Z_IS_2016U_EQ_2016(...) \, +#define Z_IS_2016_EQ_2016U(...) \, +#define Z_IS_2016U_EQ_2016U(...) \, +#define Z_IS_2017_EQ_2017(...) \, +#define Z_IS_2017U_EQ_2017(...) \, +#define Z_IS_2017_EQ_2017U(...) \, +#define Z_IS_2017U_EQ_2017U(...) \, +#define Z_IS_2018_EQ_2018(...) \, +#define Z_IS_2018U_EQ_2018(...) \, +#define Z_IS_2018_EQ_2018U(...) \, +#define Z_IS_2018U_EQ_2018U(...) \, +#define Z_IS_2019_EQ_2019(...) \, +#define Z_IS_2019U_EQ_2019(...) \, +#define Z_IS_2019_EQ_2019U(...) \, +#define Z_IS_2019U_EQ_2019U(...) \, +#define Z_IS_2020_EQ_2020(...) \, +#define Z_IS_2020U_EQ_2020(...) \, +#define Z_IS_2020_EQ_2020U(...) \, +#define Z_IS_2020U_EQ_2020U(...) \, +#define Z_IS_2021_EQ_2021(...) \, +#define Z_IS_2021U_EQ_2021(...) \, +#define Z_IS_2021_EQ_2021U(...) \, +#define Z_IS_2021U_EQ_2021U(...) \, +#define Z_IS_2022_EQ_2022(...) \, +#define Z_IS_2022U_EQ_2022(...) \, +#define Z_IS_2022_EQ_2022U(...) \, +#define Z_IS_2022U_EQ_2022U(...) \, +#define Z_IS_2023_EQ_2023(...) \, +#define Z_IS_2023U_EQ_2023(...) \, +#define Z_IS_2023_EQ_2023U(...) \, +#define Z_IS_2023U_EQ_2023U(...) \, +#define Z_IS_2024_EQ_2024(...) \, +#define Z_IS_2024U_EQ_2024(...) \, +#define Z_IS_2024_EQ_2024U(...) \, +#define Z_IS_2024U_EQ_2024U(...) \, +#define Z_IS_2025_EQ_2025(...) \, +#define Z_IS_2025U_EQ_2025(...) \, +#define Z_IS_2025_EQ_2025U(...) \, +#define Z_IS_2025U_EQ_2025U(...) \, +#define Z_IS_2026_EQ_2026(...) \, +#define Z_IS_2026U_EQ_2026(...) \, +#define Z_IS_2026_EQ_2026U(...) \, +#define Z_IS_2026U_EQ_2026U(...) \, +#define Z_IS_2027_EQ_2027(...) \, +#define Z_IS_2027U_EQ_2027(...) \, +#define Z_IS_2027_EQ_2027U(...) \, +#define Z_IS_2027U_EQ_2027U(...) \, +#define Z_IS_2028_EQ_2028(...) \, +#define Z_IS_2028U_EQ_2028(...) \, +#define Z_IS_2028_EQ_2028U(...) \, +#define Z_IS_2028U_EQ_2028U(...) \, +#define Z_IS_2029_EQ_2029(...) \, +#define Z_IS_2029U_EQ_2029(...) \, +#define Z_IS_2029_EQ_2029U(...) \, +#define Z_IS_2029U_EQ_2029U(...) \, +#define Z_IS_2030_EQ_2030(...) \, +#define Z_IS_2030U_EQ_2030(...) \, +#define Z_IS_2030_EQ_2030U(...) \, +#define Z_IS_2030U_EQ_2030U(...) \, +#define Z_IS_2031_EQ_2031(...) \, +#define Z_IS_2031U_EQ_2031(...) \, +#define Z_IS_2031_EQ_2031U(...) \, +#define Z_IS_2031U_EQ_2031U(...) \, +#define Z_IS_2032_EQ_2032(...) \, +#define Z_IS_2032U_EQ_2032(...) \, +#define Z_IS_2032_EQ_2032U(...) \, +#define Z_IS_2032U_EQ_2032U(...) \, +#define Z_IS_2033_EQ_2033(...) \, +#define Z_IS_2033U_EQ_2033(...) \, +#define Z_IS_2033_EQ_2033U(...) \, +#define Z_IS_2033U_EQ_2033U(...) \, +#define Z_IS_2034_EQ_2034(...) \, +#define Z_IS_2034U_EQ_2034(...) \, +#define Z_IS_2034_EQ_2034U(...) \, +#define Z_IS_2034U_EQ_2034U(...) \, +#define Z_IS_2035_EQ_2035(...) \, +#define Z_IS_2035U_EQ_2035(...) \, +#define Z_IS_2035_EQ_2035U(...) \, +#define Z_IS_2035U_EQ_2035U(...) \, +#define Z_IS_2036_EQ_2036(...) \, +#define Z_IS_2036U_EQ_2036(...) \, +#define Z_IS_2036_EQ_2036U(...) \, +#define Z_IS_2036U_EQ_2036U(...) \, +#define Z_IS_2037_EQ_2037(...) \, +#define Z_IS_2037U_EQ_2037(...) \, +#define Z_IS_2037_EQ_2037U(...) \, +#define Z_IS_2037U_EQ_2037U(...) \, +#define Z_IS_2038_EQ_2038(...) \, +#define Z_IS_2038U_EQ_2038(...) \, +#define Z_IS_2038_EQ_2038U(...) \, +#define Z_IS_2038U_EQ_2038U(...) \, +#define Z_IS_2039_EQ_2039(...) \, +#define Z_IS_2039U_EQ_2039(...) \, +#define Z_IS_2039_EQ_2039U(...) \, +#define Z_IS_2039U_EQ_2039U(...) \, +#define Z_IS_2040_EQ_2040(...) \, +#define Z_IS_2040U_EQ_2040(...) \, +#define Z_IS_2040_EQ_2040U(...) \, +#define Z_IS_2040U_EQ_2040U(...) \, +#define Z_IS_2041_EQ_2041(...) \, +#define Z_IS_2041U_EQ_2041(...) \, +#define Z_IS_2041_EQ_2041U(...) \, +#define Z_IS_2041U_EQ_2041U(...) \, +#define Z_IS_2042_EQ_2042(...) \, +#define Z_IS_2042U_EQ_2042(...) \, +#define Z_IS_2042_EQ_2042U(...) \, +#define Z_IS_2042U_EQ_2042U(...) \, +#define Z_IS_2043_EQ_2043(...) \, +#define Z_IS_2043U_EQ_2043(...) \, +#define Z_IS_2043_EQ_2043U(...) \, +#define Z_IS_2043U_EQ_2043U(...) \, +#define Z_IS_2044_EQ_2044(...) \, +#define Z_IS_2044U_EQ_2044(...) \, +#define Z_IS_2044_EQ_2044U(...) \, +#define Z_IS_2044U_EQ_2044U(...) \, +#define Z_IS_2045_EQ_2045(...) \, +#define Z_IS_2045U_EQ_2045(...) \, +#define Z_IS_2045_EQ_2045U(...) \, +#define Z_IS_2045U_EQ_2045U(...) \, +#define Z_IS_2046_EQ_2046(...) \, +#define Z_IS_2046U_EQ_2046(...) \, +#define Z_IS_2046_EQ_2046U(...) \, +#define Z_IS_2046U_EQ_2046U(...) \, +#define Z_IS_2047_EQ_2047(...) \, +#define Z_IS_2047U_EQ_2047(...) \, +#define Z_IS_2047_EQ_2047U(...) \, +#define Z_IS_2047U_EQ_2047U(...) \, +#define Z_IS_2048_EQ_2048(...) \, +#define Z_IS_2048U_EQ_2048(...) \, +#define Z_IS_2048_EQ_2048U(...) \, +#define Z_IS_2048U_EQ_2048U(...) \, +#define Z_IS_2049_EQ_2049(...) \, +#define Z_IS_2049U_EQ_2049(...) \, +#define Z_IS_2049_EQ_2049U(...) \, +#define Z_IS_2049U_EQ_2049U(...) \, +#define Z_IS_2050_EQ_2050(...) \, +#define Z_IS_2050U_EQ_2050(...) \, +#define Z_IS_2050_EQ_2050U(...) \, +#define Z_IS_2050U_EQ_2050U(...) \, +#define Z_IS_2051_EQ_2051(...) \, +#define Z_IS_2051U_EQ_2051(...) \, +#define Z_IS_2051_EQ_2051U(...) \, +#define Z_IS_2051U_EQ_2051U(...) \, +#define Z_IS_2052_EQ_2052(...) \, +#define Z_IS_2052U_EQ_2052(...) \, +#define Z_IS_2052_EQ_2052U(...) \, +#define Z_IS_2052U_EQ_2052U(...) \, +#define Z_IS_2053_EQ_2053(...) \, +#define Z_IS_2053U_EQ_2053(...) \, +#define Z_IS_2053_EQ_2053U(...) \, +#define Z_IS_2053U_EQ_2053U(...) \, +#define Z_IS_2054_EQ_2054(...) \, +#define Z_IS_2054U_EQ_2054(...) \, +#define Z_IS_2054_EQ_2054U(...) \, +#define Z_IS_2054U_EQ_2054U(...) \, +#define Z_IS_2055_EQ_2055(...) \, +#define Z_IS_2055U_EQ_2055(...) \, +#define Z_IS_2055_EQ_2055U(...) \, +#define Z_IS_2055U_EQ_2055U(...) \, +#define Z_IS_2056_EQ_2056(...) \, +#define Z_IS_2056U_EQ_2056(...) \, +#define Z_IS_2056_EQ_2056U(...) \, +#define Z_IS_2056U_EQ_2056U(...) \, +#define Z_IS_2057_EQ_2057(...) \, +#define Z_IS_2057U_EQ_2057(...) \, +#define Z_IS_2057_EQ_2057U(...) \, +#define Z_IS_2057U_EQ_2057U(...) \, +#define Z_IS_2058_EQ_2058(...) \, +#define Z_IS_2058U_EQ_2058(...) \, +#define Z_IS_2058_EQ_2058U(...) \, +#define Z_IS_2058U_EQ_2058U(...) \, +#define Z_IS_2059_EQ_2059(...) \, +#define Z_IS_2059U_EQ_2059(...) \, +#define Z_IS_2059_EQ_2059U(...) \, +#define Z_IS_2059U_EQ_2059U(...) \, +#define Z_IS_2060_EQ_2060(...) \, +#define Z_IS_2060U_EQ_2060(...) \, +#define Z_IS_2060_EQ_2060U(...) \, +#define Z_IS_2060U_EQ_2060U(...) \, +#define Z_IS_2061_EQ_2061(...) \, +#define Z_IS_2061U_EQ_2061(...) \, +#define Z_IS_2061_EQ_2061U(...) \, +#define Z_IS_2061U_EQ_2061U(...) \, +#define Z_IS_2062_EQ_2062(...) \, +#define Z_IS_2062U_EQ_2062(...) \, +#define Z_IS_2062_EQ_2062U(...) \, +#define Z_IS_2062U_EQ_2062U(...) \, +#define Z_IS_2063_EQ_2063(...) \, +#define Z_IS_2063U_EQ_2063(...) \, +#define Z_IS_2063_EQ_2063U(...) \, +#define Z_IS_2063U_EQ_2063U(...) \, +#define Z_IS_2064_EQ_2064(...) \, +#define Z_IS_2064U_EQ_2064(...) \, +#define Z_IS_2064_EQ_2064U(...) \, +#define Z_IS_2064U_EQ_2064U(...) \, +#define Z_IS_2065_EQ_2065(...) \, +#define Z_IS_2065U_EQ_2065(...) \, +#define Z_IS_2065_EQ_2065U(...) \, +#define Z_IS_2065U_EQ_2065U(...) \, +#define Z_IS_2066_EQ_2066(...) \, +#define Z_IS_2066U_EQ_2066(...) \, +#define Z_IS_2066_EQ_2066U(...) \, +#define Z_IS_2066U_EQ_2066U(...) \, +#define Z_IS_2067_EQ_2067(...) \, +#define Z_IS_2067U_EQ_2067(...) \, +#define Z_IS_2067_EQ_2067U(...) \, +#define Z_IS_2067U_EQ_2067U(...) \, +#define Z_IS_2068_EQ_2068(...) \, +#define Z_IS_2068U_EQ_2068(...) \, +#define Z_IS_2068_EQ_2068U(...) \, +#define Z_IS_2068U_EQ_2068U(...) \, +#define Z_IS_2069_EQ_2069(...) \, +#define Z_IS_2069U_EQ_2069(...) \, +#define Z_IS_2069_EQ_2069U(...) \, +#define Z_IS_2069U_EQ_2069U(...) \, +#define Z_IS_2070_EQ_2070(...) \, +#define Z_IS_2070U_EQ_2070(...) \, +#define Z_IS_2070_EQ_2070U(...) \, +#define Z_IS_2070U_EQ_2070U(...) \, +#define Z_IS_2071_EQ_2071(...) \, +#define Z_IS_2071U_EQ_2071(...) \, +#define Z_IS_2071_EQ_2071U(...) \, +#define Z_IS_2071U_EQ_2071U(...) \, +#define Z_IS_2072_EQ_2072(...) \, +#define Z_IS_2072U_EQ_2072(...) \, +#define Z_IS_2072_EQ_2072U(...) \, +#define Z_IS_2072U_EQ_2072U(...) \, +#define Z_IS_2073_EQ_2073(...) \, +#define Z_IS_2073U_EQ_2073(...) \, +#define Z_IS_2073_EQ_2073U(...) \, +#define Z_IS_2073U_EQ_2073U(...) \, +#define Z_IS_2074_EQ_2074(...) \, +#define Z_IS_2074U_EQ_2074(...) \, +#define Z_IS_2074_EQ_2074U(...) \, +#define Z_IS_2074U_EQ_2074U(...) \, +#define Z_IS_2075_EQ_2075(...) \, +#define Z_IS_2075U_EQ_2075(...) \, +#define Z_IS_2075_EQ_2075U(...) \, +#define Z_IS_2075U_EQ_2075U(...) \, +#define Z_IS_2076_EQ_2076(...) \, +#define Z_IS_2076U_EQ_2076(...) \, +#define Z_IS_2076_EQ_2076U(...) \, +#define Z_IS_2076U_EQ_2076U(...) \, +#define Z_IS_2077_EQ_2077(...) \, +#define Z_IS_2077U_EQ_2077(...) \, +#define Z_IS_2077_EQ_2077U(...) \, +#define Z_IS_2077U_EQ_2077U(...) \, +#define Z_IS_2078_EQ_2078(...) \, +#define Z_IS_2078U_EQ_2078(...) \, +#define Z_IS_2078_EQ_2078U(...) \, +#define Z_IS_2078U_EQ_2078U(...) \, +#define Z_IS_2079_EQ_2079(...) \, +#define Z_IS_2079U_EQ_2079(...) \, +#define Z_IS_2079_EQ_2079U(...) \, +#define Z_IS_2079U_EQ_2079U(...) \, +#define Z_IS_2080_EQ_2080(...) \, +#define Z_IS_2080U_EQ_2080(...) \, +#define Z_IS_2080_EQ_2080U(...) \, +#define Z_IS_2080U_EQ_2080U(...) \, +#define Z_IS_2081_EQ_2081(...) \, +#define Z_IS_2081U_EQ_2081(...) \, +#define Z_IS_2081_EQ_2081U(...) \, +#define Z_IS_2081U_EQ_2081U(...) \, +#define Z_IS_2082_EQ_2082(...) \, +#define Z_IS_2082U_EQ_2082(...) \, +#define Z_IS_2082_EQ_2082U(...) \, +#define Z_IS_2082U_EQ_2082U(...) \, +#define Z_IS_2083_EQ_2083(...) \, +#define Z_IS_2083U_EQ_2083(...) \, +#define Z_IS_2083_EQ_2083U(...) \, +#define Z_IS_2083U_EQ_2083U(...) \, +#define Z_IS_2084_EQ_2084(...) \, +#define Z_IS_2084U_EQ_2084(...) \, +#define Z_IS_2084_EQ_2084U(...) \, +#define Z_IS_2084U_EQ_2084U(...) \, +#define Z_IS_2085_EQ_2085(...) \, +#define Z_IS_2085U_EQ_2085(...) \, +#define Z_IS_2085_EQ_2085U(...) \, +#define Z_IS_2085U_EQ_2085U(...) \, +#define Z_IS_2086_EQ_2086(...) \, +#define Z_IS_2086U_EQ_2086(...) \, +#define Z_IS_2086_EQ_2086U(...) \, +#define Z_IS_2086U_EQ_2086U(...) \, +#define Z_IS_2087_EQ_2087(...) \, +#define Z_IS_2087U_EQ_2087(...) \, +#define Z_IS_2087_EQ_2087U(...) \, +#define Z_IS_2087U_EQ_2087U(...) \, +#define Z_IS_2088_EQ_2088(...) \, +#define Z_IS_2088U_EQ_2088(...) \, +#define Z_IS_2088_EQ_2088U(...) \, +#define Z_IS_2088U_EQ_2088U(...) \, +#define Z_IS_2089_EQ_2089(...) \, +#define Z_IS_2089U_EQ_2089(...) \, +#define Z_IS_2089_EQ_2089U(...) \, +#define Z_IS_2089U_EQ_2089U(...) \, +#define Z_IS_2090_EQ_2090(...) \, +#define Z_IS_2090U_EQ_2090(...) \, +#define Z_IS_2090_EQ_2090U(...) \, +#define Z_IS_2090U_EQ_2090U(...) \, +#define Z_IS_2091_EQ_2091(...) \, +#define Z_IS_2091U_EQ_2091(...) \, +#define Z_IS_2091_EQ_2091U(...) \, +#define Z_IS_2091U_EQ_2091U(...) \, +#define Z_IS_2092_EQ_2092(...) \, +#define Z_IS_2092U_EQ_2092(...) \, +#define Z_IS_2092_EQ_2092U(...) \, +#define Z_IS_2092U_EQ_2092U(...) \, +#define Z_IS_2093_EQ_2093(...) \, +#define Z_IS_2093U_EQ_2093(...) \, +#define Z_IS_2093_EQ_2093U(...) \, +#define Z_IS_2093U_EQ_2093U(...) \, +#define Z_IS_2094_EQ_2094(...) \, +#define Z_IS_2094U_EQ_2094(...) \, +#define Z_IS_2094_EQ_2094U(...) \, +#define Z_IS_2094U_EQ_2094U(...) \, +#define Z_IS_2095_EQ_2095(...) \, +#define Z_IS_2095U_EQ_2095(...) \, +#define Z_IS_2095_EQ_2095U(...) \, +#define Z_IS_2095U_EQ_2095U(...) \, +#define Z_IS_2096_EQ_2096(...) \, +#define Z_IS_2096U_EQ_2096(...) \, +#define Z_IS_2096_EQ_2096U(...) \, +#define Z_IS_2096U_EQ_2096U(...) \, +#define Z_IS_2097_EQ_2097(...) \, +#define Z_IS_2097U_EQ_2097(...) \, +#define Z_IS_2097_EQ_2097U(...) \, +#define Z_IS_2097U_EQ_2097U(...) \, +#define Z_IS_2098_EQ_2098(...) \, +#define Z_IS_2098U_EQ_2098(...) \, +#define Z_IS_2098_EQ_2098U(...) \, +#define Z_IS_2098U_EQ_2098U(...) \, +#define Z_IS_2099_EQ_2099(...) \, +#define Z_IS_2099U_EQ_2099(...) \, +#define Z_IS_2099_EQ_2099U(...) \, +#define Z_IS_2099U_EQ_2099U(...) \, +#define Z_IS_2100_EQ_2100(...) \, +#define Z_IS_2100U_EQ_2100(...) \, +#define Z_IS_2100_EQ_2100U(...) \, +#define Z_IS_2100U_EQ_2100U(...) \, +#define Z_IS_2101_EQ_2101(...) \, +#define Z_IS_2101U_EQ_2101(...) \, +#define Z_IS_2101_EQ_2101U(...) \, +#define Z_IS_2101U_EQ_2101U(...) \, +#define Z_IS_2102_EQ_2102(...) \, +#define Z_IS_2102U_EQ_2102(...) \, +#define Z_IS_2102_EQ_2102U(...) \, +#define Z_IS_2102U_EQ_2102U(...) \, +#define Z_IS_2103_EQ_2103(...) \, +#define Z_IS_2103U_EQ_2103(...) \, +#define Z_IS_2103_EQ_2103U(...) \, +#define Z_IS_2103U_EQ_2103U(...) \, +#define Z_IS_2104_EQ_2104(...) \, +#define Z_IS_2104U_EQ_2104(...) \, +#define Z_IS_2104_EQ_2104U(...) \, +#define Z_IS_2104U_EQ_2104U(...) \, +#define Z_IS_2105_EQ_2105(...) \, +#define Z_IS_2105U_EQ_2105(...) \, +#define Z_IS_2105_EQ_2105U(...) \, +#define Z_IS_2105U_EQ_2105U(...) \, +#define Z_IS_2106_EQ_2106(...) \, +#define Z_IS_2106U_EQ_2106(...) \, +#define Z_IS_2106_EQ_2106U(...) \, +#define Z_IS_2106U_EQ_2106U(...) \, +#define Z_IS_2107_EQ_2107(...) \, +#define Z_IS_2107U_EQ_2107(...) \, +#define Z_IS_2107_EQ_2107U(...) \, +#define Z_IS_2107U_EQ_2107U(...) \, +#define Z_IS_2108_EQ_2108(...) \, +#define Z_IS_2108U_EQ_2108(...) \, +#define Z_IS_2108_EQ_2108U(...) \, +#define Z_IS_2108U_EQ_2108U(...) \, +#define Z_IS_2109_EQ_2109(...) \, +#define Z_IS_2109U_EQ_2109(...) \, +#define Z_IS_2109_EQ_2109U(...) \, +#define Z_IS_2109U_EQ_2109U(...) \, +#define Z_IS_2110_EQ_2110(...) \, +#define Z_IS_2110U_EQ_2110(...) \, +#define Z_IS_2110_EQ_2110U(...) \, +#define Z_IS_2110U_EQ_2110U(...) \, +#define Z_IS_2111_EQ_2111(...) \, +#define Z_IS_2111U_EQ_2111(...) \, +#define Z_IS_2111_EQ_2111U(...) \, +#define Z_IS_2111U_EQ_2111U(...) \, +#define Z_IS_2112_EQ_2112(...) \, +#define Z_IS_2112U_EQ_2112(...) \, +#define Z_IS_2112_EQ_2112U(...) \, +#define Z_IS_2112U_EQ_2112U(...) \, +#define Z_IS_2113_EQ_2113(...) \, +#define Z_IS_2113U_EQ_2113(...) \, +#define Z_IS_2113_EQ_2113U(...) \, +#define Z_IS_2113U_EQ_2113U(...) \, +#define Z_IS_2114_EQ_2114(...) \, +#define Z_IS_2114U_EQ_2114(...) \, +#define Z_IS_2114_EQ_2114U(...) \, +#define Z_IS_2114U_EQ_2114U(...) \, +#define Z_IS_2115_EQ_2115(...) \, +#define Z_IS_2115U_EQ_2115(...) \, +#define Z_IS_2115_EQ_2115U(...) \, +#define Z_IS_2115U_EQ_2115U(...) \, +#define Z_IS_2116_EQ_2116(...) \, +#define Z_IS_2116U_EQ_2116(...) \, +#define Z_IS_2116_EQ_2116U(...) \, +#define Z_IS_2116U_EQ_2116U(...) \, +#define Z_IS_2117_EQ_2117(...) \, +#define Z_IS_2117U_EQ_2117(...) \, +#define Z_IS_2117_EQ_2117U(...) \, +#define Z_IS_2117U_EQ_2117U(...) \, +#define Z_IS_2118_EQ_2118(...) \, +#define Z_IS_2118U_EQ_2118(...) \, +#define Z_IS_2118_EQ_2118U(...) \, +#define Z_IS_2118U_EQ_2118U(...) \, +#define Z_IS_2119_EQ_2119(...) \, +#define Z_IS_2119U_EQ_2119(...) \, +#define Z_IS_2119_EQ_2119U(...) \, +#define Z_IS_2119U_EQ_2119U(...) \, +#define Z_IS_2120_EQ_2120(...) \, +#define Z_IS_2120U_EQ_2120(...) \, +#define Z_IS_2120_EQ_2120U(...) \, +#define Z_IS_2120U_EQ_2120U(...) \, +#define Z_IS_2121_EQ_2121(...) \, +#define Z_IS_2121U_EQ_2121(...) \, +#define Z_IS_2121_EQ_2121U(...) \, +#define Z_IS_2121U_EQ_2121U(...) \, +#define Z_IS_2122_EQ_2122(...) \, +#define Z_IS_2122U_EQ_2122(...) \, +#define Z_IS_2122_EQ_2122U(...) \, +#define Z_IS_2122U_EQ_2122U(...) \, +#define Z_IS_2123_EQ_2123(...) \, +#define Z_IS_2123U_EQ_2123(...) \, +#define Z_IS_2123_EQ_2123U(...) \, +#define Z_IS_2123U_EQ_2123U(...) \, +#define Z_IS_2124_EQ_2124(...) \, +#define Z_IS_2124U_EQ_2124(...) \, +#define Z_IS_2124_EQ_2124U(...) \, +#define Z_IS_2124U_EQ_2124U(...) \, +#define Z_IS_2125_EQ_2125(...) \, +#define Z_IS_2125U_EQ_2125(...) \, +#define Z_IS_2125_EQ_2125U(...) \, +#define Z_IS_2125U_EQ_2125U(...) \, +#define Z_IS_2126_EQ_2126(...) \, +#define Z_IS_2126U_EQ_2126(...) \, +#define Z_IS_2126_EQ_2126U(...) \, +#define Z_IS_2126U_EQ_2126U(...) \, +#define Z_IS_2127_EQ_2127(...) \, +#define Z_IS_2127U_EQ_2127(...) \, +#define Z_IS_2127_EQ_2127U(...) \, +#define Z_IS_2127U_EQ_2127U(...) \, +#define Z_IS_2128_EQ_2128(...) \, +#define Z_IS_2128U_EQ_2128(...) \, +#define Z_IS_2128_EQ_2128U(...) \, +#define Z_IS_2128U_EQ_2128U(...) \, +#define Z_IS_2129_EQ_2129(...) \, +#define Z_IS_2129U_EQ_2129(...) \, +#define Z_IS_2129_EQ_2129U(...) \, +#define Z_IS_2129U_EQ_2129U(...) \, +#define Z_IS_2130_EQ_2130(...) \, +#define Z_IS_2130U_EQ_2130(...) \, +#define Z_IS_2130_EQ_2130U(...) \, +#define Z_IS_2130U_EQ_2130U(...) \, +#define Z_IS_2131_EQ_2131(...) \, +#define Z_IS_2131U_EQ_2131(...) \, +#define Z_IS_2131_EQ_2131U(...) \, +#define Z_IS_2131U_EQ_2131U(...) \, +#define Z_IS_2132_EQ_2132(...) \, +#define Z_IS_2132U_EQ_2132(...) \, +#define Z_IS_2132_EQ_2132U(...) \, +#define Z_IS_2132U_EQ_2132U(...) \, +#define Z_IS_2133_EQ_2133(...) \, +#define Z_IS_2133U_EQ_2133(...) \, +#define Z_IS_2133_EQ_2133U(...) \, +#define Z_IS_2133U_EQ_2133U(...) \, +#define Z_IS_2134_EQ_2134(...) \, +#define Z_IS_2134U_EQ_2134(...) \, +#define Z_IS_2134_EQ_2134U(...) \, +#define Z_IS_2134U_EQ_2134U(...) \, +#define Z_IS_2135_EQ_2135(...) \, +#define Z_IS_2135U_EQ_2135(...) \, +#define Z_IS_2135_EQ_2135U(...) \, +#define Z_IS_2135U_EQ_2135U(...) \, +#define Z_IS_2136_EQ_2136(...) \, +#define Z_IS_2136U_EQ_2136(...) \, +#define Z_IS_2136_EQ_2136U(...) \, +#define Z_IS_2136U_EQ_2136U(...) \, +#define Z_IS_2137_EQ_2137(...) \, +#define Z_IS_2137U_EQ_2137(...) \, +#define Z_IS_2137_EQ_2137U(...) \, +#define Z_IS_2137U_EQ_2137U(...) \, +#define Z_IS_2138_EQ_2138(...) \, +#define Z_IS_2138U_EQ_2138(...) \, +#define Z_IS_2138_EQ_2138U(...) \, +#define Z_IS_2138U_EQ_2138U(...) \, +#define Z_IS_2139_EQ_2139(...) \, +#define Z_IS_2139U_EQ_2139(...) \, +#define Z_IS_2139_EQ_2139U(...) \, +#define Z_IS_2139U_EQ_2139U(...) \, +#define Z_IS_2140_EQ_2140(...) \, +#define Z_IS_2140U_EQ_2140(...) \, +#define Z_IS_2140_EQ_2140U(...) \, +#define Z_IS_2140U_EQ_2140U(...) \, +#define Z_IS_2141_EQ_2141(...) \, +#define Z_IS_2141U_EQ_2141(...) \, +#define Z_IS_2141_EQ_2141U(...) \, +#define Z_IS_2141U_EQ_2141U(...) \, +#define Z_IS_2142_EQ_2142(...) \, +#define Z_IS_2142U_EQ_2142(...) \, +#define Z_IS_2142_EQ_2142U(...) \, +#define Z_IS_2142U_EQ_2142U(...) \, +#define Z_IS_2143_EQ_2143(...) \, +#define Z_IS_2143U_EQ_2143(...) \, +#define Z_IS_2143_EQ_2143U(...) \, +#define Z_IS_2143U_EQ_2143U(...) \, +#define Z_IS_2144_EQ_2144(...) \, +#define Z_IS_2144U_EQ_2144(...) \, +#define Z_IS_2144_EQ_2144U(...) \, +#define Z_IS_2144U_EQ_2144U(...) \, +#define Z_IS_2145_EQ_2145(...) \, +#define Z_IS_2145U_EQ_2145(...) \, +#define Z_IS_2145_EQ_2145U(...) \, +#define Z_IS_2145U_EQ_2145U(...) \, +#define Z_IS_2146_EQ_2146(...) \, +#define Z_IS_2146U_EQ_2146(...) \, +#define Z_IS_2146_EQ_2146U(...) \, +#define Z_IS_2146U_EQ_2146U(...) \, +#define Z_IS_2147_EQ_2147(...) \, +#define Z_IS_2147U_EQ_2147(...) \, +#define Z_IS_2147_EQ_2147U(...) \, +#define Z_IS_2147U_EQ_2147U(...) \, +#define Z_IS_2148_EQ_2148(...) \, +#define Z_IS_2148U_EQ_2148(...) \, +#define Z_IS_2148_EQ_2148U(...) \, +#define Z_IS_2148U_EQ_2148U(...) \, +#define Z_IS_2149_EQ_2149(...) \, +#define Z_IS_2149U_EQ_2149(...) \, +#define Z_IS_2149_EQ_2149U(...) \, +#define Z_IS_2149U_EQ_2149U(...) \, +#define Z_IS_2150_EQ_2150(...) \, +#define Z_IS_2150U_EQ_2150(...) \, +#define Z_IS_2150_EQ_2150U(...) \, +#define Z_IS_2150U_EQ_2150U(...) \, +#define Z_IS_2151_EQ_2151(...) \, +#define Z_IS_2151U_EQ_2151(...) \, +#define Z_IS_2151_EQ_2151U(...) \, +#define Z_IS_2151U_EQ_2151U(...) \, +#define Z_IS_2152_EQ_2152(...) \, +#define Z_IS_2152U_EQ_2152(...) \, +#define Z_IS_2152_EQ_2152U(...) \, +#define Z_IS_2152U_EQ_2152U(...) \, +#define Z_IS_2153_EQ_2153(...) \, +#define Z_IS_2153U_EQ_2153(...) \, +#define Z_IS_2153_EQ_2153U(...) \, +#define Z_IS_2153U_EQ_2153U(...) \, +#define Z_IS_2154_EQ_2154(...) \, +#define Z_IS_2154U_EQ_2154(...) \, +#define Z_IS_2154_EQ_2154U(...) \, +#define Z_IS_2154U_EQ_2154U(...) \, +#define Z_IS_2155_EQ_2155(...) \, +#define Z_IS_2155U_EQ_2155(...) \, +#define Z_IS_2155_EQ_2155U(...) \, +#define Z_IS_2155U_EQ_2155U(...) \, +#define Z_IS_2156_EQ_2156(...) \, +#define Z_IS_2156U_EQ_2156(...) \, +#define Z_IS_2156_EQ_2156U(...) \, +#define Z_IS_2156U_EQ_2156U(...) \, +#define Z_IS_2157_EQ_2157(...) \, +#define Z_IS_2157U_EQ_2157(...) \, +#define Z_IS_2157_EQ_2157U(...) \, +#define Z_IS_2157U_EQ_2157U(...) \, +#define Z_IS_2158_EQ_2158(...) \, +#define Z_IS_2158U_EQ_2158(...) \, +#define Z_IS_2158_EQ_2158U(...) \, +#define Z_IS_2158U_EQ_2158U(...) \, +#define Z_IS_2159_EQ_2159(...) \, +#define Z_IS_2159U_EQ_2159(...) \, +#define Z_IS_2159_EQ_2159U(...) \, +#define Z_IS_2159U_EQ_2159U(...) \, +#define Z_IS_2160_EQ_2160(...) \, +#define Z_IS_2160U_EQ_2160(...) \, +#define Z_IS_2160_EQ_2160U(...) \, +#define Z_IS_2160U_EQ_2160U(...) \, +#define Z_IS_2161_EQ_2161(...) \, +#define Z_IS_2161U_EQ_2161(...) \, +#define Z_IS_2161_EQ_2161U(...) \, +#define Z_IS_2161U_EQ_2161U(...) \, +#define Z_IS_2162_EQ_2162(...) \, +#define Z_IS_2162U_EQ_2162(...) \, +#define Z_IS_2162_EQ_2162U(...) \, +#define Z_IS_2162U_EQ_2162U(...) \, +#define Z_IS_2163_EQ_2163(...) \, +#define Z_IS_2163U_EQ_2163(...) \, +#define Z_IS_2163_EQ_2163U(...) \, +#define Z_IS_2163U_EQ_2163U(...) \, +#define Z_IS_2164_EQ_2164(...) \, +#define Z_IS_2164U_EQ_2164(...) \, +#define Z_IS_2164_EQ_2164U(...) \, +#define Z_IS_2164U_EQ_2164U(...) \, +#define Z_IS_2165_EQ_2165(...) \, +#define Z_IS_2165U_EQ_2165(...) \, +#define Z_IS_2165_EQ_2165U(...) \, +#define Z_IS_2165U_EQ_2165U(...) \, +#define Z_IS_2166_EQ_2166(...) \, +#define Z_IS_2166U_EQ_2166(...) \, +#define Z_IS_2166_EQ_2166U(...) \, +#define Z_IS_2166U_EQ_2166U(...) \, +#define Z_IS_2167_EQ_2167(...) \, +#define Z_IS_2167U_EQ_2167(...) \, +#define Z_IS_2167_EQ_2167U(...) \, +#define Z_IS_2167U_EQ_2167U(...) \, +#define Z_IS_2168_EQ_2168(...) \, +#define Z_IS_2168U_EQ_2168(...) \, +#define Z_IS_2168_EQ_2168U(...) \, +#define Z_IS_2168U_EQ_2168U(...) \, +#define Z_IS_2169_EQ_2169(...) \, +#define Z_IS_2169U_EQ_2169(...) \, +#define Z_IS_2169_EQ_2169U(...) \, +#define Z_IS_2169U_EQ_2169U(...) \, +#define Z_IS_2170_EQ_2170(...) \, +#define Z_IS_2170U_EQ_2170(...) \, +#define Z_IS_2170_EQ_2170U(...) \, +#define Z_IS_2170U_EQ_2170U(...) \, +#define Z_IS_2171_EQ_2171(...) \, +#define Z_IS_2171U_EQ_2171(...) \, +#define Z_IS_2171_EQ_2171U(...) \, +#define Z_IS_2171U_EQ_2171U(...) \, +#define Z_IS_2172_EQ_2172(...) \, +#define Z_IS_2172U_EQ_2172(...) \, +#define Z_IS_2172_EQ_2172U(...) \, +#define Z_IS_2172U_EQ_2172U(...) \, +#define Z_IS_2173_EQ_2173(...) \, +#define Z_IS_2173U_EQ_2173(...) \, +#define Z_IS_2173_EQ_2173U(...) \, +#define Z_IS_2173U_EQ_2173U(...) \, +#define Z_IS_2174_EQ_2174(...) \, +#define Z_IS_2174U_EQ_2174(...) \, +#define Z_IS_2174_EQ_2174U(...) \, +#define Z_IS_2174U_EQ_2174U(...) \, +#define Z_IS_2175_EQ_2175(...) \, +#define Z_IS_2175U_EQ_2175(...) \, +#define Z_IS_2175_EQ_2175U(...) \, +#define Z_IS_2175U_EQ_2175U(...) \, +#define Z_IS_2176_EQ_2176(...) \, +#define Z_IS_2176U_EQ_2176(...) \, +#define Z_IS_2176_EQ_2176U(...) \, +#define Z_IS_2176U_EQ_2176U(...) \, +#define Z_IS_2177_EQ_2177(...) \, +#define Z_IS_2177U_EQ_2177(...) \, +#define Z_IS_2177_EQ_2177U(...) \, +#define Z_IS_2177U_EQ_2177U(...) \, +#define Z_IS_2178_EQ_2178(...) \, +#define Z_IS_2178U_EQ_2178(...) \, +#define Z_IS_2178_EQ_2178U(...) \, +#define Z_IS_2178U_EQ_2178U(...) \, +#define Z_IS_2179_EQ_2179(...) \, +#define Z_IS_2179U_EQ_2179(...) \, +#define Z_IS_2179_EQ_2179U(...) \, +#define Z_IS_2179U_EQ_2179U(...) \, +#define Z_IS_2180_EQ_2180(...) \, +#define Z_IS_2180U_EQ_2180(...) \, +#define Z_IS_2180_EQ_2180U(...) \, +#define Z_IS_2180U_EQ_2180U(...) \, +#define Z_IS_2181_EQ_2181(...) \, +#define Z_IS_2181U_EQ_2181(...) \, +#define Z_IS_2181_EQ_2181U(...) \, +#define Z_IS_2181U_EQ_2181U(...) \, +#define Z_IS_2182_EQ_2182(...) \, +#define Z_IS_2182U_EQ_2182(...) \, +#define Z_IS_2182_EQ_2182U(...) \, +#define Z_IS_2182U_EQ_2182U(...) \, +#define Z_IS_2183_EQ_2183(...) \, +#define Z_IS_2183U_EQ_2183(...) \, +#define Z_IS_2183_EQ_2183U(...) \, +#define Z_IS_2183U_EQ_2183U(...) \, +#define Z_IS_2184_EQ_2184(...) \, +#define Z_IS_2184U_EQ_2184(...) \, +#define Z_IS_2184_EQ_2184U(...) \, +#define Z_IS_2184U_EQ_2184U(...) \, +#define Z_IS_2185_EQ_2185(...) \, +#define Z_IS_2185U_EQ_2185(...) \, +#define Z_IS_2185_EQ_2185U(...) \, +#define Z_IS_2185U_EQ_2185U(...) \, +#define Z_IS_2186_EQ_2186(...) \, +#define Z_IS_2186U_EQ_2186(...) \, +#define Z_IS_2186_EQ_2186U(...) \, +#define Z_IS_2186U_EQ_2186U(...) \, +#define Z_IS_2187_EQ_2187(...) \, +#define Z_IS_2187U_EQ_2187(...) \, +#define Z_IS_2187_EQ_2187U(...) \, +#define Z_IS_2187U_EQ_2187U(...) \, +#define Z_IS_2188_EQ_2188(...) \, +#define Z_IS_2188U_EQ_2188(...) \, +#define Z_IS_2188_EQ_2188U(...) \, +#define Z_IS_2188U_EQ_2188U(...) \, +#define Z_IS_2189_EQ_2189(...) \, +#define Z_IS_2189U_EQ_2189(...) \, +#define Z_IS_2189_EQ_2189U(...) \, +#define Z_IS_2189U_EQ_2189U(...) \, +#define Z_IS_2190_EQ_2190(...) \, +#define Z_IS_2190U_EQ_2190(...) \, +#define Z_IS_2190_EQ_2190U(...) \, +#define Z_IS_2190U_EQ_2190U(...) \, +#define Z_IS_2191_EQ_2191(...) \, +#define Z_IS_2191U_EQ_2191(...) \, +#define Z_IS_2191_EQ_2191U(...) \, +#define Z_IS_2191U_EQ_2191U(...) \, +#define Z_IS_2192_EQ_2192(...) \, +#define Z_IS_2192U_EQ_2192(...) \, +#define Z_IS_2192_EQ_2192U(...) \, +#define Z_IS_2192U_EQ_2192U(...) \, +#define Z_IS_2193_EQ_2193(...) \, +#define Z_IS_2193U_EQ_2193(...) \, +#define Z_IS_2193_EQ_2193U(...) \, +#define Z_IS_2193U_EQ_2193U(...) \, +#define Z_IS_2194_EQ_2194(...) \, +#define Z_IS_2194U_EQ_2194(...) \, +#define Z_IS_2194_EQ_2194U(...) \, +#define Z_IS_2194U_EQ_2194U(...) \, +#define Z_IS_2195_EQ_2195(...) \, +#define Z_IS_2195U_EQ_2195(...) \, +#define Z_IS_2195_EQ_2195U(...) \, +#define Z_IS_2195U_EQ_2195U(...) \, +#define Z_IS_2196_EQ_2196(...) \, +#define Z_IS_2196U_EQ_2196(...) \, +#define Z_IS_2196_EQ_2196U(...) \, +#define Z_IS_2196U_EQ_2196U(...) \, +#define Z_IS_2197_EQ_2197(...) \, +#define Z_IS_2197U_EQ_2197(...) \, +#define Z_IS_2197_EQ_2197U(...) \, +#define Z_IS_2197U_EQ_2197U(...) \, +#define Z_IS_2198_EQ_2198(...) \, +#define Z_IS_2198U_EQ_2198(...) \, +#define Z_IS_2198_EQ_2198U(...) \, +#define Z_IS_2198U_EQ_2198U(...) \, +#define Z_IS_2199_EQ_2199(...) \, +#define Z_IS_2199U_EQ_2199(...) \, +#define Z_IS_2199_EQ_2199U(...) \, +#define Z_IS_2199U_EQ_2199U(...) \, +#define Z_IS_2200_EQ_2200(...) \, +#define Z_IS_2200U_EQ_2200(...) \, +#define Z_IS_2200_EQ_2200U(...) \, +#define Z_IS_2200U_EQ_2200U(...) \, +#define Z_IS_2201_EQ_2201(...) \, +#define Z_IS_2201U_EQ_2201(...) \, +#define Z_IS_2201_EQ_2201U(...) \, +#define Z_IS_2201U_EQ_2201U(...) \, +#define Z_IS_2202_EQ_2202(...) \, +#define Z_IS_2202U_EQ_2202(...) \, +#define Z_IS_2202_EQ_2202U(...) \, +#define Z_IS_2202U_EQ_2202U(...) \, +#define Z_IS_2203_EQ_2203(...) \, +#define Z_IS_2203U_EQ_2203(...) \, +#define Z_IS_2203_EQ_2203U(...) \, +#define Z_IS_2203U_EQ_2203U(...) \, +#define Z_IS_2204_EQ_2204(...) \, +#define Z_IS_2204U_EQ_2204(...) \, +#define Z_IS_2204_EQ_2204U(...) \, +#define Z_IS_2204U_EQ_2204U(...) \, +#define Z_IS_2205_EQ_2205(...) \, +#define Z_IS_2205U_EQ_2205(...) \, +#define Z_IS_2205_EQ_2205U(...) \, +#define Z_IS_2205U_EQ_2205U(...) \, +#define Z_IS_2206_EQ_2206(...) \, +#define Z_IS_2206U_EQ_2206(...) \, +#define Z_IS_2206_EQ_2206U(...) \, +#define Z_IS_2206U_EQ_2206U(...) \, +#define Z_IS_2207_EQ_2207(...) \, +#define Z_IS_2207U_EQ_2207(...) \, +#define Z_IS_2207_EQ_2207U(...) \, +#define Z_IS_2207U_EQ_2207U(...) \, +#define Z_IS_2208_EQ_2208(...) \, +#define Z_IS_2208U_EQ_2208(...) \, +#define Z_IS_2208_EQ_2208U(...) \, +#define Z_IS_2208U_EQ_2208U(...) \, +#define Z_IS_2209_EQ_2209(...) \, +#define Z_IS_2209U_EQ_2209(...) \, +#define Z_IS_2209_EQ_2209U(...) \, +#define Z_IS_2209U_EQ_2209U(...) \, +#define Z_IS_2210_EQ_2210(...) \, +#define Z_IS_2210U_EQ_2210(...) \, +#define Z_IS_2210_EQ_2210U(...) \, +#define Z_IS_2210U_EQ_2210U(...) \, +#define Z_IS_2211_EQ_2211(...) \, +#define Z_IS_2211U_EQ_2211(...) \, +#define Z_IS_2211_EQ_2211U(...) \, +#define Z_IS_2211U_EQ_2211U(...) \, +#define Z_IS_2212_EQ_2212(...) \, +#define Z_IS_2212U_EQ_2212(...) \, +#define Z_IS_2212_EQ_2212U(...) \, +#define Z_IS_2212U_EQ_2212U(...) \, +#define Z_IS_2213_EQ_2213(...) \, +#define Z_IS_2213U_EQ_2213(...) \, +#define Z_IS_2213_EQ_2213U(...) \, +#define Z_IS_2213U_EQ_2213U(...) \, +#define Z_IS_2214_EQ_2214(...) \, +#define Z_IS_2214U_EQ_2214(...) \, +#define Z_IS_2214_EQ_2214U(...) \, +#define Z_IS_2214U_EQ_2214U(...) \, +#define Z_IS_2215_EQ_2215(...) \, +#define Z_IS_2215U_EQ_2215(...) \, +#define Z_IS_2215_EQ_2215U(...) \, +#define Z_IS_2215U_EQ_2215U(...) \, +#define Z_IS_2216_EQ_2216(...) \, +#define Z_IS_2216U_EQ_2216(...) \, +#define Z_IS_2216_EQ_2216U(...) \, +#define Z_IS_2216U_EQ_2216U(...) \, +#define Z_IS_2217_EQ_2217(...) \, +#define Z_IS_2217U_EQ_2217(...) \, +#define Z_IS_2217_EQ_2217U(...) \, +#define Z_IS_2217U_EQ_2217U(...) \, +#define Z_IS_2218_EQ_2218(...) \, +#define Z_IS_2218U_EQ_2218(...) \, +#define Z_IS_2218_EQ_2218U(...) \, +#define Z_IS_2218U_EQ_2218U(...) \, +#define Z_IS_2219_EQ_2219(...) \, +#define Z_IS_2219U_EQ_2219(...) \, +#define Z_IS_2219_EQ_2219U(...) \, +#define Z_IS_2219U_EQ_2219U(...) \, +#define Z_IS_2220_EQ_2220(...) \, +#define Z_IS_2220U_EQ_2220(...) \, +#define Z_IS_2220_EQ_2220U(...) \, +#define Z_IS_2220U_EQ_2220U(...) \, +#define Z_IS_2221_EQ_2221(...) \, +#define Z_IS_2221U_EQ_2221(...) \, +#define Z_IS_2221_EQ_2221U(...) \, +#define Z_IS_2221U_EQ_2221U(...) \, +#define Z_IS_2222_EQ_2222(...) \, +#define Z_IS_2222U_EQ_2222(...) \, +#define Z_IS_2222_EQ_2222U(...) \, +#define Z_IS_2222U_EQ_2222U(...) \, +#define Z_IS_2223_EQ_2223(...) \, +#define Z_IS_2223U_EQ_2223(...) \, +#define Z_IS_2223_EQ_2223U(...) \, +#define Z_IS_2223U_EQ_2223U(...) \, +#define Z_IS_2224_EQ_2224(...) \, +#define Z_IS_2224U_EQ_2224(...) \, +#define Z_IS_2224_EQ_2224U(...) \, +#define Z_IS_2224U_EQ_2224U(...) \, +#define Z_IS_2225_EQ_2225(...) \, +#define Z_IS_2225U_EQ_2225(...) \, +#define Z_IS_2225_EQ_2225U(...) \, +#define Z_IS_2225U_EQ_2225U(...) \, +#define Z_IS_2226_EQ_2226(...) \, +#define Z_IS_2226U_EQ_2226(...) \, +#define Z_IS_2226_EQ_2226U(...) \, +#define Z_IS_2226U_EQ_2226U(...) \, +#define Z_IS_2227_EQ_2227(...) \, +#define Z_IS_2227U_EQ_2227(...) \, +#define Z_IS_2227_EQ_2227U(...) \, +#define Z_IS_2227U_EQ_2227U(...) \, +#define Z_IS_2228_EQ_2228(...) \, +#define Z_IS_2228U_EQ_2228(...) \, +#define Z_IS_2228_EQ_2228U(...) \, +#define Z_IS_2228U_EQ_2228U(...) \, +#define Z_IS_2229_EQ_2229(...) \, +#define Z_IS_2229U_EQ_2229(...) \, +#define Z_IS_2229_EQ_2229U(...) \, +#define Z_IS_2229U_EQ_2229U(...) \, +#define Z_IS_2230_EQ_2230(...) \, +#define Z_IS_2230U_EQ_2230(...) \, +#define Z_IS_2230_EQ_2230U(...) \, +#define Z_IS_2230U_EQ_2230U(...) \, +#define Z_IS_2231_EQ_2231(...) \, +#define Z_IS_2231U_EQ_2231(...) \, +#define Z_IS_2231_EQ_2231U(...) \, +#define Z_IS_2231U_EQ_2231U(...) \, +#define Z_IS_2232_EQ_2232(...) \, +#define Z_IS_2232U_EQ_2232(...) \, +#define Z_IS_2232_EQ_2232U(...) \, +#define Z_IS_2232U_EQ_2232U(...) \, +#define Z_IS_2233_EQ_2233(...) \, +#define Z_IS_2233U_EQ_2233(...) \, +#define Z_IS_2233_EQ_2233U(...) \, +#define Z_IS_2233U_EQ_2233U(...) \, +#define Z_IS_2234_EQ_2234(...) \, +#define Z_IS_2234U_EQ_2234(...) \, +#define Z_IS_2234_EQ_2234U(...) \, +#define Z_IS_2234U_EQ_2234U(...) \, +#define Z_IS_2235_EQ_2235(...) \, +#define Z_IS_2235U_EQ_2235(...) \, +#define Z_IS_2235_EQ_2235U(...) \, +#define Z_IS_2235U_EQ_2235U(...) \, +#define Z_IS_2236_EQ_2236(...) \, +#define Z_IS_2236U_EQ_2236(...) \, +#define Z_IS_2236_EQ_2236U(...) \, +#define Z_IS_2236U_EQ_2236U(...) \, +#define Z_IS_2237_EQ_2237(...) \, +#define Z_IS_2237U_EQ_2237(...) \, +#define Z_IS_2237_EQ_2237U(...) \, +#define Z_IS_2237U_EQ_2237U(...) \, +#define Z_IS_2238_EQ_2238(...) \, +#define Z_IS_2238U_EQ_2238(...) \, +#define Z_IS_2238_EQ_2238U(...) \, +#define Z_IS_2238U_EQ_2238U(...) \, +#define Z_IS_2239_EQ_2239(...) \, +#define Z_IS_2239U_EQ_2239(...) \, +#define Z_IS_2239_EQ_2239U(...) \, +#define Z_IS_2239U_EQ_2239U(...) \, +#define Z_IS_2240_EQ_2240(...) \, +#define Z_IS_2240U_EQ_2240(...) \, +#define Z_IS_2240_EQ_2240U(...) \, +#define Z_IS_2240U_EQ_2240U(...) \, +#define Z_IS_2241_EQ_2241(...) \, +#define Z_IS_2241U_EQ_2241(...) \, +#define Z_IS_2241_EQ_2241U(...) \, +#define Z_IS_2241U_EQ_2241U(...) \, +#define Z_IS_2242_EQ_2242(...) \, +#define Z_IS_2242U_EQ_2242(...) \, +#define Z_IS_2242_EQ_2242U(...) \, +#define Z_IS_2242U_EQ_2242U(...) \, +#define Z_IS_2243_EQ_2243(...) \, +#define Z_IS_2243U_EQ_2243(...) \, +#define Z_IS_2243_EQ_2243U(...) \, +#define Z_IS_2243U_EQ_2243U(...) \, +#define Z_IS_2244_EQ_2244(...) \, +#define Z_IS_2244U_EQ_2244(...) \, +#define Z_IS_2244_EQ_2244U(...) \, +#define Z_IS_2244U_EQ_2244U(...) \, +#define Z_IS_2245_EQ_2245(...) \, +#define Z_IS_2245U_EQ_2245(...) \, +#define Z_IS_2245_EQ_2245U(...) \, +#define Z_IS_2245U_EQ_2245U(...) \, +#define Z_IS_2246_EQ_2246(...) \, +#define Z_IS_2246U_EQ_2246(...) \, +#define Z_IS_2246_EQ_2246U(...) \, +#define Z_IS_2246U_EQ_2246U(...) \, +#define Z_IS_2247_EQ_2247(...) \, +#define Z_IS_2247U_EQ_2247(...) \, +#define Z_IS_2247_EQ_2247U(...) \, +#define Z_IS_2247U_EQ_2247U(...) \, +#define Z_IS_2248_EQ_2248(...) \, +#define Z_IS_2248U_EQ_2248(...) \, +#define Z_IS_2248_EQ_2248U(...) \, +#define Z_IS_2248U_EQ_2248U(...) \, +#define Z_IS_2249_EQ_2249(...) \, +#define Z_IS_2249U_EQ_2249(...) \, +#define Z_IS_2249_EQ_2249U(...) \, +#define Z_IS_2249U_EQ_2249U(...) \, +#define Z_IS_2250_EQ_2250(...) \, +#define Z_IS_2250U_EQ_2250(...) \, +#define Z_IS_2250_EQ_2250U(...) \, +#define Z_IS_2250U_EQ_2250U(...) \, +#define Z_IS_2251_EQ_2251(...) \, +#define Z_IS_2251U_EQ_2251(...) \, +#define Z_IS_2251_EQ_2251U(...) \, +#define Z_IS_2251U_EQ_2251U(...) \, +#define Z_IS_2252_EQ_2252(...) \, +#define Z_IS_2252U_EQ_2252(...) \, +#define Z_IS_2252_EQ_2252U(...) \, +#define Z_IS_2252U_EQ_2252U(...) \, +#define Z_IS_2253_EQ_2253(...) \, +#define Z_IS_2253U_EQ_2253(...) \, +#define Z_IS_2253_EQ_2253U(...) \, +#define Z_IS_2253U_EQ_2253U(...) \, +#define Z_IS_2254_EQ_2254(...) \, +#define Z_IS_2254U_EQ_2254(...) \, +#define Z_IS_2254_EQ_2254U(...) \, +#define Z_IS_2254U_EQ_2254U(...) \, +#define Z_IS_2255_EQ_2255(...) \, +#define Z_IS_2255U_EQ_2255(...) \, +#define Z_IS_2255_EQ_2255U(...) \, +#define Z_IS_2255U_EQ_2255U(...) \, +#define Z_IS_2256_EQ_2256(...) \, +#define Z_IS_2256U_EQ_2256(...) \, +#define Z_IS_2256_EQ_2256U(...) \, +#define Z_IS_2256U_EQ_2256U(...) \, +#define Z_IS_2257_EQ_2257(...) \, +#define Z_IS_2257U_EQ_2257(...) \, +#define Z_IS_2257_EQ_2257U(...) \, +#define Z_IS_2257U_EQ_2257U(...) \, +#define Z_IS_2258_EQ_2258(...) \, +#define Z_IS_2258U_EQ_2258(...) \, +#define Z_IS_2258_EQ_2258U(...) \, +#define Z_IS_2258U_EQ_2258U(...) \, +#define Z_IS_2259_EQ_2259(...) \, +#define Z_IS_2259U_EQ_2259(...) \, +#define Z_IS_2259_EQ_2259U(...) \, +#define Z_IS_2259U_EQ_2259U(...) \, +#define Z_IS_2260_EQ_2260(...) \, +#define Z_IS_2260U_EQ_2260(...) \, +#define Z_IS_2260_EQ_2260U(...) \, +#define Z_IS_2260U_EQ_2260U(...) \, +#define Z_IS_2261_EQ_2261(...) \, +#define Z_IS_2261U_EQ_2261(...) \, +#define Z_IS_2261_EQ_2261U(...) \, +#define Z_IS_2261U_EQ_2261U(...) \, +#define Z_IS_2262_EQ_2262(...) \, +#define Z_IS_2262U_EQ_2262(...) \, +#define Z_IS_2262_EQ_2262U(...) \, +#define Z_IS_2262U_EQ_2262U(...) \, +#define Z_IS_2263_EQ_2263(...) \, +#define Z_IS_2263U_EQ_2263(...) \, +#define Z_IS_2263_EQ_2263U(...) \, +#define Z_IS_2263U_EQ_2263U(...) \, +#define Z_IS_2264_EQ_2264(...) \, +#define Z_IS_2264U_EQ_2264(...) \, +#define Z_IS_2264_EQ_2264U(...) \, +#define Z_IS_2264U_EQ_2264U(...) \, +#define Z_IS_2265_EQ_2265(...) \, +#define Z_IS_2265U_EQ_2265(...) \, +#define Z_IS_2265_EQ_2265U(...) \, +#define Z_IS_2265U_EQ_2265U(...) \, +#define Z_IS_2266_EQ_2266(...) \, +#define Z_IS_2266U_EQ_2266(...) \, +#define Z_IS_2266_EQ_2266U(...) \, +#define Z_IS_2266U_EQ_2266U(...) \, +#define Z_IS_2267_EQ_2267(...) \, +#define Z_IS_2267U_EQ_2267(...) \, +#define Z_IS_2267_EQ_2267U(...) \, +#define Z_IS_2267U_EQ_2267U(...) \, +#define Z_IS_2268_EQ_2268(...) \, +#define Z_IS_2268U_EQ_2268(...) \, +#define Z_IS_2268_EQ_2268U(...) \, +#define Z_IS_2268U_EQ_2268U(...) \, +#define Z_IS_2269_EQ_2269(...) \, +#define Z_IS_2269U_EQ_2269(...) \, +#define Z_IS_2269_EQ_2269U(...) \, +#define Z_IS_2269U_EQ_2269U(...) \, +#define Z_IS_2270_EQ_2270(...) \, +#define Z_IS_2270U_EQ_2270(...) \, +#define Z_IS_2270_EQ_2270U(...) \, +#define Z_IS_2270U_EQ_2270U(...) \, +#define Z_IS_2271_EQ_2271(...) \, +#define Z_IS_2271U_EQ_2271(...) \, +#define Z_IS_2271_EQ_2271U(...) \, +#define Z_IS_2271U_EQ_2271U(...) \, +#define Z_IS_2272_EQ_2272(...) \, +#define Z_IS_2272U_EQ_2272(...) \, +#define Z_IS_2272_EQ_2272U(...) \, +#define Z_IS_2272U_EQ_2272U(...) \, +#define Z_IS_2273_EQ_2273(...) \, +#define Z_IS_2273U_EQ_2273(...) \, +#define Z_IS_2273_EQ_2273U(...) \, +#define Z_IS_2273U_EQ_2273U(...) \, +#define Z_IS_2274_EQ_2274(...) \, +#define Z_IS_2274U_EQ_2274(...) \, +#define Z_IS_2274_EQ_2274U(...) \, +#define Z_IS_2274U_EQ_2274U(...) \, +#define Z_IS_2275_EQ_2275(...) \, +#define Z_IS_2275U_EQ_2275(...) \, +#define Z_IS_2275_EQ_2275U(...) \, +#define Z_IS_2275U_EQ_2275U(...) \, +#define Z_IS_2276_EQ_2276(...) \, +#define Z_IS_2276U_EQ_2276(...) \, +#define Z_IS_2276_EQ_2276U(...) \, +#define Z_IS_2276U_EQ_2276U(...) \, +#define Z_IS_2277_EQ_2277(...) \, +#define Z_IS_2277U_EQ_2277(...) \, +#define Z_IS_2277_EQ_2277U(...) \, +#define Z_IS_2277U_EQ_2277U(...) \, +#define Z_IS_2278_EQ_2278(...) \, +#define Z_IS_2278U_EQ_2278(...) \, +#define Z_IS_2278_EQ_2278U(...) \, +#define Z_IS_2278U_EQ_2278U(...) \, +#define Z_IS_2279_EQ_2279(...) \, +#define Z_IS_2279U_EQ_2279(...) \, +#define Z_IS_2279_EQ_2279U(...) \, +#define Z_IS_2279U_EQ_2279U(...) \, +#define Z_IS_2280_EQ_2280(...) \, +#define Z_IS_2280U_EQ_2280(...) \, +#define Z_IS_2280_EQ_2280U(...) \, +#define Z_IS_2280U_EQ_2280U(...) \, +#define Z_IS_2281_EQ_2281(...) \, +#define Z_IS_2281U_EQ_2281(...) \, +#define Z_IS_2281_EQ_2281U(...) \, +#define Z_IS_2281U_EQ_2281U(...) \, +#define Z_IS_2282_EQ_2282(...) \, +#define Z_IS_2282U_EQ_2282(...) \, +#define Z_IS_2282_EQ_2282U(...) \, +#define Z_IS_2282U_EQ_2282U(...) \, +#define Z_IS_2283_EQ_2283(...) \, +#define Z_IS_2283U_EQ_2283(...) \, +#define Z_IS_2283_EQ_2283U(...) \, +#define Z_IS_2283U_EQ_2283U(...) \, +#define Z_IS_2284_EQ_2284(...) \, +#define Z_IS_2284U_EQ_2284(...) \, +#define Z_IS_2284_EQ_2284U(...) \, +#define Z_IS_2284U_EQ_2284U(...) \, +#define Z_IS_2285_EQ_2285(...) \, +#define Z_IS_2285U_EQ_2285(...) \, +#define Z_IS_2285_EQ_2285U(...) \, +#define Z_IS_2285U_EQ_2285U(...) \, +#define Z_IS_2286_EQ_2286(...) \, +#define Z_IS_2286U_EQ_2286(...) \, +#define Z_IS_2286_EQ_2286U(...) \, +#define Z_IS_2286U_EQ_2286U(...) \, +#define Z_IS_2287_EQ_2287(...) \, +#define Z_IS_2287U_EQ_2287(...) \, +#define Z_IS_2287_EQ_2287U(...) \, +#define Z_IS_2287U_EQ_2287U(...) \, +#define Z_IS_2288_EQ_2288(...) \, +#define Z_IS_2288U_EQ_2288(...) \, +#define Z_IS_2288_EQ_2288U(...) \, +#define Z_IS_2288U_EQ_2288U(...) \, +#define Z_IS_2289_EQ_2289(...) \, +#define Z_IS_2289U_EQ_2289(...) \, +#define Z_IS_2289_EQ_2289U(...) \, +#define Z_IS_2289U_EQ_2289U(...) \, +#define Z_IS_2290_EQ_2290(...) \, +#define Z_IS_2290U_EQ_2290(...) \, +#define Z_IS_2290_EQ_2290U(...) \, +#define Z_IS_2290U_EQ_2290U(...) \, +#define Z_IS_2291_EQ_2291(...) \, +#define Z_IS_2291U_EQ_2291(...) \, +#define Z_IS_2291_EQ_2291U(...) \, +#define Z_IS_2291U_EQ_2291U(...) \, +#define Z_IS_2292_EQ_2292(...) \, +#define Z_IS_2292U_EQ_2292(...) \, +#define Z_IS_2292_EQ_2292U(...) \, +#define Z_IS_2292U_EQ_2292U(...) \, +#define Z_IS_2293_EQ_2293(...) \, +#define Z_IS_2293U_EQ_2293(...) \, +#define Z_IS_2293_EQ_2293U(...) \, +#define Z_IS_2293U_EQ_2293U(...) \, +#define Z_IS_2294_EQ_2294(...) \, +#define Z_IS_2294U_EQ_2294(...) \, +#define Z_IS_2294_EQ_2294U(...) \, +#define Z_IS_2294U_EQ_2294U(...) \, +#define Z_IS_2295_EQ_2295(...) \, +#define Z_IS_2295U_EQ_2295(...) \, +#define Z_IS_2295_EQ_2295U(...) \, +#define Z_IS_2295U_EQ_2295U(...) \, +#define Z_IS_2296_EQ_2296(...) \, +#define Z_IS_2296U_EQ_2296(...) \, +#define Z_IS_2296_EQ_2296U(...) \, +#define Z_IS_2296U_EQ_2296U(...) \, +#define Z_IS_2297_EQ_2297(...) \, +#define Z_IS_2297U_EQ_2297(...) \, +#define Z_IS_2297_EQ_2297U(...) \, +#define Z_IS_2297U_EQ_2297U(...) \, +#define Z_IS_2298_EQ_2298(...) \, +#define Z_IS_2298U_EQ_2298(...) \, +#define Z_IS_2298_EQ_2298U(...) \, +#define Z_IS_2298U_EQ_2298U(...) \, +#define Z_IS_2299_EQ_2299(...) \, +#define Z_IS_2299U_EQ_2299(...) \, +#define Z_IS_2299_EQ_2299U(...) \, +#define Z_IS_2299U_EQ_2299U(...) \, +#define Z_IS_2300_EQ_2300(...) \, +#define Z_IS_2300U_EQ_2300(...) \, +#define Z_IS_2300_EQ_2300U(...) \, +#define Z_IS_2300U_EQ_2300U(...) \, +#define Z_IS_2301_EQ_2301(...) \, +#define Z_IS_2301U_EQ_2301(...) \, +#define Z_IS_2301_EQ_2301U(...) \, +#define Z_IS_2301U_EQ_2301U(...) \, +#define Z_IS_2302_EQ_2302(...) \, +#define Z_IS_2302U_EQ_2302(...) \, +#define Z_IS_2302_EQ_2302U(...) \, +#define Z_IS_2302U_EQ_2302U(...) \, +#define Z_IS_2303_EQ_2303(...) \, +#define Z_IS_2303U_EQ_2303(...) \, +#define Z_IS_2303_EQ_2303U(...) \, +#define Z_IS_2303U_EQ_2303U(...) \, +#define Z_IS_2304_EQ_2304(...) \, +#define Z_IS_2304U_EQ_2304(...) \, +#define Z_IS_2304_EQ_2304U(...) \, +#define Z_IS_2304U_EQ_2304U(...) \, +#define Z_IS_2305_EQ_2305(...) \, +#define Z_IS_2305U_EQ_2305(...) \, +#define Z_IS_2305_EQ_2305U(...) \, +#define Z_IS_2305U_EQ_2305U(...) \, +#define Z_IS_2306_EQ_2306(...) \, +#define Z_IS_2306U_EQ_2306(...) \, +#define Z_IS_2306_EQ_2306U(...) \, +#define Z_IS_2306U_EQ_2306U(...) \, +#define Z_IS_2307_EQ_2307(...) \, +#define Z_IS_2307U_EQ_2307(...) \, +#define Z_IS_2307_EQ_2307U(...) \, +#define Z_IS_2307U_EQ_2307U(...) \, +#define Z_IS_2308_EQ_2308(...) \, +#define Z_IS_2308U_EQ_2308(...) \, +#define Z_IS_2308_EQ_2308U(...) \, +#define Z_IS_2308U_EQ_2308U(...) \, +#define Z_IS_2309_EQ_2309(...) \, +#define Z_IS_2309U_EQ_2309(...) \, +#define Z_IS_2309_EQ_2309U(...) \, +#define Z_IS_2309U_EQ_2309U(...) \, +#define Z_IS_2310_EQ_2310(...) \, +#define Z_IS_2310U_EQ_2310(...) \, +#define Z_IS_2310_EQ_2310U(...) \, +#define Z_IS_2310U_EQ_2310U(...) \, +#define Z_IS_2311_EQ_2311(...) \, +#define Z_IS_2311U_EQ_2311(...) \, +#define Z_IS_2311_EQ_2311U(...) \, +#define Z_IS_2311U_EQ_2311U(...) \, +#define Z_IS_2312_EQ_2312(...) \, +#define Z_IS_2312U_EQ_2312(...) \, +#define Z_IS_2312_EQ_2312U(...) \, +#define Z_IS_2312U_EQ_2312U(...) \, +#define Z_IS_2313_EQ_2313(...) \, +#define Z_IS_2313U_EQ_2313(...) \, +#define Z_IS_2313_EQ_2313U(...) \, +#define Z_IS_2313U_EQ_2313U(...) \, +#define Z_IS_2314_EQ_2314(...) \, +#define Z_IS_2314U_EQ_2314(...) \, +#define Z_IS_2314_EQ_2314U(...) \, +#define Z_IS_2314U_EQ_2314U(...) \, +#define Z_IS_2315_EQ_2315(...) \, +#define Z_IS_2315U_EQ_2315(...) \, +#define Z_IS_2315_EQ_2315U(...) \, +#define Z_IS_2315U_EQ_2315U(...) \, +#define Z_IS_2316_EQ_2316(...) \, +#define Z_IS_2316U_EQ_2316(...) \, +#define Z_IS_2316_EQ_2316U(...) \, +#define Z_IS_2316U_EQ_2316U(...) \, +#define Z_IS_2317_EQ_2317(...) \, +#define Z_IS_2317U_EQ_2317(...) \, +#define Z_IS_2317_EQ_2317U(...) \, +#define Z_IS_2317U_EQ_2317U(...) \, +#define Z_IS_2318_EQ_2318(...) \, +#define Z_IS_2318U_EQ_2318(...) \, +#define Z_IS_2318_EQ_2318U(...) \, +#define Z_IS_2318U_EQ_2318U(...) \, +#define Z_IS_2319_EQ_2319(...) \, +#define Z_IS_2319U_EQ_2319(...) \, +#define Z_IS_2319_EQ_2319U(...) \, +#define Z_IS_2319U_EQ_2319U(...) \, +#define Z_IS_2320_EQ_2320(...) \, +#define Z_IS_2320U_EQ_2320(...) \, +#define Z_IS_2320_EQ_2320U(...) \, +#define Z_IS_2320U_EQ_2320U(...) \, +#define Z_IS_2321_EQ_2321(...) \, +#define Z_IS_2321U_EQ_2321(...) \, +#define Z_IS_2321_EQ_2321U(...) \, +#define Z_IS_2321U_EQ_2321U(...) \, +#define Z_IS_2322_EQ_2322(...) \, +#define Z_IS_2322U_EQ_2322(...) \, +#define Z_IS_2322_EQ_2322U(...) \, +#define Z_IS_2322U_EQ_2322U(...) \, +#define Z_IS_2323_EQ_2323(...) \, +#define Z_IS_2323U_EQ_2323(...) \, +#define Z_IS_2323_EQ_2323U(...) \, +#define Z_IS_2323U_EQ_2323U(...) \, +#define Z_IS_2324_EQ_2324(...) \, +#define Z_IS_2324U_EQ_2324(...) \, +#define Z_IS_2324_EQ_2324U(...) \, +#define Z_IS_2324U_EQ_2324U(...) \, +#define Z_IS_2325_EQ_2325(...) \, +#define Z_IS_2325U_EQ_2325(...) \, +#define Z_IS_2325_EQ_2325U(...) \, +#define Z_IS_2325U_EQ_2325U(...) \, +#define Z_IS_2326_EQ_2326(...) \, +#define Z_IS_2326U_EQ_2326(...) \, +#define Z_IS_2326_EQ_2326U(...) \, +#define Z_IS_2326U_EQ_2326U(...) \, +#define Z_IS_2327_EQ_2327(...) \, +#define Z_IS_2327U_EQ_2327(...) \, +#define Z_IS_2327_EQ_2327U(...) \, +#define Z_IS_2327U_EQ_2327U(...) \, +#define Z_IS_2328_EQ_2328(...) \, +#define Z_IS_2328U_EQ_2328(...) \, +#define Z_IS_2328_EQ_2328U(...) \, +#define Z_IS_2328U_EQ_2328U(...) \, +#define Z_IS_2329_EQ_2329(...) \, +#define Z_IS_2329U_EQ_2329(...) \, +#define Z_IS_2329_EQ_2329U(...) \, +#define Z_IS_2329U_EQ_2329U(...) \, +#define Z_IS_2330_EQ_2330(...) \, +#define Z_IS_2330U_EQ_2330(...) \, +#define Z_IS_2330_EQ_2330U(...) \, +#define Z_IS_2330U_EQ_2330U(...) \, +#define Z_IS_2331_EQ_2331(...) \, +#define Z_IS_2331U_EQ_2331(...) \, +#define Z_IS_2331_EQ_2331U(...) \, +#define Z_IS_2331U_EQ_2331U(...) \, +#define Z_IS_2332_EQ_2332(...) \, +#define Z_IS_2332U_EQ_2332(...) \, +#define Z_IS_2332_EQ_2332U(...) \, +#define Z_IS_2332U_EQ_2332U(...) \, +#define Z_IS_2333_EQ_2333(...) \, +#define Z_IS_2333U_EQ_2333(...) \, +#define Z_IS_2333_EQ_2333U(...) \, +#define Z_IS_2333U_EQ_2333U(...) \, +#define Z_IS_2334_EQ_2334(...) \, +#define Z_IS_2334U_EQ_2334(...) \, +#define Z_IS_2334_EQ_2334U(...) \, +#define Z_IS_2334U_EQ_2334U(...) \, +#define Z_IS_2335_EQ_2335(...) \, +#define Z_IS_2335U_EQ_2335(...) \, +#define Z_IS_2335_EQ_2335U(...) \, +#define Z_IS_2335U_EQ_2335U(...) \, +#define Z_IS_2336_EQ_2336(...) \, +#define Z_IS_2336U_EQ_2336(...) \, +#define Z_IS_2336_EQ_2336U(...) \, +#define Z_IS_2336U_EQ_2336U(...) \, +#define Z_IS_2337_EQ_2337(...) \, +#define Z_IS_2337U_EQ_2337(...) \, +#define Z_IS_2337_EQ_2337U(...) \, +#define Z_IS_2337U_EQ_2337U(...) \, +#define Z_IS_2338_EQ_2338(...) \, +#define Z_IS_2338U_EQ_2338(...) \, +#define Z_IS_2338_EQ_2338U(...) \, +#define Z_IS_2338U_EQ_2338U(...) \, +#define Z_IS_2339_EQ_2339(...) \, +#define Z_IS_2339U_EQ_2339(...) \, +#define Z_IS_2339_EQ_2339U(...) \, +#define Z_IS_2339U_EQ_2339U(...) \, +#define Z_IS_2340_EQ_2340(...) \, +#define Z_IS_2340U_EQ_2340(...) \, +#define Z_IS_2340_EQ_2340U(...) \, +#define Z_IS_2340U_EQ_2340U(...) \, +#define Z_IS_2341_EQ_2341(...) \, +#define Z_IS_2341U_EQ_2341(...) \, +#define Z_IS_2341_EQ_2341U(...) \, +#define Z_IS_2341U_EQ_2341U(...) \, +#define Z_IS_2342_EQ_2342(...) \, +#define Z_IS_2342U_EQ_2342(...) \, +#define Z_IS_2342_EQ_2342U(...) \, +#define Z_IS_2342U_EQ_2342U(...) \, +#define Z_IS_2343_EQ_2343(...) \, +#define Z_IS_2343U_EQ_2343(...) \, +#define Z_IS_2343_EQ_2343U(...) \, +#define Z_IS_2343U_EQ_2343U(...) \, +#define Z_IS_2344_EQ_2344(...) \, +#define Z_IS_2344U_EQ_2344(...) \, +#define Z_IS_2344_EQ_2344U(...) \, +#define Z_IS_2344U_EQ_2344U(...) \, +#define Z_IS_2345_EQ_2345(...) \, +#define Z_IS_2345U_EQ_2345(...) \, +#define Z_IS_2345_EQ_2345U(...) \, +#define Z_IS_2345U_EQ_2345U(...) \, +#define Z_IS_2346_EQ_2346(...) \, +#define Z_IS_2346U_EQ_2346(...) \, +#define Z_IS_2346_EQ_2346U(...) \, +#define Z_IS_2346U_EQ_2346U(...) \, +#define Z_IS_2347_EQ_2347(...) \, +#define Z_IS_2347U_EQ_2347(...) \, +#define Z_IS_2347_EQ_2347U(...) \, +#define Z_IS_2347U_EQ_2347U(...) \, +#define Z_IS_2348_EQ_2348(...) \, +#define Z_IS_2348U_EQ_2348(...) \, +#define Z_IS_2348_EQ_2348U(...) \, +#define Z_IS_2348U_EQ_2348U(...) \, +#define Z_IS_2349_EQ_2349(...) \, +#define Z_IS_2349U_EQ_2349(...) \, +#define Z_IS_2349_EQ_2349U(...) \, +#define Z_IS_2349U_EQ_2349U(...) \, +#define Z_IS_2350_EQ_2350(...) \, +#define Z_IS_2350U_EQ_2350(...) \, +#define Z_IS_2350_EQ_2350U(...) \, +#define Z_IS_2350U_EQ_2350U(...) \, +#define Z_IS_2351_EQ_2351(...) \, +#define Z_IS_2351U_EQ_2351(...) \, +#define Z_IS_2351_EQ_2351U(...) \, +#define Z_IS_2351U_EQ_2351U(...) \, +#define Z_IS_2352_EQ_2352(...) \, +#define Z_IS_2352U_EQ_2352(...) \, +#define Z_IS_2352_EQ_2352U(...) \, +#define Z_IS_2352U_EQ_2352U(...) \, +#define Z_IS_2353_EQ_2353(...) \, +#define Z_IS_2353U_EQ_2353(...) \, +#define Z_IS_2353_EQ_2353U(...) \, +#define Z_IS_2353U_EQ_2353U(...) \, +#define Z_IS_2354_EQ_2354(...) \, +#define Z_IS_2354U_EQ_2354(...) \, +#define Z_IS_2354_EQ_2354U(...) \, +#define Z_IS_2354U_EQ_2354U(...) \, +#define Z_IS_2355_EQ_2355(...) \, +#define Z_IS_2355U_EQ_2355(...) \, +#define Z_IS_2355_EQ_2355U(...) \, +#define Z_IS_2355U_EQ_2355U(...) \, +#define Z_IS_2356_EQ_2356(...) \, +#define Z_IS_2356U_EQ_2356(...) \, +#define Z_IS_2356_EQ_2356U(...) \, +#define Z_IS_2356U_EQ_2356U(...) \, +#define Z_IS_2357_EQ_2357(...) \, +#define Z_IS_2357U_EQ_2357(...) \, +#define Z_IS_2357_EQ_2357U(...) \, +#define Z_IS_2357U_EQ_2357U(...) \, +#define Z_IS_2358_EQ_2358(...) \, +#define Z_IS_2358U_EQ_2358(...) \, +#define Z_IS_2358_EQ_2358U(...) \, +#define Z_IS_2358U_EQ_2358U(...) \, +#define Z_IS_2359_EQ_2359(...) \, +#define Z_IS_2359U_EQ_2359(...) \, +#define Z_IS_2359_EQ_2359U(...) \, +#define Z_IS_2359U_EQ_2359U(...) \, +#define Z_IS_2360_EQ_2360(...) \, +#define Z_IS_2360U_EQ_2360(...) \, +#define Z_IS_2360_EQ_2360U(...) \, +#define Z_IS_2360U_EQ_2360U(...) \, +#define Z_IS_2361_EQ_2361(...) \, +#define Z_IS_2361U_EQ_2361(...) \, +#define Z_IS_2361_EQ_2361U(...) \, +#define Z_IS_2361U_EQ_2361U(...) \, +#define Z_IS_2362_EQ_2362(...) \, +#define Z_IS_2362U_EQ_2362(...) \, +#define Z_IS_2362_EQ_2362U(...) \, +#define Z_IS_2362U_EQ_2362U(...) \, +#define Z_IS_2363_EQ_2363(...) \, +#define Z_IS_2363U_EQ_2363(...) \, +#define Z_IS_2363_EQ_2363U(...) \, +#define Z_IS_2363U_EQ_2363U(...) \, +#define Z_IS_2364_EQ_2364(...) \, +#define Z_IS_2364U_EQ_2364(...) \, +#define Z_IS_2364_EQ_2364U(...) \, +#define Z_IS_2364U_EQ_2364U(...) \, +#define Z_IS_2365_EQ_2365(...) \, +#define Z_IS_2365U_EQ_2365(...) \, +#define Z_IS_2365_EQ_2365U(...) \, +#define Z_IS_2365U_EQ_2365U(...) \, +#define Z_IS_2366_EQ_2366(...) \, +#define Z_IS_2366U_EQ_2366(...) \, +#define Z_IS_2366_EQ_2366U(...) \, +#define Z_IS_2366U_EQ_2366U(...) \, +#define Z_IS_2367_EQ_2367(...) \, +#define Z_IS_2367U_EQ_2367(...) \, +#define Z_IS_2367_EQ_2367U(...) \, +#define Z_IS_2367U_EQ_2367U(...) \, +#define Z_IS_2368_EQ_2368(...) \, +#define Z_IS_2368U_EQ_2368(...) \, +#define Z_IS_2368_EQ_2368U(...) \, +#define Z_IS_2368U_EQ_2368U(...) \, +#define Z_IS_2369_EQ_2369(...) \, +#define Z_IS_2369U_EQ_2369(...) \, +#define Z_IS_2369_EQ_2369U(...) \, +#define Z_IS_2369U_EQ_2369U(...) \, +#define Z_IS_2370_EQ_2370(...) \, +#define Z_IS_2370U_EQ_2370(...) \, +#define Z_IS_2370_EQ_2370U(...) \, +#define Z_IS_2370U_EQ_2370U(...) \, +#define Z_IS_2371_EQ_2371(...) \, +#define Z_IS_2371U_EQ_2371(...) \, +#define Z_IS_2371_EQ_2371U(...) \, +#define Z_IS_2371U_EQ_2371U(...) \, +#define Z_IS_2372_EQ_2372(...) \, +#define Z_IS_2372U_EQ_2372(...) \, +#define Z_IS_2372_EQ_2372U(...) \, +#define Z_IS_2372U_EQ_2372U(...) \, +#define Z_IS_2373_EQ_2373(...) \, +#define Z_IS_2373U_EQ_2373(...) \, +#define Z_IS_2373_EQ_2373U(...) \, +#define Z_IS_2373U_EQ_2373U(...) \, +#define Z_IS_2374_EQ_2374(...) \, +#define Z_IS_2374U_EQ_2374(...) \, +#define Z_IS_2374_EQ_2374U(...) \, +#define Z_IS_2374U_EQ_2374U(...) \, +#define Z_IS_2375_EQ_2375(...) \, +#define Z_IS_2375U_EQ_2375(...) \, +#define Z_IS_2375_EQ_2375U(...) \, +#define Z_IS_2375U_EQ_2375U(...) \, +#define Z_IS_2376_EQ_2376(...) \, +#define Z_IS_2376U_EQ_2376(...) \, +#define Z_IS_2376_EQ_2376U(...) \, +#define Z_IS_2376U_EQ_2376U(...) \, +#define Z_IS_2377_EQ_2377(...) \, +#define Z_IS_2377U_EQ_2377(...) \, +#define Z_IS_2377_EQ_2377U(...) \, +#define Z_IS_2377U_EQ_2377U(...) \, +#define Z_IS_2378_EQ_2378(...) \, +#define Z_IS_2378U_EQ_2378(...) \, +#define Z_IS_2378_EQ_2378U(...) \, +#define Z_IS_2378U_EQ_2378U(...) \, +#define Z_IS_2379_EQ_2379(...) \, +#define Z_IS_2379U_EQ_2379(...) \, +#define Z_IS_2379_EQ_2379U(...) \, +#define Z_IS_2379U_EQ_2379U(...) \, +#define Z_IS_2380_EQ_2380(...) \, +#define Z_IS_2380U_EQ_2380(...) \, +#define Z_IS_2380_EQ_2380U(...) \, +#define Z_IS_2380U_EQ_2380U(...) \, +#define Z_IS_2381_EQ_2381(...) \, +#define Z_IS_2381U_EQ_2381(...) \, +#define Z_IS_2381_EQ_2381U(...) \, +#define Z_IS_2381U_EQ_2381U(...) \, +#define Z_IS_2382_EQ_2382(...) \, +#define Z_IS_2382U_EQ_2382(...) \, +#define Z_IS_2382_EQ_2382U(...) \, +#define Z_IS_2382U_EQ_2382U(...) \, +#define Z_IS_2383_EQ_2383(...) \, +#define Z_IS_2383U_EQ_2383(...) \, +#define Z_IS_2383_EQ_2383U(...) \, +#define Z_IS_2383U_EQ_2383U(...) \, +#define Z_IS_2384_EQ_2384(...) \, +#define Z_IS_2384U_EQ_2384(...) \, +#define Z_IS_2384_EQ_2384U(...) \, +#define Z_IS_2384U_EQ_2384U(...) \, +#define Z_IS_2385_EQ_2385(...) \, +#define Z_IS_2385U_EQ_2385(...) \, +#define Z_IS_2385_EQ_2385U(...) \, +#define Z_IS_2385U_EQ_2385U(...) \, +#define Z_IS_2386_EQ_2386(...) \, +#define Z_IS_2386U_EQ_2386(...) \, +#define Z_IS_2386_EQ_2386U(...) \, +#define Z_IS_2386U_EQ_2386U(...) \, +#define Z_IS_2387_EQ_2387(...) \, +#define Z_IS_2387U_EQ_2387(...) \, +#define Z_IS_2387_EQ_2387U(...) \, +#define Z_IS_2387U_EQ_2387U(...) \, +#define Z_IS_2388_EQ_2388(...) \, +#define Z_IS_2388U_EQ_2388(...) \, +#define Z_IS_2388_EQ_2388U(...) \, +#define Z_IS_2388U_EQ_2388U(...) \, +#define Z_IS_2389_EQ_2389(...) \, +#define Z_IS_2389U_EQ_2389(...) \, +#define Z_IS_2389_EQ_2389U(...) \, +#define Z_IS_2389U_EQ_2389U(...) \, +#define Z_IS_2390_EQ_2390(...) \, +#define Z_IS_2390U_EQ_2390(...) \, +#define Z_IS_2390_EQ_2390U(...) \, +#define Z_IS_2390U_EQ_2390U(...) \, +#define Z_IS_2391_EQ_2391(...) \, +#define Z_IS_2391U_EQ_2391(...) \, +#define Z_IS_2391_EQ_2391U(...) \, +#define Z_IS_2391U_EQ_2391U(...) \, +#define Z_IS_2392_EQ_2392(...) \, +#define Z_IS_2392U_EQ_2392(...) \, +#define Z_IS_2392_EQ_2392U(...) \, +#define Z_IS_2392U_EQ_2392U(...) \, +#define Z_IS_2393_EQ_2393(...) \, +#define Z_IS_2393U_EQ_2393(...) \, +#define Z_IS_2393_EQ_2393U(...) \, +#define Z_IS_2393U_EQ_2393U(...) \, +#define Z_IS_2394_EQ_2394(...) \, +#define Z_IS_2394U_EQ_2394(...) \, +#define Z_IS_2394_EQ_2394U(...) \, +#define Z_IS_2394U_EQ_2394U(...) \, +#define Z_IS_2395_EQ_2395(...) \, +#define Z_IS_2395U_EQ_2395(...) \, +#define Z_IS_2395_EQ_2395U(...) \, +#define Z_IS_2395U_EQ_2395U(...) \, +#define Z_IS_2396_EQ_2396(...) \, +#define Z_IS_2396U_EQ_2396(...) \, +#define Z_IS_2396_EQ_2396U(...) \, +#define Z_IS_2396U_EQ_2396U(...) \, +#define Z_IS_2397_EQ_2397(...) \, +#define Z_IS_2397U_EQ_2397(...) \, +#define Z_IS_2397_EQ_2397U(...) \, +#define Z_IS_2397U_EQ_2397U(...) \, +#define Z_IS_2398_EQ_2398(...) \, +#define Z_IS_2398U_EQ_2398(...) \, +#define Z_IS_2398_EQ_2398U(...) \, +#define Z_IS_2398U_EQ_2398U(...) \, +#define Z_IS_2399_EQ_2399(...) \, +#define Z_IS_2399U_EQ_2399(...) \, +#define Z_IS_2399_EQ_2399U(...) \, +#define Z_IS_2399U_EQ_2399U(...) \, +#define Z_IS_2400_EQ_2400(...) \, +#define Z_IS_2400U_EQ_2400(...) \, +#define Z_IS_2400_EQ_2400U(...) \, +#define Z_IS_2400U_EQ_2400U(...) \, +#define Z_IS_2401_EQ_2401(...) \, +#define Z_IS_2401U_EQ_2401(...) \, +#define Z_IS_2401_EQ_2401U(...) \, +#define Z_IS_2401U_EQ_2401U(...) \, +#define Z_IS_2402_EQ_2402(...) \, +#define Z_IS_2402U_EQ_2402(...) \, +#define Z_IS_2402_EQ_2402U(...) \, +#define Z_IS_2402U_EQ_2402U(...) \, +#define Z_IS_2403_EQ_2403(...) \, +#define Z_IS_2403U_EQ_2403(...) \, +#define Z_IS_2403_EQ_2403U(...) \, +#define Z_IS_2403U_EQ_2403U(...) \, +#define Z_IS_2404_EQ_2404(...) \, +#define Z_IS_2404U_EQ_2404(...) \, +#define Z_IS_2404_EQ_2404U(...) \, +#define Z_IS_2404U_EQ_2404U(...) \, +#define Z_IS_2405_EQ_2405(...) \, +#define Z_IS_2405U_EQ_2405(...) \, +#define Z_IS_2405_EQ_2405U(...) \, +#define Z_IS_2405U_EQ_2405U(...) \, +#define Z_IS_2406_EQ_2406(...) \, +#define Z_IS_2406U_EQ_2406(...) \, +#define Z_IS_2406_EQ_2406U(...) \, +#define Z_IS_2406U_EQ_2406U(...) \, +#define Z_IS_2407_EQ_2407(...) \, +#define Z_IS_2407U_EQ_2407(...) \, +#define Z_IS_2407_EQ_2407U(...) \, +#define Z_IS_2407U_EQ_2407U(...) \, +#define Z_IS_2408_EQ_2408(...) \, +#define Z_IS_2408U_EQ_2408(...) \, +#define Z_IS_2408_EQ_2408U(...) \, +#define Z_IS_2408U_EQ_2408U(...) \, +#define Z_IS_2409_EQ_2409(...) \, +#define Z_IS_2409U_EQ_2409(...) \, +#define Z_IS_2409_EQ_2409U(...) \, +#define Z_IS_2409U_EQ_2409U(...) \, +#define Z_IS_2410_EQ_2410(...) \, +#define Z_IS_2410U_EQ_2410(...) \, +#define Z_IS_2410_EQ_2410U(...) \, +#define Z_IS_2410U_EQ_2410U(...) \, +#define Z_IS_2411_EQ_2411(...) \, +#define Z_IS_2411U_EQ_2411(...) \, +#define Z_IS_2411_EQ_2411U(...) \, +#define Z_IS_2411U_EQ_2411U(...) \, +#define Z_IS_2412_EQ_2412(...) \, +#define Z_IS_2412U_EQ_2412(...) \, +#define Z_IS_2412_EQ_2412U(...) \, +#define Z_IS_2412U_EQ_2412U(...) \, +#define Z_IS_2413_EQ_2413(...) \, +#define Z_IS_2413U_EQ_2413(...) \, +#define Z_IS_2413_EQ_2413U(...) \, +#define Z_IS_2413U_EQ_2413U(...) \, +#define Z_IS_2414_EQ_2414(...) \, +#define Z_IS_2414U_EQ_2414(...) \, +#define Z_IS_2414_EQ_2414U(...) \, +#define Z_IS_2414U_EQ_2414U(...) \, +#define Z_IS_2415_EQ_2415(...) \, +#define Z_IS_2415U_EQ_2415(...) \, +#define Z_IS_2415_EQ_2415U(...) \, +#define Z_IS_2415U_EQ_2415U(...) \, +#define Z_IS_2416_EQ_2416(...) \, +#define Z_IS_2416U_EQ_2416(...) \, +#define Z_IS_2416_EQ_2416U(...) \, +#define Z_IS_2416U_EQ_2416U(...) \, +#define Z_IS_2417_EQ_2417(...) \, +#define Z_IS_2417U_EQ_2417(...) \, +#define Z_IS_2417_EQ_2417U(...) \, +#define Z_IS_2417U_EQ_2417U(...) \, +#define Z_IS_2418_EQ_2418(...) \, +#define Z_IS_2418U_EQ_2418(...) \, +#define Z_IS_2418_EQ_2418U(...) \, +#define Z_IS_2418U_EQ_2418U(...) \, +#define Z_IS_2419_EQ_2419(...) \, +#define Z_IS_2419U_EQ_2419(...) \, +#define Z_IS_2419_EQ_2419U(...) \, +#define Z_IS_2419U_EQ_2419U(...) \, +#define Z_IS_2420_EQ_2420(...) \, +#define Z_IS_2420U_EQ_2420(...) \, +#define Z_IS_2420_EQ_2420U(...) \, +#define Z_IS_2420U_EQ_2420U(...) \, +#define Z_IS_2421_EQ_2421(...) \, +#define Z_IS_2421U_EQ_2421(...) \, +#define Z_IS_2421_EQ_2421U(...) \, +#define Z_IS_2421U_EQ_2421U(...) \, +#define Z_IS_2422_EQ_2422(...) \, +#define Z_IS_2422U_EQ_2422(...) \, +#define Z_IS_2422_EQ_2422U(...) \, +#define Z_IS_2422U_EQ_2422U(...) \, +#define Z_IS_2423_EQ_2423(...) \, +#define Z_IS_2423U_EQ_2423(...) \, +#define Z_IS_2423_EQ_2423U(...) \, +#define Z_IS_2423U_EQ_2423U(...) \, +#define Z_IS_2424_EQ_2424(...) \, +#define Z_IS_2424U_EQ_2424(...) \, +#define Z_IS_2424_EQ_2424U(...) \, +#define Z_IS_2424U_EQ_2424U(...) \, +#define Z_IS_2425_EQ_2425(...) \, +#define Z_IS_2425U_EQ_2425(...) \, +#define Z_IS_2425_EQ_2425U(...) \, +#define Z_IS_2425U_EQ_2425U(...) \, +#define Z_IS_2426_EQ_2426(...) \, +#define Z_IS_2426U_EQ_2426(...) \, +#define Z_IS_2426_EQ_2426U(...) \, +#define Z_IS_2426U_EQ_2426U(...) \, +#define Z_IS_2427_EQ_2427(...) \, +#define Z_IS_2427U_EQ_2427(...) \, +#define Z_IS_2427_EQ_2427U(...) \, +#define Z_IS_2427U_EQ_2427U(...) \, +#define Z_IS_2428_EQ_2428(...) \, +#define Z_IS_2428U_EQ_2428(...) \, +#define Z_IS_2428_EQ_2428U(...) \, +#define Z_IS_2428U_EQ_2428U(...) \, +#define Z_IS_2429_EQ_2429(...) \, +#define Z_IS_2429U_EQ_2429(...) \, +#define Z_IS_2429_EQ_2429U(...) \, +#define Z_IS_2429U_EQ_2429U(...) \, +#define Z_IS_2430_EQ_2430(...) \, +#define Z_IS_2430U_EQ_2430(...) \, +#define Z_IS_2430_EQ_2430U(...) \, +#define Z_IS_2430U_EQ_2430U(...) \, +#define Z_IS_2431_EQ_2431(...) \, +#define Z_IS_2431U_EQ_2431(...) \, +#define Z_IS_2431_EQ_2431U(...) \, +#define Z_IS_2431U_EQ_2431U(...) \, +#define Z_IS_2432_EQ_2432(...) \, +#define Z_IS_2432U_EQ_2432(...) \, +#define Z_IS_2432_EQ_2432U(...) \, +#define Z_IS_2432U_EQ_2432U(...) \, +#define Z_IS_2433_EQ_2433(...) \, +#define Z_IS_2433U_EQ_2433(...) \, +#define Z_IS_2433_EQ_2433U(...) \, +#define Z_IS_2433U_EQ_2433U(...) \, +#define Z_IS_2434_EQ_2434(...) \, +#define Z_IS_2434U_EQ_2434(...) \, +#define Z_IS_2434_EQ_2434U(...) \, +#define Z_IS_2434U_EQ_2434U(...) \, +#define Z_IS_2435_EQ_2435(...) \, +#define Z_IS_2435U_EQ_2435(...) \, +#define Z_IS_2435_EQ_2435U(...) \, +#define Z_IS_2435U_EQ_2435U(...) \, +#define Z_IS_2436_EQ_2436(...) \, +#define Z_IS_2436U_EQ_2436(...) \, +#define Z_IS_2436_EQ_2436U(...) \, +#define Z_IS_2436U_EQ_2436U(...) \, +#define Z_IS_2437_EQ_2437(...) \, +#define Z_IS_2437U_EQ_2437(...) \, +#define Z_IS_2437_EQ_2437U(...) \, +#define Z_IS_2437U_EQ_2437U(...) \, +#define Z_IS_2438_EQ_2438(...) \, +#define Z_IS_2438U_EQ_2438(...) \, +#define Z_IS_2438_EQ_2438U(...) \, +#define Z_IS_2438U_EQ_2438U(...) \, +#define Z_IS_2439_EQ_2439(...) \, +#define Z_IS_2439U_EQ_2439(...) \, +#define Z_IS_2439_EQ_2439U(...) \, +#define Z_IS_2439U_EQ_2439U(...) \, +#define Z_IS_2440_EQ_2440(...) \, +#define Z_IS_2440U_EQ_2440(...) \, +#define Z_IS_2440_EQ_2440U(...) \, +#define Z_IS_2440U_EQ_2440U(...) \, +#define Z_IS_2441_EQ_2441(...) \, +#define Z_IS_2441U_EQ_2441(...) \, +#define Z_IS_2441_EQ_2441U(...) \, +#define Z_IS_2441U_EQ_2441U(...) \, +#define Z_IS_2442_EQ_2442(...) \, +#define Z_IS_2442U_EQ_2442(...) \, +#define Z_IS_2442_EQ_2442U(...) \, +#define Z_IS_2442U_EQ_2442U(...) \, +#define Z_IS_2443_EQ_2443(...) \, +#define Z_IS_2443U_EQ_2443(...) \, +#define Z_IS_2443_EQ_2443U(...) \, +#define Z_IS_2443U_EQ_2443U(...) \, +#define Z_IS_2444_EQ_2444(...) \, +#define Z_IS_2444U_EQ_2444(...) \, +#define Z_IS_2444_EQ_2444U(...) \, +#define Z_IS_2444U_EQ_2444U(...) \, +#define Z_IS_2445_EQ_2445(...) \, +#define Z_IS_2445U_EQ_2445(...) \, +#define Z_IS_2445_EQ_2445U(...) \, +#define Z_IS_2445U_EQ_2445U(...) \, +#define Z_IS_2446_EQ_2446(...) \, +#define Z_IS_2446U_EQ_2446(...) \, +#define Z_IS_2446_EQ_2446U(...) \, +#define Z_IS_2446U_EQ_2446U(...) \, +#define Z_IS_2447_EQ_2447(...) \, +#define Z_IS_2447U_EQ_2447(...) \, +#define Z_IS_2447_EQ_2447U(...) \, +#define Z_IS_2447U_EQ_2447U(...) \, +#define Z_IS_2448_EQ_2448(...) \, +#define Z_IS_2448U_EQ_2448(...) \, +#define Z_IS_2448_EQ_2448U(...) \, +#define Z_IS_2448U_EQ_2448U(...) \, +#define Z_IS_2449_EQ_2449(...) \, +#define Z_IS_2449U_EQ_2449(...) \, +#define Z_IS_2449_EQ_2449U(...) \, +#define Z_IS_2449U_EQ_2449U(...) \, +#define Z_IS_2450_EQ_2450(...) \, +#define Z_IS_2450U_EQ_2450(...) \, +#define Z_IS_2450_EQ_2450U(...) \, +#define Z_IS_2450U_EQ_2450U(...) \, +#define Z_IS_2451_EQ_2451(...) \, +#define Z_IS_2451U_EQ_2451(...) \, +#define Z_IS_2451_EQ_2451U(...) \, +#define Z_IS_2451U_EQ_2451U(...) \, +#define Z_IS_2452_EQ_2452(...) \, +#define Z_IS_2452U_EQ_2452(...) \, +#define Z_IS_2452_EQ_2452U(...) \, +#define Z_IS_2452U_EQ_2452U(...) \, +#define Z_IS_2453_EQ_2453(...) \, +#define Z_IS_2453U_EQ_2453(...) \, +#define Z_IS_2453_EQ_2453U(...) \, +#define Z_IS_2453U_EQ_2453U(...) \, +#define Z_IS_2454_EQ_2454(...) \, +#define Z_IS_2454U_EQ_2454(...) \, +#define Z_IS_2454_EQ_2454U(...) \, +#define Z_IS_2454U_EQ_2454U(...) \, +#define Z_IS_2455_EQ_2455(...) \, +#define Z_IS_2455U_EQ_2455(...) \, +#define Z_IS_2455_EQ_2455U(...) \, +#define Z_IS_2455U_EQ_2455U(...) \, +#define Z_IS_2456_EQ_2456(...) \, +#define Z_IS_2456U_EQ_2456(...) \, +#define Z_IS_2456_EQ_2456U(...) \, +#define Z_IS_2456U_EQ_2456U(...) \, +#define Z_IS_2457_EQ_2457(...) \, +#define Z_IS_2457U_EQ_2457(...) \, +#define Z_IS_2457_EQ_2457U(...) \, +#define Z_IS_2457U_EQ_2457U(...) \, +#define Z_IS_2458_EQ_2458(...) \, +#define Z_IS_2458U_EQ_2458(...) \, +#define Z_IS_2458_EQ_2458U(...) \, +#define Z_IS_2458U_EQ_2458U(...) \, +#define Z_IS_2459_EQ_2459(...) \, +#define Z_IS_2459U_EQ_2459(...) \, +#define Z_IS_2459_EQ_2459U(...) \, +#define Z_IS_2459U_EQ_2459U(...) \, +#define Z_IS_2460_EQ_2460(...) \, +#define Z_IS_2460U_EQ_2460(...) \, +#define Z_IS_2460_EQ_2460U(...) \, +#define Z_IS_2460U_EQ_2460U(...) \, +#define Z_IS_2461_EQ_2461(...) \, +#define Z_IS_2461U_EQ_2461(...) \, +#define Z_IS_2461_EQ_2461U(...) \, +#define Z_IS_2461U_EQ_2461U(...) \, +#define Z_IS_2462_EQ_2462(...) \, +#define Z_IS_2462U_EQ_2462(...) \, +#define Z_IS_2462_EQ_2462U(...) \, +#define Z_IS_2462U_EQ_2462U(...) \, +#define Z_IS_2463_EQ_2463(...) \, +#define Z_IS_2463U_EQ_2463(...) \, +#define Z_IS_2463_EQ_2463U(...) \, +#define Z_IS_2463U_EQ_2463U(...) \, +#define Z_IS_2464_EQ_2464(...) \, +#define Z_IS_2464U_EQ_2464(...) \, +#define Z_IS_2464_EQ_2464U(...) \, +#define Z_IS_2464U_EQ_2464U(...) \, +#define Z_IS_2465_EQ_2465(...) \, +#define Z_IS_2465U_EQ_2465(...) \, +#define Z_IS_2465_EQ_2465U(...) \, +#define Z_IS_2465U_EQ_2465U(...) \, +#define Z_IS_2466_EQ_2466(...) \, +#define Z_IS_2466U_EQ_2466(...) \, +#define Z_IS_2466_EQ_2466U(...) \, +#define Z_IS_2466U_EQ_2466U(...) \, +#define Z_IS_2467_EQ_2467(...) \, +#define Z_IS_2467U_EQ_2467(...) \, +#define Z_IS_2467_EQ_2467U(...) \, +#define Z_IS_2467U_EQ_2467U(...) \, +#define Z_IS_2468_EQ_2468(...) \, +#define Z_IS_2468U_EQ_2468(...) \, +#define Z_IS_2468_EQ_2468U(...) \, +#define Z_IS_2468U_EQ_2468U(...) \, +#define Z_IS_2469_EQ_2469(...) \, +#define Z_IS_2469U_EQ_2469(...) \, +#define Z_IS_2469_EQ_2469U(...) \, +#define Z_IS_2469U_EQ_2469U(...) \, +#define Z_IS_2470_EQ_2470(...) \, +#define Z_IS_2470U_EQ_2470(...) \, +#define Z_IS_2470_EQ_2470U(...) \, +#define Z_IS_2470U_EQ_2470U(...) \, +#define Z_IS_2471_EQ_2471(...) \, +#define Z_IS_2471U_EQ_2471(...) \, +#define Z_IS_2471_EQ_2471U(...) \, +#define Z_IS_2471U_EQ_2471U(...) \, +#define Z_IS_2472_EQ_2472(...) \, +#define Z_IS_2472U_EQ_2472(...) \, +#define Z_IS_2472_EQ_2472U(...) \, +#define Z_IS_2472U_EQ_2472U(...) \, +#define Z_IS_2473_EQ_2473(...) \, +#define Z_IS_2473U_EQ_2473(...) \, +#define Z_IS_2473_EQ_2473U(...) \, +#define Z_IS_2473U_EQ_2473U(...) \, +#define Z_IS_2474_EQ_2474(...) \, +#define Z_IS_2474U_EQ_2474(...) \, +#define Z_IS_2474_EQ_2474U(...) \, +#define Z_IS_2474U_EQ_2474U(...) \, +#define Z_IS_2475_EQ_2475(...) \, +#define Z_IS_2475U_EQ_2475(...) \, +#define Z_IS_2475_EQ_2475U(...) \, +#define Z_IS_2475U_EQ_2475U(...) \, +#define Z_IS_2476_EQ_2476(...) \, +#define Z_IS_2476U_EQ_2476(...) \, +#define Z_IS_2476_EQ_2476U(...) \, +#define Z_IS_2476U_EQ_2476U(...) \, +#define Z_IS_2477_EQ_2477(...) \, +#define Z_IS_2477U_EQ_2477(...) \, +#define Z_IS_2477_EQ_2477U(...) \, +#define Z_IS_2477U_EQ_2477U(...) \, +#define Z_IS_2478_EQ_2478(...) \, +#define Z_IS_2478U_EQ_2478(...) \, +#define Z_IS_2478_EQ_2478U(...) \, +#define Z_IS_2478U_EQ_2478U(...) \, +#define Z_IS_2479_EQ_2479(...) \, +#define Z_IS_2479U_EQ_2479(...) \, +#define Z_IS_2479_EQ_2479U(...) \, +#define Z_IS_2479U_EQ_2479U(...) \, +#define Z_IS_2480_EQ_2480(...) \, +#define Z_IS_2480U_EQ_2480(...) \, +#define Z_IS_2480_EQ_2480U(...) \, +#define Z_IS_2480U_EQ_2480U(...) \, +#define Z_IS_2481_EQ_2481(...) \, +#define Z_IS_2481U_EQ_2481(...) \, +#define Z_IS_2481_EQ_2481U(...) \, +#define Z_IS_2481U_EQ_2481U(...) \, +#define Z_IS_2482_EQ_2482(...) \, +#define Z_IS_2482U_EQ_2482(...) \, +#define Z_IS_2482_EQ_2482U(...) \, +#define Z_IS_2482U_EQ_2482U(...) \, +#define Z_IS_2483_EQ_2483(...) \, +#define Z_IS_2483U_EQ_2483(...) \, +#define Z_IS_2483_EQ_2483U(...) \, +#define Z_IS_2483U_EQ_2483U(...) \, +#define Z_IS_2484_EQ_2484(...) \, +#define Z_IS_2484U_EQ_2484(...) \, +#define Z_IS_2484_EQ_2484U(...) \, +#define Z_IS_2484U_EQ_2484U(...) \, +#define Z_IS_2485_EQ_2485(...) \, +#define Z_IS_2485U_EQ_2485(...) \, +#define Z_IS_2485_EQ_2485U(...) \, +#define Z_IS_2485U_EQ_2485U(...) \, +#define Z_IS_2486_EQ_2486(...) \, +#define Z_IS_2486U_EQ_2486(...) \, +#define Z_IS_2486_EQ_2486U(...) \, +#define Z_IS_2486U_EQ_2486U(...) \, +#define Z_IS_2487_EQ_2487(...) \, +#define Z_IS_2487U_EQ_2487(...) \, +#define Z_IS_2487_EQ_2487U(...) \, +#define Z_IS_2487U_EQ_2487U(...) \, +#define Z_IS_2488_EQ_2488(...) \, +#define Z_IS_2488U_EQ_2488(...) \, +#define Z_IS_2488_EQ_2488U(...) \, +#define Z_IS_2488U_EQ_2488U(...) \, +#define Z_IS_2489_EQ_2489(...) \, +#define Z_IS_2489U_EQ_2489(...) \, +#define Z_IS_2489_EQ_2489U(...) \, +#define Z_IS_2489U_EQ_2489U(...) \, +#define Z_IS_2490_EQ_2490(...) \, +#define Z_IS_2490U_EQ_2490(...) \, +#define Z_IS_2490_EQ_2490U(...) \, +#define Z_IS_2490U_EQ_2490U(...) \, +#define Z_IS_2491_EQ_2491(...) \, +#define Z_IS_2491U_EQ_2491(...) \, +#define Z_IS_2491_EQ_2491U(...) \, +#define Z_IS_2491U_EQ_2491U(...) \, +#define Z_IS_2492_EQ_2492(...) \, +#define Z_IS_2492U_EQ_2492(...) \, +#define Z_IS_2492_EQ_2492U(...) \, +#define Z_IS_2492U_EQ_2492U(...) \, +#define Z_IS_2493_EQ_2493(...) \, +#define Z_IS_2493U_EQ_2493(...) \, +#define Z_IS_2493_EQ_2493U(...) \, +#define Z_IS_2493U_EQ_2493U(...) \, +#define Z_IS_2494_EQ_2494(...) \, +#define Z_IS_2494U_EQ_2494(...) \, +#define Z_IS_2494_EQ_2494U(...) \, +#define Z_IS_2494U_EQ_2494U(...) \, +#define Z_IS_2495_EQ_2495(...) \, +#define Z_IS_2495U_EQ_2495(...) \, +#define Z_IS_2495_EQ_2495U(...) \, +#define Z_IS_2495U_EQ_2495U(...) \, +#define Z_IS_2496_EQ_2496(...) \, +#define Z_IS_2496U_EQ_2496(...) \, +#define Z_IS_2496_EQ_2496U(...) \, +#define Z_IS_2496U_EQ_2496U(...) \, +#define Z_IS_2497_EQ_2497(...) \, +#define Z_IS_2497U_EQ_2497(...) \, +#define Z_IS_2497_EQ_2497U(...) \, +#define Z_IS_2497U_EQ_2497U(...) \, +#define Z_IS_2498_EQ_2498(...) \, +#define Z_IS_2498U_EQ_2498(...) \, +#define Z_IS_2498_EQ_2498U(...) \, +#define Z_IS_2498U_EQ_2498U(...) \, +#define Z_IS_2499_EQ_2499(...) \, +#define Z_IS_2499U_EQ_2499(...) \, +#define Z_IS_2499_EQ_2499U(...) \, +#define Z_IS_2499U_EQ_2499U(...) \, +#define Z_IS_2500_EQ_2500(...) \, +#define Z_IS_2500U_EQ_2500(...) \, +#define Z_IS_2500_EQ_2500U(...) \, +#define Z_IS_2500U_EQ_2500U(...) \, +#define Z_IS_2501_EQ_2501(...) \, +#define Z_IS_2501U_EQ_2501(...) \, +#define Z_IS_2501_EQ_2501U(...) \, +#define Z_IS_2501U_EQ_2501U(...) \, +#define Z_IS_2502_EQ_2502(...) \, +#define Z_IS_2502U_EQ_2502(...) \, +#define Z_IS_2502_EQ_2502U(...) \, +#define Z_IS_2502U_EQ_2502U(...) \, +#define Z_IS_2503_EQ_2503(...) \, +#define Z_IS_2503U_EQ_2503(...) \, +#define Z_IS_2503_EQ_2503U(...) \, +#define Z_IS_2503U_EQ_2503U(...) \, +#define Z_IS_2504_EQ_2504(...) \, +#define Z_IS_2504U_EQ_2504(...) \, +#define Z_IS_2504_EQ_2504U(...) \, +#define Z_IS_2504U_EQ_2504U(...) \, +#define Z_IS_2505_EQ_2505(...) \, +#define Z_IS_2505U_EQ_2505(...) \, +#define Z_IS_2505_EQ_2505U(...) \, +#define Z_IS_2505U_EQ_2505U(...) \, +#define Z_IS_2506_EQ_2506(...) \, +#define Z_IS_2506U_EQ_2506(...) \, +#define Z_IS_2506_EQ_2506U(...) \, +#define Z_IS_2506U_EQ_2506U(...) \, +#define Z_IS_2507_EQ_2507(...) \, +#define Z_IS_2507U_EQ_2507(...) \, +#define Z_IS_2507_EQ_2507U(...) \, +#define Z_IS_2507U_EQ_2507U(...) \, +#define Z_IS_2508_EQ_2508(...) \, +#define Z_IS_2508U_EQ_2508(...) \, +#define Z_IS_2508_EQ_2508U(...) \, +#define Z_IS_2508U_EQ_2508U(...) \, +#define Z_IS_2509_EQ_2509(...) \, +#define Z_IS_2509U_EQ_2509(...) \, +#define Z_IS_2509_EQ_2509U(...) \, +#define Z_IS_2509U_EQ_2509U(...) \, +#define Z_IS_2510_EQ_2510(...) \, +#define Z_IS_2510U_EQ_2510(...) \, +#define Z_IS_2510_EQ_2510U(...) \, +#define Z_IS_2510U_EQ_2510U(...) \, +#define Z_IS_2511_EQ_2511(...) \, +#define Z_IS_2511U_EQ_2511(...) \, +#define Z_IS_2511_EQ_2511U(...) \, +#define Z_IS_2511U_EQ_2511U(...) \, +#define Z_IS_2512_EQ_2512(...) \, +#define Z_IS_2512U_EQ_2512(...) \, +#define Z_IS_2512_EQ_2512U(...) \, +#define Z_IS_2512U_EQ_2512U(...) \, +#define Z_IS_2513_EQ_2513(...) \, +#define Z_IS_2513U_EQ_2513(...) \, +#define Z_IS_2513_EQ_2513U(...) \, +#define Z_IS_2513U_EQ_2513U(...) \, +#define Z_IS_2514_EQ_2514(...) \, +#define Z_IS_2514U_EQ_2514(...) \, +#define Z_IS_2514_EQ_2514U(...) \, +#define Z_IS_2514U_EQ_2514U(...) \, +#define Z_IS_2515_EQ_2515(...) \, +#define Z_IS_2515U_EQ_2515(...) \, +#define Z_IS_2515_EQ_2515U(...) \, +#define Z_IS_2515U_EQ_2515U(...) \, +#define Z_IS_2516_EQ_2516(...) \, +#define Z_IS_2516U_EQ_2516(...) \, +#define Z_IS_2516_EQ_2516U(...) \, +#define Z_IS_2516U_EQ_2516U(...) \, +#define Z_IS_2517_EQ_2517(...) \, +#define Z_IS_2517U_EQ_2517(...) \, +#define Z_IS_2517_EQ_2517U(...) \, +#define Z_IS_2517U_EQ_2517U(...) \, +#define Z_IS_2518_EQ_2518(...) \, +#define Z_IS_2518U_EQ_2518(...) \, +#define Z_IS_2518_EQ_2518U(...) \, +#define Z_IS_2518U_EQ_2518U(...) \, +#define Z_IS_2519_EQ_2519(...) \, +#define Z_IS_2519U_EQ_2519(...) \, +#define Z_IS_2519_EQ_2519U(...) \, +#define Z_IS_2519U_EQ_2519U(...) \, +#define Z_IS_2520_EQ_2520(...) \, +#define Z_IS_2520U_EQ_2520(...) \, +#define Z_IS_2520_EQ_2520U(...) \, +#define Z_IS_2520U_EQ_2520U(...) \, +#define Z_IS_2521_EQ_2521(...) \, +#define Z_IS_2521U_EQ_2521(...) \, +#define Z_IS_2521_EQ_2521U(...) \, +#define Z_IS_2521U_EQ_2521U(...) \, +#define Z_IS_2522_EQ_2522(...) \, +#define Z_IS_2522U_EQ_2522(...) \, +#define Z_IS_2522_EQ_2522U(...) \, +#define Z_IS_2522U_EQ_2522U(...) \, +#define Z_IS_2523_EQ_2523(...) \, +#define Z_IS_2523U_EQ_2523(...) \, +#define Z_IS_2523_EQ_2523U(...) \, +#define Z_IS_2523U_EQ_2523U(...) \, +#define Z_IS_2524_EQ_2524(...) \, +#define Z_IS_2524U_EQ_2524(...) \, +#define Z_IS_2524_EQ_2524U(...) \, +#define Z_IS_2524U_EQ_2524U(...) \, +#define Z_IS_2525_EQ_2525(...) \, +#define Z_IS_2525U_EQ_2525(...) \, +#define Z_IS_2525_EQ_2525U(...) \, +#define Z_IS_2525U_EQ_2525U(...) \, +#define Z_IS_2526_EQ_2526(...) \, +#define Z_IS_2526U_EQ_2526(...) \, +#define Z_IS_2526_EQ_2526U(...) \, +#define Z_IS_2526U_EQ_2526U(...) \, +#define Z_IS_2527_EQ_2527(...) \, +#define Z_IS_2527U_EQ_2527(...) \, +#define Z_IS_2527_EQ_2527U(...) \, +#define Z_IS_2527U_EQ_2527U(...) \, +#define Z_IS_2528_EQ_2528(...) \, +#define Z_IS_2528U_EQ_2528(...) \, +#define Z_IS_2528_EQ_2528U(...) \, +#define Z_IS_2528U_EQ_2528U(...) \, +#define Z_IS_2529_EQ_2529(...) \, +#define Z_IS_2529U_EQ_2529(...) \, +#define Z_IS_2529_EQ_2529U(...) \, +#define Z_IS_2529U_EQ_2529U(...) \, +#define Z_IS_2530_EQ_2530(...) \, +#define Z_IS_2530U_EQ_2530(...) \, +#define Z_IS_2530_EQ_2530U(...) \, +#define Z_IS_2530U_EQ_2530U(...) \, +#define Z_IS_2531_EQ_2531(...) \, +#define Z_IS_2531U_EQ_2531(...) \, +#define Z_IS_2531_EQ_2531U(...) \, +#define Z_IS_2531U_EQ_2531U(...) \, +#define Z_IS_2532_EQ_2532(...) \, +#define Z_IS_2532U_EQ_2532(...) \, +#define Z_IS_2532_EQ_2532U(...) \, +#define Z_IS_2532U_EQ_2532U(...) \, +#define Z_IS_2533_EQ_2533(...) \, +#define Z_IS_2533U_EQ_2533(...) \, +#define Z_IS_2533_EQ_2533U(...) \, +#define Z_IS_2533U_EQ_2533U(...) \, +#define Z_IS_2534_EQ_2534(...) \, +#define Z_IS_2534U_EQ_2534(...) \, +#define Z_IS_2534_EQ_2534U(...) \, +#define Z_IS_2534U_EQ_2534U(...) \, +#define Z_IS_2535_EQ_2535(...) \, +#define Z_IS_2535U_EQ_2535(...) \, +#define Z_IS_2535_EQ_2535U(...) \, +#define Z_IS_2535U_EQ_2535U(...) \, +#define Z_IS_2536_EQ_2536(...) \, +#define Z_IS_2536U_EQ_2536(...) \, +#define Z_IS_2536_EQ_2536U(...) \, +#define Z_IS_2536U_EQ_2536U(...) \, +#define Z_IS_2537_EQ_2537(...) \, +#define Z_IS_2537U_EQ_2537(...) \, +#define Z_IS_2537_EQ_2537U(...) \, +#define Z_IS_2537U_EQ_2537U(...) \, +#define Z_IS_2538_EQ_2538(...) \, +#define Z_IS_2538U_EQ_2538(...) \, +#define Z_IS_2538_EQ_2538U(...) \, +#define Z_IS_2538U_EQ_2538U(...) \, +#define Z_IS_2539_EQ_2539(...) \, +#define Z_IS_2539U_EQ_2539(...) \, +#define Z_IS_2539_EQ_2539U(...) \, +#define Z_IS_2539U_EQ_2539U(...) \, +#define Z_IS_2540_EQ_2540(...) \, +#define Z_IS_2540U_EQ_2540(...) \, +#define Z_IS_2540_EQ_2540U(...) \, +#define Z_IS_2540U_EQ_2540U(...) \, +#define Z_IS_2541_EQ_2541(...) \, +#define Z_IS_2541U_EQ_2541(...) \, +#define Z_IS_2541_EQ_2541U(...) \, +#define Z_IS_2541U_EQ_2541U(...) \, +#define Z_IS_2542_EQ_2542(...) \, +#define Z_IS_2542U_EQ_2542(...) \, +#define Z_IS_2542_EQ_2542U(...) \, +#define Z_IS_2542U_EQ_2542U(...) \, +#define Z_IS_2543_EQ_2543(...) \, +#define Z_IS_2543U_EQ_2543(...) \, +#define Z_IS_2543_EQ_2543U(...) \, +#define Z_IS_2543U_EQ_2543U(...) \, +#define Z_IS_2544_EQ_2544(...) \, +#define Z_IS_2544U_EQ_2544(...) \, +#define Z_IS_2544_EQ_2544U(...) \, +#define Z_IS_2544U_EQ_2544U(...) \, +#define Z_IS_2545_EQ_2545(...) \, +#define Z_IS_2545U_EQ_2545(...) \, +#define Z_IS_2545_EQ_2545U(...) \, +#define Z_IS_2545U_EQ_2545U(...) \, +#define Z_IS_2546_EQ_2546(...) \, +#define Z_IS_2546U_EQ_2546(...) \, +#define Z_IS_2546_EQ_2546U(...) \, +#define Z_IS_2546U_EQ_2546U(...) \, +#define Z_IS_2547_EQ_2547(...) \, +#define Z_IS_2547U_EQ_2547(...) \, +#define Z_IS_2547_EQ_2547U(...) \, +#define Z_IS_2547U_EQ_2547U(...) \, +#define Z_IS_2548_EQ_2548(...) \, +#define Z_IS_2548U_EQ_2548(...) \, +#define Z_IS_2548_EQ_2548U(...) \, +#define Z_IS_2548U_EQ_2548U(...) \, +#define Z_IS_2549_EQ_2549(...) \, +#define Z_IS_2549U_EQ_2549(...) \, +#define Z_IS_2549_EQ_2549U(...) \, +#define Z_IS_2549U_EQ_2549U(...) \, +#define Z_IS_2550_EQ_2550(...) \, +#define Z_IS_2550U_EQ_2550(...) \, +#define Z_IS_2550_EQ_2550U(...) \, +#define Z_IS_2550U_EQ_2550U(...) \, +#define Z_IS_2551_EQ_2551(...) \, +#define Z_IS_2551U_EQ_2551(...) \, +#define Z_IS_2551_EQ_2551U(...) \, +#define Z_IS_2551U_EQ_2551U(...) \, +#define Z_IS_2552_EQ_2552(...) \, +#define Z_IS_2552U_EQ_2552(...) \, +#define Z_IS_2552_EQ_2552U(...) \, +#define Z_IS_2552U_EQ_2552U(...) \, +#define Z_IS_2553_EQ_2553(...) \, +#define Z_IS_2553U_EQ_2553(...) \, +#define Z_IS_2553_EQ_2553U(...) \, +#define Z_IS_2553U_EQ_2553U(...) \, +#define Z_IS_2554_EQ_2554(...) \, +#define Z_IS_2554U_EQ_2554(...) \, +#define Z_IS_2554_EQ_2554U(...) \, +#define Z_IS_2554U_EQ_2554U(...) \, +#define Z_IS_2555_EQ_2555(...) \, +#define Z_IS_2555U_EQ_2555(...) \, +#define Z_IS_2555_EQ_2555U(...) \, +#define Z_IS_2555U_EQ_2555U(...) \, +#define Z_IS_2556_EQ_2556(...) \, +#define Z_IS_2556U_EQ_2556(...) \, +#define Z_IS_2556_EQ_2556U(...) \, +#define Z_IS_2556U_EQ_2556U(...) \, +#define Z_IS_2557_EQ_2557(...) \, +#define Z_IS_2557U_EQ_2557(...) \, +#define Z_IS_2557_EQ_2557U(...) \, +#define Z_IS_2557U_EQ_2557U(...) \, +#define Z_IS_2558_EQ_2558(...) \, +#define Z_IS_2558U_EQ_2558(...) \, +#define Z_IS_2558_EQ_2558U(...) \, +#define Z_IS_2558U_EQ_2558U(...) \, +#define Z_IS_2559_EQ_2559(...) \, +#define Z_IS_2559U_EQ_2559(...) \, +#define Z_IS_2559_EQ_2559U(...) \, +#define Z_IS_2559U_EQ_2559U(...) \, +#define Z_IS_2560_EQ_2560(...) \, +#define Z_IS_2560U_EQ_2560(...) \, +#define Z_IS_2560_EQ_2560U(...) \, +#define Z_IS_2560U_EQ_2560U(...) \, +#define Z_IS_2561_EQ_2561(...) \, +#define Z_IS_2561U_EQ_2561(...) \, +#define Z_IS_2561_EQ_2561U(...) \, +#define Z_IS_2561U_EQ_2561U(...) \, +#define Z_IS_2562_EQ_2562(...) \, +#define Z_IS_2562U_EQ_2562(...) \, +#define Z_IS_2562_EQ_2562U(...) \, +#define Z_IS_2562U_EQ_2562U(...) \, +#define Z_IS_2563_EQ_2563(...) \, +#define Z_IS_2563U_EQ_2563(...) \, +#define Z_IS_2563_EQ_2563U(...) \, +#define Z_IS_2563U_EQ_2563U(...) \, +#define Z_IS_2564_EQ_2564(...) \, +#define Z_IS_2564U_EQ_2564(...) \, +#define Z_IS_2564_EQ_2564U(...) \, +#define Z_IS_2564U_EQ_2564U(...) \, +#define Z_IS_2565_EQ_2565(...) \, +#define Z_IS_2565U_EQ_2565(...) \, +#define Z_IS_2565_EQ_2565U(...) \, +#define Z_IS_2565U_EQ_2565U(...) \, +#define Z_IS_2566_EQ_2566(...) \, +#define Z_IS_2566U_EQ_2566(...) \, +#define Z_IS_2566_EQ_2566U(...) \, +#define Z_IS_2566U_EQ_2566U(...) \, +#define Z_IS_2567_EQ_2567(...) \, +#define Z_IS_2567U_EQ_2567(...) \, +#define Z_IS_2567_EQ_2567U(...) \, +#define Z_IS_2567U_EQ_2567U(...) \, +#define Z_IS_2568_EQ_2568(...) \, +#define Z_IS_2568U_EQ_2568(...) \, +#define Z_IS_2568_EQ_2568U(...) \, +#define Z_IS_2568U_EQ_2568U(...) \, +#define Z_IS_2569_EQ_2569(...) \, +#define Z_IS_2569U_EQ_2569(...) \, +#define Z_IS_2569_EQ_2569U(...) \, +#define Z_IS_2569U_EQ_2569U(...) \, +#define Z_IS_2570_EQ_2570(...) \, +#define Z_IS_2570U_EQ_2570(...) \, +#define Z_IS_2570_EQ_2570U(...) \, +#define Z_IS_2570U_EQ_2570U(...) \, +#define Z_IS_2571_EQ_2571(...) \, +#define Z_IS_2571U_EQ_2571(...) \, +#define Z_IS_2571_EQ_2571U(...) \, +#define Z_IS_2571U_EQ_2571U(...) \, +#define Z_IS_2572_EQ_2572(...) \, +#define Z_IS_2572U_EQ_2572(...) \, +#define Z_IS_2572_EQ_2572U(...) \, +#define Z_IS_2572U_EQ_2572U(...) \, +#define Z_IS_2573_EQ_2573(...) \, +#define Z_IS_2573U_EQ_2573(...) \, +#define Z_IS_2573_EQ_2573U(...) \, +#define Z_IS_2573U_EQ_2573U(...) \, +#define Z_IS_2574_EQ_2574(...) \, +#define Z_IS_2574U_EQ_2574(...) \, +#define Z_IS_2574_EQ_2574U(...) \, +#define Z_IS_2574U_EQ_2574U(...) \, +#define Z_IS_2575_EQ_2575(...) \, +#define Z_IS_2575U_EQ_2575(...) \, +#define Z_IS_2575_EQ_2575U(...) \, +#define Z_IS_2575U_EQ_2575U(...) \, +#define Z_IS_2576_EQ_2576(...) \, +#define Z_IS_2576U_EQ_2576(...) \, +#define Z_IS_2576_EQ_2576U(...) \, +#define Z_IS_2576U_EQ_2576U(...) \, +#define Z_IS_2577_EQ_2577(...) \, +#define Z_IS_2577U_EQ_2577(...) \, +#define Z_IS_2577_EQ_2577U(...) \, +#define Z_IS_2577U_EQ_2577U(...) \, +#define Z_IS_2578_EQ_2578(...) \, +#define Z_IS_2578U_EQ_2578(...) \, +#define Z_IS_2578_EQ_2578U(...) \, +#define Z_IS_2578U_EQ_2578U(...) \, +#define Z_IS_2579_EQ_2579(...) \, +#define Z_IS_2579U_EQ_2579(...) \, +#define Z_IS_2579_EQ_2579U(...) \, +#define Z_IS_2579U_EQ_2579U(...) \, +#define Z_IS_2580_EQ_2580(...) \, +#define Z_IS_2580U_EQ_2580(...) \, +#define Z_IS_2580_EQ_2580U(...) \, +#define Z_IS_2580U_EQ_2580U(...) \, +#define Z_IS_2581_EQ_2581(...) \, +#define Z_IS_2581U_EQ_2581(...) \, +#define Z_IS_2581_EQ_2581U(...) \, +#define Z_IS_2581U_EQ_2581U(...) \, +#define Z_IS_2582_EQ_2582(...) \, +#define Z_IS_2582U_EQ_2582(...) \, +#define Z_IS_2582_EQ_2582U(...) \, +#define Z_IS_2582U_EQ_2582U(...) \, +#define Z_IS_2583_EQ_2583(...) \, +#define Z_IS_2583U_EQ_2583(...) \, +#define Z_IS_2583_EQ_2583U(...) \, +#define Z_IS_2583U_EQ_2583U(...) \, +#define Z_IS_2584_EQ_2584(...) \, +#define Z_IS_2584U_EQ_2584(...) \, +#define Z_IS_2584_EQ_2584U(...) \, +#define Z_IS_2584U_EQ_2584U(...) \, +#define Z_IS_2585_EQ_2585(...) \, +#define Z_IS_2585U_EQ_2585(...) \, +#define Z_IS_2585_EQ_2585U(...) \, +#define Z_IS_2585U_EQ_2585U(...) \, +#define Z_IS_2586_EQ_2586(...) \, +#define Z_IS_2586U_EQ_2586(...) \, +#define Z_IS_2586_EQ_2586U(...) \, +#define Z_IS_2586U_EQ_2586U(...) \, +#define Z_IS_2587_EQ_2587(...) \, +#define Z_IS_2587U_EQ_2587(...) \, +#define Z_IS_2587_EQ_2587U(...) \, +#define Z_IS_2587U_EQ_2587U(...) \, +#define Z_IS_2588_EQ_2588(...) \, +#define Z_IS_2588U_EQ_2588(...) \, +#define Z_IS_2588_EQ_2588U(...) \, +#define Z_IS_2588U_EQ_2588U(...) \, +#define Z_IS_2589_EQ_2589(...) \, +#define Z_IS_2589U_EQ_2589(...) \, +#define Z_IS_2589_EQ_2589U(...) \, +#define Z_IS_2589U_EQ_2589U(...) \, +#define Z_IS_2590_EQ_2590(...) \, +#define Z_IS_2590U_EQ_2590(...) \, +#define Z_IS_2590_EQ_2590U(...) \, +#define Z_IS_2590U_EQ_2590U(...) \, +#define Z_IS_2591_EQ_2591(...) \, +#define Z_IS_2591U_EQ_2591(...) \, +#define Z_IS_2591_EQ_2591U(...) \, +#define Z_IS_2591U_EQ_2591U(...) \, +#define Z_IS_2592_EQ_2592(...) \, +#define Z_IS_2592U_EQ_2592(...) \, +#define Z_IS_2592_EQ_2592U(...) \, +#define Z_IS_2592U_EQ_2592U(...) \, +#define Z_IS_2593_EQ_2593(...) \, +#define Z_IS_2593U_EQ_2593(...) \, +#define Z_IS_2593_EQ_2593U(...) \, +#define Z_IS_2593U_EQ_2593U(...) \, +#define Z_IS_2594_EQ_2594(...) \, +#define Z_IS_2594U_EQ_2594(...) \, +#define Z_IS_2594_EQ_2594U(...) \, +#define Z_IS_2594U_EQ_2594U(...) \, +#define Z_IS_2595_EQ_2595(...) \, +#define Z_IS_2595U_EQ_2595(...) \, +#define Z_IS_2595_EQ_2595U(...) \, +#define Z_IS_2595U_EQ_2595U(...) \, +#define Z_IS_2596_EQ_2596(...) \, +#define Z_IS_2596U_EQ_2596(...) \, +#define Z_IS_2596_EQ_2596U(...) \, +#define Z_IS_2596U_EQ_2596U(...) \, +#define Z_IS_2597_EQ_2597(...) \, +#define Z_IS_2597U_EQ_2597(...) \, +#define Z_IS_2597_EQ_2597U(...) \, +#define Z_IS_2597U_EQ_2597U(...) \, +#define Z_IS_2598_EQ_2598(...) \, +#define Z_IS_2598U_EQ_2598(...) \, +#define Z_IS_2598_EQ_2598U(...) \, +#define Z_IS_2598U_EQ_2598U(...) \, +#define Z_IS_2599_EQ_2599(...) \, +#define Z_IS_2599U_EQ_2599(...) \, +#define Z_IS_2599_EQ_2599U(...) \, +#define Z_IS_2599U_EQ_2599U(...) \, +#define Z_IS_2600_EQ_2600(...) \, +#define Z_IS_2600U_EQ_2600(...) \, +#define Z_IS_2600_EQ_2600U(...) \, +#define Z_IS_2600U_EQ_2600U(...) \, +#define Z_IS_2601_EQ_2601(...) \, +#define Z_IS_2601U_EQ_2601(...) \, +#define Z_IS_2601_EQ_2601U(...) \, +#define Z_IS_2601U_EQ_2601U(...) \, +#define Z_IS_2602_EQ_2602(...) \, +#define Z_IS_2602U_EQ_2602(...) \, +#define Z_IS_2602_EQ_2602U(...) \, +#define Z_IS_2602U_EQ_2602U(...) \, +#define Z_IS_2603_EQ_2603(...) \, +#define Z_IS_2603U_EQ_2603(...) \, +#define Z_IS_2603_EQ_2603U(...) \, +#define Z_IS_2603U_EQ_2603U(...) \, +#define Z_IS_2604_EQ_2604(...) \, +#define Z_IS_2604U_EQ_2604(...) \, +#define Z_IS_2604_EQ_2604U(...) \, +#define Z_IS_2604U_EQ_2604U(...) \, +#define Z_IS_2605_EQ_2605(...) \, +#define Z_IS_2605U_EQ_2605(...) \, +#define Z_IS_2605_EQ_2605U(...) \, +#define Z_IS_2605U_EQ_2605U(...) \, +#define Z_IS_2606_EQ_2606(...) \, +#define Z_IS_2606U_EQ_2606(...) \, +#define Z_IS_2606_EQ_2606U(...) \, +#define Z_IS_2606U_EQ_2606U(...) \, +#define Z_IS_2607_EQ_2607(...) \, +#define Z_IS_2607U_EQ_2607(...) \, +#define Z_IS_2607_EQ_2607U(...) \, +#define Z_IS_2607U_EQ_2607U(...) \, +#define Z_IS_2608_EQ_2608(...) \, +#define Z_IS_2608U_EQ_2608(...) \, +#define Z_IS_2608_EQ_2608U(...) \, +#define Z_IS_2608U_EQ_2608U(...) \, +#define Z_IS_2609_EQ_2609(...) \, +#define Z_IS_2609U_EQ_2609(...) \, +#define Z_IS_2609_EQ_2609U(...) \, +#define Z_IS_2609U_EQ_2609U(...) \, +#define Z_IS_2610_EQ_2610(...) \, +#define Z_IS_2610U_EQ_2610(...) \, +#define Z_IS_2610_EQ_2610U(...) \, +#define Z_IS_2610U_EQ_2610U(...) \, +#define Z_IS_2611_EQ_2611(...) \, +#define Z_IS_2611U_EQ_2611(...) \, +#define Z_IS_2611_EQ_2611U(...) \, +#define Z_IS_2611U_EQ_2611U(...) \, +#define Z_IS_2612_EQ_2612(...) \, +#define Z_IS_2612U_EQ_2612(...) \, +#define Z_IS_2612_EQ_2612U(...) \, +#define Z_IS_2612U_EQ_2612U(...) \, +#define Z_IS_2613_EQ_2613(...) \, +#define Z_IS_2613U_EQ_2613(...) \, +#define Z_IS_2613_EQ_2613U(...) \, +#define Z_IS_2613U_EQ_2613U(...) \, +#define Z_IS_2614_EQ_2614(...) \, +#define Z_IS_2614U_EQ_2614(...) \, +#define Z_IS_2614_EQ_2614U(...) \, +#define Z_IS_2614U_EQ_2614U(...) \, +#define Z_IS_2615_EQ_2615(...) \, +#define Z_IS_2615U_EQ_2615(...) \, +#define Z_IS_2615_EQ_2615U(...) \, +#define Z_IS_2615U_EQ_2615U(...) \, +#define Z_IS_2616_EQ_2616(...) \, +#define Z_IS_2616U_EQ_2616(...) \, +#define Z_IS_2616_EQ_2616U(...) \, +#define Z_IS_2616U_EQ_2616U(...) \, +#define Z_IS_2617_EQ_2617(...) \, +#define Z_IS_2617U_EQ_2617(...) \, +#define Z_IS_2617_EQ_2617U(...) \, +#define Z_IS_2617U_EQ_2617U(...) \, +#define Z_IS_2618_EQ_2618(...) \, +#define Z_IS_2618U_EQ_2618(...) \, +#define Z_IS_2618_EQ_2618U(...) \, +#define Z_IS_2618U_EQ_2618U(...) \, +#define Z_IS_2619_EQ_2619(...) \, +#define Z_IS_2619U_EQ_2619(...) \, +#define Z_IS_2619_EQ_2619U(...) \, +#define Z_IS_2619U_EQ_2619U(...) \, +#define Z_IS_2620_EQ_2620(...) \, +#define Z_IS_2620U_EQ_2620(...) \, +#define Z_IS_2620_EQ_2620U(...) \, +#define Z_IS_2620U_EQ_2620U(...) \, +#define Z_IS_2621_EQ_2621(...) \, +#define Z_IS_2621U_EQ_2621(...) \, +#define Z_IS_2621_EQ_2621U(...) \, +#define Z_IS_2621U_EQ_2621U(...) \, +#define Z_IS_2622_EQ_2622(...) \, +#define Z_IS_2622U_EQ_2622(...) \, +#define Z_IS_2622_EQ_2622U(...) \, +#define Z_IS_2622U_EQ_2622U(...) \, +#define Z_IS_2623_EQ_2623(...) \, +#define Z_IS_2623U_EQ_2623(...) \, +#define Z_IS_2623_EQ_2623U(...) \, +#define Z_IS_2623U_EQ_2623U(...) \, +#define Z_IS_2624_EQ_2624(...) \, +#define Z_IS_2624U_EQ_2624(...) \, +#define Z_IS_2624_EQ_2624U(...) \, +#define Z_IS_2624U_EQ_2624U(...) \, +#define Z_IS_2625_EQ_2625(...) \, +#define Z_IS_2625U_EQ_2625(...) \, +#define Z_IS_2625_EQ_2625U(...) \, +#define Z_IS_2625U_EQ_2625U(...) \, +#define Z_IS_2626_EQ_2626(...) \, +#define Z_IS_2626U_EQ_2626(...) \, +#define Z_IS_2626_EQ_2626U(...) \, +#define Z_IS_2626U_EQ_2626U(...) \, +#define Z_IS_2627_EQ_2627(...) \, +#define Z_IS_2627U_EQ_2627(...) \, +#define Z_IS_2627_EQ_2627U(...) \, +#define Z_IS_2627U_EQ_2627U(...) \, +#define Z_IS_2628_EQ_2628(...) \, +#define Z_IS_2628U_EQ_2628(...) \, +#define Z_IS_2628_EQ_2628U(...) \, +#define Z_IS_2628U_EQ_2628U(...) \, +#define Z_IS_2629_EQ_2629(...) \, +#define Z_IS_2629U_EQ_2629(...) \, +#define Z_IS_2629_EQ_2629U(...) \, +#define Z_IS_2629U_EQ_2629U(...) \, +#define Z_IS_2630_EQ_2630(...) \, +#define Z_IS_2630U_EQ_2630(...) \, +#define Z_IS_2630_EQ_2630U(...) \, +#define Z_IS_2630U_EQ_2630U(...) \, +#define Z_IS_2631_EQ_2631(...) \, +#define Z_IS_2631U_EQ_2631(...) \, +#define Z_IS_2631_EQ_2631U(...) \, +#define Z_IS_2631U_EQ_2631U(...) \, +#define Z_IS_2632_EQ_2632(...) \, +#define Z_IS_2632U_EQ_2632(...) \, +#define Z_IS_2632_EQ_2632U(...) \, +#define Z_IS_2632U_EQ_2632U(...) \, +#define Z_IS_2633_EQ_2633(...) \, +#define Z_IS_2633U_EQ_2633(...) \, +#define Z_IS_2633_EQ_2633U(...) \, +#define Z_IS_2633U_EQ_2633U(...) \, +#define Z_IS_2634_EQ_2634(...) \, +#define Z_IS_2634U_EQ_2634(...) \, +#define Z_IS_2634_EQ_2634U(...) \, +#define Z_IS_2634U_EQ_2634U(...) \, +#define Z_IS_2635_EQ_2635(...) \, +#define Z_IS_2635U_EQ_2635(...) \, +#define Z_IS_2635_EQ_2635U(...) \, +#define Z_IS_2635U_EQ_2635U(...) \, +#define Z_IS_2636_EQ_2636(...) \, +#define Z_IS_2636U_EQ_2636(...) \, +#define Z_IS_2636_EQ_2636U(...) \, +#define Z_IS_2636U_EQ_2636U(...) \, +#define Z_IS_2637_EQ_2637(...) \, +#define Z_IS_2637U_EQ_2637(...) \, +#define Z_IS_2637_EQ_2637U(...) \, +#define Z_IS_2637U_EQ_2637U(...) \, +#define Z_IS_2638_EQ_2638(...) \, +#define Z_IS_2638U_EQ_2638(...) \, +#define Z_IS_2638_EQ_2638U(...) \, +#define Z_IS_2638U_EQ_2638U(...) \, +#define Z_IS_2639_EQ_2639(...) \, +#define Z_IS_2639U_EQ_2639(...) \, +#define Z_IS_2639_EQ_2639U(...) \, +#define Z_IS_2639U_EQ_2639U(...) \, +#define Z_IS_2640_EQ_2640(...) \, +#define Z_IS_2640U_EQ_2640(...) \, +#define Z_IS_2640_EQ_2640U(...) \, +#define Z_IS_2640U_EQ_2640U(...) \, +#define Z_IS_2641_EQ_2641(...) \, +#define Z_IS_2641U_EQ_2641(...) \, +#define Z_IS_2641_EQ_2641U(...) \, +#define Z_IS_2641U_EQ_2641U(...) \, +#define Z_IS_2642_EQ_2642(...) \, +#define Z_IS_2642U_EQ_2642(...) \, +#define Z_IS_2642_EQ_2642U(...) \, +#define Z_IS_2642U_EQ_2642U(...) \, +#define Z_IS_2643_EQ_2643(...) \, +#define Z_IS_2643U_EQ_2643(...) \, +#define Z_IS_2643_EQ_2643U(...) \, +#define Z_IS_2643U_EQ_2643U(...) \, +#define Z_IS_2644_EQ_2644(...) \, +#define Z_IS_2644U_EQ_2644(...) \, +#define Z_IS_2644_EQ_2644U(...) \, +#define Z_IS_2644U_EQ_2644U(...) \, +#define Z_IS_2645_EQ_2645(...) \, +#define Z_IS_2645U_EQ_2645(...) \, +#define Z_IS_2645_EQ_2645U(...) \, +#define Z_IS_2645U_EQ_2645U(...) \, +#define Z_IS_2646_EQ_2646(...) \, +#define Z_IS_2646U_EQ_2646(...) \, +#define Z_IS_2646_EQ_2646U(...) \, +#define Z_IS_2646U_EQ_2646U(...) \, +#define Z_IS_2647_EQ_2647(...) \, +#define Z_IS_2647U_EQ_2647(...) \, +#define Z_IS_2647_EQ_2647U(...) \, +#define Z_IS_2647U_EQ_2647U(...) \, +#define Z_IS_2648_EQ_2648(...) \, +#define Z_IS_2648U_EQ_2648(...) \, +#define Z_IS_2648_EQ_2648U(...) \, +#define Z_IS_2648U_EQ_2648U(...) \, +#define Z_IS_2649_EQ_2649(...) \, +#define Z_IS_2649U_EQ_2649(...) \, +#define Z_IS_2649_EQ_2649U(...) \, +#define Z_IS_2649U_EQ_2649U(...) \, +#define Z_IS_2650_EQ_2650(...) \, +#define Z_IS_2650U_EQ_2650(...) \, +#define Z_IS_2650_EQ_2650U(...) \, +#define Z_IS_2650U_EQ_2650U(...) \, +#define Z_IS_2651_EQ_2651(...) \, +#define Z_IS_2651U_EQ_2651(...) \, +#define Z_IS_2651_EQ_2651U(...) \, +#define Z_IS_2651U_EQ_2651U(...) \, +#define Z_IS_2652_EQ_2652(...) \, +#define Z_IS_2652U_EQ_2652(...) \, +#define Z_IS_2652_EQ_2652U(...) \, +#define Z_IS_2652U_EQ_2652U(...) \, +#define Z_IS_2653_EQ_2653(...) \, +#define Z_IS_2653U_EQ_2653(...) \, +#define Z_IS_2653_EQ_2653U(...) \, +#define Z_IS_2653U_EQ_2653U(...) \, +#define Z_IS_2654_EQ_2654(...) \, +#define Z_IS_2654U_EQ_2654(...) \, +#define Z_IS_2654_EQ_2654U(...) \, +#define Z_IS_2654U_EQ_2654U(...) \, +#define Z_IS_2655_EQ_2655(...) \, +#define Z_IS_2655U_EQ_2655(...) \, +#define Z_IS_2655_EQ_2655U(...) \, +#define Z_IS_2655U_EQ_2655U(...) \, +#define Z_IS_2656_EQ_2656(...) \, +#define Z_IS_2656U_EQ_2656(...) \, +#define Z_IS_2656_EQ_2656U(...) \, +#define Z_IS_2656U_EQ_2656U(...) \, +#define Z_IS_2657_EQ_2657(...) \, +#define Z_IS_2657U_EQ_2657(...) \, +#define Z_IS_2657_EQ_2657U(...) \, +#define Z_IS_2657U_EQ_2657U(...) \, +#define Z_IS_2658_EQ_2658(...) \, +#define Z_IS_2658U_EQ_2658(...) \, +#define Z_IS_2658_EQ_2658U(...) \, +#define Z_IS_2658U_EQ_2658U(...) \, +#define Z_IS_2659_EQ_2659(...) \, +#define Z_IS_2659U_EQ_2659(...) \, +#define Z_IS_2659_EQ_2659U(...) \, +#define Z_IS_2659U_EQ_2659U(...) \, +#define Z_IS_2660_EQ_2660(...) \, +#define Z_IS_2660U_EQ_2660(...) \, +#define Z_IS_2660_EQ_2660U(...) \, +#define Z_IS_2660U_EQ_2660U(...) \, +#define Z_IS_2661_EQ_2661(...) \, +#define Z_IS_2661U_EQ_2661(...) \, +#define Z_IS_2661_EQ_2661U(...) \, +#define Z_IS_2661U_EQ_2661U(...) \, +#define Z_IS_2662_EQ_2662(...) \, +#define Z_IS_2662U_EQ_2662(...) \, +#define Z_IS_2662_EQ_2662U(...) \, +#define Z_IS_2662U_EQ_2662U(...) \, +#define Z_IS_2663_EQ_2663(...) \, +#define Z_IS_2663U_EQ_2663(...) \, +#define Z_IS_2663_EQ_2663U(...) \, +#define Z_IS_2663U_EQ_2663U(...) \, +#define Z_IS_2664_EQ_2664(...) \, +#define Z_IS_2664U_EQ_2664(...) \, +#define Z_IS_2664_EQ_2664U(...) \, +#define Z_IS_2664U_EQ_2664U(...) \, +#define Z_IS_2665_EQ_2665(...) \, +#define Z_IS_2665U_EQ_2665(...) \, +#define Z_IS_2665_EQ_2665U(...) \, +#define Z_IS_2665U_EQ_2665U(...) \, +#define Z_IS_2666_EQ_2666(...) \, +#define Z_IS_2666U_EQ_2666(...) \, +#define Z_IS_2666_EQ_2666U(...) \, +#define Z_IS_2666U_EQ_2666U(...) \, +#define Z_IS_2667_EQ_2667(...) \, +#define Z_IS_2667U_EQ_2667(...) \, +#define Z_IS_2667_EQ_2667U(...) \, +#define Z_IS_2667U_EQ_2667U(...) \, +#define Z_IS_2668_EQ_2668(...) \, +#define Z_IS_2668U_EQ_2668(...) \, +#define Z_IS_2668_EQ_2668U(...) \, +#define Z_IS_2668U_EQ_2668U(...) \, +#define Z_IS_2669_EQ_2669(...) \, +#define Z_IS_2669U_EQ_2669(...) \, +#define Z_IS_2669_EQ_2669U(...) \, +#define Z_IS_2669U_EQ_2669U(...) \, +#define Z_IS_2670_EQ_2670(...) \, +#define Z_IS_2670U_EQ_2670(...) \, +#define Z_IS_2670_EQ_2670U(...) \, +#define Z_IS_2670U_EQ_2670U(...) \, +#define Z_IS_2671_EQ_2671(...) \, +#define Z_IS_2671U_EQ_2671(...) \, +#define Z_IS_2671_EQ_2671U(...) \, +#define Z_IS_2671U_EQ_2671U(...) \, +#define Z_IS_2672_EQ_2672(...) \, +#define Z_IS_2672U_EQ_2672(...) \, +#define Z_IS_2672_EQ_2672U(...) \, +#define Z_IS_2672U_EQ_2672U(...) \, +#define Z_IS_2673_EQ_2673(...) \, +#define Z_IS_2673U_EQ_2673(...) \, +#define Z_IS_2673_EQ_2673U(...) \, +#define Z_IS_2673U_EQ_2673U(...) \, +#define Z_IS_2674_EQ_2674(...) \, +#define Z_IS_2674U_EQ_2674(...) \, +#define Z_IS_2674_EQ_2674U(...) \, +#define Z_IS_2674U_EQ_2674U(...) \, +#define Z_IS_2675_EQ_2675(...) \, +#define Z_IS_2675U_EQ_2675(...) \, +#define Z_IS_2675_EQ_2675U(...) \, +#define Z_IS_2675U_EQ_2675U(...) \, +#define Z_IS_2676_EQ_2676(...) \, +#define Z_IS_2676U_EQ_2676(...) \, +#define Z_IS_2676_EQ_2676U(...) \, +#define Z_IS_2676U_EQ_2676U(...) \, +#define Z_IS_2677_EQ_2677(...) \, +#define Z_IS_2677U_EQ_2677(...) \, +#define Z_IS_2677_EQ_2677U(...) \, +#define Z_IS_2677U_EQ_2677U(...) \, +#define Z_IS_2678_EQ_2678(...) \, +#define Z_IS_2678U_EQ_2678(...) \, +#define Z_IS_2678_EQ_2678U(...) \, +#define Z_IS_2678U_EQ_2678U(...) \, +#define Z_IS_2679_EQ_2679(...) \, +#define Z_IS_2679U_EQ_2679(...) \, +#define Z_IS_2679_EQ_2679U(...) \, +#define Z_IS_2679U_EQ_2679U(...) \, +#define Z_IS_2680_EQ_2680(...) \, +#define Z_IS_2680U_EQ_2680(...) \, +#define Z_IS_2680_EQ_2680U(...) \, +#define Z_IS_2680U_EQ_2680U(...) \, +#define Z_IS_2681_EQ_2681(...) \, +#define Z_IS_2681U_EQ_2681(...) \, +#define Z_IS_2681_EQ_2681U(...) \, +#define Z_IS_2681U_EQ_2681U(...) \, +#define Z_IS_2682_EQ_2682(...) \, +#define Z_IS_2682U_EQ_2682(...) \, +#define Z_IS_2682_EQ_2682U(...) \, +#define Z_IS_2682U_EQ_2682U(...) \, +#define Z_IS_2683_EQ_2683(...) \, +#define Z_IS_2683U_EQ_2683(...) \, +#define Z_IS_2683_EQ_2683U(...) \, +#define Z_IS_2683U_EQ_2683U(...) \, +#define Z_IS_2684_EQ_2684(...) \, +#define Z_IS_2684U_EQ_2684(...) \, +#define Z_IS_2684_EQ_2684U(...) \, +#define Z_IS_2684U_EQ_2684U(...) \, +#define Z_IS_2685_EQ_2685(...) \, +#define Z_IS_2685U_EQ_2685(...) \, +#define Z_IS_2685_EQ_2685U(...) \, +#define Z_IS_2685U_EQ_2685U(...) \, +#define Z_IS_2686_EQ_2686(...) \, +#define Z_IS_2686U_EQ_2686(...) \, +#define Z_IS_2686_EQ_2686U(...) \, +#define Z_IS_2686U_EQ_2686U(...) \, +#define Z_IS_2687_EQ_2687(...) \, +#define Z_IS_2687U_EQ_2687(...) \, +#define Z_IS_2687_EQ_2687U(...) \, +#define Z_IS_2687U_EQ_2687U(...) \, +#define Z_IS_2688_EQ_2688(...) \, +#define Z_IS_2688U_EQ_2688(...) \, +#define Z_IS_2688_EQ_2688U(...) \, +#define Z_IS_2688U_EQ_2688U(...) \, +#define Z_IS_2689_EQ_2689(...) \, +#define Z_IS_2689U_EQ_2689(...) \, +#define Z_IS_2689_EQ_2689U(...) \, +#define Z_IS_2689U_EQ_2689U(...) \, +#define Z_IS_2690_EQ_2690(...) \, +#define Z_IS_2690U_EQ_2690(...) \, +#define Z_IS_2690_EQ_2690U(...) \, +#define Z_IS_2690U_EQ_2690U(...) \, +#define Z_IS_2691_EQ_2691(...) \, +#define Z_IS_2691U_EQ_2691(...) \, +#define Z_IS_2691_EQ_2691U(...) \, +#define Z_IS_2691U_EQ_2691U(...) \, +#define Z_IS_2692_EQ_2692(...) \, +#define Z_IS_2692U_EQ_2692(...) \, +#define Z_IS_2692_EQ_2692U(...) \, +#define Z_IS_2692U_EQ_2692U(...) \, +#define Z_IS_2693_EQ_2693(...) \, +#define Z_IS_2693U_EQ_2693(...) \, +#define Z_IS_2693_EQ_2693U(...) \, +#define Z_IS_2693U_EQ_2693U(...) \, +#define Z_IS_2694_EQ_2694(...) \, +#define Z_IS_2694U_EQ_2694(...) \, +#define Z_IS_2694_EQ_2694U(...) \, +#define Z_IS_2694U_EQ_2694U(...) \, +#define Z_IS_2695_EQ_2695(...) \, +#define Z_IS_2695U_EQ_2695(...) \, +#define Z_IS_2695_EQ_2695U(...) \, +#define Z_IS_2695U_EQ_2695U(...) \, +#define Z_IS_2696_EQ_2696(...) \, +#define Z_IS_2696U_EQ_2696(...) \, +#define Z_IS_2696_EQ_2696U(...) \, +#define Z_IS_2696U_EQ_2696U(...) \, +#define Z_IS_2697_EQ_2697(...) \, +#define Z_IS_2697U_EQ_2697(...) \, +#define Z_IS_2697_EQ_2697U(...) \, +#define Z_IS_2697U_EQ_2697U(...) \, +#define Z_IS_2698_EQ_2698(...) \, +#define Z_IS_2698U_EQ_2698(...) \, +#define Z_IS_2698_EQ_2698U(...) \, +#define Z_IS_2698U_EQ_2698U(...) \, +#define Z_IS_2699_EQ_2699(...) \, +#define Z_IS_2699U_EQ_2699(...) \, +#define Z_IS_2699_EQ_2699U(...) \, +#define Z_IS_2699U_EQ_2699U(...) \, +#define Z_IS_2700_EQ_2700(...) \, +#define Z_IS_2700U_EQ_2700(...) \, +#define Z_IS_2700_EQ_2700U(...) \, +#define Z_IS_2700U_EQ_2700U(...) \, +#define Z_IS_2701_EQ_2701(...) \, +#define Z_IS_2701U_EQ_2701(...) \, +#define Z_IS_2701_EQ_2701U(...) \, +#define Z_IS_2701U_EQ_2701U(...) \, +#define Z_IS_2702_EQ_2702(...) \, +#define Z_IS_2702U_EQ_2702(...) \, +#define Z_IS_2702_EQ_2702U(...) \, +#define Z_IS_2702U_EQ_2702U(...) \, +#define Z_IS_2703_EQ_2703(...) \, +#define Z_IS_2703U_EQ_2703(...) \, +#define Z_IS_2703_EQ_2703U(...) \, +#define Z_IS_2703U_EQ_2703U(...) \, +#define Z_IS_2704_EQ_2704(...) \, +#define Z_IS_2704U_EQ_2704(...) \, +#define Z_IS_2704_EQ_2704U(...) \, +#define Z_IS_2704U_EQ_2704U(...) \, +#define Z_IS_2705_EQ_2705(...) \, +#define Z_IS_2705U_EQ_2705(...) \, +#define Z_IS_2705_EQ_2705U(...) \, +#define Z_IS_2705U_EQ_2705U(...) \, +#define Z_IS_2706_EQ_2706(...) \, +#define Z_IS_2706U_EQ_2706(...) \, +#define Z_IS_2706_EQ_2706U(...) \, +#define Z_IS_2706U_EQ_2706U(...) \, +#define Z_IS_2707_EQ_2707(...) \, +#define Z_IS_2707U_EQ_2707(...) \, +#define Z_IS_2707_EQ_2707U(...) \, +#define Z_IS_2707U_EQ_2707U(...) \, +#define Z_IS_2708_EQ_2708(...) \, +#define Z_IS_2708U_EQ_2708(...) \, +#define Z_IS_2708_EQ_2708U(...) \, +#define Z_IS_2708U_EQ_2708U(...) \, +#define Z_IS_2709_EQ_2709(...) \, +#define Z_IS_2709U_EQ_2709(...) \, +#define Z_IS_2709_EQ_2709U(...) \, +#define Z_IS_2709U_EQ_2709U(...) \, +#define Z_IS_2710_EQ_2710(...) \, +#define Z_IS_2710U_EQ_2710(...) \, +#define Z_IS_2710_EQ_2710U(...) \, +#define Z_IS_2710U_EQ_2710U(...) \, +#define Z_IS_2711_EQ_2711(...) \, +#define Z_IS_2711U_EQ_2711(...) \, +#define Z_IS_2711_EQ_2711U(...) \, +#define Z_IS_2711U_EQ_2711U(...) \, +#define Z_IS_2712_EQ_2712(...) \, +#define Z_IS_2712U_EQ_2712(...) \, +#define Z_IS_2712_EQ_2712U(...) \, +#define Z_IS_2712U_EQ_2712U(...) \, +#define Z_IS_2713_EQ_2713(...) \, +#define Z_IS_2713U_EQ_2713(...) \, +#define Z_IS_2713_EQ_2713U(...) \, +#define Z_IS_2713U_EQ_2713U(...) \, +#define Z_IS_2714_EQ_2714(...) \, +#define Z_IS_2714U_EQ_2714(...) \, +#define Z_IS_2714_EQ_2714U(...) \, +#define Z_IS_2714U_EQ_2714U(...) \, +#define Z_IS_2715_EQ_2715(...) \, +#define Z_IS_2715U_EQ_2715(...) \, +#define Z_IS_2715_EQ_2715U(...) \, +#define Z_IS_2715U_EQ_2715U(...) \, +#define Z_IS_2716_EQ_2716(...) \, +#define Z_IS_2716U_EQ_2716(...) \, +#define Z_IS_2716_EQ_2716U(...) \, +#define Z_IS_2716U_EQ_2716U(...) \, +#define Z_IS_2717_EQ_2717(...) \, +#define Z_IS_2717U_EQ_2717(...) \, +#define Z_IS_2717_EQ_2717U(...) \, +#define Z_IS_2717U_EQ_2717U(...) \, +#define Z_IS_2718_EQ_2718(...) \, +#define Z_IS_2718U_EQ_2718(...) \, +#define Z_IS_2718_EQ_2718U(...) \, +#define Z_IS_2718U_EQ_2718U(...) \, +#define Z_IS_2719_EQ_2719(...) \, +#define Z_IS_2719U_EQ_2719(...) \, +#define Z_IS_2719_EQ_2719U(...) \, +#define Z_IS_2719U_EQ_2719U(...) \, +#define Z_IS_2720_EQ_2720(...) \, +#define Z_IS_2720U_EQ_2720(...) \, +#define Z_IS_2720_EQ_2720U(...) \, +#define Z_IS_2720U_EQ_2720U(...) \, +#define Z_IS_2721_EQ_2721(...) \, +#define Z_IS_2721U_EQ_2721(...) \, +#define Z_IS_2721_EQ_2721U(...) \, +#define Z_IS_2721U_EQ_2721U(...) \, +#define Z_IS_2722_EQ_2722(...) \, +#define Z_IS_2722U_EQ_2722(...) \, +#define Z_IS_2722_EQ_2722U(...) \, +#define Z_IS_2722U_EQ_2722U(...) \, +#define Z_IS_2723_EQ_2723(...) \, +#define Z_IS_2723U_EQ_2723(...) \, +#define Z_IS_2723_EQ_2723U(...) \, +#define Z_IS_2723U_EQ_2723U(...) \, +#define Z_IS_2724_EQ_2724(...) \, +#define Z_IS_2724U_EQ_2724(...) \, +#define Z_IS_2724_EQ_2724U(...) \, +#define Z_IS_2724U_EQ_2724U(...) \, +#define Z_IS_2725_EQ_2725(...) \, +#define Z_IS_2725U_EQ_2725(...) \, +#define Z_IS_2725_EQ_2725U(...) \, +#define Z_IS_2725U_EQ_2725U(...) \, +#define Z_IS_2726_EQ_2726(...) \, +#define Z_IS_2726U_EQ_2726(...) \, +#define Z_IS_2726_EQ_2726U(...) \, +#define Z_IS_2726U_EQ_2726U(...) \, +#define Z_IS_2727_EQ_2727(...) \, +#define Z_IS_2727U_EQ_2727(...) \, +#define Z_IS_2727_EQ_2727U(...) \, +#define Z_IS_2727U_EQ_2727U(...) \, +#define Z_IS_2728_EQ_2728(...) \, +#define Z_IS_2728U_EQ_2728(...) \, +#define Z_IS_2728_EQ_2728U(...) \, +#define Z_IS_2728U_EQ_2728U(...) \, +#define Z_IS_2729_EQ_2729(...) \, +#define Z_IS_2729U_EQ_2729(...) \, +#define Z_IS_2729_EQ_2729U(...) \, +#define Z_IS_2729U_EQ_2729U(...) \, +#define Z_IS_2730_EQ_2730(...) \, +#define Z_IS_2730U_EQ_2730(...) \, +#define Z_IS_2730_EQ_2730U(...) \, +#define Z_IS_2730U_EQ_2730U(...) \, +#define Z_IS_2731_EQ_2731(...) \, +#define Z_IS_2731U_EQ_2731(...) \, +#define Z_IS_2731_EQ_2731U(...) \, +#define Z_IS_2731U_EQ_2731U(...) \, +#define Z_IS_2732_EQ_2732(...) \, +#define Z_IS_2732U_EQ_2732(...) \, +#define Z_IS_2732_EQ_2732U(...) \, +#define Z_IS_2732U_EQ_2732U(...) \, +#define Z_IS_2733_EQ_2733(...) \, +#define Z_IS_2733U_EQ_2733(...) \, +#define Z_IS_2733_EQ_2733U(...) \, +#define Z_IS_2733U_EQ_2733U(...) \, +#define Z_IS_2734_EQ_2734(...) \, +#define Z_IS_2734U_EQ_2734(...) \, +#define Z_IS_2734_EQ_2734U(...) \, +#define Z_IS_2734U_EQ_2734U(...) \, +#define Z_IS_2735_EQ_2735(...) \, +#define Z_IS_2735U_EQ_2735(...) \, +#define Z_IS_2735_EQ_2735U(...) \, +#define Z_IS_2735U_EQ_2735U(...) \, +#define Z_IS_2736_EQ_2736(...) \, +#define Z_IS_2736U_EQ_2736(...) \, +#define Z_IS_2736_EQ_2736U(...) \, +#define Z_IS_2736U_EQ_2736U(...) \, +#define Z_IS_2737_EQ_2737(...) \, +#define Z_IS_2737U_EQ_2737(...) \, +#define Z_IS_2737_EQ_2737U(...) \, +#define Z_IS_2737U_EQ_2737U(...) \, +#define Z_IS_2738_EQ_2738(...) \, +#define Z_IS_2738U_EQ_2738(...) \, +#define Z_IS_2738_EQ_2738U(...) \, +#define Z_IS_2738U_EQ_2738U(...) \, +#define Z_IS_2739_EQ_2739(...) \, +#define Z_IS_2739U_EQ_2739(...) \, +#define Z_IS_2739_EQ_2739U(...) \, +#define Z_IS_2739U_EQ_2739U(...) \, +#define Z_IS_2740_EQ_2740(...) \, +#define Z_IS_2740U_EQ_2740(...) \, +#define Z_IS_2740_EQ_2740U(...) \, +#define Z_IS_2740U_EQ_2740U(...) \, +#define Z_IS_2741_EQ_2741(...) \, +#define Z_IS_2741U_EQ_2741(...) \, +#define Z_IS_2741_EQ_2741U(...) \, +#define Z_IS_2741U_EQ_2741U(...) \, +#define Z_IS_2742_EQ_2742(...) \, +#define Z_IS_2742U_EQ_2742(...) \, +#define Z_IS_2742_EQ_2742U(...) \, +#define Z_IS_2742U_EQ_2742U(...) \, +#define Z_IS_2743_EQ_2743(...) \, +#define Z_IS_2743U_EQ_2743(...) \, +#define Z_IS_2743_EQ_2743U(...) \, +#define Z_IS_2743U_EQ_2743U(...) \, +#define Z_IS_2744_EQ_2744(...) \, +#define Z_IS_2744U_EQ_2744(...) \, +#define Z_IS_2744_EQ_2744U(...) \, +#define Z_IS_2744U_EQ_2744U(...) \, +#define Z_IS_2745_EQ_2745(...) \, +#define Z_IS_2745U_EQ_2745(...) \, +#define Z_IS_2745_EQ_2745U(...) \, +#define Z_IS_2745U_EQ_2745U(...) \, +#define Z_IS_2746_EQ_2746(...) \, +#define Z_IS_2746U_EQ_2746(...) \, +#define Z_IS_2746_EQ_2746U(...) \, +#define Z_IS_2746U_EQ_2746U(...) \, +#define Z_IS_2747_EQ_2747(...) \, +#define Z_IS_2747U_EQ_2747(...) \, +#define Z_IS_2747_EQ_2747U(...) \, +#define Z_IS_2747U_EQ_2747U(...) \, +#define Z_IS_2748_EQ_2748(...) \, +#define Z_IS_2748U_EQ_2748(...) \, +#define Z_IS_2748_EQ_2748U(...) \, +#define Z_IS_2748U_EQ_2748U(...) \, +#define Z_IS_2749_EQ_2749(...) \, +#define Z_IS_2749U_EQ_2749(...) \, +#define Z_IS_2749_EQ_2749U(...) \, +#define Z_IS_2749U_EQ_2749U(...) \, +#define Z_IS_2750_EQ_2750(...) \, +#define Z_IS_2750U_EQ_2750(...) \, +#define Z_IS_2750_EQ_2750U(...) \, +#define Z_IS_2750U_EQ_2750U(...) \, +#define Z_IS_2751_EQ_2751(...) \, +#define Z_IS_2751U_EQ_2751(...) \, +#define Z_IS_2751_EQ_2751U(...) \, +#define Z_IS_2751U_EQ_2751U(...) \, +#define Z_IS_2752_EQ_2752(...) \, +#define Z_IS_2752U_EQ_2752(...) \, +#define Z_IS_2752_EQ_2752U(...) \, +#define Z_IS_2752U_EQ_2752U(...) \, +#define Z_IS_2753_EQ_2753(...) \, +#define Z_IS_2753U_EQ_2753(...) \, +#define Z_IS_2753_EQ_2753U(...) \, +#define Z_IS_2753U_EQ_2753U(...) \, +#define Z_IS_2754_EQ_2754(...) \, +#define Z_IS_2754U_EQ_2754(...) \, +#define Z_IS_2754_EQ_2754U(...) \, +#define Z_IS_2754U_EQ_2754U(...) \, +#define Z_IS_2755_EQ_2755(...) \, +#define Z_IS_2755U_EQ_2755(...) \, +#define Z_IS_2755_EQ_2755U(...) \, +#define Z_IS_2755U_EQ_2755U(...) \, +#define Z_IS_2756_EQ_2756(...) \, +#define Z_IS_2756U_EQ_2756(...) \, +#define Z_IS_2756_EQ_2756U(...) \, +#define Z_IS_2756U_EQ_2756U(...) \, +#define Z_IS_2757_EQ_2757(...) \, +#define Z_IS_2757U_EQ_2757(...) \, +#define Z_IS_2757_EQ_2757U(...) \, +#define Z_IS_2757U_EQ_2757U(...) \, +#define Z_IS_2758_EQ_2758(...) \, +#define Z_IS_2758U_EQ_2758(...) \, +#define Z_IS_2758_EQ_2758U(...) \, +#define Z_IS_2758U_EQ_2758U(...) \, +#define Z_IS_2759_EQ_2759(...) \, +#define Z_IS_2759U_EQ_2759(...) \, +#define Z_IS_2759_EQ_2759U(...) \, +#define Z_IS_2759U_EQ_2759U(...) \, +#define Z_IS_2760_EQ_2760(...) \, +#define Z_IS_2760U_EQ_2760(...) \, +#define Z_IS_2760_EQ_2760U(...) \, +#define Z_IS_2760U_EQ_2760U(...) \, +#define Z_IS_2761_EQ_2761(...) \, +#define Z_IS_2761U_EQ_2761(...) \, +#define Z_IS_2761_EQ_2761U(...) \, +#define Z_IS_2761U_EQ_2761U(...) \, +#define Z_IS_2762_EQ_2762(...) \, +#define Z_IS_2762U_EQ_2762(...) \, +#define Z_IS_2762_EQ_2762U(...) \, +#define Z_IS_2762U_EQ_2762U(...) \, +#define Z_IS_2763_EQ_2763(...) \, +#define Z_IS_2763U_EQ_2763(...) \, +#define Z_IS_2763_EQ_2763U(...) \, +#define Z_IS_2763U_EQ_2763U(...) \, +#define Z_IS_2764_EQ_2764(...) \, +#define Z_IS_2764U_EQ_2764(...) \, +#define Z_IS_2764_EQ_2764U(...) \, +#define Z_IS_2764U_EQ_2764U(...) \, +#define Z_IS_2765_EQ_2765(...) \, +#define Z_IS_2765U_EQ_2765(...) \, +#define Z_IS_2765_EQ_2765U(...) \, +#define Z_IS_2765U_EQ_2765U(...) \, +#define Z_IS_2766_EQ_2766(...) \, +#define Z_IS_2766U_EQ_2766(...) \, +#define Z_IS_2766_EQ_2766U(...) \, +#define Z_IS_2766U_EQ_2766U(...) \, +#define Z_IS_2767_EQ_2767(...) \, +#define Z_IS_2767U_EQ_2767(...) \, +#define Z_IS_2767_EQ_2767U(...) \, +#define Z_IS_2767U_EQ_2767U(...) \, +#define Z_IS_2768_EQ_2768(...) \, +#define Z_IS_2768U_EQ_2768(...) \, +#define Z_IS_2768_EQ_2768U(...) \, +#define Z_IS_2768U_EQ_2768U(...) \, +#define Z_IS_2769_EQ_2769(...) \, +#define Z_IS_2769U_EQ_2769(...) \, +#define Z_IS_2769_EQ_2769U(...) \, +#define Z_IS_2769U_EQ_2769U(...) \, +#define Z_IS_2770_EQ_2770(...) \, +#define Z_IS_2770U_EQ_2770(...) \, +#define Z_IS_2770_EQ_2770U(...) \, +#define Z_IS_2770U_EQ_2770U(...) \, +#define Z_IS_2771_EQ_2771(...) \, +#define Z_IS_2771U_EQ_2771(...) \, +#define Z_IS_2771_EQ_2771U(...) \, +#define Z_IS_2771U_EQ_2771U(...) \, +#define Z_IS_2772_EQ_2772(...) \, +#define Z_IS_2772U_EQ_2772(...) \, +#define Z_IS_2772_EQ_2772U(...) \, +#define Z_IS_2772U_EQ_2772U(...) \, +#define Z_IS_2773_EQ_2773(...) \, +#define Z_IS_2773U_EQ_2773(...) \, +#define Z_IS_2773_EQ_2773U(...) \, +#define Z_IS_2773U_EQ_2773U(...) \, +#define Z_IS_2774_EQ_2774(...) \, +#define Z_IS_2774U_EQ_2774(...) \, +#define Z_IS_2774_EQ_2774U(...) \, +#define Z_IS_2774U_EQ_2774U(...) \, +#define Z_IS_2775_EQ_2775(...) \, +#define Z_IS_2775U_EQ_2775(...) \, +#define Z_IS_2775_EQ_2775U(...) \, +#define Z_IS_2775U_EQ_2775U(...) \, +#define Z_IS_2776_EQ_2776(...) \, +#define Z_IS_2776U_EQ_2776(...) \, +#define Z_IS_2776_EQ_2776U(...) \, +#define Z_IS_2776U_EQ_2776U(...) \, +#define Z_IS_2777_EQ_2777(...) \, +#define Z_IS_2777U_EQ_2777(...) \, +#define Z_IS_2777_EQ_2777U(...) \, +#define Z_IS_2777U_EQ_2777U(...) \, +#define Z_IS_2778_EQ_2778(...) \, +#define Z_IS_2778U_EQ_2778(...) \, +#define Z_IS_2778_EQ_2778U(...) \, +#define Z_IS_2778U_EQ_2778U(...) \, +#define Z_IS_2779_EQ_2779(...) \, +#define Z_IS_2779U_EQ_2779(...) \, +#define Z_IS_2779_EQ_2779U(...) \, +#define Z_IS_2779U_EQ_2779U(...) \, +#define Z_IS_2780_EQ_2780(...) \, +#define Z_IS_2780U_EQ_2780(...) \, +#define Z_IS_2780_EQ_2780U(...) \, +#define Z_IS_2780U_EQ_2780U(...) \, +#define Z_IS_2781_EQ_2781(...) \, +#define Z_IS_2781U_EQ_2781(...) \, +#define Z_IS_2781_EQ_2781U(...) \, +#define Z_IS_2781U_EQ_2781U(...) \, +#define Z_IS_2782_EQ_2782(...) \, +#define Z_IS_2782U_EQ_2782(...) \, +#define Z_IS_2782_EQ_2782U(...) \, +#define Z_IS_2782U_EQ_2782U(...) \, +#define Z_IS_2783_EQ_2783(...) \, +#define Z_IS_2783U_EQ_2783(...) \, +#define Z_IS_2783_EQ_2783U(...) \, +#define Z_IS_2783U_EQ_2783U(...) \, +#define Z_IS_2784_EQ_2784(...) \, +#define Z_IS_2784U_EQ_2784(...) \, +#define Z_IS_2784_EQ_2784U(...) \, +#define Z_IS_2784U_EQ_2784U(...) \, +#define Z_IS_2785_EQ_2785(...) \, +#define Z_IS_2785U_EQ_2785(...) \, +#define Z_IS_2785_EQ_2785U(...) \, +#define Z_IS_2785U_EQ_2785U(...) \, +#define Z_IS_2786_EQ_2786(...) \, +#define Z_IS_2786U_EQ_2786(...) \, +#define Z_IS_2786_EQ_2786U(...) \, +#define Z_IS_2786U_EQ_2786U(...) \, +#define Z_IS_2787_EQ_2787(...) \, +#define Z_IS_2787U_EQ_2787(...) \, +#define Z_IS_2787_EQ_2787U(...) \, +#define Z_IS_2787U_EQ_2787U(...) \, +#define Z_IS_2788_EQ_2788(...) \, +#define Z_IS_2788U_EQ_2788(...) \, +#define Z_IS_2788_EQ_2788U(...) \, +#define Z_IS_2788U_EQ_2788U(...) \, +#define Z_IS_2789_EQ_2789(...) \, +#define Z_IS_2789U_EQ_2789(...) \, +#define Z_IS_2789_EQ_2789U(...) \, +#define Z_IS_2789U_EQ_2789U(...) \, +#define Z_IS_2790_EQ_2790(...) \, +#define Z_IS_2790U_EQ_2790(...) \, +#define Z_IS_2790_EQ_2790U(...) \, +#define Z_IS_2790U_EQ_2790U(...) \, +#define Z_IS_2791_EQ_2791(...) \, +#define Z_IS_2791U_EQ_2791(...) \, +#define Z_IS_2791_EQ_2791U(...) \, +#define Z_IS_2791U_EQ_2791U(...) \, +#define Z_IS_2792_EQ_2792(...) \, +#define Z_IS_2792U_EQ_2792(...) \, +#define Z_IS_2792_EQ_2792U(...) \, +#define Z_IS_2792U_EQ_2792U(...) \, +#define Z_IS_2793_EQ_2793(...) \, +#define Z_IS_2793U_EQ_2793(...) \, +#define Z_IS_2793_EQ_2793U(...) \, +#define Z_IS_2793U_EQ_2793U(...) \, +#define Z_IS_2794_EQ_2794(...) \, +#define Z_IS_2794U_EQ_2794(...) \, +#define Z_IS_2794_EQ_2794U(...) \, +#define Z_IS_2794U_EQ_2794U(...) \, +#define Z_IS_2795_EQ_2795(...) \, +#define Z_IS_2795U_EQ_2795(...) \, +#define Z_IS_2795_EQ_2795U(...) \, +#define Z_IS_2795U_EQ_2795U(...) \, +#define Z_IS_2796_EQ_2796(...) \, +#define Z_IS_2796U_EQ_2796(...) \, +#define Z_IS_2796_EQ_2796U(...) \, +#define Z_IS_2796U_EQ_2796U(...) \, +#define Z_IS_2797_EQ_2797(...) \, +#define Z_IS_2797U_EQ_2797(...) \, +#define Z_IS_2797_EQ_2797U(...) \, +#define Z_IS_2797U_EQ_2797U(...) \, +#define Z_IS_2798_EQ_2798(...) \, +#define Z_IS_2798U_EQ_2798(...) \, +#define Z_IS_2798_EQ_2798U(...) \, +#define Z_IS_2798U_EQ_2798U(...) \, +#define Z_IS_2799_EQ_2799(...) \, +#define Z_IS_2799U_EQ_2799(...) \, +#define Z_IS_2799_EQ_2799U(...) \, +#define Z_IS_2799U_EQ_2799U(...) \, +#define Z_IS_2800_EQ_2800(...) \, +#define Z_IS_2800U_EQ_2800(...) \, +#define Z_IS_2800_EQ_2800U(...) \, +#define Z_IS_2800U_EQ_2800U(...) \, +#define Z_IS_2801_EQ_2801(...) \, +#define Z_IS_2801U_EQ_2801(...) \, +#define Z_IS_2801_EQ_2801U(...) \, +#define Z_IS_2801U_EQ_2801U(...) \, +#define Z_IS_2802_EQ_2802(...) \, +#define Z_IS_2802U_EQ_2802(...) \, +#define Z_IS_2802_EQ_2802U(...) \, +#define Z_IS_2802U_EQ_2802U(...) \, +#define Z_IS_2803_EQ_2803(...) \, +#define Z_IS_2803U_EQ_2803(...) \, +#define Z_IS_2803_EQ_2803U(...) \, +#define Z_IS_2803U_EQ_2803U(...) \, +#define Z_IS_2804_EQ_2804(...) \, +#define Z_IS_2804U_EQ_2804(...) \, +#define Z_IS_2804_EQ_2804U(...) \, +#define Z_IS_2804U_EQ_2804U(...) \, +#define Z_IS_2805_EQ_2805(...) \, +#define Z_IS_2805U_EQ_2805(...) \, +#define Z_IS_2805_EQ_2805U(...) \, +#define Z_IS_2805U_EQ_2805U(...) \, +#define Z_IS_2806_EQ_2806(...) \, +#define Z_IS_2806U_EQ_2806(...) \, +#define Z_IS_2806_EQ_2806U(...) \, +#define Z_IS_2806U_EQ_2806U(...) \, +#define Z_IS_2807_EQ_2807(...) \, +#define Z_IS_2807U_EQ_2807(...) \, +#define Z_IS_2807_EQ_2807U(...) \, +#define Z_IS_2807U_EQ_2807U(...) \, +#define Z_IS_2808_EQ_2808(...) \, +#define Z_IS_2808U_EQ_2808(...) \, +#define Z_IS_2808_EQ_2808U(...) \, +#define Z_IS_2808U_EQ_2808U(...) \, +#define Z_IS_2809_EQ_2809(...) \, +#define Z_IS_2809U_EQ_2809(...) \, +#define Z_IS_2809_EQ_2809U(...) \, +#define Z_IS_2809U_EQ_2809U(...) \, +#define Z_IS_2810_EQ_2810(...) \, +#define Z_IS_2810U_EQ_2810(...) \, +#define Z_IS_2810_EQ_2810U(...) \, +#define Z_IS_2810U_EQ_2810U(...) \, +#define Z_IS_2811_EQ_2811(...) \, +#define Z_IS_2811U_EQ_2811(...) \, +#define Z_IS_2811_EQ_2811U(...) \, +#define Z_IS_2811U_EQ_2811U(...) \, +#define Z_IS_2812_EQ_2812(...) \, +#define Z_IS_2812U_EQ_2812(...) \, +#define Z_IS_2812_EQ_2812U(...) \, +#define Z_IS_2812U_EQ_2812U(...) \, +#define Z_IS_2813_EQ_2813(...) \, +#define Z_IS_2813U_EQ_2813(...) \, +#define Z_IS_2813_EQ_2813U(...) \, +#define Z_IS_2813U_EQ_2813U(...) \, +#define Z_IS_2814_EQ_2814(...) \, +#define Z_IS_2814U_EQ_2814(...) \, +#define Z_IS_2814_EQ_2814U(...) \, +#define Z_IS_2814U_EQ_2814U(...) \, +#define Z_IS_2815_EQ_2815(...) \, +#define Z_IS_2815U_EQ_2815(...) \, +#define Z_IS_2815_EQ_2815U(...) \, +#define Z_IS_2815U_EQ_2815U(...) \, +#define Z_IS_2816_EQ_2816(...) \, +#define Z_IS_2816U_EQ_2816(...) \, +#define Z_IS_2816_EQ_2816U(...) \, +#define Z_IS_2816U_EQ_2816U(...) \, +#define Z_IS_2817_EQ_2817(...) \, +#define Z_IS_2817U_EQ_2817(...) \, +#define Z_IS_2817_EQ_2817U(...) \, +#define Z_IS_2817U_EQ_2817U(...) \, +#define Z_IS_2818_EQ_2818(...) \, +#define Z_IS_2818U_EQ_2818(...) \, +#define Z_IS_2818_EQ_2818U(...) \, +#define Z_IS_2818U_EQ_2818U(...) \, +#define Z_IS_2819_EQ_2819(...) \, +#define Z_IS_2819U_EQ_2819(...) \, +#define Z_IS_2819_EQ_2819U(...) \, +#define Z_IS_2819U_EQ_2819U(...) \, +#define Z_IS_2820_EQ_2820(...) \, +#define Z_IS_2820U_EQ_2820(...) \, +#define Z_IS_2820_EQ_2820U(...) \, +#define Z_IS_2820U_EQ_2820U(...) \, +#define Z_IS_2821_EQ_2821(...) \, +#define Z_IS_2821U_EQ_2821(...) \, +#define Z_IS_2821_EQ_2821U(...) \, +#define Z_IS_2821U_EQ_2821U(...) \, +#define Z_IS_2822_EQ_2822(...) \, +#define Z_IS_2822U_EQ_2822(...) \, +#define Z_IS_2822_EQ_2822U(...) \, +#define Z_IS_2822U_EQ_2822U(...) \, +#define Z_IS_2823_EQ_2823(...) \, +#define Z_IS_2823U_EQ_2823(...) \, +#define Z_IS_2823_EQ_2823U(...) \, +#define Z_IS_2823U_EQ_2823U(...) \, +#define Z_IS_2824_EQ_2824(...) \, +#define Z_IS_2824U_EQ_2824(...) \, +#define Z_IS_2824_EQ_2824U(...) \, +#define Z_IS_2824U_EQ_2824U(...) \, +#define Z_IS_2825_EQ_2825(...) \, +#define Z_IS_2825U_EQ_2825(...) \, +#define Z_IS_2825_EQ_2825U(...) \, +#define Z_IS_2825U_EQ_2825U(...) \, +#define Z_IS_2826_EQ_2826(...) \, +#define Z_IS_2826U_EQ_2826(...) \, +#define Z_IS_2826_EQ_2826U(...) \, +#define Z_IS_2826U_EQ_2826U(...) \, +#define Z_IS_2827_EQ_2827(...) \, +#define Z_IS_2827U_EQ_2827(...) \, +#define Z_IS_2827_EQ_2827U(...) \, +#define Z_IS_2827U_EQ_2827U(...) \, +#define Z_IS_2828_EQ_2828(...) \, +#define Z_IS_2828U_EQ_2828(...) \, +#define Z_IS_2828_EQ_2828U(...) \, +#define Z_IS_2828U_EQ_2828U(...) \, +#define Z_IS_2829_EQ_2829(...) \, +#define Z_IS_2829U_EQ_2829(...) \, +#define Z_IS_2829_EQ_2829U(...) \, +#define Z_IS_2829U_EQ_2829U(...) \, +#define Z_IS_2830_EQ_2830(...) \, +#define Z_IS_2830U_EQ_2830(...) \, +#define Z_IS_2830_EQ_2830U(...) \, +#define Z_IS_2830U_EQ_2830U(...) \, +#define Z_IS_2831_EQ_2831(...) \, +#define Z_IS_2831U_EQ_2831(...) \, +#define Z_IS_2831_EQ_2831U(...) \, +#define Z_IS_2831U_EQ_2831U(...) \, +#define Z_IS_2832_EQ_2832(...) \, +#define Z_IS_2832U_EQ_2832(...) \, +#define Z_IS_2832_EQ_2832U(...) \, +#define Z_IS_2832U_EQ_2832U(...) \, +#define Z_IS_2833_EQ_2833(...) \, +#define Z_IS_2833U_EQ_2833(...) \, +#define Z_IS_2833_EQ_2833U(...) \, +#define Z_IS_2833U_EQ_2833U(...) \, +#define Z_IS_2834_EQ_2834(...) \, +#define Z_IS_2834U_EQ_2834(...) \, +#define Z_IS_2834_EQ_2834U(...) \, +#define Z_IS_2834U_EQ_2834U(...) \, +#define Z_IS_2835_EQ_2835(...) \, +#define Z_IS_2835U_EQ_2835(...) \, +#define Z_IS_2835_EQ_2835U(...) \, +#define Z_IS_2835U_EQ_2835U(...) \, +#define Z_IS_2836_EQ_2836(...) \, +#define Z_IS_2836U_EQ_2836(...) \, +#define Z_IS_2836_EQ_2836U(...) \, +#define Z_IS_2836U_EQ_2836U(...) \, +#define Z_IS_2837_EQ_2837(...) \, +#define Z_IS_2837U_EQ_2837(...) \, +#define Z_IS_2837_EQ_2837U(...) \, +#define Z_IS_2837U_EQ_2837U(...) \, +#define Z_IS_2838_EQ_2838(...) \, +#define Z_IS_2838U_EQ_2838(...) \, +#define Z_IS_2838_EQ_2838U(...) \, +#define Z_IS_2838U_EQ_2838U(...) \, +#define Z_IS_2839_EQ_2839(...) \, +#define Z_IS_2839U_EQ_2839(...) \, +#define Z_IS_2839_EQ_2839U(...) \, +#define Z_IS_2839U_EQ_2839U(...) \, +#define Z_IS_2840_EQ_2840(...) \, +#define Z_IS_2840U_EQ_2840(...) \, +#define Z_IS_2840_EQ_2840U(...) \, +#define Z_IS_2840U_EQ_2840U(...) \, +#define Z_IS_2841_EQ_2841(...) \, +#define Z_IS_2841U_EQ_2841(...) \, +#define Z_IS_2841_EQ_2841U(...) \, +#define Z_IS_2841U_EQ_2841U(...) \, +#define Z_IS_2842_EQ_2842(...) \, +#define Z_IS_2842U_EQ_2842(...) \, +#define Z_IS_2842_EQ_2842U(...) \, +#define Z_IS_2842U_EQ_2842U(...) \, +#define Z_IS_2843_EQ_2843(...) \, +#define Z_IS_2843U_EQ_2843(...) \, +#define Z_IS_2843_EQ_2843U(...) \, +#define Z_IS_2843U_EQ_2843U(...) \, +#define Z_IS_2844_EQ_2844(...) \, +#define Z_IS_2844U_EQ_2844(...) \, +#define Z_IS_2844_EQ_2844U(...) \, +#define Z_IS_2844U_EQ_2844U(...) \, +#define Z_IS_2845_EQ_2845(...) \, +#define Z_IS_2845U_EQ_2845(...) \, +#define Z_IS_2845_EQ_2845U(...) \, +#define Z_IS_2845U_EQ_2845U(...) \, +#define Z_IS_2846_EQ_2846(...) \, +#define Z_IS_2846U_EQ_2846(...) \, +#define Z_IS_2846_EQ_2846U(...) \, +#define Z_IS_2846U_EQ_2846U(...) \, +#define Z_IS_2847_EQ_2847(...) \, +#define Z_IS_2847U_EQ_2847(...) \, +#define Z_IS_2847_EQ_2847U(...) \, +#define Z_IS_2847U_EQ_2847U(...) \, +#define Z_IS_2848_EQ_2848(...) \, +#define Z_IS_2848U_EQ_2848(...) \, +#define Z_IS_2848_EQ_2848U(...) \, +#define Z_IS_2848U_EQ_2848U(...) \, +#define Z_IS_2849_EQ_2849(...) \, +#define Z_IS_2849U_EQ_2849(...) \, +#define Z_IS_2849_EQ_2849U(...) \, +#define Z_IS_2849U_EQ_2849U(...) \, +#define Z_IS_2850_EQ_2850(...) \, +#define Z_IS_2850U_EQ_2850(...) \, +#define Z_IS_2850_EQ_2850U(...) \, +#define Z_IS_2850U_EQ_2850U(...) \, +#define Z_IS_2851_EQ_2851(...) \, +#define Z_IS_2851U_EQ_2851(...) \, +#define Z_IS_2851_EQ_2851U(...) \, +#define Z_IS_2851U_EQ_2851U(...) \, +#define Z_IS_2852_EQ_2852(...) \, +#define Z_IS_2852U_EQ_2852(...) \, +#define Z_IS_2852_EQ_2852U(...) \, +#define Z_IS_2852U_EQ_2852U(...) \, +#define Z_IS_2853_EQ_2853(...) \, +#define Z_IS_2853U_EQ_2853(...) \, +#define Z_IS_2853_EQ_2853U(...) \, +#define Z_IS_2853U_EQ_2853U(...) \, +#define Z_IS_2854_EQ_2854(...) \, +#define Z_IS_2854U_EQ_2854(...) \, +#define Z_IS_2854_EQ_2854U(...) \, +#define Z_IS_2854U_EQ_2854U(...) \, +#define Z_IS_2855_EQ_2855(...) \, +#define Z_IS_2855U_EQ_2855(...) \, +#define Z_IS_2855_EQ_2855U(...) \, +#define Z_IS_2855U_EQ_2855U(...) \, +#define Z_IS_2856_EQ_2856(...) \, +#define Z_IS_2856U_EQ_2856(...) \, +#define Z_IS_2856_EQ_2856U(...) \, +#define Z_IS_2856U_EQ_2856U(...) \, +#define Z_IS_2857_EQ_2857(...) \, +#define Z_IS_2857U_EQ_2857(...) \, +#define Z_IS_2857_EQ_2857U(...) \, +#define Z_IS_2857U_EQ_2857U(...) \, +#define Z_IS_2858_EQ_2858(...) \, +#define Z_IS_2858U_EQ_2858(...) \, +#define Z_IS_2858_EQ_2858U(...) \, +#define Z_IS_2858U_EQ_2858U(...) \, +#define Z_IS_2859_EQ_2859(...) \, +#define Z_IS_2859U_EQ_2859(...) \, +#define Z_IS_2859_EQ_2859U(...) \, +#define Z_IS_2859U_EQ_2859U(...) \, +#define Z_IS_2860_EQ_2860(...) \, +#define Z_IS_2860U_EQ_2860(...) \, +#define Z_IS_2860_EQ_2860U(...) \, +#define Z_IS_2860U_EQ_2860U(...) \, +#define Z_IS_2861_EQ_2861(...) \, +#define Z_IS_2861U_EQ_2861(...) \, +#define Z_IS_2861_EQ_2861U(...) \, +#define Z_IS_2861U_EQ_2861U(...) \, +#define Z_IS_2862_EQ_2862(...) \, +#define Z_IS_2862U_EQ_2862(...) \, +#define Z_IS_2862_EQ_2862U(...) \, +#define Z_IS_2862U_EQ_2862U(...) \, +#define Z_IS_2863_EQ_2863(...) \, +#define Z_IS_2863U_EQ_2863(...) \, +#define Z_IS_2863_EQ_2863U(...) \, +#define Z_IS_2863U_EQ_2863U(...) \, +#define Z_IS_2864_EQ_2864(...) \, +#define Z_IS_2864U_EQ_2864(...) \, +#define Z_IS_2864_EQ_2864U(...) \, +#define Z_IS_2864U_EQ_2864U(...) \, +#define Z_IS_2865_EQ_2865(...) \, +#define Z_IS_2865U_EQ_2865(...) \, +#define Z_IS_2865_EQ_2865U(...) \, +#define Z_IS_2865U_EQ_2865U(...) \, +#define Z_IS_2866_EQ_2866(...) \, +#define Z_IS_2866U_EQ_2866(...) \, +#define Z_IS_2866_EQ_2866U(...) \, +#define Z_IS_2866U_EQ_2866U(...) \, +#define Z_IS_2867_EQ_2867(...) \, +#define Z_IS_2867U_EQ_2867(...) \, +#define Z_IS_2867_EQ_2867U(...) \, +#define Z_IS_2867U_EQ_2867U(...) \, +#define Z_IS_2868_EQ_2868(...) \, +#define Z_IS_2868U_EQ_2868(...) \, +#define Z_IS_2868_EQ_2868U(...) \, +#define Z_IS_2868U_EQ_2868U(...) \, +#define Z_IS_2869_EQ_2869(...) \, +#define Z_IS_2869U_EQ_2869(...) \, +#define Z_IS_2869_EQ_2869U(...) \, +#define Z_IS_2869U_EQ_2869U(...) \, +#define Z_IS_2870_EQ_2870(...) \, +#define Z_IS_2870U_EQ_2870(...) \, +#define Z_IS_2870_EQ_2870U(...) \, +#define Z_IS_2870U_EQ_2870U(...) \, +#define Z_IS_2871_EQ_2871(...) \, +#define Z_IS_2871U_EQ_2871(...) \, +#define Z_IS_2871_EQ_2871U(...) \, +#define Z_IS_2871U_EQ_2871U(...) \, +#define Z_IS_2872_EQ_2872(...) \, +#define Z_IS_2872U_EQ_2872(...) \, +#define Z_IS_2872_EQ_2872U(...) \, +#define Z_IS_2872U_EQ_2872U(...) \, +#define Z_IS_2873_EQ_2873(...) \, +#define Z_IS_2873U_EQ_2873(...) \, +#define Z_IS_2873_EQ_2873U(...) \, +#define Z_IS_2873U_EQ_2873U(...) \, +#define Z_IS_2874_EQ_2874(...) \, +#define Z_IS_2874U_EQ_2874(...) \, +#define Z_IS_2874_EQ_2874U(...) \, +#define Z_IS_2874U_EQ_2874U(...) \, +#define Z_IS_2875_EQ_2875(...) \, +#define Z_IS_2875U_EQ_2875(...) \, +#define Z_IS_2875_EQ_2875U(...) \, +#define Z_IS_2875U_EQ_2875U(...) \, +#define Z_IS_2876_EQ_2876(...) \, +#define Z_IS_2876U_EQ_2876(...) \, +#define Z_IS_2876_EQ_2876U(...) \, +#define Z_IS_2876U_EQ_2876U(...) \, +#define Z_IS_2877_EQ_2877(...) \, +#define Z_IS_2877U_EQ_2877(...) \, +#define Z_IS_2877_EQ_2877U(...) \, +#define Z_IS_2877U_EQ_2877U(...) \, +#define Z_IS_2878_EQ_2878(...) \, +#define Z_IS_2878U_EQ_2878(...) \, +#define Z_IS_2878_EQ_2878U(...) \, +#define Z_IS_2878U_EQ_2878U(...) \, +#define Z_IS_2879_EQ_2879(...) \, +#define Z_IS_2879U_EQ_2879(...) \, +#define Z_IS_2879_EQ_2879U(...) \, +#define Z_IS_2879U_EQ_2879U(...) \, +#define Z_IS_2880_EQ_2880(...) \, +#define Z_IS_2880U_EQ_2880(...) \, +#define Z_IS_2880_EQ_2880U(...) \, +#define Z_IS_2880U_EQ_2880U(...) \, +#define Z_IS_2881_EQ_2881(...) \, +#define Z_IS_2881U_EQ_2881(...) \, +#define Z_IS_2881_EQ_2881U(...) \, +#define Z_IS_2881U_EQ_2881U(...) \, +#define Z_IS_2882_EQ_2882(...) \, +#define Z_IS_2882U_EQ_2882(...) \, +#define Z_IS_2882_EQ_2882U(...) \, +#define Z_IS_2882U_EQ_2882U(...) \, +#define Z_IS_2883_EQ_2883(...) \, +#define Z_IS_2883U_EQ_2883(...) \, +#define Z_IS_2883_EQ_2883U(...) \, +#define Z_IS_2883U_EQ_2883U(...) \, +#define Z_IS_2884_EQ_2884(...) \, +#define Z_IS_2884U_EQ_2884(...) \, +#define Z_IS_2884_EQ_2884U(...) \, +#define Z_IS_2884U_EQ_2884U(...) \, +#define Z_IS_2885_EQ_2885(...) \, +#define Z_IS_2885U_EQ_2885(...) \, +#define Z_IS_2885_EQ_2885U(...) \, +#define Z_IS_2885U_EQ_2885U(...) \, +#define Z_IS_2886_EQ_2886(...) \, +#define Z_IS_2886U_EQ_2886(...) \, +#define Z_IS_2886_EQ_2886U(...) \, +#define Z_IS_2886U_EQ_2886U(...) \, +#define Z_IS_2887_EQ_2887(...) \, +#define Z_IS_2887U_EQ_2887(...) \, +#define Z_IS_2887_EQ_2887U(...) \, +#define Z_IS_2887U_EQ_2887U(...) \, +#define Z_IS_2888_EQ_2888(...) \, +#define Z_IS_2888U_EQ_2888(...) \, +#define Z_IS_2888_EQ_2888U(...) \, +#define Z_IS_2888U_EQ_2888U(...) \, +#define Z_IS_2889_EQ_2889(...) \, +#define Z_IS_2889U_EQ_2889(...) \, +#define Z_IS_2889_EQ_2889U(...) \, +#define Z_IS_2889U_EQ_2889U(...) \, +#define Z_IS_2890_EQ_2890(...) \, +#define Z_IS_2890U_EQ_2890(...) \, +#define Z_IS_2890_EQ_2890U(...) \, +#define Z_IS_2890U_EQ_2890U(...) \, +#define Z_IS_2891_EQ_2891(...) \, +#define Z_IS_2891U_EQ_2891(...) \, +#define Z_IS_2891_EQ_2891U(...) \, +#define Z_IS_2891U_EQ_2891U(...) \, +#define Z_IS_2892_EQ_2892(...) \, +#define Z_IS_2892U_EQ_2892(...) \, +#define Z_IS_2892_EQ_2892U(...) \, +#define Z_IS_2892U_EQ_2892U(...) \, +#define Z_IS_2893_EQ_2893(...) \, +#define Z_IS_2893U_EQ_2893(...) \, +#define Z_IS_2893_EQ_2893U(...) \, +#define Z_IS_2893U_EQ_2893U(...) \, +#define Z_IS_2894_EQ_2894(...) \, +#define Z_IS_2894U_EQ_2894(...) \, +#define Z_IS_2894_EQ_2894U(...) \, +#define Z_IS_2894U_EQ_2894U(...) \, +#define Z_IS_2895_EQ_2895(...) \, +#define Z_IS_2895U_EQ_2895(...) \, +#define Z_IS_2895_EQ_2895U(...) \, +#define Z_IS_2895U_EQ_2895U(...) \, +#define Z_IS_2896_EQ_2896(...) \, +#define Z_IS_2896U_EQ_2896(...) \, +#define Z_IS_2896_EQ_2896U(...) \, +#define Z_IS_2896U_EQ_2896U(...) \, +#define Z_IS_2897_EQ_2897(...) \, +#define Z_IS_2897U_EQ_2897(...) \, +#define Z_IS_2897_EQ_2897U(...) \, +#define Z_IS_2897U_EQ_2897U(...) \, +#define Z_IS_2898_EQ_2898(...) \, +#define Z_IS_2898U_EQ_2898(...) \, +#define Z_IS_2898_EQ_2898U(...) \, +#define Z_IS_2898U_EQ_2898U(...) \, +#define Z_IS_2899_EQ_2899(...) \, +#define Z_IS_2899U_EQ_2899(...) \, +#define Z_IS_2899_EQ_2899U(...) \, +#define Z_IS_2899U_EQ_2899U(...) \, +#define Z_IS_2900_EQ_2900(...) \, +#define Z_IS_2900U_EQ_2900(...) \, +#define Z_IS_2900_EQ_2900U(...) \, +#define Z_IS_2900U_EQ_2900U(...) \, +#define Z_IS_2901_EQ_2901(...) \, +#define Z_IS_2901U_EQ_2901(...) \, +#define Z_IS_2901_EQ_2901U(...) \, +#define Z_IS_2901U_EQ_2901U(...) \, +#define Z_IS_2902_EQ_2902(...) \, +#define Z_IS_2902U_EQ_2902(...) \, +#define Z_IS_2902_EQ_2902U(...) \, +#define Z_IS_2902U_EQ_2902U(...) \, +#define Z_IS_2903_EQ_2903(...) \, +#define Z_IS_2903U_EQ_2903(...) \, +#define Z_IS_2903_EQ_2903U(...) \, +#define Z_IS_2903U_EQ_2903U(...) \, +#define Z_IS_2904_EQ_2904(...) \, +#define Z_IS_2904U_EQ_2904(...) \, +#define Z_IS_2904_EQ_2904U(...) \, +#define Z_IS_2904U_EQ_2904U(...) \, +#define Z_IS_2905_EQ_2905(...) \, +#define Z_IS_2905U_EQ_2905(...) \, +#define Z_IS_2905_EQ_2905U(...) \, +#define Z_IS_2905U_EQ_2905U(...) \, +#define Z_IS_2906_EQ_2906(...) \, +#define Z_IS_2906U_EQ_2906(...) \, +#define Z_IS_2906_EQ_2906U(...) \, +#define Z_IS_2906U_EQ_2906U(...) \, +#define Z_IS_2907_EQ_2907(...) \, +#define Z_IS_2907U_EQ_2907(...) \, +#define Z_IS_2907_EQ_2907U(...) \, +#define Z_IS_2907U_EQ_2907U(...) \, +#define Z_IS_2908_EQ_2908(...) \, +#define Z_IS_2908U_EQ_2908(...) \, +#define Z_IS_2908_EQ_2908U(...) \, +#define Z_IS_2908U_EQ_2908U(...) \, +#define Z_IS_2909_EQ_2909(...) \, +#define Z_IS_2909U_EQ_2909(...) \, +#define Z_IS_2909_EQ_2909U(...) \, +#define Z_IS_2909U_EQ_2909U(...) \, +#define Z_IS_2910_EQ_2910(...) \, +#define Z_IS_2910U_EQ_2910(...) \, +#define Z_IS_2910_EQ_2910U(...) \, +#define Z_IS_2910U_EQ_2910U(...) \, +#define Z_IS_2911_EQ_2911(...) \, +#define Z_IS_2911U_EQ_2911(...) \, +#define Z_IS_2911_EQ_2911U(...) \, +#define Z_IS_2911U_EQ_2911U(...) \, +#define Z_IS_2912_EQ_2912(...) \, +#define Z_IS_2912U_EQ_2912(...) \, +#define Z_IS_2912_EQ_2912U(...) \, +#define Z_IS_2912U_EQ_2912U(...) \, +#define Z_IS_2913_EQ_2913(...) \, +#define Z_IS_2913U_EQ_2913(...) \, +#define Z_IS_2913_EQ_2913U(...) \, +#define Z_IS_2913U_EQ_2913U(...) \, +#define Z_IS_2914_EQ_2914(...) \, +#define Z_IS_2914U_EQ_2914(...) \, +#define Z_IS_2914_EQ_2914U(...) \, +#define Z_IS_2914U_EQ_2914U(...) \, +#define Z_IS_2915_EQ_2915(...) \, +#define Z_IS_2915U_EQ_2915(...) \, +#define Z_IS_2915_EQ_2915U(...) \, +#define Z_IS_2915U_EQ_2915U(...) \, +#define Z_IS_2916_EQ_2916(...) \, +#define Z_IS_2916U_EQ_2916(...) \, +#define Z_IS_2916_EQ_2916U(...) \, +#define Z_IS_2916U_EQ_2916U(...) \, +#define Z_IS_2917_EQ_2917(...) \, +#define Z_IS_2917U_EQ_2917(...) \, +#define Z_IS_2917_EQ_2917U(...) \, +#define Z_IS_2917U_EQ_2917U(...) \, +#define Z_IS_2918_EQ_2918(...) \, +#define Z_IS_2918U_EQ_2918(...) \, +#define Z_IS_2918_EQ_2918U(...) \, +#define Z_IS_2918U_EQ_2918U(...) \, +#define Z_IS_2919_EQ_2919(...) \, +#define Z_IS_2919U_EQ_2919(...) \, +#define Z_IS_2919_EQ_2919U(...) \, +#define Z_IS_2919U_EQ_2919U(...) \, +#define Z_IS_2920_EQ_2920(...) \, +#define Z_IS_2920U_EQ_2920(...) \, +#define Z_IS_2920_EQ_2920U(...) \, +#define Z_IS_2920U_EQ_2920U(...) \, +#define Z_IS_2921_EQ_2921(...) \, +#define Z_IS_2921U_EQ_2921(...) \, +#define Z_IS_2921_EQ_2921U(...) \, +#define Z_IS_2921U_EQ_2921U(...) \, +#define Z_IS_2922_EQ_2922(...) \, +#define Z_IS_2922U_EQ_2922(...) \, +#define Z_IS_2922_EQ_2922U(...) \, +#define Z_IS_2922U_EQ_2922U(...) \, +#define Z_IS_2923_EQ_2923(...) \, +#define Z_IS_2923U_EQ_2923(...) \, +#define Z_IS_2923_EQ_2923U(...) \, +#define Z_IS_2923U_EQ_2923U(...) \, +#define Z_IS_2924_EQ_2924(...) \, +#define Z_IS_2924U_EQ_2924(...) \, +#define Z_IS_2924_EQ_2924U(...) \, +#define Z_IS_2924U_EQ_2924U(...) \, +#define Z_IS_2925_EQ_2925(...) \, +#define Z_IS_2925U_EQ_2925(...) \, +#define Z_IS_2925_EQ_2925U(...) \, +#define Z_IS_2925U_EQ_2925U(...) \, +#define Z_IS_2926_EQ_2926(...) \, +#define Z_IS_2926U_EQ_2926(...) \, +#define Z_IS_2926_EQ_2926U(...) \, +#define Z_IS_2926U_EQ_2926U(...) \, +#define Z_IS_2927_EQ_2927(...) \, +#define Z_IS_2927U_EQ_2927(...) \, +#define Z_IS_2927_EQ_2927U(...) \, +#define Z_IS_2927U_EQ_2927U(...) \, +#define Z_IS_2928_EQ_2928(...) \, +#define Z_IS_2928U_EQ_2928(...) \, +#define Z_IS_2928_EQ_2928U(...) \, +#define Z_IS_2928U_EQ_2928U(...) \, +#define Z_IS_2929_EQ_2929(...) \, +#define Z_IS_2929U_EQ_2929(...) \, +#define Z_IS_2929_EQ_2929U(...) \, +#define Z_IS_2929U_EQ_2929U(...) \, +#define Z_IS_2930_EQ_2930(...) \, +#define Z_IS_2930U_EQ_2930(...) \, +#define Z_IS_2930_EQ_2930U(...) \, +#define Z_IS_2930U_EQ_2930U(...) \, +#define Z_IS_2931_EQ_2931(...) \, +#define Z_IS_2931U_EQ_2931(...) \, +#define Z_IS_2931_EQ_2931U(...) \, +#define Z_IS_2931U_EQ_2931U(...) \, +#define Z_IS_2932_EQ_2932(...) \, +#define Z_IS_2932U_EQ_2932(...) \, +#define Z_IS_2932_EQ_2932U(...) \, +#define Z_IS_2932U_EQ_2932U(...) \, +#define Z_IS_2933_EQ_2933(...) \, +#define Z_IS_2933U_EQ_2933(...) \, +#define Z_IS_2933_EQ_2933U(...) \, +#define Z_IS_2933U_EQ_2933U(...) \, +#define Z_IS_2934_EQ_2934(...) \, +#define Z_IS_2934U_EQ_2934(...) \, +#define Z_IS_2934_EQ_2934U(...) \, +#define Z_IS_2934U_EQ_2934U(...) \, +#define Z_IS_2935_EQ_2935(...) \, +#define Z_IS_2935U_EQ_2935(...) \, +#define Z_IS_2935_EQ_2935U(...) \, +#define Z_IS_2935U_EQ_2935U(...) \, +#define Z_IS_2936_EQ_2936(...) \, +#define Z_IS_2936U_EQ_2936(...) \, +#define Z_IS_2936_EQ_2936U(...) \, +#define Z_IS_2936U_EQ_2936U(...) \, +#define Z_IS_2937_EQ_2937(...) \, +#define Z_IS_2937U_EQ_2937(...) \, +#define Z_IS_2937_EQ_2937U(...) \, +#define Z_IS_2937U_EQ_2937U(...) \, +#define Z_IS_2938_EQ_2938(...) \, +#define Z_IS_2938U_EQ_2938(...) \, +#define Z_IS_2938_EQ_2938U(...) \, +#define Z_IS_2938U_EQ_2938U(...) \, +#define Z_IS_2939_EQ_2939(...) \, +#define Z_IS_2939U_EQ_2939(...) \, +#define Z_IS_2939_EQ_2939U(...) \, +#define Z_IS_2939U_EQ_2939U(...) \, +#define Z_IS_2940_EQ_2940(...) \, +#define Z_IS_2940U_EQ_2940(...) \, +#define Z_IS_2940_EQ_2940U(...) \, +#define Z_IS_2940U_EQ_2940U(...) \, +#define Z_IS_2941_EQ_2941(...) \, +#define Z_IS_2941U_EQ_2941(...) \, +#define Z_IS_2941_EQ_2941U(...) \, +#define Z_IS_2941U_EQ_2941U(...) \, +#define Z_IS_2942_EQ_2942(...) \, +#define Z_IS_2942U_EQ_2942(...) \, +#define Z_IS_2942_EQ_2942U(...) \, +#define Z_IS_2942U_EQ_2942U(...) \, +#define Z_IS_2943_EQ_2943(...) \, +#define Z_IS_2943U_EQ_2943(...) \, +#define Z_IS_2943_EQ_2943U(...) \, +#define Z_IS_2943U_EQ_2943U(...) \, +#define Z_IS_2944_EQ_2944(...) \, +#define Z_IS_2944U_EQ_2944(...) \, +#define Z_IS_2944_EQ_2944U(...) \, +#define Z_IS_2944U_EQ_2944U(...) \, +#define Z_IS_2945_EQ_2945(...) \, +#define Z_IS_2945U_EQ_2945(...) \, +#define Z_IS_2945_EQ_2945U(...) \, +#define Z_IS_2945U_EQ_2945U(...) \, +#define Z_IS_2946_EQ_2946(...) \, +#define Z_IS_2946U_EQ_2946(...) \, +#define Z_IS_2946_EQ_2946U(...) \, +#define Z_IS_2946U_EQ_2946U(...) \, +#define Z_IS_2947_EQ_2947(...) \, +#define Z_IS_2947U_EQ_2947(...) \, +#define Z_IS_2947_EQ_2947U(...) \, +#define Z_IS_2947U_EQ_2947U(...) \, +#define Z_IS_2948_EQ_2948(...) \, +#define Z_IS_2948U_EQ_2948(...) \, +#define Z_IS_2948_EQ_2948U(...) \, +#define Z_IS_2948U_EQ_2948U(...) \, +#define Z_IS_2949_EQ_2949(...) \, +#define Z_IS_2949U_EQ_2949(...) \, +#define Z_IS_2949_EQ_2949U(...) \, +#define Z_IS_2949U_EQ_2949U(...) \, +#define Z_IS_2950_EQ_2950(...) \, +#define Z_IS_2950U_EQ_2950(...) \, +#define Z_IS_2950_EQ_2950U(...) \, +#define Z_IS_2950U_EQ_2950U(...) \, +#define Z_IS_2951_EQ_2951(...) \, +#define Z_IS_2951U_EQ_2951(...) \, +#define Z_IS_2951_EQ_2951U(...) \, +#define Z_IS_2951U_EQ_2951U(...) \, +#define Z_IS_2952_EQ_2952(...) \, +#define Z_IS_2952U_EQ_2952(...) \, +#define Z_IS_2952_EQ_2952U(...) \, +#define Z_IS_2952U_EQ_2952U(...) \, +#define Z_IS_2953_EQ_2953(...) \, +#define Z_IS_2953U_EQ_2953(...) \, +#define Z_IS_2953_EQ_2953U(...) \, +#define Z_IS_2953U_EQ_2953U(...) \, +#define Z_IS_2954_EQ_2954(...) \, +#define Z_IS_2954U_EQ_2954(...) \, +#define Z_IS_2954_EQ_2954U(...) \, +#define Z_IS_2954U_EQ_2954U(...) \, +#define Z_IS_2955_EQ_2955(...) \, +#define Z_IS_2955U_EQ_2955(...) \, +#define Z_IS_2955_EQ_2955U(...) \, +#define Z_IS_2955U_EQ_2955U(...) \, +#define Z_IS_2956_EQ_2956(...) \, +#define Z_IS_2956U_EQ_2956(...) \, +#define Z_IS_2956_EQ_2956U(...) \, +#define Z_IS_2956U_EQ_2956U(...) \, +#define Z_IS_2957_EQ_2957(...) \, +#define Z_IS_2957U_EQ_2957(...) \, +#define Z_IS_2957_EQ_2957U(...) \, +#define Z_IS_2957U_EQ_2957U(...) \, +#define Z_IS_2958_EQ_2958(...) \, +#define Z_IS_2958U_EQ_2958(...) \, +#define Z_IS_2958_EQ_2958U(...) \, +#define Z_IS_2958U_EQ_2958U(...) \, +#define Z_IS_2959_EQ_2959(...) \, +#define Z_IS_2959U_EQ_2959(...) \, +#define Z_IS_2959_EQ_2959U(...) \, +#define Z_IS_2959U_EQ_2959U(...) \, +#define Z_IS_2960_EQ_2960(...) \, +#define Z_IS_2960U_EQ_2960(...) \, +#define Z_IS_2960_EQ_2960U(...) \, +#define Z_IS_2960U_EQ_2960U(...) \, +#define Z_IS_2961_EQ_2961(...) \, +#define Z_IS_2961U_EQ_2961(...) \, +#define Z_IS_2961_EQ_2961U(...) \, +#define Z_IS_2961U_EQ_2961U(...) \, +#define Z_IS_2962_EQ_2962(...) \, +#define Z_IS_2962U_EQ_2962(...) \, +#define Z_IS_2962_EQ_2962U(...) \, +#define Z_IS_2962U_EQ_2962U(...) \, +#define Z_IS_2963_EQ_2963(...) \, +#define Z_IS_2963U_EQ_2963(...) \, +#define Z_IS_2963_EQ_2963U(...) \, +#define Z_IS_2963U_EQ_2963U(...) \, +#define Z_IS_2964_EQ_2964(...) \, +#define Z_IS_2964U_EQ_2964(...) \, +#define Z_IS_2964_EQ_2964U(...) \, +#define Z_IS_2964U_EQ_2964U(...) \, +#define Z_IS_2965_EQ_2965(...) \, +#define Z_IS_2965U_EQ_2965(...) \, +#define Z_IS_2965_EQ_2965U(...) \, +#define Z_IS_2965U_EQ_2965U(...) \, +#define Z_IS_2966_EQ_2966(...) \, +#define Z_IS_2966U_EQ_2966(...) \, +#define Z_IS_2966_EQ_2966U(...) \, +#define Z_IS_2966U_EQ_2966U(...) \, +#define Z_IS_2967_EQ_2967(...) \, +#define Z_IS_2967U_EQ_2967(...) \, +#define Z_IS_2967_EQ_2967U(...) \, +#define Z_IS_2967U_EQ_2967U(...) \, +#define Z_IS_2968_EQ_2968(...) \, +#define Z_IS_2968U_EQ_2968(...) \, +#define Z_IS_2968_EQ_2968U(...) \, +#define Z_IS_2968U_EQ_2968U(...) \, +#define Z_IS_2969_EQ_2969(...) \, +#define Z_IS_2969U_EQ_2969(...) \, +#define Z_IS_2969_EQ_2969U(...) \, +#define Z_IS_2969U_EQ_2969U(...) \, +#define Z_IS_2970_EQ_2970(...) \, +#define Z_IS_2970U_EQ_2970(...) \, +#define Z_IS_2970_EQ_2970U(...) \, +#define Z_IS_2970U_EQ_2970U(...) \, +#define Z_IS_2971_EQ_2971(...) \, +#define Z_IS_2971U_EQ_2971(...) \, +#define Z_IS_2971_EQ_2971U(...) \, +#define Z_IS_2971U_EQ_2971U(...) \, +#define Z_IS_2972_EQ_2972(...) \, +#define Z_IS_2972U_EQ_2972(...) \, +#define Z_IS_2972_EQ_2972U(...) \, +#define Z_IS_2972U_EQ_2972U(...) \, +#define Z_IS_2973_EQ_2973(...) \, +#define Z_IS_2973U_EQ_2973(...) \, +#define Z_IS_2973_EQ_2973U(...) \, +#define Z_IS_2973U_EQ_2973U(...) \, +#define Z_IS_2974_EQ_2974(...) \, +#define Z_IS_2974U_EQ_2974(...) \, +#define Z_IS_2974_EQ_2974U(...) \, +#define Z_IS_2974U_EQ_2974U(...) \, +#define Z_IS_2975_EQ_2975(...) \, +#define Z_IS_2975U_EQ_2975(...) \, +#define Z_IS_2975_EQ_2975U(...) \, +#define Z_IS_2975U_EQ_2975U(...) \, +#define Z_IS_2976_EQ_2976(...) \, +#define Z_IS_2976U_EQ_2976(...) \, +#define Z_IS_2976_EQ_2976U(...) \, +#define Z_IS_2976U_EQ_2976U(...) \, +#define Z_IS_2977_EQ_2977(...) \, +#define Z_IS_2977U_EQ_2977(...) \, +#define Z_IS_2977_EQ_2977U(...) \, +#define Z_IS_2977U_EQ_2977U(...) \, +#define Z_IS_2978_EQ_2978(...) \, +#define Z_IS_2978U_EQ_2978(...) \, +#define Z_IS_2978_EQ_2978U(...) \, +#define Z_IS_2978U_EQ_2978U(...) \, +#define Z_IS_2979_EQ_2979(...) \, +#define Z_IS_2979U_EQ_2979(...) \, +#define Z_IS_2979_EQ_2979U(...) \, +#define Z_IS_2979U_EQ_2979U(...) \, +#define Z_IS_2980_EQ_2980(...) \, +#define Z_IS_2980U_EQ_2980(...) \, +#define Z_IS_2980_EQ_2980U(...) \, +#define Z_IS_2980U_EQ_2980U(...) \, +#define Z_IS_2981_EQ_2981(...) \, +#define Z_IS_2981U_EQ_2981(...) \, +#define Z_IS_2981_EQ_2981U(...) \, +#define Z_IS_2981U_EQ_2981U(...) \, +#define Z_IS_2982_EQ_2982(...) \, +#define Z_IS_2982U_EQ_2982(...) \, +#define Z_IS_2982_EQ_2982U(...) \, +#define Z_IS_2982U_EQ_2982U(...) \, +#define Z_IS_2983_EQ_2983(...) \, +#define Z_IS_2983U_EQ_2983(...) \, +#define Z_IS_2983_EQ_2983U(...) \, +#define Z_IS_2983U_EQ_2983U(...) \, +#define Z_IS_2984_EQ_2984(...) \, +#define Z_IS_2984U_EQ_2984(...) \, +#define Z_IS_2984_EQ_2984U(...) \, +#define Z_IS_2984U_EQ_2984U(...) \, +#define Z_IS_2985_EQ_2985(...) \, +#define Z_IS_2985U_EQ_2985(...) \, +#define Z_IS_2985_EQ_2985U(...) \, +#define Z_IS_2985U_EQ_2985U(...) \, +#define Z_IS_2986_EQ_2986(...) \, +#define Z_IS_2986U_EQ_2986(...) \, +#define Z_IS_2986_EQ_2986U(...) \, +#define Z_IS_2986U_EQ_2986U(...) \, +#define Z_IS_2987_EQ_2987(...) \, +#define Z_IS_2987U_EQ_2987(...) \, +#define Z_IS_2987_EQ_2987U(...) \, +#define Z_IS_2987U_EQ_2987U(...) \, +#define Z_IS_2988_EQ_2988(...) \, +#define Z_IS_2988U_EQ_2988(...) \, +#define Z_IS_2988_EQ_2988U(...) \, +#define Z_IS_2988U_EQ_2988U(...) \, +#define Z_IS_2989_EQ_2989(...) \, +#define Z_IS_2989U_EQ_2989(...) \, +#define Z_IS_2989_EQ_2989U(...) \, +#define Z_IS_2989U_EQ_2989U(...) \, +#define Z_IS_2990_EQ_2990(...) \, +#define Z_IS_2990U_EQ_2990(...) \, +#define Z_IS_2990_EQ_2990U(...) \, +#define Z_IS_2990U_EQ_2990U(...) \, +#define Z_IS_2991_EQ_2991(...) \, +#define Z_IS_2991U_EQ_2991(...) \, +#define Z_IS_2991_EQ_2991U(...) \, +#define Z_IS_2991U_EQ_2991U(...) \, +#define Z_IS_2992_EQ_2992(...) \, +#define Z_IS_2992U_EQ_2992(...) \, +#define Z_IS_2992_EQ_2992U(...) \, +#define Z_IS_2992U_EQ_2992U(...) \, +#define Z_IS_2993_EQ_2993(...) \, +#define Z_IS_2993U_EQ_2993(...) \, +#define Z_IS_2993_EQ_2993U(...) \, +#define Z_IS_2993U_EQ_2993U(...) \, +#define Z_IS_2994_EQ_2994(...) \, +#define Z_IS_2994U_EQ_2994(...) \, +#define Z_IS_2994_EQ_2994U(...) \, +#define Z_IS_2994U_EQ_2994U(...) \, +#define Z_IS_2995_EQ_2995(...) \, +#define Z_IS_2995U_EQ_2995(...) \, +#define Z_IS_2995_EQ_2995U(...) \, +#define Z_IS_2995U_EQ_2995U(...) \, +#define Z_IS_2996_EQ_2996(...) \, +#define Z_IS_2996U_EQ_2996(...) \, +#define Z_IS_2996_EQ_2996U(...) \, +#define Z_IS_2996U_EQ_2996U(...) \, +#define Z_IS_2997_EQ_2997(...) \, +#define Z_IS_2997U_EQ_2997(...) \, +#define Z_IS_2997_EQ_2997U(...) \, +#define Z_IS_2997U_EQ_2997U(...) \, +#define Z_IS_2998_EQ_2998(...) \, +#define Z_IS_2998U_EQ_2998(...) \, +#define Z_IS_2998_EQ_2998U(...) \, +#define Z_IS_2998U_EQ_2998U(...) \, +#define Z_IS_2999_EQ_2999(...) \, +#define Z_IS_2999U_EQ_2999(...) \, +#define Z_IS_2999_EQ_2999U(...) \, +#define Z_IS_2999U_EQ_2999U(...) \, +#define Z_IS_3000_EQ_3000(...) \, +#define Z_IS_3000U_EQ_3000(...) \, +#define Z_IS_3000_EQ_3000U(...) \, +#define Z_IS_3000U_EQ_3000U(...) \, +#define Z_IS_3001_EQ_3001(...) \, +#define Z_IS_3001U_EQ_3001(...) \, +#define Z_IS_3001_EQ_3001U(...) \, +#define Z_IS_3001U_EQ_3001U(...) \, +#define Z_IS_3002_EQ_3002(...) \, +#define Z_IS_3002U_EQ_3002(...) \, +#define Z_IS_3002_EQ_3002U(...) \, +#define Z_IS_3002U_EQ_3002U(...) \, +#define Z_IS_3003_EQ_3003(...) \, +#define Z_IS_3003U_EQ_3003(...) \, +#define Z_IS_3003_EQ_3003U(...) \, +#define Z_IS_3003U_EQ_3003U(...) \, +#define Z_IS_3004_EQ_3004(...) \, +#define Z_IS_3004U_EQ_3004(...) \, +#define Z_IS_3004_EQ_3004U(...) \, +#define Z_IS_3004U_EQ_3004U(...) \, +#define Z_IS_3005_EQ_3005(...) \, +#define Z_IS_3005U_EQ_3005(...) \, +#define Z_IS_3005_EQ_3005U(...) \, +#define Z_IS_3005U_EQ_3005U(...) \, +#define Z_IS_3006_EQ_3006(...) \, +#define Z_IS_3006U_EQ_3006(...) \, +#define Z_IS_3006_EQ_3006U(...) \, +#define Z_IS_3006U_EQ_3006U(...) \, +#define Z_IS_3007_EQ_3007(...) \, +#define Z_IS_3007U_EQ_3007(...) \, +#define Z_IS_3007_EQ_3007U(...) \, +#define Z_IS_3007U_EQ_3007U(...) \, +#define Z_IS_3008_EQ_3008(...) \, +#define Z_IS_3008U_EQ_3008(...) \, +#define Z_IS_3008_EQ_3008U(...) \, +#define Z_IS_3008U_EQ_3008U(...) \, +#define Z_IS_3009_EQ_3009(...) \, +#define Z_IS_3009U_EQ_3009(...) \, +#define Z_IS_3009_EQ_3009U(...) \, +#define Z_IS_3009U_EQ_3009U(...) \, +#define Z_IS_3010_EQ_3010(...) \, +#define Z_IS_3010U_EQ_3010(...) \, +#define Z_IS_3010_EQ_3010U(...) \, +#define Z_IS_3010U_EQ_3010U(...) \, +#define Z_IS_3011_EQ_3011(...) \, +#define Z_IS_3011U_EQ_3011(...) \, +#define Z_IS_3011_EQ_3011U(...) \, +#define Z_IS_3011U_EQ_3011U(...) \, +#define Z_IS_3012_EQ_3012(...) \, +#define Z_IS_3012U_EQ_3012(...) \, +#define Z_IS_3012_EQ_3012U(...) \, +#define Z_IS_3012U_EQ_3012U(...) \, +#define Z_IS_3013_EQ_3013(...) \, +#define Z_IS_3013U_EQ_3013(...) \, +#define Z_IS_3013_EQ_3013U(...) \, +#define Z_IS_3013U_EQ_3013U(...) \, +#define Z_IS_3014_EQ_3014(...) \, +#define Z_IS_3014U_EQ_3014(...) \, +#define Z_IS_3014_EQ_3014U(...) \, +#define Z_IS_3014U_EQ_3014U(...) \, +#define Z_IS_3015_EQ_3015(...) \, +#define Z_IS_3015U_EQ_3015(...) \, +#define Z_IS_3015_EQ_3015U(...) \, +#define Z_IS_3015U_EQ_3015U(...) \, +#define Z_IS_3016_EQ_3016(...) \, +#define Z_IS_3016U_EQ_3016(...) \, +#define Z_IS_3016_EQ_3016U(...) \, +#define Z_IS_3016U_EQ_3016U(...) \, +#define Z_IS_3017_EQ_3017(...) \, +#define Z_IS_3017U_EQ_3017(...) \, +#define Z_IS_3017_EQ_3017U(...) \, +#define Z_IS_3017U_EQ_3017U(...) \, +#define Z_IS_3018_EQ_3018(...) \, +#define Z_IS_3018U_EQ_3018(...) \, +#define Z_IS_3018_EQ_3018U(...) \, +#define Z_IS_3018U_EQ_3018U(...) \, +#define Z_IS_3019_EQ_3019(...) \, +#define Z_IS_3019U_EQ_3019(...) \, +#define Z_IS_3019_EQ_3019U(...) \, +#define Z_IS_3019U_EQ_3019U(...) \, +#define Z_IS_3020_EQ_3020(...) \, +#define Z_IS_3020U_EQ_3020(...) \, +#define Z_IS_3020_EQ_3020U(...) \, +#define Z_IS_3020U_EQ_3020U(...) \, +#define Z_IS_3021_EQ_3021(...) \, +#define Z_IS_3021U_EQ_3021(...) \, +#define Z_IS_3021_EQ_3021U(...) \, +#define Z_IS_3021U_EQ_3021U(...) \, +#define Z_IS_3022_EQ_3022(...) \, +#define Z_IS_3022U_EQ_3022(...) \, +#define Z_IS_3022_EQ_3022U(...) \, +#define Z_IS_3022U_EQ_3022U(...) \, +#define Z_IS_3023_EQ_3023(...) \, +#define Z_IS_3023U_EQ_3023(...) \, +#define Z_IS_3023_EQ_3023U(...) \, +#define Z_IS_3023U_EQ_3023U(...) \, +#define Z_IS_3024_EQ_3024(...) \, +#define Z_IS_3024U_EQ_3024(...) \, +#define Z_IS_3024_EQ_3024U(...) \, +#define Z_IS_3024U_EQ_3024U(...) \, +#define Z_IS_3025_EQ_3025(...) \, +#define Z_IS_3025U_EQ_3025(...) \, +#define Z_IS_3025_EQ_3025U(...) \, +#define Z_IS_3025U_EQ_3025U(...) \, +#define Z_IS_3026_EQ_3026(...) \, +#define Z_IS_3026U_EQ_3026(...) \, +#define Z_IS_3026_EQ_3026U(...) \, +#define Z_IS_3026U_EQ_3026U(...) \, +#define Z_IS_3027_EQ_3027(...) \, +#define Z_IS_3027U_EQ_3027(...) \, +#define Z_IS_3027_EQ_3027U(...) \, +#define Z_IS_3027U_EQ_3027U(...) \, +#define Z_IS_3028_EQ_3028(...) \, +#define Z_IS_3028U_EQ_3028(...) \, +#define Z_IS_3028_EQ_3028U(...) \, +#define Z_IS_3028U_EQ_3028U(...) \, +#define Z_IS_3029_EQ_3029(...) \, +#define Z_IS_3029U_EQ_3029(...) \, +#define Z_IS_3029_EQ_3029U(...) \, +#define Z_IS_3029U_EQ_3029U(...) \, +#define Z_IS_3030_EQ_3030(...) \, +#define Z_IS_3030U_EQ_3030(...) \, +#define Z_IS_3030_EQ_3030U(...) \, +#define Z_IS_3030U_EQ_3030U(...) \, +#define Z_IS_3031_EQ_3031(...) \, +#define Z_IS_3031U_EQ_3031(...) \, +#define Z_IS_3031_EQ_3031U(...) \, +#define Z_IS_3031U_EQ_3031U(...) \, +#define Z_IS_3032_EQ_3032(...) \, +#define Z_IS_3032U_EQ_3032(...) \, +#define Z_IS_3032_EQ_3032U(...) \, +#define Z_IS_3032U_EQ_3032U(...) \, +#define Z_IS_3033_EQ_3033(...) \, +#define Z_IS_3033U_EQ_3033(...) \, +#define Z_IS_3033_EQ_3033U(...) \, +#define Z_IS_3033U_EQ_3033U(...) \, +#define Z_IS_3034_EQ_3034(...) \, +#define Z_IS_3034U_EQ_3034(...) \, +#define Z_IS_3034_EQ_3034U(...) \, +#define Z_IS_3034U_EQ_3034U(...) \, +#define Z_IS_3035_EQ_3035(...) \, +#define Z_IS_3035U_EQ_3035(...) \, +#define Z_IS_3035_EQ_3035U(...) \, +#define Z_IS_3035U_EQ_3035U(...) \, +#define Z_IS_3036_EQ_3036(...) \, +#define Z_IS_3036U_EQ_3036(...) \, +#define Z_IS_3036_EQ_3036U(...) \, +#define Z_IS_3036U_EQ_3036U(...) \, +#define Z_IS_3037_EQ_3037(...) \, +#define Z_IS_3037U_EQ_3037(...) \, +#define Z_IS_3037_EQ_3037U(...) \, +#define Z_IS_3037U_EQ_3037U(...) \, +#define Z_IS_3038_EQ_3038(...) \, +#define Z_IS_3038U_EQ_3038(...) \, +#define Z_IS_3038_EQ_3038U(...) \, +#define Z_IS_3038U_EQ_3038U(...) \, +#define Z_IS_3039_EQ_3039(...) \, +#define Z_IS_3039U_EQ_3039(...) \, +#define Z_IS_3039_EQ_3039U(...) \, +#define Z_IS_3039U_EQ_3039U(...) \, +#define Z_IS_3040_EQ_3040(...) \, +#define Z_IS_3040U_EQ_3040(...) \, +#define Z_IS_3040_EQ_3040U(...) \, +#define Z_IS_3040U_EQ_3040U(...) \, +#define Z_IS_3041_EQ_3041(...) \, +#define Z_IS_3041U_EQ_3041(...) \, +#define Z_IS_3041_EQ_3041U(...) \, +#define Z_IS_3041U_EQ_3041U(...) \, +#define Z_IS_3042_EQ_3042(...) \, +#define Z_IS_3042U_EQ_3042(...) \, +#define Z_IS_3042_EQ_3042U(...) \, +#define Z_IS_3042U_EQ_3042U(...) \, +#define Z_IS_3043_EQ_3043(...) \, +#define Z_IS_3043U_EQ_3043(...) \, +#define Z_IS_3043_EQ_3043U(...) \, +#define Z_IS_3043U_EQ_3043U(...) \, +#define Z_IS_3044_EQ_3044(...) \, +#define Z_IS_3044U_EQ_3044(...) \, +#define Z_IS_3044_EQ_3044U(...) \, +#define Z_IS_3044U_EQ_3044U(...) \, +#define Z_IS_3045_EQ_3045(...) \, +#define Z_IS_3045U_EQ_3045(...) \, +#define Z_IS_3045_EQ_3045U(...) \, +#define Z_IS_3045U_EQ_3045U(...) \, +#define Z_IS_3046_EQ_3046(...) \, +#define Z_IS_3046U_EQ_3046(...) \, +#define Z_IS_3046_EQ_3046U(...) \, +#define Z_IS_3046U_EQ_3046U(...) \, +#define Z_IS_3047_EQ_3047(...) \, +#define Z_IS_3047U_EQ_3047(...) \, +#define Z_IS_3047_EQ_3047U(...) \, +#define Z_IS_3047U_EQ_3047U(...) \, +#define Z_IS_3048_EQ_3048(...) \, +#define Z_IS_3048U_EQ_3048(...) \, +#define Z_IS_3048_EQ_3048U(...) \, +#define Z_IS_3048U_EQ_3048U(...) \, +#define Z_IS_3049_EQ_3049(...) \, +#define Z_IS_3049U_EQ_3049(...) \, +#define Z_IS_3049_EQ_3049U(...) \, +#define Z_IS_3049U_EQ_3049U(...) \, +#define Z_IS_3050_EQ_3050(...) \, +#define Z_IS_3050U_EQ_3050(...) \, +#define Z_IS_3050_EQ_3050U(...) \, +#define Z_IS_3050U_EQ_3050U(...) \, +#define Z_IS_3051_EQ_3051(...) \, +#define Z_IS_3051U_EQ_3051(...) \, +#define Z_IS_3051_EQ_3051U(...) \, +#define Z_IS_3051U_EQ_3051U(...) \, +#define Z_IS_3052_EQ_3052(...) \, +#define Z_IS_3052U_EQ_3052(...) \, +#define Z_IS_3052_EQ_3052U(...) \, +#define Z_IS_3052U_EQ_3052U(...) \, +#define Z_IS_3053_EQ_3053(...) \, +#define Z_IS_3053U_EQ_3053(...) \, +#define Z_IS_3053_EQ_3053U(...) \, +#define Z_IS_3053U_EQ_3053U(...) \, +#define Z_IS_3054_EQ_3054(...) \, +#define Z_IS_3054U_EQ_3054(...) \, +#define Z_IS_3054_EQ_3054U(...) \, +#define Z_IS_3054U_EQ_3054U(...) \, +#define Z_IS_3055_EQ_3055(...) \, +#define Z_IS_3055U_EQ_3055(...) \, +#define Z_IS_3055_EQ_3055U(...) \, +#define Z_IS_3055U_EQ_3055U(...) \, +#define Z_IS_3056_EQ_3056(...) \, +#define Z_IS_3056U_EQ_3056(...) \, +#define Z_IS_3056_EQ_3056U(...) \, +#define Z_IS_3056U_EQ_3056U(...) \, +#define Z_IS_3057_EQ_3057(...) \, +#define Z_IS_3057U_EQ_3057(...) \, +#define Z_IS_3057_EQ_3057U(...) \, +#define Z_IS_3057U_EQ_3057U(...) \, +#define Z_IS_3058_EQ_3058(...) \, +#define Z_IS_3058U_EQ_3058(...) \, +#define Z_IS_3058_EQ_3058U(...) \, +#define Z_IS_3058U_EQ_3058U(...) \, +#define Z_IS_3059_EQ_3059(...) \, +#define Z_IS_3059U_EQ_3059(...) \, +#define Z_IS_3059_EQ_3059U(...) \, +#define Z_IS_3059U_EQ_3059U(...) \, +#define Z_IS_3060_EQ_3060(...) \, +#define Z_IS_3060U_EQ_3060(...) \, +#define Z_IS_3060_EQ_3060U(...) \, +#define Z_IS_3060U_EQ_3060U(...) \, +#define Z_IS_3061_EQ_3061(...) \, +#define Z_IS_3061U_EQ_3061(...) \, +#define Z_IS_3061_EQ_3061U(...) \, +#define Z_IS_3061U_EQ_3061U(...) \, +#define Z_IS_3062_EQ_3062(...) \, +#define Z_IS_3062U_EQ_3062(...) \, +#define Z_IS_3062_EQ_3062U(...) \, +#define Z_IS_3062U_EQ_3062U(...) \, +#define Z_IS_3063_EQ_3063(...) \, +#define Z_IS_3063U_EQ_3063(...) \, +#define Z_IS_3063_EQ_3063U(...) \, +#define Z_IS_3063U_EQ_3063U(...) \, +#define Z_IS_3064_EQ_3064(...) \, +#define Z_IS_3064U_EQ_3064(...) \, +#define Z_IS_3064_EQ_3064U(...) \, +#define Z_IS_3064U_EQ_3064U(...) \, +#define Z_IS_3065_EQ_3065(...) \, +#define Z_IS_3065U_EQ_3065(...) \, +#define Z_IS_3065_EQ_3065U(...) \, +#define Z_IS_3065U_EQ_3065U(...) \, +#define Z_IS_3066_EQ_3066(...) \, +#define Z_IS_3066U_EQ_3066(...) \, +#define Z_IS_3066_EQ_3066U(...) \, +#define Z_IS_3066U_EQ_3066U(...) \, +#define Z_IS_3067_EQ_3067(...) \, +#define Z_IS_3067U_EQ_3067(...) \, +#define Z_IS_3067_EQ_3067U(...) \, +#define Z_IS_3067U_EQ_3067U(...) \, +#define Z_IS_3068_EQ_3068(...) \, +#define Z_IS_3068U_EQ_3068(...) \, +#define Z_IS_3068_EQ_3068U(...) \, +#define Z_IS_3068U_EQ_3068U(...) \, +#define Z_IS_3069_EQ_3069(...) \, +#define Z_IS_3069U_EQ_3069(...) \, +#define Z_IS_3069_EQ_3069U(...) \, +#define Z_IS_3069U_EQ_3069U(...) \, +#define Z_IS_3070_EQ_3070(...) \, +#define Z_IS_3070U_EQ_3070(...) \, +#define Z_IS_3070_EQ_3070U(...) \, +#define Z_IS_3070U_EQ_3070U(...) \, +#define Z_IS_3071_EQ_3071(...) \, +#define Z_IS_3071U_EQ_3071(...) \, +#define Z_IS_3071_EQ_3071U(...) \, +#define Z_IS_3071U_EQ_3071U(...) \, +#define Z_IS_3072_EQ_3072(...) \, +#define Z_IS_3072U_EQ_3072(...) \, +#define Z_IS_3072_EQ_3072U(...) \, +#define Z_IS_3072U_EQ_3072U(...) \, +#define Z_IS_3073_EQ_3073(...) \, +#define Z_IS_3073U_EQ_3073(...) \, +#define Z_IS_3073_EQ_3073U(...) \, +#define Z_IS_3073U_EQ_3073U(...) \, +#define Z_IS_3074_EQ_3074(...) \, +#define Z_IS_3074U_EQ_3074(...) \, +#define Z_IS_3074_EQ_3074U(...) \, +#define Z_IS_3074U_EQ_3074U(...) \, +#define Z_IS_3075_EQ_3075(...) \, +#define Z_IS_3075U_EQ_3075(...) \, +#define Z_IS_3075_EQ_3075U(...) \, +#define Z_IS_3075U_EQ_3075U(...) \, +#define Z_IS_3076_EQ_3076(...) \, +#define Z_IS_3076U_EQ_3076(...) \, +#define Z_IS_3076_EQ_3076U(...) \, +#define Z_IS_3076U_EQ_3076U(...) \, +#define Z_IS_3077_EQ_3077(...) \, +#define Z_IS_3077U_EQ_3077(...) \, +#define Z_IS_3077_EQ_3077U(...) \, +#define Z_IS_3077U_EQ_3077U(...) \, +#define Z_IS_3078_EQ_3078(...) \, +#define Z_IS_3078U_EQ_3078(...) \, +#define Z_IS_3078_EQ_3078U(...) \, +#define Z_IS_3078U_EQ_3078U(...) \, +#define Z_IS_3079_EQ_3079(...) \, +#define Z_IS_3079U_EQ_3079(...) \, +#define Z_IS_3079_EQ_3079U(...) \, +#define Z_IS_3079U_EQ_3079U(...) \, +#define Z_IS_3080_EQ_3080(...) \, +#define Z_IS_3080U_EQ_3080(...) \, +#define Z_IS_3080_EQ_3080U(...) \, +#define Z_IS_3080U_EQ_3080U(...) \, +#define Z_IS_3081_EQ_3081(...) \, +#define Z_IS_3081U_EQ_3081(...) \, +#define Z_IS_3081_EQ_3081U(...) \, +#define Z_IS_3081U_EQ_3081U(...) \, +#define Z_IS_3082_EQ_3082(...) \, +#define Z_IS_3082U_EQ_3082(...) \, +#define Z_IS_3082_EQ_3082U(...) \, +#define Z_IS_3082U_EQ_3082U(...) \, +#define Z_IS_3083_EQ_3083(...) \, +#define Z_IS_3083U_EQ_3083(...) \, +#define Z_IS_3083_EQ_3083U(...) \, +#define Z_IS_3083U_EQ_3083U(...) \, +#define Z_IS_3084_EQ_3084(...) \, +#define Z_IS_3084U_EQ_3084(...) \, +#define Z_IS_3084_EQ_3084U(...) \, +#define Z_IS_3084U_EQ_3084U(...) \, +#define Z_IS_3085_EQ_3085(...) \, +#define Z_IS_3085U_EQ_3085(...) \, +#define Z_IS_3085_EQ_3085U(...) \, +#define Z_IS_3085U_EQ_3085U(...) \, +#define Z_IS_3086_EQ_3086(...) \, +#define Z_IS_3086U_EQ_3086(...) \, +#define Z_IS_3086_EQ_3086U(...) \, +#define Z_IS_3086U_EQ_3086U(...) \, +#define Z_IS_3087_EQ_3087(...) \, +#define Z_IS_3087U_EQ_3087(...) \, +#define Z_IS_3087_EQ_3087U(...) \, +#define Z_IS_3087U_EQ_3087U(...) \, +#define Z_IS_3088_EQ_3088(...) \, +#define Z_IS_3088U_EQ_3088(...) \, +#define Z_IS_3088_EQ_3088U(...) \, +#define Z_IS_3088U_EQ_3088U(...) \, +#define Z_IS_3089_EQ_3089(...) \, +#define Z_IS_3089U_EQ_3089(...) \, +#define Z_IS_3089_EQ_3089U(...) \, +#define Z_IS_3089U_EQ_3089U(...) \, +#define Z_IS_3090_EQ_3090(...) \, +#define Z_IS_3090U_EQ_3090(...) \, +#define Z_IS_3090_EQ_3090U(...) \, +#define Z_IS_3090U_EQ_3090U(...) \, +#define Z_IS_3091_EQ_3091(...) \, +#define Z_IS_3091U_EQ_3091(...) \, +#define Z_IS_3091_EQ_3091U(...) \, +#define Z_IS_3091U_EQ_3091U(...) \, +#define Z_IS_3092_EQ_3092(...) \, +#define Z_IS_3092U_EQ_3092(...) \, +#define Z_IS_3092_EQ_3092U(...) \, +#define Z_IS_3092U_EQ_3092U(...) \, +#define Z_IS_3093_EQ_3093(...) \, +#define Z_IS_3093U_EQ_3093(...) \, +#define Z_IS_3093_EQ_3093U(...) \, +#define Z_IS_3093U_EQ_3093U(...) \, +#define Z_IS_3094_EQ_3094(...) \, +#define Z_IS_3094U_EQ_3094(...) \, +#define Z_IS_3094_EQ_3094U(...) \, +#define Z_IS_3094U_EQ_3094U(...) \, +#define Z_IS_3095_EQ_3095(...) \, +#define Z_IS_3095U_EQ_3095(...) \, +#define Z_IS_3095_EQ_3095U(...) \, +#define Z_IS_3095U_EQ_3095U(...) \, +#define Z_IS_3096_EQ_3096(...) \, +#define Z_IS_3096U_EQ_3096(...) \, +#define Z_IS_3096_EQ_3096U(...) \, +#define Z_IS_3096U_EQ_3096U(...) \, +#define Z_IS_3097_EQ_3097(...) \, +#define Z_IS_3097U_EQ_3097(...) \, +#define Z_IS_3097_EQ_3097U(...) \, +#define Z_IS_3097U_EQ_3097U(...) \, +#define Z_IS_3098_EQ_3098(...) \, +#define Z_IS_3098U_EQ_3098(...) \, +#define Z_IS_3098_EQ_3098U(...) \, +#define Z_IS_3098U_EQ_3098U(...) \, +#define Z_IS_3099_EQ_3099(...) \, +#define Z_IS_3099U_EQ_3099(...) \, +#define Z_IS_3099_EQ_3099U(...) \, +#define Z_IS_3099U_EQ_3099U(...) \, +#define Z_IS_3100_EQ_3100(...) \, +#define Z_IS_3100U_EQ_3100(...) \, +#define Z_IS_3100_EQ_3100U(...) \, +#define Z_IS_3100U_EQ_3100U(...) \, +#define Z_IS_3101_EQ_3101(...) \, +#define Z_IS_3101U_EQ_3101(...) \, +#define Z_IS_3101_EQ_3101U(...) \, +#define Z_IS_3101U_EQ_3101U(...) \, +#define Z_IS_3102_EQ_3102(...) \, +#define Z_IS_3102U_EQ_3102(...) \, +#define Z_IS_3102_EQ_3102U(...) \, +#define Z_IS_3102U_EQ_3102U(...) \, +#define Z_IS_3103_EQ_3103(...) \, +#define Z_IS_3103U_EQ_3103(...) \, +#define Z_IS_3103_EQ_3103U(...) \, +#define Z_IS_3103U_EQ_3103U(...) \, +#define Z_IS_3104_EQ_3104(...) \, +#define Z_IS_3104U_EQ_3104(...) \, +#define Z_IS_3104_EQ_3104U(...) \, +#define Z_IS_3104U_EQ_3104U(...) \, +#define Z_IS_3105_EQ_3105(...) \, +#define Z_IS_3105U_EQ_3105(...) \, +#define Z_IS_3105_EQ_3105U(...) \, +#define Z_IS_3105U_EQ_3105U(...) \, +#define Z_IS_3106_EQ_3106(...) \, +#define Z_IS_3106U_EQ_3106(...) \, +#define Z_IS_3106_EQ_3106U(...) \, +#define Z_IS_3106U_EQ_3106U(...) \, +#define Z_IS_3107_EQ_3107(...) \, +#define Z_IS_3107U_EQ_3107(...) \, +#define Z_IS_3107_EQ_3107U(...) \, +#define Z_IS_3107U_EQ_3107U(...) \, +#define Z_IS_3108_EQ_3108(...) \, +#define Z_IS_3108U_EQ_3108(...) \, +#define Z_IS_3108_EQ_3108U(...) \, +#define Z_IS_3108U_EQ_3108U(...) \, +#define Z_IS_3109_EQ_3109(...) \, +#define Z_IS_3109U_EQ_3109(...) \, +#define Z_IS_3109_EQ_3109U(...) \, +#define Z_IS_3109U_EQ_3109U(...) \, +#define Z_IS_3110_EQ_3110(...) \, +#define Z_IS_3110U_EQ_3110(...) \, +#define Z_IS_3110_EQ_3110U(...) \, +#define Z_IS_3110U_EQ_3110U(...) \, +#define Z_IS_3111_EQ_3111(...) \, +#define Z_IS_3111U_EQ_3111(...) \, +#define Z_IS_3111_EQ_3111U(...) \, +#define Z_IS_3111U_EQ_3111U(...) \, +#define Z_IS_3112_EQ_3112(...) \, +#define Z_IS_3112U_EQ_3112(...) \, +#define Z_IS_3112_EQ_3112U(...) \, +#define Z_IS_3112U_EQ_3112U(...) \, +#define Z_IS_3113_EQ_3113(...) \, +#define Z_IS_3113U_EQ_3113(...) \, +#define Z_IS_3113_EQ_3113U(...) \, +#define Z_IS_3113U_EQ_3113U(...) \, +#define Z_IS_3114_EQ_3114(...) \, +#define Z_IS_3114U_EQ_3114(...) \, +#define Z_IS_3114_EQ_3114U(...) \, +#define Z_IS_3114U_EQ_3114U(...) \, +#define Z_IS_3115_EQ_3115(...) \, +#define Z_IS_3115U_EQ_3115(...) \, +#define Z_IS_3115_EQ_3115U(...) \, +#define Z_IS_3115U_EQ_3115U(...) \, +#define Z_IS_3116_EQ_3116(...) \, +#define Z_IS_3116U_EQ_3116(...) \, +#define Z_IS_3116_EQ_3116U(...) \, +#define Z_IS_3116U_EQ_3116U(...) \, +#define Z_IS_3117_EQ_3117(...) \, +#define Z_IS_3117U_EQ_3117(...) \, +#define Z_IS_3117_EQ_3117U(...) \, +#define Z_IS_3117U_EQ_3117U(...) \, +#define Z_IS_3118_EQ_3118(...) \, +#define Z_IS_3118U_EQ_3118(...) \, +#define Z_IS_3118_EQ_3118U(...) \, +#define Z_IS_3118U_EQ_3118U(...) \, +#define Z_IS_3119_EQ_3119(...) \, +#define Z_IS_3119U_EQ_3119(...) \, +#define Z_IS_3119_EQ_3119U(...) \, +#define Z_IS_3119U_EQ_3119U(...) \, +#define Z_IS_3120_EQ_3120(...) \, +#define Z_IS_3120U_EQ_3120(...) \, +#define Z_IS_3120_EQ_3120U(...) \, +#define Z_IS_3120U_EQ_3120U(...) \, +#define Z_IS_3121_EQ_3121(...) \, +#define Z_IS_3121U_EQ_3121(...) \, +#define Z_IS_3121_EQ_3121U(...) \, +#define Z_IS_3121U_EQ_3121U(...) \, +#define Z_IS_3122_EQ_3122(...) \, +#define Z_IS_3122U_EQ_3122(...) \, +#define Z_IS_3122_EQ_3122U(...) \, +#define Z_IS_3122U_EQ_3122U(...) \, +#define Z_IS_3123_EQ_3123(...) \, +#define Z_IS_3123U_EQ_3123(...) \, +#define Z_IS_3123_EQ_3123U(...) \, +#define Z_IS_3123U_EQ_3123U(...) \, +#define Z_IS_3124_EQ_3124(...) \, +#define Z_IS_3124U_EQ_3124(...) \, +#define Z_IS_3124_EQ_3124U(...) \, +#define Z_IS_3124U_EQ_3124U(...) \, +#define Z_IS_3125_EQ_3125(...) \, +#define Z_IS_3125U_EQ_3125(...) \, +#define Z_IS_3125_EQ_3125U(...) \, +#define Z_IS_3125U_EQ_3125U(...) \, +#define Z_IS_3126_EQ_3126(...) \, +#define Z_IS_3126U_EQ_3126(...) \, +#define Z_IS_3126_EQ_3126U(...) \, +#define Z_IS_3126U_EQ_3126U(...) \, +#define Z_IS_3127_EQ_3127(...) \, +#define Z_IS_3127U_EQ_3127(...) \, +#define Z_IS_3127_EQ_3127U(...) \, +#define Z_IS_3127U_EQ_3127U(...) \, +#define Z_IS_3128_EQ_3128(...) \, +#define Z_IS_3128U_EQ_3128(...) \, +#define Z_IS_3128_EQ_3128U(...) \, +#define Z_IS_3128U_EQ_3128U(...) \, +#define Z_IS_3129_EQ_3129(...) \, +#define Z_IS_3129U_EQ_3129(...) \, +#define Z_IS_3129_EQ_3129U(...) \, +#define Z_IS_3129U_EQ_3129U(...) \, +#define Z_IS_3130_EQ_3130(...) \, +#define Z_IS_3130U_EQ_3130(...) \, +#define Z_IS_3130_EQ_3130U(...) \, +#define Z_IS_3130U_EQ_3130U(...) \, +#define Z_IS_3131_EQ_3131(...) \, +#define Z_IS_3131U_EQ_3131(...) \, +#define Z_IS_3131_EQ_3131U(...) \, +#define Z_IS_3131U_EQ_3131U(...) \, +#define Z_IS_3132_EQ_3132(...) \, +#define Z_IS_3132U_EQ_3132(...) \, +#define Z_IS_3132_EQ_3132U(...) \, +#define Z_IS_3132U_EQ_3132U(...) \, +#define Z_IS_3133_EQ_3133(...) \, +#define Z_IS_3133U_EQ_3133(...) \, +#define Z_IS_3133_EQ_3133U(...) \, +#define Z_IS_3133U_EQ_3133U(...) \, +#define Z_IS_3134_EQ_3134(...) \, +#define Z_IS_3134U_EQ_3134(...) \, +#define Z_IS_3134_EQ_3134U(...) \, +#define Z_IS_3134U_EQ_3134U(...) \, +#define Z_IS_3135_EQ_3135(...) \, +#define Z_IS_3135U_EQ_3135(...) \, +#define Z_IS_3135_EQ_3135U(...) \, +#define Z_IS_3135U_EQ_3135U(...) \, +#define Z_IS_3136_EQ_3136(...) \, +#define Z_IS_3136U_EQ_3136(...) \, +#define Z_IS_3136_EQ_3136U(...) \, +#define Z_IS_3136U_EQ_3136U(...) \, +#define Z_IS_3137_EQ_3137(...) \, +#define Z_IS_3137U_EQ_3137(...) \, +#define Z_IS_3137_EQ_3137U(...) \, +#define Z_IS_3137U_EQ_3137U(...) \, +#define Z_IS_3138_EQ_3138(...) \, +#define Z_IS_3138U_EQ_3138(...) \, +#define Z_IS_3138_EQ_3138U(...) \, +#define Z_IS_3138U_EQ_3138U(...) \, +#define Z_IS_3139_EQ_3139(...) \, +#define Z_IS_3139U_EQ_3139(...) \, +#define Z_IS_3139_EQ_3139U(...) \, +#define Z_IS_3139U_EQ_3139U(...) \, +#define Z_IS_3140_EQ_3140(...) \, +#define Z_IS_3140U_EQ_3140(...) \, +#define Z_IS_3140_EQ_3140U(...) \, +#define Z_IS_3140U_EQ_3140U(...) \, +#define Z_IS_3141_EQ_3141(...) \, +#define Z_IS_3141U_EQ_3141(...) \, +#define Z_IS_3141_EQ_3141U(...) \, +#define Z_IS_3141U_EQ_3141U(...) \, +#define Z_IS_3142_EQ_3142(...) \, +#define Z_IS_3142U_EQ_3142(...) \, +#define Z_IS_3142_EQ_3142U(...) \, +#define Z_IS_3142U_EQ_3142U(...) \, +#define Z_IS_3143_EQ_3143(...) \, +#define Z_IS_3143U_EQ_3143(...) \, +#define Z_IS_3143_EQ_3143U(...) \, +#define Z_IS_3143U_EQ_3143U(...) \, +#define Z_IS_3144_EQ_3144(...) \, +#define Z_IS_3144U_EQ_3144(...) \, +#define Z_IS_3144_EQ_3144U(...) \, +#define Z_IS_3144U_EQ_3144U(...) \, +#define Z_IS_3145_EQ_3145(...) \, +#define Z_IS_3145U_EQ_3145(...) \, +#define Z_IS_3145_EQ_3145U(...) \, +#define Z_IS_3145U_EQ_3145U(...) \, +#define Z_IS_3146_EQ_3146(...) \, +#define Z_IS_3146U_EQ_3146(...) \, +#define Z_IS_3146_EQ_3146U(...) \, +#define Z_IS_3146U_EQ_3146U(...) \, +#define Z_IS_3147_EQ_3147(...) \, +#define Z_IS_3147U_EQ_3147(...) \, +#define Z_IS_3147_EQ_3147U(...) \, +#define Z_IS_3147U_EQ_3147U(...) \, +#define Z_IS_3148_EQ_3148(...) \, +#define Z_IS_3148U_EQ_3148(...) \, +#define Z_IS_3148_EQ_3148U(...) \, +#define Z_IS_3148U_EQ_3148U(...) \, +#define Z_IS_3149_EQ_3149(...) \, +#define Z_IS_3149U_EQ_3149(...) \, +#define Z_IS_3149_EQ_3149U(...) \, +#define Z_IS_3149U_EQ_3149U(...) \, +#define Z_IS_3150_EQ_3150(...) \, +#define Z_IS_3150U_EQ_3150(...) \, +#define Z_IS_3150_EQ_3150U(...) \, +#define Z_IS_3150U_EQ_3150U(...) \, +#define Z_IS_3151_EQ_3151(...) \, +#define Z_IS_3151U_EQ_3151(...) \, +#define Z_IS_3151_EQ_3151U(...) \, +#define Z_IS_3151U_EQ_3151U(...) \, +#define Z_IS_3152_EQ_3152(...) \, +#define Z_IS_3152U_EQ_3152(...) \, +#define Z_IS_3152_EQ_3152U(...) \, +#define Z_IS_3152U_EQ_3152U(...) \, +#define Z_IS_3153_EQ_3153(...) \, +#define Z_IS_3153U_EQ_3153(...) \, +#define Z_IS_3153_EQ_3153U(...) \, +#define Z_IS_3153U_EQ_3153U(...) \, +#define Z_IS_3154_EQ_3154(...) \, +#define Z_IS_3154U_EQ_3154(...) \, +#define Z_IS_3154_EQ_3154U(...) \, +#define Z_IS_3154U_EQ_3154U(...) \, +#define Z_IS_3155_EQ_3155(...) \, +#define Z_IS_3155U_EQ_3155(...) \, +#define Z_IS_3155_EQ_3155U(...) \, +#define Z_IS_3155U_EQ_3155U(...) \, +#define Z_IS_3156_EQ_3156(...) \, +#define Z_IS_3156U_EQ_3156(...) \, +#define Z_IS_3156_EQ_3156U(...) \, +#define Z_IS_3156U_EQ_3156U(...) \, +#define Z_IS_3157_EQ_3157(...) \, +#define Z_IS_3157U_EQ_3157(...) \, +#define Z_IS_3157_EQ_3157U(...) \, +#define Z_IS_3157U_EQ_3157U(...) \, +#define Z_IS_3158_EQ_3158(...) \, +#define Z_IS_3158U_EQ_3158(...) \, +#define Z_IS_3158_EQ_3158U(...) \, +#define Z_IS_3158U_EQ_3158U(...) \, +#define Z_IS_3159_EQ_3159(...) \, +#define Z_IS_3159U_EQ_3159(...) \, +#define Z_IS_3159_EQ_3159U(...) \, +#define Z_IS_3159U_EQ_3159U(...) \, +#define Z_IS_3160_EQ_3160(...) \, +#define Z_IS_3160U_EQ_3160(...) \, +#define Z_IS_3160_EQ_3160U(...) \, +#define Z_IS_3160U_EQ_3160U(...) \, +#define Z_IS_3161_EQ_3161(...) \, +#define Z_IS_3161U_EQ_3161(...) \, +#define Z_IS_3161_EQ_3161U(...) \, +#define Z_IS_3161U_EQ_3161U(...) \, +#define Z_IS_3162_EQ_3162(...) \, +#define Z_IS_3162U_EQ_3162(...) \, +#define Z_IS_3162_EQ_3162U(...) \, +#define Z_IS_3162U_EQ_3162U(...) \, +#define Z_IS_3163_EQ_3163(...) \, +#define Z_IS_3163U_EQ_3163(...) \, +#define Z_IS_3163_EQ_3163U(...) \, +#define Z_IS_3163U_EQ_3163U(...) \, +#define Z_IS_3164_EQ_3164(...) \, +#define Z_IS_3164U_EQ_3164(...) \, +#define Z_IS_3164_EQ_3164U(...) \, +#define Z_IS_3164U_EQ_3164U(...) \, +#define Z_IS_3165_EQ_3165(...) \, +#define Z_IS_3165U_EQ_3165(...) \, +#define Z_IS_3165_EQ_3165U(...) \, +#define Z_IS_3165U_EQ_3165U(...) \, +#define Z_IS_3166_EQ_3166(...) \, +#define Z_IS_3166U_EQ_3166(...) \, +#define Z_IS_3166_EQ_3166U(...) \, +#define Z_IS_3166U_EQ_3166U(...) \, +#define Z_IS_3167_EQ_3167(...) \, +#define Z_IS_3167U_EQ_3167(...) \, +#define Z_IS_3167_EQ_3167U(...) \, +#define Z_IS_3167U_EQ_3167U(...) \, +#define Z_IS_3168_EQ_3168(...) \, +#define Z_IS_3168U_EQ_3168(...) \, +#define Z_IS_3168_EQ_3168U(...) \, +#define Z_IS_3168U_EQ_3168U(...) \, +#define Z_IS_3169_EQ_3169(...) \, +#define Z_IS_3169U_EQ_3169(...) \, +#define Z_IS_3169_EQ_3169U(...) \, +#define Z_IS_3169U_EQ_3169U(...) \, +#define Z_IS_3170_EQ_3170(...) \, +#define Z_IS_3170U_EQ_3170(...) \, +#define Z_IS_3170_EQ_3170U(...) \, +#define Z_IS_3170U_EQ_3170U(...) \, +#define Z_IS_3171_EQ_3171(...) \, +#define Z_IS_3171U_EQ_3171(...) \, +#define Z_IS_3171_EQ_3171U(...) \, +#define Z_IS_3171U_EQ_3171U(...) \, +#define Z_IS_3172_EQ_3172(...) \, +#define Z_IS_3172U_EQ_3172(...) \, +#define Z_IS_3172_EQ_3172U(...) \, +#define Z_IS_3172U_EQ_3172U(...) \, +#define Z_IS_3173_EQ_3173(...) \, +#define Z_IS_3173U_EQ_3173(...) \, +#define Z_IS_3173_EQ_3173U(...) \, +#define Z_IS_3173U_EQ_3173U(...) \, +#define Z_IS_3174_EQ_3174(...) \, +#define Z_IS_3174U_EQ_3174(...) \, +#define Z_IS_3174_EQ_3174U(...) \, +#define Z_IS_3174U_EQ_3174U(...) \, +#define Z_IS_3175_EQ_3175(...) \, +#define Z_IS_3175U_EQ_3175(...) \, +#define Z_IS_3175_EQ_3175U(...) \, +#define Z_IS_3175U_EQ_3175U(...) \, +#define Z_IS_3176_EQ_3176(...) \, +#define Z_IS_3176U_EQ_3176(...) \, +#define Z_IS_3176_EQ_3176U(...) \, +#define Z_IS_3176U_EQ_3176U(...) \, +#define Z_IS_3177_EQ_3177(...) \, +#define Z_IS_3177U_EQ_3177(...) \, +#define Z_IS_3177_EQ_3177U(...) \, +#define Z_IS_3177U_EQ_3177U(...) \, +#define Z_IS_3178_EQ_3178(...) \, +#define Z_IS_3178U_EQ_3178(...) \, +#define Z_IS_3178_EQ_3178U(...) \, +#define Z_IS_3178U_EQ_3178U(...) \, +#define Z_IS_3179_EQ_3179(...) \, +#define Z_IS_3179U_EQ_3179(...) \, +#define Z_IS_3179_EQ_3179U(...) \, +#define Z_IS_3179U_EQ_3179U(...) \, +#define Z_IS_3180_EQ_3180(...) \, +#define Z_IS_3180U_EQ_3180(...) \, +#define Z_IS_3180_EQ_3180U(...) \, +#define Z_IS_3180U_EQ_3180U(...) \, +#define Z_IS_3181_EQ_3181(...) \, +#define Z_IS_3181U_EQ_3181(...) \, +#define Z_IS_3181_EQ_3181U(...) \, +#define Z_IS_3181U_EQ_3181U(...) \, +#define Z_IS_3182_EQ_3182(...) \, +#define Z_IS_3182U_EQ_3182(...) \, +#define Z_IS_3182_EQ_3182U(...) \, +#define Z_IS_3182U_EQ_3182U(...) \, +#define Z_IS_3183_EQ_3183(...) \, +#define Z_IS_3183U_EQ_3183(...) \, +#define Z_IS_3183_EQ_3183U(...) \, +#define Z_IS_3183U_EQ_3183U(...) \, +#define Z_IS_3184_EQ_3184(...) \, +#define Z_IS_3184U_EQ_3184(...) \, +#define Z_IS_3184_EQ_3184U(...) \, +#define Z_IS_3184U_EQ_3184U(...) \, +#define Z_IS_3185_EQ_3185(...) \, +#define Z_IS_3185U_EQ_3185(...) \, +#define Z_IS_3185_EQ_3185U(...) \, +#define Z_IS_3185U_EQ_3185U(...) \, +#define Z_IS_3186_EQ_3186(...) \, +#define Z_IS_3186U_EQ_3186(...) \, +#define Z_IS_3186_EQ_3186U(...) \, +#define Z_IS_3186U_EQ_3186U(...) \, +#define Z_IS_3187_EQ_3187(...) \, +#define Z_IS_3187U_EQ_3187(...) \, +#define Z_IS_3187_EQ_3187U(...) \, +#define Z_IS_3187U_EQ_3187U(...) \, +#define Z_IS_3188_EQ_3188(...) \, +#define Z_IS_3188U_EQ_3188(...) \, +#define Z_IS_3188_EQ_3188U(...) \, +#define Z_IS_3188U_EQ_3188U(...) \, +#define Z_IS_3189_EQ_3189(...) \, +#define Z_IS_3189U_EQ_3189(...) \, +#define Z_IS_3189_EQ_3189U(...) \, +#define Z_IS_3189U_EQ_3189U(...) \, +#define Z_IS_3190_EQ_3190(...) \, +#define Z_IS_3190U_EQ_3190(...) \, +#define Z_IS_3190_EQ_3190U(...) \, +#define Z_IS_3190U_EQ_3190U(...) \, +#define Z_IS_3191_EQ_3191(...) \, +#define Z_IS_3191U_EQ_3191(...) \, +#define Z_IS_3191_EQ_3191U(...) \, +#define Z_IS_3191U_EQ_3191U(...) \, +#define Z_IS_3192_EQ_3192(...) \, +#define Z_IS_3192U_EQ_3192(...) \, +#define Z_IS_3192_EQ_3192U(...) \, +#define Z_IS_3192U_EQ_3192U(...) \, +#define Z_IS_3193_EQ_3193(...) \, +#define Z_IS_3193U_EQ_3193(...) \, +#define Z_IS_3193_EQ_3193U(...) \, +#define Z_IS_3193U_EQ_3193U(...) \, +#define Z_IS_3194_EQ_3194(...) \, +#define Z_IS_3194U_EQ_3194(...) \, +#define Z_IS_3194_EQ_3194U(...) \, +#define Z_IS_3194U_EQ_3194U(...) \, +#define Z_IS_3195_EQ_3195(...) \, +#define Z_IS_3195U_EQ_3195(...) \, +#define Z_IS_3195_EQ_3195U(...) \, +#define Z_IS_3195U_EQ_3195U(...) \, +#define Z_IS_3196_EQ_3196(...) \, +#define Z_IS_3196U_EQ_3196(...) \, +#define Z_IS_3196_EQ_3196U(...) \, +#define Z_IS_3196U_EQ_3196U(...) \, +#define Z_IS_3197_EQ_3197(...) \, +#define Z_IS_3197U_EQ_3197(...) \, +#define Z_IS_3197_EQ_3197U(...) \, +#define Z_IS_3197U_EQ_3197U(...) \, +#define Z_IS_3198_EQ_3198(...) \, +#define Z_IS_3198U_EQ_3198(...) \, +#define Z_IS_3198_EQ_3198U(...) \, +#define Z_IS_3198U_EQ_3198U(...) \, +#define Z_IS_3199_EQ_3199(...) \, +#define Z_IS_3199U_EQ_3199(...) \, +#define Z_IS_3199_EQ_3199U(...) \, +#define Z_IS_3199U_EQ_3199U(...) \, +#define Z_IS_3200_EQ_3200(...) \, +#define Z_IS_3200U_EQ_3200(...) \, +#define Z_IS_3200_EQ_3200U(...) \, +#define Z_IS_3200U_EQ_3200U(...) \, +#define Z_IS_3201_EQ_3201(...) \, +#define Z_IS_3201U_EQ_3201(...) \, +#define Z_IS_3201_EQ_3201U(...) \, +#define Z_IS_3201U_EQ_3201U(...) \, +#define Z_IS_3202_EQ_3202(...) \, +#define Z_IS_3202U_EQ_3202(...) \, +#define Z_IS_3202_EQ_3202U(...) \, +#define Z_IS_3202U_EQ_3202U(...) \, +#define Z_IS_3203_EQ_3203(...) \, +#define Z_IS_3203U_EQ_3203(...) \, +#define Z_IS_3203_EQ_3203U(...) \, +#define Z_IS_3203U_EQ_3203U(...) \, +#define Z_IS_3204_EQ_3204(...) \, +#define Z_IS_3204U_EQ_3204(...) \, +#define Z_IS_3204_EQ_3204U(...) \, +#define Z_IS_3204U_EQ_3204U(...) \, +#define Z_IS_3205_EQ_3205(...) \, +#define Z_IS_3205U_EQ_3205(...) \, +#define Z_IS_3205_EQ_3205U(...) \, +#define Z_IS_3205U_EQ_3205U(...) \, +#define Z_IS_3206_EQ_3206(...) \, +#define Z_IS_3206U_EQ_3206(...) \, +#define Z_IS_3206_EQ_3206U(...) \, +#define Z_IS_3206U_EQ_3206U(...) \, +#define Z_IS_3207_EQ_3207(...) \, +#define Z_IS_3207U_EQ_3207(...) \, +#define Z_IS_3207_EQ_3207U(...) \, +#define Z_IS_3207U_EQ_3207U(...) \, +#define Z_IS_3208_EQ_3208(...) \, +#define Z_IS_3208U_EQ_3208(...) \, +#define Z_IS_3208_EQ_3208U(...) \, +#define Z_IS_3208U_EQ_3208U(...) \, +#define Z_IS_3209_EQ_3209(...) \, +#define Z_IS_3209U_EQ_3209(...) \, +#define Z_IS_3209_EQ_3209U(...) \, +#define Z_IS_3209U_EQ_3209U(...) \, +#define Z_IS_3210_EQ_3210(...) \, +#define Z_IS_3210U_EQ_3210(...) \, +#define Z_IS_3210_EQ_3210U(...) \, +#define Z_IS_3210U_EQ_3210U(...) \, +#define Z_IS_3211_EQ_3211(...) \, +#define Z_IS_3211U_EQ_3211(...) \, +#define Z_IS_3211_EQ_3211U(...) \, +#define Z_IS_3211U_EQ_3211U(...) \, +#define Z_IS_3212_EQ_3212(...) \, +#define Z_IS_3212U_EQ_3212(...) \, +#define Z_IS_3212_EQ_3212U(...) \, +#define Z_IS_3212U_EQ_3212U(...) \, +#define Z_IS_3213_EQ_3213(...) \, +#define Z_IS_3213U_EQ_3213(...) \, +#define Z_IS_3213_EQ_3213U(...) \, +#define Z_IS_3213U_EQ_3213U(...) \, +#define Z_IS_3214_EQ_3214(...) \, +#define Z_IS_3214U_EQ_3214(...) \, +#define Z_IS_3214_EQ_3214U(...) \, +#define Z_IS_3214U_EQ_3214U(...) \, +#define Z_IS_3215_EQ_3215(...) \, +#define Z_IS_3215U_EQ_3215(...) \, +#define Z_IS_3215_EQ_3215U(...) \, +#define Z_IS_3215U_EQ_3215U(...) \, +#define Z_IS_3216_EQ_3216(...) \, +#define Z_IS_3216U_EQ_3216(...) \, +#define Z_IS_3216_EQ_3216U(...) \, +#define Z_IS_3216U_EQ_3216U(...) \, +#define Z_IS_3217_EQ_3217(...) \, +#define Z_IS_3217U_EQ_3217(...) \, +#define Z_IS_3217_EQ_3217U(...) \, +#define Z_IS_3217U_EQ_3217U(...) \, +#define Z_IS_3218_EQ_3218(...) \, +#define Z_IS_3218U_EQ_3218(...) \, +#define Z_IS_3218_EQ_3218U(...) \, +#define Z_IS_3218U_EQ_3218U(...) \, +#define Z_IS_3219_EQ_3219(...) \, +#define Z_IS_3219U_EQ_3219(...) \, +#define Z_IS_3219_EQ_3219U(...) \, +#define Z_IS_3219U_EQ_3219U(...) \, +#define Z_IS_3220_EQ_3220(...) \, +#define Z_IS_3220U_EQ_3220(...) \, +#define Z_IS_3220_EQ_3220U(...) \, +#define Z_IS_3220U_EQ_3220U(...) \, +#define Z_IS_3221_EQ_3221(...) \, +#define Z_IS_3221U_EQ_3221(...) \, +#define Z_IS_3221_EQ_3221U(...) \, +#define Z_IS_3221U_EQ_3221U(...) \, +#define Z_IS_3222_EQ_3222(...) \, +#define Z_IS_3222U_EQ_3222(...) \, +#define Z_IS_3222_EQ_3222U(...) \, +#define Z_IS_3222U_EQ_3222U(...) \, +#define Z_IS_3223_EQ_3223(...) \, +#define Z_IS_3223U_EQ_3223(...) \, +#define Z_IS_3223_EQ_3223U(...) \, +#define Z_IS_3223U_EQ_3223U(...) \, +#define Z_IS_3224_EQ_3224(...) \, +#define Z_IS_3224U_EQ_3224(...) \, +#define Z_IS_3224_EQ_3224U(...) \, +#define Z_IS_3224U_EQ_3224U(...) \, +#define Z_IS_3225_EQ_3225(...) \, +#define Z_IS_3225U_EQ_3225(...) \, +#define Z_IS_3225_EQ_3225U(...) \, +#define Z_IS_3225U_EQ_3225U(...) \, +#define Z_IS_3226_EQ_3226(...) \, +#define Z_IS_3226U_EQ_3226(...) \, +#define Z_IS_3226_EQ_3226U(...) \, +#define Z_IS_3226U_EQ_3226U(...) \, +#define Z_IS_3227_EQ_3227(...) \, +#define Z_IS_3227U_EQ_3227(...) \, +#define Z_IS_3227_EQ_3227U(...) \, +#define Z_IS_3227U_EQ_3227U(...) \, +#define Z_IS_3228_EQ_3228(...) \, +#define Z_IS_3228U_EQ_3228(...) \, +#define Z_IS_3228_EQ_3228U(...) \, +#define Z_IS_3228U_EQ_3228U(...) \, +#define Z_IS_3229_EQ_3229(...) \, +#define Z_IS_3229U_EQ_3229(...) \, +#define Z_IS_3229_EQ_3229U(...) \, +#define Z_IS_3229U_EQ_3229U(...) \, +#define Z_IS_3230_EQ_3230(...) \, +#define Z_IS_3230U_EQ_3230(...) \, +#define Z_IS_3230_EQ_3230U(...) \, +#define Z_IS_3230U_EQ_3230U(...) \, +#define Z_IS_3231_EQ_3231(...) \, +#define Z_IS_3231U_EQ_3231(...) \, +#define Z_IS_3231_EQ_3231U(...) \, +#define Z_IS_3231U_EQ_3231U(...) \, +#define Z_IS_3232_EQ_3232(...) \, +#define Z_IS_3232U_EQ_3232(...) \, +#define Z_IS_3232_EQ_3232U(...) \, +#define Z_IS_3232U_EQ_3232U(...) \, +#define Z_IS_3233_EQ_3233(...) \, +#define Z_IS_3233U_EQ_3233(...) \, +#define Z_IS_3233_EQ_3233U(...) \, +#define Z_IS_3233U_EQ_3233U(...) \, +#define Z_IS_3234_EQ_3234(...) \, +#define Z_IS_3234U_EQ_3234(...) \, +#define Z_IS_3234_EQ_3234U(...) \, +#define Z_IS_3234U_EQ_3234U(...) \, +#define Z_IS_3235_EQ_3235(...) \, +#define Z_IS_3235U_EQ_3235(...) \, +#define Z_IS_3235_EQ_3235U(...) \, +#define Z_IS_3235U_EQ_3235U(...) \, +#define Z_IS_3236_EQ_3236(...) \, +#define Z_IS_3236U_EQ_3236(...) \, +#define Z_IS_3236_EQ_3236U(...) \, +#define Z_IS_3236U_EQ_3236U(...) \, +#define Z_IS_3237_EQ_3237(...) \, +#define Z_IS_3237U_EQ_3237(...) \, +#define Z_IS_3237_EQ_3237U(...) \, +#define Z_IS_3237U_EQ_3237U(...) \, +#define Z_IS_3238_EQ_3238(...) \, +#define Z_IS_3238U_EQ_3238(...) \, +#define Z_IS_3238_EQ_3238U(...) \, +#define Z_IS_3238U_EQ_3238U(...) \, +#define Z_IS_3239_EQ_3239(...) \, +#define Z_IS_3239U_EQ_3239(...) \, +#define Z_IS_3239_EQ_3239U(...) \, +#define Z_IS_3239U_EQ_3239U(...) \, +#define Z_IS_3240_EQ_3240(...) \, +#define Z_IS_3240U_EQ_3240(...) \, +#define Z_IS_3240_EQ_3240U(...) \, +#define Z_IS_3240U_EQ_3240U(...) \, +#define Z_IS_3241_EQ_3241(...) \, +#define Z_IS_3241U_EQ_3241(...) \, +#define Z_IS_3241_EQ_3241U(...) \, +#define Z_IS_3241U_EQ_3241U(...) \, +#define Z_IS_3242_EQ_3242(...) \, +#define Z_IS_3242U_EQ_3242(...) \, +#define Z_IS_3242_EQ_3242U(...) \, +#define Z_IS_3242U_EQ_3242U(...) \, +#define Z_IS_3243_EQ_3243(...) \, +#define Z_IS_3243U_EQ_3243(...) \, +#define Z_IS_3243_EQ_3243U(...) \, +#define Z_IS_3243U_EQ_3243U(...) \, +#define Z_IS_3244_EQ_3244(...) \, +#define Z_IS_3244U_EQ_3244(...) \, +#define Z_IS_3244_EQ_3244U(...) \, +#define Z_IS_3244U_EQ_3244U(...) \, +#define Z_IS_3245_EQ_3245(...) \, +#define Z_IS_3245U_EQ_3245(...) \, +#define Z_IS_3245_EQ_3245U(...) \, +#define Z_IS_3245U_EQ_3245U(...) \, +#define Z_IS_3246_EQ_3246(...) \, +#define Z_IS_3246U_EQ_3246(...) \, +#define Z_IS_3246_EQ_3246U(...) \, +#define Z_IS_3246U_EQ_3246U(...) \, +#define Z_IS_3247_EQ_3247(...) \, +#define Z_IS_3247U_EQ_3247(...) \, +#define Z_IS_3247_EQ_3247U(...) \, +#define Z_IS_3247U_EQ_3247U(...) \, +#define Z_IS_3248_EQ_3248(...) \, +#define Z_IS_3248U_EQ_3248(...) \, +#define Z_IS_3248_EQ_3248U(...) \, +#define Z_IS_3248U_EQ_3248U(...) \, +#define Z_IS_3249_EQ_3249(...) \, +#define Z_IS_3249U_EQ_3249(...) \, +#define Z_IS_3249_EQ_3249U(...) \, +#define Z_IS_3249U_EQ_3249U(...) \, +#define Z_IS_3250_EQ_3250(...) \, +#define Z_IS_3250U_EQ_3250(...) \, +#define Z_IS_3250_EQ_3250U(...) \, +#define Z_IS_3250U_EQ_3250U(...) \, +#define Z_IS_3251_EQ_3251(...) \, +#define Z_IS_3251U_EQ_3251(...) \, +#define Z_IS_3251_EQ_3251U(...) \, +#define Z_IS_3251U_EQ_3251U(...) \, +#define Z_IS_3252_EQ_3252(...) \, +#define Z_IS_3252U_EQ_3252(...) \, +#define Z_IS_3252_EQ_3252U(...) \, +#define Z_IS_3252U_EQ_3252U(...) \, +#define Z_IS_3253_EQ_3253(...) \, +#define Z_IS_3253U_EQ_3253(...) \, +#define Z_IS_3253_EQ_3253U(...) \, +#define Z_IS_3253U_EQ_3253U(...) \, +#define Z_IS_3254_EQ_3254(...) \, +#define Z_IS_3254U_EQ_3254(...) \, +#define Z_IS_3254_EQ_3254U(...) \, +#define Z_IS_3254U_EQ_3254U(...) \, +#define Z_IS_3255_EQ_3255(...) \, +#define Z_IS_3255U_EQ_3255(...) \, +#define Z_IS_3255_EQ_3255U(...) \, +#define Z_IS_3255U_EQ_3255U(...) \, +#define Z_IS_3256_EQ_3256(...) \, +#define Z_IS_3256U_EQ_3256(...) \, +#define Z_IS_3256_EQ_3256U(...) \, +#define Z_IS_3256U_EQ_3256U(...) \, +#define Z_IS_3257_EQ_3257(...) \, +#define Z_IS_3257U_EQ_3257(...) \, +#define Z_IS_3257_EQ_3257U(...) \, +#define Z_IS_3257U_EQ_3257U(...) \, +#define Z_IS_3258_EQ_3258(...) \, +#define Z_IS_3258U_EQ_3258(...) \, +#define Z_IS_3258_EQ_3258U(...) \, +#define Z_IS_3258U_EQ_3258U(...) \, +#define Z_IS_3259_EQ_3259(...) \, +#define Z_IS_3259U_EQ_3259(...) \, +#define Z_IS_3259_EQ_3259U(...) \, +#define Z_IS_3259U_EQ_3259U(...) \, +#define Z_IS_3260_EQ_3260(...) \, +#define Z_IS_3260U_EQ_3260(...) \, +#define Z_IS_3260_EQ_3260U(...) \, +#define Z_IS_3260U_EQ_3260U(...) \, +#define Z_IS_3261_EQ_3261(...) \, +#define Z_IS_3261U_EQ_3261(...) \, +#define Z_IS_3261_EQ_3261U(...) \, +#define Z_IS_3261U_EQ_3261U(...) \, +#define Z_IS_3262_EQ_3262(...) \, +#define Z_IS_3262U_EQ_3262(...) \, +#define Z_IS_3262_EQ_3262U(...) \, +#define Z_IS_3262U_EQ_3262U(...) \, +#define Z_IS_3263_EQ_3263(...) \, +#define Z_IS_3263U_EQ_3263(...) \, +#define Z_IS_3263_EQ_3263U(...) \, +#define Z_IS_3263U_EQ_3263U(...) \, +#define Z_IS_3264_EQ_3264(...) \, +#define Z_IS_3264U_EQ_3264(...) \, +#define Z_IS_3264_EQ_3264U(...) \, +#define Z_IS_3264U_EQ_3264U(...) \, +#define Z_IS_3265_EQ_3265(...) \, +#define Z_IS_3265U_EQ_3265(...) \, +#define Z_IS_3265_EQ_3265U(...) \, +#define Z_IS_3265U_EQ_3265U(...) \, +#define Z_IS_3266_EQ_3266(...) \, +#define Z_IS_3266U_EQ_3266(...) \, +#define Z_IS_3266_EQ_3266U(...) \, +#define Z_IS_3266U_EQ_3266U(...) \, +#define Z_IS_3267_EQ_3267(...) \, +#define Z_IS_3267U_EQ_3267(...) \, +#define Z_IS_3267_EQ_3267U(...) \, +#define Z_IS_3267U_EQ_3267U(...) \, +#define Z_IS_3268_EQ_3268(...) \, +#define Z_IS_3268U_EQ_3268(...) \, +#define Z_IS_3268_EQ_3268U(...) \, +#define Z_IS_3268U_EQ_3268U(...) \, +#define Z_IS_3269_EQ_3269(...) \, +#define Z_IS_3269U_EQ_3269(...) \, +#define Z_IS_3269_EQ_3269U(...) \, +#define Z_IS_3269U_EQ_3269U(...) \, +#define Z_IS_3270_EQ_3270(...) \, +#define Z_IS_3270U_EQ_3270(...) \, +#define Z_IS_3270_EQ_3270U(...) \, +#define Z_IS_3270U_EQ_3270U(...) \, +#define Z_IS_3271_EQ_3271(...) \, +#define Z_IS_3271U_EQ_3271(...) \, +#define Z_IS_3271_EQ_3271U(...) \, +#define Z_IS_3271U_EQ_3271U(...) \, +#define Z_IS_3272_EQ_3272(...) \, +#define Z_IS_3272U_EQ_3272(...) \, +#define Z_IS_3272_EQ_3272U(...) \, +#define Z_IS_3272U_EQ_3272U(...) \, +#define Z_IS_3273_EQ_3273(...) \, +#define Z_IS_3273U_EQ_3273(...) \, +#define Z_IS_3273_EQ_3273U(...) \, +#define Z_IS_3273U_EQ_3273U(...) \, +#define Z_IS_3274_EQ_3274(...) \, +#define Z_IS_3274U_EQ_3274(...) \, +#define Z_IS_3274_EQ_3274U(...) \, +#define Z_IS_3274U_EQ_3274U(...) \, +#define Z_IS_3275_EQ_3275(...) \, +#define Z_IS_3275U_EQ_3275(...) \, +#define Z_IS_3275_EQ_3275U(...) \, +#define Z_IS_3275U_EQ_3275U(...) \, +#define Z_IS_3276_EQ_3276(...) \, +#define Z_IS_3276U_EQ_3276(...) \, +#define Z_IS_3276_EQ_3276U(...) \, +#define Z_IS_3276U_EQ_3276U(...) \, +#define Z_IS_3277_EQ_3277(...) \, +#define Z_IS_3277U_EQ_3277(...) \, +#define Z_IS_3277_EQ_3277U(...) \, +#define Z_IS_3277U_EQ_3277U(...) \, +#define Z_IS_3278_EQ_3278(...) \, +#define Z_IS_3278U_EQ_3278(...) \, +#define Z_IS_3278_EQ_3278U(...) \, +#define Z_IS_3278U_EQ_3278U(...) \, +#define Z_IS_3279_EQ_3279(...) \, +#define Z_IS_3279U_EQ_3279(...) \, +#define Z_IS_3279_EQ_3279U(...) \, +#define Z_IS_3279U_EQ_3279U(...) \, +#define Z_IS_3280_EQ_3280(...) \, +#define Z_IS_3280U_EQ_3280(...) \, +#define Z_IS_3280_EQ_3280U(...) \, +#define Z_IS_3280U_EQ_3280U(...) \, +#define Z_IS_3281_EQ_3281(...) \, +#define Z_IS_3281U_EQ_3281(...) \, +#define Z_IS_3281_EQ_3281U(...) \, +#define Z_IS_3281U_EQ_3281U(...) \, +#define Z_IS_3282_EQ_3282(...) \, +#define Z_IS_3282U_EQ_3282(...) \, +#define Z_IS_3282_EQ_3282U(...) \, +#define Z_IS_3282U_EQ_3282U(...) \, +#define Z_IS_3283_EQ_3283(...) \, +#define Z_IS_3283U_EQ_3283(...) \, +#define Z_IS_3283_EQ_3283U(...) \, +#define Z_IS_3283U_EQ_3283U(...) \, +#define Z_IS_3284_EQ_3284(...) \, +#define Z_IS_3284U_EQ_3284(...) \, +#define Z_IS_3284_EQ_3284U(...) \, +#define Z_IS_3284U_EQ_3284U(...) \, +#define Z_IS_3285_EQ_3285(...) \, +#define Z_IS_3285U_EQ_3285(...) \, +#define Z_IS_3285_EQ_3285U(...) \, +#define Z_IS_3285U_EQ_3285U(...) \, +#define Z_IS_3286_EQ_3286(...) \, +#define Z_IS_3286U_EQ_3286(...) \, +#define Z_IS_3286_EQ_3286U(...) \, +#define Z_IS_3286U_EQ_3286U(...) \, +#define Z_IS_3287_EQ_3287(...) \, +#define Z_IS_3287U_EQ_3287(...) \, +#define Z_IS_3287_EQ_3287U(...) \, +#define Z_IS_3287U_EQ_3287U(...) \, +#define Z_IS_3288_EQ_3288(...) \, +#define Z_IS_3288U_EQ_3288(...) \, +#define Z_IS_3288_EQ_3288U(...) \, +#define Z_IS_3288U_EQ_3288U(...) \, +#define Z_IS_3289_EQ_3289(...) \, +#define Z_IS_3289U_EQ_3289(...) \, +#define Z_IS_3289_EQ_3289U(...) \, +#define Z_IS_3289U_EQ_3289U(...) \, +#define Z_IS_3290_EQ_3290(...) \, +#define Z_IS_3290U_EQ_3290(...) \, +#define Z_IS_3290_EQ_3290U(...) \, +#define Z_IS_3290U_EQ_3290U(...) \, +#define Z_IS_3291_EQ_3291(...) \, +#define Z_IS_3291U_EQ_3291(...) \, +#define Z_IS_3291_EQ_3291U(...) \, +#define Z_IS_3291U_EQ_3291U(...) \, +#define Z_IS_3292_EQ_3292(...) \, +#define Z_IS_3292U_EQ_3292(...) \, +#define Z_IS_3292_EQ_3292U(...) \, +#define Z_IS_3292U_EQ_3292U(...) \, +#define Z_IS_3293_EQ_3293(...) \, +#define Z_IS_3293U_EQ_3293(...) \, +#define Z_IS_3293_EQ_3293U(...) \, +#define Z_IS_3293U_EQ_3293U(...) \, +#define Z_IS_3294_EQ_3294(...) \, +#define Z_IS_3294U_EQ_3294(...) \, +#define Z_IS_3294_EQ_3294U(...) \, +#define Z_IS_3294U_EQ_3294U(...) \, +#define Z_IS_3295_EQ_3295(...) \, +#define Z_IS_3295U_EQ_3295(...) \, +#define Z_IS_3295_EQ_3295U(...) \, +#define Z_IS_3295U_EQ_3295U(...) \, +#define Z_IS_3296_EQ_3296(...) \, +#define Z_IS_3296U_EQ_3296(...) \, +#define Z_IS_3296_EQ_3296U(...) \, +#define Z_IS_3296U_EQ_3296U(...) \, +#define Z_IS_3297_EQ_3297(...) \, +#define Z_IS_3297U_EQ_3297(...) \, +#define Z_IS_3297_EQ_3297U(...) \, +#define Z_IS_3297U_EQ_3297U(...) \, +#define Z_IS_3298_EQ_3298(...) \, +#define Z_IS_3298U_EQ_3298(...) \, +#define Z_IS_3298_EQ_3298U(...) \, +#define Z_IS_3298U_EQ_3298U(...) \, +#define Z_IS_3299_EQ_3299(...) \, +#define Z_IS_3299U_EQ_3299(...) \, +#define Z_IS_3299_EQ_3299U(...) \, +#define Z_IS_3299U_EQ_3299U(...) \, +#define Z_IS_3300_EQ_3300(...) \, +#define Z_IS_3300U_EQ_3300(...) \, +#define Z_IS_3300_EQ_3300U(...) \, +#define Z_IS_3300U_EQ_3300U(...) \, +#define Z_IS_3301_EQ_3301(...) \, +#define Z_IS_3301U_EQ_3301(...) \, +#define Z_IS_3301_EQ_3301U(...) \, +#define Z_IS_3301U_EQ_3301U(...) \, +#define Z_IS_3302_EQ_3302(...) \, +#define Z_IS_3302U_EQ_3302(...) \, +#define Z_IS_3302_EQ_3302U(...) \, +#define Z_IS_3302U_EQ_3302U(...) \, +#define Z_IS_3303_EQ_3303(...) \, +#define Z_IS_3303U_EQ_3303(...) \, +#define Z_IS_3303_EQ_3303U(...) \, +#define Z_IS_3303U_EQ_3303U(...) \, +#define Z_IS_3304_EQ_3304(...) \, +#define Z_IS_3304U_EQ_3304(...) \, +#define Z_IS_3304_EQ_3304U(...) \, +#define Z_IS_3304U_EQ_3304U(...) \, +#define Z_IS_3305_EQ_3305(...) \, +#define Z_IS_3305U_EQ_3305(...) \, +#define Z_IS_3305_EQ_3305U(...) \, +#define Z_IS_3305U_EQ_3305U(...) \, +#define Z_IS_3306_EQ_3306(...) \, +#define Z_IS_3306U_EQ_3306(...) \, +#define Z_IS_3306_EQ_3306U(...) \, +#define Z_IS_3306U_EQ_3306U(...) \, +#define Z_IS_3307_EQ_3307(...) \, +#define Z_IS_3307U_EQ_3307(...) \, +#define Z_IS_3307_EQ_3307U(...) \, +#define Z_IS_3307U_EQ_3307U(...) \, +#define Z_IS_3308_EQ_3308(...) \, +#define Z_IS_3308U_EQ_3308(...) \, +#define Z_IS_3308_EQ_3308U(...) \, +#define Z_IS_3308U_EQ_3308U(...) \, +#define Z_IS_3309_EQ_3309(...) \, +#define Z_IS_3309U_EQ_3309(...) \, +#define Z_IS_3309_EQ_3309U(...) \, +#define Z_IS_3309U_EQ_3309U(...) \, +#define Z_IS_3310_EQ_3310(...) \, +#define Z_IS_3310U_EQ_3310(...) \, +#define Z_IS_3310_EQ_3310U(...) \, +#define Z_IS_3310U_EQ_3310U(...) \, +#define Z_IS_3311_EQ_3311(...) \, +#define Z_IS_3311U_EQ_3311(...) \, +#define Z_IS_3311_EQ_3311U(...) \, +#define Z_IS_3311U_EQ_3311U(...) \, +#define Z_IS_3312_EQ_3312(...) \, +#define Z_IS_3312U_EQ_3312(...) \, +#define Z_IS_3312_EQ_3312U(...) \, +#define Z_IS_3312U_EQ_3312U(...) \, +#define Z_IS_3313_EQ_3313(...) \, +#define Z_IS_3313U_EQ_3313(...) \, +#define Z_IS_3313_EQ_3313U(...) \, +#define Z_IS_3313U_EQ_3313U(...) \, +#define Z_IS_3314_EQ_3314(...) \, +#define Z_IS_3314U_EQ_3314(...) \, +#define Z_IS_3314_EQ_3314U(...) \, +#define Z_IS_3314U_EQ_3314U(...) \, +#define Z_IS_3315_EQ_3315(...) \, +#define Z_IS_3315U_EQ_3315(...) \, +#define Z_IS_3315_EQ_3315U(...) \, +#define Z_IS_3315U_EQ_3315U(...) \, +#define Z_IS_3316_EQ_3316(...) \, +#define Z_IS_3316U_EQ_3316(...) \, +#define Z_IS_3316_EQ_3316U(...) \, +#define Z_IS_3316U_EQ_3316U(...) \, +#define Z_IS_3317_EQ_3317(...) \, +#define Z_IS_3317U_EQ_3317(...) \, +#define Z_IS_3317_EQ_3317U(...) \, +#define Z_IS_3317U_EQ_3317U(...) \, +#define Z_IS_3318_EQ_3318(...) \, +#define Z_IS_3318U_EQ_3318(...) \, +#define Z_IS_3318_EQ_3318U(...) \, +#define Z_IS_3318U_EQ_3318U(...) \, +#define Z_IS_3319_EQ_3319(...) \, +#define Z_IS_3319U_EQ_3319(...) \, +#define Z_IS_3319_EQ_3319U(...) \, +#define Z_IS_3319U_EQ_3319U(...) \, +#define Z_IS_3320_EQ_3320(...) \, +#define Z_IS_3320U_EQ_3320(...) \, +#define Z_IS_3320_EQ_3320U(...) \, +#define Z_IS_3320U_EQ_3320U(...) \, +#define Z_IS_3321_EQ_3321(...) \, +#define Z_IS_3321U_EQ_3321(...) \, +#define Z_IS_3321_EQ_3321U(...) \, +#define Z_IS_3321U_EQ_3321U(...) \, +#define Z_IS_3322_EQ_3322(...) \, +#define Z_IS_3322U_EQ_3322(...) \, +#define Z_IS_3322_EQ_3322U(...) \, +#define Z_IS_3322U_EQ_3322U(...) \, +#define Z_IS_3323_EQ_3323(...) \, +#define Z_IS_3323U_EQ_3323(...) \, +#define Z_IS_3323_EQ_3323U(...) \, +#define Z_IS_3323U_EQ_3323U(...) \, +#define Z_IS_3324_EQ_3324(...) \, +#define Z_IS_3324U_EQ_3324(...) \, +#define Z_IS_3324_EQ_3324U(...) \, +#define Z_IS_3324U_EQ_3324U(...) \, +#define Z_IS_3325_EQ_3325(...) \, +#define Z_IS_3325U_EQ_3325(...) \, +#define Z_IS_3325_EQ_3325U(...) \, +#define Z_IS_3325U_EQ_3325U(...) \, +#define Z_IS_3326_EQ_3326(...) \, +#define Z_IS_3326U_EQ_3326(...) \, +#define Z_IS_3326_EQ_3326U(...) \, +#define Z_IS_3326U_EQ_3326U(...) \, +#define Z_IS_3327_EQ_3327(...) \, +#define Z_IS_3327U_EQ_3327(...) \, +#define Z_IS_3327_EQ_3327U(...) \, +#define Z_IS_3327U_EQ_3327U(...) \, +#define Z_IS_3328_EQ_3328(...) \, +#define Z_IS_3328U_EQ_3328(...) \, +#define Z_IS_3328_EQ_3328U(...) \, +#define Z_IS_3328U_EQ_3328U(...) \, +#define Z_IS_3329_EQ_3329(...) \, +#define Z_IS_3329U_EQ_3329(...) \, +#define Z_IS_3329_EQ_3329U(...) \, +#define Z_IS_3329U_EQ_3329U(...) \, +#define Z_IS_3330_EQ_3330(...) \, +#define Z_IS_3330U_EQ_3330(...) \, +#define Z_IS_3330_EQ_3330U(...) \, +#define Z_IS_3330U_EQ_3330U(...) \, +#define Z_IS_3331_EQ_3331(...) \, +#define Z_IS_3331U_EQ_3331(...) \, +#define Z_IS_3331_EQ_3331U(...) \, +#define Z_IS_3331U_EQ_3331U(...) \, +#define Z_IS_3332_EQ_3332(...) \, +#define Z_IS_3332U_EQ_3332(...) \, +#define Z_IS_3332_EQ_3332U(...) \, +#define Z_IS_3332U_EQ_3332U(...) \, +#define Z_IS_3333_EQ_3333(...) \, +#define Z_IS_3333U_EQ_3333(...) \, +#define Z_IS_3333_EQ_3333U(...) \, +#define Z_IS_3333U_EQ_3333U(...) \, +#define Z_IS_3334_EQ_3334(...) \, +#define Z_IS_3334U_EQ_3334(...) \, +#define Z_IS_3334_EQ_3334U(...) \, +#define Z_IS_3334U_EQ_3334U(...) \, +#define Z_IS_3335_EQ_3335(...) \, +#define Z_IS_3335U_EQ_3335(...) \, +#define Z_IS_3335_EQ_3335U(...) \, +#define Z_IS_3335U_EQ_3335U(...) \, +#define Z_IS_3336_EQ_3336(...) \, +#define Z_IS_3336U_EQ_3336(...) \, +#define Z_IS_3336_EQ_3336U(...) \, +#define Z_IS_3336U_EQ_3336U(...) \, +#define Z_IS_3337_EQ_3337(...) \, +#define Z_IS_3337U_EQ_3337(...) \, +#define Z_IS_3337_EQ_3337U(...) \, +#define Z_IS_3337U_EQ_3337U(...) \, +#define Z_IS_3338_EQ_3338(...) \, +#define Z_IS_3338U_EQ_3338(...) \, +#define Z_IS_3338_EQ_3338U(...) \, +#define Z_IS_3338U_EQ_3338U(...) \, +#define Z_IS_3339_EQ_3339(...) \, +#define Z_IS_3339U_EQ_3339(...) \, +#define Z_IS_3339_EQ_3339U(...) \, +#define Z_IS_3339U_EQ_3339U(...) \, +#define Z_IS_3340_EQ_3340(...) \, +#define Z_IS_3340U_EQ_3340(...) \, +#define Z_IS_3340_EQ_3340U(...) \, +#define Z_IS_3340U_EQ_3340U(...) \, +#define Z_IS_3341_EQ_3341(...) \, +#define Z_IS_3341U_EQ_3341(...) \, +#define Z_IS_3341_EQ_3341U(...) \, +#define Z_IS_3341U_EQ_3341U(...) \, +#define Z_IS_3342_EQ_3342(...) \, +#define Z_IS_3342U_EQ_3342(...) \, +#define Z_IS_3342_EQ_3342U(...) \, +#define Z_IS_3342U_EQ_3342U(...) \, +#define Z_IS_3343_EQ_3343(...) \, +#define Z_IS_3343U_EQ_3343(...) \, +#define Z_IS_3343_EQ_3343U(...) \, +#define Z_IS_3343U_EQ_3343U(...) \, +#define Z_IS_3344_EQ_3344(...) \, +#define Z_IS_3344U_EQ_3344(...) \, +#define Z_IS_3344_EQ_3344U(...) \, +#define Z_IS_3344U_EQ_3344U(...) \, +#define Z_IS_3345_EQ_3345(...) \, +#define Z_IS_3345U_EQ_3345(...) \, +#define Z_IS_3345_EQ_3345U(...) \, +#define Z_IS_3345U_EQ_3345U(...) \, +#define Z_IS_3346_EQ_3346(...) \, +#define Z_IS_3346U_EQ_3346(...) \, +#define Z_IS_3346_EQ_3346U(...) \, +#define Z_IS_3346U_EQ_3346U(...) \, +#define Z_IS_3347_EQ_3347(...) \, +#define Z_IS_3347U_EQ_3347(...) \, +#define Z_IS_3347_EQ_3347U(...) \, +#define Z_IS_3347U_EQ_3347U(...) \, +#define Z_IS_3348_EQ_3348(...) \, +#define Z_IS_3348U_EQ_3348(...) \, +#define Z_IS_3348_EQ_3348U(...) \, +#define Z_IS_3348U_EQ_3348U(...) \, +#define Z_IS_3349_EQ_3349(...) \, +#define Z_IS_3349U_EQ_3349(...) \, +#define Z_IS_3349_EQ_3349U(...) \, +#define Z_IS_3349U_EQ_3349U(...) \, +#define Z_IS_3350_EQ_3350(...) \, +#define Z_IS_3350U_EQ_3350(...) \, +#define Z_IS_3350_EQ_3350U(...) \, +#define Z_IS_3350U_EQ_3350U(...) \, +#define Z_IS_3351_EQ_3351(...) \, +#define Z_IS_3351U_EQ_3351(...) \, +#define Z_IS_3351_EQ_3351U(...) \, +#define Z_IS_3351U_EQ_3351U(...) \, +#define Z_IS_3352_EQ_3352(...) \, +#define Z_IS_3352U_EQ_3352(...) \, +#define Z_IS_3352_EQ_3352U(...) \, +#define Z_IS_3352U_EQ_3352U(...) \, +#define Z_IS_3353_EQ_3353(...) \, +#define Z_IS_3353U_EQ_3353(...) \, +#define Z_IS_3353_EQ_3353U(...) \, +#define Z_IS_3353U_EQ_3353U(...) \, +#define Z_IS_3354_EQ_3354(...) \, +#define Z_IS_3354U_EQ_3354(...) \, +#define Z_IS_3354_EQ_3354U(...) \, +#define Z_IS_3354U_EQ_3354U(...) \, +#define Z_IS_3355_EQ_3355(...) \, +#define Z_IS_3355U_EQ_3355(...) \, +#define Z_IS_3355_EQ_3355U(...) \, +#define Z_IS_3355U_EQ_3355U(...) \, +#define Z_IS_3356_EQ_3356(...) \, +#define Z_IS_3356U_EQ_3356(...) \, +#define Z_IS_3356_EQ_3356U(...) \, +#define Z_IS_3356U_EQ_3356U(...) \, +#define Z_IS_3357_EQ_3357(...) \, +#define Z_IS_3357U_EQ_3357(...) \, +#define Z_IS_3357_EQ_3357U(...) \, +#define Z_IS_3357U_EQ_3357U(...) \, +#define Z_IS_3358_EQ_3358(...) \, +#define Z_IS_3358U_EQ_3358(...) \, +#define Z_IS_3358_EQ_3358U(...) \, +#define Z_IS_3358U_EQ_3358U(...) \, +#define Z_IS_3359_EQ_3359(...) \, +#define Z_IS_3359U_EQ_3359(...) \, +#define Z_IS_3359_EQ_3359U(...) \, +#define Z_IS_3359U_EQ_3359U(...) \, +#define Z_IS_3360_EQ_3360(...) \, +#define Z_IS_3360U_EQ_3360(...) \, +#define Z_IS_3360_EQ_3360U(...) \, +#define Z_IS_3360U_EQ_3360U(...) \, +#define Z_IS_3361_EQ_3361(...) \, +#define Z_IS_3361U_EQ_3361(...) \, +#define Z_IS_3361_EQ_3361U(...) \, +#define Z_IS_3361U_EQ_3361U(...) \, +#define Z_IS_3362_EQ_3362(...) \, +#define Z_IS_3362U_EQ_3362(...) \, +#define Z_IS_3362_EQ_3362U(...) \, +#define Z_IS_3362U_EQ_3362U(...) \, +#define Z_IS_3363_EQ_3363(...) \, +#define Z_IS_3363U_EQ_3363(...) \, +#define Z_IS_3363_EQ_3363U(...) \, +#define Z_IS_3363U_EQ_3363U(...) \, +#define Z_IS_3364_EQ_3364(...) \, +#define Z_IS_3364U_EQ_3364(...) \, +#define Z_IS_3364_EQ_3364U(...) \, +#define Z_IS_3364U_EQ_3364U(...) \, +#define Z_IS_3365_EQ_3365(...) \, +#define Z_IS_3365U_EQ_3365(...) \, +#define Z_IS_3365_EQ_3365U(...) \, +#define Z_IS_3365U_EQ_3365U(...) \, +#define Z_IS_3366_EQ_3366(...) \, +#define Z_IS_3366U_EQ_3366(...) \, +#define Z_IS_3366_EQ_3366U(...) \, +#define Z_IS_3366U_EQ_3366U(...) \, +#define Z_IS_3367_EQ_3367(...) \, +#define Z_IS_3367U_EQ_3367(...) \, +#define Z_IS_3367_EQ_3367U(...) \, +#define Z_IS_3367U_EQ_3367U(...) \, +#define Z_IS_3368_EQ_3368(...) \, +#define Z_IS_3368U_EQ_3368(...) \, +#define Z_IS_3368_EQ_3368U(...) \, +#define Z_IS_3368U_EQ_3368U(...) \, +#define Z_IS_3369_EQ_3369(...) \, +#define Z_IS_3369U_EQ_3369(...) \, +#define Z_IS_3369_EQ_3369U(...) \, +#define Z_IS_3369U_EQ_3369U(...) \, +#define Z_IS_3370_EQ_3370(...) \, +#define Z_IS_3370U_EQ_3370(...) \, +#define Z_IS_3370_EQ_3370U(...) \, +#define Z_IS_3370U_EQ_3370U(...) \, +#define Z_IS_3371_EQ_3371(...) \, +#define Z_IS_3371U_EQ_3371(...) \, +#define Z_IS_3371_EQ_3371U(...) \, +#define Z_IS_3371U_EQ_3371U(...) \, +#define Z_IS_3372_EQ_3372(...) \, +#define Z_IS_3372U_EQ_3372(...) \, +#define Z_IS_3372_EQ_3372U(...) \, +#define Z_IS_3372U_EQ_3372U(...) \, +#define Z_IS_3373_EQ_3373(...) \, +#define Z_IS_3373U_EQ_3373(...) \, +#define Z_IS_3373_EQ_3373U(...) \, +#define Z_IS_3373U_EQ_3373U(...) \, +#define Z_IS_3374_EQ_3374(...) \, +#define Z_IS_3374U_EQ_3374(...) \, +#define Z_IS_3374_EQ_3374U(...) \, +#define Z_IS_3374U_EQ_3374U(...) \, +#define Z_IS_3375_EQ_3375(...) \, +#define Z_IS_3375U_EQ_3375(...) \, +#define Z_IS_3375_EQ_3375U(...) \, +#define Z_IS_3375U_EQ_3375U(...) \, +#define Z_IS_3376_EQ_3376(...) \, +#define Z_IS_3376U_EQ_3376(...) \, +#define Z_IS_3376_EQ_3376U(...) \, +#define Z_IS_3376U_EQ_3376U(...) \, +#define Z_IS_3377_EQ_3377(...) \, +#define Z_IS_3377U_EQ_3377(...) \, +#define Z_IS_3377_EQ_3377U(...) \, +#define Z_IS_3377U_EQ_3377U(...) \, +#define Z_IS_3378_EQ_3378(...) \, +#define Z_IS_3378U_EQ_3378(...) \, +#define Z_IS_3378_EQ_3378U(...) \, +#define Z_IS_3378U_EQ_3378U(...) \, +#define Z_IS_3379_EQ_3379(...) \, +#define Z_IS_3379U_EQ_3379(...) \, +#define Z_IS_3379_EQ_3379U(...) \, +#define Z_IS_3379U_EQ_3379U(...) \, +#define Z_IS_3380_EQ_3380(...) \, +#define Z_IS_3380U_EQ_3380(...) \, +#define Z_IS_3380_EQ_3380U(...) \, +#define Z_IS_3380U_EQ_3380U(...) \, +#define Z_IS_3381_EQ_3381(...) \, +#define Z_IS_3381U_EQ_3381(...) \, +#define Z_IS_3381_EQ_3381U(...) \, +#define Z_IS_3381U_EQ_3381U(...) \, +#define Z_IS_3382_EQ_3382(...) \, +#define Z_IS_3382U_EQ_3382(...) \, +#define Z_IS_3382_EQ_3382U(...) \, +#define Z_IS_3382U_EQ_3382U(...) \, +#define Z_IS_3383_EQ_3383(...) \, +#define Z_IS_3383U_EQ_3383(...) \, +#define Z_IS_3383_EQ_3383U(...) \, +#define Z_IS_3383U_EQ_3383U(...) \, +#define Z_IS_3384_EQ_3384(...) \, +#define Z_IS_3384U_EQ_3384(...) \, +#define Z_IS_3384_EQ_3384U(...) \, +#define Z_IS_3384U_EQ_3384U(...) \, +#define Z_IS_3385_EQ_3385(...) \, +#define Z_IS_3385U_EQ_3385(...) \, +#define Z_IS_3385_EQ_3385U(...) \, +#define Z_IS_3385U_EQ_3385U(...) \, +#define Z_IS_3386_EQ_3386(...) \, +#define Z_IS_3386U_EQ_3386(...) \, +#define Z_IS_3386_EQ_3386U(...) \, +#define Z_IS_3386U_EQ_3386U(...) \, +#define Z_IS_3387_EQ_3387(...) \, +#define Z_IS_3387U_EQ_3387(...) \, +#define Z_IS_3387_EQ_3387U(...) \, +#define Z_IS_3387U_EQ_3387U(...) \, +#define Z_IS_3388_EQ_3388(...) \, +#define Z_IS_3388U_EQ_3388(...) \, +#define Z_IS_3388_EQ_3388U(...) \, +#define Z_IS_3388U_EQ_3388U(...) \, +#define Z_IS_3389_EQ_3389(...) \, +#define Z_IS_3389U_EQ_3389(...) \, +#define Z_IS_3389_EQ_3389U(...) \, +#define Z_IS_3389U_EQ_3389U(...) \, +#define Z_IS_3390_EQ_3390(...) \, +#define Z_IS_3390U_EQ_3390(...) \, +#define Z_IS_3390_EQ_3390U(...) \, +#define Z_IS_3390U_EQ_3390U(...) \, +#define Z_IS_3391_EQ_3391(...) \, +#define Z_IS_3391U_EQ_3391(...) \, +#define Z_IS_3391_EQ_3391U(...) \, +#define Z_IS_3391U_EQ_3391U(...) \, +#define Z_IS_3392_EQ_3392(...) \, +#define Z_IS_3392U_EQ_3392(...) \, +#define Z_IS_3392_EQ_3392U(...) \, +#define Z_IS_3392U_EQ_3392U(...) \, +#define Z_IS_3393_EQ_3393(...) \, +#define Z_IS_3393U_EQ_3393(...) \, +#define Z_IS_3393_EQ_3393U(...) \, +#define Z_IS_3393U_EQ_3393U(...) \, +#define Z_IS_3394_EQ_3394(...) \, +#define Z_IS_3394U_EQ_3394(...) \, +#define Z_IS_3394_EQ_3394U(...) \, +#define Z_IS_3394U_EQ_3394U(...) \, +#define Z_IS_3395_EQ_3395(...) \, +#define Z_IS_3395U_EQ_3395(...) \, +#define Z_IS_3395_EQ_3395U(...) \, +#define Z_IS_3395U_EQ_3395U(...) \, +#define Z_IS_3396_EQ_3396(...) \, +#define Z_IS_3396U_EQ_3396(...) \, +#define Z_IS_3396_EQ_3396U(...) \, +#define Z_IS_3396U_EQ_3396U(...) \, +#define Z_IS_3397_EQ_3397(...) \, +#define Z_IS_3397U_EQ_3397(...) \, +#define Z_IS_3397_EQ_3397U(...) \, +#define Z_IS_3397U_EQ_3397U(...) \, +#define Z_IS_3398_EQ_3398(...) \, +#define Z_IS_3398U_EQ_3398(...) \, +#define Z_IS_3398_EQ_3398U(...) \, +#define Z_IS_3398U_EQ_3398U(...) \, +#define Z_IS_3399_EQ_3399(...) \, +#define Z_IS_3399U_EQ_3399(...) \, +#define Z_IS_3399_EQ_3399U(...) \, +#define Z_IS_3399U_EQ_3399U(...) \, +#define Z_IS_3400_EQ_3400(...) \, +#define Z_IS_3400U_EQ_3400(...) \, +#define Z_IS_3400_EQ_3400U(...) \, +#define Z_IS_3400U_EQ_3400U(...) \, +#define Z_IS_3401_EQ_3401(...) \, +#define Z_IS_3401U_EQ_3401(...) \, +#define Z_IS_3401_EQ_3401U(...) \, +#define Z_IS_3401U_EQ_3401U(...) \, +#define Z_IS_3402_EQ_3402(...) \, +#define Z_IS_3402U_EQ_3402(...) \, +#define Z_IS_3402_EQ_3402U(...) \, +#define Z_IS_3402U_EQ_3402U(...) \, +#define Z_IS_3403_EQ_3403(...) \, +#define Z_IS_3403U_EQ_3403(...) \, +#define Z_IS_3403_EQ_3403U(...) \, +#define Z_IS_3403U_EQ_3403U(...) \, +#define Z_IS_3404_EQ_3404(...) \, +#define Z_IS_3404U_EQ_3404(...) \, +#define Z_IS_3404_EQ_3404U(...) \, +#define Z_IS_3404U_EQ_3404U(...) \, +#define Z_IS_3405_EQ_3405(...) \, +#define Z_IS_3405U_EQ_3405(...) \, +#define Z_IS_3405_EQ_3405U(...) \, +#define Z_IS_3405U_EQ_3405U(...) \, +#define Z_IS_3406_EQ_3406(...) \, +#define Z_IS_3406U_EQ_3406(...) \, +#define Z_IS_3406_EQ_3406U(...) \, +#define Z_IS_3406U_EQ_3406U(...) \, +#define Z_IS_3407_EQ_3407(...) \, +#define Z_IS_3407U_EQ_3407(...) \, +#define Z_IS_3407_EQ_3407U(...) \, +#define Z_IS_3407U_EQ_3407U(...) \, +#define Z_IS_3408_EQ_3408(...) \, +#define Z_IS_3408U_EQ_3408(...) \, +#define Z_IS_3408_EQ_3408U(...) \, +#define Z_IS_3408U_EQ_3408U(...) \, +#define Z_IS_3409_EQ_3409(...) \, +#define Z_IS_3409U_EQ_3409(...) \, +#define Z_IS_3409_EQ_3409U(...) \, +#define Z_IS_3409U_EQ_3409U(...) \, +#define Z_IS_3410_EQ_3410(...) \, +#define Z_IS_3410U_EQ_3410(...) \, +#define Z_IS_3410_EQ_3410U(...) \, +#define Z_IS_3410U_EQ_3410U(...) \, +#define Z_IS_3411_EQ_3411(...) \, +#define Z_IS_3411U_EQ_3411(...) \, +#define Z_IS_3411_EQ_3411U(...) \, +#define Z_IS_3411U_EQ_3411U(...) \, +#define Z_IS_3412_EQ_3412(...) \, +#define Z_IS_3412U_EQ_3412(...) \, +#define Z_IS_3412_EQ_3412U(...) \, +#define Z_IS_3412U_EQ_3412U(...) \, +#define Z_IS_3413_EQ_3413(...) \, +#define Z_IS_3413U_EQ_3413(...) \, +#define Z_IS_3413_EQ_3413U(...) \, +#define Z_IS_3413U_EQ_3413U(...) \, +#define Z_IS_3414_EQ_3414(...) \, +#define Z_IS_3414U_EQ_3414(...) \, +#define Z_IS_3414_EQ_3414U(...) \, +#define Z_IS_3414U_EQ_3414U(...) \, +#define Z_IS_3415_EQ_3415(...) \, +#define Z_IS_3415U_EQ_3415(...) \, +#define Z_IS_3415_EQ_3415U(...) \, +#define Z_IS_3415U_EQ_3415U(...) \, +#define Z_IS_3416_EQ_3416(...) \, +#define Z_IS_3416U_EQ_3416(...) \, +#define Z_IS_3416_EQ_3416U(...) \, +#define Z_IS_3416U_EQ_3416U(...) \, +#define Z_IS_3417_EQ_3417(...) \, +#define Z_IS_3417U_EQ_3417(...) \, +#define Z_IS_3417_EQ_3417U(...) \, +#define Z_IS_3417U_EQ_3417U(...) \, +#define Z_IS_3418_EQ_3418(...) \, +#define Z_IS_3418U_EQ_3418(...) \, +#define Z_IS_3418_EQ_3418U(...) \, +#define Z_IS_3418U_EQ_3418U(...) \, +#define Z_IS_3419_EQ_3419(...) \, +#define Z_IS_3419U_EQ_3419(...) \, +#define Z_IS_3419_EQ_3419U(...) \, +#define Z_IS_3419U_EQ_3419U(...) \, +#define Z_IS_3420_EQ_3420(...) \, +#define Z_IS_3420U_EQ_3420(...) \, +#define Z_IS_3420_EQ_3420U(...) \, +#define Z_IS_3420U_EQ_3420U(...) \, +#define Z_IS_3421_EQ_3421(...) \, +#define Z_IS_3421U_EQ_3421(...) \, +#define Z_IS_3421_EQ_3421U(...) \, +#define Z_IS_3421U_EQ_3421U(...) \, +#define Z_IS_3422_EQ_3422(...) \, +#define Z_IS_3422U_EQ_3422(...) \, +#define Z_IS_3422_EQ_3422U(...) \, +#define Z_IS_3422U_EQ_3422U(...) \, +#define Z_IS_3423_EQ_3423(...) \, +#define Z_IS_3423U_EQ_3423(...) \, +#define Z_IS_3423_EQ_3423U(...) \, +#define Z_IS_3423U_EQ_3423U(...) \, +#define Z_IS_3424_EQ_3424(...) \, +#define Z_IS_3424U_EQ_3424(...) \, +#define Z_IS_3424_EQ_3424U(...) \, +#define Z_IS_3424U_EQ_3424U(...) \, +#define Z_IS_3425_EQ_3425(...) \, +#define Z_IS_3425U_EQ_3425(...) \, +#define Z_IS_3425_EQ_3425U(...) \, +#define Z_IS_3425U_EQ_3425U(...) \, +#define Z_IS_3426_EQ_3426(...) \, +#define Z_IS_3426U_EQ_3426(...) \, +#define Z_IS_3426_EQ_3426U(...) \, +#define Z_IS_3426U_EQ_3426U(...) \, +#define Z_IS_3427_EQ_3427(...) \, +#define Z_IS_3427U_EQ_3427(...) \, +#define Z_IS_3427_EQ_3427U(...) \, +#define Z_IS_3427U_EQ_3427U(...) \, +#define Z_IS_3428_EQ_3428(...) \, +#define Z_IS_3428U_EQ_3428(...) \, +#define Z_IS_3428_EQ_3428U(...) \, +#define Z_IS_3428U_EQ_3428U(...) \, +#define Z_IS_3429_EQ_3429(...) \, +#define Z_IS_3429U_EQ_3429(...) \, +#define Z_IS_3429_EQ_3429U(...) \, +#define Z_IS_3429U_EQ_3429U(...) \, +#define Z_IS_3430_EQ_3430(...) \, +#define Z_IS_3430U_EQ_3430(...) \, +#define Z_IS_3430_EQ_3430U(...) \, +#define Z_IS_3430U_EQ_3430U(...) \, +#define Z_IS_3431_EQ_3431(...) \, +#define Z_IS_3431U_EQ_3431(...) \, +#define Z_IS_3431_EQ_3431U(...) \, +#define Z_IS_3431U_EQ_3431U(...) \, +#define Z_IS_3432_EQ_3432(...) \, +#define Z_IS_3432U_EQ_3432(...) \, +#define Z_IS_3432_EQ_3432U(...) \, +#define Z_IS_3432U_EQ_3432U(...) \, +#define Z_IS_3433_EQ_3433(...) \, +#define Z_IS_3433U_EQ_3433(...) \, +#define Z_IS_3433_EQ_3433U(...) \, +#define Z_IS_3433U_EQ_3433U(...) \, +#define Z_IS_3434_EQ_3434(...) \, +#define Z_IS_3434U_EQ_3434(...) \, +#define Z_IS_3434_EQ_3434U(...) \, +#define Z_IS_3434U_EQ_3434U(...) \, +#define Z_IS_3435_EQ_3435(...) \, +#define Z_IS_3435U_EQ_3435(...) \, +#define Z_IS_3435_EQ_3435U(...) \, +#define Z_IS_3435U_EQ_3435U(...) \, +#define Z_IS_3436_EQ_3436(...) \, +#define Z_IS_3436U_EQ_3436(...) \, +#define Z_IS_3436_EQ_3436U(...) \, +#define Z_IS_3436U_EQ_3436U(...) \, +#define Z_IS_3437_EQ_3437(...) \, +#define Z_IS_3437U_EQ_3437(...) \, +#define Z_IS_3437_EQ_3437U(...) \, +#define Z_IS_3437U_EQ_3437U(...) \, +#define Z_IS_3438_EQ_3438(...) \, +#define Z_IS_3438U_EQ_3438(...) \, +#define Z_IS_3438_EQ_3438U(...) \, +#define Z_IS_3438U_EQ_3438U(...) \, +#define Z_IS_3439_EQ_3439(...) \, +#define Z_IS_3439U_EQ_3439(...) \, +#define Z_IS_3439_EQ_3439U(...) \, +#define Z_IS_3439U_EQ_3439U(...) \, +#define Z_IS_3440_EQ_3440(...) \, +#define Z_IS_3440U_EQ_3440(...) \, +#define Z_IS_3440_EQ_3440U(...) \, +#define Z_IS_3440U_EQ_3440U(...) \, +#define Z_IS_3441_EQ_3441(...) \, +#define Z_IS_3441U_EQ_3441(...) \, +#define Z_IS_3441_EQ_3441U(...) \, +#define Z_IS_3441U_EQ_3441U(...) \, +#define Z_IS_3442_EQ_3442(...) \, +#define Z_IS_3442U_EQ_3442(...) \, +#define Z_IS_3442_EQ_3442U(...) \, +#define Z_IS_3442U_EQ_3442U(...) \, +#define Z_IS_3443_EQ_3443(...) \, +#define Z_IS_3443U_EQ_3443(...) \, +#define Z_IS_3443_EQ_3443U(...) \, +#define Z_IS_3443U_EQ_3443U(...) \, +#define Z_IS_3444_EQ_3444(...) \, +#define Z_IS_3444U_EQ_3444(...) \, +#define Z_IS_3444_EQ_3444U(...) \, +#define Z_IS_3444U_EQ_3444U(...) \, +#define Z_IS_3445_EQ_3445(...) \, +#define Z_IS_3445U_EQ_3445(...) \, +#define Z_IS_3445_EQ_3445U(...) \, +#define Z_IS_3445U_EQ_3445U(...) \, +#define Z_IS_3446_EQ_3446(...) \, +#define Z_IS_3446U_EQ_3446(...) \, +#define Z_IS_3446_EQ_3446U(...) \, +#define Z_IS_3446U_EQ_3446U(...) \, +#define Z_IS_3447_EQ_3447(...) \, +#define Z_IS_3447U_EQ_3447(...) \, +#define Z_IS_3447_EQ_3447U(...) \, +#define Z_IS_3447U_EQ_3447U(...) \, +#define Z_IS_3448_EQ_3448(...) \, +#define Z_IS_3448U_EQ_3448(...) \, +#define Z_IS_3448_EQ_3448U(...) \, +#define Z_IS_3448U_EQ_3448U(...) \, +#define Z_IS_3449_EQ_3449(...) \, +#define Z_IS_3449U_EQ_3449(...) \, +#define Z_IS_3449_EQ_3449U(...) \, +#define Z_IS_3449U_EQ_3449U(...) \, +#define Z_IS_3450_EQ_3450(...) \, +#define Z_IS_3450U_EQ_3450(...) \, +#define Z_IS_3450_EQ_3450U(...) \, +#define Z_IS_3450U_EQ_3450U(...) \, +#define Z_IS_3451_EQ_3451(...) \, +#define Z_IS_3451U_EQ_3451(...) \, +#define Z_IS_3451_EQ_3451U(...) \, +#define Z_IS_3451U_EQ_3451U(...) \, +#define Z_IS_3452_EQ_3452(...) \, +#define Z_IS_3452U_EQ_3452(...) \, +#define Z_IS_3452_EQ_3452U(...) \, +#define Z_IS_3452U_EQ_3452U(...) \, +#define Z_IS_3453_EQ_3453(...) \, +#define Z_IS_3453U_EQ_3453(...) \, +#define Z_IS_3453_EQ_3453U(...) \, +#define Z_IS_3453U_EQ_3453U(...) \, +#define Z_IS_3454_EQ_3454(...) \, +#define Z_IS_3454U_EQ_3454(...) \, +#define Z_IS_3454_EQ_3454U(...) \, +#define Z_IS_3454U_EQ_3454U(...) \, +#define Z_IS_3455_EQ_3455(...) \, +#define Z_IS_3455U_EQ_3455(...) \, +#define Z_IS_3455_EQ_3455U(...) \, +#define Z_IS_3455U_EQ_3455U(...) \, +#define Z_IS_3456_EQ_3456(...) \, +#define Z_IS_3456U_EQ_3456(...) \, +#define Z_IS_3456_EQ_3456U(...) \, +#define Z_IS_3456U_EQ_3456U(...) \, +#define Z_IS_3457_EQ_3457(...) \, +#define Z_IS_3457U_EQ_3457(...) \, +#define Z_IS_3457_EQ_3457U(...) \, +#define Z_IS_3457U_EQ_3457U(...) \, +#define Z_IS_3458_EQ_3458(...) \, +#define Z_IS_3458U_EQ_3458(...) \, +#define Z_IS_3458_EQ_3458U(...) \, +#define Z_IS_3458U_EQ_3458U(...) \, +#define Z_IS_3459_EQ_3459(...) \, +#define Z_IS_3459U_EQ_3459(...) \, +#define Z_IS_3459_EQ_3459U(...) \, +#define Z_IS_3459U_EQ_3459U(...) \, +#define Z_IS_3460_EQ_3460(...) \, +#define Z_IS_3460U_EQ_3460(...) \, +#define Z_IS_3460_EQ_3460U(...) \, +#define Z_IS_3460U_EQ_3460U(...) \, +#define Z_IS_3461_EQ_3461(...) \, +#define Z_IS_3461U_EQ_3461(...) \, +#define Z_IS_3461_EQ_3461U(...) \, +#define Z_IS_3461U_EQ_3461U(...) \, +#define Z_IS_3462_EQ_3462(...) \, +#define Z_IS_3462U_EQ_3462(...) \, +#define Z_IS_3462_EQ_3462U(...) \, +#define Z_IS_3462U_EQ_3462U(...) \, +#define Z_IS_3463_EQ_3463(...) \, +#define Z_IS_3463U_EQ_3463(...) \, +#define Z_IS_3463_EQ_3463U(...) \, +#define Z_IS_3463U_EQ_3463U(...) \, +#define Z_IS_3464_EQ_3464(...) \, +#define Z_IS_3464U_EQ_3464(...) \, +#define Z_IS_3464_EQ_3464U(...) \, +#define Z_IS_3464U_EQ_3464U(...) \, +#define Z_IS_3465_EQ_3465(...) \, +#define Z_IS_3465U_EQ_3465(...) \, +#define Z_IS_3465_EQ_3465U(...) \, +#define Z_IS_3465U_EQ_3465U(...) \, +#define Z_IS_3466_EQ_3466(...) \, +#define Z_IS_3466U_EQ_3466(...) \, +#define Z_IS_3466_EQ_3466U(...) \, +#define Z_IS_3466U_EQ_3466U(...) \, +#define Z_IS_3467_EQ_3467(...) \, +#define Z_IS_3467U_EQ_3467(...) \, +#define Z_IS_3467_EQ_3467U(...) \, +#define Z_IS_3467U_EQ_3467U(...) \, +#define Z_IS_3468_EQ_3468(...) \, +#define Z_IS_3468U_EQ_3468(...) \, +#define Z_IS_3468_EQ_3468U(...) \, +#define Z_IS_3468U_EQ_3468U(...) \, +#define Z_IS_3469_EQ_3469(...) \, +#define Z_IS_3469U_EQ_3469(...) \, +#define Z_IS_3469_EQ_3469U(...) \, +#define Z_IS_3469U_EQ_3469U(...) \, +#define Z_IS_3470_EQ_3470(...) \, +#define Z_IS_3470U_EQ_3470(...) \, +#define Z_IS_3470_EQ_3470U(...) \, +#define Z_IS_3470U_EQ_3470U(...) \, +#define Z_IS_3471_EQ_3471(...) \, +#define Z_IS_3471U_EQ_3471(...) \, +#define Z_IS_3471_EQ_3471U(...) \, +#define Z_IS_3471U_EQ_3471U(...) \, +#define Z_IS_3472_EQ_3472(...) \, +#define Z_IS_3472U_EQ_3472(...) \, +#define Z_IS_3472_EQ_3472U(...) \, +#define Z_IS_3472U_EQ_3472U(...) \, +#define Z_IS_3473_EQ_3473(...) \, +#define Z_IS_3473U_EQ_3473(...) \, +#define Z_IS_3473_EQ_3473U(...) \, +#define Z_IS_3473U_EQ_3473U(...) \, +#define Z_IS_3474_EQ_3474(...) \, +#define Z_IS_3474U_EQ_3474(...) \, +#define Z_IS_3474_EQ_3474U(...) \, +#define Z_IS_3474U_EQ_3474U(...) \, +#define Z_IS_3475_EQ_3475(...) \, +#define Z_IS_3475U_EQ_3475(...) \, +#define Z_IS_3475_EQ_3475U(...) \, +#define Z_IS_3475U_EQ_3475U(...) \, +#define Z_IS_3476_EQ_3476(...) \, +#define Z_IS_3476U_EQ_3476(...) \, +#define Z_IS_3476_EQ_3476U(...) \, +#define Z_IS_3476U_EQ_3476U(...) \, +#define Z_IS_3477_EQ_3477(...) \, +#define Z_IS_3477U_EQ_3477(...) \, +#define Z_IS_3477_EQ_3477U(...) \, +#define Z_IS_3477U_EQ_3477U(...) \, +#define Z_IS_3478_EQ_3478(...) \, +#define Z_IS_3478U_EQ_3478(...) \, +#define Z_IS_3478_EQ_3478U(...) \, +#define Z_IS_3478U_EQ_3478U(...) \, +#define Z_IS_3479_EQ_3479(...) \, +#define Z_IS_3479U_EQ_3479(...) \, +#define Z_IS_3479_EQ_3479U(...) \, +#define Z_IS_3479U_EQ_3479U(...) \, +#define Z_IS_3480_EQ_3480(...) \, +#define Z_IS_3480U_EQ_3480(...) \, +#define Z_IS_3480_EQ_3480U(...) \, +#define Z_IS_3480U_EQ_3480U(...) \, +#define Z_IS_3481_EQ_3481(...) \, +#define Z_IS_3481U_EQ_3481(...) \, +#define Z_IS_3481_EQ_3481U(...) \, +#define Z_IS_3481U_EQ_3481U(...) \, +#define Z_IS_3482_EQ_3482(...) \, +#define Z_IS_3482U_EQ_3482(...) \, +#define Z_IS_3482_EQ_3482U(...) \, +#define Z_IS_3482U_EQ_3482U(...) \, +#define Z_IS_3483_EQ_3483(...) \, +#define Z_IS_3483U_EQ_3483(...) \, +#define Z_IS_3483_EQ_3483U(...) \, +#define Z_IS_3483U_EQ_3483U(...) \, +#define Z_IS_3484_EQ_3484(...) \, +#define Z_IS_3484U_EQ_3484(...) \, +#define Z_IS_3484_EQ_3484U(...) \, +#define Z_IS_3484U_EQ_3484U(...) \, +#define Z_IS_3485_EQ_3485(...) \, +#define Z_IS_3485U_EQ_3485(...) \, +#define Z_IS_3485_EQ_3485U(...) \, +#define Z_IS_3485U_EQ_3485U(...) \, +#define Z_IS_3486_EQ_3486(...) \, +#define Z_IS_3486U_EQ_3486(...) \, +#define Z_IS_3486_EQ_3486U(...) \, +#define Z_IS_3486U_EQ_3486U(...) \, +#define Z_IS_3487_EQ_3487(...) \, +#define Z_IS_3487U_EQ_3487(...) \, +#define Z_IS_3487_EQ_3487U(...) \, +#define Z_IS_3487U_EQ_3487U(...) \, +#define Z_IS_3488_EQ_3488(...) \, +#define Z_IS_3488U_EQ_3488(...) \, +#define Z_IS_3488_EQ_3488U(...) \, +#define Z_IS_3488U_EQ_3488U(...) \, +#define Z_IS_3489_EQ_3489(...) \, +#define Z_IS_3489U_EQ_3489(...) \, +#define Z_IS_3489_EQ_3489U(...) \, +#define Z_IS_3489U_EQ_3489U(...) \, +#define Z_IS_3490_EQ_3490(...) \, +#define Z_IS_3490U_EQ_3490(...) \, +#define Z_IS_3490_EQ_3490U(...) \, +#define Z_IS_3490U_EQ_3490U(...) \, +#define Z_IS_3491_EQ_3491(...) \, +#define Z_IS_3491U_EQ_3491(...) \, +#define Z_IS_3491_EQ_3491U(...) \, +#define Z_IS_3491U_EQ_3491U(...) \, +#define Z_IS_3492_EQ_3492(...) \, +#define Z_IS_3492U_EQ_3492(...) \, +#define Z_IS_3492_EQ_3492U(...) \, +#define Z_IS_3492U_EQ_3492U(...) \, +#define Z_IS_3493_EQ_3493(...) \, +#define Z_IS_3493U_EQ_3493(...) \, +#define Z_IS_3493_EQ_3493U(...) \, +#define Z_IS_3493U_EQ_3493U(...) \, +#define Z_IS_3494_EQ_3494(...) \, +#define Z_IS_3494U_EQ_3494(...) \, +#define Z_IS_3494_EQ_3494U(...) \, +#define Z_IS_3494U_EQ_3494U(...) \, +#define Z_IS_3495_EQ_3495(...) \, +#define Z_IS_3495U_EQ_3495(...) \, +#define Z_IS_3495_EQ_3495U(...) \, +#define Z_IS_3495U_EQ_3495U(...) \, +#define Z_IS_3496_EQ_3496(...) \, +#define Z_IS_3496U_EQ_3496(...) \, +#define Z_IS_3496_EQ_3496U(...) \, +#define Z_IS_3496U_EQ_3496U(...) \, +#define Z_IS_3497_EQ_3497(...) \, +#define Z_IS_3497U_EQ_3497(...) \, +#define Z_IS_3497_EQ_3497U(...) \, +#define Z_IS_3497U_EQ_3497U(...) \, +#define Z_IS_3498_EQ_3498(...) \, +#define Z_IS_3498U_EQ_3498(...) \, +#define Z_IS_3498_EQ_3498U(...) \, +#define Z_IS_3498U_EQ_3498U(...) \, +#define Z_IS_3499_EQ_3499(...) \, +#define Z_IS_3499U_EQ_3499(...) \, +#define Z_IS_3499_EQ_3499U(...) \, +#define Z_IS_3499U_EQ_3499U(...) \, +#define Z_IS_3500_EQ_3500(...) \, +#define Z_IS_3500U_EQ_3500(...) \, +#define Z_IS_3500_EQ_3500U(...) \, +#define Z_IS_3500U_EQ_3500U(...) \, +#define Z_IS_3501_EQ_3501(...) \, +#define Z_IS_3501U_EQ_3501(...) \, +#define Z_IS_3501_EQ_3501U(...) \, +#define Z_IS_3501U_EQ_3501U(...) \, +#define Z_IS_3502_EQ_3502(...) \, +#define Z_IS_3502U_EQ_3502(...) \, +#define Z_IS_3502_EQ_3502U(...) \, +#define Z_IS_3502U_EQ_3502U(...) \, +#define Z_IS_3503_EQ_3503(...) \, +#define Z_IS_3503U_EQ_3503(...) \, +#define Z_IS_3503_EQ_3503U(...) \, +#define Z_IS_3503U_EQ_3503U(...) \, +#define Z_IS_3504_EQ_3504(...) \, +#define Z_IS_3504U_EQ_3504(...) \, +#define Z_IS_3504_EQ_3504U(...) \, +#define Z_IS_3504U_EQ_3504U(...) \, +#define Z_IS_3505_EQ_3505(...) \, +#define Z_IS_3505U_EQ_3505(...) \, +#define Z_IS_3505_EQ_3505U(...) \, +#define Z_IS_3505U_EQ_3505U(...) \, +#define Z_IS_3506_EQ_3506(...) \, +#define Z_IS_3506U_EQ_3506(...) \, +#define Z_IS_3506_EQ_3506U(...) \, +#define Z_IS_3506U_EQ_3506U(...) \, +#define Z_IS_3507_EQ_3507(...) \, +#define Z_IS_3507U_EQ_3507(...) \, +#define Z_IS_3507_EQ_3507U(...) \, +#define Z_IS_3507U_EQ_3507U(...) \, +#define Z_IS_3508_EQ_3508(...) \, +#define Z_IS_3508U_EQ_3508(...) \, +#define Z_IS_3508_EQ_3508U(...) \, +#define Z_IS_3508U_EQ_3508U(...) \, +#define Z_IS_3509_EQ_3509(...) \, +#define Z_IS_3509U_EQ_3509(...) \, +#define Z_IS_3509_EQ_3509U(...) \, +#define Z_IS_3509U_EQ_3509U(...) \, +#define Z_IS_3510_EQ_3510(...) \, +#define Z_IS_3510U_EQ_3510(...) \, +#define Z_IS_3510_EQ_3510U(...) \, +#define Z_IS_3510U_EQ_3510U(...) \, +#define Z_IS_3511_EQ_3511(...) \, +#define Z_IS_3511U_EQ_3511(...) \, +#define Z_IS_3511_EQ_3511U(...) \, +#define Z_IS_3511U_EQ_3511U(...) \, +#define Z_IS_3512_EQ_3512(...) \, +#define Z_IS_3512U_EQ_3512(...) \, +#define Z_IS_3512_EQ_3512U(...) \, +#define Z_IS_3512U_EQ_3512U(...) \, +#define Z_IS_3513_EQ_3513(...) \, +#define Z_IS_3513U_EQ_3513(...) \, +#define Z_IS_3513_EQ_3513U(...) \, +#define Z_IS_3513U_EQ_3513U(...) \, +#define Z_IS_3514_EQ_3514(...) \, +#define Z_IS_3514U_EQ_3514(...) \, +#define Z_IS_3514_EQ_3514U(...) \, +#define Z_IS_3514U_EQ_3514U(...) \, +#define Z_IS_3515_EQ_3515(...) \, +#define Z_IS_3515U_EQ_3515(...) \, +#define Z_IS_3515_EQ_3515U(...) \, +#define Z_IS_3515U_EQ_3515U(...) \, +#define Z_IS_3516_EQ_3516(...) \, +#define Z_IS_3516U_EQ_3516(...) \, +#define Z_IS_3516_EQ_3516U(...) \, +#define Z_IS_3516U_EQ_3516U(...) \, +#define Z_IS_3517_EQ_3517(...) \, +#define Z_IS_3517U_EQ_3517(...) \, +#define Z_IS_3517_EQ_3517U(...) \, +#define Z_IS_3517U_EQ_3517U(...) \, +#define Z_IS_3518_EQ_3518(...) \, +#define Z_IS_3518U_EQ_3518(...) \, +#define Z_IS_3518_EQ_3518U(...) \, +#define Z_IS_3518U_EQ_3518U(...) \, +#define Z_IS_3519_EQ_3519(...) \, +#define Z_IS_3519U_EQ_3519(...) \, +#define Z_IS_3519_EQ_3519U(...) \, +#define Z_IS_3519U_EQ_3519U(...) \, +#define Z_IS_3520_EQ_3520(...) \, +#define Z_IS_3520U_EQ_3520(...) \, +#define Z_IS_3520_EQ_3520U(...) \, +#define Z_IS_3520U_EQ_3520U(...) \, +#define Z_IS_3521_EQ_3521(...) \, +#define Z_IS_3521U_EQ_3521(...) \, +#define Z_IS_3521_EQ_3521U(...) \, +#define Z_IS_3521U_EQ_3521U(...) \, +#define Z_IS_3522_EQ_3522(...) \, +#define Z_IS_3522U_EQ_3522(...) \, +#define Z_IS_3522_EQ_3522U(...) \, +#define Z_IS_3522U_EQ_3522U(...) \, +#define Z_IS_3523_EQ_3523(...) \, +#define Z_IS_3523U_EQ_3523(...) \, +#define Z_IS_3523_EQ_3523U(...) \, +#define Z_IS_3523U_EQ_3523U(...) \, +#define Z_IS_3524_EQ_3524(...) \, +#define Z_IS_3524U_EQ_3524(...) \, +#define Z_IS_3524_EQ_3524U(...) \, +#define Z_IS_3524U_EQ_3524U(...) \, +#define Z_IS_3525_EQ_3525(...) \, +#define Z_IS_3525U_EQ_3525(...) \, +#define Z_IS_3525_EQ_3525U(...) \, +#define Z_IS_3525U_EQ_3525U(...) \, +#define Z_IS_3526_EQ_3526(...) \, +#define Z_IS_3526U_EQ_3526(...) \, +#define Z_IS_3526_EQ_3526U(...) \, +#define Z_IS_3526U_EQ_3526U(...) \, +#define Z_IS_3527_EQ_3527(...) \, +#define Z_IS_3527U_EQ_3527(...) \, +#define Z_IS_3527_EQ_3527U(...) \, +#define Z_IS_3527U_EQ_3527U(...) \, +#define Z_IS_3528_EQ_3528(...) \, +#define Z_IS_3528U_EQ_3528(...) \, +#define Z_IS_3528_EQ_3528U(...) \, +#define Z_IS_3528U_EQ_3528U(...) \, +#define Z_IS_3529_EQ_3529(...) \, +#define Z_IS_3529U_EQ_3529(...) \, +#define Z_IS_3529_EQ_3529U(...) \, +#define Z_IS_3529U_EQ_3529U(...) \, +#define Z_IS_3530_EQ_3530(...) \, +#define Z_IS_3530U_EQ_3530(...) \, +#define Z_IS_3530_EQ_3530U(...) \, +#define Z_IS_3530U_EQ_3530U(...) \, +#define Z_IS_3531_EQ_3531(...) \, +#define Z_IS_3531U_EQ_3531(...) \, +#define Z_IS_3531_EQ_3531U(...) \, +#define Z_IS_3531U_EQ_3531U(...) \, +#define Z_IS_3532_EQ_3532(...) \, +#define Z_IS_3532U_EQ_3532(...) \, +#define Z_IS_3532_EQ_3532U(...) \, +#define Z_IS_3532U_EQ_3532U(...) \, +#define Z_IS_3533_EQ_3533(...) \, +#define Z_IS_3533U_EQ_3533(...) \, +#define Z_IS_3533_EQ_3533U(...) \, +#define Z_IS_3533U_EQ_3533U(...) \, +#define Z_IS_3534_EQ_3534(...) \, +#define Z_IS_3534U_EQ_3534(...) \, +#define Z_IS_3534_EQ_3534U(...) \, +#define Z_IS_3534U_EQ_3534U(...) \, +#define Z_IS_3535_EQ_3535(...) \, +#define Z_IS_3535U_EQ_3535(...) \, +#define Z_IS_3535_EQ_3535U(...) \, +#define Z_IS_3535U_EQ_3535U(...) \, +#define Z_IS_3536_EQ_3536(...) \, +#define Z_IS_3536U_EQ_3536(...) \, +#define Z_IS_3536_EQ_3536U(...) \, +#define Z_IS_3536U_EQ_3536U(...) \, +#define Z_IS_3537_EQ_3537(...) \, +#define Z_IS_3537U_EQ_3537(...) \, +#define Z_IS_3537_EQ_3537U(...) \, +#define Z_IS_3537U_EQ_3537U(...) \, +#define Z_IS_3538_EQ_3538(...) \, +#define Z_IS_3538U_EQ_3538(...) \, +#define Z_IS_3538_EQ_3538U(...) \, +#define Z_IS_3538U_EQ_3538U(...) \, +#define Z_IS_3539_EQ_3539(...) \, +#define Z_IS_3539U_EQ_3539(...) \, +#define Z_IS_3539_EQ_3539U(...) \, +#define Z_IS_3539U_EQ_3539U(...) \, +#define Z_IS_3540_EQ_3540(...) \, +#define Z_IS_3540U_EQ_3540(...) \, +#define Z_IS_3540_EQ_3540U(...) \, +#define Z_IS_3540U_EQ_3540U(...) \, +#define Z_IS_3541_EQ_3541(...) \, +#define Z_IS_3541U_EQ_3541(...) \, +#define Z_IS_3541_EQ_3541U(...) \, +#define Z_IS_3541U_EQ_3541U(...) \, +#define Z_IS_3542_EQ_3542(...) \, +#define Z_IS_3542U_EQ_3542(...) \, +#define Z_IS_3542_EQ_3542U(...) \, +#define Z_IS_3542U_EQ_3542U(...) \, +#define Z_IS_3543_EQ_3543(...) \, +#define Z_IS_3543U_EQ_3543(...) \, +#define Z_IS_3543_EQ_3543U(...) \, +#define Z_IS_3543U_EQ_3543U(...) \, +#define Z_IS_3544_EQ_3544(...) \, +#define Z_IS_3544U_EQ_3544(...) \, +#define Z_IS_3544_EQ_3544U(...) \, +#define Z_IS_3544U_EQ_3544U(...) \, +#define Z_IS_3545_EQ_3545(...) \, +#define Z_IS_3545U_EQ_3545(...) \, +#define Z_IS_3545_EQ_3545U(...) \, +#define Z_IS_3545U_EQ_3545U(...) \, +#define Z_IS_3546_EQ_3546(...) \, +#define Z_IS_3546U_EQ_3546(...) \, +#define Z_IS_3546_EQ_3546U(...) \, +#define Z_IS_3546U_EQ_3546U(...) \, +#define Z_IS_3547_EQ_3547(...) \, +#define Z_IS_3547U_EQ_3547(...) \, +#define Z_IS_3547_EQ_3547U(...) \, +#define Z_IS_3547U_EQ_3547U(...) \, +#define Z_IS_3548_EQ_3548(...) \, +#define Z_IS_3548U_EQ_3548(...) \, +#define Z_IS_3548_EQ_3548U(...) \, +#define Z_IS_3548U_EQ_3548U(...) \, +#define Z_IS_3549_EQ_3549(...) \, +#define Z_IS_3549U_EQ_3549(...) \, +#define Z_IS_3549_EQ_3549U(...) \, +#define Z_IS_3549U_EQ_3549U(...) \, +#define Z_IS_3550_EQ_3550(...) \, +#define Z_IS_3550U_EQ_3550(...) \, +#define Z_IS_3550_EQ_3550U(...) \, +#define Z_IS_3550U_EQ_3550U(...) \, +#define Z_IS_3551_EQ_3551(...) \, +#define Z_IS_3551U_EQ_3551(...) \, +#define Z_IS_3551_EQ_3551U(...) \, +#define Z_IS_3551U_EQ_3551U(...) \, +#define Z_IS_3552_EQ_3552(...) \, +#define Z_IS_3552U_EQ_3552(...) \, +#define Z_IS_3552_EQ_3552U(...) \, +#define Z_IS_3552U_EQ_3552U(...) \, +#define Z_IS_3553_EQ_3553(...) \, +#define Z_IS_3553U_EQ_3553(...) \, +#define Z_IS_3553_EQ_3553U(...) \, +#define Z_IS_3553U_EQ_3553U(...) \, +#define Z_IS_3554_EQ_3554(...) \, +#define Z_IS_3554U_EQ_3554(...) \, +#define Z_IS_3554_EQ_3554U(...) \, +#define Z_IS_3554U_EQ_3554U(...) \, +#define Z_IS_3555_EQ_3555(...) \, +#define Z_IS_3555U_EQ_3555(...) \, +#define Z_IS_3555_EQ_3555U(...) \, +#define Z_IS_3555U_EQ_3555U(...) \, +#define Z_IS_3556_EQ_3556(...) \, +#define Z_IS_3556U_EQ_3556(...) \, +#define Z_IS_3556_EQ_3556U(...) \, +#define Z_IS_3556U_EQ_3556U(...) \, +#define Z_IS_3557_EQ_3557(...) \, +#define Z_IS_3557U_EQ_3557(...) \, +#define Z_IS_3557_EQ_3557U(...) \, +#define Z_IS_3557U_EQ_3557U(...) \, +#define Z_IS_3558_EQ_3558(...) \, +#define Z_IS_3558U_EQ_3558(...) \, +#define Z_IS_3558_EQ_3558U(...) \, +#define Z_IS_3558U_EQ_3558U(...) \, +#define Z_IS_3559_EQ_3559(...) \, +#define Z_IS_3559U_EQ_3559(...) \, +#define Z_IS_3559_EQ_3559U(...) \, +#define Z_IS_3559U_EQ_3559U(...) \, +#define Z_IS_3560_EQ_3560(...) \, +#define Z_IS_3560U_EQ_3560(...) \, +#define Z_IS_3560_EQ_3560U(...) \, +#define Z_IS_3560U_EQ_3560U(...) \, +#define Z_IS_3561_EQ_3561(...) \, +#define Z_IS_3561U_EQ_3561(...) \, +#define Z_IS_3561_EQ_3561U(...) \, +#define Z_IS_3561U_EQ_3561U(...) \, +#define Z_IS_3562_EQ_3562(...) \, +#define Z_IS_3562U_EQ_3562(...) \, +#define Z_IS_3562_EQ_3562U(...) \, +#define Z_IS_3562U_EQ_3562U(...) \, +#define Z_IS_3563_EQ_3563(...) \, +#define Z_IS_3563U_EQ_3563(...) \, +#define Z_IS_3563_EQ_3563U(...) \, +#define Z_IS_3563U_EQ_3563U(...) \, +#define Z_IS_3564_EQ_3564(...) \, +#define Z_IS_3564U_EQ_3564(...) \, +#define Z_IS_3564_EQ_3564U(...) \, +#define Z_IS_3564U_EQ_3564U(...) \, +#define Z_IS_3565_EQ_3565(...) \, +#define Z_IS_3565U_EQ_3565(...) \, +#define Z_IS_3565_EQ_3565U(...) \, +#define Z_IS_3565U_EQ_3565U(...) \, +#define Z_IS_3566_EQ_3566(...) \, +#define Z_IS_3566U_EQ_3566(...) \, +#define Z_IS_3566_EQ_3566U(...) \, +#define Z_IS_3566U_EQ_3566U(...) \, +#define Z_IS_3567_EQ_3567(...) \, +#define Z_IS_3567U_EQ_3567(...) \, +#define Z_IS_3567_EQ_3567U(...) \, +#define Z_IS_3567U_EQ_3567U(...) \, +#define Z_IS_3568_EQ_3568(...) \, +#define Z_IS_3568U_EQ_3568(...) \, +#define Z_IS_3568_EQ_3568U(...) \, +#define Z_IS_3568U_EQ_3568U(...) \, +#define Z_IS_3569_EQ_3569(...) \, +#define Z_IS_3569U_EQ_3569(...) \, +#define Z_IS_3569_EQ_3569U(...) \, +#define Z_IS_3569U_EQ_3569U(...) \, +#define Z_IS_3570_EQ_3570(...) \, +#define Z_IS_3570U_EQ_3570(...) \, +#define Z_IS_3570_EQ_3570U(...) \, +#define Z_IS_3570U_EQ_3570U(...) \, +#define Z_IS_3571_EQ_3571(...) \, +#define Z_IS_3571U_EQ_3571(...) \, +#define Z_IS_3571_EQ_3571U(...) \, +#define Z_IS_3571U_EQ_3571U(...) \, +#define Z_IS_3572_EQ_3572(...) \, +#define Z_IS_3572U_EQ_3572(...) \, +#define Z_IS_3572_EQ_3572U(...) \, +#define Z_IS_3572U_EQ_3572U(...) \, +#define Z_IS_3573_EQ_3573(...) \, +#define Z_IS_3573U_EQ_3573(...) \, +#define Z_IS_3573_EQ_3573U(...) \, +#define Z_IS_3573U_EQ_3573U(...) \, +#define Z_IS_3574_EQ_3574(...) \, +#define Z_IS_3574U_EQ_3574(...) \, +#define Z_IS_3574_EQ_3574U(...) \, +#define Z_IS_3574U_EQ_3574U(...) \, +#define Z_IS_3575_EQ_3575(...) \, +#define Z_IS_3575U_EQ_3575(...) \, +#define Z_IS_3575_EQ_3575U(...) \, +#define Z_IS_3575U_EQ_3575U(...) \, +#define Z_IS_3576_EQ_3576(...) \, +#define Z_IS_3576U_EQ_3576(...) \, +#define Z_IS_3576_EQ_3576U(...) \, +#define Z_IS_3576U_EQ_3576U(...) \, +#define Z_IS_3577_EQ_3577(...) \, +#define Z_IS_3577U_EQ_3577(...) \, +#define Z_IS_3577_EQ_3577U(...) \, +#define Z_IS_3577U_EQ_3577U(...) \, +#define Z_IS_3578_EQ_3578(...) \, +#define Z_IS_3578U_EQ_3578(...) \, +#define Z_IS_3578_EQ_3578U(...) \, +#define Z_IS_3578U_EQ_3578U(...) \, +#define Z_IS_3579_EQ_3579(...) \, +#define Z_IS_3579U_EQ_3579(...) \, +#define Z_IS_3579_EQ_3579U(...) \, +#define Z_IS_3579U_EQ_3579U(...) \, +#define Z_IS_3580_EQ_3580(...) \, +#define Z_IS_3580U_EQ_3580(...) \, +#define Z_IS_3580_EQ_3580U(...) \, +#define Z_IS_3580U_EQ_3580U(...) \, +#define Z_IS_3581_EQ_3581(...) \, +#define Z_IS_3581U_EQ_3581(...) \, +#define Z_IS_3581_EQ_3581U(...) \, +#define Z_IS_3581U_EQ_3581U(...) \, +#define Z_IS_3582_EQ_3582(...) \, +#define Z_IS_3582U_EQ_3582(...) \, +#define Z_IS_3582_EQ_3582U(...) \, +#define Z_IS_3582U_EQ_3582U(...) \, +#define Z_IS_3583_EQ_3583(...) \, +#define Z_IS_3583U_EQ_3583(...) \, +#define Z_IS_3583_EQ_3583U(...) \, +#define Z_IS_3583U_EQ_3583U(...) \, +#define Z_IS_3584_EQ_3584(...) \, +#define Z_IS_3584U_EQ_3584(...) \, +#define Z_IS_3584_EQ_3584U(...) \, +#define Z_IS_3584U_EQ_3584U(...) \, +#define Z_IS_3585_EQ_3585(...) \, +#define Z_IS_3585U_EQ_3585(...) \, +#define Z_IS_3585_EQ_3585U(...) \, +#define Z_IS_3585U_EQ_3585U(...) \, +#define Z_IS_3586_EQ_3586(...) \, +#define Z_IS_3586U_EQ_3586(...) \, +#define Z_IS_3586_EQ_3586U(...) \, +#define Z_IS_3586U_EQ_3586U(...) \, +#define Z_IS_3587_EQ_3587(...) \, +#define Z_IS_3587U_EQ_3587(...) \, +#define Z_IS_3587_EQ_3587U(...) \, +#define Z_IS_3587U_EQ_3587U(...) \, +#define Z_IS_3588_EQ_3588(...) \, +#define Z_IS_3588U_EQ_3588(...) \, +#define Z_IS_3588_EQ_3588U(...) \, +#define Z_IS_3588U_EQ_3588U(...) \, +#define Z_IS_3589_EQ_3589(...) \, +#define Z_IS_3589U_EQ_3589(...) \, +#define Z_IS_3589_EQ_3589U(...) \, +#define Z_IS_3589U_EQ_3589U(...) \, +#define Z_IS_3590_EQ_3590(...) \, +#define Z_IS_3590U_EQ_3590(...) \, +#define Z_IS_3590_EQ_3590U(...) \, +#define Z_IS_3590U_EQ_3590U(...) \, +#define Z_IS_3591_EQ_3591(...) \, +#define Z_IS_3591U_EQ_3591(...) \, +#define Z_IS_3591_EQ_3591U(...) \, +#define Z_IS_3591U_EQ_3591U(...) \, +#define Z_IS_3592_EQ_3592(...) \, +#define Z_IS_3592U_EQ_3592(...) \, +#define Z_IS_3592_EQ_3592U(...) \, +#define Z_IS_3592U_EQ_3592U(...) \, +#define Z_IS_3593_EQ_3593(...) \, +#define Z_IS_3593U_EQ_3593(...) \, +#define Z_IS_3593_EQ_3593U(...) \, +#define Z_IS_3593U_EQ_3593U(...) \, +#define Z_IS_3594_EQ_3594(...) \, +#define Z_IS_3594U_EQ_3594(...) \, +#define Z_IS_3594_EQ_3594U(...) \, +#define Z_IS_3594U_EQ_3594U(...) \, +#define Z_IS_3595_EQ_3595(...) \, +#define Z_IS_3595U_EQ_3595(...) \, +#define Z_IS_3595_EQ_3595U(...) \, +#define Z_IS_3595U_EQ_3595U(...) \, +#define Z_IS_3596_EQ_3596(...) \, +#define Z_IS_3596U_EQ_3596(...) \, +#define Z_IS_3596_EQ_3596U(...) \, +#define Z_IS_3596U_EQ_3596U(...) \, +#define Z_IS_3597_EQ_3597(...) \, +#define Z_IS_3597U_EQ_3597(...) \, +#define Z_IS_3597_EQ_3597U(...) \, +#define Z_IS_3597U_EQ_3597U(...) \, +#define Z_IS_3598_EQ_3598(...) \, +#define Z_IS_3598U_EQ_3598(...) \, +#define Z_IS_3598_EQ_3598U(...) \, +#define Z_IS_3598U_EQ_3598U(...) \, +#define Z_IS_3599_EQ_3599(...) \, +#define Z_IS_3599U_EQ_3599(...) \, +#define Z_IS_3599_EQ_3599U(...) \, +#define Z_IS_3599U_EQ_3599U(...) \, +#define Z_IS_3600_EQ_3600(...) \, +#define Z_IS_3600U_EQ_3600(...) \, +#define Z_IS_3600_EQ_3600U(...) \, +#define Z_IS_3600U_EQ_3600U(...) \, +#define Z_IS_3601_EQ_3601(...) \, +#define Z_IS_3601U_EQ_3601(...) \, +#define Z_IS_3601_EQ_3601U(...) \, +#define Z_IS_3601U_EQ_3601U(...) \, +#define Z_IS_3602_EQ_3602(...) \, +#define Z_IS_3602U_EQ_3602(...) \, +#define Z_IS_3602_EQ_3602U(...) \, +#define Z_IS_3602U_EQ_3602U(...) \, +#define Z_IS_3603_EQ_3603(...) \, +#define Z_IS_3603U_EQ_3603(...) \, +#define Z_IS_3603_EQ_3603U(...) \, +#define Z_IS_3603U_EQ_3603U(...) \, +#define Z_IS_3604_EQ_3604(...) \, +#define Z_IS_3604U_EQ_3604(...) \, +#define Z_IS_3604_EQ_3604U(...) \, +#define Z_IS_3604U_EQ_3604U(...) \, +#define Z_IS_3605_EQ_3605(...) \, +#define Z_IS_3605U_EQ_3605(...) \, +#define Z_IS_3605_EQ_3605U(...) \, +#define Z_IS_3605U_EQ_3605U(...) \, +#define Z_IS_3606_EQ_3606(...) \, +#define Z_IS_3606U_EQ_3606(...) \, +#define Z_IS_3606_EQ_3606U(...) \, +#define Z_IS_3606U_EQ_3606U(...) \, +#define Z_IS_3607_EQ_3607(...) \, +#define Z_IS_3607U_EQ_3607(...) \, +#define Z_IS_3607_EQ_3607U(...) \, +#define Z_IS_3607U_EQ_3607U(...) \, +#define Z_IS_3608_EQ_3608(...) \, +#define Z_IS_3608U_EQ_3608(...) \, +#define Z_IS_3608_EQ_3608U(...) \, +#define Z_IS_3608U_EQ_3608U(...) \, +#define Z_IS_3609_EQ_3609(...) \, +#define Z_IS_3609U_EQ_3609(...) \, +#define Z_IS_3609_EQ_3609U(...) \, +#define Z_IS_3609U_EQ_3609U(...) \, +#define Z_IS_3610_EQ_3610(...) \, +#define Z_IS_3610U_EQ_3610(...) \, +#define Z_IS_3610_EQ_3610U(...) \, +#define Z_IS_3610U_EQ_3610U(...) \, +#define Z_IS_3611_EQ_3611(...) \, +#define Z_IS_3611U_EQ_3611(...) \, +#define Z_IS_3611_EQ_3611U(...) \, +#define Z_IS_3611U_EQ_3611U(...) \, +#define Z_IS_3612_EQ_3612(...) \, +#define Z_IS_3612U_EQ_3612(...) \, +#define Z_IS_3612_EQ_3612U(...) \, +#define Z_IS_3612U_EQ_3612U(...) \, +#define Z_IS_3613_EQ_3613(...) \, +#define Z_IS_3613U_EQ_3613(...) \, +#define Z_IS_3613_EQ_3613U(...) \, +#define Z_IS_3613U_EQ_3613U(...) \, +#define Z_IS_3614_EQ_3614(...) \, +#define Z_IS_3614U_EQ_3614(...) \, +#define Z_IS_3614_EQ_3614U(...) \, +#define Z_IS_3614U_EQ_3614U(...) \, +#define Z_IS_3615_EQ_3615(...) \, +#define Z_IS_3615U_EQ_3615(...) \, +#define Z_IS_3615_EQ_3615U(...) \, +#define Z_IS_3615U_EQ_3615U(...) \, +#define Z_IS_3616_EQ_3616(...) \, +#define Z_IS_3616U_EQ_3616(...) \, +#define Z_IS_3616_EQ_3616U(...) \, +#define Z_IS_3616U_EQ_3616U(...) \, +#define Z_IS_3617_EQ_3617(...) \, +#define Z_IS_3617U_EQ_3617(...) \, +#define Z_IS_3617_EQ_3617U(...) \, +#define Z_IS_3617U_EQ_3617U(...) \, +#define Z_IS_3618_EQ_3618(...) \, +#define Z_IS_3618U_EQ_3618(...) \, +#define Z_IS_3618_EQ_3618U(...) \, +#define Z_IS_3618U_EQ_3618U(...) \, +#define Z_IS_3619_EQ_3619(...) \, +#define Z_IS_3619U_EQ_3619(...) \, +#define Z_IS_3619_EQ_3619U(...) \, +#define Z_IS_3619U_EQ_3619U(...) \, +#define Z_IS_3620_EQ_3620(...) \, +#define Z_IS_3620U_EQ_3620(...) \, +#define Z_IS_3620_EQ_3620U(...) \, +#define Z_IS_3620U_EQ_3620U(...) \, +#define Z_IS_3621_EQ_3621(...) \, +#define Z_IS_3621U_EQ_3621(...) \, +#define Z_IS_3621_EQ_3621U(...) \, +#define Z_IS_3621U_EQ_3621U(...) \, +#define Z_IS_3622_EQ_3622(...) \, +#define Z_IS_3622U_EQ_3622(...) \, +#define Z_IS_3622_EQ_3622U(...) \, +#define Z_IS_3622U_EQ_3622U(...) \, +#define Z_IS_3623_EQ_3623(...) \, +#define Z_IS_3623U_EQ_3623(...) \, +#define Z_IS_3623_EQ_3623U(...) \, +#define Z_IS_3623U_EQ_3623U(...) \, +#define Z_IS_3624_EQ_3624(...) \, +#define Z_IS_3624U_EQ_3624(...) \, +#define Z_IS_3624_EQ_3624U(...) \, +#define Z_IS_3624U_EQ_3624U(...) \, +#define Z_IS_3625_EQ_3625(...) \, +#define Z_IS_3625U_EQ_3625(...) \, +#define Z_IS_3625_EQ_3625U(...) \, +#define Z_IS_3625U_EQ_3625U(...) \, +#define Z_IS_3626_EQ_3626(...) \, +#define Z_IS_3626U_EQ_3626(...) \, +#define Z_IS_3626_EQ_3626U(...) \, +#define Z_IS_3626U_EQ_3626U(...) \, +#define Z_IS_3627_EQ_3627(...) \, +#define Z_IS_3627U_EQ_3627(...) \, +#define Z_IS_3627_EQ_3627U(...) \, +#define Z_IS_3627U_EQ_3627U(...) \, +#define Z_IS_3628_EQ_3628(...) \, +#define Z_IS_3628U_EQ_3628(...) \, +#define Z_IS_3628_EQ_3628U(...) \, +#define Z_IS_3628U_EQ_3628U(...) \, +#define Z_IS_3629_EQ_3629(...) \, +#define Z_IS_3629U_EQ_3629(...) \, +#define Z_IS_3629_EQ_3629U(...) \, +#define Z_IS_3629U_EQ_3629U(...) \, +#define Z_IS_3630_EQ_3630(...) \, +#define Z_IS_3630U_EQ_3630(...) \, +#define Z_IS_3630_EQ_3630U(...) \, +#define Z_IS_3630U_EQ_3630U(...) \, +#define Z_IS_3631_EQ_3631(...) \, +#define Z_IS_3631U_EQ_3631(...) \, +#define Z_IS_3631_EQ_3631U(...) \, +#define Z_IS_3631U_EQ_3631U(...) \, +#define Z_IS_3632_EQ_3632(...) \, +#define Z_IS_3632U_EQ_3632(...) \, +#define Z_IS_3632_EQ_3632U(...) \, +#define Z_IS_3632U_EQ_3632U(...) \, +#define Z_IS_3633_EQ_3633(...) \, +#define Z_IS_3633U_EQ_3633(...) \, +#define Z_IS_3633_EQ_3633U(...) \, +#define Z_IS_3633U_EQ_3633U(...) \, +#define Z_IS_3634_EQ_3634(...) \, +#define Z_IS_3634U_EQ_3634(...) \, +#define Z_IS_3634_EQ_3634U(...) \, +#define Z_IS_3634U_EQ_3634U(...) \, +#define Z_IS_3635_EQ_3635(...) \, +#define Z_IS_3635U_EQ_3635(...) \, +#define Z_IS_3635_EQ_3635U(...) \, +#define Z_IS_3635U_EQ_3635U(...) \, +#define Z_IS_3636_EQ_3636(...) \, +#define Z_IS_3636U_EQ_3636(...) \, +#define Z_IS_3636_EQ_3636U(...) \, +#define Z_IS_3636U_EQ_3636U(...) \, +#define Z_IS_3637_EQ_3637(...) \, +#define Z_IS_3637U_EQ_3637(...) \, +#define Z_IS_3637_EQ_3637U(...) \, +#define Z_IS_3637U_EQ_3637U(...) \, +#define Z_IS_3638_EQ_3638(...) \, +#define Z_IS_3638U_EQ_3638(...) \, +#define Z_IS_3638_EQ_3638U(...) \, +#define Z_IS_3638U_EQ_3638U(...) \, +#define Z_IS_3639_EQ_3639(...) \, +#define Z_IS_3639U_EQ_3639(...) \, +#define Z_IS_3639_EQ_3639U(...) \, +#define Z_IS_3639U_EQ_3639U(...) \, +#define Z_IS_3640_EQ_3640(...) \, +#define Z_IS_3640U_EQ_3640(...) \, +#define Z_IS_3640_EQ_3640U(...) \, +#define Z_IS_3640U_EQ_3640U(...) \, +#define Z_IS_3641_EQ_3641(...) \, +#define Z_IS_3641U_EQ_3641(...) \, +#define Z_IS_3641_EQ_3641U(...) \, +#define Z_IS_3641U_EQ_3641U(...) \, +#define Z_IS_3642_EQ_3642(...) \, +#define Z_IS_3642U_EQ_3642(...) \, +#define Z_IS_3642_EQ_3642U(...) \, +#define Z_IS_3642U_EQ_3642U(...) \, +#define Z_IS_3643_EQ_3643(...) \, +#define Z_IS_3643U_EQ_3643(...) \, +#define Z_IS_3643_EQ_3643U(...) \, +#define Z_IS_3643U_EQ_3643U(...) \, +#define Z_IS_3644_EQ_3644(...) \, +#define Z_IS_3644U_EQ_3644(...) \, +#define Z_IS_3644_EQ_3644U(...) \, +#define Z_IS_3644U_EQ_3644U(...) \, +#define Z_IS_3645_EQ_3645(...) \, +#define Z_IS_3645U_EQ_3645(...) \, +#define Z_IS_3645_EQ_3645U(...) \, +#define Z_IS_3645U_EQ_3645U(...) \, +#define Z_IS_3646_EQ_3646(...) \, +#define Z_IS_3646U_EQ_3646(...) \, +#define Z_IS_3646_EQ_3646U(...) \, +#define Z_IS_3646U_EQ_3646U(...) \, +#define Z_IS_3647_EQ_3647(...) \, +#define Z_IS_3647U_EQ_3647(...) \, +#define Z_IS_3647_EQ_3647U(...) \, +#define Z_IS_3647U_EQ_3647U(...) \, +#define Z_IS_3648_EQ_3648(...) \, +#define Z_IS_3648U_EQ_3648(...) \, +#define Z_IS_3648_EQ_3648U(...) \, +#define Z_IS_3648U_EQ_3648U(...) \, +#define Z_IS_3649_EQ_3649(...) \, +#define Z_IS_3649U_EQ_3649(...) \, +#define Z_IS_3649_EQ_3649U(...) \, +#define Z_IS_3649U_EQ_3649U(...) \, +#define Z_IS_3650_EQ_3650(...) \, +#define Z_IS_3650U_EQ_3650(...) \, +#define Z_IS_3650_EQ_3650U(...) \, +#define Z_IS_3650U_EQ_3650U(...) \, +#define Z_IS_3651_EQ_3651(...) \, +#define Z_IS_3651U_EQ_3651(...) \, +#define Z_IS_3651_EQ_3651U(...) \, +#define Z_IS_3651U_EQ_3651U(...) \, +#define Z_IS_3652_EQ_3652(...) \, +#define Z_IS_3652U_EQ_3652(...) \, +#define Z_IS_3652_EQ_3652U(...) \, +#define Z_IS_3652U_EQ_3652U(...) \, +#define Z_IS_3653_EQ_3653(...) \, +#define Z_IS_3653U_EQ_3653(...) \, +#define Z_IS_3653_EQ_3653U(...) \, +#define Z_IS_3653U_EQ_3653U(...) \, +#define Z_IS_3654_EQ_3654(...) \, +#define Z_IS_3654U_EQ_3654(...) \, +#define Z_IS_3654_EQ_3654U(...) \, +#define Z_IS_3654U_EQ_3654U(...) \, +#define Z_IS_3655_EQ_3655(...) \, +#define Z_IS_3655U_EQ_3655(...) \, +#define Z_IS_3655_EQ_3655U(...) \, +#define Z_IS_3655U_EQ_3655U(...) \, +#define Z_IS_3656_EQ_3656(...) \, +#define Z_IS_3656U_EQ_3656(...) \, +#define Z_IS_3656_EQ_3656U(...) \, +#define Z_IS_3656U_EQ_3656U(...) \, +#define Z_IS_3657_EQ_3657(...) \, +#define Z_IS_3657U_EQ_3657(...) \, +#define Z_IS_3657_EQ_3657U(...) \, +#define Z_IS_3657U_EQ_3657U(...) \, +#define Z_IS_3658_EQ_3658(...) \, +#define Z_IS_3658U_EQ_3658(...) \, +#define Z_IS_3658_EQ_3658U(...) \, +#define Z_IS_3658U_EQ_3658U(...) \, +#define Z_IS_3659_EQ_3659(...) \, +#define Z_IS_3659U_EQ_3659(...) \, +#define Z_IS_3659_EQ_3659U(...) \, +#define Z_IS_3659U_EQ_3659U(...) \, +#define Z_IS_3660_EQ_3660(...) \, +#define Z_IS_3660U_EQ_3660(...) \, +#define Z_IS_3660_EQ_3660U(...) \, +#define Z_IS_3660U_EQ_3660U(...) \, +#define Z_IS_3661_EQ_3661(...) \, +#define Z_IS_3661U_EQ_3661(...) \, +#define Z_IS_3661_EQ_3661U(...) \, +#define Z_IS_3661U_EQ_3661U(...) \, +#define Z_IS_3662_EQ_3662(...) \, +#define Z_IS_3662U_EQ_3662(...) \, +#define Z_IS_3662_EQ_3662U(...) \, +#define Z_IS_3662U_EQ_3662U(...) \, +#define Z_IS_3663_EQ_3663(...) \, +#define Z_IS_3663U_EQ_3663(...) \, +#define Z_IS_3663_EQ_3663U(...) \, +#define Z_IS_3663U_EQ_3663U(...) \, +#define Z_IS_3664_EQ_3664(...) \, +#define Z_IS_3664U_EQ_3664(...) \, +#define Z_IS_3664_EQ_3664U(...) \, +#define Z_IS_3664U_EQ_3664U(...) \, +#define Z_IS_3665_EQ_3665(...) \, +#define Z_IS_3665U_EQ_3665(...) \, +#define Z_IS_3665_EQ_3665U(...) \, +#define Z_IS_3665U_EQ_3665U(...) \, +#define Z_IS_3666_EQ_3666(...) \, +#define Z_IS_3666U_EQ_3666(...) \, +#define Z_IS_3666_EQ_3666U(...) \, +#define Z_IS_3666U_EQ_3666U(...) \, +#define Z_IS_3667_EQ_3667(...) \, +#define Z_IS_3667U_EQ_3667(...) \, +#define Z_IS_3667_EQ_3667U(...) \, +#define Z_IS_3667U_EQ_3667U(...) \, +#define Z_IS_3668_EQ_3668(...) \, +#define Z_IS_3668U_EQ_3668(...) \, +#define Z_IS_3668_EQ_3668U(...) \, +#define Z_IS_3668U_EQ_3668U(...) \, +#define Z_IS_3669_EQ_3669(...) \, +#define Z_IS_3669U_EQ_3669(...) \, +#define Z_IS_3669_EQ_3669U(...) \, +#define Z_IS_3669U_EQ_3669U(...) \, +#define Z_IS_3670_EQ_3670(...) \, +#define Z_IS_3670U_EQ_3670(...) \, +#define Z_IS_3670_EQ_3670U(...) \, +#define Z_IS_3670U_EQ_3670U(...) \, +#define Z_IS_3671_EQ_3671(...) \, +#define Z_IS_3671U_EQ_3671(...) \, +#define Z_IS_3671_EQ_3671U(...) \, +#define Z_IS_3671U_EQ_3671U(...) \, +#define Z_IS_3672_EQ_3672(...) \, +#define Z_IS_3672U_EQ_3672(...) \, +#define Z_IS_3672_EQ_3672U(...) \, +#define Z_IS_3672U_EQ_3672U(...) \, +#define Z_IS_3673_EQ_3673(...) \, +#define Z_IS_3673U_EQ_3673(...) \, +#define Z_IS_3673_EQ_3673U(...) \, +#define Z_IS_3673U_EQ_3673U(...) \, +#define Z_IS_3674_EQ_3674(...) \, +#define Z_IS_3674U_EQ_3674(...) \, +#define Z_IS_3674_EQ_3674U(...) \, +#define Z_IS_3674U_EQ_3674U(...) \, +#define Z_IS_3675_EQ_3675(...) \, +#define Z_IS_3675U_EQ_3675(...) \, +#define Z_IS_3675_EQ_3675U(...) \, +#define Z_IS_3675U_EQ_3675U(...) \, +#define Z_IS_3676_EQ_3676(...) \, +#define Z_IS_3676U_EQ_3676(...) \, +#define Z_IS_3676_EQ_3676U(...) \, +#define Z_IS_3676U_EQ_3676U(...) \, +#define Z_IS_3677_EQ_3677(...) \, +#define Z_IS_3677U_EQ_3677(...) \, +#define Z_IS_3677_EQ_3677U(...) \, +#define Z_IS_3677U_EQ_3677U(...) \, +#define Z_IS_3678_EQ_3678(...) \, +#define Z_IS_3678U_EQ_3678(...) \, +#define Z_IS_3678_EQ_3678U(...) \, +#define Z_IS_3678U_EQ_3678U(...) \, +#define Z_IS_3679_EQ_3679(...) \, +#define Z_IS_3679U_EQ_3679(...) \, +#define Z_IS_3679_EQ_3679U(...) \, +#define Z_IS_3679U_EQ_3679U(...) \, +#define Z_IS_3680_EQ_3680(...) \, +#define Z_IS_3680U_EQ_3680(...) \, +#define Z_IS_3680_EQ_3680U(...) \, +#define Z_IS_3680U_EQ_3680U(...) \, +#define Z_IS_3681_EQ_3681(...) \, +#define Z_IS_3681U_EQ_3681(...) \, +#define Z_IS_3681_EQ_3681U(...) \, +#define Z_IS_3681U_EQ_3681U(...) \, +#define Z_IS_3682_EQ_3682(...) \, +#define Z_IS_3682U_EQ_3682(...) \, +#define Z_IS_3682_EQ_3682U(...) \, +#define Z_IS_3682U_EQ_3682U(...) \, +#define Z_IS_3683_EQ_3683(...) \, +#define Z_IS_3683U_EQ_3683(...) \, +#define Z_IS_3683_EQ_3683U(...) \, +#define Z_IS_3683U_EQ_3683U(...) \, +#define Z_IS_3684_EQ_3684(...) \, +#define Z_IS_3684U_EQ_3684(...) \, +#define Z_IS_3684_EQ_3684U(...) \, +#define Z_IS_3684U_EQ_3684U(...) \, +#define Z_IS_3685_EQ_3685(...) \, +#define Z_IS_3685U_EQ_3685(...) \, +#define Z_IS_3685_EQ_3685U(...) \, +#define Z_IS_3685U_EQ_3685U(...) \, +#define Z_IS_3686_EQ_3686(...) \, +#define Z_IS_3686U_EQ_3686(...) \, +#define Z_IS_3686_EQ_3686U(...) \, +#define Z_IS_3686U_EQ_3686U(...) \, +#define Z_IS_3687_EQ_3687(...) \, +#define Z_IS_3687U_EQ_3687(...) \, +#define Z_IS_3687_EQ_3687U(...) \, +#define Z_IS_3687U_EQ_3687U(...) \, +#define Z_IS_3688_EQ_3688(...) \, +#define Z_IS_3688U_EQ_3688(...) \, +#define Z_IS_3688_EQ_3688U(...) \, +#define Z_IS_3688U_EQ_3688U(...) \, +#define Z_IS_3689_EQ_3689(...) \, +#define Z_IS_3689U_EQ_3689(...) \, +#define Z_IS_3689_EQ_3689U(...) \, +#define Z_IS_3689U_EQ_3689U(...) \, +#define Z_IS_3690_EQ_3690(...) \, +#define Z_IS_3690U_EQ_3690(...) \, +#define Z_IS_3690_EQ_3690U(...) \, +#define Z_IS_3690U_EQ_3690U(...) \, +#define Z_IS_3691_EQ_3691(...) \, +#define Z_IS_3691U_EQ_3691(...) \, +#define Z_IS_3691_EQ_3691U(...) \, +#define Z_IS_3691U_EQ_3691U(...) \, +#define Z_IS_3692_EQ_3692(...) \, +#define Z_IS_3692U_EQ_3692(...) \, +#define Z_IS_3692_EQ_3692U(...) \, +#define Z_IS_3692U_EQ_3692U(...) \, +#define Z_IS_3693_EQ_3693(...) \, +#define Z_IS_3693U_EQ_3693(...) \, +#define Z_IS_3693_EQ_3693U(...) \, +#define Z_IS_3693U_EQ_3693U(...) \, +#define Z_IS_3694_EQ_3694(...) \, +#define Z_IS_3694U_EQ_3694(...) \, +#define Z_IS_3694_EQ_3694U(...) \, +#define Z_IS_3694U_EQ_3694U(...) \, +#define Z_IS_3695_EQ_3695(...) \, +#define Z_IS_3695U_EQ_3695(...) \, +#define Z_IS_3695_EQ_3695U(...) \, +#define Z_IS_3695U_EQ_3695U(...) \, +#define Z_IS_3696_EQ_3696(...) \, +#define Z_IS_3696U_EQ_3696(...) \, +#define Z_IS_3696_EQ_3696U(...) \, +#define Z_IS_3696U_EQ_3696U(...) \, +#define Z_IS_3697_EQ_3697(...) \, +#define Z_IS_3697U_EQ_3697(...) \, +#define Z_IS_3697_EQ_3697U(...) \, +#define Z_IS_3697U_EQ_3697U(...) \, +#define Z_IS_3698_EQ_3698(...) \, +#define Z_IS_3698U_EQ_3698(...) \, +#define Z_IS_3698_EQ_3698U(...) \, +#define Z_IS_3698U_EQ_3698U(...) \, +#define Z_IS_3699_EQ_3699(...) \, +#define Z_IS_3699U_EQ_3699(...) \, +#define Z_IS_3699_EQ_3699U(...) \, +#define Z_IS_3699U_EQ_3699U(...) \, +#define Z_IS_3700_EQ_3700(...) \, +#define Z_IS_3700U_EQ_3700(...) \, +#define Z_IS_3700_EQ_3700U(...) \, +#define Z_IS_3700U_EQ_3700U(...) \, +#define Z_IS_3701_EQ_3701(...) \, +#define Z_IS_3701U_EQ_3701(...) \, +#define Z_IS_3701_EQ_3701U(...) \, +#define Z_IS_3701U_EQ_3701U(...) \, +#define Z_IS_3702_EQ_3702(...) \, +#define Z_IS_3702U_EQ_3702(...) \, +#define Z_IS_3702_EQ_3702U(...) \, +#define Z_IS_3702U_EQ_3702U(...) \, +#define Z_IS_3703_EQ_3703(...) \, +#define Z_IS_3703U_EQ_3703(...) \, +#define Z_IS_3703_EQ_3703U(...) \, +#define Z_IS_3703U_EQ_3703U(...) \, +#define Z_IS_3704_EQ_3704(...) \, +#define Z_IS_3704U_EQ_3704(...) \, +#define Z_IS_3704_EQ_3704U(...) \, +#define Z_IS_3704U_EQ_3704U(...) \, +#define Z_IS_3705_EQ_3705(...) \, +#define Z_IS_3705U_EQ_3705(...) \, +#define Z_IS_3705_EQ_3705U(...) \, +#define Z_IS_3705U_EQ_3705U(...) \, +#define Z_IS_3706_EQ_3706(...) \, +#define Z_IS_3706U_EQ_3706(...) \, +#define Z_IS_3706_EQ_3706U(...) \, +#define Z_IS_3706U_EQ_3706U(...) \, +#define Z_IS_3707_EQ_3707(...) \, +#define Z_IS_3707U_EQ_3707(...) \, +#define Z_IS_3707_EQ_3707U(...) \, +#define Z_IS_3707U_EQ_3707U(...) \, +#define Z_IS_3708_EQ_3708(...) \, +#define Z_IS_3708U_EQ_3708(...) \, +#define Z_IS_3708_EQ_3708U(...) \, +#define Z_IS_3708U_EQ_3708U(...) \, +#define Z_IS_3709_EQ_3709(...) \, +#define Z_IS_3709U_EQ_3709(...) \, +#define Z_IS_3709_EQ_3709U(...) \, +#define Z_IS_3709U_EQ_3709U(...) \, +#define Z_IS_3710_EQ_3710(...) \, +#define Z_IS_3710U_EQ_3710(...) \, +#define Z_IS_3710_EQ_3710U(...) \, +#define Z_IS_3710U_EQ_3710U(...) \, +#define Z_IS_3711_EQ_3711(...) \, +#define Z_IS_3711U_EQ_3711(...) \, +#define Z_IS_3711_EQ_3711U(...) \, +#define Z_IS_3711U_EQ_3711U(...) \, +#define Z_IS_3712_EQ_3712(...) \, +#define Z_IS_3712U_EQ_3712(...) \, +#define Z_IS_3712_EQ_3712U(...) \, +#define Z_IS_3712U_EQ_3712U(...) \, +#define Z_IS_3713_EQ_3713(...) \, +#define Z_IS_3713U_EQ_3713(...) \, +#define Z_IS_3713_EQ_3713U(...) \, +#define Z_IS_3713U_EQ_3713U(...) \, +#define Z_IS_3714_EQ_3714(...) \, +#define Z_IS_3714U_EQ_3714(...) \, +#define Z_IS_3714_EQ_3714U(...) \, +#define Z_IS_3714U_EQ_3714U(...) \, +#define Z_IS_3715_EQ_3715(...) \, +#define Z_IS_3715U_EQ_3715(...) \, +#define Z_IS_3715_EQ_3715U(...) \, +#define Z_IS_3715U_EQ_3715U(...) \, +#define Z_IS_3716_EQ_3716(...) \, +#define Z_IS_3716U_EQ_3716(...) \, +#define Z_IS_3716_EQ_3716U(...) \, +#define Z_IS_3716U_EQ_3716U(...) \, +#define Z_IS_3717_EQ_3717(...) \, +#define Z_IS_3717U_EQ_3717(...) \, +#define Z_IS_3717_EQ_3717U(...) \, +#define Z_IS_3717U_EQ_3717U(...) \, +#define Z_IS_3718_EQ_3718(...) \, +#define Z_IS_3718U_EQ_3718(...) \, +#define Z_IS_3718_EQ_3718U(...) \, +#define Z_IS_3718U_EQ_3718U(...) \, +#define Z_IS_3719_EQ_3719(...) \, +#define Z_IS_3719U_EQ_3719(...) \, +#define Z_IS_3719_EQ_3719U(...) \, +#define Z_IS_3719U_EQ_3719U(...) \, +#define Z_IS_3720_EQ_3720(...) \, +#define Z_IS_3720U_EQ_3720(...) \, +#define Z_IS_3720_EQ_3720U(...) \, +#define Z_IS_3720U_EQ_3720U(...) \, +#define Z_IS_3721_EQ_3721(...) \, +#define Z_IS_3721U_EQ_3721(...) \, +#define Z_IS_3721_EQ_3721U(...) \, +#define Z_IS_3721U_EQ_3721U(...) \, +#define Z_IS_3722_EQ_3722(...) \, +#define Z_IS_3722U_EQ_3722(...) \, +#define Z_IS_3722_EQ_3722U(...) \, +#define Z_IS_3722U_EQ_3722U(...) \, +#define Z_IS_3723_EQ_3723(...) \, +#define Z_IS_3723U_EQ_3723(...) \, +#define Z_IS_3723_EQ_3723U(...) \, +#define Z_IS_3723U_EQ_3723U(...) \, +#define Z_IS_3724_EQ_3724(...) \, +#define Z_IS_3724U_EQ_3724(...) \, +#define Z_IS_3724_EQ_3724U(...) \, +#define Z_IS_3724U_EQ_3724U(...) \, +#define Z_IS_3725_EQ_3725(...) \, +#define Z_IS_3725U_EQ_3725(...) \, +#define Z_IS_3725_EQ_3725U(...) \, +#define Z_IS_3725U_EQ_3725U(...) \, +#define Z_IS_3726_EQ_3726(...) \, +#define Z_IS_3726U_EQ_3726(...) \, +#define Z_IS_3726_EQ_3726U(...) \, +#define Z_IS_3726U_EQ_3726U(...) \, +#define Z_IS_3727_EQ_3727(...) \, +#define Z_IS_3727U_EQ_3727(...) \, +#define Z_IS_3727_EQ_3727U(...) \, +#define Z_IS_3727U_EQ_3727U(...) \, +#define Z_IS_3728_EQ_3728(...) \, +#define Z_IS_3728U_EQ_3728(...) \, +#define Z_IS_3728_EQ_3728U(...) \, +#define Z_IS_3728U_EQ_3728U(...) \, +#define Z_IS_3729_EQ_3729(...) \, +#define Z_IS_3729U_EQ_3729(...) \, +#define Z_IS_3729_EQ_3729U(...) \, +#define Z_IS_3729U_EQ_3729U(...) \, +#define Z_IS_3730_EQ_3730(...) \, +#define Z_IS_3730U_EQ_3730(...) \, +#define Z_IS_3730_EQ_3730U(...) \, +#define Z_IS_3730U_EQ_3730U(...) \, +#define Z_IS_3731_EQ_3731(...) \, +#define Z_IS_3731U_EQ_3731(...) \, +#define Z_IS_3731_EQ_3731U(...) \, +#define Z_IS_3731U_EQ_3731U(...) \, +#define Z_IS_3732_EQ_3732(...) \, +#define Z_IS_3732U_EQ_3732(...) \, +#define Z_IS_3732_EQ_3732U(...) \, +#define Z_IS_3732U_EQ_3732U(...) \, +#define Z_IS_3733_EQ_3733(...) \, +#define Z_IS_3733U_EQ_3733(...) \, +#define Z_IS_3733_EQ_3733U(...) \, +#define Z_IS_3733U_EQ_3733U(...) \, +#define Z_IS_3734_EQ_3734(...) \, +#define Z_IS_3734U_EQ_3734(...) \, +#define Z_IS_3734_EQ_3734U(...) \, +#define Z_IS_3734U_EQ_3734U(...) \, +#define Z_IS_3735_EQ_3735(...) \, +#define Z_IS_3735U_EQ_3735(...) \, +#define Z_IS_3735_EQ_3735U(...) \, +#define Z_IS_3735U_EQ_3735U(...) \, +#define Z_IS_3736_EQ_3736(...) \, +#define Z_IS_3736U_EQ_3736(...) \, +#define Z_IS_3736_EQ_3736U(...) \, +#define Z_IS_3736U_EQ_3736U(...) \, +#define Z_IS_3737_EQ_3737(...) \, +#define Z_IS_3737U_EQ_3737(...) \, +#define Z_IS_3737_EQ_3737U(...) \, +#define Z_IS_3737U_EQ_3737U(...) \, +#define Z_IS_3738_EQ_3738(...) \, +#define Z_IS_3738U_EQ_3738(...) \, +#define Z_IS_3738_EQ_3738U(...) \, +#define Z_IS_3738U_EQ_3738U(...) \, +#define Z_IS_3739_EQ_3739(...) \, +#define Z_IS_3739U_EQ_3739(...) \, +#define Z_IS_3739_EQ_3739U(...) \, +#define Z_IS_3739U_EQ_3739U(...) \, +#define Z_IS_3740_EQ_3740(...) \, +#define Z_IS_3740U_EQ_3740(...) \, +#define Z_IS_3740_EQ_3740U(...) \, +#define Z_IS_3740U_EQ_3740U(...) \, +#define Z_IS_3741_EQ_3741(...) \, +#define Z_IS_3741U_EQ_3741(...) \, +#define Z_IS_3741_EQ_3741U(...) \, +#define Z_IS_3741U_EQ_3741U(...) \, +#define Z_IS_3742_EQ_3742(...) \, +#define Z_IS_3742U_EQ_3742(...) \, +#define Z_IS_3742_EQ_3742U(...) \, +#define Z_IS_3742U_EQ_3742U(...) \, +#define Z_IS_3743_EQ_3743(...) \, +#define Z_IS_3743U_EQ_3743(...) \, +#define Z_IS_3743_EQ_3743U(...) \, +#define Z_IS_3743U_EQ_3743U(...) \, +#define Z_IS_3744_EQ_3744(...) \, +#define Z_IS_3744U_EQ_3744(...) \, +#define Z_IS_3744_EQ_3744U(...) \, +#define Z_IS_3744U_EQ_3744U(...) \, +#define Z_IS_3745_EQ_3745(...) \, +#define Z_IS_3745U_EQ_3745(...) \, +#define Z_IS_3745_EQ_3745U(...) \, +#define Z_IS_3745U_EQ_3745U(...) \, +#define Z_IS_3746_EQ_3746(...) \, +#define Z_IS_3746U_EQ_3746(...) \, +#define Z_IS_3746_EQ_3746U(...) \, +#define Z_IS_3746U_EQ_3746U(...) \, +#define Z_IS_3747_EQ_3747(...) \, +#define Z_IS_3747U_EQ_3747(...) \, +#define Z_IS_3747_EQ_3747U(...) \, +#define Z_IS_3747U_EQ_3747U(...) \, +#define Z_IS_3748_EQ_3748(...) \, +#define Z_IS_3748U_EQ_3748(...) \, +#define Z_IS_3748_EQ_3748U(...) \, +#define Z_IS_3748U_EQ_3748U(...) \, +#define Z_IS_3749_EQ_3749(...) \, +#define Z_IS_3749U_EQ_3749(...) \, +#define Z_IS_3749_EQ_3749U(...) \, +#define Z_IS_3749U_EQ_3749U(...) \, +#define Z_IS_3750_EQ_3750(...) \, +#define Z_IS_3750U_EQ_3750(...) \, +#define Z_IS_3750_EQ_3750U(...) \, +#define Z_IS_3750U_EQ_3750U(...) \, +#define Z_IS_3751_EQ_3751(...) \, +#define Z_IS_3751U_EQ_3751(...) \, +#define Z_IS_3751_EQ_3751U(...) \, +#define Z_IS_3751U_EQ_3751U(...) \, +#define Z_IS_3752_EQ_3752(...) \, +#define Z_IS_3752U_EQ_3752(...) \, +#define Z_IS_3752_EQ_3752U(...) \, +#define Z_IS_3752U_EQ_3752U(...) \, +#define Z_IS_3753_EQ_3753(...) \, +#define Z_IS_3753U_EQ_3753(...) \, +#define Z_IS_3753_EQ_3753U(...) \, +#define Z_IS_3753U_EQ_3753U(...) \, +#define Z_IS_3754_EQ_3754(...) \, +#define Z_IS_3754U_EQ_3754(...) \, +#define Z_IS_3754_EQ_3754U(...) \, +#define Z_IS_3754U_EQ_3754U(...) \, +#define Z_IS_3755_EQ_3755(...) \, +#define Z_IS_3755U_EQ_3755(...) \, +#define Z_IS_3755_EQ_3755U(...) \, +#define Z_IS_3755U_EQ_3755U(...) \, +#define Z_IS_3756_EQ_3756(...) \, +#define Z_IS_3756U_EQ_3756(...) \, +#define Z_IS_3756_EQ_3756U(...) \, +#define Z_IS_3756U_EQ_3756U(...) \, +#define Z_IS_3757_EQ_3757(...) \, +#define Z_IS_3757U_EQ_3757(...) \, +#define Z_IS_3757_EQ_3757U(...) \, +#define Z_IS_3757U_EQ_3757U(...) \, +#define Z_IS_3758_EQ_3758(...) \, +#define Z_IS_3758U_EQ_3758(...) \, +#define Z_IS_3758_EQ_3758U(...) \, +#define Z_IS_3758U_EQ_3758U(...) \, +#define Z_IS_3759_EQ_3759(...) \, +#define Z_IS_3759U_EQ_3759(...) \, +#define Z_IS_3759_EQ_3759U(...) \, +#define Z_IS_3759U_EQ_3759U(...) \, +#define Z_IS_3760_EQ_3760(...) \, +#define Z_IS_3760U_EQ_3760(...) \, +#define Z_IS_3760_EQ_3760U(...) \, +#define Z_IS_3760U_EQ_3760U(...) \, +#define Z_IS_3761_EQ_3761(...) \, +#define Z_IS_3761U_EQ_3761(...) \, +#define Z_IS_3761_EQ_3761U(...) \, +#define Z_IS_3761U_EQ_3761U(...) \, +#define Z_IS_3762_EQ_3762(...) \, +#define Z_IS_3762U_EQ_3762(...) \, +#define Z_IS_3762_EQ_3762U(...) \, +#define Z_IS_3762U_EQ_3762U(...) \, +#define Z_IS_3763_EQ_3763(...) \, +#define Z_IS_3763U_EQ_3763(...) \, +#define Z_IS_3763_EQ_3763U(...) \, +#define Z_IS_3763U_EQ_3763U(...) \, +#define Z_IS_3764_EQ_3764(...) \, +#define Z_IS_3764U_EQ_3764(...) \, +#define Z_IS_3764_EQ_3764U(...) \, +#define Z_IS_3764U_EQ_3764U(...) \, +#define Z_IS_3765_EQ_3765(...) \, +#define Z_IS_3765U_EQ_3765(...) \, +#define Z_IS_3765_EQ_3765U(...) \, +#define Z_IS_3765U_EQ_3765U(...) \, +#define Z_IS_3766_EQ_3766(...) \, +#define Z_IS_3766U_EQ_3766(...) \, +#define Z_IS_3766_EQ_3766U(...) \, +#define Z_IS_3766U_EQ_3766U(...) \, +#define Z_IS_3767_EQ_3767(...) \, +#define Z_IS_3767U_EQ_3767(...) \, +#define Z_IS_3767_EQ_3767U(...) \, +#define Z_IS_3767U_EQ_3767U(...) \, +#define Z_IS_3768_EQ_3768(...) \, +#define Z_IS_3768U_EQ_3768(...) \, +#define Z_IS_3768_EQ_3768U(...) \, +#define Z_IS_3768U_EQ_3768U(...) \, +#define Z_IS_3769_EQ_3769(...) \, +#define Z_IS_3769U_EQ_3769(...) \, +#define Z_IS_3769_EQ_3769U(...) \, +#define Z_IS_3769U_EQ_3769U(...) \, +#define Z_IS_3770_EQ_3770(...) \, +#define Z_IS_3770U_EQ_3770(...) \, +#define Z_IS_3770_EQ_3770U(...) \, +#define Z_IS_3770U_EQ_3770U(...) \, +#define Z_IS_3771_EQ_3771(...) \, +#define Z_IS_3771U_EQ_3771(...) \, +#define Z_IS_3771_EQ_3771U(...) \, +#define Z_IS_3771U_EQ_3771U(...) \, +#define Z_IS_3772_EQ_3772(...) \, +#define Z_IS_3772U_EQ_3772(...) \, +#define Z_IS_3772_EQ_3772U(...) \, +#define Z_IS_3772U_EQ_3772U(...) \, +#define Z_IS_3773_EQ_3773(...) \, +#define Z_IS_3773U_EQ_3773(...) \, +#define Z_IS_3773_EQ_3773U(...) \, +#define Z_IS_3773U_EQ_3773U(...) \, +#define Z_IS_3774_EQ_3774(...) \, +#define Z_IS_3774U_EQ_3774(...) \, +#define Z_IS_3774_EQ_3774U(...) \, +#define Z_IS_3774U_EQ_3774U(...) \, +#define Z_IS_3775_EQ_3775(...) \, +#define Z_IS_3775U_EQ_3775(...) \, +#define Z_IS_3775_EQ_3775U(...) \, +#define Z_IS_3775U_EQ_3775U(...) \, +#define Z_IS_3776_EQ_3776(...) \, +#define Z_IS_3776U_EQ_3776(...) \, +#define Z_IS_3776_EQ_3776U(...) \, +#define Z_IS_3776U_EQ_3776U(...) \, +#define Z_IS_3777_EQ_3777(...) \, +#define Z_IS_3777U_EQ_3777(...) \, +#define Z_IS_3777_EQ_3777U(...) \, +#define Z_IS_3777U_EQ_3777U(...) \, +#define Z_IS_3778_EQ_3778(...) \, +#define Z_IS_3778U_EQ_3778(...) \, +#define Z_IS_3778_EQ_3778U(...) \, +#define Z_IS_3778U_EQ_3778U(...) \, +#define Z_IS_3779_EQ_3779(...) \, +#define Z_IS_3779U_EQ_3779(...) \, +#define Z_IS_3779_EQ_3779U(...) \, +#define Z_IS_3779U_EQ_3779U(...) \, +#define Z_IS_3780_EQ_3780(...) \, +#define Z_IS_3780U_EQ_3780(...) \, +#define Z_IS_3780_EQ_3780U(...) \, +#define Z_IS_3780U_EQ_3780U(...) \, +#define Z_IS_3781_EQ_3781(...) \, +#define Z_IS_3781U_EQ_3781(...) \, +#define Z_IS_3781_EQ_3781U(...) \, +#define Z_IS_3781U_EQ_3781U(...) \, +#define Z_IS_3782_EQ_3782(...) \, +#define Z_IS_3782U_EQ_3782(...) \, +#define Z_IS_3782_EQ_3782U(...) \, +#define Z_IS_3782U_EQ_3782U(...) \, +#define Z_IS_3783_EQ_3783(...) \, +#define Z_IS_3783U_EQ_3783(...) \, +#define Z_IS_3783_EQ_3783U(...) \, +#define Z_IS_3783U_EQ_3783U(...) \, +#define Z_IS_3784_EQ_3784(...) \, +#define Z_IS_3784U_EQ_3784(...) \, +#define Z_IS_3784_EQ_3784U(...) \, +#define Z_IS_3784U_EQ_3784U(...) \, +#define Z_IS_3785_EQ_3785(...) \, +#define Z_IS_3785U_EQ_3785(...) \, +#define Z_IS_3785_EQ_3785U(...) \, +#define Z_IS_3785U_EQ_3785U(...) \, +#define Z_IS_3786_EQ_3786(...) \, +#define Z_IS_3786U_EQ_3786(...) \, +#define Z_IS_3786_EQ_3786U(...) \, +#define Z_IS_3786U_EQ_3786U(...) \, +#define Z_IS_3787_EQ_3787(...) \, +#define Z_IS_3787U_EQ_3787(...) \, +#define Z_IS_3787_EQ_3787U(...) \, +#define Z_IS_3787U_EQ_3787U(...) \, +#define Z_IS_3788_EQ_3788(...) \, +#define Z_IS_3788U_EQ_3788(...) \, +#define Z_IS_3788_EQ_3788U(...) \, +#define Z_IS_3788U_EQ_3788U(...) \, +#define Z_IS_3789_EQ_3789(...) \, +#define Z_IS_3789U_EQ_3789(...) \, +#define Z_IS_3789_EQ_3789U(...) \, +#define Z_IS_3789U_EQ_3789U(...) \, +#define Z_IS_3790_EQ_3790(...) \, +#define Z_IS_3790U_EQ_3790(...) \, +#define Z_IS_3790_EQ_3790U(...) \, +#define Z_IS_3790U_EQ_3790U(...) \, +#define Z_IS_3791_EQ_3791(...) \, +#define Z_IS_3791U_EQ_3791(...) \, +#define Z_IS_3791_EQ_3791U(...) \, +#define Z_IS_3791U_EQ_3791U(...) \, +#define Z_IS_3792_EQ_3792(...) \, +#define Z_IS_3792U_EQ_3792(...) \, +#define Z_IS_3792_EQ_3792U(...) \, +#define Z_IS_3792U_EQ_3792U(...) \, +#define Z_IS_3793_EQ_3793(...) \, +#define Z_IS_3793U_EQ_3793(...) \, +#define Z_IS_3793_EQ_3793U(...) \, +#define Z_IS_3793U_EQ_3793U(...) \, +#define Z_IS_3794_EQ_3794(...) \, +#define Z_IS_3794U_EQ_3794(...) \, +#define Z_IS_3794_EQ_3794U(...) \, +#define Z_IS_3794U_EQ_3794U(...) \, +#define Z_IS_3795_EQ_3795(...) \, +#define Z_IS_3795U_EQ_3795(...) \, +#define Z_IS_3795_EQ_3795U(...) \, +#define Z_IS_3795U_EQ_3795U(...) \, +#define Z_IS_3796_EQ_3796(...) \, +#define Z_IS_3796U_EQ_3796(...) \, +#define Z_IS_3796_EQ_3796U(...) \, +#define Z_IS_3796U_EQ_3796U(...) \, +#define Z_IS_3797_EQ_3797(...) \, +#define Z_IS_3797U_EQ_3797(...) \, +#define Z_IS_3797_EQ_3797U(...) \, +#define Z_IS_3797U_EQ_3797U(...) \, +#define Z_IS_3798_EQ_3798(...) \, +#define Z_IS_3798U_EQ_3798(...) \, +#define Z_IS_3798_EQ_3798U(...) \, +#define Z_IS_3798U_EQ_3798U(...) \, +#define Z_IS_3799_EQ_3799(...) \, +#define Z_IS_3799U_EQ_3799(...) \, +#define Z_IS_3799_EQ_3799U(...) \, +#define Z_IS_3799U_EQ_3799U(...) \, +#define Z_IS_3800_EQ_3800(...) \, +#define Z_IS_3800U_EQ_3800(...) \, +#define Z_IS_3800_EQ_3800U(...) \, +#define Z_IS_3800U_EQ_3800U(...) \, +#define Z_IS_3801_EQ_3801(...) \, +#define Z_IS_3801U_EQ_3801(...) \, +#define Z_IS_3801_EQ_3801U(...) \, +#define Z_IS_3801U_EQ_3801U(...) \, +#define Z_IS_3802_EQ_3802(...) \, +#define Z_IS_3802U_EQ_3802(...) \, +#define Z_IS_3802_EQ_3802U(...) \, +#define Z_IS_3802U_EQ_3802U(...) \, +#define Z_IS_3803_EQ_3803(...) \, +#define Z_IS_3803U_EQ_3803(...) \, +#define Z_IS_3803_EQ_3803U(...) \, +#define Z_IS_3803U_EQ_3803U(...) \, +#define Z_IS_3804_EQ_3804(...) \, +#define Z_IS_3804U_EQ_3804(...) \, +#define Z_IS_3804_EQ_3804U(...) \, +#define Z_IS_3804U_EQ_3804U(...) \, +#define Z_IS_3805_EQ_3805(...) \, +#define Z_IS_3805U_EQ_3805(...) \, +#define Z_IS_3805_EQ_3805U(...) \, +#define Z_IS_3805U_EQ_3805U(...) \, +#define Z_IS_3806_EQ_3806(...) \, +#define Z_IS_3806U_EQ_3806(...) \, +#define Z_IS_3806_EQ_3806U(...) \, +#define Z_IS_3806U_EQ_3806U(...) \, +#define Z_IS_3807_EQ_3807(...) \, +#define Z_IS_3807U_EQ_3807(...) \, +#define Z_IS_3807_EQ_3807U(...) \, +#define Z_IS_3807U_EQ_3807U(...) \, +#define Z_IS_3808_EQ_3808(...) \, +#define Z_IS_3808U_EQ_3808(...) \, +#define Z_IS_3808_EQ_3808U(...) \, +#define Z_IS_3808U_EQ_3808U(...) \, +#define Z_IS_3809_EQ_3809(...) \, +#define Z_IS_3809U_EQ_3809(...) \, +#define Z_IS_3809_EQ_3809U(...) \, +#define Z_IS_3809U_EQ_3809U(...) \, +#define Z_IS_3810_EQ_3810(...) \, +#define Z_IS_3810U_EQ_3810(...) \, +#define Z_IS_3810_EQ_3810U(...) \, +#define Z_IS_3810U_EQ_3810U(...) \, +#define Z_IS_3811_EQ_3811(...) \, +#define Z_IS_3811U_EQ_3811(...) \, +#define Z_IS_3811_EQ_3811U(...) \, +#define Z_IS_3811U_EQ_3811U(...) \, +#define Z_IS_3812_EQ_3812(...) \, +#define Z_IS_3812U_EQ_3812(...) \, +#define Z_IS_3812_EQ_3812U(...) \, +#define Z_IS_3812U_EQ_3812U(...) \, +#define Z_IS_3813_EQ_3813(...) \, +#define Z_IS_3813U_EQ_3813(...) \, +#define Z_IS_3813_EQ_3813U(...) \, +#define Z_IS_3813U_EQ_3813U(...) \, +#define Z_IS_3814_EQ_3814(...) \, +#define Z_IS_3814U_EQ_3814(...) \, +#define Z_IS_3814_EQ_3814U(...) \, +#define Z_IS_3814U_EQ_3814U(...) \, +#define Z_IS_3815_EQ_3815(...) \, +#define Z_IS_3815U_EQ_3815(...) \, +#define Z_IS_3815_EQ_3815U(...) \, +#define Z_IS_3815U_EQ_3815U(...) \, +#define Z_IS_3816_EQ_3816(...) \, +#define Z_IS_3816U_EQ_3816(...) \, +#define Z_IS_3816_EQ_3816U(...) \, +#define Z_IS_3816U_EQ_3816U(...) \, +#define Z_IS_3817_EQ_3817(...) \, +#define Z_IS_3817U_EQ_3817(...) \, +#define Z_IS_3817_EQ_3817U(...) \, +#define Z_IS_3817U_EQ_3817U(...) \, +#define Z_IS_3818_EQ_3818(...) \, +#define Z_IS_3818U_EQ_3818(...) \, +#define Z_IS_3818_EQ_3818U(...) \, +#define Z_IS_3818U_EQ_3818U(...) \, +#define Z_IS_3819_EQ_3819(...) \, +#define Z_IS_3819U_EQ_3819(...) \, +#define Z_IS_3819_EQ_3819U(...) \, +#define Z_IS_3819U_EQ_3819U(...) \, +#define Z_IS_3820_EQ_3820(...) \, +#define Z_IS_3820U_EQ_3820(...) \, +#define Z_IS_3820_EQ_3820U(...) \, +#define Z_IS_3820U_EQ_3820U(...) \, +#define Z_IS_3821_EQ_3821(...) \, +#define Z_IS_3821U_EQ_3821(...) \, +#define Z_IS_3821_EQ_3821U(...) \, +#define Z_IS_3821U_EQ_3821U(...) \, +#define Z_IS_3822_EQ_3822(...) \, +#define Z_IS_3822U_EQ_3822(...) \, +#define Z_IS_3822_EQ_3822U(...) \, +#define Z_IS_3822U_EQ_3822U(...) \, +#define Z_IS_3823_EQ_3823(...) \, +#define Z_IS_3823U_EQ_3823(...) \, +#define Z_IS_3823_EQ_3823U(...) \, +#define Z_IS_3823U_EQ_3823U(...) \, +#define Z_IS_3824_EQ_3824(...) \, +#define Z_IS_3824U_EQ_3824(...) \, +#define Z_IS_3824_EQ_3824U(...) \, +#define Z_IS_3824U_EQ_3824U(...) \, +#define Z_IS_3825_EQ_3825(...) \, +#define Z_IS_3825U_EQ_3825(...) \, +#define Z_IS_3825_EQ_3825U(...) \, +#define Z_IS_3825U_EQ_3825U(...) \, +#define Z_IS_3826_EQ_3826(...) \, +#define Z_IS_3826U_EQ_3826(...) \, +#define Z_IS_3826_EQ_3826U(...) \, +#define Z_IS_3826U_EQ_3826U(...) \, +#define Z_IS_3827_EQ_3827(...) \, +#define Z_IS_3827U_EQ_3827(...) \, +#define Z_IS_3827_EQ_3827U(...) \, +#define Z_IS_3827U_EQ_3827U(...) \, +#define Z_IS_3828_EQ_3828(...) \, +#define Z_IS_3828U_EQ_3828(...) \, +#define Z_IS_3828_EQ_3828U(...) \, +#define Z_IS_3828U_EQ_3828U(...) \, +#define Z_IS_3829_EQ_3829(...) \, +#define Z_IS_3829U_EQ_3829(...) \, +#define Z_IS_3829_EQ_3829U(...) \, +#define Z_IS_3829U_EQ_3829U(...) \, +#define Z_IS_3830_EQ_3830(...) \, +#define Z_IS_3830U_EQ_3830(...) \, +#define Z_IS_3830_EQ_3830U(...) \, +#define Z_IS_3830U_EQ_3830U(...) \, +#define Z_IS_3831_EQ_3831(...) \, +#define Z_IS_3831U_EQ_3831(...) \, +#define Z_IS_3831_EQ_3831U(...) \, +#define Z_IS_3831U_EQ_3831U(...) \, +#define Z_IS_3832_EQ_3832(...) \, +#define Z_IS_3832U_EQ_3832(...) \, +#define Z_IS_3832_EQ_3832U(...) \, +#define Z_IS_3832U_EQ_3832U(...) \, +#define Z_IS_3833_EQ_3833(...) \, +#define Z_IS_3833U_EQ_3833(...) \, +#define Z_IS_3833_EQ_3833U(...) \, +#define Z_IS_3833U_EQ_3833U(...) \, +#define Z_IS_3834_EQ_3834(...) \, +#define Z_IS_3834U_EQ_3834(...) \, +#define Z_IS_3834_EQ_3834U(...) \, +#define Z_IS_3834U_EQ_3834U(...) \, +#define Z_IS_3835_EQ_3835(...) \, +#define Z_IS_3835U_EQ_3835(...) \, +#define Z_IS_3835_EQ_3835U(...) \, +#define Z_IS_3835U_EQ_3835U(...) \, +#define Z_IS_3836_EQ_3836(...) \, +#define Z_IS_3836U_EQ_3836(...) \, +#define Z_IS_3836_EQ_3836U(...) \, +#define Z_IS_3836U_EQ_3836U(...) \, +#define Z_IS_3837_EQ_3837(...) \, +#define Z_IS_3837U_EQ_3837(...) \, +#define Z_IS_3837_EQ_3837U(...) \, +#define Z_IS_3837U_EQ_3837U(...) \, +#define Z_IS_3838_EQ_3838(...) \, +#define Z_IS_3838U_EQ_3838(...) \, +#define Z_IS_3838_EQ_3838U(...) \, +#define Z_IS_3838U_EQ_3838U(...) \, +#define Z_IS_3839_EQ_3839(...) \, +#define Z_IS_3839U_EQ_3839(...) \, +#define Z_IS_3839_EQ_3839U(...) \, +#define Z_IS_3839U_EQ_3839U(...) \, +#define Z_IS_3840_EQ_3840(...) \, +#define Z_IS_3840U_EQ_3840(...) \, +#define Z_IS_3840_EQ_3840U(...) \, +#define Z_IS_3840U_EQ_3840U(...) \, +#define Z_IS_3841_EQ_3841(...) \, +#define Z_IS_3841U_EQ_3841(...) \, +#define Z_IS_3841_EQ_3841U(...) \, +#define Z_IS_3841U_EQ_3841U(...) \, +#define Z_IS_3842_EQ_3842(...) \, +#define Z_IS_3842U_EQ_3842(...) \, +#define Z_IS_3842_EQ_3842U(...) \, +#define Z_IS_3842U_EQ_3842U(...) \, +#define Z_IS_3843_EQ_3843(...) \, +#define Z_IS_3843U_EQ_3843(...) \, +#define Z_IS_3843_EQ_3843U(...) \, +#define Z_IS_3843U_EQ_3843U(...) \, +#define Z_IS_3844_EQ_3844(...) \, +#define Z_IS_3844U_EQ_3844(...) \, +#define Z_IS_3844_EQ_3844U(...) \, +#define Z_IS_3844U_EQ_3844U(...) \, +#define Z_IS_3845_EQ_3845(...) \, +#define Z_IS_3845U_EQ_3845(...) \, +#define Z_IS_3845_EQ_3845U(...) \, +#define Z_IS_3845U_EQ_3845U(...) \, +#define Z_IS_3846_EQ_3846(...) \, +#define Z_IS_3846U_EQ_3846(...) \, +#define Z_IS_3846_EQ_3846U(...) \, +#define Z_IS_3846U_EQ_3846U(...) \, +#define Z_IS_3847_EQ_3847(...) \, +#define Z_IS_3847U_EQ_3847(...) \, +#define Z_IS_3847_EQ_3847U(...) \, +#define Z_IS_3847U_EQ_3847U(...) \, +#define Z_IS_3848_EQ_3848(...) \, +#define Z_IS_3848U_EQ_3848(...) \, +#define Z_IS_3848_EQ_3848U(...) \, +#define Z_IS_3848U_EQ_3848U(...) \, +#define Z_IS_3849_EQ_3849(...) \, +#define Z_IS_3849U_EQ_3849(...) \, +#define Z_IS_3849_EQ_3849U(...) \, +#define Z_IS_3849U_EQ_3849U(...) \, +#define Z_IS_3850_EQ_3850(...) \, +#define Z_IS_3850U_EQ_3850(...) \, +#define Z_IS_3850_EQ_3850U(...) \, +#define Z_IS_3850U_EQ_3850U(...) \, +#define Z_IS_3851_EQ_3851(...) \, +#define Z_IS_3851U_EQ_3851(...) \, +#define Z_IS_3851_EQ_3851U(...) \, +#define Z_IS_3851U_EQ_3851U(...) \, +#define Z_IS_3852_EQ_3852(...) \, +#define Z_IS_3852U_EQ_3852(...) \, +#define Z_IS_3852_EQ_3852U(...) \, +#define Z_IS_3852U_EQ_3852U(...) \, +#define Z_IS_3853_EQ_3853(...) \, +#define Z_IS_3853U_EQ_3853(...) \, +#define Z_IS_3853_EQ_3853U(...) \, +#define Z_IS_3853U_EQ_3853U(...) \, +#define Z_IS_3854_EQ_3854(...) \, +#define Z_IS_3854U_EQ_3854(...) \, +#define Z_IS_3854_EQ_3854U(...) \, +#define Z_IS_3854U_EQ_3854U(...) \, +#define Z_IS_3855_EQ_3855(...) \, +#define Z_IS_3855U_EQ_3855(...) \, +#define Z_IS_3855_EQ_3855U(...) \, +#define Z_IS_3855U_EQ_3855U(...) \, +#define Z_IS_3856_EQ_3856(...) \, +#define Z_IS_3856U_EQ_3856(...) \, +#define Z_IS_3856_EQ_3856U(...) \, +#define Z_IS_3856U_EQ_3856U(...) \, +#define Z_IS_3857_EQ_3857(...) \, +#define Z_IS_3857U_EQ_3857(...) \, +#define Z_IS_3857_EQ_3857U(...) \, +#define Z_IS_3857U_EQ_3857U(...) \, +#define Z_IS_3858_EQ_3858(...) \, +#define Z_IS_3858U_EQ_3858(...) \, +#define Z_IS_3858_EQ_3858U(...) \, +#define Z_IS_3858U_EQ_3858U(...) \, +#define Z_IS_3859_EQ_3859(...) \, +#define Z_IS_3859U_EQ_3859(...) \, +#define Z_IS_3859_EQ_3859U(...) \, +#define Z_IS_3859U_EQ_3859U(...) \, +#define Z_IS_3860_EQ_3860(...) \, +#define Z_IS_3860U_EQ_3860(...) \, +#define Z_IS_3860_EQ_3860U(...) \, +#define Z_IS_3860U_EQ_3860U(...) \, +#define Z_IS_3861_EQ_3861(...) \, +#define Z_IS_3861U_EQ_3861(...) \, +#define Z_IS_3861_EQ_3861U(...) \, +#define Z_IS_3861U_EQ_3861U(...) \, +#define Z_IS_3862_EQ_3862(...) \, +#define Z_IS_3862U_EQ_3862(...) \, +#define Z_IS_3862_EQ_3862U(...) \, +#define Z_IS_3862U_EQ_3862U(...) \, +#define Z_IS_3863_EQ_3863(...) \, +#define Z_IS_3863U_EQ_3863(...) \, +#define Z_IS_3863_EQ_3863U(...) \, +#define Z_IS_3863U_EQ_3863U(...) \, +#define Z_IS_3864_EQ_3864(...) \, +#define Z_IS_3864U_EQ_3864(...) \, +#define Z_IS_3864_EQ_3864U(...) \, +#define Z_IS_3864U_EQ_3864U(...) \, +#define Z_IS_3865_EQ_3865(...) \, +#define Z_IS_3865U_EQ_3865(...) \, +#define Z_IS_3865_EQ_3865U(...) \, +#define Z_IS_3865U_EQ_3865U(...) \, +#define Z_IS_3866_EQ_3866(...) \, +#define Z_IS_3866U_EQ_3866(...) \, +#define Z_IS_3866_EQ_3866U(...) \, +#define Z_IS_3866U_EQ_3866U(...) \, +#define Z_IS_3867_EQ_3867(...) \, +#define Z_IS_3867U_EQ_3867(...) \, +#define Z_IS_3867_EQ_3867U(...) \, +#define Z_IS_3867U_EQ_3867U(...) \, +#define Z_IS_3868_EQ_3868(...) \, +#define Z_IS_3868U_EQ_3868(...) \, +#define Z_IS_3868_EQ_3868U(...) \, +#define Z_IS_3868U_EQ_3868U(...) \, +#define Z_IS_3869_EQ_3869(...) \, +#define Z_IS_3869U_EQ_3869(...) \, +#define Z_IS_3869_EQ_3869U(...) \, +#define Z_IS_3869U_EQ_3869U(...) \, +#define Z_IS_3870_EQ_3870(...) \, +#define Z_IS_3870U_EQ_3870(...) \, +#define Z_IS_3870_EQ_3870U(...) \, +#define Z_IS_3870U_EQ_3870U(...) \, +#define Z_IS_3871_EQ_3871(...) \, +#define Z_IS_3871U_EQ_3871(...) \, +#define Z_IS_3871_EQ_3871U(...) \, +#define Z_IS_3871U_EQ_3871U(...) \, +#define Z_IS_3872_EQ_3872(...) \, +#define Z_IS_3872U_EQ_3872(...) \, +#define Z_IS_3872_EQ_3872U(...) \, +#define Z_IS_3872U_EQ_3872U(...) \, +#define Z_IS_3873_EQ_3873(...) \, +#define Z_IS_3873U_EQ_3873(...) \, +#define Z_IS_3873_EQ_3873U(...) \, +#define Z_IS_3873U_EQ_3873U(...) \, +#define Z_IS_3874_EQ_3874(...) \, +#define Z_IS_3874U_EQ_3874(...) \, +#define Z_IS_3874_EQ_3874U(...) \, +#define Z_IS_3874U_EQ_3874U(...) \, +#define Z_IS_3875_EQ_3875(...) \, +#define Z_IS_3875U_EQ_3875(...) \, +#define Z_IS_3875_EQ_3875U(...) \, +#define Z_IS_3875U_EQ_3875U(...) \, +#define Z_IS_3876_EQ_3876(...) \, +#define Z_IS_3876U_EQ_3876(...) \, +#define Z_IS_3876_EQ_3876U(...) \, +#define Z_IS_3876U_EQ_3876U(...) \, +#define Z_IS_3877_EQ_3877(...) \, +#define Z_IS_3877U_EQ_3877(...) \, +#define Z_IS_3877_EQ_3877U(...) \, +#define Z_IS_3877U_EQ_3877U(...) \, +#define Z_IS_3878_EQ_3878(...) \, +#define Z_IS_3878U_EQ_3878(...) \, +#define Z_IS_3878_EQ_3878U(...) \, +#define Z_IS_3878U_EQ_3878U(...) \, +#define Z_IS_3879_EQ_3879(...) \, +#define Z_IS_3879U_EQ_3879(...) \, +#define Z_IS_3879_EQ_3879U(...) \, +#define Z_IS_3879U_EQ_3879U(...) \, +#define Z_IS_3880_EQ_3880(...) \, +#define Z_IS_3880U_EQ_3880(...) \, +#define Z_IS_3880_EQ_3880U(...) \, +#define Z_IS_3880U_EQ_3880U(...) \, +#define Z_IS_3881_EQ_3881(...) \, +#define Z_IS_3881U_EQ_3881(...) \, +#define Z_IS_3881_EQ_3881U(...) \, +#define Z_IS_3881U_EQ_3881U(...) \, +#define Z_IS_3882_EQ_3882(...) \, +#define Z_IS_3882U_EQ_3882(...) \, +#define Z_IS_3882_EQ_3882U(...) \, +#define Z_IS_3882U_EQ_3882U(...) \, +#define Z_IS_3883_EQ_3883(...) \, +#define Z_IS_3883U_EQ_3883(...) \, +#define Z_IS_3883_EQ_3883U(...) \, +#define Z_IS_3883U_EQ_3883U(...) \, +#define Z_IS_3884_EQ_3884(...) \, +#define Z_IS_3884U_EQ_3884(...) \, +#define Z_IS_3884_EQ_3884U(...) \, +#define Z_IS_3884U_EQ_3884U(...) \, +#define Z_IS_3885_EQ_3885(...) \, +#define Z_IS_3885U_EQ_3885(...) \, +#define Z_IS_3885_EQ_3885U(...) \, +#define Z_IS_3885U_EQ_3885U(...) \, +#define Z_IS_3886_EQ_3886(...) \, +#define Z_IS_3886U_EQ_3886(...) \, +#define Z_IS_3886_EQ_3886U(...) \, +#define Z_IS_3886U_EQ_3886U(...) \, +#define Z_IS_3887_EQ_3887(...) \, +#define Z_IS_3887U_EQ_3887(...) \, +#define Z_IS_3887_EQ_3887U(...) \, +#define Z_IS_3887U_EQ_3887U(...) \, +#define Z_IS_3888_EQ_3888(...) \, +#define Z_IS_3888U_EQ_3888(...) \, +#define Z_IS_3888_EQ_3888U(...) \, +#define Z_IS_3888U_EQ_3888U(...) \, +#define Z_IS_3889_EQ_3889(...) \, +#define Z_IS_3889U_EQ_3889(...) \, +#define Z_IS_3889_EQ_3889U(...) \, +#define Z_IS_3889U_EQ_3889U(...) \, +#define Z_IS_3890_EQ_3890(...) \, +#define Z_IS_3890U_EQ_3890(...) \, +#define Z_IS_3890_EQ_3890U(...) \, +#define Z_IS_3890U_EQ_3890U(...) \, +#define Z_IS_3891_EQ_3891(...) \, +#define Z_IS_3891U_EQ_3891(...) \, +#define Z_IS_3891_EQ_3891U(...) \, +#define Z_IS_3891U_EQ_3891U(...) \, +#define Z_IS_3892_EQ_3892(...) \, +#define Z_IS_3892U_EQ_3892(...) \, +#define Z_IS_3892_EQ_3892U(...) \, +#define Z_IS_3892U_EQ_3892U(...) \, +#define Z_IS_3893_EQ_3893(...) \, +#define Z_IS_3893U_EQ_3893(...) \, +#define Z_IS_3893_EQ_3893U(...) \, +#define Z_IS_3893U_EQ_3893U(...) \, +#define Z_IS_3894_EQ_3894(...) \, +#define Z_IS_3894U_EQ_3894(...) \, +#define Z_IS_3894_EQ_3894U(...) \, +#define Z_IS_3894U_EQ_3894U(...) \, +#define Z_IS_3895_EQ_3895(...) \, +#define Z_IS_3895U_EQ_3895(...) \, +#define Z_IS_3895_EQ_3895U(...) \, +#define Z_IS_3895U_EQ_3895U(...) \, +#define Z_IS_3896_EQ_3896(...) \, +#define Z_IS_3896U_EQ_3896(...) \, +#define Z_IS_3896_EQ_3896U(...) \, +#define Z_IS_3896U_EQ_3896U(...) \, +#define Z_IS_3897_EQ_3897(...) \, +#define Z_IS_3897U_EQ_3897(...) \, +#define Z_IS_3897_EQ_3897U(...) \, +#define Z_IS_3897U_EQ_3897U(...) \, +#define Z_IS_3898_EQ_3898(...) \, +#define Z_IS_3898U_EQ_3898(...) \, +#define Z_IS_3898_EQ_3898U(...) \, +#define Z_IS_3898U_EQ_3898U(...) \, +#define Z_IS_3899_EQ_3899(...) \, +#define Z_IS_3899U_EQ_3899(...) \, +#define Z_IS_3899_EQ_3899U(...) \, +#define Z_IS_3899U_EQ_3899U(...) \, +#define Z_IS_3900_EQ_3900(...) \, +#define Z_IS_3900U_EQ_3900(...) \, +#define Z_IS_3900_EQ_3900U(...) \, +#define Z_IS_3900U_EQ_3900U(...) \, +#define Z_IS_3901_EQ_3901(...) \, +#define Z_IS_3901U_EQ_3901(...) \, +#define Z_IS_3901_EQ_3901U(...) \, +#define Z_IS_3901U_EQ_3901U(...) \, +#define Z_IS_3902_EQ_3902(...) \, +#define Z_IS_3902U_EQ_3902(...) \, +#define Z_IS_3902_EQ_3902U(...) \, +#define Z_IS_3902U_EQ_3902U(...) \, +#define Z_IS_3903_EQ_3903(...) \, +#define Z_IS_3903U_EQ_3903(...) \, +#define Z_IS_3903_EQ_3903U(...) \, +#define Z_IS_3903U_EQ_3903U(...) \, +#define Z_IS_3904_EQ_3904(...) \, +#define Z_IS_3904U_EQ_3904(...) \, +#define Z_IS_3904_EQ_3904U(...) \, +#define Z_IS_3904U_EQ_3904U(...) \, +#define Z_IS_3905_EQ_3905(...) \, +#define Z_IS_3905U_EQ_3905(...) \, +#define Z_IS_3905_EQ_3905U(...) \, +#define Z_IS_3905U_EQ_3905U(...) \, +#define Z_IS_3906_EQ_3906(...) \, +#define Z_IS_3906U_EQ_3906(...) \, +#define Z_IS_3906_EQ_3906U(...) \, +#define Z_IS_3906U_EQ_3906U(...) \, +#define Z_IS_3907_EQ_3907(...) \, +#define Z_IS_3907U_EQ_3907(...) \, +#define Z_IS_3907_EQ_3907U(...) \, +#define Z_IS_3907U_EQ_3907U(...) \, +#define Z_IS_3908_EQ_3908(...) \, +#define Z_IS_3908U_EQ_3908(...) \, +#define Z_IS_3908_EQ_3908U(...) \, +#define Z_IS_3908U_EQ_3908U(...) \, +#define Z_IS_3909_EQ_3909(...) \, +#define Z_IS_3909U_EQ_3909(...) \, +#define Z_IS_3909_EQ_3909U(...) \, +#define Z_IS_3909U_EQ_3909U(...) \, +#define Z_IS_3910_EQ_3910(...) \, +#define Z_IS_3910U_EQ_3910(...) \, +#define Z_IS_3910_EQ_3910U(...) \, +#define Z_IS_3910U_EQ_3910U(...) \, +#define Z_IS_3911_EQ_3911(...) \, +#define Z_IS_3911U_EQ_3911(...) \, +#define Z_IS_3911_EQ_3911U(...) \, +#define Z_IS_3911U_EQ_3911U(...) \, +#define Z_IS_3912_EQ_3912(...) \, +#define Z_IS_3912U_EQ_3912(...) \, +#define Z_IS_3912_EQ_3912U(...) \, +#define Z_IS_3912U_EQ_3912U(...) \, +#define Z_IS_3913_EQ_3913(...) \, +#define Z_IS_3913U_EQ_3913(...) \, +#define Z_IS_3913_EQ_3913U(...) \, +#define Z_IS_3913U_EQ_3913U(...) \, +#define Z_IS_3914_EQ_3914(...) \, +#define Z_IS_3914U_EQ_3914(...) \, +#define Z_IS_3914_EQ_3914U(...) \, +#define Z_IS_3914U_EQ_3914U(...) \, +#define Z_IS_3915_EQ_3915(...) \, +#define Z_IS_3915U_EQ_3915(...) \, +#define Z_IS_3915_EQ_3915U(...) \, +#define Z_IS_3915U_EQ_3915U(...) \, +#define Z_IS_3916_EQ_3916(...) \, +#define Z_IS_3916U_EQ_3916(...) \, +#define Z_IS_3916_EQ_3916U(...) \, +#define Z_IS_3916U_EQ_3916U(...) \, +#define Z_IS_3917_EQ_3917(...) \, +#define Z_IS_3917U_EQ_3917(...) \, +#define Z_IS_3917_EQ_3917U(...) \, +#define Z_IS_3917U_EQ_3917U(...) \, +#define Z_IS_3918_EQ_3918(...) \, +#define Z_IS_3918U_EQ_3918(...) \, +#define Z_IS_3918_EQ_3918U(...) \, +#define Z_IS_3918U_EQ_3918U(...) \, +#define Z_IS_3919_EQ_3919(...) \, +#define Z_IS_3919U_EQ_3919(...) \, +#define Z_IS_3919_EQ_3919U(...) \, +#define Z_IS_3919U_EQ_3919U(...) \, +#define Z_IS_3920_EQ_3920(...) \, +#define Z_IS_3920U_EQ_3920(...) \, +#define Z_IS_3920_EQ_3920U(...) \, +#define Z_IS_3920U_EQ_3920U(...) \, +#define Z_IS_3921_EQ_3921(...) \, +#define Z_IS_3921U_EQ_3921(...) \, +#define Z_IS_3921_EQ_3921U(...) \, +#define Z_IS_3921U_EQ_3921U(...) \, +#define Z_IS_3922_EQ_3922(...) \, +#define Z_IS_3922U_EQ_3922(...) \, +#define Z_IS_3922_EQ_3922U(...) \, +#define Z_IS_3922U_EQ_3922U(...) \, +#define Z_IS_3923_EQ_3923(...) \, +#define Z_IS_3923U_EQ_3923(...) \, +#define Z_IS_3923_EQ_3923U(...) \, +#define Z_IS_3923U_EQ_3923U(...) \, +#define Z_IS_3924_EQ_3924(...) \, +#define Z_IS_3924U_EQ_3924(...) \, +#define Z_IS_3924_EQ_3924U(...) \, +#define Z_IS_3924U_EQ_3924U(...) \, +#define Z_IS_3925_EQ_3925(...) \, +#define Z_IS_3925U_EQ_3925(...) \, +#define Z_IS_3925_EQ_3925U(...) \, +#define Z_IS_3925U_EQ_3925U(...) \, +#define Z_IS_3926_EQ_3926(...) \, +#define Z_IS_3926U_EQ_3926(...) \, +#define Z_IS_3926_EQ_3926U(...) \, +#define Z_IS_3926U_EQ_3926U(...) \, +#define Z_IS_3927_EQ_3927(...) \, +#define Z_IS_3927U_EQ_3927(...) \, +#define Z_IS_3927_EQ_3927U(...) \, +#define Z_IS_3927U_EQ_3927U(...) \, +#define Z_IS_3928_EQ_3928(...) \, +#define Z_IS_3928U_EQ_3928(...) \, +#define Z_IS_3928_EQ_3928U(...) \, +#define Z_IS_3928U_EQ_3928U(...) \, +#define Z_IS_3929_EQ_3929(...) \, +#define Z_IS_3929U_EQ_3929(...) \, +#define Z_IS_3929_EQ_3929U(...) \, +#define Z_IS_3929U_EQ_3929U(...) \, +#define Z_IS_3930_EQ_3930(...) \, +#define Z_IS_3930U_EQ_3930(...) \, +#define Z_IS_3930_EQ_3930U(...) \, +#define Z_IS_3930U_EQ_3930U(...) \, +#define Z_IS_3931_EQ_3931(...) \, +#define Z_IS_3931U_EQ_3931(...) \, +#define Z_IS_3931_EQ_3931U(...) \, +#define Z_IS_3931U_EQ_3931U(...) \, +#define Z_IS_3932_EQ_3932(...) \, +#define Z_IS_3932U_EQ_3932(...) \, +#define Z_IS_3932_EQ_3932U(...) \, +#define Z_IS_3932U_EQ_3932U(...) \, +#define Z_IS_3933_EQ_3933(...) \, +#define Z_IS_3933U_EQ_3933(...) \, +#define Z_IS_3933_EQ_3933U(...) \, +#define Z_IS_3933U_EQ_3933U(...) \, +#define Z_IS_3934_EQ_3934(...) \, +#define Z_IS_3934U_EQ_3934(...) \, +#define Z_IS_3934_EQ_3934U(...) \, +#define Z_IS_3934U_EQ_3934U(...) \, +#define Z_IS_3935_EQ_3935(...) \, +#define Z_IS_3935U_EQ_3935(...) \, +#define Z_IS_3935_EQ_3935U(...) \, +#define Z_IS_3935U_EQ_3935U(...) \, +#define Z_IS_3936_EQ_3936(...) \, +#define Z_IS_3936U_EQ_3936(...) \, +#define Z_IS_3936_EQ_3936U(...) \, +#define Z_IS_3936U_EQ_3936U(...) \, +#define Z_IS_3937_EQ_3937(...) \, +#define Z_IS_3937U_EQ_3937(...) \, +#define Z_IS_3937_EQ_3937U(...) \, +#define Z_IS_3937U_EQ_3937U(...) \, +#define Z_IS_3938_EQ_3938(...) \, +#define Z_IS_3938U_EQ_3938(...) \, +#define Z_IS_3938_EQ_3938U(...) \, +#define Z_IS_3938U_EQ_3938U(...) \, +#define Z_IS_3939_EQ_3939(...) \, +#define Z_IS_3939U_EQ_3939(...) \, +#define Z_IS_3939_EQ_3939U(...) \, +#define Z_IS_3939U_EQ_3939U(...) \, +#define Z_IS_3940_EQ_3940(...) \, +#define Z_IS_3940U_EQ_3940(...) \, +#define Z_IS_3940_EQ_3940U(...) \, +#define Z_IS_3940U_EQ_3940U(...) \, +#define Z_IS_3941_EQ_3941(...) \, +#define Z_IS_3941U_EQ_3941(...) \, +#define Z_IS_3941_EQ_3941U(...) \, +#define Z_IS_3941U_EQ_3941U(...) \, +#define Z_IS_3942_EQ_3942(...) \, +#define Z_IS_3942U_EQ_3942(...) \, +#define Z_IS_3942_EQ_3942U(...) \, +#define Z_IS_3942U_EQ_3942U(...) \, +#define Z_IS_3943_EQ_3943(...) \, +#define Z_IS_3943U_EQ_3943(...) \, +#define Z_IS_3943_EQ_3943U(...) \, +#define Z_IS_3943U_EQ_3943U(...) \, +#define Z_IS_3944_EQ_3944(...) \, +#define Z_IS_3944U_EQ_3944(...) \, +#define Z_IS_3944_EQ_3944U(...) \, +#define Z_IS_3944U_EQ_3944U(...) \, +#define Z_IS_3945_EQ_3945(...) \, +#define Z_IS_3945U_EQ_3945(...) \, +#define Z_IS_3945_EQ_3945U(...) \, +#define Z_IS_3945U_EQ_3945U(...) \, +#define Z_IS_3946_EQ_3946(...) \, +#define Z_IS_3946U_EQ_3946(...) \, +#define Z_IS_3946_EQ_3946U(...) \, +#define Z_IS_3946U_EQ_3946U(...) \, +#define Z_IS_3947_EQ_3947(...) \, +#define Z_IS_3947U_EQ_3947(...) \, +#define Z_IS_3947_EQ_3947U(...) \, +#define Z_IS_3947U_EQ_3947U(...) \, +#define Z_IS_3948_EQ_3948(...) \, +#define Z_IS_3948U_EQ_3948(...) \, +#define Z_IS_3948_EQ_3948U(...) \, +#define Z_IS_3948U_EQ_3948U(...) \, +#define Z_IS_3949_EQ_3949(...) \, +#define Z_IS_3949U_EQ_3949(...) \, +#define Z_IS_3949_EQ_3949U(...) \, +#define Z_IS_3949U_EQ_3949U(...) \, +#define Z_IS_3950_EQ_3950(...) \, +#define Z_IS_3950U_EQ_3950(...) \, +#define Z_IS_3950_EQ_3950U(...) \, +#define Z_IS_3950U_EQ_3950U(...) \, +#define Z_IS_3951_EQ_3951(...) \, +#define Z_IS_3951U_EQ_3951(...) \, +#define Z_IS_3951_EQ_3951U(...) \, +#define Z_IS_3951U_EQ_3951U(...) \, +#define Z_IS_3952_EQ_3952(...) \, +#define Z_IS_3952U_EQ_3952(...) \, +#define Z_IS_3952_EQ_3952U(...) \, +#define Z_IS_3952U_EQ_3952U(...) \, +#define Z_IS_3953_EQ_3953(...) \, +#define Z_IS_3953U_EQ_3953(...) \, +#define Z_IS_3953_EQ_3953U(...) \, +#define Z_IS_3953U_EQ_3953U(...) \, +#define Z_IS_3954_EQ_3954(...) \, +#define Z_IS_3954U_EQ_3954(...) \, +#define Z_IS_3954_EQ_3954U(...) \, +#define Z_IS_3954U_EQ_3954U(...) \, +#define Z_IS_3955_EQ_3955(...) \, +#define Z_IS_3955U_EQ_3955(...) \, +#define Z_IS_3955_EQ_3955U(...) \, +#define Z_IS_3955U_EQ_3955U(...) \, +#define Z_IS_3956_EQ_3956(...) \, +#define Z_IS_3956U_EQ_3956(...) \, +#define Z_IS_3956_EQ_3956U(...) \, +#define Z_IS_3956U_EQ_3956U(...) \, +#define Z_IS_3957_EQ_3957(...) \, +#define Z_IS_3957U_EQ_3957(...) \, +#define Z_IS_3957_EQ_3957U(...) \, +#define Z_IS_3957U_EQ_3957U(...) \, +#define Z_IS_3958_EQ_3958(...) \, +#define Z_IS_3958U_EQ_3958(...) \, +#define Z_IS_3958_EQ_3958U(...) \, +#define Z_IS_3958U_EQ_3958U(...) \, +#define Z_IS_3959_EQ_3959(...) \, +#define Z_IS_3959U_EQ_3959(...) \, +#define Z_IS_3959_EQ_3959U(...) \, +#define Z_IS_3959U_EQ_3959U(...) \, +#define Z_IS_3960_EQ_3960(...) \, +#define Z_IS_3960U_EQ_3960(...) \, +#define Z_IS_3960_EQ_3960U(...) \, +#define Z_IS_3960U_EQ_3960U(...) \, +#define Z_IS_3961_EQ_3961(...) \, +#define Z_IS_3961U_EQ_3961(...) \, +#define Z_IS_3961_EQ_3961U(...) \, +#define Z_IS_3961U_EQ_3961U(...) \, +#define Z_IS_3962_EQ_3962(...) \, +#define Z_IS_3962U_EQ_3962(...) \, +#define Z_IS_3962_EQ_3962U(...) \, +#define Z_IS_3962U_EQ_3962U(...) \, +#define Z_IS_3963_EQ_3963(...) \, +#define Z_IS_3963U_EQ_3963(...) \, +#define Z_IS_3963_EQ_3963U(...) \, +#define Z_IS_3963U_EQ_3963U(...) \, +#define Z_IS_3964_EQ_3964(...) \, +#define Z_IS_3964U_EQ_3964(...) \, +#define Z_IS_3964_EQ_3964U(...) \, +#define Z_IS_3964U_EQ_3964U(...) \, +#define Z_IS_3965_EQ_3965(...) \, +#define Z_IS_3965U_EQ_3965(...) \, +#define Z_IS_3965_EQ_3965U(...) \, +#define Z_IS_3965U_EQ_3965U(...) \, +#define Z_IS_3966_EQ_3966(...) \, +#define Z_IS_3966U_EQ_3966(...) \, +#define Z_IS_3966_EQ_3966U(...) \, +#define Z_IS_3966U_EQ_3966U(...) \, +#define Z_IS_3967_EQ_3967(...) \, +#define Z_IS_3967U_EQ_3967(...) \, +#define Z_IS_3967_EQ_3967U(...) \, +#define Z_IS_3967U_EQ_3967U(...) \, +#define Z_IS_3968_EQ_3968(...) \, +#define Z_IS_3968U_EQ_3968(...) \, +#define Z_IS_3968_EQ_3968U(...) \, +#define Z_IS_3968U_EQ_3968U(...) \, +#define Z_IS_3969_EQ_3969(...) \, +#define Z_IS_3969U_EQ_3969(...) \, +#define Z_IS_3969_EQ_3969U(...) \, +#define Z_IS_3969U_EQ_3969U(...) \, +#define Z_IS_3970_EQ_3970(...) \, +#define Z_IS_3970U_EQ_3970(...) \, +#define Z_IS_3970_EQ_3970U(...) \, +#define Z_IS_3970U_EQ_3970U(...) \, +#define Z_IS_3971_EQ_3971(...) \, +#define Z_IS_3971U_EQ_3971(...) \, +#define Z_IS_3971_EQ_3971U(...) \, +#define Z_IS_3971U_EQ_3971U(...) \, +#define Z_IS_3972_EQ_3972(...) \, +#define Z_IS_3972U_EQ_3972(...) \, +#define Z_IS_3972_EQ_3972U(...) \, +#define Z_IS_3972U_EQ_3972U(...) \, +#define Z_IS_3973_EQ_3973(...) \, +#define Z_IS_3973U_EQ_3973(...) \, +#define Z_IS_3973_EQ_3973U(...) \, +#define Z_IS_3973U_EQ_3973U(...) \, +#define Z_IS_3974_EQ_3974(...) \, +#define Z_IS_3974U_EQ_3974(...) \, +#define Z_IS_3974_EQ_3974U(...) \, +#define Z_IS_3974U_EQ_3974U(...) \, +#define Z_IS_3975_EQ_3975(...) \, +#define Z_IS_3975U_EQ_3975(...) \, +#define Z_IS_3975_EQ_3975U(...) \, +#define Z_IS_3975U_EQ_3975U(...) \, +#define Z_IS_3976_EQ_3976(...) \, +#define Z_IS_3976U_EQ_3976(...) \, +#define Z_IS_3976_EQ_3976U(...) \, +#define Z_IS_3976U_EQ_3976U(...) \, +#define Z_IS_3977_EQ_3977(...) \, +#define Z_IS_3977U_EQ_3977(...) \, +#define Z_IS_3977_EQ_3977U(...) \, +#define Z_IS_3977U_EQ_3977U(...) \, +#define Z_IS_3978_EQ_3978(...) \, +#define Z_IS_3978U_EQ_3978(...) \, +#define Z_IS_3978_EQ_3978U(...) \, +#define Z_IS_3978U_EQ_3978U(...) \, +#define Z_IS_3979_EQ_3979(...) \, +#define Z_IS_3979U_EQ_3979(...) \, +#define Z_IS_3979_EQ_3979U(...) \, +#define Z_IS_3979U_EQ_3979U(...) \, +#define Z_IS_3980_EQ_3980(...) \, +#define Z_IS_3980U_EQ_3980(...) \, +#define Z_IS_3980_EQ_3980U(...) \, +#define Z_IS_3980U_EQ_3980U(...) \, +#define Z_IS_3981_EQ_3981(...) \, +#define Z_IS_3981U_EQ_3981(...) \, +#define Z_IS_3981_EQ_3981U(...) \, +#define Z_IS_3981U_EQ_3981U(...) \, +#define Z_IS_3982_EQ_3982(...) \, +#define Z_IS_3982U_EQ_3982(...) \, +#define Z_IS_3982_EQ_3982U(...) \, +#define Z_IS_3982U_EQ_3982U(...) \, +#define Z_IS_3983_EQ_3983(...) \, +#define Z_IS_3983U_EQ_3983(...) \, +#define Z_IS_3983_EQ_3983U(...) \, +#define Z_IS_3983U_EQ_3983U(...) \, +#define Z_IS_3984_EQ_3984(...) \, +#define Z_IS_3984U_EQ_3984(...) \, +#define Z_IS_3984_EQ_3984U(...) \, +#define Z_IS_3984U_EQ_3984U(...) \, +#define Z_IS_3985_EQ_3985(...) \, +#define Z_IS_3985U_EQ_3985(...) \, +#define Z_IS_3985_EQ_3985U(...) \, +#define Z_IS_3985U_EQ_3985U(...) \, +#define Z_IS_3986_EQ_3986(...) \, +#define Z_IS_3986U_EQ_3986(...) \, +#define Z_IS_3986_EQ_3986U(...) \, +#define Z_IS_3986U_EQ_3986U(...) \, +#define Z_IS_3987_EQ_3987(...) \, +#define Z_IS_3987U_EQ_3987(...) \, +#define Z_IS_3987_EQ_3987U(...) \, +#define Z_IS_3987U_EQ_3987U(...) \, +#define Z_IS_3988_EQ_3988(...) \, +#define Z_IS_3988U_EQ_3988(...) \, +#define Z_IS_3988_EQ_3988U(...) \, +#define Z_IS_3988U_EQ_3988U(...) \, +#define Z_IS_3989_EQ_3989(...) \, +#define Z_IS_3989U_EQ_3989(...) \, +#define Z_IS_3989_EQ_3989U(...) \, +#define Z_IS_3989U_EQ_3989U(...) \, +#define Z_IS_3990_EQ_3990(...) \, +#define Z_IS_3990U_EQ_3990(...) \, +#define Z_IS_3990_EQ_3990U(...) \, +#define Z_IS_3990U_EQ_3990U(...) \, +#define Z_IS_3991_EQ_3991(...) \, +#define Z_IS_3991U_EQ_3991(...) \, +#define Z_IS_3991_EQ_3991U(...) \, +#define Z_IS_3991U_EQ_3991U(...) \, +#define Z_IS_3992_EQ_3992(...) \, +#define Z_IS_3992U_EQ_3992(...) \, +#define Z_IS_3992_EQ_3992U(...) \, +#define Z_IS_3992U_EQ_3992U(...) \, +#define Z_IS_3993_EQ_3993(...) \, +#define Z_IS_3993U_EQ_3993(...) \, +#define Z_IS_3993_EQ_3993U(...) \, +#define Z_IS_3993U_EQ_3993U(...) \, +#define Z_IS_3994_EQ_3994(...) \, +#define Z_IS_3994U_EQ_3994(...) \, +#define Z_IS_3994_EQ_3994U(...) \, +#define Z_IS_3994U_EQ_3994U(...) \, +#define Z_IS_3995_EQ_3995(...) \, +#define Z_IS_3995U_EQ_3995(...) \, +#define Z_IS_3995_EQ_3995U(...) \, +#define Z_IS_3995U_EQ_3995U(...) \, +#define Z_IS_3996_EQ_3996(...) \, +#define Z_IS_3996U_EQ_3996(...) \, +#define Z_IS_3996_EQ_3996U(...) \, +#define Z_IS_3996U_EQ_3996U(...) \, +#define Z_IS_3997_EQ_3997(...) \, +#define Z_IS_3997U_EQ_3997(...) \, +#define Z_IS_3997_EQ_3997U(...) \, +#define Z_IS_3997U_EQ_3997U(...) \, +#define Z_IS_3998_EQ_3998(...) \, +#define Z_IS_3998U_EQ_3998(...) \, +#define Z_IS_3998_EQ_3998U(...) \, +#define Z_IS_3998U_EQ_3998U(...) \, +#define Z_IS_3999_EQ_3999(...) \, +#define Z_IS_3999U_EQ_3999(...) \, +#define Z_IS_3999_EQ_3999U(...) \, +#define Z_IS_3999U_EQ_3999U(...) \, +#define Z_IS_4000_EQ_4000(...) \, +#define Z_IS_4000U_EQ_4000(...) \, +#define Z_IS_4000_EQ_4000U(...) \, +#define Z_IS_4000U_EQ_4000U(...) \, +#define Z_IS_4001_EQ_4001(...) \, +#define Z_IS_4001U_EQ_4001(...) \, +#define Z_IS_4001_EQ_4001U(...) \, +#define Z_IS_4001U_EQ_4001U(...) \, +#define Z_IS_4002_EQ_4002(...) \, +#define Z_IS_4002U_EQ_4002(...) \, +#define Z_IS_4002_EQ_4002U(...) \, +#define Z_IS_4002U_EQ_4002U(...) \, +#define Z_IS_4003_EQ_4003(...) \, +#define Z_IS_4003U_EQ_4003(...) \, +#define Z_IS_4003_EQ_4003U(...) \, +#define Z_IS_4003U_EQ_4003U(...) \, +#define Z_IS_4004_EQ_4004(...) \, +#define Z_IS_4004U_EQ_4004(...) \, +#define Z_IS_4004_EQ_4004U(...) \, +#define Z_IS_4004U_EQ_4004U(...) \, +#define Z_IS_4005_EQ_4005(...) \, +#define Z_IS_4005U_EQ_4005(...) \, +#define Z_IS_4005_EQ_4005U(...) \, +#define Z_IS_4005U_EQ_4005U(...) \, +#define Z_IS_4006_EQ_4006(...) \, +#define Z_IS_4006U_EQ_4006(...) \, +#define Z_IS_4006_EQ_4006U(...) \, +#define Z_IS_4006U_EQ_4006U(...) \, +#define Z_IS_4007_EQ_4007(...) \, +#define Z_IS_4007U_EQ_4007(...) \, +#define Z_IS_4007_EQ_4007U(...) \, +#define Z_IS_4007U_EQ_4007U(...) \, +#define Z_IS_4008_EQ_4008(...) \, +#define Z_IS_4008U_EQ_4008(...) \, +#define Z_IS_4008_EQ_4008U(...) \, +#define Z_IS_4008U_EQ_4008U(...) \, +#define Z_IS_4009_EQ_4009(...) \, +#define Z_IS_4009U_EQ_4009(...) \, +#define Z_IS_4009_EQ_4009U(...) \, +#define Z_IS_4009U_EQ_4009U(...) \, +#define Z_IS_4010_EQ_4010(...) \, +#define Z_IS_4010U_EQ_4010(...) \, +#define Z_IS_4010_EQ_4010U(...) \, +#define Z_IS_4010U_EQ_4010U(...) \, +#define Z_IS_4011_EQ_4011(...) \, +#define Z_IS_4011U_EQ_4011(...) \, +#define Z_IS_4011_EQ_4011U(...) \, +#define Z_IS_4011U_EQ_4011U(...) \, +#define Z_IS_4012_EQ_4012(...) \, +#define Z_IS_4012U_EQ_4012(...) \, +#define Z_IS_4012_EQ_4012U(...) \, +#define Z_IS_4012U_EQ_4012U(...) \, +#define Z_IS_4013_EQ_4013(...) \, +#define Z_IS_4013U_EQ_4013(...) \, +#define Z_IS_4013_EQ_4013U(...) \, +#define Z_IS_4013U_EQ_4013U(...) \, +#define Z_IS_4014_EQ_4014(...) \, +#define Z_IS_4014U_EQ_4014(...) \, +#define Z_IS_4014_EQ_4014U(...) \, +#define Z_IS_4014U_EQ_4014U(...) \, +#define Z_IS_4015_EQ_4015(...) \, +#define Z_IS_4015U_EQ_4015(...) \, +#define Z_IS_4015_EQ_4015U(...) \, +#define Z_IS_4015U_EQ_4015U(...) \, +#define Z_IS_4016_EQ_4016(...) \, +#define Z_IS_4016U_EQ_4016(...) \, +#define Z_IS_4016_EQ_4016U(...) \, +#define Z_IS_4016U_EQ_4016U(...) \, +#define Z_IS_4017_EQ_4017(...) \, +#define Z_IS_4017U_EQ_4017(...) \, +#define Z_IS_4017_EQ_4017U(...) \, +#define Z_IS_4017U_EQ_4017U(...) \, +#define Z_IS_4018_EQ_4018(...) \, +#define Z_IS_4018U_EQ_4018(...) \, +#define Z_IS_4018_EQ_4018U(...) \, +#define Z_IS_4018U_EQ_4018U(...) \, +#define Z_IS_4019_EQ_4019(...) \, +#define Z_IS_4019U_EQ_4019(...) \, +#define Z_IS_4019_EQ_4019U(...) \, +#define Z_IS_4019U_EQ_4019U(...) \, +#define Z_IS_4020_EQ_4020(...) \, +#define Z_IS_4020U_EQ_4020(...) \, +#define Z_IS_4020_EQ_4020U(...) \, +#define Z_IS_4020U_EQ_4020U(...) \, +#define Z_IS_4021_EQ_4021(...) \, +#define Z_IS_4021U_EQ_4021(...) \, +#define Z_IS_4021_EQ_4021U(...) \, +#define Z_IS_4021U_EQ_4021U(...) \, +#define Z_IS_4022_EQ_4022(...) \, +#define Z_IS_4022U_EQ_4022(...) \, +#define Z_IS_4022_EQ_4022U(...) \, +#define Z_IS_4022U_EQ_4022U(...) \, +#define Z_IS_4023_EQ_4023(...) \, +#define Z_IS_4023U_EQ_4023(...) \, +#define Z_IS_4023_EQ_4023U(...) \, +#define Z_IS_4023U_EQ_4023U(...) \, +#define Z_IS_4024_EQ_4024(...) \, +#define Z_IS_4024U_EQ_4024(...) \, +#define Z_IS_4024_EQ_4024U(...) \, +#define Z_IS_4024U_EQ_4024U(...) \, +#define Z_IS_4025_EQ_4025(...) \, +#define Z_IS_4025U_EQ_4025(...) \, +#define Z_IS_4025_EQ_4025U(...) \, +#define Z_IS_4025U_EQ_4025U(...) \, +#define Z_IS_4026_EQ_4026(...) \, +#define Z_IS_4026U_EQ_4026(...) \, +#define Z_IS_4026_EQ_4026U(...) \, +#define Z_IS_4026U_EQ_4026U(...) \, +#define Z_IS_4027_EQ_4027(...) \, +#define Z_IS_4027U_EQ_4027(...) \, +#define Z_IS_4027_EQ_4027U(...) \, +#define Z_IS_4027U_EQ_4027U(...) \, +#define Z_IS_4028_EQ_4028(...) \, +#define Z_IS_4028U_EQ_4028(...) \, +#define Z_IS_4028_EQ_4028U(...) \, +#define Z_IS_4028U_EQ_4028U(...) \, +#define Z_IS_4029_EQ_4029(...) \, +#define Z_IS_4029U_EQ_4029(...) \, +#define Z_IS_4029_EQ_4029U(...) \, +#define Z_IS_4029U_EQ_4029U(...) \, +#define Z_IS_4030_EQ_4030(...) \, +#define Z_IS_4030U_EQ_4030(...) \, +#define Z_IS_4030_EQ_4030U(...) \, +#define Z_IS_4030U_EQ_4030U(...) \, +#define Z_IS_4031_EQ_4031(...) \, +#define Z_IS_4031U_EQ_4031(...) \, +#define Z_IS_4031_EQ_4031U(...) \, +#define Z_IS_4031U_EQ_4031U(...) \, +#define Z_IS_4032_EQ_4032(...) \, +#define Z_IS_4032U_EQ_4032(...) \, +#define Z_IS_4032_EQ_4032U(...) \, +#define Z_IS_4032U_EQ_4032U(...) \, +#define Z_IS_4033_EQ_4033(...) \, +#define Z_IS_4033U_EQ_4033(...) \, +#define Z_IS_4033_EQ_4033U(...) \, +#define Z_IS_4033U_EQ_4033U(...) \, +#define Z_IS_4034_EQ_4034(...) \, +#define Z_IS_4034U_EQ_4034(...) \, +#define Z_IS_4034_EQ_4034U(...) \, +#define Z_IS_4034U_EQ_4034U(...) \, +#define Z_IS_4035_EQ_4035(...) \, +#define Z_IS_4035U_EQ_4035(...) \, +#define Z_IS_4035_EQ_4035U(...) \, +#define Z_IS_4035U_EQ_4035U(...) \, +#define Z_IS_4036_EQ_4036(...) \, +#define Z_IS_4036U_EQ_4036(...) \, +#define Z_IS_4036_EQ_4036U(...) \, +#define Z_IS_4036U_EQ_4036U(...) \, +#define Z_IS_4037_EQ_4037(...) \, +#define Z_IS_4037U_EQ_4037(...) \, +#define Z_IS_4037_EQ_4037U(...) \, +#define Z_IS_4037U_EQ_4037U(...) \, +#define Z_IS_4038_EQ_4038(...) \, +#define Z_IS_4038U_EQ_4038(...) \, +#define Z_IS_4038_EQ_4038U(...) \, +#define Z_IS_4038U_EQ_4038U(...) \, +#define Z_IS_4039_EQ_4039(...) \, +#define Z_IS_4039U_EQ_4039(...) \, +#define Z_IS_4039_EQ_4039U(...) \, +#define Z_IS_4039U_EQ_4039U(...) \, +#define Z_IS_4040_EQ_4040(...) \, +#define Z_IS_4040U_EQ_4040(...) \, +#define Z_IS_4040_EQ_4040U(...) \, +#define Z_IS_4040U_EQ_4040U(...) \, +#define Z_IS_4041_EQ_4041(...) \, +#define Z_IS_4041U_EQ_4041(...) \, +#define Z_IS_4041_EQ_4041U(...) \, +#define Z_IS_4041U_EQ_4041U(...) \, +#define Z_IS_4042_EQ_4042(...) \, +#define Z_IS_4042U_EQ_4042(...) \, +#define Z_IS_4042_EQ_4042U(...) \, +#define Z_IS_4042U_EQ_4042U(...) \, +#define Z_IS_4043_EQ_4043(...) \, +#define Z_IS_4043U_EQ_4043(...) \, +#define Z_IS_4043_EQ_4043U(...) \, +#define Z_IS_4043U_EQ_4043U(...) \, +#define Z_IS_4044_EQ_4044(...) \, +#define Z_IS_4044U_EQ_4044(...) \, +#define Z_IS_4044_EQ_4044U(...) \, +#define Z_IS_4044U_EQ_4044U(...) \, +#define Z_IS_4045_EQ_4045(...) \, +#define Z_IS_4045U_EQ_4045(...) \, +#define Z_IS_4045_EQ_4045U(...) \, +#define Z_IS_4045U_EQ_4045U(...) \, +#define Z_IS_4046_EQ_4046(...) \, +#define Z_IS_4046U_EQ_4046(...) \, +#define Z_IS_4046_EQ_4046U(...) \, +#define Z_IS_4046U_EQ_4046U(...) \, +#define Z_IS_4047_EQ_4047(...) \, +#define Z_IS_4047U_EQ_4047(...) \, +#define Z_IS_4047_EQ_4047U(...) \, +#define Z_IS_4047U_EQ_4047U(...) \, +#define Z_IS_4048_EQ_4048(...) \, +#define Z_IS_4048U_EQ_4048(...) \, +#define Z_IS_4048_EQ_4048U(...) \, +#define Z_IS_4048U_EQ_4048U(...) \, +#define Z_IS_4049_EQ_4049(...) \, +#define Z_IS_4049U_EQ_4049(...) \, +#define Z_IS_4049_EQ_4049U(...) \, +#define Z_IS_4049U_EQ_4049U(...) \, +#define Z_IS_4050_EQ_4050(...) \, +#define Z_IS_4050U_EQ_4050(...) \, +#define Z_IS_4050_EQ_4050U(...) \, +#define Z_IS_4050U_EQ_4050U(...) \, +#define Z_IS_4051_EQ_4051(...) \, +#define Z_IS_4051U_EQ_4051(...) \, +#define Z_IS_4051_EQ_4051U(...) \, +#define Z_IS_4051U_EQ_4051U(...) \, +#define Z_IS_4052_EQ_4052(...) \, +#define Z_IS_4052U_EQ_4052(...) \, +#define Z_IS_4052_EQ_4052U(...) \, +#define Z_IS_4052U_EQ_4052U(...) \, +#define Z_IS_4053_EQ_4053(...) \, +#define Z_IS_4053U_EQ_4053(...) \, +#define Z_IS_4053_EQ_4053U(...) \, +#define Z_IS_4053U_EQ_4053U(...) \, +#define Z_IS_4054_EQ_4054(...) \, +#define Z_IS_4054U_EQ_4054(...) \, +#define Z_IS_4054_EQ_4054U(...) \, +#define Z_IS_4054U_EQ_4054U(...) \, +#define Z_IS_4055_EQ_4055(...) \, +#define Z_IS_4055U_EQ_4055(...) \, +#define Z_IS_4055_EQ_4055U(...) \, +#define Z_IS_4055U_EQ_4055U(...) \, +#define Z_IS_4056_EQ_4056(...) \, +#define Z_IS_4056U_EQ_4056(...) \, +#define Z_IS_4056_EQ_4056U(...) \, +#define Z_IS_4056U_EQ_4056U(...) \, +#define Z_IS_4057_EQ_4057(...) \, +#define Z_IS_4057U_EQ_4057(...) \, +#define Z_IS_4057_EQ_4057U(...) \, +#define Z_IS_4057U_EQ_4057U(...) \, +#define Z_IS_4058_EQ_4058(...) \, +#define Z_IS_4058U_EQ_4058(...) \, +#define Z_IS_4058_EQ_4058U(...) \, +#define Z_IS_4058U_EQ_4058U(...) \, +#define Z_IS_4059_EQ_4059(...) \, +#define Z_IS_4059U_EQ_4059(...) \, +#define Z_IS_4059_EQ_4059U(...) \, +#define Z_IS_4059U_EQ_4059U(...) \, +#define Z_IS_4060_EQ_4060(...) \, +#define Z_IS_4060U_EQ_4060(...) \, +#define Z_IS_4060_EQ_4060U(...) \, +#define Z_IS_4060U_EQ_4060U(...) \, +#define Z_IS_4061_EQ_4061(...) \, +#define Z_IS_4061U_EQ_4061(...) \, +#define Z_IS_4061_EQ_4061U(...) \, +#define Z_IS_4061U_EQ_4061U(...) \, +#define Z_IS_4062_EQ_4062(...) \, +#define Z_IS_4062U_EQ_4062(...) \, +#define Z_IS_4062_EQ_4062U(...) \, +#define Z_IS_4062U_EQ_4062U(...) \, +#define Z_IS_4063_EQ_4063(...) \, +#define Z_IS_4063U_EQ_4063(...) \, +#define Z_IS_4063_EQ_4063U(...) \, +#define Z_IS_4063U_EQ_4063U(...) \, +#define Z_IS_4064_EQ_4064(...) \, +#define Z_IS_4064U_EQ_4064(...) \, +#define Z_IS_4064_EQ_4064U(...) \, +#define Z_IS_4064U_EQ_4064U(...) \, +#define Z_IS_4065_EQ_4065(...) \, +#define Z_IS_4065U_EQ_4065(...) \, +#define Z_IS_4065_EQ_4065U(...) \, +#define Z_IS_4065U_EQ_4065U(...) \, +#define Z_IS_4066_EQ_4066(...) \, +#define Z_IS_4066U_EQ_4066(...) \, +#define Z_IS_4066_EQ_4066U(...) \, +#define Z_IS_4066U_EQ_4066U(...) \, +#define Z_IS_4067_EQ_4067(...) \, +#define Z_IS_4067U_EQ_4067(...) \, +#define Z_IS_4067_EQ_4067U(...) \, +#define Z_IS_4067U_EQ_4067U(...) \, +#define Z_IS_4068_EQ_4068(...) \, +#define Z_IS_4068U_EQ_4068(...) \, +#define Z_IS_4068_EQ_4068U(...) \, +#define Z_IS_4068U_EQ_4068U(...) \, +#define Z_IS_4069_EQ_4069(...) \, +#define Z_IS_4069U_EQ_4069(...) \, +#define Z_IS_4069_EQ_4069U(...) \, +#define Z_IS_4069U_EQ_4069U(...) \, +#define Z_IS_4070_EQ_4070(...) \, +#define Z_IS_4070U_EQ_4070(...) \, +#define Z_IS_4070_EQ_4070U(...) \, +#define Z_IS_4070U_EQ_4070U(...) \, +#define Z_IS_4071_EQ_4071(...) \, +#define Z_IS_4071U_EQ_4071(...) \, +#define Z_IS_4071_EQ_4071U(...) \, +#define Z_IS_4071U_EQ_4071U(...) \, +#define Z_IS_4072_EQ_4072(...) \, +#define Z_IS_4072U_EQ_4072(...) \, +#define Z_IS_4072_EQ_4072U(...) \, +#define Z_IS_4072U_EQ_4072U(...) \, +#define Z_IS_4073_EQ_4073(...) \, +#define Z_IS_4073U_EQ_4073(...) \, +#define Z_IS_4073_EQ_4073U(...) \, +#define Z_IS_4073U_EQ_4073U(...) \, +#define Z_IS_4074_EQ_4074(...) \, +#define Z_IS_4074U_EQ_4074(...) \, +#define Z_IS_4074_EQ_4074U(...) \, +#define Z_IS_4074U_EQ_4074U(...) \, +#define Z_IS_4075_EQ_4075(...) \, +#define Z_IS_4075U_EQ_4075(...) \, +#define Z_IS_4075_EQ_4075U(...) \, +#define Z_IS_4075U_EQ_4075U(...) \, +#define Z_IS_4076_EQ_4076(...) \, +#define Z_IS_4076U_EQ_4076(...) \, +#define Z_IS_4076_EQ_4076U(...) \, +#define Z_IS_4076U_EQ_4076U(...) \, +#define Z_IS_4077_EQ_4077(...) \, +#define Z_IS_4077U_EQ_4077(...) \, +#define Z_IS_4077_EQ_4077U(...) \, +#define Z_IS_4077U_EQ_4077U(...) \, +#define Z_IS_4078_EQ_4078(...) \, +#define Z_IS_4078U_EQ_4078(...) \, +#define Z_IS_4078_EQ_4078U(...) \, +#define Z_IS_4078U_EQ_4078U(...) \, +#define Z_IS_4079_EQ_4079(...) \, +#define Z_IS_4079U_EQ_4079(...) \, +#define Z_IS_4079_EQ_4079U(...) \, +#define Z_IS_4079U_EQ_4079U(...) \, +#define Z_IS_4080_EQ_4080(...) \, +#define Z_IS_4080U_EQ_4080(...) \, +#define Z_IS_4080_EQ_4080U(...) \, +#define Z_IS_4080U_EQ_4080U(...) \, +#define Z_IS_4081_EQ_4081(...) \, +#define Z_IS_4081U_EQ_4081(...) \, +#define Z_IS_4081_EQ_4081U(...) \, +#define Z_IS_4081U_EQ_4081U(...) \, +#define Z_IS_4082_EQ_4082(...) \, +#define Z_IS_4082U_EQ_4082(...) \, +#define Z_IS_4082_EQ_4082U(...) \, +#define Z_IS_4082U_EQ_4082U(...) \, +#define Z_IS_4083_EQ_4083(...) \, +#define Z_IS_4083U_EQ_4083(...) \, +#define Z_IS_4083_EQ_4083U(...) \, +#define Z_IS_4083U_EQ_4083U(...) \, +#define Z_IS_4084_EQ_4084(...) \, +#define Z_IS_4084U_EQ_4084(...) \, +#define Z_IS_4084_EQ_4084U(...) \, +#define Z_IS_4084U_EQ_4084U(...) \, +#define Z_IS_4085_EQ_4085(...) \, +#define Z_IS_4085U_EQ_4085(...) \, +#define Z_IS_4085_EQ_4085U(...) \, +#define Z_IS_4085U_EQ_4085U(...) \, +#define Z_IS_4086_EQ_4086(...) \, +#define Z_IS_4086U_EQ_4086(...) \, +#define Z_IS_4086_EQ_4086U(...) \, +#define Z_IS_4086U_EQ_4086U(...) \, +#define Z_IS_4087_EQ_4087(...) \, +#define Z_IS_4087U_EQ_4087(...) \, +#define Z_IS_4087_EQ_4087U(...) \, +#define Z_IS_4087U_EQ_4087U(...) \, +#define Z_IS_4088_EQ_4088(...) \, +#define Z_IS_4088U_EQ_4088(...) \, +#define Z_IS_4088_EQ_4088U(...) \, +#define Z_IS_4088U_EQ_4088U(...) \, +#define Z_IS_4089_EQ_4089(...) \, +#define Z_IS_4089U_EQ_4089(...) \, +#define Z_IS_4089_EQ_4089U(...) \, +#define Z_IS_4089U_EQ_4089U(...) \, +#define Z_IS_4090_EQ_4090(...) \, +#define Z_IS_4090U_EQ_4090(...) \, +#define Z_IS_4090_EQ_4090U(...) \, +#define Z_IS_4090U_EQ_4090U(...) \, +#define Z_IS_4091_EQ_4091(...) \, +#define Z_IS_4091U_EQ_4091(...) \, +#define Z_IS_4091_EQ_4091U(...) \, +#define Z_IS_4091U_EQ_4091U(...) \, +#define Z_IS_4092_EQ_4092(...) \, +#define Z_IS_4092U_EQ_4092(...) \, +#define Z_IS_4092_EQ_4092U(...) \, +#define Z_IS_4092U_EQ_4092U(...) \, +#define Z_IS_4093_EQ_4093(...) \, +#define Z_IS_4093U_EQ_4093(...) \, +#define Z_IS_4093_EQ_4093U(...) \, +#define Z_IS_4093U_EQ_4093U(...) \, +#define Z_IS_4094_EQ_4094(...) \, +#define Z_IS_4094U_EQ_4094(...) \, +#define Z_IS_4094_EQ_4094U(...) \, +#define Z_IS_4094U_EQ_4094U(...) \, +#define Z_IS_4095_EQ_4095(...) \, +#define Z_IS_4095U_EQ_4095(...) \, +#define Z_IS_4095_EQ_4095U(...) \, +#define Z_IS_4095U_EQ_4095U(...) \, +#define Z_IS_4096_EQ_4096(...) \, +#define Z_IS_4096U_EQ_4096(...) \, +#define Z_IS_4096_EQ_4096U(...) \, +#define Z_IS_4096U_EQ_4096U(...) \, #endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_ */ diff --git a/include/zephyr/sys/util_macro.h b/include/zephyr/sys/util_macro.h index 87c5caad56908..c8901e21454ae 100644 --- a/include/zephyr/sys/util_macro.h +++ b/include/zephyr/sys/util_macro.h @@ -93,6 +93,14 @@ extern "C" { */ #define IS_BIT_MASK(m) IS_SHIFTED_BIT_MASK(m, 0) +/** + * @brief Check if bit is set in a value + * + * @param value Value that contain checked bit + * @param bit Bit number + */ +#define IS_BIT_SET(value, bit) ((((value) >> (bit)) & (0x1)) != 0) + /** @brief Extract the Least Significant Bit from @p value. */ #define LSB_GET(value) ((value) & -(value)) @@ -296,7 +304,19 @@ extern "C" { * @brief Like a == b, but does evaluation and * short-circuiting at C preprocessor time. * - * This however only works for integer literal from 0 to 4095. + * This however only works for integer literal from 0 to 4096 (literals with U suffix, + * e.g. 0U are also included). + * + * Examples: + * + * IS_EQ(1, 1) -> 1 + * IS_EQ(1U, 1U) -> 1 + * IS_EQ(1U, 1) -> 1 + * IS_EQ(1, 1U) -> 1 + * IS_EQ(1, 0) -> 0 + * + * @param a Integer literal (can be with U suffix) + * @param b Integer literal * */ #define IS_EQ(a, b) Z_IS_EQ(a, b) diff --git a/include/zephyr/sys_clock.h b/include/zephyr/sys_clock.h index 36abcff9f874c..105d91a1545af 100644 --- a/include/zephyr/sys_clock.h +++ b/include/zephyr/sys_clock.h @@ -115,12 +115,14 @@ typedef struct { /** @} */ /** @cond INTERNAL_HIDDEN */ -#define Z_TIMEOUT_NO_WAIT ((k_timeout_t) {0}) +#define Z_TIMEOUT_NO_WAIT_INIT {0} +#define Z_TIMEOUT_NO_WAIT ((k_timeout_t) Z_TIMEOUT_NO_WAIT_INIT) #if defined(__cplusplus) && ((__cplusplus - 0) < 202002L) -#define Z_TIMEOUT_TICKS(t) ((k_timeout_t) { (t) }) +#define Z_TIMEOUT_TICKS_INIT(t) { (t) } #else -#define Z_TIMEOUT_TICKS(t) ((k_timeout_t) { .ticks = (t) }) +#define Z_TIMEOUT_TICKS_INIT(t) { .ticks = (t) } #endif +#define Z_TIMEOUT_TICKS(t) ((k_timeout_t) Z_TIMEOUT_TICKS_INIT(t)) #define Z_FOREVER Z_TIMEOUT_TICKS(K_TICKS_FOREVER) #ifdef CONFIG_TIMEOUT_64BIT diff --git a/include/zephyr/toolchain.h b/include/zephyr/toolchain.h index f8df4915736c6..93ace9520f8a1 100644 --- a/include/zephyr/toolchain.h +++ b/include/zephyr/toolchain.h @@ -44,6 +44,8 @@ #include #elif defined(__ARMCOMPILER_VERSION) #include +#elif defined(__IAR_SYSTEMS_ICC__) +#include #elif defined(__llvm__) || (defined(_LINKER) && defined(__LLD_LINKER_CMD__)) #include #elif defined(__GNUC__) || (defined(_LINKER) && defined(__GCC_LINKER_CMD__)) @@ -145,6 +147,70 @@ #define TOOLCHAIN_IGNORE_WSHADOW_END #endif +/** + * @def TOOLCHAIN_PRAGMA + * @brief Helper for using pragma in macros. + */ +#ifdef TOOLCHAIN_HAS_PRAGMA_DIAG +#define TOOLCHAIN_PRAGMA(x) _Pragma(#x) +#else +#define TOOLCHAIN_PRAGMA(x) +#endif + +/** + * @def TOOLCHAIN_DISABLE_WARNING + * @brief Disable the specified compiler warning for all compilers. + */ +#ifndef TOOLCHAIN_DISABLE_WARNING +#define TOOLCHAIN_DISABLE_WARNING(warning) +#endif + +/** + * @def TOOLCHAIN_ENABLE_WARNING + * @brief Re-enable the specified compiler warning for all compilers. + * + * Can only be used after a call to @ref TOOLCHAIN_DISABLE_WARNING. + */ +#ifndef TOOLCHAIN_ENABLE_WARNING +#define TOOLCHAIN_ENABLE_WARNING(warning) +#endif + +/** + * @def TOOLCHAIN_DISABLE_CLANG_WARNING + * @brief Disable the specified compiler warning for clang. + */ +#ifndef TOOLCHAIN_DISABLE_CLANG_WARNING +#define TOOLCHAIN_DISABLE_CLANG_WARNING(warning) +#endif + +/** + * @def TOOLCHAIN_ENABLE_CLANG_WARNING + * @brief Re-enable the specified compiler warning for clang. + * + * Can only be used after a call to @ref TOOLCHAIN_DISABLE_CLANG_WARNING. + */ +#ifndef TOOLCHAIN_ENABLE_CLANG_WARNING +#define TOOLCHAIN_ENABLE_CLANG_WARNING(warning) +#endif + +/** + * @def TOOLCHAIN_DISABLE_GCC_WARNING + * @brief Disable the specified compiler warning for gcc. + */ +#ifndef TOOLCHAIN_DISABLE_GCC_WARNING +#define TOOLCHAIN_DISABLE_GCC_WARNING(warning) +#endif + +/** + * @def TOOLCHAIN_ENABLE_GCC_WARNING + * @brief Re-enable the specified compiler warning for gcc. + * + * Can only be used after a call to @ref TOOLCHAIN_DISABLE_GCC_WARNING. + */ +#ifndef TOOLCHAIN_ENABLE_GCC_WARNING +#define TOOLCHAIN_ENABLE_GCC_WARNING(warning) +#endif + /* * Ensure that __BYTE_ORDER__ and related preprocessor definitions are defined, * and that they match the Kconfig option that is used in the code itself to diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index bb55d50a858fc..e003cd2c26f74 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -103,6 +103,10 @@ #define FUNC_ALIAS(real_func, new_alias, return_type) \ return_type new_alias() ALIAS_OF(real_func) +#if TOOLCHAIN_GCC_VERSION < 40500 +#define __builtin_unreachable() __builtin_trap() +#endif + #if defined(CONFIG_ARCH_POSIX) && !defined(_ASMLANGUAGE) #include @@ -683,4 +687,19 @@ do { \ _Pragma("GCC diagnostic pop") #endif /* !_LINKER */ + +#define _TOOLCHAIN_DISABLE_WARNING(compiler, warning) \ + TOOLCHAIN_PRAGMA(compiler diagnostic push) \ + TOOLCHAIN_PRAGMA(compiler diagnostic ignored warning) + +#define _TOOLCHAIN_ENABLE_WARNING(compiler, warning) TOOLCHAIN_PRAGMA(compiler diagnostic pop) + +#define TOOLCHAIN_DISABLE_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(GCC, warning) +#define TOOLCHAIN_ENABLE_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(GCC, warning) + +#if defined(__GNUC__) && !defined(__clang__) +#define TOOLCHAIN_DISABLE_GCC_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(GCC, warning) +#define TOOLCHAIN_ENABLE_GCC_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(GCC, warning) +#endif + #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_GCC_H_ */ diff --git a/include/zephyr/toolchain/iar.h b/include/zephyr/toolchain/iar.h new file mode 100644 index 0000000000000..76738c528fe2d --- /dev/null +++ b/include/zephyr/toolchain/iar.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_IAR_H_ +#define ZEPHYR_INCLUDE_TOOLCHAIN_IAR_H_ + +#ifdef TOOLCHAIN_PRAGMA +#define _TOOLCHAIN_DISABLE_WARNING(warning) TOOLCHAIN_PRAGMA(diag_suppress = warning) +#define _TOOLCHAIN_ENABLE_WARNING(warning) TOOLCHAIN_PRAGMA(diag_default = warning) + +#define TOOLCHAIN_DISABLE_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(warning) +#define TOOLCHAIN_ENABLE_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(warning) +#endif + +#ifdef __ICCARM__ +#include "iar/iccarm.h" +#endif +#ifdef __ICCRISCV__ +#include "iar/iccriscv.h" +#endif + +#endif /* ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_ */ diff --git a/include/zephyr/toolchain/iar/iar_missing_defs.h b/include/zephyr/toolchain/iar/iar_missing_defs.h new file mode 100644 index 0000000000000..44541adaccd53 --- /dev/null +++ b/include/zephyr/toolchain/iar/iar_missing_defs.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Basic macro definitions that gcc and clang provide on their own + * but that iccarm lacks. Only those that Zephyr requires are provided here. + */ + +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_MISSING_DEFS_H_ +#define ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_MISSING_DEFS_H_ + + /* We need to define NULL with a parenthesis around _NULL + * otherwise the DEBRACE macros won't work correctly + */ + +#undef NULL +#define NULL (_NULL) + +#if defined(__IAR_SYSTEMS_ICC__) +#ifndef __CHAR_BIT__ +#define __CHAR_BIT__ __CHAR_BITS__ +#endif +#define __SCHAR_MAX__ __SIGNED_CHAR_MAX__ + +#define __INT_MAX__ __SIGNED_INT_MAX__ +#define __INT_WIDTH__ (__INT_SIZE__*8) +#define __SIZEOF_INT__ __INT_SIZE__ + +#define __SHRT_MAX__ __SIGNED_SHORT_MAX__ +#define __SHRT_WIDTH__ (__SHORT_SIZE__*8) +#define __SIZEOF_SHORT__ __SHORT_SIZE__ + +#define __LONG_MAX__ __SIGNED_LONG_MAX__ +#define __LONG_WIDTH__ (__LONG_SIZE__*8) +#define __SIZEOF_LONG__ __LONG_SIZE__ + +#define __LONG_LONG_MAX__ __SIGNED_LONG_LONG_MAX__ +#define __LONG_LONG_WIDTH__ (__LONG_LONG_SIZE__*8) +#define __SIZEOF_LONG_LONG__ __LONG_LONG_SIZE__ + +#define __INTMAX_MAX__ __INTMAX_T_MAX__ +#define __SIZEOF_INTMAX__ sizeof(__INTMAX_T_TYPE__) +#define __INTMAX_WIDTH__ (__SIZEOF_INTMAX__*8) +#define __UINTMAX_MAX__ __UINTMAX_T_MAX__ +#define __SIZEOF_UINTMAX__ sizeof(__UINTMAX_T_TYPE__) +#define __UINTMAX_WIDTH__ (__SIZEOF_UINTMAX__*8) + +#define __INTPTR_MAX__ __INTPTR_T_MAX__ +#define __INTPTR_TYPE__ __INTPTR_T_TYPE__ +#define __INTPTR_WIDTH__ (__INTPTR_T_SIZE__*8) +#define __SIZEOF_POINTER__ __INTPTR_T_SIZE__ + +#define __PTRDIFF_MAX__ __PTRDIFF_T_MAX__ +#define __PTRDIFF_WIDTH__ (__PTRDIFF_T_SIZE__*8) +#define __SIZEOF_PTRDIFF_T__ __PTRDIFF_T_SIZE__ + +#define __UINTPTR_MAX__ __UINTPTR_T_MAX__ +#define __UINTPTR_TYPE__ __UINTPTR_T_TYPE__ + +/* + * ICCARM already defines __SIZE_T_MAX__ as "unsigned int" but there is no way + * to safeguard that here with preprocessor equality. + */ + +#define __SIZE_TYPE__ __SIZE_T_TYPE__ +#define __SIZE_MAX__ __SIZE_T_MAX__ +#define __SIZE_WIDTH__ ((__SIZEOF_SIZE_T__)*8) +/* #define __SIZEOF_SIZE_T__ 4 */ + +/* + * The following defines are inferred from the ICCARM provided defines + * already tested above. + */ + + +#define __INT8_MAX__ __INT8_T_MAX__ +#define __INT8_TYPE__ __INT8_T_TYPE__ + +#define __UINT8_MAX__ __UINT8_T_MAX__ +#define __UINT8_TYPE__ __UINT8_T_TYPE__ + +#define __INT16_MAX__ __INT16_T_MAX__ +#define __INT16_TYPE__ __INT16_T_TYPE__ + +#define __UINT16_MAX__ __UINT16_T_MAX__ +#define __UINT16_TYPE__ __UINT16_T_TYPE__ + +#define __INT32_MAX__ __INT32_T_MAX__ +#define __INT32_TYPE__ __INT32_T_TYPE__ + +#define __UINT32_MAX__ __UINT32_T_MAX__ +#define __UINT32_TYPE__ __UINT32_T_TYPE__ + +#define __INT64_MAX__ __INT64_T_MAX__ +#define __INT64_TYPE__ __INT64_T_TYPE__ + +#define __UINT64_MAX__ __UINT64_T_MAX__ +#define __UINT64_TYPE__ __UINT64_T_TYPE__ + +#define __INT_FAST8_MAX__ __INT_FAST8_T_MAX__ +#define __INT_FAST8_TYPE__ __INT_FAST8_T_TYPE__ +#define __INT_FAST8_WIDTH__ (__INT_FAST8_T_SIZE__*8) + +#define __INT_FAST16_MAX__ __INT_FAST16_T_MAX__ +#define __INT_FAST16_TYPE__ __INT_FAST16_T_TYPE__ +#define __INT_FAST16_WIDTH__ (__INT_FAST16_T_SIZE__*8) + +#define __INT_FAST32_MAX__ __INT_FAST32_T_MAX__ +#define __INT_FAST32_TYPE__ __INT_FAST32_T_TYPE__ +#define __INT_FAST32_WIDTH__ (__INT_FAST32_T_SIZE__*8) + +#define __INT_FAST64_MAX__ __INT_FAST64_T_MAX__ +#define __INT_FAST64_TYPE__ __INT_FAST64_T_TYPE__ +#define __INT_FAST64_WIDTH__ (__INT_FAST64_T_SIZE__*8) + +#define __INT_LEAST8_MAX__ __INT_LEAST8_T_MAX__ +#define __INT_LEAST8_TYPE__ __INT_LEAST8_T_TYPE__ +#define __INT_LEAST8_WIDTH__ (__INT_LEAST8_T_SIZE__*8) + +#define __INT_LEAST16_MAX__ __INT_LEAST16_T_MAX__ +#define __INT_LEAST16_TYPE__ __INT_LEAST16_T_TYPE__ +#define __INT_LEAST16_WIDTH__ (__INT_LEAST16_T_SIZE__*8) + +#define __INT_LEAST32_MAX__ __INT_LEAST32_T_MAX__ +#define __INT_LEAST32_TYPE__ __INT_LEAST32_T_TYPE__ +#define __INT_LEAST32_WIDTH__ (__INT_LEAST32_T_SIZE__*8) + +#define __INT_LEAST64_MAX__ __INT_LEAST64_T_MAX__ +#define __INT_LEAST64_TYPE__ __INT_LEAST64_T_TYPE__ +#define __INT_LEAST64_WIDTH__ (__INT_LEAST64_T_SIZE__*8) + +#define __UINT_FAST8_MAX__ __UINT_FAST8_T_MAX__ +#define __UINT_FAST8_TYPE__ __UINT_FAST8_T_TYPE__ + +#define __UINT_FAST16_MAX__ __UINT_FAST16_T_MAX__ +#define __UINT_FAST16_TYPE__ __UINT_FAST16_T_TYPE__ + +#define __UINT_FAST32_MAX__ __UINT_FAST32_T_MAX__ +#define __UINT_FAST32_TYPE__ __UINT_FAST32_T_TYPE__ + +#define __UINT_FAST64_MAX__ __UINT_FAST64_T_MAX__ +#define __UINT_FAST64_TYPE__ __UINT_FAST64_T_TYPE__ + +#define __UINT_LEAST8_MAX__ __UINT_LEAST8_T_MAX__ +#define __UINT_LEAST8_TYPE__ __UINT_LEAST8_T_TYPE__ + +#define __UINT_LEAST16_MAX__ __UINT_LEAST16_T_MAX__ +#define __UINT_LEAST16_TYPE__ __UINT_LEAST16_T_TYPE__ + +#define __UINT_LEAST32_MAX__ __UINT_LEAST32_T_MAX__ +#define __UINT_LEAST32_TYPE__ __UINT_LEAST32_T_TYPE__ + +#define __UINT_LEAST64_MAX__ __UINT_LEAST64_T_MAX__ +#define __UINT_LEAST64_TYPE__ __UINT_LEAST64_T_TYPE__ + +#endif /* __IAR_SYSTEMS_ICC__ */ + +#endif diff --git a/include/zephyr/toolchain/iar/iccarm.h b/include/zephyr/toolchain/iar/iccarm.h new file mode 100644 index 0000000000000..cc79102332979 --- /dev/null +++ b/include/zephyr/toolchain/iar/iccarm.h @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_ +#define ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_ + +/** + * @file + * @brief ICCARM toolchain abstraction + * + * Macros to abstract compiler capabilities for ICCARM toolchain. + */ + +/* ICCARM supports its own #pragma diag_{warning,default,error,warning}. */ +/* #define TOOLCHAIN_HAS_PRAGMA_DIAG 0 */ + +#define TOOLCHAIN_HAS_C_GENERIC 1 + +#define TOOLCHAIN_HAS_C_AUTO_TYPE 1 + +/* #define TOOLCHAIN_HAS_ZLA 1 */ + +/* + * IAR do not define __BYTE_ORDER__, so it must be manually + * detected and defined using arch-specific definitions. + */ + +#ifndef _LINKER + +#ifndef __ORDER_BIG_ENDIAN__ +#define __ORDER_BIG_ENDIAN__ (1) +#endif /* __ORDER_BIG_ENDIAN__ */ + +#ifndef __ORDER_LITTLE_ENDIAN__ +#define __ORDER_LITTLE_ENDIAN__ (2) +#endif /* __ORDER_LITTLE_ENDIAN__ */ + +#ifndef __ORDER_PDP_ENDIAN__ +#define __ORDER_PDP_ENDIAN__ (3) +#endif /* __ORDER_PDP_ENDIAN__ */ + +#ifndef __BYTE_ORDER__ + +#if __LITTLE_ENDIAN__ == 1 +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#else +#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ +#endif /* __LITTLE_ENDIAN__ == 1 */ + +#endif /* __BYTE_ORDER__ */ + + +#if defined(__cplusplus) && (__cplusplus >= 201103L) +#define BUILD_ASSERT(EXPR, MSG...) static_assert(EXPR, "" MSG) +#elif defined(__ICCARM__) +#define BUILD_ASSERT(EXPR, MSG...) _Static_assert(EXPR, "" MSG) +#endif + +/* Zephyr makes use of __ATOMIC_SEQ_CST */ +#ifdef __STDC_NO_ATOMICS__ +#ifndef __ATOMIC_SEQ_CST +#define __MEMORY_ORDER_SEQ_CST__ 5 +#endif +#endif +#ifndef __ATOMIC_SEQ_CST +#define __ATOMIC_SEQ_CST __MEMORY_ORDER_SEQ_CST__ +#endif + +/* By default, restrict is recognized in Standard C + * __restrict is always recognized + */ +#define ZRESTRICT __restrict + +#include +#include + +#define ALIAS_OF(of) __attribute__((alias(#of))) + +#define FUNC_ALIAS(real_func, new_alias, return_type) \ + return_type new_alias() ALIAS_OF(real_func) + +#define CODE_UNREACHABLE __builtin_unreachable() +#define FUNC_NORETURN __attribute__((__noreturn__)) + +#define _NODATA_SECTION(segment) __attribute__((section(#segment))) + +/* Unaligned access */ +#define UNALIGNED_GET(p) \ +__extension__ ({ \ + struct __attribute__((__packed__)) { \ + __typeof__(*(p)) __v; \ + } *__p = (__typeof__(__p)) (p); \ + __p->__v; \ +}) + +#define UNALIGNED_PUT(v, p) \ +do { \ + struct __attribute__((__packed__)) { \ + __typeof__(*p) __v; \ + } *__p = (__typeof__(__p)) (p); \ + __p->__v = (v); \ +} while (false) + + +/* Double indirection to ensure section names are expanded before + * stringification + */ +#define __GENERIC_SECTION(segment) __attribute__((section(STRINGIFY(segment)))) +#define Z_GENERIC_SECTION(segment) __GENERIC_SECTION(segment) + +#define __GENERIC_DOT_SECTION(segment) \ + __attribute__((section("." STRINGIFY(segment)))) +#define Z_GENERIC_DOT_SECTION(segment) __GENERIC_DOT_SECTION(segment) + +#define ___in_section(a, b, c) \ + __attribute__((section("." Z_STRINGIFY(a) \ + "." Z_STRINGIFY(b) \ + "." Z_STRINGIFY(c)))) +#define __in_section(a, b, c) ___in_section(a, b, c) + +#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__) + +#define __in_section_unique_named(seg, name) \ + ___in_section(seg, __FILE__, name) + +/* When using XIP, using '__ramfunc' places a function into RAM instead + * of FLASH. Make sure '__ramfunc' is defined only when + * CONFIG_ARCH_HAS_RAMFUNC_SUPPORT is defined, so that the compiler can + * report an error if '__ramfunc' is used but the architecture does not + * support it. + */ +#if !defined(CONFIG_XIP) +#define __ramfunc +#elif defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) +/* Use this instead of the IAR keyword __ramfunc to make sure it + * ends up in the correct section. + */ +#define __ramfunc __attribute__((noinline, section(".ramfunc"))) +#endif /* !CONFIG_XIP */ + +/* TG-WG: ICCARM does not support __fallthrough */ +#define __fallthrough [[fallthrough]] + +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif + +#ifndef __noinline +#define __noinline __attribute__((noinline)) +#endif + +#if defined(__cplusplus) +#define __alignof(x) alignof(x) +#else +#define __alignof(x) _Alignof(x) +#endif + +#define __may_alias __attribute__((__may_alias__)) + +#ifndef __printf_like +/* + * The Zephyr stdint convention enforces int32_t = int, int64_t = long long, + * and intptr_t = long so that short string format length modifiers can be + * used universally across ILP32 and LP64 architectures. Without that it + * is possible for ILP32 toolchains to have int32_t = long and intptr_t = int + * clashing with the Zephyr convention and generating pointless warnings + * as they're still the same size. Inhibit the format argument type + * validation in that case and let the other configs do it. + */ +#define __printf_like(f, a) +#endif + +#define __used __attribute__((__used__)) +#define __unused __attribute__((__unused__)) +#define __maybe_unused __attribute__((__unused__)) + +#ifndef __deprecated +#define __deprecated __attribute__((deprecated)) +#endif + +#define FUNC_NO_STACK_PROTECTOR _Pragma("no_stack_protect") + +#ifndef __attribute_const__ +#if __VER__ > 0x09000000 +#define __attribute_const__ __attribute__((const)) +#else +#define __attribute_const__ +#endif +#endif + +#ifndef __must_check +/* #warning "The attribute __warn_unused_result is not supported in ICCARM". */ +#define __must_check +/* #define __must_check __attribute__((warn_unused_result)) */ +#endif + +#define __PRAGMA(...) _Pragma(#__VA_ARGS__) +#define ARG_UNUSED(x) (void)(x) + +#define likely(x) (__builtin_expect((bool)!!(x), true) != 0L) +#define unlikely(x) (__builtin_expect((bool)!!(x), false) != 0L) +#define POPCOUNT(x) __builtin_popcount(x) + +#ifndef __no_optimization +#define __no_optimization __PRAGMA(optimize = none) +#endif + +#ifndef __attribute_nonnull + #define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) +#endif + +/* __weak is an ICCARM built-in, but it doesn't work in all positions */ +/* the Zephyr uses it so we replace it with an attribute((weak)) */ +#define __weak __attribute__((__weak__)) + +/* Builtins */ + +#include + +/* + * Be *very* careful with these. You cannot filter out __DEPRECATED_MACRO with + * -wno-deprecated, which has implications for -Werror. + */ + + +/* + * Expands to nothing and generates a warning. Used like + * + * #define FOO __WARN("Please use BAR instead") ... + * + * The warning points to the location where the macro is expanded. + */ +#define __WARN(s) __PRAGMA(message = #s) +#define __WARN1(s) __PRAGMA(message = #s) + +/* Generic message */ +#ifndef __DEPRECATED_MACRO +#define __DEPRECATED_MACRO __WARN("Macro is deprecated") +#endif + +/* These macros allow having ARM asm functions callable from thumb */ + +#if defined(_ASMLANGUAGE) + +#if defined(CONFIG_ASSEMBLER_ISA_THUMB2) +#define FUNC_CODE() .code 32 +#define FUNC_INSTR(a) +/* '.syntax unified' is a gcc-ism used in thumb-2 asm files */ +#define _ASM_FILE_PROLOGUE .text; .syntax unified; .thumb +#else +#define FUNC_CODE() +#define FUNC_INSTR(a) +#define _ASM_FILE_PROLOGUE .text; .code 32 +#endif /* CONFIG_ASSEMBLER_ISA_THUMB2 */ + +/* + * These macros are used to declare assembly language symbols that need + * to be typed properly(func or data) to be visible to the OMF tool. + * So that the build tool could mark them as an entry point to be linked + * correctly. This is an elfism. Use #if 0 for a.out. + */ + +/* This is not implemented yet for IAR */ +#define GTEXT(sym) +#define GDATA(sym) +#define WTEXT(sym) +#define WDATA(sym) + +#define SECTION_VAR(sect, sym) +#define SECTION_FUNC(sect, sym) +#define SECTION_SUBSEC_FUNC(sect, subsec, sym) + +#endif /* _ASMLANGUAGE */ + + +/* + * These macros generate absolute symbols for IAR + */ + +/* create an extern reference to the absolute symbol */ + +#define GEN_OFFSET_EXTERN(name) extern const char name[] + +#define GEN_ABS_SYM_BEGIN(name) \ + EXTERN_C void name(void); \ + void name(void) \ + { + +#define GEN_ABS_SYM_END } + +/* + * Note that GEN_ABSOLUTE_SYM(), depending on the architecture + * and toolchain, may restrict the range of values permitted + * for assignment to the named symbol. + */ +#define GEN_ABSOLUTE_SYM(name, value) \ + __PRAGMA(public_equ = #name, (unsigned int)value) + +/* + * GEN_ABSOLUTE_SYM_KCONFIG() is outputted by the build system + * to generate named symbol/value pairs for kconfigs. + */ +#define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ + __PRAGMA(public_equ = #name, (unsigned int)value) + +#define compiler_barrier() do { \ + __asm volatile("" ::: "memory"); \ +} while (false) + +/** @brief Return larger value of two provided expressions. + * + * Macro ensures that expressions are evaluated only once. + * + * @note Macro has limited usage compared to the standard macro as it cannot be + * used: + * - to generate constant integer, e.g. __aligned(Z_MAX(4,5)) + * - static variable, e.g. array like static uint8_t array[Z_MAX(...)]; + */ +#define Z_MAX(a, b) ({ \ + /* random suffix to avoid naming conflict */ \ + __typeof__(a) _value_a_ = (a); \ + __typeof__(b) _value_b_ = (b); \ + _value_a_ > _value_b_ ? _value_a_ : _value_b_; \ + }) + +/** @brief Return smaller value of two provided expressions. + * + * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for + * macro limitations. + */ +#define Z_MIN(a, b) ({ \ + /* random suffix to avoid naming conflict */ \ + __typeof__(a) _value_a_ = (a); \ + __typeof__(b) _value_b_ = (b); \ + _value_a_ < _value_b_ ? _value_a_ : _value_b_; \ + }) + +/** @brief Return a value clamped to a given range. + * + * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for + * macro limitations. + */ +#define Z_CLAMP(val, low, high) ({ \ + /* random suffix to avoid naming conflict */ \ + __typeof__(val) _value_val_ = (val); \ + __typeof__(low) _value_low_ = (low); \ + __typeof__(high) _value_high_ = (high); \ + (_value_val_ < _value_low_) ? _value_low_ : \ + (_value_val_ > _value_high_) ? _value_high_ : \ + _value_val_; \ + }) + +/** + * @brief Calculate power of two ceiling for some nonzero value + * + * @param x Nonzero unsigned long value + * @return X rounded up to the next power of two + */ +#define Z_POW2_CEIL(x) \ + ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) - 1)))) + +/** + * @brief Check whether or not a value is a power of 2 + * + * @param x The value to check + * @return true if x is a power of 2, false otherwise + */ +#define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x)-1)) == 0)) + +#ifndef __INT8_C +#define __INT8_C(x) x +#endif + +#ifndef INT8_C +#define INT8_C(x) __INT8_C(x) +#endif + +#ifndef __UINT8_C +#define __UINT8_C(x) x ## U +#endif + +#ifndef UINT8_C +#define UINT8_C(x) __UINT8_C(x) +#endif + +#ifndef __INT16_C +#define __INT16_C(x) x +#endif + +#ifndef INT16_C +#define INT16_C(x) __INT16_C(x) +#endif + +#ifndef __UINT16_C +#define __UINT16_C(x) x ## U +#endif + +#ifndef UINT16_C +#define UINT16_C(x) __UINT16_C(x) +#endif + +#ifndef __INT32_C +#define __INT32_C(x) x +#endif + +#ifndef INT32_C +#define INT32_C(x) __INT32_C(x) +#endif + +#ifndef __UINT32_C +#define __UINT32_C(x) x ## U +#endif + +#ifndef UINT32_C +#define UINT32_C(x) __UINT32_C(x) +#endif + +#ifndef __INT64_C +#define __INT64_C(x) x ## LL +#endif + +#ifndef INT64_C +#define INT64_C(x) __INT64_C(x) +#endif + +#ifndef __UINT64_C +#define __UINT64_C(x) x ## ULL +#endif + +#ifndef UINT64_C +#define UINT64_C(x) __UINT64_C(x) +#endif + +/* Convenience macros */ +#undef _GLUE_B +#undef _GLUE +#define _GLUE_B(x, y) x##y +#define _GLUE(x, y) _GLUE_B(x, y) + +#ifndef INTMAX_C +#define INTMAX_C(x) _GLUE(x, __INTMAX_C_SUFFIX__) +#endif + +#ifndef UINTMAX_C +#define UINTMAX_C(x) _GLUE(x, __UINTMAX_C_SUFFIX__) +#endif + +#endif /* !_LINKER */ +#endif /* ZEPHYR_INCLUDE_TOOLCHAIN_ICCARM_H_ */ diff --git a/include/zephyr/toolchain/llvm.h b/include/zephyr/toolchain/llvm.h index a895680730517..7eea8347c6cd8 100644 --- a/include/zephyr/toolchain/llvm.h +++ b/include/zephyr/toolchain/llvm.h @@ -30,6 +30,9 @@ #include +#define TOOLCHAIN_DISABLE_CLANG_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(clang, warning) +#define TOOLCHAIN_ENABLE_CLANG_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(clang, warning) + /* * Provide these definitions only when minimal libc is used. * Avoid collision with defines from include/zephyr/toolchain/zephyr_stdint.h diff --git a/include/zephyr/toolchain/zephyr_stdint.h b/include/zephyr/toolchain/zephyr_stdint.h index f9a44e4a25f6e..3cd4defbf6f9e 100644 --- a/include/zephyr/toolchain/zephyr_stdint.h +++ b/include/zephyr/toolchain/zephyr_stdint.h @@ -16,6 +16,33 @@ * common expectations and usage. */ +/* + * If the compiler does not define __SIZEOF_INT__ deduce it from __INT_MAX__ + * or INT_MAX. + */ +#if !defined(__SIZEOF_INT__) + +#if defined(__INT_MAX__) +/* GCC >= 3.3.0 has ____ implicitly defined. */ +#define __Z_INT_MAX __INT_MAX__ +#else +/* Fall back to POSIX versions from */ +#define __Z_INT_MAX INT_MAX +#include +#endif + +#if __Z_INT_MAX == 0x7fff +#define __SIZEOF_INT__ 2 +#elif __Z_INT_MAX == 0x7fffffffL +#define __SIZEOF_INT__ 4 +#elif __Z_INT_MAX > 0x7fffffffL +#define __SIZEOF_INT__ 8 +#endif + +#undef __Z_INT_MAX + +#endif + #if __SIZEOF_INT__ != 4 #error "unexpected int width" #endif diff --git a/include/zephyr/tracing/tracing.h b/include/zephyr/tracing/tracing.h index 13cefa7f15191..eecdcddc61f86 100644 --- a/include/zephyr/tracing/tracing.h +++ b/include/zephyr/tracing/tracing.h @@ -427,6 +427,28 @@ */ #define sys_port_trace_k_work_queue_start_exit(queue) +/** + * @brief Trace stop of a Work Queue call entry + * @param queue Work Queue structure + * @param timeout Timeout period + */ +#define sys_port_trace_k_work_queue_stop_enter(queue, timeout) + +/** + * @brief Trace stop of a Work Queue call blocking + * @param queue Work Queue structure + * @param timeout Timeout period + */ +#define sys_port_trace_k_work_queue_stop_blocking(queue, timeout) + +/** + * @brief Trace stop of a Work Queue call exit + * @param queue Work Queue structure + * @param timeout Timeout period + * @param ret Return value + */ +#define sys_port_trace_k_work_queue_stop_exit(queue, timeout, ret) + /** * @brief Trace Work Queue drain call entry * @param queue Work Queue structure @@ -1536,8 +1558,80 @@ /** * @brief Trace initialization of Pipe * @param pipe Pipe object + * @param buffer data buffer + * @param size data buffer size + */ +#define sys_port_trace_k_pipe_init(pipe, buffer, size) + +/** + * @brief Trace Pipe reset entry + * @param pipe Pipe object + */ +#define sys_port_trace_k_pipe_reset_enter(pipe) + +/** + * @brief Trace Pipe reset exit + * @param pipe Pipe object + */ +#define sys_port_trace_k_pipe_reset_exit(pipe) + +/** + * @brief Trace Pipe close entry + * @param pipe Pipe object + */ +#define sys_port_trace_k_pipe_close_enter(pipe) + +/** + * @brief Trace Pipe close exit + * @param pipe Pipe object + */ +#define sys_port_trace_k_pipe_close_exit(pipe) + +/** + * @brief Trace Pipe write attempt entry + * @param pipe Pipe object + * @param data pointer to data + * @param len length of data + * @param timeout Timeout period */ -#define sys_port_trace_k_pipe_init(pipe) +#define sys_port_trace_k_pipe_write_enter(pipe, data, len, timeout) + +/** + * @brief Trace Pipe write attempt blocking + * @param pipe Pipe object + * @param timeout Timeout period + */ +#define sys_port_trace_k_pipe_write_blocking(pipe, timeout) + +/** + * @brief Trace Pipe write attempt outcome + * @param pipe Pipe object + * @param ret Return value + */ +#define sys_port_trace_k_pipe_write_exit(pipe, ret) + +/** + * @brief Trace Pipe read attempt entry + * @param pipe Pipe object + * @param data Pointer to data + * @param len Length of data + * @param timeout Timeout period + */ +#define sys_port_trace_k_pipe_read_enter(pipe, data, len, timeout) + +/** + * @brief Trace Pipe read attempt blocking + * @param pipe Pipe object + * @param timeout Timeout period + */ +#define sys_port_trace_k_pipe_read_blocking(pipe, timeout) + +/** + * @brief Trace Pipe read attempt outcome + * @param pipe Pipe object + * @param ret Return value + */ +#define sys_port_trace_k_pipe_read_exit(pipe, ret) /** * @brief Trace Pipe cleanup entry @@ -1684,6 +1778,21 @@ */ #define sys_port_trace_k_heap_alloc_exit(h, timeout, ret) +/** + * @brief Trace Heap calloc enter + * @param h Heap object + * @param timeout Timeout period + */ +#define sys_port_trace_k_heap_calloc_enter(h, timeout) + +/** + * @brief Trace Heap calloc exit + * @param h Heap object + * @param timeout Timeout period + * @param ret Return value + */ +#define sys_port_trace_k_heap_calloc_exit(h, timeout, ret) + /** * @brief Trace Heap free * @param h Heap object diff --git a/include/zephyr/tracing/tracking.h b/include/zephyr/tracing/tracking.h index 2b2429c83f7c0..d6e24ee46a8f0 100644 --- a/include/zephyr/tracing/tracking.h +++ b/include/zephyr/tracing/tracking.h @@ -73,8 +73,8 @@ extern struct k_event *_track_list_k_event; #define sys_port_track_k_queue_cancel_wait(queue) #define sys_port_track_k_queue_init(queue) \ sys_track_k_queue_init(queue) -#define sys_port_track_k_pipe_init(pipe) \ - sys_track_k_pipe_init(pipe) +#define sys_port_track_k_pipe_init(pipe, buffer, buffer_size) \ + sys_track_k_pipe_init(pipe, buffer, buffer_size) #define sys_port_track_k_condvar_init(condvar, ret) #define sys_port_track_k_stack_init(stack) \ sys_track_k_stack_init(stack) @@ -105,7 +105,7 @@ void sys_track_k_mutex_init(struct k_mutex *mutex); void sys_track_k_stack_init(struct k_stack *stack); void sys_track_k_msgq_init(struct k_msgq *msgq); void sys_track_k_mbox_init(struct k_mbox *mbox); -void sys_track_k_pipe_init(struct k_pipe *pipe); +void sys_track_k_pipe_init(struct k_pipe *pipe, void *buffer, size_t size); void sys_track_k_queue_init(struct k_queue *queue); void sys_track_k_event_init(struct k_event *event); void sys_track_socket_init(int sock, int family, int type, int proto); @@ -132,7 +132,7 @@ void sys_track_socket_init(int sock, int family, int type, int proto); #define sys_port_track_k_queue_peek_head(queue, ret) #define sys_port_track_k_queue_cancel_wait(queue) #define sys_port_track_k_queue_init(queue) -#define sys_port_track_k_pipe_init(pipe) +#define sys_port_track_k_pipe_init(pipe, buffer, buffer_size) #define sys_port_track_k_condvar_init(condvar, ret) #define sys_port_track_k_stack_init(stack) #define sys_port_track_k_thread_name_set(thread, ret) diff --git a/include/zephyr/usb/class/usbd_dfu.h b/include/zephyr/usb/class/usbd_dfu.h new file mode 100644 index 0000000000000..ab8207fd5ba7e --- /dev/null +++ b/include/zephyr/usb/class/usbd_dfu.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief USB Device Firmware Upgrade (DFU) public header + * + * Header exposes API for registering DFU images. + */ + +#ifndef ZEPHYR_INCLUDE_USB_CLASS_USBD_DFU_H +#define ZEPHYR_INCLUDE_USB_CLASS_USBD_DFU_H + +#include + +/* DFU Class Subclass */ +#define USB_DFU_SUBCLASS 0x01 + +/* DFU Class runtime Protocol */ +#define USB_DFU_PROTOCOL_RUNTIME 0x01 + +/* DFU Class DFU mode Protocol */ +#define USB_DFU_PROTOCOL_DFU 0x02 + +/* DFU Class Specific Requests */ +#define USB_DFU_REQ_DETACH 0x00 +#define USB_DFU_REQ_DNLOAD 0x01 +#define USB_DFU_REQ_UPLOAD 0x02 +#define USB_DFU_REQ_GETSTATUS 0x03 +#define USB_DFU_REQ_CLRSTATUS 0x04 +#define USB_DFU_REQ_GETSTATE 0x05 +#define USB_DFU_REQ_ABORT 0x06 + +/* Run-Time DFU Functional Descriptor */ +struct usb_dfu_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bmAttributes; + uint16_t wDetachTimeOut; + uint16_t wTransferSize; + uint16_t bcdDFUVersion; +} __packed; + +/* DFU Functional Descriptor Type */ +#define USB_DESC_DFU_FUNCTIONAL 0x21 + +/* DFU attributes DFU Functional Descriptor */ +#define USB_DFU_ATTR_WILL_DETACH BIT(3) +#define USB_DFU_ATTR_MANIFESTATION_TOLERANT BIT(2) +#define USB_DFU_ATTR_CAN_UPLOAD BIT(1) +#define USB_DFU_ATTR_CAN_DNLOAD BIT(0) + +/* DFU Specification release */ +#define USB_DFU_VERSION 0x0110 + +/* DFU device status */ +enum usb_dfu_status { + ERR_OK = 0x00, + ERR_TARGET = 0x01, + ERR_FILE = 0x02, + ERR_WRITE = 0x03, + ERR_ERASE = 0x04, + ERR_CHECK_ERASED = 0x05, + ERR_PROG = 0x06, + ERR_VERIFY = 0x07, + ERR_ADDRESS = 0x08, + ERR_NOTDONE = 0x09, + ERR_FIRMWARE = 0x0A, + ERR_VENDOR = 0x0B, + ERR_USBR = 0x0C, + ERR_POR = 0x0D, + ERR_UNKNOWN = 0x0E, + ERR_STALLEDPKT = 0x0F, +}; + +/* DFU device states */ +enum usb_dfu_state { + APP_IDLE = 0, + APP_DETACH = 1, + DFU_IDLE = 2, + DFU_DNLOAD_SYNC = 3, + DFU_DNBUSY = 4, + DFU_DNLOAD_IDLE = 5, + DFU_MANIFEST_SYNC = 6, + DFU_MANIFEST = 7, + DFU_MANIFEST_WAIT_RST = 8, + DFU_UPLOAD_IDLE = 9, + DFU_ERROR = 10, + DFU_STATE_MAX = 11, +}; + +struct usbd_dfu_image { + const char *name; + struct usb_if_descriptor *const if_desc; + void *const priv; + struct usbd_desc_node *const sd_nd; + bool (*next_cb)(void *const priv, + const enum usb_dfu_state state, const enum usb_dfu_state next); + int (*read_cb)(void *const priv, + const uint32_t block, const uint16_t size, + uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE]); + int (*write_cb)(void *const priv, + const uint32_t block, const uint16_t size, + const uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE]); +}; + +/** + * @brief USB DFU device update API + * @defgroup usbd_dfu USB DFU device update API + * @ingroup usb + * @{ + */ + +/** + * @brief Define USB DFU image + * + * Use this macro to create USB DFU image + * + * The callbacks must be in form: + * + * @code{.c} + * static int read(void *const priv, const uint32_t block, const uint16_t size, + * uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE]) + * { + * int len; + * + * return len; + * } + * + * static int write(void *const priv, const uint32_t block, const uint16_t size, + * const uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE]) + * { + * return 0; + * } + * + * static bool next(void *const priv, + * const enum usb_dfu_state state, const enum usb_dfu_state next) + * { + * return true; + * } + * @endcode + * + * @param id Identifier by which the linker sorts registered images + * @param iname Image name as used in interface descriptor + * @param iread Image read callback + * @param iwrite Image write callback + * @param inext Notify/confirm next state + */ +#define USBD_DFU_DEFINE_IMG(id, iname, ipriv, iread, iwrite, inext) \ + static __noinit struct usb_if_descriptor usbd_dfu_iface_##id; \ + \ + USBD_DESC_STRING_DEFINE(usbd_dfu_str_##id, iname, USBD_DUT_STRING_INTERFACE); \ + \ + static const STRUCT_SECTION_ITERABLE(usbd_dfu_image, usbd_dfu_image_##id) = { \ + .name = iname, \ + .if_desc = &usbd_dfu_iface_##id, \ + .priv = ipriv, \ + .sd_nd = &usbd_dfu_str_##id, \ + .read_cb = iread, \ + .write_cb = iwrite, \ + .next_cb = inext, \ + } + +/** + * @} + */ +#endif /* ZEPHYR_INCLUDE_USB_CLASS_USBD_DFU_H */ diff --git a/include/zephyr/usb/class/usbd_hid.h b/include/zephyr/usb/class/usbd_hid.h index db2d55b6cbc7d..3772bb970d2d0 100644 --- a/include/zephyr/usb/class/usbd_hid.h +++ b/include/zephyr/usb/class/usbd_hid.h @@ -25,7 +25,7 @@ extern "C" { * @defgroup usbd_hid_device USBD HID device API * @ingroup usb * @since 3.7 - * @version 0.1.0 + * @version 0.1.1 * @{ */ @@ -159,7 +159,8 @@ struct hid_device_ops { * If the device does not use the callback, hid_device_submit_report() * will be processed synchronously. */ - void (*input_report_done)(const struct device *dev); + void (*input_report_done)(const struct device *dev, + const uint8_t *const report); /** * New output report callback. Callback will only be called for reports diff --git a/include/zephyr/usb/class/usbd_midi2.h b/include/zephyr/usb/class/usbd_midi2.h new file mode 100644 index 0000000000000..e0354e17b9002 --- /dev/null +++ b/include/zephyr/usb/class/usbd_midi2.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Titouan Christophe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_USB_CLASS_USBD_MIDI_H_ +#define ZEPHYR_INCLUDE_USB_CLASS_USBD_MIDI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief USB MIDI 2.0 class device API + * @defgroup usbd_midi2 USB MIDI 2.0 Class device API + * @ingroup usb + * @since 4.1 + * @version 0.1.0 + * @see midi20: "Universal Serial Bus Device Class Definition for MIDI Devices" + * Document Release 2.0 (May 5, 2020) + * @{ + */ + +#include +#include + +/** + * @brief MIDI2 application event handlers + */ +struct usbd_midi_ops { + /** + * @brief Callback type for incoming Universal MIDI Packets from host + * @param[in] dev The MIDI2 device receiving the packet + * @param[in] ump The received packet in Universal MIDI Packet format + */ + void (*rx_packet_cb)(const struct device *dev, const struct midi_ump ump); + + /** + * @brief Callback type for MIDI2 interface runtime status change + * @param[in] dev The MIDI2 device + * @param[in] ready True if the interface is enabled by the host + */ + void (*ready_cb)(const struct device *dev, const bool ready); +}; + +/** + * @brief Send a Universal MIDI Packet to the host + * @param[in] dev The MIDI2 device + * @param[in] ump The packet to send, in Universal MIDI Packet format + * @return 0 on success, all other values should be treated as error + * -EIO if USB MIDI 2.0 is not enabled by the host + * -ENOBUFS if there is no space in the TX buffer + */ +int usbd_midi_send(const struct device *dev, const struct midi_ump ump); + +/** + * @brief Set the application event handlers on a USB MIDI device + * @param[in] dev The MIDI2 device + * @param[in] ops The event handlers. Pass NULL to reset all callbacks + */ +void usbd_midi_set_ops(const struct device *dev, const struct usbd_midi_ops *ops); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/zephyr/usb/class/usbd_uac2.h b/include/zephyr/usb/class/usbd_uac2.h index 271d9dd016ea2..45965d648d583 100644 --- a/include/zephyr/usb/class/usbd_uac2.h +++ b/include/zephyr/usb/class/usbd_uac2.h @@ -47,6 +47,7 @@ struct uac2_ops { * @brief Start of Frame callback * * Notifies application about SOF event on the bus. + * This callback is mandatory to register. * * @param dev USB Audio 2 device * @param user_data Opaque user data pointer @@ -56,6 +57,7 @@ struct uac2_ops { * @brief Terminal update callback * * Notifies application that host has enabled or disabled a terminal. + * This callback is mandatory to register. * * @param dev USB Audio 2 device * @param terminal Terminal ID linked to AudioStreaming interface @@ -73,6 +75,7 @@ struct uac2_ops { * AudioStreaming interface. The buffer is owned by USB stack until * @ref data_recv_cb callback is called. The buffer must be sufficiently * aligned and otherwise suitable for use by UDC driver. + * This callback is mandatory to register for devices receiving USB audio from the USB host. * * @param dev USB Audio 2 device * @param terminal Input Terminal ID linked to AudioStreaming interface @@ -86,6 +89,7 @@ struct uac2_ops { * * This function releases buffer obtained in @ref get_recv_buf after USB * has written data to the buffer and/or no longer needs it. + * This callback is mandatory to register for devices receiving USB audio from the USB host. * * @param dev USB Audio 2 device * @param terminal Input Terminal ID linked to AudioStreaming interface @@ -100,6 +104,7 @@ struct uac2_ops { * * This function releases buffer provided in @ref usbd_uac2_send when * the class no longer needs it. + * This callback is mandatory to register if calling @ref usbd_uac2_send. * * @param dev USB Audio 2 device * @param terminal Output Terminal ID linked to AudioStreaming interface @@ -118,6 +123,9 @@ struct uac2_ops { * capable device is operating at Full-Speed (microframes was false), * the format is Q10.14 stored on 24 least significant bits (i.e. 8 most * significant bits are ignored). + * This callback is mandatory to register if there is USB Audio Streaming interface linked + * to Input Terminal clocked from asynchronous clock (i.e. clock source without + * sof-synchronized;) and there is no implicit-feedback; on the interface. * * @param dev USB Audio 2 device * @param terminal Input Terminal ID whose feedback should be returned @@ -176,6 +184,9 @@ void usbd_uac2_set_ops(const struct device *dev, * Data buffer must be sufficiently aligned and otherwise suitable for use by * UDC driver. * + * @note Buffer ownership is transferred to the stack in case of success, in + * case of an error the caller retains the ownership of the buffer. + * * @param dev USB Audio 2 device * @param terminal Output Terminal ID linked to AudioStreaming interface * @param data Buffer containing outgoing data diff --git a/include/zephyr/usb/usbd.h b/include/zephyr/usb/usbd.h index b588d7087d282..619d926b14e17 100644 --- a/include/zephyr/usb/usbd.h +++ b/include/zephyr/usb/usbd.h @@ -841,14 +841,30 @@ int usbd_register_class(struct usbd_context *uds_ctx, * usbd_register_class for any device, configuration number, or instance, * either usbd_register_class or this function will fail. * + * There may be situations where a particular function should not be + * registered, for example, when using the USB DFU implementation, the DFU mode + * function must be excluded during normal device operation. To do this, the + * device can pass a blocklist in the form shown below as an optional argument. + * If the blocklist is not needed, the argument should be NULL. + * + * @code{.c} + * static const char *const blocklist[] = { + * "dfu_dfu", + * NULL, + * }; + * @endcode + * * @param[in] uds_ctx Pointer to USB device support context * @param[in] speed Configuration speed * @param[in] cfg Configuration value (bConfigurationValue) + * @param[in] blocklist Null pointer terminated array of pointers to string + * literals to be used as a block list * * @return 0 on success, other values on fail. */ int usbd_register_all_classes(struct usbd_context *uds_ctx, - const enum usbd_speed speed, uint8_t cfg); + const enum usbd_speed speed, uint8_t cfg, + const char *const blocklist[]); /** * @brief Unregister an USB class instance diff --git a/include/zephyr/usb/usbd_msg.h b/include/zephyr/usb/usbd_msg.h index b9e99d00c7065..2d81e0ef2f46d 100644 --- a/include/zephyr/usb/usbd_msg.h +++ b/include/zephyr/usb/usbd_msg.h @@ -52,6 +52,10 @@ enum usbd_msg_type { USBD_MSG_CDC_ACM_LINE_CODING, /** CDC ACM Line State update */ USBD_MSG_CDC_ACM_CONTROL_LINE_STATE, + /** USB DFU class detach request */ + USBD_MSG_DFU_APP_DETACH, + /** USB DFU class download completed */ + USBD_MSG_DFU_DOWNLOAD_COMPLETED, /** Maximum number of message types */ USBD_MSG_MAX_NUMBER, }; @@ -70,6 +74,8 @@ static const char *const usbd_msg_type_list[] = { "Stack error", "CDC ACM line coding", "CDC ACM control line state", + "DFU detach request", + "DFU download completed", }; BUILD_ASSERT(ARRAY_SIZE(usbd_msg_type_list) == USBD_MSG_MAX_NUMBER, diff --git a/include/zephyr/usb/usbh.h b/include/zephyr/usb/usbh.h index 869f3007a488e..852d8b9ac6986 100644 --- a/include/zephyr/usb/usbh.h +++ b/include/zephyr/usb/usbh.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -42,15 +43,21 @@ struct usbh_contex { struct k_mutex mutex; /** Pointer to UHC device struct */ const struct device *dev; - /** peripheral list */ - sys_dlist_t peripherals; + /** USB device list */ + sys_dlist_t udevs; + /** USB root device */ + struct usb_device *root; + /** Allocated device addresses bit array */ + struct sys_bitarray *addr_ba; }; #define USBH_CONTROLLER_DEFINE(device_name, uhc_dev) \ + SYS_BITARRAY_DEFINE_STATIC(ba_##device_name, 128); \ static STRUCT_SECTION_ITERABLE(usbh_contex, device_name) = { \ .name = STRINGIFY(device_name), \ .mutex = Z_MUTEX_INITIALIZER(device_name.mutex), \ .dev = uhc_dev, \ + .addr_ba = &ba_##device_name, \ } /** diff --git a/include/zephyr/xen/gnttab.h b/include/zephyr/xen/gnttab.h index be6a0d5c906e9..4cfc65e580e92 100644 --- a/include/zephyr/xen/gnttab.h +++ b/include/zephyr/xen/gnttab.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 EPAM Systems + * Copyright (c) 2021-2024 EPAM Systems * * SPDX-License-Identifier: Apache-2.0 */ @@ -76,12 +76,12 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, unsigned int count); * Unmap foreign grant refs. The gnttab_put_page() should be used after this for * each page, that was successfully unmapped. * - * @param unmap_ops - array of prepared gnttab_map_grant_ref's for unmapping + * @param unmap_ops - array of prepared gnttab_unmap_grant_ref's for unmapping * @param count - number of grefs in unmap_ops array * @return - @count on success or negative errno on failure * also per-page status will be set in unmap_ops[i].status (GNTST_*) */ -int gnttab_unmap_refs(struct gnttab_map_grant_ref *unmap_ops, unsigned int count); +int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, unsigned int count); /* * Convert grant ref status codes (GNTST_*) to text messages. diff --git a/include/zephyr/xen/public/grant_table.h b/include/zephyr/xen/public/grant_table.h index 0124046d042f4..81803a1daa3f6 100644 --- a/include/zephyr/xen/public/grant_table.h +++ b/include/zephyr/xen/public/grant_table.h @@ -324,7 +324,23 @@ struct gnttab_setup_table { typedef struct gnttab_setup_table gnttab_setup_table_t; DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t); - +/* + * GNTTABOP_query_size: Query the current and maximum sizes of the shared + * grant table. + * NOTES: + * 1. may be specified as DOMID_SELF. + * 2. Only a sufficiently-privileged domain may specify != DOMID_SELF. + */ +struct gnttab_query_size { + /* IN parameters. */ + domid_t dom; + /* OUT parameters. */ + uint32_t nr_frames; + uint32_t max_nr_frames; + int16_t status; /* => enum grant_status */ +}; +typedef struct gnttab_query_size gnttab_query_size_t; +DEFINE_XEN_GUEST_HANDLE(gnttab_query_size_t); /* * Bitfield values for gnttab_map_grant_ref.flags. diff --git a/include/zephyr/zbus/zbus.h b/include/zephyr/zbus/zbus.h index e5657c0a54933..478268d85b4ce 100644 --- a/include/zephyr/zbus/zbus.h +++ b/include/zephyr/zbus/zbus.h @@ -81,6 +81,10 @@ struct zbus_channel { #if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__) /** Channel name. */ const char *name; +#endif +#if defined(CONFIG_ZBUS_CHANNEL_ID) || defined(__DOXYGEN__) + /** Unique numeric channel identifier. */ + uint32_t id; #endif /** Message reference. Represents the message's reference that points to the actual * shared memory region. @@ -263,6 +267,34 @@ struct zbus_channel_observation { #define _ZBUS_RUNTIME_OBSERVERS_DECL(_name) #endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */ +#define _ZBUS_MESSAGE_NAME(_name) _CONCAT(_zbus_message_, _name) + +/* clang-format off */ +#define _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data) \ + static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \ + .observers_start_idx = -1, \ + .observers_end_idx = -1, \ + .sem = Z_SEM_INITIALIZER(_CONCAT(_zbus_chan_data_, _name).sem, 1, 1), \ + IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, \ + (.highest_observer_priority = ZBUS_MIN_THREAD_PRIORITY,)) \ + IF_ENABLED(CONFIG_ZBUS_RUNTIME_OBSERVERS, \ + (.observers = SYS_SLIST_STATIC_INIT( \ + &_CONCAT(_zbus_chan_data_, _name).observers),)) \ + }; \ + static K_MUTEX_DEFINE(_CONCAT(_zbus_mutex_, _name)); \ + _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \ + ZBUS_CHANNEL_NAME_INIT(_name) /* Maybe removed */ \ + IF_ENABLED(CONFIG_ZBUS_CHANNEL_ID, (.id = _id,)) \ + .message = &_ZBUS_MESSAGE_NAME(_name), \ + .message_size = sizeof(_type), \ + .user_data = _user_data, \ + .validator = _validator, \ + .data = &_CONCAT(_zbus_chan_data_, _name), \ + IF_ENABLED(ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION, \ + (.msg_subscriber_pool = &_zbus_msg_subscribers_pool,)) \ + } +/* clang-format on */ + /** @endcond */ /* clang-format off */ @@ -328,7 +360,11 @@ struct zbus_channel_observation { */ #define ZBUS_OBSERVERS(...) __VA_ARGS__ -/* clang-format off */ +/** + * @def ZBUS_CHAN_ID_INVALID + * This macro indicates the channel does not have a unique ID. + */ +#define ZBUS_CHAN_ID_INVALID UINT32_MAX /** * @brief Zbus channel definition. @@ -345,37 +381,37 @@ struct zbus_channel_observation { * first the highest priority. * @param _init_val The message initialization. */ -#define ZBUS_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, _init_val) \ - static _type _CONCAT(_zbus_message_, _name) = _init_val; \ - static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \ - .observers_start_idx = -1, \ - .observers_end_idx = -1, \ - .sem = Z_SEM_INITIALIZER(_CONCAT(_zbus_chan_data_, _name).sem, 1, 1), \ - IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \ - .highest_observer_priority = ZBUS_MIN_THREAD_PRIORITY, \ - )) \ - IF_ENABLED(CONFIG_ZBUS_RUNTIME_OBSERVERS, ( \ - .observers = SYS_SLIST_STATIC_INIT( \ - &_CONCAT(_zbus_chan_data_, _name).observers), \ - )) \ - }; \ - static K_MUTEX_DEFINE(_CONCAT(_zbus_mutex_, _name)); \ - _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \ - ZBUS_CHANNEL_NAME_INIT(_name) /* Maybe removed */ \ - .message = &_CONCAT(_zbus_message_, _name), \ - .message_size = sizeof(_type), \ - .user_data = _user_data, \ - .validator = _validator, \ - .data = &_CONCAT(_zbus_chan_data_, _name), \ - IF_ENABLED(ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION, ( \ - .msg_subscriber_pool = &_zbus_msg_subscribers_pool, \ - )) \ - }; \ - /* Extern declaration of observers */ \ - ZBUS_OBS_DECLARE(_observers); \ - /* Create all channel observations from observers list */ \ +#define ZBUS_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, _init_val) \ + static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \ + _ZBUS_CHAN_DEFINE(_name, ZBUS_CHAN_ID_INVALID, _type, _validator, _user_data); \ + /* Extern declaration of observers */ \ + ZBUS_OBS_DECLARE(_observers); \ + /* Create all channel observations from observers list */ \ + FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers) + +/** + * @brief Zbus channel definition with numeric identifier. + * + * This macro defines a channel. + * + * @param _name The channel's name. + * @param _id The channel's unique numeric identifier. + * @param _type The Message type. It must be a struct or union. + * @param _validator The validator function. + * @param _user_data A pointer to the user data. + * + * @see struct zbus_channel + * @param _observers The observers list. The sequence indicates the priority of the observer. The + * first the highest priority. + * @param _init_val The message initialization. + */ +#define ZBUS_CHAN_DEFINE_WITH_ID(_name, _id, _type, _validator, _user_data, _observers, _init_val) \ + static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \ + _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data); \ + /* Extern declaration of observers */ \ + ZBUS_OBS_DECLARE(_observers); \ + /* Create all channel observations from observers list */ \ FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers) -/* clang-format on */ /** * @brief Initialize a message. @@ -386,10 +422,7 @@ struct zbus_channel_observation { * @param[in] _val Variadic with the initial values. ``ZBUS_INIT(0)`` means ``{0}``, as * ZBUS_INIT(.a=10, .b=30) means ``{.a=10, .b=30}``. */ -#define ZBUS_MSG_INIT(_val, ...) \ - { \ - _val, ##__VA_ARGS__ \ - } +#define ZBUS_MSG_INIT(_val, ...) {_val, ##__VA_ARGS__} /* clang-format off */ @@ -638,6 +671,20 @@ static inline const char *zbus_chan_name(const struct zbus_channel *chan) #endif +#if defined(CONFIG_ZBUS_CHANNEL_ID) || defined(__DOXYGEN__) + +/** + * @brief Retrieve a zbus channel from its numeric identifier + * + * @param channel_id Unique channel ID from @ref ZBUS_CHAN_DEFINE_WITH_ID + * + * @retval NULL If channel with ID @a channel_id does not exist. + * @retval chan Channel pointer with ID @a channel_id otherwise. + */ +const struct zbus_channel *zbus_chan_from_id(uint32_t channel_id); + +#endif + /** * @brief Get the reference for a channel message directly. * diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 8477508b98af3..8ba95f6c5708c 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -84,6 +84,10 @@ list(APPEND kernel_files thread.c sched.c ) +# FIXME: Once the prior pipe implementation is removed, this should be included in the above list +if(NOT CONFIG_PIPES) +list(APPEND kernel_files pipe.c) +endif() # NOT CONFIG_PIPES if(CONFIG_SMP) list(APPEND kernel_files smp.c @@ -140,7 +144,7 @@ set_target_properties( __ZEPHYR_SUPERVISOR__ ) -target_sources_ifdef(CONFIG_STACK_CANARIES kernel PRIVATE compiler_stack_protect.c) +target_sources_ifdef(CONFIG_REQUIRES_STACK_CANARIES kernel PRIVATE compiler_stack_protect.c) target_sources_ifdef(CONFIG_SYS_CLOCK_EXISTS kernel PRIVATE timeout.c timer.c) target_sources_ifdef(CONFIG_ATOMIC_OPERATIONS_C kernel PRIVATE atomic_c.c) target_sources_ifdef(CONFIG_MMU kernel PRIVATE mmu.c) diff --git a/kernel/Kconfig b/kernel/Kconfig index 62713a5c9bb65..9c92dc542c0e2 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -12,6 +12,7 @@ source "subsys/logging/Kconfig.template.log_config" config MULTITHREADING bool "Multi-threading" if ARCH_HAS_SINGLE_THREAD_SUPPORT default y + select RING_BUFFER help If disabled, only the main thread is available, so a main() function must be provided. Interrupts are available. Kernel objects will most @@ -52,7 +53,7 @@ config NUM_PREEMPT_PRIORITIES int "Number of preemptible priorities" if MULTITHREADING default 0 if !MULTITHREADING default 15 - range 0 128 + range 0 127 help Number of preemptible priorities available in the system. Gives access to priorities 0 to CONFIG_NUM_PREEMPT_PRIORITIES - 1. @@ -211,7 +212,7 @@ config THREAD_ABORT_NEED_CLEANUP bool help This option enables the bits to clean up the current thread if - k_thread_abort(arch_current_thread()) is called, as the cleanup cannot be + k_thread_abort(_current) is called, as the cleanup cannot be running in the current thread stack. config THREAD_CUSTOM_DATA @@ -677,6 +678,13 @@ config POLL concurrently, which can be either directly triggered or triggered by the availability of some kernel objects (semaphores and FIFOs). +config MEM_SLAB_POINTER_VALIDATE + bool "Validate the memory slab pointer when allocating or freeing" + default ASSERT + help + This enables additional runtime checks to validate the memory slab + pointer during when allocating or freeing a memory slab. + config MEM_SLAB_TRACE_MAX_UTILIZATION bool "Getting maximum slab utilization" help @@ -706,6 +714,7 @@ config EVENTS config PIPES bool "Pipe objects" + select DEPRECATED help This option enables kernel pipes. A pipe is a kernel object that allows a thread to send a byte stream to another thread. Pipes can @@ -713,6 +722,9 @@ config PIPES Note that setting this option slightly increases the size of the thread structure. + This Kconfig is deprecated and will be removed, by disabling this + kconfig another implementation of k_pipe will be available when + CONFIG_MULTITHREADING is enabled. config KERNEL_MEM_POOL bool "Use Kernel Memory Pool" @@ -862,25 +874,67 @@ config XIP menu "Security Options" -config STACK_CANARIES - bool "Compiler stack canaries" - depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR - select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS +config REQUIRES_STACK_CANARIES + bool help - This option enables compiler stack canaries. + Hidden option to signal that software stack protection is required. +choice + prompt "Stack canaries protection options" + optional + help If stack canaries are supported by the compiler, it will emit extra code that inserts a canary value into the stack frame when a function is entered and validates this value upon exit. Stack corruption (such as that caused by buffer overflow) results in a fatal error condition for the running entity. - Enabling this option can result in a significant increase - in footprint and an associated decrease in performance. + Enabling this option, depending on the level chosen, can result in a + significant increase in footprint and a corresponding decrease in performance. If stack canaries are not supported by the compiler an error will occur at build time. -if STACK_CANARIES +config STACK_CANARIES + bool "Default protection" + depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR + select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS + select REQUIRES_STACK_CANARIES + help + This option enables compiler stack canaries in functions that have + vulnerable objects. Generally this means function that call alloca or + have buffers larger than 8 bytes. + +config STACK_CANARIES_STRONG + bool "Strong protection" + depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR + select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS + select REQUIRES_STACK_CANARIES + help + This option enables compiler stack canaries in functions that call alloca, + functions that have local array definitiion or have references to local + frame addresses. + +config STACK_CANARIES_ALL + bool "Maximum protection available" + depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR + select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS + select REQUIRES_STACK_CANARIES + help + This option enables compiler stack canaries for all functions. + +config STACK_CANARIES_EXPLICIT + bool "Explicit protection" + depends on ENTROPY_GENERATOR || TEST_RANDOM_GENERATOR + depends on "${ZEPHYR_TOOLCHAIN_VARIANT}" = "zephyr" + select NEED_LIBC_MEM_PARTITION if !STACK_CANARIES_TLS + select REQUIRES_STACK_CANARIES + help + This option enables compiler stack canaries only in functions which have the + stack_protect attribute. + +endchoice + +if REQUIRES_STACK_CANARIES config STACK_CANARIES_TLS bool "Stack canaries using thread local storage" diff --git a/kernel/Kconfig.obj_core b/kernel/Kconfig.obj_core index 5c9a1418ffeea..5e846b20ffaa7 100644 --- a/kernel/Kconfig.obj_core +++ b/kernel/Kconfig.obj_core @@ -77,7 +77,7 @@ config OBJ_CORE_SEM config OBJ_CORE_PIPE bool "Integrate pipe into object core framework" - default y if PIPES + default y help When enabled, this option integrates pipes into the object core framework. diff --git a/kernel/Kconfig.vm b/kernel/Kconfig.vm index 923d511d9dbde..a8105d03da033 100644 --- a/kernel/Kconfig.vm +++ b/kernel/Kconfig.vm @@ -98,8 +98,10 @@ config KERNEL_DIRECT_MAP endif # KERNEL_VM_SUPPORT -menuconfig MMU - bool "MMU features" +menu "MMU Features" + +config MMU + bool depends on CPU_HAS_MMU select KERNEL_VM_SUPPORT help @@ -206,6 +208,7 @@ config DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS endif # DEMAND_PAGING endif # MMU +endmenu config KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK bool diff --git a/kernel/compiler_stack_protect.c b/kernel/compiler_stack_protect.c index e8408a33ed103..30da82d4a49e4 100644 --- a/kernel/compiler_stack_protect.c +++ b/kernel/compiler_stack_protect.c @@ -10,7 +10,8 @@ * * This module provides functions to support compiler stack protection * using canaries. This feature is enabled with configuration - * CONFIG_STACK_CANARIES=y. + * CONFIG_STACK_CANARIES=y or CONFIG_STACK_CANARIES_STRONG=y or + * CONFIG_STACK_CANARIES_ALL=y or CONFIG_STACK_CANARIES_EXPLICIT=y. * * When this feature is enabled, the compiler generated code refers to * function __stack_chk_fail and global variable __stack_chk_guard. diff --git a/kernel/condvar.c b/kernel/condvar.c index 615a6b30f15a7..d00eb552ff7f8 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -93,7 +93,12 @@ int z_impl_k_condvar_broadcast(struct k_condvar *condvar) SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, broadcast, condvar, woken); - z_reschedule(&lock, key); + + if (woken == 0) { + k_spin_unlock(&lock, key); + } else { + z_reschedule(&lock, key); + } return woken; } diff --git a/kernel/dynamic.c b/kernel/dynamic.c index a17a84f724ad7..a03216b00f0a4 100644 --- a/kernel/dynamic.c +++ b/kernel/dynamic.c @@ -31,11 +31,6 @@ static K_THREAD_STACK_ARRAY_DEFINE(dynamic_stack, CONFIG_DYNAMIC_THREAD_POOL_SIZ CONFIG_DYNAMIC_THREAD_STACK_SIZE); SYS_BITARRAY_DEFINE_STATIC(dynamic_ba, BA_SIZE); -static k_thread_stack_t *z_thread_stack_alloc_dyn(size_t align, size_t size) -{ - return z_thread_aligned_alloc(align, size); -} - static k_thread_stack_t *z_thread_stack_alloc_pool(size_t size) { int rv; @@ -61,7 +56,7 @@ static k_thread_stack_t *z_thread_stack_alloc_pool(size_t size) return stack; } -static k_thread_stack_t *stack_alloc_dyn(size_t size, int flags) +static k_thread_stack_t *z_thread_stack_alloc_dyn(size_t size, int flags) { if ((flags & K_USER) == K_USER) { #ifdef CONFIG_DYNAMIC_OBJECTS @@ -74,8 +69,7 @@ static k_thread_stack_t *stack_alloc_dyn(size_t size, int flags) #endif /* CONFIG_DYNAMIC_OBJECTS */ } - return z_thread_stack_alloc_dyn(Z_KERNEL_STACK_OBJ_ALIGN, - K_KERNEL_STACK_LEN(size)); + return z_thread_aligned_alloc(Z_KERNEL_STACK_OBJ_ALIGN, K_KERNEL_STACK_LEN(size)); } k_thread_stack_t *z_impl_k_thread_stack_alloc(size_t size, int flags) @@ -83,7 +77,7 @@ k_thread_stack_t *z_impl_k_thread_stack_alloc(size_t size, int flags) k_thread_stack_t *stack = NULL; if (IS_ENABLED(CONFIG_DYNAMIC_THREAD_PREFER_ALLOC)) { - stack = stack_alloc_dyn(size, flags); + stack = z_thread_stack_alloc_dyn(size, flags); if (stack == NULL && CONFIG_DYNAMIC_THREAD_POOL_SIZE > 0) { stack = z_thread_stack_alloc_pool(size); } @@ -93,7 +87,7 @@ k_thread_stack_t *z_impl_k_thread_stack_alloc(size_t size, int flags) } if ((stack == NULL) && IS_ENABLED(CONFIG_DYNAMIC_THREAD_ALLOC)) { - stack = stack_alloc_dyn(size, flags); + stack = z_thread_stack_alloc_dyn(size, flags); } } diff --git a/kernel/errno.c b/kernel/errno.c index 2535e00e336cb..bbbd6f87bfd03 100644 --- a/kernel/errno.c +++ b/kernel/errno.c @@ -36,7 +36,7 @@ int *z_impl_z_errno(void) /* Initialized to the lowest address in the stack so the thread can * directly read/write it */ - return &arch_current_thread()->userspace_local_data->errno_var; + return &_current->userspace_local_data->errno_var; } static inline int *z_vrfy_z_errno(void) @@ -48,7 +48,7 @@ static inline int *z_vrfy_z_errno(void) #else int *z_impl_z_errno(void) { - return &arch_current_thread()->errno_var; + return &_current->errno_var; } #endif /* CONFIG_USERSPACE */ diff --git a/kernel/fatal.c b/kernel/fatal.c index a5682e7cd7f41..3cf3114364da8 100644 --- a/kernel/fatal.c +++ b/kernel/fatal.c @@ -90,7 +90,7 @@ void z_fatal_error(unsigned int reason, const struct arch_esf *esf) */ unsigned int key = arch_irq_lock(); struct k_thread *thread = IS_ENABLED(CONFIG_MULTITHREADING) ? - arch_current_thread() : NULL; + _current : NULL; /* twister looks for the "ZEPHYR FATAL ERROR" string, don't * change it without also updating twister diff --git a/kernel/futex.c b/kernel/futex.c index 86acc0c74a02f..c6e5e47e683e3 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -47,7 +47,11 @@ int z_impl_k_futex_wake(struct k_futex *futex, bool wake_all) } } while (thread && wake_all); - z_reschedule(&futex_data->lock, key); + if (woken == 0) { + k_spin_unlock(&futex_data->lock, key); + } else { + z_reschedule(&futex_data->lock, key); + } return woken; } diff --git a/kernel/idle.c b/kernel/idle.c index 4d095c8f27b3a..3cf4791009303 100644 --- a/kernel/idle.c +++ b/kernel/idle.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,7 @@ void idle(void *unused1, void *unused2, void *unused3) ARG_UNUSED(unused2); ARG_UNUSED(unused3); - __ASSERT_NO_MSG(arch_current_thread()->base.prio >= 0); + __ASSERT_NO_MSG(_current->base.prio >= 0); while (true) { /* SMP systems without a working IPI can't actual @@ -85,7 +86,7 @@ void idle(void *unused1, void *unused2, void *unused3) * explicitly yield in the idle thread otherwise * nothing else will run once it starts. */ - if (_kernel.ready_q.cache != arch_current_thread()) { + if (_kernel.ready_q.cache != _current) { z_swap_unlocked(); } # endif /* !defined(CONFIG_USE_SWITCH) || defined(CONFIG_SPARC) */ @@ -100,3 +101,4 @@ void __weak arch_spin_relax(void) arch_nop(); } +EXPORT_SYMBOL(arch_spin_relax); diff --git a/kernel/include/kernel_arch_interface.h b/kernel/include/kernel_arch_interface.h index 0b7504c5b9ecd..05629c26a5f64 100644 --- a/kernel/include/kernel_arch_interface.h +++ b/kernel/include/kernel_arch_interface.h @@ -129,7 +129,10 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, * location, which must be updated. */ static inline void arch_switch(void *switch_to, void **switched_from); -#else +#endif /* CONFIG_USE_SWITCH */ + +#if !defined(CONFIG_USE_SWITCH) || defined(__DOXYGEN__) +#if defined(__DOXYGEN__) /** * Cooperatively context switch * @@ -143,6 +146,7 @@ static inline void arch_switch(void *switch_to, void **switched_from); * blocking operation. */ int arch_swap(unsigned int key); +#endif /* __DOXYGEN__ */ /** * Set the return value for the specified thread. @@ -154,7 +158,7 @@ int arch_swap(unsigned int key); */ static ALWAYS_INLINE void arch_thread_return_value_set(struct k_thread *thread, unsigned int value); -#endif /* CONFIG_USE_SWITCH */ +#endif /* !CONFIG_USE_SWITCH || __DOXYGEN__ */ #ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN /** diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index cb13aacf6007a..afc5409d20765 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -221,7 +221,7 @@ void z_mem_manage_init(void); void z_mem_manage_boot_finish(void); -void z_handle_obj_poll_events(sys_dlist_t *events, uint32_t state); +bool z_handle_obj_poll_events(sys_dlist_t *events, uint32_t state); #ifdef CONFIG_PM @@ -286,7 +286,7 @@ int z_kernel_stats_query(struct k_obj_core *obj_core, void *stats); * where these steps require that the thread is no longer running. * If the target thread is not the current running thread, the cleanup * steps will be performed immediately. However, if the target thread is - * the current running thread (e.g. k_thread_abort(arch_current_thread())), it defers + * the current running thread (e.g. k_thread_abort(_current)), it defers * the cleanup steps to later when the work will be finished in another * context. * diff --git a/kernel/include/ksched.h b/kernel/include/ksched.h index ff529d06fca03..7858282d707ad 100644 --- a/kernel/include/ksched.h +++ b/kernel/include/ksched.h @@ -119,9 +119,7 @@ static inline bool z_is_prio_lower_or_equal(int prio1, int prio2) return z_is_prio1_lower_than_or_equal_to_prio2(prio1, prio2); } -int32_t z_sched_prio_cmp(struct k_thread *thread_1, struct k_thread *thread_2); - -static inline bool _is_valid_prio(int prio, void *entry_point) +static inline bool _is_valid_prio(int prio, k_thread_entry_t entry_point) { if ((prio == K_IDLE_PRIO) && z_is_idle_thread_entry(entry_point)) { return true; @@ -143,9 +141,9 @@ static inline bool _is_valid_prio(int prio, void *entry_point) static inline void z_sched_lock(void) { __ASSERT(!arch_is_in_isr(), ""); - __ASSERT(arch_current_thread()->base.sched_locked != 1U, ""); + __ASSERT(_current->base.sched_locked != 1U, ""); - --arch_current_thread()->base.sched_locked; + --_current->base.sched_locked; compiler_barrier(); } @@ -182,7 +180,7 @@ static ALWAYS_INLINE struct k_thread *z_unpend_first_thread(_wait_q_t *wait_q) thread = _priq_wait_best(&wait_q->waitq); if (unlikely(thread != NULL)) { unpend_thread_no_timeout(thread); - (void)z_abort_thread_timeout(thread); + z_abort_thread_timeout(thread); } } diff --git a/kernel/include/kswap.h b/kernel/include/kswap.h index 66d7b431d3876..03c4a991bb08c 100644 --- a/kernel/include/kswap.h +++ b/kernel/include/kswap.h @@ -78,7 +78,6 @@ static ALWAYS_INLINE unsigned int do_swap(unsigned int key, struct k_spinlock *lock, bool is_spinlock) { - ARG_UNUSED(lock); struct k_thread *new_thread, *old_thread; #ifdef CONFIG_SPIN_VALIDATE @@ -97,12 +96,12 @@ static ALWAYS_INLINE unsigned int do_swap(unsigned int key, */ # ifndef CONFIG_ARM64 __ASSERT(arch_irq_unlocked(key) || - arch_current_thread()->base.thread_state & (_THREAD_DUMMY | _THREAD_DEAD), + _current->base.thread_state & (_THREAD_DUMMY | _THREAD_DEAD), "Context switching while holding lock!"); # endif /* CONFIG_ARM64 */ #endif /* CONFIG_SPIN_VALIDATE */ - old_thread = arch_current_thread(); + old_thread = _current; z_check_stack_sentinel(); @@ -125,7 +124,6 @@ static ALWAYS_INLINE unsigned int do_swap(unsigned int key, z_sched_usage_switch(new_thread); #ifdef CONFIG_SMP - _current_cpu->swap_ok = 0; new_thread->base.cpu = arch_curr_cpu()->id; if (!is_spinlock) { @@ -134,7 +132,7 @@ static ALWAYS_INLINE unsigned int do_swap(unsigned int key, #endif /* CONFIG_SMP */ z_thread_mark_switched_out(); z_sched_switch_spin(new_thread); - arch_current_thread_set(new_thread); + z_current_thread_set(new_thread); #ifdef CONFIG_TIMESLICING z_reset_time_slice(new_thread); @@ -147,7 +145,7 @@ static ALWAYS_INLINE unsigned int do_swap(unsigned int key, arch_cohere_stacks(old_thread, NULL, new_thread); #ifdef CONFIG_SMP - /* Now add arch_current_thread() back to the run queue, once we are + /* Now add _current back to the run queue, once we are * guaranteed to reach the context switch in finite * time. See z_sched_switch_spin(). */ @@ -175,7 +173,7 @@ static ALWAYS_INLINE unsigned int do_swap(unsigned int key, irq_unlock(key); } - return arch_current_thread()->swap_retval; + return _current->swap_retval; } static inline int z_swap_irqlock(unsigned int key) @@ -236,30 +234,6 @@ static inline void z_swap_unlocked(void) * * The memory of the dummy thread can be completely uninitialized. */ -static inline void z_dummy_thread_init(struct k_thread *dummy_thread) -{ - dummy_thread->base.thread_state = _THREAD_DUMMY; -#ifdef CONFIG_SCHED_CPU_MASK - dummy_thread->base.cpu_mask = -1; -#endif /* CONFIG_SCHED_CPU_MASK */ - dummy_thread->base.user_options = K_ESSENTIAL; -#ifdef CONFIG_THREAD_STACK_INFO - dummy_thread->stack_info.start = 0U; - dummy_thread->stack_info.size = 0U; -#endif /* CONFIG_THREAD_STACK_INFO */ -#ifdef CONFIG_USERSPACE - dummy_thread->mem_domain_info.mem_domain = &k_mem_domain_default; -#endif /* CONFIG_USERSPACE */ -#if (K_HEAP_MEM_POOL_SIZE > 0) - k_thread_system_pool_assign(dummy_thread); -#else - dummy_thread->resource_pool = NULL; -#endif /* K_HEAP_MEM_POOL_SIZE */ +void z_dummy_thread_init(struct k_thread *dummy_thread); -#ifdef CONFIG_TIMESLICE_PER_THREAD - dummy_thread->base.slice_ticks = 0; -#endif /* CONFIG_TIMESLICE_PER_THREAD */ - - arch_current_thread_set(dummy_thread); -} #endif /* ZEPHYR_KERNEL_INCLUDE_KSWAP_H_ */ diff --git a/kernel/include/kthread.h b/kernel/include/kthread.h index 39bea42c912e8..45a1fec06a1a5 100644 --- a/kernel/include/kthread.h +++ b/kernel/include/kthread.h @@ -15,6 +15,7 @@ #define Z_STATE_STR_DUMMY "dummy" #define Z_STATE_STR_PENDING "pending" +#define Z_STATE_STR_SLEEPING "sleeping" #define Z_STATE_STR_DEAD "dead" #define Z_STATE_STR_SUSPENDED "suspended" #define Z_STATE_STR_ABORTING "aborting" @@ -96,9 +97,8 @@ static inline bool z_is_thread_prevented_from_running(struct k_thread *thread) { uint8_t state = thread->base.thread_state; - return (state & (_THREAD_PENDING | _THREAD_DEAD | + return (state & (_THREAD_PENDING | _THREAD_SLEEPING | _THREAD_DEAD | _THREAD_DUMMY | _THREAD_SUSPENDED)) != 0U; - } static inline bool z_is_thread_timeout_active(struct k_thread *thread) @@ -108,8 +108,7 @@ static inline bool z_is_thread_timeout_active(struct k_thread *thread) static inline bool z_is_thread_ready(struct k_thread *thread) { - return !((z_is_thread_prevented_from_running(thread)) != 0U || - z_is_thread_timeout_active(thread)); + return !z_is_thread_prevented_from_running(thread); } static inline bool z_is_thread_state_set(struct k_thread *thread, uint32_t state) @@ -122,6 +121,16 @@ static inline bool z_is_thread_queued(struct k_thread *thread) return z_is_thread_state_set(thread, _THREAD_QUEUED); } +static inline void z_mark_thread_as_queued(struct k_thread *thread) +{ + thread->base.thread_state |= _THREAD_QUEUED; +} + +static inline void z_mark_thread_as_not_queued(struct k_thread *thread) +{ + thread->base.thread_state &= ~_THREAD_QUEUED; +} + static inline void z_mark_thread_as_suspended(struct k_thread *thread) { thread->base.thread_state |= _THREAD_SUSPENDED; @@ -146,6 +155,21 @@ static inline void z_mark_thread_as_not_pending(struct k_thread *thread) thread->base.thread_state &= ~_THREAD_PENDING; } +static inline bool z_is_thread_sleeping(struct k_thread *thread) +{ + return (thread->base.thread_state & _THREAD_SLEEPING) != 0U; +} + +static inline void z_mark_thread_as_sleeping(struct k_thread *thread) +{ + thread->base.thread_state |= _THREAD_SLEEPING; +} + +static inline void z_mark_thread_as_not_sleeping(struct k_thread *thread) +{ + thread->base.thread_state &= ~_THREAD_SLEEPING; +} + /* * This function tags the current thread as essential to system operation. * Exceptions raised by this thread will be treated as a fatal system error. @@ -186,17 +210,17 @@ static ALWAYS_INLINE bool should_preempt(struct k_thread *thread, return true; } - __ASSERT(arch_current_thread() != NULL, ""); + __ASSERT(_current != NULL, ""); /* Or if we're pended/suspended/dummy (duh) */ - if (z_is_thread_prevented_from_running(arch_current_thread())) { + if (z_is_thread_prevented_from_running(_current)) { return true; } /* Otherwise we have to be running a preemptible thread or * switching to a metairq */ - if (thread_is_preemptible(arch_current_thread()) || thread_is_metairq(thread)) { + if (thread_is_preemptible(_current) || thread_is_metairq(thread)) { return true; } diff --git a/kernel/include/priority_q.h b/kernel/include/priority_q.h index 679e3f9dbdc64..259d689dda75b 100644 --- a/kernel/include/priority_q.h +++ b/kernel/include/priority_q.h @@ -10,9 +10,6 @@ #include #include -extern int32_t z_sched_prio_cmp(struct k_thread *thread_1, - struct k_thread *thread_2); - bool z_priq_rb_lessthan(struct rbnode *a, struct rbnode *b); /* Dumb Scheduling */ @@ -20,6 +17,7 @@ bool z_priq_rb_lessthan(struct rbnode *a, struct rbnode *b); #define _priq_run_init z_priq_dumb_init #define _priq_run_add z_priq_dumb_add #define _priq_run_remove z_priq_dumb_remove +#define _priq_run_yield z_priq_dumb_yield # if defined(CONFIG_SCHED_CPU_MASK) # define _priq_run_best z_priq_dumb_mask_best # else @@ -30,21 +28,15 @@ bool z_priq_rb_lessthan(struct rbnode *a, struct rbnode *b); #define _priq_run_init z_priq_rb_init #define _priq_run_add z_priq_rb_add #define _priq_run_remove z_priq_rb_remove +#define _priq_run_yield z_priq_rb_yield #define _priq_run_best z_priq_rb_best /* Multi Queue Scheduling */ #elif defined(CONFIG_SCHED_MULTIQ) - -#if defined(CONFIG_64BIT) -#define NBITS 64 -#else -#define NBITS 32 -#endif /* CONFIG_64BIT */ #define _priq_run_init z_priq_mq_init #define _priq_run_add z_priq_mq_add #define _priq_run_remove z_priq_mq_remove +#define _priq_run_yield z_priq_mq_yield #define _priq_run_best z_priq_mq_best -static ALWAYS_INLINE void z_priq_mq_add(struct _priq_mq *pq, struct k_thread *thread); -static ALWAYS_INLINE void z_priq_mq_remove(struct _priq_mq *pq, struct k_thread *thread); #endif /* Scalable Wait Queue */ @@ -59,11 +51,74 @@ static ALWAYS_INLINE void z_priq_mq_remove(struct _priq_mq *pq, struct k_thread #define _priq_wait_best z_priq_dumb_best #endif +#if defined(CONFIG_64BIT) +#define NBITS 64 +#define TRAILING_ZEROS u64_count_trailing_zeros +#else +#define NBITS 32 +#define TRAILING_ZEROS u32_count_trailing_zeros +#endif /* CONFIG_64BIT */ + static ALWAYS_INLINE void z_priq_dumb_init(sys_dlist_t *pq) { sys_dlist_init(pq); } +/* + * Return value same as e.g. memcmp + * > 0 -> thread 1 priority > thread 2 priority + * = 0 -> thread 1 priority == thread 2 priority + * < 0 -> thread 1 priority < thread 2 priority + * Do not rely on the actual value returned aside from the above. + * (Again, like memcmp.) + */ +static ALWAYS_INLINE int32_t z_sched_prio_cmp(struct k_thread *thread_1, struct k_thread *thread_2) +{ + /* `prio` is <32b, so the below cannot overflow. */ + int32_t b1 = thread_1->base.prio; + int32_t b2 = thread_2->base.prio; + + if (b1 != b2) { + return b2 - b1; + } + +#ifdef CONFIG_SCHED_DEADLINE + /* If we assume all deadlines live within the same "half" of + * the 32 bit modulus space (this is a documented API rule), + * then the latest deadline in the queue minus the earliest is + * guaranteed to be (2's complement) non-negative. We can + * leverage that to compare the values without having to check + * the current time. + */ + uint32_t d1 = thread_1->base.prio_deadline; + uint32_t d2 = thread_2->base.prio_deadline; + + if (d1 != d2) { + /* Sooner deadline means higher effective priority. + * Doing the calculation with unsigned types and casting + * to signed isn't perfect, but at least reduces this + * from UB on overflow to impdef. + */ + return (int32_t)(d2 - d1); + } +#endif /* CONFIG_SCHED_DEADLINE */ + return 0; +} + +static ALWAYS_INLINE void z_priq_dumb_add(sys_dlist_t *pq, struct k_thread *thread) +{ + struct k_thread *t; + + SYS_DLIST_FOR_EACH_CONTAINER(pq, t, base.qnode_dlist) { + if (z_sched_prio_cmp(thread, t) > 0) { + sys_dlist_insert(&t->base.qnode_dlist, &thread->base.qnode_dlist); + return; + } + } + + sys_dlist_append(pq, &thread->base.qnode_dlist); +} + static ALWAYS_INLINE void z_priq_dumb_remove(sys_dlist_t *pq, struct k_thread *thread) { ARG_UNUSED(pq); @@ -71,6 +126,37 @@ static ALWAYS_INLINE void z_priq_dumb_remove(sys_dlist_t *pq, struct k_thread *t sys_dlist_remove(&thread->base.qnode_dlist); } +static ALWAYS_INLINE void z_priq_dumb_yield(sys_dlist_t *pq) +{ +#ifndef CONFIG_SMP + sys_dnode_t *n; + + n = sys_dlist_peek_next_no_check(pq, &_current->base.qnode_dlist); + + sys_dlist_dequeue(&_current->base.qnode_dlist); + + struct k_thread *t; + + /* + * As it is possible that the current thread was not at the head of + * the run queue, start searching from the present position for where + * to re-insert it. + */ + + while (n != NULL) { + t = CONTAINER_OF(n, struct k_thread, base.qnode_dlist); + if (z_sched_prio_cmp(_current, t) > 0) { + sys_dlist_insert(&t->base.qnode_dlist, + &_current->base.qnode_dlist); + return; + } + n = sys_dlist_peek_next_no_check(pq, n); + } + + sys_dlist_append(pq, &_current->base.qnode_dlist); +#endif +} + static ALWAYS_INLINE struct k_thread *z_priq_dumb_best(sys_dlist_t *pq) { struct k_thread *thread = NULL; @@ -82,6 +168,23 @@ static ALWAYS_INLINE struct k_thread *z_priq_dumb_best(sys_dlist_t *pq) return thread; } +#ifdef CONFIG_SCHED_CPU_MASK +static ALWAYS_INLINE struct k_thread *z_priq_dumb_mask_best(sys_dlist_t *pq) +{ + /* With masks enabled we need to be prepared to walk the list + * looking for one we can run + */ + struct k_thread *thread; + + SYS_DLIST_FOR_EACH_CONTAINER(pq, thread, base.qnode_dlist) { + if ((thread->base.cpu_mask & BIT(_current_cpu->id)) != 0) { + return thread; + } + } + return NULL; +} +#endif /* CONFIG_SCHED_CPU_MASK */ + static ALWAYS_INLINE void z_priq_rb_init(struct _priq_rb *pq) { *pq = (struct _priq_rb) { @@ -123,6 +226,14 @@ static ALWAYS_INLINE void z_priq_rb_remove(struct _priq_rb *pq, struct k_thread } } +static ALWAYS_INLINE void z_priq_rb_yield(struct _priq_rb *pq) +{ +#ifndef CONFIG_SMP + z_priq_rb_remove(pq, _current); + z_priq_rb_add(pq, _current); +#endif +} + static ALWAYS_INLINE struct k_thread *z_priq_rb_best(struct _priq_rb *pq) { struct k_thread *thread = NULL; @@ -134,34 +245,6 @@ static ALWAYS_INLINE struct k_thread *z_priq_rb_best(struct _priq_rb *pq) return thread; } -static ALWAYS_INLINE struct k_thread *z_priq_mq_best(struct _priq_mq *pq) -{ - struct k_thread *thread = NULL; - - for (int i = 0; i < PRIQ_BITMAP_SIZE; ++i) { - if (!pq->bitmask[i]) { - continue; - } - -#ifdef CONFIG_64BIT - sys_dlist_t *l = &pq->queues[i * 64 + u64_count_trailing_zeros(pq->bitmask[i])]; -#else - sys_dlist_t *l = &pq->queues[i * 32 + u32_count_trailing_zeros(pq->bitmask[i])]; -#endif - sys_dnode_t *n = sys_dlist_peek_head(l); - - if (n != NULL) { - thread = CONTAINER_OF(n, struct k_thread, base.qnode_dlist); - break; - } - } - - return thread; -} - - -#ifdef CONFIG_SCHED_MULTIQ - struct prio_info { uint8_t offset_prio; uint8_t idx; @@ -179,11 +262,29 @@ static ALWAYS_INLINE struct prio_info get_prio_info(int8_t old_prio) return ret; } +static ALWAYS_INLINE unsigned int z_priq_mq_best_queue_index(struct _priq_mq *pq) +{ + unsigned int i = 0; + + do { + if (likely(pq->bitmask[i])) { + return i * NBITS + TRAILING_ZEROS(pq->bitmask[i]); + } + i++; + } while (i < PRIQ_BITMAP_SIZE); + + return K_NUM_THREAD_PRIO - 1; +} + static ALWAYS_INLINE void z_priq_mq_init(struct _priq_mq *q) { for (int i = 0; i < ARRAY_SIZE(q->queues); i++) { sys_dlist_init(&q->queues[i]); } + +#ifndef CONFIG_SMP + q->cached_queue_index = K_NUM_THREAD_PRIO - 1; +#endif } static ALWAYS_INLINE void z_priq_mq_add(struct _priq_mq *pq, @@ -193,6 +294,12 @@ static ALWAYS_INLINE void z_priq_mq_add(struct _priq_mq *pq, sys_dlist_append(&pq->queues[pos.offset_prio], &thread->base.qnode_dlist); pq->bitmask[pos.idx] |= BIT(pos.bit); + +#ifndef CONFIG_SMP + if (pos.offset_prio < pq->cached_queue_index) { + pq->cached_queue_index = pos.offset_prio; + } +#endif } static ALWAYS_INLINE void z_priq_mq_remove(struct _priq_mq *pq, @@ -200,49 +307,41 @@ static ALWAYS_INLINE void z_priq_mq_remove(struct _priq_mq *pq, { struct prio_info pos = get_prio_info(thread->base.prio); - sys_dlist_remove(&thread->base.qnode_dlist); - if (sys_dlist_is_empty(&pq->queues[pos.offset_prio])) { + sys_dlist_dequeue(&thread->base.qnode_dlist); + if (unlikely(sys_dlist_is_empty(&pq->queues[pos.offset_prio]))) { pq->bitmask[pos.idx] &= ~BIT(pos.bit); +#ifndef CONFIG_SMP + pq->cached_queue_index = z_priq_mq_best_queue_index(pq); +#endif } } -#endif /* CONFIG_SCHED_MULTIQ */ - - -#ifdef CONFIG_SCHED_CPU_MASK -static ALWAYS_INLINE struct k_thread *z_priq_dumb_mask_best(sys_dlist_t *pq) +static ALWAYS_INLINE void z_priq_mq_yield(struct _priq_mq *pq) { - /* With masks enabled we need to be prepared to walk the list - * looking for one we can run - */ - struct k_thread *thread; +#ifndef CONFIG_SMP + struct prio_info pos = get_prio_info(_current->base.prio); - SYS_DLIST_FOR_EACH_CONTAINER(pq, thread, base.qnode_dlist) { - if ((thread->base.cpu_mask & BIT(_current_cpu->id)) != 0) { - return thread; - } - } - return NULL; + sys_dlist_dequeue(&_current->base.qnode_dlist); + sys_dlist_append(&pq->queues[pos.offset_prio], + &_current->base.qnode_dlist); +#endif } -#endif /* CONFIG_SCHED_CPU_MASK */ - -#if defined(CONFIG_SCHED_DUMB) || defined(CONFIG_WAITQ_DUMB) -static ALWAYS_INLINE void z_priq_dumb_add(sys_dlist_t *pq, - struct k_thread *thread) +static ALWAYS_INLINE struct k_thread *z_priq_mq_best(struct _priq_mq *pq) { - struct k_thread *t; +#ifdef CONFIG_SMP + unsigned int index = z_priq_mq_best_queue_index(pq); +#else + unsigned int index = pq->cached_queue_index; +#endif - SYS_DLIST_FOR_EACH_CONTAINER(pq, t, base.qnode_dlist) { - if (z_sched_prio_cmp(thread, t) > 0) { - sys_dlist_insert(&t->base.qnode_dlist, - &thread->base.qnode_dlist); - return; - } + sys_dnode_t *n = sys_dlist_peek_head(&pq->queues[index]); + + if (likely(n != NULL)) { + return CONTAINER_OF(n, struct k_thread, base.qnode_dlist); } - sys_dlist_append(pq, &thread->base.qnode_dlist); + return NULL; } -#endif /* CONFIG_SCHED_DUMB || CONFIG_WAITQ_DUMB */ #endif /* ZEPHYR_KERNEL_INCLUDE_PRIORITY_Q_H_ */ diff --git a/kernel/include/timeout_q.h b/kernel/include/timeout_q.h index a62242a9f3cfb..b3c3e61cd9fc8 100644 --- a/kernel/include/timeout_q.h +++ b/kernel/include/timeout_q.h @@ -49,9 +49,9 @@ static inline void z_add_thread_timeout(struct k_thread *thread, k_timeout_t tic z_add_timeout(&thread->base.timeout, z_thread_timeout, ticks); } -static inline int z_abort_thread_timeout(struct k_thread *thread) +static inline void z_abort_thread_timeout(struct k_thread *thread) { - return z_abort_timeout(&thread->base.timeout); + z_abort_timeout(&thread->base.timeout); } int32_t z_get_next_timeout_expiry(void); @@ -62,7 +62,7 @@ k_ticks_t z_timeout_remaining(const struct _timeout *timeout); /* Stubs when !CONFIG_SYS_CLOCK_EXISTS */ #define z_init_thread_timeout(thread_base) do {} while (false) -#define z_abort_thread_timeout(to) (0) +#define z_abort_thread_timeout(to) do {} while (false) #define z_is_inactive_timeout(to) 1 #define z_get_next_timeout_expiry() ((int32_t) K_TICKS_FOREVER) #define z_set_timeout_expiry(ticks, is_idle) do {} while (false) diff --git a/kernel/init.c b/kernel/init.c index 0327107129c22..d6c4fb3c70cca 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -289,13 +289,13 @@ void z_bss_zero_pinned(void) } #endif /* CONFIG_LINKER_USE_PINNED_SECTION */ -#ifdef CONFIG_STACK_CANARIES +#ifdef CONFIG_REQUIRES_STACK_CANARIES #ifdef CONFIG_STACK_CANARIES_TLS extern Z_THREAD_LOCAL volatile uintptr_t __stack_chk_guard; #else extern volatile uintptr_t __stack_chk_guard; #endif /* CONFIG_STACK_CANARIES_TLS */ -#endif /* CONFIG_STACK_CANARIES */ +#endif /* CONFIG_REQUIRES_STACK_CANARIES */ /* LCOV_EXCL_STOP */ @@ -598,7 +598,7 @@ static void init_idle_thread(int i) stack_size, idle, &_kernel.cpus[i], NULL, NULL, K_IDLE_PRIO, K_ESSENTIAL, tname); - z_mark_thread_as_not_suspended(thread); + z_mark_thread_as_not_sleeping(thread); #ifdef CONFIG_SMP thread->base.is_idle = 1U; @@ -675,7 +675,7 @@ static char *prepare_multithreading(void) NULL, NULL, NULL, CONFIG_MAIN_THREAD_PRIORITY, K_ESSENTIAL, "main"); - z_mark_thread_as_not_suspended(&z_main_thread); + z_mark_thread_as_not_sleeping(&z_main_thread); z_ready_thread(&z_main_thread); z_init_cpu(0); @@ -778,13 +778,13 @@ FUNC_NORETURN void z_cstart(void) #endif z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_2); -#ifdef CONFIG_STACK_CANARIES +#ifdef CONFIG_REQUIRES_STACK_CANARIES uintptr_t stack_guard; z_early_rand_get((uint8_t *)&stack_guard, sizeof(stack_guard)); __stack_chk_guard = stack_guard; __stack_chk_guard <<= 8; -#endif /* CONFIG_STACK_CANARIES */ +#endif /* CONFIG_REQUIRES_STACK_CANARIES */ #ifdef CONFIG_TIMING_FUNCTIONS_NEED_AT_BOOT timing_init(); diff --git a/kernel/ipi.c b/kernel/ipi.c index 59c2eba669867..ee01c4594251c 100644 --- a/kernel/ipi.c +++ b/kernel/ipi.c @@ -101,7 +101,7 @@ void z_sched_ipi(void) #endif /* CONFIG_TRACE_SCHED_IPI */ #ifdef CONFIG_TIMESLICING - if (thread_is_sliceable(arch_current_thread())) { + if (thread_is_sliceable(_current)) { z_time_slice(); } #endif /* CONFIG_TIMESLICING */ diff --git a/kernel/kheap.c b/kernel/kheap.c index 55b9feffced90..245558c85fefd 100644 --- a/kernel/kheap.c +++ b/kernel/kheap.c @@ -15,6 +15,7 @@ void k_heap_init(struct k_heap *heap, void *mem, size_t bytes) { z_waitq_init(&heap->wait_q); + heap->lock = (struct k_spinlock) {}; sys_heap_init(&heap->heap, mem, bytes); SYS_PORT_TRACING_OBJ_INIT(k_heap, heap); @@ -116,6 +117,25 @@ void *k_heap_alloc(struct k_heap *heap, size_t bytes, k_timeout_t timeout) return ret; } +void *k_heap_calloc(struct k_heap *heap, size_t num, size_t size, k_timeout_t timeout) +{ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_heap, calloc, heap, timeout); + + void *ret = NULL; + size_t bounds = 0U; + + if (!size_mul_overflow(num, size, &bounds)) { + ret = k_heap_alloc(heap, bounds, timeout); + } + if (ret != NULL) { + (void)memset(ret, 0, bounds); + } + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_heap, calloc, heap, timeout, ret); + + return ret; +} + void *k_heap_realloc(struct k_heap *heap, void *ptr, size_t bytes, k_timeout_t timeout) { k_timepoint_t end = sys_timepoint_calc(timeout); diff --git a/kernel/mailbox.c b/kernel/mailbox.c index 17ebfb2ea0351..d7da8e3c8e49a 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -216,7 +216,7 @@ static int mbox_message_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, k_spinlock_key_t key; /* save sender id so it can be used during message matching */ - tx_msg->rx_source_thread = arch_current_thread(); + tx_msg->rx_source_thread = _current; /* finish readying sending thread (actual or dummy) for send */ sending_thread = tx_msg->_syncing_thread; @@ -296,7 +296,7 @@ int k_mbox_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, k_timeout_t timeout) { /* configure things for a synchronous send, then send the message */ - tx_msg->_syncing_thread = arch_current_thread(); + tx_msg->_syncing_thread = _current; SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_mbox, put, mbox, timeout); @@ -321,7 +321,7 @@ void k_mbox_async_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, */ mbox_async_alloc(&async); - async->thread.prio = arch_current_thread()->base.prio; + async->thread.prio = _current->base.prio; async->tx_msg = *tx_msg; async->tx_msg._syncing_thread = (struct k_thread *)&async->thread; @@ -388,7 +388,7 @@ int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, void *buffer, int result; /* save receiver id so it can be used during message matching */ - rx_msg->tx_target_thread = arch_current_thread(); + rx_msg->tx_target_thread = _current; /* search mailbox's tx queue for a compatible sender */ key = k_spin_lock(&mbox->lock); @@ -425,7 +425,7 @@ int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, void *buffer, SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_mbox, get, mbox, timeout); /* wait until a matching sender appears or a timeout occurs */ - arch_current_thread()->base.swap_data = rx_msg; + _current->base.swap_data = rx_msg; result = z_pend_curr(&mbox->lock, key, &mbox->rx_msg_queue, timeout); /* consume message data immediately, if needed */ diff --git a/kernel/mem_domain.c b/kernel/mem_domain.c index 1fc8a36a94de2..16b337acf011d 100644 --- a/kernel/mem_domain.c +++ b/kernel/mem_domain.c @@ -299,7 +299,7 @@ void z_mem_domain_init_thread(struct k_thread *thread) k_spinlock_key_t key = k_spin_lock(&z_mem_domain_lock); /* New threads inherit memory domain configuration from parent */ - ret = add_thread_locked(arch_current_thread()->mem_domain_info.mem_domain, thread); + ret = add_thread_locked(_current->mem_domain_info.mem_domain, thread); __ASSERT_NO_MSG(ret == 0); ARG_UNUSED(ret); diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index 45ba08e27cbe2..a7da66d374fab 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -206,6 +206,10 @@ int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, static bool slab_ptr_is_good(struct k_mem_slab *slab, const void *ptr) { + if (!IS_ENABLED(CONFIG_MEM_SLAB_POINTER_VALIDATE)) { + return true; + } + const char *p = ptr; ptrdiff_t offset = p - slab->buffer; @@ -248,7 +252,7 @@ int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, k_timeout_t timeout) /* wait for a free block or timeout */ result = z_pend_curr(&slab->lock, key, &slab->wait_q, timeout); if (result == 0) { - *mem = arch_current_thread()->base.swap_data; + *mem = _current->base.swap_data; } SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mem_slab, alloc, slab, timeout, result); @@ -274,7 +278,7 @@ void k_mem_slab_free(struct k_mem_slab *slab, void *mem) k_spinlock_key_t key = k_spin_lock(&slab->lock); SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_mem_slab, free, slab); - if ((slab->free_list == NULL) && IS_ENABLED(CONFIG_MULTITHREADING)) { + if (unlikely(slab->free_list == NULL) && IS_ENABLED(CONFIG_MULTITHREADING)) { struct k_thread *pending_thread = z_unpend_first_thread(&slab->wait_q); if (unlikely(pending_thread != NULL)) { diff --git a/kernel/mempool.c b/kernel/mempool.c index 7e9a7677f71ab..d8926c63ed940 100644 --- a/kernel/mempool.c +++ b/kernel/mempool.c @@ -165,7 +165,7 @@ void *z_thread_aligned_alloc(size_t align, size_t size) if (k_is_in_isr()) { heap = _SYSTEM_HEAP; } else { - heap = arch_current_thread()->resource_pool; + heap = _current->resource_pool; } if (heap != NULL) { diff --git a/kernel/mmu.c b/kernel/mmu.c index fc55096d44b53..617b02997dd9c 100644 --- a/kernel/mmu.c +++ b/kernel/mmu.c @@ -1674,7 +1674,7 @@ static bool do_page_fault(void *addr, bool pin) #endif /* CONFIG_DEMAND_PAGING_ALLOW_IRQ */ key = k_spin_lock(&z_mm_lock); - faulting_thread = arch_current_thread(); + faulting_thread = _current; status = arch_page_location_get(addr, &page_in_location); if (status == ARCH_PAGE_LOCATION_BAD) { diff --git a/kernel/msg_q.c b/kernel/msg_q.c index 190b8c4e78e32..7b8686ffa630c 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -29,12 +29,16 @@ static struct k_obj_type obj_type_msgq; #endif /* CONFIG_OBJ_CORE_MSGQ */ -#ifdef CONFIG_POLL -static inline void handle_poll_events(struct k_msgq *msgq, uint32_t state) +static inline bool handle_poll_events(struct k_msgq *msgq) { - z_handle_obj_poll_events(&msgq->poll_events, state); -} +#ifdef CONFIG_POLL + return z_handle_obj_poll_events(&msgq->poll_events, + K_POLL_STATE_MSGQ_DATA_AVAILABLE); +#else + ARG_UNUSED(msgq); + return false; #endif /* CONFIG_POLL */ +} void k_msgq_init(struct k_msgq *msgq, char *buffer, size_t msg_size, uint32_t max_msgs) @@ -128,6 +132,7 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout struct k_thread *pending_thread; k_spinlock_key_t key; int result; + bool resched = false; key = k_spin_lock(&msgq->lock); @@ -137,16 +142,13 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout /* message queue isn't full */ pending_thread = z_unpend_first_thread(&msgq->wait_q); if (unlikely(pending_thread != NULL)) { - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_msgq, put, msgq, timeout, 0); + resched = true; /* give message to waiting thread */ - (void)memcpy(pending_thread->base.swap_data, data, - msgq->msg_size); + (void)memcpy(pending_thread->base.swap_data, data, msgq->msg_size); /* wake up waiting thread */ arch_thread_return_value_set(pending_thread, 0); z_ready_thread(pending_thread); - z_reschedule(&msgq->lock, key); - return 0; } else { /* put message in queue */ __ASSERT_NO_MSG(msgq->write_ptr >= msgq->buffer_start && @@ -157,9 +159,7 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout msgq->write_ptr = msgq->buffer_start; } msgq->used_msgs++; -#ifdef CONFIG_POLL - handle_poll_events(msgq, K_POLL_STATE_MSGQ_DATA_AVAILABLE); -#endif /* CONFIG_POLL */ + resched = handle_poll_events(msgq); } result = 0; } else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { @@ -169,7 +169,7 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_msgq, put, msgq, timeout); /* wait for put message success, failure, or timeout */ - arch_current_thread()->base.swap_data = (void *) data; + _current->base.swap_data = (void *) data; result = z_pend_curr(&msgq->lock, key, &msgq->wait_q, timeout); SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_msgq, put, msgq, timeout, result); @@ -178,7 +178,11 @@ int z_impl_k_msgq_put(struct k_msgq *msgq, const void *data, k_timeout_t timeout SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_msgq, put, msgq, timeout, result); - k_spin_unlock(&msgq->lock, key); + if (resched) { + z_reschedule(&msgq->lock, key); + } else { + k_spin_unlock(&msgq->lock, key); + } return result; } @@ -220,6 +224,7 @@ int z_impl_k_msgq_get(struct k_msgq *msgq, void *data, k_timeout_t timeout) k_spinlock_key_t key; struct k_thread *pending_thread; int result; + bool resched = false; key = k_spin_lock(&msgq->lock); @@ -253,11 +258,7 @@ int z_impl_k_msgq_get(struct k_msgq *msgq, void *data, k_timeout_t timeout) /* wake up waiting thread */ arch_thread_return_value_set(pending_thread, 0); z_ready_thread(pending_thread); - z_reschedule(&msgq->lock, key); - - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_msgq, get, msgq, timeout, 0); - - return 0; + resched = true; } result = 0; } else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { @@ -267,7 +268,7 @@ int z_impl_k_msgq_get(struct k_msgq *msgq, void *data, k_timeout_t timeout) SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_msgq, get, msgq, timeout); /* wait for get message success or timeout */ - arch_current_thread()->base.swap_data = data; + _current->base.swap_data = data; result = z_pend_curr(&msgq->lock, key, &msgq->wait_q, timeout); SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_msgq, get, msgq, timeout, result); @@ -276,7 +277,11 @@ int z_impl_k_msgq_get(struct k_msgq *msgq, void *data, k_timeout_t timeout) SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_msgq, get, msgq, timeout, result); - k_spin_unlock(&msgq->lock, key); + if (resched) { + z_reschedule(&msgq->lock, key); + } else { + k_spin_unlock(&msgq->lock, key); + } return result; } @@ -377,22 +382,29 @@ void z_impl_k_msgq_purge(struct k_msgq *msgq) { k_spinlock_key_t key; struct k_thread *pending_thread; + bool resched = false; key = k_spin_lock(&msgq->lock); SYS_PORT_TRACING_OBJ_FUNC(k_msgq, purge, msgq); /* wake up any threads that are waiting to write */ - for (pending_thread = z_unpend_first_thread(&msgq->wait_q); pending_thread != NULL; - pending_thread = z_unpend_first_thread(&msgq->wait_q)) { + for (pending_thread = z_unpend_first_thread(&msgq->wait_q); + pending_thread != NULL; + pending_thread = z_unpend_first_thread(&msgq->wait_q)) { arch_thread_return_value_set(pending_thread, -ENOMSG); z_ready_thread(pending_thread); + resched = true; } msgq->used_msgs = 0; msgq->read_ptr = msgq->write_ptr; - z_reschedule(&msgq->lock, key); + if (resched) { + z_reschedule(&msgq->lock, key); + } else { + k_spin_unlock(&msgq->lock, key); + } } #ifdef CONFIG_USERSPACE diff --git a/kernel/mutex.c b/kernel/mutex.c index 2fbede19e2caf..ce76e5a2af545 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -114,17 +114,17 @@ int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) key = k_spin_lock(&lock); - if (likely((mutex->lock_count == 0U) || (mutex->owner == arch_current_thread()))) { + if (likely((mutex->lock_count == 0U) || (mutex->owner == _current))) { mutex->owner_orig_prio = (mutex->lock_count == 0U) ? - arch_current_thread()->base.prio : + _current->base.prio : mutex->owner_orig_prio; mutex->lock_count++; - mutex->owner = arch_current_thread(); + mutex->owner = _current; LOG_DBG("%p took mutex %p, count: %d, orig prio: %d", - arch_current_thread(), mutex, mutex->lock_count, + _current, mutex, mutex->lock_count, mutex->owner_orig_prio); k_spin_unlock(&lock, key); @@ -144,7 +144,7 @@ int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_mutex, lock, mutex, timeout); - new_prio = new_prio_for_inheritance(arch_current_thread()->base.prio, + new_prio = new_prio_for_inheritance(_current->base.prio, mutex->owner->base.prio); LOG_DBG("adjusting prio up on mutex %p", mutex); @@ -157,7 +157,7 @@ int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) LOG_DBG("on mutex %p got_mutex value: %d", mutex, got_mutex); - LOG_DBG("%p got mutex %p (y/n): %c", arch_current_thread(), mutex, + LOG_DBG("%p got mutex %p (y/n): %c", _current, mutex, got_mutex ? 'y' : 'n'); if (got_mutex == 0) { @@ -167,7 +167,7 @@ int z_impl_k_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout) /* timed out */ - LOG_DBG("%p timeout on mutex %p", arch_current_thread(), mutex); + LOG_DBG("%p timeout on mutex %p", _current, mutex); key = k_spin_lock(&lock); @@ -224,7 +224,7 @@ int z_impl_k_mutex_unlock(struct k_mutex *mutex) /* * The current thread does not own the mutex. */ - CHECKIF(mutex->owner != arch_current_thread()) { + CHECKIF(mutex->owner != _current) { SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_mutex, unlock, mutex, -EPERM); return -EPERM; diff --git a/kernel/pipe.c b/kernel/pipe.c new file mode 100644 index 0000000000000..09582260ab51f --- /dev/null +++ b/kernel/pipe.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2024 MĂĽns Ansgariusson + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_OBJ_CORE_PIPE +static struct k_obj_type obj_type_pipe; +#endif /* CONFIG_OBJ_CORE_PIPE */ + +static inline bool pipe_closed(struct k_pipe *pipe) +{ + return (pipe->flags & PIPE_FLAG_OPEN) == 0; +} + +static inline bool pipe_resetting(struct k_pipe *pipe) +{ + return (pipe->flags & PIPE_FLAG_RESET) != 0; +} + +static inline bool pipe_full(struct k_pipe *pipe) +{ + return ring_buf_space_get(&pipe->buf) == 0; +} + +static inline bool pipe_empty(struct k_pipe *pipe) +{ + return ring_buf_is_empty(&pipe->buf); +} + +static int wait_for(_wait_q_t *waitq, struct k_pipe *pipe, k_spinlock_key_t *key, + k_timepoint_t time_limit, bool *need_resched) +{ + k_timeout_t timeout = sys_timepoint_timeout(time_limit); + int rc; + + if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { + return -EAGAIN; + } + + pipe->waiting++; + *need_resched = false; + if (waitq == &pipe->space) { + SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_pipe, write, pipe, timeout); + } else { + SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_pipe, read, pipe, timeout); + } + rc = z_pend_curr(&pipe->lock, *key, waitq, timeout); + *key = k_spin_lock(&pipe->lock); + pipe->waiting--; + if (unlikely(pipe_resetting(pipe))) { + if (pipe->waiting == 0) { + pipe->flags &= ~PIPE_FLAG_RESET; + } + rc = -ECANCELED; + } + + return rc; +} + +void z_impl_k_pipe_init(struct k_pipe *pipe, uint8_t *buffer, size_t buffer_size) +{ + ring_buf_init(&pipe->buf, buffer_size, buffer); + pipe->flags = PIPE_FLAG_OPEN; + pipe->waiting = 0; + + pipe->lock = (struct k_spinlock){}; + z_waitq_init(&pipe->data); + z_waitq_init(&pipe->space); + k_object_init(pipe); + +#ifdef CONFIG_POLL + sys_dlist_init(&pipe->poll_events); +#endif /* CONFIG_POLL */ +#ifdef CONFIG_OBJ_CORE_PIPE + k_obj_core_init_and_link(K_OBJ_CORE(pipe), &obj_type_pipe); +#endif /* CONFIG_OBJ_CORE_PIPE */ + SYS_PORT_TRACING_OBJ_INIT(k_pipe, pipe, buffer, buffer_size); +} + +struct pipe_buf_spec { + uint8_t * const data; + const size_t len; + size_t used; +}; + +static size_t copy_to_pending_readers(struct k_pipe *pipe, bool *need_resched, + const uint8_t *data, size_t len) +{ + struct k_thread *reader = NULL; + struct pipe_buf_spec *reader_buf; + size_t copy_size, written = 0; + + /* + * Attempt a direct data copy to waiting readers if any. + * The copy has to be done under the scheduler lock to ensure all the + * needed data is copied to the target thread whose buffer spec lives + * on that thread's stack, and then the thread unpended only if it + * received all the data it wanted, without racing with a potential + * thread timeout/cancellation event. + */ + do { + LOCK_SCHED_SPINLOCK { + reader = _priq_wait_best(&pipe->data.waitq); + if (reader == NULL) { + K_SPINLOCK_BREAK; + } + + reader_buf = reader->base.swap_data; + copy_size = MIN(len - written, + reader_buf->len - reader_buf->used); + memcpy(&reader_buf->data[reader_buf->used], + &data[written], copy_size); + written += copy_size; + reader_buf->used += copy_size; + + if (reader_buf->used < reader_buf->len) { + /* This reader wants more: don't unpend. */ + reader = NULL; + } else { + /* + * This reader has received all the data + * it was waiting for: wake it up with + * the scheduler lock still held. + */ + unpend_thread_no_timeout(reader); + z_abort_thread_timeout(reader); + } + } + if (reader != NULL) { + /* rest of thread wake-up outside the scheduler lock */ + z_thread_return_value_set_with_data(reader, 0, NULL); + z_ready_thread(reader); + *need_resched = true; + } + } while (reader != NULL && written < len); + + return written; +} + +int z_impl_k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, k_timeout_t timeout) +{ + int rc; + size_t written = 0; + k_timepoint_t end = sys_timepoint_calc(timeout); + k_spinlock_key_t key = k_spin_lock(&pipe->lock); + bool need_resched = false; + + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_pipe, write, pipe, data, len, timeout); + + if (unlikely(pipe_resetting(pipe))) { + rc = -ECANCELED; + goto exit; + } + + for (;;) { + if (unlikely(pipe_closed(pipe))) { + rc = -EPIPE; + break; + } + + if (pipe_empty(pipe)) { + if (IS_ENABLED(CONFIG_KERNEL_COHERENCE)) { + /* + * Systems that enabled this option don't have + * their stacks in coherent memory. Given our + * pipe_buf_spec is stored on the stack, and + * readers may also have their destination + * buffer on their stack too, it is not worth + * supporting direct-to-readers copy with them. + * Simply wake up all pending readers instead. + */ + need_resched = z_sched_wake_all(&pipe->data, 0, NULL); + } else if (pipe->waiting != 0) { + written += copy_to_pending_readers(pipe, &need_resched, + &data[written], + len - written); + if (written >= len) { + rc = written; + break; + } + } +#ifdef CONFIG_POLL + z_handle_obj_poll_events(&pipe->poll_events, + K_POLL_STATE_PIPE_DATA_AVAILABLE); +#endif /* CONFIG_POLL */ + } + + written += ring_buf_put(&pipe->buf, &data[written], len - written); + if (likely(written == len)) { + rc = written; + break; + } + + rc = wait_for(&pipe->space, pipe, &key, end, &need_resched); + if (rc != 0) { + if (rc == -EAGAIN) { + rc = written ? written : -EAGAIN; + } + break; + } + } +exit: + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_pipe, write, pipe, rc); + if (need_resched) { + z_reschedule(&pipe->lock, key); + } else { + k_spin_unlock(&pipe->lock, key); + } + return rc; +} + +int z_impl_k_pipe_read(struct k_pipe *pipe, uint8_t *data, size_t len, k_timeout_t timeout) +{ + struct pipe_buf_spec buf = { data, len, 0 }; + int rc; + k_timepoint_t end = sys_timepoint_calc(timeout); + k_spinlock_key_t key = k_spin_lock(&pipe->lock); + bool need_resched = false; + + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_pipe, read, pipe, data, len, timeout); + + if (unlikely(pipe_resetting(pipe))) { + rc = -ECANCELED; + goto exit; + } + + for (;;) { + if (pipe_full(pipe)) { + /* One or more pending writers may exist. */ + need_resched = z_sched_wake_all(&pipe->space, 0, NULL); + } + + buf.used += ring_buf_get(&pipe->buf, &data[buf.used], len - buf.used); + if (likely(buf.used == len)) { + rc = buf.used; + break; + } + + if (unlikely(pipe_closed(pipe))) { + rc = buf.used ? buf.used : -EPIPE; + break; + } + + /* provide our "direct copy" info to potential writers */ + _current->base.swap_data = &buf; + + rc = wait_for(&pipe->data, pipe, &key, end, &need_resched); + if (rc != 0) { + if (rc == -EAGAIN) { + rc = buf.used ? buf.used : -EAGAIN; + } + break; + } + } +exit: + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_pipe, read, pipe, rc); + if (need_resched) { + z_reschedule(&pipe->lock, key); + } else { + k_spin_unlock(&pipe->lock, key); + } + return rc; +} + +void z_impl_k_pipe_reset(struct k_pipe *pipe) +{ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_pipe, reset, pipe); + K_SPINLOCK(&pipe->lock) { + ring_buf_reset(&pipe->buf); + if (likely(pipe->waiting != 0)) { + pipe->flags |= PIPE_FLAG_RESET; + z_sched_wake_all(&pipe->data, 0, NULL); + z_sched_wake_all(&pipe->space, 0, NULL); + } + } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_pipe, reset, pipe); +} + +void z_impl_k_pipe_close(struct k_pipe *pipe) +{ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_pipe, close, pipe); + K_SPINLOCK(&pipe->lock) { + pipe->flags = 0; + z_sched_wake_all(&pipe->data, 0, NULL); + z_sched_wake_all(&pipe->space, 0, NULL); + } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_pipe, close, pipe); +} + +#ifdef CONFIG_USERSPACE +void z_vrfy_k_pipe_init(struct k_pipe *pipe, uint8_t *buffer, size_t buffer_size) +{ + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, buffer_size)); + + z_impl_k_pipe_init(pipe, buffer, buffer_size); +} +#include + +int z_vrfy_k_pipe_read(struct k_pipe *pipe, uint8_t *data, size_t len, k_timeout_t timeout) +{ + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(data, len)); + + return z_impl_k_pipe_read(pipe, data, len, timeout); +} +#include + +int z_vrfy_k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, k_timeout_t timeout) +{ + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_MEMORY_READ(data, len)); + + return z_impl_k_pipe_write(pipe, data, len, timeout); +} +#include + +void z_vrfy_k_pipe_reset(struct k_pipe *pipe) +{ + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + z_impl_k_pipe_reset(pipe); +} +#include + +void z_vrfy_k_pipe_close(struct k_pipe *pipe) +{ + K_OOPS(K_SYSCALL_OBJ(pipe, K_OBJ_PIPE)); + z_impl_k_pipe_close(pipe); +} +#include +#endif /* CONFIG_USERSPACE */ + +#ifdef CONFIG_OBJ_CORE_PIPE +static int init_pipe_obj_core_list(void) +{ + /* Initialize pipe object type */ + z_obj_type_init(&obj_type_pipe, K_OBJ_TYPE_PIPE_ID, + offsetof(struct k_pipe, obj_core)); + + /* Initialize and link statically defined pipes */ + STRUCT_SECTION_FOREACH(k_pipe, pipe) { + k_obj_core_init_and_link(K_OBJ_CORE(pipe), &obj_type_pipe); + } + + return 0; +} + +SYS_INIT(init_pipe_obj_core_list, PRE_KERNEL_1, + CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); +#endif /* CONFIG_OBJ_CORE_PIPE */ diff --git a/kernel/pipes.c b/kernel/pipes.c index a9eef5a4f368c..11d0d936f6b0f 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -36,7 +36,7 @@ static struct k_obj_type obj_type_pipe; #endif /* CONFIG_OBJ_CORE_PIPE */ -void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size) +void z_impl_k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size) { pipe->buffer = buffer; pipe->size = size; @@ -46,7 +46,7 @@ void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size) pipe->lock = (struct k_spinlock){}; z_waitq_init(&pipe->wait_q.writers); z_waitq_init(&pipe->wait_q.readers); - SYS_PORT_TRACING_OBJ_INIT(k_pipe, pipe); + SYS_PORT_TRACING_OBJ_INIT(k_pipe, pipe, buffer, size); pipe->flags = 0; @@ -87,6 +87,15 @@ int z_impl_k_pipe_alloc_init(struct k_pipe *pipe, size_t size) } #ifdef CONFIG_USERSPACE +static inline void z_vrfy_k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size) +{ + K_OOPS(K_SYSCALL_OBJ_NEVER_INIT(pipe, K_OBJ_PIPE)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(buffer, size)); + + z_impl_k_pipe_init(pipe, buffer, size); +} +#include + static inline int z_vrfy_k_pipe_alloc_init(struct k_pipe *pipe, size_t size) { K_OOPS(K_SYSCALL_OBJ_NEVER_INIT(pipe, K_OBJ_PIPE)); @@ -96,12 +105,13 @@ static inline int z_vrfy_k_pipe_alloc_init(struct k_pipe *pipe, size_t size) #include #endif /* CONFIG_USERSPACE */ -static inline void handle_poll_events(struct k_pipe *pipe) +static inline bool handle_poll_events(struct k_pipe *pipe) { #ifdef CONFIG_POLL - z_handle_obj_poll_events(&pipe->poll_events, K_POLL_STATE_PIPE_DATA_AVAILABLE); + return z_handle_obj_poll_events(&pipe->poll_events, K_POLL_STATE_PIPE_DATA_AVAILABLE); #else ARG_UNUSED(pipe); + return false; #endif /* CONFIG_POLL */ } @@ -443,11 +453,11 @@ int z_impl_k_pipe_put(struct k_pipe *pipe, const void *data, * invoked from within an ISR as that is not safe to do. */ - src_desc = k_is_in_isr() ? &isr_desc : &arch_current_thread()->pipe_desc; + src_desc = k_is_in_isr() ? &isr_desc : &_current->pipe_desc; src_desc->buffer = (unsigned char *)data; src_desc->bytes_to_xfer = bytes_to_write; - src_desc->thread = arch_current_thread(); + src_desc->thread = _current; sys_dlist_append(&src_list, &src_desc->node); *bytes_written = pipe_write(pipe, &src_list, @@ -459,7 +469,7 @@ int z_impl_k_pipe_put(struct k_pipe *pipe, const void *data, */ if ((pipe->bytes_used != 0U) && (*bytes_written != 0U)) { - handle_poll_events(pipe); + reschedule_needed = handle_poll_events(pipe) || reschedule_needed; } /* @@ -488,7 +498,7 @@ int z_impl_k_pipe_put(struct k_pipe *pipe, const void *data, SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_pipe, put, pipe, timeout); - arch_current_thread()->base.swap_data = src_desc; + _current->base.swap_data = src_desc; z_sched_wait(&pipe->lock, key, &pipe->wait_q.writers, timeout, NULL); @@ -581,11 +591,11 @@ static int pipe_get_internal(k_spinlock_key_t key, struct k_pipe *pipe, * invoked from within an ISR as that is not safe to do. */ - dest_desc = k_is_in_isr() ? &isr_desc : &arch_current_thread()->pipe_desc; + dest_desc = k_is_in_isr() ? &isr_desc : &_current->pipe_desc; dest_desc->buffer = data; dest_desc->bytes_to_xfer = bytes_to_read; - dest_desc->thread = arch_current_thread(); + dest_desc->thread = _current; src_desc = (struct _pipe_desc *)sys_dlist_get(&src_list); while (src_desc != NULL) { @@ -674,7 +684,7 @@ static int pipe_get_internal(k_spinlock_key_t key, struct k_pipe *pipe, SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_pipe, get, pipe, timeout); - arch_current_thread()->base.swap_data = dest_desc; + _current->base.swap_data = dest_desc; z_sched_wait(&pipe->lock, key, &pipe->wait_q.readers, timeout, NULL); diff --git a/kernel/poll.c b/kernel/poll.c index 05e9fe10c3e06..a1930a6292fc1 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -87,13 +87,9 @@ static inline bool is_condition_met(struct k_poll_event *event, uint32_t *state) return true; } break; -#ifdef CONFIG_PIPES case K_POLL_TYPE_PIPE_DATA_AVAILABLE: - if (k_pipe_read_avail(event->pipe)) { - *state = K_POLL_STATE_PIPE_DATA_AVAILABLE; - return true; - } -#endif /* CONFIG_PIPES */ + *state = K_POLL_STATE_PIPE_DATA_AVAILABLE; + return true; case K_POLL_TYPE_IGNORE: break; default: @@ -154,12 +150,10 @@ static inline void register_event(struct k_poll_event *event, __ASSERT(event->msgq != NULL, "invalid message queue\n"); add_event(&event->msgq->poll_events, event, poller); break; -#ifdef CONFIG_PIPES case K_POLL_TYPE_PIPE_DATA_AVAILABLE: __ASSERT(event->pipe != NULL, "invalid pipe\n"); add_event(&event->pipe->poll_events, event, poller); break; -#endif /* CONFIG_PIPES */ case K_POLL_TYPE_IGNORE: /* nothing to do */ break; @@ -195,12 +189,10 @@ static inline void clear_event_registration(struct k_poll_event *event) __ASSERT(event->msgq != NULL, "invalid message queue\n"); remove_event = true; break; -#ifdef CONFIG_PIPES case K_POLL_TYPE_PIPE_DATA_AVAILABLE: __ASSERT(event->pipe != NULL, "invalid pipe\n"); remove_event = true; break; -#endif /* CONFIG_PIPES */ case K_POLL_TYPE_IGNORE: /* nothing to do */ break; @@ -290,7 +282,7 @@ int z_impl_k_poll(struct k_poll_event *events, int num_events, { int events_registered; k_spinlock_key_t key; - struct z_poller *poller = &arch_current_thread()->poller; + struct z_poller *poller = &_current->poller; poller->is_polling = true; poller->mode = MODE_POLL; @@ -413,11 +405,9 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, case K_POLL_TYPE_MSGQ_DATA_AVAILABLE: K_OOPS(K_SYSCALL_OBJ(e->msgq, K_OBJ_MSGQ)); break; -#ifdef CONFIG_PIPES case K_POLL_TYPE_PIPE_DATA_AVAILABLE: K_OOPS(K_SYSCALL_OBJ(e->pipe, K_OBJ_PIPE)); break; -#endif /* CONFIG_PIPES */ default: ret = -EINVAL; goto out_free; @@ -464,7 +454,7 @@ static int signal_poll_event(struct k_poll_event *event, uint32_t state) return retcode; } -void z_handle_obj_poll_events(sys_dlist_t *events, uint32_t state) +bool z_handle_obj_poll_events(sys_dlist_t *events, uint32_t state) { struct k_poll_event *poll_event; k_spinlock_key_t key = k_spin_lock(&lock); @@ -475,6 +465,8 @@ void z_handle_obj_poll_events(sys_dlist_t *events, uint32_t state) } k_spin_unlock(&lock, key); + + return (poll_event != NULL); } void z_impl_k_poll_signal_init(struct k_poll_signal *sig) @@ -675,7 +667,7 @@ int k_work_poll_submit_to_queue(struct k_work_q *work_q, __ASSERT(work_q != NULL, "NULL work_q\n"); __ASSERT(work != NULL, "NULL work\n"); __ASSERT(events != NULL, "NULL events\n"); - __ASSERT(num_events > 0, "zero events\n"); + __ASSERT(num_events >= 0, "<0 events\n"); SYS_PORT_TRACING_FUNC_ENTER(k_work_poll, submit_to_queue, work_q, work, timeout); diff --git a/kernel/queue.c b/kernel/queue.c index 09b224c9c9449..af6437879944f 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -84,13 +84,15 @@ static void prepare_thread_to_run(struct k_thread *thread, void *data) z_ready_thread(thread); } -static inline void handle_poll_events(struct k_queue *queue, uint32_t state) +static inline bool handle_poll_events(struct k_queue *queue, uint32_t state) { #ifdef CONFIG_POLL - z_handle_obj_poll_events(&queue->poll_events, state); + return z_handle_obj_poll_events(&queue->poll_events, state); #else ARG_UNUSED(queue); ARG_UNUSED(state); + + return false; #endif /* CONFIG_POLL */ } @@ -100,15 +102,22 @@ void z_impl_k_queue_cancel_wait(struct k_queue *queue) k_spinlock_key_t key = k_spin_lock(&queue->lock); struct k_thread *first_pending_thread; + bool resched = false; first_pending_thread = z_unpend_first_thread(&queue->wait_q); if (first_pending_thread != NULL) { + resched = true; prepare_thread_to_run(first_pending_thread, NULL); } - handle_poll_events(queue, K_POLL_STATE_CANCELLED); - z_reschedule(&queue->lock, key); + resched = handle_poll_events(queue, K_POLL_STATE_CANCELLED) || resched; + + if (resched) { + z_reschedule(&queue->lock, key); + } else { + k_spin_unlock(&queue->lock, key); + } } #ifdef CONFIG_USERSPACE @@ -125,6 +134,8 @@ static int32_t queue_insert(struct k_queue *queue, void *prev, void *data, { struct k_thread *first_pending_thread; k_spinlock_key_t key = k_spin_lock(&queue->lock); + int32_t result = 0; + bool resched = false; SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, queue_insert, queue, alloc); @@ -137,11 +148,8 @@ static int32_t queue_insert(struct k_queue *queue, void *prev, void *data, SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_queue, queue_insert, queue, alloc, K_FOREVER); prepare_thread_to_run(first_pending_thread, data); - z_reschedule(&queue->lock, key); - - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, queue_insert, queue, alloc, 0); - - return 0; + resched = true; + goto out; } /* Only need to actually allocate if no threads are pending */ @@ -150,12 +158,8 @@ static int32_t queue_insert(struct k_queue *queue, void *prev, void *data, anode = z_thread_malloc(sizeof(*anode)); if (anode == NULL) { - k_spin_unlock(&queue->lock, key); - - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, queue_insert, queue, alloc, - -ENOMEM); - - return -ENOMEM; + result = -ENOMEM; + goto out; } anode->data = data; sys_sfnode_init(&anode->node, 0x1); @@ -167,12 +171,18 @@ static int32_t queue_insert(struct k_queue *queue, void *prev, void *data, SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_queue, queue_insert, queue, alloc, K_FOREVER); sys_sflist_insert(&queue->data_q, prev, data); - handle_poll_events(queue, K_POLL_STATE_DATA_AVAILABLE); - z_reschedule(&queue->lock, key); + resched = handle_poll_events(queue, K_POLL_STATE_DATA_AVAILABLE); - SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, queue_insert, queue, alloc, 0); +out: + if (resched) { + z_reschedule(&queue->lock, key); + } else { + k_spin_unlock(&queue->lock, key); + } - return 0; + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, queue_insert, queue, alloc, result); + + return result; } void k_queue_insert(struct k_queue *queue, void *prev, void *data) @@ -247,6 +257,7 @@ static inline int32_t z_vrfy_k_queue_alloc_prepend(struct k_queue *queue, int k_queue_append_list(struct k_queue *queue, void *head, void *tail) { SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, append_list, queue); + bool resched = false; /* invalid head or tail of list */ CHECKIF((head == NULL) || (tail == NULL)) { @@ -263,6 +274,7 @@ int k_queue_append_list(struct k_queue *queue, void *head, void *tail) } while ((head != NULL) && (thread != NULL)) { + resched = true; prepare_thread_to_run(thread, head); head = *(void **)head; thread = z_unpend_first_thread(&queue->wait_q); @@ -274,8 +286,14 @@ int k_queue_append_list(struct k_queue *queue, void *head, void *tail) SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, append_list, queue, 0); - handle_poll_events(queue, K_POLL_STATE_DATA_AVAILABLE); - z_reschedule(&queue->lock, key); + resched = handle_poll_events(queue, K_POLL_STATE_DATA_AVAILABLE) || resched; + + if (resched) { + z_reschedule(&queue->lock, key); + } else { + k_spin_unlock(&queue->lock, key); + } + return 0; } @@ -346,9 +364,9 @@ void *z_impl_k_queue_get(struct k_queue *queue, k_timeout_t timeout) int ret = z_pend_curr(&queue->lock, key, &queue->wait_q, timeout); SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, get, queue, timeout, - (ret != 0) ? NULL : arch_current_thread()->base.swap_data); + (ret != 0) ? NULL : _current->base.swap_data); - return (ret != 0) ? NULL : arch_current_thread()->base.swap_data; + return (ret != 0) ? NULL : _current->base.swap_data; } bool k_queue_remove(struct k_queue *queue, void *data) diff --git a/kernel/sched.c b/kernel/sched.c index 3323adb05e273..6a7e89e8b8da5 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -31,12 +31,12 @@ extern struct k_thread *pending_current; struct k_spinlock _sched_spinlock; /* Storage to "complete" the context switch from an invalid/incomplete thread - * context (ex: exiting an ISR that aborted arch_current_thread()) + * context (ex: exiting an ISR that aborted _current) */ __incoherent struct k_thread _thread_dummy; static ALWAYS_INLINE void update_cache(int preempt_ok); -static void halt_thread(struct k_thread *thread, uint8_t new_state); +static ALWAYS_INLINE void halt_thread(struct k_thread *thread, uint8_t new_state); static void add_to_waitq_locked(struct k_thread *thread, _wait_q_t *wait_q); @@ -45,48 +45,6 @@ BUILD_ASSERT(CONFIG_NUM_COOP_PRIORITIES >= CONFIG_NUM_METAIRQ_PRIORITIES, "CONFIG_NUM_METAIRQ_PRIORITIES as Meta IRQs are just a special class of cooperative " "threads."); -/* - * Return value same as e.g. memcmp - * > 0 -> thread 1 priority > thread 2 priority - * = 0 -> thread 1 priority == thread 2 priority - * < 0 -> thread 1 priority < thread 2 priority - * Do not rely on the actual value returned aside from the above. - * (Again, like memcmp.) - */ -int32_t z_sched_prio_cmp(struct k_thread *thread_1, - struct k_thread *thread_2) -{ - /* `prio` is <32b, so the below cannot overflow. */ - int32_t b1 = thread_1->base.prio; - int32_t b2 = thread_2->base.prio; - - if (b1 != b2) { - return b2 - b1; - } - -#ifdef CONFIG_SCHED_DEADLINE - /* If we assume all deadlines live within the same "half" of - * the 32 bit modulus space (this is a documented API rule), - * then the latest deadline in the queue minus the earliest is - * guaranteed to be (2's complement) non-negative. We can - * leverage that to compare the values without having to check - * the current time. - */ - uint32_t d1 = thread_1->base.prio_deadline; - uint32_t d2 = thread_2->base.prio_deadline; - - if (d1 != d2) { - /* Sooner deadline means higher effective priority. - * Doing the calculation with unsigned types and casting - * to signed isn't perfect, but at least reduces this - * from UB on overflow to impdef. - */ - return (int32_t) (d2 - d1); - } -#endif /* CONFIG_SCHED_DEADLINE */ - return 0; -} - static ALWAYS_INLINE void *thread_runq(struct k_thread *thread) { #ifdef CONFIG_SCHED_CPU_MASK_PIN_ONLY @@ -130,27 +88,32 @@ static ALWAYS_INLINE void runq_remove(struct k_thread *thread) _priq_run_remove(thread_runq(thread), thread); } +static ALWAYS_INLINE void runq_yield(void) +{ + _priq_run_yield(curr_cpu_runq()); +} + static ALWAYS_INLINE struct k_thread *runq_best(void) { return _priq_run_best(curr_cpu_runq()); } -/* arch_current_thread() is never in the run queue until context switch on +/* _current is never in the run queue until context switch on * SMP configurations, see z_requeue_current() */ static inline bool should_queue_thread(struct k_thread *thread) { - return !IS_ENABLED(CONFIG_SMP) || (thread != arch_current_thread()); + return !IS_ENABLED(CONFIG_SMP) || (thread != _current); } static ALWAYS_INLINE void queue_thread(struct k_thread *thread) { - thread->base.thread_state |= _THREAD_QUEUED; + z_mark_thread_as_queued(thread); if (should_queue_thread(thread)) { runq_add(thread); } #ifdef CONFIG_SMP - if (thread == arch_current_thread()) { + if (thread == _current) { /* add current to end of queue means "yield" */ _current_cpu->swap_ok = true; } @@ -159,7 +122,7 @@ static ALWAYS_INLINE void queue_thread(struct k_thread *thread) static ALWAYS_INLINE void dequeue_thread(struct k_thread *thread) { - thread->base.thread_state &= ~_THREAD_QUEUED; + z_mark_thread_as_not_queued(thread); if (should_queue_thread(thread)) { runq_remove(thread); } @@ -195,15 +158,17 @@ static inline bool is_halting(struct k_thread *thread) /* Clear the halting bits (_THREAD_ABORTING and _THREAD_SUSPENDING) */ static inline void clear_halting(struct k_thread *thread) { - barrier_dmem_fence_full(); /* Other cpus spin on this locklessly! */ - thread->base.thread_state &= ~(_THREAD_ABORTING | _THREAD_SUSPENDING); + if (IS_ENABLED(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1)) { + barrier_dmem_fence_full(); /* Other cpus spin on this locklessly! */ + thread->base.thread_state &= ~(_THREAD_ABORTING | _THREAD_SUSPENDING); + } } static ALWAYS_INLINE struct k_thread *next_up(void) { #ifdef CONFIG_SMP - if (is_halting(arch_current_thread())) { - halt_thread(arch_current_thread(), is_aborting(arch_current_thread()) ? + if (is_halting(_current)) { + halt_thread(_current, is_aborting(_current) ? _THREAD_DEAD : _THREAD_SUSPENDED); } #endif /* CONFIG_SMP */ @@ -242,42 +207,42 @@ static ALWAYS_INLINE struct k_thread *next_up(void) #else /* Under SMP, the "cache" mechanism for selecting the next * thread doesn't work, so we have more work to do to test - * arch_current_thread() against the best choice from the queue. Here, the + * _current against the best choice from the queue. Here, the * thread selected above represents "the best thread that is * not current". * - * Subtle note on "queued": in SMP mode, arch_current_thread() does not + * Subtle note on "queued": in SMP mode, _current does not * live in the queue, so this isn't exactly the same thing as - * "ready", it means "is arch_current_thread() already added back to the + * "ready", it means "is _current already added back to the * queue such that we don't want to re-add it". */ - bool queued = z_is_thread_queued(arch_current_thread()); - bool active = !z_is_thread_prevented_from_running(arch_current_thread()); + bool queued = z_is_thread_queued(_current); + bool active = !z_is_thread_prevented_from_running(_current); if (thread == NULL) { thread = _current_cpu->idle_thread; } if (active) { - int32_t cmp = z_sched_prio_cmp(arch_current_thread(), thread); + int32_t cmp = z_sched_prio_cmp(_current, thread); /* Ties only switch if state says we yielded */ if ((cmp > 0) || ((cmp == 0) && !_current_cpu->swap_ok)) { - thread = arch_current_thread(); + thread = _current; } if (!should_preempt(thread, _current_cpu->swap_ok)) { - thread = arch_current_thread(); + thread = _current; } } - /* Put arch_current_thread() back into the queue */ - if ((thread != arch_current_thread()) && active && - !z_is_idle_thread_object(arch_current_thread()) && !queued) { - queue_thread(arch_current_thread()); + /* Put _current back into the queue */ + if ((thread != _current) && active && + !z_is_idle_thread_object(_current) && !queued) { + queue_thread(_current); } - /* Take the new arch_current_thread() out of the queue */ + /* Take the new _current out of the queue */ if (z_is_thread_queued(thread)) { dequeue_thread(thread); } @@ -293,7 +258,7 @@ void move_thread_to_end_of_prio_q(struct k_thread *thread) dequeue_thread(thread); } queue_thread(thread); - update_cache(thread == arch_current_thread()); + update_cache(thread == _current); } /* Track cooperative threads preempted by metairqs so we can return to @@ -304,11 +269,11 @@ static void update_metairq_preempt(struct k_thread *thread) { #if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && \ (CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES) - if (thread_is_metairq(thread) && !thread_is_metairq(arch_current_thread()) && - !thread_is_preemptible(arch_current_thread())) { + if (thread_is_metairq(thread) && !thread_is_metairq(_current) && + !thread_is_preemptible(_current)) { /* Record new preemption */ - _current_cpu->metairq_preempted = arch_current_thread(); - } else if (!thread_is_metairq(thread) && !z_is_idle_thread_object(thread)) { + _current_cpu->metairq_preempted = _current; + } else if (!thread_is_metairq(thread)) { /* Returning from existing preemption */ _current_cpu->metairq_preempted = NULL; } @@ -327,14 +292,14 @@ static ALWAYS_INLINE void update_cache(int preempt_ok) if (should_preempt(thread, preempt_ok)) { #ifdef CONFIG_TIMESLICING - if (thread != arch_current_thread()) { + if (thread != _current) { z_reset_time_slice(thread); } #endif /* CONFIG_TIMESLICING */ update_metairq_preempt(thread); _kernel.ready_q.cache = thread; } else { - _kernel.ready_q.cache = arch_current_thread(); + _kernel.ready_q.cache = _current; } #else @@ -413,9 +378,9 @@ void z_move_thread_to_end_of_prio_q(struct k_thread *thread) */ static void thread_halt_spin(struct k_thread *thread, k_spinlock_key_t key) { - if (is_halting(arch_current_thread())) { - halt_thread(arch_current_thread(), - is_aborting(arch_current_thread()) ? _THREAD_DEAD : _THREAD_SUSPENDED); + if (is_halting(_current)) { + halt_thread(_current, + is_aborting(_current) ? _THREAD_DEAD : _THREAD_SUSPENDED); } k_spin_unlock(&_sched_spinlock, key); while (is_halting(thread)) { @@ -429,11 +394,11 @@ static void thread_halt_spin(struct k_thread *thread, k_spinlock_key_t key) /* Shared handler for k_thread_{suspend,abort}(). Called with the * scheduler lock held and the key passed (which it may * release/reacquire!) which will be released before a possible return - * (aborting arch_current_thread() will not return, obviously), which may be after + * (aborting _current will not return, obviously), which may be after * a context switch. */ -static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key, - bool terminate) +static ALWAYS_INLINE void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key, + bool terminate) { _wait_q_t *wq = &thread->join_queue; #ifdef CONFIG_SMP @@ -462,14 +427,17 @@ static void z_thread_halt(struct k_thread *thread, k_spinlock_key_t key, if (arch_is_in_isr()) { thread_halt_spin(thread, key); } else { - add_to_waitq_locked(arch_current_thread(), wq); + add_to_waitq_locked(_current, wq); z_swap(&_sched_spinlock, key); } } else { halt_thread(thread, terminate ? _THREAD_DEAD : _THREAD_SUSPENDED); - if ((thread == arch_current_thread()) && !arch_is_in_isr()) { + if ((thread == _current) && !arch_is_in_isr()) { + if (z_is_thread_essential(thread)) { + k_panic(); + } z_swap(&_sched_spinlock, key); - __ASSERT(!terminate, "aborted arch_current_thread() back from dead"); + __ASSERT(!terminate, "aborted _current back from dead"); } else { k_spin_unlock(&_sched_spinlock, key); } @@ -488,7 +456,7 @@ void z_impl_k_thread_suspend(k_tid_t thread) /* Special case "suspend the current thread" as it doesn't * need the async complexity below. */ - if (thread == arch_current_thread() && !arch_is_in_isr() && !IS_ENABLED(CONFIG_SMP)) { + if (!IS_ENABLED(CONFIG_SMP) && (thread == _current) && !arch_is_in_isr()) { k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); z_mark_thread_as_suspended(thread); @@ -498,11 +466,9 @@ void z_impl_k_thread_suspend(k_tid_t thread) return; } - (void)z_abort_thread_timeout(thread); - k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); - if ((thread->base.thread_state & _THREAD_SUSPENDED) != 0U) { + if (unlikely(z_is_thread_suspended(thread))) { /* The target thread is already suspended. Nothing to do. */ @@ -531,7 +497,7 @@ void z_impl_k_thread_resume(k_tid_t thread) k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); /* Do not try to resume a thread that was not suspended */ - if (!z_is_thread_suspended(thread)) { + if (unlikely(!z_is_thread_suspended(thread))) { k_spin_unlock(&_sched_spinlock, key); return; } @@ -558,7 +524,7 @@ static void unready_thread(struct k_thread *thread) if (z_is_thread_queued(thread)) { dequeue_thread(thread); } - update_cache(thread == arch_current_thread()); + update_cache(thread == _current); } /* _sched_spinlock must be held */ @@ -595,7 +561,7 @@ static void pend_locked(struct k_thread *thread, _wait_q_t *wait_q, void z_pend_thread(struct k_thread *thread, _wait_q_t *wait_q, k_timeout_t timeout) { - __ASSERT_NO_MSG(thread == arch_current_thread() || is_thread_dummy(thread)); + __ASSERT_NO_MSG(thread == _current || is_thread_dummy(thread)); K_SPINLOCK(&_sched_spinlock) { pend_locked(thread, wait_q, timeout); } @@ -631,7 +597,7 @@ void z_sched_wake_thread(struct k_thread *thread, bool is_timeout) if (thread->base.pended_on != NULL) { unpend_thread_no_timeout(thread); } - z_mark_thread_as_not_suspended(thread); + z_mark_thread_as_not_sleeping(thread); ready_thread(thread); } } @@ -653,7 +619,7 @@ int z_pend_curr(struct k_spinlock *lock, k_spinlock_key_t key, _wait_q_t *wait_q, k_timeout_t timeout) { #if defined(CONFIG_TIMESLICING) && defined(CONFIG_SWAP_NONATOMIC) - pending_current = arch_current_thread(); + pending_current = _current; #endif /* CONFIG_TIMESLICING && CONFIG_SWAP_NONATOMIC */ __ASSERT_NO_MSG(sizeof(_sched_spinlock) == 0 || lock != &_sched_spinlock); @@ -666,7 +632,7 @@ int z_pend_curr(struct k_spinlock *lock, k_spinlock_key_t key, * held. */ (void) k_spin_lock(&_sched_spinlock); - pend_locked(arch_current_thread(), wait_q, timeout); + pend_locked(_current, wait_q, timeout); k_spin_release(lock); return z_swap(&_sched_spinlock, key); } @@ -689,7 +655,7 @@ struct k_thread *z_unpend1_no_timeout(_wait_q_t *wait_q) void z_unpend_thread(struct k_thread *thread) { z_unpend_thread_no_timeout(thread); - (void)z_abort_thread_timeout(thread); + z_abort_thread_timeout(thread); } /* Priority set utility that does no rescheduling, it just changes the @@ -764,7 +730,7 @@ static inline bool need_swap(void) /* Check if the next ready thread is the same as the current thread */ new_thread = _kernel.ready_q.cache; - return new_thread != arch_current_thread(); + return new_thread != _current; #endif /* CONFIG_SMP */ } @@ -800,15 +766,15 @@ void k_sched_lock(void) void k_sched_unlock(void) { K_SPINLOCK(&_sched_spinlock) { - __ASSERT(arch_current_thread()->base.sched_locked != 0U, ""); + __ASSERT(_current->base.sched_locked != 0U, ""); __ASSERT(!arch_is_in_isr(), ""); - ++arch_current_thread()->base.sched_locked; + ++_current->base.sched_locked; update_cache(0); } LOG_DBG("scheduler unlocked (%p:%d)", - arch_current_thread(), arch_current_thread()->base.sched_locked); + _current, _current->base.sched_locked); SYS_PORT_TRACING_FUNC(k_thread, sched_unlock); @@ -820,10 +786,10 @@ struct k_thread *z_swap_next_thread(void) #ifdef CONFIG_SMP struct k_thread *ret = next_up(); - if (ret == arch_current_thread()) { + if (ret == _current) { /* When not swapping, have to signal IPIs here. In * the context switch case it must happen later, after - * arch_current_thread() gets requeued. + * _current gets requeued. */ signal_pending_ipi(); } @@ -834,11 +800,11 @@ struct k_thread *z_swap_next_thread(void) } #ifdef CONFIG_USE_SWITCH -/* Just a wrapper around arch_current_thread_set(xxx) with tracing */ +/* Just a wrapper around z_current_thread_set(xxx) with tracing */ static inline void set_current(struct k_thread *new_thread) { z_thread_mark_switched_out(); - arch_current_thread_set(new_thread); + z_current_thread_set(new_thread); } /** @@ -864,7 +830,7 @@ static inline void set_current(struct k_thread *new_thread) * function. * * @warning - * The arch_current_thread() value may have changed after this call and not refer + * The _current value may have changed after this call and not refer * to the interrupted thread anymore. It might be necessary to make a local * copy before calling this function. * @@ -880,7 +846,7 @@ void *z_get_next_switch_handle(void *interrupted) void *ret = NULL; K_SPINLOCK(&_sched_spinlock) { - struct k_thread *old_thread = arch_current_thread(), *new_thread; + struct k_thread *old_thread = _current, *new_thread; if (IS_ENABLED(CONFIG_SMP)) { old_thread->switch_handle = NULL; @@ -906,7 +872,7 @@ void *z_get_next_switch_handle(void *interrupted) #endif /* CONFIG_TIMESLICING */ #ifdef CONFIG_SPIN_VALIDATE - /* Changed arch_current_thread()! Update the spinlock + /* Changed _current! Update the spinlock * bookkeeping so the validation doesn't get * confused when the "wrong" thread tries to * release the lock. @@ -941,9 +907,9 @@ void *z_get_next_switch_handle(void *interrupted) return ret; #else z_sched_usage_switch(_kernel.ready_q.cache); - arch_current_thread()->switch_handle = interrupted; + _current->switch_handle = interrupted; set_current(_kernel.ready_q.cache); - return arch_current_thread()->switch_handle; + return _current->switch_handle; #endif /* CONFIG_SMP */ } #endif /* CONFIG_USE_SWITCH */ @@ -989,7 +955,7 @@ void z_impl_k_thread_priority_set(k_tid_t thread, int prio) bool need_sched = z_thread_prio_set((struct k_thread *)thread, prio); if ((need_sched) && (IS_ENABLED(CONFIG_SMP) || - (arch_current_thread()->base.sched_locked == 0U))) { + (_current->base.sched_locked == 0U))) { z_reschedule_unlocked(); } } @@ -1052,10 +1018,29 @@ static inline void z_vrfy_k_thread_deadline_set(k_tid_t tid, int deadline) #endif /* CONFIG_USERSPACE */ #endif /* CONFIG_SCHED_DEADLINE */ +void z_impl_k_reschedule(void) +{ + k_spinlock_key_t key; + + key = k_spin_lock(&_sched_spinlock); + + update_cache(0); + + z_reschedule(&_sched_spinlock, key); +} + +#ifdef CONFIG_USERSPACE +static inline void z_vrfy_k_reschedule(void) +{ + z_impl_k_reschedule(); +} +#include +#endif /* CONFIG_USERSPACE */ + bool k_can_yield(void) { return !(k_is_pre_kernel() || k_is_in_isr() || - z_is_idle_thread_object(arch_current_thread())); + z_is_idle_thread_object(_current)); } void z_impl_k_yield(void) @@ -1066,11 +1051,8 @@ void z_impl_k_yield(void) k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); - if (!IS_ENABLED(CONFIG_SMP) || - z_is_thread_queued(arch_current_thread())) { - dequeue_thread(arch_current_thread()); - } - queue_thread(arch_current_thread()); + runq_yield(); + update_cache(1); z_swap(&_sched_spinlock, key); } @@ -1089,7 +1071,7 @@ static int32_t z_tick_sleep(k_ticks_t ticks) __ASSERT(!arch_is_in_isr(), ""); - LOG_DBG("thread %p for %lu ticks", arch_current_thread(), (unsigned long)ticks); + LOG_DBG("thread %p for %lu ticks", _current, (unsigned long)ticks); /* wait of 0 ms is treated as a 'yield' */ if (ticks == 0) { @@ -1107,16 +1089,14 @@ static int32_t z_tick_sleep(k_ticks_t ticks) k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); #if defined(CONFIG_TIMESLICING) && defined(CONFIG_SWAP_NONATOMIC) - pending_current = arch_current_thread(); + pending_current = _current; #endif /* CONFIG_TIMESLICING && CONFIG_SWAP_NONATOMIC */ - unready_thread(arch_current_thread()); - z_add_thread_timeout(arch_current_thread(), timeout); - z_mark_thread_as_suspended(arch_current_thread()); + unready_thread(_current); + z_add_thread_timeout(_current, timeout); + z_mark_thread_as_sleeping(_current); (void)z_swap(&_sched_spinlock, key); - __ASSERT(!z_is_thread_state_set(arch_current_thread(), _THREAD_SUSPENDED), ""); - /* We require a 32 bit unsigned subtraction to care a wraparound */ uint32_t left_ticks = expected_wakeup_ticks - sys_clock_tick_get_32(); @@ -1137,20 +1117,12 @@ int32_t z_impl_k_sleep(k_timeout_t timeout) SYS_PORT_TRACING_FUNC_ENTER(k_thread, sleep, timeout); - /* in case of K_FOREVER, we suspend */ - if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { - - k_thread_suspend(arch_current_thread()); - SYS_PORT_TRACING_FUNC_EXIT(k_thread, sleep, timeout, (int32_t) K_TICKS_FOREVER); - - return (int32_t) K_TICKS_FOREVER; - } - ticks = timeout.ticks; ticks = z_tick_sleep(ticks); - int32_t ret = k_ticks_to_ms_ceil64(ticks); + int32_t ret = K_TIMEOUT_EQ(timeout, K_FOREVER) ? K_TICKS_FOREVER : + k_ticks_to_ms_ceil64(ticks); SYS_PORT_TRACING_FUNC_EXIT(k_thread, sleep, timeout, ret); @@ -1193,29 +1165,15 @@ void z_impl_k_wakeup(k_tid_t thread) { SYS_PORT_TRACING_OBJ_FUNC(k_thread, wakeup, thread); - if (z_is_thread_pending(thread)) { - return; - } - - if (z_abort_thread_timeout(thread) < 0) { - /* Might have just been sleeping forever */ - if (thread->base.thread_state != _THREAD_SUSPENDED) { - return; - } - } - k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); - z_mark_thread_as_not_suspended(thread); - - if (thread_active_elsewhere(thread) == NULL) { + if (z_is_thread_sleeping(thread)) { + z_abort_thread_timeout(thread); + z_mark_thread_as_not_sleeping(thread); ready_thread(thread); - } - - if (arch_is_in_isr()) { - k_spin_unlock(&_sched_spinlock, key); - } else { z_reschedule(&_sched_spinlock, key); + } else { + k_spin_unlock(&_sched_spinlock, key); } } @@ -1230,7 +1188,7 @@ static inline void z_vrfy_k_wakeup(k_tid_t thread) k_tid_t z_impl_k_sched_current_thread_query(void) { - return arch_current_thread(); + return _current; } #ifdef CONFIG_USERSPACE @@ -1247,7 +1205,7 @@ static inline void unpend_all(_wait_q_t *wait_q) for (thread = z_waitq_head(wait_q); thread != NULL; thread = z_waitq_head(wait_q)) { unpend_thread_no_timeout(thread); - (void)z_abort_thread_timeout(thread); + z_abort_thread_timeout(thread); arch_thread_return_value_set(thread, 0); ready_thread(thread); } @@ -1265,7 +1223,7 @@ extern void thread_abort_hook(struct k_thread *thread); * @param thread Identify the thread to halt * @param new_state New thread state (_THREAD_DEAD or _THREAD_SUSPENDED) */ -static void halt_thread(struct k_thread *thread, uint8_t new_state) +static ALWAYS_INLINE void halt_thread(struct k_thread *thread, uint8_t new_state) { bool dummify = false; @@ -1282,16 +1240,16 @@ static void halt_thread(struct k_thread *thread, uint8_t new_state) if (thread->base.pended_on != NULL) { unpend_thread_no_timeout(thread); } - (void)z_abort_thread_timeout(thread); + z_abort_thread_timeout(thread); unpend_all(&thread->join_queue); - /* Edge case: aborting arch_current_thread() from within an + /* Edge case: aborting _current from within an * ISR that preempted it requires clearing the - * arch_current_thread() pointer so the upcoming context + * _current pointer so the upcoming context * switch doesn't clobber the now-freed * memory */ - if (thread == arch_current_thread() && arch_is_in_isr()) { + if (thread == _current && arch_is_in_isr()) { dummify = true; } } @@ -1334,10 +1292,10 @@ static void halt_thread(struct k_thread *thread, uint8_t new_state) k_thread_abort_cleanup(thread); #endif /* CONFIG_THREAD_ABORT_NEED_CLEANUP */ - /* Do this "set arch_current_thread() to dummy" step last so that - * subsystems above can rely on arch_current_thread() being + /* Do this "set _current to dummy" step last so that + * subsystems above can rely on _current being * unchanged. Disabled for posix as that arch - * continues to use the arch_current_thread() pointer in its swap + * continues to use the _current pointer in its swap * code. Note that we must leave a non-null switch * handle for any threads spinning in join() (this can * never be used, as our thread is flagged dead, but @@ -1345,7 +1303,7 @@ static void halt_thread(struct k_thread *thread, uint8_t new_state) */ if (dummify && !IS_ENABLED(CONFIG_ARCH_POSIX)) { #ifdef CONFIG_USE_SWITCH - arch_current_thread()->switch_handle = arch_current_thread(); + _current->switch_handle = _current; #endif z_dummy_thread_init(&_thread_dummy); @@ -1361,21 +1319,20 @@ static void halt_thread(struct k_thread *thread, uint8_t new_state) void z_thread_abort(struct k_thread *thread) { + bool essential = z_is_thread_essential(thread); k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); - if (z_is_thread_essential(thread)) { - k_spin_unlock(&_sched_spinlock, key); - __ASSERT(false, "aborting essential thread %p", thread); - k_panic(); - return; - } - if ((thread->base.thread_state & _THREAD_DEAD) != 0U) { k_spin_unlock(&_sched_spinlock, key); return; } z_thread_halt(thread, key, true); + + if (essential) { + __ASSERT(!essential, "aborted essential thread %p", thread); + k_panic(); + } } #if !defined(CONFIG_ARCH_HAS_THREAD_ABORT) @@ -1403,13 +1360,13 @@ int z_impl_k_thread_join(struct k_thread *thread, k_timeout_t timeout) ret = 0; } else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { ret = -EBUSY; - } else if ((thread == arch_current_thread()) || - (thread->base.pended_on == &arch_current_thread()->join_queue)) { + } else if ((thread == _current) || + (thread->base.pended_on == &_current->join_queue)) { ret = -EDEADLK; } else { __ASSERT(!arch_is_in_isr(), "cannot join in ISR"); - add_to_waitq_locked(arch_current_thread(), &thread->join_queue); - add_thread_timeout(arch_current_thread(), timeout); + add_to_waitq_locked(_current, &thread->join_queue); + add_thread_timeout(_current, timeout); SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_thread, join, thread, timeout); ret = z_swap(&_sched_spinlock, key); @@ -1493,7 +1450,7 @@ bool z_sched_wake(_wait_q_t *wait_q, int swap_retval, void *swap_data) swap_retval, swap_data); unpend_thread_no_timeout(thread); - (void)z_abort_thread_timeout(thread); + z_abort_thread_timeout(thread); ready_thread(thread); ret = true; } @@ -1508,7 +1465,7 @@ int z_sched_wait(struct k_spinlock *lock, k_spinlock_key_t key, int ret = z_pend_curr(lock, key, wait_q, timeout); if (data != NULL) { - *data = arch_current_thread()->base.swap_data; + *data = _current->base.swap_data; } return ret; } diff --git a/kernel/sem.c b/kernel/sem.c index 58d8a86f1e979..90876c834a3bb 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -85,8 +85,7 @@ int z_vrfy_k_sem_init(struct k_sem *sem, unsigned int initial_count, static inline bool handle_poll_events(struct k_sem *sem) { #ifdef CONFIG_POLL - z_handle_obj_poll_events(&sem->poll_events, K_POLL_STATE_SEM_AVAILABLE); - return true; + return z_handle_obj_poll_events(&sem->poll_events, K_POLL_STATE_SEM_AVAILABLE); #else ARG_UNUSED(sem); return false; @@ -97,7 +96,7 @@ void z_impl_k_sem_give(struct k_sem *sem) { k_spinlock_key_t key = k_spin_lock(&lock); struct k_thread *thread; - bool resched = true; + bool resched; SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_sem, give, sem); @@ -106,6 +105,7 @@ void z_impl_k_sem_give(struct k_sem *sem) if (unlikely(thread != NULL)) { arch_thread_return_value_set(thread, 0); z_ready_thread(thread); + resched = true; } else { sem->count += (sem->count != sem->limit) ? 1U : 0U; resched = handle_poll_events(sem); @@ -167,12 +167,14 @@ void z_impl_k_sem_reset(struct k_sem *sem) { struct k_thread *thread; k_spinlock_key_t key = k_spin_lock(&lock); + bool resched = false; while (true) { thread = z_unpend_first_thread(&sem->wait_q); if (thread == NULL) { break; } + resched = true; arch_thread_return_value_set(thread, -EAGAIN); z_ready_thread(thread); } @@ -180,9 +182,13 @@ void z_impl_k_sem_reset(struct k_sem *sem) SYS_PORT_TRACING_OBJ_FUNC(k_sem, reset, sem); - handle_poll_events(sem); + resched = handle_poll_events(sem) || resched; - z_reschedule(&lock, key); + if (resched) { + z_reschedule(&lock, key); + } else { + k_spin_unlock(&lock, key); + } } #ifdef CONFIG_USERSPACE diff --git a/kernel/smp.c b/kernel/smp.c index b0eefb35e4144..63ac7bc8975e7 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -58,23 +58,23 @@ unsigned int z_smp_global_lock(void) { unsigned int key = arch_irq_lock(); - if (!arch_current_thread()->base.global_lock_count) { + if (!_current->base.global_lock_count) { while (!atomic_cas(&global_lock, 0, 1)) { arch_spin_relax(); } } - arch_current_thread()->base.global_lock_count++; + _current->base.global_lock_count++; return key; } void z_smp_global_unlock(unsigned int key) { - if (arch_current_thread()->base.global_lock_count != 0U) { - arch_current_thread()->base.global_lock_count--; + if (_current->base.global_lock_count != 0U) { + _current->base.global_lock_count--; - if (!arch_current_thread()->base.global_lock_count) { + if (!_current->base.global_lock_count) { (void)atomic_clear(&global_lock); } } @@ -248,3 +248,17 @@ bool z_smp_cpu_mobile(void) arch_irq_unlock(k); return !pinned; } + +__attribute_const__ struct k_thread *z_smp_current_get(void) +{ + /* + * _current is a field read from _current_cpu, which can race + * with preemption before it is read. We must lock local + * interrupts when reading it. + */ + unsigned int key = arch_irq_lock(); + struct k_thread *t = _current_cpu->current; + + arch_irq_unlock(key); + return t; +} diff --git a/kernel/spinlock_validate.c b/kernel/spinlock_validate.c index c2a97356d9cec..103998dea2ff1 100644 --- a/kernel/spinlock_validate.c +++ b/kernel/spinlock_validate.c @@ -5,6 +5,7 @@ */ #include #include +#include bool z_spin_lock_valid(struct k_spinlock *l) { @@ -17,6 +18,7 @@ bool z_spin_lock_valid(struct k_spinlock *l) } return true; } +EXPORT_SYMBOL(z_spin_lock_valid); bool z_spin_unlock_valid(struct k_spinlock *l) { @@ -24,24 +26,27 @@ bool z_spin_unlock_valid(struct k_spinlock *l) l->thread_cpu = 0; - if (arch_is_in_isr() && arch_current_thread()->base.thread_state & _THREAD_DUMMY) { - /* Edge case where an ISR aborted arch_current_thread() */ + if (arch_is_in_isr() && _current->base.thread_state & _THREAD_DUMMY) { + /* Edge case where an ISR aborted _current */ return true; } - if (tcpu != (_current_cpu->id | (uintptr_t)arch_current_thread())) { + if (tcpu != (_current_cpu->id | (uintptr_t)_current)) { return false; } return true; } +EXPORT_SYMBOL(z_spin_unlock_valid); void z_spin_lock_set_owner(struct k_spinlock *l) { - l->thread_cpu = _current_cpu->id | (uintptr_t)arch_current_thread(); + l->thread_cpu = _current_cpu->id | (uintptr_t)_current; } +EXPORT_SYMBOL(z_spin_lock_set_owner); #ifdef CONFIG_KERNEL_COHERENCE bool z_spin_lock_mem_coherent(struct k_spinlock *l) { return arch_mem_coherent((void *)l); } +EXPORT_SYMBOL(z_spin_lock_mem_coherent); #endif /* CONFIG_KERNEL_COHERENCE */ diff --git a/kernel/stack.c b/kernel/stack.c index b3ea624b1625e..5add38b9c2318 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -182,7 +182,7 @@ int z_impl_k_stack_pop(struct k_stack *stack, stack_data_t *data, return -EAGAIN; } - *data = (stack_data_t)arch_current_thread()->base.swap_data; + *data = (stack_data_t)_current->base.swap_data; SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_stack, pop, stack, timeout, 0); diff --git a/kernel/thread.c b/kernel/thread.c index a0761645708bb..f77d70ce494fb 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -82,7 +82,7 @@ EXPORT_SYMBOL(k_is_in_isr); #ifdef CONFIG_THREAD_CUSTOM_DATA void z_impl_k_thread_custom_data_set(void *value) { - arch_current_thread()->custom_data = value; + _current->custom_data = value; } #ifdef CONFIG_USERSPACE @@ -95,7 +95,7 @@ static inline void z_vrfy_k_thread_custom_data_set(void *data) void *z_impl_k_thread_custom_data_get(void) { - return arch_current_thread()->custom_data; + return _current->custom_data; } #ifdef CONFIG_USERSPACE @@ -110,7 +110,7 @@ static inline void *z_vrfy_k_thread_custom_data_get(void) int z_impl_k_is_preempt_thread(void) { - return !arch_is_in_isr() && thread_is_preemptible(arch_current_thread()); + return !arch_is_in_isr() && thread_is_preemptible(_current); } #ifdef CONFIG_USERSPACE @@ -139,7 +139,7 @@ int z_impl_k_thread_name_set(k_tid_t thread, const char *str) { #ifdef CONFIG_THREAD_NAME if (thread == NULL) { - thread = arch_current_thread(); + thread = _current; } strncpy(thread->name, str, CONFIG_THREAD_MAX_NAME_LEN - 1); @@ -236,6 +236,7 @@ const char *k_thread_state_str(k_tid_t thread_id, char *buf, size_t buf_size) } state_string[] = { SS_ENT(DUMMY), SS_ENT(PENDING), + SS_ENT(SLEEPING), SS_ENT(DEAD), SS_ENT(SUSPENDED), SS_ENT(ABORTING), @@ -333,11 +334,11 @@ void z_check_stack_sentinel(void) { uint32_t *stack; - if ((arch_current_thread()->base.thread_state & _THREAD_DUMMY) != 0) { + if ((_current->base.thread_state & _THREAD_DUMMY) != 0) { return; } - stack = (uint32_t *)arch_current_thread()->stack_info.start; + stack = (uint32_t *)_current->stack_info.start; if (*stack != STACK_SENTINEL) { /* Restore it so further checks don't trigger this same error */ *stack = STACK_SENTINEL; @@ -399,6 +400,7 @@ static char *setup_thread_stack(struct k_thread *new_thread, stack_buf_start = K_KERNEL_STACK_BUFFER(stack); stack_buf_size = stack_obj_size - K_KERNEL_STACK_RESERVED; +#if defined(ARCH_KERNEL_STACK_RESERVED) /* Zephyr treats stack overflow as an app bug. But * this particular overflow can be seen by static * analysis so needs to be handled somehow. @@ -406,7 +408,7 @@ static char *setup_thread_stack(struct k_thread *new_thread, if (K_KERNEL_STACK_RESERVED > stack_obj_size) { k_panic(); } - +#endif } #ifdef CONFIG_THREAD_STACK_MEM_MAPPED @@ -542,7 +544,7 @@ char *z_setup_new_thread(struct k_thread *new_thread, z_waitq_init(&new_thread->join_queue); /* Initialize various struct k_thread members */ - z_init_thread_base(&new_thread->base, prio, _THREAD_SUSPENDED, options); + z_init_thread_base(&new_thread->base, prio, _THREAD_SLEEPING, options); stack_ptr = setup_thread_stack(new_thread, stack, stack_size); #ifdef CONFIG_KERNEL_COHERENCE @@ -613,8 +615,8 @@ char *z_setup_new_thread(struct k_thread *new_thread, } #endif /* CONFIG_SCHED_CPU_MASK */ #ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN - /* arch_current_thread() may be null if the dummy thread is not used */ - if (!arch_current_thread()) { + /* _current may be null if the dummy thread is not used */ + if (!_current) { new_thread->resource_pool = NULL; return stack_ptr; } @@ -623,13 +625,13 @@ char *z_setup_new_thread(struct k_thread *new_thread, z_mem_domain_init_thread(new_thread); if ((options & K_INHERIT_PERMS) != 0U) { - k_thread_perms_inherit(arch_current_thread(), new_thread); + k_thread_perms_inherit(_current, new_thread); } #endif /* CONFIG_USERSPACE */ #ifdef CONFIG_SCHED_DEADLINE new_thread->base.prio_deadline = 0; #endif /* CONFIG_SCHED_DEADLINE */ - new_thread->resource_pool = arch_current_thread()->resource_pool; + new_thread->resource_pool = _current->resource_pool; #ifdef CONFIG_SMP z_waitq_init(&new_thread->halt_queue); @@ -724,7 +726,7 @@ k_tid_t z_vrfy_k_thread_create(struct k_thread *new_thread, */ K_OOPS(K_SYSCALL_VERIFY(_is_valid_prio(prio, NULL))); K_OOPS(K_SYSCALL_VERIFY(z_is_prio_lower_or_equal(prio, - arch_current_thread()->base.prio))); + _current->base.prio))); z_setup_new_thread(new_thread, stack, stack_size, entry, p1, p2, p3, prio, options, NULL); @@ -769,25 +771,25 @@ FUNC_NORETURN void k_thread_user_mode_enter(k_thread_entry_t entry, { SYS_PORT_TRACING_FUNC(k_thread, user_mode_enter); - arch_current_thread()->base.user_options |= K_USER; - z_thread_essential_clear(arch_current_thread()); + _current->base.user_options |= K_USER; + z_thread_essential_clear(_current); #ifdef CONFIG_THREAD_MONITOR - arch_current_thread()->entry.pEntry = entry; - arch_current_thread()->entry.parameter1 = p1; - arch_current_thread()->entry.parameter2 = p2; - arch_current_thread()->entry.parameter3 = p3; + _current->entry.pEntry = entry; + _current->entry.parameter1 = p1; + _current->entry.parameter2 = p2; + _current->entry.parameter3 = p3; #endif /* CONFIG_THREAD_MONITOR */ #ifdef CONFIG_USERSPACE - __ASSERT(z_stack_is_user_capable(arch_current_thread()->stack_obj), + __ASSERT(z_stack_is_user_capable(_current->stack_obj), "dropping to user mode with kernel-only stack object"); #ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA - memset(arch_current_thread()->userspace_local_data, 0, + memset(_current->userspace_local_data, 0, sizeof(struct _thread_userspace_local_data)); #endif /* CONFIG_THREAD_USERSPACE_LOCAL_DATA */ #ifdef CONFIG_THREAD_LOCAL_STORAGE - arch_tls_stack_setup(arch_current_thread(), - (char *)(arch_current_thread()->stack_info.start + - arch_current_thread()->stack_info.size)); + arch_tls_stack_setup(_current, + (char *)(_current->stack_info.start + + _current->stack_info.size)); #endif /* CONFIG_THREAD_LOCAL_STORAGE */ arch_user_mode_enter(entry, p1, p2, p3); #else @@ -915,7 +917,7 @@ static inline k_ticks_t z_vrfy_k_thread_timeout_expires_ticks( void z_thread_mark_switched_in(void) { #if defined(CONFIG_SCHED_THREAD_USAGE) && !defined(CONFIG_USE_SWITCH) - z_sched_usage_start(arch_current_thread()); + z_sched_usage_start(_current); #endif /* CONFIG_SCHED_THREAD_USAGE && !CONFIG_USE_SWITCH */ #ifdef CONFIG_TRACING @@ -932,9 +934,10 @@ void z_thread_mark_switched_out(void) #ifdef CONFIG_TRACING #ifdef CONFIG_THREAD_LOCAL_STORAGE /* Dummy thread won't have TLS set up to run arbitrary code */ - if (!arch_current_thread() || - (arch_current_thread()->base.thread_state & _THREAD_DUMMY) != 0) + if (!_current || + (_current->base.thread_state & _THREAD_DUMMY) != 0) { return; + } #endif /* CONFIG_THREAD_LOCAL_STORAGE */ SYS_PORT_TRACING_FUNC(k_thread, switched_out); #endif /* CONFIG_TRACING */ @@ -1083,7 +1086,7 @@ void k_thread_abort_cleanup(struct k_thread *thread) thread_to_cleanup = NULL; } - if (thread == arch_current_thread()) { + if (thread == _current) { /* Need to defer for current running thread as the cleanup * might result in exception. Actual cleanup will be done * at the next time k_thread_abort() is called, or at thread @@ -1121,3 +1124,30 @@ void k_thread_abort_cleanup_check_reuse(struct k_thread *thread) } #endif /* CONFIG_THREAD_ABORT_NEED_CLEANUP */ + +void z_dummy_thread_init(struct k_thread *dummy_thread) +{ + dummy_thread->base.thread_state = _THREAD_DUMMY; +#ifdef CONFIG_SCHED_CPU_MASK + dummy_thread->base.cpu_mask = -1; +#endif /* CONFIG_SCHED_CPU_MASK */ + dummy_thread->base.user_options = K_ESSENTIAL; +#ifdef CONFIG_THREAD_STACK_INFO + dummy_thread->stack_info.start = 0U; + dummy_thread->stack_info.size = 0U; +#endif /* CONFIG_THREAD_STACK_INFO */ +#ifdef CONFIG_USERSPACE + dummy_thread->mem_domain_info.mem_domain = &k_mem_domain_default; +#endif /* CONFIG_USERSPACE */ +#if (K_HEAP_MEM_POOL_SIZE > 0) + k_thread_system_pool_assign(dummy_thread); +#else + dummy_thread->resource_pool = NULL; +#endif /* K_HEAP_MEM_POOL_SIZE */ + +#ifdef CONFIG_TIMESLICE_PER_THREAD + dummy_thread->base.slice_ticks = 0; +#endif /* CONFIG_TIMESLICE_PER_THREAD */ + + z_current_thread_set(dummy_thread); +} diff --git a/kernel/timeout.c b/kernel/timeout.c index f751c2f20a572..17f08c9d2e22f 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -16,6 +16,10 @@ static uint64_t curr_tick; static sys_dlist_t timeout_list = SYS_DLIST_STATIC_INIT(&timeout_list); +/* + * The timeout code shall take no locks other than its own (timeout_lock), nor + * shall it call any other subsystem while holding this lock. + */ static struct k_spinlock timeout_lock; #define MAX_WAIT (IS_ENABLED(CONFIG_SYSTEM_CLOCK_SLOPPY_IDLE) \ @@ -147,8 +151,13 @@ int z_abort_timeout(struct _timeout *to) K_SPINLOCK(&timeout_lock) { if (sys_dnode_is_linked(&to->node)) { + bool is_first = (to == first()); + remove_timeout(to); ret = 0; + if (is_first) { + sys_clock_set_timeout(next_timeout(), false); + } } } diff --git a/kernel/timeslicing.c b/kernel/timeslicing.c index 0410d42b91fe3..be91d9606f51e 100644 --- a/kernel/timeslicing.c +++ b/kernel/timeslicing.c @@ -15,7 +15,7 @@ static bool slice_expired[CONFIG_MP_MAX_NUM_CPUS]; #ifdef CONFIG_SWAP_NONATOMIC /* If z_swap() isn't atomic, then it's possible for a timer interrupt - * to try to timeslice away arch_current_thread() after it has already pended + * to try to timeslice away _current after it has already pended * itself but before the corresponding context switch. Treat that as * a noop condition in z_time_slice(). */ @@ -82,7 +82,7 @@ void k_sched_time_slice_set(int32_t slice, int prio) K_SPINLOCK(&_sched_spinlock) { slice_ticks = k_ms_to_ticks_ceil32(slice); slice_max_prio = prio; - z_reset_time_slice(arch_current_thread()); + z_reset_time_slice(_current); } } @@ -103,7 +103,7 @@ void k_thread_time_slice_set(struct k_thread *thread, int32_t thread_slice_ticks void z_time_slice(void) { k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); - struct k_thread *curr = arch_current_thread(); + struct k_thread *curr = _current; #ifdef CONFIG_SWAP_NONATOMIC if (pending_current == curr) { diff --git a/kernel/userspace.c b/kernel/userspace.c index 5aeafe221c72a..7a66513c03e5a 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -437,7 +437,7 @@ static void *z_object_alloc(enum k_objects otype, size_t size) /* The allocating thread implicitly gets permission on kernel objects * that it allocates */ - k_thread_perms_set(zo, arch_current_thread()); + k_thread_perms_set(zo, _current); /* Activates reference counting logic for automatic disposal when * all permissions have been revoked @@ -654,7 +654,7 @@ static int thread_perms_test(struct k_object *ko) return 1; } - index = thread_index_get(arch_current_thread()); + index = thread_index_get(_current); if (index != -1) { return sys_bitfield_test_bit((mem_addr_t)&ko->perms, index); } @@ -663,9 +663,9 @@ static int thread_perms_test(struct k_object *ko) static void dump_permission_error(struct k_object *ko) { - int index = thread_index_get(arch_current_thread()); + int index = thread_index_get(_current); LOG_ERR("thread %p (%d) does not have permission on %s %p", - arch_current_thread(), index, + _current, index, otype_to_str(ko->type), ko->name); LOG_HEXDUMP_ERR(ko->perms, sizeof(ko->perms), "permission bitmap"); } @@ -718,7 +718,7 @@ void k_object_access_revoke(const void *object, struct k_thread *thread) void z_impl_k_object_release(const void *object) { - k_object_access_revoke(object, arch_current_thread()); + k_object_access_revoke(object, _current); } void k_object_access_all_grant(const void *object) @@ -794,7 +794,7 @@ void k_object_recycle(const void *obj) if (ko != NULL) { (void)memset(ko->perms, 0, sizeof(ko->perms)); - k_thread_perms_set(ko, arch_current_thread()); + k_thread_perms_set(ko, _current); ko->flags |= K_OBJ_FLAG_INITIALIZED; } } diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index 38e778713bafc..ab6e4f0623c7f 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -72,7 +72,7 @@ static inline void z_vrfy_k_object_release(const void *object) ko = validate_any_object(object); K_OOPS(K_SYSCALL_VERIFY_MSG(ko != NULL, "object %p access denied", object)); - k_thread_perms_clear(ko, arch_current_thread()); + k_thread_perms_clear(ko, _current); } #include diff --git a/kernel/work.c b/kernel/work.c index 5e46576770724..24691bd31096e 100644 --- a/kernel/work.c +++ b/kernel/work.c @@ -262,7 +262,7 @@ static inline int queue_submit_locked(struct k_work_q *queue, } int ret; - bool chained = (arch_current_thread() == &queue->thread) && !k_is_in_isr(); + bool chained = (_current == &queue->thread) && !k_is_in_isr(); bool draining = flag_test(&queue->flags, K_WORK_QUEUE_DRAIN_BIT); bool plugged = flag_test(&queue->flags, K_WORK_QUEUE_PLUGGED_BIT); @@ -653,6 +653,12 @@ static void work_queue_main(void *workq_ptr, void *p2, void *p3) * submissions. */ (void)z_sched_wake_all(&queue->drainq, 1, NULL); + } else if (flag_test(&queue->flags, K_WORK_QUEUE_STOP_BIT)) { + /* User has requested that the queue stop. Clear the status flags and exit. + */ + flags_set(&queue->flags, 0); + k_spin_unlock(&lock, key); + return; } else { /* No work is available and no queue state requires * special handling. @@ -812,6 +818,41 @@ int k_work_queue_unplug(struct k_work_q *queue) return ret; } +int k_work_queue_stop(struct k_work_q *queue, k_timeout_t timeout) +{ + __ASSERT_NO_MSG(queue); + + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work_queue, stop, queue, timeout); + k_spinlock_key_t key = k_spin_lock(&lock); + + if (!flag_test(&queue->flags, K_WORK_QUEUE_STARTED_BIT)) { + k_spin_unlock(&lock, key); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work_queue, stop, queue, timeout, -EALREADY); + return -EALREADY; + } + + if (!flag_test(&queue->flags, K_WORK_QUEUE_PLUGGED_BIT)) { + k_spin_unlock(&lock, key); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work_queue, stop, queue, timeout, -EBUSY); + return -EBUSY; + } + + flag_set(&queue->flags, K_WORK_QUEUE_STOP_BIT); + notify_queue_locked(queue); + k_spin_unlock(&lock, key); + SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_work_queue, stop, queue, timeout); + if (k_thread_join(&queue->thread, timeout)) { + key = k_spin_lock(&lock); + flag_clear(&queue->flags, K_WORK_QUEUE_STOP_BIT); + k_spin_unlock(&lock, key); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work_queue, stop, queue, timeout, -ETIMEDOUT); + return -ETIMEDOUT; + } + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work_queue, stop, queue, timeout, 0); + return 0; +} + #ifdef CONFIG_SYS_CLOCK_EXISTS /* Timeout handler for delayable work. diff --git a/kernel/xip.c b/kernel/xip.c index 898dfe2ae4cbb..66ce7907dde52 100644 --- a/kernel/xip.c +++ b/kernel/xip.c @@ -10,13 +10,13 @@ #include #include -#ifdef CONFIG_STACK_CANARIES +#ifdef CONFIG_REQUIRES_STACK_CANARIES #ifdef CONFIG_STACK_CANARIES_TLS extern Z_THREAD_LOCAL volatile uintptr_t __stack_chk_guard; #else extern volatile uintptr_t __stack_chk_guard; #endif /* CONFIG_STACK_CANARIES_TLS */ -#endif /* CONFIG_STACK_CANARIES */ +#endif /* CONFIG_REQUIRES_STACK_CANARIES */ /** * @brief Copy the data section from ROM to RAM @@ -49,7 +49,7 @@ void z_data_copy(void) data_copy_xip_relocation(); #endif /* CONFIG_CODE_DATA_RELOCATION */ #ifdef CONFIG_USERSPACE -#ifdef CONFIG_STACK_CANARIES +#ifdef CONFIG_REQUIRES_STACK_CANARIES /* stack canary checking is active for all C functions. * __stack_chk_guard is some uninitialized value living in the * app shared memory sections. Preserve it, and don't make any @@ -70,6 +70,6 @@ void z_data_copy(void) #else z_early_memcpy(&_app_smem_start, &_app_smem_rom_start, _app_smem_end - _app_smem_start); -#endif /* CONFIG_STACK_CANARIES */ +#endif /* CONFIG_REQUIRES_STACK_CANARIES */ #endif /* CONFIG_USERSPACE */ } diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index d0ab79f72a534..cde781c478e86 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -408,7 +408,7 @@ int acpi_legacy_irq_init(const char *hid, const char *uid) * If Name path exist then PCI interrupts are configurable and are not hardwired to * any specific interrupt inputs on the interrupt controller. OSPM can uses * _PRS/_CRS/_SRS to configure interrupts. But currently leave existing PCI bus - * driver with arch_irq_allocate() menthod for allocate and configure interrupts + * driver with arch_irq_allocate() method for allocate and configure interrupts * without conflicting. */ return -ENOENT; diff --git a/lib/cpp/Kconfig b/lib/cpp/Kconfig index 728162f55368d..da309ee3fbcd9 100644 --- a/lib/cpp/Kconfig +++ b/lib/cpp/Kconfig @@ -12,6 +12,27 @@ config CPP if CPP +config STD_CPP_VERSION + int + default 199711 if STD_CPP98 + default 201103 if STD_CPP11 + default 201402 if STD_CPP14 + default 201703 if STD_CPP17 + default 202002 if STD_CPP20 || STD_CPP2A || STD_CPP2B + help + The version number of C++ standard being used (NOTE: this uses the + full year and month, and is the same as the __cplusplus macro defined + by the compiler). This config can be used to check for a minimum + supported version. Example: + + depends on STD_CPP_VERSION >= 201703 + + Adding this to your library's enablement Kconfig will force a minimum + c++17 standard. + + The full year is used so c++98 can be checked using > and < operators + without conflicting with c++11 or higher. + choice STD_CPP prompt "C++ Standard" default STD_CPP11 diff --git a/lib/heap/CMakeLists.txt b/lib/heap/CMakeLists.txt index f3853fc5b7da8..1e4a339138899 100644 --- a/lib/heap/CMakeLists.txt +++ b/lib/heap/CMakeLists.txt @@ -11,3 +11,4 @@ zephyr_sources_ifdef(CONFIG_SYS_HEAP_STRESS heap_stress.c) zephyr_sources_ifdef(CONFIG_SHARED_MULTI_HEAP shared_multi_heap.c) zephyr_sources_ifdef(CONFIG_MULTI_HEAP multi_heap.c) zephyr_sources_ifdef(CONFIG_HEAP_LISTENER heap_listener.c) +zephyr_sources_ifdef(CONFIG_SYS_HEAP_ARRAY_SIZE heap_array.c) diff --git a/lib/heap/Kconfig b/lib/heap/Kconfig index 89ede27800613..0d97da3e340be 100644 --- a/lib/heap/Kconfig +++ b/lib/heap/Kconfig @@ -52,6 +52,18 @@ config SYS_HEAP_RUNTIME_STATS help Gather system heap runtime statistics. +config SYS_HEAP_ARRAY_SIZE + int "Size of array to store heap pointers" + default 0 + help + The size of the internal array to store heap pointers. The array + is filled with a heap pointer on every sys_heap_init() call. + One can then iterate through the array to get all heaps statistics + and to sum up the total memory allocated for all heaps. + + The default array size is zero, which disables the feature. + To enable the feature, assign a value greater than zero. + config SYS_HEAP_LISTENER bool "sys_heap event notifications" select HEAP_LISTENER diff --git a/lib/heap/heap.c b/lib/heap/heap.c index 7fb6884c90ee2..517c43f5085e7 100644 --- a/lib/heap/heap.c +++ b/lib/heap/heap.c @@ -517,6 +517,10 @@ void sys_heap_init(struct sys_heap *heap, void *mem, size_t bytes) h->max_allocated_bytes = 0; #endif +#if CONFIG_SYS_HEAP_ARRAY_SIZE + sys_heap_array_save(heap); +#endif + int nb_buckets = bucket_idx(h, heap_sz) + 1; chunksz_t chunk0_size = chunksz(sizeof(struct z_heap) + nb_buckets * sizeof(struct z_heap_bucket)); diff --git a/lib/heap/heap.h b/lib/heap/heap.h index 1be3bd9139277..85ba12e9c8130 100644 --- a/lib/heap/heap.h +++ b/lib/heap/heap.h @@ -10,7 +10,7 @@ * Internal heap APIs */ -/* Theese validation checks are non-trivially expensive, so enable +/* These validation checks are non-trivially expensive, so enable * only when debugging the heap code. They shouldn't be routine * assertions. */ diff --git a/lib/heap/heap_array.c b/lib/heap/heap_array.c new file mode 100644 index 0000000000000..dc1b3a4535d40 --- /dev/null +++ b/lib/heap/heap_array.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. www.silabs.com + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +static size_t i; +static struct sys_heap *heaps[CONFIG_SYS_HEAP_ARRAY_SIZE]; + +int sys_heap_array_save(struct sys_heap *heap) +{ + if (heap == NULL) { + return -EINVAL; + } + + if (i < CONFIG_SYS_HEAP_ARRAY_SIZE) { + heaps[i++] = heap; + } else { + return -EINVAL; + } + + return 0; +} + +int sys_heap_array_get(struct sys_heap ***heap) +{ + if (heap == NULL) { + return -EINVAL; + } + + *heap = heaps; + + return i; +} diff --git a/lib/libc/CMakeLists.txt b/lib/libc/CMakeLists.txt index a6fecf09d66c4..075e066d59b4b 100644 --- a/lib/libc/CMakeLists.txt +++ b/lib/libc/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_syscall_header( add_subdirectory_ifdef(CONFIG_ARCMWDT_LIBC arcmwdt) add_subdirectory_ifdef(CONFIG_ARMCLANG_STD_LIBC armstdc) +add_subdirectory_ifdef(CONFIG_IAR_LIBC iar) add_subdirectory_ifdef(CONFIG_MINIMAL_LIBC minimal) add_subdirectory_ifdef(CONFIG_NEWLIB_LIBC newlib) add_subdirectory_ifdef(CONFIG_PICOLIBC picolibc) diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 3012cdadf8d48..5d981e4719b0b 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -51,6 +51,13 @@ config PICOLIBC_SUPPORTED help Selected when the target has support for picolibc. +config IAR_LIBC_SUPPORTED + bool + default n + select FULL_LIBC_SUPPORTED + help + Selected if the target is an IAR Systems compiler + config NATIVE_LIBC_INCOMPATIBLE bool help @@ -65,6 +72,7 @@ choice LIBC_IMPLEMENTATION default PICOLIBC default NEWLIB_LIBC if REQUIRES_FULL_LIBC default MINIMAL_LIBC + default IAR_LIBC config MINIMAL_LIBC bool "Minimal C library" @@ -87,6 +95,7 @@ config PICOLIBC select NEED_LIBC_MEM_PARTITION select TC_PROVIDES_POSIX_C_LANG_SUPPORT_R imply COMMON_LIBC_MALLOC + imply COMMON_LIBC_ABORT depends on PICOLIBC_SUPPORTED help Build with picolibc library. The picolibc library is built as @@ -98,6 +107,7 @@ config NEWLIB_LIBC select COMMON_LIBC_ABORT depends on NEWLIB_LIBC_SUPPORTED select NEED_LIBC_MEM_PARTITION + select TC_PROVIDES_POSIX_C_LANG_SUPPORT_R imply POSIX_DEVICE_IO_ALIAS_CLOSE imply POSIX_DEVICE_IO_ALIAS_OPEN imply POSIX_DEVICE_IO_ALIAS_READ @@ -122,6 +132,17 @@ config EXTERNAL_LIBC help Build with external/user provided C library. +config IAR_LIBC + bool "IAR C Runtime Library" + depends on IAR_LIBC_SUPPORTED + depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "iar" + select COMMON_LIBC_STRNLEN + select COMMON_LIBC_TIME if POSIX_TIMERS + help + Use the full IAR Compiler runtime libraries. + A reduced Zephyr minimal libc will be used for library functionality + not provided by the IAR C Runtime Library. + endchoice # LIBC_IMPLEMENTATION config HAS_NEWLIB_LIBC_NANO diff --git a/lib/libc/armstdc/src/libc-hooks.c b/lib/libc/armstdc/src/libc-hooks.c index f9fe9d1c4200c..afce534eddfd6 100644 --- a/lib/libc/armstdc/src/libc-hooks.c +++ b/lib/libc/armstdc/src/libc-hooks.c @@ -23,7 +23,7 @@ void __stdout_hook_install(int (*hook)(int)) volatile int *__aeabi_errno_addr(void) { - return &arch_current_thread()->errno_var; + return &_current->errno_var; } int fputc(int c, FILE *f) diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index a75b028000df2..2b01e152f0098 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -101,8 +101,8 @@ static POOL_SECTION unsigned char __aligned(HEAP_ALIGN) malloc_arena[HEAP_SIZE]; # define HEAP_BASE ROUND_UP(USED_RAM_END_ADDR, HEAP_ALIGN) -# if defined(CONFIG_XTENSA) && (defined(CONFIG_SOC_FAMILY_INTEL_ADSP) \ - || defined(CONFIG_HAS_ESPRESSIF_HAL)) +# if (defined(CONFIG_XTENSA) && defined(CONFIG_SOC_FAMILY_INTEL_ADSP)) \ + || defined(CONFIG_HAS_ESPRESSIF_HAL) extern char _heap_sentry[]; # define HEAP_SIZE ROUND_DOWN((POINTER_TO_UINT(_heap_sentry) - HEAP_BASE), HEAP_ALIGN) # else diff --git a/lib/libc/iar/CMakeLists.txt b/lib/libc/iar/CMakeLists.txt new file mode 100644 index 0000000000000..f57ab75d2d303 --- /dev/null +++ b/lib/libc/iar/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(src/libc-hooks.c) +zephyr_system_include_directories(include) diff --git a/lib/libc/iar/include/errno.h b/lib/libc/iar/include/errno.h new file mode 100644 index 0000000000000..6310531a75c03 --- /dev/null +++ b/lib/libc/iar/include/errno.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Defines additional error numbers based on POSIX + */ + +#ifndef ZEPHYR_LIB_LIBC_IAR_INCLUDE_ERRNO_H_ +#define ZEPHYR_LIB_LIBC_IAR_INCLUDE_ERRNO_H_ + +#include_next + +#ifndef __cplusplus +#define EPERM 1 /**< Not owner */ +#define ENOENT 2 /**< No such file or directory */ +#define ESRCH 3 /**< No such context */ +#define EINTR 4 /**< Interrupted system call */ +#define EIO 5 /**< I/O error */ +#define ENXIO 6 /**< No such device or address */ +#define E2BIG 7 /**< Arg list too long */ +#define ENOEXEC 8 /**< Exec format error */ +#define EBADF 9 /**< Bad file number */ +#define ECHILD 10 /**< No children */ +#define EAGAIN 11 /**< No more contexts */ +#define ENOMEM 12 /**< Not enough core */ +#define EACCES 13 /**< Permission denied */ +#define EFAULT 14 /**< Bad address */ +#define ENOTBLK 15 /**< Block device required */ +#define EBUSY 16 /**< Mount device busy */ +#define EEXIST 17 /**< File exists */ +#define EXDEV 18 /**< Cross-device link */ +#define ENODEV 19 /**< No such device */ +#define ENOTDIR 20 /**< Not a directory */ +#define EISDIR 21 /**< Is a directory */ +#define EINVAL 22 /**< Invalid argument */ +#define ENFILE 23 /**< File table overflow */ +#define EMFILE 24 /**< Too many open files */ +#define ENOTTY 25 /**< Not a typewriter */ +#define ETXTBSY 26 /**< Text file busy */ +#define EFBIG 27 /**< File too large */ +#define ENOSPC 28 /**< No space left on device */ +#define ESPIPE 29 /**< Illegal seek */ +#define EROFS 30 /**< Read-only file system */ +#define EMLINK 31 /**< Too many links */ +#define EPIPE 32 /**< Broken pipe */ +#define ENOMSG 35 /**< Unexpected message type */ +#define EDEADLK 45 /**< Resource deadlock avoided */ +#define ENOLCK 46 /**< No locks available */ +#define ENOSTR 60 /**< STREAMS device required */ +#define ENODATA 61 /**< Missing expected message data */ +#define ETIME 62 /**< STREAMS timeout occurred */ +#define ENOSR 63 /**< Insufficient memory */ +#define EPROTO 71 /**< Generic STREAMS error */ +#define EBADMSG 77 /**< Invalid STREAMS message */ +#define ENOSYS 88 /**< Function not implemented */ +#define ENOTEMPTY 90 /**< Directory not empty */ +#define ENAMETOOLONG 91 /**< File name too long */ +#define ELOOP 92 /**< Too many levels of symbolic links */ +#define EOPNOTSUPP 95 /**< Operation not supported on socket */ +#define EPFNOSUPPORT 96 /**< Protocol family not supported */ +#define ECONNRESET 104 /**< Connection reset by peer */ +#define ENOBUFS 105 /**< No buffer space available */ +#define EAFNOSUPPORT 106 /**< Addr family not supported */ +#define EPROTOTYPE 107 /**< Protocol wrong type for socket */ +#define ENOTSOCK 108 /**< Socket operation on non-socket */ +#define ENOPROTOOPT 109 /**< Protocol not available */ +#define ESHUTDOWN 110 /**< Can't send after socket shutdown */ +#define ECONNREFUSED 111 /**< Connection refused */ +#define EADDRINUSE 112 /**< Address already in use */ +#define ECONNABORTED 113 /**< Software caused connection abort */ +#define ENETUNREACH 114 /**< Network is unreachable */ +#define ENETDOWN 115 /**< Network is down */ +#define ETIMEDOUT 116 /**< Connection timed out */ +#define EHOSTDOWN 117 /**< Host is down */ +#define EHOSTUNREACH 118 /**< No route to host */ +#define EINPROGRESS 119 /**< Operation now in progress */ +#define EALREADY 120 /**< Operation already in progress */ +#define EDESTADDRREQ 121 /**< Destination address required */ +#define EMSGSIZE 122 /**< Message size */ +#define EPROTONOSUPPORT 123 /**< Protocol not supported */ +#define ESOCKTNOSUPPORT 124 /**< Socket type not supported */ +#define EADDRNOTAVAIL 125 /**< Can't assign requested address */ +#define ENETRESET 126 /**< Network dropped connection on reset */ +#define EISCONN 127 /**< Socket is already connected */ +#define ENOTCONN 128 /**< Socket is not connected */ +#define ETOOMANYREFS 129 /**< Too many references: can't splice */ +#define ENOTSUP 134 /**< Unsupported value */ +#define EOVERFLOW 139 /**< Value overflow */ +#define ECANCELED 140 /**< Operation canceled */ +#define EWOULDBLOCK EAGAIN /**< Operation would block */ +#endif /* __cplusplus */ +#endif /* ZEPHYR_LIB_LIBC_IAR_INCLUDE_ERRNO_H_ */ diff --git a/lib/libc/iar/include/limits.h b/lib/libc/iar/include/limits.h new file mode 100644 index 0000000000000..50decad13ad18 --- /dev/null +++ b/lib/libc/iar/include/limits.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_IAR_INCLUDE_LIMITS_H_ +#define ZEPHYR_LIB_LIBC_IAR_INCLUDE_LIMITS_H_ + +#include_next + +#ifdef __cplusplus +extern "C" { +#endif + +#define PATH_MAX 256 + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LIB_LIBC_IAR_INCLUDE_LIMITS_H_ */ diff --git a/lib/libc/iar/include/sys/_timespec.h b/lib/libc/iar/include/sys/_timespec.h new file mode 100644 index 0000000000000..1ea3b4da5bff8 --- /dev/null +++ b/lib/libc/iar/include/sys/_timespec.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* file is intentionally empty */ diff --git a/lib/libc/iar/include/sys/_timeval.h b/lib/libc/iar/include/sys/_timeval.h new file mode 100644 index 0000000000000..43f8f7f8c8973 --- /dev/null +++ b/lib/libc/iar/include/sys/_timeval.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS__TIMEVAL_H_ +#define ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS__TIMEVAL_H_ + +#include + +#if !defined(__time_t_defined) +#define __time_t_defined +typedef long long time_t; +#endif + +#if !defined(__suseconds_t_defined) +#define __suseconds_t_defined +typedef int32_t suseconds_t; +#endif + +struct timeval { + time_t tv_sec; + suseconds_t tv_usec; +}; + +#endif /* ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS__TIMEVAL_H_ */ diff --git a/lib/libc/iar/include/sys/cdefs.h b/lib/libc/iar/include/sys/cdefs.h new file mode 100644 index 0000000000000..1ea3b4da5bff8 --- /dev/null +++ b/lib/libc/iar/include/sys/cdefs.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* file is intentionally empty */ diff --git a/lib/libc/iar/include/sys/timespec.h b/lib/libc/iar/include/sys/timespec.h new file mode 100644 index 0000000000000..d5c0549dbc9da --- /dev/null +++ b/lib/libc/iar/include/sys/timespec.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS_TIMESPEC_H_ +#define ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS_TIMESPEC_H_ + +#include +#include + +struct itimerspec { + struct timespec it_interval; /* Timer interval */ + struct timespec it_value; /* Timer expiration */ +}; + +#endif /* ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS_TIMESPEC_H_ */ diff --git a/lib/libc/iar/include/sys/types.h b/lib/libc/iar/include/sys/types.h new file mode 100644 index 0000000000000..9654efc25ee25 --- /dev/null +++ b/lib/libc/iar/include/sys/types.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS_TYPES_H_ +#define ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS_TYPES_H_ + +typedef unsigned int mode_t; +typedef signed long ssize_t; +typedef int off_t; +typedef __INT64_TYPE__ time_t; + +#if !defined(_CLOCK_T_DECLARED) && !defined(__clock_t_defined) +typedef unsigned int clock_t; +#define _CLOCK_T_DECLARED +#define __clock_t_defined +#endif + +#endif /* ZEPHYR_LIB_LIBC_IAR_INCLUDE_SYS_TYPES_H_ */ diff --git a/lib/libc/iar/include/time.h b/lib/libc/iar/include/time.h new file mode 100644 index 0000000000000..b095987857418 --- /dev/null +++ b/lib/libc/iar/include/time.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Declares additional time related functions based on POSIX + */ + +#ifndef ZEPHYR_LIB_LIBC_IAR_INCLUDE_TIME_H_ +#define ZEPHYR_LIB_LIBC_IAR_INCLUDE_TIME_H_ + +#include +#include_next + +#ifdef __cplusplus +extern "C" { +#endif + +char *asctime_r(const struct tm *ZRESTRICT tp, char *ZRESTRICT buf); +char *ctime_r(const time_t *clock, char *buf); +struct tm *gmtime_r(const time_t *ZRESTRICT timep, struct tm *ZRESTRICT result); +struct tm *localtime_r(const time_t *ZRESTRICT timer, struct tm *ZRESTRICT result); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_LIB_LIBC_IAR_INCLUDE_TIME_H_ */ diff --git a/lib/libc/iar/src/libc-hooks.c b/lib/libc/iar/src/libc-hooks.c new file mode 100644 index 0000000000000..d3deea9658a48 --- /dev/null +++ b/lib/libc/iar/src/libc-hooks.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 IAR Systems AB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static int _stdout_hook_default(int c) +{ + (void)(c); /* Prevent warning about unused argument */ + + return EOF; +} + +static int (*_stdout_hook)(int) = _stdout_hook_default; + +void __stdout_hook_install(int (*hook)(int)) +{ + _stdout_hook = hook; +} + +int fputc(int c, FILE *f) +{ + return (_stdout_hook)(c); +} + +#pragma weak __write +size_t __write(int handle, const unsigned char *buf, size_t bufSize) +{ + size_t nChars = 0; + /* Check for the command to flush all handles */ + if (handle == -1) { + return 0; + } + /* Check for stdout and stderr + * (only necessary if FILE descriptors are enabled.) + */ + if (handle != 1 && handle != 2) { + return -1; + } + for (/* Empty */; bufSize > 0; --bufSize) { + int ret = (_stdout_hook)(*buf); + + if (ret == EOF) { + break; + } + ++buf; + ++nChars; + } + return nChars; +} diff --git a/lib/libc/minimal/Kconfig b/lib/libc/minimal/Kconfig index 0b99994963de1..c6c3ef2976334 100644 --- a/lib/libc/minimal/Kconfig +++ b/lib/libc/minimal/Kconfig @@ -38,6 +38,7 @@ config MINIMAL_LIBC_RAND config MINIMAL_LIBC_TIME bool "Time functions" select COMMON_LIBC_TIME if POSIX_TIMERS + select POSIX_C_LANG_SUPPORT_R select COMMON_LIBC_GMTIME_R select COMMON_LIBC_ASCTIME select COMMON_LIBC_LOCALTIME_R_UTC diff --git a/lib/libc/newlib/libc-hooks.c b/lib/libc/newlib/libc-hooks.c index b4ae8e7c9e8e5..ba0c8efcdd96e 100644 --- a/lib/libc/newlib/libc-hooks.c +++ b/lib/libc/newlib/libc-hooks.c @@ -26,7 +26,7 @@ int _fstat(int fd, struct stat *st); int _read(int fd, void *buf, int nbytes); int _write(int fd, const void *buf, int nbytes); -int _open(const char *name, int mode); +int _open(const char *name, int flags, ...); int _close(int file); int _lseek(int file, int ptr, int dir); int _kill(int pid, int sig); @@ -239,7 +239,7 @@ int _write(int fd, const void *buf, int nbytes) } __weak FUNC_ALIAS(_write, write, int); -int _open(const char *name, int mode) +int _open(const char *name, int flags, ...) { return -1; } @@ -518,7 +518,7 @@ int _open_r(struct _reent *r, const char *name, int flags, int mode) ARG_UNUSED(r); ARG_UNUSED(flags); - return _open(name, mode); + return _open(name, flags, mode); } int _close_r(struct _reent *r, int file) diff --git a/lib/libc/picolibc/CMakeLists.txt b/lib/libc/picolibc/CMakeLists.txt index d1abfa675d25f..752379dd76d44 100644 --- a/lib/libc/picolibc/CMakeLists.txt +++ b/lib/libc/picolibc/CMakeLists.txt @@ -11,6 +11,8 @@ zephyr_library_sources( stdio.c ) +zephyr_library_compile_options($) + # define __LINUX_ERRNO_EXTENSIONS__ so we get errno defines like -ESHUTDOWN # used by the network stack zephyr_compile_definitions(__LINUX_ERRNO_EXTENSIONS__) diff --git a/lib/libc/picolibc/assert.c b/lib/libc/picolibc/assert.c index 806d996a230a1..7eede1e49d92b 100644 --- a/lib/libc/picolibc/assert.c +++ b/lib/libc/picolibc/assert.c @@ -11,18 +11,22 @@ FUNC_NORETURN void __assert_func(const char *file, int line, const char *function, const char *expression) { +#if __ASSERT_ON __ASSERT(0, "assertion \"%s\" failed: file \"%s\", line %d%s%s\n", expression, file, line, function ? ", function: " : "", function ? function : ""); - CODE_UNREACHABLE; +#endif + abort(); } #else FUNC_NORETURN void __assert_no_args(void) { +#if __ASSERT_ON __ASSERT_NO_MSG(0); - CODE_UNREACHABLE; +#endif + abort(); } #endif diff --git a/lib/net_buf/buf.c b/lib/net_buf/buf.c index 6d409430f0865..7b89e89fd7b73 100644 --- a/lib/net_buf/buf.c +++ b/lib/net_buf/buf.c @@ -271,12 +271,6 @@ struct net_buf *net_buf_alloc_len(struct net_buf_pool *pool, size_t size, k_spin_unlock(&pool->lock, key); - if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT) && - k_current_get() == k_work_queue_thread_get(&k_sys_work_q)) { - LOG_WRN("Timeout discarded. No blocking in syswq"); - timeout = K_NO_WAIT; - } - #if defined(CONFIG_NET_BUF_LOG) && (CONFIG_NET_BUF_LOG_LEVEL >= LOG_LEVEL_WRN) if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { uint32_t ref = k_uptime_get_32(); @@ -344,6 +338,8 @@ struct net_buf *net_buf_alloc_len(struct net_buf_pool *pool, size_t size, #if defined(CONFIG_NET_BUF_POOL_USAGE) atomic_dec(&pool->avail_count); __ASSERT_NO_MSG(atomic_get(&pool->avail_count) >= 0); + pool->max_used = MAX(pool->max_used, + pool->buf_count - atomic_get(&pool->avail_count)); #endif return buf; } diff --git a/lib/os/Kconfig b/lib/os/Kconfig index 9ce3be2a66ebf..004df87ccf390 100644 --- a/lib/os/Kconfig +++ b/lib/os/Kconfig @@ -106,6 +106,16 @@ config MPSC_CLEAR_ALLOCATED When enabled packet space is zeroed before returning from allocation. endif +if SCHED_DEADLINE + +config P4WQ_INIT_STAGE_EARLY + bool "Early initialization of P4WQ threads" + help + Initialize P4WQ threads early so that the P4WQ can be used on devices + initialization sequence. + +endif + config REBOOT bool "Reboot functionality" help diff --git a/lib/os/fdtable.c b/lib/os/fdtable.c index a2514b1c296be..0299e89812a34 100644 --- a/lib/os/fdtable.c +++ b/lib/os/fdtable.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -249,6 +248,7 @@ int zvfs_reserve_fd(void) (void)z_fd_ref(fd); fdtable[fd].obj = NULL; fdtable[fd].vtable = NULL; + fdtable[fd].offset = 0; k_mutex_init(&fdtable[fd].lock); k_condvar_init(&fdtable[fd].cond); } @@ -280,8 +280,14 @@ void zvfs_finalize_typed_fd(int fd, void *obj, const struct fd_op_vtable *vtable * variables to avoid keeping the lock for a long period of time. */ if (vtable && vtable->ioctl) { + int prev_errno = errno; + (void)zvfs_fdtable_call_ioctl(vtable, obj, ZFD_IOCTL_SET_LOCK, &fdtable[fd].lock); + if ((prev_errno != EOPNOTSUPP) && (errno == EOPNOTSUPP)) { + /* restore backed-up errno value if the backend does not support locking */ + errno = prev_errno; + } } } diff --git a/lib/os/mpsc_pbuf.c b/lib/os/mpsc_pbuf.c index eac184f5aa50c..56c8def5bc4fe 100644 --- a/lib/os/mpsc_pbuf.c +++ b/lib/os/mpsc_pbuf.c @@ -201,10 +201,12 @@ static bool drop_item_locked(struct mpsc_pbuf_buffer *buffer, uint32_t rd_wlen = buffer->get_wlen(item); - /* If packet is busy need to be ommited. */ + /* If packet is busy need to be omitted. */ if (!is_valid(item)) { return false; } else if (item->hdr.busy) { + bool ret = true; + MPSC_PBUF_DBG(buffer, "no space: Found busy packet %p (len:%d)", item, rd_wlen); /* Add skip packet before claimed packet. */ if (free_wlen) { @@ -215,15 +217,18 @@ static bool drop_item_locked(struct mpsc_pbuf_buffer *buffer, buffer->wr_idx = idx_inc(buffer, buffer->wr_idx, rd_wlen); /* If allocation wrapped around the buffer and found busy packet - * that was already ommited, skip it again. + * that was already omitted, skip it again and indicate that no + * packet was dropped. */ if (buffer->rd_idx == buffer->tmp_rd_idx) { buffer->tmp_rd_idx = idx_inc(buffer, buffer->tmp_rd_idx, rd_wlen); + ret = false; } buffer->tmp_wr_idx = buffer->tmp_rd_idx; buffer->rd_idx = buffer->tmp_rd_idx; buffer->flags |= MPSC_PBUF_FULL; + return ret; } else { /* Prepare packet dropping. */ rd_idx_inc(buffer, rd_wlen); @@ -373,7 +378,7 @@ union mpsc_pbuf_generic *mpsc_pbuf_alloc(struct mpsc_pbuf_buffer *buffer, add_skip_item(buffer, free_wlen); cont = true; } else if (IS_ENABLED(CONFIG_MULTITHREADING) && !K_TIMEOUT_EQ(timeout, K_NO_WAIT) && - !k_is_in_isr()) { + !k_is_in_isr() && arch_irq_unlocked(key.key)) { int err; k_spin_unlock(&buffer->lock, key); @@ -622,18 +627,28 @@ bool mpsc_pbuf_is_pending(struct mpsc_pbuf_buffer *buffer) void mpsc_pbuf_get_utilization(struct mpsc_pbuf_buffer *buffer, uint32_t *size, uint32_t *now) { + k_spinlock_key_t key = k_spin_lock(&buffer->lock); + /* One byte is left for full/empty distinction. */ *size = (buffer->size - 1) * sizeof(int); *now = get_usage(buffer) * sizeof(int); + + k_spin_unlock(&buffer->lock, key); } int mpsc_pbuf_get_max_utilization(struct mpsc_pbuf_buffer *buffer, uint32_t *max) { + int rc; + k_spinlock_key_t key = k_spin_lock(&buffer->lock); - if (!(buffer->flags & MPSC_PBUF_MAX_UTILIZATION)) { - return -ENOTSUP; + if (buffer->flags & MPSC_PBUF_MAX_UTILIZATION) { + *max = buffer->max_usage * sizeof(int); + rc = 0; + } else { + rc = -ENOTSUP; } - *max = buffer->max_usage * sizeof(int); - return 0; + k_spin_unlock(&buffer->lock, key); + + return rc; } diff --git a/lib/os/p4wq.c b/lib/os/p4wq.c index 5a48ee6cf7b26..6d519230c3748 100644 --- a/lib/os/p4wq.c +++ b/lib/os/p4wq.c @@ -87,10 +87,10 @@ static FUNC_NORETURN void p4wq_loop(void *p0, void *p1, void *p2) = CONTAINER_OF(r, struct k_p4wq_work, rbnode); rb_remove(&queue->queue, r); - w->thread = arch_current_thread(); + w->thread = _current; sys_dlist_append(&queue->active, &w->dlnode); - set_prio(arch_current_thread(), w); - thread_clear_requeued(arch_current_thread()); + set_prio(_current, w); + thread_clear_requeued(_current); k_spin_unlock(&queue->lock, k); @@ -101,10 +101,17 @@ static FUNC_NORETURN void p4wq_loop(void *p0, void *p1, void *p2) /* Remove from the active list only if it * wasn't resubmitted already */ - if (!thread_was_requeued(arch_current_thread())) { + if (!thread_was_requeued(_current)) { sys_dlist_remove(&w->dlnode); w->thread = NULL; - k_sem_give(&w->done_sem); + + if (queue->done_handler) { + k_spin_unlock(&queue->lock, k); + queue->done_handler(w); + k = k_spin_lock(&queue->lock); + } else { + k_sem_give(&w->done_sem); + } } } else { z_pend_curr(&queue->lock, k, &queue->waitq, K_FOREVER); @@ -152,6 +159,7 @@ static int static_init(void) if (!i || (pp->flags & K_P4WQ_QUEUE_PER_THREAD)) { k_p4wq_init(q); + q->done_handler = pp->done_handler; } q->flags = pp->flags; @@ -210,7 +218,11 @@ void k_p4wq_enable_static_thread(struct k_p4wq *queue, struct k_thread *thread, * so they can initialize in parallel instead of serially on the main * CPU. */ +#if defined(CONFIG_P4WQ_INIT_STAGE_EARLY) +SYS_INIT(static_init, POST_KERNEL, 1); +#else SYS_INIT(static_init, APPLICATION, 99); +#endif void k_p4wq_submit(struct k_p4wq *queue, struct k_p4wq_work *item) { @@ -223,9 +235,9 @@ void k_p4wq_submit(struct k_p4wq *queue, struct k_p4wq_work *item) item->deadline += k_cycle_get_32(); /* Resubmission from within handler? Remove from active list */ - if (item->thread == arch_current_thread()) { + if (item->thread == _current) { sys_dlist_remove(&item->dlnode); - thread_set_requeued(arch_current_thread()); + thread_set_requeued(_current); item->thread = NULL; } else { k_sem_init(&item->done_sem, 0, 1); @@ -296,7 +308,14 @@ bool k_p4wq_cancel(struct k_p4wq *queue, struct k_p4wq_work *item) if (ret) { rb_remove(&queue->queue, &item->rbnode); - k_sem_give(&item->done_sem); + + if (queue->done_handler) { + k_spin_unlock(&queue->lock, k); + queue->done_handler(item); + k = k_spin_lock(&queue->lock); + } else { + k_sem_give(&item->done_sem); + } } k_spin_unlock(&queue->lock, k); diff --git a/lib/posix/options/CMakeLists.txt b/lib/posix/options/CMakeLists.txt index 4be0e8b058c99..58f44773e31b9 100644 --- a/lib/posix/options/CMakeLists.txt +++ b/lib/posix/options/CMakeLists.txt @@ -71,9 +71,9 @@ if (NOT CONFIG_TC_PROVIDES_POSIX_FILE_SYSTEM) zephyr_library_sources_ifdef(CONFIG_POSIX_FILE_SYSTEM fs.c) endif() -zephyr_library_sources_ifdef(CONFIG_POSIX_FSYNC fsync.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_MEMLOCK mlockall.c) -zephyr_library_sources_ifdef(CONFIG_POSIX_MEMLOCK_RANGE mlock.c) +if (NOT CONFIG_TC_PROVIDES_POSIX_FILE_SYSTEM_R) + zephyr_library_sources_ifdef(CONFIG_POSIX_FILE_SYSTEM_R file_system_r.c) +endif() if (NOT CONFIG_TC_PROVIDES_POSIX_MEMORY_PROTECTION) zephyr_library_sources_ifdef(CONFIG_POSIX_MEMORY_PROTECTION mprotect.c) @@ -83,8 +83,6 @@ if (NOT CONFIG_TC_PROVIDES_POSIX_MAPPED_FILES) zephyr_library_sources_ifdef(CONFIG_POSIX_MAPPED_FILES mmap.c) endif() -zephyr_library_sources_ifdef(CONFIG_POSIX_MESSAGE_PASSING mqueue.c) - if (NOT CONFIG_TC_PROVIDES_POSIX_MULTI_PROCESS) zephyr_library_sources_ifdef(CONFIG_POSIX_MULTI_PROCESS sleep.c @@ -96,10 +94,6 @@ if (NOT CONFIG_TC_PROVIDES_POSIX_NETWORKING) zephyr_library_sources_ifdef(CONFIG_POSIX_NETWORKING net.c) endif() -if (NOT CONFIG_TC_PROVIDES_POSIX_SHARED_MEMORY_OBJECTS) - zephyr_library_sources_ifdef(CONFIG_POSIX_SHARED_MEMORY_OBJECTS shm.c) -endif() - if (NOT CONFIG_TC_PROVIDES_POSIX_SIGNALS) zephyr_library_sources_ifdef(CONFIG_POSIX_SIGNALS signal.c ${STRSIGNAL_TABLE_H}) endif() @@ -125,8 +119,6 @@ if (NOT CONFIG_TC_PROVIDES_POSIX_TIMERS) ) endif() -zephyr_library_sources_ifdef(CONFIG_POSIX_PRIORITY_SCHEDULING sched.c) - if (NOT CONFIG_TC_PROVIDES_POSIX_READER_WRITER_LOCKS) # Note: the Option is _POSIX_READER_WRITER_LOCKS, while the Option Group is POSIX_RW_LOCKS. # We have opted to use POSIX_READER_WRITER_LOCKS here to match the Option name. @@ -150,6 +142,15 @@ if (NOT CONFIG_TC_PROVIDES_POSIX_THREADS) ) endif() +if(NOT CONFIG_TC_PROVIDES_XSI_REALTIME) + zephyr_library_sources_ifdef(CONFIG_POSIX_FSYNC fsync.c) + zephyr_library_sources_ifdef(CONFIG_POSIX_MEMLOCK mlockall.c) + zephyr_library_sources_ifdef(CONFIG_POSIX_MEMLOCK_RANGE mlock.c) + zephyr_library_sources_ifdef(CONFIG_POSIX_MESSAGE_PASSING mqueue.c) + zephyr_library_sources_ifdef(CONFIG_POSIX_PRIORITY_SCHEDULING sched.c) + zephyr_library_sources_ifdef(CONFIG_POSIX_SHARED_MEMORY_OBJECTS shm.c) +endif() + zephyr_library_sources_ifdef(CONFIG_XOPEN_STREAMS stropts.c) if (NOT CONFIG_TC_PROVIDES_XSI_SYSTEM_LOGGING) @@ -169,3 +170,5 @@ zephyr_library_include_directories( ) zephyr_library_property(ALLOW_EMPTY TRUE) + +zephyr_library_compile_options(-U_POSIX_C_SOURCE -D_POSIX_C_SOURCE=200809L) diff --git a/lib/posix/options/Kconfig b/lib/posix/options/Kconfig index f453f5295d02d..15d7f2233e630 100644 --- a/lib/posix/options/Kconfig +++ b/lib/posix/options/Kconfig @@ -14,6 +14,7 @@ rsource "Kconfig.c_lang_r" rsource "Kconfig.c_lib_ext" rsource "Kconfig.device_io" rsource "Kconfig.fd_mgmt" +rsource "Kconfig.file_system_r" rsource "Kconfig.fs" rsource "Kconfig.mem" rsource "Kconfig.mqueue" @@ -28,7 +29,16 @@ rsource "Kconfig.signal" rsource "Kconfig.spinlock" rsource "Kconfig.sync_io" rsource "Kconfig.timer" -rsource "Kconfig.xsi" + +menu "X/Open system interfaces" + +rsource "Kconfig.xsi_realtime" +rsource "Kconfig.xsi_single_process" +rsource "Kconfig.xsi_streams" +rsource "Kconfig.xsi_system_logging" +rsource "Kconfig.xsi_threads_ext" + +endmenu # "X/Open system interfaces" rsource "Kconfig.compat" diff --git a/lib/posix/options/Kconfig.aio b/lib/posix/options/Kconfig.aio index 43e681f39abc8..2536301d6976b 100644 --- a/lib/posix/options/Kconfig.aio +++ b/lib/posix/options/Kconfig.aio @@ -3,8 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 config POSIX_ASYNCHRONOUS_IO - bool "POSIX asynchronous I/O [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX asynchronous I/O" help Enable this option for asynchronous I/O. This option is present for conformance purposes only. All functions listed in return -1 and set errno to ENOSYS. diff --git a/lib/posix/options/Kconfig.c_lang_r b/lib/posix/options/Kconfig.c_lang_r index 49f0f71e3f868..b2f1ae3ea4aaa 100644 --- a/lib/posix/options/Kconfig.c_lang_r +++ b/lib/posix/options/Kconfig.c_lang_r @@ -14,5 +14,5 @@ config POSIX_C_LANG_SUPPORT_R Option Group, consisting of asctime_r(), ctime_r(), gmtime_r(), localtime_r(), rand_r(), strerror_r(), and strtok_r() - For more informnation, please see + For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html diff --git a/lib/posix/options/Kconfig.c_lib_ext b/lib/posix/options/Kconfig.c_lib_ext index e8c55d8818b19..9dc4ae52520e0 100644 --- a/lib/posix/options/Kconfig.c_lib_ext +++ b/lib/posix/options/Kconfig.c_lib_ext @@ -10,7 +10,7 @@ menuconfig POSIX_C_LIB_EXT stpcpy(), stpncpy(), strcasecmp(), strdup(), strfmon(), and strncasecmp(), strndup(), and strnlen(). - For more informnation, please see + For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html if POSIX_C_LIB_EXT diff --git a/lib/posix/options/Kconfig.device_io b/lib/posix/options/Kconfig.device_io index 0b30f291fd327..416ccf74a6218 100644 --- a/lib/posix/options/Kconfig.device_io +++ b/lib/posix/options/Kconfig.device_io @@ -5,8 +5,7 @@ menu "POSIX device I/O" config POSIX_DEVICE_IO - bool "POSIX device I/O [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX device I/O" select REQUIRES_FULL_LIBC select ZVFS select ZVFS_POLL @@ -16,7 +15,7 @@ config POSIX_DEVICE_IO Group such as FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO(), close(), fdopen(), fileno(), open(), poll(), pread(), pselect(), pwrite(), read(), select(), and write(). - For more informnation, please see + For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html if POSIX_DEVICE_IO diff --git a/lib/posix/options/Kconfig.fd_mgmt b/lib/posix/options/Kconfig.fd_mgmt index 329036ffbf891..a41bba869da61 100644 --- a/lib/posix/options/Kconfig.fd_mgmt +++ b/lib/posix/options/Kconfig.fd_mgmt @@ -3,8 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 menuconfig POSIX_FD_MGMT - bool "POSIX file descriptor management [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX file descriptor management" help Select 'y' here and Zephyr will provide implementations for the POSIX_FD_MGMT Option Group. This includes support for dup(), dup2(), fcntl(), fseeko(), ftello(), ftruncate(), diff --git a/lib/posix/options/Kconfig.file_system_r b/lib/posix/options/Kconfig.file_system_r new file mode 100644 index 0000000000000..571100c9c3e87 --- /dev/null +++ b/lib/posix/options/Kconfig.file_system_r @@ -0,0 +1,14 @@ +# Copyright (c) 2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +config POSIX_FILE_SYSTEM_R + bool "Thread-Safe File System" + select FILE_SYSTEM + select FDTABLE + help + Select 'y' here and Zephyr will provide an implementation of the POSIX_FILE_SYSTEM_R + Option Group, consisting of readdir_r(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html diff --git a/lib/posix/options/Kconfig.fs b/lib/posix/options/Kconfig.fs index ce1acb118e0f4..bc492e5dc7a03 100644 --- a/lib/posix/options/Kconfig.fs +++ b/lib/posix/options/Kconfig.fs @@ -17,13 +17,4 @@ config POSIX_FILE_SYSTEM_ALIAS_FSTAT help When selected via Kconfig, Zephyr will provide an alias for fstat() as _fstat(). -config POSIX_FILE_SYSTEM_R - bool "Thread-Safe File System" - help - Select 'y' here and Zephyr will provide an implementation of the POSIX_FILE_SYSTEM_R - Option Group, consisting of readdir_r(). - - For more informnation, please see - https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html - endif # POSIX_FILE_SYSTEM diff --git a/lib/posix/options/Kconfig.mem b/lib/posix/options/Kconfig.mem index 57b9ad9670e41..346b5d363aac8 100644 --- a/lib/posix/options/Kconfig.mem +++ b/lib/posix/options/Kconfig.mem @@ -13,8 +13,7 @@ config POSIX_PAGE_SIZE This option is not user-configurable. config POSIX_SHARED_MEMORY_OBJECTS - bool "POSIX shared memory objects [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX shared memory objects" select SYS_HASH_FUNC32 select SYS_HASH_FUNC32_DJB2 select FDTABLE @@ -27,12 +26,13 @@ config POSIX_SHARED_MEMORY_OBJECTS https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html#tag_24_03_04 config POSIX_MAPPED_FILES - bool "POSIX memory-mapped files [EXPERIMENTAL]" - select EXPERIMENTAL - imply MMU + bool "POSIX memory-mapped files" help Select 'y' here and Zephyr will provide support for mmap(), msync(), and munmap(). + Note: This feature depends on hardware MMU support. If the underlying platform does not + support an MMU, then affected POSIX API functions may return -1 and set errno to ENOTSUP. + For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/V2_chap02.html https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html#tag_24_03_04 @@ -40,23 +40,27 @@ config POSIX_MAPPED_FILES if POSIX_MAPPED_FILES config POSIX_MEMLOCK - bool "POSIX memory locking [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX memory locking" help Select 'y' here and Zephyr will provide support for mlockall() and munlockall(). + Note: This feature depends on hardware MMU support as well as DEMAND_PAGING. If the + underlying platform does not support an MMU or DEMAND_PAGING, then affected POSIX API + functions will return -1 and set errno to ENOTSUP. + For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/V2_chap02.html https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html#tag_24_03_04 config POSIX_MEMLOCK_RANGE - bool "POSIX range memory locking [EXPERIMENTAL]" - select EXPERIMENTAL - imply MMU + bool "POSIX range memory locking" imply DEMAND_PAGING help Select 'y' here and Zephyr will provide support for mlock() and munlock(). + Note: This feature depends on hardware MMU support. If the underlying platform does not + support an MMU, then affected POSIX API functions will return -1 and set errno to ENOTSUP. + For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/V2_chap02.html https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_port.html#tag_24_03_04 @@ -64,8 +68,7 @@ config POSIX_MEMLOCK_RANGE endif config POSIX_MEMORY_PROTECTION - bool "POSIX memory protection [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX memory protection" help Select 'y' here and Zephyr will provide support for mprotect(). diff --git a/lib/posix/options/Kconfig.procN b/lib/posix/options/Kconfig.procN index b3a467b88b9d3..6a6b03023429e 100644 --- a/lib/posix/options/Kconfig.procN +++ b/lib/posix/options/Kconfig.procN @@ -3,8 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 menuconfig POSIX_MULTI_PROCESS - bool "POSIX multi-process support [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX multi-process support" help Support for multi-processing. diff --git a/lib/posix/options/Kconfig.profile b/lib/posix/options/Kconfig.profile index b57e07fbc2828..4f97786b0d577 100644 --- a/lib/posix/options/Kconfig.profile +++ b/lib/posix/options/Kconfig.profile @@ -102,8 +102,8 @@ config POSIX_BASE_DEFINITIONS select POSIX_ASYNCHRONOUS_IO select POSIX_BARRIERS select POSIX_CLOCK_SELECTION - # select POSIX_MAPPED_FILES - # select POSIX_MEMORY_PROTECTION + select POSIX_MAPPED_FILES + select POSIX_MEMORY_PROTECTION select POSIX_READER_WRITER_LOCKS select POSIX_REALTIME_SIGNALS select POSIX_SEMAPHORES @@ -128,10 +128,10 @@ config POSIX_AEP_REALTIME_MINIMAL select XSI_THREADS_EXT # Options select POSIX_FSYNC - # select POSIX_MEMLOCK - # select POSIX_MEMLOCK_RANGE + select POSIX_MEMLOCK + select POSIX_MEMLOCK_RANGE select POSIX_MONOTONIC_CLOCK - # select POSIX_SHARED_MEMORY_OBJECTS + select POSIX_SHARED_MEMORY_OBJECTS select POSIX_SYNCHRONIZED_IO select POSIX_THREAD_ATTR_STACKADDR select POSIX_THREAD_ATTR_STACKSIZE diff --git a/lib/posix/options/Kconfig.pthread b/lib/posix/options/Kconfig.pthread index f821d9defebb4..4eef794039a31 100644 --- a/lib/posix/options/Kconfig.pthread +++ b/lib/posix/options/Kconfig.pthread @@ -156,7 +156,7 @@ config POSIX_THREAD_PRIO_PROTECT config POSIX_THREAD_SAFE_FUNCTIONS bool "POSIX thread-safe functions" - select POSIX_FILE_SYSTEM_R if POSIX_FILE_SYSTEM + select POSIX_FILE_SYSTEM_R select POSIX_C_LANG_SUPPORT_R help Select 'y' here to enable POSIX thread-safe functions including asctime_r(), ctime_r(), diff --git a/lib/posix/options/Kconfig.sched b/lib/posix/options/Kconfig.sched index 7e0dc70fca119..08ca62787b132 100644 --- a/lib/posix/options/Kconfig.sched +++ b/lib/posix/options/Kconfig.sched @@ -5,8 +5,7 @@ menu "POSIX scheduler options" config POSIX_PRIORITY_SCHEDULING - bool "POSIX priority-based process scheduling [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX priority-based process scheduling" help This enables POSIX scheduling APIs (_POSIX_PRIORITY_SCHEDULING). diff --git a/lib/posix/options/Kconfig.signal b/lib/posix/options/Kconfig.signal index 1e84a55de598d..e844ee5eaab9c 100644 --- a/lib/posix/options/Kconfig.signal +++ b/lib/posix/options/Kconfig.signal @@ -5,8 +5,7 @@ menu "POSIX signals" config POSIX_REALTIME_SIGNALS - bool "POSIX realtime signals [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX realtime signals" help Enable support for POSIX realtime signals. @@ -22,8 +21,7 @@ config POSIX_RTSIG_MAX endif # POSIX_REALTIME_SIGNALS config POSIX_SIGNALS - bool "POSIX signals [EXPERIMENTAL]" - select EXPERIMENTAL + bool "POSIX signals" select POSIX_MULTI_PROCESS help Enable support for POSIX signals. diff --git a/lib/posix/options/Kconfig.toolchain b/lib/posix/options/Kconfig.toolchain index 30f274067e197..e328a03087944 100644 --- a/lib/posix/options/Kconfig.toolchain +++ b/lib/posix/options/Kconfig.toolchain @@ -135,9 +135,6 @@ config TC_PROVIDES_POSIX_READER_WRITER_LOCKS config TC_PROVIDES_POSIX_SEMAPHORES bool -config TC_PROVIDES_POSIX_SHARED_MEMORY_OBJECTS - bool - config TC_PROVIDES_POSIX_SHELL_FUNC bool @@ -215,6 +212,9 @@ config TC_PROVIDES_XSI_MATH config TC_PROVIDES_XSI_MULTI_PROCESS bool +config TC_PROVIDES_XSI_REALTIME + bool + config TC_PROVIDES_XSI_SIGNALS bool diff --git a/lib/posix/options/Kconfig.xsi b/lib/posix/options/Kconfig.xsi deleted file mode 100644 index f8be61e245d5d..0000000000000 --- a/lib/posix/options/Kconfig.xsi +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) 2024 Tenstorrent AI ULC -# -# SPDX-License-Identifier: Apache-2.0 - -menu "X/Open system interfaces" - -config XSI_SINGLE_PROCESS - bool "X/Open single process" - depends on POSIX_SINGLE_PROCESS - depends on POSIX_TIMERS - help - Select 'y' here and Zephyr will provide implementations of - gethostid(), gettimeofday(), and putenv(). - - For more information, please see - https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html - -config XOPEN_STREAMS - bool "X/Open streams" - help - This option provides support for the X/Open Streams interface, including functions such as - fattach(), fdetach(), getmsg(), getpmsg(), putmsg(), and putpmsg(). - - For more information, please see - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_05_09 - -config XSI_SYSTEM_LOGGING - bool "X/Open system logging" - help - This option provides support for closelog(), openlog(), syslog(), - setlogmask(), and vsyslog(). - - For more information, please see - https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html - -config XSI_THREADS_EXT - bool "X/Open threads extensions" - help - This option provides support for pthread_attr_getstack(), pthread_attr_setstack(), - pthread_getconcurrency(), and pthread_setconcurrency(). - - For more information, please see - https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html - -endmenu diff --git a/lib/posix/options/Kconfig.xsi_realtime b/lib/posix/options/Kconfig.xsi_realtime new file mode 100644 index 0000000000000..4c232b77a1dd2 --- /dev/null +++ b/lib/posix/options/Kconfig.xsi_realtime @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +config XSI_REALTIME + bool "X/Open realtime" + select POSIX_FSYNC + select POSIX_MEMLOCK + select POSIX_MEMLOCK_RANGE + select POSIX_MESSAGE_PASSING + # Not yet implemented, but optional + # imply POSIX_PRIORITIZED_IO + select POSIX_PRIORITY_SCHEDULING + select POSIX_SHARED_MEMORY_OBJECTS + select POSIX_SYNCHRONIZED_IO + help + Select 'y' here and the following functions will be provided: + + fsync(), mlockall(), munlockall(), mlock(), munlock(), mq_close(), mq_getattr(), mq_notify(), + mq_open(), mq_receive(), mq_send(), mq_setattr(), mq_unlink(), sched_get_priority_max(), + sched_get_priority_min(), sched_getparam(), sched_getscheduler(), sched_rr_get_interval(), + sched_setparam(), sched_setscheduler(), sched_yield(), mmap(), munmap(), shm_open(), + shm_unlink() + + The functions fsync(), fdatasync(), and open() will provide synchronized I/O capability. + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html diff --git a/lib/posix/options/Kconfig.xsi_single_process b/lib/posix/options/Kconfig.xsi_single_process new file mode 100644 index 0000000000000..ac5a8316455fa --- /dev/null +++ b/lib/posix/options/Kconfig.xsi_single_process @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +config XSI_SINGLE_PROCESS + bool "X/Open single process" + depends on POSIX_SINGLE_PROCESS + depends on POSIX_TIMERS + help + Select 'y' here and Zephyr will provide implementations of + gethostid(), gettimeofday(), and putenv(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html diff --git a/lib/posix/options/Kconfig.xsi_streams b/lib/posix/options/Kconfig.xsi_streams new file mode 100644 index 0000000000000..21b7e2010b517 --- /dev/null +++ b/lib/posix/options/Kconfig.xsi_streams @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +config XOPEN_STREAMS + bool "X/Open streams" + help + This option provides support for the X/Open Streams interface, including functions such as + fattach(), fdetach(), getmsg(), getpmsg(), putmsg(), and putpmsg(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_05_09 diff --git a/lib/posix/options/Kconfig.xsi_system_logging b/lib/posix/options/Kconfig.xsi_system_logging new file mode 100644 index 0000000000000..c7d9186bd9b03 --- /dev/null +++ b/lib/posix/options/Kconfig.xsi_system_logging @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +config XSI_SYSTEM_LOGGING + bool "X/Open system logging" + help + This option provides support for closelog(), openlog(), syslog(), + setlogmask(), and vsyslog(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html diff --git a/lib/posix/options/Kconfig.xsi_threads_ext b/lib/posix/options/Kconfig.xsi_threads_ext new file mode 100644 index 0000000000000..b990ff46309a0 --- /dev/null +++ b/lib/posix/options/Kconfig.xsi_threads_ext @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +config XSI_THREADS_EXT + bool "X/Open threads extensions" + help + This option provides support for pthread_attr_getstack(), pthread_attr_setstack(), + pthread_getconcurrency(), and pthread_setconcurrency(). + + For more information, please see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html diff --git a/lib/posix/options/barrier.c b/lib/posix/options/barrier.c index 7e2598b1bde84..c108b28da2171 100644 --- a/lib/posix/options/barrier.c +++ b/lib/posix/options/barrier.c @@ -19,7 +19,9 @@ struct posix_barrier { uint32_t count; }; +__pinned_bss static struct posix_barrier posix_barrier_pool[CONFIG_MAX_PTHREAD_BARRIER_COUNT]; + SYS_BITARRAY_DEFINE_STATIC(posix_barrier_bitarray, CONFIG_MAX_PTHREAD_BARRIER_COUNT); /* @@ -195,6 +197,7 @@ int pthread_barrierattr_destroy(pthread_barrierattr_t *attr) return 0; } +__boot_func static int pthread_barrier_pool_init(void) { int err; diff --git a/lib/posix/options/cond.c b/lib/posix/options/cond.c index f94c2ea7a3b5d..8155b993fcc22 100644 --- a/lib/posix/options/cond.c +++ b/lib/posix/options/cond.c @@ -17,7 +17,9 @@ LOG_MODULE_REGISTER(pthread_cond, CONFIG_PTHREAD_COND_LOG_LEVEL); int64_t timespec_to_timeoutms(const struct timespec *abstime); +__pinned_bss static struct k_condvar posix_cond_pool[CONFIG_MAX_PTHREAD_COND_COUNT]; + SYS_BITARRAY_DEFINE_STATIC(posix_cond_bitarray, CONFIG_MAX_PTHREAD_COND_COUNT); /* @@ -209,6 +211,7 @@ int pthread_cond_destroy(pthread_cond_t *cvar) return 0; } +__boot_func static int pthread_cond_pool_init(void) { int err; diff --git a/lib/posix/options/file_system_r.c b/lib/posix/options/file_system_r.c new file mode 100644 index 0000000000000..6cd14f9f81ad6 --- /dev/null +++ b/lib/posix/options/file_system_r.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Tenstorrent AI ULC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "fs_priv.h" + +#include +#include + +#include +#include +#include + +int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) +{ + int rc; + struct fs_dirent de; + struct posix_fs_desc *const ptr = dirp; + + if (result == NULL) { + return EINVAL; + } + + if (entry == NULL) { + *result = NULL; + return EINVAL; + } + + if (dirp == NULL) { + *result = NULL; + return EBADF; + } + + rc = fs_readdir(&ptr->dir, &de); + if (rc < 0) { + *result = NULL; + return -rc; + } + + strncpy(entry->d_name, de.name, MIN(sizeof(entry->d_name), sizeof(de.name))); + entry->d_name[sizeof(entry->d_name) - 1] = '\0'; + + if (entry->d_name[0] == '\0') { + *result = NULL; + return 0; + } + + *result = entry; + return 0; +} diff --git a/lib/posix/options/fs.c b/lib/posix/options/fs.c index c8221a35f955d..45028248608f7 100644 --- a/lib/posix/options/fs.c +++ b/lib/posix/options/fs.c @@ -6,6 +6,9 @@ #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L + +#include "fs_priv.h" + #include #include #include @@ -21,15 +24,6 @@ int zvfs_fstat(int fd, struct stat *buf); BUILD_ASSERT(PATH_MAX >= MAX_FILE_NAME, "PATH_MAX is less than MAX_FILE_NAME"); -struct posix_fs_desc { - union { - struct fs_file_t file; - struct fs_dir_t dir; - }; - bool is_dir; - bool used; -}; - static struct posix_fs_desc desc_array[CONFIG_POSIX_OPEN_MAX]; static struct fs_dirent fdirent; @@ -337,40 +331,6 @@ struct dirent *readdir(DIR *dirp) return &pdirent; } -#ifdef CONFIG_POSIX_FILE_SYSTEM_R -int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) -{ - struct dirent *dir; - - errno = 0; - - dir = readdir(dirp); - if (dir == NULL) { - int error = errno; - - if (error != 0) { - if (result != NULL) { - *result = NULL; - } - - return 0; - } else { - return error; - } - } - - if (entry != NULL) { - memcpy(entry, dir, sizeof(struct dirent)); - } - - if (result != NULL) { - *result = entry; - } - - return 0; -} -#endif /* CONFIG_POSIX_FILE_SYSTEM_R */ - /** * @brief Rename a file. * diff --git a/lib/posix/options/fs_priv.h b/lib/posix/options/fs_priv.h new file mode 100644 index 0000000000000..2c3ddb2084e82 --- /dev/null +++ b/lib/posix/options/fs_priv.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LIB_POSIX_OPTIONS_FS_PRIV_H_ +#define ZEPHYR_LIB_POSIX_OPTIONS_FS_PRIV_H_ + +#include + +#include + +struct posix_fs_desc { + union { + struct fs_file_t file; + struct fs_dir_t dir; + }; + bool is_dir: 1; + bool used: 1; +}; + +#endif diff --git a/lib/posix/options/mlock.c b/lib/posix/options/mlock.c index b81773c3a5711..00fee6a296562 100644 --- a/lib/posix/options/mlock.c +++ b/lib/posix/options/mlock.c @@ -9,16 +9,32 @@ #include #include +#include + int mlock(const void *addr, size_t len) { - k_mem_pin(addr, len); + if (IS_ENABLED(CONFIG_DEMAND_PAGING)) { + void *const _addr = (void *)addr; + + k_mem_pin(_addr, len); + + return 0; + } - return 0; + errno = ENOTSUP; + return -1; } int munlock(const void *addr, size_t len) { - k_mem_unpin(addr, len); + if (IS_ENABLED(CONFIG_DEMAND_PAGING)) { + void *const _addr = (void *)addr; + + k_mem_unpin(_addr, len); + + return 0; + } - return 0; + errno = ENOTSUP; + return -1; } diff --git a/lib/posix/options/mlockall.c b/lib/posix/options/mlockall.c index e921b9325352b..506eeb621022f 100644 --- a/lib/posix/options/mlockall.c +++ b/lib/posix/options/mlockall.c @@ -9,6 +9,7 @@ #include #include +#include int mlockall(int flags) { diff --git a/lib/posix/options/mprotect.c b/lib/posix/options/mprotect.c index 3bd2762763af3..6c795e3b96339 100644 --- a/lib/posix/options/mprotect.c +++ b/lib/posix/options/mprotect.c @@ -9,6 +9,7 @@ #include #include +#include int mprotect(void *addr, size_t len, int prot) { diff --git a/lib/posix/options/mutex.c b/lib/posix/options/mutex.c index cd320a969dca8..d6a54fd36d561 100644 --- a/lib/posix/options/mutex.c +++ b/lib/posix/options/mutex.c @@ -29,7 +29,9 @@ static const struct pthread_mutexattr def_attr = { .type = PTHREAD_MUTEX_DEFAULT, }; +__pinned_bss static struct k_mutex posix_mutex_pool[CONFIG_MAX_PTHREAD_MUTEX_COUNT]; + static uint8_t posix_mutex_type[CONFIG_MAX_PTHREAD_MUTEX_COUNT]; SYS_BITARRAY_DEFINE_STATIC(posix_mutex_bitarray, CONFIG_MAX_PTHREAD_MUTEX_COUNT); @@ -451,6 +453,7 @@ int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling) #endif /* CONFIG_POSIX_THREAD_PRIO_PROTECT */ +__boot_func static int pthread_mutex_pool_init(void) { int err; diff --git a/lib/posix/options/pthread.c b/lib/posix/options/pthread.c index 4ee2851dcdbff..33ee36668e66d 100644 --- a/lib/posix/options/pthread.c +++ b/lib/posix/options/pthread.c @@ -81,13 +81,19 @@ BUILD_ASSERT((PTHREAD_CANCEL_ENABLE == 0 || PTHREAD_CANCEL_DISABLE == 0) && BUILD_ASSERT(CONFIG_POSIX_PTHREAD_ATTR_STACKSIZE_BITS + CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS <= 32); +int64_t timespec_to_timeoutms(const struct timespec *abstime); static void posix_thread_recycle(void); + +__pinned_data static sys_dlist_t posix_thread_q[] = { SYS_DLIST_STATIC_INIT(&posix_thread_q[POSIX_THREAD_READY_Q]), SYS_DLIST_STATIC_INIT(&posix_thread_q[POSIX_THREAD_RUN_Q]), SYS_DLIST_STATIC_INIT(&posix_thread_q[POSIX_THREAD_DONE_Q]), }; + +__pinned_bss static struct posix_thread posix_thread_pool[CONFIG_MAX_PTHREAD_COUNT]; + static SYS_SEM_DEFINE(pthread_pool_lock, 1, 1); static int pthread_concurrency; @@ -1061,12 +1067,7 @@ void pthread_exit(void *retval) CODE_UNREACHABLE; } -/** - * @brief Wait for a thread termination. - * - * See IEEE 1003.1 - */ -int pthread_join(pthread_t pthread, void **status) +static int pthread_timedjoin_internal(pthread_t pthread, void **status, k_timeout_t timeout) { int ret = ESRCH; struct posix_thread *t = NULL; @@ -1115,8 +1116,19 @@ int pthread_join(pthread_t pthread, void **status) break; } - ret = k_thread_join(&t->thread, K_FOREVER); - /* other possibilities? */ + ret = k_thread_join(&t->thread, timeout); + if (ret != 0) { + /* when joining failed, ensure that the thread can be joined later */ + SYS_SEM_LOCK(&pthread_pool_lock) { + t->attr.detachstate = PTHREAD_CREATE_JOINABLE; + } + } + if (ret == -EBUSY) { + return EBUSY; + } else if (ret == -EAGAIN) { + return ETIMEDOUT; + } + /* Can only be ok or -EDEADLK, which should never occur for pthreads */ __ASSERT_NO_MSG(ret == 0); LOG_DBG("Joined pthread %p", &t->thread); @@ -1131,6 +1143,44 @@ int pthread_join(pthread_t pthread, void **status) return 0; } +/** + * @brief Await a thread termination with timeout. + * + * Non-portable GNU extension of IEEE 1003.1 + */ +int pthread_timedjoin_np(pthread_t pthread, void **status, const struct timespec *abstime) +{ + if (abstime == NULL) { + return EINVAL; + } + + if (abstime->tv_sec < 0 || abstime->tv_nsec < 0 || abstime->tv_nsec >= NSEC_PER_SEC) { + return EINVAL; + } + + return pthread_timedjoin_internal(pthread, status, K_MSEC(timespec_to_timeoutms(abstime))); +} + +/** + * @brief Check a thread for termination. + * + * Non-portable GNU extension of IEEE 1003.1 + */ +int pthread_tryjoin_np(pthread_t pthread, void **status) +{ + return pthread_timedjoin_internal(pthread, status, K_NO_WAIT); +} + +/** + * @brief Await a thread termination. + * + * See IEEE 1003.1 + */ +int pthread_join(pthread_t pthread, void **status) +{ + return pthread_timedjoin_internal(pthread, status, K_FOREVER); +} + /** * @brief Detach a thread. * @@ -1491,6 +1541,7 @@ int pthread_sigmask(int how, const sigset_t *ZRESTRICT set, sigset_t *ZRESTRICT return ret; } +__boot_func static int posix_thread_pool_init(void) { ARRAY_FOR_EACH_PTR(posix_thread_pool, th) { diff --git a/lib/posix/options/semaphore.c b/lib/posix/options/semaphore.c index fddad0caf6b20..537b618ff6f7c 100644 --- a/lib/posix/options/semaphore.c +++ b/lib/posix/options/semaphore.c @@ -33,7 +33,7 @@ static inline void nsem_list_lock(void) static inline void nsem_list_unlock(void) { - k_mutex_unlock(&nsem_mutex); + (void)k_mutex_unlock(&nsem_mutex); } static struct nsem_obj *nsem_find(const char *name) @@ -60,7 +60,7 @@ static void nsem_cleanup(struct nsem_obj *nsem) } } -/* Remove a named semaphore if it isn't unsed */ +/* Remove a named semaphore if it isn't used */ static void nsem_unref(struct nsem_obj *nsem) { nsem->ref_count -= 1; @@ -265,7 +265,7 @@ sem_t *sem_open(const char *name, int oflags, ...) goto unlock; } - /* Named sempahore doesn't exist, try to create new one */ + /* Named semaphore doesn't exist, try to create new one */ if ((oflags & O_CREAT) == 0) { errno = ENOENT; diff --git a/lib/posix/options/shm.c b/lib/posix/options/shm.c index d57fff7445406..56f45d0457a9b 100644 --- a/lib/posix/options/shm.c +++ b/lib/posix/options/shm.c @@ -159,7 +159,7 @@ static off_t shm_lseek(struct shm_obj *shm, off_t offset, int whence, size_t cur return -1; } - if ((INTPTR_MAX - addend) < offset) { + if ((addend > INTPTR_MAX) || ((INTPTR_MAX - addend) < offset)) { errno = EOVERFLOW; return -1; } @@ -305,7 +305,7 @@ int shm_open(const char *name, int oflag, mode_t mode) bool rw = (oflag & O_RDWR) != 0; bool creat = (oflag & O_CREAT) != 0; bool excl = (oflag & O_EXCL) != 0; - bool trunc = false; /* (oflag & O_TRUNC) != 0 */ + bool trunc = (oflag & O_TRUNC) != 0; size_t name_len = (name == NULL) ? 0 : strnlen(name, PATH_MAX); /* revisit when file-based permissions are available */ diff --git a/lib/smf/smf.c b/lib/smf/smf.c index 2c050526a5662..e511db240ec36 100644 --- a/lib/smf/smf.c +++ b/lib/smf/smf.c @@ -148,8 +148,6 @@ static bool smf_execute_ancestor_run_actions(struct smf_ctx *ctx) /* The child state either transitioned or handled it. Either way, stop propagating. */ if (internal->new_state || internal->handled) { - internal->new_state = false; - internal->handled = false; return false; } @@ -173,9 +171,6 @@ static bool smf_execute_ancestor_run_actions(struct smf_ctx *ctx) } } - internal->new_state = false; - internal->handled = false; - /* All done executing the run actions */ return false; @@ -209,10 +204,24 @@ static bool smf_execute_all_exit_actions(struct smf_ctx *const ctx, const struct } #endif /* CONFIG_SMF_ANCESTOR_SUPPORT */ -void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state) +/** + * @brief Reset the internal state of the state machine back to default values. + * Should be called on entry to smf_set_initial() and smf_set_state(). + * + * @param ctx State machine context. + */ +static void smf_clear_internal_state(struct smf_ctx *ctx) { struct internal_ctx *const internal = (void *)&ctx->internal; + internal->is_exit = false; + internal->terminate = false; + internal->handled = false; + internal->new_state = false; +} + +void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state) +{ #ifdef CONFIG_SMF_INITIAL_TRANSITION /* * The final target will be the deepest leaf state that @@ -223,15 +232,14 @@ void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state) } #endif - internal->is_exit = false; - internal->terminate = false; - internal->handled = false; - internal->new_state = false; + smf_clear_internal_state(ctx); ctx->current = init_state; ctx->previous = NULL; ctx->terminate_val = 0; #ifdef CONFIG_SMF_ANCESTOR_SUPPORT + struct internal_ctx *const internal = (void *)&ctx->internal; + ctx->executing = init_state; const struct smf_state *topmost = get_last_of(init_state); @@ -389,6 +397,11 @@ int32_t smf_run_state(struct smf_ctx *const ctx) return ctx->terminate_val; } + /* Executing a states run function could cause a transition, so clear the + * internal state to ensure that the transition is handled correctly. + */ + smf_clear_internal_state(ctx); + #ifdef CONFIG_SMF_ANCESTOR_SUPPORT ctx->executing = ctx->current; #endif diff --git a/lib/utils/json.c b/lib/utils/json.c index 6aa5f27646ea0..de1f8017e1e4c 100644 --- a/lib/utils/json.c +++ b/lib/utils/json.c @@ -728,7 +728,7 @@ static int arr_data_parse(struct json_obj *obj, struct json_obj_token *val) } else if (*obj->lex.pos == JSON_TOK_STRING) { string_state = true; } else if (*obj->lex.pos == JSON_TOK_ARRAY_START) { - /* arrary in array update structure count */ + /* array in array update structure count */ array_in_array++; } } diff --git a/lib/utils/ring_buffer.c b/lib/utils/ring_buffer.c index 39e6e257e9263..32d997205a27c 100644 --- a/lib/utils/ring_buffer.c +++ b/lib/utils/ring_buffer.c @@ -9,46 +9,45 @@ #include #include -uint32_t ring_buf_put_claim(struct ring_buf *buf, uint8_t **data, uint32_t size) +uint32_t ring_buf_area_claim(struct ring_buf *buf, struct ring_buf_index *ring, + uint8_t **data, uint32_t size) { - uint32_t free_space, wrap_size; + uint32_t wrap_size; int32_t base; - base = buf->put_base; - wrap_size = buf->put_head - base; + base = ring->base; + wrap_size = ring->head - base; if (unlikely(wrap_size >= buf->size)) { - /* put_base is not yet adjusted */ + /* ring->base is not yet adjusted */ wrap_size -= buf->size; base += buf->size; } wrap_size = buf->size - wrap_size; - - free_space = ring_buf_space_get(buf); - size = MIN(size, free_space); size = MIN(size, wrap_size); - *data = &buf->buffer[buf->put_head - base]; - buf->put_head += size; + *data = &buf->buffer[ring->head - base]; + ring->head += size; return size; } -int ring_buf_put_finish(struct ring_buf *buf, uint32_t size) +int ring_buf_area_finish(struct ring_buf *buf, struct ring_buf_index *ring, + uint32_t size) { - uint32_t finish_space, wrap_size; + uint32_t claimed_size, wrap_size; - finish_space = buf->put_head - buf->put_tail; - if (unlikely(size > finish_space)) { + claimed_size = ring->head - ring->tail; + if (unlikely(size > claimed_size)) { return -EINVAL; } - buf->put_tail += size; - buf->put_head = buf->put_tail; + ring->tail += size; + ring->head = ring->tail; - wrap_size = buf->put_tail - buf->put_base; + wrap_size = ring->tail - ring->base; if (unlikely(wrap_size >= buf->size)) { - /* we wrapped: adjust put_base */ - buf->put_base += buf->size; + /* we wrapped: adjust ring->base */ + ring->base += buf->size; } return 0; @@ -63,11 +62,14 @@ uint32_t ring_buf_put(struct ring_buf *buf, const uint8_t *data, uint32_t size) do { partial_size = ring_buf_put_claim(buf, &dst, size); + if (partial_size == 0) { + break; + } memcpy(dst, data, partial_size); total_size += partial_size; size -= partial_size; data += partial_size; - } while (size && partial_size); + } while (size != 0); err = ring_buf_put_finish(buf, total_size); __ASSERT_NO_MSG(err == 0); @@ -76,51 +78,6 @@ uint32_t ring_buf_put(struct ring_buf *buf, const uint8_t *data, uint32_t size) return total_size; } -uint32_t ring_buf_get_claim(struct ring_buf *buf, uint8_t **data, uint32_t size) -{ - uint32_t available_size, wrap_size; - int32_t base; - - base = buf->get_base; - wrap_size = buf->get_head - base; - if (unlikely(wrap_size >= buf->size)) { - /* get_base is not yet adjusted */ - wrap_size -= buf->size; - base += buf->size; - } - wrap_size = buf->size - wrap_size; - - available_size = ring_buf_size_get(buf); - size = MIN(size, available_size); - size = MIN(size, wrap_size); - - *data = &buf->buffer[buf->get_head - base]; - buf->get_head += size; - - return size; -} - -int ring_buf_get_finish(struct ring_buf *buf, uint32_t size) -{ - uint32_t finish_space, wrap_size; - - finish_space = buf->get_head - buf->get_tail; - if (unlikely(size > finish_space)) { - return -EINVAL; - } - - buf->get_tail += size; - buf->get_head = buf->get_tail; - - wrap_size = buf->get_tail - buf->get_base; - if (unlikely(wrap_size >= buf->size)) { - /* we wrapped: adjust get_base */ - buf->get_base += buf->size; - } - - return 0; -} - uint32_t ring_buf_get(struct ring_buf *buf, uint8_t *data, uint32_t size) { uint8_t *src; @@ -130,13 +87,16 @@ uint32_t ring_buf_get(struct ring_buf *buf, uint8_t *data, uint32_t size) do { partial_size = ring_buf_get_claim(buf, &src, size); + if (partial_size == 0) { + break; + } if (data) { memcpy(data, src, partial_size); data += partial_size; } total_size += partial_size; size -= partial_size; - } while (size && partial_size); + } while (size != 0); err = ring_buf_get_finish(buf, total_size); __ASSERT_NO_MSG(err == 0); @@ -152,16 +112,17 @@ uint32_t ring_buf_peek(struct ring_buf *buf, uint8_t *data, uint32_t size) uint32_t total_size = 0U; int err; - size = MIN(size, ring_buf_size_get(buf)); - do { partial_size = ring_buf_get_claim(buf, &src, size); + if (partial_size == 0) { + break; + } __ASSERT_NO_MSG(data != NULL); memcpy(data, src, partial_size); data += partial_size; total_size += partial_size; size -= partial_size; - } while (size && partial_size); + } while (size != 0); /* effectively unclaim total_size bytes */ err = ring_buf_get_finish(buf, 0); @@ -208,11 +169,14 @@ int ring_buf_item_put(struct ring_buf *buf, uint16_t type, uint8_t value, do { partial_size = ring_buf_put_claim(buf, &dst, size); + if (partial_size == 0) { + break; + } memcpy(dst, data, partial_size); size -= partial_size; total_size += partial_size; data += partial_size; - } while (size && partial_size); + } while (size != 0); __ASSERT_NO_MSG(size == 0); err = ring_buf_put_finish(buf, total_size); @@ -254,13 +218,16 @@ int ring_buf_item_get(struct ring_buf *buf, uint16_t *type, uint8_t *value, do { partial_size = ring_buf_get_claim(buf, &src, size); + if (partial_size == 0) { + break; + } if (data) { memcpy(data, src, partial_size); data += partial_size; } total_size += partial_size; size -= partial_size; - } while (size && partial_size); + } while (size != 0); err = ring_buf_get_finish(buf, total_size); __ASSERT_NO_MSG(err == 0); diff --git a/modules/Kconfig b/modules/Kconfig index 7e0e2b2872d10..a8cf861a68096 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -1,6 +1,14 @@ # Copyright (c) 2019 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +config BUILD_ONLY_NO_BLOBS + bool "Build only mode (do not link firmware blob)" + help + Exclude firmware blobs from the build. This will produce a + non-functional application, but allows drivers requiring + blobs to be built for testing purposes. Primarily intended + for CI validation of such drivers. + config TAINT_BLOBS bool select TAINT diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index 2706ad6583c98..73a6346f89b83 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -12,7 +12,7 @@ config MCUBOOT config BOOTLOADER_MCUBOOT bool "MCUboot bootloader support" - select USE_DT_CODE_PARTITION + select USE_DT_CODE_PARTITION if !MCUBOOT_BOOTLOADER_MODE_RAM_LOAD imply INIT_ARCH_HW_AT_BOOT if ARCH_SUPPORTS_ARCH_HW_INIT depends on !MCUBOOT help @@ -134,7 +134,7 @@ menu "On board MCUboot operation mode" choice MCUBOOT_BOOTLOADER_MODE prompt "Application assumed MCUboot mode of operation" - default MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH # MCUBOOT_BOOTLOADER_MODE + default MCUBOOT_BOOTLOADER_MODE_SWAP_USING_MOVE help Informs application build on assumed MCUboot mode of operation. This is important for validataing application against DT configuration, @@ -149,8 +149,17 @@ config MCUBOOT_BOOTLOADER_MODE_SINGLE_APP to DFU its own update to secondary slot and all updates need to be performed using MCUboot serial recovery. -config MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH - bool "MCUboot has been configured for swap without scratch operation" +config MCUBOOT_BOOTLOADER_MODE_SWAP_USING_OFFSET + bool "MCUboot has been configured for swap using offset operation" + select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE + help + MCUboot expects slot0_partition and slot1_partition to be present + in DT and application will boot from slot0_partition. + MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected + if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. + +config MCUBOOT_BOOTLOADER_MODE_SWAP_USING_MOVE + bool "MCUboot has been configured for swap using move operation" select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE help MCUboot expects slot0_partition and slot1_partition to be present @@ -158,6 +167,13 @@ config MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. +config MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH + bool "MCUboot has been configured for swap without scratch operation [DEPRECATED]" + select DEPRECATED + select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE + help + This Kconfig is deprecated, use MCUBOOT_BOOTLOADER_MODE_SWAP_USING_MOVE instead. + config MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH bool "MCUboot has been configured for swap using scratch operation" select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE diff --git a/modules/Kconfig.mcux b/modules/Kconfig.mcux index 87489810741ad..f6d7df3ab4f49 100644 --- a/modules/Kconfig.mcux +++ b/modules/Kconfig.mcux @@ -359,15 +359,15 @@ config HAS_MCUX_ADC_ETC Set if the ADC External Trigger Control module is present on the SoC. -config HAS_MCUX_XBARA +config HAS_MCUX_XCACHE bool help - Set if the XBARA module is present on the SoC. + Set if the XCACHE module is present on the SoC. -config HAS_NXP_MONOLITHIC_BT +config HAS_NXP_MONOLITHIC_NBU bool help - Set if the platform supports the monolithic build for BT applications. + Set if the platform supports the monolithic build for BT/15.4 applications. config NXP_FW_LOADER bool "Include firmware loader component" @@ -381,11 +381,11 @@ config NXP_MONOLITHIC_WIFI If enabled, the WiFi firmware used by the device will be linked with the application directly. -config NXP_MONOLITHIC_BT - bool "BT firmware monolithic build" - depends on HAS_NXP_MONOLITHIC_BT +config NXP_MONOLITHIC_NBU + bool "Narrowband Unit (BT/15.4) firmware monolithic build" + depends on HAS_NXP_MONOLITHIC_NBU help - If enabled, the BT firmware used by the device will be linked with the + If enabled, the NBU firmware used by the device will be linked with the application directly. config NXP_RF_IMU diff --git a/modules/Kconfig.renesas_fsp b/modules/Kconfig.renesas_fsp index 4b9eb15ddd4e9..6b35466490b3d 100644 --- a/modules/Kconfig.renesas_fsp +++ b/modules/Kconfig.renesas_fsp @@ -1,6 +1,6 @@ # Renesas FSP HAL config -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 config HAS_RENESAS_RA_FSP @@ -8,6 +8,11 @@ config HAS_RENESAS_RA_FSP help Enable Renesas RA FSP support +config HAS_RENESAS_RZ_FSP + bool + help + Enable Renesas RZ FSP support + if HAS_RENESAS_RA_FSP config USE_RA_FSP_SCI_B_UART @@ -50,10 +55,38 @@ if USE_RA_FSP_SCE config HAS_RENESAS_RA_RSIP_E51A bool default y - depends on ENTROPY_RENESAS_RA_RSIP_E51A_TRNG + depends on DT_HAS_RENESAS_RA_RSIP_E51A_TRNG_ENABLED help Includes RSIP-E51A implementation for SCE driver +config HAS_RENESAS_RA_SCE9 + bool + default y + depends on DT_HAS_RENESAS_RA_SCE9_RNG_ENABLED + help + Includes SCE9 implementation for SCE driver + +config HAS_RENESAS_RA_SCE7 + bool + default y + depends on DT_HAS_RENESAS_RA_SCE7_RNG_ENABLED + help + Includes SCE7 implementation for SCE driver + +config HAS_RENESAS_RA_SCE5 + bool + default y + depends on DT_HAS_RENESAS_RA_SCE5_RNG_ENABLED + help + Includes SCE5 implementation for SCE driver + +config HAS_RENESAS_RA_TRNG + bool + default y + depends on DT_HAS_RENESAS_RA_TRNG_ENABLED + help + Includes TRNG implementation for SCE driver + endif config USE_RA_FSP_SPI_B @@ -91,4 +124,68 @@ config USE_RA_FSP_ETHER help Enable RA FSP Ethernet driver +config USE_RA_FSP_USB_DEVICE + bool + help + Enable RA FSP USB Device Controller driver + +config USE_RA_FSP_SDRAM + bool + help + Enable RA FSP SDRAM support + +config USE_RA_FSP_DISPLAY + bool + help + Enable RA FSP Display driver + +config USE_RA_FSP_MIPI_DSI + bool + help + Enable RA FSP MIPI DSI driver + +config USE_RA_FSP_SDHI + bool + help + Enable RA FSP SDHI driver + +config USE_RA_FSP_DAC + bool + help + Enable RA FSP DAC driver + endif # HAS_RENESAS_RA_FSP + +if HAS_RENESAS_RZ_FSP + +config USE_RZ_FSP_IOPORT + bool + help + Enable RZ FSP IOPORT driver + +config USE_RZ_FSP_SCIF_UART + bool + help + Enable RZ FSP SCIF UART driver + +config USE_RZ_FSP_GTM + bool + help + Enable RZ FSP GTM driver + +config USE_RZ_FSP_GPT + bool + help + Enable RZ FSP GPT driver + +config USE_RZ_FSP_EXT_IRQ + bool + help + Enable RZ FSP External IRQ driver + +config USE_RZ_FSP_CPG + bool + help + Enable RZ FSP CLOCK CONTROL driver + +endif diff --git a/modules/Kconfig.simplelink b/modules/Kconfig.simplelink index 13b26b1ca1a48..3a1cea8ebb3e3 100644 --- a/modules/Kconfig.simplelink +++ b/modules/Kconfig.simplelink @@ -32,3 +32,8 @@ config HAS_CC13X2_CC26X2_SDK config HAS_CC13X2X7_CC26X2X7_SDK bool + +# CC23X0 SDK HAL configuration + +config HAS_CC23X0_SDK + bool diff --git a/modules/Kconfig.stm32 b/modules/Kconfig.stm32 index 500e2328444f8..c7d4437fd1316 100644 --- a/modules/Kconfig.stm32 +++ b/modules/Kconfig.stm32 @@ -30,6 +30,16 @@ config USE_STM32_HAL_ADC_EX Enable STM32Cube Extended Analog-to-Digital Converter (ADC) HAL module driver +config USE_STM32_HAL_BSEC + bool + help + Enable STM32Cube Boot and Security Control (BSEC) HAL module driver + +config USE_STM32_HAL_CACHEAXI + bool + help + Enable STM32Cube AXI Cache (CACHEAXI) HAL module driver + config USE_STM32_HAL_CAN bool help @@ -213,6 +223,11 @@ config USE_STM32_HAL_GFXMMU help Enable STM32Cube Chrom-GRCTM (GFXMMU) HAL module driver +config USE_STM32_HAL_GFXTIM + bool + help + Enable STM32Cube Graphic Timer (GFXTIM) HAL module driver + config USE_STM32_HAL_GPIO bool help @@ -335,6 +350,11 @@ config USE_STM32_HAL_LTDC_EX help Enable STM32Cube Extended LCD-TFT controller (LTDC) HAL module driver +config USE_STM32_HAL_MCE + bool + help + Enable STM32Cube Memory Cipher Engine (MCE) HAL module driver + config USE_STM32_HAL_MDF bool help @@ -463,11 +483,21 @@ config USE_STM32_HAL_RAMECC help Enable STM32Cube RAM ECC monitoring (RAMECC) HAL module driver +config USE_STM32_HAL_RIF + bool + help + Enable STM32Cube Resource Isolation Framework (RIF) HAL module driver + config USE_STM32_HAL_RNG bool help Enable STM32Cube True random number generator (RNG) HAL module driver +config USE_STM32_HAL_RNG_EX + bool + help + Enable STM32Cube Extended True random number generator (RNG) HAL module driver + config USE_STM32_HAL_RTC bool help @@ -506,6 +536,12 @@ config USE_STM32_HAL_SDADC help Enable STM32Cube SDADC HAL module driver +config USE_STM32_HAL_SDIO + bool + help + Enable STM32Cube Secure digital input/output interface (SDIO) + HAL module driver + config USE_STM32_HAL_SDRAM bool help @@ -527,6 +563,11 @@ config USE_STM32_HAL_SMBUS help Enable STM32Cube System Management Bus (SMBus) HAL module driver +config USE_STM32_HAL_SMBUS_EX + bool + help + Enable STM32Cube Extended System Management Bus (SMBus) HAL module driver + config USE_STM32_HAL_SPDIFRX bool help @@ -650,7 +691,7 @@ config USE_STM32_LL_DELAYBLOCK config USE_STM32_LL_DLYB bool help - Enable STM32Cube DelayBlock (DELAYBLOCK) LL module driver (stm32U5) + Enable STM32Cube DelayBlock (DELAYBLOCK) LL module driver (stm32U5 or STM32N6) config USE_STM32_LL_DMA bool @@ -817,4 +858,14 @@ config USE_STM32_LL_UTILS help Enable STM32Cube Utility functions (UTILS) LL module driver +config USE_STM32_LL_VENC + bool + help + Enable STM32Cube Video Encoder (VENC) LL module driver + +config USE_STM32_UTIL_I3C + bool + help + Enable STM32Cube I3C Timing Utility functions (UTILS) module driver + endif # HAS_STM32CUBE diff --git a/modules/Kconfig.tinycrypt b/modules/Kconfig.tinycrypt index 168e05ed79980..b54ad7641285e 100644 --- a/modules/Kconfig.tinycrypt +++ b/modules/Kconfig.tinycrypt @@ -9,6 +9,7 @@ config ZEPHYR_TINYCRYPT_MODULE config TINYCRYPT bool "TinyCrypt Support" depends on ZEPHYR_TINYCRYPT_MODULE + select DEPRECATED help This option enables the TinyCrypt cryptography library. diff --git a/modules/cmsis-nn/CMakeLists.txt b/modules/cmsis-nn/CMakeLists.txt index ec55bafbcfa7a..0fdf3db9675e6 100644 --- a/modules/cmsis-nn/CMakeLists.txt +++ b/modules/cmsis-nn/CMakeLists.txt @@ -85,4 +85,14 @@ if(CONFIG_CMSIS_NN) zephyr_library_sources(${SRC}) endif() + if(CONFIG_CMSIS_NN_TRANSPOSE) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/TransposeFunctions/*_s8.c") + zephyr_library_sources(${SRC}) + endif() + + if(CONFIG_CMSIS_NN_PAD) + file(GLOB SRC "${CMSIS_NN_DIR}/Source/PadFunctions/*_s8.c") + zephyr_library_sources(${SRC}) + endif() + endif() diff --git a/modules/cmsis-nn/Kconfig b/modules/cmsis-nn/Kconfig index 53c3aa4987d7d..dd5395f92efaa 100644 --- a/modules/cmsis-nn/Kconfig +++ b/modules/cmsis-nn/Kconfig @@ -78,4 +78,14 @@ config CMSIS_NN_LSTM help This option enables the NN libraries for Long Short-Term Memory. +config CMSIS_NN_PAD + bool "Pad" + help + This option enables the NN libraries for the pad layers. + +config CMSIS_NN_TRANSPOSE + bool "Transpose" + help + This option enables the NN libraries for the transpose layers. + endif #CMSIS_NN diff --git a/modules/fatfs/zephyr_fatfs_config.h b/modules/fatfs/zephyr_fatfs_config.h index 396f303ac0f7f..e55cdc3330271 100644 --- a/modules/fatfs/zephyr_fatfs_config.h +++ b/modules/fatfs/zephyr_fatfs_config.h @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#if FFCONF_DEF != 80286 +#if FFCONF_DEF != 5380 #error "Configuration version mismatch" #endif @@ -117,6 +117,21 @@ #define FF_USE_FIND 1 #endif /* defined(CONFIG_FS_FATFS_EXTRA_NATIVE_API) */ +/* + * When custom mount points are activated FF_VOLUME_STRS needs + * to be undefined in order to be able to provide a custom + * VolumeStr array containing the contents of + * CONFIG_FS_FATFS_CUSTOM_MOUNT_POINTS. Additionally the + * FF_VOLUMES define needs to be set to the correct mount + * point count contained in + * CONFIG_FS_FATFS_CUSTOM_MOUNT_POINT_COUNT. + */ +#if CONFIG_FS_FATFS_CUSTOM_MOUNT_POINT_COUNT +#undef FF_VOLUMES +#define FF_VOLUMES CONFIG_FS_FATFS_CUSTOM_MOUNT_POINT_COUNT +#undef FF_VOLUME_STRS +#endif /* CONFIG_FS_FATFS_CUSTOM_MOUNT_POINT_COUNT */ + /* * Options provided below have been added to ELM FAT source code to * support Zephyr specific features, and are not part of ffconf.h. diff --git a/modules/fatfs/zfs_diskio.c b/modules/fatfs/zfs_diskio.c index 2b0fa742e711e..d79c5b111bbdc 100644 --- a/modules/fatfs/zfs_diskio.c +++ b/modules/fatfs/zfs_diskio.c @@ -16,14 +16,19 @@ #include /* Zephyr specific FatFS API */ #include -static const char * const pdrv_str[] = {FF_VOLUME_STRS}; +#if CONFIG_FS_FATFS_CUSTOM_MOUNT_POINT_COUNT +#define PDRV_STR_ARRAY VolumeStr +#else +static const char *const pdrv_str[] = {FF_VOLUME_STRS}; +#define PDRV_STR_ARRAY pdrv_str +#endif /* CONFIG_FS_FATFS_CUSTOM_MOUNT_POINT_COUNT */ /* Get Drive Status */ DSTATUS disk_status(BYTE pdrv) { - __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + __ASSERT(pdrv < ARRAY_SIZE(PDRV_STR_ARRAY), "pdrv out-of-range\n"); - if (disk_access_status(pdrv_str[pdrv]) != 0) { + if (disk_access_status(PDRV_STR_ARRAY[pdrv]) != 0) { return STA_NOINIT; } else { return RES_OK; @@ -41,22 +46,21 @@ DSTATUS disk_initialize(BYTE pdrv) /* Read Sector(s) */ DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) { - __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + __ASSERT(pdrv < ARRAY_SIZE(PDRV_STR_ARRAY), "pdrv out-of-range\n"); - if (disk_access_read(pdrv_str[pdrv], buff, sector, count) != 0) { + if (disk_access_read(PDRV_STR_ARRAY[pdrv], buff, sector, count) != 0) { return RES_ERROR; } else { return RES_OK; } - } /* Write Sector(s) */ DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count) { - __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + __ASSERT(pdrv < ARRAY_SIZE(PDRV_STR_ARRAY), "pdrv out-of-range\n"); - if (disk_access_write(pdrv_str[pdrv], buff, sector, count) != 0) { + if (disk_access_write(PDRV_STR_ARRAY[pdrv], buff, sector, count) != 0) { return RES_ERROR; } else { return RES_OK; @@ -69,19 +73,18 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) int ret = RES_OK; uint32_t sector_size = 0; - __ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n"); + __ASSERT(pdrv < ARRAY_SIZE(PDRV_STR_ARRAY), "pdrv out-of-range\n"); switch (cmd) { case CTRL_SYNC: - if (disk_access_ioctl(pdrv_str[pdrv], - DISK_IOCTL_CTRL_SYNC, buff) != 0) { + if (disk_access_ioctl(PDRV_STR_ARRAY[pdrv], DISK_IOCTL_CTRL_SYNC, buff) != 0) { ret = RES_ERROR; } break; case GET_SECTOR_COUNT: - if (disk_access_ioctl(pdrv_str[pdrv], - DISK_IOCTL_GET_SECTOR_COUNT, buff) != 0) { + if (disk_access_ioctl(PDRV_STR_ARRAY[pdrv], DISK_IOCTL_GET_SECTOR_COUNT, buff) != + 0) { ret = RES_ERROR; } break; @@ -91,9 +94,9 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) * 32-bit number while FatFS's GET_SECTOR_SIZE is supposed to * return a 16-bit number. */ - if ((disk_access_ioctl(pdrv_str[pdrv], - DISK_IOCTL_GET_SECTOR_SIZE, §or_size) == 0) && - (sector_size == (uint16_t)sector_size)) { + if ((disk_access_ioctl(PDRV_STR_ARRAY[pdrv], DISK_IOCTL_GET_SECTOR_SIZE, + §or_size) == 0) && + (sector_size == (uint16_t)sector_size)) { *(uint16_t *)buff = (uint16_t)sector_size; } else { ret = RES_ERROR; @@ -101,8 +104,8 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) break; case GET_BLOCK_SIZE: - if (disk_access_ioctl(pdrv_str[pdrv], - DISK_IOCTL_GET_ERASE_BLOCK_SZ, buff) != 0) { + if (disk_access_ioctl(PDRV_STR_ARRAY[pdrv], DISK_IOCTL_GET_ERASE_BLOCK_SZ, buff) != + 0) { ret = RES_ERROR; } break; @@ -113,16 +116,14 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) case CTRL_POWER: if (((*(uint8_t *)buff)) == DISK_IOCTL_POWER_OFF) { /* Power disk off */ - if (disk_access_ioctl(pdrv_str[pdrv], - DISK_IOCTL_CTRL_DEINIT, - NULL) != 0) { + if (disk_access_ioctl(PDRV_STR_ARRAY[pdrv], DISK_IOCTL_CTRL_DEINIT, NULL) != + 0) { ret = RES_ERROR; } } else { /* Power disk on */ - if (disk_access_ioctl(pdrv_str[pdrv], - DISK_IOCTL_CTRL_INIT, - NULL) != 0) { + if (disk_access_ioctl(PDRV_STR_ARRAY[pdrv], DISK_IOCTL_CTRL_INIT, NULL) != + 0) { ret = STA_NOINIT; } } diff --git a/modules/hal_ethos_u/Kconfig b/modules/hal_ethos_u/Kconfig index 2c442de51a61a..4ca5136cf023a 100644 --- a/modules/hal_ethos_u/Kconfig +++ b/modules/hal_ethos_u/Kconfig @@ -26,6 +26,16 @@ config ARM_ETHOS_U65_256 bool "using Ethos-U65 with 256 macs" config ARM_ETHOS_U65_512 bool "using Ethos-U65 with 512 macs" +config ARM_ETHOS_U85_128 + bool "using Ethos-U85 with 128 macs" +config ARM_ETHOS_U85_256 + bool "using Ethos-U85 with 256 macs" +config ARM_ETHOS_U85_512 + bool "using Ethos-U85 with 512 macs" +config ARM_ETHOS_U85_1024 + bool "using Ethos-U85 with 1024 macs" +config ARM_ETHOS_U85_2048 + bool "using Ethos-U85 with 2048 macs" endchoice endmenu @@ -37,6 +47,11 @@ config ARM_ETHOS_U_NPU_NAME default "ethos-u65-128" if ARM_ETHOS_U65_128 default "ethos-u65-256" if ARM_ETHOS_U65_256 default "ethos-u65-512" if ARM_ETHOS_U65_512 + default "ethos-u85-128" if ARM_ETHOS_U85_128 + default "ethos-u85-256" if ARM_ETHOS_U85_256 + default "ethos-u85-512" if ARM_ETHOS_U85_512 + default "ethos-u85-1024" if ARM_ETHOS_U85_1024 + default "ethos-u85-2048" if ARM_ETHOS_U85_2048 help Name of the used Arm NPU diff --git a/modules/hal_infineon/Kconfig b/modules/hal_infineon/Kconfig index 17c2d283ce41d..eba1a49e24e73 100644 --- a/modules/hal_infineon/Kconfig +++ b/modules/hal_infineon/Kconfig @@ -14,6 +14,11 @@ config USE_INFINEON_ADC help Enable Analog-to-Digital Converter (ADC) HAL module driver for Infineon devices +config USE_INFINEON_DMA + bool + help + Enable ADC HAL module driver for Infineon devices + config USE_INFINEON_I2C bool help diff --git a/modules/hal_infineon/abstraction-rtos/source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c b/modules/hal_infineon/abstraction-rtos/source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c index c9df61b2f7382..27cf46f9a58be 100644 --- a/modules/hal_infineon/abstraction-rtos/source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c +++ b/modules/hal_infineon/abstraction-rtos/source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c @@ -232,6 +232,7 @@ cy_rslt_t cy_rtos_get_thread_state(cy_thread_t *thread, cy_thread_state_t *state break; case _THREAD_SUSPENDED: + case _THREAD_SLEEPING: case _THREAD_PENDING: *state = CY_THREAD_STATE_BLOCKED; break; @@ -307,10 +308,8 @@ cy_rslt_t cy_rtos_wait_thread_notification(cy_time_t timeout_ms) return status; } -cy_rslt_t cy_rtos_thread_set_notification(cy_thread_t *thread, bool in_isr) +cy_rslt_t cy_rtos_thread_set_notification(cy_thread_t *thread) { - CY_UNUSED_PARAMETER(in_isr); - cy_rslt_t status = CY_RSLT_SUCCESS; if (thread == NULL) { @@ -425,8 +424,6 @@ cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, u cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr) { - CY_UNUSED_PARAMETER(in_isr); - cy_rtos_error_t status_internal; cy_rslt_t status; @@ -461,8 +458,6 @@ cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr) { - CY_UNUSED_PARAMETER(in_isr); - cy_rslt_t status = CY_RSLT_SUCCESS; if (semaphore == NULL) { @@ -522,8 +517,6 @@ cy_rslt_t cy_rtos_init_event(cy_event_t *event) cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr) { - CY_UNUSED_PARAMETER(in_isr); - cy_rslt_t status = CY_RSLT_SUCCESS; if (event == NULL) { @@ -538,8 +531,6 @@ cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr) cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr) { - CY_UNUSED_PARAMETER(in_isr); - cy_rslt_t status = CY_RSLT_SUCCESS; if (event == NULL) { @@ -644,8 +635,6 @@ cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize) cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t timeout_ms, bool in_isr) { - CY_UNUSED_PARAMETER(in_isr); - cy_rtos_error_t status_internal; cy_rslt_t status; @@ -673,8 +662,6 @@ cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t t cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout_ms, bool in_isr) { - CY_UNUSED_PARAMETER(in_isr); - cy_rtos_error_t status_internal; cy_rslt_t status; diff --git a/modules/hal_infineon/mtb-hal-cat1/CMakeLists.txt b/modules/hal_infineon/mtb-hal-cat1/CMakeLists.txt index 268ae46546fd0..615d7874dec7c 100644 --- a/modules/hal_infineon/mtb-hal-cat1/CMakeLists.txt +++ b/modules/hal_infineon/mtb-hal-cat1/CMakeLists.txt @@ -73,8 +73,6 @@ zephyr_library_sources_ifdef(CONFIG_SOC_DIE_PSOC6_04 ${hal_cat1a_dir}/source/triggers/cyhal_triggers_psoc6_04.c) # High level interface for interacting with CAT1 hardware -zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ADC ${hal_dir}/source/cyhal_adc_sar.c) -zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ADC ${hal_dir}/source/cyhal_analog_common.c) zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_FLASH ${hal_dir}/source/cyhal_nvm.c) zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_I2C ${hal_dir}/source/cyhal_i2c.c) zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_LPTIMER ${hal_dir}/source/cyhal_lptimer.c) @@ -85,6 +83,9 @@ zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_TIMER ${hal_dir}/source/cyhal zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_TRNG ${hal_dir}/source/cyhal_trng.c) zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_UART ${hal_dir}/source/cyhal_uart.c) zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_WDT ${hal_dir}/source/cyhal_wdt.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_DMA ${hal_dir}/source/cyhal_dma.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_DMA ${hal_dir}/source/cyhal_dma_dw.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_DMA ${hal_dir}/source/cyhal_dma_dmac.c) if(CONFIG_USE_INFINEON_ADC OR CONFIG_USE_INFINEON_SMIF) zephyr_library_sources(${hal_dir}/source/cyhal_dma.c) @@ -92,6 +93,16 @@ if(CONFIG_USE_INFINEON_ADC OR CONFIG_USE_INFINEON_SMIF) zephyr_library_sources(${hal_dir}/source/cyhal_dma_dw.c) endif() +if(CONFIG_SOC_FAMILY_INFINEON_CAT1B) + zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ADC ${hal_dir}/source/cyhal_adc_mic.c) +else() + zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ADC ${hal_dir}/source/cyhal_adc_sar.c) +endif() + +if(CONFIG_USE_INFINEON_ADC) + zephyr_library_sources(${hal_dir}/source/cyhal_analog_common.c) +endif() + if(CONFIG_USE_INFINEON_TIMER) zephyr_library_sources(${hal_dir}/source/cyhal_tcpwm_common.c) endif() diff --git a/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt b/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt index 1166a48438198..4eca9d8f882f7 100644 --- a/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt +++ b/modules/hal_infineon/mtb-pdl-cat1/CMakeLists.txt @@ -61,7 +61,7 @@ if(CONFIG_USE_INFINEON_UART OR CONFIG_USE_INFINEON_I2C OR CONFIG_USE_INFINEON_SP zephyr_library_sources(${pdl_drv_dir}/source/cy_scb_common.c) endif() -if(CONFIG_USE_INFINEON_ADC OR CONFIG_USE_INFINEON_SMIF) +if(CONFIG_USE_INFINEON_DMA OR CONFIG_USE_INFINEON_ADC OR CONFIG_USE_INFINEON_SMIF) zephyr_library_sources(${pdl_drv_dir}/source/cy_dma.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_dmac.c) endif() @@ -98,6 +98,7 @@ zephyr_library_sources(${pdl_drv_dir}/source/cy_syspm.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_systick.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_trigmux.c) zephyr_library_sources(${pdl_drv_dir}/source/cy_wdt.c) +zephyr_library_sources(${pdl_drv_dir}/source/cy_tcpwm_pwm.c) # add IPC_BT driver for CYW208XX devices zephyr_library_sources_ifdef(CONFIG_BT_CYW208XX ${pdl_drv_dir}/source/cy_ipc_bt.c) diff --git a/modules/hal_infineon/wifi-host-driver/CMakeLists.txt b/modules/hal_infineon/wifi-host-driver/CMakeLists.txt index 010518f1642d3..7f6d9420862bb 100644 --- a/modules/hal_infineon/wifi-host-driver/CMakeLists.txt +++ b/modules/hal_infineon/wifi-host-driver/CMakeLists.txt @@ -49,7 +49,10 @@ zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/whd_wifi_p2p.c) # src/bus_protocols zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus.c) zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus_common.c) -zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus_sdio_protocol.c) +zephyr_library_sources_ifdef(CONFIG_AIROC_WIFI_BUS_SDIO + ${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus_sdio_protocol.c) +zephyr_library_sources_ifdef(CONFIG_AIROC_WIFI_BUS_SPI + ${hal_wifi_dir}/WiFi_Host_Driver/src/bus_protocols/whd_bus_spi_protocol.c) # resources/resource_imp zephyr_library_sources(${hal_wifi_dir}/WiFi_Host_Driver/resources/resource_imp/whd_resources.c) diff --git a/modules/hal_nordic/CMakeLists.txt b/modules/hal_nordic/CMakeLists.txt index 5209efdced978..02d724377349d 100644 --- a/modules/hal_nordic/CMakeLists.txt +++ b/modules/hal_nordic/CMakeLists.txt @@ -12,7 +12,7 @@ if(CONFIG_NRF_REGTOOL_GENERATE_UICR) list(APPEND nrf_regtool_components GENERATE:UICR) endif() if(DEFINED nrf_regtool_components) - find_package(nrf-regtool 8.0.0 + find_package(nrf-regtool 8.1.2 COMPONENTS ${nrf_regtool_components} PATHS ${CMAKE_CURRENT_LIST_DIR}/nrf-regtool NO_CMAKE_PATH diff --git a/modules/hal_nordic/Kconfig b/modules/hal_nordic/Kconfig index f29b77e120e50..32ff1a6c74c0e 100644 --- a/modules/hal_nordic/Kconfig +++ b/modules/hal_nordic/Kconfig @@ -23,6 +23,7 @@ menuconfig NRF_802154_RADIO_DRIVER depends on HAS_HW_NRF_RADIO_IEEE802154 select DYNAMIC_INTERRUPTS select ENTROPY_GENERATOR + select CLOCK_CONTROL depends on !$(dt_nodelabel_enabled,timer1) help This option enables nRF IEEE 802.15.4 radio driver in Zephyr. Note, @@ -108,7 +109,7 @@ if NRF_802154_SER_RADIO config NRF_802154_SER_RADIO_INIT_PRIO int "nRF52 IEEE 802.15.4 serialization initialization priority" - default 51 + default 53 help Set the initialization priority number. Do not mess with it unless you know what you are doing. diff --git a/modules/hal_nordic/nrf_802154/CMakeLists.txt b/modules/hal_nordic/nrf_802154/CMakeLists.txt index 30c4c237a049e..1fc5c85ec0b19 100644 --- a/modules/hal_nordic/nrf_802154/CMakeLists.txt +++ b/modules/hal_nordic/nrf_802154/CMakeLists.txt @@ -33,9 +33,6 @@ endif () target_compile_definitions(zephyr-802154-interface INTERFACE - # Radio driver shim layer uses raw api - NRF_802154_USE_RAW_API=1 - # Number of slots containing short addresses of nodes for which # pending data is stored. NRF_802154_PENDING_SHORT_ADDRESSES=${CONFIG_NRF_802154_PENDING_SHORT_ADDRESSES} diff --git a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c b/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c index f9da7537dc132..a55e63bc589df 100644 --- a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c +++ b/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c @@ -11,12 +11,7 @@ #include #include -#if defined(CONFIG_CLOCK_CONTROL_NRF) #include -#include -#elif !defined(NRF54H_SERIES) -#error No implementation to start or stop HFCLK due to missing clock_control. -#endif static bool hfclk_is_running; @@ -35,7 +30,6 @@ bool nrf_802154_clock_hfclk_is_running(void) return hfclk_is_running; } -#if defined(CONFIG_CLOCK_CONTROL_NRF) static struct onoff_client hfclk_cli; @@ -48,9 +42,9 @@ static void hfclk_on_callback(struct onoff_manager *mgr, nrf_802154_clock_hfclk_ready(); } +#if defined(CONFIG_CLOCK_CONTROL_NRF) void nrf_802154_clock_hfclk_start(void) { - int ret; struct onoff_manager *mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); @@ -58,57 +52,42 @@ void nrf_802154_clock_hfclk_start(void) sys_notify_init_callback(&hfclk_cli.notify, hfclk_on_callback); - ret = onoff_request(mgr, &hfclk_cli); + int ret = onoff_request(mgr, &hfclk_cli); __ASSERT_NO_MSG(ret >= 0); + (void)ret; } void nrf_802154_clock_hfclk_stop(void) { - int ret; struct onoff_manager *mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); __ASSERT_NO_MSG(mgr != NULL); - ret = onoff_cancel_or_release(mgr, &hfclk_cli); + int ret = onoff_cancel_or_release(mgr, &hfclk_cli); __ASSERT_NO_MSG(ret >= 0); + (void)ret; hfclk_is_running = false; } -#elif defined(NRF54H_SERIES) - -#define NRF_LRCCONF_RADIO_PD NRF_LRCCONF010 -/* HF clock time to ramp-up. */ -#define MAX_HFXO_RAMP_UP_TIME_US 550 - -static void hfclk_started_timer_handler(struct k_timer *dummy) -{ - hfclk_is_running = true; - nrf_802154_clock_hfclk_ready(); -} - -K_TIMER_DEFINE(hfclk_started_timer, hfclk_started_timer_handler, NULL); +#elif defined(CONFIG_CLOCK_CONTROL_NRF2) void nrf_802154_clock_hfclk_start(void) { - /* Use register directly, there is no support for that task in nrf_lrcconf_task_trigger. - * This code might cause troubles if there are other HFXO users in this CPU. - */ - NRF_LRCCONF_RADIO_PD->EVENTS_HFXOSTARTED = 0x0; - NRF_LRCCONF_RADIO_PD->TASKS_REQHFXO = 0x1; + sys_notify_init_callback(&hfclk_cli.notify, hfclk_on_callback); + int ret = nrf_clock_control_request(DEVICE_DT_GET(DT_NODELABEL(hfxo)), NULL, &hfclk_cli); - k_timer_start(&hfclk_started_timer, K_USEC(MAX_HFXO_RAMP_UP_TIME_US), K_NO_WAIT); + __ASSERT_NO_MSG(ret >= 0); + (void)ret; } void nrf_802154_clock_hfclk_stop(void) { - /* Use register directly, there is no support for that task in nrf_lrcconf_task_trigger. - * This code might cause troubles if there are other HFXO users in this CPU. - */ - NRF_LRCCONF_RADIO_PD->TASKS_STOPREQHFXO = 0x1; - NRF_LRCCONF_RADIO_PD->EVENTS_HFXOSTARTED = 0x0; + int ret = nrf_clock_control_cancel_or_release(DEVICE_DT_GET(DT_NODELABEL(hfxo)), + NULL, &hfclk_cli); - hfclk_is_running = false; + __ASSERT_NO_MSG(ret >= 0); + (void)ret; } #endif diff --git a/modules/hal_nordic/nrfs/CMakeLists.txt b/modules/hal_nordic/nrfs/CMakeLists.txt index f470eea00e9f0..cf738fe5bf22c 100644 --- a/modules/hal_nordic/nrfs/CMakeLists.txt +++ b/modules/hal_nordic/nrfs/CMakeLists.txt @@ -25,10 +25,12 @@ if(CONFIG_NRFS) zephyr_library_sources_ifdef(CONFIG_NRFS_CLOCK_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_clock.c) zephyr_library_sources_ifdef(CONFIG_NRFS_DIAG_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_diag.c) zephyr_library_sources_ifdef(CONFIG_NRFS_DVFS_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_dvfs.c) + zephyr_library_sources_ifdef(CONFIG_NRFS_GDFS_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_gdfs.c) zephyr_library_sources_ifdef(CONFIG_NRFS_GDPWR_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_gdpwr.c) zephyr_library_sources_ifdef(CONFIG_NRFS_MRAM_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_mram.c) zephyr_library_sources_ifdef(CONFIG_NRFS_PMIC_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_pmic.c) zephyr_library_sources_ifdef(CONFIG_NRFS_RESET_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_reset.c) + zephyr_library_sources_ifdef(CONFIG_NRFS_SWEXT_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_swext.c) zephyr_library_sources_ifdef(CONFIG_NRFS_TEMP_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_temp.c) zephyr_library_sources_ifdef(CONFIG_NRFS_VBUS_DETECTOR_SERVICE_ENABLED ${SRC_DIR}/services/nrfs_usb.c) zephyr_library_sources(${SRC_DIR}/internal/nrfs_dispatcher.c) diff --git a/modules/hal_nordic/nrfs/Kconfig b/modules/hal_nordic/nrfs/Kconfig index 8c5b61bb11f35..0684ec222bee9 100644 --- a/modules/hal_nordic/nrfs/Kconfig +++ b/modules/hal_nordic/nrfs/Kconfig @@ -19,6 +19,9 @@ config NRFS_HAS_DIAG_SERVICE config NRFS_HAS_DVFS_SERVICE bool +config NRFS_HAS_GDFS_SERVICE + bool + config NRFS_HAS_GDPWR_SERVICE bool @@ -31,6 +34,9 @@ config NRFS_HAS_PMIC_SERVICE config NRFS_HAS_RESET_SERVICE bool +config NRFS_HAS_SWEXT_SERVICE + bool + config NRFS_HAS_TEMP_SERVICE bool @@ -117,6 +123,16 @@ config NRFS_GDPWR_SERVICE_ENABLED depends on NRFS_HAS_GDPWR_SERVICE default y +config NRFS_GDFS_SERVICE_ENABLED + bool "Global domain frequency scaling service" + depends on NRFS_HAS_GDFS_SERVICE + default y + +config NRFS_SWEXT_SERVICE_ENABLED + bool "SWEXT peripheral control service" + depends on NRFS_HAS_SWEXT_SERVICE + default y + endmenu rsource "backends/Kconfig" diff --git a/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c b/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c index 129098e9b2d2f..8cc49c992344a 100644 --- a/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c +++ b/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c @@ -54,6 +54,8 @@ static struct ipc_channel_config ipc_cpusys_channel_config = { .enabled = true }; +static sys_slist_t nrfs_backend_info_cb_slist = SYS_SLIST_STATIC_INIT(&nrfs_backend_info_cb_slist); + /** * @brief nrfs backend error handler * @@ -99,6 +101,12 @@ static void ipc_sysctrl_ept_bound(void *priv) if (k_msgq_num_used_get(&ipc_transmit_msgq) > 0) { k_work_submit(&backend_send_work); } + + struct nrfs_backend_bound_info_subs *subs; + + SYS_SLIST_FOR_EACH_CONTAINER(&nrfs_backend_info_cb_slist, subs, node) { + subs->cb(); + } } static void ipc_sysctrl_ept_recv(const void *data, size_t size, void *priv) @@ -176,7 +184,10 @@ nrfs_err_t nrfs_backend_send(void *message, size_t size) nrfs_err_t nrfs_backend_send_ex(void *message, size_t size, k_timeout_t timeout, bool high_prio) { - if (size <= MAX_PACKET_DATA_SIZE) { + if (!k_is_in_isr() && nrfs_backend_connected()) { + return ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, message, size) ? + NRFS_SUCCESS : NRFS_ERR_IPC; + } else if (size <= MAX_PACKET_DATA_SIZE) { int err; struct ipc_data_packet tx_data; @@ -219,6 +230,15 @@ int nrfs_backend_wait_for_connection(k_timeout_t timeout) return (events == IPC_INIT_DONE_EVENT ? 0 : (-EAGAIN)); } +void nrfs_backend_register_bound_subscribe(struct nrfs_backend_bound_info_subs *subs, + nrfs_backend_bound_info_cb_t cb) +{ + if (cb) { + subs->cb = cb; + sys_slist_append(&nrfs_backend_info_cb_slist, &subs->node); + } +} + __weak void nrfs_backend_fatal_error_handler(enum nrfs_backend_error error_id) { LOG_ERR("Fatal error: %d rebooting...", error_id); diff --git a/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.h b/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.h index 572c05e864c78..beb07e9e8d0f5 100644 --- a/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.h +++ b/modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.h @@ -86,6 +86,21 @@ nrfs_err_t nrfs_backend_send_ex(void *message, size_t size, k_timeout_t timeout, */ void nrfs_backend_fatal_error_handler(enum nrfs_backend_error error_id); +typedef void (*nrfs_backend_bound_info_cb_t)(void); +struct nrfs_backend_bound_info_subs { + sys_snode_t node; + nrfs_backend_bound_info_cb_t cb; +}; +/** + * @brief Register callback function to notify when nrfs is connected. + * There can be multiple callbacks registered. + * + * @param subs Subcription instance. + * @param cb Callback + */ +void nrfs_backend_register_bound_subscribe(struct nrfs_backend_bound_info_subs *subs, + nrfs_backend_bound_info_cb_t cb); + #ifdef __cplusplus } #endif diff --git a/modules/hal_nordic/nrfs/dvfs/Kconfig b/modules/hal_nordic/nrfs/dvfs/Kconfig index bd6f2e4e99a0b..a1958adea9940 100644 --- a/modules/hal_nordic/nrfs/dvfs/Kconfig +++ b/modules/hal_nordic/nrfs/dvfs/Kconfig @@ -17,6 +17,7 @@ config NRFS_LOCAL_DOMAIN_DVFS_TEST config NRFS_LOCAL_DOMAIN_DVFS_SCALE_DOWN_AFTER_INIT bool "Local domain scale down after init" + select DEPRECATED help Request lowest oppoint after DVFS initialization. @@ -30,6 +31,8 @@ config NRFS_LOCAL_DOMAIN_DOWNSCALE_FINISH_DELAY_TIMEOUT_US int "Additional delay to let secdom finish dowscale procedure in us" range 1 10000000 default 1000 + help + This value depends on the secdom core performance and shouldn't be touched by the user. config NRFS_LOCAL_DOMAIN_DVFS_HANDLER_TASK_STACK_SIZE int "Stack size used for DVFS handling task" diff --git a/modules/hal_nordic/nrfs/dvfs/ld_dvfs.c b/modules/hal_nordic/nrfs/dvfs/ld_dvfs.c index 57ee0bdc37514..6697229f5504f 100644 --- a/modules/hal_nordic/nrfs/dvfs/ld_dvfs.c +++ b/modules/hal_nordic/nrfs/dvfs/ld_dvfs.c @@ -40,35 +40,7 @@ void ld_dvfs_init(void) const struct dvfs_oppoint_data *opp_data = get_dvfs_oppoint_data(DVFS_FREQ_HIGH); -#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) - LOG_DBG("%s", __func__); - LOG_DBG("REGW: NRF_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT], - opp_data->abb_ringo); - LOG_DBG("REGW: NRF_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT], - opp_data->abb_lockrange); - LOG_DBG("REGW: NRF_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT], - opp_data->abb_pvtmoncycles); - - /*For app core.*/ - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT], - opp_data->abb_ringo); - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT], - opp_data->abb_lockrange); - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT], - opp_data->abb_pvtmoncycles); -#else +#if !defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) /* TODO: Change to NRFX Hal function when available. */ NRF_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT] = opp_data->abb_ringo; NRF_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT] = opp_data->abb_lockrange; @@ -84,12 +56,7 @@ void ld_dvfs_init(void) void ld_dvfs_clear_zbb(void) { #if defined(NRF_SECURE) -#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) - LOG_DBG("%s", __func__); - LOG_DBG("REGW: NRF_ABB->CONFIG.CTRL1.MODE 0x%x, V: 0x%x", - (uint32_t)&NRF_ABB->CONFIG.CTRL1, - LD_ABB_CLR_ZBB); -#else +#if !defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) /* TODO: Change to NRFX Hal function when available. */ NRF_ABB->CONFIG.CTRL1 &= ~(ABB_CONFIG_CTRL1_MODE_Msk); NRF_APPLICATION_ABB->CONFIG.CTRL1 &= ~(ABB_CONFIG_CTRL1_MODE_Msk); @@ -161,34 +128,7 @@ void ld_dvfs_configure_abb_for_transition(enum dvfs_frequency_setting transient_ const struct dvfs_oppoint_data *opp_data = get_dvfs_oppoint_data(transient_opp); #if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) - LOG_DBG("%s", __func__); LOG_DBG("transient_opp: %d, curr_targ_opp: %d", transient_opp, curr_targ_opp); - LOG_DBG("REGW: NRF_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x", - TRANSIENT_ZBB_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.RINGO[TRANSIENT_ZBB_ABB_SLOT], - opp_data->abb_ringo); - LOG_DBG("REGW: NRF_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x", - TRANSIENT_ZBB_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.LOCKRANGE[TRANSIENT_ZBB_ABB_SLOT], - opp_data->abb_lockrange); - LOG_DBG("REGW: NRF_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x", - TRANSIENT_ZBB_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.PVTMONCYCLES[TRANSIENT_ZBB_ABB_SLOT], - opp_data->abb_pvtmoncycles); - - /* For app core.*/ - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x", - TRANSIENT_ZBB_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.RINGO[TRANSIENT_ZBB_ABB_SLOT], - opp_data->abb_ringo); - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x", - TRANSIENT_ZBB_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.LOCKRANGE[TRANSIENT_ZBB_ABB_SLOT], - opp_data->abb_lockrange); - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x", - TRANSIENT_ZBB_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[TRANSIENT_ZBB_ABB_SLOT], - opp_data->abb_pvtmoncycles); #else NRF_ABB->TRIM.RINGO[TRANSIENT_ZBB_ABB_SLOT] = opp_data->abb_ringo; @@ -201,42 +141,8 @@ void ld_dvfs_configure_abb_for_transition(enum dvfs_frequency_setting transient_ #endif opp_data = get_dvfs_oppoint_data(curr_targ_opp); -#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) - LOG_DBG("REGW: NRF_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT], - opp_data->abb_ringo); - LOG_DBG("REGW: NRF_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT], - opp_data->abb_lockrange); - LOG_DBG("REGW: NRF_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT], - opp_data->abb_pvtmoncycles); - - LOG_DBG("REGW: TODO: NRF_ABB->CONFIG.CTRL4 0x%x, V: 0x%lx", - (uint32_t)&NRF_ABB->CONFIG.CTRL4, - LD_ABB_CTRL4_TRANSITION_OPERATION); - - /* For app core */ - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.RINGO[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT], - opp_data->abb_ringo); - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.LOCKRANGE[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT], - opp_data->abb_lockrange); - LOG_DBG("REGW: NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[%d] 0x%x, V: 0x%x", - CURR_TARG_ABB_SLOT, - (uint32_t)&NRF_APPLICATION_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT], - opp_data->abb_pvtmoncycles); - - LOG_DBG("REGW: TODO: NRF_APPLICATION_ABB->CONFIG.CTRL4 0x%x, V: 0x%lx", - (uint32_t)&NRF_APPLICATION_ABB->CONFIG.CTRL4, - LD_ABB_CTRL4_TRANSITION_OPERATION); -#else +#if !defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) + NRF_ABB->TRIM.RINGO[CURR_TARG_ABB_SLOT] = opp_data->abb_ringo; NRF_ABB->TRIM.LOCKRANGE[CURR_TARG_ABB_SLOT] = opp_data->abb_lockrange; NRF_ABB->TRIM.PVTMONCYCLES[CURR_TARG_ABB_SLOT] = opp_data->abb_pvtmoncycles; @@ -281,22 +187,6 @@ int32_t ld_dvfs_configure_hsfll(enum dvfs_frequency_setting oppoint) #if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) LOG_DBG("%s oppoint: %d", __func__, oppoint); - LOG_DBG("REGW: NRF_HSFLL->MIRROR 0x%x, V: 0x%x", (uint32_t)&NRF_HSFLL->MIRROR, 1); - LOG_DBG("REGW: NRF_HSFLL->TRIM.COARSE 0x%x, V: 0x%x", - (uint32_t)&NRF_HSFLL->TRIM.COARSE, - hsfll_trim.coarse); - LOG_DBG("REGW: NRF_HSFLL->TRIM.FINE 0x%x, V: 0x%x", - (uint32_t)&NRF_HSFLL->TRIM.FINE, - hsfll_trim.fine); - LOG_DBG("REGW: NRF_HSFLL->MIRROR 0x%x, V: 0x%x", (uint32_t)&NRF_HSFLL->MIRROR, 0); - - LOG_DBG("REGW: NRF_HSFLL->CLOCKCTRL.MULT 0x%x, V: 0x%x", - (uint32_t)&NRF_HSFLL->CLOCKCTRL.MULT, - get_dvfs_oppoint_data(oppoint)->new_f_mult); - - LOG_DBG("REGW: NRF_HSFLL->NRF_HSFLL_TASK_FREQ_CHANGE 0x%x, V: 0x%x", - (uint32_t)NRF_HSFLL + NRF_HSFLL_TASK_FREQ_CHANGE, - 0x1); return 0; #else @@ -337,15 +227,7 @@ void ld_dvfs_scaling_background_process(bool downscaling) void ld_dvfs_scaling_finish(bool downscaling) { #if defined(NRF_SECURE) -#if defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) - LOG_DBG("%s", __func__); - LOG_DBG("REGW: NRF_ABB->CONFIG.CTRL4 0x%x, V: 0x%lx", - (uint32_t)&NRF_ABB->CONFIG.CTRL4, - LD_ABB_CTRL4_NORMAL_OPERATION); - LOG_DBG("REGW: NRF_APPLICATION_ABB->CONFIG.CTRL4 0x%x, V: 0x%lx", - (uint32_t)&NRF_APPLICATION_ABB->CONFIG.CTRL4, - LD_ABB_CTRL4_NORMAL_OPERATION); -#else +#if !defined(CONFIG_NRFS_LOCAL_DOMAIN_DVFS_TEST) NRF_ABB->CONFIG.CTRL4 = LD_ABB_CTRL4_NORMAL_OPERATION; NRF_APPLICATION_ABB->CONFIG.CTRL4 = LD_ABB_CTRL4_NORMAL_OPERATION; #endif diff --git a/modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c b/modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c index c28d9187a554e..f83874f347384 100644 --- a/modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c +++ b/modules/hal_nordic/nrfs/dvfs/ld_dvfs_handler.c @@ -139,9 +139,19 @@ static void dvfs_service_handler_scaling_background_job(enum dvfs_frequency_sett } } +/* Update MDK variable which is used by nrfx_coredep_delay_us (k_busy_wait). */ +static void dvfs_service_update_core_clock(enum dvfs_frequency_setting oppoint_freq) +{ + extern uint32_t SystemCoreClock; + + SystemCoreClock = oppoint_freq == DVFS_FREQ_HIGH ? 320000000 : + oppoint_freq == DVFS_FREQ_MEDLOW ? 128000000 : 64000000; +} + /* Perform scaling finnish procedure. */ static void dvfs_service_handler_scaling_finish(enum dvfs_frequency_setting oppoint_freq) { + LOG_DBG("Scaling finnish oppoint freq %d", oppoint_freq); ld_dvfs_scaling_finish(dvfs_service_handler_is_downscaling(oppoint_freq)); if (!dvfs_service_handler_is_downscaling(oppoint_freq)) { @@ -153,6 +163,7 @@ static void dvfs_service_handler_scaling_finish(enum dvfs_frequency_setting oppo } dvfs_service_handler_clear_state_bit(DVFS_SERV_HDL_FREQ_CHANGE_REQ_PENDING_BIT_POS); current_freq_setting = oppoint_freq; + dvfs_service_update_core_clock(oppoint_freq); LOG_DBG("Current LD freq setting: %d", current_freq_setting); if (dvfs_frequency_change_applied_clb) { dvfs_frequency_change_applied_clb(current_freq_setting); @@ -178,10 +189,9 @@ static void dvfs_service_handler_set_initial_hsfll_config(void) static void dvfs_service_handler_scaling_finish_delay_timeout(struct k_timer *timer) { - if (timer) { - dvfs_service_handler_scaling_finish( - *(enum dvfs_frequency_setting *)timer->user_data); - } + + dvfs_service_handler_scaling_finish( + *(enum dvfs_frequency_setting *)k_timer_user_data_get(timer)); } K_TIMER_DEFINE(dvfs_service_scaling_finish_delay_timer, @@ -216,6 +226,7 @@ static void nrfs_dvfs_evt_handler(nrfs_dvfs_evt_t const *p_evt, void *context) dvfs_service_handler_clear_state_bit(DVFS_SERV_HDL_FREQ_CHANGE_REQ_PENDING_BIT_POS); LOG_DBG("DVFS handler EVT_OPPOINT_REQ_CONFIRMED %d", (uint32_t)p_evt->freq); if (dvfs_service_handler_get_requested_oppoint() == p_evt->freq) { + dvfs_service_update_core_clock(p_evt->freq); if (dvfs_frequency_change_applied_clb) { dvfs_frequency_change_applied_clb(p_evt->freq); } @@ -237,7 +248,8 @@ static void nrfs_dvfs_evt_handler(nrfs_dvfs_evt_t const *p_evt, void *context) static enum dvfs_frequency_setting freq; freq = p_evt->freq; - dvfs_service_scaling_finish_delay_timer.user_data = (void *)&freq; + k_timer_user_data_set(&dvfs_service_scaling_finish_delay_timer, + (void *)&freq); k_timer_start(&dvfs_service_scaling_finish_delay_timer, SCALING_FINISH_DELAY_TIMEOUT_US, K_NO_WAIT); } else { diff --git a/modules/hal_nordic/nrfs/nrfs_config.h b/modules/hal_nordic/nrfs/nrfs_config.h index a092adb7850f6..da3cc1ada1b56 100644 --- a/modules/hal_nordic/nrfs/nrfs_config.h +++ b/modules/hal_nordic/nrfs/nrfs_config.h @@ -44,6 +44,18 @@ #define NRFS_GDPWR_SERVICE_ENABLED #endif +#ifdef CONFIG_NRFS_CLOCK_SERVICE_ENABLED +#define NRFS_CLOCK_SERVICE_ENABLED +#endif + +#ifdef CONFIG_NRFS_GDFS_SERVICE_ENABLED +#define NRFS_GDFS_SERVICE_ENABLED +#endif + +#ifdef CONFIG_NRFS_SWEXT_SERVICE_ENABLED +#define NRFS_SWEXT_SERVICE_ENABLED +#endif + #ifdef CONFIG_SOC_POSIX #define NRFS_UNIT_TESTS_ENABLED #endif diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index e71e34a403797..02849d9376150 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -44,10 +44,14 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_CPUPPR NRF54H20_XXAA NRF_PPR) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_CPUFLPR NRF54H20_XXAA NRF_FLPR) -zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L05 NRF54L05_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L05 NRF54L05_XXAA + DEVELOP_IN_NRF54L15) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L05_CPUAPP NRF_APPLICATION) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L05_CPUFLPR NRF_FLPR) -zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L10 NRF54L10_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L09_ENGA NRF54L09_ENGA_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L09_ENGA_CPUAPP NRF_APPLICATION) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L10 NRF54L10_XXAA + DEVELOP_IN_NRF54L15) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L10_CPUAPP NRF_APPLICATION) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L10_CPUFLPR NRF_FLPR) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L15 NRF54L15_XXAA) @@ -109,7 +113,7 @@ zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF92X ${MDK_DIR}/system_nrf92.c zephyr_library_sources(nrfx_glue.c) zephyr_library_sources(${HELPERS_DIR}/nrfx_flag32_allocator.c) -zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_NRF_RAM_CTRL ${HELPERS_DIR}/nrfx_ram_ctrl.c) +zephyr_library_sources_ifdef(CONFIG_HAS_NORDIC_RAM_CTRL ${HELPERS_DIR}/nrfx_ram_ctrl.c) zephyr_library_sources_ifdef(CONFIG_NRFX_GPPI ${HELPERS_DIR}/nrfx_gppi_dppi.c) zephyr_library_sources_ifdef(CONFIG_NRFX_GPPI ${HELPERS_DIR}/nrfx_gppi_ppi.c) @@ -118,6 +122,7 @@ zephyr_library_sources_ifdef(CONFIG_NRFX_PRS ${SRC_DIR}/prs/nrfx_prs.c) zephyr_library_sources_ifdef(CONFIG_NRFX_ADC ${SRC_DIR}/nrfx_adc.c) zephyr_library_sources_ifdef(CONFIG_NRFX_CLOCK ${SRC_DIR}/nrfx_clock.c) zephyr_library_sources_ifdef(CONFIG_NRFX_COMP ${SRC_DIR}/nrfx_comp.c) +zephyr_library_sources_ifdef(CONFIG_NRFX_CRACEN ${SRC_DIR}/nrfx_cracen.c) zephyr_library_sources_ifdef(CONFIG_NRFX_DPPI ${SRC_DIR}/nrfx_dppi.c) zephyr_library_sources_ifdef(CONFIG_NRFX_EGU ${SRC_DIR}/nrfx_egu.c) zephyr_library_sources_ifdef(CONFIG_NRFX_GPIOTE ${SRC_DIR}/nrfx_gpiote.c) @@ -179,7 +184,10 @@ if(DEFINED uicr_path) endif() if(CONFIG_SOC_NRF54L_CPUAPP_COMMON) - dt_prop(clock_frequency PATH "/cpus/cpu@0" PROPERTY "clock-frequency") + # Ideally, hfpll should taken as a phandle from clocks property from cpu but it + # seems that there is no such option in DT cmake functions. Assuming that nrf54l + # is using hfpll as CPU clock source (true for all existing devices). + dt_prop(clock_frequency PATH "/clocks/hfpll" PROPERTY "clock-frequency") math(EXPR clock_frequency_mhz "${clock_frequency} / 1000000") zephyr_compile_definitions("NRF_CONFIG_CPU_FREQ_MHZ=${clock_frequency_mhz}") endif() @@ -188,13 +196,13 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_SKIP_CLOCK_CONFIG NRF_SKIP_C zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_DISABLE_FICR_TRIMCNF NRF_DISABLE_FICR_TRIMCNF) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_SKIP_GLITCHDETECTOR_DISABLE NRF_SKIP_GLITCHDETECTOR_DISABLE) -# Inject code to skip TAMPC setup for nRF54L20. It is not supported for now. +# Inject code to skip TAMPC setup for nRF54L20 and nRF54L09. It is not supported for now. # It needs to be removed when support is provided. -if(CONFIG_SOC_NRF54L20_ENGA_CPUAPP) - zephyr_compile_definitions(NRF_SKIP_TAMPC_SETUP) +if(CONFIG_SOC_NRF54L20_ENGA_CPUAPP OR CONFIG_SOC_NRF54L09_ENGA_CPUAPP) + zephyr_compile_definitions(NRF_SKIP_TAMPC_SETUP) endif() -if(CONFIG_SOC_SERIES_NRF54LX AND CONFIG_NRFX_GPPI) +if(CONFIG_SOC_COMPATIBLE_NRF54LX AND CONFIG_NRFX_GPPI) zephyr_library_sources(${HELPERS_DIR}/nrfx_gppi_dppi_ppib_lumos.c) zephyr_library_sources(${NRFX_DIR}/soc/interconnect/dppic_ppib/nrfx_interconnect_dppic_ppib.c) endif() @@ -228,6 +236,7 @@ mdk_svd_ifdef(CONFIG_SOC_NRF54H20_CPUFLPR nrf54h20_flpr.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54H20_CPURAD nrf54h20_radiocore.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54L05_CPUAPP nrf54l05_application.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54L05_CPUFLPR nrf54l05_flpr.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF54L09_ENGA_CPUAPP nrf54l09_enga_application.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54L10_CPUAPP nrf54l10_application.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54L10_CPUFLPR nrf54l10_flpr.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54L15_CPUAPP nrf54l15_application.svd) diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 2fd97920df838..14e5c47e858f8 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -25,6 +25,10 @@ config NRFX_COMP bool "COMP driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_COMP)) +config NRFX_CRACEN + bool "CRACEN drivers" + depends on SOC_COMPATIBLE_NRF54LX + config NRFX_DPPI bool @@ -1211,6 +1215,6 @@ endmenu config NRFX_RESERVED_RESOURCES_HEADER string - default "nrfx_config_reserved_resources.h" + default "nrfx_reserved_resources.h" endmenu # "nrfx drivers" diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index 5a6c8bf01c790..6a337cd2588e0 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 - 2022, Nordic Semiconductor ASA + * Copyright (c) 2019, Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,1152 +7,109 @@ #ifndef NRFX_CONFIG_H__ #define NRFX_CONFIG_H__ -#include -#include +/* Define nrfx API version used in Zephyr. */ +#define NRFX_CONFIG_API_VER_MAJOR 3 +#define NRFX_CONFIG_API_VER_MINOR 8 +#define NRFX_CONFIG_API_VER_MICRO 0 -/* - * These are mappings of Kconfig options enabling nrfx drivers and particular - * peripheral instances to the corresponding symbols used inside of nrfx. - * Please note that only subsets of these entries are used for particular SoCs - * supported by nrfx (see the corresponding nrfx_config_*.h files). - */ - -#ifdef CONFIG_NRFX_ADC -#define NRFX_ADC_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_ADC_LOG -#define NRFX_ADC_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_CLOCK -#define NRFX_CLOCK_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_CLOCK_LOG -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC -#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#else -#define NRFX_CLOCK_CONFIG_LF_SRC 0 -#endif -#endif // CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC - -#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL -#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) -#define NRFX_CLOCK_CONFIG_LF_SRC 2 -#else -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif -#endif // CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL - -#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH -#ifdef CONFIG_SOC_COMPATIBLE_NRF53X -#define NRFX_CLOCK_CONFIG_LF_SRC 3 -#else -#define NRFX_CLOCK_CONFIG_LF_SRC 2 -#endif -#endif // CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH - -#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING -#define NRFX_CLOCK_CONFIG_LF_SRC 131073 -#endif - -#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING -#define NRFX_CLOCK_CONFIG_LF_SRC 196609 -#endif - -#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_CLOCK_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_COMP -#define NRFX_COMP_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_COMP_LOG -#define NRFX_COMP_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_DPPI -#define NRFX_DPPI_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI_LOG -#define NRFX_DPPI_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI0 -#define NRFX_DPPI0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI00 -#define NRFX_DPPI00_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI10 -#define NRFX_DPPI10_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI20 -#define NRFX_DPPI20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI30 -#define NRFX_DPPI30_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI020 -#define NRFX_DPPI020_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI120 -#define NRFX_DPPI120_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI130 -#define NRFX_DPPI130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI131 -#define NRFX_DPPI131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI132 -#define NRFX_DPPI132_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI133 -#define NRFX_DPPI133_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI134 -#define NRFX_DPPI134_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI135 -#define NRFX_DPPI135_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_DPPI136 -#define NRFX_DPPI136_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_EGU -#define NRFX_EGU_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU_LOG -#define NRFX_EGU_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU0 -#define NRFX_EGU0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU1 -#define NRFX_EGU1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU2 -#define NRFX_EGU2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU3 -#define NRFX_EGU3_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU4 -#define NRFX_EGU4_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU5 -#define NRFX_EGU5_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU10 -#define NRFX_EGU10_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU20 -#define NRFX_EGU20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU020 -#define NRFX_EGU020_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_EGU130 -#define NRFX_EGU130_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_GRTC -#define NRFX_GRTC_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_GRTC_LOG -#define NRFX_GRTC_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT -#define NRF_GRTC_HAS_EXTENDED 1 -#endif -#ifdef CONFIG_NRF_GRTC_TIMER_AUTO_KEEP_ALIVE -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif -#ifdef CONFIG_NRF_GRTC_START_SYSCOUNTER -#define NRFX_GRTC_CONFIG_AUTOSTART 1 -#endif - -#ifdef CONFIG_NRFX_GPIOTE -#define NRFX_GPIOTE_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_GPIOTE0 -#define NRFX_GPIOTE0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_GPIOTE1 -#define NRFX_GPIOTE1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_GPIOTE20 -#define NRFX_GPIOTE20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_GPIOTE30 -#define NRFX_GPIOTE30_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_GPIOTE130 -#define NRFX_GPIOTE130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_GPIOTE131 -#define NRFX_GPIOTE131_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS -#endif - -#ifdef CONFIG_NRFX_I2S -#define NRFX_I2S_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_I2S_LOG -#define NRFX_I2S_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_I2S0 -#define NRFX_I2S0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_I2S20 -#define NRFX_I2S20_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_IPC -#define NRFX_IPC_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_IPC_LOG -#define NRFX_IPC_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_LPCOMP -#define NRFX_LPCOMP_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_LPCOMP_LOG -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_NFCT -#define NRFX_NFCT_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_NFCT_LOG -#define NRFX_NFCT_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_NVMC -#define NRFX_NVMC_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_NVMC_LOG -#define NRFX_NVMC_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_PDM -#define NRFX_PDM_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PDM_LOG -#define NRFX_PDM_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PDM0 -#define NRFX_PDM0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PDM20 -#define NRFX_PDM20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PDM21 -#define NRFX_PDM21_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_POWER -#define NRFX_POWER_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_POWER_LOG -#define NRFX_POWER_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_PPI -#define NRFX_PPI_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPI_LOG -#define NRFX_PPI_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_PPIB -#define NRFX_PPIB_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB_LOG -#define NRFX_PPIB_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB00 -#define NRFX_PPIB00_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB01 -#define NRFX_PPIB01_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB10 -#define NRFX_PPIB10_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB11 -#define NRFX_PPIB11_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB20 -#define NRFX_PPIB20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB21 -#define NRFX_PPIB21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB22 -#define NRFX_PPIB22_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PPIB30 -#define NRFX_PPIB30_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_PRS -#define NRFX_PRS_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PRS_LOG -#define NRFX_PRS_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PRS_BOX_0 -#define NRFX_PRS_BOX_0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PRS_BOX_1 -#define NRFX_PRS_BOX_1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PRS_BOX_2 -#define NRFX_PRS_BOX_2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PRS_BOX_3 -#define NRFX_PRS_BOX_3_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PRS_BOX_4 -#define NRFX_PRS_BOX_4_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_PWM -#define NRFX_PWM_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM_LOG -#define NRFX_PWM_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM0 -#define NRFX_PWM0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM1 -#define NRFX_PWM1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM2 -#define NRFX_PWM2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM3 -#define NRFX_PWM3_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM20 -#define NRFX_PWM20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM21 -#define NRFX_PWM21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM22 -#define NRFX_PWM22_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM120 -#define NRFX_PWM120_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM130 -#define NRFX_PWM130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM131 -#define NRFX_PWM131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM132 -#define NRFX_PWM132_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_PWM133 -#define NRFX_PWM133_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_QDEC -#define NRFX_QDEC_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_QDEC_LOG -#define NRFX_QDEC_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_QDEC0 -#define NRFX_QDEC0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_QDEC1 -#define NRFX_QDEC1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_QDEC20 -#define NRFX_QDEC20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_QDEC21 -#define NRFX_QDEC21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_QDEC130 -#define NRFX_QDEC130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_QDEC131 -#define NRFX_QDEC131_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_QSPI -#define NRFX_QSPI_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_QSPI_LOG -#define NRFX_QSPI_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_RNG -#define NRFX_RNG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_RNG_LOG -#define NRFX_RNG_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_RRAMC -#define NRFX_RRAMC_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_RTC -#define NRFX_RTC_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_RTC_LOG -#define NRFX_RTC_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_RTC0 -#define NRFX_RTC0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_RTC1 -#define NRFX_RTC1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_RTC2 -#define NRFX_RTC2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_RTC130 -#define NRFX_RTC130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_RTC131 -#define NRFX_RTC131_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_SAADC -#define NRFX_SAADC_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SAADC_LOG -#define NRFX_SAADC_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_SPI -#define NRFX_SPI_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPI_LOG -#define NRFX_SPI_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPI0 -#define NRFX_SPI0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPI1 -#define NRFX_SPI1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPI2 -#define NRFX_SPI2_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_SPIM -#define NRFX_SPIM_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM_LOG -#define NRFX_SPIM_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM0 -#define NRFX_SPIM0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM1 -#define NRFX_SPIM1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM2 -#define NRFX_SPIM2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM3 -#define NRFX_SPIM3_ENABLED 1 -#ifdef CONFIG_NRF52_ANOMALY_198_WORKAROUND -#define NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED 1 -#endif -#endif -#ifdef CONFIG_NRFX_SPIM4 -#define NRFX_SPIM4_ENABLED 1 -#endif - -#define NRFX_SPIM_DT_HAS_RX_DELAY(node) DT_PROP(node, rx_delay_supported) + - -#if DT_FOREACH_STATUS_OKAY(nordic_nrf_spim, NRFX_SPIM_DT_HAS_RX_DELAY) 0 -#define NRFX_SPIM_EXTENDED_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM00 -#define NRFX_SPIM00_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM20 -#define NRFX_SPIM20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM21 -#define NRFX_SPIM21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM22 -#define NRFX_SPIM22_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM30 -#define NRFX_SPIM30_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM120 -#define NRFX_SPIM120_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM121 -#define NRFX_SPIM121_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM130 -#define NRFX_SPIM130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM131 -#define NRFX_SPIM131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM132 -#define NRFX_SPIM132_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM133 -#define NRFX_SPIM133_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM134 -#define NRFX_SPIM134_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM135 -#define NRFX_SPIM135_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM136 -#define NRFX_SPIM136_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIM137 -#define NRFX_SPIM137_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_SPIS -#define NRFX_SPIS_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS_LOG -#define NRFX_SPIS_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS0 -#define NRFX_SPIS0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS1 -#define NRFX_SPIS1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS2 -#define NRFX_SPIS2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS3 -#define NRFX_SPIS3_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS00 -#define NRFX_SPIS00_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS20 -#define NRFX_SPIS20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS21 -#define NRFX_SPIS21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS22 -#define NRFX_SPIS22_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS30 -#define NRFX_SPIS30_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS120 -#define NRFX_SPIS120_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS130 -#define NRFX_SPIS130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS131 -#define NRFX_SPIS131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS132 -#define NRFX_SPIS132_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS133 -#define NRFX_SPIS133_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS134 -#define NRFX_SPIS134_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS135 -#define NRFX_SPIS135_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS136 -#define NRFX_SPIS136_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SPIS137 -#define NRFX_SPIS137_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_SYSTICK -#define NRFX_SYSTICK_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_SYSTICK_LOG -#define NRFX_SYSTICK_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_TBM -#define NRFX_TBM_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_TEMP -#define NRFX_TEMP_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TEMP_LOG -#define NRFX_TEMP_CONFIG_LOG_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_TIMER -#define NRFX_TIMER_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER_LOG -#define NRFX_TIMER_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER0 -#define NRFX_TIMER0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER1 -#define NRFX_TIMER1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER2 -#define NRFX_TIMER2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER3 -#define NRFX_TIMER3_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER4 -#define NRFX_TIMER4_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER00 -#define NRFX_TIMER00_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER10 -#define NRFX_TIMER10_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER20 -#define NRFX_TIMER20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER21 -#define NRFX_TIMER21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER22 -#define NRFX_TIMER22_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER23 -#define NRFX_TIMER23_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER24 -#define NRFX_TIMER24_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER020 -#define NRFX_TIMER020_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER021 -#define NRFX_TIMER021_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER022 -#define NRFX_TIMER022_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER120 -#define NRFX_TIMER120_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER121 -#define NRFX_TIMER121_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER130 -#define NRFX_TIMER130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER131 -#define NRFX_TIMER131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER132 -#define NRFX_TIMER132_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER133 -#define NRFX_TIMER133_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER134 -#define NRFX_TIMER134_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER135 -#define NRFX_TIMER135_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER136 -#define NRFX_TIMER136_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TIMER137 -#define NRFX_TIMER137_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_TWI -#define NRFX_TWI_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWI_LOG -#define NRFX_TWI_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWI0 -#define NRFX_TWI0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWI1 -#define NRFX_TWI1_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_TWIM -#define NRFX_TWIM_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM_LOG -#define NRFX_TWIM_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM0 -#define NRFX_TWIM0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM1 -#define NRFX_TWIM1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM2 -#define NRFX_TWIM2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM3 -#define NRFX_TWIM3_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM20 -#define NRFX_TWIM20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM21 -#define NRFX_TWIM21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM22 -#define NRFX_TWIM22_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM30 -#define NRFX_TWIM30_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM120 -#define NRFX_TWIM120_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM130 -#define NRFX_TWIM130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM131 -#define NRFX_TWIM131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM132 -#define NRFX_TWIM132_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM133 -#define NRFX_TWIM133_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM134 -#define NRFX_TWIM134_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM135 -#define NRFX_TWIM135_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM136 -#define NRFX_TWIM136_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIM137 -#define NRFX_TWIM137_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_TWIS -#define NRFX_TWIS_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS_LOG -#define NRFX_TWIS_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS0 -#define NRFX_TWIS0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS1 -#define NRFX_TWIS1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS2 -#define NRFX_TWIS2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS3 -#define NRFX_TWIS3_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS20 -#define NRFX_TWIS20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS21 -#define NRFX_TWIS21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS22 -#define NRFX_TWIS22_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS30 -#define NRFX_TWIS30_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS130 -#define NRFX_TWIS130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS131 -#define NRFX_TWIS131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS132 -#define NRFX_TWIS132_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS133 -#define NRFX_TWIS133_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS134 -#define NRFX_TWIS134_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS135 -#define NRFX_TWIS135_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS136 -#define NRFX_TWIS136_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_TWIS137 -#define NRFX_TWIS137_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_UART -#define NRFX_UART_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UART_LOG -#define NRFX_UART_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UART0 -#define NRFX_UART0_ENABLED 1 -#endif - -#ifdef CONFIG_NRFX_UARTE -#define NRFX_UARTE_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE_LOG -#define NRFX_UARTE_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE0 -#define NRFX_UARTE0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE1 -#define NRFX_UARTE1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE2 -#define NRFX_UARTE2_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE3 -#define NRFX_UARTE3_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE00 -#define NRFX_UARTE00_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE20 -#define NRFX_UARTE20_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE21 -#define NRFX_UARTE21_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE22 -#define NRFX_UARTE22_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE30 -#define NRFX_UARTE30_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE120 -#define NRFX_UARTE120_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE130 -#define NRFX_UARTE130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE131 -#define NRFX_UARTE131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE132 -#define NRFX_UARTE132_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE133 -#define NRFX_UARTE133_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE134 -#define NRFX_UARTE134_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE135 -#define NRFX_UARTE135_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE136 -#define NRFX_UARTE136_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE137 -#define NRFX_UARTE137_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 1 -#endif -#ifdef CONFIG_NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 1 -#endif -#ifdef CONFIG_NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif -#ifdef CONFIG_NRFX_UARTE_CONFIG_RX_CACHE_ENABLED -#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 -#endif +/* Macros used in zephyr-specific config files. */ +#include "nrfx_zephyr_utils.h" -#ifdef CONFIG_NRFX_USBREG -#define NRFX_USBREG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_USBREG_LOG -#define NRFX_USBREG_CONFIG_LOG_ENABLED 1 -#endif +/* Define nrfx configuration based on Zephyrs KConfigs. */ +#include "nrfx_kconfig.h" -#ifdef CONFIG_NRFX_WDT -#define NRFX_WDT_ENABLED 1 -#endif -#ifdef CONFIG_WDT_NRFX_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 1 -#endif -#ifdef CONFIG_NRFX_WDT_LOG -#define NRFX_WDT_CONFIG_LOG_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT0 -#define NRFX_WDT0_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT1 -#define NRFX_WDT1_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT30 -#define NRFX_WDT30_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT31 -#define NRFX_WDT31_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT010 -#define NRFX_WDT010_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT011 -#define NRFX_WDT011_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT130 -#define NRFX_WDT130_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT131 -#define NRFX_WDT131_ENABLED 1 -#endif -#ifdef CONFIG_NRFX_WDT132 -#define NRFX_WDT132_ENABLED 1 -#endif - -#ifdef CONFIG_NRF52_ANOMALY_109_WORKAROUND -#define NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 -#define NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 -#define NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 -#define NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 -#define NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE \ - CONFIG_NRF52_ANOMALY_109_WORKAROUND_EGU_INSTANCE +/* Define resources reserved outside nrfx scope. */ +#ifdef CONFIG_NRFX_RESERVED_RESOURCES_HEADER +#include CONFIG_NRFX_RESERVED_RESOURCES_HEADER #endif +/* Include babble-sim configuration. */ #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) #include "nrfx_config_bsim.h" #endif -/* - * For chips with TrustZone support, MDK provides CMSIS-Core peripheral - * accessing symbols in two flavors, with secure and non-secure base address - * mappings. Their names contain the suffix _S or _NS, respectively. - * Because nrfx HALs and drivers require these peripheral accessing symbols - * without any suffixes, the following macro is provided that will translate - * their names according to the kind of the target that is built. - */ -#if defined(NRF_TRUSTZONE_NONSECURE) -#define NRF_PERIPH(P) P##_NS -#else -#define NRF_PERIPH(P) P##_S -#endif - -#define NRFX_CONFIG_BIT_DT(node_id, prop, idx) BIT(DT_PROP_BY_IDX(node_id, prop, idx)) -#define NRFX_CONFIG_MASK_DT(node_id, prop) \ - (COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \ - (DT_FOREACH_PROP_ELEM_SEP(node_id, prop, NRFX_CONFIG_BIT_DT, (|))), \ - (0))) - -/* If the GRTC system timer driver is to be used, prepare definitions required - * by the nrfx_grtc driver (NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK and - * NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS) based on information from devicetree. - */ -#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_grtc) -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK \ - (NRFX_CONFIG_MASK_DT(DT_INST(0, nordic_nrf_grtc), owned_channels) & \ - ~NRFX_CONFIG_MASK_DT(DT_INST(0, nordic_nrf_grtc), child_owned_channels)) -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS \ - (DT_PROP_LEN_OR(DT_INST(0, nordic_nrf_grtc), owned_channels, 0) - \ - DT_PROP_LEN_OR(DT_INST(0, nordic_nrf_grtc), child_owned_channels, 0)) -#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_grtc) */ - -/* If global of local DPPIC peripherals are used, provide the following macro - * definitions required by the interconnect/apb layer: - * - NRFX_DPPI_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) - * - NRFX_DPPI_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) - * - NRFX_DPPI_PUB_OR_SUB_MASK(inst_num) - * - NRFX_DPPI_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) - * - NRFX_INTERCONNECT_APB_GLOBAL_DPPI_DEFINE - * - NRFX_INTERCONNECT_APB_LOCAL_DPPI_DEFINE - * based on information from devicetree. - */ -#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_global) || \ - DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_local) -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 1 -#endif -/* Source (publish) channels masks generation. */ -#define NRFX_DPPI_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ - NRFX_CONFIG_MASK_DT(DT_NODELABEL(_CONCAT(dppic, inst_num)), source_channels) - -/* Sink (subscribe) channels masks generation. */ -#define NRFX_DPPI_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ - NRFX_CONFIG_MASK_DT(DT_NODELABEL(_CONCAT(dppic, inst_num)), sink_channels) - -#define NRFX_DPPI_PUB_OR_SUB_MASK(inst_num) \ - UTIL_OR(DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(dppic, inst_num)), source_channels), \ - DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(dppic, inst_num)), sink_channels)) - -/* Variables names generation. */ -#define NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(node_id) _CONCAT(_CONCAT(m_, node_id), _channels) -#define NRFX_DPPI_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) \ - NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(DT_NODELABEL(_CONCAT(dppic, inst_num))) - -/* Variables entries generation. */ -#define NRFX_CONFIG_DPPI_CHANNELS_ENTRY(node_id) \ - static nrfx_atomic_t NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(node_id) \ - __attribute__((used)) = \ - NRFX_CONFIG_MASK_DT(node_id, source_channels) | \ - NRFX_CONFIG_MASK_DT(node_id, sink_channels); -#define NRFX_INTERCONNECT_APB_GLOBAL_DPPI_DEFINE \ - DT_FOREACH_STATUS_OKAY(nordic_nrf_dppic_global, NRFX_CONFIG_DPPI_CHANNELS_ENTRY) -#define NRFX_INTERCONNECT_APB_LOCAL_DPPI_DEFINE \ - DT_FOREACH_STATUS_OKAY(nordic_nrf_dppic_local, NRFX_CONFIG_DPPI_CHANNELS_ENTRY) -#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_global) || ... */ - -/* If local or global DPPIC peripherals are used, provide the following macro - * definitions required by the interconnect/ipct layer: - * - NRFX_IPCTx_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) - * - NRFX_IPCTx_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) - * - NRFX_IPCT_PUB_OR_SUB_MASK(inst_num) - * - NRFX_IPCTx_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) - * - NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE - * - NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE - * based on information from devicetree. - */ -#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_global) || \ - DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_local) -/* Channels masks generation. */ -#define NRFX_CONFIG_IPCT_MASK_DT(node_id) \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, owned_channels), \ - (NRFX_CONFIG_MASK_DT(node_id, owned_channels)), \ - (COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, nordic_nrf_ipct_local), \ - (BIT_MASK(DT_PROP(node_id, channels))), (0)))) - -#if defined(NRF_APPLICATION) -#define NRFX_CONFIG_IPCT_LOCAL_NODE DT_NODELABEL(cpuapp_ipct) -#elif defined(NRF_RADIOCORE) -#define NRFX_CONFIG_IPCT_LOCAL_NODE DT_NODELABEL(cpurad_ipct) -#endif -#define NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num) \ - COND_CODE_1(IS_EMPTY(inst_num), \ - (NRFX_CONFIG_IPCT_LOCAL_NODE), \ - (DT_NODELABEL(_CONCAT(ipct, inst_num)))) - -#define NRFX_IPCTx_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ - NRFX_CONFIG_IPCT_MASK_DT(NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num)) - -#define NRFX_IPCTx_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ - NRFX_CONFIG_IPCT_MASK_DT(NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num)) - -#define NRFX_IPCT_PUB_OR_SUB_MASK(inst_num) \ - COND_CODE_1(IS_EMPTY(inst_num), \ - (DT_NODE_HAS_STATUS_OKAY(NRFX_CONFIG_IPCT_LOCAL_NODE)), \ - (DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(ipct, inst_num)), owned_channels))) - -/* Variables names generation. */ -#define NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(node_id) _CONCAT(_CONCAT(m_, node_id), _channels) -#define NRFX_IPCTx_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) \ - COND_CODE_1(IS_EMPTY(inst_num), \ - (NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(NRFX_CONFIG_IPCT_LOCAL_NODE)), \ - (NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(DT_NODELABEL(_CONCAT(ipct, inst_num))))) - -/* Variables entries generation. */ -#define NRFX_CONFIG_IPCT_CHANNELS_ENTRY(node_id) \ - static nrfx_atomic_t NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(node_id) \ - __attribute__((used)) = \ - NRFX_CONFIG_IPCT_MASK_DT(node_id); -#define NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE \ - DT_FOREACH_STATUS_OKAY(nordic_nrf_ipct_local, NRFX_CONFIG_IPCT_CHANNELS_ENTRY) -#define NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE \ - DT_FOREACH_STATUS_OKAY(nordic_nrf_ipct_global, NRFX_CONFIG_IPCT_CHANNELS_ENTRY) -#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_global) || ... */ - -#include +/* Use defaults for undefined symbols. */ +#include #if defined(NRF51) - #include + #include #elif defined(NRF52805_XXAA) - #include + #include #elif defined(NRF52810_XXAA) - #include + #include #elif defined(NRF52811_XXAA) - #include + #include #elif defined(NRF52820_XXAA) - #include + #include #elif defined(NRF52832_XXAA) || defined (NRF52832_XXAB) - #include + #include #elif defined(NRF52833_XXAA) - #include + #include #elif defined(NRF52840_XXAA) - #include + #include #elif defined(NRF5340_XXAA_APPLICATION) - #include + #include #elif defined(NRF5340_XXAA_NETWORK) - #include + #include #elif defined(NRF54H20_XXAA) && defined(NRF_APPLICATION) - #include + #include #elif defined(NRF54H20_XXAA) && defined(NRF_RADIOCORE) - #include + #include #elif defined(NRF54H20_XXAA) && defined(NRF_PPR) - #include + #include #elif defined(NRF54H20_XXAA) && defined(NRF_FLPR) - #include + #include +#elif defined(NRF54H20_ENGA_XXAA) && defined(NRF_APPLICATION) + #include +#elif defined(NRF54H20_ENGA_XXAA) && defined(NRF_RADIOCORE) + #include +#elif defined(NRF54H20_ENGA_XXAA) && defined(NRF_PPR) + #include +#elif defined(NRF54H20_ENGA_XXAA) && defined(NRF_FLPR) + #include +#elif defined(NRF54H20_ENGB_XXAA) && defined(NRF_APPLICATION) + #include +#elif defined(NRF54H20_ENGB_XXAA) && defined(NRF_RADIOCORE) + #include +#elif defined(NRF54H20_ENGB_XXAA) && defined(NRF_PPR) + #include +#elif defined(NRF54H20_ENGB_XXAA) && defined(NRF_FLPR) + #include #elif defined(NRF54L05_XXAA) && defined(NRF_APPLICATION) - #include + #include #elif defined(NRF54L05_XXAA) && defined(NRF_FLPR) - #include + #include +#elif defined(NRF54L09_ENGA_XXAA) && defined(NRF_APPLICATION) + #include +#elif defined(NRF54L09_ENGA_XXAA) && defined(NRF_FLPR) + #include #elif defined(NRF54L10_XXAA) && defined(NRF_APPLICATION) - #include + #include #elif defined(NRF54L10_XXAA) && defined(NRF_FLPR) - #include + #include #elif defined(NRF54L15_XXAA) && defined(NRF_APPLICATION) - #include + #include #elif defined(NRF54L15_XXAA) && defined(NRF_FLPR) - #include -#elif (defined(NRF54L20_XXAA) || defined(NRF54L20_ENGA_XXAA)) && defined(NRF_APPLICATION) - #include + #include +#elif defined(NRF54L15_ENGA_XXAA) && defined(NRF_APPLICATION) + #include +#elif defined(NRF54L15_ENGA_XXAA) && defined(NRF_FLPR) + #include +#elif defined(NRF54L20_ENGA_XXAA) && defined(NRF_APPLICATION) + #include +#elif defined(NRF54L20_ENGA_XXAA) && defined(NRF_FLPR) + #include #elif defined(NRF9120_XXAA) || defined(NRF9160_XXAA) - #include + #include #elif defined(NRF9230_ENGB_XXAA) && defined(NRF_APPLICATION) - #include + #include #elif defined(NRF9230_ENGB_XXAA) && defined(NRF_RADIOCORE) - #include + #include #elif defined(NRF9230_ENGB_XXAA) && defined(NRF_PPR) - #include + #include +#elif defined(NRF9230_ENGB_XXAA) && defined(NRF_FLPR) + #include #else - #include + #include "nrfx_config_ext.h" #endif #endif // NRFX_CONFIG_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_common.h b/modules/hal_nordic/nrfx/nrfx_config_common.h deleted file mode 100644 index 0cf800680381a..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_common.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_COMMON_H__ -#define NRFX_CONFIG_COMMON_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - -/** @brief Symbol specifying major version of the nrfx API to be used. */ -#ifndef NRFX_CONFIG_API_VER_MAJOR -#define NRFX_CONFIG_API_VER_MAJOR 3 -#endif - -/** @brief Symbol specifying minor version of the nrfx API to be used. */ -#ifndef NRFX_CONFIG_API_VER_MINOR -#define NRFX_CONFIG_API_VER_MINOR 8 -#endif - -/** @brief Symbol specifying micro version of the nrfx API to be used. */ -#ifndef NRFX_CONFIG_API_VER_MICRO -#define NRFX_CONFIG_API_VER_MICRO 0 -#endif - -#endif /* NRFX_CONFIG_COMMON_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_ext.h b/modules/hal_nordic/nrfx/nrfx_config_ext.h deleted file mode 100644 index 9110b2fa7a958..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_ext.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2023 - 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_EXT_H__ -#define NRFX_CONFIG_EXT_H__ - -#error "Unknown device." - -#endif /* NRFX_CONFIG_EXT_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf51.h b/modules/hal_nordic/nrfx/nrfx_config_nrf51.h deleted file mode 100644 index 51d8bb1b8a516..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf51.h +++ /dev/null @@ -1,871 +0,0 @@ -/* - * Copyright (c) 2017 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF51_H__ -#define NRFX_CONFIG_NRF51_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 3 -#endif - -/** - * @brief NRFX_ADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_ADC_ENABLED -#define NRFX_ADC_ENABLED 0 -#endif - -/** - * @brief NRFX_ADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_ADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_ADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_ADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_ADC_CONFIG_LOG_ENABLED -#define NRFX_ADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_ADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_ADC_CONFIG_LOG_LEVEL -#define NRFX_ADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_ENABLED -#define NRFX_PPI_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_CONFIG_LOG_ENABLED -#define NRFX_PPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPI_CONFIG_LOG_LEVEL -#define NRFX_PPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_ENABLED -#define NRFX_SPI_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_CONFIG_LOG_ENABLED -#define NRFX_SPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPI_CONFIG_LOG_LEVEL -#define NRFX_SPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI0_ENABLED -#define NRFX_SPI0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI1_ENABLED -#define NRFX_SPI1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS1_ENABLED -#define NRFX_SPIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_ENABLED -#define NRFX_TWI_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_CONFIG_LOG_ENABLED -#define NRFX_TWI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWI_CONFIG_LOG_LEVEL -#define NRFX_TWI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI0_ENABLED -#define NRFX_TWI0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI1_ENABLED -#define NRFX_TWI1_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_ENABLED -#define NRFX_UART_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_CONFIG_LOG_ENABLED -#define NRFX_UART_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UART_CONFIG_LOG_LEVEL -#define NRFX_UART_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UART0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART0_ENABLED -#define NRFX_UART0_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 3 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF51_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52805.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52805.h deleted file mode 100644 index 3ae4fa2228ce6..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52805.h +++ /dev/null @@ -1,1117 +0,0 @@ -/* - * Copyright (c) 2020 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF52805_H__ -#define NRFX_CONFIG_NRF52805_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - * - External Low Swing = 131073 - * - External Full Swing = 196609 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_CT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_CT_ENABLED -#define NRFX_CLOCK_CONFIG_CT_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_ENABLED -#define NRFX_PPI_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_CONFIG_LOG_ENABLED -#define NRFX_PPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPI_CONFIG_LOG_LEVEL -#define NRFX_PPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_ENABLED -#define NRFX_SPI_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_CONFIG_LOG_ENABLED -#define NRFX_SPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPI_CONFIG_LOG_LEVEL -#define NRFX_SPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI0_ENABLED -#define NRFX_SPI0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_ENABLED -#define NRFX_TWI_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_CONFIG_LOG_ENABLED -#define NRFX_TWI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWI_CONFIG_LOG_LEVEL -#define NRFX_TWI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI0_ENABLED -#define NRFX_TWI0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_ENABLED -#define NRFX_UART_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_CONFIG_LOG_ENABLED -#define NRFX_UART_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UART_CONFIG_LOG_LEVEL -#define NRFX_UART_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UART0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART0_ENABLED -#define NRFX_UART0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF52805_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52810.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52810.h deleted file mode 100644 index c61641c8719b8..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52810.h +++ /dev/null @@ -1,1252 +0,0 @@ -/* - * Copyright (c) 2017 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF52810_H__ -#define NRFX_CONFIG_NRF52810_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - * - External Low Swing = 131073 - * - External Full Swing = 196609 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_CT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_CT_ENABLED -#define NRFX_CLOCK_CONFIG_CT_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_ENABLED -#define NRFX_PPI_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_CONFIG_LOG_ENABLED -#define NRFX_PPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPI_CONFIG_LOG_LEVEL -#define NRFX_PPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM0_ENABLED -#define NRFX_PWM0_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_ENABLED -#define NRFX_SPI_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_CONFIG_LOG_ENABLED -#define NRFX_SPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPI_CONFIG_LOG_LEVEL -#define NRFX_SPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI0_ENABLED -#define NRFX_SPI0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_ENABLED -#define NRFX_TWI_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_CONFIG_LOG_ENABLED -#define NRFX_TWI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWI_CONFIG_LOG_LEVEL -#define NRFX_TWI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI0_ENABLED -#define NRFX_TWI0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_ENABLED -#define NRFX_UART_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_CONFIG_LOG_ENABLED -#define NRFX_UART_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UART_CONFIG_LOG_LEVEL -#define NRFX_UART_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UART0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART0_ENABLED -#define NRFX_UART0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF52810_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52811.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52811.h deleted file mode 100644 index 152569ed89996..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52811.h +++ /dev/null @@ -1,1279 +0,0 @@ -/* - * Copyright (c) 2018 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF52811_H__ -#define NRFX_CONFIG_NRF52811_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - * - External Low Swing = 131073 - * - External Full Swing = 196609 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_CT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_CT_ENABLED -#define NRFX_CLOCK_CONFIG_CT_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_ENABLED -#define NRFX_PPI_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_CONFIG_LOG_ENABLED -#define NRFX_PPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPI_CONFIG_LOG_LEVEL -#define NRFX_PPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM0_ENABLED -#define NRFX_PWM0_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_ENABLED -#define NRFX_SPI_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_CONFIG_LOG_ENABLED -#define NRFX_SPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPI_CONFIG_LOG_LEVEL -#define NRFX_SPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI1_ENABLED -#define NRFX_SPI1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI0_ENABLED -#define NRFX_SPI0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM1_ENABLED -#define NRFX_SPIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS1_ENABLED -#define NRFX_SPIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_ENABLED -#define NRFX_TWI_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_CONFIG_LOG_ENABLED -#define NRFX_TWI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWI_CONFIG_LOG_LEVEL -#define NRFX_TWI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI0_ENABLED -#define NRFX_TWI0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_ENABLED -#define NRFX_UART_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_CONFIG_LOG_ENABLED -#define NRFX_UART_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UART_CONFIG_LOG_LEVEL -#define NRFX_UART_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UART0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART0_ENABLED -#define NRFX_UART0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF52811_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52820.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52820.h deleted file mode 100644 index 863b073f0281b..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52820.h +++ /dev/null @@ -1,1277 +0,0 @@ -/* - * Copyright (c) 2020 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF52820_H__ -#define NRFX_CONFIG_NRF52820_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - * - External Low Swing = 131073 - * - External Full Swing = 196609 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_CT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_CT_ENABLED -#define NRFX_CLOCK_CONFIG_CT_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU2_ENABLED -#define NRFX_EGU2_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU3_ENABLED -#define NRFX_EGU3_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU4_ENABLED -#define NRFX_EGU4_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU5_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU5_ENABLED -#define NRFX_EGU5_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_ENABLED -#define NRFX_PPI_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_CONFIG_LOG_ENABLED -#define NRFX_PPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPI_CONFIG_LOG_LEVEL -#define NRFX_PPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_ENABLED -#define NRFX_SPI_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_CONFIG_LOG_ENABLED -#define NRFX_SPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPI_CONFIG_LOG_LEVEL -#define NRFX_SPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI0_ENABLED -#define NRFX_SPI0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI1_ENABLED -#define NRFX_SPI1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM1_ENABLED -#define NRFX_SPIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS1_ENABLED -#define NRFX_SPIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER3_ENABLED -#define NRFX_TIMER3_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_ENABLED -#define NRFX_TWI_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_CONFIG_LOG_ENABLED -#define NRFX_TWI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWI_CONFIG_LOG_LEVEL -#define NRFX_TWI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI0_ENABLED -#define NRFX_TWI0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI1_ENABLED -#define NRFX_TWI1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM1_ENABLED -#define NRFX_TWIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS1_ENABLED -#define NRFX_TWIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_ENABLED -#define NRFX_UART_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_CONFIG_LOG_ENABLED -#define NRFX_UART_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UART_CONFIG_LOG_LEVEL -#define NRFX_UART_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UART0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART0_ENABLED -#define NRFX_UART0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_ENABLED -#define NRFX_USBD_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST -#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1 -#endif - -/** - * @brief NRFX_USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when - * no data is ready. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP -#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0 -#endif - -/** - * @brief NRFX_USBD_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_LOG_ENABLED -#define NRFX_USBD_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_USBD_CONFIG_LOG_LEVEL -#define NRFX_USBD_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF52820_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52832.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52832.h deleted file mode 100644 index b181bf6cdcc6e..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52832.h +++ /dev/null @@ -1,1608 +0,0 @@ -/* - * Copyright (c) 2017 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF52832_H__ -#define NRFX_CONFIG_NRF52832_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - * - External Low Swing = 131073 - * - External Full Swing = 196609 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_CT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_CT_ENABLED -#define NRFX_CLOCK_CONFIG_CT_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU2_ENABLED -#define NRFX_EGU2_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU3_ENABLED -#define NRFX_EGU3_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU4_ENABLED -#define NRFX_EGU4_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU5_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU5_ENABLED -#define NRFX_EGU5_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0 Maximum: 5 - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 4 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_ENABLED -#define NRFX_PPI_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_CONFIG_LOG_ENABLED -#define NRFX_PPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPI_CONFIG_LOG_LEVEL -#define NRFX_PPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 Anomaly 109 workaround - * for PWM. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED -#define NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE - EGU instance used by the nRF52 Anomaly 109 - * workaround for PWM. - * - * Integer value. Minimum: 0 Maximum: 5 - */ -#ifndef NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE -#define NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE 5 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM0_ENABLED -#define NRFX_PWM0_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM1_ENABLED -#define NRFX_PWM1_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM2_ENABLED -#define NRFX_PWM2_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC2_ENABLED -#define NRFX_RTC2_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_ENABLED -#define NRFX_SPI_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_CONFIG_LOG_ENABLED -#define NRFX_SPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPI_CONFIG_LOG_LEVEL -#define NRFX_SPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI0_ENABLED -#define NRFX_SPI0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI1_ENABLED -#define NRFX_SPI1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI2_ENABLED -#define NRFX_SPI2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 Anomaly 109 workaround for - * SPIM. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED -#define NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM1_ENABLED -#define NRFX_SPIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM2_ENABLED -#define NRFX_SPIM2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 Anomaly 109 workaround - * for SPIS. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED -#define NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS1_ENABLED -#define NRFX_SPIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS2_ENABLED -#define NRFX_SPIS2_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER3_ENABLED -#define NRFX_TIMER3_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER4_ENABLED -#define NRFX_TIMER4_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_ENABLED -#define NRFX_TWI_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_CONFIG_LOG_ENABLED -#define NRFX_TWI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWI_CONFIG_LOG_LEVEL -#define NRFX_TWI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI0_ENABLED -#define NRFX_TWI0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI1_ENABLED -#define NRFX_TWI1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 Anomaly 109 workaround for - * TWIM. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED -#define NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM1_ENABLED -#define NRFX_TWIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS1_ENABLED -#define NRFX_TWIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_ENABLED -#define NRFX_UART_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_CONFIG_LOG_ENABLED -#define NRFX_UART_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UART_CONFIG_LOG_LEVEL -#define NRFX_UART_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UART0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART0_ENABLED -#define NRFX_UART0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF52832_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52833.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52833.h deleted file mode 100644 index f53b04eb62d5f..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52833.h +++ /dev/null @@ -1,1646 +0,0 @@ -/* - * Copyright (c) 2019 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF52833_H__ -#define NRFX_CONFIG_NRF52833_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - * - External Low Swing = 131073 - * - External Full Swing = 196609 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_CT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_CT_ENABLED -#define NRFX_CLOCK_CONFIG_CT_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU2_ENABLED -#define NRFX_EGU2_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU3_ENABLED -#define NRFX_EGU3_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU4_ENABLED -#define NRFX_EGU4_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU5_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU5_ENABLED -#define NRFX_EGU5_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0 Maximum: 5 - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 4 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_ENABLED -#define NRFX_PPI_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_CONFIG_LOG_ENABLED -#define NRFX_PPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPI_CONFIG_LOG_LEVEL -#define NRFX_PPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM0_ENABLED -#define NRFX_PWM0_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM1_ENABLED -#define NRFX_PWM1_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM2_ENABLED -#define NRFX_PWM2_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM3_ENABLED -#define NRFX_PWM3_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC2_ENABLED -#define NRFX_RTC2_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_ENABLED -#define NRFX_SPI_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_CONFIG_LOG_ENABLED -#define NRFX_SPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPI_CONFIG_LOG_LEVEL -#define NRFX_SPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI0_ENABLED -#define NRFX_SPI0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI1_ENABLED -#define NRFX_SPI1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI2_ENABLED -#define NRFX_SPI2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM1_ENABLED -#define NRFX_SPIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM2_ENABLED -#define NRFX_SPIM2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM3_ENABLED -#define NRFX_SPIM3_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS1_ENABLED -#define NRFX_SPIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS2_ENABLED -#define NRFX_SPIS2_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER3_ENABLED -#define NRFX_TIMER3_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER4_ENABLED -#define NRFX_TIMER4_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_ENABLED -#define NRFX_TWI_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_CONFIG_LOG_ENABLED -#define NRFX_TWI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWI_CONFIG_LOG_LEVEL -#define NRFX_TWI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI0_ENABLED -#define NRFX_TWI0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI1_ENABLED -#define NRFX_TWI1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM1_ENABLED -#define NRFX_TWIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS1_ENABLED -#define NRFX_TWIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_ENABLED -#define NRFX_UART_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_CONFIG_LOG_ENABLED -#define NRFX_UART_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UART_CONFIG_LOG_LEVEL -#define NRFX_UART_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UART0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART0_ENABLED -#define NRFX_UART0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE1_ENABLED -#define NRFX_UARTE1_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_ENABLED -#define NRFX_USBD_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST -#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1 -#endif - -/** - * @brief NRFX_USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when no - * data is ready. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP -#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0 -#endif - -/** - * @brief NRFX_USBD_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_LOG_ENABLED -#define NRFX_USBD_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_USBD_CONFIG_LOG_LEVEL -#define NRFX_USBD_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF52833_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52840.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52840.h deleted file mode 100644 index 0c49a6e5474ff..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52840.h +++ /dev/null @@ -1,1673 +0,0 @@ -/* - * Copyright (c) 2017 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF52840_H__ -#define NRFX_CONFIG_NRF52840_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - * - External Low Swing = 131073 - * - External Full Swing = 196609 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_CT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_CT_ENABLED -#define NRFX_CLOCK_CONFIG_CT_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU2_ENABLED -#define NRFX_EGU2_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU3_ENABLED -#define NRFX_EGU3_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU4_ENABLED -#define NRFX_EGU4_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU5_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU5_ENABLED -#define NRFX_EGU5_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0 Maximum: 5 - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 4 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_ENABLED -#define NRFX_PPI_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PPI_CONFIG_LOG_ENABLED -#define NRFX_PPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPI_CONFIG_LOG_LEVEL -#define NRFX_PPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM0_ENABLED -#define NRFX_PWM0_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM1_ENABLED -#define NRFX_PWM1_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM2_ENABLED -#define NRFX_PWM2_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM3_ENABLED -#define NRFX_PWM3_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QSPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QSPI_ENABLED -#define NRFX_QSPI_ENABLED 0 -#endif - -/** - * @brief NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC2_ENABLED -#define NRFX_RTC2_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_ENABLED -#define NRFX_SPI_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI_CONFIG_LOG_ENABLED -#define NRFX_SPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPI_CONFIG_LOG_LEVEL -#define NRFX_SPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI0_ENABLED -#define NRFX_SPI0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI1_ENABLED -#define NRFX_SPI1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPI2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPI2_ENABLED -#define NRFX_SPI2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED -#define NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM1_ENABLED -#define NRFX_SPIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM2_ENABLED -#define NRFX_SPIM2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM3_ENABLED -#define NRFX_SPIM3_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS1_ENABLED -#define NRFX_SPIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS2_ENABLED -#define NRFX_SPIS2_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER3_ENABLED -#define NRFX_TIMER3_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER4_ENABLED -#define NRFX_TIMER4_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_ENABLED -#define NRFX_TWI_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI_CONFIG_LOG_ENABLED -#define NRFX_TWI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWI_CONFIG_LOG_LEVEL -#define NRFX_TWI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWI0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI0_ENABLED -#define NRFX_TWI0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWI1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWI1_ENABLED -#define NRFX_TWI1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM1_ENABLED -#define NRFX_TWIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS1_ENABLED -#define NRFX_TWIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_ENABLED -#define NRFX_UART_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART_CONFIG_LOG_ENABLED -#define NRFX_UART_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UART_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UART_CONFIG_LOG_LEVEL -#define NRFX_UART_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UART0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UART0_ENABLED -#define NRFX_UART0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE1_ENABLED -#define NRFX_UARTE1_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_ENABLED -#define NRFX_USBD_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST -#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1 -#endif - -/** - * @brief NRFX_USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when no - * data is ready. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP -#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0 -#endif - -/** - * @brief NRFX_USBD_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_LOG_ENABLED -#define NRFX_USBD_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_USBD_CONFIG_LOG_LEVEL -#define NRFX_USBD_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF52840_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h deleted file mode 100644 index ab04db03f155c..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h +++ /dev/null @@ -1,1615 +0,0 @@ -/* - * Copyright (c) 2019 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF5340_APPLICATION_H__ -#define NRFX_CONFIG_NRF5340_APPLICATION_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - -#define NRF_CLOCK NRF_PERIPH(NRF_CLOCK) -#define NRF_COMP NRF_PERIPH(NRF_COMP) -#define NRF_CTRLAP NRF_PERIPH(NRF_CTRLAP) -#define NRF_DCNF NRF_PERIPH(NRF_DCNF) -#define NRF_DPPIC NRF_PERIPH(NRF_DPPIC) -#define NRF_EGU0 NRF_PERIPH(NRF_EGU0) -#define NRF_EGU1 NRF_PERIPH(NRF_EGU1) -#define NRF_EGU2 NRF_PERIPH(NRF_EGU2) -#define NRF_EGU3 NRF_PERIPH(NRF_EGU3) -#define NRF_EGU4 NRF_PERIPH(NRF_EGU4) -#define NRF_EGU5 NRF_PERIPH(NRF_EGU5) -#define NRF_FPU NRF_PERIPH(NRF_FPU) -#define NRF_I2S0 NRF_PERIPH(NRF_I2S0) -#define NRF_IPC NRF_PERIPH(NRF_IPC) -#define NRF_KMU NRF_PERIPH(NRF_KMU) -#define NRF_LPCOMP NRF_PERIPH(NRF_LPCOMP) -#define NRF_MUTEX NRF_PERIPH(NRF_MUTEX) -#define NRF_NFCT NRF_PERIPH(NRF_NFCT) -#define NRF_NVMC NRF_PERIPH(NRF_NVMC) -#define NRF_OSCILLATORS NRF_PERIPH(NRF_OSCILLATORS) -#define NRF_P0 NRF_PERIPH(NRF_P0) -#define NRF_P1 NRF_PERIPH(NRF_P1) -#define NRF_PDM0 NRF_PERIPH(NRF_PDM0) -#define NRF_POWER NRF_PERIPH(NRF_POWER) -#define NRF_PWM0 NRF_PERIPH(NRF_PWM0) -#define NRF_PWM1 NRF_PERIPH(NRF_PWM1) -#define NRF_PWM2 NRF_PERIPH(NRF_PWM2) -#define NRF_PWM3 NRF_PERIPH(NRF_PWM3) -#define NRF_QDEC0 NRF_PERIPH(NRF_QDEC0) -#define NRF_QDEC1 NRF_PERIPH(NRF_QDEC1) -#define NRF_QSPI NRF_PERIPH(NRF_QSPI) -#define NRF_REGULATORS NRF_PERIPH(NRF_REGULATORS) -#define NRF_RESET NRF_PERIPH(NRF_RESET) -#define NRF_RTC0 NRF_PERIPH(NRF_RTC0) -#define NRF_RTC1 NRF_PERIPH(NRF_RTC1) -#define NRF_SAADC NRF_PERIPH(NRF_SAADC) -#define NRF_SPIM0 NRF_PERIPH(NRF_SPIM0) -#define NRF_SPIM1 NRF_PERIPH(NRF_SPIM1) -#define NRF_SPIM2 NRF_PERIPH(NRF_SPIM2) -#define NRF_SPIM3 NRF_PERIPH(NRF_SPIM3) -#define NRF_SPIM4 NRF_PERIPH(NRF_SPIM4) -#define NRF_SPIS0 NRF_PERIPH(NRF_SPIS0) -#define NRF_SPIS1 NRF_PERIPH(NRF_SPIS1) -#define NRF_SPIS2 NRF_PERIPH(NRF_SPIS2) -#define NRF_SPIS3 NRF_PERIPH(NRF_SPIS3) -#define NRF_TIMER0 NRF_PERIPH(NRF_TIMER0) -#define NRF_TIMER1 NRF_PERIPH(NRF_TIMER1) -#define NRF_TIMER2 NRF_PERIPH(NRF_TIMER2) -#define NRF_TWIM0 NRF_PERIPH(NRF_TWIM0) -#define NRF_TWIM1 NRF_PERIPH(NRF_TWIM1) -#define NRF_TWIM2 NRF_PERIPH(NRF_TWIM2) -#define NRF_TWIM3 NRF_PERIPH(NRF_TWIM3) -#define NRF_TWIS0 NRF_PERIPH(NRF_TWIS0) -#define NRF_TWIS1 NRF_PERIPH(NRF_TWIS1) -#define NRF_TWIS2 NRF_PERIPH(NRF_TWIS2) -#define NRF_TWIS3 NRF_PERIPH(NRF_TWIS3) -#define NRF_UARTE0 NRF_PERIPH(NRF_UARTE0) -#define NRF_UARTE1 NRF_PERIPH(NRF_UARTE1) -#define NRF_UARTE2 NRF_PERIPH(NRF_UARTE2) -#define NRF_UARTE3 NRF_PERIPH(NRF_UARTE3) -#define NRF_USBD NRF_PERIPH(NRF_USBD) -#define NRF_USBREGULATOR NRF_PERIPH(NRF_USBREGULATOR) -#define NRF_VMC NRF_PERIPH(NRF_VMC) -#define NRF_WDT0 NRF_PERIPH(NRF_WDT0) -#define NRF_WDT1 NRF_PERIPH(NRF_WDT1) - -/* - * The following section provides the name translation for peripherals with - * only one type of access available. For these peripherals, you cannot choose - * between secure and non-secure mapping. - */ -#if defined(NRF_TRUSTZONE_NONSECURE) -#define NRF_GPIOTE NRF_GPIOTE1 -#define NRF_GPIOTE1 NRF_GPIOTE1_NS -#else -#define NRF_CACHE NRF_CACHE_S -#define NRF_CACHEINFO NRF_CACHEINFO_S -#define NRF_CACHEDATA NRF_CACHEDATA_S -#define NRF_CRYPTOCELL NRF_CRYPTOCELL_S -#define NRF_CTI NRF_CTI_S -#define NRF_FICR NRF_FICR_S -#define NRF_GPIOTE NRF_GPIOTE0 -#define NRF_GPIOTE0 NRF_GPIOTE0_S -#define NRF_GPIOTE1 NRF_GPIOTE1_NS -#define NRF_SPU NRF_SPU_S -#define NRF_TAD NRF_TAD_S -#define NRF_UICR NRF_UICR_S -#endif - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_HFCLK192M_SRC - * - * Integer value. - * Supported values: - * - HFINT = 0 - * - HFXO = 1 - */ -#ifndef NRFX_CLOCK_CONFIG_HFCLK192M_SRC -#define NRFX_CLOCK_CONFIG_HFCLK192M_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 1 - * - XTAL = 2 - * - Synth = 3 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 2 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU2_ENABLED -#define NRFX_EGU2_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU3_ENABLED -#define NRFX_EGU3_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU4_ENABLED -#define NRFX_EGU4_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU5_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU5_ENABLED -#define NRFX_EGU5_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S0_ENABLED -#define NRFX_I2S0_ENABLED 0 -#endif - -/** - * @brief NRFX_IPC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_IPC_ENABLED -#define NRFX_IPC_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0 Maximum: 5 - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 2 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM0_ENABLED -#define NRFX_PDM0_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM0_ENABLED -#define NRFX_PWM0_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM1_ENABLED -#define NRFX_PWM1_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM2_ENABLED -#define NRFX_PWM2_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM3_ENABLED -#define NRFX_PWM3_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC0_ENABLED -#define NRFX_QDEC0_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QDEC1_ENABLED -#define NRFX_QDEC1_ENABLED 0 -#endif - -/** - * @brief NRFX_QSPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_QSPI_ENABLED -#define NRFX_QSPI_ENABLED 0 -#endif - -/** - * @brief NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QSPI_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM1_ENABLED -#define NRFX_SPIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM4_ENABLED -#define NRFX_SPIM4_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM2_ENABLED -#define NRFX_SPIM2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM3_ENABLED -#define NRFX_SPIM3_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS1_ENABLED -#define NRFX_SPIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS2_ENABLED -#define NRFX_SPIS2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS3_ENABLED -#define NRFX_SPIS3_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM1_ENABLED -#define NRFX_TWIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM2_ENABLED -#define NRFX_TWIM2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM3_ENABLED -#define NRFX_TWIM3_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS1_ENABLED -#define NRFX_TWIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS2_ENABLED -#define NRFX_TWIS2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS3_ENABLED -#define NRFX_TWIS3_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE1_ENABLED -#define NRFX_UARTE1_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE2_ENABLED -#define NRFX_UARTE2_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE3_ENABLED -#define NRFX_UARTE3_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_ENABLED -#define NRFX_USBD_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_USBD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST -#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1 -#endif - -/** - * @brief NRFX_USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when no - * data is ready. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP -#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0 -#endif - -/** - * @brief NRFX_USBD_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBD_CONFIG_LOG_ENABLED -#define NRFX_USBD_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_USBD_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_USBD_CONFIG_LOG_LEVEL -#define NRFX_USBD_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_USBREG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_USBREG_ENABLED -#define NRFX_USBREG_ENABLED 0 -#endif - -/** - * @brief NRFX_USBREG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_USBREG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_USBREG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT0_ENABLED -#define NRFX_WDT0_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT1_ENABLED -#define NRFX_WDT1_ENABLED 0 -#endif - -#endif // NRFX_CONFIG_NRF5340_APPLICATION_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf5340_network.h b/modules/hal_nordic/nrfx/nrfx_config_nrf5340_network.h deleted file mode 100644 index 938172460fa79..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf5340_network.h +++ /dev/null @@ -1,888 +0,0 @@ -/* - * Copyright (c) 2019 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF5340_NETWORK_H__ -#define NRFX_CONFIG_NRF5340_NETWORK_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - -/* - * The MDK provides macros for accessing the peripheral register structures - * by using their secure and non-secure address mappings (with the names - * containing the suffix _S or _NS, respectively). Because the nrfx drivers - * use the macros without any suffixes, you must translate the names. - * The following section provides configuration for the name translation. - */ -#define NRF_AAR NRF_AAR_NS -#define NRF_ACL NRF_ACL_NS -#define NRF_CCM NRF_CCM_NS -#define NRF_CLOCK NRF_CLOCK_NS -#define NRF_CTI NRF_CTI_NS -#define NRF_CTRLAP NRF_CTRLAP_NS -#define NRF_DCNF NRF_DCNF_NS -#define NRF_DPPIC NRF_DPPIC_NS -#define NRF_ECB NRF_ECB_NS -#define NRF_EGU0 NRF_EGU0_NS -#define NRF_FICR NRF_FICR_NS -#define NRF_GPIOTE NRF_GPIOTE_NS -#define NRF_IPC NRF_IPC_NS -#define NRF_NVMC NRF_NVMC_NS -#define NRF_P0 NRF_P0_NS -#define NRF_P1 NRF_P1_NS -#define NRF_POWER NRF_POWER_NS -#define NRF_RADIO NRF_RADIO_NS -#define NRF_RESET NRF_RESET_NS -#define NRF_RNG NRF_RNG_NS -#define NRF_RTC0 NRF_RTC0_NS -#define NRF_RTC1 NRF_RTC1_NS -#define NRF_SPIM0 NRF_SPIM0_NS -#define NRF_SPIS0 NRF_SPIS0_NS -#define NRF_SWI0 NRF_SWI0_NS -#define NRF_SWI1 NRF_SWI1_NS -#define NRF_SWI2 NRF_SWI2_NS -#define NRF_SWI3 NRF_SWI3_NS -#define NRF_TEMP NRF_TEMP_NS -#define NRF_TIMER0 NRF_TIMER0_NS -#define NRF_TIMER1 NRF_TIMER1_NS -#define NRF_TIMER2 NRF_TIMER2_NS -#define NRF_TWIM0 NRF_TWIM0_NS -#define NRF_TWIS0 NRF_TWIS0_NS -#define NRF_UARTE0 NRF_UARTE0_NS -#define NRF_UICR NRF_UICR_NS -#define NRF_VMC NRF_VMC_NS -#define NRF_VREQCTRL NRF_VREQCTRL_NS -#define NRF_WDT NRF_WDT_NS - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 1 - * - XTAL = 2 - * - Synth = 3 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 2 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_IPC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_IPC_ENABLED -#define NRFX_IPC_ENABLED 0 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_ENABLED -#define NRFX_RNG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RNG_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RNG_CONFIG_LOG_ENABLED -#define NRFX_RNG_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RNG_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RNG_CONFIG_LOG_LEVEL -#define NRFX_RNG_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif // NRFX_CONFIG_NRF5340_NETWORK_H__ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_application.h deleted file mode 100644 index 3caed86c48b4a..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_application.h +++ /dev/null @@ -1,1947 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54H20_APPLICATION_H__ -#define NRFX_CONFIG_NRF54H20_APPLICATION_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_BELLBOARD_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD_ENABLED -#define NRFX_BELLBOARD_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_BELLBOARD0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD0_ENABLED -#define NRFX_BELLBOARD0_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD1_ENABLED -#define NRFX_BELLBOARD1_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD2_ENABLED -#define NRFX_BELLBOARD2_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD3_ENABLED -#define NRFX_BELLBOARD3_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e -#endif - -/** - * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 -#endif - -/** - * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 -#endif - -/** - * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 -#endif - -/** - * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000f -#endif - -/** - * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 -#endif - -/** - * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df -#endif - -/** - * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf -#endif - -/** - * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU130_ENABLED -#define NRFX_EGU130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE130_ENABLED -#define NRFX_GPIOTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_MVDMA_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA_ENABLED -#define NRFX_MVDMA_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA120_ENABLED -#define NRFX_MVDMA120_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_6_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_6_ENABLED -#define NRFX_PRS_BOX_6_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_7_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_7_ENABLED -#define NRFX_PRS_BOX_7_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_8_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_8_ENABLED -#define NRFX_PRS_BOX_8_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_9_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_9_ENABLED -#define NRFX_PRS_BOX_9_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM120_ENABLED -#define NRFX_PWM120_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM130_ENABLED -#define NRFX_PWM130_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM131_ENABLED -#define NRFX_PWM131_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM132_ENABLED -#define NRFX_PWM132_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM133_ENABLED -#define NRFX_PWM133_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC130_ENABLED -#define NRFX_QDEC130_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC131_ENABLED -#define NRFX_QDEC131_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC130_ENABLED -#define NRFX_RTC130_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC131_ENABLED -#define NRFX_RTC131_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM120_ENABLED -#define NRFX_SPIM120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM121_ENABLED -#define NRFX_SPIM121_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM130_ENABLED -#define NRFX_SPIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM131_ENABLED -#define NRFX_SPIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM132_ENABLED -#define NRFX_SPIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM133_ENABLED -#define NRFX_SPIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM134_ENABLED -#define NRFX_SPIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM135_ENABLED -#define NRFX_SPIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM136_ENABLED -#define NRFX_SPIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM137_ENABLED -#define NRFX_SPIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS120_ENABLED -#define NRFX_SPIS120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS130_ENABLED -#define NRFX_SPIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS131_ENABLED -#define NRFX_SPIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS132_ENABLED -#define NRFX_SPIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS133_ENABLED -#define NRFX_SPIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS134_ENABLED -#define NRFX_SPIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS135_ENABLED -#define NRFX_SPIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS136_ENABLED -#define NRFX_SPIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS137_ENABLED -#define NRFX_SPIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER120_ENABLED -#define NRFX_TIMER120_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER121_ENABLED -#define NRFX_TIMER121_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER130_ENABLED -#define NRFX_TIMER130_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER131_ENABLED -#define NRFX_TIMER131_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER132_ENABLED -#define NRFX_TIMER132_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER133_ENABLED -#define NRFX_TIMER133_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER134_ENABLED -#define NRFX_TIMER134_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER135_ENABLED -#define NRFX_TIMER135_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER136_ENABLED -#define NRFX_TIMER136_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER137_ENABLED -#define NRFX_TIMER137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM130_ENABLED -#define NRFX_TWIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM131_ENABLED -#define NRFX_TWIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM132_ENABLED -#define NRFX_TWIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM133_ENABLED -#define NRFX_TWIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM134_ENABLED -#define NRFX_TWIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM135_ENABLED -#define NRFX_TWIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM136_ENABLED -#define NRFX_TWIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM137_ENABLED -#define NRFX_TWIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance - * would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS130_ENABLED -#define NRFX_TWIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS131_ENABLED -#define NRFX_TWIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS132_ENABLED -#define NRFX_TWIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS133_ENABLED -#define NRFX_TWIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS134_ENABLED -#define NRFX_TWIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS135_ENABLED -#define NRFX_TWIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS136_ENABLED -#define NRFX_TWIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS137_ENABLED -#define NRFX_TWIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for - * configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for - * configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking - * of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED -#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE120_ENABLED -#define NRFX_UARTE120_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE130_ENABLED -#define NRFX_UARTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE131_ENABLED -#define NRFX_UARTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE132_ENABLED -#define NRFX_UARTE132_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE133_ENABLED -#define NRFX_UARTE133_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE134_ENABLED -#define NRFX_UARTE134_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE135_ENABLED -#define NRFX_UARTE135_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE136_ENABLED -#define NRFX_UARTE136_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE137_ENABLED -#define NRFX_UARTE137_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT010_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT010_ENABLED -#define NRFX_WDT010_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT011_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT011_ENABLED -#define NRFX_WDT011_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT131_ENABLED -#define NRFX_WDT131_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT132_ENABLED -#define NRFX_WDT132_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54H20_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_flpr.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_flpr.h deleted file mode 100644 index f5689f79a968b..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_flpr.h +++ /dev/null @@ -1,1823 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54H20_FLPR_H__ -#define NRFX_CONFIG_NRF54H20_FLPR_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 0 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COREDEP_VPR_LEGACY - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COREDEP_VPR_LEGACY -#define NRFX_COREDEP_VPR_LEGACY 0 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000030 -#endif - -/** - * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e -#endif - -/** - * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 -#endif - -/** - * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 -#endif - -/** - * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 -#endif - -/** - * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 -#endif - -/** - * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df -#endif - -/** - * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf -#endif - -/** - * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU130_ENABLED -#define NRFX_EGU130_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000030 -#endif - -/** - * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000c0 -#endif - -/** - * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_MVDMA_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA_ENABLED -#define NRFX_MVDMA_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA120_ENABLED -#define NRFX_MVDMA120_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_6_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_6_ENABLED -#define NRFX_PRS_BOX_6_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_7_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_7_ENABLED -#define NRFX_PRS_BOX_7_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_8_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_8_ENABLED -#define NRFX_PRS_BOX_8_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_9_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_9_ENABLED -#define NRFX_PRS_BOX_9_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM120_ENABLED -#define NRFX_PWM120_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM130_ENABLED -#define NRFX_PWM130_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM131_ENABLED -#define NRFX_PWM131_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM132_ENABLED -#define NRFX_PWM132_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM133_ENABLED -#define NRFX_PWM133_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC130_ENABLED -#define NRFX_QDEC130_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC131_ENABLED -#define NRFX_QDEC131_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC130_ENABLED -#define NRFX_RTC130_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC131_ENABLED -#define NRFX_RTC131_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM120_ENABLED -#define NRFX_SPIM120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM121_ENABLED -#define NRFX_SPIM121_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM130_ENABLED -#define NRFX_SPIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM131_ENABLED -#define NRFX_SPIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM132_ENABLED -#define NRFX_SPIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM133_ENABLED -#define NRFX_SPIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM134_ENABLED -#define NRFX_SPIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM135_ENABLED -#define NRFX_SPIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM136_ENABLED -#define NRFX_SPIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM137_ENABLED -#define NRFX_SPIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS120_ENABLED -#define NRFX_SPIS120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS130_ENABLED -#define NRFX_SPIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS131_ENABLED -#define NRFX_SPIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS132_ENABLED -#define NRFX_SPIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS133_ENABLED -#define NRFX_SPIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS134_ENABLED -#define NRFX_SPIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS135_ENABLED -#define NRFX_SPIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS136_ENABLED -#define NRFX_SPIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS137_ENABLED -#define NRFX_SPIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER120_ENABLED -#define NRFX_TIMER120_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER121_ENABLED -#define NRFX_TIMER121_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER130_ENABLED -#define NRFX_TIMER130_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER131_ENABLED -#define NRFX_TIMER131_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER132_ENABLED -#define NRFX_TIMER132_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER133_ENABLED -#define NRFX_TIMER133_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER134_ENABLED -#define NRFX_TIMER134_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER135_ENABLED -#define NRFX_TIMER135_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER136_ENABLED -#define NRFX_TIMER136_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER137_ENABLED -#define NRFX_TIMER137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM130_ENABLED -#define NRFX_TWIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM131_ENABLED -#define NRFX_TWIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM132_ENABLED -#define NRFX_TWIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM133_ENABLED -#define NRFX_TWIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM134_ENABLED -#define NRFX_TWIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM135_ENABLED -#define NRFX_TWIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM136_ENABLED -#define NRFX_TWIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM137_ENABLED -#define NRFX_TWIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS130_ENABLED -#define NRFX_TWIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS131_ENABLED -#define NRFX_TWIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS132_ENABLED -#define NRFX_TWIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS133_ENABLED -#define NRFX_TWIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS134_ENABLED -#define NRFX_TWIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS135_ENABLED -#define NRFX_TWIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS136_ENABLED -#define NRFX_TWIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS137_ENABLED -#define NRFX_TWIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for configuring GPIO pins is - * removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for configuring PSEL registers - * is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED -#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE120_ENABLED -#define NRFX_UARTE120_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE130_ENABLED -#define NRFX_UARTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE131_ENABLED -#define NRFX_UARTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE132_ENABLED -#define NRFX_UARTE132_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE133_ENABLED -#define NRFX_UARTE133_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE134_ENABLED -#define NRFX_UARTE134_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE135_ENABLED -#define NRFX_UARTE135_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE136_ENABLED -#define NRFX_UARTE136_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE137_ENABLED -#define NRFX_UARTE137_ENABLED 0 -#endif - -/** - * @brief NRFX_VEVIF_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_VEVIF_ENABLED -#define NRFX_VEVIF_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT131_ENABLED -#define NRFX_WDT131_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT132_ENABLED -#define NRFX_WDT132_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54H20_FLPR_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_ppr.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_ppr.h deleted file mode 100644 index 35716978f2809..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_ppr.h +++ /dev/null @@ -1,1884 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54H20_PPR_H__ -#define NRFX_CONFIG_NRF54H20_PPR_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 0 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COREDEP_VPR_LEGACY - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COREDEP_VPR_LEGACY -#define NRFX_COREDEP_VPR_LEGACY 0 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000030 -#endif - -/** - * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e -#endif - -/** - * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 -#endif - -/** - * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 -#endif - -/** - * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 -#endif - -/** - * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 -#endif - -/** - * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df -#endif - -/** - * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf -#endif - -/** - * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU130_ENABLED -#define NRFX_EGU130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE130_ENABLED -#define NRFX_GPIOTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 2 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000c0 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_MVDMA_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA_ENABLED -#define NRFX_MVDMA_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA120_ENABLED -#define NRFX_MVDMA120_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_6_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_6_ENABLED -#define NRFX_PRS_BOX_6_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_7_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_7_ENABLED -#define NRFX_PRS_BOX_7_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_8_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_8_ENABLED -#define NRFX_PRS_BOX_8_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_9_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_9_ENABLED -#define NRFX_PRS_BOX_9_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM120_ENABLED -#define NRFX_PWM120_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM130_ENABLED -#define NRFX_PWM130_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM131_ENABLED -#define NRFX_PWM131_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM132_ENABLED -#define NRFX_PWM132_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM133_ENABLED -#define NRFX_PWM133_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC130_ENABLED -#define NRFX_QDEC130_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC131_ENABLED -#define NRFX_QDEC131_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC130_ENABLED -#define NRFX_RTC130_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC131_ENABLED -#define NRFX_RTC131_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM120_ENABLED -#define NRFX_SPIM120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM121_ENABLED -#define NRFX_SPIM121_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM130_ENABLED -#define NRFX_SPIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM131_ENABLED -#define NRFX_SPIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM132_ENABLED -#define NRFX_SPIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM133_ENABLED -#define NRFX_SPIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM134_ENABLED -#define NRFX_SPIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM135_ENABLED -#define NRFX_SPIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM136_ENABLED -#define NRFX_SPIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM137_ENABLED -#define NRFX_SPIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS120_ENABLED -#define NRFX_SPIS120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS130_ENABLED -#define NRFX_SPIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS131_ENABLED -#define NRFX_SPIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS132_ENABLED -#define NRFX_SPIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS133_ENABLED -#define NRFX_SPIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS134_ENABLED -#define NRFX_SPIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS135_ENABLED -#define NRFX_SPIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS136_ENABLED -#define NRFX_SPIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS137_ENABLED -#define NRFX_SPIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER120_ENABLED -#define NRFX_TIMER120_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER121_ENABLED -#define NRFX_TIMER121_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER130_ENABLED -#define NRFX_TIMER130_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER131_ENABLED -#define NRFX_TIMER131_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER132_ENABLED -#define NRFX_TIMER132_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER133_ENABLED -#define NRFX_TIMER133_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER134_ENABLED -#define NRFX_TIMER134_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER135_ENABLED -#define NRFX_TIMER135_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER136_ENABLED -#define NRFX_TIMER136_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER137_ENABLED -#define NRFX_TIMER137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM130_ENABLED -#define NRFX_TWIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM131_ENABLED -#define NRFX_TWIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM132_ENABLED -#define NRFX_TWIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM133_ENABLED -#define NRFX_TWIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM134_ENABLED -#define NRFX_TWIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM135_ENABLED -#define NRFX_TWIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM136_ENABLED -#define NRFX_TWIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM137_ENABLED -#define NRFX_TWIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance - * would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS130_ENABLED -#define NRFX_TWIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS131_ENABLED -#define NRFX_TWIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS132_ENABLED -#define NRFX_TWIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS133_ENABLED -#define NRFX_TWIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS134_ENABLED -#define NRFX_TWIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS135_ENABLED -#define NRFX_TWIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS136_ENABLED -#define NRFX_TWIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS137_ENABLED -#define NRFX_TWIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for - * configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for - * configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking - * of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED -#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE120_ENABLED -#define NRFX_UARTE120_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE130_ENABLED -#define NRFX_UARTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE131_ENABLED -#define NRFX_UARTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE132_ENABLED -#define NRFX_UARTE132_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE133_ENABLED -#define NRFX_UARTE133_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE134_ENABLED -#define NRFX_UARTE134_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE135_ENABLED -#define NRFX_UARTE135_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE136_ENABLED -#define NRFX_UARTE136_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE137_ENABLED -#define NRFX_UARTE137_ENABLED 0 -#endif - -/** - * @brief NRFX_VEVIF_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_VEVIF_ENABLED -#define NRFX_VEVIF_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT131_ENABLED -#define NRFX_WDT131_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT132_ENABLED -#define NRFX_WDT132_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54H20_PPR_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_radiocore.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_radiocore.h deleted file mode 100644 index 5847cace47e89..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_radiocore.h +++ /dev/null @@ -1,2010 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54H20_RADIOCORE_H__ -#define NRFX_CONFIG_NRF54H20_RADIOCORE_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_BELLBOARD_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD_ENABLED -#define NRFX_BELLBOARD_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_BELLBOARD0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD0_ENABLED -#define NRFX_BELLBOARD0_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD1_ENABLED -#define NRFX_BELLBOARD1_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD2_ENABLED -#define NRFX_BELLBOARD2_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD3_ENABLED -#define NRFX_BELLBOARD3_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e -#endif - -/** - * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 -#endif - -/** - * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 -#endif - -/** - * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 -#endif - -/** - * @brief NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000f -#endif - -/** - * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 -#endif - -/** - * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df -#endif - -/** - * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf -#endif - -/** - * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU020_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU020_ENABLED -#define NRFX_EGU020_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU130_ENABLED -#define NRFX_EGU130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE130_ENABLED -#define NRFX_GPIOTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x00000f00 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000030 -#endif - -/** - * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000c0 -#endif - -/** - * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_MVDMA_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA_ENABLED -#define NRFX_MVDMA_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA120_ENABLED -#define NRFX_MVDMA120_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_6_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_6_ENABLED -#define NRFX_PRS_BOX_6_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_7_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_7_ENABLED -#define NRFX_PRS_BOX_7_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_8_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_8_ENABLED -#define NRFX_PRS_BOX_8_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_9_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_9_ENABLED -#define NRFX_PRS_BOX_9_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM120_ENABLED -#define NRFX_PWM120_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM130_ENABLED -#define NRFX_PWM130_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM131_ENABLED -#define NRFX_PWM131_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM132_ENABLED -#define NRFX_PWM132_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM133_ENABLED -#define NRFX_PWM133_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC130_ENABLED -#define NRFX_QDEC130_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC131_ENABLED -#define NRFX_QDEC131_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC130_ENABLED -#define NRFX_RTC130_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC131_ENABLED -#define NRFX_RTC131_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM120_ENABLED -#define NRFX_SPIM120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM121_ENABLED -#define NRFX_SPIM121_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM130_ENABLED -#define NRFX_SPIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM131_ENABLED -#define NRFX_SPIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM132_ENABLED -#define NRFX_SPIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM133_ENABLED -#define NRFX_SPIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM134_ENABLED -#define NRFX_SPIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM135_ENABLED -#define NRFX_SPIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM136_ENABLED -#define NRFX_SPIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM137_ENABLED -#define NRFX_SPIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS120_ENABLED -#define NRFX_SPIS120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS130_ENABLED -#define NRFX_SPIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS131_ENABLED -#define NRFX_SPIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS132_ENABLED -#define NRFX_SPIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS133_ENABLED -#define NRFX_SPIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS134_ENABLED -#define NRFX_SPIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS135_ENABLED -#define NRFX_SPIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS136_ENABLED -#define NRFX_SPIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS137_ENABLED -#define NRFX_SPIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER020_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER020_ENABLED -#define NRFX_TIMER020_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER021_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER021_ENABLED -#define NRFX_TIMER021_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER022_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER022_ENABLED -#define NRFX_TIMER022_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER120_ENABLED -#define NRFX_TIMER120_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER121_ENABLED -#define NRFX_TIMER121_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER130_ENABLED -#define NRFX_TIMER130_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER131_ENABLED -#define NRFX_TIMER131_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER132_ENABLED -#define NRFX_TIMER132_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER133_ENABLED -#define NRFX_TIMER133_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER134_ENABLED -#define NRFX_TIMER134_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER135_ENABLED -#define NRFX_TIMER135_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER136_ENABLED -#define NRFX_TIMER136_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER137_ENABLED -#define NRFX_TIMER137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM130_ENABLED -#define NRFX_TWIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM131_ENABLED -#define NRFX_TWIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM132_ENABLED -#define NRFX_TWIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM133_ENABLED -#define NRFX_TWIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM134_ENABLED -#define NRFX_TWIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM135_ENABLED -#define NRFX_TWIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM136_ENABLED -#define NRFX_TWIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM137_ENABLED -#define NRFX_TWIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance - * would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS130_ENABLED -#define NRFX_TWIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS131_ENABLED -#define NRFX_TWIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS132_ENABLED -#define NRFX_TWIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS133_ENABLED -#define NRFX_TWIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS134_ENABLED -#define NRFX_TWIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS135_ENABLED -#define NRFX_TWIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS136_ENABLED -#define NRFX_TWIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS137_ENABLED -#define NRFX_TWIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for - * configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for - * configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking - * of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED -#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE120_ENABLED -#define NRFX_UARTE120_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE130_ENABLED -#define NRFX_UARTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE131_ENABLED -#define NRFX_UARTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE132_ENABLED -#define NRFX_UARTE132_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE133_ENABLED -#define NRFX_UARTE133_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE134_ENABLED -#define NRFX_UARTE134_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE135_ENABLED -#define NRFX_UARTE135_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE136_ENABLED -#define NRFX_UARTE136_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE137_ENABLED -#define NRFX_UARTE137_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT010_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT010_ENABLED -#define NRFX_WDT010_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT011_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT011_ENABLED -#define NRFX_WDT011_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT131_ENABLED -#define NRFX_WDT131_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT132_ENABLED -#define NRFX_WDT132_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54H20_RADIOCORE_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l05_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l05_application.h deleted file mode 100644 index 503405b49f6dc..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54l05_application.h +++ /dev/null @@ -1,1775 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54L05_APPLICATION_H__ -#define NRFX_CONFIG_NRF54L05_APPLICATION_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI00_ENABLED -#define NRFX_DPPI00_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI10_ENABLED -#define NRFX_DPPI10_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI20_ENABLED -#define NRFX_DPPI20_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI30_ENABLED -#define NRFX_DPPI30_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU10_ENABLED -#define NRFX_EGU10_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU20_ENABLED -#define NRFX_EGU20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE20_ENABLED -#define NRFX_GPIOTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE30_ENABLED -#define NRFX_GPIOTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 8 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x00000f0f -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S20_ENABLED -#define NRFX_I2S20_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM20_ENABLED -#define NRFX_PDM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM21_ENABLED -#define NRFX_PDM21_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPIB_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_ENABLED -#define NRFX_PPIB_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_CONFIG_LOG_ENABLED -#define NRFX_PPIB_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPIB_CONFIG_LOG_LEVEL -#define NRFX_PPIB_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PPIB00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB00_ENABLED -#define NRFX_PPIB00_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB01_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB01_ENABLED -#define NRFX_PPIB01_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB10_ENABLED -#define NRFX_PPIB10_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB11_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB11_ENABLED -#define NRFX_PPIB11_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB20_ENABLED -#define NRFX_PPIB20_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB21_ENABLED -#define NRFX_PPIB21_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB22_ENABLED -#define NRFX_PPIB22_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB30_ENABLED -#define NRFX_PPIB30_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM20_ENABLED -#define NRFX_PWM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM21_ENABLED -#define NRFX_PWM21_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM22_ENABLED -#define NRFX_PWM22_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC20_ENABLED -#define NRFX_QDEC20_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC21_ENABLED -#define NRFX_QDEC21_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_ENABLED -#define NRFX_RRAMC_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_ENABLED -#define NRFX_RRAMC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_LEVEL -#define NRFX_RRAMC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC10_ENABLED -#define NRFX_RTC10_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC30_ENABLED -#define NRFX_RTC30_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM00_ENABLED -#define NRFX_SPIM00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM20_ENABLED -#define NRFX_SPIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM21_ENABLED -#define NRFX_SPIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM22_ENABLED -#define NRFX_SPIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM30_ENABLED -#define NRFX_SPIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS00_ENABLED -#define NRFX_SPIS00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS20_ENABLED -#define NRFX_SPIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS21_ENABLED -#define NRFX_SPIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS22_ENABLED -#define NRFX_SPIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS30_ENABLED -#define NRFX_SPIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER00_ENABLED -#define NRFX_TIMER00_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER10_ENABLED -#define NRFX_TIMER10_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER20_ENABLED -#define NRFX_TIMER20_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER21_ENABLED -#define NRFX_TIMER21_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER22_ENABLED -#define NRFX_TIMER22_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER23_ENABLED -#define NRFX_TIMER23_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER24_ENABLED -#define NRFX_TIMER24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM20_ENABLED -#define NRFX_TWIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM21_ENABLED -#define NRFX_TWIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM22_ENABLED -#define NRFX_TWIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM30_ENABLED -#define NRFX_TWIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * Assume that any instance would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS20_ENABLED -#define NRFX_TWIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS21_ENABLED -#define NRFX_TWIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS22_ENABLED -#define NRFX_TWIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS30_ENABLED -#define NRFX_TWIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * If enabled, support for configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * If enabled, support for configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE00_ENABLED -#define NRFX_UARTE00_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE20_ENABLED -#define NRFX_UARTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE21_ENABLED -#define NRFX_UARTE21_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE22_ENABLED -#define NRFX_UARTE22_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE30_ENABLED -#define NRFX_UARTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT30_ENABLED -#define NRFX_WDT30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT31_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT31_ENABLED -#define NRFX_WDT31_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54L05_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l05_flpr.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l05_flpr.h deleted file mode 100644 index 4d83d5cba2287..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54l05_flpr.h +++ /dev/null @@ -1,1784 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54L05_FLPR_H__ -#define NRFX_CONFIG_NRF54L05_FLPR_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 0 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COREDEP_VPR_LEGACY - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COREDEP_VPR_LEGACY -#define NRFX_COREDEP_VPR_LEGACY 0 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI00_ENABLED -#define NRFX_DPPI00_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI10_ENABLED -#define NRFX_DPPI10_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI20_ENABLED -#define NRFX_DPPI20_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI30_ENABLED -#define NRFX_DPPI30_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU10_ENABLED -#define NRFX_EGU10_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU20_ENABLED -#define NRFX_EGU20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE20_ENABLED -#define NRFX_GPIOTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE30_ENABLED -#define NRFX_GPIOTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S20_ENABLED -#define NRFX_I2S20_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM20_ENABLED -#define NRFX_PDM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM21_ENABLED -#define NRFX_PDM21_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPIB_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_ENABLED -#define NRFX_PPIB_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_CONFIG_LOG_ENABLED -#define NRFX_PPIB_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPIB_CONFIG_LOG_LEVEL -#define NRFX_PPIB_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PPIB00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB00_ENABLED -#define NRFX_PPIB00_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB01_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB01_ENABLED -#define NRFX_PPIB01_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB10_ENABLED -#define NRFX_PPIB10_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB11_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB11_ENABLED -#define NRFX_PPIB11_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB20_ENABLED -#define NRFX_PPIB20_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB21_ENABLED -#define NRFX_PPIB21_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB22_ENABLED -#define NRFX_PPIB22_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB30_ENABLED -#define NRFX_PPIB30_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM20_ENABLED -#define NRFX_PWM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM21_ENABLED -#define NRFX_PWM21_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM22_ENABLED -#define NRFX_PWM22_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC20_ENABLED -#define NRFX_QDEC20_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC21_ENABLED -#define NRFX_QDEC21_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_ENABLED -#define NRFX_RRAMC_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_ENABLED -#define NRFX_RRAMC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_LEVEL -#define NRFX_RRAMC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC10_ENABLED -#define NRFX_RTC10_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC30_ENABLED -#define NRFX_RTC30_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM00_ENABLED -#define NRFX_SPIM00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM20_ENABLED -#define NRFX_SPIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM21_ENABLED -#define NRFX_SPIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM22_ENABLED -#define NRFX_SPIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM30_ENABLED -#define NRFX_SPIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS00_ENABLED -#define NRFX_SPIS00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS20_ENABLED -#define NRFX_SPIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS21_ENABLED -#define NRFX_SPIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS22_ENABLED -#define NRFX_SPIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS30_ENABLED -#define NRFX_SPIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER00_ENABLED -#define NRFX_TIMER00_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER10_ENABLED -#define NRFX_TIMER10_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER20_ENABLED -#define NRFX_TIMER20_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER21_ENABLED -#define NRFX_TIMER21_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER22_ENABLED -#define NRFX_TIMER22_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER23_ENABLED -#define NRFX_TIMER23_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER24_ENABLED -#define NRFX_TIMER24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM20_ENABLED -#define NRFX_TWIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM21_ENABLED -#define NRFX_TWIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM22_ENABLED -#define NRFX_TWIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM30_ENABLED -#define NRFX_TWIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * Assume that any instance would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS20_ENABLED -#define NRFX_TWIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS21_ENABLED -#define NRFX_TWIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS22_ENABLED -#define NRFX_TWIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS30_ENABLED -#define NRFX_TWIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * If enabled, support for configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * If enabled, support for configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE00_ENABLED -#define NRFX_UARTE00_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE20_ENABLED -#define NRFX_UARTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE21_ENABLED -#define NRFX_UARTE21_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE22_ENABLED -#define NRFX_UARTE22_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE30_ENABLED -#define NRFX_UARTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_VEVIF_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_VEVIF_ENABLED -#define NRFX_VEVIF_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT30_ENABLED -#define NRFX_WDT30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT31_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT31_ENABLED -#define NRFX_WDT31_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54L05_FLPR_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l10_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l10_application.h deleted file mode 100644 index ab781f507e549..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54l10_application.h +++ /dev/null @@ -1,1775 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54L10_APPLICATION_H__ -#define NRFX_CONFIG_NRF54L10_APPLICATION_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI00_ENABLED -#define NRFX_DPPI00_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI10_ENABLED -#define NRFX_DPPI10_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI20_ENABLED -#define NRFX_DPPI20_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI30_ENABLED -#define NRFX_DPPI30_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU10_ENABLED -#define NRFX_EGU10_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU20_ENABLED -#define NRFX_EGU20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE20_ENABLED -#define NRFX_GPIOTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE30_ENABLED -#define NRFX_GPIOTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 8 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x00000f0f -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S20_ENABLED -#define NRFX_I2S20_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM20_ENABLED -#define NRFX_PDM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM21_ENABLED -#define NRFX_PDM21_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPIB_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_ENABLED -#define NRFX_PPIB_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_CONFIG_LOG_ENABLED -#define NRFX_PPIB_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPIB_CONFIG_LOG_LEVEL -#define NRFX_PPIB_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PPIB00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB00_ENABLED -#define NRFX_PPIB00_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB01_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB01_ENABLED -#define NRFX_PPIB01_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB10_ENABLED -#define NRFX_PPIB10_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB11_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB11_ENABLED -#define NRFX_PPIB11_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB20_ENABLED -#define NRFX_PPIB20_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB21_ENABLED -#define NRFX_PPIB21_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB22_ENABLED -#define NRFX_PPIB22_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB30_ENABLED -#define NRFX_PPIB30_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM20_ENABLED -#define NRFX_PWM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM21_ENABLED -#define NRFX_PWM21_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM22_ENABLED -#define NRFX_PWM22_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC20_ENABLED -#define NRFX_QDEC20_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC21_ENABLED -#define NRFX_QDEC21_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_ENABLED -#define NRFX_RRAMC_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_ENABLED -#define NRFX_RRAMC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_LEVEL -#define NRFX_RRAMC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC10_ENABLED -#define NRFX_RTC10_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC30_ENABLED -#define NRFX_RTC30_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM00_ENABLED -#define NRFX_SPIM00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM20_ENABLED -#define NRFX_SPIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM21_ENABLED -#define NRFX_SPIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM22_ENABLED -#define NRFX_SPIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM30_ENABLED -#define NRFX_SPIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS00_ENABLED -#define NRFX_SPIS00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS20_ENABLED -#define NRFX_SPIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS21_ENABLED -#define NRFX_SPIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS22_ENABLED -#define NRFX_SPIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS30_ENABLED -#define NRFX_SPIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER00_ENABLED -#define NRFX_TIMER00_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER10_ENABLED -#define NRFX_TIMER10_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER20_ENABLED -#define NRFX_TIMER20_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER21_ENABLED -#define NRFX_TIMER21_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER22_ENABLED -#define NRFX_TIMER22_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER23_ENABLED -#define NRFX_TIMER23_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER24_ENABLED -#define NRFX_TIMER24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM20_ENABLED -#define NRFX_TWIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM21_ENABLED -#define NRFX_TWIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM22_ENABLED -#define NRFX_TWIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM30_ENABLED -#define NRFX_TWIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * Assume that any instance would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS20_ENABLED -#define NRFX_TWIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS21_ENABLED -#define NRFX_TWIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS22_ENABLED -#define NRFX_TWIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS30_ENABLED -#define NRFX_TWIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * If enabled, support for configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * If enabled, support for configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE00_ENABLED -#define NRFX_UARTE00_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE20_ENABLED -#define NRFX_UARTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE21_ENABLED -#define NRFX_UARTE21_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE22_ENABLED -#define NRFX_UARTE22_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE30_ENABLED -#define NRFX_UARTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT30_ENABLED -#define NRFX_WDT30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT31_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT31_ENABLED -#define NRFX_WDT31_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54L10_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l10_flpr.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l10_flpr.h deleted file mode 100644 index 784cb0435a18d..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54l10_flpr.h +++ /dev/null @@ -1,1784 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54L10_FLPR_H__ -#define NRFX_CONFIG_NRF54L10_FLPR_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 0 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COREDEP_VPR_LEGACY - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COREDEP_VPR_LEGACY -#define NRFX_COREDEP_VPR_LEGACY 0 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI00_ENABLED -#define NRFX_DPPI00_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI10_ENABLED -#define NRFX_DPPI10_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI20_ENABLED -#define NRFX_DPPI20_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI30_ENABLED -#define NRFX_DPPI30_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU10_ENABLED -#define NRFX_EGU10_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU20_ENABLED -#define NRFX_EGU20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE20_ENABLED -#define NRFX_GPIOTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE30_ENABLED -#define NRFX_GPIOTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S20_ENABLED -#define NRFX_I2S20_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM20_ENABLED -#define NRFX_PDM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM21_ENABLED -#define NRFX_PDM21_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPIB_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_ENABLED -#define NRFX_PPIB_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_CONFIG_LOG_ENABLED -#define NRFX_PPIB_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPIB_CONFIG_LOG_LEVEL -#define NRFX_PPIB_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PPIB00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB00_ENABLED -#define NRFX_PPIB00_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB01_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB01_ENABLED -#define NRFX_PPIB01_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB10_ENABLED -#define NRFX_PPIB10_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB11_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB11_ENABLED -#define NRFX_PPIB11_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB20_ENABLED -#define NRFX_PPIB20_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB21_ENABLED -#define NRFX_PPIB21_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB22_ENABLED -#define NRFX_PPIB22_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB30_ENABLED -#define NRFX_PPIB30_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM20_ENABLED -#define NRFX_PWM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM21_ENABLED -#define NRFX_PWM21_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM22_ENABLED -#define NRFX_PWM22_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC20_ENABLED -#define NRFX_QDEC20_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC21_ENABLED -#define NRFX_QDEC21_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_ENABLED -#define NRFX_RRAMC_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_ENABLED -#define NRFX_RRAMC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_LEVEL -#define NRFX_RRAMC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC10_ENABLED -#define NRFX_RTC10_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC30_ENABLED -#define NRFX_RTC30_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM00_ENABLED -#define NRFX_SPIM00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM20_ENABLED -#define NRFX_SPIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM21_ENABLED -#define NRFX_SPIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM22_ENABLED -#define NRFX_SPIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM30_ENABLED -#define NRFX_SPIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS00_ENABLED -#define NRFX_SPIS00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS20_ENABLED -#define NRFX_SPIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS21_ENABLED -#define NRFX_SPIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS22_ENABLED -#define NRFX_SPIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS30_ENABLED -#define NRFX_SPIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER00_ENABLED -#define NRFX_TIMER00_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER10_ENABLED -#define NRFX_TIMER10_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER20_ENABLED -#define NRFX_TIMER20_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER21_ENABLED -#define NRFX_TIMER21_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER22_ENABLED -#define NRFX_TIMER22_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER23_ENABLED -#define NRFX_TIMER23_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER24_ENABLED -#define NRFX_TIMER24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM20_ENABLED -#define NRFX_TWIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM21_ENABLED -#define NRFX_TWIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM22_ENABLED -#define NRFX_TWIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM30_ENABLED -#define NRFX_TWIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * Assume that any instance would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS20_ENABLED -#define NRFX_TWIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS21_ENABLED -#define NRFX_TWIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS22_ENABLED -#define NRFX_TWIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS30_ENABLED -#define NRFX_TWIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * If enabled, support for configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * If enabled, support for configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE00_ENABLED -#define NRFX_UARTE00_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE20_ENABLED -#define NRFX_UARTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE21_ENABLED -#define NRFX_UARTE21_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE22_ENABLED -#define NRFX_UARTE22_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE30_ENABLED -#define NRFX_UARTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_VEVIF_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_VEVIF_ENABLED -#define NRFX_VEVIF_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT30_ENABLED -#define NRFX_WDT30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT31_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT31_ENABLED -#define NRFX_WDT31_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54L10_FLPR_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_application.h deleted file mode 100644 index cf49a5f4fa6ce..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_application.h +++ /dev/null @@ -1,1775 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54L15_APPLICATION_H__ -#define NRFX_CONFIG_NRF54L15_APPLICATION_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI00_ENABLED -#define NRFX_DPPI00_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI10_ENABLED -#define NRFX_DPPI10_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI20_ENABLED -#define NRFX_DPPI20_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI30_ENABLED -#define NRFX_DPPI30_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU10_ENABLED -#define NRFX_EGU10_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU20_ENABLED -#define NRFX_EGU20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE20_ENABLED -#define NRFX_GPIOTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE30_ENABLED -#define NRFX_GPIOTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 8 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x00000f0f -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S20_ENABLED -#define NRFX_I2S20_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM20_ENABLED -#define NRFX_PDM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM21_ENABLED -#define NRFX_PDM21_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPIB_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_ENABLED -#define NRFX_PPIB_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_CONFIG_LOG_ENABLED -#define NRFX_PPIB_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPIB_CONFIG_LOG_LEVEL -#define NRFX_PPIB_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PPIB00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB00_ENABLED -#define NRFX_PPIB00_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB01_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB01_ENABLED -#define NRFX_PPIB01_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB10_ENABLED -#define NRFX_PPIB10_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB11_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB11_ENABLED -#define NRFX_PPIB11_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB20_ENABLED -#define NRFX_PPIB20_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB21_ENABLED -#define NRFX_PPIB21_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB22_ENABLED -#define NRFX_PPIB22_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB30_ENABLED -#define NRFX_PPIB30_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM20_ENABLED -#define NRFX_PWM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM21_ENABLED -#define NRFX_PWM21_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM22_ENABLED -#define NRFX_PWM22_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC20_ENABLED -#define NRFX_QDEC20_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC21_ENABLED -#define NRFX_QDEC21_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_ENABLED -#define NRFX_RRAMC_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_ENABLED -#define NRFX_RRAMC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_LEVEL -#define NRFX_RRAMC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC10_ENABLED -#define NRFX_RTC10_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC30_ENABLED -#define NRFX_RTC30_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM00_ENABLED -#define NRFX_SPIM00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM20_ENABLED -#define NRFX_SPIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM21_ENABLED -#define NRFX_SPIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM22_ENABLED -#define NRFX_SPIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM30_ENABLED -#define NRFX_SPIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS00_ENABLED -#define NRFX_SPIS00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS20_ENABLED -#define NRFX_SPIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS21_ENABLED -#define NRFX_SPIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS22_ENABLED -#define NRFX_SPIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS30_ENABLED -#define NRFX_SPIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER00_ENABLED -#define NRFX_TIMER00_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER10_ENABLED -#define NRFX_TIMER10_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER20_ENABLED -#define NRFX_TIMER20_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER21_ENABLED -#define NRFX_TIMER21_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER22_ENABLED -#define NRFX_TIMER22_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER23_ENABLED -#define NRFX_TIMER23_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER24_ENABLED -#define NRFX_TIMER24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM20_ENABLED -#define NRFX_TWIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM21_ENABLED -#define NRFX_TWIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM22_ENABLED -#define NRFX_TWIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM30_ENABLED -#define NRFX_TWIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * Assume that any instance would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS20_ENABLED -#define NRFX_TWIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS21_ENABLED -#define NRFX_TWIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS22_ENABLED -#define NRFX_TWIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS30_ENABLED -#define NRFX_TWIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * If enabled, support for configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * If enabled, support for configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE00_ENABLED -#define NRFX_UARTE00_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE20_ENABLED -#define NRFX_UARTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE21_ENABLED -#define NRFX_UARTE21_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE22_ENABLED -#define NRFX_UARTE22_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE30_ENABLED -#define NRFX_UARTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT30_ENABLED -#define NRFX_WDT30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT31_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT31_ENABLED -#define NRFX_WDT31_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54L15_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_flpr.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_flpr.h deleted file mode 100644 index 4d5069383378e..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_flpr.h +++ /dev/null @@ -1,1784 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54L15_FLPR_H__ -#define NRFX_CONFIG_NRF54L15_FLPR_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 0 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COREDEP_VPR_LEGACY - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COREDEP_VPR_LEGACY -#define NRFX_COREDEP_VPR_LEGACY 0 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI00_ENABLED -#define NRFX_DPPI00_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI10_ENABLED -#define NRFX_DPPI10_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI20_ENABLED -#define NRFX_DPPI20_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI30_ENABLED -#define NRFX_DPPI30_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU10_ENABLED -#define NRFX_EGU10_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU20_ENABLED -#define NRFX_EGU20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE20_ENABLED -#define NRFX_GPIOTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE30_ENABLED -#define NRFX_GPIOTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_CLEAR_AT_INIT - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_CLEAR_AT_INIT -#define NRFX_GRTC_CONFIG_CLEAR_AT_INIT 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S20_ENABLED -#define NRFX_I2S20_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM20_ENABLED -#define NRFX_PDM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM21_ENABLED -#define NRFX_PDM21_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PPIB_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_ENABLED -#define NRFX_PPIB_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB_CONFIG_LOG_ENABLED -#define NRFX_PPIB_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PPIB_CONFIG_LOG_LEVEL -#define NRFX_PPIB_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PPIB00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB00_ENABLED -#define NRFX_PPIB00_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB01_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB01_ENABLED -#define NRFX_PPIB01_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB10_ENABLED -#define NRFX_PPIB10_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB11_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB11_ENABLED -#define NRFX_PPIB11_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB20_ENABLED -#define NRFX_PPIB20_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB21_ENABLED -#define NRFX_PPIB21_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB22_ENABLED -#define NRFX_PPIB22_ENABLED 0 -#endif - -/** - * @brief NRFX_PPIB30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PPIB30_ENABLED -#define NRFX_PPIB30_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM20_ENABLED -#define NRFX_PWM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM21_ENABLED -#define NRFX_PWM21_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM22_ENABLED -#define NRFX_PWM22_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC20_ENABLED -#define NRFX_QDEC20_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC21_ENABLED -#define NRFX_QDEC21_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_ENABLED -#define NRFX_RRAMC_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_ENABLED -#define NRFX_RRAMC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_LEVEL -#define NRFX_RRAMC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC10_ENABLED -#define NRFX_RTC10_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC30_ENABLED -#define NRFX_RTC30_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM00_ENABLED -#define NRFX_SPIM00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM20_ENABLED -#define NRFX_SPIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM21_ENABLED -#define NRFX_SPIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM22_ENABLED -#define NRFX_SPIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM30_ENABLED -#define NRFX_SPIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS00_ENABLED -#define NRFX_SPIS00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS20_ENABLED -#define NRFX_SPIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS21_ENABLED -#define NRFX_SPIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS22_ENABLED -#define NRFX_SPIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS30_ENABLED -#define NRFX_SPIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER00_ENABLED -#define NRFX_TIMER00_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER10_ENABLED -#define NRFX_TIMER10_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER20_ENABLED -#define NRFX_TIMER20_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER21_ENABLED -#define NRFX_TIMER21_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER22_ENABLED -#define NRFX_TIMER22_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER23_ENABLED -#define NRFX_TIMER23_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER24_ENABLED -#define NRFX_TIMER24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM20_ENABLED -#define NRFX_TWIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM21_ENABLED -#define NRFX_TWIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM22_ENABLED -#define NRFX_TWIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM30_ENABLED -#define NRFX_TWIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * Assume that any instance would be initialized only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS20_ENABLED -#define NRFX_TWIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS21_ENABLED -#define NRFX_TWIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS22_ENABLED -#define NRFX_TWIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS30_ENABLED -#define NRFX_TWIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * If enabled, support for configuring GPIO pins is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * If enabled, support for configuring PSEL registers is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE00_ENABLED -#define NRFX_UARTE00_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE20_ENABLED -#define NRFX_UARTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE21_ENABLED -#define NRFX_UARTE21_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE22_ENABLED -#define NRFX_UARTE22_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE30_ENABLED -#define NRFX_UARTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_VEVIF_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_VEVIF_ENABLED -#define NRFX_VEVIF_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT30_ENABLED -#define NRFX_WDT30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT31_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT31_ENABLED -#define NRFX_WDT31_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54L15_FLPR_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l20_enga_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l20_enga_application.h deleted file mode 100644 index 91abb93393d56..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf54l20_enga_application.h +++ /dev/null @@ -1,1604 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF54L20_ENGA_APPLICATION_H__ -#define NRFX_CONFIG_NRF54L20_ENGA_APPLICATION_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 1 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED -#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU00_ENABLED -#define NRFX_EGU00_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU10_ENABLED -#define NRFX_EGU10_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU20_ENABLED -#define NRFX_EGU20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE20_ENABLED -#define NRFX_GPIOTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE30_ENABLED -#define NRFX_GPIOTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_SLEEP_ALLOWED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_SLEEP_ALLOWED -#define NRFX_GRTC_CONFIG_SLEEP_ALLOWED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 1 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 8 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x00000f0f -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_NFCT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_ENABLED -#define NRFX_NFCT_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. - * - * Integer value. Minimum: 0. Maximum: 5. - */ -#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID -#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED -#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_NFCT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL -#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM20_ENABLED -#define NRFX_PWM20_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM21_ENABLED -#define NRFX_PWM21_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM22_ENABLED -#define NRFX_PWM22_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC20_ENABLED -#define NRFX_QDEC20_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC21_ENABLED -#define NRFX_QDEC21_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_ENABLED -#define NRFX_RRAMC_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_ENABLED -#define NRFX_RRAMC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RRAMC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RRAMC_CONFIG_LOG_LEVEL -#define NRFX_RRAMC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM00_ENABLED -#define NRFX_SPIM00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM20_ENABLED -#define NRFX_SPIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM21_ENABLED -#define NRFX_SPIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM22_ENABLED -#define NRFX_SPIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM23_ENABLED -#define NRFX_SPIM23_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM24_ENABLED -#define NRFX_SPIM24_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM30_ENABLED -#define NRFX_SPIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS00_ENABLED -#define NRFX_SPIS00_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS20_ENABLED -#define NRFX_SPIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS21_ENABLED -#define NRFX_SPIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS22_ENABLED -#define NRFX_SPIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS23_ENABLED -#define NRFX_SPIS23_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS24_ENABLED -#define NRFX_SPIS24_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS30_ENABLED -#define NRFX_SPIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER00_ENABLED -#define NRFX_TIMER00_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER10_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER10_ENABLED -#define NRFX_TIMER10_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER20_ENABLED -#define NRFX_TIMER20_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER21_ENABLED -#define NRFX_TIMER21_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER22_ENABLED -#define NRFX_TIMER22_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER23_ENABLED -#define NRFX_TIMER23_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER24_ENABLED -#define NRFX_TIMER24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM20_ENABLED -#define NRFX_TWIM20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM21_ENABLED -#define NRFX_TWIM21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM22_ENABLED -#define NRFX_TWIM22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM23_ENABLED -#define NRFX_TWIM23_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM24_ENABLED -#define NRFX_TWIM24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM30_ENABLED -#define NRFX_TWIM30_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS20_ENABLED -#define NRFX_TWIS20_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS21_ENABLED -#define NRFX_TWIS21_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS22_ENABLED -#define NRFX_TWIS22_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS23_ENABLED -#define NRFX_TWIS23_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS24_ENABLED -#define NRFX_TWIS24_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS30_ENABLED -#define NRFX_TWIS30_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for configuring GPIO pins - * is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for configuring PSEL registers - * is removed from the driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE00_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE00_ENABLED -#define NRFX_UARTE00_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE20_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE20_ENABLED -#define NRFX_UARTE20_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE21_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE21_ENABLED -#define NRFX_UARTE21_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE22_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE22_ENABLED -#define NRFX_UARTE22_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE23_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE23_ENABLED -#define NRFX_UARTE23_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE24_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE24_ENABLED -#define NRFX_UARTE24_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE30_ENABLED -#define NRFX_UARTE30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT30_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT30_ENABLED -#define NRFX_WDT30_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT31_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT31_ENABLED -#define NRFX_WDT31_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF54L20_ENGA_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf91.h b/modules/hal_nordic/nrfx/nrfx_config_nrf91.h deleted file mode 100644 index b7c471789fa54..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf91.h +++ /dev/null @@ -1,1229 +0,0 @@ -/* - * Copyright (c) 2018 - 2023, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF91_H__ -#define NRFX_CONFIG_NRF91_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - -#define NRF_CLOCK NRF_PERIPH(NRF_CLOCK) -#define NRF_DPPIC NRF_PERIPH(NRF_DPPIC) -#define NRF_EGU0 NRF_PERIPH(NRF_EGU0) -#define NRF_EGU1 NRF_PERIPH(NRF_EGU1) -#define NRF_EGU2 NRF_PERIPH(NRF_EGU2) -#define NRF_EGU3 NRF_PERIPH(NRF_EGU3) -#define NRF_EGU4 NRF_PERIPH(NRF_EGU4) -#define NRF_EGU5 NRF_PERIPH(NRF_EGU5) -#define NRF_FPU NRF_PERIPH(NRF_FPU) -#define NRF_I2S NRF_PERIPH(NRF_I2S) -#define NRF_IPC NRF_PERIPH(NRF_IPC) -#define NRF_KMU NRF_PERIPH(NRF_KMU) -#define NRF_NVMC NRF_PERIPH(NRF_NVMC) -#define NRF_P0 NRF_PERIPH(NRF_P0) -#define NRF_PDM NRF_PERIPH(NRF_PDM) -#define NRF_POWER NRF_PERIPH(NRF_POWER) -#define NRF_PWM0 NRF_PERIPH(NRF_PWM0) -#define NRF_PWM1 NRF_PERIPH(NRF_PWM1) -#define NRF_PWM2 NRF_PERIPH(NRF_PWM2) -#define NRF_PWM3 NRF_PERIPH(NRF_PWM3) -#define NRF_REGULATORS NRF_PERIPH(NRF_REGULATORS) -#define NRF_RTC0 NRF_PERIPH(NRF_RTC0) -#define NRF_RTC1 NRF_PERIPH(NRF_RTC1) -#define NRF_SAADC NRF_PERIPH(NRF_SAADC) -#define NRF_SPIM0 NRF_PERIPH(NRF_SPIM0) -#define NRF_SPIM1 NRF_PERIPH(NRF_SPIM1) -#define NRF_SPIM2 NRF_PERIPH(NRF_SPIM2) -#define NRF_SPIM3 NRF_PERIPH(NRF_SPIM3) -#define NRF_SPIS0 NRF_PERIPH(NRF_SPIS0) -#define NRF_SPIS1 NRF_PERIPH(NRF_SPIS1) -#define NRF_SPIS2 NRF_PERIPH(NRF_SPIS2) -#define NRF_SPIS3 NRF_PERIPH(NRF_SPIS3) -#define NRF_TIMER0 NRF_PERIPH(NRF_TIMER0) -#define NRF_TIMER1 NRF_PERIPH(NRF_TIMER1) -#define NRF_TIMER2 NRF_PERIPH(NRF_TIMER2) -#define NRF_TWIM0 NRF_PERIPH(NRF_TWIM0) -#define NRF_TWIM1 NRF_PERIPH(NRF_TWIM1) -#define NRF_TWIM2 NRF_PERIPH(NRF_TWIM2) -#define NRF_TWIM3 NRF_PERIPH(NRF_TWIM3) -#define NRF_TWIS0 NRF_PERIPH(NRF_TWIS0) -#define NRF_TWIS1 NRF_PERIPH(NRF_TWIS1) -#define NRF_TWIS2 NRF_PERIPH(NRF_TWIS2) -#define NRF_TWIS3 NRF_PERIPH(NRF_TWIS3) -#define NRF_UARTE0 NRF_PERIPH(NRF_UARTE0) -#define NRF_UARTE1 NRF_PERIPH(NRF_UARTE1) -#define NRF_UARTE2 NRF_PERIPH(NRF_UARTE2) -#define NRF_UARTE3 NRF_PERIPH(NRF_UARTE3) -#define NRF_VMC NRF_PERIPH(NRF_VMC) -#define NRF_WDT NRF_PERIPH(NRF_WDT) - -/* - * The following section provides the name translation for peripherals with - * only one type of access available. For these peripherals, you cannot choose - * between secure and non-secure mapping. - */ -#if defined(NRF_TRUSTZONE_NONSECURE) -#define NRF_GPIOTE NRF_GPIOTE1 -#define NRF_GPIOTE1 NRF_GPIOTE1_NS -#else -#define NRF_CC_HOST_RGF NRF_CC_HOST_RGF_S -#define NRF_CRYPTOCELL NRF_CRYPTOCELL_S -#define NRF_CTRL_AP_PERI NRF_CTRL_AP_PERI_S -#define NRF_FICR NRF_FICR_S -#define NRF_GPIOTE NRF_GPIOTE0 -#define NRF_GPIOTE0 NRF_GPIOTE0_S -#define NRF_GPIOTE1 NRF_GPIOTE1_NS -#define NRF_SPU NRF_SPU_S -#define NRF_TAD NRF_TAD_S -#define NRF_UICR NRF_UICR_S -#endif - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_CLOCK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_ENABLED -#define NRFX_CLOCK_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LF_SRC - * - * Integer value. - * Supported values: - * - RC = 1 - * - XTAL = 2 - */ -#ifndef NRFX_CLOCK_CONFIG_LF_SRC -#define NRFX_CLOCK_CONFIG_LF_SRC 2 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED -#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED -#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL -#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU0_ENABLED -#define NRFX_EGU0_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU1_ENABLED -#define NRFX_EGU1_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU2_ENABLED -#define NRFX_EGU2_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU3_ENABLED -#define NRFX_EGU3_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU4_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU4_ENABLED -#define NRFX_EGU4_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU5_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_EGU5_ENABLED -#define NRFX_EGU5_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0 Maximum: 15 - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_IPC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_IPC_ENABLED -#define NRFX_IPC_ENABLED 0 -#endif - -/** - * @brief NRFX_NVMC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_NVMC_ENABLED -#define NRFX_NVMC_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_POWER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_POWER_ENABLED -#define NRFX_POWER_ENABLED 0 -#endif - -/** - * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM0_ENABLED -#define NRFX_PWM0_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM1_ENABLED -#define NRFX_PWM1_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM2_ENABLED -#define NRFX_PWM2_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_PWM3_ENABLED -#define NRFX_PWM3_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_RTC1_ENABLED -#define NRFX_RTC1_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM0_ENABLED -#define NRFX_SPIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM1_ENABLED -#define NRFX_SPIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM2_ENABLED -#define NRFX_SPIM2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIM3_ENABLED -#define NRFX_SPIM3_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS0_ENABLED -#define NRFX_SPIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS1_ENABLED -#define NRFX_SPIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS2_ENABLED -#define NRFX_SPIS2_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SPIS3_ENABLED -#define NRFX_SPIS3_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER0_ENABLED -#define NRFX_TIMER0_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER1_ENABLED -#define NRFX_TIMER1_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TIMER2_ENABLED -#define NRFX_TIMER2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM0_ENABLED -#define NRFX_TWIM0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM1_ENABLED -#define NRFX_TWIM1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM2_ENABLED -#define NRFX_TWIM2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIM3_ENABLED -#define NRFX_TWIM3_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized - * only once. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS0_ENABLED -#define NRFX_TWIS0_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS1_ENABLED -#define NRFX_TWIS1_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS2_ENABLED -#define NRFX_TWIS2_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_TWIS3_ENABLED -#define NRFX_TWIS3_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE0_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE1_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE1_ENABLED -#define NRFX_UARTE1_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE2_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE2_ENABLED -#define NRFX_UARTE2_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE3_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_UARTE3_ENABLED -#define NRFX_UARTE3_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0 Maximum: 7 - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -#endif /* NRFX_CONFIG_NRF91_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_application.h deleted file mode 100644 index 38ce622646884..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_application.h +++ /dev/null @@ -1,1964 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF9230_ENGB_APPLICATION_H__ -#define NRFX_CONFIG_NRF9230_ENGB_APPLICATION_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_BELLBOARD_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD_ENABLED -#define NRFX_BELLBOARD_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_BELLBOARD0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD0_ENABLED -#define NRFX_BELLBOARD0_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD1_ENABLED -#define NRFX_BELLBOARD1_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD2_ENABLED -#define NRFX_BELLBOARD2_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD3_ENABLED -#define NRFX_BELLBOARD3_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e -#endif - -/** - * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 -#endif - -/** - * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 -#endif - -/** - * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 -#endif - -/** - * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000f -#endif - -/** - * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 -#endif - -/** - * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df -#endif - -/** - * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf -#endif - -/** - * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU130_ENABLED -#define NRFX_EGU130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE130_ENABLED -#define NRFX_GPIOTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE131_ENABLED -#define NRFX_GPIOTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S130_ENABLED -#define NRFX_I2S130_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S131_ENABLED -#define NRFX_I2S131_ENABLED 0 -#endif - -/** - * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_MVDMA_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA_ENABLED -#define NRFX_MVDMA_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA120_ENABLED -#define NRFX_MVDMA120_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA121_ENABLED -#define NRFX_MVDMA121_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_6_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_6_ENABLED -#define NRFX_PRS_BOX_6_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_7_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_7_ENABLED -#define NRFX_PRS_BOX_7_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_8_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_8_ENABLED -#define NRFX_PRS_BOX_8_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_9_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_9_ENABLED -#define NRFX_PRS_BOX_9_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM120_ENABLED -#define NRFX_PWM120_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM130_ENABLED -#define NRFX_PWM130_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM131_ENABLED -#define NRFX_PWM131_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM132_ENABLED -#define NRFX_PWM132_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM133_ENABLED -#define NRFX_PWM133_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC130_ENABLED -#define NRFX_QDEC130_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC131_ENABLED -#define NRFX_QDEC131_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC130_ENABLED -#define NRFX_RTC130_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC131_ENABLED -#define NRFX_RTC131_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM120_ENABLED -#define NRFX_SPIM120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM121_ENABLED -#define NRFX_SPIM121_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM130_ENABLED -#define NRFX_SPIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM131_ENABLED -#define NRFX_SPIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM132_ENABLED -#define NRFX_SPIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM133_ENABLED -#define NRFX_SPIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM134_ENABLED -#define NRFX_SPIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM135_ENABLED -#define NRFX_SPIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM136_ENABLED -#define NRFX_SPIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM137_ENABLED -#define NRFX_SPIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS120_ENABLED -#define NRFX_SPIS120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS130_ENABLED -#define NRFX_SPIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS131_ENABLED -#define NRFX_SPIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS132_ENABLED -#define NRFX_SPIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS133_ENABLED -#define NRFX_SPIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS134_ENABLED -#define NRFX_SPIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS135_ENABLED -#define NRFX_SPIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS136_ENABLED -#define NRFX_SPIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS137_ENABLED -#define NRFX_SPIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER120_ENABLED -#define NRFX_TIMER120_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER121_ENABLED -#define NRFX_TIMER121_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER130_ENABLED -#define NRFX_TIMER130_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER131_ENABLED -#define NRFX_TIMER131_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER132_ENABLED -#define NRFX_TIMER132_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER133_ENABLED -#define NRFX_TIMER133_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER134_ENABLED -#define NRFX_TIMER134_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER135_ENABLED -#define NRFX_TIMER135_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER136_ENABLED -#define NRFX_TIMER136_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER137_ENABLED -#define NRFX_TIMER137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM130_ENABLED -#define NRFX_TWIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM131_ENABLED -#define NRFX_TWIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM132_ENABLED -#define NRFX_TWIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM133_ENABLED -#define NRFX_TWIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM134_ENABLED -#define NRFX_TWIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM135_ENABLED -#define NRFX_TWIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM136_ENABLED -#define NRFX_TWIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM137_ENABLED -#define NRFX_TWIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * - * Assume that any instance would be initialized only once. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS130_ENABLED -#define NRFX_TWIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS131_ENABLED -#define NRFX_TWIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS132_ENABLED -#define NRFX_TWIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS133_ENABLED -#define NRFX_TWIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS134_ENABLED -#define NRFX_TWIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS135_ENABLED -#define NRFX_TWIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS136_ENABLED -#define NRFX_TWIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS137_ENABLED -#define NRFX_TWIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * - * If enabled, support for configuring GPIO pins is removed from the driver. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * - * If enabled, support for configuring PSEL registers is removed from the driver. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED -#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE120_ENABLED -#define NRFX_UARTE120_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE130_ENABLED -#define NRFX_UARTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE131_ENABLED -#define NRFX_UARTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE132_ENABLED -#define NRFX_UARTE132_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE133_ENABLED -#define NRFX_UARTE133_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE134_ENABLED -#define NRFX_UARTE134_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE135_ENABLED -#define NRFX_UARTE135_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE136_ENABLED -#define NRFX_UARTE136_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE137_ENABLED -#define NRFX_UARTE137_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT010_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT010_ENABLED -#define NRFX_WDT010_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT011_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT011_ENABLED -#define NRFX_WDT011_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT131_ENABLED -#define NRFX_WDT131_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT132_ENABLED -#define NRFX_WDT132_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF9230_ENGB_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_ppr.h b/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_ppr.h deleted file mode 100644 index 9ae53d739e91d..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_ppr.h +++ /dev/null @@ -1,1901 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF9230_ENGB_PPR_H__ -#define NRFX_CONFIG_NRF9230_ENGB_PPR_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 0 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_COREDEP_VPR_LEGACY - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COREDEP_VPR_LEGACY -#define NRFX_COREDEP_VPR_LEGACY 0 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000030 -#endif - -/** - * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e -#endif - -/** - * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 -#endif - -/** - * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 -#endif - -/** - * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 -#endif - -/** - * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 -#endif - -/** - * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df -#endif - -/** - * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf -#endif - -/** - * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU130_ENABLED -#define NRFX_EGU130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE130_ENABLED -#define NRFX_GPIOTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE131_ENABLED -#define NRFX_GPIOTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 2 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000c0 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S130_ENABLED -#define NRFX_I2S130_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S131_ENABLED -#define NRFX_I2S131_ENABLED 0 -#endif - -/** - * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_MVDMA_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA_ENABLED -#define NRFX_MVDMA_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA120_ENABLED -#define NRFX_MVDMA120_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA121_ENABLED -#define NRFX_MVDMA121_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_6_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_6_ENABLED -#define NRFX_PRS_BOX_6_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_7_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_7_ENABLED -#define NRFX_PRS_BOX_7_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_8_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_8_ENABLED -#define NRFX_PRS_BOX_8_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_9_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_9_ENABLED -#define NRFX_PRS_BOX_9_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM120_ENABLED -#define NRFX_PWM120_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM130_ENABLED -#define NRFX_PWM130_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM131_ENABLED -#define NRFX_PWM131_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM132_ENABLED -#define NRFX_PWM132_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM133_ENABLED -#define NRFX_PWM133_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC130_ENABLED -#define NRFX_QDEC130_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC131_ENABLED -#define NRFX_QDEC131_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC130_ENABLED -#define NRFX_RTC130_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC131_ENABLED -#define NRFX_RTC131_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM120_ENABLED -#define NRFX_SPIM120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM121_ENABLED -#define NRFX_SPIM121_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM130_ENABLED -#define NRFX_SPIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM131_ENABLED -#define NRFX_SPIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM132_ENABLED -#define NRFX_SPIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM133_ENABLED -#define NRFX_SPIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM134_ENABLED -#define NRFX_SPIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM135_ENABLED -#define NRFX_SPIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM136_ENABLED -#define NRFX_SPIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM137_ENABLED -#define NRFX_SPIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS120_ENABLED -#define NRFX_SPIS120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS130_ENABLED -#define NRFX_SPIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS131_ENABLED -#define NRFX_SPIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS132_ENABLED -#define NRFX_SPIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS133_ENABLED -#define NRFX_SPIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS134_ENABLED -#define NRFX_SPIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS135_ENABLED -#define NRFX_SPIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS136_ENABLED -#define NRFX_SPIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS137_ENABLED -#define NRFX_SPIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER120_ENABLED -#define NRFX_TIMER120_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER121_ENABLED -#define NRFX_TIMER121_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER130_ENABLED -#define NRFX_TIMER130_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER131_ENABLED -#define NRFX_TIMER131_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER132_ENABLED -#define NRFX_TIMER132_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER133_ENABLED -#define NRFX_TIMER133_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER134_ENABLED -#define NRFX_TIMER134_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER135_ENABLED -#define NRFX_TIMER135_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER136_ENABLED -#define NRFX_TIMER136_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER137_ENABLED -#define NRFX_TIMER137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM130_ENABLED -#define NRFX_TWIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM131_ENABLED -#define NRFX_TWIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM132_ENABLED -#define NRFX_TWIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM133_ENABLED -#define NRFX_TWIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM134_ENABLED -#define NRFX_TWIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM135_ENABLED -#define NRFX_TWIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM136_ENABLED -#define NRFX_TWIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM137_ENABLED -#define NRFX_TWIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * - * Assume that any instance would be initialized only once. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS130_ENABLED -#define NRFX_TWIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS131_ENABLED -#define NRFX_TWIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS132_ENABLED -#define NRFX_TWIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS133_ENABLED -#define NRFX_TWIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS134_ENABLED -#define NRFX_TWIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS135_ENABLED -#define NRFX_TWIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS136_ENABLED -#define NRFX_TWIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS137_ENABLED -#define NRFX_TWIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * - * If enabled, support for configuring GPIO pins is removed from the driver. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * - * If enabled, support for configuring PSEL registers is removed from the driver. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED -#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE120_ENABLED -#define NRFX_UARTE120_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE130_ENABLED -#define NRFX_UARTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE131_ENABLED -#define NRFX_UARTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE132_ENABLED -#define NRFX_UARTE132_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE133_ENABLED -#define NRFX_UARTE133_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE134_ENABLED -#define NRFX_UARTE134_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE135_ENABLED -#define NRFX_UARTE135_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE136_ENABLED -#define NRFX_UARTE136_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE137_ENABLED -#define NRFX_UARTE137_ENABLED 0 -#endif - -/** - * @brief NRFX_VEVIF_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_VEVIF_ENABLED -#define NRFX_VEVIF_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 3. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT131_ENABLED -#define NRFX_WDT131_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT132_ENABLED -#define NRFX_WDT132_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF9230_ENGB_PPR_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_radiocore.h b/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_radiocore.h deleted file mode 100644 index 98d71e6b385be..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf9230_engb_radiocore.h +++ /dev/null @@ -1,2031 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_NRF9230_ENGB_RADIOCORE_H__ -#define NRFX_CONFIG_NRF9230_ENGB_RADIOCORE_H__ - -#ifndef NRFX_CONFIG_H__ -#error "This file should not be included directly. Include nrfx_config.h instead." -#endif - -#ifndef NRFX_RTC0_ENABLED -#define NRFX_RTC0_ENABLED 1 -#endif - -/** - * @brief NRFX_DEFAULT_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_DEFAULT_IRQ_PRIORITY -#define NRFX_DEFAULT_IRQ_PRIORITY 7 -#endif - -/** - * @brief NRFX_BELLBOARD_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD_ENABLED -#define NRFX_BELLBOARD_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_BELLBOARD0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD0_ENABLED -#define NRFX_BELLBOARD0_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD1_ENABLED -#define NRFX_BELLBOARD1_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD2_ENABLED -#define NRFX_BELLBOARD2_ENABLED 0 -#endif - -/** - * @brief NRFX_BELLBOARD3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_BELLBOARD3_ENABLED -#define NRFX_BELLBOARD3_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_ENABLED -#define NRFX_COMP_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_COMP_CONFIG_LOG_ENABLED -#define NRFX_COMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_COMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_COMP_CONFIG_LOG_LEVEL -#define NRFX_COMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_ENABLED -#define NRFX_DPPI_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED -#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_DPPI_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL -#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000f0 -#endif - -/** - * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e -#endif - -/** - * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 -#endif - -/** - * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 -#endif - -/** - * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 -#endif - -/** - * @brief NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000f -#endif - -/** - * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff -#endif - -/** - * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 -#endif - -/** - * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df -#endif - -/** - * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf -#endif - -/** - * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e -#endif - -/** - * @brief NRFX_EGU_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU_ENABLED -#define NRFX_EGU_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_EGU020_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU020_ENABLED -#define NRFX_EGU020_ENABLED 0 -#endif - -/** - * @brief NRFX_EGU130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_EGU130_ENABLED -#define NRFX_EGU130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_ENABLED -#define NRFX_GPIOTE_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS - * - * Integer value. Minimum: 0. Maximum: 15. - */ -#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS -#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 2 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL -#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_GPIOTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE130_ENABLED -#define NRFX_GPIOTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_GPIOTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GPIOTE131_ENABLED -#define NRFX_GPIOTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_ENABLED -#define NRFX_GRTC_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOEN - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOEN -#define NRFX_GRTC_CONFIG_AUTOEN 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_AUTOSTART - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_AUTOSTART -#define NRFX_GRTC_CONFIG_AUTOSTART 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS - * - * Integer value. - */ -#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS -#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK - */ -#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK -#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x00000f00 -#endif - -/** - * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED -#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_GRTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL -#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_ENABLED -#define NRFX_I2S_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S_CONFIG_LOG_ENABLED -#define NRFX_I2S_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_I2S_CONFIG_LOG_LEVEL -#define NRFX_I2S_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_I2S130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S130_ENABLED -#define NRFX_I2S130_ENABLED 0 -#endif - -/** - * @brief NRFX_I2S131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_I2S131_ENABLED -#define NRFX_I2S131_ENABLED 0 -#endif - -/** - * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000030 -#endif - -/** - * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c -#endif - -/** - * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000c0 -#endif - -/** - * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 -#endif - -/** - * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK - */ -#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK -#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 -#endif - -/** - * @brief NRFX_LPCOMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_ENABLED -#define NRFX_LPCOMP_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED -#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL -#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_MVDMA_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA_ENABLED -#define NRFX_MVDMA_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA120_ENABLED -#define NRFX_MVDMA120_ENABLED 0 -#endif - -/** - * @brief NRFX_MVDMA121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_MVDMA121_ENABLED -#define NRFX_MVDMA121_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_ENABLED -#define NRFX_PDM_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PDM_CONFIG_LOG_ENABLED -#define NRFX_PDM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PDM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PDM_CONFIG_LOG_LEVEL -#define NRFX_PDM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_ENABLED -#define NRFX_PRS_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_CONFIG_LOG_ENABLED -#define NRFX_PRS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PRS_CONFIG_LOG_LEVEL -#define NRFX_PRS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PRS_BOX_0_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_0_ENABLED -#define NRFX_PRS_BOX_0_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_1_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_1_ENABLED -#define NRFX_PRS_BOX_1_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_2_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_2_ENABLED -#define NRFX_PRS_BOX_2_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_3_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_3_ENABLED -#define NRFX_PRS_BOX_3_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_4_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_4_ENABLED -#define NRFX_PRS_BOX_4_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_5_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_5_ENABLED -#define NRFX_PRS_BOX_5_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_6_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_6_ENABLED -#define NRFX_PRS_BOX_6_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_7_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_7_ENABLED -#define NRFX_PRS_BOX_7_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_8_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_8_ENABLED -#define NRFX_PRS_BOX_8_ENABLED 0 -#endif - -/** - * @brief NRFX_PRS_BOX_9_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PRS_BOX_9_ENABLED -#define NRFX_PRS_BOX_9_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_ENABLED -#define NRFX_PWM_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM_CONFIG_LOG_ENABLED -#define NRFX_PWM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_PWM_CONFIG_LOG_LEVEL -#define NRFX_PWM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_PWM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM120_ENABLED -#define NRFX_PWM120_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM130_ENABLED -#define NRFX_PWM130_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM131_ENABLED -#define NRFX_PWM131_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM132_ENABLED -#define NRFX_PWM132_ENABLED 0 -#endif - -/** - * @brief NRFX_PWM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_PWM133_ENABLED -#define NRFX_PWM133_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_ENABLED -#define NRFX_QDEC_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED -#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL -#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_QDEC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC130_ENABLED -#define NRFX_QDEC130_ENABLED 0 -#endif - -/** - * @brief NRFX_QDEC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_QDEC131_ENABLED -#define NRFX_QDEC131_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_ENABLED -#define NRFX_RTC_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC_CONFIG_LOG_ENABLED -#define NRFX_RTC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_RTC_CONFIG_LOG_LEVEL -#define NRFX_RTC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_RTC130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC130_ENABLED -#define NRFX_RTC130_ENABLED 0 -#endif - -/** - * @brief NRFX_RTC131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_RTC131_ENABLED -#define NRFX_RTC131_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_ENABLED -#define NRFX_SAADC_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED -#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SAADC_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL -#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_ENABLED -#define NRFX_SPIM_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED -#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL -#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIM120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM120_ENABLED -#define NRFX_SPIM120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM121_ENABLED -#define NRFX_SPIM121_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM130_ENABLED -#define NRFX_SPIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM131_ENABLED -#define NRFX_SPIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM132_ENABLED -#define NRFX_SPIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM133_ENABLED -#define NRFX_SPIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM134_ENABLED -#define NRFX_SPIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM135_ENABLED -#define NRFX_SPIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM136_ENABLED -#define NRFX_SPIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIM137_ENABLED -#define NRFX_SPIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_ENABLED -#define NRFX_SPIS_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED -#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL -#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_SPIS120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS120_ENABLED -#define NRFX_SPIS120_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS130_ENABLED -#define NRFX_SPIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS131_ENABLED -#define NRFX_SPIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS132_ENABLED -#define NRFX_SPIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS133_ENABLED -#define NRFX_SPIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS134_ENABLED -#define NRFX_SPIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS135_ENABLED -#define NRFX_SPIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS136_ENABLED -#define NRFX_SPIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_SPIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SPIS137_ENABLED -#define NRFX_SPIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_SYSTICK_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_SYSTICK_ENABLED -#define NRFX_SYSTICK_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_ENABLED -#define NRFX_TEMP_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED -#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TEMP_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL -#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_ENABLED -#define NRFX_TIMER_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED -#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL -#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TIMER020_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER020_ENABLED -#define NRFX_TIMER020_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER021_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER021_ENABLED -#define NRFX_TIMER021_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER022_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER022_ENABLED -#define NRFX_TIMER022_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER120_ENABLED -#define NRFX_TIMER120_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER121_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER121_ENABLED -#define NRFX_TIMER121_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER130_ENABLED -#define NRFX_TIMER130_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER131_ENABLED -#define NRFX_TIMER131_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER132_ENABLED -#define NRFX_TIMER132_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER133_ENABLED -#define NRFX_TIMER133_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER134_ENABLED -#define NRFX_TIMER134_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER135_ENABLED -#define NRFX_TIMER135_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER136_ENABLED -#define NRFX_TIMER136_ENABLED 0 -#endif - -/** - * @brief NRFX_TIMER137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TIMER137_ENABLED -#define NRFX_TIMER137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_ENABLED -#define NRFX_TWIM_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED -#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL -#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIM130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM130_ENABLED -#define NRFX_TWIM130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM131_ENABLED -#define NRFX_TWIM131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM132_ENABLED -#define NRFX_TWIM132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM133_ENABLED -#define NRFX_TWIM133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM134_ENABLED -#define NRFX_TWIM134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM135_ENABLED -#define NRFX_TWIM135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM136_ENABLED -#define NRFX_TWIM136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIM137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIM137_ENABLED -#define NRFX_TWIM137_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ENABLED -#define NRFX_TWIS_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED -#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - * - * Assume that any instance would be initialized only once. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY -#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -#endif - -/** - * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS_NO_SYNC_MODE -#define NRFX_TWIS_NO_SYNC_MODE 0 -#endif - -/** - * @brief NRFX_TWIS_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL -#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_TWIS130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS130_ENABLED -#define NRFX_TWIS130_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS131_ENABLED -#define NRFX_TWIS131_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS132_ENABLED -#define NRFX_TWIS132_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS133_ENABLED -#define NRFX_TWIS133_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS134_ENABLED -#define NRFX_TWIS134_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS135_ENABLED -#define NRFX_TWIS135_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS136_ENABLED -#define NRFX_TWIS136_ENABLED 0 -#endif - -/** - * @brief NRFX_TWIS137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_TWIS137_ENABLED -#define NRFX_TWIS137_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - * - * If enabled, support for configuring GPIO pins is removed from the driver. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - * - * If enabled, support for configuring PSEL registers is removed from the driver. - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG -#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX transfers. - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_TX_LINK -#define NRFX_UARTE_CONFIG_TX_LINK 1 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED -#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 -#endif - -/** - * @brief NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE - * - * Integer value. Minimum: 0. Maximum: 255. - */ -#ifndef NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE -#define NRFX_UARTE_RX_FIFO_FLUSH_WORKAROUND_MAGIC_BYTE 171 -#endif - -/** - * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED -#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL -#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_UARTE120_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE120_ENABLED -#define NRFX_UARTE120_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE130_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE130_ENABLED -#define NRFX_UARTE130_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE131_ENABLED -#define NRFX_UARTE131_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE132_ENABLED -#define NRFX_UARTE132_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE133_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE133_ENABLED -#define NRFX_UARTE133_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE134_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE134_ENABLED -#define NRFX_UARTE134_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE135_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE135_ENABLED -#define NRFX_UARTE135_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE136_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE136_ENABLED -#define NRFX_UARTE136_ENABLED 0 -#endif - -/** - * @brief NRFX_UARTE137_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_UARTE137_ENABLED -#define NRFX_UARTE137_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_ENABLED -#define NRFX_WDT_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY - * - * Integer value. Minimum: 0. Maximum: 7. - */ -#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY -#endif - -/** - * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_NO_IRQ -#define NRFX_WDT_CONFIG_NO_IRQ 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT_CONFIG_LOG_ENABLED -#define NRFX_WDT_CONFIG_LOG_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT_CONFIG_LOG_LEVEL - * - * Integer value. - * Supported values: - * - Off = 0 - * - Error = 1 - * - Warning = 2 - * - Info = 3 - * - Debug = 4 - */ -#ifndef NRFX_WDT_CONFIG_LOG_LEVEL -#define NRFX_WDT_CONFIG_LOG_LEVEL 3 -#endif - -/** - * @brief NRFX_WDT010_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT010_ENABLED -#define NRFX_WDT010_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT011_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT011_ENABLED -#define NRFX_WDT011_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT131_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT131_ENABLED -#define NRFX_WDT131_ENABLED 0 -#endif - -/** - * @brief NRFX_WDT132_ENABLED - * - * Boolean. Accepted values: 0 and 1. - */ -#ifndef NRFX_WDT132_ENABLED -#define NRFX_WDT132_ENABLED 0 -#endif - -#endif /* NRFX_CONFIG_NRF9230_ENGB_RADIOCORE_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_reserved_resources.h b/modules/hal_nordic/nrfx/nrfx_config_reserved_resources.h deleted file mode 100644 index c40e22c17d7c4..0000000000000 --- a/modules/hal_nordic/nrfx/nrfx_config_reserved_resources.h +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (c) 2024, Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef NRFX_CONFIG_RESERVED_RESOURCES_H__ -#define NRFX_CONFIG_RESERVED_RESOURCES_H__ - -/** @brief Bitmask that defines GPIOTE130 channels reserved for use outside - * of the nrfx library. - */ -#define NRFX_GPIOTE130_CHANNELS_USED \ - (~NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote130), owned_channels) | \ - NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote130), child_owned_channels)) - -/** @brief Bitmask that defines GPIOTE131 channels reserved for use outside - * of the nrfx library. - */ -#define NRFX_GPIOTE131_CHANNELS_USED \ - (~NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote131), owned_channels) | \ - NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote131), child_owned_channels)) - -/** @brief Bitmask that defines EGU instances that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_EGUS_USED 0 - -/** @brief Bitmask that defines TIMER instances that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_TIMERS_USED 0 - -/* - * The enabled Bluetooth controller subsystem is responsible for providing - * definitions of the BT_CTLR_USED_* symbols used below in a file named - * bt_ctlr_used_resources.h and for adding its location to global include - * paths so that the file can be included here for all Zephyr libraries that - * are to be built. - */ -#if defined(CONFIG_BT_LL_SW_SPLIT) -#include -#if defined(DPPI_PRESENT) -#if defined(NRF53_SERIES) -#define NRFX_DPPI0_CHANNELS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_CHANNELS -#define NRFX_DPPI0_GROUPS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_GROUPS -#elif defined(NRF54L_SERIES) -#define NRFX_DPPI10_CHANNELS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_CHANNELS -#define NRFX_DPPI10_GROUPS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_GROUPS -#endif -#else /* defined(DPPI_PRESENT) */ -#define NRFX_PPI_CHANNELS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_CHANNELS -#define NRFX_PPI_GROUPS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_GROUPS -#endif /* defined(DPPI_PRESENT) */ -#endif /* defined(CONFIG_BT_LL_SW_SPLIT) */ - -#if defined(CONFIG_NRF_802154_RADIO_DRIVER) -#if defined(NRF52_SERIES) -#include <../src/nrf_802154_peripherals_nrf52.h> -#define NRFX_PPI_CHANNELS_USED_BY_802154_DRV NRF_802154_PPI_CHANNELS_USED_MASK -#define NRFX_PPI_GROUPS_USED_BY_802154_DRV NRF_802154_PPI_GROUPS_USED_MASK -#elif defined(NRF53_SERIES) -#include <../src/nrf_802154_peripherals_nrf53.h> -#define NRFX_DPPI0_CHANNELS_USED_BY_802154_DRV NRF_802154_DPPI_CHANNELS_USED_MASK -#define NRFX_DPPI0_GROUPS_USED_BY_802154_DRV NRF_802154_DPPI_GROUPS_USED_MASK -#elif defined(NRF54L_SERIES) -#include <../src/nrf_802154_peripherals_nrf54l.h> -#define NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV NRF_802154_DPPI_CHANNELS_USED_MASK -#define NRFX_DPPI10_GROUPS_USED_BY_802154_DRV NRF_802154_DPPI_GROUPS_USED_MASK -#elif defined(NRF54H_SERIES) -#include <../src/nrf_802154_peripherals_nrf54h.h> -#define NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV NRF_802154_DPPI_CHANNELS_USED_MASK -#define NRFX_DPPI020_GROUPS_USED_BY_802154_DRV NRF_802154_DPPI_GROUPS_USED_MASK -#else -#error Unsupported chip family -#endif -#endif /* CONFIG_NRF_802154_RADIO_DRIVER */ - -#ifndef NRFX_DPPI0_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI0_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI0_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI0_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI0_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI0_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI0_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI0_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI0_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI0_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI0_GROUPS_USED_BY_MPSL -#define NRFX_DPPI0_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI00_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI00_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI00_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI00_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI00_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI00_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI00_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI00_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI00_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI00_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI00_GROUPS_USED_BY_MPSL -#define NRFX_DPPI00_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI10_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI10_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI10_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI10_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI10_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI10_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI10_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI10_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI10_GROUPS_USED_BY_MPSL -#define NRFX_DPPI10_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI20_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI20_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI20_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI20_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI20_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI20_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI20_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI20_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI20_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI20_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI20_GROUPS_USED_BY_MPSL -#define NRFX_DPPI20_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI30_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI30_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI30_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI30_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI30_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI30_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI30_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI30_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI30_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI30_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI30_GROUPS_USED_BY_MPSL -#define NRFX_DPPI30_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI020_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI020_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI020_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI020_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI020_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI020_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI020_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI020_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI020_GROUPS_USED_BY_MPSL -#define NRFX_DPPI020_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI030_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI030_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI030_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI030_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI030_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI030_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI030_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI030_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI030_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI030_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI030_GROUPS_USED_BY_MPSL -#define NRFX_DPPI030_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI120_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI120_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI120_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI120_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI120_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI120_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI120_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI120_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI120_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI120_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI120_GROUPS_USED_BY_MPSL -#define NRFX_DPPI120_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI130_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI130_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI130_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI130_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI130_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI130_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI130_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI130_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI130_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI130_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI130_GROUPS_USED_BY_MPSL -#define NRFX_DPPI130_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI131_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI131_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI131_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI131_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI131_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI131_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI131_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI131_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI131_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI131_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI131_GROUPS_USED_BY_MPSL -#define NRFX_DPPI131_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI132_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI132_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI132_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI132_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI132_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI132_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI132_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI132_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI132_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI132_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI132_GROUPS_USED_BY_MPSL -#define NRFX_DPPI132_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI133_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI133_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI133_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI133_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI133_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI133_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI133_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI133_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI133_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI133_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI133_GROUPS_USED_BY_MPSL -#define NRFX_DPPI133_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI134_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI134_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI134_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI134_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI134_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI134_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI134_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI134_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI134_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI134_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI134_GROUPS_USED_BY_MPSL -#define NRFX_DPPI134_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI135_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI135_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI135_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI135_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI135_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI135_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI135_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI135_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI135_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI135_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI135_GROUPS_USED_BY_MPSL -#define NRFX_DPPI135_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_DPPI136_CHANNELS_USED_BY_BT_CTLR -#define NRFX_DPPI136_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI136_GROUPS_USED_BY_BT_CTLR -#define NRFX_DPPI136_GROUPS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_DPPI136_CHANNELS_USED_BY_802154_DRV -#define NRFX_DPPI136_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI136_GROUPS_USED_BY_802154_DRV -#define NRFX_DPPI136_GROUPS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_DPPI136_CHANNELS_USED_BY_MPSL -#define NRFX_DPPI136_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_DPPI136_GROUPS_USED_BY_MPSL -#define NRFX_DPPI136_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_PPI_CHANNELS_USED_BY_BT_CTLR -#define NRFX_PPI_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_PPI_GROUPS_USED_BY_BT_CTLR -#define NRFX_PPI_GROUPS_USED_BY_BT_CTLR 0 -#endif - -#ifndef NRFX_PPI_CHANNELS_USED_BY_802154_DRV -#define NRFX_PPI_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_PPI_GROUPS_USED_BY_802154_DRV -#define NRFX_PPI_GROUPS_USED_BY_802154_DRV 0 -#endif - -#ifndef NRFX_PPI_CHANNELS_USED_BY_MPSL -#define NRFX_PPI_CHANNELS_USED_BY_MPSL 0 -#endif -#ifndef NRFX_PPI_GROUPS_USED_BY_MPSL -#define NRFX_PPI_GROUPS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_PPIB_00_10_CHANNELS_USED_BY_BT_CTLR -#define NRFX_PPIB_00_10_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_PPIB_00_10_CHANNELS_USED_BY_802154_DRV -#define NRFX_PPIB_00_10_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_PPIB_00_10_CHANNELS_USED_BY_MPSL -#define NRFX_PPIB_00_10_CHANNELS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_PPIB_01_20_CHANNELS_USED_BY_BT_CTLR -#define NRFX_PPIB_01_20_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_PPIB_01_20_CHANNELS_USED_BY_802154_DRV -#define NRFX_PPIB_01_20_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_PPIB_01_20_CHANNELS_USED_BY_MPSL -#define NRFX_PPIB_01_20_CHANNELS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_PPIB_11_21_CHANNELS_USED_BY_BT_CTLR -#define NRFX_PPIB_11_21_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_PPIB_11_21_CHANNELS_USED_BY_802154_DRV -#define NRFX_PPIB_11_21_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_PPIB_11_21_CHANNELS_USED_BY_MPSL -#define NRFX_PPIB_11_21_CHANNELS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_PPIB_22_30_CHANNELS_USED_BY_BT_CTLR -#define NRFX_PPIB_22_30_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_PPIB_22_30_CHANNELS_USED_BY_802154_DRV -#define NRFX_PPIB_22_30_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_PPIB_22_30_CHANNELS_USED_BY_MPSL -#define NRFX_PPIB_22_30_CHANNELS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_PPIB_02_03_CHANNELS_USED_BY_BT_CTLR -#define NRFX_PPIB_02_03_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_PPIB_02_03_CHANNELS_USED_BY_802154_DRV -#define NRFX_PPIB_02_03_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_PPIB_02_03_CHANNELS_USED_BY_MPSL -#define NRFX_PPIB_02_03_CHANNELS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_PPIB_04_12_CHANNELS_USED_BY_BT_CTLR -#define NRFX_PPIB_04_12_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_PPIB_04_12_CHANNELS_USED_BY_802154_DRV -#define NRFX_PPIB_04_12_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_PPIB_04_12_CHANNELS_USED_BY_MPSL -#define NRFX_PPIB_04_12_CHANNELS_USED_BY_MPSL 0 -#endif - -#ifndef NRFX_PPIB_020_030_CHANNELS_USED_BY_BT_CTLR -#define NRFX_PPIB_020_030_CHANNELS_USED_BY_BT_CTLR 0 -#endif -#ifndef NRFX_PPIB_020_030_CHANNELS_USED_BY_802154_DRV -#define NRFX_PPIB_020_030_CHANNELS_USED_BY_802154_DRV 0 -#endif -#ifndef NRFX_PPIB_020_030_CHANNELS_USED_BY_MPSL -#define NRFX_PPIB_020_030_CHANNELS_USED_BY_MPSL 0 -#endif - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI0_CHANNELS_USED \ - (NRFX_DPPI0_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI0_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI0_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI0_GROUPS_USED \ - (NRFX_DPPI0_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI0_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI0_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI00_CHANNELS_USED \ - (NRFX_DPPI00_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI00_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI00_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI00_GROUPS_USED \ - (NRFX_DPPI00_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI00_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI00_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI10_CHANNELS_USED \ - (NRFX_DPPI10_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI10_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI10_GROUPS_USED \ - (NRFX_DPPI10_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI10_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI10_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI20_CHANNELS_USED \ - (NRFX_DPPI20_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI20_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI20_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI20_GROUPS_USED \ - (NRFX_DPPI20_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI20_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI20_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI30_CHANNELS_USED \ - (NRFX_DPPI30_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI30_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI30_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI30_GROUPS_USED \ - (NRFX_DPPI30_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI30_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI30_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI020_CHANNELS_USED \ - (NRFX_DPPI020_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI020_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI020_GROUPS_USED \ - (NRFX_DPPI020_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI020_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI020_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI030_CHANNELS_USED \ - (NRFX_DPPI030_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI030_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI030_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI030_GROUPS_USED \ - (NRFX_DPPI030_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI030_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI030_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI120_CHANNELS_USED \ - (NRFX_DPPI120_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI120_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI120_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI120_GROUPS_USED \ - (NRFX_DPPI120_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI120_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI120_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI130_CHANNELS_USED \ - (NRFX_DPPI130_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI130_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI130_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI130_GROUPS_USED \ - (NRFX_DPPI130_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI130_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI130_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI131_CHANNELS_USED \ - (NRFX_DPPI131_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI131_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI131_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI131_GROUPS_USED \ - (NRFX_DPPI131_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI131_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI131_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI132_CHANNELS_USED \ - (NRFX_DPPI132_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI132_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI132_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI132_GROUPS_USED \ - (NRFX_DPPI132_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI132_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI132_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI133_CHANNELS_USED \ - (NRFX_DPPI133_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI133_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI133_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI133_GROUPS_USED \ - (NRFX_DPPI133_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI133_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI133_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI134_CHANNELS_USED \ - (NRFX_DPPI134_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI134_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI134_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI134_GROUPS_USED \ - (NRFX_DPPI134_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI134_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI134_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI135_CHANNELS_USED \ - (NRFX_DPPI135_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI135_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI135_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI135_GROUPS_USED \ - (NRFX_DPPI135_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI135_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI135_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI136_CHANNELS_USED \ - (NRFX_DPPI136_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI136_CHANNELS_USED_BY_802154_DRV | \ - NRFX_DPPI136_CHANNELS_USED_BY_MPSL) - -/** @brief Bitmask that defines DPPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_DPPI136_GROUPS_USED \ - (NRFX_DPPI136_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI136_GROUPS_USED_BY_802154_DRV | \ - NRFX_DPPI136_GROUPS_USED_BY_MPSL) - -/** @brief Bitmask that defines PPI channels that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_PPI_CHANNELS_USED \ - (NRFX_PPI_CHANNELS_USED_BY_BT_CTLR | NRFX_PPI_CHANNELS_USED_BY_802154_DRV | \ - NRFX_PPI_CHANNELS_USED_BY_MPSL) - -#define NRFX_DPPI_CHANNELS_USED NRFX_DPPI0_CHANNELS_USED -#define NRFX_DPPI_GROUPS_USED NRFX_DPPI0_GROUPS_USED - -/** @brief Bitmask that defines PPI groups that are reserved for use outside - * of the nrfx library. - */ -#define NRFX_PPI_GROUPS_USED \ - (NRFX_PPI_GROUPS_USED_BY_BT_CTLR | NRFX_PPI_GROUPS_USED_BY_802154_DRV | \ - NRFX_PPI_GROUPS_USED_BY_MPSL) - -#define NRFX_PPIB_INTERCONNECT_00_10_CHANNELS_USED \ - (NRFX_PPIB_00_10_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_00_10_CHANNELS_USED_BY_802154_DRV | \ - NRFX_PPIB_00_10_CHANNELS_USED_BY_MPSL) - -#define NRFX_PPIB_INTERCONNECT_01_20_CHANNELS_USED \ - (NRFX_PPIB_01_20_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_01_20_CHANNELS_USED_BY_802154_DRV | \ - NRFX_PPIB_01_20_CHANNELS_USED_BY_MPSL) - -#define NRFX_PPIB_INTERCONNECT_11_21_CHANNELS_USED \ - (NRFX_PPIB_11_21_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_11_21_CHANNELS_USED_BY_802154_DRV | \ - NRFX_PPIB_11_21_CHANNELS_USED_BY_MPSL) - -#define NRFX_PPIB_INTERCONNECT_22_30_CHANNELS_USED \ - (NRFX_PPIB_22_30_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_22_30_CHANNELS_USED_BY_802154_DRV | \ - NRFX_PPIB_22_30_CHANNELS_USED_BY_MPSL) - -#define NRFX_PPIB_INTERCONNECT_02_03_CHANNELS_USED \ - (NRFX_PPIB_02_03_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_02_03_CHANNELS_USED_BY_802154_DRV | \ - NRFX_PPIB_02_03_CHANNELS_USED_BY_MPSL) - -#define NRFX_PPIB_INTERCONNECT_04_12_CHANNELS_USED \ - (NRFX_PPIB_04_12_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_04_12_CHANNELS_USED_BY_802154_DRV | \ - NRFX_PPIB_04_12_CHANNELS_USED_BY_MPSL) - -#define NRFX_PPIB_INTERCONNECT_020_030_CHANNELS_USED \ - (NRFX_PPIB_020_030_CHANNELS_USED_BY_BT_CTLR | \ - NRFX_PPIB_020_030_CHANNELS_USED_BY_802154_DRV | NRFX_PPIB_020_030_CHANNELS_USED_BY_MPSL) - -#endif /* NRFX_CONFIG_RESERVED_RESOURCES_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_glue.h b/modules/hal_nordic/nrfx/nrfx_glue.h index 8f1109f4a79cd..0fadfb61b0274 100644 --- a/modules/hal_nordic/nrfx/nrfx_glue.h +++ b/modules/hal_nordic/nrfx/nrfx_glue.h @@ -312,14 +312,6 @@ void nrfx_busy_wait(uint32_t usec_to_wait); (void)size; \ } while (0) -/*------------------------------------------------------------------------------*/ - -#ifdef CONFIG_NRFX_RESERVED_RESOURCES_HEADER -#include CONFIG_NRFX_RESERVED_RESOURCES_HEADER -#endif - -//------------------------------------------------------------------------------ - /** * @brief Function helping to integrate nrfx IRQ handlers with IRQ_CONNECT. * diff --git a/modules/hal_nordic/nrfx/nrfx_kconfig.h b/modules/hal_nordic/nrfx/nrfx_kconfig.h new file mode 100644 index 0000000000000..d36b3617b077e --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_kconfig.h @@ -0,0 +1,1036 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_KCONFIG_H__ +#define NRFX_KCONFIG_H__ + +/* + * These are mappings of Kconfig options enabling nrfx drivers and particular + * peripheral instances to the corresponding symbols used inside of nrfx. + * Please note that only subsets of these entries are used for particular SoCs + * supported by nrfx (see the corresponding nrfx_config_*.h files). + */ + +#ifdef CONFIG_NRFX_ADC +#define NRFX_ADC_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_ADC_LOG +#define NRFX_ADC_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_CLOCK +#define NRFX_CLOCK_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_CLOCK_LOG +#define NRFX_CLOCK_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC +#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#define NRFX_CLOCK_CONFIG_LF_SRC 1 +#else +#define NRFX_CLOCK_CONFIG_LF_SRC 0 +#endif +#endif + +#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL +#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#define NRFX_CLOCK_CONFIG_LF_SRC 2 +#else +#define NRFX_CLOCK_CONFIG_LF_SRC 1 +#endif +#endif + +#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH +#ifdef CONFIG_SOC_COMPATIBLE_NRF53X +#define NRFX_CLOCK_CONFIG_LF_SRC 3 +#else +#define NRFX_CLOCK_CONFIG_LF_SRC 2 +#endif +#endif + +#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING +#define NRFX_CLOCK_CONFIG_LF_SRC 131073 +#endif + +#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING +#define NRFX_CLOCK_CONFIG_LF_SRC 196609 +#endif + +#ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION +#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_CLOCK_LFXO_TWO_STAGE_ENABLED +#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_COMP +#define NRFX_COMP_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_COMP_LOG +#define NRFX_COMP_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_CRACEN +#define NRFX_CRACEN_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_DPPI +#define NRFX_DPPI_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI_LOG +#define NRFX_DPPI_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI0 +#define NRFX_DPPI0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI00 +#define NRFX_DPPI00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI10 +#define NRFX_DPPI10_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI20 +#define NRFX_DPPI20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI30 +#define NRFX_DPPI30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI020 +#define NRFX_DPPI020_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI120 +#define NRFX_DPPI120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI130 +#define NRFX_DPPI130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI131 +#define NRFX_DPPI131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI132 +#define NRFX_DPPI132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI133 +#define NRFX_DPPI133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI134 +#define NRFX_DPPI134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI135 +#define NRFX_DPPI135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_DPPI136 +#define NRFX_DPPI136_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_EGU +#define NRFX_EGU_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU_LOG +#define NRFX_EGU_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU0 +#define NRFX_EGU0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU1 +#define NRFX_EGU1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU2 +#define NRFX_EGU2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU3 +#define NRFX_EGU3_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU4 +#define NRFX_EGU4_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU5 +#define NRFX_EGU5_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU10 +#define NRFX_EGU10_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU20 +#define NRFX_EGU20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU020 +#define NRFX_EGU020_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_EGU130 +#define NRFX_EGU130_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_GRTC +#define NRFX_GRTC_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GRTC_LOG +#define NRFX_GRTC_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT +#define NRF_GRTC_HAS_EXTENDED 1 +#endif +#ifdef CONFIG_NRF_GRTC_TIMER_AUTO_KEEP_ALIVE +#define NRFX_GRTC_CONFIG_AUTOEN 1 +#endif +#ifdef CONFIG_NRF_GRTC_START_SYSCOUNTER +#define NRFX_GRTC_CONFIG_AUTOSTART 1 +#endif + +#ifdef CONFIG_NRFX_GPIOTE +#define NRFX_GPIOTE_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE_LOG +#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE0 +#define NRFX_GPIOTE0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE1 +#define NRFX_GPIOTE1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE20 +#define NRFX_GPIOTE20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE30 +#define NRFX_GPIOTE30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE130 +#define NRFX_GPIOTE130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE131 +#define NRFX_GPIOTE131_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS +#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS +#endif + +#ifdef CONFIG_NRFX_I2S +#define NRFX_I2S_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_I2S_LOG +#define NRFX_I2S_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_I2S0 +#define NRFX_I2S0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_I2S20 +#define NRFX_I2S20_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_IPC +#define NRFX_IPC_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_IPC_LOG +#define NRFX_IPC_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_LPCOMP +#define NRFX_LPCOMP_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_LPCOMP_LOG +#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_NFCT +#define NRFX_NFCT_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_NFCT_LOG +#define NRFX_NFCT_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_NVMC +#define NRFX_NVMC_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_NVMC_LOG +#define NRFX_NVMC_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_PDM +#define NRFX_PDM_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PDM_LOG +#define NRFX_PDM_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PDM0 +#define NRFX_PDM0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PDM20 +#define NRFX_PDM20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PDM21 +#define NRFX_PDM21_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_POWER +#define NRFX_POWER_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_POWER_LOG +#define NRFX_POWER_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_PPI +#define NRFX_PPI_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPI_LOG +#define NRFX_PPI_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_PPIB +#define NRFX_PPIB_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB_LOG +#define NRFX_PPIB_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB00 +#define NRFX_PPIB00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB01 +#define NRFX_PPIB01_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB10 +#define NRFX_PPIB10_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB11 +#define NRFX_PPIB11_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB20 +#define NRFX_PPIB20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB21 +#define NRFX_PPIB21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB22 +#define NRFX_PPIB22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PPIB30 +#define NRFX_PPIB30_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_PRS +#define NRFX_PRS_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PRS_LOG +#define NRFX_PRS_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PRS_BOX_0 +#define NRFX_PRS_BOX_0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PRS_BOX_1 +#define NRFX_PRS_BOX_1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PRS_BOX_2 +#define NRFX_PRS_BOX_2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PRS_BOX_3 +#define NRFX_PRS_BOX_3_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PRS_BOX_4 +#define NRFX_PRS_BOX_4_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_PWM +#define NRFX_PWM_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM_LOG +#define NRFX_PWM_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM0 +#define NRFX_PWM0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM1 +#define NRFX_PWM1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM2 +#define NRFX_PWM2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM3 +#define NRFX_PWM3_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM20 +#define NRFX_PWM20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM21 +#define NRFX_PWM21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM22 +#define NRFX_PWM22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM120 +#define NRFX_PWM120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM130 +#define NRFX_PWM130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM131 +#define NRFX_PWM131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM132 +#define NRFX_PWM132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_PWM133 +#define NRFX_PWM133_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_QDEC +#define NRFX_QDEC_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC_LOG +#define NRFX_QDEC_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC0 +#define NRFX_QDEC0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC1 +#define NRFX_QDEC1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC20 +#define NRFX_QDEC20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC21 +#define NRFX_QDEC21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC130 +#define NRFX_QDEC130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QDEC131 +#define NRFX_QDEC131_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_QSPI +#define NRFX_QSPI_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_QSPI_LOG +#define NRFX_QSPI_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_RNG +#define NRFX_RNG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_RNG_LOG +#define NRFX_RNG_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_RRAMC +#define NRFX_RRAMC_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_RTC +#define NRFX_RTC_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_RTC_LOG +#define NRFX_RTC_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_RTC0 +#define NRFX_RTC0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_RTC1 +#define NRFX_RTC1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_RTC2 +#define NRFX_RTC2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_RTC130 +#define NRFX_RTC130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_RTC131 +#define NRFX_RTC131_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_SAADC +#define NRFX_SAADC_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SAADC_LOG +#define NRFX_SAADC_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_SPI +#define NRFX_SPI_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPI_LOG +#define NRFX_SPI_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPI0 +#define NRFX_SPI0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPI1 +#define NRFX_SPI1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPI2 +#define NRFX_SPI2_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_SPIM +#define NRFX_SPIM_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM_LOG +#define NRFX_SPIM_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM0 +#define NRFX_SPIM0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM1 +#define NRFX_SPIM1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM2 +#define NRFX_SPIM2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM3 +#define NRFX_SPIM3_ENABLED 1 +#ifdef CONFIG_NRF52_ANOMALY_198_WORKAROUND +#define NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED 1 +#endif +#endif +#ifdef CONFIG_NRFX_SPIM4 +#define NRFX_SPIM4_ENABLED 1 +#endif + +#define NRFX_SPIM_DT_HAS_RX_DELAY(node) DT_PROP(node, rx_delay_supported) + + +#ifndef NRFX_SPIM_EXTENDED_ENABLED +#if DT_FOREACH_STATUS_OKAY(nordic_nrf_spim, NRFX_SPIM_DT_HAS_RX_DELAY) 0 +#define NRFX_SPIM_EXTENDED_ENABLED 1 +#endif +#endif + +#ifdef CONFIG_NRFX_SPIM00 +#define NRFX_SPIM00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM20 +#define NRFX_SPIM20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM21 +#define NRFX_SPIM21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM22 +#define NRFX_SPIM22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM30 +#define NRFX_SPIM30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM120 +#define NRFX_SPIM120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM121 +#define NRFX_SPIM121_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM130 +#define NRFX_SPIM130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM131 +#define NRFX_SPIM131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM132 +#define NRFX_SPIM132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM133 +#define NRFX_SPIM133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM134 +#define NRFX_SPIM134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM135 +#define NRFX_SPIM135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM136 +#define NRFX_SPIM136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIM137 +#define NRFX_SPIM137_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_SPIS +#define NRFX_SPIS_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS_LOG +#define NRFX_SPIS_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS0 +#define NRFX_SPIS0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS1 +#define NRFX_SPIS1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS2 +#define NRFX_SPIS2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS3 +#define NRFX_SPIS3_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS00 +#define NRFX_SPIS00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS20 +#define NRFX_SPIS20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS21 +#define NRFX_SPIS21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS22 +#define NRFX_SPIS22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS30 +#define NRFX_SPIS30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS120 +#define NRFX_SPIS120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS130 +#define NRFX_SPIS130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS131 +#define NRFX_SPIS131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS132 +#define NRFX_SPIS132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS133 +#define NRFX_SPIS133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS134 +#define NRFX_SPIS134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS135 +#define NRFX_SPIS135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS136 +#define NRFX_SPIS136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SPIS137 +#define NRFX_SPIS137_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_SYSTICK +#define NRFX_SYSTICK_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_SYSTICK_LOG +#define NRFX_SYSTICK_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_TBM +#define NRFX_TBM_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_TEMP +#define NRFX_TEMP_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TEMP_LOG +#define NRFX_TEMP_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_TIMER +#define NRFX_TIMER_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER_LOG +#define NRFX_TIMER_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER0 +#define NRFX_TIMER0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER1 +#define NRFX_TIMER1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER2 +#define NRFX_TIMER2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER3 +#define NRFX_TIMER3_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER4 +#define NRFX_TIMER4_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER00 +#define NRFX_TIMER00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER10 +#define NRFX_TIMER10_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER20 +#define NRFX_TIMER20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER21 +#define NRFX_TIMER21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER22 +#define NRFX_TIMER22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER23 +#define NRFX_TIMER23_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER24 +#define NRFX_TIMER24_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER020 +#define NRFX_TIMER020_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER021 +#define NRFX_TIMER021_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER022 +#define NRFX_TIMER022_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER120 +#define NRFX_TIMER120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER121 +#define NRFX_TIMER121_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER130 +#define NRFX_TIMER130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER131 +#define NRFX_TIMER131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER132 +#define NRFX_TIMER132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER133 +#define NRFX_TIMER133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER134 +#define NRFX_TIMER134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER135 +#define NRFX_TIMER135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER136 +#define NRFX_TIMER136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER137 +#define NRFX_TIMER137_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_TWI +#define NRFX_TWI_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWI_LOG +#define NRFX_TWI_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWI0 +#define NRFX_TWI0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWI1 +#define NRFX_TWI1_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_TWIM +#define NRFX_TWIM_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM_LOG +#define NRFX_TWIM_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM0 +#define NRFX_TWIM0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM1 +#define NRFX_TWIM1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM2 +#define NRFX_TWIM2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM3 +#define NRFX_TWIM3_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM20 +#define NRFX_TWIM20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM21 +#define NRFX_TWIM21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM22 +#define NRFX_TWIM22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM30 +#define NRFX_TWIM30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM120 +#define NRFX_TWIM120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM130 +#define NRFX_TWIM130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM131 +#define NRFX_TWIM131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM132 +#define NRFX_TWIM132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM133 +#define NRFX_TWIM133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM134 +#define NRFX_TWIM134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM135 +#define NRFX_TWIM135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM136 +#define NRFX_TWIM136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIM137 +#define NRFX_TWIM137_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_TWIS +#define NRFX_TWIS_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS_LOG +#define NRFX_TWIS_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS0 +#define NRFX_TWIS0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS1 +#define NRFX_TWIS1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS2 +#define NRFX_TWIS2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS3 +#define NRFX_TWIS3_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS20 +#define NRFX_TWIS20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS21 +#define NRFX_TWIS21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS22 +#define NRFX_TWIS22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS30 +#define NRFX_TWIS30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS130 +#define NRFX_TWIS130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS131 +#define NRFX_TWIS131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS132 +#define NRFX_TWIS132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS133 +#define NRFX_TWIS133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS134 +#define NRFX_TWIS134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS135 +#define NRFX_TWIS135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS136 +#define NRFX_TWIS136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TWIS137 +#define NRFX_TWIS137_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_UART +#define NRFX_UART_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UART_LOG +#define NRFX_UART_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UART0 +#define NRFX_UART0_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_UARTE +#define NRFX_UARTE_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE_LOG +#define NRFX_UARTE_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE0 +#define NRFX_UARTE0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE1 +#define NRFX_UARTE1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE2 +#define NRFX_UARTE2_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE3 +#define NRFX_UARTE3_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE00 +#define NRFX_UARTE00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE20 +#define NRFX_UARTE20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE21 +#define NRFX_UARTE21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE22 +#define NRFX_UARTE22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE30 +#define NRFX_UARTE30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE120 +#define NRFX_UARTE120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE130 +#define NRFX_UARTE130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE131 +#define NRFX_UARTE131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE132 +#define NRFX_UARTE132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE133 +#define NRFX_UARTE133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE134 +#define NRFX_UARTE134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE135 +#define NRFX_UARTE135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE136 +#define NRFX_UARTE136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE137 +#define NRFX_UARTE137_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 1 +#endif +#ifdef CONFIG_NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 1 +#endif +#ifdef CONFIG_NRFX_UARTE_CONFIG_TX_LINK +#define NRFX_UARTE_CONFIG_TX_LINK 1 +#endif +#ifdef CONFIG_NRFX_UARTE_CONFIG_RX_CACHE_ENABLED +#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_USBREG +#define NRFX_USBREG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_USBREG_LOG +#define NRFX_USBREG_CONFIG_LOG_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_WDT +#define NRFX_WDT_ENABLED 1 +#endif +#ifdef CONFIG_WDT_NRFX_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 1 +#endif +#ifdef CONFIG_NRFX_WDT_LOG +#define NRFX_WDT_CONFIG_LOG_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT0 +#define NRFX_WDT0_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT1 +#define NRFX_WDT1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT30 +#define NRFX_WDT30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT31 +#define NRFX_WDT31_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT010 +#define NRFX_WDT010_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT011 +#define NRFX_WDT011_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT130 +#define NRFX_WDT130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT131 +#define NRFX_WDT131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT132 +#define NRFX_WDT132_ENABLED 1 +#endif + +#ifdef CONFIG_NRF52_ANOMALY_109_WORKAROUND +#define NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#define NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#define NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#define NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 +#define NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE \ + CONFIG_NRF52_ANOMALY_109_WORKAROUND_EGU_INSTANCE +#endif + +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_global) || \ + DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_local) +#ifndef NRFX_DPPI_ENABLED +#define NRFX_DPPI_ENABLED 1 +#endif +#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_global) || ... */ + +/* If local or global DPPIC peripherals are used, provide the following macro + * definitions required by the interconnect/ipct layer: + * - NRFX_IPCTx_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) + * - NRFX_IPCTx_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) + * - NRFX_IPCT_PUB_OR_SUB_MASK(inst_num) + * - NRFX_IPCTx_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) + * - NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE + * - NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE + * based on information from devicetree. + */ +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_global) || \ + DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_local) +/* Channels masks generation. */ +#define NRFX_CONFIG_IPCT_MASK_DT(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, owned_channels), \ + (NRFX_CONFIG_MASK_DT(node_id, owned_channels)), \ + (COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, nordic_nrf_ipct_local), \ + (BIT_MASK(DT_PROP(node_id, channels))), (0)))) + +#if defined(NRF_APPLICATION) +#define NRFX_CONFIG_IPCT_LOCAL_NODE DT_NODELABEL(cpuapp_ipct) +#elif defined(NRF_RADIOCORE) +#define NRFX_CONFIG_IPCT_LOCAL_NODE DT_NODELABEL(cpurad_ipct) +#endif +#define NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num) \ + COND_CODE_1(IS_EMPTY(inst_num), \ + (NRFX_CONFIG_IPCT_LOCAL_NODE), \ + (DT_NODELABEL(_CONCAT(ipct, inst_num)))) + +#define NRFX_IPCTx_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ + NRFX_CONFIG_IPCT_MASK_DT(NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num)) + +#define NRFX_IPCTx_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ + NRFX_CONFIG_IPCT_MASK_DT(NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num)) + +#define NRFX_IPCT_PUB_OR_SUB_MASK(inst_num) \ + COND_CODE_1(IS_EMPTY(inst_num), \ + (DT_NODE_HAS_STATUS_OKAY(NRFX_CONFIG_IPCT_LOCAL_NODE)), \ + (DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(ipct, inst_num)), owned_channels))) + +/* Variables names generation. */ +#define NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(node_id) _CONCAT(_CONCAT(m_, node_id), _channels) +#define NRFX_IPCTx_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) \ + COND_CODE_1(IS_EMPTY(inst_num), \ + (NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(NRFX_CONFIG_IPCT_LOCAL_NODE)), \ + (NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(DT_NODELABEL(_CONCAT(ipct, inst_num))))) + +/* Variables entries generation. */ +#define NRFX_CONFIG_IPCT_CHANNELS_ENTRY(node_id) \ + static nrfx_atomic_t NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(node_id) \ + __attribute__((used)) = \ + NRFX_CONFIG_IPCT_MASK_DT(node_id); +#define NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE \ + DT_FOREACH_STATUS_OKAY(nordic_nrf_ipct_local, NRFX_CONFIG_IPCT_CHANNELS_ENTRY) +#define NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE \ + DT_FOREACH_STATUS_OKAY(nordic_nrf_ipct_global, NRFX_CONFIG_IPCT_CHANNELS_ENTRY) +#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_global) || ... */ + +#endif /* NRFX_KCONFIG_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_log.h b/modules/hal_nordic/nrfx/nrfx_log.h index cfa363b4fc38a..682388d7dd16d 100644 --- a/modules/hal_nordic/nrfx/nrfx_log.h +++ b/modules/hal_nordic/nrfx/nrfx_log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * Copyright (c) 2017, Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/modules/hal_nordic/nrfx/nrfx_reserved_resources.h b/modules/hal_nordic/nrfx/nrfx_reserved_resources.h new file mode 100644 index 0000000000000..9958699723ff0 --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_reserved_resources.h @@ -0,0 +1,721 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_RESERVED_RESOURCES_H__ +#define NRFX_RESERVED_RESOURCES_H__ + +/** @brief Bitmask that defines GPIOTE130 channels reserved for use outside + * of the nrfx library. + */ +#define NRFX_GPIOTE130_CHANNELS_USED \ + (~NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote130), owned_channels) | \ + NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote130), child_owned_channels)) + +/** @brief Bitmask that defines GPIOTE131 channels reserved for use outside + * of the nrfx library. + */ +#define NRFX_GPIOTE131_CHANNELS_USED \ + (~NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote131), owned_channels) | \ + NRFX_CONFIG_MASK_DT(DT_NODELABEL(gpiote131), child_owned_channels)) + +/** @brief Bitmask that defines EGU instances that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_EGUS_USED 0 + +/** @brief Bitmask that defines TIMER instances that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_TIMERS_USED 0 + +/* If the GRTC system timer driver is to be used, prepare definitions required + * by the nrfx_grtc driver (NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK and + * NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS) based on information from devicetree. + */ +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_grtc) +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK \ + (NRFX_CONFIG_MASK_DT(DT_INST(0, nordic_nrf_grtc), owned_channels) & \ + ~NRFX_CONFIG_MASK_DT(DT_INST(0, nordic_nrf_grtc), child_owned_channels)) +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS \ + (DT_PROP_LEN_OR(DT_INST(0, nordic_nrf_grtc), owned_channels, 0) - \ + DT_PROP_LEN_OR(DT_INST(0, nordic_nrf_grtc), child_owned_channels, 0)) +#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_grtc) */ + +/* + * The enabled Bluetooth controller subsystem is responsible for providing + * definitions of the BT_CTLR_USED_* symbols used below in a file named + * bt_ctlr_used_resources.h and for adding its location to global include + * paths so that the file can be included here for all Zephyr libraries that + * are to be built. + */ +#if defined(CONFIG_BT_LL_SW_SPLIT) +#include +#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) +#define NRFX_PPI_CHANNELS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_CHANNELS +#define NRFX_PPI_GROUPS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_GROUPS +#elif defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#define NRFX_DPPI0_CHANNELS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_CHANNELS +#define NRFX_DPPI0_GROUPS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_GROUPS +#elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#define NRFX_DPPI10_CHANNELS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_CHANNELS +#define NRFX_DPPI10_GROUPS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_GROUPS +#endif +#endif /* defined(CONFIG_BT_LL_SW_SPLIT) */ + +#if defined(CONFIG_NRF_802154_RADIO_DRIVER) +#if defined(CONFIG_SOC_COMPATIBLE_NRF52X) +#include <../src/nrf_802154_peripherals_nrf52.h> +#define NRFX_PPI_CHANNELS_USED_BY_802154_DRV NRF_802154_PPI_CHANNELS_USED_MASK +#define NRFX_PPI_GROUPS_USED_BY_802154_DRV NRF_802154_PPI_GROUPS_USED_MASK +#elif defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#include <../src/nrf_802154_peripherals_nrf53.h> +#define NRFX_DPPI0_CHANNELS_USED_BY_802154_DRV NRF_802154_DPPI_CHANNELS_USED_MASK +#define NRFX_DPPI0_GROUPS_USED_BY_802154_DRV NRF_802154_DPPI_GROUPS_USED_MASK +#elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#include <../src/nrf_802154_peripherals_nrf54l.h> +#define NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV NRF_802154_DPPI_CHANNELS_USED_MASK +#define NRFX_DPPI10_GROUPS_USED_BY_802154_DRV NRF_802154_DPPI_GROUPS_USED_MASK +#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#include <../src/nrf_802154_peripherals_nrf54h.h> +#define NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV NRF_802154_DPPI_CHANNELS_USED_MASK +#define NRFX_DPPI020_GROUPS_USED_BY_802154_DRV NRF_802154_DPPI_GROUPS_USED_MASK +#else +#error Unsupported chip family +#endif +#endif /* CONFIG_NRF_802154_RADIO_DRIVER */ + +#ifndef NRFX_DPPI0_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI0_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI0_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI0_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI0_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI0_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI0_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI0_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI0_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI0_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI0_GROUPS_USED_BY_MPSL +#define NRFX_DPPI0_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI00_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI00_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI00_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI00_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI00_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI00_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI00_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI00_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI00_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI00_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI00_GROUPS_USED_BY_MPSL +#define NRFX_DPPI00_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI10_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI10_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI10_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI10_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI10_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI10_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI10_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI10_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI10_GROUPS_USED_BY_MPSL +#define NRFX_DPPI10_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI20_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI20_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI20_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI20_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI20_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI20_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI20_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI20_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI20_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI20_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI20_GROUPS_USED_BY_MPSL +#define NRFX_DPPI20_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI30_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI30_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI30_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI30_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI30_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI30_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI30_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI30_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI30_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI30_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI30_GROUPS_USED_BY_MPSL +#define NRFX_DPPI30_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI020_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI020_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI020_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI020_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI020_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI020_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI020_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI020_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI020_GROUPS_USED_BY_MPSL +#define NRFX_DPPI020_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI030_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI030_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI030_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI030_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI030_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI030_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI030_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI030_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI030_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI030_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI030_GROUPS_USED_BY_MPSL +#define NRFX_DPPI030_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI120_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI120_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI120_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI120_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI120_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI120_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI120_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI120_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI120_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI120_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI120_GROUPS_USED_BY_MPSL +#define NRFX_DPPI120_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI130_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI130_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI130_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI130_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI130_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI130_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI130_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI130_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI130_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI130_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI130_GROUPS_USED_BY_MPSL +#define NRFX_DPPI130_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI131_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI131_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI131_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI131_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI131_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI131_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI131_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI131_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI131_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI131_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI131_GROUPS_USED_BY_MPSL +#define NRFX_DPPI131_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI132_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI132_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI132_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI132_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI132_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI132_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI132_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI132_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI132_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI132_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI132_GROUPS_USED_BY_MPSL +#define NRFX_DPPI132_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI133_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI133_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI133_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI133_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI133_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI133_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI133_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI133_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI133_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI133_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI133_GROUPS_USED_BY_MPSL +#define NRFX_DPPI133_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI134_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI134_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI134_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI134_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI134_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI134_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI134_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI134_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI134_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI134_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI134_GROUPS_USED_BY_MPSL +#define NRFX_DPPI134_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI135_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI135_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI135_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI135_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI135_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI135_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI135_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI135_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI135_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI135_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI135_GROUPS_USED_BY_MPSL +#define NRFX_DPPI135_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_DPPI136_CHANNELS_USED_BY_BT_CTLR +#define NRFX_DPPI136_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI136_GROUPS_USED_BY_BT_CTLR +#define NRFX_DPPI136_GROUPS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_DPPI136_CHANNELS_USED_BY_802154_DRV +#define NRFX_DPPI136_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI136_GROUPS_USED_BY_802154_DRV +#define NRFX_DPPI136_GROUPS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_DPPI136_CHANNELS_USED_BY_MPSL +#define NRFX_DPPI136_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_DPPI136_GROUPS_USED_BY_MPSL +#define NRFX_DPPI136_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_PPI_CHANNELS_USED_BY_BT_CTLR +#define NRFX_PPI_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_PPI_GROUPS_USED_BY_BT_CTLR +#define NRFX_PPI_GROUPS_USED_BY_BT_CTLR 0 +#endif + +#ifndef NRFX_PPI_CHANNELS_USED_BY_802154_DRV +#define NRFX_PPI_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_PPI_GROUPS_USED_BY_802154_DRV +#define NRFX_PPI_GROUPS_USED_BY_802154_DRV 0 +#endif + +#ifndef NRFX_PPI_CHANNELS_USED_BY_MPSL +#define NRFX_PPI_CHANNELS_USED_BY_MPSL 0 +#endif +#ifndef NRFX_PPI_GROUPS_USED_BY_MPSL +#define NRFX_PPI_GROUPS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_PPIB_00_10_CHANNELS_USED_BY_BT_CTLR +#define NRFX_PPIB_00_10_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_PPIB_00_10_CHANNELS_USED_BY_802154_DRV +#define NRFX_PPIB_00_10_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_PPIB_00_10_CHANNELS_USED_BY_MPSL +#define NRFX_PPIB_00_10_CHANNELS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_PPIB_01_20_CHANNELS_USED_BY_BT_CTLR +#define NRFX_PPIB_01_20_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_PPIB_01_20_CHANNELS_USED_BY_802154_DRV +#define NRFX_PPIB_01_20_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_PPIB_01_20_CHANNELS_USED_BY_MPSL +#define NRFX_PPIB_01_20_CHANNELS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_PPIB_11_21_CHANNELS_USED_BY_BT_CTLR +#define NRFX_PPIB_11_21_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_PPIB_11_21_CHANNELS_USED_BY_802154_DRV +#define NRFX_PPIB_11_21_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_PPIB_11_21_CHANNELS_USED_BY_MPSL +#define NRFX_PPIB_11_21_CHANNELS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_PPIB_22_30_CHANNELS_USED_BY_BT_CTLR +#define NRFX_PPIB_22_30_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_PPIB_22_30_CHANNELS_USED_BY_802154_DRV +#define NRFX_PPIB_22_30_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_PPIB_22_30_CHANNELS_USED_BY_MPSL +#define NRFX_PPIB_22_30_CHANNELS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_PPIB_02_03_CHANNELS_USED_BY_BT_CTLR +#define NRFX_PPIB_02_03_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_PPIB_02_03_CHANNELS_USED_BY_802154_DRV +#define NRFX_PPIB_02_03_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_PPIB_02_03_CHANNELS_USED_BY_MPSL +#define NRFX_PPIB_02_03_CHANNELS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_PPIB_04_12_CHANNELS_USED_BY_BT_CTLR +#define NRFX_PPIB_04_12_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_PPIB_04_12_CHANNELS_USED_BY_802154_DRV +#define NRFX_PPIB_04_12_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_PPIB_04_12_CHANNELS_USED_BY_MPSL +#define NRFX_PPIB_04_12_CHANNELS_USED_BY_MPSL 0 +#endif + +#ifndef NRFX_PPIB_020_030_CHANNELS_USED_BY_BT_CTLR +#define NRFX_PPIB_020_030_CHANNELS_USED_BY_BT_CTLR 0 +#endif +#ifndef NRFX_PPIB_020_030_CHANNELS_USED_BY_802154_DRV +#define NRFX_PPIB_020_030_CHANNELS_USED_BY_802154_DRV 0 +#endif +#ifndef NRFX_PPIB_020_030_CHANNELS_USED_BY_MPSL +#define NRFX_PPIB_020_030_CHANNELS_USED_BY_MPSL 0 +#endif + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI0_CHANNELS_USED \ + (NRFX_DPPI0_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI0_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI0_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI0_GROUPS_USED \ + (NRFX_DPPI0_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI0_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI0_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI00_CHANNELS_USED \ + (NRFX_DPPI00_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI00_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI00_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI00_GROUPS_USED \ + (NRFX_DPPI00_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI00_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI00_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI10_CHANNELS_USED \ + (NRFX_DPPI10_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI10_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI10_GROUPS_USED \ + (NRFX_DPPI10_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI10_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI10_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI20_CHANNELS_USED \ + (NRFX_DPPI20_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI20_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI20_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI20_GROUPS_USED \ + (NRFX_DPPI20_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI20_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI20_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI30_CHANNELS_USED \ + (NRFX_DPPI30_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI30_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI30_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI30_GROUPS_USED \ + (NRFX_DPPI30_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI30_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI30_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI020_CHANNELS_USED \ + (NRFX_DPPI020_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI020_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI020_GROUPS_USED \ + (NRFX_DPPI020_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI020_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI020_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI030_CHANNELS_USED \ + (NRFX_DPPI030_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI030_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI030_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI030_GROUPS_USED \ + (NRFX_DPPI030_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI030_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI030_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI120_CHANNELS_USED \ + (NRFX_DPPI120_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI120_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI120_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI120_GROUPS_USED \ + (NRFX_DPPI120_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI120_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI120_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI130_CHANNELS_USED \ + (NRFX_DPPI130_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI130_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI130_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI130_GROUPS_USED \ + (NRFX_DPPI130_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI130_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI130_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI131_CHANNELS_USED \ + (NRFX_DPPI131_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI131_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI131_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI131_GROUPS_USED \ + (NRFX_DPPI131_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI131_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI131_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI132_CHANNELS_USED \ + (NRFX_DPPI132_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI132_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI132_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI132_GROUPS_USED \ + (NRFX_DPPI132_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI132_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI132_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI133_CHANNELS_USED \ + (NRFX_DPPI133_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI133_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI133_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI133_GROUPS_USED \ + (NRFX_DPPI133_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI133_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI133_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI134_CHANNELS_USED \ + (NRFX_DPPI134_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI134_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI134_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI134_GROUPS_USED \ + (NRFX_DPPI134_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI134_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI134_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI135_CHANNELS_USED \ + (NRFX_DPPI135_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI135_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI135_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI135_GROUPS_USED \ + (NRFX_DPPI135_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI135_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI135_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI136_CHANNELS_USED \ + (NRFX_DPPI136_CHANNELS_USED_BY_BT_CTLR | NRFX_DPPI136_CHANNELS_USED_BY_802154_DRV | \ + NRFX_DPPI136_CHANNELS_USED_BY_MPSL) + +/** @brief Bitmask that defines DPPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_DPPI136_GROUPS_USED \ + (NRFX_DPPI136_GROUPS_USED_BY_BT_CTLR | NRFX_DPPI136_GROUPS_USED_BY_802154_DRV | \ + NRFX_DPPI136_GROUPS_USED_BY_MPSL) + +/** @brief Bitmask that defines PPI channels that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_PPI_CHANNELS_USED \ + (NRFX_PPI_CHANNELS_USED_BY_BT_CTLR | NRFX_PPI_CHANNELS_USED_BY_802154_DRV | \ + NRFX_PPI_CHANNELS_USED_BY_MPSL) + +#define NRFX_DPPI_CHANNELS_USED NRFX_DPPI0_CHANNELS_USED +#define NRFX_DPPI_GROUPS_USED NRFX_DPPI0_GROUPS_USED + +/** @brief Bitmask that defines PPI groups that are reserved for use outside + * of the nrfx library. + */ +#define NRFX_PPI_GROUPS_USED \ + (NRFX_PPI_GROUPS_USED_BY_BT_CTLR | NRFX_PPI_GROUPS_USED_BY_802154_DRV | \ + NRFX_PPI_GROUPS_USED_BY_MPSL) + +#define NRFX_PPIB_INTERCONNECT_00_10_CHANNELS_USED \ + (NRFX_PPIB_00_10_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_00_10_CHANNELS_USED_BY_802154_DRV | \ + NRFX_PPIB_00_10_CHANNELS_USED_BY_MPSL) + +#define NRFX_PPIB_INTERCONNECT_01_20_CHANNELS_USED \ + (NRFX_PPIB_01_20_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_01_20_CHANNELS_USED_BY_802154_DRV | \ + NRFX_PPIB_01_20_CHANNELS_USED_BY_MPSL) + +#define NRFX_PPIB_INTERCONNECT_11_21_CHANNELS_USED \ + (NRFX_PPIB_11_21_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_11_21_CHANNELS_USED_BY_802154_DRV | \ + NRFX_PPIB_11_21_CHANNELS_USED_BY_MPSL) + +#define NRFX_PPIB_INTERCONNECT_22_30_CHANNELS_USED \ + (NRFX_PPIB_22_30_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_22_30_CHANNELS_USED_BY_802154_DRV | \ + NRFX_PPIB_22_30_CHANNELS_USED_BY_MPSL) + +#define NRFX_PPIB_INTERCONNECT_02_03_CHANNELS_USED \ + (NRFX_PPIB_02_03_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_02_03_CHANNELS_USED_BY_802154_DRV | \ + NRFX_PPIB_02_03_CHANNELS_USED_BY_MPSL) + +#define NRFX_PPIB_INTERCONNECT_04_12_CHANNELS_USED \ + (NRFX_PPIB_04_12_CHANNELS_USED_BY_BT_CTLR | NRFX_PPIB_04_12_CHANNELS_USED_BY_802154_DRV | \ + NRFX_PPIB_04_12_CHANNELS_USED_BY_MPSL) + +#define NRFX_PPIB_INTERCONNECT_020_030_CHANNELS_USED \ + (NRFX_PPIB_020_030_CHANNELS_USED_BY_BT_CTLR | \ + NRFX_PPIB_020_030_CHANNELS_USED_BY_802154_DRV | NRFX_PPIB_020_030_CHANNELS_USED_BY_MPSL) + +#endif /* NRFX_RESERVED_RESOURCES_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_zephyr_utils.h b/modules/hal_nordic/nrfx/nrfx_zephyr_utils.h new file mode 100644 index 0000000000000..e1fa4d4c321a4 --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_zephyr_utils.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_ZEPHYR_UTILS_H__ +#define NRFX_ZEPHYR_UTILS_H__ + +#include +#include + +/* + * For chips with TrustZone support, MDK provides CMSIS-Core peripheral + * accessing symbols in two flavors, with secure and non-secure base address + * mappings. Their names contain the suffix _S or _NS, respectively. + * Because nrfx HALs and drivers require these peripheral accessing symbols + * without any suffixes, the following macro is provided that will translate + * their names according to the kind of the target that is built. + */ +#if defined(NRF_TRUSTZONE_NONSECURE) +#define NRF_PERIPH(P) P##_NS +#else +#define NRF_PERIPH(P) P##_S +#endif + +#define NRFX_CONFIG_BIT_DT(node_id, prop, idx) BIT(DT_PROP_BY_IDX(node_id, prop, idx)) +#define NRFX_CONFIG_MASK_DT(node_id, prop) \ + (COND_CODE_1(DT_NODE_HAS_PROP(node_id, prop), \ + (DT_FOREACH_PROP_ELEM_SEP(node_id, prop, NRFX_CONFIG_BIT_DT, (|))), \ + (0))) + +/* If global of local DPPIC peripherals are used, provide the following macro + * definitions required by the interconnect/apb layer: + * - NRFX_DPPI_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) + * - NRFX_DPPI_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) + * - NRFX_DPPI_PUB_OR_SUB_MASK(inst_num) + * - NRFX_DPPI_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) + * - NRFX_INTERCONNECT_APB_GLOBAL_DPPI_DEFINE + * - NRFX_INTERCONNECT_APB_LOCAL_DPPI_DEFINE + * based on information from devicetree. + */ +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_global) || \ + DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_local) +/* Source (publish) channels masks generation. */ +#define NRFX_DPPI_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ + NRFX_CONFIG_MASK_DT(DT_NODELABEL(_CONCAT(dppic, inst_num)), source_channels) + +/* Sink (subscribe) channels masks generation. */ +#define NRFX_DPPI_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ + NRFX_CONFIG_MASK_DT(DT_NODELABEL(_CONCAT(dppic, inst_num)), sink_channels) + +#define NRFX_DPPI_PUB_OR_SUB_MASK(inst_num) \ + UTIL_OR(DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(dppic, inst_num)), source_channels), \ + DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(dppic, inst_num)), sink_channels)) + +/* Variables names generation. */ +#define NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(node_id) _CONCAT(_CONCAT(m_, node_id), _channels) +#define NRFX_DPPI_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) \ + NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(DT_NODELABEL(_CONCAT(dppic, inst_num))) + +/* Variables entries generation. */ +#define NRFX_CONFIG_DPPI_CHANNELS_ENTRY(node_id) \ + static nrfx_atomic_t NRFX_CONFIG_DPPI_CHANNELS_ENTRY_NAME(node_id) \ + __attribute__((used)) = \ + NRFX_CONFIG_MASK_DT(node_id, source_channels) | \ + NRFX_CONFIG_MASK_DT(node_id, sink_channels); +#define NRFX_INTERCONNECT_APB_GLOBAL_DPPI_DEFINE \ + DT_FOREACH_STATUS_OKAY(nordic_nrf_dppic_global, NRFX_CONFIG_DPPI_CHANNELS_ENTRY) +#define NRFX_INTERCONNECT_APB_LOCAL_DPPI_DEFINE \ + DT_FOREACH_STATUS_OKAY(nordic_nrf_dppic_local, NRFX_CONFIG_DPPI_CHANNELS_ENTRY) +#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_dppic_global) || ... */ + +/* If local or global DPPIC peripherals are used, provide the following macro + * definitions required by the interconnect/ipct layer: + * - NRFX_IPCTx_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) + * - NRFX_IPCTx_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) + * - NRFX_IPCT_PUB_OR_SUB_MASK(inst_num) + * - NRFX_IPCTx_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) + * - NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE + * - NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE + * based on information from devicetree. + */ +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_global) || \ + DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_local) +/* Channels masks generation. */ +#define NRFX_CONFIG_IPCT_MASK_DT(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, owned_channels), \ + (NRFX_CONFIG_MASK_DT(node_id, owned_channels)), \ + (COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, nordic_nrf_ipct_local), \ + (BIT_MASK(DT_PROP(node_id, channels))), (0)))) + +#if defined(NRF_APPLICATION) +#define NRFX_CONFIG_IPCT_LOCAL_NODE DT_NODELABEL(cpuapp_ipct) +#elif defined(NRF_RADIOCORE) +#define NRFX_CONFIG_IPCT_LOCAL_NODE DT_NODELABEL(cpurad_ipct) +#endif +#define NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num) \ + COND_CODE_1(IS_EMPTY(inst_num), \ + (NRFX_CONFIG_IPCT_LOCAL_NODE), \ + (DT_NODELABEL(_CONCAT(ipct, inst_num)))) + +#define NRFX_IPCTx_PUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ + NRFX_CONFIG_IPCT_MASK_DT(NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num)) + +#define NRFX_IPCTx_SUB_CONFIG_ALLOWED_CHANNELS_MASK_BY_INST_NUM(inst_num) \ + NRFX_CONFIG_IPCT_MASK_DT(NRFX_CONFIG_IPCT_NODE_BY_INST_NUM(inst_num)) + +#define NRFX_IPCT_PUB_OR_SUB_MASK(inst_num) \ + COND_CODE_1(IS_EMPTY(inst_num), \ + (DT_NODE_HAS_STATUS_OKAY(NRFX_CONFIG_IPCT_LOCAL_NODE)), \ + (DT_NODE_HAS_PROP(DT_NODELABEL(_CONCAT(ipct, inst_num)), owned_channels))) + +/* Variables names generation. */ +#define NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(node_id) _CONCAT(_CONCAT(m_, node_id), _channels) +#define NRFX_IPCTx_CHANNELS_SINGLE_VAR_NAME_BY_INST_NUM(inst_num) \ + COND_CODE_1(IS_EMPTY(inst_num), \ + (NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(NRFX_CONFIG_IPCT_LOCAL_NODE)), \ + (NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(DT_NODELABEL(_CONCAT(ipct, inst_num))))) + +/* Variables entries generation. */ +#define NRFX_CONFIG_IPCT_CHANNELS_ENTRY(node_id) \ + static nrfx_atomic_t NRFX_CONFIG_IPCT_CHANNELS_ENTRY_NAME(node_id) \ + __attribute__((used)) = \ + NRFX_CONFIG_IPCT_MASK_DT(node_id); +#define NRFX_INTERCONNECT_IPCT_LOCAL_DEFINE \ + DT_FOREACH_STATUS_OKAY(nordic_nrf_ipct_local, NRFX_CONFIG_IPCT_CHANNELS_ENTRY) +#define NRFX_INTERCONNECT_IPCT_GLOBAL_DEFINE \ + DT_FOREACH_STATUS_OKAY(nordic_nrf_ipct_global, NRFX_CONFIG_IPCT_CHANNELS_ENTRY) +#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_ipct_global) || ... */ + +#endif /* NRFX_ZEPHYR_UTILS_H__ */ diff --git a/modules/hal_rpi_pico/CMakeLists.txt b/modules/hal_rpi_pico/CMakeLists.txt index c91e646799253..0a02aeae89299 100644 --- a/modules/hal_rpi_pico/CMakeLists.txt +++ b/modules/hal_rpi_pico/CMakeLists.txt @@ -4,11 +4,12 @@ include(ExternalProject) if(CONFIG_HAS_RPI_PICO) zephyr_library() + zephyr_library_compile_options(-std=gnu11) set(rp2_common_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/rp2_common) - set(rp2040_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/rp2040) + set(rp2xxx_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/${CONFIG_SOC_SERIES}) set(common_dir ${ZEPHYR_HAL_RPI_PICO_MODULE_DIR}/src/common) - set(boot_stage_dir ${rp2040_dir}/boot_stage2) + set(boot_stage_dir ${rp2xxx_dir}/boot_stage2) # The Second Stage Bootloader is only linked to the app that resides # at 0x100. Therefore, only if the app's offset is 0x100, the second @@ -46,7 +47,11 @@ if(CONFIG_HAS_RPI_PICO) zephyr_library_sources(${rp2_bootloader_asm}) endif() - zephyr_compile_definitions(PICO_RP2040) + if(CONFIG_SOC_SERIES_RP2040) + zephyr_compile_definitions(PICO_RP2040) + elseif(CONFIG_SOC_SERIES_RP2350) + zephyr_compile_definitions(PICO_RP2350) + endif() # Pico sources and headers necessary for every build. # These contain definitions and implementation used mostly for @@ -57,12 +62,15 @@ if(CONFIG_HAS_RPI_PICO) ${rp2_common_dir}/hardware_pll/pll.c ${rp2_common_dir}/hardware_xosc/xosc.c ${rp2_common_dir}/hardware_watchdog/watchdog.c + ${rp2_common_dir}/hardware_sync_spin_lock/sync_spin_lock.c + ${rp2_common_dir}/hardware_ticks/ticks.c ${rp2_common_dir}/pico_bootrom/bootrom.c - ${rp2040_dir}/pico_platform/platform.c + ${rp2xxx_dir}/pico_platform/platform.c ) zephyr_include_directories( ${common_dir}/pico_base_headers/include + ${rp2_common_dir}/boot_bootrom_headers/include ${rp2_common_dir}/hardware_base/include ${rp2_common_dir}/hardware_clocks/include ${rp2_common_dir}/hardware_watchdog/include @@ -76,14 +84,15 @@ if(CONFIG_HAS_RPI_PICO) ${rp2_common_dir}/hardware_ticks/include ${rp2_common_dir}/hardware_sync_spin_lock/include ${rp2_common_dir}/pico_bootrom/include + ${rp2_common_dir}/pico_flash/include ${rp2_common_dir}/pico_platform_compiler/include ${rp2_common_dir}/pico_platform_sections/include ${rp2_common_dir}/pico_platform_panic/include ${common_dir}/boot_picoboot_headers/include ${common_dir}/boot_picobin_headers/include - ${rp2040_dir}/hardware_regs/include - ${rp2040_dir}/hardware_structs/include - ${rp2040_dir}/pico_platform/include + ${rp2xxx_dir}/hardware_regs/include + ${rp2xxx_dir}/hardware_structs/include + ${rp2xxx_dir}/pico_platform/include ${CMAKE_CURRENT_LIST_DIR} ) @@ -96,9 +105,11 @@ if(CONFIG_HAS_RPI_PICO) ${rp2_common_dir}/hardware_uart/include) zephyr_library_sources_ifdef(CONFIG_PICOSDK_USE_FLASH - ${rp2_common_dir}/hardware_flash/flash.c) + ${rp2_common_dir}/hardware_flash/flash.c + ${rp2_common_dir}/hardware_xip_cache/xip_cache.c) zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_FLASH - ${rp2_common_dir}/hardware_flash/include) + ${rp2_common_dir}/hardware_flash/include + ${rp2_common_dir}/hardware_xip_cache/include) zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_PWM ${rp2_common_dir}/hardware_pwm/include) @@ -145,4 +156,10 @@ if(CONFIG_HAS_RPI_PICO) zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_CLAIM ${common_dir}/hardware_claim/include) + zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_RP2350 + ${rp2_common_dir}/pico_runtime_init/runtime_init.c) + zephyr_include_directories_ifdef(CONFIG_SOC_SERIES_RP2350 + ${rp2_common_dir}/pico_runtime/include + ${rp2_common_dir}/pico_runtime_init/include) + endif() diff --git a/modules/hal_silabs/CMakeLists.txt b/modules/hal_silabs/CMakeLists.txt index 62d7ed54a157a..29759a3f83ea0 100644 --- a/modules/hal_silabs/CMakeLists.txt +++ b/modules/hal_silabs/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory_ifdef(CONFIG_SOC_FAMILY_SILABS_S0 gecko) add_subdirectory_ifdef(CONFIG_SOC_FAMILY_SILABS_S1 gecko) add_subdirectory_ifdef(CONFIG_SOC_FAMILY_SILABS_S2 simplicity_sdk) +add_subdirectory_ifdef(CONFIG_SOC_FAMILY_SILABS_SIWX91X wiseconnect) add_subdirectory_ifdef(CONFIG_HAS_SILABS_SI32 si32) diff --git a/modules/hal_silabs/Kconfig b/modules/hal_silabs/Kconfig index b75796c432f4c..93dff37d753ed 100644 --- a/modules/hal_silabs/Kconfig +++ b/modules/hal_silabs/Kconfig @@ -12,8 +12,20 @@ config ZEPHYR_HAL_SILABS_MODULE_BLOBS config HAS_SILABS_GECKO bool select HAS_CMSIS_CORE - depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 + depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 + +config HAS_SILABS_SISDK + bool + select HAS_CMSIS_CORE + depends on SOC_FAMILY_SILABS_S2 + +config HAS_SILABS_WISECONNECT + bool + select HAS_CMSIS_CORE + depends on SOC_FAMILY_SILABS_SIWX91X config HAS_SILABS_SI32 bool select HAS_CMSIS_CORE + +rsource "*/Kconfig" diff --git a/modules/hal_silabs/simplicity_sdk/CMakeLists.txt b/modules/hal_silabs/simplicity_sdk/CMakeLists.txt index b59c14d11ed5a..04140171854e5 100644 --- a/modules/hal_silabs/simplicity_sdk/CMakeLists.txt +++ b/modules/hal_silabs/simplicity_sdk/CMakeLists.txt @@ -8,8 +8,10 @@ # SPDX-License-Identifier: Apache-2.0 set(EMLIB_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/emlib) +set(EMDRV_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/emdrv) set(COMMON_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/common) set(DEVICE_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/Device) +set(DRIVER_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/driver) set(RADIO_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/radio) set(SECURITY_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/security) set(SERVICE_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/service) @@ -27,19 +29,24 @@ string(SUBSTRING ${CONFIG_SOC_SERIES} 7 2 SILABS_DEVICE_FAMILY_NUMBER) set(SILABS_DEVICE_PART_NUMBER ${CONFIG_SOC_PART_NUMBER}) function(add_prebuilt_library lib_name prebuilt_path) - add_library(${lib_name} STATIC IMPORTED GLOBAL) - set_target_properties(${lib_name} PROPERTIES - IMPORTED_LOCATION ${BLOBS_DIR}/${prebuilt_path} - ) - zephyr_link_libraries(${lib_name}) + if(NOT CONFIG_BUILD_ONLY_NO_BLOBS) + add_library(${lib_name} STATIC IMPORTED GLOBAL) + set_target_properties(${lib_name} PROPERTIES + IMPORTED_LOCATION ${BLOBS_DIR}/${prebuilt_path} + ) + zephyr_link_libraries(${lib_name}) + endif() endfunction() if(CONFIG_SOC_GECKO_HAS_RADIO) zephyr_include_directories_ifdef(CONFIG_SOC_FAMILY_SILABS_S2 - ${RADIO_DIR}/rail_lib/plugin/pa-conversions/efr32xg${SILABS_DEVICE_FAMILY_NUMBER}/config ${RADIO_DIR}/rail_lib/chip/efr32/efr32xg2x ) + zephyr_compile_definitions( + SL_RAIL_UTIL_PA_CONFIG_HEADER="sl_rail_util_pa_config.h" + ) + zephyr_include_directories( ${RADIO_DIR}/rail_lib/common ${RADIO_DIR}/rail_lib/plugin/pa-conversions @@ -50,12 +57,14 @@ if(CONFIG_SOC_GECKO_HAS_RADIO) zephyr_library_sources_ifdef(CONFIG_BT_SILABS_EFR32 ${SECURITY_DIR}/sl_component/sl_protocol_crypto/src/sli_radioaes_management.c ${SECURITY_DIR}/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_radioaes.c + ${SECURITY_DIR}/sl_component/sli_crypto/src/sl_crypto_s2.c ) if(CONFIG_BT_SILABS_EFR32) # prebuilt libs - add_prebuilt_library(liblinklayer protocol/bluetooth/bgstack/ll/lib/libbluetooth_controller_efr32xg${SILABS_DEVICE_FAMILY_NUMBER}_gcc_release.a) + add_prebuilt_library(liblinklayer protocol/bluetooth/bgstack/ll/build/gcc/xg${SILABS_DEVICE_FAMILY_NUMBER}/release/liblinklayer.a) add_prebuilt_library(libbgcommon protocol/bluetooth/bgcommon/lib/build/gcc/cortex-m33/bgcommon/release/libbgcommon.a) + zephyr_library_sources(src/sl_btctrl_hci_reset_shim.c) # link mbedTLS if(CONFIG_MBEDTLS) @@ -90,6 +99,11 @@ zephyr_include_directories( ${DEVICE_DIR}/SiliconLabs/${SILABS_DEVICE_FAMILY}/Include ${COMMON_DIR}/config ${COMMON_DIR}/inc + ${DRIVER_DIR}/gpio/inc + ${EMDRV_DIR}/common/inc + ${EMDRV_DIR}/dmadrv/config/s2_8ch/ + ${EMDRV_DIR}/dmadrv/inc + ${EMDRV_DIR}/dmadrv/inc/s2_signals/ ${EMLIB_DIR}/inc ${PERIPHERAL_DIR}/inc ${SERVICE_DIR}/clock_manager/inc @@ -98,20 +112,25 @@ zephyr_include_directories( ${SERVICE_DIR}/hfxo_manager/config ${SERVICE_DIR}/hfxo_manager/inc ${SERVICE_DIR}/hfxo_manager/src + ${SERVICE_DIR}/interrupt_manager/inc ${SERVICE_DIR}/memory_manager/inc ${SERVICE_DIR}/memory_manager/profiler/inc ${SERVICE_DIR}/power_manager/config ${SERVICE_DIR}/power_manager/inc - ${SERVICE_DIR}/power_manager/src ${SERVICE_DIR}/sleeptimer/config ${SERVICE_DIR}/sleeptimer/inc ${SERVICE_DIR}/sleeptimer/src ${SECURITY_DIR}/sl_component/sl_protocol_crypto/src + ${SECURITY_DIR}/sl_component/sli_crypto/inc ${BOARD_DIR} ) zephyr_compile_definitions( ${SILABS_DEVICE_PART_NUMBER} + SL_CODE_COMPONENT_CLOCK_MANAGER=clock_manager + SL_CODE_COMPONENT_DEVICE_PERIPHERAL=peripheral + SL_CODE_COMPONENT_HAL_COMMON=hal_common + SL_CODE_COMPONENT_SYSTEM=system ) zephyr_library_sources( @@ -122,7 +141,6 @@ zephyr_library_sources( ${SERVICE_DIR}/clock_manager/src/sl_clock_manager_init.c ${SERVICE_DIR}/clock_manager/src/sl_clock_manager_init_hal_s2.c ${SERVICE_DIR}/device_manager/devices/sl_device_peripheral_hal_efr32xg${SILABS_DEVICE_FAMILY_NUMBER}.c - ${SERVICE_DIR}/device_manager/gpios/sl_device_gpio_common.c ${SERVICE_DIR}/device_manager/src/sl_device_clock.c ${SERVICE_DIR}/device_manager/src/sl_device_gpio.c ${SERVICE_DIR}/device_manager/src/sl_device_peripheral.c @@ -145,6 +163,8 @@ if(CONFIG_SOC_SILABS_SLEEPTIMER) ) zephyr_compile_definitions( SL_CATALOG_SLEEPTIMER_PRESENT + SL_CODE_COMPONENT_SLEEPTIMER=sleeptimer + SL_CODE_COMPONENT_HAL_SYSRTC=hal_sysrtc ) endif() @@ -162,11 +182,14 @@ endif() # Power Manager if(CONFIG_SOC_GECKO_PM_BACKEND_PMGR) zephyr_library_sources( - ${SERVICE_DIR}/power_manager/src/sl_power_manager.c - ${SERVICE_DIR}/power_manager/src/sl_power_manager_hal_s2.c + ${SERVICE_DIR}/power_manager/src/common/sl_power_manager_common.c + ${SERVICE_DIR}/power_manager/src/common/sl_power_manager_em4.c + ${SERVICE_DIR}/power_manager/src/sleep_loop/sl_power_manager.c + ${SERVICE_DIR}/power_manager/src/sleep_loop/sl_power_manager_hal_s2.c ) zephyr_compile_definitions( SL_CATALOG_POWER_MANAGER_PRESENT + SL_CODE_COMPONENT_POWER_MANAGER=power_manager ) zephyr_compile_definitions_ifdef(CONFIG_SOC_GECKO_RTCC SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT @@ -185,17 +208,37 @@ if(CONFIG_SOC_SILABS_HFXO_MANAGER) endif() zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_DEV_INIT ${COMMON_DIR}/src/sl_slist.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_CORE - ${EMLIB_DIR}/src/em_core.c - ${COMMON_DIR}/src/sl_core_cortexm.c -) +if(CONFIG_SOC_GECKO_CORE) + zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_CORE + ${EMLIB_DIR}/src/em_core.c + ${COMMON_DIR}/src/sl_core_cortexm.c + ) + zephyr_compile_definitions( + SL_CODE_COMPONENT_CORE=core + ) +endif() +zephyr_library_sources_ifdef(CONFIG_SOC_SILABS_ACMP ${EMLIB_DIR}/src/em_acmp.c) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_CRYOTIMER ${EMLIB_DIR}/src/em_cryotimer.c) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_EMU ${EMLIB_DIR}/src/em_emu.c) -zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_GPIO ${EMLIB_DIR}/src/em_gpio.c) +if(CONFIG_SOC_GECKO_GPIO) + zephyr_library_sources( + ${EMLIB_DIR}/src/em_gpio.c + ${DRIVER_DIR}/gpio/src/sl_gpio.c + ${PERIPHERAL_DIR}/src/sl_hal_gpio.c + ) + zephyr_library_compile_definitions( + SL_CATALOG_GPIO_PRESENT + SL_CODE_COMPONENT_HAL_GPIO=hal_gpio + ) +endif() + +zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_LDMA ${EMDRV_DIR}/dmadrv/src/dmadrv.c) + zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_I2C ${EMLIB_DIR}/src/em_i2c.c) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_LETIMER ${EMLIB_DIR}/src/em_letimer.c) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_LEUART ${EMLIB_DIR}/src/em_leuart.c) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_MSC ${EMLIB_DIR}/src/em_msc.c) +zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_LDMA ${EMLIB_DIR}/src/em_ldma.c) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_PRS ${EMLIB_DIR}/src/em_prs.c) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_RMU ${EMLIB_DIR}/src/em_rmu.c) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_RTC ${EMLIB_DIR}/src/em_rtc.c) @@ -208,17 +251,33 @@ zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_WDOG ${EMLIB_DIR}/src/em_w zephyr_include_directories_ifdef(CONFIG_SOC_GECKO_SE ${SECURITY_DIR}/sl_component/se_manager/src ${SECURITY_DIR}/sl_component/se_manager/inc + ${SECURITY_DIR}/sl_component/sli_psec_osal/inc ) zephyr_library_sources_ifdef(CONFIG_SOC_GECKO_SE - ${EMLIB_DIR}/src/em_se.c ${SECURITY_DIR}/sl_component/se_manager/src/sl_se_manager.c ${SECURITY_DIR}/sl_component/se_manager/src/sl_se_manager_util.c ${SECURITY_DIR}/sl_component/se_manager/src/sli_se_manager_mailbox.c ) +zephyr_compile_definitions_ifdef(CONFIG_SOC_GECKO_SE + SL_CODE_COMPONENT_SE_MANAGER=se_manager + SL_CODE_COMPONENT_PSEC_OSAL=psec_osal +) + zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_SE ${SECURITY_DIR}/sl_component/se_manager/src/sl_se_manager_entropy.c ) -zephyr_library_sources(src/sl_memory_manager_shim.c) +zephyr_library_sources( + src/sl_interrupt_manager_shim.c + src/sl_memory_manager_shim.c +) + +zephyr_library_sources_ifdef( + CONFIG_BUILD_ONLY_NO_BLOBS + src/blob_stubs.c +) + +zephyr_linker_sources(ROM_SECTIONS linker/code_classification_text.ld) +zephyr_linker_sources(RAMFUNC_SECTION linker/code_classification_ramfunc.ld) diff --git a/modules/hal_silabs/simplicity_sdk/Kconfig b/modules/hal_silabs/simplicity_sdk/Kconfig new file mode 100644 index 0000000000000..7d2c8fcfa4b62 --- /dev/null +++ b/modules/hal_silabs/simplicity_sdk/Kconfig @@ -0,0 +1,31 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +menu "SiSDK configuration" + depends on HAS_SILABS_SISDK + +config RAIL_PA_CURVE_HEADER + string "RAIL PA custom curve header file" + default "pa_curves_efr32.h" + help + Name of custom PA curve header file for use by PA initialization. + See AN1127 for information on how to create a custom PA curve. + The header file must be available on the include path. + +config RAIL_PA_CURVE_TYPES_HEADER + string "RAIL PA curve types header file" + default "pa_curve_types_efr32.h" + help + Name of custom PA curve type header file for use by PA initialization. + See AN1127 for information on how to create a custom PA curve. + The header file must be available on the include path. + +config RAIL_PA_ENABLE_CALIBRATION + bool "RAIL PA: apply factory calibration offset" + default y + help + Ensure that the PA power remains constant chip-to-chip by applying factory + calibration. This option is enabled by default, and is recommended for all + Series 2 devices. + +endmenu diff --git a/modules/hal_silabs/simplicity_sdk/config/sl_rail_util_pa_config.h b/modules/hal_silabs/simplicity_sdk/config/sl_rail_util_pa_config.h new file mode 100644 index 0000000000000..9d3edccb05996 --- /dev/null +++ b/modules/hal_silabs/simplicity_sdk/config/sl_rail_util_pa_config.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * This configuration header is used by the HAL driver rail_util_pa from hal_silabs, + * invoked through the init function of the hci_silabs_efr32 Bluetooth driver. + * DeviceTree and Kconfig options are converted to config macros expected by the HAL driver. + */ + +#ifndef SL_RAIL_UTIL_PA_CONFIG_H +#define SL_RAIL_UTIL_PA_CONFIG_H + +#include +#include "rail_types.h" + +#define SL_RAIL_UTIL_PA_POWER_DECI_DBM (DT_PROP(DT_NODELABEL(radio), pa_initial_power_dbm) * 10) +#define SL_RAIL_UTIL_PA_RAMP_TIME_US DT_PROP(DT_NODELABEL(radio), pa_ramp_time_us) +#define SL_RAIL_UTIL_PA_VOLTAGE_MV DT_PROP(DT_NODELABEL(radio), pa_voltage_mv) + +#if DT_NODE_HAS_PROP(DT_NODELABEL(radio), pa_2p4ghz) +#define SL_RAIL_UTIL_PA_SELECTION_2P4GHZ \ + CONCAT(RAIL_TX_POWER_MODE_2P4GIG_, DT_STRING_UPPER_TOKEN(DT_NODELABEL(radio), pa_2p4ghz)) +#else +#define SL_RAIL_UTIL_PA_SELECTION_2P4GHZ RAIL_TX_POWER_MODE_NONE +#endif + +#if DT_NODE_HAS_PROP(DT_NODELABEL(radio), pa_subghz) +#define SL_RAIL_UTIL_PA_SELECTION_SUBGHZ \ + CONCAT(RAIL_TX_POWER_MODE_SUBGIG_, DT_STRING_UPPER_TOKEN(DT_NODELABEL(radio), pa_subghz)) +#else +#define SL_RAIL_UTIL_PA_SELECTION_SUBGHZ RAIL_TX_POWER_MODE_NONE +#endif + +#define SL_RAIL_UTIL_PA_CURVE_HEADER CONFIG_RAIL_PA_CURVE_HEADER +#define SL_RAIL_UTIL_PA_CURVE_TYPES CONFIG_RAIL_PA_CURVE_TYPES_HEADER +#define SL_RAIL_UTIL_PA_CALIBRATION_ENABLE CONFIG_RAIL_PA_ENABLE_CALIBRATION + +#endif /* SL_RAIL_UTIL_PA_CONFIG_H */ diff --git a/modules/hal_silabs/simplicity_sdk/linker/code_classification_ramfunc.ld b/modules/hal_silabs/simplicity_sdk/linker/code_classification_ramfunc.ld new file mode 100644 index 0000000000000..3a55e17a098ba --- /dev/null +++ b/modules/hal_silabs/simplicity_sdk/linker/code_classification_ramfunc.ld @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Place data annotated as ramfunc into the Zephyr .ramfunc section. + */ + +*(text_application_ram) diff --git a/modules/hal_silabs/simplicity_sdk/linker/code_classification_text.ld b/modules/hal_silabs/simplicity_sdk/linker/code_classification_text.ld new file mode 100644 index 0000000000000..d8596a6333096 --- /dev/null +++ b/modules/hal_silabs/simplicity_sdk/linker/code_classification_text.ld @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Place text sections tagged with Silicon Labs code classification annotations into flash. + */ + +SECTION_PROLOGUE(.cc_text,,) +{ + _cc_text_start = .; + *(SORT_BY_ALIGNMENT(text_*[0-9])) + _cc_text_end = .; +} GROUP_LINK_IN(ROMABLE_REGION) +_cc_text_size = _cc_text_end - _cc_text_start; diff --git a/modules/hal_silabs/simplicity_sdk/src/blob_stubs.c b/modules/hal_silabs/simplicity_sdk/src/blob_stubs.c new file mode 100644 index 0000000000000..ad06b11d61ea5 --- /dev/null +++ b/modules/hal_silabs/simplicity_sdk/src/blob_stubs.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Empty function stubs to enable building with CONFIG_BUILD_ONLY_NO_BLOBS. + */ + +#include +#include + +#include + +struct RAIL_TxPowerCurvesConfigAlt { +}; + +void RAIL_VerifyTxPowerCurves(const struct RAIL_TxPowerCurvesConfigAlt *config) +{ +} + +void RAIL_EnablePaCal(bool enable) +{ +} + +int16_t sl_btctrl_hci_receive(uint8_t *data, int16_t len, bool lastFragment) +{ + return 0; +} + +void BTLE_LL_Process(uint32_t events) +{ +} + +int16_t BTLE_LL_SetMaxPower(int16_t power) +{ + return 0; +} + +void sl_btctrl_disable_2m_phy(void) +{ +} + +void sl_btctrl_disable_coded_phy(void) +{ +} + +uint32_t sl_btctrl_init_mem(uint32_t memsize) +{ + return 0; +} + +void sl_btctrl_configure_le_buffer_size(uint8_t count) +{ +} + +sl_status_t sl_btctrl_init_ll(void) +{ + return SL_STATUS_NOT_AVAILABLE; +} + +void sli_btctrl_deinit_mem(void) +{ +} + +void sl_btctrl_init_adv(void) +{ +} + +void sl_btctrl_init_adv_ext(void) +{ +} + +void sl_btctrl_init_scan(void) +{ +} + +void sl_btctrl_init_scan_ext(void) +{ +} + +void sl_btctrl_init_conn(void) +{ +} + +void sl_btctrl_init_phy(void) +{ +} + +void sl_btctrl_init_basic(void) +{ +} + +void sl_btctrl_configure_completed_packets_reporting(uint8_t packets, uint8_t events) +{ +} + +void sl_bthci_init_upper(void) +{ +} + +void sl_btctrl_hci_parser_init_default(void) +{ +} + +void sl_btctrl_hci_parser_init_conn(void) +{ +} + +void sl_btctrl_hci_parser_init_adv(void) +{ +} + +void sl_btctrl_hci_parser_init_phy(void) +{ +} + +void sl_bthci_init_vs(void) +{ +} + +void AGC_IRQHandler(void) +{ +} + +void BUFC_IRQHandler(void) +{ +} + +void FRC_IRQHandler(void) +{ +} + +void MODEM_IRQHandler(void) +{ +} + +void PROTIMER_IRQHandler(void) +{ +} + +void RAC_RSM_IRQHandler(void) +{ +} + +void RAC_SEQ_IRQHandler(void) +{ +} + +void SYNTH_IRQHandler(void) +{ +} + +void RDMAILBOX_IRQHandler(void) +{ +} diff --git a/modules/hal_silabs/simplicity_sdk/src/sl_btctrl_hci_reset_shim.c b/modules/hal_silabs/simplicity_sdk/src/sl_btctrl_hci_reset_shim.c new file mode 100644 index 0000000000000..4ba10cdfb89ed --- /dev/null +++ b/modules/hal_silabs/simplicity_sdk/src/sl_btctrl_hci_reset_shim.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Shim for sl_btctrl_hci_reset API + */ + +#include + +bool sl_btctrl_hci_reset_reason_is_sys_reset(void) +{ + /* If this function returns true, the LL will emit command complete for HCI Reset during + * init. This only makes sense when the LL runs on a separate device from the host stack. + * Always return false. + */ + return false; +} + +void sl_btctrl_hci_reset(void) +{ + /* This function works as a callback during processing of the HCI Reset command, and allows + * for custom processing (such as fully resetting the device). This only makes sense when + * the LL runs on a separate device from the host stack. Do nothing. + */ +} diff --git a/modules/hal_silabs/simplicity_sdk/src/sl_interrupt_manager_shim.c b/modules/hal_silabs/simplicity_sdk/src/sl_interrupt_manager_shim.c new file mode 100644 index 0000000000000..8f6bd5092d12e --- /dev/null +++ b/modules/hal_silabs/simplicity_sdk/src/sl_interrupt_manager_shim.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Shim for sl_interrupt_manager API using Zephyr API + */ + +#include + +#include "sl_interrupt_manager.h" + +#define LOCK_KEY_DEFAULT 0xFFFFFFFFU + +static unsigned int lock_key = LOCK_KEY_DEFAULT; + +void sl_interrupt_manager_disable_interrupts(void) +{ + __ASSERT(lock_key == LOCK_KEY_DEFAULT, "Interrupt manager doesn't support nested disable"); + lock_key = irq_lock(); +} + +void sl_interrupt_manager_enable_interrupts(void) +{ + irq_unlock(lock_key); + lock_key = LOCK_KEY_DEFAULT; +} + +void sl_interrupt_manager_disable_irq(int32_t irqn) +{ + irq_disable(irqn); +} + +void sl_interrupt_manager_enable_irq(int32_t irqn) +{ + irq_enable(irqn); +} + +bool sl_interrupt_manager_is_irq_disabled(int32_t irqn) +{ + return !irq_is_enabled(irqn); +} + +bool sl_interrupt_manager_is_irq_pending(int32_t irqn) +{ + return NVIC_GetPendingIRQ(irqn); +} + +void sl_interrupt_manager_set_irq_pending(int32_t irqn) +{ + NVIC_SetPendingIRQ(irqn); +} + +void sl_interrupt_manager_clear_irq_pending(int32_t irqn) +{ + NVIC_ClearPendingIRQ(irqn); +} + +uint32_t sl_interrupt_manager_get_irq_priority(int32_t irqn) +{ + return NVIC_GetPriority(irqn); +} + +void sl_interrupt_manager_set_irq_priority(int32_t irqn, uint32_t priority) +{ + NVIC_SetPriority(irqn, priority); +} + +uint32_t sl_interrupt_manager_get_active_irq(int32_t irqn) +{ + return NVIC_GetActive(irqn); +} diff --git a/modules/hal_silabs/wiseconnect/CMakeLists.txt b/modules/hal_silabs/wiseconnect/CMakeLists.txt new file mode 100644 index 0000000000000..a7f83f6d7c76b --- /dev/null +++ b/modules/hal_silabs/wiseconnect/CMakeLists.txt @@ -0,0 +1,149 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +set(SISDK_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk) +set(WISECONNECT_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/wiseconnect) + +# Keep these values sync with +# components/device/silabs/si91x/mcu/core/chip/component/siwg917*.slcc +zephyr_compile_definitions( + SL_SI91X_ENABLE_LITTLE_ENDIAN + SLI_SI91X_MCU_COMMON_FLASH_MODE + SLI_SI91X_MCU_CONFIG_RADIO_BOARD_VER2 + SLI_SI91X_MCU_CONFIG_RADIO_BOARD_BASE_VER + SLI_SI91X_MCU_ENABLE_FLASH_BASED_EXECUTION + SLI_SI91X_MCU_ENABLE_IPMU_APIS + SLI_SI91X_MCU_INTERFACE + SLI_SI917 + SLI_SI917B0 + CLOCK_ROMDRIVER_PRESENT +) + +zephyr_include_directories( + ${SISDK_DIR}/platform/common/inc + ${SISDK_DIR}/platform/common/config + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/config + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/rom_driver/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_peripheral_drivers/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/config + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/CMSIS/Driver/Include +) + +zephyr_library_sources( + ${SISDK_DIR}/platform/common/src/sl_core_cortexm.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/src/rsi_deepsleep_soc.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/src/system_si91x.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/clock_update.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_ipmu.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_pll.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_ulpss_clk.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/src/sl_si91x_clock_manager.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_driver_gpio.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_peripheral_drivers/src/sl_si91x_peripheral_gpio.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/src/iPMU_prog/iPMU_dotc/ipmu_apis.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/src/iPMU_prog/iPMU_dotc/rsi_system_config_917.c +) + +zephyr_library_sources_ifdef(CONFIG_ENTROPY_SILABS_SIWX91X + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_rng.c +) + +zephyr_compile_definitions_ifdef(CONFIG_DMA_SILABS_SIWX91X + UDMA_ROMDRIVER_PRESENT +) + +zephyr_library_sources_ifdef(CONFIG_DMA_SILABS_SIWX91X + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/rom_driver/src/rsi_rom_table_si91x.c +) + +if(CONFIG_WIFI_SILABS_SIWX91X) + zephyr_library_sources( + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/sl_net/src/sl_si91x_net_credentials.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/sl_net/src/sl_si91x_net_internal_stack.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/sl_net/src/sl_net_si91x_integration_handler.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/sl_net/src/sl_net_rsi_utility.c + ${WISECONNECT_DIR}/components/protocol/wifi/src/sl_wifi_basic_credentials.c + ${WISECONNECT_DIR}/components/service/network_manager/si91x/sl_net_si91x.c + ${WISECONNECT_DIR}/components/service/network_manager/src/sl_net_basic_profiles.c + ${WISECONNECT_DIR}/components/service/network_manager/src/sl_net_credentials.c + ) + zephyr_compile_definitions_ifdef(CONFIG_NET_IPV6 + SLI_SI91X_ENABLE_IPV6 + ) + zephyr_compile_definitions_ifdef(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD + SLI_SI91X_OFFLOAD_NETWORK_STACK + SLI_SI91X_SOCKETS + ) + zephyr_include_directories_ifdef(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD + # Needed for + ${ZEPHYR_BASE}/include/zephyr/posix + ) + zephyr_library_sources_ifdef(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/socket/src/sl_si91x_socket_utility.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/asynchronous_socket/src/sl_si91x_socket.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/sl_net/src/sl_net_si91x_callback_framework.c + ${WISECONNECT_DIR}/components/service/network_manager/src/sl_net.c + ) +endif() # CONFIG_WIFI_SILABS_SIWX91X + +if(CONFIG_BT_SILABS_SIWX91X) + zephyr_compile_definitions( + SLI_SI91X_ENABLE_BLE + ) + zephyr_include_directories( + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ble/inc + ) + zephyr_library_sources( + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ble/src/rsi_bt_ble.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ble/src/rsi_common_apis.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ble/src/rsi_utils.c + ) +endif() # CONFIG_BT_SILABS_SIWX91X + +if(CONFIG_WISECONNECT_NETWORK_STACK) + zephyr_compile_definitions( + SLI_SI91X_ENABLE_OS + SL_SI91X_SI917_RAM_MEM_CONFIG=1 + SL_WIFI_COMPONENT_INCLUDED # Depite de the name, required for everything + ) + zephyr_include_directories( + # FIXME: find why this directory is not included when CMSIS_RTOS_V2=y + ${ZEPHYR_BASE}/include/zephyr/portability + ${SISDK_DIR}/platform/emlib/inc + ${WISECONNECT_DIR}/resources/defaults + ${WISECONNECT_DIR}/components/common/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/sl_net/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/socket/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/asynchronous_socket/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/inc + ${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/config + ${WISECONNECT_DIR}/components/protocol/wifi/inc + ${WISECONNECT_DIR}/components/service/network_manager/inc + ) + zephyr_library_sources( + ${WISECONNECT_DIR}/components/common/src/sl_utility.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/rsi_hal_mcu_m4_ram.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/rsi_hal_mcu_m4_rom.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/sli_siwx917_soc.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/sl_platform.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/sl_platform_wireless.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/sl_si91x_bus.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/host_mcu/si91x/siwx917_soc_ncp_host.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/memory/malloc_buffers.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/src/sl_rsi_utility.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/src/sl_si91x_driver.c + ${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/threading/sli_si91x_multithreaded.c + ${WISECONNECT_DIR}/components/protocol/wifi/si91x/sl_wifi.c + ${WISECONNECT_DIR}/components/protocol/wifi/src/sl_wifi_callback_framework.c + ) +endif() # CONFIG_WISECONNECT_NETWORK_STACK + +zephyr_linker_sources(ROM_SECTIONS linker/code_classification_text.ld) +zephyr_linker_sources(RAMFUNC_SECTION linker/code_classification_ramfunc.ld) diff --git a/modules/hal_silabs/wiseconnect/linker/code_classification_ramfunc.ld b/modules/hal_silabs/wiseconnect/linker/code_classification_ramfunc.ld new file mode 100644 index 0000000000000..3a55e17a098ba --- /dev/null +++ b/modules/hal_silabs/wiseconnect/linker/code_classification_ramfunc.ld @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Place data annotated as ramfunc into the Zephyr .ramfunc section. + */ + +*(text_application_ram) diff --git a/modules/hal_silabs/wiseconnect/linker/code_classification_text.ld b/modules/hal_silabs/wiseconnect/linker/code_classification_text.ld new file mode 100644 index 0000000000000..d8596a6333096 --- /dev/null +++ b/modules/hal_silabs/wiseconnect/linker/code_classification_text.ld @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Place text sections tagged with Silicon Labs code classification annotations into flash. + */ + +SECTION_PROLOGUE(.cc_text,,) +{ + _cc_text_start = .; + *(SORT_BY_ALIGNMENT(text_*[0-9])) + _cc_text_end = .; +} GROUP_LINK_IN(ROMABLE_REGION) +_cc_text_size = _cc_text_end - _cc_text_start; diff --git a/modules/hal_st/Kconfig b/modules/hal_st/Kconfig index 579f7f7d3f8c8..43a8320e13bb4 100644 --- a/modules/hal_st/Kconfig +++ b/modules/hal_st/Kconfig @@ -96,6 +96,9 @@ config USE_STDC_LIS2DU12 config USE_STDC_LIS2DUX12 bool +config USE_STDC_LIS2DUXS12 + bool + config USE_STDC_LIS2DW12 bool diff --git a/modules/hal_tdk/Kconfig b/modules/hal_tdk/Kconfig new file mode 100644 index 0000000000000..0e876177010b5 --- /dev/null +++ b/modules/hal_tdk/Kconfig @@ -0,0 +1,33 @@ +# Copyright (c) 2024 TDK Invensense +# SPDX-License-Identifier: Apache-2.0 + +config ZEPHYR_HAL_TDK_MODULE + bool + +menu "TDK drivers" + +config TDK_HAL + bool "TDK HAL drivers support" + +config USE_EMD_ICM42670 + bool "ICM42x7x High Performance 6-Axis MotionTracking IMU" + default y + imply TDK_HAL + depends on ZEPHYR_HAL_TDK_MODULE + depends on DT_HAS_INVENSENSE_ICM42670P_ENABLED \ + || DT_HAS_INVENSENSE_ICM42670S_ENABLED + +config USE_EMD_ICM42370 + bool "ICM42370P High Performance 3-Axis MotionTracking Accelerometer" + default y + imply TDK_HAL + depends on ZEPHYR_HAL_TDK_MODULE + depends on DT_HAS_INVENSENSE_ICM42370P_ENABLED + +config USE_EMD_ICP101XX + bool "ICP101XX Barometric Pressure and Temperature Sensors" + imply TDK_HAL + depends on ZEPHYR_HAL_TDK_MODULE + depends on DT_HAS_INVENSENSE_ICP101XX_ENABLED + +endmenu diff --git a/modules/hal_wch/CMakeLists.txt b/modules/hal_wch/CMakeLists.txt index 729bc4035675c..822f83b867b29 100644 --- a/modules/hal_wch/CMakeLists.txt +++ b/modules/hal_wch/CMakeLists.txt @@ -1,3 +1,3 @@ -if(CONFIG_SOC_SERIES_CH32V00X) +if(CONFIG_SOC_CH32V003) zephyr_include_directories(${ZEPHYR_HAL_WCH_MODULE_DIR}/ch32v003fun .) endif() diff --git a/modules/hostap/CMakeLists.txt b/modules/hostap/CMakeLists.txt index cfb10bb23599c..3e0bc2ddc4c8a 100644 --- a/modules/hostap/CMakeLists.txt +++ b/modules/hostap/CMakeLists.txt @@ -58,20 +58,16 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_NO_DEBUG CONFIG_NO_STDOUT_DEBUG ) -zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_ROBUST_AV - CONFIG_ROBUST_AV +zephyr_library_compile_definitions_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_ROBUST_AV + CONFIG_NO_ROBUST_AV ) -zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WMM_AC - CONFIG_WMM_AC +zephyr_library_compile_definitions_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WMM_AC +CONFIG_NO_WMM_AC ) -zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_RRM - CONFIG_RRM -) - -zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_ROBUST_AV - CONFIG_ROBUST_AV +zephyr_library_compile_definitions_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_RRM +CONFIG_NO_RRM ) zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_MBO @@ -133,6 +129,9 @@ zephyr_library_sources( ${WIFI_NM_WPA_SUPPLICANT_BASE}/ctrl_iface_zephyr.c ${WIFI_NM_WPA_SUPPLICANT_BASE}/wpa_cli_zephyr.c + ${HOSTAP_SRC_BASE}/rsn_supp/pmksa_cache.c + ${HOSTAP_SRC_BASE}/common/ptksa_cache.c + # Zephyr specific files (glue code) src/supp_main.c src/supp_api.c @@ -184,6 +183,7 @@ zephyr_library_sources( ${HOSTAP_SRC_BASE}/ap/hw_features.c ${HOSTAP_SRC_BASE}/ap/ieee802_11_auth.c ${HOSTAP_SRC_BASE}/ap/ieee802_11.c + ${HOSTAP_SRC_BASE}/ap/comeback_token.c ${HOSTAP_SRC_BASE}/ap/ieee802_11_ht.c ${HOSTAP_SRC_BASE}/ap/ieee802_11_shared.c ${HOSTAP_SRC_BASE}/ap/ieee802_11_vht.c @@ -208,12 +208,15 @@ zephyr_library_sources( ${HOSTAP_SRC_BASE}/eap_server/eap_server_identity.c ${HOSTAP_SRC_BASE}/eap_server/eap_server_methods.c ${HOSTAP_SRC_BASE}/eapol_auth/eapol_auth_sm.c - ${HOSTAP_SRC_BASE}/ap/mbo_ap.c ${HOSTAP_SRC_BASE}/ap/ctrl_iface_ap.c ${HOSTAP_SRC_BASE}/utils/crc32.c ${HOSTAP_SRC_BASE}/utils/ip_addr.c ) +if (CONFIG_WIFI_NM_WPA_SUPPLICANT_MBO) + zephyr_library_sources(${HOSTAP_SRC_BASE}/ap/mbo_ap.c) +endif() + zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX ${HOSTAP_SRC_BASE}/ap/ieee802_11_he.c ) @@ -380,6 +383,8 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_HOSTAPD_WPS zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE ${HOSTAP_SRC_BASE}/eap_common/eap_common.c + ${HOSTAP_SRC_BASE}/eap_peer/eap_tls_common.c + ) zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE @@ -389,7 +394,6 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_EN zephyr_library_sources_ifdef(CONFIG_EAP_TLS ${HOSTAP_SRC_BASE}/eap_peer/eap_tls.c - ${HOSTAP_SRC_BASE}/eap_peer/eap_tls_common.c ) zephyr_library_compile_definitions_ifdef(CONFIG_EAP_TLS @@ -438,7 +442,7 @@ zephyr_library_compile_definitions_ifdef(CONFIG_EAP_MSCHAPV2 EAP_MSCHAPv2 ) -if(CONFIG_EAP_TTLS OR CONFIG_EAP_MSCHAPV2) +if(CONFIG_EAP_TTLS OR CONFIG_EAP_MSCHAPV2 OR CONFIG_EAP_MD5) zephyr_library_sources(${HOSTAP_SRC_BASE}/eap_common/chap.c) endif() @@ -515,9 +519,12 @@ zephyr_library_compile_definitions_ifdef(CONFIG_EAP_IKEV2 EAP_IKEV2 ) +if (CONFIG_EAP_SIM OR CONFIG_EAP_AKA) + zephyr_library_sources(${HOSTAP_SRC_BASE}/eap_common/eap_sim_common.c) +endif() + zephyr_library_sources_ifdef(CONFIG_EAP_SIM ${HOSTAP_SRC_BASE}/eap_peer/eap_sim.c - ${HOSTAP_SRC_BASE}/eap_common/eap_sim_common.c ) zephyr_library_compile_definitions_ifdef(CONFIG_EAP_SIM @@ -554,16 +561,11 @@ zephyr_library_compile_definitions_ifdef(CONFIG_EAP_FAST EAP_FAST ) -zephyr_library_compile_definitions_ifndef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE - CONFIG_NO_CONFIG_BLOBS -) - zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_EAPOL ${HOSTAP_SRC_BASE}/eapol_supp/eapol_supp_sm.c ${HOSTAP_SRC_BASE}/eap_peer/eap.c ${HOSTAP_SRC_BASE}/eap_peer/eap_methods.c ${HOSTAP_SRC_BASE}/eap_common/eap_common.c - ${HOSTAP_SRC_BASE}/rsn_supp/pmksa_cache.c ) zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_EAPOL @@ -668,48 +670,6 @@ zephyr_library_compile_definitions_ifdef(CONFIG_EAP_SERVER_TTLS EAP_SERVER_TTLS ) -# crypto mbedtls related -if(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO) -zephyr_library_sources( - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-bignum.c - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls-ec.c - ${HOSTAP_SRC_BASE}/crypto/crypto_mbedtls.c - ${HOSTAP_SRC_BASE}/crypto/aes-internal.c - ${HOSTAP_SRC_BASE}/crypto/aes-wrap.c - ${HOSTAP_SRC_BASE}/crypto/aes-unwrap.c - ${HOSTAP_SRC_BASE}/crypto/rc4.c - ${HOSTAP_SRC_BASE}/crypto/sha1-internal.c - ${HOSTAP_SRC_BASE}/crypto/sha1-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha1-tlsprf.c - ${HOSTAP_SRC_BASE}/crypto/sha256-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha256-kdf.c - ${HOSTAP_SRC_BASE}/crypto/sha384-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha384-kdf.c - ${HOSTAP_SRC_BASE}/crypto/sha512-internal.c - ${HOSTAP_SRC_BASE}/crypto/sha512.c - ${HOSTAP_SRC_BASE}/crypto/sha512-prf.c - ${HOSTAP_SRC_BASE}/crypto/sha512-kdf.c -) - -zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPA3 - ${HOSTAP_SRC_BASE}/crypto/sha256-kdf.c -) - -zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE - # common - ${HOSTAP_SRC_BASE}/crypto/sha384-tlsprf.c - ${HOSTAP_SRC_BASE}/crypto/sha256-tlsprf.c - ${HOSTAP_SRC_BASE}/crypto/sha1-tlsprf.c - ${HOSTAP_SRC_BASE}/crypto/sha1-tprf.c - ${HOSTAP_SRC_BASE}/crypto/ms_funcs.c - ${HOSTAP_SRC_BASE}/crypto/aes-eax.c - # MD4 removed from MbedTLS - ${HOSTAP_SRC_BASE}/crypto/md4-internal.c - ${HOSTAP_SRC_BASE}/crypto/aes-encblock.c - ${HOSTAP_SRC_BASE}/crypto/tls_mbedtls.c -) -endif() - if(CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT) zephyr_include_directories( ${HOSTAP_BASE}/port/mbedtls diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index d61cdce704e1b..eef7d9391abc3 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -24,20 +24,18 @@ config WIFI_NM_WPA_SUPPLICANT if WIFI_NM_WPA_SUPPLICANT config HEAP_MEM_POOL_ADD_SIZE_HOSTAP - def_int 85000 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE && !MBEDTLS_ENABLE_HEAP - def_int 40000 if WIFI_NM_WPA_SUPPLICANT_AP || WIFI_NM_HOSTAPD_AP - # 8192 for MbedTLS heap - def_int 21808 if MBEDTLS_ENABLE_HEAP + def_int 66560 if WIFI_NM_HOSTAPD_AP + def_int 41808 if WIFI_NM_WPA_SUPPLICANT_AP || WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE # 30K is mandatory, but might need more for long duration use cases def_int 30000 config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE int "Stack size for wpa_supplicant thread" - default 8192 + default 5600 config WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE int "Stack size for wpa_supplicant iface workqueue" - default 6144 + default 4400 config WIFI_NM_WPA_SUPPLICANT_WQ_PRIO int "Thread priority of wpa_supplicant iface workqueue" @@ -67,7 +65,7 @@ config WIFI_NM_WPA_SUPPLICANT_DEBUG_LEVEL default 3 if WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_INF # MSG_INFO default 4 if WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_WRN # MSG_WARNING default 5 if WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_ERR # MSG_ERROR - default 6 + default 5 help Minimum priority level of a debug message emitted by WPA supplicant that is compiled-in the firmware. See wpa_debug.h file of the supplicant for @@ -75,10 +73,19 @@ config WIFI_NM_WPA_SUPPLICANT_DEBUG_LEVEL runtime filtering can also be configured in addition to the compile-time filtering. +if WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_DBG +# hostap debug is very verbose and despite large log buffer sizes +# log messages can be lost. So, we set the log mode to immediate +# to avoid losing any debug messages. +choice LOG_MODE + default LOG_MODE_IMMEDIATE +endchoice +endif # WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_DBG + # Memory optimizations config WIFI_NM_WPA_SUPPLICANT_ADVANCED_FEATURES bool "Advanced features" - default y + default y if !SOC_FAMILY_NORDIC_NRF if WIFI_NM_WPA_SUPPLICANT_ADVANCED_FEATURES @@ -115,27 +122,6 @@ choice WIFI_NM_WPA_SUPPLICANT_CRYPTO_BACKEND WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT supports enterprise mode and DPP. -config WIFI_NM_WPA_SUPPLICANT_CRYPTO - bool "Crypto support for WiFi" - select MBEDTLS - select MBEDTLS_SHA1 - select MBEDTLS_CIPHER - select MBEDTLS_CIPHER_MODE_CTR_ENABLED - select MBEDTLS_CIPHER_MODE_CBC_ENABLED - select MBEDTLS_CIPHER_AES_ENABLED - select MBEDTLS_ECP_C - select MBEDTLS_ECP_ALL_ENABLED - select MBEDTLS_CMAC - select MBEDTLS_PKCS5_C - select MBEDTLS_PK_WRITE_C - select MBEDTLS_ECDH_C - select MBEDTLS_ECDSA_C - select MBEDTLS_ECJPAKE_C - select MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - select MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - select MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - select MBEDTLS_KEY_EXCHANGE_ALL_ENABLED - config WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT bool "Crypto Mbedtls alt support for WiFi" select MBEDTLS @@ -175,6 +161,23 @@ endchoice config WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA bool "Crypto Platform Secure Architecture support for WiFi" + imply MBEDTLS_PSA_CRYPTO_C + select MBEDTLS_USE_PSA_CRYPTO + select PSA_WANT_ALG_ECDH + select PSA_WANT_ALG_HMAC + select PSA_WANT_ALG_CCM + select PSA_WANT_ALG_CTR + select PSA_WANT_ALG_MD5 + select PSA_WANT_ALG_SHA_1 + select PSA_WANT_ALG_SHA_256 + select PSA_WANT_ALG_SHA_224 + select PSA_WANT_ALG_SHA_384 + select PSA_WANT_ALG_SHA_512 + select PSA_WANT_ALG_PBKDF2_HMAC + select PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 + select PSA_WANT_KEY_TYPE_AES + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY help Support Mbedtls 3.x to use PSA apis instead of legacy apis. @@ -275,7 +278,6 @@ config WIFI_NM_WPA_SUPPLICANT_EAPOL config WIFI_NM_WPA_SUPPLICANT_CLI bool "CLI support for wpa_supplicant" - default n config WIFI_NM_WPA_SUPPLICANT_INF_MON bool "Monitor the net mgmt event to add/del interface" @@ -312,6 +314,10 @@ config EAP_SERVER_TTLS config EAP_SERVER_ALL bool "All EAP methods support" select EAP_SERVER_TLS + select EAP_SERVER_MSCHAPV2 + select EAP_SERVER_PEAP + select EAP_SERVER_GTC + select EAP_SERVER_TTLS default y if WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE config WIFI_NM_WPA_SUPPLICANT_BSS_MAX_IDLE_TIME @@ -335,7 +341,6 @@ config WIFI_NM_WPA_SUPPLICANT_DPP bool "WFA Easy Connect DPP" select DPP select DPP2 - select DPP3 select GAS select GAS_SERVER select OFFCHANNEL @@ -349,6 +354,7 @@ config WIFI_NM_WPA_SUPPLICANT_11AX config WPA_CLI bool "WPA CLI support" + default y if WIFI_NM_WPA_SUPPLICANT_CLI help Enable WPA CLI support for wpa_supplicant. @@ -509,17 +515,13 @@ config WPA_CRYPTO config WPA_SUPP_CRYPTO bool -config ROBUST_AV +config NO_ROBUST_AV bool - default y - depends on WIFI_NM_WPA_SUPPLICANT_ROBUST_AV -config RRM +config NO_RRM bool - default y - depends on WIFI_NM_WPA_SUPPLICANT_RRM -config WMM_AC +config NO_WMM_AC bool config DPP diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 2fecad1c3c928..ce28c0a1d5748 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -13,6 +13,8 @@ #include "includes.h" #include "common.h" #include "common/defs.h" +#include "common/ieee802_11_defs.h" +#include "common/ieee802_11_common.h" #include "wpa_supplicant/config.h" #include "wpa_supplicant_i.h" #include "driver_i.h" @@ -25,7 +27,11 @@ #include "hostapd_cli_zephyr.h" #include "ap_drv_ops.h" #endif +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE +#include "eap_peer/eap.h" +#endif #include "supp_events.h" +#include "wpa_supplicant/bss.h" extern struct k_sem wpa_supplicant_ready_sem; extern struct wpa_global *global; @@ -359,13 +365,77 @@ static inline enum wifi_frequency_bands wpas_band_to_zephyr(enum wpa_radio_work_ } } -static inline enum wifi_security_type wpas_key_mgmt_to_zephyr(int key_mgmt, int proto) +static inline enum wifi_wpa3_enterprise_type wpas_key_mgmt_to_zephyr_wpa3_ent(int key_mgmt) { switch (key_mgmt) { + case WPA_KEY_MGMT_IEEE8021X_SUITE_B: + return WIFI_WPA3_ENTERPRISE_SUITEB; + case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: + return WIFI_WPA3_ENTERPRISE_SUITEB_192; + case WPA_KEY_MGMT_IEEE8021X_SHA256: + return WIFI_WPA3_ENTERPRISE_ONLY; + default: + return WIFI_WPA3_ENTERPRISE_NA; + } +} + +static inline enum wifi_security_type wpas_key_mgmt_to_zephyr(bool is_hapd, + void *config, int key_mgmt, int proto, int pwe) +{ + switch (key_mgmt) { +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE case WPA_KEY_MGMT_IEEE8021X: case WPA_KEY_MGMT_IEEE8021X_SUITE_B: case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: + case WPA_KEY_MGMT_IEEE8021X_SHA256: + if (is_hapd) { +#ifdef CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE + struct hostapd_bss_config *conf = (struct hostapd_bss_config *)config; + + switch (conf->eap_user->methods[0].method) { + case WIFI_EAP_TYPE_PEAP: + if (conf->eap_user->next && conf->eap_user->next->phase2) { + switch (conf->eap_user->next->methods[0].method) { + case WIFI_EAP_TYPE_MSCHAPV2: + return WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2; + case WIFI_EAP_TYPE_GTC: + return WIFI_SECURITY_TYPE_EAP_PEAP_GTC; + case WIFI_EAP_TYPE_TLS: + return WIFI_SECURITY_TYPE_EAP_PEAP_TLS; + } + } + case WIFI_EAP_TYPE_TTLS: + if (conf->eap_user->next && conf->eap_user->next->phase2) { + if (conf->eap_user->next->ttls_auth & 0x1E) { + return WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2; + } + } + } +#endif + } else { + struct wpa_ssid *ssid = (struct wpa_ssid *)config; + + switch (ssid->eap.eap_methods->method) { + case WIFI_EAP_TYPE_TTLS: + if (!os_memcmp(ssid->eap.phase2, "auth=MSCHAPV2", + os_strlen(ssid->eap.phase2))) { + return WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2; + } + case WIFI_EAP_TYPE_PEAP: + if (!os_memcmp(ssid->eap.phase2, "auth=MSCHAPV2", + os_strlen(ssid->eap.phase2))) { + return WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2; + } else if (!os_memcmp(ssid->eap.phase2, "auth=GTC", + os_strlen(ssid->eap.phase2))) { + return WIFI_SECURITY_TYPE_EAP_PEAP_GTC; + } else if (!os_memcmp(ssid->eap.phase2, "auth=TLS", + os_strlen(ssid->eap.phase2))) { + return WIFI_SECURITY_TYPE_EAP_PEAP_TLS; + } + } + } return WIFI_SECURITY_TYPE_EAP_TLS; +#endif case WPA_KEY_MGMT_NONE: return WIFI_SECURITY_TYPE_NONE; case WPA_KEY_MGMT_PSK: @@ -377,7 +447,13 @@ static inline enum wifi_security_type wpas_key_mgmt_to_zephyr(int key_mgmt, int case WPA_KEY_MGMT_PSK_SHA256: return WIFI_SECURITY_TYPE_PSK_SHA256; case WPA_KEY_MGMT_SAE: - return WIFI_SECURITY_TYPE_SAE; + if (pwe == 1) { + return WIFI_SECURITY_TYPE_SAE_H2E; + } else if (pwe == 2) { + return WIFI_SECURITY_TYPE_SAE_AUTO; + } else { + return WIFI_SECURITY_TYPE_SAE_HNP; + } case WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK: return WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL; case WPA_KEY_MGMT_FT_PSK: @@ -388,6 +464,8 @@ static inline enum wifi_security_type wpas_key_mgmt_to_zephyr(int key_mgmt, int return WIFI_SECURITY_TYPE_FT_EAP; case WPA_KEY_MGMT_FT_IEEE8021X_SHA384: return WIFI_SECURITY_TYPE_FT_EAP_SHA384; + case WPA_KEY_MGMT_SAE_EXT_KEY: + return WIFI_SECURITY_TYPE_SAE_EXT_KEY; default: return WIFI_SECURITY_TYPE_UNKNOWN; } @@ -472,7 +550,6 @@ static struct wifi_eap_config eap_config[] = { "auth=MSCHAPV2"}, {WIFI_SECURITY_TYPE_EAP_PEAP_TLS, WIFI_EAP_TYPE_PEAP, WIFI_EAP_TYPE_TLS, "PEAP", "auth=TLS"}, - {WIFI_SECURITY_TYPE_EAP_TLS_SHA256, WIFI_EAP_TYPE_TLS, WIFI_EAP_TYPE_NONE, "TLS", NULL}, }; int process_cipher_config(struct wifi_connect_req_params *params, @@ -482,13 +559,13 @@ int process_cipher_config(struct wifi_connect_req_params *params, unsigned int gropu_mgmt_cipher_capa; unsigned int index; - if (params->suiteb_type == WIFI_SUITEB) { + if (params->wpa3_ent_mode == WIFI_WPA3_ENTERPRISE_SUITEB) { cipher_capa = WPA_CAPA_ENC_GCMP; gropu_mgmt_cipher_capa = WPA_CAPA_ENC_BIP_GMAC_128; cipher_config->key_mgmt = "WPA-EAP-SUITE-B"; cipher_config->openssl_ciphers = "SUITEB128"; cipher_config->tls_flags = "[SUITEB]"; - } else if (params->suiteb_type == WIFI_SUITEB_192) { + } else if (params->wpa3_ent_mode == WIFI_WPA3_ENTERPRISE_SUITEB_192) { cipher_capa = WPA_CAPA_ENC_GCMP_256; gropu_mgmt_cipher_capa = WPA_CAPA_ENC_BIP_GMAC_256; if (params->ft_used) { @@ -498,6 +575,10 @@ int process_cipher_config(struct wifi_connect_req_params *params, } cipher_config->openssl_ciphers = "SUITEB192"; cipher_config->tls_flags = "[SUITEB]"; + } else if (params->wpa3_ent_mode == WIFI_WPA3_ENTERPRISE_ONLY) { + cipher_capa = WPA_CAPA_ENC_CCMP; + gropu_mgmt_cipher_capa = WPA_CAPA_ENC_BIP; + cipher_config->key_mgmt = "WPA-EAP-SHA256"; } else { cipher_capa = WPA_CAPA_ENC_CCMP; gropu_mgmt_cipher_capa = WPA_CAPA_ENC_BIP; @@ -508,10 +589,6 @@ int process_cipher_config(struct wifi_connect_req_params *params, } } - if (params->security == WIFI_SECURITY_TYPE_EAP_TLS_SHA256) { - cipher_config->key_mgmt = "WPA-EAP-SHA256"; - } - for (index = 0; index < ARRAY_SIZE(ciphers); index++) { if (cipher_capa == ciphers[index].capa) { cipher_config->group_cipher = ciphers[index].name; @@ -548,8 +625,7 @@ static int is_eap_valid_security(int security) security == WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2 || security == WIFI_SECURITY_TYPE_EAP_PEAP_GTC || security == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 || - security == WIFI_SECURITY_TYPE_EAP_PEAP_TLS || - security == WIFI_SECURITY_TYPE_EAP_TLS_SHA256); + security == WIFI_SECURITY_TYPE_EAP_PEAP_TLS); } #endif @@ -823,6 +899,18 @@ int hapd_process_enterprise_config(struct hostapd_iface *iface, } #endif +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE +static void wpas_remove_certs(struct wpa_supplicant *wpa_s) +{ + wpa_config_remove_blob(wpa_s->conf, "ca_cert"); + wpa_config_remove_blob(wpa_s->conf, "client_cert"); + wpa_config_remove_blob(wpa_s->conf, "private_key"); + wpa_config_remove_blob(wpa_s->conf, "ca_cert2"); + wpa_config_remove_blob(wpa_s->conf, "client_cert2"); + wpa_config_remove_blob(wpa_s->conf, "private_key2"); +} +#endif + static int wpas_add_and_config_network(struct wpa_supplicant *wpa_s, struct wifi_connect_req_params *params, bool mode_ap) @@ -841,6 +929,8 @@ static int wpas_add_and_config_network(struct wpa_supplicant *wpa_s, char phase1[128] = {0}; char *phase2 = NULL; unsigned int index; + + wpas_remove_certs(wpa_s); #endif if (!wpa_cli_cmd_v("remove_network all")) { @@ -934,7 +1024,8 @@ static int wpas_add_and_config_network(struct wpa_supplicant *wpa_s, if (params->security == WIFI_SECURITY_TYPE_SAE_HNP || params->security == WIFI_SECURITY_TYPE_SAE_H2E || - params->security == WIFI_SECURITY_TYPE_SAE_AUTO) { + params->security == WIFI_SECURITY_TYPE_SAE_AUTO || + params->security == WIFI_SECURITY_TYPE_SAE_EXT_KEY) { if (params->sae_password) { if ((params->sae_password_length < WIFI_PSK_MIN_LEN) || (params->sae_password_length > WIFI_SAE_PSWD_MAX_LEN)) { @@ -957,19 +1048,26 @@ static int wpas_add_and_config_network(struct wpa_supplicant *wpa_s, } } - if (params->security == WIFI_SECURITY_TYPE_SAE_H2E || - params->security == WIFI_SECURITY_TYPE_SAE_AUTO) { - if (!wpa_cli_cmd_v("set sae_pwe %d", - (params->security == WIFI_SECURITY_TYPE_SAE_H2E) - ? 1 - : 2)) { - goto out; - } + if (!wpa_cli_cmd_v("set sae_pwe %d", + (params->security == WIFI_SECURITY_TYPE_SAE_H2E) + ? 1 + : ((params->security == WIFI_SECURITY_TYPE_SAE_HNP) + ? 0 + : 2))) { + goto out; } - if (!wpa_cli_cmd_v("set_network %d key_mgmt SAE%s", resp.network_id, - params->ft_used ? " FT-SAE" : "")) { - goto out; + if (params->security != WIFI_SECURITY_TYPE_SAE_EXT_KEY) { + if (!wpa_cli_cmd_v("set_network %d key_mgmt SAE%s", resp.network_id, + params->ft_used ? " FT-SAE" : "")) { + goto out; + } + } else { + if (!wpa_cli_cmd_v("set_network %d key_mgmt SAE-EXT-KEY%s", + resp.network_id, + params->ft_used ? " FT-SAE-EXT-KEY" : "")) { + goto out; + } } } else if (params->security == WIFI_SECURITY_TYPE_PSK_SHA256) { if (!wpa_cli_cmd_v("set_network %d psk \"%s\"", @@ -1045,6 +1143,20 @@ static int wpas_add_and_config_network(struct wpa_supplicant *wpa_s, goto out; } + if (params->wpa3_ent_mode == WIFI_WPA3_ENTERPRISE_SUITEB_192) { + if (params->TLS_cipher == WIFI_EAP_TLS_ECC_P384) { + if (!wpa_cli_cmd_v("set_network %d openssl_ciphers \"%s\"", + resp.network_id, + cipher_config.openssl_ciphers)) + goto out; + } else if (params->TLS_cipher == WIFI_EAP_TLS_RSA_3K) { + snprintf(phase1, sizeof(phase1), "tls_suiteb=1"); + if (!wpa_cli_cmd_v("set_network %d phase1 \"%s\"", + resp.network_id, &phase1[0])) + goto out; + } + } + if (!wpa_cli_cmd_v("set_network %d key_mgmt %s", resp.network_id, cipher_config.key_mgmt)) { goto out; @@ -1121,15 +1233,19 @@ static int wpas_add_and_config_network(struct wpa_supplicant *wpa_s, goto out; } - if (wpas_config_process_blob(wpa_s->conf, "ca_cert", - enterprise_creds.ca_cert, - enterprise_creds.ca_cert_len)) { - goto out; - } + if (false == ((params->security == WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2 || + params->security == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2) && + (!params->verify_peer_cert))) { + if (wpas_config_process_blob(wpa_s->conf, "ca_cert", + enterprise_creds.ca_cert, + enterprise_creds.ca_cert_len)) { + goto out; + } - if (!wpa_cli_cmd_v("set_network %d ca_cert \"blob://ca_cert\"", - resp.network_id)) { - goto out; + if (!wpa_cli_cmd_v("set_network %d ca_cert \"blob://ca_cert\"", + resp.network_id)) { + goto out; + } } if (wpas_config_process_blob(wpa_s->conf, "client_cert", @@ -1348,6 +1464,10 @@ static int wpas_disconnect_network(const struct device *dev, int cur_mode) wifi_mgmt_raise_disconnect_complete_event(iface, ret); } +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + wpas_remove_certs(wpa_s); +#endif + if (!wpa_cli_cmd_v("remove_network all")) { wpa_printf(MSG_ERROR, "Failed to remove all networks"); } @@ -1485,22 +1605,22 @@ int supplicant_status(const struct device *dev, struct wifi_iface_status *status u8 *_ssid = ssid->ssid; size_t ssid_len = ssid->ssid_len; struct status_resp cli_status; - bool is_ap; int proto; int key_mgmt; + int sae_pwe; if (!ssid) { wpa_printf(MSG_ERROR, "Failed to get current ssid"); goto out; } - is_ap = ssid->mode == WPAS_MODE_AP; - /* For AP its always the configured one */ - proto = is_ap ? ssid->proto : wpa_s->wpa_proto; - key_mgmt = is_ap ? ssid->key_mgmt : wpa_s->key_mgmt; + proto = ssid->proto; + key_mgmt = ssid->key_mgmt; + sae_pwe = wpa_s->conf->sae_pwe; os_memcpy(status->bssid, wpa_s->bssid, WIFI_MAC_ADDR_LEN); status->band = wpas_band_to_zephyr(wpas_freq_to_band(wpa_s->assoc_freq)); - status->security = wpas_key_mgmt_to_zephyr(key_mgmt, proto); + status->wpa3_ent_type = wpas_key_mgmt_to_zephyr_wpa3_ent(key_mgmt); + status->security = wpas_key_mgmt_to_zephyr(0, ssid, key_mgmt, proto, sae_pwe); status->mfp = get_mfp(ssid->ieee80211w); ieee80211_freq_to_chan(wpa_s->assoc_freq, &channel); status->channel = channel; @@ -1801,6 +1921,18 @@ int supplicant_set_twt(const struct device *dev, struct wifi_twt_params *params) return wifi_mgmt_api->set_twt(dev, params); } +int supplicant_set_btwt(const struct device *dev, struct wifi_twt_params *params) +{ + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_mgmt_api(dev); + + if (!wifi_mgmt_api || !wifi_mgmt_api->set_btwt) { + wpa_printf(MSG_ERROR, "Set Broadcast TWT not supported"); + return -ENOTSUP; + } + + return wifi_mgmt_api->set_btwt(dev, params); +} + int supplicant_get_power_save_config(const struct device *dev, struct wifi_ps_config *config) { @@ -1918,6 +2050,41 @@ int supplicant_get_rts_threshold(const struct device *dev, unsigned int *rts_thr return wifi_mgmt_api->get_rts_threshold(dev, rts_threshold); } +int supplicant_bss_ext_capab(const struct device *dev, int capab) +{ + struct wpa_supplicant *wpa_s; + int is_support = 0; + + wpa_s = get_wpa_s_handle(dev); + if (!wpa_s) { + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + return 0; + } + + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); + is_support = wpa_bss_ext_capab(wpa_s->current_bss, capab); + k_mutex_unlock(&wpa_supplicant_mutex); + + return is_support; +} + +int supplicant_legacy_roam(const struct device *dev) +{ + int ret = -1; + + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); + if (!wpa_cli_cmd_v("scan")) { + goto out; + } + + ret = 0; + +out: + k_mutex_unlock(&wpa_supplicant_mutex); + + return ret; +} + #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM int supplicant_btm_query(const struct device *dev, uint8_t reason) { @@ -2075,6 +2242,72 @@ int hapd_state(const struct device *dev, int *state) return ret; } +static int hapd_config_chan_center_seg0(struct wifi_connect_req_params *params) +{ + int ret = 0; + uint8_t center_freq_seg0_idx = 0; + uint8_t oper_chwidth = CHANWIDTH_USE_HT; + const uint8_t *center_freq = NULL; + static const uint8_t center_freq_40MHz[] = {38, 46, 54, 62, 102, 110, + 118, 126, 134, 142, 151, 159}; + static const uint8_t center_freq_80MHz[] = {42, 58, 106, 122, 138, 155}; + uint8_t index, index_max, chan_idx, ch_offset = 0; + + /* Unless ACS is being used, both "channel" and "vht_oper_centr_freq_seg0_idx" + * parameters must be set. + */ + switch (params->bandwidth) { + case WIFI_FREQ_BANDWIDTH_20MHZ: + oper_chwidth = CHANWIDTH_USE_HT; + center_freq_seg0_idx = params->channel; + break; + case WIFI_FREQ_BANDWIDTH_40MHZ: + oper_chwidth = CHANWIDTH_USE_HT; + center_freq = center_freq_40MHz; + index_max = ARRAY_SIZE(center_freq_40MHz); + ch_offset = 2; + break; + case WIFI_FREQ_BANDWIDTH_80MHZ: + oper_chwidth = CHANWIDTH_80MHZ; + center_freq = center_freq_80MHz; + index_max = ARRAY_SIZE(center_freq_80MHz); + ch_offset = 6; + break; + default: + return -EINVAL; + } + + if (params->bandwidth != WIFI_FREQ_BANDWIDTH_20MHZ) { + chan_idx = params->channel; + for (index = 0; index < index_max; index++) { + if ((chan_idx >= (center_freq[index] - ch_offset)) && + (chan_idx <= (center_freq[index] + ch_offset))) { + center_freq_seg0_idx = center_freq[index]; + break; + } + } + } + + if (!hostapd_cli_cmd_v("set vht_oper_chwidth %d", oper_chwidth)) { + goto out; + } + if (!hostapd_cli_cmd_v("set vht_oper_centr_freq_seg0_idx %d", center_freq_seg0_idx)) { + goto out; + } +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX + if (!hostapd_cli_cmd_v("set he_oper_chwidth %d", oper_chwidth)) { + goto out; + } + if (!hostapd_cli_cmd_v("set he_oper_centr_freq_seg0_idx %d", center_freq_seg0_idx)) { + goto out; + } +#endif + + return ret; +out: + return -EINVAL; +} + int hapd_config_network(struct hostapd_iface *iface, struct wifi_connect_req_params *params) { @@ -2111,6 +2344,11 @@ int hapd_config_network(struct hostapd_iface *iface, goto out; } + ret = hapd_config_chan_center_seg0(params); + if (ret) { + goto out; + } + if (params->security != WIFI_SECURITY_TYPE_NONE) { if (params->security == WIFI_SECURITY_TYPE_WPA_PSK) { if (!hostapd_cli_cmd_v("set wpa 1")) { @@ -2151,7 +2389,9 @@ int hapd_config_network(struct hostapd_iface *iface, if (!hostapd_cli_cmd_v("set rsn_pairwise CCMP")) { goto out; } - } else if (params->security == WIFI_SECURITY_TYPE_SAE) { + } else if (params->security == WIFI_SECURITY_TYPE_SAE_HNP || + params->security == WIFI_SECURITY_TYPE_SAE_H2E || + params->security == WIFI_SECURITY_TYPE_SAE_AUTO) { if (!hostapd_cli_cmd_v("set wpa 2")) { goto out; } @@ -2166,8 +2406,14 @@ int hapd_config_network(struct hostapd_iface *iface, if (!hostapd_cli_cmd_v("set rsn_pairwise CCMP")) { goto out; } - if (!hostapd_cli_cmd_v("set sae_pwe 2")) { - goto out; + if (params->security == WIFI_SECURITY_TYPE_SAE_H2E || + params->security == WIFI_SECURITY_TYPE_SAE_AUTO) { + if (!hostapd_cli_cmd_v("set sae_pwe %d", + (params->security == WIFI_SECURITY_TYPE_SAE_H2E) + ? 1 + : 2)) { + goto out; + } } } else if (params->security == WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL) { if (!hostapd_cli_cmd_v("set wpa 2")) { @@ -2178,11 +2424,11 @@ int hapd_config_network(struct hostapd_iface *iface, goto out; } - if (!hostapd_cli_cmd_v("set wpa_passphrase \"%s\"", params->psk)) { + if (!hostapd_cli_cmd_v("set wpa_passphrase %s", params->psk)) { goto out; } - if (!hostapd_cli_cmd_v("set sae_password \"%s\"", + if (!hostapd_cli_cmd_v("set sae_password %s", params->sae_password ? params->sae_password : params->psk)) { goto out; @@ -2241,53 +2487,72 @@ int hapd_config_network(struct hostapd_iface *iface, return -1; } +static int set_ap_config_params(const struct device *dev, struct wifi_ap_config_params *params) +{ + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_mgmt_api(dev); + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_config_params == NULL) { + return -ENOTSUP; + } + + return wifi_mgmt_api->ap_config_params(dev, params); +} + int supplicant_ap_config_params(const struct device *dev, struct wifi_ap_config_params *params) { struct hostapd_iface *iface; - const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_mgmt_api(dev); int ret = 0; - if (params->type & WIFI_AP_CONFIG_PARAM_MAX_INACTIVITY) { - if (!wifi_mgmt_api || !wifi_mgmt_api->ap_config_params) { - wpa_printf(MSG_ERROR, "ap_config_params not supported"); - return -ENOTSUP; - } + ret = set_ap_config_params(dev, params); + if (ret && (ret != -ENOTSUP)) { + wpa_printf(MSG_ERROR, "Failed to set ap config params"); + return -EINVAL; + } - ret = wifi_mgmt_api->ap_config_params(dev, params); - if (ret) { - wpa_printf(MSG_ERROR, - "Failed to set maximum inactivity duration for stations"); - } else { - wpa_printf(MSG_INFO, "Set maximum inactivity duration for stations: %d (s)", - params->max_inactivity); - } + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (iface == NULL) { + ret = -ENOENT; + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + goto out; } - if (params->type & WIFI_AP_CONFIG_PARAM_MAX_NUM_STA) { - k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); - iface = get_hostapd_handle(dev); - if (!iface) { - ret = -ENOENT; - wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + if (iface->state > HAPD_IFACE_DISABLED) { + ret = -EBUSY; + wpa_printf(MSG_ERROR, "Interface %s is not in disable state", dev->name); + goto out; + } + + if (params->type & WIFI_AP_CONFIG_PARAM_MAX_NUM_STA) { + if (!hostapd_cli_cmd_v("set max_num_sta %d", params->max_num_sta)) { + ret = -EINVAL; + wpa_printf(MSG_ERROR, "Failed to set maximum number of stations"); goto out; } + wpa_printf(MSG_INFO, "Set maximum number of stations: %d", params->max_num_sta); + } - if (iface->state > HAPD_IFACE_DISABLED) { - ret = -EBUSY; - wpa_printf(MSG_ERROR, "Interface %s is not in disable state", dev->name); + if (params->type & WIFI_AP_CONFIG_PARAM_HT_CAPAB) { + if (!hostapd_cli_cmd_v("set ht_capab %s", params->ht_capab)) { + ret = -EINVAL; + wpa_printf(MSG_ERROR, "Failed to set HT capabilities"); goto out; } + wpa_printf(MSG_INFO, "Set HT capabilities: %s", params->ht_capab); + } - if (!hostapd_cli_cmd_v("set max_num_sta %d", params->max_num_sta)) { + if (params->type & WIFI_AP_CONFIG_PARAM_VHT_CAPAB) { + if (!hostapd_cli_cmd_v("set vht_capab %s", params->vht_capab)) { ret = -EINVAL; - wpa_printf(MSG_ERROR, "Failed to set maximum number of stations"); + wpa_printf(MSG_ERROR, "Failed to set VHT capabilities"); goto out; } - wpa_printf(MSG_INFO, "Set maximum number of stations: %d", params->max_num_sta); + wpa_printf(MSG_INFO, "Set VHT capabilities: %s", params->vht_capab); + } out: k_mutex_unlock(&wpa_supplicant_mutex); - } return ret; } @@ -2303,6 +2568,7 @@ int supplicant_ap_status(const struct device *dev, struct wifi_iface_status *sta struct hostapd_hw_modes *hw_mode; int proto; /* Wi-Fi secure protocol */ int key_mgmt; /* Wi-Fi key management */ + int sae_pwe; k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); @@ -2342,7 +2608,9 @@ int supplicant_ap_status(const struct device *dev, struct wifi_iface_status *sta status->band = wpas_band_to_zephyr(wpas_freq_to_band(iface->freq)); key_mgmt = bss->wpa_key_mgmt; proto = bss->wpa; - status->security = wpas_key_mgmt_to_zephyr(key_mgmt, proto); + sae_pwe = bss->sae_pwe; + status->wpa3_ent_type = wpas_key_mgmt_to_zephyr_wpa3_ent(key_mgmt); + status->security = wpas_key_mgmt_to_zephyr(1, hapd->conf, key_mgmt, proto, sae_pwe); status->mfp = get_mfp(bss->ieee80211w); status->channel = conf->channel; os_memcpy(status->ssid, ssid->ssid, ssid->ssid_len); @@ -2405,6 +2673,7 @@ int supplicant_ap_wps_pbc(const struct device *dev) int supplicant_ap_wps_pin(const struct device *dev, struct wifi_wps_config_params *params) { +#define WPS_PIN_EXPIRE_TIME 120 struct hostapd_iface *iface; char *get_pin_cmd = "WPS_AP_PIN random"; int ret = 0; @@ -2433,7 +2702,7 @@ int supplicant_ap_wps_pin(const struct device *dev, struct wifi_wps_config_param goto out; } - if (!hostapd_cli_cmd_v("wps_pin any %s", params->pin)) { + if (!hostapd_cli_cmd_v("wps_pin any %s %d", params->pin, WPS_PIN_EXPIRE_TIME)) { goto out; } @@ -2467,6 +2736,20 @@ int supplicant_ap_wps_config(const struct device *dev, struct wifi_wps_config_pa } #endif +static int set_ap_bandwidth(const struct device *dev, enum wifi_frequency_bandwidths bandwidth) +{ + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_mgmt_api(dev); + struct wifi_ap_config_params params = {0}; + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_config_params == NULL) { + return -ENOTSUP; + } + + params.bandwidth = bandwidth; + params.type = WIFI_AP_CONFIG_PARAM_BANDWIDTH; + return wifi_mgmt_api->ap_config_params(dev, ¶ms); +} + int supplicant_ap_enable(const struct device *dev, struct wifi_connect_req_params *params) { @@ -2486,6 +2769,12 @@ int supplicant_ap_enable(const struct device *dev, return -1; } + ret = set_ap_bandwidth(dev, params->bandwidth); + if (ret && (ret != -ENOTSUP)) { + wpa_printf(MSG_ERROR, "Failed to set ap bandwidth"); + return -EINVAL; + } + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); #ifdef CONFIG_WIFI_NM_HOSTAPD_AP diff --git a/modules/hostap/src/supp_api.h b/modules/hostap/src/supp_api.h index ab1e6c014eb1c..cb4e7836f1ca6 100644 --- a/modules/hostap/src/supp_api.h +++ b/modules/hostap/src/supp_api.h @@ -156,6 +156,15 @@ int supplicant_set_power_save(const struct device *dev, struct wifi_ps_params *p */ int supplicant_set_twt(const struct device *dev, struct wifi_twt_params *params); +/** + * @brief Set Wi-Fi BTWT parameters + * + * @param dev Wi-Fi interface name to use + * @param params BTWT parameters to set + * @return 0 for OK; -1 for ERROR + */ +int supplicant_set_btwt(const struct device *dev, struct wifi_twt_params *params); + /** * @brief Get Wi-Fi power save configuration * @@ -243,6 +252,23 @@ int supplicant_get_rts_threshold(const struct device *dev, unsigned int *rts_thr int supplicant_btm_query(const struct device *dev, uint8_t reason); #endif +/** Send legacy roam + * + * @param dev Pointer to the device structure for the driver instance. + * + * @return 0 if ok, < 0 if error + */ +int supplicant_legacy_roam(const struct device *dev); + +/** Judge ap whether support the capability + * + * @param dev Pointer to the device structure for the driver instance. + * @param capab is the capability to judge + * + * @return 1 if support, 0 if not support + */ +int supplicant_bss_ext_capab(const struct device *dev, int capab); + /** Get Wi-Fi connection parameters recently used * * @param dev Pointer to the device structure for the driver instance diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index 5ac548034693e..4fdc144d435e8 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -77,6 +77,8 @@ static const struct wifi_mgmt_ops mgmt_ops = { .channel = supplicant_channel, .set_rts_threshold = supplicant_set_rts_threshold, .get_rts_threshold = supplicant_get_rts_threshold, + .bss_ext_capab = supplicant_bss_ext_capab, + .legacy_roam = supplicant_legacy_roam, #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM .btm_query = supplicant_btm_query, #endif @@ -111,9 +113,11 @@ static const struct wifi_mgmt_ops mgmt_ap_ops = { .dpp_dispatch = hapd_dpp_dispatch, #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */ .ap_config_params = supplicant_ap_config_params, + .set_rts_threshold = supplicant_set_rts_threshold, #ifdef CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE .enterprise_creds = supplicant_add_enterprise_creds, #endif + .set_btwt = supplicant_set_btwt, }; DEFINE_WIFI_NM_INSTANCE(hostapd, &mgmt_ap_ops); @@ -645,6 +649,12 @@ struct hostapd_iface *hostapd_get_interface(const char *ifname) return ctx->hostapd.iface[0]; } +static void hostapd_event_eapol_rx_cb(void *ctx, const u8 *src_addr, + const u8 *buf, size_t len) +{ + hostapd_event_eapol_rx(ctx, src_addr, buf, len, FRAME_ENCRYPTION_UNKNOWN, -1); +} + static int hostapd_enable_iface_cb(struct hostapd_iface *hapd_iface) { struct hostapd_data *bss; @@ -662,7 +672,7 @@ static int hostapd_enable_iface_cb(struct hostapd_iface *hapd_iface) l2_packet_deinit(bss->l2); bss->l2 = l2_packet_init(bss->conf->iface, bss->conf->bssid, ETH_P_EAPOL, - &hostapd_event_eapol_rx, bss, 0); + &hostapd_event_eapol_rx_cb, bss, 0); if (bss->l2 == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize l2 for hostapd interface"); return -1; @@ -710,6 +720,14 @@ static int hostapd_disable_iface_cb(struct hostapd_iface *hapd_iface) supplicant_send_wifi_mgmt_ap_status(hapd_iface, NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT, WIFI_STATUS_AP_SUCCESS); + hostapd_config_free(hapd_iface->conf); + hapd_iface->conf = hapd_iface->interfaces->config_read_cb(hapd_iface->config_fname); + for (j = 0; j < hapd_iface->num_bss; j++) { + hapd = hapd_iface->bss[j]; + hapd->iconf = hapd_iface->conf; + hapd->conf = hapd_iface->conf->bss[j]; + hapd->driver = hapd_iface->conf->driver; + } return 0; } @@ -1073,12 +1091,6 @@ static void zephyr_hostapd_init(struct supplicant_context *ctx) zephyr_hostapd_ctrl_init((void *)interfaces->iface[i]->bss[0]); } - ret = wifi_nm_register_mgd_iface(wifi_nm_get_instance("hostapd"), iface); - if (ret) { - LOG_ERR("Failed to register mgd iface with native stack %s (%d)", - ifname, ret); - goto out; - } out: return; } @@ -1207,3 +1219,16 @@ static int init(void) } SYS_INIT(init, APPLICATION, 0); + +static enum net_verdict eapol_recv(struct net_if *iface, uint16_t ptype, + struct net_pkt *pkt) +{ + ARG_UNUSED(iface); + ARG_UNUSED(ptype); + + net_pkt_set_family(pkt, AF_UNSPEC); + + return NET_CONTINUE; +} + +ETH_NET_L3_REGISTER(EAPOL, NET_ETH_PTYPE_EAPOL, eapol_recv); diff --git a/modules/hostap/src/supp_main.h b/modules/hostap/src/supp_main.h index 981bdf6695851..22e6d79035c9e 100644 --- a/modules/hostap/src/supp_main.h +++ b/modules/hostap/src/supp_main.h @@ -15,7 +15,8 @@ !defined(CONFIG_EAP_PSK) && !defined(CONFIG_EAP_PAX) && \ !defined(CONFIG_EAP_SAKE) && !defined(CONFIG_EAP_GPSK) && \ !defined(CONFIG_EAP_PWD) && !defined(CONFIG_EAP_EKE) && \ - !defined(CONFIG_EAP_IKEV2) && !defined(CONFIG_EAP_GTC) + !defined(CONFIG_EAP_IKEV2) && !defined(CONFIG_EAP_GTC) && \ + !defined(CONFIG_EAP_LEAP) #error "At least one of the following EAP methods need to be defined \ CONFIG_EAP_TLS \ CONFIG_EAP_TTLS \ diff --git a/modules/liblc3/CMakeLists.txt b/modules/liblc3/CMakeLists.txt index 1a662866d12c9..275d11cb878bf 100644 --- a/modules/liblc3/CMakeLists.txt +++ b/modules/liblc3/CMakeLists.txt @@ -1,22 +1,43 @@ if(CONFIG_LIBLC3) - zephyr_library_named(liblc3) -zephyr_library_compile_options(-O3 -std=c11 -ffast-math -Wno-array-bounds) +zephyr_library_compile_options( + -O3 -std=c11 -ffast-math -Wno-array-bounds -Wall -Wextra -Wdouble-promotion -Wvla -pedantic +) + +# LC3plus and LC3plusHR support is enabled by default in liblc3. +# In our case, we prefer those to be explicitly enabled by the user if needed. +if(CONFIG_LIBLC3_PLUS) +zephyr_library_compile_options(-DLC3_PLUS=1) +else() +zephyr_library_compile_options(-DLC3_PLUS=0) +endif() + +if(CONFIG_LIBLC3_PLUS_HR) +zephyr_library_compile_options(-DLC3_PLUS_HR=1) +else() +zephyr_library_compile_options(-DLC3_PLUS_HR=0) +endif() -zephyr_include_directories(${ZEPHYR_LIBLC3_MODULE_DIR}/include) -zephyr_include_directories(${ZEPHYR_LIBLC3_MODULE_DIR}/src) +zephyr_include_directories( + ${ZEPHYR_LIBLC3_MODULE_DIR}/include +) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/attdet.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/bits.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/bwdet.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/energy.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/lc3.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/ltpf.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/mdct.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/plc.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/sns.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/spec.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/tables.c) -zephyr_library_sources(${ZEPHYR_LIBLC3_MODULE_DIR}/src/tns.c) +zephyr_library_include_directories( + ${ZEPHYR_LIBLC3_MODULE_DIR}/src +) +zephyr_library_sources( + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/attdet.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/bits.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/bwdet.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/energy.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/lc3.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/ltpf.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/mdct.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/plc.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/sns.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/spec.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/tables.c + ${ZEPHYR_LIBLC3_MODULE_DIR}/src/tns.c +) endif() diff --git a/modules/liblc3/Kconfig b/modules/liblc3/Kconfig index 11ce2e34a6c28..eb33af61794b4 100644 --- a/modules/liblc3/Kconfig +++ b/modules/liblc3/Kconfig @@ -1,4 +1,5 @@ # Copyright (c) 2022 Bose Corporation +# Copyright (c) 2024 Codecoup # SPDX-License-Identifier: Apache-2.0 config ZEPHYR_LIBLC3_MODULE @@ -9,4 +10,20 @@ config LIBLC3 depends on FPU select REQUIRES_FULL_LIBC help - This option enables the Android liblc3 library for Bluetooth LE Audio + Enable the Low Complexity Communication Codec (LC3) + +if LIBLC3 + +config LIBLC3_PLUS + bool "LC3plus Support [EXPERIMENTAL]" + select EXPERIMENTAL + help + Enable support of 2.5ms and 5ms frame durations. + +config LIBLC3_PLUS_HR + bool "LC3plus High Resolution Support [EXPERIMENTAL]" + select EXPERIMENTAL + help + Enable support of the High-Resolution mode. + +endif diff --git a/modules/littlefs/zephyr_lfs_config.h b/modules/littlefs/zephyr_lfs_config.h index a7ab27deda952..32bd1e36f9bd0 100644 --- a/modules/littlefs/zephyr_lfs_config.h +++ b/modules/littlefs/zephyr_lfs_config.h @@ -43,6 +43,10 @@ extern "C" { #endif +#ifdef CONFIG_FS_LITTLEFS_DISK_VERSION +#define LFS_MULTIVERSION +#endif + /* Logging functions when using LittleFS with Zephyr. */ #ifndef LFS_TRACE #ifdef LFS_YES_TRACE diff --git a/modules/lvgl/CMakeLists.txt b/modules/lvgl/CMakeLists.txt index 6b00764aecc65..5ef568e6b89b6 100644 --- a/modules/lvgl/CMakeLists.txt +++ b/modules/lvgl/CMakeLists.txt @@ -16,140 +16,126 @@ zephyr_include_directories(${LVGL_DIR}/src/) zephyr_include_directories(include) zephyr_compile_definitions(LV_CONF_INCLUDE_SIMPLE=1) -zephyr_compile_definitions(LV_CONF_PATH=${CMAKE_CURRENT_SOURCE_DIR}/include/lv_conf.h) +zephyr_compile_definitions(LV_CONF_PATH="${CMAKE_CURRENT_SOURCE_DIR}/include/lv_conf.h") zephyr_library_sources( - ${LVGL_DIR}/src/core/lv_disp.c - ${LVGL_DIR}/src/core/lv_event.c + ${LVGL_DIR}/src/core/lv_group.c - ${LVGL_DIR}/src/core/lv_indev.c - ${LVGL_DIR}/src/core/lv_indev_scroll.c ${LVGL_DIR}/src/core/lv_obj.c ${LVGL_DIR}/src/core/lv_obj_class.c ${LVGL_DIR}/src/core/lv_obj_draw.c + ${LVGL_DIR}/src/core/lv_obj_event.c + ${LVGL_DIR}/src/core/lv_obj_id_builtin.c ${LVGL_DIR}/src/core/lv_obj_pos.c + ${LVGL_DIR}/src/core/lv_obj_property.c ${LVGL_DIR}/src/core/lv_obj_scroll.c ${LVGL_DIR}/src/core/lv_obj_style.c ${LVGL_DIR}/src/core/lv_obj_style_gen.c ${LVGL_DIR}/src/core/lv_obj_tree.c ${LVGL_DIR}/src/core/lv_refr.c - ${LVGL_DIR}/src/core/lv_theme.c - ${LVGL_DIR}/src/draw/arm2d/lv_gpu_arm2d.c + ${LVGL_DIR}/src/display/lv_display.c + + ${LVGL_DIR}/src/draw/dma2d/lv_draw_dma2d.c + ${LVGL_DIR}/src/draw/dma2d/lv_draw_dma2d_fill.c + ${LVGL_DIR}/src/draw/dma2d/lv_draw_dma2d_img.c + ${LVGL_DIR}/src/draw/lv_draw_arc.c + ${LVGL_DIR}/src/draw/lv_draw_buf.c ${LVGL_DIR}/src/draw/lv_draw.c - ${LVGL_DIR}/src/draw/lv_draw_img.c + ${LVGL_DIR}/src/draw/lv_draw_image.c ${LVGL_DIR}/src/draw/lv_draw_label.c - ${LVGL_DIR}/src/draw/lv_draw_layer.c ${LVGL_DIR}/src/draw/lv_draw_line.c ${LVGL_DIR}/src/draw/lv_draw_mask.c ${LVGL_DIR}/src/draw/lv_draw_rect.c - ${LVGL_DIR}/src/draw/lv_draw_transform.c ${LVGL_DIR}/src/draw/lv_draw_triangle.c - ${LVGL_DIR}/src/draw/lv_img_buf.c - ${LVGL_DIR}/src/draw/lv_img_cache.c - ${LVGL_DIR}/src/draw/lv_img_decoder.c - ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_blend.c + ${LVGL_DIR}/src/draw/lv_draw_vector.c + ${LVGL_DIR}/src/draw/lv_image_decoder.c + + ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_buf_pxp.c ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp.c - ${LVGL_DIR}/src/draw/nxp/pxp/lv_gpu_nxp_pxp.c - ${LVGL_DIR}/src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c + ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_fill.c + ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_img.c + ${LVGL_DIR}/src/draw/nxp/pxp/lv_draw_pxp_layer.c + ${LVGL_DIR}/src/draw/nxp/pxp/lv_pxp_cfg.c + ${LVGL_DIR}/src/draw/nxp/pxp/lv_pxp_osa.c + ${LVGL_DIR}/src/draw/nxp/pxp/lv_pxp_utils.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_buf_vglite.c ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_arc.c - ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_blend.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_border.c ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_fill.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_img.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_label.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_layer.c ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_line.c - ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_rect.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_draw_vglite_triangle.c ${LVGL_DIR}/src/draw/nxp/vglite/lv_vglite_buf.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_vglite_matrix.c + ${LVGL_DIR}/src/draw/nxp/vglite/lv_vglite_path.c ${LVGL_DIR}/src/draw/nxp/vglite/lv_vglite_utils.c - ${LVGL_DIR}/src/draw/renesas/lv_gpu_d2_draw_label.c - ${LVGL_DIR}/src/draw/renesas/lv_gpu_d2_ra6m3.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_arc.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_bg.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_composite.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_img.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_label.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_layer.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_line.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_mask.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_polygon.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_rect.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_stack_blur.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_texture_cache.c - ${LVGL_DIR}/src/draw/sdl/lv_draw_sdl_utils.c - ${LVGL_DIR}/src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c + + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_arc.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_border.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_fill.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_image.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_label.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_line.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_mask_rectangle.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c + ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c + + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend.c + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_i1.c + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_l8.c + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565.c + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_arc.c - ${LVGL_DIR}/src/draw/sw/lv_draw_sw_blend.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_border.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_box_shadow.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw.c - ${LVGL_DIR}/src/draw/sw/lv_draw_sw_dither.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_fill.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_gradient.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_img.c - ${LVGL_DIR}/src/draw/sw/lv_draw_sw_layer.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_letter.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_line.c - ${LVGL_DIR}/src/draw/sw/lv_draw_sw_polygon.c - ${LVGL_DIR}/src/draw/sw/lv_draw_sw_rect.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_mask.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_mask_rect.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_transform.c - ${LVGL_DIR}/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c - - ${LVGL_DIR}/src/extra/layouts/flex/lv_flex.c - ${LVGL_DIR}/src/extra/layouts/grid/lv_grid.c - ${LVGL_DIR}/src/extra/libs/bmp/lv_bmp.c - ${LVGL_DIR}/src/extra/libs/ffmpeg/lv_ffmpeg.c - ${LVGL_DIR}/src/extra/libs/freetype/lv_freetype.c - ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_fatfs.c - ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_littlefs.c - ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_posix.c - ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_stdio.c - ${LVGL_DIR}/src/extra/libs/fsdrv/lv_fs_win32.c - ${LVGL_DIR}/src/extra/libs/gif/gifdec.c - ${LVGL_DIR}/src/extra/libs/gif/lv_gif.c - ${LVGL_DIR}/src/extra/libs/png/lodepng.c - ${LVGL_DIR}/src/extra/libs/png/lv_png.c - ${LVGL_DIR}/src/extra/libs/qrcode/lv_qrcode.c - ${LVGL_DIR}/src/extra/libs/qrcode/qrcodegen.c - ${LVGL_DIR}/src/extra/libs/rlottie/lv_rlottie.c - ${LVGL_DIR}/src/extra/libs/sjpg/lv_sjpg.c - ${LVGL_DIR}/src/extra/libs/sjpg/tjpgd.c - ${LVGL_DIR}/src/extra/libs/tiny_ttf/lv_tiny_ttf.c - ${LVGL_DIR}/src/extra/lv_extra.c - ${LVGL_DIR}/src/extra/others/fragment/lv_fragment.c - ${LVGL_DIR}/src/extra/others/fragment/lv_fragment_manager.c - ${LVGL_DIR}/src/extra/others/gridnav/lv_gridnav.c - ${LVGL_DIR}/src/extra/others/ime/lv_ime_pinyin.c - ${LVGL_DIR}/src/extra/others/imgfont/lv_imgfont.c - ${LVGL_DIR}/src/extra/others/monkey/lv_monkey.c - ${LVGL_DIR}/src/extra/others/msg/lv_msg.c - ${LVGL_DIR}/src/extra/others/snapshot/lv_snapshot.c - ${LVGL_DIR}/src/extra/themes/basic/lv_theme_basic.c - ${LVGL_DIR}/src/extra/themes/default/lv_theme_default.c - ${LVGL_DIR}/src/extra/themes/mono/lv_theme_mono.c - ${LVGL_DIR}/src/extra/widgets/animimg/lv_animimg.c - ${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar.c - ${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar_header_arrow.c - ${LVGL_DIR}/src/extra/widgets/calendar/lv_calendar_header_dropdown.c - ${LVGL_DIR}/src/extra/widgets/chart/lv_chart.c - ${LVGL_DIR}/src/extra/widgets/colorwheel/lv_colorwheel.c - ${LVGL_DIR}/src/extra/widgets/imgbtn/lv_imgbtn.c - ${LVGL_DIR}/src/extra/widgets/keyboard/lv_keyboard.c - ${LVGL_DIR}/src/extra/widgets/led/lv_led.c - ${LVGL_DIR}/src/extra/widgets/list/lv_list.c - ${LVGL_DIR}/src/extra/widgets/menu/lv_menu.c - ${LVGL_DIR}/src/extra/widgets/meter/lv_meter.c - ${LVGL_DIR}/src/extra/widgets/msgbox/lv_msgbox.c - ${LVGL_DIR}/src/extra/widgets/span/lv_span.c - ${LVGL_DIR}/src/extra/widgets/spinbox/lv_spinbox.c - ${LVGL_DIR}/src/extra/widgets/spinner/lv_spinner.c - ${LVGL_DIR}/src/extra/widgets/tabview/lv_tabview.c - ${LVGL_DIR}/src/extra/widgets/tileview/lv_tileview.c - ${LVGL_DIR}/src/extra/widgets/win/lv_win.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_triangle.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_utils.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_vector.c + + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_buf_vg_lite.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_arc.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_border.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_box_shadow.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_fill.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_img.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_label.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_layer.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_line.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_triangle.c + ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_vector.c + ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_decoder.c + ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_grad.c + ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_math.c + ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_path.c + ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_pending.c + ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_stroke.c + ${LVGL_DIR}/src/draw/vg_lite/lv_vg_lite_utils.c + ${LVGL_DIR}/src/font/lv_binfont_loader.c ${LVGL_DIR}/src/font/lv_font.c ${LVGL_DIR}/src/font/lv_font_dejavu_16_persian_hebrew.c ${LVGL_DIR}/src/font/lv_font_fmt_txt.c - ${LVGL_DIR}/src/font/lv_font_loader.c ${LVGL_DIR}/src/font/lv_font_montserrat_10.c ${LVGL_DIR}/src/font/lv_font_montserrat_12.c - ${LVGL_DIR}/src/font/lv_font_montserrat_12_subpx.c ${LVGL_DIR}/src/font/lv_font_montserrat_14.c ${LVGL_DIR}/src/font/lv_font_montserrat_16.c ${LVGL_DIR}/src/font/lv_font_montserrat_18.c @@ -170,53 +156,159 @@ zephyr_library_sources( ${LVGL_DIR}/src/font/lv_font_montserrat_46.c ${LVGL_DIR}/src/font/lv_font_montserrat_48.c ${LVGL_DIR}/src/font/lv_font_montserrat_8.c + ${LVGL_DIR}/src/font/lv_font_simsun_14_cjk.c ${LVGL_DIR}/src/font/lv_font_simsun_16_cjk.c ${LVGL_DIR}/src/font/lv_font_unscii_16.c ${LVGL_DIR}/src/font/lv_font_unscii_8.c - ${LVGL_DIR}/src/hal/lv_hal_disp.c - ${LVGL_DIR}/src/hal/lv_hal_indev.c - ${LVGL_DIR}/src/hal/lv_hal_tick.c + ${LVGL_DIR}/src/indev/lv_indev.c + ${LVGL_DIR}/src/indev/lv_indev_scroll.c + + ${LVGL_DIR}/src/layouts/flex/lv_flex.c + ${LVGL_DIR}/src/layouts/grid/lv_grid.c + ${LVGL_DIR}/src/layouts/lv_layout.c + + ${LVGL_DIR}/src/libs/barcode/code128.c + ${LVGL_DIR}/src/libs/barcode/lv_barcode.c + ${LVGL_DIR}/src/libs/bin_decoder/lv_bin_decoder.c + ${LVGL_DIR}/src/libs/bmp/lv_bmp.c + ${LVGL_DIR}/src/libs/ffmpeg/lv_ffmpeg.c + ${LVGL_DIR}/src/libs/freetype/lv_freetype.c + ${LVGL_DIR}/src/libs/freetype/lv_freetype_glyph.c + ${LVGL_DIR}/src/libs/freetype/lv_freetype_image.c + ${LVGL_DIR}/src/libs/freetype/lv_freetype_outline.c + ${LVGL_DIR}/src/libs/freetype/lv_ftsystem.c + ${LVGL_DIR}/src/libs/fsdrv/lv_fs_cbfs.c + ${LVGL_DIR}/src/libs/fsdrv/lv_fs_fatfs.c + ${LVGL_DIR}/src/libs/fsdrv/lv_fs_littlefs.c + ${LVGL_DIR}/src/libs/fsdrv/lv_fs_memfs.c + ${LVGL_DIR}/src/libs/fsdrv/lv_fs_posix.c + ${LVGL_DIR}/src/libs/fsdrv/lv_fs_stdio.c + ${LVGL_DIR}/src/libs/fsdrv/lv_fs_win32.c + ${LVGL_DIR}/src/libs/gif/gifdec.c + ${LVGL_DIR}/src/libs/gif/lv_gif.c + ${LVGL_DIR}/src/libs/libjpeg_turbo/lv_libjpeg_turbo.c + ${LVGL_DIR}/src/libs/libpng/lv_libpng.c + ${LVGL_DIR}/src/libs/lodepng/lodepng.c + ${LVGL_DIR}/src/libs/lodepng/lv_lodepng.c + ${LVGL_DIR}/src/libs/lz4/lz4.c + ${LVGL_DIR}/src/libs/qrcode/lv_qrcode.c + ${LVGL_DIR}/src/libs/qrcode/qrcodegen.c + ${LVGL_DIR}/src/libs/rle/lv_rle.c + ${LVGL_DIR}/src/libs/rlottie/lv_rlottie.c + ${LVGL_DIR}/src/libs/tiny_ttf/lv_tiny_ttf.c + ${LVGL_DIR}/src/libs/tjpgd/lv_tjpgd.c + ${LVGL_DIR}/src/libs/tjpgd/tjpgd.c + ${LVGL_DIR}/src/lv_init.c + + ${LVGL_DIR}/src/misc/cache/lv_cache.c + ${LVGL_DIR}/src/misc/cache/lv_cache_entry.c + ${LVGL_DIR}/src/misc/cache/lv_cache_lru_rb.c + ${LVGL_DIR}/src/misc/cache/lv_image_cache.c + ${LVGL_DIR}/src/misc/cache/lv_image_header_cache.c ${LVGL_DIR}/src/misc/lv_anim.c ${LVGL_DIR}/src/misc/lv_anim_timeline.c ${LVGL_DIR}/src/misc/lv_area.c + ${LVGL_DIR}/src/misc/lv_array.c ${LVGL_DIR}/src/misc/lv_async.c ${LVGL_DIR}/src/misc/lv_bidi.c ${LVGL_DIR}/src/misc/lv_color.c + ${LVGL_DIR}/src/misc/lv_color_op.c + ${LVGL_DIR}/src/misc/lv_event.c ${LVGL_DIR}/src/misc/lv_fs.c - ${LVGL_DIR}/src/misc/lv_gc.c + ${LVGL_DIR}/src/misc/lv_iter.c ${LVGL_DIR}/src/misc/lv_ll.c ${LVGL_DIR}/src/misc/lv_log.c ${LVGL_DIR}/src/misc/lv_lru.c ${LVGL_DIR}/src/misc/lv_math.c - ${LVGL_DIR}/src/misc/lv_mem.c - ${LVGL_DIR}/src/misc/lv_printf.c + ${LVGL_DIR}/src/misc/lv_matrix.c + ${LVGL_DIR}/src/misc/lv_palette.c + ${LVGL_DIR}/src/misc/lv_profiler_builtin.c + ${LVGL_DIR}/src/misc/lv_rb.c ${LVGL_DIR}/src/misc/lv_style.c ${LVGL_DIR}/src/misc/lv_style_gen.c ${LVGL_DIR}/src/misc/lv_templ.c + ${LVGL_DIR}/src/misc/lv_text_ap.c + ${LVGL_DIR}/src/misc/lv_text.c ${LVGL_DIR}/src/misc/lv_timer.c - ${LVGL_DIR}/src/misc/lv_tlsf.c - ${LVGL_DIR}/src/misc/lv_txt_ap.c - ${LVGL_DIR}/src/misc/lv_txt.c ${LVGL_DIR}/src/misc/lv_utils.c + ${LVGL_DIR}/src/osal/lv_os.c + + ${LVGL_DIR}/src/others/file_explorer/lv_file_explorer.c + ${LVGL_DIR}/src/others/fragment/lv_fragment.c + ${LVGL_DIR}/src/others/fragment/lv_fragment_manager.c + ${LVGL_DIR}/src/others/gridnav/lv_gridnav.c + ${LVGL_DIR}/src/others/ime/lv_ime_pinyin.c + ${LVGL_DIR}/src/others/imgfont/lv_imgfont.c + ${LVGL_DIR}/src/others/monkey/lv_monkey.c + ${LVGL_DIR}/src/others/observer/lv_observer.c + ${LVGL_DIR}/src/others/snapshot/lv_snapshot.c + ${LVGL_DIR}/src/others/sysmon/lv_sysmon.c + ${LVGL_DIR}/src/others/vg_lite_tvg/vg_lite_matrix.c + + ${LVGL_DIR}/src/stdlib/builtin/lv_sprintf_builtin.c + ${LVGL_DIR}/src/stdlib/builtin/lv_string_builtin.c + ${LVGL_DIR}/src/stdlib/builtin/lv_tlsf.c + + ${LVGL_DIR}/src/stdlib/clib/lv_mem_core_clib.c + ${LVGL_DIR}/src/stdlib/clib/lv_sprintf_clib.c + ${LVGL_DIR}/src/stdlib/clib/lv_string_clib.c + + ${LVGL_DIR}/src/stdlib/lv_mem.c - ${LVGL_DIR}/src/widgets/lv_arc.c - ${LVGL_DIR}/src/widgets/lv_bar.c - ${LVGL_DIR}/src/widgets/lv_btn.c - ${LVGL_DIR}/src/widgets/lv_btnmatrix.c - ${LVGL_DIR}/src/widgets/lv_canvas.c - ${LVGL_DIR}/src/widgets/lv_checkbox.c - ${LVGL_DIR}/src/widgets/lv_dropdown.c - ${LVGL_DIR}/src/widgets/lv_img.c - ${LVGL_DIR}/src/widgets/lv_label.c - ${LVGL_DIR}/src/widgets/lv_line.c - ${LVGL_DIR}/src/widgets/lv_objx_templ.c - ${LVGL_DIR}/src/widgets/lv_roller.c - ${LVGL_DIR}/src/widgets/lv_slider.c - ${LVGL_DIR}/src/widgets/lv_switch.c - ${LVGL_DIR}/src/widgets/lv_table.c - ${LVGL_DIR}/src/widgets/lv_textarea.c + ${LVGL_DIR}/src/themes/default/lv_theme_default.c + + ${LVGL_DIR}/src/themes/lv_theme.c + ${LVGL_DIR}/src/themes/mono/lv_theme_mono.c + ${LVGL_DIR}/src/themes/simple/lv_theme_simple.c + + ${LVGL_DIR}/src/tick/lv_tick.c + + ${LVGL_DIR}/src/widgets/animimage/lv_animimage.c + ${LVGL_DIR}/src/widgets/arc/lv_arc.c + ${LVGL_DIR}/src/widgets/bar/lv_bar.c + ${LVGL_DIR}/src/widgets/button/lv_button.c + ${LVGL_DIR}/src/widgets/buttonmatrix/lv_buttonmatrix.c + ${LVGL_DIR}/src/widgets/calendar/lv_calendar.c + ${LVGL_DIR}/src/widgets/calendar/lv_calendar_chinese.c + ${LVGL_DIR}/src/widgets/calendar/lv_calendar_header_arrow.c + ${LVGL_DIR}/src/widgets/calendar/lv_calendar_header_dropdown.c + ${LVGL_DIR}/src/widgets/canvas/lv_canvas.c + ${LVGL_DIR}/src/widgets/chart/lv_chart.c + ${LVGL_DIR}/src/widgets/checkbox/lv_checkbox.c + ${LVGL_DIR}/src/widgets/dropdown/lv_dropdown.c + ${LVGL_DIR}/src/widgets/imagebutton/lv_imagebutton.c + ${LVGL_DIR}/src/widgets/image/lv_image.c + ${LVGL_DIR}/src/widgets/keyboard/lv_keyboard.c + ${LVGL_DIR}/src/widgets/label/lv_label.c + ${LVGL_DIR}/src/widgets/led/lv_led.c + ${LVGL_DIR}/src/widgets/line/lv_line.c + ${LVGL_DIR}/src/widgets/list/lv_list.c + ${LVGL_DIR}/src/widgets/lottie/lv_lottie.c + ${LVGL_DIR}/src/widgets/menu/lv_menu.c + ${LVGL_DIR}/src/widgets/msgbox/lv_msgbox.c + ${LVGL_DIR}/src/widgets/objx_templ/lv_objx_templ.c + ${LVGL_DIR}/src/widgets/property/lv_dropdown_properties.c + ${LVGL_DIR}/src/widgets/property/lv_image_properties.c + ${LVGL_DIR}/src/widgets/property/lv_keyboard_properties.c + ${LVGL_DIR}/src/widgets/property/lv_label_properties.c + ${LVGL_DIR}/src/widgets/property/lv_obj_properties.c + ${LVGL_DIR}/src/widgets/property/lv_roller_properties.c + ${LVGL_DIR}/src/widgets/property/lv_style_properties.c + ${LVGL_DIR}/src/widgets/property/lv_textarea_properties.c + ${LVGL_DIR}/src/widgets/roller/lv_roller.c + ${LVGL_DIR}/src/widgets/scale/lv_scale.c + ${LVGL_DIR}/src/widgets/slider/lv_slider.c + ${LVGL_DIR}/src/widgets/span/lv_span.c + ${LVGL_DIR}/src/widgets/spinbox/lv_spinbox.c + ${LVGL_DIR}/src/widgets/spinner/lv_spinner.c + ${LVGL_DIR}/src/widgets/switch/lv_switch.c + ${LVGL_DIR}/src/widgets/table/lv_table.c + ${LVGL_DIR}/src/widgets/tabview/lv_tabview.c + ${LVGL_DIR}/src/widgets/textarea/lv_textarea.c + ${LVGL_DIR}/src/widgets/tileview/lv_tileview.c + ${LVGL_DIR}/src/widgets/win/lv_win.c lvgl.c lvgl_display.c @@ -237,6 +329,8 @@ zephyr_library_sources_ifdef(CONFIG_LV_Z_BUTTON_INPUT input/lvgl_button_input.c) zephyr_library_sources_ifdef(CONFIG_LV_Z_ENCODER_INPUT input/lvgl_encoder_input.c) zephyr_library_sources_ifdef(CONFIG_LV_Z_KEYPAD_INPUT input/lvgl_keypad_input.c) +zephyr_library_sources_ifdef(CONFIG_LV_Z_USE_OSAL lvgl_zephyr_osal.c) + zephyr_library_link_libraries(LVGL) target_link_libraries(LVGL INTERFACE zephyr_interface) diff --git a/modules/lvgl/Kconfig b/modules/lvgl/Kconfig index d2b76451163a5..8084dd11a3322 100644 --- a/modules/lvgl/Kconfig +++ b/modules/lvgl/Kconfig @@ -22,6 +22,9 @@ config LV_CONF_SKIP bool default n +config LV_USE_PRIVATE_API + bool + config LV_USE_LOG bool @@ -77,6 +80,8 @@ choice LV_COLOR_DEPTH config LV_COLOR_DEPTH_32 bool "32: ARGB8888" + config LV_COLOR_DEPTH_24 + bool "24: RGB888" config LV_COLOR_DEPTH_16 bool "16: RGB565" config LV_COLOR_DEPTH_8 @@ -86,7 +91,7 @@ choice LV_COLOR_DEPTH endchoice config LV_COLOR_16_SWAP - bool + bool "Swap the 2 bytes of RGB565 color." depends on LV_COLOR_DEPTH_16 config LV_Z_FLUSH_THREAD @@ -128,15 +133,53 @@ config LV_Z_AREA_Y_ALIGNMENT_WIDTH the current frame dimensions to meet display and/or LCD host controller requirements. The value must be power of 2. -config LV_USE_GPU_STM32_DMA2D +config LV_Z_AUTO_INIT + bool "Initialize LVGL before application startup" + default y + help + Configure LVGL callbacks and display initialization before the application starts. + This can be useful to disable if you need to change a display's pixel format + prior to initialization. If using static allocation, ensure that LV_Z_BITS_PER_PIXEL + is set correctly. + +config LV_Z_INIT_PRIORITY + int "Default init priority for LVGL" + default 90 + depends on LV_Z_AUTO_INIT + help + Priority used for the automatic initialization of LVGL. + +config LV_USE_DRAW_DMA2D bool -config LV_GPU_DMA2D_CMSIS_INCLUDE +config LV_DRAW_DMA2D_HAL_INCLUDE string help Must be defined to include path of CMSIS header of target processor e.g. "stm32f769xx.h" or "stm32f429xx.h" +config LV_Z_USE_OSAL + bool "Use OSAL enabling parallel rendering" + depends on DYNAMIC_THREAD + select LV_USE_PRIVATE_API + help + Use the Zephyr LVGL OSAL to enable parallel rendering + pipelines. + +config LV_USE_PXP + bool + +config LV_USE_GPU_NXP_PXP + bool + default y if LV_USE_PXP + +config LV_Z_PXP_INTERRUPT_PRIORITY + int "PXP interrupt priority" + depends on LV_USE_PXP + default 3 + help + Sets the interrupt priority for PXP + rsource "Kconfig.memory" rsource "Kconfig.input" rsource "Kconfig.shell" diff --git a/modules/lvgl/Kconfig.memory b/modules/lvgl/Kconfig.memory index 4b4eaeefdaf72..50a14addf3096 100644 --- a/modules/lvgl/Kconfig.memory +++ b/modules/lvgl/Kconfig.memory @@ -7,8 +7,12 @@ menu "Memory manager settings" config LV_Z_BITS_PER_PIXEL int "Bits per pixel" default 32 + default 32 if LV_COLOR_DEPTH_32 + default 24 if LV_COLOR_DEPTH_24 + default 16 if LV_COLOR_DEPTH_16 + default 8 if LV_COLOR_DEPTH_8 + default 1 if LV_COLOR_DEPTH_1 range 1 32 - depends on LV_Z_BUFFER_ALLOC_STATIC help Number of bits per pixel. @@ -79,7 +83,7 @@ config LV_Z_VDB_ALIGN buffer may be accessed as a uint8_t *, uint16_t *, or uint32_t *, so buffer must be aligned to prevent unaligned memory access -config LV_Z_VBD_CUSTOM_SECTION +config LV_Z_VDB_CUSTOM_SECTION bool "Link rendering buffers to custom section" depends on LV_Z_BUFFER_ALLOC_STATIC help @@ -88,6 +92,13 @@ config LV_Z_VBD_CUSTOM_SECTION rendering buffers to a custom location, such as tightly coupled or external memory. +config LV_Z_MONOCHROME_CONVERSION_BUFFER + bool "Use intermediate conversion buffer for monochrome displays" + default y + help + When using a monochrome display an intermediate buffer with LV_Z_VDB_SIZE + is needed to perform the conversion. + choice LV_Z_RENDERING_BUFFER_ALLOCATION prompt "Rendering Buffer Allocation" default LV_Z_BUFFER_ALLOC_STATIC diff --git a/modules/lvgl/include/lv_conf.h b/modules/lvgl/include/lv_conf.h index a47bcec47d252..8f73f5e87b63b 100644 --- a/modules/lvgl/include/lv_conf.h +++ b/modules/lvgl/include/lv_conf.h @@ -12,41 +12,38 @@ /* Memory manager settings */ -#define LV_MEMCPY_MEMSET_STD 1 -#define LV_MEM_CUSTOM 1 +#define LV_USE_STDLIB_MALLOC LV_STDLIB_CUSTOM #if defined(CONFIG_LV_Z_MEM_POOL_HEAP_LIB_C) - -#define LV_MEM_CUSTOM_INCLUDE "stdlib.h" -#define LV_MEM_CUSTOM_ALLOC malloc -#define LV_MEM_CUSTOM_REALLOC realloc -#define LV_MEM_CUSTOM_FREE free - +#define LV_STDLIB_INCLUDE "stdlib.h" +#define lv_malloc_core malloc +#define lv_realloc_core realloc +#define lv_free_core free #else - -#define LV_MEM_CUSTOM_INCLUDE "lvgl_mem.h" -#define LV_MEM_CUSTOM_ALLOC lvgl_malloc -#define LV_MEM_CUSTOM_REALLOC lvgl_realloc -#define LV_MEM_CUSTOM_FREE lvgl_free - +#define LV_STDLIB_INCLUDE "lvgl_mem.h" +#define lv_malloc_core lvgl_malloc +#define lv_realloc_core lvgl_realloc +#define lv_free_core lvgl_free #endif -/* HAL settings */ - -#define LV_TICK_CUSTOM 1 -#define LV_TICK_CUSTOM_INCLUDE -#define LV_TICK_CUSTOM_SYS_TIME_EXPR (k_uptime_get_32()) - /* Misc settings */ - -#define LV_SPRINTF_CUSTOM 1 -#define LV_SPRINTF_INCLUDE "stdio.h" -#define lv_snprintf snprintf -#define lv_vsnprintf vsnprintf +#define lv_snprintf snprintf +#define lv_vsnprintf vsnprintf +#define LV_ASSERT_HANDLER __ASSERT_NO_MSG(false); +#define LV_ASSERT_HANDLER_INCLUDE "zephyr/sys/__assert.h" /* Provide definition to align LVGL buffers */ #define LV_ATTRIBUTE_MEM_ALIGN __aligned(CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE) +#ifdef CONFIG_LV_COLOR_16_SWAP +#define LV_COLOR_16_SWAP 1 +#endif /* CONFIG_LV_COLOR_16_SWAP */ + +#ifdef CONFIG_LV_Z_USE_OSAL +#define LV_USE_OS LV_OS_CUSTOM +#define LV_OS_CUSTOM_INCLUDE "lvgl_zephyr_osal.h" +#endif /* CONFIG_LV_Z_USE_OSAL */ + /* * Needed because of a workaround for a GCC bug, * see https://github.com/lvgl/lvgl/issues/3078 diff --git a/modules/lvgl/include/lvgl_common_input.h b/modules/lvgl/include/lvgl_common_input.h index f4aaffae2a2f3..72a931a9921f6 100644 --- a/modules/lvgl/include/lvgl_common_input.h +++ b/modules/lvgl/include/lvgl_common_input.h @@ -20,7 +20,6 @@ struct lvgl_common_input_config { }; struct lvgl_common_input_data { - lv_indev_drv_t indev_drv; lv_indev_t *indev; lv_indev_data_t pending_event; lv_indev_data_t previous_event; diff --git a/modules/lvgl/include/lvgl_display.h b/modules/lvgl/include/lvgl_display.h index 9a0c14c6831d7..bbe4a3193b2cb 100644 --- a/modules/lvgl/include/lvgl_display.h +++ b/modules/lvgl/include/lvgl_display.h @@ -22,35 +22,27 @@ struct lvgl_disp_data { }; struct lvgl_display_flush { - lv_disp_drv_t *disp_drv; + lv_display_t *display; uint16_t x; uint16_t y; struct display_buffer_descriptor desc; void *buf; }; -void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); -void lvgl_flush_cb_16bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); -void lvgl_flush_cb_24bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); -void lvgl_flush_cb_32bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); +void lvgl_flush_cb_mono(lv_display_t *display, const lv_area_t *area, uint8_t *px_map); +void lvgl_flush_cb_16bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map); +void lvgl_flush_cb_24bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map); +void lvgl_flush_cb_32bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map); -void lvgl_set_px_cb_mono(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, lv_color_t color, lv_opa_t opa); -void lvgl_set_px_cb_16bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, lv_color_t color, lv_opa_t opa); -void lvgl_set_px_cb_24bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, lv_color_t color, lv_opa_t opa); -void lvgl_set_px_cb_32bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, lv_color_t color, lv_opa_t opa); +void lvgl_rounder_cb_mono(lv_event_t *e); +void lvgl_set_mono_conversion_buffer(uint8_t *buffer, uint32_t buffer_size); -void lvgl_rounder_cb_mono(lv_disp_drv_t *disp_drv, lv_area_t *area); - -int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv); +int set_lvgl_rendering_cb(lv_display_t *display); void lvgl_flush_display(struct lvgl_display_flush *request); #ifdef CONFIG_LV_Z_USE_ROUNDER_CB -void lvgl_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area); +void lvgl_rounder_cb(lv_event_t *e); #endif #ifdef __cplusplus diff --git a/modules/lvgl/include/lvgl_mem.h b/modules/lvgl/include/lvgl_mem.h index 02dea4537a0da..61ce0ba0d224f 100644 --- a/modules/lvgl/include/lvgl_mem.h +++ b/modules/lvgl/include/lvgl_mem.h @@ -9,6 +9,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -22,6 +23,8 @@ void lvgl_free(void *ptr); void lvgl_print_heap_info(bool dump_chunks); +void lvgl_heap_stats(struct sys_memory_stats *stats); + void lvgl_heap_init(void); #ifdef __cplusplus diff --git a/modules/lvgl/include/lvgl_support.h b/modules/lvgl/include/lvgl_support.h new file mode 100644 index 0000000000000..7b996773b90f8 --- /dev/null +++ b/modules/lvgl/include/lvgl_support.h @@ -0,0 +1,17 @@ +/* + * Copyright 2023 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_LVGL_LVGL_SUPPORT_H_ +#define ZEPHYR_MODULES_LVGL_LVGL_SUPPORT_H_ + +#include + +static ALWAYS_INLINE void DEMO_CleanInvalidateCacheByAddr(void *addr, uint16_t size) +{ + sys_cache_data_invd_range(addr, size); +} + +#endif /* ZEPHYR_MODULES_LVGL_LVGL_SUPPORT_H_ */ diff --git a/modules/lvgl/include/lvgl_zephyr.h b/modules/lvgl/include/lvgl_zephyr.h new file mode 100644 index 0000000000000..28a69f1ce4be2 --- /dev/null +++ b/modules/lvgl/include/lvgl_zephyr.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_LVGL_ZEPHYR_H_ +#define ZEPHYR_MODULES_LVGL_ZEPHYR_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the LittlevGL library + * + * This function initializes the LittlevGL library and setups the display and input devices. + * If `LV_Z_AUTO_INIT` is disabled it must be called before any other LittlevGL function. + * + * @return 0 on success, negative errno code on failure + */ +int lvgl_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_MODULES_LVGL_ZEPHYR_H_ */ diff --git a/modules/lvgl/include/lvgl_zephyr_osal.h b/modules/lvgl/include/lvgl_zephyr_osal.h new file mode 100644 index 0000000000000..07877741bd879 --- /dev/null +++ b/modules/lvgl/include/lvgl_zephyr_osal.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_LVGL_ZEPHYR_OSAL_H_ +#define ZEPHYR_MODULES_LVGL_ZEPHYR_OSAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + k_tid_t tid; + k_thread_stack_t *stack; + struct k_thread thread; +} lv_thread_t; + +typedef struct k_mutex lv_mutex_t; + +typedef struct k_sem lv_thread_sync_t; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_MODULES_LVGL_ZEPHYR_OSAL_H_ */ diff --git a/modules/lvgl/input/lvgl_button_input.c b/modules/lvgl/input/lvgl_button_input.c index 9976df48ca77c..b5dcd53d78068 100644 --- a/modules/lvgl/input/lvgl_button_input.c +++ b/modules/lvgl/input/lvgl_button_input.c @@ -17,7 +17,7 @@ struct lvgl_button_input_config { struct lvgl_common_input_config common_config; /* Needs to be first member */ const uint16_t *input_codes; uint8_t num_codes; - const lv_coord_t *coordinates; + const int32_t *coordinates; }; static void lvgl_button_process_event(struct input_event *evt, void *user_data) @@ -39,7 +39,7 @@ static void lvgl_button_process_event(struct input_event *evt, void *user_data) } data->pending_event.btn_id = i; - data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + data->pending_event.state = evt->value ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event, K_NO_WAIT) != 0) { LOG_WRN("Could not put input data into queue"); @@ -72,8 +72,7 @@ int lvgl_button_input_init(const struct device *dev) LVGL_INPUT_DEFINE(inst, button, CONFIG_LV_Z_BUTTON_INPUT_MSGQ_COUNT, \ lvgl_button_process_event); \ static const uint16_t lvgl_button_input_codes_##inst[] = DT_INST_PROP(inst, input_codes); \ - static const lv_coord_t lvgl_button_coordinates_##inst[] = \ - DT_INST_PROP(inst, coordinates); \ + static const int32_t lvgl_button_coordinates_##inst[] = DT_INST_PROP(inst, coordinates); \ static const struct lvgl_button_input_config lvgl_button_input_config_##inst = { \ .common_config.event_msgq = &LVGL_INPUT_EVENT_MSGQ(inst, button), \ .input_codes = lvgl_button_input_codes_##inst, \ diff --git a/modules/lvgl/input/lvgl_common_input.c b/modules/lvgl/input/lvgl_common_input.c index c58d4cb84cd42..487c606d7ad97 100644 --- a/modules/lvgl/input/lvgl_common_input.c +++ b/modules/lvgl/input/lvgl_common_input.c @@ -23,15 +23,15 @@ lv_indev_t *lvgl_input_get_indev(const struct device *dev) return common_data->indev; } -static void lvgl_input_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) +static void lvgl_input_read_cb(lv_indev_t *indev, lv_indev_data_t *data) { - const struct device *dev = drv->user_data; + const struct device *dev = lv_indev_get_user_data(indev); const struct lvgl_common_input_config *cfg = dev->config; struct lvgl_common_input_data *common_data = dev->data; if (k_msgq_get(cfg->event_msgq, data, K_NO_WAIT) != 0) { memcpy(data, &common_data->previous_event, sizeof(lv_indev_data_t)); - if (drv->type == LV_INDEV_TYPE_ENCODER) { + if (lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER) { data->enc_diff = 0; /* For encoders, clear last movement */ } data->continue_reading = false; @@ -54,16 +54,16 @@ int lvgl_input_register_driver(lv_indev_type_t indev_type, const struct device * return -EINVAL; } - lv_indev_drv_init(&common_data->indev_drv); - common_data->indev_drv.type = indev_type; - common_data->indev_drv.read_cb = lvgl_input_read_cb; - common_data->indev_drv.user_data = (void *)dev; - common_data->indev = lv_indev_drv_register(&common_data->indev_drv); + common_data->indev = lv_indev_create(); if (common_data->indev == NULL) { return -EINVAL; } + lv_indev_set_type(common_data->indev, indev_type); + lv_indev_set_read_cb(common_data->indev, lvgl_input_read_cb); + lv_indev_set_user_data(common_data->indev, (void *)dev); + return 0; } diff --git a/modules/lvgl/input/lvgl_encoder_input.c b/modules/lvgl/input/lvgl_encoder_input.c index fd32e2b53c091..7d63e2d4e0788 100644 --- a/modules/lvgl/input/lvgl_encoder_input.c +++ b/modules/lvgl/input/lvgl_encoder_input.c @@ -28,7 +28,8 @@ static void lvgl_encoder_process_event(struct input_event *evt, void *user_data) if (evt->code == cfg->rotation_input_code) { data->pending_event.enc_diff = evt->value; } else if (evt->code == cfg->button_input_code) { - data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + data->pending_event.state = + evt->value ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; data->pending_event.enc_diff = 0; data->pending_event.key = LV_KEY_ENTER; } else { diff --git a/modules/lvgl/input/lvgl_keypad_input.c b/modules/lvgl/input/lvgl_keypad_input.c index 963784df0965c..77f9eb2092264 100644 --- a/modules/lvgl/input/lvgl_keypad_input.c +++ b/modules/lvgl/input/lvgl_keypad_input.c @@ -40,7 +40,7 @@ static void lvgl_keypad_process_event(struct input_event *evt, void *user_data) return; } - data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + data->pending_event.state = evt->value ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event, K_NO_WAIT) != 0) { LOG_WRN("Could not put input data into keypad queue"); } diff --git a/modules/lvgl/input/lvgl_pointer_input.c b/modules/lvgl/input/lvgl_pointer_input.c index 89f35cd04e26b..0777ec2bac5f5 100644 --- a/modules/lvgl/input/lvgl_pointer_input.c +++ b/modules/lvgl/input/lvgl_pointer_input.c @@ -32,8 +32,8 @@ static void lvgl_pointer_process_event(struct input_event *evt, void *user_data) const struct device *dev = user_data; const struct lvgl_pointer_input_config *cfg = dev->config; struct lvgl_pointer_input_data *data = dev->data; - lv_disp_t *disp = lv_disp_get_default(); - struct lvgl_disp_data *disp_data = disp->driver->user_data; + lv_display_t *disp = lv_display_get_default(); + struct lvgl_disp_data *disp_data = (struct lvgl_disp_data *)lv_display_get_user_data(disp); struct display_capabilities *cap = &disp_data->cap; lv_point_t *point = &data->common_data.pending_event.point; @@ -54,7 +54,7 @@ static void lvgl_pointer_process_event(struct input_event *evt, void *user_data) break; case INPUT_BTN_TOUCH: data->common_data.pending_event.state = - evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + evt->value ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; break; } diff --git a/modules/lvgl/lvgl.c b/modules/lvgl/lvgl.c index 76df359e7fc73..664f6fdb03a38 100644 --- a/modules/lvgl/lvgl.c +++ b/modules/lvgl/lvgl.c @@ -9,89 +9,91 @@ #include #include "lvgl_display.h" #include "lvgl_common_input.h" +#include "lvgl_zephyr.h" #ifdef CONFIG_LV_Z_USE_FILESYSTEM #include "lvgl_fs.h" #endif #ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP #include "lvgl_mem.h" #endif -#include LV_MEM_CUSTOM_INCLUDE +#include LV_STDLIB_INCLUDE #include LOG_MODULE_REGISTER(lvgl, CONFIG_LV_Z_LOG_LEVEL); -static lv_disp_drv_t disp_drv; +static lv_display_t *display; struct lvgl_disp_data disp_data = { .blanking_on = false, }; -#define DISPLAY_NODE DT_CHOSEN(zephyr_display) +#define DISPLAY_NODE DT_CHOSEN(zephyr_display) +#define IS_MONOCHROME_DISPLAY ((CONFIG_LV_Z_BITS_PER_PIXEL == 1) || (CONFIG_LV_COLOR_DEPTH_1 == 1)) +#define ALLOC_MONOCHROME_CONV_BUFFER \ + ((IS_MONOCHROME_DISPLAY == 1) && (CONFIG_LV_Z_MONOCHROME_CONVERSION_BUFFER == 1)) #ifdef CONFIG_LV_Z_BUFFER_ALLOC_STATIC -static lv_disp_draw_buf_t disp_buf; - #define DISPLAY_WIDTH DT_PROP(DISPLAY_NODE, width) #define DISPLAY_HEIGHT DT_PROP(DISPLAY_NODE, height) +#if IS_MONOCHROME_DISPLAY +/* monochrome buffers are expected to have 8 preceding bytes for the color palette */ +#define BUFFER_SIZE \ + (((CONFIG_LV_Z_VDB_SIZE * ROUND_UP(DISPLAY_WIDTH, 8) * ROUND_UP(DISPLAY_HEIGHT, 8)) / \ + 100) / 8 + \ + 8) +#else #define BUFFER_SIZE \ (CONFIG_LV_Z_BITS_PER_PIXEL * \ ((CONFIG_LV_Z_VDB_SIZE * DISPLAY_WIDTH * DISPLAY_HEIGHT) / 100) / 8) - -#define NBR_PIXELS_IN_BUFFER (BUFFER_SIZE * 8 / CONFIG_LV_Z_BITS_PER_PIXEL) +#endif /* IS_MONOCHROME_DISPLAY */ /* NOTE: depending on chosen color depth buffer may be accessed using uint8_t *, * uint16_t * or uint32_t *, therefore buffer needs to be aligned accordingly to * prevent unaligned memory accesses. */ static uint8_t buf0[BUFFER_SIZE] -#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION +#ifdef CONFIG_LV_Z_VDB_CUSTOM_SECTION Z_GENERIC_SECTION(.lvgl_buf) #endif __aligned(CONFIG_LV_Z_VDB_ALIGN); #ifdef CONFIG_LV_Z_DOUBLE_VDB static uint8_t buf1[BUFFER_SIZE] -#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION +#ifdef CONFIG_LV_Z_VDB_CUSTOM_SECTION Z_GENERIC_SECTION(.lvgl_buf) #endif __aligned(CONFIG_LV_Z_VDB_ALIGN); #endif /* CONFIG_LV_Z_DOUBLE_VDB */ +#if ALLOC_MONOCHROME_CONV_BUFFER +static uint8_t mono_vtile_buf[BUFFER_SIZE] +#ifdef CONFIG_LV_Z_VDB_CUSTOM_SECTION + Z_GENERIC_SECTION(.lvgl_buf) +#endif + __aligned(CONFIG_LV_Z_VDB_ALIGN); +#endif /* ALLOC_MONOCHROME_CONV_BUFFER */ + #endif /* CONFIG_LV_Z_BUFFER_ALLOC_STATIC */ #if CONFIG_LV_Z_LOG_LEVEL != 0 -/* - * In LVGLv8 the signature of the logging callback has changes and it no longer - * takes the log level as an integer argument. Instead, the log level is now - * already part of the buffer passed to the logging callback. It's not optimal - * but we need to live with it and parse the buffer manually to determine the - * level and then truncate the string we actually pass to the logging framework. - */ -static void lvgl_log(const char *buf) +static void lvgl_log(lv_log_level_t level, const char *buf) { - /* - * This is ugly and should be done in a loop or something but as it - * turned out, Z_LOG()'s first argument (that specifies the log level) - * cannot be an l-value... - * - * We also assume lvgl is sane and always supplies the level string. - */ - switch (buf[1]) { - case 'E': - LOG_ERR("%s", buf + strlen("[Error] ")); + switch (level) { + case LV_LOG_LEVEL_ERROR: + LOG_ERR("%s", buf + (sizeof("[Error] ") - 1)); break; - case 'W': - LOG_WRN("%s", buf + strlen("[Warn] ")); + case LV_LOG_LEVEL_WARN: + LOG_WRN("%s", buf + (sizeof("[Warn] ") - 1)); break; - case 'I': - LOG_INF("%s", buf + strlen("[Info] ")); + case LV_LOG_LEVEL_INFO: + LOG_INF("%s", buf + (sizeof("[Info] ") - 1)); break; - case 'T': - LOG_DBG("%s", buf + strlen("[Trace] ")); + case LV_LOG_LEVEL_TRACE: + LOG_DBG("%s", buf + (sizeof("[Trace] ") - 1)); break; - case 'U': - LOG_INF("%s", buf + strlen("[User] ")); + case LV_LOG_LEVEL_USER: + LOG_INF("%s", buf + (sizeof("[User] ") - 1)); break; } } @@ -99,52 +101,39 @@ static void lvgl_log(const char *buf) #ifdef CONFIG_LV_Z_BUFFER_ALLOC_STATIC -static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver) +static int lvgl_allocate_rendering_buffers(lv_display_t *display) { - struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_driver->user_data; int err = 0; - if (data->cap.x_resolution <= DISPLAY_WIDTH) { - disp_driver->hor_res = data->cap.x_resolution; - } else { - LOG_ERR("Horizontal resolution is larger than maximum"); - err = -ENOTSUP; - } - - if (data->cap.y_resolution <= DISPLAY_HEIGHT) { - disp_driver->ver_res = data->cap.y_resolution; - } else { - LOG_ERR("Vertical resolution is larger than maximum"); - err = -ENOTSUP; - } - - disp_driver->draw_buf = &disp_buf; #ifdef CONFIG_LV_Z_DOUBLE_VDB - lv_disp_draw_buf_init(disp_driver->draw_buf, &buf0, &buf1, NBR_PIXELS_IN_BUFFER); + lv_display_set_buffers(display, &buf0, &buf1, BUFFER_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL); #else - lv_disp_draw_buf_init(disp_driver->draw_buf, &buf0, NULL, NBR_PIXELS_IN_BUFFER); + lv_display_set_buffers(display, &buf0, NULL, BUFFER_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL); #endif /* CONFIG_LV_Z_DOUBLE_VDB */ +#if ALLOC_MONOCHROME_CONV_BUFFER + lvgl_set_mono_conversion_buffer(mono_vtile_buf, BUFFER_SIZE); +#endif /* ALLOC_MONOCHROME_CONV_BUFFER */ + return err; } #else -static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver) +static int lvgl_allocate_rendering_buffers(lv_display_t *display) { void *buf0 = NULL; void *buf1 = NULL; uint16_t buf_nbr_pixels; uint32_t buf_size; - struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_driver->user_data; - - disp_driver->hor_res = data->cap.x_resolution; - disp_driver->ver_res = data->cap.y_resolution; + struct lvgl_disp_data *data = (struct lvgl_disp_data *)lv_display_get_user_data(display); + uint16_t hor_res = lv_display_get_horizontal_resolution(display); + uint16_t ver_res = lv_display_get_vertical_resolution(display); - buf_nbr_pixels = (CONFIG_LV_Z_VDB_SIZE * disp_driver->hor_res * disp_driver->ver_res) / 100; + buf_nbr_pixels = (CONFIG_LV_Z_VDB_SIZE * hor_res * ver_res) / 100; /* one horizontal line is the minimum buffer requirement for lvgl */ - if (buf_nbr_pixels < disp_driver->hor_res) { - buf_nbr_pixels = disp_driver->hor_res; + if (buf_nbr_pixels < hor_res) { + buf_nbr_pixels = hor_res; } switch (data->cap.current_pixel_format) { @@ -159,42 +148,80 @@ static int lvgl_allocate_rendering_buffers(lv_disp_drv_t *disp_driver) break; case PIXEL_FORMAT_MONO01: case PIXEL_FORMAT_MONO10: - buf_size = buf_nbr_pixels / 8; + buf_size = buf_nbr_pixels / 8 + 8; buf_size += (buf_nbr_pixels % 8) == 0 ? 0 : 1; break; default: return -ENOTSUP; } - buf0 = LV_MEM_CUSTOM_ALLOC(buf_size); + buf0 = lv_malloc(buf_size); if (buf0 == NULL) { LOG_ERR("Failed to allocate memory for rendering buffer"); return -ENOMEM; } #ifdef CONFIG_LV_Z_DOUBLE_VDB - buf1 = LV_MEM_CUSTOM_ALLOC(buf_size); + buf1 = lv_malloc(buf_size); if (buf1 == NULL) { - LV_MEM_CUSTOM_FREE(buf0); + lv_free(buf0); LOG_ERR("Failed to allocate memory for rendering buffer"); return -ENOMEM; } #endif - disp_driver->draw_buf = LV_MEM_CUSTOM_ALLOC(sizeof(lv_disp_draw_buf_t)); - if (disp_driver->draw_buf == NULL) { - LV_MEM_CUSTOM_FREE(buf0); - LV_MEM_CUSTOM_FREE(buf1); - LOG_ERR("Failed to allocate memory to store rendering buffers"); +#if ALLOC_MONOCHROME_CONV_BUFFER + void *vtile_buf = lv_malloc(buf_size); + + if (vtile_buf == NULL) { + lv_free(buf0); + lv_free(buf1); + LOG_ERR("Failed to allocate memory for vtile buffer"); return -ENOMEM; } + lvgl_set_mono_conversion_buffer(vtile_buf, buf_size); +#endif /* ALLOC_MONOCHROME_CONV_BUFFER */ - lv_disp_draw_buf_init(disp_driver->draw_buf, buf0, buf1, buf_nbr_pixels); + lv_display_set_buffers(display, buf0, buf1, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL); return 0; } #endif /* CONFIG_LV_Z_BUFFER_ALLOC_STATIC */ -static int lvgl_init(void) +void lv_mem_init(void) +{ +#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP + lvgl_heap_init(); +#endif /* CONFIG_LV_Z_MEM_POOL_SYS_HEAP */ +} + +void lv_mem_deinit(void) +{ + /* Reinitializing the heap clears all allocations, no action needed */ +} + +void lv_mem_monitor_core(lv_mem_monitor_t *mon_p) +{ + memset(mon_p, 0, sizeof(lv_mem_monitor_t)); + +#if CONFIG_LV_Z_MEM_POOL_SYS_HEAP + struct sys_memory_stats stats; + + lvgl_heap_stats(&stats); + mon_p->used_pct = + (stats.allocated_bytes * 100) / (stats.allocated_bytes + stats.free_bytes); + mon_p->max_used = stats.max_allocated_bytes; +#else + LOG_WRN_ONCE("Memory statistics only supported for CONFIG_LV_Z_MEM_POOL_SYS_HEAP"); +#endif /* CONFIG_LV_Z_MEM_POOL_SYS_HEAP */ +} + +lv_result_t lv_mem_test_core(void) +{ + /* Not supported for now */ + return LV_RESULT_OK; +} + +int lvgl_init(void) { const struct device *display_dev = DEVICE_DT_GET(DISPLAY_NODE); @@ -205,15 +232,12 @@ static int lvgl_init(void) return -ENODEV; } -#ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP - lvgl_heap_init(); -#endif - #if CONFIG_LV_Z_LOG_LEVEL != 0 lv_log_register_print_cb(lvgl_log); #endif lv_init(); + lv_tick_set_cb(k_uptime_get_32); #ifdef CONFIG_LV_Z_USE_FILESYSTEM lvgl_fs_init(); @@ -222,28 +246,26 @@ static int lvgl_init(void) disp_data.display_dev = display_dev; display_get_capabilities(display_dev, &disp_data.cap); - lv_disp_drv_init(&disp_drv); - disp_drv.user_data = (void *)&disp_data; - -#ifdef CONFIG_LV_Z_FULL_REFRESH - disp_drv.full_refresh = 1; -#endif - - err = lvgl_allocate_rendering_buffers(&disp_drv); - if (err != 0) { - return err; + display = lv_display_create(disp_data.cap.x_resolution, disp_data.cap.y_resolution); + if (!display) { + return -ENOMEM; } + lv_display_set_user_data(display, &disp_data); - if (set_lvgl_rendering_cb(&disp_drv) != 0) { + if (set_lvgl_rendering_cb(display) != 0) { LOG_ERR("Display not supported."); return -ENOTSUP; } - if (lv_disp_drv_register(&disp_drv) == NULL) { - LOG_ERR("Failed to register display device."); - return -EPERM; + err = lvgl_allocate_rendering_buffers(display); + if (err != 0) { + return err; } +#ifdef CONFIG_LV_Z_FULL_REFRESH + lv_display_set_render_mode(display, LV_DISPLAY_RENDER_MODE_FULL); +#endif + err = lvgl_init_input_devices(); if (err < 0) { LOG_ERR("Failed to initialize input devices."); @@ -253,4 +275,6 @@ static int lvgl_init(void) return 0; } -SYS_INIT(lvgl_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); +#ifdef CONFIG_LV_Z_AUTO_INIT +SYS_INIT(lvgl_init, APPLICATION, CONFIG_LV_Z_INIT_PRIORITY); +#endif /* CONFIG_LV_Z_AUTO_INIT */ diff --git a/modules/lvgl/lvgl_display.c b/modules/lvgl/lvgl_display.c index 12f84725008a2..72c371cfc84a2 100644 --- a/modules/lvgl/lvgl_display.c +++ b/modules/lvgl/lvgl_display.c @@ -13,6 +13,8 @@ #ifdef CONFIG_LV_Z_FLUSH_THREAD K_SEM_DEFINE(flush_complete, 0, 1); +/* Needed because the wait callback might be called even if not flush is pending */ +K_SEM_DEFINE(flush_required, 0, 1); /* Message queue will only ever need to queue one message */ K_MSGQ_DEFINE(flush_queue, sizeof(struct lvgl_display_flush), 1, 1); @@ -23,13 +25,11 @@ void lvgl_flush_thread_entry(void *arg1, void *arg2, void *arg3) while (1) { k_msgq_get(&flush_queue, &flush, K_FOREVER); - data = (struct lvgl_disp_data *)flush.disp_drv->user_data; + data = (struct lvgl_disp_data *)lv_display_get_user_data(flush.display); - flush.desc.frame_incomplete = !lv_disp_flush_is_last(flush.disp_drv); - display_write(data->display_dev, flush.x, flush.y, &flush.desc, - flush.buf); + flush.desc.frame_incomplete = !lv_display_flush_is_last(flush.display); + display_write(data->display_dev, flush.x, flush.y, &flush.desc, flush.buf); - lv_disp_flush_ready(flush.disp_drv); k_sem_give(&flush_complete); } } @@ -37,17 +37,19 @@ void lvgl_flush_thread_entry(void *arg1, void *arg2, void *arg3) K_THREAD_DEFINE(lvgl_flush_thread, CONFIG_LV_Z_FLUSH_THREAD_STACK_SIZE, lvgl_flush_thread_entry, NULL, NULL, NULL, CONFIG_LV_Z_FLUSH_THREAD_PRIORITY, 0, 0); - -void lvgl_wait_cb(lv_disp_drv_t *disp_drv) +void lvgl_wait_cb(lv_display_t *display) { - k_sem_take(&flush_complete, K_FOREVER); + if (k_sem_take(&flush_required, K_NO_WAIT) == 0) { + k_sem_take(&flush_complete, K_FOREVER); + } } #endif /* CONFIG_LV_Z_FLUSH_THREAD */ #ifdef CONFIG_LV_Z_USE_ROUNDER_CB -void lvgl_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) +void lvgl_rounder_cb(lv_event_t *e) { + lv_area_t *area = lv_event_get_param(e); #if CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH != 1 __ASSERT(POPCOUNT(CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH) == 1, "Invalid X alignment width"); @@ -65,50 +67,46 @@ void lvgl_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) #define lvgl_rounder_cb NULL #endif -int set_lvgl_rendering_cb(lv_disp_drv_t *disp_drv) +int set_lvgl_rendering_cb(lv_display_t *display) { int err = 0; - struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data; + struct lvgl_disp_data *data = (struct lvgl_disp_data *)lv_display_get_user_data(display); #ifdef CONFIG_LV_Z_FLUSH_THREAD - disp_drv->wait_cb = lvgl_wait_cb; + lv_display_set_flush_wait_cb(display, lvgl_wait_cb); #endif switch (data->cap.current_pixel_format) { case PIXEL_FORMAT_ARGB_8888: - disp_drv->flush_cb = lvgl_flush_cb_32bit; - disp_drv->rounder_cb = lvgl_rounder_cb; -#ifdef CONFIG_LV_COLOR_DEPTH_32 - disp_drv->set_px_cb = NULL; -#else - disp_drv->set_px_cb = lvgl_set_px_cb_32bit; -#endif + lv_display_set_color_format(display, LV_COLOR_FORMAT_ARGB8888); + lv_display_set_flush_cb(display, lvgl_flush_cb_32bit); + lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA, + display); break; case PIXEL_FORMAT_RGB_888: - disp_drv->flush_cb = lvgl_flush_cb_24bit; - disp_drv->rounder_cb = lvgl_rounder_cb; - disp_drv->set_px_cb = lvgl_set_px_cb_24bit; + lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB888); + lv_display_set_flush_cb(display, lvgl_flush_cb_24bit); + lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA, + display); break; case PIXEL_FORMAT_RGB_565: case PIXEL_FORMAT_BGR_565: - disp_drv->flush_cb = lvgl_flush_cb_16bit; - disp_drv->rounder_cb = lvgl_rounder_cb; -#ifdef CONFIG_LV_COLOR_DEPTH_16 - disp_drv->set_px_cb = NULL; -#else - disp_drv->set_px_cb = lvgl_set_px_cb_16bit; -#endif + lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB565); + lv_display_set_flush_cb(display, lvgl_flush_cb_16bit); + lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA, + display); break; case PIXEL_FORMAT_MONO01: case PIXEL_FORMAT_MONO10: - disp_drv->flush_cb = lvgl_flush_cb_mono; - disp_drv->rounder_cb = lvgl_rounder_cb_mono; - disp_drv->set_px_cb = lvgl_set_px_cb_mono; + lv_display_set_color_format(display, LV_COLOR_FORMAT_I1); + lv_display_set_flush_cb(display, lvgl_flush_cb_mono); + lv_display_add_event_cb(display, lvgl_rounder_cb_mono, LV_EVENT_INVALIDATE_AREA, + display); break; default: - disp_drv->flush_cb = NULL; - disp_drv->rounder_cb = NULL; - disp_drv->set_px_cb = NULL; + lv_display_set_flush_cb(display, NULL); + lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA, + display); err = -ENOTSUP; break; } @@ -125,16 +123,16 @@ void lvgl_flush_display(struct lvgl_display_flush *request) */ k_sem_reset(&flush_complete); k_msgq_put(&flush_queue, request, K_FOREVER); + k_sem_give(&flush_required); /* Explicitly yield, in case the calling thread is a cooperative one */ k_yield(); #else /* Write directly to the display */ struct lvgl_disp_data *data = - (struct lvgl_disp_data *)request->disp_drv->user_data; + (struct lvgl_disp_data *)lv_display_get_user_data(request->display); - request->desc.frame_incomplete = !lv_disp_flush_is_last(request->disp_drv); - display_write(data->display_dev, request->x, request->y, - &request->desc, request->buf); - lv_disp_flush_ready(request->disp_drv); + request->desc.frame_incomplete = !lv_display_flush_is_last(request->display); + display_write(data->display_dev, request->x, request->y, &request->desc, request->buf); + lv_display_flush_ready(request->display); #endif } diff --git a/modules/lvgl/lvgl_display_16bit.c b/modules/lvgl/lvgl_display_16bit.c index 9e8fa81bdecdf..084cce0e37133 100644 --- a/modules/lvgl/lvgl_display_16bit.c +++ b/modules/lvgl/lvgl_display_16bit.c @@ -9,28 +9,20 @@ #include #include "lvgl_display.h" -void lvgl_flush_cb_16bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) +void lvgl_flush_cb_16bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map) { uint16_t w = area->x2 - area->x1 + 1; uint16_t h = area->y2 - area->y1 + 1; struct lvgl_display_flush flush; - flush.disp_drv = disp_drv; + flush.display = display; flush.x = area->x1; flush.y = area->y1; flush.desc.buf_size = w * 2U * h; flush.desc.width = w; flush.desc.pitch = w; flush.desc.height = h; - flush.buf = (void *)color_p; - lvgl_flush_display(&flush); -} + flush.buf = (void *)px_map; -#ifndef CONFIG_LV_COLOR_DEPTH_16 -void lvgl_set_px_cb_16bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, lv_color_t color, lv_opa_t opa) -{ - uint16_t *buf_xy = (uint16_t *)(buf + x * 2U + y * 2U * buf_w); - *buf_xy = lv_color_to16(color); + lvgl_flush_display(&flush); } -#endif diff --git a/modules/lvgl/lvgl_display_24bit.c b/modules/lvgl/lvgl_display_24bit.c index c8419a69952c1..0841655399f00 100644 --- a/modules/lvgl/lvgl_display_24bit.c +++ b/modules/lvgl/lvgl_display_24bit.c @@ -9,42 +9,28 @@ #include #include "lvgl_display.h" -void lvgl_flush_cb_24bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) +void lvgl_flush_cb_24bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map) { uint16_t w = area->x2 - area->x1 + 1; uint16_t h = area->y2 - area->y1 + 1; struct lvgl_display_flush flush; - flush.disp_drv = disp_drv; + flush.display = display; flush.x = area->x1; flush.y = area->y1; flush.desc.buf_size = w * 3U * h; flush.desc.width = w; flush.desc.pitch = w; flush.desc.height = h; - flush.buf = (void *)color_p; - lvgl_flush_display(&flush); -} + flush.buf = (void *)px_map; -void lvgl_set_px_cb_24bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, lv_color_t color, lv_opa_t opa) -{ - uint8_t *buf_xy = buf + x * 3U + y * 3U * buf_w; - lv_color32_t converted_color; + /* LVGL assumes BGR byte ordering, convert to RGB */ + for (size_t i = 0; i < flush.desc.buf_size; i += 3) { + uint8_t tmp = px_map[i]; -#ifdef CONFIG_LV_COLOR_DEPTH_32 - if (opa != LV_OPA_COVER) { - lv_color_t mix_color; - - mix_color.ch.red = *buf_xy; - mix_color.ch.green = *(buf_xy + 1); - mix_color.ch.blue = *(buf_xy + 2); - color = lv_color_mix(color, mix_color, opa); + px_map[i] = px_map[i + 2]; + px_map[i + 2] = tmp; } -#endif - converted_color.full = lv_color_to32(color); - *buf_xy = converted_color.ch.red; - *(buf_xy + 1) = converted_color.ch.green; - *(buf_xy + 2) = converted_color.ch.blue; + lvgl_flush_display(&flush); } diff --git a/modules/lvgl/lvgl_display_32bit.c b/modules/lvgl/lvgl_display_32bit.c index f879d3f6e97e7..1a9e11abe4a33 100644 --- a/modules/lvgl/lvgl_display_32bit.c +++ b/modules/lvgl/lvgl_display_32bit.c @@ -9,35 +9,19 @@ #include #include "lvgl_display.h" -void lvgl_flush_cb_32bit(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) +void lvgl_flush_cb_32bit(lv_display_t *display, const lv_area_t *area, uint8_t *px_map) { uint16_t w = area->x2 - area->x1 + 1; uint16_t h = area->y2 - area->y1 + 1; struct lvgl_display_flush flush; - flush.disp_drv = disp_drv; + flush.display = display; flush.x = area->x1; flush.y = area->y1; flush.desc.buf_size = w * 4U * h; flush.desc.width = w; flush.desc.pitch = w; flush.desc.height = h; - flush.buf = (void *)color_p; + flush.buf = (void *)px_map; lvgl_flush_display(&flush); } - -#ifndef CONFIG_LV_COLOR_DEPTH_32 -void lvgl_set_px_cb_32bit(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, lv_color_t color, lv_opa_t opa) -{ - uint32_t *buf_xy = (uint32_t *)(buf + x * 4U + y * 4U * buf_w); - - if (opa == LV_OPA_COVER) { - /* Do not mix if not required */ - *buf_xy = lv_color_to32(color); - } else { - lv_color_t bg_color = *((lv_color_t *)buf_xy); - *buf_xy = lv_color_to32(lv_color_mix(color, bg_color, opa)); - } -} -#endif diff --git a/modules/lvgl/lvgl_display_mono.c b/modules/lvgl/lvgl_display_mono.c index b6b7669962733..09b9bfd2337f3 100644 --- a/modules/lvgl/lvgl_display_mono.c +++ b/modules/lvgl/lvgl_display_mono.c @@ -6,16 +6,83 @@ #include #include +#include #include "lvgl_display.h" -void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) +#define COLOR_PALETTE_HEADER_SIZE (8) + +static uint8_t *mono_conv_buf; +static uint32_t mono_conv_buf_size; + +static ALWAYS_INLINE void set_px_at_pos(uint8_t *dst_buf, uint32_t x, uint32_t y, uint32_t width, + const struct display_capabilities *caps) +{ + uint8_t bit; + uint8_t *buf; + + if (caps->screen_info & SCREEN_INFO_MONO_VTILED) { + buf = dst_buf + x + y / 8 * width; + + if (caps->screen_info & SCREEN_INFO_MONO_MSB_FIRST) { + bit = 7 - y % 8; + } else { + bit = y % 8; + } + } else { + buf = dst_buf + x / 8 + y * width / 8; + + if (caps->screen_info & SCREEN_INFO_MONO_MSB_FIRST) { + bit = 7 - x % 8; + } else { + bit = x % 8; + } + } + + if (caps->current_pixel_format == PIXEL_FORMAT_MONO10) { + *buf |= BIT(bit); + } else { + *buf &= ~BIT(bit); + } +} + +static void lvgl_transform_buffer(uint8_t **px_map, uint32_t width, uint32_t height, + const struct display_capabilities *caps) +{ + uint8_t clear_color = caps->current_pixel_format == PIXEL_FORMAT_MONO10 ? 0x00 : 0xFF; + + memset(mono_conv_buf, clear_color, mono_conv_buf_size); + + /* Needed because LVGL reserves some bytes in the buffer for the color palette. */ + *px_map += COLOR_PALETTE_HEADER_SIZE; + + uint8_t *src_buf = *px_map; + uint32_t stride = (width + CONFIG_LV_DRAW_BUF_STRIDE_ALIGN - 1) & + ~(CONFIG_LV_DRAW_BUF_STRIDE_ALIGN - 1); + + for (uint32_t y = 0; y < height; y++) { + for (uint32_t x = 0; x < width; x++) { + uint32_t bit_idx = x + y * stride; + uint8_t src_bit = (src_buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; + + if (src_bit) { + set_px_at_pos(mono_conv_buf, x, y, width, caps); + } + } + } + + memcpy(src_buf, mono_conv_buf, mono_conv_buf_size - COLOR_PALETTE_HEADER_SIZE); +} + +void lvgl_flush_cb_mono(lv_display_t *display, const lv_area_t *area, uint8_t *px_map) { uint16_t w = area->x2 - area->x1 + 1; uint16_t h = area->y2 - area->y1 + 1; - struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data; + struct lvgl_disp_data *data = (struct lvgl_disp_data *)lv_display_get_user_data(display); const struct device *display_dev = data->display_dev; const bool is_epd = data->cap.screen_info & SCREEN_INFO_EPD; - const bool is_last = lv_disp_flush_is_last(disp_drv); + const bool is_last = lv_display_flush_is_last(display); + + lvgl_transform_buffer(&px_map, w, h, &data->cap); if (is_epd && !data->blanking_on && !is_last) { /* @@ -36,9 +103,9 @@ void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color .frame_incomplete = !is_last, }; - display_write(display_dev, area->x1, area->y1, &desc, (void *)color_p); + display_write(display_dev, area->x1, area->y1, &desc, (void *)px_map); if (data->cap.screen_info & SCREEN_INFO_DOUBLE_BUFFER) { - display_write(display_dev, area->x1, area->y1, &desc, (void *)color_p); + display_write(display_dev, area->x1, area->y1, &desc, (void *)px_map); } if (is_epd && is_last && data->blanking_on) { @@ -50,63 +117,30 @@ void lvgl_flush_cb_mono(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color data->blanking_on = false; } - lv_disp_flush_ready(disp_drv); + lv_display_flush_ready(display); } -void lvgl_set_px_cb_mono(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, - lv_coord_t y, lv_color_t color, lv_opa_t opa) +void lvgl_rounder_cb_mono(lv_event_t *e) { - struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data; - uint8_t *buf_xy; - uint8_t bit; - - if (data->cap.screen_info & SCREEN_INFO_MONO_VTILED) { - buf_xy = buf + x + y / 8 * buf_w; - - if (data->cap.screen_info & SCREEN_INFO_MONO_MSB_FIRST) { - bit = 7 - y % 8; - } else { - bit = y % 8; - } - } else { - buf_xy = buf + x / 8 + y * buf_w / 8; - - if (data->cap.screen_info & SCREEN_INFO_MONO_MSB_FIRST) { - bit = 7 - x % 8; - } else { - bit = x % 8; - } - } - - if (data->cap.current_pixel_format == PIXEL_FORMAT_MONO10) { - if (color.full == 0) { - *buf_xy &= ~BIT(bit); - } else { - *buf_xy |= BIT(bit); - } - } else { - if (color.full == 0) { - *buf_xy |= BIT(bit); - } else { - *buf_xy &= ~BIT(bit); - } - } -} - -void lvgl_rounder_cb_mono(lv_disp_drv_t *disp_drv, lv_area_t *area) -{ - struct lvgl_disp_data *data = (struct lvgl_disp_data *)disp_drv->user_data; + lv_area_t *area = lv_event_get_param(e); + lv_display_t *display = lv_event_get_user_data(e); + struct lvgl_disp_data *data = (struct lvgl_disp_data *)lv_display_get_user_data(display); if (data->cap.screen_info & SCREEN_INFO_X_ALIGNMENT_WIDTH) { area->x1 = 0; area->x2 = data->cap.x_resolution - 1; } else { + area->x1 &= ~0x7; + area->x2 |= 0x7; if (data->cap.screen_info & SCREEN_INFO_MONO_VTILED) { area->y1 &= ~0x7; area->y2 |= 0x7; - } else { - area->x1 &= ~0x7; - area->x2 |= 0x7; } } } + +void lvgl_set_mono_conversion_buffer(uint8_t *buffer, uint32_t buffer_size) +{ + mono_conv_buf = buffer; + mono_conv_buf_size = buffer_size; +} diff --git a/modules/lvgl/lvgl_fs.c b/modules/lvgl/lvgl_fs.c index 63a902ea9572d..9e1674cf07f99 100644 --- a/modules/lvgl/lvgl_fs.c +++ b/modules/lvgl/lvgl_fs.c @@ -9,9 +9,9 @@ #include #include "lvgl_fs.h" #include "lv_conf.h" -#include LV_MEM_CUSTOM_INCLUDE +#include LV_STDLIB_INCLUDE -static bool lvgl_fs_ready(struct _lv_fs_drv_t *drv) +static bool lvgl_fs_ready(lv_fs_drv_t *drv) { return true; } @@ -53,7 +53,7 @@ static lv_fs_res_t errno_to_lv_fs_res(int err) } } -static void *lvgl_fs_open(struct _lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode) +static void *lvgl_fs_open(lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode) { int err; int zmode = FS_O_CREATE; @@ -67,7 +67,7 @@ static void *lvgl_fs_open(struct _lv_fs_drv_t *drv, const char *path, lv_fs_mode zmode |= (mode & LV_FS_MODE_WR) ? FS_O_WRITE : 0; zmode |= (mode & LV_FS_MODE_RD) ? FS_O_READ : 0; - file = LV_MEM_CUSTOM_ALLOC(sizeof(struct fs_file_t)); + file = lv_malloc(sizeof(struct fs_file_t)); if (!file) { return NULL; } @@ -76,24 +76,23 @@ static void *lvgl_fs_open(struct _lv_fs_drv_t *drv, const char *path, lv_fs_mode err = fs_open((struct fs_file_t *)file, path, zmode); if (err) { - LV_MEM_CUSTOM_FREE(file); + lv_free(file); return NULL; } return file; } -static lv_fs_res_t lvgl_fs_close(struct _lv_fs_drv_t *drv, void *file) +static lv_fs_res_t lvgl_fs_close(lv_fs_drv_t *drv, void *file) { int err; err = fs_close((struct fs_file_t *)file); - LV_MEM_CUSTOM_FREE(file); + lv_free(file); return errno_to_lv_fs_res(err); } -static lv_fs_res_t lvgl_fs_read(struct _lv_fs_drv_t *drv, void *file, void *buf, uint32_t btr, - uint32_t *br) +static lv_fs_res_t lvgl_fs_read(lv_fs_drv_t *drv, void *file, void *buf, uint32_t btr, uint32_t *br) { int err; @@ -109,8 +108,8 @@ static lv_fs_res_t lvgl_fs_read(struct _lv_fs_drv_t *drv, void *file, void *buf, return errno_to_lv_fs_res(err); } -static lv_fs_res_t lvgl_fs_write(struct _lv_fs_drv_t *drv, void *file, const void *buf, - uint32_t btw, uint32_t *bw) +static lv_fs_res_t lvgl_fs_write(lv_fs_drv_t *drv, void *file, const void *buf, uint32_t btw, + uint32_t *bw) { int err; @@ -133,8 +132,7 @@ static lv_fs_res_t lvgl_fs_write(struct _lv_fs_drv_t *drv, void *file, const voi return errno_to_lv_fs_res(err); } -static lv_fs_res_t lvgl_fs_seek(struct _lv_fs_drv_t *drv, void *file, uint32_t pos, - lv_fs_whence_t whence) +static lv_fs_res_t lvgl_fs_seek(lv_fs_drv_t *drv, void *file, uint32_t pos, lv_fs_whence_t whence) { int err, fs_whence; @@ -155,7 +153,7 @@ static lv_fs_res_t lvgl_fs_seek(struct _lv_fs_drv_t *drv, void *file, uint32_t p return errno_to_lv_fs_res(err); } -static lv_fs_res_t lvgl_fs_tell(struct _lv_fs_drv_t *drv, void *file, uint32_t *pos_p) +static lv_fs_res_t lvgl_fs_tell(lv_fs_drv_t *drv, void *file, uint32_t *pos_p) { off_t pos; @@ -168,7 +166,7 @@ static lv_fs_res_t lvgl_fs_tell(struct _lv_fs_drv_t *drv, void *file, uint32_t * return LV_FS_RES_OK; } -static void *lvgl_fs_dir_open(struct _lv_fs_drv_t *drv, const char *path) +static void *lvgl_fs_dir_open(lv_fs_drv_t *drv, const char *path) { void *dir; int err; @@ -178,7 +176,7 @@ static void *lvgl_fs_dir_open(struct _lv_fs_drv_t *drv, const char *path) */ path--; - dir = LV_MEM_CUSTOM_ALLOC(sizeof(struct fs_dir_t)); + dir = lv_malloc(sizeof(struct fs_dir_t)); if (!dir) { return NULL; } @@ -186,14 +184,14 @@ static void *lvgl_fs_dir_open(struct _lv_fs_drv_t *drv, const char *path) fs_dir_t_init((struct fs_dir_t *)dir); err = fs_opendir((struct fs_dir_t *)dir, path); if (err) { - LV_MEM_CUSTOM_FREE(dir); + lv_free(dir); return NULL; } return dir; } -static lv_fs_res_t lvgl_fs_dir_read(struct _lv_fs_drv_t *drv, void *dir, char *fn) +static lv_fs_res_t lvgl_fs_dir_read(lv_fs_drv_t *drv, void *dir, char *fn, uint32_t fn_len) { /* LVGL expects a string as return parameter but the format of the * string is not documented. @@ -201,12 +199,12 @@ static lv_fs_res_t lvgl_fs_dir_read(struct _lv_fs_drv_t *drv, void *dir, char *f return LV_FS_RES_NOT_IMP; } -static lv_fs_res_t lvgl_fs_dir_close(struct _lv_fs_drv_t *drv, void *dir) +static lv_fs_res_t lvgl_fs_dir_close(lv_fs_drv_t *drv, void *dir) { int err; err = fs_closedir((struct fs_dir_t *)dir); - LV_MEM_CUSTOM_FREE(dir); + lv_free(dir); return errno_to_lv_fs_res(err); } diff --git a/modules/lvgl/lvgl_mem.c b/modules/lvgl/lvgl_mem.c index 03c36146618b3..eb7c1ddf19984 100644 --- a/modules/lvgl/lvgl_mem.c +++ b/modules/lvgl/lvgl_mem.c @@ -10,6 +10,9 @@ #include #include +#include +LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL); + #ifdef CONFIG_LV_Z_MEMORY_POOL_CUSTOM_SECTION #define HEAP_MEM_ATTRIBUTES Z_GENERIC_SECTION(.lvgl_heap) __aligned(8) #else @@ -62,6 +65,20 @@ void lvgl_print_heap_info(bool dump_chunks) k_spin_unlock(&lvgl_heap_lock, key); } +void lvgl_heap_stats(struct sys_memory_stats *stats) +{ +#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS + k_spinlock_key_t key; + + key = k_spin_lock(&lvgl_heap_lock); + sys_heap_runtime_stats_get(&lvgl_heap, stats); + k_spin_unlock(&lvgl_heap_lock, key); +#else + ARG_UNUSED(stats); + LOG_WRN_ONCE("Enable CONFIG_SYS_HEAP_RUNTIME_STATS to use the mem monitor feature"); +#endif /* CONFIG_SYS_HEAP_RUNTIME_STATS */ +} + void lvgl_heap_init(void) { sys_heap_init(&lvgl_heap, &lvgl_heap_mem[0], CONFIG_LV_Z_MEM_POOL_SIZE); diff --git a/modules/lvgl/lvgl_shell.c b/modules/lvgl/lvgl_shell.c index 42d5a5e7a2ac3..8979c6bc310e6 100644 --- a/modules/lvgl/lvgl_shell.c +++ b/modules/lvgl/lvgl_shell.c @@ -20,11 +20,11 @@ static const char *lvgl_monkey_indev_as_string(lv_monkey_t *monkey) lv_indev_t *input_device; input_device = lv_monkey_get_indev(monkey); - if (!input_device || !input_device->driver) { + if (!input_device) { return "unknown"; } - switch (input_device->driver->type) { + switch (lv_indev_get_type(input_device)) { case LV_INDEV_TYPE_POINTER: return "pointer"; case LV_INDEV_TYPE_KEYPAD: diff --git a/modules/lvgl/lvgl_zephyr_osal.c b/modules/lvgl/lvgl_zephyr_osal.c new file mode 100644 index 0000000000000..fd5adb220c6e7 --- /dev/null +++ b/modules/lvgl/lvgl_zephyr_osal.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2024 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lvgl_zephyr_osal.h" +#include + +#include +LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL); + +typedef void (*lv_thread_entry)(void *); +static void thread_entry(void *thread, void *cb, void *user_data); + +lv_result_t lv_thread_init(lv_thread_t *thread, const char *const name, lv_thread_prio_t prio, + void (*callback)(void *), size_t stack_size, void *user_data) +{ + int thread_priority; + + thread->stack = k_thread_stack_alloc(stack_size, 0); + if (thread->stack == NULL) { + return LV_RESULT_INVALID; + } + + thread_priority = (CONFIG_NUM_PREEMPT_PRIORITIES - 1) - + ((prio * (CONFIG_NUM_PREEMPT_PRIORITIES - 1)) / LV_THREAD_PRIO_HIGHEST); + + thread->tid = k_thread_create(&thread->thread, thread->stack, stack_size, thread_entry, + thread, callback, user_data, thread_priority, 0, K_NO_WAIT); + + k_thread_name_set(thread->tid, name); + + return LV_RESULT_OK; +} + +lv_result_t lv_thread_delete(lv_thread_t *thread) +{ + int ret; + + k_thread_abort(thread->tid); + ret = k_thread_stack_free(thread->stack); + if (ret < 0) { + LOG_ERR("Failled to delete thread: %d", ret); + return LV_RESULT_INVALID; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_init(lv_mutex_t *mutex) +{ + k_mutex_init(mutex); + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_lock(lv_mutex_t *mutex) +{ + int ret; + + ret = k_mutex_lock(mutex, K_FOREVER); + if (ret != 0) { + LOG_ERR("Failed to lock mutex: %d", ret); + return LV_RESULT_INVALID; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_lock_isr(lv_mutex_t *mutex) +{ + int ret; + + ret = k_mutex_lock(mutex, K_NO_WAIT); + if (ret != 0) { + LOG_ERR("Failed to lock mutex: %d", ret); + return LV_RESULT_INVALID; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_unlock(lv_mutex_t *mutex) +{ + int ret; + + ret = k_mutex_unlock(mutex); + if (ret != 0) { + LOG_ERR("Failed to unlock mutex: %d", ret); + return LV_RESULT_INVALID; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_delete(lv_mutex_t *mutex) +{ + ARG_UNUSED(mutex); + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_init(lv_thread_sync_t *sync) +{ + int ret; + + ret = k_sem_init(sync, 0, 1); + if (ret != 0) { + LOG_ERR("Failed to init thread sync: %d", ret); + return LV_RESULT_INVALID; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_wait(lv_thread_sync_t *sync) +{ + int ret; + + ret = k_sem_take(sync, K_FOREVER); + if (ret < 0) { + LOG_ERR("Error waiting on thread sync: %d", ret); + return LV_RESULT_INVALID; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_signal(lv_thread_sync_t *sync) +{ + k_sem_give(sync); + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t *sync) +{ + k_sem_give(sync); + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_delete(lv_thread_sync_t *sync) +{ + ARG_UNUSED(sync); + return LV_RESULT_OK; +} + +void thread_entry(void *thread, void *cb, void *user_data) +{ + __ASSERT_NO_MSG(cb != NULL); + lv_thread_entry entry_cb = (lv_thread_entry)cb; + + entry_cb(user_data); + lv_thread_delete((lv_thread_t *)thread); +} diff --git a/modules/mbedtls/CMakeLists.txt b/modules/mbedtls/CMakeLists.txt index e2bbe13f50257..61c7400017da0 100644 --- a/modules/mbedtls/CMakeLists.txt +++ b/modules/mbedtls/CMakeLists.txt @@ -12,7 +12,8 @@ zephyr_interface_library_named(mbedTLS) endif() if(CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - if(CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG) + if(CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG OR + CONFIG_TEST_CSPRNG_GENERATOR) message(WARNING " Non cryptographycally secure sources are enabled for psa_generate_random(). This is meant to be used only for tests, not in production!") diff --git a/modules/mbedtls/Kconfig b/modules/mbedtls/Kconfig index d15c420f5075c..cb178fb3c273e 100644 --- a/modules/mbedtls/Kconfig +++ b/modules/mbedtls/Kconfig @@ -13,7 +13,8 @@ config MBEDTLS_PROMPTLESS mbed TLS menu prompt and instead handle the selection of MBEDTLS from dependent sub-configurations and thus prevent stuck symbol behavior. -rsource "Kconfig.psa" +rsource "Kconfig.psa.auto" +rsource "Kconfig.psa.logic" menuconfig MBEDTLS bool "mbed TLS Support" if !MBEDTLS_PROMPTLESS diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa deleted file mode 100644 index 7562032bf3d4e..0000000000000 --- a/modules/mbedtls/Kconfig.psa +++ /dev/null @@ -1,355 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -# This file was automatically generated by create_psa_files.py -# from: ../../../modules/crypto/mbedtls/include/psa/crypto_config.h. -# Do not edit it manually. - -config PSA_CRYPTO_CLIENT - bool - help - Promptless symbol to state that there is a PSA crypto API provider - enabled in the system. This allows to select desired PSA_WANT features. - -if PSA_CRYPTO_CLIENT - -config PSA_CRYPTO_ENABLE_ALL - bool "All PSA crypto features" - -config PSA_WANT_ALG_CBC_NO_PADDING - bool "PSA_WANT_ALG_CBC_NO_PADDING" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_CBC_PKCS7 - bool "PSA_WANT_ALG_CBC_PKCS7" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_CCM - bool "PSA_WANT_ALG_CCM" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_CCM_STAR_NO_TAG - bool "PSA_WANT_ALG_CCM_STAR_NO_TAG" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_CMAC - bool "PSA_WANT_ALG_CMAC" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_CFB - bool "PSA_WANT_ALG_CFB" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_CHACHA20_POLY1305 - bool "PSA_WANT_ALG_CHACHA20_POLY1305" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_CTR - bool "PSA_WANT_ALG_CTR" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_DETERMINISTIC_ECDSA - bool "PSA_WANT_ALG_DETERMINISTIC_ECDSA" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_ECB_NO_PADDING - bool "PSA_WANT_ALG_ECB_NO_PADDING" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_ECDH - bool "PSA_WANT_ALG_ECDH" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_FFDH - bool "PSA_WANT_ALG_FFDH" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_ECDSA - bool "PSA_WANT_ALG_ECDSA" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_JPAKE - bool "PSA_WANT_ALG_JPAKE" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_GCM - bool "PSA_WANT_ALG_GCM" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_HKDF - bool "PSA_WANT_ALG_HKDF" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_HKDF_EXTRACT - bool "PSA_WANT_ALG_HKDF_EXTRACT" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_HKDF_EXPAND - bool "PSA_WANT_ALG_HKDF_EXPAND" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_HMAC - bool "PSA_WANT_ALG_HMAC" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_MD5 - bool "PSA_WANT_ALG_MD5" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_OFB - bool "PSA_WANT_ALG_OFB" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_PBKDF2_HMAC - bool "PSA_WANT_ALG_PBKDF2_HMAC" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 - bool "PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_RIPEMD160 - bool "PSA_WANT_ALG_RIPEMD160" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_RSA_OAEP - bool "PSA_WANT_ALG_RSA_OAEP" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_RSA_PKCS1V15_CRYPT - bool "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_RSA_PKCS1V15_SIGN - bool "PSA_WANT_ALG_RSA_PKCS1V15_SIGN" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_RSA_PSS - bool "PSA_WANT_ALG_RSA_PSS" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA_1 - bool "PSA_WANT_ALG_SHA_1" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA_224 - bool "PSA_WANT_ALG_SHA_224" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA_256 - bool "PSA_WANT_ALG_SHA_256" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA_384 - bool "PSA_WANT_ALG_SHA_384" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA_512 - bool "PSA_WANT_ALG_SHA_512" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA3_224 - bool "PSA_WANT_ALG_SHA3_224" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA3_256 - bool "PSA_WANT_ALG_SHA3_256" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA3_384 - bool "PSA_WANT_ALG_SHA3_384" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_SHA3_512 - bool "PSA_WANT_ALG_SHA3_512" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_STREAM_CIPHER - bool "PSA_WANT_ALG_STREAM_CIPHER" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_TLS12_PRF - bool "PSA_WANT_ALG_TLS12_PRF" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_TLS12_PSK_TO_MS - bool "PSA_WANT_ALG_TLS12_PSK_TO_MS" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS - bool "PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_BRAINPOOL_P_R1_256 - bool "PSA_WANT_ECC_BRAINPOOL_P_R1_256" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_BRAINPOOL_P_R1_384 - bool "PSA_WANT_ECC_BRAINPOOL_P_R1_384" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_BRAINPOOL_P_R1_512 - bool "PSA_WANT_ECC_BRAINPOOL_P_R1_512" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_MONTGOMERY_255 - bool "PSA_WANT_ECC_MONTGOMERY_255" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_MONTGOMERY_448 - bool "PSA_WANT_ECC_MONTGOMERY_448" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_SECP_K1_192 - bool "PSA_WANT_ECC_SECP_K1_192" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_SECP_K1_256 - bool "PSA_WANT_ECC_SECP_K1_256" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_SECP_R1_192 - bool "PSA_WANT_ECC_SECP_R1_192" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_SECP_R1_224 - bool "PSA_WANT_ECC_SECP_R1_224" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_SECP_R1_256 - bool "PSA_WANT_ECC_SECP_R1_256" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_SECP_R1_384 - bool "PSA_WANT_ECC_SECP_R1_384" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_ECC_SECP_R1_521 - bool "PSA_WANT_ECC_SECP_R1_521" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_DH_RFC7919_2048 - bool "PSA_WANT_DH_RFC7919_2048" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_DH_RFC7919_3072 - bool "PSA_WANT_DH_RFC7919_3072" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_DH_RFC7919_4096 - bool "PSA_WANT_DH_RFC7919_4096" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_DH_RFC7919_6144 - bool "PSA_WANT_DH_RFC7919_6144" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_DH_RFC7919_8192 - bool "PSA_WANT_DH_RFC7919_8192" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_DERIVE - bool "PSA_WANT_KEY_TYPE_DERIVE" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_PASSWORD - bool "PSA_WANT_KEY_TYPE_PASSWORD" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_PASSWORD_HASH - bool "PSA_WANT_KEY_TYPE_PASSWORD_HASH" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_HMAC - bool "PSA_WANT_KEY_TYPE_HMAC" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_AES - bool "PSA_WANT_KEY_TYPE_AES" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_ARIA - bool "PSA_WANT_KEY_TYPE_ARIA" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_CAMELLIA - bool "PSA_WANT_KEY_TYPE_CAMELLIA" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_CHACHA20 - bool "PSA_WANT_KEY_TYPE_CHACHA20" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_DES - bool "PSA_WANT_KEY_TYPE_DES" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY - bool "PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY - bool "PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_RAW_DATA - bool "PSA_WANT_KEY_TYPE_RAW_DATA" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY - bool "PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC - bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT - bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT - bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE - bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE - bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC - bool "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT - bool "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT - bool "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE - bool "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC - bool "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT - bool "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT - bool "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -config PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE - bool "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE" if !MBEDTLS_PROMPTLESS - default y if PSA_CRYPTO_ENABLE_ALL - -endif # PSA_CRYPTO_CLIENT diff --git a/modules/mbedtls/Kconfig.psa.auto b/modules/mbedtls/Kconfig.psa.auto new file mode 100644 index 0000000000000..08b1bbc024107 --- /dev/null +++ b/modules/mbedtls/Kconfig.psa.auto @@ -0,0 +1,343 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# This file was automatically generated by create_psa_files.py +# from: ../../../modules/crypto/mbedtls/include/psa/crypto_config.h. +# Do not edit it manually. + +config PSA_CRYPTO_CLIENT + bool + help + Promptless symbol to state that there is a PSA crypto API provider + enabled in the system. This allows to select desired PSA_WANT features. + +if PSA_CRYPTO_CLIENT + +config PSA_CRYPTO_ENABLE_ALL + bool "All PSA crypto features" + +config PSA_WANT_ALG_CBC_NO_PADDING + bool "PSA_WANT_ALG_CBC_NO_PADDING" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_CBC_PKCS7 + bool "PSA_WANT_ALG_CBC_PKCS7" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_CCM + bool "PSA_WANT_ALG_CCM" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_CCM_STAR_NO_TAG + bool "PSA_WANT_ALG_CCM_STAR_NO_TAG" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_CMAC + bool "PSA_WANT_ALG_CMAC" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_CFB + bool "PSA_WANT_ALG_CFB" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_CHACHA20_POLY1305 + bool "PSA_WANT_ALG_CHACHA20_POLY1305" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_CTR + bool "PSA_WANT_ALG_CTR" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_DETERMINISTIC_ECDSA + bool "PSA_WANT_ALG_DETERMINISTIC_ECDSA" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_ECB_NO_PADDING + bool "PSA_WANT_ALG_ECB_NO_PADDING" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_ECDH + bool "PSA_WANT_ALG_ECDH" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_FFDH + bool "PSA_WANT_ALG_FFDH" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_ECDSA + bool "PSA_WANT_ALG_ECDSA" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_JPAKE + bool "PSA_WANT_ALG_JPAKE" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_GCM + bool "PSA_WANT_ALG_GCM" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_HKDF + bool "PSA_WANT_ALG_HKDF" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_HKDF_EXTRACT + bool "PSA_WANT_ALG_HKDF_EXTRACT" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_HKDF_EXPAND + bool "PSA_WANT_ALG_HKDF_EXPAND" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_HMAC + bool "PSA_WANT_ALG_HMAC" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_MD5 + bool "PSA_WANT_ALG_MD5" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_OFB + bool "PSA_WANT_ALG_OFB" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_PBKDF2_HMAC + bool "PSA_WANT_ALG_PBKDF2_HMAC" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 + bool "PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_RIPEMD160 + bool "PSA_WANT_ALG_RIPEMD160" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_RSA_OAEP + bool "PSA_WANT_ALG_RSA_OAEP" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + bool "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_RSA_PKCS1V15_SIGN + bool "PSA_WANT_ALG_RSA_PKCS1V15_SIGN" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_RSA_PSS + bool "PSA_WANT_ALG_RSA_PSS" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA_1 + bool "PSA_WANT_ALG_SHA_1" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA_224 + bool "PSA_WANT_ALG_SHA_224" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA_256 + bool "PSA_WANT_ALG_SHA_256" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA_384 + bool "PSA_WANT_ALG_SHA_384" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA_512 + bool "PSA_WANT_ALG_SHA_512" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA3_224 + bool "PSA_WANT_ALG_SHA3_224" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA3_256 + bool "PSA_WANT_ALG_SHA3_256" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA3_384 + bool "PSA_WANT_ALG_SHA3_384" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_SHA3_512 + bool "PSA_WANT_ALG_SHA3_512" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_STREAM_CIPHER + bool "PSA_WANT_ALG_STREAM_CIPHER" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_TLS12_PRF + bool "PSA_WANT_ALG_TLS12_PRF" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_TLS12_PSK_TO_MS + bool "PSA_WANT_ALG_TLS12_PSK_TO_MS" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS + bool "PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_BRAINPOOL_P_R1_256 + bool "PSA_WANT_ECC_BRAINPOOL_P_R1_256" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_BRAINPOOL_P_R1_384 + bool "PSA_WANT_ECC_BRAINPOOL_P_R1_384" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_BRAINPOOL_P_R1_512 + bool "PSA_WANT_ECC_BRAINPOOL_P_R1_512" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_MONTGOMERY_255 + bool "PSA_WANT_ECC_MONTGOMERY_255" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_MONTGOMERY_448 + bool "PSA_WANT_ECC_MONTGOMERY_448" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_SECP_K1_192 + bool "PSA_WANT_ECC_SECP_K1_192" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_SECP_K1_256 + bool "PSA_WANT_ECC_SECP_K1_256" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_SECP_R1_192 + bool "PSA_WANT_ECC_SECP_R1_192" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_SECP_R1_224 + bool "PSA_WANT_ECC_SECP_R1_224" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_SECP_R1_256 + bool "PSA_WANT_ECC_SECP_R1_256" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_SECP_R1_384 + bool "PSA_WANT_ECC_SECP_R1_384" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_ECC_SECP_R1_521 + bool "PSA_WANT_ECC_SECP_R1_521" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_DH_RFC7919_2048 + bool "PSA_WANT_DH_RFC7919_2048" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_DH_RFC7919_3072 + bool "PSA_WANT_DH_RFC7919_3072" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_DH_RFC7919_4096 + bool "PSA_WANT_DH_RFC7919_4096" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_DH_RFC7919_6144 + bool "PSA_WANT_DH_RFC7919_6144" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_DH_RFC7919_8192 + bool "PSA_WANT_DH_RFC7919_8192" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_DERIVE + bool "PSA_WANT_KEY_TYPE_DERIVE" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_PASSWORD + bool "PSA_WANT_KEY_TYPE_PASSWORD" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_PASSWORD_HASH + bool "PSA_WANT_KEY_TYPE_PASSWORD_HASH" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_HMAC + bool "PSA_WANT_KEY_TYPE_HMAC" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_AES + bool "PSA_WANT_KEY_TYPE_AES" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_ARIA + bool "PSA_WANT_KEY_TYPE_ARIA" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_CAMELLIA + bool "PSA_WANT_KEY_TYPE_CAMELLIA" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_CHACHA20 + bool "PSA_WANT_KEY_TYPE_CHACHA20" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_DES + bool "PSA_WANT_KEY_TYPE_DES" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + bool "PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + bool "PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_RAW_DATA + bool "PSA_WANT_KEY_TYPE_RAW_DATA" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + bool "PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT + bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE + bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE + bool "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT + bool "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT + bool "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE + bool "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT + bool "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT + bool "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +config PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE + bool "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE" if !MBEDTLS_PROMPTLESS + default y if PSA_CRYPTO_ENABLE_ALL + +endif # PSA_CRYPTO_CLIENT diff --git a/modules/mbedtls/Kconfig.psa.logic b/modules/mbedtls/Kconfig.psa.logic new file mode 100644 index 0000000000000..dcea9e3540527 --- /dev/null +++ b/modules/mbedtls/Kconfig.psa.logic @@ -0,0 +1,27 @@ +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +# This file extends Kconfig.psa (which is automatically generated) by adding +# some logic between PSA_WANT symbols. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC + bool + default y + depends on PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC + bool + default y + depends on PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT || \ + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT || \ + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE + +config PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC + bool + default y + depends on PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT || \ + PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT || \ + PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE diff --git a/modules/mbedtls/Kconfig.tls-generic b/modules/mbedtls/Kconfig.tls-generic index 5c8ac8b569b15..369bdc9dfeb41 100644 --- a/modules/mbedtls/Kconfig.tls-generic +++ b/modules/mbedtls/Kconfig.tls-generic @@ -138,6 +138,7 @@ config MBEDTLS_ECDH_C config MBEDTLS_ECDSA_C bool "Elliptic curve DSA library" depends on MBEDTLS_ECP_C + select MBEDTLS_ASN1_PARSE_C config MBEDTLS_ECJPAKE_C bool "Elliptic curve J-PAKE library" @@ -374,6 +375,9 @@ config MBEDTLS_MD config MBEDTLS_GENPRIME_ENABLED bool "prime-number generation code." +config MBEDTLS_ASN1_PARSE_C + bool "Support for ASN1 parser functions" + config MBEDTLS_PEM_CERTIFICATE_FORMAT bool "Support for PEM certificate format" help @@ -482,11 +486,17 @@ config MBEDTLS_SSL_EXTENDED_MASTER_SECRET choice MBEDTLS_PSA_CRYPTO_RNG_SOURCE prompt "Select random source for built-in PSA crypto" depends on MBEDTLS_PSA_CRYPTO_C - default MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG if CSPRNG_ENABLED + # The only way to check if there is any entropy driver available on the + # platform is to check if the "zephyr,entropy" chosen property exists. + # CONFIG_CSPRNG_ENABLED cannot be used for this because it gets enabled by + # entropy drivers but these are gated by CONFIG_ENTROPY_GENERATOR which + # is disabled by default. + default MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG if CSPRNG_AVAILABLE default MBEDTLS_PSA_CRYPTO_LEGACY_RNG config MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG bool "Use a cryptographically secure driver as random source" + select ENTROPY_GENERATOR help Use a cryptographically secure random generator to provide random data instead of legacy Mbed TLS modules. This has a smaller footprint @@ -501,6 +511,10 @@ config MBEDTLS_PSA_CRYPTO_LEGACY_RNG bool "Use legacy modules to generate random data" select MBEDTLS_ENTROPY_C select MBEDTLS_HMAC_DRBG_ENABLED if !MBEDTLS_CTR_DRBG_ENABLED + # If there is any entropy driver in the system, then the choice would be + # CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. If we fall here, then the only + # way to get some random data is to enable CONFIG_TEST_RANDOM_GENERATOR. + select TEST_RANDOM_GENERATOR help Use legacy Mbed TLS modules to generate random data. In this configuration the entropy module is used to gather some data and then diff --git a/modules/mbedtls/configs/config-tls-generic.h b/modules/mbedtls/configs/config-tls-generic.h index f3b0e96afcb3e..087246327cfab 100644 --- a/modules/mbedtls/configs/config-tls-generic.h +++ b/modules/mbedtls/configs/config-tls-generic.h @@ -431,7 +431,7 @@ #define MBEDTLS_PK_C #endif -#if defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_X509_USE_C) +#if defined(CONFIG_MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_USE_C) #define MBEDTLS_ASN1_PARSE_C #endif @@ -482,12 +482,6 @@ #define MBEDTLS_PSA_P256M_DRIVER_ENABLED #endif -#if defined(CONFIG_ARCH_POSIX) && !defined(CONFIG_PICOLIBC) && !defined(CONFIG_SECURE_STORAGE) -#define MBEDTLS_PSA_ITS_FILE_C -#define MBEDTLS_PSA_CRYPTO_STORAGE_C -#define MBEDTLS_FS_IO -#endif - #if defined(CONFIG_SECURE_STORAGE) #define MBEDTLS_PSA_CRYPTO_STORAGE_C #endif diff --git a/modules/mbedtls/create_psa_files.py b/modules/mbedtls/create_psa_files.py index fe6d0b79b4655..c2aca4e20b43f 100755 --- a/modules/mbedtls/create_psa_files.py +++ b/modules/mbedtls/create_psa_files.py @@ -14,7 +14,7 @@ "include", "psa", "crypto_config.h") INPUT_FILE = os.path.normpath(os.path.join(SCRIPT_PATH, INPUT_REL_PATH)) -KCONFIG_PATH=os.path.join(SCRIPT_PATH, "Kconfig.psa") +KCONFIG_PATH=os.path.join(SCRIPT_PATH, "Kconfig.psa.auto") HEADER_PATH=os.path.join(SCRIPT_PATH, "configs", "config-psa.h") KCONFIG_HEADER="""\ @@ -57,6 +57,20 @@ H_FOOTER="\n#endif /* CONFIG_PSA_H */\n" +# In Mbed TLS the PSA_WANT_KEY_TYPE_[ECC|RSA|DH]_KEY_PAIR_BASIC build symbols +# are automatically enabled whenever any other _IMPORT, _EXPORT, _GENERATE or +# _DERIVE feature is set for the same key type +# (see "modules/crypto/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h"). +# Therefore we mimic the same pattern with Kconfigs as follows: +# - do not add _BASIC Kconfigs to the automatic generated file (KCONFIG_PATH); +# - add _BASIC Kconfigs to Kconfig.psa.logic and let them "default y" as soon as +# any other _IMPORT, _EXPORT, _GENERATE or _DERIVE Kconfigs are enabled. +SKIP_SYMBOLS = [ + "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC", + "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC", + "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC" +] + def parse_psa_symbols(input_file: str): symbols = [] with open(input_file) as file: @@ -70,6 +84,8 @@ def parse_psa_symbols(input_file: str): def generate_kconfig_content(symbols: List[str]) -> str: output = [] for sym in symbols: + if sym in SKIP_SYMBOLS: + continue output.append(""" config {0} \tbool "{0}" if !MBEDTLS_PROMPTLESS diff --git a/modules/nrf_wifi/os/CMakeLists.txt b/modules/nrf_wifi/os/CMakeLists.txt index daef05f2098d3..42610b9bf572b 100644 --- a/modules/nrf_wifi/os/CMakeLists.txt +++ b/modules/nrf_wifi/os/CMakeLists.txt @@ -4,183 +4,15 @@ if(NOT CONFIG_WIFI_NRF70) return() endif() -zephyr_interface_library_named(nrf-wifi-interface) -zephyr_library() -set(NRF_WIFI_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) - -# Translate the configuration to the OS agnostic code -target_compile_definitions( - nrf-wifi-interface - INTERFACE - $<$:NRF_WIFI_LOW_POWER> - $<$:NRF_WIFI_RPU_RECOVERY> - $<$:NRF_WIFI_AP_DEAD_DETECT_TIMEOUT=${CONFIG_NRF_WIFI_AP_DEAD_DETECT_TIMEOUT}> - $<$:NRF_WIFI_IFACE_MTU=${CONFIG_NRF_WIFI_IFACE_MTU}> - $<$:NRF70_STA_MODE> - $<$:NRF70_DATA_TX> - $<$:NRF70_RAW_DATA_TX> - $<$:NRF70_RAW_DATA_RX> - $<$:NRF70_PROMISC_DATA_RX> - $<$:NRF70_TX_DONE_WQ_ENABLED> - $<$:NRF70_RX_WQ_ENABLED> - $<$:NRF70_UTIL> - $<$:NRF70_RADIO_TEST> - $<$:NRF70_OFFLOADED_RAW_TX> - $<$:NRF70_TCP_IP_CHECKSUM_OFFLOAD> - $<$:NRF70_RPU_EXTEND_TWT_SP> - $<$:NRF70_SYSTEM_WITH_RAW_MODES> - $<$:NRF70_SCAN_ONLY> - $<$:NRF70_SYSTEM_MODE> - $<$:NRF70_2_4G_ONLY> - $<$:NRF70_LOG_VERBOSE> - $<$:NRF70_AP_MODE> - $<$:NRF_WIFI_MGMT_BUFF_OFFLOAD> - $<$:NRF_WIFI_FEAT_KEEPALIVE> - $<$:NRF_WIFI_KEEPALIVE_PERIOD_S=${CONFIG_NRF_WIFI_KEEPALIVE_PERIOD_S}> - $<$:WIFI_MGMT_RAW_SCAN_RESULTS> - NRF70_RX_NUM_BUFS=${CONFIG_NRF70_RX_NUM_BUFS} - NRF70_MAX_TX_TOKENS=${CONFIG_NRF70_MAX_TX_TOKENS} - NRF70_RX_MAX_DATA_SIZE=${CONFIG_NRF70_RX_MAX_DATA_SIZE} - NRF70_MAX_TX_PENDING_QLEN=${CONFIG_NRF70_MAX_TX_PENDING_QLEN} - NRF70_RPU_PS_IDLE_TIMEOUT_MS=${CONFIG_NRF70_RPU_PS_IDLE_TIMEOUT_MS} - NRF70_REG_DOMAIN=${CONFIG_NRF70_REG_DOMAIN} - NRF70_BAND_2G_LOWER_EDGE_BACKOFF_DSSS=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_DSSS} - NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_2G_UPPER_EDGE_BACKOFF_DSSS=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_DSSS} - NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HE} - NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HT=${CONFIG_NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HT} - NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HE=${CONFIG_NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HE} - NRF70_PCB_LOSS_2G=${CONFIG_NRF70_PCB_LOSS_2G} - NRF70_PCB_LOSS_5G_BAND1=${CONFIG_NRF70_PCB_LOSS_5G_BAND1} - NRF70_PCB_LOSS_5G_BAND2=${CONFIG_NRF70_PCB_LOSS_5G_BAND2} - NRF70_PCB_LOSS_5G_BAND3=${CONFIG_NRF70_PCB_LOSS_5G_BAND3} - NRF70_ANT_GAIN_2G=${CONFIG_NRF70_ANT_GAIN_2G} - NRF70_ANT_GAIN_5G_BAND1=${CONFIG_NRF70_ANT_GAIN_5G_BAND1} - NRF70_ANT_GAIN_5G_BAND2=${CONFIG_NRF70_ANT_GAIN_5G_BAND2} - NRF70_ANT_GAIN_5G_BAND3=${CONFIG_NRF70_ANT_GAIN_5G_BAND3} - NRF_WIFI_PS_INT_PS=${CONFIG_NRF_WIFI_PS_INT_PS} - NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS=${CONFIG_NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS} -) - -target_include_directories( - nrf-wifi-interface - INTERFACE - ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../bus - ${NRF_WIFI_DIR}/utils/inc - ${NRF_WIFI_DIR}/os_if/inc - ${NRF_WIFI_DIR}/bus_if/bus/qspi/inc - ${NRF_WIFI_DIR}/bus_if/bal/inc - ${NRF_WIFI_DIR}/fw_if/umac_if/inc - ${NRF_WIFI_DIR}/fw_load/mips/fw/inc - ${NRF_WIFI_DIR}/hw_if/hal/inc - ${NRF_WIFI_DIR}/hw_if/hal/inc/fw - ${NRF_WIFI_DIR}/fw_if/umac_if/inc/fw -) - -if(CONFIG_NRF70_RADIO_TEST) - target_include_directories(nrf-wifi-interface INTERFACE - ${NRF_WIFI_DIR}/fw_if/umac_if/inc/radio_test - ) -elseif(CONFIG_NRF70_OFFLOADED_RAW_TX) - target_include_directories(nrf-wifi-interface INTERFACE - ${NRF_WIFI_DIR}/fw_if/umac_if/inc/offload_raw_tx - off_raw_tx/inc - ) -else() - target_include_directories(nrf-wifi-interface INTERFACE - ${NRF_WIFI_DIR}/fw_if/umac_if/inc/default - ) -endif() - -zephyr_library_sources( - ${NRF_WIFI_DIR}/os_if/src/osal.c - ${NRF_WIFI_DIR}/utils/src/list.c - ${NRF_WIFI_DIR}/utils/src/queue.c - ${NRF_WIFI_DIR}/utils/src/util.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_api.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_fw_patch_loader.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_interrupt.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_mem.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hal_reg.c - ${NRF_WIFI_DIR}/hw_if/hal/src/hpqm.c - ${NRF_WIFI_DIR}/hw_if/hal/src/pal.c - ${NRF_WIFI_DIR}/bus_if/bal/src/bal.c - ${NRF_WIFI_DIR}/bus_if/bus/qspi/src/qspi.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/cmd.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/event.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_api_common.c -) - -if(CONFIG_NRF70_RADIO_TEST) - zephyr_library_sources( - ${NRF_WIFI_DIR}/fw_if/umac_if/src/radio_test/fmac_api.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c - ) -elseif(CONFIG_NRF70_OFFLOADED_RAW_TX) - zephyr_library_sources( - ${NRF_WIFI_DIR}/fw_if/umac_if/src/offload_raw_tx/fmac_api.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c - ) -else() - zephyr_library_sources( - ${NRF_WIFI_DIR}/fw_if/umac_if/src/rx.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_vif.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/default/fmac_api.c - ) -endif() - -zephyr_library_sources_ifdef(CONFIG_NRF70_DATA_TX - ${NRF_WIFI_DIR}/fw_if/umac_if/src/tx.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c -) - -zephyr_library_sources_ifdef(CONFIG_NRF70_STA_MODE - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c -) - -zephyr_library_sources_ifdef(CONFIG_NRF70_PROMISC_DATA_RX - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_promisc.c -) - -zephyr_library_sources_ifdef(CONFIG_NRF70_AP_MODE - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_ap.c -) - -# Without WPA supplicant we only support scan -zephyr_library_sources_ifdef(CONFIG_NRF70_STA_MODE - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_peer.c - ${NRF_WIFI_DIR}/fw_if/umac_if/src/fmac_util.c -) +add_subdirectory(${ZEPHYR_NRF_WIFI_MODULE_DIR} nrf_wifi_osal) +zephyr_library_named(nrf-wifi-shim) +zephyr_include_directories(${CMAKE_CURRENT_LIST_DIR}) zephyr_library_sources( shim.c timer.c work.c ) -target_link_libraries(zephyr_interface INTERFACE nrf-wifi-interface) -target_link_libraries(nrf_wifi PRIVATE nrf70-buslib) +zephyr_library_link_libraries(nrf-wifi-osal) diff --git a/modules/openthread/Kconfig.thread b/modules/openthread/Kconfig.thread index bac5831a86a5f..2bababd4fee5d 100644 --- a/modules/openthread/Kconfig.thread +++ b/modules/openthread/Kconfig.thread @@ -195,6 +195,12 @@ config OPENTHREAD_DEFAULT_TX_POWER help Set the default TX output power [dBm] in radio driver for OpenThread purpose. +config OPENTHREAD_TCAT_MULTIRADIO_CAPABILITIES + bool "Openthread multiradio capability" + default y if OPENTHREAD_BLE_TCAT + help + Openthread multiradio capability. + config OPENTHREAD_BLE_TCAT_THREAD_STACK_SIZE int "Openthread default TCAT stack size" default 5120 if OPENTHREAD_CRYPTO_PSA diff --git a/modules/openthread/platform/alarm.c b/modules/openthread/platform/alarm.c index 8d41c1a66f9ab..26f8c1e01fc42 100644 --- a/modules/openthread/platform/alarm.c +++ b/modules/openthread/platform/alarm.c @@ -6,7 +6,7 @@ */ #define LOG_MODULE_NAME net_openthread_alarm -#define LOG_LEVEL CONFIG_OPENTHREAD_LOG_LEVEL +#define LOG_LEVEL CONFIG_OPENTHREAD_PLATFORM_LOG_LEVEL #include LOG_MODULE_REGISTER(LOG_MODULE_NAME); diff --git a/modules/openthread/platform/ble.c b/modules/openthread/platform/ble.c index a2d6cd29af872..b3d841d46d5c4 100644 --- a/modules/openthread/platform/ble.c +++ b/modules/openthread/platform/ble.c @@ -30,7 +30,7 @@ /* Zephyr Logging */ #define LOG_MODULE_NAME net_openthread_tcat -#define LOG_LEVEL CONFIG_OPENTHREAD_LOG_LEVEL +#define LOG_LEVEL CONFIG_OPENTHREAD_PLATFORM_LOG_LEVEL LOG_MODULE_REGISTER(LOG_MODULE_NAME); @@ -406,7 +406,7 @@ bool otPlatBleSupportsMultiRadio(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return false; + return IS_ENABLED(CONFIG_OPENTHREAD_TCAT_MULTIRADIO_CAPABILITIES); } otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvertisementBuffer) @@ -438,7 +438,7 @@ otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval) ARG_UNUSED(aInstance); ARG_UNUSED(aInterval); - int err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); + int err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_2, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); if (err != 0 && err != -EALREADY) { LOG_WRN("Advertising failed to start (err %d)", err); @@ -476,7 +476,7 @@ otError otPlatBleEnable(otInstance *aInstance) LOG_WRN("BLE enable failed with error code %d", err); return OT_ERROR_FAILED; } else if (err == -EALREADY) { - err = k_sem_take(&ot_plat_ble_init_semaphore, K_MSEC(500)); + bt_conn_cb_register(&conn_callbacks); return OT_ERROR_NONE; } diff --git a/modules/openthread/platform/diag.c b/modules/openthread/platform/diag.c index 23ea3b979860e..79f4e38984af9 100644 --- a/modules/openthread/platform/diag.c +++ b/modules/openthread/platform/diag.c @@ -8,20 +8,44 @@ #include #include +#include #include +#include #include "platform-zephyr.h" #include "zephyr/sys/util.h" +enum { + DIAG_TRANSMIT_MODE_IDLE, + DIAG_TRANSMIT_MODE_PACKETS, + DIAG_TRANSMIT_MODE_CARRIER, + DIAG_TRANSMIT_MODE_MODCARRIER + +} diag_trasmit_mode; + /** * Diagnostics mode variables. * */ + static bool sDiagMode; static void *sDiagCallbackContext; static otPlatDiagOutputCallback sDiagOutputCallback; +static uint8_t sTransmitMode = DIAG_TRANSMIT_MODE_IDLE; +static uint8_t sChannel = 20; +static uint32_t sTxPeriod = 1; +static int32_t sTxCount; +static int32_t sTxRequestedCount = 1; static otError startModCarrier(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]); +static otError processTransmit(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]); + +static otError parse_long(char *aArgs, long *aValue) +{ + char *endptr; + *aValue = strtol(aArgs, &endptr, 0); + return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_PARSE; +} static void diag_output(const char *aFormat, ...) { @@ -48,15 +72,16 @@ void otPlatDiagSetOutputCallback(otInstance *aInstance, otError otPlatDiagProcess(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]) { - ARG_UNUSED(aInstance); - ARG_UNUSED(aArgsLength); - #if defined(CONFIG_IEEE802154_CARRIER_FUNCTIONS) if (strcmp(aArgs[0], "modcarrier") == 0) { return startModCarrier(aInstance, aArgsLength - 1, aArgs + 1); } #endif + if (strcmp(aArgs[0], "transmit") == 0) { + return processTransmit(aInstance, aArgsLength - 1, aArgs + 1); + } + /* Add more platform specific diagnostics features here. */ diag_output("diag feature '%s' is not supported\r\n", aArgs[0]); @@ -79,7 +104,8 @@ bool otPlatDiagModeGet(void) void otPlatDiagChannelSet(uint8_t aChannel) { - ARG_UNUSED(aChannel); + sChannel = aChannel; + platformRadioChannelSet(aChannel); } void otPlatDiagTxPowerSet(int8_t aTxPower) @@ -99,19 +125,21 @@ void otPlatDiagRadioReceived(otInstance *aInstance, #if defined(CONFIG_IEEE802154_CARRIER_FUNCTIONS) otError otPlatDiagRadioTransmitCarrier(otInstance *aInstance, bool aEnable) { - if (!otPlatDiagModeGet()) { + if (sTransmitMode != DIAG_TRANSMIT_MODE_IDLE && + sTransmitMode != DIAG_TRANSMIT_MODE_CARRIER) { return OT_ERROR_INVALID_STATE; } + if (aEnable) { + sTransmitMode = DIAG_TRANSMIT_MODE_CARRIER; + } else { + sTransmitMode = DIAG_TRANSMIT_MODE_IDLE; + } + return platformRadioTransmitCarrier(aInstance, aEnable); } #endif /* CONFIG_IEEE802154_CARRIER_FUNCTIONS */ -void otPlatDiagAlarmCallback(otInstance *aInstance) -{ - ARG_UNUSED(aInstance); -} - /* * To enable gpio diag commands, in Devicetree create `openthread` node in `/options/` path * with `compatible = "openthread,config"` property and `diag-gpios` property, @@ -147,10 +175,6 @@ static otError gpio_get_spec(uint32_t gpio_idx, const struct gpio_dt_spec **spec *spec = &gpio_spec[gpio_idx]; - if (!otPlatDiagModeGet()) { - return OT_ERROR_INVALID_STATE; - } - if (!gpio_is_ready_dt(*spec)) { return OT_ERROR_INVALID_ARGS; } @@ -291,9 +315,6 @@ otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode) static otError startModCarrier(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]) { - ARG_UNUSED(aInstance); - ARG_UNUSED(aArgsLength); - bool enable = true; uint8_t data[OT_RADIO_FRAME_MAX_SIZE + 1]; @@ -301,15 +322,143 @@ static otError startModCarrier(otInstance *aInstance, uint8_t aArgsLength, char return OT_ERROR_INVALID_ARGS; } + if (sTransmitMode != DIAG_TRANSMIT_MODE_IDLE && + sTransmitMode != DIAG_TRANSMIT_MODE_MODCARRIER) { + return OT_ERROR_INVALID_STATE; + } + if (strcmp(aArgs[0], "stop") == 0) { enable = false; + sTransmitMode = DIAG_TRANSMIT_MODE_IDLE; } else { if (hex2bin(aArgs[0], strlen(aArgs[0]), data, ARRAY_SIZE(data)) == 0) { return OT_ERROR_INVALID_ARGS; } + sTransmitMode = DIAG_TRANSMIT_MODE_MODCARRIER; } return platformRadioTransmitModulatedCarrier(aInstance, enable, data); } #endif + +void otPlatDiagAlarmCallback(otInstance *aInstance) +{ + uint32_t now; + otRadioFrame *txPacket; + const uint16_t diag_packet_len = 30; + + if (sTransmitMode == DIAG_TRANSMIT_MODE_PACKETS) { + if ((sTxCount > 0) || (sTxCount == -1)) { + txPacket = otPlatRadioGetTransmitBuffer(aInstance); + + txPacket->mInfo.mTxInfo.mTxDelayBaseTime = 0; + txPacket->mInfo.mTxInfo.mTxDelay = 0; + txPacket->mInfo.mTxInfo.mMaxCsmaBackoffs = 0; + txPacket->mInfo.mTxInfo.mMaxFrameRetries = 0; + txPacket->mInfo.mTxInfo.mRxChannelAfterTxDone = sChannel; + txPacket->mInfo.mTxInfo.mTxPower = OT_RADIO_POWER_INVALID; + txPacket->mInfo.mTxInfo.mIsHeaderUpdated = false; + txPacket->mInfo.mTxInfo.mIsARetx = false; + txPacket->mInfo.mTxInfo.mCsmaCaEnabled = false; + txPacket->mInfo.mTxInfo.mCslPresent = false; + txPacket->mInfo.mTxInfo.mIsSecurityProcessed = false; + + txPacket->mLength = diag_packet_len; + + for (uint8_t i = 0; i < diag_packet_len; i++) { + txPacket->mPsdu[i] = i; + } + + otPlatRadioTransmit(aInstance, txPacket); + + if (sTxCount != -1) { + sTxCount--; + } + + now = otPlatAlarmMilliGetNow(); + otPlatAlarmMilliStartAt(aInstance, now, sTxPeriod); + } else { + sTransmitMode = DIAG_TRANSMIT_MODE_IDLE; + otPlatAlarmMilliStop(aInstance); + otPlatLog(OT_LOG_LEVEL_DEBG, OT_LOG_REGION_PLATFORM, "Transmit done"); + } + } +} + +static otError processTransmit(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]) +{ + otError error = OT_ERROR_NONE; + long value; + uint32_t now; + + if (aArgsLength == 0) { + diag_output("transmit will send %" PRId32 " diagnostic messages with %" PRIu32 + " ms interval\r\n", + sTxRequestedCount, sTxPeriod); + + } else if (strcmp(aArgs[0], "stop") == 0) { + if (sTransmitMode == DIAG_TRANSMIT_MODE_IDLE) { + return OT_ERROR_INVALID_STATE; + } + + otPlatAlarmMilliStop(aInstance); + diag_output("diagnostic message transmission is stopped\r\n"); + sTransmitMode = DIAG_TRANSMIT_MODE_IDLE; + otPlatRadioReceive(aInstance, sChannel); + + } else if (strcmp(aArgs[0], "start") == 0) { + if (sTransmitMode != DIAG_TRANSMIT_MODE_IDLE) { + return OT_ERROR_INVALID_STATE; + } + + otPlatAlarmMilliStop(aInstance); + sTransmitMode = DIAG_TRANSMIT_MODE_PACKETS; + sTxCount = sTxRequestedCount; + now = otPlatAlarmMilliGetNow(); + otPlatAlarmMilliStartAt(aInstance, now, sTxPeriod); + diag_output("sending %" PRId32 " diagnostic messages with %" PRIu32 + " ms interval\r\n", + sTxRequestedCount, sTxPeriod); + } else if (strcmp(aArgs[0], "interval") == 0) { + + if (aArgsLength != 2) { + return OT_ERROR_INVALID_ARGS; + } + + error = parse_long(aArgs[1], &value); + if (error != OT_ERROR_NONE) { + return error; + } + + if (value <= 0) { + return OT_ERROR_INVALID_ARGS; + } + sTxPeriod = (uint32_t)(value); + diag_output("set diagnostic messages interval to %" PRIu32 + " ms\r\n", sTxPeriod); + + } else if (strcmp(aArgs[0], "count") == 0) { + + if (aArgsLength != 2) { + return OT_ERROR_INVALID_ARGS; + } + + error = parse_long(aArgs[1], &value); + if (error != OT_ERROR_NONE) { + return error; + } + + if ((value <= 0) && (value != -1)) { + return OT_ERROR_INVALID_ARGS; + } + + sTxRequestedCount = (uint32_t)(value); + diag_output("set diagnostic messages count to %" PRId32 "\r\n", + sTxRequestedCount); + } else { + return OT_ERROR_INVALID_ARGS; + } + + return error; +} diff --git a/modules/openthread/platform/messagepool.c b/modules/openthread/platform/messagepool.c index cb9a64674c424..c085aeb9a582b 100644 --- a/modules/openthread/platform/messagepool.c +++ b/modules/openthread/platform/messagepool.c @@ -10,7 +10,7 @@ #include #define LOG_MODULE_NAME net_otPlat_messagepool -#define LOG_LEVEL CONFIG_OPENTHREAD_LOG_LEVEL +#define LOG_LEVEL CONFIG_OPENTHREAD_PLATFORM_LOG_LEVEL LOG_MODULE_REGISTER(LOG_MODULE_NAME); diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index dc2e46b1e701f..15688bf67a2d9 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -14,6 +14,7 @@ #define OPENTHREAD_CORE_ZEPHYR_CONFIG_H_ #include +#include #include /** @@ -510,4 +511,12 @@ #define OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT CONFIG_OPENTHREAD_MLE_CHILD_TIMEOUT #endif +/** + * @def OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + * + * NVM offset while using key refs. + * + */ +#define OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET ZEPHYR_PSA_OPENTHREAD_KEY_ID_RANGE_BEGIN + #endif /* OPENTHREAD_CORE_ZEPHYR_CONFIG_H_ */ diff --git a/modules/openthread/platform/platform-zephyr.h b/modules/openthread/platform/platform-zephyr.h index ca25fedf2b189..d6dd26adea047 100644 --- a/modules/openthread/platform/platform-zephyr.h +++ b/modules/openthread/platform/platform-zephyr.h @@ -70,6 +70,16 @@ void platformUartPanic(void); */ uint16_t platformRadioChannelGet(otInstance *aInstance); +#if defined(CONFIG_OPENTHREAD_DIAG) +/** + * Set channel on radio driver. + * + * @param[in] aChannel The channel that the radio driver should use for operation. + * + */ +void platformRadioChannelSet(uint8_t aChannel); +#endif /* CONFIG_OPENTHREAD_DIAG */ + #if defined(CONFIG_IEEE802154_CARRIER_FUNCTIONS) /** * Start/stop continuous carrier wave transmission. diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 0aaa237ee14d9..82b54a34763e6 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -722,6 +722,13 @@ uint16_t platformRadioChannelGet(otInstance *aInstance) return channel; } +#if defined(CONFIG_OPENTHREAD_DIAG) +void platformRadioChannelSet(uint8_t aChannel) +{ + channel = aChannel; +} +#endif + void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId) { ARG_UNUSED(aInstance); @@ -756,19 +763,25 @@ bool otPlatRadioIsEnabled(otInstance *aInstance) otError otPlatRadioEnable(otInstance *aInstance) { - if (!otPlatRadioIsEnabled(aInstance)) { - sState = OT_RADIO_STATE_SLEEP; + ARG_UNUSED(aInstance); + + if (sState != OT_RADIO_STATE_DISABLED && sState != OT_RADIO_STATE_SLEEP) { + return OT_ERROR_INVALID_STATE; } + sState = OT_RADIO_STATE_SLEEP; return OT_ERROR_NONE; } otError otPlatRadioDisable(otInstance *aInstance) { - if (otPlatRadioIsEnabled(aInstance)) { - sState = OT_RADIO_STATE_DISABLED; + ARG_UNUSED(aInstance); + + if (sState != OT_RADIO_STATE_DISABLED && sState != OT_RADIO_STATE_SLEEP) { + return OT_ERROR_INVALID_STATE; } + sState = OT_RADIO_STATE_DISABLED; return OT_ERROR_NONE; } @@ -776,23 +789,24 @@ otError otPlatRadioSleep(otInstance *aInstance) { ARG_UNUSED(aInstance); - otError error = OT_ERROR_INVALID_STATE; - - if (sState == OT_RADIO_STATE_SLEEP || - sState == OT_RADIO_STATE_RECEIVE || - sState == OT_RADIO_STATE_TRANSMIT) { - error = OT_ERROR_NONE; - radio_api->stop(radio_dev); - sState = OT_RADIO_STATE_SLEEP; + if (sState != OT_RADIO_STATE_SLEEP && sState != OT_RADIO_STATE_RECEIVE) { + return OT_ERROR_INVALID_STATE; } - return error; + radio_api->stop(radio_dev); + sState = OT_RADIO_STATE_SLEEP; + + return OT_ERROR_NONE; } otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) { ARG_UNUSED(aInstance); + if (sState == OT_RADIO_STATE_DISABLED) { + return OT_ERROR_INVALID_STATE; + } + channel = aChannel; radio_api->set_channel(radio_dev, aChannel); @@ -897,7 +911,9 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aPacket) radio_caps = radio_api->get_capabilities(radio_dev); - if ((sState == OT_RADIO_STATE_RECEIVE) || (radio_caps & IEEE802154_HW_SLEEP_TO_TX)) { + if (sState == OT_RADIO_STATE_RECEIVE || + (sState == OT_RADIO_STATE_SLEEP && + radio_caps & IEEE802154_HW_SLEEP_TO_TX)) { if (run_tx_task(aInstance) == 0) { error = OT_ERROR_NONE; } diff --git a/modules/openthread/platform/uart.c b/modules/openthread/platform/uart.c index ebf156ded1563..31afdac6bac83 100644 --- a/modules/openthread/platform/uart.c +++ b/modules/openthread/platform/uart.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define LOG_LEVEL CONFIG_OPENTHREAD_LOG_LEVEL +#define LOG_LEVEL CONFIG_OPENTHREAD_PLATFORM_LOG_LEVEL #define LOG_MODULE_NAME net_otPlat_uart #include diff --git a/modules/segger/CMakeLists.txt b/modules/segger/CMakeLists.txt index dcccd4d4ecc03..ab15d7c17fccb 100644 --- a/modules/segger/CMakeLists.txt +++ b/modules/segger/CMakeLists.txt @@ -1,5 +1,6 @@ if(CONFIG_USE_SEGGER_RTT) zephyr_library() + zephyr_library_compile_definitions(SEGGER_RTT_ALIGNMENT=CONFIG_SEGGER_RTT_CB_ALIGNMENT) set(SEGGER_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) zephyr_include_directories_ifdef(CONFIG_USE_SEGGER_RTT ${SEGGER_DIR}/SEGGER diff --git a/modules/segger/Kconfig b/modules/segger/Kconfig index 597b4ab9f32ce..ca2d27d4bcf13 100644 --- a/modules/segger/Kconfig +++ b/modules/segger/Kconfig @@ -25,6 +25,14 @@ config SEGGER_RTT_CUSTOM_LOCKING help Enable custom locking using Zephyr APIs. +config SEGGER_RTT_CB_ALIGNMENT + int "Alignment of the RTT control block" + default 16 + help + Specify the alignment of the RTT control block in memory. The default + alignment of 16 bytes is chosen because PyOCD fails to discover blocks + where the 16 byte `acID` field falls across a 32 byte boundary. + config SEGGER_RTT_MAX_NUM_UP_BUFFERS int "Maximum number of up-buffers" default 3 @@ -39,7 +47,6 @@ config SEGGER_RTT_BUFFER_SIZE_UP config SEGGER_RTT_BUFFER_SIZE_DOWN int "Size of the buffer for terminal input of target, from host" - default 32 if SHELL_BACKEND_RTT default 16 config SEGGER_RTT_PRINTF_BUFFER_SIZE @@ -106,7 +113,7 @@ endif choice SEGGER_RTT_INIT_MODE prompt "RTT Initialization mode" help - RTT inizialization function can avoid re-init of Cntrol Block + RTT initialization function can avoid re-init of Control Block if another program (e.g. bootloader) has already initialized it. default SEGGER_RTT_INIT_MODE_STRONG_CHECK if SEGGER_RTT_SECTION_CUSTOM default SEGGER_RTT_INIT_MODE_STRONG_CHECK diff --git a/modules/tflite-micro/CMakeLists.txt b/modules/tflite-micro/CMakeLists.txt index c0893a7d807e0..95301b34c7939 100644 --- a/modules/tflite-micro/CMakeLists.txt +++ b/modules/tflite-micro/CMakeLists.txt @@ -41,9 +41,12 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/kiss_fft_wrappers/kiss_fft_float.cc ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/kiss_fft_wrappers/kiss_fft_int16.cc ${TENSORFLOW_LITE_MICRO_DIR}/signal/src/kiss_fft_wrappers/kiss_fft_int32.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/compiler/mlir/lite/core/api/error_reporter.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/compiler/mlir/lite/schema/schema_utils.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/array.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/c/common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/debug_log.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/hexdump.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/fake_micro_context.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/memory_helpers.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/micro_allocation_info.cc @@ -81,9 +84,7 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/internal/reference/portable_tensor_utils.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/kernels/kernel_util.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/flatbuffer_conversions.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/error_reporter.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/core/api/tensor_utils.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/schema/schema_utils.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/activations.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/activations_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/add.cc @@ -91,7 +92,7 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/add_n.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/arg_min_max.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/assign_variable.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/batch_matmul.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/batch_matmul.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/batch_to_space_nd.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/broadcast_args.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/broadcast_to.cc @@ -105,6 +106,8 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/conv.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/conv_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/cumsum.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/decompress.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/decompress_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/depth_to_space.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/depthwise_conv.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/depthwise_conv_common.cc @@ -142,7 +145,7 @@ if(CONFIG_TENSORFLOW_LITE_MICRO) ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/lstm_eval.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/lstm_eval_common.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/log_softmax.cc - ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/maximum_minimum.cc + ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/maximum_minimum.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/micro_tensor_utils.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/mirror_pad.cc ${TENSORFLOW_LITE_MICRO_DIR}/tensorflow/lite/micro/kernels/${CMSIS_NN_OPTIMIZED_KERNEL_DIR}/mul.cc diff --git a/modules/tflite-micro/Kconfig b/modules/tflite-micro/Kconfig index 72789bd51de61..99a49d6a633bf 100644 --- a/modules/tflite-micro/Kconfig +++ b/modules/tflite-micro/Kconfig @@ -28,6 +28,8 @@ config TENSORFLOW_LITE_MICRO_CMSIS_NN_KERNELS select CMSIS_NN_SOFTMAX select CMSIS_NN_SVD select CMSIS_NN_LSTM + select CMSIS_NN_TRANSPOSE + select CMSIS_NN_PAD help This option adds support for CMSIS-NN optimized kernels when using TensorFlow Lite Micro. diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index fff2be3607011..cce52e45eb3de 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -210,10 +210,6 @@ if (CONFIG_BUILD_WITH_TFM) set(TFM_TOOLCHAIN_FILE "toolchain_GNUARM.cmake") set(TFM_TOOLCHAIN_PREFIX "arm-none-eabi") set(TFM_TOOLCHAIN_PATH ${GNUARMEMB_TOOLCHAIN_PATH}/bin) - elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "xtools") - set(TFM_TOOLCHAIN_FILE "toolchain_GNUARM.cmake") - set(TFM_TOOLCHAIN_PREFIX "arm-zephyr-eabi") - set(TFM_TOOLCHAIN_PATH ${XTOOLS_TOOLCHAIN_PATH}/arm-zephyr-eabi/bin) else() message(FATAL_ERROR "Unsupported ZEPHYR_TOOLCHAIN_VARIANT: ${ZEPHYR_TOOLCHAIN_VARIANT}") endif() @@ -257,6 +253,8 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DTFM_TESTS_REVISION_CHECKS=OFF) + list(APPEND TFM_CMAKE_ARGS -DETHOS_DRIVER_PATH=${CONFIG_TFM_ETHOS_DRIVER_PATH_LOCAL}) + file(MAKE_DIRECTORY ${TFM_BINARY_DIR}) add_custom_target(tfm_cmake DEPENDS ${TFM_BINARY_DIR}/CMakeCache.txt diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 9e86bda7c6fde..ade226a0a4fcd 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -310,6 +310,17 @@ config TFM_MCUBOOT_PATH_DOWNLOAD endchoice +config TFM_ETHOS_DRIVER_PATH_LOCAL + string "Path to a locally available Ethos-U driver or an empty string" + default "${ZEPHYR_HAL_ETHOS_U_MODULE_DIR}" + help + Path to a locally available Ethos-U driver to be used for TF-M builds or + an empty string to allow TF-M to automatically fetch the Ethos-U + driver from an external repository at build time. + By default Zephyr's Ethos-U driver will be used. It is present in + the hal_ethos_u module. + Alternatively, applications can point to their own paths for Ethos-U driver. + config TFM_QCBOR_PATH string prompt "Path to QCBOR or DOWNLOAD to fetch automatically" diff --git a/modules/uoscore-uedhoc/CMakeLists.txt b/modules/uoscore-uedhoc/CMakeLists.txt index aaf842e392ca6..a7f08928381d5 100644 --- a/modules/uoscore-uedhoc/CMakeLists.txt +++ b/modules/uoscore-uedhoc/CMakeLists.txt @@ -107,7 +107,8 @@ if (CONFIG_UOSCORE OR CONFIG_UEDHOC) ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_message_1.c ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_message_2.c ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_message_3.c - ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_plaintext.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_plaintext2.c + ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_decode_plaintext3.c ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_bstr_type.c ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_data_2.c ${UOSCORE_UEDHOC_SRC_DIR}/cbor/edhoc_encode_enc_structure.c diff --git a/modules/zcbor/Kconfig b/modules/zcbor/Kconfig index deb976bbcd08a..5f6ef3b76841e 100644 --- a/modules/zcbor/Kconfig +++ b/modules/zcbor/Kconfig @@ -16,7 +16,12 @@ config ZCBOR_CANONICAL bool "Produce canonical CBOR" help Enabling this will prevent zcbor from creating lists and maps with - indefinite-length arrays (it will still decode them properly). + indefinite-length arrays. + Enabling this also enables the state->constant_state->enforce_canonical + flag in all zcbor states. This flag controls validation of canonical + data when decoding. If you only want canonical encoding, please set + the enforce_canonical flag to false in all new state structs after + initialization. config ZCBOR_STOP_ON_ERROR bool "Stop on error when processing (Must also be enabled in state var)" @@ -28,7 +33,7 @@ config ZCBOR_STOP_ON_ERROR has already happened. config ZCBOR_VERBOSE - bool "Make zcbor code print messages" + bool "Make zcbor code print messages via printf" config ZCBOR_ASSERT def_bool ASSERT diff --git a/samples/arch/mpu/mpu_test/sample.yaml b/samples/arch/mpu/mpu_test/sample.yaml index ca604ed9fc706..49f97f3217417 100644 --- a/samples/arch/mpu/mpu_test/sample.yaml +++ b/samples/arch/mpu/mpu_test/sample.yaml @@ -4,5 +4,6 @@ tests: sample.mpu.mpu_test: arch_allow: arm filter: CONFIG_CPU_HAS_MPU and not CONFIG_ARM64 - tags: mpu - harness: keyboard + tags: + - mpu + harness: shell diff --git a/samples/arch/mpu/mpu_test/test_shell.yml b/samples/arch/mpu/mpu_test/test_shell.yml new file mode 100644 index 0000000000000..fcce9e59ce9c9 --- /dev/null +++ b/samples/arch/mpu/mpu_test/test_shell.yml @@ -0,0 +1,4 @@ +- command: "mpu mtest 1" + expected: "The value is: 0x.*" +- command: "mpu mtest 2" + expected: "The value is: 0x.*" diff --git a/samples/basic/blinky_pwm/boards/esp32c3_supermini.overlay b/samples/basic/blinky_pwm/boards/esp32c3_supermini.overlay new file mode 100644 index 0000000000000..ed2fc7c1b7b50 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/esp32c3_supermini.overlay @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2021 Andrei-Edward Popa + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + */ + + #include + +/ { + aliases { + pwm-0 = &ledc0; + pwm-led0 = &pwm_led_blue; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led_blue: pwm-led-gpio0-2 { + label = "PWM LED0"; + pwms = <&ledc0 0 1000 PWM_POLARITY_NORMAL>; + }; + }; +}; + +&pinctrl { + ledc0_default: ledc0-default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; diff --git a/samples/basic/blinky_pwm/boards/nrf54h20dk_nrf54h20_cpuppr.overlay b/samples/basic/blinky_pwm/boards/nrf54h20dk_nrf54h20_cpuppr.overlay new file mode 100644 index 0000000000000..92b687ba0f8e5 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/nrf54h20dk_nrf54h20_cpuppr.overlay @@ -0,0 +1,21 @@ +#include + +/ { + aliases { + pwm-led0 = &pwm_led2; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led2: pwm_led_2 { + pwms = <&pwm130 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; +}; + +&pwm130 { + status = "okay"; + pinctrl-0 = <&pwm130_default>; + pinctrl-1 = <&pwm130_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/samples/basic/blinky_pwm/boards/nucleo_l4r5zi.overlay b/samples/basic/blinky_pwm/boards/nucleo_l4r5zi.overlay index a0192785994f1..acfca5fc91ec1 100644 --- a/samples/basic/blinky_pwm/boards/nucleo_l4r5zi.overlay +++ b/samples/basic/blinky_pwm/boards/nucleo_l4r5zi.overlay @@ -8,6 +8,10 @@ status = "okay"; }; +&timers1 { + st,prescaler = <10000>; +}; + &pwm1 { status = "okay"; }; diff --git a/samples/basic/blinky_pwm/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/basic/blinky_pwm/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 0000000000000..55fe52a20ce0f --- /dev/null +++ b/samples/basic/blinky_pwm/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,4 @@ +&pwm130 { + status = "reserved"; + interrupt-parent = <&cpuppr_clic>; +}; diff --git a/samples/basic/blinky_pwm/sysbuild/vpr_launcher/prj.conf b/samples/basic/blinky_pwm/sysbuild/vpr_launcher/prj.conf new file mode 100644 index 0000000000000..b2a4ba591044e --- /dev/null +++ b/samples/basic/blinky_pwm/sysbuild/vpr_launcher/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/samples/basic/button/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay b/samples/basic/button/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay new file mode 100644 index 0000000000000..3c8c3537e39eb --- /dev/null +++ b/samples/basic/button/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&gpio{ + status = "okay"; +}; + +&gpio18{ + irqs = <0 16>; +}; diff --git a/samples/basic/fade_led/boards/nrf54h20dk_nrf54h20_cpuppr.overlay b/samples/basic/fade_led/boards/nrf54h20dk_nrf54h20_cpuppr.overlay new file mode 100644 index 0000000000000..92b687ba0f8e5 --- /dev/null +++ b/samples/basic/fade_led/boards/nrf54h20dk_nrf54h20_cpuppr.overlay @@ -0,0 +1,21 @@ +#include + +/ { + aliases { + pwm-led0 = &pwm_led2; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led2: pwm_led_2 { + pwms = <&pwm130 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; +}; + +&pwm130 { + status = "okay"; + pinctrl-0 = <&pwm130_default>; + pinctrl-1 = <&pwm130_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/samples/basic/fade_led/src/main.c b/samples/basic/fade_led/src/main.c index c6a49a13a1222..1a7b7ef26fdad 100644 --- a/samples/basic/fade_led/src/main.c +++ b/samples/basic/fade_led/src/main.c @@ -14,46 +14,57 @@ #include #include -static const struct pwm_dt_spec pwm_led0 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0)); +#define PWM_LED_ALIAS(i) DT_ALIAS(_CONCAT(pwm_led, i)) +#define PWM_LED_IS_OKAY(i) DT_NODE_HAS_STATUS_OKAY(DT_PARENT(PWM_LED_ALIAS(i))) +#define PWM_LED(i, _) IF_ENABLED(PWM_LED_IS_OKAY(i), (PWM_DT_SPEC_GET(PWM_LED_ALIAS(i)),)) + +#define MAX_LEDS 10 +static const struct pwm_dt_spec pwm_leds[] = {LISTIFY(MAX_LEDS, PWM_LED, ())}; #define NUM_STEPS 50U #define SLEEP_MSEC 25U int main(void) { - uint32_t pulse_width = 0U; - uint32_t step = pwm_led0.period / NUM_STEPS; + uint32_t pulse_widths[ARRAY_SIZE(pwm_leds)]; + uint32_t steps[ARRAY_SIZE(pwm_leds)]; uint8_t dir = 1U; int ret; - printk("PWM-based LED fade\n"); - - if (!pwm_is_ready_dt(&pwm_led0)) { - printk("Error: PWM device %s is not ready\n", - pwm_led0.dev->name); - return 0; - } + printk("PWM-based LED fade. Found %d LEDs\n", ARRAY_SIZE(pwm_leds)); - while (1) { - ret = pwm_set_pulse_dt(&pwm_led0, pulse_width); - if (ret) { - printk("Error %d: failed to set pulse width\n", ret); + for (size_t i = 0; i < ARRAY_SIZE(pwm_leds); i++) { + pulse_widths[i] = 0; + steps[i] = pwm_leds[i].period / NUM_STEPS; + if (!pwm_is_ready_dt(&pwm_leds[i])) { + printk("Error: PWM device %s is not ready\n", pwm_leds[i].dev->name); return 0; } - printk("Using pulse width %d%%\n", 100 * pulse_width / pwm_led0.period); + } - if (dir) { - pulse_width += step; - if (pulse_width >= pwm_led0.period) { - pulse_width = pwm_led0.period - step; - dir = 0U; + while (1) { + for (size_t i = 0; i < ARRAY_SIZE(pwm_leds); i++) { + ret = pwm_set_pulse_dt(&pwm_leds[i], pulse_widths[i]); + if (ret) { + printk("Error %d: failed to set pulse width for LED %d\n", ret, i); } - } else { - if (pulse_width >= step) { - pulse_width -= step; + printk("LED %d: Using pulse width %d%%\n", i, + 100 * pulse_widths[i] / pwm_leds[i].period); + + if (dir) { + if (pulse_widths[i] + steps[i] >= pwm_leds[i].period) { + pulse_widths[i] = pwm_leds[i].period; + dir = 0U; + } else { + pulse_widths[i] += steps[i]; + } } else { - pulse_width = step; - dir = 1U; + if (pulse_widths[i] <= steps[i]) { + pulse_widths[i] = 0; + dir = 1U; + } else { + pulse_widths[i] -= steps[i]; + } } } diff --git a/samples/basic/fade_led/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/basic/fade_led/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 0000000000000..55fe52a20ce0f --- /dev/null +++ b/samples/basic/fade_led/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,4 @@ +&pwm130 { + status = "reserved"; + interrupt-parent = <&cpuppr_clic>; +}; diff --git a/samples/basic/fade_led/sysbuild/vpr_launcher/prj.conf b/samples/basic/fade_led/sysbuild/vpr_launcher/prj.conf new file mode 100644 index 0000000000000..b2a4ba591044e --- /dev/null +++ b/samples/basic/fade_led/sysbuild/vpr_launcher/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/samples/basic/sys_heap/prj.conf b/samples/basic/sys_heap/prj.conf index 2ffddad1e9b18..0c486563862cd 100644 --- a/samples/basic/sys_heap/prj.conf +++ b/samples/basic/sys_heap/prj.conf @@ -1 +1,2 @@ CONFIG_SYS_HEAP_RUNTIME_STATS=y +CONFIG_SYS_HEAP_ARRAY_SIZE=4 diff --git a/samples/basic/sys_heap/src/main.c b/samples/basic/sys_heap/src/main.c index 33f72302688df..e59ab74928385 100644 --- a/samples/basic/sys_heap/src/main.c +++ b/samples/basic/sys_heap/src/main.c @@ -9,10 +9,13 @@ #define HEAP_SIZE 256 +K_HEAP_DEFINE(my_kernel_heap, HEAP_SIZE); + static char heap_mem[HEAP_SIZE]; static struct sys_heap heap; -static void print_sys_memory_stats(void); +static void print_sys_memory_stats(struct sys_heap *); +static void print_all_heaps(void); int main(void) { @@ -21,26 +24,42 @@ int main(void) printk("System heap sample\n\n"); sys_heap_init(&heap, heap_mem, HEAP_SIZE); - print_sys_memory_stats(); + print_sys_memory_stats(&heap); p = sys_heap_alloc(&heap, 150); - print_sys_memory_stats(); + print_sys_memory_stats(&heap); p = sys_heap_realloc(&heap, p, 100); - print_sys_memory_stats(); + print_sys_memory_stats(&heap); sys_heap_free(&heap, p); - print_sys_memory_stats(); + print_sys_memory_stats(&heap); + + print_all_heaps(); return 0; } -static void print_sys_memory_stats(void) +static void print_sys_memory_stats(struct sys_heap *hp) { struct sys_memory_stats stats; - sys_heap_runtime_stats_get(&heap, &stats); + sys_heap_runtime_stats_get(hp, &stats); printk("allocated %zu, free %zu, max allocated %zu, heap size %u\n", stats.allocated_bytes, stats.free_bytes, stats.max_allocated_bytes, HEAP_SIZE); } + +static void print_all_heaps(void) +{ + struct sys_heap **ha; + size_t i, n; + + n = sys_heap_array_get(&ha); + printk("There are %zu heaps allocated:\n", n); + + for (i = 0; i < n; i++) { + printk("\t%zu - address %p ", i, ha[i]); + print_sys_memory_stats(ha[i]); + } +} diff --git a/samples/bluetooth/bap_broadcast_assistant/prj.conf b/samples/bluetooth/bap_broadcast_assistant/prj.conf index e39c4c3eef05f..370ff75f26064 100644 --- a/samples/bluetooth/bap_broadcast_assistant/prj.conf +++ b/samples/bluetooth/bap_broadcast_assistant/prj.conf @@ -10,8 +10,6 @@ CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=191 -CONFIG_BT_SEND_ECC_EMULATION=y - CONFIG_BT_EXT_ADV=y CONFIG_BT_PER_ADV_SYNC=y CONFIG_BT_BAP_BASS_MAX_SUBGROUPS=2 diff --git a/samples/bluetooth/bap_broadcast_sink/CMakeLists.txt b/samples/bluetooth/bap_broadcast_sink/CMakeLists.txt index 66649d87a33c8..5137eba4cb24d 100644 --- a/samples/bluetooth/bap_broadcast_sink/CMakeLists.txt +++ b/samples/bluetooth/bap_broadcast_sink/CMakeLists.txt @@ -6,6 +6,10 @@ project(bap_unicast_server) target_sources(app PRIVATE src/main.c + src/stream_rx.c ) +zephyr_sources_ifdef(CONFIG_LIBLC3 src/lc3.c) +zephyr_sources_ifdef(CONFIG_USB_DEVICE_AUDIO src/usb.c) + zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) diff --git a/samples/bluetooth/bap_broadcast_sink/Kconfig b/samples/bluetooth/bap_broadcast_sink/Kconfig index e8e10d84a742b..597b54e6c9f5e 100644 --- a/samples/bluetooth/bap_broadcast_sink/Kconfig +++ b/samples/bluetooth/bap_broadcast_sink/Kconfig @@ -41,7 +41,7 @@ config MAX_CODEC_FRAMES_PER_SDU range 1 255 help Maximum number of codec frames per SDU supported by this device. Increasing this value - allows support for a greater variaty of broadcasts, but also increases memory usage. + allows support for a greater variety of broadcasts, but also increases memory usage. config ENABLE_LC3 bool "Enable the LC3 codec" @@ -80,4 +80,11 @@ config TARGET_BROADCAST_CHANNEL Channel Audio Location to sync to. These corresponds to the bt_audio_location, supporting mono, left and right channels +config INFO_REPORTING_INTERVAL + int "Number of SDUs received between each information report" + default 1000 + help + Determines how often information about received data is logged. + Set to 0 to disable reporting. + source "Kconfig.zephyr" diff --git a/samples/bluetooth/bap_broadcast_sink/prj.conf b/samples/bluetooth/bap_broadcast_sink/prj.conf index fe0d8787d763c..7c4c9595bab63 100644 --- a/samples/bluetooth/bap_broadcast_sink/prj.conf +++ b/samples/bluetooth/bap_broadcast_sink/prj.conf @@ -12,8 +12,8 @@ CONFIG_BT_ISO_SYNC_RECEIVER=y CONFIG_BT_BAP_BROADCAST_SINK=y CONFIG_BT_BAP_SCAN_DELEGATOR=y CONFIG_BT_ISO_MAX_CHAN=2 -# Allocate 2 RX buffers per channel -CONFIG_BT_ISO_RX_BUF_COUNT=4 +# Allocate 4 RX buffers per channel +CONFIG_BT_ISO_RX_BUF_COUNT=8 CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT=2 CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT=2 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS=2 @@ -25,5 +25,3 @@ CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE=64 CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE=64 CONFIG_BT_DEVICE_NAME="Broadcast Audio Sink" - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/bap_broadcast_sink/src/lc3.c b/samples/bluetooth/bap_broadcast_sink/src/lc3.c new file mode 100644 index 0000000000000..9aba8a1508b0f --- /dev/null +++ b/samples/bluetooth/bap_broadcast_sink/src/lc3.c @@ -0,0 +1,495 @@ +/** + * @file + * @brief Bluetooth BAP Broadcast Sink LC3 extension + * + * This files handles all the LC3 related functionality for the sample + * + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "lc3.h" +#include "stream_rx.h" +#include "usb.h" + +LOG_MODULE_REGISTER(lc3, CONFIG_LOG_DEFAULT_LEVEL); + +#define LC3_ENCODER_STACK_SIZE 4096 +#define LC3_ENCODER_PRIORITY 5 + +struct lc3_data { + void *fifo_reserved; /* 1st word reserved for use by FIFO */ + struct net_buf *buf; + struct stream_rx *stream; + uint32_t ts; + bool do_plc; +}; + +K_MEM_SLAB_DEFINE_STATIC(lc3_data_slab, sizeof(struct lc3_data), CONFIG_BT_ISO_RX_BUF_COUNT, + __alignof__(struct lc3_data)); + +static int16_t lc3_rx_buf[LC3_MAX_NUM_SAMPLES_MONO]; +static K_FIFO_DEFINE(lc3_in_fifo); + +/* We only want to send USB to left/right from a single stream. If we have 2 left streams, the + * outgoing audio is going to be terrible. + * Since a stream can contain stereo data, both of these may be the same stream. + */ +static struct stream_rx *usb_left_stream; +static struct stream_rx *usb_right_stream; +static size_t rx_streaming_cnt; + +static int init_lc3_decoder(struct stream_rx *stream, uint32_t lc3_frame_duration_us, + uint32_t lc3_freq_hz) +{ + if (stream == NULL) { + LOG_ERR("NULL stream to init LC3 decoder"); + return -EINVAL; + } + + if (stream->lc3_decoder != NULL) { + LOG_ERR("Already initialized"); + return -EALREADY; + } + + if (lc3_freq_hz == 0U || lc3_frame_duration_us == 0U) { + LOG_ERR("Invalid freq (%u) or frame duration (%u)", lc3_freq_hz, + lc3_frame_duration_us); + + return -EINVAL; + } + + LOG_INF("Initializing the LC3 decoder with %u us duration and %u Hz frequency", + lc3_frame_duration_us, lc3_freq_hz); + /* Create the decoder instance. This shall complete before stream_started() is called. */ + stream->lc3_decoder = + lc3_setup_decoder(lc3_frame_duration_us, lc3_freq_hz, + IS_ENABLED(CONFIG_USB_DEVICE_AUDIO) ? USB_SAMPLE_RATE_HZ : 0, + &stream->lc3_decoder_mem); + if (stream->lc3_decoder == NULL) { + LOG_ERR("Failed to setup LC3 decoder - wrong parameters?\n"); + return -EINVAL; + } + + LOG_INF("Initialized LC3 decoder for %p", stream); + rx_streaming_cnt++; + + return 0; +} + +static bool decode_frame(struct lc3_data *data, size_t frame_cnt) +{ + const struct stream_rx *stream = data->stream; + const size_t total_frames = stream->lc3_chan_cnt * stream->lc3_frame_blocks_per_sdu; + const uint16_t octets_per_frame = stream->lc3_octets_per_frame; + struct net_buf *buf = data->buf; + void *iso_data; + int err; + + if (data->do_plc) { + iso_data = NULL; /* perform PLC */ + +#if CONFIG_INFO_REPORTING_INTERVAL > 0 + if ((stream->reporting_info.lc3_decoded_cnt % CONFIG_INFO_REPORTING_INTERVAL) == + 0) { + LOG_DBG("[%zu]: Performing PLC", stream->reporting_info.lc3_decoded_cnt); + } +#endif /* CONFIG_INFO_REPORTING_INTERVAL > 0 */ + + data->do_plc = false; /* clear flag */ + } else { + iso_data = net_buf_pull_mem(data->buf, octets_per_frame); + +#if CONFIG_INFO_REPORTING_INTERVAL > 0 + if ((stream->reporting_info.lc3_decoded_cnt % CONFIG_INFO_REPORTING_INTERVAL) == + 0) { + LOG_DBG("[%zu]: Decoding frame of size %u (%u/%u)", + stream->reporting_info.lc3_decoded_cnt, octets_per_frame, + frame_cnt + 1, total_frames); + } +#endif /* CONFIG_INFO_REPORTING_INTERVAL > 0 */ + } + + err = lc3_decode(stream->lc3_decoder, iso_data, octets_per_frame, LC3_PCM_FORMAT_S16, + lc3_rx_buf, 1); + if (err < 0) { + LOG_ERR("Failed to decode LC3 data (%u/%u - %u/%u)", frame_cnt + 1, total_frames, + octets_per_frame * frame_cnt, buf->len); + return false; + } + + return true; +} + +static int get_lc3_chan_alloc_from_index(const struct stream_rx *stream, uint8_t index, + enum bt_audio_location *chan_alloc) +{ +#if defined(CONFIG_USB_DEVICE_AUDIO) + const bool has_left = (stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0; + const bool has_right = (stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0; + const bool is_mono = stream->lc3_chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO; + const bool is_left = index == 0 && has_left; + const bool is_right = has_right && (index == 0U || (index == 1U && has_left)); + + /* LC3 is always Left before Right, so we can use the index and the stream channel + * allocation to determine if index 0 is left or right. + */ + if (is_left) { + *chan_alloc = BT_AUDIO_LOCATION_FRONT_LEFT; + } else if (is_right) { + *chan_alloc = BT_AUDIO_LOCATION_FRONT_RIGHT; + } else if (is_mono) { + *chan_alloc = BT_AUDIO_LOCATION_MONO_AUDIO; + } else { + /* Not suitable for USB */ + return -EINVAL; + } + + return 0; +#else /* !CONFIG_USB_DEVICE_AUDIO */ + return -EINVAL; +#endif /* CONFIG_USB_DEVICE_AUDIO */ +} + +static size_t decode_frame_block(struct lc3_data *data, size_t frame_cnt) +{ + const struct stream_rx *stream = data->stream; + const uint8_t chan_cnt = stream->lc3_chan_cnt; + size_t decoded_frames = 0U; + + for (uint8_t i = 0U; i < chan_cnt; i++) { + /* We provide the total number of decoded frames to `decode_frame` for logging + * purposes + */ + if (decode_frame(data, frame_cnt + decoded_frames)) { + decoded_frames++; + + if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) { + enum bt_audio_location chan_alloc; + int err; + + err = get_lc3_chan_alloc_from_index(stream, i, &chan_alloc); + if (err != 0) { + /* Not suitable for USB */ + continue; + } + + /* We only want to left or right from one stream to USB */ + if ((chan_alloc == BT_AUDIO_LOCATION_FRONT_LEFT && + stream != usb_left_stream) || + (chan_alloc == BT_AUDIO_LOCATION_FRONT_RIGHT && + stream != usb_right_stream)) { + continue; + } + + /* TODO: Add support for properly support the presentation delay. + * For now we just send audio to USB as soon as we get it + */ + err = usb_add_frame_to_usb(chan_alloc, lc3_rx_buf, + sizeof(lc3_rx_buf), data->ts); + if (err == -EINVAL) { + continue; + } + } + } else { + /* If decoding failed, we clear the data to USB as it would contain + * invalid data + */ + if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) { + usb_clear_frames_to_usb(); + } + + break; + } + } + + return decoded_frames; +} + +static void do_lc3_decode(struct lc3_data *data) +{ + struct stream_rx *stream = data->stream; + + if (stream->lc3_decoder != NULL) { + const uint8_t frame_blocks_per_sdu = stream->lc3_frame_blocks_per_sdu; + size_t frame_cnt; + + frame_cnt = 0; + for (uint8_t i = 0U; i < frame_blocks_per_sdu; i++) { + const size_t decoded_frames = decode_frame_block(data, frame_cnt); + + if (decoded_frames == 0) { + break; + } + + frame_cnt += decoded_frames; + } + +#if CONFIG_INFO_REPORTING_INTERVAL > 0 + stream->reporting_info.lc3_decoded_cnt++; +#endif /* CONFIG_INFO_REPORTING_INTERVAL > 0 */ + } + + net_buf_unref(data->buf); +} + +static void lc3_decoder_thread_func(void *arg1, void *arg2, void *arg3) +{ + while (true) { + struct lc3_data *data = k_fifo_get(&lc3_in_fifo, K_FOREVER); + struct stream_rx *stream = data->stream; + + if (stream->lc3_decoder == NULL) { + LOG_WRN("Decoder is NULL, discarding data from FIFO"); + k_mem_slab_free(&lc3_data_slab, (void *)data); + continue; /* Wait for new data */ + } + + do_lc3_decode(data); + + k_mem_slab_free(&lc3_data_slab, (void *)data); + } +} + +int lc3_enable(struct stream_rx *stream) +{ + const struct bt_audio_codec_cfg *codec_cfg = stream->stream.codec_cfg; + uint32_t lc3_frame_duration_us; + uint32_t lc3_freq_hz; + int ret; + + if (codec_cfg->id != BT_HCI_CODING_FORMAT_LC3) { + return -EINVAL; + } + + ret = bt_audio_codec_cfg_get_freq(codec_cfg); + if (ret >= 0) { + ret = bt_audio_codec_cfg_freq_to_freq_hz(ret); + + if (ret > 0) { + if (ret == 8000 || ret == 16000 || ret == 24000 || ret == 32000 || + ret == 48000) { + lc3_freq_hz = (uint32_t)ret; + } else { + LOG_ERR("Unsupported frequency for LC3: %d", ret); + lc3_freq_hz = 0U; + } + } else { + LOG_ERR("Invalid frequency: %d", ret); + lc3_freq_hz = 0U; + } + } else { + LOG_ERR("Could not get frequency: %d", ret); + lc3_freq_hz = 0U; + } + + if (lc3_freq_hz == 0U) { + return -EINVAL; + } + + ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); + if (ret >= 0) { + ret = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); + if (ret > 0) { + lc3_frame_duration_us = (uint32_t)ret; + } else { + LOG_ERR("Invalid frame duration: %d", ret); + lc3_frame_duration_us = 0U; + } + } else { + LOG_ERR("Could not get frame duration: %d", ret); + lc3_frame_duration_us = 0U; + } + + if (lc3_frame_duration_us == 0U) { + return -EINVAL; + } + + ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &stream->lc3_chan_allocation, true); + if (ret == 0) { + stream->lc3_chan_cnt = bt_audio_get_chan_count(stream->lc3_chan_allocation); + } else { + LOG_DBG("Could not get channel allocation: %d", ret); + stream->lc3_chan_cnt = 0U; + } + + if (stream->lc3_chan_cnt == 0U) { + return -EINVAL; + } + + ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true); + if (ret >= 0) { + stream->lc3_frame_blocks_per_sdu = (uint8_t)ret; + } else { + LOG_ERR("Could not get frame blocks per SDU: %d", ret); + stream->lc3_frame_blocks_per_sdu = 0U; + } + + if (stream->lc3_frame_blocks_per_sdu == 0U) { + return -EINVAL; + } + + ret = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); + if (ret >= 0) { + stream->lc3_octets_per_frame = (uint16_t)ret; + } else { + LOG_ERR("Could not get octets per frame: %d", ret); + stream->lc3_octets_per_frame = 0U; + } + + if (stream->lc3_octets_per_frame == 0U) { + return -EINVAL; + } + + if (stream->lc3_decoder == NULL) { + const int err = init_lc3_decoder(stream, lc3_frame_duration_us, lc3_freq_hz); + + if (err != 0) { + LOG_ERR("Failed to init LC3 decoder: %d", err); + + return err; + } + } + + if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) { + if ((stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0) { + if (usb_left_stream == NULL) { + LOG_INF("Setting USB left stream to %p", stream); + usb_left_stream = stream; + } else { + LOG_WRN("Multiple left streams started"); + } + } + + if ((stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0) { + if (usb_right_stream == NULL) { + LOG_INF("Setting USB right stream to %p", stream); + usb_right_stream = stream; + } else { + LOG_WRN("Multiple right streams started"); + } + } + } + + return 0; +} + +int lc3_disable(struct stream_rx *stream) +{ + if (rx_streaming_cnt == 0 || stream->lc3_decoder == NULL) { + return -EINVAL; + } + + stream->lc3_decoder = NULL; + rx_streaming_cnt--; + + if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) { + if (usb_left_stream == stream) { + usb_left_stream = NULL; + } + if (usb_right_stream == stream) { + usb_right_stream = NULL; + } + } + + return 0; +} + +void lc3_enqueue_for_decoding(struct stream_rx *stream, const struct bt_iso_recv_info *info, + struct net_buf *buf) +{ + const uint8_t frame_blocks_per_sdu = stream->lc3_frame_blocks_per_sdu; + const uint16_t octets_per_frame = stream->lc3_octets_per_frame; + const uint8_t chan_cnt = stream->lc3_chan_cnt; + struct lc3_data *data; + + if (stream->lc3_decoder == NULL) { + return; + } + + /* Allocate a context that holds both the buffer and the stream so that we can + * send both of these values to the LC3 decoder thread as a single struct + * in a FIFO + */ + if (k_mem_slab_alloc(&lc3_data_slab, (void **)&data, K_NO_WAIT)) { + LOG_WRN("Could not allocate LC3 data item"); + return; + } + + if ((info->flags & BT_ISO_FLAGS_VALID) == 0) { + data->do_plc = true; + } else if (buf->len != (octets_per_frame * chan_cnt * frame_blocks_per_sdu)) { + if (buf->len != 0U) { + LOG_WRN("Expected %u frame blocks with %u channels of size %u, but " + "length is %u", + frame_blocks_per_sdu, chan_cnt, octets_per_frame, buf->len); + } + + data->do_plc = true; + } + + data->buf = net_buf_ref(buf); + data->stream = stream; + if (info->flags & BT_ISO_FLAGS_TS) { + data->ts = info->ts; + } else { + data->ts = 0U; + } + + k_fifo_put(&lc3_in_fifo, data); +} + +int lc3_init(void) +{ + static K_KERNEL_STACK_DEFINE(lc3_decoder_thread_stack, 4096); + const int lc3_decoder_thread_prio = K_PRIO_PREEMPT(5); + static struct k_thread lc3_decoder_thread; + static bool initialized; + + if (initialized) { + return -EALREADY; + } + + k_thread_create(&lc3_decoder_thread, lc3_decoder_thread_stack, + K_KERNEL_STACK_SIZEOF(lc3_decoder_thread_stack), lc3_decoder_thread_func, + NULL, NULL, NULL, lc3_decoder_thread_prio, 0, K_NO_WAIT); + k_thread_name_set(&lc3_decoder_thread, "LC3 Decoder"); + + LOG_INF("LC3 initialized"); + initialized = true; + + return 0; +} + +size_t lc3_get_rx_streaming_cnt(void) +{ + return rx_streaming_cnt; +} diff --git a/samples/bluetooth/bap_broadcast_sink/src/lc3.h b/samples/bluetooth/bap_broadcast_sink/src/lc3.h new file mode 100644 index 0000000000000..2b9ef3ff0c90e --- /dev/null +++ b/samples/bluetooth/bap_broadcast_sink/src/lc3.h @@ -0,0 +1,92 @@ +/** + * @file + * @brief Bluetooth BAP Broadcast Sink LC3 header + * + * This files handles all the LC3 related functionality for the sample + * + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef SAMPLE_BAP_BROADCAST_SINK_LC3_H +#define SAMPLE_BAP_BROADCAST_SINK_LC3_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stream_rx.h" + +#define LC3_MAX_SAMPLE_RATE_HZ 48000U +#define LC3_MAX_FRAME_DURATION_US 10000U +#define LC3_MAX_NUM_SAMPLES_MONO \ + ((LC3_MAX_FRAME_DURATION_US * LC3_MAX_SAMPLE_RATE_HZ) / USEC_PER_SEC) +#define LC3_MAX_NUM_SAMPLES_STEREO (LC3_MAX_NUM_SAMPLES_MONO * 2U) + +/** + * @brief Returns the number of active streams using an LC3 codec + * + * @return the number of active streams using an LC3 codec + */ +size_t lc3_get_rx_streaming_cnt(void); + +/** + * @brief Enables LC3 for a stream + * + * This will initialize the LC3 decoder given the @p stream codec configuration + * + * @param stream The stream to enable LC3 for + + * @retval 0 Success + * @retval -EINVAL The stream is not LC3 codec configured or the codec configuration is invalid + */ +int lc3_enable(struct stream_rx *stream); + +/** + * @brief Disabled LC3 for a stream + * + * @param stream The stream to disable LC3 for + + * @retval 0 Success + * @retval -EINVAL The stream is LC3 initialized + */ +int lc3_disable(struct stream_rx *stream); + +/** + * @brief Enqueue an SDU for decoding + * + * @param stream The stream that received the SDU + * @param info Information about the SDU + * @param buf The buffer of the SDU + */ +void lc3_enqueue_for_decoding(struct stream_rx *stream, const struct bt_iso_recv_info *info, + struct net_buf *buf); + +/** + * @brief Initialize the LC3 module + * + * This will start the thread if not already initialized + * + * @retval 0 Success + * @retval -EALREADY Already initialized + */ +int lc3_init(void); +#endif /* SAMPLE_BAP_BROADCAST_SINK_LC3_H */ diff --git a/samples/bluetooth/bap_broadcast_sink/src/main.c b/samples/bluetooth/bap_broadcast_sink/src/main.c index cee4f5b008cb9..e80da73d465a7 100644 --- a/samples/bluetooth/bap_broadcast_sink/src/main.c +++ b/samples/bluetooth/bap_broadcast_sink/src/main.c @@ -32,17 +32,9 @@ #include #include -#if defined(CONFIG_LIBLC3) #include "lc3.h" -#endif /* defined(CONFIG_LIBLC3) */ -#if defined(CONFIG_USB_DEVICE_AUDIO) -#include -#include -#include -#include -#include -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ - +#include "stream_rx.h" +#include "usb.h" BUILD_ASSERT(IS_ENABLED(CONFIG_SCAN_SELF) || IS_ENABLED(CONFIG_SCAN_OFFLOAD), "Either SCAN_SELF or SCAN_OFFLOAD must be enabled"); @@ -63,27 +55,6 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_SCAN_SELF) || IS_ENABLED(CONFIG_SCAN_OFFLOAD), #define NAME_LEN sizeof(CONFIG_TARGET_BROADCAST_NAME) + 1 #define BROADCAST_DATA_ELEMENT_SIZE sizeof(int16_t) -#if defined(CONFIG_LIBLC3) -#define LC3_MAX_SAMPLE_RATE 48000U -#define LC3_MAX_FRAME_DURATION_US 10000U -#define LC3_MAX_NUM_SAMPLES_MONO ((LC3_MAX_FRAME_DURATION_US * LC3_MAX_SAMPLE_RATE) \ - / USEC_PER_SEC) -#define LC3_MAX_NUM_SAMPLES_STEREO (LC3_MAX_NUM_SAMPLES_MONO * 2) - -#define LC3_ENCODER_STACK_SIZE 4096 -#define LC3_ENCODER_PRIORITY 5 -#endif /* defined(CONFIG_LIBLC3) */ - -#if defined(CONFIG_USB_DEVICE_AUDIO) -#define USB_ENQUEUE_COUNT 10U -#define USB_SAMPLE_RATE 48000U -#define USB_FRAME_DURATION_US 1000U -#define USB_MONO_SAMPLE_SIZE \ - ((USB_FRAME_DURATION_US * USB_SAMPLE_RATE * BROADCAST_DATA_ELEMENT_SIZE) / USEC_PER_SEC) -#define USB_STEREO_SAMPLE_SIZE (USB_MONO_SAMPLE_SIZE * 2) -#define USB_RING_BUF_SIZE (5 * LC3_MAX_NUM_SAMPLES_STEREO) /* 5 SDUs*/ -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ - static K_SEM_DEFINE(sem_broadcast_sink_stopped, 0U, 1U); static K_SEM_DEFINE(sem_connected, 0U, 1U); static K_SEM_DEFINE(sem_disconnected, 0U, 1U); @@ -107,29 +78,7 @@ static struct bt_le_scan_recv_info broadcaster_info; static bt_addr_le_t broadcaster_addr; static struct bt_le_per_adv_sync *pa_sync; static uint32_t broadcaster_broadcast_id; -static struct broadcast_sink_stream { - struct bt_bap_stream stream; - size_t recv_cnt; - size_t loss_cnt; - size_t error_cnt; - size_t valid_cnt; -#if defined(CONFIG_LIBLC3) - struct net_buf *in_buf; - struct k_work_delayable lc3_decode_work; - - /* LC3 config values */ - enum bt_audio_location chan_allocation; - uint16_t lc3_octets_per_frame; - uint8_t lc3_frames_blocks_per_sdu; - - /* Internal lock for protecting net_buf from multiple access */ - struct k_mutex lc3_decoder_mutex; - lc3_decoder_t lc3_decoder; - lc3_decoder_mem_48k_t lc3_decoder_mem; -#endif /* defined(CONFIG_LIBLC3) */ -} streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; - -static struct bt_bap_stream *streams_p[ARRAY_SIZE(streams)]; +static struct bt_bap_stream *bap_streams_p[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; static volatile bool big_synced; static volatile bool base_received; static struct bt_conn *broadcast_assistant_conn; @@ -145,360 +94,25 @@ static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( /* Create a mask for the maximum BIS we can sync to using the number of streams * we have. Bit 0 is BIS index 1. */ -static const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(streams)); +static const uint32_t bis_index_mask = BIT_MASK(CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT); static uint32_t requested_bis_sync; static uint32_t bis_index_bitfield; static uint8_t sink_broadcast_code[BT_ISO_BROADCAST_CODE_SIZE]; -uint64_t total_rx_iso_packet_count; /* This value is exposed to test code */ - static int stop_adv(void); -#if defined(CONFIG_USB_DEVICE_AUDIO) -RING_BUF_DECLARE(usb_ring_buf, USB_RING_BUF_SIZE); -NET_BUF_POOL_DEFINE(usb_tx_buf_pool, USB_ENQUEUE_COUNT, USB_STEREO_SAMPLE_SIZE, 0, net_buf_destroy); - -static void add_to_usb_ring_buf(const int16_t audio_buf[LC3_MAX_NUM_SAMPLES_STEREO]); -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ - -#if defined(CONFIG_LIBLC3) -static K_SEM_DEFINE(lc3_decoder_sem, 0, 1); - -static void do_lc3_decode(lc3_decoder_t decoder, const void *in_data, uint8_t octets_per_frame, - int16_t out_data[LC3_MAX_NUM_SAMPLES_MONO]); -static void lc3_decoder_thread(void *arg1, void *arg2, void *arg3); -K_THREAD_DEFINE(decoder_tid, LC3_ENCODER_STACK_SIZE, lc3_decoder_thread, - NULL, NULL, NULL, LC3_ENCODER_PRIORITY, 0, -1); - -/* Consumer thread of the decoded stream data */ -static void lc3_decoder_thread(void *arg1, void *arg2, void *arg3) +static void stream_connected_cb(struct bt_bap_stream *bap_stream) { - while (true) { -#if defined(CONFIG_USB_DEVICE_AUDIO) - static int16_t right_frames[CONFIG_MAX_CODEC_FRAMES_PER_SDU] - [LC3_MAX_NUM_SAMPLES_MONO]; - static int16_t left_frames[CONFIG_MAX_CODEC_FRAMES_PER_SDU] - [LC3_MAX_NUM_SAMPLES_MONO]; - size_t right_frames_cnt = 0; - size_t left_frames_cnt = 0; - - memset(right_frames, 0, sizeof(right_frames)); - memset(left_frames, 0, sizeof(left_frames)); -#else - static int16_t lc3_audio_buf[LC3_MAX_NUM_SAMPLES_MONO]; -#endif /* CONFIG_USB_DEVICE_AUDIO */ - - k_sem_take(&lc3_decoder_sem, K_FOREVER); - - for (size_t i = 0; i < ARRAY_SIZE(streams); i++) { - struct broadcast_sink_stream *stream = &streams[i]; - const uint8_t frames_blocks_per_sdu = stream->lc3_frames_blocks_per_sdu; - const uint16_t octets_per_frame = stream->lc3_octets_per_frame; - uint16_t frames_per_block; - struct net_buf *buf; - - k_mutex_lock(&stream->lc3_decoder_mutex, K_FOREVER); - - if (stream->in_buf == NULL) { - k_mutex_unlock(&stream->lc3_decoder_mutex); - - continue; - } - - buf = net_buf_ref(stream->in_buf); - net_buf_unref(stream->in_buf); - stream->in_buf = NULL; - k_mutex_unlock(&stream->lc3_decoder_mutex); - - frames_per_block = bt_audio_get_chan_count(stream->chan_allocation); - if (buf->len != - (frames_per_block * octets_per_frame * frames_blocks_per_sdu)) { - printk("Expected %u frame blocks with %u frames of size %u, but " - "length is %u\n", - frames_blocks_per_sdu, frames_per_block, octets_per_frame, - buf->len); - - net_buf_unref(buf); - - continue; - } - -#if defined(CONFIG_USB_DEVICE_AUDIO) - const bool has_left = - (stream->chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0; - const bool has_right = - (stream->chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0; - const bool is_mono = - stream->chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO; - - /* Split the SDU into frames*/ - for (uint8_t i = 0U; i < frames_blocks_per_sdu; i++) { - for (uint16_t j = 0U; j < frames_per_block; j++) { - const bool is_left = j == 0 && has_left; - const bool is_right = - has_right && (j == 0 || (j == 1 && has_left)); - const void *data = net_buf_pull_mem(buf, octets_per_frame); - int16_t *out_frame; - - if (is_left) { - out_frame = left_frames[left_frames_cnt++]; - } else if (is_right) { - out_frame = right_frames[right_frames_cnt++]; - } else if (is_mono) { - /* Use left as mono*/ - out_frame = left_frames[left_frames_cnt++]; - } else { - /* unused channel */ - break; - } - - do_lc3_decode(stream->lc3_decoder, data, octets_per_frame, - out_frame); - } - } -#else - /* Dummy behavior: Decode and discard data */ - for (uint8_t i = 0U; i < frames_blocks_per_sdu; i++) { - for (uint16_t j = 0U; j < frames_per_block; j++) { - const void *data = net_buf_pull_mem(buf, octets_per_frame); - - do_lc3_decode(stream->lc3_decoder, data, octets_per_frame, - lc3_audio_buf); - } - } -#endif /* CONFIG_USB_DEVICE_AUDIO */ - - net_buf_unref(buf); - } - -#if defined(CONFIG_USB_DEVICE_AUDIO) - const bool is_left_only = right_frames_cnt == 0U; - const bool is_right_only = left_frames_cnt == 0U; - - if (!is_left_only && !is_right_only && left_frames_cnt != right_frames_cnt) { - printk("Mismatch between number of left (%zu) and right (%zu) frames, " - "discard SDU", - left_frames_cnt, right_frames_cnt); - continue; - } - - /* Send frames to USB - If we only have a single channel we mix it to stereo */ - for (size_t i = 0U; i < MAX(left_frames_cnt, right_frames_cnt); i++) { - const bool is_single_channel = is_left_only || is_right_only; - static int16_t stereo_frame[LC3_MAX_NUM_SAMPLES_STEREO]; - int16_t *right_frame = right_frames[i]; - int16_t *left_frame = left_frames[i]; - - /* Not enough space to store data */ - if (ring_buf_space_get(&usb_ring_buf) < sizeof(stereo_frame)) { - break; - } - - memset(stereo_frame, 0, sizeof(stereo_frame)); - - /* Generate the stereo frame - * - * If we only have single channel then that is always stored in the - * left_frame, and we mix that to stereo - */ - for (int j = 0; j < LC3_MAX_NUM_SAMPLES_MONO; j++) { - if (is_single_channel) { - /* Mix to stereo */ - if (is_left_only) { - stereo_frame[j * 2] = left_frame[j]; - stereo_frame[j * 2 + 1] = left_frame[j]; - } else if (is_right_only) { - stereo_frame[j * 2] = right_frame[j]; - stereo_frame[j * 2 + 1] = right_frame[j]; - } - } else { - stereo_frame[j * 2] = left_frame[j]; - stereo_frame[j * 2 + 1] = right_frame[j]; - } - } - - add_to_usb_ring_buf(stereo_frame); - } -#endif /* CONFIG_USB_DEVICE_AUDIO */ - } -} - -/** Decode LC3 data on a stream and returns true if successful */ -static void do_lc3_decode(lc3_decoder_t decoder, const void *in_data, uint8_t octets_per_frame, - int16_t out_data[LC3_MAX_NUM_SAMPLES_MONO]) -{ - int err; - - err = lc3_decode(decoder, in_data, octets_per_frame, LC3_PCM_FORMAT_S16, out_data, 1); - if (err == 1) { - printk(" decoder performed PLC\n"); - } else if (err < 0) { - printk(" decoder failed - wrong parameters? (err = %d)\n", err); - } -} - -static int lc3_enable(struct broadcast_sink_stream *sink_stream) -{ - size_t chan_alloc_bit_cnt; - size_t sdu_size_required; - int frame_duration_us; - int freq_hz; - int ret; - - printk("Enable: stream with codec %p\n", sink_stream->stream.codec_cfg); - - ret = bt_audio_codec_cfg_get_freq(sink_stream->stream.codec_cfg); - if (ret > 0) { - freq_hz = bt_audio_codec_cfg_freq_to_freq_hz(ret); - } else { - printk("Error: Codec frequency not set, cannot start codec."); - return -1; - } - - ret = bt_audio_codec_cfg_get_frame_dur(sink_stream->stream.codec_cfg); - if (ret > 0) { - frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret); - } else { - printk("Error: Frame duration not set, cannot start codec."); - return ret; - } - - ret = bt_audio_codec_cfg_get_chan_allocation(sink_stream->stream.codec_cfg, - &sink_stream->chan_allocation, true); - if (ret != 0) { - printk("Error: Channel allocation not set, invalid configuration for LC3"); - return ret; - } - - ret = bt_audio_codec_cfg_get_octets_per_frame(sink_stream->stream.codec_cfg); - if (ret > 0) { - sink_stream->lc3_octets_per_frame = (uint16_t)ret; - } else { - printk("Error: Octets per frame not set, invalid configuration for LC3"); - return ret; - } - - ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(sink_stream->stream.codec_cfg, true); - if (ret > 0) { - sink_stream->lc3_frames_blocks_per_sdu = (uint8_t)ret; - } else { - printk("Error: Frame blocks per SDU not set, invalid configuration for LC3"); - return ret; - } - - /* An SDU can consist of X frame blocks, each with Y frames (one per channel) of size Z in - * them. The minimum SDU size required for this is X * Y * Z. - */ - chan_alloc_bit_cnt = bt_audio_get_chan_count(sink_stream->chan_allocation); - sdu_size_required = chan_alloc_bit_cnt * sink_stream->lc3_octets_per_frame * - sink_stream->lc3_frames_blocks_per_sdu; - if (sdu_size_required > sink_stream->stream.qos->sdu) { - printk("With %zu channels and %u octets per frame and %u frames per block, SDUs " - "shall be at minimum %zu, but the stream has been configured for %u", - chan_alloc_bit_cnt, sink_stream->lc3_octets_per_frame, - sink_stream->lc3_frames_blocks_per_sdu, sdu_size_required, - sink_stream->stream.qos->sdu); - - return -EINVAL; - } - - printk("Enabling LC3 decoder with frame duration %uus, frequency %uHz and with channel " - "allocation 0x%08X, %u octets per frame and %u frame blocks per SDU\n", - frame_duration_us, freq_hz, sink_stream->chan_allocation, - sink_stream->lc3_octets_per_frame, sink_stream->lc3_frames_blocks_per_sdu); - -#if defined(CONFIG_USB_DEVICE_AUDIO) - sink_stream->lc3_decoder = lc3_setup_decoder(frame_duration_us, freq_hz, USB_SAMPLE_RATE, - &sink_stream->lc3_decoder_mem); -#else - sink_stream->lc3_decoder = lc3_setup_decoder(frame_duration_us, freq_hz, 0, - &sink_stream->lc3_decoder_mem); -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ - - if (sink_stream->lc3_decoder == NULL) { - printk("ERROR: Failed to setup LC3 decoder - wrong parameters?\n"); - return -1; - } - - k_thread_start(decoder_tid); - - return 0; -} -#endif /* defined(CONFIG_LIBLC3) */ - -#if defined(CONFIG_USB_DEVICE_AUDIO) -/* Move the LC3 data to the USB ring buffer */ -static void add_to_usb_ring_buf(const int16_t audio_buf[LC3_MAX_NUM_SAMPLES_STEREO]) -{ - uint32_t size; - - size = ring_buf_put(&usb_ring_buf, (uint8_t *)audio_buf, - LC3_MAX_NUM_SAMPLES_STEREO * sizeof(int16_t)); - if (size != LC3_MAX_NUM_SAMPLES_STEREO) { - static int rb_put_failures; - - rb_put_failures++; - if (rb_put_failures == LOG_INTERVAL) { - printk("%s: Failure to add to usb_ring_buf %d, %u\n", __func__, - rb_put_failures, size); - } - } -} - -/* USB consumer callback, called every 1ms, consumes data from ring-buffer */ -static void usb_data_request_cb(const struct device *dev) -{ - uint8_t usb_audio_data[USB_STEREO_SAMPLE_SIZE] = {0}; - static struct net_buf *pcm_buf; - static size_t cnt; - int err; - - ring_buf_get(&usb_ring_buf, (uint8_t *)usb_audio_data, sizeof(usb_audio_data)); - /* Ignore ring_buf_get() return value, if size is 0 we send empty PCM frames to - * not starve USB audio interface, if size is lower than USB_STEREO_SAMPLE_SIZE - * we send frames padded with 0's as usb_audio_data is 0-initialized - */ - - pcm_buf = net_buf_alloc(&usb_tx_buf_pool, K_NO_WAIT); - if (pcm_buf == NULL) { - printk("Could not allocate pcm_buf\n"); - return; - } - - net_buf_add_mem(pcm_buf, usb_audio_data, sizeof(usb_audio_data)); - - if (cnt % LOG_INTERVAL == 0) { - printk("Sending USB audio (count = %zu)\n", cnt); - } - - err = usb_audio_send(dev, pcm_buf, USB_STEREO_SAMPLE_SIZE); - if (err) { - printk("Failed to send USB audio: %d\n", err); - net_buf_unref(pcm_buf); - } - - cnt++; -} - -static void usb_data_written_cb(const struct device *dev, struct net_buf *buf, size_t size) -{ - /* Unreference the buffer now that the USB is done with it */ - net_buf_unref(buf); -} -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ - -static void stream_connected_cb(struct bt_bap_stream *stream) -{ - printk("Stream %p connected\n", stream); + printk("Stream %p connected\n", bap_stream); k_sem_give(&sem_stream_connected); } -static void stream_disconnected_cb(struct bt_bap_stream *stream, uint8_t reason) +static void stream_disconnected_cb(struct bt_bap_stream *bap_stream, uint8_t reason) { int err; - printk("Stream %p disconnected with reason 0x%02X\n", stream, reason); + printk("Stream %p disconnected with reason 0x%02X\n", bap_stream, reason); err = k_sem_take(&sem_stream_connected, K_NO_WAIT); if (err != 0) { @@ -506,96 +120,41 @@ static void stream_disconnected_cb(struct bt_bap_stream *stream, uint8_t reason) } } -static void stream_started_cb(struct bt_bap_stream *stream) +static void stream_started_cb(struct bt_bap_stream *bap_stream) { - struct broadcast_sink_stream *sink_stream = - CONTAINER_OF(stream, struct broadcast_sink_stream, stream); - - printk("Stream %p started\n", stream); - - total_rx_iso_packet_count = 0U; - sink_stream->recv_cnt = 0U; - sink_stream->loss_cnt = 0U; - sink_stream->valid_cnt = 0U; - sink_stream->error_cnt = 0U; - -#if defined(CONFIG_LIBLC3) int err; - if (stream->codec_cfg != 0 && stream->codec_cfg->id != BT_HCI_CODING_FORMAT_LC3) { - /* No subgroups with LC3 was found */ - printk("Did not parse an LC3 codec\n"); - return; - } + printk("Stream %p started\n", bap_stream); - err = lc3_enable(sink_stream); - if (err < 0) { - printk("Error: cannot enable LC3 codec: %d", err); - return; + err = stream_rx_started(bap_stream); + if (err != 0) { + printk("stream_rx_started returned error: %d\n", err); } -#endif /* CONFIG_LIBLC3 */ k_sem_give(&sem_stream_started); - if (k_sem_count_get(&sem_stream_started) == stream_count) { - big_synced = true; - printk("BIG synced\n"); - k_sem_give(&sem_big_synced); - } } -static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason) +static void stream_stopped_cb(struct bt_bap_stream *bap_stream, uint8_t reason) { int err; - printk("Stream %p stopped with reason 0x%02X\n", stream, reason); + printk("Stream %p stopped with reason 0x%02X\n", bap_stream, reason); - err = k_sem_take(&sem_stream_started, K_NO_WAIT); + err = stream_rx_stopped(bap_stream); if (err != 0) { - printk("Failed to take sem_stream_started: %d\n", err); + printk("stream_rx_stopped returned error: %d\n", err); } - if (k_sem_count_get(&sem_stream_started) != stream_count) { - printk("BIG sync terminated\n"); - big_synced = false; + err = k_sem_take(&sem_stream_started, K_NO_WAIT); + if (err != 0) { + printk("Failed to take sem_stream_started: %d\n", err); } } -static void stream_recv_cb(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, +static void stream_recv_cb(struct bt_bap_stream *bap_stream, const struct bt_iso_recv_info *info, struct net_buf *buf) { - struct broadcast_sink_stream *sink_stream = - CONTAINER_OF(stream, struct broadcast_sink_stream, stream); - - if (info->flags & BT_ISO_FLAGS_ERROR) { - sink_stream->error_cnt++; - } - - if (info->flags & BT_ISO_FLAGS_LOST) { - sink_stream->loss_cnt++; - } - - if (info->flags & BT_ISO_FLAGS_VALID) { - sink_stream->valid_cnt++; -#if defined(CONFIG_LIBLC3) - k_mutex_lock(&sink_stream->lc3_decoder_mutex, K_FOREVER); - if (sink_stream->in_buf != NULL) { - net_buf_unref(sink_stream->in_buf); - sink_stream->in_buf = NULL; - } - - sink_stream->in_buf = net_buf_ref(buf); - k_mutex_unlock(&sink_stream->lc3_decoder_mutex); - k_sem_give(&lc3_decoder_sem); -#endif /* defined(CONFIG_LIBLC3) */ - } - - total_rx_iso_packet_count++; - sink_stream->recv_cnt++; - if ((sink_stream->recv_cnt % LOG_INTERVAL) == 0U) { - printk("Stream %p: received %u total ISO packets: Valid %u | Error %u | Loss %u\n", - &sink_stream->stream, sink_stream->recv_cnt, sink_stream->valid_cnt, - sink_stream->error_cnt, sink_stream->loss_cnt); - } + stream_rx_recv(bap_stream, info, buf); } static struct bt_bap_stream_ops stream_ops = { @@ -818,9 +377,27 @@ static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_ } } +static void broadcast_sink_started_cb(struct bt_bap_broadcast_sink *sink) +{ + printk("Broadcast sink %p started\n", sink); + + big_synced = true; + k_sem_give(&sem_big_synced); +} + +static void broadcast_sink_stopped_cb(struct bt_bap_broadcast_sink *sink, uint8_t reason) +{ + printk("Broadcast sink %p stopped with reason 0x%02X\n", sink, reason); + + big_synced = false; + k_sem_give(&sem_broadcast_sink_stopped); +} + static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = { .base_recv = base_recv_cb, .syncable = syncable_cb, + .started = broadcast_sink_started_cb, + .stopped = broadcast_sink_stopped_cb, }; static void pa_timer_handler(struct k_work *work) @@ -1027,8 +604,6 @@ static int bis_sync_req_cb(struct bt_conn *conn, return err; } - - k_sem_give(&sem_broadcast_sink_stopped); } broadcaster_broadcast_id = recv_state->broadcast_id; @@ -1242,7 +817,7 @@ static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync, if (info->reason != BT_HCI_ERR_LOCALHOST_TERM_CONN && req_recv_state != NULL) { int err; - if (k_sem_count_get(&sem_stream_connected) > 0) { + if (big_synced) { err = bt_bap_broadcast_sink_stop(broadcast_sink); if (err != 0) { printk("Failed to stop Broadcast Sink: %d\n", err); @@ -1257,8 +832,6 @@ static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync, return; } - - k_sem_give(&sem_broadcast_sink_stopped); } } } @@ -1268,8 +841,13 @@ static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = { .term = bap_pa_sync_terminated_cb, }; + static int init(void) { + const struct bt_pacs_register_param pacs_param = { + .snk_pac = true, + .snk_loc = true, + }; int err; err = bt_enable(NULL); @@ -1280,6 +858,12 @@ static int init(void) printk("Bluetooth initialized\n"); + err = bt_pacs_register(&pacs_param); + if (err) { + printk("Could not register PACS (err %d)\n", err); + return err; + } + err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap); if (err) { printk("Capability register failed (err %d)\n", err); @@ -1296,30 +880,19 @@ static int init(void) bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb); bt_le_scan_cb_register(&bap_scan_cb); - for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { - streams[i].stream.ops = &stream_ops; - } + stream_rx_get_streams(bap_streams_p); - /* Initialize ring buffers and USB */ -#if defined(CONFIG_USB_DEVICE_AUDIO) - const struct device *hs_dev = DEVICE_DT_GET(DT_NODELABEL(hs_0)); - static const struct usb_audio_ops usb_ops = { - .data_request_cb = usb_data_request_cb, - .data_written_cb = usb_data_written_cb, - }; + for (size_t i = 0U; i < CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT; i++) { + bt_bap_stream_cb_register(bap_streams_p[i], &stream_ops); + } - if (!device_is_ready(hs_dev)) { - printk("Cannot get USB Headset Device\n"); - return -EIO; + if (IS_ENABLED(CONFIG_LIBLC3)) { + lc3_init(); } - usb_audio_register(hs_dev, &usb_ops); - err = usb_enable(NULL); - if (err && err != -EALREADY) { - printk("Failed to enable USB\n"); - return err; + if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) { + usb_init(); } -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ return 0; } @@ -1461,13 +1034,6 @@ int main(void) return 0; } - for (size_t i = 0U; i < ARRAY_SIZE(streams_p); i++) { - streams_p[i] = &streams[i].stream; -#if defined(CONFIG_LIBLC3) - k_mutex_init(&streams[i].lc3_decoder_mutex); -#endif /* defined(CONFIG_LIBLC3) */ - } - while (true) { uint32_t sync_bitfield; @@ -1630,7 +1196,7 @@ int main(void) "(req_bis_sync), stream_count = %u\n", sync_bitfield, bis_index_bitfield, requested_bis_sync, stream_count); - err = bt_bap_broadcast_sink_sync(broadcast_sink, sync_bitfield, streams_p, + err = bt_bap_broadcast_sink_sync(broadcast_sink, sync_bitfield, bap_streams_p, sink_broadcast_code); if (err != 0) { printk("Unable to sync to broadcast source: %d\n", err); diff --git a/samples/bluetooth/bap_broadcast_sink/src/stream_rx.c b/samples/bluetooth/bap_broadcast_sink/src/stream_rx.c new file mode 100644 index 0000000000000..1caaec5361c2e --- /dev/null +++ b/samples/bluetooth/bap_broadcast_sink/src/stream_rx.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_LIBLC3) +#include +#endif /* defined(CONFIG_LIBLC3) */ + +#include "stream_rx.h" +#include "lc3.h" + +struct stream_rx rx_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; +uint64_t total_rx_iso_packet_count; /* This value is exposed to test code */ + +LOG_MODULE_REGISTER(stream_rx, CONFIG_LOG_DEFAULT_LEVEL); + +#if CONFIG_INFO_REPORTING_INTERVAL > 0 +static void log_stream_rx(const struct stream_rx *stream, const struct bt_iso_recv_info *info, + const struct net_buf *buf) +{ + LOG_INF("[%zu]: Incoming audio on stream %p len %u, flags 0x%02X, seq_num %u and ts %u: " + "Valid %zu | Error %zu | Loss %zu | Dup TS %zu | Dup PSN %zu", + stream->reporting_info.recv_cnt, &stream->stream, buf->len, info->flags, + info->seq_num, info->ts, stream->reporting_info.valid_cnt, + stream->reporting_info.error_cnt, stream->reporting_info.loss_cnt, + stream->reporting_info.dup_ts_cnt, stream->reporting_info.dup_psn_cnt); +} +#endif /* CONFIG_INFO_REPORTING_INTERVAL > 0 */ + +void stream_rx_recv(struct bt_bap_stream *bap_stream, const struct bt_iso_recv_info *info, + struct net_buf *buf) +{ + struct stream_rx *stream = CONTAINER_OF(bap_stream, struct stream_rx, stream); + +#if CONFIG_INFO_REPORTING_INTERVAL > 0 + if ((stream->reporting_info.recv_cnt % CONFIG_INFO_REPORTING_INTERVAL) == 0U) { + log_stream_rx(stream, info, buf); + } + + if (stream->reporting_info.recv_cnt > 0U && info->ts == stream->reporting_info.last_ts) { + log_stream_rx(stream, info, buf); + LOG_WRN("Duplicated timestamp received: %u\n", stream->reporting_info.last_ts); + stream->reporting_info.dup_ts_cnt++; + } + + if (stream->reporting_info.recv_cnt > 0U && + info->seq_num == stream->reporting_info.last_seq_num) { + log_stream_rx(stream, info, buf); + LOG_WRN("Duplicated PSN received: %u\n", stream->reporting_info.last_seq_num); + stream->reporting_info.dup_psn_cnt++; + } + + if (info->flags & BT_ISO_FLAGS_ERROR) { + log_stream_rx(stream, info, buf); + LOG_DBG("ISO receive error\n"); + stream->reporting_info.error_cnt++; + } + + if (info->flags & BT_ISO_FLAGS_LOST) { + log_stream_rx(stream, info, buf); + LOG_DBG("ISO receive lost\n"); + stream->reporting_info.loss_cnt++; + } + + if (info->flags & BT_ISO_FLAGS_VALID) { + if (buf->len == 0U) { + stream->reporting_info.empty_sdu_cnt++; + } else { + stream->reporting_info.valid_cnt++; + } + } + + stream->reporting_info.last_seq_num = info->seq_num; + stream->reporting_info.last_ts = info->ts; + stream->reporting_info.recv_cnt++; +#endif /* CONFIG_INFO_REPORTING_INTERVAL > 0 */ + + total_rx_iso_packet_count++; + + if (IS_ENABLED(CONFIG_LIBLC3)) { + /* Invalid SDUs will trigger PLC */ + lc3_enqueue_for_decoding(stream, info, buf); + } +} + +int stream_rx_started(struct bt_bap_stream *bap_stream) +{ + struct stream_rx *stream = CONTAINER_OF(bap_stream, struct stream_rx, stream); + + if (stream == NULL) { + return -EINVAL; + } + +#if CONFIG_INFO_REPORTING_INTERVAL > 0 + memset(&stream->reporting_info, 0, sizeof((stream->reporting_info))); +#endif /* CONFIG_INFO_REPORTING_INTERVAL > 0 */ + + if (IS_ENABLED(CONFIG_LIBLC3) && bap_stream->codec_cfg != NULL && + bap_stream->codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { + int err; + + err = lc3_enable(stream); + if (err < 0) { + LOG_ERR("Error: cannot enable LC3 codec: %d", err); + return err; + } + } + + return 0; +} + +int stream_rx_stopped(struct bt_bap_stream *bap_stream) +{ + struct stream_rx *stream = CONTAINER_OF(bap_stream, struct stream_rx, stream); + + if (bap_stream == NULL) { + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_LIBLC3) && bap_stream->codec_cfg != NULL && + bap_stream->codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { + int err; + + err = lc3_disable(stream); + if (err < 0) { + LOG_ERR("Error: cannot disable LC3 codec: %d", err); + return err; + } + } + + return 0; +} + +void stream_rx_get_streams( + struct bt_bap_stream *bap_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]) +{ + for (size_t i = 0U; i < ARRAY_SIZE(rx_streams); i++) { + bap_streams[i] = &rx_streams[i].stream; + } +} diff --git a/samples/bluetooth/bap_broadcast_sink/src/stream_rx.h b/samples/bluetooth/bap_broadcast_sink/src/stream_rx.h new file mode 100644 index 0000000000000..b2afc64349237 --- /dev/null +++ b/samples/bluetooth/bap_broadcast_sink/src/stream_rx.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef SAMPLE_BAP_BROADCAST_SINK_STREAM_RX_H +#define SAMPLE_BAP_BROADCAST_SINK_STREAM_RX_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_LIBLC3) +#include +#endif /* defined(CONFIG_LIBLC3) */ + +struct stream_rx { + /* A BAP stream object */ + struct bt_bap_stream stream; +#if CONFIG_INFO_REPORTING_INTERVAL > 0 + /** Struct containing information useful for logging purposes */ + struct { + /** Total Number of SDUs received */ + size_t recv_cnt; + /** Number of lost SDUs */ + size_t loss_cnt; + /** Number of SDUs containing errors */ + size_t error_cnt; + /** Number of valid SDUs received */ + size_t valid_cnt; + /** Number of empty SDUs received */ + size_t empty_sdu_cnt; + /** Number of SDUs with duplicated packet sequence number received */ + size_t dup_psn_cnt; + /** Number of SDUs with duplicated timestamps received */ + size_t dup_ts_cnt; + /** The last received timestamp to track dup_ts_cnt */ + uint32_t last_ts; + /** The last received sequence number to track dup_psn_cnt */ + uint16_t last_seq_num; +#if CONFIG_LIBLC3 > 0 + /** Number of SDUs decoded */ + size_t lc3_decoded_cnt; +#endif /* CONFIG_LIBLC3 > 0 */ + } reporting_info; +#endif /* CONFIG_INFO_REPORTING_INTERVAL > 0 */ + +#if defined(CONFIG_LIBLC3) + /** Octets per frame - Used to validate that the incoming data is of correct size */ + uint16_t lc3_octets_per_frame; + /** Frame blocks per SDU - Used to split the SDU into frame blocks when decoding */ + uint8_t lc3_frame_blocks_per_sdu; + + /** Number of channels - Used to split the SDU into frame blocks when decoding */ + uint8_t lc3_chan_cnt; + + /** + * @brief The configured channels of the stream + * + * Used to determine whether to send data to USB and count number of channels + */ + enum bt_audio_location lc3_chan_allocation; + + /** Memory use for the LC3 decoder - Supports any configuration */ + lc3_decoder_mem_48k_t lc3_decoder_mem; + /** Reference to the LC3 decoder */ + lc3_decoder_t lc3_decoder; +#endif /* defined(CONFIG_LIBLC3) */ +}; + +/** + * @brief Function to call for each SDU received + * + * Will decode with LC3 and send to USB if enabled + */ +void stream_rx_recv(struct bt_bap_stream *bap_stream, const struct bt_iso_recv_info *info, + struct net_buf *buf); + +size_t stream_rx_get_streaming_cnt(void); +int stream_rx_started(struct bt_bap_stream *bap_stream); +int stream_rx_stopped(struct bt_bap_stream *bap_stream); +void stream_rx_get_streams( + struct bt_bap_stream *bap_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]); + +#endif /* SAMPLE_BAP_BROADCAST_SINK_STREAM_RX_H */ diff --git a/samples/bluetooth/bap_broadcast_sink/src/usb.c b/samples/bluetooth/bap_broadcast_sink/src/usb.c new file mode 100644 index 0000000000000..dbe5ec16a62b1 --- /dev/null +++ b/samples/bluetooth/bap_broadcast_sink/src/usb.c @@ -0,0 +1,350 @@ +/** + * @file + * @brief Bluetooth BAP Broadcast Sink Sample LC3 + * + * This files handles all the USB related functionality to audio out for the Sample + * + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lc3.h" +#include "stream_rx.h" +#include "usb.h" + +LOG_MODULE_REGISTER(usb, CONFIG_LOG_DEFAULT_LEVEL); + +#define USB_ENQUEUE_COUNT 30U /* 30 times 1ms frames => 30ms */ +#define USB_FRAME_DURATION_US 1000U +#define USB_SAMPLE_CNT ((USB_FRAME_DURATION_US * USB_SAMPLE_RATE_HZ) / USEC_PER_SEC) +#define USB_BYTES_PER_SAMPLE sizeof(int16_t) +#define USB_MONO_FRAME_SIZE (USB_SAMPLE_CNT * USB_BYTES_PER_SAMPLE) +#define USB_CHANNELS 2U +#define USB_STEREO_FRAME_SIZE (USB_MONO_FRAME_SIZE * USB_CHANNELS) +#define USB_OUT_RING_BUF_SIZE (CONFIG_BT_ISO_RX_BUF_COUNT * LC3_MAX_NUM_SAMPLES_STEREO) +#define USB_IN_RING_BUF_SIZE (USB_MONO_FRAME_SIZE * USB_ENQUEUE_COUNT) + +struct decoded_sdu { + int16_t right_frames[CONFIG_MAX_CODEC_FRAMES_PER_SDU][LC3_MAX_NUM_SAMPLES_MONO]; + int16_t left_frames[CONFIG_MAX_CODEC_FRAMES_PER_SDU][LC3_MAX_NUM_SAMPLES_MONO]; + size_t right_frames_cnt; + size_t left_frames_cnt; + size_t mono_frames_cnt; + uint32_t ts; +} decoded_sdu; + +RING_BUF_DECLARE(usb_out_ring_buf, USB_OUT_RING_BUF_SIZE); +NET_BUF_POOL_DEFINE(usb_out_buf_pool, USB_ENQUEUE_COUNT, USB_STEREO_FRAME_SIZE, 0, net_buf_destroy); + +/* USB consumer callback, called every 1ms, consumes data from ring-buffer */ +static void usb_data_request_cb(const struct device *dev) +{ + uint8_t usb_audio_data[USB_STEREO_FRAME_SIZE] = {0}; + struct net_buf *pcm_buf; + uint32_t size; + int err; + + if (lc3_get_rx_streaming_cnt() == 0) { + /* no-op as we have no streams that receive data */ + return; + } + + pcm_buf = net_buf_alloc(&usb_out_buf_pool, K_NO_WAIT); + if (pcm_buf == NULL) { + LOG_WRN("Could not allocate pcm_buf"); + return; + } + + /* This may fail without causing issues since usb_audio_data is 0-initialized */ + size = ring_buf_get(&usb_out_ring_buf, usb_audio_data, sizeof(usb_audio_data)); + + net_buf_add_mem(pcm_buf, usb_audio_data, sizeof(usb_audio_data)); + + if (size != 0) { + static size_t cnt; + + if (CONFIG_INFO_REPORTING_INTERVAL > 0 && + (++cnt % (CONFIG_INFO_REPORTING_INTERVAL * 10)) == 0U) { + LOG_INF("[%zu]: Sending USB audio", cnt); + } + } else { + static size_t cnt; + + if (CONFIG_INFO_REPORTING_INTERVAL > 0 && + (++cnt % (CONFIG_INFO_REPORTING_INTERVAL * 10)) == 0U) { + LOG_INF("[%zu]: Sending empty USB audio", cnt); + } + } + + err = usb_audio_send(dev, pcm_buf, sizeof(usb_audio_data)); + if (err != 0) { + static size_t cnt; + + cnt++; + if (CONFIG_INFO_REPORTING_INTERVAL > 0 && + (cnt % (CONFIG_INFO_REPORTING_INTERVAL * 10)) == 0) { + LOG_ERR("Failed to send USB audio: %d (%zu)", err, cnt); + } + + net_buf_unref(pcm_buf); + } +} + +static void usb_data_written_cb(const struct device *dev, struct net_buf *buf, size_t size) +{ + /* Unreference the buffer now that the USB is done with it */ + net_buf_unref(buf); +} + +static void usb_send_frames_to_usb(void) +{ + const bool is_left_only = + decoded_sdu.right_frames_cnt == 0U && decoded_sdu.mono_frames_cnt == 0U; + const bool is_right_only = + decoded_sdu.left_frames_cnt == 0U && decoded_sdu.mono_frames_cnt == 0U; + const bool is_mono_only = + decoded_sdu.left_frames_cnt == 0U && decoded_sdu.right_frames_cnt == 0U; + const bool is_single_channel = is_left_only || is_right_only || is_mono_only; + const size_t frame_cnt = + MAX(decoded_sdu.mono_frames_cnt, + MAX(decoded_sdu.left_frames_cnt, decoded_sdu.right_frames_cnt)); + static size_t cnt; + + /* Send frames to USB - If we only have a single channel we mix it to stereo */ + for (size_t i = 0U; i < frame_cnt; i++) { + static int16_t stereo_frame[LC3_MAX_NUM_SAMPLES_STEREO]; + const int16_t *right_frame = decoded_sdu.right_frames[i]; + const int16_t *left_frame = decoded_sdu.left_frames[i]; + const int16_t *mono_frame = decoded_sdu.left_frames[i]; /* use left as mono */ + static size_t fail_cnt; + uint32_t rb_size; + + /* Not enough space to store data */ + if (ring_buf_space_get(&usb_out_ring_buf) < sizeof(stereo_frame)) { + if (CONFIG_INFO_REPORTING_INTERVAL > 0 && + (fail_cnt % CONFIG_INFO_REPORTING_INTERVAL) == 0U) { + LOG_WRN("[%zu] Could not send more than %zu frames to USB", + fail_cnt, i); + } + + fail_cnt++; + + break; + } + + fail_cnt = 0U; + + /* Generate the stereo frame + * + * If we only have single channel then we mix that to stereo + */ + for (int j = 0; j < LC3_MAX_NUM_SAMPLES_MONO; j++) { + if (is_single_channel) { + int16_t sample = 0; + + /* Mix to stereo as LRLRLRLR */ + if (is_left_only) { + sample = left_frame[j]; + } else if (is_right_only) { + sample = right_frame[j]; + } else if (is_mono_only) { + sample = mono_frame[j]; + } + + stereo_frame[j * 2] = sample; + stereo_frame[j * 2 + 1] = sample; + } else { + stereo_frame[j * 2] = left_frame[j]; + stereo_frame[j * 2 + 1] = right_frame[j]; + } + } + + rb_size = ring_buf_put(&usb_out_ring_buf, (uint8_t *)stereo_frame, + sizeof(stereo_frame)); + if (rb_size != sizeof(stereo_frame)) { + LOG_WRN("Failed to put frame on USB ring buf"); + + break; + } + } + + if (CONFIG_INFO_REPORTING_INTERVAL > 0 && (++cnt % CONFIG_INFO_REPORTING_INTERVAL) == 0U) { + LOG_INF("[%zu]: Sending %u USB audio frame", cnt, frame_cnt); + } + + usb_clear_frames_to_usb(); +} + +static bool ts_overflowed(uint32_t ts) +{ + /* If the timestamp is a factor of 10 in difference, then we assume that TS overflowed + * We cannot simply check if `ts < decoded_sdu.ts` as that could also indicate old data + */ + return ((uint64_t)ts * 10 < decoded_sdu.ts); +} + +int usb_add_frame_to_usb(enum bt_audio_location chan_allocation, const int16_t *frame, + size_t frame_size, uint32_t ts) +{ + const bool is_left = (chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0; + const bool is_right = (chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0; + const bool is_mono = chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO; + const uint8_t ts_jitter_us = 100; /* timestamps may have jitter */ + static size_t cnt; + + if (CONFIG_INFO_REPORTING_INTERVAL > 0 && (++cnt % CONFIG_INFO_REPORTING_INTERVAL) == 0U) { + LOG_INF("[%zu]: Adding USB audio frame", cnt); + } + + if (frame_size > LC3_MAX_NUM_SAMPLES_MONO * sizeof(int16_t) || frame_size == 0U) { + LOG_DBG("Invalid frame of size %zu", frame_size); + + return -EINVAL; + } + + if (bt_audio_get_chan_count(chan_allocation) != 1) { + LOG_DBG("Invalid channel allocation %d", chan_allocation); + + return -EINVAL; + } + + if (((is_left || is_right) && decoded_sdu.mono_frames_cnt != 0) || + (is_mono && + (decoded_sdu.left_frames_cnt != 0U || decoded_sdu.right_frames_cnt != 0U))) { + LOG_DBG("Cannot mix and match mono with left or right"); + + return -EINVAL; + } + + /* Check if the frame can be combined with a previous frame from another channel, of if + * we have to send previous data to USB and then store the current frame + * + * This is done by comparing the timestamps of the frames, and in the case that they are the + * same, there are additional checks to see if we have received more left than right frames, + * in which case we also send existing data + */ + + if (ts + ts_jitter_us < decoded_sdu.ts && !ts_overflowed(ts)) { + /* Old data, discard */ + return -ENOEXEC; + } else if (ts > decoded_sdu.ts + ts_jitter_us || ts_overflowed(ts)) { + /* We are getting new data - Send existing data to ring buffer */ + usb_send_frames_to_usb(); + } else { /* same timestamp */ + bool send = false; + + if (is_left && decoded_sdu.left_frames_cnt > decoded_sdu.right_frames_cnt) { + /* We are receiving left again before a right, send to USB */ + send = true; + } else if (is_right && decoded_sdu.right_frames_cnt > decoded_sdu.left_frames_cnt) { + /* We are receiving right again before a left, send to USB */ + send = true; + } else if (is_mono) { + /* always send mono as it comes */ + send = true; + } + + if (send) { + usb_send_frames_to_usb(); + } + } + + if (is_left) { + if (decoded_sdu.left_frames_cnt >= ARRAY_SIZE(decoded_sdu.left_frames)) { + LOG_WRN("Could not add more left frames"); + + return -ENOMEM; + } + + memcpy(decoded_sdu.left_frames[decoded_sdu.left_frames_cnt++], frame, frame_size); + } else if (is_right) { + if (decoded_sdu.right_frames_cnt >= ARRAY_SIZE(decoded_sdu.right_frames)) { + LOG_WRN("Could not add more right frames"); + + return -ENOMEM; + } + + memcpy(decoded_sdu.right_frames[decoded_sdu.right_frames_cnt++], frame, frame_size); + } else if (is_mono) { + /* Use left as mono*/ + if (decoded_sdu.mono_frames_cnt >= ARRAY_SIZE(decoded_sdu.left_frames)) { + LOG_WRN("Could not add more mono frames"); + + return -ENOMEM; + } + + memcpy(decoded_sdu.left_frames[decoded_sdu.mono_frames_cnt++], frame, frame_size); + } else { + /* Unsupported channel */ + LOG_DBG("Unsupported channel %d", chan_allocation); + + return -EINVAL; + } + + decoded_sdu.ts = ts; + + return 0; +} + +void usb_clear_frames_to_usb(void) +{ + decoded_sdu.mono_frames_cnt = 0U; + decoded_sdu.right_frames_cnt = 0U; + decoded_sdu.left_frames_cnt = 0U; + decoded_sdu.ts = 0U; +} + +int usb_init(void) +{ + const struct device *hs_dev = DEVICE_DT_GET(DT_NODELABEL(hs_0)); + static const struct usb_audio_ops usb_ops = { + .data_request_cb = usb_data_request_cb, + .data_written_cb = usb_data_written_cb, + }; + static bool initialized; + int err; + + if (initialized) { + return -EALREADY; + } + + if (!device_is_ready(hs_dev)) { + LOG_ERR("Cannot get USB Headset Device"); + return -EIO; + } + + usb_audio_register(hs_dev, &usb_ops); + err = usb_enable(NULL); + if (err != 0) { + LOG_ERR("Failed to enable USB"); + return err; + } + + LOG_INF("USB initialized"); + initialized = true; + + return 0; +} diff --git a/samples/bluetooth/bap_broadcast_sink/src/usb.h b/samples/bluetooth/bap_broadcast_sink/src/usb.h new file mode 100644 index 0000000000000..e05a997c2516a --- /dev/null +++ b/samples/bluetooth/bap_broadcast_sink/src/usb.h @@ -0,0 +1,71 @@ +/** + * @file + * @brief Bluetooth BAP Broadcast Sink sample USB header + * + * This files handles all the USB related functionality for the sample + * + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SAMPLE_BAP_BROADCAST_SINK_USB_H +#define SAMPLE_BAP_BROADCAST_SINK_USB_H +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USB_SAMPLE_RATE_HZ 48000U + +/** + * @brief Add decoded frame to the USB buffer + * + * @param chan_allocation The channel of the frame (@ref BT_AUDIO_LOCATION_FRONT_LEFT, @ref + * BT_AUDIO_LOCATION_FRONT_RIGHT or @ref BT_AUDIO_LOCATION_MONO_AUDIO) + * @param frame The frame + * @param frame_size The size of @p in octets + * @param ts The timestamp of the frame + * + * @retval 0 Success + * @retval -EINVAL Invalid channel, frame of framesize + * @retval -ENOEXEC Old timestamp, discarded + * @retval -ENOMEM No memory to enqueue + */ +int usb_add_frame_to_usb(enum bt_audio_location chan_allocation, const int16_t *frame, + size_t frame_size, uint32_t ts); + +/** + * @brief Clear last sent SDU + * + * If only part of the SDU could be decoded, this should be called + */ +void usb_clear_frames_to_usb(void); + +/** + * @brief Initialize the USB module + * + * This will start the USB thread if not already initialized + * + * @retval 0 Success + * @retval -EALREADY Already initialized + */ +int usb_init(void); + +#endif /* SAMPLE_BAP_BROADCAST_SINK_USB_H */ diff --git a/samples/bluetooth/bap_broadcast_source/CMakeLists.txt b/samples/bluetooth/bap_broadcast_source/CMakeLists.txt index 66649d87a33c8..dc0187ae9270d 100644 --- a/samples/bluetooth/bap_broadcast_source/CMakeLists.txt +++ b/samples/bluetooth/bap_broadcast_source/CMakeLists.txt @@ -8,4 +8,6 @@ target_sources(app PRIVATE src/main.c ) -zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) +if (CONFIG_USE_USB_AUDIO_INPUT) + include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) +endif() diff --git a/samples/bluetooth/bap_broadcast_source/Kconfig b/samples/bluetooth/bap_broadcast_source/Kconfig index 97ec40502f931..a765abcf3d4d9 100644 --- a/samples/bluetooth/bap_broadcast_source/Kconfig +++ b/samples/bluetooth/bap_broadcast_source/Kconfig @@ -34,8 +34,8 @@ config USE_USB_AUDIO_INPUT # By default, use the USB Audio path is disabled. default n depends on ENABLE_LC3 - select USB_DEVICE_STACK - select USB_DEVICE_AUDIO + select USB_DEVICE_STACK_NEXT + select USBD_AUDIO2_CLASS select RING_BUFFER config BROADCAST_CODE @@ -59,4 +59,9 @@ config BROADCAST_ID help This is the 3-octet broadcast ID advertised if static broadcast IDs are enabled. +# Source common USB sample options used to initialize new experimental USB device stack. +# The scope of these options is limited to USB samples in project tree, +# you cannot use them in your own application. +source "samples/subsys/usb/common/Kconfig.sample_usbd" + source "Kconfig.zephyr" diff --git a/samples/bluetooth/bap_broadcast_source/app.overlay b/samples/bluetooth/bap_broadcast_source/app.overlay new file mode 100644 index 0000000000000..2293f07f82113 --- /dev/null +++ b/samples/bluetooth/bap_broadcast_source/app.overlay @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + uac2_broadcaster: usb_audio2 { + compatible = "zephyr,uac2"; + status = "okay"; + full-speed; + audio-function = ; + + /* Clock supporting 48KHz + * + * For simplicity we claim support for 48KHz only and then downsample if needed + */ + uac_aclk: aclk { + compatible = "zephyr,uac2-clock-source"; + clock-type = "internal-programmable"; + frequency-control = "read-only"; + sampling-frequencies = <48000>; + /* Falsely claim synchronous audio because we + * currently don't calculate feedback value + */ + sof-synchronized; + }; + + /* USB Audio terminal from USB host to USB device */ + out_terminal: out_terminal { + compatible = "zephyr,uac2-input-terminal"; + clock-source = <&uac_aclk>; + terminal-type = ; + front-left; + front-right; + }; + + /* The broadcaster_output terminal defines what we are sending over Bluetooth */ + broadcaster_output: headphones { + compatible = "zephyr,uac2-output-terminal"; + data-source = <&out_terminal>; + clock-source = <&uac_aclk>; + terminal-type = ; + }; + + as_iso_out: out_interface { + compatible = "zephyr,uac2-audio-streaming"; + linked-terminal = <&out_terminal>; + subslot-size = <2>; + bit-resolution = <16>; + }; + }; +}; diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf52833dk_nrf52833.conf b/samples/bluetooth/bap_broadcast_source/boards/nrf52833dk_nrf52833.conf index 8b65fa9a9d857..54c9145ae9f99 100644 --- a/samples/bluetooth/bap_broadcast_source/boards/nrf52833dk_nrf52833.conf +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf52833dk_nrf52833.conf @@ -1,3 +1,3 @@ # Use USB Audio as audio source CONFIG_USE_USB_AUDIO_INPUT=y -CONFIG_USB_DEVICE_PRODUCT="Zephyr Broadcast Source" +CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Source sample" diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf52833dk_nrf52833.overlay b/samples/bluetooth/bap_broadcast_source/boards/nrf52833dk_nrf52833.overlay index b8e72f1b61c5b..94b67c37c7050 100644 --- a/samples/bluetooth/bap_broadcast_source/boards/nrf52833dk_nrf52833.overlay +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf52833dk_nrf52833.overlay @@ -1,15 +1,7 @@ -zephyr_udc0: &usbd { - compatible = "nordic,nrf-usbd"; - status = "okay"; +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ - hs_0: hs_0 { - compatible = "usb-audio-hs"; - mic-feature-mute; - mic-channel-l; - mic-channel-r; - - hp-feature-mute; - hp-channel-l; - hp-channel-r; - }; -}; +#include "../app.overlay" diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf52840dk_nrf52840.conf b/samples/bluetooth/bap_broadcast_source/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 0000000000000..54c9145ae9f99 --- /dev/null +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,3 @@ +# Use USB Audio as audio source +CONFIG_USE_USB_AUDIO_INPUT=y +CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Source sample" diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf52840dk_nrf52840.overlay b/samples/bluetooth/bap_broadcast_source/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 0000000000000..94b67c37c7050 --- /dev/null +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../app.overlay" diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf52840dongle_nrf52840.conf b/samples/bluetooth/bap_broadcast_source/boards/nrf52840dongle_nrf52840.conf index 8b65fa9a9d857..39522210d288f 100644 --- a/samples/bluetooth/bap_broadcast_source/boards/nrf52840dongle_nrf52840.conf +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf52840dongle_nrf52840.conf @@ -1,3 +1,5 @@ # Use USB Audio as audio source CONFIG_USE_USB_AUDIO_INPUT=y -CONFIG_USB_DEVICE_PRODUCT="Zephyr Broadcast Source" +CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Source sample" + +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf52840dongle_nrf52840.overlay b/samples/bluetooth/bap_broadcast_source/boards/nrf52840dongle_nrf52840.overlay index b8e72f1b61c5b..94b67c37c7050 100644 --- a/samples/bluetooth/bap_broadcast_source/boards/nrf52840dongle_nrf52840.overlay +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf52840dongle_nrf52840.overlay @@ -1,15 +1,7 @@ -zephyr_udc0: &usbd { - compatible = "nordic,nrf-usbd"; - status = "okay"; +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ - hs_0: hs_0 { - compatible = "usb-audio-hs"; - mic-feature-mute; - mic-channel-l; - mic-channel-r; - - hp-feature-mute; - hp-channel-l; - hp-channel-r; - }; -}; +#include "../app.overlay" diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/bap_broadcast_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index 8b65fa9a9d857..54c9145ae9f99 100644 --- a/samples/bluetooth/bap_broadcast_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -1,3 +1,3 @@ # Use USB Audio as audio source CONFIG_USE_USB_AUDIO_INPUT=y -CONFIG_USB_DEVICE_PRODUCT="Zephyr Broadcast Source" +CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Source sample" diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.overlay b/samples/bluetooth/bap_broadcast_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.overlay new file mode 100644 index 0000000000000..94b67c37c7050 --- /dev/null +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf5340_audio_dk_nrf5340_cpuapp.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../app.overlay" diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/bap_broadcast_source/boards/nrf5340dk_nrf5340_cpuapp.conf index 8b65fa9a9d857..54c9145ae9f99 100644 --- a/samples/bluetooth/bap_broadcast_source/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -1,3 +1,3 @@ # Use USB Audio as audio source CONFIG_USE_USB_AUDIO_INPUT=y -CONFIG_USB_DEVICE_PRODUCT="Zephyr Broadcast Source" +CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Source sample" diff --git a/samples/bluetooth/bap_broadcast_source/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/bluetooth/bap_broadcast_source/boards/nrf5340dk_nrf5340_cpuapp.overlay index b8e72f1b61c5b..94b67c37c7050 100644 --- a/samples/bluetooth/bap_broadcast_source/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/samples/bluetooth/bap_broadcast_source/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -1,15 +1,7 @@ -zephyr_udc0: &usbd { - compatible = "nordic,nrf-usbd"; - status = "okay"; +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ - hs_0: hs_0 { - compatible = "usb-audio-hs"; - mic-feature-mute; - mic-channel-l; - mic-channel-r; - - hp-feature-mute; - hp-channel-l; - hp-channel-r; - }; -}; +#include "../app.overlay" diff --git a/samples/bluetooth/bap_broadcast_source/src/main.c b/samples/bluetooth/bap_broadcast_source/src/main.c index b0238ade6bd02..ee8c046130777 100644 --- a/samples/bluetooth/bap_broadcast_source/src/main.c +++ b/samples/bluetooth/bap_broadcast_source/src/main.c @@ -15,17 +15,22 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include #include +#include +#include BUILD_ASSERT(strlen(CONFIG_BROADCAST_CODE) <= BT_ISO_BROADCAST_CODE_SIZE, "Invalid broadcast code"); @@ -82,22 +87,31 @@ static struct bt_bap_lc3_preset preset_active = BT_BAP_LC3_BROADCAST_PRESET_24_2 #if defined(CONFIG_LIBLC3) #include "lc3.h" -#if defined(CONFIG_USB_DEVICE_AUDIO) +#if defined(CONFIG_USE_USB_AUDIO_INPUT) #include #include #include +#include + /* USB Audio Data is downsampled from 48kHz to match broadcast preset when receiving data */ -#define USB_SAMPLE_RATE 48000 -#define USB_DOWNSAMPLE_RATE BROADCAST_SAMPLE_RATE -#define USB_FRAME_DURATION_US 1000 -#define USB_NUM_SAMPLES ((USB_FRAME_DURATION_US * USB_DOWNSAMPLE_RATE) / USEC_PER_SEC) -#define USB_BYTES_PER_SAMPLE 2 -#define USB_CHANNELS 2 +#define USB_SAMPLE_RATE 48000 +#define USB_DOWNSAMPLE_RATE BROADCAST_SAMPLE_RATE +#define USB_FRAME_DURATION_US 1000 +#define USB_SAMPLE_CNT ((USB_FRAME_DURATION_US * USB_SAMPLE_RATE) / USEC_PER_SEC) +#define USB_DOWNSSAMPLE_CNT ((USB_FRAME_DURATION_US * USB_DOWNSAMPLE_RATE) / USEC_PER_SEC) +#define USB_BYTES_PER_SAMPLE 2 +#define USB_CHANNELS 2 +#define USB_MONO_FRAME_SIZE (USB_SAMPLE_CNT * USB_BYTES_PER_SAMPLE) +/* The number of samples received may be USB_SAMPLE_CNT -+ 1 */ +#define USB_MAX_MONO_FRAME_SIZE ((USB_SAMPLE_CNT + 1) * USB_BYTES_PER_SAMPLE) +#define USB_STEREO_FRAME_SIZE (USB_MONO_FRAME_SIZE * USB_CHANNELS) +#define USB_MAX_STEREO_FRAME_SIZE (USB_MAX_MONO_FRAME_SIZE * USB_CHANNELS) +#define USB_ENQUEUE_COUNT 30U /* 30 times 1ms frames => 30ms */ #define RING_BUF_USB_FRAMES 20 -#define AUDIO_RING_BUF_BYTES (USB_NUM_SAMPLES * USB_BYTES_PER_SAMPLE * RING_BUF_USB_FRAMES) -#else /* !defined(CONFIG_USB_DEVICE_AUDIO) */ +#define AUDIO_RING_BUF_BYTES (USB_DOWNSSAMPLE_CNT * USB_BYTES_PER_SAMPLE * RING_BUF_USB_FRAMES) +#else /* !defined(CONFIG_USE_USB_AUDIO_INPUT) */ #include @@ -124,7 +138,7 @@ static void fill_audio_buf_sin(int16_t *buf, int length_us, int frequency_hz, in buf[i] = (int16_t)(AUDIO_VOLUME * sample); } } -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ +#endif /* defined(CONFIG_USE_USB_AUDIO_INPUT) */ #endif /* defined(CONFIG_LIBLC3) */ static struct broadcast_source_stream { @@ -138,10 +152,10 @@ static struct broadcast_source_stream { #elif defined(CONFIG_BAP_BROADCAST_24_2_1) lc3_encoder_mem_48k_t lc3_encoder_mem; #endif -#if defined(CONFIG_USB_DEVICE_AUDIO) +#if defined(CONFIG_USE_USB_AUDIO_INPUT) struct ring_buf audio_ring_buf; uint8_t _ring_buffer_memory[AUDIO_RING_BUF_BYTES]; -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ +#endif /* defined(CONFIG_USE_USB_AUDIO_INPUT) */ #endif /* defined(CONFIG_LIBLC3) */ } streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT]; static struct bt_bap_broadcast_source *broadcast_source; @@ -153,8 +167,8 @@ static int16_t send_pcm_data[MAX_NUM_SAMPLES]; static uint16_t seq_num; static bool stopping; -static K_SEM_DEFINE(sem_started, 0U, ARRAY_SIZE(streams)); -static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(streams)); +static K_SEM_DEFINE(sem_started, 0U, 1U); +static K_SEM_DEFINE(sem_stopped, 0U, 1U); #define BROADCAST_SOURCE_LIFETIME 120U /* seconds */ @@ -193,7 +207,7 @@ static void send_data(struct broadcast_source_stream *source_stream) return; } -#if defined(CONFIG_USB_DEVICE_AUDIO) +#if defined(CONFIG_USE_USB_AUDIO_INPUT) uint32_t size = ring_buf_get(&source_stream->audio_ring_buf, (uint8_t *)send_pcm_data, sizeof(send_pcm_data)); @@ -271,7 +285,7 @@ static void init_lc3_thread(void *arg1, void *arg2, void *arg3) return; } -#if !defined(CONFIG_USB_DEVICE_AUDIO) +#if !defined(CONFIG_USE_USB_AUDIO_INPUT) /* If USB is not used as a sound source, generate a sine wave */ fill_audio_buf_sin(send_pcm_data, frame_duration_us, AUDIO_TONE_FREQUENCY_HZ, freq_hz); #endif @@ -303,28 +317,62 @@ static void init_lc3_thread(void *arg1, void *arg2, void *arg3) K_THREAD_DEFINE(encoder, LC3_ENCODER_STACK_SIZE, init_lc3_thread, NULL, NULL, NULL, LC3_ENCODER_PRIORITY, 0, -1); -#if defined(CONFIG_USB_DEVICE_AUDIO) -static void data_received(const struct device *dev, struct net_buf *buffer, size_t size) +#if defined(CONFIG_USE_USB_AUDIO_INPUT) +/* Allocate 3: 1 for USB to receive data to and 2 additional buffers to prevent out of memory + * errors when USB host decides to perform rapid terminal enable/disable cycles. + */ +K_MEM_SLAB_DEFINE_STATIC(usb_in_buf_pool, USB_MAX_STEREO_FRAME_SIZE, 3, UDC_BUF_ALIGN); +static bool terminal_enabled; + +static void terminal_update_cb(const struct device *dev, uint8_t terminal, bool enabled, + bool microframes, void *user_data) { - static int count; - int16_t *pcm; - int nsamples, ratio; - int16_t usb_pcm_data[USB_CHANNELS][USB_NUM_SAMPLES]; + terminal_enabled = enabled; +} - if (!buffer) { - return; +static void uac2_sof_cb(const struct device *dev, void *user_data) +{ + /* no-op, but has to be registered */ +} + +static void *get_recv_buf_cb(const struct device *dev, uint8_t terminal, uint16_t size, + void *user_data) +{ + void *buf = NULL; + int ret; + + if (!terminal_enabled) { + return NULL; } - if (!size) { - net_buf_unref(buffer); + __ASSERT(size <= USB_MAX_STEREO_FRAME_SIZE, "%u was not <= %d", size, + USB_MAX_STEREO_FRAME_SIZE); + + ret = k_mem_slab_alloc(&usb_in_buf_pool, &buf, K_NO_WAIT); + if (ret != 0) { + printk("Failed to allocate buffer: %d\n", ret); + } + + return buf; +} + +static void data_recv_cb(const struct device *dev, uint8_t terminal, void *buf, uint16_t size, + void *user_data) +{ + int16_t usb_pcm_data[USB_CHANNELS][USB_DOWNSSAMPLE_CNT]; + int nsamples, ratio; + static int count; + int16_t *pcm; + + if (!terminal_enabled || buf == NULL || size == 0U) { + k_mem_slab_free(&usb_in_buf_pool, buf); return; } - pcm = (int16_t *)net_buf_pull_mem(buffer, size); + pcm = (int16_t *)buf; /* 'size' is in bytes, containing 1ms, 48kHz, stereo, 2 bytes per sample. - * Take left channel and do a simple downsample to 16kHz/24Khz - * matching the broadcast preset. + * Do a simple downsample to 16kHz/24Khz matching the broadcast preset. */ ratio = USB_SAMPLE_RATE / USB_DOWNSAMPLE_RATE; @@ -347,15 +395,13 @@ static void data_received(const struct device *dev, struct net_buf *buffer, size } count++; - if ((count % 1000) == 0) { + if ((count % 10000) == 0) { printk("USB Data received (count = %d)\n", count); } - net_buf_unref(buffer); + k_mem_slab_free(&usb_in_buf_pool, buf); } - -static const struct usb_audio_ops ops = {.data_received_cb = data_received}; -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ +#endif /* defined(CONFIG_USE_USB_AUDIO_INPUT) */ #endif /* defined(CONFIG_LIBLC3) */ static void stream_started_cb(struct bt_bap_stream *stream) @@ -365,12 +411,6 @@ static void stream_started_cb(struct bt_bap_stream *stream) source_stream->seq_num = 0U; source_stream->sent_cnt = 0U; - k_sem_give(&sem_started); -} - -static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason) -{ - k_sem_give(&sem_stopped); } static void stream_sent_cb(struct bt_bap_stream *stream) @@ -387,7 +427,9 @@ static void stream_sent_cb(struct bt_bap_stream *stream) } static struct bt_bap_stream_ops stream_ops = { - .started = stream_started_cb, .stopped = stream_stopped_cb, .sent = stream_sent_cb}; + .started = stream_started_cb, + .sent = stream_sent_cb, +}; static int setup_broadcast_source(struct bt_bap_broadcast_source **source) { @@ -439,8 +481,24 @@ static int setup_broadcast_source(struct bt_bap_broadcast_source **source) return 0; } +static void source_started_cb(struct bt_bap_broadcast_source *source) +{ + printk("Broadcast source %p started\n", source); + k_sem_give(&sem_started); +} + +static void source_stopped_cb(struct bt_bap_broadcast_source *source, uint8_t reason) +{ + printk("Broadcast source %p stopped with reason 0x%02X\n", source, reason); + k_sem_give(&sem_stopped); +} + int main(void) { + static struct bt_bap_broadcast_source_cb broadcast_source_cb = { + .started = source_started_cb, + .stopped = source_stopped_cb, + }; struct bt_le_ext_adv *adv; int err; @@ -451,20 +509,31 @@ int main(void) } printk("Bluetooth initialized\n"); + err = bt_bap_broadcast_source_register_cb(&broadcast_source_cb); + if (err != 0) { + printk("Failed to register broadcast source callbacks (err %d)\n", err); + return 0; + } + for (size_t i = 0U; i < ARRAY_SIZE(send_pcm_data); i++) { /* Initialize mock data */ send_pcm_data[i] = i; } #if defined(CONFIG_LIBLC3) -#if defined(CONFIG_USB_DEVICE_AUDIO) - const struct device *hs_dev; - - hs_dev = DEVICE_DT_GET(DT_NODELABEL(hs_0)); - - if (!device_is_ready(hs_dev)) { - printk("Device USB Headset is not ready\n"); - return 0; +#if defined(CONFIG_USE_USB_AUDIO_INPUT) + const struct device *broadcaster_dev = DEVICE_DT_GET(DT_NODELABEL(uac2_broadcaster)); + static struct uac2_ops usb_audio_ops = { + .terminal_update_cb = terminal_update_cb, + .get_recv_buf = get_recv_buf_cb, + .data_recv_cb = data_recv_cb, + .sof_cb = uac2_sof_cb, + }; + struct usbd_context *sample_usbd; + + if (!device_is_ready(broadcaster_dev)) { + printk("Cannot get USB Broadcaster Device\n"); + return -EIO; } printk("Found USB Headset Device\n"); @@ -478,15 +547,23 @@ int main(void) ring_buf_capacity_get(&(streams[i].audio_ring_buf))); } - usb_audio_register(hs_dev, &ops); + usbd_uac2_set_ops(broadcaster_dev, &usb_audio_ops, NULL); - err = usb_enable(NULL); - if (err && err != -EALREADY) { - printk("Failed to enable USB (%d)", err); - return 0; + sample_usbd = sample_usbd_init_device(NULL); + if (sample_usbd == NULL) { + printk("Failed to init USBD device: %d\n", err); + return -ENODEV; } -#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */ + err = usbd_enable(sample_usbd); + if (err != 0) { + printk("Failed to enable USBD: %d\n", err); + return err; + } + + printk("USB initialized\n"); + +#endif /* defined(CONFIG_USE_USB_AUDIO_INPUT) */ k_thread_start(encoder); #endif /* defined(CONFIG_LIBLC3) */ @@ -581,10 +658,8 @@ int main(void) return 0; } - /* Wait for all to be started */ - for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { - k_sem_take(&sem_started, K_FOREVER); - } + /* Wait for broadcast source to be started */ + k_sem_take(&sem_started, K_FOREVER); printk("Broadcast source started\n"); /* Initialize sending */ @@ -594,10 +669,10 @@ int main(void) } } -#if defined(CONFIG_LIBLC3) && defined(CONFIG_USB_DEVICE_AUDIO) +#if defined(CONFIG_LIBLC3) && defined(CONFIG_USE_USB_AUDIO_INPUT) /* Never stop streaming when using USB Audio as input */ k_sleep(K_FOREVER); -#endif /* defined(CONFIG_LIBLC3) && defined(CONFIG_USB_DEVICE_AUDIO) */ +#endif /* defined(CONFIG_LIBLC3) && defined(CONFIG_USE_USB_AUDIO_INPUT) */ printk("Waiting %u seconds before stopped\n", BROADCAST_SOURCE_LIFETIME); k_sleep(K_SECONDS(BROADCAST_SOURCE_LIFETIME)); printk("Stopping broadcast source\n"); @@ -608,10 +683,8 @@ int main(void) return 0; } - /* Wait for all to be stopped */ - for (size_t i = 0U; i < ARRAY_SIZE(streams); i++) { - k_sem_take(&sem_stopped, K_FOREVER); - } + /* Wait for broadcast source to be stopped */ + k_sem_take(&sem_stopped, K_FOREVER); printk("Broadcast source stopped\n"); printk("Deleting broadcast source\n"); diff --git a/samples/bluetooth/bap_unicast_client/boards/native_sim.conf b/samples/bluetooth/bap_unicast_client/boards/native_sim.conf index c951fcc8c3366..8ab1d7be11310 100644 --- a/samples/bluetooth/bap_unicast_client/boards/native_sim.conf +++ b/samples/bluetooth/bap_unicast_client/boards/native_sim.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/bap_unicast_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/bap_unicast_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index 50ba07e852275..614df139f0eab 100644 --- a/samples/bluetooth/bap_unicast_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_unicast_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -9,5 +9,3 @@ CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/bap_unicast_client/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/bap_unicast_client/boards/nrf5340bsim_nrf5340_cpuapp.conf index ffb0e27ed64d5..9b059b92ddc14 100644 --- a/samples/bluetooth/bap_unicast_client/boards/nrf5340bsim_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_unicast_client/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -6,5 +6,3 @@ CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/bap_unicast_client/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/bap_unicast_client/boards/nrf5340dk_nrf5340_cpuapp.conf index e02323fb3f790..31b3a09380fc7 100644 --- a/samples/bluetooth/bap_unicast_client/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_unicast_client/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -9,5 +9,3 @@ CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/bap_unicast_client/boards/nrf54l15bsim_nrf54l15_cpuapp.conf b/samples/bluetooth/bap_unicast_client/boards/nrf54l15bsim_nrf54l15_cpuapp.conf new file mode 100644 index 0000000000000..8bfd5bc41f9bc --- /dev/null +++ b/samples/bluetooth/bap_unicast_client/boards/nrf54l15bsim_nrf54l15_cpuapp.conf @@ -0,0 +1,3 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y diff --git a/samples/bluetooth/bap_unicast_client/src/main.c b/samples/bluetooth/bap_unicast_client/src/main.c index b8861bb695696..082b9fe7d528e 100644 --- a/samples/bluetooth/bap_unicast_client/src/main.c +++ b/samples/bluetooth/bap_unicast_client/src/main.c @@ -236,7 +236,7 @@ static void stream_enabled(struct bt_bap_stream *stream) k_sem_give(&sem_stream_enabled); } -static bool stream_is_tx(const struct bt_bap_stream *stream) +static bool stream_tx_can_send(const struct bt_bap_stream *stream) { struct bt_bap_ep_info info; int err; @@ -272,7 +272,7 @@ static void stream_started(struct bt_bap_stream *stream) { printk("Audio Stream %p started\n", stream); /* Register the stream for TX if it can send */ - if (IS_ENABLED(CONFIG_BT_AUDIO_TX) && stream_is_tx(stream)) { + if (IS_ENABLED(CONFIG_BT_AUDIO_TX) && stream_tx_can_send(stream)) { const int err = stream_tx_register(stream); if (err != 0) { @@ -298,7 +298,7 @@ static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason) printk("Audio Stream %p stopped with reason 0x%02X\n", stream, reason); /* Unregister the stream for TX if it can send */ - if (IS_ENABLED(CONFIG_BT_AUDIO_TX) && stream_is_tx(stream)) { + if (IS_ENABLED(CONFIG_BT_AUDIO_TX) && stream_tx_can_send(stream)) { const int err = stream_tx_unregister(stream); if (err != 0) { diff --git a/samples/bluetooth/bap_unicast_server/boards/native_sim.conf b/samples/bluetooth/bap_unicast_server/boards/native_sim.conf index c951fcc8c3366..8ab1d7be11310 100644 --- a/samples/bluetooth/bap_unicast_server/boards/native_sim.conf +++ b/samples/bluetooth/bap_unicast_server/boards/native_sim.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/bap_unicast_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/bap_unicast_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index ffb0e27ed64d5..a8d2d0a04d6b4 100644 --- a/samples/bluetooth/bap_unicast_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_unicast_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -1,10 +1,11 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y +# The LC3 codec uses a large amount of stack. This app runs the codec in the BT RX thread, hence +# increase stack size for that thread. +CONFIG_BT_RX_STACK_SIZE=4096 CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/bap_unicast_server/boards/nrf5340bsim_nrf5340_cpuapp.conf b/samples/bluetooth/bap_unicast_server/boards/nrf5340bsim_nrf5340_cpuapp.conf index ffb0e27ed64d5..9b059b92ddc14 100644 --- a/samples/bluetooth/bap_unicast_server/boards/nrf5340bsim_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_unicast_server/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -6,5 +6,3 @@ CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/bap_unicast_server/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/bap_unicast_server/boards/nrf5340dk_nrf5340_cpuapp.conf index e02323fb3f790..a8d2d0a04d6b4 100644 --- a/samples/bluetooth/bap_unicast_server/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/bap_unicast_server/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -1,13 +1,11 @@ # For LC3 the following configs are needed CONFIG_FPU=y CONFIG_LIBLC3=y -# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence -# inctease stack size for that thread. -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 +# The LC3 codec uses a large amount of stack. This app runs the codec in the BT RX thread, hence +# increase stack size for that thread. +CONFIG_BT_RX_STACK_SIZE=4096 CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/bap_unicast_server/boards/nrf54l15bsim_nrf54l15_cpuapp.conf b/samples/bluetooth/bap_unicast_server/boards/nrf54l15bsim_nrf54l15_cpuapp.conf new file mode 100644 index 0000000000000..8bfd5bc41f9bc --- /dev/null +++ b/samples/bluetooth/bap_unicast_server/boards/nrf54l15bsim_nrf54l15_cpuapp.conf @@ -0,0 +1,3 @@ +# For LC3 the following configs are needed +CONFIG_FPU=y +CONFIG_LIBLC3=y diff --git a/samples/bluetooth/bap_unicast_server/prj.conf b/samples/bluetooth/bap_unicast_server/prj.conf index 566baa8e83075..a102747bf04ca 100644 --- a/samples/bluetooth/bap_unicast_server/prj.conf +++ b/samples/bluetooth/bap_unicast_server/prj.conf @@ -4,7 +4,6 @@ CONFIG_BT_SMP=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_ISO_PERIPHERAL=y CONFIG_BT_AUDIO=y -CONFIG_BT_GATT_CACHING=y CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_BAP_UNICAST_SERVER=y CONFIG_BT_ASCS=y diff --git a/samples/bluetooth/bap_unicast_server/src/main.c b/samples/bluetooth/bap_unicast_server/src/main.c index 0bf79e48aac33..cc13491a77d03 100644 --- a/samples/bluetooth/bap_unicast_server/src/main.c +++ b/samples/bluetooth/bap_unicast_server/src/main.c @@ -509,8 +509,7 @@ static void stream_recv_lc3_codec(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info, struct net_buf *buf) { - const uint8_t *in_buf; - uint8_t err = -1; + const bool valid_data = (info->flags & BT_ISO_FLAGS_VALID) == 0; const int octets_per_frame = buf->len / frames_per_sdu; if (lc3_decoder == NULL) { @@ -518,40 +517,24 @@ static void stream_recv_lc3_codec(struct bt_bap_stream *stream, return; } - if ((info->flags & BT_ISO_FLAGS_VALID) == 0) { + if (!valid_data) { printk("Bad packet: 0x%02X\n", info->flags); - - in_buf = NULL; - } else { - in_buf = buf->data; } - /* This code is to demonstrate the use of the LC3 codec. On an actual implementation - * it might be required to offload the processing to another task to avoid blocking the - * BT stack. - */ for (int i = 0; i < frames_per_sdu; i++) { - - int offset = 0; - - err = lc3_decode(lc3_decoder, in_buf + offset, octets_per_frame, - LC3_PCM_FORMAT_S16, audio_buf, 1); - - if (in_buf != NULL) { - offset += octets_per_frame; + /* Passing NULL performs PLC */ + const int err = lc3_decode( + lc3_decoder, valid_data ? net_buf_pull_mem(buf, octets_per_frame) : NULL, + octets_per_frame, LC3_PCM_FORMAT_S16, audio_buf, 1); + + if (err == 1) { + printk("[%d]: Decoder performed PLC\n", i); + } else if (err < 0) { + printk("[%d]: Decoder failed - wrong parameters?: %d\n", i, err); } } printk("RX stream %p len %u\n", stream, buf->len); - - if (err == 1) { - printk(" decoder performed PLC\n"); - return; - - } else if (err < 0) { - printk(" decoder failed - wrong parameters?\n"); - return; - } } #else @@ -738,9 +721,16 @@ static int set_available_contexts(void) return 0; } + int main(void) { struct bt_le_ext_adv *adv; + const struct bt_pacs_register_param pacs_param = { + .snk_pac = true, + .snk_loc = true, + .src_pac = true, + .src_loc = true, + }; int err; err = bt_enable(NULL); @@ -751,6 +741,12 @@ int main(void) printk("Bluetooth initialized\n"); + err = bt_pacs_register(&pacs_param); + if (err) { + printk("Could not register PACS (err %d)\n", err); + return 0; + } + bt_bap_unicast_server_register(¶m); bt_bap_unicast_server_register_cb(&unicast_server_cb); diff --git a/samples/bluetooth/beacon/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/samples/bluetooth/beacon/boards/nrf54l15dk_nrf54l15_cpuapp.conf deleted file mode 100644 index 350b42b0f67ab..0000000000000 --- a/samples/bluetooth/beacon/boards/nrf54l15dk_nrf54l15_cpuapp.conf +++ /dev/null @@ -1,13 +0,0 @@ -# We need a random number generator to properly initialize the PSA Crypto core -# implemented by Mbed TLS. The proper thing to do in this platform would be -# to enable ENTROPY_GENERATOR, but this is not supported right now for the -# following reasons: -# - at device-tree level (nrf54l15_cpuapp.dtsi) the only RNG source available -# is "zephyr,psa-crypto-rng" which means that TF-M is required in order for -# this to work. Unfortunately TF-M is still not supported for this platform, yet. -# - cpuapp does not have a direct access to the RNG without TF-M, so there's -# no other way it can make use of it as of now. -# -# Since both options are not viable, we fall back to the test random generator -# until further support is added to the platform. -CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/samples/bluetooth/cap_acceptor/Kconfig b/samples/bluetooth/cap_acceptor/Kconfig index 9c0ef35140467..9ec0440cef27c 100644 --- a/samples/bluetooth/cap_acceptor/Kconfig +++ b/samples/bluetooth/cap_acceptor/Kconfig @@ -7,7 +7,6 @@ config SAMPLE_UNICAST bool "Whether or not to search for CAP acceptors for unicast audio" default y select BT_BAP_UNICAST_SERVER - select BT_GATT_CACHING select BT_ISO_PERIPHERAL select BT_ASCS select BT_PAC_SNK diff --git a/samples/bluetooth/cap_acceptor/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/cap_acceptor/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f58eedb0453c5..09fa41842ebd9 100644 --- a/samples/bluetooth/cap_acceptor/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/cap_acceptor/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -2,5 +2,3 @@ CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/cap_acceptor/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/cap_acceptor/boards/nrf5340dk_nrf5340_cpuapp.conf index f58eedb0453c5..09fa41842ebd9 100644 --- a/samples/bluetooth/cap_acceptor/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/cap_acceptor/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -2,5 +2,3 @@ CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c b/samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c index 444c5f06e3ce2..190bef26eabe1 100644 --- a/samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c +++ b/samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -20,9 +21,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -605,8 +608,8 @@ static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); - printk("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X\n", broadcast_id, - le_addr, info->sid); + LOG_INF("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X\n", broadcast_id, + le_addr, info->sid); bt_addr_le_copy(¶m.addr, info->addr); param.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE; diff --git a/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c b/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c index 132ee499c8771..55a9f91099e5b 100644 --- a/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c +++ b/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c @@ -456,5 +456,8 @@ int init_cap_acceptor_unicast(struct peer_config *peer) } } + k_sem_init(&peer->source_stream_sem, 0, 1); + k_sem_init(&peer->sink_stream_sem, 0, 1); + return 0; } diff --git a/samples/bluetooth/cap_acceptor/src/main.c b/samples/bluetooth/cap_acceptor/src/main.c index 37ba41d32ec80..d0bc49cd63086 100644 --- a/samples/bluetooth/cap_acceptor/src/main.c +++ b/samples/bluetooth/cap_acceptor/src/main.c @@ -256,6 +256,12 @@ static int init_cap_acceptor(void) static const struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3( SUPPORTED_FREQ, SUPPORTED_DURATION, MAX_CHAN_PER_STREAM, MIN_SDU, MAX_SDU, FRAMES_PER_SDU, (SINK_CONTEXT | SOURCE_CONTEXT)); + const struct bt_pacs_register_param pacs_param = { + .snk_pac = true, + .snk_loc = true, + .src_pac = true, + .src_loc = true, + }; int err; err = bt_enable(NULL); @@ -267,6 +273,12 @@ static int init_cap_acceptor(void) LOG_INF("Bluetooth initialized"); + err = bt_pacs_register(&pacs_param); + if (err) { + LOG_ERR("Could not register PACS (err %d)", err); + return 0; + } + if (IS_ENABLED(CONFIG_BT_PAC_SNK)) { static struct bt_pacs_cap sink_cap = { .codec_cap = &lc3_codec_cap, diff --git a/samples/bluetooth/cap_initiator/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/cap_initiator/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf index f58eedb0453c5..09fa41842ebd9 100644 --- a/samples/bluetooth/cap_initiator/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/cap_initiator/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -2,5 +2,3 @@ CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/cap_initiator/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/cap_initiator/boards/nrf5340dk_nrf5340_cpuapp.conf index f58eedb0453c5..09fa41842ebd9 100644 --- a/samples/bluetooth/cap_initiator/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/samples/bluetooth/cap_initiator/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -2,5 +2,3 @@ CONFIG_BT_BUF_EVT_RX_SIZE=255 CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_BUF_CMD_TX_SIZE=255 - -CONFIG_BT_SEND_ECC_EMULATION=y diff --git a/samples/bluetooth/cap_initiator/src/cap_initiator_broadcast.c b/samples/bluetooth/cap_initiator/src/cap_initiator_broadcast.c index d55f0f6c3b790..7f2cbb1305a6a 100644 --- a/samples/bluetooth/cap_initiator/src/cap_initiator_broadcast.c +++ b/samples/bluetooth/cap_initiator/src/cap_initiator_broadcast.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -138,7 +139,7 @@ static int setup_extended_adv_data(struct bt_cap_broadcast_source *source, #else err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE); if (err) { - printk("Unable to generate broadcast ID: %d\n", err); + LOG_ERR("Unable to generate broadcast ID: %d\n", err); return err; } #endif /* CONFIG_STATIC_BROADCAST_ID */ diff --git a/samples/bluetooth/ccp_call_control_client/CMakeLists.txt b/samples/bluetooth/ccp_call_control_client/CMakeLists.txt new file mode 100644 index 0000000000000..101c16bf0d60b --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/CMakeLists.txt @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(ccp_call_control_client) + +target_sources(app PRIVATE + src/main.c +) + +zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) diff --git a/samples/bluetooth/ccp_call_control_client/Kconfig.sysbuild b/samples/bluetooth/ccp_call_control_client/Kconfig.sysbuild new file mode 100644 index 0000000000000..f37b265ecbc27 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/Kconfig.sysbuild @@ -0,0 +1,15 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340dk/nrf5340/cpunet" if "$(BOARD)" = "nrf5340dk" + default "nrf5340_audio_dk/nrf5340/cpunet" if "$(BOARD)" = "nrf5340_audio_dk" + default "nrf5340bsim/nrf5340/cpunet" if $(BOARD_TARGET_STRING) = "NRF5340BSIM_NRF5340_CPUAPP" + +config NET_CORE_IMAGE_HCI_IPC + bool "HCI IPC image on network core" + default y + depends on NET_CORE_BOARD != "" diff --git a/samples/bluetooth/ccp_call_control_client/README.rst b/samples/bluetooth/ccp_call_control_client/README.rst new file mode 100644 index 0000000000000..db2779297883b --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/README.rst @@ -0,0 +1,78 @@ +.. zephyr:code-sample:: bluetooth_ccp_call_control_client + :name: Call Control Profile (CCP) Call Control Server + :relevant-api: bluetooth bt_ccp bt_tbs + + CCP Call Control Server sample that registers one or more TBS bearers and advertises the + TBS UUID(s). + +Overview +******** + +Application demonstrating the CCP Call Control Client functionality. +Starts by scanning for a CCP Call Control Server to connect and set up calls. + +The profile works for both GAP Central and GAP Peripheral devices, but this sample only assumes the +GAP Central role. + +This sample can be found under :zephyr_file:`samples/bluetooth/ccp_call_control_client` +in the Zephyr tree. + +Check the :zephyr:code-sample-category:`bluetooth` samples for general information. + +Requirements +************ + +* BlueZ running on the host, or +* A board with Bluetooth Low Energy 5.2 support + +Building and Running +******************** + +When building targeting an nrf52 series board with the Zephyr Bluetooth Controller, +use ``-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf`` to enable the required feature support. + +Building for an nrf5340dk +------------------------- + +You can build both the application core image and an appropriate controller image for the network +core with: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/ccp_call_control_client/ + :board: nrf5340dk/nrf5340/cpuapp + :goals: build + :west-args: --sysbuild + +If you prefer to only build the application core image, you can do so by doing instead: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/ccp_call_control_client/ + :board: nrf5340dk/nrf5340/cpuapp + :goals: build + +In that case you can pair this application core image with the +:zephyr:code-sample:`bluetooth_hci_ipc` sample +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf` configuration. + +Building for a simulated nrf5340bsim +------------------------------------ + +Similarly to how you would for real HW, you can do: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/ccp_call_control_client/ + :board: nrf5340bsim/nrf5340/cpuapp + :goals: build + :west-args: --sysbuild + +Note this will produce a Linux executable in :file:`./build/zephyr/zephyr.exe`. +For more information, check :ref:`this board documentation `. + +Building for a simulated nrf52_bsim +----------------------------------- + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/ccp_call_control_client/ + :board: nrf52_bsim + :goals: build + :gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf diff --git a/samples/bluetooth/ccp_call_control_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/ccp_call_control_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf new file mode 100644 index 0000000000000..09fa41842ebd9 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -0,0 +1,4 @@ +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 diff --git a/samples/bluetooth/ccp_call_control_client/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/ccp_call_control_client/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 0000000000000..09fa41842ebd9 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,4 @@ +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 diff --git a/samples/bluetooth/ccp_call_control_client/overlay-bt_ll_sw_split.conf b/samples/bluetooth/ccp_call_control_client/overlay-bt_ll_sw_split.conf new file mode 100644 index 0000000000000..dce0f2c298ec1 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/overlay-bt_ll_sw_split.conf @@ -0,0 +1,6 @@ +# Zephyr Bluetooth Controller +CONFIG_BT_LL_SW_SPLIT=y + +# Zephyr Controller tested maximum advertising data that can be set in a single HCI command +CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191 +CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=191 diff --git a/samples/bluetooth/ccp_call_control_client/prj.conf b/samples/bluetooth/ccp_call_control_client/prj.conf new file mode 100644 index 0000000000000..85549f2c321c7 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/prj.conf @@ -0,0 +1,22 @@ +CONFIG_BT=y +CONFIG_LOG=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y +CONFIG_BT_AUDIO=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_DEVICE_NAME="CCP Call Control Client" + +CONFIG_BT_SMP=y +CONFIG_BT_KEYS_OVERWRITE_OLDEST=y + +# CCP support +CONFIG_BT_CCP_CALL_CONTROL_CLIENT=y +CONFIG_BT_CCP_CALL_CONTROL_CLIENT_BEARER_COUNT=2 +CONFIG_BT_TBS_CLIENT_GTBS=y +CONFIG_BT_TBS_CLIENT_TBS=y +CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES=1 +CONFIG_UTF8=y + +# TBS Client may require up to 12 buffers +CONFIG_BT_ATT_TX_COUNT=12 diff --git a/samples/bluetooth/ccp_call_control_client/sample.yaml b/samples/bluetooth/ccp_call_control_client/sample.yaml new file mode 100644 index 0000000000000..88fc3e30aa101 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/sample.yaml @@ -0,0 +1,30 @@ +sample: + description: Bluetooth Low Energy Call Control Profile Server sample + name: Bluetooth Low Energy Call Control Profile Server sample +tests: + sample.bluetooth.ccp_call_control_client: + harness: bluetooth + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + - nrf5340dk/nrf5340/cpuapp + - nrf5340bsim/nrf5340/cpuapp + integration_platforms: + - qemu_x86 + - nrf5340dk/nrf5340/cpuapp + tags: bluetooth + sysbuild: true + sample.bluetooth.ccp_call_control_client.bt_ll_sw_split: + harness: bluetooth + platform_allow: + - nrf52_bsim + - nrf52833dk/nrf52833 + - nrf52840dk/nrf52840 + - nrf52840dongle/nrf52840 + integration_platforms: + - nrf52_bsim + - nrf52833dk/nrf52833 + - nrf52840dk/nrf52840 + - nrf52840dongle/nrf52840 + extra_args: OVERLAY_CONFIG=overlay-bt_ll_sw_split.conf + tags: bluetooth diff --git a/samples/bluetooth/ccp_call_control_client/src/main.c b/samples/bluetooth/ccp_call_control_client/src/main.c new file mode 100644 index 0000000000000..db8341204a47f --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/src/main.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(ccp_call_control_client, CONFIG_LOG_DEFAULT_LEVEL); + +#define SEM_TIMEOUT K_SECONDS(10) + +static struct bt_conn *peer_conn; +/* client is not static as it is used for testing purposes */ +struct bt_ccp_call_control_client *client; +static struct bt_ccp_call_control_client_bearers client_bearers; + +static K_SEM_DEFINE(sem_conn_state_change, 0, 1); +static K_SEM_DEFINE(sem_security_updated, 0, 1); +static K_SEM_DEFINE(sem_ccp_action_completed, 0, 1); + +static void connected_cb(struct bt_conn *conn, uint8_t err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + (void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + LOG_INF("Connected: %s", addr); + + k_sem_give(&sem_conn_state_change); +} + +static void disconnected_cb(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != peer_conn) { + return; + } + + (void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + LOG_INF("Disconnected: %s (reason 0x%02x)", addr, reason); + + bt_conn_unref(peer_conn); + peer_conn = NULL; + client = NULL; + memset(&client_bearers, 0, sizeof(client_bearers)); + k_sem_give(&sem_conn_state_change); +} + +static void security_changed_cb(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) +{ + if (err == 0) { + k_sem_give(&sem_security_updated); + } else { + LOG_ERR("Failed to set security level: %s(%u)", bt_security_err_to_str(err), err); + } +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected_cb, + .disconnected = disconnected_cb, + .security_changed = security_changed_cb, +}; + +static bool check_gtbs_support(struct bt_data *data, void *user_data) +{ + struct net_buf_simple svc_data; + bool *connect = user_data; + const struct bt_uuid *uuid; + uint16_t uuid_val; + + if (data->type != BT_DATA_SVC_DATA16) { + return true; /* Continue parsing to next AD data type */ + } + + if (data->data_len < sizeof(uuid_val)) { + LOG_WRN("AD invalid size %u", data->data_len); + return true; /* Continue parsing to next AD data type */ + } + + net_buf_simple_init_with_data(&svc_data, (void *)data->data, data->data_len); + + /* Pull the 16-bit service data and compare to what we are searching for */ + uuid_val = net_buf_simple_pull_le16(&svc_data); + uuid = BT_UUID_DECLARE_16(sys_le16_to_cpu(uuid_val)); + if (bt_uuid_cmp(uuid, BT_UUID_GTBS) != 0) { + /* We are looking for the GTBS service data */ + return true; /* Continue parsing to next AD data type */ + } + + *connect = true; + + return false; /* Stop parsing */ +} + +static void scan_recv_cb(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + bool connect = false; + + if (peer_conn != NULL) { + /* Already connected */ + return; + } + + /* CCP mandates that connectbale extended advertising is used by the peripherals so we + * ignore any scan report this is not that. + * We also ignore reports with poor RSSI + */ + if (info->adv_type != BT_GAP_ADV_TYPE_EXT_ADV || + (info->adv_props & BT_GAP_ADV_PROP_EXT_ADV) == 0 || + (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) == 0 || info->rssi < -70) { + return; + } + + (void)bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str)); + LOG_INF("Connectable device found: %s (RSSI %d)", addr_str, info->rssi); + + /* Iterate on the advertising data to see if claims GTBS support */ + bt_data_parse(ad, check_gtbs_support, &connect); + + if (connect) { + int err; + + err = bt_le_scan_stop(); + if (err != 0) { + LOG_ERR("Scanning failed to stop (err %d)", err); + return; + } + + LOG_INF("Connecting to found CCP server"); + err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN, + BT_LE_CONN_PARAM_DEFAULT, &peer_conn); + if (err != 0) { + LOG_ERR("Conn create failed: %d", err); + } + } +} + +static int scan_and_connect(void) +{ + int err; + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL); + if (err != 0) { + LOG_ERR("Scanning failed to start (err %d)", err); + return err; + } + + LOG_INF("Scanning successfully started"); + + err = k_sem_take(&sem_conn_state_change, K_FOREVER); + if (err != 0) { + LOG_ERR("failed to take sem_connected (err %d)", err); + return err; + } + + err = bt_conn_set_security(peer_conn, BT_SECURITY_L2); + if (err != 0) { + LOG_ERR("failed to set security (err %d)", err); + return err; + } + + err = k_sem_take(&sem_security_updated, SEM_TIMEOUT); + if (err != 0) { + LOG_ERR("failed to take sem_security_updated (err %d)", err); + return err; + } + + LOG_INF("Security successfully updated"); + + return 0; +} + +static void ccp_call_control_client_discover_cb(struct bt_ccp_call_control_client *client, int err, + struct bt_ccp_call_control_client_bearers *bearers) +{ + if (err != 0) { + LOG_ERR("Discovery failed: %d", err); + return; + } + + LOG_INF("Discovery completed with %s%u TBS bearers", + bearers->gtbs_bearer != NULL ? "GTBS and " : "", bearers->tbs_count); + + memcpy(&client_bearers, bearers, sizeof(client_bearers)); + + k_sem_give(&sem_ccp_action_completed); +} + +static int reset_ccp_call_control_client(void) +{ + int err; + + LOG_INF("Resetting"); + + if (peer_conn != NULL) { + err = bt_conn_disconnect(peer_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + if (err != 0) { + return err; + } + + err = k_sem_take(&sem_conn_state_change, K_FOREVER); + if (err != 0) { + LOG_ERR("Failed to take sem_conn_state_change: %d", err); + return err; + } + } + + /* If scanning is already stopped it will still return `0` */ + err = bt_le_scan_stop(); + if (err != 0) { + LOG_ERR("Scanning failed to stop (err %d)", err); + return err; + } + + k_sem_reset(&sem_conn_state_change); + + return 0; +} + +static int discover_services(void) +{ + int err; + + LOG_INF("Discovering GTBS and TBS"); + + err = bt_ccp_call_control_client_discover(peer_conn, &client); + if (err != 0) { + LOG_ERR("Failed to discover: %d", err); + return err; + } + + err = k_sem_take(&sem_ccp_action_completed, SEM_TIMEOUT); + if (err != 0) { + LOG_ERR("Failed to take sem_ccp_action_completed: %d", err); + return err; + } + + return 0; +} + +static int init_ccp_call_control_client(void) +{ + static struct bt_le_scan_cb scan_cbs = { + .recv = scan_recv_cb, + }; + static struct bt_ccp_call_control_client_cb ccp_call_control_client_cbs = { + .discover = ccp_call_control_client_discover_cb, + }; + int err; + + err = bt_enable(NULL); + if (err != 0) { + LOG_ERR("Bluetooth enable failed (err %d)", err); + + return err; + } + + LOG_DBG("Bluetooth initialized"); + err = bt_le_scan_cb_register(&scan_cbs); + if (err != 0) { + LOG_ERR("Bluetooth enable failed (err %d)", err); + + return err; + } + + err = bt_ccp_call_control_client_register_cb(&ccp_call_control_client_cbs); + if (err != 0) { + LOG_ERR("Bluetooth enable failed (err %d)", err); + + return err; + } + + return 0; +} + +int main(void) +{ + int err; + + err = init_ccp_call_control_client(); + if (err != 0) { + return 0; + } + + LOG_INF("CCP Call Control Client initialized"); + + while (true) { + err = reset_ccp_call_control_client(); + if (err != 0) { + break; + } + + /* Start scanning for CCP servers and connect to the first we find */ + err = scan_and_connect(); + if (err != 0) { + continue; + } + + /* Discover TBS and GTBS on the remove server */ + err = discover_services(); + if (err != 0) { + continue; + } + + /* Reset if disconnected */ + err = k_sem_take(&sem_conn_state_change, K_FOREVER); + if (err != 0) { + LOG_ERR("Failed to take sem_conn_state_change: err %d", err); + break; + } + } + + return 0; +} diff --git a/samples/bluetooth/ccp_call_control_client/sysbuild.cmake b/samples/bluetooth/ccp_call_control_client/sysbuild.cmake new file mode 100644 index 0000000000000..2523aac8ea76f --- /dev/null +++ b/samples/bluetooth/ccp_call_control_client/sysbuild.cmake @@ -0,0 +1,24 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) + # For builds in the nrf5340, we build the netcore image with the controller + + set(NET_APP hci_ipc) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_CONF_FILE + ${NET_APP_SRC_DIR}/nrf5340_cpunet_iso-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) +endif() + +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/bluetooth/ccp_call_control_server/CMakeLists.txt b/samples/bluetooth/ccp_call_control_server/CMakeLists.txt new file mode 100644 index 0000000000000..67e198d981480 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/CMakeLists.txt @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(ccp_call_control_server) + +target_sources(app PRIVATE + src/main.c +) + +zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) diff --git a/samples/bluetooth/ccp_call_control_server/Kconfig.sysbuild b/samples/bluetooth/ccp_call_control_server/Kconfig.sysbuild new file mode 100644 index 0000000000000..f37b265ecbc27 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/Kconfig.sysbuild @@ -0,0 +1,15 @@ +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340dk/nrf5340/cpunet" if "$(BOARD)" = "nrf5340dk" + default "nrf5340_audio_dk/nrf5340/cpunet" if "$(BOARD)" = "nrf5340_audio_dk" + default "nrf5340bsim/nrf5340/cpunet" if $(BOARD_TARGET_STRING) = "NRF5340BSIM_NRF5340_CPUAPP" + +config NET_CORE_IMAGE_HCI_IPC + bool "HCI IPC image on network core" + default y + depends on NET_CORE_BOARD != "" diff --git a/samples/bluetooth/ccp_call_control_server/README.rst b/samples/bluetooth/ccp_call_control_server/README.rst new file mode 100644 index 0000000000000..eab3bbbdc0ab9 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/README.rst @@ -0,0 +1,77 @@ +.. zephyr:code-sample:: bluetooth_ccp_call_control_server + :name: Call Control Profile (CCP) Call Control Server + :relevant-api: bluetooth bt_ccp bt_tbs + + CCP Call Control Server sample that registers one or more TBS bearers and advertises the + TBS UUID(s). + +Overview +******** + +Application demonstrating the CCP Call Control Server functionality. +Starts by advertising for CCP Call Control Clients to connect and set up calls. + +The profile works for both GAP Central and GAP Peripheral devices, but this sample only assumes the +GAP Peripheral role. + +This sample can be found under :zephyr_file:`samples/bluetooth/ccp_call_control_server` in the Zephyr tree. + +Check the :zephyr:code-sample-category:`bluetooth` samples for general information. + +Requirements +************ + +* BlueZ running on the host, or +* A board with Bluetooth Low Energy 5.2 support + +Building and Running +******************** + +When building targeting an nrf52 series board with the Zephyr Bluetooth Controller, +use ``-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf`` to enable the required feature support. + +Building for an nrf5340dk +------------------------- + +You can build both the application core image and an appropriate controller image for the network +core with: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/ccp_call_control_server/ + :board: nrf5340dk/nrf5340/cpuapp + :goals: build + :west-args: --sysbuild + +If you prefer to only build the application core image, you can do so by doing instead: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/ccp_call_control_server/ + :board: nrf5340dk/nrf5340/cpuapp + :goals: build + +In that case you can pair this application core image with the +:zephyr:code-sample:`bluetooth_hci_ipc` sample +:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf` configuration. + +Building for a simulated nrf5340bsim +------------------------------------ + +Similarly to how you would for real HW, you can do: + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/ccp_call_control_server/ + :board: nrf5340bsim/nrf5340/cpuapp + :goals: build + :west-args: --sysbuild + +Note this will produce a Linux executable in :file:`./build/zephyr/zephyr.exe`. +For more information, check :ref:`this board documentation `. + +Building for a simulated nrf52_bsim +----------------------------------- + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/ccp_call_control_server/ + :board: nrf52_bsim + :goals: build + :gen-args: -DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf diff --git a/samples/bluetooth/ccp_call_control_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf b/samples/bluetooth/ccp_call_control_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf new file mode 100644 index 0000000000000..09fa41842ebd9 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/boards/nrf5340_audio_dk_nrf5340_cpuapp.conf @@ -0,0 +1,4 @@ +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 diff --git a/samples/bluetooth/ccp_call_control_server/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/bluetooth/ccp_call_control_server/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 0000000000000..09fa41842ebd9 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,4 @@ +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_BUF_CMD_TX_SIZE=255 diff --git a/samples/bluetooth/ccp_call_control_server/overlay-bt_ll_sw_split.conf b/samples/bluetooth/ccp_call_control_server/overlay-bt_ll_sw_split.conf new file mode 100644 index 0000000000000..6c1e35227169a --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/overlay-bt_ll_sw_split.conf @@ -0,0 +1,5 @@ +# Zephyr Bluetooth Controller +CONFIG_BT_LL_SW_SPLIT=y + +# Zephyr Controller tested maximum advertising data that can be set in a single HCI command +CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191 diff --git a/samples/bluetooth/ccp_call_control_server/prj.conf b/samples/bluetooth/ccp_call_control_server/prj.conf new file mode 100644 index 0000000000000..c05cd8850ab28 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/prj.conf @@ -0,0 +1,18 @@ +CONFIG_BT=y +CONFIG_LOG=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_AUDIO=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_SMP=y +CONFIG_BT_GATT_DYNAMIC_DB=y +CONFIG_BT_DEVICE_NAME="CCP Call Control Server" + +CONFIG_BT_SMP=y +CONFIG_BT_KEYS_OVERWRITE_OLDEST=y + +# CCP support +CONFIG_BT_CCP_CALL_CONTROL_SERVER=y +CONFIG_BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT=2 +CONFIG_BT_TBS=y +CONFIG_BT_TBS_BEARER_COUNT=1 +CONFIG_UTF8=y diff --git a/samples/bluetooth/ccp_call_control_server/sample.yaml b/samples/bluetooth/ccp_call_control_server/sample.yaml new file mode 100644 index 0000000000000..501c5b374210d --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/sample.yaml @@ -0,0 +1,30 @@ +sample: + description: Bluetooth Low Energy Call Control Profile Call Control Server sample + name: Bluetooth Low Energy Call Control Profile Call Control Server sample +tests: + sample.bluetooth.ccp_call_control_server: + harness: bluetooth + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + - nrf5340dk/nrf5340/cpuapp + - nrf5340bsim/nrf5340/cpuapp + integration_platforms: + - qemu_x86 + - nrf5340dk/nrf5340/cpuapp + tags: bluetooth + sysbuild: true + sample.bluetooth.ccp_call_control_server.bt_ll_sw_split: + harness: bluetooth + platform_allow: + - nrf52_bsim + - nrf52833dk/nrf52833 + - nrf52840dk/nrf52840 + - nrf52840dongle/nrf52840 + integration_platforms: + - nrf52_bsim + - nrf52833dk/nrf52833 + - nrf52840dk/nrf52840 + - nrf52840dongle/nrf52840 + extra_args: OVERLAY_CONFIG=overlay-bt_ll_sw_split.conf + tags: bluetooth diff --git a/samples/bluetooth/ccp_call_control_server/src/main.c b/samples/bluetooth/ccp_call_control_server/src/main.c new file mode 100644 index 0000000000000..df0c37b811f37 --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/src/main.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(ccp_call_control_server, CONFIG_LOG_DEFAULT_LEVEL); + +#define SEM_TIMEOUT K_SECONDS(5) + +static const struct bt_data ad[] = { + BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1), + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_SOME, BT_UUID_16_ENCODE(BT_UUID_GTBS_VAL)), + BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_GTBS_VAL)), + IF_ENABLED(CONFIG_BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT > 1, + (BT_DATA_BYTES(BT_DATA_UUID16_SOME, BT_UUID_16_ENCODE(BT_UUID_TBS_VAL)), + BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_TBS_VAL))))}; + +static struct bt_le_ext_adv *adv; +static struct bt_conn *peer_conn; +static struct bt_ccp_call_control_server_bearer + *bearers[CONFIG_BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT]; + +static K_SEM_DEFINE(sem_state_change, 0, 1); + +static void connected_cb(struct bt_conn *conn, uint8_t err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + (void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + LOG_INF("Connected: %s", addr); + + peer_conn = bt_conn_ref(conn); + k_sem_give(&sem_state_change); +} + +static void disconnected_cb(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != peer_conn) { + return; + } + + (void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + LOG_INF("Disconnected: %s (reason 0x%02x)", addr, reason); + + bt_conn_unref(peer_conn); + peer_conn = NULL; + k_sem_give(&sem_state_change); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected_cb, + .disconnected = disconnected_cb, +}; + +static int advertise(void) +{ + int err; + + err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN, NULL, &adv); + if (err) { + LOG_ERR("Failed to create advertising set: %d", err); + + return err; + } + + err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0); + if (err) { + LOG_ERR("Failed to set advertising data: %d", err); + + return err; + } + + err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err) { + LOG_ERR("Failed to start advertising set: %d", err); + + return err; + } + + LOG_INF("Advertising successfully started"); + + /* Wait for connection*/ + err = k_sem_take(&sem_state_change, K_FOREVER); + if (err != 0) { + LOG_ERR("Failed to take sem_state_change: err %d", err); + + return err; + } + + return 0; +} + +static int reset_ccp_call_control_server(void) +{ + int err; + + LOG_INF("Resetting"); + + if (peer_conn != NULL) { + err = bt_conn_disconnect(peer_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + if (err != 0) { + return err; + } + + err = k_sem_take(&sem_state_change, K_FOREVER); + if (err != 0) { + LOG_ERR("Failed to take sem_state_change: %d", err); + return err; + } + } + + if (adv != NULL) { + err = bt_le_ext_adv_stop(adv); + if (err != 0) { + LOG_ERR("Failed to stop advertiser: %d", err); + return err; + } + + err = bt_le_ext_adv_delete(adv); + if (err != 0) { + LOG_ERR("Failed to delete advertiser: %d", err); + return err; + } + + adv = NULL; + } + + k_sem_reset(&sem_state_change); + + return 0; +} + +static int init_ccp_call_control_server(void) +{ + const struct bt_tbs_register_param gtbs_param = { + .provider_name = "Generic TBS", + .uci = "un000", + .uri_schemes_supported = "tel,skype", + .gtbs = true, + .authorization_required = false, + .technology = BT_TBS_TECHNOLOGY_3G, + .supported_features = CONFIG_BT_TBS_SUPPORTED_FEATURES, + }; + int err; + + err = bt_enable(NULL); + if (err != 0) { + LOG_ERR("Bluetooth enable failed (err %d)", err); + + return err; + } + + LOG_DBG("Bluetooth initialized"); + + err = bt_ccp_call_control_server_register_bearer(>bs_param, &bearers[0]); + if (err < 0) { + LOG_ERR("Failed to register GTBS (err %d)", err); + + return err; + } + + LOG_INF("Registered GTBS bearer"); + + for (int i = 1; i < CONFIG_BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT; i++) { + char prov_name[22]; /* Enough to store "Telephone Bearer #255" */ + const struct bt_tbs_register_param tbs_param = { + .provider_name = prov_name, + .uci = "un000", + .uri_schemes_supported = "tel,skype", + .gtbs = false, + .authorization_required = false, + /* Set different technologies per bearer */ + .technology = (i % BT_TBS_TECHNOLOGY_WCDMA) + 1, + .supported_features = CONFIG_BT_TBS_SUPPORTED_FEATURES, + }; + + snprintf(prov_name, sizeof(prov_name), "Telephone Bearer #%d", i); + + err = bt_ccp_call_control_server_register_bearer(&tbs_param, &bearers[i]); + if (err < 0) { + LOG_ERR("Failed to register bearer[%d]: %d", i, err); + + return err; + } + + LOG_INF("Registered bearer[%d]", i); + } + + return 0; +} + +int main(void) +{ + int err; + + err = init_ccp_call_control_server(); + if (err != 0) { + return 0; + } + + LOG_INF("CCP Call Control Server initialized"); + + while (true) { + err = reset_ccp_call_control_server(); + if (err != 0) { + LOG_ERR("Failed to reset"); + + break; + } + + /* Start advertising as a CCP Call Control Server, which includes setting the + * required advertising data based on the roles we support. + */ + err = advertise(); + if (err != 0) { + continue; + } + + /* After advertising we expect CCP Call Control Clients to connect to us and + * eventually disconnect again. As a CCP Call Control Server we just react to their + * requests and not do anything else. + */ + + /* Reset if disconnected */ + err = k_sem_take(&sem_state_change, K_FOREVER); + if (err != 0) { + LOG_ERR("Failed to take sem_state_change: err %d", err); + + break; + } + } + + return 0; +} diff --git a/samples/bluetooth/ccp_call_control_server/sysbuild.cmake b/samples/bluetooth/ccp_call_control_server/sysbuild.cmake new file mode 100644 index 0000000000000..2523aac8ea76f --- /dev/null +++ b/samples/bluetooth/ccp_call_control_server/sysbuild.cmake @@ -0,0 +1,24 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) + # For builds in the nrf5340, we build the netcore image with the controller + + set(NET_APP hci_ipc) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_CONF_FILE + ${NET_APP_SRC_DIR}/nrf5340_cpunet_iso-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) +endif() + +native_simulator_set_final_executable(${DEFAULT_IMAGE}) diff --git a/samples/bluetooth/central/sample.yaml b/samples/bluetooth/central/sample.yaml index 973b48c7c0bb5..959a67491d42a 100644 --- a/samples/bluetooth/central/sample.yaml +++ b/samples/bluetooth/central/sample.yaml @@ -9,3 +9,15 @@ tests: tags: bluetooth integration_platforms: - qemu_cortex_m3 + sample.bluetooth.central.no_blobs: + extra_args: + - CONFIG_BUILD_ONLY_NO_BLOBS=y + platform_allow: + - esp32_devkitc_wroom/esp32/procpu + - esp32s3_devkitm/esp32s3/procpu + - esp32c3_devkitm + - sltb010a/efr32bg22c224f512im40 + - xg24_rb4187c/efr32mg24b220f1536im48 + - xg27_dk2602a/efr32bg27c140f768im40 + - xg29_rb4412a/efr32mg29b140f1024im40 + build_only: true diff --git a/samples/bluetooth/central_gatt_write/src/gatt_write_common.c b/samples/bluetooth/central_gatt_write/src/gatt_write_common.c index 7bd597e95dc13..99d2e830aea90 100644 --- a/samples/bluetooth/central_gatt_write/src/gatt_write_common.c +++ b/samples/bluetooth/central_gatt_write/src/gatt_write_common.c @@ -12,10 +12,137 @@ #include #include +/* Count down number of metrics intervals before performing a PHY update */ +#define PHY_UPDATE_COUNTDOWN 3U +static uint32_t phy_update_countdown; +static uint8_t phy_param_idx; + +static void phy_update_iterate(struct bt_conn *conn) +{ + const struct bt_conn_le_phy_param phy_param[] = { + /* List of 1M Tx with Rx on other PHYs */ + { + .options = BT_CONN_LE_PHY_OPT_NONE, + .pref_tx_phy = BT_GAP_LE_PHY_1M, + .pref_rx_phy = BT_GAP_LE_PHY_1M, + }, { + .options = BT_CONN_LE_PHY_OPT_NONE, + .pref_tx_phy = BT_GAP_LE_PHY_1M, + .pref_rx_phy = BT_GAP_LE_PHY_2M, + }, { + .options = BT_CONN_LE_PHY_OPT_NONE, + .pref_tx_phy = BT_GAP_LE_PHY_1M, + .pref_rx_phy = BT_GAP_LE_PHY_CODED, + }, + + /* List of 2M Tx with Rx on other PHYs */ + { + .options = BT_CONN_LE_PHY_OPT_NONE, + .pref_tx_phy = BT_GAP_LE_PHY_2M, + .pref_rx_phy = BT_GAP_LE_PHY_1M, + }, { + .options = BT_CONN_LE_PHY_OPT_NONE, + .pref_tx_phy = BT_GAP_LE_PHY_2M, + .pref_rx_phy = BT_GAP_LE_PHY_2M, + }, { + .options = BT_CONN_LE_PHY_OPT_NONE, + .pref_tx_phy = BT_GAP_LE_PHY_2M, + .pref_rx_phy = BT_GAP_LE_PHY_CODED, + }, + + /* List of Coded PHY S8 Tx with Rx on other PHYs */ + { + .options = BT_CONN_LE_PHY_OPT_CODED_S8, + .pref_tx_phy = BT_GAP_LE_PHY_CODED, + .pref_rx_phy = BT_GAP_LE_PHY_1M, + }, { + .options = BT_CONN_LE_PHY_OPT_CODED_S8, + .pref_tx_phy = BT_GAP_LE_PHY_CODED, + .pref_rx_phy = BT_GAP_LE_PHY_2M, + }, { + .options = BT_CONN_LE_PHY_OPT_CODED_S8, + .pref_tx_phy = BT_GAP_LE_PHY_CODED, + .pref_rx_phy = BT_GAP_LE_PHY_CODED, + }, + + /* List of Coded PHY S2 Tx with Rx on other PHYs */ + { + .options = BT_CONN_LE_PHY_OPT_CODED_S2, + .pref_tx_phy = BT_GAP_LE_PHY_CODED, + .pref_rx_phy = BT_GAP_LE_PHY_1M, + }, { + .options = BT_CONN_LE_PHY_OPT_CODED_S2, + .pref_tx_phy = BT_GAP_LE_PHY_CODED, + .pref_rx_phy = BT_GAP_LE_PHY_2M, + }, { + .options = BT_CONN_LE_PHY_OPT_CODED_S2, + .pref_tx_phy = BT_GAP_LE_PHY_CODED, + .pref_rx_phy = BT_GAP_LE_PHY_CODED, + }, + + /* Finally stop at 2M Tx with Rx on 2M */ + { + .options = BT_CONN_LE_PHY_OPT_NONE, + .pref_tx_phy = BT_GAP_LE_PHY_2M, + .pref_rx_phy = BT_GAP_LE_PHY_2M, + }, + }; + int err; + + if (phy_update_countdown--) { + return; + } + + phy_update_countdown = PHY_UPDATE_COUNTDOWN; + + phy_param_idx++; + if (phy_param_idx >= ARRAY_SIZE(phy_param)) { + /* No more PHY updates, stay at the last index */ + phy_param_idx = ARRAY_SIZE(phy_param); + return; + } + + struct bt_conn_info conn_info; + + err = bt_conn_get_info(conn, &conn_info); + if (err) { + printk("Failed to get connection info (%d).\n", err); + return; + } + + struct bt_conn_le_phy_param conn_phy_param; + + if (conn_info.role == BT_CONN_ROLE_CENTRAL) { + conn_phy_param.options = phy_param[phy_param_idx].options; + conn_phy_param.pref_tx_phy = phy_param[phy_param_idx].pref_tx_phy; + conn_phy_param.pref_rx_phy = phy_param[phy_param_idx].pref_rx_phy; + } else { + conn_phy_param.options = phy_param[phy_param_idx].options; + conn_phy_param.pref_tx_phy = phy_param[phy_param_idx].pref_rx_phy; + conn_phy_param.pref_rx_phy = phy_param[phy_param_idx].pref_tx_phy; + } + + printk("%s: PHY Update requested %u %u (%u)\n", __func__, + conn_phy_param.pref_tx_phy, + conn_phy_param.pref_rx_phy, + conn_phy_param.options); + + err = bt_conn_le_phy_update(conn, &conn_phy_param); + if (err) { + printk("Failed to update PHY (%d).\n", err); + return; + } +} + +/* Interval between storing the measured write rate */ +#define METRICS_INTERVAL 1U /* seconds */ + static struct bt_gatt_exchange_params mtu_exchange_params; static uint32_t write_count; static uint32_t write_len; static uint32_t write_rate; + +/* Globals, reused by central_gatt_write and peripheral_gatt_write samples */ struct bt_conn *conn_connected; uint32_t last_write_rate; void (*start_scan_func)(void); @@ -36,7 +163,7 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) /* if last data rx-ed was greater than 1 second in the past, * reset the metrics. */ - if (delta > (1U * NSEC_PER_SEC)) { + if (delta > (METRICS_INTERVAL * NSEC_PER_SEC)) { printk("%s: count= %u, len= %u, rate= %u bps.\n", __func__, write_count, write_len, write_rate); @@ -46,6 +173,11 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) write_len = 0U; write_rate = 0U; cycle_stamp = k_cycle_get_32(); + + if (IS_ENABLED(CONFIG_BT_USER_PHY_UPDATE)) { + phy_update_iterate(conn); + } + } else { uint16_t len; @@ -55,7 +187,7 @@ static void write_cmd_cb(struct bt_conn *conn, void *user_data) len = (uint32_t)user_data & 0xFFFF; write_len += len; - write_rate = ((uint64_t)write_len << 3) * (1U * NSEC_PER_SEC) / + write_rate = ((uint64_t)write_len << 3) * (METRICS_INTERVAL * NSEC_PER_SEC) / delta; } } @@ -119,6 +251,11 @@ static void connected(struct bt_conn *conn, uint8_t conn_err) } } #endif + + if (IS_ENABLED(CONFIG_BT_USER_PHY_UPDATE)) { + phy_update_countdown = PHY_UPDATE_COUNTDOWN; + phy_param_idx = 0U; + } } static void disconnected(struct bt_conn *conn, uint8_t reason) @@ -171,14 +308,50 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, } #endif +#if defined(CONFIG_BT_USER_PHY_UPDATE) +static void le_phy_updated(struct bt_conn *conn, + struct bt_conn_le_phy_info *param) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("LE PHY Updated: %s Tx 0x%x, Rx 0x%x\n", addr, param->tx_phy, + param->rx_phy); +} +#endif /* CONFIG_BT_USER_PHY_UPDATE */ + +#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE) +static void le_data_len_updated(struct bt_conn *conn, + struct bt_conn_le_data_len_info *info) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Data length updated: %s max tx %u (%u us) max rx %u (%u us)\n", + addr, info->tx_max_len, info->tx_max_time, info->rx_max_len, + info->rx_max_time); +} +#endif /* CONFIG_BT_USER_DATA_LEN_UPDATE */ + BT_CONN_CB_DEFINE(conn_callbacks) = { .connected = connected, .disconnected = disconnected, .le_param_req = le_param_req, .le_param_updated = le_param_updated, + #if defined(CONFIG_BT_SMP) .security_changed = security_changed, #endif + +#if defined(CONFIG_BT_USER_PHY_UPDATE) + .le_phy_updated = le_phy_updated, +#endif /* CONFIG_BT_USER_PHY_UPDATE */ + +#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE) + .le_data_len_updated = le_data_len_updated, +#endif /* CONFIG_BT_USER_DATA_LEN_UPDATE */ }; int write_cmd(struct bt_conn *conn) diff --git a/samples/bluetooth/central_ht/boards/frdm_rw612.conf b/samples/bluetooth/central_ht/boards/frdm_rw612.conf index 6bec2cd6b3781..2df782efc7115 100644 --- a/samples/bluetooth/central_ht/boards/frdm_rw612.conf +++ b/samples/bluetooth/central_ht/boards/frdm_rw612.conf @@ -1,2 +1 @@ CONFIG_PM=y -CONFIG_ENTROPY_GENERATOR=y diff --git a/samples/bluetooth/central_ht/boards/rd_rw612_bga.conf b/samples/bluetooth/central_ht/boards/rd_rw612_bga.conf index 6bec2cd6b3781..2df782efc7115 100644 --- a/samples/bluetooth/central_ht/boards/rd_rw612_bga.conf +++ b/samples/bluetooth/central_ht/boards/rd_rw612_bga.conf @@ -1,2 +1 @@ CONFIG_PM=y -CONFIG_ENTROPY_GENERATOR=y diff --git a/samples/bluetooth/central_ht/sample.yaml b/samples/bluetooth/central_ht/sample.yaml index b145c5262230b..2219cac36739f 100644 --- a/samples/bluetooth/central_ht/sample.yaml +++ b/samples/bluetooth/central_ht/sample.yaml @@ -19,4 +19,4 @@ tests: - rd_rw612_bga - frdm_rw612 extra_configs: - - CONFIG_NXP_MONOLITHIC_BT=n + - CONFIG_NXP_MONOLITHIC_NBU=n diff --git a/samples/bluetooth/central_multilink/README.rst b/samples/bluetooth/central_multilink/README.rst index 61d64d7980652..2b31c6f614d0e 100644 --- a/samples/bluetooth/central_multilink/README.rst +++ b/samples/bluetooth/central_multilink/README.rst @@ -8,7 +8,7 @@ Overview ******** Application demonstrating Bluetooth LE Central role functionality by scanning for other -BLE devices and establishing connection to up to 62 peripherals with a strong +Bluetooth LE devices and establishing connection to up to 62 peripherals with a strong enough signal. Requirements diff --git a/samples/bluetooth/central_multilink/src/central_multilink.c b/samples/bluetooth/central_multilink/src/central_multilink.c index 26a2e674ce774..f070ec56230d1 100644 --- a/samples/bluetooth/central_multilink/src/central_multilink.c +++ b/samples/bluetooth/central_multilink/src/central_multilink.c @@ -20,8 +20,8 @@ #include #include -#define SCAN_INTERVAL 0x0640 /* 1000 ms */ -#define SCAN_WINDOW 0x0030 /* 30 ms */ +#define SCAN_INTERVAL 0x0010 /* 10 ms */ +#define SCAN_WINDOW 0x0010 /* 10 ms */ #define INIT_INTERVAL 0x0010 /* 10 ms */ #define INIT_WINDOW 0x0010 /* 10 ms */ #define CONN_INTERVAL 0x0320 /* 1000 ms */ @@ -32,6 +32,7 @@ static void start_scan(void); static struct bt_conn *conn_connecting; +static uint8_t conn_count_max; static uint8_t volatile conn_count; static bool volatile is_disconnecting; @@ -74,8 +75,9 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, return; } - if (bt_le_scan_stop()) { - printk("Scanning successfully stopped\n"); + err = bt_le_scan_stop(); + if (err != 0) { + printk("Failed to stop scanning (err %d)\n", err); return; } @@ -157,7 +159,7 @@ static void connected(struct bt_conn *conn, uint8_t reason) conn_connecting = NULL; conn_count++; - if (conn_count < CONFIG_BT_MAX_CONN) { + if (conn_count < conn_count_max) { start_scan(); } @@ -186,7 +188,7 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) bt_conn_unref(conn); - if ((conn_count == 1U) && is_disconnecting) { + if ((conn_count == 1U) && (is_disconnecting || (reason == BT_HCI_ERR_CONN_FAIL_TO_ESTAB))) { is_disconnecting = false; start_scan(); } @@ -280,6 +282,27 @@ static struct bt_conn_cb conn_callbacks = { #endif /* CONFIG_BT_USER_DATA_LEN_UPDATE */ }; +static void remote_info(struct bt_conn *conn, void *data) +{ + struct bt_conn_remote_info remote_info; + char addr[BT_ADDR_LE_STR_LEN]; + int err; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Get remote info %s...\n", addr); + err = bt_conn_get_remote_info(conn, &remote_info); + if (err) { + printk("Failed remote info %s.\n", addr); + return; + } + printk("success.\n"); + + uint8_t *actual_count = (void *)data; + + (*actual_count)++; +} + static void disconnect(struct bt_conn *conn, void *data) { char addr[BT_ADDR_LE_STR_LEN]; @@ -291,14 +314,17 @@ static void disconnect(struct bt_conn *conn, void *data) err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); if (err) { printk("Failed disconnection %s.\n", addr); + return; } printk("success.\n"); } -int init_central(uint8_t iterations) +int init_central(uint8_t max_conn, uint8_t iterations) { int err; + conn_count_max = max_conn; + err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); @@ -312,10 +338,27 @@ int init_central(uint8_t iterations) start_scan(); while (true) { - while (conn_count < CONFIG_BT_MAX_CONN) { + while (conn_count < conn_count_max) { + k_sleep(K_MSEC(10)); + } + + is_disconnecting = true; + + /* Let us perform version exchange on all connections to ensure + * there is actual communication. + */ + uint8_t actual_count = 0U; + + bt_conn_foreach(BT_CONN_TYPE_LE, remote_info, &actual_count); + if (actual_count < conn_count_max) { k_sleep(K_MSEC(10)); + + continue; } + /* Lets wait sufficiently to ensure a stable connection + * before starting to disconnect for next iteration. + */ k_sleep(K_SECONDS(60)); if (!iterations) { @@ -324,9 +367,15 @@ int init_central(uint8_t iterations) iterations--; printk("Iterations remaining: %u\n", iterations); - printk("Disconnecting all...\n"); - is_disconnecting = true; - bt_conn_foreach(BT_CONN_TYPE_LE, disconnect, NULL); + /* Device needing multiple connections is the one + * initiating the disconnects. + */ + if (conn_count_max > 1U) { + printk("Disconnecting all...\n"); + bt_conn_foreach(BT_CONN_TYPE_LE, disconnect, NULL); + } else { + printk("Wait for disconnections...\n"); + } while (is_disconnecting) { k_sleep(K_MSEC(10)); diff --git a/samples/bluetooth/central_multilink/src/main.c b/samples/bluetooth/central_multilink/src/main.c index bc82cd1168602..5adf243079f82 100644 --- a/samples/bluetooth/central_multilink/src/main.c +++ b/samples/bluetooth/central_multilink/src/main.c @@ -8,10 +8,10 @@ #include -int init_central(uint8_t iterations); +int init_central(uint8_t max_conn, uint8_t iterations); int main(void) { - (void)init_central(CONFIG_SAMPLE_CONN_ITERATIONS); + (void)init_central(CONFIG_BT_MAX_CONN, CONFIG_SAMPLE_CONN_ITERATIONS); return 0; } diff --git a/samples/bluetooth/central_otc/prj.conf b/samples/bluetooth/central_otc/prj.conf index b7a9d929e909f..443fbf38a626a 100644 --- a/samples/bluetooth/central_otc/prj.conf +++ b/samples/bluetooth/central_otc/prj.conf @@ -10,3 +10,4 @@ CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192 CONFIG_LOG=y CONFIG_ASSERT=y CONFIG_BT_L2CAP_TX_BUF_COUNT=8 +CONFIG_GPIO=y diff --git a/samples/bluetooth/central_past/src/main.c b/samples/bluetooth/central_past/src/main.c index d79277bf6b375..affb0486d3fa4 100644 --- a/samples/bluetooth/central_past/src/main.c +++ b/samples/bluetooth/central_past/src/main.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/bluetooth/handsfree/boards/mimxrt1040_evk_mimxrt1042.conf b/samples/bluetooth/handsfree/boards/mimxrt1040_evk_mimxrt1042.conf index 9e8851c73af1b..0dfb6c0bc0220 100644 --- a/samples/bluetooth/handsfree/boards/mimxrt1040_evk_mimxrt1042.conf +++ b/samples/bluetooth/handsfree/boards/mimxrt1040_evk_mimxrt1042.conf @@ -1,2 +1,2 @@ -#select NXP NW612 Chipset +#select NXP NW612 firmware for IW612 Chipset CONFIG_BT_NXP_NW612=y diff --git a/samples/bluetooth/handsfree_ag/src/main.c b/samples/bluetooth/handsfree_ag/src/main.c index 84d118802717d..a87608c6eaafb 100644 --- a/samples/bluetooth/handsfree_ag/src/main.c +++ b/samples/bluetooth/handsfree_ag/src/main.c @@ -111,7 +111,8 @@ static struct bt_hfp_ag_cb ag_cb = { .terminate = ag_terminate, }; -static uint8_t sdp_discover_cb(struct bt_conn *conn, struct bt_sdp_client_result *result) +static uint8_t sdp_discover_cb(struct bt_conn *conn, struct bt_sdp_client_result *result, + const struct bt_sdp_discover_params *params) { int err; uint16_t value; @@ -136,6 +137,7 @@ static uint8_t sdp_discover_cb(struct bt_conn *conn, struct bt_sdp_client_result } static struct bt_sdp_discover_params sdp_discover = { + .type = BT_SDP_DISCOVER_SERVICE_SEARCH_ATTR, .func = sdp_discover_cb, .pool = &sdp_discover_pool, .uuid = BT_UUID_DECLARE_16(BT_SDP_HANDSFREE_SVCLASS), diff --git a/samples/bluetooth/hap_ha/boards/native_sim.conf b/samples/bluetooth/hap_ha/boards/native_sim.conf index f6c82a5dfbba1..eff540ab4cf14 100644 --- a/samples/bluetooth/hap_ha/boards/native_sim.conf +++ b/samples/bluetooth/hap_ha/boards/native_sim.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y # For LE-audio at 10ms intervals we need the tick counter to occur more frequently # than every 10 ms as each PDU for some reason takes 2 ticks to process. diff --git a/samples/bluetooth/hap_ha/prj.conf b/samples/bluetooth/hap_ha/prj.conf index efd5a4004f9e4..8260f2cb12a89 100644 --- a/samples/bluetooth/hap_ha/prj.conf +++ b/samples/bluetooth/hap_ha/prj.conf @@ -2,7 +2,6 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_ISO_PERIPHERAL=y CONFIG_BT_PRIVACY=y -CONFIG_BT_GATT_CACHING=y CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_GATT_CLIENT=y CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index 6c8cd6fd862a2..b6f9658fc61f0 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -6,17 +6,28 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include +#include +#include +#include -#include -#include -#include - +#include +#include #include #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), @@ -405,6 +416,20 @@ static struct bt_pacs_cap cap_source = { int bap_unicast_sr_init(void) { + const struct bt_pacs_register_param pacs_param = { + .snk_pac = true, + .snk_loc = true, + .src_pac = true, + .src_loc = true, + }; + int err; + + err = bt_pacs_register(&pacs_param); + if (err) { + printk("Could not register PACS (err %d)\n", err); + return err; + } + bt_bap_unicast_server_register(¶m); bt_bap_unicast_server_register_cb(&unicast_server_cb); diff --git a/samples/bluetooth/hap_ha/src/ccp_call_ctrl.c b/samples/bluetooth/hap_ha/src/ccp_call_ctrl.c index dcf1c4dffb4fe..82da06d7f0818 100644 --- a/samples/bluetooth/hap_ha/src/ccp_call_ctrl.c +++ b/samples/bluetooth/hap_ha/src/ccp_call_ctrl.c @@ -6,14 +6,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include -#include -#include -#include - +#include #include #include #include +#include +#include +#include +#include enum { CCP_FLAG_PROFILE_CONNECTED, diff --git a/samples/bluetooth/hap_ha/src/csip_set_member.c b/samples/bluetooth/hap_ha/src/csip_set_member.c index 962ac3579dad7..d3b258e7edf09 100644 --- a/samples/bluetooth/hap_ha/src/csip_set_member.c +++ b/samples/bluetooth/hap_ha/src/csip_set_member.c @@ -5,12 +5,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include +#include +#include -#include -#include - +#include #include #include +#include +#include +#include #define CSIP_SIRK_DEBUG { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce, \ 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 } diff --git a/samples/bluetooth/hap_ha/src/hap_ha.h b/samples/bluetooth/hap_ha/src/hap_ha.h index e4964035355cc..5e1915c970a0d 100644 --- a/samples/bluetooth/hap_ha/src/hap_ha.h +++ b/samples/bluetooth/hap_ha/src/hap_ha.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include /** * @brief Initialize the BAP Unicast Server role diff --git a/samples/bluetooth/hap_ha/src/has_server.c b/samples/bluetooth/hap_ha/src/has_server.c index b23b5a3c9a603..5faf24735d954 100644 --- a/samples/bluetooth/hap_ha/src/has_server.c +++ b/samples/bluetooth/hap_ha/src/has_server.c @@ -5,12 +5,15 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include +#include +#include +#include #include #include #include - -#include +#include #define PRESET_INDEX_UNIVERSAL 1 #define PRESET_INDEX_OUTDOOR 5 diff --git a/samples/bluetooth/hap_ha/src/main.c b/samples/bluetooth/hap_ha/src/main.c index 586ed60046919..6053ccf0d6dc6 100644 --- a/samples/bluetooth/hap_ha/src/main.c +++ b/samples/bluetooth/hap_ha/src/main.c @@ -3,10 +3,8 @@ * * SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include +#include +#include #include #include @@ -15,7 +13,15 @@ #include #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include #include "hap_ha.h" diff --git a/samples/bluetooth/hap_ha/src/micp_mic_dev.c b/samples/bluetooth/hap_ha/src/micp_mic_dev.c index bd36c587002bf..e579836ced61b 100644 --- a/samples/bluetooth/hap_ha/src/micp_mic_dev.c +++ b/samples/bluetooth/hap_ha/src/micp_mic_dev.c @@ -8,13 +8,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include +#include #include +#include +#include #include #include +#include +#include +#include static void micp_mic_dev_mute_cb(uint8_t mute) { diff --git a/samples/bluetooth/hap_ha/src/vcp_vol_renderer.c b/samples/bluetooth/hap_ha/src/vcp_vol_renderer.c index 4e2c47744e7c9..cfe7e1f6470de 100644 --- a/samples/bluetooth/hap_ha/src/vcp_vol_renderer.c +++ b/samples/bluetooth/hap_ha/src/vcp_vol_renderer.c @@ -8,13 +8,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include +#include #include +#include +#include +#include #include #include +#include +#include +#include static struct bt_vcp_included vcp_included; diff --git a/samples/bluetooth/hci_spi/prj.conf b/samples/bluetooth/hci_spi/prj.conf index 68c1cdb5a083f..fbab977c26656 100644 --- a/samples/bluetooth/hci_spi/prj.conf +++ b/samples/bluetooth/hci_spi/prj.conf @@ -5,7 +5,6 @@ CONFIG_MAIN_STACK_SIZE=512 CONFIG_BT=y CONFIG_BT_HCI_RAW=y CONFIG_BT_MAX_CONN=16 -CONFIG_BT_SEND_ECC_EMULATION=n # Workaround: Unable to allocate command buffer when using K_NO_WAIT since # Host number of completed commands does not follow normal flow control. diff --git a/samples/bluetooth/hci_uart/README.rst b/samples/bluetooth/hci_uart/README.rst index 5c5ab8b7198ac..2260c7e0d29b6 100644 --- a/samples/bluetooth/hci_uart/README.rst +++ b/samples/bluetooth/hci_uart/README.rst @@ -33,11 +33,11 @@ Zephyr tree, and it is built as a standard Zephyr application. Using the controller with emulators and BlueZ ********************************************* -The instructions below show how to use a Nordic nRF5x device as a Zephyr BLE +The instructions below show how to use a Nordic nRF5x device as a Zephyr Bluetooth controller and expose it to Linux's BlueZ. This can be very useful for testing the Zephyr Link Layer with the BlueZ Host. The Zephyr Bluetooth LE controller can also provide a modern Bluetooth LE 5.0 controller to a Linux-based machine for native -BLE support or QEMU-based development. +Bluetooth support or QEMU-based development. First, make sure you have a recent BlueZ version installed by following the instructions in the :ref:`bluetooth_bluez` section. diff --git a/samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp.overlay b/samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp.overlay new file mode 100644 index 0000000000000..fde3e0775dd3b --- /dev/null +++ b/samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&uart30 { + compatible = "nordic,nrf-uarte"; + current-speed = <1000000>; + status = "okay"; + hw-flow-control; +}; diff --git a/samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp_df.overlay b/samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp_df.overlay new file mode 100644 index 0000000000000..0d2af26d4ed7b --- /dev/null +++ b/samples/bluetooth/hci_uart/boards/panb511evb_nrf54l15_cpuapp_df.overlay @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Panasonic Industrial Devices Europe GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&uart30 { + compatible = "nordic,nrf-uarte"; + current-speed = <1000000>; + status = "okay"; + hw-flow-control; +}; + +&radio { + status = "okay"; + /* This is an example number of antennas that may be available + * on antenna matrix board. + */ + dfe-antenna-num = <10>; + /* This is an example switch pattern that will be used to set an + * antenna for Tx PDU (period before start of Tx CTE). + */ + dfe-pdu-antenna = <0x0>; + + /* These are example GPIO pin numbers that are provided to + * Radio peripheral. The pins will be acquired by Radio to + * drive antenna switching when AoD is enabled. + */ + dfegpio0-gpios = <&gpio1 4 0>; + dfegpio1-gpios = <&gpio1 5 0>; + dfegpio2-gpios = <&gpio1 6 0>; + dfegpio3-gpios = <&gpio1 7 0>; +}; diff --git a/samples/bluetooth/hci_uart/prj.conf b/samples/bluetooth/hci_uart/prj.conf index 036a97489104d..bb4a25b2886b0 100644 --- a/samples/bluetooth/hci_uart/prj.conf +++ b/samples/bluetooth/hci_uart/prj.conf @@ -13,7 +13,6 @@ CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 CONFIG_BT_CTLR_ASSERT_HANDLER=y CONFIG_BT_MAX_CONN=16 -CONFIG_BT_SEND_ECC_EMULATION=n CONFIG_BT_CTLR_DTM_HCI=y CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 diff --git a/samples/bluetooth/hci_uart/src/main.c b/samples/bluetooth/hci_uart/src/main.c index a2baa89ba67c4..322291e37399e 100644 --- a/samples/bluetooth/hci_uart/src/main.c +++ b/samples/bluetooth/hci_uart/src/main.c @@ -54,7 +54,7 @@ static K_FIFO_DEFINE(uart_tx_queue); #define ST_DISCARD 3 /* Dropping packet. */ /* Length of a discard/flush buffer. - * This is sized to align with a BLE HCI packet: + * This is sized to align with a Bluetooth HCI packet: * 1 byte H:4 header + 32 bytes ACL/event data * Bigger values might overflow the stack since this is declared as a local * variable, smaller ones will force the caller to call into discard more @@ -232,17 +232,19 @@ static void bt_uart_isr(const struct device *unused, void *user_data) ARG_UNUSED(unused); ARG_UNUSED(user_data); - if (!(uart_irq_rx_ready(hci_uart_dev) || - uart_irq_tx_ready(hci_uart_dev))) { - LOG_DBG("spurious interrupt"); - } + while (uart_irq_update(hci_uart_dev) && uart_irq_is_pending(hci_uart_dev)) { + if (!(uart_irq_rx_ready(hci_uart_dev) || + uart_irq_tx_ready(hci_uart_dev))) { + LOG_DBG("spurious interrupt"); + } - if (uart_irq_tx_ready(hci_uart_dev)) { - tx_isr(); - } + if (uart_irq_tx_ready(hci_uart_dev)) { + tx_isr(); + } - if (uart_irq_rx_ready(hci_uart_dev)) { - rx_isr(); + if (uart_irq_rx_ready(hci_uart_dev)) { + rx_isr(); + } } } diff --git a/samples/bluetooth/hci_uart_3wire/README.rst b/samples/bluetooth/hci_uart_3wire/README.rst index df99c17c0a846..b846c9892fd8f 100644 --- a/samples/bluetooth/hci_uart_3wire/README.rst +++ b/samples/bluetooth/hci_uart_3wire/README.rst @@ -33,11 +33,11 @@ Zephyr tree, and it is built as a standard Zephyr application. Using the controller with emulators and BlueZ ********************************************* -The instructions below show how to use a Nordic nRF5x device as a Zephyr BLE +The instructions below show how to use a Nordic nRF5x device as a Zephyr Bluetooth controller and expose it to Linux's BlueZ. This can be very useful for testing the Zephyr Link Layer with the BlueZ Host. The Zephyr Bluetooth LE controller can also provide a modern Bluetooth LE 5.0 controller to a Linux-based machine for native -BLE support or QEMU-based development. +Bluetooth support or QEMU-based development. First, make sure you have a recent BlueZ version installed by following the instructions in the :ref:`bluetooth_bluez` section. @@ -146,11 +146,6 @@ You can use following targets: Check the :zephyr:code-sample:`ble_direction_finding_connectionless_rx` and the :zephyr:code-sample:`ble_direction_finding_connectionless_tx` for more details. -Using a USB CDC ACM UART -======================== - -The sample can be configured to use a USB UART instead. See :zephyr_file:`samples/bluetooth/hci_uart_3wire/boards/nrf52840dongle_nrf52840.conf`. - Using the controller with the Zephyr host ========================================= diff --git a/samples/bluetooth/hci_uart_3wire/boards/nrf52840dongle_nrf52840.conf b/samples/bluetooth/hci_uart_3wire/boards/nrf52840dongle_nrf52840.conf deleted file mode 100644 index f87530dd3c2c7..0000000000000 --- a/samples/bluetooth/hci_uart_3wire/boards/nrf52840dongle_nrf52840.conf +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="Zephyr HCI UART 3Wire sample" -CONFIG_USB_CDC_ACM=y -CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n diff --git a/samples/bluetooth/hci_uart_3wire/prj.conf b/samples/bluetooth/hci_uart_3wire/prj.conf index 670bcec3234da..d9a03554f9fd3 100644 --- a/samples/bluetooth/hci_uart_3wire/prj.conf +++ b/samples/bluetooth/hci_uart_3wire/prj.conf @@ -12,7 +12,6 @@ CONFIG_BT_BUF_ACL_RX_SIZE=255 CONFIG_BT_BUF_CMD_TX_SIZE=255 CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255 CONFIG_BT_MAX_CONN=16 -CONFIG_BT_SEND_ECC_EMULATION=n CONFIG_BT_CTLR_DTM_HCI=y CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 diff --git a/samples/bluetooth/hci_uart_3wire/src/main.c b/samples/bluetooth/hci_uart_3wire/src/main.c index 5454b0cd9c7c6..7cfbe39dc3e07 100644 --- a/samples/bluetooth/hci_uart_3wire/src/main.c +++ b/samples/bluetooth/hci_uart_3wire/src/main.c @@ -20,8 +20,6 @@ #include #include -#include - #include #include #include @@ -751,13 +749,6 @@ static int hci_uart_init(void) { LOG_DBG(""); - if (IS_ENABLED(CONFIG_USB_CDC_ACM)) { - if (usb_enable(NULL)) { - LOG_ERR("Failed to enable USB"); - return -EINVAL; - } - } - if (!device_is_ready(h5_dev)) { LOG_ERR("HCI UART %s is not ready", h5_dev->name); return -EINVAL; diff --git a/samples/bluetooth/hci_uart_async/README.rst b/samples/bluetooth/hci_uart_async/README.rst index ce1a369b2fc19..7787741683302 100644 --- a/samples/bluetooth/hci_uart_async/README.rst +++ b/samples/bluetooth/hci_uart_async/README.rst @@ -36,7 +36,7 @@ in the Zephyr tree and is built as a standard Zephyr application. Using the controller with emulators and BlueZ ********************************************* -The instructions below show how to use a Nordic nRF5x device as a Zephyr BLE +The instructions below show how to use a Nordic nRF5x device as a Zephyr Bluetooth controller and expose it to Linux's BlueZ. First, make sure you have a recent BlueZ version installed by following the diff --git a/samples/bluetooth/hci_usb_h4/CMakeLists.txt b/samples/bluetooth/hci_usb_h4/CMakeLists.txt deleted file mode 100644 index 55b3476ec2e5e..0000000000000 --- a/samples/bluetooth/hci_usb_h4/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(hci_usb_h4) - -target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/hci_usb_h4/README.rst b/samples/bluetooth/hci_usb_h4/README.rst deleted file mode 100644 index dbce1c85cb1ba..0000000000000 --- a/samples/bluetooth/hci_usb_h4/README.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. zephyr:code-sample:: bluetooth_hci_usb_h4 - :name: HCI H4 over USB - :relevant-api: hci_raw bluetooth _usb_device_core_api usbd_api - - Turn a Zephyr board into a USB H4 Bluetooth dongle (Linux/BlueZ only). - -Overview -******** - -Make a USB H4 Bluetooth dongle out of Zephyr. Requires USB device support from -the board it runs on (e.g. :ref:`nrf52840dk_nrf52840` supports both Bluetooth LE and -USB). - -Requirements -************ - -* Bluetooth stack running on the host (e.g. BlueZ) -* A board with Bluetooth and USB support in Zephyr - -Building and Running -******************** -This sample can be found under :zephyr_file:`samples/bluetooth/hci_usb_h4` in -the Zephyr tree. - -See :zephyr:code-sample-category:`bluetooth` samples for details. diff --git a/samples/bluetooth/hci_usb_h4/prj.conf b/samples/bluetooth/hci_usb_h4/prj.conf deleted file mode 100644 index 77f48fca5a207..0000000000000 --- a/samples/bluetooth/hci_usb_h4/prj.conf +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG_STDOUT_CONSOLE=y -CONFIG_GPIO=y -CONFIG_SERIAL=y -CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n - -CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PID=0x000C -CONFIG_USB_DEVICE_BT_H4=y - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -CONFIG_BT_BUF_CMD_TX_COUNT=10 diff --git a/samples/bluetooth/hci_usb_h4/sample.yaml b/samples/bluetooth/hci_usb_h4/sample.yaml deleted file mode 100644 index dd62b9b8397cf..0000000000000 --- a/samples/bluetooth/hci_usb_h4/sample.yaml +++ /dev/null @@ -1,15 +0,0 @@ -sample: - name: Bluetooth over USB sample -tests: - sample.bluetooth.hci_usb_h4: - harness: bluetooth - depends_on: - - usb_device - - ble - tags: - - usb - - bluetooth - # FIXME: exclude due to build error - platform_exclude: - - 96b_carbon/stm32f401xe - - stm32l562e_dk diff --git a/samples/bluetooth/hci_usb_h4/src/main.c b/samples/bluetooth/hci_usb_h4/src/main.c deleted file mode 100644 index aaef82a58499f..0000000000000 --- a/samples/bluetooth/hci_usb_h4/src/main.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -int main(void) -{ - int ret; - - ret = usb_enable(NULL); - if (ret != 0) { - printk("Failed to enable USB"); - return 0; - } - - printk("Bluetooth H:4 over USB sample\n"); - return 0; -} diff --git a/samples/bluetooth/iso_broadcast_benchmark/sample.yaml b/samples/bluetooth/iso_broadcast_benchmark/sample.yaml index d9804ac7029e2..cb8b5d76e20d5 100644 --- a/samples/bluetooth/iso_broadcast_benchmark/sample.yaml +++ b/samples/bluetooth/iso_broadcast_benchmark/sample.yaml @@ -1,5 +1,5 @@ sample: - name: BLE ISO Broadcast + name: Bluetooth LE ISO Broadcast description: Bluetooth Low Energy ISO Broadcast Benchmark sample tests: sample.bluetooth.iso_broadcast_benchmark: diff --git a/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c b/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c index 2f03528093fb6..4665eed3ca870 100644 --- a/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c +++ b/samples/bluetooth/iso_broadcast_benchmark/src/broadcaster.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -86,7 +87,7 @@ static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason) chan, reason); connected_bis--; - if (connected_bis == big_create_param.num_bis) { + if (connected_bis == 0) { k_sem_give(&sem_big_term); } } @@ -681,7 +682,7 @@ static int create_big(struct bt_le_ext_adv **adv, struct bt_iso_big **big) err = bt_le_ext_adv_set_data(*adv, ad, ARRAY_SIZE(ad), NULL, 0); if (err) { LOG_ERR("Failed to set advertising data (err %d)", err); - return 0; + return err; } LOG_INF("Setting Periodic Advertising parameters"); @@ -739,32 +740,41 @@ static int delete_big(struct bt_le_ext_adv **adv, struct bt_iso_big **big) { int err; - err = bt_iso_big_terminate(*big); - if (err != 0) { - LOG_ERR("Failed to terminate BIG (err %d)", err); - return err; + if (*big != NULL) { + err = bt_iso_big_terminate(*big); + if (err != 0) { + LOG_ERR("Failed to terminate BIG (err %d)", err); + return err; + } + err = k_sem_take(&sem_big_term, K_FOREVER); + if (err != 0) { + LOG_ERR("failed to take sem_big_term (err %d)", err); + return err; + } + *big = NULL; } - *big = NULL; - err = bt_le_per_adv_stop(*adv); - if (err != 0) { - LOG_ERR("Failed to stop periodic advertising (err %d)", err); - return err; - } + if (*adv != NULL) { + err = bt_le_per_adv_stop(*adv); + if (err != 0) { + LOG_ERR("Failed to stop periodic advertising (err %d)", err); + return err; + } - err = bt_le_ext_adv_stop(*adv); - if (err != 0) { - LOG_ERR("Failed to stop advertising (err %d)", err); - return err; - } + err = bt_le_ext_adv_stop(*adv); + if (err != 0) { + LOG_ERR("Failed to stop advertising (err %d)", err); + return err; + } - err = bt_le_ext_adv_delete(*adv); - if (err != 0) { - LOG_ERR("Failed to delete advertiser (err %d)", err); - return err; - } + err = bt_le_ext_adv_delete(*adv); + if (err != 0) { + LOG_ERR("Failed to delete advertiser (err %d)", err); + return err; + } - *adv = NULL; + *adv = NULL; + } return 0; } @@ -810,7 +820,15 @@ int test_run_broadcaster(void) err = create_big(&adv, &big); if (err) { + int del_err; + LOG_ERR("Could not create BIG: %d", err); + + del_err = delete_big(&adv, &big); + if (del_err) { + LOG_ERR("Could not delete BIG: %d", del_err); + } + return err; } diff --git a/samples/bluetooth/iso_connected_benchmark/prj.conf b/samples/bluetooth/iso_connected_benchmark/prj.conf index eb099a3497aba..09781083adbc5 100644 --- a/samples/bluetooth/iso_connected_benchmark/prj.conf +++ b/samples/bluetooth/iso_connected_benchmark/prj.conf @@ -15,5 +15,3 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_LOG=y CONFIG_CBPRINTF_FP_SUPPORT=y CONFIG_LOG_BUFFER_SIZE=2048 - -CONFIG_ENTROPY_GENERATOR=y diff --git a/samples/bluetooth/iso_connected_benchmark/sample.yaml b/samples/bluetooth/iso_connected_benchmark/sample.yaml index fd4eb7d9615b4..c2a82196e1987 100644 --- a/samples/bluetooth/iso_connected_benchmark/sample.yaml +++ b/samples/bluetooth/iso_connected_benchmark/sample.yaml @@ -1,5 +1,5 @@ sample: - name: BLE ISO Connected + name: Bluetooth LE ISO Connected description: Bluetooth Low Energy ISO Connected Benchmark sample tests: sample.bluetooth.iso_connected_benchmark: diff --git a/samples/bluetooth/iso_receive/Kconfig b/samples/bluetooth/iso_receive/Kconfig index 22e164ebfe4b3..e7989ff4c1126 100644 --- a/samples/bluetooth/iso_receive/Kconfig +++ b/samples/bluetooth/iso_receive/Kconfig @@ -18,3 +18,9 @@ config ISO_ALIGN_PRINT_INTERVALS Align interval-counter with packet number from incoming ISO packets. This may be needed if report printouts are to be synchronized between the iso_broadcast sample and the iso_receive sample. + +config ISO_BLINK_LED0 + bool "Blink led0" + depends on $(dt_alias_enabled,led0) + select GPIO + default y diff --git a/samples/bluetooth/iso_receive/src/main.c b/samples/bluetooth/iso_receive/src/main.c index b7714e08b2185..e51bbe6d34be1 100644 --- a/samples/bluetooth/iso_receive/src/main.c +++ b/samples/bluetooth/iso_receive/src/main.c @@ -42,9 +42,8 @@ static K_SEM_DEFINE(sem_big_sync_lost, 0, BIS_ISO_CHAN_COUNT); /* The devicetree node identifier for the "led0" alias. */ #define LED0_NODE DT_ALIAS(led0) -#if DT_NODE_HAS_STATUS_OKAY(LED0_NODE) +#ifdef CONFIG_ISO_BLINK_LED0 static const struct gpio_dt_spec led_gpio = GPIO_DT_SPEC_GET(LED0_NODE, gpios); -#define HAS_LED 1 #define BLINK_ONOFF K_MSEC(500) static struct k_work_delayable blink_work; @@ -303,7 +302,7 @@ int main(void) printk("Starting Synchronized Receiver Demo\n"); -#if defined(HAS_LED) +#ifdef CONFIG_ISO_BLINK_LED0 printk("Get reference to LED device..."); if (!gpio_is_ready_dt(&led_gpio)) { @@ -320,7 +319,7 @@ int main(void) printk("done.\n"); k_work_init_delayable(&blink_work, blink_timeout); -#endif /* HAS_LED */ +#endif /* CONFIG_ISO_BLINK_LED0 */ /* Initialize the Bluetooth Subsystem */ err = bt_enable(NULL); @@ -349,13 +348,13 @@ int main(void) } printk("success.\n"); -#if defined(HAS_LED) +#ifdef CONFIG_ISO_BLINK_LED0 printk("Start blinking LED...\n"); led_is_on = false; blink = true; gpio_pin_set_dt(&led_gpio, (int)led_is_on); k_work_reschedule(&blink_work, BLINK_ONOFF); -#endif /* HAS_LED */ +#endif /* CONFIG_ISO_BLINK_LED0 */ printk("Waiting for periodic advertising...\n"); per_adv_found = false; @@ -456,7 +455,7 @@ int main(void) } printk("BIG sync established.\n"); -#if defined(HAS_LED) +#ifdef CONFIG_ISO_BLINK_LED0 printk("Stop blinking LED.\n"); blink = false; /* If this fails, we'll exit early in the handler because blink @@ -467,7 +466,7 @@ int main(void) /* Keep LED on */ led_is_on = true; gpio_pin_set_dt(&led_gpio, (int)led_is_on); -#endif /* HAS_LED */ +#endif /* CONFIG_ISO_BLINK_LED0 */ for (uint8_t chan = 0U; chan < BIS_ISO_CHAN_COUNT; chan++) { printk("Waiting for BIG sync lost chan %u...\n", chan); diff --git a/samples/bluetooth/mesh/README.rst b/samples/bluetooth/mesh/README.rst index f566c071ad2d0..1d884bc0d0204 100644 --- a/samples/bluetooth/mesh/README.rst +++ b/samples/bluetooth/mesh/README.rst @@ -2,7 +2,7 @@ :name: Mesh :relevant-api: bt_mesh bluetooth - Use basic Bluetooth LE Mesh functionality. + Use basic Bluetooth Mesh functionality. Overview ******** diff --git a/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf new file mode 100644 index 0000000000000..2c00cdba0819c --- /dev/null +++ b/samples/bluetooth/mesh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -0,0 +1 @@ +CONFIG_SECURE_STORAGE=n diff --git a/samples/bluetooth/mesh/prj.conf b/samples/bluetooth/mesh/prj.conf index 9c8daad91316c..14b19316a8669 100644 --- a/samples/bluetooth/mesh/prj.conf +++ b/samples/bluetooth/mesh/prj.conf @@ -5,6 +5,7 @@ CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_NVS=y CONFIG_SETTINGS=y +CONFIG_SECURE_STORAGE=y CONFIG_HWINFO=y CONFIG_BT=y diff --git a/samples/bluetooth/mesh/src/main.c b/samples/bluetooth/mesh/src/main.c index b220b354fd5c1..cec8159e292ac 100644 --- a/samples/bluetooth/mesh/src/main.c +++ b/samples/bluetooth/mesh/src/main.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf new file mode 100644 index 0000000000000..2c00cdba0819c --- /dev/null +++ b/samples/bluetooth/mesh_demo/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -0,0 +1 @@ +CONFIG_SECURE_STORAGE=n diff --git a/samples/bluetooth/mesh_demo/prj.conf b/samples/bluetooth/mesh_demo/prj.conf index c8c52aaffce3b..bcb738ae5bd1d 100644 --- a/samples/bluetooth/mesh_demo/prj.conf +++ b/samples/bluetooth/mesh_demo/prj.conf @@ -31,6 +31,7 @@ CONFIG_FLASH_MAP=y CONFIG_NVS=y CONFIG_SETTINGS=y CONFIG_BT_MESH_RPL_STORE_TIMEOUT=600 +CONFIG_SECURE_STORAGE=y # Limit the number of key slots in PSA Crypto core to reduce # RAM footprint diff --git a/samples/bluetooth/mesh_demo/src/microbit.c b/samples/bluetooth/mesh_demo/src/microbit.c index bfc608dc82970..38568d26c5a23 100644 --- a/samples/bluetooth/mesh_demo/src/microbit.c +++ b/samples/bluetooth/mesh_demo/src/microbit.c @@ -6,7 +6,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include diff --git a/samples/bluetooth/mesh_provisioner/Kconfig b/samples/bluetooth/mesh_provisioner/Kconfig new file mode 100644 index 0000000000000..013e97d963c21 --- /dev/null +++ b/samples/bluetooth/mesh_provisioner/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +mainmenu "Bluetooth: Mesh Provisioner" + +config MESH_PROVISIONER_USE_SW0 + bool "Use sw0 button to provision" + depends on $(dt_alias_enabled,sw0) + select GPIO + default y diff --git a/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf new file mode 100644 index 0000000000000..2c00cdba0819c --- /dev/null +++ b/samples/bluetooth/mesh_provisioner/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -0,0 +1 @@ +CONFIG_SECURE_STORAGE=n diff --git a/samples/bluetooth/mesh_provisioner/prj.conf b/samples/bluetooth/mesh_provisioner/prj.conf index 8055e388df141..10949c5480dbc 100644 --- a/samples/bluetooth/mesh_provisioner/prj.conf +++ b/samples/bluetooth/mesh_provisioner/prj.conf @@ -45,6 +45,7 @@ CONFIG_FLASH_MAP=y CONFIG_NVS=y CONFIG_SETTINGS=y CONFIG_BT_MESH_RPL_STORE_TIMEOUT=600 +CONFIG_SECURE_STORAGE=y #CONFIG_BT_MESH_LOG_LEVEL_DBG=y #CONFIG_BT_MESH_SETTINGS_LOG_LEVEL_DBG=y diff --git a/samples/bluetooth/mesh_provisioner/src/main.c b/samples/bluetooth/mesh_provisioner/src/main.c index d4be8601304f2..cf66453a5d78a 100644 --- a/samples/bluetooth/mesh_provisioner/src/main.c +++ b/samples/bluetooth/mesh_provisioner/src/main.c @@ -20,7 +20,7 @@ static uint8_t node_uuid[16]; K_SEM_DEFINE(sem_unprov_beacon, 0, 1); K_SEM_DEFINE(sem_node_added, 0, 1); -#if DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#ifdef CONFIG_MESH_PROVISIONER_USE_SW0 K_SEM_DEFINE(sem_button_pressed, 0, 1); #endif @@ -315,7 +315,7 @@ static uint8_t check_unconfigured(struct bt_mesh_cdb_node *node, void *data) return BT_MESH_CDB_ITER_CONTINUE; } -#if DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#ifdef CONFIG_MESH_PROVISIONER_USE_SW0 static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0}); static struct gpio_callback button_cb_data; @@ -366,7 +366,7 @@ int main(void) printk("Bluetooth initialized\n"); bt_ready(); -#if DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#ifdef CONFIG_MESH_PROVISIONER_USE_SW0 button_init(); #endif @@ -383,7 +383,7 @@ int main(void) bin2hex(node_uuid, 16, uuid_hex_str, sizeof(uuid_hex_str)); -#if DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#ifdef CONFIG_MESH_PROVISIONER_USE_SW0 k_sem_reset(&sem_button_pressed); printk("Device %s detected, press button 1 to provision.\n", uuid_hex_str); err = k_sem_take(&sem_button_pressed, K_SECONDS(30)); diff --git a/samples/bluetooth/pbp_public_broadcast_source/src/main.c b/samples/bluetooth/pbp_public_broadcast_source/src/main.c index 364adf0454f32..b996889190c53 100644 --- a/samples/bluetooth/pbp_public_broadcast_source/src/main.c +++ b/samples/bluetooth/pbp_public_broadcast_source/src/main.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/samples/bluetooth/periodic_adv_conn/README.rst b/samples/bluetooth/periodic_adv_conn/README.rst index 7ae2095c78bac..0676bc16fe091 100644 --- a/samples/bluetooth/periodic_adv_conn/README.rst +++ b/samples/bluetooth/periodic_adv_conn/README.rst @@ -7,7 +7,7 @@ Overview ******** -A simple application demonstrating the initiator side of the BLE +A simple application demonstrating the initiator side of the Bluetooth LE Periodic Advertising Connection Procedure. How the initiator decides the address of the synced device to connect to diff --git a/samples/bluetooth/periodic_sync/Kconfig b/samples/bluetooth/periodic_sync/Kconfig index 38c5ef9a6a3cf..23af62bf2257a 100644 --- a/samples/bluetooth/periodic_sync/Kconfig +++ b/samples/bluetooth/periodic_sync/Kconfig @@ -12,4 +12,10 @@ config PER_ADV_NAME help Name of target advertising for Periodic Advertising Synchronization. +config PER_BLINK_LED0 + bool "Blink led0" + depends on $(dt_alias_enabled,led0) + select GPIO + default y + source "Kconfig.zephyr" diff --git a/samples/bluetooth/periodic_sync/src/main.c b/samples/bluetooth/periodic_sync/src/main.c index fdc736c52fe87..3a6f3973dda9c 100644 --- a/samples/bluetooth/periodic_sync/src/main.c +++ b/samples/bluetooth/periodic_sync/src/main.c @@ -27,8 +27,7 @@ static K_SEM_DEFINE(sem_per_sync_lost, 0, 1); /* The devicetree node identifier for the "led0" alias. */ #define LED0_NODE DT_ALIAS(led0) -#if DT_NODE_HAS_STATUS_OKAY(LED0_NODE) -#define HAS_LED 1 +#ifdef CONFIG_PER_BLINK_LED0 static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); #define BLINK_ONOFF K_MSEC(500) @@ -186,7 +185,7 @@ int main(void) printk("Starting Periodic Advertising Synchronization Demo\n"); -#if defined(HAS_LED) +#ifdef CONFIG_PER_BLINK_LED0 printk("Checking LED device..."); if (!gpio_is_ready_dt(&led)) { printk("failed.\n"); @@ -203,7 +202,7 @@ int main(void) printk("done.\n"); k_work_init_delayable(&blink_work, blink_timeout); -#endif /* HAS_LED */ +#endif /* CONFIG_PER_BLINK_LED0 */ /* Initialize the Bluetooth Subsystem */ err = bt_enable(NULL); @@ -229,14 +228,14 @@ int main(void) printk("success.\n"); do { -#if defined(HAS_LED) +#ifdef CONFIG_PER_BLINK_LED0 struct k_work_sync work_sync; printk("Start blinking LED...\n"); led_is_on = false; gpio_pin_set(led.port, led.pin, (int)led_is_on); k_work_schedule(&blink_work, BLINK_ONOFF); -#endif /* HAS_LED */ +#endif /* CONFIG_PER_BLINK_LED0 */ printk("Waiting for periodic advertising...\n"); per_adv_found = false; @@ -275,14 +274,14 @@ int main(void) } printk("Periodic sync established.\n"); -#if defined(HAS_LED) +#ifdef CONFIG_PER_BLINK_LED0 printk("Stop blinking LED.\n"); k_work_cancel_delayable_sync(&blink_work, &work_sync); /* Keep LED on */ led_is_on = true; gpio_pin_set(led.port, led.pin, (int)led_is_on); -#endif /* HAS_LED */ +#endif /* CONFIG_PER_BLINK_LED0 */ printk("Waiting for periodic sync lost...\n"); err = k_sem_take(&sem_per_sync_lost, K_FOREVER); diff --git a/samples/bluetooth/periodic_sync_conn/README.rst b/samples/bluetooth/periodic_sync_conn/README.rst index 1ec8aec3d25d1..24c9ee5f5277f 100644 --- a/samples/bluetooth/periodic_sync_conn/README.rst +++ b/samples/bluetooth/periodic_sync_conn/README.rst @@ -7,7 +7,7 @@ Overview ******** -A simple application demonstrating the responder side of the BLE +A simple application demonstrating the responder side of the Bluetooth LE Periodic Advertising Connection Procedure. This sample will send its address in response to the advertiser when receiving diff --git a/samples/bluetooth/peripheral/boards/nucleo_l4r5zi_stm32l4r5xx.conf b/samples/bluetooth/peripheral/boards/nucleo_l4r5zi_stm32l4r5xx.conf deleted file mode 100644 index 5858c7b6db1b3..0000000000000 --- a/samples/bluetooth/peripheral/boards/nucleo_l4r5zi_stm32l4r5xx.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_ENTROPY_GENERATOR=y diff --git a/samples/bluetooth/peripheral/sample.yaml b/samples/bluetooth/peripheral/sample.yaml index d28d9e23d0111..aca027dfc1d47 100644 --- a/samples/bluetooth/peripheral/sample.yaml +++ b/samples/bluetooth/peripheral/sample.yaml @@ -1,6 +1,6 @@ sample: name: Bluetooth Peripheral - description: Demonstrates the BLE Peripheral role + description: Demonstrates the Bluetooth LE Peripheral role tests: sample.bluetooth.peripheral: harness: bluetooth @@ -19,3 +19,15 @@ tests: extra_args: SHIELD=x_nucleo_idb05a1 integration_platforms: - nucleo_l4r5zi + sample.bluetooth.peripheral.no_blobs: + extra_args: + - CONFIG_BUILD_ONLY_NO_BLOBS=y + platform_allow: + - esp32_devkitc_wroom/esp32/procpu + - esp32s3_devkitm/esp32s3/procpu + - esp32c3_devkitm + - sltb010a/efr32bg22c224f512im40 + - xg24_rb4187c/efr32mg24b220f1536im48 + - xg27_dk2602a/efr32bg27c140f768im40 + - xg29_rb4412a/efr32mg29b140f1024im40 + build_only: true diff --git a/samples/bluetooth/peripheral_accept_list/README.rst b/samples/bluetooth/peripheral_accept_list/README.rst index 4f40556146645..cce075d559413 100644 --- a/samples/bluetooth/peripheral_accept_list/README.rst +++ b/samples/bluetooth/peripheral_accept_list/README.rst @@ -12,7 +12,7 @@ If no device is bonded to the peripheral, casual advertising will be performed. Once a device is bonded, on subsequent boots, connection requests will only be accepted if the central device is on the accept list. Additionally, scan response data will only be sent to devices that are on the accept list. As a result, some -BLE central devices (such as Android smartphones) might not display the device +Bluetooth LE central devices (such as Android smartphones) might not display the device in the scan results if the central device is not on the accept list. This sample also provides two Bluetooth LE characteristics. To perform a write, devices need diff --git a/samples/bluetooth/peripheral_csc/prj.conf b/samples/bluetooth/peripheral_csc/prj.conf index fc1993bc808f0..59dbb7799dfd2 100644 --- a/samples/bluetooth/peripheral_csc/prj.conf +++ b/samples/bluetooth/peripheral_csc/prj.conf @@ -1,4 +1,3 @@ -CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y diff --git a/samples/bluetooth/peripheral_dis/prj.conf b/samples/bluetooth/peripheral_dis/prj.conf index 4fed0a4e66fe7..cc58337db9c0e 100644 --- a/samples/bluetooth/peripheral_dis/prj.conf +++ b/samples/bluetooth/peripheral_dis/prj.conf @@ -3,12 +3,14 @@ CONFIG_BT_PERIPHERAL=y CONFIG_BT_DIS=y CONFIG_BT_DIS_PNP=n -CONFIG_BT_DIS_MODEL="Zephyr Model" -CONFIG_BT_DIS_MANUF="Zephyr" +CONFIG_BT_DIS_MODEL_NUMBER=y +CONFIG_BT_DIS_MANUF_NAME=y CONFIG_BT_DIS_SERIAL_NUMBER=y CONFIG_BT_DIS_FW_REV=y CONFIG_BT_DIS_HW_REV=y CONFIG_BT_DIS_SW_REV=y +CONFIG_BT_DIS_MODEL_NUMBER_STR="Zephyr Model" +CONFIG_BT_DIS_MANUF_NAME_STR="Zephyr" CONFIG_BT_DIS_SERIAL_NUMBER_STR="Zephyr Serial" CONFIG_BT_DIS_FW_REV_STR="Zephyr Firmware" CONFIG_BT_DIS_HW_REV_STR="Zephyr Hardware" diff --git a/samples/bluetooth/peripheral_hr/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/samples/bluetooth/peripheral_hr/boards/nrf54l15dk_nrf54l15_cpuapp.conf deleted file mode 100644 index 350b42b0f67ab..0000000000000 --- a/samples/bluetooth/peripheral_hr/boards/nrf54l15dk_nrf54l15_cpuapp.conf +++ /dev/null @@ -1,13 +0,0 @@ -# We need a random number generator to properly initialize the PSA Crypto core -# implemented by Mbed TLS. The proper thing to do in this platform would be -# to enable ENTROPY_GENERATOR, but this is not supported right now for the -# following reasons: -# - at device-tree level (nrf54l15_cpuapp.dtsi) the only RNG source available -# is "zephyr,psa-crypto-rng" which means that TF-M is required in order for -# this to work. Unfortunately TF-M is still not supported for this platform, yet. -# - cpuapp does not have a direct access to the RNG without TF-M, so there's -# no other way it can make use of it as of now. -# -# Since both options are not viable, we fall back to the test random generator -# until further support is added to the platform. -CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/samples/bluetooth/peripheral_ht/boards/frdm_rw612.conf b/samples/bluetooth/peripheral_ht/boards/frdm_rw612.conf index 6bec2cd6b3781..2df782efc7115 100644 --- a/samples/bluetooth/peripheral_ht/boards/frdm_rw612.conf +++ b/samples/bluetooth/peripheral_ht/boards/frdm_rw612.conf @@ -1,2 +1 @@ CONFIG_PM=y -CONFIG_ENTROPY_GENERATOR=y diff --git a/samples/bluetooth/peripheral_ht/boards/mimxrt1020_evk_mimxrt1021.conf b/samples/bluetooth/peripheral_ht/boards/mimxrt1020_evk_mimxrt1021.conf deleted file mode 100644 index 5858c7b6db1b3..0000000000000 --- a/samples/bluetooth/peripheral_ht/boards/mimxrt1020_evk_mimxrt1021.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_ENTROPY_GENERATOR=y diff --git a/samples/bluetooth/peripheral_ht/boards/rd_rw612_bga.conf b/samples/bluetooth/peripheral_ht/boards/rd_rw612_bga.conf index 6bec2cd6b3781..2df782efc7115 100644 --- a/samples/bluetooth/peripheral_ht/boards/rd_rw612_bga.conf +++ b/samples/bluetooth/peripheral_ht/boards/rd_rw612_bga.conf @@ -1,2 +1 @@ CONFIG_PM=y -CONFIG_ENTROPY_GENERATOR=y diff --git a/samples/bluetooth/peripheral_ht/sample.yaml b/samples/bluetooth/peripheral_ht/sample.yaml index 1e77988bde1cf..3316b0fdc81dd 100644 --- a/samples/bluetooth/peripheral_ht/sample.yaml +++ b/samples/bluetooth/peripheral_ht/sample.yaml @@ -16,13 +16,16 @@ tests: harness: bluetooth platform_allow: - mimxrt1020_evk - - mimxrt1050_evk - - mimxrt1060_evk + - mimxrt1050_evk/mimxrt1052/hyperflash + - mimxrt1060_evk@A/mimxrt1062/qspi + - mimxrt1060_evk@B/mimxrt1062/qspi + - mimxrt1060_evk@C/mimxrt1062/qspi - frdm_k64f tags: bluetooth extra_args: SHIELD=frdm_kw41z integration_platforms: - mimxrt1020_evk + - mimxrt1060_evk/mimxrt1062/qspi sample.bluetooth.peripheral_ht.nxp: # Disabling monolithic since CI environment doesn't use blobs build_only: true @@ -31,4 +34,4 @@ tests: - rd_rw612_bga - frdm_rw612 extra_configs: - - CONFIG_NXP_MONOLITHIC_BT=n + - CONFIG_NXP_MONOLITHIC_NBU=n diff --git a/samples/bluetooth/peripheral_identity/src/main.c b/samples/bluetooth/peripheral_identity/src/main.c index 4d33341328f21..61f1b01921330 100644 --- a/samples/bluetooth/peripheral_identity/src/main.c +++ b/samples/bluetooth/peripheral_identity/src/main.c @@ -8,10 +8,10 @@ #include -int init_peripheral(uint8_t iterations); +int init_peripheral(uint8_t max_conn, uint8_t iterations); int main(void) { - (void)init_peripheral(CONFIG_SAMPLE_CONN_ITERATIONS); + (void)init_peripheral(CONFIG_BT_MAX_CONN, CONFIG_SAMPLE_CONN_ITERATIONS); return 0; } diff --git a/samples/bluetooth/peripheral_identity/src/peripheral_identity.c b/samples/bluetooth/peripheral_identity/src/peripheral_identity.c index a4722907d501e..027c893a3a619 100644 --- a/samples/bluetooth/peripheral_identity/src/peripheral_identity.c +++ b/samples/bluetooth/peripheral_identity/src/peripheral_identity.c @@ -15,6 +15,7 @@ #include static struct k_work work_adv_start; +static uint8_t conn_count_max; static uint8_t volatile conn_count; static uint8_t id_current; static bool volatile is_disconnecting; @@ -49,7 +50,7 @@ static void adv_start(struct k_work *work) if (id < 0) { printk("Create id failed (%d)\n", id); if (id_current == 0) { - id_current = CONFIG_BT_MAX_CONN; + id_current = conn_count_max; } id_current--; } else { @@ -67,7 +68,7 @@ static void adv_start(struct k_work *work) } id_current++; - if (id_current == CONFIG_BT_MAX_CONN) { + if (id_current == conn_count_max) { id_current = 0; } @@ -84,7 +85,7 @@ static void connected(struct bt_conn *conn, uint8_t err) } conn_count++; - if (conn_count < CONFIG_BT_MAX_CONN) { + if (conn_count < conn_count_max) { k_work_submit(&work_adv_start); } @@ -225,11 +226,29 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, } #endif /* CONFIG_BT_OBSERVER */ -int init_peripheral(uint8_t iterations) +static void disconnect(struct bt_conn *conn, void *data) +{ + char addr[BT_ADDR_LE_STR_LEN]; + int err; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + printk("Disconnecting %s...\n", addr); + err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + if (err) { + printk("Failed disconnection %s.\n", addr); + return; + } + printk("success.\n"); +} + +int init_peripheral(uint8_t max_conn, uint8_t iterations) { size_t id_count; int err; + conn_count_max = max_conn; + err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); @@ -264,7 +283,7 @@ int init_peripheral(uint8_t iterations) id_count = 0xFF; bt_id_get(NULL, &id_count); - } while (id_count != CONFIG_BT_MAX_CONN); + } while (id_count != conn_count_max); /* rotate identities so reconnections are attempted in case of any * disconnections @@ -272,17 +291,31 @@ int init_peripheral(uint8_t iterations) uint8_t prev_count = conn_count; while (1) { /* If maximum connections is reached, wait for disconnections - * initiated by peer central devices. */ - if (conn_count == CONFIG_BT_MAX_CONN) { + if (conn_count == conn_count_max) { + is_disconnecting = true; + + /* Lets wait sufficiently to ensure a stable connection + * before starting to disconnect for next iteration. + */ + k_sleep(K_SECONDS(60)); + if (!iterations) { break; } iterations--; printk("Iterations remaining: %u\n", iterations); - printk("Wait for disconnections...\n"); - is_disconnecting = true; + /* Device needing multiple connections is the one + * initiating the disconnects. + */ + if (conn_count_max > 1U) { + printk("Disconnecting all...\n"); + bt_conn_foreach(BT_CONN_TYPE_LE, disconnect, NULL); + } else { + printk("Wait for disconnections...\n"); + } + while (is_disconnecting) { k_sleep(K_MSEC(10)); } @@ -306,6 +339,9 @@ int init_peripheral(uint8_t iterations) * connections plus few seconds of margin. */ while ((prev_count == conn_count) && wait) { + printk("Waiting connections (%u/%u) %u...\n", + prev_count, conn_count, wait); + wait--; k_sleep(K_MSEC(10)); diff --git a/samples/bluetooth/peripheral_nus/src/main.c b/samples/bluetooth/peripheral_nus/src/main.c index dd4d57cf31db2..ac987ddfa63ea 100644 --- a/samples/bluetooth/peripheral_nus/src/main.c +++ b/samples/bluetooth/peripheral_nus/src/main.c @@ -29,13 +29,10 @@ static void notif_enabled(bool enabled, void *ctx) static void received(struct bt_conn *conn, const void *data, uint16_t len, void *ctx) { - char message[CONFIG_BT_L2CAP_TX_MTU + 1] = ""; - ARG_UNUSED(conn); ARG_UNUSED(ctx); - memcpy(message, data, MIN(sizeof(message) - 1, len)); - printk("%s() - Len: %d, Message: %s\n", __func__, len, message); + printk("%s() - Len: %d, Message: %.*s\n", __func__, len, len, (char *)data); } struct bt_nus_cb nus_listener = { diff --git a/samples/bluetooth/peripheral_past/src/main.c b/samples/bluetooth/peripheral_past/src/main.c index 1bd6aa35cf7f6..1ad4692c9cd7f 100644 --- a/samples/bluetooth/peripheral_past/src/main.c +++ b/samples/bluetooth/peripheral_past/src/main.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/samples/bluetooth/peripheral_sc_only/boards/tlsr9518adk80d.conf b/samples/bluetooth/peripheral_sc_only/boards/tlsr9518adk80d.conf deleted file mode 100644 index ce0a87933b7d8..0000000000000 --- a/samples/bluetooth/peripheral_sc_only/boards/tlsr9518adk80d.conf +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright (c) 2022 Telink Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_BT_SEND_ECC_EMULATION=n diff --git a/samples/bluetooth/peripheral_sc_only/prj.conf b/samples/bluetooth/peripheral_sc_only/prj.conf index b8086b247fe58..37276678c5e49 100644 --- a/samples/bluetooth/peripheral_sc_only/prj.conf +++ b/samples/bluetooth/peripheral_sc_only/prj.conf @@ -7,6 +7,5 @@ CONFIG_LOG=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y CONFIG_BT_SMP_SC_ONLY=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_BT_MAX_PAIRED=2 CONFIG_BT_DEVICE_NAME="SC only peripheral" diff --git a/samples/bluetooth/peripheral_sc_only/src/main.c b/samples/bluetooth/peripheral_sc_only/src/main.c index f4ae4252cdcd0..1a7860851fafc 100644 --- a/samples/bluetooth/peripheral_sc_only/src/main.c +++ b/samples/bluetooth/peripheral_sc_only/src/main.c @@ -28,6 +28,18 @@ static const struct bt_data sd[] = { BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1), }; +static void start_adv(void) +{ + int err; + + err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); + if (err) { + printk("Advertising failed to start (err %d)\n", err); + } else { + printk("Advertising successfully started\n"); + } +} + static void connected(struct bt_conn *conn, uint8_t err) { char addr[BT_ADDR_LE_STR_LEN]; @@ -86,6 +98,7 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, BT_CONN_CB_DEFINE(conn_callbacks) = { .connected = connected, .disconnected = disconnected, + .recycled = start_adv, .identity_resolved = identity_resolved, .security_changed = security_changed, }; @@ -145,12 +158,7 @@ int main(void) bt_conn_auth_cb_register(&auth_cb_display); bt_conn_auth_info_cb_register(&auth_cb_info); - err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); - if (err) { - printk("Advertising failed to start (err %d)\n", err); - return 0; - } + start_adv(); - printk("Advertising successfully started\n"); return 0; } diff --git a/samples/bluetooth/scan_adv/sample.yaml b/samples/bluetooth/scan_adv/sample.yaml index 52ec407b0a72e..e1e501e93c3ef 100644 --- a/samples/bluetooth/scan_adv/sample.yaml +++ b/samples/bluetooth/scan_adv/sample.yaml @@ -1,6 +1,6 @@ sample: name: Bluetooth Scan & Advertise - description: Demonstrates combined BLE Broadcaster & Observer role functionality + description: Demonstrates combined Bluetooth LE Broadcaster & Observer role functionality tests: sample.bluetooth.scan_adv: harness: bluetooth diff --git a/samples/bluetooth/st_ble_sensor/README.rst b/samples/bluetooth/st_ble_sensor/README.rst index b1cad9d78e8f9..30d6f2fd1b362 100644 --- a/samples/bluetooth/st_ble_sensor/README.rst +++ b/samples/bluetooth/st_ble_sensor/README.rst @@ -2,7 +2,7 @@ :name: ST Bluetooth LE Sensor Demo :relevant-api: bt_gatt bluetooth - Export vendor-specific GATT services over BLE. + Export vendor-specific GATT services over Bluetooth. Overview ******** diff --git a/samples/bluetooth/st_ble_sensor/prj.conf b/samples/bluetooth/st_ble_sensor/prj.conf index 4bcba44c6062a..75048c22ce384 100644 --- a/samples/bluetooth/st_ble_sensor/prj.conf +++ b/samples/bluetooth/st_ble_sensor/prj.conf @@ -4,4 +4,4 @@ CONFIG_BT_DEVICE_NAME="P2PSRV1" CONFIG_BT_GATT_CLIENT=y CONFIG_LOG=y CONFIG_LOG_BUFFER_SIZE=2048 -CONFIG_ENTROPY_GENERATOR=y +CONFIG_GPIO=y diff --git a/samples/bluetooth/st_ble_sensor/sample.yaml b/samples/bluetooth/st_ble_sensor/sample.yaml index 16936ebbc1413..d53b4e63c1c8d 100644 --- a/samples/bluetooth/st_ble_sensor/sample.yaml +++ b/samples/bluetooth/st_ble_sensor/sample.yaml @@ -1,6 +1,6 @@ sample: - name: Bluetooth ST BLE Sensor Demo - description: Demonstrates BLE peripheral by exposing vendor-specific GATT + name: Bluetooth ST Bluetooth LE Sensor Demo + description: Demonstrates Bluetooth LE peripheral by exposing vendor-specific GATT services tests: sample.bluetooth.st_ble_sensor: diff --git a/samples/bluetooth/st_ble_sensor/src/button_svc.c b/samples/bluetooth/st_ble_sensor/src/button_svc.c index 2f1ff573f6f40..e212095676dc7 100644 --- a/samples/bluetooth/st_ble_sensor/src/button_svc.c +++ b/samples/bluetooth/st_ble_sensor/src/button_svc.c @@ -10,6 +10,7 @@ #include "button_svc.h" +#include #include #include diff --git a/samples/bluetooth/tmap_bmr/boards/native_posix.conf b/samples/bluetooth/tmap_bmr/boards/native_posix.conf index c951fcc8c3366..8ab1d7be11310 100644 --- a/samples/bluetooth/tmap_bmr/boards/native_posix.conf +++ b/samples/bluetooth/tmap_bmr/boards/native_posix.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/tmap_bmr/boards/native_sim.conf b/samples/bluetooth/tmap_bmr/boards/native_sim.conf index 8927008819a1d..87e355c867514 100644 --- a/samples/bluetooth/tmap_bmr/boards/native_sim.conf +++ b/samples/bluetooth/tmap_bmr/boards/native_sim.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/tmap_bmr/src/bap_broadcast_sink.c b/samples/bluetooth/tmap_bmr/src/bap_broadcast_sink.c index 9c2994f99976e..0271645184a4f 100644 --- a/samples/bluetooth/tmap_bmr/src/bap_broadcast_sink.c +++ b/samples/bluetooth/tmap_bmr/src/bap_broadcast_sink.c @@ -313,8 +313,18 @@ static int reset(void) int bap_broadcast_sink_init(void) { + const struct bt_pacs_register_param pacs_param = { + .snk_pac = true, + .snk_loc = true, + }; int err; + err = bt_pacs_register(&pacs_param); + if (err) { + printk("Could not register PACS (err %d)\n", err); + return err; + } + bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs); bt_le_per_adv_sync_cb_register(&broadcast_sync_cb); diff --git a/samples/bluetooth/tmap_bms/boards/native_posix.conf b/samples/bluetooth/tmap_bms/boards/native_posix.conf index c951fcc8c3366..8ab1d7be11310 100644 --- a/samples/bluetooth/tmap_bms/boards/native_posix.conf +++ b/samples/bluetooth/tmap_bms/boards/native_posix.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/tmap_bms/boards/native_sim.conf b/samples/bluetooth/tmap_bms/boards/native_sim.conf index 8927008819a1d..87e355c867514 100644 --- a/samples/bluetooth/tmap_bms/boards/native_sim.conf +++ b/samples/bluetooth/tmap_bms/boards/native_sim.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/tmap_bms/src/cap_initiator.c b/samples/bluetooth/tmap_bms/src/cap_initiator.c index 5ea8f88475b86..0a81a3026cd91 100644 --- a/samples/bluetooth/tmap_bms/src/cap_initiator.c +++ b/samples/bluetooth/tmap_bms/src/cap_initiator.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/samples/bluetooth/tmap_central/CMakeLists.txt b/samples/bluetooth/tmap_central/CMakeLists.txt index dd1bca04e1302..7a122c1157c89 100644 --- a/samples/bluetooth/tmap_central/CMakeLists.txt +++ b/samples/bluetooth/tmap_central/CMakeLists.txt @@ -8,7 +8,7 @@ target_sources(app PRIVATE src/main.c src/mcp_server.c src/vcp_vol_ctlr.c - src/ccp_server.c + src/ccp_call_control_server.c src/cap_initiator.c ) diff --git a/samples/bluetooth/tmap_central/boards/native_posix.conf b/samples/bluetooth/tmap_central/boards/native_posix.conf index c951fcc8c3366..8ab1d7be11310 100644 --- a/samples/bluetooth/tmap_central/boards/native_posix.conf +++ b/samples/bluetooth/tmap_central/boards/native_posix.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/tmap_central/boards/native_sim.conf b/samples/bluetooth/tmap_central/boards/native_sim.conf index 8927008819a1d..87e355c867514 100644 --- a/samples/bluetooth/tmap_central/boards/native_sim.conf +++ b/samples/bluetooth/tmap_central/boards/native_sim.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/tmap_central/prj.conf b/samples/bluetooth/tmap_central/prj.conf index 0718245e20106..2d2b50dc1173d 100644 --- a/samples/bluetooth/tmap_central/prj.conf +++ b/samples/bluetooth/tmap_central/prj.conf @@ -35,6 +35,7 @@ CONFIG_MCTL_LOCAL_PLAYER_CONTROL=y CONFIG_MCTL=y # CCP support +CONFIG_BT_CCP_CALL_CONTROL_SERVER=y CONFIG_BT_TBS=y CONFIG_BT_TBS_SUPPORTED_FEATURES=3 diff --git a/samples/bluetooth/tmap_central/src/ccp_call_control_server.c b/samples/bluetooth/tmap_central/src/ccp_call_control_server.c new file mode 100644 index 0000000000000..9ddbcfff01a6c --- /dev/null +++ b/samples/bluetooth/tmap_central/src/ccp_call_control_server.c @@ -0,0 +1,56 @@ +/** @file + * @brief Bluetooth Call Control Profile (CCP) Server role. + * + * Copyright 2023 NXP + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include +#include + +#define URI_LIST_LEN 2 + +static const char *uri_list[URI_LIST_LEN] = {"skype", "tel"}; + +static bool tbs_originate_call_cb(struct bt_conn *conn, uint8_t call_index, + const char *caller_id) +{ + printk("CCP: Placing call to remote with id %u to %s\n", + call_index, caller_id); + return true; +} + +static void tbs_terminate_call_cb(struct bt_conn *conn, uint8_t call_index, uint8_t reason) +{ + printk("CCP: Call terminated for id %u with reason %u\n", + call_index, reason); +} + +static struct bt_tbs_cb tbs_cbs = { + .originate_call = tbs_originate_call_cb, + .terminate_call = tbs_terminate_call_cb, + .hold_call = NULL, + .accept_call = NULL, + .retrieve_call = NULL, + .join_calls = NULL, + .authorize = NULL, +}; + +int ccp_call_control_server_init(void) +{ + int err; + + bt_tbs_register_cb(&tbs_cbs); + + err = bt_tbs_set_uri_scheme_list(0, (const char **)&uri_list, URI_LIST_LEN); + + return err; +} diff --git a/samples/bluetooth/tmap_central/src/ccp_server.c b/samples/bluetooth/tmap_central/src/ccp_server.c deleted file mode 100644 index 7f21563cfe0d1..0000000000000 --- a/samples/bluetooth/tmap_central/src/ccp_server.c +++ /dev/null @@ -1,56 +0,0 @@ -/** @file - * @brief Bluetooth Call Control Profile (CCP) Server role. - * - * Copyright 2023 NXP - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include -#include -#include -#include - -#define URI_LIST_LEN 2 - -static const char *uri_list[URI_LIST_LEN] = {"skype", "tel"}; - -static bool tbs_originate_call_cb(struct bt_conn *conn, uint8_t call_index, - const char *caller_id) -{ - printk("CCP: Placing call to remote with id %u to %s\n", - call_index, caller_id); - return true; -} - -static void tbs_terminate_call_cb(struct bt_conn *conn, uint8_t call_index, uint8_t reason) -{ - printk("CCP: Call terminated for id %u with reason %u\n", - call_index, reason); -} - -static struct bt_tbs_cb tbs_cbs = { - .originate_call = tbs_originate_call_cb, - .terminate_call = tbs_terminate_call_cb, - .hold_call = NULL, - .accept_call = NULL, - .retrieve_call = NULL, - .join_calls = NULL, - .authorize = NULL, -}; - -int ccp_server_init(void) -{ - int err; - - bt_tbs_register_cb(&tbs_cbs); - - err = bt_tbs_set_uri_scheme_list(0, (const char **)&uri_list, URI_LIST_LEN); - - return err; -} diff --git a/samples/bluetooth/tmap_central/src/main.c b/samples/bluetooth/tmap_central/src/main.c index 98edc30bf9dc7..4c47e232bc08b 100644 --- a/samples/bluetooth/tmap_central/src/main.c +++ b/samples/bluetooth/tmap_central/src/main.c @@ -306,8 +306,8 @@ int main(void) } printk("MCP initialized\n"); - /* Initialize CCP Server */ - err = ccp_server_init(); + /* Initialize CCP Call Control Server */ + err = ccp_call_control_server_init(); if (err != 0) { return err; } diff --git a/samples/bluetooth/tmap_central/src/mcp_server.c b/samples/bluetooth/tmap_central/src/mcp_server.c index 1144569a1baa2..5225e5b51eab0 100644 --- a/samples/bluetooth/tmap_central/src/mcp_server.c +++ b/samples/bluetooth/tmap_central/src/mcp_server.c @@ -6,13 +6,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include - #include #include +#include +#include int mcp_server_init(void) { diff --git a/samples/bluetooth/tmap_central/src/tmap_central.h b/samples/bluetooth/tmap_central/src/tmap_central.h index 1b2277a3b5be6..6792c03351163 100644 --- a/samples/bluetooth/tmap_central/src/tmap_central.h +++ b/samples/bluetooth/tmap_central/src/tmap_central.h @@ -18,11 +18,11 @@ int mcp_server_init(void); /** - * @brief Initialize the CCP Server role + * @brief Initialize the CCP Call Control Server role * * @return 0 if success, errno on failure. */ -int ccp_server_init(void); +int ccp_call_control_server_init(void); /** * @brief Initialize the VCP Volume Controller role diff --git a/samples/bluetooth/tmap_peripheral/boards/native_posix.conf b/samples/bluetooth/tmap_peripheral/boards/native_posix.conf index c951fcc8c3366..8ab1d7be11310 100644 --- a/samples/bluetooth/tmap_peripheral/boards/native_posix.conf +++ b/samples/bluetooth/tmap_peripheral/boards/native_posix.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/tmap_peripheral/boards/native_sim.conf b/samples/bluetooth/tmap_peripheral/boards/native_sim.conf index 8927008819a1d..87e355c867514 100644 --- a/samples/bluetooth/tmap_peripheral/boards/native_sim.conf +++ b/samples/bluetooth/tmap_peripheral/boards/native_sim.conf @@ -1,5 +1,4 @@ CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_LIBLC3=y CONFIG_FPU=y diff --git a/samples/bluetooth/tmap_peripheral/prj.conf b/samples/bluetooth/tmap_peripheral/prj.conf index ebe30c7548639..cf40172576a62 100644 --- a/samples/bluetooth/tmap_peripheral/prj.conf +++ b/samples/bluetooth/tmap_peripheral/prj.conf @@ -43,14 +43,13 @@ CONFIG_BT_PAC_SNK_LOC=y # Source PAC Location Support CONFIG_BT_PAC_SRC_LOC=y -# CCP Client Support +# CCP Call Control Client Support CONFIG_BT_TBS_CLIENT_GTBS=y CONFIG_BT_TBS_CLIENT_ORIGINATE_CALL=y CONFIG_BT_TBS_CLIENT_TERMINATE_CALL=y CONFIG_BT_TBS_CLIENT_BEARER_URI_SCHEMES_SUPPORTED_LIST=y # Generic config -CONFIG_BT_GATT_CACHING=y CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_GATT_CLIENT=y CONFIG_BT_EXT_ADV=y diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index 0aea8794f294a..8883a2aad2c58 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -367,8 +367,23 @@ static struct bt_pacs_cap cap = { .codec_cap = &lc3_codec_cap, }; + int bap_unicast_sr_init(void) { + const struct bt_pacs_register_param pacs_param = { + .snk_pac = true, + .snk_loc = true, + .src_pac = true, + .src_loc = true, + }; + int err; + + err = bt_pacs_register(&pacs_param); + if (err) { + printk("Could not register PACS (err %d)\n", err); + return err; + } + bt_bap_unicast_server_register(¶m); bt_bap_unicast_server_register_cb(&unicast_server_cb); diff --git a/samples/boards/bbc/microbit/display/src/main.c b/samples/boards/bbc/microbit/display/src/main.c index b6b00f0e7a2e9..bf7e5de0c19e0 100644 --- a/samples/boards/bbc/microbit/display/src/main.c +++ b/samples/boards/bbc/microbit/display/src/main.c @@ -6,7 +6,6 @@ #include #include -#include #include #include diff --git a/samples/boards/bbc/microbit/pong/src/ble.c b/samples/boards/bbc/microbit/pong/src/ble.c index bdbad05639af3..36d0115aa6813 100644 --- a/samples/boards/bbc/microbit/pong/src/ble.c +++ b/samples/boards/bbc/microbit/pong/src/ble.c @@ -6,7 +6,6 @@ #include #include -#include #include #include diff --git a/samples/boards/espressif/deep_sleep/Kconfig b/samples/boards/espressif/deep_sleep/Kconfig index 540963e5c6cc6..6bf10e53393fb 100644 --- a/samples/boards/espressif/deep_sleep/Kconfig +++ b/samples/boards/espressif/deep_sleep/Kconfig @@ -6,6 +6,7 @@ mainmenu "Espressif Deep Sleep demo" config EXAMPLE_EXT1_WAKEUP bool "Enable wakeup from GPIO" depends on !SOC_SERIES_ESP32C3 + select GPIO help This option enables wake-up from deep sleep using GPIO2 and GPIO4. The sample enables internal pull-down on EXT1 pins to @@ -16,6 +17,7 @@ config EXAMPLE_EXT1_WAKEUP config EXAMPLE_GPIO_WAKEUP bool "Enable wakeup from GPIO" depends on SOC_SERIES_ESP32C3 + select GPIO help This option enables wake-up from GPIO. Only GPIO0~5 can be used as wake-up source. Be aware that when low level is used to trigger diff --git a/samples/boards/espressif/deep_sleep/socs/esp32c3_usb.conf b/samples/boards/espressif/deep_sleep/socs/esp32c3_usb.conf new file mode 100644 index 0000000000000..2ce9f6b8f5c54 --- /dev/null +++ b/samples/boards/espressif/deep_sleep/socs/esp32c3_usb.conf @@ -0,0 +1 @@ +CONFIG_EXAMPLE_GPIO_WAKEUP=y diff --git a/samples/boards/espressif/deep_sleep/socs/esp32c3_usb.overlay b/samples/boards/espressif/deep_sleep/socs/esp32c3_usb.overlay new file mode 100644 index 0000000000000..6235a933aec8f --- /dev/null +++ b/samples/boards/espressif/deep_sleep/socs/esp32c3_usb.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + /* On ESP32-C3, only GPIO0~5 can be used + * as wake-up sources + */ + wakeup-button = &sample_button; + }; + + gpio_keys { + compatible = "gpio-keys"; + sample_button: sample_button { + gpios = <&gpio0 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + }; + }; +}; diff --git a/samples/boards/espressif/deep_sleep/src/main.c b/samples/boards/espressif/deep_sleep/src/main.c index 519a1a550df9f..5cf93c6a98cd7 100644 --- a/samples/boards/espressif/deep_sleep/src/main.c +++ b/samples/boards/espressif/deep_sleep/src/main.c @@ -9,7 +9,9 @@ #include #include -#define WAKEUP_TIME_SEC (20) +#include + +#define WAKEUP_TIME_SEC (5) #ifdef CONFIG_EXAMPLE_EXT1_WAKEUP #define EXT_WAKEUP_PIN_1 (2) @@ -24,8 +26,15 @@ static const struct gpio_dt_spec wakeup_button = GPIO_DT_SPEC_GET(DT_ALIAS(wakeu #endif #endif +/* keep data in RTC memory after deep-sleep */ +RTC_DATA_ATTR int s_rtc_data = 0; + int main(void) { +#ifdef CONFIG_BOOTLOADER_MCUBOOT + printk("ESP32 deep sleep example, current counter is %d\r\n", s_rtc_data++); +#endif + switch (esp_sleep_get_wakeup_cause()) { #ifdef CONFIG_EXAMPLE_EXT1_WAKEUP case ESP_SLEEP_WAKEUP_EXT1: diff --git a/samples/boards/espressif/light_sleep/prj.conf b/samples/boards/espressif/light_sleep/prj.conf index 7890496e35388..134a3f5f5a22e 100644 --- a/samples/boards/espressif/light_sleep/prj.conf +++ b/samples/boards/espressif/light_sleep/prj.conf @@ -1,3 +1,4 @@ CONFIG_PM=y # Required to disable default behavior of deep sleep on timeout CONFIG_PM_DEVICE=y +CONFIG_GPIO=y diff --git a/samples/boards/espressif/spiram_test/prj.conf b/samples/boards/espressif/spiram_test/prj.conf index c7dc9a2f6a9ea..64d0f6d73c9f8 100644 --- a/samples/boards/espressif/spiram_test/prj.conf +++ b/samples/boards/espressif/spiram_test/prj.conf @@ -1,3 +1,2 @@ CONFIG_ESP_SPIRAM=y CONFIG_HEAP_MEM_POOL_SIZE=98304 -CONFIG_ESP_HEAP_SEARCH_ALL_REGIONS=n diff --git a/samples/boards/nordic/battery/prj.conf b/samples/boards/nordic/battery/prj.conf index 488a81dca5204..22559d6e7645b 100644 --- a/samples/boards/nordic/battery/prj.conf +++ b/samples/boards/nordic/battery/prj.conf @@ -1 +1,2 @@ CONFIG_ADC=y +CONFIG_GPIO=y diff --git a/samples/boards/nordic/clock_control/configs/global_hsfll.conf b/samples/boards/nordic/clock_control/configs/global_hsfll.conf new file mode 100644 index 0000000000000..53eebac30bed0 --- /dev/null +++ b/samples/boards/nordic/clock_control/configs/global_hsfll.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CLOCK_CONTROL=y + +CONFIG_SAMPLE_CLOCK_FREQUENCY_HZ=320000000 diff --git a/samples/boards/nordic/clock_control/configs/global_hsfll.overlay b/samples/boards/nordic/clock_control/configs/global_hsfll.overlay new file mode 100644 index 0000000000000..24585f5a5c668 --- /dev/null +++ b/samples/boards/nordic/clock_control/configs/global_hsfll.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/{ + aliases { + sample-clock = &hsfll120; + }; +}; diff --git a/samples/boards/nordic/clock_control/sample.yaml b/samples/boards/nordic/clock_control/sample.yaml index dd2cfe86c4181..820ad0de75f44 100644 --- a/samples/boards/nordic/clock_control/sample.yaml +++ b/samples/boards/nordic/clock_control/sample.yaml @@ -29,3 +29,15 @@ tests: extra_args: - CONF_FILE="configs/cpuapp_hsfll.conf" - DTC_OVERLAY_FILE="configs/cpuapp_hsfll.overlay" + sample.boards.nrf.clock_control.global_hsfll: + filter: dt_nodelabel_enabled("hsfll120") + extra_args: + - CONF_FILE="configs/global_hsfll.conf" + - DTC_OVERLAY_FILE="configs/global_hsfll.overlay" + sample.boards.nrf.clock_control.global_hsfll.req_low_freq_n: + filter: dt_nodelabel_enabled("hsfll120") + extra_configs: + - CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_REQ_LOW_FREQ=n + extra_args: + - CONF_FILE="configs/global_hsfll.conf" + - DTC_OVERLAY_FILE="configs/global_hsfll.overlay" diff --git a/samples/boards/nordic/coresight_stm/pytest/test_stm.py b/samples/boards/nordic/coresight_stm/pytest/test_stm.py index fb2203e809e5c..4af24fbfa3c94 100644 --- a/samples/boards/nordic/coresight_stm/pytest/test_stm.py +++ b/samples/boards/nordic/coresight_stm/pytest/test_stm.py @@ -7,6 +7,7 @@ import logging import re import subprocess +from dataclasses import dataclass from pathlib import Path from time import sleep @@ -18,7 +19,8 @@ SB_CONFIG_APP_CPUPPR_RUN = None SB_CONFIG_APP_CPUFLPR_RUN = None -# https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/misc/coresight/nrf_etr.c#L102 +# See definition of stm_m_id[] and stm_m_name[] in +# https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/misc/coresight/nrf_etr.c STM_M_ID = { "sec": 33, "app": 34, @@ -31,7 +33,19 @@ } -def _analyse_autoconf(filepath: str) -> None: +@dataclass +class STMLimits: + log_0_arg: float | None + log_1_arg: float | None + log_2_arg: float | None + log_3_arg: float | None + log_str: float | None + tracepoint: float | None + tracepoint_d32: float | None + tolerance: float | None + + +def analyse_autoconf(filepath: str) -> None: global SB_CONFIG_APP_CPUPPR_RUN global SB_CONFIG_APP_CPUFLPR_RUN @@ -50,7 +64,7 @@ def _analyse_autoconf(filepath: str) -> None: logger.debug(f"{SB_CONFIG_APP_CPUFLPR_RUN=}") -def _check_benchmark_results(output: str, core: str) -> None: +def check_console_output(output: str, core: str) -> None: """ Use regular expressions to parse 'output' string. Search for benchmark results related to 'core' coprocessor. @@ -92,6 +106,55 @@ def _check_benchmark_results(output: str, core: str) -> None: assert latency_tracepoint_d32_str is not None, "Timing for tracepoint_d32 NOT found" +def check_benchmark_results(output: str, core: str, constraints: STMLimits) -> None: + """ + Use regular expressions to parse 'output' string. + Search for benchmark results related to 'core' coprocessor. + Check that benchamrk results are lower than limits provided in 'constraints'. + """ + + cfg = { + "log message with 0 arguments": { + "regex": rf"{core}: Timing for log message with 0 arguments: (.+)us", + "expected": constraints.log_0_arg, + }, + "log message with 1 argument": { + "regex": rf"{core}: Timing for log message with 1 argument: (.+)us", + "expected": constraints.log_1_arg, + }, + "log message with 2 arguments": { + "regex": rf"{core}: Timing for log message with 2 arguments: (.+)us", + "expected": constraints.log_2_arg, + }, + "log message with 3 arguments": { + "regex": rf"{core}: Timing for log message with 3 arguments: (.+)us", + "expected": constraints.log_3_arg, + }, + "log message with string": { + "regex": rf"{core}: Timing for log_message with string: (.+)us", + "expected": constraints.log_str, + }, + "tracepoint": { + "regex": rf"{core}: Timing for tracepoint: (.+)us", + "expected": constraints.tracepoint, + }, + "tracepoint_d32": { + "regex": rf"{core}: Timing for tracepoint_d32: (.+)us", + "expected": constraints.tracepoint_d32, + }, + } + + for check in cfg: + observed_str = re.search(cfg[check]["regex"], output).group(1) + assert observed_str is not None, f"Timing for {check} NOT found" + # check value + observed = float(observed_str) + threshold = cfg[check]["expected"] * (1 + constraints.tolerance) + assert ( + observed < threshold + ), f"{core}: Timing for {check} - {observed} us exceeds {threshold} us" + + # nrfutil starts children processes # when subprocess.terminate(nrfutil_process) is executed, only the parent terminates # this blocks serial port for other uses @@ -104,19 +167,21 @@ def _kill(proc): logger.exception(f'Could not kill nrfutil - {e}') -def _nrfutil_dictionary_from_serial( +def nrfutil_dictionary_from_serial( dut: DeviceAdapter, decoded_file_name: str = "output.txt", collect_time: float = 60.0, ) -> None: UART_PATH = dut.device_config.serial - UART_BAUDRATE = dut.device_config.baud dut.close() logger.debug(f"Using serial: {UART_PATH}") - if Path(f"{decoded_file_name}").exists(): - logger.warning("Output file already exists!") + try: + Path(f"{decoded_file_name}").unlink() + logger.info("Old output file was deleted") + except FileNotFoundError: + pass # prepare database config string BUILD_DIR = str(dut.device_config.build_dir) @@ -132,7 +197,7 @@ def _nrfutil_dictionary_from_serial( cmd = ( "nrfutil trace stm --database-config " f"{config_str} " - f"--input-serialport {UART_PATH} --baudrate {UART_BAUDRATE} " + f"--input-serialport {UART_PATH} " f"--output-ascii {decoded_file_name}" ) try: @@ -149,11 +214,11 @@ def _nrfutil_dictionary_from_serial( _kill(proc) -def test_STM_decoded(dut: DeviceAdapter): +def test_sample_STM_decoded(dut: DeviceAdapter): """ - Run sample.boards.nrf.coresight_stm from samples/boards/nrf/coresight_stm sample. - Both Application and Radio cores use STM for logging. - STM proxy (Application core) decodes logs from all domains. + Run sample.boards.nrf.coresight_stm from samples/boards/nordic/coresight_stm sample. + Application, Radio, PPR and FLPR cores use STM for logging. + STM proxy (Application core) decodes logs from all cores. After reset, coprocessors execute code in expected way and Application core outputs STM traces on UART port. """ @@ -162,45 +227,126 @@ def test_STM_decoded(dut: DeviceAdapter): # nrf54h20 prints immediately after it is flashed. # Wait a bit to skipp logs from previous test. - sleep(4) + sleep(5) # Get output from serial port output = "\n".join(dut.readlines()) # set SB_CONFIG_APP_CPUPPR_RUN, SB_CONFIG_APP_CPUFLPR_RUN - _analyse_autoconf(autoconf_file) + analyse_autoconf(autoconf_file) # check that LOGs from Application core are present - _check_benchmark_results( + check_console_output( output=output, core='app', ) # check that LOGs from Radio core are present - _check_benchmark_results( + check_console_output( output=output, core='rad', ) if SB_CONFIG_APP_CPUPPR_RUN: # check that LOGs from PPR core are present - _check_benchmark_results( + check_console_output( output=output, core='ppr', ) if SB_CONFIG_APP_CPUFLPR_RUN: # check that LOGs from FLPR core are present - _check_benchmark_results( + check_console_output( output=output, core='flpr', ) -def test_STM_dictionary_mode(dut: DeviceAdapter): +def test_STM_decoded(dut: DeviceAdapter): + """ + Run boards.nrf.coresight_stm from tests/boards/nrf/coresight_stm test suite. + Application, Radio, PPR and FLPR cores use STM for logging. + STM proxy (Application core) decodes logs from all cores. + After reset, coprocessors execute code in expected way and Application core + outputs STM traces on UART port. + """ + BUILD_DIR = str(dut.device_config.build_dir) + autoconf_file = f"{BUILD_DIR}/_sysbuild/autoconf.h" + + app_constraints = STMLimits( + # all values in us + log_0_arg=1.8, + log_1_arg=2.1, + log_2_arg=2.0, + log_3_arg=2.1, + log_str=4.5, + tracepoint=0.5, + tracepoint_d32=0.5, + tolerance=0.5, # 50 % + ) + rad_constraints = STMLimits( + # all values in us + log_0_arg=4.6, + log_1_arg=5.0, + log_2_arg=5.2, + log_3_arg=5.6, + log_str=6.3, + tracepoint=0.5, + tracepoint_d32=0.5, + tolerance=0.5, + ) + ppr_constraints = STMLimits( + # all values in us + log_0_arg=25.7, + log_1_arg=27.1, + log_2_arg=27.3, + log_3_arg=30.4, + log_str=65.7, + tracepoint=0.55, + tracepoint_d32=0.25, + tolerance=0.5, + ) + flpr_constraints = STMLimits( + # all values in us + log_0_arg=1.3, + log_1_arg=1.6, + log_2_arg=1.6, + log_3_arg=1.7, + log_str=3.0, + tracepoint=0.5, + tracepoint_d32=0.5, + tolerance=0.5, + ) + + # nrf54h20 prints immediately after it is flashed. + # Wait a bit to skipp logs from previous test. + sleep(5) + + # Get output from serial port + output = "\n".join(dut.readlines()) + + # set SB_CONFIG_APP_CPUPPR_RUN, SB_CONFIG_APP_CPUFLPR_RUN + analyse_autoconf(autoconf_file) + + # check results on Application core + check_benchmark_results(output=output, core='app', constraints=app_constraints) + + # check results on Radio core + check_benchmark_results(output=output, core='rad', constraints=rad_constraints) + + if SB_CONFIG_APP_CPUPPR_RUN: + # check results on PPR core + check_benchmark_results(output=output, core='ppr', constraints=ppr_constraints) + + if SB_CONFIG_APP_CPUFLPR_RUN: + # check results on FLPR core + check_benchmark_results(output=output, core='flpr', constraints=flpr_constraints) + + +def test_sample_STM_dictionary_mode(dut: DeviceAdapter): """ - Run sample.boards.nrf.coresight_stm.dict from samples/boards/nrf/coresight_stm sample. - Both Application and Radio cores use STM for logging. + Run sample.boards.nrf.coresight_stm.dict from samples/boards/nordic/coresight_stm sample. + Application, Radio, PPR and FLPR cores use STM for logging. STM proxy (Application core) prints on serial port raw logs from all domains. Nrfutil trace is used to decode STM logs. After reset, coprocessors execute code in expected way and Application core @@ -213,10 +359,10 @@ def test_STM_dictionary_mode(dut: DeviceAdapter): # set SB_CONFIG_APP_CPUPPR_RUN, SB_CONFIG_APP_CPUFLPR_RUN # this information is needed to build nrfutil database-config - _analyse_autoconf(autoconf_file) + analyse_autoconf(autoconf_file) # use nrfutil trace to decode logs - _nrfutil_dictionary_from_serial( + nrfutil_dictionary_from_serial( dut=dut, decoded_file_name=f"{test_filename}", collect_time=COLLECT_TIMEOUT, @@ -232,27 +378,123 @@ def test_STM_dictionary_mode(dut: DeviceAdapter): ), f"File {test_filename} is empty" # check that LOGs from Application core are present - _check_benchmark_results( + check_console_output( output=decoded_file_content, core='app', ) # check that LOGs from Radio core are present - _check_benchmark_results( + check_console_output( output=decoded_file_content, core='rad', ) if SB_CONFIG_APP_CPUPPR_RUN: # check that LOGs from PPR core are present - _check_benchmark_results( + check_console_output( output=decoded_file_content, core='ppr', ) if SB_CONFIG_APP_CPUFLPR_RUN: # check that LOGs from FLPR core are present - _check_benchmark_results( + check_console_output( output=decoded_file_content, core='flpr', ) + + +def test_STM_dictionary_mode(dut: DeviceAdapter): + """ + Run boards.nrf.coresight_stm.dict from tests/boards/nrf/coresight_stm test suite. + Application, Radio, PPR and FLPR cores use STM for logging. + STM proxy (Application core) prints on serial port raw logs from all domains. + Nrfutil trace is used to decode STM logs. + After reset, coprocessors execute code in expected way and Application core + outputs STM traces on UART port. + """ + BUILD_DIR = str(dut.device_config.build_dir) + test_filename = f"{BUILD_DIR}/coresight_stm_dictionary.txt" + autoconf_file = f"{BUILD_DIR}/_sysbuild/autoconf.h" + COLLECT_TIMEOUT = 10.0 + + app_constraints = STMLimits( + # all values in us + log_0_arg=0.7, + log_1_arg=0.8, + log_2_arg=0.8, + log_3_arg=1.3, + log_str=3.2, + tracepoint=0.5, + tracepoint_d32=0.5, + tolerance=0.5, # 50 % + ) + rad_constraints = STMLimits( + # all values in us + log_0_arg=0.8, + log_1_arg=0.9, + log_2_arg=1.0, + log_3_arg=1.5, + log_str=3.6, + tracepoint=0.5, + tracepoint_d32=0.5, + tolerance=0.5, + ) + ppr_constraints = STMLimits( + # all values in us + log_0_arg=7.5, + log_1_arg=8.5, + log_2_arg=8.6, + log_3_arg=17.4, + log_str=45.2, + tracepoint=0.5, + tracepoint_d32=0.5, + tolerance=0.5, + ) + flpr_constraints = STMLimits( + # all values in us + log_0_arg=0.3, + log_1_arg=0.4, + log_2_arg=0.5, + log_3_arg=0.8, + log_str=2.6, + tracepoint=0.5, + tracepoint_d32=0.5, + tolerance=0.5, # 50 % + ) + + # set SB_CONFIG_APP_CPUPPR_RUN, SB_CONFIG_APP_CPUFLPR_RUN + # this information is needed to build nrfutil database-config + analyse_autoconf(autoconf_file) + + # use nrfutil trace to decode logs + nrfutil_dictionary_from_serial( + dut=dut, + decoded_file_name=f"{test_filename}", + collect_time=COLLECT_TIMEOUT, + ) + + # read decoded logs + with open(f"{test_filename}", errors="ignore") as decoded_file: + decoded_file_content = decoded_file.read() + + # if nothing in decoded_file, stop test + assert len(decoded_file_content) > 0, f"File {test_filename} is empty" + + # check results on Application core + check_benchmark_results(output=decoded_file_content, core='app', constraints=app_constraints) + + # check results on Radio core + check_benchmark_results(output=decoded_file_content, core='rad', constraints=rad_constraints) + + if SB_CONFIG_APP_CPUPPR_RUN: + # check results on PPR core + check_benchmark_results( + output=decoded_file_content, core='ppr', constraints=ppr_constraints + ) + + if SB_CONFIG_APP_CPUFLPR_RUN: + # check results on FLPR core + check_benchmark_results( + output=decoded_file_content, core='flpr', constraints=flpr_constraints + ) diff --git a/samples/boards/nordic/coresight_stm/sample.yaml b/samples/boards/nordic/coresight_stm/sample.yaml index 4251c5d6df8c1..000241d4d979e 100644 --- a/samples/boards/nordic/coresight_stm/sample.yaml +++ b/samples/boards/nordic/coresight_stm/sample.yaml @@ -2,7 +2,7 @@ sample: name: Logging using Coresight STM on nrf54h20 common: - tags: stm + tags: coresight_stm sysbuild: true platform_allow: - nrf54h20dk/nrf54h20/cpuapp @@ -15,7 +15,7 @@ tests: harness_config: pytest_dut_scope: session pytest_root: - - "pytest/test_stm.py::test_STM_dictionary_mode" + - "pytest/test_stm.py::test_sample_STM_dictionary_mode" required_snippets: - nordic-log-stm-dict extra_args: @@ -27,7 +27,7 @@ tests: harness_config: pytest_dut_scope: session pytest_root: - - "pytest/test_stm.py::test_STM_decoded" + - "pytest/test_stm.py::test_sample_STM_decoded" required_snippets: - nordic-log-stm extra_args: diff --git a/samples/boards/nordic/coresight_stm/src/main.c b/samples/boards/nordic/coresight_stm/src/main.c index 221633d8638c4..b788d4fc15d97 100644 --- a/samples/boards/nordic/coresight_stm/src/main.c +++ b/samples/boards/nordic/coresight_stm/src/main.c @@ -103,5 +103,7 @@ int main(void) timing_report(t_tpd, rpt_tp, "tracepoint_d32"); #endif + /* Needed in coverage run to separate STM logs from printk() */ + k_msleep(400); return 0; } diff --git a/samples/boards/nordic/dynamic_pinctrl/prj.conf b/samples/boards/nordic/dynamic_pinctrl/prj.conf index 7aff295bd072c..c54d43cad6387 100644 --- a/samples/boards/nordic/dynamic_pinctrl/prj.conf +++ b/samples/boards/nordic/dynamic_pinctrl/prj.conf @@ -3,3 +3,4 @@ CONFIG_PINCTRL_DYNAMIC=y # configure serial and console to come after remap hook CONFIG_SERIAL_INIT_PRIORITY=60 CONFIG_CONSOLE_INIT_PRIORITY=70 +CONFIG_GPIO=y diff --git a/samples/boards/nordic/mesh/onoff-app/prj.conf b/samples/boards/nordic/mesh/onoff-app/prj.conf index 4c65164456452..0e67042b2653a 100644 --- a/samples/boards/nordic/mesh/onoff-app/prj.conf +++ b/samples/boards/nordic/mesh/onoff-app/prj.conf @@ -9,6 +9,8 @@ CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_NVS=y CONFIG_SETTINGS=y +CONFIG_SECURE_STORAGE=y + CONFIG_BT_MESH_RPL_STORE_TIMEOUT=600 CONFIG_BOOT_BANNER=y @@ -27,7 +29,6 @@ CONFIG_BT_CTLR_PRIVACY=n CONFIG_BT_PERIPHERAL=y CONFIG_BT=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_BT_L2CAP_TX_BUF_COUNT=8 CONFIG_BT_MESH=y diff --git a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/CMakeLists.txt b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/CMakeLists.txt index cbcb8a11d1ab8..67a278e537fe5 100644 --- a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/CMakeLists.txt +++ b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/CMakeLists.txt @@ -18,7 +18,7 @@ target_sources(app PRIVATE src/mesh/transition.c ) -zephyr_include_directories( +target_include_directories(app PRIVATE src/ src/mesh ) diff --git a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/prj.conf b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/prj.conf index b9ce470b9eb6e..3bb984208c708 100644 --- a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/prj.conf +++ b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/prj.conf @@ -7,6 +7,7 @@ CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_NVS=y CONFIG_SETTINGS=y +CONFIG_SECURE_STORAGE=y CONFIG_BT_OBSERVER=y CONFIG_BT_BROADCASTER=y @@ -22,7 +23,6 @@ CONFIG_BT_CTLR_TX_PWR_PLUS_8=y CONFIG_BT_PERIPHERAL=y CONFIG_BT=y -CONFIG_BT_SEND_ECC_EMULATION=y CONFIG_BT_RX_STACK_SIZE=4096 CONFIG_BT_L2CAP_TX_BUF_COUNT=8 diff --git a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c index 1c59ef8fbd752..21067df99aa36 100644 --- a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c +++ b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c @@ -5,8 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include "ble_mesh.h" #include "common.h" #include "device_composition.h" diff --git a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/state_binding.c b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/state_binding.c index c923304f0dc1b..b1d317e6460e6 100644 --- a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/state_binding.c +++ b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/state_binding.c @@ -6,7 +6,6 @@ */ #include -#include #include "ble_mesh.h" #include "device_composition.h" diff --git a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c index 262958ad1c2b1..18adb5a6773eb 100644 --- a/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c +++ b/samples/boards/nordic/mesh/onoff_level_lighting_vnd_app/src/mesh/transition.c @@ -5,8 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include "ble_mesh.h" #include "common.h" #include "device_composition.h" diff --git a/samples/boards/nordic/nrfx_prs/prj.conf b/samples/boards/nordic/nrfx_prs/prj.conf index 4c9d7771ef6a5..3c8ea985f56c9 100644 --- a/samples/boards/nordic/nrfx_prs/prj.conf +++ b/samples/boards/nordic/nrfx_prs/prj.conf @@ -7,3 +7,4 @@ CONFIG_NRFX_PRS_BOX_2=y # This is needed for using another SPIM instance via the Zephyr SPI driver. CONFIG_SPI=y +CONFIG_GPIO=y diff --git a/samples/boards/nordic/nrfx_prs/src/main.c b/samples/boards/nordic/nrfx_prs/src/main.c index cf989b4c4c9ec..1b9411d2da43a 100644 --- a/samples/boards/nordic/nrfx_prs/src/main.c +++ b/samples/boards/nordic/nrfx_prs/src/main.c @@ -122,6 +122,7 @@ static bool switch_to_spim(void) { int ret; nrfx_err_t err; + uint32_t sck_pin; PINCTRL_DT_DEFINE(SPIM_NODE); @@ -155,8 +156,11 @@ static bool switch_to_spim(void) } /* Set initial state of SCK according to the SPI mode. */ - nrfy_gpio_pin_write(nrfy_spim_sck_pin_get(spim.p_reg), - (spim_config.mode <= NRF_SPIM_MODE_1) ? 0 : 1); + sck_pin = nrfy_spim_sck_pin_get(spim.p_reg); + + if (sck_pin != NRF_SPIM_PIN_NOT_CONNECTED) { + nrfy_gpio_pin_write(sck_pin, (spim_config.mode <= NRF_SPIM_MODE_1) ? 0 : 1); + } err = nrfx_spim_init(&spim, &spim_config, spim_handler, NULL); if (err != NRFX_SUCCESS) { diff --git a/samples/boards/nordic/system_off/CMakeLists.txt b/samples/boards/nordic/system_off/CMakeLists.txt index 1cff779506b9a..a4105e44c9798 100644 --- a/samples/boards/nordic/system_off/CMakeLists.txt +++ b/samples/boards/nordic/system_off/CMakeLists.txt @@ -5,6 +5,6 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(nrf_system_off) target_sources(app PRIVATE src/main.c) -if (CONFIG_APP_USE_NRF_RETENTION OR CONFIG_APP_USE_RETAINED_MEM) +if(CONFIG_APP_USE_RETAINED_MEM) target_sources(app PRIVATE src/retained.c) endif() diff --git a/samples/boards/nordic/system_off/Kconfig b/samples/boards/nordic/system_off/Kconfig index 910a64f6fbe07..c7b4a9f85575b 100644 --- a/samples/boards/nordic/system_off/Kconfig +++ b/samples/boards/nordic/system_off/Kconfig @@ -3,27 +3,24 @@ mainmenu "Nordic SYSTEM_OFF demo" -choice - prompt "Use retention" - optional - -config APP_USE_NRF_RETENTION - bool "Use state retention in system off using nRF POWER" - depends on SOC_COMPATIBLE_NRF52X && CRC - help - On some Nordic chips this application supports retaining - memory while in system off using POWER peripheral. - Select this to enable the feature. - config APP_USE_RETAINED_MEM bool "Use state retention in system off using retained_mem driver" - depends on RETAINED_MEM + select RETAINED_MEM -endchoice +config GPIO_WAKEUP_ENABLE + bool "Use button to wake up device from system off" + default y + help + Enable system off wakeup from pressing sw0 button. config GRTC_WAKEUP_ENABLE bool "Use GRTC to wake up device from system off" help - Switch wake up source from pressing sw0 button to GRTC + Enable system off wakeup from GRTC. + +config LPCOMP_WAKEUP_ENABLE + bool "Use COMP to wake up device from system off" + help + Enable system off wakeup from analog comparator. source "Kconfig.zephyr" diff --git a/samples/boards/nordic/system_off/README.rst b/samples/boards/nordic/system_off/README.rst index 7c98a4e833628..5124d087b77fb 100644 --- a/samples/boards/nordic/system_off/README.rst +++ b/samples/boards/nordic/system_off/README.rst @@ -13,10 +13,10 @@ deep sleep on Nordic platforms. RAM Retention ============= -This sample can also can demonstrate RAM retention. By selecting -``CONFIG_APP_USE_NRF_RETENTION=y`` or ``CONFIG_APP_USE_RETAINED_MEM=y`` -state related to number of boots, number of times system off was entered, -and total uptime since initial power-on are retained in a checksummed data structure. +This sample can also demonstrate RAM retention. +By selecting ``CONFIG_APP_USE_RETAINED_MEM=y`` state related to number of boots, +number of times system off was entered, and total uptime since initial power-on +are retained in a checksummed data structure. RAM is configured to keep the containing section powered while in system-off mode. Requirements diff --git a/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay b/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 0000000000000..c203d90a0a144 --- /dev/null +++ b/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,22 @@ +/ { + sram0@2003f000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2003f000 DT_SIZE_K(4)>; + zephyr,memory-region = "RetainedMem"; + status = "okay"; + + retainedmem0: retainedmem { + compatible = "zephyr,retained-ram"; + status = "okay"; + }; + }; + + aliases { + retainedmemdevice = &retainedmem0; + }; +}; + +&sram0 { + /* Shrink SRAM size to avoid overlap with retained memory region */ + reg = <0x20000000 DT_SIZE_K(252)>; +}; diff --git a/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay b/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay new file mode 100644 index 0000000000000..13e2e99ddf283 --- /dev/null +++ b/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay @@ -0,0 +1,22 @@ +/ { + sram0@20007000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20007000 DT_SIZE_K(4)>; + zephyr,memory-region = "RetainedMem"; + status = "okay"; + + retainedmem0: retainedmem { + compatible = "zephyr,retained-ram"; + status = "okay"; + }; + }; + + aliases { + retainedmemdevice = &retainedmem0; + }; +}; + +&sram0 { + /* Shrink SRAM size to avoid overlap with retained memory region */ + reg = <0x20000000 DT_SIZE_K(28)>; +}; diff --git a/samples/boards/nordic/system_off/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/boards/nordic/system_off/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 0000000000000..383d9896bea3b --- /dev/null +++ b/samples/boards/nordic/system_off/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,22 @@ +/ { + sram0_image@2006f000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2006f000 DT_SIZE_K(4)>; + zephyr,memory-region = "RetainedMem"; + status = "okay"; + + retainedmem0: retainedmem { + compatible = "zephyr,retained-ram"; + status = "okay"; + }; + }; + + aliases { + retainedmemdevice = &retainedmem0; + }; +}; + +&sram0_image { + /* Shrink SRAM size to avoid overlap with retained memory region */ + reg = <0x20000000 DT_SIZE_K(444)>; +}; diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp.overlay similarity index 100% rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp_retained_mem.overlay rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp.overlay diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp.overlay similarity index 100% rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp_retained_mem.overlay rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp.overlay diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp.overlay similarity index 100% rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp.overlay diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_comparator.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_comparator.overlay new file mode 100644 index 0000000000000..f0b39b456206f --- /dev/null +++ b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_comparator.overlay @@ -0,0 +1,6 @@ +&comp { + compatible = "nordic,nrf-lpcomp"; + psel = "AIN4"; + refsel = "VDD_4_8"; + status = "okay"; +}; diff --git a/samples/boards/nordic/system_off/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay b/samples/boards/nordic/system_off/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay new file mode 100644 index 0000000000000..3a79636a4833b --- /dev/null +++ b/samples/boards/nordic/system_off/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay @@ -0,0 +1,25 @@ +/ { + cpuapp_sram@2007ec00 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2007ec00 DT_SIZE_K(4)>; + zephyr,memory-region = "RetainedMem"; + status = "okay"; + + retainedmem0: retainedmem { + compatible = "zephyr,retained-ram"; + status = "okay"; + }; + }; + + aliases { + retainedmemdevice = &retainedmem0; + }; +}; + +&cpuapp_sram { + /* Shrink SRAM size to avoid overlap with retained memory region: + * 511 - 4 = 507KB = 0x7ec00 + */ + reg = <0x20000000 DT_SIZE_K(507)>; + ranges = <0x0 0x20000000 0x7ec00>; +}; diff --git a/samples/boards/nordic/system_off/sample.yaml b/samples/boards/nordic/system_off/sample.yaml index 18f629c4e540f..bed08d8fe525a 100644 --- a/samples/boards/nordic/system_off/sample.yaml +++ b/samples/boards/nordic/system_off/sample.yaml @@ -14,6 +14,7 @@ tests: - nrf54l15dk/nrf54l05/cpuapp - nrf54l15dk/nrf54l10/cpuapp - nrf54l15dk/nrf54l15/cpuapp + - nrf54l20pdk/nrf54l20/cpuapp harness: console harness_config: type: multi_line @@ -22,32 +23,19 @@ tests: - "system off demo" - "Retained data not supported" - "Entering system off; press sw0 to restart" - sample.boards.nrf.system_off.nrf_retained: + sample.boards.nrf.system_off.retained_mem: integration_platforms: - nrf52840dk/nrf52840 platform_allow: - nrf52840dk/nrf52840 - nrf52dk/nrf52832 - extra_configs: - - CONFIG_APP_USE_NRF_RETENTION=y - harness: console - harness_config: - type: multi_line - ordered: true - regex: - - "system off demo" - - "Retained data: INVALID" - - "Boot count: 1" - - "Off count: 0" - - "Active Ticks:" - - "Entering system off; press sw0 to restart" - sample.boards.nrf.system_off.retained_mem: - extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay" - platform_allow: + - nrf5340dk/nrf5340/cpuapp + - nrf54l15dk/nrf54l05/cpuapp + - nrf54l15dk/nrf54l10/cpuapp - nrf54l15dk/nrf54l15/cpuapp + - nrf54l20pdk/nrf54l20/cpuapp extra_configs: - CONFIG_APP_USE_RETAINED_MEM=y - - CONFIG_RETAINED_MEM=y harness: console harness_config: type: multi_line @@ -61,9 +49,13 @@ tests: - "Entering system off; press sw0 to restart" sample.boards.nrf.system_off.grtc_wakeup: platform_allow: + - nrf54l15dk/nrf54l05/cpuapp + - nrf54l15dk/nrf54l10/cpuapp - nrf54l15dk/nrf54l15/cpuapp + - nrf54l20pdk/nrf54l20/cpuapp extra_configs: - CONFIG_GRTC_WAKEUP_ENABLE=y + - CONFIG_GPIO_WAKEUP_ENABLE=n harness: console harness_config: type: multi_line @@ -79,13 +71,15 @@ tests: - "Retained data not supported" - "Entering system off; wait 2 seconds to restart" sample.boards.nrf.system_off.retained_mem.grtc_wakeup: - extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay" platform_allow: + - nrf54l15dk/nrf54l05/cpuapp + - nrf54l15dk/nrf54l10/cpuapp - nrf54l15dk/nrf54l15/cpuapp + - nrf54l20pdk/nrf54l20/cpuapp extra_configs: - CONFIG_APP_USE_RETAINED_MEM=y - CONFIG_GRTC_WAKEUP_ENABLE=y - - CONFIG_RETAINED_MEM=y + - CONFIG_GPIO_WAKEUP_ENABLE=n harness: console harness_config: type: multi_line @@ -103,3 +97,43 @@ tests: - "Off count: 1" - "Active Ticks:" - "Entering system off; wait 2 seconds to restart" + sample.boards.nrf.system_off.lpcomp_wakeup: + extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_comparator.overlay" + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + extra_configs: + - CONFIG_LPCOMP_WAKEUP_ENABLE=y + - CONFIG_GPIO_WAKEUP_ENABLE=n + - CONFIG_COMPARATOR=y + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "system off demo" + - "Retained data not supported" + - "Entering system off; change signal level at comparator input to restart" + sample.boards.nrf.system_off.retained_mem.lpcomp_wakeup: + extra_args: + - "DTC_OVERLAY_FILE= + boards/nrf54l15dk_nrf54l15_cpuapp_comparator.overlay; + boards/nrf54l15dk_nrf54l15_cpuapp.overlay" + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + extra_configs: + - CONFIG_APP_USE_RETAINED_MEM=y + - CONFIG_GPIO_WAKEUP_ENABLE=n + - CONFIG_LPCOMP_WAKEUP_ENABLE=y + - CONFIG_RETAINED_MEM=y + - CONFIG_COMPARATOR=y + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "system off demo" + - "Retained data: INVALID" + - "Boot count: 1" + - "Off count: 0" + - "Active Ticks:" + - "Entering system off; change signal level at comparator input to restart" diff --git a/samples/boards/nordic/system_off/src/main.c b/samples/boards/nordic/system_off/src/main.c index c10dda31fc9cd..e8617be2c5f96 100644 --- a/samples/boards/nordic/system_off/src/main.c +++ b/samples/boards/nordic/system_off/src/main.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -19,9 +20,13 @@ #if defined(CONFIG_GRTC_WAKEUP_ENABLE) #include #define DEEP_SLEEP_TIME_S 2 -#else +#endif +#if defined(CONFIG_GPIO_WAKEUP_ENABLE) static const struct gpio_dt_spec sw0 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios); #endif +#if defined(CONFIG_LPCOMP_WAKEUP_ENABLE) +static const struct device *comp_dev = DEVICE_DT_GET(DT_NODELABEL(comp)); +#endif int main(void) { @@ -35,7 +40,7 @@ int main(void) printf("\n%s system off demo\n", CONFIG_BOARD); - if (IS_ENABLED(CONFIG_APP_USE_NRF_RETENTION) || IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) { + if (IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) { bool retained_ok = retained_validate(); /* Increment for this boot attempt and update. */ @@ -58,7 +63,8 @@ int main(void) } else { printk("Entering system off; wait %u seconds to restart\n", DEEP_SLEEP_TIME_S); } -#else +#endif +#if defined(CONFIG_GPIO_WAKEUP_ENABLE) /* configure sw0 as input, interrupt as level active to allow wake-up */ rc = gpio_pin_configure_dt(&sw0, GPIO_INPUT); if (rc < 0) { @@ -74,6 +80,11 @@ int main(void) printf("Entering system off; press sw0 to restart\n"); #endif +#if defined(CONFIG_LPCOMP_WAKEUP_ENABLE) + comparator_set_trigger(comp_dev, COMPARATOR_TRIGGER_BOTH_EDGES); + comparator_trigger_is_pending(comp_dev); + printf("Entering system off; change signal level at comparator input to restart\n"); +#endif rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND); if (rc < 0) { @@ -81,7 +92,7 @@ int main(void) return 0; } - if (IS_ENABLED(CONFIG_APP_USE_NRF_RETENTION) || IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) { + if (IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) { /* Update the retained state */ retained.off_count += 1; retained_update(); diff --git a/samples/boards/nordic/system_off/src/retained.c b/samples/boards/nordic/system_off/src/retained.c index 66f6a353f0409..316ec165d620d 100644 --- a/samples/boards/nordic/system_off/src/retained.c +++ b/samples/boards/nordic/system_off/src/retained.c @@ -15,147 +15,24 @@ #include #include -#if CONFIG_APP_USE_NRF_RETENTION -#include - -/* nRF52 RAM (really, RAM AHB slaves) are partitioned as: - * * Up to 8 blocks of two 4 KiBy byte "small" sections - * * A 9th block of with 32 KiBy "large" sections - * - * At time of writing the maximum number of large sections is 6, all - * within the first large block. Theoretically there could be more - * sections in the 9th block, and possibly more blocks. - */ - -/* Inclusive address of RAM start */ -#define SRAM_BEGIN (uintptr_t)DT_REG_ADDR(DT_NODELABEL(sram0)) - -/* Exclusive address of RAM end */ -#define SRAM_END (SRAM_BEGIN + (uintptr_t)DT_REG_SIZE(DT_NODELABEL(sram0))) - -/* Size of a controllable RAM section in the small blocks */ -#define SMALL_SECTION_SIZE 4096 - -/* Number of controllable RAM sections in each of the lower blocks */ -#define SMALL_SECTIONS_PER_BLOCK 2 - -/* Span of a small block */ -#define SMALL_BLOCK_SIZE (SMALL_SECTIONS_PER_BLOCK * SMALL_SECTION_SIZE) - -/* Number of small blocks */ -#define SMALL_BLOCK_COUNT 8 - -/* Span of the SRAM area covered by small sections */ -#define SMALL_SECTION_SPAN (SMALL_BLOCK_COUNT * SMALL_BLOCK_SIZE) - -/* Inclusive address of the RAM range covered by large sections */ -#define LARGE_SECTION_BEGIN (SRAM_BEGIN + SMALL_SECTION_SPAN) - -/* Size of a controllable RAM section in large blocks */ -#define LARGE_SECTION_SIZE 32768 - -#elif CONFIG_APP_USE_RETAINED_MEM +#if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(retainedmemdevice)) const static struct device *retained_mem_device = DEVICE_DT_GET(DT_ALIAS(retainedmemdevice)); -#endif - -/* Set or clear RAM retention in SYSTEM_OFF for the provided object. - * - * @param ptr pointer to the start of the retainable object - * - * @param len length of the retainable object - * - * @param enable true to enable retention, false to clear retention - */ -static int ram_range_retain(const void *ptr, - size_t len, - bool enable) -{ - int rc = 0; - -#if CONFIG_APP_USE_NRF_RETENTION - /* This only works for nRF52 with the POWER module. - * The other Nordic chips use a different low-level API, - * which is not currently used by this variant. - */ - uintptr_t addr = (uintptr_t)ptr; - uintptr_t addr_end = addr + len; - - /* Error if the provided range is empty or doesn't lie - * entirely within the SRAM address space. - */ - if ((len == 0U) - || (addr < SRAM_BEGIN) - || (addr > (SRAM_END - len))) { - return -EINVAL; - } - - /* Iterate over each section covered by the range, setting the - * corresponding RAM OFF retention bit in the parent block. - */ - do { - uintptr_t block_base = SRAM_BEGIN; - uint32_t section_size = SMALL_SECTION_SIZE; - uint32_t sections_per_block = SMALL_SECTIONS_PER_BLOCK; - bool is_large = (addr >= LARGE_SECTION_BEGIN); - uint8_t block = 0; - - if (is_large) { - block = 8; - block_base = LARGE_SECTION_BEGIN; - section_size = LARGE_SECTION_SIZE; - - /* RAM[x] supports only 16 sections, each its own bit - * for POWER (0..15) and RETENTION (16..31). We don't - * know directly how many sections are present, so - * assume they all are; the true limit will be - * determined by the SRAM size. - */ - sections_per_block = 16; - } - - uint32_t section = (addr - block_base) / section_size; - - if (section >= sections_per_block) { - block += section / sections_per_block; - section %= sections_per_block; - } - - uint32_t section_mask = - (POWER_RAM_POWERSET_S0RETENTION_On - << (section + POWER_RAM_POWERSET_S0RETENTION_Pos)); - - if (enable) { - nrf_power_rampower_mask_on(NRF_POWER, block, section_mask); - } else { - nrf_power_rampower_mask_off(NRF_POWER, block, section_mask); - } - - /* Move to the first address in the next section. */ - addr += section_size - (addr % section_size); - } while (addr < addr_end); -#elif CONFIG_APP_USE_RETAINED_MEM - /* Retention setting cannot be controlled runtime with retained_mem API */ - (void)enable; - rc = retained_mem_write(retained_mem_device, 0, ptr, len); #else - #error "Unsupported retention setting" +#error "retained_mem region not defined" #endif - return rc; -} - -/* Retained data must be defined in a no-init section to prevent the C - * runtime initialization from zeroing it before anybody can see it. - * It is not necesarry when retained_mem driver is utilized - * as in this case retained data is stored in an area not initialized in runtime. - */ -__noinit struct retained_data retained; +struct retained_data retained; #define RETAINED_CRC_OFFSET offsetof(struct retained_data, crc) #define RETAINED_CHECKED_SIZE (RETAINED_CRC_OFFSET + sizeof(retained.crc)) bool retained_validate(void) { + int rc; + + rc = retained_mem_read(retained_mem_device, 0, (uint8_t *)&retained, sizeof(retained)); + __ASSERT_NO_MSG(rc == 0); + /* The residue of a CRC is what you get from the CRC over the * message catenated with its CRC. This is the post-final-xor * residue for CRC-32 (CRC-32/ISO-HDLC) which Zephyr calls @@ -174,19 +51,13 @@ bool retained_validate(void) /* Reset to accrue runtime from this session. */ retained.uptime_latest = 0; - /* Reconfigure to retain the state during system off, regardless of - * whether validation succeeded. Although these values can sometimes - * be observed to be preserved across System OFF, the product - * specification states they are not retained in that situation, and - * that can also be observed. - */ - (void)ram_range_retain(&retained, RETAINED_CHECKED_SIZE, true); - return valid; } void retained_update(void) { + int rc; + uint64_t now = k_uptime_ticks(); retained.uptime_sum += (now - retained.uptime_latest); @@ -196,4 +67,7 @@ void retained_update(void) RETAINED_CRC_OFFSET); retained.crc = sys_cpu_to_le32(crc); + + rc = retained_mem_write(retained_mem_device, 0, (uint8_t *)&retained, sizeof(retained)); + __ASSERT_NO_MSG(rc == 0); } diff --git a/samples/boards/nxp/mimxrt1060_evk/system_off/prj.conf b/samples/boards/nxp/mimxrt1060_evk/system_off/prj.conf index 877c720aac355..3bcd2f7797d6e 100644 --- a/samples/boards/nxp/mimxrt1060_evk/system_off/prj.conf +++ b/samples/boards/nxp/mimxrt1060_evk/system_off/prj.conf @@ -5,3 +5,4 @@ CONFIG_COUNTER=y CONFIG_COUNTER_MCUX_SNVS=y CONFIG_COUNTER_MCUX_SNVS_SRTC=y CONFIG_COUNTER_MCUX_SNVS_SRTC_WAKE=y +CONFIG_GPIO=y diff --git a/samples/boards/nxp/mimxrt1060_evk/system_off/sample.yaml b/samples/boards/nxp/mimxrt1060_evk/system_off/sample.yaml index a871dcc74f8db..d6ca0dd5ee0ea 100644 --- a/samples/boards/nxp/mimxrt1060_evk/system_off/sample.yaml +++ b/samples/boards/nxp/mimxrt1060_evk/system_off/sample.yaml @@ -6,7 +6,8 @@ tests: sample.boards.mimxrt1060_evk.system_off: build_only: true platform_allow: - - mimxrt1060_evk - - mimxrt1060_evkb + - mimxrt1060_evk@A/mimxrt1062/qspi + - mimxrt1060_evk@B/mimxrt1062/qspi + - mimxrt1060_evk@C/mimxrt1062/qspi integration_platforms: - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi diff --git a/samples/boards/nxp/mimxrt1170_evk_cm7/magic_addr/pytest/test_magic_addr.py b/samples/boards/nxp/mimxrt1170_evk_cm7/magic_addr/pytest/test_magic_addr.py new file mode 100644 index 0000000000000..3943c1aa092c4 --- /dev/null +++ b/samples/boards/nxp/mimxrt1170_evk_cm7/magic_addr/pytest/test_magic_addr.py @@ -0,0 +1,24 @@ +# Copyright (c) 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +import logging + +from twister_harness import DeviceAdapter + +logger = logging.getLogger(__name__) + + +def test_magic_addr(dut: DeviceAdapter): + ''' + tag memory twice and check result + ''' + dut.readlines_until(regex='Cast some characters:', print_output=True) + dut.write(str.encode('A')) + lines = dut.readlines_until(regex='Magic DTCM address accessed', print_output=True) + logger.info(lines) + dut.write(str.encode('B')) + lines = dut.readlines_until(regex='Magic DTCM address accessed', print_output=True) + logger.info(lines) + ret = any('Magic DTCM address accessed' in line for line in lines) + assert ret diff --git a/samples/boards/nxp/mimxrt1170_evk_cm7/magic_addr/sample.yaml b/samples/boards/nxp/mimxrt1170_evk_cm7/magic_addr/sample.yaml index 462a1d165e534..45a3e95fe97f8 100644 --- a/samples/boards/nxp/mimxrt1170_evk_cm7/magic_addr/sample.yaml +++ b/samples/boards/nxp/mimxrt1170_evk_cm7/magic_addr/sample.yaml @@ -1,12 +1,13 @@ sample: - description: RT1170 FLEXRAM Magic Addr example + description: RT11xx FLEXRAM Magic Addr example name: magic addr common: integration_platforms: - mimxrt1170_evk/mimxrt1176/cm7 - mimxrt1160_evk/mimxrt1166/cm7 + tags: + - pytest tests: - sample.boards.mimxrt1170_evk.magic_addr: - platform_allow: - - mimxrt1170_evk/mimxrt1176/cm7 - - mimxrt1160_evk/mimxrt1166/cm7 + sample.boards.magic_addr: + filter: dt_node_prop_enabled("flexram", "flexram,has-magic-addr") + harness: pytest diff --git a/samples/boards/phytec/reel_board/mesh_badge/prj.conf b/samples/boards/phytec/reel_board/mesh_badge/prj.conf index ad6f656f30154..5367f4d1e9a6a 100644 --- a/samples/boards/phytec/reel_board/mesh_badge/prj.conf +++ b/samples/boards/phytec/reel_board/mesh_badge/prj.conf @@ -66,4 +66,5 @@ CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_NVS=y CONFIG_SETTINGS=y +CONFIG_SECURE_STORAGE=y CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/samples/boards/phytec/reel_board/mesh_badge/src/periphs.c b/samples/boards/phytec/reel_board/mesh_badge/src/periphs.c index d4883397c2d28..76ce27e3c027c 100644 --- a/samples/boards/phytec/reel_board/mesh_badge/src/periphs.c +++ b/samples/boards/phytec/reel_board/mesh_badge/src/periphs.c @@ -5,7 +5,6 @@ */ #include -#include #include #include "board.h" #include "mesh.h" diff --git a/samples/boards/raspberrypi/rpi_pico/uart_pio/boards/rpi_pico2_rp2350a_m33.overlay b/samples/boards/raspberrypi/rpi_pico/uart_pio/boards/rpi_pico2_rp2350a_m33.overlay new file mode 100644 index 0000000000000..8b83efe6ea08f --- /dev/null +++ b/samples/boards/raspberrypi/rpi_pico/uart_pio/boards/rpi_pico2_rp2350a_m33.overlay @@ -0,0 +1,8 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Andrew Featherstone + */ + +/* Pico 2 is compatible with the Pico 1, so reuse. */ +#include "rpi_pico.overlay" diff --git a/samples/boards/st/bluetooth/interactive_gui/src/main.c b/samples/boards/st/bluetooth/interactive_gui/src/main.c index 9b31a1e69ffc9..56ef463c761d8 100644 --- a/samples/boards/st/bluetooth/interactive_gui/src/main.c +++ b/samples/boards/st/bluetooth/interactive_gui/src/main.c @@ -51,7 +51,7 @@ static K_FIFO_DEFINE(uart_tx_queue); #define ST_DISCARD 3 /* Dropping packet. */ /* Length of a discard/flush buffer. - * This is sized to align with a BLE HCI packet: + * This is sized to align with a Bluetooth HCI packet: * 1 byte H:4 header + 32 bytes ACL/event data * Bigger values might overflow the stack since this is declared as a local * variable, smaller ones will force the caller to call into discard more diff --git a/samples/boards/st/mco/README.rst b/samples/boards/st/mco/README.rst index cb3c1d9e92719..57b1b25d6c0df 100644 --- a/samples/boards/st/mco/README.rst +++ b/samples/boards/st/mco/README.rst @@ -16,6 +16,13 @@ Requirements The SoC should support MCO functionality and use a pin that has the MCO alternate function. To support another board, add a dts overlay file in boards folder. Make sure that the output clock is enabled in dts overlay file. +Depending on the stm32 serie, several clock source and prescaler are possible for each MCOx. +The clock source is set by the DTS among the possible values for each stm32 serie. +The prescaler is set by the DTS, through the property ``prescaler = ;`` + +See :zephyr_file:`dts/bindings/clock/st,stm32-clock-mco.yaml` + +It is required to check the Reference Manual to configure the DTS correctly. Building and Running diff --git a/samples/boards/st/mco/boards/nucleo_f411re.overlay b/samples/boards/st/mco/boards/nucleo_f411re.overlay new file mode 100644 index 0000000000000..3e71e127fd0dc --- /dev/null +++ b/samples/boards/st/mco/boards/nucleo_f411re.overlay @@ -0,0 +1,30 @@ +/* Enable the PLLI2s and set it as clock source for the MCO2 (with prescaler 5) */ + +&plli2s { + div-m = <8>; + mul-n = <100>; + div-r = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +/* see RefMan RM0383 */ +&mco1 { + /* Select One of the line below for clock source */ + clocks = <&rcc STM32_SRC_HSI MCO1_SEL(0)>; +/* clocks = <&rcc STM32_SRC_LSE MCO1_SEL(1)>; */ +/* clocks = <&rcc STM32_SRC_HSE MCO1_SEL(2)>; */ +/* clocks = <&rcc STM32_SRC_PLL_P MCO1_SEL(3)>; */ + prescaler = ; + pinctrl-0 = <&rcc_mco_1_pa8>; + pinctrl-names = "default"; + status = "okay"; +}; + +&mco2 { + clocks = <&rcc STM32_SRC_PLLI2S_R MCO2_SEL(1)>; + prescaler = ; + pinctrl-0 = <&rcc_mco_2_pc9>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/boards/st/mco/boards/nucleo_f446ze.overlay b/samples/boards/st/mco/boards/nucleo_f446ze.overlay new file mode 100644 index 0000000000000..4a1713ba49daa --- /dev/null +++ b/samples/boards/st/mco/boards/nucleo_f446ze.overlay @@ -0,0 +1,30 @@ +/* Enable the PLLI2s and set it as clock source for the MCO2 (with prescaler 2) : 25MHz */ + +&plli2s { + div-m = <8>; + mul-n = <100>; + div-r = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +/* see RefMan RM0390 */ +&mco1 { + /* Select One of the line below for clock source */ +/* clocks = <&rcc STM32_SRC_HSI MCO1_SEL(0)>; */ +/* clocks = <&rcc STM32_SRC_LSE MCO1_SEL(1)>; */ + clocks = <&rcc STM32_SRC_HSE MCO1_SEL(2)>; +/* clocks = <&rcc STM32_SRC_PLL_P MCO1_SEL(3)>;*/ + prescaler = ; + pinctrl-0 = <&rcc_mco_1_pa8>; + pinctrl-names = "default"; + status = "okay"; +}; + +&mco2 { + clocks = <&rcc STM32_SRC_PLLI2S_R MCO2_SEL(1)>; + prescaler = ; + pinctrl-0 = <&rcc_mco_2_pc9>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/samples/boards/st/mco/boards/nucleo_u5a5zj_q.overlay b/samples/boards/st/mco/boards/nucleo_u5a5zj_q.overlay index acff74efdc3b9..05510d7b06e7d 100644 --- a/samples/boards/st/mco/boards/nucleo_u5a5zj_q.overlay +++ b/samples/boards/st/mco/boards/nucleo_u5a5zj_q.overlay @@ -8,15 +8,10 @@ */ #define MCO1_SEL_LSE 7 -/* See reference manual (RM0456): - * 0b001: MCO divided by 2 - */ -#define MCO1_PRE_DIV_2 1 - &mco1 { status = "okay"; clocks = <&rcc STM32_SRC_LSE MCO1_SEL(MCO1_SEL_LSE)>; - prescaler = ; + prescaler = ; pinctrl-0 = <&rcc_mco_pa8>; pinctrl-names = "default"; }; diff --git a/samples/boards/st/mco/boards/nucleo_wba55cg.overlay b/samples/boards/st/mco/boards/nucleo_wba55cg.overlay new file mode 100644 index 0000000000000..f73226be39953 --- /dev/null +++ b/samples/boards/st/mco/boards/nucleo_wba55cg.overlay @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 STMicroelectronics + */ + +/* The clock that is output must be enabled. */ +&clk_lse { + status = "okay"; +}; +/* MCO use same pin like usart1 RX - disable usart */ +/ { + chosen { + zephyr,bt-c2h-uart = &lpuart1; + zephyr,uart-pipe = &lpuart1; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + }; +}; +&usart1 { + status = "disabled"; +}; + +&mco1 { + status = "okay"; + clocks = <&rcc STM32_SRC_LSE MCO1_SEL(MCO_SEL_LSE)>; + prescaler = ; + pinctrl-0 = <&rcc_mco_pa8>; + pinctrl-names = "default"; +}; diff --git a/samples/boards/st/mco/boards/stm32f746g_disco.overlay b/samples/boards/st/mco/boards/stm32f746g_disco.overlay index a69e0d147b5e4..c480dc9b0f449 100644 --- a/samples/boards/st/mco/boards/stm32f746g_disco.overlay +++ b/samples/boards/st/mco/boards/stm32f746g_disco.overlay @@ -12,15 +12,10 @@ */ #define MCO1_SEL_LSE 1 -/* See reference manual (RM0385): - * 0b100: division by 2 - */ -#define MCO1_PRE_DIV_2 4 - &mco1 { status = "okay"; clocks = <&rcc STM32_SRC_LSE MCO1_SEL(MCO1_SEL_LSE)>; - prescaler = ; + prescaler = ; pinctrl-0 = <&rcc_mco_1_pa8>; /* D10 (CN7) */ pinctrl-names = "default"; }; @@ -30,15 +25,10 @@ */ #define MCO2_SEL_HSE 2 -/* See reference manual (RM0385): - * 0b111: division by 5 - */ -#define MCO2_PRE_DIV_5 7 - &mco2 { status = "okay"; clocks = <&rcc STM32_SRC_HSE MCO2_SEL(MCO2_SEL_HSE)>; - prescaler = ; + prescaler = ; pinctrl-0 = <&rcc_mco_2_pc9>; /* uSD_D1 (CN3 pin 8) */ pinctrl-names = "default"; }; diff --git a/samples/boards/st/mco/sample.yaml b/samples/boards/st/mco/sample.yaml index 1cecb6772eabf..e9f9cddcb0f19 100644 --- a/samples/boards/st/mco/sample.yaml +++ b/samples/boards/st/mco/sample.yaml @@ -3,6 +3,11 @@ sample: tests: sample.board.stm32.mco: platform_allow: + - nucleo_f411re + - nucleo_f446ze + - stm32f746g_disco - nucleo_u5a5zj_q + - nucleo_wba55cg + integration_platforms: - stm32f746g_disco tags: board diff --git a/samples/boards/st/mco/src/main.c b/samples/boards/st/mco/src/main.c index 7e79d1e8cd8dc..92df7ad883662 100644 --- a/samples/boards/st/mco/src/main.c +++ b/samples/boards/st/mco/src/main.c @@ -9,7 +9,6 @@ int main(void) { - const struct device *dev; /* This sample demonstrates MCO usage via Device Tree. * MCO configuration is performed in the Device Tree overlay files. @@ -17,23 +16,30 @@ int main(void) * initialization. This sample checks that all MCOs are ready - if so, * the selected clock should be visible on the chosen GPIO pin. */ - dev = DEVICE_DT_GET(DT_NODELABEL(mco1)); - if (device_is_ready(dev)) { + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mco1)) + const struct device *dev1; + + dev1 = DEVICE_DT_GET(DT_NODELABEL(mco1)); + if (device_is_ready(dev1)) { printk("MCO1 device successfully configured\n"); } else { printk("MCO1 device not ready\n"); return -1; } +#endif /* mco1 */ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mco2)) - dev = DEVICE_DT_GET(DT_NODELABEL(mco2)); - if (device_is_ready(dev)) { + const struct device *dev2; + + dev2 = DEVICE_DT_GET(DT_NODELABEL(mco2)); + if (device_is_ready(dev2)) { printk("MCO2 device successfully configured\n"); } else { printk("MCO2 device not ready\n"); return -1; } -#endif +#endif /* mco2 */ printk("\nDisplayed the status of all MCO devices - end of example.\n"); return 0; diff --git a/samples/boards/st/power_mgmt/blinky/prj.conf b/samples/boards/st/power_mgmt/blinky/prj.conf index 6888f24a03f9a..105b9e19c1352 100644 --- a/samples/boards/st/power_mgmt/blinky/prj.conf +++ b/samples/boards/st/power_mgmt/blinky/prj.conf @@ -3,3 +3,4 @@ CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y CONFIG_PM_DEVICE_SYSTEM_MANAGED=y CONFIG_ASSERT=y +CONFIG_GPIO=y diff --git a/samples/boards/st/power_mgmt/standby_shutdown/prj.conf b/samples/boards/st/power_mgmt/standby_shutdown/prj.conf index 885312c4353b9..ccfaa02003379 100644 --- a/samples/boards/st/power_mgmt/standby_shutdown/prj.conf +++ b/samples/boards/st/power_mgmt/standby_shutdown/prj.conf @@ -3,3 +3,4 @@ CONFIG_PM_DEVICE=n CONFIG_PM_DEVICE_RUNTIME=n CONFIG_HWINFO=y CONFIG_POWEROFF=y +CONFIG_GPIO=y diff --git a/samples/boards/st/power_mgmt/stm32wb_ble/src/main.c b/samples/boards/st/power_mgmt/stm32wb_ble/src/main.c index faabd4eda3049..659c7016cf5b9 100644 --- a/samples/boards/st/power_mgmt/stm32wb_ble/src/main.c +++ b/samples/boards/st/power_mgmt/stm32wb_ble/src/main.c @@ -122,7 +122,7 @@ int main(void) /* Give time to bt_ready sequence */ k_sleep(K_SECONDS(6)); - printk("BLE disable\n"); + printk("Bluetooth disable\n"); err = bt_disable(); if (err) { printk("Bluetooth disable failed (err %d)\n", err); @@ -130,7 +130,7 @@ int main(void) k_sleep(K_SECONDS(2)); - printk("BLE restart\n"); + printk("Bluetooth restart\n"); /* Initialize the Bluetooth Subsystem */ err = bt_enable(bt_ready); if (err) { @@ -140,7 +140,7 @@ int main(void) /* Give time to bt_ready sequence */ k_sleep(K_SECONDS(6)); - printk("BLE disable\n"); + printk("Bluetooth disable\n"); err = bt_disable(); if (err) { printk("Bluetooth disable failed (err %d)\n", err); diff --git a/samples/boards/st/power_mgmt/stop3/prj.conf b/samples/boards/st/power_mgmt/stop3/prj.conf index 6888f24a03f9a..105b9e19c1352 100644 --- a/samples/boards/st/power_mgmt/stop3/prj.conf +++ b/samples/boards/st/power_mgmt/stop3/prj.conf @@ -3,3 +3,4 @@ CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y CONFIG_PM_DEVICE_SYSTEM_MANAGED=y CONFIG_ASSERT=y +CONFIG_GPIO=y diff --git a/samples/boards/st/power_mgmt/suspend_to_ram/prj.conf b/samples/boards/st/power_mgmt/suspend_to_ram/prj.conf index ce43f3f936fb5..b9a1cf9305e47 100644 --- a/samples/boards/st/power_mgmt/suspend_to_ram/prj.conf +++ b/samples/boards/st/power_mgmt/suspend_to_ram/prj.conf @@ -9,3 +9,4 @@ CONFIG_SPI=y CONFIG_SPI_STM32_DMA=y CONFIG_SPI_STM32_INTERRUPT=n CONFIG_SPI_ASYNC=n +CONFIG_GPIO=y diff --git a/samples/boards/st/power_mgmt/wkup_pins/prj.conf b/samples/boards/st/power_mgmt/wkup_pins/prj.conf index 2331687b7894e..c4da52ab9fb65 100644 --- a/samples/boards/st/power_mgmt/wkup_pins/prj.conf +++ b/samples/boards/st/power_mgmt/wkup_pins/prj.conf @@ -1,2 +1,3 @@ CONFIG_POWEROFF=y CONFIG_STM32_WKUP_PINS=y +CONFIG_GPIO=y diff --git a/samples/boards/st/uart/circular_dma/CMakeLists.txt b/samples/boards/st/uart/circular_dma/CMakeLists.txt new file mode 100644 index 0000000000000..375342e59434a --- /dev/null +++ b/samples/boards/st/uart/circular_dma/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(circular_dma) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/st/uart/circular_dma/README.rst b/samples/boards/st/uart/circular_dma/README.rst new file mode 100644 index 0000000000000..9614365eeb843 --- /dev/null +++ b/samples/boards/st/uart/circular_dma/README.rst @@ -0,0 +1,49 @@ +.. zephyr:code-sample:: uart + :name: UART circular mode + :relevant-api: uart_interface + + Read data from the console and echo it back using a circular dma configuration. + +Overview +******** + +This sample demonstrates how to use STM32 UART serial driver with DMA in circular mode. +It reads data from the console and echoes it back. + +By default, the UART peripheral that is normally assigned to the Zephyr shell +is used, hence the majority of boards should be able to run this sample. + +Building and Running +******************** + +Build and flash the sample as follows, changing ``nucleo_g071rb`` for +your board: + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/st/uart/circular_dma + :board: nucleo_g071rb + :goals: build flash + :compact: + +Sample Output +============= + +.. code-block:: console + + Enter message to fill RX buffer size and press enter : + # Type e.g. : + # "Lorem Ipsum is simply dummy text of the printing and typesetting industry. + # Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, + # when an unknown printer took a galley of type and scrambled it to make a type specimen book. + # It has survived not only five centuries, but also the leap into electronic typesetting, + # remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset + # sheets containing Lorem Ipsum passages, and more recently with desktop publishing software + # like Aldus PageMaker including versions of Lorem Ipsum." + + Lorem Ipsum is simply dummy text of the printing and typesetting industry. + Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, + when an unknown printer took a galley of type and scrambled it to make a type specimen book. + It has survived not only five centuries, but also the leap into electronic typesetting, + remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset + sheets containing Lorem Ipsum passages, and more recently with desktop publishing software + like Aldus PageMaker including versions of Lorem Ipsum. diff --git a/samples/boards/st/uart/circular_dma/boards/nucleo_c031c6.overlay b/samples/boards/st/uart/circular_dma/boards/nucleo_c031c6.overlay new file mode 100644 index 0000000000000..de7d0772e510d --- /dev/null +++ b/samples/boards/st/uart/circular_dma/boards/nucleo_c031c6.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&usart2 { + dmas = <&dmamux1 0 53 (STM32_DMA_PERIPH_TX)>, + <&dmamux1 3 52 (STM32_DMA_PERIPH_RX | STM32_DMA_MEM_8BITS | STM32_DMA_MODE_CYCLIC)>; + dma-names = "tx", "rx"; + fifo-enable; +}; + +&dma1 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; diff --git a/samples/boards/st/uart/circular_dma/boards/nucleo_f091rc.overlay b/samples/boards/st/uart/circular_dma/boards/nucleo_f091rc.overlay new file mode 100644 index 0000000000000..274b8d1d5b733 --- /dev/null +++ b/samples/boards/st/uart/circular_dma/boards/nucleo_f091rc.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&usart2 { + dmas = <&dma1 4 (STM32_DMA_PERIPH_TX)>, + <&dma1 5 (STM32_DMA_PERIPH_RX | STM32_DMA_MEM_8BITS | STM32_DMA_MODE_CYCLIC)>; + dma-names = "tx", "rx"; + fifo-enable; +}; + +&dma1 { + status = "okay"; +}; diff --git a/samples/boards/st/uart/circular_dma/boards/nucleo_g071rb.overlay b/samples/boards/st/uart/circular_dma/boards/nucleo_g071rb.overlay new file mode 100644 index 0000000000000..de7d0772e510d --- /dev/null +++ b/samples/boards/st/uart/circular_dma/boards/nucleo_g071rb.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&usart2 { + dmas = <&dmamux1 0 53 (STM32_DMA_PERIPH_TX)>, + <&dmamux1 3 52 (STM32_DMA_PERIPH_RX | STM32_DMA_MEM_8BITS | STM32_DMA_MODE_CYCLIC)>; + dma-names = "tx", "rx"; + fifo-enable; +}; + +&dma1 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; diff --git a/samples/boards/st/uart/circular_dma/boards/nucleo_wba55cg.overlay b/samples/boards/st/uart/circular_dma/boards/nucleo_wba55cg.overlay new file mode 100644 index 0000000000000..751836f855452 --- /dev/null +++ b/samples/boards/st/uart/circular_dma/boards/nucleo_wba55cg.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&usart1 { + dmas = <&gpdma1 0 12 (STM32_DMA_PERIPH_TX) + &gpdma1 1 11 (STM32_DMA_MODE_CYCLIC | STM32_DMA_PERIPH_RX | STM32_DMA_MEM_8BITS)>; + dma-names = "tx", "rx"; + fifo-enable; +}; + +&gpdma1 { + status = "okay"; +}; diff --git a/samples/boards/st/uart/circular_dma/prj.conf b/samples/boards/st/uart/circular_dma/prj.conf new file mode 100644 index 0000000000000..ad49326a82a7f --- /dev/null +++ b/samples/boards/st/uart/circular_dma/prj.conf @@ -0,0 +1,3 @@ +CONFIG_SERIAL=y +CONFIG_UART_ASYNC_API=y +CONFIG_RING_BUFFER=y diff --git a/samples/boards/st/uart/circular_dma/sample.yaml b/samples/boards/st/uart/circular_dma/sample.yaml new file mode 100644 index 0000000000000..1fa418f0c4e92 --- /dev/null +++ b/samples/boards/st/uart/circular_dma/sample.yaml @@ -0,0 +1,11 @@ +sample: + name: UART driver sample +tests: + sample.boards.stm32.uart.circular_dma: + integration_platforms: + - nucleo_g071rb + tags: + - serial + - uart + filter: dt_chosen_enabled("zephyr,shell-uart") and CONFIG_SOC_FAMILY_STM32 + harness: keyboard diff --git a/samples/boards/st/uart/circular_dma/src/main.c b/samples/boards/st/uart/circular_dma/src/main.c new file mode 100644 index 0000000000000..f230a500dc210 --- /dev/null +++ b/samples/boards/st/uart/circular_dma/src/main.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define RING_BUF_SIZE 1000 +#define RX_BUF_SIZE 10 + +#define RECEIVE_TIMEOUT 0 + +#define STACK_SIZE 1024 + +#define UART_DEVICE_NODE DT_CHOSEN(zephyr_shell_uart) + +static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE); + +/* uart configuration structure */ +const struct uart_config uart_cfg = {.baudrate = 115200, + .parity = UART_CFG_PARITY_NONE, + .stop_bits = UART_CFG_STOP_BITS_1, + .data_bits = UART_CFG_DATA_BITS_8, + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE}; + +/* define a ring buffer to get raw bytes*/ +RING_BUF_DECLARE(ring_buf, RING_BUF_SIZE); + +/* define uart rx buffer */ +static uint8_t rx_buffer[RX_BUF_SIZE]; + +/* define thread stack size */ +static K_THREAD_STACK_DEFINE(uart_rx_stack, STACK_SIZE); + +/* struct uart_event async_evt */ +static struct k_thread uart_rx_thread_data = {0}; + +void print_uart(char *buf, int len) +{ + for (int i = 0; i < len; i++) { + + if ((buf[i] == '\n' || buf[i] == '\r')) { + uart_poll_out(uart_dev, '\n'); + } else { + uart_poll_out(uart_dev, buf[i]); + } + } +} + +/* Data processing thread */ +static void uart_rx_thread(void *p1, void *p2, void *p3) +{ + uint8_t rx_data[RX_BUF_SIZE]; + size_t len; + + while (1) { + + /* Check if there's data in the ring buffer */ + len = ring_buf_get(&ring_buf, rx_data, sizeof(rx_data)); + + if (len > 0) { + + /* Process `len` bytes of data */ + print_uart(rx_data, len); + } + } +} + +void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data) +{ + switch (evt->type) { + case UART_RX_RDY: + /* Data received; place into ring buffer */ + ring_buf_put(&ring_buf, evt->data.rx.buf + evt->data.rx.offset, evt->data.rx.len); + + break; + + case UART_RX_DISABLED: + /* Re-enable RX */ + uart_rx_enable(uart_dev, rx_buffer, sizeof(rx_buffer), RECEIVE_TIMEOUT); + + break; + + default: + break; + } +} + +int main(void) +{ + if (!uart_dev) { + printk("Failed to get UART device"); + return 1; + } + + /* uart configuration parameters */ + int err = uart_configure(uart_dev, &uart_cfg); + + if (err == -ENOSYS) { + printk("Configuration is not supported by device or driver," + " check the UART settings configuration\n"); + return -ENOSYS; + } + + /* Configure uart callback */ + uart_callback_set(uart_dev, uart_cb, NULL); + + /* enable uart reception */ + uart_rx_enable(uart_dev, rx_buffer, sizeof(rx_buffer), RECEIVE_TIMEOUT); + + printk("\n Enter message to fill RX buffer size :\n"); + + /* start uart data processing thread */ + k_tid_t tid = k_thread_create(&uart_rx_thread_data, uart_rx_stack, + K_THREAD_STACK_SIZEOF(uart_rx_stack), uart_rx_thread, NULL, + NULL, NULL, 5, 0, K_NO_WAIT); + k_thread_name_set(tid, "RX_thread"); +} diff --git a/samples/boards/st/uart/single_wire/README.rst b/samples/boards/st/uart/single_wire/README.rst index 09c01c817251f..67484bfa5969a 100644 --- a/samples/boards/st/uart/single_wire/README.rst +++ b/samples/boards/st/uart/single_wire/README.rst @@ -7,14 +7,18 @@ Overview ******** -A simple application demonstrating how to use the single wire / half-duplex UART -functionality of STM32. Without adaptions this example runs on STM32F3 discovery -board. You need to establish a physical connection between pins PA2 (USART2_TX) and -PC10 (UART4_TX). - +A simple application demonstrating how to use the single-wire/half-duplex +UART functionality of STM32 devices. The example runs on various STM32 +boards with minimal adaptations. Add a ``single_wire_uart_loopback`` fixture to your board in the hardware map to allow twister to verify this sample's output automatically. +Hardware Setup +************** + +You need to establish a physical connection between UART pins on the board. +Refer to the specific board overlay file for the exact pin connections. + Building and Running ******************** diff --git a/samples/boards/st/uart/single_wire/boards/nucleo_wba55cg.overlay b/samples/boards/st/uart/single_wire/boards/nucleo_wba55cg.overlay new file mode 100644 index 0000000000000..375d125fbaa5f --- /dev/null +++ b/samples/boards/st/uart/single_wire/boards/nucleo_wba55cg.overlay @@ -0,0 +1,36 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 STMicroelectronics + */ + +&usart2 { + status = "okay"; + pinctrl-0 = <&usart2_tx_pa12>; + current-speed = <115200>; + single-wire; +}; + +&lpuart1 { + status = "okay"; + pinctrl-0 = <&lpuart1_tx_pa2>; + current-speed = <115200>; + single-wire; +}; + +&usart2_tx_pa12 { + bias-pull-up; + drive-open-drain; +}; + +&lpuart1_tx_pa2 { + bias-pull-up; + drive-open-drain; +}; + +/ { + aliases { + single-line-uart1 = &usart2; + single-line-uart2 = &lpuart1; + }; +}; diff --git a/samples/boards/st/uart/single_wire/sample.yaml b/samples/boards/st/uart/single_wire/sample.yaml index 6bf267e50a455..9d9bbaa0abe71 100644 --- a/samples/boards/st/uart/single_wire/sample.yaml +++ b/samples/boards/st/uart/single_wire/sample.yaml @@ -2,7 +2,9 @@ sample: name: STM32 Single Wire UART sample tests: sample.boards.stm32.uart.single_wire: - platform_allow: stm32f3_disco + platform_allow: + - stm32f3_disco + - nucleo_wba55cg tags: - drivers - uart diff --git a/samples/drivers/adc/adc_dt/boards/cyw920829m2evk_02.overlay b/samples/drivers/adc/adc_dt/boards/cyw920829m2evk_02.overlay new file mode 100644 index 0000000000000..540cbef09bff2 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/cyw920829m2evk_02.overlay @@ -0,0 +1,56 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + */ + +#include + +/ { + zephyr,user { + io-channels = <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@4 { + reg = <4>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + zephyr,input-positive = <4>; /* P3.4 */ + }; + + channel@5 { + reg = <5>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + zephyr,input-positive = <5>; /* P3.5 */ + }; + + channel@6 { + reg = <6>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + zephyr,input-positive = <6>; /* P3.6 */ + }; + + channel@7 { + reg = <7>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + zephyr,input-positive = <7>; /* P3.7 */ + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32_devkitc_wroom_procpu.overlay b/samples/drivers/adc/adc_dt/boards/esp32_devkitc_wroom_procpu.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32_devkitc_wroom_procpu.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32_devkitc_wrover_procpu.overlay b/samples/drivers/adc/adc_dt/boards/esp32_devkitc_wrover_procpu.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32_devkitc_wrover_procpu.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32c3_devkitm.overlay b/samples/drivers/adc/adc_dt/boards/esp32c3_devkitm.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32c3_devkitm.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32c3_luatos_core.overlay b/samples/drivers/adc/adc_dt/boards/esp32c3_luatos_core.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32c3_luatos_core.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32c3_luatos_core_esp32c3_usb.overlay b/samples/drivers/adc/adc_dt/boards/esp32c3_luatos_core_esp32c3_usb.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32c3_luatos_core_esp32c3_usb.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32s2_saola.overlay b/samples/drivers/adc/adc_dt/boards/esp32s2_saola.overlay deleted file mode 100644 index 9bdf0584c3292..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32s2_saola.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <13>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <13>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32s3_devkitm_procpu.overlay b/samples/drivers/adc/adc_dt/boards/esp32s3_devkitm_procpu.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32s3_devkitm_procpu.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32s3_luatos_core_procpu.overlay b/samples/drivers/adc/adc_dt/boards/esp32s3_luatos_core_procpu.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32s3_luatos_core_procpu.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32s3_luatos_core_procpu_usb.overlay b/samples/drivers/adc/adc_dt/boards/esp32s3_luatos_core_procpu_usb.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32s3_luatos_core_procpu_usb.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/esp32s3_touch_lcd_1_28.overlay b/samples/drivers/adc/adc_dt/boards/esp32s3_touch_lcd_1_28.overlay deleted file mode 100644 index de0570620192e..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/esp32s3_touch_lcd_1_28.overlay +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2024 Joel Guittet - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = <&adc0 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/frdm_mcxa156.overlay b/samples/drivers/adc/adc_dt/boards/frdm_mcxa156.overlay new file mode 100644 index 0000000000000..5a34f23bf78a0 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/frdm_mcxa156.overlay @@ -0,0 +1,30 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&lpadc0 0>; + }; +}; + +&lpadc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <3300>; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = ; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/frdm_mcxc444.conf b/samples/drivers/adc/adc_dt/boards/frdm_mcxc444.conf new file mode 100644 index 0000000000000..3201f7a9cc405 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/frdm_mcxc444.conf @@ -0,0 +1 @@ +CONFIG_ADC_MCUX_ADC16_VREF_ALTERNATE=y diff --git a/samples/drivers/adc/adc_dt/boards/frdm_mcxc444.overlay b/samples/drivers/adc/adc_dt/boards/frdm_mcxc444.overlay new file mode 100644 index 0000000000000..a20b62decf950 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/frdm_mcxc444.overlay @@ -0,0 +1,31 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2024 NXP + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + /* + * To use this sample: + * - Connect ADC0 SE0 signal to voltage between 0~3.3V (J4 pin 1) + */ + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_VDD_1"; + zephyr,vref-mv = <3300>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/mimxrt1050_evk.overlay b/samples/drivers/adc/adc_dt/boards/mimxrt1050_evk_mimxrt1052_hyperflash.overlay similarity index 100% rename from samples/drivers/adc/adc_dt/boards/mimxrt1050_evk.overlay rename to samples/drivers/adc/adc_dt/boards/mimxrt1050_evk_mimxrt1052_hyperflash.overlay diff --git a/samples/drivers/adc/adc_dt/boards/mimxrt1060_evk.overlay b/samples/drivers/adc/adc_dt/boards/mimxrt1060_evk_mimxrt1062_qspi.overlay similarity index 100% rename from samples/drivers/adc/adc_dt/boards/mimxrt1060_evk.overlay rename to samples/drivers/adc/adc_dt/boards/mimxrt1060_evk_mimxrt1062_qspi.overlay diff --git a/samples/drivers/adc/adc_dt/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay b/samples/drivers/adc/adc_dt/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay new file mode 100644 index 0000000000000..45fe5e8b5e59e --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay @@ -0,0 +1,25 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2021 NXP + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc1 0>; + }; +}; + +&adc1 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_common.dtsi b/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_common.dtsi new file mode 100644 index 0000000000000..7c78d5891d4ba --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_common.dtsi @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Nordic Semiconductor ASA + */ + +/ { + zephyr,user { + io-channels = <&adc 0>, <&adc 1>, <&adc 7>; + }; +}; + +&adc { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_2"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = ; /* P1.01 */ + zephyr,resolution = <10>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1_2"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = ; /* P1.02 */ + zephyr,resolution = <12>; + zephyr,oversampling = <8>; + }; + + channel@7 { + reg = <7>; + zephyr,gain = "ADC_GAIN_1_2"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,input-positive = ; /* P1.03 */ + zephyr,input-negative = ; /* P1.07 */ + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index 7c78d5891d4ba..658b19b0ae5d9 100644 --- a/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ b/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -4,42 +4,4 @@ * Copyright (c) 2024 Nordic Semiconductor ASA */ -/ { - zephyr,user { - io-channels = <&adc 0>, <&adc 1>, <&adc 7>; - }; -}; - -&adc { - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_2"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,input-positive = ; /* P1.01 */ - zephyr,resolution = <10>; - }; - - channel@1 { - reg = <1>; - zephyr,gain = "ADC_GAIN_1_2"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,input-positive = ; /* P1.02 */ - zephyr,resolution = <12>; - zephyr,oversampling = <8>; - }; - - channel@7 { - reg = <7>; - zephyr,gain = "ADC_GAIN_1_2"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,input-positive = ; /* P1.03 */ - zephyr,input-negative = ; /* P1.07 */ - zephyr,resolution = <12>; - }; -}; +#include "nrf54h20dk_nrf54h20_common.dtsi" diff --git a/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuppr.overlay b/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuppr.overlay new file mode 100644 index 0000000000000..4599ed3f8a074 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/nrf54h20dk_nrf54h20_cpuppr.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Nordic Semiconductor ASA + */ + +#include "nrf54h20dk_nrf54h20_common.dtsi" + +&adc { + status = "okay"; +}; diff --git a/samples/drivers/adc/adc_dt/boards/nucleo_c071rb.overlay b/samples/drivers/adc/adc_dt/boards/nucleo_c071rb.overlay new file mode 100644 index 0000000000000..716a674b29a20 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/nucleo_c071rb.overlay @@ -0,0 +1,41 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 STMicroelectronics + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc1 0>, <&adc1 1>, <&adc1 4>; + }; +}; + +&adc1 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@4 { + reg = <4>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/rpi_pico2_rp2350a_m33.overlay b/samples/drivers/adc/adc_dt/boards/rpi_pico2_rp2350a_m33.overlay new file mode 100644 index 0000000000000..8b83efe6ea08f --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/rpi_pico2_rp2350a_m33.overlay @@ -0,0 +1,8 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Andrew Featherstone + */ + +/* Pico 2 is compatible with the Pico 1, so reuse. */ +#include "rpi_pico.overlay" diff --git a/samples/drivers/adc/adc_dt/boards/xg24_rb4187c.overlay b/samples/drivers/adc/adc_dt/boards/xg24_rb4187c.overlay new file mode 100644 index 0000000000000..6ab6c25219f25 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/xg24_rb4187c.overlay @@ -0,0 +1,50 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Silicon Laboratories Inc. + */ + +#include +#include + +/ { + zephyr,user { + io-channels = <&adc0 3>, <&adc0 4>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group0 { + /* Allocate odd bus 0 on GPIO port B to IADC for access to pin PB1 */ + silabs,analog-bus = ; + }; + }; +}; + +&adc0 { + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + zephyr,input-positive = ; + }; + + channel@4 { + reg = <4>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_VDD_1"; + zephyr,vref-mv = <3300>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + zephyr,input-positive = ; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/xiao_esp32s3_procpu.overlay b/samples/drivers/adc/adc_dt/boards/xiao_esp32s3_procpu.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/xiao_esp32s3_procpu.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/boards/yd_esp32_procpu.overlay b/samples/drivers/adc/adc_dt/boards/yd_esp32_procpu.overlay deleted file mode 100644 index d43209179f755..0000000000000 --- a/samples/drivers/adc/adc_dt/boards/yd_esp32_procpu.overlay +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Wolter HV - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - io-channels = - <&adc0 0>, - <&adc1 0>; - }; -}; - -&adc0 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; - -&adc1 { - status = "okay"; - #address-cells = <1>; - #size-cells = <0>; - - channel@0 { - reg = <0>; - zephyr,gain = "ADC_GAIN_1_4"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,resolution = <12>; - }; -}; diff --git a/samples/drivers/adc/adc_dt/sample.yaml b/samples/drivers/adc/adc_dt/sample.yaml index a855a3f523841..f686b8edcb5f1 100644 --- a/samples/drivers/adc/adc_dt/sample.yaml +++ b/samples/drivers/adc/adc_dt/sample.yaml @@ -35,6 +35,7 @@ tests: - frdm_mcxn947/mcxn947/cpu0 - frdm_mcxc242 - ucans32k1sic + - xg24_rb4187c integration_platforms: - nucleo_l073rz - nrf52840dk/nrf52840 diff --git a/samples/drivers/adc/adc_dt/socs/esp32_procpu.overlay b/samples/drivers/adc/adc_dt/socs/esp32_procpu.overlay new file mode 100644 index 0000000000000..272d0d7bcd900 --- /dev/null +++ b/samples/drivers/adc/adc_dt/socs/esp32_procpu.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/socs/esp32c3.overlay b/samples/drivers/adc/adc_dt/socs/esp32c3.overlay new file mode 100644 index 0000000000000..272d0d7bcd900 --- /dev/null +++ b/samples/drivers/adc/adc_dt/socs/esp32c3.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/socs/esp32s2.overlay b/samples/drivers/adc/adc_dt/socs/esp32s2.overlay new file mode 100644 index 0000000000000..272d0d7bcd900 --- /dev/null +++ b/samples/drivers/adc/adc_dt/socs/esp32s2.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/socs/esp32s3_procpu.overlay b/samples/drivers/adc/adc_dt/socs/esp32s3_procpu.overlay new file mode 100644 index 0000000000000..272d0d7bcd900 --- /dev/null +++ b/samples/drivers/adc/adc_dt/socs/esp32s3_procpu.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Wolter HV + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1_4"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/drivers/adc/adc_dt/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 0000000000000..d3ddd5ac09351 --- /dev/null +++ b/samples/drivers/adc/adc_dt/sysbuild/vpr_launcher/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "../../../boards/nrf54h20dk_nrf54h20_common.dtsi" + +&adc { + status = "reserved"; + interrupt-parent = <&cpuppr_clic>; +}; diff --git a/samples/drivers/adc/adc_dt/sysbuild/vpr_launcher/prj.conf b/samples/drivers/adc/adc_dt/sysbuild/vpr_launcher/prj.conf new file mode 100644 index 0000000000000..b2a4ba591044e --- /dev/null +++ b/samples/drivers/adc/adc_dt/sysbuild/vpr_launcher/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/samples/drivers/adc/adc_sequence/Kconfig b/samples/drivers/adc/adc_sequence/Kconfig index c8351a5e71259..e2d97244d4f6f 100644 --- a/samples/drivers/adc/adc_sequence/Kconfig +++ b/samples/drivers/adc/adc_sequence/Kconfig @@ -9,4 +9,8 @@ config SEQUENCE_RESOLUTION int "Set the resolution of the sequence readings." default 12 +config SEQUENCE_32BITS_REGISTERS + bool "ADC data sequences are on 32bits" + default n + source "Kconfig.zephyr" diff --git a/samples/drivers/adc/adc_sequence/boards/frdm_mcxc444.conf b/samples/drivers/adc/adc_sequence/boards/frdm_mcxc444.conf new file mode 100644 index 0000000000000..3201f7a9cc405 --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/frdm_mcxc444.conf @@ -0,0 +1 @@ +CONFIG_ADC_MCUX_ADC16_VREF_ALTERNATE=y diff --git a/samples/drivers/adc/adc_sequence/boards/frdm_mcxc444.overlay b/samples/drivers/adc/adc_sequence/boards/frdm_mcxc444.overlay new file mode 100644 index 0000000000000..ef107d2a365a0 --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/frdm_mcxc444.overlay @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2024 NXP + */ + +/ { + aliases { + adc0 = &adc0; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + /* + * To use this sample: + * - Connect ADC0 SE0 signal to voltage between 0~3.3V (J4 pin 1) + */ + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_VDD_1"; + zephyr,vref-mv = <3300>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_sequence/boards/stm32f3_disco.conf b/samples/drivers/adc/adc_sequence/boards/stm32f3_disco.conf new file mode 100644 index 0000000000000..08cc33d8603d5 --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/stm32f3_disco.conf @@ -0,0 +1,4 @@ +# A4114 driver can only acquire one sequence sample +CONFIG_SEQUENCE_SAMPLES=1 +CONFIG_SEQUENCE_RESOLUTION=12 +CONFIG_SEQUENCE_32BITS_REGISTERS=y diff --git a/samples/drivers/adc/adc_sequence/boards/stm32f3_disco.overlay b/samples/drivers/adc/adc_sequence/boards/stm32f3_disco.overlay new file mode 100644 index 0000000000000..7b171fe759c2b --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/stm32f3_disco.overlay @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2024 Pierrick Curt + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + adc0 = &adc_ad4114; + }; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + status = "okay"; + + adc_ad4114: adc_ad4114@0 { + compatible = "adi,ad4114-adc"; + spi-max-frequency = ; + status = "okay"; + reg = <0>; + #io-channel-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + /* INPUTx mapping bits [9:0] for CH0 to CH15 */ + map-inputs = <0x10 0x30 0x50 0x70 0x90 0xB0 0xD0 0xF0 0x110 \ + 0x130 0x150 0x170 0x190 0x1B0 0x1D0 0x1F0>; + + + channel@0 { + reg = <0x0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@4 { + reg = <4>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@5 { + reg = <5>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@6 { + reg = <6>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@7 { + reg = <7>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@8 { + reg = <8>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@9 { + reg = <9>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@a { + reg = <0xa>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@b { + reg = <0xb>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@c { + reg = <0xc>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@d { + reg = <0xd>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@e { + reg = <0xe>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + channel@f { + reg = <0xf>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + }; + }; +}; diff --git a/samples/drivers/adc/adc_sequence/sample.yaml b/samples/drivers/adc/adc_sequence/sample.yaml index 29bcadf4497bf..0461205a058f6 100644 --- a/samples/drivers/adc/adc_sequence/sample.yaml +++ b/samples/drivers/adc/adc_sequence/sample.yaml @@ -13,6 +13,7 @@ tests: - nrf54h20dk/nrf54h20/cpuapp - ucans32k1sic - frdm_mcxc242 + - stm32f3_disco integration_platforms: - nrf52840dk/nrf52840 harness: console diff --git a/samples/drivers/adc/adc_sequence/src/main.c b/samples/drivers/adc/adc_sequence/src/main.c index 60bde60650d6e..d80a09a601ebc 100644 --- a/samples/drivers/adc/adc_sequence/src/main.c +++ b/samples/drivers/adc/adc_sequence/src/main.c @@ -30,7 +30,11 @@ int main(void) { int err; uint32_t count = 0; +#ifdef CONFIG_SEQUENCE_32BITS_REGISTERS + uint32_t channel_reading[CONFIG_SEQUENCE_SAMPLES][CHANNEL_COUNT]; +#else uint16_t channel_reading[CONFIG_SEQUENCE_SAMPLES][CHANNEL_COUNT]; +#endif /* Options for the sequence sampling. */ const struct adc_sequence_options options = { diff --git a/samples/drivers/counter/alarm/boards/ek_ra4m1.overlay b/samples/drivers/counter/alarm/boards/ek_ra4m1.overlay new file mode 100644 index 0000000000000..5b83678c38c07 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/ek_ra4m1.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&agt0 { + status = "okay"; + interrupts = <30 1>, <31 1>; + interrupt-names = "agti", "agtcmai"; + renesas,prescaler = <4>; + counter0: counter { + status = "okay"; + }; +}; diff --git a/samples/drivers/counter/alarm/boards/esp32s3_luatos_core_procpu_usb.overlay b/samples/drivers/counter/alarm/boards/esp32s3_luatos_core_procpu_usb.overlay deleted file mode 100644 index 241947b06437b..0000000000000 --- a/samples/drivers/counter/alarm/boards/esp32s3_luatos_core_procpu_usb.overlay +++ /dev/null @@ -1,3 +0,0 @@ -&timer0 { - status = "okay"; -}; diff --git a/samples/drivers/counter/alarm/boards/fpb_ra4e1.overlay b/samples/drivers/counter/alarm/boards/fpb_ra4e1.overlay new file mode 100644 index 0000000000000..881baf7475a42 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/fpb_ra4e1.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&agt0 { + status = "okay"; + interrupts = <83 1>, <84 1>; + interrupt-names = "agti", "agtcmai"; + renesas,prescaler = <4>; + counter0: counter { + status = "okay"; + }; +}; diff --git a/samples/drivers/counter/alarm/boards/max78000evkit_max78000_m4.overlay b/samples/drivers/counter/alarm/boards/max78000evkit_max78000_m4.overlay new file mode 100644 index 0000000000000..9c5ef490ac421 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/max78000evkit_max78000_m4.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&timer0 { + status = "okay"; + counter0: counter { + status = "okay"; + }; +}; diff --git a/samples/drivers/counter/alarm/boards/max78000fthr_max78000_m4.overlay b/samples/drivers/counter/alarm/boards/max78000fthr_max78000_m4.overlay new file mode 100644 index 0000000000000..9c5ef490ac421 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/max78000fthr_max78000_m4.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&timer0 { + status = "okay"; + counter0: counter { + status = "okay"; + }; +}; diff --git a/samples/drivers/counter/alarm/boards/nrf54l09pdk_nrf54l09_cpuapp.overlay b/samples/drivers/counter/alarm/boards/nrf54l09pdk_nrf54l09_cpuapp.overlay new file mode 100644 index 0000000000000..0847233437baf --- /dev/null +++ b/samples/drivers/counter/alarm/boards/nrf54l09pdk_nrf54l09_cpuapp.overlay @@ -0,0 +1,9 @@ +/ { + chosen { + counter = &timer24; + }; +}; + +&timer24 { + status = "okay"; +}; diff --git a/samples/drivers/counter/alarm/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay b/samples/drivers/counter/alarm/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay new file mode 100644 index 0000000000000..0847233437baf --- /dev/null +++ b/samples/drivers/counter/alarm/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay @@ -0,0 +1,9 @@ +/ { + chosen { + counter = &timer24; + }; +}; + +&timer24 { + status = "okay"; +}; diff --git a/samples/drivers/counter/alarm/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay b/samples/drivers/counter/alarm/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay new file mode 100644 index 0000000000000..98bb1332ad893 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +>m0 { + counter { + status = "okay"; + }; +}; diff --git a/samples/drivers/counter/alarm/boards/voice_ra4e1.overlay b/samples/drivers/counter/alarm/boards/voice_ra4e1.overlay new file mode 100644 index 0000000000000..881baf7475a42 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/voice_ra4e1.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&agt0 { + status = "okay"; + interrupts = <83 1>, <84 1>; + interrupt-names = "agti", "agtcmai"; + renesas,prescaler = <4>; + counter0: counter { + status = "okay"; + }; +}; diff --git a/samples/drivers/counter/alarm/boards/yd_esp32_procpu.overlay b/samples/drivers/counter/alarm/boards/yd_esp32_procpu.overlay deleted file mode 100644 index 241947b06437b..0000000000000 --- a/samples/drivers/counter/alarm/boards/yd_esp32_procpu.overlay +++ /dev/null @@ -1,3 +0,0 @@ -&timer0 { - status = "okay"; -}; diff --git a/samples/drivers/counter/alarm/boards/esp32_devkitc_wroom_procpu.overlay b/samples/drivers/counter/alarm/socs/esp32_procpu.overlay similarity index 100% rename from samples/drivers/counter/alarm/boards/esp32_devkitc_wroom_procpu.overlay rename to samples/drivers/counter/alarm/socs/esp32_procpu.overlay diff --git a/samples/drivers/counter/alarm/boards/esp32s2_saola.overlay b/samples/drivers/counter/alarm/socs/esp32c3_usb.overlay similarity index 100% rename from samples/drivers/counter/alarm/boards/esp32s2_saola.overlay rename to samples/drivers/counter/alarm/socs/esp32c3_usb.overlay diff --git a/samples/drivers/counter/alarm/boards/esp32s3_devkitm_procpu.overlay b/samples/drivers/counter/alarm/socs/esp32s2.overlay similarity index 100% rename from samples/drivers/counter/alarm/boards/esp32s3_devkitm_procpu.overlay rename to samples/drivers/counter/alarm/socs/esp32s2.overlay diff --git a/samples/drivers/counter/alarm/boards/esp32s3_luatos_core_procpu.overlay b/samples/drivers/counter/alarm/socs/esp32s3_procpu.overlay similarity index 100% rename from samples/drivers/counter/alarm/boards/esp32s3_luatos_core_procpu.overlay rename to samples/drivers/counter/alarm/socs/esp32s3_procpu.overlay diff --git a/samples/drivers/counter/alarm/src/main.c b/samples/drivers/counter/alarm/src/main.c index deb64e21540e1..d7f577e72c7e5 100644 --- a/samples/drivers/counter/alarm/src/main.c +++ b/samples/drivers/counter/alarm/src/main.c @@ -23,6 +23,8 @@ struct counter_alarm_cfg alarm_cfg; #define TIMER DT_NODELABEL(extrtc0) #elif defined(CONFIG_COUNTER_NRF_RTC) #define TIMER DT_NODELABEL(rtc0) +#elif defined(CONFIG_COUNTER_NRF_TIMER) +#define TIMER DT_CHOSEN(counter) #elif defined(CONFIG_COUNTER_TIMER_STM32) #define TIMER DT_INST(0, st_stm32_counter) #elif defined(CONFIG_COUNTER_RTC_STM32) @@ -57,6 +59,8 @@ struct counter_alarm_cfg alarm_cfg; #define TIMER DT_NODELABEL(counter0) #elif defined(CONFIG_COUNTER_RA_AGT) #define TIMER DT_NODELABEL(counter0) +#elif defined(CONFIG_COUNTER_RENESAS_RZ_GTM) +#define TIMER DT_INST(0, renesas_rz_gtm_counter) #else #error Unable to find a counter device node in devicetree #endif diff --git a/samples/drivers/dac/Kconfig b/samples/drivers/dac/Kconfig new file mode 100644 index 0000000000000..2194ec09a5116 --- /dev/null +++ b/samples/drivers/dac/Kconfig @@ -0,0 +1,16 @@ +# Private config options for dac sample + +# Copyright (c) 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "DAC sample application" + +source "Kconfig.zephyr" + +ZEPHYR_USER := zephyr,user + +config DAC_SAMPLE_RUN + bool "Run DAC sample application" + default y if $(dt_node_has_prop,/$(ZEPHYR_USER),dac) + help + platform supports dac sample diff --git a/samples/drivers/dac/boards/ek_ra2a1.overlay b/samples/drivers/dac/boards/ek_ra2a1.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra2a1.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra4e2.overlay b/samples/drivers/dac/boards/ek_ra4e2.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra4e2.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra4m2.overlay b/samples/drivers/dac/boards/ek_ra4m2.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra4m2.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra4m3.overlay b/samples/drivers/dac/boards/ek_ra4m3.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra4m3.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra6e2.overlay b/samples/drivers/dac/boards/ek_ra6e2.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra6e2.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra6m1.overlay b/samples/drivers/dac/boards/ek_ra6m1.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra6m1.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra6m2.overlay b/samples/drivers/dac/boards/ek_ra6m2.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra6m2.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra6m3.overlay b/samples/drivers/dac/boards/ek_ra6m3.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra6m3.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra6m4.overlay b/samples/drivers/dac/boards/ek_ra6m4.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra6m4.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra6m5.overlay b/samples/drivers/dac/boards/ek_ra6m5.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra6m5.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra8d1.overlay b/samples/drivers/dac/boards/ek_ra8d1.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra8d1.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/ek_ra8m1.overlay b/samples/drivers/dac/boards/ek_ra8m1.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/ek_ra8m1.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/esp32s2_saola.overlay b/samples/drivers/dac/boards/esp32s2_saola.overlay deleted file mode 100644 index 4bb2651bd68cb..0000000000000 --- a/samples/drivers/dac/boards/esp32s2_saola.overlay +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2022 Espressif (Shanghai) - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - dac = <&dac>; - dac-channel-id = <0>; - dac-resolution = <8>; - }; -}; - -&dac { - status = "okay"; -}; diff --git a/samples/drivers/dac/boards/fpb_ra6e1.overlay b/samples/drivers/dac/boards/fpb_ra6e1.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/fpb_ra6e1.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/fpb_ra6e2.overlay b/samples/drivers/dac/boards/fpb_ra6e2.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/fpb_ra6e2.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/mck_ra8t1.overlay b/samples/drivers/dac/boards/mck_ra8t1.overlay new file mode 100644 index 0000000000000..a726274e2b2ff --- /dev/null +++ b/samples/drivers/dac/boards/mck_ra8t1.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/sam4s_xplained.overlay b/samples/drivers/dac/boards/sam4s_xplained.overlay new file mode 100644 index 0000000000000..a075a04a5e749 --- /dev/null +++ b/samples/drivers/dac/boards/sam4s_xplained.overlay @@ -0,0 +1,7 @@ +/ { + zephyr,user { + dac = <&dacc>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/samples/drivers/dac/boards/yd_esp32_procpu.overlay b/samples/drivers/dac/boards/yd_esp32_procpu.overlay deleted file mode 100644 index 4bb2651bd68cb..0000000000000 --- a/samples/drivers/dac/boards/yd_esp32_procpu.overlay +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2022 Espressif (Shanghai) - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - zephyr,user { - dac = <&dac>; - dac-channel-id = <0>; - dac-resolution = <8>; - }; -}; - -&dac { - status = "okay"; -}; diff --git a/samples/drivers/dac/sample.yaml b/samples/drivers/dac/sample.yaml index 9c7a53beef1f3..a94482fa06f1a 100644 --- a/samples/drivers/dac/sample.yaml +++ b/samples/drivers/dac/sample.yaml @@ -3,48 +3,8 @@ sample: tests: sample.drivers.dac: tags: DAC - platform_allow: - - arduino_zero - - b_u585i_iot02a - - bl652_dvk - - bl653_dvk - - bl654_dvk - - bl5340_dvk/nrf5340/cpuapp - - disco_l475_iot1 - - esp32_devkitc_wroom/esp32/procpu - - esp32_devkitc_wrover/esp32/procpu - - esp32s2_saola - - frdm_k22f - - frdm_k64f - - gd32a503v_eval - - gd32e103v_eval - - gd32f450i_eval - - longan_nano - - longan_nano/gd32vf103/lite - - nucleo_f091rc - - nucleo_f207zg - - nucleo_f429zi - - nucleo_f746zg - - nucleo_f767zi - - nucleo_g071rb - - nucleo_g431rb - - nucleo_g474re - - nucleo_h743zi - - nucleo_l073rz - - nucleo_l152re - - nucleo_l552ze_q - - nucleo_u575zi_q - - nucleo_wl55jc - - sam_e70_xplained/same70q21 - - sam_e70_xplained/same70q21b - - sam_v71_xult/samv71q21 - - sam_v71_xult/samv71q21b - - stm32f3_disco - - stm32l562e_dk - - twr_ke18f - - lpcxpresso55s36 - - rd_rw612_bga depends_on: dac + filter: CONFIG_DAC_SAMPLE_RUN integration_platforms: - nucleo_l152re harness: console diff --git a/samples/drivers/dac/boards/esp32_devkitc_wroom_procpu.overlay b/samples/drivers/dac/socs/esp32_procpu.overlay similarity index 100% rename from samples/drivers/dac/boards/esp32_devkitc_wroom_procpu.overlay rename to samples/drivers/dac/socs/esp32_procpu.overlay diff --git a/samples/drivers/dac/boards/esp32_devkitc_wrover_procpu.overlay b/samples/drivers/dac/socs/esp32s2.overlay similarity index 100% rename from samples/drivers/dac/boards/esp32_devkitc_wrover_procpu.overlay rename to samples/drivers/dac/socs/esp32s2.overlay diff --git a/samples/drivers/display/README.rst b/samples/drivers/display/README.rst index 4b8ff6b637546..628202888cca8 100644 --- a/samples/drivers/display/README.rst +++ b/samples/drivers/display/README.rst @@ -15,6 +15,17 @@ grey changes from black through to white. If the grey looks too green or red at any point or the order of the corners is not as described above then the LCD may be endian swapped. +On displays with the :c:enumerator:`SCREEN_INFO_X_ALIGNMENT_WIDTH` capability, +such as those using the :dtcompatible:`sharp,ls0xx` driver, it is only possible +to draw full lines at a time. On these displays, the rectangles described above +will be replaced with bars that take up the entire width of the display. Only +the green and grey bar will be visible. + +On monochrome displays, the rectangles (or bars) will all be some shade of grey. + +On displays with 1 bit per pixel, the greyscale animation of the bottom +rectangle (or bar) will appear as flickering between black and white. + Building and Running ******************** diff --git a/samples/drivers/display/boards/ek_ra8d1.conf b/samples/drivers/display/boards/ek_ra8d1.conf new file mode 100644 index 0000000000000..0e0a8cb0f908a --- /dev/null +++ b/samples/drivers/display/boards/ek_ra8d1.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_HEAP_MEM_POOL_SIZE=90440 diff --git a/samples/drivers/display/sample.yaml b/samples/drivers/display/sample.yaml index 066138eb16564..494b117f1cf32 100644 --- a/samples/drivers/display/sample.yaml +++ b/samples/drivers/display/sample.yaml @@ -61,8 +61,10 @@ tests: sample.display.rk043fn02h_ct: platform_allow: - mimxrt1064_evk - - mimxrt1060_evk - - mimxrt1050_evk + - mimxrt1060_evk@A/mimxrt1062/qspi + - mimxrt1060_evk@B/mimxrt1062/qspi + - mimxrt1060_evk@C/mimxrt1062/qspi + - mimxrt1050_evk/mimxrt1052/hyperflash - mimxrt1040_evk integration_platforms: - mimxrt1040_evk @@ -106,3 +108,5 @@ tests: - platform:mimxrt1040_evk/mimxrt1042:SHIELD=rk043fn66hs_ctg - platform:frdm_mcxn947/mcxn947/cpu0:SHIELD=lcd_par_s035_8080 - platform:frdm_mcxn236/mcxn236:SHIELD=lcd_par_s035_8080 + - platform:frdm_mcxa156/mcxa156:SHIELD=lcd_par_s035_8080 + - platform:ek_ra8d1:SHIELD=rtkmipilcdb00000be diff --git a/samples/drivers/display/src/main.c b/samples/drivers/display/src/main.c index cdb4c2b4c8dc9..fc12cc86e8fcf 100644 --- a/samples/drivers/display/src/main.c +++ b/samples/drivers/display/src/main.c @@ -231,6 +231,10 @@ int main(void) grey_scale_sleep = 100; } + if (capabilities.screen_info & SCREEN_INFO_X_ALIGNMENT_WIDTH) { + rect_w = capabilities.x_resolution; + } + buf_size = rect_w * rect_h; if (buf_size < (capabilities.x_resolution * h_step)) { diff --git a/samples/drivers/espi/Kconfig b/samples/drivers/espi/Kconfig index f4ea69e33a2c0..063869977b453 100644 --- a/samples/drivers/espi/Kconfig +++ b/samples/drivers/espi/Kconfig @@ -11,4 +11,10 @@ config ESPI_VIRTUAL_WIRE_TIMEOUT help Timeout for virtual wires +config ESPI_USE_BOARD_POWER + bool "Use board power" + depends on $(dt_nodelabel_enabled,board_power) + select GPIO + default y + source "Kconfig.zephyr" diff --git a/samples/drivers/espi/src/espi_oob_handler.c b/samples/drivers/espi/src/espi_oob_handler.c index 59f988c7ad519..40c1fff74c505 100644 --- a/samples/drivers/espi/src/espi_oob_handler.c +++ b/samples/drivers/espi/src/espi_oob_handler.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/samples/drivers/espi/src/main.c b/samples/drivers/espi/src/main.c index aa6b92a472563..be511bcda1594 100644 --- a/samples/drivers/espi/src/main.c +++ b/samples/drivers/espi/src/main.c @@ -45,7 +45,7 @@ LOG_MODULE_DECLARE(espi, CONFIG_ESPI_LOG_LEVEL); /* The devicetree node identifier for the board power rails pins. */ #define BRD_PWR_NODE DT_NODELABEL(board_power) -#if DT_NODE_HAS_STATUS_OKAY(BRD_PWR_NODE) +#ifdef CONFIG_ESPI_USE_BOARD_POWER static const struct gpio_dt_spec pwrgd_gpio = GPIO_DT_SPEC_GET(BRD_PWR_NODE, pwrg_gpios); static const struct gpio_dt_spec rsm_gpio = GPIO_DT_SPEC_GET(BRD_PWR_NODE, rsm_gpios); #endif @@ -911,7 +911,7 @@ int espi_init(void) return ret; } -#if DT_NODE_HAS_STATUS_OKAY(BRD_PWR_NODE) +#ifdef CONFIG_ESPI_USE_BOARD_POWER static int wait_for_pin(const struct gpio_dt_spec *gpio, uint16_t timeout, int exp_level) { uint16_t loop_cnt = timeout; @@ -1172,7 +1172,7 @@ int espi_test(void) */ k_sleep(K_SECONDS(1)); -#if DT_NODE_HAS_STATUS_OKAY(BRD_PWR_NODE) +#ifdef CONFIG_ESPI_USE_BOARD_POWER if (!gpio_is_ready_dt(&pwrgd_gpio)) { LOG_ERR("%s: device not ready.", pwrgd_gpio.port->name); return -ENODEV; @@ -1201,7 +1201,7 @@ int espi_test(void) LOG_INF("Hello eSPI test %s", CONFIG_BOARD); -#if DT_NODE_HAS_STATUS_OKAY(BRD_PWR_NODE) +#ifdef CONFIG_ESPI_USE_BOARD_POWER ret = gpio_pin_configure_dt(&pwrgd_gpio, GPIO_INPUT); if (ret) { LOG_ERR("Unable to configure %d:%d", pwrgd_gpio.pin, ret); @@ -1252,7 +1252,7 @@ int espi_test(void) } #endif -#if DT_NODE_HAS_STATUS_OKAY(BRD_PWR_NODE) +#ifdef CONFIG_ESPI_USE_BOARD_POWER ret = wait_for_pin(&pwrgd_gpio, PWR_SEQ_TIMEOUT, 1); if (ret) { LOG_ERR("RSMRST_PWRGD timeout"); diff --git a/samples/drivers/flash_shell/sample.yaml b/samples/drivers/flash_shell/sample.yaml index ed75923bc9d1e..dff4a058b1f90 100644 --- a/samples/drivers/flash_shell/sample.yaml +++ b/samples/drivers/flash_shell/sample.yaml @@ -6,11 +6,15 @@ tests: tags: - flash - shell - filter: CONFIG_FLASH_HAS_DRIVER_ENABLED + filter: CONFIG_FLASH_HAS_DRIVER_ENABLED and dt_chosen_enabled('zephyr,flash-controller') + and not CONFIG_SOC_SERIES_BSIM_NRFXX platform_exclude: - stm32h7s78_dk - gd32f350r_eval - harness: keyboard + harness: shell + extra_configs: + - arch:posix:CONFIG_NATIVE_UART_0_ON_STDINOUT=y min_ram: 12 integration_platforms: - qemu_x86 + - native_sim diff --git a/samples/drivers/flash_shell/test_shell.yml b/samples/drivers/flash_shell/test_shell.yml new file mode 100644 index 0000000000000..2e4dbee98a022 --- /dev/null +++ b/samples/drivers/flash_shell/test_shell.yml @@ -0,0 +1,2 @@ +- command: "flash page_info 0" + expected: "Page for address 0x0" diff --git a/samples/drivers/i2c/rtio_loopback/CMakeLists.txt b/samples/drivers/i2c/rtio_loopback/CMakeLists.txt new file mode 100644 index 0000000000000..5633adaec301c --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(i2c_rtio_loopback) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/drivers/i2c/rtio_loopback/README.rst b/samples/drivers/i2c/rtio_loopback/README.rst new file mode 100644 index 0000000000000..29599173d73ea --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/README.rst @@ -0,0 +1,50 @@ +.. zephyr:code-sample:: i2c-rtio-loopback + :name: I2C RTIO loopback + :relevant-api: rtio i2c_interface + + Perform I2C transfers between I2C controller and custom I2C target using RTIO. + +Overview +******** + +This sample demonstrates how to perform I2C transfers, synchronously and async +using RTIO. It uses up to two I2C controllers, acting as I2C controller and +target. + +Requirements +************ + +This sample requires either: + +* Two I2C controllers, one supporting the I2C controller role, one supporting the + I2C peripheral role, both connected to the same I2C bus. +* An I2C controller supporting both I2C controller and peripheral role + simultaneously. + +.. note:: + + Remember to set up the I2C bus, connecting SCL and SDA pull-up resistors, and + connecting the relevant I2C controllers to the bus physically. + +Board support +************* + +Any board which meets the requirements must use an overlay to specify which +I2C controller will act as the controller, and which as the peripheral, note +that this could be the same controller. This is done using the devicetree +aliases ``i2c-controller`` and ``i2c-controller-target`` respectively: + +.. code-block:: devicetree + + / { + aliases { + i2c-controller = &i2c1; + i2c-controller-target = &i2c2; + }; + }; + +If necessary, add any board specific configs to the board specific overlay: + +.. code-block:: cfg + + CONFIG_I2C_TARGET_BUFFER_MODE=y diff --git a/samples/drivers/i2c/rtio_loopback/boards/b_u585i_iot02a.conf b/samples/drivers/i2c/rtio_loopback/boards/b_u585i_iot02a.conf new file mode 100644 index 0000000000000..45754c654c62e --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/boards/b_u585i_iot02a.conf @@ -0,0 +1 @@ +CONFIG_I2C_STM32_INTERRUPT=y diff --git a/samples/drivers/i2c/rtio_loopback/boards/b_u585i_iot02a.overlay b/samples/drivers/i2c/rtio_loopback/boards/b_u585i_iot02a.overlay new file mode 100644 index 0000000000000..7fb47fd073560 --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/boards/b_u585i_iot02a.overlay @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* I2C bus pins are exposed on the STMod+. + * + * Bus SDA SCL + * Pin Hdr Pin Hdr + * i2c1 PB9 CN3:10 PB8 CN3:7 + * i2c2 PH5 CN2:10 PH4 CN2:7 + * + * Short Pin PB9 to PH5, and PB8 to PH4, for the test to pass. + */ + +/ { + aliases { + i2c-controller = &i2c1; + i2c-controller-target = &i2c2; + }; +}; diff --git a/samples/drivers/i2c/rtio_loopback/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/drivers/i2c/rtio_loopback/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 0000000000000..64627ec86880f --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_I2C_TARGET_BUFFER_MODE=y diff --git a/samples/drivers/i2c/rtio_loopback/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/drivers/i2c/rtio_loopback/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 0000000000000..21bf0e503a4d9 --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * SDA = P0.26 and P1.2 + * SCL = P0.25 and P1.3 + */ + +/ { + aliases { + i2c-controller = &i2c1; + i2c-controller-target = &i2c2; + }; +}; + +&pinctrl { + i2c2_default: i2c2_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c2_sleep: i2c2_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&i2c2 { + compatible = "nordic,nrf-twis"; + pinctrl-0 = <&i2c2_default>; + pinctrl-1 = <&i2c2_sleep>; + pinctrl-names = "default", "sleep"; + status = "okay"; +}; diff --git a/samples/drivers/i2c/rtio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/samples/drivers/i2c/rtio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.conf new file mode 100644 index 0000000000000..9a83d7afb811c --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_I2C_NRFX_TWIS_BUF_SIZE=256 diff --git a/samples/drivers/i2c/rtio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/drivers/i2c/rtio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 0000000000000..928b52a66f57a --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * SDA = P2.8 and P2.9 + * SCL = P1.2 and P1.3 + */ + +/ { + aliases { + i2c-controller = &i2c130; + i2c-controller-target = &i2c131; + }; +}; + +&pinctrl { + i2c130_default: i2c130_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c130_sleep: i2c130_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + i2c131_default: i2c131_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c131_sleep: i2c131_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&i2c130 { + clock-frequency = ; + pinctrl-0 = <&i2c130_default>; + pinctrl-1 = <&i2c130_sleep>; + pinctrl-names = "default", "sleep"; + zephyr,concat-buf-size = <256>; + memory-regions = <&cpuapp_dma_region>; + status = "okay"; +}; + +&i2c131 { + compatible = "nordic,nrf-twis"; + clock-frequency = ; + pinctrl-0 = <&i2c131_default>; + pinctrl-1 = <&i2c131_sleep>; + pinctrl-names = "default", "sleep"; + memory-regions = <&cpuapp_dma_region>; + status = "okay"; +}; diff --git a/samples/drivers/i2c/rtio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/samples/drivers/i2c/rtio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.conf new file mode 100644 index 0000000000000..9a83d7afb811c --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_I2C_NRFX_TWIS_BUF_SIZE=256 diff --git a/samples/drivers/i2c/rtio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/samples/drivers/i2c/rtio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay new file mode 100644 index 0000000000000..4a7d2fe02a6f5 --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * SDA = P1.8 and P1.9 + * SCL = P1.10 and P1.11 + */ + +/ { + aliases { + i2c-controller = &i2c21; + i2c-controller-target = &i2c22; + }; +}; + +&pinctrl { + i2c21_default: i2c21_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c21_sleep: i2c21_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + i2c22_default: i2c22_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c22_sleep: i2c22_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&i2c21 { + pinctrl-0 = <&i2c21_default>; + pinctrl-1 = <&i2c21_sleep>; + pinctrl-names = "default", "sleep"; + zephyr,concat-buf-size = <256>; + status = "okay"; +}; + +&i2c22 { + compatible = "nordic,nrf-twis"; + pinctrl-0 = <&i2c22_default>; + pinctrl-1 = <&i2c22_sleep>; + pinctrl-names = "default", "sleep"; + status = "okay"; +}; diff --git a/samples/drivers/i2c/rtio_loopback/prj.conf b/samples/drivers/i2c/rtio_loopback/prj.conf new file mode 100644 index 0000000000000..f3579dce3759f --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/prj.conf @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_I2C=y +CONFIG_RTIO=y +CONFIG_I2C_RTIO=y +CONFIG_I2C_TARGET=y +CONFIG_I2C_TARGET_BUFFER_MODE=y diff --git a/samples/drivers/i2c/rtio_loopback/sample.yaml b/samples/drivers/i2c/rtio_loopback/sample.yaml new file mode 100644 index 0000000000000..68a752df94733 --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/sample.yaml @@ -0,0 +1,15 @@ +sample: + name: I2C RTIO loopback sample +tests: + sample.drivers.i2c.rtio_loopback: + tags: + - rtio + - i2c_target + harness: ztest + harness_config: + fixture: i2c_bus_short + platform_allow: + - b_u585i_iot02a + - nrf5340dk/nrf5340/cpuapp + - nrf54l15dk/nrf54l15/cpuapp + - nrf54h20dk/nrf54h20/cpuapp diff --git a/samples/drivers/i2c/rtio_loopback/src/main.c b/samples/drivers/i2c/rtio_loopback/src/main.c new file mode 100644 index 0000000000000..ef2a17dd47aed --- /dev/null +++ b/samples/drivers/i2c/rtio_loopback/src/main.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +#define I2C_CONTROLLER_NODE DT_ALIAS(i2c_controller) +#define I2C_CONTROLLER_TARGET_NODE DT_ALIAS(i2c_controller_target) +#define I2C_CONTROLLER_DEVICE_GET DEVICE_DT_GET(I2C_CONTROLLER_NODE) +#define I2C_CONTROLLER_TARGET_DEVICE_GET DEVICE_DT_GET(I2C_CONTROLLER_TARGET_NODE) +#define I2C_TARGET_ADDR 0x0A +#define SAMPLE_TIMEOUT K_SECONDS(1) + +static const struct device *sample_i2c_controller = I2C_CONTROLLER_DEVICE_GET; +static const struct device *sample_i2c_controller_target = I2C_CONTROLLER_TARGET_DEVICE_GET; + +/* Data to write and buffer to store write in */ +static uint8_t sample_write_data[] = {0x0A, 0x0B}; +static uint8_t sample_write_buf[sizeof(sample_write_data)]; +static uint32_t sample_write_buf_pos; + +/* Data to read and buffer to store read in */ +static uint8_t sample_read_data[] = {0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5}; +static uint32_t sample_read_data_pos; +static uint8_t sample_read_buf[sizeof(sample_read_data)]; + +/* + * The user defines an RTIO context to which actions like writes and reads will be + * submitted, and the results of said actions will be retrieved. + * + * We will be using 3 submission queue events (SQEs); i2c write, i2c read, + * done callback, and 2 completion queue events (CQEs); i2c write result, + * i2c read result. + */ +RTIO_DEFINE(sample_rtio, 3, 2); + +/* + * The user defines an RTIO IODEV which wraps the device which will perform the + * actions submitted to the RTIO context. In this sample, we are using an I2C + * controller device, so we use the I2C specific helper to define the RTIO IODEV. + */ +I2C_IODEV_DEFINE(sample_rtio_iodev, I2C_CONTROLLER_NODE, I2C_TARGET_ADDR); + +/* + * For async write read operation we will be waiting for a callback from RTIO. + * We will wait on this sem which we will give from the callback. + */ +static K_SEM_DEFINE(sample_write_read_sem, 0, 1); + +/* + * We register a simple I2C target which we will be targeting using RTIO. We + * store written data, and return sample_read_data when read. + */ +static int sample_target_write_requested(struct i2c_target_config *target_config) +{ + sample_write_buf_pos = 0; + return 0; +} + +static int sample_target_read_requested(struct i2c_target_config *target_config, uint8_t *val) +{ + sample_read_data_pos = 0; + *val = sample_read_data[sample_read_data_pos]; + return 0; +} + +static int sample_target_write_received(struct i2c_target_config *target_config, uint8_t val) +{ + if (sample_write_buf_pos == sizeof(sample_write_buf)) { + return -ENOMEM; + } + + sample_write_buf[sample_write_buf_pos] = val; + sample_write_buf_pos++; + return 0; +} + +static int sample_target_read_processed(struct i2c_target_config *target_config, uint8_t *val) +{ + sample_read_data_pos++; + + if (sample_read_data_pos == sizeof(sample_read_data)) { + return -ENOMEM; + } + + *val = sample_read_data[sample_read_data_pos]; + return 0; +} + +static void sample_target_buf_write_received(struct i2c_target_config *target_config, + uint8_t *data, + uint32_t size) +{ + sample_write_buf_pos = MIN(size, ARRAY_SIZE(sample_write_buf)); + memcpy(sample_write_buf, data, sample_write_buf_pos); +} + +static int sample_target_buf_read_requested(struct i2c_target_config *target_config, + uint8_t **data, + uint32_t *size) +{ + *data = sample_read_data; + *size = sizeof(sample_read_data); + return 0; +} + +static int sample_target_stop(struct i2c_target_config *config) +{ + ARG_UNUSED(config); + return 0; +} + +static const struct i2c_target_callbacks sample_target_callbacks = { + .write_requested = sample_target_write_requested, + .read_requested = sample_target_read_requested, + .write_received = sample_target_write_received, + .read_processed = sample_target_read_processed, + .buf_write_received = sample_target_buf_write_received, + .buf_read_requested = sample_target_buf_read_requested, + .stop = sample_target_stop, +}; + +static struct i2c_target_config sample_target_config = { + .address = I2C_TARGET_ADDR, + .callbacks = &sample_target_callbacks, +}; + +static int sample_init_i2c_target(void) +{ + return i2c_target_register(sample_i2c_controller_target, &sample_target_config); +} + +static void sample_reset_buffers(void) +{ + memset(sample_write_buf, 0, sizeof(sample_write_buf)); + memset(sample_read_buf, 0, sizeof(sample_read_buf)); +} + +static int sample_standard_write_read(void) +{ + int ret; + struct i2c_msg msgs[2]; + + msgs[0].buf = sample_write_data; + msgs[0].len = sizeof(sample_write_data); + msgs[0].flags = I2C_MSG_WRITE; + + msgs[1].buf = sample_read_buf; + msgs[1].len = sizeof(sample_read_buf); + msgs[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP; + + ret = i2c_transfer(sample_i2c_controller, + msgs, + ARRAY_SIZE(msgs), + I2C_TARGET_ADDR); + if (ret) { + return -EIO; + } + + return 0; +} + +static int sample_validate_write_read(void) +{ + int ret; + + if (sample_write_buf_pos != sizeof(sample_write_data)) { + return -EIO; + } + + ret = memcmp(sample_write_buf, sample_write_data, sizeof(sample_write_data)); + if (ret) { + return -EIO; + } + + ret = memcmp(sample_read_buf, sample_read_data, sizeof(sample_read_data)); + if (ret) { + return -EIO; + } + + return 0; +} + +/* This is functionally identical to sample_standard_write_read() but uses RTIO */ +static int sample_rtio_write_read(void) +{ + struct rtio_sqe *wr_sqe, *rd_sqe; + struct rtio_cqe *wr_rd_cqe; + int ret; + + /* + * We allocate one of the 3 submission queue events (SQEs) as defined by + * RTIO_DEFINE() and configure it to write sample_write_data to + * sample_rtio_iodev. + */ + wr_sqe = rtio_sqe_acquire(&sample_rtio); + rtio_sqe_prep_write(wr_sqe, + &sample_rtio_iodev, + 0, + sample_write_data, + sizeof(sample_write_data), + NULL); + + /* + * This write SQE is followed by a read SQE, which is part of a single + * transaction. We configure this by setting the RTIO_SQE_TRANSACTION. + */ + wr_sqe->flags |= RTIO_SQE_TRANSACTION; + + /* + * We then allocate an SQE and configure it to read + * sizeof(sample_read_buf) into sample_read_buf. + */ + rd_sqe = rtio_sqe_acquire(&sample_rtio); + rtio_sqe_prep_read(rd_sqe, + &sample_rtio_iodev, + 0, + sample_read_buf, + sizeof(sample_read_buf), NULL); + + /* + * Since we are working with I2C messages, we need to specify the I2C + * message options. The I2C_READ and I2C_WRITE are implicit since we + * are preparing read and write SQEs, I2C_STOP and I2C_RESTART are not, + * so we add them to the read SQE. + */ + rd_sqe->iodev_flags = RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + + /* + * With the two SQEs of the sample_rtio context prepared, we call + * rtio_submit() to have them executed. This call will execute all + * prepared SQEs. + * + * In this case, we wait for the two SQEs to be completed before + * continuing, similar to calling i2c_transfer(). + */ + ret = rtio_submit(&sample_rtio, 2); + if (ret) { + return -EIO; + } + + /* + * Since the RTIO SQEs are executed in the background, we need to + * get the CQE after and check its result. Since we configured the + * write and read SQEs as a single transaction, only one CQE is + * generated which includes both of them. If we had chained them + * instead, one CQE would be created for each of them. + */ + wr_rd_cqe = rtio_cqe_consume(&sample_rtio); + if (wr_rd_cqe->result) { + return -EIO; + } + + /* Release the CQE after having checked its result. */ + rtio_cqe_release(&sample_rtio, wr_rd_cqe); + return 0; +} + +static void rtio_write_read_done_callback(struct rtio *r, const struct rtio_sqe *sqe, void *arg0) +{ + struct k_sem *sem = arg0; + struct rtio_cqe *wr_rd_cqe; + + /* See sample_rtio_write_read() */ + wr_rd_cqe = rtio_cqe_consume(&sample_rtio); + if (wr_rd_cqe->result) { + /* Signal write and read SQEs completed with error */ + k_sem_reset(sem); + } + + /* See sample_rtio_write_read() */ + rtio_cqe_release(&sample_rtio, wr_rd_cqe); + + /* Signal write and read SQEs completed with success */ + k_sem_give(sem); +} + +/* + * Aside from the blocking wait for the sample_write_read_sem, async RTIO + * can be performed entirely from within ISRs. + */ +static int sample_rtio_write_read_async(void) +{ + struct rtio_sqe *wr_sqe, *rd_sqe, *cb_sqe; + int ret; + + /* See sample_rtio_write_read() */ + wr_sqe = rtio_sqe_acquire(&sample_rtio); + rtio_sqe_prep_write(wr_sqe, + &sample_rtio_iodev, + 0, + sample_write_data, + sizeof(sample_write_data), NULL); + wr_sqe->flags |= RTIO_SQE_TRANSACTION; + + /* See sample_rtio_write_read() */ + rd_sqe = rtio_sqe_acquire(&sample_rtio); + rtio_sqe_prep_read(rd_sqe, + &sample_rtio_iodev, + 0, + sample_read_buf, + sizeof(sample_read_buf), NULL); + rd_sqe->iodev_flags = RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + + /* + * The next SQE is a callback which we will use to signal that the + * write and read SQEs have completed. It has to be executed only + * after the write and read SQEs, which we configure by setting the + * RTIO_SQE_CHAINED flag. + */ + rd_sqe->flags |= RTIO_SQE_CHAINED; + + /* + * Prepare the callback SQE. The SQE allows us to pass an optional + * argument to the handler, which we will use to store a pointer to + * the binary semaphore we will be waiting on. + */ + cb_sqe = rtio_sqe_acquire(&sample_rtio); + rtio_sqe_prep_callback_no_cqe(cb_sqe, + rtio_write_read_done_callback, + &sample_write_read_sem, + NULL); + + /* + * Submit the SQEs for execution, without waiting for any of them + * to be completed. We use the callback to signal completion of all + * of them. + */ + ret = rtio_submit(&sample_rtio, 0); + if (ret) { + return -EIO; + } + + /* + * We wait for the callback which signals RTIO transfer has completed. + * + * We will be checking the CQE result from within the callback, which + * is entirely safe given RTIO is designed to work from ISR context. + * If the result is ok, we give the sem, if its not ok, we reset the + * sem (which makes k_sem_take() return an error). + */ + ret = k_sem_take(&sample_write_read_sem, SAMPLE_TIMEOUT); + if (ret) { + return -EIO; + } + + return 0; +} + +int main(void) +{ + int ret; + + printk("%s %s\n", "init_i2c_target", "running"); + ret = sample_init_i2c_target(); + if (ret) { + printk("%s %s\n", "init_i2c_target", "failed"); + return 0; + } + + sample_reset_buffers(); + + printk("%s %s\n", "standard_write_read", "running"); + ret = sample_standard_write_read(); + if (ret) { + printk("%s %s\n", "standard_write_read", "failed"); + return 0; + } + + ret = sample_validate_write_read(); + if (ret) { + printk("%s %s\n", "standard_write_read", "corrupted"); + return 0; + } + + sample_reset_buffers(); + + printk("%s %s\n", "rtio_write_read", "running"); + ret = sample_rtio_write_read(); + if (ret) { + printk("%s %s\n", "rtio_write_read", "failed"); + return 0; + } + + ret = sample_validate_write_read(); + if (ret) { + printk("%s %s\n", "rtio_write_read", "corrupted"); + return 0; + } + + sample_reset_buffers(); + + printk("%s %s\n", "rtio_write_read_async", "running"); + ret = sample_rtio_write_read_async(); + if (ret) { + printk("%s %s\n", "rtio_write_read_async", "failed"); + return 0; + } + + ret = sample_validate_write_read(); + if (ret) { + printk("%s %s\n", "rtio_write_read_async", "corrupted"); + return 0; + } + + printk("sample complete\n"); + return 0; +} diff --git a/samples/drivers/i2s/echo/Kconfig b/samples/drivers/i2s/echo/Kconfig index 8cd630f1c66ae..623e2ae6318ad 100644 --- a/samples/drivers/i2s/echo/Kconfig +++ b/samples/drivers/i2s/echo/Kconfig @@ -5,3 +5,15 @@ source "Kconfig.zephyr" config I2C default $(dt_compat_on_bus,$(DT_COMPAT_WOLFSON_WM8731),i2c) + +config TOGGLE_ECHO_EFFECT_SW0 + bool "Toggle echo effect when pressing sw0" + depends on $(dt_alias_enabled,sw0) + select GPIO + default y + +config STOP_START_STREAMS_SW1 + bool "Start/stop I2S streams when pressing sw1" + depends on $(dt_alias_enabled,sw1) + select GPIO + default y diff --git a/samples/drivers/i2s/echo/src/main.c b/samples/drivers/i2s/echo/src/main.c index bffa794158b3f..d9619bf94c7a4 100644 --- a/samples/drivers/i2s/echo/src/main.c +++ b/samples/drivers/i2s/echo/src/main.c @@ -30,12 +30,12 @@ #define TIMEOUT 1000 #define SW0_NODE DT_ALIAS(sw0) -#if DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#ifdef CONFIG_TOGGLE_ECHO_EFFECT_SW0 static struct gpio_dt_spec sw0_spec = GPIO_DT_SPEC_GET(SW0_NODE, gpios); #endif #define SW1_NODE DT_ALIAS(sw1) -#if DT_NODE_HAS_STATUS_OKAY(SW1_NODE) +#ifdef CONFIG_STOP_START_STREAMS_SW1 static struct gpio_dt_spec sw1_spec = GPIO_DT_SPEC_GET(SW1_NODE, gpios); #endif @@ -47,7 +47,7 @@ static int16_t echo_block[SAMPLES_PER_BLOCK]; static volatile bool echo_enabled = true; static K_SEM_DEFINE(toggle_transfer, 1, 1); -#if DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#ifdef CONFIG_TOGGLE_ECHO_EFFECT_SW0 static void sw0_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { @@ -58,7 +58,7 @@ static void sw0_handler(const struct device *dev, struct gpio_callback *cb, } #endif -#if DT_NODE_HAS_STATUS_OKAY(SW1_NODE) +#ifdef CONFIG_STOP_START_STREAMS_SW1 static void sw1_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { @@ -70,7 +70,7 @@ static bool init_buttons(void) { int ret; -#if DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#ifdef CONFIG_TOGGLE_ECHO_EFFECT_SW0 static struct gpio_callback sw0_cb_data; if (!gpio_is_ready_dt(&sw0_spec)) { @@ -98,7 +98,7 @@ static bool init_buttons(void) printk("Press \"%s\" to toggle the echo effect\n", sw0_spec.port->name); #endif -#if DT_NODE_HAS_STATUS_OKAY(SW1_NODE) +#ifdef CONFIG_STOP_START_STREAMS_SW1 static struct gpio_callback sw1_cb_data; if (!gpio_is_ready_dt(&sw1_spec)) { diff --git a/samples/drivers/i2s/i2s_codec/boards/stm32f4_disco.conf b/samples/drivers/i2s/i2s_codec/boards/stm32f4_disco.conf new file mode 100644 index 0000000000000..b3872c1efe5e2 --- /dev/null +++ b/samples/drivers/i2s/i2s_codec/boards/stm32f4_disco.conf @@ -0,0 +1,8 @@ +# Copyright 2025 Titouan Christophe +# SPDX-License-Identifier: Apache-2.0 + +# Even though the stm32f4_disco board overlay is tuned for 22.05/44.1/88.2kHz +# audio output, it hasn't enough RAM to hold all buffers allocated by this +# sample at such higher audio rates +CONFIG_SAMPLE_FREQ=8000 +CONFIG_AUDIO_CODEC=y diff --git a/samples/drivers/i2s/i2s_codec/boards/stm32f4_disco.overlay b/samples/drivers/i2s/i2s_codec/boards/stm32f4_disco.overlay new file mode 100644 index 0000000000000..e4adf92457874 --- /dev/null +++ b/samples/drivers/i2s/i2s_codec/boards/stm32f4_disco.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 Titouan Christophe + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + i2s-codec-tx = &i2s3; + }; +}; diff --git a/samples/drivers/i2s/i2s_codec/src/main.c b/samples/drivers/i2s/i2s_codec/src/main.c index 734d9a9f27b7f..cc96ae8bc5d43 100644 --- a/samples/drivers/i2s/i2s_codec/src/main.c +++ b/samples/drivers/i2s/i2s_codec/src/main.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/samples/drivers/i2s/output/README.rst b/samples/drivers/i2s/output/README.rst index 69d821b36a077..ec39ceacdd015 100644 --- a/samples/drivers/i2s/output/README.rst +++ b/samples/drivers/i2s/output/README.rst @@ -31,6 +31,6 @@ To build and flash the application: .. zephyr-app-commands:: :zephyr-app: samples/drivers/i2s/output - :board: mimxrt1060_evkb + :board: mimxrt1060_evk@B :goals: build flash :compact: diff --git a/samples/drivers/i2s/output/boards/mimxrt1060_evkb.conf b/samples/drivers/i2s/output/boards/mimxrt1060_evk_mimxrt1062_qspi_B.conf similarity index 100% rename from samples/drivers/i2s/output/boards/mimxrt1060_evkb.conf rename to samples/drivers/i2s/output/boards/mimxrt1060_evk_mimxrt1062_qspi_B.conf diff --git a/samples/drivers/i2s/output/boards/mimxrt1060_evkb.overlay b/samples/drivers/i2s/output/boards/mimxrt1060_evk_mimxrt1062_qspi_B.overlay similarity index 100% rename from samples/drivers/i2s/output/boards/mimxrt1060_evkb.overlay rename to samples/drivers/i2s/output/boards/mimxrt1060_evk_mimxrt1062_qspi_B.overlay diff --git a/samples/drivers/i2s/output/sample.yaml b/samples/drivers/i2s/output/sample.yaml index 8763b5128b23b..5b58271ec2646 100644 --- a/samples/drivers/i2s/output/sample.yaml +++ b/samples/drivers/i2s/output/sample.yaml @@ -2,7 +2,9 @@ sample: description: I2S Output Sample name: i2s_output common: - tags: drivers + tags: + - drivers + - i2s depends_on: i2s tests: sample.drivers.i2s.output: diff --git a/samples/drivers/ipm/ipm_esp32/Kconfig.sysbuild b/samples/drivers/ipm/ipm_esp32/Kconfig.sysbuild index 143c6c08eb505..3e6504f65bbf7 100644 --- a/samples/drivers/ipm/ipm_esp32/Kconfig.sysbuild +++ b/samples/drivers/ipm/ipm_esp32/Kconfig.sysbuild @@ -3,9 +3,3 @@ # SPDX-License-Identifier: Apache-2.0 source "share/sysbuild/Kconfig" - -config IPM_REMOTE_BOARD - string - default "esp32_devkitc_wrover/esp32/appcpu" if $(BOARD) = "esp32_devkitc_wroom" - default "esp32_devkitc_wroom/esp32/appcpu" if $(BOARD) = "esp32_devkitc_wroom" - default "esp32s3_devkitm/esp32s3/appcpu" if $(BOARD) = "esp32s3_devkitm" diff --git a/samples/drivers/ipm/ipm_esp32/boards/esp32s3_devkitm_procpu.overlay b/samples/drivers/ipm/ipm_esp32/boards/esp32s3_devkitm_procpu.overlay deleted file mode 100644 index ab1795abad772..0000000000000 --- a/samples/drivers/ipm/ipm_esp32/boards/esp32s3_devkitm_procpu.overlay +++ /dev/null @@ -1,3 +0,0 @@ -&ipm0 { - status = "okay"; -}; diff --git a/samples/drivers/ipm/ipm_esp32/boards/yd_esp32_procpu.overlay b/samples/drivers/ipm/ipm_esp32/boards/yd_esp32_procpu.overlay deleted file mode 100644 index ab1795abad772..0000000000000 --- a/samples/drivers/ipm/ipm_esp32/boards/yd_esp32_procpu.overlay +++ /dev/null @@ -1,3 +0,0 @@ -&ipm0 { - status = "okay"; -}; diff --git a/samples/drivers/ipm/ipm_esp32/src/procpu_shell.c b/samples/drivers/ipm/ipm_esp32/src/procpu_shell.c index e3889efa4ba5b..e036b6608e62b 100644 --- a/samples/drivers/ipm/ipm_esp32/src/procpu_shell.c +++ b/samples/drivers/ipm/ipm_esp32/src/procpu_shell.c @@ -4,10 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#if defined(CONFIG_IPM) || defined(CONFIG_MBOX) + #include #include -#include #include #include #include @@ -57,3 +58,4 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_amp, ); SHELL_CMD_REGISTER(amp, &sub_amp, "AMP debug commands.", NULL); +#endif diff --git a/samples/drivers/ipm/ipm_esp32/sysbuild.cmake b/samples/drivers/ipm/ipm_esp32/sysbuild.cmake index 1ec5cf9c3e4d3..1acb297b8b3c2 100644 --- a/samples/drivers/ipm/ipm_esp32/sysbuild.cmake +++ b/samples/drivers/ipm/ipm_esp32/sysbuild.cmake @@ -2,11 +2,20 @@ # # Copyright 2024 Espressif +# Prepare the full board name to be used for the remote target +string(REPLACE "procpu" "appcpu" REMOTE_CPU "${BOARD_QUALIFIERS}") +string(CONFIGURE "${BOARD}${REMOTE_CPU}" IPM_REMOTE_BOARD) + +if(${REMOTE_CPU} STREQUAL ${BOARD_QUALIFIERS}) + # Make sure the remote build is using different target than host CPU + message(FATAL_ERROR "BOARD_QUALIFIERS name error. Please check the target board name string.") +endif() + # Add external project ExternalZephyrProject_Add( APPLICATION ipm_esp32_remote SOURCE_DIR ${APP_DIR}/remote - BOARD ${SB_CONFIG_IPM_REMOTE_BOARD} + BOARD ${IPM_REMOTE_BOARD} ) # Add dependencies so that the remote sample will be built first diff --git a/samples/drivers/jesd216/boards/bmd_345_eval.conf b/samples/drivers/jesd216/boards/bmd_345_eval.conf deleted file mode 100644 index 8c262a3483ed3..0000000000000 --- a/samples/drivers/jesd216/boards/bmd_345_eval.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2021 Linumiz -# -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_SPI=n -CONFIG_SPI_NOR=n -CONFIG_NORDIC_QSPI_NOR=y diff --git a/samples/drivers/jesd216/boards/mr_canhubk3.conf b/samples/drivers/jesd216/boards/mr_canhubk3.conf deleted file mode 100644 index b625f401a1c86..0000000000000 --- a/samples/drivers/jesd216/boards/mr_canhubk3.conf +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright 2023 NXP -# SPDX-License-Identifier: Apache-2.0 - -# Override defaults for SPI NOR flash driver -CONFIG_SPI_NOR=n diff --git a/samples/drivers/jesd216/boards/nrf52840dk_nrf52840.conf b/samples/drivers/jesd216/boards/nrf52840dk_nrf52840.conf deleted file mode 100644 index 976830569e3d7..0000000000000 --- a/samples/drivers/jesd216/boards/nrf52840dk_nrf52840.conf +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2019 Peter Bigot Consulting, LLC -# Copyright (c) 2019 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_SPI=n -CONFIG_SPI_NOR=n -#CONFIG_NORDIC_QSPI_NOR=y diff --git a/samples/drivers/jesd216/boards/nrf52840dk_nrf52840_spi.conf b/samples/drivers/jesd216/boards/nrf52840dk_nrf52840_spi.conf deleted file mode 100644 index 15982f1c92edf..0000000000000 --- a/samples/drivers/jesd216/boards/nrf52840dk_nrf52840_spi.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2022 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_SPI=y -CONFIG_SPI_NOR=y diff --git a/samples/drivers/jesd216/prj.conf b/samples/drivers/jesd216/prj.conf index c5c747a3bb334..b1b51a1e12fed 100644 --- a/samples/drivers/jesd216/prj.conf +++ b/samples/drivers/jesd216/prj.conf @@ -1,8 +1,3 @@ CONFIG_STDOUT_CONSOLE=y CONFIG_FLASH=y CONFIG_FLASH_JESD216_API=y - -# Assume the standard SPI NOR flash driver. If the device uses -# another driver add an override configuration in boards/. -CONFIG_SPI=y -CONFIG_SPI_NOR=y diff --git a/samples/drivers/jesd216/sample.yaml b/samples/drivers/jesd216/sample.yaml index 5dcdc6678dc4c..0ea0dae331aee 100644 --- a/samples/drivers/jesd216/sample.yaml +++ b/samples/drivers/jesd216/sample.yaml @@ -26,7 +26,6 @@ tests: sample.drivers.jesd216.nrf52840dk_spi: extra_args: - DTC_OVERLAY_FILE=boards/nrf52840dk_nrf52840_spi.overlay - - EXTRA_CONF_FILE=boards/nrf52840dk_nrf52840_spi.conf platform_allow: nrf52840dk/nrf52840 integration_platforms: - nrf52840dk/nrf52840 diff --git a/samples/drivers/kscan/src/main.c b/samples/drivers/kscan/src/main.c index 21c02a3adc81b..66fdd5727bb62 100644 --- a/samples/drivers/kscan/src/main.c +++ b/samples/drivers/kscan/src/main.c @@ -6,7 +6,6 @@ #include #include -#include #include #include diff --git a/samples/drivers/led/led_strip/boards/adafruit_qt_py_esp32s3_procpu.conf b/samples/drivers/led/led_strip/boards/adafruit_qt_py_esp32s3_procpu.conf new file mode 100644 index 0000000000000..8230eb9896b4f --- /dev/null +++ b/samples/drivers/led/led_strip/boards/adafruit_qt_py_esp32s3_procpu.conf @@ -0,0 +1,2 @@ +CONFIG_GPIO=y +CONFIG_GPIO_HOGS=y diff --git a/samples/drivers/led_strip/boards/bbc_microbit.conf b/samples/drivers/led/led_strip/boards/bbc_microbit.conf similarity index 100% rename from samples/drivers/led_strip/boards/bbc_microbit.conf rename to samples/drivers/led/led_strip/boards/bbc_microbit.conf diff --git a/samples/drivers/led/led_strip/boards/esp32s3_devkitc_procpu.overlay b/samples/drivers/led/led_strip/boards/esp32s3_devkitc_procpu.overlay index 00b7c46871e28..8818cbd2384d2 100644 --- a/samples/drivers/led/led_strip/boards/esp32s3_devkitc_procpu.overlay +++ b/samples/drivers/led/led_strip/boards/esp32s3_devkitc_procpu.overlay @@ -20,10 +20,10 @@ i2s_led: &i2s0 { dmas = <&dma 3>; dma-names = "tx"; - led_strip: ws2812 { + led_strip: ws2812@0 { compatible = "worldsemi,ws2812-i2s"; - i2s-dev = <&i2s_led>; + reg = <0>; chain-length = <46>; color-mapping = ; pinctrl-names = "default"; - led_strip: ws2812 { + led_strip: ws2812@0 { compatible = "worldsemi,ws2812-i2s"; - i2s-dev = <&i2s_led>; + reg = <0>; chain-length = <42>; /* arbitrary; change at will */ color-mapping = ; pinctrl-names = "default"; - led_strip: ws2812 { + led_strip: ws2812@0 { compatible = "worldsemi,ws2812-i2s"; - i2s-dev = < &i2s_led >; + reg = <0>; chain-length = <10>; /* arbitrary; change at will */ color-mapping = ; +}; + +&pwm1 { + status = "okay"; +}; diff --git a/samples/drivers/led/pwm/boards/rpi_pico2_rp2350a_m33.conf b/samples/drivers/led/pwm/boards/rpi_pico2_rp2350a_m33.conf new file mode 100644 index 0000000000000..64a21d23f2715 --- /dev/null +++ b/samples/drivers/led/pwm/boards/rpi_pico2_rp2350a_m33.conf @@ -0,0 +1,3 @@ +CONFIG_BLINK_DELAY_SHORT=20 +CONFIG_BLINK_DELAY_LONG=50 +CONFIG_FADE_DELAY=15 diff --git a/samples/drivers/led/pwm/boards/rpi_pico2_rp2350a_m33.overlay b/samples/drivers/led/pwm/boards/rpi_pico2_rp2350a_m33.overlay new file mode 100644 index 0000000000000..8b83efe6ea08f --- /dev/null +++ b/samples/drivers/led/pwm/boards/rpi_pico2_rp2350a_m33.overlay @@ -0,0 +1,8 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Andrew Featherstone + */ + +/* Pico 2 is compatible with the Pico 1, so reuse. */ +#include "rpi_pico.overlay" diff --git a/samples/drivers/led/pwm/boards/stm32f4_disco.overlay b/samples/drivers/led/pwm/boards/stm32f4_disco.overlay new file mode 100644 index 0000000000000..d52bb64e67309 --- /dev/null +++ b/samples/drivers/led/pwm/boards/stm32f4_disco.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + leds { + status = "disabled"; + }; +}; diff --git a/samples/drivers/led/pwm/sample.yaml b/samples/drivers/led/pwm/sample.yaml index 21d27c0d6a999..8b7e745a292ca 100644 --- a/samples/drivers/led/pwm/sample.yaml +++ b/samples/drivers/led/pwm/sample.yaml @@ -17,6 +17,7 @@ tests: - "Turned on" - "Turned off" - "Increasing brightness gradually" + - "Decreasing brightness gradually" - "Blinking on: ([0-9]+) msec, off: ([0-9]+) msec" - "(Blinking on: ([0-9]+) msec, off: ([0-9]+) msec|Cycle period not supported)" - "Turned off, loop end" diff --git a/samples/drivers/led/pwm/src/main.c b/samples/drivers/led/pwm/src/main.c index a59887c6b8f93..7ec77550defdf 100644 --- a/samples/drivers/led/pwm/src/main.c +++ b/samples/drivers/led/pwm/src/main.c @@ -33,7 +33,7 @@ const int num_leds = ARRAY_SIZE(led_label); static void run_led_test(const struct device *led_pwm, uint8_t led) { int err; - uint16_t level; + int16_t level; LOG_INF("Testing LED %d - %s", led, led_label[led] ? : "no label"); @@ -67,6 +67,18 @@ static void run_led_test(const struct device *led_pwm, uint8_t led) } k_sleep(K_MSEC(1000)); + /* Decrease LED brightness gradually down to the minimum level. */ + LOG_INF(" Decreasing brightness gradually"); + for (level = MAX_BRIGHTNESS; level >= 0; level--) { + err = led_set_brightness(led_pwm, led, level); + if (err < 0) { + LOG_ERR("err=%d brightness=%d\n", err, level); + return; + } + k_sleep(K_MSEC(CONFIG_FADE_DELAY)); + } + k_sleep(K_MSEC(1000)); + #if CONFIG_BLINK_DELAY_SHORT > 0 /* Start LED blinking (short cycle) */ err = led_blink(led_pwm, led, CONFIG_BLINK_DELAY_SHORT, CONFIG_BLINK_DELAY_SHORT); diff --git a/samples/drivers/led/sx1509b_intensity/prj.conf b/samples/drivers/led/sx1509b_intensity/prj.conf index 4fe0993667514..7c6ec6ce52884 100644 --- a/samples/drivers/led/sx1509b_intensity/prj.conf +++ b/samples/drivers/led/sx1509b_intensity/prj.conf @@ -9,3 +9,4 @@ CONFIG_USE_SEGGER_RTT=y CONFIG_LOG_MODE_MINIMAL=n CONFIG_I2C=y +CONFIG_GPIO=y diff --git a/samples/drivers/lora/receive/sample.yaml b/samples/drivers/lora/receive/sample.yaml index 46b53a008c618..93e070db46ca5 100644 --- a/samples/drivers/lora/receive/sample.yaml +++ b/samples/drivers/lora/receive/sample.yaml @@ -11,3 +11,5 @@ tests: type: one_line regex: - " lora_receive: Synchronous reception" + integration_platforms: + - b_l072z_lrwan1 diff --git a/samples/drivers/lora/receive/src/main.c b/samples/drivers/lora/receive/src/main.c index 102e28fa8b1da..db42583860b0a 100644 --- a/samples/drivers/lora/receive/src/main.c +++ b/samples/drivers/lora/receive/src/main.c @@ -21,12 +21,13 @@ BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(DEFAULT_RADIO_NODE), LOG_MODULE_REGISTER(lora_receive); void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size, - int16_t rssi, int8_t snr) + int16_t rssi, int8_t snr, void *user_data) { static int cnt; ARG_UNUSED(dev); ARG_UNUSED(size); + ARG_UNUSED(user_data); LOG_INF("LoRa RX RSSI: %d dBm, SNR: %d dB", rssi, snr); LOG_HEXDUMP_INF(data, size, "LoRa RX payload"); @@ -34,7 +35,7 @@ void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size, /* Stop receiving after 10 packets */ if (++cnt == 10) { LOG_INF("Stopping packet receptions"); - lora_recv_async(dev, NULL); + lora_recv_async(dev, NULL, NULL); } } @@ -80,12 +81,12 @@ int main(void) } LOG_INF("LoRa RX RSSI: %d dBm, SNR: %d dB", rssi, snr); - LOG_HEXDUMP_INF(data, size, "LoRa RX payload"); + LOG_HEXDUMP_INF(data, len, "LoRa RX payload"); } /* Enable asynchronous reception */ LOG_INF("Asynchronous reception"); - lora_recv_async(lora_dev, lora_receive_cb); + lora_recv_async(lora_dev, lora_receive_cb, NULL); k_sleep(K_FOREVER); return 0; } diff --git a/samples/drivers/lora/send/sample.yaml b/samples/drivers/lora/send/sample.yaml index 67024e5fdfb0b..3e9fcc96f0004 100644 --- a/samples/drivers/lora/send/sample.yaml +++ b/samples/drivers/lora/send/sample.yaml @@ -11,3 +11,5 @@ tests: type: one_line regex: - " lora_send: Data sent!" + integration_platforms: + - b_l072z_lrwan1 diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index 7ae21a6a8e99f..0d1644d418978 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -1,6 +1,6 @@ # # Copyright (c) 2021 Carlo Caione -# Copyright 2023-2024 NXP +# Copyright 2023-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -16,7 +16,9 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_ADP_XC7K_AE350 OR CONFIG_BOARD_MIMXRT1170_EVK_MIMXRT1176_CM7 OR CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM7 OR + CONFIG_BOARD_MIMXRT1180_EVK_MIMXRT1189_CM33 OR CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU0 OR + CONFIG_BOARD_FRDM_MCXN947_MCXN947_CPU0 OR CONFIG_BOARD_ESP32_DEVKITC_WROOM_ESP32_PROCPU OR CONFIG_BOARD_ESP32S3_DEVKITM_ESP32S3_PROCPU OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR diff --git a/samples/drivers/mbox/Kconfig.sysbuild b/samples/drivers/mbox/Kconfig.sysbuild index cc0a847f28d54..ce58f93763baf 100644 --- a/samples/drivers/mbox/Kconfig.sysbuild +++ b/samples/drivers/mbox/Kconfig.sysbuild @@ -1,5 +1,5 @@ # Copyright 2023 Nordic Semiconductor ASA -# Copyright 2023-2024 NXP +# Copyright 2023-2025 NXP # # SPDX-License-Identifier: Apache-2.0 @@ -13,7 +13,9 @@ config REMOTE_BOARD default "mimxrt1170_evkb/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evkb" default "mimxrt1170_evk/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evk" default "mimxrt1160_evk/mimxrt1166/cm4" if $(BOARD) = "mimxrt1160_evk" + default "mimxrt1180_evk/mimxrt1189/cm7" if $(BOARD) = "mimxrt1180_evk" default "lpcxpresso55s69/lpc55s69/cpu1" if $(BOARD) = "lpcxpresso55s69" + default "frdm_mcxn947/mcxn947/cpu1" if $(BOARD) = "frdm_mcxn947" default "nrf54h20dk/nrf54h20/cpuapp" if "$(BOARD)${BOARD_QUALIFIERS}" = "nrf54h20dk/nrf54h20/cpurad" default "nrf54l15dk/nrf54l15/cpuflpr" if $(BOARD) = "nrf54l15dk" default "stm32h747i_disco/stm32h747xx/m4" if $(BOARD) = "stm32h747i_disco" diff --git a/samples/drivers/mbox/boards/esp32_devkitc_wroom_procpu.overlay b/samples/drivers/mbox/boards/esp32_devkitc_wroom_procpu.overlay index 211ec3f8f5107..0b2dfea45ff7d 100644 --- a/samples/drivers/mbox/boards/esp32_devkitc_wroom_procpu.overlay +++ b/samples/drivers/mbox/boards/esp32_devkitc_wroom_procpu.overlay @@ -6,7 +6,7 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &mbox0; }; diff --git a/samples/drivers/mbox/boards/esp32s3_devkitm_procpu.overlay b/samples/drivers/mbox/boards/esp32s3_devkitm_procpu.overlay index 211ec3f8f5107..0b2dfea45ff7d 100644 --- a/samples/drivers/mbox/boards/esp32s3_devkitm_procpu.overlay +++ b/samples/drivers/mbox/boards/esp32s3_devkitm_procpu.overlay @@ -6,7 +6,7 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &mbox0; }; diff --git a/samples/drivers/mbox/boards/frdm_mcxn947_mcxn947_cpu0.conf b/samples/drivers/mbox/boards/frdm_mcxn947_mcxn947_cpu0.conf new file mode 100644 index 0000000000000..7e6904d56d59d --- /dev/null +++ b/samples/drivers/mbox/boards/frdm_mcxn947_mcxn947_cpu0.conf @@ -0,0 +1 @@ +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox/boards/frdm_mcxn947_mcxn947_cpu0.overlay b/samples/drivers/mbox/boards/frdm_mcxn947_mcxn947_cpu0.overlay new file mode 100644 index 0000000000000..42601e9533612 --- /dev/null +++ b/samples/drivers/mbox/boards/frdm_mcxn947_mcxn947_cpu0.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox 1>, <&mbox 0>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox/boards/mimxrt1180_evk_mimxrt1189_cm33.conf b/samples/drivers/mbox/boards/mimxrt1180_evk_mimxrt1189_cm33.conf new file mode 100644 index 0000000000000..60eead5a076e4 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt1180_evk_mimxrt1189_cm33.conf @@ -0,0 +1,2 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_INCLUDE_REMOTE_DIR=y diff --git a/samples/drivers/mbox/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/samples/drivers/mbox/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..9836b08ebe3d3 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox1_a 1>, <&mbox1_a 0>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox/remote/CMakeLists.txt b/samples/drivers/mbox/remote/CMakeLists.txt index 311e489177d70..7382d8ce60279 100644 --- a/samples/drivers/mbox/remote/CMakeLists.txt +++ b/samples/drivers/mbox/remote/CMakeLists.txt @@ -1,6 +1,6 @@ # # Copyright (c) 2021 Carlo Caione -# Copyright 2023-2024 NXP +# Copyright 2023-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -14,7 +14,9 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET OR CONFIG_BOARD_ADP_XC7K_AE350 OR CONFIG_BOARD_MIMXRT1170_EVK_MIMXRT1176_CM4 OR CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM4 OR + CONFIG_BOARD_MIMXRT1180_EVK_MIMXRT1189_CM7 OR CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU1 OR + CONFIG_BOARD_FRDM_MCXN947_MCXN947_CPU1 OR CONFIG_BOARD_ESP32_DEVKITC_WROOM_ESP32_APPCPU OR CONFIG_BOARD_ESP32S3_DEVKITM_ESP32S3_APPCPU OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR OR diff --git a/samples/drivers/mbox/remote/boards/esp32_devkitc_wroom_appcpu.overlay b/samples/drivers/mbox/remote/boards/esp32_devkitc_wroom_appcpu.overlay index c9643fb3e5d0a..405e3bc23e9f5 100644 --- a/samples/drivers/mbox/remote/boards/esp32_devkitc_wroom_appcpu.overlay +++ b/samples/drivers/mbox/remote/boards/esp32_devkitc_wroom_appcpu.overlay @@ -6,7 +6,7 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &mbox0; }; diff --git a/samples/drivers/mbox/remote/boards/esp32s3_devkitm_appcpu.overlay b/samples/drivers/mbox/remote/boards/esp32s3_devkitm_appcpu.overlay index c9643fb3e5d0a..405e3bc23e9f5 100644 --- a/samples/drivers/mbox/remote/boards/esp32s3_devkitm_appcpu.overlay +++ b/samples/drivers/mbox/remote/boards/esp32s3_devkitm_appcpu.overlay @@ -6,7 +6,7 @@ / { chosen { - zephyr,sram = &sram0; + zephyr,sram = &sram1; zephyr,ipc_shm = &shm0; zephyr,ipc = &mbox0; }; diff --git a/samples/drivers/mbox/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf b/samples/drivers/mbox/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf new file mode 100644 index 0000000000000..7e6904d56d59d --- /dev/null +++ b/samples/drivers/mbox/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf @@ -0,0 +1 @@ +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay b/samples/drivers/mbox/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay new file mode 100644 index 0000000000000..4e3b4ae1208c4 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox 0>, <&mbox 1>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf b/samples/drivers/mbox/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf new file mode 100644 index 0000000000000..77adcfa24f4e2 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf @@ -0,0 +1,2 @@ +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/samples/drivers/mbox/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay new file mode 100644 index 0000000000000..db51f5184fd5a --- /dev/null +++ b/samples/drivers/mbox/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox1_b 0>, <&mbox1_b 1>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index f264050b68e47..aacac1eea1c9c 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -13,6 +13,7 @@ tests: - mimxrt1170_evk/mimxrt1176/cm7 - mimxrt1160_evk/mimxrt1166/cm7 - lpcxpresso55s69/lpc55s69/cpu0 + - frdm_mcxn947/mcxn947/cpu0 integration_platforms: - nrf5340dk/nrf5340/cpuapp harness: console diff --git a/samples/drivers/mbox/sysbuild.cmake b/samples/drivers/mbox/sysbuild.cmake index e2a5a03b87eb6..3180273351476 100644 --- a/samples/drivers/mbox/sysbuild.cmake +++ b/samples/drivers/mbox/sysbuild.cmake @@ -1,5 +1,5 @@ # Copyright (c) 2023 Nordic Semiconductor ASA -# Copyright 2023-2024 NXP +# Copyright 2023-2025 NXP # SPDX-License-Identifier: Apache-2.0 if("${SB_CONFIG_REMOTE_BOARD}" STREQUAL "") @@ -22,6 +22,7 @@ native_simulator_set_final_executable(${DEFAULT_IMAGE}) if(SB_CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM7 OR SB_CONFIG_BOARD_MIMXRT1170_EVK_MIMXRT1176_CM7 OR + SB_CONFIG_BOARD_MIMXRT1180_EVK_MIMXRT1189_CM33 OR SB_CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU0) # For these NXP boards the main core application is dependent on # 'zephyr_image_info.h' generated by remote application. diff --git a/samples/drivers/mbox_data/CMakeLists.txt b/samples/drivers/mbox_data/CMakeLists.txt index e816cf7426f24..31cd00e202b1c 100644 --- a/samples/drivers/mbox_data/CMakeLists.txt +++ b/samples/drivers/mbox_data/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -11,6 +11,8 @@ set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/../remote/zephyr) if(CONFIG_BOARD_MIMXRT1170_EVK_MIMXRT1176_CM7 OR CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM7 OR + CONFIG_BOARD_FRDM_MCXN947_MCXN947_CPU0 OR + CONFIG_BOARD_MIMXRT1180_EVK_MIMXRT1189_CM33 OR CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU0) message(STATUS "${BOARD}${BOARD_QUALIFIERS} compile as Main in this sample") else() diff --git a/samples/drivers/mbox_data/Kconfig.sysbuild b/samples/drivers/mbox_data/Kconfig.sysbuild index 66a4e929ae2f9..106ccb1cb7d39 100644 --- a/samples/drivers/mbox_data/Kconfig.sysbuild +++ b/samples/drivers/mbox_data/Kconfig.sysbuild @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 @@ -9,4 +9,6 @@ string default "mimxrt1170_evkb/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evkb" default "mimxrt1170_evk/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evk" default "mimxrt1160_evk/mimxrt1166/cm4" if $(BOARD) = "mimxrt1160_evk" + default "mimxrt1180_evk/mimxrt1189/cm7" if $(BOARD) = "mimxrt1180_evk" default "lpcxpresso55s69/lpc55s69/cpu1" if $(BOARD) = "lpcxpresso55s69" + default "frdm_mcxn947/mcxn947/cpu1" if $(BOARD) = "frdm_mcxn947" diff --git a/samples/drivers/mbox_data/README.rst b/samples/drivers/mbox_data/README.rst index 1f8b1615f8eda..1ad37ea1ed15a 100644 --- a/samples/drivers/mbox_data/README.rst +++ b/samples/drivers/mbox_data/README.rst @@ -54,6 +54,15 @@ Building the application for lpcxpresso55s69_cpu1 :goals: debug :west-args: --sysbuild +Building the application for frdm_mcxn947/mcxn947/cpu0 +====================================================== + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/mbox_data/ + :board: frdm_mcxn947/mcxn947/cpu0 + :goals: debug + :west-args: --sysbuild + Sample Output ============= diff --git a/samples/drivers/mbox_data/boards/frdm_mcxn947_mcxn947_cpu0.conf b/samples/drivers/mbox_data/boards/frdm_mcxn947_mcxn947_cpu0.conf new file mode 100644 index 0000000000000..7e6904d56d59d --- /dev/null +++ b/samples/drivers/mbox_data/boards/frdm_mcxn947_mcxn947_cpu0.conf @@ -0,0 +1 @@ +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox_data/boards/frdm_mcxn947_mcxn947_cpu0.overlay b/samples/drivers/mbox_data/boards/frdm_mcxn947_mcxn947_cpu0.overlay new file mode 100644 index 0000000000000..42601e9533612 --- /dev/null +++ b/samples/drivers/mbox_data/boards/frdm_mcxn947_mcxn947_cpu0.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox 1>, <&mbox 0>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox_data/boards/mimxrt1180_evk_mimxrt1189_cm33.conf b/samples/drivers/mbox_data/boards/mimxrt1180_evk_mimxrt1189_cm33.conf new file mode 100644 index 0000000000000..60eead5a076e4 --- /dev/null +++ b/samples/drivers/mbox_data/boards/mimxrt1180_evk_mimxrt1189_cm33.conf @@ -0,0 +1,2 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_INCLUDE_REMOTE_DIR=y diff --git a/samples/drivers/mbox_data/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/samples/drivers/mbox_data/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..9836b08ebe3d3 --- /dev/null +++ b/samples/drivers/mbox_data/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox1_a 1>, <&mbox1_a 0>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox_data/remote/CMakeLists.txt b/samples/drivers/mbox_data/remote/CMakeLists.txt index d3d0991a65ca3..5342a2c98156f 100644 --- a/samples/drivers/mbox_data/remote/CMakeLists.txt +++ b/samples/drivers/mbox_data/remote/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -9,6 +9,8 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) if(CONFIG_BOARD_MIMXRT1170_EVK_MIMXRT1176_CM4 OR CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM4 OR + CONFIG_BOARD_FRDM_MCXN947_MCXN947_CPU1 OR + CONFIG_BOARD_MIMXRT1180_EVK_MIMXRT1189_CM7 OR CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU1) message(STATUS "${BOARD}${BOARD_QUALIFIERS} compile as remote in this sample") else() diff --git a/samples/drivers/mbox_data/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf b/samples/drivers/mbox_data/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf new file mode 100644 index 0000000000000..7e6904d56d59d --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf @@ -0,0 +1 @@ +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox_data/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay b/samples/drivers/mbox_data/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay new file mode 100644 index 0000000000000..4e3b4ae1208c4 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox 0>, <&mbox 1>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox_data/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf b/samples/drivers/mbox_data/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf new file mode 100644 index 0000000000000..77adcfa24f4e2 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf @@ -0,0 +1,2 @@ +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox_data/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/samples/drivers/mbox_data/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay new file mode 100644 index 0000000000000..db51f5184fd5a --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + mbox-consumer { + compatible = "vnd,mbox-consumer"; + mboxes = <&mbox1_b 0>, <&mbox1_b 1>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/drivers/mbox_data/sample.yaml b/samples/drivers/mbox_data/sample.yaml index 53390b5b16a24..33fd2574e50f4 100644 --- a/samples/drivers/mbox_data/sample.yaml +++ b/samples/drivers/mbox_data/sample.yaml @@ -10,6 +10,7 @@ tests: - mimxrt1170_evk/mimxrt1176/cm7 - mimxrt1160_evk/mimxrt1166/cm7 - lpcxpresso55s69/lpc55s69/cpu0 + - frdm_mcxn947/mcxn947/cpu0 integration_platforms: - mimxrt1160_evk/mimxrt1166/cm7 - lpcxpresso55s69/lpc55s69/cpu0 diff --git a/samples/drivers/mbox_data/sysbuild.cmake b/samples/drivers/mbox_data/sysbuild.cmake index 0fb83fbadd3e2..dcb2509a05d57 100644 --- a/samples/drivers/mbox_data/sysbuild.cmake +++ b/samples/drivers/mbox_data/sysbuild.cmake @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 @@ -18,6 +18,7 @@ ExternalZephyrProject_Add( if(SB_CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM7 OR SB_CONFIG_BOARD_MIMXRT1170_EVK_MIMXRT1176_CM7 OR + SB_CONFIG_BOARD_MIMXRT1180_EVK_MIMXRT1189_CM33 OR SB_CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU0) # For these NXP boards the main core application is dependent on # 'zephyr_image_info.h' generated by remote application. diff --git a/samples/drivers/misc/ft800/src/main.c b/samples/drivers/misc/ft800/src/main.c index 44178d9e1435b..48e763bb93125 100644 --- a/samples/drivers/misc/ft800/src/main.c +++ b/samples/drivers/misc/ft800/src/main.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include @@ -23,22 +24,31 @@ static volatile bool process_touch; -static void touch_irq(void) +static void touch_irq(const struct device *dev, void *user_data) { + (void)dev; + (void)user_data; + process_touch = true; } int main(void) { + const struct device *ft8xx = DEVICE_DT_GET_ONE(ftdi_ft800); int cnt; int val; struct ft8xx_touch_transform tt; + if (!device_is_ready(ft8xx)) { + printk("FT8xx device is not ready. Aborting\n"); + return -1; + } + /* To get touch events calibrate the display */ - ft8xx_calibrate(&tt); + ft8xx_calibrate(ft8xx, &tt); /* Get interrupts on touch event */ - ft8xx_register_int(touch_irq); + ft8xx_register_int(ft8xx, touch_irq, NULL); /* Starting counting */ val = 0; @@ -46,40 +56,40 @@ int main(void) while (1) { /* Start Display List */ - ft8xx_copro_cmd_dlstart(); - ft8xx_copro_cmd(FT8XX_CLEAR_COLOR_RGB(0x00, 0x00, 0x00)); - ft8xx_copro_cmd(FT8XX_CLEAR(1, 1, 1)); + ft8xx_copro_cmd_dlstart(ft8xx); + ft8xx_copro_cmd(ft8xx, FT8XX_CLEAR_COLOR_RGB(0x00, 0x00, 0x00)); + ft8xx_copro_cmd(ft8xx, FT8XX_CLEAR(1, 1, 1)); /* Set color */ - ft8xx_copro_cmd(FT8XX_COLOR_RGB(0xf0, 0xf0, 0xf0)); + ft8xx_copro_cmd(ft8xx, FT8XX_COLOR_RGB(0xf0, 0xf0, 0xf0)); /* Display the counter */ - ft8xx_copro_cmd_number(20, 20, 29, FT8XX_OPT_SIGNED, cnt); + ft8xx_copro_cmd_number(ft8xx, 20, 20, 29, FT8XX_OPT_SIGNED, cnt); cnt++; /* Display the hello message */ - ft8xx_copro_cmd_text(20, 70, 30, 0, "Hello,"); + ft8xx_copro_cmd_text(ft8xx, 20, 70, 30, 0, "Hello,"); /* Set Zephyr color */ - ft8xx_copro_cmd(FT8XX_COLOR_RGB(0x78, 0x29, 0xd2)); - ft8xx_copro_cmd_text(20, 105, 30, 0, "Zephyr!"); + ft8xx_copro_cmd(ft8xx, FT8XX_COLOR_RGB(0x78, 0x29, 0xd2)); + ft8xx_copro_cmd_text(ft8xx, 20, 105, 30, 0, "Zephyr!"); /* Display value set with buttons */ - ft8xx_copro_cmd(FT8XX_COLOR_RGB(0xff, 0xff, 0xff)); - ft8xx_copro_cmd_number(80, 170, 29, + ft8xx_copro_cmd(ft8xx, FT8XX_COLOR_RGB(0xff, 0xff, 0xff)); + ft8xx_copro_cmd_number(ft8xx, 80, 170, 29, FT8XX_OPT_SIGNED | FT8XX_OPT_RIGHTX, val); - ft8xx_copro_cmd(FT8XX_TAG(TAG_PLUS)); - ft8xx_copro_cmd_text(90, 160, 31, 0, "+"); - ft8xx_copro_cmd(FT8XX_TAG(TAG_MINUS)); - ft8xx_copro_cmd_text(20, 160, 31, 0, "-"); + ft8xx_copro_cmd(ft8xx, FT8XX_TAG(TAG_PLUS)); + ft8xx_copro_cmd_text(ft8xx, 90, 160, 31, 0, "+"); + ft8xx_copro_cmd(ft8xx, FT8XX_TAG(TAG_MINUS)); + ft8xx_copro_cmd_text(ft8xx, 20, 160, 31, 0, "-"); /* Finish Display List */ - ft8xx_copro_cmd(FT8XX_DISPLAY()); + ft8xx_copro_cmd(ft8xx, FT8XX_DISPLAY()); /* Display created frame */ - ft8xx_copro_cmd_swap(); + ft8xx_copro_cmd_swap(ft8xx); if (process_touch) { - int tag = ft8xx_get_touch_tag(); + int tag = ft8xx_get_touch_tag(ft8xx); if (tag == TAG_PLUS) { val++; diff --git a/samples/drivers/rtc/README.rst b/samples/drivers/rtc/README.rst index 726771535c889..4b9e30ed86912 100644 --- a/samples/drivers/rtc/README.rst +++ b/samples/drivers/rtc/README.rst @@ -27,8 +27,7 @@ Sample Output .. code-block:: console - RTC date and time: 2024-11-17 04:21:47 - RTC date and time: 2024-11-17 04:21:48 - RTC date and time: 2024-11-17 04:21:49 + RTC date and time: 2024-11-17 04:19:00 + RTC date and time: 2024-11-17 04:19:01 diff --git a/samples/drivers/rtc/sample.yaml b/samples/drivers/rtc/sample.yaml index 10f0a08c46367..b7dbd755a7e78 100644 --- a/samples/drivers/rtc/sample.yaml +++ b/samples/drivers/rtc/sample.yaml @@ -4,9 +4,16 @@ tests: sample.drivers.rtc: platform_allow: - stm32f3_disco + integration_platforms: + - stm32f3_disco tags: - samples - rtc - api depends_on: - rtc + harness: console + harness_config: + type: one_line + regex: + - "RTC date and time: 2024-11-17 04:19:01" diff --git a/samples/drivers/spi_flash/boards/adafruit_feather_nrf52840_sense.conf b/samples/drivers/spi_flash/boards/adafruit_feather_nrf52840_sense.conf deleted file mode 100644 index d9add33645a0c..0000000000000 --- a/samples/drivers/spi_flash/boards/adafruit_feather_nrf52840_sense.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2020 Teslabs Engineering S.L. -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_NORDIC_QSPI_NOR=y diff --git a/samples/drivers/spi_flash/boards/em_starterkit_emsk_em9d.conf b/samples/drivers/spi_flash/boards/em_starterkit_emsk_em9d.conf deleted file mode 100644 index 4e3bfcd17d5b1..0000000000000 --- a/samples/drivers/spi_flash/boards/em_starterkit_emsk_em9d.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023 Synopsys. -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_SPI_NOR=y diff --git a/samples/drivers/spi_flash/boards/emsdp_emsdp_em11d.conf b/samples/drivers/spi_flash/boards/emsdp_emsdp_em11d.conf deleted file mode 100644 index 4e3bfcd17d5b1..0000000000000 --- a/samples/drivers/spi_flash/boards/emsdp_emsdp_em11d.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023 Synopsys. -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_SPI_NOR=y diff --git a/samples/drivers/spi_flash/boards/max32655evkit_max32655_m4.conf b/samples/drivers/spi_flash/boards/max32655evkit_max32655_m4.conf new file mode 100644 index 0000000000000..e8a061fe07756 --- /dev/null +++ b/samples/drivers/spi_flash/boards/max32655evkit_max32655_m4.conf @@ -0,0 +1,7 @@ +# +# Copyright (c) 2025 Analog Devices, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SPI_MAX32_INTERRUPT=y diff --git a/samples/drivers/spi_flash/boards/mec172xevb_assy6906.conf b/samples/drivers/spi_flash/boards/mec172xevb_assy6906.conf deleted file mode 100644 index 38f06a0c0f85c..0000000000000 --- a/samples/drivers/spi_flash/boards/mec172xevb_assy6906.conf +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2022 Microchip Technology Inc. -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_SPI_NOR=y diff --git a/samples/drivers/spi_flash/boards/nrf52840_mdk.conf b/samples/drivers/spi_flash/boards/nrf52840_mdk.conf deleted file mode 100644 index c17e6e08b3927..0000000000000 --- a/samples/drivers/spi_flash/boards/nrf52840_mdk.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2020 Stephane D'Alu -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_SPI=n -CONFIG_NORDIC_QSPI_NOR=y diff --git a/samples/drivers/spi_flash/boards/nrf52840dk_nrf52840.conf b/samples/drivers/spi_flash/boards/nrf52840dk_nrf52840.conf deleted file mode 100644 index c483efdb826f6..0000000000000 --- a/samples/drivers/spi_flash/boards/nrf52840dk_nrf52840.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2019 Peter Bigot Consulting, LLC -# Copyright (c) 2019 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_NORDIC_QSPI_NOR=y diff --git a/samples/drivers/spi_flash/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/drivers/spi_flash/boards/nrf5340dk_nrf5340_cpuapp.conf deleted file mode 100644 index 10239a8fd1bd1..0000000000000 --- a/samples/drivers/spi_flash/boards/nrf5340dk_nrf5340_cpuapp.conf +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2020 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# - -CONFIG_SPI=n -CONFIG_NORDIC_QSPI_NOR=y diff --git a/samples/drivers/spi_flash/boards/stm32h735g_disco.conf b/samples/drivers/spi_flash/boards/stm32h735g_disco.conf deleted file mode 100644 index d073f9492d822..0000000000000 --- a/samples/drivers/spi_flash/boards/stm32h735g_disco.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SPI=n diff --git a/samples/drivers/spi_flash/boards/stm32h7b3i_dk.conf b/samples/drivers/spi_flash/boards/stm32h7b3i_dk.conf deleted file mode 100644 index d073f9492d822..0000000000000 --- a/samples/drivers/spi_flash/boards/stm32h7b3i_dk.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_SPI=n diff --git a/samples/drivers/spi_flash/prj.conf b/samples/drivers/spi_flash/prj.conf index c5beb21553af4..d78e334e0fb62 100644 --- a/samples/drivers/spi_flash/prj.conf +++ b/samples/drivers/spi_flash/prj.conf @@ -1,3 +1,2 @@ CONFIG_STDOUT_CONSOLE=y CONFIG_FLASH=y -CONFIG_SPI=y diff --git a/samples/drivers/stepper/index.rst b/samples/drivers/stepper/index.rst new file mode 100644 index 0000000000000..7592d15577ca9 --- /dev/null +++ b/samples/drivers/stepper/index.rst @@ -0,0 +1,5 @@ +.. zephyr:code-sample-category:: stepper + :name: Stepper + :show-listing: + + These samples demonstrate how to use the :ref:`stepper ` driver API. diff --git a/samples/drivers/stepper/tmc50xx/CMakeLists.txt b/samples/drivers/stepper/tmc50xx/CMakeLists.txt new file mode 100644 index 0000000000000..7d5a7d600f21b --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/CMakeLists.txt @@ -0,0 +1,10 @@ + # SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + # SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(tmc50xx) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/drivers/stepper/tmc50xx/Kconfig b/samples/drivers/stepper/tmc50xx/Kconfig new file mode 100644 index 0000000000000..59e2cc9f8d66e --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/Kconfig @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "TMC50XX sample application" + +config STEPS_PER_REV + int "Steps per revolution" + default 200 + +config PING_PONG_N_REV + int "Change direction every N revolutions" + default 1 + +config MAX_VELOCITY_MULTIPLIER + int "Max velocity multiplier" + default 1 + +source "Kconfig.zephyr" diff --git a/samples/drivers/stepper/tmc50xx/README.rst b/samples/drivers/stepper/tmc50xx/README.rst new file mode 100644 index 0000000000000..17191c3f3741e --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/README.rst @@ -0,0 +1,49 @@ +.. zephyr:code-sample:: tmc50xx + :name: TMC50XX stepper + :relevant-api: stepper_interface + + + Rotate a TMC50XX stepper motor and change velocity at runtime. + +Description +*********** + +This sample application periodically spins the stepper clockwise and counterclockwise depending on +the :kconfig:option:`CONFIG_PING_PONG_N_REV` configuration. + +References +********** + + - TMC5041: https://www.analog.com/media/en/technical-documentation/data-sheets/TMC5041_datasheet_rev1.16.pdf + - TMC5072: https://www.analog.com/media/en/technical-documentation/data-sheets/TMC5072_datasheet_rev1.26.pdf + +Wiring +******* + +This sample uses the TMC5072 BOB controlled using the SPI interface. The board's Devicetree must define +a ``stepper`` alias for the stepper motor node. + +Building and Running +******************** + +This project spins the stepper and outputs the events to the console. It requires an TMC50XX stepper +driver. It should work with any platform featuring a SPI peripheral interface. +It does not work on QEMU. + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/stepper/tmc50xx + :board: nucleo_g071rb + :goals: build flash + +Sample Output +============= + +.. code-block:: console + + Starting tmc50xx stepper sample + stepper is 0x8007240, name is tmc_stepper@0 + stepper_callback steps completed changing direction + stepper_callback steps completed changing direction + stepper_callback steps completed changing direction + + diff --git a/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay b/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay new file mode 100644 index 0000000000000..e3b70a3553140 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay @@ -0,0 +1,52 @@ +/ { + aliases { + stepper = &tmc_stepper; + }; +}; + +&spi1 { + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; + status = "okay"; + tmc50xx: tmc50xx@0 { + compatible = "adi,tmc50xx"; + reg = <0>; + spi-max-frequency = ; /* Maximum SPI bus frequency */ + + #address-cells = <1>; + #size-cells = <0>; + + clock-frequency = ; /* Internal/External Clock frequency */ + + tmc_stepper: tmc_stepper@0 { + status = "okay"; + reg = <0>; + + /* common stepper controller settings */ + micro-step-res = <256>; + + /* ADI TMC stallguard settings specific to TMC50XX */ + activate-stallguard2; + stallguard-velocity-check-interval-ms=<1000>; + stallguard2-threshold=<30>; + stallguard-threshold-velocity=<200000>; + + /* ADI TMC ramp generator as well as current settings */ + vstart = <1000>; + vstop = <10>; + a1 = <10000>; + v1 = <50000>; + d1 = <14000>; + vmax = <900000>; + amax = <50000>; + dmax = <7000>; + tzerowait = <100>; + vhigh = <900000>; + vcoolthrs = <900000>; + ihold = <1>; + irun = <10>; + iholddelay = <1>; + }; + }; +}; diff --git a/samples/drivers/stepper/tmc50xx/prj.conf b/samples/drivers/stepper/tmc50xx/prj.conf new file mode 100644 index 0000000000000..f17d0707cf5d4 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/prj.conf @@ -0,0 +1,2 @@ +CONFIG_STEPPER=y +CONFIG_LOG=y diff --git a/samples/drivers/stepper/tmc50xx/sample.yaml b/samples/drivers/stepper/tmc50xx/sample.yaml new file mode 100644 index 0000000000000..fd600756c0d58 --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/sample.yaml @@ -0,0 +1,8 @@ +sample: + name: TMC50XX Stepper Sample +tests: + sample.stepper.tmc50xx: + harness: stepper + tags: stepper + platform_allow: nucleo_g071rb + depends_on: spi diff --git a/samples/drivers/stepper/tmc50xx/src/main.c b/samples/drivers/stepper/tmc50xx/src/main.c new file mode 100644 index 0000000000000..b5cb96632a1ab --- /dev/null +++ b/samples/drivers/stepper/tmc50xx/src/main.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +const struct device *stepper = DEVICE_DT_GET(DT_ALIAS(stepper)); + +int32_t ping_pong_target_position = CONFIG_STEPS_PER_REV * CONFIG_PING_PONG_N_REV * + DT_PROP(DT_ALIAS(stepper), micro_step_res); + +K_SEM_DEFINE(steps_completed_sem, 0, 1); + +void stepper_callback(const struct device *dev, const enum stepper_event event, void *user_data) +{ + switch (event) { + case STEPPER_EVENT_STEPS_COMPLETED: + k_sem_give(&steps_completed_sem); + break; + default: + break; + } +} + +int main(void) +{ + printf("Starting tmc50xx stepper sample\n"); + if (!device_is_ready(stepper)) { + printf("Device %s is not ready\n", stepper->name); + return -ENODEV; + } + printf("stepper is %p, name is %s\n", stepper, stepper->name); + + stepper_set_event_callback(stepper, stepper_callback, NULL); + stepper_enable(stepper, true); + stepper_set_reference_position(stepper, 0); + stepper_move_by(stepper, ping_pong_target_position); + + /* Change Max Velocity during runtime */ + int32_t tmc_velocity = DT_PROP(DT_ALIAS(stepper), vmax) * CONFIG_MAX_VELOCITY_MULTIPLIER; + (void)tmc50xx_stepper_set_max_velocity(stepper, tmc_velocity); + + for (;;) { + if (k_sem_take(&steps_completed_sem, K_FOREVER) == 0) { + ping_pong_target_position *= -1; + stepper_move_by(stepper, ping_pong_target_position); + } + } + return 0; +} diff --git a/samples/drivers/video/capture/Kconfig b/samples/drivers/video/capture/Kconfig index 5ec77c553e198..ee63ebbbb73ff 100644 --- a/samples/drivers/video/capture/Kconfig +++ b/samples/drivers/video/capture/Kconfig @@ -22,6 +22,11 @@ config VIDEO_PIXEL_FORMAT help Pixel format of the video frame. If not set, the default pixel format is used. +config VIDEO_CTRL_HFLIP + bool "Mirror the video frame horizontally" + help + If set, mirror the video frame horizontally + endmenu source "Kconfig.zephyr" diff --git a/samples/drivers/video/capture/boards/esp32s3_eye_procpu.conf b/samples/drivers/video/capture/boards/esp32s3_eye_procpu.conf index 76321800fa069..24a8455c94ba4 100644 --- a/samples/drivers/video/capture/boards/esp32s3_eye_procpu.conf +++ b/samples/drivers/video/capture/boards/esp32s3_eye_procpu.conf @@ -9,3 +9,4 @@ CONFIG_VIDEO_BUFFER_SMH_ATTRIBUTE=2 CONFIG_VIDEO_FRAME_HEIGHT=240 CONFIG_VIDEO_FRAME_WIDTH=240 CONFIG_VIDEO_PIXEL_FORMAT="RGBP" +CONFIG_ST7789V_BGR565=y diff --git a/samples/drivers/video/capture/boards/mimxrt1060_evk_mimxrt1062_qspi_B.conf b/samples/drivers/video/capture/boards/mimxrt1060_evk_mimxrt1062_qspi_B.conf new file mode 100644 index 0000000000000..6c888f960c596 --- /dev/null +++ b/samples/drivers/video/capture/boards/mimxrt1060_evk_mimxrt1062_qspi_B.conf @@ -0,0 +1,2 @@ +# Mirror video images horizontally +CONFIG_VIDEO_CTRL_HFLIP=y diff --git a/samples/drivers/video/capture/boards/mimxrt1060_evkb.conf b/samples/drivers/video/capture/boards/mimxrt1060_evkb.conf deleted file mode 100644 index 55ff96ee215a5..0000000000000 --- a/samples/drivers/video/capture/boards/mimxrt1060_evkb.conf +++ /dev/null @@ -1,4 +0,0 @@ -# Leverage PXP to mirror image by flipping -CONFIG_DMA=y -CONFIG_MCUX_ELCDIF_PXP=y -CONFIG_MCUX_ELCDIF_PXP_FLIP_HORIZONTAL=y diff --git a/samples/drivers/video/capture/boards/mimxrt1064_evk.conf b/samples/drivers/video/capture/boards/mimxrt1064_evk.conf index 55ff96ee215a5..6c888f960c596 100644 --- a/samples/drivers/video/capture/boards/mimxrt1064_evk.conf +++ b/samples/drivers/video/capture/boards/mimxrt1064_evk.conf @@ -1,4 +1,2 @@ -# Leverage PXP to mirror image by flipping -CONFIG_DMA=y -CONFIG_MCUX_ELCDIF_PXP=y -CONFIG_MCUX_ELCDIF_PXP_FLIP_HORIZONTAL=y +# Mirror video images horizontally +CONFIG_VIDEO_CTRL_HFLIP=y diff --git a/samples/drivers/video/capture/src/main.c b/samples/drivers/video/capture/src/main.c index 1d21b4fe8b85e..59f200b94d8d0 100644 --- a/samples/drivers/video/capture/src/main.c +++ b/samples/drivers/video/capture/src/main.c @@ -9,13 +9,12 @@ #include #include +#include #include LOG_MODULE_REGISTER(main); #ifdef CONFIG_TEST -#include - #include "check_test_pattern.h" #define LOG_LEVEL LOG_LEVEL_DBG @@ -145,9 +144,7 @@ int main(void) #endif if (strcmp(CONFIG_VIDEO_PIXEL_FORMAT, "")) { - fmt.pixelformat = - video_fourcc(CONFIG_VIDEO_PIXEL_FORMAT[0], CONFIG_VIDEO_PIXEL_FORMAT[1], - CONFIG_VIDEO_PIXEL_FORMAT[2], CONFIG_VIDEO_PIXEL_FORMAT[3]); + fmt.pixelformat = VIDEO_FOURCC_FROM_STR(CONFIG_VIDEO_PIXEL_FORMAT); } LOG_INF("- Video format: %c%c%c%c %ux%u", (char)fmt.pixelformat, @@ -179,6 +176,11 @@ int main(void) fie.index++; } + /* Set controls */ + if (IS_ENABLED(CONFIG_VIDEO_CTRL_HFLIP)) { + video_set_ctrl(video_dev, VIDEO_CID_HFLIP, (void *)1); + } + #ifdef CONFIG_TEST video_set_ctrl(video_dev, VIDEO_CID_TEST_PATTERN, (void *)1); #endif @@ -211,7 +213,8 @@ int main(void) * For some hardwares, such as the PxP used on i.MX RT1170 to do image rotation, * buffer alignment is needed in order to achieve the best performance */ - buffers[i] = video_buffer_aligned_alloc(bsize, CONFIG_VIDEO_BUFFER_POOL_ALIGN); + buffers[i] = video_buffer_aligned_alloc(bsize, CONFIG_VIDEO_BUFFER_POOL_ALIGN, + K_FOREVER); if (buffers[i] == NULL) { LOG_ERR("Unable to alloc video buffer"); return 0; diff --git a/samples/drivers/video/capture_to_lvgl/boards/stm32h7b3i_dk.conf b/samples/drivers/video/capture_to_lvgl/boards/stm32h7b3i_dk.conf new file mode 100644 index 0000000000000..bb4f8b12a920a --- /dev/null +++ b/samples/drivers/video/capture_to_lvgl/boards/stm32h7b3i_dk.conf @@ -0,0 +1,11 @@ +# +# Copyright (c) 2025 Charles Dias +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_LOG_BUFFER_SIZE=2048 + +CONFIG_VIDEO_WIDTH=480 +CONFIG_VIDEO_HEIGHT=272 +CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=262144 diff --git a/samples/drivers/video/capture_to_lvgl/boards/stm32h7b3i_dk.overlay b/samples/drivers/video/capture_to_lvgl/boards/stm32h7b3i_dk.overlay new file mode 100644 index 0000000000000..b9e8ba05e9456 --- /dev/null +++ b/samples/drivers/video/capture_to_lvgl/boards/stm32h7b3i_dk.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2025 Charles Dias + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/delete-node/ &sram1; +/delete-node/ &sram2; + +/* Increase the SRAM0 bank memory size to accommodate the VIDEO_BUFFER_POOL_SZ_MAX configuration. */ +&sram0 { + reg = <0x24000000 DT_SIZE_K(1024)>; +}; diff --git a/samples/drivers/video/capture_to_lvgl/prj.conf b/samples/drivers/video/capture_to_lvgl/prj.conf index bd8407787cfd2..4a64bbaad53da 100644 --- a/samples/drivers/video/capture_to_lvgl/prj.conf +++ b/samples/drivers/video/capture_to_lvgl/prj.conf @@ -11,7 +11,6 @@ CONFIG_DISPLAY_LOG_LEVEL_ERR=y CONFIG_LVGL=y CONFIG_LV_CONF_MINIMAL=y -CONFIG_LV_MEM_CUSTOM=y -CONFIG_LV_USE_IMG=y +CONFIG_LV_USE_IMAGE=y CONFIG_LV_Z_MEM_POOL_SIZE=16384 CONFIG_LV_USE_PERF_MONITOR=y diff --git a/samples/drivers/video/capture_to_lvgl/src/main.c b/samples/drivers/video/capture_to_lvgl/src/main.c index 0d0a07e0d553c..ab57c9a52a5ef 100644 --- a/samples/drivers/video/capture_to_lvgl/src/main.c +++ b/samples/drivers/video/capture_to_lvgl/src/main.c @@ -97,7 +97,7 @@ int main(void) /* Alloc video buffers and enqueue for capture */ for (i = 0; i < ARRAY_SIZE(buffers); i++) { - buffers[i] = video_buffer_alloc(bsize); + buffers[i] = video_buffer_alloc(bsize, K_FOREVER); if (buffers[i] == NULL) { LOG_ERR("Unable to alloc video buffer"); return 0; @@ -131,11 +131,10 @@ int main(void) display_blanking_off(display_dev); const lv_img_dsc_t video_img = { - .header.always_zero = 0, .header.w = CONFIG_VIDEO_WIDTH, .header.h = CONFIG_VIDEO_HEIGHT, .data_size = CONFIG_VIDEO_WIDTH * CONFIG_VIDEO_HEIGHT * sizeof(lv_color_t), - .header.cf = LV_IMG_CF_TRUE_COLOR, + .header.cf = LV_COLOR_FORMAT_NATIVE, .data = (const uint8_t *)buffers[0]->buffer, }; diff --git a/samples/drivers/video/tcpserversink/src/main.c b/samples/drivers/video/tcpserversink/src/main.c index 9918654519885..af728d85887ba 100644 --- a/samples/drivers/video/tcpserversink/src/main.c +++ b/samples/drivers/video/tcpserversink/src/main.c @@ -105,7 +105,7 @@ int main(void) /* Alloc Buffers */ for (i = 0; i < ARRAY_SIZE(buffers); i++) { - buffers[i] = video_buffer_alloc(fmt.pitch * fmt.height); + buffers[i] = video_buffer_alloc(fmt.pitch * fmt.height, K_FOREVER); if (buffers[i] == NULL) { LOG_ERR("Unable to alloc video buffer"); return 0; diff --git a/samples/drivers/w1/scanner/boards/max32655evkit_max32655_m4.overlay b/samples/drivers/w1/scanner/boards/max32655evkit_max32655_m4.overlay new file mode 100644 index 0000000000000..b39b6bfd394d3 --- /dev/null +++ b/samples/drivers/w1/scanner/boards/max32655evkit_max32655_m4.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&owm_io_p0_6 { + power-source=; +}; + +&owm_pe_p0_7 { + power-source=; +}; + +&w1 { + status = "okay"; + internal-pullup = <1>; + external-pullup = <0>; +}; diff --git a/samples/drivers/w1/scanner/boards/max32666evkit_max32666_cpu0.overlay b/samples/drivers/w1/scanner/boards/max32666evkit_max32666_cpu0.overlay new file mode 100644 index 0000000000000..eee8e0fc933f4 --- /dev/null +++ b/samples/drivers/w1/scanner/boards/max32666evkit_max32666_cpu0.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&owm_io_p0_4 { + power-source=; +}; + +&owm_pe_p0_5 { + power-source=; +}; + +&w1 { + status = "okay"; + internal-pullup = <1>; + external-pullup = <0>; +}; diff --git a/samples/drivers/w1/scanner/boards/max32666fthr_max32666_cpu0.overlay b/samples/drivers/w1/scanner/boards/max32666fthr_max32666_cpu0.overlay new file mode 100644 index 0000000000000..9060237897645 --- /dev/null +++ b/samples/drivers/w1/scanner/boards/max32666fthr_max32666_cpu0.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&owm_io_p0_12 { + power-source=; +}; + +&owm_pe_p0_13 { + power-source=; +}; + +&w1 { + status = "okay"; + internal-pullup = <1>; + external-pullup = <0>; +}; diff --git a/samples/drivers/w1/scanner/boards/max32690evkit_max32690_m4.overlay b/samples/drivers/w1/scanner/boards/max32690evkit_max32690_m4.overlay new file mode 100644 index 0000000000000..31b91be77b7f1 --- /dev/null +++ b/samples/drivers/w1/scanner/boards/max32690evkit_max32690_m4.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&owm_io_p0_8 { + power-source=; +}; + +&owm_pe_p0_7 { + power-source=; +}; + +&w1 { + status = "okay"; + internal-pullup = <1>; + external-pullup = <0>; +}; diff --git a/samples/drivers/w1/scanner/boards/max78000evkit_max78000_m4.overlay b/samples/drivers/w1/scanner/boards/max78000evkit_max78000_m4.overlay new file mode 100644 index 0000000000000..933dd2f3de9f3 --- /dev/null +++ b/samples/drivers/w1/scanner/boards/max78000evkit_max78000_m4.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&owm_io_p0_18 { + power-source=; +}; + +&owm_pe_p0_19 { + power-source=; +}; + +&w1 { + status = "okay"; + internal-pullup = <1>; + external-pullup = <0>; +}; diff --git a/samples/drivers/w1/scanner/boards/max78000fthr_max78000_m4.overlay b/samples/drivers/w1/scanner/boards/max78000fthr_max78000_m4.overlay new file mode 100644 index 0000000000000..933dd2f3de9f3 --- /dev/null +++ b/samples/drivers/w1/scanner/boards/max78000fthr_max78000_m4.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&owm_io_p0_18 { + power-source=; +}; + +&owm_pe_p0_19 { + power-source=; +}; + +&w1 { + status = "okay"; + internal-pullup = <1>; + external-pullup = <0>; +}; diff --git a/samples/drivers/w1/scanner/boards/max78002evkit_max78002_m4.overlay b/samples/drivers/w1/scanner/boards/max78002evkit_max78002_m4.overlay new file mode 100644 index 0000000000000..b39b6bfd394d3 --- /dev/null +++ b/samples/drivers/w1/scanner/boards/max78002evkit_max78002_m4.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&owm_io_p0_6 { + power-source=; +}; + +&owm_pe_p0_7 { + power-source=; +}; + +&w1 { + status = "okay"; + internal-pullup = <1>; + external-pullup = <0>; +}; diff --git a/samples/drivers/w1/scanner/sample.yaml b/samples/drivers/w1/scanner/sample.yaml index 9a610bf63f12d..776eb3babb568 100644 --- a/samples/drivers/w1/scanner/sample.yaml +++ b/samples/drivers/w1/scanner/sample.yaml @@ -3,6 +3,8 @@ sample: common: harness: console + tags: + - w1 tests: sample.drivers.w1.scanner.ds2482-800: @@ -25,7 +27,7 @@ tests: regex: - "Number of devices found on bus: .*" fixture: w1_scanner_ds2484 - samples.drivers.w1.scanner.ds2485: + sample.drivers.w1.scanner.ds2485: depends_on: arduino_i2c extra_args: DTC_OVERLAY_FILE=ds2485.overlay platform_allow: @@ -36,7 +38,7 @@ tests: regex: - "Number of devices found on bus: .*" fixture: w1_scanner_ds2485 - samples.drivers.w1.scanner.w1_serial: + sample.drivers.w1.scanner.w1_serial: depends_on: - arduino_serial extra_args: DTC_OVERLAY_FILE=w1_serial.overlay @@ -48,3 +50,20 @@ tests: regex: - "Number of devices found on bus: .*" fixture: w1_scanner_w1_serial + sample.drivers.w1.scanner.max: + depends_on: w1 + platform_allow: + - max32655evkit/max32655/m4 + - max32666evkit/max32666/cpu0 + - max32666fthr/max32666/cpu0 + - max32690evkit/max32690/m4 + - max78000evkit/max78000/m4 + - max78000fthr/max78000/m4 + - max78002evkit/max78002/m4 + integration_platforms: + - max32655evkit/max32655/m4 + harness_config: + type: one_line + regex: + - "Number of devices found on bus: .*" + fixture: w1_scanner_w1_max diff --git a/samples/drivers/watchdog/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay b/samples/drivers/watchdog/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay new file mode 100644 index 0000000000000..5c765a8a89633 --- /dev/null +++ b/samples/drivers/watchdog/boards/nrf54l20pdk_nrf54l20_cpuapp.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt31 { + status = "okay"; +}; diff --git a/samples/drivers/watchdog/sample.yaml b/samples/drivers/watchdog/sample.yaml index ce97a6f921319..504c952105316 100644 --- a/samples/drivers/watchdog/sample.yaml +++ b/samples/drivers/watchdog/sample.yaml @@ -22,6 +22,9 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - panb511evb/nrf54l15/cpuapp + - panb511evb/nrf54l15/cpuflpr + - panb511evb/nrf54l15/cpuflpr/xip sample.drivers.watchdog.stm32_wwdg: extra_args: DTC_OVERLAY_FILE=boards/stm32_wwdg.overlay filter: dt_compat_enabled("st,stm32-window-watchdog") diff --git a/samples/modules/lvgl/accelerometer_chart/src/main.c b/samples/modules/lvgl/accelerometer_chart/src/main.c index 937f4690e79fe..cf727fa121fb9 100644 --- a/samples/modules/lvgl/accelerometer_chart/src/main.c +++ b/samples/modules/lvgl/accelerometer_chart/src/main.c @@ -62,7 +62,7 @@ static void create_accelerometer_chart(lv_obj_t *parent) lv_chart_set_point_count(chart1, CONFIG_SAMPLE_CHART_POINTS_PER_SERIES); /* Do not display point markers on the data */ - lv_obj_set_style_size(chart1, 0, LV_PART_INDICATOR); + lv_obj_set_style_size(chart1, 0, 0, LV_PART_INDICATOR); } int main(void) @@ -81,15 +81,15 @@ int main(void) return -ENODEV; } - create_accelerometer_chart(lv_scr_act()); + create_accelerometer_chart(lv_screen_active()); sensor_timer = lv_timer_create(sensor_timer_cb, 1000 / CONFIG_SAMPLE_ACCEL_SAMPLING_RATE, NULL); - lv_task_handler(); + lv_timer_handler(); display_blanking_off(display_dev); while (1) { - uint32_t sleep_ms = lv_task_handler(); + uint32_t sleep_ms = lv_timer_handler(); k_msleep(MIN(sleep_ms, INT32_MAX)); } diff --git a/samples/modules/lvgl/demos/CMakeLists.txt b/samples/modules/lvgl/demos/CMakeLists.txt index c80e3b4364b19..03ff9716abf23 100644 --- a/samples/modules/lvgl/demos/CMakeLists.txt +++ b/samples/modules/lvgl/demos/CMakeLists.txt @@ -66,16 +66,13 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_MUSIC app PRIVATE ) target_sources_ifdef(CONFIG_LV_USE_DEMO_BENCHMARK app PRIVATE + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_avatar.c + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_lvgl_logo_argb.c + ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_lvgl_logo_rgb.c + ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_12_compr_az.c.c + ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_16_compr_az.c.c + ${LVGL_DIR}/demos/benchmark/assets/lv_font_benchmark_montserrat_28_compr_az.c.c ${LVGL_DIR}/demos/benchmark/lv_demo_benchmark.c - ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_indexed16.c - ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_28_compr_az.c.c - ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_16_compr_az.c.c - ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_argb.c - ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_alpha16.c - ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_rgb.c - ${LVGL_DIR}/demos/benchmark/assets/lv_font_bechmark_montserrat_12_compr_az.c.c - ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_chroma_keyed.c - ${LVGL_DIR}/demos/benchmark/assets/img_benchmark_cogwheel_rgb565a8.c ) target_sources_ifdef(CONFIG_LV_USE_DEMO_STRESS app PRIVATE @@ -85,6 +82,76 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_STRESS app PRIVATE target_sources_ifdef(CONFIG_LV_USE_DEMO_WIDGETS app PRIVATE ${LVGL_DIR}/demos/widgets/assets/img_clothes.c ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_avatar.c + ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_needle.c ${LVGL_DIR}/demos/widgets/assets/img_lvgl_logo.c ${LVGL_DIR}/demos/widgets/lv_demo_widgets.c ) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_FLEX_LAYOUT app PRIVATE + ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_main.c + ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_view.c + ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_flex_loader.c + ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_view_child_node.c + ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_view_ctrl_pad.c + ${LVGL_DIR}/demos/flex_layout/lv_demo_flex_layout_ctrl_pad.c +) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER app PRIVATE + ${LVGL_DIR}/demos/keypad_encoder/lv_demo_keypad_encoder.c +) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_RENDER app PRIVATE + ${LVGL_DIR}/demos/render/assets/img_render_arc_bg.c + ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_argb8888.c + ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_i1.c + ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_l8.c + ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_rgb565.c + ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_rgb565a8.c + ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_rgb888.c + ${LVGL_DIR}/demos/render/assets/img_render_lvgl_logo_xrgb8888.c + ${LVGL_DIR}/demos/render/lv_demo_render.c +) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_SCROLL app PRIVATE + ${LVGL_DIR}/demos/scroll/lv_demo_scroll.c +) + +target_sources_ifdef(CONFIG_LV_USE_DEMO_MULTILANG app PRIVATE + ${LVGL_DIR}/demos/multilang/assets/img_multilang_like.c + ${LVGL_DIR}/demos/multilang/assets/fonts/font_multilang_large.c + ${LVGL_DIR}/demos/multilang/assets/fonts/font_multilang_small.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_movie_camera.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_flexed_biceps.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_rocket.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_artist_palette.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_deciduous_tree.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_cat_face.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_red_heart.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_camera_with_flash.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_dog_face.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_books.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_earth_globe_europe_africa.c + ${LVGL_DIR}/demos/multilang/assets/emojis/img_emoji_soccer_ball.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_19.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_4.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_8.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_5.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_16.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_22.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_9.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_6.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_18.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_17.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_13.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_2.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_3.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_25.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_14.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_1.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_11.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_7.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_15.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_12.c + ${LVGL_DIR}/demos/multilang/assets/avatars/img_multilang_avatar_10.c + ${LVGL_DIR}/demos/multilang/lv_demo_multilang.c +) diff --git a/samples/modules/lvgl/demos/Kconfig b/samples/modules/lvgl/demos/Kconfig index 6f61694f65181..39d2cb104f5af 100644 --- a/samples/modules/lvgl/demos/Kconfig +++ b/samples/modules/lvgl/demos/Kconfig @@ -16,6 +16,7 @@ config LV_Z_DEMO_MUSIC config LV_Z_DEMO_BENCHMARK bool "LVGL benchmark demo" select LV_USE_DEMO_BENCHMARK + select LV_USE_DEMO_WIDGETS help Build benchmarking demo application. @@ -29,8 +30,59 @@ config LV_Z_DEMO_WIDGETS bool "LVGL widgets demo" select LV_USE_DEMO_WIDGETS help - Build stress testing demo application. + Build widgets demo application. + +config LV_Z_DEMO_FLEX_LAYOUT + bool "LVGL flex layout demo" + select LV_USE_DEMO_FLEX_LAYOUT + help + Build flex layout demo application. + +config LV_Z_DEMO_KEYPAD_AND_ENCODER + bool "LVGL keypad and encoder demo" + select LV_USE_DEMO_KEYPAD_AND_ENCODER + help + Build keypad and encoder demo application. + +config LV_Z_DEMO_RENDER + bool "LVGL render demo" + select LV_USE_DEMO_RENDER + help + Build render demo application. + +config LV_Z_DEMO_SCROLL + bool "LVGL scroll demo" + select LV_USE_DEMO_SCROLL + help + Build scroll demo application. + +config LV_Z_DEMO_MULTILANG + bool "LVGL multilang demo" + select LV_USE_DEMO_MULTILANG + select LV_USE_IMGFONT + help + Build multilang demo application. endchoice +config LV_Z_DEMO_RENDER_SCENE_DYNAMIC + bool "Switch scenes dynamically" + help + Switch between scenes to render dynamically. + +config LV_Z_DEMO_RENDER_SCENE_INDEX + int "Index of the rendered scene" + depends on !LV_Z_DEMO_RENDER_SCENE_DYNAMIC + default 0 + range 0 11 + help + Render scene by its index (refer to lv_demo_render.h) + +config LV_Z_DEMO_RENDER_DYNAMIC_SCENE_TIMEOUT + int "Seconds each rendered scene is shown" + depends on LV_Z_DEMO_RENDER_SCENE_DYNAMIC + default 3 + help + Seconds each rendered scenar is shown + source "Kconfig.zephyr" diff --git a/samples/modules/lvgl/demos/README.rst b/samples/modules/lvgl/demos/README.rst index 8c85495342b02..7124c17a7673a 100644 --- a/samples/modules/lvgl/demos/README.rst +++ b/samples/modules/lvgl/demos/README.rst @@ -17,6 +17,16 @@ A sample showcasing upstream LVGL demos. A stress test for LVGL. It contains a lot of object creation, deletion, animations, styles usage, and so on. It can be used if there is any memory corruption during heavy usage or any memory leaks. * Widgets Shows how the widgets look like out of the box using the built-in material theme. +* Flex Layout + Showcases the use of the flex layout. +* Keypad and Encoder + Shows how to control widget with a keypad and hardware encoder. +* Render + Collection of multiple rendering tests. +* Scroll + Shows the scroll behaviour of a panel with a large list. +* Multilang + Shows a UI with multilanguage options, supporting unicode characters. More details can be found in `LVGL demos Readme`_. @@ -72,6 +82,46 @@ These demos can be built for simulated display environment as follows: :goals: run :compact: +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_sim + :gen-args: -DCONFIG_LV_Z_DEMO_FLEX_LAYOUT=y + :goals: run + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_sim + :gen-args: -DCONFIG_LV_Z_DEMO_KEYPAD_AND_ENCODER=y + :goals: run + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_sim + :gen-args: -DCONFIG_LV_Z_DEMO_RENDER=y + :goals: run + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_sim + :gen-args: -DCONFIG_LV_Z_DEMO_SCROLL=y + :goals: run + :compact: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/lvgl/demos + :host-os: unix + :board: native_sim + :gen-args: -DCONFIG_LV_Z_DEMO_MULTILANG=y + :goals: run + :compact: + Alternatively, if building from a 64-bit host machine, the previous target board argument may also be replaced by ``native_sim/native/64``. diff --git a/samples/modules/lvgl/demos/prj.conf b/samples/modules/lvgl/demos/prj.conf index 3392d5c4fd312..4b7ab1bb7dbb3 100644 --- a/samples/modules/lvgl/demos/prj.conf +++ b/samples/modules/lvgl/demos/prj.conf @@ -3,7 +3,7 @@ CONFIG_LOG=y CONFIG_SHELL=y CONFIG_LVGL=y -CONFIG_LV_Z_MEM_POOL_SIZE=49152 +CONFIG_LV_Z_MEM_POOL_SIZE=58368 CONFIG_LV_Z_SHELL=y CONFIG_LV_USE_MONKEY=y @@ -13,6 +13,8 @@ CONFIG_INPUT=y CONFIG_LV_FONT_MONTSERRAT_12=y CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_16=y +CONFIG_LV_FONT_MONTSERRAT_18=y +CONFIG_LV_FONT_MONTSERRAT_24=y # Benchmark Demo CONFIG_LV_USE_FONT_COMPRESSED=y diff --git a/samples/modules/lvgl/demos/sample.yaml b/samples/modules/lvgl/demos/sample.yaml index 40c14a0a085cb..4fdb529d9986a 100644 --- a/samples/modules/lvgl/demos/sample.yaml +++ b/samples/modules/lvgl/demos/sample.yaml @@ -27,13 +27,28 @@ tests: sample.modules.lvgl.demo_benchmark: extra_configs: - CONFIG_LV_Z_DEMO_BENCHMARK=y + - CONFIG_LV_USE_DEMO_WIDGETS=y sample.modules.lvgl.demo_stress: extra_configs: - CONFIG_LV_Z_DEMO_STRESS=y sample.modules.lvgl.demo_widgets: extra_configs: - CONFIG_LV_Z_DEMO_WIDGETS=y - + sample.modules.lvgl.demo_flex_layout: + extra_configs: + - CONFIG_LV_Z_DEMO_FLEX_LAYOUT=y + sample.modules.lvgl.demo_keypad_encoder: + extra_configs: + - CONFIG_LV_Z_DEMO_KEYPAD_AND_ENCODER=y + sample.modules.lvgl.demo_render: + extra_configs: + - CONFIG_LV_Z_DEMO_RENDER=y + sample.modules.lvgl.demo_scroll: + extra_configs: + - CONFIG_LV_Z_DEMO_SCROLL=y + sample.modules.lvgl.demo_multilang: + extra_configs: + - CONFIG_LV_Z_DEMO_MULTILANG=y sample.modules.lvgl.demos.st_b_lcd40_dsi1_mb1166: filter: dt_compat_enabled("orisetech,otm8009a") platform_allow: stm32h747i_disco/stm32h747xx/m7 @@ -68,3 +83,17 @@ tests: - shield - lvgl - gui + sample.modules.lvgl.demos.rtkmipilcdb00000be: + platform_allow: ek_ra8d1 + harness: console + harness_config: + fixture: fixture_display + extra_args: SHIELD=rtkmipilcdb00000be + modules: + - lvgl + tags: + - samples + - display + - shield + - lvgl + - gui diff --git a/samples/modules/lvgl/demos/src/main.c b/samples/modules/lvgl/demos/src/main.c index 59ed84244a848..384888aa254d2 100644 --- a/samples/modules/lvgl/demos/src/main.c +++ b/samples/modules/lvgl/demos/src/main.c @@ -18,6 +18,10 @@ LOG_MODULE_REGISTER(app); int main(void) { const struct device *display_dev; +#ifdef CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC + k_timepoint_t next_scene_switch; + lv_demo_render_scene_t cur_scene = LV_DEMO_RENDER_SCENE_FILL; +#endif /* CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC */ display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); if (!device_is_ready(display_dev)) { @@ -25,20 +29,37 @@ int main(void) return 0; } -#if defined(CONFIG_LV_USE_DEMO_MUSIC) +#if defined(CONFIG_LV_Z_DEMO_MUSIC) lv_demo_music(); -#elif defined(CONFIG_LV_USE_DEMO_BENCHMARK) +#elif defined(CONFIG_LV_Z_DEMO_BENCHMARK) lv_demo_benchmark(); -#elif defined(CONFIG_LV_USE_DEMO_STRESS) +#elif defined(CONFIG_LV_Z_DEMO_STRESS) lv_demo_stress(); -#elif defined(CONFIG_LV_USE_DEMO_WIDGETS) +#elif defined(CONFIG_LV_Z_DEMO_WIDGETS) lv_demo_widgets(); +#elif defined(CONFIG_LV_Z_DEMO_FLEX_LAYOUT) + lv_demo_flex_layout(); +#elif defined(CONFIG_LV_Z_DEMO_KEYPAD_AND_ENCODER) + lv_demo_keypad_encoder(); +#elif defined(CONFIG_LV_Z_DEMO_RENDER) + +#ifdef CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC + lv_demo_render(cur_scene, 255); + next_scene_switch = + sys_timepoint_calc(K_SECONDS(CONFIG_LV_Z_DEMO_RENDER_DYNAMIC_SCENE_TIMEOUT)); +#else + lv_demo_render(CONFIG_LV_Z_DEMO_RENDER_SCENE_INDEX, 255); +#endif /* CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC */ + +#elif defined(CONFIG_LV_Z_DEMO_SCROLL) + lv_demo_scroll(); +#elif defined(CONFIG_LV_Z_DEMO_MULTILANG) + lv_demo_multilang(); #else -#error Enable one of the demos CONFIG_LV_USE_DEMO_MUSIC, CONFIG_LV_USE_DEMO_BENCHMARK ,\ - CONFIG_LV_USE_DEMO_STRESS, or CONFIG_LV_USE_DEMO_WIDGETS +#error Enable one of the demos CONFIG_LV_Z_DEMO_* #endif - lv_task_handler(); + lv_timer_handler(); display_blanking_off(display_dev); #ifdef CONFIG_LV_Z_MEM_POOL_SYS_HEAP lvgl_print_heap_info(false); @@ -46,9 +67,17 @@ int main(void) printf("lvgl in malloc mode\n"); #endif while (1) { - uint32_t sleep_ms = lv_task_handler(); + uint32_t sleep_ms = lv_timer_handler(); k_msleep(MIN(sleep_ms, INT32_MAX)); +#ifdef CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC + if (sys_timepoint_expired(next_scene_switch)) { + cur_scene = (cur_scene + 1) % _LV_DEMO_RENDER_SCENE_NUM; + lv_demo_render(cur_scene, 255); + next_scene_switch = sys_timepoint_calc( + K_SECONDS(CONFIG_LV_Z_DEMO_RENDER_DYNAMIC_SCENE_TIMEOUT)); + } +#endif /* CONFIG_LV_Z_DEMO_RENDER_SCENE_DYNAMIC */ } return 0; diff --git a/samples/modules/lvgl/screen_transparency/prj.conf b/samples/modules/lvgl/screen_transparency/prj.conf index 7c857deba03f5..20856b0155c94 100644 --- a/samples/modules/lvgl/screen_transparency/prj.conf +++ b/samples/modules/lvgl/screen_transparency/prj.conf @@ -4,6 +4,5 @@ CONFIG_LOG=y CONFIG_LVGL=y CONFIG_LV_Z_MEM_POOL_SIZE=16384 CONFIG_LV_COLOR_DEPTH_32=y -CONFIG_LV_COLOR_SCREEN_TRANSP=y CONFIG_DISPLAY=y diff --git a/samples/modules/lvgl/screen_transparency/src/main.c b/samples/modules/lvgl/screen_transparency/src/main.c index 64494ffdaed18..16faa7a19276a 100644 --- a/samples/modules/lvgl/screen_transparency/src/main.c +++ b/samples/modules/lvgl/screen_transparency/src/main.c @@ -21,14 +21,13 @@ static void initialize_gui(void) lv_obj_t *label; /* Configure screen and background for transparency */ - lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_TRANSP, LV_PART_MAIN); - lv_disp_set_bg_opa(NULL, LV_OPA_TRANSP); - lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x000000), LV_PART_MAIN); + lv_obj_set_style_bg_opa(lv_screen_active(), LV_OPA_TRANSP, LV_PART_MAIN); + lv_obj_set_style_bg_opa(lv_layer_bottom(), LV_OPA_TRANSP, LV_PART_MAIN); /* Create a label, set its text and align it to the center */ - label = lv_label_create(lv_scr_act()); + label = lv_label_create(lv_screen_active()); lv_label_set_text(label, "Hello, world!"); - lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xff00ff), LV_PART_MAIN); + lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xff00ff), LV_PART_MAIN); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); } @@ -45,7 +44,7 @@ int main(void) } display_get_capabilities(display_dev, &display_caps); - if (!(display_caps.supported_pixel_formats | PIXEL_FORMAT_ARGB_8888)) { + if (!(display_caps.supported_pixel_formats & PIXEL_FORMAT_ARGB_8888)) { LOG_ERR("Display does not support ARGB8888 mode"); return -ENOTSUP; } @@ -60,11 +59,11 @@ int main(void) initialize_gui(); - lv_task_handler(); + lv_timer_handler(); display_blanking_off(display_dev); while (1) { - uint32_t sleep_ms = lv_task_handler(); + uint32_t sleep_ms = lv_timer_handler(); k_msleep(MIN(sleep_ms, INT32_MAX)); } diff --git a/samples/modules/mctp/mctp.rst b/samples/modules/mctp/mctp.rst new file mode 100644 index 0000000000000..6bfebf7c47440 --- /dev/null +++ b/samples/modules/mctp/mctp.rst @@ -0,0 +1,5 @@ +.. zephyr:code-sample-category:: mctp + :name: MCTP + :show-listing: + + These samples demonstrate how to build communicating firmwares using MCTP in Zephyr. diff --git a/samples/modules/mctp/mctp_endpoint/CMakeLists.txt b/samples/modules/mctp/mctp_endpoint/CMakeLists.txt new file mode 100644 index 0000000000000..e3f4e04676ad1 --- /dev/null +++ b/samples/modules/mctp/mctp_endpoint/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(mctp_endpoint) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/modules/mctp/mctp_endpoint/README.rst b/samples/modules/mctp/mctp_endpoint/README.rst new file mode 100644 index 0000000000000..6f7d7b98a5f25 --- /dev/null +++ b/samples/modules/mctp/mctp_endpoint/README.rst @@ -0,0 +1,41 @@ +.. zephyr:code-sample:: mctp_endpoint_sample + :name: MCTP Endpoint Sample + + Create an MCTP endpoint over UART. + +Overview +******** +Sets up an MCTP node that listens on a UART for messages targeting a particular +MCTP endpoint id with the message "hello". Responds to this "hello" message with +"world". + +Requirements +************ +A board and SoC that provide access to a UART and a driver that implements the +UART async API. + +Wiring +****** +The listening UART pins should be wired to a board which will run the MCTP host +sample such that this board's UART tx pin connects to the host board's rx pin, +and this board's UART rx pin connects to the host board's tx pin. The boards' +grounds should also be wired together. + +Optionally a logic analyzer can be wired up and listening to the UART to inspect +the data flowing. + +Building and Running +******************** + + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/mctp/mctp_endpoint + :host-os: unix + :board: nrf52840_nrf52840dk + :goals: run + :compact: + +References +********** + +`MCTP Base Specification 2019 `_ diff --git a/samples/modules/mctp/mctp_endpoint/boards/nrf52840dk_nrf52840.overlay b/samples/modules/mctp/mctp_endpoint/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 0000000000000..48c7f840dcab6 --- /dev/null +++ b/samples/modules/mctp/mctp_endpoint/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,3 @@ +&arduino_serial{ + status = "okay"; +}; diff --git a/samples/modules/mctp/mctp_endpoint/prj.conf b/samples/modules/mctp/mctp_endpoint/prj.conf new file mode 100644 index 0000000000000..495c9ca12fa9b --- /dev/null +++ b/samples/modules/mctp/mctp_endpoint/prj.conf @@ -0,0 +1,8 @@ +CONFIG_SERIAL=y +CONFIG_UART_ASYNC_API=y +CONFIG_MCTP=y +CONFIG_MCTP_UART=y +CONFIG_LOG=y +CONFIG_LOG_BUFFER_SIZE=4096 +CONFIG_MCTP_LOG_LEVEL_DBG=y +CONFIG_ISR_STACK_SIZE=4096 diff --git a/samples/modules/mctp/mctp_endpoint/src/main.c b/samples/modules/mctp/mctp_endpoint/src/main.c new file mode 100644 index 0000000000000..430447ad2fe46 --- /dev/null +++ b/samples/modules/mctp/mctp_endpoint/src/main.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mctp_endpoint); + +#include + +static struct mctp *mctp_ctx; + +#define LOCAL_HELLO_EID 10 + +#define REMOTE_HELLO_EID 20 + +K_SEM_DEFINE(mctp_rx, 0, 1); + +static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg, + size_t len) +{ + switch (eid) { + case REMOTE_HELLO_EID: + LOG_INF("got mctp message %s for eid %d, replying to 5 with \"world\"", (char *)msg, + eid); + mctp_message_tx(mctp_ctx, LOCAL_HELLO_EID, false, 0, "world", sizeof("world")); + break; + default: + LOG_INF("Unknown endpoint %d", eid); + break; + } + + k_sem_give(&mctp_rx); +} + +MCTP_UART_DT_DEFINE(mctp_endpoint, DEVICE_DT_GET(DT_NODELABEL(arduino_serial))); + +#define RX_BUF_SZ 128 + +int main(void) +{ + LOG_INF("MCTP Endpoint EID:%d on %s\n", LOCAL_HELLO_EID, CONFIG_BOARD_TARGET); + + mctp_set_alloc_ops(malloc, free, realloc); + mctp_ctx = mctp_init(); + __ASSERT_NO_MSG(mctp_ctx != NULL); + mctp_register_bus(mctp_ctx, &mctp_endpoint.binding, LOCAL_HELLO_EID); + mctp_set_rx_all(mctp_ctx, rx_message, NULL); + + /* MCTP poll loop */ + while (true) { + mctp_uart_start_rx(&mctp_endpoint); + k_sem_take(&mctp_rx, K_FOREVER); + } + + LOG_INF("exiting"); + return 0; +} diff --git a/samples/modules/mctp/mctp_host/CMakeLists.txt b/samples/modules/mctp/mctp_host/CMakeLists.txt new file mode 100644 index 0000000000000..4b19d992eb2b4 --- /dev/null +++ b/samples/modules/mctp/mctp_host/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(mctp_host) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/modules/mctp/mctp_host/README.rst b/samples/modules/mctp/mctp_host/README.rst new file mode 100644 index 0000000000000..d80d02d2137eb --- /dev/null +++ b/samples/modules/mctp/mctp_host/README.rst @@ -0,0 +1,40 @@ +.. zephyr:code-sample:: mctp_host_sample + :name: MCTP Host Sample + + Create an MCTP host over UART. + +Overview +******** +Sets up an MCTP node that sends a request on a UART targeting a particular MCTP +endpoint id with the message "hello". Expects and waits for a response to this +"hello" message containing "world". + +Requirements +************ +A board and SoC that provide access to a UART and a driver that implements the +UART async API. + +Wiring +****** +The UART pins should be wired to a board which will run the MCTP endpoint +sample such that this board's UART tx pin connects to the endpoint board's rx +pin, and this board's UART rx pin connects to the endpoint board's tx pin. The +boards' grounds should also be wired together. + +Optionally a logic analyzer can be wired up and listening to the UART to inspect +the data flowing. + +Building and Running +******************** + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/mctp/mctp_host + :host-os: unix + :board: nrf52840_nrf52840dk + :goals: run + :compact: + +References +********** + +`MCTP Base Specification 2019 `_ diff --git a/samples/modules/mctp/mctp_host/boards/nrf52840dk_nrf52840.overlay b/samples/modules/mctp/mctp_host/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 0000000000000..48c7f840dcab6 --- /dev/null +++ b/samples/modules/mctp/mctp_host/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,3 @@ +&arduino_serial{ + status = "okay"; +}; diff --git a/samples/modules/mctp/mctp_host/prj.conf b/samples/modules/mctp/mctp_host/prj.conf new file mode 100644 index 0000000000000..341787ecbd3eb --- /dev/null +++ b/samples/modules/mctp/mctp_host/prj.conf @@ -0,0 +1,8 @@ +# nothing here +CONFIG_SERIAL=y +CONFIG_UART_ASYNC_API=y +CONFIG_MCTP=y +CONFIG_MCTP_UART=y +CONFIG_MCTP_LOG_LEVEL_DBG=y +CONFIG_LOG=y +CONFIG_LOG_BUFFER_SIZE=4096 diff --git a/samples/modules/mctp/mctp_host/src/main.c b/samples/modules/mctp/mctp_host/src/main.c new file mode 100644 index 0000000000000..7fa9423c24cde --- /dev/null +++ b/samples/modules/mctp/mctp_host/src/main.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mctp_host); + +#define LOCAL_HELLO_EID 20 + +#define REMOTE_HELLO_EID 10 + +K_SEM_DEFINE(mctp_rx, 0, 1); + +static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg, + size_t len) +{ + LOG_INF("received message %s for endpoint %d, msg_tag %d, len %zu", (char *)msg, eid, + msg_tag, len); + k_sem_give(&mctp_rx); +} + +MCTP_UART_DT_DEFINE(mctp_host, DEVICE_DT_GET(DT_NODELABEL(arduino_serial))); + +int main(void) +{ + int rc; + struct mctp *mctp_ctx; + + LOG_INF("MCTP Host EID:%d on %s\n", LOCAL_HELLO_EID, CONFIG_BOARD_TARGET); + + mctp_set_alloc_ops(malloc, free, realloc); + mctp_ctx = mctp_init(); + __ASSERT_NO_MSG(mctp_ctx != NULL); + mctp_register_bus(mctp_ctx, &mctp_host.binding, LOCAL_HELLO_EID); + mctp_set_rx_all(mctp_ctx, rx_message, NULL); + mctp_uart_start_rx(&mctp_host); + + /* MCTP poll loop, send "hello" and get "world" back */ + while (true) { + rc = mctp_message_tx(mctp_ctx, REMOTE_HELLO_EID, false, 0, "hello", + sizeof("hello")); + if (rc != 0) { + LOG_WRN("Failed to send message, errno %d\n", rc); + k_msleep(1000); + } else { + k_sem_take(&mctp_rx, K_MSEC(10)); + } + rc = 0; + } + + return 0; +} diff --git a/samples/modules/tflite-micro/hello_world/README.rst b/samples/modules/tflite-micro/hello_world/README.rst index 7a1d89cf83aad..12ac4f93a8313 100644 --- a/samples/modules/tflite-micro/hello_world/README.rst +++ b/samples/modules/tflite-micro/hello_world/README.rst @@ -65,7 +65,7 @@ the :envvar:`PATH` variable, then building and testing can be done with followin commands. ``` -$ west build -p auto -b mps3/corstone300/an547 samples/modules/tflite-micro/hello_world/ -T sample.tensorflow.helloworld.cmsis_nn +$ west build -p auto -b mps3/corstone300/fvp samples/modules/tflite-micro/hello_world/ -T sample.tensorflow.helloworld.cmsis_nn $ FVP_Corstone_SSE-300_Ethos-U55 build/zephyr/zephyr.elf ``` diff --git a/samples/modules/tflite-micro/hello_world/sample.yaml b/samples/modules/tflite-micro/hello_world/sample.yaml index b0f087f1c44de..e5521bfed2dad 100644 --- a/samples/modules/tflite-micro/hello_world/sample.yaml +++ b/samples/modules/tflite-micro/hello_world/sample.yaml @@ -24,6 +24,6 @@ tests: sample.tensorflow.helloworld.cmsis_nn: tags: tensorflow platform_allow: - - mps3/corstone300/an547 + - mps3/corstone300/fvp extra_configs: - CONFIG_TENSORFLOW_LITE_MICRO_CMSIS_NN_KERNELS=y diff --git a/samples/modules/tflite-micro/tflm_ethosu/README.rst b/samples/modules/tflite-micro/tflm_ethosu/README.rst index 0e8d7279dfd1b..bf27c6279960e 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/README.rst +++ b/samples/modules/tflite-micro/tflm_ethosu/README.rst @@ -43,5 +43,5 @@ commands. .. code-block:: bash - $ west build -b mps3/corstone300/an547 zephyr/samples/modules/tflite-micro/tflm_ethosu + $ west build -b mps3/corstone300/fvp zephyr/samples/modules/tflite-micro/tflm_ethosu $ FVP_Corstone_SSE-300_Ethos-U55 build/zephyr/zephyr.elf diff --git a/samples/modules/tflite-micro/tflm_ethosu/sample.yaml b/samples/modules/tflite-micro/tflm_ethosu/sample.yaml index 37d97a87d346d..86a7542fd6b80 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/sample.yaml +++ b/samples/modules/tflite-micro/tflm_ethosu/sample.yaml @@ -10,4 +10,4 @@ tests: filter: dt_compat_enabled("arm,ethos-u") build_only: true integration_platforms: - - mps3/corstone300/an547 + - mps3/corstone300/fvp diff --git a/samples/modules/tflite-micro/tflm_ethosu/src/inference_process.cpp b/samples/modules/tflite-micro/tflm_ethosu/src/inference_process.cpp index 5807588302e10..352c8308f738a 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/src/inference_process.cpp +++ b/samples/modules/tflite-micro/tflm_ethosu/src/inference_process.cpp @@ -28,7 +28,7 @@ bool copyOutput(const TfLiteTensor &src, InferenceProcess::DataPtr &dst) } if (src.bytes > dst.size) { - printk("Tensor size mismatch (bytes): actual=%d, expected%d.\n", src.bytes, + printf("Tensor size mismatch (bytes): actual=%d, expected%d.\n", src.bytes, dst.size); return true; } @@ -112,7 +112,7 @@ bool InferenceProcess::runJob(InferenceJob &job) /* Get model handle and verify that the version is correct */ const tflite::Model *model = ::tflite::GetModel(job.networkModel.data); if (model->version() != TFLITE_SCHEMA_VERSION) { - printk("Model schema version unsupported: version=%" PRIu32 ", supported=%d.\n", + printf("Model schema version unsupported: version=%" PRIu32 ", supported=%d.\n", model->version(), TFLITE_SCHEMA_VERSION); return true; } @@ -126,12 +126,12 @@ bool InferenceProcess::runJob(InferenceJob &job) /* Allocate tensors */ TfLiteStatus allocate_status = interpreter.AllocateTensors(); if (allocate_status != kTfLiteOk) { - printk("Failed to allocate tensors for inference. job=%p\n", &job); + printf("Failed to allocate tensors for inference. job=%p\n", &job); return true; } if (job.input.size() != interpreter.inputs_size()) { - printk("Number of job and network inputs do not match. input=%zu, network=%zu\n", + printf("Number of job and network inputs do not match. input=%zu, network=%zu\n", job.input.size(), interpreter.inputs_size()); return true; } @@ -142,7 +142,7 @@ bool InferenceProcess::runJob(InferenceJob &job) const TfLiteTensor *tensor = interpreter.input(i); if (input.size != tensor->bytes) { - printk("Input tensor size mismatch. index=%zu, input=%zu, network=%u\n", i, + printf("Input tensor size mismatch. index=%zu, input=%zu, network=%u\n", i, input.size, tensor->bytes); return true; } @@ -154,14 +154,14 @@ bool InferenceProcess::runJob(InferenceJob &job) /* Run the inference */ TfLiteStatus invoke_status = interpreter.Invoke(); if (invoke_status != kTfLiteOk) { - printk("Invoke failed for inference. job=%s\n", job.name.c_str()); + printf("Invoke failed for inference. job=%s\n", job.name.c_str()); return true; } /* Copy output data */ if (job.output.size() > 0) { if (interpreter.outputs_size() != job.output.size()) { - printk("Number of job and network outputs do not match. job=%zu, network=%u\n", + printf("Number of job and network outputs do not match. job=%zu, network=%u\n", job.output.size(), interpreter.outputs_size()); return true; } @@ -175,7 +175,7 @@ bool InferenceProcess::runJob(InferenceJob &job) if (job.expectedOutput.size() > 0) { if (job.expectedOutput.size() != interpreter.outputs_size()) { - printk("Number of job and network expected outputs do not match. job=%zu, network=%zu\n", + printf("Number of job and network expected outputs do not match. job=%zu, network=%zu\n", job.expectedOutput.size(), interpreter.outputs_size()); return true; } @@ -185,7 +185,7 @@ bool InferenceProcess::runJob(InferenceJob &job) const TfLiteTensor *output = interpreter.output(i); if (expected.size != output->bytes) { - printk("Expected output tensor size mismatch. index=%u, expected=%zu, network=%zu\n", + printf("Expected output tensor size mismatch. index=%u, expected=%zu, network=%zu\n", i, expected.size, output->bytes); return true; } @@ -193,7 +193,7 @@ bool InferenceProcess::runJob(InferenceJob &job) for (unsigned int j = 0; j < output->bytes; ++j) { if (output->data.uint8[j] != static_cast(expected.data)[j]) { - printk("Expected output tensor data mismatch. index=%u, offset=%u, expected=%02x, network=%02x\n", + printf("Expected output tensor data mismatch. index=%u, offset=%u, expected=%02x, network=%02x\n", i, j, static_cast(expected.data)[j], output->data.uint8[j]); return true; diff --git a/samples/modules/tflite-micro/tflm_ethosu/src/main.cpp b/samples/modules/tflite-micro/tflm_ethosu/src/main.cpp index 5671b0a071854..f951fb7b91fd5 100644 --- a/samples/modules/tflite-micro/tflm_ethosu/src/main.cpp +++ b/samples/modules/tflite-micro/tflm_ethosu/src/main.cpp @@ -108,7 +108,7 @@ void *allocateHeap(const size_t size) uint8_t *buf = static_cast(k_malloc(size)); if ((buf == nullptr) || (heap == nullptr)) { - printk("Heap allocation failed. heap=%p, buf=%p, size=%zu\n", heap, buf, size); + printf("Heap allocation failed. heap=%p, buf=%p, size=%zu\n", heap, buf, size); exit(1); } @@ -133,17 +133,17 @@ void inferenceProcessTask(void *_name, void *heap, void *_params) xInferenceJob *job = static_cast(k_queue_get(params->queueHandle, Z_FOREVER)); - printk("%s: Received inference job. job=%p\n", name->c_str(), job); + printf("%s: Received inference job. job=%p\n", name->c_str(), job); /* Run inference */ job->status = inferenceProcess.runJob(*job); - printk("%s: Sending inference response. job=%p\n", name->c_str(), job); + printf("%s: Sending inference response. job=%p\n", name->c_str(), job); /* Return inference message */ int ret = k_queue_alloc_append(job->responseQueue, job); if (0 != ret) { - printk("%s: Failed to send message\n", name->c_str()); + printf("%s: Failed to send message\n", name->c_str()); exit(1); } } @@ -177,13 +177,13 @@ void inferenceSenderTask(void *_name, void *heap, void *_queue) { DataPtr(expectedOutputData, sizeof(expectedOutputData)) }, &senderQueue); - printk("%s: Sending inference. job=%p, name=%s\n", name->c_str(), &job, + printf("%s: Sending inference. job=%p, name=%s\n", name->c_str(), &job, job.name.c_str()); /* Queue job */ ret = k_queue_alloc_append(inferenceQueue, &job); if (0 != ret) { - printk("%s: Failed to send message\n", name->c_str()); + printf("%s: Failed to send message\n", name->c_str()); exit(1); } } @@ -193,7 +193,7 @@ void inferenceSenderTask(void *_name, void *heap, void *_queue) xInferenceJob *job = static_cast(k_queue_get(&senderQueue, Z_FOREVER)); - printk("%s: Received job response. job=%p, status=%u\n", name->c_str(), job, + printf("%s: Received job response. job=%p, status=%u\n", name->c_str(), job, job->status); totalCompletedJobs++; @@ -229,7 +229,7 @@ int main() const size_t stackSize = 2048; k_thread_stack_t *stack = static_cast(k_malloc(stackSize)); if (stack == nullptr) { - printk("Failed to allocate stack to 'inferenceSenderTask%i'\n", n); + printf("Failed to allocate stack to 'inferenceSenderTask%i'\n", n); exit(1); } @@ -239,7 +239,7 @@ int main() thread.id = k_thread_create(&thread.thread, stack, stackSize, inferenceSenderTask, name, heapPtr, &inferenceQueue, 3, 0, K_FOREVER); if (thread.id == 0) { - printk("Failed to create 'inferenceSenderTask%i'\n", n); + printf("Failed to create 'inferenceSenderTask%i'\n", n); exit(1); } @@ -252,7 +252,7 @@ int main() const size_t stackSize = 8192; k_thread_stack_t *stack = static_cast(k_malloc(stackSize)); if (stack == nullptr) { - printk("Failed to allocate stack to 'inferenceSenderTask%i'\n", n); + printf("Failed to allocate stack to 'inferenceSenderTask%i'\n", n); exit(1); } @@ -265,7 +265,7 @@ int main() thread.id = k_thread_create(&thread.thread, stack, stackSize, inferenceProcessTask, name, heapPtr, &taskParam, 2, 0, K_FOREVER); if (thread.id == 0) { - printk("Failed to create 'inferenceProcessTask%i'\n", n); + printf("Failed to create 'inferenceProcessTask%i'\n", n); exit(1); } @@ -283,7 +283,7 @@ int main() /* Safety belt */ k_thread_suspend(k_current_get()); - printk("Zephyr application failed to initialise \n"); + printf("Zephyr application failed to initialise \n"); return 1; } diff --git a/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.conf b/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.conf index 11107ff947769..78e64e0c4c942 100644 --- a/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.conf +++ b/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.conf @@ -1,9 +1,6 @@ CONFIG_UART_ASYNC_API=y CONFIG_UART_1_ASYNC=y CONFIG_UART_1_INTERRUPT_DRIVEN=n -# Enable HW RX byte counting. This especially matters at higher baud rates. -CONFIG_UART_1_NRF_HW_ASYNC=y -CONFIG_UART_1_NRF_HW_ASYNC_TIMER=1 # Align with the Serial LTE Modem (SLM) application. CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE=1500 diff --git a/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.conf b/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.conf index 6e0cb02062f8b..c0586115e19ae 100644 --- a/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.conf +++ b/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.conf @@ -1,9 +1,6 @@ CONFIG_UART_ASYNC_API=y CONFIG_UART_1_ASYNC=y CONFIG_UART_1_INTERRUPT_DRIVEN=n -# Enable HW RX byte counting. This especially matters at higher baud rates. -CONFIG_UART_1_NRF_HW_ASYNC=y -CONFIG_UART_1_NRF_HW_ASYNC_TIMER=1 # Align with the Serial LTE Modem (SLM) application. CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE=1500 diff --git a/samples/net/cloud/aws_iot_mqtt/CMakeLists.txt b/samples/net/cloud/aws_iot_mqtt/CMakeLists.txt index 7ee0400ba7cac..c3e6c69dda7df 100644 --- a/samples/net/cloud/aws_iot_mqtt/CMakeLists.txt +++ b/samples/net/cloud/aws_iot_mqtt/CMakeLists.txt @@ -21,3 +21,5 @@ else() endif() target_sources(app PRIVATE "src/main.c" ${creds}) + +include(${ZEPHYR_BASE}/samples/net/common/common.cmake) diff --git a/samples/net/cloud/aws_iot_mqtt/Kconfig b/samples/net/cloud/aws_iot_mqtt/Kconfig index a80d28db5c634..da81b7b8595e6 100644 --- a/samples/net/cloud/aws_iot_mqtt/Kconfig +++ b/samples/net/cloud/aws_iot_mqtt/Kconfig @@ -81,4 +81,5 @@ config AWS_EXPONENTIAL_BACKOFF endmenu +source "samples/net/common/Kconfig" source "Kconfig.zephyr" diff --git a/samples/net/cloud/aws_iot_mqtt/boards/mg100.conf b/samples/net/cloud/aws_iot_mqtt/boards/mg100.conf new file mode 100644 index 0000000000000..4278846625f9c --- /dev/null +++ b/samples/net/cloud/aws_iot_mqtt/boards/mg100.conf @@ -0,0 +1,12 @@ +# The HL7800 driver gets its IP settings from the cell network +CONFIG_NET_CONFIG_SETTINGS=n +CONFIG_NET_DHCPV4=n +CONFIG_DNS_SERVER_IP_ADDRESSES=n +# NB-IoT has large latency, so increase timeouts. It is ok to use this for Cat-M1 as well. +CONFIG_NET_SOCKETS_DNS_TIMEOUT=12000 +CONFIG_NET_SOCKETS_CONNECT_TIMEOUT=15000 +# Wait for the network to be ready +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_NET_SAMPLE_COMMON_WAIT_DNS_SERVER_ADDITION=y +# Don't require device to have time/date +CONFIG_MBEDTLS_HAVE_TIME_DATE=n diff --git a/samples/net/cloud/aws_iot_mqtt/boards/pinnacle_100_dvk.conf b/samples/net/cloud/aws_iot_mqtt/boards/pinnacle_100_dvk.conf new file mode 100644 index 0000000000000..4278846625f9c --- /dev/null +++ b/samples/net/cloud/aws_iot_mqtt/boards/pinnacle_100_dvk.conf @@ -0,0 +1,12 @@ +# The HL7800 driver gets its IP settings from the cell network +CONFIG_NET_CONFIG_SETTINGS=n +CONFIG_NET_DHCPV4=n +CONFIG_DNS_SERVER_IP_ADDRESSES=n +# NB-IoT has large latency, so increase timeouts. It is ok to use this for Cat-M1 as well. +CONFIG_NET_SOCKETS_DNS_TIMEOUT=12000 +CONFIG_NET_SOCKETS_CONNECT_TIMEOUT=15000 +# Wait for the network to be ready +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_NET_SAMPLE_COMMON_WAIT_DNS_SERVER_ADDITION=y +# Don't require device to have time/date +CONFIG_MBEDTLS_HAVE_TIME_DATE=n diff --git a/samples/net/cloud/aws_iot_mqtt/prj.conf b/samples/net/cloud/aws_iot_mqtt/prj.conf index fa0a5202a5dce..ef5f6574ef752 100644 --- a/samples/net/cloud/aws_iot_mqtt/prj.conf +++ b/samples/net/cloud/aws_iot_mqtt/prj.conf @@ -71,3 +71,9 @@ CONFIG_MBEDTLS_TLS_VERSION_1_2=y CONFIG_MBEDTLS_MEMORY_DEBUG=y CONFIG_MBEDTLS_HAVE_TIME_DATE=y CONFIG_MBEDTLS_SSL_ALPN=y + +# Debugging options +# CONFIG_MBEDTLS_DEBUG=y +# CONFIG_MBEDTLS_LOG_LEVEL_DBG=y +# CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=1 +# CONFIG_LOG_BUFFER_SIZE=50000 diff --git a/samples/net/cloud/aws_iot_mqtt/src/main.c b/samples/net/cloud/aws_iot_mqtt/src/main.c index c03f250bcaa21..5c78e78530c43 100644 --- a/samples/net/cloud/aws_iot_mqtt/src/main.c +++ b/samples/net/cloud/aws_iot_mqtt/src/main.c @@ -17,6 +17,7 @@ #include #include #include +#include "net_sample_common.h" #if defined(CONFIG_MBEDTLS_MEMORY_DEBUG) @@ -453,6 +454,8 @@ int main(void) { setup_credentials(); + wait_for_network(); + for (;;) { resolve_broker_addr(&aws_broker); diff --git a/samples/net/common/Kconfig b/samples/net/common/Kconfig new file mode 100644 index 0000000000000..8692a8b3120e2 --- /dev/null +++ b/samples/net/common/Kconfig @@ -0,0 +1,12 @@ +# +# Copyright (c) 2025 Ezurio +# +# SPDX-License-Identifier: Apache-2.0 +# + +config NET_SAMPLE_COMMON_WAIT_DNS_SERVER_ADDITION + bool "Wait DNS server addition before considering connection to be up" + depends on MODEM_HL7800 && !DNS_SERVER_IP_ADDRESSES + help + Make sure we get DNS server addresses from the network + before considering the connection to be up. diff --git a/samples/net/common/net_sample_common.c b/samples/net/common/net_sample_common.c index 1e744f178b514..9c785963298fa 100644 --- a/samples/net/common/net_sample_common.c +++ b/samples/net/common/net_sample_common.c @@ -10,7 +10,11 @@ LOG_MODULE_REGISTER(net_samples_common, LOG_LEVEL_DBG); #include #if defined(CONFIG_NET_CONNECTION_MANAGER) +#if defined(CONFIG_NET_SAMPLE_COMMON_WAIT_DNS_SERVER_ADDITION) +#define L4_EVENT_MASK (NET_EVENT_DNS_SERVER_ADD | NET_EVENT_L4_DISCONNECTED) +#else #define L4_EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED) +#endif static struct net_mgmt_event_callback l4_cb; static K_SEM_DEFINE(network_connected, 0, 1); @@ -19,7 +23,11 @@ static void l4_event_handler(struct net_mgmt_event_callback *cb, uint32_t event, struct net_if *iface) { switch (event) { +#if defined(CONFIG_NET_SAMPLE_COMMON_WAIT_DNS_SERVER_ADDITION) + case NET_EVENT_DNS_SERVER_ADD: +#else case NET_EVENT_L4_CONNECTED: +#endif LOG_INF("Network connectivity established and IP address assigned"); k_sem_give(&network_connected); break; diff --git a/samples/net/dns_resolve/sample.yaml b/samples/net/dns_resolve/sample.yaml index 7cf510d0ba430..0d346fec82119 100644 --- a/samples/net/dns_resolve/sample.yaml +++ b/samples/net/dns_resolve/sample.yaml @@ -26,6 +26,6 @@ tests: sample.net.dns_resolve.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/dsa/CMakeLists.txt b/samples/net/dsa/CMakeLists.txt index 6f80b96f5e18d..f22d38467c708 100644 --- a/samples/net/dsa/CMakeLists.txt +++ b/samples/net/dsa/CMakeLists.txt @@ -5,4 +5,5 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(dsa) -target_sources(app PRIVATE src/main.c src/dsa_lldp.c) +target_sources(app PRIVATE src/main.c) +target_sources_ifdef(CONFIG_NET_SAMPLE_DSA_LLDP app PRIVATE src/dsa_lldp.c) diff --git a/samples/net/dsa/Kconfig b/samples/net/dsa/Kconfig new file mode 100644 index 0000000000000..de09e85206fb8 --- /dev/null +++ b/samples/net/dsa/Kconfig @@ -0,0 +1,25 @@ +# Private config options for DSA + +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "DSA sample application" + +if NET_DSA + +config NET_SAMPLE_DSA_MAX_SLAVE_PORTS + int "DSA slave ports maximum number" + range 2 10 + default 3 + help + DSA slave ports maximum number. + +config NET_SAMPLE_DSA_LLDP + bool "DSA LLDP example" + default y + help + Enable DSA LLDP example. + +endif + +source "Kconfig.zephyr" diff --git a/samples/net/dsa/boards/ip_k66f.conf b/samples/net/dsa/boards/ip_k66f.conf new file mode 100644 index 0000000000000..eb7d269a4e1c6 --- /dev/null +++ b/samples/net/dsa/boards/ip_k66f.conf @@ -0,0 +1,15 @@ +CONFIG_DSA_SPI=y +CONFIG_DSA_KSZ_TAIL_TAGGING=y + +CONFIG_SHELL_BACKEND_RTT=y +CONFIG_SHELL_BACKEND_SERIAL=n +CONFIG_LOG_BACKEND_RTT=n + +CONFIG_NET_CONFIG_SETTINGS=y +CONFIG_NET_CONFIG_NEED_IPV6=y +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_INIT_TIMEOUT=10 + +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.2" +CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.1" +CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" diff --git a/samples/net/dsa/boards/mimxrt1180_evk_mimxrt1189_cm33.conf b/samples/net/dsa/boards/mimxrt1180_evk_mimxrt1189_cm33.conf new file mode 100644 index 0000000000000..40b0f514bf7d7 --- /dev/null +++ b/samples/net/dsa/boards/mimxrt1180_evk_mimxrt1189_cm33.conf @@ -0,0 +1,5 @@ +CONFIG_NET_IF_MAX_IPV4_COUNT=7 +CONFIG_NET_IF_MAX_IPV6_COUNT=7 + +CONFIG_NET_SAMPLE_DSA_LLDP=n +CONFIG_NET_SAMPLE_DSA_MAX_SLAVE_PORTS=5 diff --git a/samples/net/dsa/boards/mimxrt1180_evk_mimxrt1189_cm7.conf b/samples/net/dsa/boards/mimxrt1180_evk_mimxrt1189_cm7.conf new file mode 100644 index 0000000000000..40b0f514bf7d7 --- /dev/null +++ b/samples/net/dsa/boards/mimxrt1180_evk_mimxrt1189_cm7.conf @@ -0,0 +1,5 @@ +CONFIG_NET_IF_MAX_IPV4_COUNT=7 +CONFIG_NET_IF_MAX_IPV6_COUNT=7 + +CONFIG_NET_SAMPLE_DSA_LLDP=n +CONFIG_NET_SAMPLE_DSA_MAX_SLAVE_PORTS=5 diff --git a/samples/net/dsa/prj.conf b/samples/net/dsa/prj.conf index 84a2317555fa4..39edbd3263961 100644 --- a/samples/net/dsa/prj.conf +++ b/samples/net/dsa/prj.conf @@ -25,16 +25,10 @@ CONFIG_NET_SHELL=y # DSA support CONFIG_NET_DSA=y -CONFIG_DSA_SPI=y -CONFIG_DSA_KSZ_TAIL_TAGGING=y # Ethernet is needed for LLDP CONFIG_NET_L2_ETHERNET=y -CONFIG_NET_CONFIG_NEED_IPV6=y -CONFIG_NET_CONFIG_NEED_IPV4=y -CONFIG_NET_CONFIG_SETTINGS=y - # Logging CONFIG_LOG=y CONFIG_NET_DSA_LOG_LEVEL_INF=y @@ -47,20 +41,8 @@ CONFIG_POSIX_API=y # How many traffic classes to enable CONFIG_NET_TC_TX_COUNT=6 CONFIG_NET_TC_RX_COUNT=4 -CONFIG_NET_CONFIG_INIT_TIMEOUT=10 CONFIG_REQUIRES_FULL_LIBC=y CONFIG_NET_IF_MAX_IPV4_COUNT=4 CONFIG_NET_IF_MAX_IPV6_COUNT=4 -CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.0.2" -CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.0.1" -CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" - -# Add RTT SHELL support -> Instead of LOG_BACKEND_RTT -# Shell can be used to test the DSA operation with e.g. -# 'net ping -I3 192.168.0.1' -CONFIG_SHELL=y -CONFIG_SHELL_BACKEND_RTT=y -CONFIG_SHELL_BACKEND_SERIAL=n -CONFIG_LOG_BACKEND_RTT=n diff --git a/samples/net/dsa/sample.yaml b/samples/net/dsa/sample.yaml index fe4bd46d810c1..3016a7e5f6f16 100644 --- a/samples/net/dsa/sample.yaml +++ b/samples/net/dsa/sample.yaml @@ -9,5 +9,8 @@ common: tests: sample.net.dsa: build_only: true - platform_allow: ip_k66f + platform_allow: + - ip_k66f + - mimxrt1180_evk/mimxrt1189/cm33 + - mimxrt1180_evk/mimxrt1189/cm7 depends_on: eth diff --git a/samples/net/dsa/src/dsa.h b/samples/net/dsa/src/dsa.h new file mode 100644 index 0000000000000..a279293e74f5e --- /dev/null +++ b/samples/net/dsa/src/dsa.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020 DENX Software Engineering GmbH + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DSA_SAMPLE__ +#define __DSA_SAMPLE__ + +#include +#include + +extern struct ud user_data; + +/* User data for the interface callback */ +struct ud { + struct net_if *lan[CONFIG_NET_SAMPLE_DSA_MAX_SLAVE_PORTS]; + struct net_if *master; +}; + +#endif diff --git a/samples/net/dsa/src/dsa_lldp.c b/samples/net/dsa/src/dsa_lldp.c index 5f14af271a37e..3a25f683fa97a 100644 --- a/samples/net/dsa/src/dsa_lldp.c +++ b/samples/net/dsa/src/dsa_lldp.c @@ -18,24 +18,89 @@ #include #include -#include "main.h" /* Loglevel of dsa_lldp function */ -LOG_MODULE_DECLARE(net_dsa_lldp_sample, CONFIG_NET_DSA_LOG_LEVEL); +LOG_MODULE_DECLARE(net_dsa_sample, CONFIG_NET_DSA_LOG_LEVEL); -#define LLDP_SYSTEM_NAME_SIZE 24 -#define LLDP_ETHER_TYPE 0x88CC +#include "dsa_lldp.h" + +#define LLDP_SYSTEM_NAME_SIZE 24 +#define LLDP_ETHER_TYPE 0x88CC #define LLDP_INPUT_DATA_BUF_SIZE 512 -#define DSA_BUF_SIZ 128 -int dsa_lldp_send(struct net_if *iface, struct instance_data *pd, - uint16_t lan, int src_port, int origin_port, int cmd, - struct eth_addr *origin_addr) +#define DSA_BUF_SIZ 128 + +static const uint8_t eth_filter_l2_addr_base[][6] = { + /* MAC address of other device - for filtering testing */ + {0x01, 0x80, 0xc2, 0x00, 0x00, 0x03}}; + +enum net_verdict dsa_ll_addr_switch_cb(struct net_if *iface, struct net_pkt *pkt) +{ + struct net_eth_hdr *hdr = NET_ETH_HDR(pkt); + struct net_linkaddr lladst; + + net_pkt_cursor_init(pkt); + lladst.len = sizeof(hdr->dst.addr); + lladst.addr = &hdr->dst.addr[0]; + + /* + * Pass packet to lan1..3 when matching one from + * check_ll_ether_addr table + */ + if (check_ll_ether_addr(lladst.addr, ð_filter_l2_addr_base[0][0])) { + return NET_CONTINUE; + } + + return NET_OK; +} + +int start_slave_port_packet_socket(struct net_if *iface, struct instance_data *pd) +{ + struct sockaddr_ll dst; + int ret; + + pd->sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (pd->sock < 0) { + LOG_ERR("Failed to create RAW socket : %d", errno); + return -errno; + } + + dst.sll_ifindex = net_if_get_by_iface(iface); + dst.sll_family = AF_PACKET; + + ret = bind(pd->sock, (const struct sockaddr *)&dst, sizeof(struct sockaddr_ll)); + if (ret < 0) { + LOG_ERR("Failed to bind packet socket : %d", errno); + return -errno; + } + + return 0; +} + +void dsa_lldp(struct ud *user_data) +{ + uint8_t tbl_buf[8]; + + /* + * Set static table to forward LLDP protocol packets + * to master port. + */ + dsa_switch_set_mac_table_entry(user_data->lan[0], ð_filter_l2_addr_base[0][0], BIT(4), 0, + 0); + dsa_switch_get_mac_table_entry(user_data->lan[0], tbl_buf, 0); + + LOG_INF("DSA static MAC address table entry [%d]:", 0); + LOG_INF("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", tbl_buf[7], tbl_buf[6], tbl_buf[5], + tbl_buf[4], tbl_buf[3], tbl_buf[2], tbl_buf[1], tbl_buf[0]); +} + +static int dsa_lldp_send(struct net_if *iface, struct instance_data *pd, uint16_t lan, int src_port, + int origin_port, int cmd, struct eth_addr *origin_addr) { int ret, len; char buffer[DSA_BUF_SIZ], sys_name[LLDP_SYSTEM_NAME_SIZE]; struct sockaddr_ll dst; struct ethernet_context *ctx = net_if_l2_data(iface); - struct net_eth_hdr *eth_hdr = (struct net_eth_hdr *) buffer; + struct net_eth_hdr *eth_hdr = (struct net_eth_hdr *)buffer; uint8_t *p = &buffer[sizeof(struct net_eth_hdr)]; uint8_t *pb = p; @@ -92,7 +157,7 @@ int dsa_lldp_send(struct net_if *iface, struct instance_data *pd, return 0; } -void dsa_lldp_print_info(uint8_t *lldp_p, uint8_t lanid) +static void dsa_lldp_print_info(uint8_t *lldp_p, uint8_t lanid) { uint16_t tl, length; uint8_t type, subtype; @@ -104,7 +169,7 @@ void dsa_lldp_print_info(uint8_t *lldp_p, uint8_t lanid) /* In-buffer data is stored as big endian */ t1 = *lldp_p++; t2 = *lldp_p++; - tl = (uint16_t) t1 << 8 | t2; + tl = (uint16_t)t1 << 8 | t2; /* Get type and length */ type = tl >> 9; @@ -125,16 +190,16 @@ void dsa_lldp_print_info(uint8_t *lldp_p, uint8_t lanid) case LLDP_TLV_END_LLDPDU: return; case LLDP_TLV_CHASSIS_ID: - LOG_INF("\tCHASSIS ID:\t%02x:%02x:%02x:%02x:%02x:%02x", - p[0], p[1], p[2], p[3], p[4], p[5]); + LOG_INF("\tCHASSIS ID:\t%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], + p[3], p[4], p[5]); break; case LLDP_TLV_PORT_ID: - LOG_INF("\tPORT ID:\t%02x:%02x:%02x:%02x:%02x:%02x", - p[0], p[1], p[2], p[3], p[4], p[5]); + LOG_INF("\tPORT ID:\t%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], + p[4], p[5]); break; case LLDP_TLV_TTL: /* TTL field has 2 bytes in BE */ - LOG_INF("\tTTL:\t\t%ds", (uint16_t) p[0] << 8 | p[1]); + LOG_INF("\tTTL:\t\t%ds", (uint16_t)p[0] << 8 | p[1]); break; case LLDP_TLV_SYSTEM_NAME: memset(t, 0, length + 1); @@ -146,21 +211,18 @@ void dsa_lldp_print_info(uint8_t *lldp_p, uint8_t lanid) } while (1); } -int dsa_lldp_recv(struct net_if *iface, struct instance_data *pd, - uint16_t *lan, int *origin_port, - struct eth_addr *origin_addr) +static int dsa_lldp_recv(struct net_if *iface, struct instance_data *pd, uint16_t *lan, + int *origin_port, struct eth_addr *origin_addr) { struct ethernet_context *ctx = net_if_l2_data(iface); - struct net_eth_hdr *eth_hdr = - (struct net_eth_hdr *) pd->recv_buffer; + struct net_eth_hdr *eth_hdr = (struct net_eth_hdr *)pd->recv_buffer; uint8_t *lldp_p = &pd->recv_buffer[sizeof(struct net_eth_hdr)]; int received; *lan = ctx->dsa_port_idx; /* Receive data */ - received = recv(pd->sock, pd->recv_buffer, - sizeof(pd->recv_buffer), 0); + received = recv(pd->sock, pd->recv_buffer, sizeof(pd->recv_buffer), 0); if (received < 0) { LOG_ERR("RAW : recv error %d", errno); return -1; diff --git a/samples/net/dsa/src/dsa_lldp.h b/samples/net/dsa/src/dsa_lldp.h new file mode 100644 index 0000000000000..c66202b7e409a --- /dev/null +++ b/samples/net/dsa/src/dsa_lldp.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020 DENX Software Engineering GmbH + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DSA_SAMPLE_LLDP__ +#define __DSA_SAMPLE_LLDP__ + +#include "dsa.h" + +#define MCAST_DEST_MAC0 0x01 +#define MCAST_DEST_MAC1 0x80 +#define MCAST_DEST_MAC2 0xc2 +#define MCAST_DEST_MAC3 0x00 +#define MCAST_DEST_MAC4 0x00 +#define MCAST_DEST_MAC5 0x03 + +#define RECV_BUFFER_SIZE 1280 +#define ETH_ALEN 6 +#define PACKET_LEN 128 + +struct eth_addr { + uint8_t addr[ETH_ALEN]; /* origin hardware address */ +}; + +struct instance_data { + char *if_name; + int sock; + char recv_buffer[RECV_BUFFER_SIZE]; +}; + +static inline bool check_ll_ether_addr(const uint8_t *a, const uint8_t *b) +{ + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) | (a[4] ^ b[4]) | + (a[5] ^ b[5])) == 0; +} + +static inline void dsa_buf_write_be16(uint16_t tl, uint8_t **p) +{ + uint8_t *v = (uint8_t *)&tl; + **p = v[1]; + (*p)++; + **p = v[0]; + (*p)++; +} + +int start_slave_port_packet_socket(struct net_if *iface, struct instance_data *pd); + +enum net_verdict dsa_ll_addr_switch_cb(struct net_if *iface, struct net_pkt *pkt); + +void dsa_lldp(struct ud *user_data); + +#define CMD_DISCOVER 0 +#define CMD_ACK 1 +#define DSA_STACK_SIZE 4096 +#define DSA_PRIORITY 5 +#define DSA_THREAD_START_DELAY 4000 + +#define DSA_THREAD(ID, FN_RECV, FN_SEND) \ + static void dsa_thread_##ID(void *t1, void *t2, void *t3); \ + K_THREAD_DEFINE(dsa_tid_##ID, DSA_STACK_SIZE, dsa_thread_##ID, NULL, NULL, NULL, \ + DSA_PRIORITY, 0, DSA_THREAD_START_DELAY); \ + \ + void dsa_thread_##ID(void *t1, void *t2, void *t3) \ + { \ + int origin_port, ret; \ + uint16_t seq; \ + struct eth_addr origin_addr; \ + struct instance_data data; \ + struct net_if *iface; \ + \ + iface = user_data.lan[ID - 1]; \ + \ + data.if_name = "lan" #ID; \ + ret = start_slave_port_packet_socket(iface, &data); \ + if (ret < 0) { \ + LOG_ERR("start_slave_port_packet_socket failed %d", ret); \ + return; \ + } \ + dsa_register_recv_callback(iface, dsa_ll_addr_switch_cb); \ + \ + LOG_INF("DSA -> eth/lan" #ID " idx: %d sock: %d", net_if_get_by_iface(iface), \ + data.sock); \ + do { \ + ret = FN_RECV(iface, &data, &seq, &origin_port, &origin_addr); \ + if (ret) { \ + break; \ + } \ + ret = FN_SEND(iface, &data, seq, 0, origin_port, CMD_ACK, &origin_addr); \ + if (ret) { \ + break; \ + } \ + } while (true); \ + } + +#endif /* __DSA_SAMPLE_LLDP__ */ diff --git a/samples/net/dsa/src/main.c b/samples/net/dsa/src/main.c index a7c0e14dd2c07..81cf5bb03da69 100644 --- a/samples/net/dsa/src/main.c +++ b/samples/net/dsa/src/main.c @@ -5,12 +5,17 @@ */ #include -LOG_MODULE_REGISTER(net_dsa_lldp_sample, CONFIG_NET_DSA_LOG_LEVEL); +LOG_MODULE_REGISTER(net_dsa_sample, CONFIG_NET_DSA_LOG_LEVEL); -#include -#include "main.h" +#include "dsa.h" -static void iface_cb(struct net_if *iface, void *user_data) +#if defined(CONFIG_NET_SAMPLE_DSA_LLDP) +#include "dsa_lldp.h" +#endif + +struct ud user_data; + +static void dsa_iface_find_cb(struct net_if *iface, void *user_data) { struct ud *ifaces = user_data; @@ -28,9 +33,9 @@ static void iface_cb(struct net_if *iface, void *user_data) struct net_if *slave = dsa_get_slave_port(iface, i); if (slave == NULL) { - LOG_ERR("Slave interface %d not found.", i); - break; + continue; } + LOG_INF("Slave interface %d found.", i); ifaces->lan[i] = slave; } @@ -39,87 +44,15 @@ static void iface_cb(struct net_if *iface, void *user_data) } } -static const uint8_t eth_filter_l2_addr_base[][6] = { - /* MAC address of other device - for filtering testing */ - { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 } -}; - -enum net_verdict dsa_ll_addr_switch_cb(struct net_if *iface, - struct net_pkt *pkt) -{ - struct net_eth_hdr *hdr = NET_ETH_HDR(pkt); - struct net_linkaddr lladst; - - net_pkt_cursor_init(pkt); - lladst.len = sizeof(hdr->dst.addr); - lladst.addr = &hdr->dst.addr[0]; - - /* - * Pass packet to lan1..3 when matching one from - * check_ll_ether_addr table - */ - if (check_ll_ether_addr(lladst.addr, ð_filter_l2_addr_base[0][0])) { - return 1; - } - - return 0; -} - -int start_slave_port_packet_socket(struct net_if *iface, - struct instance_data *pd) -{ - struct sockaddr_ll dst; - int ret; - - pd->sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (pd->sock < 0) { - LOG_ERR("Failed to create RAW socket : %d", errno); - return -errno; - } - - dst.sll_ifindex = net_if_get_by_iface(iface); - dst.sll_family = AF_PACKET; - - ret = bind(pd->sock, (const struct sockaddr *)&dst, - sizeof(struct sockaddr_ll)); - if (ret < 0) { - LOG_ERR("Failed to bind packet socket : %d", errno); - return -errno; - } - - return 0; -} - -struct ud user_data_ifaces; -static int init_dsa_ports(void) -{ - uint8_t tbl_buf[8]; - - /* Initialize interfaces - read them to user_data_ifaces */ - (void)memset(&user_data_ifaces, 0, sizeof(user_data_ifaces)); - net_if_foreach(iface_cb, &user_data_ifaces); - - /* - * Set static table to forward LLDP protocol packets - * to master port. - */ - dsa_switch_set_mac_table_entry(user_data_ifaces.lan[0], - ð_filter_l2_addr_base[0][0], - BIT(4), 0, 0); - dsa_switch_get_mac_table_entry(user_data_ifaces.lan[0], tbl_buf, 0); - - LOG_INF("DSA static MAC address table entry [%d]:", 0); - LOG_INF("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", - tbl_buf[7], tbl_buf[6], tbl_buf[5], tbl_buf[4], - tbl_buf[3], tbl_buf[2], tbl_buf[1], tbl_buf[0]); - - return 0; -} - int main(void) { - init_dsa_ports(); + /* Initialize interfaces - read them to user_data */ + (void)memset(&user_data, 0, sizeof(user_data)); + net_if_foreach(dsa_iface_find_cb, &user_data); +#if defined(CONFIG_NET_SAMPLE_DSA_LLDP) + dsa_lldp(&user_data); +#endif LOG_INF("DSA ports init - OK"); return 0; } diff --git a/samples/net/dsa/src/main.h b/samples/net/dsa/src/main.h deleted file mode 100644 index 5d8cd70e6ade4..0000000000000 --- a/samples/net/dsa/src/main.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2020 DENX Software Engineering GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __DSA_SAMPLE__ -#define __DSA_SAMPLE__ - -#include -#include - -#include -#include -#include -#include -#include - -#define MCAST_DEST_MAC0 0x01 -#define MCAST_DEST_MAC1 0x80 -#define MCAST_DEST_MAC2 0xc2 -#define MCAST_DEST_MAC3 0x00 -#define MCAST_DEST_MAC4 0x00 -#define MCAST_DEST_MAC5 0x03 - -#define RECV_BUFFER_SIZE 1280 -#define ETH_ALEN 6 -#define PACKET_LEN 128 - -extern struct ud user_data_ifaces; - -struct eth_addr { - uint8_t addr[ETH_ALEN]; /* origin hardware address */ -}; - -struct instance_data { - char *if_name; - int sock; - char recv_buffer[RECV_BUFFER_SIZE]; -}; - -/* User data for the interface callback */ -struct ud { - struct net_if *lan[3]; - struct net_if *master; -}; - -static inline bool check_ll_ether_addr(const uint8_t *a, const uint8_t *b) -{ - return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | - (a[3] ^ b[3]) | (a[4] ^ b[4]) | (a[5] ^ b[5])) == 0; -} - -static inline void dsa_buf_write_be16(uint16_t tl, uint8_t **p) -{ - uint8_t *v = (uint8_t *) &tl; - **p = v[1]; - (*p)++; - **p = v[0]; - (*p)++; -} - -int start_slave_port_packet_socket(struct net_if *iface, - struct instance_data *pd); - -enum net_verdict dsa_ll_addr_switch_cb(struct net_if *iface, - struct net_pkt *pkt); - -#define CMD_DISCOVER 0 -#define CMD_ACK 1 -#define DSA_STACK_SIZE 4096 -#define DSA_PRIORITY 5 -#define DSA_THREAD_START_DELAY 4000 - -#define DSA_THREAD(ID, FN_RECV, FN_SEND) \ - static void dsa_thread_##ID(void *t1, void *t2, void *t3); \ - K_THREAD_DEFINE(dsa_tid_##ID, DSA_STACK_SIZE, \ - dsa_thread_##ID, NULL, NULL, NULL, \ - DSA_PRIORITY, 0, DSA_THREAD_START_DELAY); \ - \ - void dsa_thread_##ID(void *t1, void *t2, void *t3) \ - { \ - int origin_port, ret; \ - uint16_t seq; \ - struct eth_addr origin_addr; \ - struct instance_data data; \ - struct net_if *iface; \ - \ - iface = user_data_ifaces.lan[ID-1]; \ - \ - data.if_name = "lan"#ID; \ - ret = start_slave_port_packet_socket(iface, &data); \ - if (ret < 0) { \ - LOG_ERR("start_slave_port_packet_socket failed %d", \ - ret); \ - return; \ - } \ - dsa_register_recv_callback(iface, \ - dsa_ll_addr_switch_cb); \ - \ - LOG_INF("DSA -> eth/lan"#ID" idx: %d sock: %d", \ - net_if_get_by_iface(iface), data.sock); \ - do { \ - ret = FN_RECV(iface, &data, &seq, \ - &origin_port, &origin_addr); \ - if (ret) { \ - break; \ - } \ - ret = FN_SEND(iface, &data, \ - seq, 0, origin_port, CMD_ACK, \ - &origin_addr); \ - if (ret) { \ - break; \ - } \ - } while (true); \ - } - -#endif /* __DSA_SAMPLE__ */ diff --git a/samples/net/gptp/boards/mimxrt1050_evk.conf b/samples/net/gptp/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf similarity index 100% rename from samples/net/gptp/boards/mimxrt1050_evk.conf rename to samples/net/gptp/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf diff --git a/samples/net/ipv4_autoconf/sample.yaml b/samples/net/ipv4_autoconf/sample.yaml index eb9c06ae18e90..2e3ce46e51c51 100644 --- a/samples/net/ipv4_autoconf/sample.yaml +++ b/samples/net/ipv4_autoconf/sample.yaml @@ -18,6 +18,6 @@ tests: sample.net.ipv4_autoconf.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/lwm2m_client/Kconfig b/samples/net/lwm2m_client/Kconfig index 1bc4b6c49b008..888e83152f7f8 100644 --- a/samples/net/lwm2m_client/Kconfig +++ b/samples/net/lwm2m_client/Kconfig @@ -41,4 +41,11 @@ config LWM2M_APP_SERVER When port number is missing, CONFIG_LWM2M_PEER_PORT is used instead. IPv6 addresses must be enclosed in square brackets, for example "coap://[fd00::1]". +config WAIT_DNS_SERVER_ADDITION + bool "Wait DNS server addition before considering connection to be up" + depends on MODEM_HL7800 && !DNS_SERVER_IP_ADDRESSES + help + Make sure we get DNS server addresses from the network + before considering the connection to be up. + source "Kconfig.zephyr" diff --git a/samples/net/lwm2m_client/boards/native_sim.conf b/samples/net/lwm2m_client/boards/native_sim.conf index 3e21f837f7c2e..8ac063ecc3164 100644 --- a/samples/net/lwm2m_client/boards/native_sim.conf +++ b/samples/net/lwm2m_client/boards/native_sim.conf @@ -3,3 +3,5 @@ CONFIG_DNS_SERVER_IP_ADDRESSES=y CONFIG_DNS_SERVER1="192.0.2.2" CONFIG_LWM2M_DNS_SUPPORT=y CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" +CONFIG_HEAP_MEM_POOL_SIZE=32768 +CONFIG_ZVFS_OPEN_MAX=16 diff --git a/samples/net/lwm2m_client/overlay-dtls.conf b/samples/net/lwm2m_client/overlay-dtls.conf index b19c2f8c95217..c379c1f260764 100644 --- a/samples/net/lwm2m_client/overlay-dtls.conf +++ b/samples/net/lwm2m_client/overlay-dtls.conf @@ -32,3 +32,10 @@ CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 # then this has to be match length of CONFIG_BOARD. Default 16 is not enough # for some boards, so, increase it to 32. CONFIG_LWM2M_SECURITY_KEY_SIZE=32 + +# Debug options +# CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=y +# CONFIG_MBEDTLS_DEBUG=y +# CONFIG_MBEDTLS_LOG_LEVEL_DBG=y +# CONFIG_MBEDTLS_MEMORY_DEBUG=y +# CONFIG_MBEDTLS_SHELL=y diff --git a/samples/net/lwm2m_client/overlay-hl7800.conf b/samples/net/lwm2m_client/overlay-hl7800.conf new file mode 100644 index 0000000000000..99ecce48a1e08 --- /dev/null +++ b/samples/net/lwm2m_client/overlay-hl7800.conf @@ -0,0 +1,18 @@ +# Ensure your board has proper device tree configuration for the HL7800 modem +CONFIG_MODEM=y +CONFIG_MODEM_HL7800=y + +# The HL7800 driver gets its IP settings from the cell network +CONFIG_NET_CONFIG_SETTINGS=n +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_WAIT_DNS_SERVER_ADDITION=y +CONFIG_DNS_RESOLVER=y + +# NB-IoT has large latency, so increase timeouts. It is ok to use this for Cat-M1 as well. +CONFIG_NET_SOCKETS_DNS_TIMEOUT=12000 +CONFIG_NET_SOCKETS_CONNECT_TIMEOUT=13000 +CONFIG_NET_SOCKETS_DTLS_TIMEOUT=15000 +CONFIG_COAP_INIT_ACK_TIMEOUT_MS=15000 + +# Debug options +# CONFIG_MODEM_LOG_LEVEL_DBG=y diff --git a/samples/net/lwm2m_client/overlay-tickless.conf b/samples/net/lwm2m_client/overlay-tickless.conf index 132515f6380fd..0dbeb04b11a57 100644 --- a/samples/net/lwm2m_client/overlay-tickless.conf +++ b/samples/net/lwm2m_client/overlay-tickless.conf @@ -1,2 +1,3 @@ -CONFIG_NET_SOCKETPAIR=y +CONFIG_ZVFS_EVENTFD=y +CONFIG_ZVFS_EVENTFD_MAX=2 CONFIG_LWM2M_TICKLESS=y diff --git a/samples/net/lwm2m_client/src/lwm2m-client.c b/samples/net/lwm2m_client/src/lwm2m-client.c index e59b4e9482a3d..b2a1f4e2077cf 100644 --- a/samples/net/lwm2m_client/src/lwm2m-client.c +++ b/samples/net/lwm2m_client/src/lwm2m-client.c @@ -13,7 +13,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include -#include #include #include #include @@ -34,7 +33,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define TEMP_SENSOR_UNITS "Celcius" /* Macros used to subscribe to specific Zephyr NET management events. */ +#if defined(CONFIG_WAIT_DNS_SERVER_ADDITION) +#define L4_EVENT_MASK (NET_EVENT_DNS_SERVER_ADD | NET_EVENT_L4_DISCONNECTED) +#else #define L4_EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED) +#endif #define CONN_LAYER_EVENT_MASK (NET_EVENT_CONN_IF_FATAL_ERROR) static uint8_t bat_idx = LWM2M_DEVICE_PWR_SRC_TYPE_BAT_INT; @@ -335,7 +338,11 @@ static void l4_event_handler(struct net_mgmt_event_callback *cb, struct net_if *iface) { switch (event) { +#if defined(CONFIG_WAIT_DNS_SERVER_ADDITION) + case NET_EVENT_DNS_SERVER_ADD: +#else case NET_EVENT_L4_CONNECTED: +#endif LOG_INF("IP Up"); on_net_event_l4_connected(); break; @@ -387,6 +394,7 @@ int main(void) (void)conn_mgr_if_connect(net_if_get_default()); + LOG_INF("Waiting for network connection..."); k_sem_take(&network_connected_sem, K_FOREVER); } diff --git a/samples/net/mdns_responder/prj.conf b/samples/net/mdns_responder/prj.conf index 4bc9b6b13d22c..9746167843035 100644 --- a/samples/net/mdns_responder/prj.conf +++ b/samples/net/mdns_responder/prj.conf @@ -8,7 +8,7 @@ CONFIG_NET_IPV4=y CONFIG_NET_IF_MAX_IPV6_COUNT=3 CONFIG_NET_IF_MAX_IPV4_COUNT=3 -CONFIG_ZVFS_POLL_MAX=7 +CONFIG_ZVFS_POLL_MAX=9 CONFIG_NET_HOSTNAME_ENABLE=y CONFIG_NET_HOSTNAME_UNIQUE=n diff --git a/samples/net/mdns_responder/sample.yaml b/samples/net/mdns_responder/sample.yaml index 31b12260d0f99..48ab0bf70506b 100644 --- a/samples/net/mdns_responder/sample.yaml +++ b/samples/net/mdns_responder/sample.yaml @@ -12,9 +12,17 @@ tests: - qemu_cortex_m3 integration_platforms: - qemu_x86 + sample.net.mdns_responder.probing: + extra_args: + - CONFIG_MDNS_RESPONDER_PROBE=y + platform_allow: + - qemu_x86 + - qemu_cortex_m3 + integration_platforms: + - qemu_x86 sample.net.mdns_responder.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/mdns_responder/src/main.c b/samples/net/mdns_responder/src/main.c index d6eea7c8337d0..663ebc27545d6 100644 --- a/samples/net/mdns_responder/src/main.c +++ b/samples/net/mdns_responder/src/main.c @@ -36,10 +36,11 @@ static inline int init_vlan(void) */ int main(void) { + init_vlan(); + wait_for_network(); LOG_INF("Waiting mDNS queries..."); - init_vlan(); service(); return 0; } diff --git a/samples/net/mdns_responder/src/vlan.c b/samples/net/mdns_responder/src/vlan.c index 832b172f36762..6f29520ec7e4e 100644 --- a/samples/net/mdns_responder/src/vlan.c +++ b/samples/net/mdns_responder/src/vlan.c @@ -105,6 +105,11 @@ int init_vlan(void) struct ud user_data; int ret; + if (CONFIG_NET_VLAN_COUNT == 0) { + LOG_DBG("No VLAN interfaces defined."); + return 0; + } + iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET)); if (!iface) { LOG_ERR("No ethernet interfaces found."); diff --git a/samples/net/mqtt_publisher/sample.yaml b/samples/net/mqtt_publisher/sample.yaml index 8d3662fe0bf0b..bbf2f47322748 100644 --- a/samples/net/mqtt_publisher/sample.yaml +++ b/samples/net/mqtt_publisher/sample.yaml @@ -31,6 +31,6 @@ tests: sample.net.mqtt_publisher.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/openthread/README.rst b/samples/net/openthread/README.rst new file mode 100644 index 0000000000000..eb94b5cb5c5ae --- /dev/null +++ b/samples/net/openthread/README.rst @@ -0,0 +1,5 @@ +.. zephyr:code-sample-category:: openthread + :name: OpenThread + :show-listing: + + These samples demonstrate various use cases for the Thread protocol and underlying IEEE 802.15.4. diff --git a/samples/net/openthread/coap/CMakeLists.txt b/samples/net/openthread/coap/CMakeLists.txt new file mode 100644 index 0000000000000..3d39d1e6d1330 --- /dev/null +++ b/samples/net/openthread/coap/CMakeLists.txt @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(ot_coap) + +target_include_directories(app PRIVATE src) + +target_sources(app PRIVATE + src/main.c + src/coap_utils.c + src/coap_shell.c +) + +target_sources_ifdef(CONFIG_OT_COAP_SAMPLE_LED app PRIVATE src/led.c) +target_sources_ifdef(CONFIG_OT_COAP_SAMPLE_SW app PRIVATE src/button.c) + +include(${ZEPHYR_BASE}/samples/net/common/common.cmake) + +set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/) diff --git a/samples/net/openthread/coap/Kconfig b/samples/net/openthread/coap/Kconfig new file mode 100644 index 0000000000000..b3ddcad321ecb --- /dev/null +++ b/samples/net/openthread/coap/Kconfig @@ -0,0 +1,23 @@ +# Config options for OpenThread Border CoAP sample app + +# Copyright (c) 2024 Alexandre Bailon +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "OpenThread CoAP Sample" + +menu "Application configuration" + +config OT_COAP_SAMPLE_SERVER + bool "Build the sample CoAP server application" + +config OT_COAP_SAMPLE_LED + bool "Enable LED support" + default y + +config OT_COAP_SAMPLE_SW + bool "Enable switch support" + default y + +endmenu + +source "Kconfig.zephyr" diff --git a/samples/net/openthread/coap/README.rst b/samples/net/openthread/coap/README.rst new file mode 100644 index 0000000000000..7a9c6ad1511f7 --- /dev/null +++ b/samples/net/openthread/coap/README.rst @@ -0,0 +1,196 @@ +.. zephyr:code-sample:: ot-coap + :name: OpenThread CoAP client and server application + :relevant-api: openthread + + Build a Full Thread Device (FTD) CoAP server and client. + +Overview +******** + +This sample demonstrates how to use OpenThread CoAP API. +It can be built to work as a server or as a client. + +By running a client and server on two boards, a local Thread network can be created. +To create the network, OpenThread uses the network key provided with Kconfig. +Once the boards have been flashed, the network will be +automatically created and configured. + +Once the network is operational, then the client could start interacting with +the server. +Every time the user presses the button, the LED on server should toggle. + +The source code for this sample application can be found at: +:zephyr_file:`samples/net/openthread/coap`. + +.. note:: + This sample uses the OpenThread CoAP API whereas Zephyr has its own CoAP API. + So, why are we using the OpenThread CoAP API here ? + + * OpenThread uses it internaly to implement many of its services. + * OpenThread CoAP API has a more direct access to radio. + + So by using OpenThread CoAP API instead of Zephyr one, + we could expect less overhead although this makes the application less portable. + +Building and Running +******************** + +Build the OpenThread FTD CoAP server sample application like this: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/openthread/coap + :board: + :west-args: -T sample.net.openthread.ftd.coap.server + :goals: build + :compact: + +Build the OpenThread FTD CoAP client sample application like this: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/openthread/coap + :board: + :west-args: -T sample.net.openthread.ftd.coap.client + :goals: build + :compact: + +Example building CoAP server for the cc1352p7 launchpad: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/openthread/coap + :host-os: unix + :board: cc1352p7_lp + :west-args: -T sample.net.openthread.ftd.coap.server + :goals: build flash + :compact: + +Example building CoAP client for the cc1352p7 launchpad: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/openthread/coap + :host-os: unix + :board: cc1352p7_lp + :west-args: -T sample.net.openthread.ftd.coap.client + :goals: build flash + :compact: + +Checking Thread network state +***************************** + +Open a console on both server and client boards then check the sate: + +.. code-block:: console + + server:~$ ot state + router + Done + +A valid state could be child, router or leader. + +Once Thread network is operational, you could start using client. + +Controlling server board's LED using a button on client board +************************************************************* + +There is nothing to do once Thread network is operational. +Just press the button sw0 on the client and you should see led0 toggling. + +The client uses a broadcast address to request CoAP server to toggle the LED. +It does not know the address of the server so if there is a second server +on the network, then the LED of the second board will toggle too. + +Controlling server board's LED from a computer +********************************************** + +Although we use OpenThread CoAP API, we could interact with any CoAP client +or server available on network. In this example, we are going to control the +LED from a computer that is not in the Thread network. +This requires an `OpenThread Border Router`_ with NAT64 support enabled on the same network. + +First, check that the server (or the client) is connected to the otbr and +can use NAT64: + +.. code-block:: console + + server:~$ ot netdata show + router + Done + Prefixes: + fd6f:cb3a:802:1::/64 paos low dc00 + Routes: + fc00::/7 sa med dc00 + fd6f:cb3a:802:2:0:0::/96 sn low dc00 + Services: + 44970 01 14000500000e10 s dc00 0 + 44970 5d fd78b9ce54779c6eb5484d062c3b5b22d120 s dc00 1 + Contexts: + fd6f:cb3a:802:1::/64 1 c + Commissioning: + 11426 - - - + Done + +Prefixes show the IPv6 prefies that could be used by device outside the +Thread network to contact devices on Thread network. + +We should have an IPv6 address using the prefix: + +.. code-block:: console + + server:~$ ot ipaddr + fd78:b9ce:5477:9c6e:0:ff:fe00:a800 + fd6f:cb3a:802:1:f0ec:c1e2:c1bb:744 + fd78:b9ce:5477:9c6e:75b8:386c:1f79:1013 + fe80:0:0:0:50d1:bed5:6e6e:ad75 + Done + +fd6f:cb3a:802:1:f0ec:c1e2:c1bb:744 is the IPv6 address that could be used +to contact the CoAP server outside of the Thread network. + +We could also check that we could access internet from Thread network: + +.. code-block:: console + + server:~$ ot ping 8.8.8.8 + Pinging synthesized IPv6 address: fd6f:cb3a:802:2:0:0:808:808 + 16 bytes from fd6f:cb3a:802:2:0:0:808:808: icmp_seq=1 hlim=114 time=36ms + 1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 36/36.0/36 ms. + Done + +If everything is working, then, we could start controlling the LED from a computer. +To do that, let's use aiocoap-client, a tool written in python. +First, install it: + +.. code-block:: shell + + pip install aiocoap + + +Then, send a request to the server to toggle the LED: + +.. code-block:: shell + + aiocoap-client -m PUT --payload '{"led_id":0,"state":2}' coap://[fd6f:cb3a:802:1:f0ec:c1e2:c1bb:744]/led + +The LED state should have changed. + + +.. _OpenThread Border Router: https://openthread.io/codelabs/openthread-border-router-nat64 + +Controlling server board's LED using shell command +************************************************** + +The example also provides a shell command to control the LED on the server from the client. + +To toggle the LED: + +.. code-block:: + + $client:~$ ot_coap led set 0 toggle + +The LED state should have changed. + +Same as for the button, this uses the broadcast address by default. +To control the LED of a specific server, we can use it IPv6 address: + +.. code-block:: + + $client:~$ ot_coap led set 0 toggle fd6f:cb3a:802:1:f0ec:c1e2:c1bb:744 diff --git a/samples/net/openthread/coap/prj.conf b/samples/net/openthread/coap/prj.conf new file mode 100644 index 0000000000000..959fb3c62680d --- /dev/null +++ b/samples/net/openthread/coap/prj.conf @@ -0,0 +1,28 @@ +CONFIG_NETWORKING=y +CONFIG_NET_L2_OPENTHREAD=y +CONFIG_OPENTHREAD_COAP=y +CONFIG_OPENTHREAD_SLAAC=y +CONFIG_JSON_LIBRARY=y + +# Logging +CONFIG_LOG=y +CONFIG_LOG_MAX_LEVEL=1 +CONFIG_LOG_MODE_MINIMAL=n +CONFIG_BOOT_BANNER=y +CONFIG_LOG_BACKEND_UART=y + +# Kernel options +CONFIG_MAIN_STACK_SIZE=2560 +CONFIG_INIT_STACKS=y + +# Add features required for FTD CLI +CONFIG_SHELL=y +CONFIG_OPENTHREAD_SHELL=y +CONFIG_OPENTHREAD_PING_SENDER=y + +# Network config +CONFIG_OPENTHREAD_PANID=4660 +CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" +CONFIG_OPENTHREAD_NETWORKKEY="00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff" +CONFIG_OPENTHREAD_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThreadDemo" diff --git a/samples/net/openthread/coap/sample.yaml b/samples/net/openthread/coap/sample.yaml new file mode 100644 index 0000000000000..7727aa287fda6 --- /dev/null +++ b/samples/net/openthread/coap/sample.yaml @@ -0,0 +1,21 @@ +common: + harness: net + tags: + - net + - openthread + depends_on: openthread + min_flash: 140 +sample: + description: Runs the OpenThread stack as FTD with CoAP + name: OpenThread FTD CoAP +tests: + sample.net.openthread.ftd.coap.client: + build_only: true + platform_allow: + - cc1352p7_lp + sample.net.openthread.ftd.coap.server: + build_only: true + platform_allow: + - cc1352p7_lp + extra_configs: + - CONFIG_OT_COAP_SAMPLE_SERVER=y diff --git a/samples/net/openthread/coap/src/button.c b/samples/net/openthread/coap/src/button.c new file mode 100644 index 0000000000000..da054c3e71c0d --- /dev/null +++ b/samples/net/openthread/coap/src/button.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2024 Alexandre Bailon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +LOG_MODULE_DECLARE(coap); + +#include "coap_utils.h" +#include "button.h" + +struct btn_rsc_data { + const struct gpio_dt_spec gpio; +}; + +struct btn_rsc_ctx { + struct btn_rsc_data *btn; + int count; +}; + +static const struct json_obj_descr json_btn_state_descr[] = { + JSON_OBJ_DESCR_PRIM(struct json_btn_state, btn_id, JSON_TOK_NUMBER), + JSON_OBJ_DESCR_PRIM(struct json_btn_state, state, JSON_TOK_NUMBER), +}; + +static const struct json_obj_descr json_btn_get_descr[] = { + JSON_OBJ_DESCR_PRIM(struct json_btn_get, device_id, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY(struct json_btn_get, btns, JSON_MAX_BTN, count, + json_btn_state_descr, ARRAY_SIZE(json_btn_state_descr)), +}; + +static K_SEM_DEFINE(btn_get_sem, 0, 1); + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER +static int btn_handler_get(void *ctx, otMessage *msg, const otMessageInfo *msg_info) +{ + uint8_t buf[COAP_MAX_BUF_SIZE]; + struct btn_rsc_ctx *btn_ctx = ctx; + + struct json_btn_get btn_data = { + .device_id = coap_device_id(), + }; + + for (int i = 0; i < btn_ctx->count; i++) { + btn_data.btns[i].btn_id = i; + btn_data.btns[i].state = gpio_pin_get_dt(&btn_ctx->btn[i].gpio); + } + btn_data.count = btn_ctx->count; + + json_obj_encode_buf(json_btn_get_descr, ARRAY_SIZE(json_btn_get_descr), &btn_data, buf, + COAP_MAX_BUF_SIZE); + + return coap_resp_send(msg, msg_info, buf, strlen(buf) + 1); +} + +static void btn_handler(void *ctx, otMessage *msg, const otMessageInfo *msg_info) +{ + coap_req_handler(ctx, msg, msg_info, NULL, btn_handler_get); +} + +#define DEFINE_BTN_CTX(node_id) \ + { \ + .gpio = GPIO_DT_SPEC_GET(node_id, gpios), \ + }, + +#define DEFINE_BTNS_CTX(inst, compat, ...) DT_FOREACH_CHILD(DT_INST(inst, compat), DEFINE_BTN_CTX) + +static struct btn_rsc_data btn_rsc_data[] = { + DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(gpio_keys, DEFINE_BTNS_CTX)}; + +static struct btn_rsc_ctx btn_rsc_ctx = { + .btn = btn_rsc_data, + .count = ARRAY_SIZE(btn_rsc_data), +}; + +static otCoapResource btn_rsc = { + .mUriPath = BTN_URI, + .mHandler = btn_handler, + .mContext = &btn_rsc_ctx, + .mNext = NULL, +}; + +static int button_init_rsc(otCoapResource *rsc) +{ + int ret = 0; + + struct btn_rsc_ctx *btn_ctx = rsc->mContext; + const struct gpio_dt_spec *gpio; + + LOG_INF("Initializing the buttons"); + for (int i = 0; i < btn_ctx->count; i++) { + gpio = &btn_ctx->btn[i].gpio; + ret = button_init(gpio); + if (ret) { + break; + } + } + + return ret; +} + +void coap_btn_reg_rsc(void) +{ + otInstance *ot = openthread_get_default_instance(); + + button_init_rsc(&btn_rsc); + LOG_INF("Registering button rsc"); + otCoapAddResource(ot, &btn_rsc); +} +#endif /* CONFIG_OT_COAP_SAMPLE_SERVER */ + +int button_init(const struct gpio_dt_spec *gpio) +{ + int ret; + + if (!gpio_is_ready_dt(gpio)) { + LOG_ERR("Error: button device %s is not ready\n", gpio->port->name); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(gpio, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("Error %d: failed to configure %s pin %d\n", ret, gpio->port->name, + gpio->pin); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0) { + LOG_ERR("Error %d: failed to configure interrupt on %s pin %d\n", ret, + gpio->port->name, gpio->pin); + return ret; + } + + return 0; +} + +static void coap_btn_get_state_cb(void *ctx, otMessage *msg, const otMessageInfo *msg_info, + otError error) +{ + uint8_t buf[COAP_MAX_BUF_SIZE]; + int len = COAP_MAX_BUF_SIZE; + struct json_btn_get *btn = (struct json_btn_get *)ctx; + int ret; + + ret = coap_get_data(msg, buf, &len); + if (ret) { + btn->count = 0; + goto exit; + } + + json_obj_parse(buf, len, json_btn_get_descr, ARRAY_SIZE(json_btn_get_descr), btn); +exit: + k_sem_give(&btn_get_sem); +} + +int coap_btn_get_state(const char *addr, int btn_id, int *state) +{ + struct json_btn_get btn; + int ret; + + ret = coap_get_req_send(addr, BTN_URI, NULL, 0, coap_btn_get_state_cb, &btn); + if (ret) { + return ret; + } + + ret = k_sem_take(&btn_get_sem, K_FOREVER); + if (ret) { + return ret; + } + + if (btn_id >= btn.count) { + return -ENODEV; + } + + *state = btn.btns[btn_id].state; + return ret; +} diff --git a/samples/net/openthread/coap/src/button.h b/samples/net/openthread/coap/src/button.h new file mode 100644 index 0000000000000..2f2a0a3e777a1 --- /dev/null +++ b/samples/net/openthread/coap/src/button.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Alexandre Bailon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef COAP_BUTTON_H +#define COAP_BUTTON_H + +#include +#include + +#define BTN_URI "sw" + +#define BTN_MSG_STATE_OFF 0 +#define BTN_MSG_STATE_ON 1 + +#define JSON_MAX_BTN 4 + +struct json_btn_state { + int btn_id; + int state; +}; + +struct json_btn_get { + const char *device_id; + struct json_btn_state btns[JSON_MAX_BTN]; + int count; +}; + +int button_init(const struct gpio_dt_spec *gpio); +int coap_btn_get_state(const char *addr, int led_id, int *state); + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER +void coap_btn_reg_rsc(void); +#endif + +#endif /* COAP_BUTTON_H */ diff --git a/samples/net/openthread/coap/src/coap_shell.c b/samples/net/openthread/coap/src/coap_shell.c new file mode 100644 index 0000000000000..22e330104fbad --- /dev/null +++ b/samples/net/openthread/coap/src/coap_shell.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2024 Alexandre Bailon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "led.h" +#include "button.h" + +static int coap_cmd_led_set(const struct shell *sh, size_t argc, char **argv) +{ + int led_id; + int led_state; + const char *addr; + int err = 0; + + led_id = shell_strtol(argv[1], 10, &err); + if (err) { + shell_error(sh, "Failed to get a valid LED id: %s", argv[1]); + return err; + } + + if (!strcmp(argv[2], "on")) { + led_state = LED_MSG_STATE_ON; + } else if (!strcmp(argv[2], "off")) { + led_state = LED_MSG_STATE_OFF; + } else if (!strcmp(argv[2], "toggle")) { + led_state = LED_MSG_STATE_TOGGLE; + } else { + shell_error(sh, "Failed to get a valid LED state"); + return -EINVAL; + } + + if (argc <= 3) { + addr = "ff03::1"; + } else { + addr = argv[3]; + } + + return coap_led_set_state(addr, led_id, led_state); +} + +static int coap_cmd_led_get(const struct shell *sh, size_t argc, char **argv) +{ + int led_id; + int led_state; + const char *addr; + int err = 0; + + led_id = shell_strtol(argv[1], 10, &err); + if (err) { + shell_error(sh, "Failed to get a valid LED id: %s", argv[1]); + return err; + } + + if (argc <= 3) { + addr = "ff03::1"; + } else { + addr = argv[3]; + } + + err = coap_led_get_state(addr, led_id, &led_state); + if (err) { + return err; + } + + if (led_state == LED_MSG_STATE_ON) { + shell_info(sh, "on"); + } else { + shell_info(sh, "off"); + } + + return 0; +} + +static int coap_cmd_btn_get(const struct shell *sh, size_t argc, char **argv) +{ + int btn_id; + int btn_state; + const char *addr; + int err = 0; + + btn_id = shell_strtol(argv[1], 10, &err); + if (err) { + shell_error(sh, "Failed to get a valid button id: %s", argv[1]); + return err; + } + + if (argc <= 3) { + addr = "ff03::1"; + } else { + addr = argv[3]; + } + + err = coap_btn_get_state(addr, btn_id, &btn_state); + if (err) { + return err; + } + + if (btn_state == BTN_MSG_STATE_ON) { + shell_info(sh, "on"); + } else { + shell_info(sh, "off"); + } + + return 0; +} + +static const char coap_cmd_led_set_help[] = + "Set a LED state using CoAP\n" + "led set [addr]\n" + "\tled_id: a number defining the LED to control from CoAP server\n" + "\tled_state: on, off or toggle\n" + "\taddr: the IPv6 address of CoAP server. If not defined, it will broadcast to all CoAP " + "servers\n"; + +static const char coap_cmd_led_get_help[] = + "Get a LED state using CoAP\n" + "led get [addr]\n" + "\tled_id: a number defining the LED to get from CoAP server\n" + "\taddr: the IPv6 address of CoAP server. If not defined, it " + "will broadcast to all CoAP servers\n"; + +SHELL_STATIC_SUBCMD_SET_CREATE( + coap_led_subcmd, SHELL_CMD_ARG(set, NULL, coap_cmd_led_set_help, coap_cmd_led_set, 3, 1), + SHELL_CMD_ARG(get, NULL, coap_cmd_led_get_help, coap_cmd_led_get, 2, 1), + SHELL_SUBCMD_SET_END); + +static const char coap_cmd_btn_get_help[] = + "Get a button state using CoAP\n" + "btn get [addr]\n" + "\tbtn_id: a number defining the button to get from CoAP server\n" + "\taddr: the IPv6 address of CoAP server. If not defined, it " + "will broadcast to all CoAP servers\n"; + +SHELL_STATIC_SUBCMD_SET_CREATE(coap_btn_subcmd, + SHELL_CMD_ARG(get, NULL, coap_cmd_btn_get_help, coap_cmd_btn_get, 2, + 1), + SHELL_SUBCMD_SET_END); + +SHELL_STATIC_SUBCMD_SET_CREATE(coap_subcmd, + SHELL_CMD(led, &coap_led_subcmd, "Manage a LED using CoAP", NULL), + SHELL_CMD(btn, &coap_btn_subcmd, "Manage a button using CoAP", NULL), + SHELL_SUBCMD_SET_END); + +SHELL_CMD_REGISTER(ot_coap, &coap_subcmd, "CoAP sample client", NULL); diff --git a/samples/net/openthread/coap/src/coap_utils.c b/samples/net/openthread/coap/src/coap_utils.c new file mode 100644 index 0000000000000..4f4e8af7c0a69 --- /dev/null +++ b/samples/net/openthread/coap/src/coap_utils.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2024 Alexandre Bailon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +LOG_MODULE_DECLARE(coap); + +#include "coap_utils.h" + +static uint8_t coap_buf[COAP_MAX_BUF_SIZE]; +static uint8_t coap_dev_id[COAP_DEVICE_ID_SIZE]; + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER +static void coap_default_handler(void *context, otMessage *message, + const otMessageInfo *message_info) +{ + ARG_UNUSED(context); + ARG_UNUSED(message); + ARG_UNUSED(message_info); + + LOG_INF("Received CoAP message that does not match any request " + "or resource"); +} +#endif /* CONFIG_OT_COAP_SAMPLE_SERVER */ + +static int coap_req_send(const char *addr, const char *uri, uint8_t *buf, int len, + otCoapResponseHandler handler, void *ctx, otCoapCode code) +{ + otInstance *ot; + otMessage *msg; + otMessageInfo msg_info; + otError err; + int ret; + + ot = openthread_get_default_instance(); + if (!ot) { + LOG_ERR("Failed to get an OpenThread instance"); + return -ENODEV; + } + + memset(&msg_info, 0, sizeof(msg_info)); + otIp6AddressFromString(addr, &msg_info.mPeerAddr); + msg_info.mPeerPort = OT_DEFAULT_COAP_PORT; + + msg = otCoapNewMessage(ot, NULL); + if (!msg) { + LOG_ERR("Failed to allocate a new CoAP message"); + return -ENOMEM; + } + + otCoapMessageInit(msg, OT_COAP_TYPE_CONFIRMABLE, code); + + err = otCoapMessageAppendUriPathOptions(msg, uri); + if (err != OT_ERROR_NONE) { + LOG_ERR("Failed to append uri-path: %s", otThreadErrorToString(err)); + ret = -EBADMSG; + goto err; + } + + err = otCoapMessageSetPayloadMarker(msg); + if (err != OT_ERROR_NONE) { + LOG_ERR("Failed to set payload marker: %s", otThreadErrorToString(err)); + ret = -EBADMSG; + goto err; + } + + err = otMessageAppend(msg, buf, len); + if (err != OT_ERROR_NONE) { + LOG_ERR("Failed to set append payload to response: %s", otThreadErrorToString(err)); + ret = -EBADMSG; + goto err; + } + + err = otCoapSendRequest(ot, msg, &msg_info, handler, ctx); + if (err != OT_ERROR_NONE) { + LOG_ERR("Failed to send the request: %s", otThreadErrorToString(err)); + ret = -EIO; /* Find a better error code */ + goto err; + } + + return 0; + +err: + otMessageFree(msg); + return ret; +} + +int coap_put_req_send(const char *addr, const char *uri, uint8_t *buf, int len, + otCoapResponseHandler handler, void *ctx) +{ + return coap_req_send(addr, uri, buf, len, handler, ctx, OT_COAP_CODE_PUT); +} + +int coap_get_req_send(const char *addr, const char *uri, uint8_t *buf, int len, + otCoapResponseHandler handler, void *ctx) +{ + return coap_req_send(addr, uri, buf, len, handler, ctx, OT_COAP_CODE_GET); +} + +int coap_resp_send(otMessage *req, const otMessageInfo *req_info, uint8_t *buf, int len) +{ + otInstance *ot; + otMessage *resp; + otCoapCode resp_code; + otCoapType resp_type; + otError err; + int ret; + + ot = openthread_get_default_instance(); + if (!ot) { + LOG_ERR("Failed to get an OpenThread instance"); + return -ENODEV; + } + + resp = otCoapNewMessage(ot, NULL); + if (!resp) { + LOG_ERR("Failed to allocate a new CoAP message"); + return -ENOMEM; + } + + switch (otCoapMessageGetType(req)) { + case OT_COAP_TYPE_CONFIRMABLE: + resp_type = OT_COAP_TYPE_ACKNOWLEDGMENT; + break; + case OT_COAP_TYPE_NON_CONFIRMABLE: + resp_type = OT_COAP_TYPE_NON_CONFIRMABLE; + break; + default: + LOG_ERR("Invalid message type"); + ret = -EINVAL; + goto err; + } + + switch (otCoapMessageGetCode(req)) { + case OT_COAP_CODE_GET: + resp_code = OT_COAP_CODE_CONTENT; + break; + case OT_COAP_CODE_PUT: + resp_code = OT_COAP_CODE_CHANGED; + break; + default: + LOG_ERR("Invalid message code"); + ret = -EINVAL; + goto err; + } + + err = otCoapMessageInitResponse(resp, req, resp_type, resp_code); + if (err != OT_ERROR_NONE) { + LOG_ERR("Failed to initialize the response: %s", otThreadErrorToString(err)); + ret = -EBADMSG; + goto err; + } + + err = otCoapMessageSetPayloadMarker(resp); + if (err != OT_ERROR_NONE) { + LOG_ERR("Failed to set payload marker: %s", otThreadErrorToString(err)); + ret = -EBADMSG; + goto err; + } + + err = otMessageAppend(resp, buf, len); + if (err != OT_ERROR_NONE) { + LOG_ERR("Failed to set append payload to response: %s", otThreadErrorToString(err)); + ret = -EBADMSG; + goto err; + } + + err = otCoapSendResponse(ot, resp, req_info); + if (err != OT_ERROR_NONE) { + LOG_ERR("Failed to send the response: %s", otThreadErrorToString(err)); + ret = -EIO; + goto err; + } + + return 0; + +err: + otMessageFree(resp); + return ret; +} + +int coap_req_handler(void *ctx, otMessage *msg, const otMessageInfo *msg_info, + coap_req_handler_put put_fn, coap_req_handler_get get_fn) +{ + otCoapCode msg_code = otCoapMessageGetCode(msg); + otCoapType msg_type = otCoapMessageGetType(msg); + int ret; + + if (msg_type != OT_COAP_TYPE_CONFIRMABLE && msg_type != OT_COAP_TYPE_NON_CONFIRMABLE) { + return -EINVAL; + } + + if (msg_code == OT_COAP_CODE_PUT && put_fn) { + int len = otMessageGetLength(msg) - otMessageGetOffset(msg); + + otMessageRead(msg, otMessageGetOffset(msg), coap_buf, len); + ret = put_fn(ctx, coap_buf, len); + if (ret) { + return ret; + } + + if (msg_type == OT_COAP_TYPE_CONFIRMABLE) { + ret = get_fn(ctx, msg, msg_info); + } + + return ret; + } + + if (msg_code == OT_COAP_CODE_GET) { + return get_fn(ctx, msg, msg_info); + } + + return -EINVAL; +} + +const char *coap_device_id(void) +{ + otInstance *ot = openthread_get_default_instance(); + otExtAddress eui64; + int i; + + if (coap_dev_id[0] != '\0') { + return coap_dev_id; + } + + otPlatRadioGetIeeeEui64(ot, eui64.m8); + for (i = 0; i < 8; i++) { + if (i * 2 >= COAP_DEVICE_ID_SIZE) { + i = COAP_DEVICE_ID_SIZE - 1; + break; + } + sprintf(coap_dev_id + i * 2, "%02x", eui64.m8[i]); + } + coap_dev_id[i * 2] = '\0'; + + return coap_dev_id; +} + +int coap_get_data(otMessage *msg, void *buf, int *len) +{ + int coap_len = otMessageGetLength(msg) - otMessageGetOffset(msg); + + if (coap_len > *len) { + return -ENOMEM; + } + + *len = coap_len; + otMessageRead(msg, otMessageGetOffset(msg), buf, coap_len); + + return 0; +} + +int coap_init(void) +{ + otError err; + otInstance *ot; + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER + LOG_INF("Initializing OpenThread CoAP server"); +#else /* CONFIG_OT_COAP_SAMPLE_SERVER */ + LOG_INF("Initializing OpenThread CoAP client"); +#endif /* CONFIG_OT_COAP_SAMPLE_SERVER */ + ot = openthread_get_default_instance(); + if (!ot) { + LOG_ERR("Failed to get an OpenThread instance"); + return -ENODEV; + } + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER + otCoapSetDefaultHandler(ot, coap_default_handler, NULL); +#endif /* CONFIG_OT_COAP_SAMPLE_SERVER */ + + err = otCoapStart(ot, OT_DEFAULT_COAP_PORT); + if (err != OT_ERROR_NONE) { + LOG_ERR("Cannot start CoAP: %s", otThreadErrorToString(err)); + return -EBADMSG; + } + + return 0; +} diff --git a/samples/net/openthread/coap/src/coap_utils.h b/samples/net/openthread/coap/src/coap_utils.h new file mode 100644 index 0000000000000..6db5db6379dea --- /dev/null +++ b/samples/net/openthread/coap/src/coap_utils.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Alexandre Bailon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef COAP_UTILS_H +#define COAP_UTILS_H + +#include +#include + +#define COAP_MAX_BUF_SIZE 128 +#define COAP_DEVICE_ID_SIZE 25 + +typedef int (*coap_req_handler_put)(void *ctx, uint8_t *buf, int size); +typedef int (*coap_req_handler_get)(void *ctx, otMessage *msg, const otMessageInfo *msg_info); + +int coap_init(void); +int coap_req_handler(void *ctx, otMessage *msg, const otMessageInfo *msg_info, + coap_req_handler_put put_fn, coap_req_handler_get get_fn); +int coap_resp_send(otMessage *req, const otMessageInfo *req_info, uint8_t *buf, int len); +int coap_put_req_send(const char *addr, const char *uri, uint8_t *buf, int len, + otCoapResponseHandler handler, void *ctx); +int coap_get_req_send(const char *addr, const char *uri, uint8_t *buf, int len, + otCoapResponseHandler handler, void *ctx); +const char *coap_device_id(void); +int coap_get_data(otMessage *msg, void *buf, int *len); + +#endif /* COAP_UTILS_H */ diff --git a/samples/net/openthread/coap/src/led.c b/samples/net/openthread/coap/src/led.c new file mode 100644 index 0000000000000..739e0f2de47fd --- /dev/null +++ b/samples/net/openthread/coap/src/led.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2024 Alexandre Bailon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +LOG_MODULE_DECLARE(coap); + +#include "coap_utils.h" +#include "led.h" + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER +struct led_rsc_data { + const struct gpio_dt_spec gpio; + int state; +}; + +struct led_rsc_ctx { + struct led_rsc_data *led; + int count; +}; +#endif + +static const struct json_obj_descr json_led_state_descr[] = { + JSON_OBJ_DESCR_PRIM(struct json_led_state, led_id, JSON_TOK_NUMBER), + JSON_OBJ_DESCR_PRIM(struct json_led_state, state, JSON_TOK_NUMBER), +}; + +static const struct json_obj_descr json_led_get_descr[] = { + JSON_OBJ_DESCR_PRIM(struct json_led_get, device_id, JSON_TOK_STRING), + JSON_OBJ_DESCR_OBJ_ARRAY(struct json_led_get, leds, JSON_MAX_LED, count, + json_led_state_descr, ARRAY_SIZE(json_led_state_descr)), +}; + +K_SEM_DEFINE(led_get_sem, 0, 1); + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER +static int led_init(otCoapResource *rsc) +{ + struct led_rsc_ctx *led_ctx = rsc->mContext; + int ret; + + LOG_INF("Initializing the LED"); + for (int i = 0; i < led_ctx->count; i++) { + struct led_rsc_data *led = &led_ctx->led[i]; + + if (!gpio_is_ready_dt(&led->gpio)) { + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&led->gpio, GPIO_OUTPUT); + if (ret) { + LOG_ERR("Failed to configure the GPIO"); + return ret; + } + } + + return 0; +} + +static int led_handler_put(void *ctx, uint8_t *buf, int size) +{ + struct json_led_state led_data; + struct led_rsc_ctx *led_ctx = ctx; + struct led_rsc_data *led; + int ret = -EINVAL; + + json_obj_parse(buf, size, json_led_state_descr, ARRAY_SIZE(json_led_state_descr), + &led_data); + + if (led_data.led_id >= led_ctx->count) { + LOG_ERR("Invalid led id: %x", led_data.led_id); + return -EINVAL; + } + led = &led_ctx->led[led_data.led_id]; + + switch (led_data.state) { + case LED_MSG_STATE_ON: + ret = gpio_pin_set_dt(&led->gpio, 1); + led->state = 1; + break; + case LED_MSG_STATE_OFF: + ret = gpio_pin_set_dt(&led->gpio, 0); + led->state = 0; + break; + case LED_MSG_STATE_TOGGLE: + led->state = 1 - led->state; + ret = gpio_pin_set_dt(&led->gpio, led->state); + break; + default: + LOG_ERR("Set an unsupported LED state: %x", led_data.state); + } + + return ret; +} + +static int led_handler_get(void *ctx, otMessage *msg, const otMessageInfo *msg_info) +{ + uint8_t buf[COAP_MAX_BUF_SIZE]; + struct led_rsc_ctx *led_ctx = ctx; + + struct json_led_get led_data = { + .device_id = coap_device_id(), + }; + + for (int i = 0; i < led_ctx->count; i++) { + led_data.leds[i].led_id = i; + led_data.leds[i].state = led_ctx->led[i].state; + } + led_data.count = led_ctx->count; + + json_obj_encode_buf(json_led_get_descr, ARRAY_SIZE(json_led_get_descr), &led_data, buf, + COAP_MAX_BUF_SIZE); + + return coap_resp_send(msg, msg_info, buf, strlen(buf) + 1); +} + +static void led_handler(void *ctx, otMessage *msg, const otMessageInfo *msg_info) +{ + coap_req_handler(ctx, msg, msg_info, led_handler_put, led_handler_get); +} + +#define DEFINE_LED_CTX(node_id) \ + { \ + .gpio = GPIO_DT_SPEC_GET(node_id, gpios), \ + .state = 0, \ + }, + +#define DEFINE_LEDS_CTX(inst, compat, ...) DT_FOREACH_CHILD(DT_INST(inst, compat), DEFINE_LED_CTX) + +static struct led_rsc_data led_rsc_data[] = { + DT_COMPAT_FOREACH_STATUS_OKAY_VARGS(gpio_leds, DEFINE_LEDS_CTX)}; + +static struct led_rsc_ctx led_rsc_ctx = { + .led = led_rsc_data, + .count = ARRAY_SIZE(led_rsc_data), +}; + +static otCoapResource led_rsc = { + .mUriPath = LED_URI, + .mHandler = led_handler, + .mContext = &led_rsc_ctx, + .mNext = NULL, +}; + +void coap_led_reg_rsc(void) +{ + otInstance *ot = openthread_get_default_instance(); + + LOG_INF("Registering LED rsc"); + led_init(&led_rsc); + otCoapAddResource(ot, &led_rsc); +} +#endif /* CONFIG_OT_COAP_SAMPLE_SERVER */ + +static void coap_led_send_req_cb(void *ctx, otMessage *msg, const otMessageInfo *msg_info, + otError error) +{ +} + +int coap_led_set_state(const char *addr, int led_id, int state) +{ + uint8_t buf[COAP_MAX_BUF_SIZE]; + + struct json_led_state led_data = { + .led_id = led_id, + .state = state, + }; + + json_obj_encode_buf(json_led_state_descr, ARRAY_SIZE(json_led_state_descr), &led_data, buf, + COAP_MAX_BUF_SIZE); + + return coap_put_req_send(addr, LED_URI, buf, strlen(buf) + 1, coap_led_send_req_cb, NULL); +} + +static void coap_led_get_state_cb(void *ctx, otMessage *msg, const otMessageInfo *msg_info, + otError error) +{ + uint8_t buf[COAP_MAX_BUF_SIZE]; + int len = COAP_MAX_BUF_SIZE; + struct json_led_get *led = (struct json_led_get *)ctx; + int ret; + + ret = coap_get_data(msg, buf, &len); + if (ret) { + led->count = 0; + goto exit; + } + + json_obj_parse(buf, len, json_led_get_descr, ARRAY_SIZE(json_led_get_descr), led); +exit: + k_sem_give(&led_get_sem); +} + +int coap_led_get_state(const char *addr, int led_id, int *state) +{ + struct json_led_get led; + int ret; + + ret = coap_get_req_send(addr, LED_URI, NULL, 0, coap_led_get_state_cb, &led); + if (ret) { + return ret; + } + + ret = k_sem_take(&led_get_sem, K_FOREVER); + if (ret) { + return ret; + } + + if (led_id >= led.count) { + return -ENODEV; + } + + *state = led.leds[led_id].state; + return ret; +} diff --git a/samples/net/openthread/coap/src/led.h b/samples/net/openthread/coap/src/led.h new file mode 100644 index 0000000000000..6c07f65d4e453 --- /dev/null +++ b/samples/net/openthread/coap/src/led.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Alexandre Bailon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef COAP_LED_H +#define COAP_LED_H + +#include + +#define LED_URI "led" + +#define LED_MSG_STATE_OFF 0 +#define LED_MSG_STATE_ON 1 +#define LED_MSG_STATE_TOGGLE 2 + +#define JSON_MAX_LED 4 + +struct json_led_state { + int led_id; + int state; +}; + +struct json_led_get { + const char *device_id; + struct json_led_state leds[JSON_MAX_LED]; + int count; +}; + +int coap_led_set_state(const char *addr, int led_id, int state); +int coap_led_get_state(const char *addr, int led_id, int *state); + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER +void coap_led_reg_rsc(void); +#endif /* CONFIG_OT_COAP_SAMPLE_SERVER */ + +#endif /* COAP_LED_H */ diff --git a/samples/net/openthread/coap/src/main.c b/samples/net/openthread/coap/src/main.c new file mode 100644 index 0000000000000..f9d3fbf6c5fdb --- /dev/null +++ b/samples/net/openthread/coap/src/main.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Alexandre Bailon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(coap); + +#include + +#ifdef CONFIG_OT_COAP_SAMPLE_LED +#include "led.h" +#endif /* CONFIG_OT_COAP_SAMPLE_LED */ + +#ifdef CONFIG_OT_COAP_SAMPLE_SW +#include +#include "button.h" + +/* + * Get button configuration from the devicetree sw0 alias. This is mandatory. + */ +#define SW0_NODE DT_ALIAS(sw0) +#if !DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#error "Unsupported board: sw0 devicetree alias is not defined" +#endif +static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0}); +static struct gpio_callback button_cb_data; + +void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + coap_led_set_state("ff03::1", 0, LED_MSG_STATE_TOGGLE); +} +#endif /* CONFIG_OT_COAP_SAMPLE_SW */ + +int main(void) +{ + int ret; + +#ifdef CONFIG_OT_COAP_SAMPLE_SERVER +#ifdef CONFIG_OT_COAP_SAMPLE_LED + coap_led_reg_rsc(); +#endif /* CONFIG_OT_COAP_SAMPLE_LED */ +#ifdef CONFIG_OT_COAP_SAMPLE_SW + coap_btn_reg_rsc(); +#endif /* CONFIG_OT_COAP_SAMPLE_SW */ +#endif /* CONFIG_OT_COAP_SAMPLE_SERVER */ + + ret = coap_init(); + if (ret) { + return ret; + } + +#ifdef CONFIG_OT_COAP_SAMPLE_SW + button_init(&button); + + gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); + gpio_add_callback_dt(&button, &button_cb_data); +#endif /*CONFIG_OT_COAP_SAMPLE_SW */ + + return 0; +} diff --git a/samples/net/openthread/coprocessor/README.rst b/samples/net/openthread/coprocessor/README.rst index 373fbdf8f593d..9fa548201af78 100644 --- a/samples/net/openthread/coprocessor/README.rst +++ b/samples/net/openthread/coprocessor/README.rst @@ -1,6 +1,4 @@ -:orphan: - -.. zephyr:code-sample:: coprocessor +.. zephyr:code-sample:: openthread-coprocessor :name: OpenThread co-processor :relevant-api: openthread diff --git a/samples/net/openthread/shell/CMakeLists.txt b/samples/net/openthread/shell/CMakeLists.txt new file mode 100644 index 0000000000000..8ed710a9eb5fe --- /dev/null +++ b/samples/net/openthread/shell/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(openthread_shell) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/net/openthread/shell/README.rst b/samples/net/openthread/shell/README.rst new file mode 100644 index 0000000000000..70e9cc3970965 --- /dev/null +++ b/samples/net/openthread/shell/README.rst @@ -0,0 +1,35 @@ +.. zephyr:code-sample:: openthread-shell + :name: OpenThread shell + :relevant-api: net_stats + + Test Thread and IEEE 802.15.4 using the OpenThread shell. + +Overview +******** + +This sample allows testing the Thread protocol and the underlying IEEE 802.15.4 drivers for various +boards using the OpenThread shell. + +Building and Running +******************** + +Verify that the board and chip you are targeting provide IEEE 802.15.4 support. + +For instance you can use Nordic's nRF52840 DK. + +.. zephyr-app-commands:: + :zephyr-app: samples/net/openthread/shell + :board: nrf52840dk/nrf52840 + :goals: build + :compact: + +Sample console interaction +========================== + +.. code-block:: console + + uart:~$ ot scan + | PAN | MAC Address | Ch | dBm | LQI | + +------+------------------+----+-----+-----+ + | fe09 | abcdef1234567890 | 15 | -78 | 60 | + Done diff --git a/samples/net/openthread/shell/prj.conf b/samples/net/openthread/shell/prj.conf new file mode 100644 index 0000000000000..78ddc17ac1b08 --- /dev/null +++ b/samples/net/openthread/shell/prj.conf @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Increased main stack size required for initialization +CONFIG_MAIN_STACK_SIZE=4096 + +# Enable Networking and OpenThread stack +CONFIG_NETWORKING=y +CONFIG_NET_L2_OPENTHREAD=y + +# Use NVS as settings backend +CONFIG_NVS=y + +# Logging +CONFIG_LOG=y +CONFIG_NET_LOG=y + +# Networking and OpenThread shells +CONFIG_SHELL=y +CONFIG_NET_SHELL=y +CONFIG_OPENTHREAD_SHELL=y diff --git a/samples/net/openthread/shell/sample.yaml b/samples/net/openthread/shell/sample.yaml new file mode 100644 index 0000000000000..98d3212297a66 --- /dev/null +++ b/samples/net/openthread/shell/sample.yaml @@ -0,0 +1,17 @@ +common: + harness: net + tags: + - net + - openthread + depends_on: openthread +sample: + description: Test Thread and IEEE 802.15.4 using the OpenThread shell + name: OpenThread Shell +tests: + sample.net.openthread.shell: + build_only: true + platform_allow: + - nrf52840dk/nrf52840 + - nrf52840dongle/nrf52840 + integration_platforms: + - nrf52840dk/nrf52840 diff --git a/samples/net/openthread/shell/src/main.c b/samples/net/openthread/shell/src/main.c new file mode 100644 index 0000000000000..ee1cde55a16c7 --- /dev/null +++ b/samples/net/openthread/shell/src/main.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 A Labs GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +int main(void) +{ + /* Nothing to do here. The shell is automatically started in the background. */ + + return 0; +} diff --git a/samples/net/prometheus/sample.yaml b/samples/net/prometheus/sample.yaml index c499e52f40f48..57fa5abfef1e8 100644 --- a/samples/net/prometheus/sample.yaml +++ b/samples/net/prometheus/sample.yaml @@ -3,6 +3,7 @@ sample: name: prometheus_client_sample common: harness: net + depends_on: netif min_ram: 192 tags: - http diff --git a/samples/net/prometheus/src/main.c b/samples/net/prometheus/src/main.c index 5497da2e07802..399a783236c60 100644 --- a/samples/net/prometheus/src/main.c +++ b/samples/net/prometheus/src/main.c @@ -40,7 +40,7 @@ struct app_context { #if defined(CONFIG_NET_SAMPLE_HTTP_SERVICE) static uint16_t test_http_service_port = CONFIG_NET_SAMPLE_HTTP_SERVER_SERVICE_PORT; HTTP_SERVICE_DEFINE(test_http_service, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &test_http_service_port, 1, - 10, NULL); + 10, NULL, NULL); static int dyn_handler(struct http_client_ctx *client, enum http_data_status status, const struct http_request_ctx *request_ctx, @@ -99,7 +99,7 @@ const sec_tag_t sec_tag_list_verify_none[] = { static uint16_t test_https_service_port = CONFIG_NET_SAMPLE_HTTPS_SERVER_SERVICE_PORT; HTTPS_SERVICE_DEFINE(test_https_service, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &test_https_service_port, - 1, 10, NULL, sec_tag_list_verify_none, sizeof(sec_tag_list_verify_none)); + 1, 10, NULL, NULL, sec_tag_list_verify_none, sizeof(sec_tag_list_verify_none)); HTTP_RESOURCE_DEFINE(index_html_gz_resource_https, test_https_service, "/metrics", &dyn_resource_detail); diff --git a/samples/net/sockets/coap_download/src/main.c b/samples/net/sockets/coap_download/src/main.c index 2bc935f9d7d82..bb15551cfba41 100644 --- a/samples/net/sockets/coap_download/src/main.c +++ b/samples/net/sockets/coap_download/src/main.c @@ -82,6 +82,8 @@ static void do_coap_download(struct sockaddr *sa) /* Wait for CoAP request to complete */ k_sem_take(&coap_done_sem, K_FOREVER); + coap_client_cancel_requests(&client); + zsock_close(sockfd); } diff --git a/samples/net/sockets/coap_server/sample.yaml b/samples/net/sockets/coap_server/sample.yaml index 9f7d5de78d765..d1efb96970631 100644 --- a/samples/net/sockets/coap_server/sample.yaml +++ b/samples/net/sockets/coap_server/sample.yaml @@ -15,6 +15,6 @@ tests: sample.net.sockets.coap_server.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/sockets/dumb_http_server/overlay-netusb.conf b/samples/net/sockets/dumb_http_server/overlay-netusb.conf deleted file mode 100644 index b39bdaac0f63e..0000000000000 --- a/samples/net/sockets/dumb_http_server/overlay-netusb.conf +++ /dev/null @@ -1,9 +0,0 @@ -# USB Device settings -CONFIG_USB_DEVICE_STACK=y - -# Select USB Configurations -CONFIG_USB_DEVICE_NETWORK_ECM=y - -# Logging -CONFIG_USB_DRIVER_LOG_LEVEL_INF=y -CONFIG_USB_DEVICE_LOG_LEVEL_INF=y diff --git a/samples/net/sockets/dumb_http_server/sample.yaml b/samples/net/sockets/dumb_http_server/sample.yaml index 7e076a94eb1ad..301f70820d413 100644 --- a/samples/net/sockets/dumb_http_server/sample.yaml +++ b/samples/net/sockets/dumb_http_server/sample.yaml @@ -14,25 +14,3 @@ tests: sample.net.sockets.dumb_http_server: extra_configs: - CONFIG_POSIX_API=y - sample.net.sockets.dumb_http_server.netusb: - depends_on: usb_device - harness: net - extra_args: EXTRA_CONF_FILE="overlay-netusb.conf" - tags: usb - # native_sim usb driver does not work with CONFIG_POSIX_API - platform_exclude: - - native_sim - - native_sim/native/64 - - native_posix - - native_posix/native/64 - sample.net.sockets.dumb_http_server.netusb_zeroconf: - depends_on: usb_device - harness: net - extra_args: EXTRA_CONF_FILE="overlay-netusb.conf;overlay-zeroconf.conf" - tags: usb - # native_sim usb driver does not work with CONFIG_POSIX_API - platform_exclude: - - native_sim - - native_sim/native/64 - - native_posix - - native_posix/native/64 diff --git a/samples/net/sockets/echo_async/sample.yaml b/samples/net/sockets/echo_async/sample.yaml index 811f2115c57b8..1a03bbcc91bd8 100644 --- a/samples/net/sockets/echo_async/sample.yaml +++ b/samples/net/sockets/echo_async/sample.yaml @@ -15,6 +15,6 @@ tests: sample.net.sockets.echo_async.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/sockets/echo_client/README.rst b/samples/net/sockets/echo_client/README.rst index 289a90acc39b8..02cc74b302df7 100644 --- a/samples/net/sockets/echo_client/README.rst +++ b/samples/net/sockets/echo_client/README.rst @@ -179,3 +179,161 @@ on how to test TLS with Linux host samples. See the :zephyr:code-sample:`sockets-echo-server` documentation for an alternate way of running, with the echo-client on the Linux host and the echo-server in QEMU. + +OpenThread RCP+Zephyr HOST (SPINEL connection via UART) +======================================================= + +Prerequisites: +-------------- + +- Build ``echo-server`` for HOST PC (x86_64) + (https://github.com/zephyrproject-rtos/net-tools) SHA1:1c4fdba + +.. code-block:: console + + $ make echo-server + +- Program nRF RCP from Nordic nrf SDK (v2.7.0): + +.. code-block:: console + + (v2.7.0) ~/ncs$ west build -p always -b nrf21540dk/nrf52840 -S logging nrf/samples/openthread/coprocessor + + +- Build mimxrt1020_evk HOST (Zephyr): + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/echo_client + :board: mimxrt1020_evk + :conf: "prj.conf overlay-ot-rcp-host-uart.conf" + :goals: build + :compact: + +And flash + +.. code-block:: console + + $ west flash -r pyocd -i 0226000047784e4500439004d9170013e56100009796990 + + +- Connect the nRF RCP with IMXRT1020 (HOST) via UART + +.. code-block:: c + + /* + * imxrt1020_evk -> HOST + * nRF21540-DK -> RCP (nrf/samples/openthread/coprocessor) + * LPUART2 used for communication: + * nRF21540 (P6) P0.08 RXD -> IMXRT1020-EVK (J17) D1 (GPIO B1 08) (TXD) + * nRF21540 (P6) P0.07 CTS -> IMXRT1020-EVK (J19) D8 (GPIO B1 07) (RTS) + * nRF21540 (P6) P0.06 TXD -> IMXRT1020-EVK (J17) D0 (GPIO B1 09) (RXD) + * nRF21540 (P6) P0.05 RTS -> IMXRT1020-EVK (J17) D7 (GPIO B1 06) (CTS) + */ + + +- Install the OTBR (OpenThread Border Router) docker container on your HOST PC (x86_64) + Follow steps from https://docs.nordicsemi.com/bundle/ncs-2.5.1/page/nrf/protocols/thread/tools.html#running_otbr_using_docker + +**Most notable ones:** + + 1. Create ``otbr0`` network bridge to have access to OT network from HOST + Linux PC + + .. code-block:: console + + sudo docker network create --ipv6 --subnet fd11:db8:1::/64 -o com.docker.network.bridge.name=otbr0 otbr + + + 2. Pull docker container for OTBR: + + .. code-block:: console + + docker pull nrfconnect/otbr:84c6aff + + + 3. Start the docker image: + + .. code-block:: console + + sudo modprobe ip6table_filter + sudo docker run -it --rm --privileged --name otbr --network otbr -p 8080:80 --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" --volume /dev/ttyACM5:/dev/radio nrfconnect/otbr:84c6aff --radio-url spinel+hdlc+uart:///dev/radio?uart-baudrate=1000000 + + + 4. Add proper routing (``fd11:22::/64`` are the IPv6 addresses - On-Mesh - which allow accessing the OT devices) on HOST PC (x86_64) + + .. code-block:: console + + sudo ip -6 route add fd11:22::/64 dev otbr0 via fd11:db8:1::2 + + + And the output for on-OT address: + + .. code-block:: console + + ip route get fd11:22:0:0:5188:1678:d0c0:6893 + fd11:22::5188:1678:d0c0:6893 from :: via fd11:db8:1::2 dev otbr0 src fd11:db8:1::1 metric 1024 pref medium + + + 5. Start the console to the docker image: + + .. code-block:: console + + sudo docker exec -it otbr /bin/bash + + + Test with e.g. + + .. code-block:: console + + ot-ctl router table + ot-ctl ipaddr + + + +Configure OTBR +-------------- + +On the HOST PC's webbrowser: http://localhost:8080/ + +Go to ``Form`` and leave default values - e.g: + + * Network Key: ``00112233445566778899aabbccddeeff`` + * On-Mesh Prefix: ``fd11:22::`` + * Channel: ``15`` + + +to "FORM" the OT network. + +*Note:* +The "On-Mesh Prefix" shall match the one setup in ``otbr0`` routing. + + +Configure RCP (nRF21540-DK) + OT HOST (mimxrt1020) +-------------------------------------------------- + +.. code-block:: console + + ot factoryreset + ot dataset networkkey 00112233445566778899aabbccddeeff + ot ifconfig up + + +In the HOST PC www webpage interface please: +Commission -> Joiner PSKd* set to ``J01NME`` -> START COMMISSION + +.. code-block:: console + + ot joiner start J01NME + ot thread start + + +The ``ot ipaddr`` shall show IPv6 address starting from ``fd11:22:0:0:``. +This one can be accessed from HOST's PC network (via e.g. +``ping -6 fd11:22:0:0:e8bf:266b:63ca:eff4``). + +Start ``echo-server`` on HOST PC (x86-64) +----------------------------------------- + +.. code-block:: console + + ./echo-server -i otbr0 diff --git a/samples/net/sockets/echo_client/boards/frdm_mcxw71.conf b/samples/net/sockets/echo_client/boards/frdm_mcxw71.conf new file mode 100644 index 0000000000000..36b66408f8675 --- /dev/null +++ b/samples/net/sockets/echo_client/boards/frdm_mcxw71.conf @@ -0,0 +1,4 @@ +CONFIG_COUNTER=y + +CONFIG_OPENTHREAD_MAX_IP_ADDR_PER_CHILD=4 +CONFIG_OPENTHREAD_MAX_CHILDREN=30 diff --git a/samples/net/sockets/echo_client/boards/frdm_mcxw71.overlay b/samples/net/sockets/echo_client/boards/frdm_mcxw71.overlay new file mode 100644 index 0000000000000..71da6a25089fd --- /dev/null +++ b/samples/net/sockets/echo_client/boards/frdm_mcxw71.overlay @@ -0,0 +1,20 @@ +/* + * Copyright 2023-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&stcm { + ranges = <0x0 0x30000000 DT_SIZE_K(112)>; + + stcm1: system_memory@1a000 { + compatible = "zephyr,memory-region","mmio-sram"; + reg = <0x1a000 DT_SIZE_K(4)>; + zephyr,memory-region = "RetainedMem"; + }; +}; + +&stcm0 { + /* With only the first 64KB having ECC */ + reg = <0x0 DT_SIZE_K(108)>; +}; diff --git a/samples/net/sockets/echo_client/boards/mimxrt1020_evk.overlay b/samples/net/sockets/echo_client/boards/mimxrt1020_evk.overlay new file mode 100644 index 0000000000000..09743d6d61880 --- /dev/null +++ b/samples/net/sockets/echo_client/boards/mimxrt1020_evk.overlay @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024 DENX Software Engineering GmbH + * Lukasz Majewski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * imxrt1020_evk -> HOST + * nRF21540-DK -> RCP (nrf/samples/openthread/coprocessor) + * LPUART2 used for communication: + * nRF21540 (P6) P0.08 RXD -> IMXRT1020-EVK (J17) D1 (GPIO B1 08) (TXD) + * nRF21540 (P6) P0.07 CTS -> IMXRT1020-EVK (J19) D8 (GPIO B1 07) (RTS) + * nRF21540 (P6) P0.06 TXD -> IMXRT1020-EVK (J17) D0 (GPIO B1 09) (RXD) + * nRF21540 (P6) P0.05 RTS -> IMXRT1020-EVK (J17) D7 (GPIO B1 06) (CTS) + */ + +/** + * Overlay to enable support for OpenThread's RCP UART communication + * on the imxrt1020_evk board. + */ + +/ { + chosen { + zephyr,hdlc-rcp-if = &hdlc_rcp_if; + zephyr,ot-uart = &lpuart2; + }; + + hdlc_rcp_if: hdlc_rcp_if { + compatible = "uart,hdlc-rcp-if"; + }; +}; + +&lpuart2 { + status = "okay"; + current-speed = <1000000>; + pinctrl-0 = <&pinmux_lpuart2_flowcontrol>; + pinctrl-1 = <&pinmux_lpuart2_sleep>; + pinctrl-names = "default", "sleep"; + hw-flow-control; +}; + +/* + * The lpuart2's CTS pin is mapped to PHY's int-gpio or to SDRAM EMC 20. + * As SPINEL UART's implementation required CTS/RTS flow control - + * the PHY's mdio interrupt needs to be disabled. + */ +&phy { + /delete-property/ int-gpios; +}; + +&pinctrl { + pinmux_lpuart2_flowcontrol: pinmux_lpuart2_flowcontrol { + group0 { + pinmux = <&iomuxc_gpio_ad_b1_09_lpuart2_rx>, + <&iomuxc_gpio_ad_b1_08_lpuart2_tx>, + <&iomuxc_gpio_ad_b1_06_lpuart2_cts_b>, + <&iomuxc_gpio_ad_b1_07_lpuart2_rts_b>; + drive-strength = "r0-6"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + }; +}; + +/delete-node/ &{/soc/iomuxc@401f8000/pinctrl/pinmux_enet_mdio/group1}; diff --git a/samples/net/sockets/echo_client/overlay-ot-rcp-host-uart.conf b/samples/net/sockets/echo_client/overlay-ot-rcp-host-uart.conf new file mode 100644 index 0000000000000..b7e67b1ee0fb6 --- /dev/null +++ b/samples/net/sockets/echo_client/overlay-ot-rcp-host-uart.conf @@ -0,0 +1,60 @@ +CONFIG_REQUIRES_FULL_LIBC=y + +# CPP library +CONFIG_CPP=y + +# Disable TCP and IPv4 (TCP disabled to avoid heavy traffic) +CONFIG_NET_TCP=n +CONFIG_NET_IPV4=n + +CONFIG_NET_IPV6_NBR_CACHE=n +CONFIG_NET_IPV6_MLD=n +CONFIG_NET_CONFIG_NEED_IPV4=n +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="" + +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=32768 +CONFIG_INIT_STACKS=y + +# Enable OpenThread shell +CONFIG_SHELL=y +CONFIG_OPENTHREAD_SHELL=y +CONFIG_SHELL_STACK_SIZE=8192 + +CONFIG_NET_L2_OPENTHREAD=y + +# Use NVS as settings backend +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y + +# Enable Openthread rcp host +CONFIG_HDLC_RCP_IF=y + +# Enable OpenThread features set +CONFIG_OPENTHREAD_THREAD_STACK_SIZE=8192 +CONFIG_OPENTHREAD_THREAD_VERSION_1_3=y +#CONFIG_OPENTHREAD_DEBUG=y +#CONFIG_OPENTHREAD_L2_DEBUG=y +#CONFIG_OPENTHREAD_L2_LOG_LEVEL_INF=y + +# mbedTLS tweaks +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=768 + +# A sample configuration to enable Thread Joiner, uncomment if needed +CONFIG_OPENTHREAD_JOINER=y + +# Enable diagnostic module, uncomment if needed +#CONFIG_OPENTHREAD_DIAG=y + +# To have OTBR On-Mesh address assigned (fd11:22:0:0:) +CONFIG_OPENTHREAD_SLAAC=y + +# Setup the communication to echo-server +CONFIG_NET_CONFIG_PEER_IPV6_ADDR="fd11:db8:1::1" +CONFIG_NET_CONFIG_INIT_TIMEOUT=60 + +# Configure the OpenThread manually +CONFIG_OPENTHREAD_MANUAL_START=y + +CONFIG_EVENTS=y diff --git a/samples/net/sockets/echo_client/sample.yaml b/samples/net/sockets/echo_client/sample.yaml index 47d0b6364a61e..6ded48ae319f7 100644 --- a/samples/net/sockets/echo_client/sample.yaml +++ b/samples/net/sockets/echo_client/sample.yaml @@ -70,35 +70,27 @@ tests: sample.net.sockets.echo_client.nrf_802154: extra_args: EXTRA_CONF_FILE="overlay-802154.conf" platform_allow: nrf52840dk/nrf52840 - sample.net.sockets.echo_client.nrf_openthread: + sample.net.sockets.echo_client.openthread: extra_args: EXTRA_CONF_FILE="overlay-ot.conf" slow: true tags: - net - openthread - platform_allow: nrf52840dk/nrf52840 + platform_allow: + - frdm_kw41z + - frdm_mcxw71 + - nrf52840dk/nrf52840 + - tlsr9518adk80d filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_client.b91_802154: extra_args: EXTRA_CONF_FILE="overlay-802154.conf" platform_allow: tlsr9518adk80d - sample.net.sockets.echo_client.b91_openthread: - extra_args: EXTRA_CONF_FILE="overlay-ot.conf" - slow: true - tags: - - net - - openthread - platform_allow: tlsr9518adk80d - filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC - sample.net.sockets.echo_client.kw41z_openthread: - extra_args: EXTRA_CONF_FILE="overlay-ot.conf" - slow: true - tags: - - net - - openthread - platform_allow: frdm_kw41z - filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_client.rw612_openthread_rcp_host: - extra_args: OVERLAY_CONFIG="overlay-ot-rcp-host-nxp.conf" + build_only: true + extra_args: + # Disabling monolithic since CI environment doesn't use blobs + - CONFIG_NXP_MONOLITHIC_NBU=n + - OVERLAY_CONFIG="overlay-ot-rcp-host-nxp.conf" slow: true tags: - net diff --git a/samples/net/sockets/echo_client/src/vlan.c b/samples/net/sockets/echo_client/src/vlan.c index f7b96c9863ffe..7611ae096416d 100644 --- a/samples/net/sockets/echo_client/src/vlan.c +++ b/samples/net/sockets/echo_client/src/vlan.c @@ -85,6 +85,11 @@ int init_vlan(void) struct ud ud; int ret; + if (CONFIG_NET_VLAN_COUNT == 0) { + LOG_DBG("No VLAN interfaces defined."); + return 0; + } + iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET)); if (!iface) { LOG_ERR("No ethernet interfaces found."); diff --git a/samples/net/sockets/echo_server/boards/frdm_mcxw71.conf b/samples/net/sockets/echo_server/boards/frdm_mcxw71.conf new file mode 100644 index 0000000000000..36b66408f8675 --- /dev/null +++ b/samples/net/sockets/echo_server/boards/frdm_mcxw71.conf @@ -0,0 +1,4 @@ +CONFIG_COUNTER=y + +CONFIG_OPENTHREAD_MAX_IP_ADDR_PER_CHILD=4 +CONFIG_OPENTHREAD_MAX_CHILDREN=30 diff --git a/samples/net/sockets/echo_server/boards/frdm_mcxw71.overlay b/samples/net/sockets/echo_server/boards/frdm_mcxw71.overlay new file mode 100644 index 0000000000000..71da6a25089fd --- /dev/null +++ b/samples/net/sockets/echo_server/boards/frdm_mcxw71.overlay @@ -0,0 +1,20 @@ +/* + * Copyright 2023-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&stcm { + ranges = <0x0 0x30000000 DT_SIZE_K(112)>; + + stcm1: system_memory@1a000 { + compatible = "zephyr,memory-region","mmio-sram"; + reg = <0x1a000 DT_SIZE_K(4)>; + zephyr,memory-region = "RetainedMem"; + }; +}; + +&stcm0 { + /* With only the first 64KB having ECC */ + reg = <0x0 DT_SIZE_K(108)>; +}; diff --git a/samples/net/sockets/echo_server/sample.yaml b/samples/net/sockets/echo_server/sample.yaml index 65bec0267a391..9595e2444439f 100644 --- a/samples/net/sockets/echo_server/sample.yaml +++ b/samples/net/sockets/echo_server/sample.yaml @@ -88,32 +88,24 @@ tests: - native_sim/native/64 - native_posix - native_posix/native/64 - sample.net.sockets.echo_server.nrf_openthread: + sample.net.sockets.echo_server.openthread: extra_args: EXTRA_CONF_FILE="overlay-ot.conf" slow: true tags: - net - openthread - platform_allow: nrf52840dk/nrf52840 - filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC - sample.net.sockets.echo_server.b91_openthread: - extra_args: EXTRA_CONF_FILE="overlay-ot.conf" - slow: true - tags: - - net - - openthread - platform_allow: tlsr9518adk80d - filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC - sample.net.sockets.echo_server.kw41z_openthread: - extra_args: EXTRA_CONF_FILE="overlay-ot.conf" - slow: true - tags: - - net - - openthread - platform_allow: frdm_kw41z + platform_allow: + - frdm_kw41z + - frdm_mcxw71 + - nrf52840dk/nrf52840 + - tlsr9518adk80d filter: CONFIG_FULL_LIBC_SUPPORTED and not CONFIG_NATIVE_LIBC sample.net.sockets.echo_server.rw612_openthread_rcp_host: - extra_args: OVERLAY_CONFIG="overlay-ot-rcp-host-nxp.conf" + build_only: true + extra_args: + # Disabling monolithic since CI environment doesn't use blobs + - CONFIG_NXP_MONOLITHIC_NBU=n + - OVERLAY_CONFIG="overlay-ot-rcp-host-nxp.conf" slow: true tags: - net diff --git a/samples/net/sockets/echo_server/src/vlan.c b/samples/net/sockets/echo_server/src/vlan.c index b9a28d222c40c..1c70b91fe46b8 100644 --- a/samples/net/sockets/echo_server/src/vlan.c +++ b/samples/net/sockets/echo_server/src/vlan.c @@ -107,6 +107,11 @@ int init_vlan(void) struct ud ud; int ret; + if (CONFIG_NET_VLAN_COUNT == 0) { + LOG_DBG("No VLAN interfaces defined."); + return 0; + } + memset(&ud, 0, sizeof(ud)); net_if_foreach(iface_cb, &ud); diff --git a/samples/net/sockets/echo_server/src/ws_console/index.html b/samples/net/sockets/echo_server/src/ws_console/index.html index add412e3b4c96..a5381947bf10d 100644 --- a/samples/net/sockets/echo_server/src/ws_console/index.html +++ b/samples/net/sockets/echo_server/src/ws_console/index.html @@ -16,8 +16,8 @@ ws.onopen = function() { output("Connection opened"); connected = "true"; - // No need to print Escape codes for colors - ws.send("shell colors off\n"); + // No need to print escape codes + ws.send("shell colors off\nshell vt100 off\n"); }; ws.onmessage = function(e) { diff --git a/samples/net/sockets/echo_service/prj.conf b/samples/net/sockets/echo_service/prj.conf index 72cb9c21f05f1..a59d2f469e390 100644 --- a/samples/net/sockets/echo_service/prj.conf +++ b/samples/net/sockets/echo_service/prj.conf @@ -10,11 +10,8 @@ CONFIG_NET_IPV6=y CONFIG_NET_TCP=y CONFIG_NET_SOCKETS=y CONFIG_NET_IPV4_MAPPING_TO_IPV6=y -CONFIG_ZVFS_OPEN_MAX=10 CONFIG_NET_MAX_CONN=5 CONFIG_NET_SOCKETS_SERVICE=y -CONFIG_ZVFS_OPEN_MAX=20 -CONFIG_ZVFS_POLL_MAX=20 # Network driver config CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/samples/net/sockets/http_get/Kconfig b/samples/net/sockets/http_get/Kconfig new file mode 100644 index 0000000000000..1fd79445866fa --- /dev/null +++ b/samples/net/sockets/http_get/Kconfig @@ -0,0 +1,8 @@ +# +# Copyright (c) 2025 Ezurio +# +# SPDX-License-Identifier: Apache-2.0 +# + +source "samples/net/common/Kconfig" +source "Kconfig.zephyr" diff --git a/samples/net/sockets/http_get/overlay-hl7800.conf b/samples/net/sockets/http_get/overlay-hl7800.conf new file mode 100644 index 0000000000000..d941052c89fca --- /dev/null +++ b/samples/net/sockets/http_get/overlay-hl7800.conf @@ -0,0 +1,15 @@ +# The HL7800 driver gets its IP settings from the cell network +CONFIG_DNS_SERVER_IP_ADDRESSES=n +CONFIG_NET_CONFIG_SETTINGS=n +# Wait for the network to be ready +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_NET_SAMPLE_COMMON_WAIT_DNS_SERVER_ADDITION=y +# NB-IoT has large latency, so increase timeouts. It is ok to use this for Cat-M1 as well. +CONFIG_NET_SOCKETS_DNS_TIMEOUT=12000 +CONFIG_NET_SOCKETS_CONNECT_TIMEOUT=15000 + +# CONFIG_MODEM_LOG_LEVEL_DBG=y +# CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=1 +# CONFIG_LOG_BUFFER_SIZE=20000 +# CONFIG_MODEM_HL7800_SET_APN_NAME_ON_STARTUP=y +# CONFIG_MODEM_HL7800_APN_NAME="VZWINTERNET" diff --git a/samples/net/sockets/http_get/overlay-tls.conf b/samples/net/sockets/http_get/overlay-tls.conf index 0cf82f18cf857..70da57986639c 100644 --- a/samples/net/sockets/http_get/overlay-tls.conf +++ b/samples/net/sockets/http_get/overlay-tls.conf @@ -10,3 +10,7 @@ CONFIG_MBEDTLS_HASH_ALL_ENABLED=y CONFIG_MBEDTLS_CMAC=y CONFIG_NET_SOCKETS_SOCKOPT_TLS=y + +# Debugging options +#CONFIG_MBEDTLS_DEBUG=y +#CONFIG_MBEDTLS_LOG_LEVEL_DBG=y diff --git a/samples/net/sockets/http_get/sample.yaml b/samples/net/sockets/http_get/sample.yaml index 269fbc3bd3db6..d30583f7a84b3 100644 --- a/samples/net/sockets/http_get/sample.yaml +++ b/samples/net/sockets/http_get/sample.yaml @@ -58,6 +58,6 @@ tests: sample.net.sockets.http_get.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/sockets/http_get/src/http_get.c b/samples/net/sockets/http_get/src/http_get.c index b4ad0ff8410ce..81b268fe533a0 100644 --- a/samples/net/sockets/http_get/src/http_get.c +++ b/samples/net/sockets/http_get/src/http_get.c @@ -40,11 +40,10 @@ /* HTTP path to request */ #define HTTP_PATH "/" - #define SSTRLEN(s) (sizeof(s) - 1) -#define CHECK(r) { if (r == -1) { printf("Error: " #r "\n"); exit(1); } } +#define CHECK(r) { if (r < 0) { printf("Error: %d\n", (int)r); exit(1); } } -#define REQUEST "GET " HTTP_PATH " HTTP/1.0\r\nHost: " HTTP_HOST "\r\n\r\n" +#define REQUEST "GET " HTTP_PATH " HTTP/1.1\r\nHost: " HTTP_HOST "\r\n\r\n" static char response[1024]; @@ -52,9 +51,8 @@ void dump_addrinfo(const struct addrinfo *ai) { printf("addrinfo @%p: ai_family=%d, ai_socktype=%d, ai_protocol=%d, " "sa_family=%d, sin_port=%x\n", - ai, ai->ai_family, ai->ai_socktype, ai->ai_protocol, - ai->ai_addr->sa_family, - ((struct sockaddr_in *)ai->ai_addr)->sin_port); + ai, ai->ai_family, ai->ai_socktype, ai->ai_protocol, ai->ai_addr->sa_family, + ntohs(((struct sockaddr_in *)ai->ai_addr)->sin_port)); } int main(void) @@ -110,7 +108,9 @@ int main(void) HTTP_HOST, sizeof(HTTP_HOST))) #endif + printf("Connecting to server...\n"); CHECK(connect(sock, res->ai_addr, res->ai_addrlen)); + printf("Connected!\r\nSending request...\n"); CHECK(send(sock, REQUEST, SSTRLEN(REQUEST), 0)); printf("Response:\n\n"); @@ -131,7 +131,7 @@ int main(void) printf("%s", response); } - printf("\n"); + printf("\nClose socket\n"); (void)close(sock); return 0; diff --git a/samples/net/sockets/http_server/CMakeLists.txt b/samples/net/sockets/http_server/CMakeLists.txt index b4853257c786f..b860f8a07ce6b 100644 --- a/samples/net/sockets/http_server/CMakeLists.txt +++ b/samples/net/sockets/http_server/CMakeLists.txt @@ -20,6 +20,20 @@ if(CONFIG_NET_SOCKETS_SOCKOPT_TLS AND add_dependencies(app development_psk) endif() +set(CERTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/certs) + +add_custom_target(sample_ca_cert + WORKING_DIRECTORY ${CERTS_DIR} + COMMAND sh gen_ca_cert.sh + COMMENT "Generating sample CA certificate" +) + +add_custom_target(sample_server_cert + WORKING_DIRECTORY ${CERTS_DIR} + COMMAND sh gen_server_cert.sh + COMMENT "Generating sample server certificate" +) + option(INCLUDE_HTML_CONTENT "Include the HTML content" ON) target_sources(app PRIVATE src/main.c) @@ -54,15 +68,12 @@ foreach(web_resource endforeach() foreach(inc_file - ca.der - server.der + server_cert.der server_privkey.der - https-server-cert.der - https-server-key.der ) generate_inc_file_for_target( app - src/${inc_file} + src/certs/${inc_file} ${gen_dir}/${inc_file}.inc ) endforeach() diff --git a/samples/net/sockets/http_server/Kconfig b/samples/net/sockets/http_server/Kconfig index db09c5b261efc..1accd28594109 100644 --- a/samples/net/sockets/http_server/Kconfig +++ b/samples/net/sockets/http_server/Kconfig @@ -17,12 +17,30 @@ config NET_SAMPLE_HTTP_SERVER_SERVICE_PORT config NET_SAMPLE_HTTPS_SERVICE bool "Enable https service" depends on NET_SOCKETS_SOCKOPT_TLS || TLS_CREDENTIALS + imply MBEDTLS_PSA_CRYPTO_C if !BUILD_WITH_TFM + +if NET_SAMPLE_HTTPS_SERVICE config NET_SAMPLE_HTTPS_SERVER_SERVICE_PORT int "Port number for https service" default 443 depends on NET_SAMPLE_HTTPS_SERVICE +config NET_SAMPLE_HTTPS_USE_ALPN + bool "Allow HTTP2 connectivity with web browsers by using ALPN" + select MBEDTLS_SSL_ALPN + select HTTP_SERVER_TLS_USE_ALPN + help + Web browsers only use HTTP/2 over HTTPS, and use ALPN to determine if a + server supports HTTP/2. If this option is enabled, web browsers can use + HTTP/2 to communicate with the server. However web browsers are stricter + with security when using HTTP/2, at a minimum you will need to add the CA + certificate used to sign the server certificate into your web browser's + trusted authorities. Otherwise the connection can fail with a security + error, without giving an option to ignore this and proceed anyway. + +endif # NET_SAMPLE_HTTPS_SERVICE + config NET_SAMPLE_PSK_HEADER_FILE string "Header file containing PSK" default "dummy_psk.h" @@ -31,13 +49,6 @@ config NET_SAMPLE_PSK_HEADER_FILE Name of a header file containing a pre-shared key. -config NET_SAMPLE_CERTS_WITH_SC - bool "Signed certificates" - depends on NET_SOCKETS_SOCKOPT_TLS - help - Enable this flag, if you are interested to run this - application with signed certificates and keys. - config NET_SAMPLE_WEBSOCKET_SERVICE bool "Enable websocket service" default y if HTTP_SERVER_WEBSOCKET diff --git a/samples/net/sockets/http_server/README.rst b/samples/net/sockets/http_server/README.rst index 33c2f2874e45c..e7f1771be29c3 100644 --- a/samples/net/sockets/http_server/README.rst +++ b/samples/net/sockets/http_server/README.rst @@ -34,12 +34,21 @@ There are configuration files for various setups in the * - :zephyr_file:`overlay-netusb.conf ` - This overlay config can be added for connecting via network USB. -To build and run the application: + * - :zephyr_file:`overlay-tls.conf ` + - This overlay config can be added to build the HTTPS variant. + +To build and run the HTTP server application: .. code-block:: bash $ west build -p auto -b -t run samples/net/sockets/http_server +For the HTTPS version: + +.. code-block:: bash + + $ west build -p auto -b -t run --test samples/net/sockets/http_server/sample.net.sockets.https.server + When the server is up, we can make requests to the server using either HTTP/1.1 or HTTP/2 protocol from the host machine. @@ -55,6 +64,36 @@ HTTP/2 protocol from the host machine. - Using curl: ``curl --http2 -v --compressed http://192.0.2.1/`` - Using h2load: ``h2load -n10 http://192.0.2.1/`` +Web browsers use stricter security settings for the HTTP/2 protocol. So to use HTTP/2 +with a web browser, you must ALPN (add ``-DCONFIG_NET_SAMPLE_HTTPS_USE_ALPN`` to +the west build command) on top of the HTTPS build shown above. +Additionally the server certificate must be signed by a CA certificate trusted +by your browser. + +The best way to do this is to generate your own CA certificate: + +.. code-block:: bash + + $ west build -b -t sample_ca_cert samples/net/sockets/http_server + +Generate a server certificate signed by this CA certificate: + +.. code-block:: bash + + $ west build -t sample_server_cert samples/net/sockets/http_server + +And then build the application with the newly generated server certificate and key: + +.. code-block:: bash + + $ west build samples/net/sockets/http_server + +The CA certificate should be added to your browser's list of trusted authorities to +enable usage of HTTP/2. If using Firefox, it may also be required to change the setting +``network.http.http2.enforce-tls-profile`` to false, since it seems that using a CA +certificate issued by an authority unknown to Firefox is considered a security error when +using HTTP/2. + Server Customization --------------------- @@ -108,6 +147,61 @@ connectivity. ws.close() +Testing over USB +---------------- + +Let's see a real example on how the HTTP(S) server can be tested on a real device +using an USB connection toward a Linux host PC. For this purpose let's take an +NRF52840 board as example. + +First of all build the sample enabling HTTPS service and flash the board: + +.. zephyr-app-commands:: + :zephyr-app: samples/net/sockets/http_server/ + :board: nrf52840dk/nrf52840 + :goals: build + :gen-args: -DCONFIG_NET_SAMPLE_HTTPS_SERVICE=y -DEXTRA_CONF_FILE=overlay-netusb.conf + +Then connect the USB cable to the host PC and issue: + +.. code-block:: bash + + $ ip link show + +to get the device name Linux assigned to the USB-Ethernet interface. For the +following let's assume that the name is ``eth-device``. + +Now we need to configure IP and routing for this interface: + +.. code-block:: bash + + $ sudo ip addr add 192.0.2.2/24 dev eth-device + $ sudo ip route add 192.0.2.0/24 dev eth-device + +Here: + +* we picked an IP address for the interface, i.e. ``192.0.2.2/24``, which is + different form the server one, i.e. :kconfig:option:`CONFIG_NET_CONFIG_MY_IPV4_ADDR`, + but in the allowed IP range defined by the ``/24`` mask. +* we assume that 192.168.0.x range do not conflict with other addresses and + routes in the host system. If that's the case, then all IP addresses should + be fixed (sample, host IP interface, certificate). + +Once this is done, it should be possible to test either HTTP and HTTPS with +``curl``: + +.. code-block:: bash + + $ curl -v --compressed http://192.0.2.1 + $ curl -v --compressed https://192.0.2.1 + +.. note:: + + To have a successful HTTPS connection ensure to update the CA certificates + of the host Linux system adding + :zephyr_file:`samples/net/sockets/http_server/src/certs/ca_cert.pem` to the + list of known CAs. + Performance Analysis -------------------- diff --git a/samples/net/sockets/http_server/overlay-tls.conf b/samples/net/sockets/http_server/overlay-tls.conf new file mode 100644 index 0000000000000..b35ab7fcf2726 --- /dev/null +++ b/samples/net/sockets/http_server/overlay-tls.conf @@ -0,0 +1,26 @@ +CONFIG_NET_SAMPLE_HTTPS_SERVICE=y + +# TLS configuration +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_BUILTIN=y +CONFIG_MBEDTLS_ENABLE_HEAP=y +CONFIG_MBEDTLS_HEAP_SIZE=60000 +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048 +CONFIG_NET_SOCKETS_SOCKOPT_TLS=y +CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=6 +CONFIG_TLS_CREDENTIALS=y +CONFIG_TLS_MAX_CREDENTIALS_NUMBER=5 +CONFIG_PSA_WANT_ALG_ECDH=y +CONFIG_PSA_WANT_ALG_ECDSA=y +CONFIG_PSA_WANT_ECC_SECP_R1_256=y +CONFIG_PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY=y +CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT=y +CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT=y +CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y +CONFIG_PSA_WANT_ALG_CCM=y +CONFIG_PSA_WANT_ALG_GCM=y +CONFIG_MBEDTLS_PK_WRITE_C=y +CONFIG_PSA_WANT_ALG_TLS12_PRF=y +CONFIG_PSA_WANT_ALG_SHA_1=y +CONFIG_PSA_WANT_ALG_SHA_256=y diff --git a/samples/net/sockets/http_server/prj.conf b/samples/net/sockets/http_server/prj.conf index aa04b93f22376..5cfe2a04ad297 100644 --- a/samples/net/sockets/http_server/prj.conf +++ b/samples/net/sockets/http_server/prj.conf @@ -58,18 +58,6 @@ CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" -# TLS configuration -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_BUILTIN=y -CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=60000 -CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048 -CONFIG_MBEDTLS_USE_PSA_CRYPTO=n -CONFIG_NET_SOCKETS_SOCKOPT_TLS=y -CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=6 -CONFIG_TLS_CREDENTIALS=y -CONFIG_TLS_MAX_CREDENTIALS_NUMBER=5 - # Networking tweaks # Required to handle large number of consecutive connections, # e.g. when testing with ApacheBench. diff --git a/samples/net/sockets/http_server/sample.yaml b/samples/net/sockets/http_server/sample.yaml index 8af05127cd4b4..5a2413e62a2ae 100644 --- a/samples/net/sockets/http_server/sample.yaml +++ b/samples/net/sockets/http_server/sample.yaml @@ -13,5 +13,8 @@ common: platform_exclude: - native_posix - native_posix/native/64 + - nrf5340dk/nrf5340/cpuapp/ns # Excluding due to ROM overflow. tests: sample.net.sockets.http.server: {} + sample.net.sockets.https.server: + extra_args: EXTRA_CONF_FILE="overlay-tls.conf" diff --git a/samples/net/sockets/http_server/src/ca.der b/samples/net/sockets/http_server/src/ca.der deleted file mode 100644 index b1d3e097cadce..0000000000000 Binary files a/samples/net/sockets/http_server/src/ca.der and /dev/null differ diff --git a/samples/net/sockets/http_server/src/certificate.h b/samples/net/sockets/http_server/src/certificate.h index 52a3fa9c8ea18..eea583b892982 100644 --- a/samples/net/sockets/http_server/src/certificate.h +++ b/samples/net/sockets/http_server/src/certificate.h @@ -8,40 +8,20 @@ #define __CERTIFICATE_H__ enum tls_tag { - /** The Certificate Authority public key */ - HTTP_SERVER_CA_CERTIFICATE_TAG, /** Used for both the public and private server keys */ HTTP_SERVER_CERTIFICATE_TAG, - /** Used for both the public and private client keys */ - HTTP_SERVER_CLIENT_CERTIFICATE_TAG, + /* Used for pre-shared key */ PSK_TAG, }; -#if !defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) static const unsigned char server_certificate[] = { -#include "https-server-cert.der.inc" -}; - -/* This is the private key in pkcs#8 format. */ -static const unsigned char private_key[] = { -#include "https-server-key.der.inc" -}; - -#else - -static const unsigned char ca_certificate[] = { -#include "ca.der.inc" -}; - -static const unsigned char server_certificate[] = { -#include "server.der.inc" +#include "server_cert.der.inc" }; /* This is the private key in pkcs#8 format. */ static const unsigned char private_key[] = { #include "server_privkey.der.inc" }; -#endif #if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) #include CONFIG_NET_SAMPLE_PSK_HEADER_FILE diff --git a/samples/net/sockets/http_server/src/certs/.gitignore b/samples/net/sockets/http_server/src/certs/.gitignore new file mode 100644 index 0000000000000..96aff7026ab79 --- /dev/null +++ b/samples/net/sockets/http_server/src/certs/.gitignore @@ -0,0 +1,3 @@ +*.pem +!ca_cert.pem +*.ext diff --git a/samples/net/sockets/http_server/src/certs/ca_cert.der b/samples/net/sockets/http_server/src/certs/ca_cert.der new file mode 100644 index 0000000000000..d2d00cd84115a Binary files /dev/null and b/samples/net/sockets/http_server/src/certs/ca_cert.der differ diff --git a/samples/net/sockets/http_server/src/certs/ca_cert.pem b/samples/net/sockets/http_server/src/certs/ca_cert.pem new file mode 100644 index 0000000000000..38ea9d14c99d8 --- /dev/null +++ b/samples/net/sockets/http_server/src/certs/ca_cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5DCCAYmgAwIBAgIUXHpFEmhwtzDyteoz+ZSOhyQ6xzUwCgYIKoZIzj0EAwIw +RjEWMBQGA1UECgwNWmVwaHlycHJvamVjdDEsMCoGA1UEAwwjWmVwaHlycHJvamVj +dCBTYW1wbGUgRGV2ZWxvcG1lbnQgQ0EwIBcNMjQxMTI3MTE1ODUwWhgPMjEyNDEx +MDMxMTU4NTBaMEYxFjAUBgNVBAoMDVplcGh5cnByb2plY3QxLDAqBgNVBAMMI1pl +cGh5cnByb2plY3QgU2FtcGxlIERldmVsb3BtZW50IENBMFkwEwYHKoZIzj0CAQYI +KoZIzj0DAQcDQgAEvCX35MoLVdt4STWeomwFjuLV8nAz+K1IIc5PrfD9nVhLZfOS +Z35O9dTEMvn1dP2MqUqjL6wWA3oSnvItU81qD6NTMFEwHQYDVR0OBBYEFNFC9qd/ +SSYq7aDvLGsc4Fu7Fn5cMB8GA1UdIwQYMBaAFNFC9qd/SSYq7aDvLGsc4Fu7Fn5c +MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhALWzu1PtNJYu9sWb +A2iBixJuoK7y8EqCkGDp0e66mA+qAiEAyz7YdO7zhcHWgaUXqLwlVqe5cstVMsLv +4TbLwQi+wfI= +-----END CERTIFICATE----- diff --git a/samples/net/sockets/http_server/src/certs/gen_ca_cert.sh b/samples/net/sockets/http_server/src/certs/gen_ca_cert.sh new file mode 100644 index 0000000000000..e2e38e3803953 --- /dev/null +++ b/samples/net/sockets/http_server/src/certs/gen_ca_cert.sh @@ -0,0 +1,17 @@ +# Copyright (c) 2024, Witekio +# SPDX-License-Identifier: Apache-2.0 + +# Generate a root CA private key +openssl ecparam \ + -name prime256v1 \ + -genkey \ + -out ca_privkey.pem + +# Generate a root CA certificate using private key +openssl req \ + -new \ + -x509 \ + -days 36500 \ + -key ca_privkey.pem \ + -out ca_cert.pem \ + -subj "/O=Zephyrproject/CN=Zephyrproject Sample Development CA" diff --git a/samples/net/sockets/http_server/src/certs/gen_server_cert.sh b/samples/net/sockets/http_server/src/certs/gen_server_cert.sh new file mode 100644 index 0000000000000..a088e708db2ac --- /dev/null +++ b/samples/net/sockets/http_server/src/certs/gen_server_cert.sh @@ -0,0 +1,48 @@ +# Copyright (c) 2024, Witekio +# SPDX-License-Identifier: Apache-2.0 + +# Generate a server private key +openssl ecparam \ + -name prime256v1 \ + -genkey \ + -out server_privkey.pem + +# Generate a certificate signing request using server key +openssl req \ + -new \ + -sha256 \ + -key server_privkey.pem \ + -out server_csr.pem \ + -subj "/O=Zephyrproject/CN=zephyr" + +# Create a file containing server CSR extensions +echo "subjectKeyIdentifier=hash" > server_csr.ext +echo "authorityKeyIdentifier=keyid,issuer" >> server_csr.ext +echo "basicConstraints=critical,CA:FALSE" >> server_csr.ext +echo "keyUsage=critical,digitalSignature" >> server_csr.ext +echo "extendedKeyUsage=serverAuth" >> server_csr.ext +echo "subjectAltName=DNS:zephyr.local,IP.1:192.0.2.1,IP.2:2001:db8::1" >> server_csr.ext + +# Create a server certificate by signing the server CSR using the CA cert/key +openssl x509 \ + -req \ + -sha256 \ + -CA ca_cert.pem \ + -CAkey ca_privkey.pem \ + -days 36500 \ + -CAcreateserial \ + -CAserial ca.srl \ + -in server_csr.pem \ + -out server_cert.pem \ + -extfile server_csr.ext + +# Create DER encoded versions of server certificate and private key +openssl ec \ + -outform der \ + -in server_privkey.pem \ + -out server_privkey.der + +openssl x509 \ + -outform der \ + -in server_cert.pem \ + -out server_cert.der diff --git a/samples/net/sockets/http_server/src/certs/server_cert.der b/samples/net/sockets/http_server/src/certs/server_cert.der new file mode 100644 index 0000000000000..35b47f4487d90 Binary files /dev/null and b/samples/net/sockets/http_server/src/certs/server_cert.der differ diff --git a/samples/net/sockets/http_server/src/certs/server_privkey.der b/samples/net/sockets/http_server/src/certs/server_privkey.der new file mode 100644 index 0000000000000..5e6ab5bd1f40b Binary files /dev/null and b/samples/net/sockets/http_server/src/certs/server_privkey.der differ diff --git a/samples/net/sockets/http_server/src/https-server-cert.der b/samples/net/sockets/http_server/src/https-server-cert.der deleted file mode 100644 index bfcb335e31c8c..0000000000000 Binary files a/samples/net/sockets/http_server/src/https-server-cert.der and /dev/null differ diff --git a/samples/net/sockets/http_server/src/https-server-key.der b/samples/net/sockets/http_server/src/https-server-key.der deleted file mode 100644 index 5a4d67372ea41..0000000000000 Binary files a/samples/net/sockets/http_server/src/https-server-key.der and /dev/null differ diff --git a/samples/net/sockets/http_server/src/main.c b/samples/net/sockets/http_server/src/main.c index 23ab975cd6cd5..1341a91169be3 100644 --- a/samples/net/sockets/http_server/src/main.c +++ b/samples/net/sockets/http_server/src/main.c @@ -248,7 +248,7 @@ struct http_resource_detail_websocket ws_netstats_resource_detail = { #if defined(CONFIG_NET_SAMPLE_HTTP_SERVICE) static uint16_t test_http_service_port = CONFIG_NET_SAMPLE_HTTP_SERVER_SERVICE_PORT; HTTP_SERVICE_DEFINE(test_http_service, NULL, &test_http_service_port, 1, - 10, NULL); + 10, NULL, NULL); HTTP_RESOURCE_DEFINE(index_html_gz_resource, test_http_service, "/", &index_html_gz_resource_detail); @@ -281,7 +281,7 @@ static const sec_tag_t sec_tag_list_verify_none[] = { static uint16_t test_https_service_port = CONFIG_NET_SAMPLE_HTTPS_SERVER_SERVICE_PORT; HTTPS_SERVICE_DEFINE(test_https_service, NULL, - &test_https_service_port, 1, 10, NULL, + &test_https_service_port, 1, 10, NULL, NULL, sec_tag_list_verify_none, sizeof(sec_tag_list_verify_none)); HTTP_RESOURCE_DEFINE(index_html_gz_resource_https, test_https_service, "/", @@ -311,16 +311,6 @@ static void setup_tls(void) #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) int err; -#if defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) - err = tls_credential_add(HTTP_SERVER_CERTIFICATE_TAG, - TLS_CREDENTIAL_CA_CERTIFICATE, - ca_certificate, - sizeof(ca_certificate)); - if (err < 0) { - LOG_ERR("Failed to register CA certificate: %d", err); - } -#endif /* defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) */ - err = tls_credential_add(HTTP_SERVER_CERTIFICATE_TAG, TLS_CREDENTIAL_SERVER_CERTIFICATE, server_certificate, diff --git a/samples/net/sockets/http_server/src/server.der b/samples/net/sockets/http_server/src/server.der deleted file mode 100644 index 2b664a4bdb2ce..0000000000000 Binary files a/samples/net/sockets/http_server/src/server.der and /dev/null differ diff --git a/samples/net/sockets/http_server/src/server_privkey.der b/samples/net/sockets/http_server/src/server_privkey.der deleted file mode 100644 index 2269293fe790f..0000000000000 Binary files a/samples/net/sockets/http_server/src/server_privkey.der and /dev/null differ diff --git a/samples/net/sockets/http_server/src/ws.c b/samples/net/sockets/http_server/src/ws.c index 7215aeefb62b4..1338e437419d1 100644 --- a/samples/net/sockets/http_server/src/ws.c +++ b/samples/net/sockets/http_server/src/ws.c @@ -295,7 +295,7 @@ int ws_netstats_init(void) } SYS_INIT(ws_netstats_init, APPLICATION, 0); -int ws_echo_setup(int ws_socket, void *user_data) +int ws_echo_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data) { int slot; @@ -331,7 +331,7 @@ int ws_echo_setup(int ws_socket, void *user_data) return 0; } -int ws_netstats_setup(int ws_socket, void *user_data) +int ws_netstats_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data) { int ret; int slot; diff --git a/samples/net/sockets/http_server/src/ws.h b/samples/net/sockets/http_server/src/ws.h index 85ba61bbe1677..0afdd6287f095 100644 --- a/samples/net/sockets/http_server/src/ws.h +++ b/samples/net/sockets/http_server/src/ws.h @@ -4,22 +4,26 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + /** * @brief Setup websocket for echoing data back to client * * @param ws_socket Socket file descriptor associated with websocket + * @param request_ctx Request context associated with websocket HTTP upgrade request * @param user_data User data pointer * * @return 0 on success */ -int ws_echo_setup(int ws_socket, void *user_data); +int ws_echo_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data); /** * @brief Setup websocket for sending net statistics to client * * @param ws_socket Socket file descriptor associated with websocket + * @param request_ctx Request context associated with websocket HTTP upgrade request * @param user_data User data pointer * * @return 0 on success */ -int ws_netstats_setup(int ws_socket, void *user_data); +int ws_netstats_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data); diff --git a/samples/net/sockets/sntp_client/sample.yaml b/samples/net/sockets/sntp_client/sample.yaml index 762da6d00007b..81d5fc6e95ba4 100644 --- a/samples/net/sockets/sntp_client/sample.yaml +++ b/samples/net/sockets/sntp_client/sample.yaml @@ -12,6 +12,6 @@ tests: sample.net.sockets.sntp_client.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/sockets/txtime/src/vlan.c b/samples/net/sockets/txtime/src/vlan.c index 8eee42161dede..04b28e427e365 100644 --- a/samples/net/sockets/txtime/src/vlan.c +++ b/samples/net/sockets/txtime/src/vlan.c @@ -99,6 +99,11 @@ int init_vlan(void) struct ud ud; int ret; + if (CONFIG_NET_VLAN_COUNT == 0) { + LOG_DBG("No VLAN interfaces defined."); + return 0; + } + iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET)); if (!iface) { LOG_ERR("No ethernet interfaces found."); diff --git a/samples/net/syslog_net/prj.conf b/samples/net/syslog_net/prj.conf index 7bd3870b43142..46a0276a8201a 100644 --- a/samples/net/syslog_net/prj.conf +++ b/samples/net/syslog_net/prj.conf @@ -35,7 +35,5 @@ CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" # logging net backend config CONFIG_LOG_BACKEND_NET=y +CONFIG_POSIX_C_LANG_SUPPORT_R=y CONFIG_LOG_BACKEND_NET_SERVER="[2001:db8::2]:514" - -# Get a proper libc by default in order to get working time function support -CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/net/syslog_net/sample.yaml b/samples/net/syslog_net/sample.yaml index 7770f1ea80b0c..a68f3b1bb5444 100644 --- a/samples/net/syslog_net/sample.yaml +++ b/samples/net/syslog_net/sample.yaml @@ -40,6 +40,6 @@ tests: sample.net.syslog.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/telnet/sample.yaml b/samples/net/telnet/sample.yaml index 508b76fe4f6ed..5dd685e6bf36a 100644 --- a/samples/net/telnet/sample.yaml +++ b/samples/net/telnet/sample.yaml @@ -14,6 +14,6 @@ tests: sample.net.telnet.wifi.nrf70dk: extra_args: - SNIPPET=wifi-ipv4 - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/wifi/apsta_mode/README.rst b/samples/net/wifi/apsta_mode/README.rst index 38f5c1c2e7c37..06a6b46381eaf 100644 --- a/samples/net/wifi/apsta_mode/README.rst +++ b/samples/net/wifi/apsta_mode/README.rst @@ -40,7 +40,7 @@ Building, Flashing and Running ****************************** .. zephyr-app-commands:: - :zephyr-app: samples/boards/espressif/deep_sleep + :zephyr-app: samples/net/wifi/apsta_mode :board: esp32_devkitc_wroom/esp32/procpu :goals: build flash :compact: diff --git a/samples/net/wifi/shell/boards/frdm_rw612.conf b/samples/net/wifi/shell/boards/frdm_rw612.conf index 8f40dd471fabd..7ea696cf074ac 100644 --- a/samples/net/wifi/shell/boards/frdm_rw612.conf +++ b/samples/net/wifi/shell/boards/frdm_rw612.conf @@ -20,7 +20,6 @@ CONFIG_LOG_PRINTK=n CONFIG_THREAD_CUSTOM_DATA=y CONFIG_EVENTS=y CONFIG_SYS_HEAP_AUTO=y -CONFIG_HEAP_MEM_POOL_SIZE=122880 CONFIG_SCHED_MULTIQ=y CONFIG_ZVFS_OPEN_MAX=30 @@ -32,18 +31,19 @@ CONFIG_SHELL_CMD_BUFF_SIZE=512 # net CONFIG_NET_L2_ETHERNET=y -CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT=32 CONFIG_NET_IPV4=y CONFIG_NET_IPV6=y CONFIG_ETH_MCUX=n CONFIG_NET_ZPERF=y CONFIG_NET_ZPERF_MAX_PACKET_SIZE=1500 CONFIG_NET_BUF_LOG=y -CONFIG_NET_PKT_RX_COUNT=60 -CONFIG_NET_PKT_TX_COUNT=40 -CONFIG_NET_BUF_RX_COUNT=60 -CONFIG_NET_BUF_TX_COUNT=80 +CONFIG_NET_PKT_RX_COUNT=36 +CONFIG_NET_PKT_TX_COUNT=36 +CONFIG_NET_BUF_RX_COUNT=40 +CONFIG_NET_BUF_TX_COUNT=40 CONFIG_NET_BUF_DATA_SIZE=1744 +CONFIG_NET_TCP_MAX_SEND_WINDOW_SIZE=46720 +CONFIG_NET_TCP_MAX_RECV_WINDOW_SIZE=46720 CONFIG_NET_TC_TX_COUNT=1 CONFIG_NET_TC_RX_COUNT=1 CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=20 @@ -62,7 +62,6 @@ CONFIG_NET_IPV6_FRAGMENT_MAX_COUNT=3 CONFIG_NET_IPV6_FRAGMENT_MAX_PKT=8 CONFIG_NET_IPV6_FRAGMENT_TIMEOUT=3 CONFIG_NET_MAX_CONN=10 -CONFIG_NET_DHCPV4_SERVER_ICMP_PROBE_TIMEOUT=100 CONFIG_ETH_DRIVER=n # net threads priority @@ -73,40 +72,11 @@ CONFIG_NET_TC_TX_THREAD_BASE_PRIO=3 CONFIG_NET_TC_RX_THREAD_BASE_PRIO=3 CONFIG_ZPERF_WORK_Q_THREAD_PRIORITY=3 CONFIG_NET_SOCKETS_SERVICE_THREAD_PRIO=3 -CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO=y +CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO=y CONFIG_NET_CONTEXT_PRIORITY=y CONFIG_NET_MGMT_THREAD_PRIO_CUSTOM=y CONFIG_NET_MGMT_THREAD_PRIORITY=3 -CONFIG_WIFI_NM_WPA_SUPPLICANT=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_CLI=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_EAPOL=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_INF_MON=n -CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES=2 -CONFIG_SAE_PWE_EARLY_EXIT=y -CONFIG_WIFI_NM_HOSTAPD_AP=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS=y -CONFIG_WIFI_NM_HOSTAPD_WPS=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_ROAMING=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_SKIP_DHCP_ON_ROAMING=y -CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE=y - -# Enable mbedtls -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_BUILTIN=y -CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y -CONFIG_MBEDTLS_USER_CONFIG_FILE="wpa_supp_els_pkc_mbedtls_config.h" - -# Include els_pkc in build -CONFIG_ENTROPY_GENERATOR=y -CONFIG_MBEDTLS_PSA_CRYPTO_C=y -CONFIG_MBEDTLS_ENTROPY_C=y -CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=8192 - # power management CONFIG_PM=y CONFIG_PM_DEVICE=y @@ -121,8 +91,6 @@ CONFIG_NET_MGMT_EVENT_STACK_SIZE=4608 CONFIG_NET_TCP_WORKQ_STACK_SIZE=2048 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_NET_SOCKETS_SERVICE_STACK_SIZE=4096 -CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE=12288 -CONFIG_WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE=12288 # optimization level # refer to Kconfig.zephyr for Optimizations Level @@ -150,14 +118,7 @@ CONFIG_NET_STATISTICS_USER_API=y #CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 #CONFIG_ZPERF_WORK_Q_STACK_SIZE=4096 #CONFIG_MAIN_STACK_SIZE=4096 -#CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE=16384 -#CONFIG_WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE=16384 #CONFIG_IDLE_STACK_SIZE=2048 # comment out for -O0 CONFIG_CODE_DATA_RELOCATION_SRAM=y -#CONFIG_WIFI_NM_WPA_SUPPLICANT_DEBUG_LEVEL=2 -CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_INF=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_PRIO=3 -CONFIG_WIFI_NM_WPA_SUPPLICANT_PRIO=3 -CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=80000 diff --git a/samples/net/wifi/shell/boards/overlay_hostap_rw612.conf b/samples/net/wifi/shell/boards/overlay_hostap_rw612.conf new file mode 100644 index 0000000000000..694ccc1353404 --- /dev/null +++ b/samples/net/wifi/shell/boards/overlay_hostap_rw612.conf @@ -0,0 +1,41 @@ +# wpa_supplicant +CONFIG_WIFI_NM_WPA_SUPPLICANT=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_CLI=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_EAPOL=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_INF_MON=n +CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES=2 +CONFIG_SAE_PWE_EARLY_EXIT=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS=y + +# Enable mbedtls +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_BUILTIN=y +CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y +CONFIG_MBEDTLS_USER_CONFIG_FILE="wpa_supp_els_pkc_mbedtls_config.h" +CONFIG_ENTROPY_GENERATOR=y +CONFIG_MBEDTLS_PSA_CRYPTO_C=y +CONFIG_MBEDTLS_ENTROPY_C=y +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=8192 +# mbedtls heap for enterprise case +CONFIG_MBEDTLS_ENABLE_HEAP=y +CONFIG_MBEDTLS_HEAP_SIZE=69952 + +#priority +CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_PRIO=3 +CONFIG_WIFI_NM_WPA_SUPPLICANT_PRIO=3 + +# stack size +CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE=12288 +CONFIG_WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE=12288 + +# stack size for -O0 +#CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE=16384 +#CONFIG_WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE=16384 + +# debug level +#CONFIG_WIFI_NM_WPA_SUPPLICANT_DEBUG_LEVEL=2 +CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_INF=y diff --git a/samples/net/wifi/shell/boards/rd_rw612_bga.conf b/samples/net/wifi/shell/boards/rd_rw612_bga.conf index da51250fc0c91..9681eceb3ed19 100644 --- a/samples/net/wifi/shell/boards/rd_rw612_bga.conf +++ b/samples/net/wifi/shell/boards/rd_rw612_bga.conf @@ -20,7 +20,6 @@ CONFIG_LOG_PRINTK=n CONFIG_THREAD_CUSTOM_DATA=y CONFIG_EVENTS=y CONFIG_SYS_HEAP_AUTO=y -CONFIG_HEAP_MEM_POOL_SIZE=122880 CONFIG_SCHED_MULTIQ=y CONFIG_ZVFS_OPEN_MAX=30 @@ -32,18 +31,19 @@ CONFIG_SHELL_CMD_BUFF_SIZE=512 # net CONFIG_NET_L2_ETHERNET=y -CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT=32 CONFIG_NET_IPV4=y CONFIG_NET_IPV6=y CONFIG_ETH_MCUX=n CONFIG_NET_ZPERF=y CONFIG_NET_ZPERF_MAX_PACKET_SIZE=1500 CONFIG_NET_BUF_LOG=y -CONFIG_NET_PKT_RX_COUNT=60 -CONFIG_NET_PKT_TX_COUNT=40 -CONFIG_NET_BUF_RX_COUNT=60 -CONFIG_NET_BUF_TX_COUNT=80 +CONFIG_NET_PKT_RX_COUNT=36 +CONFIG_NET_PKT_TX_COUNT=36 +CONFIG_NET_BUF_RX_COUNT=40 +CONFIG_NET_BUF_TX_COUNT=40 CONFIG_NET_BUF_DATA_SIZE=1744 +CONFIG_NET_TCP_MAX_SEND_WINDOW_SIZE=46720 +CONFIG_NET_TCP_MAX_RECV_WINDOW_SIZE=46720 CONFIG_NET_TC_TX_COUNT=1 CONFIG_NET_TC_RX_COUNT=1 CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=20 @@ -62,7 +62,6 @@ CONFIG_NET_IPV6_FRAGMENT_MAX_COUNT=3 CONFIG_NET_IPV6_FRAGMENT_MAX_PKT=8 CONFIG_NET_IPV6_FRAGMENT_TIMEOUT=3 CONFIG_NET_MAX_CONN=10 -CONFIG_NET_DHCPV4_SERVER_ICMP_PROBE_TIMEOUT=100 # net threads priority CONFIG_NET_TC_THREAD_PRIO_CUSTOM=y @@ -72,40 +71,11 @@ CONFIG_NET_TC_TX_THREAD_BASE_PRIO=3 CONFIG_NET_TC_RX_THREAD_BASE_PRIO=3 CONFIG_ZPERF_WORK_Q_THREAD_PRIORITY=3 CONFIG_NET_SOCKETS_SERVICE_THREAD_PRIO=3 -CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO=y +CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO=y CONFIG_NET_CONTEXT_PRIORITY=y CONFIG_NET_MGMT_THREAD_PRIO_CUSTOM=y CONFIG_NET_MGMT_THREAD_PRIORITY=3 -CONFIG_WIFI_NM_WPA_SUPPLICANT=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_CLI=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_EAPOL=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_INF_MON=n -CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES=2 -CONFIG_SAE_PWE_EARLY_EXIT=y -CONFIG_WIFI_NM_HOSTAPD_AP=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS=y -CONFIG_WIFI_NM_HOSTAPD_WPS=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_ROAMING=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_SKIP_DHCP_ON_ROAMING=y -CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE=y - -# Enable mbedtls -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_BUILTIN=y -CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y -CONFIG_MBEDTLS_USER_CONFIG_FILE="wpa_supp_els_pkc_mbedtls_config.h" - -# Include els_pkc in build -CONFIG_ENTROPY_GENERATOR=y -CONFIG_MBEDTLS_PSA_CRYPTO_C=y -CONFIG_MBEDTLS_ENTROPY_C=y -CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=8192 - # power management CONFIG_PM=y CONFIG_PM_DEVICE=y @@ -120,8 +90,6 @@ CONFIG_NET_MGMT_EVENT_STACK_SIZE=4608 CONFIG_NET_TCP_WORKQ_STACK_SIZE=2048 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_NET_SOCKETS_SERVICE_STACK_SIZE=4096 -CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE=12288 -CONFIG_WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE=12288 # optimization level # refer to Kconfig.zephyr for Optimizations Level @@ -149,14 +117,7 @@ CONFIG_NET_STATISTICS_USER_API=y #CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 #CONFIG_ZPERF_WORK_Q_STACK_SIZE=4096 #CONFIG_MAIN_STACK_SIZE=4096 -#CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE=16384 -#CONFIG_WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE=16384 #CONFIG_IDLE_STACK_SIZE=2048 # comment out for -O0 CONFIG_CODE_DATA_RELOCATION_SRAM=y -#CONFIG_WIFI_NM_WPA_SUPPLICANT_DEBUG_LEVEL=2 -CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_INF=y -CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_PRIO=3 -CONFIG_WIFI_NM_WPA_SUPPLICANT_PRIO=3 -CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=80000 diff --git a/samples/net/wifi/shell/overlay-debug.conf b/samples/net/wifi/shell/overlay-debug.conf new file mode 100644 index 0000000000000..d28921e3e8b2d --- /dev/null +++ b/samples/net/wifi/shell/overlay-debug.conf @@ -0,0 +1,5 @@ +# Debugging +CONFIG_STACK_SENTINEL=y +CONFIG_DEBUG_COREDUMP=y +CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=y +CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=y diff --git a/samples/net/wifi/shell/sample.yaml b/samples/net/wifi/shell/sample.yaml index bc5f10b6751e3..82be44c22cc62 100644 --- a/samples/net/wifi/shell/sample.yaml +++ b/samples/net/wifi/shell/sample.yaml @@ -12,6 +12,7 @@ tests: - cc3220sf_launchxl - disco_l475_iot1 - reel_board + - siwx917_rb4338a integration_platforms: - cc3220sf_launchxl sample.net.wifi.mikroe_wifi_bt_click: @@ -43,7 +44,7 @@ tests: - frdm_k64f sample.net.wifi.nrf70dk: extra_args: - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y - CONFIG_WIFI_CREDENTIALS=y - CONFIG_FLASH=y - CONFIG_FLASH_MAP=y @@ -57,7 +58,7 @@ tests: - nrf7002dk/nrf5340/cpuapp/nrf7001 sample.net.wifi.nrf7002ek: extra_args: - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y - SHIELD=nrf7002ek platform_allow: - nrf5340dk/nrf5340/cpuapp @@ -68,7 +69,7 @@ tests: sample.net.wifi.nrf7002eb: extra_args: - CONFIG_NRF70_UTIL=y - - CONFIG_NRF_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y - SHIELD=nrf7002eb platform_allow: - thingy53/nrf5340/cpuapp @@ -76,7 +77,22 @@ tests: - thingy53/nrf5340/cpuapp sample.net.wifi.nxp_wifi: extra_args: - - CONFIG_NXP_WIFI_BUILD_ONLY_MODE=y + - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - frdm_rw612 - rd_rw612_bga + sample.net.wifi.esp32: + extra_args: + - CONFIG_BUILD_ONLY_NO_BLOBS=y + platform_allow: + - esp32_devkitc_wroom/esp32/procpu + - esp32s2_saola + - esp32c3_devkitm + - esp32s3_devkitm/esp32s3/procpu + - esp8684_devkitm + - esp32c6_devkitc + sample.net.wifi.siwx91x_offloaded: + extra_args: + - CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD=y + platform_allow: + - siwx917_rb4338a diff --git a/samples/net/wifi/shell/socs/esp32c3_usb.conf b/samples/net/wifi/shell/socs/esp32c3_usb.conf new file mode 100644 index 0000000000000..a72fdf39efa24 --- /dev/null +++ b/samples/net/wifi/shell/socs/esp32c3_usb.conf @@ -0,0 +1,11 @@ +CONFIG_WIFI=y + +CONFIG_NETWORKING=y +CONFIG_NET_L2_ETHERNET=y + +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=y +CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y + +CONFIG_NET_LOG=y diff --git a/samples/net/wifi/shell/socs/esp32c3_usb.overlay b/samples/net/wifi/shell/socs/esp32c3_usb.overlay new file mode 100644 index 0000000000000..ea9865cf5f8a3 --- /dev/null +++ b/samples/net/wifi/shell/socs/esp32c3_usb.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wifi { + status = "okay"; +}; diff --git a/samples/net/zperf/CMakeLists.txt b/samples/net/zperf/CMakeLists.txt index dd1a09bbb22c3..9b3b5084b3976 100644 --- a/samples/net/zperf/CMakeLists.txt +++ b/samples/net/zperf/CMakeLists.txt @@ -26,3 +26,9 @@ endif() if (CONFIG_USB_DEVICE_STACK_NEXT) include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) endif() + +if (CONFIG_SOC_NRF5340_CPUAPP) + target_sources(app PRIVATE + src/nrf5340_cpu_boost.c + ) +endif() diff --git a/samples/net/zperf/README.rst b/samples/net/zperf/README.rst index 7bfe3c32d2f93..79ea582e1a46a 100644 --- a/samples/net/zperf/README.rst +++ b/samples/net/zperf/README.rst @@ -61,3 +61,9 @@ Usage See :ref:`zperf library documentation ` for more information about the library usage. + +Wi-Fi +===== + +The IPv4 Wi-Fi support can be enabled in the sample with +:ref:`Wi-Fi snippet `. diff --git a/samples/net/zperf/boards/mimxrt1050_evk.conf b/samples/net/zperf/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf similarity index 100% rename from samples/net/zperf/boards/mimxrt1050_evk.conf rename to samples/net/zperf/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf diff --git a/samples/net/zperf/boards/mimxrt1060_evk.conf b/samples/net/zperf/boards/mimxrt1060_evk_mimxrt1062_qspi.conf similarity index 100% rename from samples/net/zperf/boards/mimxrt1060_evk.conf rename to samples/net/zperf/boards/mimxrt1060_evk_mimxrt1062_qspi.conf diff --git a/samples/net/zperf/boards/nrf7002dk_nrf5340_cpuapp.conf b/samples/net/zperf/boards/nrf7002dk_nrf5340_cpuapp.conf new file mode 100644 index 0000000000000..7842b0da31e47 --- /dev/null +++ b/samples/net/zperf/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -0,0 +1,25 @@ +# Optimized networking settings for performance +CONFIG_NET_PKT_RX_COUNT=28 +CONFIG_NET_PKT_TX_COUNT=27 +CONFIG_NET_BUF_RX_COUNT=28 +CONFIG_NET_BUF_TX_COUNT=54 +CONFIG_NET_BUF_DATA_SIZE=1100 +CONFIG_HEAP_MEM_POOL_SIZE=260000 +CONFIG_NRF70_MAX_TX_AGGREGATION=4 +CONFIG_NRF70_QSPI_LOW_POWER=n + +# For speed optimizations +CONFIG_PICOLIBC_USE_MODULE=y + +# Consumes more memory +CONFIG_WIFI_CREDENTIALS=n +CONFIG_FLASH=n +CONFIG_NVS=n +CONFIG_SETTINGS=n + +# Debugging +CONFIG_NRF70_UTIL=y +CONFIG_SYS_HEAP_RUNTIME_STATS=y +CONFIG_NET_STATISTICS=y +CONFIG_NET_STATISTICS_WIFI=y +CONFIG_NET_STATISTICS_USER_API=y diff --git a/samples/net/zperf/sample.yaml b/samples/net/zperf/sample.yaml index 3c6077df6bc10..7dbb0cb8acff3 100644 --- a/samples/net/zperf/sample.yaml +++ b/samples/net/zperf/sample.yaml @@ -123,3 +123,8 @@ tests: sample.net.zperf.802154.subg: extra_args: EXTRA_CONF_FILE="overlay-802154-subg.conf" platform_allow: beagleconnect_freedom + sample.net.zperf.nrf7002dk: + extra_args: SNIPPET=wifi-ipv4 + extra_configs: + - CONFIG_BUILD_ONLY_NO_BLOBS=y + platform_allow: nrf7002dk/nrf5340/cpuapp diff --git a/samples/net/zperf/src/main.c b/samples/net/zperf/src/main.c index 86e6ea2f0c1cb..648adacf2235d 100644 --- a/samples/net/zperf/src/main.c +++ b/samples/net/zperf/src/main.c @@ -12,6 +12,8 @@ #include #include +LOG_MODULE_REGISTER(zperf, CONFIG_NET_ZPERF_LOG_LEVEL); + #ifdef CONFIG_NET_LOOPBACK_SIMULATE_PACKET_DROP #include #endif diff --git a/samples/net/zperf/src/nrf5340_cpu_boost.c b/samples/net/zperf/src/nrf5340_cpu_boost.c new file mode 100644 index 0000000000000..0eff58c32e373 --- /dev/null +++ b/samples/net/zperf/src/nrf5340_cpu_boost.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief CPU frequency boost for nRF53 series + */ + +#include +#include + +#include + +LOG_MODULE_DECLARE(zperf, CONFIG_NET_ZPERF_LOG_LEVEL); + +static int nrf53_cpu_boost(void) +{ + int err; + + /* For optimal performance, the CPU frequency should be set to 128 MHz */ + err = nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK, NRF_CLOCK_HFCLK_DIV_1); + err -= NRFX_ERROR_BASE_NUM; + if (err != 0) { + LOG_WRN("Failed to set 128 MHz: %d", err); + } + + LOG_INF("Starting %s with CPU frequency: %d MHz", CONFIG_BOARD, SystemCoreClock/MHZ(1)); + + return err; +} + +SYS_INIT(nrf53_cpu_boost, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/samples/psa/its/overlay-entropy_not_secure.conf b/samples/psa/its/overlay-entropy_not_secure.conf index f2ab17793542e..e8eeddbcf92be 100644 --- a/samples/psa/its/overlay-entropy_not_secure.conf +++ b/samples/psa/its/overlay-entropy_not_secure.conf @@ -2,3 +2,4 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_TIMER_RANDOM_GENERATOR=y +CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y diff --git a/samples/psa/persistent_key/overlay-entropy_not_secure.conf b/samples/psa/persistent_key/overlay-entropy_not_secure.conf index f2ab17793542e..e8eeddbcf92be 100644 --- a/samples/psa/persistent_key/overlay-entropy_not_secure.conf +++ b/samples/psa/persistent_key/overlay-entropy_not_secure.conf @@ -2,3 +2,4 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_TIMER_RANDOM_GENERATOR=y +CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y diff --git a/samples/psa/persistent_key/src/main.c b/samples/psa/persistent_key/src/main.c index c79d8184f94fe..2f010a012ea08 100644 --- a/samples/psa/persistent_key/src/main.c +++ b/samples/psa/persistent_key/src/main.c @@ -3,10 +3,11 @@ */ #include #include +#include LOG_MODULE_REGISTER(persistent_key); -#define SAMPLE_KEY_ID PSA_KEY_ID_USER_MIN +#define SAMPLE_KEY_ID ZEPHYR_PSA_APPLICATION_KEY_ID_RANGE_BEGIN #define SAMPLE_KEY_TYPE PSA_KEY_TYPE_AES #define SAMPLE_ALG PSA_ALG_CTR #define SAMPLE_KEY_BITS 256 diff --git a/samples/sensor/6dof_motion_drdy/CMakeLists.txt b/samples/sensor/6dof_motion_drdy/CMakeLists.txt new file mode 100644 index 0000000000000..892aaf5ed8add --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 TDK Invensense +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(6dof_motion_drdy) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/sensor/6dof_motion_drdy/README.rst b/samples/sensor/6dof_motion_drdy/README.rst new file mode 100644 index 0000000000000..811259b795d5b --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/README.rst @@ -0,0 +1,56 @@ +.. zephyr:code-sample:: 6dof_motion_drdy + :name: Generic 6DOF Motion Dataready + :relevant-api: sensor_interface + + Get 6-Axis accelerometer and gyroscope data from a sensor (data ready interrupt mode). + +Overview +******** + +This sample application periodically (100 Hz) measures the 6-axis IMU sensor with +temperature, acceleration, and angular velocity, displaying the +values on the console along with a timestamp since startup. +Trigger options could be configured through KConfig. + +Wiring +****** + +This sample uses an external breakout for the sensor. A devicetree +overlay must be provided to identify the 6-axis motion sensor, the SPI or I2C bus interface and the interrupt +sensor GPIO. + +Building and Running +******************** + +This sample supports up to 6-Axis IMU devices. Each device needs +to be aliased as ``6dof-motion-drdyN`` where ``N`` goes from ``0`` to ``9``. For example: + +.. code-block:: devicetree + + / { + aliases { + 6dof-motion-drdy0 = &icm42670p; + }; + }; + +Make sure the aliases are in devicetree, then build and run with: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/6dof_motion_drdy + :board: nrf52dk/nrf52832 + :goals: build flash + +Sample Output +============= + +.. code-block:: console + +Found device "icm42670p@68", getting sensor data +[0:00:01.716]: temp 23.00 Cel accel 0.150839 -0.140065 9.994899 m/s/s gyro -0.001597 0.005859 0.001597 rad/s +[0:00:01.726]: temp 23.00 Cel accel 0.140065 -0.146050 9.988914 m/s/s gyro -0.002663 0.005859 0.003195 rad/s +[0:00:01.736]: temp 23.50 Cel accel 0.146050 -0.130487 9.988914 m/s/s gyro -0.001597 0.006391 0.003195 rad/s +[0:00:01.746]: temp 23.00 Cel accel 0.149642 -0.136473 9.990111 m/s/s gyro -0.002663 0.004261 0.002663 rad/s +[0:00:01.756]: temp 23.00 Cel accel 0.146050 -0.136473 9.979337 m/s/s gyro -0.002130 0.005326 0.001597 rad/s +[0:00:01.766]: temp 23.00 Cel accel 0.136473 -0.147247 9.986519 m/s/s gyro -0.001065 0.005859 0.002663 rad/s + + diff --git a/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_i2c.overlay b/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_i2c.overlay new file mode 100644 index 0000000000000..24a82484942f8 --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_i2c.overlay @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Get a node identifier for 6-axis IMU sensor. + */ +/ { + aliases { + 6dof-motion-drdy0 = &icm42670p; + }; +}; + +/* + * Example configuration of a ICM42670-P device on i2c0 compatible with an Arduino I2C bus. + * + * Device address 0x68 is assumed. Your device may have a different + * address; check your device documentation if unsure. + * + * Configure 100Hz IMU data reporting + */ +&arduino_i2c { + status = "okay"; + icm42670p: icm42670p@68 { + compatible = "invensense,icm42670p"; + reg = <0x68>; + int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ + accel-hz = <100>; + gyro-hz = <100>; + accel-fs = <16>; + gyro-fs = <2000>; + }; +}; + +/* + * Increase native UART speed to report all IMU data at 100Hz. + */ +&uart0 { + compatible = "nordic,nrf-uarte"; + current-speed = <1000000>; +}; diff --git a/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_spi.overlay b/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_spi.overlay new file mode 100644 index 0000000000000..d74e8bd092f40 --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_spi.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024, TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Get a node identifier for 6-axis IMU sensor. + */ +/ { + aliases { + 6dof-motion-drdy0 = &icm42670p; + }; +}; + +/* Example configuration of a ICM42670-P device on spi2 compatible with an Arduino SPI bus. + * + * Configure 100Hz IMU data reporting + */ +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ + icm42670p: icm42670p@0 { + compatible = "invensense,icm42670p"; + reg = <0>; + spi-max-frequency = <1000000>; /* conservatively set to 1MHz */ + int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ + accel-hz = <100>; + gyro-hz = <100>; + accel-fs = <16>; + gyro-fs = <2000>; + }; +}; + +/* + * Increase native UART speed to report all IMU data at 100Hz. + */ +&uart0 { + compatible = "nordic,nrf-uarte"; + current-speed = <1000000>; +}; diff --git a/samples/sensor/6dof_motion_drdy/prj.conf b/samples/sensor/6dof_motion_drdy/prj.conf new file mode 100644 index 0000000000000..7731b5b6de1e3 --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/prj.conf @@ -0,0 +1,19 @@ +# +# Copyright (c) 2024 TDK Invensense +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SENSOR=y +CONFIG_LOG=y +CONFIG_SENSOR_LOG_LEVEL_DBG=n + +# Floating point format support +# Selecting this increases stack size requirements slightly, but increases code size significantly. +CONFIG_CBPRINTF_FP_SUPPORT=y + +# nrf52dk/nrf52832 specific +CONFIG_USE_SEGGER_RTT=n + +# Trigger mode: sample is using interrupt triggering +CONFIG_ICM42X70_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/6dof_motion_drdy/sample.yaml b/samples/sensor/6dof_motion_drdy/sample.yaml new file mode 100644 index 0000000000000..02932da4ebd56 --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/sample.yaml @@ -0,0 +1,9 @@ +sample: + name: 6DOF Motion dataready sample +tests: + sample.sensor.6dof_motion_drdy: + build_only: true + tags: sensors + filter: dt_alias_exists("6dof_motion_drdy0") + integration_platforms: + - nrf52dk/nrf52832 diff --git a/samples/sensor/6dof_motion_drdy/src/main.c b/samples/sensor/6dof_motion_drdy/src/main.c new file mode 100644 index 0000000000000..547c86b51da83 --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/src/main.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +static struct sensor_trigger data_trigger; + +/* Flag set from IMU device irq handler */ +static volatile int irq_from_device; + +/* + * Get a device structure from a devicetree node from alias + * "6dof_motion_drdy0". + */ +static const struct device *get_6dof_motion_device(void) +{ + const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(6dof_motion_drdy0)); + + if (!device_is_ready(dev)) { + printk("\nError: Device \"%s\" is not ready; " + "check the driver initialization logs for errors.\n", + dev->name); + return NULL; + } + + printk("Found device \"%s\", getting sensor data\n", dev->name); + return dev; +} + +static const char *now_str(void) +{ + static char buf[16]; /* ...HH:MM:SS.MMM */ + uint32_t now = k_uptime_get_32(); + unsigned int ms = now % MSEC_PER_SEC; + unsigned int s; + unsigned int min; + unsigned int h; + + now /= MSEC_PER_SEC; + s = now % 60U; + now /= 60U; + min = now % 60U; + now /= 60U; + h = now; + + snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u", h, min, s, ms); + return buf; +} + +static void handle_6dof_motion_drdy(const struct device *dev, const struct sensor_trigger *trig) +{ + if (trig->type == SENSOR_TRIG_DATA_READY) { + int rc = sensor_sample_fetch_chan(dev, trig->chan); + + if (rc < 0) { + printf("sample fetch failed: %d\n", rc); + printf("cancelling trigger due to failure: %d\n", rc); + (void)sensor_trigger_set(dev, trig, NULL); + return; + } else if (rc == 0) { + irq_from_device = 1; + } + } +} + +int main(void) +{ + const struct device *dev = get_6dof_motion_device(); + struct sensor_value accel[3]; + struct sensor_value gyro[3]; + struct sensor_value temperature; + + if (dev == NULL) { + return 0; + } + + data_trigger = (struct sensor_trigger){ + .type = SENSOR_TRIG_DATA_READY, + .chan = SENSOR_CHAN_ALL, + }; + if (sensor_trigger_set(dev, &data_trigger, handle_6dof_motion_drdy) < 0) { + printf("Cannot configure data trigger!!!\n"); + return 0; + } + + k_sleep(K_MSEC(1000)); + + while (1) { + + if (irq_from_device) { + sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, accel); + sensor_channel_get(dev, SENSOR_CHAN_GYRO_XYZ, gyro); + sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, &temperature); + + printf("[%s]: temp %.2f Cel " + " accel %f %f %f m/s/s " + " gyro %f %f %f rad/s\n", + now_str(), sensor_value_to_double(&temperature), + sensor_value_to_double(&accel[0]), sensor_value_to_double(&accel[1]), + sensor_value_to_double(&accel[2]), sensor_value_to_double(&gyro[0]), + sensor_value_to_double(&gyro[1]), sensor_value_to_double(&gyro[2])); + irq_from_device = 0; + } + } + return 0; +} diff --git a/samples/sensor/accel_trig/Kconfig b/samples/sensor/accel_trig/Kconfig new file mode 100644 index 0000000000000..ec0fa9d253e80 --- /dev/null +++ b/samples/sensor/accel_trig/Kconfig @@ -0,0 +1,13 @@ +# +# Copyright (c) 2025 Pierrick Curt +# +# SPDX-License-Identifier: Apache-2.0 +# + +mainmenu "Accelerometer trigger sample application" + +config SAMPLE_TAP_DETECTION + bool "Set tap detection as trigger in the sample" + default n + +source "Kconfig.zephyr" diff --git a/samples/sensor/accel_trig/README.rst b/samples/sensor/accel_trig/README.rst index 37a3f18e8c8e5..1933edf1671e5 100644 --- a/samples/sensor/accel_trig/README.rst +++ b/samples/sensor/accel_trig/README.rst @@ -7,6 +7,10 @@ Overview ******** This sample application demonstrates how to use 3-Axis accelerometers with triggers. +By default it uses a data ready trigger to read the accelerometer data and print it to the console. + +If the accelerometer is enabled with a tap trigger, the sample uses the tap trigger event to +read the accelerometer data and print it to the console. Building and Running ******************** @@ -27,8 +31,21 @@ Make sure the aliases are in devicetree, then build and run with: :goals: build flash :compact: -Sample Output -============= +With this example, you can also detect a double tap with an accelerometer by activating the +:kconfig:option:`CONFIG_SAMPLE_TAP_DETECTION`. +In this example we use a x_nucleo_iks01a3 shield with a LIS2DW12 accelerometer. +You can build it with the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/accel_trig + :board: nrf52dk/nrf52832 + :shield: x_nucleo_iks01a3 + :goals: build + :compact: + + +Sample Output (SENSOR_TRIG_DATA_READY) +======================================= .. code-block:: console @@ -43,3 +60,28 @@ Sample Output fxos8700@1d [m/s^2]: ( -0.105345, -0.028731, 9.921571) fxos8700@1d [m/s^2]: ( -0.095769, -0.028731, 9.931148) fxos8700@1d [m/s^2]: ( -0.095769, -0.009577, 9.940725) + + +Sample Output (SENSOR_TRIG_DOUBLE_TAP) +====================================== + +.. code-block:: console + + TAP detected + lis2dw12@19 [m/s^2]: ( -1.899901, -12.550355, -2.742174) + TAP detected + lis2dw12@19 [m/s^2]: ( 12.349357, -18.125630, 6.015556) + TAP detected + lis2dw12@19 [m/s^2]: ( -11.385050, -7.274181, -9.229117) + TAP detected + lis2dw12@19 [m/s^2]: ( 9.214760, -9.286545, 2.311466) + TAP detected + lis2dw12@19 [m/s^2]: ( 10.090533, -17.391034, 12.320643) + TAP detected + lis2dw12@19 [m/s^2]: ( -0.478564, 2.390429, 15.876378) + TAP detected + lis2dw12@19 [m/s^2]: ( -5.668596, -13.138989, 0.741775) + TAP detected + lis2dw12@19 [m/s^2]: ( -2.385644, -10.559526, 9.899107) + TAP detected + lis2dw12@19 [m/s^2]: ( 7.537391, -8.551948, 16.740187) diff --git a/samples/sensor/accel_trig/boards/frdm_k82f.conf b/samples/sensor/accel_trig/boards/frdm_k82f.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/frdm_k82f.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/frdm_kl25z.conf b/samples/sensor/accel_trig/boards/frdm_kl25z.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/frdm_kl25z.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/frdm_kw41z.conf b/samples/sensor/accel_trig/boards/frdm_kw41z.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/frdm_kw41z.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/frdm_mcxc242.conf b/samples/sensor/accel_trig/boards/frdm_mcxc242.conf new file mode 100644 index 0000000000000..9dc813d038c5b --- /dev/null +++ b/samples/sensor/accel_trig/boards/frdm_mcxc242.conf @@ -0,0 +1 @@ +CONFIG_FXLS8974_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/accel_trig/boards/lpcxpresso55s28.conf b/samples/sensor/accel_trig/boards/lpcxpresso55s28.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/lpcxpresso55s28.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/lpcxpresso55s69_lpc55s69_cpu0.conf b/samples/sensor/accel_trig/boards/lpcxpresso55s69_lpc55s69_cpu0.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/lpcxpresso55s69_lpc55s69_cpu0.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/mimxrt1040_evk.conf b/samples/sensor/accel_trig/boards/mimxrt1040_evk.conf new file mode 100644 index 0000000000000..9dc813d038c5b --- /dev/null +++ b/samples/sensor/accel_trig/boards/mimxrt1040_evk.conf @@ -0,0 +1 @@ +CONFIG_FXLS8974_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/accel_trig/boards/mimxrt1040_evk.overlay b/samples/sensor/accel_trig/boards/mimxrt1040_evk.overlay new file mode 100644 index 0000000000000..56ec2a98c5b18 --- /dev/null +++ b/samples/sensor/accel_trig/boards/mimxrt1040_evk.overlay @@ -0,0 +1,12 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2025 NXP + */ + + +&fxls8974 { + status = "okay"; + int1-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + int2-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; +}; diff --git a/samples/sensor/accel_trig/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf b/samples/sensor/accel_trig/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/mimxrt1160_evk_mimxrt1166_cm7.conf b/samples/sensor/accel_trig/boards/mimxrt1160_evk_mimxrt1166_cm7.conf new file mode 100644 index 0000000000000..e3dadc69fc771 --- /dev/null +++ b/samples/sensor/accel_trig/boards/mimxrt1160_evk_mimxrt1166_cm7.conf @@ -0,0 +1,6 @@ +# +# check the fxos8700 dts for this board for addition settings +# + +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/mimxrt1170_evk@A_mimxrt1176_cm7.conf b/samples/sensor/accel_trig/boards/mimxrt1170_evk@A_mimxrt1176_cm7.conf new file mode 100644 index 0000000000000..e3dadc69fc771 --- /dev/null +++ b/samples/sensor/accel_trig/boards/mimxrt1170_evk@A_mimxrt1176_cm7.conf @@ -0,0 +1,6 @@ +# +# check the fxos8700 dts for this board for addition settings +# + +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/samples/sensor/accel_trig/boards/mimxrt595_evk_mimxrt595s_cm33.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/mimxrt685_evk_mimxrt685s_cm33.conf b/samples/sensor/accel_trig/boards/mimxrt685_evk_mimxrt685s_cm33.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/mimxrt685_evk_mimxrt685s_cm33.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/nrf52dk_nrf52832.overlay b/samples/sensor/accel_trig/boards/nrf52dk_nrf52832.overlay new file mode 100644 index 0000000000000..f33cce2022116 --- /dev/null +++ b/samples/sensor/accel_trig/boards/nrf52dk_nrf52832.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Pierrick Curt + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +&lis2dw12_19_x_nucleo_iks01a3 { + status = "okay"; + compatible = "st,lis2dw12"; + reg = <0x19>; + odr = <400>; + tap-mode = ; + tap-threshold = <12>, <12>, <12>; + power-mode = ; + tap-shock = <0x03>; + tap-quiet = <0x03>; + tap-latency = <0x03>; + irq-gpios = <&arduino_header 3 GPIO_ACTIVE_HIGH>; /* A3 */ +}; diff --git a/samples/sensor/accel_trig/boards/stm32f3_disco.conf b/samples/sensor/accel_trig/boards/stm32f3_disco.conf new file mode 100644 index 0000000000000..67dc73ec34251 --- /dev/null +++ b/samples/sensor/accel_trig/boards/stm32f3_disco.conf @@ -0,0 +1,4 @@ +CONFIG_I2C=y +CONFIG_SENSOR_LOG_LEVEL_DBG=y +CONFIG_LIS2DW12_TRIGGER_GLOBAL_THREAD=y +CONFIG_LIS2DW12_TAP=y diff --git a/samples/sensor/accel_trig/boards/stm32f3_disco.overlay b/samples/sensor/accel_trig/boards/stm32f3_disco.overlay new file mode 100644 index 0000000000000..79d5a106a8894 --- /dev/null +++ b/samples/sensor/accel_trig/boards/stm32f3_disco.overlay @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, Pierrick Curt. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + accel0 = &lis2dw12_accel; + }; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pa9 &i2c2_sda_pa10>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; + + lis2dw12_accel: lis2dw12@19 { + compatible = "st,lis2dw12"; + reg = <0x19>; + odr = <400>; + tap-mode = ; + tap-threshold = <12>, <12>, <12>; + power-mode = ; + tap-shock = <0x03>; + tap-quiet = <0x03>; + tap-latency = <0x03>; + irq-gpios = <&gpioe 6 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/samples/sensor/accel_trig/boards/twr_ke18f.conf b/samples/sensor/accel_trig/boards/twr_ke18f.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/twr_ke18f.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/boards/twr_ke18f.overlay b/samples/sensor/accel_trig/boards/twr_ke18f.overlay new file mode 100644 index 0000000000000..4f82667c80b69 --- /dev/null +++ b/samples/sensor/accel_trig/boards/twr_ke18f.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2025 NXP + */ + +&fxos8700 { + status = "okay"; + int1-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; + int2-gpios = <&gpioa 17 GPIO_ACTIVE_LOW>; +}; diff --git a/samples/sensor/accel_trig/boards/twr_kv58f220m.conf b/samples/sensor/accel_trig/boards/twr_kv58f220m.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/accel_trig/boards/twr_kv58f220m.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/accel_trig/sample.yaml b/samples/sensor/accel_trig/sample.yaml index 9392668a5e0c2..a35b8731f6f35 100644 --- a/samples/sensor/accel_trig/sample.yaml +++ b/samples/sensor/accel_trig/sample.yaml @@ -6,6 +6,7 @@ tests: tags: sensors filter: dt_alias_exists("accel0") harness_config: + fixture: fixture_sensor_accel_int type: one_line regex: - "^\\s*[0-9A-Za-z_,+-.]*@[0-9A-Fa-f]* \\[m\/s\\^2\\]: \ diff --git a/samples/sensor/accel_trig/src/main.c b/samples/sensor/accel_trig/src/main.c index e5ddde1e2bef3..6f56cc1e9d51e 100644 --- a/samples/sensor/accel_trig/src/main.c +++ b/samples/sensor/accel_trig/src/main.c @@ -11,6 +11,19 @@ K_SEM_DEFINE(sem, 0, 1); /* starts off "not available" */ +#ifdef CONFIG_SAMPLE_TAP_DETECTION +static void tap_trigger_handler(const struct device *dev, const struct sensor_trigger *trigger) +{ + ARG_UNUSED(trigger); + printf("TAP detected\n"); + + if (sensor_sample_fetch_chan(dev, SENSOR_CHAN_ACCEL_XYZ) < 0) { + printf("ERROR: SENSOR_CHAN_ACCEL_XYZ fetch failed\n"); + } + + k_sem_give(&sem); +} +#else static void trigger_handler(const struct device *dev, const struct sensor_trigger *trigger) { ARG_UNUSED(trigger); @@ -25,6 +38,7 @@ static void trigger_handler(const struct device *dev, const struct sensor_trigge k_sem_give(&sem); } +#endif int main(void) { @@ -41,10 +55,19 @@ int main(void) return 0; } +#ifdef CONFIG_SAMPLE_TAP_DETECTION + trig.type = SENSOR_TRIG_DOUBLE_TAP; + trig.chan = SENSOR_CHAN_ACCEL_XYZ; + if (sensor_trigger_set(dev, &trig, tap_trigger_handler) < 0) { + printf("Could not set tap trigger\n"); + return 0; + } +#else if (sensor_trigger_set(dev, &trig, trigger_handler)) { printf("Could not set trigger\n"); return 0; } +#endif while (1) { k_sem_take(&sem, K_FOREVER); diff --git a/samples/sensor/clock/CMakeLists.txt b/samples/sensor/clock/CMakeLists.txt new file mode 100644 index 0000000000000..412f9ec7bfd7b --- /dev/null +++ b/samples/sensor/clock/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 Cienet +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(clock) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/sensor/clock/README.rst b/samples/sensor/clock/README.rst new file mode 100644 index 0000000000000..b213e787beb82 --- /dev/null +++ b/samples/sensor/clock/README.rst @@ -0,0 +1,53 @@ +.. zephyr:code-sample:: sensor_clock + :name: Sensor Clock + :relevant-api: sensor_interface + + Test and debug Sensor Clock functionality. + +Overview +******** + +This sample application demonstrates how to select the sensor clock source +and utilize the Sensor Clock API. + +Building and Running +******************** + +The sample below uses the :ref:`nrf52840dk_nrf52840` and :ref:`nrf52833dk_nrf52833` boards. + +To run this sample, ensure the following configurations: + + * Enable one of the Kconfig options: + :kconfig:option:`CONFIG_SENSOR_CLOCK_COUNTER`, + :kconfig:option:`CONFIG_SENSOR_CLOCK_RTC`, or + :kconfig:option:`CONFIG_SENSOR_CLOCK_SYSTEM`. + +Build and run the sample with the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/clock + :board: + :goals: build flash + +Sample Output +============= + +The application will print the current sensor clock cycles and +their corresponding time in nanoseconds. + +.. code-block:: console + + Cycles: 143783087 + Nanoseconds: 8986442937 + Cycles: 159776386 + Nanoseconds: 9986024125 + Cycles: 175772543 + Nanoseconds: 10985783937 + Cycles: 191771203 + Nanoseconds: 11985700187 + Cycles: 207758870 + Nanoseconds: 12984929375 + Cycles: 223752074 + Nanoseconds: 13984504625 + + ... diff --git a/samples/sensor/clock/boards/nrf52833dk_nrf52833.overlay b/samples/sensor/clock/boards/nrf52833dk_nrf52833.overlay new file mode 100644 index 0000000000000..057465d10757f --- /dev/null +++ b/samples/sensor/clock/boards/nrf52833dk_nrf52833.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Cienet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rtc0 { + status = "okay"; +}; + +&timer0 { + status = "okay"; +}; diff --git a/samples/sensor/clock/boards/nrf52840dk_nrf52840.overlay b/samples/sensor/clock/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 0000000000000..057465d10757f --- /dev/null +++ b/samples/sensor/clock/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Cienet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&rtc0 { + status = "okay"; +}; + +&timer0 { + status = "okay"; +}; diff --git a/samples/sensor/clock/boards/nrf528xx_counter.overlay b/samples/sensor/clock/boards/nrf528xx_counter.overlay new file mode 100644 index 0000000000000..51def7ff52241 --- /dev/null +++ b/samples/sensor/clock/boards/nrf528xx_counter.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Cienet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,sensor-clock = &timer0; + }; +}; diff --git a/samples/sensor/clock/boards/nrf528xx_rtc.overlay b/samples/sensor/clock/boards/nrf528xx_rtc.overlay new file mode 100644 index 0000000000000..ddacc14684196 --- /dev/null +++ b/samples/sensor/clock/boards/nrf528xx_rtc.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Cienet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,sensor-clock = &rtc0; + }; +}; diff --git a/samples/sensor/clock/prj.conf b/samples/sensor/clock/prj.conf new file mode 100644 index 0000000000000..8fdcaf2c1961c --- /dev/null +++ b/samples/sensor/clock/prj.conf @@ -0,0 +1,14 @@ +# +# Copyright (c) 2024 Cienet +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_LOG=y +CONFIG_LOG_DEFAULT_LEVEL=3 + +CONFIG_SENSOR=y +CONFIG_COUNTER=y +CONFIG_RTC=y +CONFIG_SENSOR_ASYNC_API=y + +CONFIG_SENSOR_CLOCK_COUNTER=y diff --git a/samples/sensor/clock/sample.yaml b/samples/sensor/clock/sample.yaml new file mode 100644 index 0000000000000..08ee185c212c2 --- /dev/null +++ b/samples/sensor/clock/sample.yaml @@ -0,0 +1,38 @@ +# +# Copyright (c) 2024 Cienet +# +# SPDX-License-Identifier: Apache-2.0 + +tests: + sample.sensor.clock.counter: + filter: CONFIG_SENSOR_CLOCK_COUNTER + tags: + - drivers + - sensor + - counter + platform_allow: + - nrf52840dk/nrf52840 + - nrf52833dk/nrf52833 + extra_dtc_overlay_files: + - "boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}.overlay" + - "boards/nrf528xx_counter.overlay" + + sample.sensor.clock.rtc: + filter: CONFIG_SENSOR_CLOCK_RTC + tags: + - drivers + - sensor + - rtc + platform_allow: + - nrf52840dk/nrf52840 + - nrf52833dk/nrf52833 + extra_dtc_overlay_files: + - "boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}.overlay" + - "boards/nrf528xx_rtc.overlay" + + sample.sensor.clock.system: + filter: CONFIG_SENSOR_CLOCK_SYSTEM + tags: + - drivers + - sensor + - system_clock diff --git a/samples/sensor/clock/src/main.c b/samples/sensor/clock/src/main.c new file mode 100644 index 0000000000000..fcaf6520af492 --- /dev/null +++ b/samples/sensor/clock/src/main.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Cienet + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +int main(void) +{ + uint64_t cycles = 0; + uint64_t delta_ns = 0; + int err; + + while (true) { + k_sleep(K_MSEC(1000)); + + err = sensor_clock_get_cycles(&cycles); + if (err) { + printf("Failed to get sensor clock cycles, error: %d\n", err); + continue; + } + + printf("Cycles: %llu\n", cycles); + + delta_ns = sensor_clock_cycles_to_ns(cycles); + + printf("Nanoseconds: %llu\n", delta_ns); + } + + return 0; +} diff --git a/samples/sensor/dht_polling/src/main.c b/samples/sensor/dht_polling/src/main.c index 9055f07cb925c..fcbe0ca929523 100644 --- a/samples/sensor/dht_polling/src/main.c +++ b/samples/sensor/dht_polling/src/main.c @@ -84,7 +84,7 @@ int main(void) (struct sensor_chan_spec) {SENSOR_CHAN_HUMIDITY, 0}, &hum_fit, 1, &hum_data); - printk("%16s: temp is %s%d.%d °C humidity is %s%d.%d RH\n", dev->name, + printk("%16s: temp is %s%d.%d °C humidity is %s%d.%d %%RH\n", dev->name, PRIq_arg(temp_data.readings[0].temperature, 2, temp_data.shift), PRIq_arg(hum_data.readings[0].humidity, 2, hum_data.shift)); } diff --git a/samples/sensor/die_temp_polling/boards/mimxrt1050_evk.conf b/samples/sensor/die_temp_polling/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf similarity index 100% rename from samples/sensor/die_temp_polling/boards/mimxrt1050_evk.conf rename to samples/sensor/die_temp_polling/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf diff --git a/samples/sensor/die_temp_polling/boards/mimxrt1050_evk.overlay b/samples/sensor/die_temp_polling/boards/mimxrt1050_evk_mimxrt1052_hyperflash.overlay similarity index 100% rename from samples/sensor/die_temp_polling/boards/mimxrt1050_evk.overlay rename to samples/sensor/die_temp_polling/boards/mimxrt1050_evk_mimxrt1052_hyperflash.overlay diff --git a/samples/sensor/die_temp_polling/boards/rpi_pico2_rp2350a_m33.overlay b/samples/sensor/die_temp_polling/boards/rpi_pico2_rp2350a_m33.overlay new file mode 100644 index 0000000000000..0c8a120437bb5 --- /dev/null +++ b/samples/sensor/die_temp_polling/boards/rpi_pico2_rp2350a_m33.overlay @@ -0,0 +1,8 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Andrew Featherstone + */ + +/* Pico 2 is compatible with the Pico 1, so reuse. */ +#include "rpi_pico.overlay" diff --git a/samples/sensor/die_temp_polling/socs/esp32c3_usb.conf b/samples/sensor/die_temp_polling/socs/esp32c3_usb.conf new file mode 100644 index 0000000000000..5ab7306afeb39 --- /dev/null +++ b/samples/sensor/die_temp_polling/socs/esp32c3_usb.conf @@ -0,0 +1 @@ +CONFIG_REQUIRES_FULL_LIBC=y diff --git a/samples/sensor/die_temp_polling/socs/esp32c3_usb.overlay b/samples/sensor/die_temp_polling/socs/esp32c3_usb.overlay new file mode 100644 index 0000000000000..a1229102bf805 --- /dev/null +++ b/samples/sensor/die_temp_polling/socs/esp32c3_usb.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023, Hiroki Tada + * + * SPDX-License-Identifier: Apache-2.0 + * + * Application overlay for creating temperature sensor device instance + */ + +&coretemp { + status = "okay"; +}; diff --git a/samples/sensor/fxos8700/README.rst b/samples/sensor/fxos8700/README.rst deleted file mode 100644 index cc0f3a5885a9b..0000000000000 --- a/samples/sensor/fxos8700/README.rst +++ /dev/null @@ -1,150 +0,0 @@ -.. zephyr:code-sample:: fxos8700 - :name: FXOS8700 Accelerometer/Magnetometer Sensor - :relevant-api: sensor_interface - - Get accelerometer and magnetometer data from an FXOS8700 sensor (polling & trigger mode). - -Overview -******** - -This sample application shows how to use the FXOS8700 driver. -The driver supports FXOS8700 accelerometer/magnetometer and -MMA8451Q, MMA8652FC, MMA8653FC accelerometers. - -Building and Running -******************** - -This project outputs sensor data to the console. FXOS8700 -sensor is present on the :zephyr:board:`frdm_k64f`, :zephyr:board:`frdm_k22f`, -:zephyr:board:`frdm_kw41z`, :ref:`hexiwear`, and :zephyr:board:`twr_ke18f` boards. -Accelerometer only devices are present on the :zephyr:board:`frdm_kl25z`, -:zephyr:board:`bbc_microbit`, and :ref:`reel_board` boards. It does not work on -QEMU. - -Building and Running for FRDM-K64F -================================== -FRDM-K64F is equipped with FXOS8700CQ accelerometer and magnetometer. -Sample can be built and executed for the FRDM-K64F as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: frdm_k64f - :goals: build flash - :compact: - -Example building for the FRDM-K64F with motion detection support: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: frdm_k64f - :conf: "prj.conf overlay-motion.conf" - :goals: build flash - :compact: - -Building and Running for FRDM-K22F -================================== -FRDM-K22F is equipped with FXOS8700CQ accelerometer and magnetometer. -Sample can be built and executed for the FRDM-K22F as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: frdm_k22f - :goals: build flash - :compact: - -Example building for the FRDM-K22F with motion detection support: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: frdm_k22f - :conf: "prj.conf overlay-motion.conf" - :goals: build flash - :compact: - -Building and Running for TWR-KE18F -================================== -TWR-KE18F is equipped with FXOS8700CQ accelerometer and magnetometer. -The FXOS8700CQ IRQ lines, however, are not connected by default, so -motion detection is not supported. - -Sample can be built and executed for the TWR-KE18F as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: twr_ke18f - :goals: build flash - :compact: - -Building and Running for FRDM-KL25Z -=================================== -FRDM-KL25Z is equipped with MMA8451Q accelerometer. -Sample can be built and executed for the FRDM-KL25Z as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: frdm_kl25z - :conf: "prj_accel.conf" - :goals: build flash - :compact: - -Building and Running for Micro Bit -================================== -Micro Bit is equipped with MMA8653FC accelerometer. -Sample can be built and executed for the Micro Bit as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: bbc_microbit - :conf: "prj_accel.conf" - :goals: build flash - :compact: - -Building and Running for reel board -=================================== -The reel board is equipped with MMA8652FC accelerometer. -Sample can be built and executed for the reel board as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: reel_board - :conf: "prj_accel.conf" - :goals: build flash - :compact: - -Building and Running for MIMXRT685-EVK -====================================== -MIMXRT685-EVK is equipped with FXOS8700CQ accelerometer and magnetometer. -Sample can be built and executed for the MIMXRT685-EVK as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: mimxrt685_evk/mimxrt685s/cm33 - :goals: build flash - :compact: - -Building and Running for MIMXRT595-EVK -====================================== -MIMXRT595-EVK is optionally equipped with FXOS8700CQ accelerometer and magnetometer. -Please confirm the FXOS8700CQ(U6) is populated on your board. -Sample can be built and executed for the MIMXRT595-EVK as follows: - -.. zephyr-app-commands:: - :zephyr-app: samples/sensor/fxos8700 - :board: mimxrt595_evk/mimxrt595s/cm33 - :goals: build flash - :compact: - -Sample Output -============= - -.. code-block:: console - - AX= -0.191537 AY= 0.067037 AZ= 9.902418 MX= 0.379000 MY= 0.271000 MZ= -0.056000 T= 22.080000 - AX= -0.162806 AY= 0.143652 AZ= 9.940725 MX= 0.391000 MY= 0.307000 MZ= -0.058000 T= 22.080000 - AX= -0.172383 AY= 0.134075 AZ= 9.969455 MX= 0.395000 MY= 0.287000 MZ= -0.017000 T= 22.080000 - AX= -0.210690 AY= 0.105344 AZ= 9.911994 MX= 0.407000 MY= 0.306000 MZ= -0.068000 T= 22.080000 - AX= -0.153229 AY= 0.124498 AZ= 9.950302 MX= 0.393000 MY= 0.301000 MZ= -0.021000 T= 22.080000 - AX= -0.153229 AY= 0.095768 AZ= 9.921571 MX= 0.398000 MY= 0.278000 MZ= -0.040000 T= 22.080000 - AX= -0.162806 AY= 0.105344 AZ= 9.902418 MX= 0.372000 MY= 0.300000 MZ= -0.046000 T= 22.080000 - - diff --git a/samples/sensor/grow_r502a/src/main.c b/samples/sensor/grow_r502a/src/main.c index da8923e1fc27b..c8164d0684eb2 100644 --- a/samples/sensor/grow_r502a/src/main.c +++ b/samples/sensor/grow_r502a/src/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/samples/sensor/lsm6dso/README.rst b/samples/sensor/lsm6dso/README.rst index 2f82e28f18735..a55a04240362c 100644 --- a/samples/sensor/lsm6dso/README.rst +++ b/samples/sensor/lsm6dso/README.rst @@ -7,7 +7,7 @@ Overview ******** -This sample sets the date rate of LSM6DSO accelerometer and gyroscope to +This sample sets the data rate of the LSM6DSO accelerometer and gyroscope to 12.5Hz and enables a trigger on data ready. It displays on the console the values for accelerometer and gyroscope. diff --git a/samples/sensor/magn_trig/boards/frdm_k82f.conf b/samples/sensor/magn_trig/boards/frdm_k82f.conf new file mode 100644 index 0000000000000..008252267cd22 --- /dev/null +++ b/samples/sensor/magn_trig/boards/frdm_k82f.conf @@ -0,0 +1 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/magn_trig/boards/frdm_kw41z.conf b/samples/sensor/magn_trig/boards/frdm_kw41z.conf new file mode 100644 index 0000000000000..008252267cd22 --- /dev/null +++ b/samples/sensor/magn_trig/boards/frdm_kw41z.conf @@ -0,0 +1 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/magn_trig/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf b/samples/sensor/magn_trig/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf new file mode 100644 index 0000000000000..008252267cd22 --- /dev/null +++ b/samples/sensor/magn_trig/boards/mimxrt1050_evk_mimxrt1052_hyperflash.conf @@ -0,0 +1 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/magn_trig/boards/mimxrt1160_evk_mimxrt1166_cm7.conf b/samples/sensor/magn_trig/boards/mimxrt1160_evk_mimxrt1166_cm7.conf new file mode 100644 index 0000000000000..2a9f025bc1fa9 --- /dev/null +++ b/samples/sensor/magn_trig/boards/mimxrt1160_evk_mimxrt1166_cm7.conf @@ -0,0 +1,5 @@ +# +# check the fxos8700 dts for this board for addition settings +# + +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/magn_trig/boards/mimxrt1170_evk@A_mimxrt1176_cm7.conf b/samples/sensor/magn_trig/boards/mimxrt1170_evk@A_mimxrt1176_cm7.conf new file mode 100644 index 0000000000000..2a9f025bc1fa9 --- /dev/null +++ b/samples/sensor/magn_trig/boards/mimxrt1170_evk@A_mimxrt1176_cm7.conf @@ -0,0 +1,5 @@ +# +# check the fxos8700 dts for this board for addition settings +# + +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/magn_trig/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/samples/sensor/magn_trig/boards/mimxrt595_evk_mimxrt595s_cm33.conf new file mode 100644 index 0000000000000..ebcb58d5b5446 --- /dev/null +++ b/samples/sensor/magn_trig/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -0,0 +1,2 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y +CONFIG_FXOS8700_MODE_ACCEL=y diff --git a/samples/sensor/magn_trig/boards/mimxrt685_evk_mimxrt685s_cm33.conf b/samples/sensor/magn_trig/boards/mimxrt685_evk_mimxrt685s_cm33.conf new file mode 100644 index 0000000000000..008252267cd22 --- /dev/null +++ b/samples/sensor/magn_trig/boards/mimxrt685_evk_mimxrt685s_cm33.conf @@ -0,0 +1 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/magn_trig/boards/twr_ke18f.conf b/samples/sensor/magn_trig/boards/twr_ke18f.conf new file mode 100644 index 0000000000000..008252267cd22 --- /dev/null +++ b/samples/sensor/magn_trig/boards/twr_ke18f.conf @@ -0,0 +1 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/magn_trig/boards/twr_ke18f.overlay b/samples/sensor/magn_trig/boards/twr_ke18f.overlay new file mode 100644 index 0000000000000..c35b67ae86dc5 --- /dev/null +++ b/samples/sensor/magn_trig/boards/twr_ke18f.overlay @@ -0,0 +1,12 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2025 NXP + */ + + +&fxos8700 { + status = "okay"; + int1-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; + int2-gpios = <&gpioa 17 GPIO_ACTIVE_LOW>; +}; diff --git a/samples/sensor/magn_trig/boards/twr_kv58f220m.conf b/samples/sensor/magn_trig/boards/twr_kv58f220m.conf new file mode 100644 index 0000000000000..008252267cd22 --- /dev/null +++ b/samples/sensor/magn_trig/boards/twr_kv58f220m.conf @@ -0,0 +1 @@ +CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/magn_trig/sample.yaml b/samples/sensor/magn_trig/sample.yaml index 8f4a27381a04d..0e49242ce7715 100644 --- a/samples/sensor/magn_trig/sample.yaml +++ b/samples/sensor/magn_trig/sample.yaml @@ -6,6 +6,7 @@ tests: tags: sensors filter: dt_alias_exists("magn0") harness_config: + fixture: fixture_sensor_magn_int type: one_line regex: - "^\\s*[0-9A-Za-z_,+-.]*@[0-9A-Fa-f]* \\(x, y, z\\): \ diff --git a/samples/sensor/mcux_acmp/README.rst b/samples/sensor/mcux_acmp/README.rst index 765169fa0e186..9f7d58e91bcd7 100644 --- a/samples/sensor/mcux_acmp/README.rst +++ b/samples/sensor/mcux_acmp/README.rst @@ -42,7 +42,7 @@ ACMP input voltage by changing the voltage input to J25-13. .. zephyr-app-commands:: :zephyr-app: samples/sensor/mcux_acmp - :board: mimxrt1170_evk_cm7 + :board: mimxrt1170_evk@A/mimxrt1176/cm7 :goals: flash :compact: diff --git a/samples/sensor/mcux_acmp/sample.yaml b/samples/sensor/mcux_acmp/sample.yaml index a00773fdbb68c..c077538abeb2c 100644 --- a/samples/sensor/mcux_acmp/sample.yaml +++ b/samples/sensor/mcux_acmp/sample.yaml @@ -4,8 +4,8 @@ sample: common: platform_allow: - twr_ke18f - - mimxrt1170_evk/mimxrt1176/cm7 - - mimxrt1170_evk/mimxrt1176/cm4 + - mimxrt1170_evk@A/mimxrt1176/cm7 + - mimxrt1170_evk@A/mimxrt1176/cm4 - frdm_ke17z - frdm_ke17z512 - mimxrt1180_evk/mimxrt1189/cm33 diff --git a/samples/sensor/mcux_lpcmp/README.rst b/samples/sensor/mcux_lpcmp/README.rst index 3f6a5631debf0..69becfac9b3e6 100644 --- a/samples/sensor/mcux_lpcmp/README.rst +++ b/samples/sensor/mcux_lpcmp/README.rst @@ -46,3 +46,14 @@ LPCMP positive input port voltage by changing the voltage input to J2-8. :board: frdm_mcxn236 :goals: build flash :compact: + +Building and Running for NXP FRDM-MCXA156 +========================================= +Build the application for the :zephyr:board:`frdm_mcxa156` board, and adjust the +LPCMP positive input port voltage by changing the voltage input to J2-9. + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/mcux_lpcmp + :board: frdm_mcxa156 + :goals: build flash + :compact: diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa156.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa156.overlay new file mode 100644 index 0000000000000..cec0ea5e62421 --- /dev/null +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa156.overlay @@ -0,0 +1,9 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&lpcmp0 { + function-clock = "CMP_CLOCK"; +}; diff --git a/samples/sensor/mcux_lpcmp/sample.yaml b/samples/sensor/mcux_lpcmp/sample.yaml index 505d36a0099e6..d23c4b5ed9eab 100644 --- a/samples/sensor/mcux_lpcmp/sample.yaml +++ b/samples/sensor/mcux_lpcmp/sample.yaml @@ -5,6 +5,7 @@ common: platform_allow: - frdm_mcxn947/mcxn947/cpu0 - frdm_mcxn236 + - frdm_mcxa156 integration_platforms: - frdm_mcxn947/mcxn947/cpu0 - frdm_mcxn236 diff --git a/samples/sensor/qdec/boards/mimxrt1050_evk.overlay b/samples/sensor/qdec/boards/mimxrt1050_evk_mimxrt1052_hyperflash.overlay similarity index 100% rename from samples/sensor/qdec/boards/mimxrt1050_evk.overlay rename to samples/sensor/qdec/boards/mimxrt1050_evk_mimxrt1052_hyperflash.overlay diff --git a/samples/sensor/qdec/prj.conf b/samples/sensor/qdec/prj.conf index 9fd06347851e4..51a1c5d3c3017 100644 --- a/samples/sensor/qdec/prj.conf +++ b/samples/sensor/qdec/prj.conf @@ -1,2 +1,3 @@ CONFIG_SENSOR=y CONFIG_PRINTK=y +CONFIG_GPIO=y diff --git a/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.conf b/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.conf new file mode 100644 index 0000000000000..80b1183f91e35 --- /dev/null +++ b/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.conf @@ -0,0 +1,10 @@ +# Copyright 2025 CogniPilot Foundation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_DEBUG=y +CONFIG_SENSOR_SHELL_STREAM=y +CONFIG_SENSOR_LOG_LEVEL_DBG=n +CONFIG_RTIO_SUBMIT_SEM=y +CONFIG_SPI_RTIO=y +CONFIG_SPI_ASYNC=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=10000 diff --git a/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.overlay b/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.overlay new file mode 100644 index 0000000000000..fa28bdb243067 --- /dev/null +++ b/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.overlay @@ -0,0 +1,26 @@ +/* Copyright 2025 CogniPilot Foundation */ +/* SPDX-License-Identifier: Apache-2.0 */ + +&lpspi1 { + /delete-node/ icm42688p0@0; + /delete-property/ dmas; + /delete-property/ dma-names; +}; + +&lpspi2 { + status = "okay"; + cs-gpios =<&gpio3 24 GPIO_ACTIVE_LOW>; + + icm42688_1: icm42688p1@0 { + compatible = "invensense,icm42688"; + reg = <0>; + int-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; + spi-max-frequency = <24000000>; + accel-pwr-mode = ; + accel-odr = ; + accel-fs = ; + gyro-pwr-mode = ; + gyro-odr = ; + gyro-fs = ; + }; +}; diff --git a/samples/sensor/sensor_shell/pytest/test_sensor_shell.py b/samples/sensor/sensor_shell/pytest/test_sensor_shell.py index 7a01bec9978c7..49627d6f4a2b9 100644 --- a/samples/sensor/sensor_shell/pytest/test_sensor_shell.py +++ b/samples/sensor/sensor_shell/pytest/test_sensor_shell.py @@ -21,16 +21,12 @@ def test_sensor_shell_info(shell: Shell): def test_sensor_shell_get(shell: Shell): logger.info('send "sensor get" command') - lines = shell.exec_command('sensor get sensor@0 voltage') - assert any(['channel type=31(voltage)' in line for line in lines]), 'expected response not found' - - lines = shell.exec_command('sensor get sensor@1 53') - assert any(['channel type=53(gauge_state_of_health)' in line for line in lines]), 'expected response not found' - # Channel should be the last one before 'all' (because 'all' doesn't print anything) so that the # for-loop in `parse_named_int()` will go through everything - lines = shell.exec_command('sensor get sensor@0 gauge_desired_charging_current') - assert any(['channel type=59(gauge_desired_charging_current)' in line for line in lines]), 'expected response not found' + for channel in range(59): + logger.info(f'channel {channel}') + lines = shell.exec_command(f'sensor get sensor@0 {channel}') + assert any([f'channel type={channel}' in line for line in lines]), 'expected response not found' logger.info('response is valid') @@ -41,7 +37,7 @@ def test_sensor_shell_attr_get(shell: Shell): lines = shell.exec_command('sensor attr_get sensor@0 co2 sampling_frequency') assert any(['sensor@0(channel=co2, attr=sampling_frequency)' in line for line in lines]), 'expected response not found' - lines = shell.exec_command('sensor attr_get sensor@1 53 3') + lines = shell.exec_command('sensor attr_get sensor@1 54 3') assert any(['sensor@1(channel=gauge_state_of_health, attr=slope_th)' in line for line in lines]), 'expected response not found' logger.info('response is valid') @@ -54,7 +50,7 @@ def test_sensor_shell_attr_set(shell: Shell): expected_line = 'sensor@0 channel=co2, attr=sampling_frequency set to value=1' assert any([expected_line in line for line in lines]), 'expected response not found' - lines = shell.exec_command('sensor attr_set sensor@1 53 3 1') + lines = shell.exec_command('sensor attr_set sensor@1 54 3 1') expected_line = 'sensor@1 channel=gauge_state_of_health, attr=slope_th set to value=1' assert any([expected_line in line for line in lines]), 'expected response not found' diff --git a/samples/sensor/stream_fifo/CMakeLists.txt b/samples/sensor/stream_fifo/CMakeLists.txt new file mode 100644 index 0000000000000..e056c0a32bc82 --- /dev/null +++ b/samples/sensor/stream_fifo/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(stream_fifo) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/sensor/stream_fifo/README.rst b/samples/sensor/stream_fifo/README.rst new file mode 100644 index 0000000000000..708e5f18ad0b6 --- /dev/null +++ b/samples/sensor/stream_fifo/README.rst @@ -0,0 +1,143 @@ +.. zephyr:code-sample:: stream_fifo + :name: Generic device FIFO streaming + :relevant-api: sensor_interface + + Get accelerometer/gyroscope/temperature FIFO data frames from a sensor using + SENSOR_TRIG_FIFO_WATERMARK as a trigger. + +Overview +******** + +This sample application demonstrates how to stream FIFO data using the :ref:`RTIO framework `. + +The streaming is started using the sensor_stream() API and it is self-sustained by the +SENSOR_TRIG_FIFO_WATERMARK trigger. + +Currently the sample gets/prints data for the following sensor channels: + +- SENSOR_CHAN_ACCEL_XYZ +- SENSOR_CHAN_GYRO_XYZ +- SENSOR_CHAN_DIE_TEMP +- SENSOR_CHAN_GAME_ROTATION_VECTOR +- SENSOR_CHAN_GRAVITY_VECTOR +- SENSOR_CHAN_GBIAS_XYZ + +Building and Running +******************** + +This sample supports up to 10 FIFO streaming devices. Each device needs +to be aliased as :samp:`stream{N}` where ``N`` goes from ``0`` to ``9``. For example: + +.. code-block:: devicetree + + / { + aliases { + stream0 = &lsm6dsv16x_6b_x_nucleo_iks4a1; + }; + }; + +.. note:: + Note that NUM_SENSORS defined in main.c must match ``N`` and should be set accordingly. + +Example devicetree overlays and configurations are already available for nucleo_f401re and +nucleo_h503rb in the boards directory: + +- :zephyr_file:`samples/sensor/stream_fifo/boards/nucleo_f401re.overlay` + + DT overlay file for the nucleo_f401re board. + +- :zephyr_file:`samples/sensor/stream_fifo/boards/nucleo_f401re.conf` + + Configuration file for the nucleo_f401re board. + +- :zephyr_file:`samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay` + + DT overlay file for the nucleo_h503rb board. + +- :zephyr_file:`samples/sensor/stream_fifo/boards/nucleo_h503rb.conf` + + Configuration file for the nucleo_h503rb board. + +For example, build and run sample for nucleo_h503rb with: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/stream_fifo + :board: nucleo_h503rb + :goals: build flash + :compact: + +Sample Output +============= + +The following example output is for lsm6dsv16x IMU device with accelerometer, gyroscope +and temperature sensor including also the Sensor Fusion Low Power (SFLP) information. +The FIFO watermark is set to 64. The board used is a nucleo_h503rb +equipped with a :ref:`x-nucleo-iks4a1` shield. + +.. code-block:: console + + FIFO count - 64 + XL data for lsm6dsv16x@6b 1680572433340ns (0.373229, -0.009569, 9.909734) + XL data for lsm6dsv16x@6b 1680639100006ns (0.354089, -0.023924, 9.909734) + XL data for lsm6dsv16x@6b 1680705766672ns (0.368444, 0.000000, 9.933659) + XL data for lsm6dsv16x@6b 1680772433338ns (0.373229, 0.000000, 9.924089) + XL data for lsm6dsv16x@6b 1680839100004ns (0.368444, -0.004784, 9.924089) + XL data for lsm6dsv16x@6b 1680905766670ns (0.363659, -0.009569, 9.924089) + XL data for lsm6dsv16x@6b 1680972433336ns (0.358874, -0.004784, 9.928874) + XL data for lsm6dsv16x@6b 1681039100002ns (0.363659, 0.004784, 9.928874) + GY data for lsm6dsv16x@6b 1680572433340ns (0.001524, -0.000609, 0.004269) + GY data for lsm6dsv16x@6b 1680639100006ns (-0.001219, 0.002134, 0.004879) + GY data for lsm6dsv16x@6b 1680705766672ns (0.001219, -0.001219, 0.004879) + GY data for lsm6dsv16x@6b 1680772433338ns (-0.000914, 0.001219, 0.003964) + GY data for lsm6dsv16x@6b 1680839100004ns (0.000914, -0.001219, 0.004574) + GY data for lsm6dsv16x@6b 1680905766670ns (0.001829, 0.000914, 0.005489) + GY data for lsm6dsv16x@6b 1680972433336ns (-0.000609, 0.000304, 0.004574) + GY data for lsm6dsv16x@6b 1681039100002ns (0.001829, 0.000304, 0.004879) + TP data for lsm6dsv16x@6b 1680572433340ns 24.347656 °C + TP data for lsm6dsv16x@6b 1680639100006ns 24.324218 °C + TP data for lsm6dsv16x@6b 1680705766672ns 24.316406 °C + TP data for lsm6dsv16x@6b 1680772433338ns 24.296875 °C + ROT data for lsm6dsv16x@6b 1680639100006ns (-0.000008, -0.018661, 0.021575, 0.999593) + ROT data for lsm6dsv16x@6b 1680705766672ns (-0.000139, -0.018524, 0.021606, 0.999594) + ROT data for lsm6dsv16x@6b 1680772433338ns (-0.000055, -0.018569, 0.021621, 0.999593) + ROT data for lsm6dsv16x@6b 1680839100004ns (-0.000050, -0.018539, 0.021606, 0.999594) + ROT data for lsm6dsv16x@6b 1680905766670ns (-0.000003, -0.018569, 0.021621, 0.999593) + ROT data for lsm6dsv16x@6b 1680972433336ns (0.000044, -0.018493, 0.021667, 0.999594) + ROT data for lsm6dsv16x@6b 1681039100002ns (0.000013, -0.018432, 0.021667, 0.999595) + ROT data for lsm6dsv16x@6b 1681105766668ns (0.000113, -0.018402, 0.021682, 0.999595) + GV data for lsm6dsv16x@6b 1680639100006ns (37.270999, -0.792999, 998.447998) + GV data for lsm6dsv16x@6b 1680705766672ns (36.965999, -1.037000, 998.447998) + GV data for lsm6dsv16x@6b 1680772433338ns (37.088001, -0.854000, 998.447998) + GV data for lsm6dsv16x@6b 1680839100004ns (37.027000, -0.854000, 998.447998) + GV data for lsm6dsv16x@6b 1680905766670ns (37.088001, -0.792999, 998.447998) + GV data for lsm6dsv16x@6b 1680972433336ns (36.904998, -0.670999, 998.447998) + GV data for lsm6dsv16x@6b 1681039100002ns (36.783000, -0.732000, 998.447998) + GV data for lsm6dsv16x@6b 1681105766668ns (36.722000, -0.548999, 998.447998) + GY GBIAS data for lsm6dsv16x@6b 1680572433340ns (0.000303, -0.000151, 0.004179) + GY GBIAS data for lsm6dsv16x@6b 1680639100006ns (0.000303, 0.000000, 0.004179) + GY GBIAS data for lsm6dsv16x@6b 1680705766672ns (0.000303, -0.000075, 0.004179) + GY GBIAS data for lsm6dsv16x@6b 1680772433338ns (0.000227, 0.000000, 0.004179) + GY GBIAS data for lsm6dsv16x@6b 1680839100004ns (0.000303, -0.000075, 0.004179) + GY GBIAS data for lsm6dsv16x@6b 1680905766670ns (0.000303, 0.000000, 0.004255) + GY GBIAS data for lsm6dsv16x@6b 1680972433336ns (0.000303, 0.000000, 0.004255) + GY GBIAS data for lsm6dsv16x@6b 1681039100002ns (0.000379, 0.000000, 0.004255) + XL data for lsm6dsv16x@6b 1681105766668ns (0.358874, -0.019139, 9.928874) + XL data for lsm6dsv16x@6b 1681172433334ns (0.382799, -0.004784, 9.962369) + XL data for lsm6dsv16x@6b 1681239100000ns (0.354089, 0.000000, 9.914519) + GY data for lsm6dsv16x@6b 1681105766668ns (0.000304, 0.002134, 0.004574) + GY data for lsm6dsv16x@6b 1681172433334ns (-0.000914, 0.000914, 0.004574) + GY data for lsm6dsv16x@6b 1681239100000ns (0.002744, -0.002439, 0.004879) + TP data for lsm6dsv16x@6b 1680839100004ns 24.339843 °C + TP data for lsm6dsv16x@6b 1680905766670ns 24.339843 °C + TP data for lsm6dsv16x@6b 1680972433336ns 24.289062 °C + TP data for lsm6dsv16x@6b 1681039100002ns 24.296875 °C + ROT data for lsm6dsv16x@6b 1681172433334ns (0.000049, -0.018310, 0.021697, 0.999596) + ROT data for lsm6dsv16x@6b 1681239100000ns (0.000020, -0.018371, 0.021697, 0.999595) + GV data for lsm6dsv16x@6b 1681172433334ns (36.539001, -0.670999, 998.447998) + GV data for lsm6dsv16x@6b 1681239100000ns (36.660999, -0.732000, 998.447998) + GY GBIAS data for lsm6dsv16x@6b 1681105766668ns (0.000379, 0.000000, 0.004331) + GY GBIAS data for lsm6dsv16x@6b 1681172433334ns (0.000303, 0.000075, 0.004331) + GY GBIAS data for lsm6dsv16x@6b 1681239100000ns (0.000379, 0.000000, 0.004331) + TP data for lsm6dsv16x@6b 1681105766668ns 24.289062 °C + TP data for lsm6dsv16x@6b 1681172433334ns 24.324218 °C + TP data for lsm6dsv16x@6b 1681239100000ns 24.281250 °C diff --git a/samples/sensor/stream_fifo/boards/nucleo_f401re.conf b/samples/sensor/stream_fifo/boards/nucleo_f401re.conf new file mode 100644 index 0000000000000..877b30fd2d651 --- /dev/null +++ b/samples/sensor/stream_fifo/boards/nucleo_f401re.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_I2C_RTIO=y +CONFIG_LSM6DSV16X_STREAM=y +CONFIG_LSM6DSV16X_ENABLE_TEMP=y diff --git a/samples/sensor/stream_fifo/boards/nucleo_f401re.overlay b/samples/sensor/stream_fifo/boards/nucleo_f401re.overlay new file mode 100644 index 0000000000000..a428b585ed569 --- /dev/null +++ b/samples/sensor/stream_fifo/boards/nucleo_f401re.overlay @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + + +/* + * Nucleo F401RE board + shield iks4a1 + * + * This devicetree overlay file will be automatically picked by the Zephyr + * build system when building the sample for the nucleo_f401re board. + */ + +/ { + aliases { + stream0 = &lsm6dsv16x_6b_x_nucleo_iks4a1; + }; +}; + +&arduino_i2c { + lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b { + compatible = "st,lsm6dsv16x"; + reg = <0x6b>; + accel-odr = ; + accel-range = ; + gyro-odr = ; + gyro-range = ; + fifo-watermark = <64>; + accel-fifo-batch-rate = ; + gyro-fifo-batch-rate = ; + temp-fifo-batch-rate = ; + int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */ + drdy-pin = <2>; + drdy-pulsed; + }; +}; diff --git a/samples/sensor/stream_fifo/boards/nucleo_h503rb.conf b/samples/sensor/stream_fifo/boards/nucleo_h503rb.conf new file mode 100644 index 0000000000000..877b30fd2d651 --- /dev/null +++ b/samples/sensor/stream_fifo/boards/nucleo_h503rb.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_I2C_RTIO=y +CONFIG_LSM6DSV16X_STREAM=y +CONFIG_LSM6DSV16X_ENABLE_TEMP=y diff --git a/samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay b/samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay new file mode 100644 index 0000000000000..95fbcacd48d9f --- /dev/null +++ b/samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + + +/* + * Nucleo F401RE board + shield iks4a1 + * + * This devicetree overlay file will be automatically picked by the Zephyr + * build system when building the sample for the nucleo_f401re board. + */ + +/ { + aliases { + stream0 = &lsm6dsv16x_6b_x_nucleo_iks4a1; + }; +}; + +&arduino_i2c { + lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b { + compatible = "st,lsm6dsv16x"; + reg = <0x6b>; + accel-odr = ; + accel-range = ; + gyro-odr = ; + gyro-range = ; + fifo-watermark = <64>; + accel-fifo-batch-rate = ; + gyro-fifo-batch-rate = ; + temp-fifo-batch-rate = ; + + sflp-odr = ; + sflp-fifo-enable = ; + int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */ + drdy-pin = <2>; + drdy-pulsed; + }; +}; diff --git a/samples/sensor/stream_fifo/prj.conf b/samples/sensor/stream_fifo/prj.conf new file mode 100644 index 0000000000000..b638fffcb3834 --- /dev/null +++ b/samples/sensor/stream_fifo/prj.conf @@ -0,0 +1,7 @@ +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_STDOUT_CONSOLE=y +CONFIG_SENSOR=y +CONFIG_SENSOR_ASYNC_API=y +CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/samples/sensor/stream_fifo/sample.yaml b/samples/sensor/stream_fifo/sample.yaml new file mode 100644 index 0000000000000..a3cd7465ae6a9 --- /dev/null +++ b/samples/sensor/stream_fifo/sample.yaml @@ -0,0 +1,12 @@ +sample: + name: Stream FIFO sample +tests: + sample.sensor.stream_fifo: + harness: console + tags: sensors + filter: dt_alias_exists("stream0") + harness_config: + type: one_line + regex: + - "^\\s*[0-9A-Za-z_,+-.]*@[0-9A-Fa-f]* \\[m\/s\\^2\\]: \ + \\(\\s*-?[0-9\\.]*,\\s*-?[0-9\\.]*,\\s*-?[0-9\\.]*\\)$" diff --git a/samples/sensor/stream_fifo/src/main.c b/samples/sensor/stream_fifo/src/main.c new file mode 100644 index 0000000000000..9b7564bd1becc --- /dev/null +++ b/samples/sensor/stream_fifo/src/main.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define STREAMDEV_ALIAS(i) DT_ALIAS(_CONCAT(stream, i)) +#define STREAMDEV_DEVICE(i, _) \ + IF_ENABLED(DT_NODE_EXISTS(STREAMDEV_ALIAS(i)), (DEVICE_DT_GET(STREAMDEV_ALIAS(i)),)) +#define NUM_SENSORS 1 + +/* support up to 10 sensors */ +static const struct device *const sensors[] = { LISTIFY(10, STREAMDEV_DEVICE, ()) }; + +#define STREAM_IODEV_SYM(id) CONCAT(stream_iodev, id) +#define STREAM_IODEV_PTR(id, _) &STREAM_IODEV_SYM(id) + +#define STREAM_TRIGGERS \ + { SENSOR_TRIG_FIFO_FULL, SENSOR_STREAM_DATA_NOP }, \ + { SENSOR_TRIG_FIFO_WATERMARK, SENSOR_STREAM_DATA_INCLUDE } + +#define STREAM_DEFINE_IODEV(id, _) \ + SENSOR_DT_STREAM_IODEV( \ + STREAM_IODEV_SYM(id), \ + STREAMDEV_ALIAS(id), \ + STREAM_TRIGGERS); + +LISTIFY(NUM_SENSORS, STREAM_DEFINE_IODEV, (;)); + +struct rtio_iodev *iodevs[NUM_SENSORS] = { LISTIFY(NUM_SENSORS, STREAM_IODEV_PTR, (,)) }; + +RTIO_DEFINE_WITH_MEMPOOL(stream_ctx, NUM_SENSORS, NUM_SENSORS, + NUM_SENSORS * 20, 256, sizeof(void *)); + +struct sensor_chan_spec accel_chan = { SENSOR_CHAN_ACCEL_XYZ, 0 }; +struct sensor_chan_spec gyro_chan = { SENSOR_CHAN_GYRO_XYZ, 0 }; +struct sensor_chan_spec temp_chan = { SENSOR_CHAN_DIE_TEMP, 0 }; +struct sensor_chan_spec rot_vector_chan = { SENSOR_CHAN_GAME_ROTATION_VECTOR, 0 }; +struct sensor_chan_spec gravity_chan = { SENSOR_CHAN_GRAVITY_VECTOR, 0 }; +struct sensor_chan_spec gbias_chan = { SENSOR_CHAN_GBIAS_XYZ, 0 }; + +#define TASK_STACK_SIZE 2048ul +static K_THREAD_STACK_ARRAY_DEFINE(thread_stack, NUM_SENSORS, TASK_STACK_SIZE); +static struct k_thread thread_id[NUM_SENSORS]; + +static void print_stream(void *p1, void *p2, void *p3) +{ + const struct device *dev = (const struct device *)p1; + struct rtio_iodev *iodev = (struct rtio_iodev *)p2; + int rc = 0; + const struct sensor_decoder_api *decoder; + struct rtio_cqe *cqe; + uint8_t *buf; + uint32_t buf_len; + struct rtio_sqe *handle; + uint8_t accel_buf[128] = { 0 }; + uint8_t gyro_buf[128] = { 0 }; + uint8_t temp_buf[64] = { 0 }; + uint8_t rot_vect_buf[128] = { 0 }; + uint8_t gravity_buf[128] = { 0 }; + uint8_t gbias_buf[128] = { 0 }; + struct sensor_three_axis_data *accel_data = (struct sensor_three_axis_data *)accel_buf; + struct sensor_three_axis_data *gyro_data = (struct sensor_three_axis_data *)gyro_buf; + struct sensor_q31_data *temp_data = (struct sensor_q31_data *)temp_buf; + struct sensor_game_rotation_vector_data *rot_vect_data = + (struct sensor_game_rotation_vector_data *)rot_vect_buf; + struct sensor_three_axis_data *gravity_data = (struct sensor_three_axis_data *)gravity_buf; + struct sensor_three_axis_data *gbias_data = (struct sensor_three_axis_data *)gbias_buf; + + /* Start the stream */ + printk("sensor_stream\n"); + sensor_stream(iodev, &stream_ctx, NULL, &handle); + + while (1) { + cqe = rtio_cqe_consume_block(&stream_ctx); + + if (cqe->result != 0) { + printk("async read failed %d\n", cqe->result); + return; + } + + rc = rtio_cqe_get_mempool_buffer(&stream_ctx, cqe, &buf, &buf_len); + + if (rc != 0) { + printk("get mempool buffer failed %d\n", rc); + return; + } + + const struct device *sensor = dev; + + rtio_cqe_release(&stream_ctx, cqe); + + rc = sensor_get_decoder(sensor, &decoder); + + if (rc != 0) { + printk("sensor_get_decoder failed %d\n", rc); + return; + } + + /* Frame iterator values when data comes from a FIFO */ + uint32_t accel_fit = 0, gyro_fit = 0; + uint32_t temp_fit = 0; + uint32_t rot_vect_fit = 0, gravity_fit = 0, gbias_fit = 0; + + /* Number of sensor data frames */ + uint16_t xl_count, gy_count, tp_count; + uint16_t rot_vect_count, gravity_count, gbias_count, frame_count; + + rc = decoder->get_frame_count(buf, accel_chan, &xl_count); + rc += decoder->get_frame_count(buf, gyro_chan, &gy_count); + rc += decoder->get_frame_count(buf, temp_chan, &tp_count); + rc += decoder->get_frame_count(buf, rot_vector_chan, &rot_vect_count); + rc += decoder->get_frame_count(buf, gravity_chan, &gravity_count); + rc += decoder->get_frame_count(buf, gbias_chan, &gbias_count); + + if (rc != 0) { + printk("sensor_get_frame failed %d\n", rc); + return; + } + + frame_count = xl_count + gy_count + tp_count; + frame_count += rot_vect_count + gravity_count + gbias_count; + + /* If a tap has occurred lets print it out */ + if (decoder->has_trigger(buf, SENSOR_TRIG_TAP)) { + printk("Tap! Sensor %s\n", dev->name); + } + + /* Decode all available sensor FIFO frames */ + printk("FIFO count - %d\n", frame_count); + + int i = 0; + + while (i < frame_count) { + int8_t c = 0; + + /* decode and print Accelerometer FIFO frames */ + c = decoder->decode(buf, accel_chan, &accel_fit, 8, accel_data); + + for (int k = 0; k < c; k++) { + printk("XL data for %s %lluns (%" PRIq(6) ", %" PRIq(6) + ", %" PRIq(6) ")\n", dev->name, + PRIsensor_three_axis_data_arg(*accel_data, k)); + } + i += c; + + /* decode and print Gyroscope FIFO frames */ + c = decoder->decode(buf, gyro_chan, &gyro_fit, 8, gyro_data); + + for (int k = 0; k < c; k++) { + printk("GY data for %s %lluns (%" PRIq(6) ", %" PRIq(6) + ", %" PRIq(6) ")\n", dev->name, + PRIsensor_three_axis_data_arg(*gyro_data, k)); + } + i += c; + + /* decode and print Temperature FIFO frames */ + c = decoder->decode(buf, temp_chan, &temp_fit, 4, temp_data); + + for (int k = 0; k < c; k++) { + printk("TP data for %s %lluns %s%d.%d °C\n", dev->name, + PRIsensor_q31_data_arg(*temp_data, k)); + } + i += c; + + /* decode and print Game Rotation Vector FIFO frames */ + c = decoder->decode(buf, rot_vector_chan, &rot_vect_fit, 8, rot_vect_data); + + for (int k = 0; k < c; k++) { + printk("ROT data for %s %lluns (%" PRIq(6) ", %" PRIq(6) + ", %" PRIq(6) ", %" PRIq(6) ")\n", dev->name, + PRIsensor_game_rotation_vector_data_arg(*rot_vect_data, k)); + } + i += c; + + /* decode and print Gravity Vector FIFO frames */ + c = decoder->decode(buf, gravity_chan, &gravity_fit, 8, gravity_data); + + for (int k = 0; k < c; k++) { + printk("GV data for %s %lluns (%" PRIq(6) ", %" PRIq(6) + ", %" PRIq(6) ")\n", dev->name, + PRIsensor_three_axis_data_arg(*gravity_data, k)); + } + i += c; + + /* decode and print Gyroscope GBIAS FIFO frames */ + c = decoder->decode(buf, gbias_chan, &gbias_fit, 8, gbias_data); + + for (int k = 0; k < c; k++) { + printk("GY GBIAS data for %s %lluns (%" PRIq(6) ", %" PRIq(6) + ", %" PRIq(6) ")\n", dev->name, + PRIsensor_three_axis_data_arg(*gbias_data, k)); + } + i += c; + } + + rtio_release_buffer(&stream_ctx, buf, buf_len); + } +} + +static void check_sensor_is_off(const struct device *dev) +{ + int ret; + struct sensor_value odr; + + ret = sensor_attr_get(dev, SENSOR_CHAN_ACCEL_XYZ, SENSOR_ATTR_SAMPLING_FREQUENCY, &odr); + + /* Check if accel is off */ + if (ret != 0 || (odr.val1 == 0 && odr.val2 == 0)) { + printk("%s WRN : accelerometer device is off\n", dev->name); + } + + ret = sensor_attr_get(dev, SENSOR_CHAN_GYRO_XYZ, SENSOR_ATTR_SAMPLING_FREQUENCY, &odr); + + /* Check if gyro is off */ + if (ret != 0 || (odr.val1 == 0 && odr.val2 == 0)) { + printk("%s WRN : gyroscope device is off\n", dev->name); + } +} + +int main(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(sensors); i++) { + if (!device_is_ready(sensors[i])) { + printk("sensor: device %s not ready.\n", sensors[i]->name); + return 0; + } + check_sensor_is_off(sensors[i]); + + k_thread_create(&thread_id[i], thread_stack[i], TASK_STACK_SIZE, print_stream, + (void *)sensors[i], (void *)iodevs[i], NULL, K_PRIO_COOP(5), + K_INHERIT_PERMS, K_FOREVER); + k_thread_start(&thread_id[i]); + } + + return 0; +} diff --git a/samples/sensor/tdk_apex/CMakeLists.txt b/samples/sensor/tdk_apex/CMakeLists.txt new file mode 100644 index 0000000000000..16fbf44e810ff --- /dev/null +++ b/samples/sensor/tdk_apex/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 TDK Invensense +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(tdk_apex) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/sensor/tdk_apex/README.rst b/samples/sensor/tdk_apex/README.rst new file mode 100644 index 0000000000000..9d6f9c20d13dc --- /dev/null +++ b/samples/sensor/tdk_apex/README.rst @@ -0,0 +1,134 @@ +.. zephyr:code-sample:: tdk_apex + :name: TDK Advanced Pedometer and Event Detection (APEX) + :relevant-api: sensor_interface + + Get TDK APEX event detection (trigger mode). + +Overview +******** + +This sample application shows how to use the APEX (Advanced Pedometer +and Event Detection) features of TDK Invensense sensors. It consists of: +** Pedometer: Tracks step count, and provide details such as the cadence +and the estimated activity type (Walk, Run, Unknown). +** Tilt Detection: Detects the Tilt when tilting the board with an angle +of 30 degrees or more. The tilt event is generated when the +position is held for 4 seconds. +** Wake on Motion (WoM): Detects motion per axis exceeding 195 mg threshold. +** Significant Motion Detector (SMD): Detects when the user has moved +significantly. +APEX features support are configured through devicetree. + +References +********** + + - https://invensense.tdk.com/download-pdf/an-000271-icm-42607x-and-icm-42670x-apex-motion-functions-description-and-usage/ + +Driver configuration +******************** + +The APEX is based on accelerometer data only. The TDK Sensor driver configures +accelerometer low power mode and the APEX operating frequency (25Hz or 50Hz). + +Wiring +******* + +This sample uses an external breakout for the sensor. A devicetree +overlay must be provided to identify the TDK sensor, the SPI or I2C bus interface and the interrupt +sensor GPIO. + +Building and Running +******************** + +This sample supports TDK IMU devices. Each device needs +to be aliased as ``tdk-apex-sensorN`` where ``N`` goes from ``0`` to ``9``. For example: + +.. code-block:: devicetree + + / { + aliases { + tdk-apex-sensor0 = &icm42670p; + }; + }; + +This sample supports APEX feature of TDK device. It needs to be specified as bellow: + +.. code-block:: devicetree + + icm42670p: icm42670p@0 { + apex = "pedometer"; + } + +Make sure the apex feature used is in devicetree, then build and run with: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/tdk_apex + :board: nrf52dk/nrf52832 + :goals: build flash + +Sample Output +============= + +.. code-block:: devicetree + + icm42670p: icm42670p@0 { + apex = "pedometer"; + } + +.. code-block:: console + + Found device "icm42670p@68", getting sensor data + [0:00:09.287]: STEP_DET count: 6 steps cadence: 2.0 steps/s activity: Unknown + [0:00:09.689]: STEP_DET count: 7 steps cadence: 2.1 steps/s activity: Walk + [0:00:10.051]: STEP_DET count: 8 steps cadence: 2.2 steps/s activity: Walk + [0:00:10.433]: STEP_DET count: 9 steps cadence: 2.2 steps/s activity: Walk + [0:00:10.835]: STEP_DET count: 10 steps cadence: 2.3 steps/s activity: Walk + + + +.. code-block:: devicetree + + icm42670p: icm42670p@0 { + apex = "tilt"; + } + +.. code-block:: console + + Found device "icm42670p@68", getting sensor data + [0:00:15.249]: TILT + [0:00:21.479]: TILT + [0:00:26.765]: TILT + + + +.. code-block:: devicetree + + icm42670p: icm42670p@0 { + apex = "wom"; + } + +.. code-block:: console + + Found device "icm42670p@68", getting sensor data + [0:00:02.555]: WOM x=1 y=0 z=1 + [0:00:02.636]: WOM x=0 y=0 z=1 + [0:00:02.797]: WOM x=0 y=1 z=0 + [0:00:02.877]: WOM x=0 y=0 z=1 + [0:00:02.957]: WOM x=1 y=1 z=1 + + + +.. code-block:: devicetree + + icm42670p: icm42670p@0 { + apex = "smd"; + } + +.. code-block:: console + + Found device "icm42670@68", getting sensor data + [0:00:04.622]: SMD + [0:00:05.084]: SMD + [0:00:05.566]: SMD + + diff --git a/samples/sensor/tdk_apex/boards/nrf52dk_nrf52832_i2c.overlay b/samples/sensor/tdk_apex/boards/nrf52dk_nrf52832_i2c.overlay new file mode 100644 index 0000000000000..8c9056772605e --- /dev/null +++ b/samples/sensor/tdk_apex/boards/nrf52dk_nrf52832_i2c.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024, TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Get a node identifier for TDK IMU sensor supporting APEX feature. + */ +/ { + aliases { + tdk-apex-sensor0 = &icm42670p; + }; +}; + +/* + * Example configuration of a ICM42670-P device on i2c0 compatible with an Arduino I2C bus. + * + * Device address 0x68 is assumed. Your device may have a different + * address; check your device documentation if unsure. + */ +&arduino_i2c { + status = "okay"; + icm42670p: icm42670p@68 { + compatible = "invensense,icm42670p"; + reg = <0x68>; + int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ + accel-hz = <50>; + gyro-hz = <50>; + accel-fs = <16>; + gyro-fs = <2000>; + apex = "pedometer"; + }; +}; diff --git a/samples/sensor/tdk_apex/boards/nrf52dk_nrf52832_spi.overlay b/samples/sensor/tdk_apex/boards/nrf52dk_nrf52832_spi.overlay new file mode 100644 index 0000000000000..a7976d29ed2ac --- /dev/null +++ b/samples/sensor/tdk_apex/boards/nrf52dk_nrf52832_spi.overlay @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Get a node identifier for TDK IMU sensor supporting APEX feature. + */ +/ { + aliases { + tdk-apex-sensor0 = &icm42670p; + }; +}; + +/* + * Example configuration of a ICM42670-P device on spi2 compatible with an Arduino SPI bus. + */ +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ + icm42670p: icm42670p@0 { + compatible = "invensense,icm42670p"; + reg = <0>; + spi-max-frequency = <1000000>; /* conservatively set to 1MHz */ + int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ + accel-hz = <50>; + gyro-hz = <50>; + accel-fs = <16>; + gyro-fs = <2000>; + apex = "pedometer"; + }; +}; diff --git a/samples/sensor/tdk_apex/prj.conf b/samples/sensor/tdk_apex/prj.conf new file mode 100644 index 0000000000000..7731b5b6de1e3 --- /dev/null +++ b/samples/sensor/tdk_apex/prj.conf @@ -0,0 +1,19 @@ +# +# Copyright (c) 2024 TDK Invensense +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SENSOR=y +CONFIG_LOG=y +CONFIG_SENSOR_LOG_LEVEL_DBG=n + +# Floating point format support +# Selecting this increases stack size requirements slightly, but increases code size significantly. +CONFIG_CBPRINTF_FP_SUPPORT=y + +# nrf52dk/nrf52832 specific +CONFIG_USE_SEGGER_RTT=n + +# Trigger mode: sample is using interrupt triggering +CONFIG_ICM42X70_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/tdk_apex/sample.yaml b/samples/sensor/tdk_apex/sample.yaml new file mode 100644 index 0000000000000..5b266cc8104de --- /dev/null +++ b/samples/sensor/tdk_apex/sample.yaml @@ -0,0 +1,9 @@ +sample: + name: TDK Sensor APEX sample +tests: + sample.sensor.icm42670.apex: + build_only: true + tags: sensors + filter: dt_alias_exists("tdk_apex_sensor0") + integration_platforms: + - nrf52dk/nrf52832 diff --git a/samples/sensor/tdk_apex/src/main.c b/samples/sensor/tdk_apex/src/main.c new file mode 100644 index 0000000000000..09e1cc7a0455c --- /dev/null +++ b/samples/sensor/tdk_apex/src/main.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2024 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +static struct sensor_trigger data_trigger; + +/* Flag set from IMU device irq handler */ +static volatile int irq_from_device; + +/* + * Get a device structure from a devicetree node from alias + * "tdk_apex_sensor0". + */ +static const struct device *get_tdk_apex_device(void) +{ + const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(tdk_apex_sensor0)); + + if (!device_is_ready(dev)) { + printk("\nError: Device \"%s\" is not ready; " + "check the driver initialization logs for errors.\n", + dev->name); + return NULL; + } + + printk("Found device \"%s\", getting sensor data\n", dev->name); + return dev; +} + +static const char *now_str(void) +{ + static char buf[16]; /* ...HH:MM:SS.MMM */ + uint32_t now = k_uptime_get_32(); + unsigned int ms = now % MSEC_PER_SEC; + unsigned int s; + unsigned int min; + unsigned int h; + + now /= MSEC_PER_SEC; + s = now % 60U; + now /= 60U; + min = now % 60U; + now /= 60U; + h = now; + + snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u", h, min, s, ms); + return buf; +} + +static void handle_tdk_apex_drdy(const struct device *dev, const struct sensor_trigger *trig) +{ + if (trig->type == SENSOR_TRIG_MOTION) { + int rc = sensor_sample_fetch_chan(dev, trig->chan); + + if (rc < 0) { + printf("sample fetch failed: %d\n", rc); + printf("cancelling trigger due to failure: %d\n", rc); + (void)sensor_trigger_set(dev, trig, NULL); + return; + } else if (rc == 0) { + irq_from_device = 1; + } + } +} + +int main(void) +{ + const struct device *dev = get_tdk_apex_device(); + struct sensor_value apex_mode; + + if (dev == NULL) { + return 0; + } + + sensor_attr_get(dev, SENSOR_CHAN_APEX_MOTION, SENSOR_ATTR_CONFIGURATION, &apex_mode); + if (apex_mode.val1 == TDK_APEX_PEDOMETER) { + printf("Pedometer data sample.\n"); + } else if (apex_mode.val1 == TDK_APEX_TILT) { + printf("Tilt data sample.\n"); + } else if (apex_mode.val1 == TDK_APEX_WOM) { + printf("WOM data sample.\n"); + } else if (apex_mode.val1 == TDK_APEX_SMD) { + printf("SMD data sample.\n"); + } + apex_mode.val2 = 0; + sensor_attr_set(dev, SENSOR_CHAN_APEX_MOTION, SENSOR_ATTR_CONFIGURATION, &apex_mode); + + data_trigger = (struct sensor_trigger){ + .type = SENSOR_TRIG_MOTION, + .chan = SENSOR_CHAN_APEX_MOTION, + }; + if (sensor_trigger_set(dev, &data_trigger, handle_tdk_apex_drdy) < 0) { + printf("Cannot configure data trigger!!!\n"); + return 0; + } + + printf("Configured for APEX data collecting.\n"); + + k_sleep(K_MSEC(1000)); + + while (1) { + + if (irq_from_device) { + if (apex_mode.val1 == TDK_APEX_PEDOMETER) { + struct sensor_value apex_pedometer[3]; + + sensor_channel_get(dev, SENSOR_CHAN_APEX_MOTION, apex_pedometer); + + printf("[%s]: STEP_DET count: %d steps cadence: %.1f steps/s " + "activity: %s\n", + now_str(), apex_pedometer[0].val1, + sensor_value_to_double(&apex_pedometer[2]), + apex_pedometer[1].val1 == 1 ? "Walk" + : apex_pedometer[1].val1 == 2 ? "Run" + : "Unknown"); + } else if (apex_mode.val1 == TDK_APEX_TILT) { + struct sensor_value apex_tilt; + + sensor_channel_get(dev, SENSOR_CHAN_APEX_MOTION, &apex_tilt); + + printf("[%s]: %s\n", now_str(), + apex_tilt.val1 ? "TILT" : "Unknown trig"); + } else if (apex_mode.val1 == TDK_APEX_WOM) { + struct sensor_value apex_wom[3]; + + sensor_channel_get(dev, SENSOR_CHAN_APEX_MOTION, apex_wom); + + printf("[%s]: WOM x=%d y=%d z=%d\n", now_str(), apex_wom[0].val1, + apex_wom[1].val1, apex_wom[2].val1); + } else if (apex_mode.val1 == TDK_APEX_SMD) { + struct sensor_value apex_smd; + + sensor_channel_get(dev, SENSOR_CHAN_APEX_MOTION, &apex_smd); + + printf("[%s]: %s\n", now_str(), + apex_smd.val1 ? "SMD" : "Unknown trig"); + } + irq_from_device = 0; + } + } + return 0; +} diff --git a/samples/sensor/thermometer/sample.yaml b/samples/sensor/thermometer/sample.yaml index 7d6b3479eb63a..ce7c59c53d2a2 100644 --- a/samples/sensor/thermometer/sample.yaml +++ b/samples/sensor/thermometer/sample.yaml @@ -1,20 +1,43 @@ sample: name: Temperature Sensor +common: + filter: dt_alias_exists("ambient-temp0") + harness: console tests: sample.sensor.thermometer: tags: sensors - filter: dt_alias_exists("ambient-temp0") + harness_config: + fixture: sensor_ambient_temp + type: multi_line + regex: + - "Thermometer Example (.*)" + - "Temperature device is 0x[0-9|a-z]+, name is [a-z|0-9]+@[a-z|0-9]+" + - "Temperature is [0-9|.]+°C" integration_platforms: - nrf52840dk/nrf52840 # mcp9700a - frdm_k22f # tcn75a - robokit1 # ntc_thermistor - adi_eval_adin1110ebz # adt7420 - - frdm_mcxn947/mcxn947/cpu0 # p3t1755 - harness: console + extra_args: + - platform:mimxrt1180_evk/mimxrt1189/cm33:SHIELD=p3t1755dp_ard_i2c + - platform:mimxrt1180_evk/mimxrt1189/cm7:SHIELD=p3t1755dp_ard_i2c + - platform:frdm_mcxn236/mcxn236:SHIELD=p3t1755dp_ard_i2c + - platform:mimxrt700_evk/mimxrt798s/cm33_cpu0:SHIELD=p3t1755dp_ard_i2c + sample.sensor.thermometer_i3c: + tags: sensors harness_config: - fixture: sensor_ambient_temp + fixture: sensor_ambient_temp_i3c type: multi_line regex: - "Thermometer Example (.*)" - "Temperature device is 0x[0-9|a-z]+, name is [a-z|0-9]+@[a-z|0-9]+" - "Temperature is [0-9|.]+°C" + integration_platforms: + - frdm_mcxn947/mcxn947/cpu0 # p3t1755 + depends_on: + - i3c + filter: dt_alias_exists("ambient-temp0") + extra_args: + - platform:mimxrt1180_evk/mimxrt1189/cm33:SHIELD=p3t1755dp_ard_i3c + - platform:mimxrt1180_evk/mimxrt1189/cm7:SHIELD=p3t1755dp_ard_i3c + - platform:frdm_mcxn236/mcxn236:SHIELD=p3t1755dp_ard_i3c diff --git a/samples/sensor/vl53l0x/README.rst b/samples/sensor/vl53l0x/README.rst index 53f4bc9e1f919..4d7fbc6f02053 100644 --- a/samples/sensor/vl53l0x/README.rst +++ b/samples/sensor/vl53l0x/README.rst @@ -9,7 +9,7 @@ Overview This sample periodically measures distance between vl53l0x sensor and target. The result is displayed on the console. -It also shows how we can use the vl53l0x as a proximity sensor. +It shows the usage of all available channels including private ones. Requirements ************ @@ -24,24 +24,33 @@ References Building and Running ******************** - This project outputs sensor data to the console. It requires a VL53L0X - sensor, which is present on the disco_l475_iot1 board. +This project outputs sensor data to the console. It requires a VL53L0X +sensor, which is present on the disco_l475_iot1 board. - .. zephyr-app-commands:: - :zephyr-app: samples/sensor/vl53l0x/ - :goals: build flash +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/vl53l0x/ + :goals: build flash Sample Output ============= - .. code-block:: console - - prox is 0 - distance is 1938 - prox is 1 - distance is 70 - prox is 0 - distance is 1995 - - +.. code-block:: console + + prox is 0 + distance is 1874 mm + Max distance is 000 mm + Signal rate is 33435 Cps + Ambient rate is 17365 Cps + SPADs used: 195 + Status: OK + + prox is 0 + distance is 1888 mm + Max distance is 000 mm + Signal rate is 20846 Cps + Ambient rate is 25178 Cps + SPADs used: 195 + Status: OK + + diff --git a/samples/sensor/vl53l0x/src/main.c b/samples/sensor/vl53l0x/src/main.c index cfed1adaa623b..e9b76d410e777 100644 --- a/samples/sensor/vl53l0x/src/main.c +++ b/samples/sensor/vl53l0x/src/main.c @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include int main(void) { @@ -31,12 +31,30 @@ int main(void) ret = sensor_channel_get(dev, SENSOR_CHAN_PROX, &value); printk("prox is %d\n", value.val1); - ret = sensor_channel_get(dev, - SENSOR_CHAN_DISTANCE, - &value); - printf("distance is %.3fm\n", sensor_value_to_double(&value)); + ret = sensor_channel_get(dev, SENSOR_CHAN_DISTANCE, &value); + printk("distance is %.3lld mm\n", sensor_value_to_milli(&value)); - k_sleep(K_MSEC(1000)); + ret = sensor_channel_get(dev, SENSOR_CHAN_VL53L0X_RANGE_DMAX, &value); + printk("Max distance is %.3lld mm\n", sensor_value_to_milli(&value)); + + ret = sensor_channel_get(dev, SENSOR_CHAN_VL53L0X_SIGNAL_RATE_RTN_CPS, &value); + printk("Signal rate is %d Cps\n", value.val1); + + ret = sensor_channel_get(dev, SENSOR_CHAN_VL53L0X_AMBIENT_RATE_RTN_CPS, &value); + printk("Ambient rate is %d Cps\n", value.val1); + + ret = sensor_channel_get(dev, SENSOR_CHAN_VL53L0X_EFFECTIVE_SPAD_RTN_COUNT, &value); + printk("SPADs used: %d\n", value.val1); + + ret = sensor_channel_get(dev, SENSOR_CHAN_VL53L0X_RANGE_STATUS, &value); + if (value.val1 == VL53L0X_RANGE_STATUS_RANGE_VALID) { + printk("Status: OK\n"); + } else { + printk("Status: Error code %d\n", value.val1); + } + + printk("\n"); + k_sleep(K_MSEC(5000)); } return 0; } diff --git a/samples/shields/x_nucleo_iks4a1/standard/README.rst b/samples/shields/x_nucleo_iks4a1/standard/README.rst index 7f6b93787613e..6069d8ac4da38 100644 --- a/samples/shields/x_nucleo_iks4a1/standard/README.rst +++ b/samples/shields/x_nucleo_iks4a1/standard/README.rst @@ -16,6 +16,7 @@ periodically reads and displays data from the shield sensors: - LSM6DSO16IS 6-Axis acceleration and angular velocity - LPS22DF ambient temperature and atmospheric pressure - LIS2MDL 3-Axis magnetic field intensity +- LIS2DUXS12 3-Axis acceleration Requirements ************ @@ -53,10 +54,14 @@ Sample Output LSM6DSV16X: GYro (dps): x: -0.000, y: 0.000, z: 0.005 LPS22DF: Temperature: 25.2 C LPS22DF: Pressure:98.121 kpa + LIS2DUXS12: Accel (m.s-2): x: 0.689, y: -0.306, z: 9.571 + LIS2DUXS12: Temperature: 23.9 C + 10:: lis2mdl trig 1839 10:: lsm6dso16is acc trig 3892 10:: lsm6dsv16x acc trig 4412 10:: lps22df trig 174 + 10:: lis2duxs12 acc trig 3681 diff --git a/samples/shields/x_nucleo_iks4a1/standard/prj.conf b/samples/shields/x_nucleo_iks4a1/standard/prj.conf index 3d831e846e295..0aa79db759f79 100644 --- a/samples/shields/x_nucleo_iks4a1/standard/prj.conf +++ b/samples/shields/x_nucleo_iks4a1/standard/prj.conf @@ -5,8 +5,10 @@ CONFIG_SENSOR=y CONFIG_SENSOR_LOG_LEVEL_DBG=y CONFIG_LIS2MDL_TRIGGER_OWN_THREAD=y CONFIG_LPS2XDF_TRIGGER_OWN_THREAD=y -CONFIG_LSM6DSO16IS_TRIGGER_OWN_THREAD=y +CONFIG_LSM6DSO16IS_TRIGGER_NONE=y CONFIG_LSM6DSO16IS_ENABLE_TEMP=y CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSV16X_ENABLE_TEMP=y +CONFIG_LIS2DUX12_TRIGGER_OWN_THREAD=y +CONFIG_LIS2DUX12_ENABLE_TEMP=y CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/samples/shields/x_nucleo_iks4a1/standard/src/main.c b/samples/shields/x_nucleo_iks4a1/standard/src/main.c index 84d7756b76efb..c4aef34c943a0 100644 --- a/samples/shields/x_nucleo_iks4a1/standard/src/main.c +++ b/samples/shields/x_nucleo_iks4a1/standard/src/main.c @@ -54,6 +54,17 @@ static void lsm6dsv16x_acc_trig_handler(const struct device *dev, } #endif +#ifdef CONFIG_LIS2DUX12_TRIGGER +static int lis2duxs12_acc_trig_cnt; + +static void lis2duxs12_acc_trig_handler(const struct device *dev, + const struct sensor_trigger *trig) +{ + sensor_sample_fetch_chan(dev, SENSOR_CHAN_ALL); + lis2duxs12_acc_trig_cnt++; +} +#endif + static void lis2mdl_config(const struct device *lis2mdl) { struct sensor_value odr_attr; @@ -214,6 +225,37 @@ static void lps22df_config(const struct device *lps22df) #endif } +static void lis2duxs12_config(const struct device *lis2duxs12) +{ + struct sensor_value odr_attr, fs_attr; + + /* set LSM6DSV16X accel sampling frequency to 200 Hz */ + odr_attr.val1 = 200; + odr_attr.val2 = 0; + + if (sensor_attr_set(lis2duxs12, SENSOR_CHAN_ACCEL_XYZ, + SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) { + printk("Cannot set sampling frequency for LSM6DSV16X accel\n"); + return; + } + + sensor_g_to_ms2(16, &fs_attr); + + if (sensor_attr_set(lis2duxs12, SENSOR_CHAN_ACCEL_XYZ, + SENSOR_ATTR_FULL_SCALE, &fs_attr) < 0) { + printk("Cannot set fs for LSM6DSV16X accel\n"); + return; + } + +#ifdef CONFIG_LIS2DUX12_TRIGGER + struct sensor_trigger trig; + + trig.type = SENSOR_TRIG_DATA_READY; + trig.chan = SENSOR_CHAN_ACCEL_XYZ; + sensor_trigger_set(lis2duxs12, &trig, lis2duxs12_acc_trig_handler); +#endif +} + int main(void) { struct sensor_value lis2mdl_magn[3], lis2mdl_temp, lps22df_press, lps22df_temp; @@ -225,10 +267,12 @@ int main(void) struct sensor_value lsm6dsv16x_temp; #endif struct sensor_value lsm6dsv16x_xl[3], lsm6dsv16x_gy[3]; + struct sensor_value lis2duxs12_xl[3], lis2duxs12_temp; const struct device *const lis2mdl = DEVICE_DT_GET_ONE(st_lis2mdl); const struct device *const lsm6dso16is = DEVICE_DT_GET_ONE(st_lsm6dso16is); const struct device *const lsm6dsv16x = DEVICE_DT_GET_ONE(st_lsm6dsv16x); const struct device *const lps22df = DEVICE_DT_GET_ONE(st_lps22df); + const struct device *const lis2duxs12 = DEVICE_DT_GET_ONE(st_lis2duxs12); int cnt = 1; if (!device_is_ready(lsm6dso16is)) { @@ -247,11 +291,16 @@ int main(void) printk("%s: device not ready.\n", lps22df->name); return 0; } + if (!device_is_ready(lis2duxs12)) { + printk("%s: device not ready.\n", lis2duxs12->name); + return 0; + } lis2mdl_config(lis2mdl); lsm6dso16is_config(lsm6dso16is); lsm6dsv16x_config(lsm6dsv16x); lps22df_config(lps22df); + lis2duxs12_config(lis2duxs12); while (1) { /* Get sensor samples */ @@ -280,6 +329,12 @@ int main(void) return 0; } #endif +#ifndef CONFIG_LIS2DUX12_TRIGGER + if (sensor_sample_fetch(lis2duxs12) < 0) { + printf("LIS2DUXS12 XL Sensor sample update error\n"); + return 0; + } +#endif /* Get sensor data */ sensor_channel_get(lis2mdl, SENSOR_CHAN_MAGN_XYZ, lis2mdl_magn); @@ -298,6 +353,8 @@ int main(void) sensor_channel_get(lps22df, SENSOR_CHAN_PRESS, &lps22df_press); sensor_channel_get(lps22df, SENSOR_CHAN_AMBIENT_TEMP, &lps22df_temp); + sensor_channel_get(lis2duxs12, SENSOR_CHAN_ACCEL_XYZ, lis2duxs12_xl); + sensor_channel_get(lis2duxs12, SENSOR_CHAN_DIE_TEMP, &lis2duxs12_temp); /* Display sensor data */ /* Erase previous */ @@ -349,6 +406,14 @@ int main(void) printf("LPS22DF: Temperature: %.1f C\n", sensor_value_to_double(&lps22df_temp)); printf("LPS22DF: Pressure:%.3f kpa\n", sensor_value_to_double(&lps22df_press)); + printf("LIS2DUXS12: Accel (m.s-2): x: %.3f, y: %.3f, z: %.3f\n", + sensor_value_to_double(&lis2duxs12_xl[0]), + sensor_value_to_double(&lis2duxs12_xl[1]), + sensor_value_to_double(&lis2duxs12_xl[2])); + + printf("LIS2DUXS12: Temperature: %.1f C\n", + sensor_value_to_double(&lis2duxs12_temp)); + #if defined(CONFIG_LIS2MDL_TRIGGER) printk("%d: lis2mdl trig %d\n", cnt, lis2mdl_trig_cnt); #endif @@ -363,6 +428,9 @@ int main(void) #ifdef CONFIG_LPS2XDF_TRIGGER printk("%d: lps22df trig %d\n", cnt, lps22df_trig_cnt); #endif +#ifdef CONFIG_LIS2DUX12_TRIGGER + printk("%d:: lis2duxs12 acc trig %d\n", cnt, lis2duxs12_acc_trig_cnt); +#endif cnt++; k_sleep(K_MSEC(2000)); diff --git a/samples/subsys/debug/debugmon/prj.conf b/samples/subsys/debug/debugmon/prj.conf index fd4651957c1d3..f4d311233ef3a 100644 --- a/samples/subsys/debug/debugmon/prj.conf +++ b/samples/subsys/debug/debugmon/prj.conf @@ -1 +1,2 @@ CONFIG_CORTEX_M_DEBUG_MONITOR_HOOK=y +CONFIG_GPIO=y diff --git a/samples/subsys/display/lvgl/Kconfig b/samples/subsys/display/lvgl/Kconfig new file mode 100644 index 0000000000000..e86f91cd7b775 --- /dev/null +++ b/samples/subsys/display/lvgl/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +mainmenu "LVGL Sample" + +config RESET_COUNTER_SW0 + bool "Reset counter when sw0 is pressed" + depends on $(dt_alias_enabled,sw0) + select GPIO + default y diff --git a/samples/subsys/display/lvgl/prj.conf b/samples/subsys/display/lvgl/prj.conf index 41c0eca6e70fc..2d7f2f196f24c 100644 --- a/samples/subsys/display/lvgl/prj.conf +++ b/samples/subsys/display/lvgl/prj.conf @@ -1,6 +1,6 @@ CONFIG_LV_Z_MEM_POOL_SIZE=16384 CONFIG_LV_Z_SHELL=y -CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_MAIN_STACK_SIZE=4096 CONFIG_DISPLAY=y CONFIG_DISPLAY_LOG_LEVEL_ERR=y @@ -9,11 +9,8 @@ CONFIG_LOG=y CONFIG_SHELL=y CONFIG_LVGL=y -CONFIG_LV_MEM_CUSTOM=y CONFIG_LV_USE_LOG=y CONFIG_LV_USE_LABEL=y -CONFIG_LV_USE_BTN=y CONFIG_LV_USE_ARC=y -CONFIG_LV_USE_IMG=y CONFIG_LV_USE_MONKEY=y CONFIG_LV_FONT_MONTSERRAT_14=y diff --git a/samples/subsys/display/lvgl/sample.yaml b/samples/subsys/display/lvgl/sample.yaml index ebb8b04270e53..185cf55e0135d 100644 --- a/samples/subsys/display/lvgl/sample.yaml +++ b/samples/subsys/display/lvgl/sample.yaml @@ -1,6 +1,14 @@ sample: description: LVGL sample application name: lvgl +common: + tags: + - display + - gui + - lvgl + - samples + modules: + - lvgl tests: sample.display.lvgl.gui: filter: dt_chosen_enabled("zephyr,display") @@ -11,16 +19,10 @@ tests: min_flash: 250 min_ram: 32 harness: none - tags: - - samples - - display - - gui - - lvgl - modules: - - lvgl integration_platforms: - native_sim/native/64 sample.display.lvgl.rk055hdmipi4m: + tags: shield # This sample is intended to test the RT1170 and RT595, which require # a display shield to work with LVGL min_flash: 250 @@ -28,12 +30,6 @@ tests: # but the RT595 uses external PSRAM for the display buffer min_ram: 32 harness: none - tags: - - samples - - display - - gui - modules: - - lvgl extra_args: SHIELD="rk055hdmipi4m" platform_allow: - mimxrt1170_evk/mimxrt1176/cm7 @@ -43,58 +39,68 @@ tests: harness_config: fixture: fixture_display_rk055hdmipi4m sample.subsys.display.lvgl.st_b_lcd40_dsi1_mb1166: + tags: shield filter: dt_compat_enabled("orisetech,otm8009a") platform_allow: stm32h747i_disco/stm32h747xx/m7 extra_args: SHIELD=st_b_lcd40_dsi1_mb1166 harness: console harness_config: fixture: fixture_display - modules: - - lvgl - tags: - - samples - - display - - shield - - lvgl - - gui sample.subsys.display.lvgl.st_b_lcd40_dsi1_mb1166_a09: + tags: shield filter: dt_compat_enabled("frida,nt35510") platform_allow: stm32h747i_disco/stm32h747xx/m7 extra_args: SHIELD=st_b_lcd40_dsi1_mb1166_a09 harness: console harness_config: fixture: fixture_display - modules: - - lvgl - tags: - - samples - - display - - shield - - lvgl - - gui - samples.subsys.display.lvgl.rk043fn66hs_ctg: + sample.subsys.display.lvgl.rk043fn66hs_ctg: + tags: shield platform_allow: - mimxrt1064_evk - - mimxrt1060_evk - - mimxrt1050_evk + - mimxrt1060_evk/mimxrt1062/qspi + - mimxrt1050_evk/mimxrt1052/hyperflash - mimxrt1040_evk integration_platforms: - mimxrt1040_evk - tags: display harness: console extra_args: SHIELD=rk043fn66hs_ctg harness_config: fixture: fixture_display_rk043fn66hs_ctg - samples.subsys.display.lvgl.rk043fn02h_ct: + sample.subsys.display.lvgl.rk043fn02h_ct: + tags: shield platform_allow: - mimxrt1064_evk - - mimxrt1060_evk - - mimxrt1050_evk + - mimxrt1060_evk@C/mimxrt1062/qspi + - mimxrt1050_evk/mimxrt1052/hyperflash - mimxrt1040_evk integration_platforms: - mimxrt1040_evk - tags: display harness: console extra_args: SHIELD=rk043fn02h_ct harness_config: fixture: fixture_display_rk043fn02h_ct + sample.subsys.display.lvgl.rtkmipilcdb00000be: + tags: shield + platform_allow: + - ek_ra8d1 + harness: console + extra_args: SHIELD=rtkmipilcdb00000be + harness_config: + fixture: fixture_display + sample.subsys.display.lvgl.seeed_xiao_round_display: + tags: shield + min_flash: 320 + min_ram: 64 + depends_on: + - xiao_adc + - xiao_gpio + - xiao_i2c + - xiao_spi + integration_platforms: + - xiao_ble + - xiao_esp32s3/esp32s3/procpu + extra_args: SHIELD=seeed_xiao_round_display + harness: console + harness_config: + fixture: fixture_seeed_xiao_round_display diff --git a/samples/subsys/display/lvgl/src/main.c b/samples/subsys/display/lvgl/src/main.c index 9f704eb442300..00e500ce14a2c 100644 --- a/samples/subsys/display/lvgl/src/main.c +++ b/samples/subsys/display/lvgl/src/main.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(app); static uint32_t count; -#ifdef CONFIG_GPIO +#ifdef CONFIG_RESET_COUNTER_SW0 static struct gpio_dt_spec button_gpio = GPIO_DT_SPEC_GET_OR( DT_ALIAS(sw0), gpios, {0}); static struct gpio_callback button_callback; @@ -35,7 +35,7 @@ static void button_isr_callback(const struct device *port, count = 0; } -#endif /* CONFIG_GPIO */ +#endif /* CONFIG_RESET_COUNTER_SW0 */ #ifdef CONFIG_LV_Z_ENCODER_INPUT static const struct device *lvgl_encoder = @@ -67,7 +67,7 @@ int main(void) return 0; } -#ifdef CONFIG_GPIO +#ifdef CONFIG_RESET_COUNTER_SW0 if (gpio_is_ready_dt(&button_gpio)) { int err; @@ -93,13 +93,13 @@ int main(void) return 0; } } -#endif /* CONFIG_GPIO */ +#endif /* CONFIG_RESET_COUNTER_SW0 */ #ifdef CONFIG_LV_Z_ENCODER_INPUT lv_obj_t *arc; lv_group_t *arc_group; - arc = lv_arc_create(lv_scr_act()); + arc = lv_arc_create(lv_screen_active()); lv_obj_align(arc, LV_ALIGN_CENTER, 0, -15); lv_obj_set_size(arc, 150, 150); @@ -113,9 +113,9 @@ int main(void) lv_group_t *btn_matrix_group; static const char *const btnm_map[] = {"1", "2", "3", "4", ""}; - btn_matrix = lv_btnmatrix_create(lv_scr_act()); + btn_matrix = lv_buttonmatrix_create(lv_screen_active()); lv_obj_align(btn_matrix, LV_ALIGN_CENTER, 0, 70); - lv_btnmatrix_set_map(btn_matrix, (const char **)btnm_map); + lv_buttonmatrix_set_map(btn_matrix, (const char **)btnm_map); lv_obj_set_size(btn_matrix, 100, 50); btn_matrix_group = lv_group_create(); @@ -126,22 +126,22 @@ int main(void) if (IS_ENABLED(CONFIG_LV_Z_POINTER_INPUT)) { lv_obj_t *hello_world_button; - hello_world_button = lv_btn_create(lv_scr_act()); + hello_world_button = lv_button_create(lv_screen_active()); lv_obj_align(hello_world_button, LV_ALIGN_CENTER, 0, -15); lv_obj_add_event_cb(hello_world_button, lv_btn_click_callback, LV_EVENT_CLICKED, NULL); hello_world_label = lv_label_create(hello_world_button); } else { - hello_world_label = lv_label_create(lv_scr_act()); + hello_world_label = lv_label_create(lv_screen_active()); } lv_label_set_text(hello_world_label, "Hello world!"); lv_obj_align(hello_world_label, LV_ALIGN_CENTER, 0, 0); - count_label = lv_label_create(lv_scr_act()); + count_label = lv_label_create(lv_screen_active()); lv_obj_align(count_label, LV_ALIGN_BOTTOM_MID, 0, 0); - lv_task_handler(); + lv_timer_handler(); display_blanking_off(display_dev); while (1) { @@ -149,7 +149,7 @@ int main(void) sprintf(count_str, "%d", count/100U); lv_label_set_text(count_label, count_str); } - lv_task_handler(); + lv_timer_handler(); ++count; k_sleep(K_MSEC(10)); } diff --git a/samples/subsys/fs/format/README.rst b/samples/subsys/fs/format/README.rst index 59029d2dbfae5..327563fbd9d01 100644 --- a/samples/subsys/fs/format/README.rst +++ b/samples/subsys/fs/format/README.rst @@ -45,6 +45,7 @@ Sample Output ============= When the sample runs successfully you should see following message on the screen: + .. code-block:: console I: LittleFS version 2.4, disk version 2.0 diff --git a/samples/subsys/fs/fs_sample/boards/max32666fthr_max32666_cpu0.conf b/samples/subsys/fs/fs_sample/boards/max32666fthr_max32666_cpu0.conf new file mode 100644 index 0000000000000..7b52334dee751 --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/max32666fthr_max32666_cpu0.conf @@ -0,0 +1,3 @@ +CONFIG_SDMMC_SUBSYS=y +CONFIG_SDHC=y +CONFIG_LOG=n diff --git a/samples/subsys/fs/littlefs/sample.yaml b/samples/subsys/fs/littlefs/sample.yaml index 8d26a2a3e0572..85fa6468ee45d 100644 --- a/samples/subsys/fs/littlefs/sample.yaml +++ b/samples/subsys/fs/littlefs/sample.yaml @@ -12,7 +12,7 @@ tests: - particle_xenon - disco_l475_iot1 - mimxrt685_evk/mimxrt685s/cm33 - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi - mimxrt1064_evk - qemu_x86 - native_sim @@ -26,6 +26,10 @@ tests: - nrf54l15dk/nrf54l15/cpuapp - frdm_ke17z - frdm_ke17z512 + - s32z2xxdc2/s32z270/rtu0 + - s32z2xxdc2/s32z270/rtu1 + - s32z2xxdc2@D/s32z270/rtu0 + - s32z2xxdc2@D/s32z270/rtu1 integration_platforms: - nrf52840dk/nrf52840 sample.filesystem.littlefs.blk: diff --git a/samples/subsys/ipc/ipc_service/icmsg/src/main.c b/samples/subsys/ipc/ipc_service/icmsg/src/main.c index 86469cac64b02..afb5016dbeb36 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/src/main.c +++ b/samples/subsys/ipc/ipc_service/icmsg/src/main.c @@ -40,6 +40,11 @@ static void ep_bound(void *priv) LOG_INF("Ep bounded"); } +static void ep_unbound(void *priv) +{ + LOG_INF("Ep unbounded"); +} + static void ep_recv(const void *data, size_t len, void *priv) { #if defined(CONFIG_ASSERT) @@ -68,6 +73,11 @@ static void ep_recv(const void *data, size_t len, void *priv) } } +static void ep_error(const char *message, void *priv) +{ + LOG_ERR("ICMsg error: %s", message); +} + static int send_for_time(struct ipc_ept *ep, const int64_t sending_time_ms) { struct data_packet msg = {.data[0] = 'a'}; @@ -123,7 +133,9 @@ static int send_for_time(struct ipc_ept *ep, const int64_t sending_time_ms) static struct ipc_ept_cfg ep_cfg = { .cb = { .bound = ep_bound, + .unbound = ep_unbound, .received = ep_recv, + .error = ep_error, }, }; diff --git a/samples/subsys/ipc/ipc_service/static_vrings/CMakeLists.txt b/samples/subsys/ipc/ipc_service/static_vrings/CMakeLists.txt index 588bfe71dd0c4..49384bac63057 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/CMakeLists.txt +++ b/samples/subsys/ipc/ipc_service/static_vrings/CMakeLists.txt @@ -1,6 +1,6 @@ # # Copyright (c) 2021 Carlo Caione -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -15,7 +15,9 @@ if(NOT (CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUAPP OR CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU0 OR CONFIG_BOARD_MIMXRT1160_EVK_MIMXRT1166_CM7 OR - CONFIG_BOARD_MIMXRT1170_EVK_MIMXRT1176_CM7 + CONFIG_BOARD_MIMXRT1170_EVK_MIMXRT1176_CM7 OR + CONFIG_BOARD_FRDM_MCXN947_MCXN947_CPU0 OR + CONFIG_BOARD_MIMXRT1180_EVK_MIMXRT1189_CM33 ) ) message(FATAL_ERROR "${BOARD} is not supported for this sample") diff --git a/samples/subsys/ipc/ipc_service/static_vrings/Kconfig.sysbuild b/samples/subsys/ipc/ipc_service/static_vrings/Kconfig.sysbuild index 4f9caa8250168..a0a4146d396ee 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/Kconfig.sysbuild +++ b/samples/subsys/ipc/ipc_service/static_vrings/Kconfig.sysbuild @@ -1,5 +1,5 @@ # Copyright 2023 Nordic Semiconductor ASA -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 @@ -13,3 +13,5 @@ string default "mimxrt1160_evk/mimxrt1166/cm4" if $(BOARD) = "mimxrt1160_evk" default "mimxrt1170_evk/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evk" default "mimxrt1170_evkb/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evkb" + default "frdm_mcxn947/mcxn947/cpu1" if $(BOARD) = "frdm_mcxn947" + default "mimxrt1180_evk/mimxrt1189/cm7" if $(BOARD) = "mimxrt1180_evk" diff --git a/samples/subsys/ipc/ipc_service/static_vrings/README.rst b/samples/subsys/ipc/ipc_service/static_vrings/README.rst index 8fe0591b786cc..086c16ccb1f1c 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/README.rst +++ b/samples/subsys/ipc/ipc_service/static_vrings/README.rst @@ -56,6 +56,15 @@ Building the application for mimxrt1170_evk@B/mimxrt1176/cm7 :goals: debug :west-args: --sysbuild +Building the application for frdm_mcxn947/mcxn947/cpu0 +************************************************************ + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/ipc/ipc_service/static_vrings + :board: frdm_mcxn947/mcxn947/cpu0 + :goals: debug + :west-args: --sysbuild + Open a serial terminal (minicom, putty, etc.) and connect the board with the following settings: diff --git a/samples/subsys/ipc/ipc_service/static_vrings/boards/frdm_mcxn947_mcxn947_cpu0.conf b/samples/subsys/ipc/ipc_service/static_vrings/boards/frdm_mcxn947_mcxn947_cpu0.conf new file mode 100644 index 0000000000000..7e6904d56d59d --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/boards/frdm_mcxn947_mcxn947_cpu0.conf @@ -0,0 +1 @@ +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/ipc_service/static_vrings/boards/frdm_mcxn947_mcxn947_cpu0.overlay b/samples/subsys/ipc/ipc_service/static_vrings/boards/frdm_mcxn947_mcxn947_cpu0.overlay new file mode 100644 index 0000000000000..19bbe1e16d79a --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/boards/frdm_mcxn947_mcxn947_cpu0.overlay @@ -0,0 +1,51 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + /* Define memory regions for IPC + * Note that shared memory must have specific MPU attributes set. + */ + sram1_ipc0: memory@20060000{ + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20060000 DT_SIZE_K(16)>; + zephyr,memory-region="SRAM1_IPC0"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + sram1_ipc1: memory@20064000{ + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20064000 DT_SIZE_K(16)>; + zephyr,memory-region="SRAM1_IPC1"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + ipc { + /delete-node/ ipc0; + + ipc0: ipc0 { + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&sram1_ipc0>; + mboxes = <&mbox 0>, <&mbox 1>; + mbox-names = "tx", "rx"; + role = "host"; + status = "okay"; + }; + + ipc1: ipc1 { + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&sram1_ipc1>; + mboxes = <&mbox 2>, <&mbox 3>; + mbox-names = "tx", "rx"; + role = "host"; + zephyr,priority = <1 PRIO_COOP>; + zephyr,buffer-size = <128>; + status = "okay"; + }; + }; +}; diff --git a/samples/subsys/ipc/ipc_service/static_vrings/boards/mimxrt1180_evk_mimxrt1189_cm33.conf b/samples/subsys/ipc/ipc_service/static_vrings/boards/mimxrt1180_evk_mimxrt1189_cm33.conf new file mode 100644 index 0000000000000..60eead5a076e4 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/boards/mimxrt1180_evk_mimxrt1189_cm33.conf @@ -0,0 +1,2 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_INCLUDE_REMOTE_DIR=y diff --git a/samples/subsys/ipc/ipc_service/static_vrings/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/samples/subsys/ipc/ipc_service/static_vrings/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..2bcb576660516 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,49 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + /* Define memory regions for IPC */ + ocram2_ipc0: memory@20500000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20500000 DT_SIZE_K(16)>; + zephyr,memory-region="OCRAM2_IPC0"; + zephyr,memory-attr = <(DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + ocram2_ipc1: memory@20504000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20504000 DT_SIZE_K(16)>; + zephyr,memory-region="OCRAM2_IPC1"; + zephyr,memory-attr = <(DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + ipc { + /delete-node/ ipc0; + + ipc0: ipc0 { + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&ocram2_ipc0>; + mboxes = <&mbox1_a 0>, <&mbox1_a 1>; + mbox-names = "tx", "rx"; + role = "host"; + status = "okay"; + }; + + ipc1: ipc1 { + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&ocram2_ipc1>; + mboxes = <&mbox1_a 2>, <&mbox1_a 3>; + mbox-names = "tx", "rx"; + role = "host"; + zephyr,priority = <1 PRIO_COOP>; + zephyr,buffer-size = <128>; + status = "okay"; + }; + }; +}; diff --git a/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf new file mode 100644 index 0000000000000..7e6904d56d59d --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf @@ -0,0 +1 @@ +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay new file mode 100644 index 0000000000000..4960c98561609 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay @@ -0,0 +1,51 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + /* Define memory regions for IPC + * Note that shared memory must have specific MPU attributes set. + */ + sram1_ipc0: memory@20060000{ + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20060000 DT_SIZE_K(16)>; + zephyr,memory-region="SRAM1_IPC0"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + sram1_ipc1: memory@20064000{ + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20064000 DT_SIZE_K(16)>; + zephyr,memory-region="SRAM1_IPC1"; + zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + ipc { + /delete-node/ ipc0; + + ipc0: ipc0 { + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&sram1_ipc0>; + mboxes = <&mbox 0>, <&mbox 1>; + mbox-names = "rx", "tx"; + role = "remote"; + status = "okay"; + }; + + ipc1: ipc1 { + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&sram1_ipc1>; + mboxes = <&mbox 2>, <&mbox 3>; + mbox-names = "rx", "tx"; + role = "remote"; + zephyr,priority = <1 PRIO_COOP>; + zephyr,buffer-size = <128>; + status = "okay"; + }; + }; +}; diff --git a/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf new file mode 100644 index 0000000000000..77adcfa24f4e2 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf @@ -0,0 +1,2 @@ +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay new file mode 100644 index 0000000000000..d6958308790ea --- /dev/null +++ b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -0,0 +1,49 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + /* Define memory regions for IPC */ + ocram2_ipc0: memory@20500000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20500000 DT_SIZE_K(16)>; + zephyr,memory-region="OCRAM2_IPC0"; + zephyr,memory-attr = <(DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + ocram2_ipc1: memory@20504000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20504000 DT_SIZE_K(16)>; + zephyr,memory-region="OCRAM2_IPC1"; + zephyr,memory-attr = <(DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + ipc { + /delete-node/ ipc0; + + ipc0: ipc0 { + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&ocram2_ipc0>; + mboxes = <&mbox1_b 0>, <&mbox1_b 1>; + mbox-names = "rx", "tx"; + role = "remote"; + status = "okay"; + }; + + ipc1: ipc1 { + compatible = "zephyr,ipc-openamp-static-vrings"; + memory-region = <&ocram2_ipc1>; + mboxes = <&mbox1_b 2>, <&mbox1_b 3>; + mbox-names = "rx", "tx"; + role = "remote"; + zephyr,priority = <1 PRIO_COOP>; + zephyr,buffer-size = <128>; + status = "okay"; + }; + }; +}; diff --git a/samples/subsys/ipc/ipc_service/static_vrings/sample.yaml b/samples/subsys/ipc/ipc_service/static_vrings/sample.yaml index d15df7b803e45..d73c17429d75f 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/sample.yaml +++ b/samples/subsys/ipc/ipc_service/static_vrings/sample.yaml @@ -9,6 +9,7 @@ tests: - mimxrt1160_evk/mimxrt1166/cm7 - mimxrt1170_evk/mimxrt1176/cm7 - mimxrt1170_evk@B/mimxrt1176/cm7 + - frdm_mcxn947/mcxn947/cpu0 integration_platforms: - nrf5340dk/nrf5340/cpuapp - nrf5340bsim/nrf5340/cpuapp diff --git a/samples/subsys/ipc/openamp/Kconfig.sysbuild b/samples/subsys/ipc/openamp/Kconfig.sysbuild index 9063dacafa1d7..61dc0f4b8bf75 100644 --- a/samples/subsys/ipc/openamp/Kconfig.sysbuild +++ b/samples/subsys/ipc/openamp/Kconfig.sysbuild @@ -1,4 +1,4 @@ -# Copyright 2022-2023 NXP +# Copyright 2022-2025 NXP # # SPDX-License-Identifier: Apache-2.0 @@ -13,3 +13,5 @@ string default "mimxrt1170_evk/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evk" default "mimxrt1160_evk/mimxrt1166/cm4" if $(BOARD) = "mimxrt1160_evk" default "mimxrt1170_evkb/mimxrt1176/cm4" if $(BOARD) = "mimxrt1170_evkb" + default "frdm_mcxn947/mcxn947/cpu1" if $(BOARD) = "frdm_mcxn947" + default "mimxrt1180_evk/mimxrt1189/cm7" if $(BOARD) = "mimxrt1180_evk" diff --git a/samples/subsys/ipc/openamp/README.rst b/samples/subsys/ipc/openamp/README.rst index a75ef69017d5b..9f3416ade7f84 100644 --- a/samples/subsys/ipc/openamp/README.rst +++ b/samples/subsys/ipc/openamp/README.rst @@ -57,6 +57,15 @@ Building the application for mimxrt1170_evk_cm7 :goals: debug :west-args: --sysbuild +Building the application for frdm_mcxn947/mcxn947/cpu0 +****************************************************** + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/ipc/openamp + :board: frdm_mcxn947/mcxn947/cpu0 + :goals: debug + :west-args: --sysbuild + Open a serial terminal (minicom, putty, etc.) and connect the board with the following settings: diff --git a/samples/subsys/ipc/openamp/boards/frdm_mcxn947_mcxn947_cpu0.conf b/samples/subsys/ipc/openamp/boards/frdm_mcxn947_mcxn947_cpu0.conf new file mode 100644 index 0000000000000..7e6904d56d59d --- /dev/null +++ b/samples/subsys/ipc/openamp/boards/frdm_mcxn947_mcxn947_cpu0.conf @@ -0,0 +1 @@ +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/openamp/boards/frdm_mcxn947_mcxn947_cpu0.overlay b/samples/subsys/ipc/openamp/boards/frdm_mcxn947_mcxn947_cpu0.overlay new file mode 100644 index 0000000000000..f2436532b8c15 --- /dev/null +++ b/samples/subsys/ipc/openamp/boards/frdm_mcxn947_mcxn947_cpu0.overlay @@ -0,0 +1,28 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* + * shared memory reserved for the inter-processor communication + */ + + zephyr,ipc_shm = &sramh; + zephyr,ipc = &mailbox0; + }; + + /* Delete MBOX Driver node */ + /delete-node/ mbox@b2000; + soc { + mailbox0:mailbox@400b2000 { + compatible = "nxp,lpc-mailbox"; + reg = <0x400b2000 0xEC>; + interrupts = <54 0>; + resets = <&reset NXP_SYSCON_RESET(0, 26)>; + status = "okay"; + }; + }; +}; diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1180_evk_mimxrt1189_cm33.conf b/samples/subsys/ipc/openamp/boards/mimxrt1180_evk_mimxrt1189_cm33.conf new file mode 100644 index 0000000000000..b57d6b0281ac6 --- /dev/null +++ b/samples/subsys/ipc/openamp/boards/mimxrt1180_evk_mimxrt1189_cm33.conf @@ -0,0 +1,5 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_INCLUDE_REMOTE_DIR=y +CONFIG_IPM=y +CONFIG_IPM_MBOX=y +CONFIG_MBOX=y diff --git a/samples/subsys/ipc/openamp/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/samples/subsys/ipc/openamp/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..582c4271c5d67 --- /dev/null +++ b/samples/subsys/ipc/openamp/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,33 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + chosen { + /* + * shared memory reserved for the inter-processor communication + */ + + zephyr,ipc_shm = &ocram2_sh_mem; + zephyr,ipc = &mailbox_a; + }; + + /* Define memory regions for IPC */ + ocram2_sh_mem: memory@20500000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20500000 DT_SIZE_K(32)>; + zephyr,memory-region="OCRAM2_SH_MEM"; + zephyr,memory-attr = <(DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + mailbox_a: ipm-mbox { + compatible = "zephyr,mbox-ipm"; + mboxes = <&mbox1_a 1>, <&mbox1_a 0>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/subsys/ipc/openamp/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf b/samples/subsys/ipc/openamp/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf new file mode 100644 index 0000000000000..7e6904d56d59d --- /dev/null +++ b/samples/subsys/ipc/openamp/remote/boards/frdm_mcxn947_mcxn947_cpu1.conf @@ -0,0 +1 @@ +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/subsys/ipc/openamp/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay b/samples/subsys/ipc/openamp/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay new file mode 100644 index 0000000000000..f2436532b8c15 --- /dev/null +++ b/samples/subsys/ipc/openamp/remote/boards/frdm_mcxn947_mcxn947_cpu1.overlay @@ -0,0 +1,28 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* + * shared memory reserved for the inter-processor communication + */ + + zephyr,ipc_shm = &sramh; + zephyr,ipc = &mailbox0; + }; + + /* Delete MBOX Driver node */ + /delete-node/ mbox@b2000; + soc { + mailbox0:mailbox@400b2000 { + compatible = "nxp,lpc-mailbox"; + reg = <0x400b2000 0xEC>; + interrupts = <54 0>; + resets = <&reset NXP_SYSCON_RESET(0, 26)>; + status = "okay"; + }; + }; +}; diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf b/samples/subsys/ipc/openamp/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf new file mode 100644 index 0000000000000..b31b3845defda --- /dev/null +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.conf @@ -0,0 +1,5 @@ +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y +CONFIG_IPM=y +CONFIG_IPM_MBOX=y +CONFIG_MBOX=y diff --git a/samples/subsys/ipc/openamp/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/samples/subsys/ipc/openamp/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay new file mode 100644 index 0000000000000..80831a425fc9e --- /dev/null +++ b/samples/subsys/ipc/openamp/remote/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -0,0 +1,33 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + chosen { + /* + * shared memory reserved for the inter-processor communication + */ + + zephyr,ipc_shm = &ocram2_sh_mem; + zephyr,ipc = &mailbox_b; + }; + + /* Define memory regions for IPC */ + ocram2_sh_mem: memory@20500000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20500000 DT_SIZE_K(32)>; + zephyr,memory-region="OCRAM2_SH_MEM"; + zephyr,memory-attr = <(DT_MEM_ARM(ATTR_MPU_IO))>; + }; + + mailbox_b: ipm-mbox { + compatible = "zephyr,mbox-ipm"; + mboxes = <&mbox1_b 0>, <&mbox1_b 1>; + mbox-names = "tx", "rx"; + }; +}; diff --git a/samples/subsys/ipc/openamp/sample.yaml b/samples/subsys/ipc/openamp/sample.yaml index 1679d6a469738..70668a77425e5 100644 --- a/samples/subsys/ipc/openamp/sample.yaml +++ b/samples/subsys/ipc/openamp/sample.yaml @@ -6,6 +6,7 @@ tests: platform_allow: - lpcxpresso54114/lpc54114/m4 - lpcxpresso55s69/lpc55s69/cpu0 + - frdm_mcxn947/mcxn947/cpu0 - mps2/an521/cpu0 - v2m_musca_b1/musca_b1 integration_platforms: diff --git a/samples/subsys/llext/modules/CMakeLists.txt b/samples/subsys/llext/modules/CMakeLists.txt index 9e5f0e427a511..5c90a65568351 100644 --- a/samples/subsys/llext/modules/CMakeLists.txt +++ b/samples/subsys/llext/modules/CMakeLists.txt @@ -11,7 +11,7 @@ if(CONFIG_HELLO_WORLD_MODE STREQUAL "m") set(ext_name hello_world) set(ext_src src/${ext_name}_ext.c) - set(ext_bin ${ZEPHYR_BINARY_DIR}/${ext_name}.llext) + set(ext_bin ${PROJECT_BINARY_DIR}/llext/${ext_name}.llext) set(ext_inc ${ZEPHYR_BINARY_DIR}/include/generated/${ext_name}_ext.inc) add_llext_target(${ext_name}_ext OUTPUT ${ext_bin} diff --git a/samples/subsys/llext/shell_loader/CMakeLists.txt b/samples/subsys/llext/shell_loader/CMakeLists.txt index a9d5d832334ec..c6af8da1bff64 100644 --- a/samples/subsys/llext/shell_loader/CMakeLists.txt +++ b/samples/subsys/llext/shell_loader/CMakeLists.txt @@ -7,3 +7,11 @@ project(fs_shell) FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) + +# Add a target for building the extension code +set(ext_src ${PROJECT_SOURCE_DIR}/hello_world.c) +set(ext_bin ${PROJECT_BINARY_DIR}/hello_world.llext) +add_llext_target(hello_world_ext + OUTPUT ${ext_bin} + SOURCES ${ext_src} +) diff --git a/samples/subsys/llext/shell_loader/README.rst b/samples/subsys/llext/shell_loader/README.rst index 681a9487cedab..3d7e1840b28b2 100644 --- a/samples/subsys/llext/shell_loader/README.rst +++ b/samples/subsys/llext/shell_loader/README.rst @@ -13,55 +13,64 @@ ability to manage loadable code extensions in the shell. Requirements ************ -A board with a supported llext architecture and shell capable console. +A board with a supported LLEXT architecture and shell capable console. The +following example uses an ARMv7 CPU, but the same instructions can be adapted +to any LLEXT-supported target. Building ******** +The following command will build the main shell application: + .. zephyr-app-commands:: :zephyr-app: samples/subsys/llext/shell_loader :board: robokit1 :goals: build :compact: -.. note:: You may need to disable memory protection for the sample to work (e.g. CONFIG_ARM_MPU=n). +.. note:: -Running -******* + You may need to disable memory protection for the sample to work (e.g. + ``CONFIG_ARM_MPU=n``). See the full list of similar flags in + :zephyr_file:`tests/subsys/llext/no_mem_protection.conf`. -Once the board has booted, you will be presented with a shell prompt. -All the llext system related commands are available as sub-commands of llext -which can be seen with llext help +This sample also includes the source for a very basic extension, +:zephyr_file:`samples/subsys/llext/shell_loader/hello_world.c`, which can be +used to test the LLEXT features. + +It can be compiled to :file:`build/hello_world.llext` using the Zephyr build +system like this: .. code-block:: console - uart:~$ llext help - llext - Loadable extension commands - Subcommands: - list :List loaded extensions and their size in memory - load_hex :Load an elf file encoded in hex directly from the shell input. - Syntax: - - unload :Unload an extension by name. Syntax: - - list_symbols :List extension symbols. Syntax: - - call_fn :Call extension function with prototype void fn(void). Syntax: - + $ ninja -C build -vvv hello_world_ext + +On a host machine with the Zephyr SDK and the ``arm-zephyr-eabi`` toolchain in +``PATH``, you can also obtain the same result directly with ``gcc``: + +.. code-block:: console + + $ arm-zephyr-eabi-gcc -mlong-calls -mthumb -c -o build/hello_world.llext samples/subsys/llext/shell/hello_world.c + +.. note:: -A hello world C file can be found in tests/subsys/llext/hello_world/hello_world.c + LLEXT by default only imports symbols that have been explicitly exported by + the extension via the :c:macro:`EXPORT_SYMBOL` macro. Compiling with this + macro requires using the full Zephyr build system, or at least the + :ref:`LLEXT EDK `. -This can be built into a relocatable elf usable on arm v7 platforms. It can be -inspected with some binutils to see symbols, sections, and relocations. -Then using additional tools converted to a hex string usable by the llext -load_hex shell command. + To avoid this complexity, this sample configures Zephyr to use all global + symbols defined in the extension ELF file via the Kconfig option + :kconfig:option:`CONFIG_LLEXT_IMPORT_ALL_GLOBALS`. This is not recommended + for large extensions as the memory usage increases significantly. -On a host machine with the zephyr sdk setup and the arm toolchain in PATH +The compiled extension can be inspected with the usual binutils utilities to +see symbols, sections, and relocations. Then, using additional tools, converted +to a hex string usable by the ``llext load_hex`` shell command: .. code-block:: console - $ arm-zephyr-eabi-gcc -mlong-calls -mthumb -c -o hello_world.elf tests/subsys/llext/hello_world/hello_world.c - $ arm-zephyr-eabi-objdump -r -d -x hello_world.elf + $ arm-zephyr-eabi-objdump -r -d -x build/hello_world.llext hello_world.elf: file format elf32-littlearm hello_world.elf @@ -128,9 +137,40 @@ On a host machine with the zephyr sdk setup and the arm toolchain in PATH 34: 4718 bx r3 36: 46c0 nop ; (mov r8, r8) - $ xxd -p hello_world.elf | tr -d '\n' + $ xxd -p build/hello_world.llext | tr -d '\n' + 7f454c4601010100000000000000000001002800010000000000000000000000680200000000000534000000000028000b000a0080b500af084b1800084b00f013f82a22074b11001800054b00f00cf8c046bd4680bc01bc0047c0460400000000000000140000001847c0462a00000068656c6c6f20776f726c640a0000000041206e756d62657220697320256c750a00004743433a20285a65706879722053444b20302e31362e31292031322e322e30004129000000616561626900011f000000053454000602080109011204140115011703180119011a011e06000000000000000000000000000000000100000000000000000000000400f1ff000000000000000000000000030001000000000000000000000000000300030000000000000000000000000003000400000000000000000000000000030005000f00000000000000000000000000050012000000000000000400000001000500190000000000000000000000000001000f0000002800000000000000000001001900000034000000000000000000010000000000000000000000000003000600000000000000000000000000030007001c000000010000003400000012000100280000000000000000000000100000000068656c6c6f5f776f726c642e63002464006e756d6265720024740068656c6c6f5f776f726c64007072696e746b000028000000020500002c000000020e00003000000002050000002e73796d746162002e737472746162002e7368737472746162002e72656c2e74657874002e64617461002e627373002e726f64617461002e636f6d6d656e74002e41524d2e6174747269627574657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0000000100000006000000000000003400000038000000000000000000000004000000000000001b000000090000004000000000000000fc0100001800000008000000010000000400000008000000250000000100000003000000000000006c00000000000000000000000000000001000000000000002b0000000800000003000000000000006c0000000000000000000000000000000100000000000000300000000100000002000000000000006c00000025000000000000000000000004000000000000003800000001000000300000000000000091000000210000000000000000000000010000000100000041000000030000700000000000000000b20000002a0000000000000000000000010000000000000001000000020000000000000000000000dc000000f0000000090000000d000000040000001000000009000000030000000000000000000000cc0100002f0000000000000000000000010000000000000011000000030000000000000000000000140200005100000000000000000000000100000000000000 -The resulting hex string can be used to load the extension. +In this sample there are 3 absolute (``R_ARM_ABS32``) relocations, 2 of which +are meant to hold addresses into the ``.rodata`` sections where the strings are +located. A third is an address of where the ``printk`` function (symbol) can be +found. At load time LLEXT replaces the values in the ``.text`` section with +real memory addresses so that ``printk`` works as expected with the strings +included in the hello world sample. + +Running +******* + +Once the board has booted, you will be presented with a shell prompt. +All the LLEXT system related commands are available as sub-commands of +``llext``, and can be seen with ``llext help``: + +.. code-block:: console + + uart:~$ llext help + llext - Loadable extension commands + Subcommands: + list :List loaded extensions and their size in memory + load_hex :Load an elf file encoded in hex directly from the shell input. + Syntax: + + unload :Unload an extension by name. Syntax: + + list_symbols :List extension symbols. Syntax: + + call_fn :Call extension function with prototype void fn(void). Syntax: + + +The hex string generated above can be used to load the extension: .. code-block:: console @@ -144,6 +184,3 @@ run (``call_fn``). uart:~$ llext call_fn hello_world hello_world hello world - A number is 42 - -In this sample there are 3 absolute (R_ARM_ABS32) relocations, 2 of which are meant to hold addresses into the .rodata sections where the strings are located. A third is an address of where the printk function (symbol) can be found. At load time llext replaces the values in the .text section with real memory addresses so that printk works as expected with the strings included in the hello world sample. diff --git a/samples/subsys/llext/shell_loader/hello_world.c b/samples/subsys/llext/shell_loader/hello_world.c new file mode 100644 index 0000000000000..8469e9b2727d3 --- /dev/null +++ b/samples/subsys/llext/shell_loader/hello_world.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This very simple hello world C code can be used while learning about llext. + */ + +extern void printk(const char *fmt, ...); + +void hello_world(void) +{ + printk("hello world\n"); +} diff --git a/samples/subsys/llext/shell_loader/prj.conf b/samples/subsys/llext/shell_loader/prj.conf index 0e0d38fdcf45e..923560ce0f04b 100644 --- a/samples/subsys/llext/shell_loader/prj.conf +++ b/samples/subsys/llext/shell_loader/prj.conf @@ -8,5 +8,6 @@ CONFIG_SHELL_STACK_SIZE=4096 CONFIG_LLEXT=y CONFIG_LLEXT_LOG_LEVEL_DBG=y +CONFIG_LLEXT_IMPORT_ALL_GLOBALS=y CONFIG_LLEXT_HEAP_SIZE=8 CONFIG_LLEXT_SHELL=y diff --git a/samples/subsys/logging/ble_backend/README.rst b/samples/subsys/logging/ble_backend/README.rst index 7e229b6dea049..add2d90dd2233 100644 --- a/samples/subsys/logging/ble_backend/README.rst +++ b/samples/subsys/logging/ble_backend/README.rst @@ -1,24 +1,24 @@ .. zephyr:code-sample:: logging-ble-backend - :name: BLE logging backend + :name: Bluetooth logging backend :relevant-api: log_api log_backend bt_gatt - Send log messages over BLE using the BLE logging backend. + Send log messages over Bluetooth using the Bluetooth logging backend. Overview ******** -Sample that demonstrates how to setup and use the BLE Logging backend. The -BLE Logger uses the NRF Connect SDK NUS service as UUID to make it compatible -with already existing apps to debug BLE connections over UART. +Sample that demonstrates how to setup and use the Bluetooth Logging backend. The +Bluetooth Logger uses the NRF Connect SDK NUS service as UUID to make it compatible +with already existing apps to debug Bluetooth connections over UART. -The notification size of the ble backend buffer is dependent on the +The notification size of the Bluetooth backend buffer is dependent on the transmission size of the mtu set with :kconfig:option:`CONFIG_BT_L2CAP_TX_MTU`. Be sure -to change this configuration to increase the logger throughput over BLE. +to change this configuration to increase the logger throughput over Bluetooth. Requirements ************ -* A board with BLE support +* A board with Bluetooth LE support Building and Running ******************** @@ -26,5 +26,5 @@ Building and Running This sample can be found under :zephyr_file:`samples/subsys/logging/ble_backend` in the Zephyr tree. -The BLE logger can be tested with the NRF Toolbox app or any similar app that can connect over -BLE and detect the NRF NUS UUID service. +The Bluetooth logger can be tested with the NRF Toolbox app or any similar app that can connect over +Bluetooth and detect the NRF NUS UUID service. diff --git a/samples/subsys/logging/ble_backend/sample.yaml b/samples/subsys/logging/ble_backend/sample.yaml index 5a025aa80f27d..6c3ec10a6b5a2 100644 --- a/samples/subsys/logging/ble_backend/sample.yaml +++ b/samples/subsys/logging/ble_backend/sample.yaml @@ -1,6 +1,6 @@ sample: - description: A simple application that demonstrates the use of the logging ble backend. - name: logger backend ble + description: A simple application that demonstrates the use of the logging Bluetooth backend. + name: logger backend Bluetooth tests: sample.logging.ble_backend.nrf52833: harness: bluetooth diff --git a/samples/subsys/logging/ble_backend/src/main.c b/samples/subsys/logging/ble_backend/src/main.c index 249e582a0e833..87a5fd5698779 100644 --- a/samples/subsys/logging/ble_backend/src/main.c +++ b/samples/subsys/logging/ble_backend/src/main.c @@ -73,9 +73,9 @@ void backend_ble_hook(bool status, void *ctx) ARG_UNUSED(ctx); if (status) { - LOG_INF("BLE Logger Backend enabled."); + LOG_INF("Bluetooth Logger Backend enabled."); } else { - LOG_INF("BLE Logger Backend disabled."); + LOG_INF("Bluetooth Logger Backend disabled."); } } @@ -84,7 +84,7 @@ int main(void) { int err; - LOG_INF("BLE LOG Demo"); + LOG_INF("Bluetooth LOG Demo"); logger_backend_ble_set_hook(backend_ble_hook, NULL); err = bt_enable(NULL); if (err) { diff --git a/samples/subsys/lorawan/class_a/README.rst b/samples/subsys/lorawan/class_a/README.rst index 22d9b8f3a4820..4d8c421209a5b 100644 --- a/samples/subsys/lorawan/class_a/README.rst +++ b/samples/subsys/lorawan/class_a/README.rst @@ -25,3 +25,16 @@ The following commands build and flash the sample. :board: nucleo_wl55jc :goals: build flash :compact: + +Important Notes for Multiple Runs +********************************* + +By default, this example will only succeed the first time it is run. On subsequent join attempts, the LoRaWAN network server may reject the join request due to a hardcoded ``dev_nonce`` value. According to the LoRaWAN specification, ``dev_nonce`` must increment for every new connection attempt. + +To run this sample multiple times, choose one of the following options: + +1. **Manually Increment ``dev_nonce``:** + Modify the sample code to increment ``join_cfg.otaa.dev_nonce`` before each connection attempt and ensure it is preserved across reboots. + +2. **Built-in Zephyr Settings Implementation:** + Enable :kconfig:option:`CONFIG_LORAWAN_NVM_SETTINGS` in the Kconfig. This allows proper storage and reuse of configuration settings, including the ``dev_nonce``, across multiple runs. diff --git a/samples/subsys/mgmt/hawkbit/README.rst b/samples/subsys/mgmt/hawkbit/README.rst index f4a206c32f987..7e5fa64239d97 100644 --- a/samples/subsys/mgmt/hawkbit/README.rst +++ b/samples/subsys/mgmt/hawkbit/README.rst @@ -29,7 +29,7 @@ Caveats :zephyr:board:`Freedom-K64F ` MCU by default. The application should build and run for other platforms with support internet connection. Some platforms need some modification. Overlay files would be needed to support - BLE 6lowpan, 802.15.4 or OpenThread configurations as well as the + Bluetooth LE, 6lowpan, 802.15.4 or OpenThread configurations as well as the understanding that most other connectivity options would require an edge gateway of some sort (Border Router, etc). diff --git a/samples/subsys/mgmt/hawkbit/prj.conf b/samples/subsys/mgmt/hawkbit/prj.conf index e25016994855e..4ff8a11bd9359 100644 --- a/samples/subsys/mgmt/hawkbit/prj.conf +++ b/samples/subsys/mgmt/hawkbit/prj.conf @@ -15,6 +15,9 @@ CONFIG_DNS_RESOLVER=y CONFIG_JSON_LIBRARY=y CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_SETTINGS=y +CONFIG_SMF=y +CONFIG_SMF_ANCESTOR_SUPPORT=y + CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=n CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE=y CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem" @@ -67,3 +70,6 @@ CONFIG_BUILD_OUTPUT_HEX=y #Use custom attributes for hawkBit CONFIG_HAWKBIT_CUSTOM_ATTRIBUTES=y + +# Use event callbacks for hawkBit +CONFIG_HAWKBIT_EVENT_CALLBACKS=y diff --git a/samples/subsys/mgmt/hawkbit/sample.yaml b/samples/subsys/mgmt/hawkbit/sample.yaml index 4a7bf0db6c753..6104df0035a06 100644 --- a/samples/subsys/mgmt/hawkbit/sample.yaml +++ b/samples/subsys/mgmt/hawkbit/sample.yaml @@ -34,3 +34,7 @@ tests: sample.net.hawkbit.set_settings_runtime: extra_configs: - CONFIG_HAWKBIT_SET_SETTINGS_RUNTIME=y + sample.net.hawkbit.save_progress: + extra_configs: + - CONFIG_HAWKBIT_SAVE_PROGRESS=y + - CONFIG_STREAM_FLASH_PROGRESS=y diff --git a/samples/subsys/mgmt/hawkbit/src/main.c b/samples/subsys/mgmt/hawkbit/src/main.c index ab07501f7a6f2..1fb1eb3d8d28a 100644 --- a/samples/subsys/mgmt/hawkbit/src/main.c +++ b/samples/subsys/mgmt/hawkbit/src/main.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,29 @@ int hawkbit_new_config_data_cb(const char *device_id, uint8_t *buffer, const siz } #endif /* CONFIG_HAWKBIT_CUSTOM_ATTRIBUTES */ +#ifdef CONFIG_HAWKBIT_EVENT_CALLBACKS +void hawkbit_event_cb(struct hawkbit_event_callback *cb, enum hawkbit_event_type event) +{ + LOG_INF("hawkBit event: %d", event); + + switch (event) { + case HAWKBIT_EVENT_START_RUN: + LOG_INF("Run of hawkBit started"); + break; + + case HAWKBIT_EVENT_END_RUN: + LOG_INF("Run of hawkBit ended"); + break; + + default: + break; + } +} + +static HAWKBIT_EVENT_CREATE_CALLBACK(hb_event_cb_start, hawkbit_event_cb, HAWKBIT_EVENT_START_RUN); +static HAWKBIT_EVENT_CREATE_CALLBACK(hb_event_cb_end, hawkbit_event_cb, HAWKBIT_EVENT_END_RUN); +#endif /* CONFIG_HAWKBIT_EVENT_CALLBACKS */ + int main(void) { int ret = -1; @@ -73,6 +97,11 @@ int main(void) } #endif /* CONFIG_HAWKBIT_CUSTOM_ATTRIBUTES */ +#ifdef CONFIG_HAWKBIT_EVENT_CALLBACKS + hawkbit_event_add_callback(&hb_event_cb_start); + hawkbit_event_add_callback(&hb_event_cb_end); +#endif /* CONFIG_HAWKBIT_EVENT_CALLBACKS */ + ret = hawkbit_init(); if (ret < 0) { LOG_ERR("Failed to init hawkBit"); @@ -105,14 +134,6 @@ int main(void) LOG_INF("No update found"); break; - case HAWKBIT_CANCEL_UPDATE: - LOG_INF("hawkBit update cancelled from server"); - break; - - case HAWKBIT_OK: - LOG_INF("Image is already updated"); - break; - case HAWKBIT_UPDATE_INSTALLED: LOG_INF("Update installed"); break; diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml index b1312de4029ad..3d9cb6489cfb2 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml @@ -74,8 +74,8 @@ tests: - mimxrt1020_evk - mimxrt1024_evk - mimxrt1040_evk - - mimxrt1050_evk - - mimxrt1060_evk + - mimxrt1050_evk/mimxrt1052/hyperflash + - mimxrt1060_evk/mimxrt1062/qspi - mimxrt1062_fmurt6 - mimxrt1064_evk - mimxrt1160_evk/mimxrt1166/cm7 @@ -132,8 +132,8 @@ tests: - mimxrt1020_evk - mimxrt1024_evk - mimxrt1040_evk - - mimxrt1050_evk - - mimxrt1060_evk + - mimxrt1050_evk/mimxrt1052/hyperflash + - mimxrt1060_evk/mimxrt1062/qspi - mimxrt1062_fmurt6 - mimxrt1064_evk - mimxrt1160_evk/mimxrt1166/cm7 @@ -147,7 +147,7 @@ tests: - mg100 integration_platforms: - nrf52840dk/nrf52840 - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi - mimxrt1064_evk sample.mcumgr.smp_svr.shell_mgmt: extra_args: EXTRA_CONF_FILE="overlay-shell-mgmt.conf" diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c b/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c index 7c5723bf999f2..477494b9c24dd 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c +++ b/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c @@ -43,11 +43,10 @@ static void connected(struct bt_conn *conn, uint8_t err) { if (err) { LOG_ERR("Connection failed, err 0x%02x %s", err, bt_hci_err_to_str(err)); + k_work_submit(&advertise_work); } else { LOG_INF("Connected"); } - - k_work_submit(&advertise_work); } static void disconnected(struct bt_conn *conn, uint8_t reason) diff --git a/samples/subsys/modbus/rtu_client/src/main.c b/samples/subsys/modbus/rtu_client/src/main.c index fd3466475f349..668bb57e5c1eb 100644 --- a/samples/subsys/modbus/rtu_client/src/main.c +++ b/samples/subsys/modbus/rtu_client/src/main.c @@ -6,7 +6,6 @@ #include #include -#include #include #include diff --git a/samples/subsys/nvs/socs/esp32c3_usb.conf b/samples/subsys/nvs/socs/esp32c3_usb.conf new file mode 100644 index 0000000000000..26d52701286e5 --- /dev/null +++ b/samples/subsys/nvs/socs/esp32c3_usb.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=256 diff --git a/samples/subsys/rtio/rtio.rst b/samples/subsys/rtio/rtio.rst new file mode 100644 index 0000000000000..7a186aa02c079 --- /dev/null +++ b/samples/subsys/rtio/rtio.rst @@ -0,0 +1,5 @@ +.. zephyr:code-sample-category:: rtio + :name: Real Time I/O (RTIO) + :show-listing: + + Samples that demonstrate the :ref:`rtio` subsystem. diff --git a/samples/subsys/rtio/sensor_batch_processing/README.rst b/samples/subsys/rtio/sensor_batch_processing/README.rst new file mode 100644 index 0000000000000..23f744bd784cc --- /dev/null +++ b/samples/subsys/rtio/sensor_batch_processing/README.rst @@ -0,0 +1,75 @@ +.. zephyr:code-sample:: sensor_batch_processing + :name: Sensor batch processing + :relevant-api: rtio + + Implement a sensor device using RTIO for asynchronous data processing. + +Overview +******** + +This sample application demonstrates the use of the :ref:`rtio` framework for +doing asynchronous operation chains. +Application uses :ref:`rtio` with mempool API to fetch data from virtual sensor +and displays it on the console. + +Requirements +************ + +* A board with flash support or native_sim target + +Building and Running +******************** + +This sample can be found under :zephyr_file:`samples/subsys/rtio` in the Zephyr tree. + +The sample can be built for most platforms, the following commands build the +application for the native_sim target. + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/rtio + :board: native_sim + :goals: build run + :compact: + +When running, the output on the console shows the operations of +submitting for, consuming, and processing the sensor data. + +Sample Output +============= + +.. code-block:: console + + *** Booting Zephyr OS build v4.0.0-1260-gbaa49f6f32d5 *** + I: Submitting 4 read requests + D: sensor@0: buf_len = 16, buf = 0x8056430 + D: sensor@0: buf_len = 16, buf = 0x8056440 + D: sensor@0: buf_len = 16, buf = 0x8056450 + D: sensor@0: buf_len = 16, buf = 0x8056460 + D: Consumed completion event 0 + D: Consumed completion event 1 + D: Consumed completion event 2 + D: Consumed completion event 3 + I: Start processing 4 samples + D: Sample data: + D: 00 01 02 03 04 05 06 07 |........ + D: 08 09 0a 0b 0c 0d 0e 0f |........ + D: Sample data: + D: 10 11 12 13 14 15 16 17 |........ + D: 18 19 1a 1b 1c 1d 1e 1f |........ + D: Sample data: + D: 20 21 22 23 24 25 26 27 | !"#$%&' + D: 28 29 2a 2b 2c 2d 2e 2f |()*+,-./ + D: Sample data: + D: 30 31 32 33 34 35 36 37 |01234567 + D: 38 39 3a 3b 3c 3d 3e 3f |89:;<=>? + D: sensor@0: buf_len = 16, buf = 0x8056470 + D: sensor@0: buf_len = 16, buf = 0x8056480 + D: sensor@0: buf_len = 16, buf = 0x8056490 + I: Finished processing 4 samples + I: Submitting 4 read requests + D: sensor@0: buf_len = 16, buf = 0x8056430 + D: sensor@0: buf_len = 16, buf = 0x8056440 + D: sensor@0: buf_len = 16, buf = 0x8056450 + D: sensor@0: buf_len = 16, buf = 0x8056460 + D: Consumed completion event 0 + ... diff --git a/samples/subsys/settings/boards/mimxrt1020_evk.conf b/samples/subsys/settings/boards/mimxrt1020_evk.conf new file mode 100644 index 0000000000000..3746c13c741b0 --- /dev/null +++ b/samples/subsys/settings/boards/mimxrt1020_evk.conf @@ -0,0 +1,2 @@ +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y diff --git a/samples/subsys/settings/boards/s32z2xxdc2_s32z270_rtu0.conf b/samples/subsys/settings/boards/s32z2xxdc2_s32z270_rtu0.conf new file mode 100644 index 0000000000000..1535e4d46cd99 --- /dev/null +++ b/samples/subsys/settings/boards/s32z2xxdc2_s32z270_rtu0.conf @@ -0,0 +1,5 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y diff --git a/samples/subsys/settings/boards/s32z2xxdc2_s32z270_rtu1.conf b/samples/subsys/settings/boards/s32z2xxdc2_s32z270_rtu1.conf new file mode 100644 index 0000000000000..1535e4d46cd99 --- /dev/null +++ b/samples/subsys/settings/boards/s32z2xxdc2_s32z270_rtu1.conf @@ -0,0 +1,5 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y diff --git a/samples/subsys/settings/sample.yaml b/samples/subsys/settings/sample.yaml index 5836746516661..aafc61e555ecd 100644 --- a/samples/subsys/settings/sample.yaml +++ b/samples/subsys/settings/sample.yaml @@ -14,6 +14,10 @@ tests: - nrf54l15dk/nrf54l10/cpuapp - nrf54l15dk/nrf54l15/cpuapp - nrf54h20dk/nrf54h20/cpuapp + - s32z2xxdc2/s32z270/rtu0 + - s32z2xxdc2/s32z270/rtu1 + - s32z2xxdc2@D/s32z270/rtu0 + - s32z2xxdc2@D/s32z270/rtu1 integration_platforms: - native_sim harness: console diff --git a/samples/subsys/settings/boards/esp32_devkitc_wroom_procpu.conf b/samples/subsys/settings/socs/esp32_procpu.conf similarity index 100% rename from samples/subsys/settings/boards/esp32_devkitc_wroom_procpu.conf rename to samples/subsys/settings/socs/esp32_procpu.conf diff --git a/samples/subsys/settings/boards/esp32s2_saola.conf b/samples/subsys/settings/socs/esp32c3_usb.conf similarity index 100% rename from samples/subsys/settings/boards/esp32s2_saola.conf rename to samples/subsys/settings/socs/esp32c3_usb.conf diff --git a/samples/subsys/settings/boards/esp32s3_devkitm_procpu.conf b/samples/subsys/settings/socs/esp32c6.conf similarity index 100% rename from samples/subsys/settings/boards/esp32s3_devkitm_procpu.conf rename to samples/subsys/settings/socs/esp32c6.conf diff --git a/samples/subsys/settings/boards/esp32s3_luatos_core_procpu.conf b/samples/subsys/settings/socs/esp32s2.conf similarity index 100% rename from samples/subsys/settings/boards/esp32s3_luatos_core_procpu.conf rename to samples/subsys/settings/socs/esp32s2.conf diff --git a/samples/subsys/settings/boards/esp32s3_luatos_core_procpu_usb.conf b/samples/subsys/settings/socs/esp32s3_procpu.conf similarity index 100% rename from samples/subsys/settings/boards/esp32s3_luatos_core_procpu_usb.conf rename to samples/subsys/settings/socs/esp32s3_procpu.conf diff --git a/samples/subsys/shell/fs/sample.yaml b/samples/subsys/shell/fs/sample.yaml index e065b4e27eba8..afba7ddf0e29e 100644 --- a/samples/subsys/shell/fs/sample.yaml +++ b/samples/subsys/shell/fs/sample.yaml @@ -10,9 +10,13 @@ tests: sample.filesystem.shell: platform_allow: - reel_board - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi - mr_canhubk3 - native_sim + - s32z2xxdc2/s32z270/rtu0 + - s32z2xxdc2/s32z270/rtu1 + - s32z2xxdc2@D/s32z270/rtu0 + - s32z2xxdc2@D/s32z270/rtu1 integration_platforms: - reel_board sample.filesystem.shell.fuse: diff --git a/samples/subsys/shell/shell_module/sample.yaml b/samples/subsys/shell/shell_module/sample.yaml index 46c7fbb127f6a..70ea442d93b34 100644 --- a/samples/subsys/shell/shell_module/sample.yaml +++ b/samples/subsys/shell/shell_module/sample.yaml @@ -1,7 +1,7 @@ sample: name: Shell Sample common: - filter: not CONFIG_NATIVE_LIBC + filter: not CONFIG_NATIVE_LIBC and not CONFIG_SOC_SERIES_BSIM_NRFXX platform_exclude: - native_posix - native_posix/native/64 @@ -9,11 +9,12 @@ tests: sample.shell.shell_module: filter: CONFIG_SERIAL and dt_chosen_enabled("zephyr,shell-uart") tags: shell - harness: keyboard + harness: shell min_ram: 40 integration_platforms: - native_sim - - intel_socfpga_agilex5_socdk + extra_configs: + - arch:posix:CONFIG_NATIVE_UART_0_ON_STDINOUT=y sample.shell.shell_module.usb: depends_on: usb_device tags: diff --git a/samples/subsys/shell/shell_module/src/test_module.c b/samples/subsys/shell/shell_module/src/test_module.c index 3d9b197518817..6723629d93009 100644 --- a/samples/subsys/shell/shell_module/src/test_module.c +++ b/samples/subsys/shell/shell_module/src/test_module.c @@ -42,5 +42,5 @@ static int sub_cmd1_handler(const struct shell *sh, size_t argc, char **argv) return 0; } -SHELL_SUBCMD_COND_ADD(1, (section_cmd, cmd1), sub_cmd1, NULL, "help for cmd2", +SHELL_SUBCMD_COND_ADD(1, (section_cmd, cmd1), sub_cmd1, NULL, "help for sub_cmd1", sub_cmd1_handler, 1, 0); diff --git a/samples/subsys/shell/shell_module/test_shell.yml b/samples/subsys/shell/shell_module/test_shell.yml new file mode 100644 index 0000000000000..172651f7847b1 --- /dev/null +++ b/samples/subsys/shell/shell_module/test_shell.yml @@ -0,0 +1,4 @@ +- command: "kernel cycles" + expected: "cycles: .* hw cycles" +- command: "kernel version" + expected: "Zephyr version .*" diff --git a/samples/subsys/testsuite/pytest/shell/testcase.yaml b/samples/subsys/testsuite/pytest/shell/testcase.yaml index 86b9314f44441..adbbc85088b2e 100644 --- a/samples/subsys/testsuite/pytest/shell/testcase.yaml +++ b/samples/subsys/testsuite/pytest/shell/testcase.yaml @@ -1,14 +1,34 @@ +common: + tags: + - test_framework + - pytest + - shell + filter: CONFIG_SERIAL and not CONFIG_SMP and dt_chosen_enabled("zephyr,shell-uart") + extra_configs: + - arch:posix:CONFIG_NATIVE_UART_0_ON_STDINOUT=y + min_ram: 40 + integration_platforms: + - native_sim + - qemu_cortex_m3 tests: sample.pytest.shell: - filter: CONFIG_SERIAL and dt_chosen_enabled("zephyr,shell-uart") - min_ram: 40 harness: pytest + sample.pytest.shell.vt100_colors_off: + harness: pytest + extra_configs: + - CONFIG_SHELL_VT100_COLORS=n + sample.harness.shell: + harness: shell + harness_config: + shell_commands: &kernel_commands + - command: "kernel cycles" + expected: "cycles: .* hw cycles" + - command: "kernel version" + expected: "Zephyr version .*" + - command: "kernel sleep 100" + sample.harness.shell.vt100_colors_off: + harness: shell extra_configs: - - arch:posix:CONFIG_NATIVE_UART_0_ON_STDINOUT=y - integration_platforms: - - native_sim - - qemu_cortex_m3 - tags: - - test_framework - - pytest - - shell + - CONFIG_SHELL_VT100_COLORS=n + harness_config: + shell_commands: *kernel_commands diff --git a/samples/subsys/tracing/sample.yaml b/samples/subsys/tracing/sample.yaml index c6fb90b0160f5..7bd19aac5c107 100644 --- a/samples/subsys/tracing/sample.yaml +++ b/samples/subsys/tracing/sample.yaml @@ -24,7 +24,7 @@ tests: sample.tracing.format.sysview: platform_allow: - nrf52840dk/nrf52840 - - mimxrt1050_evk + - mimxrt1050_evk/mimxrt1052/hyperflash - mimxrt1064_evk integration_platforms: - nrf52840dk/nrf52840 @@ -78,9 +78,17 @@ tests: - percepio sample.tracing.gpio: depends_on: gpio - harness: ztest harness_config: - fixture: gpio_loopback + type: multi_line + regex: + - "port: gpio_emul, pin: [01] flags: (.*)" + - "port: gpio_emul, pin: [01] ret: 0" + - "port: gpio_emul, pins: [01]" + - "port: gpio_emul, ret: 0" + - "Interrupt detected!" + - "thread_a: Hello World from (.*)!" + - "thread_b: Hello World from (.*)!" + - "sys_trace_.*_user.*" extra_args: - CONF_FILE="prj_gpio.conf" - EXTRA_DTC_OVERLAY_FILE="gpio.overlay" diff --git a/samples/subsys/usb/cdc_acm/app.overlay b/samples/subsys/usb/cdc_acm/app.overlay index c50d0fd9d69e7..56ed8d4b43f06 100644 --- a/samples/subsys/usb/cdc_acm/app.overlay +++ b/samples/subsys/usb/cdc_acm/app.overlay @@ -7,5 +7,6 @@ &zephyr_udc0 { cdc_acm_uart0 { compatible = "zephyr,cdc-acm-uart"; + label = "Zephyr USB CDC-ACM"; }; }; diff --git a/samples/subsys/usb/cdc_acm/sample.yaml b/samples/subsys/usb/cdc_acm/sample.yaml index 4bd7ad1cd7951..d1906f58502c3 100644 --- a/samples/subsys/usb/cdc_acm/sample.yaml +++ b/samples/subsys/usb/cdc_acm/sample.yaml @@ -21,7 +21,7 @@ tests: - stm32f723e_disco - nucleo_f413zh - mimxrt685_evk/mimxrt685s/cm33 - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi harness: console harness_config: type: one_line diff --git a/samples/subsys/usb/common/sample_usbd_init.c b/samples/subsys/usb/common/sample_usbd_init.c index fb5b8e0dc3246..2d3266b4c7577 100644 --- a/samples/subsys/usb/common/sample_usbd_init.c +++ b/samples/subsys/usb/common/sample_usbd_init.c @@ -15,6 +15,12 @@ LOG_MODULE_REGISTER(usbd_sample_config); #define ZEPHYR_PROJECT_USB_VID 0x2fe3 +/* By default, do not register the USB DFU class DFU mode instance. */ +static const char *const blocklist[] = { + "dfu_dfu", + NULL, +}; + /* doc device instantiation start */ /* * Instantiate a context named sample_usbd using the default USB device @@ -73,6 +79,7 @@ static void sample_fix_code_triple(struct usbd_context *uds_ctx, if (IS_ENABLED(CONFIG_USBD_CDC_ACM_CLASS) || IS_ENABLED(CONFIG_USBD_CDC_ECM_CLASS) || IS_ENABLED(CONFIG_USBD_CDC_NCM_CLASS) || + IS_ENABLED(CONFIG_USBD_MIDI2_CLASS) || IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS)) { /* * Class with multiple interfaces have an Interface @@ -124,7 +131,8 @@ struct usbd_context *sample_usbd_setup_device(usbd_msg_cb_t msg_cb) return NULL; } - err = usbd_register_all_classes(&sample_usbd, USBD_SPEED_HS, 1); + err = usbd_register_all_classes(&sample_usbd, USBD_SPEED_HS, 1, + blocklist); if (err) { LOG_ERR("Failed to add register classes"); return NULL; @@ -143,7 +151,7 @@ struct usbd_context *sample_usbd_setup_device(usbd_msg_cb_t msg_cb) /* doc configuration register end */ /* doc functions register start */ - err = usbd_register_all_classes(&sample_usbd, USBD_SPEED_FS, 1); + err = usbd_register_all_classes(&sample_usbd, USBD_SPEED_FS, 1, blocklist); if (err) { LOG_ERR("Failed to add register classes"); return NULL; diff --git a/samples/subsys/usb/console-next/CMakeLists.txt b/samples/subsys/usb/console-next/CMakeLists.txt new file mode 100644 index 0000000000000..d8de1e746aff2 --- /dev/null +++ b/samples/subsys/usb/console-next/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(console-next) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/subsys/usb/console-next/README.rst b/samples/subsys/usb/console-next/README.rst new file mode 100644 index 0000000000000..1ca2063640b65 --- /dev/null +++ b/samples/subsys/usb/console-next/README.rst @@ -0,0 +1,39 @@ +.. zephyr:code-sample:: usbd-cdc-acm-console + :name: Console over USB CDC ACM + :relevant-api: usbd_api uart_interface + + Output "Hello World!" to the console over USB CDC ACM. + +Overview +******** + +This example application shows how to use the CDC ACM UART provided by the new +experimental USB device stack as a serial backend for the console. + +Requirements +************ + +This project requires an experimental USB device driver (UDC API). + +Building and Running +******************** + +This sample can be built for multiple boards, in this example we will build it +for the reel_board board: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/usb/console-next + :board: reel_board + :goals: flash + :compact: + +Plug the board into a host device, for sample, a PC running Linux OS. +The board will be detected as a CDC ACM serial device. To see the console output +from the sample, use a command similar to :command:`minicom -D /dev/ttyACM1`. + +.. code-block:: console + + Hello World! arm + Hello World! arm + Hello World! arm + Hello World! arm diff --git a/samples/subsys/usb/console-next/app.overlay b/samples/subsys/usb/console-next/app.overlay new file mode 100644 index 0000000000000..47b52ce7d6d0e --- /dev/null +++ b/samples/subsys/usb/console-next/app.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,console = &cdc_acm_uart0; + }; +}; + +&zephyr_udc0 { + cdc_acm_uart0: cdc_acm_uart0 { + compatible = "zephyr,cdc-acm-uart"; + }; +}; diff --git a/samples/subsys/usb/console-next/prj.conf b/samples/subsys/usb/console-next/prj.conf new file mode 100644 index 0000000000000..fe0b2be7270c5 --- /dev/null +++ b/samples/subsys/usb/console-next/prj.conf @@ -0,0 +1,10 @@ +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_STDOUT_CONSOLE=y +CONFIG_UART_LINE_CTRL=y + +CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=y +CONFIG_CDC_ACM_SERIAL_PID=0x0004 +CONFIG_CDC_ACM_SERIAL_PRODUCT_STRING="USBD console sample" diff --git a/samples/subsys/usb/console-next/sample.yaml b/samples/subsys/usb/console-next/sample.yaml new file mode 100644 index 0000000000000..f12969623c2b1 --- /dev/null +++ b/samples/subsys/usb/console-next/sample.yaml @@ -0,0 +1,10 @@ +sample: + name: Console over CDC ACM serial +tests: + sample.usbd.console: + depends_on: + - usbd + tags: usb + harness: console + harness_config: + fixture: fixture_usb_cdc diff --git a/samples/subsys/usb/console-next/src/main.c b/samples/subsys/usb/console-next/src/main.c new file mode 100644 index 0000000000000..7bb050598186b --- /dev/null +++ b/samples/subsys/usb/console-next/src/main.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console), zephyr_cdc_acm_uart), + "Console device is not ACM CDC UART device"); + +int main(void) +{ + const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); + uint32_t dtr = 0; + + /* Poll if the DTR flag was set */ + while (!dtr) { + uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr); + /* Give CPU resources to low priority threads. */ + k_sleep(K_MSEC(100)); + } + + while (1) { + printk("Hello World! %s\n", CONFIG_ARCH); + k_sleep(K_SECONDS(1)); + } +} diff --git a/samples/subsys/usb/console/Kconfig b/samples/subsys/usb/console/Kconfig deleted file mode 100644 index 96c5455894806..0000000000000 --- a/samples/subsys/usb/console/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -# Source common USB sample options used to initialize new experimental USB -# device stack. The scope of these options is limited to USB samples in project -# tree, you cannot use them in your own application. -source "samples/subsys/usb/common/Kconfig.sample_usbd" - -source "Kconfig.zephyr" diff --git a/samples/subsys/usb/console/src/main.c b/samples/subsys/usb/console/src/main.c index bf2230687e1c9..59296591ac5f3 100644 --- a/samples/subsys/usb/console/src/main.c +++ b/samples/subsys/usb/console/src/main.c @@ -4,52 +4,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include #include #include -#include #include BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console), zephyr_cdc_acm_uart), "Console device is not ACM CDC UART device"); -#if defined(CONFIG_USB_DEVICE_STACK_NEXT) -static struct usbd_context *sample_usbd; - -static int enable_usb_device_next(void) -{ - int err; - - sample_usbd = sample_usbd_init_device(NULL); - if (sample_usbd == NULL) { - return -ENODEV; - } - - err = usbd_enable(sample_usbd); - if (err) { - return err; - } - - return 0; -} -#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */ - int main(void) { const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); uint32_t dtr = 0; -#if defined(CONFIG_USB_DEVICE_STACK_NEXT) - if (enable_usb_device_next()) { - return 0; - } -#else if (usb_enable(NULL)) { return 0; } -#endif /* Poll if the DTR flag was set */ while (!dtr) { diff --git a/samples/subsys/usb/console/usbd_next_prj.conf b/samples/subsys/usb/console/usbd_next_prj.conf deleted file mode 100644 index 841bffbf012b5..0000000000000 --- a/samples/subsys/usb/console/usbd_next_prj.conf +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG_USB_DEVICE_STACK_NEXT=y - -CONFIG_STDOUT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_UART_LINE_CTRL=y -CONFIG_USBD_CDC_ACM_CLASS=y - -CONFIG_LOG=y -CONFIG_USBD_LOG_LEVEL_WRN=y -CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y - -CONFIG_SAMPLE_USBD_PID=0x0004 -CONFIG_SAMPLE_USBD_PRODUCT="USBD console sample" diff --git a/samples/subsys/usb/dfu-next/CMakeLists.txt b/samples/subsys/usb/dfu-next/CMakeLists.txt new file mode 100644 index 0000000000000..defe46f998fb6 --- /dev/null +++ b/samples/subsys/usb/dfu-next/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(usb-dfu) + +include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/subsys/usb/dfu-next/Kconfig b/samples/subsys/usb/dfu-next/Kconfig new file mode 100644 index 0000000000000..44a54b057d3ff --- /dev/null +++ b/samples/subsys/usb/dfu-next/Kconfig @@ -0,0 +1,36 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "USB DFU sample options" + +config APP_USB_DFU_USE_FLASH_BACKEND + select FLASH + select FLASH_MAP + select STREAM_FLASH + select IMG_MANAGER + select IMG_ERASE_PROGRESSIVELY + bool "Option to clear the flash area before mounting" + help + Use this to force an existing file system to be created. + +if APP_USB_DFU_USE_FLASH_BACKEND + +config USBD_DFU_FLASH + default y + +config USBD_DFU_FLASH_SLOT0 + default n + +config USBD_DFU_FLASH_SLOT1 + default y + +endif + +endmenu + +# Source common USB sample options used to initialize new experimental USB +# device stack. The scope of these options is limited to USB samples in project +# tree, you cannot use them in your own application. +source "samples/subsys/usb/common/Kconfig.sample_usbd" + +source "Kconfig.zephyr" diff --git a/samples/subsys/usb/dfu-next/README.rst b/samples/subsys/usb/dfu-next/README.rst new file mode 100644 index 0000000000000..7d78fedc07900 --- /dev/null +++ b/samples/subsys/usb/dfu-next/README.rst @@ -0,0 +1,137 @@ +.. zephyr:code-sample:: dfu-next + :name: USB DFU + :relevant-api: usbd_api usbd_dfu + + Implement a basic USB DFU device + +Overview +******** + +This sample application demonstrates the USB DFU implementation using the +new experimental USB device stack. + +Requirements +************ + +This project requires an experimental USB device driver (UDC API) and uses the +:ref:`disk_access_api` and RAM-disk to download/upload the image. + +Building and Running +******************** + +This sample can be built for multiple boards, in this example we will build it +for the reel board: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/usb/dfu-next + :board: reel_board + :goals: build flash + :compact: + +`dfu-util`_ tool can be used to download or upload the images. There are two +modes of operation in the USB DFU, runtime and DFU. The example starts in +runtime mode. To switch to DFU mode without uploading or downloading, the +following command can be used: + +.. code-block:: console + + dfu-util --detach + +Use the following command to upload the ``ramdisk0`` image to the host: + +.. code-block:: console + + dfu-util --alt 0 --upload ramdisk0_backup.bin + +Use the following command to download the ``ramdisk0`` image to the device: + +.. code-block:: console + + dfu-util --alt 0 --download ramdisk0_backup.bin + +Building with flash backend enabled +*********************************** + +The USB DFU device support has a built-in flash backend. This backend uses +:ref:`flash_img_api` and :ref:`flash_map_api` to write or read flash image, the +implementation is similar to the one we had in the previous USB DFU device +example. + +To use flash backend set the :kconfig:option:`CONFIG_APP_USB_DFU_USE_FLASH_BACKEND`. +An additional interface will be available in DFU mode to upload/download the +SLOT-1 image. + +It is also possible to try the sample together with the MCUboot bootloader +library. The following example shows how to build MCUboot and this sample with +flash backend and MCUboot support enabled using the :ref:`sysbuild`: + +.. zephyr-app-commands:: + :tool: west + :zephyr-app: samples/subsys/usb/dfu-next + :board: reel_board + :goals: build flash + :west-args: --sysbuild + :gen-args: -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_APP_USB_DFU_USE_FLASH_BACKEND=y + +Another application image is required to be used as a firmware update and +downloaded to SLOT-1. Build and sign a second application image e.g. +:zephyr:code-sample:`hello_world`, which will be used as an image for the +update. Do not forget to enable the required :kconfig:option:`CONFIG_BOOTLOADER_MCUBOOT` +option (as described in :ref:`mcuboot`). For example: + +.. zephyr-app-commands:: + :app: zephyr/samples/hello_world + :board: reel_board + :gen-args: -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\" -DCONFIG_BOOTLOADER_MCUBOOT=y + :goals: flash + +Use the following command to download new image to the device: + +.. code-block:: console + + dfu-util --alt 1 --download build/zephyr/zephyr.signed.bin + +Reset the SoC. MCUboot boot will swap the images and boot the new application, +showing this output to the console: + +.. code-block:: console + + *** Booting MCUboot v2.1.0-rc1-134-gb9d69dd2a2d6 *** + *** Using Zephyr OS build v3.7.0-4345-ga5d0d8533a41 *** + I: Starting bootloader + I: Primary image: magic=good, swap_type=0x4, copy_done=0x1, image_ok=0x1 + I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3 + I: Boot source: none + I: Image index: 0, Swap type: test + I: Starting swap using move algorithm. + I: Bootloader chainload address offset: 0xc000 + I: Image version: v0.0.0 + I: Jumping to the first image slot + *** Booting Zephyr OS build v3.7.0-4345-ga5d0d8533a41 *** + Hello World! reel_board@1/nrf52840 + + +Reset the SoC again and MCUboot should revert the images and boot +USB DFU sample, showing this output to the console: + +.. code-block:: console + + *** Booting MCUboot v2.1.0-rc1-134-gb9d69dd2a2d6 *** + *** Using Zephyr OS build v3.7.0-4345-ga5d0d8533a41 *** + I: Starting bootloader + I: Primary image: magic=good, swap_type=0x2, copy_done=0x1, image_ok=0x3 + I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 + I: Boot source: none + I: Image index: 0, Swap type: revert + I: Starting swap using move algorithm. + I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 + I: Bootloader chainload address offset: 0xc000 + I: Image version: v0.0.0 + I: Jumping to the first image slot + *** Booting Zephyr OS build v3.7.0-4345-ga5d0d8533a41 *** + [00:00:00.000,335] main: USBD message: VBUS ready + [00:00:00.000,427] main: USB DFU sample is initialized + + +.. _dfu-util: https://dfu-util.sourceforge.net/ +.. _Using MCUboot with Zephyr: https://docs.mcuboot.com/readme-zephyr diff --git a/samples/subsys/usb/dfu-next/app.overlay b/samples/subsys/usb/dfu-next/app.overlay new file mode 100644 index 0000000000000..ef18db35ccb42 --- /dev/null +++ b/samples/subsys/usb/dfu-next/app.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ramdisk0 { + compatible = "zephyr,ram-disk"; + disk-name = "image0"; + sector-size = <512>; + sector-count = <32>; + }; +}; diff --git a/samples/subsys/usb/dfu-next/prj.conf b/samples/subsys/usb/dfu-next/prj.conf new file mode 100644 index 0000000000000..4ac6e6dd8d2ee --- /dev/null +++ b/samples/subsys/usb/dfu-next/prj.conf @@ -0,0 +1,10 @@ +CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_USBD_DFU=y + +CONFIG_LOG=y +CONFIG_USBD_LOG_LEVEL_WRN=y +CONFIG_USBD_DFU_LOG_LEVEL_WRN=y +CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y +CONFIG_SAMPLE_USBD_PID=0x0005 + +CONFIG_DISK_ACCESS=y diff --git a/samples/subsys/usb/dfu-next/sample.yaml b/samples/subsys/usb/dfu-next/sample.yaml new file mode 100644 index 0000000000000..02b53e25d5362 --- /dev/null +++ b/samples/subsys/usb/dfu-next/sample.yaml @@ -0,0 +1,25 @@ +sample: + name: USB DFU sample +common: + min_ram: 64 + depends_on: + - usbd +tests: + sample.usbd.dfu: + integration_platforms: + - nrf52840dk/nrf52840 + - nrf54h20dk/nrf54h20/cpuapp + - frdm_k64f + - stm32f723e_disco + - nucleo_f413zh + - mimxrt685_evk/mimxrt685s/cm33 + - mimxrt1060_evk/mimxrt1062/qspi + tags: usb + sample.usbd.dfu-flash: + platform_allow: + - nrf52840dk/nrf52840 + - frdm_k64f + min_flash: 1024 + tags: usb + extra_configs: + - CONFIG_APP_USB_DFU_USE_FLASH_BACKEND=y diff --git a/samples/subsys/usb/dfu-next/src/main.c b/samples/subsys/usb/dfu-next/src/main.c new file mode 100644 index 0000000000000..81f8aa6c89c00 --- /dev/null +++ b/samples/subsys/usb/dfu-next/src/main.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(main, LOG_LEVEL_INF); + +USBD_DEVICE_DEFINE(dfu_usbd, + DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)), + 0x2fe3, 0xffff); + +USBD_DESC_LANG_DEFINE(sample_lang); +USBD_DESC_CONFIG_DEFINE(fs_cfg_desc, "DFU FS Configuration"); +USBD_DESC_CONFIG_DEFINE(hs_cfg_desc, "DFU HS Configuration"); + +static const uint8_t attributes = (IS_ENABLED(CONFIG_SAMPLE_USBD_SELF_POWERED) ? + USB_SCD_SELF_POWERED : 0) | + (IS_ENABLED(CONFIG_SAMPLE_USBD_REMOTE_WAKEUP) ? + USB_SCD_REMOTE_WAKEUP : 0); +/* Full speed configuration */ +USBD_CONFIGURATION_DEFINE(sample_fs_config, + attributes, + CONFIG_SAMPLE_USBD_MAX_POWER, &fs_cfg_desc); + +/* High speed configuration */ +USBD_CONFIGURATION_DEFINE(sample_hs_config, + attributes, + CONFIG_SAMPLE_USBD_MAX_POWER, &hs_cfg_desc); + +static void switch_to_dfu_mode(struct usbd_context *const ctx); + +struct dfu_ramdisk_data { + const char *name; + uint32_t last_block; + uint32_t sector_size; + uint32_t sector_count; + union { + uint32_t uploaded; + uint32_t downloaded; + }; +}; + +static struct dfu_ramdisk_data ramdisk0_data = { + .name = "image0", +}; + +static int init_dfu_ramdisk_data(struct dfu_ramdisk_data *const data) +{ + int err; + + err = disk_access_init(data->name); + if (err) { + return err; + } + + err = disk_access_status(data->name); + if (err) { + return err; + } + + err = disk_access_ioctl(data->name, DISK_IOCTL_GET_SECTOR_COUNT, &data->sector_count); + if (err) { + return err; + } + + err = disk_access_ioctl(data->name, DISK_IOCTL_GET_SECTOR_SIZE, &data->sector_size); + if (err) { + return err; + } + + LOG_INF("disk %s sector count %u sector size %u", + data->name, data->sector_count, data->sector_size); + + return err; +} + +static int ramdisk_read(void *const priv, const uint32_t block, const uint16_t size, + uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE]) +{ + struct dfu_ramdisk_data *const data = priv; + int err; + + if (size == 0) { + /* There is nothing to upload */ + return 0; + } + + if (block == 0) { + if (init_dfu_ramdisk_data(data)) { + LOG_ERR("Failed to init ramdisk data"); + return -EINVAL; + } + + data->last_block = 0; + data->uploaded = 0; + } else { + if (data->last_block + 1U != block) { + return -EINVAL; + } + + } + + if (block >= data->sector_count) { + /* Nothing to upload */ + return 0; + } + + err = disk_access_read(data->name, buf, block, 1); + if (err) { + LOG_ERR("Failed to read from RAMdisk"); + return err; + } + + data->last_block = block; + data->uploaded += MIN(size, data->sector_size); + LOG_INF("block %u size %u uploaded %u", block, size, data->uploaded); + + return size; +} + +static int ramdisk_write(void *const priv, const uint32_t block, const uint16_t size, + const uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE]) +{ + struct dfu_ramdisk_data *const data = priv; + int err; + + if (block == 0) { + if (init_dfu_ramdisk_data(data)) { + LOG_ERR("Failed to init ramdisk data"); + return -EINVAL; + } + + data->last_block = 0; + data->downloaded = 0; + } else { + if (data->last_block + 1U != block) { + return -EINVAL; + } + + } + + if (size == 0) { + /* Nothing to write */ + return 0; + } + + err = disk_access_write(data->name, buf, block, 1); + if (err) { + LOG_ERR("Failed to write to RAMdisk"); + return err; + } + + data->last_block = block; + data->downloaded += size; + LOG_INF("block %u size %u downloaded %u", block, size, data->downloaded); + + return 0; +} + +USBD_DFU_DEFINE_IMG(ramdisk0, "ramdisk0", &ramdisk0_data, ramdisk_read, ramdisk_write, NULL); + +static void msg_cb(struct usbd_context *const usbd_ctx, + const struct usbd_msg *const msg) +{ + LOG_INF("USBD message: %s", usbd_msg_type_string(msg->type)); + + if (msg->type == USBD_MSG_CONFIGURATION) { + LOG_INF("\tConfiguration value %d", msg->status); + } + + if (usbd_can_detect_vbus(usbd_ctx)) { + if (msg->type == USBD_MSG_VBUS_READY) { + if (usbd_enable(usbd_ctx)) { + LOG_ERR("Failed to enable device support"); + } + } + + if (msg->type == USBD_MSG_VBUS_REMOVED) { + if (usbd_disable(usbd_ctx)) { + LOG_ERR("Failed to disable device support"); + } + } + } + + if (msg->type == USBD_MSG_DFU_APP_DETACH) { + switch_to_dfu_mode(usbd_ctx); + } + + if (msg->type == USBD_MSG_DFU_DOWNLOAD_COMPLETED) { + if (IS_ENABLED(CONFIG_BOOTLOADER_MCUBOOT) && + IS_ENABLED(CONFIG_APP_USB_DFU_USE_FLASH_BACKEND)) { + boot_request_upgrade(false); + } + } +} + +static void switch_to_dfu_mode(struct usbd_context *const ctx) +{ + int err; + + LOG_INF("Detach USB device"); + usbd_disable(ctx); + usbd_shutdown(ctx); + + err = usbd_add_descriptor(&dfu_usbd, &sample_lang); + if (err) { + LOG_ERR("Failed to initialize language descriptor (%d)", err); + return; + } + + if (usbd_caps_speed(&dfu_usbd) == USBD_SPEED_HS) { + err = usbd_add_configuration(&dfu_usbd, USBD_SPEED_HS, &sample_hs_config); + if (err) { + LOG_ERR("Failed to add High-Speed configuration"); + return; + } + + err = usbd_register_class(&dfu_usbd, "dfu_dfu", USBD_SPEED_HS, 1); + if (err) { + LOG_ERR("Failed to add register classes"); + return; + } + + usbd_device_set_code_triple(&dfu_usbd, USBD_SPEED_HS, 0, 0, 0); + } + + err = usbd_add_configuration(&dfu_usbd, USBD_SPEED_FS, &sample_fs_config); + if (err) { + LOG_ERR("Failed to add Full-Speed configuration"); + return; + } + + err = usbd_register_class(&dfu_usbd, "dfu_dfu", USBD_SPEED_FS, 1); + if (err) { + LOG_ERR("Failed to add register classes"); + return; + } + + usbd_device_set_code_triple(&dfu_usbd, USBD_SPEED_FS, 0, 0, 0); + + err = usbd_init(&dfu_usbd); + if (err) { + LOG_ERR("Failed to initialize USB device support"); + return; + } + + err = usbd_msg_register_cb(&dfu_usbd, msg_cb); + if (err) { + LOG_ERR("Failed to register message callback"); + return; + } + + err = usbd_enable(&dfu_usbd); + if (err) { + LOG_ERR("Failed to enable USB device support"); + } +} + +int main(void) +{ + struct usbd_context *sample_usbd; + int ret; + + sample_usbd = sample_usbd_init_device(msg_cb); + if (sample_usbd == NULL) { + LOG_ERR("Failed to initialize USB device"); + return -ENODEV; + } + + if (!usbd_can_detect_vbus(sample_usbd)) { + ret = usbd_enable(sample_usbd); + if (ret) { + LOG_ERR("Failed to enable device support"); + return ret; + } + } + + LOG_INF("USB DFU sample is initialized"); + + return 0; +} diff --git a/samples/subsys/usb/dfu/sample.yaml b/samples/subsys/usb/dfu/sample.yaml index a298d5b5a6e8b..dea42901cc7b9 100644 --- a/samples/subsys/usb/dfu/sample.yaml +++ b/samples/subsys/usb/dfu/sample.yaml @@ -6,19 +6,26 @@ common: arch_exclude: posix platform_exclude: - mimxrt1010_evk - - mimxrt1050_evk@qspi - mimxrt1020_evk - mimxrt1015_evk - - mimxrt1060_evk + - mimxrt1060_evk@A/mimxrt1062/qspi + - mimxrt1060_evk@B/mimxrt1062/qspi + - mimxrt1060_evk@C/mimxrt1062/qspi - sam4l_ek - - mimxrt1050_evk - - mimxrt1060_evk@hyperflash + - same54_xpro + - samr21_xpro + - mimxrt1050_evk/mimxrt1052/hyperflash + - mimxrt1050_evk/mimxrt1052/qspi + - mimxrt1060_evk/mimxrt1062/hyperflash + - mimxrt1180_evk/mimxrt1189/cm7 - nucleo_f207zg - teensy40 - teensy41 - b_u585i_iot02a - frdm_kl25z - frdm_mcxc242 + - frdm_mcxc444 + - frdm_mcxa156 - lpcxpresso55s69/lpc55s69/cpu0 - stm32l562e_dk/stm32l562xx/ns depends_on: usb_device diff --git a/samples/subsys/usb/hid-keyboard/sample.yaml b/samples/subsys/usb/hid-keyboard/sample.yaml index 736036cde5b77..2631f07f81ec6 100644 --- a/samples/subsys/usb/hid-keyboard/sample.yaml +++ b/samples/subsys/usb/hid-keyboard/sample.yaml @@ -13,7 +13,7 @@ common: - stm32f723e_disco - nucleo_f413zh - mimxrt685_evk/mimxrt685s/cm33 - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi tests: sample.usbd.hid-keyboard: tags: usb diff --git a/samples/subsys/usb/hid-mouse/sample.yaml b/samples/subsys/usb/hid-mouse/sample.yaml index 0434927ea4e8f..ea670e849e9f9 100644 --- a/samples/subsys/usb/hid-mouse/sample.yaml +++ b/samples/subsys/usb/hid-mouse/sample.yaml @@ -21,8 +21,7 @@ tests: - frdm_k64f - stm32f723e_disco - nucleo_f413zh - - mimxrt685_evk/mimxrt685s/cm33 - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi extra_args: - CONF_FILE="usbd_next_prj.conf" - EXTRA_DTC_OVERLAY_FILE="usbd_next.overlay" diff --git a/samples/subsys/usb/mass/sample.yaml b/samples/subsys/usb/mass/sample.yaml index 6ee3daa6a2d92..352ee21002275 100644 --- a/samples/subsys/usb/mass/sample.yaml +++ b/samples/subsys/usb/mass/sample.yaml @@ -29,7 +29,7 @@ tests: - stm32f723e_disco - nucleo_f413zh - mimxrt685_evk/mimxrt685s/cm33 - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi extra_args: - CONF_FILE="usbd_next_prj.conf" - EXTRA_DTC_OVERLAY_FILE="ramdisk.overlay" diff --git a/samples/subsys/usb/midi/CMakeLists.txt b/samples/subsys/usb/midi/CMakeLists.txt new file mode 100644 index 0000000000000..5bb9b0097df20 --- /dev/null +++ b/samples/subsys/usb/midi/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(usb_midi) + +include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/subsys/usb/midi/Kconfig b/samples/subsys/usb/midi/Kconfig new file mode 100644 index 0000000000000..b6cd6618aff3a --- /dev/null +++ b/samples/subsys/usb/midi/Kconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Titouan Christophe +# SPDX-License-Identifier: Apache-2.0 + +# Source common USB sample options used to initialize new experimental USB +# device stack. The scope of these options is limited to USB samples in project +# tree, you cannot use them in your own application. +source "samples/subsys/usb/common/Kconfig.sample_usbd" + +source "Kconfig.zephyr" diff --git a/samples/subsys/usb/midi/README.rst b/samples/subsys/usb/midi/README.rst new file mode 100644 index 0000000000000..35c2b52acaa49 --- /dev/null +++ b/samples/subsys/usb/midi/README.rst @@ -0,0 +1,84 @@ +.. zephyr:code-sample:: usb-midi2-device + :name: USB MIDI2 device + :relevant-api: usbd_api usbd_midi2 input_events + + Implements a simple USB MIDI loopback and keyboard device. + +Overview +******** + +This sample demonstrates how to implement a USB MIDI device. It can run on +any board with a USB device controller. This sample sends all MIDI1 messages +sent to the device back to the host. In addition, presses and release on +input keys (such as the board user buttons) are sent as MIDI1 note on and +note off events. + +The application exposes a single USB-MIDI interface with a single bidirectional +group terminal. This allows exchanging data with the host on a "virtual wire" +that carries MIDI1 messages, pretty much like a standard USB-MIDI in/out adapter +would provide. The loopback acts as if a real MIDI cable was connected between +the output and the input, and the input keys act as a MIDI keyboard. + +Building and Running +******************** + +The code can be found in :zephyr_file:`samples/subsys/usb/midi`. + +To build and flash the application: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/usb/midi + :board: nucleo_f429zi + :goals: build flash + :compact: + +Using the MIDI interface +************************ + +Once this sample is flashed, connect the device USB port to a host computer +with MIDI support. For example, on Linux, you can use alsa to access the device: + +.. code-block:: console + + $ amidi -l + Dir Device Name + IO hw:2,1,0 Group 1 (USBD MIDI Sample) + +On Mac OS you can use the system tool "Audio MIDI Setup" to view the device, +see https://support.apple.com/guide/audio-midi-setup/set-up-midi-devices-ams875bae1e0/mac + +The "USBD MIDI Sample" interface should also appear in any program with MIDI +support; like your favorite Digital Audio Workstation or synthetizer. If you +don't have any such program at hand, there are some webmidi programs online, +for example: https://muted.io/piano/. + +Testing loopback +**************** + +Open a first shell, and start dumping MIDI events: + +.. code-block:: console + + $ amidi -p hw:2,1,0 -d + + +Then, in a second shell, send some MIDI events (for example note-on/note-off): + +.. code-block:: console + + $ amidi -p hw:2,1,0 -S "90427f 804200" + +These events should then appear in the first shell (dump) + +On devboards with a user button, press it and observe that there are some note +on/note off events delivered to the first shell (dump) + +.. code-block:: console + + $ amidi -p hw:2,1,0 -d + + 90 40 7F + 80 40 7F + 90 40 7F + 80 40 7F + [...] diff --git a/samples/subsys/usb/midi/app.overlay b/samples/subsys/usb/midi/app.overlay new file mode 100644 index 0000000000000..7d8ba72ef5cb3 --- /dev/null +++ b/samples/subsys/usb/midi/app.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Titouan Christophe + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + usb_midi: usb_midi { + compatible = "zephyr,midi2-device"; + status = "okay"; + #address-cells = <1>; + #size-cells = <1>; + + midi_in_out@0 { + reg = <0 1>; + protocol = "midi1-up-to-128b"; + }; + }; +}; diff --git a/samples/subsys/usb/midi/prj.conf b/samples/subsys/usb/midi/prj.conf new file mode 100644 index 0000000000000..fdc77affb2302 --- /dev/null +++ b/samples/subsys/usb/midi/prj.conf @@ -0,0 +1,11 @@ +CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_USBD_MIDI2_CLASS=y + +CONFIG_SAMPLE_USBD_PRODUCT="USBD MIDI Sample" +CONFIG_SAMPLE_USBD_PID=0x0010 + +CONFIG_INPUT=y + +CONFIG_LOG=y +CONFIG_USBD_LOG_LEVEL_WRN=y +CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y diff --git a/samples/subsys/usb/midi/sample.yaml b/samples/subsys/usb/midi/sample.yaml new file mode 100644 index 0000000000000..5189725c1a4eb --- /dev/null +++ b/samples/subsys/usb/midi/sample.yaml @@ -0,0 +1,11 @@ +sample: + name: USB MIDI 2.0 device class sample +tests: + sample.usb_device_next.midi: + depends_on: usbd + tags: usb + harness: console + harness_config: + type: one_line + regex: + - "USB device support enabled" diff --git a/samples/subsys/usb/midi/src/main.c b/samples/subsys/usb/midi/src/main.c new file mode 100644 index 0000000000000..4581d1f01835b --- /dev/null +++ b/samples/subsys/usb/midi/src/main.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024 Titouan Christophe + * + * SPDX-License-Identifier: Apache-2.0 + * + * @file + * @brief Sample application for USB MIDI 2.0 device class + */ + +#include + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(sample_usb_midi, LOG_LEVEL_INF); + +static const struct device *const midi = DEVICE_DT_GET(DT_NODELABEL(usb_midi)); + +static struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios, {0}); + +static void key_press(struct input_event *evt, void *user_data) +{ + /* Only handle key presses in the 7bit MIDI range */ + if (evt->type != INPUT_EV_KEY || evt->code > 0x7f) { + return; + } + uint8_t command = evt->value ? UMP_MIDI_NOTE_ON : UMP_MIDI_NOTE_OFF; + uint8_t channel = 0; + uint8_t note = evt->code; + uint8_t velocity = 100; + + struct midi_ump ump = UMP_MIDI1_CHANNEL_VOICE(0, command, channel, + note, velocity); + usbd_midi_send(midi, ump); +} +INPUT_CALLBACK_DEFINE(NULL, key_press, NULL); + +static void on_midi_packet(const struct device *dev, const struct midi_ump ump) +{ + LOG_INF("Received MIDI packet (MT=%X)", UMP_MT(ump)); + + /* Only send MIDI1 channel voice messages back to the host */ + if (UMP_MT(ump) == UMP_MT_MIDI1_CHANNEL_VOICE) { + LOG_INF("Send back MIDI1 message %02X %02X %02X", UMP_MIDI_STATUS(ump), + UMP_MIDI1_P1(ump), UMP_MIDI1_P2(ump)); + usbd_midi_send(dev, ump); + } +} + +static void on_device_ready(const struct device *dev, const bool ready) +{ + /* Light up the LED (if any) when USB-MIDI2.0 is enabled */ + if (led.port) { + gpio_pin_set_dt(&led, ready); + } +} + +static const struct usbd_midi_ops ops = { + .rx_packet_cb = on_midi_packet, + .ready_cb = on_device_ready, +}; + +int main(void) +{ + struct usbd_context *sample_usbd; + + if (!device_is_ready(midi)) { + LOG_ERR("MIDI device not ready"); + return -1; + } + + if (led.port) { + if (gpio_pin_configure_dt(&led, GPIO_OUTPUT)) { + LOG_ERR("Unable to setup LED, not using it"); + memset(&led, 0, sizeof(led)); + } + } + + usbd_midi_set_ops(midi, &ops); + + sample_usbd = sample_usbd_init_device(NULL); + if (sample_usbd == NULL) { + LOG_ERR("Failed to initialize USB device"); + return -1; + } + + if (usbd_enable(sample_usbd)) { + LOG_ERR("Failed to enable device support"); + return -1; + } + + LOG_INF("USB device support enabled"); + return 0; +} diff --git a/samples/subsys/usb/shell/prj.conf b/samples/subsys/usb/shell/prj.conf index e821f19c03ab8..03d6eb8f1bbec 100644 --- a/samples/subsys/usb/shell/prj.conf +++ b/samples/subsys/usb/shell/prj.conf @@ -2,6 +2,7 @@ CONFIG_SHELL=y CONFIG_USB_DEVICE_STACK_NEXT=y CONFIG_USBD_SHELL=y CONFIG_USBD_LOOPBACK_CLASS=y +CONFIG_UDC_BUF_POOL_SIZE=4096 CONFIG_LOG=y CONFIG_USBD_LOG_LEVEL_WRN=y diff --git a/samples/subsys/usb/shell/sample.yaml b/samples/subsys/usb/shell/sample.yaml index 7316a4d10e270..a0a03a8c4c51b 100644 --- a/samples/subsys/usb/shell/sample.yaml +++ b/samples/subsys/usb/shell/sample.yaml @@ -10,7 +10,7 @@ tests: - nrf54h20dk/nrf54h20/cpuapp - frdm_k64f - mimxrt685_evk/mimxrt685s/cm33 - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi harness: keyboard tags: usb sample.usbh.shell: diff --git a/samples/subsys/usb/webusb-next/sample.yaml b/samples/subsys/usb/webusb-next/sample.yaml index d3beb068981cc..e26352fe50e56 100644 --- a/samples/subsys/usb/webusb-next/sample.yaml +++ b/samples/subsys/usb/webusb-next/sample.yaml @@ -11,5 +11,5 @@ tests: - stm32f723e_disco - nucleo_f413zh - mimxrt685_evk/mimxrt685s/cm33 - - mimxrt1060_evk + - mimxrt1060_evk/mimxrt1062/qspi harness: TBD diff --git a/samples/subsys/usb/webusb-next/src/sfunc.c b/samples/subsys/usb/webusb-next/src/sfunc.c index d20482e429ad0..6ac16ba265b6e 100644 --- a/samples/subsys/usb/webusb-next/src/sfunc.c +++ b/samples/subsys/usb/webusb-next/src/sfunc.c @@ -19,7 +19,7 @@ LOG_MODULE_REGISTER(sfunc, LOG_LEVEL_INF); NET_BUF_POOL_FIXED_DEFINE(sfunc_pool, 1, 0, sizeof(struct udc_buf_info), NULL); -static uint8_t __aligned(sizeof(void *)) sfunc_buf[512]; +UDC_STATIC_BUF_DEFINE(sfunc_buf, 512); struct sfunc_desc { struct usb_if_descriptor if0; @@ -133,7 +133,6 @@ struct net_buf *sfunc_buf_alloc(struct usbd_class_data *const c_data, } bi = udc_get_buf_info(buf); - memset(bi, 0, sizeof(struct udc_buf_info)); bi->ep = ep; return buf; diff --git a/samples/subsys/usb_c/sink/src/main.c b/samples/subsys/usb_c/sink/src/main.c index fb6407a030917..14daabd48bd5f 100644 --- a/samples/subsys/usb_c/sink/src/main.c +++ b/samples/subsys/usb_c/sink/src/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/samples/subsys/usb_c/source/prj.conf b/samples/subsys/usb_c/source/prj.conf index c3d4ebb510b34..644d0d02bb79e 100644 --- a/samples/subsys/usb_c/source/prj.conf +++ b/samples/subsys/usb_c/source/prj.conf @@ -4,3 +4,4 @@ CONFIG_USBC_THREAD_PRIORITY=10 CONFIG_ADC=y CONFIG_PWM=y CONFIG_LOG=y +CONFIG_GPIO=y diff --git a/samples/subsys/usb_c/source/src/main.c b/samples/subsys/usb_c/source/src/main.c index 1e7018c2748fa..177860a4335e8 100644 --- a/samples/subsys/usb_c/source/src/main.c +++ b/samples/subsys/usb_c/source/src/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/samples/tfm_integration/tfm_psa_test/sample.yaml b/samples/tfm_integration/tfm_psa_test/sample.yaml index d924e70461862..2d7c7d1c0c246 100644 --- a/samples/tfm_integration/tfm_psa_test/sample.yaml +++ b/samples/tfm_integration/tfm_psa_test/sample.yaml @@ -10,7 +10,6 @@ common: - v2m_musca_s1/musca_s1/ns modules: - psa-arch-tests - - tf-m-tests integration_platforms: - mps2/an521/cpu0/ns harness: console diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index 61af265e77b10..30d29f35c9591 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -3,7 +3,7 @@ common: - trusted-firmware-m - mcuboot modules: - - psa-arch-tests + - tf-m-tests platform_allow: - nrf5340dk/nrf5340/cpuapp/ns - nrf9160dk/nrf9160/ns diff --git a/samples/userspace/prod_consumer/src/sample_driver_foo.c b/samples/userspace/prod_consumer/src/sample_driver_foo.c index 929ff6c1e007a..c84efe94589b9 100644 --- a/samples/userspace/prod_consumer/src/sample_driver_foo.c +++ b/samples/userspace/prod_consumer/src/sample_driver_foo.c @@ -65,7 +65,7 @@ static int sample_driver_foo_state_set(const struct device *dev, bool active) return 0; } -static struct sample_driver_api sample_driver_foo_api = { +static DEVICE_API(sample, sample_driver_foo_api) = { .write = sample_driver_foo_write, .set_callback = sample_driver_foo_set_callback, .state_set = sample_driver_foo_state_set diff --git a/samples/userspace/shared_mem/sample.yaml b/samples/userspace/shared_mem/sample.yaml index e53d93490fd0f..19749ed7cef53 100644 --- a/samples/userspace/shared_mem/sample.yaml +++ b/samples/userspace/shared_mem/sample.yaml @@ -21,5 +21,7 @@ tests: - cy8cproto_062_4343w - cy8cproto_063_ble - ucans32k1sic + - mimxrt700_evk/mimxrt798s/cm33_cpu0 + - mimxrt700_evk/mimxrt798s/cm33_cpu1 extra_configs: - CONFIG_TEST_HW_STACK_PROTECTION=n diff --git a/scripts/build/elf_parser.py b/scripts/build/elf_parser.py old mode 100644 new mode 100755 diff --git a/scripts/build/file2hex.py b/scripts/build/file2hex.py index 2bb967cf29da0..71336d0bb3d69 100755 --- a/scripts/build/file2hex.py +++ b/scripts/build/file2hex.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # # Copyright (c) 2017 Intel Corporation +# Copyright (c) 2025 Siemens AG # # SPDX-License-Identifier: Apache-2.0 @@ -31,6 +32,8 @@ def parse_args(): parser.add_argument("-l", "--length", type=lambda x: int(x, 0), default=-1, help="""Length in bytes to read from the input file. Defaults to reading till the end of the input file.""") + parser.add_argument("-m", "--format", default="list", + help="Output format: 'list' (default) or 'literal' (string literal)") parser.add_argument("-g", "--gzip", action="store_true", help="Compress the file using gzip before output") parser.add_argument("-t", "--gzip-mtime", type=int, default=0, @@ -43,7 +46,11 @@ def parse_args(): def get_nice_string(list_or_iterator): - return ", ".join("0x" + str(x) for x in list_or_iterator) + # Convert into comma separated list form. + s = ", ".join("0x" + str(x) for x in list_or_iterator) + + # Format the list to eight values per line. + return "\n".join(s[i:i+47] for i in range(0, len(s), 48)) def make_hex(chunk): @@ -52,6 +59,12 @@ def make_hex(chunk): print(get_nice_string(hexlist) + ',') +def make_string_literal(chunk): + hexdata = codecs.encode(chunk, 'hex').decode("utf-8") + hexlist = map(''.join, zip(*[iter(hexdata)] * 2)) + print(''.join("\\x" + str(x) for x in hexlist), end='') + + def main(): parse_args() @@ -70,14 +83,30 @@ def main(): else: with open(args.file, "rb") as fp: fp.seek(args.offset) - if args.length < 0: - for chunk in iter(lambda: fp.read(8), b''): - make_hex(chunk) + + if args.format == "literal": + if args.length < 0: + print('"', end='') + for chunk in iter(lambda: fp.read(1024), b''): + make_string_literal(chunk) + print('"', end='') + else: + print('"', end='') + remainder = args.length + for chunk in iter(lambda: fp.read(min(1024, remainder)), b''): + make_string_literal(chunk) + remainder = remainder - len(chunk) + print('"', end='') + else: - remainder = args.length - for chunk in iter(lambda: fp.read(min(8, remainder)), b''): - make_hex(chunk) - remainder = remainder - len(chunk) + if args.length < 0: + for chunk in iter(lambda: fp.read(1024), b''): + make_hex(chunk) + else: + remainder = args.length + for chunk in iter(lambda: fp.read(min(1024, remainder)), b''): + make_hex(chunk) + remainder = remainder - len(chunk) if __name__ == "__main__": diff --git a/scripts/build/gen_app_partitions.py b/scripts/build/gen_app_partitions.py old mode 100644 new mode 100755 diff --git a/scripts/build/gen_image_info.py b/scripts/build/gen_image_info.py old mode 100644 new mode 100755 diff --git a/scripts/build/gen_isr_tables_parser_carrays.py b/scripts/build/gen_isr_tables_parser_carrays.py old mode 100644 new mode 100755 diff --git a/scripts/build/gen_isr_tables_parser_local.py b/scripts/build/gen_isr_tables_parser_local.py old mode 100644 new mode 100755 diff --git a/scripts/build/gen_iter_sections.py b/scripts/build/gen_iter_sections.py old mode 100644 new mode 100755 diff --git a/scripts/build/gen_relocate_app.py b/scripts/build/gen_relocate_app.py old mode 100644 new mode 100755 index f1bcccf1df699..48ef8a4bf95cf --- a/scripts/build/gen_relocate_app.py +++ b/scripts/build/gen_relocate_app.py @@ -8,21 +8,22 @@ """ This script will relocate .text, .rodata, .data and .bss sections from required files and places it in the required memory region. This memory region and file -are given to this python script in the form of a string. +are given to this python script in the form of a file. +A regular expression filter can be applied to select only the required sections from the file. -Example of such a string would be:: +Example of content in such an input file would be:: - SRAM2:COPY:/home/xyz/zephyr/samples/hello_world/src/main.c,\ - SRAM1:COPY:/home/xyz/zephyr/samples/hello_world/src/main2.c, \ - FLASH2:NOCOPY:/home/xyz/zephyr/samples/hello_world/src/main3.c + SRAM2:COPY:/home/xyz/zephyr/samples/hello_world/src/main.c,.*foo|.*bar + SRAM1:COPY:/home/xyz/zephyr/samples/hello_world/src/main2.c,.*bar + FLASH2:NOCOPY:/home/xyz/zephyr/samples/hello_world/src/main3.c, One can also specify the program header for a given memory region: - SRAM2\\ :phdr0:COPY:/home/xyz/zephyr/samples/hello_world/src/main.c + SRAM2\\ :phdr0:COPY:/home/xyz/zephyr/samples/hello_world/src/main.c, To invoke this script:: - python3 gen_relocate_app.py -i input_string -o generated_linker -c generated_code + python3 gen_relocate_app.py -i input_file -o generated_linker -c generated_code Configuration that needs to be sent to the python script. @@ -45,6 +46,7 @@ import argparse import os import glob +import re import warnings from collections import defaultdict from enum import Enum @@ -225,7 +227,7 @@ def region_is_default_ram(region_name: str) -> bool: return region_name == args.default_ram_region -def find_sections(filename: str) -> 'dict[SectionKind, list[OutputSection]]': +def find_sections(filename: str, symbol_filter: str) -> 'dict[SectionKind, list[OutputSection]]': """ Locate relocatable sections in the given object file. @@ -243,6 +245,9 @@ def find_sections(filename: str) -> 'dict[SectionKind, list[OutputSection]]': out = defaultdict(list) for section in sections: + if not re.search(symbol_filter, section.name): + # Section is filtered-out + continue section_kind = SectionKind.for_section_named(section.name) if section_kind is None: continue @@ -501,9 +506,10 @@ def get_obj_filename(searchpath, filename): # Extracts all possible components for the input string: -# [\ :program_header]:[;...]:[;...] -# Returns a 4-tuple with them: (mem_region, program_header, flags, files) +# [\ :program_header]:[;...]:[;...][,filter] +# Returns a 5-tuple with them: (mem_region, program_header, flags, files, filter) # If no `program_header` is defined, returns an empty string +# If no `filter` is defined, returns an empty string def parse_input_string(line): # Be careful when splitting by : to avoid breaking absolute paths on Windows mem_region, rest = line.split(':', 1) @@ -513,27 +519,34 @@ def parse_input_string(line): mem_region = mem_region.rstrip() phdr, rest = rest.split(':', 1) - # Split lists by semicolons, in part to support generator expressions - flag_list, file_list = (lst.split(';') for lst in rest.split(':', 1)) + flag_list, rest = rest.split(':', 1) + flag_list = flag_list.split(';') + + + # Split file list by semicolons, in part to support generator expressions + file_list, symbol_filter = rest.split(',', 1) + file_list = file_list.split(';') - return mem_region, phdr, flag_list, file_list + return mem_region, phdr, flag_list, file_list, symbol_filter -# Create a dict with key as memory type and files as a list of values. +# Create a dict with key as memory type and (files, symbol_filter) tuple +# as a list of values. # Also, return another dict with program headers for memory regions def create_dict_wrt_mem(): # need to support wild card * rel_dict = dict() phdrs = dict() - input_rel_dict = args.input_rel_dict.read() - if input_rel_dict == '': + input_rel_dict = args.input_rel_dict.read().splitlines() + if not input_rel_dict: sys.exit("Disable CONFIG_CODE_DATA_RELOCATION if no file needs relocation") - for line in input_rel_dict.split('|'): + + for line in input_rel_dict: if ':' not in line: continue - mem_region, phdr, flag_list, file_list = parse_input_string(line) + mem_region, phdr, flag_list, file_list, symbol_filter = parse_input_string(line) # Handle any program header if phdr != '': @@ -556,12 +569,15 @@ def create_dict_wrt_mem(): if args.verbose: print("Memory region ", mem_region, " Selected for files:", file_name_list) + # Apply filter on files + file_name_filter_list = [(f, symbol_filter) for f in file_name_list] + mem_region = "|".join((mem_region, *flag_list)) if mem_region in rel_dict: - rel_dict[mem_region].extend(file_name_list) + rel_dict[mem_region].extend(file_name_filter_list) else: - rel_dict[mem_region] = file_name_list + rel_dict[mem_region] = file_name_filter_list return rel_dict, phdrs @@ -585,13 +601,13 @@ def main(): for memory_type, files in rel_dict.items(): full_list_of_sections: 'dict[SectionKind, list[OutputSection]]' = defaultdict(list) - for filename in files: + for filename, symbol_filter in files: obj_filename = get_obj_filename(searchpath, filename) # the obj file wasn't found. Probably not compiled. if not obj_filename: continue - file_sections = find_sections(obj_filename) + file_sections = find_sections(obj_filename, symbol_filter) # Merge sections from file into collection of sections for all files for category, sections in file_sections.items(): full_list_of_sections[category].extend(sections) diff --git a/scripts/build/gen_symtab.py b/scripts/build/gen_symtab.py old mode 100644 new mode 100755 diff --git a/scripts/build/gen_syscalls.py b/scripts/build/gen_syscalls.py index 607445ce129cd..352130caf8333 100755 --- a/scripts/build/gen_syscalls.py +++ b/scripts/build/gen_syscalls.py @@ -158,10 +158,14 @@ """ -exported_template = """ +llext_weakdefs_template = """/* auto-generated by gen_syscalls.py, don't edit */ + +#include +#include + /* * This symbol is placed at address 0 by llext-sections.ld. Its value and - * type is not important, we are only interested in its location + * type is not important, we are only interested in its location. */ static void * const no_syscall_impl Z_GENERIC_SECTION(llext_no_syscall_impl); @@ -171,6 +175,19 @@ * an extension requiring them is loaded. */ %s +""" + + +llext_exports_template = """/* auto-generated by gen_syscalls.py, don't edit */ + +/* + * Export the implementation functions of all emitted syscalls. + * Only the symbol names are relevant in this file, they will be + * resolved to the actual implementation functions by the linker. + */ + +/* Symbol declarations */ +%s /* Exported symbols */ %s @@ -345,7 +362,7 @@ def marshall_defs(func_name, func_type, args): else: mrsh += "\t\t" + "uintptr_t arg3, uintptr_t arg4, void *more, void *ssf)\n" mrsh += "{\n" - mrsh += "\t" + "arch_current_thread()->syscall_frame = ssf;\n" + mrsh += "\t" + "_current->syscall_frame = ssf;\n" for unused_arg in range(nmrsh, 6): mrsh += "\t(void) arg%d;\t/* unused */\n" % unused_arg @@ -371,7 +388,7 @@ def marshall_defs(func_name, func_type, args): if func_type == "void": mrsh += "\t" + "%s;\n" % vrfy_call - mrsh += "\t" + "arch_current_thread()->syscall_frame = NULL;\n" + mrsh += "\t" + "_current->syscall_frame = NULL;\n" mrsh += "\t" + "return 0;\n" else: mrsh += "\t" + "%s ret = %s;\n" % (func_type, vrfy_call) @@ -380,10 +397,10 @@ def marshall_defs(func_name, func_type, args): ptr = "((uint64_t *)%s)" % mrsh_rval(nmrsh - 1, nmrsh) mrsh += "\t" + "K_OOPS(K_SYSCALL_MEMORY_WRITE(%s, 8));\n" % ptr mrsh += "\t" + "*%s = ret;\n" % ptr - mrsh += "\t" + "arch_current_thread()->syscall_frame = NULL;\n" + mrsh += "\t" + "_current->syscall_frame = NULL;\n" mrsh += "\t" + "return 0;\n" else: - mrsh += "\t" + "arch_current_thread()->syscall_frame = NULL;\n" + mrsh += "\t" + "_current->syscall_frame = NULL;\n" mrsh += "\t" + "return (uintptr_t) ret;\n" mrsh += "}\n" @@ -435,8 +452,10 @@ def parse_args(): help="Indicates we are on system with 64-bit registers") parser.add_argument("--gen-mrsh-files", action="store_true", help="Generate marshalling files (*_mrsh.c)") - parser.add_argument("-e", "--syscall-export-llext", + parser.add_argument("-e", "--syscall-exports-llext", help="output C system call export for extensions") + parser.add_argument("-w", "--syscall-weakdefs-llext", + help="output C system call weak definitions") parser.add_argument("-u", "--userspace-only", action="store_true", help="Only generate the userpace path of wrappers") args = parser.parse_args() @@ -498,14 +517,23 @@ def main(): fp.write(table_template % (weak_defines, ",\n\t".join(table_entries))) - if args.syscall_export_llext: - with open(args.syscall_export_llext, "w") as fp: - # Export symbols for emitted syscalls + exported.sort() + + if args.syscall_weakdefs_llext: + with open(args.syscall_weakdefs_llext, "w") as fp: + # Provide weak definitions for all emitted syscalls weak_refs = "\n".join("extern __weak ALIAS_OF(no_syscall_impl) void * const %s;" % e for e in exported) + fp.write(llext_weakdefs_template % weak_refs) + + if args.syscall_exports_llext: + with open(args.syscall_exports_llext, "w") as fp: + # Export symbols for emitted syscalls + extern_refs = "\n".join("extern void * const %s;" + % e for e in exported) exported_symbols = "\n".join("EXPORT_SYMBOL(%s);" % e for e in exported) - fp.write(exported_template % (weak_refs, exported_symbols)) + fp.write(llext_exports_template % (extern_refs, exported_symbols)) # Listing header emitted to stdout ids_emit.sort() diff --git a/scripts/build/llext_inject_slids.py b/scripts/build/llext_inject_slids.py index 19e87edba9338..b2f42f0c81321 100755 --- a/scripts/build/llext_inject_slids.py +++ b/scripts/build/llext_inject_slids.py @@ -36,20 +36,22 @@ def __init__(self, elf_path, log): self.elf = ELFFile(self.elf_fd) def _find_symtab(self): - supported_symtab_sections = [ - ".symtab", - ".dynsym", - ] - - symtab = None - for section_name in supported_symtab_sections: - symtab = self.elf.get_section_by_name(section_name) - if not isinstance(symtab, SymbolTableSection): - self.log.debug(f"section {section_name} not found.") - else: - self.log.info(f"processing '{section_name}' symbol table...") - self.log.debug(f"(symbol table is at file offset 0x{symtab['sh_offset']:X})") - break + e_type = self.elf.header['e_type'] + if e_type == 'ET_DYN': + symtab_name = ".dynsym" + elif e_type == 'ET_REL': + symtab_name = ".symtab" + else: + self.log.error(f"unexpected ELF file type {e_type}") + return None + + symtab = self.elf.get_section_by_name(symtab_name) + if not isinstance(symtab, SymbolTableSection): + self.log.debug(f"section {symtab_name} not found.") + return None + + self.log.info(f"processing symbol table from '{symtab_name}'...") + self.log.debug(f"(symbol table is at file offset 0x{symtab['sh_offset']:X})") return symtab def _find_imports_in_symtab(self, symtab): diff --git a/scripts/build/mergehex.py b/scripts/build/mergehex.py old mode 100644 new mode 100755 diff --git a/scripts/build/parse_syscalls.py b/scripts/build/parse_syscalls.py old mode 100644 new mode 100755 diff --git a/scripts/build/subfolder_list.py b/scripts/build/subfolder_list.py old mode 100644 new mode 100755 diff --git a/scripts/build/uf2families.json b/scripts/build/uf2families.json index 14c8e5d043cb6..10a8e4038c118 100644 --- a/scripts/build/uf2families.json +++ b/scripts/build/uf2families.json @@ -189,6 +189,11 @@ "short_name": "RP2040", "description": "Raspberry Pi RP2040" }, + { + "id": "0xe48bff57", + "short_name": "RP2350", + "description": "Raspberry Pi RP2350" + }, { "id": "0x00ff6919", "short_name": "STM32L4", diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6a35bdebc94fb..25b09073bdb33 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -464,10 +464,13 @@ sub hash_show_words { (?:__)?(?:u|s|be|le)(?:8|16|32|64)| atomic_t )}; +# DIR is misinterpreted as a macro or value in some POSIX headers +our $typePosixTypedefs = qr{DIR}; our $typeTypedefs = qr{(?x: $typeC99Typedefs\b| $typeOtherOSTypedefs\b| - $typeKernelTypedefs\b + $typeKernelTypedefs\b| + $typePosixTypedefs\b )}; our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; @@ -5497,8 +5500,9 @@ sub process { my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); my $offset = statement_rawlines($whitespace) - 1; - $allowed[$allow] = 0; - #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; + # always allow braces (i.e. require them) + $allowed[$allow] = 1; + #print "COND<$cond> block<$block> whitespace<$whitespace> offset<$offset>\n"; # We have looked at and allowed this specific line. $suppress_ifbraces{$ln + $offset} = 1; @@ -5507,46 +5511,37 @@ sub process { $ln += statement_rawlines($block) - 1; substr($block, 0, length($cond), ''); + #print "COND<$cond> block<$block>\n"; + + # Remove any 0x1C characters. The script replaces + # comments /* */ with those. + $block =~ tr/\x1C//d; $seen++ if ($block =~ /^\s*{/); - #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; - if (statement_lines($cond) > 1) { - #print "APW: ALLOWED: cond<$cond>\n"; - $allowed[$allow] = 1; - } - if ($block =~/\b(?:if|for|while)\b/) { - #print "APW: ALLOWED: block<$block>\n"; - $allowed[$allow] = 1; - } - if (statement_block_size($block) > 1) { - #print "APW: ALLOWED: lines block<$block>\n"; - $allowed[$allow] = 1; - } $allow++; } - if ($seen) { - my $sum_allowed = 0; - foreach (@allowed) { - $sum_allowed += $_; - } - if ($sum_allowed == 0) { - WARN("BRACES", - "braces {} are not necessary for any arm of this statement\n" . $herectx); - } elsif ($sum_allowed != $allow && - $seen != $allow) { - CHK("BRACES", - "braces {} should be used on all arms of this statement\n" . $herectx); - } + my $sum_allowed = 0; + foreach (@allowed) { + $sum_allowed += $_; + } + #print "sum_allowed<$sum_allowed> seen<$seen> allow<$allow>\n"; + if ($sum_allowed == 0) { + WARN("BRACES", + "braces {} are not necessary for any arm of this statement\n" . $herectx); + } elsif ($seen != $allow) { + WARN("BRACES", + "braces {} must be used on all arms of this statement\n" . $herectx); } } } if (!defined $suppress_ifbraces{$linenr - 1} && $line =~ /\b(if|while|for|else)\b/) { my $allowed = 0; - - # Check the pre-context. - if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { + # Check the pre-context for: + # '#': #if + # '}': } while() + if (substr($line, 0, $-[0]) =~ /([\#\}]\s*)$/) { #print "APW: ALLOWED: pre<$1>\n"; $allowed = 1; } @@ -5556,39 +5551,21 @@ sub process { # Check the condition. my ($cond, $block) = @{$chunks[0]}; - #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; + #print "level $level CHECKING<$linenr> cond<$cond> block<$block>\n"; if (defined $cond) { substr($block, 0, length($cond), ''); } - if (statement_lines($cond) > 1) { - #print "APW: ALLOWED: cond<$cond>\n"; - $allowed = 1; - } - if ($block =~/\b(?:if|for|while)\b/) { - #print "APW: ALLOWED: block<$block>\n"; - $allowed = 1; - } - if (statement_block_size($block) > 1) { - #print "APW: ALLOWED: lines block<$block>\n"; - $allowed = 1; - } - # Check the post-context. - if (defined $chunks[1]) { - my ($cond, $block) = @{$chunks[1]}; - if (defined $cond) { - substr($block, 0, length($cond), ''); - } - if ($block =~ /^\s*\{/) { - #print "APW: ALLOWED: chunk-1 block<$block>\n"; - $allowed = 1; - } - } - if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { + # Remove any 0x1C characters. The script replaces + # comments /* */ with those. + $block =~ tr/\x1C//d; + #print sprintf '%v02X', $block; + #print "\n"; + if ($level == 0 && $block !~ /^\s*\{/ && !$allowed) { my $cnt = statement_rawlines($block); my $herectx = get_stat_here($linenr, $cnt, $here); WARN("BRACES", - "braces {} are not necessary for single statement blocks\n" . $herectx); + "braces {} are required around if/while/for/else\n" . $herectx); } } @@ -6073,6 +6050,7 @@ sub process { # Check for __attribute__ aligned, prefer __aligned if ($realfile !~ m@\binclude/uapi/@ && + $realfile !~ m@\binclude/zephyr/toolchain@ && $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { WARN("PREFER_ALIGNED", "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); @@ -6588,9 +6566,10 @@ sub process { } # check for uses of __BYTE_ORDER__ - while ($line =~ /\b(__BYTE_ORDER__)\b/g) { - ERROR("BYTE_ORDER", - "Use of the '$1' macro is disallowed. Use CONFIG_(BIG|LITTLE)_ENDIAN instead\n" . $herecurr); + while ($realfile !~ m@^include/zephyr/toolchain@ && + $line =~ /\b(__BYTE_ORDER__)\b/g) { + ERROR("BYTE_ORDER", + "Use of the '$1' macro is disallowed. Use CONFIG_(BIG|LITTLE)_ENDIAN instead\n" . $herecurr); } # check for use of yield() diff --git a/scripts/checkpatch/typedefsfile b/scripts/checkpatch/typedefsfile index 0fc22b9779b43..ad569c5e33042 100644 --- a/scripts/checkpatch/typedefsfile +++ b/scripts/checkpatch/typedefsfile @@ -2,7 +2,6 @@ _cpu_arch_t k_mem_partition_attr_t k_timepoint_t mbedtls_pk_context -z_arch_esf_t pinctrl_soc_pin_t io_rw_32 \b[a-zA-Z_][a-zA-Z0-9_]*TypeDef diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index aa4ec915b158e..34073348ff97c 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -212,16 +212,29 @@ def run(self): if not os.path.exists(checkpatch): self.skip(f'{checkpatch} not found') + # check for Perl installation on Windows + if os.name == 'nt': + if not shutil.which('perl'): + self.failure("Perl not installed - required for checkpatch.pl. Please install Perl or add to PATH.") + return + else: + cmd = ['perl', checkpatch] + + # Linux and MacOS + else: + cmd = [checkpatch] + + cmd.extend(['--mailback', '--no-tree', '-']) diff = subprocess.Popen(('git', 'diff', '--no-ext-diff', COMMIT_RANGE), stdout=subprocess.PIPE, cwd=GIT_TOP) try: - subprocess.run((checkpatch, '--mailback', '--no-tree', '-'), + subprocess.run(cmd, check=True, stdin=diff.stdout, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - shell=True, cwd=GIT_TOP) + shell=False, cwd=GIT_TOP) except subprocess.CalledProcessError as ex: output = ex.output.decode("utf-8") @@ -371,10 +384,14 @@ class KconfigCheck(ComplianceTest): doc = "See https://docs.zephyrproject.org/latest/build/kconfig/tips.html for more details." path_hint = "" - def run(self, full=True, no_modules=False, filename="Kconfig", hwm=None): - self.no_modules = no_modules + # Top-level Kconfig file. The path can be relative to srctree (ZEPHYR_BASE). + FILENAME = "Kconfig" - kconf = self.parse_kconfig(filename=filename, hwm=hwm) + # Kconfig symbol prefix/namespace. + CONFIG_ = "CONFIG_" + + def run(self): + kconf = self.parse_kconfig() self.check_top_menu_not_too_long(kconf) self.check_no_pointless_menuconfigs(kconf) @@ -382,10 +399,10 @@ def run(self, full=True, no_modules=False, filename="Kconfig", hwm=None): self.check_no_redefined_in_defconfig(kconf) self.check_no_enable_in_boolean_prompt(kconf) self.check_soc_name_sync(kconf) - if full: - self.check_no_undef_outside_kconfig(kconf) + self.check_no_undef_outside_kconfig(kconf) + self.check_disallowed_defconfigs(kconf) - def get_modules(self, modules_file, settings_file): + def get_modules(self, modules_file, sysbuild_modules_file, settings_file): """ Get a list of modules and put them in a file that is parsed by Kconfig @@ -393,17 +410,14 @@ def get_modules(self, modules_file, settings_file): This is needed to complete Kconfig sanity tests. """ - if self.no_modules: - with open(modules_file, 'w') as fp_module_file: - fp_module_file.write("# Empty\n") - return - # Invoke the script directly using the Python executable since this is # not a module nor a pip-installed Python utility zephyr_module_path = os.path.join(ZEPHYR_BASE, "scripts", "zephyr_module.py") cmd = [sys.executable, zephyr_module_path, - '--kconfig-out', modules_file, '--settings-out', settings_file] + '--kconfig-out', modules_file, + '--sysbuild-kconfig-out', sysbuild_modules_file, + '--settings-out', settings_file] try: subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) @@ -474,32 +488,6 @@ def get_kconfig_dts(self, kconfig_dts_file, settings_file): except subprocess.CalledProcessError as ex: self.error(ex.output.decode("utf-8")) - def get_v1_model_syms(self, kconfig_v1_file, kconfig_v1_syms_file): - """ - Generate a symbol define Kconfig file. - This function creates a file with all Kconfig symbol definitions from - old boards model so that those symbols will not appear as undefined - symbols in hardware model v2. - - This is needed to complete Kconfig compliance tests. - """ - os.environ['HWM_SCHEME'] = 'v1' - # 'kconfiglib' is global - # pylint: disable=undefined-variable - - try: - kconf_v1 = kconfiglib.Kconfig(filename=kconfig_v1_file, warn=False) - except kconfiglib.KconfigError as e: - self.failure(str(e)) - raise EndTest - - with open(kconfig_v1_syms_file, 'w') as fp_kconfig_v1_syms_file: - for s in kconf_v1.defined_syms: - if s.type != kconfiglib.UNKNOWN: - fp_kconfig_v1_syms_file.write('config ' + s.name) - fp_kconfig_v1_syms_file.write('\n\t' + kconfiglib.TYPE_TO_STR[s.type]) - fp_kconfig_v1_syms_file.write('\n\n') - def get_v2_model(self, kconfig_dir, settings_file): """ Get lists of v2 boards and SoCs and put them in a file that is parsed by @@ -508,8 +496,15 @@ def get_v2_model(self, kconfig_dir, settings_file): This is needed to complete Kconfig sanity tests. """ os.environ['HWM_SCHEME'] = 'v2' + os.environ["KCONFIG_BOARD_DIR"] = os.path.join(kconfig_dir, 'boards') + + os.makedirs(os.path.join(kconfig_dir, 'boards'), exist_ok=True) + os.makedirs(os.path.join(kconfig_dir, 'soc'), exist_ok=True) + os.makedirs(os.path.join(kconfig_dir, 'arch'), exist_ok=True) + kconfig_file = os.path.join(kconfig_dir, 'boards', 'Kconfig') kconfig_boards_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.boards') + kconfig_sysbuild_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.sysbuild') kconfig_defconfig_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.defconfig') board_roots = self.get_module_setting_root('board', settings_file) @@ -526,6 +521,11 @@ def get_v2_model(self, kconfig_dir, settings_file): for board_dir in board.directories: fp.write('osource "' + (board_dir / 'Kconfig.defconfig').as_posix() + '"\n') + with open(kconfig_sysbuild_file, 'w') as fp: + for board in v2_boards: + for board_dir in board.directories: + fp.write('osource "' + (board_dir / 'Kconfig.sysbuild').as_posix() + '"\n') + with open(kconfig_boards_file, 'w') as fp: for board in v2_boards: board_str = 'BOARD_' + re.sub(r"[^a-zA-Z0-9_]", "_", board.name).upper() @@ -542,14 +542,12 @@ def get_v2_model(self, kconfig_dir, settings_file): ) with open(kconfig_file, 'w') as fp: - fp.write( - 'osource "' + (Path(kconfig_dir) / 'boards' / 'Kconfig.syms.v1').as_posix() + '"\n' - ) for board in v2_boards: for board_dir in board.directories: fp.write('osource "' + (board_dir / 'Kconfig').as_posix() + '"\n') kconfig_defconfig_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.defconfig') + kconfig_sysbuild_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.sysbuild') kconfig_soc_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.soc') kconfig_file = os.path.join(kconfig_dir, 'soc', 'Kconfig') @@ -561,6 +559,10 @@ def get_v2_model(self, kconfig_dir, settings_file): for folder in soc_folders: fp.write('osource "' + (Path(folder) / 'Kconfig.defconfig').as_posix() + '"\n') + with open(kconfig_sysbuild_file, 'w') as fp: + for folder in soc_folders: + fp.write('osource "' + (Path(folder) / 'Kconfig.sysbuild').as_posix() + '"\n') + with open(kconfig_soc_file, 'w') as fp: for folder in soc_folders: fp.write('source "' + (Path(folder) / 'Kconfig.soc').as_posix() + '"\n') @@ -578,7 +580,7 @@ def get_v2_model(self, kconfig_dir, settings_file): for arch in v2_archs['archs']: fp.write('source "' + (Path(arch['path']) / 'Kconfig').as_posix() + '"\n') - def parse_kconfig(self, filename="Kconfig", hwm=None): + def parse_kconfig(self): """ Returns a kconfiglib.Kconfig object for the Kconfig files. We reuse this object for all tests to avoid having to reparse for each test. @@ -615,18 +617,12 @@ def parse_kconfig(self, filename="Kconfig", hwm=None): # For multi repo support self.get_modules(os.path.join(kconfiglib_dir, "Kconfig.modules"), + os.path.join(kconfiglib_dir, "Kconfig.sysbuild.modules"), os.path.join(kconfiglib_dir, "settings_file.txt")) # For Kconfig.dts support self.get_kconfig_dts(os.path.join(kconfiglib_dir, "Kconfig.dts"), os.path.join(kconfiglib_dir, "settings_file.txt")) - - # To make compliance work with old hw model and HWMv2 simultaneously. - kconfiglib_boards_dir = os.path.join(kconfiglib_dir, 'boards') - os.makedirs(kconfiglib_boards_dir, exist_ok=True) - os.makedirs(os.path.join(kconfiglib_dir, 'soc'), exist_ok=True) - os.makedirs(os.path.join(kconfiglib_dir, 'arch'), exist_ok=True) - - os.environ["KCONFIG_BOARD_DIR"] = kconfiglib_boards_dir + # For hardware model support (board, soc, arch) self.get_v2_model(kconfiglib_dir, os.path.join(kconfiglib_dir, "settings_file.txt")) # Tells Kconfiglib to generate warnings for all references to undefined @@ -638,7 +634,7 @@ def parse_kconfig(self, filename="Kconfig", hwm=None): # them: so some warnings might get printed # twice. "warn_to_stderr=False" could unfortunately cause # some (other) warnings to never be printed. - return kconfiglib.Kconfig(filename=filename) + return kconfiglib.Kconfig(filename=self.FILENAME) except kconfiglib.KconfigError as e: self.failure(str(e)) raise EndTest @@ -679,6 +675,84 @@ def get_logging_syms(self, kconf): return set(kconf_syms) + def check_disallowed_defconfigs(self, kconf): + """ + Checks that there are no disallowed Kconfigs used in board/SoC defconfig files + """ + # Grep for symbol references. + # + # Example output line for a reference to CONFIG_FOO at line 17 of + # foo/bar.c: + # + # foo/bar.c17#ifdef CONFIG_FOO + # + # 'git grep --only-matching' would get rid of the surrounding context + # ('#ifdef '), but it was added fairly recently (second half of 2018), + # so we extract the references from each line ourselves instead. + # + # The regex uses word boundaries (\b) to isolate the reference, and + # negative lookahead to automatically allowlist the following: + # + # - ##, for token pasting (CONFIG_FOO_##X) + # + # - $, e.g. for CMake variable expansion (CONFIG_FOO_${VAR}) + # + # - @, e.g. for CMakes's configure_file() (CONFIG_FOO_@VAR@) + # + # - {, e.g. for Python scripts ("CONFIG_FOO_{}_BAR".format(...)") + # + # - *, meant for comments like '#endif /* CONFIG_FOO_* */ + + disallowed_symbols = { + "PINCTRL": "Drivers requiring PINCTRL must SELECT it instead.", + } + + disallowed_regex = "(" + "|".join(disallowed_symbols.keys()) + ")$" + + # Warning: Needs to work with both --perl-regexp and the 're' module + regex_boards = r"\bCONFIG_[A-Z0-9_]+\b(?!\s*##|[$@{(.*])" + regex_socs = r"\bconfig\s+[A-Z0-9_]+$" + + grep_stdout_boards = git("grep", "--line-number", "-I", "--null", + "--perl-regexp", regex_boards, "--", ":boards", + cwd=ZEPHYR_BASE) + grep_stdout_socs = git("grep", "--line-number", "-I", "--null", + "--perl-regexp", regex_socs, "--", ":soc", + cwd=ZEPHYR_BASE) + + # Board processing + # splitlines() supports various line terminators + for grep_line in grep_stdout_boards.splitlines(): + path, lineno, line = grep_line.split("\0") + + # Extract symbol references (might be more than one) within the line + for sym_name in re.findall(regex_boards, line): + sym_name = sym_name[len("CONFIG_"):] + # Only check in Kconfig fragment files, references might exist in documentation + if re.match(disallowed_regex, sym_name) and (path[-len("conf"):] == "conf" or + path[-len("defconfig"):] == "defconfig"): + reason = disallowed_symbols.get(sym_name) + self.fmtd_failure("error", "BoardDisallowedKconfigs", path, lineno, desc=f""" +Found disallowed Kconfig symbol in board Kconfig files: CONFIG_{sym_name:35} +{reason} +""") + + # SoCs processing + # splitlines() supports various line terminators + for grep_line in grep_stdout_socs.splitlines(): + path, lineno, line = grep_line.split("\0") + + # Extract symbol references (might be more than one) within the line + for sym_name in re.findall(regex_socs, line): + sym_name = sym_name[len("config"):].strip() + # Only check in Kconfig defconfig files + if re.match(disallowed_regex, sym_name) and "defconfig" in path: + reason = disallowed_symbols.get(sym_name, "Unknown reason") + self.fmtd_failure("error", "SoCDisallowedKconfigs", path, lineno, desc=f""" +Found disallowed Kconfig symbol in SoC Kconfig files: {sym_name:35} +{reason} +""") + def get_defined_syms(self, kconf): # Returns a set() with the names of all defined Kconfig symbols (with no # 'CONFIG_' prefix). This is complicated by samples and tests defining @@ -868,7 +942,7 @@ def check_no_undef_outside_kconfig(self, kconf): undef_to_locs = collections.defaultdict(list) # Warning: Needs to work with both --perl-regexp and the 're' module - regex = r"\bCONFIG_[A-Z0-9_]+\b(?!\s*##|[$@{(.*])" + regex = r"\b" + self.CONFIG_ + r"[A-Z0-9_]+\b(?!\s*##|[$@{(.*])" # Skip doc/releases and doc/security/vulnerabilities.rst, which often # reference removed symbols @@ -884,7 +958,7 @@ def check_no_undef_outside_kconfig(self, kconf): # Extract symbol references (might be more than one) within the # line for sym_name in re.findall(regex, line): - sym_name = sym_name[7:] # Strip CONFIG_ + sym_name = sym_name[len(self.CONFIG_):] # Strip CONFIG_ if sym_name not in defined_syms and \ sym_name not in self.UNDEF_KCONFIG_ALLOWLIST and \ not (sym_name.endswith("_MODULE") and sym_name[:-7] in defined_syms): @@ -900,7 +974,7 @@ def check_no_undef_outside_kconfig(self, kconf): # # CONFIG_ALSO_MISSING arch/xtensa/core/fatal.c:273 # CONFIG_MISSING arch/xtensa/core/fatal.c:264, subsys/fb/cfb.c:20 - undef_desc = "\n".join(f"CONFIG_{sym_name:35} {', '.join(locs)}" + undef_desc = "\n".join(f"{self.CONFIG_}{sym_name:35} {', '.join(locs)}" for sym_name, locs in sorted(undef_to_locs.items())) self.failure(f""" @@ -956,6 +1030,7 @@ def check_no_undef_outside_kconfig(self, kconf): "BOOT_SIGNATURE_TYPE_NONE", # MCUboot setting used by sysbuild "BOOT_SIGNATURE_TYPE_RSA", # MCUboot setting used by sysbuild "BOOT_SWAP_USING_MOVE", # Used in sysbuild for MCUboot configuration + "BOOT_SWAP_USING_OFFSET", # Used in sysbuild for MCUboot configuration "BOOT_SWAP_USING_SCRATCH", # Used in sysbuild for MCUboot configuration "BOOT_UPGRADE_ONLY", # Used in example adjusting MCUboot config, but # symbol is defined in MCUboot itself. @@ -984,6 +1059,11 @@ def check_no_undef_outside_kconfig(self, kconf): "FOO_SETTING_2", "HEAP_MEM_POOL_ADD_SIZE_", # Used as an option matching prefix "HUGETLBFS", # Linux, in boards/xtensa/intel_adsp_cavs25/doc + "IAR_BUFFERED_WRITE", + "IAR_LIBCPP", + "IAR_SEMIHOSTING", + "IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS", # Used in ICMsg tests for intercompatibility + # with older versions of the ICMsg. "LIBGCC_RTLIB", "LLVM_USE_LD", # Both LLVM_USE_* are in cmake/toolchain/llvm/Kconfig "LLVM_USE_LLD", # which are only included if LLVM is selected but @@ -1053,26 +1133,28 @@ class KconfigBasicCheck(KconfigCheck): references inside the Kconfig tree. """ name = "KconfigBasic" - doc = "See https://docs.zephyrproject.org/latest/build/kconfig/tips.html for more details." - path_hint = "" - def run(self): - super().run(full=False) + def check_no_undef_outside_kconfig(self, kconf): + pass + -class KconfigBasicNoModulesCheck(KconfigCheck): +class KconfigBasicNoModulesCheck(KconfigBasicCheck): """ Checks if we are introducing any new warnings/errors with Kconfig when no modules are available. Catches symbols used in the main repository but defined only in a module. """ name = "KconfigBasicNoModules" - doc = "See https://docs.zephyrproject.org/latest/build/kconfig/tips.html for more details." - path_hint = "" - def run(self): - super().run(full=False, no_modules=True) + def get_modules(self, modules_file, sysbuild_modules_file, settings_file): + with open(modules_file, 'w') as fp_module_file: + fp_module_file.write("# Empty\n") + + with open(sysbuild_modules_file, 'w') as fp_module_file: + fp_module_file.write("# Empty\n") -class KconfigHWMv2Check(KconfigCheck, ComplianceTest): + +class KconfigHWMv2Check(KconfigBasicCheck): """ This runs the Kconfig test for board and SoC v2 scheme. This check ensures that all symbols inside the v2 scheme is also defined @@ -1080,13 +1162,52 @@ class KconfigHWMv2Check(KconfigCheck, ComplianceTest): This ensures the board and SoC trees are fully self-contained and reusable. """ name = "KconfigHWMv2" - doc = "See https://docs.zephyrproject.org/latest/guides/kconfig/index.html for more details." - def run(self): - # Use dedicated Kconfig board / soc v2 scheme file. - # This file sources only v2 scheme tree. - kconfig_file = os.path.join(os.path.dirname(__file__), "Kconfig.board.v2") - super().run(full=False, hwm="v2", filename=kconfig_file) + # Use dedicated Kconfig board / soc v2 scheme file. + # This file sources only v2 scheme tree. + FILENAME = os.path.join(os.path.dirname(__file__), "Kconfig.board.v2") + + +class SysbuildKconfigCheck(KconfigCheck): + """ + Checks if we are introducing any new warnings/errors with sysbuild Kconfig, + for example using undefined Kconfig variables. + """ + name = "SysbuildKconfig" + + FILENAME = "share/sysbuild/Kconfig" + CONFIG_ = "SB_CONFIG_" + + # A different allowlist is used for symbols prefixed with SB_CONFIG_ (omitted here). + UNDEF_KCONFIG_ALLOWLIST = { + # zephyr-keep-sorted-start re(^\s+") + "FOO", + "SECOND_SAMPLE", # Used in sysbuild documentation + "SUIT_ENVELOPE", # Used by nRF runners to program provisioning data + "SUIT_MPI_APP_AREA_PATH", # Used by nRF runners to program provisioning data + "SUIT_MPI_GENERATE", # Used by nRF runners to program provisioning data + "SUIT_MPI_RAD_AREA_PATH", # Used by nRF runners to program provisioning data + # zephyr-keep-sorted-stop + } + + +class SysbuildKconfigBasicCheck(SysbuildKconfigCheck, KconfigBasicCheck): + """ + Checks if we are introducing any new warnings/errors with sysbuild Kconfig, + for example using undefined Kconfig variables. + This runs the basic Kconfig test, which is checking only for undefined + references inside the sysbuild Kconfig tree. + """ + name = "SysbuildKconfigBasic" + + +class SysbuildKconfigBasicNoModulesCheck(SysbuildKconfigCheck, KconfigBasicNoModulesCheck): + """ + Checks if we are introducing any new warnings/errors with sysbuild Kconfig + when no modules are available. Catches symbols used in the main repository + but defined only in a module. + """ + name = "SysbuildKconfigBasicNoModules" class Nits(ComplianceTest): @@ -1322,7 +1443,7 @@ class Identity(ComplianceTest): def run(self): for shaidx in get_shas(COMMIT_RANGE): - commit = git("log", "--decorate=short", "-n 1", shaidx) + commit = git("log", "--decorate=short", "--no-use-mailmap", "-n 1", shaidx) signed = [] author = "" sha = "" diff --git a/scripts/ci/coverage/coverage_analysis.py b/scripts/ci/coverage/coverage_analysis.py index 759690753bd0c..df0ebc20a73d2 100644 --- a/scripts/ci/coverage/coverage_analysis.py +++ b/scripts/ci/coverage/coverage_analysis.py @@ -334,7 +334,7 @@ def _xlsx_generate_summary_page(self, workbook, json_report): { "bold": True, "fg_color": "#538DD5", - "color":"white" + "font_color":"white" } ) cell_format = workbook.add_format( @@ -404,7 +404,7 @@ def generate_xlsx_report(self, json_report, output): { "bold": True, "fg_color": "#538DD5", - "color":"white" + "font_color":"white" } ) @@ -415,7 +415,7 @@ def generate_xlsx_report(self, json_report, output): "align": "center", "valign": "vcenter", "fg_color": "#538DD5", - "color":"white" + "font_color":"white" } ) cell_format = self.report_book.add_format( diff --git a/scripts/ci/twister_ignore.txt b/scripts/ci/twister_ignore.txt index abcdc774ed42a..96dfdfd83d5b9 100644 --- a/scripts/ci/twister_ignore.txt +++ b/scripts/ci/twister_ignore.txt @@ -43,6 +43,7 @@ scripts/ci/errno.py scripts/ci/upload_test_results_es.py scripts/ci/what_changed.py scripts/ci/version_mgr.py +scripts/ci/twister_report_analyzer.py scripts/ci/stats/* scripts/requirements* scripts/checkpatch/* diff --git a/scripts/ci/twister_report_analyzer.py b/scripts/ci/twister_report_analyzer.py new file mode 100755 index 0000000000000..3a52c8a2bfe9c --- /dev/null +++ b/scripts/ci/twister_report_analyzer.py @@ -0,0 +1,380 @@ +#!/usr/bin/env python3 +# Copyright (c) 2025 Nordic Semiconductor NA +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import argparse +import csv +import json +import logging +import os +import textwrap +from dataclasses import asdict, dataclass, field, is_dataclass + +logger = logging.getLogger(__name__) + + +def create_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + allow_abbrev=False, + description='Analyzes Twister JSON reports', + epilog=( + textwrap.dedent(""" + Example usage: + To analyze errors with predefined CMake and Build error patterns, run: + > python %(prog)s twister_reports/*.json --long-summary + The summary will be saved to twister_report_summary.json file unless --output option is used. + To save error summary to CSV file, use --output-csv option (number of test files is limited to 100): + > python %(prog)s twister_reports/*.json --output-csv twister_report_summary.csv + One can use --error-patterns option to provide custom error patterns file: + > python %(prog)s **/twister.json --error-patterns error_patterns.txt + """) # noqa E501 + ), + ) + parser.add_argument('inputs', type=str, nargs="+", help='twister.json files to read') + parser.add_argument( + '--error-patterns', + type=str, + help='text file with custom error patterns, ' 'each entry must be separated by newlines', + ) + parser.add_argument( + '--output', + type=str, + default='twister_report_summary.json', + help='output json file name, default: twister_report_summary.json', + ) + parser.add_argument('--output-csv', type=str, help='output csv file name') + parser.add_argument( + '--output-md', type=str, help='output markdown file name to store table with errors' + ) + parser.add_argument( + '--status', + action='store_true', + help='add statuses of testsuites and testcases to the summary', + ) + parser.add_argument( + '--platforms', + action='store_true', + help='add errors per platform to the summary', + ) + parser.add_argument( + '--long-summary', + action='store_true', + help='show all matched errors grouped by reason, otherwise show only most common errors', + ) + + parser.add_argument( + '-ll', + '--log-level', + type=str.upper, + default='INFO', + choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], + ) + return parser + + +@dataclass +class Counters: + counters: dict[str, TestCollection] = field(default_factory=dict) + + def add_counter(self, key: str, test: str = '') -> None: + self.counters[key] = self.counters.get(key, TestCollection()) + self.counters[key].append(test) + + def print_counters(self, indent: int = 0): + for key, value in self.counters.items(): + print(f'{" " * indent}{value.quantity:4} {key}') + if value.has_subcounters(): + value.subcounters.print_counters(indent + 4) + + def sort_by_quantity(self): + self.counters = dict( + sorted(self.counters.items(), key=lambda item: item[1].quantity, reverse=True) + ) + for value in self.counters.values(): + if value.has_subcounters(): + value.subcounters.sort_by_quantity() + + def get_next_entry(self, depth: int = 0, max_depth: int = 10): + for key, value in self.counters.items(): + # limit number of test files to 100 to not exceed CSV cell limit + yield depth, value.quantity, key, ', '.join(value.tests[0:100]) + if value.has_subcounters() and depth < max_depth: + yield from value.subcounters.get_next_entry(depth + 1, max_depth) + + def _flatten(self): + """ + Yield all deepest counters in a flat structure. + Deepest counters refer to those counters which + do not contain any further nested subcounters. + """ + for key, value in self.counters.items(): + if value.has_subcounters(): + yield from value.subcounters._flatten() + else: + yield key, value + + def get_most_common(self, n: int = 10): + return dict(sorted(self._flatten(), key=lambda item: item[1].quantity, reverse=True)[:n]) + + +@dataclass +class TestCollection: + quantity: int = 0 + tests: list[str] = field(default_factory=list) + subcounters: Counters = field(default_factory=Counters) + + def append(self, test: str = ''): + self.quantity += 1 + if test: + self.tests.append(test) + + def has_subcounters(self): + return bool(self.subcounters.counters) + + +class TwisterReports: + def __init__(self): + self.status: Counters = Counters() + self.errors: Counters = Counters() + self.platforms: Counters = Counters() + + def parse_report(self, json_filename): + logger.info(f'Process {json_filename}') + with open(json_filename) as json_results: + json_data = json.load(json_results) + + for ts in json_data.get('testsuites', []): + self.parse_statuses(ts) + + for ts in json_data.get('testsuites', []): + self.parse_testsuite(ts) + + def parse_statuses(self, testsuite): + ts_status = testsuite.get('status', 'no status in testsuite') + self.status.add_counter(ts_status) + # Process testcases + for tc in testsuite.get('testcases', []): + tc_status = tc.get('status') + self.status.counters[ts_status].subcounters.add_counter(tc_status) + + def parse_testsuite(self, testsuite): + ts_status = testsuite.get('status') or 'no status in testsuite' + if ts_status not in ('error', 'failed'): + return + + ts_platform = testsuite.get('platform') or 'Unknown platform' + self.platforms.add_counter(ts_platform) + ts_reason = testsuite.get('reason') or 'Unknown reason' + ts_log = testsuite.get('log') + test_identifier = f'{testsuite.get("platform")}:{testsuite.get("name")}' + + # CMake and Build failures are treated separately. + # Extract detailed information to group errors. Keep the parsing methods + # to allow for further customization and keep backward compatibility. + if ts_reason.startswith('CMake build failure'): + reason = 'CMake build failure' + self.errors.add_counter(reason) + error_key = ts_reason.split(reason, 1)[-1].lstrip(' -') + if not error_key: + error_key = self._parse_cmake_build_failure(ts_log) + self.errors.counters[reason].subcounters.add_counter(error_key, test_identifier) + ts_reason = reason + elif ts_reason.startswith('Build failure'): + reason = 'Build failure' + self.errors.add_counter(reason) + error_key = ts_reason.split(reason, 1)[-1].lstrip(' -') + if not error_key: + error_key = self._parse_build_failure(ts_log) + self.errors.counters[reason].subcounters.add_counter(error_key, test_identifier) + ts_reason = reason + else: + self.errors.add_counter(ts_reason) + + # Process testcases + for tc in testsuite.get('testcases', []): + tc_reason = tc.get('reason') + tc_log = tc.get('log') + if tc_reason and tc_log: + self.errors.counters[ts_reason].subcounters.add_counter(tc_reason, test_identifier) + + if not self.errors.counters[ts_reason].has_subcounters(): + self.errors.counters[ts_reason].tests.append(test_identifier) + + def _parse_cmake_build_failure(self, log: str) -> str | None: + last_warning = 'no warning found' + lines = log.splitlines() + for i, line in enumerate(lines): + if "warning: " in line: + last_warning = line + elif "devicetree error: " in line: + return "devicetree error" + elif "fatal error: " in line: + return line[line.index('fatal error: ') :].strip() + elif "error: " in line: # error: Aborting due to Kconfig warnings + if "undefined symbol" in last_warning: + return last_warning[last_warning.index('undefined symbol') :].strip() + return last_warning + elif "CMake Error at" in line: + for next_line in lines[i + 1 :]: + if next_line.strip(): + return line + ' ' + next_line + return line + return "No matching CMake error pattern found" + + def _parse_build_failure(self, log: str) -> str | None: + last_warning = '' + lines = log.splitlines() + for i, line in enumerate(lines): + if "undefined reference" in line: + return line[line.index('undefined reference') :].strip() + elif "error: ld returned" in line: + if last_warning: + return last_warning + elif "overflowed by" in lines[i - 1]: + return "ld.bfd: region overflowed" + elif "ld.bfd: warning: " in lines[i - 1]: + return "ld.bfd:" + lines[i - 1].split("ld.bfd:", 1)[-1] + return line + elif "error: " in line: + return line[line.index('error: ') :].strip() + elif ": in function " in line: + last_warning = line[line.index('in function') :].strip() + return "No matching build error pattern found" + + def sort_counters(self): + self.status.sort_by_quantity() + self.platforms.sort_by_quantity() + self.errors.sort_by_quantity() + + +class TwisterReportsWithPatterns(TwisterReports): + def __init__(self, error_patterns_file): + super().__init__() + self.error_patterns = [] + self.add_error_patterns(error_patterns_file) + + def add_error_patterns(self, filename): + with open(filename) as f: + self.error_patterns = [ + line + for line in f.read().splitlines() + if line.strip() and not line.strip().startswith('#') + ] + logger.info(f'Loaded {len(self.error_patterns)} error patterns from {filename}') + + def parse_testsuite(self, testsuite): + ts_status = testsuite.get('status') or 'no status in testsuite' + if ts_status not in ('error', 'failed'): + return + + ts_log = testsuite.get('log') + test_identifier = f'{testsuite.get("platform")}:{testsuite.get("name")}' + if key := self._parse_log_with_error_paterns(ts_log): + self.errors.add_counter(key, test_identifier) + # Process testcases + for tc in testsuite.get('testcases', []): + tc_log = tc.get('log') + if tc_log and (key := self._parse_log_with_error_paterns(tc_log)): + self.errors.add_counter(key, test_identifier) + + def _parse_log_with_error_paterns(self, log: str) -> str | None: + for line in log.splitlines(): + for error_pattern in self.error_patterns: + if error_pattern in line: + logger.debug(f'Matched: {error_pattern} in {line}') + return error_pattern + return None + + +class EnhancedJSONEncoder(json.JSONEncoder): + def default(self, o): + if is_dataclass(o): + return asdict(o) + return super().default(o) + + +def dump_to_json(filename, data): + with open(filename, 'w') as f: + json.dump(data, f, indent=4, cls=EnhancedJSONEncoder) + logger.info(f'Data saved to {filename}') + + +def dump_to_csv(filename, data: Counters): + with open(filename, 'w', newline='') as csvfile: + csvwriter = csv.writer(csvfile) + # Write headers + csvwriter.writerow(['Depth', 'Counter', 'Key', 'Tests']) + # Write error data + for csv_data in data.get_next_entry(): + csvwriter.writerow(csv_data) + logger.info(f'Data saved to {filename}') + + +def dump_markdown_table(filename, data: Counters, max_depth=2): + with open(filename, 'w', newline='') as md: + for depth, quantity, key, _ in data.get_next_entry(max_depth=max_depth): + if depth == 0: + md.write('\n') + md.write(f'| {quantity:4} | {key} |\n') + if depth == 0: + md.write('|-------|------|\n') + logger.info(f'Markdown table saved to {filename}') + + +def summary_with_most_common_errors(errors: Counters, limit: int = 15): + print('\nMost common errors summary:') + for key, value in errors.get_most_common(n=limit).items(): + print(f'{value.quantity:4} {key}') + + +def main(): + parser = create_parser() + args = parser.parse_args() + + logging.basicConfig(level=args.log_level, format='%(levelname)-8s: %(message)s') + logger = logging.getLogger() + + if args.error_patterns: + reports = TwisterReportsWithPatterns(args.error_patterns) + else: + reports = TwisterReports() + + for filename in args.inputs: + if os.path.exists(filename): + reports.parse_report(filename) + else: + logger.warning(f'File not found: {filename}') + + reports.sort_counters() + dump_to_json( + args.output, + {'status': reports.status, 'platforms': reports.platforms, 'errors': reports.errors}, + ) + + if args.status: + print('\nTestsuites and testcases status summary:') + reports.status.print_counters() + + if not reports.errors.counters: + return + + if args.platforms and reports.platforms.counters: + print('\nErrors per platform:') + reports.platforms.print_counters() + + if args.long_summary: + print('\nErrors summary:') + reports.errors.print_counters() + else: + summary_with_most_common_errors(reports.errors) + + if args.output_csv: + dump_to_csv(args.output_csv, reports.errors) + if args.output_md: + dump_markdown_table(args.output_md, reports.errors, max_depth=2) + + +if __name__ == '__main__': + main() diff --git a/scripts/coredump/coredump_parser/log_parser.py b/scripts/coredump/coredump_parser/log_parser.py index 889cfb033bfbd..409ee7ff568c6 100644 --- a/scripts/coredump/coredump_parser/log_parser.py +++ b/scripts/coredump/coredump_parser/log_parser.py @@ -62,6 +62,7 @@ def __init__(self, logfile): self.log_hdr = None self.arch_data = list() self.memory_regions = list() + self.threads_metadata = {"hdr_ver" : None, "data" : None} def open(self): self.fd = open(self.logfile, "rb") diff --git a/scripts/coredump/gdbstubs/gdbstub.py b/scripts/coredump/gdbstubs/gdbstub.py index 2fa37303d1e51..07d019ae9008e 100644 --- a/scripts/coredump/gdbstubs/gdbstub.py +++ b/scripts/coredump/gdbstubs/gdbstub.py @@ -179,6 +179,11 @@ def handle_general_query_packet(self, pkt): # For packets qfThreadInfo/qsThreadInfo, obtain a list of all active thread IDs if pkt[0:12] == b"qfThreadInfo": threads_metadata_data = self.logfile.get_threads_metadata()["data"] + + if threads_metadata_data is None: + self.put_gdb_packet(b"l") + return + size_t_size = self.elffile.get_kernel_thread_info_size_t_size() # First, find and store the thread that _kernel considers current diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py index 9fdb3cda5778c..99aac7d720cea 100755 --- a/scripts/dts/gen_defines.py +++ b/scripts/dts/gen_defines.py @@ -97,6 +97,7 @@ def main(): out_dt_define(f"{node.z_path_id}_FOREACH_NODELABEL_VARGS(fn, ...)", " ".join(f"fn({nodelabel}, __VA_ARGS__)" for nodelabel in node.labels)) + write_parent(node) write_children(node) write_dep_info(node) write_idents_and_existence(node) @@ -245,13 +246,13 @@ def write_idents_and_existence(node: edtlib.Node) -> None: idents.extend(f"N_NODELABEL_{str2ident(label)}" for label in node.labels) out_comment("Existence and alternate IDs:") - out_dt_define(node.z_path_id + "_EXISTS", 1) + out_dt_define(f"{node.z_path_id}_EXISTS", 1) # Only determine maxlen if we have any idents if idents: - maxlen = max(len("DT_" + ident) for ident in idents) + maxlen = max(len(f"DT_{ident}") for ident in idents) for ident in idents: - out_dt_define(ident, "DT_" + node.z_path_id, width=maxlen) + out_dt_define(ident, f"DT_{node.z_path_id}", width=maxlen) def write_bus(node: edtlib.Node) -> None: @@ -410,8 +411,8 @@ def map_arm_gic_irq_type(irq, irq_num): idx_vals.append((idx_macro, cell_value)) idx_vals.append((idx_macro + "_EXISTS", 1)) if irq.name: - name_macro = \ - f"{path_id}_IRQ_NAME_{str2ident(irq.name)}_VAL_{name}" + name_macro = ( + f"{path_id}_IRQ_NAME_{str2ident(irq.name)}_VAL_{name}") name_vals.append((name_macro, f"DT_{idx_macro}")) name_vals.append((name_macro + "_EXISTS", 1)) @@ -457,6 +458,17 @@ def write_compatibles(node: edtlib.Node) -> None: out_dt_define(f"{node.z_path_id}_COMPAT_MODEL_IDX_{i}", quote_str(node.edt.compat2model[compat])) +def write_parent(node: edtlib.Node) -> None: + # Visit all parent nodes. + def _visit_parent_node(node: edtlib.Node): + while node is not None: + yield node.parent + node = node.parent + + # Writes helper macros for dealing with node's parent. + out_dt_define(f"{node.z_path_id}_FOREACH_ANCESTOR(fn)", + " ".join(f"fn(DT_{parent.z_path_id})" for parent in + _visit_parent_node(node) if parent is not None)) def write_children(node: edtlib.Node) -> None: # Writes helper macros for dealing with node's children. @@ -593,8 +605,8 @@ def write_vanilla_props(node: edtlib.Node) -> None: # DT_N__P__IDX_0_EXISTS: # Allows treating the string like a degenerate case of a # string-array of length 1. - macro2val[macro + "_IDX_0"] = quote_str(prop.val) - macro2val[macro + "_IDX_0_EXISTS"] = 1 + macro2val[f"{macro}_IDX_0"] = quote_str(prop.val) + macro2val[f"{macro}_IDX_0_EXISTS"] = 1 if prop.enum_indices is not None: macro2val.update(enum_macros(prop, macro)) @@ -607,31 +619,30 @@ def write_vanilla_props(node: edtlib.Node) -> None: plen = prop_len(prop) if plen is not None: # DT_N__P__FOREACH_PROP_ELEM - macro2val[f"{macro}_FOREACH_PROP_ELEM(fn)"] = \ - ' \\\n\t'.join( - f'fn(DT_{node.z_path_id}, {prop_id}, {i})' - for i in range(plen)) + macro2val[f"{macro}_FOREACH_PROP_ELEM(fn)"] = ( + ' \\\n\t'.join(f'fn(DT_{node.z_path_id}, {prop_id}, {i})' + for i in range(plen))) # DT_N__P__FOREACH_PROP_ELEM_SEP - macro2val[f"{macro}_FOREACH_PROP_ELEM_SEP(fn, sep)"] = \ + macro2val[f"{macro}_FOREACH_PROP_ELEM_SEP(fn, sep)"] = ( ' DT_DEBRACKET_INTERNAL sep \\\n\t'.join( f'fn(DT_{node.z_path_id}, {prop_id}, {i})' - for i in range(plen)) + for i in range(plen))) # DT_N__P__FOREACH_PROP_ELEM_VARGS - macro2val[f"{macro}_FOREACH_PROP_ELEM_VARGS(fn, ...)"] = \ + macro2val[f"{macro}_FOREACH_PROP_ELEM_VARGS(fn, ...)"] = ( ' \\\n\t'.join( f'fn(DT_{node.z_path_id}, {prop_id}, {i}, __VA_ARGS__)' - for i in range(plen)) + for i in range(plen))) # DT_N__P__FOREACH_PROP_ELEM_SEP_VARGS - macro2val[f"{macro}_FOREACH_PROP_ELEM_SEP_VARGS(fn, sep, ...)"] = \ + macro2val[f"{macro}_FOREACH_PROP_ELEM_SEP_VARGS(fn, sep, ...)"] = ( ' DT_DEBRACKET_INTERNAL sep \\\n\t'.join( f'fn(DT_{node.z_path_id}, {prop_id}, {i}, __VA_ARGS__)' - for i in range(plen)) + for i in range(plen))) # DT_N__P__LEN - macro2val[macro + "_LEN"] = plen + macro2val[f"{macro}_LEN"] = plen # DT_N__P__EXISTS macro2val[f"{macro}_EXISTS"] = 1 @@ -669,9 +680,9 @@ def enum_macros(prop: edtlib.Property, macro: str): for i, subval in enumerate(val): # DT_N__P__IDX__EXISTS - ret[macro + f"_IDX_{i}_EXISTS"] = 1 + ret[f"{macro}_IDX_{i}_EXISTS"] = 1 # DT_N__P__IDX__ENUM_VAL__EXISTS 1 - ret[macro + f"_IDX_{i}_ENUM_VAL_{subval}_EXISTS"] = 1 + ret[f"{macro}_IDX_{i}_ENUM_VAL_{subval}_EXISTS"] = 1 return ret @@ -683,15 +694,15 @@ def array_macros(prop: edtlib.Property, macro: str): ret = {} for i, subval in enumerate(prop.val): # DT_N__P__IDX__EXISTS - ret[macro + f"_IDX_{i}_EXISTS"] = 1 + ret[f"{macro}_IDX_{i}_EXISTS"] = 1 # DT_N__P__IDX_ if isinstance(subval, str): - ret[macro + f"_IDX_{i}"] = quote_str(subval) + ret[f"{macro}_IDX_{i}"] = quote_str(subval) # DT_N__P__IDX__STRING_... - ret.update(string_macros(macro + f"_IDX_{i}", subval)) + ret.update(string_macros(f"{macro}_IDX_{i}", subval)) else: - ret[macro + f"_IDX_{i}"] = subval + ret[f"{macro}_IDX_{i}"] = subval return ret @@ -703,12 +714,15 @@ def fmt_dep_list(dep_list): if dep_list: # Sort the list by dependency ordinal for predictability. sorted_list = sorted(dep_list, key=lambda node: node.dep_ordinal) - return "\\\n\t" + \ - " \\\n\t".join(f"{n.dep_ordinal}, /* {n.path} */" - for n in sorted_list) + return ("\\\n\t" + " \\\n\t" + .join(f"{n.dep_ordinal}, /* {n.path} */" + for n in sorted_list)) else: return "/* nothing */" + out_comment("Node's hash:") + out_dt_define(f"{node.z_path_id}_HASH", node.hash) + out_comment("Node's dependency ordinal:") out_dt_define(f"{node.z_path_id}_ORD", node.dep_ordinal) out_dt_define(f"{node.z_path_id}_ORD_STR_SORTABLE", f"{node.dep_ordinal:0>5}") @@ -855,8 +869,8 @@ def controller_and_data_macros(entry: edtlib.ControllerAndData, i: int, macro: s # DT_N__P__NAME__VAL_ for cell, val in data.items(): cell_ident = str2ident(cell) - ret[f"{macro}_NAME_{name}_VAL_{cell_ident}"] = \ - f"DT_{macro}_IDX_{i}_VAL_{cell_ident}" + ret[f"{macro}_NAME_{name}_VAL_{cell_ident}"] = ( + f"DT_{macro}_IDX_{i}_VAL_{cell_ident}") ret[f"{macro}_NAME_{name}_VAL_{cell_ident}_EXISTS"] = 1 return ret @@ -907,24 +921,24 @@ def write_global_macros(edt: edtlib.EDT): # Helpers for non-INST for-each macros that take node # identifiers as arguments. - for_each_macros[f"DT_FOREACH_OKAY_{ident}(fn)"] = \ + for_each_macros[f"DT_FOREACH_OKAY_{ident}(fn)"] = ( " ".join(f"fn(DT_{node.z_path_id})" - for node in okay_nodes) - for_each_macros[f"DT_FOREACH_OKAY_VARGS_{ident}(fn, ...)"] = \ + for node in okay_nodes)) + for_each_macros[f"DT_FOREACH_OKAY_VARGS_{ident}(fn, ...)"] = ( " ".join(f"fn(DT_{node.z_path_id}, __VA_ARGS__)" - for node in okay_nodes) + for node in okay_nodes)) # Helpers for INST versions of for-each macros, which take # instance numbers. We emit separate helpers for these because # avoiding an intermediate node_id --> instance number # conversion in the preprocessor helps to keep the macro # expansions simpler. That hopefully eases debugging. - for_each_macros[f"DT_FOREACH_OKAY_INST_{ident}(fn)"] = \ + for_each_macros[f"DT_FOREACH_OKAY_INST_{ident}(fn)"] = ( " ".join(f"fn({edt.compat2nodes[compat].index(node)})" - for node in okay_nodes) - for_each_macros[f"DT_FOREACH_OKAY_INST_VARGS_{ident}(fn, ...)"] = \ + for node in okay_nodes)) + for_each_macros[f"DT_FOREACH_OKAY_INST_VARGS_{ident}(fn, ...)"] = ( " ".join(f"fn({edt.compat2nodes[compat].index(node)}, __VA_ARGS__)" - for node in okay_nodes) + for node in okay_nodes)) for compat, nodes in edt.compat2nodes.items(): for node in nodes: @@ -985,7 +999,7 @@ def out_dt_define( # generate a warning if used, via __WARN()). # # Returns the full generated macro for 'macro', with leading "DT_". - ret = "DT_" + macro + ret = f"DT_{macro}" out_define(ret, val, width=width, deprecation_msg=deprecation_msg) return ret @@ -1031,15 +1045,14 @@ def out_comment(s: str, blank_before=True) -> None: for line in s.splitlines(): # Avoid an extra space after '*' for empty lines. They turn red in # Vim if space error checking is on, which is annoying. - res.append(" *" if not line.strip() else " * " + line) + res.append(f" * {line}".rstrip()) res.append(" */") print("\n".join(res), file=header_file) else: # Format single-line comments like # # /* foo bar */ - print("/* " + s + " */", file=header_file) - + print(f"/* {s} */", file=header_file) ESCAPE_TABLE = str.maketrans( { diff --git a/scripts/dts/gen_driver_kconfig_dts.py b/scripts/dts/gen_driver_kconfig_dts.py index 2d433bbd5ddf1..6014027b455bf 100755 --- a/scripts/dts/gen_driver_kconfig_dts.py +++ b/scripts/dts/gen_driver_kconfig_dts.py @@ -1,13 +1,12 @@ #!/usr/bin/env python3 # # Copyright (c) 2022 Kumar Gala +# Copyright (c) 2025 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 import argparse import os -import sys -import re import yaml try: @@ -16,22 +15,33 @@ except ImportError: from yaml import SafeLoader # type: ignore -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'python-devicetree', - 'src')) -def binding_paths(bindings_dirs): - # Returns a list with the paths to all bindings (.yaml files) in - # 'bindings_dirs' +HEADER = """\ +# Generated devicetree Kconfig +# +# SPDX-License-Identifier: Apache-2.0""" + + +KCONFIG_TEMPLATE = """ +DT_COMPAT_{COMPAT} := {compat} + +config DT_HAS_{COMPAT}_ENABLED +\tdef_bool $(dt_compat_enabled,$(DT_COMPAT_{COMPAT}))""" - binding_paths = [] + +# Character translation table used to derive Kconfig symbol names +TO_UNDERSCORES = str.maketrans("-,.@/+", "______") + + +def binding_paths(bindings_dirs): + # Yields paths to all bindings (.yaml files) in 'bindings_dirs' for bindings_dir in bindings_dirs: for root, _, filenames in os.walk(bindings_dir): for filename in filenames: - if filename.endswith(".yaml") or filename.endswith(".yml"): - binding_paths.append(os.path.join(root, filename)) + if filename.endswith((".yaml", ".yml")): + yield os.path.join(root, filename) - return binding_paths def parse_args(): # Returns parsed command-line arguments @@ -45,56 +55,38 @@ def parse_args(): return parser.parse_args() -def printfile(s): - print(s, file=kconfig_file) - -def str2ident(s): - # Converts 's' to a form suitable for (part of) an identifier - - return re.sub('[-,.@/+]', '_', s.upper()) - -def compat2kconfig(compat): - compat_ident = str2ident(compat) - - printfile(f'') - printfile(f'DT_COMPAT_{compat_ident} := {compat}') - printfile(f'') - printfile(f'config DT_HAS_{compat_ident}_ENABLED') - printfile(f'\tdef_bool $(dt_compat_enabled,$(DT_COMPAT_{compat_ident}))') def main(): - global kconfig_file args = parse_args() - compat_list = [] + compats = set() for binding_path in binding_paths(args.bindings_dirs): with open(binding_path, encoding="utf-8") as f: - contents = f.read() - try: - # Parsed PyYAML output (Python lists/dictionaries/strings/etc., - # representing the file) - raw = yaml.load(contents, Loader=SafeLoader) + # Parsed PyYAML representation graph. For our purpose, + # we don't need the whole file converted into a dict. + root = yaml.compose(f, Loader=SafeLoader) except yaml.YAMLError as e: print(f"WARNING: '{binding_path}' appears in binding " f"directories but isn't valid YAML: {e}") continue - if raw is None or 'compatible' not in raw: - continue - compat_list.append(raw['compatible']) - - # Remove any duplicates and sort the list - compat_list = sorted(set(compat_list)) + if not isinstance(root, yaml.MappingNode): + continue + for key, node in root.value: + if key.value == "compatible" and isinstance(node, yaml.ScalarNode): + compats.add(node.value) + break with open(args.kconfig_out, "w", encoding="utf-8") as kconfig_file: - printfile(f'# Generated devicetree Kconfig') - printfile(f'#') - printfile(f'# SPDX-License-Identifier: Apache-2.0') + print(HEADER, file=kconfig_file) - for c in compat_list: - compat2kconfig(c) + for c in sorted(compats): + out = KCONFIG_TEMPLATE.format( + compat=c, COMPAT=c.upper().translate(TO_UNDERSCORES) + ) + print(out, file=kconfig_file) if __name__ == "__main__": diff --git a/scripts/dts/python-devicetree/src/devicetree/dtlib.py b/scripts/dts/python-devicetree/src/devicetree/dtlib.py index 2a1c298f12058..c4cd1cdbb2b25 100644 --- a/scripts/dts/python-devicetree/src/devicetree/dtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/dtlib.py @@ -20,8 +20,9 @@ import string import sys import textwrap -from typing import Any, Dict, Iterable, List, \ - NamedTuple, NoReturn, Optional, Set, Tuple, TYPE_CHECKING, Union +from typing import (Any, Iterable, + NamedTuple, NoReturn, Optional, + TYPE_CHECKING, Union) # NOTE: tests/test_dtlib.py is the test suite for this library. @@ -91,9 +92,9 @@ def __init__(self, name: str, parent: Optional['Node'], dt: 'DT'): # Remember to update DT.__deepcopy__() if you change this. self._name = name - self.props: Dict[str, 'Property'] = {} - self.nodes: Dict[str, 'Node'] = {} - self.labels: List[str] = [] + self.props: dict[str, Property] = {} + self.nodes: dict[str, Node] = {} + self.labels: list[str] = [] self.parent = parent self.dt = dt @@ -308,13 +309,13 @@ def __init__(self, node: Node, name: str): self.name = name self.value = b"" - self.labels: List[str] = [] + self.labels: list[str] = [] # We have to wait to set this until later, when we've got # the entire tree. - self.offset_labels: Dict[str, int] = {} + self.offset_labels: dict[str, int] = {} self.node: Node = node - self._label_offset_lst: List[Tuple[str, int]] = [] + self._label_offset_lst: list[tuple[str, int]] = [] # A list of [offset, label, type] lists (sorted by offset), # giving the locations of references within the value. 'type' @@ -322,7 +323,7 @@ def __init__(self, node: Node, name: str): # _MarkerType.PHANDLE, for a phandle reference, or # _MarkerType.LABEL, for a label on/within data. Node paths # and phandles need to be patched in after parsing. - self._markers: List[List] = [] + self._markers: list[list] = [] @property def type(self) -> Type: @@ -353,8 +354,8 @@ def type(self) -> Type: if types == [_MarkerType.PATH]: return Type.PATH - if types == [_MarkerType.UINT32, _MarkerType.PHANDLE] and \ - len(self.value) == 4: + if (types == [_MarkerType.UINT32, _MarkerType.PHANDLE] + and len(self.value) == 4): return Type.PHANDLE if set(types) == {_MarkerType.UINT32, _MarkerType.PHANDLE}: @@ -380,14 +381,13 @@ def to_num(self, signed=False) -> int: unsigned. """ if self.type is not Type.NUM: - _err("expected property '{0}' on {1} in {2} to be assigned with " - "'{0} = < (number) >;', not '{3}'" - .format(self.name, self.node.path, self.node.dt.filename, - self)) + _err(f"expected property '{self.name}' on {self.node.path} in " + f"{self.node.dt.filename} to be assigned with " + f"'{self.name} = < (number) >;', not '{self}'") return int.from_bytes(self.value, "big", signed=signed) - def to_nums(self, signed=False) -> List[int]: + def to_nums(self, signed=False) -> list[int]: """ Returns the value of the property as a list of numbers. @@ -401,10 +401,9 @@ def to_nums(self, signed=False) -> List[int]: unsigned. """ if self.type not in (Type.NUM, Type.NUMS): - _err("expected property '{0}' on {1} in {2} to be assigned with " - "'{0} = < (number) (number) ... >;', not '{3}'" - .format(self.name, self.node.path, self.node.dt.filename, - self)) + _err(f"expected property '{self.name}' on {self.node.path} in " + f"{self.node.dt.filename} to be assigned with " + f"'{self.name} = < (number) (number) ... >;', not '{self}'") return [int.from_bytes(self.value[i:i + 4], "big", signed=signed) for i in range(0, len(self.value), 4)] @@ -420,10 +419,9 @@ def to_bytes(self) -> bytes: foo = [ 01 ... ]; """ if self.type is not Type.BYTES: - _err("expected property '{0}' on {1} in {2} to be assigned with " - "'{0} = [ (byte) (byte) ... ];', not '{3}'" - .format(self.name, self.node.path, self.node.dt.filename, - self)) + _err(f"expected property '{self.name}' on {self.node.path} " + f"in {self.node.dt.filename} to be assigned with " + f"'{self.name} = [ (byte) (byte) ... ];', not '{self}'") return self.value @@ -440,10 +438,9 @@ def to_string(self) -> str: not valid UTF-8. """ if self.type is not Type.STRING: - _err("expected property '{0}' on {1} in {2} to be assigned with " - "'{0} = \"string\";', not '{3}'" - .format(self.name, self.node.path, self.node.dt.filename, - self)) + _err(f"expected property '{self.name}' on {self.node.path} " + f"in {self.node.dt.filename} to be assigned with " + f"'{self.name} = \"string\";', not '{self}'") try: ret = self.value.decode("utf-8")[:-1] # Strip null @@ -454,7 +451,7 @@ def to_string(self) -> str: return ret # The separate 'return' appeases the type checker. - def to_strings(self) -> List[str]: + def to_strings(self) -> list[str]: """ Returns the value of the property as a list of strings. @@ -466,10 +463,9 @@ def to_strings(self) -> List[str]: Also raises DTError if any of the strings are not valid UTF-8. """ if self.type not in (Type.STRING, Type.STRINGS): - _err("expected property '{0}' on {1} in {2} to be assigned with " - "'{0} = \"string\", \"string\", ... ;', not '{3}'" - .format(self.name, self.node.path, self.node.dt.filename, - self)) + _err(f"expected property '{self.name}' on {self.node.path} in " + f"{self.node.dt.filename} to be assigned with " + f"'{self.name} = \"string\", \"string\", ... ;', not '{self}'") try: ret = self.value.decode("utf-8").split("\0")[:-1] @@ -490,14 +486,13 @@ def to_node(self) -> Node: foo = < &bar >; """ if self.type is not Type.PHANDLE: - _err("expected property '{0}' on {1} in {2} to be assigned with " - "'{0} = < &foo >;', not '{3}'" - .format(self.name, self.node.path, self.node.dt.filename, - self)) + _err(f"expected property '{self.name}' on {self.node.path} in " + f"{self.node.dt.filename} to be assigned with " + f"'{self.name} = < &foo >;', not '{self}'") return self.node.dt.phandle2node[int.from_bytes(self.value, "big")] - def to_nodes(self) -> List[Node]: + def to_nodes(self) -> list[Node]: """ Returns a list with the Nodes the phandles in the property point to. @@ -516,10 +511,9 @@ def type_ok(): return self.type is Type.NUMS and not self.value if not type_ok(): - _err("expected property '{0}' on {1} in {2} to be assigned with " - "'{0} = < &foo &bar ... >;', not '{3}'" - .format(self.name, self.node.path, - self.node.dt.filename, self)) + _err(f"expected property '{self.name}' on {self.node.path} in " + f"{self.node.dt.filename} to be assigned with " + f"'{self.name} = < &foo &bar ... >;', not '{self}'") return [self.node.dt.phandle2node[int.from_bytes(self.value[i:i + 4], "big")] @@ -538,10 +532,10 @@ def to_path(self) -> Node: For the second case, DTError is raised if the path does not exist. """ if self.type not in (Type.PATH, Type.STRING): - _err("expected property '{0}' on {1} in {2} to be assigned with " - "either '{0} = &foo' or '{0} = \"/path/to/node\"', not '{3}'" - .format(self.name, self.node.path, self.node.dt.filename, - self)) + _err(f"expected property '{self.name}' on {self.node.path} in " + f"{self.node.dt.filename} to be assigned with either " + f"'{self.name} = &foo' or '{self.name} = \"/path/to/node\"', " + f"not '{self}'") try: path = self.value.decode("utf-8")[:-1] @@ -608,9 +602,10 @@ def __str__(self): pos += elm_size - if pos != 0 and \ - (not next_marker or - next_marker[1] not in (_MarkerType.PHANDLE, _MarkerType.LABEL)): + if (pos != 0 + and (not next_marker + or next_marker[1] + not in (_MarkerType.PHANDLE, _MarkerType.LABEL))): s += _N_BYTES_TO_END_STR[elm_size] if pos != len(self.value): @@ -620,8 +615,8 @@ def __str__(self): def __repr__(self): - return f"" + return (f"") # # Internal functions @@ -759,12 +754,12 @@ def __init__(self, filename: Optional[str], include_path: Iterable[str] = (), # Remember to update __deepcopy__() if you change this. self._root: Optional[Node] = None - self.alias2node: Dict[str, Node] = {} - self.label2node: Dict[str, Node] = {} - self.label2prop: Dict[str, Property] = {} - self.label2prop_offset: Dict[str, Tuple[Property, int]] = {} - self.phandle2node: Dict[int, Node] = {} - self.memreserves: List[Tuple[Set[str], int, int]] = [] + self.alias2node: dict[str, Node] = {} + self.label2node: dict[str, Node] = {} + self.label2prop: dict[str, Property] = {} + self.label2prop_offset: dict[str, tuple[Property, int]] = {} + self.phandle2node: dict[int, Node] = {} + self.memreserves: list[tuple[set[str], int, int]] = [] self.filename = filename self._force = force @@ -772,7 +767,7 @@ def __init__(self, filename: Optional[str], include_path: Iterable[str] = (), if filename is not None: self._parse_file(filename, include_path) else: - self._include_path: List[str] = [] + self._include_path: list[str] = [] @property def root(self) -> Node: @@ -914,8 +909,8 @@ def __repr__(self): the DT instance is evaluated. """ if self.filename: - return f"DT(filename='{self.filename}', " \ - f"include_path={self._include_path})" + return (f"DT(filename='{self.filename}', " + f"include_path={self._include_path})") return super().__repr__() def __deepcopy__(self, memo): @@ -1025,7 +1020,7 @@ def _parse_file(self, filename: str, include_path: Iterable[str]): self._file_contents = f.read() self._tok_i = self._tok_end_i = 0 - self._filestack: List[_FileStackElt] = [] + self._filestack: list[_FileStackElt] = [] self._lexer_state: int = _DEFAULT self._saved_token: Optional[_Token] = None @@ -1634,8 +1629,8 @@ def _next_token(self): # State handling - if tok_id in (_T.DEL_PROP, _T.DEL_NODE, _T.OMIT_IF_NO_REF) or \ - tok_val in ("{", ";"): + if (tok_id in (_T.DEL_PROP, _T.DEL_NODE, _T.OMIT_IF_NO_REF) + or tok_val in ("{", ";")): self._lexer_state = _EXPECT_PROPNODENAME @@ -1709,8 +1704,8 @@ def _enter_file(self, filename): def _leave_file(self): # Leaves an /include/d file, returning to the file that /include/d it - self.filename, self._lineno, self._file_contents, self._tok_end_i = \ - self._filestack.pop() + self.filename, self._lineno, self._file_contents, self._tok_end_i = ( + self._filestack.pop()) def _next_ref2node(self): # Checks that the next token is a label/path reference and returns the @@ -2025,7 +2020,7 @@ def to_num(data: bytes, length: Optional[int] = None, return int.from_bytes(data, "big", signed=signed) -def to_nums(data: bytes, length: int = 4, signed: bool = False) -> List[int]: +def to_nums(data: bytes, length: int = 4, signed: bool = False) -> list[int]: """ Like Property.to_nums(), but takes an arbitrary 'bytes' array. The values are assumed to be in big-endian format, which is standard in devicetree. @@ -2067,10 +2062,10 @@ def _decode_and_escape(b): # 'backslashreplace' bytes.translate() can't map to more than a single # byte, but str.translate() can map to more than one character, so it's # nice here. There's probably a nicer way to do this. - return b.decode("utf-8", "surrogateescape") \ - .translate(_escape_table) \ - .encode("utf-8", "surrogateescape") \ - .decode("utf-8", "backslashreplace") + return (b.decode("utf-8", "surrogateescape") + .translate(_escape_table) + .encode("utf-8", "surrogateescape") + .decode("utf-8", "backslashreplace")) def _root_and_path_to_node(cur, path, fullpath): # Returns the node pointed at by 'path', relative to the Node 'cur'. For diff --git a/scripts/dts/python-devicetree/src/devicetree/edtlib.py b/scripts/dts/python-devicetree/src/devicetree/edtlib.py index 30c936b373360..0238c239065aa 100644 --- a/scripts/dts/python-devicetree/src/devicetree/edtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/edtlib.py @@ -70,8 +70,10 @@ from collections import defaultdict from copy import deepcopy from dataclasses import dataclass -from typing import Any, Callable, Dict, Iterable, List, NoReturn, \ - Optional, Set, TYPE_CHECKING, Tuple, Union +from typing import (Any, Callable, Iterable, NoReturn, + Optional, TYPE_CHECKING, Union) +import base64 +import hashlib import logging import os import re @@ -90,6 +92,12 @@ from devicetree.grutils import Graph from devicetree._private import _slice_helper +def _compute_hash(path: str) -> str: + # Calculates the hash associated with the node's full path. + hasher = hashlib.sha256() + hasher.update(path.encode()) + return base64.b64encode(hasher.digest(), altchars=b'__').decode().rstrip('=') + # # Public classes # @@ -161,7 +169,7 @@ class Binding: are multiple levels of 'child-binding' descriptions in the binding. """ - def __init__(self, path: Optional[str], fname2path: Dict[str, str], + def __init__(self, path: Optional[str], fname2path: dict[str, str], raw: Any = None, require_compatible: bool = True, require_description: bool = True): """ @@ -193,7 +201,7 @@ def __init__(self, path: Optional[str], fname2path: Dict[str, str], if it is present in the binding. """ self.path: Optional[str] = path - self._fname2path: Dict[str, str] = fname2path + self._fname2path: dict[str, str] = fname2path if raw is None: if path is None: @@ -225,10 +233,10 @@ def __init__(self, path: Optional[str], fname2path: Dict[str, str], self._check(require_compatible, require_description) # Initialize look up tables. - self.prop2specs: Dict[str, 'PropertySpec'] = {} + self.prop2specs: dict[str, 'PropertySpec'] = {} for prop_name in self.raw.get("properties", {}).keys(): self.prop2specs[prop_name] = PropertySpec(prop_name, self) - self.specifier2cells: Dict[str, List[str]] = {} + self.specifier2cells: dict[str, list[str]] = {} for key, val in self.raw.items(): if key.endswith("-cells"): self.specifier2cells[key[:-len("-cells")]] = val @@ -252,12 +260,12 @@ def compatible(self) -> Optional[str]: return self.raw.get('compatible') @property - def bus(self) -> Union[None, str, List[str]]: + def bus(self) -> Union[None, str, list[str]]: "See the class docstring" return self.raw.get('bus') @property - def buses(self) -> List[str]: + def buses(self) -> list[str]: "See the class docstring" if self.raw.get('bus') is not None: return self._buses @@ -287,7 +295,7 @@ def _merge_includes(self, raw: dict, binding_path: Optional[str]) -> dict: # file has a 'required:' for a particular property, OR the values # together, so that 'required: true' wins. - merged: Dict[str, Any] = {} + merged: dict[str, Any] = {} if isinstance(include, str): # Simple scalar string case @@ -401,9 +409,9 @@ def _check(self, require_compatible: bool, require_description: bool): if "bus" in raw: bus = raw["bus"] - if not isinstance(bus, str) and \ - (not isinstance(bus, list) and \ - not all(isinstance(elem, str) for elem in bus)): + if (not isinstance(bus, str) and + (not isinstance(bus, list) and + not all(isinstance(elem, str) for elem in bus))): _err(f"malformed 'bus:' value in {self.path}, " "expected string or list of strings") @@ -413,8 +421,8 @@ def _check(self, require_compatible: bool, require_description: bool): # Convert bus into a list self._buses = [bus] - if "on-bus" in raw and \ - not isinstance(raw["on-bus"], str): + if ("on-bus" in raw + and not isinstance(raw["on-bus"], str)): _err(f"malformed 'on-bus:' value in {self.path}, " "expected string") @@ -422,8 +430,8 @@ def _check(self, require_compatible: bool, require_description: bool): for key, val in raw.items(): if key.endswith("-cells"): - if not isinstance(val, list) or \ - not all(isinstance(elem, str) for elem in val): + if (not isinstance(val, list) + or not all(isinstance(elem, str) for elem in val)): _err(f"malformed '{key}:' in {self.path}, " "expected a list of strings") @@ -460,8 +468,8 @@ def _check_properties(self) -> None: _err(f"'{prop_name}' in 'properties' in {self.path} should not " "have both 'deprecated' and 'required' set") - if "description" in options and \ - not isinstance(options["description"], str): + if ("description" in options + and not isinstance(options["description"], str)): _err("missing, malformed, or empty 'description' for " f"'{prop_name}' in 'properties' in {self.path}") @@ -485,7 +493,9 @@ class PropertySpec: path: The file where this property was defined. In case a binding includes - other bindings, this is the file where the property was last modified. + other bindings, this is the including binding file. + Generally this means that this will be the binding file specifying + the devicetree node of which this is a property. type: The type of the property as a string, as given in the binding. @@ -530,7 +540,7 @@ class PropertySpec: def __init__(self, name: str, binding: Binding): self.binding: Binding = binding self.name: str = name - self._raw: Dict[str, Any] = self.binding.raw["properties"][name] + self._raw: dict[str, Any] = self.binding.raw["properties"][name] def __repr__(self) -> str: return f"" @@ -579,18 +589,19 @@ def enum_upper_tokenizable(self) -> bool: if not self.enum_tokenizable: self._enum_upper_tokenizable = False else: - self._enum_upper_tokenizable = \ - (len(self._as_tokens) == - len(set(x.upper() for x in self._as_tokens))) + self._enum_upper_tokenizable = ( + len(self._as_tokens) == len( + set(x.upper() for x in self._as_tokens) + )) return self._enum_upper_tokenizable @property - def const(self) -> Union[None, int, List[int], str, List[str]]: + def const(self) -> Union[None, int, list[int], str, list[str]]: "See the class docstring" return self._raw.get("const") @property - def default(self) -> Union[None, int, List[int], str, List[str]]: + def default(self) -> Union[None, int, list[int], str, list[str]]: "See the class docstring" return self._raw.get("default") @@ -610,9 +621,9 @@ def specifier_space(self) -> Optional[str]: return self._raw.get("specifier-space") PropertyValType = Union[int, str, - List[int], List[str], - 'Node', List['Node'], - List[Optional['ControllerAndData']], + list[int], list[str], + 'Node', list['Node'], + list[Optional['ControllerAndData']], bytes, None] @@ -696,7 +707,7 @@ def type(self) -> str: return self.spec.type @property - def val_as_tokens(self) -> List[str]: + def val_as_tokens(self) -> list[str]: "See the class docstring" ret = [] for subval in self.val if isinstance(self.val, list) else [self.val]: @@ -705,7 +716,7 @@ def val_as_tokens(self) -> List[str]: return ret @property - def enum_indices(self) -> Optional[List[int]]: + def enum_indices(self) -> Optional[list[int]]: "See the class docstring" enum = self.spec.enum val = self.val if isinstance(self.val, list) else [self.val] @@ -847,7 +858,7 @@ class PinCtrl: node: 'Node' name: Optional[str] - conf_nodes: List['Node'] + conf_nodes: list['Node'] @property def name_as_token(self): @@ -911,6 +922,11 @@ class Node: The ordinal is defined for all Nodes, and is unique among nodes in its EDT 'nodes' list. + hash: + A hashed value of the devicetree path of the node. This is defined for + all Nodes, and is checked for uniqueness among nodes in its EDT 'nodes' + list. + required_by: A list with the nodes that directly depend on the node @@ -946,8 +962,9 @@ class Node: props: A dict that maps property names to Property objects. - Property objects are created for all devicetree properties on the node - that are mentioned in 'properties:' in the binding. + Property objects are created for the devicetree properties + defined by the node's binding and that have a default value + or for which a value is set in the DTS. aliases: A list of aliases for the node. This is fetched from the /aliases node. @@ -1019,13 +1036,14 @@ def __init__( # Public, some of which are initialized properly later: self.edt: 'EDT' = edt self.dep_ordinal: int = -1 - self.compats: List[str] = compats - self.ranges: List[Range] = [] - self.regs: List[Register] = [] - self.props: Dict[str, Property] = {} - self.interrupts: List[ControllerAndData] = [] - self.pinctrls: List[PinCtrl] = [] + self.compats: list[str] = compats + self.ranges: list[Range] = [] + self.regs: list[Register] = [] + self.props: dict[str, Property] = {} + self.interrupts: list[ControllerAndData] = [] + self.pinctrls: list[PinCtrl] = [] self.bus_node = self._bus_node(support_fixed_partitions_on_any_bus) + self.hash: str = _compute_hash(dt_node.path) self._init_binding() self._init_regs() @@ -1073,7 +1091,7 @@ def label(self) -> Optional[str]: return None @property - def labels(self) -> List[str]: + def labels(self) -> list[str]: "See the class docstring" return self._node.labels @@ -1083,7 +1101,7 @@ def parent(self) -> Optional['Node']: return self.edt._node2enode.get(self._node.parent) # type: ignore @property - def children(self) -> Dict[str, 'Node']: + def children(self) -> dict[str, 'Node']: "See the class docstring" # Could be initialized statically too to preserve identity, but not # sure if needed. Parent nodes being initialized before their children @@ -1100,7 +1118,7 @@ def child_index(self, node) -> int: # method is callable to handle parents needing to be # initialized before their chidlren. By the time we # return from __init__, 'self.children' is callable. - self._child2index: Dict[str, int] = {} + self._child2index: dict[str, int] = {} for index, child_path in enumerate(child.path for child in self.children.values()): self._child2index[child_path] = index @@ -1108,12 +1126,12 @@ def child_index(self, node) -> int: return self._child2index[node.path] @property - def required_by(self) -> List['Node']: + def required_by(self) -> list['Node']: "See the class docstring" return self.edt._graph.required_by(self) @property - def depends_on(self) -> List['Node']: + def depends_on(self) -> list['Node']: "See the class docstring" return self.edt._graph.depends_on(self) @@ -1152,20 +1170,20 @@ def binding_path(self) -> Optional[str]: return None @property - def aliases(self) -> List[str]: + def aliases(self) -> list[str]: "See the class docstring" return [alias for alias, node in self._node.dt.alias2node.items() if node is self._node] @property - def buses(self) -> List[str]: + def buses(self) -> list[str]: "See the class docstring" if self._binding: return self._binding.buses return [] @property - def on_buses(self) -> List[str]: + def on_buses(self) -> list[str]: "See the class docstring" bus_node = self.bus_node return bus_node.buses if bus_node else [] @@ -1224,7 +1242,7 @@ def spi_cs_gpio(self) -> Optional[ControllerAndData]: return ret @property - def gpio_hogs(self) -> List[ControllerAndData]: + def gpio_hogs(self) -> list[ControllerAndData]: "See the class docstring" if "gpio-hog" not in self.props: @@ -1326,12 +1344,12 @@ def _binding_from_properties(self) -> None: _err(f"compatible in node with inferred binding: {self.path}") # Synthesize a 'raw' binding as if it had been parsed from YAML. - raw: Dict[str, Any] = { + raw: dict[str, Any] = { 'description': 'Inferred binding from properties, via edtlib.', 'properties': {}, } for name, prop in self._node.props.items(): - pp: Dict[str, str] = {} + pp: dict[str, str] = {} if prop.type == Type.EMPTY: pp["type"] = "boolean" elif prop.type == Type.BYTES: @@ -1532,11 +1550,9 @@ def _prop_val( if prop_type == "boolean": if prop.type != Type.EMPTY: - _err( - "'{0}' in {1!r} is defined with 'type: boolean' in {2}, " - "but is assigned a value ('{3}') instead of being empty " - "('{0};')".format(name, node, binding_path, prop) - ) + _err(f"'{name}' in {node!r} is defined with 'type: boolean' " + f"in {binding_path}, but is assigned a value ('{prop}') " + f"instead of being empty ('{name};')") return True if prop_type == "int": @@ -1585,14 +1601,14 @@ def _prop_val( def _check_undeclared_props(self) -> None: # Checks that all properties are declared in the binding + wl = {"compatible", "status", "ranges", "phandle", + "interrupt-parent", "interrupts-extended", "device_type"} for prop_name in self._node.props: # Allow a few special properties to not be declared in the binding - if prop_name.endswith("-controller") or \ - prop_name.startswith("#") or \ - prop_name in { - "compatible", "status", "ranges", "phandle", - "interrupt-parent", "interrupts-extended", "device_type"}: + if (prop_name.endswith("-controller") + or prop_name.startswith("#") + or prop_name in wl): continue if TYPE_CHECKING: @@ -1749,7 +1765,7 @@ def _standard_phandle_val_list( self, prop: dtlib_Property, specifier_space: Optional[str] - ) -> List[Optional[ControllerAndData]]: + ) -> list[Optional[ControllerAndData]]: # Parses a property like # # = ; @@ -1799,7 +1815,7 @@ def _standard_phandle_val_list( # if there is no specifier space in _check_prop_by_type(). specifier_space = prop.name[:-1] - res: List[Optional[ControllerAndData]] = [] + res: list[Optional[ControllerAndData]] = [] for item in _phandle_val_list(prop, specifier_space): if item is None: @@ -1807,9 +1823,9 @@ def _standard_phandle_val_list( continue controller_node, data = item - mapped_controller, mapped_data = \ - _map_phandle_array_entry(prop.node, controller_node, data, - specifier_space) + mapped_controller, mapped_data = ( + _map_phandle_array_entry(prop.node, controller_node, + data, specifier_space)) controller = self.edt._node2enode[mapped_controller] # We'll fix up the names below. @@ -1828,7 +1844,7 @@ def _named_cells( controller: 'Node', data: bytes, basename: str - ) -> Dict[str, int]: + ) -> dict[str, int]: # Returns a dictionary that maps -cells names given in the # binding for 'controller' to cell values. 'data' is the raw data, as a # byte array. @@ -1838,7 +1854,7 @@ def _named_cells( f"for {self._node!r} lacks binding") if basename in controller._binding.specifier2cells: - cell_names: List[str] = controller._binding.specifier2cells[basename] + cell_names: list[str] = controller._binding.specifier2cells[basename] else: # Treat no *-cells in the binding the same as an empty *-cells, so # that bindings don't have to have e.g. an empty 'clock-cells:' for @@ -1922,12 +1938,12 @@ class EDT: def __init__(self, dts: Optional[str], - bindings_dirs: List[str], + bindings_dirs: list[str], warn_reg_unit_address_mismatch: bool = True, default_prop_types: bool = True, support_fixed_partitions_on_any_bus: bool = True, infer_binding_for_paths: Optional[Iterable[str]] = None, - vendor_prefixes: Optional[Dict[str, str]] = None, + vendor_prefixes: Optional[dict[str, str]] = None, werror: bool = False): """EDT constructor. @@ -1976,34 +1992,34 @@ def __init__(self, # and update the tests for that method. # Public attributes (the rest are properties) - self.nodes: List[Node] = [] - self.compat2nodes: Dict[str, List[Node]] = defaultdict(list) - self.compat2okay: Dict[str, List[Node]] = defaultdict(list) - self.compat2notokay: Dict[str, List[Node]] = defaultdict(list) - self.compat2vendor: Dict[str, str] = defaultdict(str) - self.compat2model: Dict[str, str] = defaultdict(str) - self.label2node: Dict[str, Node] = {} - self.dep_ord2node: Dict[int, Node] = {} + self.nodes: list[Node] = [] + self.compat2nodes: dict[str, list[Node]] = defaultdict(list) + self.compat2okay: dict[str, list[Node]] = defaultdict(list) + self.compat2notokay: dict[str, list[Node]] = defaultdict(list) + self.compat2vendor: dict[str, str] = defaultdict(str) + self.compat2model: dict[str, str] = defaultdict(str) + self.label2node: dict[str, Node] = {} + self.dep_ord2node: dict[int, Node] = {} self.dts_path: str = dts # type: ignore - self.bindings_dirs: List[str] = list(bindings_dirs) + self.bindings_dirs: list[str] = list(bindings_dirs) # Saved kwarg values for internal use self._warn_reg_unit_address_mismatch: bool = warn_reg_unit_address_mismatch self._default_prop_types: bool = default_prop_types self._fixed_partitions_no_bus: bool = support_fixed_partitions_on_any_bus - self._infer_binding_for_paths: Set[str] = set(infer_binding_for_paths or []) - self._vendor_prefixes: Dict[str, str] = vendor_prefixes or {} + self._infer_binding_for_paths: set[str] = set(infer_binding_for_paths or []) + self._vendor_prefixes: dict[str, str] = vendor_prefixes or {} self._werror: bool = bool(werror) # Other internal state - self._compat2binding: Dict[Tuple[str, Optional[str]], Binding] = {} + self._compat2binding: dict[tuple[str, Optional[str]], Binding] = {} self._graph: Graph = Graph() - self._binding_paths: List[str] = _binding_paths(self.bindings_dirs) - self._binding_fname2path: Dict[str, str] = { + self._binding_paths: list[str] = _binding_paths(self.bindings_dirs) + self._binding_fname2path: dict[str, str] = { os.path.basename(path): path for path in self._binding_paths } - self._node2enode: Dict[dtlib_Node, Node] = {} + self._node2enode: dict[dtlib_Node, Node] = {} if dts is not None: try: @@ -2035,8 +2051,8 @@ def get_node(self, path: str) -> Node: _err(e) @property - def chosen_nodes(self) -> Dict[str, Node]: - ret: Dict[str, Node] = {} + def chosen_nodes(self) -> dict[str, Node]: + ret: dict[str, Node] = {} try: chosen = self._dt.get_node("/chosen") @@ -2066,8 +2082,8 @@ def dts_source(self) -> str: return f"{self._dt}" def __repr__(self) -> str: - return f"" + return (f"") def __deepcopy__(self, memo) -> 'EDT': """ @@ -2091,7 +2107,7 @@ def __deepcopy__(self, memo) -> 'EDT': return ret @property - def scc_order(self) -> List[List[Node]]: + def scc_order(self) -> list[list[Node]]: try: return self._graph.scc_order() except Exception as e: @@ -2226,7 +2242,7 @@ def _init_compat2binding(self) -> None: def _binding(self, raw: Optional[dict], binding_path: str, - dt_compats: Set[str]) -> Optional[Binding]: + dt_compats: set[str]) -> Optional[Binding]: # Convert a 'raw' binding from YAML to a Binding object and return it. # # Error out if the raw data looks like an invalid binding. @@ -2269,10 +2285,18 @@ def _init_nodes(self) -> None: # Creates a list of edtlib.Node objects from the dtlib.Node objects, in # self.nodes + hash2node: dict[str, Node] = {} + for dt_node in self._dt.node_iter(): # Warning: We depend on parent Nodes being created before their # children. This is guaranteed by node_iter(). node = Node(dt_node, self, self._fixed_partitions_no_bus) + + if node.hash in hash2node: + _err(f"hash collision between '{node.path}' and " + f"'{hash2node[node.hash].path}'") + hash2node[node.hash] = node + self.nodes.append(node) self._node2enode[dt_node] = node @@ -2386,8 +2410,8 @@ def _check(self) -> None: assert isinstance(compat, str) -def bindings_from_paths(yaml_paths: List[str], - ignore_errors: bool = False) -> List[Binding]: +def bindings_from_paths(yaml_paths: list[str], + ignore_errors: bool = False) -> list[Binding]: """ Get a list of Binding objects from the yaml files 'yaml_paths'. @@ -2416,11 +2440,11 @@ class EDTError(Exception): # -def load_vendor_prefixes_txt(vendor_prefixes: str) -> Dict[str, str]: +def load_vendor_prefixes_txt(vendor_prefixes: str) -> dict[str, str]: """Load a vendor-prefixes.txt file and return a dict representation mapping a vendor prefix to the vendor name. """ - vnd2vendor: Dict[str, str] = {} + vnd2vendor: dict[str, str] = {} with open(vendor_prefixes, 'r', encoding='utf-8') as f: for line in f: line = line.strip() @@ -2442,7 +2466,7 @@ def load_vendor_prefixes_txt(vendor_prefixes: str) -> Dict[str, str]: # -def _dt_compats(dt: DT) -> Set[str]: +def _dt_compats(dt: DT) -> set[str]: # Returns a set() with all 'compatible' strings in the devicetree # represented by dt (a dtlib.DT instance) @@ -2452,7 +2476,7 @@ def _dt_compats(dt: DT) -> Set[str]: for compat in node.props["compatible"].to_strings()} -def _binding_paths(bindings_dirs: List[str]) -> List[str]: +def _binding_paths(bindings_dirs: list[str]) -> list[str]: # Returns a list with the paths to all bindings (.yaml files) in # 'bindings_dirs' @@ -2474,8 +2498,8 @@ def _binding_inc_error(msg): def _check_include_dict(name: Optional[str], - allowlist: Optional[List[str]], - blocklist: Optional[List[str]], + allowlist: Optional[list[str]], + blocklist: Optional[list[str]], child_filter: Optional[dict], binding_path: Optional[str]) -> None: # Check that an 'include:' named 'name' with property-allowlist @@ -2493,12 +2517,12 @@ def _check_include_dict(name: Optional[str], while child_filter is not None: child_copy = deepcopy(child_filter) - child_allowlist: Optional[List[str]] = \ - child_copy.pop('property-allowlist', None) - child_blocklist: Optional[List[str]] = \ - child_copy.pop('property-blocklist', None) - next_child_filter: Optional[dict] = \ - child_copy.pop('child-binding', None) + child_allowlist: Optional[list[str]] = ( + child_copy.pop('property-allowlist', None)) + child_blocklist: Optional[list[str]] = ( + child_copy.pop('property-blocklist', None)) + next_child_filter: Optional[dict] = ( + child_copy.pop('child-binding', None)) if child_copy: # We've popped out all the valid keys. @@ -2515,8 +2539,8 @@ def _check_include_dict(name: Optional[str], def _filter_properties(raw: dict, - allowlist: Optional[List[str]], - blocklist: Optional[List[str]], + allowlist: Optional[list[str]], + blocklist: Optional[list[str]], child_filter: Optional[dict], binding_path: Optional[str]) -> None: # Destructively modifies 'raw["properties"]' and @@ -2537,8 +2561,8 @@ def _filter_properties(raw: dict, def _filter_properties_helper(props: Optional[dict], - allowlist: Optional[List[str]], - blocklist: Optional[List[str]], + allowlist: Optional[list[str]], + blocklist: Optional[list[str]], binding_path: Optional[str]) -> None: if props is None or (allowlist is None and blocklist is None): return @@ -2559,7 +2583,7 @@ def _filter_properties_helper(props: Optional[dict], del props[prop] -def _check_prop_filter(name: str, value: Optional[List[str]], +def _check_prop_filter(name: str, value: Optional[list[str]], binding_path: Optional[str]) -> None: # Ensure an include: ... property-allowlist or property-blocklist # is a list. @@ -2595,8 +2619,8 @@ def _merge_props(to_dict: dict, # These are used to generate errors for sketchy property overwrites. for prop in from_dict: - if isinstance(to_dict.get(prop), dict) and \ - isinstance(from_dict[prop], dict): + if (isinstance(to_dict.get(prop), dict) + and isinstance(from_dict[prop], dict)): _merge_props(to_dict[prop], from_dict[prop], prop, binding_path, check_required) elif prop not in to_dict: @@ -2709,8 +2733,8 @@ def ok_default() -> bool: # If you change this, be sure to update the type annotation for # PropertySpec.default. - if prop_type == "int" and isinstance(default, int) or \ - prop_type == "string" and isinstance(default, str): + if (prop_type == "int" and isinstance(default, int) + or prop_type == "string" and isinstance(default, str)): return True # array, uint8-array, or string-array @@ -2718,12 +2742,13 @@ def ok_default() -> bool: if not isinstance(default, list): return False - if prop_type == "array" and \ - all(isinstance(val, int) for val in default): + if (prop_type == "array" + and all(isinstance(val, int) for val in default)): return True - if prop_type == "uint8-array" and \ - all(isinstance(val, int) and 0 <= val <= 255 for val in default): + if (prop_type == "uint8-array" + and all(isinstance(val, int) + and 0 <= val <= 255 for val in default)): return True # string-array @@ -2830,7 +2855,7 @@ def _interrupt_parent(start_node: dtlib_Node) -> dtlib_Node: f"nor any of its parents has an 'interrupt-parent' property") -def _interrupts(node: dtlib_Node) -> List[Tuple[dtlib_Node, bytes]]: +def _interrupts(node: dtlib_Node) -> list[tuple[dtlib_Node, bytes]]: # Returns a list of (, ) tuples, with one tuple per # interrupt generated by 'node'. is the destination of the # interrupt (possibly after mapping through an 'interrupt-map'), and @@ -2840,7 +2865,7 @@ def _interrupts(node: dtlib_Node) -> List[Tuple[dtlib_Node, bytes]]: if "interrupts-extended" in node.props: prop = node.props["interrupts-extended"] - ret: List[Tuple[dtlib_Node, bytes]] = [] + ret: list[tuple[dtlib_Node, bytes]] = [] for entry in _phandle_val_list(prop, "interrupt"): if entry is None: _err(f"node '{node.path}' interrupts-extended property " @@ -2867,7 +2892,7 @@ def _map_interrupt( child: dtlib_Node, parent: dtlib_Node, child_spec: bytes -) -> Tuple[dtlib_Node, bytes]: +) -> tuple[dtlib_Node, bytes]: # Translates an interrupt headed from 'child' to 'parent' with data # 'child_spec' through any 'interrupt-map' properties. Returns a # (, ) tuple with the final destination after mapping. @@ -2904,7 +2929,7 @@ def _map_phandle_array_entry( parent: dtlib_Node, child_spec: bytes, basename: str -) -> Tuple[dtlib_Node, bytes]: +) -> tuple[dtlib_Node, bytes]: # Returns a (, ) tuple with the final destination after # mapping through any '-map' (e.g. gpio-map) properties. See # _map_interrupt(). @@ -2928,7 +2953,7 @@ def _map( child_spec: bytes, spec_len_fn: Callable[[dtlib_Node], int], require_controller: bool -) -> Tuple[dtlib_Node, bytes]: +) -> tuple[dtlib_Node, bytes]: # Common code for mapping through -map properties, e.g. # interrupt-map and gpio-map. # @@ -3103,7 +3128,7 @@ def _not(b: bytes) -> bytes: def _phandle_val_list( prop: dtlib_Property, n_cells_name: str -) -> List[Optional[Tuple[dtlib_Node, bytes]]]: +) -> list[Optional[tuple[dtlib_Node, bytes]]]: # Parses a ' ...' value. The number of # cells that make up each is derived from the node pointed at by # the preceding . @@ -3121,7 +3146,7 @@ def _phandle_val_list( full_n_cells_name = f"#{n_cells_name}-cells" - res: List[Optional[Tuple[dtlib_Node, bytes]]] = [] + res: list[Optional[tuple[dtlib_Node, bytes]]] = [] raw = prop.value while raw: @@ -3185,7 +3210,7 @@ def _interrupt_cells(node: dtlib_Node) -> int: def _slice(node: dtlib_Node, prop_name: str, size: int, - size_hint: str) -> List[bytes]: + size_hint: str) -> list[bytes]: return _slice_helper(node, prop_name, size, size_hint, EDTError) @@ -3257,7 +3282,7 @@ class _BindingLoader(Loader): # include/devicetree.h. # -_DEFAULT_PROP_TYPES: Dict[str, str] = { +_DEFAULT_PROP_TYPES: dict[str, str] = { "compatible": "string-array", "status": "string", "ranges": "compound", # NUMS or EMPTY @@ -3270,12 +3295,12 @@ class _BindingLoader(Loader): "interrupt-controller": "boolean", } -_STATUS_ENUM: List[str] = "ok okay disabled reserved fail fail-sss".split() +_STATUS_ENUM: list[str] = "ok okay disabled reserved fail fail-sss".split() def _raw_default_property_for( name: str -) -> Dict[str, Union[str, bool, List[str]]]: - ret: Dict[str, Union[str, bool, List[str]]] = { +) -> dict[str, Union[str, bool, list[str]]]: + ret: dict[str, Union[str, bool, list[str]]] = { 'type': _DEFAULT_PROP_TYPES[name], 'required': False, } @@ -3294,7 +3319,7 @@ def _raw_default_property_for( require_compatible=False, require_description=False, ) -_DEFAULT_PROP_SPECS: Dict[str, PropertySpec] = { +_DEFAULT_PROP_SPECS: dict[str, PropertySpec] = { name: PropertySpec(name, _DEFAULT_PROP_BINDING) for name in _DEFAULT_PROP_TYPES } diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/base.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/base.yaml new file mode 100644 index 0000000000000..7535b28b54459 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/base.yaml @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Base include file for testing bindings initialization. +# +# Involves base property definitions ("type:", "description:", "const:", +# "required:", "enum:" and "default:") up to the grandchild-binding level. +# +# Binding: +# + prop-1 +# + prop-2 +# + prop-enum +# + prop-req +# + prop-const +# + prop-default +# +# Child-binding: +# + child-prop-1 +# + child-prop-2 +# + child-prop-enum +# + child-prop-req +# + child-prop-const +# + child-prop-default +# +# Grandchild-binding: +# + grandchild-prop-1 +# + grandchild-prop-2 +# + grandchild-prop-enum +# + grandchild-prop-req +# + grandchild-prop-const +# + grandchild-prop-default + +description: Base property specifications. + +properties: + prop-1: + description: Base property 1. + type: int + prop-2: + type: string + prop-enum: + type: string + required: false + enum: + - FOO + - BAR + prop-const: + type: int + const: 8 + prop-req: + type: int + required: true + prop-default: + type: int + default: 1 + +child-binding: + description: Base child-binding description. + + properties: + child-prop-1: + description: Base child-prop 1. + type: int + child-prop-2: + type: string + child-prop-enum: + type: string + required: false + enum: + - CHILD_FOO + - CHILD_BAR + child-prop-const: + type: int + const: 16 + child-prop-req: + type: int + required: true + child-prop-default: + type: int + default: 2 + + child-binding: + description: Base grandchild-binding description. + + properties: + grandchild-prop-1: + description: Base grandchild-prop 1. + type: int + grandchild-prop-2: + type: string + grandchild-prop-enum: + type: string + required: false + enum: + - GRANDCHILD_FOO + - GRANDCHILD_BAR + grandchild-prop-const: + type: int + const: 32 + grandchild-prop-req: + type: int + required: true + grandchild-prop-default: + type: int + default: 3 diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/base_amend.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/base_amend.yaml new file mode 100644 index 0000000000000..bd24de099c83d --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/base_amend.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Amends base properties specifications: +# - extends property specifications by adding definitions, +# e.g. setting a "default:" value +# - overwrites existing definitions of a property, +# e.g. change its "description:" +# - specify new properties +# +# The same kind of amendments are applied to the same properties +# at each level (binding, child-binding, grandchild-binding). +# +# | Definition | Extended for | Overwritten for | +# |----------------|--------------|-----------------| +# | description: | prop-2 | prop-1 | +# | required: | | prop-enum | +# | enum: | prop-2 | | +# | const: | prop-1 | | +# | default: | prop-2 | | +# +# Non authorized amendments, e.g. changing a "const:" value +# or downgrading a "required: true" definition are tested separately. + +description: Amended description. + +include: base.yaml + +properties: + prop-1: + # The including binding is permitted to overwrite a property description. + description: Overwritten description. + # The including binding is permitted to set a "const:" value. + const: 0xf0 + + prop-2: + # The including binding is permitted to add a property description. + description: New description. + # The including binding is permitted to limit property values + # to an enumeration. + enum: + - EXT_FOO + - EXT_BAR + # The including binding is permitted to set a default value. + default: EXT_FOO + + # The including binding is permitted to promote a property + # to requirement. + prop-enum: + required: true + + # The including binding is permitted to define a new property. + prop-new: + type: int + +# Same amendments at the child-binding level. +child-binding: + properties: + child-prop-1: + description: Overwritten description (child). + const: 0xf1 + + child-prop-2: + description: New description (child). + enum: + - CHILD_EXT_FOO + - CHILD_EXT_BAR + default: CHILD_EXT_FOO + + child-prop-enum: + required: true + + child-prop-new: + type: int + + # Same amendments at the grandchild-binding level. + child-binding: + # Plus amended grandchild-binding description. + description: Amended grandchild-binding description. + + properties: + grandchild-prop-1: + description: Overwritten description (grandchild). + const: 0xf2 + + grandchild-prop-2: + description: New description (grandchild). + enum: + - GRANDCHILD_EXT_FOO + - GRANDCHILD_EXT_BAR + default: GRANDCHILD_EXT_FOO + + grandchild-prop-enum: + required: true + + grandchild-prop-new: + type: int diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/base_inherit.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/base_inherit.yaml new file mode 100644 index 0000000000000..eec7711c7a413 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/base_inherit.yaml @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Inherit base specifications without modification. + +include: base.yaml diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/base_multi.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/base_multi.yaml new file mode 100644 index 0000000000000..c713f1b8d3a66 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/base_multi.yaml @@ -0,0 +1,103 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Includes base bindings at multiple levels (binding, +# child-binding, grandchild-binding): +# +# include: base.yaml +# child-binding: +# include: base.yaml +# child-binding: +# include: base.yaml +# +# Which properties are specified at which levels is summarized bellow +# for convenience. +# +# Child-binding level: +# From top-level "include:" element. +# - child-prop-1 (amended) +# - child-prop-2 +# - child-prop-enum +# From "child-binding: include:" element. +# - prop-1 (amended) +# - prop-2 (amended) +# - prop-enum (amended) +# +# Grandchild-binding level: +# From top-level "include:" element. +# - grandchild-prop-1 (amended) +# - grandchild-prop-2 +# - grandchild-prop-enum +# From "child-binding: include:" element. +# - child-prop-1 (amended) +# - child-prop-2 +# - child-prop-enum +# From "child-binding: child-binding: include:" element. +# - prop-1 (amended) +# - prop-2 (amended) +# - prop-enum (amended) +# +# Grand-grandchild-binding level: +# From "child-binding: include:" element. +# - child-prop-1 +# - child-prop-2 +# - child-prop-enum +# From "child-binding: child-binding: include:" element. +# - grandchild-prop-1 +# - grandchild-prop-2 +# - grandchild-prop-enum + +description: Description of 'base_multi.yaml'. + +include: + - name: base.yaml + child-binding: + property-allowlist: [child-prop-1, child-prop-2, child-prop-enum] + child-binding: + property-allowlist: [grandchild-prop-1, grandchild-prop-2, grandchild-prop-enum] + +child-binding: + include: + - name: base.yaml + property-allowlist: [prop-1, prop-2, prop-enum] + child-binding: + property-allowlist: [child-prop-1, child-prop-2, child-prop-enum] + child-binding: + property-allowlist: [grandchild-prop-1, grandchild-prop-2, grandchild-prop-enum] + + properties: + # Amend top-level "include:" element. + child-prop-1: + const: 0xf1 + # Amend this "child-binding: include:" element. + prop-1: + const: 0xf1 + prop-2: + description: New description (child). + prop-enum: + required: true + default: FOO + + child-binding: + include: + - name: base.yaml + property-allowlist: [prop-1, prop-2, prop-enum] + child-binding: + property-allowlist: [child-prop-1, child-prop-2, child-prop-enum] + child-binding: + property-allowlist: [grandchild-prop-1, grandchild-prop-2, grandchild-prop-enum] + + properties: + # Amend above top-level "include:" element. + grandchild-prop-1: + const: 0xf2 + # Amend above "child-binding: include:" element. + child-prop-1: + const: 0xf2 + # Amend this "child-binding: child-binding: include:" element. + prop-1: + const: 0xf2 + prop-2: + description: New description (grandchild). + prop-enum: + required: true + default: FOO diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc.yaml new file mode 100644 index 0000000000000..1bd5bce1c81e4 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc.yaml @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Test inheritance rules applied to compatible strings +# and bindings descriptions. + +description: Binding description. + +compatible: vnd,compat-desc + +include: compat_desc_base.yaml + +child-binding: + description: Child-binding description. + compatible: vnd,child-compat-desc + + child-binding: + description: Grandchild-binding description. + compatible: vnd,grandchild-compat-desc diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc_base.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc_base.yaml new file mode 100644 index 0000000000000..263b5adcbb9c3 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc_base.yaml @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Base file for testing inheritance rules applied to +# compatible strings and bindings descriptions. + +description: Binding description (base). + +compatible: vnd,compat-desc-base + +child-binding: + description: Child-binding description (base). + compatible: vnd,child-compat-desc-base + + child-binding: + description: Grandchild-binding description (base). + compatible: vnd,grandchild-compat-desc-base diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc_multi.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc_multi.yaml new file mode 100644 index 0000000000000..c729875d02bc9 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/compat_desc_multi.yaml @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Test consequences of inclusion order on inherited +# compatible strings and descriptions. + +description: Binding description (multi). + +compatible: vnd,compat-desc-multi + +# Descriptions at the child-binding level and bellow +# will depend on inclusion order: the first wins. +include: + - compat_desc_base.yaml + - compat_desc.yaml diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/diamond.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/diamond.yaml new file mode 100644 index 0000000000000..0a3865506eaa6 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/diamond.yaml @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Binding file for testing diamond inheritance (top-bottom). +# +# diamond.yaml +# / \ +# / \ +# base_amend.yaml thing.yaml +# \ / +# \ / +# base.yaml +# +# Which properties are specified at which levels is summarized bellow +# for convenience. +# +# * Binding level. +# Diamond's left: +# - prop-1 (amended in base_amend.yaml) +# - prop-enum (amended in base_amend.yaml) +# - prop-default (inherited from base.yaml) +# Diamond's right: +# - prop-1 (last amended in thing.yaml) +# - prop-enum (amended in thing.yaml) +# - prop-thing (inherited from thing.yaml) +# Diamond's top: +# - prop-enum (last amended here) +# - prop-diamond +# +# * Child-binding level: +# Diamond's left: +# - child-prop-1 (amended in base_amend.yaml) +# - child-prop-enum (amended in base_amend.yaml) +# - child-prop-default (inherited from base.yaml) +# Diamond's right: +# - child-prop-1 (last amended in thing.yaml) +# - child-prop-enum (amended in thing.yaml) +# - child-prop-thing (inherited from thing.yaml) +# Diamond's top: +# - child-prop-enum (last amended here) +# - child-prop-diamond +# +# * Grandchild-binding level: +# Diamond's left: +# - grandchild-prop-1 (amended in base_amend.yaml) +# - grandchild-prop-enum (amended in base_amend.yaml) +# - grandchild-prop-default (inherited from base.yaml) +# Diamond's right: +# - grandchild-prop-1 (last amended in thing.yaml) +# - grandchild-prop-enum (amended in thing.yaml) +# - grandchild-prop-thing (inherited from thing.yaml) +# Diamond's top: +# - grandchild-prop-enum (last amended here) +# - grandchild-prop-diamond + +description: Diamond's top. + +compatible: diamond + +include: + # Diamond's left. + - name: base_amend.yaml + property-allowlist: [prop-1, prop-enum, prop-default] + child-binding: + property-allowlist: [child-prop-1, child-prop-enum, child-prop-default] + child-binding: + property-allowlist: [grandchild-prop-1, grandchild-prop-enum, grandchild-prop-default] + # Diamond's right. + - name: thing.yaml + +properties: + prop-diamond: + type: int + prop-enum: + description: Overwritten in diamond.yaml. + default: FOO + +child-binding: + description: Diamond's child-binding. + + properties: + child-prop-diamond: + type: int + child-prop-enum: + description: Overwritten in diamond.yaml (child). + default: CHILD_FOO + + child-binding: + properties: + grandchild-prop-diamond: + type: int + grandchild-prop-enum: + description: Overwritten in diamond.yaml (grandchild). + default: GRANDCHILD_FOO diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/filter_allows_notblocked.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/filter_allows_notblocked.yaml new file mode 100644 index 0000000000000..1af2b2d346364 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/filter_allows_notblocked.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding file allows a property which is not blocked +# in simple_blocklist.yaml: we should end up with this property. + +include: + - name: simple_blocklist.yaml + property-allowlist: [prop-2] + child-binding: + property-allowlist: [child-prop-2] + child-binding: + property-allowlist: [grandchild-prop-2] diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/filter_among_allowed.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/filter_among_allowed.yaml new file mode 100644 index 0000000000000..3faa647926bd9 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/filter_among_allowed.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding file allows only properties that are not allowed +# in simple_allowlist.yaml: we should end up with no property at all. + +include: + - name: simple_allowlist.yaml + property-allowlist: [prop-3] + child-binding: + property-allowlist: [child-prop-3] + child-binding: + property-allowlist: [grandchild-prop-3] diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/filter_among_notblocked.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/filter_among_notblocked.yaml new file mode 100644 index 0000000000000..873f762ed1d5b --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/filter_among_notblocked.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding file blocks all properties not blocked +# in simple_filter.yaml: we should end up with no property at all. + +include: + - name: simple_blocklist.yaml + property-blocklist: [prop-2, prop-3] + child-binding: + property-blocklist: [child-prop-2, child-prop-3] + child-binding: + property-blocklist: [grandchild-prop-2, grandchild-prop-3] diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propconst.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propconst.yaml new file mode 100644 index 0000000000000..20739bad14aab --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propconst.yaml @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "const:" value +# in a property specification inherited from an included file. + +include: base.yaml + +child-binding: + properties: + child-prop-const: + const: 999 diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propdefault.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propdefault.yaml new file mode 100644 index 0000000000000..fd1ec81361259 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propdefault.yaml @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "default:" value +# in a property specification inherited from an included file. + +include: base.yaml + +child-binding: + properties: + child-prop-default: + default: 999 diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propenum.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propenum.yaml new file mode 100644 index 0000000000000..73947b3007e9c --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propenum.yaml @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to change the "enum:" values +# in a property specification inherited from an included file. + +include: base.yaml + +child-binding: + properties: + child-prop-enum: + enum: + - OTHER_FOO + - OTHER_BAR diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propreq.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propreq.yaml new file mode 100644 index 0000000000000..298a3624ffb53 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_propreq.yaml @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override "required: true" +# in a property specification inherited from an included file. + +include: base.yaml + +child-binding: + properties: + child-prop-req: + required: false diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_proptype.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_proptype.yaml new file mode 100644 index 0000000000000..8f80ec81e3855 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_child_proptype.yaml @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "type:" +# of an inherited property. + +include: base.yaml + +child-binding: + properties: + child-prop-1: + type: string diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propconst.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propconst.yaml new file mode 100644 index 0000000000000..5b8a1cb0d5178 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propconst.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "const:" value +# in a property specification inherited from an included file. + +include: base.yaml + +child-binding: + child-binding: + properties: + grandchild-prop-const: + const: 999 diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propdefault.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propdefault.yaml new file mode 100644 index 0000000000000..f2f69d31e4b7e --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propdefault.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "default:" value +# in a property specification inherited from an included file. + +include: base.yaml + +child-binding: + child-binding: + properties: + grandchild-prop-default: + default: 999 diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propenum.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propenum.yaml new file mode 100644 index 0000000000000..637ba811e3dfb --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propenum.yaml @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to change the "enum:" values +# in a property specification inherited from an included file. + +include: base.yaml + +child-binding: + child-binding: + properties: + grandchild-prop-enum: + enum: + - OTHER_FOO + - OTHER_BAR diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propreq.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propreq.yaml new file mode 100644 index 0000000000000..dc9273a7adc5f --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_propreq.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override "required: true" +# in a property specification inherited from an included file. + +include: base.yaml + +child-binding: + child-binding: + properties: + grandchild-prop-req: + required: false diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_proptype.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_proptype.yaml new file mode 100644 index 0000000000000..4135db67f1d15 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_grandchild_proptype.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "type:" +# of an inherited property. + +include: base.yaml + +child-binding: + child-binding: + properties: + grandchild-prop-1: + type: string diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propconst.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propconst.yaml new file mode 100644 index 0000000000000..9eaa11e31d549 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propconst.yaml @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "const:" value +# in a property specification inherited from an included file. +# +# Bindings, child-bindings and grandchild-bindings have +# to be tested separately, see also: +# - invalid_child_propconst.yaml +# - invalid_grandchild_propconst.yaml + +include: base.yaml + +properties: + prop-const: + const: 999 diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propdefault.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propdefault.yaml new file mode 100644 index 0000000000000..8b621a24098f1 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propdefault.yaml @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "default:" value +# in a property specification inherited from an included file. +# +# Bindings, child-bindings and grandchild-bindings have +# to be tested separately, see also: +# - invalid_child_propdefault.yaml +# - invalid_grandchild_propdefault.yaml + +include: base.yaml + +properties: + prop-default: + default: 999 diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propenum.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propenum.yaml new file mode 100644 index 0000000000000..38839826536c7 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propenum.yaml @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to change the "enum:" values +# in a property specification inherited from an included file. +# +# Bindings, child-bindings and grandchild-bindings have +# to be tested separately, see also: +# - invalid_child_propenum.yaml +# - invalid_grandchild_propenum.yaml + +include: base.yaml + +properties: + prop-enum: + enum: + - OTHER_FOO + - OTHER_BAR diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propreq.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propreq.yaml new file mode 100644 index 0000000000000..fd0412c505be0 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_propreq.yaml @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override "required: true" +# in a property specification inherited from an included file. +# +# Bindings, child-bindings and grandchild-bindings have +# to be tested separately, see also: +# - invalid_child_propreq.yaml +# - invalid_grandchild_propreq.yaml + +include: base.yaml + +properties: + prop-req: + required: false diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_proptype.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_proptype.yaml new file mode 100644 index 0000000000000..fca2c752676e3 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/invalid_proptype.yaml @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# This binding should not try to override the "type:" +# of an inherited property. +# +# Bindings, child-bindings and grandchild-bindings have +# to be tested separately, see also: +# - invalid_child_protype.yaml +# - invalid_grandchild_proptype.yaml + +include: base.yaml + +properties: + prop-1: + type: string diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/simple.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/simple.yaml new file mode 100644 index 0000000000000..27f6ce8120d91 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/simple.yaml @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Base properties for testing property filters propagation +# up to the grandchild-binding level. + +properties: + prop-1: + type: int + prop-2: + type: int + prop-3: + type: int + +child-binding: + properties: + child-prop-1: + type: int + child-prop-2: + type: int + child-prop-3: + type: int + + child-binding: + properties: + grandchild-prop-1: + type: int + grandchild-prop-2: + type: int + grandchild-prop-3: + type: int diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/simple_allowlist.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/simple_allowlist.yaml new file mode 100644 index 0000000000000..7294393a2a2e1 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/simple_allowlist.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Filter inherited property specifications +# up to the grandchild-binding level. + +include: + - name: simple_inherit.yaml + property-allowlist: [prop-1, prop-2] + child-binding: + property-allowlist: [child-prop-1, child-prop-2] + child-binding: + property-allowlist: [grandchild-prop-1, grandchild-prop-2] diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/simple_blocklist.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/simple_blocklist.yaml new file mode 100644 index 0000000000000..c9d581e2c077d --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/simple_blocklist.yaml @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Filter inherited property specifications +# up to the grandchild-binding level. + +include: + - name: simple_inherit.yaml + property-blocklist: [prop-1] + child-binding: + property-blocklist: [child-prop-1] + child-binding: + property-blocklist: [grandchild-prop-1] diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/simple_inherit.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/simple_inherit.yaml new file mode 100644 index 0000000000000..8a95ef38f9511 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/simple_inherit.yaml @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Inherits property specifications without modification. + +include: simple.yaml diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/thing.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/thing.yaml new file mode 100644 index 0000000000000..82a31aaa39117 --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/thing.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Right (included last) YAML file for testing diamond inheritance. +# +# Amends base.yaml. +# +# Binding level: +# - prop-1 (amended) +# - prop-enum (amended) +# - prop-thing (new property) +# +# Child-binding level: +# - child-prop-1 (amended) +# - child-prop-enum (amended) +# - child-prop-thing (new property) +# +# Grandchild-binding level: +# - grandchild-prop-1 (amended) +# - grandchild-prop-enum (amended) +# - grandchild-prop-thing (new property) + +description: Description of 'thing.yaml'. + +include: + - name: base.yaml + property-allowlist: [prop-1, prop-enum] + child-binding: + property-allowlist: [child-prop-1, child-prop-enum] + child-binding: + property-allowlist: [grandchild-prop-1, grandchild-prop-enum] + +properties: + prop-1: + default: 1 + # Diamond inheritance in diamond.yaml: should overwrite + # the amended description from base_amend.yaml. + description: Overwritten in thing.yaml. + + prop-enum: + # This is the definition inherited from base.yaml. + # + # Diamond inheritance in diamond.yaml: should be ORed + # with the definition inherited via base_amend.yaml. + required: false + + prop-thing: + description: Thing property. + type: int + +child-binding: + description: Child-binding description (thing). + properties: + child-prop-1: + description: Overwritten in thing.yaml (child). + default: 2 + child-prop-enum: + required: false + child-prop-thing: + description: Thing child-binding property. + type: int + + child-binding: + description: Grandchild-binding description (thing). + properties: + grandchild-prop-1: + description: Overwritten in thing.yaml (grandchild). + default: 3 + grandchild-prop-enum: + required: false + grandchild-prop-thing: + description: Thing grandchild-binding property. + type: int diff --git a/scripts/dts/python-devicetree/tests/test-bindings-init/vnd,thing.yaml b/scripts/dts/python-devicetree/tests/test-bindings-init/vnd,thing.yaml new file mode 100644 index 0000000000000..30015716a7d3d --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test-bindings-init/vnd,thing.yaml @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: BSD-3-Clause +# +# Top level binding file (device binding) for testing +# descriptions and compatible strings. + +description: The Thing device. + +compatible: "vnd,thing" + +include: + - name: base_amend.yaml + - name: thing.yaml + +child-binding: + compatible: "vnd,thing-child" + description: The Thing's child-binding. + + child-binding: + compatible: "vnd,thing-grandchild" + description: The Thing's grandchild-binding. diff --git a/scripts/dts/python-devicetree/tests/test_edtlib_binding_init.py b/scripts/dts/python-devicetree/tests/test_edtlib_binding_init.py new file mode 100644 index 0000000000000..d4ded2965c34a --- /dev/null +++ b/scripts/dts/python-devicetree/tests/test_edtlib_binding_init.py @@ -0,0 +1,1160 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Christophe Dufaza + +"""Unit tests dedicated to edtlib.Binding objects initialization. + +Running the assumption that any (valid) YAML binding file is +something we can make a Binding instance with: +- check which properties are defined at which level (binding, child-binding, + grandchild-binding, etc) and their specifications once the binding + is initialized +- check how including bindings are permitted to specialize + the specifications of inherited properties +- check the rules applied when overwriting a binding's description + or compatible string (at the binding, child-binding, etc, levels) + +At any level, an including binding is permitted to: +- filter the properties it chooses to inherit with either "property:allowlist" + or "property:blocklist" but not both +- extend inherited properties: + - override (implicit or) explicit "required: false" with "required: true" + - add constraints to the possible value(s) of a property with "const:" + or "enum:" + - add a "default:" value to a property + - add or overwrite a property's "description:"; when overwritten multiple + times by several included binding files, "include:"ed first "wins" +- define new properties + +At any level, an including binding is NOT permitted to: +- remove a requirement by overriding "required: true" with "required: false" +- change existing constrains applied to the possible values of + an inherited property with "const:" or "enum:" +- change the "default:" value of an inherited property +- change the "type:" of an inherited property + +Rules applying to bindings' descriptions and compatible strings: +- included files can't overwrite the description or compatible string set + by the including binding (despite that "description:" appears before + "include:"): this seems consistent, the top-level binding file "wins" +- an including binding can overwrite descriptions and compatible strings + inherited at the child-binding levels: this seems consistent, + the top-level binding file "wins" +- when we include multiple files overwriting a description or compatible + string inherited at the child-binding levels, order of inclusion matters, + the first "wins"; this is consistent with property descriptions + +For all tests, the entry point is a Binding instance initialized +by loading the YAML file which represents the test case: our focus here +really is what happens when we (recursively) call Binding's constructor, +independently of any actual devicetree model (edtlib.EDT instance). +""" + +# pylint: disable=too-many-statements + +import contextlib +import os +from collections.abc import Generator +from typing import Any + +import pytest +from devicetree import edtlib + +YAML_KNOWN_BASE_BINDINGS: dict[str, str] = { + # Base properties, bottom of the diamond test case. + "base.yaml": "test-bindings-init/base.yaml", + # Amended properties, left (first) "include:" in the diamond test case. + "base_amend.yaml": "test-bindings-init/base_amend.yaml", + # Amended properties, right (last) "include:" in the diamond test case. + "thing.yaml": "test-bindings-init/thing.yaml", + # Used for testing property filters when "A includes B includes C". + "simple.yaml": "test-bindings-init/simple.yaml", + "simple_inherit.yaml": "test-bindings-init/simple_inherit.yaml", + "simple_allowlist.yaml": "test-bindings-init/simple_allowlist.yaml", + "simple_blocklist.yaml": "test-bindings-init/simple_blocklist.yaml", + # Test applied rules for compatible strings and descriptions. + "compat_desc_base.yaml": "test-bindings-init/compat_desc_base.yaml", + "compat_desc.yaml": "test-bindings-init/compat_desc.yaml", +} + + +def load_binding(path: str) -> edtlib.Binding: + """Load YAML file as Binding instance, + using YAML_BASE to resolve includes. + + Args: + path: Path relative to ZEPHYR_BASE/scripts/dts/python-devicetree/tests. + """ + with _from_here(): + binding = edtlib.Binding( + path=path, + fname2path=YAML_KNOWN_BASE_BINDINGS, + raw=None, + require_compatible=False, + require_description=False, + ) + return binding + + +def child_binding_of(path: str) -> edtlib.Binding: + """Load YAML file as Binding instance, and returns its child-binding. + The child-binding must exist. + + Args: + path: Path relative to ZEPHYR_BASE/scripts/dts/python-devicetree/tests. + """ + binding = load_binding(path) + assert binding.child_binding + return binding.child_binding + + +def grandchild_binding_of(path: str) -> edtlib.Binding: + """Load YAML file as Binding instance, and returns its grandchild-binding. + The grandchild-binding must exist. + + Args: + path: Path relative to ZEPHYR_BASE/scripts/dts/python-devicetree/tests. + """ + child_binding = child_binding_of(path) + assert child_binding.child_binding + return child_binding.child_binding + + +def verify_expected_propspec( + propspec: edtlib.PropertySpec, + /, + *, + # Most properties are integers. + expect_type: str = "int", + expect_req: bool = False, + expect_desc: str | None = None, + expect_enum: list[int | str] | None = None, + expect_const: Any | None = None, + expect_default: Any | None = None, +) -> None: + """Compare a property specification with the definitions + we (finally) expect. + + All definitions are tested for equality. + + Args: + propsec: The property specification to verify. + expect_type: The expected property type definition. + expect_req: Whether the property is expected to be required. + expect_desc: The expected property description. + expect_enum: The expected property "enum:" definition. + expect_const: The expected property "const:" definition. + expect_default: The expected property "default:" definition. + """ + assert expect_type == propspec.type + assert expect_req == propspec.required + assert expect_desc == propspec.description + assert expect_enum == propspec.enum + assert expect_const == propspec.const + assert expect_default == propspec.default + + +def verify_binding_propspecs_consistency(binding: edtlib.Binding) -> None: + """Verify consistency between what's in Binding.prop2specs + and Binding.raw. + + Asserts that: + Binding.raw["properties"][prop] == Binding.prop2specs[prop]._raw + + If the binding has a child-binding, also recursively verify child-bindings. + + NOTE: do not confuse with binding.prop2specs[prop].binding == binding, + which we do not assume here. + """ + if binding.prop2specs: + assert set(binding.raw["properties"].keys()) == set(binding.prop2specs.keys()) + assert all( + binding.raw["properties"][prop] == propspec._raw + for prop, propspec in binding.prop2specs.items() + ) + if binding.child_binding: + verify_binding_propspecs_consistency(binding.child_binding) + + +def test_expect_propspecs_inherited_bindings() -> None: + """Test the basics of including property specifications. + + Specifications are simply inherited without modifications + up to the grandchild-binding level. + + Check that we actually inherit all expected definitions as-is. + """ + binding = load_binding("test-bindings-init/base_inherit.yaml") + + # Binding level. + assert { + "prop-1", + "prop-2", + "prop-enum", + "prop-req", + "prop-const", + "prop-default", + } == set(binding.prop2specs.keys()) + propspec = binding.prop2specs["prop-1"] + verify_expected_propspec(propspec, expect_desc="Base property 1.") + propspec = binding.prop2specs["prop-2"] + verify_expected_propspec(propspec, expect_type="string") + propspec = binding.prop2specs["prop-enum"] + verify_expected_propspec(propspec, expect_type="string", expect_enum=["FOO", "BAR"]) + propspec = binding.prop2specs["prop-const"] + verify_expected_propspec(propspec, expect_const=8) + propspec = binding.prop2specs["prop-req"] + verify_expected_propspec(propspec, expect_req=True) + propspec = binding.prop2specs["prop-default"] + verify_expected_propspec(propspec, expect_default=1) + + # Child-Binding level. + assert binding.child_binding + child_binding = binding.child_binding + assert { + "child-prop-1", + "child-prop-2", + "child-prop-enum", + "child-prop-req", + "child-prop-const", + "child-prop-default", + } == set(child_binding.prop2specs.keys()) + propspec = child_binding.prop2specs["child-prop-1"] + verify_expected_propspec(propspec, expect_desc="Base child-prop 1.") + propspec = child_binding.prop2specs["child-prop-2"] + verify_expected_propspec(propspec, expect_type="string") + propspec = child_binding.prop2specs["child-prop-enum"] + verify_expected_propspec(propspec, expect_type="string", expect_enum=["CHILD_FOO", "CHILD_BAR"]) + propspec = child_binding.prop2specs["child-prop-const"] + verify_expected_propspec(propspec, expect_const=16) + propspec = child_binding.prop2specs["child-prop-req"] + verify_expected_propspec(propspec, expect_req=True) + propspec = child_binding.prop2specs["child-prop-default"] + verify_expected_propspec(propspec, expect_default=2) + + # GrandChild-Binding level. + assert child_binding.child_binding + grandchild_binding = child_binding.child_binding + assert { + "grandchild-prop-1", + "grandchild-prop-2", + "grandchild-prop-enum", + "grandchild-prop-req", + "grandchild-prop-const", + "grandchild-prop-default", + } == set(grandchild_binding.prop2specs.keys()) + propspec = grandchild_binding.prop2specs["grandchild-prop-1"] + verify_expected_propspec(propspec, expect_desc="Base grandchild-prop 1.") + propspec = grandchild_binding.prop2specs["grandchild-prop-2"] + verify_expected_propspec(propspec, expect_type="string") + propspec = grandchild_binding.prop2specs["grandchild-prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["GRANDCHILD_FOO", "GRANDCHILD_BAR"], + ) + propspec = grandchild_binding.prop2specs["grandchild-prop-const"] + verify_expected_propspec(propspec, expect_const=32) + propspec = grandchild_binding.prop2specs["grandchild-prop-req"] + verify_expected_propspec(propspec, expect_req=True) + propspec = grandchild_binding.prop2specs["grandchild-prop-default"] + verify_expected_propspec(propspec, expect_default=3) + + +def test_expect_propspecs_amended_bindings() -> None: + """Test the basics of including and amending property specifications. + + Base specifications are included once at the binding level: + + include: base.yaml + properties: + # Amend base.yaml + child-binding: + properties: + # Amend base.yaml + child-binding: + properties: + # Amend base.yaml + + Check that we finally get the expected property specifications + up to the grandchild-binding level. + """ + binding = load_binding("test-bindings-init/base_amend.yaml") + + # Binding level. + # + assert { + "prop-1", + "prop-2", + "prop-enum", + "prop-req", + "prop-const", + "prop-default", + "prop-new", + } == set(binding.prop2specs.keys()) + propspec = binding.prop2specs["prop-1"] + verify_expected_propspec( + propspec, + # Amended in base_amend.yaml. + expect_desc="Overwritten description.", + expect_const=0xF0, + ) + propspec = binding.prop2specs["prop-2"] + verify_expected_propspec( + propspec, + expect_type="string", + # Amended in base_amend.yaml. + expect_desc="New description.", + expect_enum=["EXT_FOO", "EXT_BAR"], + expect_default="EXT_FOO", + ) + propspec = binding.prop2specs["prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["FOO", "BAR"], + # Amended in base_amend.yaml. + expect_req=True, + ) + # Inherited from base.yaml without modification. + propspec = binding.prop2specs["prop-const"] + verify_expected_propspec(propspec, expect_const=8) + propspec = binding.prop2specs["prop-req"] + verify_expected_propspec(propspec, expect_req=True) + propspec = binding.prop2specs["prop-default"] + verify_expected_propspec(propspec, expect_default=1) + + # New property in base_amend.yaml. + propspec = binding.prop2specs["prop-new"] + verify_expected_propspec(propspec) + + # Child-Binding level. + # + assert binding.child_binding + child_binding = binding.child_binding + assert { + "child-prop-1", + "child-prop-2", + "child-prop-enum", + "child-prop-req", + "child-prop-const", + "child-prop-default", + "child-prop-new", + } == set(child_binding.prop2specs.keys()) + propspec = child_binding.prop2specs["child-prop-1"] + verify_expected_propspec( + propspec, + # Amended in base_amend.yaml. + expect_desc="Overwritten description (child).", + expect_const=0xF1, + ) + propspec = child_binding.prop2specs["child-prop-2"] + verify_expected_propspec( + propspec, + expect_type="string", + # Amended in base_amend.yaml. + expect_desc="New description (child).", + expect_enum=["CHILD_EXT_FOO", "CHILD_EXT_BAR"], + expect_default="CHILD_EXT_FOO", + ) + propspec = child_binding.prop2specs["child-prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["CHILD_FOO", "CHILD_BAR"], + # Amended in base_amend.yaml. + expect_req=True, + ) + # Inherited from base.yaml without modification. + propspec = child_binding.prop2specs["child-prop-const"] + verify_expected_propspec(propspec, expect_const=16) + propspec = child_binding.prop2specs["child-prop-req"] + verify_expected_propspec(propspec, expect_req=True) + propspec = child_binding.prop2specs["child-prop-default"] + verify_expected_propspec(propspec, expect_default=2) + + # New property in base_amend.yaml. + propspec = child_binding.prop2specs["child-prop-new"] + verify_expected_propspec(propspec) + + # GrandChild-Binding level. + # + assert child_binding.child_binding + grandchild_binding = child_binding.child_binding + assert { + "grandchild-prop-1", + "grandchild-prop-2", + "grandchild-prop-enum", + "grandchild-prop-req", + "grandchild-prop-const", + "grandchild-prop-default", + "grandchild-prop-new", + } == set(grandchild_binding.prop2specs.keys()) + propspec = grandchild_binding.prop2specs["grandchild-prop-1"] + verify_expected_propspec( + propspec, + # Amended in base_amend.yaml. + expect_desc="Overwritten description (grandchild).", + expect_const=0xF2, + ) + propspec = grandchild_binding.prop2specs["grandchild-prop-2"] + verify_expected_propspec( + propspec, + expect_type="string", + # Amended in base_amend.yaml. + expect_desc="New description (grandchild).", + expect_enum=["GRANDCHILD_EXT_FOO", "GRANDCHILD_EXT_BAR"], + expect_default="GRANDCHILD_EXT_FOO", + ) + propspec = grandchild_binding.prop2specs["grandchild-prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["GRANDCHILD_FOO", "GRANDCHILD_BAR"], + # Amended in base_amend.yaml. + expect_req=True, + ) + # Inherited from base.yaml without modification. + propspec = grandchild_binding.prop2specs["grandchild-prop-const"] + verify_expected_propspec(propspec, expect_const=32) + propspec = grandchild_binding.prop2specs["grandchild-prop-req"] + verify_expected_propspec(propspec, expect_req=True) + propspec = grandchild_binding.prop2specs["grandchild-prop-default"] + verify_expected_propspec(propspec, expect_default=3) + + # New property in base_amend.yaml. + propspec = grandchild_binding.prop2specs["grandchild-prop-new"] + verify_expected_propspec(propspec) + + +def test_expect_propspecs_multi_child_binding() -> None: + """Test including base bindings at multiple levels. + + Base specifications are included at the binding, child-binding + and child-binding levels: + + include: base.yaml + child-binding: + include: base.yaml + child-binding: + include: base.yaml + + This test checks that we finally get the expected property specifications + at the child-binding level. + """ + binding = child_binding_of("test-bindings-init/base_multi.yaml") + + assert { + # From top-level "include:" element. + "child-prop-1", + "child-prop-2", + "child-prop-enum", + # From "child-binding: include:" element. + "prop-1", + "prop-2", + "prop-enum", + } == set(binding.prop2specs.keys()) + + # Inherited from base.yaml without modification. + propspec = binding.prop2specs["child-prop-2"] + verify_expected_propspec(propspec, expect_type="string") + propspec = binding.prop2specs["child-prop-enum"] + verify_expected_propspec(propspec, expect_type="string", expect_enum=["CHILD_FOO", "CHILD_BAR"]) + + propspec = binding.prop2specs["child-prop-1"] + verify_expected_propspec( + propspec, + expect_desc="Base child-prop 1.", + # Amended in base_multi.yaml. + expect_const=0xF1, + ) + propspec = binding.prop2specs["prop-1"] + verify_expected_propspec( + propspec, + expect_desc="Base property 1.", + # Amended in base_multi.yaml. + expect_const=0xF1, + ) + propspec = binding.prop2specs["prop-2"] + verify_expected_propspec( + propspec, + expect_type="string", + # Amended in base_multi.yaml. + expect_desc="New description (child).", + ) + propspec = binding.prop2specs["prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["FOO", "BAR"], + # Amended in base_multi.yaml. + expect_default="FOO", + expect_req=True, + ) + + +def test_expect_propspecs_multi_grandchild_binding() -> None: + """Test including base bindings at multiple levels. + + This test checks that we finally get the expected property specifications + at the grandchild-binding level. + + See also: test_expect_propspecs_multi_child_binding() + """ + binding = grandchild_binding_of("test-bindings-init/base_multi.yaml") + + assert { + # From top-level "include:" element. + "grandchild-prop-1", + "grandchild-prop-2", + "grandchild-prop-enum", + # From "child-binding: include:" element. + "child-prop-1", + "child-prop-2", + "child-prop-enum", + # From "child-binding: child-binding: include:" element. + "prop-1", + "prop-2", + "prop-enum", + } == set(binding.prop2specs.keys()) + + # Inherited from base.yaml without modification. + propspec = binding.prop2specs["grandchild-prop-2"] + verify_expected_propspec(propspec, expect_type="string") + propspec = binding.prop2specs["grandchild-prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["GRANDCHILD_FOO", "GRANDCHILD_BAR"], + ) + propspec = binding.prop2specs["child-prop-2"] + verify_expected_propspec(propspec, expect_type="string") + propspec = binding.prop2specs["child-prop-enum"] + verify_expected_propspec(propspec, expect_type="string", expect_enum=["CHILD_FOO", "CHILD_BAR"]) + + propspec = binding.prop2specs["grandchild-prop-1"] + verify_expected_propspec( + propspec, + expect_desc="Base grandchild-prop 1.", + # Amended in base_multi.yaml. + expect_const=0xF2, + ) + propspec = binding.prop2specs["child-prop-1"] + verify_expected_propspec( + propspec, + expect_desc="Base child-prop 1.", + # Amended in base_multi.yaml. + expect_const=0xF2, + ) + propspec = binding.prop2specs["prop-1"] + verify_expected_propspec( + propspec, + expect_desc="Base property 1.", + # Amended in base_amend.yaml. + expect_const=0xF2, + ) + propspec = binding.prop2specs["prop-2"] + verify_expected_propspec( + propspec, + expect_type="string", + # Amended in base_amend.yaml. + expect_desc="New description (grandchild).", + ) + propspec = binding.prop2specs["prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["FOO", "BAR"], + # Amended in base_amend.yaml. + expect_req=True, + expect_default="FOO", + ) + + +def test_expect_propspecs_multi_grand_grandchild_binding() -> None: + """Test including base bindings at multiple levels. + + This test checks that we finally get the expected property specifications + at the grand-grandchild-binding level. + + See also: test_expect_propspecs_multi_child_binding() + """ + binding = grandchild_binding_of("test-bindings-init/base_multi.yaml").child_binding + assert binding + + assert { + # From "child-binding: include:" element. + "child-prop-1", + "child-prop-2", + "child-prop-enum", + # From "child-binding: child-binding: include:" element. + "grandchild-prop-1", + "grandchild-prop-2", + "grandchild-prop-enum", + } == set(binding.prop2specs.keys()) + + # Inherited from base.yaml without modification. + propspec = binding.prop2specs["child-prop-1"] + verify_expected_propspec(propspec, expect_desc="Base child-prop 1.") + propspec = binding.prop2specs["child-prop-2"] + verify_expected_propspec(propspec, expect_type="string") + propspec = binding.prop2specs["child-prop-enum"] + verify_expected_propspec(propspec, expect_type="string", expect_enum=["CHILD_FOO", "CHILD_BAR"]) + propspec = binding.prop2specs["grandchild-prop-1"] + verify_expected_propspec(propspec, expect_desc="Base grandchild-prop 1.") + propspec = binding.prop2specs["grandchild-prop-2"] + verify_expected_propspec(propspec, expect_type="string") + propspec = binding.prop2specs["grandchild-prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["GRANDCHILD_FOO", "GRANDCHILD_BAR"], + ) + + +def test_expect_propspecs_diamond_binding() -> None: + """Test property specifications produced by diamond inheritance. + + This test checks that we finally get the expected property specifications + at the binding level. + """ + binding = load_binding("test-bindings-init/diamond.yaml") + + assert { + # From base.yaml, amended in base_amend.yaml (left), + # last modified in thing.yaml (right). + "prop-1", + # From base.yaml, amended in base_amend.yaml (left), + # and thing.yaml (right), last modified in diamond.yaml(top). + "prop-enum", + # From base.yaml, inherited in base_amend.yaml (left). + "prop-default", + # From thing.yaml (right). + "prop-thing", + # From diamond.yaml (top). + "prop-diamond", + } == set(binding.prop2specs.keys()) + + # Inherited from base.yaml without modification. + propspec = binding.prop2specs["prop-default"] + verify_expected_propspec(propspec, expect_default=1) + # Inherited from thing.yaml without modification. + propspec = binding.prop2specs["prop-thing"] + verify_expected_propspec(propspec, expect_desc="Thing property.") + + # New property in diamond.yaml. + propspec = binding.prop2specs["prop-diamond"] + verify_expected_propspec(propspec) + + propspec = binding.prop2specs["prop-1"] + verify_expected_propspec( + propspec, + # From base_amend.yaml. + expect_const=0xF0, + # Included first wins. + expect_desc="Overwritten description.", + # From thing.yaml. + expect_default=1, + ) + propspec = binding.prop2specs["prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["FOO", "BAR"], + # From base_amend.yaml. + expect_req=True, + # From diamond.yaml. + expect_desc="Overwritten in diamond.yaml.", + expect_default="FOO", + ) + + +def test_expect_propspecs_diamond_child_binding() -> None: + """Test property specifications produced by diamond inheritance. + + This test checks that we finally get the expected property specifications + at the child-binding level. + """ + binding = child_binding_of("test-bindings-init/diamond.yaml") + + assert { + # From base.yaml, amended in base_amend.yaml (left), + # last modified in thing.yaml (right). + "child-prop-1", + # From base.yaml, amended in base_amend.yaml (left), + # and thing.yaml (right), last modified in diamond.yaml(top). + "child-prop-enum", + # From base.yaml, inherited in base_amend.yaml (left). + "child-prop-default", + # From thing.yaml (right). + "child-prop-thing", + # From diamond.yaml (top). + "child-prop-diamond", + } == set(binding.prop2specs.keys()) + + propspec = binding.prop2specs["child-prop-1"] + verify_expected_propspec( + propspec, + # From base_amend.yaml. + expect_const=0xF1, + # Included first wins. + expect_desc="Overwritten description (child).", + # From thing.yaml. + expect_default=2, + ) + + propspec = binding.prop2specs["child-prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["CHILD_FOO", "CHILD_BAR"], + # From base_amend.yaml. + # ORed with thing.yaml. + expect_req=True, + # From diamond.yaml. + expect_default="CHILD_FOO", + expect_desc="Overwritten in diamond.yaml (child).", + ) + + # Inherited from base.yaml without modification. + propspec = binding.prop2specs["child-prop-default"] + verify_expected_propspec(propspec, expect_default=2) + # Inherited from thing.yaml without modification. + propspec = binding.prop2specs["child-prop-thing"] + verify_expected_propspec(propspec, expect_desc="Thing child-binding property.") + + # New property in diamond.yaml. + propspec = binding.prop2specs["child-prop-diamond"] + verify_expected_propspec(propspec) + + +def test_expect_propspecs_diamond_grandchild_binding() -> None: + """Test property specifications produced by diamond inheritance. + + This test checks that we finally get the expected property specifications + at the grandchild-binding level. + """ + binding = grandchild_binding_of("test-bindings-init/diamond.yaml") + + assert { + # From base.yaml, amended in base_amend.yaml (left), + # last modified in thing.yaml (right). + "grandchild-prop-1", + # From base.yaml, amended in base_amend.yaml (left), + # last modified in diamond.yaml (top). + "grandchild-prop-enum", + # From base.yaml, inherited in base_amend.yaml (left). + "grandchild-prop-default", + # From thing.yaml (right). + "grandchild-prop-thing", + # From diamond.yaml (top). + "grandchild-prop-diamond", + } == set(binding.prop2specs.keys()) + + propspec = binding.prop2specs["grandchild-prop-1"] + verify_expected_propspec( + propspec, + # From base_amend.yaml. + expect_const=0xF2, + # Included first wins. + expect_desc="Overwritten description (grandchild).", + # From thing.yaml. + expect_default=3, + ) + + propspec = binding.prop2specs["grandchild-prop-enum"] + verify_expected_propspec( + propspec, + expect_type="string", + expect_enum=["GRANDCHILD_FOO", "GRANDCHILD_BAR"], + # From base_amend.yaml. + # ORed with thing.yaml. + expect_req=True, + # From diamond.yaml. + expect_default="GRANDCHILD_FOO", + expect_desc="Overwritten in diamond.yaml (grandchild).", + ) + + # Inherited from base.yaml without modification. + propspec = binding.prop2specs["grandchild-prop-default"] + verify_expected_propspec(propspec, expect_default=3) + # Inherited from thing.yaml without modification. + propspec = binding.prop2specs["grandchild-prop-thing"] + verify_expected_propspec(propspec, expect_desc="Thing grandchild-binding property.") + + # New property in diamond.yaml. + propspec = binding.prop2specs["grandchild-prop-diamond"] + verify_expected_propspec(propspec) + + +def test_binding_description_overwrite() -> None: + """Test whether we can overwrite a binding's description. + + Included files can't overwrite the description set by the including binding + (despite that "description:" appears before "include:"). + + This seems consistent: the top-level binding file "wins". + """ + binding = load_binding("test-bindings-init/compat_desc.yaml") + assert binding.description == "Binding description." + + binding = load_binding("test-bindings-init/compat_desc_multi.yaml") + assert binding.description == "Binding description (multi)." + + +def test_binding_compat_overwrite() -> None: + """Test whether we can overwrite a binding's compatible string. + + Included files can't overwrite the compatible string set by the + including binding (despite that "compatible:" appears before "include:"). + + This seems consistent: the top-level binding file "wins". + """ + binding = load_binding("test-bindings-init/compat_desc.yaml") + assert binding.compatible == "vnd,compat-desc" + + binding = load_binding("test-bindings-init/compat_desc_multi.yaml") + assert binding.compatible == "vnd,compat-desc-multi" + + +def test_child_binding_description_overwrite() -> None: + """Test whether we can overwrite a child-binding's description. + + An including binding can overwrite an inherited child-binding's description. + + When we include multiple files overwriting the description + at the child-binding level, the first "wins". + """ + child_binding = child_binding_of("test-bindings-init/compat_desc.yaml") + # Overwrite inherited description. + assert child_binding.description == "Child-binding description." + + child_binding = child_binding_of("test-bindings-init/compat_desc_multi.yaml") + # When inherited multiple times, the first "description:" wins. + assert child_binding.description == "Child-binding description (base)." + + +def test_child_binding_compat_overwrite() -> None: + """Test whether we can overwrite a child-binding's compatible string. + + An including binding can overwrite an inherited child-binding's + compatible string. + + When we include multiple files overwriting the compatible string + at the child-binding level, the first "wins". + """ + child_binding = child_binding_of("test-bindings-init/compat_desc.yaml") + # Overwrite inherited description. + assert child_binding.compatible == "vnd,child-compat-desc" + + child_binding = child_binding_of("test-bindings-init/compat_desc_multi.yaml") + # When inherited multiple times, the first "compatible:" wins. + assert child_binding.compatible == "vnd,child-compat-desc-base" + + +def test_grandchild_binding_description_overwrite() -> None: + """Test whether we can overwrite a grandchild-binding's description. + + See also: test_child_binding_description_overwrite() + """ + grandchild_binding = grandchild_binding_of("test-bindings-init/compat_desc.yaml") + assert grandchild_binding.description == "Grandchild-binding description." + + grandchild_binding = grandchild_binding_of("test-bindings-init/compat_desc_multi.yaml") + assert grandchild_binding.description == "Grandchild-binding description (base)." + + +def test_grandchild_binding_compat_overwrite() -> None: + """Test whether we can overwrite a grandchild-binding's compatible string. + + See also: test_child_binding_compat_overwrite() + """ + grandchild_binding = grandchild_binding_of("test-bindings-init/compat_desc.yaml") + # Overwrite inherited description. + assert grandchild_binding.compatible == "vnd,grandchild-compat-desc" + + grandchild_binding = grandchild_binding_of("test-bindings-init/compat_desc_multi.yaml") + # When inherited multiple times, the first "compatible:" wins. + assert grandchild_binding.compatible == "vnd,grandchild-compat-desc-base" + + +def test_filter_inherited_propspecs_basics() -> None: + """Test the basics of filtering properties inherited via an intermediary + binding file. + + Use-case "B filters I includes X": + - X is a base binding file, specifying common properties + - I is an intermediary binding file, which includes X without modification + nor filter + - B includes I, filtering the properties it chooses to inherit + with an allowlist or a blocklist + + Checks, up to the grandchild-binding level, that the properties inherited + from X via I are actually filtered as B intends to. + """ + # Binding level. + binding = load_binding("test-bindings-init/simple_allowlist.yaml") + # Allowed properties. + assert {"prop-1", "prop-2"} == set(binding.prop2specs.keys()) + binding = load_binding("test-bindings-init/simple_blocklist.yaml") + # Non blocked properties. + assert {"prop-2", "prop-3"} == set(binding.prop2specs.keys()) + + # Child-binding level. + child_binding = child_binding_of("test-bindings-init/simple_allowlist.yaml") + # Allowed properties. + assert {"child-prop-1", "child-prop-2"} == set(child_binding.prop2specs.keys()) + child_binding = child_binding_of("test-bindings-init/simple_blocklist.yaml") + # Non blocked properties. + assert {"child-prop-2", "child-prop-3"} == set(child_binding.prop2specs.keys()) + + # GrandChild-binding level. + grandchild_binding = grandchild_binding_of("test-bindings-init/simple_allowlist.yaml") + # Allowed properties. + assert {"grandchild-prop-1", "grandchild-prop-2"} == set(grandchild_binding.prop2specs.keys()) + grandchild_binding = grandchild_binding_of("test-bindings-init/simple_blocklist.yaml") + # Non blocked properties. + assert {"grandchild-prop-2", "grandchild-prop-3"} == set(grandchild_binding.prop2specs.keys()) + + +def test_filter_inherited_propspecs_among_allowed() -> None: + """Test filtering properties which have been allowed by an intermediary + binding file. + + Complementary to test_filter_inherited_propspecs_basics(). + + Use-case "B filters I filters X": + - X is a base binding file, specifying common properties + - I is an intermediary binding file, filtering the properties specified + in X with an allowlist + - B includes I, filtering the properties it chooses to inherit + also with an allowlist + + Checks, up to the grandchild-binding level, that B inherits the properties + specified in X which are first allowed in I, then also allowed in B. + + For that, we check that if B allows only properties that are not allowed in I, + we then end up with no property at all. + """ + binding = load_binding("test-bindings-init/filter_among_allowed.yaml") + assert not set(binding.prop2specs.keys()) + assert binding.child_binding + child_binding = binding.child_binding + assert not set(child_binding.prop2specs.keys()) + assert child_binding.child_binding + grandchild_binding = child_binding.child_binding + assert not set(grandchild_binding.prop2specs.keys()) + + +def test_filter_inherited_propspecs_among_notblocked() -> None: + """Test filtering properties which have not been blocked by an intermediary + binding file. + + Complementary to test_filter_inherited_propspecs_basics(). + + Use-case "B filters I filters X": + - X is a base binding file, specifying common properties + - I is an intermediary binding file, filtering the properties specified + in X with a blocklist + - B includes I, filtering the properties it chooses to inherit + also with a blocklist + + Checks, up to the grandchild-binding level, that B inherits the properties + specified in X which are not blocked in I, then neither blocked in B. + + For that, we check that if B blocks all properties that are not blocked in I, + we then end up with no property at all. + """ + binding = load_binding("test-bindings-init/filter_among_notblocked.yaml") + assert not set(binding.prop2specs.keys()) + assert binding.child_binding + child_binding = binding.child_binding + assert not set(child_binding.prop2specs.keys()) + assert child_binding.child_binding + grandchild_binding = child_binding.child_binding + assert not set(grandchild_binding.prop2specs.keys()) + + +def test_filter_inherited_propspecs_allows_notblocked() -> None: + """Test allowing properties which have not been blocked by an intermediary + binding file. + + Complementary to test_filter_inherited_propspecs_basics(). + + Use-case "B filters I filters X": + - X is a base binding file, specifying common properties + - I is an intermediary binding file, filtering the properties specified + in X with a blocklist + - B includes I, filtering the properties it chooses to inherit + also with an allowlist + + Checks, up to the grandchild-binding level, that B inherits the properties + specified in X which are not blocked in I, then allowed in B. + + Permits to verify we can apply both "property-allowlist" + and "property-blocklist" filters to the same file, + as long as they're not applied simultaneously + (i.e. within the same YAML "include:" map). + """ + binding = load_binding("test-bindings-init/filter_allows_notblocked.yaml") + assert {"prop-2"} == set(binding.prop2specs.keys()) + assert binding.child_binding + child_binding = binding.child_binding + assert {"child-prop-2"} == set(child_binding.prop2specs.keys()) + assert child_binding.child_binding + grandchild_binding = child_binding.child_binding + assert {"grandchild-prop-2"} == set(grandchild_binding.prop2specs.keys()) + + +def test_invalid_binding_type_override() -> None: + """An including binding should not try to override the "type:" + of an inherited property. + + Tested up to the grandchild-binding level. + """ + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_proptype.yaml") + assert "prop-1" in str(e) + assert "'int' replaced with 'string'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_child_proptype.yaml") + assert "child-prop-1" in str(e) + assert "'int' replaced with 'string'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_grandchild_proptype.yaml") + assert "grandchild-prop-1" in str(e) + assert "'int' replaced with 'string'" in str(e) + + +def test_invalid_binding_const_override() -> None: + """An including binding should not try to override the "const:" value + in a property specification inherited from an included file. + + Tested up to the grandchild-binding level. + """ + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_propconst.yaml") + assert "prop-const" in str(e) + assert "'8' replaced with '999'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_child_propconst.yaml") + assert "child-prop-const" in str(e) + assert "'16' replaced with '999'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_grandchild_propconst.yaml") + assert "grandchild-prop-const" in str(e) + assert "'32' replaced with '999'" in str(e) + + +def test_invalid_binding_required_override() -> None: + """An including binding should not try to override "required: true" + in a property specification inherited from an included file. + + Tested up to the grandchild-binding level. + """ + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_propreq.yaml") + assert "prop-req" in str(e) + assert "'True' replaced with 'False'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_child_propreq.yaml") + assert "child-prop-req" in str(e) + assert "'True' replaced with 'False'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_grandchild_propreq.yaml") + assert "grandchild-prop-req" in str(e) + assert "'True' replaced with 'False'" in str(e) + + +def test_invalid_binding_default_override() -> None: + """An including binding should not try to override the "default:" value + in a property specification inherited from an included file. + + Tested up to the grandchild-binding level. + """ + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_propdefault.yaml") + assert "prop-default" in str(e) + assert "'1' replaced with '999'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_child_propdefault.yaml") + assert "child-prop-default" in str(e) + assert "'2' replaced with '999'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_grandchild_propdefault.yaml") + assert "grandchild-prop-default" in str(e) + assert "'3' replaced with '999'" in str(e) + + +def test_invalid_binding_enum_override() -> None: + """An including binding should not try to override the "enum:" values + in a property specification inherited from an included file. + + Tested up to the grandchild-binding level. + """ + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_propenum.yaml") + assert "prop-enum" in str(e) + assert "'['FOO', 'BAR']' replaced with '['OTHER_FOO', 'OTHER_BAR']'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_child_propenum.yaml") + assert "child-prop-enum" in str(e) + assert "'['CHILD_FOO', 'CHILD_BAR']' replaced with '['OTHER_FOO', 'OTHER_BAR']'" in str(e) + + with pytest.raises(edtlib.EDTError) as e: + load_binding("test-bindings-init/invalid_grandchild_propenum.yaml") + assert "grandchild-prop-enum" in str(e) + assert ( + "'['GRANDCHILD_FOO', 'GRANDCHILD_BAR']' replaced with '['OTHER_FOO', 'OTHER_BAR']'" + in str(e) + ) + + +def test_bindings_propspecs_consistency() -> None: + """Verify property specifications consistency. + + Consistency is recursively checked for all defined properties, + from top-level binding files down to their child bindings. + + Consistency is checked with: + Binding.raw["properties"][prop] == Binding.prop2specs[prop]._raw + + See verify_binding_propspecs_consistency(). + """ + binding = load_binding("test-bindings-init/base_inherit.yaml") + verify_binding_propspecs_consistency(binding) + + binding = load_binding("test-bindings-init/base_amend.yaml") + verify_binding_propspecs_consistency(binding) + + binding = load_binding("test-bindings-init/base_multi.yaml") + verify_binding_propspecs_consistency(binding) + + binding = load_binding("test-bindings-init/thing.yaml") + verify_binding_propspecs_consistency(binding) + + binding = load_binding("test-bindings-init/diamond.yaml") + verify_binding_propspecs_consistency(binding) + + +# Borrowed from test_edtlib.py. +@contextlib.contextmanager +def _from_here() -> Generator[None, None, None]: + cwd = os.getcwd() + try: + os.chdir(os.path.dirname(__file__)) + yield + finally: + os.chdir(cwd) + + +def _basename(path: str | None) -> str: + return os.path.basename(path or "?") diff --git a/scripts/footprint/plan.txt b/scripts/footprint/plan.txt index f53a1371e7c74..a28cb93f142a3 100644 --- a/scripts/footprint/plan.txt +++ b/scripts/footprint/plan.txt @@ -5,7 +5,7 @@ footprints,userspace,disco_l475_iot1,tests/benchmarks/footprints,-DCONF_FILE=prj footprints,default,nrf5340dk/nrf5340/cpuapp,tests/benchmarks/footprints,,benchmark.kernel.footprints.default footprints,default,nrf51dk/nrf51822,tests/benchmarks/footprints,,benchmark.kernel.footprints.default footprints,default,altera_max10,tests/benchmarks/footprints,,benchmark.kernel.footprints.default -footprints,default,hifive1_revb,tests/benchmarks/footprints,,benchmark.kernel.footprints.default +footprints,default,hifive1@B,tests/benchmarks/footprints,,benchmark.kernel.footprints.default footprints,default,intel_ehl_crb,tests/benchmarks/footprints,,benchmark.kernel.footprints.default footprints,userspace,intel_ehl_crb,tests/benchmarks/footprints,-DCONF_FILE=prj_userspace.conf,benchmark.kernel.footprints.userspace footprints,power-management,frdm_k64f,tests/benchmarks/footprints,-DCONF_FILE=prj_pm.conf,benchmark.kernel.footprints.pm diff --git a/scripts/kconfig/kconfigfunctions.py b/scripts/kconfig/kconfigfunctions.py index 03071fba7dfd8..81411a9d7a1cc 100644 --- a/scripts/kconfig/kconfigfunctions.py +++ b/scripts/kconfig/kconfigfunctions.py @@ -772,6 +772,23 @@ def dt_compat_any_has_prop(kconf, _, compat, prop, value=None): return "y" return "n" +def dt_compat_any_not_has_prop(kconf, _, compat, prop): + """ + This function takes a 'compat', and a 'prop'. + The function returns "y" if any enabled node with compatible 'compat' + does NOT contain the property 'prop'. + It returns "n" otherwise. + """ + if doc_mode or edt is None: + return "n" + + if compat in edt.compat2okay: + for node in edt.compat2okay[compat]: + if prop not in node.props: + return "y" + + return "n" + def dt_nodelabel_has_compat(kconf, _, label, compat): """ This function takes a 'label' and looks for an EDT node with that label. @@ -1006,6 +1023,7 @@ def inc_dec(kconf, name, *args): "dt_compat_enabled": (dt_compat_enabled, 1, 1), "dt_compat_on_bus": (dt_compat_on_bus, 2, 2), "dt_compat_any_has_prop": (dt_compat_any_has_prop, 2, 3), + "dt_compat_any_not_has_prop": (dt_compat_any_not_has_prop, 2, 2), "dt_chosen_label": (dt_chosen_label, 1, 1), "dt_chosen_enabled": (dt_chosen_enabled, 1, 1), "dt_chosen_path": (dt_chosen_path, 1, 1), diff --git a/scripts/logging/dictionary/database_gen.py b/scripts/logging/dictionary/database_gen.py index 5060ef3b928fd..cabc139508328 100755 --- a/scripts/logging/dictionary/database_gen.py +++ b/scripts/logging/dictionary/database_gen.py @@ -366,7 +366,7 @@ def extract_string_variables(elf): # its address in memory. loc_attr = die.attributes['DW_AT_location'] if loc_parser.attribute_has_location(loc_attr, die.cu['version']): - loc = loc_parser.parse_from_attribute(loc_attr, die.cu['version']) + loc = loc_parser.parse_from_attribute(loc_attr, die.cu['version'], die) if isinstance(loc, LocationExpr): try: addr = describe_DWARF_expr(loc.loc_expr, diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py index 3f73045f899fe..87ecac0f75a9d 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py @@ -67,6 +67,8 @@ def launch(self) -> None: if not self.command: self.generate_command() + if self.device_config.extra_test_args: + self.command.extend(self.device_config.extra_test_args.split()) if self.device_config.type != 'hardware': self._flash_and_run() @@ -238,7 +240,7 @@ def _handle_device_output(self) -> None: with open(self.handler_log_path, 'a+') as log_file: while self.is_device_running(): if self.is_device_connected(): - output = self._read_device_output().decode(errors='replace').strip() + output = self._read_device_output().decode(errors='replace').rstrip("\r\n") if output: self._device_read_queue.put(output) log_file.write(f'{output}\n') diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py index 991b347b7521f..79a3a93564481 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py @@ -73,6 +73,9 @@ def _prepare_runner_args(self) -> tuple[list[str], list[str]]: if runner == 'pyocd': extra_args.append('--board-id') extra_args.append(board_id) + elif runner == "esp32": + extra_args.append("--esp-device") + extra_args.append(board_id) elif runner in ('nrfjprog', 'nrfutil'): extra_args.append('--dev-id') extra_args.append(board_id) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py index 7782617538c7c..0960db7743ae8 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/shell.py @@ -22,7 +22,9 @@ class Shell: Helper class that provides methods used to interact with shell application. """ - def __init__(self, device: DeviceAdapter, prompt: str = 'uart:~$', timeout: float | None = None) -> None: + def __init__( + self, device: DeviceAdapter, prompt: str = 'uart:~$', timeout: float | None = None + ) -> None: self._device: DeviceAdapter = device self.prompt: str = prompt self.base_timeout: float = timeout or device.base_timeout @@ -48,7 +50,9 @@ def wait_for_prompt(self, timeout: float | None = None) -> bool: return True return False - def exec_command(self, command: str, timeout: float | None = None, print_output: bool = True) -> list[str]: + def exec_command( + self, command: str, timeout: float | None = None, print_output: bool = True + ) -> list[str]: """ Send shell command to a device and return response. Passed command is extended by double enter sings - first one to execute this command @@ -63,20 +67,42 @@ def exec_command(self, command: str, timeout: float | None = None, print_output: self._device.write(command_ext.encode()) lines: list[str] = [] # wait for device command print - it should be done immediately after sending command to device - lines.extend(self._device.readlines_until(regex=regex_command, timeout=1.0, print_output=print_output)) + lines.extend( + self._device.readlines_until( + regex=regex_command, timeout=1.0, print_output=print_output + ) + ) # wait for device command execution - lines.extend(self._device.readlines_until(regex=regex_prompt, timeout=timeout, print_output=print_output)) + lines.extend( + self._device.readlines_until( + regex=regex_prompt, timeout=timeout, print_output=print_output + ) + ) return lines def get_filtered_output(self, command_lines: list[str]) -> list[str]: + """ + Filter out prompts and log messages + + Take the output of exec_command, which can contain log messages and command prompts, + and filter them to obtain only the command output. + + Example: + >>> # equivalent to `lines = shell.exec_command("kernel version")` + >>> lines = [ + >>> 'uart:~$', # filter prompts + >>> 'Zephyr version 3.6.0', # keep this line + >>> 'uart:~$ debug message' # filter log messages + >>> ] + >>> filtered_output = shell.get_filtered_output(output) + >>> filtered_output + ['Zephyr version 3.6.0'] + + :param command_lines: List of strings i.e. the output of `exec_command`. + :return: A list of strings containing, excluding prompts and log messages. + """ regex_filter = re.compile( - '|'.join([ - re.escape(self.prompt), - '', - '', - '', - '' - ]) + '|'.join([re.escape(self.prompt), '', '', '', '']) ) return list(filter(lambda l: not regex_filter.search(l), command_lines)) @@ -106,6 +132,7 @@ class ShellMCUbootCommandParsed: """ Helper class to keep data from `mcuboot` shell command. """ + areas: list[ShellMCUbootArea] = field(default_factory=list) @classmethod diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py index ef8a1fb6dc197..ec212db98bde6 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py @@ -126,6 +126,10 @@ def pytest_addoption(parser: pytest.Parser): '--twister-fixture', action='append', dest='fixtures', metavar='FIXTURE', default=[], help='Twister fixture supported by this platform. May be given multiple times.' ) + twister_harness_group.addoption( + '--extra-test-args', + help='Additional args passed to the test binary' + ) def pytest_configure(config: pytest.Config): diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py index c635f62973a8b..65aa87d8635bd 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/twister_harness_config.py @@ -36,6 +36,7 @@ class DeviceConfig: post_flash_script: Path | None = None fixtures: list[str] = None app_build_dir: Path | None = None + extra_test_args: str = '' def __post_init__(self): domains = self.build_dir / 'domains.yaml' @@ -81,6 +82,7 @@ def create(cls, config: pytest.Config) -> TwisterHarnessConfig: post_script=_cast_to_path(config.option.post_script), post_flash_script=_cast_to_path(config.option.post_flash_script), fixtures=config.option.fixtures, + extra_test_args=config.option.extra_test_args ) devices.append(device_from_cli) diff --git a/scripts/pylib/shell-twister-harness/conftest.py b/scripts/pylib/shell-twister-harness/conftest.py new file mode 100644 index 0000000000000..54cb2239ec4bf --- /dev/null +++ b/scripts/pylib/shell-twister-harness/conftest.py @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + + +def pytest_addoption(parser): + parser.addoption('--testdata') diff --git a/scripts/pylib/shell-twister-harness/test_shell.py b/scripts/pylib/shell-twister-harness/test_shell.py new file mode 100644 index 0000000000000..62c224537303b --- /dev/null +++ b/scripts/pylib/shell-twister-harness/test_shell.py @@ -0,0 +1,41 @@ +# Copyright (c) 2025 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +import logging +import re + +import pytest +import yaml +from twister_harness import Shell + +logger = logging.getLogger(__name__) + + +@pytest.fixture +def testdata_path(request): + return request.config.getoption("--testdata") + + +def get_next_commands(testdata_path): + with open(testdata_path) as yaml_file: + data = yaml.safe_load(yaml_file) + for entry in data: + yield entry['command'], entry.get('expected', None) + + +def test_shell_harness(shell: Shell, testdata_path): + if not testdata_path: + pytest.skip('testdata not provided') + for command, expected in get_next_commands(testdata_path): + logger.info('send command: %s', command) + lines = shell.exec_command(command) + if not expected: + logger.debug('no expected response') + continue + match = False + for line in lines: + if re.match(expected, line): + match = True + break + assert match, 'expected response not found' + logger.info('response is valid') diff --git a/scripts/pylib/twister/expr_parser.py b/scripts/pylib/twister/expr_parser.py index 03bee8dbe6683..4fafd453544ce 100644 --- a/scripts/pylib/twister/expr_parser.py +++ b/scripts/pylib/twister/expr_parser.py @@ -273,6 +273,14 @@ def ast_expr(ast, env, edt): if node and node.status == "okay": return True return False + elif ast[0] == "dt_node_prop_enabled": + label = ast[1][0] + node = edt.label2node.get(label) + prop = ast[1][1] + if node and prop in node.props and node.props[prop].val: + return True + return False + mutex = threading.Lock() diff --git a/scripts/pylib/twister/twisterlib/config_parser.py b/scripts/pylib/twister/twisterlib/config_parser.py index b330e1395d5fa..e5a379d0445de 100644 --- a/scripts/pylib/twister/twisterlib/config_parser.py +++ b/scripts/pylib/twister/twisterlib/config_parser.py @@ -66,6 +66,7 @@ class TwisterConfigParser: "vendor_exclude": {"type": "set"}, "extra_sections": {"type": "list", "default": []}, "integration_platforms": {"type": "list", "default": []}, + "integration_toolchains": {"type": "list", "default": []}, "ignore_faults": {"type": "bool", "default": False }, "ignore_qemu_crash": {"type": "bool", "default": False }, "testcases": {"type": "list", "default": []}, diff --git a/scripts/pylib/twister/twisterlib/coverage.py b/scripts/pylib/twister/twisterlib/coverage.py index dd647c60ddc34..3ae14a50131cc 100644 --- a/scripts/pylib/twister/twisterlib/coverage.py +++ b/scripts/pylib/twister/twisterlib/coverage.py @@ -1,6 +1,6 @@ # vim: set syntax=python ts=4 : # -# Copyright (c) 2018-2022 Intel Corporation +# Copyright (c) 2018-2025 Intel Corporation # SPDX-License-Identifier: Apache-2.0 import contextlib @@ -31,6 +31,10 @@ def __init__(self): self.gcov_tool = None self.base_dir = None self.output_formats = None + self.coverage_capture = True + self.coverage_report = True + self.coverage_per_instance = False + self.instances = {} @staticmethod def factory(tool, jobs=None): @@ -109,7 +113,7 @@ def merge_hexdumps(self, hexdumps): def create_gcda_files(self, extracted_coverage_info): gcda_created = True - logger.debug("Generating gcda files") + logger.debug(f"Generating {len(extracted_coverage_info)} gcda files") for filename, hexdumps in extracted_coverage_info.items(): # if kobject_hash is given for coverage gcovr fails # hence skipping it problem only in gcovr v4.1 @@ -132,7 +136,7 @@ def create_gcda_files(self, extracted_coverage_info): gcda_created = False return gcda_created - def generate(self, outdir): + def capture_data(self, outdir): coverage_completed = True for filename in glob.glob(f"{outdir}/**/handler.log", recursive=True): gcov_data = self.__class__.retrieve_gcov_data(filename) @@ -148,9 +152,18 @@ def generate(self, outdir): else: logger.error(f"Gcov data capture incomplete: {filename}") coverage_completed = False + return coverage_completed + def generate(self, outdir): + coverage_completed = self.capture_data(outdir) if self.coverage_capture else True + if not coverage_completed or not self.coverage_report: + return coverage_completed, {} + build_dirs = None + if not self.coverage_capture and self.coverage_report and self.coverage_per_instance: + build_dirs = [instance.build_dir for instance in self.instances.values()] + reports = {} with open(os.path.join(outdir, "coverage.log"), "a") as coveragelog: - ret = self._generate(outdir, coveragelog) + ret, reports = self._generate(outdir, coveragelog, build_dirs) if ret == 0: report_log = { "html": "HTML report generated: {}".format( @@ -180,7 +193,7 @@ def generate(self, outdir): else: coverage_completed = False logger.debug(f"All coverage data processed: {coverage_completed}") - return coverage_completed + return coverage_completed, reports class Lcov(CoverageTool): @@ -261,24 +274,56 @@ def run_lcov(self, args, coveragelog): ] + parallel + args return self.run_command(cmd, coveragelog) - def _generate(self, outdir, coveragelog): + + def _generate(self, outdir, coveragelog, build_dirs=None): coveragefile = os.path.join(outdir, "coverage.info") ztestfile = os.path.join(outdir, "ztest.info") - cmd = ["--capture", "--directory", outdir, "--output-file", coveragefile] - self.run_lcov(cmd, coveragelog) + if build_dirs: + files = [] + for dir_ in build_dirs: + files_ = [fname for fname in + [os.path.join(dir_, "coverage.info"), + os.path.join(dir_, "ztest.info")] + if os.path.exists(fname)] + if not files_: + logger.debug("Coverage merge no files in: %s", dir_) + continue + files += files_ + logger.debug("Coverage merge %d reports in %s", len(files), outdir) + cmd = ["--output-file", coveragefile] + for filename in files: + cmd.append("--add-tracefile") + cmd.append(filename) + else: + cmd = ["--capture", "--directory", outdir, "--output-file", coveragefile] + if self.coverage_per_instance and len(self.instances) == 1: + invalid_chars = re.compile(r"[^A-Za-z0-9_]") + cmd.append("--test-name") + cmd.append(invalid_chars.sub("_", next(iter(self.instances)))) + ret = self.run_lcov(cmd, coveragelog) + if ret: + logger.error("LCOV capture report stage failed with %s", ret) + return ret, {} # We want to remove tests/* and tests/ztest/test/* but save tests/ztest cmd = ["--extract", coveragefile, os.path.join(self.base_dir, "tests", "ztest", "*"), "--output-file", ztestfile] - self.run_lcov(cmd, coveragelog) + ret = self.run_lcov(cmd, coveragelog) + if ret: + logger.error("LCOV extract report stage failed with %s", ret) + return ret, {} + files = [] if os.path.exists(ztestfile) and os.path.getsize(ztestfile) > 0: cmd = ["--remove", ztestfile, os.path.join(self.base_dir, "tests/ztest/test/*"), "--output-file", ztestfile] - self.run_lcov(cmd, coveragelog) + ret = self.run_lcov(cmd, coveragelog) + if ret: + logger.error("LCOV remove ztest report stage failed with %s", ret) + return ret, {} files = [coveragefile, ztestfile] else: @@ -286,15 +331,26 @@ def _generate(self, outdir, coveragelog): for i in self.ignores: cmd = ["--remove", coveragefile, i, "--output-file", coveragefile] - self.run_lcov(cmd, coveragelog) + ret = self.run_lcov(cmd, coveragelog) + if ret: + logger.error("LCOV remove ignores report stage failed with %s", ret) + return ret, {} if 'html' not in self.output_formats.split(','): - return 0 + return 0, {} cmd = ["genhtml", "--legend", "--branch-coverage", "--prefix", self.base_dir, - "-output-directory", os.path.join(outdir, "coverage")] + files - return self.run_command(cmd, coveragelog) + "-output-directory", os.path.join(outdir, "coverage")] + if self.coverage_per_instance: + cmd.append("--show-details") + cmd += files + ret = self.run_command(cmd, coveragelog) + if ret: + logger.error("LCOV genhtml report stage failed with %s", ret) + + # TODO: Add LCOV summary coverage report. + return ret, { 'report': coveragefile, 'ztest': ztestfile, 'summary': None } class Gcovr(CoverageTool): @@ -305,6 +361,10 @@ def __init__(self): self.ignore_branch_patterns = [] self.output_formats = "html" self.version = self.get_version() + # Different ifdef-ed implementations of the same function should not be + # in conflict treated by GCOVR as separate objects for coverage statistics. + self.options = ["-v", "--merge-mode-functions=separate"] + def get_version(self): try: @@ -343,39 +403,73 @@ def _interleave_list(prefix, list): def _flatten_list(list): return [a for b in list for a in b] - def _generate(self, outdir, coveragelog): - coveragefile = os.path.join(outdir, "coverage.json") - ztestfile = os.path.join(outdir, "ztest.json") - + def collect_coverage(self, outdir, coverage_file, ztest_file, coveragelog): excludes = Gcovr._interleave_list("-e", self.ignores) if len(self.ignore_branch_patterns) > 0: # Last pattern overrides previous values, so merge all patterns together merged_regex = "|".join([f"({p})" for p in self.ignore_branch_patterns]) excludes += ["--exclude-branches-by-pattern", merged_regex] - # Different ifdef-ed implementations of the same function should not be - # in conflict treated by GCOVR as separate objects for coverage statistics. - mode_options = ["--merge-mode-functions=separate"] - # We want to remove tests/* and tests/ztest/test/* but save tests/ztest cmd = ["gcovr", "-r", self.base_dir, "--gcov-ignore-parse-errors=negative_hits.warn_once_per_file", "--gcov-executable", self.gcov_tool, "-e", "tests/*"] - cmd += excludes + mode_options + ["--json", "-o", coveragefile, outdir] + cmd += excludes + self.options + ["--json", "-o", coverage_file, outdir] cmd_str = " ".join(cmd) - logger.debug(f"Running {cmd_str}...") - subprocess.call(cmd, stdout=coveragelog) - - subprocess.call(["gcovr", "-r", self.base_dir, "--gcov-executable", - self.gcov_tool, "-f", "tests/ztest", "-e", - "tests/ztest/test/*", "--json", "-o", ztestfile, - outdir] + mode_options, stdout=coveragelog) - - if os.path.exists(ztestfile) and os.path.getsize(ztestfile) > 0: - files = [coveragefile, ztestfile] + logger.debug(f"Running: {cmd_str}") + coveragelog.write(f"Running: {cmd_str}\n") + coveragelog.flush() + ret = subprocess.call(cmd, stdout=coveragelog, stderr=coveragelog) + if ret: + logger.error(f"GCOVR failed with {ret}") + return ret, [] + + cmd = ["gcovr", "-r", self.base_dir] + self.options + cmd += ["--gcov-executable", self.gcov_tool, + "-f", "tests/ztest", "-e", "tests/ztest/test/*", + "--json", "-o", ztest_file, outdir] + cmd_str = " ".join(cmd) + logger.debug(f"Running: {cmd_str}") + coveragelog.write(f"Running: {cmd_str}\n") + coveragelog.flush() + ret = subprocess.call(cmd, stdout=coveragelog, stderr=coveragelog) + if ret: + logger.error(f"GCOVR ztest stage failed with {ret}") + return ret, [] + + return ret, [file_ for file_ in [coverage_file, ztest_file] + if os.path.exists(file_) and os.path.getsize(file_) > 0] + + + def _generate(self, outdir, coveragelog, build_dirs=None): + coverage_file = os.path.join(outdir, "coverage.json") + coverage_summary = os.path.join(outdir, "coverage_summary.json") + ztest_file = os.path.join(outdir, "ztest.json") + + ret = 0 + cmd_ = [] + files = [] + if build_dirs: + for dir_ in build_dirs: + files_ = [fname for fname in + [os.path.join(dir_, "coverage.json"), + os.path.join(dir_, "ztest.json")] + if os.path.exists(fname)] + if not files_: + logger.debug(f"Coverage merge no files in: {dir_}") + continue + files += files_ + logger.debug(f"Coverage merge {len(files)} reports in {outdir}") + ztest_file = None + cmd_ = ["--json-pretty", "--json", coverage_file] else: - files = [coveragefile] + ret, files = self.collect_coverage(outdir, coverage_file, ztest_file, coveragelog) + logger.debug(f"Coverage collected {len(files)} reports from: {outdir}") + + if not files: + logger.warning(f"No coverage files to compose report for {outdir}") + return ret, {} subdir = os.path.join(outdir, "coverage") os.makedirs(subdir, exist_ok=True) @@ -396,21 +490,22 @@ def _generate(self, outdir, coveragelog): [report_options[r] for r in self.output_formats.split(',')] ) - return subprocess.call( - ["gcovr", "-r", self.base_dir] \ - + mode_options + gcovr_options + tracefiles, stdout=coveragelog - ) + cmd = ["gcovr", "-r", self.base_dir] + self.options + gcovr_options + tracefiles + cmd += cmd_ + cmd += ["--json-summary-pretty", "--json-summary", coverage_summary] + cmd_str = " ".join(cmd) + logger.debug(f"Running: {cmd_str}") + coveragelog.write(f"Running: {cmd_str}\n") + coveragelog.flush() + ret = subprocess.call(cmd, stdout=coveragelog, stderr=coveragelog) + if ret: + logger.error(f"GCOVR merge report stage failed with {ret}") + return ret, { 'report': coverage_file, 'ztest': ztest_file, 'summary': coverage_summary } -def run_coverage(testplan, options): - use_system_gcov = False +def choose_gcov_tool(options, is_system_gcov): gcov_tool = None - - for plat in options.coverage_platform: - _plat = testplan.get_platform(plat) - if _plat and (_plat.type in {"native", "unit"}): - use_system_gcov = True if not options.gcov_tool: zephyr_sdk_gcov_tool = os.path.join( os.environ.get("ZEPHYR_SDK_INSTALL_DIR", default=""), @@ -427,7 +522,7 @@ def run_coverage(testplan, options): except OSError: shutil.copy(llvm_cov, gcov_lnk) gcov_tool = gcov_lnk - elif use_system_gcov: + elif is_system_gcov: gcov_tool = "gcov" elif os.path.exists(zephyr_sdk_gcov_tool): gcov_tool = zephyr_sdk_gcov_tool @@ -439,10 +534,22 @@ def run_coverage(testplan, options): else: gcov_tool = str(options.gcov_tool) - logger.info("Generating coverage files...") - logger.info(f"Using gcov tool: {gcov_tool}") + return gcov_tool + + +def run_coverage_tool(options, outdir, is_system_gcov, instances, + coverage_capture, coverage_report): coverage_tool = CoverageTool.factory(options.coverage_tool, jobs=options.jobs) - coverage_tool.gcov_tool = gcov_tool + if not coverage_tool: + return False, {} + + coverage_tool.gcov_tool = str(choose_gcov_tool(options, is_system_gcov)) + logger.debug(f"Using gcov tool: {coverage_tool.gcov_tool}") + + coverage_tool.instances = instances + coverage_tool.coverage_per_instance = options.coverage_per_instance + coverage_tool.coverage_capture = coverage_capture + coverage_tool.coverage_report = coverage_report coverage_tool.base_dir = os.path.abspath(options.coverage_basedir) # Apply output format default if options.coverage_formats is not None: @@ -456,5 +563,34 @@ def run_coverage(testplan, options): # Ignore branch coverage on __ASSERT* macros # Covering the failing case is not desirable as it will immediately terminate the test. coverage_tool.add_ignore_branch_pattern(r"^\s*__ASSERT(?:_EVAL|_NO_MSG|_POST_ACTION)?\(.*") - coverage_completed = coverage_tool.generate(options.outdir) - return coverage_completed + return coverage_tool.generate(outdir) + + +def has_system_gcov(platform): + return platform and (platform.type in {"native", "unit"}) + + +def run_coverage(options, testplan): + """ Summary code coverage over the full test plan's scope. + """ + is_system_gcov = False + + for plat in options.coverage_platform: + if has_system_gcov(testplan.get_platform(plat)): + is_system_gcov = True + break + + return run_coverage_tool(options, options.outdir, is_system_gcov, + instances=testplan.instances, + coverage_capture=False, + coverage_report=True) + + +def run_coverage_instance(options, instance): + """ Per-instance code coverage called by ProjectBuilder ('coverage' operation). + """ + is_system_gcov = has_system_gcov(instance.platform) + return run_coverage_tool(options, instance.build_dir, is_system_gcov, + instances={instance.name: instance}, + coverage_capture=True, + coverage_report=options.coverage_per_instance) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index b161096d562d0..4aae6e39f3905 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set syntax=python ts=4 : # -# Copyright (c) 2018-2024 Intel Corporation +# Copyright (c) 2018-2025 Intel Corporation # Copyright 2022 NXP # Copyright (c) 2024 Arm Limited (or its affiliates). All rights reserved. # @@ -114,6 +114,12 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: title="Memory footprint", description="Collect and report ROM/RAM size footprint for the test instance images built.") + coverage_group = parser.add_argument_group( + title="Code coverage", + description="Build with code coverage support, collect code coverage statistics " + "executing tests, compose code coverage report at the end.\n" + "Effective for devices with 'HAS_COVERAGE_SUPPORT'.") + test_plan_report_xor.add_argument( "-E", "--save-tests", @@ -148,12 +154,10 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: test_plan_report_xor.add_argument("--list-tests", action="store_true", help="""List of all sub-test functions recursively found in - all --testsuite-root arguments. Note different sub-tests can share - the same test scenario identifier (section.subsection) - and come from different directories. - The output is flattened and reports --sub-test names only, - not their directories. For instance net.socket.getaddrinfo_ok - and net.socket.fd_set belong to different directories. + all --testsuite-root arguments. The output is flattened and reports detailed + sub-test names without their directories. + Note: sub-test names can share the same test scenario identifier prefix + (section.subsection) even if they are from different test projects. """) test_plan_report_xor.add_argument("--test-tree", action="store_true", @@ -264,9 +268,11 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: functions. Sub-tests are named by: 'section.subsection_in_testcase_yaml.ztest_suite.ztest_without_test_prefix'. Example_1: 'kernel.fifo.fifo_api_1cpu.fifo_loop' where 'kernel.fifo' is a test scenario - name (section.subsection) and 'fifo_api_1cpu.fifo_loop' is - a Ztest suite_name.test_name identificator. + name (section.subsection) and 'fifo_api_1cpu.fifo_loop' is a Ztest 'suite_name.test_name'. Example_2: 'debug.coredump.logging_backend' is a standalone test scenario name. + Note: This selection mechanism works only for Ztest suite and test function names in + the source files which are not generated by macro-substitutions. + Note: With --no-detailed-test-id use only Ztest names without scenario name. """) parser.add_argument( @@ -275,6 +281,12 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: will extend the pytest_args from the harness_config in YAML file. """) + parser.add_argument( + "--ctest-args", action="append", + help="""Pass additional arguments to the ctest subprocess. This parameter + will extend the ctest_args from the harness_config in YAML file. + """) + valgrind_asan_group.add_argument( "--enable-valgrind", action="store_true", help="""Run binary through valgrind and check for several memory access @@ -336,10 +348,6 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: If not provided, seed in generated by system. Used only when --shuffle-tests is provided.""") - parser.add_argument("-C", "--coverage", action="store_true", - help="Generate coverage reports. Implies " - "--enable-coverage.") - parser.add_argument( "-c", "--clobber-output", action="store_true", help="Cleaning the output directory will simply delete it instead " @@ -349,27 +357,51 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: "--cmake-only", action="store_true", help="Only run cmake, do not build or run.") - parser.add_argument("--coverage-basedir", default=ZEPHYR_BASE, - help="Base source directory for coverage report.") - - parser.add_argument("--coverage-platform", action="append", default=[], - help="Platforms to run coverage reports on. " - "This option may be used multiple times. " - "Default to what was selected with --platform.") - - parser.add_argument("--coverage-tool", choices=['lcov', 'gcovr'], default='gcovr', - help="Tool to use to generate coverage report.") - - parser.add_argument( - "--coverage-formats", - action="store", - default=None, # default behavior is set in run_coverage - help="Output formats to use for generated coverage reports, as a comma-separated list. " + - "Valid options for 'gcovr' tool are: " + - ','.join(supported_coverage_formats['gcovr']) + " (html - default)." + - " Valid options for 'lcov' tool are: " + - ','.join(supported_coverage_formats['lcov']) + " (html,lcov - default)." - ) + coverage_group.add_argument("--enable-coverage", action="store_true", + help="Enable code coverage collection using gcov.") + + coverage_group.add_argument("-C", "--coverage", action="store_true", + help="Generate coverage reports. Implies " + "--enable-coverage to collect the coverage data first.") + + coverage_group.add_argument("--gcov-tool", type=Path, default=None, + help="Path to the 'gcov' tool to use for code coverage reports. " + "By default it will be chosen in the following order:" + " using ZEPHYR_TOOLCHAIN_VARIANT ('llvm': from LLVM_TOOLCHAIN_PATH)," + " gcov installed on the host - for 'native' or 'unit' platform types," + " using ZEPHYR_SDK_INSTALL_DIR.") + + coverage_group.add_argument("--coverage-basedir", default=ZEPHYR_BASE, + help="Base source directory for coverage report.") + + coverage_group.add_argument("--coverage-platform", action="append", default=[], + help="Platforms to run coverage reports on. " + "This option may be used multiple times. " + "Default to what was selected with --platform.") + + coverage_group.add_argument("--coverage-tool", choices=['lcov', 'gcovr'], default='gcovr', + help="Tool to use to generate coverage reports (%(default)s - default).") + + coverage_group.add_argument("--coverage-formats", action="store", default=None, + help="Output formats to use for generated coverage reports " + + "as a comma-separated list without spaces. " + + "Valid options for 'gcovr' tool are: " + + ','.join(supported_coverage_formats['gcovr']) + " (html - default)." + + " Valid options for 'lcov' tool are: " + + ','.join(supported_coverage_formats['lcov']) + " (html,lcov - default).") + + coverage_group.add_argument("--coverage-per-instance", action="store_true", default=False, + help="""Compose individual coverage reports for each test suite + when coverage reporting is enabled; it might run in addition to + the default aggregation mode which produces one coverage report for + all executed test suites. Default: %(default)s""") + + coverage_group.add_argument("--disable-coverage-aggregation", + action="store_true", default=False, + help="""Don't aggregate coverage report statistics for all the test suites + selected to run with enabled coverage. Requires another reporting mode to be + active (`--coverage-per-instance`) to have at least one of these reporting + modes. Default: %(default)s""") parser.add_argument( "--test-config", @@ -396,9 +428,6 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: help="Specify tags of tests that should not run. " "Default is to run all tests with all tags.") - parser.add_argument("--enable-coverage", action="store_true", - help="Enable code coverage using gcov.") - parser.add_argument( "--enable-lsan", action="store_true", help="""Enable leak sanitizer to check for heap memory leaks. @@ -431,10 +460,6 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: help="Do not filter based on toolchain, use the set " " toolchain unconditionally") - parser.add_argument("--gcov-tool", type=Path, default=None, - help="Path to the gcov tool to use for code coverage " - "reports") - footprint_group.add_argument( "--create-rom-ram-report", action="store_true", @@ -578,15 +603,21 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: parser.add_argument( '--detailed-test-id', action='store_true', - help="Include paths to tests' locations in tests' names. Names will follow " - "PATH_TO_TEST/SCENARIO_NAME schema " - "e.g. samples/hello_world/sample.basic.helloworld") + help="Compose each test Suite name from its configuration path (relative to root) and " + "the appropriate Scenario name using PATH_TO_TEST_CONFIG/SCENARIO_NAME schema. " + "Also (for Ztest only), prefix each test Case name with its Scenario name. " + "For example: 'kernel.common.timing' Scenario with test Suite name " + "'tests/kernel/sleep/kernel.common.timing' and 'kernel.common.timing.sleep.usleep' " + "test Case (where 'sleep' is its Ztest suite name and 'usleep' is Ztest test name.") parser.add_argument( "--no-detailed-test-id", dest='detailed_test_id', action="store_false", - help="Don't put paths into tests' names. " - "With this arg a test name will be a scenario name " - "e.g. sample.basic.helloworld.") + help="Don't prefix each test Suite name with its configuration path, " + "so it is the same as the appropriate Scenario name. " + "Also (for Ztest only), don't prefix each Ztest Case name with its Scenario name. " + "For example: 'kernel.common.timing' Scenario name, the same Suite name, " + "and 'sleep.usleep' test Case (where 'sleep' is its Ztest suite name " + "and 'usleep' is Ztest test name.") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -668,6 +699,12 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: help="Use the list of test scenarios under quarantine and run them" "to verify their current status.") + parser.add_argument( + "--quit-on-failure", + action="store_true", + help="""quit twister once there is build / run failure + """) + parser.add_argument( "--report-name", help="""Create a report with a custom name. @@ -884,6 +921,21 @@ def parse_arguments( if options.enable_coverage and not options.coverage_platform: options.coverage_platform = options.platform + if ( + (not options.coverage) + and (options.disable_coverage_aggregation or options.coverage_per_instance) + ): + logger.error("Enable coverage reporting to set its aggregation mode.") + sys.exit(1) + + if ( + options.coverage + and options.disable_coverage_aggregation and (not options.coverage_per_instance) + ): + logger.error("At least one coverage reporting mode should be enabled: " + "either aggregation, or per-instance, or both.") + sys.exit(1) + if options.coverage_formats: for coverage_format in options.coverage_formats.split(','): if coverage_format not in supported_coverage_formats[options.coverage_tool]: diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index c67ec07349aad..b9e688309328b 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -317,7 +317,7 @@ def _create_env(self): return env - def _update_instance_info(self, harness_status, handler_time): + def _update_instance_info(self, harness, handler_time): self.instance.execution_time = handler_time if not self.terminated and self.returncode != 0: self.instance.status = TwisterStatus.FAIL @@ -326,11 +326,13 @@ def _update_instance_info(self, harness_status, handler_time): else: # When a process is killed, the default handler returns 128 + SIGTERM # so in that case the return code itself is not meaningful - self.instance.reason = "Failed" - elif harness_status != TwisterStatus.NONE: - self.instance.status = harness_status - if harness_status == TwisterStatus.FAIL: - self.instance.reason = "Failed" + self.instance.reason = f"Failed (rc={self.returncode})" + self.instance.add_missing_case_status(TwisterStatus.BLOCK) + elif harness.status != TwisterStatus.NONE: + self.instance.status = harness.status + if harness.status == TwisterStatus.FAIL: + self.instance.reason = f"Failed harness:'{harness.reason}'" + self.instance.add_missing_case_status(TwisterStatus.BLOCK) else: self.instance.status = TwisterStatus.FAIL self.instance.reason = "Timeout" @@ -354,12 +356,9 @@ def handle(self, harness): return stderr_log = f"{self.instance.build_dir}/handler_stderr.log" - with ( - open(stderr_log, "w+") as stderr_log_fp, - subprocess.Popen( - command, stdout=subprocess.PIPE, stderr=stderr_log_fp, cwd=self.build_dir, env=env - ) as proc, - ): + with open(stderr_log, "w+") as stderr_log_fp, subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=stderr_log_fp, cwd=self.build_dir, env=env + ) as proc: logger.debug(f"Spawning BinaryHandler Thread for {self.name}") t = threading.Thread(target=self._output_handler, args=(proc, harness,), daemon=True) t.start() @@ -381,7 +380,7 @@ def handle(self, harness): if sys.stdout.isatty(): subprocess.call(["stty", "sane"], stdin=sys.stdout) - self._update_instance_info(harness.status, handler_time) + self._update_instance_info(harness, handler_time) self._final_handle_actions(harness, handler_time) @@ -570,6 +569,9 @@ def _create_command(self, runner, hardware): if runner in ("pyocd", "nrfjprog", "nrfutil"): command_extra_args.append("--dev-id") command_extra_args.append(board_id) + elif runner == "esp32": + command_extra_args.append("--esp-device") + command_extra_args.append(board_id) elif ( runner == "openocd" and product == "STM32 STLink" @@ -592,7 +594,7 @@ def _create_command(self, runner, hardware): # --probe=# select by probe index # --probe= select by probe serial number command.append(f"--probe={board_id}") - elif runner == "stm32cubeprogrammer": + elif runner == "stm32cubeprogrammer" and product != "BOOT-SERIAL": command.append(f"--tool-opt=sn={board_id}") # Receive parameters from runner_params field. @@ -608,13 +610,13 @@ def _create_command(self, runner, hardware): return command - def _update_instance_info(self, harness_status, handler_time, flash_error): + def _update_instance_info(self, harness, handler_time, flash_error): self.instance.execution_time = handler_time - if harness_status != TwisterStatus.NONE: - self.instance.status = harness_status - if harness_status == TwisterStatus.FAIL: - self.instance.reason = "Failed" - self.instance.add_missing_case_status(TwisterStatus.BLOCK, harness_status) + if harness.status != TwisterStatus.NONE: + self.instance.status = harness.status + if harness.status == TwisterStatus.FAIL: + self.instance.reason = f"Failed harness:'{harness.reason}'" + self.instance.add_missing_case_status(TwisterStatus.BLOCK, harness.status) elif not flash_error: self.instance.status = TwisterStatus.FAIL self.instance.reason = "Timeout" @@ -833,7 +835,7 @@ def handle(self, harness): handler_time = time.time() - start_time - self._update_instance_info(harness.status, handler_time, flash_error) + self._update_instance_info(harness, handler_time, flash_error) self._final_handle_actions(harness, handler_time) @@ -1060,9 +1062,9 @@ def _create_command(self, sysbuild_build_dir): return command - def _update_instance_info(self, harness_status, is_timeout): + def _update_instance_info(self, harness, is_timeout): if (self.returncode != 0 and not self.ignore_qemu_crash) or \ - harness_status == TwisterStatus.NONE: + harness.status == TwisterStatus.NONE: self.instance.status = TwisterStatus.FAIL if is_timeout: self.instance.reason = "Timeout" @@ -1098,10 +1100,11 @@ def handle(self, harness): is_timeout = False qemu_pid = None - with subprocess.Popen( + with open(self.stdout_fn, "w") as stdout_fp, \ + open(self.stderr_fn, "w") as stderr_fp, subprocess.Popen( command, - stdout=open(self.stdout_fn, "w"), - stderr=open(self.stderr_fn, "w"), + stdout=stdout_fp, + stderr=stderr_fp, cwd=self.build_dir ) as proc: logger.debug(f"Spawning QEMUHandler Thread for {self.name}") @@ -1139,7 +1142,7 @@ def handle(self, harness): logger.debug(f"return code from QEMU ({qemu_pid}): {self.returncode}") - self._update_instance_info(harness.status, is_timeout) + self._update_instance_info(harness, is_timeout) self._final_handle_actions(harness, 0) @@ -1240,9 +1243,9 @@ def _create_command(self, sysbuild_build_dir): return command - def _update_instance_info(self, harness_status, is_timeout): + def _update_instance_info(self, harness, is_timeout): if (self.returncode != 0 and not self.ignore_qemu_crash) or \ - harness_status == TwisterStatus.NONE: + harness.status == TwisterStatus.NONE: self.instance.status = TwisterStatus.FAIL if is_timeout: self.instance.reason = "Timeout" @@ -1424,7 +1427,7 @@ def handle(self, harness): os.close(self.pipe_handle) self.pipe_handle = None - self._update_instance_info(harness.status, is_timeout) + self._update_instance_info(harness, is_timeout) self._final_handle_actions(harness, 0) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index f7d0e51fae4fe..83b895d73b9fd 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -16,6 +16,8 @@ from collections import OrderedDict from enum import Enum +import junitparser.junitparser as junit +import yaml from pytest import ExitCode from twisterlib.constants import SUPPORTED_SIMS_IN_PYTEST from twisterlib.environment import PYTEST_PLUGIN_INSTALLED, ZEPHYR_BASE @@ -52,7 +54,8 @@ def __init__(self): self.capture_coverage = False self.next_pattern = 0 self.record = None - self.record_pattern = None + self.record_patterns = [] + self.record_merge = False self.record_as_json = None self.recording = [] self.ztest = False @@ -98,7 +101,8 @@ def configure(self, instance): self.ordered = config.get('ordered', True) self.record = config.get('record', {}) if self.record: - self.record_pattern = re.compile(self.record.get("regex", "")) + self.record_patterns = [re.compile(p) for p in self.record.get("regex", [])] + self.record_merge = self.record.get("merge", False) self.record_as_json = self.record.get("as_json") def build(self): @@ -124,17 +128,27 @@ def translate_record(self, record: dict) -> dict: record[k] = { 'ERROR': { 'msg': str(parse_error), 'doc': record[k] } } return record - def parse_record(self, line) -> re.Match: - match = None - if self.record_pattern: - match = self.record_pattern.search(line) + def parse_record(self, line) -> int: + match_cnt = 0 + for record_pattern in self.record_patterns: + match = record_pattern.search(line) if match: + match_cnt += 1 rec = self.translate_record( { k:v.strip() for k,v in match.groupdict(default="").items() } ) - self.recording.append(rec) - return match - # + if self.record_merge and len(self.recording) > 0: + for k,v in rec.items(): + if k in self.recording[0]: + if isinstance(self.recording[0][k], list): + self.recording[0][k].append(v) + else: + self.recording[0][k] = [self.recording[0][k], v] + else: + self.recording[0][k] = v + else: + self.recording.append(rec) + return match_cnt def process_test(self, line): @@ -388,11 +402,9 @@ def generate_command(self): '-s', '-v', f'--build-dir={self.running_dir}', f'--junit-xml={self.report_file}', - '--log-file-level=DEBUG', - '--log-file-format=%(asctime)s.%(msecs)d:%(levelname)s:%(name)s: %(message)s', - f'--log-file={self.pytest_log_file_path}', f'--platform={self.instance.platform.name}' ] + command.extend([os.path.normpath(os.path.join( self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root]) @@ -426,6 +438,9 @@ def generate_command(self): for fixture in handler.options.fixture: command.append(f'--twister-fixture={fixture}') + if handler.options.extra_test_args and handler.type_str == 'native': + command.append(f'--extra-test-args={shlex.join(handler.options.extra_test_args)}') + command.extend(pytest_args_yaml) if handler.options.pytest_args: @@ -513,9 +528,9 @@ def run_command(self, cmd, timeout): if proc.returncode in (ExitCode.INTERRUPTED, ExitCode.USAGE_ERROR, ExitCode.INTERNAL_ERROR): self.status = TwisterStatus.ERROR self.instance.reason = f'Pytest error - return code {proc.returncode}' - with open(self.pytest_log_file_path, 'w') as log_file: - log_file.write(shlex.join(cmd) + '\n\n') - log_file.write('\n'.join(self._output)) + with open(self.pytest_log_file_path, 'w') as log_file: + log_file.write(shlex.join(cmd) + '\n\n') + log_file.write('\n'.join(self._output)) @staticmethod def _update_command_with_env_dependencies(cmd): @@ -615,6 +630,35 @@ def _parse_report_file(self, report): self.instance.reason = 'No tests collected' +class Shell(Pytest): + def generate_command(self): + config = self.instance.testsuite.harness_config + pytest_root = [os.path.join(ZEPHYR_BASE, 'scripts', 'pylib', 'shell-twister-harness')] + config['pytest_root'] = pytest_root + + command = super().generate_command() + if test_shell_file := self._get_shell_commands_file(config): + command.append(f'--testdata={test_shell_file}') + else: + logger.warning('No shell commands provided') + return command + + def _get_shell_commands_file(self, harness_config): + if shell_commands := harness_config.get('shell_commands'): + test_shell_file = os.path.join(self.running_dir, 'test_shell.yml') + with open(test_shell_file, 'w') as f: + yaml.dump(shell_commands, f) + return test_shell_file + + test_shell_file = harness_config.get('shell_commands_file', 'test_shell.yml') + test_shell_file = os.path.join( + self.source_dir, os.path.expanduser(os.path.expandvars(test_shell_file)) + ) + if os.path.exists(test_shell_file): + return test_shell_file + return None + + class Gtest(Harness): ANSI_ESCAPE = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') _NAME_PATTERN = "[a-zA-Z_][a-zA-Z0-9_]*" @@ -754,12 +798,14 @@ def get_testcase(self, tc_name, phase, ts_name=None): """ ts_names = self.started_suites.keys() if ts_name: - if ts_name not in self.instance.testsuite.ztest_suite_names: - logger.warning(f"On {phase}: unexpected Ztest suite '{ts_name}' " - f"not present among: {self.instance.testsuite.ztest_suite_names}") + if self.trace and ts_name not in self.instance.testsuite.ztest_suite_names: + # This can happen if a ZTEST_SUITE name is macro-generated + # in the test source files, e.g. based on DT information. + logger.debug(f"{phase}: unexpected Ztest suite '{ts_name}' is " + f"not present among: {self.instance.testsuite.ztest_suite_names}") if ts_name not in self.detected_suite_names: if self.trace: - logger.debug(f"On {phase}: detected new Ztest suite '{ts_name}'") + logger.debug(f"{phase}: detected new Ztest suite '{ts_name}'") self.detected_suite_names.append(ts_name) ts_names = [ ts_name ] if ts_name in ts_names else [] @@ -767,71 +813,77 @@ def get_testcase(self, tc_name, phase, ts_name=None): for ts_name_ in ts_names: if self.started_suites[ts_name_]['count'] < (0 if phase == 'TS_SUM' else 1): continue - tc_fq_id = f"{self.id}.{ts_name_}.{tc_name}" + tc_fq_id = self.instance.compose_case_name(f"{ts_name_}.{tc_name}") if tc := self.instance.get_case_by_name(tc_fq_id): if self.trace: - logger.debug(f"On {phase}: Ztest case '{tc_name}' matched to '{tc_fq_id}") + logger.debug(f"{phase}: Ztest case '{tc_name}' matched to '{tc_fq_id}") return tc logger.debug( - f"On {phase}: Ztest case '{tc_name}' is not known" + f"{phase}: Ztest case '{tc_name}' is not known" f" in {self.started_suites} running suite(s)." ) - tc_id = f"{self.id}.{tc_name}" + tc_id = self.instance.compose_case_name(tc_name) return self.instance.get_case_or_create(tc_id) - def start_suite(self, suite_name): + def start_suite(self, suite_name, phase='TS_START'): if suite_name not in self.detected_suite_names: self.detected_suite_names.append(suite_name) - if suite_name not in self.instance.testsuite.ztest_suite_names: - logger.warning(f"Unexpected Ztest suite '{suite_name}'") + if self.trace and suite_name not in self.instance.testsuite.ztest_suite_names: + # This can happen if a ZTEST_SUITE name is macro-generated + # in the test source files, e.g. based on DT information. + logger.debug(f"{phase}: unexpected Ztest suite '{suite_name}' is " + f"not present among: {self.instance.testsuite.ztest_suite_names}") if suite_name in self.started_suites: if self.started_suites[suite_name]['count'] > 0: - logger.warning(f"Already STARTED '{suite_name}':{self.started_suites[suite_name]}") + # Either the suite restarts itself or unexpected state transition. + logger.warning(f"{phase}: already STARTED '{suite_name}':" + f"{self.started_suites[suite_name]}") elif self.trace: - logger.debug(f"START suite '{suite_name}'") + logger.debug(f"{phase}: START suite '{suite_name}'") self.started_suites[suite_name]['count'] += 1 self.started_suites[suite_name]['repeat'] += 1 else: self.started_suites[suite_name] = { 'count': 1, 'repeat': 0 } - def end_suite(self, suite_name, phase='', suite_status=None): + def end_suite(self, suite_name, phase='TS_END', suite_status=None): if suite_name in self.started_suites: if phase == 'TS_SUM' and self.started_suites[suite_name]['count'] == 0: return if self.started_suites[suite_name]['count'] < 1: logger.error( - f"Already ENDED {phase} suite '{suite_name}':{self.started_suites[suite_name]}" + f"{phase}: already ENDED suite '{suite_name}':{self.started_suites[suite_name]}" ) elif self.trace: - logger.debug(f"END {phase} suite '{suite_name}':{self.started_suites[suite_name]}") + logger.debug(f"{phase}: END suite '{suite_name}':{self.started_suites[suite_name]}") self.started_suites[suite_name]['count'] -= 1 elif suite_status == 'SKIP': - self.start_suite(suite_name) # register skipped suites at their summary end + self.start_suite(suite_name, phase) # register skipped suites at their summary end self.started_suites[suite_name]['count'] -= 1 else: - logger.warning(f"END {phase} suite '{suite_name}' without START detected") + logger.warning(f"{phase}: END suite '{suite_name}' without START detected") - def start_case(self, tc_name): + def start_case(self, tc_name, phase='TC_START'): if tc_name in self.started_cases: if self.started_cases[tc_name]['count'] > 0: - logger.warning(f"Already STARTED '{tc_name}':{self.started_cases[tc_name]}") + logger.warning(f"{phase}: already STARTED case " + f"'{tc_name}':{self.started_cases[tc_name]}") self.started_cases[tc_name]['count'] += 1 else: self.started_cases[tc_name] = { 'count': 1 } - def end_case(self, tc_name, phase=''): + def end_case(self, tc_name, phase='TC_END'): if tc_name in self.started_cases: if phase == 'TS_SUM' and self.started_cases[tc_name]['count'] == 0: return if self.started_cases[tc_name]['count'] < 1: logger.error( - f"Already ENDED {phase} case '{tc_name}':{self.started_cases[tc_name]}" + f"{phase}: already ENDED case '{tc_name}':{self.started_cases[tc_name]}" ) elif self.trace: - logger.debug(f"END {phase} case '{tc_name}':{self.started_cases[tc_name]}") + logger.debug(f"{phase}: END case '{tc_name}':{self.started_cases[tc_name]}") self.started_cases[tc_name]['count'] -= 1 elif phase != 'TS_SUM': - logger.warning(f"END {phase} case '{tc_name}' without START detected") + logger.warning(f"{phase}: END case '{tc_name}' without START detected") def handle(self, line): @@ -843,7 +895,7 @@ def handle(self, line): self.start_suite(test_suite_start_match.group("suite_name")) elif test_suite_end_match := re.search(self.test_suite_end_pattern, line): suite_name=test_suite_end_match.group("suite_name") - self.end_suite(suite_name, 'TS_END') + self.end_suite(suite_name) elif testcase_match := re.search(self.test_case_start_pattern, line): tc_name = testcase_match.group(2) tc = self.get_testcase(tc_name, 'TC_START') @@ -944,6 +996,142 @@ def build(self): logger.debug(f'Copying executable from {original_exe_path} to {new_exe_path}') shutil.copy(original_exe_path, new_exe_path) +class Ctest(Harness): + def configure(self, instance: TestInstance): + super().configure(instance) + self.running_dir = instance.build_dir + self.report_file = os.path.join(self.running_dir, 'report.xml') + self.ctest_log_file_path = os.path.join(self.running_dir, 'twister_harness.log') + self._output = [] + + def ctest_run(self, timeout): + assert self.instance is not None + try: + cmd = self.generate_command() + self.run_command(cmd, timeout) + except Exception as err: + logger.error(str(err)) + self.status = TwisterStatus.FAIL + self.instance.reason = str(err) + finally: + self.instance.record(self.recording) + self._update_test_status() + + def generate_command(self): + config = self.instance.testsuite.harness_config + handler: Handler = self.instance.handler + ctest_args_yaml = config.get('ctest_args', []) if config else [] + command = [ + 'ctest', + '--build-nocmake', + '--test-dir', + self.running_dir, + '--output-junit', + self.report_file, + '--output-log', + self.ctest_log_file_path, + '--output-on-failure', + ] + base_timeout = handler.get_test_timeout() + command.extend(['--timeout', str(base_timeout)]) + command.extend(ctest_args_yaml) + + if handler.options.ctest_args: + command.extend(handler.options.ctest_args) + + return command + + def run_command(self, cmd, timeout): + with subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) as proc: + try: + reader_t = threading.Thread(target=self._output_reader, args=(proc,), daemon=True) + reader_t.start() + reader_t.join(timeout) + if reader_t.is_alive(): + terminate_process(proc) + logger.warning('Timeout has occurred. Can be extended in testspec file. ' + f'Currently set to {timeout} seconds.') + self.instance.reason = 'Ctest timeout' + self.status = TwisterStatus.FAIL + proc.wait(timeout) + except subprocess.TimeoutExpired: + self.status = TwisterStatus.FAIL + proc.kill() + + if proc.returncode in (ExitCode.INTERRUPTED, ExitCode.USAGE_ERROR, ExitCode.INTERNAL_ERROR): + self.status = TwisterStatus.ERROR + self.instance.reason = f'Ctest error - return code {proc.returncode}' + with open(self.ctest_log_file_path, 'w') as log_file: + log_file.write(shlex.join(cmd) + '\n\n') + log_file.write('\n'.join(self._output)) + + def _output_reader(self, proc): + self._output = [] + while proc.stdout.readable() and proc.poll() is None: + line = proc.stdout.readline().decode().strip() + if not line: + continue + self._output.append(line) + logger.debug(f'CTEST: {line}') + self.parse_record(line) + proc.communicate() + + def _update_test_status(self): + if self.status == TwisterStatus.NONE: + self.instance.testcases = [] + try: + self._parse_report_file(self.report_file) + except Exception as e: + logger.error(f'Error when parsing file {self.report_file}: {e}') + self.status = TwisterStatus.FAIL + finally: + if not self.instance.testcases: + self.instance.init_cases() + + self.instance.status = self.status if self.status != TwisterStatus.NONE else \ + TwisterStatus.FAIL + if self.instance.status in [TwisterStatus.ERROR, TwisterStatus.FAIL]: + self.instance.reason = self.instance.reason or 'Ctest failed' + self.instance.add_missing_case_status(TwisterStatus.BLOCK, self.instance.reason) + + def _parse_report_file(self, report): + suite = junit.JUnitXml.fromfile(report) + if suite is None: + self.status = TwisterStatus.SKIP + self.instance.reason = 'No tests collected' + return + + assert isinstance(suite, junit.TestSuite) + + if suite.failures and suite.failures > 0: + self.status = TwisterStatus.FAIL + self.instance.reason = f"{suite.failures}/{suite.tests} ctest scenario(s) failed" + elif suite.errors and suite.errors > 0: + self.status = TwisterStatus.ERROR + self.instance.reason = 'Error during ctest execution' + elif suite.skipped and suite.skipped > 0: + self.status = TwisterStatus.SKIP + else: + self.status = TwisterStatus.PASS + self.instance.execution_time = suite.time + + for case in suite: + tc = self.instance.add_testcase(f"{self.id}.{case.name}") + tc.duration = case.time + if any(isinstance(r, junit.Failure) for r in case.result): + tc.status = TwisterStatus.FAIL + tc.output = case.system_out + elif any(isinstance(r, junit.Error) for r in case.result): + tc.status = TwisterStatus.ERROR + tc.output = case.system_out + elif any(isinstance(r, junit.Skipped) for r in case.result): + tc.status = TwisterStatus.SKIP + else: + tc.status = TwisterStatus.PASS class HarnessImporter: diff --git a/scripts/pylib/twister/twisterlib/package.py b/scripts/pylib/twister/twisterlib/package.py index 11566d6aeae6f..1a98ba07c18b4 100644 --- a/scripts/pylib/twister/twisterlib/package.py +++ b/scripts/pylib/twister/twisterlib/package.py @@ -11,11 +11,12 @@ class Artifacts: - + """Package the test artifacts into a tarball.""" def __init__(self, env): self.options = env.options def make_tarfile(self, output_filename, source_dirs): + """Create a tarball from the test artifacts.""" root = os.path.basename(self.options.outdir) with tarfile.open(output_filename, "w:bz2") as tar: tar.add(self.options.outdir, recursive=False) @@ -24,14 +25,21 @@ def make_tarfile(self, output_filename, source_dirs): tar.add(d, arcname=os.path.join(root, f)) def package(self): + """Package the test artifacts into a tarball.""" dirs = [] - with open(os.path.join(self.options.outdir, "twister.json")) as json_test_plan: + with open( + os.path.join(self.options.outdir, "twister.json"), encoding='utf-8' + ) as json_test_plan: jtp = json.load(json_test_plan) for t in jtp['testsuites']: if t['status'] != TwisterStatus.FILTER: p = t['platform'] normalized = p.replace("/", "_") - dirs.append(os.path.join(self.options.outdir, normalized, t['name'])) + dirs.append( + os.path.join( + self.options.outdir, normalized, t['toolchain'], t['name'] + ) + ) dirs.extend( [ diff --git a/scripts/pylib/twister/twisterlib/platform.py b/scripts/pylib/twister/twisterlib/platform.py index 325520d15130e..f960610ae1419 100644 --- a/scripts/pylib/twister/twisterlib/platform.py +++ b/scripts/pylib/twister/twisterlib/platform.py @@ -9,7 +9,10 @@ import logging import os import shutil +from argparse import Namespace +from itertools import groupby +import list_boards import scl from twisterlib.constants import SUPPORTED_SIMS from twisterlib.environment import ZEPHYR_BASE @@ -70,6 +73,7 @@ def __init__(self): # if no flash size is specified by the board, take a default of 512K self.flash = 512 self.supported = set() + self.binaries = [] self.arch = None self.vendor = "" @@ -83,28 +87,18 @@ def __init__(self): self.filter_data = dict() self.uart = "" self.resc = "" - self.qualifier = None - def load(self, board, target, aliases, data): + def load(self, board, target, aliases, data, variant_data): """Load the platform data from the board data and target data board: the board object as per the zephyr build system target: the target name of the board as per the zephyr build system aliases: list of aliases for the target - data: the data from the twister.yaml file for the target + data: the default data from the twister.yaml file for the board + variant_data: the target-specific data to replace the default data """ self.name = target self.aliases = aliases - # Get data for various targets and use the main board data as a - # defauly. Individual variant information will replace the default data - # provded in the main twister configuration for this board. - variants = data.get("variants", {}) - variant_data = {} - for alias in aliases: - variant_data = variants.get(alias, {}) - if variant_data: - break - self.normalized_name = self.name.replace("/", "_") self.sysbuild = variant_data.get("sysbuild", data.get("sysbuild", self.sysbuild)) self.twister = variant_data.get("twister", data.get("twister", self.twister)) @@ -114,15 +108,24 @@ def load(self, board, target, aliases, data): # if no flash size is specified by the board, take a default of 512K self.flash = variant_data.get("flash", data.get("flash", self.flash)) - testing = variant_data.get("testing", data.get("testing", {})) - self.timeout_multiplier = testing.get("timeout_multiplier", self.timeout_multiplier) - self.ignore_tags = testing.get("ignore_tags", self.ignore_tags) - self.only_tags = testing.get("only_tags", self.only_tags) + testing = data.get("testing", {}) + self.ignore_tags = testing.get("ignore_tags", []) + self.only_tags = testing.get("only_tags", []) self.default = testing.get("default", self.default) self.binaries = testing.get("binaries", []) + self.timeout_multiplier = testing.get("timeout_multiplier", self.timeout_multiplier) + + # testing data for variant + testing_var = variant_data.get("testing", data.get("testing", {})) + self.timeout_multiplier = testing_var.get("timeout_multiplier", self.timeout_multiplier) + self.ignore_tags = testing_var.get("ignore_tags", self.ignore_tags) + self.only_tags = testing_var.get("only_tags", self.only_tags) + self.default = testing_var.get("default", self.default) + self.binaries = testing_var.get("binaries", self.binaries) renode = testing.get("renode", {}) self.uart = renode.get("uart", "") self.resc = renode.get("resc", "") + self.supported = set() for supp_feature in variant_data.get("supported", data.get("supported", [])): for item in supp_feature.split(":"): @@ -149,18 +152,18 @@ def load(self, board, target, aliases, data): support_toolchain_variants = { # we don't provide defaults for 'arc' intentionally: some targets can't be built with GNU - # toolchain ("zephyr", "cross-compile", "xtools" options) and for some targets we haven't - # provided MWDT compiler / linker options in corresponding SoC file in Zephyr, so these - # targets can't be built with ARC MWDT toolchain ("arcmwdt" option) by Zephyr build system - # Instead for 'arc' we rely on 'toolchain' option in board yaml configuration. - "arm": ["zephyr", "gnuarmemb", "xtools", "armclang", "llvm"], + # toolchain ("zephyr", "cross-compile" options) and for some targets we haven't provided + # MWDT compiler / linker options in corresponding SoC file in Zephyr, so these targets + # can't be built with ARC MWDT toolchain ("arcmwdt" option) by Zephyr build system Instead + # for 'arc' we rely on 'toolchain' option in board yaml configuration. + "arm": ["zephyr", "gnuarmemb", "armclang", "llvm"], "arm64": ["zephyr", "cross-compile"], - "mips": ["zephyr", "xtools"], - "nios2": ["zephyr", "xtools"], + "mips": ["zephyr"], + "nios2": ["zephyr"], "riscv": ["zephyr", "cross-compile"], "posix": ["host", "llvm"], - "sparc": ["zephyr", "xtools"], - "x86": ["zephyr", "xtools", "llvm"], + "sparc": ["zephyr"], + "x86": ["zephyr", "llvm"], # Xtensa is not listed on purpose, since there is no single toolchain # that is supported on all board targets for xtensa. } @@ -184,3 +187,116 @@ def simulator_by_name(self, sim_name: str | None) -> Simulator | None: def __repr__(self): return f"<{self.name} on {self.arch}>" + + +def generate_platforms(board_roots, soc_roots, arch_roots): + """Initialize and yield all Platform instances. + + Using the provided board/soc/arch roots, determine the available + platform names and load the test platform description files. + + An exception is raised if not all platform files are valid YAML, + or if not all platform names are unique. + """ + alias2target = {} + target2board = {} + target2data = {} + dir2data = {} + legacy_files = [] + + lb_args = Namespace(board_roots=board_roots, soc_roots=soc_roots, arch_roots=arch_roots, + board=None, board_dir=None) + + for board in list_boards.find_v2_boards(lb_args).values(): + for board_dir in board.directories: + if board_dir in dir2data: + # don't load the same board data twice + continue + file = board_dir / "twister.yaml" + if file.is_file(): + data = scl.yaml_load_verify(file, Platform.platform_schema) + else: + data = None + dir2data[board_dir] = data + + legacy_files.extend( + file for file in board_dir.glob("*.yaml") if file.name != "twister.yaml" + ) + + for qual in list_boards.board_v2_qualifiers(board): + if board.revisions: + for rev in board.revisions: + if rev.name: + target = f"{board.name}@{rev.name}/{qual}" + alias2target[target] = target + if rev.name == board.revision_default: + alias2target[f"{board.name}/{qual}"] = target + if '/' not in qual and len(board.socs) == 1: + if rev.name == board.revision_default: + alias2target[f"{board.name}"] = target + alias2target[f"{board.name}@{rev.name}"] = target + else: + target = f"{board.name}/{qual}" + alias2target[target] = target + if '/' not in qual and len(board.socs) == 1 \ + and rev.name == board.revision_default: + alias2target[f"{board.name}"] = target + + target2board[target] = board + else: + target = f"{board.name}/{qual}" + alias2target[target] = target + if '/' not in qual and len(board.socs) == 1: + alias2target[board.name] = target + target2board[target] = board + + for board_dir, data in dir2data.items(): + if data is None: + continue + # Separate the default and variant information in the loaded board data. + # The default (top-level) data can be shared by multiple board targets; + # it will be overlaid by the variant data (if present) for each target. + variant_data = data.pop("variants", {}) + for variant in variant_data: + target = alias2target.get(variant) + if target is None: + continue + if target in target2data: + logger.error(f"Duplicate platform {target} in {board_dir}") + raise Exception(f"Duplicate platform identifier {target} found") + target2data[target] = variant_data[variant] + + # note: this inverse mapping will only be used for loading legacy files + target2aliases = {} + + for target, aliases in groupby(alias2target, alias2target.get): + aliases = list(aliases) + board = target2board[target] + + # Default board data always comes from the primary 'board.dir'. + # Other 'board.directories' can only supply variant data. + data = dir2data[board.dir] + if data is not None: + variant_data = target2data.get(target, {}) + + platform = Platform() + platform.load(board, target, aliases, data, variant_data) + yield platform + + target2aliases[target] = aliases + + for file in legacy_files: + data = scl.yaml_load_verify(file, Platform.platform_schema) + target = alias2target.get(data.get("identifier")) + if target is None: + continue + + board = target2board[target] + if dir2data[board.dir] is not None: + # all targets are already loaded for this board + logger.error(f"Duplicate platform {target} in {file.parent}") + raise Exception(f"Duplicate platform identifier {target} found") + + platform = Platform() + platform.load(board, target, target2aliases[target], data, variant_data={}) + yield platform diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index c64ddfefef3d0..8a11097b3919c 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -11,7 +11,7 @@ import xml.etree.ElementTree as ET from datetime import datetime from enum import Enum -from pathlib import PosixPath +from pathlib import Path from colorama import Fore from twisterlib.statuses import TwisterStatus @@ -29,6 +29,13 @@ def __str__(self): SKIP = 'skipped' +class ReportingJSONEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, Path): + return str(obj) + return super().default(obj) + + class Reporting: json_filters = { @@ -51,6 +58,7 @@ def __init__(self, plan, env) -> None: self.outdir = os.path.abspath(env.options.outdir) self.instance_fail_count = plan.instance_fail_count self.footprint = None + self.coverage_status = None @staticmethod @@ -171,6 +179,7 @@ def xunit_report_suites(self, json_file, filename): runnable = suite.get('runnable', 0) duration += float(handler_time) ts_status = TwisterStatus(suite.get('status')) + classname = Path(suite.get("name","")).name for tc in suite.get("testcases", []): status = TwisterStatus(tc.get('status')) reason = tc.get('reason', suite.get('reason', 'Unknown')) @@ -178,7 +187,6 @@ def xunit_report_suites(self, json_file, filename): tc_duration = tc.get('execution_time', handler_time) name = tc.get("identifier") - classname = ".".join(name.split(".")[:2]) fails, passes, errors, skips = self.xunit_testcase(eleTestsuite, name, classname, status, ts_status, reason, tc_duration, runnable, (fails, passes, errors, skips), log, True) @@ -191,6 +199,7 @@ def xunit_report_suites(self, json_file, filename): eleTestsuite.attrib['skipped'] = f"{skips}" eleTestsuite.attrib['tests'] = f"{total}" + ET.indent(eleTestsuites, space="\t", level=0) result = ET.tostring(eleTestsuites) with open(filename, 'wb') as report: report.write(result) @@ -252,6 +261,7 @@ def xunit_report(self, json_file, filename, selected_platform=None, full_report= ): continue if full_report: + classname = Path(ts.get("name","")).name for tc in ts.get("testcases", []): status = TwisterStatus(tc.get('status')) reason = tc.get('reason', ts.get('reason', 'Unknown')) @@ -259,7 +269,6 @@ def xunit_report(self, json_file, filename, selected_platform=None, full_report= tc_duration = tc.get('execution_time', handler_time) name = tc.get("identifier") - classname = ".".join(name.split(".")[:2]) fails, passes, errors, skips = self.xunit_testcase(eleTestsuite, name, classname, status, ts_status, reason, tc_duration, runnable, (fails, passes, errors, skips), log, True) @@ -280,6 +289,7 @@ def xunit_report(self, json_file, filename, selected_platform=None, full_report= eleTestsuite.attrib['skipped'] = f"{skips}" eleTestsuite.attrib['tests'] = f"{total}" + ET.indent(eleTestsuites, space="\t", level=0) result = ET.tostring(eleTestsuites) with open(filename, 'wb') as report: report.write(result) @@ -292,10 +302,6 @@ def json_report(self, filename, version="NA", platform=None, filters=None): else: report_options = self.env.non_default_options() - # Resolve known JSON serialization problems. - for k,v in report_options.items(): - report_options[k] = str(v) if type(v) in [PosixPath] else v - report = {} report["environment"] = {"os": os.name, "zephyr_version": version, @@ -355,6 +361,8 @@ def json_report(self, filename, version="NA", platform=None, filters=None): suite["used_rom"] = used_rom suite['retries'] = instance.retries + if instance.toolchain: + suite['toolchain'] = instance.toolchain if instance.dut: suite["dut"] = instance.dut @@ -364,7 +372,6 @@ def json_report(self, filename, version="NA", platform=None, filters=None): suite["available_rom"] = available_rom if instance.status in [TwisterStatus.ERROR, TwisterStatus.FAIL]: suite['status'] = instance.status - suite["reason"] = instance.reason # FIXME if os.path.exists(pytest_log): suite["log"] = self.process_log(pytest_log) @@ -374,6 +381,11 @@ def json_report(self, filename, version="NA", platform=None, filters=None): suite["log"] = self.process_log(device_log) else: suite["log"] = self.process_log(build_log) + + suite["reason"] = self.get_detailed_reason(instance.reason, suite["log"]) + # update the reason to get more details also in other reports (e.g. junit) + # where build log is not available + instance.reason = suite["reason"] elif instance.status == TwisterStatus.FILTER: suite["status"] = TwisterStatus.FILTER suite["reason"] = instance.reason @@ -479,7 +491,7 @@ def json_report(self, filename, version="NA", platform=None, filters=None): report["testsuites"] = suites with open(filename, 'w') as json_file: - json.dump(report, json_file, indent=4, separators=(',',':')) + json.dump(report, json_file, indent=4, separators=(',',':'), cls=ReportingJSONEncoder) def compare_metrics(self, filename): @@ -790,3 +802,55 @@ def target_report(self, json_file, outdir, suffix): self.json_report(json_platform_file + "_footprint.json", version=self.env.version, platform=platform.name, filters=self.json_filters['footprint.json']) + + def get_detailed_reason(self, reason: str, log: str) -> str: + if reason == 'CMake build failure': + if error_key := self._parse_cmake_build_failure(log): + return f"{reason} - {error_key}" + elif reason == 'Build failure': # noqa SIM102 + if error_key := self._parse_build_failure(log): + return f"{reason} - {error_key}" + return reason + + @staticmethod + def _parse_cmake_build_failure(log: str) -> str | None: + last_warning = 'no warning found' + lines = log.splitlines() + for i, line in enumerate(lines): + if "warning: " in line: + last_warning = line + elif "devicetree error: " in line: + return "devicetree error" + elif "fatal error: " in line: + return line[line.index('fatal error: ') :].strip() + elif "error: " in line: # error: Aborting due to Kconfig warnings + if "undefined symbol" in last_warning: + return last_warning[last_warning.index('undefined symbol') :].strip() + return last_warning + elif "CMake Error at" in line: + for next_line in lines[i + 1 :]: + if next_line.strip(): + return line + ' ' + next_line + return line + return None + + @staticmethod + def _parse_build_failure(log: str) -> str | None: + last_warning = '' + lines = log.splitlines() + for i, line in enumerate(lines): + if "undefined reference" in line: + return line[line.index('undefined reference') :].strip() + elif "error: ld returned" in line: + if last_warning: + return last_warning + elif "overflowed by" in lines[i - 1]: + return "ld.bfd: region overflowed" + elif "ld.bfd: warning: " in lines[i - 1]: + return "ld.bfd:" + lines[i - 1].split("ld.bfd:", 1)[-1] + return line + elif "error: " in line: + return line[line.index('error: ') :].strip() + elif ": in function " in line: + last_warning = line[line.index('in function') :].strip() + return None diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 287069f47d87e..0593cbc7fc3a4 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1,6 +1,6 @@ # vim: set syntax=python ts=4 : # -# Copyright (c) 2018-2024 Intel Corporation +# Copyright (c) 2018-2025 Intel Corporation # Copyright 2022 NXP # SPDX-License-Identifier: Apache-2.0 @@ -42,8 +42,9 @@ sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/build_helpers")) from domains import Domains +from twisterlib.coverage import run_coverage_instance from twisterlib.environment import TwisterEnv -from twisterlib.harness import HarnessImporter, Pytest +from twisterlib.harness import Ctest, HarnessImporter, Pytest from twisterlib.log_helper import log_command from twisterlib.platform import Platform from twisterlib.testinstance import TestInstance @@ -598,10 +599,13 @@ def run_build(self, args=None): log.write(log_msg) if log_msg: - overflow_found = re.findall( - "region `(FLASH|ROM|RAM|ICCM|DCCM|SRAM|dram\\d_\\d_seg)' overflowed by", - log_msg + pattern = ( + r"region `(FLASH|ROM|RAM|ICCM|DCCM|SRAM|" + r"dram\d_\d_seg|iram\d_\d_seg)' " + "overflowed by" ) + overflow_found = re.findall(pattern, log_msg) + imgtool_overflow_found = re.findall( r"Error: Image size \(.*\) \+ trailer \(.*\) exceeds requested size", log_msg @@ -651,6 +655,16 @@ def run_cmake(self, args="", filter_stages=None): f'-DPython3_EXECUTABLE={pathlib.Path(sys.executable).as_posix()}' ] + if self.instance.testsuite.harness == 'bsim': + cmake_args.extend([ + '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON', + '-DCONFIG_ASSERT=y', + '-DCONFIG_COVERAGE=y' + ]) + + if self.instance.toolchain: + cmake_args.append(f'-DZEPHYR_TOOLCHAIN_VARIANT={self.instance.toolchain}') + # If needed, run CMake using the package_helper script first, to only run # a subset of all cmake modules. This output will be used to filter # testcases, and the full CMake configuration will be run for @@ -823,7 +837,13 @@ def parse_generated(self, filter_stages=None): and self.env.options.west_flash is None ): logger.warning("Sysbuild test will be skipped. West must be used for flashing.") - return {os.path.join(self.platform.name, self.testsuite.name): True} + return { + os.path.join( + self.platform.name, + self.instance.toolchain, + self.testsuite.name + ): True + } if self.testsuite and self.testsuite.filter: try: @@ -839,9 +859,21 @@ def parse_generated(self, filter_stages=None): raise se if not ret: - return {os.path.join(self.platform.name, self.testsuite.name): True} + return { + os.path.join( + self.platform.name, + self.instance.toolchain, + self.testsuite.name + ): True + } else: - return {os.path.join(self.platform.name, self.testsuite.name): False} + return { + os.path.join( + self.platform.name, + self.instance.toolchain, + self.testsuite.name + ): False + } else: self.platform.filter_data = filter_data return filter_data @@ -1099,7 +1131,7 @@ def process(self, pipeline, done, message, lock, results): self.instance.handler.thread = None self.instance.handler.duts = None - next_op = 'report' + next_op = "coverage" if self.options.coverage else "report" additionals = { "status": self.instance.status, "reason": self.instance.reason @@ -1115,6 +1147,28 @@ def process(self, pipeline, done, message, lock, results): finally: self._add_to_pipeline(pipeline, next_op, additionals) + # Run per-instance code coverage + elif op == "coverage": + try: + logger.debug(f"Run coverage for '{self.instance.name}'") + self.instance.coverage_status, self.instance.coverage = \ + run_coverage_instance(self.options, self.instance) + next_op = 'report' + additionals = { + "status": self.instance.status, + "reason": self.instance.reason + } + except StatusAttributeError as sae: + logger.error(str(sae)) + self.instance.status = TwisterStatus.ERROR + reason = f"Incorrect status assignment on {op}" + self.instance.reason = reason + self.instance.add_missing_case_status(TwisterStatus.BLOCK, reason) + next_op = 'report' + additionals = {} + finally: + self._add_to_pipeline(pipeline, next_op, additionals) + # Report results and output progress to screen elif op == "report": try: @@ -1179,12 +1233,8 @@ def demangle(self, symbol_name): return symbol_name def determine_testcases(self, results): - yaml_testsuite_name = self.instance.testsuite.id - logger.debug(f"Determine test cases for test suite: {yaml_testsuite_name}") + logger.debug(f"Determine test cases for test suite: {self.instance.testsuite.id}") - logger.debug( - f"Test instance {self.instance.name} already has {len(self.instance.testcases)} cases." - ) new_ztest_unit_test_regex = re.compile(r"z_ztest_unit_test__([^\s]+?)__([^\s]*)") detected_cases = [] @@ -1207,17 +1257,27 @@ def determine_testcases(self, results): # The 1st capture group is new ztest suite name. # The 2nd capture group is new ztest unit test name. new_ztest_suite = m_[1] - if new_ztest_suite not in self.instance.testsuite.ztest_suite_names: - logger.warning( - f"Unexpected Ztest suite '{new_ztest_suite}' " + if self.trace and \ + new_ztest_suite not in self.instance.testsuite.ztest_suite_names: + # This can happen if a ZTEST_SUITE name is macro-generated + # in the test source files, e.g. based on DT information. + logger.debug( + f"Unexpected Ztest suite '{new_ztest_suite}' is " f"not present in: {self.instance.testsuite.ztest_suite_names}" ) test_func_name = m_[2].replace("test_", "", 1) - testcase_id = f"{yaml_testsuite_name}.{new_ztest_suite}.{test_func_name}" + testcase_id = self.instance.compose_case_name( + f"{new_ztest_suite}.{test_func_name}" + ) detected_cases.append(testcase_id) + logger.debug( + f"Test instance {self.instance.name} already has {len(self.instance.testcases)} " + f"testcase(s) known: {self.instance.testcases}" + ) if detected_cases: - logger.debug(f"Detected Ztest cases: [{', '.join(detected_cases)}] in {elf_file}") + logger.debug(f"Detected {len(detected_cases)} Ztest case(s): " + f"[{', '.join(detected_cases)}] in {elf_file}") tc_keeper = { tc.name: {'status': tc.status, 'reason': tc.reason} for tc in self.instance.testcases @@ -1225,16 +1285,17 @@ def determine_testcases(self, results): self.instance.testcases.clear() self.instance.testsuite.testcases.clear() - # When the old regex-based test case collection is fully deprecated, - # this will be the sole place where test cases get added to the test instance. - # Then we can further include the new_ztest_suite info in the testcase_id. - for testcase_id in detected_cases: testcase = self.instance.add_testcase(name=testcase_id) self.instance.testsuite.add_testcase(name=testcase_id) # Keep previous statuses and reasons tc_info = tc_keeper.get(testcase_id, {}) + if not tc_info and self.trace: + # Also happens when Ztest uses macroses, eg. DEFINE_TEST_VARIANT + logger.debug(f"Ztest case '{testcase_id}' discovered for " + f"'{self.instance.testsuite.source_dir_rel}' " + f"with {list(tc_keeper)}") testcase.status = tc_info.get('status', TwisterStatus.NONE) testcase.reason = tc_info.get('reason') @@ -1534,6 +1595,8 @@ def report_out(self, results): and hasattr(self.instance.handler, 'seed') and self.instance.handler.seed is not None ): more_info += "/seed: " + str(self.options.seed) + if instance.toolchain: + more_info += f" <{instance.toolchain}>" logger.info( f"{results.done - results.filtered_static:>{total_tests_width}}/{total_to_do}" f" {instance.platform.name:<25} {instance.testsuite.name:<50}" @@ -1708,6 +1771,8 @@ def run(self): # if isinstance(harness, Pytest): harness.pytest_run(instance.handler.get_test_timeout()) + elif isinstance(harness, Ctest): + harness.ctest_run(instance.handler.get_test_timeout()) else: instance.handler.handle(harness) @@ -1807,8 +1872,8 @@ def run(self): self.results.done = self.results.total - self.results.failed self.results.failed = 0 if self.options.retry_build_errors: - self.results.error = 0 self.results.done -= self.results.error + self.results.error = 0 else: self.results.done = self.results.filtered_static @@ -1927,6 +1992,11 @@ def pipeline_mgr(self, pipeline, done_queue, lock, results): pb = ProjectBuilder(instance, self.env, self.jobserver) pb.duts = self.duts pb.process(pipeline, done_queue, task, lock, results) + if self.env.options.quit_on_failure and \ + pb.instance.status in [TwisterStatus.FAIL, TwisterStatus.ERROR]: + with pipeline.mutex: + pipeline.queue.clear() + break return True else: @@ -1940,9 +2010,14 @@ def pipeline_mgr(self, pipeline, done_queue, lock, results): pb = ProjectBuilder(instance, self.env, self.jobserver) pb.duts = self.duts pb.process(pipeline, done_queue, task, lock, results) + if self.env.options.quit_on_failure and \ + pb.instance.status in [TwisterStatus.FAIL, TwisterStatus.ERROR]: + with pipeline.mutex: + pipeline.queue.clear() + break return True except Exception as e: - logger.error(f"General exception: {e}") + logger.error(f"General exception: {e}\n{traceback.format_exc()}") sys.exit(1) def execute(self, pipeline, done): diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index d7b658c454757..4822146d93ca1 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -1,6 +1,6 @@ # vim: set syntax=python ts=4 : # -# Copyright (c) 2018-2022 Intel Corporation +# Copyright (c) 2018-2025 Intel Corporation # Copyright 2022 NXP # Copyright (c) 2024 Arm Limited (or its affiliates). All rights reserved. # @@ -49,7 +49,7 @@ class TestInstance: __test__ = False - def __init__(self, testsuite, platform, outdir): + def __init__(self, testsuite, platform, toolchain, outdir): self.testsuite: TestSuite = testsuite self.platform: Platform = platform @@ -59,16 +59,21 @@ def __init__(self, testsuite, platform, outdir): self.metrics = dict() self.handler = None self.recording = None + self.coverage = None + self.coverage_status = None self.outdir = outdir self.execution_time = 0 self.build_time = 0 self.retries = 0 + self.toolchain = toolchain - self.name = os.path.join(platform.name, testsuite.name) + self.name = os.path.join(platform.name, toolchain, testsuite.name) self.dut = None if testsuite.detailed_test_id: - self.build_dir = os.path.join(outdir, platform.normalized_name, testsuite.name) + self.build_dir = os.path.join( + outdir, platform.normalized_name, self.toolchain, testsuite.name + ) else: # if suite is not in zephyr, # keep only the part after ".." in reconstructed dir structure @@ -76,6 +81,7 @@ def __init__(self, testsuite, platform, outdir): self.build_dir = os.path.join( outdir, platform.normalized_name, + self.toolchain, source_dir_rel, testsuite.name ) @@ -101,9 +107,12 @@ def record(self, recording, fname_csv="recording.csv"): self.recording.extend(recording) filename = os.path.join(self.build_dir, fname_csv) + fieldnames = set() + for r in self.recording: + fieldnames.update(r) with open(filename, 'w') as csvfile: cw = csv.DictWriter(csvfile, - fieldnames = self.recording[0].keys(), + fieldnames = sorted(list(fieldnames)), lineterminator = os.linesep, quoting = csv.QUOTE_NONNUMERIC) cw.writeheader() @@ -173,6 +182,9 @@ def __setstate__(self, d): def __lt__(self, other): return self.name < other.name + def compose_case_name(self, tc_name) -> str: + return self.testsuite.compose_case_name(tc_name) + def set_case_status_by_name(self, name, status, reason=None): tc = self.get_case_or_create(name) tc.status = status @@ -206,7 +218,16 @@ def get_case_or_create(self, name): def testsuite_runnable(testsuite, fixtures): can_run = False # console harness allows us to run the test and capture data. - if testsuite.harness in [ 'console', 'ztest', 'pytest', 'test', 'gtest', 'robot']: + if testsuite.harness in [ + 'console', + 'ztest', + 'pytest', + 'test', + 'gtest', + 'robot', + 'ctest', + 'shell' + ]: can_run = True # if we have a fixture that is also being supplied on the # command-line, then we need to run the test, not just build it. @@ -249,6 +270,8 @@ def setup_handler(self, env: TwisterEnv): handler.ready = True else: handler = Handler(self, "", *common_args) + if self.testsuite.harness == "ctest": + handler.ready = True self.handler = handler @@ -284,12 +307,13 @@ def check_runnable(self, target_ready = bool(self.testsuite.type == "unit" or \ self.platform.type == "native" or \ + self.testsuite.harness == "ctest" or \ (simulator and simulator.name in SUPPORTED_SIMS and \ simulator.name not in self.testsuite.simulation_exclude) or \ device_testing) # check if test is runnable in pytest - if self.testsuite.harness == 'pytest': + if self.testsuite.harness in ['pytest', 'shell']: target_ready = bool( filter == 'runnable' or simulator and simulator.name in SUPPORTED_SIMS_IN_PYTEST ) @@ -304,7 +328,7 @@ def check_runnable(self, if hardware_map: for h in hardware_map.duts: - if (h.platform == self.platform.name and + if (h.platform in self.platform.aliases and self.testsuite_runnable(self.testsuite, h.fixtures)): testsuite_runnable = True break diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 2857345f4e0ad..1742e15ee592b 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 # vim: set syntax=python ts=4 : # -# Copyright (c) 2018 Intel Corporation +# Copyright (c) 2018-2024 Intel Corporation # Copyright (c) 2024 Arm Limited (or its affiliates). All rights reserved. # # SPDX-License-Identifier: Apache-2.0 import collections import copy -import glob +import itertools import json import logging import os @@ -27,11 +27,10 @@ except ImportError: print("Install the anytree module to use the --test-tree option") -import list_boards import scl from twisterlib.config_parser import TwisterConfigParser from twisterlib.error import TwisterRuntimeError -from twisterlib.platform import Platform +from twisterlib.platform import Platform, generate_platforms from twisterlib.quarantine import Quarantine from twisterlib.statuses import TwisterStatus from twisterlib.testinstance import TestInstance @@ -195,7 +194,7 @@ def discover(self): self.add_configurations() num = self.add_testsuites(testsuite_filter=self.run_individual_testsuite) if num == 0: - raise TwisterRuntimeError("No test cases found at the specified location...") + raise TwisterRuntimeError("No testsuites found at the specified location...") if self.load_errors: raise TwisterRuntimeError( f"Found {self.load_errors} errors loading {num} test configurations." @@ -346,9 +345,13 @@ def handle_modules(self): def report(self): if self.options.test_tree: + if not self.options.detailed_test_id: + logger.info("Test tree is always shown with detailed test-id.") self.report_test_tree() return 0 elif self.options.list_tests: + if not self.options.detailed_test_id: + logger.info("Test list is always shown with detailed test-id.") self.report_test_list() return 0 elif self.options.list_tags: @@ -432,99 +435,21 @@ def info(what): sys.stdout.write(what + "\n") sys.stdout.flush() - def find_twister_data(self, board_data_list, board_aliases): - """Find the twister data for a board in the list of board data based on the aliases""" - for board_data in board_data_list: - if board_data.get('identifier') in board_aliases: - return board_data - def add_configurations(self): # Create a list of board roots as defined by the build system in general # Note, internally in twister a board root includes the `boards` folder # but in Zephyr build system, the board root is without the `boards` in folder path. board_roots = [Path(os.path.dirname(root)) for root in self.env.board_roots] - lb_args = Namespace(arch_roots=self.env.arch_roots, soc_roots=self.env.soc_roots, - board_roots=board_roots, board=None, board_dir=None) + soc_roots = self.env.soc_roots + arch_roots = self.env.arch_roots - known_boards = list_boards.find_v2_boards(lb_args) - bdirs = {} platform_config = self.test_config.get('platforms', {}) - # helper function to initialize and add platforms - def init_and_add_platforms(data, board, target, qualifier, aliases): - platform = Platform() - if not new_config_found: - data = self.find_twister_data(bdirs[board.dir], aliases) - if not data: - return - platform.load(board, target, aliases, data) - platform.qualifier = qualifier - if platform.name in [p.name for p in self.platforms]: - logger.error(f"Duplicate platform {platform.name} in {board.dir}") - raise Exception(f"Duplicate platform identifier {platform.name} found") + for platform in generate_platforms(board_roots, soc_roots, arch_roots): if not platform.twister: - return + continue self.platforms.append(platform) - for board in known_boards.values(): - new_config_found = False - # don't load the same board data twice - if not bdirs.get(board.dir): - datas = [] - for file in glob.glob(os.path.join(board.dir, "*.yaml")): - if os.path.basename(file) == "twister.yaml": - continue - try: - scp = TwisterConfigParser(file, Platform.platform_schema) - sdata = scp.load() - datas.append(sdata) - except Exception as e: - logger.error(f"Error loading {file}: {e!r}") - self.load_errors += 1 - continue - bdirs[board.dir] = datas - data = {} - if os.path.exists(board.dir / 'twister.yaml'): - try: - scp = TwisterConfigParser(board.dir / 'twister.yaml', Platform.platform_schema) - data = scp.load() - except Exception as e: - logger.error(f"Error loading {board.dir / 'twister.yaml'}: {e!r}") - self.load_errors += 1 - continue - new_config_found = True - - - - for qual in list_boards.board_v2_qualifiers(board): - - if board.revisions: - for rev in board.revisions: - if rev.name: - target = f"{board.name}@{rev.name}/{qual}" - aliases = [target] - if rev.name == board.revision_default: - aliases.append(f"{board.name}/{qual}") - if '/' not in qual and len(board.socs) == 1: - if rev.name == board.revision_default: - aliases.append(f"{board.name}") - aliases.append(f"{board.name}@{rev.name}") - else: - target = f"{board.name}/{qual}" - aliases = [target] - if '/' not in qual and len(board.socs) == 1 \ - and rev.name == board.revision_default: - aliases.append(f"{board.name}") - - init_and_add_platforms(data, board, target, qual, aliases) - else: - target = f"{board.name}/{qual}" - aliases = [target] - if '/' not in qual and len(board.socs) == 1: - aliases.append(board.name) - init_and_add_platforms(data, board, target, qual, aliases) - - for platform in self.platforms: if not platform_config.get('override_default_platforms', False): if platform.default: self.default_platforms.append(platform.name) @@ -551,18 +476,18 @@ def get_tests_list(self): for _, ts in self.testsuites.items(): if ts.tags.intersection(tag_filter): for case in ts.testcases: - testcases.append(case.name) + testcases.append(case.detailed_name) else: for _, ts in self.testsuites.items(): for case in ts.testcases: - testcases.append(case.name) + testcases.append(case.detailed_name) if exclude_tag := self.options.exclude_tag: for _, ts in self.testsuites.items(): if ts.tags.intersection(exclude_tag): for case in ts.testcases: - if case.name in testcases: - testcases.remove(case.name) + if case.detailed_name in testcases: + testcases.remove(case.detailed_name) return testcases def add_testsuites(self, testsuite_filter=None): @@ -571,7 +496,7 @@ def add_testsuites(self, testsuite_filter=None): for root in self.env.test_roots: root = os.path.abspath(root) - logger.debug(f"Reading test case configuration files under {root}...") + logger.debug(f"Reading testsuite configuration files under {root}...") for dirpath, _, filenames in os.walk(root, topdown=True): if self.SAMPLE_FILENAME in filenames: @@ -614,27 +539,15 @@ def add_testsuites(self, testsuite_filter=None): ) # convert to fully qualified names - _integration = [] - _platform_allow = [] - _platform_exclude = [] - for _ip in suite.integration_platforms: - if _ip in self.platform_names: - _integration.append(self.get_platform(_ip).name) - else: - logger.error(f"Platform {_ip} not found in the list of platforms") - suite.integration_platforms = _integration - for _pe in suite.platform_exclude: - if _pe in self.platform_names: - _platform_exclude.append(self.get_platform(_pe).name) - else: - logger.error(f"Platform {_pe} not found in the list of platforms") - suite.platform_exclude = _platform_exclude - for _pa in suite.platform_allow: - if _pa in self.platform_names: - _platform_allow.append(self.get_platform(_pa).name) - else: - logger.error(f"Platform {_pa} not found in the list of platforms") - suite.platform_allow = _platform_allow + suite.integration_platforms = self.verify_platforms_existence( + suite.integration_platforms, + f"integration_platforms in {suite.name}") + suite.platform_exclude = self.verify_platforms_existence( + suite.platform_exclude, + f"platform_exclude in {suite.name}") + suite.platform_allow = self.verify_platforms_existence( + suite.platform_allow, + f"platform_allow in {suite.name}") if suite.harness in ['ztest', 'test']: if subcases is None: @@ -706,11 +619,14 @@ def load_from_file(self, file, filter_platform=None): for ts in jtp.get("testsuites", []): logger.debug(f"loading {ts['name']}...") testsuite = ts["name"] + toolchain = ts["toolchain"] platform = self.get_platform(ts["platform"]) if filter_platform and platform.name not in filter_platform: continue - instance = TestInstance(self.testsuites[testsuite], platform, self.env.outdir) + instance = TestInstance( + self.testsuites[testsuite], platform, toolchain, self.env.outdir + ) if ts.get("run_id"): instance.run_id = ts.get("run_id") @@ -785,7 +701,6 @@ def check_platform(self, platform, platform_list): def apply_filters(self, **kwargs): - toolchain = self.env.toolchain platform_filter = self.options.platform vendor_filter = self.options.vendor exclude_platform = self.options.exclude_platform @@ -812,14 +727,14 @@ def apply_filters(self, **kwargs): emulation_platforms = False if all_filter: - logger.info("Selecting all possible platforms per test case") + logger.info("Selecting all possible platforms per testsuite scenario") # When --all used, any --platform arguments ignored platform_filter = [] elif not platform_filter and not emu_filter and not vendor_filter: - logger.info("Selecting default platforms per test case") + logger.info("Selecting default platforms per testsuite scenario") default_platforms = True elif emu_filter: - logger.info("Selecting emulation platforms per test case") + logger.info("Selecting emulation platforms per testsuite scenraio") emulation_platforms = True elif vendor_filter: vendor_platforms = True @@ -828,12 +743,7 @@ def apply_filters(self, **kwargs): if platform_filter: logger.debug(f"Checking platform filter: {platform_filter}") # find in aliases and rename - self.verify_platforms_existence(platform_filter, "platform_filter") - for pf in platform_filter: - logger.debug(f"Checking platform in filter: {pf}") - if pf in self.platform_names: - _platforms.append(self.get_platform(pf).name) - platform_filter = _platforms + platform_filter = self.verify_platforms_existence(platform_filter, "platform_filter") platforms = list(filter(lambda p: p.name in platform_filter, self.platforms)) elif emu_filter: platforms = list( @@ -862,7 +772,7 @@ def apply_filters(self, **kwargs): keyed_tests = {} - for ts_name, ts in self.testsuites.items(): + for _, ts in self.testsuites.items(): if ( ts.build_on_all and not platform_filter @@ -874,14 +784,10 @@ def apply_filters(self, **kwargs): filter(lambda item: item.name in ts.integration_platforms, self.platforms) ) if self.options.integration: - self.verify_platforms_existence( - ts.integration_platforms, f"{ts_name} - integration_platforms") platform_scope = integration_platforms else: # if not in integration mode, still add integration platforms to the list if not platform_filter: - self.verify_platforms_existence( - ts.integration_platforms, f"{ts_name} - integration_platforms") platform_scope = platforms + integration_platforms else: platform_scope = platforms @@ -898,7 +804,6 @@ def apply_filters(self, **kwargs): and not integration and platform_config.get('increased_platform_scope', True) ): - self.verify_platforms_existence(ts.platform_allow, f"{ts_name} - platform_allow") a = set(platform_scope) b = set(filter(lambda item: item.name in ts.platform_allow, self.platforms)) c = a.intersection(b) @@ -908,8 +813,21 @@ def apply_filters(self, **kwargs): ) # list of instances per testsuite, aka configurations. instance_list = [] - for plat in platform_scope: - instance = TestInstance(ts, plat, self.env.outdir) + for itoolchain, plat in itertools.product( + ts.integration_toolchains or [None], platform_scope + ): + if itoolchain: + toolchain = itoolchain + elif plat.arch in ['posix', 'unit']: + # workaround until toolchain variant in zephyr is overhauled and improved. + if self.env.toolchain in ['llvm']: + toolchain = 'llvm' + else: + toolchain = 'host' + else: + toolchain = "zephyr" if not self.env.toolchain else self.env.toolchain + + instance = TestInstance(ts, plat, toolchain, self.env.outdir) instance.run = instance.check_runnable( self.options, self.hwm @@ -976,31 +894,25 @@ def apply_filters(self, **kwargs): if not force_platform: if ts.arch_allow and plat.arch not in ts.arch_allow: - instance.add_filter("Not in test case arch allow list", Filters.TESTSUITE) + instance.add_filter("Not in testsuite arch allow list", Filters.TESTSUITE) if ts.arch_exclude and plat.arch in ts.arch_exclude: - instance.add_filter("In test case arch exclude", Filters.TESTSUITE) + instance.add_filter("In testsuite arch exclude", Filters.TESTSUITE) if ts.vendor_allow and plat.vendor not in ts.vendor_allow: instance.add_filter( - "Not in test suite vendor allow list", + "Not in testsuite vendor allow list", Filters.TESTSUITE ) if ts.vendor_exclude and plat.vendor in ts.vendor_exclude: - instance.add_filter("In test suite vendor exclude", Filters.TESTSUITE) + instance.add_filter("In testsuite vendor exclude", Filters.TESTSUITE) if ts.platform_exclude and plat.name in ts.platform_exclude: - # works only when we have all platforms parsed, -p limits parsing... - if not platform_filter: - self.verify_platforms_existence( - ts.platform_exclude, - f"{ts_name} - platform_exclude" - ) - instance.add_filter("In test case platform exclude", Filters.TESTSUITE) + instance.add_filter("In testsuite platform exclude", Filters.TESTSUITE) if ts.toolchain_exclude and toolchain in ts.toolchain_exclude: - instance.add_filter("In test case toolchain exclude", Filters.TOOLCHAIN) + instance.add_filter("In testsuite toolchain exclude", Filters.TOOLCHAIN) if platform_filter and plat.name not in platform_filter: instance.add_filter("Command line platform filter", Filters.CMD_LINE) @@ -1023,10 +935,11 @@ def apply_filters(self, **kwargs): ) if not force_toolchain \ - and toolchain and (toolchain not in plat.supported_toolchains) \ - and "host" not in plat.supported_toolchains \ - and ts.type != 'unit': - instance.add_filter("Not supported by the toolchain", Filters.PLATFORM) + and toolchain and (toolchain not in plat.supported_toolchains): + instance.add_filter( + f"Not supported by the toolchain: {toolchain}", + Filters.PLATFORM + ) if plat.ram < ts.min_ram: instance.add_filter("Not enough RAM", Filters.PLATFORM) @@ -1042,7 +955,10 @@ def apply_filters(self, **kwargs): if ts.depends_on: dep_intersection = ts.depends_on.intersection(set(plat.supported)) if dep_intersection != set(ts.depends_on): - instance.add_filter("No hardware support", Filters.PLATFORM) + instance.add_filter( + f"No hardware support for {set(ts.depends_on)-dep_intersection}", + Filters.PLATFORM + ) if plat.flash < ts.min_flash: instance.add_filter("Not enough FLASH", Filters.PLATFORM) @@ -1261,12 +1177,16 @@ def verify_platforms_existence(self, platform_names_to_verify, log_info=""): as platform_allow or integration_platforms options) is correct. If not - log and raise error. """ + _platforms = [] for platform in platform_names_to_verify: if platform in self.platform_names: - continue + p = self.get_platform(platform) + if p: + _platforms.append(p.name) else: logger.error(f"{log_info} - unrecognized platform - {platform}") sys.exit(2) + return _platforms def create_build_dir_links(self): """ diff --git a/scripts/pylib/twister/twisterlib/testsuite.py b/scripts/pylib/twister/twisterlib/testsuite.py index 62637172c0285..a99e9c88e091a 100644 --- a/scripts/pylib/twister/twisterlib/testsuite.py +++ b/scripts/pylib/twister/twisterlib/testsuite.py @@ -386,6 +386,10 @@ def __init__(self, name=None, testsuite=None): self.output = "" self.freeform = False + @property + def detailed_name(self) -> str: + return TestSuite.get_case_name_(self.testsuite, self.name, detailed=True) + @property def status(self) -> TwisterStatus: return self._status @@ -477,20 +481,31 @@ def load(self, data): 'Harness config error: console harness defined without a configuration.' ) + @staticmethod + def get_case_name_(test_suite, tc_name, detailed=True) -> str: + return f"{test_suite.id}.{tc_name}" \ + if test_suite and detailed and not test_suite.detailed_test_id else f"{tc_name}" + + @staticmethod + def compose_case_name_(test_suite, tc_name) -> str: + return f"{test_suite.id}.{tc_name}" \ + if test_suite and test_suite.detailed_test_id else f"{tc_name}" + + def compose_case_name(self, tc_name) -> str: + return self.compose_case_name_(self, tc_name) + def add_subcases(self, data, parsed_subcases=None, suite_names=None): testcases = data.get("testcases", []) if testcases: for tc in testcases: - self.add_testcase(name=f"{self.id}.{tc}") + self.add_testcase(name=self.compose_case_name(tc)) else: if not parsed_subcases: self.add_testcase(self.id, freeform=True) else: # only add each testcase once - for sub in set(parsed_subcases): - name = f"{self.id}.{sub}" - self.add_testcase(name) - + for tc in set(parsed_subcases): + self.add_testcase(name=self.compose_case_name(tc)) if suite_names: self.ztest_suite_names = suite_names diff --git a/scripts/pylib/twister/twisterlib/twister_main.py b/scripts/pylib/twister/twisterlib/twister_main.py index 5644b98113196..2c847e49bb119 100644 --- a/scripts/pylib/twister/twisterlib/twister_main.py +++ b/scripts/pylib/twister/twisterlib/twister_main.py @@ -147,7 +147,7 @@ def main(options: argparse.Namespace, default_options: argparse.Namespace): continue logger.debug( f"{i.platform.name:<25} {i.testsuite.name:<50}" - f" {Fore.YELLOW}SKIPPED{Fore.RESET}: {i.reason}" + f" {Fore.YELLOW}FILTERED{Fore.RESET}: {i.reason}" ) report = Reporting(tplan, env) @@ -214,10 +214,10 @@ def main(options: argparse.Namespace, default_options: argparse.Namespace): report.summary(runner.results, options.disable_unrecognized_section_test, duration) - coverage_completed = True - if options.coverage: + report.coverage_status = True + if options.coverage and not options.disable_coverage_aggregation: if not options.build_only: - coverage_completed = run_coverage(tplan, options) + report.coverage_status, report.coverage = run_coverage(options, tplan) else: logger.info("Skipping coverage report generation due to --build-only.") @@ -238,13 +238,17 @@ def main(options: argparse.Namespace, default_options: argparse.Namespace): artifacts = Artifacts(env) artifacts.package() - logger.info("Run completed") if ( runner.results.failed or runner.results.error or (tplan.warnings and options.warnings_as_errors) - or (options.coverage and not coverage_completed) + or (options.coverage and not report.coverage_status) ): + if env.options.quit_on_failure: + logger.info("twister aborted because of a failure/error") + else: + logger.info("Run completed") return 1 + logger.info("Run completed") return 0 diff --git a/scripts/requirements-base.txt b/scripts/requirements-base.txt index 3938fa7b349e7..1f898b1cd2693 100644 --- a/scripts/requirements-base.txt +++ b/scripts/requirements-base.txt @@ -23,6 +23,7 @@ pylink-square pyserial requests semver +tqdm # for ram/rom reports anytree diff --git a/scripts/requirements-build-test.txt b/scripts/requirements-build-test.txt index c0f808880fbad..0d540dd05c3e4 100644 --- a/scripts/requirements-build-test.txt +++ b/scripts/requirements-build-test.txt @@ -19,3 +19,6 @@ mypy # used for mocking functions in pytest mock>=4.0.1 + +# used for JUnit XML parsing in CTest harness +junitparser diff --git a/scripts/requirements-extras.txt b/scripts/requirements-extras.txt index 0dd10bfbf52fa..884a8970cb576 100644 --- a/scripts/requirements-extras.txt +++ b/scripts/requirements-extras.txt @@ -18,18 +18,8 @@ lpc_checksum # used by scripts/build/gen_cfb_font_header.py - helper script for user Pillow>=10.0 -# can be used to sign a Zephyr application binary for consumption by a bootloader -imgtool>=2.1.0 - -# used by nanopb module to generate sources from .proto files -grpcio-tools>=1.47.0 -protobuf>=3.20.3 - # used by scripts/release/bug_bash.py for generating top ten bug squashers PyGithub # used to generate devicetree dependency graphs graphviz - -# used to generate CBOR encoders and decoders, e.g. lwm2m_senml_cbor. -zcbor>=0.8.0 diff --git a/scripts/schemas/build-schema.yml b/scripts/schemas/build-schema.yml index 5086afbb25b17..078cca85782f5 100644 --- a/scripts/schemas/build-schema.yml +++ b/scripts/schemas/build-schema.yml @@ -56,6 +56,17 @@ mapping: type: seq sequence: - type: str + images: + type: seq + sequence: + - type: map + mapping: + name: + type: str + source-dir: + type: str + type: + type: str kconfig: type: map mapping: @@ -71,6 +82,19 @@ mapping: type: seq sequence: - type: str + llext-edk: + type: map + mapping: + cflags: + type: seq + sequence: + - type: str + file: + type: str + include-dirs: + type: seq + sequence: + - type: str sysbuild: type: bool toolchain: diff --git a/scripts/schemas/patch-schema.yml b/scripts/schemas/patch-schema.yml new file mode 100644 index 0000000000000..f74a589f706ad --- /dev/null +++ b/scripts/schemas/patch-schema.yml @@ -0,0 +1,115 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +# A pykwalify schema for basic validation of the patches.yml format. + +# The schema for individual patch objects +schema;patch-schema: + type: seq + sequence: + - type: map + mapping: + + # The path to the patch file, relative to patch-base + # E.g. zephyr/kernel-pipe-fix-not-k-no-wait-and-ge-min-xfer-bytes.patch + path: + required: true + type: str + + # The SHA-256 checksum of the patch file + # e.g. e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + sha256sum: + required: true + type: str + pattern: "^[0-9a-f]{64}$" + + # The path of the module the patch is for, relative to the west workspace + # e.g. zephyr, or bootloader/mcuboot + module: + required: true + type: str + + # The name of the primary author of the patch, e.g. Kermit D. Frog + author: + required: true + type: str + + # The email address of the primary author of the patch, e.g. itsnoteasy@being.gr + email: + required: true + type: str + pattern: ".+@.+" + + # The date the patch was created, in ISO 8601 date format YYYY-MM-DD + date: + required: true + type: date + format: "%Y-%m-%d" + + # Whether the patch should be submitted upstream + upstreamable: + type: bool + default: true + + # The URL of the upstream pull request to merge the patch + # e.g. https://github.com/zephyrproject-rtos/zephyr/pull/24486 + merge-pr: + type: str + pattern: "^https?://" + + # The URL of the upstream issue associated with the patch, such as an enhancement issue + # or bug report, e.g. https://github.com/zephyrproject-rtos/zephyr/issues/24485 + issue: + type: str + pattern: "^https?://" + + # Whether the associated merge-pr has been merged + merge-status: + type: bool + + # The SHA-1 hash of the upstream git commit incorporating the associated merge-pr + # e.g. af926ae728c78affa89cbc1de811ab4211ed0f69 + merge-commit: + type: str + pattern: "^[0-9a-f]{40}" + + # The date the associated merge-pr was merged, in ISO 8601 date format YYYY-MM-DD + merge-date: + type: date + format: "%Y-%m-%d" + + # The command used to apply the change represented by the patch + apply-command: + type: str + default: "git apply" + + # Comments useful to other developers about the patch, + # e.g. "This is a workaround for xyz and probably should not go upstream" + comments: + type: str + + # Custom field that may be used for any purpose. For example, if the chosen apply-patch + # command is able to filter based on semantic versioning and a particular patch file + # only applies to version 1.2.3, one could specify e.g. custom: [1, 2, 3]. + # This field may be of any type and is not validated. + custom: + type: any + +# The top-level schema for patches.yml files +type: map +mapping: + + # The list of patch objects + patches: + include: patch-schema + + # The command used to undo local changes to each module when "west patch clean" is run + checkout-command: + type: str + default: "git checkout ." + + # The command used to clean each module when "west patch clean" is run + clean-command: + type: str + default: "git clean -d -f -x" diff --git a/scripts/schemas/snippet-schema.yml b/scripts/schemas/snippet-schema.yml index 307e27be2ca43..319097c58f8d7 100644 --- a/scripts/schemas/snippet-schema.yml +++ b/scripts/schemas/snippet-schema.yml @@ -13,6 +13,8 @@ schema;append-schema: type: str EXTRA_CONF_FILE: type: str + SB_EXTRA_CONF_FILE: + type: str DTS_EXTRA_CPPFLAGS: type: str diff --git a/scripts/schemas/twister/testsuite-schema.yaml b/scripts/schemas/twister/testsuite-schema.yaml index 7f167899fc307..55bfbcb7b9cce 100644 --- a/scripts/schemas/twister/testsuite-schema.yaml +++ b/scripts/schemas/twister/testsuite-schema.yaml @@ -89,6 +89,11 @@ schema;scenario-schema: required: false sequence: - type: str + "integration_toolchains": + type: seq + required: false + sequence: + - type: str "ignore_faults": type: bool required: false @@ -102,6 +107,20 @@ schema;scenario-schema: type: map required: false mapping: + "shell_commands_file": + type: str + required: false + "shell_commands": + type: seq + required: false + sequence: + - type: map + mapping: + "command": + type: str + required: true + "expected": + type: str "type": type: str required: false @@ -125,6 +144,11 @@ schema;scenario-schema: type: str enum: ["function", "class", "module", "package", "session"] required: false + "ctest_args": + type: seq + required: false + sequence: + - type: str "regex": type: seq required: false @@ -141,8 +165,13 @@ schema;scenario-schema: required: false mapping: "regex": - type: str + type: seq required: true + sequence: + - type: str + "merge": + type: bool + required: false "as_json": type: seq required: false diff --git a/scripts/snippets.py b/scripts/snippets.py index 0cdc0d31e1348..d725f08891e0a 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -48,11 +48,11 @@ class Snippet: appends: Appends = field(default_factory=_new_append) board2appends: Dict[str, Appends] = field(default_factory=_new_board2appends) - def process_data(self, pathobj: Path, snippet_data: dict): + def process_data(self, pathobj: Path, snippet_data: dict, sysbuild: bool): '''Process the data in a snippet.yml file, after it is loaded into a python object and validated by pykwalify.''' def append_value(variable, value): - if variable in ('EXTRA_DTC_OVERLAY_FILE', 'EXTRA_CONF_FILE'): + if variable in ('SB_EXTRA_CONF_FILE', 'EXTRA_DTC_OVERLAY_FILE', 'EXTRA_CONF_FILE'): path = pathobj.parent / value if not path.is_file(): _err(f'snippet file {pathobj}: {variable}: file not found: {path}') @@ -62,14 +62,18 @@ def append_value(variable, value): _err(f'unknown append variable: {variable}') for variable, value in snippet_data.get('append', {}).items(): - self.appends[variable].append(append_value(variable, value)) + if (sysbuild is True and variable[0:3] == 'SB_') or \ + (sysbuild is False and variable[0:3] != 'SB_'): + self.appends[variable].append(append_value(variable, value)) for board, settings in snippet_data.get('boards', {}).items(): if board.startswith('/') and not board.endswith('/'): _err(f"snippet file {pathobj}: board {board} starts with '/', so " "it must end with '/' to use a regular expression") for variable, value in settings.get('append', {}).items(): - self.board2appends[board][variable].append( - append_value(variable, value)) + if (sysbuild is True and variable[0:3] == 'SB_') or \ + (sysbuild is False and variable[0:3] != 'SB_'): + self.board2appends[board][variable].append( + append_value(variable, value)) class Snippets(UserDict): '''Type for all the information we have discovered about all snippets. @@ -212,6 +216,8 @@ def parse_args(): parser.add_argument('--cmake-out', type=Path, help='''file to write cmake output to; include() this file after calling this script''') + parser.add_argument('--sysbuild', action="store_true", + help='''set if this is running as sysbuild''') return parser.parse_args() def setup_logging(): @@ -234,7 +240,7 @@ def process_snippets(args: argparse.Namespace) -> Snippets: # Process each path in snippet_root in order, adjusting # snippets as needed for each one. for root in args.snippet_root: - process_snippets_in(root, snippets) + process_snippets_in(root, snippets, args.sysbuild) return snippets @@ -250,11 +256,11 @@ def find_snippets_in_roots(requested_snippets, snippet_roots) -> Snippets: # Process each path in snippet_root in order, adjusting # snippets as needed for each one. for root in snippet_roots: - process_snippets_in(root, snippets) + process_snippets_in(root, snippets, False) return snippets -def process_snippets_in(root_dir: Path, snippets: Snippets) -> None: +def process_snippets_in(root_dir: Path, snippets: Snippets, sysbuild: bool) -> None: '''Process snippet.yml files in *root_dir*, updating *snippets* as needed.''' @@ -276,7 +282,7 @@ def process_snippets_in(root_dir: Path, snippets: Snippets) -> None: name = snippet_data['name'] if name not in snippets: snippets[name] = Snippet(name=name) - snippets[name].process_data(snippet_yml, snippet_data) + snippets[name].process_data(snippet_yml, snippet_data, sysbuild) snippets.paths.add(snippet_yml) def load_snippet_yml(snippet_yml: Path) -> dict: diff --git a/scripts/tests/twister/conftest.py b/scripts/tests/twister/conftest.py index bc391ad5e3d54..7c91be6ffc55d 100644 --- a/scripts/tests/twister/conftest.py +++ b/scripts/tests/twister/conftest.py @@ -90,7 +90,7 @@ def instances_fixture(class_testplan, platforms_list, all_testsuites_dict, tmpdi platform = class_testplan.get_platform("demo_board_2") instance_list = [] for _, testcase in all_testsuites_dict.items(): - instance = TestInstance(testcase, platform, class_testplan.outdir) + instance = TestInstance(testcase, platform, 'zephyr', class_testplan.outdir) instance_list.append(instance) class_testplan.add_instances(instance_list) return class_testplan.instances diff --git a/scripts/tests/twister/pytest_integration/test_harness_pytest.py b/scripts/tests/twister/pytest_integration/test_harness_pytest.py index 5e3d92535f238..1233a732304ad 100644 --- a/scripts/tests/twister/pytest_integration/test_harness_pytest.py +++ b/scripts/tests/twister/pytest_integration/test_harness_pytest.py @@ -18,16 +18,18 @@ def testinstance() -> TestInstance: testsuite = TestSuite('.', 'samples/hello', 'unit.test') testsuite.harness_config = {} + testsuite.harness = 'pytest' testsuite.ignore_faults = False testsuite.sysbuild = False platform = Platform() - testinstance = TestInstance(testsuite, platform, 'outdir') + testinstance = TestInstance(testsuite, platform, 'zephyr', 'outdir') testinstance.handler = mock.Mock() testinstance.handler.options = mock.Mock() testinstance.handler.options.verbose = 1 testinstance.handler.options.fixture = ['fixture1:option1', 'fixture2'] testinstance.handler.options.pytest_args = None + testinstance.handler.options.extra_test_args = [] testinstance.handler.type_str = 'native' return testinstance @@ -72,6 +74,15 @@ def test_pytest_command_extra_args(testinstance: TestInstance): assert c in command +def test_pytest_command_extra_test_args(testinstance: TestInstance): + pytest_harness = Pytest() + extra_test_args = ['-stop_at=3', '-no-rt'] + testinstance.handler.options.extra_test_args = extra_test_args + pytest_harness.configure(testinstance) + command = pytest_harness.generate_command() + assert f'--extra-test-args={extra_test_args[0]} {extra_test_args[1]}' in command + + def test_pytest_command_extra_args_in_options(testinstance: TestInstance): pytest_harness = Pytest() pytest_args_from_yaml = '--extra-option' diff --git a/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_1.yaml b/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_1.yaml index b801812080c9b..fd48fa43d979b 100644 --- a/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_1.yaml +++ b/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_1.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_2.yaml b/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_2.yaml index 7336ba1c2f4c7..78f7c3892cc21 100644 --- a/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_2.yaml +++ b/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_2.yaml @@ -5,7 +5,6 @@ arch: x86 toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_3.yaml b/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_3.yaml index 57118726f3c84..2897ea8c13004 100644 --- a/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_3.yaml +++ b/scripts/tests/twister/test_data/boards/1_level/2_level/board_config_3.yaml @@ -5,7 +5,6 @@ arch: arm toolchain: - zephyr - gnuarmemb - - xtools ram: 256 flash: 1024 supported: diff --git a/scripts/tests/twister/test_handlers.py b/scripts/tests/twister/test_handlers.py index de2ac883df081..e4710060a35e3 100644 --- a/scripts/tests/twister/test_handlers.py +++ b/scripts/tests/twister/test_handlers.py @@ -510,8 +510,8 @@ def test_binaryhandler_create_env( TESTDATA_6 = [ (TwisterStatus.NONE, False, 2, True, TwisterStatus.FAIL, 'Valgrind error', False), - (TwisterStatus.NONE, False, 1, False, TwisterStatus.FAIL, 'Failed', False), - (TwisterStatus.FAIL, False, 0, False, TwisterStatus.FAIL, 'Failed', False), + (TwisterStatus.NONE, False, 1, False, TwisterStatus.FAIL, 'Failed (rc=1)', False), + (TwisterStatus.FAIL, False, 0, False, TwisterStatus.FAIL, "Failed harness:'foobar'", False), ('success', False, 0, False, 'success', 'Unknown', False), (TwisterStatus.NONE, True, 1, True, TwisterStatus.FAIL, 'Timeout', True), ] @@ -540,8 +540,9 @@ def test_binaryhandler_update_instance_info( handler.returncode = returncode missing_mock = mock.Mock() handler.instance.add_missing_case_status = missing_mock + mocked_harness = mock.Mock(status=harness_status, reason="foobar") - handler._update_instance_info(harness_status, handler_time) + handler._update_instance_info(mocked_harness, handler_time) assert handler.instance.execution_time == handler_time @@ -1189,7 +1190,7 @@ def test_devicehandler_create_command( TESTDATA_14 = [ ('success', False, 'success', 'Unknown', False), - (TwisterStatus.FAIL, False, TwisterStatus.FAIL, 'Failed', True), + (TwisterStatus.FAIL, False, TwisterStatus.FAIL, "Failed harness:'foobar'", True), (TwisterStatus.ERROR, False, TwisterStatus.ERROR, 'Unknown', True), (TwisterStatus.NONE, True, TwisterStatus.NONE, 'Unknown', False), (TwisterStatus.NONE, False, TwisterStatus.FAIL, 'Timeout', True), @@ -1213,8 +1214,9 @@ def test_devicehandler_update_instance_info( handler_time = 59 missing_mock = mock.Mock() handler.instance.add_missing_case_status = missing_mock + mocked_harness = mock.Mock(status=harness_status, reason="foobar") - handler._update_instance_info(harness_status, handler_time, flash_error) + handler._update_instance_info(mocked_harness, handler_time, flash_error) assert handler.instance.execution_time == handler_time @@ -1716,12 +1718,13 @@ def test_qemuhandler_update_instance_info( ): mocked_instance.add_missing_case_status = mock.Mock() mocked_instance.reason = self_instance_reason + mocked_harness = mock.Mock(status=harness_status, reason="foobar") handler = QEMUHandler(mocked_instance, 'build', mock.Mock()) handler.returncode = self_returncode handler.ignore_qemu_crash = self_ignore_qemu_crash - handler._update_instance_info(harness_status, is_timeout) + handler._update_instance_info(mocked_harness, is_timeout) assert handler.instance.status == expected_status assert handler.instance.reason == expected_reason diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index 7e0fca79677ab..bc529932eefbb 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -30,6 +30,7 @@ Test, ) from twisterlib.statuses import TwisterStatus +from twisterlib.testsuite import TestSuite from twisterlib.testinstance import TestInstance GTEST_START_STATE = " RUN " @@ -60,26 +61,77 @@ def process_logs(harness, logs): TEST_DATA_RECORDING = [ - ([""], "^START:(?P.*):END", [], None), - (["START:bar:STOP"], "^START:(?P.*):END", [], None), - (["START:bar:END"], "^START:(?P.*):END", [{"foo": "bar"}], None), + ([""], ["^START:(?P.*):END"], [], None, None), + (["START:bar:STOP"], ["^START:(?P.*):END"], [], None, None), + (["START:bar:END"], ["^START:(?P.*):END"], [{"foo": "bar"}], None, None), ( ["START:bar:baz:END"], - "^START:(?P.*):(?P.*):END", + ["^START:(?P.*):(?P.*):END"], [{"foo": "bar", "boo": "baz"}], None, + None, + ), + ( + ["START:bar:END"], + ["^(START:(?P[a-z]+):END)|(START:(?P[0-9]+):END)"], + [{"foo": "bar", "boo": ""}], + None, + None, + ), + ( + ["START:bar:baz:END"], + ["^START:(?P.*):baz:END", "^START:bar:(?P.*):END"], + [{"foo": "bar"}, {"boo": "baz"}], + None, + None, + ), + ( + ["START:bar:END", "START:123:END"], + ["^START:(?P[a-z]+):END", "^START:(?P[0-9]+):END"], + [{"foo": "bar"}, {"boo": "123"}], + None, + None, + ), + ( + ["START:bar:END", "START:123:END"], + ["^START:(?P[a-z]+):END", "^START:(?P[0-9]+):END"], + [{"foo": "bar"}, {"foo": "123"}], + None, + None, + ), + ( + ["START:bar:END", "START:123:END"], + ["^START:(?P[a-z]+):END", "^START:(?P[0-9]+):END"], + [{"foo": ["bar", "123"]}], + None, + True, + ), + ( + ["START:bar:baz:END"], + ["^START:(?P.*):baz:END", "^START:bar:(?P.*):END"], + [{"foo": "bar", "boo": "baz"}], + None, + True, + ), + ( + ["START:bar:baz:END"], + ["^START:(?P.*):baz:END", "^START:bar:(?P.*):END"], + [{"foo": ["bar", "baz"]}], + None, + True, ), ( ["START:bar:baz:END", "START:may:jun:END"], - "^START:(?P.*):(?P.*):END", + ["^START:(?P.*):(?P.*):END"], [{"foo": "bar", "boo": "baz"}, {"foo": "may", "boo": "jun"}], None, + None, ), - (["START:bar:END"], "^START:(?P.*):END", [{"foo": "bar"}], []), - (["START:bar:END"], "^START:(?P.*):END", [{"foo": "bar"}], ["boo"]), + (["START:bar:END"], ["^START:(?P.*):END"], [{"foo": "bar"}], [], None), + (["START:bar:END"], ["^START:(?P.*):END"], [{"foo": "bar"}], ["boo"], None), ( ["START:bad_json:END"], - "^START:(?P.*):END", + ["^START:(?P.*):END"], [ { "foo": { @@ -91,37 +143,66 @@ def process_logs(harness, logs): } ], ["foo"], + None, ), - (["START::END"], "^START:(?P.*):END", [{"foo": {}}], ["foo"]), + (["START::END"], ["^START:(?P.*):END"], [{"foo": {}}], ["foo"], None), ( ['START: {"one":1, "two":2} :END'], - "^START:(?P.*):END", + ["^START:(?P.*):END"], [{"foo": {"one": 1, "two": 2}}], ["foo"], + None, ), ( ['START: {"one":1, "two":2} :STOP:oops:END'], - "^START:(?P.*):STOP:(?P.*):END", + ["^START:(?P.*):STOP:(?P.*):END"], [{"foo": {"one": 1, "two": 2}, "boo": "oops"}], ["foo"], + None, ), ( ['START: {"one":1, "two":2} :STOP:{"oops":0}:END'], - "^START:(?P.*):STOP:(?P.*):END", + ["^START:(?P.*):STOP:(?P.*):END"], [{"foo": {"one": 1, "two": 2}, "boo": {"oops": 0}}], ["foo", "boo"], + None, + ), + ( + ['START: {"one":1, "two":2} :STOP:{"oops":0}:END'], + ["^START:(?P.*):STOP:.*:END", + "^START:.*:STOP:(?P.*):END" + ], + [{"foo": {"one": 1, "two": 2}}, {"boo": {"oops": 0}}], + ["foo", "boo"], + None, + ), + ( + ['START: {"one":1, "two":2} :STOP:{"oops":0}:END'], + ["^START:(?P.*):STOP:.*:END", + "^START:.*:STOP:(?P.*):END" + ], + [{"foo": [{"one": 1, "two": 2}, {"oops": 0}]}], + ["foo"], + True, ), ] @pytest.mark.parametrize( - "lines, pattern, expected_records, as_json", + "lines, patterns, expected_records, as_json, merge", TEST_DATA_RECORDING, ids=[ "empty", "no match", "match 1 field", "match 2 fields", + "2 or-ed groups one miss", + "one line, two patters, match 2 fields -> 2 records", + "two lines, two patters -> 2 records", + "two lines, two patters same field -> 2 same records", + "two lines, two patters same field merge -> 1 records 2 values", + "one line, two patters, match 2 fields, merge -> 1 record", + "one line, two patters, match 1 field, merge -> 1 record list", "match 2 records", "as_json empty", "as_json no such field", @@ -130,13 +211,16 @@ def process_logs(harness, logs): "simple json", "plain field and json field", "two json fields", + "two json fields in two patterns -> 2 records", + "two json fields in two patterns merge -> 1 records 2 items", ], ) -def test_harness_parse_record(lines, pattern, expected_records, as_json): +def test_harness_parse_record(lines, patterns, expected_records, as_json, merge): harness = Harness() - harness.record = {"regex": pattern} - harness.record_pattern = re.compile(pattern) + harness.record = {"regex": patterns} + harness.record_patterns = [re.compile(p) for p in patterns] + harness.record_merge = merge harness.record_as_json = as_json if as_json is not None: harness.record["as_json"] = as_json @@ -206,7 +290,7 @@ def test_robot_configure(tmp_path): outdir.mkdir() instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir ) instance.testsuite.harness_config = { "robot_testsuite": "/path/to/robot/test", @@ -237,7 +321,7 @@ def test_robot_handle(tmp_path): outdir.mkdir() instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir ) handler = Robot() @@ -287,7 +371,7 @@ def test_robot_run_robot_test(tmp_path, caplog, exp_out, returncode, expected_st outdir.mkdir() instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir ) instance.build_dir = "build_dir" @@ -341,7 +425,7 @@ def test_console_configure(tmp_path, type, num_patterns): outdir.mkdir() instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir ) instance.testsuite.harness_config = { "type": type, @@ -402,7 +486,7 @@ def test_console_handle( outdir.mkdir() instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir ) console = Console() @@ -464,7 +548,7 @@ def test_pytest__generate_parameters_for_hardware(tmp_path, pty_value, hardware_ outdir.mkdir() instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir ) handler = mock.Mock() @@ -562,7 +646,7 @@ def test_pytest_run(tmp_path, caplog): outdir.mkdir() instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir ) instance.handler = handler @@ -594,6 +678,7 @@ def test_get_harness(name): TEST_DATA_7 = [ ( + True, "", "Running TESTSUITE suite_name", ["suite_name"], @@ -604,17 +689,19 @@ def test_get_harness(name): TwisterStatus.NONE, ), ( - "On TC_START: Ztest case 'testcase' is not known in {} running suite(s)", + True, + "TC_START: Ztest case 'testcase' is not known in {} running suite(s)", "START - test_testcase", [], {}, - { 'test_id.testcase': { 'count': 1 } }, + { 'dummy.test_id.testcase': { 'count': 1 } }, TwisterStatus.STARTED, True, TwisterStatus.NONE ), ( - "On TC_END: Ztest case 'example' is not known in {} running suite(s)", + True, + "TC_END: Ztest case 'example' is not known in {} running suite(s)", "PASS - test_example in 0 seconds", [], {}, @@ -624,7 +711,8 @@ def test_get_harness(name): TwisterStatus.NONE, ), ( - "On TC_END: Ztest case 'example' is not known in {} running suite(s)", + True, + "TC_END: Ztest case 'example' is not known in {} running suite(s)", "SKIP - test_example in 0 seconds", [], {}, @@ -634,7 +722,8 @@ def test_get_harness(name): TwisterStatus.NONE, ), ( - "On TC_END: Ztest case 'example' is not known in {} running suite(s)", + True, + "TC_END: Ztest case 'example' is not known in {} running suite(s)", "FAIL - test_example in 0 seconds", [], {}, @@ -644,21 +733,34 @@ def test_get_harness(name): TwisterStatus.NONE, ), ( - "not a ztest and no state for test_id", + True, + "not a ztest and no state for dummy.test_id", + "START - test_testcase", + [], + {}, + { 'dummy.test_id.testcase': { 'count': 1 } }, + TwisterStatus.PASS, + False, + TwisterStatus.PASS, + ), + ( + False, + "not a ztest and no state for dummy.test_id", "START - test_testcase", [], {}, - { 'test_id.testcase': { 'count': 1 } }, + { 'testcase': { 'count': 1 } }, TwisterStatus.PASS, False, TwisterStatus.PASS, ), ( - "not a ztest and no state for test_id", + True, + "not a ztest and no state for dummy.test_id", "START - test_testcase", [], {}, - { 'test_id.testcase': { 'count': 1 } }, + { 'dummy.test_id.testcase': { 'count': 1 } }, TwisterStatus.FAIL, False, TwisterStatus.FAIL, @@ -667,12 +769,12 @@ def test_get_harness(name): @pytest.mark.parametrize( - "exp_out, line, exp_suite_name, exp_started_suites, exp_started_cases, exp_status, ztest, state", + "detailed_id, exp_out, line, exp_suite_name, exp_started_suites, exp_started_cases, exp_status, ztest, state", TEST_DATA_7, - ids=["testsuite", "testcase", "pass", "skip", "failed", "ztest pass", "ztest fail"], + ids=["testsuite", "testcase", "pass", "skip", "failed", "ztest pass", "ztest pass short id", "ztest fail"], ) def test_test_handle( - tmp_path, caplog, exp_out, line, + tmp_path, caplog, detailed_id, exp_out, line, exp_suite_name, exp_started_suites, exp_started_cases, exp_status, ztest, state ): @@ -682,24 +784,28 @@ def test_test_handle( mock_platform.name = "mock_platform" mock_platform.normalized_name = "mock_platform" - mock_testsuite = mock.Mock(id="id", testcases=[]) - mock_testsuite.name = "mock_testsuite" + mock_testsuite = mock.Mock(id="dummy.test_id", testcases=[]) + mock_testsuite.name = "dummy_suite/dummy.test_id" mock_testsuite.harness_config = {} mock_testsuite.ztest_suite_names = [] - - outdir = tmp_path / "gtest_out" - outdir.mkdir() - - instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir - ) + mock_testsuite.detailed_test_id = detailed_id + mock_testsuite.source_dir_rel = "dummy_suite" + mock_testsuite.compose_case_name.return_value = TestSuite.compose_case_name_(mock_testsuite, "testcase") + + outdir = tmp_path / "ztest_out" + with mock.patch('twisterlib.testsuite.TestSuite.get_unique', return_value="dummy_suite"): + instance = TestInstance( + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir + ) + instance.handler = mock.Mock(options=mock.Mock(verbose=0), type_str="handler_type") test_obj = Test() test_obj.configure(instance) - test_obj.id = "test_id" + test_obj.id = "dummy.test_id" test_obj.ztest = ztest test_obj.status = state - test_obj.id = "test_id" + test_obj.started_cases = {} + # Act test_obj.handle(line) @@ -730,7 +836,7 @@ def gtest(tmp_path): outdir.mkdir() instance = TestInstance( - testsuite=mock_testsuite, platform=mock_platform, outdir=outdir + testsuite=mock_testsuite, platform=mock_platform, toolchain='zephyr', outdir=outdir ) harness = Gtest() diff --git a/scripts/tests/twister/test_platform.py b/scripts/tests/twister/test_platform.py index c4b9858d8b1fb..cdbfd15d20c56 100644 --- a/scripts/tests/twister/test_platform.py +++ b/scripts/tests/twister/test_platform.py @@ -11,10 +11,13 @@ import mock import pytest +from contextlib import nullcontext +from pykwalify.errors import SchemaError + ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister")) -from twisterlib.platform import Platform, Simulator +from twisterlib.platform import Platform, Simulator, generate_platforms TESTDATA_1 = [ @@ -129,3 +132,363 @@ def xtest_platform_load(platform_text, expected_data, expected_repr): assert att == v assert platform.__repr__() == expected_repr + + +TESTDATA_2 = [ + ( + ['m0'], + None, + { + 'p1e1/s1', 'p1e2/s1', 'p2/s1', 'p3@A/s2/c1', 'p3@B/s2/c1', + }, + ), + ( + ['m0', 'm1'], + None, + { + 'p1e1/s1', 'p1e2/s1', 'p2/s1', 'p3@A/s2/c1', 'p3@B/s2/c1', + 'p1e1/s1/v1', 'p1e1/s1/v2', 'p1e2/s1/v1', 'p2/s1/v1', + }, + ), + ( + ['m0', 'm1', 'm2'], + None, + { + 'p1e1/s1', 'p1e2/s1', 'p2/s1', 'p3@A/s2/c1', 'p3@B/s2/c1', + 'p1e1/s1/v1', 'p1e1/s1/v2', 'p1e2/s1/v1', 'p2/s1/v1', + 'p3@A/s2/c2', 'p3@B/s2/c2', 'p4/s1', + }, + ), + ( + ['m0', 'm3'], + Exception("Duplicate platform identifier p1e1/s1 found"), + None, + ), + ( + ['m0', 'm1', 'm4'], + Exception("Duplicate platform identifier p1e2/s1/v1 found"), + None, + ), + ( + ['m0', 'm5'], + SchemaError(), # Unknown message as this is raised externally + None, + ), +] + +@pytest.mark.parametrize( + 'roots, expected_exception, expected_platform_names', + TESTDATA_2, + ids=[ + 'default board root', + '1 extra board root', + '2 extra board roots', + '1 extra board root, duplicate platform', + '2 extra board roots, duplicate platform', + '1 extra board root, malformed yaml', + ] +) +def test_generate_platforms( + tmp_path, + roots, + expected_exception, + expected_platform_names, +): + tmp_files = { + 'm0/boards/zephyr/p1/board.yml': """\ +boards: + - name: p1e1 + vendor: zephyr + socs: + - name: s1 + - name: p1e2 + vendor: zephyr + socs: + - name: s1 +""", + 'm0/boards/zephyr/p1/twister.yaml': """\ +type: native +arch: x86 +variants: + p1e1: + twister: False + p1e2: + sysbuild: True +""", + 'm0/boards/zephyr/p2/board.yml': """\ +boards: + - name: p2 + vendor: zephyr + socs: + - name: s1 +""", + 'm0/boards/zephyr/p2/p2.yaml': """\ +identifier: p2/s1 +type: sim +arch: x86 +vendor: vendor2 +testing: + default: True +""", + 'm0/boards/arm/p3/board.yml': """\ +board: + name: p3 + vendor: arm + revision: + format: letter + default: "A" + revisions: + - name: "A" + - name: "B" + socs: + - name: s2 +""", + 'm0/boards/arm/p3/twister.yaml': """\ +type: unit +arch: arm +vendor: vendor3 +sysbuild: True +variants: + p3/s2/c1: + testing: + timeout_multiplier: 2.71828 + p3@B/s2/c1: + testing: + timeout_multiplier: 3.14159 +""", + 'm0/soc/zephyr/soc.yml': """\ +family: + - name: zephyr + series: + - name: zephyr_testing + socs: + - name: s1 + - name: s2 + cpuclusters: + - name: c1 +""", + 'm1/boards/zephyr/p1e1/board.yml': """\ +board: + extend: p1e1 + variants: + - name: v1 + qualifier: s1 + - name: v2 + qualifier: s1 +""", + 'm1/boards/zephyr/p1e1/twister.yaml': """\ +variants: + p1e1/s1/v1: + testing: + default: True +""", + 'm1/boards/zephyr/p1e2/board.yml': """\ +board: + extend: p1e2 + variants: + - name: v1 + qualifier: s1 +""", + 'm1/boards/zephyr/p2/board.yml': """\ +board: + extend: p2 + variants: + - name: v1 + qualifier: s1 +""", + 'm1/boards/zephyr/p2/p2_s1_v1.yaml': """\ +identifier: p2/s1/v1 +""", + 'm2/boards/misc/board.yml': """\ +boards: + - extend: p3 + - name: p4 + vendor: misc + socs: + - name: s1 +""", + 'm2/boards/misc/twister.yaml': """\ +type: qemu +arch: riscv +vendor: vendor4 +simulation: + - name: qemu +variants: + p3@A/s2/c2: + sysbuild: False +""", + 'm2/soc/zephyr/soc.yml': """\ +socs: + - extend: s2 + cpuclusters: + - name: c2 +""", + 'm3/boards/zephyr/p1e1/board.yml': """\ +board: + extend: p1e1 +""", + 'm3/boards/zephyr/p1e1/twister.yaml': """\ +variants: + p1e1/s1: + name: Duplicate Platform +""", + 'm4/boards/zephyr/p1e2/board.yml': """\ +board: + extend: p2 +""", + 'm4/boards/zephyr/p1e2/p1e2_s1_v1.yaml': """\ +identifier: p1e2/s1/v1 +""", + 'm5/boards/zephyr/p2/p2-2.yaml': """\ +testing: + ć#@%!#!#^#@%@:1.0 +identifier: p2_2 +type: sim +arch: x86 +vendor: vendor2 +""", + 'm5/boards/zephyr/p2/board.yml': """\ +board: + extend: p2 +""", + } + + for filename, content in tmp_files.items(): + (tmp_path / filename).parent.mkdir(parents=True, exist_ok=True) + (tmp_path / filename).write_text(content) + + roots = list(map(tmp_path.joinpath, roots)) + with pytest.raises(type(expected_exception)) if \ + expected_exception else nullcontext() as exception: + platforms = list(generate_platforms(board_roots=roots, soc_roots=roots, arch_roots=roots)) + + if expected_exception: + if expected_exception.args: + assert str(expected_exception) == str(exception.value) + return + + platform_names = {platform.name for platform in platforms} + assert len(platforms) == len(platform_names) + assert platform_names == expected_platform_names + + expected_data = { + 'p1e1/s1': { + 'aliases': ['p1e1/s1', 'p1e1'], + # m0/boards/zephyr/p1/board.yml + 'vendor': 'zephyr', + # m0/boards/zephyr/p1/twister.yaml (base + variant) + 'twister': False, + 'arch': 'x86', + 'type': 'native', + }, + 'p1e2/s1': { + 'aliases': ['p1e2/s1', 'p1e2'], + # m0/boards/zephyr/p1/board.yml + 'vendor': 'zephyr', + # m0/boards/zephyr/p1/twister.yaml (base + variant) + 'sysbuild': True, + 'arch': 'x86', + 'type': 'native', + }, + 'p1e1/s1/v1': { + 'aliases': ['p1e1/s1/v1'], + # m0/boards/zephyr/p1/board.yml + 'vendor': 'zephyr', + # m0/boards/zephyr/p1/twister.yaml (base) + # m1/boards/zephyr/p1e1/twister.yaml (variant) + 'default': True, + 'arch': 'x86', + 'type': 'native', + }, + 'p1e1/s1/v2': { + 'aliases': ['p1e1/s1/v2'], + # m0/boards/zephyr/p1/board.yml + 'vendor': 'zephyr', + # m0/boards/zephyr/p1/twister.yaml (base) + 'arch': 'x86', + 'type': 'native', + }, + 'p1e2/s1/v1': { + 'aliases': ['p1e2/s1/v1'], + # m0/boards/zephyr/p1/board.yml + 'vendor': 'zephyr', + # m0/boards/zephyr/p1/twister.yaml (base) + 'arch': 'x86', + 'type': 'native', + }, + 'p2/s1': { + 'aliases': ['p2/s1', 'p2'], + # m0/boards/zephyr/p2/board.yml + 'vendor': 'zephyr', + # m0/boards/zephyr/p2/p2.yaml + 'default': True, + 'arch': 'x86', + 'type': 'sim', + }, + 'p2/s1/v1': { + 'aliases': ['p2/s1/v1'], + # m0/boards/zephyr/p2/board.yml + 'vendor': 'zephyr', + # m1/boards/zephyr/p2/p2_s1_v1.yaml + }, + 'p3@A/s2/c1': { + 'aliases': ['p3@A/s2/c1', 'p3/s2/c1'], + # m0/boards/arm/p3/board.yml + 'vendor': 'arm', + # m0/boards/arm/p3/twister.yaml (base + variant) + 'sysbuild': True, + 'timeout_multiplier': 2.71828, + 'arch': 'arm', + 'type': 'unit', + }, + 'p3@B/s2/c1': { + 'aliases': ['p3@B/s2/c1'], + # m0/boards/arm/p3/board.yml + 'vendor': 'arm', + # m0/boards/arm/p3/twister.yaml (base + variant) + 'sysbuild': True, + 'timeout_multiplier': 3.14159, + 'arch': 'arm', + 'type': 'unit', + }, + 'p3@A/s2/c2': { + 'aliases': ['p3@A/s2/c2', 'p3/s2/c2'], + # m0/boards/arm/p3/board.yml + 'vendor': 'arm', + # m0/boards/arm/p3/twister.yaml (base) + # m2/boards/misc/twister.yaml (variant) + 'sysbuild': False, + 'arch': 'arm', + 'type': 'unit', + }, + 'p3@B/s2/c2': { + 'aliases': ['p3@B/s2/c2'], + # m0/boards/arm/p3/board.yml + 'vendor': 'arm', + # m0/boards/arm/p3/twister.yaml (base) + 'sysbuild': True, + 'arch': 'arm', + 'type': 'unit', + }, + 'p4/s1': { + 'aliases': ['p4/s1', 'p4'], + # m2/boards/misc/board.yml + 'vendor': 'misc', + # m2/boards/misc/twister.yaml (base) + 'arch': 'riscv', + 'type': 'qemu', + 'simulators': [Simulator({'name': 'qemu'})], + 'simulation': 'qemu', + }, + } + + init_platform = Platform() + for platform in platforms: + expected_platform_data = expected_data[platform.name] + for attr, default in vars(init_platform).items(): + if attr in {'name', 'normalized_name', 'supported_toolchains'}: + continue + expected = expected_platform_data.get(attr, default) + actual = getattr(platform, attr, None) + assert expected == actual, \ + f"expected '{platform}.{attr}' to be '{expected}', was '{actual}'" diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index 16c3c5d73e364..63894e14aedd2 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -381,6 +381,7 @@ def mock_popen(*args, **kwargs): '-DSB_CONFIG_COMPILER_WARNINGS_AS_ERRORS=y', '-DEXTRA_GEN_EDT_ARGS=--edtlib-Werror', '-Gdummy_generator', f'-DPython3_EXECUTABLE={pathlib.Path(sys.executable).as_posix()}', + '-DZEPHYR_TOOLCHAIN_VARIANT=zephyr', '-S' + os.path.join('source', 'dir'), 'arg1', 'arg2', '-DBOARD=', @@ -396,6 +397,7 @@ def mock_popen(*args, **kwargs): '-DSB_CONFIG_COMPILER_WARNINGS_AS_ERRORS=n', '-DEXTRA_GEN_EDT_ARGS=', '-Gdummy_generator', f'-DPython3_EXECUTABLE={pathlib.Path(sys.executable).as_posix()}', + '-DZEPHYR_TOOLCHAIN_VARIANT=zephyr', '-Szephyr_base/share/sysbuild', '-DAPP_DIR=' + os.path.join('source', 'dir'), 'arg1', 'arg2', @@ -451,6 +453,7 @@ def mock_popen(*args, **kwargs): instance_mock.build_time = 0 instance_mock.status = TwisterStatus.NONE instance_mock.reason = None + instance_mock.toolchain = 'zephyr' instance_mock.testsuite = mock.Mock() instance_mock.testsuite.name = 'testcase' instance_mock.testsuite.required_snippets = ['dummy snippet 1', 'ds2'] @@ -525,7 +528,7 @@ def mock_popen(*args, **kwargs): b'dummy edt pickle contents', [f'Loaded sysbuild domain data from' \ f' {os.path.join("build", "dir", "domains.yaml")}'], - {os.path.join('other', 'dummy.testsuite.name'): True} + {os.path.join('other', 'zephyr', 'dummy.testsuite.name'): True} ), ( 'other', ['kconfig'], True, @@ -539,7 +542,7 @@ def mock_popen(*args, **kwargs): 'CONFIG_FOO': 'no', 'dummy cache elem': 1}, b'dummy edt pickle contents', [], - {os.path.join('other', 'dummy.testsuite.name'): False} + {os.path.join('other', 'zephyr', 'dummy.testsuite.name'): False} ), ( 'other', ['other'], False, @@ -552,7 +555,7 @@ def mock_popen(*args, **kwargs): {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True}, b'dummy edt pickle contents', [], - {os.path.join('other', 'dummy.testsuite.name'): False} + {os.path.join('other', 'zephyr', 'dummy.testsuite.name'): False} ), ( 'other', ['other'], True, @@ -565,7 +568,7 @@ def mock_popen(*args, **kwargs): {}, None, ['Sysbuild test will be skipped. West must be used for flashing.'], - {os.path.join('other', 'dummy.testsuite.name'): True} + {os.path.join('other', 'zephyr', 'dummy.testsuite.name'): True} ), ( 'other', ['other'], False, @@ -579,7 +582,7 @@ def mock_popen(*args, **kwargs): 'dummy cache elem': 1}, None, [], - {os.path.join('other', 'dummy.testsuite.name'): False} + {os.path.join('other', 'zephyr', 'dummy.testsuite.name'): False} ), ( 'other', ['other'], False, @@ -593,7 +596,7 @@ def mock_popen(*args, **kwargs): 'dummy cache elem': 1}, b'dummy edt pickle contents', [], - {os.path.join('other', 'dummy.testsuite.name'): False} + {os.path.join('other', 'zephyr', 'dummy.testsuite.name'): False} ), ( 'other', ['other'], False, @@ -607,7 +610,7 @@ def mock_popen(*args, **kwargs): 'dummy cache elem': 1}, b'dummy edt pickle contents', [], - {os.path.join('other', 'dummy.testsuite.name'): True} + {os.path.join('other', 'zephyr', 'dummy.testsuite.name'): True} ), ( 'other', ['other'], False, @@ -723,6 +726,7 @@ def mock_pickle(datafile): mocked_jobserver) instance_mock = mock.Mock() instance_mock.sysbuild = 'sysbuild' if sysbuild else None + instance_mock.toolchain = 'zephyr' fb.instance = instance_mock fb.env = mock.Mock() fb.env.options = mock.Mock() @@ -1241,7 +1245,7 @@ def mock_getsize(filename, *args, **kwargs): mock.ANY, ['run test: dummy instance name', 'run status: dummy instance name success'], - {'op': 'report', 'test': mock.ANY, 'status': 'success', 'reason': 'OK'}, + {'op': 'coverage', 'test': mock.ANY, 'status': 'success', 'reason': 'OK'}, 'success', 'OK', 0, @@ -1562,17 +1566,31 @@ def mock_determine_testcases(res): TESTDATA_7 = [ ( + True, + [ + 'z_ztest_unit_test__dummy_suite1_name__dummy_test_name1', + 'z_ztest_unit_test__dummy_suite2_name__test_dummy_name2', + 'no match' + ], + [ + 'dummy.test_id.dummy_suite1_name.dummy_name1', + 'dummy.test_id.dummy_suite2_name.dummy_name2' + ] + ), + ( + False, [ 'z_ztest_unit_test__dummy_suite1_name__dummy_test_name1', 'z_ztest_unit_test__dummy_suite2_name__test_dummy_name2', 'no match' ], [ - ('dummy_id.dummy_suite1_name.dummy_name1'), - ('dummy_id.dummy_suite2_name.dummy_name2') + 'dummy_suite1_name.dummy_name1', + 'dummy_suite2_name.dummy_name2' ] ), ( + True, [ 'z_ztest_unit_test__dummy_suite2_name__test_dummy_name2', 'z_ztest_unit_test__bad_suite3_name_no_test', @@ -1583,27 +1601,48 @@ def mock_determine_testcases(res): '_ZN15foobarnamespaceL54z_ztest_unit_test__dummy_suite3_name__test_dummy_name6E', ], [ - ('dummy_id.dummy_suite2_name.dummy_name2'), - ('dummy_id.dummy_suite3_name.dummy_name4'), - ('dummy_id.dummy_suite3_name.bad_name1E'), - ('dummy_id.dummy_suite3_name.dummy_name5'), - ('dummy_id.dummy_suite3_name.dummy_name6'), + 'dummy.test_id.dummy_suite2_name.dummy_name2', + 'dummy.test_id.dummy_suite3_name.dummy_name4', + 'dummy.test_id.dummy_suite3_name.bad_name1E', + 'dummy.test_id.dummy_suite3_name.dummy_name5', + 'dummy.test_id.dummy_suite3_name.dummy_name6', ] ), ( + True, + [ + 'z_ztest_unit_test__dummy_suite2_name__test_dummy_name2', + 'z_ztest_unit_test__bad_suite3_name_no_test', + '_ZN12_GLOBAL__N_1L54z_ztest_unit_test__dummy_suite3_name__test_dummy_name4E', + '_ZN12_GLOBAL__N_1L54z_ztest_unit_test__dummy_suite3_name__test_bad_name1E', + '_ZN12_GLOBAL__N_1L51z_ztest_unit_test_dummy_suite3_name__test_bad_name2E', + '_ZN12_GLOBAL__N_1L54z_ztest_unit_test__dummy_suite3_name__test_dummy_name5E', + '_ZN15foobarnamespaceL54z_ztest_unit_test__dummy_suite3_name__test_dummy_name6E', + ], + [ + 'dummy_suite2_name.dummy_name2', + 'dummy_suite3_name.dummy_name4', + 'dummy_suite3_name.bad_name1E', + 'dummy_suite3_name.dummy_name5', + 'dummy_suite3_name.dummy_name6', + ] + ), + ( + True, ['no match'], [] ), ] @pytest.mark.parametrize( - 'symbols_names, added_tcs', + 'detailed_id, symbols_names, added_tcs', TESTDATA_7, - ids=['two hits, one miss', 'demangle', 'nothing'] + ids=['two hits, one miss', 'two hits short id', 'demangle', 'demangle short id', 'nothing'] ) def test_projectbuilder_determine_testcases( mocked_jobserver, mocked_env, + detailed_id, symbols_names, added_tcs ): @@ -1621,8 +1660,10 @@ def test_projectbuilder_determine_testcases( instance_mock = mock.Mock() instance_mock.testcases = [] - instance_mock.testsuite.id = 'dummy_id' + instance_mock.testsuite.id = 'dummy.test_id' instance_mock.testsuite.ztest_suite_names = [] + instance_mock.testsuite.detailed_test_id = detailed_id + instance_mock.compose_case_name = mock.Mock(side_effect=iter(added_tcs)) pb = ProjectBuilder(instance_mock, mocked_env, mocked_jobserver) @@ -1994,14 +2035,14 @@ def mock_open(fname, *args, **kwargs): ['INFO 20/25 dummy platform' \ ' dummy.testsuite.name' \ ' PASSED' \ - ' (dummy handler type: dummy dut, 60.000s)'], + ' (dummy handler type: dummy dut, 60.000s )'], None ), ( TwisterStatus.PASS, True, False, False, ['INFO 20/25 dummy platform' \ ' dummy.testsuite.name' \ - ' PASSED (build)'], + ' PASSED (build )'], None ), ( @@ -2039,6 +2080,7 @@ def test_projectbuilder_report_out( instance_mock.platform.name = 'dummy platform' instance_mock.status = status instance_mock.reason = 'dummy reason' + instance_mock.toolchain = 'zephyr' instance_mock.testsuite.name = 'dummy.testsuite.name' skip_mock_tc = mock.Mock(status=TwisterStatus.SKIP, reason=None) skip_mock_tc.name = 'mocked_testcase_to_skip' diff --git a/scripts/tests/twister/test_testinstance.py b/scripts/tests/twister/test_testinstance.py index 07cb72fbd2cc9..4c93e76bbe1f7 100644 --- a/scripts/tests/twister/test_testinstance.py +++ b/scripts/tests/twister/test_testinstance.py @@ -68,7 +68,7 @@ def test_check_build_or_run( testsuite.build_only = build_only testsuite.slow = slow - testinstance = TestInstance(testsuite, platform, class_testplan.env.outdir) + testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir) env = mock.Mock( options=mock.Mock( device_testing=False, @@ -147,7 +147,7 @@ def test_create_overlay( class_testplan.platforms = platforms_list platform = class_testplan.get_platform("demo_board_2") - testinstance = TestInstance(testcase, platform, class_testplan.env.outdir) + testinstance = TestInstance(testcase, platform, 'zephyr', class_testplan.env.outdir) platform.type = platform_type assert testinstance.create_overlay(platform, enable_asan, enable_ubsan, enable_coverage, coverage_platform) == expected_content @@ -158,7 +158,7 @@ def test_calculate_sizes(class_testplan, all_testsuites_dict, platforms_list): 'test_app/sample_test.app') class_testplan.platforms = platforms_list platform = class_testplan.get_platform("demo_board_2") - testinstance = TestInstance(testcase, platform, class_testplan.env.outdir) + testinstance = TestInstance(testcase, platform, 'zephyr', class_testplan.env.outdir) with pytest.raises(BuildError): assert testinstance.calculate_sizes() == "Missing/multiple output ELF binary" @@ -210,7 +210,7 @@ def sample_testinstance(all_testsuites_dict, class_testplan, platforms_list, req class_testplan.platforms = platforms_list platform = class_testplan.get_platform(request.param.get('board_name', 'demo_board_2')) - testinstance = TestInstance(testsuite, platform, class_testplan.env.outdir) + testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir) return testinstance @@ -228,12 +228,12 @@ def test_testinstance_init(all_testsuites_dict, class_testplan, platforms_list, class_testplan.platforms = platforms_list platform = class_testplan.get_platform("demo_board_2/unit_testing") - testinstance = TestInstance(testsuite, platform, class_testplan.env.outdir) + testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir) if detailed_test_id: - assert testinstance.build_dir == os.path.join(class_testplan.env.outdir, platform.normalized_name, testsuite_path) + assert testinstance.build_dir == os.path.join(class_testplan.env.outdir, platform.normalized_name, 'zephyr', testsuite_path) else: - assert testinstance.build_dir == os.path.join(class_testplan.env.outdir, platform.normalized_name, testsuite.source_dir_rel, testsuite.name) + assert testinstance.build_dir == os.path.join(class_testplan.env.outdir, platform.normalized_name, 'zephyr', testsuite.source_dir_rel, testsuite.name) @pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'sample'}], indirect=True) @@ -287,7 +287,7 @@ def test_testinstance_init_cases(all_testsuites_dict, class_testplan, platforms_ class_testplan.platforms = platforms_list platform = class_testplan.get_platform("demo_board_2") - testinstance = TestInstance(testsuite, platform, class_testplan.env.outdir) + testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir) testinstance.init_cases() @@ -341,8 +341,8 @@ def test_testinstance_dunders(all_testsuites_dict, class_testplan, platforms_lis class_testplan.platforms = platforms_list platform = class_testplan.get_platform("demo_board_2") - testinstance = TestInstance(testsuite, platform, class_testplan.env.outdir) - testinstance_copy = TestInstance(testsuite, platform, class_testplan.env.outdir) + testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir) + testinstance_copy = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir) d = testinstance.__getstate__() diff --git a/scripts/tests/twister/test_testplan.py b/scripts/tests/twister/test_testplan.py index a885d541f1558..73b2673b08efb 100644 --- a/scripts/tests/twister/test_testplan.py +++ b/scripts/tests/twister/test_testplan.py @@ -264,38 +264,38 @@ def test_add_instances_short(tmp_path, class_env, all_testsuites_dict, platforms platform = plan.get_platform("demo_board_2") instance_list = [] for _, testcase in all_testsuites_dict.items(): - instance = TestInstance(testcase, platform, class_env.outdir) + instance = TestInstance(testcase, platform, 'zephyr', class_env.outdir) instance_list.append(instance) plan.add_instances(instance_list) assert list(plan.instances.keys()) == \ - [platform.name + '/' + s for s in list(all_testsuites_dict.keys())] + [platform.name + '/zephyr/' + s for s in list(all_testsuites_dict.keys())] assert all(isinstance(n, TestInstance) for n in list(plan.instances.values())) assert list(plan.instances.values()) == instance_list QUARANTINE_BASIC = { - 'demo_board_1/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_1' : 'a1 on board_1 and board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_1' : 'a1 on board_1 and board_3' + 'demo_board_1/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_1' : 'a1 on board_1 and board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_1' : 'a1 on board_1 and board_3' } QUARANTINE_WITH_REGEXP = { - 'demo_board_2/unit_testing/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_2' : 'a2 and c2 on x86', - 'demo_board_1/unit_testing/scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1' : 'all test_d', - 'demo_board_3/unit_testing/scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1' : 'all test_d', - 'demo_board_2/unit_testing/scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1' : 'all test_d', - 'demo_board_2/unit_testing/scripts/tests/twister/test_data/testsuites/tests/test_c/test_c.check_2' : 'a2 and c2 on x86' + 'demo_board_2/unit_testing/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_2' : 'a2 and c2 on x86', + 'demo_board_1/unit_testing/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1' : 'all test_d', + 'demo_board_3/unit_testing/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1' : 'all test_d', + 'demo_board_2/unit_testing/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1' : 'all test_d', + 'demo_board_2/unit_testing/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_c/test_c.check_2' : 'a2 and c2 on x86' } QUARANTINE_PLATFORM = { - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_1' : 'all on board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_2' : 'all on board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1' : 'all on board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_b/test_b.check_1' : 'all on board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_b/test_b.check_2' : 'all on board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_c/test_c.check_1' : 'all on board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_c/test_c.check_2' : 'all on board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_e/test_e.check_1' : 'all on board_3', - 'demo_board_3/scripts/tests/twister/test_data/testsuites/tests/test_config/test_config.main' : 'all on board_3' + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_1' : 'all on board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_2' : 'all on board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_d/test_d.check_1' : 'all on board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_b/test_b.check_1' : 'all on board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_b/test_b.check_2' : 'all on board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_c/test_c.check_1' : 'all on board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_c/test_c.check_2' : 'all on board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_e/test_e.check_1' : 'all on board_3', + 'demo_board_3/zephyr/scripts/tests/twister/test_data/testsuites/tests/test_config/test_config.main' : 'all on board_3' } QUARANTINE_MULTIFILES = { @@ -381,7 +381,6 @@ def test_required_snippets_short( 'testsuites', 'tests', testpath) testsuite = class_testplan.testsuites.get(testpath) plan.platforms = platforms_list - print(platforms_list) plan.platform_names = [p.name for p in platforms_list] plan.testsuites = {testpath: testsuite} @@ -621,21 +620,25 @@ def test_testplan_load( { "name": "ts1", "platform": "t-p1", + "toolchain": "zephyr", "testcases": [] }, { "name": "ts1", "platform": "t-p2", + "toolchain": "zephyr", "testcases": [] }, { "name": "ts2", "platform": "t-p3", + "toolchain": "zephyr", "testcases": [] }, { "name": "ts2", "platform": "t-p4", + "toolchain": "zephyr", "testcases": [] } ] @@ -650,21 +653,25 @@ def test_testplan_load( { "name": "ts1", "platform": "ts-p1", + "toolchain": "zephyr", "testcases": [] }, { "name": "ts1", "platform": "ts-p2", + "toolchain": "zephyr", "testcases": [] }, { "name": "ts2", "platform": "ts-p3", + "toolchain": "zephyr", "testcases": [] }, { "name": "ts2", "platform": "ts-p4", + "toolchain": "zephyr", "testcases": [] } ] @@ -679,21 +686,25 @@ def test_testplan_load( { "name": "ts1", "platform": "lt-p1", + "toolchain": "zephyr", "testcases": [] }, { "name": "ts1", "platform": "lt-p2", + "toolchain": "zephyr", "testcases": [] }, { "name": "ts2", "platform": "lt-p3", + "toolchain": "zephyr", \"testcases": [] }, { "name": "ts2", "platform": "lt-p4", + "toolchain": "zephyr", "testcases": [] } ] @@ -1099,167 +1110,7 @@ def test_testplan_add_configurations( expected_platform_names, expected_defaults ): - # tmp_path - # └ boards <- board root - # ├ zephyr - # │ ├ p1 - # │ | ├ p1e1.yaml - # │ | └ p1e2.yaml - # │ └ p2 - # │ ├ p2.yaml - # │ └ p2-1.yaml <- duplicate - # │ └ p2-2.yaml <- load error - # └ arm - # └ p3 - # ├ p3.yaml - # └ p3_B.conf - tmp_soc_root_dir = tmp_path / 'soc' - tmp_soc_root_dir.mkdir() - - tmp_vend1_dir = tmp_soc_root_dir / 'zephyr' - tmp_vend1_dir.mkdir() - - tmp_soc1_dir = tmp_vend1_dir / 's1' - tmp_soc1_dir.mkdir() - - soc1_yaml = """\ -family: - - name: zephyr - series: - - name: zephyr_testing - socs: - - name: unit_testing -""" - soc1_yamlfile = tmp_soc1_dir / 'soc.yml' - soc1_yamlfile.write_text(soc1_yaml) - - tmp_board_root_dir = tmp_path / 'boards' - tmp_board_root_dir.mkdir() - - tmp_vend1_dir = tmp_board_root_dir / 'zephyr' - tmp_vend1_dir.mkdir() - - tmp_p1_dir = tmp_vend1_dir / 'p1' - tmp_p1_dir.mkdir() - - p1e1_bs_yaml = """\ -boards: - - - name: p1e1 - vendor: zephyr - socs: - - name: unit_testing - - name: p1e2 - vendor: zephyr - socs: - - name: unit_testing -""" - p1e1_yamlfile = tmp_p1_dir / 'board.yml' - p1e1_yamlfile.write_text(p1e1_bs_yaml) - - p1e1_yaml = """\ -identifier: p1e1 -name: Platform 1 Edition 1 -type: native -arch: x86 -vendor: zephyr -toolchain: - - zephyr -twister: False -""" - p1e1_yamlfile = tmp_p1_dir / 'p1e1.yaml' - p1e1_yamlfile.write_text(p1e1_yaml) - - p1e2_yaml = """\ -identifier: p1e2 -name: Platform 1 Edition 2 -type: native -arch: x86 -vendor: zephyr -toolchain: - - zephyr -""" - p1e2_yamlfile = tmp_p1_dir / 'p1e2.yaml' - p1e2_yamlfile.write_text(p1e2_yaml) - - tmp_p2_dir = tmp_vend1_dir / 'p2' - tmp_p2_dir.mkdir() - - p2_bs_yaml = """\ -boards: - - - name: p2 - vendor: zephyr - socs: - - name: unit_testing - - name: p2_2 - vendor: zephyr - socs: - - name: unit_testing -""" - p2_yamlfile = tmp_p2_dir / 'board.yml' - p2_yamlfile.write_text(p2_bs_yaml) - - p2_yaml = """\ -identifier: p2/unit_testing -name: Platform 2 -type: sim -arch: x86 -vendor: vendor2 -toolchain: - - zephyr -testing: - default: True -""" - p2_yamlfile = tmp_p2_dir / 'p2.yaml' - p2_yamlfile.write_text(p2_yaml) - - - p2_2_yaml = """\ -testing: - ć#@%!#!#^#@%@:1.0 -identifier: p2_2 -name: Platform 2 2 -type: sim -arch: x86 -vendor: vendor2 -toolchain: - - zephyr -""" - p2_2_yamlfile = tmp_p2_dir / 'p2-2.yaml' - p2_2_yamlfile.write_text(p2_2_yaml) - - tmp_vend2_dir = tmp_board_root_dir / 'arm' - tmp_vend2_dir.mkdir() - - tmp_p3_dir = tmp_vend2_dir / 'p3' - tmp_p3_dir.mkdir() - - p3_bs_yaml = """\ -boards: - - name: p3 - vendor: zephyr - socs: - - name: unit_testing -""" - p3_yamlfile = tmp_p3_dir / 'board.yml' - p3_yamlfile.write_text(p3_bs_yaml) - - p3_yaml = """\ -identifier: p3 -name: Platform 3 -type: unit -arch: arm -vendor: vendor3 -toolchain: - - zephyr -testing: - default: True -""" - p3_yamlfile = tmp_p3_dir / 'p3.yaml' - p3_yamlfile.write_text(p3_yaml) - - env = mock.Mock(board_roots=[tmp_board_root_dir],soc_roots=[tmp_path], arch_roots=[tmp_path]) + env = mock.Mock(board_roots=[tmp_path / 'boards'], soc_roots=[tmp_path], arch_roots=[tmp_path]) testplan = TestPlan(env=env) @@ -1270,8 +1121,23 @@ def test_testplan_add_configurations( } } + def mock_gen_plat(board_roots, soc_roots, arch_roots): + assert [tmp_path] == board_roots + assert [tmp_path] == soc_roots + assert [tmp_path] == arch_roots - testplan.add_configurations() + platforms = [ + mock.Mock(aliases=['p1e1/unit_testing', 'p1e1'], twister=False, default=False), + mock.Mock(aliases=['p1e2/unit_testing', 'p1e2'], twister=True, default=False), + mock.Mock(aliases=['p2/unit_testing', 'p2'], twister=True, default=True), + mock.Mock(aliases=['p3/unit_testing', 'p3'], twister=True, default=True), + ] + for platform in platforms: + type(platform).name = mock.PropertyMock(return_value=platform.aliases[0]) + yield platform + + with mock.patch('twisterlib.testplan.generate_platforms', mock_gen_plat): + testplan.add_configurations() if expected_defaults is not None: print(expected_defaults) @@ -1509,20 +1375,25 @@ def get_platform(name): ts1tc1.name = 'TS1.tc1' ts1 = mock.Mock(testcases=[ts1tc1]) ts1.name = 'TestSuite 1' + ts1.toolchain = 'zephyr' ts2 = mock.Mock(testcases=[]) ts2.name = 'TestSuite 2' + ts2.toolchain = 'zephyr' ts3tc1 = mock.Mock() ts3tc1.name = 'TS3.tc1' ts3tc2 = mock.Mock() ts3tc2.name = 'TS3.tc2' ts3 = mock.Mock(testcases=[ts3tc1, ts3tc2]) ts3.name = 'TestSuite 3' + ts3.toolchain = 'zephyr' ts4tc1 = mock.Mock() ts4tc1.name = 'TS4.tc1' ts4 = mock.Mock(testcases=[ts4tc1]) ts4.name = 'TestSuite 4' + ts4.toolchain = 'zephyr' ts5 = mock.Mock(testcases=[]) ts5.name = 'TestSuite 5' + ts5.toolchain = 'zephyr' testplan = TestPlan(env=mock.Mock(outdir=os.path.join('out', 'dir'))) testplan.options = mock.Mock(device_testing=device_testing, test_only=True, report_summary=None) @@ -1549,6 +1420,7 @@ def get_platform(name): "used_rom": 1024, "available_rom": 1047552, "status": "passed", + "toolchain": "zephyr", "reason": "OK", "testcases": [ { @@ -1562,7 +1434,8 @@ def get_platform(name): }, { "name": "TestSuite 2", - "platform": "Platform 1" + "platform": "Platform 1", + "toolchain": "zephyr" }, { "name": "TestSuite 3", @@ -1574,6 +1447,7 @@ def get_platform(name): "used_rom": 1024, "available_rom": 1047552, "status": "error", + "toolchain": "zephyr", "reason": "File Not Found Error", "testcases": [ { @@ -1597,6 +1471,7 @@ def get_platform(name): "used_rom": 1024, "available_rom": 1047552, "status": "skipped", + "toolchain": "zephyr", "reason": "Not in requested test list.", "testcases": [ { @@ -1613,7 +1488,8 @@ def get_platform(name): }, { "name": "TestSuite 5", - "platform": "Platform 2" + "platform": "Platform 2", + "toolchain": "zephyr" } ] } @@ -1629,7 +1505,7 @@ def get_platform(name): testplan.load_from_file('dummy.yaml', filter_platform) expected_instances = { - 'Platform 1/TestSuite 1': { + 'Platform 1/zephyr/TestSuite 1': { 'metrics': { 'handler_time': 60.0, 'used_ram': 4096, @@ -1638,6 +1514,7 @@ def get_platform(name): 'available_rom': 1047552 }, 'retries': 0, + 'toolchain': 'zephyr', 'testcases': { 'TS1.tc1': { 'status': TwisterStatus.PASS, @@ -1647,7 +1524,7 @@ def get_platform(name): } } }, - 'Platform 1/TestSuite 2': { + 'Platform 1/zephyr/TestSuite 2': { 'metrics': { 'handler_time': 0, 'used_ram': 0, @@ -1656,9 +1533,10 @@ def get_platform(name): 'available_rom': 0 }, 'retries': 0, + 'toolchain': 'zephyr', 'testcases': [] }, - 'Platform 1/TestSuite 3': { + 'Platform 1/zephyr/TestSuite 3': { 'metrics': { 'handler_time': 360.0, 'used_ram': 4096, @@ -1667,6 +1545,7 @@ def get_platform(name): 'available_rom': 1047552 }, 'retries': 1, + 'toolchain': 'zephyr', 'testcases': { 'TS3.tc1': { 'status': TwisterStatus.ERROR, @@ -1682,7 +1561,7 @@ def get_platform(name): } } }, - 'Platform 1/TestSuite 4': { + 'Platform 1/zephyr/TestSuite 4': { 'metrics': { 'handler_time': 360.0, 'used_ram': 4096, @@ -1691,6 +1570,7 @@ def get_platform(name): 'available_rom': 1047552 }, 'retries': 0, + 'toolchain': 'zephyr', 'testcases': { 'TS4.tc1': { 'status': TwisterStatus.SKIP, diff --git a/scripts/tests/twister_blackbox/test_coverage.py b/scripts/tests/twister_blackbox/test_coverage.py index 5c1b6cec72d3b..aeb41e63daf37 100644 --- a/scripts/tests/twister_blackbox/test_coverage.py +++ b/scripts/tests/twister_blackbox/test_coverage.py @@ -13,8 +13,7 @@ import sys import json -# pylint: disable=duplicate-code -# pylint: disable=no-name-in-module +# pylint: disable=duplicate-code, disable=no-name-in-module from conftest import TEST_DATA, ZEPHYR_BASE, testsuite_filename_mock, clear_log_in_test from twisterlib.testplan import TestPlan @@ -123,7 +122,7 @@ class TestCoverage: os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic', 'group2'), ['qemu_x86'], 'gcovr', - 'Running gcovr -r' + 'Running: gcovr ' ), ( os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic', 'group2'), @@ -136,7 +135,7 @@ class TestCoverage: ( os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic', 'group2'), ['qemu_x86'], - ['The specified file does not exist.', r'\[Errno 13\] Permission denied:'], + ['GCOVR failed with '], ) ] TESTDATA_7 = [ diff --git a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup1/test_data.yaml b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup1/test_data.yaml index 5bd1d3d4b06f1..04a16df130b45 100644 --- a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup1/test_data.yaml +++ b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup1/test_data.yaml @@ -9,3 +9,4 @@ tests: tags: - agnostic - subgrouped + - odd diff --git a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup2/test_data.yaml b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup2/test_data.yaml index 9bf2f04688522..a4903f06b8a20 100644 --- a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup2/test_data.yaml +++ b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group1/subgroup2/test_data.yaml @@ -10,3 +10,4 @@ tests: tags: - agnostic - subgrouped + - even diff --git a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group2/test_data.yaml b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group2/test_data.yaml index f53a0d299480f..56e7d0035d2a6 100644 --- a/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group2/test_data.yaml +++ b/scripts/tests/twister_blackbox/test_data/tests/dummy/agnostic/group2/test_data.yaml @@ -6,4 +6,6 @@ tests: - qemu_x86_64 integration_platforms: - native_sim - tags: agnostic + tags: + - agnostic + - even diff --git a/scripts/tests/twister_blackbox/test_device.py b/scripts/tests/twister_blackbox/test_device.py index b6e78acc28b7a..790e0774e3004 100644 --- a/scripts/tests/twister_blackbox/test_device.py +++ b/scripts/tests/twister_blackbox/test_device.py @@ -72,5 +72,5 @@ def test_seed(self, capfd, out_path, seed): assert str(sys_exit.value) == '1' - expected_line = r'seed_native_sim.dummy FAILED Failed \(native (\d+\.\d+)s/seed: {}\)'.format(seed[0]) + expected_line = r'seed_native_sim.dummy FAILED Failed \(rc=1\) \(native (\d+\.\d+)s/seed: {} \)'.format(seed[0]) assert re.search(expected_line, err) diff --git a/scripts/tests/twister_blackbox/test_error.py b/scripts/tests/twister_blackbox/test_error.py index ba43731e09734..4a28f7fb178cd 100644 --- a/scripts/tests/twister_blackbox/test_error.py +++ b/scripts/tests/twister_blackbox/test_error.py @@ -46,7 +46,7 @@ class TestError: ), ( '--overflow-as-errors', - r'always_overflow.dummy ERROR Build failure \(build\)' + r'always_overflow.dummy ERROR Build failure \(build \)' ) ] diff --git a/scripts/tests/twister_blackbox/test_filter.py b/scripts/tests/twister_blackbox/test_filter.py index 3558296d40b11..c0da4270c3731 100644 --- a/scripts/tests/twister_blackbox/test_filter.py +++ b/scripts/tests/twister_blackbox/test_filter.py @@ -24,47 +24,47 @@ class TestFilter: ( 'x86', [ - r'(it8xxx2_evb/it81302bx).*?(SKIPPED: Command line testsuite arch filter)', + r'(it8xxx2_evb/it81302bx).*?(FILTERED: Command line testsuite arch filter)', ], ), ( 'arm', [ - r'(it8xxx2_evb/it81302bx).*?(SKIPPED: Command line testsuite arch filter)', - r'(qemu_x86/atom).*?(SKIPPED: Command line testsuite arch filter)', - r'(hsdk/arc_hsdk).*?(SKIPPED: Command line testsuite arch filter)', + r'(it8xxx2_evb/it81302bx).*?(FILTERED: Command line testsuite arch filter)', + r'(qemu_x86/atom).*?(FILTERED: Command line testsuite arch filter)', + r'(hsdk/arc_hsdk).*?(FILTERED: Command line testsuite arch filter)', ] ), ( 'riscv', [ - r'(qemu_x86/atom).*?(SKIPPED: Command line testsuite arch filter)', - r'(hsdk/arc_hsdk).*?(SKIPPED: Command line testsuite arch filter)', ] + r'(qemu_x86/atom).*?(FILTERED: Command line testsuite arch filter)', + r'(hsdk/arc_hsdk).*?(FILTERED: Command line testsuite arch filter)', ] ) ] TESTDATA_2 = [ ( 'nxp', [ - r'(it8xxx2_evb/it81302bx).*?(SKIPPED: Not a selected vendor platform)', - r'(hsdk/arc_hsdk).*?(SKIPPED: Not a selected vendor platform)', - r'(qemu_x86).*?(SKIPPED: Not a selected vendor platform)', + r'(it8xxx2_evb/it81302bx).*?(FILTERED: Not a selected vendor platform)', + r'(hsdk/arc_hsdk).*?(FILTERED: Not a selected vendor platform)', + r'(qemu_x86).*?(FILTERED: Not a selected vendor platform)', ], ), ( 'intel', [ - r'(it8xxx2_evb/it81302bx).*?(SKIPPED: Not a selected vendor platform)', - r'(qemu_x86/atom).*?(SKIPPED: Not a selected vendor platform)', + r'(it8xxx2_evb/it81302bx).*?(FILTERED: Not a selected vendor platform)', + r'(qemu_x86/atom).*?(FILTERED: Not a selected vendor platform)', r'(DEBUG\s+- adding intel_adl_crb)' ] ), ( 'ite', [ - r'(qemu_x86/atom).*?(SKIPPED: Not a selected vendor platform)', - r'(intel_adl_crb/alder_lake).*?(SKIPPED: Not a selected vendor platform)', - r'(hsdk/arc_hsdk).*?(SKIPPED: Not a selected vendor platform)', + r'(qemu_x86/atom).*?(FILTERED: Not a selected vendor platform)', + r'(intel_adl_crb/alder_lake).*?(FILTERED: Not a selected vendor platform)', + r'(hsdk/arc_hsdk).*?(FILTERED: Not a selected vendor platform)', r'(DEBUG\s+- adding it8xxx2_evb)' ] ) diff --git a/scripts/tests/twister_blackbox/test_outfile.py b/scripts/tests/twister_blackbox/test_outfile.py index 0376769781841..57a874041cbff 100644 --- a/scripts/tests/twister_blackbox/test_outfile.py +++ b/scripts/tests/twister_blackbox/test_outfile.py @@ -97,7 +97,7 @@ def test_runtime_artifact_cleanup(self, out_path): assert str(sys_exit.value) == '0' relpath = os.path.relpath(path, ZEPHYR_BASE) - sample_path = os.path.join(out_path, 'qemu_x86_atom', relpath, 'sample.basic.helloworld') + sample_path = os.path.join(out_path, 'qemu_x86_atom', 'zephyr', relpath, 'sample.basic.helloworld') listdir = os.listdir(sample_path) zephyr_listdir = os.listdir(os.path.join(sample_path, 'zephyr')) @@ -122,7 +122,7 @@ def test_short_build_path(self, out_path): ) for val in pair] relative_test_path = os.path.relpath(path, ZEPHYR_BASE) - test_result_path = os.path.join(out_path, 'qemu_x86_atom', + test_result_path = os.path.join(out_path, 'qemu_x86_atom', 'zephyr', relative_test_path, 'dummy.agnostic.group2') with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ @@ -181,7 +181,7 @@ def test_prep_artifacts_for_testing(self, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] path = os.path.join(TEST_DATA, 'samples', 'hello_world') relative_test_path = os.path.relpath(path, ZEPHYR_BASE) - zephyr_out_path = os.path.join(out_path, 'qemu_x86_atom', relative_test_path, + zephyr_out_path = os.path.join(out_path, 'qemu_x86_atom', 'zephyr', relative_test_path, 'sample.basic.helloworld', 'zephyr') args = ['-i', '--outdir', out_path, '-T', path] + \ ['--prep-artifacts-for-testing'] + \ diff --git a/scripts/tests/twister_blackbox/test_output.py b/scripts/tests/twister_blackbox/test_output.py index def3703e85f60..a1686b343fb5f 100644 --- a/scripts/tests/twister_blackbox/test_output.py +++ b/scripts/tests/twister_blackbox/test_output.py @@ -14,6 +14,7 @@ import sys import json +# pylint: disable=no-name-in-module from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock, clear_log_in_test from twisterlib.testplan import TestPlan @@ -74,7 +75,12 @@ def test_detailed_test_id(self, out_path, flag, expect_paths): assert len(filtered_j) > 0, "No dummy tests found." expected_start = os.path.relpath(TEST_DATA, ZEPHYR_BASE) if expect_paths else 'dummy.' - assert all([testsuite.startswith(expected_start)for _, testsuite, _ in filtered_j]) + assert all([testsuite.startswith(expected_start) for _, testsuite, _ in filtered_j]) + if expect_paths: + assert all([(tc_name.count('.') > 1) for _, _, tc_name in filtered_j]) + else: + assert all([(tc_name.count('.') == 1) for _, _, tc_name in filtered_j]) + def test_inline_logs(self, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] @@ -91,7 +97,7 @@ def test_inline_logs(self, out_path): assert str(sys_exit.value) == '1' rel_path = os.path.relpath(path, ZEPHYR_BASE) - build_path = os.path.join(out_path, 'qemu_x86_atom', rel_path, 'always_fail.dummy', 'build.log') + build_path = os.path.join(out_path, 'qemu_x86_atom', 'zephyr', rel_path, 'always_fail.dummy', 'build.log') with open(build_path) as f: build_log = f.read() @@ -141,12 +147,13 @@ def _get_matches(self, err, regex_line): matches = [] for line in err.split('\n'): columns = line.split() - if len(columns) == 8: - for i in range(8): - match = re.fullmatch(regex_line[i], columns[i]) + regexes = len(regex_line) + if len(columns) == regexes: + for i, column in enumerate(columns): + match = re.fullmatch(regex_line[i], column) if match: matches.append(match) - if len(matches) == 8: + if len(matches) == regexes: return matches else: matches = [] @@ -186,7 +193,7 @@ def test_output_levels(self, capfd, out_path, flags): assert 'Total test suites: ' not in out # Brief summary shows up only on verbosity 0 - instance-by-instance otherwise - regex_info_line = [r'INFO', r'-', r'\d+/\d+', r'\S+', r'\S+', r'[A-Z]+', r'\(\w+', r'[\d.]+s\)'] + regex_info_line = [r'INFO', r'-', r'\d+/\d+', r'\S+', r'\S+', r'[A-Z]+', r'\(\w+', r'[\d.]+s', r'<\S+>\)'] info_matches = self._get_matches(err, regex_info_line) if not any(f in flags for f in ['-v', '-vv']): assert not info_matches diff --git a/scripts/tests/twister_blackbox/test_printouts.py b/scripts/tests/twister_blackbox/test_printouts.py index 853797354f44c..8f07a0fd3aa88 100644 --- a/scripts/tests/twister_blackbox/test_printouts.py +++ b/scripts/tests/twister_blackbox/test_printouts.py @@ -29,7 +29,7 @@ class TestPrintOuts: TESTDATA_1 = [ ( os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), - ['agnostic', 'subgrouped'] + ['agnostic', 'subgrouped', 'even', 'odd'] ), ( os.path.join(TEST_DATA, 'tests', 'dummy', 'device'), @@ -47,13 +47,100 @@ class TestPrintOuts: 'dummy.agnostic.group2.a2_tests.assert2', 'dummy.agnostic.group2.a3_tests.assert1', 'dummy.agnostic.group2.a2_tests.assert3' - ] + ], + '--no-detailed-test-id', + '' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + [ + 'dummy.agnostic.group1.subgroup2.a1_2_tests.assert', + 'dummy.agnostic.group2.a2_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert2', + 'dummy.agnostic.group2.a3_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert3' + ], + '--no-detailed-test-id', + 'odd' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + [], + '--no-detailed-test-id', + 'odd even' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + [ + 'dummy.agnostic.group1.subgroup1.a1_1_tests.assert', + 'dummy.agnostic.group1.subgroup2.a1_2_tests.assert', + 'dummy.agnostic.group2.a2_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert2', + 'dummy.agnostic.group2.a3_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert3' + ], + '--no-detailed-test-id', + 'unknown_tag' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + [ + 'dummy.agnostic.group1.subgroup1.a1_1_tests.assert', + 'dummy.agnostic.group1.subgroup2.a1_2_tests.assert', + 'dummy.agnostic.group2.a2_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert2', + 'dummy.agnostic.group2.a3_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert3' + ], + '--detailed-test-id', + '' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + [ + 'dummy.agnostic.group1.subgroup2.a1_2_tests.assert', + 'dummy.agnostic.group2.a2_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert2', + 'dummy.agnostic.group2.a3_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert3' + ], + '--detailed-test-id', + 'odd' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + [], + '--detailed-test-id', + 'odd even' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + [ + 'dummy.agnostic.group1.subgroup1.a1_1_tests.assert', + 'dummy.agnostic.group1.subgroup2.a1_2_tests.assert', + 'dummy.agnostic.group2.a2_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert2', + 'dummy.agnostic.group2.a3_tests.assert1', + 'dummy.agnostic.group2.a2_tests.assert3' + ], + '--detailed-test-id', + 'unknown_tag' ), ( os.path.join(TEST_DATA, 'tests', 'dummy', 'device'), [ 'dummy.device.group.d_tests.assert' - ] + ], + '--no-detailed-test-id', + '' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'device'), + [ + 'dummy.device.group.d_tests.assert' + ], + '--detailed-test-id', + '' ), ] @@ -70,7 +157,79 @@ class TestPrintOuts: ' ├── dummy.agnostic.group2.a2_tests.assert1\n' \ ' ├── dummy.agnostic.group2.a2_tests.assert2\n' \ ' ├── dummy.agnostic.group2.a2_tests.assert3\n' \ - ' └── dummy.agnostic.group2.a3_tests.assert1\n' + ' └── dummy.agnostic.group2.a3_tests.assert1\n', + '--no-detailed-test-id', + '' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + 'Testsuite\n' \ + '├── Samples\n' \ + '└── Tests\n' \ + ' └── dummy\n' \ + ' └── agnostic\n' \ + ' ├── dummy.agnostic.group1.subgroup2.a1_2_tests.assert\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert1\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert2\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert3\n' \ + ' └── dummy.agnostic.group2.a3_tests.assert1\n', + '--no-detailed-test-id', + 'odd' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + 'Testsuite\n' \ + '├── Samples\n' \ + '└── Tests\n' \ + ' └── dummy\n' \ + ' └── agnostic\n' \ + ' ├── dummy.agnostic.group1.subgroup1.a1_1_tests.assert\n' \ + ' ├── dummy.agnostic.group1.subgroup2.a1_2_tests.assert\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert1\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert2\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert3\n' \ + ' └── dummy.agnostic.group2.a3_tests.assert1\n', + '--detailed-test-id', + '' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + 'Testsuite\n' \ + '├── Samples\n' \ + '└── Tests\n' \ + ' └── dummy\n' \ + ' └── agnostic\n' \ + ' ├── dummy.agnostic.group1.subgroup2.a1_2_tests.assert\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert1\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert2\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert3\n' \ + ' └── dummy.agnostic.group2.a3_tests.assert1\n', + '--detailed-test-id', + 'odd' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + 'Testsuite\n' \ + '├── Samples\n' \ + '└── Tests\n', + '--detailed-test-id', + 'odd even' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), + 'Testsuite\n' \ + '├── Samples\n' \ + '└── Tests\n' \ + ' └── dummy\n' \ + ' └── agnostic\n' \ + ' ├── dummy.agnostic.group1.subgroup1.a1_1_tests.assert\n' \ + ' ├── dummy.agnostic.group1.subgroup2.a1_2_tests.assert\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert1\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert2\n' \ + ' ├── dummy.agnostic.group2.a2_tests.assert3\n' \ + ' └── dummy.agnostic.group2.a3_tests.assert1\n', + '--detailed-test-id', + 'unknown_tag' ), ( os.path.join(TEST_DATA, 'tests', 'dummy', 'device'), @@ -79,7 +238,20 @@ class TestPrintOuts: '└── Tests\n' ' └── dummy\n' ' └── device\n' - ' └── dummy.device.group.d_tests.assert\n' + ' └── dummy.device.group.d_tests.assert\n', + '--no-detailed-test-id', + '' + ), + ( + os.path.join(TEST_DATA, 'tests', 'dummy', 'device'), + 'Testsuite\n' + '├── Samples\n' + '└── Tests\n' + ' └── dummy\n' + ' └── device\n' + ' └── dummy.device.group.d_tests.assert\n', + '--detailed-test-id', + '' ), ] @@ -128,15 +300,25 @@ def test_list_tags(self, capfd, out_path, test_path, expected): assert str(sys_exit.value) == '0' @pytest.mark.parametrize( - 'test_path, expected', + 'test_path, expected, detailed_id, exclude_tags', TESTDATA_2, ids=[ - 'tests/dummy/agnostic', + 'tests/dummy/agnostic no_detailed_id', + 'tests/dummy/agnostic no_detailed_id excl_tag', + 'tests/dummy/agnostic no_detailed_id excl_all_tags', + 'tests/dummy/agnostic no_detailed_id no_excl_tag', + 'tests/dummy/agnostic detailed_id', + 'tests/dummy/agnostic detailed_id excl_tag', + 'tests/dummy/agnostic detailed_id excl_all_tags', + 'tests/dummy/agnostic detailed_id no_excl_tag', 'tests/dummy/device', + 'tests/dummy/device detailed_id', ] ) - def test_list_tests(self, capfd, out_path, test_path, expected): - args = ['--outdir', out_path, '-T', test_path, '--list-tests'] + def test_list_tests(self, capfd, out_path, test_path, expected, detailed_id, exclude_tags): + args = ['--outdir', out_path, '-T', test_path, '--list-tests', detailed_id] + for tag in exclude_tags.split(): + args += ['--exclude-tag', tag] with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ pytest.raises(SystemExit) as sys_exit: @@ -147,7 +329,8 @@ def test_list_tests(self, capfd, out_path, test_path, expected): sys.stderr.write(err) printed_tests = [test.strip() for test in out.split('- ')[1:]] - printed_tests[-1] = printed_tests[-1].split('\n')[0] + if printed_tests: + printed_tests[-1] = printed_tests[-1].split('\n')[0] assert all([test in printed_tests for test in expected]) assert all([test in expected for test in printed_tests]) @@ -155,15 +338,23 @@ def test_list_tests(self, capfd, out_path, test_path, expected): assert str(sys_exit.value) == '0' @pytest.mark.parametrize( - 'test_path, expected', + 'test_path, expected, detailed_id, exclude_tags', TESTDATA_3, ids=[ - 'tests/dummy/agnostic', + 'tests/dummy/agnostic no_detailed_id', + 'tests/dummy/agnostic no_detailed_id excl_tag', + 'tests/dummy/agnostic detailed_id', + 'tests/dummy/agnostic detailed_id excl_tag', + 'tests/dummy/agnostic detailed_id excl_all_tags', + 'tests/dummy/agnostic detailed_id no_excl_tag', 'tests/dummy/device', + 'tests/dummy/device detailed_id', ] ) - def test_tree(self, capfd, out_path, test_path, expected): - args = ['--outdir', out_path, '-T', test_path, '--test-tree'] + def test_tree(self, capfd, out_path, test_path, expected, detailed_id, exclude_tags): + args = ['--outdir', out_path, '-T', test_path, '--test-tree', detailed_id] + for tag in exclude_tags.split(): + args += ['--exclude-tag', tag] with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ pytest.raises(SystemExit) as sys_exit: @@ -293,7 +484,7 @@ def test_size(self, capfd, out_path): capfd.readouterr() p = os.path.relpath(path, ZEPHYR_BASE) - prev_path = os.path.join(out_path, 'qemu_x86_atom', p, + prev_path = os.path.join(out_path, 'qemu_x86_atom', 'zephyr', p, 'sample.basic.helloworld', 'zephyr', 'zephyr.elf') args = ['--size', prev_path] diff --git a/scripts/tests/twister_blackbox/test_quarantine.py b/scripts/tests/twister_blackbox/test_quarantine.py index 404e0be2b07e2..61cfa9634e3ea 100644 --- a/scripts/tests/twister_blackbox/test_quarantine.py +++ b/scripts/tests/twister_blackbox/test_quarantine.py @@ -89,26 +89,26 @@ def test_quarantine_list(self, capfd, out_path, test_path, test_platforms, quara sys.stdout.write(out) sys.stderr.write(err) - board1_match1 = re.search('agnostic/group2/dummy.agnostic.group2 SKIPPED: Quarantine: test ' + board1_match1 = re.search('agnostic/group2/dummy.agnostic.group2 FILTERED: Quarantine: test ' 'intel_adl_crb', err) board1_match2 = re.search( - 'agnostic/group1/subgroup2/dummy.agnostic.group1.subgroup2 SKIPPED: Quarantine: test ' + 'agnostic/group1/subgroup2/dummy.agnostic.group1.subgroup2 FILTERED: Quarantine: test ' 'intel_adl_crb', err) qemu_64_match = re.search( - 'agnostic/group1/subgroup2/dummy.agnostic.group1.subgroup2 SKIPPED: Quarantine: test ' + 'agnostic/group1/subgroup2/dummy.agnostic.group1.subgroup2 FILTERED: Quarantine: test ' 'qemu_x86_64', err) all_platforms_match = re.search( - 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantine: test ' + 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 FILTERED: Quarantine: test ' 'all platforms', err) all_platforms_match2 = re.search( - 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantine: test ' + 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 FILTERED: Quarantine: test ' 'all platforms', err) all_platforms_match3 = re.search( - 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 SKIPPED: Quarantine: test ' + 'agnostic/group1/subgroup1/dummy.agnostic.group1.subgroup1 FILTERED: Quarantine: test ' 'all platforms', err) diff --git a/scripts/tests/twister_blackbox/test_report.py b/scripts/tests/twister_blackbox/test_report.py index c2ed41f2747de..83d5942c8554c 100644 --- a/scripts/tests/twister_blackbox/test_report.py +++ b/scripts/tests/twister_blackbox/test_report.py @@ -114,8 +114,8 @@ class TestReport: os.path.join(TEST_DATA, 'tests', 'one_fail_two_error_one_pass'), ['qemu_x86/atom'], [r'one_fail_two_error_one_pass.agnostic.group1.subgroup2 on qemu_x86/atom FAILED \(.*\)', - r'one_fail_two_error_one_pass.agnostic.group1.subgroup3 on qemu_x86/atom ERROR \(Build failure\)', - r'one_fail_two_error_one_pass.agnostic.group1.subgroup4 on qemu_x86/atom ERROR \(Build failure\)'], + r'one_fail_two_error_one_pass.agnostic.group1.subgroup3 on qemu_x86/atom ERROR \(Build failure.*\)', + r'one_fail_two_error_one_pass.agnostic.group1.subgroup4 on qemu_x86/atom ERROR \(Build failure.*\)'], ) ] diff --git a/scripts/tests/twister_blackbox/test_runner.py b/scripts/tests/twister_blackbox/test_runner.py index e1b6a19470333..57ecef3fbfed2 100644 --- a/scripts/tests/twister_blackbox/test_runner.py +++ b/scripts/tests/twister_blackbox/test_runner.py @@ -128,9 +128,9 @@ class TestRunner: os.path.join(TEST_DATA, 'tests', 'dummy'), ['qemu_x86/atom'], ['device'], - ['dummy.agnostic.group2 SKIPPED: Command line testsuite tag filter', - 'dummy.agnostic.group1.subgroup2 SKIPPED: Command line testsuite tag filter', - 'dummy.agnostic.group1.subgroup1 SKIPPED: Command line testsuite tag filter', + ['dummy.agnostic.group2 FILTERED: Command line testsuite tag filter', + 'dummy.agnostic.group1.subgroup2 FILTERED: Command line testsuite tag filter', + 'dummy.agnostic.group1.subgroup1 FILTERED: Command line testsuite tag filter', r'0 of 0 executed test configurations passed \(0.00%\), 0 built \(not run\), 0 failed, 0 errored' ] ), @@ -138,7 +138,7 @@ class TestRunner: os.path.join(TEST_DATA, 'tests', 'dummy'), ['qemu_x86/atom'], ['subgrouped'], - ['dummy.agnostic.group2 SKIPPED: Command line testsuite tag filter', + ['dummy.agnostic.group2 FILTERED: Command line testsuite tag filter', r'1 of 2 executed test configurations passed \(50.00%\), 1 built \(not run\), 0 failed, 0 errored' ] ), @@ -556,8 +556,7 @@ def test_timeout_multiplier(self, capfd, out_path, test_path, test_platforms, ti out, err = capfd.readouterr() sys.stdout.write(out) sys.stderr.write(err) - - elapsed_time = float(re.search(r'Timeout \(qemu (\d+\.\d+)s\)', err).group(1)) + elapsed_time = float(re.search(r'Timeout \(qemu (\d+\.\d+)s.*\)', err).group(1)) assert abs( elapsed_time - float(timeout) * 10) <= tolerance, f"Time is different from expected" diff --git a/scripts/west-commands.yml b/scripts/west-commands.yml index c42d3aa290443..68a0951daf8fb 100644 --- a/scripts/west-commands.yml +++ b/scripts/west-commands.yml @@ -89,3 +89,8 @@ west-commands: - name: packages class: Packages help: manage packages for Zephyr + - file: scripts/west_commands/patch.py + commands: + - name: patch + class: Patch + help: manage patches for Zephyr modules diff --git a/scripts/west_commands/blobs.py b/scripts/west_commands/blobs.py index fd124eccc7834..618c2489c3b21 100644 --- a/scripts/west_commands/blobs.py +++ b/scripts/west_commands/blobs.py @@ -120,7 +120,7 @@ def fetch_blob(self, url, path): # Compare the checksum of a file we've just downloaded # to the digest in blob metadata, warn user if they differ. - def verify_blob(self, blob): + def verify_blob(self, blob) -> bool: self.dbg('Verifying blob {module}: {abspath}'.format(**blob)) status = zephyr_module.get_blob_status(blob['abspath'], blob['sha256']) @@ -140,8 +140,11 @@ def verify_blob(self, blob): Blob: {blob['path']} URL: {blob['url']} Info: {blob['description']}''')) + return False + return True def fetch(self, args): + bad_checksum_count = 0 blobs = self.get_blobs(args) for blob in blobs: if blob['status'] == zephyr_module.BLOB_PRESENT: @@ -149,7 +152,12 @@ def fetch(self, args): continue self.inf('Fetching blob {module}: {abspath}'.format(**blob)) self.fetch_blob(blob['url'], blob['abspath']) - self.verify_blob(blob) + if not self.verify_blob(blob): + bad_checksum_count += 1 + + if bad_checksum_count: + self.err(f"{bad_checksum_count} blobs have bad checksums") + sys.exit(os.EX_DATAERR) def clean(self, args): blobs = self.get_blobs(args) diff --git a/scripts/west_commands/packages.py b/scripts/west_commands/packages.py index 116a278cd7b06..795f3d4fe1399 100644 --- a/scripts/west_commands/packages.py +++ b/scripts/west_commands/packages.py @@ -95,6 +95,14 @@ def do_add_parser(self, parser_adder): "'--dry-run' to pip not to actually install anything, but print what would be.", ) + pip_parser.add_argument( + "--ignore-venv-check", + action="store_true", + help="Ignore the virtual environment check. " + "This is useful when running 'west packages pip --install' " + "in a CI environment where the virtual environment is not set up.", + ) + return parser def do_run(self, args, unknown): @@ -145,7 +153,7 @@ def do_run_pip(self, args, manager_args): requirements += [Path(module.project) / r for r in pip.get("requirement-files", [])] if args.install: - if not in_venv(): + if not in_venv() and not args.ignore_venv_check: self.die("Running pip install outside of a virtual environment") if len(requirements) > 0: diff --git a/scripts/west_commands/patch.py b/scripts/west_commands/patch.py new file mode 100644 index 0000000000000..618a45bc66a12 --- /dev/null +++ b/scripts/west_commands/patch.py @@ -0,0 +1,556 @@ +# Copyright (c) 2024 Tenstorrent AI ULC +# +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import hashlib +import os +import re +import shlex +import subprocess +import sys +import textwrap +import urllib.request +from pathlib import Path + +import pykwalify.core +import yaml +from west.commands import WestCommand + +sys.path.append(os.fspath(Path(__file__).parent.parent)) +import zephyr_module +from zephyr_ext_common import ZEPHYR_BASE + +try: + from yaml import CSafeDumper as SafeDumper + from yaml import CSafeLoader as SafeLoader +except ImportError: + from yaml import SafeDumper, SafeLoader + +WEST_PATCH_SCHEMA_PATH = Path(__file__).parents[1] / "schemas" / "patch-schema.yml" +with open(WEST_PATCH_SCHEMA_PATH) as f: + patches_schema = yaml.load(f, Loader=SafeLoader) + +WEST_PATCH_BASE = Path("zephyr") / "patches" +WEST_PATCH_YAML = Path("zephyr") / "patches.yml" + + +class Patch(WestCommand): + def __init__(self): + super().__init__( + "patch", + "apply patches to the west workspace", + "Apply patches to the west workspace", + accepts_unknown_args=False, + ) + + def do_add_parser(self, parser_adder): + parser = parser_adder.add_parser( + self.name, + help=self.help, + formatter_class=argparse.RawDescriptionHelpFormatter, + description=self.description, + epilog=textwrap.dedent("""\ + Applying Patches: + + Run "west patch apply" to apply patches. + See "west patch apply --help" for details. + + Cleaning Patches: + + Run "west patch clean" to clean patches. + See "west patch clean --help" for details. + + Listing Patches: + + Run "west patch list" to list patches. + See "west patch list --help" for details. + + Fetching Patches: + + Run "west patch gh-fetch" to fetch patches from Github. + See "west patch gh-fetch --help" for details. + + YAML File Format: + + The patches.yml syntax is described in "scripts/schemas/patch-schema.yml". + + patches: + - path: zephyr/kernel-pipe-fix-not-k-no-wait-and-ge-min-xfer-bytes.patch + sha256sum: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + module: zephyr + author: Kermit D. Frog + email: itsnoteasy@being.gr + date: 2020-04-20 + upstreamable: true + merge-pr: https://github.com/zephyrproject-rtos/zephyr/pull/24486 + issue: https://github.com/zephyrproject-rtos/zephyr/issues/24485 + merge-status: true + merge-commit: af926ae728c78affa89cbc1de811ab4211ed0f69 + merge-date: 2020-04-27 + apply-command: git apply + comments: | + Songs about rainbows - why are there so many?? + custom: + possible-muppets-to-ask-for-clarification-with-the-above-question: + - Miss Piggy + - Gonzo + - Fozzie Bear + - Animal + """), + ) + + parser.add_argument( + "-b", + "--patch-base", + help=f""" + Directory containing patch files (absolute or relative to module dir, + default: {WEST_PATCH_BASE})""", + metavar="DIR", + type=Path, + ) + parser.add_argument( + "-l", + "--patch-yml", + help=f""" + Path to patches.yml file (absolute or relative to module dir, + default: {WEST_PATCH_YAML})""", + metavar="FILE", + type=Path, + ) + parser.add_argument( + "-w", + "--west-workspace", + help="West workspace", + metavar="DIR", + type=Path, + ) + parser.add_argument( + "-sm", + "--src-module", + dest="src_module", + metavar="MODULE", + type=str, + help=""" + Zephyr module containing the patch definition (name, absolute path or + path relative to west-workspace)""", + ) + parser.add_argument( + "-dm", + "--dst-module", + action="append", + dest="dst_modules", + metavar="MODULE", + type=str, + help=""" + Zephyr module to run the 'patch' command for. + Option can be passed multiple times. + If this option is not given, the 'patch' command will run for Zephyr + and all modules.""", + ) + + subparsers = parser.add_subparsers( + dest="subcommand", + metavar="", + help="select a subcommand. If omitted treat it as 'list'", + ) + + apply_arg_parser = subparsers.add_parser( + "apply", + help="Apply patches", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=textwrap.dedent( + """ + Applying Patches: + + Run "west patch apply" to apply patches. + """ + ), + ) + apply_arg_parser.add_argument( + "-r", + "--roll-back", + help="Roll back if any patch fails to apply", + action="store_true", + default=False, + ) + + subparsers.add_parser( + "clean", + help="Clean patches", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=textwrap.dedent( + """ + Cleaning Patches: + + Run "west patch clean" to clean patches. + """ + ), + ) + + gh_fetch_arg_parser = subparsers.add_parser( + "gh-fetch", + help="Fetch patch from Github", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=textwrap.dedent( + """ + Fetching Patches from Github: + + Run "west patch gh-fetch" to fetch a PR from Github and store it as a patch. + The meta data is generated and appended to the provided patches.yml file. + + If no patches.yml file exists, it will be created. + """ + ), + ) + gh_fetch_arg_parser.add_argument( + "-o", + "--owner", + action="store", + default="zephyrproject-rtos", + help="Github repository owner", + ) + gh_fetch_arg_parser.add_argument( + "-r", + "--repo", + action="store", + default="zephyr", + help="Github repository", + ) + gh_fetch_arg_parser.add_argument( + "-pr", + "--pull-request", + metavar="ID", + action="store", + required=True, + type=int, + help="Github Pull Request ID", + ) + gh_fetch_arg_parser.add_argument( + "-m", + "--module", + metavar="DIR", + action="store", + required=True, + type=Path, + help="Module path", + ) + gh_fetch_arg_parser.add_argument( + "-s", + "--split-commits", + action="store_true", + help="Create patch files for each commit instead of a single patch for the entire PR", + ) + gh_fetch_arg_parser.add_argument( + '-t', + '--token', + metavar='FILE', + dest='tokenfile', + help='File containing GitHub token (alternatively, use GITHUB_TOKEN env variable)', + ) + + subparsers.add_parser( + "list", + help="List patches", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=textwrap.dedent( + """ + Listing Patches: + + Run "west patch list" to list patches. + """ + ), + ) + + return parser + + def filter_args(self, args): + try: + manifest_path = self.config.get("manifest.path") + except BaseException: + self.die("could not retrieve manifest path from west configuration") + + topdir = Path(self.topdir) + + if args.src_module is not None: + mod_path = self.get_module_path(args.src_module) + if mod_path is None: + self.die(f'Source module "{args.src_module}" not found') + if args.patch_base is not None and args.patch_base.is_absolute(): + self.die("patch-base must not be an absolute path in combination with src-module") + if args.patch_yml is not None and args.patch_yml.is_absolute(): + self.die("patch-yml must not be an absolute path in combination with src-module") + manifest_dir = topdir / mod_path + else: + manifest_dir = topdir / manifest_path + + if args.patch_base is None: + args.patch_base = manifest_dir / WEST_PATCH_BASE + if not args.patch_base.is_absolute(): + args.patch_base = manifest_dir / args.patch_base + + if args.patch_yml is None: + args.patch_yml = manifest_dir / WEST_PATCH_YAML + elif not args.patch_yml.is_absolute(): + args.patch_yml = manifest_dir / args.patch_yml + + if args.west_workspace is None: + args.west_workspace = topdir + elif not args.west_workspace.is_absolute(): + args.west_workspace = topdir / args.west_workspace + + if args.dst_modules is not None: + args.dst_modules = [self.get_module_path(m) for m in args.dst_modules] + + def load_yml(self, args, allow_missing): + if not os.path.isfile(args.patch_yml): + if not allow_missing: + self.inf(f"no patches to apply: {args.patch_yml} not found") + return None + + # Return the schema defaults + return pykwalify.core.Core(source_data={}, schema_data=patches_schema).validate() + + try: + with open(args.patch_yml) as f: + yml = yaml.load(f, Loader=SafeLoader) + return pykwalify.core.Core(source_data=yml, schema_data=patches_schema).validate() + except (yaml.YAMLError, pykwalify.errors.SchemaError) as e: + self.die(f"ERROR: Malformed yaml {args.patch_yml}: {e}") + + def do_run(self, args, _): + self.filter_args(args) + + west_config = Path(args.west_workspace) / ".west" / "config" + if not os.path.isfile(west_config): + self.die(f"{args.west_workspace} is not a valid west workspace") + + yml = self.load_yml(args, args.subcommand in ["gh-fetch"]) + if yml is None: + return + + if not args.subcommand: + args.subcommand = "list" + + method = { + "apply": self.apply, + "clean": self.clean, + "list": self.list, + "gh-fetch": self.gh_fetch, + } + + method[args.subcommand](args, yml, args.dst_modules) + + def apply(self, args, yml, dst_mods=None): + patches = yml.get("patches", []) + if not patches: + return + + patch_count = 0 + failed_patch = None + patched_mods = set() + + for patch_info in patches: + mod = self.get_module_path(patch_info["module"]) + if mod is None: + continue + + if dst_mods and mod not in dst_mods: + continue + + pth = patch_info["path"] + patch_path = os.path.realpath(Path(args.patch_base) / pth) + + apply_cmd = patch_info["apply-command"] + apply_cmd_list = shlex.split(apply_cmd) + + self.dbg(f"reading patch file {pth}") + patch_file_data = None + + try: + with open(patch_path, "rb") as pf: + patch_file_data = pf.read() + except Exception as e: + self.err(f"failed to read {pth}: {e}") + failed_patch = pth + break + + self.dbg("checking patch integrity... ", end="") + expect_sha256 = patch_info["sha256sum"] + hasher = hashlib.sha256() + hasher.update(patch_file_data) + actual_sha256 = hasher.hexdigest() + if actual_sha256 != expect_sha256: + self.dbg("FAIL") + self.err( + f"sha256 mismatch for {pth}:\n" + f"expect: {expect_sha256}\n" + f"actual: {actual_sha256}" + ) + failed_patch = pth + break + self.dbg("OK") + patch_count += 1 + patch_file_data = None + + mod_path = Path(args.west_workspace) / mod + patched_mods.add(mod) + + self.dbg(f"patching {mod}... ", end="") + apply_cmd += patch_path + apply_cmd_list.extend([patch_path]) + proc = subprocess.run(apply_cmd_list, cwd=mod_path) + if proc.returncode: + self.dbg("FAIL") + self.err(proc.stderr) + failed_patch = pth + break + self.dbg("OK") + + if not failed_patch: + self.inf(f"{patch_count} patches applied successfully \\o/") + return + + if args.roll_back: + self.clean(args, yml, patched_mods) + + self.die(f"failed to apply patch {failed_patch}") + + def clean(self, args, yml, dst_mods=None): + clean_cmd = yml["clean-command"] + checkout_cmd = yml["checkout-command"] + + if not clean_cmd and not checkout_cmd: + self.dbg("no clean or checkout commands specified") + return + + clean_cmd_list = shlex.split(clean_cmd) + checkout_cmd_list = shlex.split(checkout_cmd) + + for mod in yml.get("patches", []): + m = self.get_module_path(mod.get("module")) + if m is None: + continue + if dst_mods and m not in dst_mods: + continue + mod_path = Path(args.west_workspace) / m + + try: + if checkout_cmd: + self.dbg(f"Running '{checkout_cmd}' in {mod}.. ", end="") + proc = subprocess.run(checkout_cmd_list, capture_output=True, cwd=mod_path) + if proc.returncode: + self.dbg("FAIL") + self.err(f"{checkout_cmd} failed for {mod}\n{proc.stderr}") + else: + self.dbg("OK") + + if clean_cmd: + self.dbg(f"Running '{clean_cmd}' in {mod}.. ", end="") + proc = subprocess.run(clean_cmd_list, capture_output=True, cwd=mod_path) + if proc.returncode: + self.dbg("FAIL") + self.err(f"{clean_cmd} failed for {mod}\n{proc.stderr}") + else: + self.dbg("OK") + + except Exception as e: + # If this fails for some reason, just log it and continue + self.err(f"failed to clean up {mod}: {e}") + + def list(self, args, yml, dst_mods=None): + patches = yml.get("patches", []) + if not patches: + return + + for patch_info in patches: + if dst_mods and self.get_module_path(patch_info["module"]) not in dst_mods: + continue + self.inf(patch_info) + + def gh_fetch(self, args, yml, mods=None): + if mods: + self.die( + "Module filters are not available for the gh-fetch subcommand, " + "pass a single -m/--module argument after the subcommand." + ) + + try: + from github import Auth, Github + except ImportError: + self.die("PyGithub not found; can be installed with 'pip install PyGithub'") + + gh = Github(auth=Auth.Token(args.tokenfile) if args.tokenfile else None) + pr = gh.get_repo(f"{args.owner}/{args.repo}").get_pull(args.pull_request) + args.patch_base.mkdir(parents=True, exist_ok=True) + + if args.split_commits: + for cm in pr.get_commits(): + subject = cm.commit.message.splitlines()[0] + filename = "-".join(filter(None, re.split("[^a-zA-Z0-9]+", subject))) + ".patch" + + # No patch URL is provided by the API, but appending .patch to the HTML works too + urllib.request.urlretrieve(f"{cm.html_url}.patch", args.patch_base / filename) + + patch_info = { + "path": filename, + "sha256sum": self.get_file_sha256sum(args.patch_base / filename), + "module": str(args.module), + "author": cm.commit.author.name or "Hidden", + "email": cm.commit.author.email or "hidden@github.com", + "date": cm.commit.author.date.strftime("%Y-%m-%d"), + "upstreamable": True, + "merge-pr": pr.html_url, + "merge-status": pr.merged, + } + + yml.setdefault("patches", []).append(patch_info) + else: + filename = "-".join(filter(None, re.split("[^a-zA-Z0-9]+", pr.title))) + ".patch" + urllib.request.urlretrieve(pr.patch_url, args.patch_base / filename) + + patch_info = { + "path": filename, + "sha256sum": self.get_file_sha256sum(args.patch_base / filename), + "module": str(args.module), + "author": pr.user.name or "Hidden", + "email": pr.user.email or "hidden@github.com", + "date": pr.created_at.strftime("%Y-%m-%d"), + "upstreamable": True, + "merge-pr": pr.html_url, + "merge-status": pr.merged, + } + + yml.setdefault("patches", []).append(patch_info) + + args.patch_yml.parent.mkdir(parents=True, exist_ok=True) + with open(args.patch_yml, "w") as f: + yaml.dump(yml, f, Dumper=SafeDumper) + + @staticmethod + def get_file_sha256sum(filename: Path) -> str: + with open(filename, "rb") as fp: + digest = hashlib.file_digest(fp, "sha256") + + return digest.hexdigest() + + def get_module_path(self, module_name_or_path): + if module_name_or_path is None: + return None + + topdir = Path(self.topdir) + + if Path(module_name_or_path).is_absolute(): + if Path(module_name_or_path).is_dir(): + return Path(module_name_or_path).resolve().relative_to(topdir) + return None + + if (topdir / module_name_or_path).is_dir(): + return Path(module_name_or_path) + + all_modules = zephyr_module.parse_modules(ZEPHYR_BASE, self.manifest) + for m in all_modules: + if m.meta['name'] == module_name_or_path: + return Path(m.project).relative_to(topdir) + + return None diff --git a/scripts/west_commands/run_common.py b/scripts/west_commands/run_common.py index adfd2922fb98d..e5492ad2f7b89 100644 --- a/scripts/west_commands/run_common.py +++ b/scripts/west_commands/run_common.py @@ -6,6 +6,7 @@ '''Common code used by commands which execute runners. ''' +import importlib.util import re import argparse import logging @@ -28,7 +29,8 @@ from runners.core import BuildConfiguration import yaml -from zephyr_ext_common import ZEPHYR_SCRIPTS +import zephyr_module +from zephyr_ext_common import ZEPHYR_BASE, ZEPHYR_SCRIPTS # Runners depend on edtlib. Make sure the copy in the tree is # available to them before trying to import any. @@ -107,6 +109,13 @@ class SocBoardFilesProcessing: priority: int = IGNORED_RUN_ONCE_PRIORITY yaml: object = None +def import_from_path(module_name, file_path): + spec = importlib.util.spec_from_file_location(module_name, file_path) + module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = module + spec.loader.exec_module(module) + return module + def command_verb(command): return "flash" if command.name == "flash" else "debug" @@ -197,6 +206,14 @@ def do_run_common(command, user_args, user_runner_args, domain_file=None): dump_context(command, user_args, user_runner_args) return + # Import external module runners + for module in zephyr_module.parse_modules(ZEPHYR_BASE, command.manifest): + runners_ext = module.meta.get("runners", []) + for runner in runners_ext: + import_from_path( + module.meta.get("name", "runners_ext"), Path(module.project) / runner["file"] + ) + build_dir = get_build_dir(user_args) if not user_args.skip_rebuild: rebuild(command, build_dir, user_args) diff --git a/scripts/west_commands/runners/__init__.py b/scripts/west_commands/runners/__init__.py index 5fd582fc9527e..3ed333c24c28e 100644 --- a/scripts/west_commands/runners/__init__.py +++ b/scripts/west_commands/runners/__init__.py @@ -31,6 +31,7 @@ def _import_runner_module(runner_name): 'canopen_program', 'dediprog', 'dfu', + 'ecpprog', 'esp32', 'ezflashcli', 'gd32isp', diff --git a/scripts/west_commands/runners/bossac.py b/scripts/west_commands/runners/bossac.py index 227d6b5c82e7a..0cfbcc1adfe99 100644 --- a/scripts/west_commands/runners/bossac.py +++ b/scripts/west_commands/runners/bossac.py @@ -25,12 +25,13 @@ class BossacBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for bossac.''' def __init__(self, cfg, bossac='bossac', port=DEFAULT_BOSSAC_PORT, - speed=DEFAULT_BOSSAC_SPEED, boot_delay=0): + speed=DEFAULT_BOSSAC_SPEED, boot_delay=0, erase=False): super().__init__(cfg) self.bossac = bossac self.port = port self.speed = speed self.boot_delay = boot_delay + self.erase = erase @classmethod def name(cls): @@ -38,7 +39,7 @@ def name(cls): @classmethod def capabilities(cls): - return RunnerCaps(commands={'flash'}) + return RunnerCaps(commands={'flash'}, erase=True) @classmethod def do_add_parser(cls, parser): @@ -60,7 +61,7 @@ def do_add_parser(cls, parser): def do_create(cls, cfg, args): return BossacBinaryRunner(cfg, bossac=args.bossac, port=args.bossac_port, speed=args.speed, - boot_delay=args.delay) + boot_delay=args.delay, erase=args.erase) def read_help(self): """Run bossac --help and return the output as a list of lines""" @@ -180,9 +181,12 @@ def magic_delay(self): def make_bossac_cmd(self): self.ensure_output('bin') - cmd_flash = [self.bossac, '-p', self.port, '-R', '-e', '-w', '-v', + cmd_flash = [self.bossac, '-p', self.port, '-R', '-w', '-v', '-b', self.cfg.bin_file] + if self.erase: + cmd_flash += ['-e'] + dt_chosen_code_partition_nd = self.get_chosen_code_partition_node() if self.is_partition_enabled(): diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index cf01d2abf4538..20e4b72a8c388 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -920,22 +920,27 @@ def ensure_output(self, output_type: str) -> None: # RuntimeError avoids a stack trace saved in run_common. raise RuntimeError(err) - def run_telnet_client(self, host: str, port: int) -> None: + def run_telnet_client(self, host: str, port: int, active_sock=None) -> None: ''' Run a telnet client for user interaction. ''' - # If a `nc` command is available, run it, as it will provide the best support for - # CONFIG_SHELL_VT100_COMMANDS etc. - if shutil.which('nc') is not None: + # If the caller passed in an active socket, use that + if active_sock is not None: + sock = active_sock + elif shutil.which('nc') is not None: + # If a `nc` command is available, run it, as it will provide the + # best support for CONFIG_SHELL_VT100_COMMANDS etc. client_cmd = ['nc', host, str(port)] # Note: netcat (nc) does not handle sigint, so cannot use run_client() self.check_call(client_cmd) return + else: + # Start a new socket connection + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((host, port)) # Otherwise, use a pure python implementation. This will work well for logging, # but input is line based only. - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((host, port)) sel = selectors.DefaultSelector() sel.register(sys.stdin, selectors.EVENT_READ) sel.register(sock, selectors.EVENT_READ) diff --git a/scripts/west_commands/runners/ecpprog.py b/scripts/west_commands/runners/ecpprog.py new file mode 100644 index 0000000000000..48454c2c8a5aa --- /dev/null +++ b/scripts/west_commands/runners/ecpprog.py @@ -0,0 +1,41 @@ +# Copyright (c) 2024 tinyVision.ai Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +"""Runner for the ecpprog programming tool for Lattice FPGAs.""" +# https://github.com/gregdavill/ecpprog + +from runners.core import BuildConfiguration, RunnerCaps, ZephyrBinaryRunner + + +class EcpprogBinaryRunner(ZephyrBinaryRunner): + """Runner front-end for programming the FPGA flash at some offset.""" + + def __init__(self, cfg, device=None): + super().__init__(cfg) + self.device = device + + @classmethod + def name(cls): + return "ecpprog" + + @classmethod + def capabilities(cls): + return RunnerCaps(commands={"flash"}) + + @classmethod + def do_add_parser(cls, parser): + parser.add_argument( + "--device", dest="device", help="Device identifier such as i::" + ) + + @classmethod + def do_create(cls, cfg, args): + return EcpprogBinaryRunner(cfg, device=args.device) + + def do_run(self, command, **kwargs): + build_conf = BuildConfiguration(self.cfg.build_dir) + load_offset = build_conf.get("CONFIG_FLASH_LOAD_OFFSET", 0) + command = ("ecpprog", "-o", hex(load_offset), self.cfg.bin_file) + self.logger.debug(" ".join(command)) + self.check_call(command) diff --git a/scripts/west_commands/runners/esp32.py b/scripts/west_commands/runners/esp32.py index faaa2b047ebed..619c16460e853 100644 --- a/scripts/west_commands/runners/esp32.py +++ b/scripts/west_commands/runners/esp32.py @@ -19,7 +19,7 @@ def __init__(self, cfg, device, boot_address, part_table_address, app_address, erase=False, reset=False, baud=921600, flash_size='detect', flash_freq='40m', flash_mode='dio', espidf='espidf', bootloader_bin=None, partition_table_bin=None, - no_stub=False): + encrypt=False, no_stub=False): super().__init__(cfg) self.elf = cfg.elf_file self.app_bin = cfg.bin_file @@ -36,6 +36,7 @@ def __init__(self, cfg, device, boot_address, part_table_address, self.espidf = espidf self.bootloader_bin = bootloader_bin self.partition_table_bin = partition_table_bin + self.encrypt = encrypt self.no_stub = no_stub @classmethod @@ -78,6 +79,8 @@ def do_add_parser(cls, parser): help='Bootloader image to flash') parser.add_argument('--esp-flash-partition_table', help='Partition table to flash') + parser.add_argument('--esp-encrypt', default=False, action='store_true', + help='Encrypt firmware while flashing (correct efuses required)') parser.add_argument('--esp-no-stub', default=False, action='store_true', help='Disable launching the flasher stub, only talk to ROM bootloader') @@ -99,7 +102,7 @@ def do_create(cls, cfg, args): flash_freq=args.esp_flash_freq, flash_mode=args.esp_flash_mode, espidf=espidf, bootloader_bin=args.esp_flash_bootloader, partition_table_bin=args.esp_flash_partition_table, - no_stub=args.esp_no_stub) + encrypt=args.esp_encrypt, no_stub=args.esp_no_stub) def do_run(self, command, **kwargs): self.require(self.espidf) @@ -124,6 +127,9 @@ def do_run(self, command, **kwargs): cmd_flash.extend(['--flash_freq', self.flash_freq]) cmd_flash.extend(['--flash_size', self.flash_size]) + if self.encrypt: + cmd_flash.extend(['--encrypt']) + if self.bootloader_bin: cmd_flash.extend([self.boot_address, self.bootloader_bin]) if self.partition_table_bin: diff --git a/scripts/west_commands/runners/jlink.py b/scripts/west_commands/runners/jlink.py index cd2ea3e8d67e6..00438ba6e5dd4 100644 --- a/scripts/west_commands/runners/jlink.py +++ b/scripts/west_commands/runners/jlink.py @@ -5,6 +5,7 @@ '''Runner for debugging with J-Link.''' import argparse +import glob import ipaddress import logging import os @@ -25,7 +26,37 @@ except ImportError: MISSING_REQUIREMENTS = True -DEFAULT_JLINK_EXE = 'JLink.exe' if sys.platform == 'win32' else 'JLinkExe' +if sys.platform == 'win32': + # JLink.exe can collide with the JDK executable of the same name + # Look in the usual locations before falling back to $PATH + for root in [os.environ["ProgramFiles"], os.environ["ProgramFiles(x86)"], str(Path.home())]: # noqa SIM112 + # SEGGER folder can contain a single "JLink" folder + _direct = Path(root) / "SEGGER" / "JLink" / "JLink.exe" + if _direct.exists(): + DEFAULT_JLINK_EXE = str(_direct) + del _direct + else: + # SEGGER folder can contain multiple versions such as: + # JLink_V796b + # JLink_V796t + # JLink_V798c + # Find the latest version + _versions = glob.glob(str(Path(root) / "SEGGER" / "JLink_V*")) + if len(_versions) == 0: + continue + _expected_jlink = Path(_versions[-1]) / "JLink.exe" + if not _expected_jlink.exists(): + continue + DEFAULT_JLINK_EXE = str(_expected_jlink) + # Cleanup variables + del _versions + del _expected_jlink + break + else: + # Not found in the normal locations, hope that $PATH is correct + DEFAULT_JLINK_EXE = "JLink.exe" +else: + DEFAULT_JLINK_EXE = "JLinkExe" DEFAULT_JLINK_GDB_PORT = 2331 DEFAULT_JLINK_RTT_PORT = 19021 @@ -269,7 +300,7 @@ def do_run(self, command, **kwargs): + ['-speed', self.speed] + ['-device', self.device] + ['-silent'] - + ['-endian' 'big' if big_endian else 'little'] + + ['-endian', 'big' if big_endian else 'little'] + ['-singlerun'] + (['-nogui'] if self.supports_nogui else []) + (['-rtos', plugin_dir] if rtos else []) @@ -299,9 +330,7 @@ def do_run(self, command, **kwargs): break except ConnectionRefusedError: time.sleep(0.1) - sock.shutdown(socket.SHUT_RDWR) - time.sleep(0.1) - self.run_telnet_client('localhost', self.rtt_port) + self.run_telnet_client('localhost', self.rtt_port, sock) except Exception as e: self.logger.error(e) finally: diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index 1593f98828e72..5895456d8ea65 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -32,20 +32,23 @@ ErrVerify = 25 UICR_RANGES = { - 'NRF53_FAMILY': { - 'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800), - 'NRFDL_DEVICE_CORE_NETWORK': (0x01FF8000, 0x01FF8800), + 'nrf53': { + 'Application': (0x00FF8000, 0x00FF8800), + 'Network': (0x01FF8000, 0x01FF8800), }, - 'NRF54H_FAMILY': { - 'NRFDL_DEVICE_CORE_APPLICATION': (0x0FFF8000, 0x0FFF8800), - 'NRFDL_DEVICE_CORE_NETWORK': (0x0FFFA000, 0x0FFFA800), + 'nrf54h': { + 'Application': (0x0FFF8000, 0x0FFF8800), + 'Network': (0x0FFFA000, 0x0FFFA800), }, - 'NRF91_FAMILY': { - 'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800), + 'nrf54l': { + 'Application': (0x00FFD000, 0x00FFDA00), }, - 'NRF92_FAMILY': { - 'NRFDL_DEVICE_CORE_APPLICATION': (0x0FFF8000, 0x0FFF8800), - 'NRFDL_DEVICE_CORE_NETWORK': (0x0FFFA000, 0x0FFFA800), + 'nrf91': { + 'Application': (0x00FF8000, 0x00FF8800), + }, + 'nrf92': { + 'Application': (0x0FFF8000, 0x0FFF8800), + 'Network': (0x0FFFA000, 0x0FFFA800), }, } @@ -75,14 +78,14 @@ def _get_suit_starter(): class NrfBinaryRunner(ZephyrBinaryRunner): '''Runner front-end base class for nrf tools.''' - def __init__(self, cfg, family, softreset, dev_id, erase=False, + def __init__(self, cfg, family, softreset, pinreset, dev_id, erase=False, reset=True, tool_opt=None, force=False, recover=False): super().__init__(cfg) self.hex_ = cfg.hex_file - if family and not family.endswith('_FAMILY'): - family = f'{family}_FAMILY' - self.family = family + # The old --nrf-family options takes upper-case family names + self.family = family.lower() if family else None self.softreset = softreset + self.pinreset = pinreset self.dev_id = dev_id self.erase = bool(erase) self.reset = bool(reset) @@ -115,9 +118,14 @@ def do_add_parser(cls, parser): 'NRF54H', 'NRF91', 'NRF92'], help='''MCU family; still accepted for compatibility only''') + # Not using a mutual exclusive group for softreset and pinreset due to + # the way dump_runner_option_help() works in run_common.py parser.add_argument('--softreset', required=False, action='store_true', - help='use reset instead of pinreset') + help='use softreset instead of pinreset') + parser.add_argument('--pinreset', required=False, + action='store_true', + help='use pinreset instead of softreset') parser.add_argument('--snr', required=False, dest='dev_id', help='obsolete synonym for -i/--dev-id') parser.add_argument('--force', required=False, @@ -214,19 +222,19 @@ def ensure_family(self): return if self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF51X'): - self.family = 'NRF51_FAMILY' + self.family = 'nrf51' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF52X'): - self.family = 'NRF52_FAMILY' + self.family = 'nrf52' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF53X'): - self.family = 'NRF53_FAMILY' + self.family = 'nrf53' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54LX'): - self.family = 'NRF54L_FAMILY' + self.family = 'nrf54l' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54HX'): - self.family = 'NRF54H_FAMILY' + self.family = 'nrf54h' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF91X'): - self.family = 'NRF91_FAMILY' + self.family = 'nrf91' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF92X'): - self.family = 'NRF92_FAMILY' + self.family = 'nrf92' else: raise RuntimeError(f'unknown nRF; update {__file__}') @@ -251,7 +259,7 @@ def flush(self, force=False): self.flush_ops(force=force) except subprocess.CalledProcessError as cpe: if cpe.returncode == ErrNotAvailableBecauseProtection: - if self.family == 'NRF53_FAMILY': + if self.family == 'nrf53': family_help = ( ' Note: your target is an nRF53; all flash memory ' 'for both the network and application cores will be ' @@ -278,7 +286,7 @@ def flush(self, force=False): def recover_target(self): - if self.family in ('NRF53_FAMILY', 'NRF54H_FAMILY', 'NRF92_FAMILY'): + if self.family in ('nrf53', 'nrf54h', 'nrf92'): self.logger.info( 'Recovering and erasing flash memory for both the network ' 'and application cores.') @@ -291,36 +299,44 @@ def recover_target(self): # keeps the debug access port open, recovering the network core last # would result in that small image being deleted from the app core. # In the case of the 54H, the order is indifferent. - if self.family in ('NRF53_FAMILY', 'NRF54H_FAMILY', 'NRF92_FAMILY'): - self.exec_op('recover', core='NRFDL_DEVICE_CORE_NETWORK') + if self.family in ('nrf53', 'nrf54h', 'nrf92'): + self.exec_op('recover', core='Network') self.exec_op('recover') + def _get_core(self): + if self.family in ('nrf54h', 'nrf92'): + if (self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUAPP') or + self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUFLPR') or + self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUPPR') or + self.build_conf.getboolean('CONFIG_SOC_NRF9280_CPUAPP')): + return 'Application' + if (self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPURAD') or + self.build_conf.getboolean('CONFIG_SOC_NRF9280_CPURAD')): + return 'Network' + raise RuntimeError(f'Core not found for family: {self.family}') + + if self.family in ('nrf53'): + if self.build_conf.getboolean('CONFIG_SOC_NRF5340_CPUAPP'): + return 'Application' + if self.build_conf.getboolean('CONFIG_SOC_NRF5340_CPUNET'): + return 'Network' + raise RuntimeError(f'Core not found for family: {self.family}') + + return None + def program_hex(self): # Get the command use to actually program self.hex_. self.logger.info(f'Flashing file: {self.hex_}') # What type of erase/core arguments should we pass to the tool? - core = None + core = self._get_core() - if self.family in ('NRF54H_FAMILY', 'NRF92_FAMILY'): + if self.family in ('nrf54h', 'nrf92'): erase_arg = 'ERASE_NONE' - cpuapp = ( - self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUAPP') or - self.build_conf.getboolean('CONFIG_SOC_NRF9280_CPUAPP') - ) - cpurad = ( - self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPURAD') or - self.build_conf.getboolean('CONFIG_SOC_NRF9280_CPURAD') - ) generated_uicr = self.build_conf.getboolean('CONFIG_NRF_REGTOOL_GENERATE_UICR') - if cpuapp: - core = 'NRFDL_DEVICE_CORE_APPLICATION' - elif cpurad: - core = 'NRFDL_DEVICE_CORE_NETWORK' - if generated_uicr and not self.hex_get_uicrs().get(core): raise RuntimeError( f"Expected a UICR to be contained in: {self.hex_}\n" @@ -329,8 +345,8 @@ def program_hex(self): ) if self.erase: - self.exec_op('erase', core='NRFDL_DEVICE_CORE_APPLICATION') - self.exec_op('erase', core='NRFDL_DEVICE_CORE_NETWORK') + self.exec_op('erase', core='Application', kind='all') + self.exec_op('erase', core='Network', kind='all') # Manage SUIT artifacts. # This logic should be executed only once per build. @@ -354,7 +370,7 @@ def program_hex(self): 'ERASE_NONE', None, defer=True, - core='NRFDL_DEVICE_CORE_APPLICATION', + core='Application', ) if os.path.exists(rad_mpi_hex_file): self.op_program( @@ -362,13 +378,13 @@ def program_hex(self): 'ERASE_NONE', None, defer=True, - core='NRFDL_DEVICE_CORE_NETWORK', + core='Network', ) # Handle SUIT root manifest if application manifests are not used. # If an application firmware is built, the root envelope is merged # with other application manifests as well as the output HEX file. - if not cpuapp and self.sysbuild_conf.get('SB_CONFIG_SUIT_ENVELOPE'): + if core != 'Application' and self.sysbuild_conf.get('SB_CONFIG_SUIT_ENVELOPE'): app_root_envelope_hex_file = os.fspath( mpi_hex_dir / 'suit_installed_envelopes_application_merged.hex' ) @@ -378,117 +394,45 @@ def program_hex(self): 'ERASE_NONE', None, defer=True, - core='NRFDL_DEVICE_CORE_APPLICATION', + core='Application', ) if not self.erase and generated_uicr: - self.exec_op('erase', core=core, option={'chip_erase_mode': 'ERASE_UICR', - 'qspi_erase_mode': 'ERASE_NONE'}) + self.exec_op('erase', core=core, kind='uicr') else: if self.erase: erase_arg = 'ERASE_ALL' else: - if self.family == 'NRF52_FAMILY': - erase_arg = 'ERASE_PAGES_INCLUDING_UICR' - else: - erase_arg = 'ERASE_PAGES' + erase_arg = 'ERASE_RANGES_TOUCHED_BY_FIRMWARE' xip_ranges = { - 'NRF52_FAMILY': (0x12000000, 0x19FFFFFF), - 'NRF53_FAMILY': (0x10000000, 0x1FFFFFFF), + 'nrf52': (0x12000000, 0x19FFFFFF), + 'nrf53': (0x10000000, 0x1FFFFFFF), } - qspi_erase_opt = None + ext_mem_erase_opt = None if self.family in xip_ranges: xip_start, xip_end = xip_ranges[self.family] if self.hex_refers_region(xip_start, xip_end): - qspi_erase_opt = 'ERASE_ALL' - - # What tool commands do we need to flash this target? - if self.family == 'NRF53_FAMILY': - # nRF53 requires special treatment due to the extra coprocessor. - self.program_hex_nrf53(erase_arg, qspi_erase_opt) - else: - self.op_program(self.hex_, erase_arg, qspi_erase_opt, defer=True, core=core) + ext_mem_erase_opt = erase_arg + self.op_program(self.hex_, erase_arg, ext_mem_erase_opt, defer=True, core=core) self.flush(force=False) - def program_hex_nrf53(self, erase_arg, qspi_erase_opt): - # program_hex() helper for nRF53. - - # *********************** NOTE ******************************* - # self.hex_ can contain code for both the application core and - # the network core. - # - # We can't assume, for example, that - # CONFIG_SOC_NRF5340_CPUAPP=y means self.hex_ only contains - # data for the app core's flash: the user can put arbitrary - # addresses into one of the files in HEX_FILES_TO_MERGE. - # - # Therefore, on this family, we may need to generate two new - # hex files, one for each core, and flash them individually - # with the correct '--coprocessor' arguments. - # - # Kind of hacky, but it works, and the tools are not capable of - # flashing to both cores at once. If self.hex_ only affects - # one core's flash, then we skip the extra work to save time. - # ************************************************************ - - # Address range of the network coprocessor's flash. From nRF5340 OPS. - # We should get this from DTS instead if multiple values are possible, - # but this is fine for now. - net_flash_start = 0x01000000 - net_flash_end = 0x0103FFFF - - # If there is nothing in the hex file for the network core, - # only the application core is programmed. - if not self.hex_refers_region(net_flash_start, net_flash_end): - self.op_program(self.hex_, erase_arg, qspi_erase_opt, defer=True, - core='NRFDL_DEVICE_CORE_APPLICATION') - # If there is some content that addresses a region beyond the network - # core flash range, two hex files are generated and the two cores - # are programmed one by one. - elif self.hex_contents.minaddr() < net_flash_start or \ - self.hex_contents.maxaddr() > net_flash_end: - - net_hex, app_hex = IntelHex(), IntelHex() - for start, end in self.hex_contents.segments(): - if net_flash_start <= start <= net_flash_end: - net_hex.merge(self.hex_contents[start:end]) - else: - app_hex.merge(self.hex_contents[start:end]) - - hex_path = Path(self.hex_) - hex_dir, hex_name = hex_path.parent, hex_path.name - - net_hex_file = os.fspath( - hex_dir / f'GENERATED_CP_NETWORK_{hex_name}') - app_hex_file = os.fspath( - hex_dir / f'GENERATED_CP_APPLICATION_{hex_name}') - - self.logger.info( - f'{self.hex_} targets both nRF53 coprocessors; ' - f'splitting it into: {net_hex_file} and {app_hex_file}') - - net_hex.write_hex_file(net_hex_file) - app_hex.write_hex_file(app_hex_file) - - self.op_program(net_hex_file, erase_arg, None, defer=True, - core='NRFDL_DEVICE_CORE_NETWORK') - self.op_program(app_hex_file, erase_arg, qspi_erase_opt, defer=True, - core='NRFDL_DEVICE_CORE_APPLICATION') - # Otherwise, only the network core is programmed. - else: - self.op_program(self.hex_, erase_arg, None, defer=True, - core='NRFDL_DEVICE_CORE_NETWORK') def reset_target(self): - if self.family == 'NRF52_FAMILY' and not self.softreset: + sw_reset = "RESET_HARD" if self.family in ('nrf54h', 'nrf92') else "RESET_SYSTEM" + # Default to soft reset on nRF52 only, because ICs in these series can + # reconfigure the reset pin as a regular GPIO + default = sw_reset if self.family == 'nrf52' else "RESET_PIN" + kind = (sw_reset if self.softreset else "RESET_PIN" if + self.pinreset else default) + + if self.family == 'nrf52' and kind == "RESET_PIN": + # Write to the UICR enabling nRESET in the corresponding pin self.exec_op('pinreset-enable') - if self.softreset: - self.exec_op('reset', option="RESET_SYSTEM") - else: - self.exec_op('reset', option="RESET_PIN") + self.logger.debug(f'Reset kind: {kind}') + self.exec_op('reset', kind=kind) @abc.abstractmethod def do_require(self): @@ -498,7 +442,7 @@ def _check_suit_starter(self, op): op = op['operation'] if op['type'] not in ('erase', 'recover', 'program'): return None - if op['type'] == 'program' and op['chip_erase_mode'] != "ERASE_UICR": + if op['type'] == 'program' and op['options']['chip_erase_mode'] != "ERASE_UICR": return None file = _get_suit_starter() @@ -506,15 +450,15 @@ def _check_suit_starter(self, op): return file - def op_program(self, hex_file, erase, qspi_erase, defer=False, core=None): - args = self._op_program(hex_file, erase, qspi_erase) + def op_program(self, hex_file, erase, ext_mem_erase, defer=False, core=None): + args = self._op_program(hex_file, erase, ext_mem_erase) self.exec_op('program', defer, core, **args) - def _op_program(self, hex_file, erase, qspi_erase): + def _op_program(self, hex_file, erase, ext_mem_erase): args = {'firmware': {'file': hex_file}, - 'chip_erase_mode': erase, 'verify': 'VERIFY_READ'} - if qspi_erase: - args['qspi_erase_mode'] = qspi_erase + 'options': {'chip_erase_mode': erase, 'verify': 'VERIFY_READ'}} + if ext_mem_erase: + args['options']['ext_mem_erase_mode'] = ext_mem_erase return args @@ -533,7 +477,7 @@ def _exec_op(op, defer=False, core=None, **kwargs): _op = _exec_op(op, defer, core, **kwargs) # Check if the suit manifest starter needs programming - if self.suit_starter and self.family == 'NRF54H_FAMILY': + if self.suit_starter and self.family == 'nrf54h': file = self._check_suit_starter(_op) if file: args = self._op_program(file, 'ERASE_NONE', None) @@ -558,6 +502,10 @@ def flush_ops(self, force=True): def do_run(self, command, **kwargs): self.do_require() + if self.softreset and self.pinreset: + raise RuntimeError('Options --softreset and --pinreset are mutually ' + 'exclusive.') + self.ensure_output('hex') if IntelHex is None: raise RuntimeError('Python dependency intelhex was missing; ' diff --git a/scripts/west_commands/runners/nrfjprog.py b/scripts/west_commands/runners/nrfjprog.py index c4e06efcd8849..36461b7236de6 100644 --- a/scripts/west_commands/runners/nrfjprog.py +++ b/scripts/west_commands/runners/nrfjprog.py @@ -17,11 +17,11 @@ class NrfJprogBinaryRunner(NrfBinaryRunner): '''Runner front-end for nrfjprog.''' - def __init__(self, cfg, family, softreset, dev_id, erase=False, + def __init__(self, cfg, family, softreset, pinreset, dev_id, erase=False, reset=True, tool_opt=None, force=False, recover=False, qspi_ini=None): - super().__init__(cfg, family, softreset, dev_id, erase, reset, + super().__init__(cfg, family, softreset, pinreset, dev_id, erase, reset, tool_opt, force, recover) self.qspi_ini = qspi_ini @@ -37,7 +37,7 @@ def tool_opt_help(cls) -> str: @classmethod def do_create(cls, cfg, args): return NrfJprogBinaryRunner(cfg, args.nrf_family, args.softreset, - args.dev_id, erase=args.erase, + args.pinreset, args.dev_id, erase=args.erase, reset=args.reset, tool_opt=args.tool_opt, force=args.force, recover=args.recover, qspi_ini=args.qspi_ini) @@ -58,11 +58,11 @@ def do_exec_op(self, op, force=False): self.logger.debug(f'Executing op: {op}') # Translate the op - families = {'NRF51_FAMILY': 'NRF51', 'NRF52_FAMILY': 'NRF52', - 'NRF53_FAMILY': 'NRF53', 'NRF54L_FAMILY': 'NRF54L', - 'NRF91_FAMILY': 'NRF91'} - cores = {'NRFDL_DEVICE_CORE_APPLICATION': 'CP_APPLICATION', - 'NRFDL_DEVICE_CORE_NETWORK': 'CP_NETWORK'} + families = {'nrf51': 'NRF51', 'nrf52': 'NRF52', + 'nrf53': 'NRF53', 'nrf54l': 'NRF54L', + 'nrf91': 'NRF91'} + cores = {'Application': 'CP_APPLICATION', + 'Network': 'CP_NETWORK'} core_opt = ['--coprocessor', cores[op['core']]] \ if op.get('core') else [] @@ -76,22 +76,27 @@ def do_exec_op(self, op, force=False): elif op_type == 'program': cmd.append('--program') cmd.append(_op['firmware']['file']) - erase = _op['chip_erase_mode'] + opts = _op['options'] + erase = opts['chip_erase_mode'] if erase == 'ERASE_ALL': cmd.append('--chiperase') - elif erase == 'ERASE_PAGES': - cmd.append('--sectorerase') - elif erase == 'ERASE_PAGES_INCLUDING_UICR': - cmd.append('--sectoranduicrerase') + elif erase == 'ERASE_RANGES_TOUCHED_BY_FIRMWARE': + if self.family == 'nrf52': + cmd.append('--sectoranduicrerase') + else: + cmd.append('--sectorerase') elif erase == 'NO_ERASE': pass else: raise RuntimeError(f'Invalid erase mode: {erase}') - if _op.get('qspi_erase_mode'): - # In the future there might be multiple QSPI erase modes - cmd.append('--qspisectorerase') - if _op.get('verify'): + if opts.get('ext_mem_erase_mode'): + if opts['ext_mem_erase_mode'] == 'ERASE_RANGES_TOUCHED_BY_FIRMWARE': + cmd.append('--qspisectorerase') + elif opts['ext_mem_erase_mode'] == 'ERASE_ALL': + cmd.append('--qspichiperase') + + if opts.get('verify'): # In the future there might be multiple verify modes cmd.append('--verify') if self.qspi_ini: @@ -100,13 +105,12 @@ def do_exec_op(self, op, force=False): elif op_type == 'recover': cmd.append('--recover') elif op_type == 'reset': - if _op['option'] == 'RESET_SYSTEM': + if _op['kind'] == 'RESET_SYSTEM': cmd.append('--reset') - if _op['option'] == 'RESET_PIN': + if _op['kind'] == 'RESET_PIN': cmd.append('--pinreset') - elif op_type == 'erasepage': - cmd.append('--erasepage') - cmd.append(f"0x{_op['page']:08x}") + elif op_type == 'erase': + cmd.append(f'--erase{_op["kind"]}') else: raise RuntimeError(f'Invalid operation: {op_type}') diff --git a/scripts/west_commands/runners/nrfutil.py b/scripts/west_commands/runners/nrfutil.py index ced68d2e95234..f937da74c071b 100644 --- a/scripts/west_commands/runners/nrfutil.py +++ b/scripts/west_commands/runners/nrfutil.py @@ -5,7 +5,6 @@ '''Runner for flashing with nrfutil.''' import json -import os import subprocess import sys from pathlib import Path @@ -17,14 +16,15 @@ class NrfUtilBinaryRunner(NrfBinaryRunner): '''Runner front-end for nrfutil.''' - def __init__(self, cfg, family, softreset, dev_id, erase=False, + def __init__(self, cfg, family, softreset, pinreset, dev_id, erase=False, reset=True, tool_opt=None, force=False, recover=False, - suit_starter=False): + suit_starter=False, ext_mem_config_file=None): - super().__init__(cfg, family, softreset, dev_id, erase, reset, + super().__init__(cfg, family, softreset, pinreset, dev_id, erase, reset, tool_opt, force, recover) self.suit_starter = suit_starter + self.ext_mem_config_file = ext_mem_config_file self._ops = [] self._op_id = 1 @@ -40,11 +40,12 @@ def tool_opt_help(cls) -> str: @classmethod def do_create(cls, cfg, args): return NrfUtilBinaryRunner(cfg, args.nrf_family, args.softreset, - args.dev_id, erase=args.erase, + args.pinreset, args.dev_id, erase=args.erase, reset=args.reset, tool_opt=args.tool_opt, force=args.force, recover=args.recover, - suit_starter=args.suit_manifest_starter) + suit_starter=args.suit_manifest_starter, + ext_mem_config_file=args.ext_mem_config_file) @classmethod def do_add_parser(cls, parser): @@ -52,6 +53,10 @@ def do_add_parser(cls, parser): parser.add_argument('--suit-manifest-starter', required=False, action='store_true', help='Use the SUIT manifest starter file') + parser.add_argument('--ext-mem-config-file', required=False, + dest='ext_mem_config_file', + help='path to an JSON file with external memory configuration') + def _exec(self, args): jout_all = [] @@ -102,24 +107,51 @@ def _insert_op(self, op): self._op_id += 1 self._ops.append(op) - def _exec_batch(self): - # prepare the dictionary and convert to JSON - batch = json.dumps({'family': f'{self.family}', - 'operations': [op for op in self._ops]}, - indent=4) + '\n' - - hex_dir = Path(self.hex_).parent - json_file = os.fspath(hex_dir / 'generated_nrfutil_batch.json') + def _append_batch(self, op, json_file): + _op = op['operation'] + op_type = _op['type'] + + cmd = [f'{op_type}'] + + if op_type == 'program': + cmd += ['--firmware', _op['firmware']['file']] + opts = _op['options'] + # populate the options + cmd.append('--options') + cli_opts = f"chip_erase_mode={opts['chip_erase_mode']}" + if opts.get('ext_mem_erase_mode'): + cli_opts += f",ext_mem_erase_mode={opts['ext_mem_erase_mode']}" + if opts.get('verify'): + cli_opts += f",verify={opts['verify']}" + cmd.append(cli_opts) + elif op_type == 'reset': + cmd += ['--reset-kind', _op['kind']] + elif op_type == 'erase': + cmd.append(f'--{_op["kind"]}') + + cmd += ['--core', op['core']] if op.get('core') else [] + cmd += ['--x-family', f'{self.family}'] + cmd += ['--x-append-batch', f'{json_file}'] + self._exec(cmd) - with open(json_file, "w") as f: - f.write(batch) + def _exec_batch(self): + # Use x-append-batch to get the JSON from nrfutil itself + json_file = Path(self.hex_).parent / 'generated_nrfutil_batch.json' + json_file.unlink(missing_ok=True) + for op in self._ops: + self._append_batch(op, json_file) # reset first in case an exception is thrown self._ops = [] self._op_id = 1 self.logger.debug(f'Executing batch in: {json_file}') - self._exec(['x-execute-batch', '--batch-path', f'{json_file}', - '--serial-number', f'{self.dev_id}']) + precmd = [] + if self.ext_mem_config_file: + # This needs to be prepended, as it's a global option + precmd = ['--x-ext-mem-config-file', self.ext_mem_config_file] + + self._exec(precmd + ['x-execute-batch', '--batch-path', f'{json_file}', + '--serial-number', f'{self.dev_id}']) def do_exec_op(self, op, force=False): self.logger.debug(f'Executing op: {op}') diff --git a/scripts/west_commands/runners/openocd.py b/scripts/west_commands/runners/openocd.py index 9b39791e1eee5..d30992a30a00b 100644 --- a/scripts/west_commands/runners/openocd.py +++ b/scripts/west_commands/runners/openocd.py @@ -9,11 +9,16 @@ import re import subprocess +from os import name as os_name from os import path from pathlib import Path from zephyr_ext_common import ZEPHYR_BASE +if os_name != "nt": + import sys + import termios + try: # noqa SIM105 from elftools.elf.elffile import ELFFile except ImportError: @@ -44,8 +49,8 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner): '''Runner front-end for openocd.''' def __init__(self, cfg, pre_init=None, reset_halt_cmd=DEFAULT_OPENOCD_RESET_HALT_CMD, - pre_load=None, load_cmd=None, verify_cmd=None, post_verify=None, - do_verify=False, do_verify_only=False, + pre_load=None, erase_cmd=None, load_cmd=None, verify_cmd=None, + post_verify=None, do_verify=False, do_verify_only=False, do_erase=False, tui=None, config=None, serial=None, use_elf=None, no_halt=False, no_init=False, no_targets=False, tcl_port=DEFAULT_OPENOCD_TCL_PORT, @@ -93,11 +98,13 @@ def __init__(self, cfg, pre_init=None, reset_halt_cmd=DEFAULT_OPENOCD_RESET_HALT self.pre_init = pre_init or [] self.reset_halt_cmd = reset_halt_cmd self.pre_load = pre_load or [] + self.erase_cmd = erase_cmd self.load_cmd = load_cmd self.verify_cmd = verify_cmd self.post_verify = post_verify or [] self.do_verify = do_verify or False self.do_verify_only = do_verify_only or False + self.do_erase = do_erase or False self.tcl_port = tcl_port self.telnet_port = telnet_port self.gdb_port = gdb_port @@ -120,7 +127,8 @@ def name(cls): @classmethod def capabilities(cls): - return RunnerCaps(commands={'flash', 'debug', 'debugserver', 'attach', 'rtt'}, rtt=True) + return RunnerCaps(commands={'flash', 'debug', 'debugserver', 'attach', 'rtt'}, + rtt=True, erase=True) @classmethod def do_add_parser(cls, parser): @@ -142,6 +150,8 @@ def do_add_parser(cls, parser): parser.add_argument('--cmd-pre-load', action='append', help='''Command to run before flashing; may be given multiple times''') + parser.add_argument('--cmd-erase', action='append', + help='''Command to erase device; may be given multiple times''') parser.add_argument('--cmd-load', help='''Command to load/flash binary (required when flashing)''') @@ -191,9 +201,9 @@ def do_create(cls, cfg, args): return OpenOcdBinaryRunner( cfg, pre_init=args.cmd_pre_init, reset_halt_cmd=args.cmd_reset_halt, - pre_load=args.cmd_pre_load, load_cmd=args.cmd_load, + pre_load=args.cmd_pre_load, erase_cmd=args.cmd_erase, load_cmd=args.cmd_load, verify_cmd=args.cmd_verify, post_verify=args.cmd_post_verify, - do_verify=args.verify, do_verify_only=args.verify_only, + do_verify=args.verify, do_verify_only=args.verify_only, do_erase=args.erase, tui=args.tui, config=args.config, serial=args.serial, use_elf=args.use_elf, no_halt=args.no_halt, no_init=args.no_init, no_targets=args.no_targets, tcl_port=args.tcl_port, @@ -222,7 +232,7 @@ def read_version(self): out = self.check_output([self.openocd_cmd[0], '--version'], stderr=subprocess.STDOUT).decode() - version_match = re.search(r"Open On-Chip Debugger (\d+.\d+.\d+)", out) + version_match = re.search(r"Open On-Chip Debugger v?(\d+.\d+.\d+)", out) version = version_match.group(1).split('.') return [to_num(i) for i in version] @@ -285,8 +295,20 @@ def do_flash(self, **kwargs): load_image = [] if not self.do_verify_only: - load_image = ['-c', self.reset_halt_cmd, - '-c', self.load_cmd + ' ' + hex_name] + # Halt target + load_image = ['-c', self.reset_halt_cmd] + # Perform any erase operations + if self.do_erase: + if self.erase_cmd is None: + self.logger.error('--erase not supported for target without --cmd-erase') + return + for erase_cmd in self.erase_cmd: + load_image += ["-c", erase_cmd] + # Trim the "erase" from "flash write_image erase" since a mass erase is already done + if self.load_cmd.endswith(' erase'): + self.load_cmd = self.load_cmd[:-6] + # Load image + load_image +=['-c', self.load_cmd + ' ' + hex_name] verify_image = [] if self.do_verify or self.do_verify_only: @@ -396,16 +418,38 @@ def do_attach_debug_rtt(self, command, **kwargs): self.print_gdbserver_message() if command in ('attach', 'debug'): - self.run_server_and_client(server_cmd, gdb_cmd) + server_proc = self.popen_ignore_int(server_cmd, stderr=subprocess.DEVNULL) + try: + self.run_client(gdb_cmd) + finally: + server_proc.terminate() + server_proc.wait() elif command == 'rtt': self.print_rttserver_message() server_proc = self.popen_ignore_int(server_cmd) + + if os_name != 'nt': + # Save the terminal settings + fd = sys.stdin.fileno() + new_term = termios.tcgetattr(fd) + old_term = termios.tcgetattr(fd) + + # New terminal setting unbuffered + new_term[3] = new_term[3] & ~termios.ICANON & ~termios.ECHO + termios.tcsetattr(fd, termios.TCSAFLUSH, new_term) + else: + fd = None + old_term = None + try: # run the binary with gdb, set up the rtt server (runs to completion) subprocess.run(gdb_cmd) # run the rtt client in the foreground self.run_telnet_client('localhost', self.rtt_port) finally: + if old_term is not None and fd is not None: + termios.tcsetattr(fd, termios.TCSAFLUSH, old_term) + server_proc.terminate() server_proc.wait() diff --git a/scripts/west_commands/runners/stm32cubeprogrammer.py b/scripts/west_commands/runners/stm32cubeprogrammer.py index a1e53d8b60ff5..032e40837bf88 100644 --- a/scripts/west_commands/runners/stm32cubeprogrammer.py +++ b/scripts/west_commands/runners/stm32cubeprogrammer.py @@ -7,6 +7,7 @@ """ import argparse +import functools import os import platform import shlex @@ -33,6 +34,10 @@ def __init__( port: str, frequency: int | None, reset_mode: str | None, + download_address: int | None, + download_modifiers: list[str], + start_address: int | None, + start_modifiers: list[str], conn_modifiers: str | None, cli: Path | None, use_elf: bool, @@ -44,6 +49,17 @@ def __init__( self._port = port self._frequency = frequency + + self._download_address = download_address + self._download_modifiers: list[str] = list() + for opts in [shlex.split(opt) for opt in download_modifiers]: + self._download_modifiers += opts + + self._start_address = start_address + self._start_modifiers: list[str] = list() + for opts in [shlex.split(opt) for opt in start_modifiers]: + self._start_modifiers += opts + self._reset_mode = reset_mode self._conn_modifiers = conn_modifiers self._cli = ( @@ -146,6 +162,38 @@ def do_add_parser(cls, parser): choices=["sw", "hw", "core"], help="Reset mode", ) + parser.add_argument( + "--download-address", + # To accept arguments in hex format, a wrapper lambda around int() must be used. + # Wrapping the lambda with functools.wraps() makes it so that 'invalid int value' + # is displayed when an invalid value is provided for this argument. + type=functools.wraps(int)(lambda s: int(s, base=0)), + required=False, + help="Address where flashing should be done" + ) + parser.add_argument( + "--download-modifiers", + default=[], + required=False, + action='append', + help="Additional options for the --download argument" + ) + parser.add_argument( + "--start-address", + # To accept arguments in hex format, a wrapper lambda around int() must be used. + # Wrapping the lambda with functools.wraps() makes it so that 'invalid int value' + # is displayed when an invalid value is provided for this argument. + type=functools.wraps(int)(lambda s: int(s, base=0)), + required=False, + help="Address where execution should begin after flashing" + ) + parser.add_argument( + "--start-modifiers", + default=[], + required=False, + action='append', + help="Additional options for the --start argument" + ) parser.add_argument( "--conn-modifiers", type=str, @@ -182,6 +230,10 @@ def do_create( port=args.port, frequency=args.frequency, reset_mode=args.reset_mode, + download_address=args.download_address, + download_modifiers=args.download_modifiers, + start_address=args.start_address, + start_modifiers=args.start_modifiers, conn_modifiers=args.conn_modifiers, cli=args.cli, use_elf=args.use_elf, @@ -220,9 +272,30 @@ def flash(self, **kwargs) -> None: self.check_call(cmd + ["--erase", "all"]) # flash image and run application - dl_file = self.cfg.elf_file if self._use_elf else self.cfg.hex_file + if self._use_elf: + dl_file = self.cfg.elf_file + elif self.cfg.bin_file is not None and os.path.isfile(self.cfg.bin_file) and \ + "zephyr.signed" in self.cfg.bin_file: + dl_file = self.cfg.bin_file + elif self.cfg.hex_file is not None and os.path.isfile(self.cfg.hex_file): + # --user-elf not used and no bin file given, default to hex + dl_file = self.cfg.hex_file if dl_file is None: raise RuntimeError('cannot flash; no download file was specified') elif not os.path.isfile(dl_file): raise RuntimeError(f'download file {dl_file} does not exist') - self.check_call(cmd + ["--download", dl_file, "--start"]) + + flash_and_run_args = ["--download", dl_file] + if self._download_address is not None: + flash_and_run_args.append(f"0x{self._download_address:X}") + flash_and_run_args += self._download_modifiers + + # '--start' is needed to start execution after flash. + # The default start address is the beggining of the flash, + # but another value can be explicitly specified if desired. + flash_and_run_args.append("--start") + if self._start_address is not None: + flash_and_run_args.append(f"0x{self._start_address:X}") + flash_and_run_args += self._start_modifiers + + self.check_call(cmd + flash_and_run_args) diff --git a/scripts/west_commands/runners/xsdb.py b/scripts/west_commands/runners/xsdb.py index e084a917a0ccc..7029a3a9354ae 100644 --- a/scripts/west_commands/runners/xsdb.py +++ b/scripts/west_commands/runners/xsdb.py @@ -54,5 +54,5 @@ def do_run(self, command, **kwargs): elif self.fsbl: cmd = ['xsdb', self.xsdb_cfg_file, self.elf_file, self.fsbl] else: - cmd = ['xsdb', self.xsdb_cfg_file] + cmd = ['xsdb', self.xsdb_cfg_file, self.elf_file] self.check_call(cmd) diff --git a/scripts/west_commands/sdk.py b/scripts/west_commands/sdk.py index 396edc9228225..8a84f063dc9b6 100755 --- a/scripts/west_commands/sdk.py +++ b/scripts/west_commands/sdk.py @@ -4,6 +4,7 @@ import argparse import hashlib +import io import os import patoolib import platform @@ -14,6 +15,7 @@ import subprocess import tempfile import textwrap +import tqdm import zcmake from pathlib import Path @@ -313,10 +315,41 @@ def download_and_extract(self, base_dir, dir_name, target_release, req_headers): total_length = int(resp.headers["Content-Length"]) count = 0 + class WestLogAdapter(io.StringIO): + buf = [] + ctx = None + + def __init__(self, ctx): + super(__class__, self).__init__() + self.ctx = ctx + + def write(self, buf): + try: + self.ctx.inf(buf, colorize=False, end='') + except TypeError: + # West v1.1.0 and earlier versions do not support the end parameter. + self.ctx.inf(buf, colorize=False) + + def flush(self): + pass + + tbar = tqdm.tqdm( + total=total_length, + file=WestLogAdapter(self), + desc=Path(file.name).name, + unit_scale=True, + ncols=shutil.get_terminal_size().columns, + unit="", + bar_format="{desc}: {percentage:3.0f}%|{bar}| {n_fmt} {rate_fmt} [{elapsed}] ", + ) + for chunk in resp.iter_content(chunk_size=8192): + tbar.update(len(chunk)) file.write(chunk) count = count + len(chunk) - self.inf(f"\r {count}/{total_length}", end="") + + tbar.close() + self.inf() self.inf(f"Downloaded: {file.name}") file.close() diff --git a/scripts/west_commands/sign.py b/scripts/west_commands/sign.py index 6f11e673a1782..411563068b0ca 100644 --- a/scripts/west_commands/sign.py +++ b/scripts/west_commands/sign.py @@ -12,6 +12,8 @@ import subprocess import sys +from elftools.elf.elffile import ELFFile + from west import manifest from west.commands import Verbosity from west.util import quote_sh_list @@ -419,6 +421,17 @@ def rimage_config_dir(self): self.command.dbg(f'rimage config directory={conf_dir}') return conf_dir + def generate_uuid_registry(self): + 'Runs the uuid-registry.h generator script' + + generate_cmd = [sys.executable, str(self.sof_src_dir / 'scripts' / 'gen-uuid-reg.py'), + str(self.sof_src_dir / 'uuid-registry.txt'), + str(pathlib.Path('zephyr') / 'include' / 'generated' / 'uuid-registry.h') + ] + + self.command.inf(quote_sh_list(generate_cmd)) + subprocess.run(generate_cmd, check=True, cwd=self.build_dir) + def preprocess_toml(self, config_dir, toml_basename, subdir): 'Runs the C pre-processor on config_dir/toml_basename.h' @@ -442,9 +455,16 @@ def preprocess_toml(self, config_dir, toml_basename, subdir): preproc_cmd += ['-I', str(self.sof_src_dir / 'src')] preproc_cmd += ['-imacros', str(pathlib.Path('zephyr') / 'include' / 'generated' / 'zephyr' / 'autoconf.h')] + preproc_cmd += ['-imacros', + str(pathlib.Path('zephyr') / 'include' / 'generated' / 'uuid-registry.h')] + + # Need to preprocess the TOML file twice: once with + # LLEXT_FORCE_ALL_MODULAR defined and once without it + full_preproc_cmd = preproc_cmd + ['-o', str(subdir / 'rimage_config_full.toml'), '-DLLEXT_FORCE_ALL_MODULAR'] preproc_cmd += ['-o', str(subdir / 'rimage_config.toml')] self.command.inf(quote_sh_list(preproc_cmd)) subprocess.run(preproc_cmd, check=True, cwd=self.build_dir) + subprocess.run(full_preproc_cmd, check=True, cwd=self.build_dir) def sign(self, command, build_dir, build_conf, formats): self.command = command @@ -469,19 +489,26 @@ def sign(self, command, build_dir, build_conf, formats): kernel_name = build_conf.get('CONFIG_KERNEL_BIN_NAME', 'zephyr') - # TODO: make this a new sign.py --bootloader option. - if target in ('imx8', 'imx8m', 'imx8ulp', 'imx95', 'rmb'): - bootloader = None - kernel = str(b / 'zephyr' / f'{kernel_name}.elf') - out_bin = str(b / 'zephyr' / f'{kernel_name}.ri') - out_xman = str(b / 'zephyr' / f'{kernel_name}.ri.xman') - out_tmp = str(b / 'zephyr' / f'{kernel_name}.rix') - else: + bootloader = None + cold = None + kernel = str(b / 'zephyr' / f'{kernel_name}.elf') + out_bin = str(b / 'zephyr' / f'{kernel_name}.ri') + out_xman = str(b / 'zephyr' / f'{kernel_name}.ri.xman') + out_tmp = str(b / 'zephyr' / f'{kernel_name}.rix') + + # Intel platforms generate a "boot.mod" and "main.mod" as + # separate intermediates to use. Other platforms just use + # zephyr.elf directly. + if os.path.exists(str(b / 'zephyr' / 'boot.mod')): bootloader = str(b / 'zephyr' / 'boot.mod') + if os.path.exists(str(b / 'zephyr' / 'cold.mod')): + cold = str(b / 'zephyr' / 'cold.mod') + with open(cold, 'rb') as f_cold: + elf = ELFFile(f_cold) + if elf.get_section_by_name('.cold') is None: + cold = None + if os.path.exists(str(b / 'zephyr' / 'main.mod')): kernel = str(b / 'zephyr' / 'main.mod') - out_bin = str(b / 'zephyr' / f'{kernel_name}.ri') - out_xman = str(b / 'zephyr' / f'{kernel_name}.ri.xman') - out_tmp = str(b / 'zephyr' / f'{kernel_name}.rix') # Clean any stale output. This is especially important when using --if-tool-available # (but not just) @@ -539,6 +566,7 @@ def sign(self, command, build_dir, build_conf, formats): is_sof_build = build_conf.getboolean('CONFIG_SOF') if not is_sof_build: no_manifest = True + self.generate_uuid_registry() if no_manifest: extra_ri_args = [ ] @@ -552,7 +580,10 @@ def sign(self, command, build_dir, build_conf, formats): if not args.quiet and args.verbose: sign_base += ['-v'] * args.verbose + # Order is important components = [ ] if bootloader is None else [ bootloader ] + if cold is not None: + components += [ cold ] components += [ kernel ] sign_config_extra_args = command.config_get_words('rimage.extra-args', []) diff --git a/scripts/west_commands/spdx.py b/scripts/west_commands/spdx.py index 7a10b44153471..d4d366480ac84 100644 --- a/scripts/west_commands/spdx.py +++ b/scripts/west_commands/spdx.py @@ -74,8 +74,9 @@ def do_run_init(self, args): if query_ready: self.inf("initialized; run `west build` then run `west spdx`") else: - self.err("Couldn't create CMake file-based API query directory") - self.err("You can manually create an empty file at $BUILDDIR/.cmake/api/v1/query/codemodel-v2") + self.die("Couldn't create CMake file-based API query directory\n" + "You can manually create an empty file at " + "$BUILDDIR/.cmake/api/v1/query/codemodel-v2") def do_run_spdx(self, args): if not args.build_dir: @@ -110,4 +111,5 @@ def do_run_spdx(self, args): # create the directory os.makedirs(cfg.spdxDir, exist_ok=False) - makeSPDX(cfg) + if not makeSPDX(cfg): + self.die("Failed to create SPDX output") diff --git a/scripts/west_commands/tests/nrf/README.rst b/scripts/west_commands/tests/nrf/README.rst deleted file mode 100644 index 2b1c35fde0867..0000000000000 --- a/scripts/west_commands/tests/nrf/README.rst +++ /dev/null @@ -1 +0,0 @@ -This directory contains test data files for test_nrf.py. diff --git a/scripts/west_commands/tests/nrf/nrf5340_app_and_net.hex b/scripts/west_commands/tests/nrf/nrf5340_app_and_net.hex deleted file mode 100644 index 2dda35e11108e..0000000000000 --- a/scripts/west_commands/tests/nrf/nrf5340_app_and_net.hex +++ /dev/null @@ -1,5 +0,0 @@ -:020000040000FA -:0100000001FE -:020000040100F9 -:0100000001FE -:00000001FF diff --git a/scripts/west_commands/tests/nrf/nrf5340_app_only.hex b/scripts/west_commands/tests/nrf/nrf5340_app_only.hex deleted file mode 100644 index d3641b390510f..0000000000000 --- a/scripts/west_commands/tests/nrf/nrf5340_app_only.hex +++ /dev/null @@ -1,2 +0,0 @@ -:0100000001FE -:00000001FF diff --git a/scripts/west_commands/tests/nrf/nrf5340_net_only.hex b/scripts/west_commands/tests/nrf/nrf5340_net_only.hex deleted file mode 100644 index 68cefd69a0391..0000000000000 --- a/scripts/west_commands/tests/nrf/nrf5340_net_only.hex +++ /dev/null @@ -1,3 +0,0 @@ -:020000040100F9 -:0100000001FE -:00000001FF diff --git a/scripts/west_commands/tests/test_bossac.py b/scripts/west_commands/tests/test_bossac.py index 58cc8b01b5d70..2e1b7b2c223fb 100644 --- a/scripts/west_commands/tests/test_bossac.py +++ b/scripts/west_commands/tests/test_bossac.py @@ -27,7 +27,7 @@ ['stty', '-F', TEST_BOSSAC_PORT, 'raw', 'ispeed', '115200', 'ospeed', '115200', 'cs8', '-cstopb', 'ignpar', 'eol', '255', 'eof', '255'], - ['bossac', '-p', TEST_BOSSAC_PORT, '-R', '-e', '-w', '-v', + ['bossac', '-p', TEST_BOSSAC_PORT, '-R', '-w', '-v', '-b', RC_KERNEL_BIN], ] @@ -35,15 +35,22 @@ ['stty', '-F', TEST_BOSSAC_PORT, 'raw', 'ispeed', TEST_BOSSAC_SPEED, 'ospeed', TEST_BOSSAC_SPEED, 'cs8', '-cstopb', 'ignpar', 'eol', '255', 'eof', '255'], - ['bossac', '-p', TEST_BOSSAC_PORT, '-R', '-e', '-w', '-v', + ['bossac', '-p', TEST_BOSSAC_PORT, '-R', '-w', '-v', '-b', RC_KERNEL_BIN], ] +EXPECTED_COMMANDS_WITH_ERASE = [ + ['stty', '-F', TEST_BOSSAC_PORT, 'raw', 'ispeed', '115200', + 'ospeed', '115200', 'cs8', '-cstopb', 'ignpar', 'eol', '255', + 'eof', '255'], + ['bossac', '-p', TEST_BOSSAC_PORT, '-R', '-w', '-v', + '-b', RC_KERNEL_BIN, '-e'], +] EXPECTED_COMMANDS_WITH_OFFSET = [ ['stty', '-F', TEST_BOSSAC_PORT, 'raw', 'ispeed', '115200', 'ospeed', '115200', 'cs8', '-cstopb', 'ignpar', 'eol', '255', 'eof', '255'], - ['bossac', '-p', TEST_BOSSAC_PORT, '-R', '-e', '-w', '-v', + ['bossac', '-p', TEST_BOSSAC_PORT, '-R', '-w', '-v', '-b', RC_KERNEL_BIN, '-o', str(TEST_OFFSET)], ] @@ -54,7 +61,7 @@ 'eof', '255' ], [ - 'bossac', '-p', TEST_BOSSAC_PORT, '-R', '-e', '-w', '-v', + 'bossac', '-p', TEST_BOSSAC_PORT, '-R', '-w', '-v', '-b', RC_KERNEL_BIN, '-o', str(TEST_FLASH_ADDRESS), ], ] @@ -66,7 +73,7 @@ 'eof', '255' ], [ - 'bossac', '-p', TEST_BOSSAC_PORT, '-R', '-e', '-w', '-v', + 'bossac', '-p', TEST_BOSSAC_PORT, '-R', '-w', '-v', '-b', RC_KERNEL_BIN, '-o', str(TEST_FLASH_ADDRESS), ], ] @@ -175,6 +182,7 @@ def test_bossac_init(cc, req, get_cod_par, sup, runner_config, tmpdir): Output: no --offset + no -e """ runner_config = adjust_runner_config(runner_config, tmpdir, DOTCONFIG_STD) runner = BossacBinaryRunner(runner_config, port=TEST_BOSSAC_PORT) @@ -207,6 +215,7 @@ def test_bossac_create(cc, req, get_cod_par, sup, runner_config, tmpdir): Output: no --offset + no -e """ args = ['--bossac-port', str(TEST_BOSSAC_PORT)] parser = argparse.ArgumentParser(allow_abbrev=False) @@ -257,6 +266,42 @@ def test_bossac_create_with_speed(cc, req, get_cod_par, sup, runner_config, tmpd assert cc.call_args_list == [call(x) for x in EXPECTED_COMMANDS_WITH_SPEED] +@patch('runners.bossac.BossacBinaryRunner.supports', + return_value=False) +@patch('runners.bossac.BossacBinaryRunner.get_chosen_code_partition_node', + return_value=None) +@patch('runners.core.ZephyrBinaryRunner.require', + side_effect=require_patch) +@patch('runners.core.ZephyrBinaryRunner.check_call') +def test_bossac_create_with_erase(cc, req, get_cod_par, sup, runner_config, tmpdir): + """ + Test commands using a runner created from command line parameters. + + Requirements: + Any SDK + + Configuration: + ROM bootloader + CONFIG_USE_DT_CODE_PARTITION=n + without zephyr,code-partition + + Input: + --erase + + Output: + no --offset + """ + args = ['--bossac-port', str(TEST_BOSSAC_PORT), + '--erase'] + parser = argparse.ArgumentParser(allow_abbrev=False) + BossacBinaryRunner.add_parser(parser) + arg_namespace = parser.parse_args(args) + runner_config = adjust_runner_config(runner_config, tmpdir, DOTCONFIG_STD) + runner = BossacBinaryRunner.create(runner_config, arg_namespace) + with patch('os.path.isfile', side_effect=os_path_isfile_patch): + runner.run('flash') + assert cc.call_args_list == [call(x) for x in EXPECTED_COMMANDS_WITH_ERASE] + @patch('runners.bossac.BossacBinaryRunner.supports', return_value=True) @patch('runners.bossac.BossacBinaryRunner.get_chosen_code_partition_node', diff --git a/scripts/west_commands/tests/test_imports.py b/scripts/west_commands/tests/test_imports.py index d47470c5a6646..3fb08b68a9e1f 100644 --- a/scripts/west_commands/tests/test_imports.py +++ b/scripts/west_commands/tests/test_imports.py @@ -22,6 +22,7 @@ def test_runner_imports(): 'canopen', 'dediprog', 'dfu-util', + 'ecpprog', 'esp32', 'ezflashcli', 'gd32isp', diff --git a/scripts/west_commands/tests/test_nrf.py b/scripts/west_commands/tests/test_nrf.py index d3f429ef775a9..767739ef9e230 100644 --- a/scripts/west_commands/tests/test_nrf.py +++ b/scripts/west_commands/tests/test_nrf.py @@ -7,9 +7,7 @@ import functools import io import os -from pathlib import Path import shlex -import shutil import typing from unittest.mock import patch, call @@ -30,14 +28,6 @@ TEST_TOOL_OPT = '--ip 192.168.1.10' TEST_TOOL_OPT_L = shlex.split(TEST_TOOL_OPT) -# nRF53 flashing is special in that we have different results -# depending on the input hex file. For that reason, we test it with -# real hex files. -TEST_DIR = Path(__file__).parent / 'nrf' -NRF5340_APP_ONLY_HEX = os.fspath(TEST_DIR / 'nrf5340_app_only.hex') -NRF5340_NET_ONLY_HEX = os.fspath(TEST_DIR / 'nrf5340_net_only.hex') -NRF5340_APP_AND_NET_HEX = os.fspath(TEST_DIR / 'nrf5340_app_and_net.hex') - CLASS_MAP = {'nrfjprog': NrfJprogBinaryRunner, 'nrfutil': NrfUtilBinaryRunner} # @@ -66,6 +56,9 @@ class TC(typing.NamedTuple): # 'TestCase' # Use --reset instead of --pinreset if True softreset: bool + # Use --pinreset instead of --reset if True + pinreset: bool + # --snr TEST_OVR_SNR if True, --snr TEST_DEF_SNR if False snr: bool @@ -82,46 +75,46 @@ class TC(typing.NamedTuple): # 'TestCase' # ------------------------------------------------------------------------- # NRF51 # - # family CP recov soft snr erase tool_opt - TC('NRF51_FAMILY', None, False, False, False, False, False): + # family CP recov soft pin snr erase tool_opt + TC('nrf51', None, False, False, False, False, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF51', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF51', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF51_FAMILY', None, False, False, False, True, False): + TC('nrf51', None, False, False, False, False, True, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF51', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF51', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF51_FAMILY', None, False, False, True, False, False): + TC('nrf51', None, False, False, True, True, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF51', '--snr', TEST_OVR_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF51', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - TC('NRF51_FAMILY', None, False, True, False, False, False): + TC('nrf51', None, False, True, False, False, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF51', '--snr', TEST_DEF_SNR], ['nrfjprog', '--reset', '-f', 'NRF51', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF51_FAMILY', None, True, False, False, False, False): + TC('nrf51', None, True, False, True, False, False, False): ((['nrfjprog', '--recover', '-f', 'NRF51', '--snr', TEST_DEF_SNR], ['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF51', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF51', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF51_FAMILY', None, True, True, True, True, False): + TC('nrf51', None, True, True, False, True, True, False): ((['nrfjprog', '--recover', '-f', 'NRF51', '--snr', TEST_OVR_SNR], ['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF51', '--snr', TEST_OVR_SNR], ['nrfjprog', '--reset', '-f', 'NRF51', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - TC('NRF51_FAMILY', None, True, True, True, True, True): + TC('nrf51', None, True, True, False, True, True, True): ((['nrfjprog', '--recover', '-f', 'NRF51', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, ['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF51', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, @@ -131,35 +124,33 @@ class TC(typing.NamedTuple): # 'TestCase' # ------------------------------------------------------------------------- # NRF52 # - # family CP recov soft snr erase tool_opt - TC('NRF52_FAMILY', None, False, False, False, False, False): + # family CP recov soft pin snr erase tool_opt + TC('nrf52', None, False, False, False, False, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectoranduicrerase', '--verify', '-f', 'NRF52', '--snr', TEST_DEF_SNR], - ['nrfjprog', '--pinresetenable', '-f', 'NRF52', '--snr', TEST_DEF_SNR], - ['nrfjprog', '--pinreset', '-f', 'NRF52', '--snr', TEST_DEF_SNR]), + ['nrfjprog', '--reset', '-f', 'NRF52', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF52_FAMILY', None, False, False, False, True, False): + TC('nrf52', None, False, False, True, False, True, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF52', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinresetenable', '-f', 'NRF52', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF52', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF52_FAMILY', None, False, False, True, False, False): + TC('nrf52', None, False, False, False, True, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectoranduicrerase', '--verify', '-f', 'NRF52', '--snr', TEST_OVR_SNR], - ['nrfjprog', '--pinresetenable', '-f', 'NRF52', '--snr', TEST_OVR_SNR], - ['nrfjprog', '--pinreset', '-f', 'NRF52', '--snr', TEST_OVR_SNR]), + ['nrfjprog', '--reset', '-f', 'NRF52', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - TC('NRF52_FAMILY', None, False, True, False, False, False): + TC('nrf52', None, False, True, False, False, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectoranduicrerase', '--verify', '-f', 'NRF52', '--snr', TEST_DEF_SNR], ['nrfjprog', '--reset', '-f', 'NRF52', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF52_FAMILY', None, True, False, False, False, False): + TC('nrf52', None, True, False, True, False, False, False): ((['nrfjprog', '--recover', '-f', 'NRF52', '--snr', TEST_DEF_SNR], ['nrfjprog', '--program', RC_KERNEL_HEX, '--sectoranduicrerase', '--verify', '-f', 'NRF52', '--snr', TEST_DEF_SNR], @@ -167,14 +158,14 @@ class TC(typing.NamedTuple): # 'TestCase' ['nrfjprog', '--pinreset', '-f', 'NRF52', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF52_FAMILY', None, True, True, True, True, False): + TC('nrf52', None, True, True, False, True, True, False): ((['nrfjprog', '--recover', '-f', 'NRF52', '--snr', TEST_OVR_SNR], ['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF52', '--snr', TEST_OVR_SNR], ['nrfjprog', '--reset', '-f', 'NRF52', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - TC('NRF52_FAMILY', None, True, True, True, True, True): + TC('nrf52', None, True, True, False, True, True, True): ((['nrfjprog', '--recover', '-f', 'NRF52', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, ['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF52', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, @@ -182,259 +173,140 @@ class TC(typing.NamedTuple): # 'TestCase' (TEST_OVR_SNR, None)), # ------------------------------------------------------------------------- - # NRF53 APP only + # NRF53 APP # - # family CP recov soft snr erase tool_opt - TC('NRF53_FAMILY', 'APP', False, False, False, False, False): - ((['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--sectorerase', + # family CP recov soft pin snr erase tool_opt + TC('nrf53', 'APP', False, False, False, False, False, False): + ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF53_FAMILY', 'APP', False, False, False, True, False): - ((['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--chiperase', + TC('nrf53', 'APP', False, False, True, False, True, False): + ((['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF53_FAMILY', 'APP', False, False, True, False, False): - ((['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--sectorerase', + TC('nrf53', 'APP', False, False, False, True, False, False): + ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - TC('NRF53_FAMILY', 'APP', False, True, False, False, False): - ((['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--sectorerase', + TC('nrf53', 'APP', False, True, False, False, False, False): + ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR], ['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF53_FAMILY', 'APP', True, False, False, False, False): + TC('nrf53', 'APP', True, False, True, False, False, False): ((['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], ['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_DEF_SNR], - ['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--sectorerase', + ['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF53_FAMILY', 'APP', True, True, True, True, False): + TC('nrf53', 'APP', True, True, False, True, True, False): ((['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR], ['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_OVR_SNR], - ['nrfjprog', '--program', NRF5340_APP_ONLY_HEX, '--chiperase', + ['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR], ['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), # ------------------------------------------------------------------------- - # NRF53 NET only + # NRF53 NET # - # family CP recov soft snr erase tool_opt - TC('NRF53_FAMILY', 'NET', False, False, False, False, False): - ((['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--sectorerase', + # family CP recov soft pin snr erase tool_opt + TC('nrf53', 'NET', False, False, False, False, False, False): + ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF53_FAMILY', 'NET', False, False, False, True, False): - ((['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--chiperase', + TC('nrf53', 'NET', False, False, True, False, True, False): + ((['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF53_FAMILY', 'NET', False, False, True, False, False): - ((['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--sectorerase', + TC('nrf53', 'NET', False, False, False, True, False, False): + ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - TC('NRF53_FAMILY', 'NET', False, True, False, False, False): - ((['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--sectorerase', + TC('nrf53', 'NET', False, True, False, False, False, False): + ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], ['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF53_FAMILY', 'NET', True, False, False, False, False): + TC('nrf53', 'NET', True, False, True, False, False, False): ((['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], ['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_DEF_SNR], - ['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--sectorerase', + ['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF53_FAMILY', 'NET', True, True, True, True, False): + TC('nrf53', 'NET', True, True, False, True, True, False): ((['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR], ['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_OVR_SNR], - ['nrfjprog', '--program', NRF5340_NET_ONLY_HEX, '--chiperase', + ['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR], ['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - # ------------------------------------------------------------------------- - # NRF53 APP+NET - # - # family CP recov soft snr erase tool_opt - TC('NRF53_FAMILY', 'APP+NET', False, False, False, False, False): - ((lambda tmpdir, infile: \ - (['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name), - '--sectorerase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name), - '--sectorerase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR], - ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR])), - (TEST_DEF_SNR, None)), - - TC('NRF53_FAMILY', 'APP+NET', False, False, False, True, False): - ((lambda tmpdir, infile: \ - (['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name), - '--chiperase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name), - '--chiperase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR], - ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR])), - (TEST_DEF_SNR, None)), - - TC('NRF53_FAMILY', 'APP+NET', False, False, True, False, False): - ((lambda tmpdir, infile: \ - (['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name), - '--sectorerase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR], - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name), - '--sectorerase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR], - ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_OVR_SNR])), - (TEST_OVR_SNR, None)), - - TC('NRF53_FAMILY', 'APP+NET', False, True, False, False, False): - ((lambda tmpdir, infile: \ - (['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name), - '--sectorerase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name), - '--sectorerase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR], - ['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_DEF_SNR])), - (TEST_DEF_SNR, None)), - - TC('NRF53_FAMILY', 'APP+NET', True, False, False, False, False): - ((lambda tmpdir, infile: \ - (['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', - '--snr', TEST_DEF_SNR], - ['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_DEF_SNR], - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name), - '--sectorerase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_NETWORK', '--snr', TEST_DEF_SNR], - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name), - '--sectorerase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_APPLICATION', '--snr', TEST_DEF_SNR], - ['nrfjprog', '--pinreset', '-f', 'NRF53', '--snr', TEST_DEF_SNR])), - (TEST_DEF_SNR, None)), - - TC('NRF53_FAMILY', 'APP+NET', True, True, True, True, False): - ((lambda tmpdir, infile: \ - (['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', - '--snr', TEST_OVR_SNR], - ['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_OVR_SNR], - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name), - '--chiperase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR], - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name), - '--chiperase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR], - ['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_OVR_SNR])), - (TEST_OVR_SNR, None)), - - TC('NRF53_FAMILY', 'APP+NET', True, True, True, True, True): - ((lambda tmpdir, infile: \ - (['nrfjprog', '--recover', '-f', 'NRF53', '--coprocessor', 'CP_NETWORK', - '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, - ['nrfjprog', '--recover', '-f', 'NRF53', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_NETWORK_' + Path(infile).name), - '--chiperase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_NETWORK', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, - ['nrfjprog', - '--program', - os.fspath(tmpdir / 'GENERATED_CP_APPLICATION_' + Path(infile).name), - '--chiperase', '--verify', '-f', 'NRF53', - '--coprocessor', 'CP_APPLICATION', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, - ['nrfjprog', '--reset', '-f', 'NRF53', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L)), - (TEST_OVR_SNR, None)), - - # ------------------------------------------------------------------------- # NRF91 # - # family CP recov soft snr erase tool_opt - TC('NRF91_FAMILY', None, False, False, False, False, False): + # family CP recov soft pin snr erase tool_opt + TC('nrf91', None, False, False, False, False, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF91', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF91', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF91_FAMILY', None, False, False, False, True, False): + TC('nrf91', None, False, False, True, False, True, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF91', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF91', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF91_FAMILY', None, False, False, True, False, False): + TC('nrf91', None, False, False, False, True, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF91', '--snr', TEST_OVR_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF91', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - TC('NRF91_FAMILY', None, False, True, False, False, False): + TC('nrf91', None, False, True, False, False, False, False): ((['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF91', '--snr', TEST_DEF_SNR], ['nrfjprog', '--reset', '-f', 'NRF91', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF91_FAMILY', None, True, False, False, False, False): + TC('nrf91', None, True, False, True, False, False, False): ((['nrfjprog', '--recover', '-f', 'NRF91', '--snr', TEST_DEF_SNR], ['nrfjprog', '--program', RC_KERNEL_HEX, '--sectorerase', '--verify', '-f', 'NRF91', '--snr', TEST_DEF_SNR], ['nrfjprog', '--pinreset', '-f', 'NRF91', '--snr', TEST_DEF_SNR]), (TEST_DEF_SNR, None)), - TC('NRF91_FAMILY', None, True, True, True, True, False): + TC('nrf91', None, True, True, False, True, True, False): ((['nrfjprog', '--recover', '-f', 'NRF91', '--snr', TEST_OVR_SNR], ['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF91', '--snr', TEST_OVR_SNR], ['nrfjprog', '--reset', '-f', 'NRF91', '--snr', TEST_OVR_SNR]), (TEST_OVR_SNR, None)), - TC('NRF91_FAMILY', None, True, True, True, True, True): + TC('nrf91', None, True, True, False, True, True, True): ((['nrfjprog', '--recover', '-f', 'NRF91', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, ['nrfjprog', '--program', RC_KERNEL_HEX, '--chiperase', '--verify', '-f', 'NRF91', '--snr', TEST_OVR_SNR] + TEST_TOOL_OPT_L, @@ -470,13 +342,14 @@ def id_fn(test_case): cp = '' else: cp = f'-{test_case.coprocessor}' - s = 'soft_reset' if test_case.softreset else 'pin_reset' + s = 'soft_reset' if test_case.softreset else 'no_soft_reset' + p = 'pin_reset' if test_case.pinreset else 'no_pin_reset' sn = 'default_snr' if test_case.snr else 'override_snr' e = 'chip_erase' if test_case.erase else 'sector[anduicr]_erase' r = 'recover' if test_case.recover else 'no_recover' t = 'tool_opt' if test_case.tool_opt else 'no_tool_opt' - return f'{test_case.family[:5]}{cp}-{s}-{sn}-{e}-{r}-{t}' + return f'{test_case.family[:5]}{cp}-{s}-{p}-{sn}-{e}-{r}-{t}' def fix_up_runner_config(test_case, runner_config, tmpdir): # Helper that adjusts the common runner_config fixture for our @@ -491,25 +364,14 @@ def fix_up_runner_config(test_case, runner_config, tmpdir): dotconfig = os.fspath(zephyr / '.config') with open(dotconfig, 'w') as f: f.write(f''' -CONFIG_SOC_SERIES_{test_case.family[:5]}X=y +CONFIG_SOC_SERIES_{test_case.family.upper()}X=y +''') + if test_case.family == 'nrf53': + f.write(f''' +CONFIG_SOC_NRF5340_CPU{test_case.coprocessor}=y ''') - to_replace['build_dir'] = tmpdir - if test_case.family != 'NRF53_FAMILY': - return runner_config._replace(**to_replace) - - if test_case.coprocessor == 'APP': - to_replace['hex_file'] = NRF5340_APP_ONLY_HEX - elif test_case.coprocessor == 'NET': - to_replace['hex_file'] = NRF5340_NET_ONLY_HEX - elif test_case.coprocessor == 'APP+NET': - # Since the runner is going to generate files next to its input - # file, we need to stash a copy in a tmpdir it can use. - outfile = tmpdir / Path(NRF5340_APP_AND_NET_HEX).name - shutil.copyfile(NRF5340_APP_AND_NET_HEX, outfile) - to_replace['hex_file'] = os.fspath(outfile) - else: - assert False, f'bad test case {test_case}' + to_replace['build_dir'] = tmpdir return runner_config._replace(**to_replace) @@ -517,10 +379,12 @@ def check_expected(tool, test_case, check_fn, get_snr, tmpdir, runner_config): expected = EXPECTED_RESULTS[test_case][EXPECTED_MAP[tool]] if tool == 'nrfutil': - assert len(check_fn.call_args_list) == 1 - assert len(check_fn.call_args_list[0].args) == 1 + # Skip the preparation calls for now + assert len(check_fn.call_args_list) >= 1 + xi = len(check_fn.call_args_list) - 1 + assert len(check_fn.call_args_list[xi].args) == 1 # Extract filename - nrfutil_args = check_fn.call_args_list[0].args[0] + nrfutil_args = check_fn.call_args_list[xi].args[0] tmpfile = nrfutil_args[nrfutil_args.index('--batch-path') + 1] cmds = (['nrfutil', '--json', 'device', 'x-execute-batch', '--batch-path', tmpfile, '--serial-number', expected[0]],) @@ -559,6 +423,7 @@ def test_init(check_call, popen, get_snr, require, tool, test_case, runner = cls(runner_config, test_case.family, test_case.softreset, + test_case.pinreset, snr, erase=test_case.erase, tool_opt=tool_opt, @@ -589,6 +454,8 @@ def test_create(check_call, popen, get_snr, require, tool, test_case, args = [] if test_case.softreset: args.append('--softreset') + if test_case.pinreset: + args.append('--pinreset') if test_case.snr: args.extend(['--dev-id', TEST_OVR_SNR]) if test_case.erase: diff --git a/scripts/west_commands/tests/test_stm32cubeprogrammer.py b/scripts/west_commands/tests/test_stm32cubeprogrammer.py index 82d6dcd5450f7..917a0099b45ea 100644 --- a/scripts/west_commands/tests/test_stm32cubeprogrammer.py +++ b/scripts/west_commands/tests/test_stm32cubeprogrammer.py @@ -64,7 +64,11 @@ "port": "swd", "frequency": None, "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": False, "erase": False, @@ -83,11 +87,43 @@ ], ], }, + { + "port": "swd", + "frequency": None, + "reset_mode": None, + "download_address": None, + "start_address": 0x8001000, + "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], + "cli": CLI_PATH, + "use_elf": False, + "erase": False, + "extload": None, + "tool_opt": [], + "system": "", + "cli_path": str(CLI_PATH), + "calls": [ + [ + str(CLI_PATH), + "--connect", + "port=swd", + "--download", + RC_KERNEL_HEX, + "--start", + "0x8001000" + ], + ], + }, { "port": "swd", "frequency": "4000", "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": False, "erase": False, @@ -110,7 +146,11 @@ "port": "swd", "frequency": None, "reset_mode": "hw", + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": False, "erase": False, @@ -133,7 +173,11 @@ "port": "swd", "frequency": None, "reset_mode": "sw", + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": False, "erase": False, @@ -156,7 +200,11 @@ "port": "swd", "frequency": None, "reset_mode": "core", + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": False, "erase": False, @@ -179,7 +227,11 @@ "port": "swd", "frequency": None, "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": "br=115200 sn=TEST", + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": False, "erase": False, @@ -202,7 +254,11 @@ "port": "swd", "frequency": None, "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": True, "erase": False, @@ -225,7 +281,11 @@ "port": "swd", "frequency": None, "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": False, "erase": True, @@ -249,7 +309,11 @@ "port": "swd", "frequency": None, "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": CLI_PATH, "use_elf": False, "erase": False, @@ -273,7 +337,11 @@ "port": "swd", "frequency": None, "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": None, "use_elf": False, "erase": False, @@ -296,7 +364,11 @@ "port": "swd", "frequency": None, "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": None, "use_elf": False, "erase": False, @@ -319,7 +391,11 @@ "port": "swd", "frequency": None, "reset_mode": None, + "download_address": None, + "start_address": None, "conn_modifiers": None, + "start_modifiers": [], + "download_modifiers": [], "cli": None, "use_elf": False, "erase": False, @@ -338,6 +414,36 @@ ], ], }, + { + "port": "swd", + "frequency": None, + "reset_mode": None, + "download_address": 0x80000000, + "start_address": None, + "conn_modifiers": None, + "start_modifiers": ["noack"], + "download_modifiers": ["0x1"], + "cli": CLI_PATH, + "use_elf": False, + "erase": False, + "extload": None, + "tool_opt": [], + "system": "", + "cli_path": str(CLI_PATH), + "calls": [ + [ + str(CLI_PATH), + "--connect", + "port=swd", + "--download", + RC_KERNEL_HEX, + "0x80000000", + "0x1", + "--start", + "noack", + ], + ], + }, ) """Test cases.""" @@ -363,6 +469,10 @@ def test_stm32cubeprogrammer_init( port=tc["port"], frequency=tc["frequency"], reset_mode=tc["reset_mode"], + download_address=tc["download_address"], + download_modifiers=tc["download_modifiers"], + start_address=tc["start_address"], + start_modifiers=tc["start_modifiers"], conn_modifiers=tc["conn_modifiers"], cli=tc["cli"], use_elf=tc["use_elf"], @@ -398,6 +508,10 @@ def test_stm32cubeprogrammer_create( args.extend(["--frequency", tc["frequency"]]) if tc["reset_mode"]: args.extend(["--reset-mode", tc["reset_mode"]]) + if tc["download_address"]: + args.extend(["--download-address", str(tc["download_address"])]) + if tc["start_address"]: + args.extend(["--start-address", str(tc["start_address"])]) if tc["conn_modifiers"]: args.extend(["--conn-modifiers", tc["conn_modifiers"]]) if tc["cli"]: @@ -410,6 +524,10 @@ def test_stm32cubeprogrammer_create( args.extend(["--extload", tc["extload"]]) if tc["tool_opt"]: args.extend(["--tool-opt", " " + tc["tool_opt"][0]]) + if tc["download_modifiers"]: + args.extend(["--download-modifiers", " " + tc["download_modifiers"][0]]) + if tc["start_modifiers"]: + args.extend(["--start-modifiers", " " + tc["start_modifiers"][0]]) parser = argparse.ArgumentParser(allow_abbrev=False) STM32CubeProgrammerBinaryRunner.add_parser(parser) diff --git a/scripts/west_commands/tests/test_xsdb.py b/scripts/west_commands/tests/test_xsdb.py index ca97e7ad5118b..0711da5f38e3e 100644 --- a/scripts/west_commands/tests/test_xsdb.py +++ b/scripts/west_commands/tests/test_xsdb.py @@ -13,13 +13,13 @@ "config": None, "bitstream": None, "fsbl": None, - "expected_cmd": ["xsdb", "default_cfg_path"], + "expected_cmd": ["xsdb", "default_cfg_path", RC_KERNEL_ELF], }, { "config": "custom_cfg_path", "bitstream": None, "fsbl": None, - "expected_cmd": ["xsdb", "custom_cfg_path"], + "expected_cmd": ["xsdb", "custom_cfg_path", RC_KERNEL_ELF], }, { "config": None, diff --git a/scripts/zephyr_module.py b/scripts/zephyr_module.py index ae2c35cc62d18..22369aa8295b1 100755 --- a/scripts/zephyr_module.py +++ b/scripts/zephyr_module.py @@ -174,6 +174,15 @@ type: seq sequence: - type: str + runners: + required: false + type: seq + sequence: + - type: map + mapping: + file: + required: true + type: str ''' MODULE_YML_PATH = PurePath('zephyr/module.yml') diff --git a/share/sysbuild/cmake/modules/sysbuild_default.cmake b/share/sysbuild/cmake/modules/sysbuild_default.cmake index 2d45bc1d9343b..f3ffa81bb28bf 100644 --- a/share/sysbuild/cmake/modules/sysbuild_default.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_default.cmake @@ -15,6 +15,7 @@ include(zephyr_module) include(boards) include(shields) include(hwm_v2) +include(sysbuild_snippets) include(sysbuild_kconfig) include(native_simulator_sb_extensions) include(sysbuild_images) diff --git a/share/sysbuild/cmake/modules/sysbuild_images.cmake b/share/sysbuild/cmake/modules/sysbuild_images.cmake index eb73ec994483f..7115567b8d955 100644 --- a/share/sysbuild/cmake/modules/sysbuild_images.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_images.cmake @@ -5,6 +5,26 @@ # This module is responsible for including images into sysbuild and to call # pre and post hooks. +# Internal function to update build info with list of images abnd write the file. +# Main reason for using an internal function is to properly scope variable usage. +# Function takes a list of images. +function(sysbuild_info_image images) + set(info_image_list) + foreach(image ${images}) + ExternalProject_Get_Property(${image} SOURCE_DIR) + get_target_property(type ${image} APP_TYPE) + if(type) + list(APPEND info_image_list MAP "name: ${image}, source-dir: ${SOURCE_DIR}, type: ${type}") + else() + list(APPEND info_image_list MAP "name: ${image}, source-dir: ${source_dir}") + endif() + endforeach() + build_info(images VALUE ${info_image_list}) + # Save current state of build info. This allow external tools to fetch sysbuild controlled images + # even in the event that one or more image fails configuration stage. + yaml_save(NAME build_info) +endfunction() + get_filename_component(APP_DIR ${APP_DIR} ABSOLUTE) get_filename_component(app_name ${APP_DIR} NAME) set(DEFAULT_IMAGE "${app_name}") @@ -15,6 +35,9 @@ sysbuild_add_subdirectory(${sysbuild_toplevel_SOURCE_DIR}/images sysbuild/images get_property(IMAGES GLOBAL PROPERTY sysbuild_images) sysbuild_module_call(PRE_CMAKE MODULES ${SYSBUILD_MODULE_NAMES} IMAGES ${IMAGES}) sysbuild_images_order(IMAGES_CONFIGURATION_ORDER CONFIGURE IMAGES ${IMAGES}) + +sysbuild_info_image("${IMAGES}") + foreach(image ${IMAGES_CONFIGURATION_ORDER}) sysbuild_module_call(PRE_IMAGE_CMAKE MODULES ${SYSBUILD_MODULE_NAMES} IMAGES ${IMAGES} IMAGE ${image}) ExternalZephyrProject_Cmake(APPLICATION ${image}) diff --git a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake index 41094454116e0..f366c66dbde0b 100644 --- a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake @@ -105,6 +105,15 @@ set(KCONFIG_NAMESPACE SB_CONFIG) if(EXISTS ${APP_DIR}/Kconfig.sysbuild) set(KCONFIG_ROOT ${APP_DIR}/Kconfig.sysbuild) endif() + +# Apply any EXTRA_CONF_FILE variables from snippets +zephyr_scope_exists(scope_defined snippets) +if(scope_defined) + zephyr_get_scoped(snippets_EXTRA_CONF_FILE snippets SB_EXTRA_CONF_FILE) + list(APPEND EXTRA_CONF_FILE ${snippets_EXTRA_CONF_FILE}) +endif() + include(${ZEPHYR_BASE}/cmake/modules/kconfig.cmake) set(CONF_FILE) set(EXTRA_CONF_FILE) +set(SB_EXTRA_CONF_FILE) diff --git a/share/sysbuild/cmake/modules/sysbuild_root.cmake b/share/sysbuild/cmake/modules/sysbuild_root.cmake index ca9f37238cf78..19a7034c80ca8 100644 --- a/share/sysbuild/cmake/modules/sysbuild_root.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_root.cmake @@ -31,6 +31,7 @@ zephyr_get(BOARD_ROOT MERGE) zephyr_get(SOC_ROOT MERGE) zephyr_get(ARCH_ROOT MERGE) zephyr_get(SCA_ROOT MERGE) +zephyr_get(SNIPPET_ROOT MERGE) # Convert paths to absolute, relative from APP_DIR zephyr_file(APPLICATION_ROOT MODULE_EXT_ROOT BASE_DIR ${APP_DIR}) @@ -38,6 +39,7 @@ zephyr_file(APPLICATION_ROOT BOARD_ROOT BASE_DIR ${APP_DIR}) zephyr_file(APPLICATION_ROOT SOC_ROOT BASE_DIR ${APP_DIR}) zephyr_file(APPLICATION_ROOT ARCH_ROOT BASE_DIR ${APP_DIR}) zephyr_file(APPLICATION_ROOT SCA_ROOT BASE_DIR ${APP_DIR}) +zephyr_file(APPLICATION_ROOT SNIPPET_ROOT BASE_DIR ${APP_DIR}) # Sysbuild must ensure any locally defined variables in sysbuild/CMakeLists.txt # have been added to the cache in order for the settings to propagate to images. @@ -61,3 +63,7 @@ endif() if(DEFINED SCA_ROOT) set(SCA_ROOT ${SCA_ROOT} CACHE PATH "Sysbuild adjusted SCA_ROOT" FORCE) endif() + +if(DEFINED SNIPPET_ROOT) + set(SNIPPET_ROOT ${SNIPPET_ROOT} CACHE PATH "Sysbuild adjusted SNIPPET_ROOT" FORCE) +endif() diff --git a/share/sysbuild/cmake/modules/sysbuild_snippets.cmake b/share/sysbuild/cmake/modules/sysbuild_snippets.cmake new file mode 100644 index 0000000000000..32ece9f593aa2 --- /dev/null +++ b/share/sysbuild/cmake/modules/sysbuild_snippets.cmake @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_get(SB_SNIPPET) +if(NOT SB_SNIPPET AND SNIPPET) + set_ifndef(SB_SNIPPET ${SNIPPET}) +endif() +set(SNIPPET_NAMESPACE SB_SNIPPET) +set(SNIPPET_PYTHON_EXTRA_ARGS --sysbuild) +set(SNIPPET_APP_DIR ${APP_DIR}) +include(${ZEPHYR_BASE}/cmake/modules/snippets.cmake) + +set(SNIPPET_NAMESPACE) +set(SNIPPET_PYTHON_EXTRA_ARGS) +set(SNIPPET_APP_DIR) diff --git a/share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake b/share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake index 8485cd77d59a8..422fdb8303080 100644 --- a/share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake +++ b/share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake @@ -6,6 +6,7 @@ # on Zephyr MCUboot / bootloader image. set(bootmodes CONFIG_SINGLE_APPLICATION_SLOT + CONFIG_BOOT_SWAP_USING_OFFSET CONFIG_BOOT_SWAP_USING_SCRATCH CONFIG_BOOT_UPGRADE_ONLY CONFIG_BOOT_SWAP_USING_MOVE @@ -15,7 +16,9 @@ set(bootmodes CONFIG_SINGLE_APPLICATION_SLOT if(SB_CONFIG_MCUBOOT_MODE_SINGLE_APP) set(bootmode CONFIG_SINGLE_APPLICATION_SLOT) -elseif(SB_CONFIG_MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH) +elseif(SB_CONFIG_MCUBOOT_MODE_SWAP_USING_OFFSET) + set(bootmode CONFIG_BOOT_SWAP_USING_OFFSET) +elseif(SB_CONFIG_MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH OR SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE) set(bootmode CONFIG_BOOT_SWAP_USING_MOVE) elseif(SB_CONFIG_MCUBOOT_MODE_SWAP_SCRATCH) set(bootmode CONFIG_BOOT_SWAP_USING_SCRATCH) diff --git a/share/sysbuild/image_configurations/MAIN_image_default.cmake b/share/sysbuild/image_configurations/MAIN_image_default.cmake index cd447a29d0cff..28dd6d0aacb71 100644 --- a/share/sysbuild/image_configurations/MAIN_image_default.cmake +++ b/share/sysbuild/image_configurations/MAIN_image_default.cmake @@ -22,8 +22,10 @@ if(SB_CONFIG_BOOTLOADER_MCUBOOT) if(SB_CONFIG_MCUBOOT_MODE_SINGLE_APP) set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_BOOTLOADER_MODE_SINGLE_APP y) - elseif(SB_CONFIG_MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH) - set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH y) + elseif(SB_CONFIG_MCUBOOT_MODE_SWAP_USING_OFFSET) + set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_USING_OFFSET y) + elseif(SB_CONFIG_MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH OR SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE) + set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_USING_MOVE y) elseif(SB_CONFIG_MCUBOOT_MODE_SWAP_SCRATCH) set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH y) elseif(SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY) diff --git a/share/sysbuild/images/bootloader/Kconfig b/share/sysbuild/images/bootloader/Kconfig index df97b18e3e6bc..1b5cdec41eae7 100644 --- a/share/sysbuild/images/bootloader/Kconfig +++ b/share/sysbuild/images/bootloader/Kconfig @@ -32,7 +32,7 @@ if BOOTLOADER_MCUBOOT choice MCUBOOT_MODE prompt "Mode of operation" - default MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH + default MCUBOOT_MODE_SWAP_USING_MOVE help The operating mode of MCUboot (which will also be propagated to the application). @@ -43,13 +43,27 @@ config MCUBOOT_MODE_SINGLE_APP slots. In this mode application is not able to DFU its own update to secondary slot and all updates need to be performed using MCUboot serial recovery. -config MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH - bool "Swap without scratch (swap using move)" +config MCUBOOT_MODE_SWAP_USING_OFFSET + bool "Swap using offset" + select EXPERIMENTAL help MCUboot expects slot0_partition and slot1_partition to be present in DT and application will boot from slot0_partition. MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected in main application if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. +config MCUBOOT_MODE_SWAP_USING_MOVE + bool "Swap using move" + help + MCUboot expects slot0_partition and slot1_partition to be present in DT and application + will boot from slot0_partition. MCUBOOT_BOOTLOADER_NO_DOWNGRADE should also be selected + in main application if MCUboot has been built with MCUBOOT_DOWNGRADE_PREVENTION. + +config MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH + bool "Swap without scratch (swap using move) [DEPRECATED]" + select DEPRECATED + help + This Kconfig is deprecated, use MCUBOOT_MODE_SWAP_USING_MOVE instead. + config MCUBOOT_MODE_SWAP_SCRATCH bool "Swap using scratch" help @@ -116,10 +130,10 @@ endchoice config SIGNATURE_TYPE string - default NONE if BOOT_SIGNATURE_TYPE_NONE - default RSA if BOOT_SIGNATURE_TYPE_RSA - default ECDSA_P256 if BOOT_SIGNATURE_TYPE_ECDSA_P256 - default ED25519 if BOOT_SIGNATURE_TYPE_ED25519 + default "NONE" if BOOT_SIGNATURE_TYPE_NONE + default "RSA" if BOOT_SIGNATURE_TYPE_RSA + default "ECDSA_P256" if BOOT_SIGNATURE_TYPE_ECDSA_P256 + default "ED25519" if BOOT_SIGNATURE_TYPE_ED25519 choice BOOT_SIGNATURE_TYPE prompt "Signature type" diff --git a/snippets/usbip-native-sim/README.rst b/snippets/usbip-native-sim/README.rst new file mode 100644 index 0000000000000..c082445e19047 --- /dev/null +++ b/snippets/usbip-native-sim/README.rst @@ -0,0 +1,17 @@ +.. _snippet-usbip-native-sim: + +USB/IP on Native Simulator Snippet (usbip-native-sim) +##################################################### + +.. code-block:: console + + west build -S usbip-native-sim [...] + +Overview +******** + +This snippet allows to configure USB device samples with USB/IP support on a +native simulator. When building samples with this snippet, you need to provide +samples DTC overlays using the EXTRA_DTC_OVERLAY_FILE argument. + +This snippet is experimental, the behavior may change without notice. diff --git a/snippets/usbip-native-sim/snippet.yml b/snippets/usbip-native-sim/snippet.yml new file mode 100644 index 0000000000000..794930c059663 --- /dev/null +++ b/snippets/usbip-native-sim/snippet.yml @@ -0,0 +1,4 @@ +name: usbip-native-sim +append: + EXTRA_CONF_FILE: usbip-native-sim.conf + EXTRA_DTC_OVERLAY_FILE: usbip-native-sim.overlay diff --git a/snippets/usbip-native-sim/usbip-native-sim.conf b/snippets/usbip-native-sim/usbip-native-sim.conf new file mode 100644 index 0000000000000..74bad4572774e --- /dev/null +++ b/snippets/usbip-native-sim/usbip-native-sim.conf @@ -0,0 +1,21 @@ +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_TCP=y +CONFIG_NET_SOCKETS=y + +# Network address config +CONFIG_NET_CONFIG_SETTINGS=y +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" + +CONFIG_NET_LOG=y + +CONFIG_USB_HOST_STACK=y +CONFIG_USBH_LOG_LEVEL_WRN=y +CONFIG_UHC_DRIVER_LOG_LEVEL_WRN=y +CONFIG_USBIP=y +CONFIG_USBIP_LOG_LEVEL_WRN=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000000 +CONFIG_UHC_BUF_COUNT=32 +CONFIG_UHC_XFER_COUNT=32 diff --git a/snippets/usbip-native-sim/usbip-native-sim.overlay b/snippets/usbip-native-sim/usbip-native-sim.overlay new file mode 100644 index 0000000000000..d206391f3cd5d --- /dev/null +++ b/snippets/usbip-native-sim/usbip-native-sim.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &zephyr_udc0; + +/ { + zephyr_uhc0: uhc_vrt0 { + compatible = "zephyr,uhc-virtual"; + + zephyr_udc0: udc_vrt0 { + compatible = "zephyr,udc-virtual"; + num-bidir-endpoints = <8>; + maximum-speed = "high-speed"; + }; + }; +}; diff --git a/snippets/wifi-ipv4/wifi-ipv4.conf b/snippets/wifi-ipv4/wifi-ipv4.conf index 59f4eafc2222a..89feb091ad351 100644 --- a/snippets/wifi-ipv4/wifi-ipv4.conf +++ b/snippets/wifi-ipv4/wifi-ipv4.conf @@ -7,7 +7,7 @@ CONFIG_WIFI_NM_WPA_SUPPLICANT=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_ZVFS_OPEN_MAX=24 CONFIG_NET_MAX_CONN=10 -CONFIG_NET_SOCKETS_POLL_MAX=9 +CONFIG_ZVFS_POLL_MAX=10 # IPv4 only for now CONFIG_NET_IPV6=n diff --git a/soc/adi/max32/CMakeLists.txt b/soc/adi/max32/CMakeLists.txt index 41041da7e08c4..b398dcd8d8f7d 100644 --- a/soc/adi/max32/CMakeLists.txt +++ b/soc/adi/max32/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2023-2024 Analog Devices, Inc. +# Copyright (c) 2023-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(${ZEPHYR_BASE}/drivers) @@ -6,6 +6,8 @@ zephyr_include_directories(common) zephyr_sources(soc.c) zephyr_linker_sources_ifdef(CONFIG_SOC_FLASH_MAX32 SECTIONS flash.ld) -zephyr_linker_sources_ifdef(CONFIG_SOC_MAX78002 SECTIONS max78002.ld) +if(CONFIG_SOC_MAX78000 OR CONFIG_SOC_MAX78002) + zephyr_linker_sources(SECTIONS max7800x.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/adi/max32/Kconfig b/soc/adi/max32/Kconfig index b2bdc351518f6..2bddfc6e556b9 100644 --- a/soc/adi/max32/Kconfig +++ b/soc/adi/max32/Kconfig @@ -1,44 +1,35 @@ # Analog Devices MAX32xxx MCU family -# Copyright (c) 2023-2024 Analog Devices, Inc. +# Copyright (c) 2023-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 config SOC_FAMILY_MAX32 - select ARM - select CPU_HAS_ARM_MPU - select CPU_HAS_FPU - select CPU_CORTEX_M_HAS_SYSTICK select CLOCK_CONTROL select BUILD_OUTPUT_HEX select SOC_EARLY_INIT_HOOK select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE -config SOC_MAX32655 - select CPU_CORTEX_M4 - -config SOC_MAX32662 - select CPU_CORTEX_M4 - -config SOC_MAX32666 - select CPU_CORTEX_M4 - -config SOC_MAX32670 +config SOC_FAMILY_MAX32_M4 + select ARM select CPU_CORTEX_M4 + select CPU_CORTEX_M_HAS_SYSTICK + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU -config SOC_MAX32672 - select CPU_CORTEX_M4 +config SOC_MAX32655_M4 + select MAX32_HAS_SECONDARY_RV32 -config SOC_MAX32675 - select CPU_CORTEX_M4 +config SOC_MAX32680_M4 + select MAX32_HAS_SECONDARY_RV32 -config SOC_MAX32680 - select CPU_CORTEX_M4 +config SOC_MAX32690_M4 + select MAX32_HAS_SECONDARY_RV32 -config SOC_MAX32690 - select CPU_CORTEX_M4 +config SOC_MAX78000_M4 + select MAX32_HAS_SECONDARY_RV32 config SOC_MAX78002_M4 - select CPU_CORTEX_M4 + select MAX32_HAS_SECONDARY_RV32 if SOC_FAMILY_MAX32 @@ -52,4 +43,18 @@ config MAX32_ON_ENTER_CPU_IDLE_HOOK If needed, this hook can be used to prevent the CPU from actually entering sleep by skipping the WFE/WFI instruction. +config MAX32_HAS_SECONDARY_RV32 + bool + +config MAX32_SECONDARY_RV32 + bool "Secondary RISC-V core enable" + depends on MAX32_HAS_SECONDARY_RV32 + +DT_CHOSEN_Z_CODE_RV32_PARTITION := zephyr,code-rv32-partition + +config MAX32_SECONDARY_RV32_BOOT_ADDRESS + hex "Secondary RISC-V core boot address" + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_RV32_PARTITION)) + depends on MAX32_SECONDARY_RV32 + endif # SOC_FAMILY_MAX32 diff --git a/soc/adi/max32/Kconfig.defconfig.max32650 b/soc/adi/max32/Kconfig.defconfig.max32650 new file mode 100644 index 0000000000000..9c8608b1b775d --- /dev/null +++ b/soc/adi/max32/Kconfig.defconfig.max32650 @@ -0,0 +1,14 @@ +# Analog Devices MAX32650 MCU + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MAX32650 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/clocks/clk_ipo,clock-frequency) + +config NUM_IRQS + default 80 + +endif # SOC_MAX32650 diff --git a/soc/adi/max32/Kconfig.defconfig.max32660 b/soc/adi/max32/Kconfig.defconfig.max32660 new file mode 100644 index 0000000000000..29848d44d1dc5 --- /dev/null +++ b/soc/adi/max32/Kconfig.defconfig.max32660 @@ -0,0 +1,14 @@ +# Analog Devices MAX32660 MCU + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MAX32660 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/clocks/clk_ipo,clock-frequency) + +config NUM_IRQS + default 55 + +endif # SOC_MAX32660 diff --git a/soc/adi/max32/Kconfig.defconfig.max78000 b/soc/adi/max32/Kconfig.defconfig.max78000 new file mode 100644 index 0000000000000..8643911a766e1 --- /dev/null +++ b/soc/adi/max32/Kconfig.defconfig.max78000 @@ -0,0 +1,14 @@ +# Analog Devices MAX78000 MCU + +# Copyright (c) 2025 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MAX78000 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/clocks/clk_ipo,clock-frequency) + +config NUM_IRQS + default 119 + +endif # SOC_MAX78000 diff --git a/soc/adi/max32/Kconfig.soc b/soc/adi/max32/Kconfig.soc index 130d9b88b1f10..e0be0041b4b6c 100644 --- a/soc/adi/max32/Kconfig.soc +++ b/soc/adi/max32/Kconfig.soc @@ -1,72 +1,94 @@ # Analog Devices MAX32xxx MCU family -# Copyright (c) 2023-2024 Analog Devices, Inc. +# Copyright (c) 2023-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 config SOC_FAMILY_MAX32 bool +config SOC_FAMILY_MAX32_M4 + bool + select SOC_FAMILY_MAX32 + config SOC_FAMILY default "max32" if SOC_FAMILY_MAX32 +config SOC_MAX32650 + bool + select SOC_FAMILY_MAX32_M4 + config SOC_MAX32655 bool - select SOC_FAMILY_MAX32 config SOC_MAX32655_M4 bool select SOC_MAX32655 + select SOC_FAMILY_MAX32_M4 + +config SOC_MAX32660 + bool + select SOC_FAMILY_MAX32_M4 config SOC_MAX32662 bool - select SOC_FAMILY_MAX32 + select SOC_FAMILY_MAX32_M4 config SOC_MAX32666 bool - select SOC_FAMILY_MAX32 config SOC_MAX32666_CPU0 bool select SOC_MAX32666 + select SOC_FAMILY_MAX32_M4 config SOC_MAX32670 bool - select SOC_FAMILY_MAX32 + select SOC_FAMILY_MAX32_M4 config SOC_MAX32672 bool - select SOC_FAMILY_MAX32 + select SOC_FAMILY_MAX32_M4 config SOC_MAX32675 bool - select SOC_FAMILY_MAX32 + select SOC_FAMILY_MAX32_M4 config SOC_MAX32680 bool - select SOC_FAMILY_MAX32 config SOC_MAX32680_M4 bool select SOC_MAX32680 + select SOC_FAMILY_MAX32_M4 config SOC_MAX32690 bool - select SOC_FAMILY_MAX32 config SOC_MAX32690_M4 bool select SOC_MAX32690 + select SOC_FAMILY_MAX32_M4 + +config SOC_MAX78000 + bool + +config SOC_MAX78000_M4 + bool + select SOC_MAX78000 + select SOC_FAMILY_MAX32_M4 config SOC_MAX78002 bool - select SOC_FAMILY_MAX32 config SOC_MAX78002_M4 bool select SOC_MAX78002 + select SOC_FAMILY_MAX32_M4 config SOC + default "max32650" if SOC_MAX32650 default "max32655" if SOC_MAX32655 + default "max32660" if SOC_MAX32660 default "max32662" if SOC_MAX32662 default "max32666" if SOC_MAX32666 default "max32670" if SOC_MAX32670 @@ -74,4 +96,5 @@ config SOC default "max32675" if SOC_MAX32675 default "max32680" if SOC_MAX32680 default "max32690" if SOC_MAX32690 + default "max78000" if SOC_MAX78000 default "max78002" if SOC_MAX78002 diff --git a/soc/adi/max32/max78002.ld b/soc/adi/max32/max7800x.ld similarity index 100% rename from soc/adi/max32/max78002.ld rename to soc/adi/max32/max7800x.ld diff --git a/soc/adi/max32/soc.c b/soc/adi/max32/soc.c index c509e8e5cf3f6..fc24e6e1d8265 100644 --- a/soc/adi/max32/soc.c +++ b/soc/adi/max32/soc.c @@ -14,6 +14,10 @@ #include +#ifdef CONFIG_MAX32_SECONDARY_RV32 +#include +#endif + #if defined(CONFIG_MAX32_ON_ENTER_CPU_IDLE_HOOK) bool z_arm_on_enter_cpu_idle(void) { @@ -31,4 +35,10 @@ void soc_early_init_hook(void) { /* Apply device related preinit configuration */ max32xx_system_init(); + +#ifdef CONFIG_MAX32_SECONDARY_RV32 + MXC_FCR->urvbootaddr = CONFIG_MAX32_SECONDARY_RV32_BOOT_ADDRESS; + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_CPU1); + MXC_GCR->rst1 |= MXC_F_GCR_RST1_CPU1; +#endif /* CONFIG_MAX32_SECONDARY_RV32 */ } diff --git a/soc/adi/max32/soc.yml b/soc/adi/max32/soc.yml index 3f164890071da..3bf7288d120df 100644 --- a/soc/adi/max32/soc.yml +++ b/soc/adi/max32/soc.yml @@ -1,12 +1,14 @@ -# Copyright (c) 2023-2024 Analog Devices, Inc. +# Copyright (c) 2023-2025 Analog Devices, Inc. # SPDX-License-Identifier: Apache-2.0 family: - name: max32 socs: + - name: max32650 - name: max32655 cpuclusters: - name: m4 + - name: max32660 - name: max32662 - name: max32666 cpuclusters: @@ -20,6 +22,9 @@ family: - name: max32690 cpuclusters: - name: m4 + - name: max78000 + cpuclusters: + - name: m4 - name: max78002 cpuclusters: - name: m4 diff --git a/soc/ambiq/apollo3x/Kconfig.defconfig.apollo3_blue b/soc/ambiq/apollo3x/Kconfig.defconfig.apollo3_blue index 4a1b30205537d..ca99e2af30d7a 100644 --- a/soc/ambiq/apollo3x/Kconfig.defconfig.apollo3_blue +++ b/soc/ambiq/apollo3x/Kconfig.defconfig.apollo3_blue @@ -37,4 +37,11 @@ config BT_HCI_ACL_FLOW_CONTROL endif # BT +if !BOOTLOADER_MCUBOOT + +config FLASH_LOAD_OFFSET + default 0xc000 + +endif # !BOOTLOADER_MCUBOOT + endif # SOC_APOLLO3_BLUE diff --git a/soc/amd/acp_6_0/Kconfig.soc b/soc/amd/acp_6_0/Kconfig.soc index 89f5a09f2f7d0..96f7fae4e4bc0 100644 --- a/soc/amd/acp_6_0/Kconfig.soc +++ b/soc/amd/acp_6_0/Kconfig.soc @@ -10,4 +10,4 @@ config SOC config SOC_TOOLCHAIN_NAME string - default "amd_acp_6_0_adsp" + default "amd_acp_6_0_adsp" if SOC_ACP_6_0 diff --git a/soc/amd/acp_6_0/adsp/linker.ld b/soc/amd/acp_6_0/adsp/linker.ld index 8a16d331d7f15..ff3dd4342f9bd 100644 --- a/soc/amd/acp_6_0/adsp/linker.ld +++ b/soc/amd/acp_6_0/adsp/linker.ld @@ -524,6 +524,14 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } .debug_ranges 0 : { *(.debug_ranges) } + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } .xtensa.info 0 : { *(.xtensa.info) } .xt.insn 0 : diff --git a/soc/antmicro/myra/Kconfig b/soc/antmicro/myra/Kconfig new file mode 100644 index 0000000000000..5dd9da987703e --- /dev/null +++ b/soc/antmicro/myra/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config SOC_MYRA + select SOC_STM32G491XX diff --git a/soc/antmicro/myra/Kconfig.soc b/soc/antmicro/myra/Kconfig.soc new file mode 100644 index 0000000000000..adc05f48a5a3a --- /dev/null +++ b/soc/antmicro/myra/Kconfig.soc @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +# The Myra is technically a SiP (System-in-Package) that consists of +# the STM32G491REI6 MCU and additional components like FRAM. So for +# Antmicro Myra SiP Baseboard the STM32G491XX SoC is to be indicated as +# the build target, but since the Myra SiP is what a user can actually +# see on a board, using only STM32G491XX in the Zephyr build +# infrastructure might be confusing. That's why in the top level of SoC +# definitions (for user-configurable options in Kconfig, for example) +# the Myra term is used and STM32G491XX underneath. +config SOC_MYRA + bool + help + Antmicro Myra System-in-Package + +config SOC + default "myra" if SOC_MYRA diff --git a/soc/antmicro/myra/soc.yml b/soc/antmicro/myra/soc.yml new file mode 100644 index 0000000000000..a36bf71cc87e6 --- /dev/null +++ b/soc/antmicro/myra/soc.yml @@ -0,0 +1,2 @@ +socs: + - name: myra diff --git a/soc/arm/mps2/Kconfig b/soc/arm/mps2/Kconfig index 248be2250a21c..2c999393a7732 100644 --- a/soc/arm/mps2/Kconfig +++ b/soc/arm/mps2/Kconfig @@ -1,4 +1,5 @@ # Copyright (c) 2017-2019 Linaro Limited +# Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 config SOC_SERIES_MPS2 @@ -9,10 +10,25 @@ config SOC_MPS2_AN521 select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU +config SOC_MPS2_AN383 + select CPU_CORTEX_M0PLUS + select CPU_HAS_ARM_MPU + select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR + config SOC_MPS2_AN385 select CPU_CORTEX_M3 select CPU_HAS_ARM_MPU +config SOC_MPS2_AN386 + select CPU_CORTEX_M4 + select CPU_HAS_ARM_MPU + select CPU_HAS_VFP + +config SOC_MPS2_AN500 + select CPU_CORTEX_M7 + select CPU_HAS_ARM_MPU + config SOC_MPS2_AN521_CPU0 select CPU_HAS_ARM_SAU diff --git a/soc/arm/mps2/Kconfig.defconfig.an383 b/soc/arm/mps2/Kconfig.defconfig.an383 new file mode 100644 index 0000000000000..0d59cb09d261a --- /dev/null +++ b/soc/arm/mps2/Kconfig.defconfig.an383 @@ -0,0 +1,9 @@ +# Copyright 2024 Arm Limited and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MPS2_AN383 + +config NUM_IRQS + default 32 + +endif diff --git a/soc/arm/mps2/Kconfig.defconfig.an386 b/soc/arm/mps2/Kconfig.defconfig.an386 new file mode 100644 index 0000000000000..9c75afbef8b16 --- /dev/null +++ b/soc/arm/mps2/Kconfig.defconfig.an386 @@ -0,0 +1,9 @@ +# Copyright 2024 Arm Limited and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MPS2_AN386 + +config NUM_IRQS + default 32 + +endif diff --git a/soc/arm/mps2/Kconfig.defconfig.an500 b/soc/arm/mps2/Kconfig.defconfig.an500 new file mode 100644 index 0000000000000..8cf914f573aec --- /dev/null +++ b/soc/arm/mps2/Kconfig.defconfig.an500 @@ -0,0 +1,9 @@ +# Copyright 2024 Arm Limited and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MPS2_AN500 + +config NUM_IRQS + default 32 + +endif diff --git a/soc/arm/mps2/Kconfig.soc b/soc/arm/mps2/Kconfig.soc index bc9fa98fdcc6c..42ba48639bb30 100644 --- a/soc/arm/mps2/Kconfig.soc +++ b/soc/arm/mps2/Kconfig.soc @@ -1,4 +1,5 @@ # Copyright (c) 2017-2019 Linaro Limited +# Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 config SOC_SERIES_MPS2 @@ -7,12 +8,30 @@ config SOC_SERIES_MPS2 help Enable support for ARM MPS2 MCU Series +config SOC_MPS2_AN383 + bool + select SOC_SERIES_MPS2 + help + ARM Cortex-M0+ SMM on V2M-MPS2 (Application Note AN383) + config SOC_MPS2_AN385 bool select SOC_SERIES_MPS2 help ARM Cortex-M3 SMM on V2M-MPS2 (Application Note AN385) +config SOC_MPS2_AN386 + bool + select SOC_SERIES_MPS2 + help + ARM Cortex-M4 SMM on V2M-MPS2 (Application Note AN386) + +config SOC_MPS2_AN500 + bool + select SOC_SERIES_MPS2 + help + ARM Cortex-M7 SMM on V2M-MPS2+ (Application Note AN500) + config SOC_MPS2_AN521 bool select SOC_SERIES_MPS2 @@ -33,5 +52,8 @@ config SOC_SERIES default "mps2" if SOC_SERIES_MPS2 config SOC + default "an383" if SOC_MPS2_AN383 default "an385" if SOC_MPS2_AN385 + default "an386" if SOC_MPS2_AN386 + default "an500" if SOC_MPS2_AN500 default "an521" if SOC_MPS2_AN521 diff --git a/soc/arm/mps2/soc.c b/soc/arm/mps2/soc.c index 343330d4515c8..a45e1815f3d7e 100644 --- a/soc/arm/mps2/soc.c +++ b/soc/arm/mps2/soc.c @@ -7,40 +7,24 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include - -/* Setup GPIO drivers for accessing FPGAIO registers */ -#define FPGAIO_NODE(n) DT_INST(n, arm_mps2_fpgaio_gpio) -#define FPGAIO_INIT(n) \ - GPIO_MMIO32_INIT(FPGAIO_NODE(n), \ - DT_REG_ADDR(FPGAIO_NODE(n)), \ - BIT_MASK(DT_PROP(FPGAIO_NODE(n), ngpios))) - -/* We expect there to be 3 arm,mps2-fpgaio-gpio devices: - * led0, button, and misc - */ -FPGAIO_INIT(0); -FPGAIO_INIT(1); -FPGAIO_INIT(2); - /* (Secure System Control) Base Address */ -#define SSE_200_SYSTEM_CTRL_S_BASE (0x50021000UL) -#define SSE_200_SYSTEM_CTRL_INITSVTOR1 (SSE_200_SYSTEM_CTRL_S_BASE + 0x114) -#define SSE_200_SYSTEM_CTRL_CPU_WAIT (SSE_200_SYSTEM_CTRL_S_BASE + 0x118) -#define SSE_200_CPU_ID_UNIT_BASE (0x5001F000UL) +#define SSE_200_SYSTEM_CTRL_S_BASE (0x50021000UL) +#define SSE_200_SYSTEM_CTRL_INITSVTOR1 (SSE_200_SYSTEM_CTRL_S_BASE + 0x114) +#define SSE_200_SYSTEM_CTRL_CPU_WAIT (SSE_200_SYSTEM_CTRL_S_BASE + 0x118) +#define SSE_200_CPU_ID_UNIT_BASE (0x5001F000UL) /* The base address that the application image will start at on the secondary * (non-TrustZone) Cortex-M33 mcu. */ -#define CPU1_FLASH_ADDRESS (0x38B000) +#define CPU1_FLASH_ADDRESS (0x38B000) /* The memory map offset for the application image, which is used * to determine the location of the reset vector at startup. */ -#define CPU1_FLASH_OFFSET (0x10000000) +#define CPU1_FLASH_OFFSET (0x10000000) /** * @brief Wake up CPU 1 from another CPU, this is platform specific. @@ -49,9 +33,7 @@ void wakeup_cpu1(void) { /* Set the Initial Secure Reset Vector Register for CPU 1 */ *(uint32_t *)(SSE_200_SYSTEM_CTRL_INITSVTOR1) = - (uint32_t)_vector_start + - CPU1_FLASH_ADDRESS - - CPU1_FLASH_OFFSET; + (uint32_t)_vector_start + CPU1_FLASH_ADDRESS - CPU1_FLASH_OFFSET; /* Set the CPU Boot wait control after reset */ *(uint32_t *)(SSE_200_SYSTEM_CTRL_CPU_WAIT) = 0; diff --git a/soc/arm/mps3/CMakeLists.txt b/soc/arm/mps3/CMakeLists.txt index 3cf33caa58dba..bd8fb92d7804f 100644 --- a/soc/arm/mps3/CMakeLists.txt +++ b/soc/arm/mps3/CMakeLists.txt @@ -1,10 +1,6 @@ # Copyright (c) 2021 Linaro Limited # SPDX-License-Identifier: Apache-2.0 -zephyr_sources( - soc.c - ) - zephyr_include_directories(.) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/arm/mps3/soc.c b/soc/arm/mps3/soc.c deleted file mode 100644 index e51a9ba5c59ad..0000000000000 --- a/soc/arm/mps3/soc.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2021 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - - -/* Setup GPIO drivers for accessing FPGAIO registers */ -#define FPGAIO_NODE(n) DT_INST(n, arm_mps3_fpgaio_gpio) -#define FPGAIO_INIT(n) \ - GPIO_MMIO32_INIT(FPGAIO_NODE(n), \ - DT_REG_ADDR(FPGAIO_NODE(n)), \ - BIT_MASK(DT_PROP(FPGAIO_NODE(n), ngpios))) - -/* We expect there to be 3 arm,mps3-fpgaio-gpio devices: - * led0, button, and misc - */ -FPGAIO_INIT(0); -FPGAIO_INIT(1); -FPGAIO_INIT(2); diff --git a/soc/arm/soc.yml b/soc/arm/soc.yml index 4f1f01726deb4..866f34dafd458 100644 --- a/soc/arm/soc.yml +++ b/soc/arm/soc.yml @@ -3,7 +3,10 @@ family: series: - name: mps2 socs: + - name: an383 - name: an385 + - name: an386 + - name: an500 - name: an521 cpuclusters: - name: cpu0 diff --git a/soc/atmel/sam/common/Kconfig b/soc/atmel/sam/common/Kconfig index e9709351f5ca5..760288ce486e1 100644 --- a/soc/atmel/sam/common/Kconfig +++ b/soc/atmel/sam/common/Kconfig @@ -38,7 +38,7 @@ config SOC_ATMEL_SAM_PLLA_MULA int "PLL MULA" default 6 if SOC_SERIES_SAM3X default 9 if SOC_SERIES_SAM4S || SOC_SERIES_SAM4E - default 24 if SOC_SERIES_SAME70 || SOC_SERIES_SAMV71 + default 24 if SOC_SERIES_SAMX7X range 1 62 help This is the multiplier (MULA) used by the PLL. @@ -65,7 +65,7 @@ config SOC_ATMEL_SAM_PLLA_DIVA config SOC_ATMEL_SAM_MDIV int "MDIV" - depends on SOC_SERIES_SAME70 || SOC_SERIES_SAMV71 + depends on SOC_SERIES_SAMX7X default 2 range 1 4 help diff --git a/soc/atmel/sam/common/pwm_fixup.h b/soc/atmel/sam/common/pwm_fixup.h deleted file mode 100644 index b2a038f8e8660..0000000000000 --- a/soc/atmel/sam/common/pwm_fixup.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2021 Linaro Limited - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef _ATMEL_SAM_PWM_FIXUP_H_ -#define _ATMEL_SAM_PWM_FIXUP_H_ - -/* The SAMV71 HALs change the name of the field, so we need to - * define it this way to match how the other SoC variants name it - */ -#if defined(CONFIG_SOC_SERIES_SAMV71) -#define PWM_CH_NUM PwmChNum -#endif - -#endif /* _ATMEL_SAM_PWM_FIXUP_H_ */ diff --git a/soc/atmel/sam/common/soc_pmc.h b/soc/atmel/sam/common/soc_pmc.h index 3be251a3d09fc..dc730faa026fa 100644 --- a/soc/atmel/sam/common/soc_pmc.h +++ b/soc/atmel/sam/common/soc_pmc.h @@ -119,7 +119,7 @@ static ALWAYS_INLINE void soc_pmc_mck_set_prescaler(uint32_t prescaler) } } -#if defined(CONFIG_SOC_SERIES_SAME70) || defined(CONFIG_SOC_SERIES_SAMV71) +#ifdef CONFIG_SOC_SERIES_SAMX7X /** * @brief Set the divider of the Master clock. @@ -155,7 +155,7 @@ static ALWAYS_INLINE void soc_pmc_mck_set_divider(uint32_t divider) } } -#endif /* CONFIG_SOC_SERIES_SAME70 || CONFIG_SOC_SERIES_SAMV71 */ +#endif /* CONFIG_SOC_SERIES_SAMX7X */ /** * @brief Set the source of the Master clock. diff --git a/soc/atmel/sam/sam4l/soc.c b/soc/atmel/sam/sam4l/soc.c index 3836d99723eba..ae34131515a52 100644 --- a/soc/atmel/sam/sam4l/soc.c +++ b/soc/atmel/sam/sam4l/soc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2023 Gerson Fernando Budke + * Copyright (c) 2020-2025 Gerson Fernando Budke * SPDX-License-Identifier: Apache-2.0 */ @@ -16,33 +16,6 @@ #include #include -/** Watchdog control register first write keys */ -#define WDT_FIRST_KEY 0x55ul -/** Watchdog control register second write keys */ -#define WDT_SECOND_KEY 0xAAul - -/** - * @brief Sets the WatchDog Timer Control register to the \a ctrl value thanks - * to the WatchDog Timer key. - * - * @param ctrl Value to set the WatchDog Timer Control register to. - */ -static ALWAYS_INLINE void wdt_set_ctrl(uint32_t ctrl) -{ - volatile uint32_t dly; - - /** Calculate delay for internal synchronization - * see 45.1.3 WDT errata - */ - dly = DIV_ROUND_UP(48000000 * 2, 115000); - dly >>= 3; /* ~8 cycles for one while loop */ - while (dly--) { - ; - } - WDT->CTRL = ctrl | WDT_CTRL_KEY(WDT_FIRST_KEY); - WDT->CTRL = ctrl | WDT_CTRL_KEY(WDT_SECOND_KEY); -} - #define XTAL_FREQ 12000000 #define NR_PLLS 1 #define PLL_MAX_STARTUP_CYCLES (SCIF_PLL_PLLCOUNT_Msk >> SCIF_PLL_PLLCOUNT_Pos) @@ -83,6 +56,19 @@ static inline bool osc_is_ready(uint8_t id) } } +/** + * Enable Backup System Control Oscilator RC32K + */ +static inline void osc_priv_enable_rc32k(void) +{ + uint32_t temp = BSCIF->RC32KCR; + uint32_t addr = (uint32_t)&BSCIF->RC32KCR - (uint32_t)BSCIF; + + BSCIF->UNLOCK = BSCIF_UNLOCK_KEY(0xAAu) + | BSCIF_UNLOCK_ADDR(addr); + BSCIF->RC32KCR = temp | BSCIF_RC32KCR_EN32K | BSCIF_RC32KCR_EN; +} + /** * The PLL options #PLL_OPT_VCO_RANGE_HIGH and #PLL_OPT_OUTPUT_DIV will * be set automatically based on the calculated target frequency. @@ -180,6 +166,8 @@ static inline void flashcalw_issue_command(uint32_t command, int page_number) */ static ALWAYS_INLINE void clock_init(void) { + uint32_t gen_clk_conf; + /* Disable PicoCache and Enable HRAMC1 as extended RAM */ soc_pmc_peripheral_enable( PM_CLOCK_MASK(PM_CLK_GRP_HSB, SYSCLK_HRAMC1_DATA)); @@ -251,17 +239,28 @@ static ALWAYS_INLINE void clock_init(void) PM->UNLOCK = PM_UNLOCK_KEY(0xAAu) | PM_UNLOCK_ADDR((uint32_t)&PM->MCCTRL - (uint32_t)PM); PM->MCCTRL = OSC_SRC_PLL0; -} -void soc_reset_hook(void) -{ -#if defined(CONFIG_WDT_DISABLE_AT_BOOT) - wdt_set_ctrl(WDT->CTRL & ~WDT_CTRL_EN); - while (WDT->CTRL & WDT_CTRL_EN) { + /** Enable RC32K Oscilator */ + osc_priv_enable_rc32k(); + while (!osc_is_ready(OSC_ID_RC32K)) { ; } -#endif + /** Enable Generic Clock 5 + * Source: RC32K + * Div: 32 + * Clk: 1024 Hz + * The GCLK-5 can be used by GLOC, TC0 and RC32KIFB_REF + */ + gen_clk_conf = SCIF_GCCTRL_RESETVALUE; + gen_clk_conf |= SCIF_GCCTRL_OSCSEL(GEN_CLK_SRC_RC32K); + gen_clk_conf |= SCIF_GCCTRL_DIVEN; + gen_clk_conf |= SCIF_GCCTRL_DIV(((32 + 1) / 2) - 1); + SCIF->GCCTRL[GEN_CLK_TC0_GLOC_RC32] = gen_clk_conf | SCIF_GCCTRL_CEN; +} + +void soc_reset_hook(void) +{ /* Setup system clocks. */ clock_init(); } diff --git a/soc/atmel/sam/sam4l/soc.h b/soc/atmel/sam/sam4l/soc.h index 329178aa2884d..09180c6e2b6ae 100644 --- a/soc/atmel/sam/sam4l/soc.h +++ b/soc/atmel/sam/sam4l/soc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2024 Gerson Fernando Budke + * Copyright (c) 2020-2025 Gerson Fernando Budke * SPDX-License-Identifier: Apache-2.0 */ @@ -66,6 +66,9 @@ /** Master Clock (MCK) Frequency */ #define SOC_ATMEL_SAM_MCK_FREQ_HZ SOC_ATMEL_SAM_HCLK_FREQ_HZ +#define SOC_ATMEL_SAM_RCSYS_NOMINAL_HZ 115000 +#define SOC_ATMEL_SAM_RC32K_NOMINAL_HZ 32768 + /** Oscillator identifiers * External Oscillator 0 * External 32 kHz oscillator @@ -205,18 +208,64 @@ * 10- ADCIFE * 11- Master generic clock. Can be used as source for other generic clocks. */ -#define GEN_CLK_DFLL_REF 0 -#define GEN_CLK_DFLL_DITHER 1 -#define GEN_CLK_AST 2 -#define GEN_CLK_CATB 3 -#define GEN_CLK_AESA 4 -#define GEN_CLK_GLOC 5 -#define GEN_CLK_ABDACB 6 -#define GEN_CLK_USBC 7 -#define GEN_CLK_TC1_PEVC0 8 -#define GEN_CLK_PLL0_PEVC1 9 -#define GEN_CLK_ADCIFE 10 -#define GEN_CLK_MASTER_GEN 11 +#define GEN_CLK_DFLL_REF 0 +#define GEN_CLK_DFLL_DITHER 1 +#define GEN_CLK_AST 2 +#define GEN_CLK_CATB 3 +#define GEN_CLK_AESA 4 +#define GEN_CLK_TC0_GLOC_RC32 5 +#define GEN_CLK_ABDACB 6 +#define GEN_CLK_USBC 7 +#define GEN_CLK_TC1_PEVC0 8 +#define GEN_CLK_PLL0_PEVC1 9 +#define GEN_CLK_ADCIFE 10 +#define GEN_CLK_MASTER_GEN 11 + +/** + * 0- System RC oscillator + * 1- 32 kHz oscillator + * 2- DFLL + * 3- Oscillator 0 + * 4- 80 MHz RC oscillator + * 5- 4-8-12 MHz RC oscillator + * 6- 1 MHz RC oscillator + * 7- CPU clock + * 8- High Speed Bus clock + * 9- Peripheral Bus A clock + * 10- Peripheral Bus B clock + * 11- Peripheral Bus C clock + * 12- Peripheral Bus D clock + * 13- 32 kHz RC oscillator + * 15- 1 kHz output from OSC32K + * 16- PLL0 + * 17- High resolution prescaler + * 18- Fractional prescaler + * 19- GCLKIN0 + * 20- GCLKIN1 + * 21- GCLK11 + */ + +#define GEN_CLK_SRC_RCSYS 0 +#define GEN_CLK_SRC_OSC32K 1 +#define GEN_CLK_SRC_DFLL 2 +#define GEN_CLK_SRC_OSC0 3 +#define GEN_CLK_SRC_RC80M 4 +#define GEN_CLK_SRC_RCFAST 5 +#define GEN_CLK_SRC_RC1M 6 +#define GEN_CLK_SRC_CLK_CPU 7 +#define GEN_CLK_SRC_CLK_HSB 8 +#define GEN_CLK_SRC_CLK_PBA 9 +#define GEN_CLK_SRC_CLK_PBB 10 +#define GEN_CLK_SRC_CLK_PBC 11 +#define GEN_CLK_SRC_CLK_PBD 12 +#define GEN_CLK_SRC_RC32K 13 +#define GEN_CLK_SRC_CLK_1K 15 +#define GEN_CLK_SRC_PLL0 16 +#define GEN_CLK_SRC_HRPCLK 17 +#define GEN_CLK_SRC_FPCLK 18 +#define GEN_CLK_SRC_GCLKIN0 19 +#define GEN_CLK_SRC_GCLKIN1 20 +#define GEN_CLK_SRC_GCLK11 21 #endif /* !_ASMLANGUAGE */ diff --git a/soc/atmel/sam/same70/Kconfig b/soc/atmel/sam/same70/Kconfig deleted file mode 100644 index a41b5e4e5878a..0000000000000 --- a/soc/atmel/sam/same70/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -# Atmel SAM E70 MCU series - -# Copyright (c) 2016 Piotr Mienkowski -# Copyright (c) 2023-2024 Gerson Fernando Budke -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_SAME70 - select ARM - select CPU_CORTEX_M7 - select CPU_CORTEX_M_HAS_DWT - select CPU_HAS_ARM_MPU - select CPU_HAS_FPU_DOUBLE_PRECISION - select CPU_HAS_ICACHE - select CPU_HAS_DCACHE - select INIT_ARCH_HW_AT_BOOT - select SOC_RESET_HOOK - select HAS_SWO - select XIP - select HAS_POWEROFF - select SOC_EARLY_INIT_HOOK diff --git a/soc/atmel/sam/same70/Kconfig.defconfig b/soc/atmel/sam/same70/Kconfig.defconfig deleted file mode 100644 index 6d2a78218c2f6..0000000000000 --- a/soc/atmel/sam/same70/Kconfig.defconfig +++ /dev/null @@ -1,13 +0,0 @@ -# Atmel SAM E70 MCU series configuration options - -# Copyright (c) 2016 Piotr Mienkowski -# Copyright (c) 2023-2024 Gerson Fernando Budke -# SPDX-License-Identifier: Apache-2.0 - -if SOC_SERIES_SAME70 - -config NUM_IRQS - default 74 if SOC_ATMEL_SAME70_REVB - default 71 - -endif # SOC_SERIES_SAME70 diff --git a/soc/atmel/sam/same70/Kconfig.soc b/soc/atmel/sam/same70/Kconfig.soc deleted file mode 100644 index 1cef18f21f1ca..0000000000000 --- a/soc/atmel/sam/same70/Kconfig.soc +++ /dev/null @@ -1,122 +0,0 @@ -# Atmel SAM E70 MCU series - -# Copyright (c) 2016 Piotr Mienkowski -# Copyright (c) 2024 Gerson Fernando Budke -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_SAME70 - bool - select SOC_FAMILY_ATMEL_SAM - help - Enable support for Atmel SAM E70 ARM Cortex-M7 Microcontrollers. - Part No.: SAME70J19, SAME70J20, SAME70J21, SAME70N19, SAME70N20, - SAME70N21, SAME70Q19, SAME70Q20, SAME70Q21, SAME70J19B, SAME70J20B, - SAME70J21B, SAME70N19B, SAME70N20B, SAME70N21B, SAME70Q19B, - SAME70Q20B, SAME70Q21B - -config SOC_ATMEL_SAME70_REVB - bool - -config SOC_SERIES - default "same70" if SOC_SERIES_SAME70 - -config SOC_SAME70J19 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70J20 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70J21 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70N19 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70N20 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70N21 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70Q19 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70Q20 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70Q21 - bool - select SOC_SERIES_SAME70 - -config SOC_SAME70J19B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC_SAME70J20B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC_SAME70J21B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC_SAME70N19B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC_SAME70N20B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC_SAME70N21B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC_SAME70Q19B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC_SAME70Q20B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC_SAME70Q21B - bool - select SOC_SERIES_SAME70 - select SOC_ATMEL_SAME70_REVB - -config SOC - default "same70j19" if SOC_SAME70J19 - default "same70j20" if SOC_SAME70J20 - default "same70j21" if SOC_SAME70J21 - default "same70n19" if SOC_SAME70N19 - default "same70n20" if SOC_SAME70N20 - default "same70n21" if SOC_SAME70N21 - default "same70q19" if SOC_SAME70Q19 - default "same70q20" if SOC_SAME70Q20 - default "same70q21" if SOC_SAME70Q21 - default "same70j19b" if SOC_SAME70J19B - default "same70j20b" if SOC_SAME70J20B - default "same70j21b" if SOC_SAME70J21B - default "same70n19b" if SOC_SAME70N19B - default "same70n20b" if SOC_SAME70N20B - default "same70n21b" if SOC_SAME70N21B - default "same70q19b" if SOC_SAME70Q19B - default "same70q20b" if SOC_SAME70Q20B - default "same70q21b" if SOC_SAME70Q21B diff --git a/soc/atmel/sam/same70/soc.c b/soc/atmel/sam/same70/soc.c deleted file mode 100644 index fdadb506dc562..0000000000000 --- a/soc/atmel/sam/same70/soc.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2016 Piotr Mienkowski - * Copyright (c) 2023-2024 Gerson Fernando Budke - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief Atmel SAM E70 MCU initialization code - * - * This file provides routines to initialize and support board-level hardware - * for the Atmel SAM E70 MCU. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL -LOG_MODULE_REGISTER(soc); - -/** - * @brief Setup various clocks on SoC at boot time. - * - * Setup Slow, Main, PLLA, Processor and Master clocks during the device boot. - * It is assumed that the relevant registers are at their reset value. - */ -static ALWAYS_INLINE void clock_init(void) -{ - /* Switch the main clock to the internal OSC with 12MHz */ - soc_pmc_switch_mainck_to_fastrc(SOC_PMC_FAST_RC_FREQ_12MHZ); - - /* Switch MCK (Master Clock) to the main clock */ - soc_pmc_mck_set_source(SOC_PMC_MCK_SRC_MAIN_CLK); - - EFC->EEFC_FMR = EEFC_FMR_FWS(0) | EEFC_FMR_CLOE; - - soc_pmc_enable_clock_failure_detector(); - - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_SLCK)) { - soc_supc_slow_clock_select_crystal_osc(); - } - - - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_MAINCK)) { - /* - * Setup main external crystal oscillator. - */ - - /* We select maximum setup time. - * While start up time could be shortened - * this optimization is not deemed - * critical now. - */ - soc_pmc_switch_mainck_to_xtal(false, 0xff); - } - - /* - * Set FWS (Flash Wait State) value before increasing Master Clock - * (MCK) frequency. - * TODO: set FWS based on the actual MCK frequency and VDDIO value - * rather than maximum supported 150 MHz at standard VDDIO=2.7V - */ - EFC->EEFC_FMR = EEFC_FMR_FWS(5) | EEFC_FMR_CLOE; - - /* - * Setup PLLA - */ - - /* - * PLL clock = Main * (MULA + 1) / DIVA - * - * By default, MULA == 24, DIVA == 1. - * With main crystal running at 12 MHz, - * PLL = 12 * (24 + 1) / 1 = 300 MHz - * - * With Processor Clock prescaler at 1 - * Processor Clock (HCLK)=300 MHz. - */ - soc_pmc_enable_pllack(CONFIG_SOC_ATMEL_SAM_PLLA_MULA, 0x3Fu, - CONFIG_SOC_ATMEL_SAM_PLLA_DIVA); - - - soc_pmc_enable_upllck(0x3Fu); - - /* - * Final setup of the Master Clock - */ - - /* Setting PLLA as MCK, first prescaler, then divider and source last */ - soc_pmc_mck_set_prescaler(1); - soc_pmc_mck_set_divider(CONFIG_SOC_ATMEL_SAM_MDIV); - soc_pmc_mck_set_source(SOC_PMC_MCK_SRC_PLLA_CLK); - - - /* Disable internal fast RC if we have an external crystal oscillator */ - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_MAINCK)) { - soc_pmc_osc_disable_fastrc(); - } -} - -void soc_reset_hook(void) -{ - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_WAIT_MODE)) { - /* - * Instruct CPU to enter Wait mode instead of Sleep mode to - * keep Processor Clock (HCLK) and thus be able to debug - * CPU using JTAG. - */ - soc_pmc_enable_waitmode(); - } - - /* - * DTCM is enabled by default at reset, therefore we have to disable - * it first to get the caches into a state where then the - * sys_cache*-functions can enable them, if requested by the - * configuration. - */ - SCB_InvalidateDCache(); - SCB_DisableDCache(); - - /* - * Enable the caches only if configured to do so. - */ - sys_cache_instr_enable(); - sys_cache_data_enable(); - - /* Setup system clocks */ - clock_init(); -} - -extern void atmel_same70_config(void); -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run at the very beginning. - */ -void soc_early_init_hook(void) -{ - /* Check that the CHIP CIDR matches the HAL one */ - if (CHIPID->CHIPID_CIDR != CHIP_CIDR) { - LOG_WRN("CIDR mismatch: chip = 0x%08x vs HAL = 0x%08x", - (uint32_t)CHIPID->CHIPID_CIDR, (uint32_t)CHIP_CIDR); - } - atmel_same70_config(); -} diff --git a/soc/atmel/sam/same70/soc.h b/soc/atmel/sam/same70/soc.h deleted file mode 100644 index 92cec70d926af..0000000000000 --- a/soc/atmel/sam/same70/soc.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016 Piotr Mienkowski - * Copyright (c) 2024 Gerson Fernando Budke - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief Register access macros for the Atmel SAM E70 MCU. - * - * This file provides register access macros for the Atmel SAM E70 MCU, HAL - * drivers for core peripherals as well as symbols specific to Atmel SAM family. - */ - -#ifndef _SOC_ATMEL_SAM_SAME70_SOC_H_ -#define _SOC_ATMEL_SAM_SAME70_SOC_H_ - -#include - -#ifndef _ASMLANGUAGE - -#define DONT_USE_CMSIS_INIT -#define DONT_USE_PREDEFINED_CORE_HANDLERS -#define DONT_USE_PREDEFINED_PERIPHERALS_HANDLERS - -#if defined(CONFIG_SOC_SAME70J19) -#include -#elif defined(CONFIG_SOC_SAME70J20) -#include -#elif defined(CONFIG_SOC_SAME70J21) -#include -#elif defined(CONFIG_SOC_SAME70N19) -#include -#elif defined(CONFIG_SOC_SAME70N20) -#include -#elif defined(CONFIG_SOC_SAME70N21) -#include -#elif defined(CONFIG_SOC_SAME70Q19) -#include -#elif defined(CONFIG_SOC_SAME70Q20) -#include -#elif defined(CONFIG_SOC_SAME70Q21) -#include -#elif defined(CONFIG_SOC_SAME70J19B) -#include -#elif defined(CONFIG_SOC_SAME70J20B) -#include -#elif defined(CONFIG_SOC_SAME70J21B) -#include -#elif defined(CONFIG_SOC_SAME70N19B) -#include -#elif defined(CONFIG_SOC_SAME70N20B) -#include -#elif defined(CONFIG_SOC_SAME70N21B) -#include -#elif defined(CONFIG_SOC_SAME70Q19B) -#include -#elif defined(CONFIG_SOC_SAME70Q20B) -#include -#elif defined(CONFIG_SOC_SAME70Q21B) -#include -#else - #error Library does not support the specified device. -#endif - -#include "../common/soc_pmc.h" -#include "../common/soc_gpio.h" -#include "../common/soc_supc.h" -#include "../common/atmel_sam_dt.h" - -/** Processor Clock (HCLK) Frequency */ -#define SOC_ATMEL_SAM_HCLK_FREQ_HZ ATMEL_SAM_DT_CPU_CLK_FREQ_HZ - -/** Master Clock (MCK) Frequency */ -#define SOC_ATMEL_SAM_MCK_FREQ_HZ \ - (SOC_ATMEL_SAM_HCLK_FREQ_HZ / CONFIG_SOC_ATMEL_SAM_MDIV) - -/** UTMI PLL clock (UPLLCK) Frequency */ -#define SOC_ATMEL_SAM_UPLLCK_FREQ_HZ MHZ(480) - -#endif /* _ASMLANGUAGE */ - -#endif /* _SOC_ATMEL_SAM_SAME70_SOC_H_ */ diff --git a/soc/atmel/sam/same70/soc_config.c b/soc/atmel/sam/same70/soc_config.c deleted file mode 100644 index c390235c75958..0000000000000 --- a/soc/atmel/sam/same70/soc_config.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2016 Piotr Mienkowski - * Copyright (c) 2024 Gerson Fernando Budke - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief System module to support early Atmel SAM E70 MCU configuration - */ - -#include -#include -#include -#include - -/** - * @brief Perform SoC configuration at boot. - * - * This should be run early during the boot process but after basic hardware - * initialization is done. - */ -void atmel_same70_config(void) -{ - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_DISABLE_ERASE_PIN)) { - /* Disable ERASE function on PB12 pin, this is controlled - * by Bus Matrix - */ - MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO12; - } - - /* In Cortex-M based SoCs JTAG interface can be used to perform - * IEEE1149.1 JTAG Boundary scan only. It can not be used as a debug - * interface therefore there is no harm done by disabling the JTAG TDI - * pin by default. - */ - /* Disable TDI function on PB4 pin, this is controlled by Bus Matrix */ - MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4; - - if (IS_ENABLED(CONFIG_LOG_BACKEND_SWO)) { - /* Disable PCK3 clock used by ETM module */ - PMC->PMC_SCDR = PMC_SCDR_PCK3; - while ((PMC->PMC_SCSR) & PMC_SCSR_PCK3) { - ; - } - /* Select PLLA clock as PCK3 clock */ - PMC->PMC_PCK[3] = PMC_MCKR_CSS_PLLA_CLK; - /* Enable PCK3 clock */ - PMC->PMC_SCER = PMC_SCER_PCK3; - /* Wait for PCK3 setup to complete */ - while (!((PMC->PMC_SR) & PMC_SR_PCKRDY3)) { - ; - } - /* Enable TDO/TRACESWO function on PB5 pin */ - MATRIX->CCFG_SYSIO &= ~CCFG_SYSIO_SYSIO5; - } else { - /* Disable TDO/TRACESWO function on PB5 pin */ - MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO5; - } - -} diff --git a/soc/atmel/sam/samv71/CMakeLists.txt b/soc/atmel/sam/samv71/CMakeLists.txt deleted file mode 100644 index 2ed685c2f6f4f..0000000000000 --- a/soc/atmel/sam/samv71/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) 2024 Gerson Fernando Budke -# SPDX-License-Identifier: Apache-2.0 - -zephyr_include_directories(.) - -zephyr_sources( - soc.c - soc_config.c - ) - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/atmel/sam/samv71/Kconfig b/soc/atmel/sam/samv71/Kconfig deleted file mode 100644 index c1dcc0c4e3473..0000000000000 --- a/soc/atmel/sam/samv71/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -# Atmel SAM V71 MCU series - -# Copyright (c) 2016 Piotr Mienkowski -# Copyright (c) 2019-2024 Gerson Fernando Budke -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_SAMV71 - select ARM - select CPU_CORTEX_M7 - select CPU_CORTEX_M_HAS_DWT - select CPU_HAS_ARM_MPU - select CPU_HAS_FPU_DOUBLE_PRECISION - select CPU_HAS_ICACHE - select CPU_HAS_DCACHE - select INIT_ARCH_HW_AT_BOOT - select SOC_RESET_HOOK - select HAS_SWO - select XIP - select HAS_POWEROFF - select SOC_EARLY_INIT_HOOK diff --git a/soc/atmel/sam/samv71/Kconfig.defconfig b/soc/atmel/sam/samv71/Kconfig.defconfig deleted file mode 100644 index 2eefe71ec55a3..0000000000000 --- a/soc/atmel/sam/samv71/Kconfig.defconfig +++ /dev/null @@ -1,13 +0,0 @@ -# Atmel SAM V71 MCU series configuration options - -# Copyright (c) 2016 Piotr Mienkowski -# Copyright (c) 2019-2024 Gerson Fernando Budke -# SPDX-License-Identifier: Apache-2.0 - -if SOC_SERIES_SAMV71 - -config NUM_IRQS - default 74 if SOC_ATMEL_SAMV71_REVB - default 71 - -endif # SOC_SERIES_SAMV71 diff --git a/soc/atmel/sam/samv71/Kconfig.soc b/soc/atmel/sam/samv71/Kconfig.soc deleted file mode 100644 index 180ed60c49dfe..0000000000000 --- a/soc/atmel/sam/samv71/Kconfig.soc +++ /dev/null @@ -1,122 +0,0 @@ -# Atmel SAM V71 MCU series - -# Copyright (c) 2016 Piotr Mienkowski -# Copyright (c) 2019-2024 Gerson Fernando Budke -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_SAMV71 - bool - select SOC_FAMILY_ATMEL_SAM - help - Enable support for Atmel SAM V71 ARM Cortex-M7 Microcontrollers. - Part No.: SAMV71J19, SAMV71J20, SAMV71J21, SAMV71N19, SAMV71N20, - SAMV71N21, SAMV71Q19, SAMV71Q20, SAMV71Q21, SAMV71J19B, SAMV71J20B, - SAMV71J21B, SAMV71N19B, SAMV71N20B, SAMV71N21B, SAMV71Q19B, - SAMV71Q20B, SAMV71Q21B - -config SOC_ATMEL_SAMV71_REVB - bool - -config SOC_SERIES - default "samv71" if SOC_SERIES_SAMV71 - -config SOC_SAMV71J19 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71J20 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71J21 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71N19 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71N20 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71N21 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71Q19 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71Q20 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71Q21 - bool - select SOC_SERIES_SAMV71 - -config SOC_SAMV71J19B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC_SAMV71J20B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC_SAMV71J21B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC_SAMV71N19B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC_SAMV71N20B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC_SAMV71N21B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC_SAMV71Q19B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC_SAMV71Q20B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC_SAMV71Q21B - bool - select SOC_SERIES_SAMV71 - select SOC_ATMEL_SAMV71_REVB - -config SOC - default "samv71j19" if SOC_SAMV71J19 - default "samv71j20" if SOC_SAMV71J20 - default "samv71j21" if SOC_SAMV71J21 - default "samv71n19" if SOC_SAMV71N19 - default "samv71n20" if SOC_SAMV71N20 - default "samv71n21" if SOC_SAMV71N21 - default "samv71q19" if SOC_SAMV71Q19 - default "samv71q20" if SOC_SAMV71Q20 - default "samv71q21" if SOC_SAMV71Q21 - default "samv71j19b" if SOC_SAMV71J19B - default "samv71j20b" if SOC_SAMV71J20B - default "samv71j21b" if SOC_SAMV71J21B - default "samv71n19b" if SOC_SAMV71N19B - default "samv71n20b" if SOC_SAMV71N20B - default "samv71n21b" if SOC_SAMV71N21B - default "samv71q19b" if SOC_SAMV71Q19B - default "samv71q20b" if SOC_SAMV71Q20B - default "samv71q21b" if SOC_SAMV71Q21B diff --git a/soc/atmel/sam/samv71/soc.c b/soc/atmel/sam/samv71/soc.c deleted file mode 100644 index a69713167f7fe..0000000000000 --- a/soc/atmel/sam/samv71/soc.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2016 Piotr Mienkowski - * Copyright (c) 2019-2023 Gerson Fernando Budke - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief Atmel SAM V71 MCU initialization code - * - * This file provides routines to initialize and support board-level hardware - * for the Atmel SAM V71 MCU. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL -LOG_MODULE_REGISTER(soc); - -/** - * @brief Setup various clocks on SoC at boot time. - * - * Setup Slow, Main, PLLA, Processor and Master clocks during the device boot. - * It is assumed that the relevant registers are at their reset value. - */ -static ALWAYS_INLINE void clock_init(void) -{ - /* Switch the main clock to the internal OSC with 12MHz */ - soc_pmc_switch_mainck_to_fastrc(SOC_PMC_FAST_RC_FREQ_12MHZ); - - /* Switch MCK (Master Clock) to the main clock */ - soc_pmc_mck_set_source(SOC_PMC_MCK_SRC_MAIN_CLK); - - EFC->EEFC_FMR = EEFC_FMR_FWS(0) | EEFC_FMR_CLOE; - - soc_pmc_enable_clock_failure_detector(); - - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_SLCK)) { - soc_supc_slow_clock_select_crystal_osc(); - } - - - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_MAINCK)) { - /* - * Setup main external crystal oscillator. - */ - - /* We select maximum setup time. - * While start up time could be shortened - * this optimization is not deemed - * critical now. - */ - soc_pmc_switch_mainck_to_xtal(false, 0xff); - } - - /* - * Set FWS (Flash Wait State) value before increasing Master Clock - * (MCK) frequency. - * TODO: set FWS based on the actual MCK frequency and VDDIO value - * rather than maximum supported 150 MHz at standard VDDIO=2.7V - */ - EFC->EEFC_FMR = EEFC_FMR_FWS(5) | EEFC_FMR_CLOE; - - /* - * Setup PLLA - */ - - /* - * PLL clock = Main * (MULA + 1) / DIVA - * - * By default, MULA == 24, DIVA == 1. - * With main crystal running at 12 MHz, - * PLL = 12 * (24 + 1) / 1 = 300 MHz - * - * With Processor Clock prescaler at 1 - * Processor Clock (HCLK)=300 MHz. - */ - soc_pmc_enable_pllack(CONFIG_SOC_ATMEL_SAM_PLLA_MULA, 0x3Fu, - CONFIG_SOC_ATMEL_SAM_PLLA_DIVA); - - - soc_pmc_enable_upllck(0x3Fu); - - /* - * Final setup of the Master Clock - */ - - /* Setting PLLA as MCK, first prescaler, then divider and source last */ - soc_pmc_mck_set_prescaler(1); - soc_pmc_mck_set_divider(CONFIG_SOC_ATMEL_SAM_MDIV); - soc_pmc_mck_set_source(SOC_PMC_MCK_SRC_PLLA_CLK); - - /* Disable internal fast RC if we have an external crystal oscillator */ - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_MAINCK)) { - soc_pmc_osc_disable_fastrc(); - } -} - -void soc_reset_hook(void) -{ - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_WAIT_MODE)) { - /* - * Instruct CPU to enter Wait mode instead of Sleep mode to - * keep Processor Clock (HCLK) and thus be able to debug - * CPU using JTAG. - */ - soc_pmc_enable_waitmode(); - } - - /* - * DTCM is enabled by default at reset, therefore we have to disable - * it first to get the caches into a state where then the - * sys_cache*-functions can enable them, if requested by the - * configuration. - */ - SCB_InvalidateDCache(); - SCB_DisableDCache(); - - /* - * Enable the caches only if configured to do so. - */ - sys_cache_instr_enable(); - sys_cache_data_enable(); - - /* Setup system clocks */ - clock_init(); -} - -extern void atmel_samv71_config(void); -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run at the very beginning. - */ -void soc_early_init_hook(void) -{ - /* Check that the CHIP CIDR matches the HAL one */ - if (CHIPID->CHIPID_CIDR != CHIP_CIDR) { - LOG_WRN("CIDR mismatch: chip = 0x%08x vs HAL = 0x%08x", - (uint32_t)CHIPID->CHIPID_CIDR, (uint32_t)CHIP_CIDR); - } - atmel_samv71_config(); -} diff --git a/soc/atmel/sam/samv71/soc.h b/soc/atmel/sam/samv71/soc.h deleted file mode 100644 index 8b54125bce52e..0000000000000 --- a/soc/atmel/sam/samv71/soc.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016 Piotr Mienkowski - * Copyright (c) 2019-2024 Gerson Fernando Budke - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief Register access macros for the Atmel SAM V71 MCU. - * - * This file provides register access macros for the Atmel SAM V71 MCU, HAL - * drivers for core peripherals as well as symbols specific to Atmel SAM family. - */ - -#ifndef _SOC_ATMEL_SAM_SAMV71_SOC_H_ -#define _SOC_ATMEL_SAM_SAMV71_SOC_H_ - -#include - -#ifndef _ASMLANGUAGE - -#define DONT_USE_CMSIS_INIT -#define DONT_USE_PREDEFINED_CORE_HANDLERS -#define DONT_USE_PREDEFINED_PERIPHERALS_HANDLERS - -#if defined(CONFIG_SOC_SAMV71J19) -#include -#elif defined(CONFIG_SOC_SAMV71J20) -#include -#elif defined(CONFIG_SOC_SAMV71J21) -#include -#elif defined(CONFIG_SOC_SAMV71N19) -#include -#elif defined(CONFIG_SOC_SAMV71N20) -#include -#elif defined(CONFIG_SOC_SAMV71N21) -#include -#elif defined(CONFIG_SOC_SAMV71Q19) -#include -#elif defined(CONFIG_SOC_SAMV71Q20) -#include -#elif defined(CONFIG_SOC_SAMV71Q21) -#include -#elif defined(CONFIG_SOC_SAMV71J19B) -#include -#elif defined(CONFIG_SOC_SAMV71J20B) -#include -#elif defined(CONFIG_SOC_SAMV71J21B) -#include -#elif defined(CONFIG_SOC_SAMV71N19B) -#include -#elif defined(CONFIG_SOC_SAMV71N20B) -#include -#elif defined(CONFIG_SOC_SAMV71N21B) -#include -#elif defined(CONFIG_SOC_SAMV71Q19B) -#include -#elif defined(CONFIG_SOC_SAMV71Q20B) -#include -#elif defined(CONFIG_SOC_SAMV71Q21B) -#include -#else - #error Library does not support the specified device. -#endif - -#include "../common/soc_pmc.h" -#include "../common/soc_gpio.h" -#include "../common/soc_supc.h" -#include "../common/atmel_sam_dt.h" - -/** Processor Clock (HCLK) Frequency */ -#define SOC_ATMEL_SAM_HCLK_FREQ_HZ ATMEL_SAM_DT_CPU_CLK_FREQ_HZ - -/** Master Clock (MCK) Frequency */ -#define SOC_ATMEL_SAM_MCK_FREQ_HZ \ - (SOC_ATMEL_SAM_HCLK_FREQ_HZ / CONFIG_SOC_ATMEL_SAM_MDIV) - -/** UTMI PLL clock (UPLLCK) Frequency */ -#define SOC_ATMEL_SAM_UPLLCK_FREQ_HZ MHZ(480) - -#endif /* _ASMLANGUAGE */ - -#include "pwm_fixup.h" - -#endif /* _SOC_ATMEL_SAM_SAMV71_SOC_H_ */ diff --git a/soc/atmel/sam/samv71/soc_config.c b/soc/atmel/sam/samv71/soc_config.c deleted file mode 100644 index 85a07e6b6b112..0000000000000 --- a/soc/atmel/sam/samv71/soc_config.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2016 Piotr Mienkowski - * Copyright (c) 2019-2024 Gerson Fernando Budke - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief System module to support early Atmel SAM V71 MCU configuration - */ - -#include -#include -#include -#include - -/** - * @brief Perform SoC configuration at boot. - * - * This should be run early during the boot process but after basic hardware - * initialization is done. - */ -void atmel_samv71_config(void) -{ - if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_DISABLE_ERASE_PIN)) { - /* Disable ERASE function on PB12 pin, this is controlled - * by Bus Matrix - */ - MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO12; - } - - /* In Cortex-M based SoCs JTAG interface can be used to perform - * IEEE1149.1 JTAG Boundary scan only. It can not be used as a debug - * interface therefore there is no harm done by disabling the JTAG TDI - * pin by default. - */ - /* Disable TDI function on PB4 pin, this is controlled by Bus Matrix - */ - MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4; - - if (IS_ENABLED(CONFIG_LOG_BACKEND_SWO)) { - /* Disable PCK3 clock used by ETM module */ - PMC->PMC_SCDR = PMC_SCDR_PCK3; - while ((PMC->PMC_SCSR) & PMC_SCSR_PCK3) { - ; - } - /* Select PLLA clock as PCK3 clock */ - PMC->PMC_PCK[3] = PMC_MCKR_CSS_PLLA_CLK; - /* Enable PCK3 clock */ - PMC->PMC_SCER = PMC_SCER_PCK3; - /* Wait for PCK3 setup to complete */ - while (!((PMC->PMC_SR) & PMC_SR_PCKRDY3)) { - ; - } - /* Enable TDO/TRACESWO function on PB5 pin */ - MATRIX->CCFG_SYSIO &= ~CCFG_SYSIO_SYSIO5; - } else { - /* Disable TDO/TRACESWO function on PB5 pin */ - MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO5; - } -} diff --git a/soc/atmel/sam/same70/CMakeLists.txt b/soc/atmel/sam/samx7x/CMakeLists.txt similarity index 100% rename from soc/atmel/sam/same70/CMakeLists.txt rename to soc/atmel/sam/samx7x/CMakeLists.txt diff --git a/soc/atmel/sam/samx7x/Kconfig b/soc/atmel/sam/samx7x/Kconfig new file mode 100644 index 0000000000000..cd685170db9a4 --- /dev/null +++ b/soc/atmel/sam/samx7x/Kconfig @@ -0,0 +1,20 @@ +# Atmel SAM E70/S70/V70/V71 MCU series + +# Copyright (c) 2016 Piotr Mienkowski +# Copyright (c) 2019-2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SAMX7X + select ARM + select CPU_CORTEX_M7 + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU_DOUBLE_PRECISION + select CPU_HAS_ICACHE + select CPU_HAS_DCACHE + select INIT_ARCH_HW_AT_BOOT + select SOC_RESET_HOOK + select HAS_SWO + select XIP + select HAS_POWEROFF + select SOC_EARLY_INIT_HOOK diff --git a/soc/atmel/sam/samx7x/Kconfig.defconfig b/soc/atmel/sam/samx7x/Kconfig.defconfig new file mode 100644 index 0000000000000..7c9de5a3e8159 --- /dev/null +++ b/soc/atmel/sam/samx7x/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Atmel SAM E70/S70/V70/V71 MCU series configuration options + +# Copyright (c) 2016 Piotr Mienkowski +# Copyright (c) 2019-2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_SAMX7X + +config NUM_IRQS + default 74 if SOC_ATMEL_SAME70_REVB + default 74 if SOC_ATMEL_SAMV71_REVB + default 71 + +endif # SOC_SERIES_SAMX7X diff --git a/soc/atmel/sam/samx7x/Kconfig.soc b/soc/atmel/sam/samx7x/Kconfig.soc new file mode 100644 index 0000000000000..296cc75e0060b --- /dev/null +++ b/soc/atmel/sam/samx7x/Kconfig.soc @@ -0,0 +1,17 @@ +# Atmel SAM E70/S70/V70/V71 MCU series + +# Copyright (c) 2016 Piotr Mienkowski +# Copyright (c) 2019-2024 Gerson Fernando Budke +# Copyright (c) 2024 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SAMX7X + bool + select SOC_FAMILY_ATMEL_SAM + help + Enable support for Atmel SAM E70/S70/V70/V71 ARM Cortex-M7 Microcontrollers. + +config SOC_SERIES + default "samx7x" if SOC_SERIES_SAMX7X + +rsource "Kconfig.soc.sam*" diff --git a/soc/atmel/sam/samx7x/Kconfig.soc.same70 b/soc/atmel/sam/samx7x/Kconfig.soc.same70 new file mode 100644 index 0000000000000..341bf827b287a --- /dev/null +++ b/soc/atmel/sam/samx7x/Kconfig.soc.same70 @@ -0,0 +1,106 @@ +# Atmel SAM E70 MCU series + +# Copyright (c) 2016 Piotr Mienkowski +# Copyright (c) 2024 Gerson Fernando Budke +# Copyright (c) 2024 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config SOC_ATMEL_SAME70 + select SOC_SERIES_SAMX7X + bool + +config SOC_ATMEL_SAME70_REVB + select SOC_SERIES_SAMX7X + bool + +config SOC_SAME70J19 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70J20 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70J21 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70N19 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70N20 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70N21 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70Q19 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70Q20 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70Q21 + bool + select SOC_ATMEL_SAME70 + +config SOC_SAME70J19B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC_SAME70J20B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC_SAME70J21B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC_SAME70N19B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC_SAME70N20B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC_SAME70N21B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC_SAME70Q19B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC_SAME70Q20B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC_SAME70Q21B + bool + select SOC_ATMEL_SAME70_REVB + +config SOC + default "same70j19" if SOC_SAME70J19 + default "same70j20" if SOC_SAME70J20 + default "same70j21" if SOC_SAME70J21 + default "same70n19" if SOC_SAME70N19 + default "same70n20" if SOC_SAME70N20 + default "same70n21" if SOC_SAME70N21 + default "same70q19" if SOC_SAME70Q19 + default "same70q20" if SOC_SAME70Q20 + default "same70q21" if SOC_SAME70Q21 + default "same70j19b" if SOC_SAME70J19B + default "same70j20b" if SOC_SAME70J20B + default "same70j21b" if SOC_SAME70J21B + default "same70n19b" if SOC_SAME70N19B + default "same70n20b" if SOC_SAME70N20B + default "same70n21b" if SOC_SAME70N21B + default "same70q19b" if SOC_SAME70Q19B + default "same70q20b" if SOC_SAME70Q20B + default "same70q21b" if SOC_SAME70Q21B diff --git a/soc/atmel/sam/samx7x/Kconfig.soc.samv71 b/soc/atmel/sam/samx7x/Kconfig.soc.samv71 new file mode 100644 index 0000000000000..9a1b59dcb8109 --- /dev/null +++ b/soc/atmel/sam/samx7x/Kconfig.soc.samv71 @@ -0,0 +1,106 @@ +# Atmel SAM V71 MCU series + +# Copyright (c) 2016 Piotr Mienkowski +# Copyright (c) 2019-2024 Gerson Fernando Budke +# Copyright (c) 2024 Henrik Brix Andersen +# SPDX-License-Identifier: Apache-2.0 + +config SOC_ATMEL_SAMV71 + bool + select SOC_SERIES_SAMX7X + +config SOC_ATMEL_SAMV71_REVB + bool + select SOC_SERIES_SAMX7X + +config SOC_SAMV71J19 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71J20 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71J21 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71N19 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71N20 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71N21 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71Q19 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71Q20 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71Q21 + bool + select SOC_ATMEL_SAMV71 + +config SOC_SAMV71J19B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC_SAMV71J20B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC_SAMV71J21B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC_SAMV71N19B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC_SAMV71N20B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC_SAMV71N21B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC_SAMV71Q19B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC_SAMV71Q20B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC_SAMV71Q21B + bool + select SOC_ATMEL_SAMV71_REVB + +config SOC + default "samv71j19" if SOC_SAMV71J19 + default "samv71j20" if SOC_SAMV71J20 + default "samv71j21" if SOC_SAMV71J21 + default "samv71n19" if SOC_SAMV71N19 + default "samv71n20" if SOC_SAMV71N20 + default "samv71n21" if SOC_SAMV71N21 + default "samv71q19" if SOC_SAMV71Q19 + default "samv71q20" if SOC_SAMV71Q20 + default "samv71q21" if SOC_SAMV71Q21 + default "samv71j19b" if SOC_SAMV71J19B + default "samv71j20b" if SOC_SAMV71J20B + default "samv71j21b" if SOC_SAMV71J21B + default "samv71n19b" if SOC_SAMV71N19B + default "samv71n20b" if SOC_SAMV71N20B + default "samv71n21b" if SOC_SAMV71N21B + default "samv71q19b" if SOC_SAMV71Q19B + default "samv71q20b" if SOC_SAMV71Q20B + default "samv71q21b" if SOC_SAMV71Q21B diff --git a/soc/atmel/sam/samx7x/soc.c b/soc/atmel/sam/samx7x/soc.c new file mode 100644 index 0000000000000..72360cc141126 --- /dev/null +++ b/soc/atmel/sam/samx7x/soc.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2016 Piotr Mienkowski + * Copyright (c) 2019-2024 Gerson Fernando Budke + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Atmel SAM E70/S70/V70/V71 MCU series initialization code + * + * This file provides routines to initialize and support board-level hardware + * for the Atmel SAM E70/S70/V70/V71 MCU series. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL +LOG_MODULE_REGISTER(soc); + +/** + * @brief Setup various clocks on SoC at boot time. + * + * Setup Slow, Main, PLLA, Processor and Master clocks during the device boot. + * It is assumed that the relevant registers are at their reset value. + */ +static ALWAYS_INLINE void clock_init(void) +{ + /* Switch the main clock to the internal OSC with 12MHz */ + soc_pmc_switch_mainck_to_fastrc(SOC_PMC_FAST_RC_FREQ_12MHZ); + + /* Switch MCK (Master Clock) to the main clock */ + soc_pmc_mck_set_source(SOC_PMC_MCK_SRC_MAIN_CLK); + + EFC->EEFC_FMR = EEFC_FMR_FWS(0) | EEFC_FMR_CLOE; + + soc_pmc_enable_clock_failure_detector(); + + if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_SLCK)) { + soc_supc_slow_clock_select_crystal_osc(); + } + + if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_MAINCK)) { + /* + * Setup main external crystal oscillator. + */ + + /* We select maximum setup time. + * While start up time could be shortened + * this optimization is not deemed + * critical now. + */ + soc_pmc_switch_mainck_to_xtal(false, 0xff); + } + + /* + * Set FWS (Flash Wait State) value before increasing Master Clock + * (MCK) frequency. + * TODO: set FWS based on the actual MCK frequency and VDDIO value + * rather than maximum supported 150 MHz at standard VDDIO=2.7V + */ + EFC->EEFC_FMR = EEFC_FMR_FWS(5) | EEFC_FMR_CLOE; + + /* + * Setup PLLA + */ + + /* + * PLL clock = Main * (MULA + 1) / DIVA + * + * By default, MULA == 24, DIVA == 1. + * With main crystal running at 12 MHz, + * PLL = 12 * (24 + 1) / 1 = 300 MHz + * + * With Processor Clock prescaler at 1 + * Processor Clock (HCLK)=300 MHz. + */ + soc_pmc_enable_pllack(CONFIG_SOC_ATMEL_SAM_PLLA_MULA, 0x3Fu, + CONFIG_SOC_ATMEL_SAM_PLLA_DIVA); + + soc_pmc_enable_upllck(0x3Fu); + + /* + * Final setup of the Master Clock + */ + + /* Setting PLLA as MCK, first prescaler, then divider and source last */ + soc_pmc_mck_set_prescaler(1); + soc_pmc_mck_set_divider(CONFIG_SOC_ATMEL_SAM_MDIV); + soc_pmc_mck_set_source(SOC_PMC_MCK_SRC_PLLA_CLK); + + /* Disable internal fast RC if we have an external crystal oscillator */ + if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_EXT_MAINCK)) { + soc_pmc_osc_disable_fastrc(); + } +} + +void soc_reset_hook(void) +{ + if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_WAIT_MODE)) { + /* + * Instruct CPU to enter Wait mode instead of Sleep mode to + * keep Processor Clock (HCLK) and thus be able to debug + * CPU using JTAG. + */ + soc_pmc_enable_waitmode(); + } + + /* + * DTCM is enabled by default at reset, therefore we have to disable + * it first to get the caches into a state where then the + * sys_cache*-functions can enable them, if requested by the + * configuration. + */ + SCB_InvalidateDCache(); + SCB_DisableDCache(); + + /* + * Enable the caches only if configured to do so. + */ + sys_cache_instr_enable(); + sys_cache_data_enable(); + + /* Setup system clocks */ + clock_init(); +} + +extern void atmel_samx7x_config(void); +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run at the very beginning. + */ +void soc_early_init_hook(void) +{ + /* Check that the CHIP CIDR matches the HAL one */ + if (CHIPID->CHIPID_CIDR != CHIP_CIDR) { + LOG_WRN("CIDR mismatch: chip = 0x%08x vs HAL = 0x%08x", + (uint32_t)CHIPID->CHIPID_CIDR, (uint32_t)CHIP_CIDR); + } + + atmel_samx7x_config(); +} diff --git a/soc/atmel/sam/samx7x/soc.h b/soc/atmel/sam/samx7x/soc.h new file mode 100644 index 0000000000000..ddd3d5a2e314a --- /dev/null +++ b/soc/atmel/sam/samx7x/soc.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016 Piotr Mienkowski + * Copyright (c) 2019-2024 Gerson Fernando Budke + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Register access macros for the Atmel SAM E70/S70/V70/V71 MCU series. + * + * This file provides register access macros for the Atmel SAM E70/S70/V70/V71 MCU series, HAL + * drivers for core peripherals as well as symbols specific to this Atmel SAM family. + */ + +#ifndef _SOC_ATMEL_SAM_SAMX7X_SOC_H_ +#define _SOC_ATMEL_SAM_SAMX7X_SOC_H_ + +#include + +#ifndef _ASMLANGUAGE + +#define DONT_USE_CMSIS_INIT +#define DONT_USE_PREDEFINED_CORE_HANDLERS +#define DONT_USE_PREDEFINED_PERIPHERALS_HANDLERS + +#if defined(CONFIG_SOC_SAME70J19) +#include +#elif defined(CONFIG_SOC_SAME70J20) +#include +#elif defined(CONFIG_SOC_SAME70J21) +#include +#elif defined(CONFIG_SOC_SAME70N19) +#include +#elif defined(CONFIG_SOC_SAME70N20) +#include +#elif defined(CONFIG_SOC_SAME70N21) +#include +#elif defined(CONFIG_SOC_SAME70Q19) +#include +#elif defined(CONFIG_SOC_SAME70Q20) +#include +#elif defined(CONFIG_SOC_SAME70Q21) +#include +#elif defined(CONFIG_SOC_SAME70J19B) +#include +#elif defined(CONFIG_SOC_SAME70J20B) +#include +#elif defined(CONFIG_SOC_SAME70J21B) +#include +#elif defined(CONFIG_SOC_SAME70N19B) +#include +#elif defined(CONFIG_SOC_SAME70N20B) +#include +#elif defined(CONFIG_SOC_SAME70N21B) +#include +#elif defined(CONFIG_SOC_SAME70Q19B) +#include +#elif defined(CONFIG_SOC_SAME70Q20B) +#include +#elif defined(CONFIG_SOC_SAME70Q21B) +#include +#elif defined(CONFIG_SOC_SAMV71J19) +#include +#elif defined(CONFIG_SOC_SAMV71J20) +#include +#elif defined(CONFIG_SOC_SAMV71J21) +#include +#elif defined(CONFIG_SOC_SAMV71N19) +#include +#elif defined(CONFIG_SOC_SAMV71N20) +#include +#elif defined(CONFIG_SOC_SAMV71N21) +#include +#elif defined(CONFIG_SOC_SAMV71Q19) +#include +#elif defined(CONFIG_SOC_SAMV71Q20) +#include +#elif defined(CONFIG_SOC_SAMV71Q21) +#include +#elif defined(CONFIG_SOC_SAMV71J19B) +#include +#elif defined(CONFIG_SOC_SAMV71J20B) +#include +#elif defined(CONFIG_SOC_SAMV71J21B) +#include +#elif defined(CONFIG_SOC_SAMV71N19B) +#include +#elif defined(CONFIG_SOC_SAMV71N20B) +#include +#elif defined(CONFIG_SOC_SAMV71N21B) +#include +#elif defined(CONFIG_SOC_SAMV71Q19B) +#include +#elif defined(CONFIG_SOC_SAMV71Q20B) +#include +#elif defined(CONFIG_SOC_SAMV71Q21B) +#include +#else + #error Library does not support the specified device. +#endif + +#include "../common/soc_pmc.h" +#include "../common/soc_gpio.h" +#include "../common/soc_supc.h" +#include "../common/atmel_sam_dt.h" + +/** Processor Clock (HCLK) Frequency */ +#define SOC_ATMEL_SAM_HCLK_FREQ_HZ ATMEL_SAM_DT_CPU_CLK_FREQ_HZ + +/** Master Clock (MCK) Frequency */ +#define SOC_ATMEL_SAM_MCK_FREQ_HZ \ + (SOC_ATMEL_SAM_HCLK_FREQ_HZ / CONFIG_SOC_ATMEL_SAM_MDIV) + +/** UTMI PLL clock (UPLLCK) Frequency */ +#define SOC_ATMEL_SAM_UPLLCK_FREQ_HZ MHZ(480) + +#endif /* _ASMLANGUAGE */ + +#endif /* _SOC_ATMEL_SAM_SAMX7X_SOC_H_ */ diff --git a/soc/atmel/sam/samx7x/soc_config.c b/soc/atmel/sam/samx7x/soc_config.c new file mode 100644 index 0000000000000..613a88e1acee8 --- /dev/null +++ b/soc/atmel/sam/samx7x/soc_config.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016 Piotr Mienkowski + * Copyright (c) 2019-2024 Gerson Fernando Budke + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief System module to support early Atmel SAM E70/S70/V70/V71 MCU series configuration + */ + +#include +#include +#include +#include + +/** + * @brief Perform SoC configuration at boot. + * + * This should be run early during the boot process but after basic hardware + * initialization is done. + */ +void atmel_samx7x_config(void) +{ + if (IS_ENABLED(CONFIG_SOC_ATMEL_SAM_DISABLE_ERASE_PIN)) { + /* Disable ERASE function on PB12 pin, this is controlled + * by Bus Matrix + */ + MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO12; + } + + /* In Cortex-M based SoCs JTAG interface can be used to perform + * IEEE1149.1 JTAG Boundary scan only. It can not be used as a debug + * interface therefore there is no harm done by disabling the JTAG TDI + * pin by default. + */ + /* Disable TDI function on PB4 pin, this is controlled by Bus Matrix + */ + MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4; + + if (IS_ENABLED(CONFIG_LOG_BACKEND_SWO)) { + /* Disable PCK3 clock used by ETM module */ + PMC->PMC_SCDR = PMC_SCDR_PCK3; + while ((PMC->PMC_SCSR) & PMC_SCSR_PCK3) { + ; + } + /* Select PLLA clock as PCK3 clock */ + PMC->PMC_PCK[3] = PMC_MCKR_CSS_PLLA_CLK; + /* Enable PCK3 clock */ + PMC->PMC_SCER = PMC_SCER_PCK3; + /* Wait for PCK3 setup to complete */ + while (!((PMC->PMC_SR) & PMC_SR_PCKRDY3)) { + ; + } + /* Enable TDO/TRACESWO function on PB5 pin */ + MATRIX->CCFG_SYSIO &= ~CCFG_SYSIO_SYSIO5; + } else { + /* Disable TDO/TRACESWO function on PB5 pin */ + MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO5; + } +} diff --git a/soc/atmel/sam0/common/Kconfig.samd2x b/soc/atmel/sam0/common/Kconfig.samd2x index f23b655796313..11f76f608a145 100644 --- a/soc/atmel/sam0/common/Kconfig.samd2x +++ b/soc/atmel/sam0/common/Kconfig.samd2x @@ -1,3 +1,4 @@ +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 if SOC_SERIES_SAMD20 || SOC_SERIES_SAMD21 || SOC_SERIES_SAMR21 @@ -35,6 +36,21 @@ config SOC_ATMEL_SAMD_XOSC32K_CRYSTAL Enable the crystal oscillator (if disabled, expect a clock signal on XIN32). +DT_ATMEL_RTC := $(dt_nodelabel_path,rtc) +DT_ATMEL_RTC_COUNTER_CLOCK_MODE := $(dt_node_str_prop_equals,$(DT_ATMEL_RTC),counter-mode,clock) + +config SOC_ATMEL_SAMD_XOSC32K_PRESCALER + int "XOSC32 Generic Clock Prescaler" + range 1 512 + default 32 if "$(DT_ATMEL_RTC_COUNTER_CLOCK_MODE)" + default 1 + depends on SOC_ATMEL_SAMD_XOSC32K + help + Configure the prescaler for the generic clock output + connected on the xosc32. When using RTC in calendar mode + the GCLK should be divided by 32 to RTC receive the + 1024 Hz reference clock. + config SOC_ATMEL_SAMD_XOSC bool "External 0.4..32 MHz clock source" help diff --git a/soc/atmel/sam0/common/Kconfig.samd5x b/soc/atmel/sam0/common/Kconfig.samd5x index dd05fe605d1e4..e18616862e1f5 100644 --- a/soc/atmel/sam0/common/Kconfig.samd5x +++ b/soc/atmel/sam0/common/Kconfig.samd5x @@ -1,4 +1,5 @@ # Copyright (c) 2019 ML!PA Consulting GmbH +# Copyright (c) 2024-2025 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 if SOC_SERIES_SAMD51 || SOC_SERIES_SAME51 || SOC_SERIES_SAME53 || SOC_SERIES_SAME54 @@ -10,6 +11,42 @@ config SOC_ATMEL_SAMD5X_XOSC32K startup. This can then be selected as the main clock source for the SOC. +config SOC_ATMEL_SAMD5X_XOSC32K_STARTUP + depends on SOC_ATMEL_SAMD5X_XOSC32K + hex "Startup time external 32 kHz crystal oscillator" + range 0x0 0x6 + default 0x1 + help + Selects the startup time for the external 32 kHz crystal oscillator. + +config SOC_ATMEL_SAMD5X_XOSC32K_CRYSTAL + bool "External 32.768 kHz clock is a crystal oscillator" + depends on SOC_ATMEL_SAMD5X_XOSC32K + default y + help + Enable the crystal oscillator (if disabled, expect a clock + signal on XIN32). + +config SOC_ATMEL_SAMD5X_XOSC32K_GAIN_HS + bool "XOSC32 High Speed gain" + depends on SOC_ATMEL_SAMD5X_XOSC32K + help + When this option is selected the gain is set High Speed + instead standard. + +DT_ATMEL_RTC := $(dt_nodelabel_path,rtc) +DT_ATMEL_RTC_COUNTER_CLOCK_MODE := $(dt_node_str_prop_equals,$(DT_ATMEL_RTC),counter-mode,clock) + +config SOC_ATMEL_SAMD5X_OSC32K_PRESCALER + int "XOSC32 Generic Clock Prescaler" + range 1 512 + default 32 if "$(DT_ATMEL_RTC_COUNTER_CLOCK_MODE)" + default 1 + help + Configure the prescaler for the generic clock output connected on the + xosc32 or osculp32k. When using RTC in calendar mode the GCLK should + be divided by 32 to RTC receive the 1024 Hz reference clock. + choice prompt "Main clock source" default SOC_ATMEL_SAMD5X_DEFAULT_AS_MAIN diff --git a/soc/atmel/sam0/common/atmel_sam0_dt.h b/soc/atmel/sam0/common/atmel_sam0_dt.h index f803596c872ac..2c86808a9a1e3 100644 --- a/soc/atmel/sam0/common/atmel_sam0_dt.h +++ b/soc/atmel/sam0/common/atmel_sam0_dt.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020 Linaro Ltd. - * Copyright (c) 2021 Gerson Fernando Budke + * Copyright (c) 2020, Linaro Ltd. + * Copyright (c) 2021-2024, Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,12 +12,30 @@ #ifndef _ATMEL_SAM0_DT_H_ #define _ATMEL_SAM0_DT_H_ -/* Helper macro to get MCLK register address for corresponding - * that has corresponding clock enable bit. +/* clang-format off */ + +#define ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, cell) \ + (volatile uint32_t *) \ + (DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, cell)) + \ + DT_INST_CLOCKS_CELL_BY_NAME(n, cell, offset)) + +#define ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, name, cell) \ + BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, name, cell)) + +/* Helper macro to get register address that control peripheral clock + * enable bit. */ -#define MCLK_MASK_DT_INT_REG_ADDR(n) \ - (DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, mclk)) + \ - DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, offset)) +#define ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, pm))) + +/* Helper macro to get peripheral clock bit mask. + */ +#define ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, cell) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, mclk, cell)), \ + (ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, pm, cell))) /* Helper macros for use with ATMEL SAM0 DMAC controller * return 0xff as default value if there is no 'dmas' property @@ -48,4 +66,340 @@ #define ATMEL_SAM0_DT_CPU_CLK_FREQ_HZ \ DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) +/** + * @brief Test if a node has a atmel,assigned-clocks phandle-array property at + * a given index. + * + * This expands to 1 if the given index is valid atmel,assigned-clocks property + * phandle-array index. Otherwise, it expands to 0. + * + * Example devicetree fragment: + * + * n1: node-1 { + * atmel,assigned-clocks = <...>, <...>; + * }; + * + * n2: node-2 { + * atmel,assigned-clocks = <...>; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 0) // 1 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 1) // 1 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 2) // 0 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_NODELABEL(n2), 1) // 0 + * + * @param node_id node identifier; may or may not have any atmel,assigned-clocks + * property + * @param idx index of a atmel,assigned-clocks property phandle-array whose + * existence to check + * @return 1 if the index exists, 0 otherwise + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(node_id, idx) \ + DT_PROP_HAS_IDX(node_id, atmel_assigned_clocks, idx) + +/** + * @brief Test if a node has a clock-names array property holds a given name + * + * This expands to 1 if the name is available as atmel,assigned-clocks-name array + * property cell. Otherwise, it expands to 0. + * + * Example devicetree fragment: + * + * n1: node-1 { + * atmel,assigned-clocks = <...>, <...>; + * atmel,assigned-clock-names = "alpha", "beta"; + * }; + * + * n2: node-2 { + * atmel,assigned-clocks = <...>; + * atmel,assigned-clock-names = "alpha"; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(DT_NODELABEL(n1), alpha) // 1 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(DT_NODELABEL(n1), beta) // 1 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(DT_NODELABEL(n2), beta) // 0 + * + * @param node_id node identifier; may or may not have any clock-names property. + * @param name lowercase-and-underscores clock-names cell value name to check + * @return 1 if the atmel,assigned-clock name exists, 0 otherwise + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(node_id, name) \ + DT_PROP_HAS_NAME(node_id, atmel_assigned_clocks, name) + +/** + * @brief Get the number of elements in a atmel,assigned-clocks property + * + * Example devicetree fragment: + * + * n1: node-1 { + * atmel,assigned-clocks = <&foo>, <&bar>; + * }; + * + * n2: node-2 { + * atmel,assigned-clocks = <&foo>; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(DT_NODELABEL(n1)) // 2 + * ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(DT_NODELABEL(n2)) // 1 + * + * @param node_id node identifier with a atmel,assigned-clocks property + * @return number of elements in the property + */ +#define ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(node_id) \ + DT_PROP_LEN(node_id, atmel_assigned_clocks) + + +/** + * @brief Get the node identifier for the controller phandle from a + * "atmel,assigned-clocks" phandle-array property at an index + * + * Example devicetree fragment: + * + * clk1: clock-controller@... { ... }; + * + * clk2: clock-controller@... { ... }; + * + * n: node { + * atmel,assigned-clocks = <&clk1 10 20>, <&clk2 30 40>; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(DT_NODELABEL(n), 0)) // DT_NODELABEL(clk1) + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(DT_NODELABEL(n), 1)) // DT_NODELABEL(clk2) + * + * @param node_id node identifier + * @param idx logical index into "atmel,assigned-clocks" + * @return the node identifier for the clock controller referenced at index "idx" + * @see DT_PHANDLE_BY_IDX() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(node_id, idx) \ + DT_PHANDLE_BY_IDX(node_id, atmel_assigned_clocks, idx) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(node_id, 0) + * @param node_id node identifier + * @return a node identifier for the atmel,assigned-clocks controller at index 0 + * in "atmel,assigned-clocks" + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR(node_id) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(node_id, 0) + +/** + * @brief Get the node identifier for the controller phandle from a + * atmel,assigned-clocks phandle-array property by name + * + * Example devicetree fragment: + * + * clk1: clock-controller@... { ... }; + * + * clk2: clock-controller@... { ... }; + * + * n: node { + * atmel,assigned-clocks = <&clk1 10 20>, <&clk2 30 40>; + * atmel,assigned-clock-names = "alpha", "beta"; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_NAME(DT_NODELABEL(n), beta) // DT_NODELABEL(clk2) + * + * @param node_id node identifier + * @param name lowercase-and-underscores name of a atmel,assigned-clocks element + * as defined by the node's clock-names property + * @return the node identifier for the clock controller referenced by name + * @see DT_PHANDLE_BY_NAME() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_NAME(node_id, name) \ + DT_PHANDLE_BY_NAME(node_id, atmel_assigned_clocks, name) + +/** + * @brief Get a atmel,assigned-clock specifier's cell value at an index + * + * Example devicetree fragment: + * + * clk1: clock-controller@... { + * compatible = "vnd,clock"; + * #atmel,assigned-clock-cells = < 2 >; + * }; + * + * n: node { + * atmel,assigned-clocks = < &clk1 10 20 >, < &clk1 30 40 >; + * }; + * + * Bindings fragment for the vnd,clock compatible: + * + * atmel,assigned-clock-cells: + * - bus + * - bits + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(DT_NODELABEL(n), 0, bus) // 10 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(DT_NODELABEL(n), 1, bits) // 40 + * + * @param node_id node identifier for a node with a atmel,assigned-clocks property + * @param idx logical index into atmel,assigned-clocks property + * @param cell lowercase-and-underscores cell name + * @return the cell value at index "idx" + * @see DT_PHA_BY_IDX() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(node_id, idx, cell) \ + DT_PHA_BY_IDX(node_id, atmel_assigned_clocks, idx, cell) + +/** + * @brief Get a atmel,assigned-clock specifier's cell value by name + * + * Example devicetree fragment: + * + * clk1: clock-controller@... { + * compatible = "vnd,clock"; + * #atmel,assigned-clock-cells = < 2 >; + * }; + * + * n: node { + * atmel,assigned-clocks = < &clk1 10 20 >, < &clk1 30 40 >; + * clock-names = "alpha", "beta"; + * }; + * + * Bindings fragment for the vnd,clock compatible: + * + * atmel,assigned-clock-cells: + * - bus + * - bits + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME(DT_NODELABEL(n), alpha, bus) // 10 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME(DT_NODELABEL(n), beta, bits) // 40 + * + * @param node_id node identifier for a node with a atmel,assigned-clocks property + * @param name lowercase-and-underscores name of a atmel,assigned-clocks element + * as defined by the node's clock-names property + * @param cell lowercase-and-underscores cell name + * @return the cell value in the specifier at the named element + * @see DT_PHA_BY_NAME() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME(node_id, name, cell) \ + DT_PHA_BY_NAME(node_id, atmel_assigned_clocks, name, cell) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(node_id, 0, cell) + * @param node_id node identifier for a node with a atmel,assigned-clocks property + * @param cell lowercase-and-underscores cell name + * @return the cell value at index 0 + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL(node_id, cell) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(node_id, 0, cell) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_DRV_INST(inst), idx) + * @param inst DT_DRV_COMPAT instance number; may or may not have any + * atmel,assigned-clocks property + * @param idx index of a atmel,assigned-clocks property phandle-array whose existence + * to check + * @return 1 if the index exists, 0 otherwise + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_HAS_IDX(inst, idx) \ + DT_ASSIGNED_CLOCKS_HAS_IDX(DT_DRV_INST(inst), idx) + +/** + * @brief Equivalent to DT_CLOCK_HAS_NAME(DT_DRV_INST(inst), name) + * @param inst DT_DRV_COMPAT instance number; may or may not have any + * atmel,clock-names property. + * @param name lowercase-and-underscores clock-names cell value name to check + * @return 1 if the atmel,assigned-clock name exists, 0 otherwise + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_HAS_NAME(inst, name) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(DT_DRV_INST(inst), name) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(DT_DRV_INST(inst)) + * @param inst instance number + * @return number of elements in the atmel,assigned-clocks property + */ +#define ATMEL_SAM0_DT_INST_NUM_ASSIGNED_CLOCKS(inst) \ + ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(DT_DRV_INST(inst)) + +/** + * @brief Get the node identifier for the controller phandle from a + * "atmel,assigned-clocks" phandle-array property at an index + * + * @param inst instance number + * @param idx logical index into "atmel,assigned-clocks" + * @return the node identifier for the clock controller referenced at + * index "idx" + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR_BY_IDX(inst, idx) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(DT_DRV_INST(inst), idx) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR_BY_IDX(inst, 0) + * @param inst instance number + * @return a node identifier for the atmel,assigned-clocks controller at index 0 + * in "atmel,assigned-clocks" + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR(inst) \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR_BY_IDX(inst, 0) + +/** + * @brief Get the node identifier for the controller phandle from a + * atmel,assigned-clocks phandle-array property by name + * + * @param inst instance number + * @param name lowercase-and-underscores name of a atmel,assigned-clocks element + * as defined by the node's atmel,assigned-clock-names property + * @return the node identifier for the clock controller referenced by + * the named element + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_NAME() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR_BY_NAME(inst, name) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_NAME(DT_DRV_INST(inst), name) + +/** + * @brief Get a DT_DRV_COMPAT instance's atmel,assigned-clock specifier's cell + * value at an index + * @param inst DT_DRV_COMPAT instance number + * @param idx logical index into atmel,assigned-clocks property + * @param cell lowercase-and-underscores cell name + * @return the cell value at index "idx" + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_IDX(inst, idx, cell) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(DT_DRV_INST(inst), idx, cell) + +/** + * @brief Get a DT_DRV_COMPAT instance's atmel,assigned-clock specifier's cell + * value by name + * @param inst DT_DRV_COMPAT instance number + * @param name lowercase-and-underscores name of a atmel,assigned-clocks element + * as defined by the node's atmel,assigned-clock-names property + * @param cell lowercase-and-underscores cell name + * @return the cell value in the specifier at the named element + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME(inst, name, cell) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME(DT_DRV_INST(inst), name, cell) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_IDX(inst, 0, cell) + * @param inst DT_DRV_COMPAT instance number + * @param cell lowercase-and-underscores cell name + * @return the value of the cell inside the specifier at index 0 + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL(inst, cell) \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_IDX(inst, 0, cell) + +/* clang-format on */ + #endif /* _ATMEL_SAM0_SOC_DT_H_ */ diff --git a/soc/atmel/sam0/common/soc_samc2x.c b/soc/atmel/sam0/common/soc_samc2x.c index 1581b62eef2e7..bfcb111b0c2c6 100644 --- a/soc/atmel/sam0/common/soc_samc2x.c +++ b/soc/atmel/sam0/common/soc_samc2x.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2022 Kamil Serwus - * Copyright (c) 2023 Gerson Fernando Budke + * Copyright (c) 2023-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,11 +10,19 @@ * @brief Atmel SAMC MCU series initialization code */ +/* GCLK Gen 0 -> GCLK_MAIN @ OSC48M + * GCLK Gen 2 -> WDT @ reserved + * GCLK Gen 0 -> ADC @ OSC48M + * GCLK Gen 4 -> RTC @ reserved + */ + #include #include #include #include +/* clang-format off */ + static void flash_waitstates_init(void) { /* Two wait state at 48 MHz. */ @@ -50,3 +58,5 @@ void soc_reset_hook(void) mclk_init(); gclks_init(); } + +/* clang-format on */ diff --git a/soc/atmel/sam0/common/soc_samd2x.c b/soc/atmel/sam0/common/soc_samd2x.c index f915459a57662..f332100bf644f 100644 --- a/soc/atmel/sam0/common/soc_samd2x.c +++ b/soc/atmel/sam0/common/soc_samd2x.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2017 Google LLC. * Copyright (c) 2023 Ionut Catalin Pavel - * Copyright (c) 2023 Gerson Fernando Budke + * Copyright (c) 2023-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ * GCLK Gen 1 -> DFLL48M (variable) * GCLK Gen 2 -> WDT @ 32768 Hz * GCLK Gen 3 -> ADC @ 8 MHz + * GCLK Gen 4 -> RTC @ xtal 32768 Hz */ #include @@ -29,6 +30,8 @@ #include #include +/* clang-format off */ + /** * Fix different naming conventions for SAMD20 */ @@ -38,6 +41,23 @@ #define FUSES_OSC32K_CAL_Msk FUSES_OSC32KCAL_Msk #endif +static void gclk_connect(uint8_t gclk, uint32_t src, uint32_t div, uint32_t flags) +{ + GCLK->GENDIV.reg = GCLK_GENDIV_ID(gclk) + | GCLK_GENDIV_DIV(div); + + while (GCLK->STATUS.bit.SYNCBUSY) { + } + + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk) + | GCLK_GENCTRL_GENEN + | src + | flags; + + while (GCLK->STATUS.bit.SYNCBUSY) { + } +} + static inline void osc8m_init(void) { uint32_t reg; @@ -57,19 +77,7 @@ static inline void osc8m_init(void) /* Use 8Mhz clock as gclk_main to allow switching between clocks * when using bootloaders */ - GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) - | GCLK_GENDIV_DIV(0); - - while (GCLK->STATUS.bit.SYNCBUSY) { - } - - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(0) - | GCLK_GENCTRL_SRC_OSC8M - | GCLK_GENCTRL_IDC - | GCLK_GENCTRL_GENEN; - - while (GCLK->STATUS.bit.SYNCBUSY) { - } + gclk_connect(0, GCLK_GENCTRL_SRC_OSC8M, 0, 0); } #if !CONFIG_SOC_ATMEL_SAMD_OSC32K || CONFIG_SOC_ATMEL_SAMD_DEFAULT_AS_MAIN @@ -149,28 +157,17 @@ static inline void dfll48m_init(void) { uint32_t fcal, ccal; - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(1) + gclk_connect(1, #if CONFIG_SOC_ATMEL_SAMD_OSC32K_AS_MAIN - | GCLK_GENCTRL_SRC_OSC32K + GCLK_GENCTRL_SRC_OSC32K, #elif CONFIG_SOC_ATMEL_SAMD_XOSC32K_AS_MAIN - | GCLK_GENCTRL_SRC_XOSC32K + GCLK_GENCTRL_SRC_XOSC32K, #elif CONFIG_SOC_ATMEL_SAMD_OSC8M_AS_MAIN - | GCLK_GENCTRL_SRC_OSC8M + GCLK_GENCTRL_SRC_OSC8M, #elif CONFIG_SOC_ATMEL_SAMD_XOSC_AS_MAIN - | GCLK_GENCTRL_SRC_XOSC + GCLK_GENCTRL_SRC_XOSC, #endif - | GCLK_GENCTRL_IDC - | GCLK_GENCTRL_RUNSTDBY - | GCLK_GENCTRL_GENEN; - - while (GCLK->STATUS.bit.SYNCBUSY) { - } - - GCLK->GENDIV.reg = GCLK_GENDIV_ID(1) - | GCLK_GENDIV_DIV(SOC_ATMEL_SAM0_GCLK1_DIV); - - while (GCLK->STATUS.bit.SYNCBUSY) { - } + SOC_ATMEL_SAM0_GCLK1_DIV, GCLK_GENCTRL_RUNSTDBY); /* Route multiplexer 0 to DFLL48M */ GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(0) @@ -222,19 +219,7 @@ static inline void flash_waitstates_init(void) #else static inline void gclk_main_configure(void) { - GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) - | GCLK_GENDIV_DIV(SOC_ATMEL_SAM0_GCLK0_DIV); - - while (GCLK->STATUS.bit.SYNCBUSY) { - } - - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(0) - | GCLK_GENCTRL_SRC_DFLL48M - | GCLK_GENCTRL_IDC - | GCLK_GENCTRL_GENEN; - - while (GCLK->STATUS.bit.SYNCBUSY) { - } + gclk_connect(0, GCLK_GENCTRL_SRC_DFLL48M, SOC_ATMEL_SAM0_GCLK0_DIV, 0); } #endif @@ -243,19 +228,16 @@ static inline void gclk_main_configure(void) #else static inline void gclk_adc_configure(void) { - GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) - | GCLK_GENDIV_DIV(SOC_ATMEL_SAM0_GCLK3_DIV); - - while (GCLK->STATUS.bit.SYNCBUSY) { - } - - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(3) - | GCLK_GENCTRL_SRC_DFLL48M - | GCLK_GENCTRL_IDC - | GCLK_GENCTRL_GENEN; + gclk_connect(3, GCLK_GENCTRL_SRC_DFLL48M, SOC_ATMEL_SAM0_GCLK3_DIV, 0); +} +#endif - while (GCLK->STATUS.bit.SYNCBUSY) { - } +#if !CONFIG_RTC_ATMEL_SAM0 || CONFIG_SOC_ATMEL_SAMD_DEFAULT_AS_MAIN +#define gclk_rtc_configure() +#else +static inline void gclk_rtc_configure(void) +{ + gclk_connect(4, GCLK_GENCTRL_SRC_XOSC32K, CONFIG_SOC_ATMEL_SAMD_XOSC32K_PRESCALER, 0); } #endif @@ -264,16 +246,7 @@ static inline void gclk_adc_configure(void) #else static inline void gclk_wdt_configure(void) { - GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) - | GCLK_GENDIV_DIV(4); - - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) - | GCLK_GENCTRL_GENEN - | GCLK_GENCTRL_SRC_OSCULP32K - | GCLK_GENCTRL_DIVSEL; - - while (GCLK->STATUS.bit.SYNCBUSY) { - } + gclk_connect(2, GCLK_GENCTRL_SRC_OSCULP32K, 4, GCLK_GENCTRL_DIVSEL); } #endif @@ -296,6 +269,9 @@ void soc_reset_hook(void) flash_waitstates_init(); gclk_main_configure(); gclk_adc_configure(); + gclk_rtc_configure(); gclk_wdt_configure(); osc8m_disable(); } + +/* clang-format on */ diff --git a/soc/atmel/sam0/common/soc_samd5x.c b/soc/atmel/sam0/common/soc_samd5x.c index f9f337f0f3b2f..77ac12e1d1320 100644 --- a/soc/atmel/sam0/common/soc_samd5x.c +++ b/soc/atmel/sam0/common/soc_samd5x.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2019 ML!PA Consulting GmbH - * Copyright (c) 2023 Gerson Fernando Budke + * Copyright (c) 2023-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,25 +10,57 @@ * @brief Atmel SAMD MCU series initialization code */ +/* The CPU clock will be configured to the DT requested value, + * and run via DFLL48M. + * + * Reference -> GCLK Gen 1 -> DFLL48M -> GCLK Gen 0 -> GCLK_MAIN + * + * GCLK Gen 0 -> GCLK_MAIN @ DPLL0 + * GCLK Gen 1 -> DFLL48M @ 32768 Hz + * GCLK Gen 2 -> USB @ DFLL48M + * GCLK Gen 3 -> ADC @ reserved + * GCLK Gen 4 -> RTC @ xtal 32768 Hz + */ + #include #include #include #include +/* clang-format off */ + #define SAM0_DFLL_FREQ_HZ (48000000U) #define SAM0_DPLL_FREQ_MIN_HZ (96000000U) #define SAM0_DPLL_FREQ_MAX_HZ (200000000U) +#define SAM0_XOSC32K_STARTUP_TIME CONFIG_SOC_ATMEL_SAMD5X_XOSC32K_STARTUP -#if CONFIG_SOC_ATMEL_SAMD5X_XOSC32K_AS_MAIN -static void osc32k_init(void) +#if !CONFIG_SOC_ATMEL_SAMD5X_XOSC32K +#define xosc32k_init() +#else +static inline void xosc32k_init(void) { - OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_XTALEN - | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_RUNSTDBY - | OSC32KCTRL_XOSC32K_STARTUP(0) | OSC32KCTRL_XOSC32K_CGM_XT; + OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE +#if CONFIG_SOC_ATMEL_SAMD5X_XOSC32K_CRYSTAL + | OSC32KCTRL_XOSC32K_XTALEN +#endif +#if CONFIG_SOC_ATMEL_SAMD5X_XOSC32K_GAIN_HS + | OSC32KCTRL_XOSC32K_CGM_HS +#else + | OSC32KCTRL_XOSC32K_CGM_XT +#endif + | OSC32KCTRL_XOSC32K_EN32K + | OSC32KCTRL_XOSC32K_EN1K + | OSC32KCTRL_XOSC32K_RUNSTDBY + | OSC32KCTRL_XOSC32K_STARTUP(SAM0_XOSC32K_STARTUP_TIME); while (!OSC32KCTRL->STATUS.bit.XOSC32KRDY) { } +} +#endif +#if CONFIG_SOC_ATMEL_SAMD5X_XOSC32K_AS_MAIN +static void osc32k_init(void) +{ GCLK->GENCTRL[1].reg = GCLK_GENCTRL_SRC(GCLK_SOURCE_XOSC32K) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN; @@ -127,6 +159,7 @@ void soc_reset_hook(void) CMCC->CTRL.bit.CEN = 0; gclk_reset(); + xosc32k_init(); osc32k_init(); dfll_init(); dpll_init(0, dfll_div * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); @@ -136,4 +169,15 @@ void soc_reset_hook(void) /* connect GCLK2 to 48 MHz DFLL for USB */ gclk_connect(2, GCLK_SOURCE_DFLL48M, 0); + + /* connect GCLK4 to xosc32k for RTC. The output is 1024 Hz*/ + gclk_connect(4, +#if CONFIG_SOC_ATMEL_SAMD5X_XOSC32K + GCLK_SOURCE_XOSC32K, +#else + GCLK_SOURCE_OSCULP32K, +#endif + CONFIG_SOC_ATMEL_SAMD5X_OSC32K_PRESCALER); } + +/* clang-format on */ diff --git a/soc/atmel/sam0/common/soc_saml2x.c b/soc/atmel/sam0/common/soc_saml2x.c index 3dd657a52f225..d65831f785a54 100644 --- a/soc/atmel/sam0/common/soc_saml2x.c +++ b/soc/atmel/sam0/common/soc_saml2x.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2021 Argentum Systems Ltd. - * Copyright (c) 2023 Gerson Fernando Budke + * Copyright (c) 2023-2025 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,8 @@ #include #include +/* clang-format off */ + /* the SAML21 currently operates only in Performance Level 2... sleep * and low-power operation are not currently supported by the BSP * @@ -27,6 +29,7 @@ * GCLK Gen 1 -> DFLL48M (variable) * GCLK Gen 2 -> USB @ 48 MHz * GCLK Gen 3 -> ADC @ 24 MHz (further /2 in the ADC peripheral) + * GCLK Gen 4 -> RTC @ reserved */ static inline void gclk_reset(void) @@ -57,6 +60,7 @@ static inline void osc32k_init(void) | !OSC32KCTRL_OSC32K_ONDEMAND | OSC32KCTRL_OSC32K_RUNSTDBY | OSC32KCTRL_OSC32K_EN32K + | OSC32KCTRL_OSC32K_EN1K | OSC32KCTRL_OSC32K_ENABLE; /* wait for ready */ @@ -75,6 +79,7 @@ static inline void xosc32k_init(void) | !OSC32KCTRL_XOSC32K_ONDEMAND | OSC32KCTRL_XOSC32K_RUNSTDBY | OSC32KCTRL_XOSC32K_EN32K + | OSC32KCTRL_XOSC32K_EN1K #if CONFIG_SOC_ATMEL_SAML_XOSC32K_CRYSTAL | OSC32KCTRL_XOSC32K_XTALEN #endif @@ -266,3 +271,5 @@ void soc_reset_hook(void) gclk_usb_configure(); gclk_adc_configure(); } + +/* clang-format on */ diff --git a/soc/cdns/xtensa_sample_controller/include/xtensa-sample-controller.ld b/soc/cdns/xtensa_sample_controller/include/xtensa-sample-controller.ld index 0e911cbbf3faf..58484df9a0419 100644 --- a/soc/cdns/xtensa_sample_controller/include/xtensa-sample-controller.ld +++ b/soc/cdns/xtensa_sample_controller/include/xtensa-sample-controller.ld @@ -625,6 +625,14 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } .debug_ranges 0 : { *(.debug_ranges) } + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } .xtensa.info 0 : { *(.xtensa.info) } .xt.insn 0 : { diff --git a/soc/common/riscv-privileged/vector.S b/soc/common/riscv-privileged/vector.S index 7230561a340d1..1cd5a18b07cc1 100644 --- a/soc/common/riscv-privileged/vector.S +++ b/soc/common/riscv-privileged/vector.S @@ -27,6 +27,10 @@ SECTION_FUNC(vectors, __start) .option norvc; +#if defined(CONFIG_SOC_RESET_HOOK) + call soc_reset_hook +#endif + #if defined(CONFIG_RISCV_VECTORED_MODE) #if defined(CONFIG_RISCV_HAS_CLIC) diff --git a/soc/espressif/Kconfig b/soc/espressif/Kconfig index 1efa0169ee6e6..7a3b927957c9c 100644 --- a/soc/espressif/Kconfig +++ b/soc/espressif/Kconfig @@ -35,6 +35,12 @@ endmenu menu "RTC Clock Config" +config RESERVE_RTC_MEM + int + default 0 + help + This option reserves an area in RTC FAST memory. + config RTC_CLK_CAL_CYCLES int "Number of cycles for RTC_SLOW_CLK calibration" default 3000 diff --git a/soc/espressif/common/CMakeLists.txt b/soc/espressif/common/CMakeLists.txt index d5e0a563412bc..a8d85bdc33525 100644 --- a/soc/espressif/common/CMakeLists.txt +++ b/soc/espressif/common/CMakeLists.txt @@ -4,6 +4,80 @@ zephyr_include_directories(include) if(NOT CONFIG_MCUBOOT AND NOT CONFIG_SOC_ESP32_APPCPU AND NOT CONFIG_SOC_ESP32S3_APPCPU) - zephyr_sources_ifdef(CONFIG_ESP_SPIRAM psram.c) - zephyr_sources_ifdef(CONFIG_ESP_HEAP_RUNTIME esp_heap_runtime.c) + zephyr_sources_ifdef(CONFIG_ESP_SPIRAM esp_psram.c) +endif() + +# Get flash size to use in esptool as string +math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") + +# Get UART baudrate from DT +dt_chosen(dts_shell_uart PROPERTY "zephyr,shell-uart") +if(${dts_shell_uart}) + dt_prop(monitor_baud PATH ${dts_shell_uart} PROPERTY "current-speed") +endif() + +message("-- Espressif HAL path: ${ESP_IDF_PATH}") + +if(CONFIG_ESP_SIMPLE_BOOT OR CONFIG_MCUBOOT) + if(CONFIG_BUILD_OUTPUT_BIN) + set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) + message("-- Use the esptool.py: ${ESPTOOL_PY}") + + set(ELF2IMAGE_ARG "") + if(NOT CONFIG_MCUBOOT) + set(ELF2IMAGE_ARG "--ram-only-header") + endif() + + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} + ARGS --chip ${CONFIG_SOC} elf2image ${ELF2IMAGE_ARG} + --flash_mode dio + --flash_freq ${CONFIG_ESPTOOLPY_FLASHFREQ} + --flash_size ${esptoolpy_flashsize}MB + -o ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME} + ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME}) + endif() +endif() + +set_property(TARGET bintools PROPERTY disassembly_flag_inline_source) + +# Select the image origin depending on the boot configuration +if(CONFIG_SOC_ESP32_APPCPU OR CONFIG_SOC_ESP32S3_APPCPU) + dt_nodelabel(dts_partition_path NODELABEL "slot0_appcpu_partition") +elseif(CONFIG_MCUBOOT OR CONFIG_ESP_SIMPLE_BOOT) + dt_nodelabel(dts_partition_path NODELABEL "boot_partition") +else() + dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") +endif() + +dt_reg_addr(image_off PATH ${dts_partition_path}) +board_finalize_runner_args(esp32 "--esp-app-address=${image_off}") +board_finalize_runner_args(esp32 "--esp-flash-size=${esptoolpy_flashsize}MB") +board_finalize_runner_args(esp32 "--esp-flash-freq=${CONFIG_ESPTOOLPY_FLASHFREQ}") +board_finalize_runner_args(esp32 "--esp-flash-mode=${CONFIG_ESPTOOLPY_FLASHMODE}") +board_finalize_runner_args(esp32 "--esp-monitor-baud=${monitor_baud}") + +message("-- Image partition ${dts_partition_path}") + +# Look for cross references between bootloader sections +if(CONFIG_MCUBOOT) + message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND + ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/ci/check_callgraph.py + ARGS + --rtl-dirs ${CMAKE_BINARY_DIR}/zephyr + --elf-file ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME} + find-refs + --from-section='.iram0.loader_text' + --to-section='.iram0.text' + --exit-code) +endif() + +if(CONFIG_MCUBOOT) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/../${CONFIG_SOC}/mcuboot.ld CACHE INTERNAL "") +elseif(CONFIG_SOC_ESP32_APPCPU OR CONFIG_SOC_ESP32S3_APPCPU) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/../${CONFIG_SOC}/default_appcpu.ld CACHE INTERNAL "") +else() + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/../${CONFIG_SOC}/default.ld CACHE INTERNAL "") endif() diff --git a/soc/espressif/common/Kconfig b/soc/espressif/common/Kconfig index ffeac4ab04535..555085435c3e2 100644 --- a/soc/espressif/common/Kconfig +++ b/soc/espressif/common/Kconfig @@ -24,14 +24,6 @@ config ESP_SIMPLE_BOOT Please note that this method brings the system up with all memories set-up, but all other features, such as secure boot OTA or slots management are not available. -config ESP_HEAP_RUNTIME - bool - default y - help - Enabling this will allocate SRAM area starting from the last linked data at the symbolic `_end`, - ending at the last memory location that can be safely accessed (depending on a boot mode). - This is a memory pool used in runtime to create a new heap memory. - config ESP32_TIMER_TASK_STACK_SIZE int "Stack size of the high resolution ESP Timer" default 4096 @@ -56,8 +48,20 @@ config ESP32_PHY_MAX_TX_POWER Set maximum transmit power for Wi-Fi radio. Actual transmit power for high data rates may be lower than this setting. +config ESP32_SW_COEXIST_ENABLE + bool "Software controls Wi-Fi/Bluetooth coexistence" + default y if (BT_ESP32 && WIFI_ESP32) + help + If enabled, Wi-Fi & Bluetooth coexistence is controlled by software rather than hardware. + Recommended for heavy traffic scenarios. Both coexistence configuration options are + automatically managed, no user intervention is required. + If only Bluetooth is used, it is recommended to disable this option to reduce binary file + size. + endif +rsource "Kconfig.amp" +rsource "Kconfig.console" rsource "Kconfig.spiram" rsource "Kconfig.esptool" rsource "Kconfig.flash" diff --git a/soc/espressif/common/Kconfig.amp b/soc/espressif/common/Kconfig.amp new file mode 100644 index 0000000000000..cce7c86692872 --- /dev/null +++ b/soc/espressif/common/Kconfig.amp @@ -0,0 +1,38 @@ +# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_ENABLE_APPCPU + bool + default y + depends on (IPM || MBOX) + depends on SOC_SERIES_ESP32 || SOC_SERIES_ESP32S3 + help + This hidden configuration lets PROCPU core to map and start APPCPU whenever IPM is enabled. + +menu "Espressif AMP Config" + +config ESP_APPCPU_IRAM_SIZE + hex "ESP32* APPCPU IRAM size" + default 0x10000 + help + Defines APPCPU IRAM area size in bytes. + +config ESP_APPCPU_DRAM_SIZE + hex "ESP32* APPCPU DRAM size" + default 0x10000 + help + Defines APPCPU DRAM area size in bytes. + +config ESP_APPCPU_IROM_SIZE + hex "ESP32* APPCPU IROM size" + default 0x100000 + help + Defines APPCPU IROM area size in bytes. + +config ESP_APPCPU_DROM_SIZE + hex "ESP32* APPCPU DRAM size" + default 0x100000 + help + Defines APPCPU DROM area size in bytes. + +endmenu # AMP config diff --git a/soc/espressif/common/Kconfig.console b/soc/espressif/common/Kconfig.console new file mode 100644 index 0000000000000..b6c9b9f0343fc --- /dev/null +++ b/soc/espressif/common/Kconfig.console @@ -0,0 +1,79 @@ +# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_ESPRESSIF_ESP32 + +DT_CHOSEN_Z_CONSOLE := zephyr,console + +if !$(dt_chosen_enabled,$(DT_CHOSEN_Z_CONSOLE)) + +config ESP_CONSOLE_UART_NUM + int + default -1 + +config ESP_CONSOLE_UART_BAUDRATE + int + default 0 + +endif # !$(dt_chosen_enabled,$(DT_CHOSEN_Z_CONSOLE)) + +if $(dt_chosen_enabled,$(DT_CHOSEN_Z_CONSOLE)) + +if $(dt_nodelabel_enabled,uart0) + ESP32_UART0_NODE_PATH := $(dt_nodelabel_path,uart0) + ESP32_UART0_CURR_SPEED := $(dt_node_int_prop_int,$(ESP32_UART0_NODE_PATH),current-speed) +endif # $(dt_nodelabel_enabled,uart0) + +if $(dt_nodelabel_enabled,uart1) + ESP32_UART1_NODE_PATH := $(dt_nodelabel_path,uart1) + ESP32_UART1_CURR_SPEED := $(dt_node_int_prop_int,$(ESP32_UART1_NODE_PATH),current-speed) +endif # $(dt_nodelabel_enabled,uart1) + +if $(dt_nodelabel_enabled,uart2) + ESP32_UART2_NODE_PATH := $(dt_nodelabel_path,uart2) + ESP32_UART2_CURR_SPEED := $(dt_node_int_prop_int,$(ESP32_UART2_NODE_PATH),current-speed) +endif # $(dt_nodelabel_enabled,uart2) + +if $(dt_nodelabel_enabled,usb_serial) + ESP32_USB_SERIAL_CURR_SPEED := 1 + +config ESP_ROM_USB_SERIAL_DEVICE_NUM + int + default 4 if SOC_SERIES_ESP32S3 + default 3 + +endif # $(dt_nodelabel_enabled,usb_serial) + +config ESP_CONSOLE_UART + bool + default y if $(dt_nodelabel_enabled,uart0) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart0) || \ + $(dt_nodelabel_enabled,uart1) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart1) || \ + $(dt_nodelabel_enabled,uart2) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart2) + +config ESP_CONSOLE_USB_SERIAL_JTAG + bool + default y if $(dt_nodelabel_enabled,usb_serial) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,usb_serial) + +config ESP_CONSOLE_UART_NUM + int + default 0 if $(dt_nodelabel_enabled,uart0) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart0) + default 1 if $(dt_nodelabel_enabled,uart1) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart1) + default 2 if $(dt_nodelabel_enabled,uart2) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart2) + default ESP_ROM_USB_SERIAL_DEVICE_NUM if $(dt_nodelabel_enabled,usb_serial) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,usb_serial) + default -1 + +config ESP_CONSOLE_UART_BAUDRATE + int + default $(ESP32_UART0_CURR_SPEED) if $(dt_nodelabel_enabled,uart0) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart0) + default $(ESP32_UART1_CURR_SPEED) if $(dt_nodelabel_enabled,uart1) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart1) + default $(ESP32_UART2_CURR_SPEED) if $(dt_nodelabel_enabled,uart2) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,uart2) + default $(ESP32_USB_SERIAL_CURR_SPEED) if $(dt_nodelabel_enabled,usb_serial) && $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CONSOLE)) = $(dt_nodelabel_reg_addr_hex,usb_serial) + default 0 + +config ESP_CONSOLE + bool + default y if ESP_CONSOLE_UART || ESP_CONSOLE_USB_SERIAL_JTAG + +endif # $(dt_chosen_enabled,$(DT_CHOSEN_Z_CONSOLE)) + +endif # SOC_FAMILY_ESPRESSIF_ESP32 diff --git a/soc/espressif/common/Kconfig.spiram b/soc/espressif/common/Kconfig.spiram index 94dcf9a167629..1c209839a7a27 100644 --- a/soc/espressif/common/Kconfig.spiram +++ b/soc/espressif/common/Kconfig.spiram @@ -15,14 +15,6 @@ config ESP_SPIRAM menu "SPI RAM config" depends on ESP_SPIRAM -config ESP_HEAP_SEARCH_ALL_REGIONS - bool "Search for all available heap regions" - default y - help - This configuration enables searching all available heap - regions. If the region of desired capability is exhausted, - memory will be allocated from other available region. - config ESP_SPIRAM_HEAP_SIZE int "Size of SPIRAM heap" default 262134 if SYS_HEAP_SMALL_ONLY diff --git a/soc/espressif/common/esp_heap_runtime.c b/soc/espressif/common/esp_heap_runtime.c deleted file mode 100644 index 210e714c7923d..0000000000000 --- a/soc/espressif/common/esp_heap_runtime.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "esp_log.h" - -#define TAG "heap_runtime" - -/* ESP dynamic pool heap */ -extern unsigned int z_mapped_end; -extern unsigned int _heap_sentry; -static void *esp_heap_runtime_init_mem = &z_mapped_end; - -#define ESP_HEAP_RUNTIME_MAX_SIZE ((uintptr_t)&_heap_sentry - (uintptr_t)&z_mapped_end) - -static struct k_heap esp_heap_runtime; - -static int esp_heap_runtime_init(void) -{ - ESP_EARLY_LOGI(TAG, "ESP heap runtime init at 0x%x size %d kB.\n", - esp_heap_runtime_init_mem, ESP_HEAP_RUNTIME_MAX_SIZE / 1024); - - k_heap_init(&esp_heap_runtime, esp_heap_runtime_init_mem, ESP_HEAP_RUNTIME_MAX_SIZE); - -#if defined(CONFIG_WIFI_ESP32) && defined(CONFIG_BT_ESP32) - assert(ESP_HEAP_RUNTIME_MAX_SIZE > 65535); -#elif defined(CONFIG_WIFI_ESP32) - assert(ESP_HEAP_RUNTIME_MAX_SIZE > 51200); -#elif defined(CONFIG_BT_ESP32) - assert(ESP_HEAP_RUNTIME_MAX_SIZE > 40960); -#endif - - return 0; -} - -void *esp_heap_runtime_malloc(size_t size) -{ - return k_heap_alloc(&esp_heap_runtime, size, K_NO_WAIT); -} - -void *esp_heap_runtime_calloc(size_t n, size_t size) -{ - size_t sz; - - if (__builtin_mul_overflow(n, size, &sz)) { - return NULL; - } - void *ptr = k_heap_alloc(&esp_heap_runtime, sz, K_NO_WAIT); - - if (ptr) { - memset(ptr, 0, sz); - } - - return ptr; -} - -void *esp_heap_runtime_realloc(void *ptr, size_t bytes) -{ - return k_heap_realloc(&esp_heap_runtime, ptr, bytes, K_NO_WAIT); -} - -void esp_heap_runtime_free(void *mem) -{ - k_heap_free(&esp_heap_runtime, mem); -} - -SYS_INIT(esp_heap_runtime_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/soc/espressif/common/psram.c b/soc/espressif/common/esp_psram.c similarity index 100% rename from soc/espressif/common/psram.c rename to soc/espressif/common/esp_psram.c diff --git a/soc/espressif/common/include/esp_heap_runtime.h b/soc/espressif/common/include/esp_heap_runtime.h deleted file mode 100644 index 11f7139b71544..0000000000000 --- a/soc/espressif/common/include/esp_heap_runtime.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @brief Allocate memory from the esp_heap_runtime. - * - * @param size Amount of memory requested (in bytes). - * - * @return Address of the allocated memory if successful; otherwise NULL. - */ -void *esp_heap_runtime_malloc(size_t size); - -/** - * @brief Allocate memory from esp_heap_runtime, array style - * - * @param n Number of elements in the requested array - * @param size Size of each array element (in bytes). - * - * @return Address of the allocated memory if successful; otherwise NULL. - */ -void *esp_heap_runtime_calloc(size_t n, size_t size); - -/** - * @brief Reallocate memory from a esp_heap_runtime - * - * @param ptr Original pointer returned from a previous allocation - * @param bytes Desired size of block to allocate - * - * @return Pointer to memory the caller can now use, or NULL - */ -void *esp_heap_runtime_realloc(void *ptr, size_t bytes); - -/** - * @brief Free memory allocated from esp_heap_runtime. - * - * If @a ptr is NULL, no operation is performed. - * - * @param ptr Pointer to previously allocated memory. - */ -void esp_heap_runtime_free(void *mem); diff --git a/soc/espressif/common/include/hw_init.h b/soc/espressif/common/include/hw_init.h index 1c318fdb8261d..3c7cf807b6d4e 100644 --- a/soc/espressif/common/include/hw_init.h +++ b/soc/espressif/common/include/hw_init.h @@ -7,6 +7,17 @@ #ifndef _SOC_ESPRESSIF_COMMON_HW_INIT_H_ #define _SOC_ESPRESSIF_COMMON_HW_INIT_H_ +struct rom_segments { + unsigned int irom_map_addr; /* Mapped address (VMA) for IROM region */ + unsigned int irom_flash_offset; /* Flash offset (LMA) for IROM region */ + unsigned int irom_size; /* Size of IROM region */ + unsigned int drom_map_addr; /* Mapped address (VMA) for DROM region */ + unsigned int drom_flash_offset; /* Flash offset (LMA) for DROM region */ + unsigned int drom_size; /* Size of DROM region */ +}; + +void map_rom_segments(int core, struct rom_segments *map); + int hardware_init(void); #endif /* _SOC_ESPRESSIF_COMMON_HW_INIT_H_ */ diff --git a/soc/espressif/common/loader.c b/soc/espressif/common/loader.c index cf66bfd356f0b..b3cea05329041 100644 --- a/soc/espressif/common/loader.c +++ b/soc/espressif/common/loader.c @@ -21,9 +21,11 @@ #include #include #include - #include +#include +#include + #if CONFIG_SOC_SERIES_ESP32C6 #include #include @@ -48,21 +50,36 @@ #include "soc_init.h" #include "soc_random.h" +#if defined(CONFIG_SOC_ESP32S3_APPCPU) || defined(CONFIG_SOC_ESP32_APPCPU) +#error "APPCPU does not need this file!" +#endif + #define TAG "boot" #define CHECKSUM_ALIGN 16 -#define IS_PADD(addr) (addr == 0) -#define IS_DRAM(addr) (addr >= SOC_DRAM_LOW && addr < SOC_DRAM_HIGH) -#define IS_IRAM(addr) (addr >= SOC_IRAM_LOW && addr < SOC_IRAM_HIGH) -#define IS_IROM(addr) (addr >= SOC_IROM_LOW && addr < SOC_IROM_HIGH) -#define IS_DROM(addr) (addr >= SOC_DROM_LOW && addr < SOC_DROM_HIGH) -#define IS_SRAM(addr) (IS_IRAM(addr) || IS_DRAM(addr)) -#define IS_MMAP(addr) (IS_IROM(addr) || IS_DROM(addr)) -#define IS_NONE(addr) \ - (!IS_IROM(addr) && !IS_DROM(addr) && !IS_IRAM(addr) && !IS_DRAM(addr) && !IS_PADD(addr)) +#define IS_PADD(addr) (addr == 0) +#define IS_DRAM(addr) (addr >= SOC_DRAM_LOW && addr < SOC_DRAM_HIGH) +#define IS_IRAM(addr) (addr >= SOC_IRAM_LOW && addr < SOC_IRAM_HIGH) +#define IS_IROM(addr) (addr >= SOC_IROM_LOW && addr < SOC_IROM_HIGH) +#define IS_DROM(addr) (addr >= SOC_DROM_LOW && addr < SOC_DROM_HIGH) +#ifdef SOC_RTC_MEM_SUPPORTED +#define IS_RTC(addr) (addr >= SOC_RTC_DRAM_LOW && addr < SOC_RTC_DRAM_HIGH) +#else +#define IS_RTC(addr) 0 +#endif +#define IS_SRAM(addr) (IS_IRAM(addr) || IS_DRAM(addr)) +#define IS_MMAP(addr) (IS_IROM(addr) || IS_DROM(addr)) +#define IS_NONE(addr) (!IS_IROM(addr) && !IS_DROM(addr) \ + && !IS_IRAM(addr) && !IS_DRAM(addr) && !IS_PADD(addr) && !IS_RTC(addr)) #define HDR_ATTR __attribute__((section(".entry_addr"))) __attribute__((used)) +#if !defined(CONFIG_SOC_ESP32_APPCPU) && !defined(CONFIG_SOC_ESP32S3_APPCPU) +#define PART_OFFSET FIXED_PARTITION_OFFSET(slot0_partition) +#else +#define PART_OFFSET FIXED_PARTITION_OFFSET(slot0_appcpu_partition) +#endif + void __start(void); static HDR_ATTR void (*_entry_point)(void) = &__start; @@ -71,34 +88,28 @@ extern uint32_t _image_irom_start, _image_irom_size, _image_irom_vaddr; extern uint32_t _image_drom_start, _image_drom_size, _image_drom_vaddr; #ifndef CONFIG_MCUBOOT -static uint32_t _app_irom_start = - (FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_irom_start); -static uint32_t _app_irom_size = (uint32_t)&_image_irom_size; -static uint32_t _app_drom_start = - (FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_drom_start); -static uint32_t _app_drom_size = (uint32_t)&_image_drom_size; -#endif - -static uint32_t _app_irom_vaddr = ((uint32_t)&_image_irom_vaddr); -static uint32_t _app_drom_vaddr = ((uint32_t)&_image_drom_vaddr); +extern uint32_t _libc_heap_size; +static uint32_t libc_heap_size = (uint32_t)&_libc_heap_size; -#ifndef CONFIG_BOOTLOADER_MCUBOOT -static int spi_flash_read(uint32_t address, void *buffer, size_t length) -{ - return esp_flash_read(NULL, buffer, address, length); -} -#endif /* CONFIG_BOOTLOADER_MCUBOOT */ +static struct rom_segments map = { + .irom_map_addr = (uint32_t)&_image_irom_vaddr, + .irom_flash_offset = PART_OFFSET + (uint32_t)&_image_irom_start, + .irom_size = (uint32_t)&_image_irom_size, + .drom_map_addr = ((uint32_t)&_image_drom_vaddr), + .drom_flash_offset = PART_OFFSET + (uint32_t)&_image_drom_start, + .drom_size = (uint32_t)&_image_drom_size, +}; -void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t app_drom_size, - uint32_t app_irom_start, uint32_t app_irom_vaddr, uint32_t app_irom_size) +void map_rom_segments(int core, struct rom_segments *map) { - uint32_t app_irom_start_aligned = app_irom_start & MMU_FLASH_MASK; - uint32_t app_irom_vaddr_aligned = app_irom_vaddr & MMU_FLASH_MASK; + uint32_t app_irom_vaddr_align = map->irom_map_addr & MMU_FLASH_MASK; + uint32_t app_irom_start_align = map->irom_flash_offset & MMU_FLASH_MASK; - uint32_t app_drom_start_aligned = app_drom_start & MMU_FLASH_MASK; - uint32_t app_drom_vaddr_aligned = app_drom_vaddr & MMU_FLASH_MASK; + uint32_t app_drom_vaddr_align = map->drom_map_addr & MMU_FLASH_MASK; + uint32_t app_drom_start_align = map->drom_flash_offset & MMU_FLASH_MASK; + /* Traverse segments to fix flash offset changes due to post-build processing */ #ifndef CONFIG_BOOTLOADER_MCUBOOT esp_image_segment_header_t WORD_ALIGNED_ATTR segment_hdr; size_t offset = FIXED_PARTITION_OFFSET(boot_partition); @@ -110,7 +121,8 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t while (segments++ < 16) { - if (spi_flash_read(offset, &segment_hdr, sizeof(esp_image_segment_header_t)) != 0) { + if (esp_rom_flash_read(offset, &segment_hdr, + sizeof(esp_image_segment_header_t), true) != 0) { ESP_EARLY_LOGE(TAG, "Failed to read segment header at %x", offset); abort(); } @@ -122,29 +134,29 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t } ESP_EARLY_LOGI(TAG, "%s: lma 0x%08x vma 0x%08x len 0x%-6x (%u)", - IS_NONE(segment_hdr.load_addr) ? "???" - : IS_MMAP(segment_hdr.load_addr) - ? IS_IROM(segment_hdr.load_addr) ? "IMAP" : "DMAP" - : IS_PADD(segment_hdr.load_addr) ? "padd" - : IS_DRAM(segment_hdr.load_addr) ? "DRAM" - : "IRAM", - offset + sizeof(esp_image_segment_header_t), segment_hdr.load_addr, - segment_hdr.data_len, segment_hdr.data_len); + IS_NONE(segment_hdr.load_addr) ? "???" : + IS_MMAP(segment_hdr.load_addr) ? + IS_IROM(segment_hdr.load_addr) ? "IMAP" : "DMAP" : + IS_DRAM(segment_hdr.load_addr) ? "DRAM" : + IS_RTC(segment_hdr.load_addr) ? "RTC" : "IRAM", + offset + sizeof(esp_image_segment_header_t), + segment_hdr.load_addr, segment_hdr.data_len, segment_hdr.data_len); /* Fix drom and irom produced be the linker, as it could * be invalidated by the elf2image and flash load offset */ - if (segment_hdr.load_addr == _app_drom_vaddr) { - app_drom_start = offset + sizeof(esp_image_segment_header_t); - app_drom_start_aligned = app_drom_start & MMU_FLASH_MASK; + if (segment_hdr.load_addr == map->drom_map_addr) { + map->drom_flash_offset = offset + sizeof(esp_image_segment_header_t); + app_drom_start_align = map->drom_flash_offset & MMU_FLASH_MASK; } - if (segment_hdr.load_addr == _app_irom_vaddr) { - app_irom_start = offset + sizeof(esp_image_segment_header_t); - app_irom_start_aligned = app_irom_start & MMU_FLASH_MASK; + if (segment_hdr.load_addr == map->irom_map_addr) { + map->irom_flash_offset = offset + sizeof(esp_image_segment_header_t); + app_irom_start_align = map->irom_flash_offset & MMU_FLASH_MASK; } - if (IS_SRAM(segment_hdr.load_addr)) { + if (IS_SRAM(segment_hdr.load_addr) || IS_RTC(segment_hdr.load_addr)) { ram_segments++; } + offset += sizeof(esp_image_segment_header_t) + segment_hdr.data_len; if (ram_segments == bootloader_image_hdr.segment_count && !checksum) { @@ -161,8 +173,8 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t #endif /* !CONFIG_BOOTLOADER_MCUBOOT */ #if CONFIG_SOC_SERIES_ESP32 - Cache_Read_Disable(0); - Cache_Flush(0); + Cache_Read_Disable(core); + Cache_Flush(core); #else cache_hal_disable(CACHE_TYPE_ALL); #endif /* CONFIG_SOC_SERIES_ESP32 */ @@ -170,56 +182,56 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t /* Clear the MMU entries that are already set up, * so the new app only has the mappings it creates. */ - mmu_hal_unmap_all(); + if (core == 0) { + mmu_hal_unmap_all(); + } #if CONFIG_SOC_SERIES_ESP32 int rc = 0; uint32_t drom_page_count = - (app_drom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE; + (map->drom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE; - rc |= cache_flash_mmu_set(0, 0, app_drom_vaddr_aligned, app_drom_start_aligned, 64, - drom_page_count); - rc |= cache_flash_mmu_set(1, 0, app_drom_vaddr_aligned, app_drom_start_aligned, 64, + rc |= cache_flash_mmu_set(core, 0, app_drom_vaddr_align, app_drom_start_align, 64, drom_page_count); uint32_t irom_page_count = - (app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE; + (map->irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE; - rc |= cache_flash_mmu_set(0, 0, app_irom_vaddr_aligned, app_irom_start_aligned, 64, - irom_page_count); - rc |= cache_flash_mmu_set(1, 0, app_irom_vaddr_aligned, app_irom_start_aligned, 64, + rc |= cache_flash_mmu_set(core, 0, app_irom_vaddr_align, app_irom_start_align, 64, irom_page_count); if (rc != 0) { - ESP_EARLY_LOGE(TAG, "Failed to setup XIP, aborting"); + ESP_EARLY_LOGE(TAG, "Failed to setup flash cache (e=0x%X). Aborting!", rc); abort(); } #else uint32_t actual_mapped_len = 0; - mmu_hal_map_region(0, MMU_TARGET_FLASH0, app_drom_vaddr_aligned, app_drom_start_aligned, - app_drom_size, &actual_mapped_len); + mmu_hal_map_region(core, MMU_TARGET_FLASH0, app_drom_vaddr_align, app_drom_start_align, + map->drom_size, &actual_mapped_len); - mmu_hal_map_region(0, MMU_TARGET_FLASH0, app_irom_vaddr_aligned, app_irom_start_aligned, - app_irom_size, &actual_mapped_len); + mmu_hal_map_region(core, MMU_TARGET_FLASH0, app_irom_vaddr_align, app_irom_start_align, + map->irom_size, &actual_mapped_len); #endif /* CONFIG_SOC_SERIES_ESP32 */ /* ----------------------Enable corresponding buses---------------- */ - cache_bus_mask_t bus_mask = cache_ll_l1_get_bus(0, app_drom_vaddr_aligned, app_drom_size); + cache_bus_mask_t bus_mask; + + bus_mask = cache_ll_l1_get_bus(core, app_drom_vaddr_align, map->drom_size); + cache_ll_l1_enable_bus(core, bus_mask); + bus_mask = cache_ll_l1_get_bus(core, app_irom_vaddr_align, map->irom_size); + cache_ll_l1_enable_bus(core, bus_mask); - cache_ll_l1_enable_bus(0, bus_mask); - bus_mask = cache_ll_l1_get_bus(0, app_irom_vaddr_aligned, app_irom_size); - cache_ll_l1_enable_bus(0, bus_mask); #if CONFIG_MP_MAX_NUM_CPUS > 1 - bus_mask = cache_ll_l1_get_bus(1, app_drom_vaddr_aligned, app_drom_size); + bus_mask = cache_ll_l1_get_bus(1, app_drom_vaddr_align, map->drom_size); cache_ll_l1_enable_bus(1, bus_mask); - bus_mask = cache_ll_l1_get_bus(1, app_irom_vaddr_aligned, app_irom_size); + bus_mask = cache_ll_l1_get_bus(1, app_irom_vaddr_align, map->irom_size); cache_ll_l1_enable_bus(1, bus_mask); #endif /* ----------------------Enable Cache---------------- */ #if CONFIG_SOC_SERIES_ESP32 /* Application will need to do Cache_Flush(1) and Cache_Read_Enable(1) */ - Cache_Read_Enable(0); + Cache_Read_Enable(core); #else cache_hal_enable(CACHE_TYPE_ALL); #endif /* CONFIG_SOC_SERIES_ESP32 */ @@ -227,25 +239,25 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t #if !defined(CONFIG_SOC_SERIES_ESP32) && !defined(CONFIG_SOC_SERIES_ESP32S2) /* Configure the Cache MMU size for instruction and rodata in flash. */ uint32_t cache_mmu_irom_size = - ((app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) * + ((map->irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) * sizeof(uint32_t); /* Split the cache usage by the segment sizes */ Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size); #endif - /* Show map segments continue using same log format as during MCUboot phase */ - ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "DROM", - app_drom_start_aligned, app_drom_vaddr_aligned, app_drom_size, - app_drom_size); - ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "IROM", - app_irom_start_aligned, app_irom_vaddr_aligned, app_irom_size, - app_irom_size); - esp_rom_uart_tx_wait_idle(0); } +#endif /* !CONFIG_MCUBOOT */ void __start(void) { #ifdef CONFIG_RISCV_GP + + __asm__ __volatile__("la t0, _esp_vector_table\n" + "csrw mtvec, t0\n"); + + /* Disable normal interrupts. */ + csr_read_clear(mstatus, MSTATUS_MIE); + /* Configure the global pointer register * (This should be the first thing startup does, as any other piece of code could be * relaxed by the linker to access something relative to __global_pointer$) @@ -254,29 +266,61 @@ void __start(void) ".option norelax\n" "la gp, __global_pointer$\n" ".option pop"); + + z_bss_zero(); + +#else /* xtensa */ + + extern uint32_t _init_start; + + /* Move the exception vector table to IRAM. */ + __asm__ __volatile__("wsr %0, vecbase" : : "r"(&_init_start)); + + z_bss_zero(); + + __asm__ __volatile__("" : : "g"(&__bss_start) : "memory"); + + /* Disable normal interrupts. */ + __asm__ __volatile__("wsr %0, PS" : : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE)); + + /* Initialize the architecture CPU pointer. Some of the + * initialization code wants a valid arch_current_thread() before + * arch_kernel_init() is invoked. + */ + __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0])); + #endif /* CONFIG_RISCV_GP */ -#ifndef CONFIG_BOOTLOADER_MCUBOOT - /* Init fundamental components */ +/* Initialize hardware only during 1st boot */ +#if defined(CONFIG_MCUBOOT) || defined(CONFIG_ESP_SIMPLE_BOOT) if (hardware_init()) { ESP_EARLY_LOGE(TAG, "HW init failed, aborting"); abort(); } #endif -#if !defined(CONFIG_MCUBOOT) && !defined(CONFIG_SOC_ESP32S3_APPCPU) - map_rom_segments(_app_drom_start, _app_drom_vaddr, _app_drom_size, _app_irom_start, - _app_irom_vaddr, _app_irom_size); -#endif -#ifndef CONFIG_SOC_SERIES_ESP32C2 +#if defined(CONFIG_ESP_SIMPLE_BOOT) || defined(CONFIG_BOOTLOADER_MCUBOOT) + map_rom_segments(0, &map); + + /* Show map segments continue using same log format as during MCUboot phase */ + ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "IROM", + map.irom_flash_offset, map.irom_map_addr, map.irom_size, map.irom_size); + ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "DROM", + map.drom_flash_offset, map.drom_map_addr, map.drom_size, map.drom_size); + esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); + /* Disable RNG entropy source as it was already used */ soc_random_disable(); -#endif /* CONFIG_SOC_SERIES_ESP32C2 */ -#if defined(CONFIG_SOC_SERIES_ESP32S3) || defined(CONFIG_SOC_SERIES_ESP32C3) + /* Disable glitch detection as it can be falsely triggered by EMI interference */ - ESP_EARLY_LOGI(TAG, "Disabling glitch detection"); ana_clock_glitch_reset_config(false); -#endif /* CONFIG_SOC_SERIES_ESP32S2 */ - ESP_EARLY_LOGI(TAG, "Jumping to the main image..."); - __esp_platform_start(); + + ESP_EARLY_LOGI(TAG, "libc heap size %d kB.", libc_heap_size / 1024); + + __esp_platform_app_start(); +#endif /* CONFIG_ESP_SIMPLE_BOOT || CONFIG_BOOTLOADER_MCUBOOT */ + +#if defined(CONFIG_MCUBOOT) + __esp_platform_mcuboot_start(); +#endif } diff --git a/soc/espressif/esp32/CMakeLists.txt b/soc/espressif/esp32/CMakeLists.txt index eb4ba71f56d77..36484e5875ecf 100644 --- a/soc/espressif/esp32/CMakeLists.txt +++ b/soc/espressif/esp32/CMakeLists.txt @@ -1,7 +1,9 @@ # SPDX-License-Identifier: Apache-2.0 if (CONFIG_SOC_ESP32_APPCPU) - zephyr_sources(soc_appcpu.c) + zephyr_sources( + soc_appcpu.c + ) else() zephyr_sources( soc.c @@ -20,82 +22,3 @@ zephyr_library_sources_ifdef(CONFIG_GDBSTUB gdbstub.c) zephyr_library_sources_ifdef(CONFIG_PM power.c) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) - -# get flash size to use in esptool as string -math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") - -# This includes CONFIG_MCUBOOT and CONFIG_ESP_SIMPLE_BOOT -if(NOT CONFIG_BOOTLOADER_MCUBOOT) - - if(CONFIG_BUILD_OUTPUT_BIN) - - set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) - message("esptool path: ${ESPTOOL_PY}") - - set(ELF2IMAGE_ARG "") - if(NOT CONFIG_MCUBOOT) - set(ELF2IMAGE_ARG "--ram-only-header") - endif() - - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} - ARGS --chip esp32 elf2image ${ELF2IMAGE_ARG} - --flash_mode dio --flash_freq 40m - --flash_size ${esptoolpy_flashsize}MB - -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf) - endif() - -endif() - -## When building for APPCPU -if (CONFIG_SOC_ESP32_APPCPU) - - if(CONFIG_BUILD_OUTPUT_BIN) - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/esp_bin2c_array.py - ARGS -i ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.c - -a "esp32_appcpu_fw_array") - endif() - -else() - - set_property(TARGET bintools PROPERTY disassembly_flag_inline_source) - - # get code-partition boot address - dt_nodelabel(dts_partition_path NODELABEL "boot_partition") - dt_reg_addr(boot_off PATH ${dts_partition_path}) - - # get code-partition slot0 address - dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") - dt_reg_addr(img_0_off PATH ${dts_partition_path}) - - if(CONFIG_BOOTLOADER_MCUBOOT) - board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") - else() - board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}") - endif() - -endif() - -if(CONFIG_MCUBOOT) - # search from cross references between bootloader sections - message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND - ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/ci/check_callgraph.py - ARGS - --rtl-dirs ${CMAKE_BINARY_DIR}/zephyr - --elf-file ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf - find-refs --from-section=.iram0.iram_loader --to-section=.iram0.text - --exit-code) -endif() - -if(CONFIG_MCUBOOT) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") -elseif(CONFIG_SOC_ESP32_APPCPU) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default_appcpu.ld CACHE INTERNAL "") -else() - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") -endif() diff --git a/soc/espressif/esp32/Kconfig b/soc/espressif/esp32/Kconfig index 9aeaada682e90..17d67408c0996 100644 --- a/soc/espressif/esp32/Kconfig +++ b/soc/espressif/esp32/Kconfig @@ -15,27 +15,6 @@ config SOC_SERIES_ESP32 if SOC_SERIES_ESP32 -config ESP32_APPCPU_IRAM - hex "ESP32 APPCPU IRAM size" - depends on SOC_ESP32_PROCPU || SOC_ESP32_APPCPU - default 0x20000 - help - Defines APPCPU IRAM area in bytes. - -config ESP32_APPCPU_DRAM - hex "ESP32 APPCPU DRAM size" - depends on SOC_ESP32_PROCPU || SOC_ESP32_APPCPU - default 0x10000 - help - Defines APPCPU DRAM area in bytes. - -config SOC_ENABLE_APPCPU - bool - default y - depends on (IPM || MBOX) && SOC_ESP32_PROCPU - help - This hidden configuration lets PROCPU core to map and start APPCPU whenever IPM is enabled. - config ESP32_BT_RESERVE_DRAM hex "Bluetooth controller reserved RAM region" default 0xdb5c if BT diff --git a/soc/espressif/esp32/Kconfig.defconfig b/soc/espressif/esp32/Kconfig.defconfig index 74f7949e714f3..44a4aa96b4fd8 100644 --- a/soc/espressif/esp32/Kconfig.defconfig +++ b/soc/espressif/esp32/Kconfig.defconfig @@ -9,6 +9,12 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_node_reg_addr_hex,/soc/flash-controller@3ff42000/flash@0) +config BOOTLOADER_MCUBOOT + default y if SOC_ESP32_APPCPU + +config MAIN_STACK_SIZE + default 2048 + if SMP config SCHED_IPI_SUPPORTED diff --git a/soc/espressif/esp32/default.ld b/soc/espressif/esp32/default.ld index 82aaa3699e371..44c74d4ce8912 100644 --- a/soc/espressif/esp32/default.ld +++ b/soc/espressif/esp32/default.ld @@ -12,19 +12,15 @@ #include "memory.h" -/* The "user_iram_end" represents the last DRAM memory location - * that is occupied by the ROM code. Since the "iram_loader_seg" - * - which is the last memory the bootloader runs from - resides - * in the SRAM0 "cache" memory, the "user_iram_end" applies for\ - * all build cases - Simple boot and the MCUboot application. - */ -user_iram_end = SRAM1_DRAM_IRAM_CALC(SRAM1_DRAM_USER_START); - /* User available SRAM memory segments */ -user_iram_seg_org = (SRAM0_IRAM_START + SRAM0_CACHE_SIZE); -user_iram_seg_len = user_iram_end - user_iram_seg_org; -user_dram_seg_org = SRAM2_DRAM_USER_START; -user_dram_seg_len = SRAM2_DRAM_USER_SIZE; +procpu_iram_end = USER_IRAM_END - APPCPU_SRAM_SIZE; +procpu_iram_org = SRAM0_IRAM_START + SRAM0_CACHE_SIZE; +procpu_iram_len = procpu_iram_end - procpu_iram_org; + +procpu_dram_end = SRAM2_DRAM_END; +procpu_dram_org = SRAM2_DRAM_USER_START + CONFIG_ESP32_BT_RESERVE_DRAM; +procpu_dram_len = SRAM2_DRAM_USER_SIZE - CONFIG_ESP32_BT_RESERVE_DRAM; + user_dram_2_seg_org = SRAM1_DRAM_USER_START; user_dram_2_seg_len = SRAM1_USER_SIZE; @@ -36,12 +32,6 @@ user_dram_2_seg_len = SRAM1_USER_SIZE; #define RAMABLE_REGION dram0_0_seg #define ROMABLE_REGION FLASH -#ifndef CONFIG_SOC_ESP32_PROCPU -#define RAMABLE_REGION_1 dram0_1_seg -#else -#define RAMABLE_REGION_1 dram0_0_seg -#endif - #undef GROUP_DATA_LINK_IN #define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion @@ -64,40 +54,34 @@ MEMORY { #ifdef CONFIG_BOOTLOADER_MCUBOOT mcuboot_hdr (R): org = 0x0, len = 0x20 - metadata (R): org = 0x20, len = 0x20 - FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 #else /* Make safety margin in the FLASH memory size so the * (esp_img_header + (n*esp_seg_headers)) would fit */ FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 #endif /* CONFIG_BOOTLOADER_MCUBOOT */ -#ifndef CONFIG_SOC_ESP32_APPCPU - iram0_0_seg(RX): org = user_iram_seg_org, len = user_iram_seg_len -#else - iram0_0_seg(RX): org = user_iram_seg_org, len = 0x8000 -#endif /* CONFIG_SOC_ESP32_APPCPU */ - - dram0_0_seg(RW): org = user_dram_seg_org + CONFIG_ESP32_BT_RESERVE_DRAM, - len = user_dram_seg_len - CONFIG_ESP32_BT_RESERVE_DRAM - -#ifdef CONFIG_SOC_ESP32_PROCPU - /* shared RAM reserved for IPM */ - dram0_shm0_seg(RW): org = 0x3ffe5230, len = 2K - /* shared data reserved for IPM data header */ - dram0_sem0_seg(RW): org = 0x3ffe5a30, len = 8 - /* for AMP builds dram0_1 is reserved for network core */ - dram0_1_seg(RW): org = 0x3ffe5a38, len = 0K -#else - /* skip data for APP CPU initialization usage */ - dram0_1_seg(RW): org = user_dram_2_seg_org, len = user_dram_2_seg_len -#endif /* CONFIG_SOC_ESP32_PROCPU */ + iram0_0_seg(RX): org = procpu_iram_org, len = procpu_iram_len + dram0_0_seg(RW): org = procpu_dram_org, len = procpu_dram_len irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN rtc_iram_seg(RWX): org = 0x400c0000, len = 0x2000 - rtc_slow_seg(RW): org = 0x50000000, len = 0x1000 + rtc_slow_seg(RW): org = 0x50000000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM + rtc_data_seg(RW): org = 0x3ff80000, len = 0x2000 + + /* We reduced the size of rtc_slow_seg by CONFIG_RESERVE_RTC_MEM value. + It reserves the amount of RTC slow memory that we use for this memory segment. + This segment is intended for keeping rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). + The aim of this is to keep data that will not be moved around and have a fixed address. + org = 0x50000000 + 0x2000 - CONFIG_RESERVE_RTC_MEM + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + rtc_slow_reserved_seg(RW): org = 0x50000000 + 0x2000 - CONFIG_RESERVE_RTC_MEM, + len = CONFIG_RESERVE_RTC_MEM +#endif #ifdef CONFIG_ESP_SPIRAM ext_ram_seg(RW): org = 0x3f800000, len = CONFIG_ESP_SPIRAM_SIZE @@ -116,7 +100,9 @@ _rom_store_table = 0; PROVIDE(_memmap_vecbase_reset = 0x40000450); PROVIDE(_memmap_reset_vector = 0x40000400); +/* Heap size calculations for PROCPU is also valid for AMP scenario */ _heap_sentry = SRAM2_DRAM_END; +_libc_heap_size = _heap_sentry - _end; SECTIONS { @@ -154,6 +140,42 @@ SECTIONS LONG(ADDR(.dram0.data)) LONG(LOADADDR(.dram0.data)) LONG(LOADADDR(.dram0.end) + SIZEOF(.dram0.end) - LOADADDR(.dram0.data)) + + /* RTC_IRAM metadata: + * 8. Destination address (VMA) for RTC_IRAM region + * 9. Flash offset (LMA) for start of RTC_IRAM region + * 10. Size of RTC_IRAM region + */ + LONG(ADDR(.rtc.text)) + LONG(LOADADDR(.rtc.text)) + LONG(SIZEOF(.rtc.text)) + + /* RTC_DRAM metadata: + * 11. Destination address (VMA) for RTC_DRAM region + * 12. Flash offset (LMA) for start of RTC_DRAM region + * 13. Size of RTC_DRAM region + */ + LONG(ADDR(.rtc.data)) + LONG(LOADADDR(.rtc.data)) + LONG(SIZEOF(.rtc.data)) + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(ADDR(.flash.text)) + LONG(LOADADDR(.flash.text)) + LONG(SIZEOF(.flash.text)) + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(ADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata_end) - LOADADDR(.flash.rodata)) } > metadata #endif /* CONFIG_BOOTLOADER_MCUBOOT */ @@ -165,38 +187,62 @@ SECTIONS /* --- RTC BEGIN --- */ - /* RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ .rtc.text : { . = ALIGN(4); - *(.rtc.literal .rtc.text) - *rtc_wake_stub*.o(.literal .text .literal.* .text.*) + *(.rtc.literal .rtc.literal.*) + *(.rtc.text .rtc.text.*) + . = ALIGN(4); } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) - /* RTC slow memory holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c - */ + /* + This section is required to skip rtc.text area because rtc_iram_seg and + rtc_data_seg reflect the same address space on different buses. + */ + .rtc.dummy : + { + . = SIZEOF(.rtc.text); + } GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION) + + /* This section located in RTC FAST Memory area. + It holds data marked with RTC_FAST_ATTR attribute. + See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + . = ALIGN(4); + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION) + + /* RTC data section holds RTC wake stub + data/rodata, including from any source file + named rtc_wake_stub*.c and the data marked with + RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + */ .rtc.data : { + . = ALIGN(4); _rtc_data_start = ABSOLUTE(.); - *(.rtc.data) - *(.rtc.rodata) - *rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*) - _rtc_data_end = ABSOLUTE(.); + *(.rtc.data .rtc.data.*) + *(.rtc.rodata .rtc.rodata.*) + . = ALIGN(4); } GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION) - /* RTC bss, from any source file named rtc_wake_stub*.c */ .rtc.bss (NOLOAD) : { _rtc_bss_start = ABSOLUTE(.); - *rtc_wake_stub*.o(.bss .bss.*) - *rtc_wake_stub*.o(COMMON) + *(.rtc.bss .rtc.bss.*) _rtc_bss_end = ABSOLUTE(.); } GROUP_LINK_IN(rtc_slow_seg) + .rtc_noinit (NOLOAD) : + { + . = ALIGN(4); + *(.rtc_noinit .rtc_noinit.*) + . = ALIGN(4) ; + } GROUP_LINK_IN(rtc_slow_seg) + /* This section located in RTC SLOW Memory area. * It holds data marked with RTC_SLOW_ATTR attribute. * See the file "esp_attr.h" for more information. @@ -204,22 +250,33 @@ SECTIONS .rtc.force_slow : { . = ALIGN(4); - _rtc_force_slow_start = ABSOLUTE(.); *(.rtc.force_slow .rtc.force_slow.*) . = ALIGN(4) ; _rtc_force_slow_end = ABSOLUTE(.); - } > rtc_slow_seg + } GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION) - /* Get size of rtc slow data */ _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); + /** + * This section holds RTC SLOW data that should have fixed addresses. + * The data are not initialized at power-up and are retained during deep sleep. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + .rtc_slow_reserved (NOLOAD) : + { + . = ALIGN(4); + _rtc_slow_reserved_start = ABSOLUTE(.); + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + _rtc_slow_reserved_end = ABSOLUTE(.); + } GROUP_LINK_IN(rtc_slow_reserved_seg) +#endif + /* --- RTC END --- */ /* --- IRAM BEGIN --- */ .iram0.vectors : ALIGN(4) { - _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 */ @@ -253,6 +310,7 @@ SECTIONS *(.init.literal) *(.init) _init_end = ABSOLUTE(.); + _iram_start = ABSOLUTE(.); } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) .iram0.text : ALIGN(4) @@ -385,6 +443,7 @@ SECTIONS #if defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiorslpiram .wifiorslpiram.* .wifiextrairam .wifiextrairam.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) /* [mapping:esp_wifi] */ *(.literal.wifi_clock_enable_wrapper .text.wifi_clock_enable_wrapper) @@ -708,16 +767,33 @@ SECTIONS .dram0.noinit (NOLOAD) : { - . = ALIGN (8); + . = ALIGN (4); + __dram_noinit_start = ABSOLUTE(.); +#ifdef CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM + *(EXCLUDE_FILE( + *libdrivers__wifi.a:* + *libsubsys__net__l2__ethernet.a:* + *libsubsys__net__lib__config.a:* + *libsubsys__net__ip.a:* + *libsubsys__net.a:* ) .noinit) + *(EXCLUDE_FILE( + *libdrivers__wifi.a:* + *libsubsys__net__l2__ethernet.a:* + *libsubsys__net__lib__config.a:* + *libsubsys__net__ip.a:* + *libsubsys__net.a:* ) .noinit.*) +#else *(.noinit) *(.noinit.*) - . = ALIGN (8); - } GROUP_LINK_IN(RAMABLE_REGION_1) +#endif /* CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM */ + __dram_noinit_end = ABSOLUTE(.); + . = ALIGN (4); + } GROUP_LINK_IN(RAMABLE_REGION) /* Provide total SRAM usage, including IRAM and DRAM */ _image_ram_start = _dram_data_start; #include - _image_ram_size += _iram_end - _iram_start; + _image_ram_size += _iram_end - _init_start; ASSERT(((_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM data does not fit.") @@ -726,9 +802,10 @@ SECTIONS /* --- SPIRAM BEGIN --- */ #ifdef CONFIG_ESP_SPIRAM - .ext_ram.bss (NOLOAD): + .ext_ram (NOLOAD): { - _ext_ram_data_start = ABSOLUTE(.); + _ext_ram_start = ABSOLUTE(.); + _ext_ram_noinit_start = ABSOLUTE(.); #ifdef CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM *libdrivers__wifi.a:(.noinit .noinit.*) @@ -737,14 +814,26 @@ SECTIONS *libsubsys__net__ip.a:(.noinit .noinit.*) *libsubsys__net.a:(.noinit .noinit.*) #endif /* CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM */ + . = ALIGN(16); + + *(.ext_ram_noinit*) + *(.ext_ram_noinit.*) + + . = ALIGN(16); + _ext_ram_noinit_end = ABSOLUTE(.); _ext_ram_bss_start = ABSOLUTE(.); + *(.ext_ram.bss*) + + . = ALIGN(16); _ext_ram_bss_end = ABSOLUTE(.); + _spiram_heap_start = ABSOLUTE(.); . = . + CONFIG_ESP_SPIRAM_HEAP_SIZE; + . = ALIGN(4); - _ext_ram_data_end = ABSOLUTE(.); + _ext_ram_end = ABSOLUTE(.); } GROUP_LINK_IN(ext_ram_seg) #endif /* CONFIG_ESP_SPIRAM */ @@ -860,6 +949,7 @@ SECTIONS #ifndef CONFIG_ESP32_WIFI_IRAM_OPT *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiorslpiram .wifiorslpiram.* .wifiextrairam .wifiextrairam.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) #endif #ifndef CONFIG_ESP32_WIFI_RX_IRAM_OPT @@ -928,6 +1018,6 @@ SECTIONS /* --- XTENSA GLUE AND DEBUG END --- */ #ifdef CONFIG_ESP_SPIRAM -ASSERT(((_ext_ram_data_end - _ext_ram_data_start) <= CONFIG_ESP_SPIRAM_SIZE), +ASSERT(((_ext_ram_end - _ext_ram_start) <= CONFIG_ESP_SPIRAM_SIZE), "External SPIRAM overflowed.") #endif /* CONFIG_ESP_SPIRAM */ diff --git a/soc/espressif/esp32/default_appcpu.ld b/soc/espressif/esp32/default_appcpu.ld index 145f23e6d7139..71c640df534bb 100644 --- a/soc/espressif/esp32/default_appcpu.ld +++ b/soc/espressif/esp32/default_appcpu.ld @@ -1,42 +1,63 @@ /* * Copyright (c) 2016 Cadence Design Systems, Inc. * Copyright (c) 2017 Intel Corporation - * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * SPDX-License-Identifier: Apache-2.0 */ -/** - * @file - * @brief Linker command/script file - * - * Linker script for the Xtensa platform. - */ - #include #include #include #include -#define RAMABLE_REGION dram0_1_seg -#define RAMABLE_REGION_1 dram0_1_seg -#define RODATA_REGION dram0_1_seg -#define IRAM_REGION iram0_0_seg -#define FLASH_CODE_REGION iram0_0_seg -#define ROMABLE_REGION iram0_0_seg -#define ROMABLE_DATA_REGION dram0_1_seg -#define dram0_0_seg dram0_1_seg +#if !defined(CONFIG_BOOTLOADER_MCUBOOT) +#error "APPCPU image must use MCUboot image format." +#endif /* CONFIG_BOOTLOADER_MCUBOOT */ + +#include "memory.h" + +/* User available SRAM memory segments */ +appcpu_iram_end = USER_IRAM_END - APPCPU_DRAM_SIZE; +appcpu_iram_org = appcpu_iram_end - APPCPU_IRAM_SIZE; +appcpu_iram_len = APPCPU_IRAM_SIZE; + +appcpu_dram_org = SRAM1_DRAM_USER_START; +appcpu_dram_len = APPCPU_DRAM_SIZE; + +/* Aliases */ +#define ROMABLE_REGION FLASH +#define RODATA_REGION dram0_1_seg +#define RAMABLE_REGION dram0_1_seg +#define IRAM_REGION iram0_1_seg -/* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. +/* Zephyr macro re-definitions */ +#undef GROUP_DATA_LINK_IN +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion + +#undef GROUP_NOLOAD_LINK_IN +#define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion + +/* Flash segments (rodata and text) should be mapped in the virtual address spaces. * Executing directly from LMA is not possible. */ #undef GROUP_ROM_LINK_IN #define GROUP_ROM_LINK_IN(vregion, lregion) > RODATA_REGION AT > lregion +/* Make sure new sections have consistent alignment between input and output sections */ +#undef SECTION_DATA_PROLOGUE +#define SECTION_DATA_PROLOGUE(name, options, align) name options : ALIGN_WITH_INPUT + +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE SECTION_DATA_PROLOGUE + MEMORY { - iram0_0_seg(RX): org = 0x40080000 + 0x08000, len = 0x18000 - dram0_shm0_seg(RW): org = 0x3FFE5230, len = 16K /* shared RAM reserved for IPM */ - dram0_sem0_seg(RW): org = 0x3FFED238, len = 8 /*shared data reserved for IPM data header */ - dram0_1_seg(RW): org = 0x3FFE9238 + CONFIG_ESP32_BT_RESERVE_DRAM, len = 0x17CB0 - 0xEE0 - CONFIG_ESP32_BT_RESERVE_DRAM + mcuboot_hdr (R): org = 0x0, len = 0x20 + metadata (R): org = 0x20, len = 0x20 + FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 + + iram0_1_seg(RX): org = appcpu_iram_org, len = appcpu_iram_len + dram0_1_seg(RW): org = appcpu_dram_org, len = appcpu_dram_len + #ifdef CONFIG_GEN_ISR_TABLES IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 #endif @@ -44,26 +65,62 @@ MEMORY /* Default entry point: */ PROVIDE ( _ResetVector = 0x40000400 ); -ENTRY(__app_cpu_start) +ENTRY(__appcpu_start) _rom_store_table = 0; PROVIDE(_memmap_vecbase_reset = 0x40000450); PROVIDE(_memmap_reset_vector = 0x40000400); -_heap_sentry = 0x3ffe3f20; +/* Heap size calculations for APPCPU */ +_heap_sentry = BOOTLOADER_DRAM_SEG_START + APPCPU_DRAM_SIZE; +_libc_heap_size = _heap_sentry - _end; SECTIONS { -#include + /* Reserve space for MCUboot header in the binary */ + .mcuboot_header : + { + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + } > mcuboot_hdr + /* Image load table */ + .metadata : + { + /* 0. Magic byte for load header */ + LONG(0xace637d3) + + /* 1. Application entry point address */ + KEEP(*(.entry_addr)) + + /* IRAM metadata: + * 2. Destination address (VMA) for IRAM region + * 3. Flash offset (LMA) for start of IRAM region + * 4. Size of IRAM region + */ + LONG(ADDR(.iram0.vectors)) + LONG(LOADADDR(.iram0.vectors)) + LONG(_iram_end - _init_start); + + /* DRAM metadata: + * 5. Destination address (VMA) for DRAM region + * 6. Flash offset (LMA) for start of DRAM region + * 7. Size of DRAM region + */ + LONG(ADDR(.dram0.data)) + LONG(LOADADDR(.dram0.data)) + LONG(_data_end - _data_start) + } > metadata + + #include #ifdef CONFIG_LLEXT -#include + #include #endif - _image_iram_start = LOADADDR(.iram0.vectors); - _image_iram_size = LOADADDR(_TEXT_SECTION_NAME) + SIZEOF(_TEXT_SECTION_NAME) - _image_iram_start; - _image_iram_vaddr = ADDR(.iram0.vectors); + /* --- START OF IRAM --- */ /* Send .iram0 code to iram */ .iram0.vectors : ALIGN(4) @@ -102,12 +159,10 @@ SECTIONS *(.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); + _iram_start = ABSOLUTE(.); } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) - SECTION_PROLOGUE(_TEXT_SECTION_NAME, , ALIGN(4)) + .iram0.text : ALIGN(4) { /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); @@ -150,25 +205,136 @@ SECTIONS *libnet80211.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*) *libpp.a:( .wifirxiram .wifirxiram.* .wifislprxiram .wifislprxiram.*) + . = ALIGN(16); + _iram_text_end = ABSOLUTE(.); + _iram_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) + + .flash.text : ALIGN(16) + { + _stext = .; + _text_start = ABSOLUTE(.); + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + *(.literal .text .literal.* .text.*) + + /* CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _text_end = ABSOLUTE(.); + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + . = ALIGN(4); + _flash_cache_start = ABSOLUTE(0); + . = ALIGN(4); _iram_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) - _image_drom_start = LOADADDR(_RODATA_SECTION_NAME); - _image_drom_size = LOADADDR(_RODATA_SECTION_END) + SIZEOF(_RODATA_SECTION_END) - _image_drom_start; - _image_drom_vaddr = ADDR(_RODATA_SECTION_NAME); + /* --- END OF IRAM --- */ - SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) + /* --- START OF DRAM --- */ + + .dram0.data : { - __rodata_region_start = ABSOLUTE(.); + . = ALIGN(16); + __data_start = ABSOLUTE(.); + _data_start = ABSOLUTE(.); + + _btdm_data_start = ABSOLUTE(.); + *libbtdm_app.a:(.data .data.*) + . = ALIGN (4); + _btdm_data_end = ABSOLUTE(.); + + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + /* rodata for panic handler(libarch__xtensa__core.a) and all + * dependent functions should be placed in DRAM to avoid issue + * when flash cache is disabled */ + *libarch__xtensa__core.a:(.rodata .rodata.*) + *libkernel.a:fatal.*(.rodata .rodata.*) + *libkernel.a:init.*(.rodata .rodata.*) + *libzephyr.a:cbprintf_complete*(.rodata .rodata.*) + *libzephyr.a:log_core.*(.rodata .rodata.*) + *libzephyr.a:log_backend_uart.*(.rodata .rodata.*) + *libzephyr.a:log_output.*(.rodata .rodata.*) + *libzephyr.a:loader.*(.rodata .rodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_rom_patch.*(.rodata .rodata.*) + *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.*) . = ALIGN(4); + #include + . = ALIGN(4); + + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + . = ALIGN(16); + + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + #include + #include + #include + #include + #include + #include + + .dram0.rodata : ALIGN(4) + { + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ + *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ + + __rodata_region_start = ABSOLUTE(.); + . = ALIGN(16); #include . = ALIGN(4); - *(EXCLUDE_FILE (*libarch__xtensa__core.a:* *libkernel.a:fatal.* *libkernel.a:init.* *libzephyr.a:cbprintf_complete* *libzephyr.a:log_core.* *libzephyr.a:log_backend_uart.* *libdrivers__flash.a:esp32_mp.* *libzephyr.a:log_output.* *libzephyr.a:loader.* *libdrivers__flash.a:flash_esp32.* *libdrivers__serial.a:uart_esp32.* *libzephyr.a:spi_flash_rom_patch.*) .rodata) - *(EXCLUDE_FILE (*libarch__xtensa__core.a:* *libkernel.a:fatal.* *libkernel.a:init.* *libzephyr.a:cbprintf_complete* *libzephyr.a:log_core.* *libzephyr.a:log_backend_uart.* *libdrivers__flash.a:esp32_mp.* *libzephyr.a:log_output.* *libzephyr.a:loader.* *libdrivers__flash.a:flash_esp32.* *libdrivers__serial.a:uart_esp32.* *libzephyr.a:spi_flash_rom_patch.*) .rodata.*) + *(EXCLUDE_FILE ( + *libarch__xtensa__core.a:* + *libkernel.a:fatal.* + *libkernel.a:init.* + *libzephyr.a:cbprintf_complete* + *libzephyr.a:log_core.* + *libzephyr.a:log_backend_uart.* + *libzephyr.a:log_output.* + *libzephyr.a:loader.* + *libdrivers__serial.a:uart_esp32.*) .rodata) + + *(EXCLUDE_FILE ( + *libarch__xtensa__core.a:* + *libkernel.a:fatal.* + *libkernel.a:init.* + *libzephyr.a:cbprintf_complete* + *libzephyr.a:log_core.* + *libzephyr.a:log_backend_uart.* + *libzephyr.a:log_output.* + *libzephyr.a:loader.* + *libdrivers__serial.a:uart_esp32.*) .rodata.*) *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ *(.gnu.linkonce.r.*) @@ -209,8 +375,9 @@ SECTIONS *(.rodata_wlog*) _thread_local_end = ABSOLUTE(.); . = ALIGN(4); - } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_DATA_REGION) + } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) + #include #include #include #include @@ -218,84 +385,33 @@ SECTIONS #include #include #include + #include #include /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ - SECTION_PROLOGUE(_RODATA_SECTION_END,,) + .dram0.rodata_end : ALIGN(16) { . = ALIGN(4); _image_rodata_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) - _image_dram_start = LOADADDR(.dram0.data); - _image_dram_size = LOADADDR(.dram0.end) + SIZEOF(.dram0.end) - _image_dram_start; - _image_dram_vaddr = ADDR(.dram0.data); - - .dram0.data : - { - __data_start = ABSOLUTE(.); - - _btdm_data_start = ABSOLUTE(.); - *libbtdm_app.a:(.data .data.*) - . = ALIGN (4); - _btdm_data_end = ABSOLUTE(.); - - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - /* rodata for panic handler(libarch__xtensa__core.a) and all - * dependent functions should be placed in DRAM to avoid issue - * when flash cache is disabled */ - *libarch__xtensa__core.a:(.rodata .rodata.*) - *libkernel.a:fatal.*(.rodata .rodata.*) - *libkernel.a:init.*(.rodata .rodata.*) - *libzephyr.a:cbprintf_complete*(.rodata .rodata.*) - *libzephyr.a:log_core.*(.rodata .rodata.*) - *libzephyr.a:log_backend_uart.*(.rodata .rodata.*) - *libzephyr.a:log_output.*(.rodata .rodata.*) - *libzephyr.a:loader.*(.rodata .rodata.*) - *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) - *libzephyr.a:spi_flash_rom_patch.*(.rodata .rodata.*) - *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.*) - - KEEP(*(.jcr)) - *(.dram1 .dram1.*) - . = ALIGN(4); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_DATA_REGION) - - #include - #include - #include - #include - #include - - /* logging sections should be placed in RAM area to avoid flash cache disabled issues */ - #pragma push_macro("GROUP_ROM_LINK_IN") - #undef GROUP_ROM_LINK_IN - #define GROUP_ROM_LINK_IN GROUP_DATA_LINK_IN - #include - #pragma pop_macro("GROUP_ROM_LINK_IN") - .dram0.end : { - . = ALIGN(4); - - #include - - . = ALIGN(4); __data_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_DATA_REGION) + _data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .dram0.noinit (NOLOAD): + { + . = ALIGN (8); + *(.noinit) + *(.noinit.*) + . = ALIGN (8); + } GROUP_LINK_IN(RAMABLE_REGION) /* Shared RAM */ - SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) + .dram0.bss (NOLOAD) : { . = ALIGN (8); _bss_start = ABSOLUTE(.); /* required by bluetooth library */ @@ -306,9 +422,6 @@ SECTIONS . = ALIGN (4); _btdm_bss_end = ABSOLUTE(.); - /* Buffer for system heap should be placed in dram0_0_seg */ - *libkernel.a:mempool.*(.noinit.kheap_buf__system_heap .noinit.*.kheap_buf__system_heap) - *(.dynsbss) *(.sbss) *(.sbss.*) @@ -330,40 +443,16 @@ SECTIONS /* Provide total SRAM usage, including IRAM and DRAM */ _image_ram_start = __rodata_region_start; #include - _image_ram_size += _iram_end - _iram_start; + _image_ram_size += _iram_end - _init_start; - ASSERT(((__bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), + ASSERT(((__bss_end - ORIGIN(dram0_1_seg)) <= LENGTH(dram0_1_seg)), "DRAM segment data does not fit.") - SECTION_DATA_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD),) - { - . = ALIGN (8); - *(.noinit) - *(.noinit.*) - . = ALIGN (8); - } GROUP_LINK_IN(RAMABLE_REGION_1) - - _image_irom_start = LOADADDR(.flash.text); - _image_irom_size = LOADADDR(.flash.text) + SIZEOF(.flash.text) - _image_irom_start; - _image_irom_vaddr = ADDR(.flash.text); - - .flash.text : ALIGN(4) - { - _stext = .; - _text_start = ABSOLUTE(.); - - *(.literal .text .literal.* .text.*) - . = ALIGN(4); - _text_end = ABSOLUTE(.); - _etext = .; - - /* Similar to _iram_start, this symbol goes here so it is - resolved by addr2line in preference to the first symbol in - the flash.text segment. - */ - _flash_cache_start = ABSOLUTE(0); - } GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION) + /* --- END OF DRAM --- */ +#ifdef CONFIG_GEN_ISR_TABLES +#include +#endif #include @@ -400,12 +489,7 @@ SECTIONS KEEP (*(.xt.profile_files)) KEEP (*(.gnu.linkonce.xt.profile_files.*)) } - -#ifdef CONFIG_GEN_ISR_TABLES -#include -#endif - } -ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), +ASSERT(((_iram_end - ORIGIN(iram0_1_seg)) <= LENGTH(iram0_1_seg)), "IRAM0 segment data does not fit.") diff --git a/soc/espressif/esp32/esp32-mp.c b/soc/espressif/esp32/esp32-mp.c index 963bcfc0d5627..55bc5fd028e4f 100644 --- a/soc/espressif/esp32/esp32-mp.c +++ b/soc/espressif/esp32/esp32-mp.c @@ -1,35 +1,32 @@ /* * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ -/* Include esp-idf headers first to avoid redefining BIT() macro */ -#include -#include -#include - -#include -#include -#include -#include #include #include #include #include +#include +#include -#define Z_REG(base, off) (*(volatile uint32_t *)((base) + (off))) - -#define RTC_CNTL_BASE 0x3ff48000 -#define RTC_CNTL_OPTIONS0 Z_REG(RTC_CNTL_BASE, 0x0) -#define RTC_CNTL_SW_CPU_STALL Z_REG(RTC_CNTL_BASE, 0xac) +#include +#include +#include "esp_rom_uart.h" -#define DPORT_BASE 0x3ff00000 -#define DPORT_APPCPU_CTRL_A Z_REG(DPORT_BASE, 0x02C) -#define DPORT_APPCPU_CTRL_B Z_REG(DPORT_BASE, 0x030) -#define DPORT_APPCPU_CTRL_C Z_REG(DPORT_BASE, 0x034) +#include "esp_mcuboot_image.h" +#include "esp_memory_utils.h" #ifdef CONFIG_SMP + +#include + +#ifndef CONFIG_SOC_ESP32_PROCPU +static struct k_spinlock loglock; +#endif + struct cpustart_rec { int cpu; arch_cpustart_t fn; @@ -43,7 +40,6 @@ volatile struct cpustart_rec *start_rec; static void *appcpu_top; static bool cpus_active[CONFIG_MP_MAX_NUM_CPUS]; static struct k_spinlock loglock; -#endif /* Note that the logging done here is ACTUALLY REQUIRED FOR RELIABLE * OPERATION! At least one particular board will experience spurious @@ -62,7 +58,6 @@ static struct k_spinlock loglock; */ void smp_log(const char *msg) { -#ifndef CONFIG_SOC_ESP32_PROCPU k_spinlock_key_t key = k_spin_lock(&loglock); while (*msg) { @@ -72,10 +67,8 @@ void smp_log(const char *msg) esp_rom_uart_tx_one_char('\n'); k_spin_unlock(&loglock, key); -#endif } -#ifdef CONFIG_SMP static void appcpu_entry2(void) { volatile int ps, ie; @@ -168,7 +161,6 @@ static void appcpu_entry1(void) { z_appcpu_stack_switch(appcpu_top, appcpu_entry2); } -#endif /* The calls and sequencing here were extracted from the ESP-32 * FreeRTOS integration with just a tiny bit of cleanup. None of the @@ -177,7 +169,7 @@ static void appcpu_entry1(void) */ void esp_appcpu_start(void *entry_point) { - smp_log("ESP32: starting APPCPU"); + ets_printf("ESP32: starting APPCPU"); /* These two calls are wrapped in a "stall_other_cpu" API in * esp-idf. But in this context the appcpu is stalled by @@ -189,15 +181,10 @@ void esp_appcpu_start(void *entry_point) esp_rom_ets_set_appcpu_boot_addr((void *)0); - RTC_CNTL_SW_CPU_STALL &= ~RTC_CNTL_SW_STALL_APPCPU_C1; - RTC_CNTL_OPTIONS0 &= ~RTC_CNTL_SW_STALL_APPCPU_C0; - DPORT_APPCPU_CTRL_B |= DPORT_APPCPU_CLKGATE_EN; - DPORT_APPCPU_CTRL_C &= ~DPORT_APPCPU_RUNSTALL; - - /* Pulse the RESETTING bit */ - DPORT_APPCPU_CTRL_A |= DPORT_APPCPU_RESETTING; - DPORT_APPCPU_CTRL_A &= ~DPORT_APPCPU_RESETTING; - + DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN); + DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL); + DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING); + DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING); /* extracted from SMP LOG above, THIS IS REQUIRED FOR AMP RELIABLE * OPERATION AS WELL, PLEASE DON'T touch on the dummy write below! @@ -223,10 +210,9 @@ void esp_appcpu_start(void *entry_point) */ esp_rom_ets_set_appcpu_boot_addr((void *)entry_point); - smp_log("ESP32: APPCPU start sequence complete"); + ets_printf("ESP32: APPCPU start sequence complete"); } -#ifdef CONFIG_SMP IRAM_ATTR static void esp_crosscore_isr(void *arg) { ARG_UNUSED(arg); @@ -317,3 +303,160 @@ IRAM_ATTR bool arch_cpu_active(int cpu_num) return cpus_active[cpu_num]; } #endif /* CONFIG_SMP */ + +void esp_appcpu_start2(void *entry_point) +{ + esp_cpu_unstall(1); + + if (!DPORT_GET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN)) { + DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN); + DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL); + DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING); + DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING); + } + + esp_rom_ets_set_appcpu_boot_addr((void *)entry_point); + + esp_cpu_reset(1); +} + +/* AMP support */ +#ifdef CONFIG_SOC_ENABLE_APPCPU + +#include "bootloader_flash_priv.h" + +#define sys_mmap bootloader_mmap +#define sys_munmap bootloader_munmap + +static int load_segment(uint32_t src_addr, uint32_t src_len, uint32_t dst_addr) +{ + const uint32_t *data = (const uint32_t *)sys_mmap(src_addr, src_len); + + if (!data) { + ets_printf("%s: mmap failed", __func__); + return -1; + } + + volatile uint32_t *dst = (volatile uint32_t *)dst_addr; + + for (int i = 0; i < src_len / 4; i++) { + dst[i] = data[i]; + } + + sys_munmap(data); + + return 0; +} + +int IRAM_ATTR esp_appcpu_image_load(unsigned int hdr_offset, unsigned int *entry_addr) +{ + const uint32_t img_off = FIXED_PARTITION_OFFSET(slot0_appcpu_partition); + const uint32_t fa_size = FIXED_PARTITION_SIZE(slot0_appcpu_partition); + const uint8_t fa_id = FIXED_PARTITION_ID(slot0_appcpu_partition); + + if (entry_addr == NULL) { + ets_printf("Can't return the entry address. Aborting!\n"); + abort(); + return -1; + } + + uint32_t mcuboot_header[8] = {0}; + esp_image_load_header_t image_header = {0}; + + const uint32_t *data = (const uint32_t *)sys_mmap(img_off, 0x40); + + memcpy((void *)&mcuboot_header, data, sizeof(mcuboot_header)); + memcpy((void *)&image_header, data + (hdr_offset / sizeof(uint32_t)), + sizeof(esp_image_load_header_t)); + + sys_munmap(data); + + if (image_header.header_magic == ESP_LOAD_HEADER_MAGIC) { + ets_printf("APPCPU image, area id: %d, offset: 0x%x, hdr.off: 0x%x, size: %d kB\n", + fa_id, img_off, hdr_offset, fa_size / 1024); + } else if ((image_header.header_magic & 0xff) == 0xE9) { + ets_printf("ESP image format is not supported\n"); + abort(); + } else { + ets_printf("Unknown or empty image detected. Aborting!\n"); + abort(); + } + + if (!esp_ptr_in_iram((void *)image_header.iram_dest_addr) || + !esp_ptr_in_iram((void *)(image_header.iram_dest_addr + image_header.iram_size))) { + ets_printf("IRAM region in load header is not valid. Aborting"); + abort(); + } + + if (!esp_ptr_in_dram((void *)image_header.dram_dest_addr) || + !esp_ptr_in_dram((void *)(image_header.dram_dest_addr + image_header.dram_size))) { + ets_printf("DRAM region in load header is not valid. Aborting"); + abort(); + } + + if (!esp_ptr_in_iram((void *)image_header.entry_addr)) { + ets_printf("Application entry point (%xh) is not in IRAM. Aborting", + image_header.entry_addr); + abort(); + } + + ets_printf("IRAM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) load\n", + (img_off + image_header.iram_flash_offset), image_header.iram_dest_addr, + image_header.iram_size, image_header.iram_size); + + load_segment(img_off + image_header.iram_flash_offset, image_header.iram_size, + image_header.iram_dest_addr); + + ets_printf("DRAM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) load\n", + (img_off + image_header.dram_flash_offset), image_header.dram_dest_addr, + image_header.dram_size, image_header.dram_size); + + load_segment(img_off + image_header.dram_flash_offset, image_header.dram_size, + image_header.dram_dest_addr); + + ets_printf("Application start=%xh\n\n", image_header.entry_addr); + esp_rom_uart_tx_wait_idle(0); + + assert(entry_addr != NULL); + *entry_addr = image_header.entry_addr; + + return 0; +} + +void esp_appcpu_image_stop(void) +{ + esp_cpu_stall(1); +} + +void esp_appcpu_image_start(unsigned int hdr_offset) +{ + static int started; + unsigned int entry_addr = 0; + + if (started) { + printk("APPCPU already started.\r\n"); + return; + } + + /* Input image meta header, output appcpu entry point */ + esp_appcpu_image_load(hdr_offset, &entry_addr); + + esp_appcpu_start2((void *)entry_addr); +} + +int esp_appcpu_init(void) +{ + /* Load APPCPU image using image header offset + * (skipping the MCUBoot header) + */ + esp_appcpu_image_start(0x20); + + return 0; +} + +#if !defined(CONFIG_MCUBOOT) +extern int esp_appcpu_init(void); +SYS_INIT(esp_appcpu_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +#endif + +#endif /* CONFIG_SOC_ENABLE_APPCPU */ diff --git a/soc/espressif/esp32/hw_init.c b/soc/espressif/esp32/hw_init.c index 8ff2a3f684b44..0282f1706421d 100644 --- a/soc/espressif/esp32/hw_init.c +++ b/soc/espressif/esp32/hw_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -51,18 +51,14 @@ int hardware_init(void) bootloader_clock_configure(); +#ifdef CONFIG_ESP_CONSOLE /* initialize console, from now on, we can log */ esp_console_init(); print_banner(); - - spi_flash_init_chip_state(); - err = esp_flash_init_default_chip(); - if (err != 0) { - ESP_EARLY_LOGE(TAG, "Failed to init flash chip, error %d", err); - return err; - } +#endif /* CONFIG_ESP_CONSOLE */ reset_mmu(); + flash_update_id(); err = bootloader_flash_xmc_startup(); @@ -88,6 +84,7 @@ int hardware_init(void) check_wdt_reset(); config_wdt(); + soc_random_enable(); return 0; diff --git a/soc/espressif/esp32/mcuboot.ld b/soc/espressif/esp32/mcuboot.ld index b880e2c7b34ea..6b321111a0e06 100644 --- a/soc/espressif/esp32/mcuboot.ld +++ b/soc/espressif/esp32/mcuboot.ld @@ -44,28 +44,17 @@ SECTIONS *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *libarch__xtensa__core.a:xtensa_asm2_util.*(.literal .text .literal.* .text.*) - *liblib__libc__common.a:abort.*(.literal .text .literal.* .text.*) - *libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*) *libarch__common.a:dynamic_isr.*(.literal .text .literal.* .text.*) *libarch__common.a:sw_isr_common.*(.literal .text .literal.* .text.*) *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*) - *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out) *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*) *libzephyr.a:cpu.*(.literal .text .literal.* .text.*) *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) - - *libzephyr.a:heap.*(.literal .text .literal.* .text.*) - - *libkernel.a:kheap.*(.literal .text .literal.* .text.*) - *libkernel.a:mempool.*(.literal .text .literal.* .text.*) *libkernel.a:device.*(.literal .text .literal.* .text.*) - *libkernel.a:timeout.*(.literal .text .literal.* .text.*) - *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) - *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) diff --git a/soc/espressif/esp32/memory.h b/soc/espressif/esp32/memory.h index de298c34976f0..67da219f2d11b 100644 --- a/soc/espressif/esp32/memory.h +++ b/soc/espressif/esp32/memory.h @@ -5,22 +5,22 @@ #pragma once /* SRAM0 (192kB) instruction cache+memory */ -#define SRAM0_IRAM_START 0x40070000 +#define SRAM0_IRAM_START DT_REG_ADDR(DT_NODELABEL(sram0)) #define SRAM0_CACHE_SIZE 0x10000 -#define SRAM0_SIZE 0x30000 +#define SRAM0_SIZE DT_REG_SIZE(DT_NODELABEL(sram0)) /* SRAM1 (128kB) instruction/data memory */ -#define SRAM1_IRAM_START 0x400a0000 -#define SRAM1_DRAM_START 0x3ffe0000 -#define SRAM1_SIZE 0x20000 -#define SRAM1_DRAM_END (SRAM1_DRAM_START + SRAM1_SIZE) -#define SRAM1_DRAM_PROAPP_PRIV_SIZE 0x8000 -#define SRAM1_DRAM_USER_START 0x3ffe8000 -#define SRAM1_USER_SIZE (0x40000000 - SRAM1_DRAM_USER_START) +#define SRAM1_IRAM_START (SRAM0_IRAM_START + SRAM0_SIZE) +#define SRAM1_DRAM_START DT_REG_ADDR(DT_NODELABEL(sram1)) +#define SRAM1_SIZE DT_REG_SIZE(DT_NODELABEL(sram1)) +#define SRAM1_DRAM_END (SRAM1_DRAM_START + SRAM1_SIZE) +#define SRAM1_RESERVED_SIZE 0x8000 +#define SRAM1_DRAM_USER_START (SRAM1_DRAM_START + SRAM1_RESERVED_SIZE) +#define SRAM1_USER_SIZE (0x40000000 - SRAM1_DRAM_USER_START) /* SRAM2 (200kB) data memory */ -#define SRAM2_DRAM_START 0x3ffae000 -#define SRAM2_DRAM_SIZE 0x32000 +#define SRAM2_DRAM_START DT_REG_ADDR(DT_NODELABEL(sram2)) +#define SRAM2_DRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sram2)) #define SRAM2_DRAM_SHM_SIZE 0x2000 #define SRAM2_DRAM_END (SRAM2_DRAM_START + SRAM2_DRAM_SIZE) #define SRAM2_DRAM_USER_START (SRAM2_DRAM_START + SRAM2_DRAM_SHM_SIZE) @@ -43,12 +43,15 @@ #define DRAM1_BT_SHM_BUFFERS_START 0x3ffe4350 #define DRAM1_BT_SHM_BUFFERS_END 0x3ffe5230 +/* The address is a limit set manually for AMP build */ +#define DRAM1_AMP_SHM_BUFFERS_END 0x3ffe9800 + /* Convert IRAM address to its DRAM counterpart in SRAM1 memory */ -#define SRAM1_IRAM_DRAM_CALC(addr_iram) ((addr_iram > SRAM1_IRAM_START) ? \ - (SRAM1_SIZE - (addr_iram - SRAM1_IRAM_START) + SRAM1_DRAM_START) : (SRAM1_DRAM_END)) +#define SRAM1_IRAM_DRAM_CALC(addr_iram) (SRAM1_SIZE - (addr_iram - SRAM1_IRAM_START) + \ + SRAM1_DRAM_START) /* Convert DRAM address to its IRAM counterpart in SRAM1 memory */ -#define SRAM1_DRAM_IRAM_CALC(addr_dram) \ - (SRAM1_SIZE - (addr_dram - SRAM1_DRAM_START) + SRAM1_IRAM_START) +#define SRAM1_DRAM_IRAM_CALC(addr_dram) (SRAM1_SIZE - (addr_dram - SRAM1_DRAM_START) + \ + SRAM1_IRAM_START) /* Set bootloader segments size */ #define BOOTLOADER_DRAM_SEG_LEN 0x7a00 @@ -61,6 +64,29 @@ #define BOOTLOADER_IRAM_LOADER_SEG_START 0x40078000 #define BOOTLOADER_IRAM_SEG_START 0x400a0000 +/* The `USER_IRAM_END` represents the end of staticaly allocated memory. + * This address is where 2nd stage bootloader starts allocating memory. + * The `iram_loader_seg` which is the last memory the bootloader runs from + * resides in the SRAM0 'cache' area, the `user_iram_end` applies for + * all build cases - Simple boot and the MCUboot application. + */ +#if defined(CONFIG_SOC_ENABLE_APPCPU) || defined(CONFIG_SOC_ESP32_APPCPU) +#define USER_IRAM_END SRAM1_DRAM_IRAM_CALC(DRAM1_AMP_SHM_BUFFERS_END) +#else +#define USER_IRAM_END SRAM1_DRAM_IRAM_CALC(SRAM1_DRAM_USER_START) +#endif + +/* AMP memory */ +#if defined(CONFIG_SOC_ENABLE_APPCPU) || defined(CONFIG_SOC_ESP32_APPCPU) +#define APPCPU_IRAM_SIZE CONFIG_ESP_APPCPU_IRAM_SIZE +#define APPCPU_DRAM_SIZE CONFIG_ESP_APPCPU_DRAM_SIZE +#else +#define APPCPU_IRAM_SIZE 0 +#define APPCPU_DRAM_SIZE 0 +#endif + +#define APPCPU_SRAM_SIZE (APPCPU_IRAM_SIZE + APPCPU_DRAM_SIZE) + /* Flash */ #ifdef CONFIG_FLASH_SIZE #define FLASH_SIZE CONFIG_FLASH_SIZE @@ -74,10 +100,3 @@ #define IROM_SEG_LEN (FLASH_SIZE - 0x1000) #define DROM_SEG_ORG 0x3f400000 #define DROM_SEG_LEN (FLASH_SIZE - 0x1000) - -/* AMP: TODO utilise memory for APPCPU */ -#ifndef CONFIG_SOC_ESP32_PROCPU -#define APPCPU_IRAM_SIZE 0x20000 -#else -#define APPCPU_IRAM_SIZE 0x8000 -#endif diff --git a/soc/espressif/esp32/soc.c b/soc/espressif/esp32/soc.c index f6f21eddffb1b..e0f307a2d8ec6 100644 --- a/soc/espressif/esp32/soc.c +++ b/soc/espressif/esp32/soc.c @@ -1,162 +1,36 @@ /* * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2025 Espressif Systems (Shanghai) CO LTD. * * SPDX-License-Identifier: Apache-2.0 */ -/* Include esp-idf headers first to avoid redefining BIT() macro */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#if CONFIG_ESP_SPIRAM -#include "psram.h" -#endif - -#include -#include -#include -#include -#include -#include - +#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include -#include - -#ifndef CONFIG_SOC_ENABLE_APPCPU -#include "esp_clk_internal.h" -#endif /* CONFIG_SOC_ENABLE_APPCPU */ - +#include +#include #include -#include "esp_log.h" - -#define TAG "boot.esp32" extern void z_prep_c(void); extern void esp_reset_reason_init(void); -#ifdef CONFIG_SOC_ENABLE_APPCPU -extern const unsigned char esp32_appcpu_fw_array[]; - -void IRAM_ATTR esp_start_appcpu(void) +void IRAM_ATTR __esp_platform_app_start(void) { - esp_image_header_t *header = (esp_image_header_t *)&esp32_appcpu_fw_array[0]; - esp_image_segment_header_t *segment = - (esp_image_segment_header_t *)&esp32_appcpu_fw_array[sizeof(esp_image_header_t)]; - uint8_t *segment_payload; - uint32_t entry_addr = header->entry_addr; - uint32_t idx = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t); - - for (int i = 0; i < header->segment_count; i++) { - segment_payload = (uint8_t *)&esp32_appcpu_fw_array[idx]; - - if (segment->load_addr >= SOC_IRAM_LOW && segment->load_addr < SOC_IRAM_HIGH) { - /* IRAM segment only accepts 4 byte access, avoid memcpy usage here */ - volatile uint32_t *src = (volatile uint32_t *)segment_payload; - volatile uint32_t *dst = (volatile uint32_t *)segment->load_addr; - - for (int j = 0; j < segment->data_len / 4; j++) { - dst[j] = src[j]; - } - } else if (segment->load_addr >= SOC_DRAM_LOW && - segment->load_addr < SOC_DRAM_HIGH) { - - memcpy((void *)segment->load_addr, (const void *)segment_payload, - segment->data_len); - } - - idx += segment->data_len; - segment = (esp_image_segment_header_t *)&esp32_appcpu_fw_array[idx]; - idx += sizeof(esp_image_segment_header_t); - } - - esp_appcpu_start((void *)entry_addr); -} -#endif /* CONFIG_SOC_ENABLE_APPCPU */ - -/* - * This is written in C rather than assembly since, during the port bring up, - * Zephyr is being booted by the Espressif bootloader. With it, the C stack - * is already set up. - */ -void IRAM_ATTR __esp_platform_start(void) -{ - extern uint32_t _init_start; - - /* Move the exception vector table to IRAM. */ - __asm__ __volatile__ ( - "wsr %0, vecbase" - : - : "r"(&_init_start)); - - z_bss_zero(); - - __asm__ __volatile__ ( - "" - : - : "g"(&__bss_start) - : "memory"); - - /* Disable normal interrupts. */ - __asm__ __volatile__ ( - "wsr %0, PS" - : - : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE)); - - /* Initialize the architecture CPU pointer. Some of the - * initialization code wants a valid arch_current_thread() before - * z_prep_c() is invoked. - */ - __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0])); - esp_reset_reason_init(); -#ifndef CONFIG_MCUBOOT - /* ESP-IDF/MCUboot 2nd stage bootloader enables RTC WDT to check - * on startup sequence related issues in application. Hence disable that - * as we are about to start Zephyr environment. - */ - wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; - - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_disable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - esp_timer_early_init(); -#if CONFIG_SOC_ENABLE_APPCPU - /* start the ESP32 APP CPU */ - esp_start_appcpu(); -#endif - - esp_mspi_pin_init(); + esp_flash_config(); - esp_flash_app_init(); - - esp_mmu_map_init(); + esp_intr_initialize(); #if CONFIG_ESP_SPIRAM esp_init_psram(); -#endif /* CONFIG_ESP_SPIRAM */ -#endif /* !CONFIG_MCUBOOT */ - - esp_intr_initialize(); - -#if CONFIG_ESP_SPIRAM /* Init Shared Multi Heap for PSRAM */ int err = esp_psram_smh_init(); @@ -171,6 +45,16 @@ void IRAM_ATTR __esp_platform_start(void) CODE_UNREACHABLE; } +void IRAM_ATTR __esp_platform_mcuboot_start(void) +{ + esp_intr_initialize(); + + /* Start Zephyr */ + z_prep_c(); + + CODE_UNREACHABLE; +} + /* Boot-time static default printk handler, possibly to be overridden later. */ int IRAM_ATTR arch_printk_char_out(int c) { diff --git a/soc/espressif/esp32/soc.h b/soc/espressif/esp32/soc.h index e2ea8cc50b7e6..6958a25fbd0d3 100644 --- a/soc/espressif/esp32/soc.h +++ b/soc/espressif/esp32/soc.h @@ -20,7 +20,8 @@ #include #include -void __esp_platform_start(void); +void __esp_platform_mcuboot_start(void); +void __esp_platform_app_start(void); static inline void esp32_set_mask32(uint32_t v, uint32_t mem_addr) { diff --git a/soc/espressif/esp32/soc_appcpu.c b/soc/espressif/esp32/soc_appcpu.c index 74d807606248f..82c8ef1ad6571 100644 --- a/soc/espressif/esp32/soc_appcpu.c +++ b/soc/espressif/esp32/soc_appcpu.c @@ -33,14 +33,28 @@ #include #include +#define HDR_ATTR __attribute__((section(".entry_addr"))) __attribute__((used)) + +void __appcpu_start(void); +static HDR_ATTR void (*_entry_point)(void) = &__appcpu_start; + extern void z_prep_c(void); +static void core_intr_matrix_clear(void) +{ + uint32_t core_id = esp_cpu_get_core_id(); + + for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) { + intr_matrix_set(core_id, i, ETS_INVALID_INUM); + } +} + /* * This is written in C rather than assembly since, during the port bring up, * Zephyr is being booted by the Espressif bootloader. With it, the C stack * is already set up. */ -void __app_cpu_start(void) +void IRAM_ATTR __appcpu_start(void) { extern uint32_t _init_start; @@ -66,12 +80,15 @@ void __app_cpu_start(void) : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE)); /* Initialize the architecture CPU pointer. Some of the - * initialization code wants a valid arch_current_thread() before + * initialization code wants a valid _current before * z_prep_c() is invoked. */ - __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0])); + __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[1])); + + core_intr_matrix_clear(); esp_intr_initialize(); + /* Start Zephyr */ z_prep_c(); diff --git a/soc/espressif/esp32c2/CMakeLists.txt b/soc/espressif/esp32c2/CMakeLists.txt index 2d70c8cd7de6f..bd1b0474de643 100644 --- a/soc/espressif/esp32c2/CMakeLists.txt +++ b/soc/espressif/esp32c2/CMakeLists.txt @@ -11,71 +11,3 @@ zephyr_sources( zephyr_include_directories(.) zephyr_sources_ifndef(CONFIG_BOOTLOADER_MCUBOOT hw_init.c) - -# get flash size to use in esptool as string -math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") - -if(NOT CONFIG_BOOTLOADER_MCUBOOT) - - if(CONFIG_BUILD_OUTPUT_BIN) - # make ESP ROM loader compatible image - message("ESP-IDF path: ${ESP_IDF_PATH}") - - set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) - message("esptool path: ${ESPTOOL_PY}") - - set(ELF2IMAGE_ARG "") - if(NOT CONFIG_MCUBOOT) - set(ELF2IMAGE_ARG "--ram-only-header") - endif() - - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} - ARGS --chip esp32c2 elf2image ${ELF2IMAGE_ARG} - --flash_mode dio --flash_freq 60m --flash_size ${esptoolpy_flashsize}MB - -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf) - endif() - -endif() - -# get code-partition slot0 address -dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") -dt_reg_addr(img_0_off PATH ${dts_partition_path}) - -# get code-partition boot address -dt_nodelabel(dts_partition_path NODELABEL "boot_partition") -dt_reg_addr(boot_off PATH ${dts_partition_path}) - -# get UART baudrate from DT -dt_chosen(dts_shell_uart PROPERTY "zephyr,shell-uart") -dt_prop(monitor_baud PATH ${dts_shell_uart} PROPERTY "current-speed") - -# C2 uses specific values for flash frequency and UART baudrate -board_runner_args(esp32 "--esp-flash-freq=60m") -board_runner_args(esp32 "--esp-monitor-baud=${monitor_baud}") - -if(CONFIG_BOOTLOADER_MCUBOOT) - board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") -else() - board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}") -endif() - -if(CONFIG_MCUBOOT) - # search from cross references between bootloader sections - message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND - ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/ci/check_callgraph.py - ARGS - --rtl-dirs ${CMAKE_BINARY_DIR}/zephyr - --elf-file ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf - find-refs --from-section=.iram0.iram_loader --to-section=.iram0.text - --exit-code) -endif() - -if(CONFIG_MCUBOOT) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") -else() - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") -endif() diff --git a/soc/espressif/esp32c2/Kconfig b/soc/espressif/esp32c2/Kconfig index a0e6c98e31ac0..1e7f41e8b7455 100644 --- a/soc/espressif/esp32c2/Kconfig +++ b/soc/espressif/esp32c2/Kconfig @@ -15,6 +15,11 @@ config SOC_SERIES_ESP32C2 if SOC_SERIES_ESP32C2 +config SOC_ESP32C2_REV_2_0 + bool "SOC is revision v2.0 (ECO4)" + help + ESP32-C2 revision v2.0 has updated ROM functions. + config MAC_BB_PD bool "Power down MAC and baseband of Wi-Fi and Bluetooth when PHY is disabled" depends on SOC_SERIES_ESP32C2 && TICKLESS_KERNEL diff --git a/soc/espressif/esp32c2/Kconfig.defconfig b/soc/espressif/esp32c2/Kconfig.defconfig index 36604de6fe45c..21877a186a996 100644 --- a/soc/espressif/esp32c2/Kconfig.defconfig +++ b/soc/espressif/esp32c2/Kconfig.defconfig @@ -14,4 +14,7 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0) +config MAIN_STACK_SIZE + default 2048 + endif # SOC_SERIES_ESP32C2 diff --git a/soc/espressif/esp32c2/default.ld b/soc/espressif/esp32c2/default.ld index 8febd61ec627e..0c866ba9332d7 100644 --- a/soc/espressif/esp32c2/default.ld +++ b/soc/espressif/esp32c2/default.ld @@ -59,8 +59,8 @@ MEMORY { #ifdef CONFIG_BOOTLOADER_MCUBOOT mcuboot_hdr (R): org = 0x0, len = 0x20 - metadata (R): org = 0x20, len = 0x20 - FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 #else /* Make safety margin in the FLASH memory size so the * (esp_img_header + (n*esp_seg_headers)) would fit */ @@ -85,8 +85,9 @@ _rom_store_table = 0; _iram_dram_offset = IRAM_DRAM_OFFSET; -/* Used as a pointer to the heap end */ +/* Heap size calculations */ _heap_sentry = DRAM_RESERVED_START; +_libc_heap_size = _heap_sentry - _end; SECTIONS { @@ -124,6 +125,42 @@ SECTIONS LONG(ADDR(.dram0.data)) LONG(LOADADDR(.dram0.data)) LONG(LOADADDR(.dram0.end) - LOADADDR(.dram0.data)) + + /* LP_IRAM metadata - There is no RTC/LP memory! + * 8. Destination address (VMA) for LP_IRAM region + * 9. Flash offset (LMA) for start of LP_IRAM region + * 10. Size of LP_IRAM region + */ + LONG(0x0) + LONG(0x0) + LONG(0x0) + + /* LP_DRAM metadata - There is no RTC/LP memory! + * 11. Destination address (VMA) for LP_DRAM region + * 12. Flash offset (LMA) for start of LP_DRAM region + * 13. Size of LP_DRAM region + */ + LONG(0x0) + LONG(0x0) + LONG(0x0) + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(ADDR(.flash.text)) + LONG(LOADADDR(.flash.text)) + LONG(SIZEOF(.flash.text)) + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(ADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata_end) - LOADADDR(.flash.rodata)) } > metadata #endif /* CONFIG_BOOTLOADER_MCUBOOT */ @@ -175,6 +212,7 @@ SECTIONS *libzephyr.a:console_init.*(.literal .text .literal.* .text.*) *libzephyr.a:soc_init.*(.literal .text .literal.* .text.*) *libzephyr.a:hw_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_random.*(.literal .text .literal.* .text.*) *libarch__riscv__core.a:(.literal .text .literal.* .text.*) *libsubsys__net__l2__ethernet.a:(.literal .text .literal.* .text.*) *libsubsys__net__lib__config.a:(.literal .text .literal.* .text.*) @@ -282,7 +320,7 @@ SECTIONS #if defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) - *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) /* [mapping:esp_wifi] */ *(.literal.wifi_clock_enable_wrapper .text.wifi_clock_enable_wrapper) @@ -320,7 +358,6 @@ SECTIONS *libzephyr.a:esp_image_format.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_ops.*(.literal .text .literal.* .text.*) - *libzephyr.a:flash_ops_esp32c2.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_encrypt.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_partitions.*(.literal .text .literal.* .text.*) @@ -426,6 +463,7 @@ SECTIONS *libzephyr.a:console_init.*(.rodata .rodata.*) *libzephyr.a:soc_init.*(.rodata .rodata.*) *libzephyr.a:hw_init.*(.rodata .rodata.*) + *libzephyr.a:soc_random.*(.rodata .rodata.*) *libzephyr.a:cache_utils.*(.rodata .rodata.* .srodata .srodata.*) /* [mapping:hal] */ @@ -615,6 +653,7 @@ SECTIONS #if !defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) #endif /* CONFIG_ESP32_WIFI_IRAM_OPT */ #if !defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT) diff --git a/soc/espressif/esp32c2/hw_init.c b/soc/espressif/esp32c2/hw_init.c index 3a57704040d66..7ca871282daad 100644 --- a/soc/espressif/esp32c2/hw_init.c +++ b/soc/espressif/esp32c2/hw_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -36,34 +36,18 @@ int hardware_init(void) #ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE esp_cpu_configure_region_protection(); #endif -#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - - if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { - cfg.drefh = 3; - cfg.drefm = 3; - cfg.drefl = 3; - cfg.force = 1; - rtc_vddsdio_set_config(cfg); - esp_rom_delay_us(10); - } -#endif /* CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V */ bootloader_clock_configure(); +#ifdef CONFIG_ESP_CONSOLE /* initialize console, from now on, we can log */ esp_console_init(); print_banner(); - - spi_flash_init_chip_state(); - err = esp_flash_init_default_chip(); - if (err != 0) { - ESP_EARLY_LOGE(TAG, "Failed to init flash chip, error %d", err); - return err; - } +#endif /* CONFIG_ESP_CONSOLE */ cache_hal_init(); mmu_hal_init(); + flash_update_id(); err = bootloader_flash_xmc_startup(); @@ -90,5 +74,7 @@ int hardware_init(void) check_wdt_reset(); config_wdt(); + soc_random_enable(); + return 0; } diff --git a/soc/espressif/esp32c2/mcuboot.ld b/soc/espressif/esp32c2/mcuboot.ld index 54aff6076c4b2..595fce23789e6 100644 --- a/soc/espressif/esp32c2/mcuboot.ld +++ b/soc/espressif/esp32c2/mcuboot.ld @@ -44,22 +44,14 @@ SECTIONS _loader_text_start = ABSOLUTE(.); *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - /* TODO: cross-segments calls in the libzephyr.a:device.* */ - *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*) *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*) *libzephyr.a:cpu.*(.literal .text .literal.* .text.*) *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) - - *libzephyr.a:heap.*(.literal .text .literal.* .text.*) - - *libkernel.a:kheap.*(.literal .text .literal.* .text.*) - *libkernel.a:mempool.*(.literal .text .literal.* .text.*) - + *libkernel.a:device.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) - *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) diff --git a/soc/espressif/esp32c2/memory.h b/soc/espressif/esp32c2/memory.h index c9ca4b5557476..fbf9a7b8f22bf 100644 --- a/soc/espressif/esp32c2/memory.h +++ b/soc/espressif/esp32c2/memory.h @@ -5,13 +5,13 @@ #pragma once /* SRAM0 (16kB) memory */ -#define SRAM0_IRAM_START 0x4037c000 -#define SRAM0_SIZE 0x4000 +#define SRAM0_IRAM_START DT_REG_ADDR(DT_NODELABEL(sram0)) +#define SRAM0_SIZE DT_REG_SIZE(DT_NODELABEL(sram0)) /* SRAM1 (256kB) memory */ -#define SRAM1_DRAM_START 0x3fca0000 -#define SRAM1_IRAM_START 0x40380000 -#define SRAM1_SIZE 0x40000 +#define SRAM1_IRAM_START (SRAM1_DRAM_START + IRAM_DRAM_OFFSET) +#define SRAM1_DRAM_START DT_REG_ADDR(DT_NODELABEL(sram1)) +#define SRAM1_SIZE DT_REG_SIZE(DT_NODELABEL(sram1)) /* ICache size is fixed to 16KB on ESP32-C2 */ #define ICACHE_SIZE SRAM0_SIZE diff --git a/soc/espressif/esp32c2/soc.c b/soc/espressif/esp32c2/soc.c index 9ed4bbcb4370f..f131f5fbfee07 100644 --- a/soc/espressif/esp32c2/soc.c +++ b/soc/espressif/esp32c2/soc.c @@ -1,83 +1,39 @@ /* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2024-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ -/* Include esp-idf headers first to avoid redefining BIT() macro */ -#include -#include -#include -#include -#include -#include -#include "hal/wdt_hal.h" -#include "esp_cpu.h" -#include "hal/soc_hal.h" -#include "hal/cpu_hal.h" -#include "esp_timer.h" -#include "esp_private/system_internal.h" -#include "esp_clk_internal.h" -#include -#include -#include "esp_private/esp_mmu_map_private.h" -#include - +#include +#include +#include +#include +#include +#include #include - #include #include -#include -#include -#include extern void esp_reset_reason_init(void); -/* - * This is written in C rather than assembly since, during the port bring up, - * Zephyr is being booted by the Espressif bootloader. With it, the C stack - * is already set up. - */ -void __attribute__((section(".iram1"))) __esp_platform_start(void) +void IRAM_ATTR __esp_platform_app_start(void) { - __asm__ __volatile__("la t0, _esp32c2_vector_table\n" - "csrw mtvec, t0\n"); - - z_bss_zero(); - - /* Disable normal interrupts. */ - csr_read_clear(mstatus, MSTATUS_MIE); - esp_reset_reason_init(); -#ifndef CONFIG_MCUBOOT - /* ESP-IDF 2nd stage bootloader enables RTC WDT to check on startup sequence - * related issues in application. Hence disable that as we are about to start - * Zephyr environment. - */ - wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; - - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_disable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - - /* Enable wireless phy subsystem clock, - * This needs to be done before the kernel starts - */ - REG_CLR_BIT(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_SDIOSLAVE_EN); - SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); - esp_timer_early_init(); - esp_mspi_pin_init(); + esp_flash_config(); - esp_flash_app_init(); + esp_intr_initialize(); - esp_mmu_map_init(); + /* Start Zephyr */ + z_cstart(); -#endif /* !CONFIG_MCUBOOT */ + CODE_UNREACHABLE; +} - /*Initialize the esp32c2 interrupt controller */ +void IRAM_ATTR __esp_platform_mcuboot_start(void) +{ esp_intr_initialize(); /* Start Zephyr */ diff --git a/soc/espressif/esp32c2/soc.h b/soc/espressif/esp32c2/soc.h index da96d9faf83ac..66a098444b2da 100644 --- a/soc/espressif/esp32c2/soc.h +++ b/soc/espressif/esp32c2/soc.h @@ -18,7 +18,8 @@ #ifndef _ASMLANGUAGE -void __esp_platform_start(void); +void __esp_platform_mcuboot_start(void); +void __esp_platform_app_start(void); static inline uint32_t esp_core_id(void) { diff --git a/soc/espressif/esp32c2/vectors.S b/soc/espressif/esp32c2/vectors.S index e8f8f0213bed2..9299750a525db 100644 --- a/soc/espressif/esp32c2/vectors.S +++ b/soc/espressif/esp32c2/vectors.S @@ -22,12 +22,12 @@ GTEXT(_isr_wrapper) * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). */ - .global _esp32c2_vector_table + .global _esp_vector_table .section .exception_vectors.text .balign 0x100 - .type _esp32c2_vector_table, @function + .type _esp_vector_table, @function -_esp32c2_vector_table: +_esp_vector_table: .option push .option norvc .rept (32) diff --git a/soc/espressif/esp32c3/CMakeLists.txt b/soc/espressif/esp32c3/CMakeLists.txt index bfec91fbc4c94..186cf17af9ba1 100644 --- a/soc/espressif/esp32c3/CMakeLists.txt +++ b/soc/espressif/esp32c3/CMakeLists.txt @@ -14,63 +14,3 @@ zephyr_sources_ifndef(CONFIG_BOOTLOADER_MCUBOOT hw_init.c) zephyr_library_sources_ifdef(CONFIG_PM power.c) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) - -# get flash size to use in esptool as string -math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") - -if(NOT CONFIG_BOOTLOADER_MCUBOOT) - - if(CONFIG_BUILD_OUTPUT_BIN) - # make ESP ROM loader compatible image - message("ESP-IDF path: ${ESP_IDF_PATH}") - - set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) - message("esptool path: ${ESPTOOL_PY}") - - set(ELF2IMAGE_ARG "") - if(NOT CONFIG_MCUBOOT) - set(ELF2IMAGE_ARG "--ram-only-header") - endif() - - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} - ARGS --chip esp32c3 elf2image ${ELF2IMAGE_ARG} - --flash_mode dio --flash_freq 40m --flash_size ${esptoolpy_flashsize}MB - -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf) - endif() - -endif() - -# get code-partition slot0 address -dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") -dt_reg_addr(img_0_off PATH ${dts_partition_path}) - -# get code-partition boot address -dt_nodelabel(dts_partition_path NODELABEL "boot_partition") -dt_reg_addr(boot_off PATH ${dts_partition_path}) - -if(CONFIG_BOOTLOADER_MCUBOOT) - board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") -else() - board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}") -endif() - -if(CONFIG_MCUBOOT) - # search from cross references between bootloader sections - message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND - ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/ci/check_callgraph.py - ARGS - --rtl-dirs ${CMAKE_BINARY_DIR}/zephyr - --elf-file ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf - find-refs --from-section=.iram0.iram_loader --to-section=.iram0.text - --exit-code) -endif() - -if(CONFIG_MCUBOOT) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") -else() - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") -endif() diff --git a/soc/espressif/esp32c3/Kconfig.defconfig b/soc/espressif/esp32c3/Kconfig.defconfig index 43d1d471ab62e..1e9f47ad6a30c 100644 --- a/soc/espressif/esp32c3/Kconfig.defconfig +++ b/soc/espressif/esp32c3/Kconfig.defconfig @@ -12,4 +12,7 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0) +config MAIN_STACK_SIZE + default 2048 + endif # SOC_SERIES_ESP32C3 diff --git a/soc/espressif/esp32c3/default.ld b/soc/espressif/esp32c3/default.ld index 5edb5047f2b2b..4cce6c7f1ebc6 100644 --- a/soc/espressif/esp32c3/default.ld +++ b/soc/espressif/esp32c3/default.ld @@ -59,8 +59,8 @@ MEMORY { #ifdef CONFIG_BOOTLOADER_MCUBOOT mcuboot_hdr (R): org = 0x0, len = 0x20 - metadata (R): org = 0x20, len = 0x20 - FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 #else /* Make safety margin in the FLASH memory size so the * (esp_img_header + (n*esp_seg_headers)) would fit */ @@ -73,19 +73,24 @@ MEMORY irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN drom0_0_seg (R): org = DROM_SEG_ORG, len = DROM_SEG_LEN - rtc_iram_seg(RWX): org = 0x50000000, len = 0x2000 + rtc_iram_seg(RWX): org = 0x50000000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM + + /* We reduced the size of rtc_iram_seg by CONFIG_RESERVE_RTC_MEM value. + It reserves the amount of RTC fast memory that we use for this memory segment. + This segment is intended for keeping: + - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). + The aim of this is to keep data that will not be moved around and have a fixed address. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + rtc_reserved_seg(RW): org = 0x50000000 + 0x2000 - CONFIG_RESERVE_RTC_MEM, + len = CONFIG_RESERVE_RTC_MEM +#endif #ifdef CONFIG_GEN_ISR_TABLES IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 #endif } -/* The line below defines location alias for .rtc.data section - * As C3 only has RTC fast memory, this is not configurable like - * on other targets. - */ -REGION_ALIAS("rtc_slow_seg", rtc_iram_seg); - /* Default entry point: */ ENTRY(CONFIG_KERNEL_ENTRY) @@ -93,8 +98,9 @@ _rom_store_table = 0; _iram_dram_offset = IRAM_DRAM_OFFSET; -/* Stack sentry */ +/* Heap size calculations */ _heap_sentry = DRAM_RESERVED_START; +_libc_heap_size = _heap_sentry - _end; SECTIONS { @@ -132,17 +138,45 @@ SECTIONS LONG(ADDR(.dram0.data)) LONG(LOADADDR(.dram0.data)) LONG(LOADADDR(.dram0.end) - LOADADDR(.dram0.data)) + + /* RTC_IRAM metadata: + * 8. Destination address (VMA) for RTC_IRAM region + * 9. Flash offset (LMA) for start of RTC_IRAM region + * 10. Size of RTC_IRAM region + */ + LONG(ADDR(.rtc.text)) + LONG(LOADADDR(.rtc.text)) + LONG(SIZEOF(.rtc.text)) + + /* RTC_DRAM metadata: + * 11. Destination address (VMA) for RTC_DRAM region + * 12. Flash offset (LMA) for start of RTC_DRAM region + * 13. Size of RTC_DRAM region + */ + LONG(ADDR(.rtc.data)) + LONG(LOADADDR(.rtc.data)) + LONG(SIZEOF(.rtc.data)) + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(ADDR(.flash.text)) + LONG(LOADADDR(.flash.text)) + LONG(SIZEOF(.flash.text)) + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(ADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata_end) - LOADADDR(.flash.rodata)) } > metadata #endif /* CONFIG_BOOTLOADER_MCUBOOT */ - iram_vma = ADDR(.iram0.text); - iram_lma = LOADADDR(.iram0.text); - iram_size_field = LOADADDR(.iram0.data) - LOADADDR(.iram0.text); - - dram_vma = ADDR(.dram0.data); - dram_lma = LOADADDR(.dram0.data); - dram_size_field = LOADADDR(.dram0.end) - LOADADDR(.dram0.data); - #include #ifdef CONFIG_LLEXT @@ -151,38 +185,61 @@ SECTIONS /* --- START OF RTC --- */ + /* RTC fast memory holds RTC wake stub code */ .rtc.text : { . = ALIGN(4); - *(.rtc.literal .rtc.text) - *rtc_wake_stub*.o(.literal .text .literal.* .text.*) + *(.rtc.literal .rtc.literal.*) + *(.rtc.text .rtc.text.*) + . = ALIGN(4); } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) - /* This section is required to skip rtc.text area because the text and - * data segments reflect the same address space on different buses. + /** + * This section located in RTC FAST Memory area. + * It holds data marked with RTC_FAST_ATTR attribute. + * See the file "esp_attr.h" for more information. */ - .rtc.dummy (NOLOAD): + .rtc.force_fast : { - . = SIZEOF(.rtc.text); - } GROUP_LINK_IN(rtc_iram_seg) + . = ALIGN(4); + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) + /** + * RTC data section holds data marked with + * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + * See the file "esp_attr.h" for more information. + */ .rtc.data : { + . = ALIGN(4); _rtc_data_start = ABSOLUTE(.); - *(.rtc.data) - *(.rtc.rodata) - *rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*) - _rtc_data_end = ABSOLUTE(.); + *(.rtc.data .rtc.data.*) + *(.rtc.rodata .rtc.rodata.*) + . = ALIGN(4); } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) .rtc.bss (NOLOAD) : { _rtc_bss_start = ABSOLUTE(.); - *rtc_wake_stub*.o(.bss .bss.*) - *rtc_wake_stub*.o(COMMON) + *(.rtc.bss .rtc.bss.*) _rtc_bss_end = ABSOLUTE(.); } GROUP_LINK_IN(rtc_iram_seg) + /** + * This section holds data that should not be initialized at power up + * and will be retained during deep sleep. + * 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 .rtc_noinit.*) + . = ALIGN(4); + } GROUP_LINK_IN(rtc_iram_seg) + /* This section located in RTC SLOW Memory area. * It holds data marked with RTC_SLOW_ATTR attribute. * See the file "esp_attr.h" for more information. @@ -190,15 +247,28 @@ SECTIONS .rtc.force_slow : { . = ALIGN(4); - _rtc_force_slow_start = ABSOLUTE(.); *(.rtc.force_slow .rtc.force_slow.*) - . = ALIGN(4) ; + . = ALIGN(4); _rtc_force_slow_end = ABSOLUTE(.); - } > rtc_slow_seg + } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) /* Get size of rtc slow data */ _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); + /** + * This section holds RTC data that should have fixed addresses. + * The data are not initialized at power-up and are retained during deep sleep. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + .rtc_reserved (NOLOAD) : + { + . = ALIGN(4); + _rtc_reserved_start = ABSOLUTE(.); + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + _rtc_reserved_end = ABSOLUTE(.); + } GROUP_LINK_IN(rtc_reserved_seg) +#endif + /* --- END OF RTC --- */ /* --- START OF IRAM --- */ @@ -343,7 +413,7 @@ SECTIONS #if defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) - *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) /* [mapping:esp_wifi] */ *(.literal.wifi_clock_enable_wrapper .text.wifi_clock_enable_wrapper) @@ -681,6 +751,7 @@ SECTIONS #if !defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) #endif /* CONFIG_ESP32_WIFI_IRAM_OPT */ #if !defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT) diff --git a/soc/espressif/esp32c3/hw_init.c b/soc/espressif/esp32c3/hw_init.c index 37aacd3bbbda9..f3ecc5f4f6ab7 100644 --- a/soc/espressif/esp32c3/hw_init.c +++ b/soc/espressif/esp32c3/hw_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,34 +38,18 @@ int hardware_init(void) #ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE esp_cpu_configure_region_protection(); #endif -#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - - if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { - cfg.drefh = 3; - cfg.drefm = 3; - cfg.drefl = 3; - cfg.force = 1; - rtc_vddsdio_set_config(cfg); - esp_rom_delay_us(10); - } -#endif /* CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V */ bootloader_clock_configure(); +#ifdef CONFIG_ESP_CONSOLE /* initialize console, from now on, we can log */ esp_console_init(); print_banner(); - - spi_flash_init_chip_state(); - err = esp_flash_init_default_chip(); - if (err != 0) { - ESP_EARLY_LOGE(TAG, "Failed to init flash chip, error %d", err); - return err; - } +#endif /* CONFIG_ESP_CONSOLE */ cache_hal_init(); mmu_hal_init(); + flash_update_id(); err = bootloader_flash_xmc_startup(); diff --git a/soc/espressif/esp32c3/mcuboot.ld b/soc/espressif/esp32c3/mcuboot.ld index cbc727faf0bef..b4dee564e91e1 100644 --- a/soc/espressif/esp32c3/mcuboot.ld +++ b/soc/espressif/esp32c3/mcuboot.ld @@ -44,22 +44,14 @@ SECTIONS _loader_text_start = ABSOLUTE(.); *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - /* TODO: cross-segments calls in the libzephyr.a:device.* */ - *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*) *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*) *libzephyr.a:cpu.*(.literal .text .literal.* .text.*) *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) - - *libzephyr.a:heap.*(.literal .text .literal.* .text.*) - - *libkernel.a:kheap.*(.literal .text .literal.* .text.*) - *libkernel.a:mempool.*(.literal .text .literal.* .text.*) - + *libkernel.a:device.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) - *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) diff --git a/soc/espressif/esp32c3/memory.h b/soc/espressif/esp32c3/memory.h index 97b2068bb45b2..07eab679ad301 100644 --- a/soc/espressif/esp32c3/memory.h +++ b/soc/espressif/esp32c3/memory.h @@ -5,12 +5,12 @@ #pragma once /* SRAM0 (16kB) memory */ -#define SRAM0_IRAM_START 0x4037c000 -#define SRAM0_SIZE 0x4000 +#define SRAM0_IRAM_START DT_REG_ADDR(DT_NODELABEL(sram0)) +#define SRAM0_SIZE DT_REG_SIZE(DT_NODELABEL(sram0)) /* SRAM1 (384kB) memory */ -#define SRAM1_DRAM_START 0x3fc80000 -#define SRAM1_IRAM_START 0x40380000 -#define SRAM1_SIZE 0x60000 +#define SRAM1_DRAM_START DT_REG_ADDR(DT_NODELABEL(sram1)) +#define SRAM1_IRAM_START (SRAM1_DRAM_START + IRAM_DRAM_OFFSET) +#define SRAM1_SIZE DT_REG_SIZE(DT_NODELABEL(sram1)) /* ICache size is fixed to 16KB on ESP32-C3 */ #define ICACHE_SIZE SRAM0_SIZE @@ -47,7 +47,7 @@ #define BOOTLOADER_STACK_OVERHEAD 0x0 /* These lengths can be adjusted, if necessary: */ #define BOOTLOADER_DRAM_SEG_LEN 0x9800 -#define BOOTLOADER_IRAM_SEG_LEN 0x9800 +#define BOOTLOADER_IRAM_SEG_LEN 0x9C00 #define BOOTLOADER_IRAM_LOADER_SEG_LEN 0x1400 /* Start of the lower region is determined by region size and the end of the higher region */ diff --git a/soc/espressif/esp32c3/soc.c b/soc/espressif/esp32c3/soc.c index aa21357e72876..7541530eec02e 100644 --- a/soc/espressif/esp32c3/soc.c +++ b/soc/espressif/esp32c3/soc.c @@ -1,83 +1,40 @@ /* * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2025 Espressif Systems (Shanghai) CO LTD. * * SPDX-License-Identifier: Apache-2.0 */ -/* Include esp-idf headers first to avoid redefining BIT() macro */ -#include -#include -#include -#include -#include -#include -#include "hal/wdt_hal.h" -#include "esp_cpu.h" -#include "hal/soc_hal.h" -#include "hal/cpu_hal.h" -#include "esp_timer.h" -#include "esp_private/system_internal.h" -#include "esp_clk_internal.h" -#include -#include -#include "esp_private/esp_mmu_map_private.h" -#include - +#include +#include +#include +#include +#include +#include #include - #include #include -#include -#include -#include extern void esp_reset_reason_init(void); -/* - * This is written in C rather than assembly since, during the port bring up, - * Zephyr is being booted by the Espressif bootloader. With it, the C stack - * is already set up. - */ -void __attribute__((section(".iram1"))) __esp_platform_start(void) +void IRAM_ATTR __esp_platform_app_start(void) { - __asm__ __volatile__("la t0, _esp32c3_vector_table\n" - "csrw mtvec, t0\n"); - - z_bss_zero(); - - /* Disable normal interrupts. */ - csr_read_clear(mstatus, MSTATUS_MIE); - esp_reset_reason_init(); -#ifndef CONFIG_MCUBOOT - /* ESP-IDF 2nd stage bootloader enables RTC WDT to check on startup sequence - * related issues in application. Hence disable that as we are about to start - * Zephyr environment. - */ - wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; - - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_disable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - - /* Enable wireless phy subsystem clock, - * This needs to be done before the kernel starts - */ - REG_CLR_BIT(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_SDIOSLAVE_EN); - SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN); - esp_timer_early_init(); - esp_mspi_pin_init(); + esp_flash_config(); - esp_flash_app_init(); + esp_intr_initialize(); - esp_mmu_map_init(); + /* Start Zephyr */ + z_cstart(); -#endif /* !CONFIG_MCUBOOT */ + CODE_UNREACHABLE; +} - /*Initialize the esp32c3 interrupt controller */ +void IRAM_ATTR __esp_platform_mcuboot_start(void) +{ esp_intr_initialize(); /* Start Zephyr */ diff --git a/soc/espressif/esp32c3/soc.h b/soc/espressif/esp32c3/soc.h index 73e2fbfee1ead..192d0aaf6fc97 100644 --- a/soc/espressif/esp32c3/soc.h +++ b/soc/espressif/esp32c3/soc.h @@ -18,7 +18,8 @@ #ifndef _ASMLANGUAGE -void __esp_platform_start(void); +void __esp_platform_mcuboot_start(void); +void __esp_platform_app_start(void); static inline uint32_t esp_core_id(void) { diff --git a/soc/espressif/esp32c3/vectors.S b/soc/espressif/esp32c3/vectors.S index 570740469eb11..629ce21ff0d82 100644 --- a/soc/espressif/esp32c3/vectors.S +++ b/soc/espressif/esp32c3/vectors.S @@ -22,12 +22,12 @@ GTEXT(_isr_wrapper) * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). */ - .global _esp32c3_vector_table + .global _esp_vector_table .section .exception_vectors.text .balign 0x100 - .type _esp32c3_vector_table, @function + .type _esp_vector_table, @function -_esp32c3_vector_table: +_esp_vector_table: .option push .option norvc .rept (32) diff --git a/soc/espressif/esp32c6/CMakeLists.txt b/soc/espressif/esp32c6/CMakeLists.txt index 6bd5b99e6ff53..186cf17af9ba1 100644 --- a/soc/espressif/esp32c6/CMakeLists.txt +++ b/soc/espressif/esp32c6/CMakeLists.txt @@ -14,63 +14,3 @@ zephyr_sources_ifndef(CONFIG_BOOTLOADER_MCUBOOT hw_init.c) zephyr_library_sources_ifdef(CONFIG_PM power.c) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) - -# get flash size to use in esptool as string -math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") - -if(NOT CONFIG_BOOTLOADER_MCUBOOT) - - if(CONFIG_BUILD_OUTPUT_BIN) - # make ESP ROM loader compatible image - message("ESP-IDF path: ${ESP_IDF_PATH}") - - set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) - message("esptool path: ${ESPTOOL_PY}") - - set(ELF2IMAGE_ARG "") - if(NOT CONFIG_MCUBOOT) - set(ELF2IMAGE_ARG "--ram-only-header") - endif() - - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} - ARGS --chip esp32c6 elf2image ${ELF2IMAGE_ARG} - --flash_mode dio --flash_freq 40m --flash_size ${esptoolpy_flashsize}MB - -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf) - endif() - -endif() - -# get code-partition slot0 address -dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") -dt_reg_addr(img_0_off PATH ${dts_partition_path}) - -# get code-partition boot address -dt_nodelabel(dts_partition_path NODELABEL "boot_partition") -dt_reg_addr(boot_off PATH ${dts_partition_path}) - -if(CONFIG_BOOTLOADER_MCUBOOT) - board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") -else() - board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}") -endif() - -if(CONFIG_MCUBOOT) - # search from cross references between bootloader sections - message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND - ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/ci/check_callgraph.py - ARGS - --rtl-dirs ${CMAKE_BINARY_DIR}/zephyr - --elf-file ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf - find-refs --from-section=.iram0.iram_loader --to-section=.iram0.text - --exit-code) -endif() - -if(CONFIG_MCUBOOT) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") -else() - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") -endif() diff --git a/soc/espressif/esp32c6/Kconfig.defconfig b/soc/espressif/esp32c6/Kconfig.defconfig index feb27615d9fe6..69a04a39a37be 100644 --- a/soc/espressif/esp32c6/Kconfig.defconfig +++ b/soc/espressif/esp32c6/Kconfig.defconfig @@ -14,4 +14,7 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_node_reg_addr_hex,/soc/flash-controller@60002000/flash@0) +config MAIN_STACK_SIZE + default 2048 + endif # SOC_SERIES_ESP32C6 diff --git a/soc/espressif/esp32c6/default.ld b/soc/espressif/esp32c6/default.ld index 9716efc299326..ea24cf1abffdc 100644 --- a/soc/espressif/esp32c6/default.ld +++ b/soc/espressif/esp32c6/default.ld @@ -48,16 +48,13 @@ user_sram_size = (user_sram_end - user_sram_org); #undef SECTION_PROLOGUE #define SECTION_PROLOGUE SECTION_DATA_PROLOGUE -/* TODO: add RTC support */ -#define RESERVE_RTC_MEM 0 - /* Global symbols required for espressif hal build */ MEMORY { #ifdef CONFIG_BOOTLOADER_MCUBOOT mcuboot_hdr (R): org = 0x0, len = 0x20 - metadata (R): org = 0x20, len = 0x20 - FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 #else /* Make safety margin in the FLASH memory size so the * (esp_img_header + (n*esp_seg_headers)) would fit */ @@ -70,10 +67,19 @@ MEMORY drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN lp_ram_seg(RW): org = LPSRAM_IRAM_START, - len = 0x2000 - RESERVE_RTC_MEM - - lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x2000 - RESERVE_RTC_MEM, - len = RESERVE_RTC_MEM + len = 0x4000 - CONFIG_RESERVE_RTC_MEM + + /* We reduced the size of lp_ram_seg by CONFIG_RESERVE_RTC_MEM value. + It reserves the amount of LP memory that we use for this memory segment. + This segment is intended for keeping: + - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). + - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). + The aim of this is to keep data that will not be moved around and have a fixed address. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + lp_reserved_seg(RW) : org = LPSRAM_IRAM_START + 0x4000 - CONFIG_RESERVE_RTC_MEM, + len = CONFIG_RESERVE_RTC_MEM +#endif #ifdef CONFIG_GEN_ISR_TABLES IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 @@ -90,12 +96,13 @@ REGION_ALIAS("rtc_iram_seg", lp_ram_seg ); REGION_ALIAS("rtc_data_seg", rtc_iram_seg ); REGION_ALIAS("rtc_slow_seg", rtc_iram_seg ); REGION_ALIAS("rtc_data_location", rtc_iram_seg ); -REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg ); /* Default entry point: */ ENTRY(CONFIG_KERNEL_ENTRY) +/* Heap size calculations */ _heap_sentry = DRAM_RESERVED_START; +_libc_heap_size = _heap_sentry - _end; SECTIONS { @@ -133,6 +140,42 @@ SECTIONS LONG(ADDR(.dram0.data)) LONG(LOADADDR(.dram0.data)) LONG(LOADADDR(.dram0.end) - LOADADDR(.dram0.data)) + + /* LP_IRAM metadata: + * 8. Destination address (VMA) for LP_IRAM region + * 9. Flash offset (LMA) for start of LP_IRAM region + * 10. Size of LP_IRAM region + */ + LONG(ADDR(.rtc.text)) + LONG(LOADADDR(.rtc.text)) + LONG(SIZEOF(.rtc.text)) + + /* LP_DATA metadata: + * 11. Destination address (VMA) for LP_DRAM region + * 12. Flash offset (LMA) for start of LP_DRAM region + * 13. Size of LP_DRAM region + */ + LONG(ADDR(.rtc.data)) + LONG(LOADADDR(.rtc.data)) + LONG(SIZEOF(.rtc.data)) + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(ADDR(.flash.text)) + LONG(LOADADDR(.flash.text)) + LONG(SIZEOF(.flash.text)) + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(ADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata_end) - LOADADDR(.flash.rodata)) } > metadata #endif /* CONFIG_BOOTLOADER_MCUBOOT */ @@ -150,12 +193,10 @@ SECTIONS _rtc_fast_start = ABSOLUTE(.); _rtc_text_start = ABSOLUTE(.); *(.rtc.entry.text) - *(.rtc.literal .rtc.text) - *rtc_wake_stub*.o(.literal .text .literal.* .text.*) + *(.rtc.literal .rtc.literal.* .rtc.text .rtc.text.*) . = ALIGN(4); - _rtc_text_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) /* This section located in RTC FAST Memory area. * It holds data marked with RTC_FAST_ATTR attribute. @@ -167,9 +208,9 @@ SECTIONS _rtc_force_fast_start = ABSOLUTE(.); *(.rtc.force_fast .rtc.force_fast.*) - . = ALIGN(4) ; + . = ALIGN(4); _rtc_force_fast_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION) + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) /* RTC data section holds data marked with * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. @@ -177,34 +218,31 @@ SECTIONS .rtc.data : { _rtc_data_start = ABSOLUTE(.); - *(.rtc.data) - *(.rtc.rodata) + *(.rtc.data .rtc.data.*) + *(.rtc.rodata .rtc.rodata.*) _rtc_data_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) .rtc.bss (NOLOAD) : { _rtc_bss_start = ABSOLUTE(.); - - *(.rtc.data) - *(.rtc.rodata) - + *(.rtc.bss .rtc.bss.*) _rtc_bss_end = ABSOLUTE(.); - } GROUP_LINK_IN(rtc_iram_seg) + } GROUP_LINK_IN(lp_ram_seg) /* This section holds data that should not be initialized at power up * and will be retained during deep sleep. * 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): + .rtc_noinit (NOLOAD) : { . = ALIGN(4); _rtc_noinit_start = ABSOLUTE(.); *(.rtc_noinit .rtc_noinit.*) . = ALIGN(4) ; _rtc_noinit_end = ABSOLUTE(.); - } GROUP_LINK_IN(rtc_slow_seg) + } GROUP_LINK_IN(lp_ram_seg) /* This section located in RTC SLOW Memory area. * It holds data marked with RTC_SLOW_ATTR attribute. @@ -217,24 +255,21 @@ SECTIONS *(.rtc.force_slow .rtc.force_slow.*) . = ALIGN(4); _rtc_force_slow_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION) + } GROUP_DATA_LINK_IN(lp_ram_seg, ROMABLE_REGION) /** * This section holds RTC data that should have fixed addresses. * The data are not initialized at power-up and are retained during deep sleep. */ - .rtc_reserved (NOLOAD): +#if (CONFIG_RESERVE_RTC_MEM > 0) + .rtc_reserved (NOLOAD) : { . = ALIGN(4); _rtc_reserved_start = ABSOLUTE(.); - /* New data can only be added here to ensure existing data are not moved. - Because data have adhered to the end of the segment and code is relied on it. - >> put new data here << */ - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) _rtc_reserved_end = ABSOLUTE(.); - } GROUP_LINK_IN(rtc_reserved_seg) + } GROUP_LINK_IN(lp_reserved_seg) +#endif /* Get size of rtc slow data based on rtc_data_location alias */ _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); @@ -395,7 +430,7 @@ SECTIONS #if defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.* .wifi_extra_iram.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.* .wifi_extra_iram.*) - *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) /* [mapping:esp_wifi] */ *(.literal.wifi_clock_enable_wrapper .text.wifi_clock_enable_wrapper) @@ -743,6 +778,7 @@ SECTIONS #if !defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.* .wifi_extra_iram.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.* .wifi_extra_iram.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) #endif /* CONFIG_ESP32_WIFI_IRAM_OPT */ #if !defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT) diff --git a/soc/espressif/esp32c6/hw_init.c b/soc/espressif/esp32c6/hw_init.c index e4fc9b34d9e78..3eaf036e68e77 100644 --- a/soc/espressif/esp32c6/hw_init.c +++ b/soc/espressif/esp32c6/hw_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -54,31 +54,14 @@ int hardware_init(void) #ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE esp_cpu_configure_region_protection(); #endif -#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - - if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { - cfg.drefh = 3; - cfg.drefm = 3; - cfg.drefl = 3; - cfg.force = 1; - rtc_vddsdio_set_config(cfg); - esp_rom_delay_us(10); - } -#endif /* CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V */ bootloader_clock_configure(); +#ifdef CONFIG_ESP_CONSOLE /* initialize console, from now on, we can log */ esp_console_init(); print_banner(); - - spi_flash_init_chip_state(); - err = esp_flash_init_default_chip(); - if (err != 0) { - ESP_EARLY_LOGE(TAG, "Failed to init flash chip, error %d", err); - return err; - } +#endif /* CONFIG_ESP_CONSOLE */ cache_hal_init(); mmu_hal_init(); diff --git a/soc/espressif/esp32c6/mcuboot.ld b/soc/espressif/esp32c6/mcuboot.ld index 8c76315ffe331..da247e2241b0c 100644 --- a/soc/espressif/esp32c6/mcuboot.ld +++ b/soc/espressif/esp32c6/mcuboot.ld @@ -50,14 +50,8 @@ SECTIONS *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) - - *libzephyr.a:heap.*(.literal .text .literal.* .text.*) - - *libkernel.a:kheap.*(.literal .text .literal.* .text.*) - *libkernel.a:mempool.*(.literal .text .literal.* .text.*) - + *libkernel.a:device.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) - *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) diff --git a/soc/espressif/esp32c6/memory.h b/soc/espressif/esp32c6/memory.h index 95fbc21fa1dc7..455c62aba03b4 100644 --- a/soc/espressif/esp32c6/memory.h +++ b/soc/espressif/esp32c6/memory.h @@ -5,13 +5,13 @@ #pragma once /* LP-SRAM (16kB) memory */ -#define LPSRAM_IRAM_START 0x50000000 -#define LPSRAM_SIZE 0x4000 +#define LPSRAM_IRAM_START DT_REG_ADDR(DT_NODELABEL(sramlp)) +#define LPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramlp)) /* HP-SRAM (512kB) memory */ -#define HPSRAM_START 0x40800000 -#define HPSRAM_SIZE 0x80000 -#define HPSRAM_DRAM_START 0x40800000 -#define HPSRAM_IRAM_START 0x40800000 +#define HPSRAM_START DT_REG_ADDR(DT_NODELABEL(sramhp)) +#define HPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramhp)) +#define HPSRAM_DRAM_START HPSRAM_START +#define HPSRAM_IRAM_START HPSRAM_START /* ICache size is fixed to 32KB on ESP32-C6 */ #define ICACHE_SIZE 0x8000 diff --git a/soc/espressif/esp32c6/soc.c b/soc/espressif/esp32c6/soc.c index 1c8877d85416a..8fdd8b71e5fd5 100644 --- a/soc/espressif/esp32c6/soc.c +++ b/soc/espressif/esp32c6/soc.c @@ -1,73 +1,39 @@ /* - * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2023-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ -/* Include esp-idf headers first to avoid redefining BIT() macro */ -#include -#include -#include -#include -#include "hal/wdt_hal.h" -#include "esp_cpu.h" -#include "hal/soc_hal.h" -#include "hal/cpu_hal.h" -#include "esp_timer.h" -#include "esp_private/system_internal.h" -#include "esp_clk_internal.h" -#include -#include -#include "esp_private/esp_mmu_map_private.h" -#include - +#include +#include +#include +#include +#include +#include #include - #include #include -#include -#include -#include - -/* - * This is written in C rather than assembly since, during the port bring up, - * Zephyr is being booted by the Espressif bootloader. With it, the C stack - * is already set up. - */ -void IRAM_ATTR __esp_platform_start(void) -{ - __asm__ __volatile__("la t0, _esp32c6_vector_table\n" - "csrw mtvec, t0\n"); - - z_bss_zero(); - /* Disable normal interrupts. */ - csr_read_clear(mstatus, MSTATUS_MIE); +extern void esp_reset_reason_init(void); +void IRAM_ATTR __esp_platform_app_start(void) +{ esp_reset_reason_init(); -#ifndef CONFIG_MCUBOOT - /* ESP-IDF 2nd stage bootloader enables RTC WDT to check on startup sequence - * related issues in application. Hence disable that as we are about to start - * Zephyr environment. - */ - wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; - - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_disable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - esp_timer_early_init(); - esp_mspi_pin_init(); + esp_flash_config(); - esp_flash_app_init(); + esp_intr_initialize(); - esp_mmu_map_init(); + /* Start Zephyr */ + z_cstart(); -#endif /* !CONFIG_MCUBOOT */ + CODE_UNREACHABLE; +} - /*Initialize the esp32c6 interrupt controller */ +void IRAM_ATTR __esp_platform_mcuboot_start(void) +{ esp_intr_initialize(); /* Start Zephyr */ diff --git a/soc/espressif/esp32c6/soc.h b/soc/espressif/esp32c6/soc.h index bfa5644977751..4cbae49783564 100644 --- a/soc/espressif/esp32c6/soc.h +++ b/soc/espressif/esp32c6/soc.h @@ -27,7 +27,8 @@ #ifndef _ASMLANGUAGE -void __esp_platform_start(void); +void __esp_platform_mcuboot_start(void); +void __esp_platform_app_start(void); static inline uint32_t esp_core_id(void) { diff --git a/soc/espressif/esp32c6/vectors.S b/soc/espressif/esp32c6/vectors.S index d248c0b49b51c..3ad3ae6d79095 100644 --- a/soc/espressif/esp32c6/vectors.S +++ b/soc/espressif/esp32c6/vectors.S @@ -22,12 +22,12 @@ GTEXT(_isr_wrapper) * only uses the 24 MSBs of the MTVEC, i.e. (MTVEC & 0xffffff00). */ - .global _esp32c6_vector_table + .global _esp_vector_table .section .exception_vectors.text .balign 0x100 - .type _esp32c6_vector_table, @function + .type _esp_vector_table, @function -_esp32c6_vector_table: +_esp_vector_table: .option push .option norvc .rept (32) diff --git a/soc/espressif/esp32s2/CMakeLists.txt b/soc/espressif/esp32s2/CMakeLists.txt index ef1d907a64c8b..6cae59aed5b65 100644 --- a/soc/espressif/esp32s2/CMakeLists.txt +++ b/soc/espressif/esp32s2/CMakeLists.txt @@ -14,64 +14,3 @@ zephyr_library_sources_ifdef(CONFIG_NEWLIB_LIBC newlib_fix.c) zephyr_library_sources_ifdef(CONFIG_PM power.c) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) - -# get flash size to use in esptool as string -math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") - -if(NOT CONFIG_BOOTLOADER_MCUBOOT) - - if(CONFIG_BUILD_OUTPUT_BIN) - # make ESP ROM loader compatible image - message("ESP-IDF path: ${ESP_IDF_PATH}") - - set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) - message("esptool path: ${ESPTOOL_PY}") - - set(ELF2IMAGE_ARG "") - if(NOT CONFIG_MCUBOOT) - set(ELF2IMAGE_ARG "--ram-only-header") - endif() - - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} - ARGS --chip esp32s2 elf2image ${ELF2IMAGE_ARG} - --flash_mode dio --flash_freq 40m - --flash_size ${esptoolpy_flashsize}MB - -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf) - endif() - -endif() - -# Get code-partition boot address -dt_nodelabel(dts_partition_path NODELABEL "boot_partition") -dt_reg_addr(boot_off PATH ${dts_partition_path}) - -# Get code-partition slot0 address -dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") -dt_reg_addr(img_0_off PATH ${dts_partition_path}) - -if(CONFIG_BOOTLOADER_MCUBOOT) - board_finalize_runner_args(esp32 "--esp-app-address=${img_0_off}") -else() - board_finalize_runner_args(esp32 "--esp-app-address=${boot_off}") -endif() - -if(CONFIG_MCUBOOT) - # search from cross references between bootloader sections - message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND - ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/ci/check_callgraph.py - ARGS - --rtl-dirs ${CMAKE_BINARY_DIR}/zephyr - --elf-file ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf - find-refs --from-section=.iram0.iram_loader --to-section=.iram0.text - --exit-code) -endif() - -if(CONFIG_MCUBOOT) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") -else() - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") -endif() diff --git a/soc/espressif/esp32s2/Kconfig.defconfig b/soc/espressif/esp32s2/Kconfig.defconfig index ec58addff6741..d79c78ba97276 100644 --- a/soc/espressif/esp32s2/Kconfig.defconfig +++ b/soc/espressif/esp32s2/Kconfig.defconfig @@ -9,4 +9,7 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_node_reg_addr_hex,/soc/flash-controller@3f402000/flash@0) +config MAIN_STACK_SIZE + default 2048 + endif # SOC_SERIES_ESP32S2 diff --git a/soc/espressif/esp32s2/default.ld b/soc/espressif/esp32s2/default.ld index eaaeee11b0320..a9ca15c0dca18 100644 --- a/soc/espressif/esp32s2/default.ld +++ b/soc/espressif/esp32s2/default.ld @@ -55,14 +55,12 @@ user_dram_seg_len = user_sram_size; #undef SECTION_PROLOGUE #define SECTION_PROLOGUE SECTION_DATA_PROLOGUE -#define RESERVE_RTC_MEM 0 - MEMORY { #ifdef CONFIG_BOOTLOADER_MCUBOOT mcuboot_hdr (R): org = 0x0, len = 0x20 - metadata (R): org = 0x20, len = 0x20 - FLASH (R): org = 0x40, len = FLASH_SIZE + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 #else /* Make safety margin in the FLASH memory size so the * (esp_img_header + (n*esp_seg_headers)) would fit */ @@ -75,20 +73,24 @@ MEMORY irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN - rtc_iram_seg(RWX): org = 0x40070000, len = 0x2000 - RESERVE_RTC_MEM + rtc_iram_seg(RWX): org = 0x40070000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM rtc_slow_seg(RW): org = 0x50000000, len = 0x2000 - /* RTC fast memory (same block as above, rtc_iram_seg), viewed from data bus */ - rtc_data_seg(RW) : org = 0x3ff9e000, len = 0x2000 - RESERVE_RTC_MEM - /* We reduced the size of rtc_data_seg and rtc_iram_seg by RESERVE_RTC_MEM value. - * It reserves the amount of RTC fast memory that we use for this memory segment. - * This segment is intended for keeping: - * - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). - * - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). - * The aim of this is to keep data that will not be moved around and have a fixed address. - */ - rtc_reserved_seg(RW) : org = 0x3ff9e000 + 0x2000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM + rtc_data_seg(RW) : org = 0x3ff9e000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM + + /* We reduced the size of rtc_data_seg and rtc_iram_seg by CONFIG_RESERVE_RTC_MEM value. + It reserves the amount of RTC fast memory that we use for this memory segment. + This segment is intended for keeping: + - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). + - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). + The aim of this is to keep data that will not be moved around and have a fixed address. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + rtc_reserved_seg(RW): org = 0x3ff9e000 + 0x2000 - CONFIG_RESERVE_RTC_MEM, + len = CONFIG_RESERVE_RTC_MEM +#endif + #ifdef CONFIG_ESP_SPIRAM - ext_data_ram_seg(RW): org = 0x3f800000, len = CONFIG_ESP_SPIRAM_SIZE /* OR 0x780000 */ + ext_ram_seg(RW): org = 0x3f800000, len = CONFIG_ESP_SPIRAM_SIZE /* OR 0x780000 */ #endif /* CONFIG_ESP_SPIRAM */ #ifdef CONFIG_GEN_ISR_TABLES @@ -103,6 +105,7 @@ _rom_store_table = 0; /* Used as a pointer to the heap end */ _heap_sentry = DRAM_RESERVED_START; +_libc_heap_size = _heap_sentry - _end; SECTIONS { @@ -142,6 +145,42 @@ SECTIONS LONG(ADDR(.dram0.data)) LONG(LOADADDR(.dram0.data)) LONG(LOADADDR(.dram0.data_end) - LOADADDR(.dram0.data)) + + /* RTC_IRAM metadata: + * 8. Destination address (VMA) for RTC_IRAM region + * 9. Flash offset (LMA) for start of RTC_IRAM region + * 10. Size of RTC_IRAM region + */ + LONG(ADDR(.rtc.text)) + LONG(LOADADDR(.rtc.text)) + LONG(SIZEOF(.rtc.text)) + + /* RTC_DRAM metadata: + * 11. Destination address (VMA) for RTC_DRAM region + * 12. Flash offset (LMA) for start of RTC_DRAM region + * 13. Size of RTC_DRAM region + */ + LONG(ADDR(.rtc.data)) + LONG(LOADADDR(.rtc.data)) + LONG(SIZEOF(.rtc.data)) + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(ADDR(.flash.text)) + LONG(LOADADDR(.flash.text)) + LONG(SIZEOF(.flash.text)) + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(ADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata_end) - LOADADDR(.flash.rodata)) } > metadata #endif /* CONFIG_BOOTLOADER_MCUBOOT */ @@ -154,128 +193,90 @@ SECTIONS /* --- START OF RTC --- */ - /* RTC fast memory holds RTC wake stub code, - * including from any source file named rtc_wake_stub*.c - */ .rtc.text : { - _rtc_text_start = ABSOLUTE(.); . = ALIGN(4); - - _rtc_code_start = .; - - /* mapping[rtc_text] */ - - *rtc_wake_stub*.*(.literal .text .literal.* .text.*) - _rtc_code_end = .; - - /* possibly align + add 16B for CPU dummy speculative instr. fetch */ - . = ((_rtc_code_end - _rtc_code_start) == 0) ? ALIGN(0) : ALIGN(4) + 16; - - _rtc_text_end = ABSOLUTE(.); + *(.rtc.literal .rtc.literal.*) + *(.rtc.text .rtc.text.*) + . = ALIGN(4); } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) /* - * This section is required to skip rtc.text area because rtc_iram_seg and - * rtc_data_seg are reflect the same address space on different buses. - */ + This section is required to skip rtc.text area because rtc_iram_seg and + rtc_data_seg reflect the same address space on different buses. + */ .rtc.dummy : { - _rtc_dummy_start = ABSOLUTE(.); - _rtc_fast_start = ABSOLUTE(.); . = SIZEOF(.rtc.text); - _rtc_dummy_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) + } GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION) /* This section located in RTC FAST Memory area. - * It holds data marked with RTC_FAST_ATTR attribute. - * See the file "esp_attr.h" for more information. - */ + It holds data marked with RTC_FAST_ATTR attribute. + See the file "esp_attr.h" for more information. + */ .rtc.force_fast : { . = ALIGN(4); - _rtc_force_fast_start = ABSOLUTE(.); - - /* mapping[rtc_force_fast] */ - *(.rtc.force_fast .rtc.force_fast.*) - . = ALIGN(4) ; - _rtc_force_fast_end = ABSOLUTE(.); - } > rtc_data_seg + . = ALIGN(4); + } GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION) /* RTC data section holds RTC wake stub - * data/rodata, including from any source file - * named rtc_wake_stub*.c and the data marked with - * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. - */ + data/rodata, including from any source file + named rtc_wake_stub*.c and the data marked with + RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + */ .rtc.data : { + . = ALIGN(4); _rtc_data_start = ABSOLUTE(.); + *(.rtc.data .rtc.data.*) + *(.rtc.rodata .rtc.rodata.*) + . = ALIGN(4); + } GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION) - /* mapping[rtc_data] */ - - *rtc_wake_stub*.*(.data .rodata .data.* .rodata.*) - _rtc_data_end = ABSOLUTE(.); - } > rtc_data_seg - - /* RTC bss, from any source file named rtc_wake_stub*.c */ .rtc.bss (NOLOAD) : { _rtc_bss_start = ABSOLUTE(.); - *rtc_wake_stub*.*(.bss .bss.*) - *rtc_wake_stub*.*(COMMON) - - /* mapping[rtc_bss] */ - + *(.rtc.bss .rtc.bss.*) _rtc_bss_end = ABSOLUTE(.); - } > rtc_data_seg + } GROUP_LINK_IN(rtc_slow_seg) - /* This section holds data that should not be initialized at power up - * and will be retained during deep sleep. - * 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): + .rtc_noinit (NOLOAD) : { . = ALIGN(4); - _rtc_noinit_start = ABSOLUTE(.); *(.rtc_noinit .rtc_noinit.*) . = ALIGN(4) ; - _rtc_noinit_end = ABSOLUTE(.); - } > rtc_data_seg + } GROUP_LINK_IN(rtc_slow_seg) /* This section located in RTC SLOW Memory area. - * It holds data marked with RTC_SLOW_ATTR attribute. - * See the file "esp_attr.h" for more information. + * It holds data marked with RTC_SLOW_ATTR attribute. + * See the file "esp_attr.h" for more information. */ .rtc.force_slow : { . = ALIGN(4); - _rtc_force_slow_start = ABSOLUTE(.); *(.rtc.force_slow .rtc.force_slow.*) - . = ALIGN(4) ; + . = ALIGN(4); _rtc_force_slow_end = ABSOLUTE(.); - } > rtc_slow_seg + } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) + + /* Get size of rtc slow data */ + _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); /** * This section holds RTC data that should have fixed addresses. * The data are not initialized at power-up and are retained during deep sleep. */ - .rtc_reserved (NOLOAD): +#if (CONFIG_RESERVE_RTC_MEM > 0) + .rtc_reserved (NOLOAD) : { . = ALIGN(4); _rtc_reserved_start = ABSOLUTE(.); - /* New data can only be added here to ensure existing data are not moved. - Because data have adhered to the end of the segment and code is relied on it. - >> put new data here << */ - *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) - KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) _rtc_reserved_end = ABSOLUTE(.); - } > rtc_reserved_seg - - /* Get size of rtc slow data */ - _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); + } GROUP_LINK_IN(rtc_reserved_seg) +#endif /* --- END OF RTC --- */ @@ -449,7 +450,7 @@ SECTIONS #if defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:(.wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:(.wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiorslpiram .wifiorslpiram.* .wifiextrairam .wifiextrairam.*) - *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) /* [mapping:esp_wifi] */ *(.literal.wifi_clock_enable_wrapper .text.wifi_clock_enable_wrapper) @@ -779,17 +780,11 @@ SECTIONS #ifdef CONFIG_ESP_SPIRAM /* This section holds .ext_ram.bss data, and will be put in PSRAM */ - .ext_ram.bss (NOLOAD): + .ext_ram (NOLOAD): { - _ext_ram_data_start = ABSOLUTE(.); - _ext_ram_bss_start = ABSOLUTE(.); - *(.ext_ram.bss*) - . = ALIGN(4); - _ext_ram_bss_end = ABSOLUTE(.); - } > ext_data_ram_seg + _ext_ram_start = ABSOLUTE(.); + _ext_ram_noinit_start = ABSOLUTE(.); - .ext_ram_noinit (NOLOAD) : - { #ifdef CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM *libdrivers__wifi.a:(.noinit .noinit.*) *libsubsys__net__l2__ethernet.a:(.noinit .noinit.*) @@ -797,12 +792,26 @@ SECTIONS *libsubsys__net__ip.a:(.noinit .noinit.*) *libsubsys__net.a:(.noinit .noinit.*) #endif /* CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM */ + . = ALIGN(16); + + *(.ext_ram_noinit*) + *(.ext_ram_noinit.*) + + . = ALIGN(16); + _ext_ram_noinit_end = ABSOLUTE(.); + + _ext_ram_bss_start = ABSOLUTE(.); + + *(.ext_ram.bss*) + + . = ALIGN(16); + _ext_ram_bss_end = ABSOLUTE(.); _spiram_heap_start = ABSOLUTE(.); . += CONFIG_ESP_SPIRAM_HEAP_SIZE; - _ext_ram_data_end = ABSOLUTE(.); - } > ext_data_ram_seg + _ext_ram_end = ABSOLUTE(.); + } GROUP_LINK_IN(ext_ram_seg) #endif /* CONFIG_ESP_SPIRAM */ .dram0.noinit (NOLOAD) : @@ -843,7 +852,7 @@ SECTIONS #if !defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiorslpiram .wifiorslpiram.* .wifiextrairam .wifiextrairam.*) - + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) #endif #if !defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT) @@ -1002,6 +1011,6 @@ SECTIONS /* --- XTENSA GLUE AND DEBUG END --- */ #ifdef CONFIG_ESP_SPIRAM -ASSERT(((_ext_ram_data_end - _ext_ram_data_start) <= CONFIG_ESP_SPIRAM_SIZE), +ASSERT(((_ext_ram_end - _ext_ram_start) <= CONFIG_ESP_SPIRAM_SIZE), "External SPIRAM overflowed.") #endif /* CONFIG_ESP_SPIRAM */ diff --git a/soc/espressif/esp32s2/hw_init.c b/soc/espressif/esp32s2/hw_init.c index e538124555966..abed31dd22006 100644 --- a/soc/espressif/esp32s2/hw_init.c +++ b/soc/espressif/esp32s2/hw_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -36,33 +36,17 @@ int hardware_init(void) #ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE esp_cpu_configure_region_protection(); #endif -#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - - if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { - cfg.drefh = 3; - cfg.drefm = 3; - cfg.drefl = 3; - cfg.force = 1; - rtc_vddsdio_set_config(cfg); - esp_rom_delay_us(10); - } -#endif /* CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V */ bootloader_clock_configure(); +#ifdef CONFIG_ESP_CONSOLE /* initialize console, from now on, we can log */ esp_console_init(); print_banner(); - - spi_flash_init_chip_state(); - err = esp_flash_init_default_chip(); - if (err != 0) { - ESP_EARLY_LOGE(TAG, "Failed to init flash chip, error %d", err); - return err; - } +#endif /* CONFIG_ESP_CONSOLE */ cache_hal_init(); + mmu_hal_init(); /* Workaround: normal ROM bootloader exits with DROM0 cache unmasked, but 2nd bootloader diff --git a/soc/espressif/esp32s2/mcuboot.ld b/soc/espressif/esp32s2/mcuboot.ld index bf14afeb6a3e8..b14ad89af4a12 100644 --- a/soc/espressif/esp32s2/mcuboot.ld +++ b/soc/espressif/esp32s2/mcuboot.ld @@ -44,28 +44,17 @@ SECTIONS *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *libarch__xtensa__core.a:xtensa_asm2_util.*(.literal .text .literal.* .text.*) - *liblib__libc__common.a:abort.*(.literal .text .literal.* .text.*) - *libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*) *libarch__common.a:dynamic_isr.*(.literal .text .literal.* .text.*) *libarch__common.a:sw_isr_common.*(.literal .text .literal.* .text.*) *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*) - *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out) *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*) *libzephyr.a:cpu.*(.literal .text .literal.* .text.*) *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) - *libzephyr.a:heap.*(.literal .text .literal.* .text.*) - *libkernel.a:kheap.*(.literal .text .literal.* .text.*) - *libkernel.a:mempool.*(.literal .text .literal.* .text.*) *libkernel.a:device.*(.literal .text .literal.* .text.*) - *libkernel.a:timeout.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) - *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libzephyr.a:rtc_time.*(.literal .literal.* .text .text.*) - *libzephyr.a:rtc_clk.*(.literal .literal.* .text .text.*) - *libzephyr.a:rtc_clk_init.*(.literal .literal.* .text .text.*) *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) diff --git a/soc/espressif/esp32s2/memory.h b/soc/espressif/esp32s2/memory.h index 74a0f7f05fe6e..4b6e8a17c36c8 100644 --- a/soc/espressif/esp32s2/memory.h +++ b/soc/espressif/esp32s2/memory.h @@ -7,8 +7,8 @@ /* SRAM0 (32k) with adjacted SRAM1 (288k) * Ibus and Dbus address space */ -#define SRAM_IRAM_START 0x40020000 -#define SRAM_DRAM_START 0x3ffb0000 +#define SRAM_IRAM_START (SRAM_DRAM_START + IRAM_DRAM_OFFSET) +#define SRAM_DRAM_START DT_REG_ADDR(DT_NODELABEL(sram0)) #define SRAM_CACHE_SIZE (CONFIG_ESP32S2_INSTRUCTION_CACHE_SIZE + CONFIG_ESP32S2_DATA_CACHE_SIZE) /** Simplified memory map for the bootloader. diff --git a/soc/espressif/esp32s2/soc.c b/soc/espressif/esp32s2/soc.c index 858618817f2bd..286bbe2469a67 100644 --- a/soc/espressif/esp32s2/soc.c +++ b/soc/espressif/esp32s2/soc.c @@ -1,85 +1,24 @@ /* - * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd. + * Copyright (c) 2021-2025 Espressif Systems (Shanghai) Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 */ -/* Include esp-idf headers first to avoid redefining BIT() macro */ -#include "soc.h" -#include -#include -#include -#include -#include -#include -#include -#include -#if CONFIG_ESP_SPIRAM -#include "psram.h" -#endif - -#include -#include -#include -#include -#include - +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include +#include #include -#include "esp_log.h" - -#define TAG "boot.esp32s2" -extern void rtc_clk_cpu_freq_set_xtal(void); -extern void esp_reset_reason_init(void); extern void z_prep_c(void); +extern void esp_reset_reason_init(void); -/* - * This is written in C rather than assembly since, during the port bring up, - * Zephyr is being booted by the Espressif bootloader. With it, the C stack - * is already set up. - */ -void __attribute__((section(".iram1"))) __esp_platform_start(void) +void IRAM_ATTR __esp_platform_app_start(void) { - extern uint32_t _init_start; - - /* Move the exception vector table to IRAM. */ - __asm__ __volatile__("wsr %0, vecbase" : : "r"(&_init_start)); - - /* Zero out BSS */ - z_bss_zero(); - - /* Disable normal interrupts. */ - __asm__ __volatile__("wsr %0, PS" : : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE)); - - /* Initialize the architecture CPU pointer. Some of the - * initialization code wants a valid arch_current_thread() before - * arch_kernel_init() is invoked. - */ - __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0])); - - esp_reset_reason_init(); - -#ifndef CONFIG_MCUBOOT - /* ESP-IDF 2nd stage bootloader enables RTC WDT to check on startup sequence - * related issues in application. Hence disable that as we are about to start - * Zephyr environment. - */ - wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; - - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_disable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - /* * Configure the mode of instruction cache : * cache size, cache associated ways, cache line size. @@ -96,23 +35,17 @@ void __attribute__((section(".iram1"))) __esp_platform_start(void) esp_config_data_cache_mode(); esp_rom_Cache_Enable_DCache(0); - esp_timer_early_init(); + esp_reset_reason_init(); - esp_mspi_pin_init(); + esp_timer_early_init(); - esp_flash_app_init(); + esp_flash_config(); - esp_mmu_map_init(); + esp_intr_initialize(); #if CONFIG_ESP_SPIRAM esp_init_psram(); -#endif /* CONFIG_ESP_SPIRAM */ - -#endif /* !CONFIG_MCUBOOT */ - esp_intr_initialize(); - -#if CONFIG_ESP_SPIRAM /* Init Shared Multi Heap for PSRAM */ int err = esp_psram_smh_init(); @@ -127,6 +60,16 @@ void __attribute__((section(".iram1"))) __esp_platform_start(void) CODE_UNREACHABLE; } +void IRAM_ATTR __esp_platform_mcuboot_start(void) +{ + esp_intr_initialize(); + + /* Start Zephyr */ + z_prep_c(); + + CODE_UNREACHABLE; +} + /* Boot-time static default printk handler, possibly to be overridden later. */ int IRAM_ATTR arch_printk_char_out(int c) { diff --git a/soc/espressif/esp32s2/soc.h b/soc/espressif/esp32s2/soc.h index 2edd0d12cc947..9a5c5e9795955 100644 --- a/soc/espressif/esp32s2/soc.h +++ b/soc/espressif/esp32s2/soc.h @@ -22,7 +22,8 @@ #include #include -void __esp_platform_start(void); +void __esp_platform_mcuboot_start(void); +void __esp_platform_app_start(void); static inline uint32_t esp_core_id(void) { diff --git a/soc/espressif/esp32s3/CMakeLists.txt b/soc/espressif/esp32s3/CMakeLists.txt index 00d26e14df860..48c6936487bac 100644 --- a/soc/espressif/esp32s3/CMakeLists.txt +++ b/soc/espressif/esp32s3/CMakeLists.txt @@ -26,82 +26,3 @@ zephyr_library_sources_ifdef(CONFIG_NEWLIB_LIBC newlib_fix.c) # Power Management zephyr_library_sources_ifdef(CONFIG_PM power.c) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) - -# Get flash size to use in esptool as string -math(EXPR esptoolpy_flashsize "${CONFIG_FLASH_SIZE} / 0x100000") - -# Get UART baudrate from DT -dt_chosen(dts_shell_uart PROPERTY "zephyr,shell-uart") -if(${dts_shell_uart}) - dt_prop(monitor_baud PATH ${dts_shell_uart} PROPERTY "current-speed") -endif() - -board_runner_args(esp32 "--esp-monitor-baud=${monitor_baud}") - -message("-- Espressif HAL path: ${ESP_IDF_PATH}") - -# Select image processing - -if(CONFIG_ESP_SIMPLE_BOOT OR CONFIG_MCUBOOT) - - if(CONFIG_BUILD_OUTPUT_BIN) - - set(ESPTOOL_PY ${ESP_IDF_PATH}/tools/esptool_py/esptool.py) - message("-- Use the esptool.py: ${ESPTOOL_PY}") - - set(ELF2IMAGE_ARG "") - if(NOT CONFIG_MCUBOOT) - set(ELF2IMAGE_ARG "--ram-only-header") - endif() - - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ESPTOOL_PY} - ARGS --chip ${CONFIG_SOC} elf2image ${ELF2IMAGE_ARG} - --flash_mode dio --flash_freq 40m - --flash_size ${esptoolpy_flashsize}MB - -o ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf) - - endif() - -endif() - -# Select the image origin depending on the boot configuration -if(CONFIG_SOC_ESP32S3_APPCPU) - dt_nodelabel(dts_partition_path NODELABEL "slot0_appcpu_partition") -elseif(CONFIG_MCUBOOT) - dt_nodelabel(dts_partition_path NODELABEL "boot_partition") -elseif(CONFIG_ESP_SIMPLE_BOOT) - dt_nodelabel(dts_partition_path NODELABEL "boot_partition") -else() - dt_nodelabel(dts_partition_path NODELABEL "slot0_partition") -endif() - -dt_reg_addr(image_off PATH ${dts_partition_path}) -board_finalize_runner_args(esp32 "--esp-app-address=${image_off}") - -message("-- Image partition ${dts_partition_path}") - -# Look for cross references between bootloader sections -if(CONFIG_MCUBOOT) - - message("check_callgraph using: ${ESP_IDF_PATH}/tools/ci/check_callgraph.py") - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND - ${PYTHON_EXECUTABLE} ${ESP_IDF_PATH}/tools/ci/check_callgraph.py - ARGS - --rtl-dirs ${CMAKE_BINARY_DIR}/zephyr - --elf-file ${CMAKE_BINARY_DIR}/zephyr/${CONFIG_KERNEL_BIN_NAME}.elf - find-refs - --from-section='.iram0.loader_text' - --to-section='.iram0.text' - --exit-code) -endif() - -if(CONFIG_MCUBOOT) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.ld CACHE INTERNAL "") -elseif(CONFIG_SOC_ESP32S3_APPCPU) - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default_appcpu.ld CACHE INTERNAL "") -else() - set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/default.ld CACHE INTERNAL "") -endif() diff --git a/soc/espressif/esp32s3/Kconfig b/soc/espressif/esp32s3/Kconfig index 3e2886edcf663..99ebadeb44056 100644 --- a/soc/espressif/esp32s3/Kconfig +++ b/soc/espressif/esp32s3/Kconfig @@ -156,6 +156,4 @@ config MAC_BB_PD endmenu # Cache config -rsource "Kconfig.amp" - endif # SOC_SERIES_ESP32S3 diff --git a/soc/espressif/esp32s3/Kconfig.amp b/soc/espressif/esp32s3/Kconfig.amp deleted file mode 100644 index f6acbbc52a24e..0000000000000 --- a/soc/espressif/esp32s3/Kconfig.amp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. -# SPDX-License-Identifier: Apache-2.0 - -if SOC_SERIES_ESP32S3 - -menu "AMP config" - -config ESP32S3_APPCPU_IRAM_SIZE - hex "ESP32S3 APPCPU IRAM size" - depends on SOC_ESP32S3_PROCPU || SOC_ESP32S3_APPCPU - default 0x10000 - help - Defines APPCPU IRAM area size in bytes. - -config ESP32S3_APPCPU_DRAM_SIZE - hex "ESP32S3 APPCPU DRAM size" - depends on SOC_ESP32S3_PROCPU || SOC_ESP32S3_APPCPU - default 0x10000 - help - Defines APPCPU DRAM area size in bytes. - -config SOC_ENABLE_APPCPU - bool - default y - depends on (IPM || MBOX) && SOC_ESP32S3_PROCPU - help - This hidden configuration lets PROCPU core to map and start APPCPU whenever IPM is enabled. - -endmenu # AMP config - -endif # SOC_SERIES_ESP32S3 diff --git a/soc/espressif/esp32s3/Kconfig.defconfig b/soc/espressif/esp32s3/Kconfig.defconfig index 110471dba6298..171e1f8adce3a 100644 --- a/soc/espressif/esp32s3/Kconfig.defconfig +++ b/soc/espressif/esp32s3/Kconfig.defconfig @@ -12,4 +12,7 @@ config FLASH_BASE_ADDRESS config BOOTLOADER_MCUBOOT default y if SOC_ESP32S3_APPCPU +config MAIN_STACK_SIZE + default 4096 + endif # SOC_SERIES_ESP32S3 diff --git a/soc/espressif/esp32s3/default.ld b/soc/espressif/esp32s3/default.ld index 0f40119015f5d..79f8af91bd546 100644 --- a/soc/espressif/esp32s3/default.ld +++ b/soc/espressif/esp32s3/default.ld @@ -11,16 +11,31 @@ #include "memory.h" /* User available SRAM memory segments */ -amp_total_size = APPCPU_SRAM_TOTAL_SIZE; -procpu_iram_end = USER_IRAM_END - APPCPU_SRAM_TOTAL_SIZE; -procpu_dram_end = USER_DRAM_END - APPCPU_SRAM_TOTAL_SIZE; +procpu_iram_end = USER_IRAM_END - APPCPU_SRAM_SIZE; +procpu_dram_end = USER_DRAM_END - APPCPU_SRAM_SIZE; procpu_iram_org = SRAM_USER_IRAM_START; procpu_iram_len = procpu_iram_end - procpu_iram_org; +procpu_dram_org2 = ORIGIN(dram0_0_seg); procpu_dram_org = SRAM1_DRAM_START; procpu_dram_len = procpu_dram_end - procpu_dram_org; +/* User available ROM memory segments */ +procpu_irom_end = ICACHE0_START + ICACHE0_SIZE - APPCPU_ROM_SIZE; +procpu_drom_end = DCACHE0_START + DCACHE0_SIZE - APPCPU_ROM_SIZE; + +procpu_irom_org = ICACHE0_START; +procpu_irom_len = ICACHE0_SIZE - APPCPU_ROM_SIZE; + +procpu_drom_org = DCACHE0_START; +procpu_drom_len = DCACHE0_SIZE - APPCPU_ROM_SIZE; + +#if defined(CONFIG_ESP_SPIRAM) +procpu_extram_org = DCACHE0_START; +procpu_extram_len = CONFIG_ESP_SPIRAM_SIZE; +#endif + /* Aliases */ #define FLASH_CODE_REGION irom0_0_seg #define RODATA_REGION drom0_0_seg @@ -50,35 +65,46 @@ procpu_dram_len = procpu_dram_end - procpu_dram_org; MEMORY { #ifdef CONFIG_BOOTLOADER_MCUBOOT - mcuboot_hdr (R): org = 0x0, len = 0x20 - metadata (R): org = 0x20, len = 0x20 - FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 + mcuboot_hdr (R): org = 0x0, len = 0x20 + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 #else /* Make safety margin in the FLASH memory size so the * (esp_img_header + (n*esp_seg_headers)) would fit */ - FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 + FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 #endif /* CONFIG_BOOTLOADER_MCUBOOT */ iram0_0_seg(RX): org = procpu_iram_org, len = procpu_iram_len dram0_0_seg(RW): org = procpu_dram_org, len = procpu_dram_len - irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN - drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN + irom0_0_seg(RX): org = procpu_irom_org, len = procpu_irom_len + drom0_0_seg(R): org = procpu_drom_org, len = procpu_drom_len /* The `ext_ram_seg` and `drom0_0_seg` share the same bus and the address region. * A dummy section is used to avoid overlap. See `.ext_ram.dummy` in `sections.ld.in` */ #if defined(CONFIG_ESP_SPIRAM) - ext_ram_seg(RWX): org = DROM_SEG_ORG, len = CONFIG_ESP_SPIRAM_SIZE - 0x40 + /* `ext_[id]ram_seg` and `drom0_0_seg` share the same bus and the address region. + * A dummy section is used to avoid overlap. See `.ext_ram.dummy` */ + ext_dram_seg(RW): org = procpu_extram_org, len = procpu_extram_len + ext_iram_seg(RX): org = procpu_extram_org, len = procpu_extram_len #endif /* RTC fast memory (executable). Persists over deep sleep. */ - rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000 - - /* RTC fast memory (same block as above), viewed from data bus - */ - rtc_data_seg(RW): org = 0x600fe000, len = 0x2000 + rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM + + /* We reduced the size of rtc_iram_seg by CONFIG_RESERVE_RTC_MEM value. + It reserves the amount of RTC fast memory that we use for this memory segment. + This segment is intended for keeping: + - (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files). + - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). + The aim of this is to keep data that will not be moved around and have a fixed address. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + rtc_reserved_seg(RW): org = 0x600fe000 + 0x2000 - CONFIG_RESERVE_RTC_MEM, + len = CONFIG_RESERVE_RTC_MEM +#endif /* RTC slow memory (data accessible). Persists over deep sleep. */ @@ -92,13 +118,15 @@ MEMORY /* Default entry point: */ ENTRY(CONFIG_KERNEL_ENTRY) -/* Used as a pointer to the heap end */ +/* Heap size calculations differs between the APPCPU and PROCPU */ #ifdef CONFIG_SOC_ENABLE_APPCPU _heap_sentry = procpu_dram_end; #else _heap_sentry = DRAM_RESERVED_START; #endif +_libc_heap_size = _heap_sentry - _end; + SECTIONS { _iram_dram_offset = IRAM_DRAM_OFFSET; @@ -137,7 +165,43 @@ SECTIONS */ LONG(ADDR(.dram0.data)) LONG(LOADADDR(.dram0.data)) - LONG(LOADADDR(.dram0.end) + SIZEOF(.dram0.end) - LOADADDR(.dram0.data)) + LONG(LOADADDR(.dram0.data_end) + SIZEOF(.dram0.data_end) - LOADADDR(.dram0.data)) + + /* RTC_IRAM metadata: + * 8. Destination address (VMA) for RTC_IRAM region + * 9. Flash offset (LMA) for start of RTC_IRAM region + * 10. Size of RTC_IRAM region + */ + LONG(ADDR(.rtc.text)) + LONG(LOADADDR(.rtc.text)) + LONG(SIZEOF(.rtc.text)) + + /* RTC_DRAM metadata: + * 11. Destination address (VMA) for RTC_DRAM region + * 12. Flash offset (LMA) for start of RTC_DRAM region + * 13. Size of RTC_DRAM region + */ + LONG(ADDR(.rtc.data)) + LONG(LOADADDR(.rtc.data)) + LONG(SIZEOF(.rtc.data)) + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(ADDR(.flash.text)) + LONG(LOADADDR(.flash.text)) + LONG(SIZEOF(.flash.text)) + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(ADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata)) + LONG(LOADADDR(.flash.rodata_end) - LOADADDR(.flash.rodata)) } > metadata #endif /* CONFIG_BOOTLOADER_MCUBOOT */ @@ -154,11 +218,13 @@ SECTIONS .rtc.text : { . = ALIGN(4); - _rtc_fast_start = ABSOLUTE(.); _rtc_text_start = ABSOLUTE(.); - *(.rtc.entry.literal .rtc.text) + _rtc_fast_start = ABSOLUTE(.); + *(.rtc.literal .rtc.literal.*) + *(.rtc.text .rtc.text.*) + *(.rtc.entry.literal) *(.rtc.entry.text) - _rtc_text_end = ABSOLUTE(.); + . = ALIGN(4); } GROUP_DATA_LINK_IN(rtc_iram_seg, ROMABLE_REGION) /* This section located in RTC FAST Memory area. @@ -169,30 +235,27 @@ SECTIONS { . = ALIGN(4); _rtc_force_fast_start = ABSOLUTE(.); - *(.rtc.force_fast .rtc.force_fast.*) - . = ALIGN(4) ; + . = ALIGN(4); _rtc_force_fast_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(rtc_data_seg, ROMABLE_REGION) + } GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION) /* RTC data section holds data marked with * RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. */ .rtc.data : { + . = ALIGN(4); _rtc_data_start = ABSOLUTE(.); - *(.rtc.data) - *(.rtc.rodata) + *(.rtc.data .rtc.data.*) + *(.rtc.rodata .rtc.rodata.*) _rtc_data_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION) .rtc.bss (NOLOAD) : { _rtc_bss_start = ABSOLUTE(.); - - *(.rtc.data) - *(.rtc.rodata) - + *(.rtc.bss .rtc.bss.*) _rtc_bss_end = ABSOLUTE(.); } GROUP_LINK_IN(rtc_slow_seg) @@ -201,13 +264,11 @@ SECTIONS * 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): + .rtc_noinit (NOLOAD) : { . = ALIGN(4); - _rtc_noinit_start = ABSOLUTE(.); *(.rtc_noinit .rtc_noinit.*) . = ALIGN(4) ; - _rtc_noinit_end = ABSOLUTE(.); } GROUP_LINK_IN(rtc_slow_seg) /* This section located in RTC SLOW Memory area. @@ -223,13 +284,24 @@ SECTIONS _rtc_force_slow_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(rtc_slow_seg, ROMABLE_REGION) + /** + * This section holds RTC data that should have fixed addresses. + * The data are not initialized at power-up and are retained during deep sleep. + */ +#if (CONFIG_RESERVE_RTC_MEM > 0) + .rtc_reserved (NOLOAD) : + { + . = ALIGN(4); + _rtc_reserved_start = ABSOLUTE(.); + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + _rtc_reserved_end = ABSOLUTE(.); + } GROUP_LINK_IN(rtc_reserved_seg) +#endif + /* Get size of rtc slow data based on rtc_data_location alias */ _rtc_slow_length = (_rtc_force_slow_end - _rtc_data_start); _rtc_fast_length = (_rtc_force_fast_end - _rtc_fast_start); - ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), "RTC_SLOW segment data does not fit.") - ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), "RTC_FAST segment data does not fit.") - /* --- END OF RTC --- */ /* --- START OF IRAM --- */ @@ -237,7 +309,6 @@ SECTIONS /* Send .iram0 code to iram */ .iram0.vectors : ALIGN(4) { - _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 */ @@ -271,9 +342,9 @@ SECTIONS *(.entry.text) *(.init.literal) *(.init) - _init_end = ABSOLUTE(.); + _iram_start = ABSOLUTE(.); } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) .iram0.text : ALIGN(4) @@ -403,7 +474,7 @@ SECTIONS #if defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:(.wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:(.wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiorslpiram .wifiorslpiram.* .wifiextrairam .wifiextrairam.*) - *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) /* [mapping:esp_wifi] */ *(.literal.wifi_clock_enable_wrapper .text.wifi_clock_enable_wrapper) @@ -504,8 +575,8 @@ SECTIONS /* Spacer section is required to skip .iram0.text area because * iram0_0_seg and dram0_0_seg reflect the same address space on different buses. */ - . = ORIGIN(dram0_0_seg) + MAX(_iram_end, SRAM1_IRAM_START) - SRAM1_IRAM_START; - . = ALIGN(4) + 16; + . = ORIGIN(dram0_0_seg) + (MAX(_iram_end, SRAM1_IRAM_START) - SRAM1_IRAM_START); + . = ALIGN(16); } GROUP_LINK_IN(RAMABLE_REGION) .dram0.data : @@ -698,12 +769,37 @@ SECTIONS #include #pragma pop_macro("GROUP_ROM_LINK_IN") - .dram0.end : + .dram0.data_end : { __data_end = ABSOLUTE(.); _data_end = ABSOLUTE(.); } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + .dram0.noinit (NOLOAD): + { + . = ALIGN(4); + __dram_noinit_start = ABSOLUTE(.); +#ifdef CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM + *(EXCLUDE_FILE( + *libdrivers__wifi.a:* + *libsubsys__net__l2__ethernet.a:* + *libsubsys__net__lib__config.a:* + *libsubsys__net__ip.a:* + *libsubsys__net.a:* ) .noinit) + *(EXCLUDE_FILE( + *libdrivers__wifi.a:* + *libsubsys__net__l2__ethernet.a:* + *libsubsys__net__lib__config.a:* + *libsubsys__net__ip.a:* + *libsubsys__net.a:* ) .noinit.*) +#else + *(.noinit) + *(.noinit.*) +#endif /* CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM */ + __dram_noinit_end = ABSOLUTE(.); + . = ALIGN(4) ; + } GROUP_LINK_IN(RAMABLE_REGION) + /* Shared RAM */ .dram0.bss (NOLOAD) : { @@ -736,16 +832,8 @@ SECTIONS __bss_end = ABSOLUTE(.); } GROUP_LINK_IN(RAMABLE_REGION) - .dram0.noinit (NOLOAD): - { - . = ALIGN(4); - *(.noinit) - *(.noinit.*) - . = ALIGN(4) ; - } GROUP_LINK_IN(RAMABLE_REGION) - /* Provide total SRAM usage, including IRAM and DRAM */ - _image_ram_start = _iram_start - IRAM_DRAM_OFFSET; + _image_ram_start = _init_start - IRAM_DRAM_OFFSET; #include ASSERT(((_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.") @@ -776,6 +864,7 @@ SECTIONS #if !defined(CONFIG_ESP32_WIFI_IRAM_OPT) *libnet80211.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiextrairam .wifiextrairam.*) *libpp.a:( .wifi0iram .wifi0iram.* .wifislpiram .wifislpiram.* .wifiorslpiram .wifiorslpiram.* .wifiextrairam .wifiextrairam.*) + *libcoexist.a:(.wifi_slp_iram .wifi_slp_iram.* .coexiram .coexiram.* .coexsleepiram .coexsleepiram.*) #endif #if !defined(CONFIG_ESP32_WIFI_RX_IRAM_OPT) @@ -825,7 +914,7 @@ SECTIONS .flash.rodata : ALIGN(CACHE_ALIGN) { - _flash_rodata_start = ABSOLUTE(.); + _image_rodata_start = ABSOLUTE(.); _rodata_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.rodata start, this can be used for mmu driver to maintain virtual address */ _rodata_start = ABSOLUTE(.); __rodata_region_start = ABSOLUTE(.); @@ -900,25 +989,41 @@ SECTIONS */ #if defined(CONFIG_ESP_SPIRAM) + /* This section is required to skip flash rodata sections, because `ext_[id]ram_seg` + * and `drom0_0_seg` are on the same bus */ .ext_ram.dummy (NOLOAD): { - . = ORIGIN(ext_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start); + . = ADDR(.flash.rodata_end) - ORIGIN(ext_dram_seg); . = ALIGN (CACHE_ALIGN); - } GROUP_LINK_IN(ext_ram_seg) + } GROUP_LINK_IN(ext_dram_seg) /* This section holds .ext_ram.bss data, and will be put in PSRAM */ .ext_ram.bss (NOLOAD) : { + _ext_ram_start = ABSOLUTE(.); + _ext_ram_noinit_start = ABSOLUTE(.); + +#ifdef CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM + *libdrivers__wifi.a:(.noinit .noinit.*) + *libsubsys__net__l2__ethernet.a:(.noinit .noinit.*) + *libsubsys__net__lib__config.a:(.noinit .noinit.*) + *libsubsys__net__ip.a:(.noinit .noinit.*) + *libsubsys__net.a:(.noinit .noinit.*) +#endif /* CONFIG_ESP32_WIFI_NET_ALLOC_SPIRAM */ + . = ALIGN(16); + _ext_ram_noinit_end = ABSOLUTE(.); + _ext_ram_bss_start = ABSOLUTE(.); *(.ext_ram.bss*) - . = ALIGN(4); + . = ALIGN(16); + _ext_ram_bss_end = ABSOLUTE(.); _spiram_heap_start = ABSOLUTE(.); . = . + CONFIG_ESP_SPIRAM_HEAP_SIZE - (_spiram_heap_start - _ext_ram_bss_start); - . = ALIGN(4); + . = ALIGN(16); - _ext_ram_bss_end = ABSOLUTE(.); - } GROUP_LINK_IN(ext_ram_seg) + _ext_ram_end = ABSOLUTE(.); + } GROUP_LINK_IN(ext_dram_seg) #endif /* CONFIG_ESP_SPIRAM */ @@ -969,7 +1074,13 @@ SECTIONS /* --- XTENSA GLUE AND DEBUG END --- */ +ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") + +ASSERT(((_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.") + #if defined(CONFIG_ESP_SPIRAM) -ASSERT(((_ext_ram_bss_end - _ext_ram_bss_start) <= CONFIG_ESP_SPIRAM_SIZE), +ASSERT(((_ext_ram_end - _ext_ram_start) <= CONFIG_ESP_SPIRAM_SIZE), "External SPIRAM overflowed.") #endif diff --git a/soc/espressif/esp32s3/default_appcpu.ld b/soc/espressif/esp32s3/default_appcpu.ld index 58ec051e389f9..ef11fccb218b7 100644 --- a/soc/espressif/esp32s3/default_appcpu.ld +++ b/soc/espressif/esp32s3/default_appcpu.ld @@ -8,6 +8,10 @@ #include #include +#if !defined(CONFIG_BOOTLOADER_MCUBOOT) +#error "APPCPU image must use MCUboot image format." +#endif /* CONFIG_BOOTLOADER_MCUBOOT */ + #include "memory.h" /* User available SRAM memory segments */ @@ -20,11 +24,19 @@ appcpu_dram_org = appcpu_dram_end - APPCPU_SRAM_SIZE; appcpu_iram_len = APPCPU_SRAM_SIZE; appcpu_dram_len = APPCPU_SRAM_SIZE; +/* User available ROM memory segments */ +appcpu_irom_org = (ICACHE0_START + ICACHE0_SIZE) - APPCPU_ROM_SIZE; +appcpu_drom_org = (DCACHE0_START + DCACHE0_SIZE) - APPCPU_ROM_SIZE; + +appcpu_irom_len = APPCPU_ROM_SIZE; +appcpu_drom_len = APPCPU_ROM_SIZE; + /* Aliases */ -#define ROMABLE_REGION FLASH -#define RODATA_REGION dram0_1_seg /* drom0_1_seg */ -#define RAMABLE_REGION dram0_1_seg -#define IRAM_REGION iram0_1_seg +#define FLASH_CODE_REGION irom0_1_seg +#define RODATA_REGION drom0_1_seg +#define IRAM_REGION iram0_1_seg +#define RAMABLE_REGION dram0_1_seg +#define ROMABLE_REGION FLASH /* Zephyr macro re-definitions */ #undef GROUP_DATA_LINK_IN @@ -47,19 +59,16 @@ appcpu_dram_len = APPCPU_SRAM_SIZE; MEMORY { -#ifdef CONFIG_BOOTLOADER_MCUBOOT - mcuboot_hdr (R): org = 0x0, len = 0x20 - metadata (R): org = 0x20, len = 0x20 - FLASH (R): org = 0x40, len = FLASH_SIZE - 0x40 -#else - /* Make safety margin in the FLASH memory size so the - * (esp_img_header + (n*esp_seg_headers)) would fit */ - FLASH (R): org = 0x0, len = FLASH_SIZE - 0x100 -#endif /* CONFIG_BOOTLOADER_MCUBOOT */ + mcuboot_hdr (R): org = 0x0, len = 0x20 + metadata (R): org = 0x20, len = 0x60 + FLASH (R): org = 0x80, len = FLASH_SIZE - 0x80 iram0_1_seg(RX): org = appcpu_iram_org, len = appcpu_iram_len dram0_1_seg(RW): org = appcpu_dram_org, len = appcpu_dram_len + irom0_1_seg(RX): org = appcpu_irom_org, len = appcpu_irom_len + drom0_1_seg(R): org = appcpu_drom_org, len = appcpu_drom_len + #ifdef CONFIG_GEN_ISR_TABLES IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000 #endif @@ -68,12 +77,12 @@ MEMORY /* Default entry point: */ ENTRY(__appcpu_start) -/* Used as a pointer to the heap end */ +/* Heap size calculations for APPCPU */ _heap_sentry = DRAM_RESERVED_START; +_libc_heap_size = _heap_sentry - _end; SECTIONS { -#if defined(CONFIG_BOOTLOADER_MCUBOOT) /* Reserve space for MCUboot header in the binary */ .mcuboot_header : { @@ -108,21 +117,55 @@ SECTIONS LONG(ADDR(.dram0.data)) LONG(LOADADDR(.dram0.data)) LONG(_data_end - _data_start) + + /* RTC_IRAM metadata: + * 8. Destination address (VMA) for RTC_IRAM region + * 9. Flash offset (LMA) for start of RTC_IRAM region + * 10. Size of RTC_IRAM region + */ + LONG(0); + LONG(0); + LONG(0); + + /* RTC_DRAM metadata: + * 11. Destination address (VMA) for RTC_DRAM region + * 12. Flash offset (LMA) for start of RTC_DRAM region + * 13. Size of RTC_DRAM region + */ + LONG(0); + LONG(0); + LONG(0); + + /* IROM metadata: + * 14. Destination address (VMA) for IROM region + * 15. Flash offset (LMA) for start of IROM region + * 16. Size of IROM region + */ + LONG(_image_irom_vaddr); + LONG(_image_irom_start); + LONG(_image_irom_size); + + /* DROM metadata: + * 17. Destination address (VMA) for DROM region + * 18. Flash offset (LMA) for start of DROM region + * 19. Size of DROM region + */ + LONG(_image_drom_vaddr); + LONG(_image_drom_start); + LONG(_image_drom_size); } > metadata -#endif /* CONFIG_BOOTLOADER_MCUBOOT */ #include - #ifdef CONFIG_LLEXT +#ifdef CONFIG_LLEXT #include - #endif +#endif /* --- START OF IRAM --- */ /* Send .iram0 code to iram */ .iram0.vectors : ALIGN(4) { - _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 */ @@ -156,29 +199,25 @@ SECTIONS *(.entry.text) *(.init.literal) *(.init) - . = ALIGN (16); - _init_end = ABSOLUTE(.); + _iram_start = ABSOLUTE(.); } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) .iram0.text : ALIGN(4) { + /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); *(.iram1 .iram1.*) *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) - *libesp32.a:panic.*(.literal .text .literal.* .text.*) - *librtc.a:(.literal .text .literal.* .text.*) *libarch__xtensa__core.a:(.literal .text .literal.* .text.*) *libkernel.a:(.literal .text .literal.* .text.*) - *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*) - *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) + *libzephyr.a:cbprintf_packaged.*(.literal .text .literal.* .text.*) *libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*) *libzephyr.a:windowspill_asm.*(.literal .text .literal.* .text.*) *libzephyr.a:log_noos.*(.literal .text .literal.* .text.*) *libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*) - *libzephyr.a:systimer_hal.*(.literal .text .literal.* .text.*) *libzephyr.a:log_core.*(.literal .text .literal.* .text.*) *libzephyr.a:cbprintf_complete.*(.literal .text .literal.* .text.*) *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out) @@ -187,50 +226,138 @@ SECTIONS *libdrivers__console.a:uart_console.*(.literal.console_out .text.console_out) *libzephyr.a:log_output.*(.literal .text .literal.* .text.*) *libzephyr.a:log_backend_uart.*(.literal .text .literal.* .text.*) + *libzephyr.a:log_minimal.*(.literal .literal.* .text .text.*) *libzephyr.a:loader.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_flash_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:console_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:hw_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:soc_random.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_mmu_map.*(.literal .literal.* .text .text.*) + *libdrivers__interrupt_controller.a:(.literal .literal.* .text .text.*) *liblib__libc__minimal.a:string.*(.literal .text .literal.* .text.*) *liblib__libc__newlib.a:string.*(.literal .text .literal.* .text.*) - *libc.a:*(.literal .text .literal.* .text.*) + *liblib__libc__picolibc.a:string.*(.literal .text .literal.* .text.*) *libphy.a:(.phyiram .phyiram.*) *libgcov.a:(.literal .text .literal.* .text.*) + /* APPCPU_ENABLED */ + *libzephyr.a:bootloader_flash.*(.literal .text .literal.* .text.*) + *libzephyr.a:flash_mmap.*(.literal .text .literal.* .text.*) + + /* [mapping:esp_psram] */ + *libzephyr.a:mmu_psram_flash.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_psram_impl_quad.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_psram_impl_octal.*(.literal .literal.* .text .text.*) + + /* [mapping:hal] */ + *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_encrypt_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:cache_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:ledc_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:i2c_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) + *libzephyr.a:systimer_hal.*(.literal .text .literal.* .text.*) + *libzephyr.a:spi_flash_hal_gpspi.*(.literal .text .literal.* .text.*) + + /* [mapping:soc] */ + *libzephyr.a:lldesc.*(.literal .literal.* .text .text.*) + + /* [mapping:log] */ + *(.literal.esp_log_write .text.esp_log_write) + *(.literal.esp_log_timestamp .text.esp_log_timestamp) + *(.literal.esp_log_early_timestamp .text.esp_log_early_timestamp) + *(.literal.esp_log_impl_lock .text.esp_log_impl_lock) + *(.literal.esp_log_impl_lock_timeout .text.esp_log_impl_lock_timeout) + *(.literal.esp_log_impl_unlock .text.esp_log_impl_unlock) + + /* [mapping:spi_flash] */ + *libzephyr.a:spi_flash_chip_boya.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_gd.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_generic.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_issi.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_mxic.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_mxic_opi.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_th.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_chip_winbond.*(.literal .literal.* .text .text.*) + *libzephyr.a:memspi_host_driver.*(.literal .literal.* .text .text.*) + *libzephyr.a:flash_brownout_hook.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_wrap.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_hpm_enable.*(.literal .literal.* .text .text.*) + *libzephyr.a:spi_flash_oct_flash_init.*(.literal .literal.* .text .text.*) + *libzephyr.a:flash_ops.*(.literal .literal.* .text .text.*) + + /* [mapping:esp_system] */ + *libzephyr.a:esp_err.*(.literal .literal.* .text .text.*) + *(.literal.esp_system_abort .text.esp_system_abort) + + /* [mapping:esp_hw_support] */ + *(.literal.esp_cpu_stall .text.esp_cpu_stall) + *(.literal.esp_cpu_unstall .text.esp_cpu_unstall) + *(.literal.esp_cpu_reset .text.esp_cpu_reset) + *(.literal.esp_cpu_wait_for_intr .text.esp_cpu_wait_for_intr) + *(.literal.esp_cpu_compare_and_set .text.esp_cpu_compare_and_set) + *(.literal.esp_gpio_reserve_pins .text.esp_gpio_reserve_pins) + *(.literal.esp_gpio_is_pin_reserved .text.esp_gpio_is_pin_reserved) + *(.literal.rtc_vddsdio_get_config .text.rtc_vddsdio_get_config) + *(.literal.rtc_vddsdio_set_config .text.rtc_vddsdio_set_config) + *libzephyr.a:esp_memory_utils.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_clk.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_clk_init.*(.literal .text .literal.* .text.*) + *libzephyr.a:rtc_sleep.*(.literal .literal.* .text .text.*) + *libzephyr.a:rtc_time.*(.literal .literal.* .text .text.*) + *libzephyr.a:systimer.*(.literal .literal.* .text .text.*) + *libzephyr.a:mspi_timing_config.*(.literal .literal.* .text .text.*) + *libzephyr.a:mspi_timing_tuning.*(.literal .literal.* .text .text.*) + *(.literal.sar_periph_ctrl_power_enable .text.sar_periph_ctrl_power_enable) + + /* [mapping:soc_pm] */ + *(.literal.GPIO_HOLD_MASK .text.GPIO_HOLD_MASK) + + /* [mapping:esp_rom] */ + *libzephyr.a:esp_rom_cache_esp32s2_esp32s3.*(.literal .literal.* .text .text.*) + *libzephyr.a:cache_utils.*(.literal .text .literal.* .text.*) + *libzephyr.a:esp_rom_spiflash.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_systimer.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_wdt.*(.literal .literal.* .text .text.*) + *libzephyr.a:esp_rom_efuse.*(.literal .literal.* .text .text.*) + + /* [mapping:esp_mm] */ + *libzephyr.a:esp_cache.*(.literal .literal.* .text .text.*) + . = ALIGN(16); } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) - .flash.text : ALIGN(16) + /* Marks the end of IRAM code segment */ + .iram0.text_end (NOLOAD) : { - _stext = .; - _text_start = ABSOLUTE(.); - - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - *(.literal .text .literal.* .text.*) - - /* CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; + /* ESP32-S3 memprot requires 16B padding for possible CPU prefetch and 256B alignment for PMS split lines */ + . = ALIGN(4) + 16; + _iram_text_end = ABSOLUTE(.); + } GROUP_LINK_IN(IRAM_REGION) - _text_end = ABSOLUTE(.); - _etext = .; - - /* Similar to _iram_start, this symbol goes here so it is - * resolved by addr2line in preference to the first symbol in - * the flash.text segment. - */ + .iram0.data : + { . = ALIGN(4); - _flash_cache_start = ABSOLUTE(0); + _iram_data_start = ABSOLUTE(.); + *(.iram.data) + *(.iram.data*) + _iram_data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) + .iram0.bss (NOLOAD) : + { + . = ALIGN(4); + _iram_bss_start = ABSOLUTE(.); + *(.iram.bss) + *(.iram.bss*) + _iram_bss_end = ABSOLUTE(.); . = ALIGN(4); _iram_end = ABSOLUTE(.); - - } GROUP_DATA_LINK_IN(IRAM_REGION, ROMABLE_REGION) + } GROUP_LINK_IN(IRAM_REGION) /* --- END OF IRAM --- */ @@ -238,15 +365,21 @@ SECTIONS .dram0.dummy (NOLOAD): { - . = ORIGIN(dram0_1_seg) + MAX(_iram_end, appcpu_iram_org) - appcpu_iram_org; + . = ORIGIN(dram0_1_seg) + (MAX(_iram_end, _init_start) - _init_start); . = ALIGN(16); } GROUP_LINK_IN(RAMABLE_REGION) .dram0.data : { . = ALIGN (8); - __data_start = ABSOLUTE(.); _data_start = ABSOLUTE(.); + __data_start = ABSOLUTE(.); + + /* bluetooth library requires this symbol to be defined */ + _btdm_data_start = ABSOLUTE(.); + *libbtdm_app.a:(.data .data.*) + . = ALIGN (4); + _btdm_data_end = ABSOLUTE(.); *(.data) *(.data.*) @@ -258,20 +391,126 @@ SECTIONS *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) + *(.srodata) + *(.srodata.*) /* rodata for panic handler(libarch__xtensa__core.a) and all * dependent functions should be placed in DRAM to avoid issue * when flash cache is disabled */ *libarch__xtensa__core.a:(.rodata .rodata.*) *libkernel.a:fatal.*(.rodata .rodata.*) *libkernel.a:init.*(.rodata .rodata.*) - *libzephyr.a:cbprintf_complete*(.rodata .rodata.*) - *libzephyr.a:systimer_hal.*(.rodata .rodata.*) + *libzephyr.a:cbprintf_complete.*(.rodata .rodata.*) *libzephyr.a:log_core.*(.rodata .rodata.*) *libzephyr.a:log_backend_uart.*(.rodata .rodata.*) *libzephyr.a:log_output.*(.rodata .rodata.*) + *libzephyr.a:log_minimal.*(.rodata .rodata.*) *libzephyr.a:loader.*(.rodata .rodata.*) + *libzephyr.a:flash_init.*(.rodata .rodata.*) + *libzephyr.a:soc_flash_init.*(.rodata .rodata.*) + *libzephyr.a:console_init.*(.rodata .rodata.*) + *libzephyr.a:soc_init.*(.rodata .rodata.*) + *libzephyr.a:hw_init.*(.rodata .rodata.*) + *libzephyr.a:soc_random.*(.rodata .rodata.*) *libdrivers__serial.a:uart_esp32.*(.rodata .rodata.*) - *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) + *libdrivers__flash.a:flash_esp32.*(.rodata .rodata.*) + *libzephyr.a:esp_mmu_map.*(.rodata .rodata.*) + *libdrivers__interrupt_controller.a:(.rodata .rodata.*) + + /* APPCPU_ENABLE */ + *libzephyr.a:esp32s3-mp.*(.rodata .rodata.*) + *libzephyr.a:bootloader_flash.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*) + *libzephyr.a:flash_mmap.*(.rodata .rodata.* .sdata2 .sdata2.* .srodata .srodata.*) + + /* [mapping:esp_psram] */ + *libzephyr.a:mmu_psram_flash.*(.rodata .rodata.*) + *libzephyr.a:esp_psram_impl_octal.*(.rodata .rodata.*) + *libzephyr.a:esp_psram_impl_quad.*(.rodata .rodata.*) + + /* [mapping:hal] */ + *libzephyr.a:mmu_hal.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_hal_iram.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_encrypt_hal_iram.*(.rodata .rodata.*) + *libzephyr.a:cache_hal.*(.rodata .rodata.*) + *libzephyr.a:ledc_hal_iram.*(.rodata .rodata.*) + *libzephyr.a:i2c_hal_iram.*(.rodata .rodata.*) + *libzephyr.a:wdt_hal_iram.*(.rodata .rodata.*) + *libzephyr.a:systimer_hal.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_hal_gpspi.*(.rodata .rodata.*) + + /* [mapping:soc] */ + *libzephyr.a:lldesc.*(.rodata .rodata.*) + + /* [mapping:log] */ + *(.rodata.esp_log_write) + *(.rodata.esp_log_timestamp) + *(.rodata.esp_log_early_timestamp) + *(.rodata.esp_log_impl_lock) + *(.rodata.esp_log_impl_lock_timeout) + *(.rodata.esp_log_impl_unlock) + + /* [mapping:spi_flash] */ + *libzephyr.a:spi_flash_chip_boya.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_chip_gd.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_chip_generic.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_chip_issi.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_chip_mxic.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_chip_mxic_opi.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_chip_th.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_chip_winbond.*(.rodata .rodata.*) + *libzephyr.a:memspi_host_driver.*(.rodata .rodata.*) + *libzephyr.a:flash_brownout_hook.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_wrap.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_hpm_enable.*(.rodata .rodata.*) + *libzephyr.a:spi_flash_oct_flash_init.*(.rodata .rodata.*) + *libzephyr.a:flash_qio_mode.*(.rodata .rodata.*) + *libzephyr.a:flash_ops.*(.rodata .rodata.*) + + /* [mapping:esp_mm] */ + *libzephyr.a:esp_cache.*(.rodata .rodata.*) + + /* [mapping:esp_hw_support] */ + *(.rodata.esp_cpu_stall) + *(.rodata.esp_cpu_unstall) + *(.rodata.esp_cpu_reset) + *(.rodata.esp_cpu_wait_for_intr) + *(.rodata.esp_cpu_compare_and_set) + *(.rodata.esp_gpio_reserve_pins) + *(.rodata.esp_gpio_is_pin_reserved) + *(.rodata.rtc_vddsdio_get_config) + *(.rodata.rtc_vddsdio_set_config) + *libzephyr.a:esp_memory_utils.*(.rodata .rodata.*) + *libzephyr.a:rtc_clk.*(.rodata .rodata.*) + *libzephyr.a:rtc_clk_init.*(.rodata .rodata.*) + *libzephyr.a:systimer.*(.rodata .rodata.*) + *libzephyr.a:mspi_timing_config.*(.rodata .rodata.*) + *libzephyr.a:mspi_timing_tuning.*(.rodata .rodata.*) + *(.rodata.sar_periph_ctrl_power_enable) + + /* [mapping:soc_pm] */ + *(.rodata.GPIO_HOLD_MASK) + + /* [mapping:esp_rom] */ + *libzephyr.a:esp_rom_cache_esp32s2_esp32s3.*(.rodata .rodata.*) + *libzephyr.a:cache_utils.*(.rodata .rodata.*) + *libzephyr.a:esp_rom_spiflash.*(.rodata .rodata.*) + *libzephyr.a:esp_rom_systimer.*(.rodata .rodata.*) + *libzephyr.a:esp_rom_wdt.*(.rodata .rodata.*) + *libzephyr.a:esp_rom_efuse.*(.rodata .rodata.*) + + /* [mapping:esp_system] */ + *libzephyr.a:esp_err.*(.rodata .rodata.*) + *(.rodata.esp_system_abort) + +#if defined(CONFIG_ESP32_WIFI_IRAM_OPT) + /* [mapping:esp_wifi] */ + *(.rodata.wifi_clock_enable_wrapper) + *(.rodata.wifi_clock_disable_wrapper) + + /* [mapping:esp_phy] */ + *(.rodata.esp_phy_enable) + *(.rodata.esp_phy_disable) + *(.rodata.esp_wifi_bt_power_domain_off) +#endif . = ALIGN(4); #include @@ -279,7 +518,7 @@ SECTIONS KEEP(*(.jcr)) *(.dram1 .dram1.*) - . = ALIGN(16); + . = ALIGN(4); } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) @@ -288,10 +527,135 @@ SECTIONS #include #include #include + + /* logging sections should be placed in RAM area to avoid flash cache disabled issues */ + #pragma push_macro("GROUP_ROM_LINK_IN") + #undef GROUP_ROM_LINK_IN + #define GROUP_ROM_LINK_IN GROUP_DATA_LINK_IN #include + #pragma pop_macro("GROUP_ROM_LINK_IN") + + .dram0.data_end : + { + __data_end = ABSOLUTE(.); + _data_end = ABSOLUTE(.); + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + .dram0.noinit (NOLOAD): + { + . = ALIGN(8); + *(.noinit) + *(.noinit.*) + . = ALIGN(8) ; + } GROUP_LINK_IN(RAMABLE_REGION) + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); /* required by bluetooth library */ + __bss_start = ABSOLUTE(.); + + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + __bss_end = ABSOLUTE(.); + } GROUP_LINK_IN(RAMABLE_REGION) + + /* Provide total SRAM usage, including IRAM and DRAM */ + _image_ram_start = _init_start - IRAM_DRAM_OFFSET; + #include + + ASSERT(((__bss_end - ORIGIN(dram0_1_seg)) <= LENGTH(dram0_1_seg)), "DRAM segment data does not fit.") + + /* --- END OF DRAM --- */ - /* SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) */ - .dram0.rodata : ALIGN(4) + /* --- START OF IROM --- */ + + /* Symbols used during the application memory mapping */ + _image_irom_start = LOADADDR(.flash.text); + _image_irom_size = LOADADDR(.flash.text) + SIZEOF(.flash.text) - _image_irom_start; + _image_irom_vaddr = ADDR(.flash.text); + + /* Align next section to 64k to allow mapping */ + .flash.text_dummy (NOLOAD) : + { + . = ALIGN(CACHE_ALIGN); + } GROUP_LINK_IN(ROMABLE_REGION) + + .flash.text : ALIGN(16) + { + _stext = .; + _text_start = ABSOLUTE(.); + + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + *(.literal .text .literal.* .text.*) + + /* CPU will try to prefetch up to 16 bytes of + * of instructions. This means that any configuration (e.g. MMU, PMS) must allow + * safe access to up to 16 bytes after the last real instruction, add + * dummy bytes to ensure this + */ + . += 16; + + _text_end = ABSOLUTE(.); + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + * resolved by addr2line in preference to the first symbol in + * the flash.text segment. + */ + . = ALIGN(4); + _flash_cache_start = ABSOLUTE(0); + + . = ALIGN(4); + + } GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION) + + /* --- END OF IROM --- */ + + /* --- START OF DROM --- */ + + /* This dummy section represents the .flash.text section but in default_rodata_seg. + * Thus, it must have its alignment and (at least) its size. + */ + .cache.rodata_dummy (NOLOAD): + { + _cache_rodata_dummy_start = ABSOLUTE(.); + . += SIZEOF(.flash.text); + . = ALIGN(CACHE_ALIGN); + _cache_rodata_dummy_end = ABSOLUTE(.); + } GROUP_LINK_IN(RODATA_REGION) + + .flash.rodata_dummy (NOLOAD): + { + _flash_rodata_dummy_start = ABSOLUTE(.); + . += SIZEOF(.flash.text); + . = ALIGN(CACHE_ALIGN); + _flash_rodata_dummy_end = ABSOLUTE(.); + } GROUP_LINK_IN(ROMABLE_REGION) + + _image_drom_start = LOADADDR(.flash.rodata); + _image_drom_size = LOADADDR(.flash.rodata_end) + SIZEOF(.flash.rodata_end) - _image_drom_start; + _image_drom_vaddr = ADDR(.flash.rodata); + + .flash.rodata : ALIGN(4) { _rodata_start = ABSOLUTE(.); @@ -303,28 +667,9 @@ SECTIONS #include . = ALIGN(4); - *(EXCLUDE_FILE ( - *libarch__xtensa__core.a:* - *libkernel.a:fatal.* - *libkernel.a:init.* - *libzephyr.a:cbprintf_complete* - *libzephyr.a:log_core.* - *libzephyr.a:log_backend_uart.* - *libzephyr.a:log_output.* - *libzephyr.a:loader.* - *libdrivers__serial.a:uart_esp32.*) .rodata) - - *(EXCLUDE_FILE ( - *libarch__xtensa__core.a:* - *libkernel.a:fatal.* - *libkernel.a:init.* - *libzephyr.a:cbprintf_complete* - *libzephyr.a:log_core.* - *libzephyr.a:log_backend_uart.* - *libzephyr.a:log_output.* - *libzephyr.a:loader.* - *libdrivers__serial.a:uart_esp32.*) .rodata.*) + *(.rodata) + *(.rodata.*) . = ALIGN(4); *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ @@ -365,15 +710,8 @@ SECTIONS *(.rodata_wlog) *(.rodata_wlog*) _thread_local_end = ABSOLUTE(.); - _rodata_reserved_end = ABSOLUTE(.); . = ALIGN(4); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) - - /* Flash segments (rodata and text) should be mapped in virtual address space by providing VMA. - * Executing directly from LMA is not possible. */ - #pragma push_macro("GROUP_ROM_LINK_IN") - #undef GROUP_ROM_LINK_IN - #define GROUP_ROM_LINK_IN(vregion, lregion) > RAMABLE_REGION AT > lregion + } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) #include #include @@ -386,71 +724,19 @@ SECTIONS #include #include - #pragma pop_macro("GROUP_ROM_LINK_IN") - /* Create an explicit section at the end of all the data that shall be mapped into drom. * This is used to calculate the size of the _image_drom_size variable */ - /* SECTION_PROLOGUE(_RODATA_SECTION_END,,) */ - .dram0.rodata_end : ALIGN(0x10) + .flash.rodata_end : ALIGN(16) { . = ALIGN(16); + _rodata_reserved_end = ABSOLUTE(.); _image_rodata_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) - - - .dram0.end : - { - __data_end = ABSOLUTE(.); - _data_end = ABSOLUTE(.); - } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) - - .dram0.noinit (NOLOAD): - { - . = ALIGN(8); - *(.noinit) - *(.noinit.*) - . = ALIGN(8) ; - } GROUP_LINK_IN(RAMABLE_REGION) - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _bss_start = ABSOLUTE(.); /* required by bluetooth library */ - __bss_start = ABSOLUTE(.); - - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.share.mem) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - __bss_end = ABSOLUTE(.); - } GROUP_LINK_IN(RAMABLE_REGION) + } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) - /* Provide total SRAM usage, including IRAM and DRAM */ - _image_ram_start = _iram_start - IRAM_DRAM_OFFSET; - #include - - ASSERT(((__bss_end - ORIGIN(dram0_1_seg)) <= LENGTH(dram0_1_seg)), "DRAM segment data does not fit.") - - /* --- END OF DRAM --- */ - - /* --- START OF IROM --- */ - /* --- END OF IROM --- */ - - /* --- START OF DROM --- */ /* --- END OF DROM --- */ + /* --- XTENSA GLUE AND DEBUG BEGIN --- */ + #ifdef CONFIG_GEN_ISR_TABLES #include #endif @@ -492,5 +778,10 @@ SECTIONS } } + /* --- XTENSA GLUE AND DEBUG END --- */ + ASSERT(((_iram_end - ORIGIN(iram0_1_seg)) <= LENGTH(iram0_1_seg)), "IRAM0 segment data does not fit.") + +ASSERT(((_end - ORIGIN(dram0_1_seg)) <= LENGTH(dram0_1_seg)), + "DRAM segment data does not fit.") diff --git a/soc/espressif/esp32s3/esp32s3-mp.c b/soc/espressif/esp32s3/esp32s3-mp.c index 8cae6d5e87cad..fadbd9224189e 100644 --- a/soc/espressif/esp32s3/esp32s3-mp.c +++ b/soc/espressif/esp32s3/esp32s3-mp.c @@ -12,12 +12,17 @@ #include #include +#include #include #include "esp_rom_uart.h" #include "esp_mcuboot_image.h" #include "esp_memory_utils.h" +#include "hw_init.h" +#define TAG "amp" + +/* AMP support */ #ifdef CONFIG_SOC_ENABLE_APPCPU #include "bootloader_flash_priv.h" @@ -46,7 +51,7 @@ static int load_segment(uint32_t src_addr, uint32_t src_len, uint32_t dst_addr) const uint32_t *data = (const uint32_t *)sys_mmap(src_addr, src_len); if (!data) { - ets_printf("%s: mmap failed", __func__); + ESP_EARLY_LOGE(TAG, "%s: mmap failed", __func__); return -1; } @@ -63,24 +68,20 @@ static int load_segment(uint32_t src_addr, uint32_t src_len, uint32_t dst_addr) int IRAM_ATTR esp_appcpu_image_load(unsigned int hdr_offset, unsigned int *entry_addr) { - const uint32_t img_off = FIXED_PARTITION_OFFSET(slot0_appcpu_partition); + const uint32_t fa_offset = FIXED_PARTITION_OFFSET(slot0_appcpu_partition); const uint32_t fa_size = FIXED_PARTITION_SIZE(slot0_appcpu_partition); const uint8_t fa_id = FIXED_PARTITION_ID(slot0_appcpu_partition); - int rc = 0; if (entry_addr == NULL) { - ets_printf("Can't return the entry address. Aborting!\n"); + ESP_EARLY_LOGE(TAG, "Can't return the entry address. Aborting!"); abort(); return -1; } - ets_printf("Loading appcpu image, area id: %d, offset: 0x%x, hdr.off: 0x%x, size: %d kB\n", - fa_id, img_off, hdr_offset, fa_size / 1024); - uint32_t mcuboot_header[8] = {0}; esp_image_load_header_t image_header = {0}; - const uint32_t *data = (const uint32_t *)sys_mmap(img_off, 0x40); + const uint32_t *data = (const uint32_t *)sys_mmap(fa_offset, 0x80); memcpy((void *)&mcuboot_header, data, sizeof(mcuboot_header)); memcpy((void *)&image_header, data + (hdr_offset / sizeof(uint32_t)), @@ -89,54 +90,75 @@ int IRAM_ATTR esp_appcpu_image_load(unsigned int hdr_offset, unsigned int *entry sys_munmap(data); if (image_header.header_magic == ESP_LOAD_HEADER_MAGIC) { - ets_printf("MCUboot image format\n"); + ESP_EARLY_LOGI(TAG, + "APPCPU image, area id: %d, offset: 0x%x, hdr.off: 0x%x, size: %d kB", + fa_id, fa_offset, hdr_offset, fa_size / 1024); } else if ((image_header.header_magic & 0xff) == 0xE9) { - ets_printf("ESP image format is not supported\n"); + ESP_EARLY_LOGE(TAG, "ESP image format is not supported"); abort(); } else { - ets_printf("Unknown or empty image detected. Aborting!\n"); + ESP_EARLY_LOGE(TAG, "Unknown or empty image detected. Aborting!"); abort(); } if (!esp_ptr_in_iram((void *)image_header.iram_dest_addr) || !esp_ptr_in_iram((void *)(image_header.iram_dest_addr + image_header.iram_size))) { - ets_printf("IRAM region in load header is not valid. Aborting"); + ESP_EARLY_LOGE(TAG, "IRAM region in load header is not valid. Aborting"); abort(); } if (!esp_ptr_in_dram((void *)image_header.dram_dest_addr) || !esp_ptr_in_dram((void *)(image_header.dram_dest_addr + image_header.dram_size))) { - ets_printf("DRAM region in load header is not valid. Aborting"); + ESP_EARLY_LOGE(TAG, "DRAM region in load header is not valid. Aborting"); abort(); } if (!esp_ptr_in_iram((void *)image_header.entry_addr)) { - ets_printf("Application entry point (%xh) is not in IRAM. Aborting", + ESP_EARLY_LOGE(TAG, "Application entry point (%xh) is not in IRAM. Aborting", image_header.entry_addr); abort(); } - ets_printf("IRAM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) load\n", - (img_off + image_header.iram_flash_offset), image_header.iram_dest_addr, + ESP_EARLY_LOGI(TAG, "IRAM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) load", + (fa_offset + image_header.iram_flash_offset), image_header.iram_dest_addr, image_header.iram_size, image_header.iram_size); - load_segment(img_off + image_header.iram_flash_offset, image_header.iram_size, + load_segment(fa_offset + image_header.iram_flash_offset, image_header.iram_size, image_header.iram_dest_addr); - ets_printf("DRAM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) load\n", - (img_off + image_header.dram_flash_offset), image_header.dram_dest_addr, + ESP_EARLY_LOGI(TAG, "DRAM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) load", + (fa_offset + image_header.dram_flash_offset), image_header.dram_dest_addr, image_header.dram_size, image_header.dram_size); - load_segment(img_off + image_header.dram_flash_offset, image_header.dram_size, + load_segment(fa_offset + image_header.dram_flash_offset, image_header.dram_size, image_header.dram_dest_addr); - ets_printf("Application start=%xh\n", image_header.entry_addr); + ESP_EARLY_LOGI(TAG, "IROM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) map", + (fa_offset + image_header.irom_flash_offset), image_header.irom_map_addr, + image_header.irom_size, image_header.irom_size); + + ESP_EARLY_LOGI(TAG, "DROM segment: paddr=%08xh, vaddr=%08xh, size=%05xh (%6d) map", + (fa_offset + image_header.drom_flash_offset), image_header.drom_map_addr, + image_header.drom_size, image_header.drom_size); + + struct rom_segments rom = { + image_header.drom_map_addr, + image_header.drom_flash_offset + fa_offset, + image_header.drom_size, + image_header.irom_map_addr, + image_header.irom_flash_offset + fa_offset, + image_header.irom_size, + }; + + map_rom_segments(1, &rom); + + ESP_EARLY_LOGI(TAG, "Application start=%xh\n\n", image_header.entry_addr); esp_rom_uart_tx_wait_idle(0); assert(entry_addr != NULL); *entry_addr = image_header.entry_addr; - return rc; + return 0; } void esp_appcpu_image_stop(void) @@ -169,4 +191,10 @@ int esp_appcpu_init(void) return 0; } + +#if !defined(CONFIG_MCUBOOT) +extern int esp_appcpu_init(void); +SYS_INIT(esp_appcpu_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +#endif + #endif /* CONFIG_SOC_ENABLE_APPCPU */ diff --git a/soc/espressif/esp32s3/hw_init.c b/soc/espressif/esp32s3/hw_init.c index 97ffb0ef8265c..a53f7753148b6 100644 --- a/soc/espressif/esp32s3/hw_init.c +++ b/soc/espressif/esp32s3/hw_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -42,33 +42,17 @@ int hardware_init(void) #ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE esp_cpu_configure_region_protection(); #endif -#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V - rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config(); - - if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { - cfg.drefh = 3; - cfg.drefm = 3; - cfg.drefl = 3; - cfg.force = 1; - rtc_vddsdio_set_config(cfg); - esp_rom_delay_us(10); - } -#endif /* CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V */ bootloader_clock_configure(); +#ifdef CONFIG_ESP_CONSOLE /* initialize console, from now on, we can log */ esp_console_init(); print_banner(); - - spi_flash_init_chip_state(); - err = esp_flash_init_default_chip(); - if (err != 0) { - ESP_EARLY_LOGE(TAG, "Failed to init flash chip, error %d", err); - return err; - } +#endif /* CONFIG_ESP_CONSOLE */ cache_hal_init(); + mmu_hal_init(); flash_update_id(); @@ -95,6 +79,7 @@ int hardware_init(void) } check_wdt_reset(); + config_wdt(); soc_random_enable(); diff --git a/soc/espressif/esp32s3/mcuboot.ld b/soc/espressif/esp32s3/mcuboot.ld index f0fb717d5d91b..7c5271ae50fcb 100644 --- a/soc/espressif/esp32s3/mcuboot.ld +++ b/soc/espressif/esp32s3/mcuboot.ld @@ -47,28 +47,17 @@ SECTIONS *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *libarch__xtensa__core.a:xtensa_asm2_util.*(.literal .text .literal.* .text.*) - *liblib__libc__common.a:abort.*(.literal .text .literal.* .text.*) - *libdrivers__timer.a:xtensa_sys_timer.*(.literal .text .literal.* .text.*) *libarch__common.a:dynamic_isr.*(.literal .text .literal.* .text.*) *libarch__common.a:sw_isr_common.*(.literal .text .literal.* .text.*) *libapp.a:flash_map_extended.*(.literal .text .literal.* .text.*) - *libzephyr.a:printk.*(.literal.printk .literal.vprintk .literal.char_out .text.printk .text.vprintk .text.char_out) *libzephyr.a:cbprintf_nano.*(.literal .text .literal.* .text.*) *libzephyr.a:cpu.*(.literal .text .literal.* .text.*) *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *libzephyr.a:flash_map.*(.literal .text .literal.* .text.*) *libzephyr.a:esp_rom_spiflash.*(.literal .text .literal.* .text.*) - - *libzephyr.a:heap.*(.literal .text .literal.* .text.*) - - *libkernel.a:kheap.*(.literal .text .literal.* .text.*) - *libkernel.a:mempool.*(.literal .text .literal.* .text.*) *libkernel.a:device.*(.literal .text .literal.* .text.*) - *libkernel.a:timeout.*(.literal .text .literal.* .text.*) - *libzephyr.a:esp_loader.*(.literal .text .literal.* .text.*) - *libzephyr.a:mmu_hal.*(.literal .text .literal.* .text.*) *(.literal.esp_intr_disable .literal.esp_intr_disable.* .text.esp_intr_disable .text.esp_intr_disable.*) *(.literal.default_intr_handler .text.default_intr_handler .iram1.*.default_intr_handler) diff --git a/soc/espressif/esp32s3/memory.h b/soc/espressif/esp32s3/memory.h index f3e22a0451375..9888542505325 100644 --- a/soc/espressif/esp32s3/memory.h +++ b/soc/espressif/esp32s3/memory.h @@ -7,14 +7,14 @@ /* SRAM0 (32k), SRAM1 (416k), SRAM2 (64k) memories * Ibus and Dbus address space */ -#define SRAM0_IRAM_START 0x40370000 -#define SRAM0_SIZE 0x8000 -#define SRAM1_DRAM_START 0x3fc88000 -#define SRAM1_IRAM_START 0x40378000 +#define SRAM0_IRAM_START DT_REG_ADDR(DT_NODELABEL(sram0)) +#define SRAM0_SIZE DT_REG_SIZE(DT_NODELABEL(sram0)) +#define SRAM1_DRAM_START DT_REG_ADDR(DT_NODELABEL(sram1)) +#define SRAM1_IRAM_START (SRAM0_IRAM_START + SRAM0_SIZE) #define SRAM_USER_IRAM_START (SRAM0_IRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE) -#define SRAM2_DRAM_START 0x3fcf0000 -#define SRAM2_SIZE 0x10000 +#define SRAM2_DRAM_START DT_REG_ADDR(DT_NODELABEL(sram2)) +#define SRAM2_SIZE DT_REG_SIZE(DT_NODELABEL(sram2)) #define SRAM2_USER_DRAM_START (SRAM2_DRAM_START + CONFIG_ESP32S3_DATA_CACHE_SIZE) #define SRAM2_USER_DRAM_SIZE (SRAM2_SIZE - CONFIG_ESP32S3_DATA_CACHE_SIZE) @@ -68,6 +68,7 @@ * and it should not be overlapped by the user image. * When there is no 2nd stage bootloader the bootstrapping is done * by the so-called SIMPLE_BOOT. + * NOTE: AMP is supported only if MCUboot is enabled. */ #ifdef CONFIG_ESP_SIMPLE_BOOT #define USER_DRAM_END BOOTLOADER_USER_DRAM_END @@ -77,29 +78,37 @@ #define USER_IRAM_END (USER_DRAM_END + IRAM_DRAM_OFFSET) /* AMP */ -#if defined(CONFIG_SOC_ENABLE_APPCPU) || defined(CONFIG_SOC_ESP32S3_APPCPU) -#define APPCPU_IRAM_SIZE CONFIG_ESP32S3_APPCPU_IRAM_SIZE -#define APPCPU_DRAM_SIZE CONFIG_ESP32S3_APPCPU_DRAM_SIZE -#define AMP_COMM_SIZE (0x4000 + 0x400) +#if (defined(CONFIG_SOC_ENABLE_APPCPU) || defined(CONFIG_SOC_ESP32S3_APPCPU)) +#define APPCPU_IRAM_SIZE CONFIG_ESP_APPCPU_IRAM_SIZE +#define APPCPU_DRAM_SIZE CONFIG_ESP_APPCPU_DRAM_SIZE +#define AMP_COMM_SIZE DT_REG_SIZE(DT_NODELABEL(ipmmem0)) + DT_REG_SIZE(DT_NODELABEL(shm0)) + \ + DT_REG_SIZE(DT_NODELABEL(ipm0)) + DT_REG_SIZE(DT_NODELABEL(mbox0)) +#undef DRAM_RESERVED_START +#define DRAM_RESERVED_START 0x3fce5000 +#define APPCPU_IROM_SIZE CONFIG_ESP_APPCPU_IROM_SIZE +#define APPCPU_DROM_SIZE CONFIG_ESP_APPCPU_DROM_SIZE #else #define APPCPU_IRAM_SIZE 0 #define APPCPU_DRAM_SIZE 0 #define AMP_COMM_SIZE 0 +#define APPCPU_IROM_SIZE 0 +#define APPCPU_DROM_SIZE 0 #endif -#define APPCPU_SRAM_SIZE (APPCPU_IRAM_SIZE + APPCPU_DRAM_SIZE) -#define APPCPU_SRAM_TOTAL_SIZE (APPCPU_SRAM_SIZE + AMP_COMM_SIZE) +#define APPCPU_SRAM_SIZE (APPCPU_IRAM_SIZE + APPCPU_DRAM_SIZE) +#define APPCPU_ROM_SIZE (APPCPU_IROM_SIZE + APPCPU_DROM_SIZE) -/* Flash */ +/* Cached memory */ +#define ICACHE0_START DT_REG_ADDR(DT_NODELABEL(icache0)) +#define ICACHE0_SIZE DT_REG_SIZE(DT_NODELABEL(icache0)) +#define DCACHE0_START DT_REG_ADDR(DT_NODELABEL(dcache0)) +#define DCACHE0_SIZE DT_REG_SIZE(DT_NODELABEL(dcache0)) + +#define CACHE_ALIGN CONFIG_MMU_PAGE_SIZE + +/* Flash memory */ #ifdef CONFIG_FLASH_SIZE #define FLASH_SIZE CONFIG_FLASH_SIZE #else #define FLASH_SIZE 0x800000 #endif - -/* Cached memory */ -#define CACHE_ALIGN CONFIG_MMU_PAGE_SIZE -#define IROM_SEG_ORG 0x42000000 -#define IROM_SEG_LEN FLASH_SIZE -#define DROM_SEG_ORG 0x3c000000 -#define DROM_SEG_LEN FLASH_SIZE diff --git a/soc/espressif/esp32s3/soc.c b/soc/espressif/esp32s3/soc.c index 2449fd9088714..881d709d7a0da 100644 --- a/soc/espressif/esp32s3/soc.c +++ b/soc/espressif/esp32s3/soc.c @@ -1,66 +1,23 @@ /* * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2025 Espressif Systems (Shanghai) CO LTD. * * SPDX-License-Identifier: Apache-2.0 */ -/* Include esp-idf headers first to avoid redefining BIT() macro */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include -#include - -#if CONFIG_ESP_SPIRAM -#include "psram.h" -#endif - -#include -#include -#include -#include -#include -#include - #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include - +#include +#include #include -#include "esp_log.h" - -#include -#include - -#define TAG "boot.esp32s3" extern void z_prep_c(void); extern void esp_reset_reason_init(void); -extern int esp_appcpu_init(void); -#ifndef CONFIG_MCUBOOT -/* - * This function is a container for SoC patches - * that needs to be applied during the startup. - */ static void IRAM_ATTR esp_errata(void) { /* Handle the clock gating fix */ @@ -77,32 +34,9 @@ static void IRAM_ATTR esp_errata(void) Cache_Occupy_Addr(SOC_DROM_LOW, 0x4000); #endif } -#endif /* CONFIG_MCUBOOT */ -/* - * This is written in C rather than assembly since, during the port bring up, - * Zephyr is being booted by the Espressif bootloader. With it, the C stack - * is already set up. - */ -void IRAM_ATTR __esp_platform_start(void) +void IRAM_ATTR __esp_platform_app_start(void) { - extern uint32_t _init_start; - - /* Move the exception vector table to IRAM. */ - __asm__ __volatile__("wsr %0, vecbase" : : "r"(&_init_start)); - - z_bss_zero(); - - /* Disable normal interrupts. */ - __asm__ __volatile__("wsr %0, PS" : : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE)); - - /* Initialize the architecture CPU pointer. Some of the - * initialization code wants a valid arch_current_thread() before - * arch_kernel_init() is invoked. - */ - __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[0])); - -#ifndef CONFIG_MCUBOOT /* Configure the mode of instruction cache : cache size, cache line size. */ esp_config_instruction_cache_mode(); @@ -114,38 +48,17 @@ void IRAM_ATTR __esp_platform_start(void) /* Apply SoC patches */ esp_errata(); - /* ESP-IDF/MCUboot 2nd stage bootloader enables RTC WDT to check on startup sequence - * related issues in application. Hence disable that as we are about to start - * Zephyr environment. - */ - wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; - - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_disable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - esp_reset_reason_init(); esp_timer_early_init(); - esp_mspi_pin_init(); - - esp_flash_app_init(); + esp_flash_config(); - mspi_timing_flash_tuning(); - - esp_mmu_map_init(); + esp_intr_initialize(); #if CONFIG_ESP_SPIRAM esp_init_psram(); -#endif /* CONFIG_ESP_SPIRAM */ -#endif /* !CONFIG_MCUBOOT */ - - esp_intr_initialize(); - -#if CONFIG_ESP_SPIRAM - /* Init Shared Multi Heap for PSRAM */ int err = esp_psram_smh_init(); if (err) { @@ -159,6 +72,16 @@ void IRAM_ATTR __esp_platform_start(void) CODE_UNREACHABLE; } +void IRAM_ATTR __esp_platform_mcuboot_start(void) +{ + esp_intr_initialize(); + + /* Start Zephyr */ + z_prep_c(); + + CODE_UNREACHABLE; +} + /* Boot-time static default printk handler, possibly to be overridden later. */ int IRAM_ATTR arch_printk_char_out(int c) { @@ -173,8 +96,3 @@ void sys_arch_reboot(int type) { esp_restart_noos(); } - -#if defined(CONFIG_SOC_ENABLE_APPCPU) && !defined(CONFIG_MCUBOOT) -extern int esp_appcpu_init(void); -SYS_INIT(esp_appcpu_init, POST_KERNEL, 50); -#endif diff --git a/soc/espressif/esp32s3/soc.h b/soc/espressif/esp32s3/soc.h index 1d6d2204cf41c..f74376cc5ba58 100644 --- a/soc/espressif/esp32s3/soc.h +++ b/soc/espressif/esp32s3/soc.h @@ -25,7 +25,8 @@ #include #include -void __esp_platform_start(void); +void __esp_platform_mcuboot_start(void); +void __esp_platform_app_start(void); static inline void esp32_set_mask32(uint32_t v, uint32_t mem_addr) { diff --git a/soc/espressif/esp32s3/soc_appcpu.c b/soc/espressif/esp32s3/soc_appcpu.c index 1ec3bbf94aab7..a03304c87519e 100644 --- a/soc/espressif/esp32s3/soc_appcpu.c +++ b/soc/espressif/esp32s3/soc_appcpu.c @@ -65,7 +65,7 @@ void IRAM_ATTR __appcpu_start(void) __asm__ __volatile__("wsr %0, PS" : : "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE)); /* Initialize the architecture CPU pointer. Some of the - * initialization code wants a valid arch_current_thread() before + * initialization code wants a valid _current before * arch_kernel_init() is invoked. */ __asm__ __volatile__("wsr.MISC0 %0; rsync" : : "r"(&_kernel.cpus[1])); diff --git a/soc/gd/gd32/gd32vf103/CMakeLists.txt b/soc/gd/gd32/gd32vf103/CMakeLists.txt index 6778c0a4f1b3a..649c118de6700 100644 --- a/soc/gd/gd32/gd32vf103/CMakeLists.txt +++ b/soc/gd/gd32/gd32vf103/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_sources(entry.S) zephyr_sources(soc.c) +zephyr_sources(soc_irq.S) zephyr_include_directories(.) diff --git a/soc/gd/gd32/gd32vf103/Kconfig b/soc/gd/gd32/gd32vf103/Kconfig index b14bddbd46a08..99f60cd6ab861 100644 --- a/soc/gd/gd32/gd32vf103/Kconfig +++ b/soc/gd/gd32/gd32vf103/Kconfig @@ -14,6 +14,7 @@ config SOC_SERIES_GD32VF103 select RISCV_ISA_EXT_ZIFENCEI select RISCV_HAS_CLIC select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING + select RISCV_SOC_CONTEXT_SAVE select ATOMIC_OPERATIONS_C select INCLUDE_RESET_VECTOR select GD32_HAS_AFIO_PINMUX diff --git a/soc/gd/gd32/gd32vf103/soc_context.h b/soc/gd/gd32/gd32vf103/soc_context.h new file mode 100644 index 0000000000000..51a082aa0bf2c --- /dev/null +++ b/soc/gd/gd32/gd32vf103/soc_context.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Andes Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H +#define SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H + +#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE + + #define SOC_ESF_MEMBERS + + #define SOC_ESF_INIT + +#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */ + +#endif /* SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H */ diff --git a/soc/gd/gd32/gd32vf103/soc_irq.S b/soc/gd/gd32/gd32vf103/soc_irq.S new file mode 100644 index 0000000000000..fe0248dad166c --- /dev/null +++ b/soc/gd/gd32/gd32vf103/soc_irq.S @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Andes Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* Exports */ +#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE +GTEXT(__soc_save_context) +GTEXT(__soc_restore_context) +#endif + +#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE + +SECTION_FUNC(exception.other, __soc_save_context) + + ret + +SECTION_FUNC(exception.other, __soc_restore_context) + + /* + * For Nuclei ECLIC, the interrupt level (mintstatus.MIL) is restored + * from the previous interrupt level (mcause.MPIL) only if + * mcause.interrupt is set when executing MRET. + * Always set the next context's mcause.interrupt to ensure the + * interrupt level is restored correctly after MRET. + */ + addi a0, a0, -__struct_arch_esf_soc_context_OFFSET + lw t0, __struct_arch_esf_mcause_OFFSET(a0) + li t1, 1 << RISCV_MCAUSE_IRQ_POS + or t0, t0, t1 + sw t0, __struct_arch_esf_mcause_OFFSET(a0) + + ret + +#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */ diff --git a/soc/gd/gd32/gd32vf103/soc_offsets.h b/soc/gd/gd32/gd32vf103/soc_offsets.h new file mode 100644 index 0000000000000..7322e91b81d7d --- /dev/null +++ b/soc/gd/gd32/gd32vf103/soc_offsets.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Andes Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_ +#define SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_ + +#ifdef CONFIG_RISCV_SOC_OFFSETS + + #define GEN_SOC_OFFSET_SYMS() + +#endif /* CONFIG_RISCV_SOC_OFFSETS */ + +#endif /* SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_*/ diff --git a/soc/infineon/cat1a/Kconfig b/soc/infineon/cat1a/Kconfig index c69e8f5e0bdf7..c257f5195e9f6 100644 --- a/soc/infineon/cat1a/Kconfig +++ b/soc/infineon/cat1a/Kconfig @@ -12,11 +12,13 @@ config SOC_FAMILY_PSOC6 select DYNAMIC_INTERRUPTS select CPU_HAS_FPU select SOC_FAMILY_INFINEON_CAT1 + select BUILD_OUTPUT_HEX config SOC_FAMILY_PSOC6_LEGACY select ARM select HAS_CYPRESS_DRIVERS select CPU_CORTEX_M_HAS_SYSTICK + select BUILD_OUTPUT_HEX select CPU_HAS_ARM_MPU config SOC_FAMILY_PSOC6_LEGACY_M4 diff --git a/soc/infineon/cat1a/psoc6_01/Kconfig.defconfig b/soc/infineon/cat1a/psoc6_01/Kconfig.defconfig index acfefd580e24f..8fa95ba849919 100644 --- a/soc/infineon/cat1a/psoc6_01/Kconfig.defconfig +++ b/soc/infineon/cat1a/psoc6_01/Kconfig.defconfig @@ -13,6 +13,9 @@ config NUM_IRQS config SYS_CLOCK_HW_CYCLES_PER_SEC default 100000000 +config MAIN_STACK_SIZE + default 2048 + # add additional die specific params endif # SOC_DIE_PSOC6_01 diff --git a/soc/infineon/cat1a/psoc6_02/Kconfig.defconfig b/soc/infineon/cat1a/psoc6_02/Kconfig.defconfig index 7f3f36d865fa2..944d43c68b070 100644 --- a/soc/infineon/cat1a/psoc6_02/Kconfig.defconfig +++ b/soc/infineon/cat1a/psoc6_02/Kconfig.defconfig @@ -13,6 +13,12 @@ config NUM_IRQS config SYS_CLOCK_HW_CYCLES_PER_SEC default 100000000 +config BUILD_OUTPUT_HEX + default y + +config MAIN_STACK_SIZE + default 2048 + # add additional die specific params endif # SOC_DIE_PSOC6_02 diff --git a/soc/infineon/cat1a/psoc6_03/Kconfig.defconfig b/soc/infineon/cat1a/psoc6_03/Kconfig.defconfig index 1516df04b3365..50df2131ac32e 100644 --- a/soc/infineon/cat1a/psoc6_03/Kconfig.defconfig +++ b/soc/infineon/cat1a/psoc6_03/Kconfig.defconfig @@ -13,6 +13,9 @@ config NUM_IRQS config SYS_CLOCK_HW_CYCLES_PER_SEC default 100000000 +config MAIN_STACK_SIZE + default 2048 + # add additional die specific params endif # SOC_DIE_PSOC6_03 diff --git a/soc/infineon/cat1a/psoc6_04/Kconfig.defconfig b/soc/infineon/cat1a/psoc6_04/Kconfig.defconfig index 3ebc2882b79be..44d3bd03eaa38 100644 --- a/soc/infineon/cat1a/psoc6_04/Kconfig.defconfig +++ b/soc/infineon/cat1a/psoc6_04/Kconfig.defconfig @@ -13,6 +13,9 @@ config NUM_IRQS config SYS_CLOCK_HW_CYCLES_PER_SEC default 100000000 +config MAIN_STACK_SIZE + default 2048 + # add additional die specific params endif # SOC_DIE_PSOC6_04 diff --git a/soc/infineon/cat1b/cyw20829/CMakeLists.txt b/soc/infineon/cat1b/cyw20829/CMakeLists.txt index 464a3f44a3067..5bbff012c05f5 100644 --- a/soc/infineon/cat1b/cyw20829/CMakeLists.txt +++ b/soc/infineon/cat1b/cyw20829/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_sources(soc.c) zephyr_sources(app_header.c) +zephyr_sources(mpu_regions.c) zephyr_include_directories(.) zephyr_sources_ifdef(CONFIG_PM power.c) diff --git a/soc/infineon/cat1b/cyw20829/Kconfig b/soc/infineon/cat1b/cyw20829/Kconfig index 85ec200be8e9d..f4e960d65c49f 100644 --- a/soc/infineon/cat1b/cyw20829/Kconfig +++ b/soc/infineon/cat1b/cyw20829/Kconfig @@ -8,8 +8,11 @@ config SOC_SERIES_CYW20829 select ARM select CPU_HAS_ARM_MPU + select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS select CPU_CORTEX_M33 - select CPU_HAS_FPU select DYNAMIC_INTERRUPTS select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_PM + select BUILD_OUTPUT_HEX + select BUILD_OUTPUT_BIN + select SOC_EARLY_INIT_HOOK diff --git a/soc/infineon/cat1b/cyw20829/Kconfig.defconfig b/soc/infineon/cat1b/cyw20829/Kconfig.defconfig index 78b2cdd8956f2..06764ebfc9d33 100644 --- a/soc/infineon/cat1b/cyw20829/Kconfig.defconfig +++ b/soc/infineon/cat1b/cyw20829/Kconfig.defconfig @@ -22,6 +22,9 @@ config BUILD_OUTPUT_ADJUST_LMA depends on XIP default "0x60000000 - $(dt_node_reg_addr_hex,$(dt_nodelabel_path,flash0))" +config MAIN_STACK_SIZE + default 2048 + # add additional die specific params endif # SOC_DIE_CYW20829 diff --git a/soc/infineon/cat1b/cyw20829/mpu_regions.c b/soc/infineon/cat1b/cyw20829/mpu_regions.c new file mode 100644 index 0000000000000..e0bbc71984708 --- /dev/null +++ b/soc/infineon/cat1b/cyw20829/mpu_regions.c @@ -0,0 +1,34 @@ +/* Copyright 2024 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define BOOTSTRAP_RAM_BASE_ADDRESS DT_REG_ADDR(DT_NODELABEL(sram_bootstrap)) +#define BOOTSTRAP_RAM_SIZE DT_REG_SIZE(DT_NODELABEL(sram_bootstrap)) + +#define REGION_BOOTSTRAP_RAM_ATTR(base, size) \ + { \ + .rbar = FULL_ACCESS_Msk | NON_SHAREABLE_Msk, \ + .mair_idx = MPU_MAIR_INDEX_SRAM, \ + .r_limit = REGION_LIMIT_ADDR(base, size), \ + } + +static const struct arm_mpu_region mpu_regions[] = { + MPU_REGION_ENTRY("FLASH", CONFIG_FLASH_BASE_ADDRESS, + REGION_FLASH_ATTR(CONFIG_FLASH_BASE_ADDRESS, CONFIG_FLASH_SIZE * 1024)), + + MPU_REGION_ENTRY("SRAM", CONFIG_SRAM_BASE_ADDRESS, + REGION_RAM_ATTR(CONFIG_SRAM_BASE_ADDRESS, CONFIG_SRAM_SIZE * 1024)), + + MPU_REGION_ENTRY("BOOTSTRAP_RAM", BOOTSTRAP_RAM_BASE_ADDRESS, + REGION_BOOTSTRAP_RAM_ATTR(BOOTSTRAP_RAM_BASE_ADDRESS, BOOTSTRAP_RAM_SIZE)), +}; + +const struct arm_mpu_config mpu_config = { + .num_regions = ARRAY_SIZE(mpu_regions), + .mpu_regions = mpu_regions, +}; diff --git a/soc/infineon/cat1b/cyw20829/soc.c b/soc/infineon/cat1b/cyw20829/soc.c index 3a55e035c7940..2ec0cd8ab1060 100644 --- a/soc/infineon/cat1b/cyw20829/soc.c +++ b/soc/infineon/cat1b/cyw20829/soc.c @@ -85,22 +85,16 @@ void disable_mpu_rasr_xn(void) } #endif /* CONFIG_ARM_MPU */ -static int init_cycfg_platform_wrapper(void) +void soc_early_init_hook(void) { #ifdef CONFIG_ARM_MPU disable_mpu_rasr_xn(); -#endif /* CONFIG_ARM_MPU */ +#endif /* CONFIG_ARM_MPU */ /* Initializes the system */ SystemInit(); - return 0; -} - -SYS_INIT(init_cycfg_platform_wrapper, PRE_KERNEL_1, 0); #ifdef CONFIG_PM -void soc_early_init_hook(void) -{ ifx_pm_init(); -} #endif +} diff --git a/soc/intel/intel_adsp/ace/Kconfig.defconfig.series b/soc/intel/intel_adsp/ace/Kconfig.defconfig.series index 1c4ea73ae0da4..0d606715e09ae 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.defconfig.series +++ b/soc/intel/intel_adsp/ace/Kconfig.defconfig.series @@ -23,7 +23,7 @@ config MULTI_LEVEL_INTERRUPTS default y config MAX_IRQ_PER_AGGREGATOR - default 29 + default 30 config NUM_2ND_LEVEL_AGGREGATORS default 1 diff --git a/soc/intel/intel_adsp/ace/ace-link.ld b/soc/intel/intel_adsp/ace/ace-link.ld index cf31c96383a18..2a220746b5dd2 100644 --- a/soc/intel/intel_adsp/ace/ace-link.ld +++ b/soc/intel/intel_adsp/ace/ace-link.ld @@ -171,6 +171,16 @@ SECTIONS { */ .imrdata : ALIGN(4096) { *(.imrdata .imrdata.*) + } >imr + + /* Cold code in IMR memory */ + .cold : ALIGN(4096) { + *(.cold .cold.* ) + } >imr + + /* Cold data. */ + .coldrodata : ALIGN(4096) { + *(.coldrodata .coldrodata.*) _imr_end = .; } >imr @@ -553,6 +563,7 @@ SECTIONS { /* rimage module manifest headers */ .module.boot : { KEEP(*(.module.boot)) } >noload + .module.cold : { KEEP(*(.module.cold)) } >noload .module.main : { KEEP(*(.module.main)) } >noload .static_uuid_entries : { diff --git a/soc/intel/intel_adsp/ace/include/ace30/adsp_interrupt.h b/soc/intel/intel_adsp/ace/include/ace30/adsp_interrupt.h index b34a3fc9f1cc9..9a6848b9af402 100644 --- a/soc/intel/intel_adsp/ace/include/ace30/adsp_interrupt.h +++ b/soc/intel/intel_adsp/ace/include/ace30/adsp_interrupt.h @@ -36,6 +36,7 @@ #define ACE_INTL_DTF 26 #define ACE_INTL_FLV 27 #define ACE_INTL_DPDMA 28 +#define ACE_INTL_MIC_PRIV 29 /* Device interrupt control for the low priority interrupts. It * provides per-core masking and status checking: ACE_DINT is an array diff --git a/soc/intel/intel_adsp/ace/power.c b/soc/intel/intel_adsp/ace/power.c index ed133b8eedd9c..34684e6756c22 100644 --- a/soc/intel/intel_adsp/ace/power.c +++ b/soc/intel/intel_adsp/ace/power.c @@ -340,7 +340,7 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) sys_cache_data_flush_range((void *)imr_layout, sizeof(*imr_layout)); #endif /* CONFIG_ADSP_IMR_CONTEXT_SAVE */ /* do power down - this function won't return */ - power_down(true, CONFIG_ADSP_POWER_DOWN_HPSRAM, true); + power_down(true, IS_ENABLED(CONFIG_ADSP_POWER_DOWN_HPSRAM), true); } else { power_gate_entry(cpu); } diff --git a/soc/intel/intel_adsp/common/CMakeLists.txt b/soc/intel/intel_adsp/common/CMakeLists.txt index 11d8ca67c8b19..267e176d5a458 100644 --- a/soc/intel/intel_adsp/common/CMakeLists.txt +++ b/soc/intel/intel_adsp/common/CMakeLists.txt @@ -82,11 +82,22 @@ add_custom_command( --rename-section .module.boot=.module ${KERNEL_REMAPPED} ${CMAKE_BINARY_DIR}/zephyr/boot.mod 2>${NULL_FILE} + COMMAND ${CMAKE_OBJCOPY} + --only-section .cold + --only-section .coldrodata + --only-section .module.cold + --set-section-flags .module.cold=noload,readonly + --rename-section .module.cold=.module + ${KERNEL_REMAPPED} ${CMAKE_BINARY_DIR}/zephyr/cold.mod 2>${NULL_FILE} + # Remove .fw_metadata here... COMMAND ${CMAKE_OBJCOPY} --remove-section .imr --remove-section .imrdata + --remove-section .cold + --remove-section .coldrodata --remove-section .module.boot + --remove-section .module.cold --remove-section .fw_metadata --set-section-flags .module.main=noload,readonly --set-section-flags .static_uuid_entries=noload,readonly diff --git a/soc/intel/intel_adsp/common/boot.c b/soc/intel/intel_adsp/common/boot.c index c5433a0d4a45e..ff015cffeb1b3 100644 --- a/soc/intel/intel_adsp/common/boot.c +++ b/soc/intel/intel_adsp/common/boot.c @@ -92,7 +92,9 @@ static __imr void parse_module(struct sof_man_fw_header *hdr, switch (mod->segment[i].flags.r.type) { case SOF_MAN_SEGMENT_TEXT: case SOF_MAN_SEGMENT_DATA: - if (mod->segment[i].flags.r.load == 0) { + if (mod->segment[i].flags.r.load == 0 || + mod->segment[i].v_base_addr >= L2_SRAM_BASE + L2_SRAM_SIZE || + mod->segment[i].v_base_addr < L2_SRAM_BASE) { continue; } diff --git a/soc/intel/intel_adsp/common/rimage_modules.c b/soc/intel/intel_adsp/common/rimage_modules.c index fd4bca1137c7f..50ca77f4f7542 100644 --- a/soc/intel/intel_adsp/common/rimage_modules.c +++ b/soc/intel/intel_adsp/common/rimage_modules.c @@ -42,3 +42,17 @@ const struct sof_man_module_manifest main_manifest = { .affinity_mask = 3, } }; + +__attribute__((section(".module.cold"))) +const struct sof_man_module_manifest cold_manifest = { + .module = { + .name = "COLD", + /* d406d134-c3c1-402c-8aec-6821c0c2b0e6 */ + .uuid = {0x34, 0xd1, 0x06, 0xd4, 0xc1, 0xc3, 0x2c, 0x40, + 0x8a, 0xec, 0x68, 0x21, 0xc0, 0xc2, 0xb0, 0xe6}, + .entry_point = 0, + .type = { .load_type = SOF_MAN_MOD_TYPE_MODULE, + .domain_ll = 1 }, + .affinity_mask = 3, + } +}; diff --git a/soc/intel/intel_adsp/tools/cavstool.py b/soc/intel/intel_adsp/tools/cavstool.py index 8f2f55e6c5708..5d8c3f97df1bf 100755 --- a/soc/intel/intel_adsp/tools/cavstool.py +++ b/soc/intel/intel_adsp/tools/cavstool.py @@ -211,7 +211,11 @@ def adsp_mem_window_config(): return (base, stride) def map_regs(log_only): - p = runx(f"grep -iEl 'PCI_CLASS=40(10|38)0' /sys/bus/pci/devices/*/uevent") + try: + p = runx(f"grep -iEl 'PCI_CLASS=40(10|38)0' /sys/bus/pci/devices/*/uevent") + except subprocess.CalledProcessError: + # if no device found, also try 40300 class no-DSP devices + p = runx(f"grep -iEl 'PCI_CLASS=40300' /sys/bus/pci/devices/*/uevent") pcidir = os.path.dirname(p) # Platform/quirk detection. ID lists cribbed from the SOF kernel driver diff --git a/soc/intel/intel_ish/Kconfig b/soc/intel/intel_ish/Kconfig index 084fb45b70feb..82232a2010465 100644 --- a/soc/intel/intel_ish/Kconfig +++ b/soc/intel/intel_ish/Kconfig @@ -6,10 +6,10 @@ config SOC_FAMILY_INTEL_ISH select X86 + select CPU_LAKEMONT_VALUE select X86_NO_SPECULATIVE_VULNERABILITIES select IOAPIC select LOAPIC - select CPU_HAS_FPU select INTEL_HAL select HAS_PM select HAS_COVERAGE_SUPPORT diff --git a/soc/intel/intel_socfpga/agilex5/mmu_regions.c b/soc/intel/intel_socfpga/agilex5/mmu_regions.c index 984c729bddd6b..b921d1cd3cd6e 100644 --- a/soc/intel/intel_socfpga/agilex5/mmu_regions.c +++ b/soc/intel/intel_socfpga/agilex5/mmu_regions.c @@ -8,6 +8,10 @@ #include static const struct arm_mmu_region mmu_regions[] = { + MMU_REGION_FLAT_ENTRY("CLOCK", + DT_REG_ADDR(DT_NODELABEL(clock)), + DT_REG_SIZE(DT_NODELABEL(clock)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), /* System manager register that required by clock driver */ MMU_REGION_FLAT_ENTRY("SYSTEM_MANAGER", diff --git a/soc/intel/lakemont/Kconfig b/soc/intel/lakemont/Kconfig index 42727fddd5acb..48614d4297f19 100644 --- a/soc/intel/lakemont/Kconfig +++ b/soc/intel/lakemont/Kconfig @@ -4,7 +4,7 @@ config SOC_LAKEMONT select X86 - select CPU_LAKEMONT + select CPU_LAKEMONT_PERF select X86_MMU if FPU select X86_SSE if FPU select X86_SSE2 if FPU diff --git a/soc/lowrisc/opentitan/Kconfig.defconfig b/soc/lowrisc/opentitan/Kconfig.defconfig index 7cbedf1f60bf4..94c92d69c41be 100644 --- a/soc/lowrisc/opentitan/Kconfig.defconfig +++ b/soc/lowrisc/opentitan/Kconfig.defconfig @@ -18,4 +18,9 @@ config 2ND_LVL_INTR_00_OFFSET config NUM_IRQS default 256 +# The OpenTitan SoC requires a manifest in front of the +# application binary. +config ROM_START_OFFSET + default 0x400 + endif # SOC_OPENTITAN diff --git a/soc/lowrisc/opentitan/rom_header.S b/soc/lowrisc/opentitan/rom_header.S index e7b41235dab73..2303614c4dc5c 100644 --- a/soc/lowrisc/opentitan/rom_header.S +++ b/soc/lowrisc/opentitan/rom_header.S @@ -17,7 +17,7 @@ GTEXT(__rom_header) * 0x6c47 (minor). The manifest format is documented here: * https://github.com/lowRISC/opentitan/blob/689a163294e1791bd30cfe096decf7f9233abad4/sw/host/opentitanlib/src/image/manifest.rs#L205 */ -SECTION_FUNC(rom_header, __rom_header) +SECTION_VAR(rom_header, __rom_header) .rept(225) .word 0 .endr diff --git a/soc/mediatek/mt8xxx/CMakeLists.txt b/soc/mediatek/mt8xxx/CMakeLists.txt index 96d0ae468b14a..82228618dcfe7 100644 --- a/soc/mediatek/mt8xxx/CMakeLists.txt +++ b/soc/mediatek/mt8xxx/CMakeLists.txt @@ -12,3 +12,33 @@ add_custom_target(dsp_img ALL COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/gen_img.py ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} ${CMAKE_BINARY_DIR}/zephyr/zephyr.img) + +# Sign zephyr.ri using west (if the underlying rimage tool is +# available; generally it isn't except in SOF builds). Note that the +# "target" string to use for rimage is set at the board level as a +# RIMAGE_TARGET cached (cached so that the python script can read it!) +# cmake variable (not kconfig!). See board_set_rimage_target(). +# Thankfully the SOC name and the rimage target names for these +# platforms are identical. The west sign integration similarly needs +# a RIMAGE_CONFIG_PATH cmake cached (!) variable set to a directory +# containing the .toml files for the platforms, which SOF will set on +# its own at build time. And likewise the signing key isn't provided +# by Zephyr and needs tob e found by a SOF build by passing it in +# RIMAGE_SIGN_KEY. +# +# The short version is that zephyr.ri can only realistically be +# exercised from a SOF build and it doesn't belong here in Zephyr; +# rimage is a SOF tool. Signing audio firmware is only done for SOF +# firmware and not general Zephyr apps for the same hardware. This +# should live in SOF where it doesn't have to be duplicated for every +# device and where it won't be forced to communicate via side channels. +board_set_rimage_target(${CONFIG_SOC}) +set(RIMAGE_SIGN_KEY "otc_private_key_3k.pem" CACHE STRING "default rimage key") +add_custom_target(zephyr.ri ALL DEPENDS ${CMAKE_BINARY_DIR}/zephyr/zephyr.ri) +add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/zephyr/zephyr.ri + COMMENT "Sign with rimage..." + COMMAND west $<$:--verbose> sign + --if-tool-available --tool rimage --build-dir ${CMAKE_BINARY_DIR} + DEPENDS ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_ELF_NAME} +) diff --git a/soc/mediatek/mt8xxx/Kconfig.defconfig b/soc/mediatek/mt8xxx/Kconfig.defconfig index 8603103104427..d8ebe43c402da 100644 --- a/soc/mediatek/mt8xxx/Kconfig.defconfig +++ b/soc/mediatek/mt8xxx/Kconfig.defconfig @@ -31,11 +31,38 @@ config IRQ_OFFLOAD_NESTED default n if SOC_SERIES_MT818X default y +config CPU_HAS_DCACHE + default y +config DCACHE + default y +config CACHE_MANAGEMENT + default y +config DCACHE_LINE_SIZE + default 128 + +config NOCACHE_MEMORY + default y + config MTK_ADSP_TIMER default y config XTENSA_TIMER default n +config CONSOLE + default y +config WINSTREAM_CONSOLE + default y +config WINSTREAM + default y +config LOG_BACKEND_ADSP + default y if LOG + +config XTENSA_CCOUNT_HZ + default 720000000 if SOC_MT8195 + default 400000000 if SOC_MT8186 + default 800000000 if SOC_MT8188 + default 800000000 if SOC_MT8196 + config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_node_int_prop_int,$(dt_nodelabel_path,ostimer64),freq-hz) @@ -61,6 +88,7 @@ config XTENSA_HAL config SOC_TOOLCHAIN_NAME default "mtk_mt8195_adsp" if SOC_SERIES_MT8195 default "mtk_mt818x_adsp" if SOC_SERIES_MT818X + default "mtk_mt8196_adsp" if SOC_SERIES_MT8196 config XTENSA_RESET_VECTOR default n diff --git a/soc/mediatek/mt8xxx/linker.ld b/soc/mediatek/mt8xxx/linker.ld index 47a72aae2a81a..1593c0d3b3370 100644 --- a/soc/mediatek/mt8xxx/linker.ld +++ b/soc/mediatek/mt8xxx/linker.ld @@ -25,6 +25,11 @@ ENTRY(mtk_adsp_boot_entry) SECTIONS { + /* kluged-in entry point for Linux loader */ + .sof_entry : { + KEEP(*(.sof_entry.text)) + } > sram + #include > sram @@ -60,6 +65,15 @@ SECTIONS { *(.gnu.linkonce.h.*) } > dram + /* SOF extended manifest */ + . = ALIGN(16); + _fw_metadata_start = .; + .fw_metadata : { + KEEP (*(.fw_metadata)) + . = ALIGN(16); + } > dram + _fw_metadata_end = .; + #include #include @@ -96,6 +110,11 @@ SECTIONS { _end = .; _mtk_adsp_dram_end = .; + .nocache (NOLOAD) : { + . = ALIGN(4096); + *(.nocache .nocache.*) + } > dram + /* Non-runtime-loaded sections below */ #include diff --git a/soc/mediatek/mt8xxx/mbox.c b/soc/mediatek/mt8xxx/mbox.c index 69fc7b0839346..448cb3b96a59b 100644 --- a/soc/mediatek/mt8xxx/mbox.c +++ b/soc/mediatek/mt8xxx/mbox.c @@ -57,7 +57,6 @@ struct mtk_mbox { struct mbox_cfg { volatile struct mtk_mbox *mbox; - uint32_t irq; }; struct mbox_data { @@ -85,7 +84,12 @@ void mtk_adsp_mbox_signal(const struct device *mbox, uint32_t chan) } } -static void mbox_isr(const void *arg) +#define DEF_DEVPTR(N) DEVICE_DT_INST_GET(N), +const struct device * const mbox_devs[] = { + DT_INST_FOREACH_STATUS_OKAY(DEF_DEVPTR) +}; + +static void mbox_handle(const void *arg) { const struct mbox_cfg *cfg = ((struct device *)arg)->config; struct mbox_data *data = ((struct device *)arg)->data; @@ -101,8 +105,16 @@ static void mbox_isr(const void *arg) cfg->mbox->in_cmd_clr = cfg->mbox->in_cmd; /* ACK */ } +static void mbox_isr(const void *arg) +{ + for (int i = 0; i < ARRAY_SIZE(mbox_devs); i++) { + mbox_handle(mbox_devs[i]); + } +} + #define DEF_IRQ(N) \ - IRQ_CONNECT(DT_INST_IRQN(N), 0, mbox_isr, DEVICE_DT_INST_GET(N), 0); + { IRQ_CONNECT(DT_INST_IRQN(N), 0, mbox_isr, DEVICE_DT_INST_GET(N), 0); \ + irq_enable(DT_INST_IRQN(N)); } static int mbox_init(void) { @@ -115,7 +127,7 @@ SYS_INIT(mbox_init, POST_KERNEL, 0); #define DEF_DEV(N) \ static struct mbox_data dev_data##N; \ static const struct mbox_cfg dev_cfg##N = \ - { .irq = DT_INST_IRQN(N), .mbox = (void *)DT_INST_REG_ADDR(N), }; \ + { .mbox = (void *)DT_INST_REG_ADDR(N), }; \ DEVICE_DT_INST_DEFINE(N, NULL, NULL, &dev_data##N, &dev_cfg##N, \ POST_KERNEL, 0, NULL); diff --git a/soc/mediatek/mt8xxx/mt8196/Kconfig.defconfig b/soc/mediatek/mt8xxx/mt8196/Kconfig.defconfig index e406dce76a5be..67c58defefc7b 100644 --- a/soc/mediatek/mt8xxx/mt8196/Kconfig.defconfig +++ b/soc/mediatek/mt8xxx/mt8196/Kconfig.defconfig @@ -3,9 +3,6 @@ if SOC_MT8196 -config LEGACY_MULTI_LEVEL_TABLE_GENERATION - default n - config NUM_2ND_LEVEL_AGGREGATORS default 2 diff --git a/soc/mediatek/mt8xxx/mtk_adsp_load.py b/soc/mediatek/mt8xxx/mtk_adsp_load.py index ba3e4dbaddde1..42127b75ec5c8 100755 --- a/soc/mediatek/mt8xxx/mtk_adsp_load.py +++ b/soc/mediatek/mt8xxx/mtk_adsp_load.py @@ -171,7 +171,7 @@ def start(self, boot_vector): # stream at 0x60700000 -- the top of the linkable region of # existing SOF firmware, before the heap. Nothing uses this # currently. Will be replaced by winstream very soon. -def log(dev): +def old_log(dev): msg = b'' dram = maps["dram1"] for i in dev.logrange(): @@ -218,6 +218,99 @@ def le4(bstr): return struct.unpack(" 0x2000000 or (r.START >= r.WLEN) or (r.END >= r.WLEN): + raise RuntimeError("Invalid winstream") + self.regs = r + self.data = (ctypes.c_char * r.WLEN).from_address(addr + 16) + self.msg = bytearray(r.WLEN) + self.seq = 0 + + def read(self): + ws, msg, data = self.regs, self.msg, self.data + last_seq = self.seq + wlen = ws.WLEN + while True: + start, end, seq = ws.START, ws.END, ws.SEQ + self.seq = seq + if seq == last_seq or start == end: + return "" + behind = seq - last_seq + if behind > ((end - start) % wlen): + return "" + copy = (end - behind) % wlen + suffix = min(behind, wlen - copy) + for i in range(suffix): + msg[i] = data[copy + i][0] + msglen = suffix + l2 = behind - suffix + if l2 > 0: + for i in range(l2): + msg[msglen + i] = data[i][0] + msglen += l2 + if start == ws.START and seq == ws.SEQ: + return msg[0:msglen].decode("utf-8", "replace") + + +# Locates a winstream descriptor in the firmware via its 96-bit magic +# number and returns the address and size fields it finds there. +def find_winstream(maps): + magic = b'\x74\x5f\x6a\xd0\x79\xe2\x4f\x00\xcd\xb8\xbd\xf9' + for m in maps: + if "dram" in m: + # Some python versions produce bus errors (!) on the + # hardware when finding a 12 byte substring (maybe a SIMD + # load that the hardware doesn't like?). Do it in two + # chunks. + magoff = maps[m].find(magic[0:8]) + if magoff >= 0: + magoff = maps[m].find(magic[8:], magoff) - 8 + if magoff >= 0: + addr = le4(maps[m][magoff + 12 : magoff + 16]) + return addr + raise RuntimeError("Cannot find winstream descriptor in firmware runtime") + + +def winstream_localaddr(globaddr, mmio, maps): + for m in mmio: + off = globaddr - mmio[m][0] + if 0 <= off < mmio[m][1]: + return ctypes.addressof(ctypes.c_int.from_buffer(maps[m])) + off + raise RuntimeError("Winstream address not inside DSP memory") + + +def winstream_log(mmio, maps): + physaddr = find_winstream(maps) + regsbase = winstream_localaddr(physaddr, mmio, maps) + ws = Winstream(regsbase) + while True: + msg = ws.read() + if msg: + sys.stdout.write(msg) + sys.stdout.flush() + else: + time.sleep(0.1) + + def main(): dsp = detect() assert dsp @@ -272,10 +365,18 @@ def main(): for i in range(len(dram), mmio["dram1"][1]): maps["dram1"][i] = 0 dev.start(boot_vector) - log(dev) + winstream_log(mmio, maps) elif sys.argv[1] == "log": - log(dev) + winstream_log(mmio, maps) + + elif sys.argv[1] == "oldlog": + old_log(dev) + + elif sys.argv[1] == "mem": + print("Memory Regions:") + for m in mmio: + print(f" {m}: {mmio[m][1]} @ 0x{mmio[m][0]:08x}") elif sys.argv[1] == "dump": sz = mmio[sys.argv[2]][1] diff --git a/soc/mediatek/mt8xxx/soc.c b/soc/mediatek/mt8xxx/soc.c index 744980f084a3e..330a247bbe93d 100644 --- a/soc/mediatek/mt8xxx/soc.c +++ b/soc/mediatek/mt8xxx/soc.c @@ -19,6 +19,11 @@ extern char _mtk_adsp_dram_end[]; #define DRAM_SIZE DT_REG_SIZE(DT_NODELABEL(dram0)) #define DRAM_END (DRAM_START + DRAM_SIZE) +#define DMA_START DT_REG_ADDR(DT_NODELABEL(dram1)) +#define DMA_SIZE DT_REG_SIZE(DT_NODELABEL(dram1)) +#define DMA_END (DMA_START + DMA_SIZE) + + #ifdef CONFIG_SOC_MT8196 #define INIT_STACK "0x90400000" #define LOG_BASE 0x90580000 @@ -29,6 +34,113 @@ extern char _mtk_adsp_dram_end[]; #define LOG_LEN 0x100000 #endif +/* The MT8196 interrupt controller is very simple at runtime, with + * just an enable and status register needed, like its + * predecessors. But it has routing control which resets to "nothing + * enabled", so needs a driver. + * + * There are 64 interrupt inputs to the controller, controlled by + * pairs of words (the "intc64" type below). Each interrupt is + * associated with one[1] of 16 "groups", each of which directs to a + * different Xtensa architectural interrupt. So each Xtensa interrupt + * can be configured to handle any subset of interrupt inputs. + * + * The mapping of groups to Xtensa interrupts is given below. Note + * particularly that the final two groups are NMIs directed to an + * interrupt level higher than EXCM_LEVEL, so cannot be safely used + * for OS code (they'll interrupt spinlocks), but an app might exploit + * them for e.g. debug or watchdog hooks. + * + * GroupNum XtensaIRQ XtensaLevel + * 0-5 0-5 1 (L1 is shared w/exceptions, poor choice) + * 6-7 7-8 1 + * 8-10 9-11 2 + * 11-13 16-18 3 + * 14,15 20,21 4 (Unmaskable! Do not use w/Zephyr code!) + * + * Naming of the inputs looks like this, though obviously only a small + * fraction have been validated (or are even useful for an audio DSP): + * + * 0: CCU 20: USB1 40: WDT + * 1: SCP 21: SCPVOW 41: CONNSYS1 + * 2: SPM 22: CCIF3_C0 42: CONNSYS3 + * 3: PCIE 23: CCIF3_C1 43: CONNSYS4 + * 4: INFRA_HANG 24: PWR_CTRL 44: CONNSYS2 + * 5: PERI_TIMEOUT 25: DMA_C0 45: IPIC + * 6: MBOX_C0 26: DMA_C1 46: AXI_DMA2 + * 7: MBOX_C1 27: AXI_DMA0 47: AXI_DMA3 + * 8: TIMER0 28: AXI_DMA1 48: APSRC_DDREN + * 9: TIMER1 29: AUDIO_C0 49: LAT_MON_EMI + * 10: IPC_C0 30: AUDIO_C1 50: LAT_MON_INFRA + * 11: IPC_C1 31: HIFI5_WDT_C0 51: DEVAPC_VIO + * 12: IPC1_RSV 32: HIFI5_WDT_C1 52: AO_INFRA_HANG + * 13: C2C_SW_C0 33: APU_MBOX_C0 53: BUS_TRA_EMI + * 14: C2C_SW_C1 34: APU_MBOX_C1 54: BUS_TRA_INFRA + * 15: UART 35: TIMER2 55: L2SRAM_VIO + * 16: UART_BT 36: PWR_ON_C0_IRQ 56: L2SRAM_SETERR + * 17: LATENCY_MON 37: PWR_ON_C1_IRQ 57: PCIERC_GRP2 + * 18: BUS_TRACKER 38: WAKEUP_SRC_C0 58: PCIERC_GRP3 + * 19: USB0 39: WAKEUP_SRC_C1 59: IRQ_MAX_CHANNEL + * + * [1] It is legal and works as expected for an interrupt to be part + * of more than one group (more than one interrupt fires to handle + * it), though I don't understand why an application would want to + * do that. + */ + +struct intc64 { uint32_t lo, hi; }; + +struct intc_8196 { + struct intc64 input; /* Raw (?) input signal, normally high */ + struct intc64 status; /* Latched input, inverted (active == 1) */ + struct intc64 enable; /* Interrupt enable */ + struct intc64 polarity; /* 1 == active low */ + struct intc64 wake_enable; + struct intc64 _unused; + struct intc64 stage1_enable; + struct intc64 sw_trigger; + struct intc64 groups[16]; /* set bit == "member of group" */ + struct intc64 group_status[16]; /* status, but masked by group */ +}; + +#define INTC (*(volatile struct intc_8196 *)0x1a014000) + +static void set_group_bit(volatile struct intc64 *g, uint32_t bit, bool val) +{ + volatile uint32_t *p = bit < 32 ? &g->lo : &g->hi; + volatile uint32_t mask = BIT(bit & 0x1f); + + *p = val ? (*p | mask) : (*p & ~mask); +} + +static void mt8196_intc_set_irq_group(uint32_t irq, uint32_t group) +{ + for (int i = 0; i < 16; i++) { + set_group_bit(&INTC.groups[i], irq, i == group); + } +} + +void mt8196_intc_init(void) +{ + struct intc64 zero = { 0, 0 }; + + INTC.enable = zero; + INTC.polarity.lo = 0xffffffff; + INTC.polarity.hi = 0xffffffff; + INTC.wake_enable = zero; + INTC.stage1_enable = zero; + for (int i = 0; i < ARRAY_SIZE(INTC.groups); i++) { + INTC.groups[i] = zero; + } + + /* Now wire up known interrupts for existing drivers to their + * legacy settings + */ + mt8196_intc_set_irq_group(6, 2); /* mbox0 in group 2 */ + mt8196_intc_set_irq_group(7, 2); /* mbox1 in group 2 */ + mt8196_intc_set_irq_group(8, 1); /* ostimer in group 1 */ +} + /* This is the true boot vector. This device allows for direct * setting of the alternate reset vector, so we let it link wherever * it lands and extract its address in the loader. This represents @@ -50,6 +162,27 @@ __asm__(".align 4\n\t" " movi a1, " INIT_STACK "\n\t" " call4 c_boot\n\t"); +/* Unfortunately the SOF kernel loader doesn't understand the boot + * vector in the ELF/rimage file yet, so we still need a stub to get + * actual audio firmware to load. Leave a stub in place that jumps to + * our "real" vector. Note that this is frustratingly pessimal: the + * kernel wants the entry point to be at the start of the SRAM region, + * but (1) Xtensa can only load an immediate from addresses LOWER than + * a L32R instruction, which we can't do and so need to jump across a + * region to put one, and (2) the vector table that gets displaced has + * a 1024 byte alignment requirement, forcing us to waste ~1011 bytes + * needlessly. + */ +__asm__(".pushsection .sof_entry.text\n\t" + " j 2f\n" + ".align 4\n\t" + "1:\n\t" + " .word mtk_adsp_boot_entry\n" + "2:\n\t" + " l32r a0, 1b\n\t" + " jx a0\n\t" + ".popsection"); + /* Initial MPU configuration, needed to enable caching */ static void enable_mpu(void) { @@ -64,11 +197,12 @@ static void enable_mpu(void) { 0x10000000, 0x06f00 }, /* MMIO registers */ { 0x1d000000, 0x06000 }, /* inaccessible */ { SRAM_START, 0xf7f00 }, /* cached SRAM */ - { (uint32_t)&_mtk_adsp_sram_end, 0x06f00 }, /* uncached SRAM */ { SRAM_END, 0x06000 }, /* inaccessible */ { DRAM_START, 0xf7f00 }, /* cached DRAM */ { (uint32_t)&_mtk_adsp_dram_end, 0x06f00 }, /* uncached DRAM */ { DRAM_END, 0x06000 }, /* inaccessible top of mem */ + { DMA_START, 0x06f00 }, /* uncached host "DMA" area */ + { DMA_END, 0x06000 }, /* inaccessible top of mem */ }; /* Must write BACKWARDS FROM THE END to avoid introducing a @@ -116,6 +250,7 @@ static void enable_mpu(void) * dram clear and also set buf[0] to 0 manually (as it isn't affected * by device reset). */ +#ifndef CONFIG_WINSTREAM_CONSOLE int arch_printk_char_out(int c) { char volatile * const buf = (void *)LOG_BASE; @@ -128,6 +263,10 @@ int arch_printk_char_out(int c) } return 0; } +#endif + +/* Define this here as a simple uncached array, no special linkage requirements */ +__nocache char _winstream_console_buf[CONFIG_WINSTREAM_CONSOLE_STATIC_SIZE]; void c_boot(void) { @@ -188,6 +327,10 @@ void c_boot(void) /* Default console, a driver can override this later */ __stdout_hook_install(arch_printk_char_out); +#ifdef CONFIG_SOC_MT8196 + mt8196_intc_init(); +#endif + void z_prep_c(void); z_prep_c(); } diff --git a/soc/microchip/mec/common/reg/mec_adc.h b/soc/microchip/mec/common/reg/mec_adc.h index 48850a5ef7268..eb7a141e17458 100644 --- a/soc/microchip/mec/common/reg/mec_adc.h +++ b/soc/microchip/mec/common/reg/mec_adc.h @@ -10,9 +10,15 @@ #include #include +#if defined(CONFIG_SOC_MEC172X_NLJ) +/* 16 ADC channels numbered 0 - 15 */ +#define MCHP_ADC_MAX_CHAN 16u +#define MCHP_ADC_MAX_CHAN_MASK 0x0fu +#else /* Eight ADC channels numbered 0 - 7 */ #define MCHP_ADC_MAX_CHAN 8u #define MCHP_ADC_MAX_CHAN_MASK 0x07u +#endif /* Control register */ #define MCHP_ADC_CTRL_REG_OFS 0u @@ -42,15 +48,27 @@ /* Single Conversion Select register */ #define MCHP_ADC_SCS_REG_OFS 0x0cu +#if defined(CONFIG_SOC_MEC172X_NLJ) +#define MCHP_ADC_SCS_REG_MASK 0xffffu +#define MCHP_ADC_SCS_CH_0_15 0xffffu +#define MCHP_ADC_SCS_CH(n) BIT(((n) & 0x0fu)) +#else #define MCHP_ADC_SCS_REG_MASK 0xffu #define MCHP_ADC_SCS_CH_0_7 0xffu #define MCHP_ADC_SCS_CH(n) BIT(((n) & 0x07u)) +#endif /* Repeat Conversion Select register */ #define MCHP_ADC_RCS_REG_OFS 0x10u +#if defined(CONFIG_SOC_MEC172X_NLJ) +#define MCHP_ADC_RCS_REG_MASK 0xffffu +#define MCHP_ADC_RCS_CH_0_15 0xffffu +#define MCHP_ADC_RCS_CH(n) BIT(((n) & 0x0fu)) +#else #define MCHP_ADC_RCS_REG_MASK 0xffu #define MCHP_ADC_RCS_CH_0_7 0xffu #define MCHP_ADC_RCS_CH(n) BIT(((n) & 0x07u)) +#endif /* Channel reading registers */ #define MCHP_ADC_RDCH_REG_MASK 0xfffu @@ -62,6 +80,14 @@ #define MCHP_ADC_RDCH5_REG_OFS 0x28u #define MCHP_ADC_RDCH6_REG_OFS 0x2cu #define MCHP_ADC_RDCH7_REG_OFS 0x30u +#define MCHP_ADC_RDCH8_REG_OFS 0x34u +#define MCHP_ADC_RDCH9_REG_OFS 0x38u +#define MCHP_ADC_RDCH10_REG_OFS 0x3cu +#define MCHP_ADC_RDCH11_REG_OFS 0x40u +#define MCHP_ADC_RDCH12_REG_OFS 0x44u +#define MCHP_ADC_RDCH13_REG_OFS 0x48u +#define MCHP_ADC_RDCH14_REG_OFS 0x4cu +#define MCHP_ADC_RDCH15_REG_OFS 0x50u /* Configuration register */ #define MCHP_ADC_CFG_REG_OFS 0x7cu @@ -76,9 +102,15 @@ /* Channel Vref Select register */ #define MCHP_ADC_CH_VREF_SEL_REG_OFS 0x80u #define MCHP_ADC_CH_VREF_SEL_REG_MASK 0x00ffffffu +#if defined(CONFIG_SOC_MEC172X_NLJ) +#define MCHP_ADC_CH_VREF_SEL_MASK(n) SHLU32(0x03u, (((n) & 0x0f) * 2u)) +#define MCHP_ADC_CH_VREF_SEL_PAD(n) 0u +#define MCHP_ADC_CH_VREF_SEL_GPIO(n) SHLU32(0x01u, (((n) & 0x0f) * 2u)) +#else #define MCHP_ADC_CH_VREF_SEL_MASK(n) SHLU32(0x03u, (((n) & 0x07) * 2u)) #define MCHP_ADC_CH_VREF_SEL_PAD(n) 0u #define MCHP_ADC_CH_VREF_SEL_GPIO(n) SHLU32(0x01u, (((n) & 0x07) * 2u)) +#endif /* Vref Control register */ #define MCHP_ADC_VREF_CTRL_REG_OFS 0x84u @@ -131,8 +163,8 @@ struct adc_regs { volatile uint32_t STATUS; volatile uint32_t SINGLE; volatile uint32_t REPEAT; - volatile uint32_t RD[8]; - uint8_t RSVD1[0x7c - 0x34]; + volatile uint32_t RD[MCHP_ADC_MAX_CHAN]; + uint8_t RSVD1[0x7c - ((MCHP_ADC_MAX_CHAN * 4) + 0x14)]; volatile uint32_t CONFIG; volatile uint32_t VREF_CHAN_SEL; volatile uint32_t VREF_CTRL; diff --git a/soc/nordic/CMakeLists.txt b/soc/nordic/CMakeLists.txt index cebbdf155007c..5aec1af882002 100644 --- a/soc/nordic/CMakeLists.txt +++ b/soc/nordic/CMakeLists.txt @@ -17,11 +17,13 @@ zephyr_library_sources( # headers for different SoCs. set(dt_binding_includes ${DTS_INCLUDE_FILES}) list(FILTER dt_binding_includes INCLUDE REGEX "/dt-bindings/.*\.h$") -list(TRANSFORM dt_binding_includes PREPEND "-include;") + +set(include_flag $$) + set_source_files_properties( validate_binding_headers.c DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - PROPERTIES COMPILE_OPTIONS "${dt_binding_includes}" + PROPERTIES COMPILE_OPTIONS "${include_flag}$" ) if(CONFIG_SOC_HAS_TIMING_FUNCTIONS AND NOT CONFIG_BOARD_HAS_TIMING_FUNCTIONS) diff --git a/soc/nordic/Kconfig b/soc/nordic/Kconfig index f380eb64bb692..f510c1ec39194 100644 --- a/soc/nordic/Kconfig +++ b/soc/nordic/Kconfig @@ -8,7 +8,7 @@ config SOC_FAMILY_NORDIC_NRF select SOC_COMPATIBLE_NRF - select SOC_RESET_HOOK if ARM + select SOC_RESET_HOOK select CMSIS_CORE_HAS_SYSTEM_CORE_CLOCK if ARM if SOC_FAMILY_NORDIC_NRF diff --git a/soc/nordic/Kconfig.defconfig b/soc/nordic/Kconfig.defconfig index efa122aa5b50c..3e819b9ad5902 100644 --- a/soc/nordic/Kconfig.defconfig +++ b/soc/nordic/Kconfig.defconfig @@ -11,7 +11,7 @@ rsource "*/Kconfig.defconfig" # based on the Haltium platform SoCs where clock control is not needed # for the system timer config CLOCK_CONTROL - default y if SYS_CLOCK_EXISTS && !NRF_PLATFORM_HALTIUM + default y if SYS_CLOCK_EXISTS && !NRF_PLATFORM_HALTIUM && !RISCV_CORE_NORDIC_VPR config SYS_CLOCK_HW_CYCLES_PER_SEC default 1000000 if NRF_GRTC_TIMER diff --git a/soc/nordic/common/CMakeLists.txt b/soc/nordic/common/CMakeLists.txt index 8c00b768b9030..04cd174d28eea 100644 --- a/soc/nordic/common/CMakeLists.txt +++ b/soc/nordic/common/CMakeLists.txt @@ -3,13 +3,11 @@ add_subdirectory_ifdef(CONFIG_RISCV_CORE_NORDIC_VPR vpr) -if(CONFIG_ARM) - # Let SystemInit() be called in place of soc_reset_hook() by default. - zephyr_linker_symbol(SYMBOL soc_reset_hook EXPR "@SystemInit@") +# Let SystemInit() be called in place of soc_reset_hook() by default. +zephyr_linker_symbol(SYMBOL soc_reset_hook EXPR "@SystemInit@") - # This file is used when the CMake linker script generator is disabled. - zephyr_linker_sources(SECTIONS arm_platform_init.ld) -endif() +# This file is used when the CMake linker script generator is disabled. +zephyr_linker_sources(SECTIONS platform_init.ld) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) if(CONFIG_ARM) diff --git a/soc/nordic/common/Kconfig b/soc/nordic/common/Kconfig index 6ed44bdd8cbbc..a5bae67d5a114 100644 --- a/soc/nordic/common/Kconfig +++ b/soc/nordic/common/Kconfig @@ -4,6 +4,9 @@ config HAS_NORDIC_DMM bool +config HAS_NORDIC_RAM_CTRL + bool + config NRF_SYS_EVENT bool "nRF system event support" select NRFX_POWER if !NRF_PLATFORM_HALTIUM @@ -22,6 +25,13 @@ config MRAM_LATENCY_SYNC_TIMEOUT help Timeout is given in milliseconds. +config MRAM_LATENCY_AUTO_REQ + bool "Request MRAM without latency at start" + help + When enabled then MRAM configuration without latency is requested + during the initialization and is kept enabled until the mram_latency API user + calls mram_no_latency_sync_release(). + module = MRAM_LATENCY module-str = mram_latency source "subsys/logging/Kconfig.template.log_config" diff --git a/soc/nordic/common/mram_latency.c b/soc/nordic/common/mram_latency.c index 0bfc6d4bfe2da..cba1b498d6c31 100644 --- a/soc/nordic/common/mram_latency.c +++ b/soc/nordic/common/mram_latency.c @@ -168,6 +168,10 @@ static int init_nrfs(void) state = MRAM_LATENCY_ON; + if (IS_ENABLED(CONFIG_MRAM_LATENCY_AUTO_REQ)) { + mram_no_latency_sync_request(); + } + return rv; } diff --git a/soc/nordic/common/arm_platform_init.ld b/soc/nordic/common/platform_init.ld similarity index 100% rename from soc/nordic/common/arm_platform_init.ld rename to soc/nordic/common/platform_init.ld diff --git a/soc/nordic/common/poweroff.c b/soc/nordic/common/poweroff.c index b3210da697d13..857b2f38078a7 100644 --- a/soc/nordic/common/poweroff.c +++ b/soc/nordic/common/poweroff.c @@ -5,6 +5,7 @@ #include #include +#include #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) #include @@ -17,8 +18,46 @@ #include #endif +#if defined(CONFIG_HAS_NORDIC_RAM_CTRL) +#include +#endif + void z_sys_poweroff(void) { +#if defined(CONFIG_HAS_NORDIC_RAM_CTRL) + uint8_t *ram_start; + size_t ram_size; + +#if defined(NRF_MEMORY_RAM_BASE) + ram_start = (uint8_t *)NRF_MEMORY_RAM_BASE; +#else + ram_start = (uint8_t *)NRF_MEMORY_RAM0_BASE; +#endif + + ram_size = 0; +#if defined(NRF_MEMORY_RAM_SIZE) + ram_size += NRF_MEMORY_RAM_SIZE; +#endif +#if defined(NRF_MEMORY_RAM0_SIZE) + ram_size += NRF_MEMORY_RAM0_SIZE; +#endif +#if defined(NRF_MEMORY_RAM1_SIZE) + ram_size += NRF_MEMORY_RAM1_SIZE; +#endif +#if defined(NRF_MEMORY_RAM2_SIZE) + ram_size += NRF_MEMORY_RAM2_SIZE; +#endif + + /* Disable retention for all memory blocks */ + nrfx_ram_ctrl_retention_enable_set(ram_start, ram_size, false); + +#endif /* defined(CONFIG_HAS_NORDIC_RAM_CTRL) */ + +#if defined(CONFIG_RETAINED_MEM_NRF_RAM_CTRL) + /* Restore retention for retained_mem driver regions defined in devicetree */ + (void)z_nrf_retained_mem_retention_apply(); +#endif + #if defined(CONFIG_SOC_SERIES_NRF54LX) nrfx_reset_reason_clear(UINT32_MAX); #endif diff --git a/soc/nordic/common/vpr/Kconfig b/soc/nordic/common/vpr/Kconfig index 45f2489dd5757..6c207afcd3a25 100644 --- a/soc/nordic/common/vpr/Kconfig +++ b/soc/nordic/common/vpr/Kconfig @@ -12,6 +12,7 @@ config RISCV_CORE_NORDIC_VPR select RISCV_ISA_EXT_C select RISCV_ISA_EXT_ZICSR select RISCV_SOC_HAS_ISR_STACKING + select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING select RISCV_HAS_CLIC select RISCV_SOC_CONTEXT_SAVE select HAS_FLASH_LOAD_OFFSET diff --git a/soc/nordic/common/vpr/soc_context.h b/soc/nordic/common/vpr/soc_context.h index 9735057e79213..2aba882afd773 100644 --- a/soc/nordic/common/vpr/soc_context.h +++ b/soc/nordic/common/vpr/soc_context.h @@ -8,14 +8,9 @@ #define SOC_ESF_MEMBERS \ unsigned long minttresh; \ - unsigned long sp_align; \ - unsigned long padding0; \ - unsigned long padding1; \ - unsigned long padding2 + unsigned long sp_align; #define SOC_ESF_INIT \ - 0, \ - 0, \ 0, \ 0 diff --git a/soc/nordic/common/vpr/soc_isr_stacking.h b/soc/nordic/common/vpr/soc_isr_stacking.h index 8d2f64ad7291f..c5f0e7b2762d7 100644 --- a/soc/nordic/common/vpr/soc_isr_stacking.h +++ b/soc/nordic/common/vpr/soc_isr_stacking.h @@ -20,7 +20,6 @@ struct arch_esf { \ unsigned long s0; \ unsigned long mstatus; \ - unsigned long tp; \ struct soc_esf soc_context; \ \ unsigned long t2; \ @@ -43,7 +42,6 @@ struct arch_esf { \ unsigned long s0; \ unsigned long mstatus; \ - unsigned long tp; \ struct soc_esf soc_context; \ \ unsigned long ra; \ @@ -62,6 +60,13 @@ #endif /* DT_PROP(VPR_CPU, nordic_bus_width) == 64 */ +/* + * VPR stacked mcause needs to have proper value on initial stack. + * Initial mret will restore this value. + */ +#define SOC_ISR_STACKING_ESR_INIT \ + stack_init->_mcause = 0; + #else /* _ASMLANGUAGE */ /* @@ -79,7 +84,7 @@ * Size of the SW managed part of the ESF in case of interrupt * sizeof(__padding) + ... + sizeof(soc_context) */ -#define ESF_SW_IRQ_SIZEOF (0x20) +#define ESF_SW_IRQ_SIZEOF (0x10) /* * VPR needs aligned(8) SP when doing HW stacking, if this condition is not fulfilled it will move diff --git a/soc/nordic/nrf52/Kconfig b/soc/nordic/nrf52/Kconfig index adb57916627e4..edc2b70d66768 100644 --- a/soc/nordic/nrf52/Kconfig +++ b/soc/nordic/nrf52/Kconfig @@ -11,6 +11,7 @@ config SOC_SERIES_NRF52X imply XIP select HAS_NRFX select HAS_NORDIC_DRIVERS + select HAS_NORDIC_RAM_CTRL select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_SWO select HAS_POWEROFF diff --git a/soc/nordic/nrf53/Kconfig b/soc/nordic/nrf53/Kconfig index 9fc9d7a9df09c..856330992d222 100644 --- a/soc/nordic/nrf53/Kconfig +++ b/soc/nordic/nrf53/Kconfig @@ -13,6 +13,7 @@ config SOC_SERIES_NRF53X imply XIP select HAS_NRFX select HAS_NORDIC_DRIVERS + select HAS_NORDIC_RAM_CTRL select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_SWO help diff --git a/soc/nordic/nrf53/nrf53_cpunet_mgmt.c b/soc/nordic/nrf53/nrf53_cpunet_mgmt.c index f7d2b54f3d6b6..9c869a2ecc088 100644 --- a/soc/nordic/nrf53/nrf53_cpunet_mgmt.c +++ b/soc/nordic/nrf53/nrf53_cpunet_mgmt.c @@ -15,14 +15,41 @@ #include #include #include +#include #include #include static struct onoff_manager cpunet_mgr; +#ifdef CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 + +#define GPIOS_PSEL_BY_IDX(node_id, prop, idx) \ + NRF_DT_GPIOS_TO_PSEL_BY_IDX(node_id, prop, idx), +#define ALL_GPIOS_IN_NODE(node_id) \ + DT_FOREACH_PROP_ELEM(node_id, gpios, GPIOS_PSEL_BY_IDX) +#define ALL_GPIOS_IN_FORWARDER(node_id) \ + DT_FOREACH_CHILD(node_id, ALL_GPIOS_IN_NODE) + +static void assign_pins(nrf_gpio_pin_sel_t sel) +{ + static const uint8_t forwarded_psels[] = { + DT_FOREACH_STATUS_OKAY(nordic_nrf_gpio_forwarder, ALL_GPIOS_IN_FORWARDER) + }; + + for (int i = 0; i < ARRAY_SIZE(forwarded_psels); i++) { + soc_secure_gpio_pin_mcu_select(forwarded_psels[i], sel); + } +} +#endif /* CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 */ + static void onoff_start(struct onoff_manager *mgr, onoff_notify_fn notify) { +#ifdef CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 + /* Forward assigned pins to the network core. */ + assign_pins(NRF_GPIO_PIN_SEL_NETWORK); +#endif + nrf_reset_network_force_off(NRF_RESET, false); notify(mgr, 0); @@ -32,6 +59,11 @@ static void onoff_stop(struct onoff_manager *mgr, onoff_notify_fn notify) { nrf_reset_network_force_off(NRF_RESET, true); +#ifdef CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 + /* Assign pins back to app core. */ + assign_pins(NRF_GPIO_PIN_SEL_APP); +#endif + notify(mgr, 0); } diff --git a/soc/nordic/nrf53/soc.c b/soc/nordic/nrf53/soc.c index cbdb8e04fe0fe..c9fb9adc4f499 100644 --- a/soc/nordic/nrf53/soc.c +++ b/soc/nordic/nrf53/soc.c @@ -47,15 +47,6 @@ #define RTC1_PRETICK_SELECTED_CC_MASK BIT_MASK(CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT + 1U) #define RTC0_PRETICK_SELECTED_CC_MASK BIT_MASK(NRF_RTC_CC_COUNT_MAX) -#if defined(CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340) -#define GPIOS_PSEL_BY_IDX(node_id, prop, idx) \ - NRF_DT_GPIOS_TO_PSEL_BY_IDX(node_id, prop, idx), -#define ALL_GPIOS_IN_NODE(node_id) \ - DT_FOREACH_PROP_ELEM(node_id, gpios, GPIOS_PSEL_BY_IDX) -#define ALL_GPIOS_IN_FORWARDER(node_id) \ - DT_FOREACH_CHILD(node_id, ALL_GPIOS_IN_NODE) -#endif - #ifdef CONFIG_SOC_NRF5340_CPUAPP #define LFXO_NODE DT_NODELABEL(lfxo) #define HFXO_NODE DT_NODELABEL(hfxo) @@ -562,17 +553,6 @@ static int nordicsemi_nrf53_init(void) nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_HIGH, true); #endif -#if defined(CONFIG_SOC_NRF_GPIO_FORWARDER_FOR_NRF5340) - static const uint8_t forwarded_psels[] = { - DT_FOREACH_STATUS_OKAY(nordic_nrf_gpio_forwarder, ALL_GPIOS_IN_FORWARDER) - }; - - for (int i = 0; i < ARRAY_SIZE(forwarded_psels); i++) { - soc_secure_gpio_pin_mcu_select(forwarded_psels[i], NRF_GPIO_PIN_SEL_NETWORK); - } - -#endif - return 0; } diff --git a/soc/nordic/nrf54h/CMakeLists.txt b/soc/nordic/nrf54h/CMakeLists.txt index 7edc4d43ea128..23c1cab1e77a5 100644 --- a/soc/nordic/nrf54h/CMakeLists.txt +++ b/soc/nordic/nrf54h/CMakeLists.txt @@ -16,4 +16,5 @@ zephyr_include_directories(.) # for the image correctly zephyr_linker_sources(SECTIONS SORT_KEY zzz_place_align_at_end align.ld) +add_subdirectory(bicr) add_subdirectory(gpd) diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index 95af5153892d9..fa4ca5eb9bc38 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -21,11 +21,14 @@ config SOC_NRF54H20_CPUAPP_COMMON select CPU_HAS_FPU select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS select HAS_NORDIC_DMM + select HAS_NORDIC_RAM_CTRL select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select NRFS_HAS_CLOCK_SERVICE select NRFS_HAS_DVFS_SERVICE + select NRFS_HAS_GDFS_SERVICE select NRFS_HAS_GDPWR_SERVICE select NRFS_HAS_MRAM_SERVICE + select NRFS_HAS_SWEXT_SERVICE select NRFS_HAS_TEMP_SERVICE select NRFS_HAS_VBUS_DETECTOR_SERVICE select HAS_PM @@ -47,11 +50,14 @@ config SOC_NRF54H20_CPURAD_COMMON select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select NRFS_HAS_CLOCK_SERVICE + select NRFS_HAS_GDFS_SERVICE select NRFS_HAS_GDPWR_SERVICE select NRFS_HAS_MRAM_SERVICE + select NRFS_HAS_SWEXT_SERVICE select NRFS_HAS_TEMP_SERVICE select NRFS_HAS_VBUS_DETECTOR_SERVICE select HAS_NORDIC_DMM + select HAS_NORDIC_RAM_CTRL select HAS_PM select HAS_POWEROFF @@ -64,4 +70,5 @@ config SOC_NRF54H20_CPUPPR config SOC_NRF54H20_CPUFLPR select RISCV_CORE_NORDIC_VPR +rsource "bicr/Kconfig" rsource "gpd/Kconfig" diff --git a/soc/nordic/nrf54h/bicr/CMakeLists.txt b/soc/nordic/nrf54h/bicr/CMakeLists.txt new file mode 100644 index 0000000000000..a93e36abbd26d --- /dev/null +++ b/soc/nordic/nrf54h/bicr/CMakeLists.txt @@ -0,0 +1,21 @@ +if(CONFIG_SOC_NRF54H20_GENERATE_BICR) + set(bicr_json_file ${BOARD_DIR}/bicr.json) + set(bicr_hex_file ${PROJECT_BINARY_DIR}/bicr.hex) + set(svd_file ${ZEPHYR_HAL_NORDIC_MODULE_DIR}/nrfx/mdk/nrf54h20_application.svd) + + if(EXISTS ${bicr_json_file}) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${bicr_json_file}) + + execute_process( + COMMAND + ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_LIST_DIR}/bicrgen.py + --svd ${svd_file} + --input ${bicr_json_file} + --output ${bicr_hex_file} + WORKING_DIRECTORY ${BOARD_DIR} + COMMAND_ERROR_IS_FATAL ANY + ) + message(STATUS "Generated BICR hex file: ${bicr_hex_file}") + endif() +endif() diff --git a/soc/nordic/nrf54h/bicr/Kconfig b/soc/nordic/nrf54h/bicr/Kconfig new file mode 100644 index 0000000000000..a1ba7d2400c34 --- /dev/null +++ b/soc/nordic/nrf54h/bicr/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +config SOC_NRF54H20_GENERATE_BICR + bool "Generate nRF54H20 BICR file" + depends on SOC_NRF54H20_CPUAPP + default y + help + This option generates a BICR file for the board being used. Board + directory must contain a "bicr.json" file for this option to work. diff --git a/soc/nordic/nrf54h/bicr/bicr-schema.json b/soc/nordic/nrf54h/bicr/bicr-schema.json new file mode 100644 index 0000000000000..28eb208af3e5e --- /dev/null +++ b/soc/nordic/nrf54h/bicr/bicr-schema.json @@ -0,0 +1,422 @@ +{ + "title": "nRF54H20 BICR Configuration", + "type": "object", + "properties": { + "power": { + "type": "object", + "title": "Power supply configuration", + "properties": { + "scheme": { + "type": "string", + "title": "Power supply scheme", + "enumNames": [ + "Unconfigured (system will not boot)", + "VDDH supplied with 2.1-5.5 V and VDD regulated by the chip (inductor present)", + "Both VDD and VDDH supplied with 1.8 V (inductor present)" + ], + "enum": [ + "UNCONFIGURED", + "VDD_VDDH_1V8", + "VDDH_2V1_5V5" + ], + "default": "UNCONFIGURED" + } + }, + "required": [ + "scheme" + ] + }, + "ioPortPower": { + "type": "object", + "title": "IO port power configuration", + "properties": { + "p1Supply": { + "type": "string", + "title": "P1 power supply (VDDIO_P1)", + "enumNames": [ + "Not supplied (P1 not used)", + "VDDIO_P1 connected to an external 1.8 V supply or to VDD_EXT", + "VDDIO_P1 shorted to VDD" + ], + "enum": [ + "DISCONNECTED", + "EXTERNAL_1V8", + "SHORTED" + ], + "default": "DISCONNECTED" + }, + "p2Supply": { + "type": "string", + "title": "P2 power supply (VDDIO_P2)", + "enumNames": [ + "Not supplied (P2 not used)", + "VDDIO_P2 connected to an external 1.8 V supply or to VDD_EXT", + "VDDIO_P2 shorted to VDD" + ], + "enum": [ + "DISCONNECTED", + "EXTERNAL_1V8", + "SHORTED" + ], + "default": "DISCONNECTED" + }, + "p6Supply": { + "type": "string", + "title": "P6 power supply (VDDIO_P6)", + "enumNames": [ + "Not supplied (P6 not used)", + "VDDIO_P6 connected to an external 1.8 V supply or to VDD_EXT", + "VDDIO_P6 shorted to VDD" + ], + "enum": [ + "DISCONNECTED", + "EXTERNAL_1V8", + "SHORTED" + ], + "default": "DISCONNECTED" + }, + "p7Supply": { + "type": "string", + "title": "P7 power supply (VDDIO_P7)", + "enumNames": [ + "Not supplied (P7 not used)", + "VDDIO_P7 connected to an external 1.8 V supply or to VDD_EXT", + "VDDIO_P7 shorted to VDD" + ], + "enum": [ + "DISCONNECTED", + "EXTERNAL_1V8", + "SHORTED" + ], + "default": "DISCONNECTED" + }, + "p9Supply": { + "type": "string", + "title": "P9 power supply (VDDIO_P9)", + "enumNames": [ + "Not supplied (P9 not used)", + "VDDIO_P9 connected to an external 1.8 V supply or to VDD_EXT", + "VDDIO_P9 connected to an external supply (above 1.8 V, up to 3 V)", + "VDDIO_P9 shorted to VDD" + ], + "enum": [ + "DISCONNECTED", + "EXTERNAL_1V8", + "EXTERNAL_FULL", + "SHORTED" + ], + "default": "EXTERNAL_FULL" + } + }, + "required": [ + "p1Supply", + "p2Supply", + "p6Supply", + "p7Supply", + "p9Supply" + ] + }, + "ioPortImpedance": { + "type": "object", + "title": "IO port impedance configuration", + "properties": { + "p6ImpedanceOhms": { + "type": "number", + "title": "P6 impedance", + "enum": [ + 33, + 40, + 50, + 66, + 100 + ], + "default": 50 + }, + "p7ImpedanceOhms": { + "type": "number", + "title": "P7 impedance", + "enum": [ + 33, + 40, + 50, + 66, + 100 + ], + "default": 50 + } + }, + "required": [ + "p6ImpedanceOhms", + "p7ImpedanceOhms" + ] + }, + "lfosc": { + "type": "object", + "title": "Low Frequency Oscillator (LFOSC) configuration", + "properties": { + "source": { + "type": "string", + "title": "Source", + "enumNames": [ + "Low Frequency Crystal Oscillator (LFXO)", + "Low Frequency RC Oscillator (LFRC)" + ], + "enum": [ + "LFXO", + "LFRC" + ], + "default": "LFXO" + } + }, + "required": [ + "source" + ], + "dependencies": { + "source": { + "oneOf": [ + { + "properties": { + "source": { + "const": "LFXO" + }, + "lfxo": { + "type": "object", + "title": "Low Frequency Crystal Oscillator (LFXO) configuration", + "properties": { + "mode": { + "type": "string", + "title": "Mode", + "enumNames": [ + "Crystal", + "External sine signal", + "External square signal" + ], + "enum": [ + "CRYSTAL", + "ETX_SINE", + "EXT_SQUARE" + ], + "default": "CRYSTAL" + }, + "accuracyPPM": { + "type": "number", + "title": "Accuracy", + "enum": [ + 20, + 30, + 50, + 75, + 100, + 150, + 250, + 500 + ], + "default": 20 + }, + "startupTimeMs": { + "type": "number", + "title": "Startup time", + "minimum": 0, + "maximum": 4094, + "multipleOf": 1, + "default": 600 + } + }, + "required": [ + "mode", + "accuracyPPM", + "startupTimeMs" + ], + "dependencies": { + "mode": { + "oneOf": [ + { + "properties": { + "mode": { + "const": "CRYSTAL" + }, + "builtInLoadCapacitors": { + "type": "boolean", + "title": "Use built-in load capacitors", + "default": true + } + }, + "required": [ + "builtInLoadCapacitors" + ], + "dependencies": { + "builtInLoadCapacitors": { + "oneOf": [ + { + "properties": { + "builtInLoadCapacitors": { + "const": true + }, + "builtInLoadCapacitancePf": { + "type": "integer", + "title": "Built-in load capacitance", + "minimum": 1, + "maximum": 25, + "multipleOf": 1, + "default": 15 + } + }, + "required": [ + "builtInLoadCapacitancePf" + ] + } + ] + } + } + } + ] + } + } + } + } + }, + { + "properties": { + "source": { + "const": "LFRC" + }, + "lfrccal": { + "type": "object", + "title": "Low Frequency RC (LFRC) autocalibration configuration", + "properties": { + "calibrationEnabled": { + "type": "boolean", + "title": "Enable autocalibration", + "default": true + } + }, + "required": [ + "calibrationEnabled" + ], + "dependencies": { + "calibrationEnabled": { + "oneOf": [ + { + "properties": { + "calibrationEnabled": { + "const": true + }, + "tempMeasIntervalSeconds": { + "type": "number", + "title": "Temperature measurement interval", + "minimum": 0.25, + "maximum": 31.75, + "multipleOf": 0.25, + "default": 4 + }, + "tempDeltaCalibrationTriggerCelsius": { + "type": "number", + "title": "Temperature delta that should trigger calibration", + "minimum": 0.25, + "maximum": 31.75, + "multipleOf": 0.25, + "default": 0.5 + }, + "maxMeasIntervalBetweenCalibrations": { + "type": "number", + "title": "Maximum number of measurement intervals between calibrations", + "minimum": 0, + "maximum": 31, + "multipleOf": 1, + "default": 2 + } + }, + "required": [ + "tempMeasIntervalSeconds", + "tempDeltaCalibrationTriggerCelsius", + "maxMeasIntervalBetweenCalibrations" + ] + } + ] + } + } + } + } + } + ] + } + } + }, + "hfxo": { + "type": "object", + "title": "High Frequency Cristal Oscillator (HFXO) configuration", + "properties": { + "mode": { + "type": "string", + "title": "Mode", + "enumNames": [ + "Crystal", + "External square signal" + ], + "enum": [ + "CRYSTAL", + "EXT_SQUARE" + ], + "default": "CRYSTAL" + }, + "startupTimeUs": { + "type": "number", + "title": "Startup time", + "minimum": 0, + "maximum": 4294967294, + "multipleOf": 1, + "default": 850 + } + }, + "required": [ + "mode", + "startupTimeUs" + ], + "dependencies": { + "mode": { + "oneOf": [ + { + "properties": { + "mode": { + "const": "CRYSTAL" + }, + "builtInLoadCapacitors": { + "type": "boolean", + "title": "Use built-in load capacitors", + "default": true + } + }, + "required": [ + "builtInLoadCapacitors" + ], + "dependencies": { + "builtInLoadCapacitors": { + "oneOf": [ + { + "properties": { + "builtInLoadCapacitors": { + "const": true + }, + "builtInLoadCapacitancePf": { + "type": "number", + "title": "Built-in load capacitance", + "minimum": 0.25, + "maximum": 25.75, + "multipleOf": 0.25, + "default": 14 + } + }, + "required": [ + "builtInLoadCapacitancePf" + ] + } + ] + } + } + } + ] + } + } + } + } +} diff --git a/soc/nordic/nrf54h/bicr/bicrgen.py b/soc/nordic/nrf54h/bicr/bicrgen.py new file mode 100644 index 0000000000000..b28fdc571a880 --- /dev/null +++ b/soc/nordic/nrf54h/bicr/bicrgen.py @@ -0,0 +1,703 @@ +""" +BICR Generation Tool +-------------------- + +This tool is used to generate a BICR (Board Information Configuration Register) +file from a JSON file that contains the BICR configuration. It can also be used +to do the reverse operation, i.e., to extract the BICR configuration from a BICR +hex file. + +:: + + JSON ┌────────────┐ JSON + │ │ │ ▲ + └─────►│ ├───────┘ + │ bicrgen.py │ + ┌─────►│ ├───────┐ + │ │ │ ▼ + HEX └────────────┘ HEX + +Usage:: + + python genbicr.py \ + --input \ + [--svd ] \ + [--output ] \ + [--list] + +Copyright (c) 2024 Nordic Semiconductor ASA +SPDX-License-Identifier: Apache-2.0 +""" + +import argparse +import json +import struct +import sys +import xml.etree.ElementTree as ET +from dataclasses import dataclass +from enum import Enum +from pathlib import Path +from pprint import pprint + +from intelhex import IntelHex + + +class Register: + def __init__(self, regs: ET.Element, name: str, data: bytes | bytearray | None = None) -> None: + cluster_name, reg_name = name.split(".") + + cluster = regs.find(f".//registers/cluster[name='{cluster_name}']") + self._offset = int(cluster.find("addressOffset").text, 0) + + self._reg = cluster.find(f".//register[name='{reg_name}']") + self._offset += int(self._reg.find("addressOffset").text, 0) + self._size = int(self._reg.find("size").text, 0) // 8 + + self._data = data + + @property + def offset(self) -> int: + return self._offset + + @property + def size(self) -> int: + return self._size + + def _msk_pos(self, name: str) -> tuple[int, int]: + field = self._reg.find(f".//fields/field[name='{name}']") + field_lsb = int(field.find("lsb").text, 0) + field_msb = int(field.find("msb").text, 0) + + mask = (0xFFFFFFFF - (1 << field_lsb) + 1) & (0xFFFFFFFF >> (31 - field_msb)) + + return mask, field_lsb + + def _enums(self, field: str) -> list[ET.Element]: + return self._reg.findall( + f".//fields/field[name='{field}']/enumeratedValues/enumeratedValue" + ) + + def __getitem__(self, field: str) -> int: + if not self._data: + raise TypeError("Empty register") + + msk, pos = self._msk_pos(field) + raw = struct.unpack("> pos + + def __setitem__(self, field: str, value: int) -> None: + if not isinstance(self._data, bytearray): + raise TypeError("Register is read-only") + + msk, pos = self._msk_pos(field) + raw = raw = struct.unpack(" str: + value = self[field] + for enum in self._enums(field): + if value == int(enum.find("value").text, 0): + return enum.find("name").text + + raise ValueError(f"Invalid enum value for {field}: {value}") + + def enum_set(self, field: str, value: str) -> None: + for enum in self._enums(field): + if value == enum.find("name").text: + self[field] = int(enum.find("value").text, 0) + return + + raise ValueError(f"Invalid enum value for {field}: {value}") + + +class PowerSupplyScheme(Enum): + UNCONFIGURED = "Unconfigured" + VDD_VDDH_1V8 = "VDD_VDDH_1V8" + VDDH_2V1_5V5 = "VDDH_2V1_5V5" + + +@dataclass +class PowerConfig: + scheme: PowerSupplyScheme + + @classmethod + def from_raw(cls: "PowerConfig", bicr_spec: ET.Element, data: bytes) -> "PowerConfig": + power_config = Register(bicr_spec, "POWER.CONFIG", data) + + if ( + power_config.enum_get("VDDAO5V0") == "Shorted" + and power_config.enum_get("VDDAO1V8") == "External" + ): + scheme = PowerSupplyScheme.VDD_VDDH_1V8 + elif ( + power_config.enum_get("VDDAO5V0") == "External" + and power_config.enum_get("VDDAO1V8") == "Internal" + ): + scheme = PowerSupplyScheme.VDDH_2V1_5V5 + else: + scheme = PowerSupplyScheme.UNCONFIGURED + + return cls(scheme=scheme) + + @classmethod + def from_json(cls: "PowerConfig", data: dict) -> "PowerConfig": + power = data["power"] + + return cls(scheme=PowerSupplyScheme[power["scheme"]]) + + def to_raw(self, bicr_spec: ET.Element, buf: bytearray): + power_config = Register(bicr_spec, "POWER.CONFIG", buf) + + if self.scheme == PowerSupplyScheme.VDD_VDDH_1V8: + power_config.enum_set("VDDAO5V0", "Shorted") + power_config.enum_set("VDDAO1V8", "External") + power_config.enum_set("VDD1V0", "Internal") + power_config.enum_set("VDDRF1V0", "Shorted") + power_config.enum_set("VDDAO0V8", "Internal") + power_config.enum_set("VDDVS0V8", "Internal") + power_config.enum_set("INDUCTOR", "Present") + elif self.scheme == PowerSupplyScheme.VDDH_2V1_5V5: + power_config.enum_set("VDDAO5V0", "External") + power_config.enum_set("VDDAO1V8", "Internal") + power_config.enum_set("VDD1V0", "Internal") + power_config.enum_set("VDDRF1V0", "Shorted") + power_config.enum_set("VDDAO0V8", "Internal") + power_config.enum_set("VDDVS0V8", "Internal") + power_config.enum_set("INDUCTOR", "Present") + else: + power_config.enum_set("VDDAO5V0", "Unconfigured") + power_config.enum_set("VDDAO1V8", "Unconfigured") + power_config.enum_set("VDD1V0", "Unconfigured") + power_config.enum_set("VDDRF1V0", "Unconfigured") + power_config.enum_set("VDDAO0V8", "Unconfigured") + power_config.enum_set("VDDVS0V8", "Unconfigured") + power_config.enum_set("INDUCTOR", "Unconfigured") + + def to_json(self, buf: dict): + buf["power"] = {"scheme": self.scheme.name} + + +class IoPortPower(Enum): + DISCONNECTED = "Disconnected" + SHORTED = "Shorted" + EXTERNAL_1V8 = "External1V8" + + +class IoPortPowerExtended(Enum): + DISCONNECTED = "Disconnected" + SHORTED = "Shorted" + EXTERNAL_1V8 = "External1V8" + EXTERNAL_FULL = "ExternalFull" + + +@dataclass +class IoPortPowerConfig: + p1_supply: IoPortPower + p2_supply: IoPortPower + p6_supply: IoPortPower + p7_supply: IoPortPower + p9_supply: IoPortPowerExtended + + @classmethod + def from_raw( + cls: "IoPortPowerConfig", bicr_spec: ET.Element, data: bytes + ) -> "IoPortPowerConfig": + ioport_power0 = Register(bicr_spec, "IOPORT.POWER0", data) + ioport_power1 = Register(bicr_spec, "IOPORT.POWER1", data) + + return cls( + p1_supply=IoPortPower(ioport_power0.enum_get("P1")), + p2_supply=IoPortPower(ioport_power0.enum_get("P2")), + p6_supply=IoPortPower(ioport_power0.enum_get("P6")), + p7_supply=IoPortPower(ioport_power0.enum_get("P7")), + p9_supply=IoPortPowerExtended(ioport_power1.enum_get("P9")), + ) + + @classmethod + def from_json(cls: "IoPortPowerConfig", data: dict) -> "IoPortPowerConfig": + ioport_power = data["ioPortPower"] + + return cls( + p1_supply=IoPortPower[ioport_power["p1Supply"]], + p2_supply=IoPortPower[ioport_power["p2Supply"]], + p6_supply=IoPortPower[ioport_power["p6Supply"]], + p7_supply=IoPortPower[ioport_power["p7Supply"]], + p9_supply=IoPortPowerExtended[ioport_power["p9Supply"]], + ) + + def to_raw(self, bicr_spec: ET.Element, buf: bytearray): + ioport_power0 = Register(bicr_spec, "IOPORT.POWER0", buf) + ioport_power1 = Register(bicr_spec, "IOPORT.POWER1", buf) + + ioport_power0.enum_set("P1", self.p1_supply.value) + ioport_power0.enum_set("P2", self.p2_supply.value) + ioport_power0.enum_set("P6", self.p6_supply.value) + ioport_power0.enum_set("P7", self.p7_supply.value) + ioport_power1.enum_set("P9", self.p9_supply.value) + + def to_json(self, buf: dict): + buf["ioPortPower"] = { + "p1Supply": self.p1_supply.name, + "p2Supply": self.p2_supply.name, + "p6Supply": self.p6_supply.name, + "p7Supply": self.p7_supply.name, + "p9Supply": self.p9_supply.name, + } + + +@dataclass +class IoPortImpedanceConfig: + p6_impedance_ohms: int + p7_impedance_ohms: int + + @classmethod + def from_raw( + cls: "IoPortImpedanceConfig", bicr_spec: ET.Element, data: bytes + ) -> "IoPortImpedanceConfig": + drivectl0 = Register(bicr_spec, "IOPORT.DRIVECTRL0", data) + + return cls( + p6_impedance_ohms=int(drivectl0.enum_get("P6")[4:]), + p7_impedance_ohms=int(drivectl0.enum_get("P7")[4:]), + ) + + @classmethod + def from_json(cls: "IoPortImpedanceConfig", data: dict) -> "IoPortImpedanceConfig": + ioport_impedance = data["ioPortImpedance"] + + return cls( + p6_impedance_ohms=ioport_impedance["p6ImpedanceOhms"], + p7_impedance_ohms=ioport_impedance["p7ImpedanceOhms"], + ) + + def to_raw(self, bicr_spec: ET.Element, buf: bytearray): + drivectl0 = Register(bicr_spec, "IOPORT.DRIVECTRL0", buf) + + drivectl0.enum_set("P6", f"Ohms{self.p6_impedance_ohms}") + drivectl0.enum_set("P7", f"Ohms{self.p7_impedance_ohms}") + + def to_json(self, buf: dict): + buf["ioPortImpedance"] = { + "p6ImpedanceOhms": self.p6_impedance_ohms, + "p7ImpedanceOhms": self.p7_impedance_ohms, + } + + +class LFXOMode(Enum): + CRYSTAL = "Crystal" + EXT_SINE = "ExtSine" + EXT_SQUARE = "ExtSquare" + + +@dataclass +class LFXOConfig: + accuracy_ppm: int + mode: LFXOMode + builtin_load_capacitors: bool + builtin_load_capacitance_pf: int | None + startup_time_ms: int + + @classmethod + def from_raw(cls: "LFXOConfig", bicr_spec: ET.Element, data: bytes) -> "LFXOConfig": + lfosc_lfxoconfig = Register(bicr_spec, "LFOSC.LFXOCONFIG", data) + + try: + loadcap = lfosc_lfxoconfig.enum_get("LOADCAP") + except ValueError: + builtin_load_capacitors = True + builtin_load_capacitance_pf = lfosc_lfxoconfig["LOADCAP"] + else: + if loadcap == "Unconfigured": + raise ValueError("Invalid LFXO load capacitors configuration") + + builtin_load_capacitors = False + builtin_load_capacitance_pf = None + + startup_time_ms = 0 + try: + lfosc_lfxoconfig.enum_get("TIME") + except ValueError: + startup_time_ms = lfosc_lfxoconfig["TIME"] + else: + raise ValueError("Invalid LFXO startup time (not configured)") + + return cls( + accuracy_ppm=int(lfosc_lfxoconfig.enum_get("ACCURACY")[:3]), + mode=LFXOMode(lfosc_lfxoconfig.enum_get("MODE")), + builtin_load_capacitors=builtin_load_capacitors, + builtin_load_capacitance_pf=builtin_load_capacitance_pf, + startup_time_ms=startup_time_ms, + ) + + @classmethod + def from_json(cls: "LFXOConfig", data: dict) -> "LFXOConfig": + lfxo = data["lfosc"]["lfxo"] + + builtin_load_capacitors = lfxo["builtInLoadCapacitors"] + if builtin_load_capacitors: + builtin_load_capacitance_pf = lfxo["builtInLoadCapacitancePf"] + else: + builtin_load_capacitance_pf = None + + return cls( + accuracy_ppm=lfxo["accuracyPPM"], + mode=LFXOMode[lfxo["mode"]], + builtin_load_capacitors=builtin_load_capacitors, + builtin_load_capacitance_pf=builtin_load_capacitance_pf, + startup_time_ms=lfxo["startupTimeMs"], + ) + + def to_raw(self, bicr_spec: ET.Element, buf: bytearray): + lfosc_lfxoconfig = Register(bicr_spec, "LFOSC.LFXOCONFIG", buf) + + lfosc_lfxoconfig.enum_set("ACCURACY", f"{self.accuracy_ppm}ppm") + lfosc_lfxoconfig.enum_set("MODE", self.mode.value) + lfosc_lfxoconfig["TIME"] = self.startup_time_ms + + if self.builtin_load_capacitors: + lfosc_lfxoconfig["LOADCAP"] = self.builtin_load_capacitance_pf + else: + lfosc_lfxoconfig.enum_set("LOADCAP", "External") + + def to_json(self, buf: dict): + lfosc = buf["lfosc"] + lfosc["lfxo"] = { + "accuracyPPM": self.accuracy_ppm, + "mode": self.mode.name, + "builtInLoadCapacitors": self.builtin_load_capacitors, + "startupTimeMs": self.startup_time_ms, + } + + if self.builtin_load_capacitors: + lfosc["lfxo"]["builtInLoadCapacitancePf"] = self.builtin_load_capacitance_pf + + +@dataclass +class LFRCCalibrationConfig: + calibration_enabled: bool + temp_meas_interval_seconds: float | None + temp_delta_calibration_trigger_celsius: float | None + max_meas_interval_between_calibrations: int | None + + @classmethod + def from_raw( + cls: "LFRCCalibrationConfig", bicr_spec: ET.Element, data: bytes + ) -> "LFRCCalibrationConfig": + lfosc_lfrcautocalconfig = Register(bicr_spec, "LFOSC.LFRCAUTOCALCONFIG", data) + + calibration_enabled = lfosc_lfrcautocalconfig.enum_get("ENABLE") == "Enabled" + if calibration_enabled: + return cls( + calibration_enabled=calibration_enabled, + temp_meas_interval_seconds=lfosc_lfrcautocalconfig["TEMPINTERVAL"], + temp_delta_calibration_trigger_celsius=lfosc_lfrcautocalconfig["TEMPDELTA"], + max_meas_interval_between_calibrations=lfosc_lfrcautocalconfig["INTERVALMAXNO"], + ) + else: + return cls( + calibration_enabled=calibration_enabled, + temp_meas_interval_seconds=None, + temp_delta_calibration_trigger_celsius=None, + max_meas_interval_between_calibrations=None, + ) + + @classmethod + def from_json(cls: "LFRCCalibrationConfig", data: dict) -> "LFRCCalibrationConfig": + lfrccal = data["lfosc"]["lfrccal"] + + calibration_enabled = lfrccal["calibrationEnabled"] + if calibration_enabled: + temp_meas_interval_seconds = lfrccal["tempMeasIntervalSeconds"] + temp_delta_calibration_trigger_celsius = lfrccal["tempDeltaCalibrationTriggerCelsius"] + max_meas_interval_between_calibrations = lfrccal["maxMeasIntervalBetweenCalibrations"] + else: + temp_meas_interval_seconds = None + temp_delta_calibration_trigger_celsius = None + max_meas_interval_between_calibrations = None + + return cls( + calibration_enabled=calibration_enabled, + temp_meas_interval_seconds=temp_meas_interval_seconds, + temp_delta_calibration_trigger_celsius=temp_delta_calibration_trigger_celsius, + max_meas_interval_between_calibrations=max_meas_interval_between_calibrations, + ) + + def to_raw(self, bicr_spec: ET.Element, buf: bytearray): + lfosc_lfrcautocalconfig = Register(bicr_spec, "LFOSC.LFRCAUTOCALCONFIG", buf) + + lfosc_lfrcautocalconfig.enum_set( + "ENABLE", "Enabled" if self.calibration_enabled else "Disabled" + ) + if self.calibration_enabled: + lfosc_lfrcautocalconfig["TEMPINTERVAL"] = self.temp_meas_interval_seconds + lfosc_lfrcautocalconfig["TEMPDELTA"] = self.temp_delta_calibration_trigger_celsius + lfosc_lfrcautocalconfig["INTERVALMAXNO"] = self.max_meas_interval_between_calibrations + + def to_json(self, buf: dict): + lfosc = buf["lfosc"] + lfosc["lfrccal"] = { + "calibrationEnabled": self.calibration_enabled, + } + + if self.calibration_enabled: + lfosc["lfrccal"]["tempMeasIntervalSeconds"] = self.temp_meas_interval_seconds + lfosc["lfrccal"]["tempDeltaCalibrationTriggerCelsius"] = ( + self.temp_delta_calibration_trigger_celsius + ) + lfosc["lfrccal"]["maxMeasIntervalBetweenCalibrations"] = ( + self.max_meas_interval_between_calibrations + ) + + +class LFOSCSource(Enum): + LFXO = "LFXO" + LFRC = "LFRC" + + +@dataclass +class LFOSCConfig: + source: LFOSCSource + lfxo: LFXOConfig | None + lfrccal: LFRCCalibrationConfig | None + + @classmethod + def from_raw(cls: "LFOSCConfig", bicr_spec: ET.Element, data: bytes) -> "LFOSCConfig": + lfosc_lfxoconfig = Register(bicr_spec, "LFOSC.LFXOCONFIG", data) + + mode = lfosc_lfxoconfig.enum_get("MODE") + if mode == "Disabled": + source = LFOSCSource.LFRC + lfxo = None + lfrccal = LFRCCalibrationConfig.from_raw(bicr_spec, data) + elif mode == "Unconfigured": + raise ValueError("Invalid LFOSC configuration") + else: + source = LFOSCSource.LFXO + lfxo = LFXOConfig.from_raw(bicr_spec, data) + lfrccal = None + + return cls( + source=source, + lfxo=lfxo, + lfrccal=lfrccal, + ) + + @classmethod + def from_json(cls: "LFOSCConfig", data: dict) -> "LFOSCConfig": + lfosc = data["lfosc"] + + source = LFOSCSource[lfosc["source"]] + if source == LFOSCSource.LFXO: + source = source + lfxo = LFXOConfig.from_json(data) + lfrccal = None + else: + source = source + lfxo = None + lfrccal = LFRCCalibrationConfig.from_json(data) + + return cls( + source=source, + lfxo=lfxo, + lfrccal=lfrccal, + ) + + def to_raw(self, bicr_spec: ET.Element, buf: bytearray): + lfosc_lfxoconfig = Register(bicr_spec, "LFOSC.LFXOCONFIG", buf) + + if self.source == LFOSCSource.LFRC: + lfosc_lfxoconfig.enum_set("MODE", "Disabled") + self.lfrccal.to_raw(bicr_spec, buf) + elif self.source == LFOSCSource.LFXO: + self.lfxo.to_raw(bicr_spec, buf) + + def to_json(self, buf: dict): + buf["lfosc"] = { + "source": self.source.name, + } + + if self.source == LFOSCSource.LFXO: + self.lfxo.to_json(buf) + else: + self.lfrccal.to_json(buf) + + +class HFXOMode(Enum): + CRYSTAL = "Crystal" + EXT_SQUARE = "ExtSquare" + + +@dataclass +class HFXOConfig: + mode: HFXOMode + builtin_load_capacitors: bool + builtin_load_capacitance_pf: float | None + startup_time_us: int + + @classmethod + def from_raw(cls: "HFXOConfig", bicr_spec: ET.Element, data: bytes) -> "HFXOConfig": + hfxo_config = Register(bicr_spec, "HFXO.CONFIG", data) + hfxo_startuptime = Register(bicr_spec, "HFXO.STARTUPTIME", data) + + mode = HFXOMode(hfxo_config.enum_get("MODE")) + + try: + loadcap = hfxo_config.enum_get("LOADCAP") + except ValueError: + builtin_load_capacitors = True + builtin_load_capacitance_pf = hfxo_config["LOADCAP"] * 0.25 + else: + if loadcap == "Unconfigured": + raise ValueError("Invalid HFXO load capacitors configuration") + + builtin_load_capacitors = False + builtin_load_capacitance_pf = None + + startup_time_us = 0 + try: + hfxo_startuptime.enum_get("TIME") + except ValueError: + startup_time_us = hfxo_startuptime["TIME"] + else: + raise ValueError("Invalid LFXO startup time (not configured)") + + return cls( + mode=mode, + builtin_load_capacitors=builtin_load_capacitors, + builtin_load_capacitance_pf=builtin_load_capacitance_pf, + startup_time_us=startup_time_us, + ) + + @classmethod + def from_json(cls: "HFXOConfig", data: dict) -> "HFXOConfig": + hfxo = data["hfxo"] + + builtin_load_capacitors = hfxo["builtInLoadCapacitors"] + if builtin_load_capacitors: + builtin_load_capacitance_pf = hfxo["builtInLoadCapacitancePf"] + else: + builtin_load_capacitance_pf = None + + return cls( + mode=HFXOMode[hfxo["mode"]], + builtin_load_capacitors=builtin_load_capacitors, + builtin_load_capacitance_pf=builtin_load_capacitance_pf, + startup_time_us=hfxo["startupTimeUs"], + ) + + def to_raw(self, bicr_spec: ET.Element, buf: bytearray): + hfxo_config = Register(bicr_spec, "HFXO.CONFIG", buf) + hfxo_startuptime = Register(bicr_spec, "HFXO.STARTUPTIME", buf) + + hfxo_config.enum_set("MODE", self.mode.value) + hfxo_startuptime["TIME"] = self.startup_time_us + + if self.builtin_load_capacitors: + hfxo_config["LOADCAP"] = int(self.builtin_load_capacitance_pf / 0.25) + else: + hfxo_config.enum_set("LOADCAP", "External") + + def to_json(self, buf: dict): + buf["hfxo"] = { + "mode": self.mode.name, + "builtInLoadCapacitors": self.builtin_load_capacitors, + "startupTimeUs": self.startup_time_us, + } + + if self.builtin_load_capacitors: + buf["hfxo"]["builtInLoadCapacitancePf"] = self.builtin_load_capacitance_pf + + +@dataclass +class BICR: + power: PowerConfig + ioport_power: IoPortPowerConfig + ioport_impedance: IoPortImpedanceConfig + lfosc: LFOSCConfig + hfxo: HFXOConfig + + @classmethod + def from_raw(cls: "BICR", bicr_spec: ET.Element, data: bytes) -> "BICR": + return cls( + power=PowerConfig.from_raw(bicr_spec, data), + ioport_power=IoPortPowerConfig.from_raw(bicr_spec, data), + ioport_impedance=IoPortImpedanceConfig.from_raw(bicr_spec, data), + lfosc=LFOSCConfig.from_raw(bicr_spec, data), + hfxo=HFXOConfig.from_raw(bicr_spec, data), + ) + + @classmethod + def from_json(cls: "BICR", data: dict) -> "BICR": + return cls( + power=PowerConfig.from_json(data), + ioport_power=IoPortPowerConfig.from_json(data), + ioport_impedance=IoPortImpedanceConfig.from_json(data), + lfosc=LFOSCConfig.from_json(data), + hfxo=HFXOConfig.from_json(data), + ) + + def to_raw(self, bicr_spec: ET.Element, buf: bytearray): + self.power.to_raw(bicr_spec, buf) + self.ioport_power.to_raw(bicr_spec, buf) + self.ioport_impedance.to_raw(bicr_spec, buf) + self.lfosc.to_raw(bicr_spec, buf) + self.hfxo.to_raw(bicr_spec, buf) + + def to_json(self, buf: dict): + self.power.to_json(buf) + self.ioport_power.to_json(buf) + self.ioport_impedance.to_json(buf) + self.lfosc.to_json(buf) + self.hfxo.to_json(buf) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("-i", "--input", type=Path, required=True, help="Input file") + parser.add_argument("-s", "--svd", type=Path, help="SVD file") + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument("-o", "--output", type=Path, help="Output file") + group.add_argument("-l", "--list", action="store_true", help="List BICR options") + args = parser.parse_args() + + if args.input.suffix == ".hex" or (args.output and args.output.suffix == ".hex"): + if not args.svd: + sys.exit("SVD file is required for hex files") + + bicr_spec = ET.parse(args.svd).getroot().find(".//peripheral[name='BICR_NS']") + + if args.input.suffix == ".hex": + ih = IntelHex() + ih.loadhex(args.input) + bicr = BICR.from_raw(bicr_spec, ih.tobinstr()) + elif args.input.suffix == ".json": + with open(args.input) as f: + data = json.load(f) + bicr = BICR.from_json(data) + else: + sys.exit("Unsupported input file format") + + if args.output: + if args.output.suffix == ".hex": + bicr_address = int(bicr_spec.find("baseAddress").text, 0) + last_reg = Register(bicr_spec, "TAMPC.ACTIVESHIELD") + bicr_size = last_reg.offset + last_reg.size + + buf = bytearray([0xFF] * bicr_size) + bicr.to_raw(bicr_spec, buf) + + ih = IntelHex() + ih.frombytes(buf, offset=bicr_address) + ih.tofile(args.output, format="hex") + elif args.output.suffix == ".json": + buf = dict() + bicr.to_json(buf) + + with open(args.output, "w") as f: + json.dump(buf, f, indent=4) + else: + sys.exit("Unsupported output file format") + elif args.list: + pprint(bicr) diff --git a/soc/nordic/nrf54h/gpd/gpd.c b/soc/nordic/nrf54h/gpd/gpd.c index 540c1cb03bd48..5e5f0b2dae133 100644 --- a/soc/nordic/nrf54h/gpd/gpd.c +++ b/soc/nordic/nrf54h/gpd/gpd.c @@ -20,9 +20,11 @@ LOG_MODULE_REGISTER(gpd, CONFIG_SOC_LOG_LEVEL); /* enforce alignment between DT<->nrfs */ -BUILD_ASSERT(GDPWR_POWER_DOMAIN_ACTIVE_FAST == NRF_GPD_FAST_ACTIVE1); -BUILD_ASSERT(GDPWR_POWER_DOMAIN_ACTIVE_SLOW == NRF_GPD_SLOW_ACTIVE); -BUILD_ASSERT(GDPWR_POWER_DOMAIN_MAIN_SLOW == NRF_GPD_SLOW_MAIN); +BUILD_ASSERT(GDPWR_GD_FAST_ACTIVE_0 == NRF_GPD_FAST_ACTIVE0); +BUILD_ASSERT(GDPWR_GD_FAST_ACTIVE_1 == NRF_GPD_FAST_ACTIVE1); +BUILD_ASSERT(GDPWR_GD_FAST_MAIN == NRF_GPD_FAST_MAIN); +BUILD_ASSERT(GDPWR_GD_SLOW_ACTIVE == NRF_GPD_SLOW_ACTIVE); +BUILD_ASSERT(GDPWR_GD_SLOW_MAIN == NRF_GPD_SLOW_MAIN); struct gpd_onoff_manager { struct onoff_manager mgr; @@ -44,11 +46,21 @@ static void stop(struct onoff_manager *mgr, onoff_notify_fn notify); #define GPD_SERVICE_REQ_ERR BIT(3) static atomic_t gpd_service_status = ATOMIC_INIT(0); +static struct gpd_onoff_manager fast_active0 = { + .id = NRF_GPD_FAST_ACTIVE0, + .lock = Z_MUTEX_INITIALIZER(fast_active0.lock), + .sem = Z_SEM_INITIALIZER(fast_active0.sem, 0, 1), +}; static struct gpd_onoff_manager fast_active1 = { .id = NRF_GPD_FAST_ACTIVE1, .lock = Z_MUTEX_INITIALIZER(fast_active1.lock), .sem = Z_SEM_INITIALIZER(fast_active1.sem, 0, 1), }; +static struct gpd_onoff_manager fast_main = { + .id = NRF_GPD_FAST_MAIN, + .lock = Z_MUTEX_INITIALIZER(fast_main.lock), + .sem = Z_SEM_INITIALIZER(fast_main.sem, 0, 1), +}; static struct gpd_onoff_manager slow_active = { .id = NRF_GPD_SLOW_ACTIVE, .lock = Z_MUTEX_INITIALIZER(slow_active.lock), @@ -66,8 +78,12 @@ static const struct onoff_transitions transitions = static struct gpd_onoff_manager *get_mgr(uint8_t id) { switch (id) { + case NRF_GPD_FAST_ACTIVE0: + return &fast_active0; case NRF_GPD_FAST_ACTIVE1: return &fast_active1; + case NRF_GPD_FAST_MAIN: + return &fast_main; case NRF_GPD_SLOW_ACTIVE: return &slow_active; case NRF_GPD_SLOW_MAIN: @@ -123,6 +139,8 @@ static int nrf_gpd_sync(struct gpd_onoff_manager *gpd_mgr) if (atomic_test_bit(&gpd_service_status, GPD_SERVICE_REQ_OK)) { return 0; } + + k_yield(); } LOG_ERR("nRFs GDPWR request timed out"); @@ -285,11 +303,21 @@ static int nrf_gpd_pre_init(void) { int ret; + ret = onoff_manager_init(&fast_active0.mgr, &transitions); + if (ret < 0) { + return ret; + } + ret = onoff_manager_init(&fast_active1.mgr, &transitions); if (ret < 0) { return ret; } + ret = onoff_manager_init(&fast_main.mgr, &transitions); + if (ret < 0) { + return ret; + } + ret = onoff_manager_init(&slow_active.mgr, &transitions); if (ret < 0) { return ret; @@ -321,11 +349,21 @@ static int nrf_gpd_post_init(void) } /* submit GD requests now to align collected statuses */ + ret = nrf_gpd_sync(&fast_active0); + if (ret < 0) { + goto err; + } + ret = nrf_gpd_sync(&fast_active1); if (ret < 0) { goto err; } + ret = nrf_gpd_sync(&fast_main); + if (ret < 0) { + goto err; + } + ret = nrf_gpd_sync(&slow_active); if (ret < 0) { goto err; diff --git a/soc/nordic/nrf54l/CMakeLists.txt b/soc/nordic/nrf54l/CMakeLists.txt index f1c18291fc6bf..cebbda571b686 100644 --- a/soc/nordic/nrf54l/CMakeLists.txt +++ b/soc/nordic/nrf54l/CMakeLists.txt @@ -6,7 +6,3 @@ zephyr_library_sources( ../validate_rram_partitions.c ) zephyr_include_directories(.) - -if(CONFIG_ELV_GRTC_LFXO_ALLOWED) - message(WARNING "WARNING! ELV mode feature is EXPERIMENTAL and may brick your device!") -endif() diff --git a/soc/nordic/nrf54l/Kconfig b/soc/nordic/nrf54l/Kconfig index bb9fea6dd9b46..35c698c7b0866 100644 --- a/soc/nordic/nrf54l/Kconfig +++ b/soc/nordic/nrf54l/Kconfig @@ -20,10 +20,14 @@ config SOC_NRF54L_CPUAPP_COMMON select CPU_HAS_FPU select HAS_HW_NRF_RADIO_IEEE802154 select HAS_POWEROFF + select HAS_NORDIC_RAM_CTRL config SOC_NRF54L05_CPUAPP select SOC_NRF54L_CPUAPP_COMMON +config SOC_NRF54L09_ENGA_CPUAPP + select SOC_NRF54L_CPUAPP_COMMON + config SOC_NRF54L10_CPUAPP select SOC_NRF54L_CPUAPP_COMMON @@ -73,18 +77,4 @@ config SOC_NRF_FORCE_CONSTLAT of base resources on while in sleep. The advantage of having a constant and predictable latency will be at the cost of having increased power consumption. -if NRF_GRTC_TIMER - -config ELV_GRTC_LFXO_ALLOWED - bool - depends on POWEROFF - select EXPERIMENTAL - help - This feature allows using ELV mode when GRTC operates with the LFXO as - a low-frequency clock source. The LFXO is automatically activated when - preparing to system-off. - WARNING! This feature is EXPERIMENTAL and may brick your device! - -endif # NRF_GRTC_TIMER - endif # SOC_SERIES_NRF54LX diff --git a/soc/nordic/nrf54l/Kconfig.defconfig.nrf54l09_enga_cpuapp b/soc/nordic/nrf54l/Kconfig.defconfig.nrf54l09_enga_cpuapp new file mode 100644 index 0000000000000..95d2d43fca125 --- /dev/null +++ b/soc/nordic/nrf54l/Kconfig.defconfig.nrf54l09_enga_cpuapp @@ -0,0 +1,14 @@ +# Nordic Semiconductor nRF54L09 MCU + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54L09_ENGA_CPUAPP + +config NUM_IRQS + default 274 + +config IEEE802154_NRF5 + default IEEE802154 + +endif # SOC_NRF54L09_ENGA_CPUAPP diff --git a/soc/nordic/nrf54l/Kconfig.defconfig.nrf54l20_enga_cpuapp b/soc/nordic/nrf54l/Kconfig.defconfig.nrf54l20_enga_cpuapp index 6aabb1a873884..153f2fd767b0c 100644 --- a/soc/nordic/nrf54l/Kconfig.defconfig.nrf54l20_enga_cpuapp +++ b/soc/nordic/nrf54l/Kconfig.defconfig.nrf54l20_enga_cpuapp @@ -6,6 +6,6 @@ if SOC_NRF54L20_ENGA_CPUAPP config NUM_IRQS - default 274 + default 290 endif # SOC_NRF54L20_ENGA_CPUAPP diff --git a/soc/nordic/nrf54l/Kconfig.soc b/soc/nordic/nrf54l/Kconfig.soc index f7c5adf6924e9..e1feb7cdef1e1 100644 --- a/soc/nordic/nrf54l/Kconfig.soc +++ b/soc/nordic/nrf54l/Kconfig.soc @@ -21,6 +21,24 @@ config SOC_NRF54L05_CPUFLPR help NRF54L05 CPUFLPR +config SOC_NRF54L09 + bool + select SOC_SERIES_NRF54LX + help + NRF54L09 + +config SOC_NRF54L09_ENGA + bool + select SOC_NRF54L09 + help + NRF54L09 ENGA + +config SOC_NRF54L09_ENGA_CPUAPP + bool + select SOC_NRF54L09_ENGA + help + NRF54L09 ENGA CPUAPP + config SOC_NRF54L10 bool select SOC_SERIES_NRF54LX @@ -77,6 +95,7 @@ config SOC_NRF54L20_ENGA_CPUAPP config SOC default "nrf54l05" if SOC_NRF54L05 + default "nrf54l09" if SOC_NRF54L09 default "nrf54l10" if SOC_NRF54L10 default "nrf54l15" if SOC_NRF54L15 default "nrf54l20" if SOC_NRF54L20 diff --git a/soc/nordic/nrf54l/soc.c b/soc/nordic/nrf54l/soc.c index b0ed4ba0ef79b..5c24df49d54d2 100644 --- a/soc/nordic/nrf54l/soc.c +++ b/soc/nordic/nrf54l/soc.c @@ -30,7 +30,9 @@ #endif #include +#include #include +#include LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); @@ -42,9 +44,9 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); static int nordicsemi_nrf54l_init(void) { /* Update the SystemCoreClock global variable with current core clock - * retrieved from hardware state. + * retrieved from the DT. */ - SystemCoreClockUpdate(); + SystemCoreClock = NRF_PERIPH_GET_FREQUENCY(DT_NODELABEL(cpu)); #if defined(NRF_APPLICATION) /* Enable ICACHE */ @@ -153,17 +155,16 @@ static int nordicsemi_nrf54l_init(void) } #if (DT_PROP(DT_NODELABEL(vregmain), regulator_initial_mode) == NRF5X_REG_MODE_DCDC) -#if defined(__CORTEX_M) && !defined(NRF_TRUSTZONE_NONSECURE) && defined(__ARM_FEATURE_CMSE) - if (*(uint32_t volatile *)0x00FFC334 <= 0x180A1D00) { - *(uint32_t volatile *)0x50120640 = 0x1EA9E040; +#if NRF54L_ERRATA_31_ENABLE_WORKAROUND + /* Workaround for Errata 31 */ + if (nrf54l_errata_31()) { + *((volatile uint32_t *)0x50120624ul) = 20 | 1<<5; + *((volatile uint32_t *)0x5012063Cul) &= ~(1<<19); } #endif nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_MAIN, true); #endif -#if defined(CONFIG_ELV_GRTC_LFXO_ALLOWED) - nrf_regulators_elv_mode_allow_set(NRF_REGULATORS, NRF_REGULATORS_ELV_ELVGRTCLFXO_MASK); -#endif /* CONFIG_ELV_GRTC_LFXO_ALLOWED */ #endif /* NRF_APPLICATION */ return 0; diff --git a/soc/nordic/soc.yml b/soc/nordic/soc.yml index ee79c7ee86826..b4c8ef5a034d4 100644 --- a/soc/nordic/soc.yml +++ b/soc/nordic/soc.yml @@ -25,6 +25,9 @@ family: cpuclusters: - name: cpuapp - name: cpuflpr + - name: nrf54l09 + cpuclusters: + - name: cpuapp - name: nrf54l10 cpuclusters: - name: cpuapp @@ -105,6 +108,8 @@ runners: - qualifiers: - nrf54l05/cpuapp - nrf54l05/cpuflpr + - qualifiers: + - nrf54l09/cpuapp - qualifiers: - nrf54l10/cpuapp - nrf54l10/cpuflpr @@ -165,6 +170,8 @@ runners: - qualifiers: - nrf54l05/cpuapp - nrf54l05/cpuflpr + - qualifiers: + - nrf54l09/cpuapp - qualifiers: - nrf54l10/cpuapp - nrf54l10/cpuflpr diff --git a/soc/nordic/validate_base_addresses.c b/soc/nordic/validate_base_addresses.c index f47c3dc456ed9..ef1dd19457894 100644 --- a/soc/nordic/validate_base_addresses.c +++ b/soc/nordic/validate_base_addresses.c @@ -330,6 +330,7 @@ CHECK_DT_REG(uart136, NRF_UARTE136); CHECK_DT_REG(uart137, NRF_UARTE137); CHECK_DT_REG(uicr, NRF_UICR); CHECK_DT_REG(cpuapp_uicr, NRF_APPLICATION_UICR); +CHECK_DT_REG(bicr, NRF_APPLICATION_BICR); CHECK_DT_REG(cpurad_uicr, NRF_RADIOCORE_UICR); CHECK_DT_REG(usbd, NRF_USBD); CHECK_DT_REG(usbhs, NRF_USBHS); diff --git a/soc/nuvoton/npcx/common/reg/reg_access.h b/soc/nuvoton/npcx/common/reg/reg_access.h index ae1d6a61694b7..b779b98fa2a62 100644 --- a/soc/nuvoton/npcx/common/reg/reg_access.h +++ b/soc/nuvoton/npcx/common/reg/reg_access.h @@ -10,7 +10,6 @@ /* * NPCX register bit/field access operations */ -#define IS_BIT_SET(reg, bit) (((reg >> bit) & (0x1)) != 0) #define GET_POS_FIELD(pos, size) pos #define GET_SIZE_FIELD(pos, size) size diff --git a/soc/nuvoton/npcx/common/reg/reg_def.h b/soc/nuvoton/npcx/common/reg/reg_def.h index b35089f65b6ba..012470ffb4f46 100644 --- a/soc/nuvoton/npcx/common/reg/reg_def.h +++ b/soc/nuvoton/npcx/common/reg/reg_def.h @@ -775,6 +775,7 @@ struct espi_reg { #define NPCX_VWEVMS_INDEX FIELD(8, 7) #define NPCX_VWEVMS_INDEX_EN 15 #define NPCX_VWEVMS_IE 18 +#define NPCX_VWEVMS_ENESPIRST 19 #define NPCX_VWEVMS_WE 20 #define NPCX_VWEVSM_WIRE FIELD(0, 4) #define NPCX_VWEVSM_VALID FIELD(4, 4) diff --git a/soc/nuvoton/npcx/common/scfg.c b/soc/nuvoton/npcx/common/scfg.c index b57476225bb2b..b29d7356b5506 100644 --- a/soc/nuvoton/npcx/common/scfg.c +++ b/soc/nuvoton/npcx/common/scfg.c @@ -105,6 +105,35 @@ void npcx_pinctrl_i2c_port_sel(int controller, int port) } } +void npcx_i2c_target_start_wk_enable(int controller, bool enable) +{ + struct glue_reg *const inst_glue = HAL_GLUE_INST(); + + if (enable) { + /* Clear Start condition detection status */ + inst_glue->SMB_SBD |= BIT(controller); + /* Enable wake up event assertion */ + inst_glue->SMB_EEN |= BIT(controller); + } else { + /* Disable wake up event assertion */ + inst_glue->SMB_EEN &= ~BIT(controller); + } +} + +void npcx_i2c_target_clear_detection_event(void) +{ + struct glue_reg *const inst_glue = HAL_GLUE_INST(); + uint8_t een = inst_glue->SMB_EEN; + uint8_t sbd = inst_glue->SMB_SBD; + + /* Clear Start condition detection status */ + for (uint8_t i = 0; i < 8; i++) { + if ((een & BIT(i)) != 0 && (sbd & BIT(i)) != 0) { + inst_glue->SMB_SBD |= BIT(i); + } + } +} + int npcx_pinctrl_flash_write_protect_set(void) { struct scfg_reg *inst_scfg = HAL_SFCG_INST(); diff --git a/soc/nuvoton/npcx/common/soc_pins.h b/soc/nuvoton/npcx/common/soc_pins.h index 143aad6b58ded..dcd403aa306a4 100644 --- a/soc/nuvoton/npcx/common/soc_pins.h +++ b/soc/nuvoton/npcx/common/soc_pins.h @@ -94,6 +94,20 @@ void npcx_host_interface_sel(enum npcx_hif_type hif_type); */ void npcx_i3c_target_sel(uint8_t module, bool enable); +/** + * @brief Enable smb controller wake up event detection in target mode + * + * @param controller i2c controller device + * @param enable True to enable wake up event detection, false to disable. + */ +void npcx_i2c_target_start_wk_enable(int controller, bool enable); + +/** + * @brief Clear wake up event detection status in target mode + * + */ +void npcx_i2c_target_clear_detection_event(void); + #ifdef __cplusplus } #endif diff --git a/soc/nuvoton/npcx/npcx4/soc.h b/soc/nuvoton/npcx/npcx4/soc.h index 4ada738102c43..d3f387edd2738 100644 --- a/soc/nuvoton/npcx/npcx4/soc.h +++ b/soc/nuvoton/npcx/npcx4/soc.h @@ -38,6 +38,7 @@ /* NPCX4 FIU register fields */ #define NPCX_FIU_EXT_CFG_SPI1_2DEV 6 +#define NPCX_FIU_EXT_CFG_LOW_DEV_NUM 7 /* NPCX4 supported group mask of DEVALT_LK */ #define NPCX_DEVALT_LK_GROUP_MASK \ diff --git a/soc/nxp/common/Kconfig.nbu b/soc/nxp/common/Kconfig.nbu new file mode 100644 index 0000000000000..08fe9fee28951 --- /dev/null +++ b/soc/nxp/common/Kconfig.nbu @@ -0,0 +1,9 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config NXP_NBU + bool + default y if BT || IEEE802154 + depends on DT_HAS_NXP_NBU_ENABLED + help + NXP Narrow Band Unit interrupt initialization. diff --git a/soc/nxp/common/Kconfig.xspi_xip b/soc/nxp/common/Kconfig.xspi_xip new file mode 100644 index 0000000000000..d087e8b2d2e3e --- /dev/null +++ b/soc/nxp/common/Kconfig.xspi_xip @@ -0,0 +1,42 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +DT_CHOSEN_Z_FLASH := zephyr,flash +DT_COMPAT_XSPI := nxp,xspi + +DT_CHOSEN_FLASH_NODE := $(dt_chosen_path,$(DT_CHOSEN_Z_FLASH)) +DT_CHOSEN_FLASH_PARENT := $(dt_node_parent,$(DT_CHOSEN_FLASH_NODE)) + +DT_FLASH_PARENT_IS_XSPI := $(dt_node_has_compat,$(DT_CHOSEN_FLASH_PARENT),$(DT_COMPAT_XSPI)) +DT_FLASH_HAS_SIZE_PROP := $(dt_node_has_prop,$(DT_CHOSEN_FLASH_NODE),size) + +config FLASH_BASE_ADDRESS + default $(dt_node_reg_addr_hex,$(DT_CHOSEN_FLASH_PARENT),1) \ + if $(DT_FLASH_PARENT_IS_XSPI) + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) + +config FLASH_SIZE + default $(dt_node_int_prop_int,$(DT_CHOSEN_FLASH_NODE),size,Kb) + +config FLASH_MCUX_XSPI_XIP + bool + default $(DT_FLASH_PARENT_IS_XSPI) + select XIP + help + Allows the soc to safely initialize the clocks for the + XSpi when planning to execute code in XSpi Memory. + +if FLASH_MCUX_XSPI_XIP + +config CODE_DATA_RELOCATION_SRAM + default y + +config FLASH_MCUX_XSPI_XIP_MEM + string + prompt "Xspi drivers memory location" + default "RAM" + help + Select the location to run the XSPI drivers when using + the flash API. + +endif diff --git a/soc/nxp/common/nxp_nbu.c b/soc/nxp/common/nxp_nbu.c new file mode 100644 index 0000000000000..7354194956f9f --- /dev/null +++ b/soc/nxp/common/nxp_nbu.c @@ -0,0 +1,56 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Interrupt Narrow Band Unit. This is meant for a RCP radio device. + */ + +/* -------------------------------------------------------------------------- */ +/* Includes */ +/* -------------------------------------------------------------------------- */ +#include + +/* -------------------------------------------------------------------------- */ +/* Definitions */ +/* -------------------------------------------------------------------------- */ +#define DT_DRV_COMPAT nxp_nbu + +#define NBU_RX_IRQ_N DT_IRQ_BY_NAME(DT_DRV_INST(0), nbu_rx_int, irq) +#define NBU_RX_IRQ_P DT_IRQ_BY_NAME(DT_DRV_INST(0), nbu_rx_int, priority) +#if DT_INST_IRQ_HAS_NAME(0, wakeup_int) +#define NBU_WAKE_UP_IRQ_N DT_IRQ_BY_NAME(DT_DRV_INST(0), wakeup_int, irq) +#define NBU_WAKE_UP_IRQ_P DT_IRQ_BY_NAME(DT_DRV_INST(0), wakeup_int, priority) +#endif + +/* -------------------------------------------------------------------------- */ +/* Private prototypes */ +/* -------------------------------------------------------------------------- */ +extern int32_t nbu_handler(void); +extern int32_t nbu_wakeup_done_handler(void); + +/* -------------------------------------------------------------------------- */ +/* Public function */ +/* -------------------------------------------------------------------------- */ + +void nxp_nbu_init(void) +{ +#if defined(CONFIG_BT) || defined(CONFIG_IEEE802154) + /* NBU interface Interrupt */ + IRQ_CONNECT(NBU_RX_IRQ_N, NBU_RX_IRQ_P, nbu_handler, 0, 0); + irq_enable(NBU_RX_IRQ_N); + +#if DT_INST_IRQ_HAS_NAME(0, wakeup_int) + /* Wake up done interrupt */ + IRQ_CONNECT(NBU_WAKE_UP_IRQ_N, NBU_WAKE_UP_IRQ_P, nbu_wakeup_done_handler, 0, 0); + irq_enable(NBU_WAKE_UP_IRQ_N); +#endif +#if (DT_INST_PROP(0, wakeup_source)) && CONFIG_PM + EnableDeepSleepIRQ(NBU_RX_IRQ_N); +#endif + +#endif +} diff --git a/soc/nxp/imx/imx6sx/soc.c b/soc/nxp/imx/imx6sx/soc.c index 516c2e9bcf62a..9377d2fd94366 100644 --- a/soc/nxp/imx/imx6sx/soc.c +++ b/soc/nxp/imx/imx6sx/soc.c @@ -183,7 +183,7 @@ static void SOC_CacheInit(void) } /* Initialize clock. */ -static void SOC_ClockInit(void) +void __weak SOC_ClockInit(void) { /* OSC/PLL is already initialized by Cortex-A9 core */ diff --git a/soc/nxp/imx/imx7d/soc.c b/soc/nxp/imx/imx7d/soc.c index 780c405a0bb95..7b98389762533 100644 --- a/soc/nxp/imx/imx7d/soc.c +++ b/soc/nxp/imx/imx7d/soc.c @@ -11,7 +11,7 @@ #include "wdog_imx.h" /* Initialize clock. */ -void SOC_ClockInit(void) +__weak void SOC_ClockInit(void) { /* OSC/PLL is already initialized by Cortex-A7 (u-boot) */ diff --git a/soc/nxp/imx/imx8/adsp/linker.ld b/soc/nxp/imx/imx8/adsp/linker.ld index 36f90d309a473..682dc08b62a0a 100644 --- a/soc/nxp/imx/imx8/adsp/linker.ld +++ b/soc/nxp/imx/imx8/adsp/linker.ld @@ -476,6 +476,14 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } .debug_ranges 0 : { *(.debug_ranges) } + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } .xtensa.info 0 : { *(.xtensa.info) } .xt.insn 0 : { diff --git a/soc/nxp/imx/imx8m/Kconfig b/soc/nxp/imx/imx8m/Kconfig index a1344a8c38e2c..66b08e44700e4 100644 --- a/soc/nxp/imx/imx8m/Kconfig +++ b/soc/nxp/imx/imx8m/Kconfig @@ -6,6 +6,7 @@ config SOC_MIMX8MM6_A53 select CPU_CORTEX_A53 select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS select HAS_MCUX if CLOCK_CONTROL + select HAS_MCUX_IGPIO select HAS_MCUX_CCM if CLOCK_CONTROL select HAS_MCUX_IOMUXC if PINCTRL select HAS_MCUX_RDC @@ -30,6 +31,7 @@ config SOC_MIMX8ML8_A53 select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS select HAS_MCUX if CLOCK_CONTROL select HAS_MCUX_CCM if CLOCK_CONTROL + select HAS_MCUX_IGPIO select HAS_MCUX_IOMUXC if PINCTRL select HAS_MCUX_RDC select HAS_MCUX_CACHE @@ -40,6 +42,7 @@ config SOC_MIMX8MN6_A53 select CPU_CORTEX_A53 select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS select HAS_MCUX if CLOCK_CONTROL + select HAS_MCUX_IGPIO select HAS_MCUX_CCM if CLOCK_CONTROL select HAS_MCUX_IOMUXC if PINCTRL select HAS_MCUX_RDC diff --git a/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8ml8_a53 b/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8ml8_a53 index 0c114c9de5197..25aecdaf1f282 100644 --- a/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8ml8_a53 +++ b/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8ml8_a53 @@ -12,6 +12,10 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) +# Enable GIC Safe Configuration to run multiple OSes on Cortex-A Cores +config GIC_SAFE_CONFIG + default y + config NUM_IRQS default 240 diff --git a/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8mm6_a53 b/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8mm6_a53 index ec804ba1cc758..a3e0a8ec7ff93 100644 --- a/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8mm6_a53 +++ b/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8mm6_a53 @@ -12,6 +12,10 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) +# Enable GIC Safe Configuration to run multiple OSes on Cortex-A Cores +config GIC_SAFE_CONFIG + default y + config NUM_IRQS default 240 diff --git a/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8mn6_a53 b/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8mn6_a53 index 22b09dac391cf..0ccfc4bc7245f 100644 --- a/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8mn6_a53 +++ b/soc/nxp/imx/imx8m/Kconfig.defconfig.mimx8mn6_a53 @@ -12,6 +12,10 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) +# Enable GIC Safe Configuration to run multiple OSes on Cortex-A Cores +config GIC_SAFE_CONFIG + default y + config NUM_IRQS default 240 diff --git a/soc/nxp/imx/imx8m/a53/soc.c b/soc/nxp/imx/imx8m/a53/soc.c index a110213e2b635..7ad3b444ff5cd 100644 --- a/soc/nxp/imx/imx8m/a53/soc.c +++ b/soc/nxp/imx/imx8m/a53/soc.c @@ -45,6 +45,12 @@ static void soc_rdc_init(void) periphConfig.policy = RDC_DT_VAL(enet); RDC_SetPeriphAccessConfig(rdc_inst, &periphConfig); #endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(i2c3)) && DT_NODE_HAS_PROP(DT_NODELABEL(i2c3), rdc) + periphConfig.periph = kRDC_Periph_I2C3; + periphConfig.policy = RDC_DT_VAL(i2c3); + RDC_SetPeriphAccessConfig(rdc_inst, &periphConfig); +#endif } #else @@ -52,7 +58,19 @@ static void soc_rdc_init(void) #endif +__weak void soc_clock_init(void) +{ +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(i2c3)) + /* Set I2C source to SysPLL1 Div5 160MHZ */ + CLOCK_SetRootMux(kCLOCK_RootI2c3, kCLOCK_I2cRootmuxSysPll1Div5); + /* Set root clock to 160MHZ / 10 = 16MHZ */ + CLOCK_SetRootDivider(kCLOCK_RootI2c3, 1U, 10U); + CLOCK_EnableClock(kCLOCK_I2c3); +#endif +} + void soc_prep_hook(void) { soc_rdc_init(); + soc_clock_init(); } diff --git a/soc/nxp/imx/imx8m/adsp/linker.ld b/soc/nxp/imx/imx8m/adsp/linker.ld index 35fc7d3525182..04e1776801050 100644 --- a/soc/nxp/imx/imx8m/adsp/linker.ld +++ b/soc/nxp/imx/imx8m/adsp/linker.ld @@ -483,6 +483,14 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } .debug_ranges 0 : { *(.debug_ranges) } + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } .xtensa.info 0 : { *(.xtensa.info) } .xt.insn 0 : { diff --git a/soc/nxp/imx/imx8m/m4_mini/soc.c b/soc/nxp/imx/imx8m/m4_mini/soc.c index e9404f7b17faf..6b01301c4bf0f 100644 --- a/soc/nxp/imx/imx8m/m4_mini/soc.c +++ b/soc/nxp/imx/imx8m/m4_mini/soc.c @@ -71,7 +71,7 @@ static const ccm_analog_frac_pll_config_t g_audioPll2Config = { .postDiv = 1U, /* AUDIO PLL2 frequency = 722534399HZ */ }; -static void SOC_ClockInit(void) +__weak void SOC_ClockInit(void) { /* * Switch AHB NOC root to 24M first in order to configure diff --git a/soc/nxp/imx/imx8m/m4_quad/soc.c b/soc/nxp/imx/imx8m/m4_quad/soc.c index eea984fc172af..c46b51a631a4d 100644 --- a/soc/nxp/imx/imx8m/m4_quad/soc.c +++ b/soc/nxp/imx/imx8m/m4_quad/soc.c @@ -46,7 +46,7 @@ static void SOC_RdcInit(void) CLOCK_ControlGate(kCLOCK_VideoPll2Gate, kCLOCK_ClockNeededAll); } -static void SOC_ClockInit(void) +__weak void SOC_ClockInit(void) { /* * Switch AHB NOC root to 25M first in order to configure diff --git a/soc/nxp/imx/imx8m/m7/soc.c b/soc/nxp/imx/imx8m/m7/soc.c index 7cd42b3bb5d75..4a28224a2c20c 100644 --- a/soc/nxp/imx/imx8m/m7/soc.c +++ b/soc/nxp/imx/imx8m/m7/soc.c @@ -80,7 +80,7 @@ const ccm_analog_integer_pll_config_t g_sysPll3Config = { .postDiv = 2U, /*!< SYSTEM PLL3 frequency = 600MHZ */ }; -static void SOC_ClockInit(void) +__weak void SOC_ClockInit(void) { /* * The following steps just show how to configure the PLL clock sources using the clock diff --git a/soc/nxp/imx/imx8ulp/adsp/linker.ld b/soc/nxp/imx/imx8ulp/adsp/linker.ld index a9f07e825ec3b..45283cce03cd9 100644 --- a/soc/nxp/imx/imx8ulp/adsp/linker.ld +++ b/soc/nxp/imx/imx8ulp/adsp/linker.ld @@ -470,6 +470,14 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } .debug_ranges 0 : { *(.debug_ranges) } + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } .xtensa.info 0 : { *(.xtensa.info) } .xt.insn 0 : { diff --git a/soc/nxp/imx/imx8x/adsp/linker.ld b/soc/nxp/imx/imx8x/adsp/linker.ld index b0bc2aaad968b..f5a0e489c5e93 100644 --- a/soc/nxp/imx/imx8x/adsp/linker.ld +++ b/soc/nxp/imx/imx8x/adsp/linker.ld @@ -477,6 +477,14 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } .debug_ranges 0 : { *(.debug_ranges) } + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } .xtensa.info 0 : { *(.xtensa.info) } .xt.insn 0 : { diff --git a/soc/nxp/imx/imx9/CMakeLists.txt b/soc/nxp/imx/imx9/CMakeLists.txt index 369519ad7b3b5..7c0803be8074c 100644 --- a/soc/nxp/imx/imx9/CMakeLists.txt +++ b/soc/nxp/imx/imx9/CMakeLists.txt @@ -1,7 +1,9 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 -if(CONFIG_SOC_MIMX9352) +if(CONFIG_SOC_MIMX9131) + add_subdirectory(imx91) +elseif(CONFIG_SOC_MIMX9352) add_subdirectory(imx93) elseif(CONFIG_SOC_MIMX9596) add_subdirectory(imx95) diff --git a/soc/nxp/imx/imx9/imx91/CMakeLists.txt b/soc/nxp/imx/imx9/imx91/CMakeLists.txt new file mode 100644 index 0000000000000..4d342af6f1393 --- /dev/null +++ b/soc/nxp/imx/imx9/imx91/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 +zephyr_compile_options(-Wno-misleading-indentation) + +zephyr_include_directories(.) + +zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/imx/imx9/imx91/Kconfig b/soc/nxp/imx/imx9/imx91/Kconfig new file mode 100644 index 0000000000000..a528effa490c3 --- /dev/null +++ b/soc/nxp/imx/imx9/imx91/Kconfig @@ -0,0 +1,12 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_MIMX9131 + select ARM64 + select CPU_CORTEX_A55 + select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS + select HAS_MCUX if CLOCK_CONTROL + select HAS_MCUX_CCM_REV2 if CLOCK_CONTROL + select HAS_MCUX_IOMUXC if PINCTRL + select HAS_MCUX_CACHE + select KERNEL_DIRECT_MAP if HAS_MCUX diff --git a/soc/nxp/imx/imx9/imx91/Kconfig.defconfig b/soc/nxp/imx/imx9/imx91/Kconfig.defconfig new file mode 100644 index 0000000000000..1f176ff474826 --- /dev/null +++ b/soc/nxp/imx/imx9/imx91/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_IMX9 + +rsource "Kconfig.defconfig.*" + +endif # SOC_SERIES_IMX9 diff --git a/soc/nxp/imx/imx9/imx91/Kconfig.defconfig.mimx91 b/soc/nxp/imx/imx9/imx91/Kconfig.defconfig.mimx91 new file mode 100644 index 0000000000000..748117545f0f6 --- /dev/null +++ b/soc/nxp/imx/imx9/imx91/Kconfig.defconfig.mimx91 @@ -0,0 +1,21 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MIMX9131 + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_FLASH := zephyr,flash + +config FLASH_SIZE + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0,K) + +config FLASH_BASE_ADDRESS + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) + +config NUM_IRQS + default 300 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 24000000 + +endif diff --git a/soc/nxp/imx/imx9/imx91/Kconfig.soc b/soc/nxp/imx/imx9/imx91/Kconfig.soc new file mode 100644 index 0000000000000..a3a063740cd9e --- /dev/null +++ b/soc/nxp/imx/imx9/imx91/Kconfig.soc @@ -0,0 +1,21 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_MIMX9131 + bool + select SOC_SERIES_IMX9 + help + NXP i.MX91 + +config SOC_PART_NUMBER_MIMX9131CVVXJ + bool + +config SOC_PART_NUMBER_MIMX9131DVVXJ + bool + +config SOC_PART_NUMBER + default "MIMX9131CVVXJ" if SOC_PART_NUMBER_MIMX9131CVVXJ + default "MIMX9131DVVXJ" if SOC_PART_NUMBER_MIMX9131DVVXJ + +config SOC + default "mimx9131" if SOC_MIMX9131 diff --git a/soc/nxp/imx/imx9/imx91/mmu_regions.c b/soc/nxp/imx/imx9/imx91/mmu_regions.c new file mode 100644 index 0000000000000..62f04672b6623 --- /dev/null +++ b/soc/nxp/imx/imx9/imx91/mmu_regions.c @@ -0,0 +1,38 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static const struct arm_mmu_region mmu_regions[] = { + MMU_REGION_FLAT_ENTRY("GIC", DT_REG_ADDR_BY_IDX(DT_NODELABEL(gic), 0), + DT_REG_SIZE_BY_IDX(DT_NODELABEL(gic), 0), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), + + MMU_REGION_FLAT_ENTRY("GIC", DT_REG_ADDR_BY_IDX(DT_NODELABEL(gic), 1), + DT_REG_SIZE_BY_IDX(DT_NODELABEL(gic), 1), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), + + MMU_REGION_FLAT_ENTRY("CCM", DT_REG_ADDR(DT_NODELABEL(ccm)), DT_REG_SIZE(DT_NODELABEL(ccm)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), + + MMU_REGION_FLAT_ENTRY("ANA_PLL", DT_REG_ADDR(DT_NODELABEL(ana_pll)), + DT_REG_SIZE(DT_NODELABEL(ana_pll)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), + + MMU_REGION_FLAT_ENTRY("IOMUXC", DT_REG_ADDR(DT_NODELABEL(iomuxc)), + DT_REG_SIZE(DT_NODELABEL(iomuxc)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), + + MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_lpuart, + (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS)) +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; diff --git a/soc/nxp/imx/imx9/imx91/pinctrl_soc.h b/soc/nxp/imx/imx9/imx91/pinctrl_soc.h new file mode 100644 index 0000000000000..da79bbfab43a2 --- /dev/null +++ b/soc/nxp/imx/imx9/imx91/pinctrl_soc.h @@ -0,0 +1,79 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM64_NXP_IMX9_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM64_NXP_IMX9_PINCTRL_SOC_H_ + +#include +#include +#include "fsl_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MCUX_IMX_INPUT_SCHMITT_ENABLE_SHIFT IOMUXC1_SW_PAD_CTL_PAD_HYS_SHIFT +#define MCUX_IMX_DRIVE_OPEN_DRAIN_SHIFT IOMUXC1_SW_PAD_CTL_PAD_OD_SHIFT +#define MCUX_IMX_BIAS_PULL_DOWN_SHIFT IOMUXC1_SW_PAD_CTL_PAD_PD_SHIFT +#define MCUX_IMX_BIAS_PULL_UP_SHIFT IOMUXC1_SW_PAD_CTL_PAD_PU_SHIFT +#define MCUX_IMX_SLEW_RATE_SHIFT IOMUXC1_SW_PAD_CTL_PAD_FSEL1_SHIFT +#define MCUX_IMX_DRIVE_STRENGTH_SHIFT IOMUXC1_SW_PAD_CTL_PAD_DSE_SHIFT +#define MCUX_IMX_INPUT_ENABLE_SHIFT 23 /* Shift to a bit not used by IOMUXC_SW_PAD_CTL */ +#define MCUX_IMX_INPUT_ENABLE(x) ((x >> MCUX_IMX_INPUT_ENABLE_SHIFT) & 0x1) + +#define Z_PINCTRL_MCUX_IMX_PINCFG_INIT(node_id) \ + ((DT_PROP(node_id, input_schmitt_enable) << MCUX_IMX_INPUT_SCHMITT_ENABLE_SHIFT) | \ + (DT_PROP(node_id, drive_open_drain) << MCUX_IMX_DRIVE_OPEN_DRAIN_SHIFT) | \ + (DT_PROP(node_id, bias_pull_down) << MCUX_IMX_BIAS_PULL_DOWN_SHIFT) | \ + (DT_PROP(node_id, bias_pull_up) << MCUX_IMX_BIAS_PULL_UP_SHIFT) | \ + (DT_ENUM_IDX(node_id, slew_rate) << MCUX_IMX_SLEW_RATE_SHIFT) | \ + ((~(0xff << DT_ENUM_IDX(node_id, drive_strength))) << MCUX_IMX_DRIVE_STRENGTH_SHIFT) | \ + (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT)) + +/* This struct must be present. It is used by the mcux gpio driver */ +struct pinctrl_soc_pinmux { + uint32_t mux_register; /*!< IOMUXC SW_PAD_MUX register */ + uint32_t config_register; /*!< IOMUXC SW_PAD_CTL register */ + uint32_t input_register; /*!< IOMUXC SELECT_INPUT DAISY register */ + uint8_t mux_mode: 4; /*!< Mux value for SW_PAD_MUX register */ + uint32_t input_daisy: 4; /*!< Mux value for SELECT_INPUT_DAISY register */ +}; + +struct pinctrl_soc_pin { + struct pinctrl_soc_pinmux pinmux; + uint32_t pin_ctrl_flags; /*!< value to write to IOMUXC_SW_PAD_CTL register */ +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +/* This definition must be present. It is used by the mcux gpio driver */ +#define MCUX_IMX_PINMUX(node_id) \ + { \ + .mux_register = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .config_register = DT_PROP_BY_IDX(node_id, pinmux, 4), \ + .input_register = DT_PROP_BY_IDX(node_id, pinmux, 2), \ + .mux_mode = DT_PROP_BY_IDX(node_id, pinmux, 1), \ + .input_daisy = DT_PROP_BY_IDX(node_id, pinmux, 3), \ + } + +#define Z_PINCTRL_PINMUX(group_id, pin_prop, idx) \ + MCUX_IMX_PINMUX(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx)) + +#define Z_PINCTRL_STATE_PIN_INIT(group_id, pin_prop, idx) \ + { \ + .pinmux = Z_PINCTRL_PINMUX(group_id, pin_prop, idx), \ + .pin_ctrl_flags = Z_PINCTRL_MCUX_IMX_PINCFG_INIT(group_id), \ + }, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM64_NXP_IMX9_PINCTRL_SOC_H_ */ diff --git a/soc/nxp/imx/imx9/imx93/CMakeLists.txt b/soc/nxp/imx/imx9/imx93/CMakeLists.txt index 59bd50b2d3ee8..1d511e7d5ff04 100644 --- a/soc/nxp/imx/imx9/imx93/CMakeLists.txt +++ b/soc/nxp/imx/imx9/imx93/CMakeLists.txt @@ -10,5 +10,6 @@ if(CONFIG_SOC_MIMX9352_A55) elseif(CONFIG_SOC_MIMX9352_M33) zephyr_include_directories(.) zephyr_include_directories(m33) + zephyr_sources(m33/soc.c) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") endif() diff --git a/soc/nxp/imx/imx9/imx93/Kconfig b/soc/nxp/imx/imx9/imx93/Kconfig index 87de1fbcf92db..f17c137891189 100644 --- a/soc/nxp/imx/imx9/imx93/Kconfig +++ b/soc/nxp/imx/imx9/imx93/Kconfig @@ -21,6 +21,7 @@ config SOC_MIMX9352_M33 select HAS_MCUX select HAS_MCUX_IOMUXC if PINCTRL select HAS_MCUX_CACHE + select SOC_EARLY_INIT_HOOK config MCUX_CORE_SUFFIX default "_ca55" if SOC_MIMX9352_A55 diff --git a/soc/nxp/imx/imx9/imx93/Kconfig.defconfig.mimx93.a55 b/soc/nxp/imx/imx9/imx93/Kconfig.defconfig.mimx93.a55 index e0516f2bf69e2..187953e17a05b 100644 --- a/soc/nxp/imx/imx9/imx93/Kconfig.defconfig.mimx93.a55 +++ b/soc/nxp/imx/imx9/imx93/Kconfig.defconfig.mimx93.a55 @@ -12,6 +12,10 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) +# Enable GIC Safe Configuration to run multiple OSes on Cortex-A Cores +config GIC_SAFE_CONFIG + default y + config NUM_IRQS default 240 diff --git a/soc/nxp/imx/imx9/imx93/a55/mmu_regions.c b/soc/nxp/imx/imx9/imx93/a55/mmu_regions.c index 1052a55a5dce7..b4bc0e24965e7 100644 --- a/soc/nxp/imx/imx9/imx93/a55/mmu_regions.c +++ b/soc/nxp/imx/imx9/imx93/a55/mmu_regions.c @@ -29,7 +29,7 @@ static const struct arm_mmu_region mmu_regions[] = { DT_REG_SIZE(DT_NODELABEL(iomuxc)), MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS), - MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_kinetis_lpuart, + MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_lpuart, (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS)) MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_flexcan, diff --git a/soc/nxp/imx/imx9/imx93/m33/soc.c b/soc/nxp/imx/imx9/imx93/m33/soc.c new file mode 100644 index 0000000000000..ef61a7cb7fbb9 --- /dev/null +++ b/soc/nxp/imx/imx9/imx93/m33/soc.c @@ -0,0 +1,21 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#ifdef CONFIG_SOC_EARLY_INIT_HOOK +void soc_early_init_hook(void) +{ + /* Configure secure access to pin registers */ + GPIO1->PCNS = 0x0; + GPIO2->PCNS = 0x0; + GPIO3->PCNS = 0x0; + GPIO4->PCNS = 0x0; +} +#endif diff --git a/soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.a55 b/soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.a55 index 603b1b826dd9c..ce23fcbf2e4ea 100644 --- a/soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.a55 +++ b/soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.a55 @@ -12,6 +12,10 @@ config FLASH_SIZE config FLASH_BASE_ADDRESS default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) +# Enable GIC Safe Configuration to run multiple OSes on Cortex-A Cores +config GIC_SAFE_CONFIG + default y + config NUM_IRQS default 320 diff --git a/soc/nxp/imx/imx9/imx95/a55/mmu_regions.c b/soc/nxp/imx/imx9/imx95/a55/mmu_regions.c index d79f99e0ac64e..fa40e4639e042 100644 --- a/soc/nxp/imx/imx9/imx95/a55/mmu_regions.c +++ b/soc/nxp/imx/imx9/imx95/a55/mmu_regions.c @@ -21,7 +21,7 @@ static const struct arm_mmu_region mmu_regions[] = { MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_mbox_imx_mu, (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS)) - MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_kinetis_lpuart, + MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_lpuart, (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS)) }; diff --git a/soc/nxp/imx/soc.yml b/soc/nxp/imx/soc.yml index 64371b41c235f..e955bfee6a8ac 100644 --- a/soc/nxp/imx/soc.yml +++ b/soc/nxp/imx/soc.yml @@ -35,6 +35,7 @@ family: - name: m4 - name: imx9 socs: + - name: mimx9131 - name: mimx9352 cpuclusters: - name: a55 diff --git a/soc/nxp/imxrt/CMakeLists.txt b/soc/nxp/imxrt/CMakeLists.txt index 5984d081ba9b2..82d23ee5b5a0d 100644 --- a/soc/nxp/imxrt/CMakeLists.txt +++ b/soc/nxp/imxrt/CMakeLists.txt @@ -39,9 +39,6 @@ if(CONFIG_SOC_SERIES_IMXRT10XX OR CONFIG_SOC_SERIES_IMXRT11XX) endif() if(CONFIG_SOC_SERIES_IMXRT118X) - if(CONFIG_SOC_MIMXRT1189_CM7) - zephyr_sources(mpu_regions.c) - endif() if(CONFIG_EXTERNAL_MEM_CONFIG_DATA) set(boot_hdr_xmcd_data_section ".boot_hdr.xmcd_data") endif() @@ -69,7 +66,7 @@ if(CONFIG_SOC_SERIES_IMXRT118X) zephyr_compile_definitions(XIP_EXTERNAL_FLASH) endif() -if(CONFIG_SOC_SERIES_IMXRT6XX OR CONFIG_SOC_SERIES_IMXRT5XX) +if(CONFIG_SOC_SERIES_IMXRT6XX OR CONFIG_SOC_SERIES_IMXRT5XX OR CONFIG_SOC_SERIES_IMXRT7XX) zephyr_linker_sources_ifdef(CONFIG_USB_DEVICE_DRIVER SECTIONS usb.ld) zephyr_linker_sources_ifdef(CONFIG_UDC_DRIVER SECTIONS usb.ld) endif() diff --git a/soc/nxp/imxrt/Kconfig b/soc/nxp/imxrt/Kconfig index eb10a3a1a7602..c09776302e7bf 100644 --- a/soc/nxp/imxrt/Kconfig +++ b/soc/nxp/imxrt/Kconfig @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 config SOC_FAMILY_NXP_IMXRT @@ -10,7 +10,13 @@ if SOC_FAMILY_NXP_IMXRT # can override the defaults given here rsource "*/Kconfig" +if DT_HAS_NXP_IMX_FLEXSPI_ENABLED rsource "../common/Kconfig.flexspi_xip" +endif + +if DT_HAS_NXP_XSPI_ENABLED +rsource "../common/Kconfig.xspi_xip" +endif # Note- When SECOND_CORE_MCUX is set, the dependencies for this Kconfig # should be set elsewhere, since the determination of which SOC core @@ -29,8 +35,13 @@ rsource "../common/Kconfig.rom_loader" choice BOOT_DEVICE prompt "Boot device" + default BOOT_XSPI_NOR if DT_HAS_NXP_XSPI_ENABLED default BOOT_FLEXSPI_NOR +config BOOT_XSPI_NOR + bool "XPI serial NOR" + depends on DT_HAS_NXP_XSPI_ENABLED + config BOOT_FLEXSPI_NOR bool "FlexSPI serial NOR" depends on HAS_MCUX_FLEXSPI @@ -49,6 +60,8 @@ config BOOT_SEMC_NAND endchoice # BOOT_DEVICE +if BOOT_FLEXSPI_NOR + config FLEXSPI_CONFIG_BLOCK_OFFSET hex "FlexSPI config block offset" default 0x0 if BOOT_FLEXSPI_NOR @@ -59,6 +72,21 @@ config FLEXSPI_CONFIG_BLOCK_OFFSET sequence (optional), etc. The boot ROM expects FlexSPI configuration parameter to be presented in serial nor flash. +endif # BOOT_FLEXSPI_NOR + +if BOOT_XSPI_NOR + +config XSPI_CONFIG_BLOCK_OFFSET + hex "XSPI config block offset" + default 0x0 + help + XSPI configuration block consists of parameters regarding specific + flash devices including read command sequence, quad mode enablement + sequence (optional), etc. The boot ROM expects XSPI configuration + parameter to be presented in serial nor flash. + +endif # BOOT_XSPI_NOR + config IMAGE_VECTOR_TABLE_OFFSET hex "Image vector table offset" default 0x1000 if BOOT_FLEXSPI_NOR || BOOT_SEMC_NOR @@ -113,9 +141,10 @@ config NXP_IMX_EXTERNAL_HYPERRAM This setting should be enabled when the application uses HYPERRAM, or an MPU region will be defined to disable cached access to the HYPERRAM memory space. + config SECOND_CORE_MCUX bool "Dual core operation on the RT11xx series" - depends on SOC_SERIES_IMXRT11XX + depends on SOC_SERIES_IMXRT11XX || SOC_SERIES_IMXRT118X help Indicates the second core will be enabled, and the part will run in dual core mode. Enables dual core operation on the RT11xx series, @@ -124,6 +153,13 @@ config SECOND_CORE_MCUX generated header specifying the VMA and LMA of each memory section to load +config SECOND_CORE_MCUX_REMOTE_DIR + string "Directory to with output image header from second core" + depends on SECOND_CORE_MCUX + help + Sets the remote directory to include the output image header data + from when launching a second core image + if SOC_SERIES_IMXRT10XX || SOC_SERIES_IMXRT11XX || SOC_SERIES_IMXRT118X config PM_MCUX_GPC diff --git a/soc/nxp/imxrt/Kconfig.defconfig b/soc/nxp/imxrt/Kconfig.defconfig index 5a05de8bb200f..f82e9e126f01b 100644 --- a/soc/nxp/imxrt/Kconfig.defconfig +++ b/soc/nxp/imxrt/Kconfig.defconfig @@ -81,10 +81,6 @@ choice SEGGER_SYSVIEW_SECTION depends on SEGGER_SYSTEMVIEW endchoice -config MBEDTLS - default y if CSPRNG_ENABLED - depends on ENTROPY_GENERATOR - if MBEDTLS # # MBEDTLS CTR_DRBG code path needs extra stack space for initialization than diff --git a/soc/nxp/imxrt/Kconfig.sysbuild b/soc/nxp/imxrt/Kconfig.sysbuild new file mode 100644 index 0000000000000..3bcebc671b15b --- /dev/null +++ b/soc/nxp/imxrt/Kconfig.sysbuild @@ -0,0 +1,12 @@ +# Copyright 2024 Daniel DeGrasse +# SPDX-License-Identifier: Apache-2.0 + +config SECOND_CORE_MCUX_LAUNCHER + bool "Load minimal application to primary core to boot secondary one" + default y if (SOC_MIMXRT1176_CM4 || SOC_MIMXRT1166_CM4) + depends on SOC_SERIES_IMXRT11XX + help + Load a minimal application to the primary core to boot the secondary + one. The primary core will be loaded with the samples/basic/minimal + application, and the appropriate configuration will be set to + boot the secondary core during startup. diff --git a/soc/nxp/imxrt/boot_header.ld b/soc/nxp/imxrt/boot_header.ld index 618c760f0170b..b61487c481955 100644 --- a/soc/nxp/imxrt/boot_header.ld +++ b/soc/nxp/imxrt/boot_header.ld @@ -9,11 +9,15 @@ __VECTOR_TABLE = CONFIG_ROM_START_OFFSET; __Vectors = __VECTOR_TABLE; #endif +#if defined(CONFIG_BOOT_XSPI_NOR) +. = CONFIG_XSPI_CONFIG_BLOCK_OFFSET; +#else . = CONFIG_FLEXSPI_CONFIG_BLOCK_OFFSET; +#endif #if defined(CONFIG_SOC_SERIES_IMXRT11XX) || defined(CONFIG_SOC_SERIES_IMXRT10XX) || defined(CONFIG_SOC_SERIES_IMXRT118X) KEEP(*(.boot_hdr.conf)) #endif -#if defined(CONFIG_SOC_SERIES_IMXRT6XX) || defined(CONFIG_SOC_SERIES_IMXRT5XX) +#if defined(CONFIG_SOC_SERIES_IMXRT6XX) || defined(CONFIG_SOC_SERIES_IMXRT5XX) || defined(CONFIG_SOC_SERIES_IMXRT7XX) KEEP(*(.flash_conf)) #endif #if defined(CONFIG_SOC_SERIES_IMXRT118X) diff --git a/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt index 0689025c9fca8..77421318acc25 100644 --- a/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt @@ -11,7 +11,7 @@ if(CONFIG_PM) zephyr_code_relocate(FILES power.c LOCATION ITCM_TEXT) if(CONFIG_SOC_MIMXRT1064) zephyr_sources(lpm_rt1064.c) - zephyr_code_relocate(FILES lpm_rt1064 LOCATION ITCM_TEXT) + zephyr_code_relocate(FILES lpm_rt1064.c LOCATION ITCM_TEXT) endif() endif() diff --git a/soc/nxp/imxrt/imxrt10xx/Kconfig b/soc/nxp/imxrt/imxrt10xx/Kconfig index c86f946aab835..4a9508777abc9 100644 --- a/soc/nxp/imxrt/imxrt10xx/Kconfig +++ b/soc/nxp/imxrt/imxrt10xx/Kconfig @@ -87,7 +87,6 @@ config SOC_MIMXRT1052 select HAS_MCUX_FLEXCAN select HAS_MCUX_PWM select HAS_MCUX_SRC - select HAS_MCUX_XBARA config SOC_MIMXRT1062 select HAS_MCUX_ELCDIF @@ -107,7 +106,6 @@ config SOC_MIMXRT1062 select HAS_MCUX_I2S select HAS_MCUX_ADC_ETC select HAS_MCUX_SRC - select HAS_MCUX_XBARA config SOC_MIMXRT1064 select HAS_MCUX_ELCDIF diff --git a/soc/nxp/imxrt/imxrt10xx/soc.c b/soc/nxp/imxrt/imxrt10xx/soc.c index 941ae1d34747f..e6b6160600d35 100644 --- a/soc/nxp/imxrt/imxrt10xx/soc.c +++ b/soc/nxp/imxrt/imxrt10xx/soc.c @@ -135,7 +135,7 @@ const __imx_boot_ivt_section ivt image_vector_table = { /** * @brief Initialize the system clock */ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { /* Boot ROM did initialize the XTAL, here we only sets external XTAL * OSC freq diff --git a/soc/nxp/imxrt/imxrt118x/CMakeLists.txt b/soc/nxp/imxrt/imxrt118x/CMakeLists.txt index faabf48236ffd..4441a41b39ec1 100644 --- a/soc/nxp/imxrt/imxrt118x/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt118x/CMakeLists.txt @@ -11,6 +11,10 @@ if(CONFIG_SOC_MIMXRT1189_CM33) zephyr_linker_sources(DTCM_SECTION m33/dtcm.ld) endif() +if(CONFIG_SOC_MIMXRT1189_CM7) + zephyr_sources(m7/mpu_regions.c) +endif() + zephyr_include_directories(.) if(CONFIG_MEMC_MCUX_FLEXSPI) diff --git a/soc/nxp/imxrt/imxrt118x/Kconfig b/soc/nxp/imxrt/imxrt118x/Kconfig index b2aa59090af73..d62af3d1b5183 100644 --- a/soc/nxp/imxrt/imxrt118x/Kconfig +++ b/soc/nxp/imxrt/imxrt118x/Kconfig @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 config SOC_SERIES_IMXRT118X - select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS if SOC_MIMXRT1189_CM7 select CPU_CORTEX_M_HAS_DWT select SOC_RESET_HOOK select INIT_ARCH_HW_AT_BOOT if SOC_MIMXRT1189_CM33 @@ -13,12 +12,12 @@ config SOC_SERIES_IMXRT118X select CPU_HAS_ARM_SAU if SOC_MIMXRT1189_CM33 select HAS_MCUX select CPU_HAS_ARM_MPU - select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS if SOC_MIMXRT1189_CM33 - select ARM_MPU if SOC_MIMXRT1189_CM33 + select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS + select ARM_MPU select INIT_ARM_PLL select ARM_TRUSTZONE_M if SOC_MIMXRT1189_CM33 - select CPU_HAS_ICACHE if SOC_MIMXRT1189_CM7 - select CPU_HAS_DCACHE if SOC_MIMXRT1189_CM7 + select CPU_HAS_ICACHE + select CPU_HAS_DCACHE select CPU_HAS_FPU select CPU_HAS_FPU_DOUBLE_PRECISION if SOC_MIMXRT1189_CM7 select HAS_MCUX_IOMUXC @@ -28,6 +27,8 @@ config SOC_SERIES_IMXRT118X config SOC_MIMXRT1189_CM33 select CPU_CORTEX_M33 + select HAS_MCUX_XCACHE + select CACHE_MANAGEMENT config SOC_MIMXRT1189_CM7 select CPU_CORTEX_M7 @@ -66,12 +67,4 @@ config S3MU_MCUX_S3MU default y bool "Use S3MU MCUX Driver" -config IMXRT118X_CM33_XCACHE_PS - bool "Use CM33 XCACHE_PS" - default y if SOC_MIMXRT1189_CM33 - help - Use CM33 XCACHE_PS at boot. Please note XCACHE_PC have been - enabled in SystemInit function. If this Kconfig is cleared, - the XCACHE controller won't be enabled during SOC init - endif # SOC_SERIES_IMXRT118X diff --git a/soc/nxp/imxrt/imxrt118x/Kconfig.defconfig b/soc/nxp/imxrt/imxrt118x/Kconfig.defconfig index ee930543c9b1c..228c42311dfc2 100644 --- a/soc/nxp/imxrt/imxrt118x/Kconfig.defconfig +++ b/soc/nxp/imxrt/imxrt118x/Kconfig.defconfig @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 if SOC_SERIES_IMXRT118X @@ -30,8 +30,13 @@ if SECOND_CORE_MCUX # RT Boot header is only needed on primary core config NXP_IMXRT_BOOT_HEADER - depends on !CPU_CORTEX_M7 + default y + depends on !(CPU_CORTEX_M7 || BOOTLOADER_MCUBOOT) endif # SECOND_CORE_MCUX +choice CACHE_TYPE + default EXTERNAL_CACHE if SOC_MIMXRT1189_CM33 +endchoice + endif # SOC_SERIES_IMXRT118X diff --git a/soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c b/soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c index 0e017caa56b3c..8783ad6a77edf 100644 --- a/soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c +++ b/soc/nxp/imxrt/imxrt118x/m33/mpu_regions.c @@ -11,6 +11,8 @@ #define REGION_FLEXSPI2_SIZE 0x04000000 #define REGION_DTCM_BASE_ADDRESS 0x30000000 #define REGION_DTCM_SIZE 0x00020000 +#define REGION_SRAM2_SHM_BASE_ADDRESS 0x20500000 +#define REGION_SRAM2_SHM_SIZE 0x00008000 #define REGION_FLEXSPI_BASE_ADDRESS 0x38000000 #define REGION_FLEXSPI_SIZE 0x08000000 #define REGION_PERIPHERAL_BASE_ADDRESS 0x50000000 @@ -23,6 +25,9 @@ static const struct arm_mpu_region mpu_regions[] = { REGION_FLASH_ATTR(REGION_FLEXSPI_BASE_ADDRESS, REGION_FLEXSPI_SIZE)), MPU_REGION_ENTRY("DTCM", REGION_DTCM_BASE_ADDRESS, REGION_RAM_NOCACHE_ATTR(REGION_DTCM_BASE_ADDRESS, REGION_DTCM_SIZE)), + MPU_REGION_ENTRY( + "SRAM2_SHM", REGION_SRAM2_SHM_BASE_ADDRESS, + REGION_RAM_NOCACHE_ATTR(REGION_SRAM2_SHM_BASE_ADDRESS, REGION_SRAM2_SHM_SIZE)), MPU_REGION_ENTRY( "PERIPHERAL", REGION_PERIPHERAL_BASE_ADDRESS, REGION_DEVICE_ATTR(REGION_PERIPHERAL_BASE_ADDRESS, REGION_PERIPHERAL_SIZE)), diff --git a/soc/nxp/imxrt/imxrt118x/m7/mpu_regions.c b/soc/nxp/imxrt/imxrt118x/m7/mpu_regions.c new file mode 100644 index 0000000000000..dbc52d8b68fdc --- /dev/null +++ b/soc/nxp/imxrt/imxrt118x/m7/mpu_regions.c @@ -0,0 +1,35 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define REGION_ITCM_BASE_ADDRESS 0x00000000 +#define REGION_ITCM_SIZE REGION_256K +#define REGION_FLEXSPI2_BASE_ADDRESS 0x04000000 +#define REGION_FLEXSPI2_SIZE REGION_64M +#define REGION_DTCM_BASE_ADDRESS 0x20000000 +#define REGION_DTCM_SIZE REGION_256K +#define REGION_FLEXSPI_BASE_ADDRESS 0x28000000 +#define REGION_FLEXSPI_SIZE REGION_128M +#define REGION_PERIPHERAL_BASE_ADDRESS 0x40000000 +#define REGION_PERIPHERAL_SIZE REGION_1G + +static const struct arm_mpu_region mpu_regions[] = { + MPU_REGION_ENTRY("ITCM", REGION_ITCM_BASE_ADDRESS, REGION_FLASH_ATTR(REGION_ITCM_SIZE)), + MPU_REGION_ENTRY("FLEXSPI2", REGION_FLEXSPI2_BASE_ADDRESS, + REGION_RAM_ATTR(REGION_FLEXSPI2_SIZE)), + MPU_REGION_ENTRY("FLEXSPI", REGION_FLEXSPI_BASE_ADDRESS, + REGION_FLASH_ATTR(REGION_FLEXSPI_SIZE)), + MPU_REGION_ENTRY("DTCM", REGION_DTCM_BASE_ADDRESS, REGION_RAM_ATTR(REGION_DTCM_SIZE)), + MPU_REGION_ENTRY("PERIPHERAL", REGION_PERIPHERAL_BASE_ADDRESS, + REGION_PPB_ATTR(REGION_PERIPHERAL_SIZE)), +}; + +const struct arm_mpu_config mpu_config = { + .num_regions = ARRAY_SIZE(mpu_regions), + .mpu_regions = mpu_regions, +}; diff --git a/soc/nxp/imxrt/imxrt118x/pinctrl_soc.h b/soc/nxp/imxrt/imxrt118x/pinctrl_soc.h index 797e62e9697c1..be0e3f8ebc56e 100644 --- a/soc/nxp/imxrt/imxrt118x/pinctrl_soc.h +++ b/soc/nxp/imxrt/imxrt118x/pinctrl_soc.h @@ -56,7 +56,7 @@ extern "C" { IF_ENABLED(DT_PROP(node_id, bias_pull_up), \ (MCUX_IMX_PULL_PULLUP << MCUX_IMX_PULL_SHIFT) |) \ (MCUX_IMX_NOPULL(node_id) << MCUX_IMX_PULL_SHIFT) | \ - (DT_ENUM_IDX_OR(node_id, drive_strength, 0) << MCUX_IMX_PDRV_SHIFT) | \ + ((!DT_ENUM_IDX_OR(node_id, drive_strength, 0)) << MCUX_IMX_PDRV_SHIFT) | \ (DT_PROP(node_id, drive_open_drain) << MCUX_IMX_ODE_SHIFT) | \ (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT) diff --git a/soc/nxp/imxrt/imxrt118x/soc.c b/soc/nxp/imxrt/imxrt118x/soc.c index fa4d3079c3b9d..3aad5b6ee3e5b 100644 --- a/soc/nxp/imxrt/imxrt118x/soc.c +++ b/soc/nxp/imxrt/imxrt118x/soc.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,23 +7,37 @@ #include #include #include +#include #include #include #include -#if defined(CONFIG_SOC_MIMXRT1189_CM7) #include -#elif defined(CONFIG_IMXRT118X_CM33_XCACHE_PS) -#include -#endif #include #include #include #include #include #include +#if defined(CONFIG_WDT_MCUX_RTWDOG) +#include +#endif #include #include +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33) +#include +/* Memcpy macro to copy segments from secondary core image stored in flash + * to RAM section that secondary core boots from. + * n is the segment number, as defined in zephyr_image_info.h + */ +#define MEMCPY_SEGMENT(n, _) \ + memcpy((uint32_t *)(((SEGMENT_LMA_ADDRESS_ ## n) - ADJUSTED_LMA) + 0x303C0000), \ + (uint32_t *)(SEGMENT_LMA_ADDRESS_ ## n), \ + (SEGMENT_SIZE_ ## n)) +#endif + /* * Set ELE_STICK_FAILED_STS to 0 when ELE status check is not required, * which is useful when debug reset, where the core has already get the @@ -42,6 +56,18 @@ #define ELE_TRDC_WAKEUP_ID 0x78 #define ELE_CORE_CM33_ID 0x1 #define ELE_CORE_CM7_ID 0x2 +#define EDMA_DID 0x7U + +/* When CM33 sets TRDC, CM7 must NOT require TRDC ownership from ELE */ +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_SOC_MIMXRT1189_CM33) +/* When CONFIG_SECOND_CORE_MCUX then TRDC(AON/WAKEUP) ownership cannot be released + * to CM33 and CM7 both in one ELE reset cycle. + * Only CM33 will set TRDC. + */ +#define CM33_SET_TRDC 1U +#else +#define CM33_SET_TRDC 0U +#endif #ifdef CONFIG_INIT_ARM_PLL static const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { @@ -56,6 +82,14 @@ static const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = { }; #endif +#if defined(CONFIG_WDT_MCUX_RTWDOG) +#define RTWDOG_IF_SET_SRC(n, i) \ + if (IS_ENABLED(DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(rtwdog##n), nxp_rtwdog, okay))) { \ + SRC_SetGlobalSystemResetMode(SRC_GENERAL_REG, kSRC_Wdog##i##Reset, \ + kSRC_ResetSystem); \ + } +#endif + const clock_sys_pll1_config_t sysPll1Config_BOARD_BootClockRUN = { /* Enable Sys Pll1 divide-by-2 clock or not */ .pllDiv2En = 1, @@ -91,7 +125,7 @@ __attribute__((weak)) void board_flexspi_clock_safe_config(void) /** * @brief Initialize the system clock */ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { clock_root_config_t rootCfg = {0}; @@ -260,15 +294,34 @@ static ALWAYS_INLINE void clock_init(void) CLOCK_SetRootClock(kCLOCK_Root_Lpi2c0506, &rootCfg); #endif -#if defined(CONFIG_SPI_MCUX_LPSPI) && \ - (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi1)) \ - || DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi2))) +#if defined(CONFIG_SPI_MCUX_LPSPI) + +#if (DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi1), okay) \ + || DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi2), okay)) /* Configure LPSPI0102 using SYS_PLL3_PFD1_CLK */ rootCfg.mux = kCLOCK_LPSPI0102_ClockRoot_MuxSysPll3Pfd1; rootCfg.div = 2; CLOCK_SetRootClock(kCLOCK_Root_Lpspi0102, &rootCfg); #endif +#if (DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi3), okay) \ + || DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi4), okay)) + /* Configure LPSPI0304 using SYS_PLL3_PFD1_CLK */ + rootCfg.mux = kCLOCK_LPSPI0304_ClockRoot_MuxSysPll3Pfd1; + rootCfg.div = 2; + CLOCK_SetRootClock(kCLOCK_Root_Lpspi0304, &rootCfg); +#endif + +#if (DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi5), okay) \ + || DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi6), okay)) + /* Configure LPSPI0506 using SYS_PLL3_PFD1_CLK */ + rootCfg.mux = kCLOCK_LPSPI0506_ClockRoot_MuxSysPll3Pfd1; + rootCfg.div = 2; + CLOCK_SetRootClock(kCLOCK_Root_Lpspi0506, &rootCfg); +#endif + +#endif /* CONFIG_SPI_MCUX_LPSPI */ + #if defined(CONFIG_COUNTER_MCUX_GPT) #if (DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpt1))) @@ -417,9 +470,88 @@ static ALWAYS_INLINE void clock_init(void) CLOCK_SetRootClock(kCLOCK_Root_Flexspi1, &rootCfg); #endif +#ifdef CONFIG_HAS_MCUX_TPM + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(tpm2), okay) + /* Configure TPM2 using SYS_PLL3_DIV2_CLK */ + rootCfg.mux = kCLOCK_TPM2_ClockRoot_MuxSysPll3Div2; + rootCfg.div = 3; + CLOCK_SetRootClock(kCLOCK_Root_Tpm2, &rootCfg); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(tpm4), okay) + /* Configure TPM4 using SYS_PLL3_DIV2_CLK */ + rootCfg.mux = kCLOCK_TPM4_ClockRoot_MuxSysPll3Div2; + rootCfg.div = 3; + CLOCK_SetRootClock(kCLOCK_Root_Tpm4, &rootCfg); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(tpm5), okay) + /* Configure TPM5 using SYS_PLL3_DIV2_CLK */ + rootCfg.mux = kCLOCK_TPM5_ClockRoot_MuxSysPll3Div2; + rootCfg.div = 3; + CLOCK_SetRootClock(kCLOCK_Root_Tpm5, &rootCfg); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(tpm6), okay) + /* Configure TPM6 using SYS_PLL3_DIV2_CLK */ + rootCfg.mux = kCLOCK_TPM6_ClockRoot_MuxSysPll3Div2; + rootCfg.div = 3; + CLOCK_SetRootClock(kCLOCK_Root_Tpm6, &rootCfg); +#endif + +#endif /* CONFIG_HAS_MCUX_TPM */ + +#ifdef CONFIG_DT_HAS_NXP_MCUX_I3C_ENABLED + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c1), okay) + /* Configure I3C1 using SYS_PLL3_DIV2_CLK */ + rootCfg.mux = kCLOCK_I3C1_ClockRoot_MuxSysPll3Div2; + rootCfg.div = 10; + CLOCK_SetRootClock(kCLOCK_Root_I3c1, &rootCfg); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c2), okay) + /* Configure I3C2 using SYS_PLL3_DIV2_CLK */ + rootCfg.mux = kCLOCK_I3C2_ClockRoot_MuxSysPll3Div2; + rootCfg.div = 10; + CLOCK_SetRootClock(kCLOCK_Root_I3c2, &rootCfg); +#endif + +#endif /* CONFIG_DT_HAS_NXP_MCUX_I3C_ENABLED */ + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb1)) && CONFIG_UDC_NXP_EHCI + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usb480M, + DT_PROP_BY_PHANDLE(DT_NODELABEL(usb1), clocks, clock_frequency)); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, + DT_PROP_BY_PHANDLE(DT_NODELABEL(usb1), clocks, clock_frequency)); +#endif + +#ifdef CONFIG_IMX_USDHC + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc1), okay) + /* Configure USDHC1 using SysPll2Pfd2 */ + rootCfg.mux = kCLOCK_USDHC1_ClockRoot_MuxSysPll2Pfd2; + rootCfg.div = 2; + CLOCK_SetRootClock(kCLOCK_Root_Usdhc1, &rootCfg); +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(usdhc2), okay) + /* Configure USDHC2 using SysPll2Pfd2 */ + rootCfg.mux = kCLOCK_USDHC2_ClockRoot_MuxSysPll2Pfd2; + rootCfg.div = 2; + CLOCK_SetRootClock(kCLOCK_Root_Usdhc2, &rootCfg); +#endif + +#endif /* CONFIG_IMX_USDHC */ + /* Keep core clock ungated during WFI */ CCM->LPCG[1].LPM0 = 0x33333333; CCM->LPCG[1].LPM1 = 0x33333333; + + /* Let the core clock still running in WAIT mode */ + BLK_CTRL_S_AONMIX->M7_CFG |= BLK_CTRL_S_AONMIX_M7_CFG_CORECLK_FORCE_ON_MASK; + /* Keep the system clock running so SYSTICK can wake up * the system from wfi. */ @@ -427,13 +559,6 @@ static ALWAYS_INLINE void clock_init(void) GPC_CM_SetNextCpuMode(1, kGPC_RunMode); GPC_CM_EnableCpuSleepHold(0, false); GPC_CM_EnableCpuSleepHold(1, false); - -#if !defined(CONFIG_PM) - /* Enable the AHB clock while the CM7 is sleeping to allow debug access - * to TCM - */ - BLK_CTRL_S_AONMIX->M7_CFG |= BLK_CTRL_S_AONMIX_M7_CFG_TCM_SIZE_MASK; -#endif } /** @@ -444,33 +569,55 @@ static ALWAYS_INLINE void trdc_enable_all_access(void) status_t sts; uint8_t i, j; - /* Get ELE FW status */ + /* Get ELE FW status */ do { uint32_t ele_fw_sts; sts = ELE_BaseAPI_GetFwStatus(MU_RT_S3MUA, &ele_fw_sts); } while (sts != kStatus_Success); - do { #if defined(CONFIG_SOC_MIMXRT1189_CM33) - /* Release TRDC A to CM33 core */ - sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_AON_ID, ELE_CORE_CM33_ID); + /* Release TRDC AON to CM33 core */ + sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_AON_ID, ELE_CORE_CM33_ID); #elif defined(CONFIG_SOC_MIMXRT1189_CM7) - /* Release TRDC A to CM7 core */ - sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_AON_ID, ELE_CORE_CM7_ID); + /* Release TRDC AON to CM7 core */ + sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_AON_ID, ELE_CORE_CM7_ID); #endif - } while (ELE_IS_FAILED(sts)); + if (sts != kStatus_Success) { + LOG_WRN("warning: TRDC AON permission get failed. If core don't get TRDC " + "AON permission, AON domain permission can't be configured."); + } - /* Release TRDC W to CM33 core */ - do { #if defined(CONFIG_SOC_MIMXRT1189_CM33) - /* Release TRDC A to CM33 core */ - sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_WAKEUP_ID, ELE_CORE_CM33_ID); + /* Release TRDC Wakeup to CM33 core */ + sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_WAKEUP_ID, ELE_CORE_CM33_ID); #elif defined(CONFIG_SOC_MIMXRT1189_CM7) - /* Release TRDC A to CM7 core */ - sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_WAKEUP_ID, ELE_CORE_CM7_ID); + /* Release TRDC Wakeup to CM7 core */ + sts = ELE_BaseAPI_ReleaseRDC(MU_RT_S3MUA, ELE_TRDC_WAKEUP_ID, ELE_CORE_CM7_ID); #endif - } while (ELE_IS_FAILED(sts)); + if (sts != kStatus_Success) { + LOG_WRN("warning: TRDC Wakeup permission get failed. If core don't get TRDC " + "Wakeup permission, Wakeup domain permission can't be configured."); + } + + /* Set the master domain access configuration for eDMA3/eDMA4 */ + trdc_non_processor_domain_assignment_t edmaAssignment; + + /* By default, EDMA access is done in privilege and security mode, + * However, the NSE bit reset value in TRDC is 0, so that TRDC does + * not allow nonsecurity access to other memory by default. + * So by DAC module, EDMA access mode is changed to security/privilege + * mode by the DAC module + */ + (void)memset(&edmaAssignment, 0, sizeof(edmaAssignment)); + edmaAssignment.domainId = EDMA_DID; + edmaAssignment.privilegeAttr = kTRDC_MasterPrivilege; + edmaAssignment.secureAttr = kTRDC_ForceSecure; + edmaAssignment.bypassDomainId = true; + edmaAssignment.lock = false; + + TRDC_SetNonProcessorDomainAssignment(TRDC1, kTRDC1_MasterDMA3, &edmaAssignment); + TRDC_SetNonProcessorDomainAssignment(TRDC2, kTRDC2_MasterDMA4, &edmaAssignment); /* Enable all access modes for MBC and MRC of TRDCA and TRDCW */ trdc_hardware_config_t hwConfig; @@ -492,12 +639,18 @@ static ALWAYS_INLINE void trdc_enable_all_access(void) TRDC_GetHardwareConfig(TRDC1, &hwConfig); for (i = 0U; i < hwConfig.mrcNumber; i++) { + /* Set TRDC1(A) secure access for eDMA domain, MRC i, all region for i memory */ + TRDC_MrcDomainNseClear(TRDC1, i, 1UL << EDMA_DID); + for (j = 0U; j < 8; j++) { TRDC_MrcSetMemoryAccessConfig(TRDC1, &memAccessConfig, i, j); } } for (i = 0U; i < hwConfig.mbcNumber; i++) { + /* Set TRDC1(A) secure access for eDMA domain, MBC i, all memory blocks */ + TRDC_MbcNseClearAll(TRDC1, i, 1UL << EDMA_DID, 0xF); + for (j = 0U; j < 8; j++) { TRDC_MbcSetMemoryAccessConfig(TRDC1, &memAccessConfig, i, j); } @@ -505,12 +658,18 @@ static ALWAYS_INLINE void trdc_enable_all_access(void) TRDC_GetHardwareConfig(TRDC2, &hwConfig); for (i = 0U; i < hwConfig.mrcNumber; i++) { + /* Set TRDC2(W) secure access for eDMA domain, MRC i, all region for i memory */ + TRDC_MrcDomainNseClear(TRDC2, i, 1UL << EDMA_DID); + for (j = 0U; j < 8; j++) { TRDC_MrcSetMemoryAccessConfig(TRDC2, &memAccessConfig, i, j); } } for (i = 0U; i < hwConfig.mbcNumber; i++) { + /* Set TRDC2(W) secure access for eDMA domain, MBC i, all memory blocks */ + TRDC_MbcNseClearAll(TRDC2, i, 1UL << EDMA_DID, 0xF); + for (j = 0U; j < 8; j++) { TRDC_MbcSetMemoryAccessConfig(TRDC2, &memAccessConfig, i, j); } @@ -532,17 +691,42 @@ void soc_early_init_hook(void) { /* Initialize system clock */ clock_init(); + +#if (defined(CM33_SET_TRDC) && (CM33_SET_TRDC > 0U)) /* Get trdc and enable all access modes for MBC and MRC of TRDCA and TRDCW */ trdc_enable_all_access(); +#endif /* (defined(CM33_SET_TRDC) && (CM33_SET_TRDC > 0U) */ + +#if defined(CONFIG_WDT_MCUX_RTWDOG) + /* Unmask the watchdog reset channel */ + RTWDOG_IF_SET_SRC(0, 1) + RTWDOG_IF_SET_SRC(1, 2) + RTWDOG_IF_SET_SRC(2, 3) + RTWDOG_IF_SET_SRC(3, 4) + RTWDOG_IF_SET_SRC(4, 5) + + /* Clear the reset status otherwise TCM memory will reload in next reset */ + uint32_t mask = SRC_GetResetStatusFlags(SRC_GENERAL_REG); + + SRC_ClearGlobalSystemResetStatus(SRC_GENERAL_REG, mask); +#endif /* defined(CONFIG_WDT_MCUX_RTWDOG) */ + +#if (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) + /** + * Copy CM7 core from flash to memory. Note that depending on where the + * user decided to store CM7 code, this is likely going to read from the + * flexspi while using XIP. Provided we DO NOT WRITE TO THE FLEXSPI, + * this operation is safe. + * + * Note that this copy MUST occur before enabling the M33 caching to + * ensure the data is written directly to RAM (since the M4 core will use it) + */ + LISTIFY(SEGMENT_NUM, MEMCPY_SEGMENT, (;)); +#endif /* (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) */ /* Enable data cache */ -#if defined(CONFIG_IMXRT118X_CM33_XCACHE_PS) - XCACHE_EnableCache(XCACHE_PC); - XCACHE_EnableCache(XCACHE_PS); -#elif defined(CONFIG_SOC_MIMXRT1189_CM7) - sys_cache_instr_enable(); sys_cache_data_enable(); -#endif + __ISB(); __DSB(); } @@ -551,5 +735,41 @@ void soc_early_init_hook(void) void soc_reset_hook(void) { SystemInit(); + +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33) + Prepare_CM7(0); +#endif +} +#endif + +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33) + +static int second_core_boot(void) +{ + /* + * RT1180 Specific CM7 Kick Off operation + */ + /* Trigger S401 */ + while ((MU_RT_S3MUA->TSR & MU_TSR_TE0_MASK) == 0) { + ; } /* Wait TR empty */ + MU_RT_S3MUA->TR[0] = 0x17d20106; + while ((MU_RT_S3MUA->RSR & MU_RSR_RF0_MASK) == 0) { + ; } /* Wait RR Full */ + while ((MU_RT_S3MUA->RSR & MU_RSR_RF1_MASK) == 0) { + ; } /* Wait RR Full */ + + /* Response from ELE must be always read */ + __attribute__((unused)) volatile uint32_t result1, result2; + result1 = MU_RT_S3MUA->RR[0]; + result2 = MU_RT_S3MUA->RR[1]; + + /* Deassert Wait */ + BLK_CTRL_S_AONMIX->M7_CFG = + (BLK_CTRL_S_AONMIX->M7_CFG & (~BLK_CTRL_S_AONMIX_M7_CFG_WAIT_MASK)) | + BLK_CTRL_S_AONMIX_M7_CFG_WAIT(0); + + return 0; } + +SYS_INIT(second_core_boot, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt index 49636be86e631..960129d5cba79 100644 --- a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt @@ -16,4 +16,10 @@ if(CONFIG_MEMC_MCUX_FLEXSPI) endif() endif() +if(CONFIG_SECOND_CORE_MCUX_REMOTE_DIR) + # Add remote directory to include within the build + zephyr_include_directories(${CONFIG_SECOND_CORE_MCUX_REMOTE_DIR}) +endif() + + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/imxrt/imxrt11xx/Kconfig b/soc/nxp/imxrt/imxrt11xx/Kconfig index 434a22a5e155a..624831f3bf56e 100644 --- a/soc/nxp/imxrt/imxrt11xx/Kconfig +++ b/soc/nxp/imxrt/imxrt11xx/Kconfig @@ -15,6 +15,7 @@ config SOC_SERIES_IMXRT11XX select HAS_MCUX_LPI2C select HAS_MCUX_LPSPI select HAS_MCUX_LPADC + select HAS_MCUX_ADC_ETC select HAS_MCUX_LPUART select HAS_MCUX_ELCDIF select HAS_MCUX_MIPI_DSI @@ -41,7 +42,6 @@ config SOC_SERIES_IMXRT11XX select HAS_MCUX_USB_EHCI select HAS_MCUX_SRC_V2 select HAS_MCUX_IOMUXC - select HAS_MCUX_XBARA select HAS_SWO select HAS_PM diff --git a/soc/nxp/imxrt/imxrt11xx/pinctrl_soc.h b/soc/nxp/imxrt/imxrt11xx/pinctrl_soc.h index 04d652635c304..f2ca28b3c1432 100644 --- a/soc/nxp/imxrt/imxrt11xx/pinctrl_soc.h +++ b/soc/nxp/imxrt/imxrt11xx/pinctrl_soc.h @@ -58,7 +58,7 @@ extern "C" { IF_ENABLED(DT_PROP(node_id, bias_pull_up), \ (MCUX_IMX_PULL_PULLUP << MCUX_IMX_PULL_SHIFT) |) \ (MCUX_IMX_NOPULL(node_id) << MCUX_IMX_PULL_SHIFT) | \ - (DT_ENUM_IDX_OR(node_id, drive_strength, 0) << MCUX_IMX_PDRV_SHIFT) | \ + ((!DT_ENUM_IDX_OR(node_id, drive_strength, 0)) << MCUX_IMX_PDRV_SHIFT) | \ (DT_PROP(node_id, drive_open_drain) << MCUX_IMX_ODE_SHIFT) | \ (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT) diff --git a/soc/nxp/imxrt/imxrt11xx/soc.c b/soc/nxp/imxrt/imxrt11xx/soc.c index 8d6bae6323114..a75297fe2963d 100644 --- a/soc/nxp/imxrt/imxrt11xx/soc.c +++ b/soc/nxp/imxrt/imxrt11xx/soc.c @@ -160,7 +160,7 @@ const __imx_boot_ivt_section ivt image_vector_table = { /** * @brief Initialize the system clock */ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { clock_root_config_t rootCfg = {0}; @@ -567,6 +567,14 @@ static ALWAYS_INLINE void clock_init(void) CLOCK_SetRootClock(kCLOCK_Root_Flexspi1, &rootCfg); #endif +#if !(DT_NODE_HAS_COMPAT(DT_PARENT(DT_CHOSEN(zephyr_flash)), nxp_imx_flexspi)) && \ + defined(CONFIG_MEMC_MCUX_FLEXSPI) && DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexspi2)) + /* Configure FLEXSPI2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_FLEXSPI2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Flexspi2, &rootCfg); +#endif + /* Keep core clock ungated during WFI */ CCM->GPR_PRIVATE1_SET = 0x1; /* Keep the system clock running so SYSTICK can wake up the system from diff --git a/soc/nxp/imxrt/imxrt11xx/sysbuild.cmake b/soc/nxp/imxrt/imxrt11xx/sysbuild.cmake new file mode 100644 index 0000000000000..23fcbb43ef27d --- /dev/null +++ b/soc/nxp/imxrt/imxrt11xx/sysbuild.cmake @@ -0,0 +1,42 @@ +# Copyright 2024 Daniel DeGrasse +# SPDX-License-Identifier: Apache-2.0 + +# Based on Nordic's implementation of VPR launcher, which is +# Copyright (c) 2024 Nordic Semiconductor ASA + +if(SB_CONFIG_SECOND_CORE_MCUX_LAUNCHER) + # M7 is the boot core, and will start secondary core + set(launcher_core "cm7") + string(REPLACE "/" ";" launcher_quals ${BOARD_QUALIFIERS}) + list(LENGTH launcher_quals launcher_quals_len) + list(GET launcher_quals 1 launcher_soc) + + string(CONCAT launcher_board ${BOARD} "/" ${launcher_soc} "/" ${launcher_core}) + + set(launcher_image "cm4_launcher") + + ExternalZephyrProject_Add( + APPLICATION ${launcher_image} + SOURCE_DIR ${ZEPHYR_BASE}/samples/basic/minimal + BOARD ${launcher_board} + ) + + set(remote_dir "${APPLICATION_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/include/public") + + # Enable CONFIG_SECOND_CORE_MCUX and CONFIG_BUILD_OUTPUT_HEX + # for the application running on the CM4 core + set_config_bool(${DEFAULT_IMAGE} CONFIG_SECOND_CORE_MCUX 1) + set_config_bool(${DEFAULT_IMAGE} CONFIG_BUILD_OUTPUT_HEX 1) + + # Enable CONFIG_SECOND_CORE_MCUX for the image running on the CM7 core + set_config_bool(${launcher_image} CONFIG_SECOND_CORE_MCUX 1) + # Set the initial include path for the image running on the CM7 core to + # include the image header output by the CM4 image + set_config_string(${launcher_image} CONFIG_SECOND_CORE_MCUX_REMOTE_DIR ${remote_dir}) + + # Add dependency on CM4 core image to CM7 image. This way, + # the CM4 image will be built first. This is required because the M7 image + # depends on output headers generated by the M4 image. + add_dependencies(${launcher_image} ${DEFAULT_IMAGE}) + sysbuild_add_dependencies(CONFIGURE ${launcher_image} ${DEFAULT_IMAGE}) +endif() diff --git a/soc/nxp/imxrt/imxrt5xx/Kconfig.defconfig b/soc/nxp/imxrt/imxrt5xx/Kconfig.defconfig index dba7c8831fb75..0f91836ca5258 100644 --- a/soc/nxp/imxrt/imxrt5xx/Kconfig.defconfig +++ b/soc/nxp/imxrt/imxrt5xx/Kconfig.defconfig @@ -20,10 +20,6 @@ config NUM_IRQS config ZTEST_NO_YIELD default y if (PM && ZTEST) -config MBEDTLS - default y if CSPRNG_ENABLED - depends on ENTROPY_GENERATOR - if MBEDTLS # # MBEDTLS CTR_DRBG code path needs extra stack space for initialization than diff --git a/soc/nxp/imxrt/imxrt5xx/cm33/soc.c b/soc/nxp/imxrt/imxrt5xx/cm33/soc.c index b8eeef23a452d..dd95cee362d36 100644 --- a/soc/nxp/imxrt/imxrt5xx/cm33/soc.c +++ b/soc/nxp/imxrt/imxrt5xx/cm33/soc.c @@ -321,6 +321,10 @@ void __weak rt5xx_clock_init(void) /* Switch FLEXCOMM12 to FRG */ CLOCK_AttachClk(kFRG_to_FLEXCOMM12); #endif +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm12), nxp_lpc_spi, okay) + /* Switch FLEXCOMM12 to FRG */ + CLOCK_AttachClk(kFRG_to_FLEXCOMM12); +#endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pmic_i2c), nxp_lpc_i2c, okay) CLOCK_AttachClk(kFRO_DIV4_to_FLEXCOMM15); #endif diff --git a/soc/nxp/imxrt/imxrt5xx/f1/linker.ld b/soc/nxp/imxrt/imxrt5xx/f1/linker.ld index 0a3058b6d9b2d..effbfdc6c56f3 100644 --- a/soc/nxp/imxrt/imxrt5xx/f1/linker.ld +++ b/soc/nxp/imxrt/imxrt5xx/f1/linker.ld @@ -433,6 +433,14 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } .debug_ranges 0 : { *(.debug_ranges) } + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } .xtensa.info 0 : { *(.xtensa.info) } .xt.insn 0 : { diff --git a/soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig b/soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig index f934bd9136376..b36ea66ad6272 100644 --- a/soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig +++ b/soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig @@ -38,10 +38,6 @@ config NUM_IRQS config ZTEST_NO_YIELD default y if (ZTEST && PM) -config MBEDTLS - default y if CSPRNG_ENABLED - depends on ENTROPY_GENERATOR - if MBEDTLS # # MBEDTLS CTR_DRBG code path needs extra stack space for initialization than diff --git a/soc/nxp/imxrt/imxrt6xx/cm33/soc.c b/soc/nxp/imxrt/imxrt6xx/cm33/soc.c index cf5bc6f57b47d..e390528e6abca 100644 --- a/soc/nxp/imxrt/imxrt6xx/cm33/soc.c +++ b/soc/nxp/imxrt/imxrt6xx/cm33/soc.c @@ -181,7 +181,7 @@ static void usb_device_clock_init(void) /** * @brief Initialize the system clock */ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { #ifdef CONFIG_SOC_MIMXRT685S_CM33 /* Configure LPOSC clock*/ diff --git a/soc/nxp/imxrt/imxrt7xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt7xx/CMakeLists.txt new file mode 100644 index 0000000000000..dc36672a9ba2c --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +if(CONFIG_SOC_MIMXRT798S_CM33_CPU0 OR CONFIG_SOC_MIMXRT798S_CM33_CPU1) + add_subdirectory(cm33) +endif() diff --git a/soc/nxp/imxrt/imxrt7xx/Kconfig b/soc/nxp/imxrt/imxrt7xx/Kconfig new file mode 100644 index 0000000000000..a35c2dbd8ee7a --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/Kconfig @@ -0,0 +1,58 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_MIMXRT798S_CM33_CPU0 + select CPU_CORTEX_M33 + select CLOCK_CONTROL + select CPU_CORTEX_M_HAS_DWT + select ARM + select CPU_HAS_ARM_SAU + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU + select ARMV8_M_DSP + select ARM_TRUSTZONE_M + select CPU_CORTEX_M_HAS_SYSTICK + select HAS_MCUX + select HAS_MCUX_SYSCON + select HAS_MCUX_XCACHE + select CACHE_MANAGEMENT + select CPU_HAS_ICACHE + select CPU_HAS_DCACHE + select INIT_ARCH_HW_AT_BOOT + select SOC_RESET_HOOK + select SOC_EARLY_INIT_HOOK + select HAS_MCUX_FLEXCOMM + +config SOC_MIMXRT798S_CM33_CPU1 + select CPU_CORTEX_M33 + select CLOCK_CONTROL + select CPU_CORTEX_M_HAS_DWT + select ARM + select CPU_HAS_ARM_SAU + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU + select ARMV8_M_DSP + select ARM_TRUSTZONE_M + select CPU_CORTEX_M_HAS_SYSTICK + select HAS_MCUX + select HAS_MCUX_SYSCON + select HAS_MCUX_FLEXCOMM + +if SOC_SERIES_IMXRT7XX + +if NXP_IMXRT_BOOT_HEADER + +config IMAGE_VECTOR_TABLE_OFFSET + default 0x4000 + +endif # NXP_IMXRT_BOOT_HEADER + +config GLIKEY_MCUX_GLIKEY + default y + bool "Use glikey MCUX Driver" + +config MCUX_CORE_SUFFIX + default "_cm33_core0" if SOC_MIMXRT798S_CM33_CPU0 + default "_cm33_core1" if SOC_MIMXRT798S_CM33_CPU1 + +endif # SOC_SERIES_IMXRT7XX diff --git a/soc/nxp/imxrt/imxrt7xx/Kconfig.defconfig b/soc/nxp/imxrt/imxrt7xx/Kconfig.defconfig new file mode 100644 index 0000000000000..2b7904f630f28 --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/Kconfig.defconfig @@ -0,0 +1,35 @@ +# Copyright 2024-2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_MIMXRT798S_CM33_CPU0 + +config ROM_START_OFFSET + default 0x4000 if NXP_IMXRT_BOOT_HEADER + +config NUM_IRQS + default 158 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 237500000 if CORTEX_M_SYSTICK + default 1000000 if MCUX_OS_TIMER + +choice CACHE_TYPE + default EXTERNAL_CACHE +endchoice + +endif # SOC_MIMXRT798S_CM33_CPU0 + +if SOC_MIMXRT798S_CM33_CPU1 + +config NUM_IRQS + default 93 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 100000000 if CORTEX_M_SYSTICK + default 1000000 if MCUX_OS_TIMER + +endif # SOC_MIMXRT798S_CM33_CPU1 + +config MFD + default y + depends on DT_HAS_NXP_LP_FLEXCOMM_ENABLED diff --git a/soc/nxp/imxrt/imxrt7xx/Kconfig.soc b/soc/nxp/imxrt/imxrt7xx/Kconfig.soc new file mode 100644 index 0000000000000..5e321bdc9bb26 --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/Kconfig.soc @@ -0,0 +1,50 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_IMXRT7XX + bool + select SOC_FAMILY_NXP_IMXRT + +config SOC_MIMXRT798S + bool + select SOC_SERIES_IMXRT7XX + +config SOC_MIMXRT798S_CM33_CPU0 + bool + select SOC_MIMXRT798S + +config SOC_MIMXRT798S_CM33_CPU1 + bool + select SOC_MIMXRT798S + +config SOC_SERIES + default "imxrt7xx" if SOC_SERIES_IMXRT7XX + +config SOC + default "mimxrt798s" if SOC_MIMXRT798S + +config SOC_PART_NUMBER_MIMXRT798SGAWAR + bool + +config SOC_PART_NUMBER_MIMXRT798SGFOA + bool + +config SOC_PART_NUMBER_MIMXRT758SGAWAR + bool + +config SOC_PART_NUMBER_MIMXRT758SGFOA + bool + +config SOC_PART_NUMBER_MIMXRT735SGAWAR + bool + +config SOC_PART_NUMBER_MIMXRT735SGFOA + bool + +config SOC_PART_NUMBER + default "MIMXRT798SGFOA" if SOC_PART_NUMBER_MIMXRT798SGFOA + default "MIMXRT798SGAWAR" if SOC_PART_NUMBER_MIMXRT798SGAWAR + default "MIMXRT758SGFOA" if SOC_PART_NUMBER_MIMXRT758SGFOA + default "MIMXRT758SGAWAR" if SOC_PART_NUMBER_MIMXRT758SGAWAR + default "MIMXRT735SGFOA" if SOC_PART_NUMBER_MIMXRT735SGFOA + default "MIMXRT735SGAWAR" if SOC_PART_NUMBER_MIMXRT735SGAWAR diff --git a/soc/nxp/imxrt/imxrt7xx/cm33/CMakeLists.txt b/soc/nxp/imxrt/imxrt7xx/cm33/CMakeLists.txt new file mode 100644 index 0000000000000..cd9319bffaaf4 --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/cm33/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_compile_definitions_ifdef(CONFIG_NXP_LP_FLEXCOMM LPFLEXCOMM_INIT_NOT_USED_IN_DRIVER=1) + +zephyr_compile_definitions(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) + +zephyr_include_directories(.) + +zephyr_sources(soc.c) + +if(CONFIG_FLASH_MCUX_XSPI_XIP) + zephyr_sources(flash_clock_setup.c) + zephyr_code_relocate(FILES flash_clock_setup.c LOCATION ${CONFIG_FLASH_MCUX_XSPI_XIP_MEM}_TEXT) +endif() + +zephyr_library_include_directories( + ${ZEPHYR_BASE}/kernel/include + ${ZEPHYR_BASE}/arch/${ARCH}/include + ) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/imxrt/imxrt7xx/cm33/flash_clock_setup.c b/soc/nxp/imxrt/imxrt7xx/cm33/flash_clock_setup.c new file mode 100644 index 0000000000000..9994fc3885f29 --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/cm33/flash_clock_setup.c @@ -0,0 +1,168 @@ +/* + * Copyright 2024 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifdef CONFIG_HAS_MCUX_CACHE +#include +#endif + +static void enable_xspi_cache(CACHE64_CTRL_Type *cache) +{ + /* First, invalidate the entire cache. */ + cache->CCR |= CACHE64_CTRL_CCR_INVW0_MASK | CACHE64_CTRL_CCR_INVW1_MASK | + CACHE64_CTRL_CCR_GO_MASK; + while ((cache->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0x00U) { + } + /* As a precaution clear the bits to avoid inadvertently re-running this command. */ + cache->CCR &= ~(CACHE64_CTRL_CCR_INVW0_MASK | CACHE64_CTRL_CCR_INVW1_MASK); + /* Now enable the cache. */ + cache->CCR |= CACHE64_CTRL_CCR_ENCACHE_MASK; +} + +static void disable_xspi_cache(CACHE64_CTRL_Type *cache) +{ + cache->CCR |= CACHE64_CTRL_CCR_PUSHW0_MASK | CACHE64_CTRL_CCR_PUSHW1_MASK | + CACHE64_CTRL_CCR_GO_MASK; /* First, clean XSPI cache. */ + while ((cache->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0x00U) { + } + /* As a precaution clear the bits to avoid inadvertently re-running this command. */ + cache->CCR &= ~(CACHE64_CTRL_CCR_PUSHW0_MASK | CACHE64_CTRL_CCR_PUSHW1_MASK); + + /* Now disable XSPI cache. */ + cache->CCR &= ~CACHE64_CTRL_CCR_ENCACHE_MASK; +} + +static void flash_deinit(XSPI_Type *base, CACHE64_CTRL_Type *cache) +{ + if (base == XSPI0) { + /* Enable clock again. */ + CLKCTL0->PSCCTL1_SET = CLKCTL0_PSCCTL1_CLR_XSPI0_MASK; + } else if (base == XSPI1) { + /* Enable clock again. */ + CLKCTL0->PSCCTL1_SET = CLKCTL0_PSCCTL1_CLR_XSPI1_MASK; + } + + base->MCR &= ~XSPI_MCR_MDIS_MASK; + if ((cache->CCR & CACHE64_CTRL_CCR_ENCACHE_MASK) != 0x00U) { + disable_xspi_cache(cache); + } + /* Wait until XSPI is not busy */ + while ((base->SR & XSPI_SR_BUSY_MASK) != 0U) { + } + /* Disable module. */ + base->MCR |= XSPI_MCR_MDIS_MASK; +} + +static void flash_init(XSPI_Type *base, CACHE64_CTRL_Type *cache) +{ + /* Enable XSPI module */ + base->MCR |= XSPI_MCR_MDIS_MASK; + + base->MCR |= XSPI_MCR_SWRSTSD_MASK | XSPI_MCR_SWRSTHD_MASK; + for (uint32_t i = 0; i < 6; i++) { + __NOP(); + } + base->MCR &= ~(XSPI_MCR_SWRSTSD_MASK | XSPI_MCR_SWRSTHD_MASK); + base->MCR |= XSPI_MCR_IPS_TG_RST_MASK | XSPI_MCR_MDIS_MASK; + base->MCR &= ~XSPI_MCR_ISD3FA_MASK; + base->MCR &= ~XSPI_MCR_MDIS_MASK; + base->MCR |= XSPI_MCR_MDIS_MASK; + base->MCR |= XSPI_MCR_ISD3FA_MASK; + base->MCR &= ~XSPI_MCR_MDIS_MASK; + + base->MCR |= XSPI_MCR_MDIS_MASK; + base->SMPR = (((base->SMPR) & (~XSPI_SMPR_DLLFSMPFA_MASK)) | + XSPI_SMPR_DLLFSMPFA(FSL_FEATURE_XSPI_DLL_REF_VALUE_DDR_DELAY_TAP_NUM)); + base->MCR &= ~XSPI_MCR_MDIS_MASK; + + base->DLLCR[0] &= + ~(XSPI_DLLCR_SLV_DLL_BYPASS_MASK | XSPI_DLLCR_DLL_CDL8_MASK | + XSPI_DLLCR_SLV_DLY_OFFSET_MASK | XSPI_DLLCR_SLV_FINE_OFFSET_MASK | + XSPI_DLLCR_DLLRES_MASK | XSPI_DLLCR_DLL_REFCNTR_MASK | XSPI_DLLCR_FREQEN_MASK); + base->DLLCR[0] &= + ~(XSPI_DLLCR_SLV_EN_MASK | XSPI_DLLCR_SLAVE_AUTO_UPDT_MASK | XSPI_DLLCR_DLLEN_MASK); + /* Enable subordinate as auto update mode. */ + base->DLLCR[0] |= XSPI_DLLCR_SLV_EN_MASK | XSPI_DLLCR_SLAVE_AUTO_UPDT_MASK; + /* program DLL to desired delay. */ + base->DLLCR[0] |= + XSPI_DLLCR_DLLRES(FSL_FEATURE_XSPI_DLL_REF_VALUE_AUTOUPDATE_X16_DISABLE_RES) | + XSPI_DLLCR_DLL_REFCNTR( + FSL_FEATURE_XSPI_DLL_REF_VALUE_AUTOUPDATE_X16_DISABLED_REF_COUNTER) | + XSPI_DLLCR_SLV_FINE_OFFSET(0) | XSPI_DLLCR_SLV_DLY_OFFSET(0) | + XSPI_DLLCR_FREQEN(1U); + /* Load above settings into delay chain. */ + base->DLLCR[0] |= XSPI_DLLCR_SLV_UPD_MASK; + base->DLLCR[0] |= XSPI_DLLCR_DLLEN_MASK; + base->DLLCR[0] &= ~XSPI_DLLCR_SLV_UPD_MASK; + + while ((base->DLLSR & XSPI_DLLSR_SLVA_LOCK_MASK) == 0UL) { + } + + if ((cache->CCR & CACHE64_CTRL_CCR_ENCACHE_MASK) == 0x00U) { + enable_xspi_cache(cache); + /* flush pipeline */ + __DSB(); + __ISB(); + } +} + +/* xspi_setup_clock run in RAM when XIP. */ +void xspi_setup_clock(XSPI_Type *base, uint32_t src, uint32_t divider) +{ + if (base == XSPI0) { + if ((CLKCTL0->XSPI0FCLKSEL != CLKCTL0_XSPI0FCLKSEL_SEL(src)) || + ((CLKCTL0->XSPI0FCLKDIV & CLKCTL0_XSPI0FCLKDIV_DIV_MASK) != (divider - 1))) { + /* Always deinit XSPI and init XSPI for the flash to make + * sure the flash works correctly after the XSPI root clock + * changed as the default XSPI configuration may does not + * work for the new root clock frequency. + */ + flash_deinit(base, CACHE64_CTRL0); + + /* Disable clock before changing clock source */ + CLKCTL0->PSCCTL1_CLR = CLKCTL0_PSCCTL1_CLR_XSPI0_MASK; + /* Update XSPI clock. */ + CLKCTL0->XSPI0FCLKSEL = + CLKCTL0_XSPI0FCLKSEL_SEL(src) | CLKCTL0_XSPI0FCLKSEL_SEL_EN_MASK; + CLKCTL0->XSPI0FCLKDIV = CLKCTL0_XSPI0FCLKDIV_DIV(divider - 1); + while ((CLKCTL0->XSPI0FCLKDIV) & CLKCTL0_XSPI0FCLKDIV_REQFLAG_MASK) { + } + /* Enable XSPI clock again */ + CLKCTL0->PSCCTL1_SET = CLKCTL0_PSCCTL1_SET_XSPI0_MASK; + + flash_init(base, CACHE64_CTRL0); + } + } else if (base == XSPI1) { + if ((CLKCTL0->XSPI1FCLKSEL != CLKCTL0_XSPI1FCLKSEL_SEL(src)) || + ((CLKCTL0->XSPI1FCLKDIV & CLKCTL0_XSPI1FCLKDIV_DIV_MASK) != (divider - 1))) { + /* Always deinit XSPI and init XSPI for the flash to make sure the flash + * works correctly after the XSPI root clock changed as the default XSPI + * configuration may does not work for the new root clock frequency. + */ + flash_deinit(base, CACHE64_CTRL1); + + /* Disable clock before changing clock source */ + CLKCTL0->PSCCTL1_CLR = CLKCTL0_PSCCTL1_CLR_XSPI1_MASK; + /* Update XSPI clock. */ + CLKCTL0->XSPI1FCLKSEL = + CLKCTL0_XSPI1FCLKSEL_SEL(src) | CLKCTL0_XSPI1FCLKSEL_SEL_EN_MASK; + CLKCTL0->XSPI1FCLKDIV = CLKCTL0_XSPI1FCLKDIV_DIV(divider - 1); + while ((CLKCTL0->XSPI1FCLKDIV) & CLKCTL0_XSPI1FCLKDIV_REQFLAG_MASK) { + } + /* Enable XSPI clock again */ + CLKCTL0->PSCCTL1_SET = CLKCTL0_PSCCTL1_SET_XSPI1_MASK; + + flash_init(base, CACHE64_CTRL1); + } + } +} + +void xspi_clock_safe_config(void) +{ + xspi_setup_clock(XSPI0, 0U, 1U); + xspi_setup_clock(XSPI1, 0U, 1U); +} diff --git a/soc/nxp/imxrt/imxrt7xx/cm33/pinctrl_soc.h b/soc/nxp/imxrt/imxrt7xx/cm33/pinctrl_soc.h new file mode 100644 index 0000000000000..35f048dd0e602 --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/cm33/pinctrl_soc.h @@ -0,0 +1,87 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_NXP_IMX_RT7XX_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_NXP_IMX_RT7XX_PINCTRL_SOC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +typedef uint32_t pinctrl_soc_pin_t; + +#define IOPCTL_PIO_PUPDENA_MASK (0x10U) +#define IOPCTL_PIO_PUPDSEL_MASK (0x20U) + +#define IOPCTL_PIO_ODENA_MASK (0x400U) +#define IOPCTL_PIO_ODENA_SHIFT (10U) +#define IOPCTL_PIO_ODENA(x) \ + (((uint32_t)(((uint32_t)(x)) << IOPCTL_PIO_ODENA_SHIFT)) & IOPCTL_PIO_ODENA_MASK) + +#define IOPCTL_PIO_IBENA_MASK (0x40U) +#define IOPCTL_PIO_IBENA_SHIFT (6U) +#define IOPCTL_PIO_IBENA(x) \ + (((uint32_t)(((uint32_t)(x)) << IOPCTL_PIO_IBENA_SHIFT)) & IOPCTL_PIO_IBENA_MASK) + +/* Please note there is no SLEWRATE attribution on IOPCTL2 */ +#define IOPCTL_PIO_SLEWRATE_MASK (0x80U) +#define IOPCTL_PIO_SLEWRATE_SHIFT (7U) +#define IOPCTL_PIO_SLEWRATE(x) \ + (((uint32_t)(((uint32_t)(x)) << IOPCTL_PIO_SLEWRATE_SHIFT)) & IOPCTL_PIO_SLEWRATE_MASK) + +/* Please note there is no FULLDRIVE attribution on IOPCTL2 */ +#define IOPCTL_PIO_FULLDRIVE_MASK (0x100U) +#define IOPCTL_PIO_FULLDRIVE_SHIFT (8U) +#define IOPCTL_PIO_FULLDRIVE(x) \ + (((uint32_t)(((uint32_t)(x)) << IOPCTL_PIO_FULLDRIVE_SHIFT)) & IOPCTL_PIO_FULLDRIVE_MASK) + +#define IOPCTL_PIO_IIENA_MASK (0x800U) +#define IOPCTL_PIO_IIENA_SHIFT (11U) +#define IOPCTL_PIO_IIENA(x) \ + (((uint32_t)(((uint32_t)(x)) << IOPCTL_PIO_IIENA_SHIFT)) & IOPCTL1_PIO_IIENA_MASK) + +/* Please note there is no AMENA attribution on IOPCTL2 */ +#define IOPCTL_PIO_AMENA_MASK (0x200U) +#define IOPCTL_PIO_AMENA_SHIFT (9U) +#define IOPCTL_PIO_AMENA(x) \ + (((uint32_t)(((uint32_t)(x)) << IOPCTL_PIO_AMENA_SHIFT)) & IOPCTL_PIO_AMENA_MASK) + +#define Z_PINCTRL_IOPCTL_PINCFG(node_id) \ + (IF_ENABLED(DT_PROP(node_id, bias_pull_down), \ + (IOPCTL_PIO_PUPDENA_MASK |)) /* pull down */ \ + IF_ENABLED(DT_PROP(node_id, bias_pull_up), \ + (IOPCTL_PIO_PUPDENA_MASK | IOPCTL_PIO_PUPDSEL_MASK |)) /* pull up */ \ + IOPCTL_PIO_ODENA(DT_PROP(node_id, drive_open_drain)) | /* open drain */ \ + IOPCTL_PIO_IBENA(DT_PROP(node_id, input_enable)) | /* input buffer */ \ + IOPCTL_PIO_SLEWRATE(DT_ENUM_IDX(node_id, slew_rate)) | /* slew rate */ \ + IOPCTL_PIO_FULLDRIVE( \ + DT_ENUM_IDX(node_id, drive_strength)) | /* drive strength */ \ + IOPCTL_PIO_IIENA(DT_PROP(node_id, nxp_invert)) | /* invert input */ \ + IOPCTL_PIO_AMENA( \ + DT_PROP(node_id, nxp_analog_mode))) /* analog multiplexor */ + +/* MCUX RT parts only have one pin type */ +#define Z_PINCTRL_IOCON_D_PIN_MASK (0xFFF) +#define Z_PINCTRL_IOCON_A_PIN_MASK (0) +#define Z_PINCTRL_IOCON_I_PIN_MASK (0) + +#define Z_PINCTRL_STATE_PIN_INIT(group, pin_prop, idx) \ + DT_PROP_BY_IDX(group, pin_prop, idx) | Z_PINCTRL_IOPCTL_PINCFG(group), + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_NXP_IMX_RT7XX_PINCTRL_SOC_H_ */ diff --git a/soc/nxp/imxrt/imxrt7xx/cm33/soc.c b/soc/nxp/imxrt/imxrt7xx/cm33/soc.c new file mode 100644 index 0000000000000..5b88ac716445e --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/cm33/soc.c @@ -0,0 +1,37 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for NXP RT7XX platform + * + * This module provides routines to initialize and support board-level + * hardware for the RT7XX platforms. + */ + +#include +#include +#include +#include +#include + +void soc_early_init_hook(void) +{ + /* Enable data cache */ + sys_cache_data_enable(); + + __ISB(); + __DSB(); +} + +#ifdef CONFIG_SOC_RESET_HOOK + +void soc_reset_hook(void) +{ + SystemInit(); +} + +#endif /* CONFIG_SOC_RESET_HOOK */ diff --git a/soc/nxp/imxrt/imxrt7xx/cm33/soc.h b/soc/nxp/imxrt/imxrt7xx/cm33/soc.h new file mode 100644 index 0000000000000..92b4e3dd9795b --- /dev/null +++ b/soc/nxp/imxrt/imxrt7xx/cm33/soc.h @@ -0,0 +1,42 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Board configuration macros for the MIMXRT7XX platform + * + * This header file is used to specify and describe board-level aspects for the + * 'MIMXRT7XX' platform. + */ + +#ifndef _SOC__H_ +#define _SOC__H_ + +#ifndef _ASMLANGUAGE + +#include +#include + +/* CPU 0 has an instruction and data cache, provide the defines for XCACHE */ +#ifdef CONFIG_SOC_MIMXRT798S_CM33_CPU0 +#define NXP_XCACHE_INSTR XCACHE1 +#define NXP_XCACHE_DATA XCACHE0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void xspi_clock_safe_config(void); +void xspi_setup_clock(XSPI_Type *base, uint32_t src, uint32_t divider); + +#ifdef __cplusplus +} +#endif + +#endif /* !_ASMLANGUAGE */ + +#endif /* _SOC__H_ */ diff --git a/soc/nxp/imxrt/soc.yml b/soc/nxp/imxrt/soc.yml index 2fd2a0df226d3..75ca12e72f76c 100644 --- a/soc/nxp/imxrt/soc.yml +++ b/soc/nxp/imxrt/soc.yml @@ -38,6 +38,12 @@ family: - name: mimxrt685s cpuclusters: - name: cm33 + - name: imxrt7xx + socs: + - name: mimxrt798s + cpuclusters: + - name: cm33_cpu0 + - name: cm33_cpu1 runners: run_once: '--erase': @@ -53,6 +59,9 @@ runners: - qualifiers: - mimxrt1176/cm7 - mimxrt1176/cm4 + - qualifiers: + - mimxrt1189/cm33 + - mimxrt1189/cm7 - qualifiers: - mimxrt595s/cm33 - mimxrt595s/f1 @@ -71,6 +80,9 @@ runners: - qualifiers: - mimxrt1176/cm7 - mimxrt1176/cm4 + - qualifiers: + - mimxrt1189/cm33 + - mimxrt1189/cm7 - qualifiers: - mimxrt595s/cm33 - mimxrt595s/f1 diff --git a/soc/nxp/imxrt/sysbuild.cmake b/soc/nxp/imxrt/sysbuild.cmake new file mode 100644 index 0000000000000..9babc6d592b9e --- /dev/null +++ b/soc/nxp/imxrt/sysbuild.cmake @@ -0,0 +1,7 @@ +# Copyright 2024 Daniel DeGrasse +# SPDX-License-Identifier: Apache-2.0 + +if(SB_CONFIG_SOC_SERIES_IMXRT11XX) + # Include RT11XX specific sysbuild + include(${SOC_${SB_CONFIG_SOC}_DIR}/imxrt11xx/sysbuild.cmake OPTIONAL) +endif() diff --git a/soc/nxp/kinetis/k2x/CMakeLists.txt b/soc/nxp/kinetis/k2x/CMakeLists.txt index 915f002e0eda7..29354d5bca3e9 100644 --- a/soc/nxp/kinetis/k2x/CMakeLists.txt +++ b/soc/nxp/kinetis/k2x/CMakeLists.txt @@ -9,7 +9,7 @@ zephyr_sources( soc.c ) -if(DEFINED CONFIG_ARM_MPU AND DEFINED CONFIG_CPU_HAS_NXP_MPU) +if(DEFINED CONFIG_ARM_MPU AND DEFINED CONFIG_CPU_HAS_NXP_SYSMPU) # MK22F12 series MCUs have NXP MPU zephyr_sources(nxp_mpu_regions.c) endif() diff --git a/soc/nxp/kinetis/k2x/Kconfig b/soc/nxp/kinetis/k2x/Kconfig index f89d6c86b4cf9..d287d387e1dde 100644 --- a/soc/nxp/kinetis/k2x/Kconfig +++ b/soc/nxp/kinetis/k2x/Kconfig @@ -45,4 +45,4 @@ config SOC_MK22F12 select CPU_HAS_FPU select HAS_MCUX_DAC select HAS_MCUX_RCM - select CPU_HAS_NXP_MPU + select CPU_HAS_NXP_SYSMPU diff --git a/soc/nxp/kinetis/k2x/soc.c b/soc/nxp/kinetis/k2x/soc.c index e89526f555685..069e5a862412d 100644 --- a/soc/nxp/kinetis/k2x/soc.c +++ b/soc/nxp/kinetis/k2x/soc.c @@ -84,7 +84,7 @@ static const sim_clock_config_t simConfig = { * clock. * */ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { CLOCK_SetSimSafeDivs(); diff --git a/soc/nxp/kinetis/k6x/Kconfig b/soc/nxp/kinetis/k6x/Kconfig index af342ae30caf0..936f980e51389 100644 --- a/soc/nxp/kinetis/k6x/Kconfig +++ b/soc/nxp/kinetis/k6x/Kconfig @@ -7,7 +7,7 @@ config SOC_SERIES_KINETIS_K6X select ARM select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT - select CPU_HAS_NXP_MPU + select CPU_HAS_NXP_SYSMPU select HAS_MCUX_PIT select CLOCK_CONTROL select SOC_RESET_HOOK diff --git a/soc/nxp/kinetis/k6x/soc.c b/soc/nxp/kinetis/k6x/soc.c index 32832dc8a0a28..7f95d7d8f1cfc 100644 --- a/soc/nxp/kinetis/k6x/soc.c +++ b/soc/nxp/kinetis/k6x/soc.c @@ -87,7 +87,7 @@ static const sim_clock_config_t simConfig = { * clock. * */ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { CLOCK_SetSimSafeDivs(); diff --git a/soc/nxp/kinetis/k8x/Kconfig b/soc/nxp/kinetis/k8x/Kconfig index bf30d20797e9c..8007315e1ce2b 100644 --- a/soc/nxp/kinetis/k8x/Kconfig +++ b/soc/nxp/kinetis/k8x/Kconfig @@ -8,7 +8,7 @@ config SOC_SERIES_KINETIS_K8X select ARM select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT - select CPU_HAS_NXP_MPU + select CPU_HAS_NXP_SYSMPU select CPU_HAS_FPU select CLOCK_CONTROL select HAS_MCUX diff --git a/soc/nxp/kinetis/k8x/soc.c b/soc/nxp/kinetis/k8x/soc.c index d338ad72a967c..df5061cbcb8d4 100644 --- a/soc/nxp/kinetis/k8x/soc.c +++ b/soc/nxp/kinetis/k8x/soc.c @@ -69,7 +69,7 @@ static const sim_clock_config_t sim_config = { .pllFllFrac = (0), }; -static ALWAYS_INLINE void clk_init(void) +__weak void clk_init(void) { CLOCK_SetSimSafeDivs(); diff --git a/soc/nxp/kinetis/ke1xf/Kconfig b/soc/nxp/kinetis/ke1xf/Kconfig index b3cf86dd9356b..c4967cb09905e 100644 --- a/soc/nxp/kinetis/ke1xf/Kconfig +++ b/soc/nxp/kinetis/ke1xf/Kconfig @@ -8,7 +8,7 @@ config SOC_SERIES_KINETIS_KE1XF select ARM select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT - select CPU_HAS_NXP_MPU + select CPU_HAS_NXP_SYSMPU select CPU_HAS_FPU select CLOCK_CONTROL select HAS_MCUX diff --git a/soc/nxp/kinetis/ke1xf/soc.c b/soc/nxp/kinetis/ke1xf/soc.c index 35968f6acf0f5..899d28984ade0 100644 --- a/soc/nxp/kinetis/ke1xf/soc.c +++ b/soc/nxp/kinetis/ke1xf/soc.c @@ -145,7 +145,7 @@ static const scg_spll_config_t scg_spll_config = { .mult = (SCG_CLOCK_MULT(pll) - 16U) }; -static ALWAYS_INLINE void clk_init(void) +__weak void clk_init(void) { const scg_sys_clk_config_t scg_sys_clk_config_safe = { .divSlow = kSCG_SysClkDivBy4, diff --git a/soc/nxp/kinetis/ke1xz/soc.c b/soc/nxp/kinetis/ke1xz/soc.c index 0f8ad0de6acaa..d3b8e156dd4cd 100644 --- a/soc/nxp/kinetis/ke1xz/soc.c +++ b/soc/nxp/kinetis/ke1xz/soc.c @@ -81,7 +81,7 @@ static const scg_firc_config_t scg_firc_config = { .trimConfig = NULL }; -static ALWAYS_INLINE void clk_init(void) +__weak void clk_init(void) { const scg_sys_clk_config_t scg_sys_clk_config_safe = { .divSlow = kSCG_SysClkDivBy4, diff --git a/soc/nxp/kinetis/kl2x/soc.c b/soc/nxp/kinetis/kl2x/soc.c index 8ab125d4c7ce4..359b32bd6cb61 100644 --- a/soc/nxp/kinetis/kl2x/soc.c +++ b/soc/nxp/kinetis/kl2x/soc.c @@ -24,7 +24,7 @@ * Variables ******************************************************************************/ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { /* * Core clock: 48MHz diff --git a/soc/nxp/kinetis/kv5x/soc.c b/soc/nxp/kinetis/kv5x/soc.c index cd5d4048c42c7..f4d7958c2c992 100644 --- a/soc/nxp/kinetis/kv5x/soc.c +++ b/soc/nxp/kinetis/kv5x/soc.c @@ -63,7 +63,7 @@ static const sim_clock_config_t sim_config = { SIM_CLKDIV1_OUTDIV4(CLOCK_DIVIDER(flash_clk)), }; -static ALWAYS_INLINE void clk_init(void) +__weak void clk_init(void) { CLOCK_SetSimSafeDivs(); diff --git a/soc/nxp/kinetis/kwx/soc_kw2xd.c b/soc/nxp/kinetis/kwx/soc_kw2xd.c index c2fcddfa6ed06..a94217fa0cb66 100644 --- a/soc/nxp/kinetis/kwx/soc_kw2xd.c +++ b/soc/nxp/kinetis/kwx/soc_kw2xd.c @@ -117,7 +117,7 @@ static void set_modem_clock(void) * clock. * */ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { CLOCK_SetSimSafeDivs(); diff --git a/soc/nxp/kinetis/kwx/soc_kw4xz.c b/soc/nxp/kinetis/kwx/soc_kw4xz.c index f6baedb07b76f..c730dac498eba 100644 --- a/soc/nxp/kinetis/kwx/soc_kw4xz.c +++ b/soc/nxp/kinetis/kwx/soc_kw4xz.c @@ -52,7 +52,7 @@ static void CLOCK_SYS_FllStableDelay(void) } } -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { CLOCK_SetSimSafeDivs(); diff --git a/soc/nxp/lpc/lpc54xxx/soc.c b/soc/nxp/lpc/lpc54xxx/soc.c index a18e6e300c7a7..14f6cd31d0bdb 100644 --- a/soc/nxp/lpc/lpc54xxx/soc.c +++ b/soc/nxp/lpc/lpc54xxx/soc.c @@ -46,7 +46,7 @@ */ #define CPU_FREQ DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { #ifdef CONFIG_SOC_LPC54114_M4 diff --git a/soc/nxp/lpc/lpc55xxx/soc.c b/soc/nxp/lpc/lpc55xxx/soc.c index 7b7332d0b61bc..47adb934616b0 100644 --- a/soc/nxp/lpc/lpc55xxx/soc.c +++ b/soc/nxp/lpc/lpc55xxx/soc.c @@ -78,7 +78,7 @@ const pll_setup_t pll1Setup = { * */ -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { ExternalClockFrequency = 0; diff --git a/soc/nxp/mcx/mcxa/Kconfig.defconfig b/soc/nxp/mcx/mcxa/Kconfig.defconfig index 0dfa047ab5456..11195acc0d7b3 100644 --- a/soc/nxp/mcx/mcxa/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxa/Kconfig.defconfig @@ -9,7 +9,7 @@ config NUM_IRQS config SYS_CLOCK_HW_CYCLES_PER_SEC default 1000000 if MCUX_OS_TIMER default 16000 if MCUX_LPTMR_TIMER - default 150000000 if CORTEX_M_SYSTICK + default 96000000 if CORTEX_M_SYSTICK # Set to the minimal size of data which can be written. config FLASH_FILL_BUFFER_SIZE diff --git a/soc/nxp/mcx/mcxc/flash_configuration.c b/soc/nxp/mcx/mcxc/flash_configuration.c index d53c6df5bf5ea..444ade974d65f 100644 --- a/soc/nxp/mcx/mcxc/flash_configuration.c +++ b/soc/nxp/mcx/mcxc/flash_configuration.c @@ -29,7 +29,7 @@ uint8_t __kinetis_flash_config_section __kinetis_flash_config[] = { /* Flash security register (FSEC) enables/disables backdoor key access, * mass erase, factory access, and flash security */ - DT_PROP_OR(DT_NODELABEL(ftfa), fsec, 0xFF), + DT_PROP_OR(DT_NODELABEL(ftfa), fsec, 0xFE), /* Flash nonvolatile option register (FOPT) enables/disables NMI, * EzPort, and boot options diff --git a/soc/nxp/mcx/mcxc/soc.c b/soc/nxp/mcx/mcxc/soc.c index 4b9c58a88785d..0f254bb0068fc 100644 --- a/soc/nxp/mcx/mcxc/soc.c +++ b/soc/nxp/mcx/mcxc/soc.c @@ -83,7 +83,7 @@ const osc_config_t oscConfig_BOARD_BootClockRUN = { } }; -static void clock_init(void) +__weak void clock_init(void) { /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); @@ -96,10 +96,14 @@ static void clock_init(void) CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); /* Set SystemCoreClock variable. */ SystemCoreClock = DT_PROP(DT_NODELABEL(cpu0), clock_frequency); - /* Set LPUART0 clock source. */ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart0)) + /* Set LPUART0 clock source. */ CLOCK_SetLpuart0Clock(LPUART_CLOCK_SEL(lpuart0)); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart1)) + /* Set LPUART1 clock source. */ + CLOCK_SetLpuart1Clock(LPUART_CLOCK_SEL(lpuart1)); +#endif #if DT_HAS_COMPAT_STATUS_OKAY(nxp_kinetis_tpm) /* All TPM instances share common clock source for counter clock. * Select the clock source using an arbitrary enabled TPM node. diff --git a/soc/nxp/mcx/mcxn/Kconfig b/soc/nxp/mcx/mcxn/Kconfig index c4be2c40554f4..16b7ef6009b2c 100644 --- a/soc/nxp/mcx/mcxn/Kconfig +++ b/soc/nxp/mcx/mcxn/Kconfig @@ -9,7 +9,6 @@ config SOC_SERIES_MCXN select HAS_MCUX_FLEXCOMM select CPU_CORTEX_M_HAS_SYSTICK select CPU_CORTEX_M_HAS_DWT - select SOC_RESET_HOOK config SOC_MCXN947_CPU0 select CPU_CORTEX_M33 @@ -17,15 +16,20 @@ config SOC_MCXN947_CPU0 select CPU_HAS_ARM_MPU select CPU_HAS_FPU select ARMV8_M_DSP + select SOC_RESET_HOOK select ARM_TRUSTZONE_M select HAS_MCUX_CACHE +config SOC_MCXN947_CPU1 + select CPU_CORTEX_M33 + config SOC_MCXN236 select CPU_CORTEX_M33 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU select CPU_HAS_FPU select ARMV8_M_DSP + select SOC_RESET_HOOK select ARM_TRUSTZONE_M if SOC_SERIES_MCXN diff --git a/soc/nxp/mcx/mcxn/Kconfig.defconfig b/soc/nxp/mcx/mcxn/Kconfig.defconfig index ada924c897c48..1668cfad798a7 100644 --- a/soc/nxp/mcx/mcxn/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxn/Kconfig.defconfig @@ -27,4 +27,9 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config FLASH_FILL_BUFFER_SIZE default 128 +# The existing SAI diver cannot initialize the PLL on the board, +# so the PLL settings will not be performed in the driver. +config I2S_HAS_PLL_SETTING + default n + endif # SOC_SERIES_MCXN diff --git a/soc/nxp/mcx/mcxn/soc.c b/soc/nxp/mcx/mcxn/soc.c index cbeb7f17f7f2e..ce7ae3649093a 100644 --- a/soc/nxp/mcx/mcxn/soc.c +++ b/soc/nxp/mcx/mcxn/soc.c @@ -27,7 +27,7 @@ void soc_reset_hook(void) #endif #define FLEXCOMM_CHECK_2(n) \ - BUILD_ASSERT((DT_NODE_HAS_COMPAT(n, nxp_kinetis_lpuart) == 0) && \ + BUILD_ASSERT((DT_NODE_HAS_COMPAT(n, nxp_lpuart) == 0) && \ (DT_NODE_HAS_COMPAT(n, nxp_lpi2c) == 0), \ "Do not enable SPI and UART/I2C on the same Flexcomm node"); @@ -38,3 +38,24 @@ void soc_reset_hook(void) * Throw a build error if user is enabling SPI and UART/I2C on a Flexcomm node. */ DT_FOREACH_STATUS_OKAY(nxp_lpspi, FLEXCOMM_CHECK) + +#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_SOC_MCXN947_CPU0) + +/* This function is also called at deep sleep resume. */ +static int second_core_boot(void) +{ + /* Boot source for Core 1 from flash */ + SYSCON->CPBOOT = ((uint32_t)(char *)DT_REG_ADDR(DT_CHOSEN(zephyr_code_cpu1_partition)) & + SYSCON_CPBOOT_CPBOOT_MASK); + + uint32_t temp = SYSCON->CPUCTRL; + + temp |= 0xc0c40000U; + SYSCON->CPUCTRL = temp | SYSCON_CPUCTRL_CPU1RSTEN_MASK | SYSCON_CPUCTRL_CPU1CLKEN_MASK; + SYSCON->CPUCTRL = (temp | SYSCON_CPUCTRL_CPU1CLKEN_MASK) & (~SYSCON_CPUCTRL_CPU1RSTEN_MASK); + + return 0; +} + +SYS_INIT(second_core_boot, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +#endif diff --git a/soc/nxp/mcx/mcxw/CMakeLists.txt b/soc/nxp/mcx/mcxw/CMakeLists.txt index 3447992547b76..aad110de351bf 100644 --- a/soc/nxp/mcx/mcxw/CMakeLists.txt +++ b/soc/nxp/mcx/mcxw/CMakeLists.txt @@ -1,11 +1,19 @@ -# Copyright 2023-2024 NXP +# Copyright 2023-2025 NXP # # SPDX-License-Identifier: Apache-2.0 -zephyr_sources(soc.c mcxw71_platform_init.S) +zephyr_sources(soc.c) +zephyr_sources_ifdef(CONFIG_SOC_MCXW716C mcxw71_platform_init.S) +zephyr_sources_ifdef(CONFIG_SOC_MCXW727C mcxw72_platform_init.S) + +zephyr_sources_ifdef(CONFIG_NXP_NBU + ../../common/nxp_nbu.c + ) zephyr_include_directories(.) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") -zephyr_linker_sources_ifdef(CONFIG_BT RAM_SECTIONS sections.ld) +if (CONFIG_BT OR CONFIG_IEEE802154) + zephyr_linker_sources(RAM_SECTIONS sections.ld) +endif() diff --git a/soc/nxp/mcx/mcxw/Kconfig b/soc/nxp/mcx/mcxw/Kconfig index 1804035d96a9c..2a5c4351ef57e 100644 --- a/soc/nxp/mcx/mcxw/Kconfig +++ b/soc/nxp/mcx/mcxw/Kconfig @@ -15,3 +15,14 @@ config SOC_SERIES_MCXW select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK select CLOCK_CONTROL + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + + rsource "../../common/Kconfig.nbu" + +if SOC_MCXW727C + +config MCUX_CORE_SUFFIX + default "_cm33_core0" if SOC_MCXW727C_CPU0 + default "_cm33_core1" if SOC_MCXW727C_CPU1 + +endif # SOC_MCXW727C diff --git a/soc/nxp/mcx/mcxw/Kconfig.defconfig b/soc/nxp/mcx/mcxw/Kconfig.defconfig index 8d715a3aaf712..d04ed76905a88 100644 --- a/soc/nxp/mcx/mcxw/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxw/Kconfig.defconfig @@ -1,9 +1,10 @@ -# Copyright 2023-2024 NXP +# Copyright 2023-2025 NXP # SPDX-License-Identifier: Apache-2.0 if SOC_SERIES_MCXW config NUM_IRQS + default 77 if SOC_MCXW727C default 75 config SYS_CLOCK_HW_CYCLES_PER_SEC @@ -14,6 +15,22 @@ config MCUX_FLASH_K4_API if BT +config MAIN_STACK_SIZE + default 2560 + +config BT_LONG_WQ_STACK_SIZE + default 2560 + +config SYSTEM_WORKQUEUE_STACK_SIZE + default 2048 + +if SHELL + +config SHELL_STACK_SIZE + default 4096 + +endif # SHELL + # Include intercore messaging component config NXP_RF_IMU default y @@ -28,4 +45,14 @@ config HCI_NXP_RX_THREAD default y endif # BT + +if NET_L2_IEEE802154 || NET_L2_OPENTHREAD + +# Include intercore messaging component +config NXP_RF_IMU + default y + +endif # NET_L2_IEEE802154 || NET_L2_OPENTHREAD + + endif # SOC_SERIES_MCXW diff --git a/soc/nxp/mcx/mcxw/Kconfig.soc b/soc/nxp/mcx/mcxw/Kconfig.soc index f6b03d9b893eb..9bbc38bcfbdb1 100644 --- a/soc/nxp/mcx/mcxw/Kconfig.soc +++ b/soc/nxp/mcx/mcxw/Kconfig.soc @@ -12,11 +12,28 @@ config SOC_MCXW716C bool select SOC_SERIES_MCXW +config SOC_MCXW727C + bool + select SOC_SERIES_MCXW + +config SOC_MCXW727C_CPU0 + bool + select SOC_MCXW727C + +config SOC_MCXW727C_CPU1 + bool + select SOC_MCXW727C + config SOC default "mcxw716c" if SOC_MCXW716C + default "mcxw727c" if SOC_MCXW727C config SOC_PART_NUMBER_MCXW716CMFTA bool +config SOC_PART_NUMBER_MCXW727CMFTA + bool + config SOC_PART_NUMBER default "MCXW716CMFTA" if SOC_PART_NUMBER_MCXW716CMFTA + default "MCXW727CMFTA" if SOC_PART_NUMBER_MCXW727CMFTA diff --git a/soc/nxp/mcx/mcxw/mcxw72_platform_init.S b/soc/nxp/mcx/mcxw/mcxw72_platform_init.S new file mode 100644 index 0000000000000..ce02d53580df2 --- /dev/null +++ b/soc/nxp/mcx/mcxw/mcxw72_platform_init.S @@ -0,0 +1,58 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief MCXW72 Platform-Specific Initialization + * + * When compared to MCXW71, the Ram Banks with ECC + * are located in different addresses. + * + * MCXW72 SOC reset code that initializes RAM + * to prevent ECC causing faults, and calls SystemInit + */ + +#include +#include + +_ASM_FILE_PROLOGUE + +GTEXT(soc_reset_hook) +SECTION_SUBSEC_FUNC(TEXT,_reset_section,soc_reset_hook) + +.soc_reset_hook: + ldr r0, =0x14000000 + ldr r1, =.ram_init_ctcm01 + bics r1, #0x10000000 + cmp r0, r1 + bcc .ram_init_done +.ram_init_ctcm01: /* Initialize ctcm01 */ + ldr r0, =0x14000000 + ldr r1, =0x14008000 + ldr r2, =0 + ldr r3, =0 + ldr r4, =0 + ldr r5, =0 +.loop01: + stmia r0!, {r2 - r5} + cmp r0, r1 + bcc.n .loop01 +.ram_init_stcm012: /* Initialize stcm012 */ + ldr r0, =0x30000000 + ldr r1, =0x30010000 +.loop012: + stmia r0!, {r2 - r5} + cmp r0, r1 + bcc.n .loop012 +.ram_init_stcm8: + ldr r0, =0x30038000 + ldr r1, =0x3003a000 +.loop8: /* Initialize stcm5 */ + stmia r0!, {r2 - r5} + cmp r0, r1 + bcc.n .loop8 +.ram_init_done: + b SystemInit diff --git a/soc/nxp/mcx/mcxw/soc.c b/soc/nxp/mcx/mcxw/soc.c index 34f678199a180..94b22710234db 100644 --- a/soc/nxp/mcx/mcxw/soc.c +++ b/soc/nxp/mcx/mcxw/soc.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,8 +17,9 @@ #include extern uint32_t SystemCoreClock; +extern void nxp_nbu_init(void); -static ALWAYS_INLINE void clock_init(void) +__weak void clock_init(void) { /* Unlock Reference Clock Status Registers to allow writes */ CLOCK_UnlockFircControlStatusReg(); @@ -38,10 +39,15 @@ static ALWAYS_INLINE void clock_init(void) }; /* Enable OSC32K */ CCM32K_Set32kOscConfig(CCM32K, kCCM32K_Enable32kHzCrystalOsc, &ccm32k_osc_config); + /* Disable ROSC Monitor, because switching the source would generate an expected error */ CLOCK_SetRoscMonitorMode(kSCG_RoscMonitorDisable); + /* Select the Real Time Clock (RTC) source as OSC32K */ + while ((CCM32K_GetStatusFlag(CCM32K) & CCM32K_STATUS_OSC32K_RDY_MASK) == 0UL) { + } CCM32K_SelectClockSource(CCM32K, kCCM32K_ClockSourceSelectOsc32k); + /* Wait for RTC Oscillator to be Valid */ while (!CLOCK_IsRoscValid()) ; @@ -50,6 +56,8 @@ static ALWAYS_INLINE void clock_init(void) /* Disable the FRO32K to save power */ CCM32K_Enable32kFro(CCM32K, false); + CLOCK_SetXtal32Freq(32768U); + /* Configuration to set FIRC to maximum frequency */ scg_firc_config_t scg_firc_config = { .enableMode = kSCG_FircEnable, /* Fast IRC is enabled */ @@ -90,7 +98,7 @@ static ALWAYS_INLINE void clock_init(void) /* OSC-RF / System Oscillator Configuration */ scg_sosc_config_t sosc_config = { - .freq = 32000U, + .freq = 32000000U, .monitorMode = kSCG_SysOscMonitorDisable, .enableMode = kSCG_SoscEnable, }; @@ -125,11 +133,23 @@ static ALWAYS_INLINE void clock_init(void) CLOCK_SetIpSrcDiv(kCLOCK_Lpadc0, kSCG_SysClkDivBy10); /* Ungate clocks if the peripheral is enabled in devicetree */ - if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart0), nxp_lpc_lpuart, okay)) { + if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(gpioa), nxp_kinetis_gpio, okay)) { + CLOCK_EnableClock(kCLOCK_PortA); + } + + if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(gpiob), nxp_kinetis_gpio, okay)) { + CLOCK_EnableClock(kCLOCK_PortB); + } + + if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(gpioc), nxp_kinetis_gpio, okay)) { + CLOCK_EnableClock(kCLOCK_PortC); + } + + if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart0), nxp_lpuart, okay)) { CLOCK_EnableClock(kCLOCK_Lpuart0); } - if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart1), nxp_lpc_lpuart, okay)) { + if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart1), nxp_lpuart, okay)) { CLOCK_EnableClock(kCLOCK_Lpuart1); } @@ -200,4 +220,8 @@ void soc_early_init_hook(void) /* restore interrupt state */ irq_unlock(oldLevel); + +#if defined(CONFIG_BT) || defined(CONFIG_IEEE802154) + nxp_nbu_init(); +#endif } diff --git a/soc/nxp/mcx/mcxw/soc.h b/soc/nxp/mcx/mcxw/soc.h index 9d1de1abadc11..260341f3feb01 100644 --- a/soc/nxp/mcx/mcxw/soc.h +++ b/soc/nxp/mcx/mcxw/soc.h @@ -10,6 +10,6 @@ #define PORT_MUX_GPIO kPORT_MuxAsGpio -#define ble_hci_handler RF_IMU0_IRQHandler +#define nbu_handler RF_IMU0_IRQHandler #endif /* _SOC__H_ */ diff --git a/soc/nxp/mcx/soc.yml b/soc/nxp/mcx/soc.yml index de7fee7da33bd..fef7853a0298a 100644 --- a/soc/nxp/mcx/soc.yml +++ b/soc/nxp/mcx/soc.yml @@ -20,6 +20,10 @@ family: - name: mcxw socs: - name: mcxw716c + - name: mcxw727c + cpuclusters: + - name: cpu0 + - name: cpu1 runners: run_once: '--erase': @@ -30,6 +34,20 @@ runners: - qualifiers: - mcxn947/cpu0 - mcxn947/cpu1 + - qualifiers: + - mcxn236 + - qualifiers: + - mcxc141 + - qualifiers: + - mcxc142 + - qualifiers: + - mcxc242 + - qualifiers: + - mcxc444 + - qualifiers: + - mcxa156 + - qualifiers: + - mcxw716c '--reset': - run: last runners: @@ -38,3 +56,17 @@ runners: - qualifiers: - mcxn947/cpu0 - mcxn947/cpu1 + - qualifiers: + - mcxn236 + - qualifiers: + - mcxc141 + - qualifiers: + - mcxc142 + - qualifiers: + - mcxc242 + - qualifiers: + - mcxc444 + - qualifiers: + - mcxa156 + - qualifiers: + - mcxw716c diff --git a/soc/nxp/rw/CMakeLists.txt b/soc/nxp/rw/CMakeLists.txt index b716ea5a21b30..c55254984d1ac 100644 --- a/soc/nxp/rw/CMakeLists.txt +++ b/soc/nxp/rw/CMakeLists.txt @@ -7,6 +7,10 @@ zephyr_sources( flexspi_clock_setup.c ) +zephyr_sources_ifdef(CONFIG_NXP_NBU + ../common/nxp_nbu.c + ) + zephyr_sources_ifdef(CONFIG_PM power.c ) diff --git a/soc/nxp/rw/Kconfig b/soc/nxp/rw/Kconfig index 194fa94bbbd97..13b6b4e5dc907 100644 --- a/soc/nxp/rw/Kconfig +++ b/soc/nxp/rw/Kconfig @@ -17,8 +17,9 @@ config SOC_SERIES_RW6XX select HAS_MCUX_FLEXCOMM select HAS_MCUX_CACHE select HAS_PM - select HAS_NXP_MONOLITHIC_BT + select HAS_NXP_MONOLITHIC_NBU select SOC_EARLY_INIT_HOOK + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE if SOC_SERIES_RW6XX @@ -52,5 +53,6 @@ config IMAGE_VECTOR_TABLE_OFFSET endif # NXP_RW6XX_BOOT_HEADER rsource "../common/Kconfig.flexspi_xip" +rsource "../common/Kconfig.nbu" endif # SOC_SERIES_RW6XX diff --git a/soc/nxp/rw/Kconfig.defconfig b/soc/nxp/rw/Kconfig.defconfig index ed5d5d4c0577b..d627e9906475a 100644 --- a/soc/nxp/rw/Kconfig.defconfig +++ b/soc/nxp/rw/Kconfig.defconfig @@ -14,10 +14,10 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC default 1000000 if MCUX_OS_TIMER default 260000000 if CORTEX_M_SYSTICK -if BT +config NXP_MONOLITHIC_NBU + default y if (BT || IEEE802154) -config NXP_MONOLITHIC_BT - default y +if BT config HCI_NXP_ENABLE_AUTO_SLEEP default y @@ -26,7 +26,20 @@ config HCI_NXP_SET_CAL_DATA default y config MAIN_STACK_SIZE - default 1280 + default 2560 + +config BT_LONG_WQ_STACK_SIZE + default 2560 + +config SYSTEM_WORKQUEUE_STACK_SIZE + default 2048 + +if SHELL + +config SHELL_STACK_SIZE + default 4096 + +endif # SHELL endif # BT @@ -34,9 +47,13 @@ config NXP_MONOLITHIC_WIFI default y if WIFI config NXP_FW_LOADER - default y if (BT || WIFI) + default y if (BT || WIFI || IEEE802154) config NXP_RF_IMU - default y if (BT || WIFI) + default y if (BT || WIFI || IEEE802154) + +if WIFI +orsource "Kconfig.defconfig.wifi" +endif # WIFI endif # SOC_SERIES_RW6XX diff --git a/soc/nxp/rw/Kconfig.defconfig.wifi b/soc/nxp/rw/Kconfig.defconfig.wifi new file mode 100644 index 0000000000000..7d4d4453137b6 --- /dev/null +++ b/soc/nxp/rw/Kconfig.defconfig.wifi @@ -0,0 +1,17 @@ +# Copyright 2022-2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if NETWORKING +if NET_DHCPV4_SERVER +config NET_DHCPV4_SERVER_ADDR_COUNT + default 32 + +config NET_DHCPV4_SERVER_ICMP_PROBE_TIMEOUT + default 100 +endif # NET_DHCPV4_SERVER + +if NET_L2_WIFI_MGMT +config WIFI_MGMT_AP_MAX_NUM_STA + default 8 if NXP_WIFI_SOFTAP_SUPPORT +endif # NET_L2_WIFI_MGMT +endif # NETWORKING diff --git a/soc/nxp/rw/firmwares.ld b/soc/nxp/rw/firmwares.ld index 98953c7143530..fdb9fcf9d86dc 100644 --- a/soc/nxp/rw/firmwares.ld +++ b/soc/nxp/rw/firmwares.ld @@ -15,7 +15,7 @@ KEEP(*(.fw_cpu1)) . += 4; #endif -#if defined(CONFIG_NXP_MONOLITHIC_BT) +#if defined(CONFIG_NXP_MONOLITHIC_NBU) . = ALIGN(4); -KEEP(*(.fw_cpu2_ble)) +KEEP(*(.fw_cpu2)) #endif diff --git a/soc/nxp/rw/pinctrl_defs.h b/soc/nxp/rw/pinctrl_defs.h index fac979127222a..0d98a34783e2b 100644 --- a/soc/nxp/rw/pinctrl_defs.h +++ b/soc/nxp/rw/pinctrl_defs.h @@ -284,49 +284,42 @@ #define IOMUX_GPIO_CLR_28 \ (IOMUX_FLEXCOMM_CLR(0x0ULL, 0x0ULL) | /* Flexcomm bits to clear */ \ - IOMUX_FSEL_CLR(0x2ULL) | /* FSEL bits to clear */ \ IOMUX_CTIMER_CLR(0ULL, 0ULL) | /* CTIMER offset to clear */ \ IOMUX_SCTIMER_IN_CLR(0ULL, 0ULL) | /* SCTIMER input offset to clear */ \ IOMUX_SCTIMER_OUT_CLR(0ULL, 0ULL)) /* SCTIMER output offset to clear */ #define IOMUX_GPIO_CLR_29 \ (IOMUX_FLEXCOMM_CLR(0x0ULL, 0x0ULL) | /* Flexcomm bits to clear */ \ - IOMUX_FSEL_CLR(0x2ULL) | /* FSEL bits to clear */ \ IOMUX_CTIMER_CLR(0ULL, 0ULL) | /* CTIMER offset to clear */ \ IOMUX_SCTIMER_IN_CLR(0ULL, 0ULL) | /* SCTIMER input offset to clear */ \ IOMUX_SCTIMER_OUT_CLR(0ULL, 0ULL)) /* SCTIMER output offset to clear */ #define IOMUX_GPIO_CLR_30 \ (IOMUX_FLEXCOMM_CLR(0x0ULL, 0x0ULL) | /* Flexcomm bits to clear */ \ - IOMUX_FSEL_CLR(0x2ULL) | /* FSEL bits to clear */ \ IOMUX_CTIMER_CLR(0ULL, 0ULL) | /* CTIMER offset to clear */ \ IOMUX_SCTIMER_IN_CLR(0ULL, 0ULL) | /* SCTIMER input offset to clear */ \ IOMUX_SCTIMER_OUT_CLR(0ULL, 0ULL)) /* SCTIMER output offset to clear */ #define IOMUX_GPIO_CLR_31 \ (IOMUX_FLEXCOMM_CLR(0x0ULL, 0x0ULL) | /* Flexcomm bits to clear */ \ - IOMUX_FSEL_CLR(0x2ULL) | /* FSEL bits to clear */ \ IOMUX_CTIMER_CLR(0ULL, 0ULL) | /* CTIMER offset to clear */ \ IOMUX_SCTIMER_IN_CLR(0ULL, 0ULL) | /* SCTIMER input offset to clear */ \ IOMUX_SCTIMER_OUT_CLR(0ULL, 0ULL)) /* SCTIMER output offset to clear */ #define IOMUX_GPIO_CLR_32 \ (IOMUX_FLEXCOMM_CLR(0x0ULL, 0x0ULL) | /* Flexcomm bits to clear */ \ - IOMUX_FSEL_CLR(0x2ULL) | /* FSEL bits to clear */ \ IOMUX_CTIMER_CLR(0ULL, 0ULL) | /* CTIMER offset to clear */ \ IOMUX_SCTIMER_IN_CLR(0ULL, 0ULL) | /* SCTIMER input offset to clear */ \ IOMUX_SCTIMER_OUT_CLR(0ULL, 0ULL)) /* SCTIMER output offset to clear */ #define IOMUX_GPIO_CLR_33 \ (IOMUX_FLEXCOMM_CLR(0x0ULL, 0x0ULL) | /* Flexcomm bits to clear */ \ - IOMUX_FSEL_CLR(0x2ULL) | /* FSEL bits to clear */ \ IOMUX_CTIMER_CLR(0ULL, 0ULL) | /* CTIMER offset to clear */ \ IOMUX_SCTIMER_IN_CLR(0ULL, 0ULL) | /* SCTIMER input offset to clear */ \ IOMUX_SCTIMER_OUT_CLR(0ULL, 0ULL)) /* SCTIMER output offset to clear */ #define IOMUX_GPIO_CLR_34 \ (IOMUX_FLEXCOMM_CLR(0x0ULL, 0x0ULL) | /* Flexcomm bits to clear */ \ - IOMUX_FSEL_CLR(0x2ULL) | /* FSEL bits to clear */ \ IOMUX_CTIMER_CLR(0ULL, 0ULL) | /* CTIMER offset to clear */ \ IOMUX_SCTIMER_IN_CLR(0ULL, 0ULL) | /* SCTIMER input offset to clear */ \ IOMUX_SCTIMER_OUT_CLR(0ULL, 0ULL)) /* SCTIMER output offset to clear */ diff --git a/soc/nxp/rw/soc.c b/soc/nxp/rw/soc.c index 9d3b6c548f155..0eb068349cf12 100644 --- a/soc/nxp/rw/soc.c +++ b/soc/nxp/rw/soc.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 NXP + * Copyright 2022-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,8 @@ #include "soc.h" #include "flexspi_clock_setup.h" #include "fsl_ocotp.h" + +extern void nxp_nbu_init(void); #ifdef CONFIG_NXP_RW6XX_BOOT_HEADER extern char z_main_stack[]; extern char _flash_used[]; @@ -78,7 +80,7 @@ const clock_avpll_config_t avpll_config = { * clock needs to be re-initialized on exit from Standby mode. Hence * this function is relocated to RAM. */ -__ramfunc void clock_init(void) +__weak __ramfunc void clock_init(void) { POWER_DisableGDetVSensors(); @@ -301,12 +303,16 @@ void soc_early_init_hook(void) /* Initialize clock */ clock_init(); -#if defined(CONFIG_ADC_MCUX_GAU) || defined(CONFIG_DAC_MCUX_GAU) +#if defined(CONFIG_ADC_MCUX_GAU) || defined(CONFIG_DAC_MCUX_GAU) POWER_PowerOnGau(); #endif #if CONFIG_PM nxp_rw6xx_power_init(); #endif + +#if defined(CONFIG_BT) || defined(CONFIG_IEEE802154) + nxp_nbu_init(); +#endif } void soc_reset_hook(void) diff --git a/soc/nxp/rw/soc.h b/soc/nxp/rw/soc.h index 1e29e78cd5314..9786dba038065 100644 --- a/soc/nxp/rw/soc.h +++ b/soc/nxp/rw/soc.h @@ -16,11 +16,8 @@ #endif /* !_ASMLANGUAGE */ -#define ble_hci_handler BLE_MCI_WAKEUP0_DriverIRQHandler -#define ble_wakeup_done_handler BLE_MCI_WAKEUP_DONE0_DriverIRQHandler - -#define hdlc_rcp_if_handler BLE_MCI_WAKEUP0_DriverIRQHandler -#define hdlc_rcp_if_wakeup_done_handler BLE_MCI_WAKEUP_DONE0_DriverIRQHandler +#define nbu_handler BLE_MCI_WAKEUP0_DriverIRQHandler +#define nbu_wakeup_done_handler BLE_MCI_WAKEUP_DONE0_DriverIRQHandler /* Wrapper Function to deal with SDK differences in power API */ static inline void EnableDeepSleepIRQ(IRQn_Type irq) diff --git a/soc/nxp/s32/s32k1/Kconfig b/soc/nxp/s32/s32k1/Kconfig index f405124f03e3c..bcfac8fcc3170 100644 --- a/soc/nxp/s32/s32k1/Kconfig +++ b/soc/nxp/s32/s32k1/Kconfig @@ -7,7 +7,7 @@ config SOC_SERIES_S32K1 select ARM select HAS_NXP_S32_HAL select HAS_MCUX - select CPU_HAS_NXP_MPU + select CPU_HAS_NXP_SYSMPU select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS select MPU_ALLOW_FLASH_WRITE if !XIP select CLOCK_CONTROL diff --git a/soc/raspberrypi/CMakeLists.txt b/soc/raspberrypi/CMakeLists.txt deleted file mode 100644 index 226f3bd626f61..0000000000000 --- a/soc/raspberrypi/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -add_subdirectory(${SOC_SERIES}) diff --git a/soc/raspberrypi/rp2xxx/Kconfig b/soc/raspberrypi/rp2xxx/Kconfig deleted file mode 100644 index 1abc32af2ceee..0000000000000 --- a/soc/raspberrypi/rp2xxx/Kconfig +++ /dev/null @@ -1,53 +0,0 @@ -# Raspberry Pi RP2XXX MCU line - -# Copyright (c) 2021 Nordic Semiconductor ASA -# Copyright (c) 2021 Yonatan Schachter -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RP2XXX - select ARM - select CPU_CORTEX_M0PLUS - select CPU_CORTEX_M_HAS_SYSTICK - select CPU_CORTEX_M_HAS_VTOR - select CPU_HAS_ARM_MPU - select HAS_RPI_PICO - select XIP - select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE - help - Enable support for Raspberry Pi RP2 MCU series - -config RP2_REQUIRES_SECOND_STAGE_BOOT - bool - default y if FLASH_LOAD_OFFSET = 0x100 - -# Flash type used by the SoC. The board should select the one used. - -config RP2_FLASH_W25Q080 - bool - help - Configure RP2 to use a W25Q080 flash chip, or similar. Should be selected - by the board definition, not the user. - -config RP2_FLASH_GENERIC_03H - bool - help - Configure RP2 to use a flash chip supporting the standard 03h command. - Should be selected by the board definition, not the user. - -config RP2_FLASH_IS25LP080 - bool - help - Configure RP2 to use a IS25LP080 flash chip, or similar. Should be selected - by the board definition, not the user. - -config RP2_FLASH_W25X10CL - bool - help - Configure RP2 to use a W25X10CL flash chip, or similar. Should be selected - by the board definition, not the user. - -config RP2_FLASH_AT25SF128A - bool - help - Configure RP2 to use a AT25SF128A flash chip, or similar. Should be selected - by the board definition, not the user. diff --git a/soc/raspberrypi/rp2xxx/Kconfig.defconfig b/soc/raspberrypi/rp2xxx/Kconfig.defconfig deleted file mode 100644 index 82256e806d053..0000000000000 --- a/soc/raspberrypi/rp2xxx/Kconfig.defconfig +++ /dev/null @@ -1,14 +0,0 @@ -# Raspberry Pi RP2XXX MCU line - -# Copyright (c) 2021 Nordic Semiconductor ASA -# Copyright (c) 2021 Yonatan Schachter -# SPDX-License-Identifier: Apache-2.0 - -if SOC_SERIES_RP2XXX - -rsource "Kconfig.defconfig.rp2*" - -config NUM_IRQS - default 26 - -endif # SOC_SERIES_RP2XXX diff --git a/soc/raspberrypi/rp2xxx/Kconfig.soc b/soc/raspberrypi/rp2xxx/Kconfig.soc deleted file mode 100644 index 045061697fe3e..0000000000000 --- a/soc/raspberrypi/rp2xxx/Kconfig.soc +++ /dev/null @@ -1,19 +0,0 @@ -# Raspberry Pi RP2XXX MCU line - -# Copyright (c) 2021 Nordic Semiconductor ASA -# Copyright (c) 2021 Yonatan Schachter -# SPDX-License-Identifier: Apache-2.0 - -config SOC_RP2040 - bool - select SOC_SERIES_RP2XXX - -config SOC_SERIES_RP2XXX - bool - select SOC_FAMILY_RPI_PICO - -config SOC_SERIES - default "rp2xxx" if SOC_SERIES_RP2XXX - -config SOC - default "rp2040" if SOC_RP2040 diff --git a/soc/raspberrypi/rp2xxx/pinctrl_soc.h b/soc/raspberrypi/rp2xxx/pinctrl_soc.h deleted file mode 100644 index 8ee56c005e1b7..0000000000000 --- a/soc/raspberrypi/rp2xxx/pinctrl_soc.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2021 Yonatan Schachter - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_ -#define ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_ - -#include - -/** - * @brief Type to hold a pin's pinctrl configuration. - */ -struct rpi_pinctrl_soc_pin { - /** Pin number 0..29 */ - uint32_t pin_num : 5; - /** Alternative function (UART, SPI, etc.) */ - uint32_t alt_func : 4; - /** Maximum current used by a pin, in mA */ - uint32_t drive_strength : 4; - /** Slew rate, may be either false (slow) or true (fast) */ - uint32_t slew_rate : 1; - /** Enable the internal pull up resistor */ - uint32_t pullup : 1; - /** Enable the internal pull down resistor */ - uint32_t pulldown : 1; - /** Enable the pin as an input */ - uint32_t input_enable : 1; - /** Enable the internal schmitt trigger */ - uint32_t schmitt_enable : 1; - /** Output-enable override */ - uint32_t oe_override : 2; -}; - -typedef struct rpi_pinctrl_soc_pin pinctrl_soc_pin_t; - -/** - * @brief Utility macro to initialize each pin. - * - * @param node_id Node identifier. - * @param prop Property name. - * @param idx Property entry index. - */ -#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ - { \ - RP2_GET_PIN_NUM(DT_PROP_BY_IDX(node_id, prop, idx)), \ - RP2_GET_PIN_ALT_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \ - DT_ENUM_IDX(node_id, drive_strength), \ - DT_ENUM_IDX(node_id, slew_rate), \ - DT_PROP(node_id, bias_pull_up), \ - DT_PROP(node_id, bias_pull_down), \ - DT_PROP(node_id, input_enable), \ - DT_PROP(node_id, input_schmitt_enable), \ - DT_PROP(node_id, raspberrypi_oe_override), \ - }, - -/** - * @brief Utility macro to initialize state pins contained in a given property. - * - * @param node_id Node identifier. - * @param prop Property name describing state pins. - */ -#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ - {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ - DT_FOREACH_PROP_ELEM, pinmux, \ - Z_PINCTRL_STATE_PIN_INIT)} - -#define RP2_GET_PIN_NUM(pinctrl) \ - (((pinctrl) >> RP2_PIN_NUM_POS) & RP2_PIN_NUM_MASK) -#define RP2_GET_PIN_ALT_FUNC(pinctrl) \ - (((pinctrl) >> RP2_ALT_FUNC_POS) & RP2_ALT_FUNC_MASK) - -#endif /* ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_ */ diff --git a/soc/raspberrypi/rp2xxx/soc.c b/soc/raspberrypi/rp2xxx/soc.c deleted file mode 100644 index 012f5431283b8..0000000000000 --- a/soc/raspberrypi/rp2xxx/soc.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021 Nordic Semiconductor ASA - * Copyright (c) 2021 Yonatan Schachter - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Raspberry Pi RP2040 family processor - * - * This module provides routines to initialize and support board-level hardware - * for the Raspberry Pi RP2040 family processor. - */ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -/* - * Some pico-sdk drivers call panic on fatal error. - * This alternative implementation of panic handles the panic - * through Zephyr. - */ -void __attribute__((noreturn)) panic(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vprintf(fmt, args); - k_fatal_halt(K_ERR_CPU_EXCEPTION); -} diff --git a/soc/raspberrypi/rp2xxx/soc.h b/soc/raspberrypi/rp2xxx/soc.h deleted file mode 100644 index 0eef4cf92a247..0000000000000 --- a/soc/raspberrypi/rp2xxx/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2016 Linaro Limited - * Copyright (c) 2021 Yonatan Schachter - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Raspberry Pi RP2040 family processors - */ - -#ifndef _RPI_PICO_RP2040_SOC_H_ -#define _RPI_PICO_RP2040_SOC_H_ - -#include - -#endif /* _RPI_PICO_RP2040_SOC_H_ */ diff --git a/soc/raspberrypi/rpi_pico/CMakeLists.txt b/soc/raspberrypi/rpi_pico/CMakeLists.txt new file mode 100644 index 0000000000000..c5f97039eb75b --- /dev/null +++ b/soc/raspberrypi/rpi_pico/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(common) +add_subdirectory(${SOC_SERIES}) diff --git a/soc/raspberrypi/Kconfig b/soc/raspberrypi/rpi_pico/Kconfig similarity index 100% rename from soc/raspberrypi/Kconfig rename to soc/raspberrypi/rpi_pico/Kconfig diff --git a/soc/raspberrypi/Kconfig.defconfig b/soc/raspberrypi/rpi_pico/Kconfig.defconfig similarity index 100% rename from soc/raspberrypi/Kconfig.defconfig rename to soc/raspberrypi/rpi_pico/Kconfig.defconfig diff --git a/soc/raspberrypi/Kconfig.soc b/soc/raspberrypi/rpi_pico/Kconfig.soc similarity index 100% rename from soc/raspberrypi/Kconfig.soc rename to soc/raspberrypi/rpi_pico/Kconfig.soc diff --git a/soc/raspberrypi/rpi_pico/common/CMakeLists.txt b/soc/raspberrypi/rpi_pico/common/CMakeLists.txt new file mode 100644 index 0000000000000..d87ecff49c08d --- /dev/null +++ b/soc/raspberrypi/rpi_pico/common/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_sources( + soc.c +) diff --git a/soc/raspberrypi/rpi_pico/common/pinctrl_soc.h b/soc/raspberrypi/rpi_pico/common/pinctrl_soc.h new file mode 100644 index 0000000000000..43cafe1cff992 --- /dev/null +++ b/soc/raspberrypi/rpi_pico/common/pinctrl_soc.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_ + +#include + +/** + * @brief Type to hold a pin's pinctrl configuration. + */ +struct rpi_pinctrl_soc_pin { + /** Pin number 0..29 */ + uint32_t pin_num : 5; + /** Alternative function (UART, SPI, etc.) */ + uint32_t alt_func : 5; + /** Maximum current used by a pin, in mA */ + uint32_t drive_strength : 4; + /** Slew rate, may be either false (slow) or true (fast) */ + uint32_t slew_rate : 1; + /** Enable the internal pull up resistor */ + uint32_t pullup : 1; + /** Enable the internal pull down resistor */ + uint32_t pulldown : 1; + /** Enable the pin as an input */ + uint32_t input_enable : 1; + /** Enable the internal schmitt trigger */ + uint32_t schmitt_enable : 1; + /** Output-enable override */ + uint32_t oe_override : 2; +}; + +typedef struct rpi_pinctrl_soc_pin pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + RP2_GET_PIN_NUM(DT_PROP_BY_IDX(node_id, prop, idx)), \ + RP2_GET_PIN_ALT_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \ + DT_ENUM_IDX(node_id, drive_strength), \ + DT_ENUM_IDX(node_id, slew_rate), \ + DT_PROP(node_id, bias_pull_up), \ + DT_PROP(node_id, bias_pull_down), \ + DT_PROP(node_id, input_enable), \ + DT_PROP(node_id, input_schmitt_enable), \ + DT_PROP(node_id, raspberrypi_oe_override), \ + }, + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ + DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +#define RP2_GET_PIN_NUM(pinctrl) \ + (((pinctrl) >> RP2_PIN_NUM_POS) & RP2_PIN_NUM_MASK) +#define RP2_GET_PIN_ALT_FUNC(pinctrl) \ + (((pinctrl) >> RP2_ALT_FUNC_POS) & RP2_ALT_FUNC_MASK) + +#endif /* ZEPHYR_SOC_ARM_RPI_PICO_RP2_PINCTRL_SOC_H_ */ diff --git a/soc/raspberrypi/rpi_pico/common/soc.c b/soc/raspberrypi/rpi_pico/common/soc.c new file mode 100644 index 0000000000000..37e98105fa14c --- /dev/null +++ b/soc/raspberrypi/rpi_pico/common/soc.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * Copyright (c) 2021 Yonatan Schachter + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Raspberry Pi RP2xxx family of processors + * + * This module provides routines to initialize and support board-level hardware + * for the Raspberry Pi RP2xxx family of processors (RP2040, RP235x). + */ + +#include + +#include +#include + +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +/* + * Some pico-sdk drivers call panic on fatal error. + * This alternative implementation of panic handles the panic + * through Zephyr. + */ +void __attribute__((noreturn)) panic(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vprintf(fmt, args); + k_fatal_halt(K_ERR_CPU_EXCEPTION); +} diff --git a/soc/raspberrypi/rpi_pico/common/soc.h b/soc/raspberrypi/rpi_pico/common/soc.h new file mode 100644 index 0000000000000..c3d669ec99beb --- /dev/null +++ b/soc/raspberrypi/rpi_pico/common/soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2016 Linaro Limited + * Copyright (c) 2021 Yonatan Schachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Raspberry Pi RP2040 family processors + */ + +#ifndef _RPI_PICO_COMMON_SOC_H_ +#define _RPI_PICO_COMMON_SOC_H_ + +#include + +#endif /* _RPI_PICO_COMMON_SOC_H_ */ diff --git a/soc/raspberrypi/rpi_pico/rp2040/CMakeLists.txt b/soc/raspberrypi/rpi_pico/rp2040/CMakeLists.txt new file mode 100644 index 0000000000000..4c53cf10d0fd4 --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2040/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/raspberrypi/rpi_pico/rp2040/Kconfig b/soc/raspberrypi/rpi_pico/rp2040/Kconfig new file mode 100644 index 0000000000000..818482b995238 --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2040/Kconfig @@ -0,0 +1,57 @@ +# Raspberry Pi RP2XXX MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RP2040 + select ARM + select CPU_CORTEX_M0PLUS + select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU + select HAS_RPI_PICO + select XIP + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + help + Enable support for Raspberry Pi RP2040 MCU series + +if SOC_SERIES_RP2040 + +config RP2_REQUIRES_SECOND_STAGE_BOOT + bool + default y if FLASH_LOAD_OFFSET = 0x100 + +# Flash type used by the SoC. The board should select the one used. + +config RP2_FLASH_W25Q080 + bool + help + Configure RP2 to use a W25Q080 flash chip, or similar. Should be selected + by the board definition, not the user. + +config RP2_FLASH_GENERIC_03H + bool + help + Configure RP2 to use a flash chip supporting the standard 03h command. + Should be selected by the board definition, not the user. + +config RP2_FLASH_IS25LP080 + bool + help + Configure RP2 to use a IS25LP080 flash chip, or similar. Should be selected + by the board definition, not the user. + +config RP2_FLASH_W25X10CL + bool + help + Configure RP2 to use a W25X10CL flash chip, or similar. Should be selected + by the board definition, not the user. + +config RP2_FLASH_AT25SF128A + bool + help + Configure RP2 to use a AT25SF128A flash chip, or similar. Should be selected + by the board definition, not the user. + +endif diff --git a/soc/raspberrypi/rpi_pico/rp2040/Kconfig.defconfig b/soc/raspberrypi/rpi_pico/rp2040/Kconfig.defconfig new file mode 100644 index 0000000000000..adaa1e691011f --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2040/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Raspberry Pi RP2040 MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RP2040 + +rsource "Kconfig.defconfig.rp2*" + +config NUM_IRQS + default 26 + +endif # SOC_SERIES_RP2040 diff --git a/soc/raspberrypi/rp2xxx/Kconfig.defconfig.rp2040 b/soc/raspberrypi/rpi_pico/rp2040/Kconfig.defconfig.rp2040 similarity index 100% rename from soc/raspberrypi/rp2xxx/Kconfig.defconfig.rp2040 rename to soc/raspberrypi/rpi_pico/rp2040/Kconfig.defconfig.rp2040 diff --git a/soc/raspberrypi/rpi_pico/rp2040/Kconfig.soc b/soc/raspberrypi/rpi_pico/rp2040/Kconfig.soc new file mode 100644 index 0000000000000..c5b99567a7e39 --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2040/Kconfig.soc @@ -0,0 +1,19 @@ +# Raspberry Pi RP2040 MCU line + +# Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2021 Yonatan Schachter +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES + default "rp2040" if SOC_SERIES_RP2040 + +config SOC_SERIES_RP2040 + bool + select SOC_FAMILY_RPI_PICO + +config SOC_RP2040 + bool + select SOC_SERIES_RP2040 + +config SOC + default "rp2040" if SOC_RP2040 diff --git a/soc/raspberrypi/rp2xxx/linker.ld b/soc/raspberrypi/rpi_pico/rp2040/linker.ld similarity index 100% rename from soc/raspberrypi/rp2xxx/linker.ld rename to soc/raspberrypi/rpi_pico/rp2040/linker.ld diff --git a/soc/raspberrypi/rp2xxx/CMakeLists.txt b/soc/raspberrypi/rpi_pico/rp2350/CMakeLists.txt similarity index 100% rename from soc/raspberrypi/rp2xxx/CMakeLists.txt rename to soc/raspberrypi/rpi_pico/rp2350/CMakeLists.txt diff --git a/soc/raspberrypi/rpi_pico/rp2350/Kconfig b/soc/raspberrypi/rpi_pico/rp2350/Kconfig new file mode 100644 index 0000000000000..2de28a5dd56f2 --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2350/Kconfig @@ -0,0 +1,29 @@ +# Raspberry Pi RP235XX MCU line + +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RP2350 + select HAS_RPI_PICO + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + select SOC_RESET_HOOK + select XIP + +config SOC_RP2350A_M33 + select ARM + select ARM_TRUSTZONE_M + select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR + select CPU_CORTEX_M33 + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + +config RP2_REQUIRES_IMAGE_DEFINITION_BLOCK + bool + default y + # Currently the IDF only supports using the Cortex-M33 cores. Enforce + # this at build configuration time. + depends on SOC_SERIES_RP2350 && CPU_CORTEX_M33 + help + Include an Image Definition Block (IMAGE_DEF) to enable the bootroom in + RP23XX devices to consider this a valid image in flash. diff --git a/soc/raspberrypi/rpi_pico/rp2350/Kconfig.defconfig b/soc/raspberrypi/rpi_pico/rp2350/Kconfig.defconfig new file mode 100644 index 0000000000000..46b0574904596 --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2350/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Raspberry Pi RP2350 MCU line + +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RP2350 + +config BUILD_OUTPUT_UF2_USE_FLASH_BASE + default y if BUILD_OUTPUT_UF2 + +config NUM_IRQS + default 52 + +endif # SOC_SERIES_RP2350 diff --git a/soc/raspberrypi/rpi_pico/rp2350/Kconfig.soc b/soc/raspberrypi/rpi_pico/rp2350/Kconfig.soc new file mode 100644 index 0000000000000..19012bb5648ab --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2350/Kconfig.soc @@ -0,0 +1,24 @@ +# Raspberry Pi RP2350 MCU line + +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RP2350 + bool + select SOC_FAMILY_RPI_PICO + +config SOC_SERIES + default "rp2350" if SOC_SERIES_RP2350 + +config SOC_RP2350A + bool + select SOC_SERIES_RP2350 + +config SOC_RP2350A_M33 + bool + select SOC_RP2350A + help + Use the RP2350A with a Cortex-M33 core in both 'sockets'. + +config SOC + default "rp2350a" if SOC_RP2350A diff --git a/soc/raspberrypi/rpi_pico/rp2350/linker.ld b/soc/raspberrypi/rpi_pico/rp2350/linker.ld new file mode 100644 index 0000000000000..6368409c9e273 --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2350/linker.ld @@ -0,0 +1,27 @@ +/* linker.ld - Linker command/script file */ + +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +MEMORY +{ + IMAGE_DEF_FLASH (r) : ORIGIN = 0x10000000, LENGTH = 128 +} + +SECTIONS +{ + .image_def : { + LONG(0xffffded3) /* PICOBIN_BLOCK_MARKER_START */ + LONG(0x10210142) /* IMAGE_DEF Item */ + LONG(0x00000203) /* VECTOR_TABLE Item */ + LONG(ABSOLUTE(_vector_start)) /* - Address of the vector table in flash */ + LONG(0x000003ff) /* Last Item in Block */ + LONG(0x00000000) /* End of block loop */ + LONG(0xab123579) /* PICOBIN_BLOCK_MARKER_END */ + } > IMAGE_DEF_FLASH +} + +#include diff --git a/soc/raspberrypi/rpi_pico/rp2350/soc.c b/soc/raspberrypi/rpi_pico/rp2350/soc.c new file mode 100644 index 0000000000000..84bcbffc7d97f --- /dev/null +++ b/soc/raspberrypi/rpi_pico/rp2350/soc.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Raspberry Pi RP235xx MCUs + * + * This module provides routines to initialize and support board-level hardware + * for the Raspberry Pi RP235xx (RP2350A, RP2350B, RP2354A, RP2354B). + */ + +#if CONFIG_SOC_RESET_HOOK +#include + + +void soc_reset_hook(void) +{ + runtime_init_per_core_enable_coprocessors(); +} + +#endif /* CONFIG_SOC_RESET_HOOK */ diff --git a/soc/raspberrypi/rpi_pico/soc.yml b/soc/raspberrypi/rpi_pico/soc.yml new file mode 100644 index 0000000000000..32039c2094401 --- /dev/null +++ b/soc/raspberrypi/rpi_pico/soc.yml @@ -0,0 +1,11 @@ +family: +- name: rpi_pico + series: + - name: rp2040 + socs: + - name: rp2040 + - name: rp2350 + socs: + - name: rp2350a + cpuclusters: + - name: m33 diff --git a/soc/raspberrypi/soc.yml b/soc/raspberrypi/soc.yml deleted file mode 100644 index 192d7a947f265..0000000000000 --- a/soc/raspberrypi/soc.yml +++ /dev/null @@ -1,6 +0,0 @@ -family: -- name: rpi_pico - series: - - name: rp2xxx - socs: - - name: rp2040 diff --git a/soc/realtek/ec/CMakeLists.txt b/soc/realtek/ec/CMakeLists.txt new file mode 100644 index 0000000000000..9953afd14f4df --- /dev/null +++ b/soc/realtek/ec/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +add_subdirectory(${SOC_SERIES}) +add_subdirectory(common) diff --git a/soc/realtek/ec/Kconfig b/soc/realtek/ec/Kconfig new file mode 100644 index 0000000000000..a759cb44c37b4 --- /dev/null +++ b/soc/realtek/ec/Kconfig @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +if SOC_FAMILY_REALTEK_EC + +menuconfig REALTEK_RTS5912_BOOTROM_HEADER + bool "Create BOOTROM header for RTS5912" + help + The RTS5912 BOOTROM needs the information about boot up progress. + Invoke the 'rts5912_imgtool' to generates the RTS5912 bootrom header. + +if REALTEK_RTS5912_BOOTROM_HEADER + +config REALTEK_HEADER_CHIP + string + default "RTS5912" if SOC_RTS5912 + +DT_CHOSEN_Z_FLASH := zephyr,flash +FLASH_BASE := $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) + +config REALTEK_RTS5912_BOOTROM_HEADER_LOAD_ADDRESS + string "Set the address for BOOTROM" + default "$(FLASH_BASE) - 0x20" + help + This address will be used by the RTS5912 BOOTROM to decide where firmware image start. + +endif # REALTEK_RTS5912_BOOTROM_HEADER + +# Select SoC Part No. and configuration options +rsource "*/Kconfig" + +endif # SOC_FAMILY_REALTEK_EC diff --git a/soc/realtek/ec/Kconfig.defconfig b/soc/realtek/ec/Kconfig.defconfig new file mode 100644 index 0000000000000..effe686675ae4 --- /dev/null +++ b/soc/realtek/ec/Kconfig.defconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +if SOC_FAMILY_REALTEK_EC + +rsource "*/Kconfig.defconfig.series" + +endif # SOC_FAMILY_REALTEK_EC diff --git a/soc/realtek/ec/Kconfig.soc b/soc/realtek/ec/Kconfig.soc new file mode 100644 index 0000000000000..fd19689cb0774 --- /dev/null +++ b/soc/realtek/ec/Kconfig.soc @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config SOC_FAMILY_REALTEK_EC + bool + +config SOC_FAMILY + string + default "realtek_ec" if SOC_FAMILY_REALTEK_EC + +rsource "*/Kconfig.soc" diff --git a/soc/realtek/ec/common/CMakeLists.txt b/soc/realtek/ec/common/CMakeLists.txt new file mode 100644 index 0000000000000..de4a266ee3949 --- /dev/null +++ b/soc/realtek/ec/common/CMakeLists.txt @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +zephyr_include_directories(.) + +if (DEFINED CONFIG_REALTEK_RTS5912_BOOTROM_HEADER) + math(EXPR adjustment "${CONFIG_REALTEK_RTS5912_BOOTROM_HEADER_LOAD_ADDRESS}" OUTPUT_FORMAT DECIMAL) + set(RTS5912_BIN_NAME ${CONFIG_KERNEL_BIN_NAME}.rts5912.bin) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/soc/realtek/ec/common/rts5912_imgtool/img_gen.py + -L ${adjustment} + -I ${KERNEL_BIN_NAME} + -O ${RTS5912_BIN_NAME} + -V + ) +endif() diff --git a/soc/realtek/ec/common/pinctrl_soc.h b/soc/realtek/ec/common/pinctrl_soc.h new file mode 100644 index 0000000000000..5ca47e1e8a544 --- /dev/null +++ b/soc/realtek/ec/common/pinctrl_soc.h @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +/** + * @file + * realtek SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_ARM_REALTEK_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_REALTEK_COMMON_PINCTRL_SOC_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +typedef uint32_t pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_REALTEK_RTS5912_PINMUX_INIT(node_id) (uint32_t)(DT_PROP(node_id, pinmux)) + +#define Z_PINCTRL_STATE_PINCFG_INIT(node_id) \ + ((DT_PROP(node_id, bias_pull_down) << REALTEK_RTS5912_PD_POS) | \ + (DT_PROP(node_id, bias_pull_up) << REALTEK_RTS5912_PU_POS) | \ + (DT_PROP(node_id, drive_open_drain) << REALTEK_RTS5912_TYPE_POS) | \ + (DT_PROP(node_id, output_high) << REALTEK_RTS5912_HIGH_LOW_POS) | \ + (DT_PROP(node_id, output_enable) << REALTEK_RTS5912_INPUT_OUTPUT_POS) | \ + (DT_PROP(node_id, input_schmitt_enable) << REALTEK_RTS5912_SCHMITTER_POS) | \ + (DT_PROP(node_id, input_enable) << REALTEK_RTS5912_INPUT_DETECTION_POS) | \ + (DT_ENUM_IDX_OR(node_id, slew_rate, 0x0) << REALTEK_RTS5912_SLEW_RATE_POS) | \ + (DT_ENUM_IDX_OR(node_id, drive_strength, 0x0) << REALTEK_RTS5912_DRV_STR_POS)) + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, state_prop, idx) \ + (Z_PINCTRL_REALTEK_RTS5912_PINMUX_INIT(DT_PROP_BY_IDX(node_id, state_prop, idx)) | \ + Z_PINCTRL_STATE_PINCFG_INIT(DT_PROP_BY_IDX(node_id, state_prop, idx))), + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { \ + DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) \ + } + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_REALTEK_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/realtek/ec/common/rts5912_imgtool/img_gen.py b/soc/realtek/ec/common/rts5912_imgtool/img_gen.py new file mode 100644 index 0000000000000..53fcefb916e0d --- /dev/null +++ b/soc/realtek/ec/common/rts5912_imgtool/img_gen.py @@ -0,0 +1,161 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# Author: Dylan Hsieh + +""" +The RTS5912 specific image header shows the bootROM how to +load the image from flash to internal SRAM, this script obtains +the header to original BIN and output a new BIN file. +""" + +import argparse +import os +import struct + +IMAGE_MAGIC = 0x524C544B # ASCII 'RLTK' +IMAGE_HDR_SIZE = 32 +RAM_LOAD = 0x0000020 +FREQ_50M = 0 +FREQ_25M = 1 +FREQ_12P5M = 2 +FREQ_6P25M = 3 +NORMAL_read = "0x03" +DUAL_read = "0x3B" +QUAD_read = "0x6B" + + +def parse_args(): + """ + Parsing the arguments + """ + parser = argparse.ArgumentParser(allow_abbrev=False) + + parser.add_argument( + "-L", + "--load-addr", + type=int, + dest="load_addr", + help="Load address for image when it should run from RAM.", + ) + + parser.add_argument( + "-I", + "--input", + type=str, + dest="original_bin", + default="zephyr.bin", + help="Input bin file path", + ) + + parser.add_argument( + "-O", + "--output", + type=str, + dest="signed_bin", + default="zephyr.rts5912.bin", + help="Output bin file path", + ) + + parser.add_argument( + "-F", + "--spi-freq", + type=int, + dest="spi_freq", + choices=[FREQ_50M, FREQ_25M, FREQ_12P5M, FREQ_6P25M], + default=FREQ_6P25M, + help="Specify the frequency of SPI I/F.", + ) + + parser.add_argument( + "-R", + "--spi-rdcmd", + type=str, + dest="spi_rdcmd", + choices=[NORMAL_read, DUAL_read, QUAD_read], + default=NORMAL_read, + help="Specify the command for flash read.", + ) + + parser.add_argument("-V", "--verbose", action="count", default=0, help="Verbose Output") + + ret_args = parser.parse_args() + return ret_args + + +def img_gen(load_addr, spi_freq, spi_rdcmd, original_bin, signed_bin): + """ + To obtain the RTS5912 image header and output a new BIN file + """ + img_size = os.path.getsize(original_bin) + payload = bytearray(0) + img_size = os.path.getsize(original_bin) + + fmt = ( + "<" + + + # type ImageHdr struct { + "I" # Magic uint32 + + "I" # LoadAddr uint32 + + "H" # HdrSz uint16 + + "H" # reserved uint16 + + "I" # ImgSz uint32 + + "I" # Flags uint32 + + "I" # reserved uint32 + + "I" # reserved uint32 + + "B" # SpiFmt uint8 + + "B" # SpiRdCmd uint8 + + "H" # reserved uint16 + ) # } + + header = struct.pack( + fmt, + IMAGE_MAGIC, + load_addr, + IMAGE_HDR_SIZE, + 0, + img_size, + RAM_LOAD, + 0, + 0, + 0 + (int(spi_freq) << 2), + int(spi_rdcmd, 0), + 0, + ) + + payload[: len(header)] = header + + with open(signed_bin, "wb") as signed: + signed.write(payload) + signed.flush() + signed.close() + + with open(signed_bin, "ab") as signed, open(original_bin, "rb") as original: + signed.write(original.read()) + signed.flush() + signed.close() + original.close() + + +def main(): + """ + Image generateor tool entry point + """ + args = parse_args() + if args.verbose: + print(f" Input = {args.original_bin}") + print(f" Output = {args.signed_bin}") + print(f" Load Address = {hex(args.load_addr)}") + print(f" SPI Frequency = {args.spi_freq}") + print(f" SPI Read Command = {args.spi_rdcmd}") + img_gen( + args.load_addr, + args.spi_freq, + args.spi_rdcmd, + args.original_bin, + args.signed_bin, + ) + + +if __name__ == "__main__": + main() diff --git a/soc/realtek/ec/rts5912/CMakeLists.txt b/soc/realtek/ec/rts5912/CMakeLists.txt new file mode 100644 index 0000000000000..219c68e5a8dee --- /dev/null +++ b/soc/realtek/ec/rts5912/CMakeLists.txt @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +zephyr_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_sources(soc.c) +zephyr_include_directories(.) + +zephyr_sources_ifdef(CONFIG_PM + device_power.c + power.c + ) + +zephyr_sources_ifdef(CONFIG_DT_HAS_SWJ_CONNECTOR_ENABLED debug_swj.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/realtek/ec/rts5912/Kconfig b/soc/realtek/ec/rts5912/Kconfig new file mode 100644 index 0000000000000..aebac7b3d008b --- /dev/null +++ b/soc/realtek/ec/rts5912/Kconfig @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config SOC_SERIES_RTS5912 + select ARM + select CPU_CORTEX_M33 + select SYS_CLOCK_EXISTS + select DYNAMIC_INTERRUPTS + select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RTS5912 + +config RTS5912_ON_ENTER_CPU_IDLE_HOOK + bool "CPU idle hook enable" + default y + imply ARM_ON_ENTER_CPU_IDLE_HOOK + help + Enables a hook (z_arm_on_enter_cpu_idle()) that is called when + the CPU is made idle (by k_cpu_idle() or k_cpu_atomic_idle()). + If needed, this hook can be used to prevent the CPU from actually + entering sleep by skipping the WFE/WFI instruction. + +endif # SOC_SERIES_RTS5912 diff --git a/soc/realtek/ec/rts5912/Kconfig.defconfig.rts5912 b/soc/realtek/ec/rts5912/Kconfig.defconfig.rts5912 new file mode 100644 index 0000000000000..5ff22637497cf --- /dev/null +++ b/soc/realtek/ec/rts5912/Kconfig.defconfig.rts5912 @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +if SOC_RTS5912 + +if REALTEK_RTS5912_RTMR + +config PM + default y + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 + +config SYS_CLOCK_TICKS_PER_SEC + default 32768 + +config ARCH_HAS_CUSTOM_BUSY_WAIT + default y + +endif # REALTEK_RTS5912_RTMR + +endif # SOC_RTS5912 diff --git a/soc/realtek/ec/rts5912/Kconfig.defconfig.series b/soc/realtek/ec/rts5912/Kconfig.defconfig.series new file mode 100644 index 0000000000000..429dbd9c788dc --- /dev/null +++ b/soc/realtek/ec/rts5912/Kconfig.defconfig.series @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +if SOC_SERIES_RTS5912 + +config NUM_IRQS + default 240 + +rsource "Kconfig.defconfig.rts5912" + +endif # SOC_SERIES_RTS5912 diff --git a/soc/realtek/ec/rts5912/Kconfig.soc b/soc/realtek/ec/rts5912/Kconfig.soc new file mode 100644 index 0000000000000..cf86fe3bcb701 --- /dev/null +++ b/soc/realtek/ec/rts5912/Kconfig.soc @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 +# + +config SOC_SERIES_RTS5912 + bool + select SOC_FAMILY_REALTEK_EC + help + Enable support for REALTEK EC MCU series + +config SOC_SERIES + default "rts5912" if SOC_SERIES_RTS5912 + +config SOC_RTS5912 + bool + select SOC_SERIES_RTS5912 + +config SOC + default "rts5912" if SOC_RTS5912 diff --git a/soc/realtek/ec/rts5912/debug_swj.c b/soc/realtek/ec/rts5912/debug_swj.c new file mode 100644 index 0000000000000..c04c9d8c106ac --- /dev/null +++ b/soc/realtek/ec/rts5912/debug_swj.c @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Titan Chen + */ + +#include +#include + +#define SWJ_NODE DT_NODELABEL(swj_port) + +PINCTRL_DT_DEFINE(SWJ_NODE); + +const struct pinctrl_dev_config *swj_pcfg = PINCTRL_DT_DEV_CONFIG_GET(SWJ_NODE); + +int swj_connector_init(void) +{ + int err; + + err = pinctrl_apply_state(swj_pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + return 0; +} diff --git a/soc/realtek/ec/rts5912/debug_swj.h b/soc/realtek/ec/rts5912/debug_swj.h new file mode 100644 index 0000000000000..0f610b7285f75 --- /dev/null +++ b/soc/realtek/ec/rts5912/debug_swj.h @@ -0,0 +1,8 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +int swj_connector_init(void); diff --git a/soc/realtek/ec/rts5912/device_power.c b/soc/realtek/ec/rts5912/device_power.c new file mode 100644 index 0000000000000..b346cafd15616 --- /dev/null +++ b/soc/realtek/ec/rts5912/device_power.c @@ -0,0 +1,25 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#include +#include + +#include +#include "device_power.h" + +void before_rts5912_sleep(void) +{ + __disable_irq(); + __set_BASEPRI(0); + __ISB(); +} + +void after_rts5912_sleep(void) +{ + __enable_irq(); + __ISB(); +} diff --git a/soc/realtek/ec/rts5912/device_power.h b/soc/realtek/ec/rts5912/device_power.h new file mode 100644 index 0000000000000..6a2817fa79fbb --- /dev/null +++ b/soc/realtek/ec/rts5912/device_power.h @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#ifndef ZEPHYR_SOC_REALTEK_RTS5912_DEVICE_POWER_H +#define ZEPHYR_SOC_REALTEK_RTS5912_DEVICE_POWER_H + +void before_rts5912_sleep(void); +void after_rts5912_sleep(void); + +#endif /* ZEPHYR_SOC_REALTEK_RTS5912_DEVICE_POWER_H */ diff --git a/soc/realtek/ec/rts5912/power.c b/soc/realtek/ec/rts5912/power.c new file mode 100644 index 0000000000000..d0702bc4ada15 --- /dev/null +++ b/soc/realtek/ec/rts5912/power.c @@ -0,0 +1,88 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#include +#include + +#include +#include "device_power.h" + +#define RTS5912_SCCON_REG_BASE ((SYSTEM_Type *)(DT_REG_ADDR(DT_NODELABEL(sccon)))) + +static void realtek_WFI(void) +{ + __DSB(); + __WFI(); +} + +static void rts5912_light_sleep(void) +{ + SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE; + + before_rts5912_sleep(); + + sys_reg->SLPCTRL &= ~SYSTEM_SLPCTRL_SLPMDSEL_Msk; + + realtek_WFI(); + + after_rts5912_sleep(); +} + +static void rts5912_heavy_sleep(void) +{ + SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE; + int main_clk_src_record = sys_reg->SYSCLK; + int PLL_en_record = sys_reg->PLLCTRL; + + before_rts5912_sleep(); + + if ((main_clk_src_record & SYSTEM_SYSCLK_SRC_Msk) == 0x0) { + if ((PLL_en_record & SYSTEM_PLLCTRL_EN_Msk) == 0x0) { + sys_reg->PLLCTRL |= SYSTEM_PLLCTRL_EN_Msk; /* Force to enable PLL */ + while ((sys_reg->PLLCTRL & SYSTEM_PLLCTRL_RDY_Msk) == 0x00) { + ; /* Wait until PLL is ready */ + } + } + sys_reg->SYSCLK |= SYSTEM_SYSCLK_SRC_Msk; /* Switch system clock to PLL */ + } + + sys_reg->SLPCTRL |= SYSTEM_SLPCTRL_SLPMDSEL_Msk; /* Heavy Sleep mode */ + + realtek_WFI(); + + if ((main_clk_src_record & SYSTEM_SYSCLK_SRC_Msk) == 0) { + sys_reg->SYSCLK &= ~SYSTEM_SYSCLK_SRC_Msk; /* Return system clock to 25M */ + if ((PLL_en_record & SYSTEM_PLLCTRL_EN_Msk) == 0x0) { + sys_reg->PLLCTRL &= ~SYSTEM_PLLCTRL_EN_Msk; /* Disable PLL */ + } + } + + after_rts5912_sleep(); +} + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + rts5912_light_sleep(); + break; + case PM_STATE_SUSPEND_TO_RAM: + rts5912_heavy_sleep(); + break; + default: + break; + } +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(state); + ARG_UNUSED(substate_id); + + irq_unlock(0); +} diff --git a/soc/realtek/ec/rts5912/reg/reg_gpio.h b/soc/realtek/ec/rts5912/reg/reg_gpio.h new file mode 100644 index 0000000000000..818408c69144c --- /dev/null +++ b/soc/realtek/ec/rts5912/reg/reg_gpio.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Realtek, SIBG-SD7 + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_RTS5912_REG_GPIO_H +#define ZEPHYR_SOC_REALTEK_RTS5912_REG_GPIO_H + +/* + * @brief GPIO Controller (GPIO) + */ + +typedef struct { + volatile uint32_t GCR[132]; +} GPIO_Type; + +/* GCR */ +#define GPIO_GCR_DIR_Pos (0UL) +#define GPIO_GCR_DIR_Msk BIT(GPIO_GCR_DIR_Pos) +#define GPIO_GCR_INDETEN_Pos (1UL) +#define GPIO_GCR_INDETEN_Msk BIT(GPIO_GCR_INDETEN_Pos) +#define GPIO_GCR_INVOLMD_Pos (2UL) +#define GPIO_GCR_INVOLMD_Msk BIT(GPIO_GCR_INVOLMD_Pos) +#define GPIO_GCR_PINSTS_Pos (3UL) +#define GPIO_GCR_PINSTS_Msk BIT(GPIO_GCR_PINSTS_Pos) +#define GPIO_GCR_MFCTRL_Pos (8UL) +#define GPIO_GCR_MFCTRL_Msk GENMASK(10, 8) +#define GPIO_GCR_OUTDRV_Pos (11UL) +#define GPIO_GCR_OUTDRV_Msk BIT(GPIO_GCR_OUTDRV_Pos) +#define GPIO_GCR_SLEWRATE_Pos (12UL) +#define GPIO_GCR_SLEWRATE_Msk BIT(GPIO_GCR_SLEWRATE_Pos) +#define GPIO_GCR_PULLDWEN_Pos (13UL) +#define GPIO_GCR_PULLDWEN_Msk BIT(GPIO_GCR_PULLDWEN_Pos) +#define GPIO_GCR_PULLUPEN_Pos (14UL) +#define GPIO_GCR_PULLUPEN_Msk BIT(GPIO_GCR_PULLUPEN_Pos) +#define GPIO_GCR_SCHEN_Pos (15UL) +#define GPIO_GCR_SCHEN_Msk BIT(GPIO_GCR_SCHEN_Pos) +#define GPIO_GCR_OUTMD_Pos (16UL) +#define GPIO_GCR_OUTMD_Msk BIT(GPIO_GCR_OUTMD_Pos) +#define GPIO_GCR_OUTCTRL_Pos (17UL) +#define GPIO_GCR_OUTCTRL_Msk BIT(GPIO_GCR_OUTCTRL_Pos) +#define GPIO_GCR_INTCTRL_Pos (24UL) +#define GPIO_GCR_INTCTRL_Msk GENMASK(26, 24) +#define GPIO_GCR_INTEN_Pos (28UL) +#define GPIO_GCR_INTEN_Msk BIT(GPIO_GCR_INTEN_Pos) +#define GPIO_GCR_INTSTS_Pos (31UL) +#define GPIO_GCR_INTSTS_Msk BIT(GPIO_GCR_INTSTS_Pos) + +#endif /* ZEPHYR_SOC_REALTEK_RTS5912_REG_GPIO_H */ diff --git a/soc/realtek/ec/rts5912/reg/reg_rtmr.h b/soc/realtek/ec/rts5912/reg/reg_rtmr.h new file mode 100644 index 0000000000000..639574947285d --- /dev/null +++ b/soc/realtek/ec/rts5912/reg/reg_rtmr.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Realtek, SIBG-SD7 + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_RTS5912_REG_RTMR_H +#define ZEPHYR_SOC_REALTEK_RTS5912_REG_RTMR_H + +/* + * @brief RTOS Timer Controller (RTMR) + */ + +typedef struct { + volatile uint32_t LDCNT; + volatile uint32_t CNT; + volatile uint32_t CTRL; + volatile uint32_t INTSTS; +} RTOSTMR_Type; +/* CTRL */ +#define RTOSTMR_CTRL_EN_Pos (0UL) +#define RTOSTMR_CTRL_EN_Msk BIT(RTOSTMR_CTRL_EN_Pos) +#define RTOSTMR_CTRL_MDSEL_Pos (1UL) +#define RTOSTMR_CTRL_MDSEL_Msk BIT(RTOSTMR_CTRL_MDSEL_Pos) +#define RTOSTMR_CTRL_INTEN_Pos (2UL) +#define RTOSTMR_CTRL_INTEN_Msk BIT(RTOSTMR_CTRL_INTEN_Pos) +/* INTSTS */ +#define RTOSTMR_INTSTS_STS_Pos (0UL) +#define RTOSTMR_INTSTS_STS_Msk BIT(RTOSTMR_INTSTS_STS_Pos) + +#endif /* ZEPHYR_SOC_REALTEK_RTS5912_REG_RTMR_H */ diff --git a/soc/realtek/ec/rts5912/reg/reg_system.h b/soc/realtek/ec/rts5912/reg/reg_system.h new file mode 100644 index 0000000000000..673baf4ac35a3 --- /dev/null +++ b/soc/realtek/ec/rts5912/reg/reg_system.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2023 Realtek, SIBG-SD7 + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_RTS5912_REG_SYSTEM_H +#define ZEPHYR_SOC_REALTEK_RTS5912_REG_SYSTEM_H + +/* + * @brief System Controller (SYSTEM) + */ +typedef struct { + union { + volatile uint32_t I3CCLK; + volatile uint32_t TMRRST; + }; + volatile uint32_t I2CCLK; + volatile uint32_t TMRCLK; + volatile uint32_t PERICLKPWR0; + volatile uint32_t UARTCLK; + volatile uint32_t SYSCLK; + volatile uint32_t ADCCLK; + volatile uint32_t PERICLKPWR1; + volatile const uint32_t RESERVED[24]; + volatile uint32_t SLPCTRL; + volatile const uint32_t RESERVED1[7]; + volatile uint32_t VIVOCTRL; + volatile uint32_t LDOCTRL; + volatile uint32_t RC25MCTRL; + volatile uint32_t PLLCTRL; + volatile const uint32_t RESERVED2[12]; + volatile uint32_t RC32KCTRL; + volatile const uint32_t RESERVED3; + volatile uint32_t PERICLKPWR2; +} SYSTEM_Type; + +/* I3CCLK */ +#define SYSTEM_I3CCLK_I3C0DIV_Pos (0UL) +#define SYSTEM_I3CCLK_I3C0DIV_Msk GENMASK(1, 0) +#define SYSTEM_I3CCLK_I3C1DIV_Pos (2UL) +#define SYSTEM_I3CCLK_I3C1DIV_Msk GENMASK(3, 2) +/* TMRRST */ +#define SYSTEM_TMRRST_TMR0RST_Pos (4UL) +#define SYSTEM_TMRRST_TMR0RST_Msk BIT(SYSTEM_TMRRST_TMR0RST_Pos) +#define SYSTEM_TMRRST_TMR1RST_Pos (5UL) +#define SYSTEM_TMRRST_TMR1RST_Msk BIT(SYSTEM_TMRRST_TMR1RST_Pos) +#define SYSTEM_TMRRST_TMR2RST_Pos (6UL) +#define SYSTEM_TMRRST_TMR2RST_Msk BIT(SYSTEM_TMRRST_TMR2RST_Pos) +#define SYSTEM_TMRRST_TMR3RST_Pos (7UL) +#define SYSTEM_TMRRST_TMR3RST_Msk BIT(SYSTEM_TMRRST_TMR3RST_Pos) +#define SYSTEM_TMRRST_TMR4RST_Pos (8UL) +#define SYSTEM_TMRRST_TMR4RST_Msk BIT(SYSTEM_TMRRST_TMR4RST_Pos) +#define SYSTEM_TMRRST_TMR5RST_Pos (9UL) +#define SYSTEM_TMRRST_TMR5RST_Msk BIT(SYSTEM_TMRRST_TMR5RST_Pos) +/* I2CCLK */ +#define SYSTEM_I2CCLK_I2C0CLKPWR_Pos (0UL) +#define SYSTEM_I2CCLK_I2C0CLKPWR_Msk BIT(SYSTEM_I2CCLK_I2C0CLKPWR_Pos) +#define SYSTEM_I2CCLK_I2C0CLKSRC_Pos (1UL) +#define SYSTEM_I2CCLK_I2C0CLKSRC_Msk BIT(SYSTEM_I2CCLK_I2C0CLKSRC_Pos) +#define SYSTEM_I2CCLK_I2C0CLKDIV_Pos (2UL) +#define SYSTEM_I2CCLK_I2C0CLKDIV_Msk GENMASK(3, 2) +#define SYSTEM_I2CCLK_I2C1CLKPWR_Pos (4UL) +#define SYSTEM_I2CCLK_I2C1CLKPWR_Msk BIT(SYSTEM_I2CCLK_I2C1CLKPWR_Pos) +#define SYSTEM_I2CCLK_I2C1CLKSRC_Pos (5UL) +#define SYSTEM_I2CCLK_I2C1CLKSRC_Msk BIT(SYSTEM_I2CCLK_I2C1CLKSRC_Pos) +#define SYSTEM_I2CCLK_I2C1CLKDIV_Pos (6UL) +#define SYSTEM_I2CCLK_I2C1CLKDIV_Msk GENMASK(7, 6) +#define SYSTEM_I2CCLK_I2C2CLKPWR_Pos (8UL) +#define SYSTEM_I2CCLK_I2C2CLKPWR_Msk BIT(SYSTEM_I2CCLK_I2C2CLKPWR_Pos) +#define SYSTEM_I2CCLK_I2C2CLKSRC_Pos (9UL) +#define SYSTEM_I2CCLK_I2C2CLKSRC_Msk BIT(SYSTEM_I2CCLK_I2C2CLKSRC_Pos) +#define SYSTEM_I2CCLK_I2C2CLKDIV_Pos (10UL) +#define SYSTEM_I2CCLK_I2C2CLKDIV_Msk GENMASK(11, 10) +#define SYSTEM_I2CCLK_I2C3CLKPWR_Pos (12UL) +#define SYSTEM_I2CCLK_I2C3CLKPWR_Msk BIT(SYSTEM_I2CCLK_I2C3CLKPWR_Pos) +#define SYSTEM_I2CCLK_I2C3CLKSRC_Pos (13UL) +#define SYSTEM_I2CCLK_I2C3CLKSRC_Msk BIT(SYSTEM_I2CCLK_I2C3CLKSRC_Pos) +#define SYSTEM_I2CCLK_I2C3CLKDIV_Pos (14UL) +#define SYSTEM_I2CCLK_I2C3CLKDIV_Msk GENMASK(15, 14) +#define SYSTEM_I2CCLK_I2C4CLKPWR_Pos (16UL) +#define SYSTEM_I2CCLK_I2C4CLKPWR_Msk BIT(SYSTEM_I2CCLK_I2C4CLKPWR_Pos) +#define SYSTEM_I2CCLK_I2C4CLKSRC_Pos (17UL) +#define SYSTEM_I2CCLK_I2C4CLKSRC_Msk BIT(SYSTEM_I2CCLK_I2C4CLKSRC_Pos) +#define SYSTEM_I2CCLK_I2C4CLKDIV_Pos (18UL) +#define SYSTEM_I2CCLK_I2C4CLKDIV_Msk GENMASK(19, 18) +#define SYSTEM_I2CCLK_I2C5CLKPWR_Pos (20UL) +#define SYSTEM_I2CCLK_I2C5CLKPWR_Msk BIT(SYSTEM_I2CCLK_I2C5CLKPWR_Pos) +#define SYSTEM_I2CCLK_I2C5CLKSRC_Pos (21UL) +#define SYSTEM_I2CCLK_I2C5CLKSRC_Msk BIT(SYSTEM_I2CCLK_I2C5CLKSRC_Pos) +#define SYSTEM_I2CCLK_I2C5CLKDIV_Pos (22UL) +#define SYSTEM_I2CCLK_I2C5CLKDIV_Msk GENMASK(23, 22) +#define SYSTEM_I2CCLK_I2C6CLKPWR_Pos (24UL) +#define SYSTEM_I2CCLK_I2C6CLKPWR_Msk BIT(SYSTEM_I2CCLK_I2C6CLKPWR_Pos) +#define SYSTEM_I2CCLK_I2C6CLKSRC_Pos (25UL) +#define SYSTEM_I2CCLK_I2C6CLKSRC_Msk BIT(SYSTEM_I2CCLK_I2C6CLKSRC_Pos) +#define SYSTEM_I2CCLK_I2C6CLKDIV_Pos (26UL) +#define SYSTEM_I2CCLK_I2C6CLKDIV_Msk GENMASK(27, 26) +#define SYSTEM_I2CCLK_I2C7CLKPWR_Pos (28UL) +#define SYSTEM_I2CCLK_I2C7CLKPWR_Msk BIT(SYSTEM_I2CCLK_I2C7CLKPWR_Pos) +#define SYSTEM_I2CCLK_I2C7CLKSRC_Pos (29UL) +#define SYSTEM_I2CCLK_I2C7CLKSRC_Msk BIT(SYSTEM_I2CCLK_I2C7CLKSRC_Pos) +#define SYSTEM_I2CCLK_I2C7CLKDIV_Pos (30UL) +#define SYSTEM_I2CCLK_I2C7CLKDIV_Msk GENMASK(31, 30) +/* TMRCLK */ +#define SYSTEM_TMRCLK_TMR0DIV_Pos (0UL) +#define SYSTEM_TMRCLK_TMR0DIV_Msk GENMASK(3, 0) +#define SYSTEM_TMRCLK_TMR1DIV_Pos (4UL) +#define SYSTEM_TMRCLK_TMR1DIV_Msk GENMASK(7, 4) +#define SYSTEM_TMRCLK_TMR2DIV_Pos (8UL) +#define SYSTEM_TMRCLK_TMR2DIV_Msk GENMASK(11, 8) +#define SYSTEM_TMRCLK_TMR3DIV_Pos (12UL) +#define SYSTEM_TMRCLK_TMR3DIV_Msk GENMASK(15, 12) +#define SYSTEM_TMRCLK_TMR4DIV_Pos (16UL) +#define SYSTEM_TMRCLK_TMR4DIV_Msk GENMASK(19, 16) +#define SYSTEM_TMRCLK_TMR5DIV_Pos (20UL) +#define SYSTEM_TMRCLK_TMR5DIV_Msk GENMASK(23, 20) +#define SYSTEM_TMRCLK_TMR0PAUSE_Pos (24UL) +#define SYSTEM_TMRCLK_TMR0PAUSE_Msk BIT(SYSTEM_TMRCLK_TMR0PAUSE_Pos) +#define SYSTEM_TMRCLK_TMR1PAUSE_Pos (25UL) +#define SYSTEM_TMRCLK_TMR1PAUSE_Msk BIT(SYSTEM_TMRCLK_TMR1PAUSE_Pos) +#define SYSTEM_TMRCLK_TMR2PAUSE_Pos (26UL) +#define SYSTEM_TMRCLK_TMR2PAUSE_Msk BIT(SYSTEM_TMRCLK_TMR2PAUSE_Pos) +#define SYSTEM_TMRCLK_TMR3PAUSE_Pos (27UL) +#define SYSTEM_TMRCLK_TMR3PAUSE_Msk BIT(SYSTEM_TMRCLK_TMR3PAUSE_Pos) +#define SYSTEM_TMRCLK_TMR4PAUSE_Pos (28UL) +#define SYSTEM_TMRCLK_TMR4PAUSE_Msk BIT(SYSTEM_TMRCLK_TMR4PAUSE_Pos) +#define SYSTEM_TMRCLK_TMR5PAUSE_Pos (29UL) +#define SYSTEM_TMRCLK_TMR5PAUSE_Msk BIT(SYSTEM_TMRCLK_TMR5PAUSE_Pos) +/* PERICLKPWR0 */ +#define SYSTEM_PERICLKPWR0_GPIOCLKPWR_Pos (0UL) +#define SYSTEM_PERICLKPWR0_GPIOCLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_GPIOCLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_TACHO0CLKPWR_Pos (1UL) +#define SYSTEM_PERICLKPWR0_TACHO0CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_TACHO0CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_TACHO1CLKPWR_Pos (2UL) +#define SYSTEM_PERICLKPWR0_TACHO1CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_TACHO1CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_TACHO2CLKPWR_Pos (3UL) +#define SYSTEM_PERICLKPWR0_TACHO2CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_TACHO2CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_TACHO3CLKPWR_Pos (4UL) +#define SYSTEM_PERICLKPWR0_TACHO3CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_TACHO3CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PS2CLKPWR_Pos (5UL) +#define SYSTEM_PERICLKPWR0_PS2CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PS2CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_KBMCLKPWR_Pos (6UL) +#define SYSTEM_PERICLKPWR0_KBMCLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_KBMCLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PECICLKPWR_Pos (7UL) +#define SYSTEM_PERICLKPWR0_PECICLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PECICLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PL0CLKPWR_Pos (8UL) +#define SYSTEM_PERICLKPWR0_PL0CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PL0CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PL1CLKPWR_Pos (9UL) +#define SYSTEM_PERICLKPWR0_PL1CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PL1CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM0CLKPWR_Pos (10UL) +#define SYSTEM_PERICLKPWR0_PWM0CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM0CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM1CLKPWR_Pos (11UL) +#define SYSTEM_PERICLKPWR0_PWM1CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM1CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM2CLKPWR_Pos (12UL) +#define SYSTEM_PERICLKPWR0_PWM2CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM2CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM3CLKPWR_Pos (13UL) +#define SYSTEM_PERICLKPWR0_PWM3CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM3CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM4CLKPWR_Pos (14UL) +#define SYSTEM_PERICLKPWR0_PWM4CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM4CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM5CLKPWR_Pos (15UL) +#define SYSTEM_PERICLKPWR0_PWM5CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM5CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM6CLKPWR_Pos (16UL) +#define SYSTEM_PERICLKPWR0_PWM6CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM6CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM7CLKPWR_Pos (17UL) +#define SYSTEM_PERICLKPWR0_PWM7CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM7CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM8CLKPWR_Pos (18UL) +#define SYSTEM_PERICLKPWR0_PWM8CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM8CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM9CLKPWR_Pos (19UL) +#define SYSTEM_PERICLKPWR0_PWM9CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM9CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM10CLKPWR_Pos (20UL) +#define SYSTEM_PERICLKPWR0_PWM10CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM10CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PWM11CLKPWR_Pos (21UL) +#define SYSTEM_PERICLKPWR0_PWM11CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PWM11CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_ESPICLKPWR_Pos (22UL) +#define SYSTEM_PERICLKPWR0_ESPICLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_ESPICLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_KBCCLKPWR_Pos (23UL) +#define SYSTEM_PERICLKPWR0_KBCCLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_KBCCLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_ACPICLKPWR_Pos (24UL) +#define SYSTEM_PERICLKPWR0_ACPICLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_ACPICLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PMPORT0CLKPWR_Pos (25UL) +#define SYSTEM_PERICLKPWR0_PMPORT0CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PMPORT0CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PMPORT1CLKPWR_Pos (26UL) +#define SYSTEM_PERICLKPWR0_PMPORT1CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PMPORT1CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PMPORT2CLKPWR_Pos (27UL) +#define SYSTEM_PERICLKPWR0_PMPORT2CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PMPORT2CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_PMPORT3CLKPWR_Pos (28UL) +#define SYSTEM_PERICLKPWR0_PMPORT3CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_PMPORT3CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_P80CLKPWR_Pos (29UL) +#define SYSTEM_PERICLKPWR0_P80CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_P80CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_EMI0CLKPWR_Pos (30UL) +#define SYSTEM_PERICLKPWR0_EMI0CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_EMI0CLKPWR_Pos) +#define SYSTEM_PERICLKPWR0_EMI1CLKPWR_Pos (31UL) +#define SYSTEM_PERICLKPWR0_EMI1CLKPWR_Msk BIT(SYSTEM_PERICLKPWR0_EMI1CLKPWR_Pos) +/* UARTCLK */ +#define SYSTEM_UARTCLK_PWR_Pos (0UL) +#define SYSTEM_UARTCLK_PWR_Msk BIT(SYSTEM_UARTCLK_PWR_Pos) +#define SYSTEM_UARTCLK_SRC_Pos (1UL) +#define SYSTEM_UARTCLK_SRC_Msk BIT(SYSTEM_UARTCLK_SRC_Pos) +#define SYSTEM_UARTCLK_DIV_Pos (2UL) +#define SYSTEM_UARTCLK_DIV_Msk GENMASK(3, 2) +/* SYSCLK */ +#define SYSTEM_SYSCLK_SRC_Pos (1UL) +#define SYSTEM_SYSCLK_SRC_Msk BIT(SYSTEM_SYSCLK_SRC_Pos) +#define SYSTEM_SYSCLK_DIV_Pos (2UL) +#define SYSTEM_SYSCLK_DIV_Msk BIT(SYSTEM_SYSCLK_DIV_Pos) +/* ADCCLK */ +#define SYSTEM_ADCCLK_PWR_Pos (0UL) +#define SYSTEM_ADCCLK_PWR_Msk BIT(SYSTEM_ADCCLK_PWR_Pos) +#define SYSTEM_ADCCLK_SRC_Pos (1UL) +#define SYSTEM_ADCCLK_SRC_Msk BIT(SYSTEM_ADCCLK_SRC_Pos) +#define SYSTEM_ADCCLK_DIV_Pos (2UL) +#define SYSTEM_ADCCLK_DIV_Msk GENMASK(4, 2) +/* PERICLKPWR1 */ +#define SYSTEM_PERICLKPWR1_EMI2CLKPWR_Pos (0UL) +#define SYSTEM_PERICLKPWR1_EMI2CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_EMI2CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_EMI3CLKPWR_Pos (1UL) +#define SYSTEM_PERICLKPWR1_EMI3CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_EMI3CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_EMI4CLKPWR_Pos (2UL) +#define SYSTEM_PERICLKPWR1_EMI4CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_EMI4CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_EMI5CLKPWR_Pos (3UL) +#define SYSTEM_PERICLKPWR1_EMI5CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_EMI5CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_EMI6CLKPWR_Pos (4UL) +#define SYSTEM_PERICLKPWR1_EMI6CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_EMI6CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_EMI7CLKPWR_Pos (5UL) +#define SYSTEM_PERICLKPWR1_EMI7CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_EMI7CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_I3C0CLKPWR_Pos (9UL) +#define SYSTEM_PERICLKPWR1_I3C0CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_I3C0CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_I3C1CLKPWR_Pos (10UL) +#define SYSTEM_PERICLKPWR1_I3C1CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_I3C1CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_I2CAUTOCLKPWR_Pos (11UL) +#define SYSTEM_PERICLKPWR1_I2CAUTOCLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_I2CAUTOCLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_MCCLKPWR_Pos (12UL) +#define SYSTEM_PERICLKPWR1_MCCLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_MCCLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_TMR0CLKPWR_Pos (13UL) +#define SYSTEM_PERICLKPWR1_TMR0CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_TMR0CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_TMR1CLKPWR_Pos (14UL) +#define SYSTEM_PERICLKPWR1_TMR1CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_TMR1CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_TMR2CLKPWR_Pos (15UL) +#define SYSTEM_PERICLKPWR1_TMR2CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_TMR2CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_TMR3CLKPWR_Pos (16UL) +#define SYSTEM_PERICLKPWR1_TMR3CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_TMR3CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_TMR4CLKPWR_Pos (17UL) +#define SYSTEM_PERICLKPWR1_TMR4CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_TMR4CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_TMR5CLKPWR_Pos (18UL) +#define SYSTEM_PERICLKPWR1_TMR5CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_TMR5CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_RTMRCLKPWR_Pos (19UL) +#define SYSTEM_PERICLKPWR1_RTMRCLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_RTMRCLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_SLWTMR0CLKPWR_Pos (20UL) +#define SYSTEM_PERICLKPWR1_SLWTMR0CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_SLWTMR0CLKPWR_Pos) +#define SYSTEM_PERICLKPWR1_SLWTMR1CLKPWR_Pos (21UL) +#define SYSTEM_PERICLKPWR1_SLWTMR1CLKPWR_Msk BIT(SYSTEM_PERICLKPWR1_SLWTMR1CLKPWR_Pos) +/* SLPCTRL */ +#define SYSTEM_SLPCTRL_SLPMDSEL_Pos (1UL) +#define SYSTEM_SLPCTRL_SLPMDSEL_Msk BIT(SYSTEM_SLPCTRL_SLPMDSEL_Pos) +#define SYSTEM_SLPCTRL_ESPIWKEN_Pos (2UL) +#define SYSTEM_SLPCTRL_ESPIWKEN_Msk BIT(SYSTEM_SLPCTRL_ESPIWKEN_Pos) +#define SYSTEM_SLPCTRL_PS2WKEN_Pos (3UL) +#define SYSTEM_SLPCTRL_PS2WKEN_Msk BIT(SYSTEM_SLPCTRL_PS2WKEN_Pos) +#define SYSTEM_SLPCTRL_I2CWKEN_Pos (4UL) +#define SYSTEM_SLPCTRL_I2CWKEN_Msk BIT(SYSTEM_SLPCTRL_I2CWKEN_Pos) +#define SYSTEM_SLPCTRL_GPIOWKEN_Pos (5UL) +#define SYSTEM_SLPCTRL_GPIOWKEN_Msk BIT(SYSTEM_SLPCTRL_GPIOWKEN_Pos) +/* VIVOCTRL */ +#define SYSTEM_VIVOCTRL_VIN0MD_Pos (0UL) +#define SYSTEM_VIVOCTRL_VIN0MD_Msk BIT(SYSTEM_VIVOCTRL_VIN0MD_Pos) +#define SYSTEM_VIVOCTRL_VIN1MD_Pos (1UL) +#define SYSTEM_VIVOCTRL_VIN1MD_Msk BIT(SYSTEM_VIVOCTRL_VIN1MD_Pos) +#define SYSTEM_VIVOCTRL_VIN2MD_Pos (2UL) +#define SYSTEM_VIVOCTRL_VIN2MD_Msk BIT(SYSTEM_VIVOCTRL_VIN2MD_Pos) +#define SYSTEM_VIVOCTRL_VIN3MD_Pos (3UL) +#define SYSTEM_VIVOCTRL_VIN3MD_Msk BIT(SYSTEM_VIVOCTRL_VIN3MD_Pos) +#define SYSTEM_VIVOCTRL_VIN4MD_Pos (4UL) +#define SYSTEM_VIVOCTRL_VIN4MD_Msk BIT(SYSTEM_VIVOCTRL_VIN4MD_Pos) +#define SYSTEM_VIVOCTRL_VIN5MD_Pos (5UL) +#define SYSTEM_VIVOCTRL_VIN5MD_Msk BIT(SYSTEM_VIVOCTRL_VIN5MD_Pos) +#define SYSTEM_VIVOCTRL_VIN0STS_Pos (6UL) +#define SYSTEM_VIVOCTRL_VIN0STS_Msk BIT(SYSTEM_VIVOCTRL_VIN0STS_Pos) +#define SYSTEM_VIVOCTRL_VIN1STS_Pos (7UL) +#define SYSTEM_VIVOCTRL_VIN1STS_Msk BIT(SYSTEM_VIVOCTRL_VIN1STS_Pos) +#define SYSTEM_VIVOCTRL_VIN2STS_Pos (8UL) +#define SYSTEM_VIVOCTRL_VIN2STS_Msk BIT(SYSTEM_VIVOCTRL_VIN2STS_Pos) +#define SYSTEM_VIVOCTRL_VIN3STS_Pos (9UL) +#define SYSTEM_VIVOCTRL_VIN3STS_Msk BIT(SYSTEM_VIVOCTRL_VIN3STS_Pos) +#define SYSTEM_VIVOCTRL_VIN4STS_Pos (10UL) +#define SYSTEM_VIVOCTRL_VIN4STS_Msk BIT(SYSTEM_VIVOCTRL_VIN4STS_Pos) +#define SYSTEM_VIVOCTRL_VIN5STS_Pos (11UL) +#define SYSTEM_VIVOCTRL_VIN5STS_Msk BIT(SYSTEM_VIVOCTRL_VIN5STS_Pos) +#define SYSTEM_VIVOCTRL_VIN0POL_Pos (12UL) +#define SYSTEM_VIVOCTRL_VIN0POL_Msk BIT(SYSTEM_VIVOCTRL_VIN0POL_Pos) +#define SYSTEM_VIVOCTRL_VIN1POL_Pos (13UL) +#define SYSTEM_VIVOCTRL_VIN1POL_Msk BIT(SYSTEM_VIVOCTRL_VIN1POL_Pos) +#define SYSTEM_VIVOCTRL_VIN2POL_Pos (14UL) +#define SYSTEM_VIVOCTRL_VIN2POL_Msk BIT(SYSTEM_VIVOCTRL_VIN2POL_Pos) +#define SYSTEM_VIVOCTRL_VIN3POL_Pos (15UL) +#define SYSTEM_VIVOCTRL_VIN3POL_Msk BIT(SYSTEM_VIVOCTRL_VIN3POL_Pos) +#define SYSTEM_VIVOCTRL_VIN4POL_Pos (16UL) +#define SYSTEM_VIVOCTRL_VIN4POL_Msk BIT(SYSTEM_VIVOCTRL_VIN4POL_Pos) +#define SYSTEM_VIVOCTRL_VIN5POL_Pos (17UL) +#define SYSTEM_VIVOCTRL_VIN5POL_Msk BIT(SYSTEM_VIVOCTRL_VIN5POL_Pos) +#define SYSTEM_VIVOCTRL_REGWREN_Pos (30UL) +#define SYSTEM_VIVOCTRL_REGWREN_Msk BIT(SYSTEM_VIVOCTRL_REGWREN_Pos) +#define SYSTEM_VIVOCTRL_VOUTMD_Pos (31UL) +#define SYSTEM_VIVOCTRL_VOUTMD_Msk BIT(SYSTEM_VIVOCTRL_VOUTMD_Pos) +/* LDOCTRL */ +#define SYSTEM_LDOCTRL_LDO2EN_Pos (3UL) +#define SYSTEM_LDOCTRL_LDO2EN_Msk BIT(SYSTEM_LDOCTRL_LDO2EN_Pos) +#define SYSTEM_LDOCTRL_LDO3EN_Pos (7UL) +#define SYSTEM_LDOCTRL_LDO3EN_Msk BIT(SYSTEM_LDOCTRL_LDO3EN_Pos) +/* RC25MCTRL */ +#define SYSTEM_RC25MCTRL_EN_Pos (0UL) +#define SYSTEM_RC25MCTRL_EN_Msk BIT(SYSTEM_RC25MCTRL_EN_Pos) +#define SYSTEM_RC25MCTRL_CALCURR_Pos (1UL) +#define SYSTEM_RC25MCTRL_CALCURR_Msk GENMASK(7, 1) +/* PLLCTRL */ +#define SYSTEM_PLLCTRL_EN_Pos (0UL) +#define SYSTEM_PLLCTRL_EN_Msk BIT(SYSTEM_PLLCTRL_EN_Pos) +#define SYSTEM_PLLCTRL_RDY_Pos (19UL) +#define SYSTEM_PLLCTRL_RDY_Msk BIT(SYSTEM_PLLCTRL_RDY_Pos) +/* RC32KCTRL */ +#define SYSTEM_RC32KCTRL_EN_Pos (0UL) +#define SYSTEM_RC32KCTRL_EN_Msk BIT(SYSTEM_RC32KCTRL_EN_Pos) +#define SYSTEM_RC32KCTRL_CAL_Pos (1UL) +#define SYSTEM_RC32KCTRL_CAL_Msk GENMASK(7, 1) +/* PERICLKPWR2 */ +#define SYSTEM_PERICLKPWR2_RTCCLKPWR_Pos (0UL) +#define SYSTEM_PERICLKPWR2_RTCCLKPWR_Msk BIT(SYSTEM_PERICLKPWR2_RTCCLKPWR_Pos) +#define SYSTEM_PERICLKPWR2_WDTCLKPWR_Pos (1UL) +#define SYSTEM_PERICLKPWR2_WDTCLKPWR_Msk BIT(SYSTEM_PERICLKPWR2_WDTCLKPWR_Pos) +#define SYSTEM_PERICLKPWR2_PWRBTNCLKPWR_Pos (2UL) +#define SYSTEM_PERICLKPWR2_PWRBTNCLKPWR_Msk BIT(SYSTEM_PERICLKPWR2_PWRBTNCLKPWR_Pos) +#define SYSTEM_PERICLKPWR2_RC32KSRC_Pos (30UL) +#define SYSTEM_PERICLKPWR2_RC32KSRC_Msk GENMASK(31, 30) + +#endif /* ZEPHYR_SOC_REALTEK_RTS5912_REG_SYSTEM_H */ diff --git a/soc/realtek/ec/rts5912/soc.c b/soc/realtek/ec/rts5912/soc.c new file mode 100644 index 0000000000000..ce1e254e0517d --- /dev/null +++ b/soc/realtek/ec/rts5912/soc.c @@ -0,0 +1,38 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng / Titan Chen + */ + +#include +#include +#include +#include +#include "debug_swj.h" + +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#if defined(CONFIG_RTS5912_ON_ENTER_CPU_IDLE_HOOK) +bool z_arm_on_enter_cpu_idle(void) +{ + /* Returning false prevent device goes to sleep mode */ + return false; +} +#endif + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + */ +void soc_early_init_hook(void) +{ + int ret; + + /* Apply device related preinit configuration */ + ret = swj_connector_init(); + if (ret < 0) { + LOG_ERR("SWJ init failed"); + } +} diff --git a/soc/realtek/ec/rts5912/soc.h b/soc/realtek/ec/rts5912/soc.h new file mode 100644 index 0000000000000..3824ae900fb2e --- /dev/null +++ b/soc/realtek/ec/rts5912/soc.h @@ -0,0 +1,13 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7 + * Author: Lin Yu-Cheng + */ + +#ifndef SOC_REALTEK_RTS5912_H_ +#define SOC_REALTEK_RTS5912_H_ + +#include + +#endif /* SOC_REALTEK_RTS5912_H_ */ diff --git a/soc/realtek/ec/soc.yml b/soc/realtek/ec/soc.yml new file mode 100644 index 0000000000000..928ceedb6355e --- /dev/null +++ b/soc/realtek/ec/soc.yml @@ -0,0 +1,2 @@ +socs: +- name: rts5912 diff --git a/soc/renesas/ra/ra2a1/Kconfig.defconfig b/soc/renesas/ra/ra2a1/Kconfig.defconfig index 7176e95746acb..e0ae0c6bd23dc 100644 --- a/soc/renesas/ra/ra2a1/Kconfig.defconfig +++ b/soc/renesas/ra/ra2a1/Kconfig.defconfig @@ -6,4 +6,15 @@ if SOC_SERIES_RA2A1 config NUM_IRQS default 32 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + endif # SOC_SERIES_RA2A1 diff --git a/soc/renesas/ra/ra2l1/CMakeLists.txt b/soc/renesas/ra/ra2l1/CMakeLists.txt new file mode 100644 index 0000000000000..240342ab88d24 --- /dev/null +++ b/soc/renesas/ra/ra2l1/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (c) 2022-2024 MUNIC SA +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_sources( + soc.c +) + +zephyr_linker_sources(ROM_START opt_set_mem.ld) + +zephyr_linker_sources(SECTIONS sections.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra2l1/Kconfig b/soc/renesas/ra/ra2l1/Kconfig new file mode 100644 index 0000000000000..e3a0ab7ceabe0 --- /dev/null +++ b/soc/renesas/ra/ra2l1/Kconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 MUNIC SA +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RA2L1 + select ARM + select CPU_CORTEX_M23 + select CPU_HAS_ARM_MPU + select HAS_RENESAS_RA_FSP + select CPU_CORTEX_M_HAS_VTOR + select CPU_CORTEX_M_HAS_SYSTICK + select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL + select HAS_SWO + select SOC_EARLY_INIT_HOOK diff --git a/soc/renesas/ra/ra2l1/Kconfig.defconfig b/soc/renesas/ra/ra2l1/Kconfig.defconfig new file mode 100644 index 0000000000000..ccfd393a9f5ac --- /dev/null +++ b/soc/renesas/ra/ra2l1/Kconfig.defconfig @@ -0,0 +1,20 @@ +# Copyright (c) 2024 MUNIC SA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RA2L1 + +config NUM_IRQS + default 32 + +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +endif # SOC_SERIES_RA2L1 diff --git a/soc/renesas/ra/ra2l1/Kconfig.soc b/soc/renesas/ra/ra2l1/Kconfig.soc new file mode 100644 index 0000000000000..5a4fdb1cfd7a3 --- /dev/null +++ b/soc/renesas/ra/ra2l1/Kconfig.soc @@ -0,0 +1,21 @@ +# Copyright (c) 2024 MUNIC SA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RA2L1 + bool + select SOC_FAMILY_RENESAS_RA + +config SOC_R7FA2L1A9XXFP + bool + select SOC_SERIES_RA2L1 + +config SOC_R7FA2L1ABXXFP + bool + select SOC_SERIES_RA2L1 + +config SOC_SERIES + default "ra2l1" if SOC_SERIES_RA2L1 + +config SOC + default "r7fa2l1a9xxfp" if SOC_R7FA2L1A9XXFP + default "r7fa2l1abxxfp" if SOC_R7FA2L1ABXXFP diff --git a/soc/renesas/ra/ra2l1/opt_set_mem.ld b/soc/renesas/ra/ra2l1/opt_set_mem.ld new file mode 100644 index 0000000000000..07aef9e92d838 --- /dev/null +++ b/soc/renesas/ra/ra2l1/opt_set_mem.ld @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* ROM Registers start at address 0x00000400 */ +. = 0x400; +KEEP(*(.rom_registers*)) +/* Reserving 0x100 bytes of space for ROM registers. */ +. = 0x500; diff --git a/soc/renesas/ra/ra2l1/sections.ld b/soc/renesas/ra/ra2l1/sections.ld new file mode 100644 index 0000000000000..5e7aad11ed7c3 --- /dev/null +++ b/soc/renesas/ra/ra2l1/sections.ld @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) +{ + /* If DTC is used, put the DTC vector table at the start of SRAM. + This avoids memory holes due to 1K alignment required by it. */ + *(.fsp_dtc_vector_table) +} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_ofs), okay) + +SECTION_PROLOGUE(.option_setting_ofs,,) +{ + __OPTION_SETTING_OFS_Start = .; + KEEP(*(.option_setting_ofs0)) + . = __OPTION_SETTING_OFS_Start + 0x04; + KEEP(*(.option_setting_ofs2)) + . = __OPTION_SETTING_OFS_Start + 0x10; + KEEP(*(.option_setting_dualsel)) + __OPTION_SETTING_OFS_End = .; +} GROUP_LINK_IN(OPTION_SETTING_OFS) = 0xFF + +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_sas), okay) + +SECTION_PROLOGUE(.option_setting_sas,,) +{ + __OPTION_SETTING_SAS_Start = .; + KEEP(*(.option_setting_sas)) + __OPTION_SETTING_SAS_End = .; +} GROUP_LINK_IN(OPTION_SETTING_SAS) = 0xFF + +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_ns), okay) + +SECTION_PROLOGUE(.option_setting_ns,,) +{ + __OPTION_SETTING_NS_Start = .; + KEEP(*(.option_setting_ofs1)) + . = __OPTION_SETTING_NS_Start + 0x04; + KEEP(*(.option_setting_ofs3)) + . = __OPTION_SETTING_NS_Start + 0x10; + KEEP(*(.option_setting_banksel)) + . = __OPTION_SETTING_NS_Start + 0x40; + KEEP(*(.option_setting_bps0)) + . = __OPTION_SETTING_NS_Start + 0x44; + KEEP(*(.option_setting_bps1)) + . = __OPTION_SETTING_NS_Start + 0x48; + KEEP(*(.option_setting_bps2)) + . = __OPTION_SETTING_NS_Start + 0x4C; + KEEP(*(.option_setting_bps3)) + . = __OPTION_SETTING_NS_Start + 0x60; + KEEP(*(.option_setting_pbps0)) + . = __OPTION_SETTING_NS_Start + 0x64; + KEEP(*(.option_setting_pbps1)) + . = __OPTION_SETTING_NS_Start + 0x68; + KEEP(*(.option_setting_pbps2)) + . = __OPTION_SETTING_NS_Start + 0x6C; + KEEP(*(.option_setting_pbps3)) + __OPTION_SETTING_NS_End = .; +} GROUP_LINK_IN(OPTION_SETTING) = 0xFF + +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_s), okay) + +SECTION_PROLOGUE(.option_setting_s,,) +{ + __OPTION_SETTING_S_Start = .; + KEEP(*(.option_setting_ofs1_sec)) + . = __OPTION_SETTING_S_Start + 0x04; + KEEP(*(.option_setting_ofs3_sec)) + . = __OPTION_SETTING_S_Start + 0x10; + KEEP(*(.option_setting_banksel_sec)) + . = __OPTION_SETTING_S_Start + 0x40; + KEEP(*(.option_setting_bps_sec0)) + . = __OPTION_SETTING_S_Start + 0x44; + KEEP(*(.option_setting_bps_sec1)) + . = __OPTION_SETTING_S_Start + 0x48; + KEEP(*(.option_setting_bps_sec2)) + . = __OPTION_SETTING_S_Start + 0x4C; + KEEP(*(.option_setting_bps_sec3)) + . = __OPTION_SETTING_S_Start + 0x60; + KEEP(*(.option_setting_pbps_sec0)) + . = __OPTION_SETTING_S_Start + 0x64; + KEEP(*(.option_setting_pbps_sec1)) + . = __OPTION_SETTING_S_Start + 0x68; + KEEP(*(.option_setting_pbps_sec2)) + . = __OPTION_SETTING_S_Start + 0x6C; + KEEP(*(.option_setting_pbps_sec3)) + . = __OPTION_SETTING_S_Start + 0x80; + KEEP(*(.option_setting_ofs1_sel)) + . = __OPTION_SETTING_S_Start + 0x84; + KEEP(*(.option_setting_ofs3_sel)) + . = __OPTION_SETTING_S_Start + 0x90; + KEEP(*(.option_setting_banksel_sel)) + . = __OPTION_SETTING_S_Start + 0xC0; + KEEP(*(.option_setting_bps_sel0)) + . = __OPTION_SETTING_S_Start + 0xC4; + KEEP(*(.option_setting_bps_sel1)) + . = __OPTION_SETTING_S_Start + 0xC8; + KEEP(*(.option_setting_bps_sel2)) + . = __OPTION_SETTING_S_Start + 0xCC; + KEEP(*(.option_setting_bps_sel3)) + __OPTION_SETTING_S_End = .; +} GROUP_LINK_IN(OPTION_SETTING_S) = 0xFF + +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(id_code), okay) + +SECTION_PROLOGUE(.id_code,,) +{ + KEEP(*(.id_code*)) +} GROUP_LINK_IN(ID_CODE) + +#endif diff --git a/soc/renesas/ra/ra2l1/soc.c b/soc/renesas/ra/ra2l1/soc.c new file mode 100644 index 0000000000000..9e1cdb3930284 --- /dev/null +++ b/soc/renesas/ra/ra2l1/soc.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023-2024 MUNIC SA + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Renesas RA2L1 family processor + */ + +#include +#include +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#include "bsp_cfg.h" +#include + +uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; + +volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + */ +void soc_early_init_hook(void) +{ + + SystemCoreClock = BSP_MOCO_HZ; + g_protect_pfswe_counter = 0; + +} diff --git a/soc/renesas/ra/ra2l1/soc.h b/soc/renesas/ra/ra2l1/soc.h new file mode 100644 index 0000000000000..2fa588a6c0c3f --- /dev/null +++ b/soc/renesas/ra/ra2l1/soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021-2024 MUNIC SA + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Renesas RA2L1 family MCU + */ + +#ifndef ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4e1/CMakeLists.txt b/soc/renesas/ra/ra4e1/CMakeLists.txt new file mode 100644 index 0000000000000..e6758812e492e --- /dev/null +++ b/soc/renesas/ra/ra4e1/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_sources( + soc.c +) + +zephyr_linker_sources(SECTIONS sections.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e1/Kconfig b/soc/renesas/ra/ra4e1/Kconfig new file mode 100644 index 0000000000000..dd5a14ef2bf43 --- /dev/null +++ b/soc/renesas/ra/ra4e1/Kconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RA4E1 + select ARM + select CPU_HAS_ARM_MPU + select CPU_CORTEX_M33 + select HAS_RENESAS_RA_FSP + select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL + select CPU_CORTEX_M_HAS_DWT + select ARMV8_M_DSP + select CPU_HAS_FPU + select FPU + select HAS_SWO + select XIP + select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra4e1/Kconfig.defconfig b/soc/renesas/ra/ra4e1/Kconfig.defconfig new file mode 100644 index 0000000000000..7f12ebb724603 --- /dev/null +++ b/soc/renesas/ra/ra4e1/Kconfig.defconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RA4E1 + +config NUM_IRQS + default 96 + +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + +endif # SOC_SERIES_RA4E1 diff --git a/soc/renesas/ra/ra4e1/Kconfig.soc b/soc/renesas/ra/ra4e1/Kconfig.soc new file mode 100644 index 0000000000000..01f75b23d29ed --- /dev/null +++ b/soc/renesas/ra/ra4e1/Kconfig.soc @@ -0,0 +1,27 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RA4E1 + bool + select SOC_FAMILY_RENESAS_RA + help + Renesas RA4E1 series + +config SOC_R7FA4E10D2CFM + bool + select SOC_SERIES_RA4E1 + help + R7FA4E10D2CFM + +config SOC_R7FA4E10D2CNE + bool + select SOC_SERIES_RA4E1 + help + R7FA4E10D2CNE + +config SOC_SERIES + default "ra4e1" if SOC_SERIES_RA4E1 + +config SOC + default "r7fa4e10d2cfm" if SOC_R7FA4E10D2CFM + default "r7fa4e10d2cne" if SOC_R7FA4E10D2CNE diff --git a/soc/renesas/ra/ra4e1/sections.ld b/soc/renesas/ra/ra4e1/sections.ld new file mode 100644 index 0000000000000..38f0a5e25f929 --- /dev/null +++ b/soc/renesas/ra/ra4e1/sections.ld @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) +{ + /* If DTC is used, put the DTC vector table at the start of SRAM. + This avoids memory holes due to 1K alignment required by it. */ + *(.fsp_dtc_vector_table) +} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) + +SECTION_PROLOGUE(.option_setting_ofs,,) +{ + __OPTION_SETTING_OFS_Start = .; + KEEP(*(.option_setting_ofs0)) + . = __OPTION_SETTING_OFS_Start + 0x04; + KEEP(*(.option_setting_ofs2)) + . = __OPTION_SETTING_OFS_Start + 0x10; + KEEP(*(.option_setting_dualsel)) + __OPTION_SETTING_OFS_End = .; +} GROUP_LINK_IN(OPTION_SETTING_OFS) = 0xFF + +SECTION_PROLOGUE(.option_setting_sas,,) +{ + __OPTION_SETTING_SAS_Start = .; + KEEP(*(.option_setting_sas)) + __OPTION_SETTING_SAS_End = .; +} GROUP_LINK_IN(OPTION_SETTING_SAS) = 0xFF + +SECTION_PROLOGUE(.option_setting_s,,) +{ + __OPTION_SETTING_S_Start = .; + KEEP(*(.option_setting_ofs1_sec)) + . = __OPTION_SETTING_S_Start + 0x04; + KEEP(*(.option_setting_ofs3_sec)) + . = __OPTION_SETTING_S_Start + 0x10; + KEEP(*(.option_setting_banksel_sec)) + . = __OPTION_SETTING_S_Start + 0x40; + KEEP(*(.option_setting_bps_sec0)) + . = __OPTION_SETTING_S_Start + 0x44; + KEEP(*(.option_setting_bps_sec1)) + . = __OPTION_SETTING_S_Start + 0x48; + KEEP(*(.option_setting_bps_sec2)) + . = __OPTION_SETTING_S_Start + 0x4C; + KEEP(*(.option_setting_bps_sec3)) + . = __OPTION_SETTING_S_Start + 0x60; + KEEP(*(.option_setting_pbps_sec0)) + . = __OPTION_SETTING_S_Start + 0x64; + KEEP(*(.option_setting_pbps_sec1)) + . = __OPTION_SETTING_S_Start + 0x68; + KEEP(*(.option_setting_pbps_sec2)) + . = __OPTION_SETTING_S_Start + 0x6C; + KEEP(*(.option_setting_pbps_sec3)) + . = __OPTION_SETTING_S_Start + 0x80; + KEEP(*(.option_setting_ofs1_sel)) + . = __OPTION_SETTING_S_Start + 0x84; + KEEP(*(.option_setting_ofs3_sel)) + . = __OPTION_SETTING_S_Start + 0x90; + KEEP(*(.option_setting_banksel_sel)) + . = __OPTION_SETTING_S_Start + 0xC0; + KEEP(*(.option_setting_bps_sel0)) + . = __OPTION_SETTING_S_Start + 0xC4; + KEEP(*(.option_setting_bps_sel1)) + . = __OPTION_SETTING_S_Start + 0xC8; + KEEP(*(.option_setting_bps_sel2)) + . = __OPTION_SETTING_S_Start + 0xCC; + KEEP(*(.option_setting_bps_sel3)) + __OPTION_SETTING_S_End = .; +} GROUP_LINK_IN(OPTION_SETTING_S) = 0xFF diff --git a/soc/renesas/ra/ra4e1/soc.c b/soc/renesas/ra/ra4e1/soc.c new file mode 100644 index 0000000000000..a14c81ddb4ce4 --- /dev/null +++ b/soc/renesas/ra/ra4e1/soc.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Renesas RA4E1 family processor + */ + +#include +#include +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#include "bsp_cfg.h" +#include + +uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; + +volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + */ +void soc_early_init_hook(void) +{ + extern volatile uint16_t g_protect_counters[]; + + for (uint32_t i = 0; i < 4; i++) { + g_protect_counters[i] = 0; + } + +#if FSP_PRIV_TZ_USE_SECURE_REGS + /* Disable protection using PRCR register. */ + R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); + + /* Initialize peripherals to secure mode for flat projects */ + R_PSCU->PSARB = 0; + R_PSCU->PSARC = 0; + R_PSCU->PSARD = 0; + R_PSCU->PSARE = 0; + + R_CPSCU->ICUSARG = 0; + R_CPSCU->ICUSARH = 0; + R_CPSCU->ICUSARI = 0; + + /* Enable protection using PRCR register. */ + R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); +#endif + + SystemCoreClock = BSP_MOCO_HZ; + g_protect_pfswe_counter = 0; +} diff --git a/soc/renesas/ra/ra4e1/soc.h b/soc/renesas/ra/ra4e1/soc.h new file mode 100644 index 0000000000000..704d430fecf57 --- /dev/null +++ b/soc/renesas/ra/ra4e1/soc.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Renesas RA4E1 family MCU + */ + +#ifndef ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4e2/Kconfig.defconfig b/soc/renesas/ra/ra4e2/Kconfig.defconfig index c19cc52a7f7f4..ff781e3becb39 100644 --- a/soc/renesas/ra/ra4e2/Kconfig.defconfig +++ b/soc/renesas/ra/ra4e2/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA4E2 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA4E2 diff --git a/soc/renesas/ra/ra4e2/sections.ld b/soc/renesas/ra/ra4e2/sections.ld index 511ad0854a26a..8999a6524ed40 100644 --- a/soc/renesas/ra/ra4e2/sections.ld +++ b/soc/renesas/ra/ra4e2/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra4l1/CMakeLists.txt b/soc/renesas/ra/ra4l1/CMakeLists.txt new file mode 100644 index 0000000000000..e6758812e492e --- /dev/null +++ b/soc/renesas/ra/ra4l1/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_sources( + soc.c +) + +zephyr_linker_sources(SECTIONS sections.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4l1/Kconfig b/soc/renesas/ra/ra4l1/Kconfig new file mode 100644 index 0000000000000..314e037d34e7b --- /dev/null +++ b/soc/renesas/ra/ra4l1/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RA4L1 + select ARM + select CPU_CORTEX_M33 + select CPU_HAS_ARM_MPU + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_FPU + select FPU + select ARMV8_M_DSP + select HAS_SWO + select HAS_RENESAS_RA_FSP + select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL + select XIP + select SOC_EARLY_INIT_HOOK diff --git a/soc/renesas/ra/ra4l1/Kconfig.defconfig b/soc/renesas/ra/ra4l1/Kconfig.defconfig new file mode 100644 index 0000000000000..afa4ac00fd333 --- /dev/null +++ b/soc/renesas/ra/ra4l1/Kconfig.defconfig @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RA4L1 + +config NUM_IRQS + default 64 + +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +endif # SOC_SERIES_RA4L1 diff --git a/soc/renesas/ra/ra4l1/Kconfig.soc b/soc/renesas/ra/ra4l1/Kconfig.soc new file mode 100644 index 0000000000000..b7a8acf6714ac --- /dev/null +++ b/soc/renesas/ra/ra4l1/Kconfig.soc @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RA4L1 + bool + select SOC_FAMILY_RENESAS_RA + help + Renesas RA4L1 series + +config SOC_R7FA4L1BD4CFP + bool + select SOC_SERIES_RA4L1 + help + R7FA4L1BD4CFP + +config SOC_SERIES + default "ra4l1" if SOC_SERIES_RA4L1 + +config SOC + default "r7fa4l1bd4cfp" if SOC_R7FA4L1BD4CFP diff --git a/soc/renesas/ra/ra4l1/sections.ld b/soc/renesas/ra/ra4l1/sections.ld new file mode 100644 index 0000000000000..d9eb2cd4a9a34 --- /dev/null +++ b/soc/renesas/ra/ra4l1/sections.ld @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) +{ + /* If DTC is used, put the DTC vector table at the start of SRAM. + This avoids memory holes due to 1K alignment required by it. */ + *(.fsp_dtc_vector_table) +} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_ofs), okay) +SECTION_PROLOGUE(.option_setting_ofs,,) +{ + __OPTION_SETTING_OFS_Start = .; + KEEP(*(.option_setting_ofs0)) + . = __OPTION_SETTING_OFS_Start + 0x04; + KEEP(*(.option_setting_ofs2)) + . = __OPTION_SETTING_OFS_Start + 0x10; + KEEP(*(.option_setting_dualsel)) + __OPTION_SETTING_OFS_End = .; +} GROUP_LINK_IN(OPTION_SETTING_OFS) = 0xFF +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_sas), okay) +SECTION_PROLOGUE(.option_setting_sas,,) +{ + __OPTION_SETTING_SAS_Start = .; + KEEP(*(.option_setting_sas)) + __OPTION_SETTING_SAS_End = .; +} GROUP_LINK_IN(OPTION_SETTING_SAS) = 0xFF +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(option_setting_s), okay) +SECTION_PROLOGUE(.option_setting_s,,) +{ + __OPTION_SETTING_S_Start = .; + KEEP(*(.option_setting_ofs1_sec)) + . = __OPTION_SETTING_S_Start + 0x04; + KEEP(*(.option_setting_ofs3_sec)) + . = __OPTION_SETTING_S_Start + 0x10; + KEEP(*(.option_setting_banksel_sec)) + . = __OPTION_SETTING_S_Start + 0x40; + KEEP(*(.option_setting_bps_sec0)) + . = __OPTION_SETTING_S_Start + 0x44; + KEEP(*(.option_setting_bps_sec1)) + . = __OPTION_SETTING_S_Start + 0x48; + KEEP(*(.option_setting_bps_sec2)) + . = __OPTION_SETTING_S_Start + 0x4C; + KEEP(*(.option_setting_bps_sec3)) + . = __OPTION_SETTING_S_Start + 0x60; + KEEP(*(.option_setting_pbps_sec0)) + . = __OPTION_SETTING_S_Start + 0x64; + KEEP(*(.option_setting_pbps_sec1)) + . = __OPTION_SETTING_S_Start + 0x68; + KEEP(*(.option_setting_pbps_sec2)) + . = __OPTION_SETTING_S_Start + 0x6C; + KEEP(*(.option_setting_pbps_sec3)) + . = __OPTION_SETTING_S_Start + 0x80; + KEEP(*(.option_setting_ofs1_sel)) + . = __OPTION_SETTING_S_Start + 0x84; + KEEP(*(.option_setting_ofs3_sel)) + . = __OPTION_SETTING_S_Start + 0x90; + KEEP(*(.option_setting_banksel_sel)) + . = __OPTION_SETTING_S_Start + 0xC0; + KEEP(*(.option_setting_bps_sel0)) + . = __OPTION_SETTING_S_Start + 0xC4; + KEEP(*(.option_setting_bps_sel1)) + . = __OPTION_SETTING_S_Start + 0xC8; + KEEP(*(.option_setting_bps_sel2)) + . = __OPTION_SETTING_S_Start + 0xCC; + KEEP(*(.option_setting_bps_sel3)) + __OPTION_SETTING_S_End = .; +} GROUP_LINK_IN(OPTION_SETTING_S) = 0xFF +#endif diff --git a/soc/renesas/ra/ra4l1/soc.c b/soc/renesas/ra/ra4l1/soc.c new file mode 100644 index 0000000000000..b207d99c65fd0 --- /dev/null +++ b/soc/renesas/ra/ra4l1/soc.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Renesas RA4L1 family processor + */ + +#include +#include +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#include "bsp_cfg.h" +#include "bsp_api.h" + +uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; + +volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + */ +void soc_early_init_hook(void) +{ + extern volatile uint16_t g_protect_counters[]; + + for (uint32_t i = 0; i < 4; i++) { + g_protect_counters[i] = 0; + } + +#if FSP_PRIV_TZ_USE_SECURE_REGS + /* Disable protection using PRCR register. */ + R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); + + /* Initialize peripherals to secure mode for flat projects */ + R_PSCU->PSARB = 0; + R_PSCU->PSARC = 0; + R_PSCU->PSARD = 0; + R_PSCU->PSARE = 0; + + R_CPSCU->ICUSARG = 0; + R_CPSCU->ICUSARH = 0; + R_CPSCU->ICUSARI = 0; + + /* Enable protection using PRCR register. */ + R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); +#endif + + SystemCoreClock = BSP_MOCO_HZ; + g_protect_pfswe_counter = 0; +} diff --git a/soc/renesas/ra/ra4l1/soc.h b/soc/renesas/ra/ra4l1/soc.h new file mode 100644 index 0000000000000..cf99273edd374 --- /dev/null +++ b/soc/renesas/ra/ra4l1/soc.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Renesas RA4L1 family MCU + */ + +#ifndef ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4m1/Kconfig b/soc/renesas/ra/ra4m1/Kconfig index 798725677bbd9..5d071b7f9fceb 100644 --- a/soc/renesas/ra/ra4m1/Kconfig +++ b/soc/renesas/ra/ra4m1/Kconfig @@ -13,7 +13,8 @@ config SOC_SERIES_RA4M1 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK - select DYNAMIC_INTERRUPTS + select DYNAMIC_INTERRUPTS if SOC_R7FA4M1AB3CFM + select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4M1 diff --git a/soc/renesas/ra/ra4m1/Kconfig.defconfig b/soc/renesas/ra/ra4m1/Kconfig.defconfig index 5913bd7257fa8..38587b92ebc63 100644 --- a/soc/renesas/ra/ra4m1/Kconfig.defconfig +++ b/soc/renesas/ra/ra4m1/Kconfig.defconfig @@ -6,4 +6,15 @@ if SOC_SERIES_RA4M1 config NUM_IRQS default 32 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + endif # SOC_SERIES_RA4M1 diff --git a/soc/renesas/ra/ra4m1/Kconfig.soc b/soc/renesas/ra/ra4m1/Kconfig.soc index cb3cbe60a8f58..dbe0c57fa8ba6 100644 --- a/soc/renesas/ra/ra4m1/Kconfig.soc +++ b/soc/renesas/ra/ra4m1/Kconfig.soc @@ -13,8 +13,15 @@ config SOC_R7FA4M1AB3CFM help R7FA4M1AB3CFM +config SOC_R7FA4M1AB3CFP + bool + select SOC_SERIES_RA4M1 + help + R7FA4M1AB3CFP + config SOC_SERIES default "ra4m1" if SOC_SERIES_RA4M1 config SOC default "r7fa4m1ab3cfm" if SOC_R7FA4M1AB3CFM + default "r7fa4m1ab3cfp" if SOC_R7FA4M1AB3CFP diff --git a/soc/renesas/ra/ra4m2/Kconfig b/soc/renesas/ra/ra4m2/Kconfig index a4b6d2c7c50fe..5058fde961655 100644 --- a/soc/renesas/ra/ra4m2/Kconfig +++ b/soc/renesas/ra/ra4m2/Kconfig @@ -14,3 +14,4 @@ config SOC_SERIES_RA4M2 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra4m2/Kconfig.defconfig b/soc/renesas/ra/ra4m2/Kconfig.defconfig index 27a3e35097d89..87ce2fc6817cd 100644 --- a/soc/renesas/ra/ra4m2/Kconfig.defconfig +++ b/soc/renesas/ra/ra4m2/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA4M2 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA4M2 diff --git a/soc/renesas/ra/ra4m2/sections.ld b/soc/renesas/ra/ra4m2/sections.ld index cfc81aeec00b5..1fe7db907a3d9 100644 --- a/soc/renesas/ra/ra4m2/sections.ld +++ b/soc/renesas/ra/ra4m2/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra4m3/Kconfig b/soc/renesas/ra/ra4m3/Kconfig index 0898c3796bce1..dfa3719068650 100644 --- a/soc/renesas/ra/ra4m3/Kconfig +++ b/soc/renesas/ra/ra4m3/Kconfig @@ -14,3 +14,4 @@ config SOC_SERIES_RA4M3 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra4m3/Kconfig.defconfig b/soc/renesas/ra/ra4m3/Kconfig.defconfig index 974ba532beec0..af4c164af81fd 100644 --- a/soc/renesas/ra/ra4m3/Kconfig.defconfig +++ b/soc/renesas/ra/ra4m3/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA4M3 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA4M3 diff --git a/soc/renesas/ra/ra4m3/sections.ld b/soc/renesas/ra/ra4m3/sections.ld index cfc81aeec00b5..1fe7db907a3d9 100644 --- a/soc/renesas/ra/ra4m3/sections.ld +++ b/soc/renesas/ra/ra4m3/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra4w1/Kconfig b/soc/renesas/ra/ra4w1/Kconfig index c9d1fbb37033e..34f44bf6d0742 100644 --- a/soc/renesas/ra/ra4w1/Kconfig +++ b/soc/renesas/ra/ra4w1/Kconfig @@ -13,3 +13,4 @@ config SOC_SERIES_RA4W1 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra4w1/Kconfig.defconfig b/soc/renesas/ra/ra4w1/Kconfig.defconfig index 56c1866d0e96b..3e3cbb9747c44 100644 --- a/soc/renesas/ra/ra4w1/Kconfig.defconfig +++ b/soc/renesas/ra/ra4w1/Kconfig.defconfig @@ -6,4 +6,15 @@ if SOC_SERIES_RA4W1 config NUM_IRQS default 32 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + endif # SOC_SERIES_RA4W1 diff --git a/soc/renesas/ra/ra6e1/Kconfig b/soc/renesas/ra/ra6e1/Kconfig index accd57e26a069..097baa6241484 100644 --- a/soc/renesas/ra/ra6e1/Kconfig +++ b/soc/renesas/ra/ra6e1/Kconfig @@ -14,3 +14,4 @@ config SOC_SERIES_RA6E1 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra6e1/Kconfig.defconfig b/soc/renesas/ra/ra6e1/Kconfig.defconfig index dfdaec67bf456..d8478071e7a60 100644 --- a/soc/renesas/ra/ra6e1/Kconfig.defconfig +++ b/soc/renesas/ra/ra6e1/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA6E1 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA6E1 diff --git a/soc/renesas/ra/ra6e1/sections.ld b/soc/renesas/ra/ra6e1/sections.ld index cfc81aeec00b5..1fe7db907a3d9 100644 --- a/soc/renesas/ra/ra6e1/sections.ld +++ b/soc/renesas/ra/ra6e1/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra6e2/Kconfig.defconfig b/soc/renesas/ra/ra6e2/Kconfig.defconfig index 25c013dd85529..9d56855abe191 100644 --- a/soc/renesas/ra/ra6e2/Kconfig.defconfig +++ b/soc/renesas/ra/ra6e2/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA6E2 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA6E2 diff --git a/soc/renesas/ra/ra6e2/sections.ld b/soc/renesas/ra/ra6e2/sections.ld index 511ad0854a26a..8999a6524ed40 100644 --- a/soc/renesas/ra/ra6e2/sections.ld +++ b/soc/renesas/ra/ra6e2/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra6m1/Kconfig b/soc/renesas/ra/ra6m1/Kconfig index 649b6702629d3..ffe573117178b 100644 --- a/soc/renesas/ra/ra6m1/Kconfig +++ b/soc/renesas/ra/ra6m1/Kconfig @@ -13,3 +13,4 @@ config SOC_SERIES_RA6M1 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra6m1/Kconfig.defconfig b/soc/renesas/ra/ra6m1/Kconfig.defconfig index af401ae242cd0..f863f67d6f22d 100644 --- a/soc/renesas/ra/ra6m1/Kconfig.defconfig +++ b/soc/renesas/ra/ra6m1/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA6M1 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA6M1 diff --git a/soc/renesas/ra/ra6m1/sections.ld b/soc/renesas/ra/ra6m1/sections.ld index b850a64f64374..8d31894fc387d 100644 --- a/soc/renesas/ra/ra6m1/sections.ld +++ b/soc/renesas/ra/ra6m1/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra6m2/Kconfig b/soc/renesas/ra/ra6m2/Kconfig index 680e649349d7a..09c6427a52ea8 100644 --- a/soc/renesas/ra/ra6m2/Kconfig +++ b/soc/renesas/ra/ra6m2/Kconfig @@ -13,3 +13,4 @@ config SOC_SERIES_RA6M2 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra6m2/Kconfig.defconfig b/soc/renesas/ra/ra6m2/Kconfig.defconfig index c95ecd0cc2928..7e5cd7a2eec12 100644 --- a/soc/renesas/ra/ra6m2/Kconfig.defconfig +++ b/soc/renesas/ra/ra6m2/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA6M2 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA6M2 diff --git a/soc/renesas/ra/ra6m2/sections.ld b/soc/renesas/ra/ra6m2/sections.ld index b850a64f64374..8d31894fc387d 100644 --- a/soc/renesas/ra/ra6m2/sections.ld +++ b/soc/renesas/ra/ra6m2/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra6m3/Kconfig b/soc/renesas/ra/ra6m3/Kconfig index bebd78f1babbf..3dea36935aeaf 100644 --- a/soc/renesas/ra/ra6m3/Kconfig +++ b/soc/renesas/ra/ra6m3/Kconfig @@ -13,3 +13,4 @@ config SOC_SERIES_RA6M3 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra6m3/Kconfig.defconfig b/soc/renesas/ra/ra6m3/Kconfig.defconfig index e2a02946b3849..ae8951e40c5ca 100644 --- a/soc/renesas/ra/ra6m3/Kconfig.defconfig +++ b/soc/renesas/ra/ra6m3/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA6M3 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA6M3 diff --git a/soc/renesas/ra/ra6m3/sections.ld b/soc/renesas/ra/ra6m3/sections.ld index b850a64f64374..8d31894fc387d 100644 --- a/soc/renesas/ra/ra6m3/sections.ld +++ b/soc/renesas/ra/ra6m3/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra6m4/Kconfig b/soc/renesas/ra/ra6m4/Kconfig index ee2acc2855fd4..dec6aba2581e9 100644 --- a/soc/renesas/ra/ra6m4/Kconfig +++ b/soc/renesas/ra/ra6m4/Kconfig @@ -14,3 +14,4 @@ config SOC_SERIES_RA6M4 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra6m4/Kconfig.defconfig b/soc/renesas/ra/ra6m4/Kconfig.defconfig index aa79e91370a74..7e6de81829e88 100644 --- a/soc/renesas/ra/ra6m4/Kconfig.defconfig +++ b/soc/renesas/ra/ra6m4/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA6M4 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA6M4 diff --git a/soc/renesas/ra/ra6m4/sections.ld b/soc/renesas/ra/ra6m4/sections.ld index cfc81aeec00b5..1fe7db907a3d9 100644 --- a/soc/renesas/ra/ra6m4/sections.ld +++ b/soc/renesas/ra/ra6m4/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra6m5/Kconfig b/soc/renesas/ra/ra6m5/Kconfig index 4a8f750eab60a..792239394c72c 100644 --- a/soc/renesas/ra/ra6m5/Kconfig +++ b/soc/renesas/ra/ra6m5/Kconfig @@ -14,3 +14,4 @@ config SOC_SERIES_RA6M5 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra6m5/Kconfig.defconfig b/soc/renesas/ra/ra6m5/Kconfig.defconfig index d0c5c5fc0c3c4..51c5a3c0de2f5 100644 --- a/soc/renesas/ra/ra6m5/Kconfig.defconfig +++ b/soc/renesas/ra/ra6m5/Kconfig.defconfig @@ -6,4 +6,19 @@ if SOC_SERIES_RA6M5 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,iclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + +# Set to the minimal size of data which can be written. +config FLASH_FILL_BUFFER_SIZE + default 128 + endif # SOC_SERIES_RA6M5 diff --git a/soc/renesas/ra/ra6m5/sections.ld b/soc/renesas/ra/ra6m5/sections.ld index cfc81aeec00b5..1fe7db907a3d9 100644 --- a/soc/renesas/ra/ra6m5/sections.ld +++ b/soc/renesas/ra/ra6m5/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra8d1/Kconfig b/soc/renesas/ra/ra8d1/Kconfig index 968c60343c6d8..50907d2be70c9 100644 --- a/soc/renesas/ra/ra8d1/Kconfig +++ b/soc/renesas/ra/ra8d1/Kconfig @@ -14,3 +14,4 @@ config SOC_SERIES_RA8D1 select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra8d1/Kconfig.defconfig b/soc/renesas/ra/ra8d1/Kconfig.defconfig index 5c2a630bfd75d..219dbd2336db9 100644 --- a/soc/renesas/ra/ra8d1/Kconfig.defconfig +++ b/soc/renesas/ra/ra8d1/Kconfig.defconfig @@ -6,8 +6,22 @@ if SOC_SERIES_RA8D1 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + # Set to the minimal size of data which can be written. config FLASH_FILL_BUFFER_SIZE default 128 +config CACHE_MANAGEMENT + default y + endif # SOC_SERIES_RA8D1 diff --git a/soc/renesas/ra/ra8d1/sections.ld b/soc/renesas/ra/ra8d1/sections.ld index cfc81aeec00b5..1fe7db907a3d9 100644 --- a/soc/renesas/ra/ra8d1/sections.ld +++ b/soc/renesas/ra/ra8d1/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra8d1/soc.c b/soc/renesas/ra/ra8d1/soc.c index 4d78ba0e1ca27..685ec6b349e39 100644 --- a/soc/renesas/ra/ra8d1/soc.c +++ b/soc/renesas/ra/ra8d1/soc.c @@ -17,10 +17,14 @@ #include #include #include +#include +#include LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); #include +#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) + uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; @@ -34,4 +38,24 @@ void soc_early_init_hook(void) { SystemCoreClock = BSP_MOCO_HZ; g_protect_pfswe_counter = 0; + + SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; + barrier_dsync_fence_full(); + barrier_isync_fence_full(); + + /* Apply Arm Cortex-M85 errata workarounds for D-Cache + * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. + * Set bit 16 in ACTLR to 1. + * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 + * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, + * Document ID: SDEN-2236668). + */ + MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; + barrier_dsync_fence_full(); + barrier_isync_fence_full(); + ICB->ACTLR |= (1U << 16U); + barrier_dsync_fence_full(); + barrier_isync_fence_full(); + + sys_cache_data_enable(); } diff --git a/soc/renesas/ra/ra8m1/Kconfig b/soc/renesas/ra/ra8m1/Kconfig index f1fd9d9967e6e..31d4aaefda5ee 100644 --- a/soc/renesas/ra/ra8m1/Kconfig +++ b/soc/renesas/ra/ra8m1/Kconfig @@ -14,5 +14,6 @@ config SOC_SERIES_RA8M1 select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR help Enable support for Renesas RA8M1 MCU series diff --git a/soc/renesas/ra/ra8m1/Kconfig.defconfig b/soc/renesas/ra/ra8m1/Kconfig.defconfig index d963468bb07e3..18f1da7e08d2e 100644 --- a/soc/renesas/ra/ra8m1/Kconfig.defconfig +++ b/soc/renesas/ra/ra8m1/Kconfig.defconfig @@ -6,6 +6,17 @@ if SOC_SERIES_RA8M1 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + # Set to the minimal size of data which can be written. config FLASH_FILL_BUFFER_SIZE default 128 diff --git a/soc/renesas/ra/ra8m1/sections.ld b/soc/renesas/ra/ra8m1/sections.ld index cfc81aeec00b5..1fe7db907a3d9 100644 --- a/soc/renesas/ra/ra8m1/sections.ld +++ b/soc/renesas/ra/ra8m1/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/ra8t1/Kconfig b/soc/renesas/ra/ra8t1/Kconfig index 426e72be95d11..5fe21152ad401 100644 --- a/soc/renesas/ra/ra8t1/Kconfig +++ b/soc/renesas/ra/ra8t1/Kconfig @@ -14,3 +14,4 @@ config SOC_SERIES_RA8T1 select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP select SOC_EARLY_INIT_HOOK + select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra8t1/Kconfig.defconfig b/soc/renesas/ra/ra8t1/Kconfig.defconfig index 3e721bd8fc3ac..44acb5cf41301 100644 --- a/soc/renesas/ra/ra8t1/Kconfig.defconfig +++ b/soc/renesas/ra/ra8t1/Kconfig.defconfig @@ -6,6 +6,17 @@ if SOC_SERIES_RA8T1 config NUM_IRQS default 96 +DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) + +config BUILD_OUTPUT_HEX + default y + +config CLOCK_CONTROL + default y + # Set to the minimal size of data which can be written. config FLASH_FILL_BUFFER_SIZE default 128 diff --git a/soc/renesas/ra/ra8t1/sections.ld b/soc/renesas/ra/ra8t1/sections.ld index cfc81aeec00b5..1fe7db907a3d9 100644 --- a/soc/renesas/ra/ra8t1/sections.ld +++ b/soc/renesas/ra/ra8t1/sections.ld @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -.code_in_ram : -{ - . = ALIGN(4); - __Code_In_RAM_Start = .; - KEEP(*(.code_in_ram*)) - __Code_In_RAM_End = .; -} > RAMABLE_REGION - SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) { /* If DTC is used, put the DTC vector table at the start of SRAM. diff --git a/soc/renesas/ra/soc.yml b/soc/renesas/ra/soc.yml index 6e7887b098a3c..e923db71a671d 100644 --- a/soc/renesas/ra/soc.yml +++ b/soc/renesas/ra/soc.yml @@ -4,12 +4,24 @@ family: - name: ra2a1 socs: - name: r7fa2a1ab3cfm + - name: ra2l1 + socs: + - name: r7fa2l1a9xxfp + - name: r7fa2l1abxxfp + - name: ra4e1 + socs: + - name: r7fa4e10d2cfm + - name: r7fa4e10d2cne - name: ra4e2 socs: - name: r7fa4e2b93cfm + - name: ra4l1 + socs: + - name: r7fa4l1bd4cfp - name: ra4m1 socs: - name: r7fa4m1ab3cfm + - name: r7fa4m1ab3cfp - name: ra4m2 socs: - name: r7fa4m2ad3cfp diff --git a/soc/renesas/rz/CMakeLists.txt b/soc/renesas/rz/CMakeLists.txt new file mode 100644 index 0000000000000..77d3f459bf159 --- /dev/null +++ b/soc/renesas/rz/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories_ifdef(CONFIG_HAS_RENESAS_RZ_FSP common) + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/renesas/rz/Kconfig b/soc/renesas/rz/Kconfig new file mode 100644 index 0000000000000..0987cc809c3c2 --- /dev/null +++ b/soc/renesas/rz/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_RENESAS_RZ + +rsource "*/Kconfig" + +endif # SOC_FAMILY_RENESAS_RZ diff --git a/soc/renesas/rz/Kconfig.defconfig b/soc/renesas/rz/Kconfig.defconfig new file mode 100644 index 0000000000000..460b3387e760c --- /dev/null +++ b/soc/renesas/rz/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_RENESAS_RZ + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_RENESAS_RZ diff --git a/soc/renesas/rz/Kconfig.soc b/soc/renesas/rz/Kconfig.soc new file mode 100644 index 0000000000000..c6457e225213a --- /dev/null +++ b/soc/renesas/rz/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_RENESAS_RZ + bool + +config SOC_FAMILY + default "renesas_rz" if SOC_FAMILY_RENESAS_RZ + +rsource "*/Kconfig.soc" diff --git a/soc/renesas/rz/common/pinctrl_rzg.h b/soc/renesas/rz/common/pinctrl_rzg.h new file mode 100644 index 0000000000000..e2ef13fbe33f9 --- /dev/null +++ b/soc/renesas/rz/common/pinctrl_rzg.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_SOC_RENESAS_RZ_COMMON_PINCTRL_RZG_H_ +#define ZEPHYR_SOC_RENESAS_RZ_COMMON_PINCTRL_RZG_H_ + +#include +#include +#include +#include "r_ioport.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*Porting*/ +typedef struct pinctrl_cfg_data_t { + uint32_t reserved: 4; + uint32_t pupd_reg: 6; + uint32_t iolh_reg: 6; + uint32_t pmc_reg: 2; + uint32_t ien_reg: 1; + uint32_t filonoff_reg: 1; + uint32_t filnum_reg: 2; + uint32_t filclksel_reg: 2; + uint32_t pfc_reg: 3; +} pinctrl_cfg_data_t; + +typedef struct pinctrl_soc_pin_t { + bsp_io_port_pin_t port_pin; + pinctrl_cfg_data_t config; +} pinctrl_soc_pin_t; + +/* Iterate over each pinctrl-n phandle child */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, state_prop, idx) \ + DT_FOREACH_CHILD(DT_PHANDLE_BY_IDX(node_id, state_prop, idx), \ + Z_PINCTRL_STATE_PIN_CHILD_INIT) + +/* Iterate over each pinctrl-n phandle child */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_PROP_ELEM_SEP(node_id, prop, Z_PINCTRL_STATE_PIN_INIT, ())}; + +#define Z_PINCTRL_STATE_PIN_CHILD_INIT(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, pinmux), \ + (DT_FOREACH_PROP_ELEM(node_id, pinmux, Z_PINCTRL_PINMUX_INIT)), \ + ()) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, pins), \ + (DT_FOREACH_PROP_ELEM(node_id, pins, Z_PINCTRL_SPECIAL_PINS_INIT)), \ + ()) + +#define RZG_GET_PORT_PIN(pinmux) (pinmux & ~(0xF << 4)) +#define RZG_GET_FUNC(pinmux) ((pinmux & 0xF0) >> 4) + +#define RZG_GET_PU_PD(node_id) \ + DT_PROP(node_id, bias_pull_up) == 1 ? 1U : (DT_PROP(node_id, bias_pull_down) == 1 ? 2U : 0U) + +#define RZG_GET_FILNUM(node_id) ((DT_PROP(node_id, renesas_filter) >> 2) & 0x3) + +#define RZG_GET_FILCLKSEL(node_id) (DT_PROP(node_id, renesas_filter) & 0x3) + +#define RZG_FILTER_ON_OFF(node_id) COND_CODE_0(DT_PROP(node_id, renesas_filter), (0), (1)) + +/* Process pinmux cfg */ +#define Z_PINCTRL_PINMUX_INIT(node_id, state_prop, idx) \ + { \ + .port_pin = RZG_GET_PORT_PIN(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ + .config = \ + { \ + .reserved = 0, \ + .pupd_reg = RZG_GET_PU_PD(node_id), \ + .iolh_reg = DT_PROP(node_id, drive_strength), \ + .pmc_reg = 1, \ + .ien_reg = DT_PROP(node_id, input_enable), \ + .filonoff_reg = RZG_FILTER_ON_OFF(node_id), \ + .filnum_reg = RZG_GET_FILNUM(node_id), \ + .filclksel_reg = RZG_GET_FILCLKSEL(node_id), \ + .pfc_reg = \ + (RZG_GET_FUNC(DT_PROP_BY_IDX(node_id, state_prop, idx)) - \ + 1), \ + }, \ + }, + +#define Z_PINCTRL_SPECIAL_PINS_INIT(node_id, state_prop, idx) \ + { \ + .port_pin = DT_PROP_BY_IDX(node_id, state_prop, idx), \ + .config = \ + { \ + .reserved = 0, \ + .pupd_reg = RZG_GET_PU_PD(node_id), \ + .iolh_reg = DT_PROP(node_id, drive_strength), \ + .pmc_reg = 0, \ + .ien_reg = DT_PROP(node_id, input_enable), \ + .filonoff_reg = RZG_FILTER_ON_OFF(node_id), \ + .filnum_reg = RZG_GET_FILNUM(node_id), \ + .filclksel_reg = RZG_GET_FILCLKSEL(node_id), \ + .pfc_reg = 0, \ + }, \ + }, + +#ifdef __cplusplus +} +#endif +#endif /*ZEPHYR_SOC_RENESAS_RZ_COMMON_PINCTRL_RZG_H_*/ diff --git a/soc/renesas/rz/rzg3s/CMakeLists.txt b/soc/renesas/rz/rzg3s/CMakeLists.txt new file mode 100644 index 0000000000000..2db47f0bb7946 --- /dev/null +++ b/soc/renesas/rz/rzg3s/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc.c) + +zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/rz/rzg3s/Kconfig b/soc/renesas/rz/rzg3s/Kconfig new file mode 100644 index 0000000000000..15eaa95f17809 --- /dev/null +++ b/soc/renesas/rz/rzg3s/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2024 EPAM Systems +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RZG3S + select ARM + select CPU_CORTEX_M33 + select CPU_HAS_ARM_MPU + select HAS_RENESAS_RZ_FSP + select CPU_CORTEX_M_HAS_DWT + select SOC_EARLY_INIT_HOOK diff --git a/soc/renesas/rz/rzg3s/Kconfig.defconfig b/soc/renesas/rz/rzg3s/Kconfig.defconfig new file mode 100644 index 0000000000000..77439d92b82a0 --- /dev/null +++ b/soc/renesas/rz/rzg3s/Kconfig.defconfig @@ -0,0 +1,29 @@ +# Copyright (c) 2024 EPAM Systems +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RZG3S + +config NUM_IRQS + default 480 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +config FLASH_SIZE + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0,K) + +config FLASH_BASE_ADDRESS + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) + +config SYS_CLOCK_EXISTS + default y + +# This is required to support debug with xSPI boot when Zephyr already booted by TF-A +config INIT_ARCH_HW_AT_BOOT + default y + +config BUILD_OUTPUT_S19 + default y + +endif # SOC_SERIES_RZG3S diff --git a/soc/renesas/rz/rzg3s/Kconfig.soc b/soc/renesas/rz/rzg3s/Kconfig.soc new file mode 100644 index 0000000000000..dc65a2303ed25 --- /dev/null +++ b/soc/renesas/rz/rzg3s/Kconfig.soc @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RZG3S + bool + select SOC_FAMILY_RENESAS_RZ + help + Renesas RZ/G3S series + +config SOC_SERIES + default "rzg3s" if SOC_SERIES_RZG3S + +config SOC_R9A08G045S33GBG + bool + select SOC_SERIES_RZG3S + help + R9A08G045S33GBG + +config SOC_R9A08G045S33GBG_CM33 + bool + select SOC_R9A08G045S33GBG + +config SOC + default "r9a08g045s33gbg" if SOC_R9A08G045S33GBG diff --git a/soc/renesas/rz/rzg3s/pinctrl_soc.h b/soc/renesas/rz/rzg3s/pinctrl_soc.h new file mode 100644 index 0000000000000..8ce37a9d7a89d --- /dev/null +++ b/soc/renesas/rz/rzg3s/pinctrl_soc.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_RENESAS_RZ_RZG3S_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RZ_RZG3S_PINCTRL_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RZ_RZG3S_PINCTRL_SOC_H_ */ diff --git a/soc/renesas/rz/rzg3s/soc.c b/soc/renesas/rz/rzg3s/soc.c new file mode 100644 index 0000000000000..a263b91b28387 --- /dev/null +++ b/soc/renesas/rz/rzg3s/soc.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Renesas RZ/G3S Group + */ + +#include +#include + +/* System core clock is set to 250 MHz by IPL of A55 */ +uint32_t SystemCoreClock = 250000000; + +void soc_early_init_hook(void) +{ + bsp_clock_init(); + + /* This delay is required to wait for the A55 to complete its setting first before */ + /* UART initialization of M33 */ + R_BSP_SoftwareDelay(CONFIG_UART_RENESAS_RZG_INIT_DELAY_MS, BSP_DELAY_UNITS_MILLISECONDS); +} diff --git a/soc/renesas/rz/rzg3s/soc.h b/soc/renesas/rz/rzg3s/soc.h new file mode 100644 index 0000000000000..1d2a2d05cfd18 --- /dev/null +++ b/soc/renesas/rz/rzg3s/soc.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_RENESAS_RZG3S_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RZG3S_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RZG3S_SOC_H_ */ diff --git a/soc/renesas/rz/soc.yml b/soc/renesas/rz/soc.yml new file mode 100644 index 0000000000000..3cc8edd8baf78 --- /dev/null +++ b/soc/renesas/rz/soc.yml @@ -0,0 +1,8 @@ +family: + - name: renesas_rz + series: + - name: rzg3s + socs: + - name: r9a08g045s33gbg + cpuclusters: + - name: cm33 diff --git a/soc/rockchip/rk35/CMakeLists.txt b/soc/rockchip/rk35/CMakeLists.txt new file mode 100644 index 0000000000000..b45e8592a61da --- /dev/null +++ b/soc/rockchip/rk35/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2024 Université Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_RK3568) + add_subdirectory(rk3568) +elseif(CONFIG_SOC_RK3588S) + add_subdirectory(rk3588s) +endif() diff --git a/soc/rockchip/rk35/Kconfig b/soc/rockchip/rk35/Kconfig new file mode 100644 index 0000000000000..80f0d67eb4d94 --- /dev/null +++ b/soc/rockchip/rk35/Kconfig @@ -0,0 +1,11 @@ +# +# Copyright 2021 Huawei France Technologies SASU +# +# SPDX-License-Identifier: Apache-2.0 +# + +if SOC_FAMILY_ROCKCHIP + +rsource "*/Kconfig" + +endif # SOC_FAMILY_ROCKCHIP diff --git a/soc/rockchip/rk35/Kconfig.defconfig b/soc/rockchip/rk35/Kconfig.defconfig new file mode 100644 index 0000000000000..122e92dc99996 --- /dev/null +++ b/soc/rockchip/rk35/Kconfig.defconfig @@ -0,0 +1,11 @@ +# +# Copyright 2021 Huawei France Technologies SASU +# +# SPDX-License-Identifier: Apache-2.0 +# + +if SOC_FAMILY_ROCKCHIP + +rsource "*/Kconfig.defconfig" + +endif diff --git a/soc/rockchip/rk35/Kconfig.soc b/soc/rockchip/rk35/Kconfig.soc new file mode 100644 index 0000000000000..5c3276841f812 --- /dev/null +++ b/soc/rockchip/rk35/Kconfig.soc @@ -0,0 +1,11 @@ +# Copyright 2024 Université Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RK35 + bool + select SOC_FAMILY_ROCKCHIP + +config SOC_SERIES + default "rk35" if SOC_SERIES_RK35 + +rsource "*/Kconfig.soc" diff --git a/soc/rockchip/rk3568/CMakeLists.txt b/soc/rockchip/rk35/rk3568/CMakeLists.txt similarity index 100% rename from soc/rockchip/rk3568/CMakeLists.txt rename to soc/rockchip/rk35/rk3568/CMakeLists.txt diff --git a/soc/rockchip/rk35/rk3568/Kconfig b/soc/rockchip/rk35/rk3568/Kconfig new file mode 100644 index 0000000000000..e29f96c8c7794 --- /dev/null +++ b/soc/rockchip/rk35/rk3568/Kconfig @@ -0,0 +1,11 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +config SOC_RK3568 + select ARM64 + select CPU_CORTEX_A55 + select ARM_ARCH_TIMER + +config SOC_PART_NUMBER + default "RK3568" if SOC_RK3568 diff --git a/soc/rockchip/rk35/rk3568/Kconfig.defconfig b/soc/rockchip/rk35/rk3568/Kconfig.defconfig new file mode 100644 index 0000000000000..28b62874a3d43 --- /dev/null +++ b/soc/rockchip/rk35/rk3568/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +if SOC_RK3568 + +rsource "Kconfig.defconfig.rk3568" + +endif # SOC_SERIES_RK3568 diff --git a/soc/rockchip/rk3568/Kconfig.defconfig.rk3568 b/soc/rockchip/rk35/rk3568/Kconfig.defconfig.rk3568 similarity index 100% rename from soc/rockchip/rk3568/Kconfig.defconfig.rk3568 rename to soc/rockchip/rk35/rk3568/Kconfig.defconfig.rk3568 diff --git a/soc/rockchip/rk35/rk3568/Kconfig.soc b/soc/rockchip/rk35/rk3568/Kconfig.soc new file mode 100644 index 0000000000000..1acf4d0ffe47d --- /dev/null +++ b/soc/rockchip/rk35/rk3568/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright 2022 HNU-ESNL +# Copyright 2022 openEuler SIG-Zephyr +# SPDX-License-Identifier: Apache-2.0 + +config SOC_RK3568 + bool + select SOC_SERIES_RK35 + +config SOC + default "rk3568" if SOC_RK3568 diff --git a/soc/rockchip/rk3568/mmu_regions.c b/soc/rockchip/rk35/rk3568/mmu_regions.c similarity index 100% rename from soc/rockchip/rk3568/mmu_regions.c rename to soc/rockchip/rk35/rk3568/mmu_regions.c diff --git a/soc/rockchip/rk35/rk3588s/CMakeLists.txt b/soc/rockchip/rk35/rk3588s/CMakeLists.txt new file mode 100644 index 0000000000000..667a960e91b7b --- /dev/null +++ b/soc/rockchip/rk35/rk3588s/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright 2024 Université Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/rockchip/rk35/rk3588s/Kconfig b/soc/rockchip/rk35/rk3588s/Kconfig new file mode 100644 index 0000000000000..edd700a9a9e4e --- /dev/null +++ b/soc/rockchip/rk35/rk3588s/Kconfig @@ -0,0 +1,10 @@ +# Copyright 2024 Université Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +config SOC_RK3588S + select ARM64 + select CPU_CORTEX_A55 + select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS + +config SOC_PART_NUMBER + default "RK3588S" if SOC_RK3588S diff --git a/soc/rockchip/rk35/rk3588s/Kconfig.defconfig b/soc/rockchip/rk35/rk3588s/Kconfig.defconfig new file mode 100644 index 0000000000000..f056f362aac14 --- /dev/null +++ b/soc/rockchip/rk35/rk3588s/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright 2024 Université Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +if SOC_RK3588S + +rsource "Kconfig.defconfig.rk3588s" + +endif # SOC_RK3588S diff --git a/soc/rockchip/rk35/rk3588s/Kconfig.defconfig.rk3588s b/soc/rockchip/rk35/rk3588s/Kconfig.defconfig.rk3588s new file mode 100644 index 0000000000000..fe40d7884687a --- /dev/null +++ b/soc/rockchip/rk35/rk3588s/Kconfig.defconfig.rk3588s @@ -0,0 +1,19 @@ +# Copyright 2024 Université Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +if SOC_RK3588S + +config NUM_IRQS + default 544 + +config FLASH_SIZE + default 0 + +config FLASH_BASE_ADDRESS + default 0 + +config UART_NS16550_ACCESS_WORD_ONLY + default y + depends on UART_NS16550 + +endif diff --git a/soc/rockchip/rk35/rk3588s/Kconfig.soc b/soc/rockchip/rk35/rk3588s/Kconfig.soc new file mode 100644 index 0000000000000..3dcf0bc6e8144 --- /dev/null +++ b/soc/rockchip/rk35/rk3588s/Kconfig.soc @@ -0,0 +1,9 @@ +# Copyright 2024 Université Gustave Eiffel +# SPDX-License-Identifier: Apache-2.0 + +config SOC_RK3588S + bool + select SOC_SERIES_RK35 + +config SOC + default "rk3588s" if SOC_RK3588S diff --git a/soc/rockchip/rk35/rk3588s/mmu_regions.c b/soc/rockchip/rk35/rk3588s/mmu_regions.c new file mode 100644 index 0000000000000..f33dce56c6390 --- /dev/null +++ b/soc/rockchip/rk35/rk3588s/mmu_regions.c @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Université Gustave Eiffel + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static const struct arm_mmu_region mmu_regions[] = { + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 0), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; diff --git a/soc/rockchip/rk3568/Kconfig b/soc/rockchip/rk3568/Kconfig deleted file mode 100644 index b5b046b04306a..0000000000000 --- a/soc/rockchip/rk3568/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2022 HNU-ESNL -# Copyright 2022 openEuler SIG-Zephyr -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RK3568 - select ARM64 - select CPU_CORTEX_A55 - select ARM_ARCH_TIMER - -config SOC_PART_NUMBER - default "RK3568" if SOC_SERIES_RK3568 diff --git a/soc/rockchip/rk3568/Kconfig.defconfig b/soc/rockchip/rk3568/Kconfig.defconfig deleted file mode 100644 index b7f52249abe26..0000000000000 --- a/soc/rockchip/rk3568/Kconfig.defconfig +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2022 HNU-ESNL -# Copyright 2022 openEuler SIG-Zephyr -# SPDX-License-Identifier: Apache-2.0 - -if SOC_SERIES_RK3568 - -rsource "Kconfig.defconfig.rk3568" - -endif # SOC_SERIES_RK3568 diff --git a/soc/rockchip/rk3568/Kconfig.soc b/soc/rockchip/rk3568/Kconfig.soc deleted file mode 100644 index 7d965d764cbcc..0000000000000 --- a/soc/rockchip/rk3568/Kconfig.soc +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2022 HNU-ESNL -# Copyright 2022 openEuler SIG-Zephyr -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RK3568 - bool - select SOC_FAMILY_ROCKCHIP - -config SOC_RK3568 - bool - select SOC_SERIES_RK3568 - -config SOC - default "rk3568" if SOC_RK3568 - -config SOC_SERIES - default "rk3568" if SOC_RK3568 diff --git a/soc/rockchip/soc.yml b/soc/rockchip/soc.yml index 5568a11aa49ae..777bd05a9d3c0 100644 --- a/soc/rockchip/soc.yml +++ b/soc/rockchip/soc.yml @@ -4,6 +4,7 @@ family: - name: rk3399 socs: - name: rk3399 - - name: rk3568 + - name: rk35 socs: + - name: rk3588s - name: rk3568 diff --git a/soc/sensry/ganymed/sy1xx/common/pinctrl_soc.h b/soc/sensry/ganymed/sy1xx/common/pinctrl_soc.h new file mode 100644 index 0000000000000..5a124fa0783e6 --- /dev/null +++ b/soc/sensry/ganymed/sy1xx/common/pinctrl_soc.h @@ -0,0 +1,72 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 sensry.io + */ + +#ifndef GANYMED_SY1XX_PINCTRL_SOC_H +#define GANYMED_SY1XX_PINCTRL_SOC_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SY1XX_SCHMITT_ENABLE 1U +#define SY1XX_PULL_UP_ENABLE 1U +#define SY1XX_PULL_DOWN_ENABLE 1U +#define SY1XX_TRISTATE_ENABLE 1U +#define SY1XX_OUTPUT_ENABLE 1U + +#define SY1XX_PAD_SCHMITT_OFFS 7 +#define SY1XX_PAD_PULL_UP_OFFS 5 +#define SY1XX_PAD_PULL_DOWN_OFFS 4 +#define SY1XX_PAD_DRIVE_OFFS 2 +#define SY1XX_PAD_TRISTATE_OFFS 1 +#define SY1XX_PAD_DIR_OFFS 0 + +/** Type for SY1XX pin. */ +typedef struct { + /** address of pin config register */ + uint32_t addr; + /** intra register offset (8bit cfg per pin) */ + uint32_t iro; + /** config for pin (8bit), describes pull-up/down, ... */ + uint32_t cfg; +} pinctrl_soc_pin_t; + +#define Z_PINCTRL_CFG(node) \ + ( \ + \ + (SY1XX_SCHMITT_ENABLE * DT_PROP(node, input_schmitt_enable)) \ + << SY1XX_PAD_SCHMITT_OFFS | \ + (SY1XX_PULL_UP_ENABLE * DT_PROP(node, bias_pull_up)) << SY1XX_PAD_PULL_UP_OFFS | \ + (SY1XX_PULL_DOWN_ENABLE * DT_PROP(node, bias_pull_down)) \ + << SY1XX_PAD_PULL_DOWN_OFFS | \ + (SY1XX_TRISTATE_ENABLE * DT_PROP(node, bias_high_impedance)) \ + << SY1XX_PAD_TRISTATE_OFFS | \ + (SY1XX_OUTPUT_ENABLE & (1 - DT_PROP(node, input_enable))) << SY1XX_PAD_DIR_OFFS \ + \ + ) + +#define Z_PINCTRL_STATE_PIN_INIT(node, pr, idx) \ + { \ + \ + .addr = DT_PROP_BY_IDX(DT_PHANDLE_BY_IDX(node, pr, idx), pinmux, 0), \ + .iro = DT_PROP_BY_IDX(DT_PHANDLE_BY_IDX(node, pr, idx), pinmux, 1), \ + .cfg = Z_PINCTRL_CFG(DT_PHANDLE_BY_IDX(node, pr, idx)) \ + \ + }, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { \ + DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT) \ + } + +#ifdef __cplusplus +} +#endif + +#endif /* GANYMED_SY1XX_PINCTRL_SOC_H */ diff --git a/soc/silabs/CMakeLists.txt b/soc/silabs/CMakeLists.txt index d173ecfec669c..bce90b74766fe 100644 --- a/soc/silabs/CMakeLists.txt +++ b/soc/silabs/CMakeLists.txt @@ -1,8 +1,11 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) 2017 Christian Taedcke -add_subdirectory(common) +zephyr_include_directories(${SOC_FAMILY}) zephyr_include_directories(${SOC_FAMILY}/${SOC_SERIES}) -add_subdirectory_ifdef(CONFIG_SOC_FAMILY_SILABS_S2 silabs_s2) -add_subdirectory_ifdef(CONFIG_SOC_SERIES_SIM3U silabs_sim3/sim3u) +add_subdirectory(common) + +add_subdirectory_ifdef(CONFIG_SOC_FAMILY_SILABS_S2 silabs_s2) +add_subdirectory_ifdef(CONFIG_SOC_FAMILY_SILABS_SIWX91X silabs_siwx91x) +add_subdirectory_ifdef(CONFIG_SOC_SERIES_SIM3U silabs_sim3/sim3u) diff --git a/soc/silabs/Kconfig b/soc/silabs/Kconfig index e1474623154a4..dcf8de541c63c 100644 --- a/soc/silabs/Kconfig +++ b/soc/silabs/Kconfig @@ -23,6 +23,11 @@ config SOC_GECKO_CORE help Set if the Core interrupt handling (CORE) HAL module is used. +config SOC_SILABS_ACMP + bool + help + Set if the Analog comparator (ACMP) HAL module is used. + config SOC_GECKO_ADC bool help @@ -64,6 +69,11 @@ config SOC_GECKO_LEUART Set if the Low Energy Universal Asynchronous Receiver/Transmitter (LEUART) HAL module is used. +config SOC_GECKO_LDMA + bool + help + Set if the Linked Direct Memory Access (LDMA) HAL module is used. + config SOC_GECKO_MSC bool help @@ -124,7 +134,7 @@ config SOC_GECKO_TRNG config SOC_SILABS_SLEEPTIMER bool select SOC_GECKO_PRS - select SOC_GECKO_RTCC if SOC_SERIES_EFR32BG22 || SOC_SERIES_EFR32BG27 || SOC_SERIES_EFR32MG21 + select SOC_GECKO_RTCC if SOC_FAMILY_SILABS_S2 && $(dt_nodelabel_enabled,rtcc0) help Set if the Sleeptimer HAL module is used. @@ -203,7 +213,7 @@ config SOC_GECKO_CMU help Set if the clock management unit (CMU) is present in the SoC. -if SOC_GECKO_CMU +if SOC_GECKO_CMU && (SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1) config CMU_NEED_LFXO bool diff --git a/soc/silabs/Kconfig.defconfig b/soc/silabs/Kconfig.defconfig index 5c55a394c687c..aaf363576f8ec 100644 --- a/soc/silabs/Kconfig.defconfig +++ b/soc/silabs/Kconfig.defconfig @@ -19,4 +19,7 @@ config CORTEX_M_SYSTICK config IDLE_STACK_SIZE default 512 if SOC_GECKO_PM_BACKEND_PMGR +configdefault NUM_METAIRQ_PRIORITIES + default 1 if BT_SILABS_EFR32 + endif diff --git a/soc/silabs/Kconfig.soc b/soc/silabs/Kconfig.soc index 7b1174c686442..099b50d751d04 100644 --- a/soc/silabs/Kconfig.soc +++ b/soc/silabs/Kconfig.soc @@ -5,6 +5,7 @@ config SOC_FAMILY default "silabs_s0" if SOC_FAMILY_SILABS_S0 default "silabs_s1" if SOC_FAMILY_SILABS_S1 default "silabs_s2" if SOC_FAMILY_SILABS_S2 + default "silabs_siwx91x" if SOC_FAMILY_SILABS_SIWX91X default "silabs_sim3" if SOC_FAMILY_SILABS_SIM3 rsource "*/Kconfig.soc" diff --git a/soc/silabs/common/pinctrl_soc.h b/soc/silabs/common/pinctrl_soc.h index 82592eafcf59d..9b4d27c9a54fd 100644 --- a/soc/silabs/common/pinctrl_soc.h +++ b/soc/silabs/common/pinctrl_soc.h @@ -73,14 +73,30 @@ typedef struct pinctrl_soc_pin { .en_bit = \ (FIELD_GET(SILABS_PINCTRL_HAVE_EN_MASK, DT_PROP_BY_IDX(node, prop, idx)) \ ? FIELD_GET(SILABS_PINCTRL_EN_BIT_MASK, DT_PROP_BY_IDX(node, prop, idx)) \ - : 0xFF), \ + : SILABS_PINCTRL_UNUSED), \ .route_offset = FIELD_GET(SILABS_PINCTRL_ROUTE_MASK, DT_PROP_BY_IDX(node, prop, idx)), \ .mode = Z_PINCTRL_SILABS_MODE_INIT(node), \ .dout = Z_PINCTRL_SILABS_DOUT_INIT(node)}, +#define Z_PINCTRL_STATE_ABUS_INIT(node, prop, idx) \ + { \ + .base_offset = \ + FIELD_GET(SILABS_PINCTRL_ABUS_BUS_MASK, DT_PROP_BY_IDX(node, prop, idx)), \ + .route_offset = FIELD_GET(SILABS_PINCTRL_ABUS_PERIPH_MASK, \ + DT_PROP_BY_IDX(node, prop, idx)), \ + .en_bit = SILABS_PINCTRL_ANALOG, \ + .mode = FIELD_GET(SILABS_PINCTRL_ABUS_PARITY_MASK, \ + DT_PROP_BY_IDX(node, prop, idx)), \ + }, + +#define Z_PINCTRL_SILABS_DISPATCH(group) \ + IF_ENABLED(DT_NODE_HAS_PROP(group, pins), \ + (DT_FOREACH_PROP_ELEM(group, pins, Z_PINCTRL_STATE_PIN_INIT))) \ + IF_ENABLED(DT_NODE_HAS_PROP(group, silabs_analog_bus), \ + (DT_FOREACH_PROP_ELEM(group, silabs_analog_bus, Z_PINCTRL_STATE_ABUS_INIT))) + #define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ - {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pins, \ - Z_PINCTRL_STATE_PIN_INIT)} + {DT_FOREACH_CHILD(DT_PHANDLE(node_id, prop), Z_PINCTRL_SILABS_DISPATCH)} #else diff --git a/soc/silabs/common/soc_power_pmgr.c b/soc/silabs/common/soc_power_pmgr.c index 1980c95a56b5d..402701c1c2397 100644 --- a/soc/silabs/common/soc_power_pmgr.c +++ b/soc/silabs/common/soc_power_pmgr.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); @@ -46,31 +48,25 @@ void pm_state_set(enum pm_state state, uint8_t substate_id) break; } - /* FIXME: When this function is entered the Kernel has disabled - * interrupts using BASEPRI register. This is incorrect as it prevents - * waking up from any interrupt which priority is not 0. Work around the - * issue and disable interrupts using PRIMASK register as recommended - * by ARM. - */ - - /* Set PRIMASK */ - __disable_irq(); - /* Set BASEPRI to 0 */ - irq_unlock(0); - LOG_DBG("Entry to energy mode %d", energy_mode); - if (energy_mode != SL_POWER_MANAGER_EM0) { + if (energy_mode == SL_POWER_MANAGER_EM4) { + sl_power_manager_enter_em4(); + } else if (energy_mode != SL_POWER_MANAGER_EM0) { + /* Calling the tracing and hook functions provided in arch_cpu_idle(). */ +#if defined(CONFIG_TRACING) + sys_trace_idle(); +#endif +#if CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK + z_arm_on_enter_cpu_idle_prepare(); +#endif + sl_power_manager_add_em_requirement(energy_mode); sl_power_manager_sleep(); - k_cpu_idle(); sl_power_manager_remove_em_requirement(energy_mode); } LOG_DBG("Exit from energy mode %d", energy_mode); - - /* Clear PRIMASK */ - __enable_irq(); } void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) @@ -79,6 +75,33 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) ARG_UNUSED(substate_id); } +/* This function is called by sl_power_manager_sleep() after it has set the PRIMASK. */ +bool sl_power_manager_is_ok_to_sleep(void) +{ + /* FIXME: When this function is entered the Kernel has disabled + * interrupts using BASEPRI register. This is incorrect as it prevents + * waking up from any interrupt which priority is not 0. Work around the + * issue and disable interrupts using PRIMASK register as recommended + * by ARM. + */ + /* Set BASEPRI to 0. */ + irq_unlock(0); + + return true; +} + +/* This function is called by sl_power_manager_sleep() right after it was woken up from WFI. */ +void sli_power_manager_on_wakeup(void) +{ +#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON) + /* Handle the HFXO IRQ as soon as possible to retrieve the startup time. */ + sl_hfxo_manager_irq_handler(); +#endif + /* Forces a clock restore before handling interrupts. */ + sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1); + sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1); +} + /** * Some SiLabs blobs, such as RAIL, call directly into sl_power_manager, and * for that they had to include sl_power_manager.h during build. Some of those diff --git a/soc/silabs/silabs_s2/Kconfig.defconfig b/soc/silabs/silabs_s2/Kconfig.defconfig index d7dec5deb3df8..9bea631fe7924 100644 --- a/soc/silabs/silabs_s2/Kconfig.defconfig +++ b/soc/silabs/silabs_s2/Kconfig.defconfig @@ -18,4 +18,17 @@ config SILABS_SLEEPTIMER_TIMER config CORTEX_M_SYSTICK default n if SILABS_SLEEPTIMER_TIMER || GECKO_BURTC_TIMER +# silabs_s2 uses simplicity_sdk hal library, which already have by default a zero latency +# IRQs mechanism with a hardcoded value. In order to be aligned with simplicity_sdk, we +# need to activate Zero Latency IRQ in Zephyr by default. The level (2) depends on the +# hardcoded value in simplicity_sdk (CORE_ATOMIC_BASE_PRIORITY_LEVEL). Without this config, +# if you use an IRQ with a priority of 0 or 1, irq_lock() and irq_unlock() have no effect +# over this IRQ. + +config ZERO_LATENCY_IRQS + default y + +config ZERO_LATENCY_LEVELS + default 2 + endif diff --git a/soc/silabs/silabs_s2/efr32bg22/Kconfig b/soc/silabs/silabs_s2/efr32bg22/Kconfig index fcecbbbc3e8c2..5ac51ff898a39 100644 --- a/soc/silabs/silabs_s2/efr32bg22/Kconfig +++ b/soc/silabs/silabs_s2/efr32bg22/Kconfig @@ -9,7 +9,7 @@ config SOC_SERIES_EFR32BG22 select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU select CPU_HAS_FPU - select HAS_SILABS_GECKO + select HAS_SILABS_SISDK select HAS_SWO select SOC_GECKO_HAS_RADIO select SOC_GECKO_GPIO diff --git a/soc/silabs/silabs_s2/efr32bg22/soc.h b/soc/silabs/silabs_s2/efr32bg22/soc.h deleted file mode 100644 index 7591b111ad287..0000000000000 --- a/soc/silabs/silabs_s2/efr32bg22/soc.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2021 Sateesh Kotapati - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Register access macros for the EFR32BG22 SoC - * - */ - -#ifndef EFR32BG22_SOC_H_ -#define EFR32BG22_SOC_H_ - -#ifndef _ASMLANGUAGE - -#include -#include "../common/soc_gpio.h" - -#endif /* !_ASMLANGUAGE */ - -#endif /* EFR32BG22_SOC_H_ */ diff --git a/soc/silabs/silabs_s2/efr32bg27/Kconfig b/soc/silabs/silabs_s2/efr32bg27/Kconfig index 7431fbecb6801..36353d045046c 100644 --- a/soc/silabs/silabs_s2/efr32bg27/Kconfig +++ b/soc/silabs/silabs_s2/efr32bg27/Kconfig @@ -9,7 +9,7 @@ config SOC_SERIES_EFR32BG27 select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU select CPU_HAS_FPU - select HAS_SILABS_GECKO + select HAS_SILABS_SISDK select HAS_SWO select SOC_GECKO_HAS_RADIO select SOC_GECKO_CMU diff --git a/soc/silabs/silabs_s2/efr32bg27/soc.h b/soc/silabs/silabs_s2/efr32bg27/soc.h deleted file mode 100644 index b1974d02c00b2..0000000000000 --- a/soc/silabs/silabs_s2/efr32bg27/soc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (c) 2023 Antmicro - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Register access macros for the EFR32BG27 SoC - */ - -#ifndef EFR32BG27_SOC_H_ -#define EFR32BG27_SOC_H_ - -#ifndef _ASMLANGUAGE -#include -#include "../common/soc_gpio.h" -#endif /* _ASMLANGUAGE */ - -#endif /* EFR32BG27_SOC_H_ */ diff --git a/soc/silabs/silabs_s2/efr32mg21/Kconfig b/soc/silabs/silabs_s2/efr32mg21/Kconfig index db3f7e6ae66e7..0cbeb648461a9 100644 --- a/soc/silabs/silabs_s2/efr32mg21/Kconfig +++ b/soc/silabs/silabs_s2/efr32mg21/Kconfig @@ -11,7 +11,7 @@ config SOC_SERIES_EFR32MG21 select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU select SOC_GECKO_HAS_RADIO - select HAS_SILABS_GECKO + select HAS_SILABS_SISDK select HAS_SWO select SOC_GECKO_CMU select SOC_GECKO_EMU diff --git a/soc/silabs/silabs_s2/efr32mg21/soc.h b/soc/silabs/silabs_s2/efr32mg21/soc.h deleted file mode 100644 index 90b93a0acd14d..0000000000000 --- a/soc/silabs/silabs_s2/efr32mg21/soc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2020 TriaGnoSys GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Board configuration macros for the EFR32MG21 SoC - * - */ - -#ifndef _SILABS_EFR32MG21_SOC_H -#define _SILABS_EFR32MG21_SOC_H - -#include - -#ifndef _ASMLANGUAGE - -#include - -#include "soc_pinmap.h" -#include "../common/soc_gpio.h" - - -#endif /* !_ASMLANGUAGE */ - -#endif /* _SILABS_EFR32MG21_SOC_H */ diff --git a/soc/silabs/silabs_s2/efr32mg24/Kconfig b/soc/silabs/silabs_s2/efr32mg24/Kconfig index 1412bc95629b3..8b8df640a8bf8 100644 --- a/soc/silabs/silabs_s2/efr32mg24/Kconfig +++ b/soc/silabs/silabs_s2/efr32mg24/Kconfig @@ -11,7 +11,7 @@ config SOC_SERIES_EFR32MG24 select ARMV8_M_DSP select ARM_TRUSTZONE_M select SOC_GECKO_HAS_RADIO - select HAS_SILABS_GECKO + select HAS_SILABS_SISDK select HAS_SWO select SOC_GECKO_CMU select SOC_GECKO_EMU diff --git a/soc/silabs/silabs_s2/efr32mg24/Kconfig.soc b/soc/silabs/silabs_s2/efr32mg24/Kconfig.soc index 630441964726e..cfac8c2bf446f 100644 --- a/soc/silabs/silabs_s2/efr32mg24/Kconfig.soc +++ b/soc/silabs/silabs_s2/efr32mg24/Kconfig.soc @@ -19,15 +19,21 @@ config SOC_PART_NUMBER_EFR32MG24B310F1536IM48 bool select SOC_SERIES_EFR32MG24 +config SOC_PART_NUMBER_EFR32MG24B210F1536IM48 + bool + select SOC_SERIES_EFR32MG24 + config SOC_SERIES default "efr32mg24" if SOC_SERIES_EFR32MG24 config SOC default "efr32mg24b220f1536im48" if SOC_PART_NUMBER_EFR32MG24B220F1536IM48 default "efr32mg24b310f1536im48" if SOC_PART_NUMBER_EFR32MG24B310F1536IM48 + default "efr32mg24b210f1536im48" if SOC_PART_NUMBER_EFR32MG24B210F1536IM48 default "efr32mg24b020f1536im40" if SOC_PART_NUMBER_EFR32MG24B020F1536IM40 config SOC_PART_NUMBER default "EFR32MG24B220F1536IM48" if SOC_PART_NUMBER_EFR32MG24B220F1536IM48 default "EFR32MG24B310F1536IM48" if SOC_PART_NUMBER_EFR32MG24B310F1536IM48 + default "EFR32MG24B210F1536IM48" if SOC_PART_NUMBER_EFR32MG24B210F1536IM48 default "EFR32MG24B020F1536IM40" if SOC_PART_NUMBER_EFR32MG24B020F1536IM40 diff --git a/soc/silabs/silabs_s2/efr32mg24/soc.h b/soc/silabs/silabs_s2/efr32mg24/soc.h deleted file mode 100644 index 210526c11099b..0000000000000 --- a/soc/silabs/silabs_s2/efr32mg24/soc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2020 TriaGnoSys GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief Board configuration macros for the EFR32MG24 SoC - * - */ - -#ifndef _SILABS_EFR32MG24_SOC_H -#define _SILABS_EFR32MG24_SOC_H - -#include - -#ifndef _ASMLANGUAGE - -#include - -#include "soc_pinmap.h" -#include "../common/soc_gpio.h" - -/* Add include for DTS generated information */ -#include - -#endif /* !_ASMLANGUAGE */ - -#endif /* _SILABS_EFR32MG24_SOC_H */ diff --git a/soc/silabs/silabs_s2/efr32zg23/Kconfig b/soc/silabs/silabs_s2/efr32zg23/Kconfig new file mode 100644 index 0000000000000..1e645eb8d23a0 --- /dev/null +++ b/soc/silabs/silabs_s2/efr32zg23/Kconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Yishai Jaffe +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_EFR32ZG23 + select ARM + select ARMV8_M_DSP + select ARM_TRUSTZONE_M + select CPU_CORTEX_M33 + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + select CPU_HAS_FPU + select HAS_PM + select HAS_SILABS_SISDK + select HAS_SWO + select SOC_GECKO_CMU + select SOC_GECKO_CORE + select SOC_GECKO_DEV_INIT + select SOC_GECKO_EMU + select SOC_GECKO_GPIO + select SOC_GECKO_HAS_RADIO + select SOC_GECKO_SE + +config SOC_GECKO_SDID + default 210 if SOC_SERIES_EFR32ZG23 diff --git a/soc/silabs/silabs_s2/efr32zg23/Kconfig.defconfig b/soc/silabs/silabs_s2/efr32zg23/Kconfig.defconfig new file mode 100644 index 0000000000000..26eaef2f4f5f9 --- /dev/null +++ b/soc/silabs/silabs_s2/efr32zg23/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Yishai Jaffe +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_EFR32ZG23 + +config NUM_IRQS + # must be >= the highest interrupt number used + default 75 + +config PM + select UART_INTERRUPT_DRIVEN + +config GPIO_GECKO + default y + +endif diff --git a/soc/silabs/silabs_s2/efr32zg23/Kconfig.soc b/soc/silabs/silabs_s2/efr32zg23/Kconfig.soc new file mode 100644 index 0000000000000..02f6a8229e3f9 --- /dev/null +++ b/soc/silabs/silabs_s2/efr32zg23/Kconfig.soc @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Yishai Jaffe +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_EFR32ZG23 + bool + select SOC_FAMILY_SILABS_S2 + help + Silicon Labs EFR32ZG23 Series MCU + +config SOC_PART_NUMBER_EFR32ZG23B020F512IM48 + bool + select SOC_SERIES_EFR32ZG23 + +config SOC_SERIES + default "efr32zg23" if SOC_SERIES_EFR32ZG23 + +config SOC + default "efr32zg23b020f512im48" if SOC_PART_NUMBER_EFR32ZG23B020F512IM48 + +config SOC_PART_NUMBER + default "EFR32ZG23B020F512IM48" if SOC_PART_NUMBER_EFR32ZG23B020F512IM48 diff --git a/soc/silabs/silabs_s2/soc.h b/soc/silabs/silabs_s2/soc.h new file mode 100644 index 0000000000000..9933938e09f31 --- /dev/null +++ b/soc/silabs/silabs_s2/soc.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Register access macros for Silabs Series 2 SoCs + * + */ + +#ifndef SILABS_S2_SOC_H_ +#define SILABS_S2_SOC_H_ + +#ifndef _ASMLANGUAGE +#include +#endif + +#endif diff --git a/soc/silabs/silabs_s2/xg29/Kconfig b/soc/silabs/silabs_s2/xg29/Kconfig new file mode 100644 index 0000000000000..19f99079c1770 --- /dev/null +++ b/soc/silabs/silabs_s2/xg29/Kconfig @@ -0,0 +1,43 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_EFR32BG29 + select ARM + select CPU_CORTEX_M33 + select CPU_HAS_FPU + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + select CPU_CORTEX_M_HAS_DWT + select ARMV8_M_DSP + select ARM_TRUSTZONE_M + select SOC_GECKO_HAS_RADIO + select HAS_SILABS_SISDK + select HAS_SWO + select SOC_GECKO_CMU + select SOC_GECKO_EMU + select SOC_GECKO_GPIO + select SOC_GECKO_DEV_INIT + select SOC_GECKO_SE + select HAS_PM + +config SOC_SERIES_EFR32MG29 + select ARM + select CPU_CORTEX_M33 + select CPU_HAS_FPU + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + select CPU_CORTEX_M_HAS_DWT + select ARMV8_M_DSP + select ARM_TRUSTZONE_M + select SOC_GECKO_HAS_RADIO + select HAS_SILABS_SISDK + select HAS_SWO + select SOC_GECKO_CMU + select SOC_GECKO_EMU + select SOC_GECKO_GPIO + select SOC_GECKO_DEV_INIT + select SOC_GECKO_SE + select HAS_PM + +config SOC_GECKO_SDID + default 240 if SOC_SERIES_EFR32BG29 || SOC_SERIES_EFR32MG29 diff --git a/soc/silabs/silabs_s2/xg29/Kconfig.defconfig b/soc/silabs/silabs_s2/xg29/Kconfig.defconfig new file mode 100644 index 0000000000000..84949e8912c47 --- /dev/null +++ b/soc/silabs/silabs_s2/xg29/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_EFR32BG29 || SOC_SERIES_EFR32MG29 + +config NUM_IRQS + # must be >= the highest interrupt number used + default 70 + +config PM + default n + select UART_INTERRUPT_DRIVEN if SERIAL_SUPPORT_INTERRUPT + +choice PM_POLICY + default PM_POLICY_DEFAULT + depends on PM +endchoice + +endif diff --git a/soc/silabs/silabs_s2/xg29/Kconfig.soc b/soc/silabs/silabs_s2/xg29/Kconfig.soc new file mode 100644 index 0000000000000..f17bd7e503305 --- /dev/null +++ b/soc/silabs/silabs_s2/xg29/Kconfig.soc @@ -0,0 +1,58 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_EFR32BG29 + bool + select SOC_FAMILY_SILABS_S2 + help + Silicon Labs EFR32BG29 (Blue Gecko) Series MCU + +config SOC_SERIES_EFR32MG29 + bool + select SOC_FAMILY_SILABS_S2 + help + Silicon Labs EFR32MG29 (Mighty Gecko) Series MCU + +config SOC_PART_NUMBER_EFR32BG29B140F1024IM40 + bool + select SOC_SERIES_EFR32BG29 + +config SOC_PART_NUMBER_EFR32BG29B220F1024CJ45 + bool + select SOC_SERIES_EFR32BG29 + +config SOC_PART_NUMBER_EFR32BG29B221F1024CJ45 + bool + select SOC_SERIES_EFR32BG29 + +config SOC_PART_NUMBER_EFR32BG29B230F1024CM40 + bool + select SOC_SERIES_EFR32BG29 + +config SOC_PART_NUMBER_EFR32MG29B140F1024IM40 + bool + select SOC_SERIES_EFR32MG29 + +config SOC_PART_NUMBER_EFR32MG29B230F1024CM40 + bool + select SOC_SERIES_EFR32MG29 + +config SOC_SERIES + default "efr32bg29" if SOC_SERIES_EFR32BG29 + default "efr32mg29" if SOC_SERIES_EFR32MG29 + +config SOC + default "efr32bg29b140f1024im40" if SOC_PART_NUMBER_EFR32BG29B140F1024IM40 + default "efr32bg29b220f1024cj45" if SOC_PART_NUMBER_EFR32BG29B220F1024CJ45 + default "efr32bg29b221f1024cj45" if SOC_PART_NUMBER_EFR32BG29B221F1024CJ45 + default "efr32bg29b230f1024cm40" if SOC_PART_NUMBER_EFR32BG29B230F1024CM40 + default "efr32mg29b140f1024im40" if SOC_PART_NUMBER_EFR32MG29B140F1024IM40 + default "efr32mg29b230f1024cm40" if SOC_PART_NUMBER_EFR32MG29B230F1024CM40 + +config SOC_PART_NUMBER + default "EFR32BG29B140F1024IM40" if SOC_PART_NUMBER_EFR32BG29B140F1024IM40 + default "EFR32BG29B220F1024CJ45" if SOC_PART_NUMBER_EFR32BG29B220F1024CJ45 + default "EFR32BG29B221F1024CJ45" if SOC_PART_NUMBER_EFR32BG29B221F1024CJ45 + default "EFR32BG29B230F1024CM40" if SOC_PART_NUMBER_EFR32BG29B230F1024CM40 + default "EFR32MG29B140F1024IM40" if SOC_PART_NUMBER_EFR32MG29B140F1024IM40 + default "EFR32MG29B230F1024CM40" if SOC_PART_NUMBER_EFR32MG29B230F1024CM40 diff --git a/soc/silabs/silabs_siwx91x/CMakeLists.txt b/soc/silabs/silabs_siwx91x/CMakeLists.txt new file mode 100644 index 0000000000000..7e3a8c84a16c3 --- /dev/null +++ b/soc/silabs/silabs_siwx91x/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(siwg917) + +# Necessary to not overwrite NWP Firmware +math(EXPR FLASH_LOAD_ADDRESS "(${CONFIG_FLASH_BASE_ADDRESS}) + (${CONFIG_FLASH_LOAD_OFFSET})") + +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/siwx91x_isp_prepare.py + --load-addr ${FLASH_LOAD_ADDRESS} + ${KERNEL_BIN_NAME} + ${KERNEL_BIN_NAME}.rps +) diff --git a/soc/silabs/silabs_siwx91x/Kconfig b/soc/silabs/silabs_siwx91x/Kconfig new file mode 100644 index 0000000000000..a1f7371e9fb02 --- /dev/null +++ b/soc/silabs/silabs_siwx91x/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Antmicro +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_SILABS_SIWX91X + select ARM + select CPU_CORTEX_M4 + select CPU_HAS_FPU + select CPU_HAS_ARM_MPU + select HAS_SILABS_WISECONNECT + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE diff --git a/soc/silabs/silabs_siwx91x/Kconfig.defconfig b/soc/silabs/silabs_siwx91x/Kconfig.defconfig new file mode 100644 index 0000000000000..eeef3b6a75363 --- /dev/null +++ b/soc/silabs/silabs_siwx91x/Kconfig.defconfig @@ -0,0 +1,39 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_SILABS_SIWX91X + +config WISECONNECT_NETWORK_STACK + bool + select CMSIS_RTOS_V2 + select POLL + select DYNAMIC_THREAD + select THREAD_NAME + select THREAD_STACK_INFO + select THREAD_MONITOR + select INIT_STACKS + +if WISECONNECT_NETWORK_STACK + +# WiseConnect create threads with realtime priority. Default (10kHz) clock tick +# prevent proper use of the system with these threads. +config SYS_CLOCK_TICKS_PER_SEC + default 1024 + +config NUM_PREEMPT_PRIORITIES + default 56 + +config CMSIS_V2_THREAD_DYNAMIC_MAX_COUNT + default 2 + +config CMSIS_V2_THREAD_DYNAMIC_STACK_SIZE + default 1024 + +config CMSIS_V2_THREAD_MAX_STACK_SIZE + default 2048 + +endif # WISECONNECT_NETWORK_STACK + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_SILABS_SIWX91X diff --git a/soc/silabs/silabs_siwx91x/Kconfig.soc b/soc/silabs/silabs_siwx91x/Kconfig.soc new file mode 100644 index 0000000000000..f615334d2e431 --- /dev/null +++ b/soc/silabs/silabs_siwx91x/Kconfig.soc @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Antmicro +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_SILABS_SIWX91X + bool + +rsource "*/Kconfig.soc" diff --git a/soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt b/soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt new file mode 100644 index 0000000000000..33985be7796fc --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_SOC_SERIES_SIWG917 soc.c) +zephyr_sources_ifdef(CONFIG_WISECONNECT_NETWORK_STACK nwp_init.c) + +set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/silabs/silabs_siwx91x/siwg917/Kconfig b/soc/silabs/silabs_siwx91x/siwg917/Kconfig new file mode 100644 index 0000000000000..e9d4e75ff235e --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Antmicro +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SIWG917 + select SOC_EARLY_INIT_HOOK diff --git a/soc/silabs/silabs_siwx91x/siwg917/Kconfig.defconfig b/soc/silabs/silabs_siwx91x/siwg917/Kconfig.defconfig new file mode 100644 index 0000000000000..9fa79429bcd18 --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_SIWG917 + +config NUM_IRQS + default 99 + +config BUILD_OUTPUT_HEX + default y + +endif diff --git a/soc/silabs/silabs_siwx91x/siwg917/Kconfig.soc b/soc/silabs/silabs_siwx91x/siwg917/Kconfig.soc new file mode 100644 index 0000000000000..c5e89582184dc --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/Kconfig.soc @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SIWG917 + bool + select SOC_FAMILY_SILABS_SIWX91X + help + SiWG917 Series MCU + +config SOC_PART_NUMBER_SIWG917M111MGTBA + bool + select SOC_SERIES_SIWG917 + +config SOC_SERIES + default "siwg917" if SOC_SERIES_SIWG917 + +config SOC + default "siwg917m111mgtba" if SOC_PART_NUMBER_SIWG917M111MGTBA + +config SOC_PART_NUMBER + default "SIWG917M111MGTBA" if SOC_PART_NUMBER_SIWG917M111MGTBA diff --git a/soc/silabs/silabs_siwx91x/siwg917/linker.ld b/soc/silabs/silabs_siwx91x/siwg917/linker.ld new file mode 100644 index 0000000000000..b21a3cca0ee51 --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/linker.ld @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +MEMORY +{ + udma0 (rwx) : ORIGIN = 0x0002fc00, LENGTH = 0x00000400 + udma1 (rwx) : ORIGIN = 0x24061c00, LENGTH = 0x00000400 +} + +SECTIONS +{ + .common_tcm_code : + { + *(.common_tcm_code*) + } > FLASH + + /* These regions of SRAM is where the UDMA descriptors are stored. The corresponding + section must be properly declared in the linker script to ensure correct data transfer + and proper functioning of the UDMA module */ + .udma_addr0 : + { + *(.udma_addr0*) + } > udma0 AT> FLASH + + .udma_addr1 : + { + *(.udma_addr1*) + } > udma1 AT> FLASH +} diff --git a/soc/silabs/silabs_siwx91x/siwg917/nwp_init.c b/soc/silabs/silabs_siwx91x/siwg917/nwp_init.c new file mode 100644 index 0000000000000..fb508dae7101c --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/nwp_init.c @@ -0,0 +1,111 @@ +/** + * @file + * @brief Network Processor Initialization for SiWx91x. + * + * This file contains the initialization routine for the (ThreadArch) network processor + * on the SiWx91x platform. The component is responsible for setting up the necessary + * hardware and software components to enable network communication. + * + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "sl_wifi.h" +#include "sl_wifi_callback_framework.h" +#ifdef CONFIG_BT_SILABS_SIWX91X +#include "rsi_ble_common_config.h" +#endif + +static int siwg917_nwp_init(void) +{ + sl_wifi_device_configuration_t network_config = { + .boot_option = LOAD_NWP_FW, + .band = SL_SI91X_WIFI_BAND_2_4GHZ, + .region_code = DEFAULT_REGION, + .boot_config = { + .oper_mode = SL_SI91X_CLIENT_MODE, + .tcp_ip_feature_bit_map = SL_SI91X_TCP_IP_FEAT_EXTENSION_VALID, + .ext_tcp_ip_feature_bit_map = SL_SI91X_CONFIG_FEAT_EXTENSION_VALID, + .config_feature_bit_map = SL_SI91X_ENABLE_ENHANCED_MAX_PSP, + .custom_feature_bit_map = SL_SI91X_CUSTOM_FEAT_EXTENSION_VALID, + .ext_custom_feature_bit_map = + MEMORY_CONFIG | + SL_SI91X_EXT_FEAT_XTAL_CLK | + SL_SI91X_EXT_FEAT_FRONT_END_SWITCH_PINS_ULP_GPIO_4_5_0, + } + }; + sl_si91x_boot_configuration_t *cfg = &network_config.boot_config; + + if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X) && IS_ENABLED(CONFIG_BT_SILABS_SIWX91X)) { + cfg->coex_mode = SL_SI91X_WLAN_BLE_MODE; + } else if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X)) { + cfg->coex_mode = SL_SI91X_WLAN_ONLY_MODE; + } else if (IS_ENABLED(CONFIG_BT_SILABS_SIWX91X)) { + cfg->coex_mode = SL_SI91X_BLE_MODE; + } else { + /* + * Even if neither WiFi or BLE is used we have to specify a Coex mode + */ + cfg->coex_mode = SL_SI91X_BLE_MODE; + } + +#ifdef CONFIG_WIFI_SILABS_SIWX91X + cfg->feature_bit_map |= SL_SI91X_FEAT_SECURITY_OPEN | SL_SI91X_FEAT_WPS_DISABLE, + cfg->ext_custom_feature_bit_map |= SL_SI91X_EXT_FEAT_IEEE_80211W; + if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD)) { + cfg->ext_tcp_ip_feature_bit_map |= SL_SI91X_EXT_TCP_IP_WINDOW_SCALING; + cfg->ext_tcp_ip_feature_bit_map |= SL_SI91X_EXT_TCP_IP_TOTAL_SELECTS(10); + cfg->tcp_ip_feature_bit_map |= SL_SI91X_TCP_IP_FEAT_ICMP; + if (IS_ENABLED(CONFIG_NET_IPV6)) { + cfg->tcp_ip_feature_bit_map |= SL_SI91X_TCP_IP_FEAT_DHCPV6_CLIENT; + cfg->tcp_ip_feature_bit_map |= SL_SI91X_TCP_IP_FEAT_IPV6; + } + if (IS_ENABLED(CONFIG_NET_IPV4)) { + cfg->tcp_ip_feature_bit_map |= SL_SI91X_TCP_IP_FEAT_DHCPV4_CLIENT; + } + } else { + cfg->tcp_ip_feature_bit_map |= SL_SI91X_TCP_IP_FEAT_BYPASS; + } +#endif + +#ifdef CONFIG_BT_SILABS_SIWX91X + cfg->ext_custom_feature_bit_map |= SL_SI91X_EXT_FEAT_BT_CUSTOM_FEAT_ENABLE; + cfg->bt_feature_bit_map |= SL_SI91X_BT_RF_TYPE | SL_SI91X_ENABLE_BLE_PROTOCOL; + cfg->ble_feature_bit_map |= SL_SI91X_BLE_MAX_NBR_PERIPHERALS(RSI_BLE_MAX_NBR_PERIPHERALS) | + SL_SI91X_BLE_MAX_NBR_CENTRALS(RSI_BLE_MAX_NBR_CENTRALS) | + SL_SI91X_BLE_MAX_NBR_ATT_SERV(RSI_BLE_MAX_NBR_ATT_SERV) | + SL_SI91X_BLE_MAX_NBR_ATT_REC(RSI_BLE_MAX_NBR_ATT_REC) | + SL_SI91X_BLE_PWR_INX(RSI_BLE_PWR_INX) | + SL_SI91X_BLE_PWR_SAVE_OPTIONS(RSI_BLE_PWR_SAVE_OPTIONS) | + SL_SI91X_916_BLE_COMPATIBLE_FEAT_ENABLE | + SL_SI91X_FEAT_BLE_CUSTOM_FEAT_EXTENSION_VALID; + cfg->ble_ext_feature_bit_map |= SL_SI91X_BLE_NUM_CONN_EVENTS(RSI_BLE_NUM_CONN_EVENTS) | + SL_SI91X_BLE_NUM_REC_BYTES(RSI_BLE_NUM_REC_BYTES) | + SL_SI91X_BLE_ENABLE_ADV_EXTN | + SL_SI91X_BLE_AE_MAX_ADV_SETS(RSI_BLE_AE_MAX_ADV_SETS); +#endif + + /* TODO: If sl_net_*_profile() functions will be needed for WiFi then call + * sl_net_set_profile() here. Currently these are unused. + */ + return sl_wifi_init(&network_config, NULL, sl_wifi_default_event_handler); +} +SYS_INIT(siwg917_nwp_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); + +/* IRQn 74 is used for communication with co-processor */ +Z_ISR_DECLARE(74, 0, IRQ074_Handler, 0); + +/* Co-processor will use value stored in IVT to store its stack. + * + * FIXME: We can't use Z_ISR_DECLARE() to declare this entry + * FIXME: Allow to configure size of buffer + */ +static uint8_t __aligned(8) siwg917_nwp_stack[10 * 1024]; +static Z_DECL_ALIGN(struct _isr_list) Z_GENERIC_SECTION(.intList) + __used __isr_siwg917_coprocessor_stack_irq = { + .irq = 30, + .flags = ISR_FLAG_DIRECT, + .func = &siwg917_nwp_stack[sizeof(siwg917_nwp_stack) - 1], + }; diff --git a/soc/silabs/silabs_siwx91x/siwg917/pinctrl_soc.h b/soc/silabs/silabs_siwx91x/siwg917/pinctrl_soc.h new file mode 100644 index 0000000000000..bf066ff203b95 --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/pinctrl_soc.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories, Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_SILABS_SIWG917_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_SILABS_SIWG917_PINCTRL_SOC_H_ + +#include +#include + +typedef struct pinctrl_soc_pin_t { + uint8_t port; + uint8_t pin; + uint8_t ulppin; + uint8_t mode; + uint8_t ulpmode; + uint8_t pad; +} pinctrl_soc_pin_t; + +#define Z_PINCTRL_STATE_PIN_INIT(node, prop, idx) { \ + .port = FIELD_GET(SIWX91X_PINCTRL_PORT_MASK, DT_PROP_BY_IDX(node, prop, idx)), \ + .pin = FIELD_GET(SIWX91X_PINCTRL_PIN_MASK, DT_PROP_BY_IDX(node, prop, idx)), \ + .ulppin = FIELD_GET(SIWX91X_PINCTRL_ULPPIN_MASK, DT_PROP_BY_IDX(node, prop, idx)), \ + .mode = FIELD_GET(SIWX91X_PINCTRL_MODE_MASK, DT_PROP_BY_IDX(node, prop, idx)), \ + .ulpmode = FIELD_GET(SIWX91X_PINCTRL_ULPMODE_MASK, DT_PROP_BY_IDX(node, prop, idx)), \ + .pad = FIELD_GET(SIWX91X_PINCTRL_PAD_MASK, DT_PROP_BY_IDX(node, prop, idx)), \ +}, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) { \ + DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, \ + pinmux, Z_PINCTRL_STATE_PIN_INIT) \ +} + +#endif diff --git a/soc/silabs/silabs_siwx91x/siwg917/soc.c b/soc/silabs/silabs_siwx91x/siwg917/soc.c new file mode 100644 index 0000000000000..139b7f3492a5d --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/soc.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Antmicro + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include + +#include "em_device.h" + +void soc_early_init_hook(void) +{ + SystemInit(); +} + +/* SiWx917's bootloader requires IRQn 32 to hold payload's entry point address. */ +extern void z_arm_reset(void); +Z_ISR_DECLARE_DIRECT(32, 0, z_arm_reset); diff --git a/soc/silabs/silabs_siwx91x/siwg917/soc.h b/soc/silabs/silabs_siwx91x/siwg917/soc.h new file mode 100644 index 0000000000000..b96cf08e1a9dd --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwg917/soc.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef SIWG917_SOC_H +#define SIWG917_SOC_H + +#include "si91x_device.h" + +#endif diff --git a/soc/silabs/silabs_siwx91x/siwx91x_isp_prepare.py b/soc/silabs/silabs_siwx91x/siwx91x_isp_prepare.py new file mode 100755 index 0000000000000..3a217b0c217b8 --- /dev/null +++ b/soc/silabs/silabs_siwx91x/siwx91x_isp_prepare.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2023 Antmicro +# Copyright (c) 2024 Silicon Laboratories Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import struct +import sys + +import intelhex + + +# For reference: +# width=32 poly=0xd95eaae5 init=0 refin=true refout=true xorout=0 +def create_table() -> list[int]: + crc_table = [0] * 256 + for b in range(256): + register = b + for _ in range(8): + lsb = register & 1 + register >>= 1 + if lsb: + # Reflected polynomial: 0xd95eaae5 + register ^= 0xA7557A9B + crc_table[b] = register + return crc_table + + +def calc_crc32(data: bytes) -> int: + crc_table = create_table() + register = 0 + for b in data: + register = crc_table[(b ^ register) & 0xFF] ^ (register >> 8) + return register + + +def calc_checksum(data: bytes | bytearray, size: int, prev_sum: int) -> int: + # Truncate + data = data[:size] + # Zero-pad data to mul of 4 bytes + nzeros = ((len(data) + 3) // 4 * 4) - len(data) + data += b"\0" * nzeros + # Reinterpret data as LE u32 + ints = list(x[0] for x in struct.iter_unpack("> 32) + chk = (~chk) & 0xFFFFFFFF + return chk + + +def set_bits(x: int, off: int, size: int, field: int) -> int: + field = int(field) + mask = ((1 << size) - 1) << off + x &= ~mask + x |= (field << off) & mask + return x + + +def get_bootload_entry( + ctrl_len: int = 0, + ctrl_reserved: int = 0, + ctrl_spi_32bitmode: bool = False, + ctrl_release_ta_softreset: bool = False, + ctrl_start_from_rom_pc: bool = False, + ctrl_spi_8bitmode: bool = False, + ctrl_last_entry: bool = True, + dest_addr: int = 0, +) -> bytes: + # Format bootload_entry struct + ctrl = 0 + ctrl = set_bits(ctrl, 0, 24, ctrl_len) + ctrl = set_bits(ctrl, 24, 3, ctrl_reserved) + ctrl = set_bits(ctrl, 27, 1, ctrl_spi_32bitmode) + ctrl = set_bits(ctrl, 28, 1, ctrl_release_ta_softreset) + ctrl = set_bits(ctrl, 29, 1, ctrl_start_from_rom_pc) + ctrl = set_bits(ctrl, 30, 1, ctrl_spi_8bitmode) + ctrl = set_bits(ctrl, 31, 1, ctrl_last_entry) + return struct.pack(" bytes: + ret = b"" + ret += int(fixed_pattern).to_bytes(2, "little") + ret += int(offset).to_bytes(2, "little") + ret += int(ivt_offset).to_bytes(4, "little") + for i in range(7): + ret += get_bootload_entry(ctrl_last_entry=i == 0) + return ret + + +def get_fwupreq(flash_location: int, image_size: int) -> bytes: + # Field values + cflags = 1 + sha_type = 0 + magic_no = 0x900D900D + fw_version = 0 + # Initially CRC value is set to 0, then the CRC is calculated on the + # whole image (including fwupreq header), and injected here + crc = 0 + mic = [0, 0, 0, 0] + counter = 0 + rsvd = [0, 0, 0, 0, magic_no] + # Format + ret = b"" + ret += cflags.to_bytes(2, "little") + ret += sha_type.to_bytes(2, "little") + ret += magic_no.to_bytes(4, "little") + ret += image_size.to_bytes(4, "little") + ret += fw_version.to_bytes(4, "little") + ret += flash_location.to_bytes(4, "little") + ret += crc.to_bytes(4, "little") + for x in mic: + ret += x.to_bytes(4, "little") + ret += counter.to_bytes(4, "little") + for x in rsvd: + ret += x.to_bytes(4, "little") + return ret + + +def main(): + parser = argparse.ArgumentParser( + description="Converts raw binary output from Zephyr into an ISP binary for Silabs SiWx91x", + allow_abbrev=False, + ) + parser.add_argument( + "ifile", + metavar="INPUT.BIN", + help="Raw binary file to read", + type=argparse.FileType("rb"), + ) + parser.add_argument( + "ofile", + metavar="OUTPUT.BIN", + help="ISP binary file to write", + type=argparse.FileType("wb"), + ) + parser.add_argument( + "--load-addr", + metavar="ADDRESS", + help="Address at which the raw binary image begins in the memory", + type=lambda x: int(x, 0), + required=True, + ) + parser.add_argument( + "--out-hex", + metavar="FILE.HEX", + help="Generate Intel HEX output in addition to binary one", + type=argparse.FileType("w", encoding="ascii"), + ) + args = parser.parse_args() + + img = bytearray(args.ifile.read()) + + # Calculate and inject checksum + chk = calc_checksum(img, 236, 1) + print(f"ROM checksum: 0x{chk:08x}", file=sys.stderr) + img[236:240] = chk.to_bytes(4, "little") + + # Get bootloader header, pad to 4032 and glue it to the image payload + bl = bytearray(get_bootload_ds(4032, args.load_addr)) + padding = bytearray(4032 - len(bl)) + img = bl + padding + img + + # Get fwupreq header and glue it to the bootloader payload + fwupreq = bytearray(get_fwupreq(args.load_addr - 0x8001000, len(img))) + img = fwupreq + img + + # Calculate and inject CRC + crc = calc_crc32(img) + print(f"Image CRC: 0x{crc:08x}", file=sys.stderr) + img[20:24] = crc.to_bytes(4, "little") + + args.ofile.write(img) + + # If you want to compare this file with the .hex file generated by Zephyr, + # You have to reformat the Zephyr output: + # import intelhex + # hx = intelhex.IntelHex() + # hx.fromfile("zephyr.hex", "hex") + # hx.write_hex_file("zephyr.out.hex", byte_count=32) + if args.out_hex: + hx = intelhex.IntelHex() + # len(bl) + len(padding) + len(fwupreq) == 4096 + hx.frombytes(img, args.load_addr - 4096) + hx.write_hex_file(args.out_hex, byte_count=32) + + +if __name__ == "__main__": + main() diff --git a/soc/silabs/soc.yml b/soc/silabs/soc.yml index f1765c8c83962..b274cbda0621d 100644 --- a/soc/silabs/soc.yml +++ b/soc/silabs/soc.yml @@ -51,10 +51,29 @@ family: socs: - name: efr32mg24b220f1536im48 - name: efr32mg24b310f1536im48 + - name: efr32mg24b210f1536im48 - name: efr32mg24b020f1536im40 - name: efr32bg27 socs: - name: efr32bg27c140f768im40 + - name: efr32zg23 + socs: + - name: efr32zg23b020f512im48 + - name: efr32bg29 + socs: + - name: efr32bg29b140f1024im40 + - name: efr32bg29b220f1024cj45 + - name: efr32bg29b221f1024cj45 + - name: efr32bg29b230f1024cm40 + - name: efr32mg29 + socs: + - name: efr32mg29b140f1024im40 + - name: efr32mg29b230f1024cm40 + - name: silabs_siwx91x + series: + - name: siwg917 + socs: + - name: siwg917m111mgtba - name: silabs_sim3 series: - name: sim3u diff --git a/soc/st/stm32/Kconfig.defconfig b/soc/st/stm32/Kconfig.defconfig index 0741439de6c79..67879e6cf6285 100644 --- a/soc/st/stm32/Kconfig.defconfig +++ b/soc/st/stm32/Kconfig.defconfig @@ -7,6 +7,8 @@ if SOC_FAMILY_STM32 +# Source series Kconfig files first, so SoCs +# can override the defaults given here rsource "*/Kconfig.defconfig" config CLOCK_CONTROL diff --git a/soc/st/stm32/common/stm32_wkup_pins.c b/soc/st/stm32/common/stm32_wkup_pins.c index 23a2d2a80f00d..c25887dfc3993 100644 --- a/soc/st/stm32/common/stm32_wkup_pins.c +++ b/soc/st/stm32/common/stm32_wkup_pins.c @@ -107,7 +107,7 @@ static const struct gpio_dt_spec empty_gpio = {.port = NULL, .pin = 0, .dt_flags /* wkup_pin idx starts from 1 */ #define WKUP_PIN_CFG_DT_BY_IDX(idx) WKUP_PIN_CFG_DT(WKUP_PIN_NODE_ID_BY_IDX(idx)) -#define PWR_STM32_WKUP_PIN_DEF(i, _) LL_PWR_WAKEUP_PIN##i +#define PWR_STM32_WKUP_PIN_LOOKUP_MEMBER(i, _) CONCAT(LL_PWR_WAKEUP_PIN, UTIL_INC(i)) #define WKUP_PIN_CFG_DT_COMMA(wkup_pin_id) WKUP_PIN_CFG_DT(wkup_pin_id), @@ -133,7 +133,9 @@ struct wkup_pin_cfg_t { * @brief LookUp Table to store LL_PWR_WAKEUP_PINx for each wake-up pin. */ static const uint32_t table_wakeup_pins[PWR_STM32_MAX_NB_WKUP_PINS + 1] = { - LISTIFY(PWR_STM32_MAX_NB_WKUP_PINS, PWR_STM32_WKUP_PIN_DEF, (,))}; + 0, + LISTIFY(PWR_STM32_MAX_NB_WKUP_PINS, PWR_STM32_WKUP_PIN_LOOKUP_MEMBER, (,)), +}; static struct wkup_pin_dt_cfg_t wkup_pins_cfgs[] = { DT_FOREACH_CHILD(STM32_PWR_NODE, WKUP_PIN_CFG_DT_COMMA)}; diff --git a/soc/st/stm32/common/stm32_wkup_pins.h b/soc/st/stm32/common/stm32_wkup_pins.h index c8ea75f7eb58a..717a59fddd40b 100644 --- a/soc/st/stm32/common/stm32_wkup_pins.h +++ b/soc/st/stm32/common/stm32_wkup_pins.h @@ -17,7 +17,6 @@ extern "C" { #endif /* Some stm32 devices do not have all the LL_PWR_WAKEUP_PINx */ -#define LL_PWR_WAKEUP_PIN0 0 #ifndef LL_PWR_WAKEUP_PIN3 #define LL_PWR_WAKEUP_PIN3 0 #endif /* LL_PWR_WAKEUP_PIN3 */ diff --git a/soc/st/stm32/soc.yml b/soc/st/stm32/soc.yml index 9ef503be86eca..4e5d659573395 100644 --- a/soc/st/stm32/soc.yml +++ b/soc/st/stm32/soc.yml @@ -5,6 +5,7 @@ family: socs: - name: stm32c011xx - name: stm32c031xx + - name: stm32c071xx - name: stm32f0x socs: - name: stm32f030x6 @@ -132,6 +133,10 @@ family: cpuclusters: - name: m7 - name: m4 + - name: stm32h757xx + cpuclusters: + - name: m7 + - name: m4 - name: stm32l0x socs: - name: stm32l010x4 @@ -181,6 +186,9 @@ family: - name: stm32mp1x socs: - name: stm32mp157cxx + - name: stm32n6x + socs: + - name: stm32n657xx - name: stm32u0x socs: - name: stm32u031xx diff --git a/soc/st/stm32/stm32c0x/Kconfig.defconfig.stm32c071xx b/soc/st/stm32/stm32c0x/Kconfig.defconfig.stm32c071xx new file mode 100644 index 0000000000000..fdddd25275bfd --- /dev/null +++ b/soc/st/stm32/stm32c0x/Kconfig.defconfig.stm32c071xx @@ -0,0 +1,11 @@ +# STMicroelectronics STM32C071xx MCU + +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32C071XX + +config NUM_IRQS + default 29 + +endif # SOC_STM32C071XX diff --git a/soc/st/stm32/stm32c0x/Kconfig.soc b/soc/st/stm32/stm32c0x/Kconfig.soc index 57a833c82f036..adf62f3c56983 100644 --- a/soc/st/stm32/stm32c0x/Kconfig.soc +++ b/soc/st/stm32/stm32c0x/Kconfig.soc @@ -10,14 +10,19 @@ config SOC_SERIES_STM32C0X config SOC_SERIES default "stm32c0x" if SOC_SERIES_STM32C0X +config SOC_STM32C011XX + bool + select SOC_SERIES_STM32C0X + config SOC_STM32C031XX bool select SOC_SERIES_STM32C0X -config SOC_STM32C011XX +config SOC_STM32C071XX bool select SOC_SERIES_STM32C0X config SOC default "stm32c011xx" if SOC_STM32C011XX default "stm32c031xx" if SOC_STM32C031XX + default "stm32c071xx" if SOC_STM32C071XX diff --git a/soc/st/stm32/stm32h7x/Kconfig b/soc/st/stm32/stm32h7x/Kconfig index 4f8fd58571248..6961800544749 100644 --- a/soc/st/stm32/stm32h7x/Kconfig +++ b/soc/st/stm32/stm32h7x/Kconfig @@ -59,6 +59,12 @@ config SOC_STM32H755XX_M7 config SOC_STM32H755XX_M4 select CPU_CORTEX_M4 +config SOC_STM32H757XX_M7 + select CPU_CORTEX_M7 + +config SOC_STM32H757XX_M4 + select CPU_CORTEX_M4 + config SOC_STM32H7A3XX select CPU_CORTEX_M7 diff --git a/soc/st/stm32/stm32h7x/Kconfig.defconfig b/soc/st/stm32/stm32h7x/Kconfig.defconfig index 790b1659c0514..5c9ca2c97721e 100644 --- a/soc/st/stm32/stm32h7x/Kconfig.defconfig +++ b/soc/st/stm32/stm32h7x/Kconfig.defconfig @@ -14,4 +14,11 @@ config ROM_START_OFFSET default 0x400 if BOOTLOADER_MCUBOOT default 0x0 if !BOOTLOADER_MCUBOOT +if LVGL + +config LV_DRAW_DMA2D_HAL_INCLUDE + default "stm32h7xx.h" + +endif # LVGL + endif # SOC_SERIES_STM32H7X diff --git a/soc/st/stm32/stm32h7x/Kconfig.defconfig.stm32h757xx b/soc/st/stm32/stm32h7x/Kconfig.defconfig.stm32h757xx new file mode 100644 index 0000000000000..2248759755353 --- /dev/null +++ b/soc/st/stm32/stm32h7x/Kconfig.defconfig.stm32h757xx @@ -0,0 +1,15 @@ +# ST STM32H757X MCU configuration options +# +# Copyright (c) 2024 Grinn sp. z o.o. +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32H757XX_M7 || SOC_STM32H757XX_M4 + +config STM32H7_DUAL_CORE + default y + +config NUM_IRQS + default 150 + +endif # SOC_STM32H757XX_M7 || SOC_STM32H757XX_M4 diff --git a/soc/st/stm32/stm32h7x/Kconfig.soc b/soc/st/stm32/stm32h7x/Kconfig.soc index e28e09fd5da26..382489284e69c 100644 --- a/soc/st/stm32/stm32h7x/Kconfig.soc +++ b/soc/st/stm32/stm32h7x/Kconfig.soc @@ -68,6 +68,14 @@ config SOC_STM32H755XX_M7 bool select SOC_SERIES_STM32H7X +config SOC_STM32H757XX_M4 + bool + select SOC_SERIES_STM32H7X + +config SOC_STM32H757XX_M7 + bool + select SOC_SERIES_STM32H7X + config SOC_STM32H7A3XX bool select SOC_SERIES_STM32H7X @@ -110,3 +118,4 @@ config SOC default "stm32h750xx" if SOC_STM32H750XX default "stm32h753xx" if SOC_STM32H753XX default "stm32h755xx" if SOC_STM32H755XX_M7 || SOC_STM32H755XX_M4 + default "stm32h757xx" if SOC_STM32H757XX_M7 || SOC_STM32H757XX_M4 diff --git a/soc/st/stm32/stm32h7x/mpu_regions.c b/soc/st/stm32/stm32h7x/mpu_regions.c index 8582db6072493..f77018d36caed 100644 --- a/soc/st/stm32/stm32h7x/mpu_regions.c +++ b/soc/st/stm32/stm32h7x/mpu_regions.c @@ -22,19 +22,19 @@ static const struct arm_mpu_region mpu_regions[] = { MPU_RASR_XN_Msk | P_RW_U_NA_Msk) }), #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mac)) + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sram3)) - MPU_REGION_ENTRY("SRAM3_ETH_BUF", - DT_REG_ADDR(DT_NODELABEL(sram3)), - REGION_RAM_NOCACHE_ATTR(REGION_16K)), - MPU_REGION_ENTRY("SRAM3_ETH_DESC", - DT_REG_ADDR(DT_NODELABEL(sram3)), - REGION_PPB_ATTR(REGION_256B)), +#define sram_eth_node DT_NODELABEL(sram3) #else - MPU_REGION_ENTRY("SRAM2_ETH_BUF", - DT_REG_ADDR(DT_NODELABEL(sram2)), +#define sram_eth_node DT_NODELABEL(sram2) +#endif + +#if DT_NODE_HAS_STATUS_OKAY(sram_eth_node) + MPU_REGION_ENTRY("SRAM_ETH_BUF", + DT_REG_ADDR(sram_eth_node), REGION_RAM_NOCACHE_ATTR(REGION_16K)), - MPU_REGION_ENTRY("SRAM2_ETH_DESC", - DT_REG_ADDR(DT_NODELABEL(sram2)), + MPU_REGION_ENTRY("SRAM_ETH_DESC", + DT_REG_ADDR(sram_eth_node), REGION_PPB_ATTR(REGION_256B)), #endif #endif diff --git a/soc/st/stm32/stm32h7x/sections.ld b/soc/st/stm32/stm32h7x/sections.ld index 5f4fd794dd2a1..4989d8e90ea38 100644 --- a/soc/st/stm32/stm32h7x/sections.ld +++ b/soc/st/stm32/stm32h7x/sections.ld @@ -4,24 +4,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if DT_NODE_HAS_STATUS(DT_NODELABEL(mac), okay) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mac)) +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(sram3)) +#define sram_eth_node DT_NODELABEL(sram3) +#else +#define sram_eth_node DT_NODELABEL(sram2) +#endif + +#if DT_NODE_HAS_STATUS_OKAY(sram_eth_node) SECTION_DATA_PROLOGUE(eth_stm32,(NOLOAD),) { -#if DT_NODE_HAS_STATUS(DT_NODELABEL(sram3), okay) - . = ABSOLUTE(DT_REG_ADDR(DT_NODELABEL(sram3))); + . = ABSOLUTE(DT_REG_ADDR(sram_eth_node)); *(.eth_stm32_desc) - . = ABSOLUTE(DT_REG_ADDR(DT_NODELABEL(sram3))) + 256; + . = ABSOLUTE(DT_REG_ADDR(sram_eth_node)) + 256; *(.eth_stm32_buf) - . = ABSOLUTE(DT_REG_ADDR(DT_NODELABEL(sram3))) + 16K; -} GROUP_DATA_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(sram3)), LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(sram3))) - -#else - . = ABSOLUTE(DT_REG_ADDR(DT_NODELABEL(sram2))); - *(.eth_stm32_desc) - . = ABSOLUTE(DT_REG_ADDR(DT_NODELABEL(sram2))) + 256; - *(.eth_stm32_buf) - . = ABSOLUTE(DT_REG_ADDR(DT_NODELABEL(sram2))) + 16K; -} GROUP_DATA_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(sram2)), LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(sram2))) -#endif + . = ABSOLUTE(DT_REG_ADDR(sram_eth_node)) + 16K; +} GROUP_DATA_LINK_IN(LINKER_DT_NODE_REGION_NAME(sram_eth_node), LINKER_DT_NODE_REGION_NAME(sram_eth_node)) #endif + +#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(mac), okay) */ diff --git a/soc/st/stm32/stm32n6x/CMakeLists.txt b/soc/st/stm32/stm32n6x/CMakeLists.txt new file mode 100644 index 0000000000000..d8ded3541e4f7 --- /dev/null +++ b/soc/st/stm32/stm32n6x/CMakeLists.txt @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_sources( + soc.c + ) + +zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") + +if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) + set(SIGNING_TOOL STM32_SigningTool_CLI.exe) +else() + set(SIGNING_TOOL STM32_SigningTool_CLI) +endif() + +find_file(SIGNING_TOOL_FIND ${SIGNING_TOOL}) +if(SIGNING_TOOL_FIND STREQUAL SIGNING_TOOL_FIND-NOTFOUND) + message(WARNING " + Signing Image tool (${SIGNING_TOOL}) is not available. + Signed image will not be generated. + You won't be able to run image on board.") +endif() + +if(NOT SIGNING_TOOL_FIND STREQUAL SIGNING_TOOL_FIND-NOTFOUND) + + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${SIGNING_TOOL} + -in ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin + -nk -t fsbl -hv 2.3 + -o ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.signed.bin + -dump ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.signed.bin + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + + set_property(TARGET runners_yaml_props_target PROPERTY bin_file ${CONFIG_KERNEL_BIN_NAME}.signed.bin) + +endif() diff --git a/soc/st/stm32/stm32n6x/Kconfig b/soc/st/stm32/stm32n6x/Kconfig new file mode 100644 index 0000000000000..d95a4b04e0fec --- /dev/null +++ b/soc/st/stm32/stm32n6x/Kconfig @@ -0,0 +1,23 @@ +# ST Microelectronics STM32N6 MCU series + +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_STM32N6X + select ARM + select CPU_CORTEX_M55 + select ARM_TRUSTZONE_M + select CPU_HAS_ARM_SAU + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU + select ARMV8_M_DSP + select CPU_CORTEX_M_HAS_DWT + select HAS_STM32CUBE + select INIT_ARCH_HW_AT_BOOT + select SOC_RESET_HOOK + select SOC_EARLY_INIT_HOOK + select TRUSTED_EXECUTION_SECURE + select BUILD_OUTPUT_BIN + +config STM32N6_BOOT_SERIAL + bool "Serial boot target (USB)" diff --git a/soc/st/stm32/stm32n6x/Kconfig.defconfig b/soc/st/stm32/stm32n6x/Kconfig.defconfig new file mode 100644 index 0000000000000..2e9856e8b02a2 --- /dev/null +++ b/soc/st/stm32/stm32n6x/Kconfig.defconfig @@ -0,0 +1,17 @@ +# ST Microelectronics STM32N6 MCU series + +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_STM32N6X + +rsource "Kconfig.defconfig.stm32n6*" + +DT_STM32_CPU_CLOCK_PATH := $(dt_nodelabel_path,cpusw) +DT_STM32_CPU_CLOCK_FREQ := $(dt_node_int_prop_int,$(DT_STM32_CPU_CLOCK_PATH),clock-frequency) + +# For STM32N6, override the value defined in STM32 Kconfig to use CPU clock frequency +config SYS_CLOCK_HW_CYCLES_PER_SEC + default "$(DT_STM32_CPU_CLOCK_FREQ)" if "$(dt_nodelabel_enabled,cpusw)" + +endif # SOC_SERIES_STM32N6X diff --git a/soc/st/stm32/stm32n6x/Kconfig.defconfig.stm32n657xx b/soc/st/stm32/stm32n6x/Kconfig.defconfig.stm32n657xx new file mode 100644 index 0000000000000..910e642669077 --- /dev/null +++ b/soc/st/stm32/stm32n6x/Kconfig.defconfig.stm32n657xx @@ -0,0 +1,11 @@ +# ST Microelectronics STM32N6 MCU series + +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32N657XX + +config NUM_IRQS + default 194 + +endif # SOC_STM32N657XX diff --git a/soc/st/stm32/stm32n6x/Kconfig.soc b/soc/st/stm32/stm32n6x/Kconfig.soc new file mode 100644 index 0000000000000..71879c0848a38 --- /dev/null +++ b/soc/st/stm32/stm32n6x/Kconfig.soc @@ -0,0 +1,18 @@ +# ST Microelectronics STM32N6 MCU series + +# Copyright (c) 2024 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_STM32N6X + bool + select SOC_FAMILY_STM32 + +config SOC_SERIES + default "stm32n6x" if SOC_SERIES_STM32N6X + +config SOC_STM32N657XX + bool + select SOC_SERIES_STM32N6X + +config SOC + default "stm32n657xx" if SOC_STM32N657XX diff --git a/soc/st/stm32/stm32n6x/soc.c b/soc/st/stm32/stm32n6x/soc.c new file mode 100644 index 0000000000000..c967404862c17 --- /dev/null +++ b/soc/st/stm32/stm32n6x/soc.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for STM32N6 processor + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL +LOG_MODULE_REGISTER(soc); + +extern char _vector_start[]; +void *g_pfnVectors = (void *)_vector_start; + +#if defined(CONFIG_SOC_RESET_HOOK) +void soc_reset_hook(void) +{ + /* This is provided by STM32Cube HAL */ + SystemInit(); +} +#endif + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + * + * @return 0 + */ +void soc_early_init_hook(void) +{ + /* Enable caches */ + sys_cache_instr_enable(); + sys_cache_data_enable(); + + /* Update CMSIS SystemCoreClock variable (HCLK) */ + /* At reset, system core clock is set to 64 MHz from HSI */ + SystemCoreClock = 64000000; + + /* Enable PWR */ + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_PWR); + + /* Enable IOs */ + LL_PWR_EnableVddIO2(); + LL_PWR_EnableVddIO3(); + LL_PWR_EnableVddIO4(); + LL_PWR_EnableVddIO5(); +} diff --git a/soc/st/stm32/stm32n6x/soc.h b/soc/st/stm32/stm32n6x/soc.h new file mode 100644 index 0000000000000..9274a7db70b71 --- /dev/null +++ b/soc/st/stm32/stm32n6x/soc.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the STM32N6 family processors. + * + */ + + +#ifndef _STM32N6_SOC_H_ +#define _STM32N6_SOC_H_ + +#ifndef _ASMLANGUAGE + +#include + +#endif /* !_ASMLANGUAGE */ + +#endif /* _STM32N6_SOC_H_ */ diff --git a/soc/st/stm32/stm32wb0x/Kconfig b/soc/st/stm32/stm32wb0x/Kconfig index 5816f0b83b409..2533ed349e9e1 100644 --- a/soc/st/stm32/stm32wb0x/Kconfig +++ b/soc/st/stm32/stm32wb0x/Kconfig @@ -10,6 +10,7 @@ config SOC_SERIES_STM32WB0X select CPU_CORTEX_M_HAS_SYSTICK select CPU_HAS_ARM_MPU select HAS_STM32CUBE + select SOC_EARLY_INIT_HOOK # WB0x has a ROM bootloader executed at reset, # which makes the following option required select INIT_ARCH_HW_AT_BOOT diff --git a/soc/st/stm32/stm32wb0x/Kconfig.defconfig b/soc/st/stm32/stm32wb0x/Kconfig.defconfig index a0079e8b2a344..19e70895b92ea 100644 --- a/soc/st/stm32/stm32wb0x/Kconfig.defconfig +++ b/soc/st/stm32/stm32wb0x/Kconfig.defconfig @@ -8,6 +8,8 @@ if SOC_SERIES_STM32WB0X config NUM_IRQS default 32 +if BT + config BT_AUTO_PHY_UPDATE default n @@ -17,4 +19,9 @@ config BT_AUTO_DATA_LEN_UPDATE config BT_HCI_ACL_FLOW_CONTROL default n +config MAIN_STACK_SIZE + default 1600 + +endif # BT + endif # SOC_SERIES_STM32WB0X diff --git a/soc/st/stm32/stm32wb0x/soc.c b/soc/st/stm32/stm32wb0x/soc.c index 8cac3ca231ed3..758652781a721 100644 --- a/soc/st/stm32/stm32wb0x/soc.c +++ b/soc/st/stm32/stm32wb0x/soc.c @@ -146,12 +146,9 @@ static void configure_smps(void) /** * @brief Perform basic hardware initialization at boot. * - * This needs to be run from the very beginning, - * so the init priority has to be 0 (zero). - * - * @return 0 + * This needs to be run from the very beginning. */ -static int stm32wb0_init(void) +void soc_early_init_hook(void) { /* Update CMSIS SystemCoreClock variable (CLK_SYS) */ /* On reset, the 64MHz HSI is selected as input to @@ -181,8 +178,4 @@ static int stm32wb0_init(void) /* Configure SMPS step-down converter */ configure_smps(); - - return 0; } - -SYS_INIT(stm32wb0_init, PRE_KERNEL_1, 0); diff --git a/soc/telink/tlsr/tlsr951x/Kconfig.defconfig b/soc/telink/tlsr/tlsr951x/Kconfig.defconfig index b210321b07966..777a0ac6f44e3 100644 --- a/soc/telink/tlsr/tlsr951x/Kconfig.defconfig +++ b/soc/telink/tlsr/tlsr951x/Kconfig.defconfig @@ -12,9 +12,6 @@ config RISCV_SOC_INTERRUPT_INIT config NUM_IRQS default 64 -config PINCTRL - default y - config XIP default n diff --git a/soc/ti/k3/am6x/Kconfig b/soc/ti/k3/am6x/Kconfig index a28996cc30589..504e044184a6c 100644 --- a/soc/ti/k3/am6x/Kconfig +++ b/soc/ti/k3/am6x/Kconfig @@ -9,6 +9,7 @@ config SOC_SERIES_AM6X_A53 config SOC_SERIES_AM6X_M4 select ARM select CPU_CORTEX_M4 + select CPU_HAS_FPU select CPU_CORTEX_M_HAS_SYSTICK select DYNAMIC_INTERRUPTS select CPU_CORTEX_M_HAS_DWT @@ -23,6 +24,7 @@ config SOC_SERIES_AM6X_R5 select ARM select CPU_CORTEX_R5 select CPU_HAS_ARM_MPU + select VFP_SP_D16 select ARM_CUSTOM_INTERRUPT_CONTROLLER select VIM select TI_DM_TIMER diff --git a/soc/ti/k3/am6x/Kconfig.soc b/soc/ti/k3/am6x/Kconfig.soc index 2f76accd255f9..82c56f200b876 100644 --- a/soc/ti/k3/am6x/Kconfig.soc +++ b/soc/ti/k3/am6x/Kconfig.soc @@ -39,6 +39,14 @@ config SOC_J721E_MAIN_R5F0_0 bool select SOC_SERIES_AM6X_R5 +config SOC_J722S_MAIN_R5F0_0 + bool + select SOC_SERIES_AM6X_R5 + +config SOC_J722S_MCU_R5F0_0 + bool + select SOC_SERIES_AM6X_R5 + config SOC_SERIES default "am6x" if SOC_SERIES_AM6X @@ -46,3 +54,4 @@ config SOC default "am6234" if SOC_AM6234_M4 || SOC_AM6234_A53 default "am6442" if SOC_AM6442_M4 default "j721e" if SOC_J721E_MAIN_R5F0_0 + default "j722s" if SOC_J722S_MAIN_R5F0_0 || SOC_J722S_MCU_R5F0_0 diff --git a/soc/ti/k3/am6x/m4/linker.ld b/soc/ti/k3/am6x/m4/linker.ld index 5e478a0541ff0..dfe71053cfe6b 100644 --- a/soc/ti/k3/am6x/m4/linker.ld +++ b/soc/ti/k3/am6x/m4/linker.ld @@ -13,6 +13,6 @@ SECTIONS SECTION_PROLOGUE(.resource_table,, SUBALIGN(4)) { KEEP(*(.resource_table*)) - } GROUP_LINK_IN(DDR) + } GROUP_LINK_IN(RSC_TABLE) #endif } diff --git a/soc/ti/k3/soc.yml b/soc/ti/k3/soc.yml index b8832d4f6b4ce..44e530703a81a 100644 --- a/soc/ti/k3/soc.yml +++ b/soc/ti/k3/soc.yml @@ -13,3 +13,7 @@ family: - name: j721e cpuclusters: - name: main_r5f0_0 + - name: j722s + cpuclusters: + - name: main_r5f0_0 + - name: mcu_r5f0_0 diff --git a/soc/ti/simplelink/Kconfig b/soc/ti/simplelink/Kconfig index af4cd5f74333e..e4e57d9a9dd7d 100644 --- a/soc/ti/simplelink/Kconfig +++ b/soc/ti/simplelink/Kconfig @@ -12,4 +12,10 @@ config HAS_TI_CCFG Selected when CCFG (Customer Configuration) registers appear at the end of flash +config TI_SIMPLELINK_DYNAMIC_DPL_OBJECTS + bool + help + Turn on dynamic memory allocation for DPL objects. Reserves + extra memory for this. + endif # SOC_FAMILY_TI_SIMPLELINK diff --git a/soc/ti/simplelink/cc23x0/CMakeLists.txt b/soc/ti/simplelink/cc23x0/CMakeLists.txt new file mode 100644 index 0000000000000..b8e02adbd58e8 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc.c) +zephyr_sources(ccfg.c) +zephyr_include_directories(.) + +zephyr_linker_sources_ifdef(CONFIG_HAS_TI_CCFG SECTIONS ccfg.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/ti/simplelink/cc23x0/Kconfig b/soc/ti/simplelink/cc23x0/Kconfig new file mode 100644 index 0000000000000..fa1c2c45af3e3 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/Kconfig @@ -0,0 +1,49 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_CC23X0 + select ARM + select CPU_CORTEX_M0PLUS + select CPU_CORTEX_M_HAS_VTOR + select SOC_RESET_HOOK + select TICKLESS_KERNEL + select DYNAMIC_INTERRUPTS + select HAS_CC23X0_SDK + select HAS_TI_CCFG + select TI_SIMPLELINK_DYNAMIC_DPL_OBJECTS + select EVENTS + select DYNAMIC_THREAD + select DYNAMIC_THREAD_ALLOC + select THREAD_STACK_INFO + select BUILD_OUTPUT_HEX + select BUILD_NO_GAP_FILL + +menu "Bootloader Configuration" +depends on SOC_SERIES_CC23X0 + +choice CC23X0_BLDR_VTOR_TYPE + prompt "Pointer to user bootloader vector table" + default CC23X0_BLDR_VTOR_TYPE_UNDEF + +config CC23X0_BLDR_VTOR_TYPE_UNDEF + bool "ROM serial bootloader" + +config CC23X0_BLDR_VTOR_TYPE_FORBID + bool "No bootloader invoked" + +config CC23X0_BLDR_VTOR_TYPE_USE_FCFG + bool "Use factory configuration" + +config CC23X0_BLDR_VTOR_TYPE_FLASH + bool "Use valid main flash address" + +endchoice # CC23X0_BLDR_VTOR_TYPE + +config CC23X0_BLDR_ENABLED + bool "Bootloader commands" + help + If n, bootloader ignores all commands. + +endmenu # "Bootloader Configuration" diff --git a/soc/ti/simplelink/cc23x0/Kconfig.defconfig b/soc/ti/simplelink/cc23x0/Kconfig.defconfig new file mode 100644 index 0000000000000..442c9b09c9e07 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Texas Instruments SimpleLink CC23X0 + +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_CC23X0 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +config NUM_IRQS + default 19 + +endif diff --git a/soc/ti/simplelink/cc23x0/Kconfig.soc b/soc/ti/simplelink/cc23x0/Kconfig.soc new file mode 100644 index 0000000000000..6817c069f9399 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/Kconfig.soc @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_CC23X0 + bool + select SOC_FAMILY_TI_SIMPLELINK + help + Enable support for TI SimpleLink CC23X0 series SOCs. + +config SOC_CC2340R5 + bool + select SOC_SERIES_CC23X0 + help + CC2340R5 + +config SOC_SERIES + default "cc23x0" if SOC_SERIES_CC23X0 + +config SOC + default "cc2340r5" if SOC_CC2340R5 diff --git a/soc/ti/simplelink/cc23x0/ccfg.c b/soc/ti/simplelink/cc23x0/ccfg.c new file mode 100644 index 0000000000000..08031e40adc0a --- /dev/null +++ b/soc/ti/simplelink/cc23x0/ccfg.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#define CC23_CCFG_FLASH DT_INST(0, ti_cc23x0_ccfg_flash) +#define CC23_CCFG_FLASH_PROP(prop) DT_PROP(CC23_CCFG_FLASH, prop) + +#define CC23_TO_PERM_VAL(en) ((en) ? CCFG_PERMISSION_ALLOW : CCFG_PERMISSION_FORBID) + +#if CONFIG_CC23X0_BLDR_VTOR_TYPE_UNDEF +#define CC23X0_BLDR_VTOR 0xffffffff +#elif CONFIG_CC23X0_BLDR_VTOR_TYPE_FORBID +#define CC23X0_BLDR_VTOR 0xfffffffc +#elif CONFIG_CC23X0_BLDR_VTOR_TYPE_USE_FCFG +#define CC23X0_BLDR_VTOR 0xfffffff0 +#else +#define CC23X0_BLDR_VTOR CC23_CCFG_FLASH_PROP(ti_bldr_vtor_flash) +#endif + +#define CC23X0_P_APP_VTOR DT_REG_ADDR(DT_CHOSEN(zephyr_code_partition)) + +#if CC23_CCFG_FLASH_PROP(ti_chip_erase) == 0 +#warning ti,chip-erase property is NOT PRESENT in your device tree, \ + flashing this firmware will LOCK YOUR DEVICE. +#endif + +/* Default CCFG */ +const ccfg_t ccfg __attribute__((section(".ti_ccfg"))) __attribute__((used)) = { + .bootCfg.pBldrVtor = (void *)CC23X0_BLDR_VTOR, + .bootCfg.bldrParam.serialRomBldrParamStruct.bldrEnabled = + IS_ENABLED(CONFIG_CC23X0_BLDR_ENABLED), + .bootCfg.bldrParam.serialRomBldrParamStruct.serialIoCfgIndex = + CC23_CCFG_FLASH_PROP(ti_serial_io_cfg_index), + .bootCfg.bldrParam.serialRomBldrParamStruct.pinTriggerEnabled = + CC23_CCFG_FLASH_PROP(ti_pin_trigger), + .bootCfg.bldrParam.serialRomBldrParamStruct.pinTriggerDio = + CC23_CCFG_FLASH_PROP(ti_pin_trigger_dio), + .bootCfg.bldrParam.serialRomBldrParamStruct.pinTriggerLevel = + CC23_CCFG_FLASH_PROP(ti_pin_trigger_level_hi), + .bootCfg.pAppVtor = (void *)CC23X0_P_APP_VTOR, + + .hwOpts = {0xffffffff, 0xffffffff}, + + .permissions.allowDebugPort = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_debug_port)), + .permissions.allowEnergyTrace = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_energy_trace)), + .permissions.allowFlashVerify = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_flash_verify)), + .permissions.allowFlashProgram = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_flash_program)), + .permissions.allowChipErase = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_chip_erase)), + .permissions.allowToolsClientMode = CCFG_PERMISSION_ALLOW, + .permissions.allowReturnToFactory = + CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_ret_to_factory)), + .permissions.allowFakeStby = CCFG_PERMISSION_ALLOW, + + .misc.saciTimeoutOverride = 0, + .misc.saciTimeoutExp = XCFG_MISC_SACITOEXP_8SEC, + + .flashProt.writeEraseProt.mainSectors0_31 = CC23_CCFG_FLASH_PROP(ti_wr_er_prot_sect0_31), + .flashProt.writeEraseProt.mainSectors32_255 = + CC23_CCFG_FLASH_PROP(ti_wr_er_prot_sect32_255), + .flashProt.writeEraseProt.ccfgSector = CC23_CCFG_FLASH_PROP(ti_wr_er_prot_ccfg_sect), + .flashProt.writeEraseProt.fcfgSector = CC23_CCFG_FLASH_PROP(ti_wr_er_prot_fcfg_sect), + .flashProt.writeEraseProt.engrSector = CC23_CCFG_FLASH_PROP(ti_wr_er_prot_engr_sect), + + .flashProt.res = 0xffffffff, + + .flashProt.chipEraseRetain.mainSectors0_31 = + CC23_CCFG_FLASH_PROP(ti_chip_er_retain_sect0_31), + .flashProt.chipEraseRetain.mainSectors32_255 = + CC23_CCFG_FLASH_PROP(ti_chip_er_retain_sect32_255), + + .debugCfg.authorization = CCFG_DBGAUTH_DBGOPEN, + .debugCfg.allowBldr = CCFG_DBGBLDR_ALLOW, +}; diff --git a/soc/ti/simplelink/cc23x0/ccfg.ld b/soc/ti/simplelink/cc23x0/ccfg.ld new file mode 100644 index 0000000000000..a9baf05dcf46d --- /dev/null +++ b/soc/ti/simplelink/cc23x0/ccfg.ld @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +GROUP_START(FLASH_CCFG) + +CRC_CCFG_BOOT_CFG_begin = 0x4e020000; +CRC_CCFG_BOOT_CFG_end = 0x4e02000B; +CRC_CCFG_begin = 0x4E020010; +CRC_CCFG_end = 0x4E02074B; +CRC_CCFG_DEBUG_begin = 0x4E0207D0; +CRC_CCFG_DEBUG_end = 0x4E0207FB; +CRC_CCFG_USER_RECORD_begin = 0x4E020750; +CRC_CCFG_USER_RECORD_end = 0x4E0207CB; +SECTION_PROLOGUE(.ti_ccfg,,) +{ + KEEP(*(_TI_CCFG_SECTION_NAME)) +} GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(ti_ccfg_partition))) + +GROUP_END(FLASH_CCFG) diff --git a/soc/ti/simplelink/cc23x0/linker.ld b/soc/ti/simplelink/cc23x0/linker.ld new file mode 100644 index 0000000000000..448cc70c043d1 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/linker.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/ti/simplelink/cc23x0/pinctrl_soc.h b/soc/ti/simplelink/cc23x0/pinctrl_soc.h new file mode 100644 index 0000000000000..4c2c6fefd1605 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/pinctrl_soc.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TI_SIMPLELINK_CC23X0_SOC_PINCTRL_H_ +#define TI_SIMPLELINK_CC23X0_SOC_PINCTRL_H_ + +#include + +/* IO enabling/disabling */ +#define IOC_INPUT_ENABLE BIT(29) +#define IOC_INPUT_DISABLE 0U +#define IOC_HYST_ENABLE BIT(30) +#define IOC_HYST_DISABLE 0U + +/* IO modes */ +#define IOC_IOMODE_NORMAL 0U +#define IOC_IOMODE_INV BIT(24) +#define IOC_IOMODE_OPEN_DRAIN_NORMAL BIT(25) +#define IOC_IOMODE_OPEN_DRAIN_INV GENMASK(25, 24) +#define IOC_IOMODE_OPEN_SRC_NORMAL BIT(26) +#define IOC_IOMODE_OPEN_SRC_INV (BIT(26) | BIT(24)) + +/* IO pull */ +#define IOC_NO_IOPULL 0U +#define IOC_IOPULL_UP BIT(14) +#define IOC_IOPULL_DOWN BIT(13) + +typedef struct pinctrl_soc_pin { + uint32_t pin; + uint32_t iofunc; + uint32_t iomode; +} pinctrl_soc_pin_t; + +/* Convert DT flags to SoC flags */ +#define CC23X0_PIN_FLAGS(node_id) \ + (DT_PROP(node_id, bias_pull_up) * IOC_IOPULL_UP | \ + DT_PROP(node_id, bias_pull_down) * IOC_IOPULL_DOWN | \ + DT_PROP(node_id, bias_disable) * IOC_NO_IOPULL | \ + DT_PROP(node_id, drive_open_drain) * IOC_IOMODE_OPEN_DRAIN_NORMAL | \ + DT_PROP(node_id, drive_open_source) * IOC_IOMODE_OPEN_SRC_NORMAL | \ + DT_PROP(node_id, input_enable) * IOC_INPUT_ENABLE | \ + DT_PROP(node_id, input_schmitt_enable) * IOC_HYST_ENABLE) + +#define CC23X0_DT_PIN(node_id) \ + {.pin = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .iofunc = DT_PROP_BY_IDX(node_id, pinmux, 1), \ + .iomode = CC23X0_PIN_FLAGS(node_id)}, + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + CC23X0_DT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT)} + +#endif /* TI_SIMPLELINK_CC23X0_SOC_PINCTRL_H_ */ diff --git a/soc/ti/simplelink/cc23x0/soc.c b/soc/ti/simplelink/cc23x0/soc.c new file mode 100644 index 0000000000000..cddae58b4e05d --- /dev/null +++ b/soc/ti/simplelink/cc23x0/soc.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +void soc_reset_hook(void) +{ + /* Perform necessary trim of the device. */ + SetupTrimDevice(); +} diff --git a/soc/ti/simplelink/cc23x0/soc.h b/soc/ti/simplelink/cc23x0/soc.h new file mode 100644 index 0000000000000..968cbc99d9c54 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/soc.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TI_SIMPLELINK_CC23X0_SOC_H_ +#define TI_SIMPLELINK_CC23X0_SOC_H_ + +#include "cmsis/cc23x0r5.h" + +#endif /* TI_SIMPLELINK_CC23X0_SOC_H_ */ diff --git a/soc/ti/simplelink/soc.yml b/soc/ti/simplelink/soc.yml index 2dbf91f315e6f..bbf1ef19de4b5 100644 --- a/soc/ti/simplelink/soc.yml +++ b/soc/ti/simplelink/soc.yml @@ -13,6 +13,9 @@ family: - name: cc1352r7 - name: cc2652p7 - name: cc2652r7 + - name: cc23x0 + socs: + - name: cc2340r5 - name: cc32xx socs: - name: cc3220sf diff --git a/soc/wch/ch32v/CMakeLists.txt b/soc/wch/ch32v/CMakeLists.txt new file mode 100644 index 0000000000000..0f127dd9c7566 --- /dev/null +++ b/soc/wch/ch32v/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Michael Hope +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/wch/ch32v/Kconfig b/soc/wch/ch32v/Kconfig new file mode 100644 index 0000000000000..86da17a0321c6 --- /dev/null +++ b/soc/wch/ch32v/Kconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2024 Michael Hope +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_CH32V + select RISCV + select BUILD_OUTPUT_HEX + select CH32V00X_SYSTICK + select ATOMIC_OPERATIONS_C + imply XIP + +if SOC_FAMILY_CH32V + +config VECTOR_TABLE_SIZE + int "Number of Interrupt and Exception Vectors" + range 20 256 + help + This option defines the total number of interrupt and exception + vectors in the vector table. + +rsource "*/Kconfig" + +endif # SOC_FAMILY_CH32V diff --git a/soc/wch/ch32v/Kconfig.defconfig b/soc/wch/ch32v/Kconfig.defconfig new file mode 100644 index 0000000000000..7d710b5b910be --- /dev/null +++ b/soc/wch/ch32v/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Michael Hope +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_CH32V + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_CH32V diff --git a/soc/wch/ch32v/Kconfig.soc b/soc/wch/ch32v/Kconfig.soc new file mode 100644 index 0000000000000..39cb7270b1cf2 --- /dev/null +++ b/soc/wch/ch32v/Kconfig.soc @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Michael Hope +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_CH32V + bool + +config SOC_FAMILY + default "ch32v" if SOC_FAMILY_CH32V + +rsource "*/Kconfig.soc" diff --git a/soc/wch/ch32v/qingke_v2a/CMakeLists.txt b/soc/wch/ch32v/qingke_v2a/CMakeLists.txt new file mode 100644 index 0000000000000..a7e9de643d690 --- /dev/null +++ b/soc/wch/ch32v/qingke_v2a/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Michael Hope +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + soc_irq.S + vector.S +) + +zephyr_include_directories(.) diff --git a/soc/wch/ch32v/qingke_v2a/Kconfig b/soc/wch/ch32v/qingke_v2a/Kconfig new file mode 100644 index 0000000000000..de004227a4732 --- /dev/null +++ b/soc/wch/ch32v/qingke_v2a/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Michael Hope +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_QINGKE_V2A + select RISCV_ISA_RV32E + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select RISCV_ISA_EXT_C diff --git a/soc/wch/ch32v/qingke_v2a/Kconfig.defconfig b/soc/wch/ch32v/qingke_v2a/Kconfig.defconfig new file mode 100644 index 0000000000000..02aa7004c3c76 --- /dev/null +++ b/soc/wch/ch32v/qingke_v2a/Kconfig.defconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2024 Michael Hope +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_QINGKE_V2A + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +config MAIN_STACK_SIZE + default 512 + +config IDLE_STACK_SIZE + default 256 + +config ISR_STACK_SIZE + default 256 + +config CLOCK_CONTROL + default y + +rsource "Kconfig.defconfig.*" + +endif # SOC_SERIES_QINGKE_V2A diff --git a/soc/wch/ch32v/qingke_v2a/Kconfig.defconfig.ch32v003 b/soc/wch/ch32v/qingke_v2a/Kconfig.defconfig.ch32v003 new file mode 100644 index 0000000000000..44d27fd3865fd --- /dev/null +++ b/soc/wch/ch32v/qingke_v2a/Kconfig.defconfig.ch32v003 @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Michael Hope +# SPDX-License-Identifier: Apache-2.0 + +if SOC_CH32V003 + +config VECTOR_TABLE_SIZE + default 38 + +config NUM_IRQS + default 48 + +endif # SOC_CH32V003 diff --git a/soc/wch/ch32v/qingke_v2a/Kconfig.soc b/soc/wch/ch32v/qingke_v2a/Kconfig.soc new file mode 100644 index 0000000000000..ccf0d2fdf374f --- /dev/null +++ b/soc/wch/ch32v/qingke_v2a/Kconfig.soc @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_QINGKE_V2A + bool + select SOC_FAMILY_CH32V + +config SOC_SERIES + default "qingke_v2a" if SOC_SERIES_QINGKE_V2A + +rsource "Kconfig.soc.*" diff --git a/soc/wch/ch32v/qingke_v2a/Kconfig.soc.ch32v003 b/soc/wch/ch32v/qingke_v2a/Kconfig.soc.ch32v003 new file mode 100644 index 0000000000000..b8ffe5e596bf1 --- /dev/null +++ b/soc/wch/ch32v/qingke_v2a/Kconfig.soc.ch32v003 @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Michael Hope +# SPDX-License-Identifier: Apache-2.0 + +config SOC_CH32V003 + bool + select SOC_SERIES_QINGKE_V2A + +config SOC + default "ch32v003" if SOC_CH32V003 diff --git a/soc/wch/ch32v00x/pinctrl_soc.h b/soc/wch/ch32v/qingke_v2a/pinctrl_soc.h similarity index 100% rename from soc/wch/ch32v00x/pinctrl_soc.h rename to soc/wch/ch32v/qingke_v2a/pinctrl_soc.h diff --git a/soc/wch/ch32v00x/soc_irq.S b/soc/wch/ch32v/qingke_v2a/soc_irq.S similarity index 100% rename from soc/wch/ch32v00x/soc_irq.S rename to soc/wch/ch32v/qingke_v2a/soc_irq.S diff --git a/soc/wch/ch32v/qingke_v2a/vector.S b/soc/wch/ch32v/qingke_v2a/vector.S new file mode 100644 index 0000000000000..d078444d85e15 --- /dev/null +++ b/soc/wch/ch32v/qingke_v2a/vector.S @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#ifndef CONFIG_VECTOR_TABLE_SIZE +#error "VECTOR_TABLE_SIZE must be defined" +#endif + +/* Exports */ +GTEXT(__start) + +/* Imports */ +GTEXT(__initialize) + +SECTION_FUNC(vectors, ivt) + .option norvc + j __start + .rept CONFIG_VECTOR_TABLE_SIZE + .word _isr_wrapper + .endr + +SECTION_FUNC(vectors, __start) + li a0, 3 + csrw mtvec, a0 + j __initialize diff --git a/soc/wch/ch32v/soc.yml b/soc/wch/ch32v/soc.yml new file mode 100644 index 0000000000000..c01905a7ed7c3 --- /dev/null +++ b/soc/wch/ch32v/soc.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Michael Hope +# SPDX-License-Identifier: Apache-2.0 + +family: +- name: ch32v + series: + - name: qingke-v2 + socs: + - name: ch32v003 diff --git a/soc/wch/ch32v00x/CMakeLists.txt b/soc/wch/ch32v00x/CMakeLists.txt deleted file mode 100644 index e16889335807b..0000000000000 --- a/soc/wch/ch32v00x/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2024 Michael Hope -# SPDX-License-Identifier: Apache-2.0 - -zephyr_sources( - soc_irq.S - vector.S -) - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/wch/ch32v00x/Kconfig b/soc/wch/ch32v00x/Kconfig deleted file mode 100644 index c5de3547451ed..0000000000000 --- a/soc/wch/ch32v00x/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2024 Michael Hope -# SPDX-License-Identifier: Apache-2.0 - -config SOC_CH32V003 - select RISCV - select BUILD_OUTPUT_HEX - select RISCV_ISA_RV32E - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - select RISCV_ISA_EXT_C - select CH32V00X_SYSTICK - select ATOMIC_OPERATIONS_C - imply XIP diff --git a/soc/wch/ch32v00x/Kconfig.defconfig b/soc/wch/ch32v00x/Kconfig.defconfig deleted file mode 100644 index ecdd57f74f7c8..0000000000000 --- a/soc/wch/ch32v00x/Kconfig.defconfig +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2024 Michael Hope -# SPDX-License-Identifier: Apache-2.0 - -if SOC_CH32V003 - -config NUM_IRQS - default 48 - -config SYS_CLOCK_HW_CYCLES_PER_SEC - default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) - -config MAIN_STACK_SIZE - default 512 - -config IDLE_STACK_SIZE - default 256 - -config ISR_STACK_SIZE - default 256 - -config CLOCK_CONTROL - default y - -endif # SOC_CH32V003 diff --git a/soc/wch/ch32v00x/Kconfig.soc b/soc/wch/ch32v00x/Kconfig.soc deleted file mode 100644 index c717a405603e6..0000000000000 --- a/soc/wch/ch32v00x/Kconfig.soc +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2024 Michael Hope -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_CH32V00X - bool - -config SOC_CH32V003 - bool - select SOC_SERIES_CH32V00X - -config SOC_SERIES - default "ch32v00x" if SOC_SERIES_CH32V00X - -config SOC - default "ch32v003" if SOC_CH32V003 diff --git a/soc/wch/ch32v00x/soc.yml b/soc/wch/ch32v00x/soc.yml deleted file mode 100644 index 5c39c57a7c7d9..0000000000000 --- a/soc/wch/ch32v00x/soc.yml +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2024 Michael Hope -# SPDX-License-Identifier: Apache-2.0 - -series: - - name: ch32v00x - socs: - - name: ch32v003 diff --git a/soc/wch/ch32v00x/vector.S b/soc/wch/ch32v00x/vector.S deleted file mode 100644 index 7abbc167c9c92..0000000000000 --- a/soc/wch/ch32v00x/vector.S +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024 Michael Hope - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -/* Exports */ -GTEXT(__start) - -/* Imports */ -GTEXT(__initialize) - -SECTION_FUNC(vectors, ivt) - .option norvc - j __start - .rept 38 - .word _isr_wrapper - .endr - -SECTION_FUNC(vectors, __start) - li a0, 3 - csrw mtvec, a0 - j __initialize diff --git a/soc/xlnx/zynq7000/xc7zxxx/soc.c b/soc/xlnx/zynq7000/xc7zxxx/soc.c index c1dad84ff36e3..5bc0c422b1546 100644 --- a/soc/xlnx/zynq7000/xc7zxxx/soc.c +++ b/soc/xlnx/zynq7000/xc7zxxx/soc.c @@ -52,14 +52,6 @@ static const struct arm_mmu_region mmu_regions[] = { MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), #endif -/* GPIO controller */ -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(psgpio)) - MMU_REGION_FLAT_ENTRY("psgpio", - DT_REG_ADDR(DT_NODELABEL(psgpio)), - DT_REG_SIZE(DT_NODELABEL(psgpio)), - MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), -#endif - DT_FOREACH_STATUS_OKAY(xlnx_xps_gpio_1_00_a, AXI_GPIO_MMU_ENTRY) }; diff --git a/soc/xlnx/zynq7000/xc7zxxxs/soc.c b/soc/xlnx/zynq7000/xc7zxxxs/soc.c index 982ee094e01f7..b19e9e43ce16c 100644 --- a/soc/xlnx/zynq7000/xc7zxxxs/soc.c +++ b/soc/xlnx/zynq7000/xc7zxxxs/soc.c @@ -52,14 +52,6 @@ static const struct arm_mmu_region mmu_regions[] = { MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), #endif -/* GPIO controller */ -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(psgpio)) - MMU_REGION_FLAT_ENTRY("psgpio", - DT_REG_ADDR(DT_NODELABEL(psgpio)), - DT_REG_SIZE(DT_NODELABEL(psgpio)), - MT_DEVICE | MATTR_SHARED | MPERM_R | MPERM_W), -#endif - DT_FOREACH_STATUS_OKAY(xlnx_xps_gpio_1_00_a, AXI_GPIO_MMU_ENTRY) }; diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml index 8365f5d5b02e2..b3d961d267034 100644 --- a/submanifests/optional.yaml +++ b/submanifests/optional.yaml @@ -23,7 +23,7 @@ manifest: groups: - optional - name: nanopb - revision: 98bf4db69897b53434f3d0ba72e0a3ab1a902824 + revision: 7307ce399b81ddcb3c3a5dc862c52d4754328d38 path: modules/lib/nanopb remote: upstream groups: @@ -35,7 +35,7 @@ manifest: groups: - optional - name: sof - revision: 316f414b64dee8e4aefce503af6c2c2e57d266f4 + revision: bc08c9c606324cfba0c104f4ffaf5dd456cb11d6 path: modules/audio/sof remote: upstream groups: @@ -47,7 +47,7 @@ manifest: groups: - optional - name: tflite-micro - revision: 48613f7ba1ffbda46ad771a77a35408f48f922e9 + revision: 8d404de73acf7687831e16d88e86e4f73cfddf8e path: optional/modules/lib/tflite-micro repo-path: tflite-micro remote: upstream @@ -60,7 +60,7 @@ manifest: groups: - optional - name: zephyr-lang-rust - revision: 7af3db47bf7335ac6a6fe7480df6b41fb46dbe9d + revision: 49c6712fe53b5b82e5c09e94548a4a51a021acfe path: modules/lang/rust remote: upstream groups: diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index b4ea9eb476285..61f7f3cf940db 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -46,6 +46,7 @@ add_subdirectory_ifdef(CONFIG_IMG_MANAGER dfu) add_subdirectory_ifdef(CONFIG_INPUT input) add_subdirectory_ifdef(CONFIG_JWT jwt) add_subdirectory_ifdef(CONFIG_LLEXT llext) +add_subdirectory_ifdef(CONFIG_MCTP mctp) add_subdirectory_ifdef(CONFIG_MODEM_MODULES modem) add_subdirectory_ifdef(CONFIG_NETWORKING net) add_subdirectory_ifdef(CONFIG_PROFILING profiling) diff --git a/subsys/Kconfig b/subsys/Kconfig index 561d526342268..93880693f51b5 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -26,6 +26,7 @@ source "subsys/jwt/Kconfig" source "subsys/llext/Kconfig" source "subsys/logging/Kconfig" source "subsys/lorawan/Kconfig" +source "subsys/mctp/Kconfig" source "subsys/mem_mgmt/Kconfig" source "subsys/mgmt/Kconfig" source "subsys/modbus/Kconfig" diff --git a/subsys/bluetooth/Kconfig b/subsys/bluetooth/Kconfig index 1665059ce333e..4bff894c66f10 100644 --- a/subsys/bluetooth/Kconfig +++ b/subsys/bluetooth/Kconfig @@ -225,7 +225,161 @@ config BT_CHANNEL_SOUNDING_REASSEMBLY_BUFFER_CNT endif # BT_CONN -rsource "Kconfig.iso" +config BT_ISO + bool + +config BT_ISO_TX + bool + +config BT_ISO_RX + bool + +#TODO : Split between client(central) and server(peripheral) +config BT_ISO_UNICAST + bool + depends on BT_CONN + select BT_ISO + select BT_ISO_TX + select BT_ISO_RX + help + This option enables support for Bluetooth Unicast + Isochronous channels. + +config BT_ISO_PERIPHERAL + bool "Bluetooth Isochronous Channel Unicast Peripheral Support" + depends on !HAS_BT_CTLR || BT_CTLR_PERIPHERAL_ISO_SUPPORT + depends on BT_PERIPHERAL + select BT_ISO_UNICAST + help + This option enables support for Bluetooth Unicast + Isochronous channels for the peripheral role. + +config BT_ISO_CENTRAL + bool "Bluetooth Isochronous Channel Unicast Central Support" + depends on !HAS_BT_CTLR || BT_CTLR_CENTRAL_ISO_SUPPORT + depends on BT_CENTRAL + select BT_ISO_UNICAST + help + This option enables support for Bluetooth Broadcast + Isochronous channels for the central role. + +config BT_ISO_BROADCAST + bool + select BT_ISO + select BT_EXT_ADV + +config BT_ISO_BROADCASTER + bool "Bluetooth Isochronous Broadcaster Support" + depends on !HAS_BT_CTLR || BT_CTLR_ADV_ISO_SUPPORT + select BT_ISO_BROADCAST + select BT_ISO_TX + select BT_BROADCASTER + select BT_PER_ADV + help + This option enables support for the Bluetooth Isochronous Broadcaster. + +config BT_ISO_SYNC_RECEIVER + bool "Bluetooth Isochronous Synchronized Receiver Support" + depends on !HAS_BT_CTLR || BT_CTLR_SYNC_ISO_SUPPORT + depends on BT_OBSERVER + select BT_ISO_BROADCAST + select BT_ISO_RX + select BT_PER_ADV_SYNC + help + This option enables support for the Bluetooth Isochronous + Synchronized Receiver. + +if BT_ISO + +config BT_ISO_MAX_CHAN + int "Maximum number of simultaneous ISO channels" + depends on BT_ISO + default BT_MAX_CONN if BT_CONN + default 1 + range 1 64 + help + Maximum number of simultaneous Bluetooth isochronous channels + supported. + +config BT_ISO_TX_BUF_COUNT + int "Number of Isochronous TX buffers" + default 1 + range 1 $(UINT8_MAX) + help + Number of buffers available for outgoing Isochronous channel SDUs. + +config BT_ISO_TX_FRAG_COUNT + int "Number of ISO TX fragment buffers" + default 2 + range 0 $(UINT8_MAX) + help + Number of buffers available for fragments of TX buffers. Warning: + setting this to 0 means that the application must ensure that + queued TX buffers never need to be fragmented, i.e. that the + controller's buffer size is large enough. If this is not ensured, + and there are no dedicated fragment buffers, a deadlock may occur. + In most cases the default value of 2 is a safe bet. + +config BT_ISO_TX_MTU + int "Maximum supported MTU for Isochronous TX buffers" + range 1 4095 + default 247 + help + Maximum MTU for Isochronous channels TX buffers. + This is the actual data payload. It doesn't include the optional + HCI ISO Data packet fields (e.g. `struct bt_hci_iso_sdu_ts_hdr`). + Set this value to 247 to fit 247 bytes of data within a single + HCI ISO Data packet with Data_Total_Length of 255, utilizing + timestamps. + +config BT_ISO_RX_BUF_COUNT + int "Number of Isochronous RX buffers" + default 1 + range 1 $(UINT8_MAX) + help + Number of buffers available for incoming Isochronous channel SDUs. + +config BT_ISO_RX_MTU + int "Maximum supported MTU for Isochronous RX buffers" + default 251 + range 23 4095 + help + Maximum MTU for Isochronous channels RX buffers. + This is the actual data payload. It doesn't include the optional + HCI ISO Data packet fields (e.g. `struct bt_hci_iso_sdu_ts_hdr`) + +config BT_ISO_TEST_PARAMS + bool "ISO test parameters support" + help + Enabling advanced ISO parameters will allow the use of the ISO test + parameters for creating a CIG or a BIG. These test parameters were + intended for testing, but can be used to allow the host to set more + settings that are otherwise usually controlled by the controller. + +if BT_ISO_UNICAST + +config BT_ISO_MAX_CIG + int "Maximum number of Connected Isochronous Groups (CIGs) to support" + default 1 + help + Maximum number of CIGs that are supported by the host. A CIG can be + used for either transmitting or receiving. + +endif # BT_ISO_UNICAST + +if BT_ISO_BROADCAST + +config BT_ISO_MAX_BIG + int "Maximum number of Broadcast Isochronous Groups (BIGs) to support" + default 1 + range 1 BT_EXT_ADV_MAX_ADV_SET + help + Maximum number of BIGs that are supported by the host. A BIG can be + used for either transmitting or receiving, but not at the same time. + +endif # BT_ISO_BROADCAST +endif # BT_ISO + rsource "common/Kconfig" rsource "host/Kconfig" rsource "controller/Kconfig" @@ -236,6 +390,7 @@ rsource "Kconfig.logging" config BT_SHELL bool "Bluetooth shell" select SHELL + select BT_PRIVATE_SHELL select BT_TICKER_NEXT_SLOT_GET if BT_LL_SW_SPLIT help Activate shell module that provides Bluetooth commands to the diff --git a/subsys/bluetooth/Kconfig.adv b/subsys/bluetooth/Kconfig.adv index 99b40250a9495..28e1dea61a240 100644 --- a/subsys/bluetooth/Kconfig.adv +++ b/subsys/bluetooth/Kconfig.adv @@ -68,6 +68,14 @@ config BT_PER_ADV_SYNC_RSP Select this to enable Periodic Advertising with Responses Sync API support. +config BT_EXT_ADV_CODING_SELECTION + bool "Advertising Coding Selection support" + depends on !HAS_BT_CTLR || BT_CTLR_PHY_CODED + help + Select this to enable Advertising Coding Selection API support. + This allows the Host to indicate their strict requirement + concerning coding scheme when using Extended Advertising. + if BT_PER_ADV_SYNC config BT_PER_ADV_SYNC_MAX diff --git a/subsys/bluetooth/Kconfig.iso b/subsys/bluetooth/Kconfig.iso deleted file mode 100644 index 4c7bb9a03e32d..0000000000000 --- a/subsys/bluetooth/Kconfig.iso +++ /dev/null @@ -1,159 +0,0 @@ -# Bluetooth Isochronous Channel configuration options - -# Copyright (c) 2016 Intel Corporation -# Copyright (c) 2021 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -config BT_ISO - bool - -config BT_ISO_TX - bool - -config BT_ISO_RX - bool - -# TODO: Split between client (central) and server (peripheral) -config BT_ISO_UNICAST - bool - depends on BT_CONN - select BT_ISO - select BT_ISO_TX - select BT_ISO_RX - help - This option enables support for Bluetooth Unicast - Isochronous channels. - -config BT_ISO_PERIPHERAL - bool "Bluetooth Isochronous Channel Unicast Peripheral Support" - depends on !HAS_BT_CTLR || BT_CTLR_PERIPHERAL_ISO_SUPPORT - depends on BT_PERIPHERAL - select BT_ISO_UNICAST - help - This option enables support for Bluetooth Unicast - Isochronous channels for the peripheral role. - -config BT_ISO_CENTRAL - bool "Bluetooth Isochronous Channel Unicast Central Support" - depends on !HAS_BT_CTLR || BT_CTLR_CENTRAL_ISO_SUPPORT - depends on BT_CENTRAL - select BT_ISO_UNICAST - help - This option enables support for Bluetooth Broadcast - Isochronous channels for the central role. - -config BT_ISO_BROADCAST - bool - select BT_ISO - select BT_EXT_ADV - -config BT_ISO_BROADCASTER - bool "Bluetooth Isochronous Broadcaster Support" - depends on !HAS_BT_CTLR || BT_CTLR_ADV_ISO_SUPPORT - select BT_ISO_BROADCAST - select BT_ISO_TX - select BT_BROADCASTER - select BT_PER_ADV - help - This option enables support for the Bluetooth Isochronous Broadcaster. - -config BT_ISO_SYNC_RECEIVER - bool "Bluetooth Isochronous Synchronized Receiver Support" - depends on !HAS_BT_CTLR || BT_CTLR_SYNC_ISO_SUPPORT - depends on BT_OBSERVER - select BT_ISO_BROADCAST - select BT_ISO_RX - select BT_PER_ADV_SYNC - help - This option enables support for the Bluetooth Isochronous - Synchronized Receiver. - -if BT_ISO - -config BT_ISO_MAX_CHAN - int "Maximum number of simultaneous ISO channels" - depends on BT_ISO - default BT_MAX_CONN if BT_CONN - default 1 - range 1 64 - help - Maximum number of simultaneous Bluetooth isochronous channels - supported. - -config BT_ISO_TX_BUF_COUNT - int "Number of Isochronous TX buffers" - default 1 - range 1 $(UINT8_MAX) - help - Number of buffers available for outgoing Isochronous channel SDUs. - -config BT_ISO_TX_FRAG_COUNT - int "Number of ISO TX fragment buffers" - default 2 - range 0 $(UINT8_MAX) - help - Number of buffers available for fragments of TX buffers. Warning: - setting this to 0 means that the application must ensure that - queued TX buffers never need to be fragmented, i.e. that the - controller's buffer size is large enough. If this is not ensured, - and there are no dedicated fragment buffers, a deadlock may occur. - In most cases the default value of 2 is a safe bet. - -config BT_ISO_TX_MTU - int "Maximum supported MTU for Isochronous TX buffers" - range 1 4095 - default 247 - help - Maximum MTU for Isochronous channels TX buffers. - This is the actual data payload. It doesn't include the optional - HCI ISO Data packet fields (e.g. `struct bt_hci_iso_sdu_ts_hdr`). - Set this value to 247 to fit 247 bytes of data within a single - HCI ISO Data packet with Data_Total_Length of 255, utilizing - timestamps. - -config BT_ISO_RX_BUF_COUNT - int "Number of Isochronous RX buffers" - default 1 - range 1 $(UINT8_MAX) - help - Number of buffers available for incoming Isochronous channel SDUs. - -config BT_ISO_RX_MTU - int "Maximum supported MTU for Isochronous RX buffers" - default 251 - range 23 4095 - help - Maximum MTU for Isochronous channels RX buffers. - This is the actual data payload. It doesn't include the optional - HCI ISO Data packet fields (e.g. `struct bt_hci_iso_sdu_ts_hdr`) - -config BT_ISO_TEST_PARAMS - bool "ISO test parameters support" - help - Enabling advanced ISO parameters will allow the use of the ISO test - parameters for creating a CIG or a BIG. These test parameters were - intended for testing, but can be used to allow the host to set more - settings that are otherwise usually controlled by the controller. - -if BT_ISO_UNICAST - -config BT_ISO_MAX_CIG - int "Maximum number of Connected Isochronous Groups (CIGs) to support" - default 1 - help - Maximum number of CIGs that are supported by the host. A CIG can be - used for either transmitting or receiving. - -endif # BT_ISO_UNICAST - -if BT_ISO_BROADCAST - -config BT_ISO_MAX_BIG - int "Maximum number of Broadcast Isochronous Groups (BIGs) to support" - default 1 - help - Maximum number of BIGs that are supported by the host. A BIG can be - used for either transmitting or receiving, but not at the same time. - -endif # BT_ISO_BROADCAST -endif # BT_ISO diff --git a/subsys/bluetooth/audio/CMakeLists.txt b/subsys/bluetooth/audio/CMakeLists.txt index ef6fc16640b22..a7537140a64e5 100644 --- a/subsys/bluetooth/audio/CMakeLists.txt +++ b/subsys/bluetooth/audio/CMakeLists.txt @@ -58,6 +58,8 @@ zephyr_library_sources_ifdef(CONFIG_BT_BAP_BROADCAST_SOURCE bap_broadcast_source zephyr_library_sources_ifdef(CONFIG_BT_BAP_BROADCAST_SINK bap_broadcast_sink.c) zephyr_library_sources_ifdef(CONFIG_BT_BAP_SCAN_DELEGATOR bap_scan_delegator.c) zephyr_library_sources_ifdef(CONFIG_BT_BAP_BROADCAST_ASSISTANT bap_broadcast_assistant.c) +zephyr_library_sources_ifdef(CONFIG_BT_CCP_CALL_CONTROL_CLIENT ccp_call_control_client.c) +zephyr_library_sources_ifdef(CONFIG_BT_CCP_CALL_CONTROL_SERVER ccp_call_control_server.c) zephyr_library_sources_ifdef(CONFIG_BT_HAS has.c) zephyr_library_sources_ifdef(CONFIG_BT_HAS_CLIENT has_client.c) zephyr_library_sources_ifdef(CONFIG_BT_CAP cap_stream.c) diff --git a/subsys/bluetooth/audio/Kconfig b/subsys/bluetooth/audio/Kconfig index f56c3fe5236ad..bc3335aaf5dff 100644 --- a/subsys/bluetooth/audio/Kconfig +++ b/subsys/bluetooth/audio/Kconfig @@ -34,6 +34,7 @@ config BT_AUDIO_NOTIFY_RETRY_DELAY available. rsource "Kconfig.bap" +rsource "Kconfig.ccp" rsource "Kconfig.vocs" rsource "Kconfig.aics" rsource "Kconfig.vcp" diff --git a/subsys/bluetooth/audio/Kconfig.aics b/subsys/bluetooth/audio/Kconfig.aics index bcc6c2fafdbaf..c2d2283bf9dc2 100644 --- a/subsys/bluetooth/audio/Kconfig.aics +++ b/subsys/bluetooth/audio/Kconfig.aics @@ -10,6 +10,7 @@ config BT_AICS_MAX_INSTANCE_COUNT int "Audio Input Control Service max instance count" + depends on BT_SMP default 0 range 0 15 help @@ -38,6 +39,7 @@ endif # BT_AICS config BT_AICS_CLIENT_MAX_INSTANCE_COUNT int "Audio Input Control Service client max instance count" + depends on BT_SMP default 0 range 0 15 help diff --git a/subsys/bluetooth/audio/Kconfig.ascs b/subsys/bluetooth/audio/Kconfig.ascs index 21f05dd520032..0c4f05e084d21 100644 --- a/subsys/bluetooth/audio/Kconfig.ascs +++ b/subsys/bluetooth/audio/Kconfig.ascs @@ -8,6 +8,7 @@ config BT_ASCS bool "Audio Stream Control Service Support" + depends on BT_SMP help This option enables support for Audio Stream Control Service. @@ -39,7 +40,7 @@ config BT_ASCS_MAX_ACTIVE_ASES default BT_ISO_MAX_CHAN range 1 $(UINT16_MAX) help - The number of simultanesouly supported active ASEs, in particular + The number of simultaneously supported active ASEs, in particular meaning the number of ASEs that are allowed to be in a non-idle state at a single time. diff --git a/subsys/bluetooth/audio/Kconfig.bap b/subsys/bluetooth/audio/Kconfig.bap index c370e0d4e3078..01ab717f379dc 100644 --- a/subsys/bluetooth/audio/Kconfig.bap +++ b/subsys/bluetooth/audio/Kconfig.bap @@ -12,7 +12,6 @@ config BT_BAP_UNICAST config BT_BAP_UNICAST_SERVER bool "Bluetooth Unicast Audio Server Support" depends on BT_GATT_DYNAMIC_DB - depends on BT_GATT_CACHING depends on BT_PERIPHERAL depends on BT_ISO_PERIPHERAL depends on BT_ASCS @@ -171,9 +170,8 @@ if BT_BAP_BROADCAST_SINK config BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT int "Basic Audio Profile Broadcast Sink subgroup count" - default 1 - range 1 BT_ISO_MAX_CHAN if BT_ISO_MAX_CHAN < 31 - range 1 31 + default BT_BAP_BASS_MAX_SUBGROUPS + range 1 BT_BAP_BASS_MAX_SUBGROUPS help This option sets the maximum number of subgroups per broadcast sink to support. diff --git a/subsys/bluetooth/audio/Kconfig.ccp b/subsys/bluetooth/audio/Kconfig.ccp new file mode 100644 index 0000000000000..c397b831cfc01 --- /dev/null +++ b/subsys/bluetooth/audio/Kconfig.ccp @@ -0,0 +1,59 @@ +# Bluetooth Audio - Call Control Profile (CCP) configuration options +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +if BT_AUDIO + +config BT_CCP_CALL_CONTROL_CLIENT + bool "Call Control Profile Client Support" + depends on BT_EXT_ADV + depends on BT_TBS_CLIENT + depends on BT_BONDABLE + help + This option enables support for the Call Control Profile Client which uses the Telephone + Bearer Service (TBS) client to control calls on a remote device. + +if BT_CCP_CALL_CONTROL_CLIENT + +config BT_CCP_CALL_CONTROL_CLIENT_BEARER_COUNT + int "Telephone bearer count" + default 1 + range 1 $(UINT8_MAX) if BT_TBS_CLIENT_TBS + range 1 1 + help + The number of supported telephone bearers on the CCP Call Control Client + +module = BT_CCP_CALL_CONTROL_CLIENT +module-str = "Call Control Profile Client" +source "subsys/logging/Kconfig.template.log_config" + +endif # BT_CCP_CALL_CONTROL_CLIENT + +config BT_CCP_CALL_CONTROL_SERVER + bool "Call Control Profile Call Control Server Support" + depends on BT_EXT_ADV + depends on BT_TBS + depends on BT_BONDABLE + help + This option enables support for the Call Control Profile Call Control Server which uses + the Telephone Bearer Service (TBS) to hold and control calls on a device. + +if BT_CCP_CALL_CONTROL_SERVER + +config BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT + int "Telephone bearer count" + default 1 + range 1 $(UINT8_MAX) + help + The number of supported telephone bearers on the CCP Call Control Server + +module = BT_CCP_CALL_CONTROL_SERVER +module-str = "Call Control Profile Call Control Server" +source "subsys/logging/Kconfig.template.log_config" + +endif # BT_CCP_CALL_CONTROL_SERVER + +endif # BT_AUDIO diff --git a/subsys/bluetooth/audio/Kconfig.csip b/subsys/bluetooth/audio/Kconfig.csip index 7ca25770c0fa2..9796a54329dc6 100644 --- a/subsys/bluetooth/audio/Kconfig.csip +++ b/subsys/bluetooth/audio/Kconfig.csip @@ -10,6 +10,8 @@ config BT_CSIP_SET_MEMBER bool "Coordinated Set Identification Profile Set Member support" + depends on BT_GATT_DYNAMIC_DB + depends on BT_SMP imply BT_EXT_ADV if BT_PRIVACY help This option enables support for Coordinated Set Identification @@ -35,7 +37,7 @@ config BT_CSIP_SET_MEMBER_ENC_SIRK_SUPPORT Enables support encrypting the SIRK. config BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT - int "Coordinated Set Identification Profle max service instance count" + int "Coordinated Set Identification Profile max service instance count" default 1 range 1 $(UINT8_MAX) help @@ -59,6 +61,7 @@ config BT_CSIP_SET_COORDINATOR bool "Coordinated Set Identification Profile Set Coordinator Support" depends on BT_GATT_CLIENT depends on BT_GATT_AUTO_DISCOVER_CCC + depends on BT_SMP help This option enables support for Coordinated Set Identification Profile Set Coordinator. diff --git a/subsys/bluetooth/audio/Kconfig.has b/subsys/bluetooth/audio/Kconfig.has index adf8cda6bbb1f..541ee84468bb1 100644 --- a/subsys/bluetooth/audio/Kconfig.has +++ b/subsys/bluetooth/audio/Kconfig.has @@ -60,5 +60,6 @@ config BT_HAS_CLIENT depends on BT_GATT_CLIENT depends on BT_GATT_AUTO_DISCOVER_CCC depends on BT_GATT_AUTO_UPDATE_MTU + depends on BT_SMP help This option enables support for Hearing Access Service Client. diff --git a/subsys/bluetooth/audio/Kconfig.mcs b/subsys/bluetooth/audio/Kconfig.mcs index 6c08dd57d2022..d1103f796d3ba 100644 --- a/subsys/bluetooth/audio/Kconfig.mcs +++ b/subsys/bluetooth/audio/Kconfig.mcs @@ -13,6 +13,7 @@ config BT_MCS depends on MCTL_LOCAL_PLAYER_REMOTE_CONTROL depends on UTF8 depends on BT_GATT_DYNAMIC_DB + depends on BT_SMP help This option enables support for the Media Control Service. @@ -22,6 +23,7 @@ config BT_MCC bool "Media Control Client Support" depends on BT_GATT_CLIENT depends on BT_GATT_AUTO_DISCOVER_CCC + depends on BT_SMP help This option enables support for the Media Control Client. diff --git a/subsys/bluetooth/audio/Kconfig.pacs b/subsys/bluetooth/audio/Kconfig.pacs index fba32e709fd28..a0e851f1ae64a 100644 --- a/subsys/bluetooth/audio/Kconfig.pacs +++ b/subsys/bluetooth/audio/Kconfig.pacs @@ -9,6 +9,8 @@ menu "Published Audio Capabilities (PAC) options" config BT_PAC_SNK bool "Sink PAC Characteristic Support" + depends on BT_GATT_DYNAMIC_DB + depends on BT_SMP help This option enables support for Sink Published Audio Capabilities. @@ -43,6 +45,7 @@ endif # BT_PACS_SNK config BT_PAC_SRC bool "Source PAC Characteristic Support" + depends on BT_GATT_DYNAMIC_DB help This option enables support for Source Published Audio Capabilities. diff --git a/subsys/bluetooth/audio/Kconfig.tbs b/subsys/bluetooth/audio/Kconfig.tbs index 14729499bee46..6b3cfa77bc19f 100644 --- a/subsys/bluetooth/audio/Kconfig.tbs +++ b/subsys/bluetooth/audio/Kconfig.tbs @@ -13,6 +13,7 @@ if BT_AUDIO config BT_TBS bool "Telephone Bearer Service Support" depends on BT_GATT_DYNAMIC_DB + depends on BT_SMP depends on UTF8 help This option enables support for Telephone Bearer Service. By default this only @@ -58,20 +59,24 @@ endif # BT_TBS config BT_TBS_CLIENT_GTBS bool "Generic Telephone Bearer Service client support" + depends on BT_GATT_CLIENT + depends on BT_GATT_AUTO_DISCOVER_CCC + depends on BT_SMP depends on UTF8 help This option enables support for the GTBS-oriented Call Control client. config BT_TBS_CLIENT_TBS bool "Telephone Bearer Service client support" + depends on BT_GATT_CLIENT + depends on BT_GATT_AUTO_DISCOVER_CCC + depends on BT_SMP depends on UTF8 help This option enables support for the TBS-oriented Call Control client. config BT_TBS_CLIENT def_bool BT_TBS_CLIENT_GTBS || BT_TBS_CLIENT_TBS - depends on BT_GATT_CLIENT - depends on BT_GATT_AUTO_DISCOVER_CCC if BT_TBS_CLIENT diff --git a/subsys/bluetooth/audio/Kconfig.tmap b/subsys/bluetooth/audio/Kconfig.tmap index aa5dd7e727c66..bd450f3d1540c 100644 --- a/subsys/bluetooth/audio/Kconfig.tmap +++ b/subsys/bluetooth/audio/Kconfig.tmap @@ -4,6 +4,25 @@ # # SPDX-License-Identifier: Apache-2.0 # +config BT_TMAP_CG_SUPPORTED + def_bool (BT_CAP_INITIATOR && BT_CAP_COMMANDER && BT_BAP_UNICAST_CLIENT && BT_AUDIO_RX && \ + BT_AUDIO_TX && BT_VCP_VOL_CTLR && BT_TBS) + +config BT_TMAP_CT_SUPPORTED + def_bool BT_CAP_ACCEPTOR && BT_BAP_UNICAST_SERVER + +config BT_TMAP_UMS_SUPPORTED + def_bool (BT_CAP_INITIATOR && BT_CAP_COMMANDER && BT_BAP_UNICAST_CLIENT && BT_AUDIO_TX && \ + BT_VCP_VOL_CTLR && BT_MCS) + +config BT_TMAP_UMR_SUPPORTED + def_bool BT_CAP_ACCEPTOR && BT_BAP_UNICAST_SERVER && BT_VCP_VOL_REND + +config BT_TMAP_BMS_SUPPORTED + def_bool BT_CAP_INITIATOR && BT_BAP_BROADCAST_SOURCE + +config BT_TMAP_BMR_SUPPORTED + def_bool BT_CAP_ACCEPTOR && BT_BAP_BROADCAST_SINK && BT_VCP_VOL_REND config BT_TMAP bool "Telephony and Media Audio Profile" diff --git a/subsys/bluetooth/audio/Kconfig.vcp b/subsys/bluetooth/audio/Kconfig.vcp index 3699e56c822fe..7b23a544ee4e9 100644 --- a/subsys/bluetooth/audio/Kconfig.vcp +++ b/subsys/bluetooth/audio/Kconfig.vcp @@ -11,6 +11,7 @@ config BT_VCP_VOL_REND bool "Volume Control Profile Volume Renderer Support" depends on BT_GATT_DYNAMIC_DB + depends on BT_SMP help This option enables support for Volume Control Profile Volume Renderer role and the Volume Control Service. @@ -60,6 +61,7 @@ config BT_VCP_VOL_CTLR bool "Volume Control Profile Volume Controller Support" depends on BT_GATT_CLIENT depends on BT_GATT_AUTO_DISCOVER_CCC + depends on BT_SMP help This option enables support for Volume Control Profile Volume Controller. diff --git a/subsys/bluetooth/audio/Kconfig.vocs b/subsys/bluetooth/audio/Kconfig.vocs index d582b2aaab4a9..94b0748f4e83d 100644 --- a/subsys/bluetooth/audio/Kconfig.vocs +++ b/subsys/bluetooth/audio/Kconfig.vocs @@ -9,6 +9,7 @@ config BT_VOCS_MAX_INSTANCE_COUNT int "Volume Offset Control Service max instance count" + depends on BT_SMP default 0 range 0 15 help @@ -36,6 +37,7 @@ endif # BT_VOCS config BT_VOCS_CLIENT_MAX_INSTANCE_COUNT int "Volume Offset Control Service client max instance count" + depends on BT_SMP default 0 range 0 15 help diff --git a/subsys/bluetooth/audio/aics.c b/subsys/bluetooth/audio/aics.c index 222969aba241b..9c87f718adc68 100644 --- a/subsys/bluetooth/audio/aics.c +++ b/subsys/bluetooth/audio/aics.c @@ -487,7 +487,7 @@ int bt_aics_register(struct bt_aics *aics, struct bt_aics_register_param *param) return -EINVAL; } - CHECKIF(param->type > BT_AICS_INPUT_TYPE_STREAMING) { + CHECKIF(param->type > BT_AICS_INPUT_TYPE_AMBIENT) { LOG_DBG("Invalid AICS input type value: %u", param->type); return -EINVAL; } diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index ae94530214c29..f2edf555a9363 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -200,17 +200,6 @@ static void ase_free(struct bt_ascs_ase *ase) (void)k_work_cancel_delayable(&ase->state_transition_work); } -static uint16_t get_max_ntf_size(struct bt_conn *conn) -{ - const uint16_t mtu = conn == NULL ? 0 : bt_gatt_get_mtu(conn); - - if (mtu > NTF_HEADER_SIZE) { - return mtu - NTF_HEADER_SIZE; - } - - return 0U; -} - static int ase_state_notify(struct bt_ascs_ase *ase) { struct bt_conn *conn = ase->conn; @@ -238,7 +227,7 @@ static int ase_state_notify(struct bt_ascs_ase *ase) ascs_ep_get_status(&ase->ep, &ase_buf); - max_ntf_size = get_max_ntf_size(conn); + max_ntf_size = bt_audio_get_max_ntf_size(conn); ntf_size = MIN(max_ntf_size, ase_buf.len); if (ntf_size < ase_buf.len) { @@ -329,10 +318,7 @@ static void ase_enter_state_idle(struct bt_ascs_ase *ase) ase->ep.receiver_ready = false; - if (stream->conn != NULL) { - bt_conn_unref(stream->conn); - stream->conn = NULL; - } + bt_bap_stream_detach(stream); ops = stream->ops; if (ops != NULL && ops->released != NULL) { @@ -1488,32 +1474,12 @@ static void ascs_cp_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) LOG_DBG("attr %p value 0x%04x", attr, value); } -struct codec_cap_lookup_id_data { - uint8_t id; - uint16_t cid; - uint16_t vid; - const struct bt_audio_codec_cap *codec_cap; -}; - -static bool codec_lookup_id(const struct bt_pacs_cap *cap, void *user_data) -{ - struct codec_cap_lookup_id_data *data = user_data; - - if (cap->codec_cap->id == data->id && cap->codec_cap->cid == data->cid && - cap->codec_cap->vid == data->vid) { - data->codec_cap = cap->codec_cap; - - return false; - } - - return true; -} - static int ascs_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, uint16_t vid, uint8_t *cc, uint8_t len, struct bt_bap_ascs_rsp *rsp) { + const struct bt_audio_codec_cap *codec_cap; struct bt_audio_codec_cfg *codec_cfg; - struct codec_cap_lookup_id_data lookup_data = { + const struct bt_pac_codec codec_id = { .id = id, .cid = cid, .vid = vid, @@ -1530,11 +1496,11 @@ static int ascs_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, uin LOG_DBG("ep %p dir %s codec id 0x%02x cid 0x%04x vid 0x%04x len %u", ep, bt_audio_dir_str(ep->dir), id, cid, vid, len); - bt_pacs_cap_foreach(ep->dir, codec_lookup_id, &lookup_data); - - if (lookup_data.codec_cap == NULL) { - LOG_DBG("Codec with id %u for dir %s is not supported by our capabilities", - id, bt_audio_dir_str(ep->dir)); + codec_cap = bt_pacs_get_codec_cap(ep->dir, &codec_id); + if (codec_cap == NULL) { + LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x for dir %s is not " + "supported by our capabilities", + codec_id.id, codec_id.cid, codec_id.vid, bt_audio_dir_str(ep->dir)); *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID, BT_BAP_ASCS_REASON_CODEC); @@ -1546,7 +1512,7 @@ static int ascs_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, uin codec_cfg->vid = vid; codec_cfg->data_len = len; memcpy(codec_cfg->data, cc, len); - codec_cfg->path_id = lookup_data.codec_cap->path_id; + codec_cfg->path_id = codec_cap->path_id; *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE); @@ -1728,10 +1694,11 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream, struct bt_audio_codec_cfg *codec_cfg, const struct bt_bap_qos_cfg_pref *qos_pref) { - int err; + const struct bt_audio_codec_cap *codec_cap; struct bt_ascs_ase *ase = NULL; + struct bt_pac_codec codec_id; struct bt_bap_ep *ep; - struct codec_cap_lookup_id_data lookup_data; + int err; CHECKIF(conn == NULL || stream == NULL || codec_cfg == NULL || qos_pref == NULL) { LOG_DBG("NULL value(s) supplied)"); @@ -1763,15 +1730,15 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream, return -EINVAL; } - lookup_data.id = codec_cfg->id; - lookup_data.cid = codec_cfg->cid; - lookup_data.vid = codec_cfg->vid; - - bt_pacs_cap_foreach(ep->dir, codec_lookup_id, &lookup_data); + codec_id.id = codec_cfg->id; + codec_id.cid = codec_cfg->cid; + codec_id.vid = codec_cfg->vid; - if (lookup_data.codec_cap == NULL) { - LOG_DBG("Codec with id %u for dir %s is not supported by our capabilities", - codec_cfg->id, bt_audio_dir_str(ep->dir)); + codec_cap = bt_pacs_get_codec_cap(ep->dir, &codec_id); + if (codec_cap == NULL) { + LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x for dir %s is not " + "supported by our capabilities", + codec_id.id, codec_id.cid, codec_id.vid, bt_audio_dir_str(ep->dir)); return -ENOENT; } @@ -1793,7 +1760,7 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream, static uint16_t get_max_ase_rsp_for_conn(struct bt_conn *conn) { - const uint16_t max_ntf_size = get_max_ntf_size(conn); + const uint16_t max_ntf_size = bt_audio_get_max_ntf_size(conn); const size_t rsp_hdr_size = sizeof(struct bt_ascs_cp_rsp); if (max_ntf_size > rsp_hdr_size) { @@ -3290,7 +3257,7 @@ int bt_ascs_unregister(void) } err = bt_gatt_service_unregister(&ascs_svc); - /* If unregistration was succesfull, make sure to reset ascs_attrs so it can be used for + /* If unregistration was successful, make sure to reset ascs_attrs so it can be used for * new registrations */ if (err != 0) { diff --git a/subsys/bluetooth/audio/ascs_internal.h b/subsys/bluetooth/audio/ascs_internal.h index 1651e21f42d68..97658999cc63b 100644 --- a/subsys/bluetooth/audio/ascs_internal.h +++ b/subsys/bluetooth/audio/ascs_internal.h @@ -11,6 +11,8 @@ #ifndef BT_ASCS_INTERNAL_H #define BT_ASCS_INTERNAL_H +#include + #include #include #include diff --git a/subsys/bluetooth/audio/audio.c b/subsys/bluetooth/audio/audio.c index 55412c4f7e1a9..75109d4fd9657 100644 --- a/subsys/bluetooth/audio/audio.c +++ b/subsys/bluetooth/audio/audio.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "audio_internal.h" @@ -256,4 +257,16 @@ ssize_t bt_audio_ccc_cfg_write(struct bt_conn *conn, const struct bt_gatt_attr * return sizeof(value); } + +uint16_t bt_audio_get_max_ntf_size(struct bt_conn *conn) +{ + const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */ + const uint16_t mtu = conn == NULL ? 0 : bt_gatt_get_mtu(conn); + + if (mtu > att_ntf_header_size) { + return mtu - att_ntf_header_size; + } + + return 0U; +} #endif /* CONFIG_BT_CONN */ diff --git a/subsys/bluetooth/audio/audio_internal.h b/subsys/bluetooth/audio/audio_internal.h index 4336b8ede0609..49e8aa070626a 100644 --- a/subsys/bluetooth/audio/audio_internal.h +++ b/subsys/bluetooth/audio/audio_internal.h @@ -79,3 +79,4 @@ static inline const char *bt_audio_dir_str(enum bt_audio_dir dir) } bool bt_audio_valid_ltv(const uint8_t *data, uint8_t data_len); +uint16_t bt_audio_get_max_ntf_size(struct bt_conn *conn); diff --git a/subsys/bluetooth/audio/bap_base.c b/subsys/bluetooth/audio/bap_base.c index cba23a66c8f87..313456f3bde4b 100644 --- a/subsys/bluetooth/audio/bap_base.c +++ b/subsys/bluetooth/audio/bap_base.c @@ -30,7 +30,6 @@ LOG_MODULE_REGISTER(bt_bap_base, CONFIG_BT_BAP_BASE_LOG_LEVEL); /* The BASE and the following defines are defined by BAP v1.0.1, section 3.7.2.2 Basic Audio * Announcements */ -#define BASE_MAX_SIZE (UINT8_MAX - 1 /* type */ - BT_UUID_SIZE_16) #define BASE_CODEC_ID_SIZE (1 /* id */ + 2 /* cid */ + 2 /* vid */) #define BASE_PD_SIZE 3 #define BASE_SUBGROUP_COUNT_SIZE 1 @@ -39,14 +38,14 @@ LOG_MODULE_REGISTER(bt_bap_base, CONFIG_BT_BAP_BASE_LOG_LEVEL); #define BASE_META_LEN_SIZE 1 #define BASE_BIS_INDEX_SIZE 1 #define BASE_BIS_CC_LEN_SIZE 1 -#define BASE_SUBGROUP_MAX_SIZE (BASE_MAX_SIZE - BASE_PD_SIZE - BASE_SUBGROUP_COUNT_SIZE) +#define BASE_SUBGROUP_MAX_SIZE (BT_BASE_MAX_SIZE - BASE_PD_SIZE - BASE_SUBGROUP_COUNT_SIZE) #define BASE_SUBGROUP_MIN_SIZE \ (BASE_NUM_BIS_SIZE + BASE_CODEC_ID_SIZE + BASE_CC_LEN_SIZE + BASE_META_LEN_SIZE + \ BASE_BIS_INDEX_SIZE + BASE_BIS_CC_LEN_SIZE) #define BASE_MIN_SIZE \ (BT_UUID_SIZE_16 + BASE_PD_SIZE + BASE_SUBGROUP_COUNT_SIZE + BASE_SUBGROUP_MIN_SIZE) #define BASE_SUBGROUP_MAX_COUNT \ - ((BASE_MAX_SIZE - BASE_PD_SIZE - BASE_SUBGROUP_COUNT_SIZE) / BASE_SUBGROUP_MIN_SIZE) + ((BT_BASE_MAX_SIZE - BASE_PD_SIZE - BASE_SUBGROUP_COUNT_SIZE) / BASE_SUBGROUP_MIN_SIZE) static uint32_t base_pull_pd(struct net_buf_simple *net_buf) { @@ -233,7 +232,7 @@ int bt_bap_base_get_size(const struct bt_bap_base *base) return -EINVAL; } - net_buf_simple_init_with_data(&net_buf, (void *)base, BASE_MAX_SIZE); + net_buf_simple_init_with_data(&net_buf, (void *)base, BT_BASE_MAX_SIZE); base_pull_pd(&net_buf); size += BASE_PD_SIZE; subgroup_count = net_buf_simple_pull_u8(&net_buf); @@ -301,7 +300,7 @@ int bt_bap_base_get_subgroup_count(const struct bt_bap_base *base) return -EINVAL; } - net_buf_simple_init_with_data(&net_buf, (void *)base, BASE_MAX_SIZE); + net_buf_simple_init_with_data(&net_buf, (void *)base, BT_BASE_MAX_SIZE); base_pull_pd(&net_buf); subgroup_count = net_buf_simple_pull_u8(&net_buf); @@ -329,7 +328,7 @@ int bt_bap_base_foreach_subgroup(const struct bt_bap_base *base, return -EINVAL; } - net_buf_simple_init_with_data(&net_buf, (void *)base, BASE_MAX_SIZE); + net_buf_simple_init_with_data(&net_buf, (void *)base, BT_BASE_MAX_SIZE); base_pull_pd(&net_buf); subgroup_count = net_buf_simple_pull_u8(&net_buf); diff --git a/subsys/bluetooth/audio/bap_broadcast_assistant.c b/subsys/bluetooth/audio/bap_broadcast_assistant.c index f5105eb24032e..db2b78df3ad10 100644 --- a/subsys/bluetooth/audio/bap_broadcast_assistant.c +++ b/subsys/bluetooth/audio/bap_broadcast_assistant.c @@ -48,6 +48,7 @@ LOG_MODULE_REGISTER(bt_bap_broadcast_assistant, CONFIG_BT_BAP_BROADCAST_ASSISTAN #include "common/bt_str.h" +#include "audio_internal.h" #include "bap_internal.h" #include "../host/conn_internal.h" #include "../host/hci_core.h" @@ -514,8 +515,7 @@ static uint8_t notify_handler(struct bt_conn *conn, } if (length != 0) { - const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */ - const uint16_t max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size; + const uint16_t max_ntf_size = bt_audio_get_max_ntf_size(conn); /* Cancel any pending long reads containing now obsolete information */ (void)k_work_cancel_delayable(&inst->bap_read_work); @@ -1238,6 +1238,112 @@ int bt_bap_broadcast_assistant_scan_stop(struct bt_conn *conn) return bt_bap_broadcast_assistant_common_cp(conn, &att_buf); } +static bool bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs, uint32_t aggregated_bis_syncs) +{ + if (requested_bis_syncs == 0U || aggregated_bis_syncs == 0U) { + return true; + } + + if (requested_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF && + aggregated_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF) { + return true; + } + + return (requested_bis_syncs & aggregated_bis_syncs) != 0U; +} + +static bool valid_subgroup_params(uint8_t pa_sync, const struct bt_bap_bass_subgroup subgroups[], + uint8_t num_subgroups) +{ + uint32_t aggregated_bis_syncs = 0U; + + for (uint8_t i = 0U; i < num_subgroups; i++) { + /* BIS sync values of 0 and BT_BAP_BIS_SYNC_NO_PREF are allowed at any time, but any + * other values are only allowed if PA sync state is also set + */ + CHECKIF(pa_sync == 0 && (subgroups[i].bis_sync != 0U && + subgroups[i].bis_sync != BT_BAP_BIS_SYNC_NO_PREF)) { + LOG_DBG("[%u]: Only syncing to BIS is not allowed", i); + + return false; + } + + /* Verify that the request BIS sync indexes are unique or no preference */ + if (!bis_syncs_unique_or_no_pref(subgroups[i].bis_sync, aggregated_bis_syncs)) { + LOG_DBG("[%u]: Duplicate BIS index 0x%08x (aggregated 0x%08x)", i, + subgroups[i].bis_sync, aggregated_bis_syncs); + + return false; + } + + /* Keep track of BIS sync values to ensure that we do not have duplicates */ + if (subgroups[i].bis_sync != BT_BAP_BIS_SYNC_NO_PREF) { + aggregated_bis_syncs |= subgroups[i].bis_sync; + } + +#if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) + if (subgroups[i].metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) { + LOG_DBG("[%u]: Invalid metadata_len: %u", i, subgroups[i].metadata_len); + + return false; + } + } +#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */ + + return true; +} + +static bool valid_add_src_param(const struct bt_bap_broadcast_assistant_add_src_param *param) +{ + CHECKIF(param == NULL) { + LOG_DBG("param is NULL"); + return false; + } + + CHECKIF(param->addr.type > BT_ADDR_LE_RANDOM) { + LOG_DBG("Invalid address type %u", param->addr.type); + return false; + } + + CHECKIF(param->adv_sid > BT_GAP_SID_MAX) { + LOG_DBG("Invalid adv_sid %u", param->adv_sid); + return false; + } + + CHECKIF(!(param->pa_interval != BT_BAP_PA_INTERVAL_UNKNOWN) && + !IN_RANGE(param->pa_interval, BT_GAP_PER_ADV_MIN_INTERVAL, + BT_GAP_PER_ADV_MAX_INTERVAL)) { + LOG_DBG("Invalid pa_interval 0x%04X", param->pa_interval); + return false; + } + + CHECKIF(param->broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) { + LOG_DBG("Invalid broadcast_id 0x%08X", param->broadcast_id); + return false; + } + + CHECKIF(param->num_subgroups != 0 && param->subgroups == NULL) { + LOG_DBG("Subgroups are NULL when num_subgroups = %u", param->num_subgroups); + return false; + } + + CHECKIF(param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) { + LOG_DBG("Too many subgroups %u/%u", param->num_subgroups, + CONFIG_BT_BAP_BASS_MAX_SUBGROUPS); + + return false; + } + + CHECKIF(param->subgroups != NULL) { + if (!valid_subgroup_params(param->pa_sync, param->subgroups, + param->num_subgroups)) { + return false; + } + } + + return true; +} + int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn, const struct bt_bap_broadcast_assistant_add_src_param *param) { @@ -1264,6 +1370,10 @@ int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn, return -EINVAL; } + if (!valid_add_src_param(param)) { + return -EINVAL; + } + if (inst->cp_handle == 0) { LOG_DBG("handle not set"); @@ -1315,28 +1425,58 @@ int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn, subgroup->bis_sync = param->subgroups[i].bis_sync; - CHECKIF(param->pa_sync == 0 && subgroup->bis_sync != 0) { - LOG_DBG("Only syncing to BIS is not allowed"); - - atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY); - - return -EINVAL; - } - +#if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) if (param->subgroups[i].metadata_len != 0) { - (void)memcpy(subgroup->metadata, - param->subgroups[i].metadata, + (void)memcpy(subgroup->metadata, param->subgroups[i].metadata, param->subgroups[i].metadata_len); subgroup->metadata_len = param->subgroups[i].metadata_len; } else { - subgroup->metadata_len = 0; + subgroup->metadata_len = 0U; } - +#else + subgroup->metadata_len = 0U; +#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */ } return bt_bap_broadcast_assistant_common_cp(conn, &att_buf); } +static bool valid_add_mod_param(const struct bt_bap_broadcast_assistant_mod_src_param *param) +{ + CHECKIF(param == NULL) { + LOG_DBG("param is NULL"); + return false; + } + + CHECKIF(!(param->pa_interval != BT_BAP_PA_INTERVAL_UNKNOWN) && + !IN_RANGE(param->pa_interval, BT_GAP_PER_ADV_MIN_INTERVAL, + BT_GAP_PER_ADV_MAX_INTERVAL)) { + LOG_DBG("Invalid pa_interval 0x%04X", param->pa_interval); + return false; + } + + CHECKIF(param->num_subgroups != 0 && param->subgroups == NULL) { + LOG_DBG("Subgroups are NULL when num_subgroups = %u", param->num_subgroups); + return false; + } + + CHECKIF(param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) { + LOG_DBG("Too many subgroups %u/%u", param->num_subgroups, + CONFIG_BT_BAP_BASS_MAX_SUBGROUPS); + + return false; + } + + CHECKIF(param->subgroups != NULL) { + if (!valid_subgroup_params(param->pa_sync, param->subgroups, + param->num_subgroups)) { + return false; + } + } + + return true; +} + int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn, const struct bt_bap_broadcast_assistant_mod_src_param *param) { @@ -1351,6 +1491,10 @@ int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn, return -EINVAL; } + if (!valid_add_mod_param(param)) { + return -EINVAL; + } + inst = inst_by_conn(conn); if (inst == NULL) { return -EINVAL; @@ -1423,22 +1567,18 @@ int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn, subgroup->bis_sync = param->subgroups[i].bis_sync; - CHECKIF(param->pa_sync == 0 && subgroup->bis_sync != 0) { - LOG_DBG("Only syncing to BIS is not allowed"); - - atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY); - - return -EINVAL; - } - +#if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) if (param->subgroups[i].metadata_len != 0) { (void)memcpy(subgroup->metadata, param->subgroups[i].metadata, param->subgroups[i].metadata_len); subgroup->metadata_len = param->subgroups[i].metadata_len; } else { - subgroup->metadata_len = 0; + subgroup->metadata_len = 0U; } +#else + subgroup->metadata_len = 0U; +#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */ } return bt_bap_broadcast_assistant_common_cp(conn, &att_buf); diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index d6b8578696805..fa1f0b8ee5645 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -1,7 +1,7 @@ /* Bluetooth Audio Broadcast Sink */ /* - * Copyright (c) 2021-2023 Nordic Semiconductor ASA + * Copyright (c) 2021-2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,6 +43,7 @@ #include "audio_internal.h" #include "bap_iso.h" #include "bap_endpoint.h" +#include "pacs_internal.h" LOG_MODULE_REGISTER(bt_bap_broadcast_sink, CONFIG_BT_BAP_BROADCAST_SINK_LOG_LEVEL); @@ -402,11 +403,6 @@ static void broadcast_sink_iso_disconnected(struct bt_iso_chan *chan, if (!sys_slist_find_and_remove(&sink->streams, &stream->_node)) { LOG_DBG("Could not find and remove stream %p from sink %p", stream, sink); } - - /* Clear sink->big if not already cleared */ - if (sys_slist_is_empty(&sink->streams) && sink->big) { - broadcast_sink_clear_big(sink, reason); - } } if (ops != NULL && ops->stopped != NULL) { @@ -449,6 +445,17 @@ static struct bt_bap_broadcast_sink *broadcast_sink_get_by_pa(struct bt_le_per_a return NULL; } +static struct bt_bap_broadcast_sink *broadcast_sink_get_by_big(const struct bt_iso_big *big) +{ + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sinks); i++) { + if (broadcast_sinks[i].big == big) { + return &broadcast_sinks[i]; + } + } + + return NULL; +} + static void broadcast_sink_add_src(struct bt_bap_broadcast_sink *sink) { struct bt_bap_scan_delegator_add_src_param add_src_param; @@ -536,10 +543,9 @@ static void update_recv_state_base(const struct bt_bap_broadcast_sink *sink, mod_src_param.num_subgroups = sink->subgroup_count; for (uint8_t i = 0U; i < sink->subgroup_count; i++) { struct bt_bap_bass_subgroup *subgroup_param = &mod_src_param.subgroups[i]; - const struct bt_bap_broadcast_sink_subgroup *sink_subgroup = &sink->subgroups[i]; - /* Set the bis_sync value to the indexes available per subgroup */ - subgroup_param->bis_sync = sink_subgroup->bis_indexes & sink->indexes_bitfield; + /* Leave the bis_sync unchanged */ + subgroup_param->bis_sync = recv_state->subgroups[i].bis_sync; } err = bt_bap_scan_delegator_mod_src(&mod_src_param); @@ -548,127 +554,61 @@ static void update_recv_state_base(const struct bt_bap_broadcast_sink *sink, } } -static bool codec_lookup_id(const struct bt_pacs_cap *cap, void *user_data) +static bool base_subgroup_bis_count_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data) { - struct codec_cap_lookup_id_data *data = user_data; - - if (cap->codec_cap->id == data->id) { - data->codec_cap = cap->codec_cap; + uint8_t *bis_cnt = user_data; + int ret; + ret = bt_bap_base_get_subgroup_bis_count(subgroup); + if (ret < 0) { return false; } + *bis_cnt += (uint8_t)ret; + return true; } -struct store_base_info_data { - struct bt_bap_broadcast_sink_bis bis[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; - struct bt_bap_broadcast_sink_subgroup subgroups[CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT]; - struct bt_audio_codec_cfg *subgroup_codec_cfg; - uint32_t valid_indexes_bitfield; - uint8_t subgroup_count; - uint8_t bis_count; -}; - -static bool merge_bis_and_subgroup_data_cb(struct bt_data *data, void *user_data) +static int base_get_bis_count(const struct bt_bap_base *base) { - struct bt_audio_codec_cfg *codec_cfg = user_data; + uint8_t bis_cnt = 0U; int err; - err = bt_audio_codec_cfg_set_val(codec_cfg, data->type, data->data, data->data_len); - if (err < 0) { - LOG_DBG("Failed to set type %u with len %u in codec_cfg: %d", data->type, - data->data_len, err); - - return false; + err = bt_bap_base_foreach_subgroup(base, base_subgroup_bis_count_cb, &bis_cnt); + if (err != 0) { + LOG_DBG("Failed to parse subgroups: %d", err); + return err; } - return true; + return bis_cnt; } -static bool base_subgroup_bis_index_cb(const struct bt_bap_base_subgroup_bis *bis, void *user_data) +static bool base_decode_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis *bis, void *user_data) { - struct bt_bap_broadcast_sink_subgroup *sink_subgroup; - struct store_base_info_data *data = user_data; - struct bt_bap_broadcast_sink_bis *sink_bis; - - if (data->bis_count == ARRAY_SIZE(data->bis)) { - /* We've parsed as many subgroups as we support */ - LOG_DBG("Could only store %u BIS", data->bis_count); - return false; - } - - sink_bis = &data->bis[data->bis_count]; - sink_subgroup = &data->subgroups[data->subgroup_count]; - - sink_bis->index = bis->index; - sink_subgroup->bis_indexes |= BT_ISO_BIS_INDEX_BIT(bis->index); - -#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 - - memcpy(&sink_bis->codec_cfg, data->subgroup_codec_cfg, sizeof(sink_bis->codec_cfg)); - - if (bis->data_len > 0) { - /* Merge subgroup codec configuration with the BIS configuration - * As per the BAP spec, if a value exist at level 2 (subgroup) and 3 (BIS), then it - * is the value at level 3 that shall be used - */ - if (sink_bis->codec_cfg.id == BT_HCI_CODING_FORMAT_LC3) { - int err; - - memcpy(&sink_bis->codec_cfg, data->subgroup_codec_cfg, - sizeof(sink_bis->codec_cfg)); + uint32_t *base_bis_index_bitfield = user_data; - err = bt_audio_data_parse(bis->data, bis->data_len, - merge_bis_and_subgroup_data_cb, - &sink_bis->codec_cfg); - if (err != 0) { - LOG_DBG("Could not merge BIS and subgroup config in codec_cfg: %d", - err); - - return false; - } - } else { - /* If it is not LC3, then we don't know how to merge the subgroup and BIS - * codecs, so we just append them - */ - if (sink_bis->codec_cfg.data_len + bis->data_len > - sizeof(sink_bis->codec_cfg.data)) { - LOG_DBG("Could not store BIS and subgroup config in codec_cfg (%u " - "> %u)", - sink_bis->codec_cfg.data_len + bis->data_len, - sizeof(sink_bis->codec_cfg.data)); - - return false; - } - - memcpy(&sink_bis->codec_cfg.data[sink_bis->codec_cfg.data_len], bis->data, - bis->data_len); - sink_bis->codec_cfg.data_len += bis->data_len; - } - } -#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */ - - data->bis_count++; + *base_bis_index_bitfield |= BT_ISO_BIS_INDEX_BIT(bis->index); return true; } -static bool base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data) +static bool base_decode_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data) { - struct bt_bap_broadcast_sink_subgroup *sink_subgroup; - struct codec_cap_lookup_id_data lookup_data = {0}; - struct store_base_info_data *data = user_data; + struct bt_bap_broadcast_sink *sink = (struct bt_bap_broadcast_sink *)user_data; + const struct bt_audio_codec_cap *codec_cap; struct bt_audio_codec_cfg codec_cfg; + struct bt_pac_codec codec_id; int ret; - if (data->subgroup_count == ARRAY_SIZE(data->subgroups)) { + if (sink->subgroup_count == ARRAY_SIZE(sink->subgroups)) { /* We've parsed as many subgroups as we support */ - LOG_DBG("Could only store %u subgroups", data->subgroup_count); + LOG_DBG("Could only store %u subgroups", sink->subgroup_count); return false; } - sink_subgroup = &data->subgroups[data->subgroup_count]; + uint32_t *subgroup_bis_indexes = &sink->subgroups[sink->subgroup_count].bis_indexes; + + *subgroup_bis_indexes = 0; ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &codec_cfg); if (ret < 0) { @@ -677,151 +617,83 @@ static bool base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void * } /* Lookup and assign path_id based on capabilities */ - lookup_data.id = codec_cfg.id; - - bt_pacs_cap_foreach(BT_AUDIO_DIR_SINK, codec_lookup_id, &lookup_data); - if (lookup_data.codec_cap == NULL) { - LOG_DBG("Codec with id %u is not supported by our capabilities", lookup_data.id); + codec_id.id = codec_cfg.id; + codec_id.cid = codec_cfg.cid; + codec_id.vid = codec_cfg.vid; + + codec_cap = bt_pacs_get_codec_cap(BT_AUDIO_DIR_SINK, &codec_id); + if (codec_cap == NULL) { + LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x is not supported by our " + "capabilities", + codec_id.id, codec_id.cid, codec_id.vid); } else { - codec_cfg.path_id = lookup_data.codec_cap->path_id; - codec_cfg.ctlr_transcode = lookup_data.codec_cap->ctlr_transcode; - - data->subgroup_codec_cfg = &codec_cfg; + ret = bt_bap_base_subgroup_foreach_bis(subgroup, base_decode_subgroup_bis_cb, + subgroup_bis_indexes); - ret = bt_bap_base_subgroup_foreach_bis(subgroup, base_subgroup_bis_index_cb, data); - if (ret < 0) { + if (ret != 0) { LOG_DBG("Could not parse BISes: %d", ret); return false; } - /* Add BIS to bitfield of valid BIS indexes we support */ - data->valid_indexes_bitfield |= sink_subgroup->bis_indexes; - data->subgroup_count++; - } - - return true; -} - -static int store_base_info(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base) -{ - /* data is static due to its size, which easily can exceed the stack size */ - static struct store_base_info_data data; - uint32_t pres_delay; - int ret; - - ret = bt_bap_base_get_pres_delay(base); - if (ret < 0) { - LOG_DBG("Could not get presentation delay: %d", ret); - return ret; - } - - pres_delay = (uint32_t)ret; - - memset(&data, 0, sizeof(data)); - - ret = bt_bap_base_foreach_subgroup(base, base_subgroup_cb, &data); - if (ret != 0) { - LOG_DBG("Failed to parse all subgroups: %d", ret); - return ret; - } - - /* Ensure that we have not synced while parsing the BASE */ - if (sink->big == NULL) { - sink->qos_cfg.pd = pres_delay; - memcpy(sink->bis, data.bis, sizeof(sink->bis)); - memcpy(sink->subgroups, data.subgroups, sizeof(sink->subgroups)); - sink->subgroup_count = data.subgroup_count; - sink->valid_indexes_bitfield = data.valid_indexes_bitfield; + sink->valid_indexes_bitfield |= *subgroup_bis_indexes; } - return 0; -} - -static bool base_subgroup_bis_count_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data) -{ - uint8_t *bis_cnt = user_data; - int ret; - - ret = bt_bap_base_get_subgroup_bis_count(subgroup); - if (ret < 0) { - return false; - } - - *bis_cnt += (uint8_t)ret; + sink->subgroup_count++; return true; } -static int base_get_bis_count(const struct bt_bap_base *base) -{ - uint8_t bis_cnt = 0U; - int err; - - err = bt_bap_base_foreach_subgroup(base, base_subgroup_bis_count_cb, &bis_cnt); - if (err != 0) { - LOG_DBG("Failed to parse subgroups: %d", err); - return err; - } - - return bis_cnt; -} - static bool pa_decode_base(struct bt_data *data, void *user_data) { struct bt_bap_broadcast_sink *sink = (struct bt_bap_broadcast_sink *)user_data; const struct bt_bap_base *base = bt_bap_base_get_base_from_ad(data); struct bt_bap_broadcast_sink_cb *listener; int base_size; - int ret; /* Base is NULL if the data does not contain a valid BASE */ if (base == NULL) { return true; } - if (atomic_test_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_BIGINFO_RECEIVED)) { - ret = base_get_bis_count(base); - - if (ret < 0) { - LOG_DBG("Invalid BASE: %d", ret); - return false; - } else if (ret != sink->biginfo_num_bis) { - LOG_DBG("BASE contains different amount of BIS (%u) than reported by " - "BIGInfo (%u)", - ret, sink->biginfo_num_bis); - return false; - } - } + /* We provide the BASE without the service data UUID */ + base_size = bt_bap_base_get_size(base); + if (base_size != sink->base_size || memcmp(base, sink->base, base_size) != 0) { + /* New BASE, parse */ - /* Store newest BASE info until we are BIG synced */ - if (sink->big == NULL) { - LOG_DBG("Updating BASE for sink %p with %d subgroups\n", sink, - bt_bap_base_get_subgroup_count(base)); + if (atomic_test_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_BIGINFO_RECEIVED)) { + int ret; - ret = store_base_info(sink, base); - if (ret < 0) { - LOG_DBG("Could not store BASE information: %d", ret); + ret = base_get_bis_count(base); - /* If it returns -ECANCELED it means that we stopped parsing ourselves due - * to lack of memory. In this case we can still provide the BASE to the - * application else abort - */ - if (ret != -ECANCELED) { + if (ret < 0) { + LOG_DBG("Invalid BASE: %d", ret); + return false; + } else if (ret != sink->biginfo_num_bis) { + LOG_DBG("BASE contains different amount of BIS (%u) than reported " + "by BIGInfo (%u)", + ret, sink->biginfo_num_bis); return false; } } - } - if (atomic_test_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID)) { - update_recv_state_base(sink, base); - } + /* Store newest BASE info until we are BIG synced */ + if (sink->big == NULL) { + sink->qos_cfg.pd = bt_bap_base_get_pres_delay(base); - /* We provide the BASE without the service data UUID */ - base_size = bt_bap_base_get_size(base); - if (base_size < 0) { - LOG_DBG("BASE get size failed (%d)", base_size); + sink->subgroup_count = 0; + sink->valid_indexes_bitfield = 0; + bt_bap_base_foreach_subgroup(base, base_decode_subgroup_cb, sink); - return false; + LOG_DBG("Updating BASE for sink %p with %d subgroups\n", sink, + sink->subgroup_count); + + memcpy(sink->base, base, base_size); + sink->base_size = base_size; + } + + if (atomic_test_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID)) { + update_recv_state_base(sink, base); + } } SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, _node) { @@ -859,6 +731,7 @@ static void pa_term_cb(struct bt_le_per_adv_sync *sync, if (sink != NULL) { sink->pa_sync = NULL; + sink->base_size = 0U; } } @@ -966,13 +839,72 @@ static uint16_t interval_to_sync_timeout(uint16_t interval) return (uint16_t)timeout; } +static void big_started_cb(struct bt_iso_big *big) +{ + struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_big(big); + struct bt_bap_broadcast_sink_cb *listener; + + if (sink == NULL) { + /* Not one of ours */ + return; + } + + SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, _node) { + if (listener->started != NULL) { + listener->started(sink); + } + } +} + +static void big_stopped_cb(struct bt_iso_big *big, uint8_t reason) +{ + struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_big(big); + struct bt_bap_broadcast_sink_cb *listener; + + if (sink == NULL) { + /* Not one of ours */ + return; + } + + broadcast_sink_clear_big(sink, reason); + + SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, _node) { + if (listener->stopped != NULL) { + listener->stopped(sink, reason); + } + } +} + int bt_bap_broadcast_sink_register_cb(struct bt_bap_broadcast_sink_cb *cb) { + static bool iso_big_cb_registered; + CHECKIF(cb == NULL) { LOG_DBG("cb is NULL"); + return -EINVAL; } + if (sys_slist_find(&sink_cbs, &cb->_node, NULL)) { + LOG_DBG("cb %p is already registered", cb); + + return -EEXIST; + } + + if (!iso_big_cb_registered) { + static struct bt_iso_big_cb big_cb = { + .started = big_started_cb, + .stopped = big_stopped_cb, + }; + const int err = bt_iso_big_register_cb(&big_cb); + + if (err != 0) { + __ASSERT(false, "Failed to register ISO BIG callbacks: %d", err); + } + + iso_big_cb_registered = true; + } + sys_slist_append(&sink_cbs, &cb->_node); return 0; @@ -1082,23 +1014,6 @@ static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink) (void)memset(sink, 0, sizeof(*sink)); /* also clears flags */ } -static struct bt_audio_codec_cfg *codec_cfg_from_base_by_index(struct bt_bap_broadcast_sink *sink, - uint8_t index) -{ - for (size_t i = 0U; i < ARRAY_SIZE(sink->bis); i++) { - struct bt_bap_broadcast_sink_bis *bis = &sink->bis[i]; - - if (bis->index == index) { - return &bis->codec_cfg; - } else if (bis->index == 0) { - /* index 0 is invalid, so we can use that as a terminator in the array */ - break; - } - } - - return NULL; -} - int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t broadcast_id, struct bt_bap_broadcast_sink **out_sink) { @@ -1156,15 +1071,166 @@ int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t br return 0; } +static uint8_t bit_count(uint32_t bitfield) +{ +#ifdef POPCOUNT + return POPCOUNT(bitfield); +#else + uint8_t cnt = 0U; + + while (bitfield != 0U) { + cnt += bitfield & 1U; + bitfield >>= 1U; + } + + return cnt; +#endif +} + +struct sync_base_info_data { + struct bt_audio_codec_cfg codec_cfgs[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; + struct bt_audio_codec_cfg *subgroup_codec_cfg; + uint32_t sync_indexes_bitfield; + uint8_t subgroup_count; + uint8_t stream_count; +}; + +static bool merge_bis_and_subgroup_data_cb(struct bt_data *data, void *user_data) +{ + struct bt_audio_codec_cfg *codec_cfg = user_data; + int err; + + err = bt_audio_codec_cfg_set_val(codec_cfg, data->type, data->data, data->data_len); + if (err < 0) { + LOG_DBG("Failed to set type %u with len %u in codec_cfg: %d", data->type, + data->data_len, err); + + return false; + } + + return true; +} + +static bool sync_base_subgroup_bis_index_cb(const struct bt_bap_base_subgroup_bis *bis, + void *user_data) +{ + struct sync_base_info_data *data = user_data; + struct bt_audio_codec_cfg *codec_cfg; + + /* Only process selected BISes */ + if ((data->sync_indexes_bitfield & BT_ISO_BIS_INDEX_BIT(bis->index)) == 0) { + return true; + } + +#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 + + codec_cfg = &data->codec_cfgs[data->stream_count]; + + memcpy(codec_cfg, data->subgroup_codec_cfg, sizeof(struct bt_audio_codec_cfg)); + + if (bis->data_len > 0) { + /* Merge subgroup codec configuration with the BIS configuration + * As per the BAP spec, if a value exist at level 2 (subgroup) and 3 (BIS), then it + * is the value at level 3 that shall be used + */ + if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { + int err; + + memcpy(codec_cfg, data->subgroup_codec_cfg, + sizeof(struct bt_audio_codec_cfg)); + + err = bt_audio_data_parse(bis->data, bis->data_len, + merge_bis_and_subgroup_data_cb, codec_cfg); + if (err != 0) { + LOG_DBG("Could not merge BIS and subgroup config in codec_cfg: %d", + err); + + return false; + } + } else { + /* If it is not LC3, then we don't know how to merge the subgroup and BIS + * codecs, so we just append them + */ + if (codec_cfg->data_len + bis->data_len > sizeof(codec_cfg->data)) { + LOG_DBG("Could not store BIS and subgroup config in codec_cfg (%u " + "> %u)", + codec_cfg->data_len + bis->data_len, + sizeof(codec_cfg->data)); + + return false; + } + + memcpy(&codec_cfg->data[codec_cfg->data_len], bis->data, bis->data_len); + codec_cfg->data_len += bis->data_len; + } + } +#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */ + + data->stream_count++; + + return true; +} + +static bool sync_base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data) +{ + struct sync_base_info_data *data = user_data; + const struct bt_audio_codec_cap *codec_cap; + struct bt_audio_codec_cfg codec_cfg; + struct bt_pac_codec codec_id; + int ret; + + if (data->subgroup_count == CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT) { + /* We've parsed as many subgroups as we support */ + LOG_DBG("Could only store %u subgroups", data->subgroup_count); + return false; + } + + ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &codec_cfg); + if (ret < 0) { + LOG_DBG("Could not store codec_cfg: %d", ret); + return false; + } + + /* Lookup and assign path_id based on capabilities */ + codec_id.id = codec_cfg.id; + codec_id.cid = codec_cfg.cid; + codec_id.vid = codec_cfg.vid; + + codec_cap = bt_pacs_get_codec_cap(BT_AUDIO_DIR_SINK, &codec_id); + if (codec_cap == NULL) { + LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x is not supported by our " + "capabilities", + codec_id.id, codec_id.cid, codec_id.vid); + } else { + codec_cfg.path_id = codec_cap->path_id; + codec_cfg.ctlr_transcode = codec_cap->ctlr_transcode; + + data->subgroup_codec_cfg = &codec_cfg; + + ret = bt_bap_base_subgroup_foreach_bis(subgroup, sync_base_subgroup_bis_index_cb, + data); + if (ret < 0) { + LOG_DBG("Could not parse BISes: %d", ret); + return false; + } + + data->subgroup_count++; + } + + return true; +} + int bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink *sink, uint32_t indexes_bitfield, struct bt_bap_stream *streams[], const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE]) { + static struct sync_base_info_data data; struct bt_iso_big_sync_param param; - struct bt_audio_codec_cfg *codec_cfgs[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT] = {NULL}; struct bt_iso_chan *bis_channels[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; + uint8_t bis_count; uint8_t stream_count; int err; + int ret; CHECKIF(sink == NULL) { LOG_DBG("sink is NULL"); @@ -1204,32 +1270,34 @@ int bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink *sink, uint32_t inde return -EINVAL; } - /* Validate that number of bits set is less than number of streams */ + /* Validate that number of bits set is within supported range */ + bis_count = bit_count(indexes_bitfield); + if (bis_count > CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT) { + LOG_DBG("Cannot sync to more than %d streams (%u was requested)", + CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT, bis_count); + return -EINVAL; + } + + /* Validate that the bits set are present in BASE */ if ((indexes_bitfield & sink->valid_indexes_bitfield) != indexes_bitfield) { - LOG_DBG("Request BIS indexes 0x%08X contains bits not support by the Broadcast " - "Sink 0x%08X", + LOG_DBG("Request BIS indexes (0x%08X) contains bits not present in BASE (0x%08X)", indexes_bitfield, sink->valid_indexes_bitfield); return -EINVAL; } - stream_count = 0; - for (int i = 1; i < BT_ISO_MAX_GROUP_ISO_COUNT; i++) { - if ((indexes_bitfield & BT_ISO_BIS_INDEX_BIT(i)) != 0) { - struct bt_audio_codec_cfg *codec_cfg = - codec_cfg_from_base_by_index(sink, i); - - __ASSERT(codec_cfg != NULL, "Index %d not found in sink", i); + memset(&data, 0, sizeof(data)); - codec_cfgs[stream_count++] = codec_cfg; + data.sync_indexes_bitfield = indexes_bitfield; - if (stream_count > CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT) { - LOG_DBG("Cannot sync to more than %d streams (%u was requested)", - CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT, stream_count); - return -EINVAL; - } - } + ret = bt_bap_base_foreach_subgroup((const struct bt_bap_base *)sink->base, + sync_base_subgroup_cb, &data); + if (ret != 0) { + LOG_DBG("Failed to parse all subgroups: %d", ret); + return ret; } + stream_count = data.stream_count; + for (size_t i = 0; i < stream_count; i++) { CHECKIF(streams[i] == NULL) { LOG_DBG("streams[%zu] is NULL", i); @@ -1243,7 +1311,7 @@ int bt_bap_broadcast_sink_sync(struct bt_bap_broadcast_sink *sink, uint32_t inde struct bt_audio_codec_cfg *codec_cfg; stream = streams[i]; - codec_cfg = codec_cfgs[i]; + codec_cfg = &data.codec_cfgs[i]; err = bt_bap_broadcast_sink_setup_stream(sink, stream, codec_cfg); if (err != 0) { @@ -1314,9 +1382,6 @@ int bt_bap_broadcast_sink_stop(struct bt_bap_broadcast_sink *sink) return err; } - broadcast_sink_clear_big(sink, BT_HCI_ERR_LOCALHOST_TERM_CONN); - /* Channel states will be updated in the broadcast_sink_iso_disconnected function */ - return 0; } diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index 93186af67f0f7..132dca5580a37 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -1,7 +1,7 @@ /* Bluetooth Audio Broadcast Source */ /* - * Copyright (c) 2021-2023 Nordic Semiconductor ASA + * Copyright (c) 2021-2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ static struct bt_bap_broadcast_subgroup broadcast_source_subgroups[CONFIG_BT_BAP_BROADCAST_SRC_COUNT] [CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]; static struct bt_bap_broadcast_source broadcast_sources[CONFIG_BT_BAP_BROADCAST_SRC_COUNT]; +static sys_slist_t bap_broadcast_source_cbs = SYS_SLIST_STATIC_INIT(&bap_broadcast_source_cbs); /** * 2 octets UUID @@ -238,9 +240,9 @@ static void broadcast_source_iso_disconnected(struct bt_iso_chan *chan, uint8_t } static struct bt_iso_chan_ops broadcast_source_iso_ops = { - .sent = broadcast_source_iso_sent, - .connected = broadcast_source_iso_connected, - .disconnected = broadcast_source_iso_disconnected, + .sent = broadcast_source_iso_sent, + .connected = broadcast_source_iso_connected, + .disconnected = broadcast_source_iso_disconnected, }; bool bt_bap_ep_is_broadcast_src(const struct bt_bap_ep *ep) @@ -440,8 +442,7 @@ static bool encode_base(struct bt_bap_broadcast_source *source, struct net_buf_s */ streams_encoded = 0; SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) { - if (!encode_base_subgroup(subgroup, - &source->stream_data[streams_encoded], + if (!encode_base_subgroup(subgroup, &source->stream_data[streams_encoded], &streams_encoded, buf)) { return false; } @@ -454,12 +455,10 @@ static void broadcast_source_cleanup(struct bt_bap_broadcast_source *source) { struct bt_bap_broadcast_subgroup *subgroup, *next_subgroup; - SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&source->subgroups, subgroup, - next_subgroup, _node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&source->subgroups, subgroup, next_subgroup, _node) { struct bt_bap_stream *stream, *next_stream; - SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&subgroup->streams, stream, - next_stream, _node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&subgroup->streams, stream, next_stream, _node) { bt_bap_iso_unbind_ep(stream->ep->iso, stream->ep); stream->ep->stream = NULL; stream->ep = NULL; @@ -467,8 +466,7 @@ static void broadcast_source_cleanup(struct bt_bap_broadcast_source *source) stream->qos = NULL; stream->group = NULL; - sys_slist_remove(&subgroup->streams, NULL, - &stream->_node); + sys_slist_remove(&subgroup->streams, NULL, &stream->_node); } sys_slist_remove(&source->subgroups, NULL, &subgroup->_node); } @@ -777,8 +775,7 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_param *param, bis_count++; } - err = broadcast_source_setup_stream(index, stream, - codec_cfg, qos, source); + err = broadcast_source_setup_stream(index, stream, codec_cfg, qos, source); if (err != 0) { LOG_DBG("Failed to setup streams[%zu]: %d", i, err); broadcast_source_cleanup(source); @@ -1039,7 +1036,7 @@ int bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source *sour int bt_bap_broadcast_source_start(struct bt_bap_broadcast_source *source, struct bt_le_ext_adv *adv) { struct bt_iso_chan *bis[BROADCAST_STREAM_CNT]; - struct bt_iso_big_create_param param = { 0 }; + struct bt_iso_big_create_param param = {0}; struct bt_bap_broadcast_subgroup *subgroup; enum bt_bap_ep_state broadcast_state; struct bt_bap_stream *stream; @@ -1078,8 +1075,7 @@ int bt_bap_broadcast_source_start(struct bt_bap_broadcast_source *source, struct param.latency = source->qos->latency; param.encryption = source->encryption; if (param.encryption) { - (void)memcpy(param.bcode, source->broadcast_code, - sizeof(param.bcode)); + (void)memcpy(param.bcode, source->broadcast_code, sizeof(param.bcode)); } #if defined(CONFIG_BT_ISO_TEST_PARAMS) param.irc = source->irc; @@ -1125,14 +1121,12 @@ int bt_bap_broadcast_source_stop(struct bt_bap_broadcast_source *source) return -EALREADY; } - err = bt_iso_big_terminate(source->big); + err = bt_iso_big_terminate(source->big); if (err) { LOG_DBG("Failed to terminate BIG (err %d)", err); return err; } - source->big = NULL; - return 0; } @@ -1188,3 +1182,102 @@ int bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source *source, return 0; } + +static struct bt_bap_broadcast_source *get_broadcast_source_by_big(const struct bt_iso_big *big) +{ + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sources); i++) { + if (broadcast_sources[i].big == big) { + return &broadcast_sources[i]; + } + } + + return NULL; +} + +static void big_started_cb(struct bt_iso_big *big) +{ + struct bt_bap_broadcast_source *source = get_broadcast_source_by_big(big); + struct bt_bap_broadcast_source_cb *listener; + + if (source == NULL) { + /* Not one of ours */ + return; + } + + SYS_SLIST_FOR_EACH_CONTAINER(&bap_broadcast_source_cbs, listener, _node) { + if (listener->started != NULL) { + listener->started(source); + } + } +} + +static void big_stopped_cb(struct bt_iso_big *big, uint8_t reason) +{ + struct bt_bap_broadcast_source *source = get_broadcast_source_by_big(big); + struct bt_bap_broadcast_source_cb *listener; + + if (source == NULL) { + /* Not one of ours */ + return; + } + + source->big = NULL; + + SYS_SLIST_FOR_EACH_CONTAINER(&bap_broadcast_source_cbs, listener, _node) { + if (listener->stopped != NULL) { + listener->stopped(source, reason); + } + } +} + +int bt_bap_broadcast_source_register_cb(struct bt_bap_broadcast_source_cb *cb) +{ + static bool iso_big_cb_registered; + + CHECKIF(cb == NULL) { + LOG_DBG("cb is NULL"); + + return -EINVAL; + } + + if (sys_slist_find(&bap_broadcast_source_cbs, &cb->_node, NULL)) { + LOG_DBG("cb %p is already registered", cb); + + return -EEXIST; + } + + if (!iso_big_cb_registered) { + static struct bt_iso_big_cb big_cb = { + .started = big_started_cb, + .stopped = big_stopped_cb, + }; + const int err = bt_iso_big_register_cb(&big_cb); + + if (err != 0) { + __ASSERT(false, "Failed to register ISO BIG callbacks: %d", err); + } + + iso_big_cb_registered = true; + } + + sys_slist_append(&bap_broadcast_source_cbs, &cb->_node); + + return 0; +} + +int bt_bap_broadcast_source_unregister_cb(struct bt_bap_broadcast_source_cb *cb) +{ + CHECKIF(cb == NULL) { + LOG_DBG("cb is NULL"); + + return -EINVAL; + } + + if (!sys_slist_find_and_remove(&bap_broadcast_source_cbs, &cb->_node)) { + LOG_DBG("cb %p is not registered", cb); + + return -ENOENT; + } + + return 0; +} diff --git a/subsys/bluetooth/audio/bap_endpoint.h b/subsys/bluetooth/audio/bap_endpoint.h index 08d385aefacba..4f1a5fe7a0b09 100644 --- a/subsys/bluetooth/audio/bap_endpoint.h +++ b/subsys/bluetooth/audio/bap_endpoint.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -180,6 +181,8 @@ struct bt_bap_broadcast_sink { struct bt_bap_qos_cfg qos_cfg; struct bt_le_per_adv_sync *pa_sync; struct bt_iso_big *big; + uint8_t base_size; + uint8_t base[BT_BASE_MAX_SIZE]; struct bt_bap_broadcast_sink_bis bis[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; struct bt_bap_broadcast_sink_subgroup subgroups[CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT]; const struct bt_bap_scan_delegator_recv_state *recv_state; diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index 8fdf83557d761..bb6b54b039bea 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -151,35 +151,42 @@ static void bt_debug_dump_recv_state(const struct bass_recv_state_internal *recv } } -static void bass_notify_receive_state(struct bt_conn *conn, - const struct bass_recv_state_internal *internal_state) +static void receive_state_notify_cb(struct bt_conn *conn, void *data) { - const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */ + const struct bass_recv_state_internal *internal_state = data; + struct bt_conn_info conn_info; uint16_t max_ntf_size; uint16_t ntf_size; int err; - if (conn != NULL) { - max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size; - } else { - max_ntf_size = MIN(BT_L2CAP_RX_MTU, BT_L2CAP_TX_MTU) - att_ntf_header_size; + err = bt_conn_get_info(conn, &conn_info); + __ASSERT_NO_MSG(err == 0); + + if (conn_info.state != BT_CONN_STATE_CONNECTED || + !bt_gatt_is_subscribed(conn, internal_state->attr, BT_GATT_CCC_NOTIFY)) { + return; } + max_ntf_size = bt_audio_get_max_ntf_size(conn); + ntf_size = MIN(max_ntf_size, read_buf.len); if (ntf_size < read_buf.len) { LOG_DBG("Sending truncated notification (%u/%u)", ntf_size, read_buf.len); } - LOG_DBG("Sending bytes %d", ntf_size); - err = bt_gatt_notify_uuid(NULL, BT_UUID_BASS_RECV_STATE, - internal_state->attr, read_buf.data, - ntf_size); - - if (err != 0 && err != -ENOTCONN) { + LOG_DBG("Sending bytes %u for %p", ntf_size, (void *)conn); + err = bt_gatt_notify_uuid(conn, BT_UUID_BASS_RECV_STATE, internal_state->attr, + read_buf.data, ntf_size); + if (err != 0) { LOG_DBG("Could not notify receive state: %d", err); } } +static void bass_notify_receive_state(const struct bass_recv_state_internal *internal_state) +{ + bt_conn_foreach(BT_CONN_TYPE_LE, receive_state_notify_cb, (void *)internal_state); +} + static void net_buf_put_recv_state(const struct bass_recv_state_internal *recv_state) { const struct bt_bap_scan_delegator_recv_state *state = &recv_state->state; @@ -237,7 +244,7 @@ static void receive_state_updated(struct bt_conn *conn, bt_debug_dump_recv_state(internal_state); net_buf_put_recv_state(internal_state); - bass_notify_receive_state(conn, internal_state); + bass_notify_receive_state(internal_state); if (scan_delegator_cbs != NULL && scan_delegator_cbs->recv_state_updated != NULL) { scan_delegator_cbs->recv_state_updated(conn, @@ -285,7 +292,7 @@ static void scan_delegator_security_changed(struct bt_conn *conn, } net_buf_put_recv_state(internal_state); - bass_notify_receive_state(conn, internal_state); + receive_state_notify_cb(conn, (void *)internal_state); k_sem_give(&read_buf_sem); } @@ -494,6 +501,8 @@ static int scan_delegator_add_source(struct bt_conn *conn, uint32_t aggregated_bis_syncs = 0; uint32_t broadcast_id; bool bis_sync_requested; + uint16_t total_len; + struct bt_bap_bass_cp_add_src *add_src; /* subtract 1 as the opcode has already been pulled */ if (buf->len < sizeof(struct bt_bap_bass_cp_add_src) - 1) { @@ -501,6 +510,34 @@ static int scan_delegator_add_source(struct bt_conn *conn, return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } + add_src = (void *)(buf->data - 1); + total_len = sizeof(struct bt_bap_bass_cp_add_src) - 1; + for (int i = 0; i < add_src->num_subgroups; i++) { + struct bt_bap_bass_cp_subgroup *subgroup; + uint16_t index = total_len; + + total_len += sizeof(struct bt_bap_bass_cp_subgroup); + if (total_len > buf->len) { + LOG_DBG("Invalid length %u", buf->len); + + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); + } + + subgroup = (void *)&buf->data[index]; + total_len += subgroup->metadata_len; + if (total_len > buf->len) { + LOG_DBG("Invalid length %u", buf->len); + + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); + } + } + + if (total_len != buf->len) { + LOG_DBG("Invalid length %u", buf->len); + + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); + } + internal_state = get_free_recv_state(); if (internal_state == NULL) { LOG_DBG("Could not get free receive state"); @@ -558,11 +595,6 @@ static int scan_delegator_add_source(struct bt_conn *conn, struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i]; uint8_t *metadata; - if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) { - LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); - } - internal_state->requested_bis_sync[i] = net_buf_simple_pull_le32(buf); if (internal_state->requested_bis_sync[i] && @@ -596,13 +628,6 @@ static int scan_delegator_add_source(struct bt_conn *conn, subgroup->metadata_len = net_buf_simple_pull_u8(buf); - if (buf->len < subgroup->metadata_len) { - LOG_DBG("Invalid length %u", buf->size); - - return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); - } - - if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) { LOG_WRN("Metadata too long %u/%u", subgroup->metadata_len, CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE); @@ -615,11 +640,6 @@ static int scan_delegator_add_source(struct bt_conn *conn, subgroup->metadata_len); } - if (buf->len != 0) { - LOG_DBG("Invalid length %u", buf->size); - return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); - } - /* The active flag shall be set before any application callbacks, so that any calls for the * receive state can be processed */ @@ -676,6 +696,8 @@ static int scan_delegator_mod_src(struct bt_conn *conn, uint8_t pa_sync; uint32_t aggregated_bis_syncs = 0; bool bis_sync_change_requested; + uint16_t total_len; + struct bt_bap_bass_cp_mod_src *mod_src; /* subtract 1 as the opcode has already been pulled */ if (buf->len < sizeof(struct bt_bap_bass_cp_mod_src) - 1) { @@ -684,6 +706,34 @@ static int scan_delegator_mod_src(struct bt_conn *conn, return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); } + mod_src = (void *)(buf->data - 1); + total_len = sizeof(struct bt_bap_bass_cp_mod_src) - 1; + for (int i = 0; i < mod_src->num_subgroups; i++) { + struct bt_bap_bass_cp_subgroup *subgroup; + uint16_t index = total_len; + + total_len += sizeof(struct bt_bap_bass_cp_subgroup); + if (total_len > buf->len) { + LOG_DBG("Invalid length %u", buf->len); + + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); + } + + subgroup = (void *)&buf->data[index]; + total_len += subgroup->metadata_len; + if (total_len > buf->len) { + LOG_DBG("Invalid length %u", buf->len); + + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); + } + } + + if (total_len != buf->len) { + LOG_DBG("Invalid length %u", buf->len); + + return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); + } + src_id = net_buf_simple_pull_u8(buf); internal_state = bass_lookup_src_id(src_id); @@ -718,11 +768,6 @@ static int scan_delegator_mod_src(struct bt_conn *conn, uint32_t old_bis_sync_req; uint8_t *metadata; - if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) { - LOG_DBG("Invalid length %u", buf->len); - return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); - } - old_bis_sync_req = internal_state->requested_bis_sync[i]; internal_state->requested_bis_sync[i] = net_buf_simple_pull_le32(buf); @@ -754,11 +799,6 @@ static int scan_delegator_mod_src(struct bt_conn *conn, subgroup->metadata_len = net_buf_simple_pull_u8(buf); - if (buf->len < subgroup->metadata_len) { - LOG_DBG("Invalid length %u", buf->len); - return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); - } - if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) { LOG_WRN("Metadata too long %u/%u", subgroup->metadata_len, CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE); @@ -771,12 +811,6 @@ static int scan_delegator_mod_src(struct bt_conn *conn, subgroup->metadata_len); } - if (buf->len != 0) { - LOG_DBG("Invalid length %u", buf->size); - - return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED); - } - /* All input has been validated; update receive state and check for changes */ state = &internal_state->state; diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 280a2ff02226d..2b52c000b11bf 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -1747,7 +1747,6 @@ static uint8_t unicast_client_ep_notify(struct bt_conn *conn, { struct net_buf_simple buf; struct bt_bap_unicast_client_ep *client_ep; - const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */ uint16_t max_ntf_size; struct bt_bap_ep *ep; @@ -1765,7 +1764,7 @@ static uint8_t unicast_client_ep_notify(struct bt_conn *conn, return BT_GATT_ITER_STOP; } - max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size; + max_ntf_size = bt_audio_get_max_ntf_size(conn); if (length == max_ntf_size) { struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)]; @@ -2166,8 +2165,7 @@ static void gatt_write_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_writ int bt_bap_unicast_client_ep_send(struct bt_conn *conn, struct bt_bap_ep *ep, struct net_buf_simple *buf) { - const uint8_t att_write_header_size = 3; /* opcode (1) + handle (2) */ - const uint16_t max_write_size = bt_gatt_get_mtu(conn) - att_write_header_size; + const uint16_t max_write_size = bt_audio_get_max_ntf_size(conn); struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)]; struct bt_bap_unicast_client_ep *client_ep = CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep); diff --git a/subsys/bluetooth/audio/bap_unicast_client_internal.h b/subsys/bluetooth/audio/bap_unicast_client_internal.h index 6c6c2857b1e6a..ae71b864d43f7 100644 --- a/subsys/bluetooth/audio/bap_unicast_client_internal.h +++ b/subsys/bluetooth/audio/bap_unicast_client_internal.h @@ -7,6 +7,7 @@ */ #include +#include #include #include diff --git a/subsys/bluetooth/audio/cap_commander.c b/subsys/bluetooth/audio/cap_commander.c index 1a0bb2f8f9d88..4828dd1970d0a 100644 --- a/subsys/bluetooth/audio/cap_commander.c +++ b/subsys/bluetooth/audio/cap_commander.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -517,7 +518,7 @@ static void cap_commander_broadcast_assistant_mod_src_cb(struct bt_conn *conn, i bt_cap_common_abort_proc(conn, err); } else { - LOG_DBG("Conn %p broadcast source modifified (%zu/%zu streams done)", (void *)conn, + LOG_DBG("Conn %p broadcast source modified (%zu/%zu streams done)", (void *)conn, active_proc->proc_done_cnt, active_proc->proc_cnt); } diff --git a/subsys/bluetooth/audio/cap_initiator.c b/subsys/bluetooth/audio/cap_initiator.c index d6485e5f094a8..45a4b0b03af17 100644 --- a/subsys/bluetooth/audio/cap_initiator.c +++ b/subsys/bluetooth/audio/cap_initiator.c @@ -119,7 +119,7 @@ static bool cap_initiator_valid_metadata(const uint8_t meta[], size_t meta_len) }; int err; - LOG_DBG("meta %p len %zu", meta, meta_len); + LOG_DBG("meta %p len %zu", (void *)meta, meta_len); err = bt_audio_data_parse(meta, meta_len, data_func_cb, &metadata_param); if (err != 0 && err != -ECANCELED) { @@ -257,9 +257,54 @@ int bt_cap_initiator_broadcast_audio_create( &(*broadcast_source)->bap_broadcast); } +static struct bt_cap_broadcast_source *get_cap_broadcast_source_by_bap_broadcast_source( + const struct bt_bap_broadcast_source *bap_broadcast_source) +{ + for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sources); i++) { + if (broadcast_sources[i].bap_broadcast == bap_broadcast_source) { + return &broadcast_sources[i]; + } + } + + return NULL; +} + +static void broadcast_source_started_cb(struct bt_bap_broadcast_source *bap_broadcast_source) +{ + if (cap_cb && cap_cb->broadcast_started) { + struct bt_cap_broadcast_source *source = + get_cap_broadcast_source_by_bap_broadcast_source(bap_broadcast_source); + + if (source == NULL) { + /* Not one of ours */ + return; + } + + cap_cb->broadcast_started(source); + } +} + +static void broadcast_source_stopped_cb(struct bt_bap_broadcast_source *bap_broadcast_source, + uint8_t reason) +{ + if (cap_cb && cap_cb->broadcast_stopped) { + struct bt_cap_broadcast_source *source = + get_cap_broadcast_source_by_bap_broadcast_source(bap_broadcast_source); + + if (source == NULL) { + /* Not one of ours */ + return; + } + + cap_cb->broadcast_stopped(source, reason); + } +} + int bt_cap_initiator_broadcast_audio_start(struct bt_cap_broadcast_source *broadcast_source, struct bt_le_ext_adv *adv) { + static bool broadcast_source_cbs_registered; + CHECKIF(adv == NULL) { LOG_DBG("adv is NULL"); return -EINVAL; @@ -270,6 +315,21 @@ int bt_cap_initiator_broadcast_audio_start(struct bt_cap_broadcast_source *broad return -EINVAL; } + if (!broadcast_source_cbs_registered) { + static struct bt_bap_broadcast_source_cb broadcast_source_cb = { + .started = broadcast_source_started_cb, + .stopped = broadcast_source_stopped_cb, + }; + const int err = bt_bap_broadcast_source_register_cb(&broadcast_source_cb); + + if (err != 0) { + __ASSERT(false, "Failed to register BAP broadcast source callbacks: %d", + err); + } + + broadcast_source_cbs_registered = true; + } + return bt_bap_broadcast_source_start(broadcast_source->bap_broadcast, adv); } diff --git a/subsys/bluetooth/audio/cap_internal.h b/subsys/bluetooth/audio/cap_internal.h index c83c4af0e948d..9eddf63293fa9 100644 --- a/subsys/bluetooth/audio/cap_internal.h +++ b/subsys/bluetooth/audio/cap_internal.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -113,7 +114,7 @@ struct cap_broadcast_reception_stop { /* Note that although the broadcast_code will be the same for all * we nevertheless store a separate copy for each sink, for - * consistensy in the struct bt_cap_commander_proc_param + * consistency in the struct bt_cap_commander_proc_param * There is no memory savings by not having broadcast_code part of the * union: struct cap_broadcast_reception_start uses minimum 20 bytes * and struct cap_distribute_broadcast_code uses 17 bytes diff --git a/subsys/bluetooth/audio/ccp_call_control_client.c b/subsys/bluetooth/audio/ccp_call_control_client.c new file mode 100644 index 0000000000000..69afa66e7e36e --- /dev/null +++ b/subsys/bluetooth/audio/ccp_call_control_client.c @@ -0,0 +1,234 @@ +/* Bluetooth CCP - Call Control Profile Call Control Server + * + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(bt_ccp_call_control_client, CONFIG_BT_CCP_CALL_CONTROL_CLIENT_LOG_LEVEL); + +static sys_slist_t ccp_call_control_client_cbs = + SYS_SLIST_STATIC_INIT(&ccp_call_control_client_cbs); + +static struct bt_tbs_client_cb tbs_client_cbs; + +/* A service instance can either be a GTBS or a TBS insttance */ +struct bt_ccp_call_control_client_bearer { + uint8_t tbs_index; + bool discovered; +}; + +enum ccp_call_control_client_flag { + CCP_CALL_CONTROL_CLIENT_FLAG_BUSY, + + CCP_CALL_CONTROL_CLIENT_FLAG_NUM_FLAGS, /* keep as last */ +}; + +struct bt_ccp_call_control_client { + struct bt_ccp_call_control_client_bearer + bearers[CONFIG_BT_CCP_CALL_CONTROL_CLIENT_BEARER_COUNT]; + struct bt_conn *conn; + + ATOMIC_DEFINE(flags, CCP_CALL_CONTROL_CLIENT_FLAG_NUM_FLAGS); +}; + +static struct bt_ccp_call_control_client clients[CONFIG_BT_MAX_CONN]; + +static struct bt_ccp_call_control_client *get_client_by_conn(const struct bt_conn *conn) +{ + return &clients[bt_conn_index(conn)]; +} + +static void connected_cb(struct bt_conn *conn, uint8_t err) +{ + static bool cbs_registered; + + /* We register the callbacks in the connected callback. That way we ensure that they are + * registered before any procedures are completed or we receive any notifications, while + * registering them as late as possible + */ + if (err == BT_HCI_ERR_SUCCESS && !cbs_registered) { + int cb_err; + + cb_err = bt_tbs_client_register_cb(&tbs_client_cbs); + __ASSERT(cb_err == 0, "Failed to register TBS callbacks: %d", cb_err); + + cbs_registered = true; + } +} + +static void disconnected_cb(struct bt_conn *conn, uint8_t reason) +{ + struct bt_ccp_call_control_client *client = get_client_by_conn(conn); + + /* client->conn may be NULL */ + if (client->conn == conn) { + bt_conn_unref(client->conn); + client->conn = NULL; + } +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected_cb, + .disconnected = disconnected_cb, +}; + +static void populate_bearers(struct bt_ccp_call_control_client *client, + struct bt_ccp_call_control_client_bearers *bearers) +{ + size_t i = 0; + +#if defined(CONFIG_BT_TBS_CLIENT_GTBS) + if (client->bearers[i].discovered) { + bearers->gtbs_bearer = &client->bearers[i++]; + } +#endif /* CONFIG_BT_TBS_CLIENT_GTBS */ + +#if defined(CONFIG_BT_TBS_CLIENT_TBS) + for (; i < ARRAY_SIZE(client->bearers); i++) { + if (!client->bearers[i].discovered) { + break; + } + + bearers->tbs_bearers[bearers->tbs_count++] = &client->bearers[i]; + } +#endif /* CONFIG_BT_TBS_CLIENT_TBS */ +} + +static void tbs_client_discover_cb(struct bt_conn *conn, int err, uint8_t tbs_count, + bool gtbs_found) +{ + struct bt_ccp_call_control_client *client = get_client_by_conn(conn); + struct bt_ccp_call_control_client_bearers bearers = {0}; + struct bt_ccp_call_control_client_cb *listener, *next; + + LOG_DBG("conn %p err %d tbs_count %u gtbs_found %d", (void *)conn, err, tbs_count, + gtbs_found); + + memset(client->bearers, 0, sizeof((client->bearers))); + + if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && gtbs_found) { + client->bearers[0].discovered = true; + client->bearers[0].tbs_index = BT_TBS_GTBS_INDEX; + } + + if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_TBS)) { + for (uint8_t i = 0U; i < tbs_count; i++) { + const uint8_t idx = i + (gtbs_found ? 1 : 0); + + if (idx >= ARRAY_SIZE(client->bearers)) { + LOG_WRN("Discoverd more TBS instances (%u) than the CCP Call " + "Control Client supports %zu", + tbs_count, ARRAY_SIZE(client->bearers)); + break; + } + + client->bearers[idx].discovered = true; + client->bearers[idx].tbs_index = i; + } + } + + populate_bearers(client, &bearers); + + atomic_clear_bit(client->flags, CCP_CALL_CONTROL_CLIENT_FLAG_BUSY); + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&ccp_call_control_client_cbs, listener, next, _node) { + if (listener->discover != NULL) { + listener->discover(client, err, &bearers); + } + } +} + +int bt_ccp_call_control_client_discover(struct bt_conn *conn, + struct bt_ccp_call_control_client **out_client) +{ + struct bt_ccp_call_control_client *client; + int err; + + CHECKIF(conn == NULL) { + LOG_DBG("conn is NULL"); + + return -EINVAL; + } + + CHECKIF(out_client == NULL) { + LOG_DBG("client is NULL"); + + return -EINVAL; + } + + client = get_client_by_conn(conn); + if (atomic_test_and_set_bit(client->flags, CCP_CALL_CONTROL_CLIENT_FLAG_BUSY)) { + return -EBUSY; + } + + tbs_client_cbs.discover = tbs_client_discover_cb; + + err = bt_tbs_client_discover(conn); + if (err != 0) { + LOG_DBG("Failed to discover TBS for %p: %d", (void *)conn, err); + + atomic_clear_bit(client->flags, CCP_CALL_CONTROL_CLIENT_FLAG_BUSY); + + /* Return known errors */ + if (err == -EBUSY || err == -ENOTCONN) { + return err; + } + + return -ENOEXEC; + } + + client->conn = bt_conn_ref(conn); + *out_client = client; + + return 0; +} + +int bt_ccp_call_control_client_register_cb(struct bt_ccp_call_control_client_cb *cb) +{ + CHECKIF(cb == NULL) { + LOG_DBG("cb is NULL"); + + return -EINVAL; + } + + if (sys_slist_find(&ccp_call_control_client_cbs, &cb->_node, NULL)) { + return -EEXIST; + } + + sys_slist_append(&ccp_call_control_client_cbs, &cb->_node); + + return 0; +} + +int bt_ccp_call_control_client_unregister_cb(struct bt_ccp_call_control_client_cb *cb) +{ + CHECKIF(cb == NULL) { + LOG_DBG("cb is NULL"); + return -EINVAL; + } + + if (!sys_slist_find_and_remove(&ccp_call_control_client_cbs, &cb->_node)) { + return -EALREADY; + } + + return 0; +} diff --git a/subsys/bluetooth/audio/ccp_call_control_server.c b/subsys/bluetooth/audio/ccp_call_control_server.c new file mode 100644 index 0000000000000..a51354f4ce42d --- /dev/null +++ b/subsys/bluetooth/audio/ccp_call_control_server.c @@ -0,0 +1,106 @@ +/* Bluetooth CCP - Call Control Profile Call Control Server + * + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(bt_ccp_call_control_server, CONFIG_BT_CCP_CALL_CONTROL_SERVER_LOG_LEVEL); + +/* A service instance can either be a GTBS or a TBS instance */ +struct bt_ccp_call_control_server_bearer { + uint8_t tbs_index; + bool registered; +}; + +static struct bt_ccp_call_control_server_bearer + bearers[CONFIG_BT_CCP_CALL_CONTROL_SERVER_BEARER_COUNT]; + +static struct bt_ccp_call_control_server_bearer *get_free_bearer(void) +{ + + for (size_t i = 0; i < ARRAY_SIZE(bearers); i++) { + if (!bearers[i].registered) { + return &bearers[i]; + } + } + + return NULL; +} + +int bt_ccp_call_control_server_register_bearer(const struct bt_tbs_register_param *param, + struct bt_ccp_call_control_server_bearer **bearer) +{ + struct bt_ccp_call_control_server_bearer *free_bearer; + int ret; + + CHECKIF(bearer == NULL) { + LOG_DBG("bearer is NULL"); + + return -EINVAL; + } + + free_bearer = get_free_bearer(); + if (free_bearer == NULL) { + return -ENOMEM; + } + + ret = bt_tbs_register_bearer(param); + if (ret < 0) { + LOG_DBG("Failed to register TBS bearer: %d", ret); + + /* Return known errors */ + if (ret == -EINVAL || ret == -EALREADY || ret == -EAGAIN || ret == -ENOMEM) { + return ret; + } + + return -ENOEXEC; + } + + free_bearer->registered = true; + free_bearer->tbs_index = (uint8_t)ret; + *bearer = free_bearer; + + return 0; +} + +int bt_ccp_call_control_server_unregister_bearer(struct bt_ccp_call_control_server_bearer *bearer) +{ + int err; + + CHECKIF(bearer == NULL) { + LOG_DBG("bearer is NULL"); + + return -EINVAL; + } + + if (!bearer->registered) { + LOG_DBG("Bearer %p already unregistered", bearer); + + return -EALREADY; + } + + err = bt_tbs_unregister_bearer(bearer->tbs_index); + if (err != 0) { + /* Return known errors */ + if (err == -EINVAL || err == -EALREADY) { + return err; + } + + return -ENOEXEC; + } + + bearer->registered = false; + + return 0; +} diff --git a/subsys/bluetooth/audio/csip_crypto.c b/subsys/bluetooth/audio/csip_crypto.c index 08346bed0bdcc..b46ca984f2b49 100644 --- a/subsys/bluetooth/audio/csip_crypto.c +++ b/subsys/bluetooth/audio/csip_crypto.c @@ -171,14 +171,8 @@ int bt_csip_sef(const uint8_t k[BT_CSIP_CRYPTO_KEY_SIZE], const uint8_t sirk[BT_ LOG_DBG("SIRK %s", bt_hex(sirk, BT_CSIP_SIRK_SIZE)); - if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { - /* Swap because aes_cmac is big endian - * and we are little endian - */ - sys_memcpy_swap(k1_tmp, k, sizeof(k1_tmp)); - } else { - (void)memcpy(k1_tmp, k, sizeof(k1_tmp)); - } + /* Swap because aes_cmac is big endian and k is little endian */ + sys_memcpy_swap(k1_tmp, k, sizeof(k1_tmp)); LOG_DBG("BE: k %s", bt_hex(k1_tmp, sizeof(k1_tmp))); err = s1(m, sizeof(m), s1_out); @@ -195,10 +189,8 @@ int bt_csip_sef(const uint8_t k[BT_CSIP_CRYPTO_KEY_SIZE], const uint8_t sirk[BT_ LOG_DBG("BE: k1 result %s", bt_hex(k1_out, sizeof(k1_out))); - if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { - /* Swap result back to little endian */ - sys_mem_swap(k1_out, sizeof(k1_out)); - } + /* Get result back to little endian. */ + sys_mem_swap(k1_out, sizeof(k1_out)); mem_xor_128(out_sirk, k1_out, sirk); LOG_DBG("out %s", bt_hex(out_sirk, BT_CSIP_SIRK_SIZE)); diff --git a/subsys/bluetooth/audio/csip_crypto.h b/subsys/bluetooth/audio/csip_crypto.h index b522eb94a98a3..bc547988ec8b3 100644 --- a/subsys/bluetooth/audio/csip_crypto.h +++ b/subsys/bluetooth/audio/csip_crypto.h @@ -22,9 +22,10 @@ * used in RSIs - Used by the Coordinated Set Identification service and * profile. * - * @param sirk 16 byte LS byte first SIRK - * @param r 3 byte LS byte first random value - * @param out 3 byte LS byte first output buffer + * @param sirk 16-byte SIRK in little-endian byte order. + * @param r 3-byte random value in little-endian byte order. + * @param out 3-byte output buffer in little-endian byte order. + * * @return int 0 on success, any other value indicates a failure. */ int bt_csip_sih(const uint8_t sirk[BT_CSIP_SIRK_SIZE], uint8_t r[BT_CSIP_CRYPTO_PRAND_SIZE], @@ -37,20 +38,18 @@ int bt_csip_sih(const uint8_t sirk[BT_CSIP_SIRK_SIZE], uint8_t r[BT_CSIP_CRYPTO_ * with a key K. The value of K depends on the transport on which the pairing * between the client and the server was performed. * - * If the pairing was performed on BR/EDR, K is equal to the Link Key shared by - * the server and the client. + * If the pairing was performed on Basic Rate/Enhanced Data Rate (BR/EDR), K is equal to the + * Link Key shared by the server and the client. * K = Link Key. * - * If the pairing was performed on LE, the 64 LSBs of K correspond to the 64 - * LSBs of the IRK that the server sent to the client during the Phase 3 - * (Transport Specific Key Distribution) of the pairing procedure (see Volume 3, - * Part H, Section 2.1 in [2]), and the 64 MSBs of K correspond to the 64 MSBs - * of the LTK shared by the server and client. That is, - * K = LTK_64-127 || IRK_0-63 + * If the pairing was performed on Bluetooth Low Energy (LE), K is equal to the LTK shared by the + * server and client. That is, + * K = LTK + * + * @param k 16-byte key in little-endian byte order. + * @param sirk 16-byte unencrypted SIRK key in little-endian byte order. + * @param out_sirk 16-byte encrypted SIRK key in little-endian byte order. * - * @param k 16-byte key. - * @param sirk The unencrypted SIRK. - * @param out_sirk The encrypted SIRK. * @return int 0 on success, any other value indicates a failure. */ int bt_csip_sef(const uint8_t k[BT_CSIP_CRYPTO_KEY_SIZE], const uint8_t sirk[BT_CSIP_SIRK_SIZE], @@ -63,20 +62,18 @@ int bt_csip_sef(const uint8_t k[BT_CSIP_CRYPTO_KEY_SIZE], const uint8_t sirk[BT_ * with a key K. The value of K depends on the transport on which the pairing * between the client and the server was performed. * - * If the pairing was performed on BR/EDR, K is equal to the Link Key shared by - * the server and the client. + * If the pairing was performed on Basic Rate/Enhanced Data Rate (BR/EDR), K is equal to the + * Link Key shared by the server and the client. * K = Link Key. * - * If the pairing was performed on LE, the 64 LSBs of K correspond to the 64 - * LSBs of the IRK that the server sent to the client during the Phase 3 - * (Transport Specific Key Distribution) of the pairing procedure (see Volume 3, - * Part H, Section 2.1 in [2]), and the 64 MSBs of K correspond to the 64 MSBs - * of the LTK shared by the server and client. That is, - * K = LTK_64-127 || IRK_0-63 + * If the pairing was performed on Bluetooth Low Energy (LE), K is equal to the LTK shared by the + * server and client. That is, + * K = LTK + * + * @param k 16-byte key in little-endian byte order. + * @param sirk 16-byte encrypted SIRK in little-endian byte order. + * @param out_sirk 16-byte decrypted SIRK in little-endian byte order. * - * @param k 16-byte key. - * @param sirk The encrypted SIRK. - * @param out_sirk The decrypted SIRK. * @return int 0 on success, any other value indicates a failure. */ int bt_csip_sdf(const uint8_t k[BT_CSIP_CRYPTO_KEY_SIZE], const uint8_t enc_sirk[BT_CSIP_SIRK_SIZE], diff --git a/subsys/bluetooth/audio/csip_internal.h b/subsys/bluetooth/audio/csip_internal.h index 0ac61f335c0bf..8cf6c7f7d0707 100644 --- a/subsys/bluetooth/audio/csip_internal.h +++ b/subsys/bluetooth/audio/csip_internal.h @@ -21,6 +21,7 @@ struct bt_csip_sirk { uint8_t type; + /* SIRK stored in little endian byte order. */ uint8_t value[BT_CSIP_SIRK_SIZE]; } __packed; diff --git a/subsys/bluetooth/audio/csip_set_coordinator.c b/subsys/bluetooth/audio/csip_set_coordinator.c index a56ee7d5456d7..eaf5b1a037524 100644 --- a/subsys/bluetooth/audio/csip_set_coordinator.c +++ b/subsys/bluetooth/audio/csip_set_coordinator.c @@ -266,23 +266,19 @@ static int sirk_decrypt(struct bt_conn *conn, uint8_t *out_sirk) { int err; - uint8_t *k; + const uint8_t *k; if (IS_ENABLED(CONFIG_BT_CSIP_SET_COORDINATOR_TEST_SAMPLE_DATA)) { /* test_k is from the sample data from A.2 in the CSIS spec */ - static uint8_t test_k[] = {0x67, 0x6e, 0x1b, 0x9b, - 0xd4, 0x48, 0x69, 0x6f, - 0x06, 0x1e, 0xc6, 0x22, - 0x3c, 0xe5, 0xce, 0xd9}; - static bool swapped; + static const uint8_t test_k[] = { + /* Sample data is in big-endian, we need it in little-endian. */ + REVERSE_ARGS(0x67, 0x6e, 0x1b, 0x9b, + 0xd4, 0x48, 0x69, 0x6f, + 0x06, 0x1e, 0xc6, 0x22, + 0x3c, 0xe5, 0xce, 0xd9) }; LOG_DBG("Decrypting with sample data K"); - if (!swapped && IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { - /* Swap test_k to little endian */ - sys_mem_swap(test_k, 16); - swapped = true; - } k = test_k; } else { k = conn->le.keys->ltk.val; diff --git a/subsys/bluetooth/audio/csip_set_member.c b/subsys/bluetooth/audio/csip_set_member.c index f3e91beb8a555..f7e46e071e989 100644 --- a/subsys/bluetooth/audio/csip_set_member.c +++ b/subsys/bluetooth/audio/csip_set_member.c @@ -145,21 +145,16 @@ static int sirk_encrypt(struct bt_conn *conn, const struct bt_csip_sirk *sirk, struct bt_csip_sirk *enc_sirk) { int err; - uint8_t *k; + const uint8_t *k; if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_TEST_SAMPLE_DATA)) { /* test_k is from the sample data from A.2 in the CSIS spec */ - static uint8_t test_k[] = {0x67, 0x6e, 0x1b, 0x9b, - 0xd4, 0x48, 0x69, 0x6f, - 0x06, 0x1e, 0xc6, 0x22, - 0x3c, 0xe5, 0xce, 0xd9}; - static bool swapped; - - if (!swapped && IS_ENABLED(CONFIG_LITTLE_ENDIAN)) { - /* Swap test_k to little endian */ - sys_mem_swap(test_k, 16); - swapped = true; - } + static const uint8_t test_k[] = { + /* Sample data is in big-endian, we need it in little-endian. */ ++ REVERSE_ARGS(0x67, 0x6e, 0x1b, 0x9b, + 0xd4, 0x48, 0x69, 0x6f, + 0x06, 0x1e, 0xc6, 0x22, + 0x3c, 0xe5, 0xce, 0xd9) }; LOG_DBG("Encrypting test SIRK"); k = test_k; } else { diff --git a/subsys/bluetooth/audio/has.c b/subsys/bluetooth/audio/has.c index ad72904ec4351..3eebad6c4ac93 100644 --- a/subsys/bluetooth/audio/has.c +++ b/subsys/bluetooth/audio/has.c @@ -750,13 +750,11 @@ static void control_point_ind_complete(struct bt_conn *conn, static int control_point_send(struct has_client *client, struct net_buf_simple *buf) { - const uint16_t mtu_size = bt_gatt_get_mtu(client->conn); - /* PDU structure is [Opcode (1)] [Handle (2)] [...] */ - const uint16_t pdu_size = 3 + buf->len; + const uint16_t max_ntf_size = bt_audio_get_max_ntf_size(client->conn); - if (mtu_size < pdu_size) { - LOG_WRN("Sending truncated control point PDU %d < %d", mtu_size, pdu_size); - buf->len -= (pdu_size - mtu_size); + if (max_ntf_size < buf->len) { + LOG_WRN("Sending truncated control point PDU %u < %u", max_ntf_size, buf->len); + buf->len = max_ntf_size; } #if defined(CONFIG_BT_HAS_PRESET_CONTROL_POINT_NOTIFIABLE) @@ -778,6 +776,7 @@ static int control_point_send(struct has_client *client, struct net_buf_simple * client->params.ind.func = control_point_ind_complete; client->params.ind.destroy = NULL; client->params.ind.data = buf->data; + /* indications have same size as notifications */ client->params.ind.len = buf->len; return bt_gatt_indicate(client->conn, &client->params.ind); diff --git a/subsys/bluetooth/audio/mcs.c b/subsys/bluetooth/audio/mcs.c index d0eb2f7658bb3..4120812af4ea0 100644 --- a/subsys/bluetooth/audio/mcs.c +++ b/subsys/bluetooth/audio/mcs.c @@ -985,18 +985,12 @@ static void notify(const struct bt_uuid *uuid, const void *data, uint16_t len) static void notify_string(struct bt_conn *conn, const struct bt_uuid *uuid, const char *str) { - const uint8_t att_header_size = 3; /* opcode + handle */ - uint16_t att_mtu; - uint16_t maxlen; + const uint16_t max_ntf_size = bt_audio_get_max_ntf_size(conn); int err; - att_mtu = bt_gatt_get_mtu(conn); - __ASSERT(att_mtu > att_header_size, "Could not get valid ATT MTU"); - maxlen = att_mtu - att_header_size; /* Subtract opcode and handle */ - /* Send notification potentially truncated to the MTU */ err = bt_gatt_notify_uuid(conn, uuid, mcs.attrs, (void *)str, - MIN(strlen(str), maxlen)); + MIN(strlen(str), max_ntf_size)); if (err != 0) { LOG_ERR("Notification error: %d", err); } diff --git a/subsys/bluetooth/audio/media_proxy.c b/subsys/bluetooth/audio/media_proxy.c index 7e427203ec3e0..7f72bd465fbea 100644 --- a/subsys/bluetooth/audio/media_proxy.c +++ b/subsys/bluetooth/audio/media_proxy.c @@ -22,7 +22,7 @@ #include "media_proxy_internal.h" #include "mcs_internal.h" -LOG_MODULE_REGISTER(media_proxy, CONFIG_MCTL_LOG_LEVEL); +LOG_MODULE_REGISTER(bt_media_proxy, CONFIG_MCTL_LOG_LEVEL); /* Media player */ struct media_player { diff --git a/subsys/bluetooth/audio/mpl.c b/subsys/bluetooth/audio/mpl.c index b657fe5beffce..a55d4ff805c26 100644 --- a/subsys/bluetooth/audio/mpl.c +++ b/subsys/bluetooth/audio/mpl.c @@ -2526,8 +2526,7 @@ void mpl_debug_dump_state(void) } #endif /* CONFIG_BT_MPL_LOG_LEVEL_DBG */ -#if defined(CONFIG_BT_MPL_LOG_LEVEL_DBG) && \ - defined(CONFIG_BT_TESTING) /* Special commands for testing */ +#if defined(CONFIG_BT_TESTING) /* Special commands for testing */ #if CONFIG_BT_MPL_OBJECTS void mpl_test_unset_parent_group(void) @@ -2626,4 +2625,4 @@ void mpl_test_search_results_changed_cb(void) } #endif /* CONFIG_BT_MPL_OBJECTS */ -#endif /* CONFIG_BT_MPL_LOG_LEVEL_DBG && CONFIG_BT_TESTING */ +#endif /* CONFIG_BT_TESTING */ diff --git a/subsys/bluetooth/audio/pacs.c b/subsys/bluetooth/audio/pacs.c index 30e5d64d9a405..826c45d63c390 100644 --- a/subsys/bluetooth/audio/pacs.c +++ b/subsys/bluetooth/audio/pacs.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -38,8 +37,7 @@ #include #include -#include "../host/conn_internal.h" -#include "../host/hci_core.h" +#include "host/hci_core.h" #include "common/bt_str.h" #include "audio_internal.h" @@ -52,15 +50,19 @@ LOG_MODULE_REGISTER(bt_pacs, CONFIG_BT_PACS_LOG_LEVEL); #define READ_BUF_SEM_TIMEOUT K_MSEC(50) #if defined(CONFIG_BT_PAC_SRC) -static uint32_t pacs_src_location; -static sys_slist_t src_pacs_list = SYS_SLIST_STATIC_INIT(&src_pacs_list); +static sys_slist_t src_pac_list = SYS_SLIST_STATIC_INIT(&src_pac_list); static uint16_t src_supported_contexts; +#if defined(CONFIG_BT_PAC_SRC_LOC) +static uint32_t pacs_src_location; +#endif /* CONFIG_BT_PAC_SRC_LOC */ #endif /* CONFIG_BT_PAC_SRC */ #if defined(CONFIG_BT_PAC_SNK) -static uint32_t pacs_snk_location; -static sys_slist_t snk_pacs_list = SYS_SLIST_STATIC_INIT(&snk_pacs_list); +static sys_slist_t snk_pac_list = SYS_SLIST_STATIC_INIT(&snk_pac_list); static uint16_t snk_supported_contexts; +#if defined(CONFIG_BT_PAC_SNK_LOC) +static uint32_t pacs_snk_location; +#endif /* CONFIG_BT_PAC_SNK_LOC */ #endif /* CONFIG_BT_PAC_SNK */ static uint16_t src_available_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED; @@ -77,7 +79,18 @@ enum { FLAG_NUM, }; -static struct pacs_client { +enum { + PACS_FLAG_REGISTERED, + PACS_FLAG_SVC_CHANGING, + PACS_FLAG_NOTIFY_RDY, + PACS_FLAG_SNK_PAC, + PACS_FLAG_SNK_LOC, + PACS_FLAG_SRC_PAC, + PACS_FLAG_SRC_LOC, + PACS_FLAG_NUM, +}; + +struct pacs_client { bt_addr_le_t addr; #if defined(CONFIG_BT_PAC_SNK) @@ -92,9 +105,14 @@ static struct pacs_client { /* Pending notification flags */ ATOMIC_DEFINE(flags, FLAG_NUM); -} clients[CONFIG_BT_MAX_PAIRED]; +}; + +static struct pacs { + ATOMIC_DEFINE(flags, PACS_FLAG_NUM); + + struct pacs_client clients[CONFIG_BT_MAX_PAIRED]; +} pacs; -static atomic_t notify_rdy; static K_SEM_DEFINE(read_buf_sem, 1, 1); NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, BT_ATT_MAX_ATTRIBUTE_LEN); @@ -117,10 +135,10 @@ static struct pacs_client *client_lookup_conn(const struct bt_conn *conn) { __ASSERT_NO_MSG(conn != NULL); - for (size_t i = 0; i < ARRAY_SIZE(clients); i++) { - if (atomic_test_bit(clients[i].flags, FLAG_ACTIVE) && - bt_addr_le_eq(&clients[i].addr, bt_conn_get_dst(conn))) { - return &clients[i]; + for (size_t i = 0; i < ARRAY_SIZE(pacs.clients); i++) { + if (atomic_test_bit(pacs.clients[i].flags, FLAG_ACTIVE) && + bt_addr_le_eq(&pacs.clients[i].addr, bt_conn_get_dst(conn))) { + return &pacs.clients[i]; } } @@ -129,9 +147,9 @@ static struct pacs_client *client_lookup_conn(const struct bt_conn *conn) static void pacs_set_notify_bit(int bit) { - for (size_t i = 0U; i < ARRAY_SIZE(clients); i++) { - if (atomic_test_bit(clients[i].flags, FLAG_ACTIVE)) { - atomic_set_bit(clients[i].flags, bit); + for (size_t i = 0U; i < ARRAY_SIZE(pacs.clients); i++) { + if (atomic_test_bit(pacs.clients[i].flags, FLAG_ACTIVE)) { + atomic_set_bit(pacs.clients[i].flags, bit); } } } @@ -226,14 +244,16 @@ static enum bt_audio_context pacs_get_available_contexts_for_conn(struct bt_conn switch (dir) { case BT_AUDIO_DIR_SINK: #if defined(CONFIG_BT_PAC_SNK) - if (client->snk_available_contexts != NULL) { + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_PAC) && + client->snk_available_contexts != NULL) { return POINTER_TO_UINT(client->snk_available_contexts); } #endif /* CONFIG_BT_PAC_SNK */ break; case BT_AUDIO_DIR_SOURCE: #if defined(CONFIG_BT_PAC_SRC) - if (client->src_available_contexts != NULL) { + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_PAC) && + client->src_available_contexts != NULL) { return POINTER_TO_UINT(client->src_available_contexts); } #endif /* CONFIG_BT_PAC_SRC */ @@ -254,7 +274,7 @@ static ssize_t available_contexts_read(struct bt_conn *conn, pacs_get_available_contexts_for_conn(conn, BT_AUDIO_DIR_SOURCE)), }; - LOG_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len, offset); + LOG_DBG("conn %p attr %p buf %p len %u offset %u", (void *)conn, attr, buf, len, offset); return bt_gatt_attr_read(conn, attr, buf, len, offset, &context, sizeof(context)); @@ -273,11 +293,17 @@ static uint16_t supported_context_get(enum bt_audio_dir dir) switch (dir) { #if defined(CONFIG_BT_PAC_SNK) case BT_AUDIO_DIR_SINK: - return snk_supported_contexts | BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_PAC)) { + return snk_supported_contexts | BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED; + } + break; #endif /* CONFIG_BT_PAC_SNK */ #if defined(CONFIG_BT_PAC_SRC) case BT_AUDIO_DIR_SOURCE: - return src_supported_contexts | BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_PAC)) { + return src_supported_contexts | BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED; + } + break; #endif /* CONFIG_BT_PAC_SRC */ default: break; @@ -295,7 +321,7 @@ static ssize_t supported_context_read(struct bt_conn *conn, .src = sys_cpu_to_le16(supported_context_get(BT_AUDIO_DIR_SOURCE)), }; - LOG_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len, offset); + LOG_DBG("conn %p attr %p buf %p len %u offset %u", (void *)conn, attr, buf, len, offset); return bt_gatt_attr_read(conn, attr, buf, len, offset, &context, sizeof(context)); @@ -362,7 +388,7 @@ static ssize_t snk_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, ssize_t ret_val; int err; - LOG_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len, offset); + LOG_DBG("conn %p attr %p buf %p len %u offset %u", (void *)conn, attr, buf, len, offset); err = k_sem_take(&read_buf_sem, READ_BUF_SEM_TIMEOUT); if (err != 0) { @@ -371,7 +397,7 @@ static ssize_t snk_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES); } - get_pac_records(&snk_pacs_list, &read_buf); + get_pac_records(&snk_pac_list, &read_buf); ret_val = bt_gatt_attr_read(conn, attr, buf, len, offset, read_buf.data, read_buf.len); @@ -398,7 +424,7 @@ static ssize_t snk_loc_read(struct bt_conn *conn, { uint32_t location = sys_cpu_to_le32(pacs_snk_location); - LOG_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len, offset); + LOG_DBG("conn %p attr %p buf %p len %u offset %u", (void *)conn, attr, buf, len, offset); return bt_gatt_attr_read(conn, attr, buf, len, offset, &location, sizeof(location)); @@ -415,15 +441,17 @@ static void snk_loc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) static void set_snk_location(enum bt_audio_location audio_location) { - if (audio_location == pacs_snk_location) { - return; - } + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_LOC)) { + if (audio_location == pacs_snk_location) { + return; + } - pacs_snk_location = audio_location; + pacs_snk_location = audio_location; - if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE)) { - pacs_set_notify_bit(FLAG_SINK_AUDIO_LOCATIONS_CHANGED); - k_work_submit(&deferred_nfy_work); + if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE)) { + pacs_set_notify_bit(FLAG_SINK_AUDIO_LOCATIONS_CHANGED); + k_work_submit(&deferred_nfy_work); + } } } #else @@ -467,7 +495,7 @@ static ssize_t src_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, ssize_t ret_val; int err; - LOG_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len, offset); + LOG_DBG("conn %p attr %p buf %p len %u offset %u", (void *)conn, attr, buf, len, offset); err = k_sem_take(&read_buf_sem, READ_BUF_SEM_TIMEOUT); if (err != 0) { @@ -476,7 +504,7 @@ static ssize_t src_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES); } - get_pac_records(&src_pacs_list, &read_buf); + get_pac_records(&src_pac_list, &read_buf); ret_val = bt_gatt_attr_read(conn, attr, buf, len, offset, read_buf.data, read_buf.len); @@ -503,7 +531,7 @@ static ssize_t src_loc_read(struct bt_conn *conn, { uint32_t location = sys_cpu_to_le32(pacs_src_location); - LOG_DBG("conn %p attr %p buf %p len %u offset %u", conn, attr, buf, len, offset); + LOG_DBG("conn %p attr %p buf %p len %u offset %u", (void *)conn, attr, buf, len, offset); return bt_gatt_attr_read(conn, attr, buf, len, offset, &location, sizeof(location)); @@ -520,15 +548,17 @@ static void src_loc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) static void set_src_location(enum bt_audio_location audio_location) { - if (audio_location == pacs_src_location) { - return; - } + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_LOC)) { + if (audio_location == pacs_src_location) { + return; + } - pacs_src_location = audio_location; + pacs_src_location = audio_location; - if (IS_ENABLED(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE)) { - pacs_set_notify_bit(FLAG_SOURCE_AUDIO_LOCATIONS_CHANGED); - k_work_submit(&deferred_nfy_work); + if (IS_ENABLED(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE)) { + pacs_set_notify_bit(FLAG_SOURCE_AUDIO_LOCATIONS_CHANGED); + k_work_submit(&deferred_nfy_work); + } } } #else @@ -566,30 +596,35 @@ static ssize_t src_loc_write(struct bt_conn *conn, #endif /* CONFIG_BT_PAC_SRC_LOC_WRITEABLE */ -static sys_slist_t *pacs_get(enum bt_audio_dir dir) +static sys_slist_t *pacs_get_pac(enum bt_audio_dir dir) { switch (dir) { #if defined(CONFIG_BT_PAC_SNK) case BT_AUDIO_DIR_SINK: - return &snk_pacs_list; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_PAC)) { + return &snk_pac_list; + } + return NULL; #endif /* CONFIG_BT_PAC_SNK */ #if defined(CONFIG_BT_PAC_SRC) case BT_AUDIO_DIR_SOURCE: - return &src_pacs_list; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_PAC)) { + return &src_pac_list; + } + return NULL; #endif /* CONFIG_BT_PAC_SRC */ default: return NULL; } } +#if defined(CONFIG_BT_PAC_SNK) #define BT_PACS_SNK_PROP \ BT_GATT_CHRC_READ \ IF_ENABLED(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE, (|BT_GATT_CHRC_NOTIFY)) -#define BT_PAC_SNK(_read) \ - BT_AUDIO_CHRC(BT_UUID_PACS_SNK, \ - BT_PACS_SNK_PROP, \ - BT_GATT_PERM_READ_ENCRYPT, \ - _read, NULL, NULL), \ +#define BT_PAC_SNK \ + BT_AUDIO_CHRC(BT_UUID_PACS_SNK, BT_PACS_SNK_PROP, BT_GATT_PERM_READ_ENCRYPT, snk_read, \ + NULL, NULL), \ IF_ENABLED(CONFIG_BT_PAC_SNK_NOTIFIABLE, (BT_AUDIO_CCC(snk_cfg_changed),)) #define BT_PACS_SNK_LOC_PROP \ @@ -597,27 +632,39 @@ static sys_slist_t *pacs_get(enum bt_audio_dir dir) IF_ENABLED(CONFIG_BT_PAC_SNK_LOC_WRITEABLE, (|BT_GATT_CHRC_WRITE)) \ IF_ENABLED(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE, (|BT_GATT_CHRC_NOTIFY)) -#define BT_PACS_SNK_LOC_PERM \ - BT_GATT_PERM_READ_ENCRYPT \ +#define BT_PACS_SNK_LOC_PERM \ + BT_GATT_PERM_READ_ENCRYPT \ IF_ENABLED(CONFIG_BT_PAC_SNK_LOC_WRITEABLE, (|BT_GATT_PERM_WRITE_ENCRYPT)) -#define BT_PACS_SNK_LOC(_read) \ - BT_AUDIO_CHRC(BT_UUID_PACS_SNK_LOC, \ - BT_PACS_SNK_LOC_PROP, \ - BT_PACS_SNK_LOC_PERM, \ - _read, \ - COND_CODE_1(CONFIG_BT_PAC_SNK_LOC_WRITEABLE, (snk_loc_write), (NULL)), \ - NULL), \ +/* declaration + value [+ cccd] */ +#define PACS_SNK_PAC_CHAR_ATTR_COUNT COND_CODE_1(IS_ENABLED(CONFIG_BT_PAC_SNK_NOTIFIABLE), (3), (2)) +#else +#define BT_PAC_SNK +#define PACS_SNK_PAC_CHAR_ATTR_COUNT 0 +#endif /* CONFIG_BT_PAC_SNK */ + +#if defined(CONFIG_BT_PAC_SNK_LOC) +#define BT_PACS_SNK_LOC \ + BT_AUDIO_CHRC(BT_UUID_PACS_SNK_LOC, BT_PACS_SNK_LOC_PROP, BT_PACS_SNK_LOC_PERM, \ + snk_loc_read, \ + COND_CODE_1(CONFIG_BT_PAC_SNK_LOC_WRITEABLE, (snk_loc_write), (NULL)), NULL),\ IF_ENABLED(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE, (BT_AUDIO_CCC(snk_loc_cfg_changed),)) +/* declaration + value [+ cccd] */ +#define PACS_SNK_PAC_LOC_CHAR_ATTR_COUNT \ + COND_CODE_1(IS_ENABLED(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE), (3), (2)) +#else +#define BT_PACS_SNK_LOC +#define PACS_SNK_PAC_LOC_CHAR_ATTR_COUNT 0 +#endif /* CONFIG_BT_PAC_SNK_LOC*/ + +#if defined(CONFIG_BT_PAC_SRC) #define BT_PACS_SRC_PROP \ BT_GATT_CHRC_READ \ IF_ENABLED(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE, (|BT_GATT_CHRC_NOTIFY)) -#define BT_PAC_SRC(_read) \ - BT_AUDIO_CHRC(BT_UUID_PACS_SRC, \ - BT_PACS_SRC_PROP, \ - BT_GATT_PERM_READ_ENCRYPT, \ - _read, NULL, NULL), \ +#define BT_PAC_SRC \ + BT_AUDIO_CHRC(BT_UUID_PACS_SRC, BT_PACS_SRC_PROP, BT_GATT_PERM_READ_ENCRYPT, src_read, \ + NULL, NULL), \ IF_ENABLED(CONFIG_BT_PAC_SRC_NOTIFIABLE, (BT_AUDIO_CCC(src_cfg_changed),)) #define BT_PACS_SRC_LOC_PROP \ @@ -625,55 +672,236 @@ static sys_slist_t *pacs_get(enum bt_audio_dir dir) IF_ENABLED(CONFIG_BT_PAC_SRC_LOC_WRITEABLE, (|BT_GATT_CHRC_WRITE)) \ IF_ENABLED(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE, (|BT_GATT_CHRC_NOTIFY)) -#define BT_PACS_SRC_LOC_PERM \ - BT_GATT_PERM_READ_ENCRYPT \ +#define BT_PACS_SRC_LOC_PERM \ + BT_GATT_PERM_READ_ENCRYPT \ IF_ENABLED(CONFIG_BT_PAC_SRC_LOC_WRITEABLE, (|BT_GATT_PERM_WRITE_ENCRYPT)) -#define BT_PACS_SRC_LOC(_read) \ - BT_AUDIO_CHRC(BT_UUID_PACS_SRC_LOC, \ - BT_PACS_SRC_LOC_PROP, \ - BT_PACS_SRC_LOC_PERM, \ - _read, \ - COND_CODE_1(CONFIG_BT_PAC_SRC_LOC_WRITEABLE, (src_loc_write), (NULL)), \ - NULL), \ +/* declaration + value [+ cccd] */ +#define PACS_SRC_PAC_CHAR_ATTR_COUNT COND_CODE_1(IS_ENABLED(CONFIG_BT_PAC_SRC_NOTIFIABLE), (3), (2)) +#else +#define BT_PAC_SRC +#define PACS_SRC_PAC_CHAR_ATTR_COUNT 0 +#endif + +#if defined(CONFIG_BT_PAC_SRC_LOC) +#define BT_PACS_SRC_LOC \ + BT_AUDIO_CHRC(BT_UUID_PACS_SRC_LOC, BT_PACS_SRC_LOC_PROP, BT_PACS_SRC_LOC_PERM, \ + src_loc_read, \ + COND_CODE_1(CONFIG_BT_PAC_SRC_LOC_WRITEABLE, (src_loc_write), (NULL)), NULL),\ IF_ENABLED(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE, (BT_AUDIO_CCC(src_loc_cfg_changed),)) -#define BT_PAC_AVAILABLE_CONTEXT(_read) \ - BT_AUDIO_CHRC(BT_UUID_PACS_AVAILABLE_CONTEXT, \ - BT_GATT_CHRC_READ|BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, \ - _read, NULL, NULL), \ +/* declaration + value [+ cccd] */ +#define PACS_SRC_PAC_LOC_CHAR_ATTR_COUNT \ + COND_CODE_1(IS_ENABLED(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE), (3), (2)) +#else +#define BT_PACS_SRC_LOC +#define PACS_SRC_PAC_LOC_CHAR_ATTR_COUNT 0 +#endif + +#define BT_PAC_AVAILABLE_CONTEXT \ + BT_AUDIO_CHRC(BT_UUID_PACS_AVAILABLE_CONTEXT, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ + BT_GATT_PERM_READ_ENCRYPT, available_contexts_read, NULL, NULL), \ BT_AUDIO_CCC(available_context_cfg_changed), #define BT_PACS_SUPPORTED_CONTEXT_PROP \ BT_GATT_CHRC_READ \ IF_ENABLED(CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE, (|BT_GATT_CHRC_NOTIFY)) -#define BT_PAC_SUPPORTED_CONTEXT(_read) \ - BT_AUDIO_CHRC(BT_UUID_PACS_SUPPORTED_CONTEXT, \ - BT_PACS_SUPPORTED_CONTEXT_PROP, \ - BT_GATT_PERM_READ_ENCRYPT, \ - _read, NULL, NULL), \ - IF_ENABLED(CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE, \ +#define BT_PAC_SUPPORTED_CONTEXT \ + BT_AUDIO_CHRC(BT_UUID_PACS_SUPPORTED_CONTEXT, BT_PACS_SUPPORTED_CONTEXT_PROP, \ + BT_GATT_PERM_READ_ENCRYPT, supported_context_read, NULL, NULL), \ + IF_ENABLED(CONFIG_BT_PACS_SUPPORTED_CONTEXT_NOTIFIABLE, \ (BT_AUDIO_CCC(supported_context_cfg_changed),)) -BT_GATT_SERVICE_DEFINE(pacs_svc, - BT_GATT_PRIMARY_SERVICE(BT_UUID_PACS), -#if defined(CONFIG_BT_PAC_SNK) - BT_PAC_SNK(snk_read) +#define BT_PACS_SERVICE_DEFINITION() { \ + BT_GATT_PRIMARY_SERVICE(BT_UUID_PACS), \ + BT_PAC_SNK \ + BT_PACS_SNK_LOC \ + BT_PAC_SRC \ + BT_PACS_SRC_LOC \ + BT_PAC_AVAILABLE_CONTEXT \ + BT_PAC_SUPPORTED_CONTEXT \ +} + +static const struct bt_gatt_attr _pacs_attrs[] = BT_PACS_SERVICE_DEFINITION(); +static struct bt_gatt_attr pacs_attrs[] = BT_PACS_SERVICE_DEFINITION(); +static struct bt_gatt_service pacs_svc = (struct bt_gatt_service)BT_GATT_SERVICE(pacs_attrs); + +static void configure_pacs_char(const struct bt_pacs_register_param *param) +{ + const uint8_t first_attr_offset = 1U; + struct bt_gatt_attr *svc_attrs = + &pacs_svc.attrs[first_attr_offset]; /* first attribute is the service */ + uint8_t attrs_to_rem = 0U; + uint8_t first_to_rem = 0U; + + /* Remove the Sink PAC and Location */ #if defined(CONFIG_BT_PAC_SNK_LOC) - BT_PACS_SNK_LOC(snk_loc_read) + if (!param->snk_loc) { + first_to_rem = PACS_SNK_PAC_CHAR_ATTR_COUNT; + attrs_to_rem = PACS_SNK_PAC_LOC_CHAR_ATTR_COUNT; + } #endif /* CONFIG_BT_PAC_SNK_LOC */ +#if defined(CONFIG_BT_PAC_SNK) + if (!param->snk_pac) { + first_to_rem = 0U; + attrs_to_rem = PACS_SNK_PAC_CHAR_ATTR_COUNT + PACS_SNK_PAC_LOC_CHAR_ATTR_COUNT; + } #endif /* CONFIG_BT_PAC_SNK */ + + if (attrs_to_rem > 0U) { + for (uint8_t i = first_to_rem + attrs_to_rem; + i < pacs_svc.attr_count - first_attr_offset; i++) { + svc_attrs[i - attrs_to_rem] = svc_attrs[i]; + } + pacs_svc.attr_count -= attrs_to_rem; + } + #if defined(CONFIG_BT_PAC_SRC) - BT_PAC_SRC(src_read) + /* Set first_to_rem to the start of Source PAC Char, for cleaner offset calc */ + const uint8_t src_pac_offset = + (PACS_SNK_PAC_CHAR_ATTR_COUNT + PACS_SNK_PAC_LOC_CHAR_ATTR_COUNT) - attrs_to_rem; + attrs_to_rem = 0U; + + /* Remove the Source PAC and Location */ #if defined(CONFIG_BT_PAC_SRC_LOC) - BT_PACS_SRC_LOC(src_loc_read) + if (!param->src_loc) { + first_to_rem = src_pac_offset + PACS_SRC_PAC_CHAR_ATTR_COUNT; + attrs_to_rem = PACS_SRC_PAC_LOC_CHAR_ATTR_COUNT; + } #endif /* CONFIG_BT_PAC_SRC_LOC */ + + if (!param->src_pac) { + first_to_rem = src_pac_offset; + attrs_to_rem = PACS_SRC_PAC_CHAR_ATTR_COUNT + PACS_SRC_PAC_LOC_CHAR_ATTR_COUNT; + } + + if (attrs_to_rem > 0U) { + for (uint8_t i = first_to_rem + attrs_to_rem; + i < pacs_svc.attr_count - first_attr_offset; i++) { + svc_attrs[i - attrs_to_rem] = svc_attrs[i]; + } + pacs_svc.attr_count -= attrs_to_rem; + } +#endif /* CONFIG_BT_PAC_SRC */ +} + +static bool valid_pacs_register_param(const struct bt_pacs_register_param *param) +{ + bool any_pac_registered = false; + + if (param == NULL) { + LOG_DBG("param is NULL"); + return false; + } + +#if defined(CONFIG_BT_PAC_SNK) + any_pac_registered |= param->snk_pac; +#endif /* CONFIG_BT_PAC_SNK */ +#if defined(CONFIG_BT_PAC_SNK_LOC) + if (param->snk_loc && !param->snk_pac) { + LOG_DBG("Cannot register snk_loc without snk_pac"); + return false; + } +#endif /* CONFIG_BT_PAC_SNK_LOC */ +#if defined(CONFIG_BT_PAC_SRC) + any_pac_registered |= param->src_pac; +#endif /* CONFIG_BT_PAC_SRC */ +#if defined(CONFIG_BT_PAC_SRC_LOC) + if (param->src_loc && !param->src_pac) { + LOG_DBG("Cannot register src_loc without src_pac"); + return false; + } +#endif /* CONFIG_BT_PAC_SRC_LOC */ + + if (!any_pac_registered) { + LOG_DBG("Neither snk_pac or src_pac registered"); + return false; + } + + return true; +} + +int bt_pacs_register(const struct bt_pacs_register_param *param) +{ + int err = 0; + + if (!valid_pacs_register_param(param)) { + return -EINVAL; + } + + if (atomic_test_and_set_bit(pacs.flags, PACS_FLAG_REGISTERED)) { + LOG_DBG("PACS already registered"); + + return -EALREADY; + } + + /* Save registration param so we can guard functions accordingly */ +#if defined(CONFIG_BT_PAC_SNK) + atomic_set_bit_to(pacs.flags, PACS_FLAG_SNK_PAC, param->snk_pac); +#endif /* CONFIG_BT_PAC_SNK */ +#if defined(CONFIG_BT_PAC_SNK_LOC) + atomic_set_bit_to(pacs.flags, PACS_FLAG_SNK_LOC, param->snk_loc); +#endif /* CONFIG_BT_PAC_SNK_LOC */ +#if defined(CONFIG_BT_PAC_SRC) + atomic_set_bit_to(pacs.flags, PACS_FLAG_SRC_PAC, param->src_pac); #endif /* CONFIG_BT_PAC_SRC */ - BT_PAC_AVAILABLE_CONTEXT(available_contexts_read) - BT_PAC_SUPPORTED_CONTEXT(supported_context_read) -); +#if defined(CONFIG_BT_PAC_SRC_LOC) + atomic_set_bit_to(pacs.flags, PACS_FLAG_SRC_LOC, param->src_loc); +#endif /* CONFIG_BT_PAC_SRC_LOC */ + + /* Remove characteristics if necessary */ + configure_pacs_char(param); + + err = bt_gatt_service_register(&pacs_svc); + if (err != 0) { + LOG_DBG("Failed to register ASCS in gatt DB: %d", err); + atomic_clear_bit(pacs.flags, PACS_FLAG_REGISTERED); + + return -ENOEXEC; + } + + return 0; +} + +int bt_pacs_unregister(void) +{ + int err; + + if (!atomic_test_bit(pacs.flags, PACS_FLAG_REGISTERED)) { + LOG_DBG("No pacs instance registered"); + + return -EALREADY; + } + + if (atomic_test_and_set_bit(pacs.flags, PACS_FLAG_SVC_CHANGING)) { + LOG_DBG("Service change already in progress"); + atomic_clear_bit(pacs.flags, PACS_FLAG_SVC_CHANGING); + + return -EBUSY; + } + + err = bt_gatt_service_unregister(&pacs_svc); + + /* If unregistration was successful, make sure to reset pacs_attrs so it can be used for + * new registrations + */ + if (err != 0) { + LOG_DBG("Failed to unregister PACS"); + atomic_clear_bit(pacs.flags, PACS_FLAG_SVC_CHANGING); + + return err; + } + + /* Restore to original definition */ + memcpy(pacs_svc.attrs, &_pacs_attrs, sizeof(_pacs_attrs)); + pacs_svc.attr_count = ARRAY_SIZE(pacs_attrs); + + atomic_clear_bit(pacs.flags, PACS_FLAG_REGISTERED); + atomic_clear_bit(pacs.flags, PACS_FLAG_SVC_CHANGING); + + return err; +} #if defined(CONFIG_BT_PAC_SNK_LOC_NOTIFIABLE) || defined(CONFIG_BT_PAC_SRC_LOC_NOTIFIABLE) static int pac_notify_loc(struct bt_conn *conn, enum bt_audio_dir dir) @@ -713,7 +941,7 @@ static int pac_notify_loc(struct bt_conn *conn, enum bt_audio_dir dir) static int pac_notify(struct bt_conn *conn, enum bt_audio_dir dir) { int err = 0; - sys_slist_t *pacs; + sys_slist_t *pac; const struct bt_uuid *uuid; switch (dir) { @@ -738,9 +966,9 @@ static int pac_notify(struct bt_conn *conn, enum bt_audio_dir dir) return err; } - pacs = pacs_get(dir); - __ASSERT(pacs, "Failed to get pacs.\n"); - get_pac_records(pacs, &read_buf); + pac = pacs_get_pac(dir); + __ASSERT(pac, "Failed to get pacs.\n"); + get_pac_records(pac, &read_buf); err = pacs_gatt_notify(conn, uuid, pacs_svc.attrs, read_buf.data, read_buf.len); @@ -799,7 +1027,7 @@ static int supported_contexts_notify(struct bt_conn *conn) void pacs_gatt_notify_complete_cb(struct bt_conn *conn, void *user_data) { /* Notification done, clear bit and reschedule work */ - atomic_clear(¬ify_rdy); + atomic_clear_bit(pacs.flags, PACS_FLAG_NOTIFY_RDY); k_work_submit(&deferred_nfy_work); } @@ -820,11 +1048,16 @@ static int pacs_gatt_notify(struct bt_conn *conn, params.func = pacs_gatt_notify_complete_cb; /* Mark notification in progress */ - atomic_set(¬ify_rdy, 1); + if (atomic_test_bit(pacs.flags, PACS_FLAG_SVC_CHANGING) || + !atomic_test_bit(pacs.flags, PACS_FLAG_REGISTERED)) { + return 0; + } + + atomic_set_bit(pacs.flags, PACS_FLAG_NOTIFY_RDY); err = bt_gatt_notify_cb(conn, ¶ms); if (err != 0) { - atomic_clear(¬ify_rdy); + atomic_clear_bit(pacs.flags, PACS_FLAG_NOTIFY_RDY); } if (err && err != -ENOTCONN) { @@ -859,7 +1092,7 @@ static void notify_cb(struct bt_conn *conn, void *data) } /* Check if we have unverified notifications in progress */ - if (atomic_get(¬ify_rdy)) { + if (atomic_test_bit(pacs.flags, PACS_FLAG_NOTIFY_RDY)) { return; } @@ -936,18 +1169,18 @@ static void pacs_auth_pairing_complete(struct bt_conn *conn, bool bonded) } /* Check if already in list, and do nothing if it is */ - for (size_t i = 0U; i < ARRAY_SIZE(clients); i++) { - if (atomic_test_bit(clients[i].flags, FLAG_ACTIVE) && - bt_addr_le_eq(bt_conn_get_dst(conn), &clients[i].addr)) { + for (size_t i = 0U; i < ARRAY_SIZE(pacs.clients); i++) { + if (atomic_test_bit(pacs.clients[i].flags, FLAG_ACTIVE) && + bt_addr_le_eq(bt_conn_get_dst(conn), &pacs.clients[i].addr)) { return; } } /* Else add the device */ - for (size_t i = 0U; i < ARRAY_SIZE(clients); i++) { - if (!atomic_test_bit(clients[i].flags, FLAG_ACTIVE)) { - atomic_set_bit(clients[i].flags, FLAG_ACTIVE); - memcpy(&clients[i].addr, bt_conn_get_dst(conn), sizeof(bt_addr_le_t)); + for (size_t i = 0U; i < ARRAY_SIZE(pacs.clients); i++) { + if (!atomic_test_bit(pacs.clients[i].flags, FLAG_ACTIVE)) { + atomic_set_bit(pacs.clients[i].flags, FLAG_ACTIVE); + memcpy(&pacs.clients[i].addr, bt_conn_get_dst(conn), sizeof(bt_addr_le_t)); /* Send out all pending notifications */ k_work_submit(&deferred_nfy_work); @@ -959,35 +1192,44 @@ static void pacs_auth_pairing_complete(struct bt_conn *conn, bool bonded) static void pacs_bond_deleted(uint8_t id, const bt_addr_le_t *peer) { /* Find the device entry to delete */ - for (size_t i = 0U; i < ARRAY_SIZE(clients); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(pacs.clients); i++) { /* Check if match, and if active, if so, reset */ - if (atomic_test_bit(clients[i].flags, FLAG_ACTIVE) && - bt_addr_le_eq(peer, &clients[i].addr)) { + if (atomic_test_bit(pacs.clients[i].flags, FLAG_ACTIVE) && + bt_addr_le_eq(peer, &pacs.clients[i].addr)) { for (size_t j = 0U; j < FLAG_NUM; j++) { - atomic_clear_bit(clients[i].flags, j); + atomic_clear_bit(pacs.clients[i].flags, j); } - (void)memset(&clients[i].addr, 0, sizeof(bt_addr_le_t)); + (void)memset(&pacs.clients[i].addr, 0, sizeof(bt_addr_le_t)); return; } } } static void pacs_security_changed(struct bt_conn *conn, bt_security_t level, - enum bt_security_err err) + enum bt_security_err sec_err) { + struct bt_conn_info info; + int err; + LOG_DBG("%s changed security level to %d", bt_addr_le_str(bt_conn_get_dst(conn)), level); - if (err != 0 || conn->encrypt == 0) { + if (sec_err != BT_SECURITY_ERR_SUCCESS || level <= BT_SECURITY_L1) { return; } - if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) { + err = bt_conn_get_info(conn, &info); + if (err < 0) { + __ASSERT_NO_MSG(false); + return; + } + + if (!bt_addr_le_is_bonded(info.id, info.le.dst)) { return; } - for (size_t i = 0U; i < ARRAY_SIZE(clients); i++) { + for (size_t i = 0U; i < ARRAY_SIZE(pacs.clients); i++) { for (size_t j = 0U; j < FLAG_NUM; j++) { - if (atomic_test_bit(clients[i].flags, j)) { + if (atomic_test_bit(pacs.clients[i].flags, j)) { /** * It's enough that one flag is set, as the defer work will go @@ -1010,7 +1252,8 @@ static void pacs_disconnected(struct bt_conn *conn, uint8_t reason) } #if defined(CONFIG_BT_PAC_SNK) - if (client->snk_available_contexts != NULL) { + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_PAC) && + client->snk_available_contexts != NULL) { uint16_t old = POINTER_TO_UINT(client->snk_available_contexts); uint16_t new; @@ -1022,7 +1265,8 @@ static void pacs_disconnected(struct bt_conn *conn, uint8_t reason) #endif /* CONFIG_BT_PAC_SNK */ #if defined(CONFIG_BT_PAC_SRC) - if (client->src_available_contexts != NULL) { + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_PAC) && + client->src_available_contexts != NULL) { uint16_t old = POINTER_TO_UINT(client->src_available_contexts); uint16_t new; @@ -1034,7 +1278,7 @@ static void pacs_disconnected(struct bt_conn *conn, uint8_t reason) #endif /* CONFIG_BT_PAC_SRC */ } -static struct bt_conn_cb conn_callbacks = { +BT_CONN_CB_DEFINE(conn_callbacks) = { .security_changed = pacs_security_changed, .disconnected = pacs_disconnected, }; @@ -1053,7 +1297,7 @@ void bt_pacs_cap_foreach(enum bt_audio_dir dir, bt_pacs_cap_foreach_func_t func, return; } - pac = pacs_get(dir); + pac = pacs_get_pac(dir); if (!pac) { return; } @@ -1063,14 +1307,14 @@ void bt_pacs_cap_foreach(enum bt_audio_dir dir, bt_pacs_cap_foreach_func_t func, static void add_bonded_addr_to_client_list(const struct bt_bond_info *info, void *data) { - for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) { + for (uint8_t i = 0; i < ARRAY_SIZE(pacs.clients); i++) { /* Check if device is registered, it not, add it */ - if (!atomic_test_bit(clients[i].flags, FLAG_ACTIVE)) { + if (!atomic_test_bit(pacs.clients[i].flags, FLAG_ACTIVE)) { char addr_str[BT_ADDR_LE_STR_LEN]; - atomic_set_bit(clients[i].flags, FLAG_ACTIVE); - memcpy(&clients[i].addr, &info->addr, sizeof(bt_addr_le_t)); - bt_addr_le_to_str(&clients[i].addr, addr_str, sizeof(addr_str)); + atomic_set_bit(pacs.clients[i].flags, FLAG_ACTIVE); + memcpy(&pacs.clients[i].addr, &info->addr, sizeof(bt_addr_le_t)); + bt_addr_le_to_str(&pacs.clients[i].addr, addr_str, sizeof(addr_str)); LOG_DBG("Added %s to bonded list\n", addr_str); return; } @@ -1090,7 +1334,7 @@ int bt_pacs_cap_register(enum bt_audio_dir dir, struct bt_pacs_cap *cap) codec_cap = cap->codec_cap; - pac = pacs_get(dir); + pac = pacs_get_pac(dir); if (!pac) { return -EINVAL; } @@ -1104,7 +1348,6 @@ int bt_pacs_cap_register(enum bt_audio_dir dir, struct bt_pacs_cap *cap) sys_slist_append(pac, &cap->_node); if (!callbacks_registered) { - bt_conn_cb_register(&conn_callbacks); bt_conn_auth_info_cb_register(&auth_callbacks); callbacks_registered = true; @@ -1132,7 +1375,7 @@ int bt_pacs_cap_unregister(enum bt_audio_dir dir, struct bt_pacs_cap *cap) return -EINVAL; } - pac = pacs_get(dir); + pac = pacs_get_pac(dir); if (!pac) { return -EINVAL; } @@ -1181,13 +1424,22 @@ int bt_pacs_set_location(enum bt_audio_dir dir, enum bt_audio_location location) int bt_pacs_set_available_contexts(enum bt_audio_dir dir, enum bt_audio_context contexts) { + if (!atomic_test_bit(pacs.flags, PACS_FLAG_REGISTERED)) { + return -EINVAL; + } switch (dir) { case BT_AUDIO_DIR_SINK: - return set_available_contexts(contexts, &snk_available_contexts, - supported_context_get(dir)); + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_PAC)) { + return set_available_contexts(contexts, &snk_available_contexts, + supported_context_get(dir)); + } + return -EINVAL; case BT_AUDIO_DIR_SOURCE: - return set_available_contexts(contexts, &src_available_contexts, - supported_context_get(dir)); + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_PAC)) { + return set_available_contexts(contexts, &src_available_contexts, + supported_context_get(dir)); + } + return -EINVAL; } return -EINVAL; @@ -1215,23 +1467,29 @@ int bt_pacs_conn_set_available_contexts_for_conn(struct bt_conn *conn, enum bt_a switch (dir) { #if defined(CONFIG_BT_PAC_SNK) case BT_AUDIO_DIR_SINK: - if (contexts != NULL) { - client->snk_available_contexts = UINT_TO_POINTER(*contexts); - } else { - client->snk_available_contexts = NULL; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_PAC)) { + if (contexts != NULL) { + client->snk_available_contexts = UINT_TO_POINTER(*contexts); + } else { + client->snk_available_contexts = NULL; + } + break; } - break; + return -EINVAL; #endif /* CONFIG_BT_PAC_SNK */ #if defined(CONFIG_BT_PAC_SRC) case BT_AUDIO_DIR_SOURCE: - if (contexts != NULL) { - client->src_available_contexts = UINT_TO_POINTER(*contexts); - } else { - client->src_available_contexts = NULL; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_PAC)) { + if (contexts != NULL) { + client->src_available_contexts = UINT_TO_POINTER(*contexts); + } else { + client->src_available_contexts = NULL; + } + break; } - break; + return -EINVAL; #endif /* CONFIG_BT_PAC_SRC */ default: return -EINVAL; @@ -1260,16 +1518,22 @@ int bt_pacs_set_supported_contexts(enum bt_audio_dir dir, enum bt_audio_context switch (dir) { case BT_AUDIO_DIR_SINK: #if defined(CONFIG_BT_PAC_SNK) - supported_contexts = &snk_supported_contexts; - available_contexts = &snk_available_contexts; - break; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_PAC)) { + supported_contexts = &snk_supported_contexts; + available_contexts = &snk_available_contexts; + break; + } + return -EINVAL; #endif /* CONFIG_BT_PAC_SNK */ return -ENOTSUP; case BT_AUDIO_DIR_SOURCE: #if defined(CONFIG_BT_PAC_SRC) - supported_contexts = &src_supported_contexts; - available_contexts = &src_available_contexts; - break; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_PAC)) { + supported_contexts = &src_supported_contexts; + available_contexts = &src_available_contexts; + break; + } + return -EINVAL; #endif /* CONFIG_BT_PAC_SRC */ return -ENOTSUP; default: @@ -1287,9 +1551,15 @@ enum bt_audio_context bt_pacs_get_available_contexts(enum bt_audio_dir dir) { switch (dir) { case BT_AUDIO_DIR_SINK: - return snk_available_contexts; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SNK_PAC)) { + return snk_available_contexts; + } + return -EINVAL; case BT_AUDIO_DIR_SOURCE: - return src_available_contexts; + if (atomic_test_bit(pacs.flags, PACS_FLAG_SRC_PAC)) { + return src_available_contexts; + } + return -EINVAL; } return BT_AUDIO_CONTEXT_TYPE_PROHIBITED; @@ -1305,3 +1575,36 @@ enum bt_audio_context bt_pacs_get_available_contexts_for_conn(struct bt_conn *co return pacs_get_available_contexts_for_conn(conn, dir); } + +struct codec_cap_lookup_id_data { + const struct bt_pac_codec *codec_id; + const struct bt_audio_codec_cap *codec_cap; +}; + +static bool codec_lookup_id(const struct bt_pacs_cap *cap, void *user_data) +{ + struct codec_cap_lookup_id_data *data = user_data; + + if (cap->codec_cap->id == data->codec_id->id && + cap->codec_cap->cid == data->codec_id->cid && + cap->codec_cap->vid == data->codec_id->vid) { + data->codec_cap = cap->codec_cap; + + return false; + } + + return true; +} + +const struct bt_audio_codec_cap *bt_pacs_get_codec_cap(enum bt_audio_dir dir, + const struct bt_pac_codec *codec_id) +{ + struct codec_cap_lookup_id_data lookup_data = { + .codec_id = codec_id, + .codec_cap = NULL, + }; + + bt_pacs_cap_foreach(dir, codec_lookup_id, &lookup_data); + + return lookup_data.codec_cap; +} diff --git a/subsys/bluetooth/audio/pacs_internal.h b/subsys/bluetooth/audio/pacs_internal.h index 8fe715e57ba87..897f8800504da 100644 --- a/subsys/bluetooth/audio/pacs_internal.h +++ b/subsys/bluetooth/audio/pacs_internal.h @@ -9,6 +9,7 @@ #include +#include #include #define BT_AUDIO_LOCATION_MASK BIT_MASK(28) @@ -38,3 +39,6 @@ struct bt_pacs_context { uint16_t snk; uint16_t src; } __packed; + +const struct bt_audio_codec_cap *bt_pacs_get_codec_cap(enum bt_audio_dir dir, + const struct bt_pac_codec *codec_id); diff --git a/subsys/bluetooth/audio/shell/CMakeLists.txt b/subsys/bluetooth/audio/shell/CMakeLists.txt index d44f4e1841777..bb71e1e65c0ae 100644 --- a/subsys/bluetooth/audio/shell/CMakeLists.txt +++ b/subsys/bluetooth/audio/shell/CMakeLists.txt @@ -3,6 +3,14 @@ zephyr_library() zephyr_library_link_libraries(subsys__bluetooth) +zephyr_library_sources_ifdef( + CONFIG_BT_CCP_CALL_CONTROL_SERVER + ccp_call_control_server.c + ) +zephyr_library_sources_ifdef( + CONFIG_BT_CCP_CALL_CONTROL_CLIENT + ccp_call_control_client.c + ) zephyr_library_sources_ifdef( CONFIG_BT_VCP_VOL_REND vcp_vol_rend.c diff --git a/subsys/bluetooth/audio/shell/audio.h b/subsys/bluetooth/audio/shell/audio.h index a02724bd75fdb..e73e10e0e8332 100644 --- a/subsys/bluetooth/audio/shell/audio.h +++ b/subsys/bluetooth/audio/shell/audio.h @@ -13,6 +13,7 @@ #ifndef AUDIO_SHELL_AUDIO_H #define AUDIO_SHELL_AUDIO_H +#include #include #include #include @@ -32,24 +33,24 @@ #include #include -#include "host/shell/bt.h" +#include "common/bt_shell_private.h" #define SHELL_PRINT_INDENT_LEVEL_SIZE 2 #define MAX_CODEC_FRAMES_PER_SDU 4U extern struct bt_csip_set_member_svc_inst *svc_inst; -ssize_t audio_ad_data_add(struct bt_data *data, const size_t data_size, const bool discoverable, - const bool connectable); -ssize_t audio_pa_data_add(struct bt_data *data_array, const size_t data_array_size); -ssize_t csis_ad_data_add(struct bt_data *data, const size_t data_size, const bool discoverable); +size_t audio_ad_data_add(struct bt_data *data, const size_t data_size, const bool discoverable, + const bool connectable); +size_t audio_pa_data_add(struct bt_data *data_array, const size_t data_array_size); +size_t csis_ad_data_add(struct bt_data *data, const size_t data_size, const bool discoverable); size_t cap_acceptor_ad_data_add(struct bt_data data[], size_t data_size, bool discoverable); size_t bap_scan_delegator_ad_data_add(struct bt_data data[], size_t data_size); size_t gmap_ad_data_add(struct bt_data data[], size_t data_size); size_t pbp_ad_data_add(struct bt_data data[], size_t data_size); -ssize_t cap_initiator_ad_data_add(struct bt_data *data_array, const size_t data_array_size, - const bool discoverable, const bool connectable); -ssize_t cap_initiator_pa_data_add(struct bt_data *data_array, const size_t data_array_size); +size_t cap_initiator_ad_data_add(struct bt_data *data_array, const size_t data_array_size, + const bool discoverable, const bool connectable); +size_t cap_initiator_pa_data_add(struct bt_data *data_array, const size_t data_array_size); #if defined(CONFIG_BT_AUDIO) /* Must guard before including audio.h as audio.h uses Kconfigs guarded by @@ -233,21 +234,19 @@ int cap_ac_unicast(const struct shell *sh, const struct bap_unicast_ac_param *pa #endif /* CONFIG_BT_BAP_UNICAST_CLIENT */ #endif /* CONFIG_BT_BAP_UNICAST */ -static inline void print_qos(const struct shell *sh, const struct bt_bap_qos_cfg *qos) +static inline void print_qos(const struct bt_bap_qos_cfg *qos) { #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_UNICAST) - shell_print(sh, - "QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u latency %u pd %u", - qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->latency, - qos->pd); + bt_shell_print("QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u latency %u pd %u", + qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->latency, + qos->pd); #else - shell_print(sh, "QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u pd %u", - qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->pd); + bt_shell_print("QoS: interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u pd %u", + qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->pd); #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_UNICAST */ } struct print_ltv_info { - const struct shell *sh; size_t indent; size_t cnt; }; @@ -257,27 +256,25 @@ static bool print_ltv_elem(struct bt_data *data, void *user_data) struct print_ltv_info *ltv_info = user_data; const size_t elem_indent = ltv_info->indent += SHELL_PRINT_INDENT_LEVEL_SIZE; - shell_print(ltv_info->sh, "%*s#%zu: type 0x%02x value_len %u", ltv_info->indent, "", - ltv_info->cnt, data->type, data->data_len); + bt_shell_print("%*s#%zu: type 0x%02x value_len %u", ltv_info->indent, "", + ltv_info->cnt, data->type, data->data_len); - shell_fprintf(ltv_info->sh, SHELL_NORMAL, "%*s", elem_indent, ""); + bt_shell_fprintf_print("%*s", elem_indent, ""); for (uint8_t i = 0U; i < data->data_len; i++) { - shell_fprintf(ltv_info->sh, SHELL_NORMAL, "%02X", data->data[i]); + bt_shell_fprintf_print("%02X", data->data[i]); } - shell_fprintf(ltv_info->sh, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); ltv_info->cnt++; return true; } -static void print_ltv_array(const struct shell *sh, size_t indent, const uint8_t *ltv_data, - size_t ltv_data_len) +static void print_ltv_array(size_t indent, const uint8_t *ltv_data, size_t ltv_data_len) { struct print_ltv_info ltv_info = { - .sh = sh, .cnt = 0U, .indent = indent, }; @@ -285,14 +282,13 @@ static void print_ltv_array(const struct shell *sh, size_t indent, const uint8_t err = bt_audio_data_parse(ltv_data, ltv_data_len, print_ltv_elem, <v_info); if (err != 0 && err != -ECANCELED) { - shell_error(sh, "%*sInvalid LTV data: %d", indent, "", err); + bt_shell_error("%*sInvalid LTV data: %d", indent, "", err); } } -static inline void print_codec_meta_pref_context(const struct shell *sh, size_t indent, - enum bt_audio_context context) +static inline void print_codec_meta_pref_context(size_t indent, enum bt_audio_context context) { - shell_print(sh, "%*sPreferred audio contexts:", indent, ""); + bt_shell_print("%*sPreferred audio contexts:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; @@ -301,16 +297,15 @@ static inline void print_codec_meta_pref_context(const struct shell *sh, size_t const uint16_t bit_val = BIT(i); if (context & bit_val) { - shell_print(sh, "%*s%s (0x%04X)", indent, "", - bt_audio_context_bit_to_str(bit_val), bit_val); + bt_shell_print("%*s%s (0x%04X)", indent, "", + bt_audio_context_bit_to_str(bit_val), bit_val); } } } -static inline void print_codec_meta_stream_context(const struct shell *sh, size_t indent, - enum bt_audio_context context) +static inline void print_codec_meta_stream_context(size_t indent, enum bt_audio_context context) { - shell_print(sh, "%*sStreaming audio contexts:", indent, ""); + bt_shell_print("%*sStreaming audio contexts:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; @@ -319,121 +314,118 @@ static inline void print_codec_meta_stream_context(const struct shell *sh, size_ const uint16_t bit_val = BIT(i); if (context & bit_val) { - shell_print(sh, "%*s%s (0x%04X)", indent, "", - bt_audio_context_bit_to_str(bit_val), bit_val); + bt_shell_print("%*s%s (0x%04X)", indent, "", + bt_audio_context_bit_to_str(bit_val), bit_val); } } } -static inline void print_codec_meta_program_info(const struct shell *sh, size_t indent, - const uint8_t *program_info, +static inline void print_codec_meta_program_info(size_t indent, const uint8_t *program_info, uint8_t program_info_len) { - shell_print(sh, "%*sProgram info:", indent, ""); + bt_shell_print("%*sProgram info:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; - shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < program_info_len; i++) { - shell_fprintf(sh, SHELL_NORMAL, "%c", (char)program_info[i]); + bt_shell_fprintf_print("%c", (char)program_info[i]); } - shell_fprintf(sh, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } -static inline void print_codec_meta_language(const struct shell *sh, size_t indent, +static inline void print_codec_meta_language(size_t indent, const uint8_t lang[BT_AUDIO_LANG_SIZE]) { - shell_print(sh, "%*sLanguage: %c%c%c", indent, "", (char)lang[0], (char)lang[1], - (char)lang[2]); + bt_shell_print("%*sLanguage: %c%c%c", indent, "", (char)lang[0], (char)lang[1], + (char)lang[2]); } -static inline void print_codec_meta_ccid_list(const struct shell *sh, size_t indent, - const uint8_t *ccid_list, uint8_t ccid_list_len) +static inline void print_codec_meta_ccid_list(size_t indent, const uint8_t *ccid_list, + uint8_t ccid_list_len) { - shell_print(sh, "%*sCCID list:", indent, ""); + bt_shell_print("%*sCCID list:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; /* There can be up to 16 bits set in the field */ for (uint8_t i = 0U; i < ccid_list_len; i++) { - shell_print(sh, "%*s0x%02X ", indent, "", ccid_list[i]); + bt_shell_print("%*s0x%02X ", indent, "", ccid_list[i]); } } -static inline void print_codec_meta_parental_rating(const struct shell *sh, size_t indent, +static inline void print_codec_meta_parental_rating(size_t indent, enum bt_audio_parental_rating parental_rating) { - shell_print(sh, "%*sRating: %s (0x%02X)", indent, "", - bt_audio_parental_rating_to_str(parental_rating), (uint8_t)parental_rating); + bt_shell_print("%*sRating: %s (0x%02X)", indent, "", + bt_audio_parental_rating_to_str(parental_rating), (uint8_t)parental_rating); } -static inline void print_codec_meta_program_info_uri(const struct shell *sh, size_t indent, +static inline void print_codec_meta_program_info_uri(size_t indent, const uint8_t *program_info_uri, uint8_t program_info_uri_len) { - shell_print(sh, "%*sProgram info URI:", indent, ""); + bt_shell_print("%*sProgram info URI:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; - shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < program_info_uri_len; i++) { - shell_fprintf(sh, SHELL_NORMAL, "%c", (char)program_info_uri[i]); + bt_shell_fprintf_print("%c", (char)program_info_uri[i]); } - shell_fprintf(sh, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } -static inline void print_codec_meta_audio_active_state(const struct shell *sh, size_t indent, +static inline void print_codec_meta_audio_active_state(size_t indent, enum bt_audio_active_state state) { - shell_print(sh, "%*sAudio active state: %s (0x%02X)", indent, "", - bt_audio_active_state_to_str(state), (uint8_t)state); + bt_shell_print("%*sAudio active state: %s (0x%02X)", indent, "", + bt_audio_active_state_to_str(state), (uint8_t)state); } -static inline void print_codec_meta_bcast_audio_immediate_rend_flag(const struct shell *sh, - size_t indent) +static inline void print_codec_meta_bcast_audio_immediate_rend_flag(size_t indent) { - shell_print(sh, "%*sBroadcast audio immediate rendering flag set", indent, ""); + bt_shell_print("%*sBroadcast audio immediate rendering flag set", indent, ""); } -static inline void print_codec_meta_extended(const struct shell *sh, size_t indent, - const uint8_t *extended_meta, size_t extended_meta_len) +static inline void print_codec_meta_extended(size_t indent, const uint8_t *extended_meta, + size_t extended_meta_len) { - shell_print(sh, "%*sExtended metadata:", indent, ""); + bt_shell_print("%*sExtended metadata:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; - shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < extended_meta_len; i++) { - shell_fprintf(sh, SHELL_NORMAL, "%u", (uint8_t)extended_meta[i]); + bt_shell_fprintf_print("%u", (uint8_t)extended_meta[i]); } - shell_fprintf(sh, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } -static inline void print_codec_meta_vendor(const struct shell *sh, size_t indent, - const uint8_t *vendor_meta, size_t vender_meta_len) +static inline void print_codec_meta_vendor(size_t indent, const uint8_t *vendor_meta, + size_t vender_meta_len) { - shell_print(sh, "%*sVendor metadata:", indent, ""); + bt_shell_print("%*sVendor metadata:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; - shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < vender_meta_len; i++) { - shell_fprintf(sh, SHELL_NORMAL, "%u", (uint8_t)vendor_meta[i]); + bt_shell_fprintf_print("%u", (uint8_t)vendor_meta[i]); } - shell_fprintf(sh, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } -static inline void print_codec_cap_freq(const struct shell *sh, size_t indent, - enum bt_audio_codec_cap_freq freq) +static inline void print_codec_cap_freq(size_t indent, enum bt_audio_codec_cap_freq freq) { - shell_print(sh, "%*sSupported sampling frequencies:", indent, ""); + bt_shell_print("%*sSupported sampling frequencies:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; /* There can be up to 16 bits set in the field */ @@ -441,16 +433,16 @@ static inline void print_codec_cap_freq(const struct shell *sh, size_t indent, const uint16_t bit_val = BIT(i); if (freq & bit_val) { - shell_print(sh, "%*s%s (0x%04X)", indent, "", - bt_audio_codec_cap_freq_bit_to_str(bit_val), bit_val); + bt_shell_print("%*s%s (0x%04X)", indent, "", + bt_audio_codec_cap_freq_bit_to_str(bit_val), bit_val); } } } -static inline void print_codec_cap_frame_dur(const struct shell *sh, size_t indent, +static inline void print_codec_cap_frame_dur(size_t indent, enum bt_audio_codec_cap_frame_dur frame_dur) { - shell_print(sh, "%*sSupported frame durations:", indent, ""); + bt_shell_print("%*sSupported frame durations:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; /* There can be up to 8 bits set in the field */ @@ -458,16 +450,16 @@ static inline void print_codec_cap_frame_dur(const struct shell *sh, size_t inde const uint8_t bit_val = BIT(i); if (frame_dur & bit_val) { - shell_print(sh, "%*s%s (0x%02X)", indent, "", - bt_audio_codec_cap_frame_dur_bit_to_str(bit_val), bit_val); + bt_shell_print("%*s%s (0x%02X)", indent, "", + bt_audio_codec_cap_frame_dur_bit_to_str(bit_val), bit_val); } } } -static inline void print_codec_cap_chan_count(const struct shell *sh, size_t indent, +static inline void print_codec_cap_chan_count(size_t indent, enum bt_audio_codec_cap_chan_count chan_count) { - shell_print(sh, "%*sSupported channel counts:", indent, ""); + bt_shell_print("%*sSupported channel counts:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; /* There can be up to 8 bits set in the field */ @@ -475,82 +467,80 @@ static inline void print_codec_cap_chan_count(const struct shell *sh, size_t ind const uint8_t bit_val = BIT(i); if (chan_count & bit_val) { - shell_print(sh, "%*s%s (0x%02X)", indent, "", - bt_audio_codec_cap_chan_count_bit_to_str(bit_val), bit_val); + bt_shell_print("%*s%s (0x%02X)", indent, "", + bt_audio_codec_cap_chan_count_bit_to_str(bit_val), bit_val); } } } static inline void print_codec_cap_octets_per_codec_frame( - const struct shell *sh, size_t indent, - const struct bt_audio_codec_octets_per_codec_frame *codec_frame) + size_t indent, const struct bt_audio_codec_octets_per_codec_frame *codec_frame) { - shell_print(sh, "%*sSupported octets per codec frame counts:", indent, ""); + bt_shell_print("%*sSupported octets per codec frame counts:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; - shell_print(sh, "%*sMin: %u", indent, "", codec_frame->min); - shell_print(sh, "%*sMax: %u", indent, "", codec_frame->max); + bt_shell_print("%*sMin: %u", indent, "", codec_frame->min); + bt_shell_print("%*sMax: %u", indent, "", codec_frame->max); } -static inline void print_codec_cap_max_codec_frames_per_sdu(const struct shell *sh, size_t indent, +static inline void print_codec_cap_max_codec_frames_per_sdu(size_t indent, uint8_t codec_frames_per_sdu) { - shell_print(sh, "%*sSupported max codec frames per SDU: %u", indent, "", - codec_frames_per_sdu); + bt_shell_print("%*sSupported max codec frames per SDU: %u", indent, "", + codec_frames_per_sdu); } -static inline void print_codec_cap(const struct shell *sh, size_t indent, - const struct bt_audio_codec_cap *codec_cap) +static inline void print_codec_cap(size_t indent, const struct bt_audio_codec_cap *codec_cap) { - shell_print(sh, "%*scodec cap id 0x%02x cid 0x%04x vid 0x%04x", indent, "", codec_cap->id, - codec_cap->cid, codec_cap->vid); + bt_shell_print("%*scodec cap id 0x%02x cid 0x%04x vid 0x%04x", indent, "", codec_cap->id, + codec_cap->cid, codec_cap->vid); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 - shell_print(sh, "%*sCodec specific capabilities:", indent, ""); + bt_shell_print("%*sCodec specific capabilities:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; if (codec_cap->data_len == 0U) { - shell_print(sh, "%*sNone", indent, ""); + bt_shell_print("%*sNone", indent, ""); } else if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) { struct bt_audio_codec_octets_per_codec_frame codec_frame; int ret; ret = bt_audio_codec_cap_get_freq(codec_cap); if (ret >= 0) { - print_codec_cap_freq(sh, indent, (enum bt_audio_codec_cap_freq)ret); + print_codec_cap_freq(indent, (enum bt_audio_codec_cap_freq)ret); } ret = bt_audio_codec_cap_get_frame_dur(codec_cap); if (ret >= 0) { - print_codec_cap_frame_dur(sh, indent, + print_codec_cap_frame_dur(indent, (enum bt_audio_codec_cap_frame_dur)ret); } ret = bt_audio_codec_cap_get_supported_audio_chan_counts(codec_cap, true); if (ret >= 0) { - print_codec_cap_chan_count(sh, indent, + print_codec_cap_chan_count(indent, (enum bt_audio_codec_cap_chan_count)ret); } ret = bt_audio_codec_cap_get_octets_per_frame(codec_cap, &codec_frame); if (ret >= 0) { - print_codec_cap_octets_per_codec_frame(sh, indent, &codec_frame); + print_codec_cap_octets_per_codec_frame(indent, &codec_frame); } ret = bt_audio_codec_cap_get_max_codec_frames_per_sdu(codec_cap, true); if (ret >= 0) { - print_codec_cap_max_codec_frames_per_sdu(sh, indent, (uint8_t)ret); + print_codec_cap_max_codec_frames_per_sdu(indent, (uint8_t)ret); } } else { /* If not LC3, we cannot assume it's LTV */ - shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < codec_cap->data_len; i++) { - shell_fprintf(sh, SHELL_NORMAL, "%*s%02X", indent, "", codec_cap->data[i]); + bt_shell_fprintf_print("%*s%02X", indent, "", codec_cap->data[i]); } - shell_fprintf(sh, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } /* Reduce for metadata*/ @@ -558,169 +548,166 @@ static inline void print_codec_cap(const struct shell *sh, size_t indent, #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */ #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 - shell_print(sh, "%*sCodec capabilities metadata:", indent, ""); + bt_shell_print("%*sCodec capabilities metadata:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; if (codec_cap->meta_len == 0U) { - shell_print(sh, "%*sNone", indent, ""); + bt_shell_print("%*sNone", indent, ""); } else { const uint8_t *data; int ret; ret = bt_audio_codec_cap_meta_get_pref_context(codec_cap); if (ret >= 0) { - print_codec_meta_pref_context(sh, indent, (enum bt_audio_context)ret); + print_codec_meta_pref_context(indent, (enum bt_audio_context)ret); } ret = bt_audio_codec_cap_meta_get_stream_context(codec_cap); if (ret >= 0) { - print_codec_meta_stream_context(sh, indent, (enum bt_audio_context)ret); + print_codec_meta_stream_context(indent, (enum bt_audio_context)ret); } ret = bt_audio_codec_cap_meta_get_program_info(codec_cap, &data); if (ret >= 0) { - print_codec_meta_program_info(sh, indent, data, (uint8_t)ret); + print_codec_meta_program_info(indent, data, (uint8_t)ret); } ret = bt_audio_codec_cap_meta_get_lang(codec_cap, &data); if (ret >= 0) { - print_codec_meta_language(sh, indent, data); + print_codec_meta_language(indent, data); } ret = bt_audio_codec_cap_meta_get_ccid_list(codec_cap, &data); if (ret >= 0) { - print_codec_meta_ccid_list(sh, indent, data, (uint8_t)ret); + print_codec_meta_ccid_list(indent, data, (uint8_t)ret); } ret = bt_audio_codec_cap_meta_get_parental_rating(codec_cap); if (ret >= 0) { - print_codec_meta_parental_rating(sh, indent, + print_codec_meta_parental_rating(indent, (enum bt_audio_parental_rating)ret); } ret = bt_audio_codec_cap_meta_get_audio_active_state(codec_cap); if (ret >= 0) { - print_codec_meta_audio_active_state(sh, indent, + print_codec_meta_audio_active_state(indent, (enum bt_audio_active_state)ret); } ret = bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(codec_cap); if (ret >= 0) { - print_codec_meta_bcast_audio_immediate_rend_flag(sh, indent); + print_codec_meta_bcast_audio_immediate_rend_flag(indent); } ret = bt_audio_codec_cap_meta_get_extended(codec_cap, &data); if (ret >= 0) { - print_codec_meta_extended(sh, indent, data, (uint8_t)ret); + print_codec_meta_extended(indent, data, (uint8_t)ret); } ret = bt_audio_codec_cap_meta_get_vendor(codec_cap, &data); if (ret >= 0) { - print_codec_meta_vendor(sh, indent, data, (uint8_t)ret); + print_codec_meta_vendor(indent, data, (uint8_t)ret); } } #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */ } -static inline void print_codec_cfg_freq(const struct shell *sh, size_t indent, - enum bt_audio_codec_cfg_freq freq) +static inline void print_codec_cfg_freq(size_t indent, enum bt_audio_codec_cfg_freq freq) { - shell_print(sh, "%*sSampling frequency: %u Hz (0x%04X)", indent, "", - bt_audio_codec_cfg_freq_to_freq_hz(freq), (uint16_t)freq); + bt_shell_print("%*sSampling frequency: %u Hz (0x%04X)", indent, "", + bt_audio_codec_cfg_freq_to_freq_hz(freq), (uint16_t)freq); } -static inline void print_codec_cfg_frame_dur(const struct shell *sh, size_t indent, +static inline void print_codec_cfg_frame_dur(size_t indent, enum bt_audio_codec_cfg_frame_dur frame_dur) { - shell_print(sh, "%*sFrame duration: %u us (0x%02X)", indent, "", - bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur), (uint8_t)frame_dur); + bt_shell_print("%*sFrame duration: %u us (0x%02X)", indent, "", + bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur), (uint8_t)frame_dur); } -static inline void print_codec_cfg_chan_allocation(const struct shell *sh, size_t indent, +static inline void print_codec_cfg_chan_allocation(size_t indent, enum bt_audio_location chan_allocation) { - shell_print(sh, "%*sChannel allocation:", indent, ""); + bt_shell_print("%*sChannel allocation:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; if (chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO) { - shell_print(sh, "%*s Mono", indent, ""); + bt_shell_print("%*s Mono", indent, ""); } else { /* There can be up to 32 bits set in the field */ for (size_t i = 0; i < 32; i++) { const uint8_t bit_val = BIT(i); if (chan_allocation & bit_val) { - shell_print(sh, "%*s%s (0x%08X)", indent, "", - bt_audio_location_bit_to_str(bit_val), bit_val); + bt_shell_print("%*s%s (0x%08X)", indent, "", + bt_audio_location_bit_to_str(bit_val), bit_val); } } } } -static inline void print_codec_cfg_octets_per_frame(const struct shell *sh, size_t indent, - uint16_t octets_per_frame) +static inline void print_codec_cfg_octets_per_frame(size_t indent, uint16_t octets_per_frame) { - shell_print(sh, "%*sOctets per codec frame: %u", indent, "", octets_per_frame); + bt_shell_print("%*sOctets per codec frame: %u", indent, "", octets_per_frame); } -static inline void print_codec_cfg_frame_blocks_per_sdu(const struct shell *sh, size_t indent, +static inline void print_codec_cfg_frame_blocks_per_sdu(size_t indent, uint8_t frame_blocks_per_sdu) { - shell_print(sh, "%*sCodec frame blocks per SDU: %u", indent, "", frame_blocks_per_sdu); + bt_shell_print("%*sCodec frame blocks per SDU: %u", indent, "", frame_blocks_per_sdu); } -static inline void print_codec_cfg(const struct shell *sh, size_t indent, - const struct bt_audio_codec_cfg *codec_cfg) +static inline void print_codec_cfg(size_t indent, const struct bt_audio_codec_cfg *codec_cfg) { - shell_print(sh, "%*scodec cfg id 0x%02x cid 0x%04x vid 0x%04x count %u", indent, "", - codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len); + bt_shell_print("%*scodec cfg id 0x%02x cid 0x%04x vid 0x%04x count %u", indent, "", + codec_cfg->id, codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 - shell_print(sh, "%*sCodec specific configuration:", indent, ""); + bt_shell_print("%*sCodec specific configuration:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; if (codec_cfg->data_len == 0U) { - shell_print(sh, "%*sNone", indent, ""); + bt_shell_print("%*sNone", indent, ""); } else if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) { enum bt_audio_location chan_allocation; int ret; ret = bt_audio_codec_cfg_get_freq(codec_cfg); if (ret >= 0) { - print_codec_cfg_freq(sh, indent, (enum bt_audio_codec_cfg_freq)ret); + print_codec_cfg_freq(indent, (enum bt_audio_codec_cfg_freq)ret); } ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg); if (ret >= 0) { - print_codec_cfg_frame_dur(sh, indent, + print_codec_cfg_frame_dur(indent, (enum bt_audio_codec_cfg_frame_dur)ret); } ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation, false); if (ret == 0) { - print_codec_cfg_chan_allocation(sh, indent, chan_allocation); + print_codec_cfg_chan_allocation(indent, chan_allocation); } ret = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg); if (ret >= 0) { - print_codec_cfg_octets_per_frame(sh, indent, (uint16_t)ret); + print_codec_cfg_octets_per_frame(indent, (uint16_t)ret); } ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, false); if (ret >= 0) { - print_codec_cfg_frame_blocks_per_sdu(sh, indent, (uint8_t)ret); + print_codec_cfg_frame_blocks_per_sdu(indent, (uint8_t)ret); } } else { /* If not LC3, we cannot assume it's LTV */ - shell_fprintf(sh, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < codec_cfg->data_len; i++) { - shell_fprintf(sh, SHELL_NORMAL, "%*s%02X", indent, "", codec_cfg->data[i]); + bt_shell_fprintf_print("%*s%02X", indent, "", codec_cfg->data[i]); } - shell_fprintf(sh, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } /* Reduce for metadata*/ @@ -728,65 +715,65 @@ static inline void print_codec_cfg(const struct shell *sh, size_t indent, #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */ #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 - shell_print(sh, "%*sCodec specific metadata:", indent, ""); + bt_shell_print("%*sCodec specific metadata:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; if (codec_cfg->meta_len == 0U) { - shell_print(sh, "%*sNone", indent, ""); + bt_shell_print("%*sNone", indent, ""); } else { const uint8_t *data; int ret; ret = bt_audio_codec_cfg_meta_get_pref_context(codec_cfg, true); if (ret >= 0) { - print_codec_meta_pref_context(sh, indent, (enum bt_audio_context)ret); + print_codec_meta_pref_context(indent, (enum bt_audio_context)ret); } ret = bt_audio_codec_cfg_meta_get_stream_context(codec_cfg); if (ret >= 0) { - print_codec_meta_stream_context(sh, indent, (enum bt_audio_context)ret); + print_codec_meta_stream_context(indent, (enum bt_audio_context)ret); } ret = bt_audio_codec_cfg_meta_get_program_info(codec_cfg, &data); if (ret >= 0) { - print_codec_meta_program_info(sh, indent, data, (uint8_t)ret); + print_codec_meta_program_info(indent, data, (uint8_t)ret); } ret = bt_audio_codec_cfg_meta_get_lang(codec_cfg, &data); if (ret >= 0) { - print_codec_meta_language(sh, indent, data); + print_codec_meta_language(indent, data); } ret = bt_audio_codec_cfg_meta_get_ccid_list(codec_cfg, &data); if (ret >= 0) { - print_codec_meta_ccid_list(sh, indent, data, (uint8_t)ret); + print_codec_meta_ccid_list(indent, data, (uint8_t)ret); } ret = bt_audio_codec_cfg_meta_get_parental_rating(codec_cfg); if (ret >= 0) { - print_codec_meta_parental_rating(sh, indent, + print_codec_meta_parental_rating(indent, (enum bt_audio_parental_rating)ret); } ret = bt_audio_codec_cfg_meta_get_audio_active_state(codec_cfg); if (ret >= 0) { - print_codec_meta_audio_active_state(sh, indent, + print_codec_meta_audio_active_state(indent, (enum bt_audio_active_state)ret); } ret = bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(codec_cfg); if (ret >= 0) { - print_codec_meta_bcast_audio_immediate_rend_flag(sh, indent); + print_codec_meta_bcast_audio_immediate_rend_flag(indent); } ret = bt_audio_codec_cfg_meta_get_extended(codec_cfg, &data); if (ret >= 0) { - print_codec_meta_extended(sh, indent, data, (uint8_t)ret); + print_codec_meta_extended(indent, data, (uint8_t)ret); } ret = bt_audio_codec_cfg_meta_get_vendor(codec_cfg, &data); if (ret >= 0) { - print_codec_meta_vendor(sh, indent, data, (uint8_t)ret); + print_codec_meta_vendor(indent, data, (uint8_t)ret); } } #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */ @@ -813,7 +800,7 @@ static inline bool print_base_subgroup_bis_cb(const struct bt_bap_base_subgroup_ size_t indent = 2 * SHELL_PRINT_INDENT_LEVEL_SIZE; struct bt_bap_base_codec_id *codec_id = user_data; - shell_print(ctx_shell, "%*sBIS index: 0x%02X", indent, "", bis->index); + bt_shell_print("%*sBIS index: 0x%02X", indent, "", bis->index); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; @@ -828,22 +815,22 @@ static inline bool print_base_subgroup_bis_cb(const struct bt_bap_base_subgroup_ err = bt_bap_base_subgroup_bis_codec_to_codec_cfg(bis, &codec_cfg); if (err == 0) { - print_codec_cfg(ctx_shell, indent, &codec_cfg); + print_codec_cfg(indent, &codec_cfg); } else { - shell_print(ctx_shell, "%*sCodec specific configuration:", indent, ""); - print_ltv_array(ctx_shell, indent, bis->data, bis->data_len); + bt_shell_print("%*sCodec specific configuration:", indent, ""); + print_ltv_array(indent, bis->data, bis->data_len); } } else { /* If not LC3, we cannot assume it's LTV */ - shell_print(ctx_shell, "%*sCodec specific configuration:", indent, ""); + bt_shell_print("%*sCodec specific configuration:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; - shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < bis->data_len; i++) { - shell_fprintf(ctx_shell, SHELL_NORMAL, "%02X", bis->data[i]); + bt_shell_fprintf_print("%02X", bis->data[i]); } - shell_fprintf(ctx_shell, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } return true; @@ -858,20 +845,20 @@ static inline bool print_base_subgroup_cb(const struct bt_bap_base_subgroup *sub uint8_t *data; int ret; - shell_print(ctx_shell, "Subgroup %p:", subgroup); + bt_shell_print("Subgroup %p:", subgroup); ret = bt_bap_base_get_subgroup_codec_id(subgroup, &codec_id); if (ret < 0) { return false; } - shell_print(ctx_shell, "%*sCodec Format: 0x%02X", indent, "", codec_id.id); - shell_print(ctx_shell, "%*sCompany ID : 0x%04X", indent, "", codec_id.cid); - shell_print(ctx_shell, "%*sVendor ID : 0x%04X", indent, "", codec_id.vid); + bt_shell_print("%*sCodec Format: 0x%02X", indent, "", codec_id.id); + bt_shell_print("%*sCompany ID : 0x%04X", indent, "", codec_id.cid); + bt_shell_print("%*sVendor ID : 0x%04X", indent, "", codec_id.vid); ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &codec_cfg); if (ret == 0) { - print_codec_cfg(ctx_shell, indent, &codec_cfg); + print_codec_cfg(indent, &codec_cfg); } else { /* If we cannot store it in a codec_cfg, then we cannot easily print it as such */ ret = bt_bap_base_get_subgroup_codec_data(subgroup, &data); @@ -879,20 +866,20 @@ static inline bool print_base_subgroup_cb(const struct bt_bap_base_subgroup *sub return false; } - shell_print(ctx_shell, "%*sCodec specific configuration:", indent, ""); + bt_shell_print("%*sCodec specific configuration:", indent, ""); indent += SHELL_PRINT_INDENT_LEVEL_SIZE; /* Print CC data */ if (codec_id.id == BT_HCI_CODING_FORMAT_LC3) { - print_ltv_array(ctx_shell, indent, data, (uint8_t)ret); + print_ltv_array(indent, data, (uint8_t)ret); } else { /* If not LC3, we cannot assume it's LTV */ - shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < (uint8_t)ret; i++) { - shell_fprintf(ctx_shell, SHELL_NORMAL, "%c", data[i]); + bt_shell_fprintf_print("%c", data[i]); } - shell_fprintf(ctx_shell, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } ret = bt_bap_base_get_subgroup_codec_meta(subgroup, &data); @@ -900,21 +887,21 @@ static inline bool print_base_subgroup_cb(const struct bt_bap_base_subgroup *sub return false; } - shell_print(ctx_shell, - "%*sCodec specific metadata:", indent - SHELL_PRINT_INDENT_LEVEL_SIZE, - ""); + bt_shell_print( + "%*sCodec specific metadata:", indent - SHELL_PRINT_INDENT_LEVEL_SIZE, + ""); /* Print metadata */ if (codec_id.id == BT_HCI_CODING_FORMAT_LC3) { - print_ltv_array(ctx_shell, indent, data, (uint8_t)ret); + print_ltv_array(indent, data, (uint8_t)ret); } else { /* If not LC3, we cannot assume it's LTV */ - shell_fprintf(ctx_shell, SHELL_NORMAL, "%*s", indent, ""); + bt_shell_fprintf_print("%*s", indent, ""); for (uint8_t i = 0U; i < (uint8_t)ret; i++) { - shell_fprintf(ctx_shell, SHELL_NORMAL, "%c", data[i]); + bt_shell_fprintf_print("%c", data[i]); } - shell_fprintf(ctx_shell, SHELL_NORMAL, "\n"); + bt_shell_fprintf_print("\n"); } } @@ -930,12 +917,12 @@ static inline void print_base(const struct bt_bap_base *base) { int err; - shell_print(ctx_shell, "Presentation delay: %d", bt_bap_base_get_pres_delay(base)); - shell_print(ctx_shell, "Subgroup count: %d", bt_bap_base_get_subgroup_count(base)); + bt_shell_print("Presentation delay: %d", bt_bap_base_get_pres_delay(base)); + bt_shell_print("Subgroup count: %d", bt_bap_base_get_subgroup_count(base)); err = bt_bap_base_foreach_subgroup(base, print_base_subgroup_cb, NULL); if (err < 0) { - shell_info(ctx_shell, "Invalid BASE: %d", err); + bt_shell_info("Invalid BASE: %d", err); } } diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index d06d055318d4f..71a335859453d 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #include #include +#include "common/bt_shell_private.h" #include "host/shell/bt.h" #include "audio.h" @@ -294,23 +296,23 @@ static int16_t lc3_tx_buf[LC3_MAX_NUM_SAMPLES_MONO]; static int init_lc3_encoder(struct shell_stream *sh_stream) { if (sh_stream == NULL) { - shell_error(ctx_shell, "NULL stream to init LC3"); + bt_shell_error("NULL stream to init LC3"); return -EINVAL; } if (!sh_stream->is_tx) { - shell_error(ctx_shell, "Invalid stream to init LC3 encoder"); + bt_shell_error("Invalid stream to init LC3 encoder"); return -EINVAL; } if (sh_stream->tx.lc3_encoder != NULL) { - shell_error(ctx_shell, "Already initialized"); + bt_shell_error("Already initialized"); return -EALREADY; } if (sh_stream->lc3_freq_hz == 0 || sh_stream->lc3_frame_duration_us == 0) { - shell_error(ctx_shell, "Invalid freq (%u) or frame duration (%u)", - sh_stream->lc3_freq_hz, sh_stream->lc3_frame_duration_us); + bt_shell_error("Invalid freq (%u) or frame duration (%u)", + sh_stream->lc3_freq_hz, sh_stream->lc3_frame_duration_us); return -EINVAL; } @@ -319,25 +321,25 @@ static int init_lc3_encoder(struct shell_stream *sh_stream) const size_t frame_size = bap_usb_get_frame_size(sh_stream); if (frame_size > sizeof(lc3_tx_buf)) { - shell_error(ctx_shell, "Cannot put %u octets in lc3_tx_buf of size %zu", - frame_size, sizeof(lc3_tx_buf)); + bt_shell_error("Cannot put %u octets in lc3_tx_buf of size %zu", + frame_size, sizeof(lc3_tx_buf)); return -EINVAL; } } - shell_print(ctx_shell, - "Initializing LC3 encoder for BAP stream %p with %u us duration and %u Hz " - "frequency", - bap_stream_from_shell_stream(sh_stream), sh_stream->lc3_frame_duration_us, - sh_stream->lc3_freq_hz); + bt_shell_print( + "Initializing LC3 encoder for BAP stream %p with %u us duration and %u Hz " + "frequency", + bap_stream_from_shell_stream(sh_stream), sh_stream->lc3_frame_duration_us, + sh_stream->lc3_freq_hz); sh_stream->tx.lc3_encoder = lc3_setup_encoder(sh_stream->lc3_frame_duration_us, sh_stream->lc3_freq_hz, IS_ENABLED(CONFIG_USB_DEVICE_AUDIO) ? USB_SAMPLE_RATE : 0, &sh_stream->tx.lc3_encoder_mem); if (sh_stream->tx.lc3_encoder == NULL) { - shell_error(ctx_shell, "Failed to setup LC3 encoder - wrong parameters?\n"); + bt_shell_error("Failed to setup LC3 encoder - wrong parameters?\n"); return -EINVAL; } @@ -391,15 +393,15 @@ static bool encode_frame(struct shell_stream *sh_stream, uint8_t index, size_t f } if ((sh_stream->tx.encoded_cnt % bap_stats_interval) == 0) { - shell_print(ctx_shell, "[%zu]: Encoding frame of size %u (%u/%u)", - sh_stream->tx.encoded_cnt, octets_per_frame, frame_cnt + 1, - total_frames); + bt_shell_print("[%zu]: Encoding frame of size %u (%u/%u)", + sh_stream->tx.encoded_cnt, octets_per_frame, frame_cnt + 1, + total_frames); } lc3_ret = lc3_encode(sh_stream->tx.lc3_encoder, LC3_PCM_FORMAT_S16, lc3_tx_buf, 1, octets_per_frame, net_buf_tail(out_buf)); if (lc3_ret == -1) { - shell_error(ctx_shell, "LC3 encoder failed - wrong parameters?: %d", lc3_ret); + bt_shell_error("LC3 encoder failed - wrong parameters?: %d", lc3_ret); return false; } @@ -456,22 +458,22 @@ static void lc3_audio_send_data(struct shell_stream *sh_stream) } if (sh_stream->tx.lc3_encoder == NULL) { - shell_error(ctx_shell, "LC3 encoder not setup, cannot encode data"); + bt_shell_error("LC3 encoder not setup, cannot encode data"); return; } if (bap_stream == NULL || bap_stream->qos == NULL) { - shell_error(ctx_shell, "invalid stream, aborting"); + bt_shell_error("invalid stream, aborting"); return; } if (tx_sdu_len == 0U || tx_sdu_len > SINE_TX_POOL_SIZE) { - shell_error(ctx_shell, - "Cannot send %u length SDU (from frame blocks per sdu %u, channel " - "count %u and %u octets per frame) for pool size %d", - tx_sdu_len, sh_stream->lc3_frame_blocks_per_sdu, - sh_stream->lc3_chan_cnt, sh_stream->lc3_octets_per_frame, - SINE_TX_POOL_SIZE); + bt_shell_error( + "Cannot send %u length SDU (from frame blocks per sdu %u, channel " + "count %u and %u octets per frame) for pool size %d", + tx_sdu_len, sh_stream->lc3_frame_blocks_per_sdu, + sh_stream->lc3_chan_cnt, sh_stream->lc3_octets_per_frame, + SINE_TX_POOL_SIZE); return; } @@ -487,16 +489,16 @@ static void lc3_audio_send_data(struct shell_stream *sh_stream) err = bt_bap_stream_send(bap_stream, buf, sh_stream->tx.seq_num); if (err < 0) { - shell_error(ctx_shell, "Failed to send LC3 audio data (%d)", err); + bt_shell_error("Failed to send LC3 audio data (%d)", err); net_buf_unref(buf); return; } if ((sh_stream->tx.lc3_sdu_cnt % bap_stats_interval) == 0U) { - shell_info(ctx_shell, "[%zu]: stream %p : TX LC3: %zu (seq_num %u)", - sh_stream->tx.lc3_sdu_cnt, bap_stream, tx_sdu_len, - sh_stream->tx.seq_num); + bt_shell_info("[%zu]: stream %p : TX LC3: %zu (seq_num %u)", + sh_stream->tx.lc3_sdu_cnt, bap_stream, tx_sdu_len, + sh_stream->tx.seq_num); } sh_stream->tx.lc3_sdu_cnt++; @@ -587,7 +589,7 @@ static void set_unicast_stream(struct bt_bap_stream *stream) for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) { if (stream == bap_stream_from_shell_stream(&unicast_streams[i])) { - shell_print(ctx_shell, "Default stream: %u", i + 1); + bt_shell_print("Default stream: %u", i + 1); } } } @@ -639,20 +641,20 @@ static int lc3_config(struct bt_conn *conn, const struct bt_bap_ep *ep, enum bt_ const struct bt_audio_codec_cfg *codec_cfg, struct bt_bap_stream **stream, struct bt_bap_qos_cfg_pref *const pref, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "ASE Codec Config: conn %p ep %p dir %u", conn, ep, dir); + bt_shell_print("ASE Codec Config: conn %p ep %p dir %u", conn, ep, dir); - print_codec_cfg(ctx_shell, 0, codec_cfg); + print_codec_cfg(0, codec_cfg); *stream = stream_alloc(); if (*stream == NULL) { - shell_print(ctx_shell, "No unicast_streams available"); + bt_shell_print("No unicast_streams available"); *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM, BT_BAP_ASCS_REASON_NONE); return -ENOMEM; } - shell_print(ctx_shell, "ASE Codec Config stream %p", *stream); + bt_shell_print("ASE Codec Config stream %p", *stream); set_unicast_stream(*stream); @@ -665,9 +667,9 @@ static int lc3_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir, const struct bt_audio_codec_cfg *codec_cfg, struct bt_bap_qos_cfg_pref *const pref, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "ASE Codec Reconfig: stream %p", stream); + bt_shell_print("ASE Codec Reconfig: stream %p", stream); - print_codec_cfg(ctx_shell, 0, codec_cfg); + print_codec_cfg(0, codec_cfg); if (default_stream == NULL) { set_unicast_stream(stream); @@ -681,9 +683,9 @@ static int lc3_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir, static int lc3_qos(struct bt_bap_stream *stream, const struct bt_bap_qos_cfg *qos, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "QoS: stream %p %p", stream, qos); + bt_shell_print("QoS: stream %p %p", stream, qos); - print_qos(ctx_shell, qos); + print_qos(qos); return 0; } @@ -691,20 +693,18 @@ static int lc3_qos(struct bt_bap_stream *stream, const struct bt_bap_qos_cfg *qo static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "Enable: stream %p meta_len %zu", stream, - meta_len); + bt_shell_print("Enable: stream %p meta_len %zu", stream, meta_len); return 0; } static int lc3_start(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "Start: stream %p", stream); + bt_shell_print("Start: stream %p", stream); return 0; } - static bool meta_data_func_cb(struct bt_data *data, void *user_data) { struct bt_bap_ascs_rsp *rsp = (struct bt_bap_ascs_rsp *)user_data; @@ -721,29 +721,28 @@ static bool meta_data_func_cb(struct bt_data *data, void *user_data) static int lc3_metadata(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "Metadata: stream %p meta_len %zu", stream, - meta_len); + bt_shell_print("Metadata: stream %p meta_len %zu", stream, meta_len); return bt_audio_data_parse(meta, meta_len, meta_data_func_cb, rsp); } static int lc3_disable(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "Disable: stream %p", stream); + bt_shell_print("Disable: stream %p", stream); return 0; } static int lc3_stop(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "Stop: stream %p", stream); + bt_shell_print("Stop: stream %p", stream); return 0; } static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp) { - shell_print(ctx_shell, "Release: stream %p", stream); + bt_shell_print("Release: stream %p", stream); if (stream == default_stream) { default_stream = NULL; @@ -913,10 +912,9 @@ static void print_remote_codec_cap(const struct bt_conn *conn, const struct bt_audio_codec_cap *codec_cap, enum bt_audio_dir dir) { - shell_print(ctx_shell, "conn %p: codec_cap %p dir 0x%02x", conn, codec_cap, - dir); + bt_shell_print("conn %p: codec_cap %p dir 0x%02x", conn, codec_cap, dir); - print_codec_cap(ctx_shell, 0, codec_cap); + print_codec_cap(0, codec_cap); } #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 @@ -926,14 +924,14 @@ static void add_sink(const struct bt_conn *conn, struct bt_bap_ep *ep) for (size_t i = 0U; i < ARRAY_SIZE(snks[conn_index]); i++) { if (snks[conn_index][i] == NULL) { - shell_print(ctx_shell, "Conn: %p, Sink #%zu: ep %p", conn, i, ep); + bt_shell_print("Conn: %p, Sink #%zu: ep %p", conn, i, ep); snks[conn_index][i] = ep; return; } } - shell_error(ctx_shell, "Could not add more sink endpoints"); + bt_shell_error("Could not add more sink endpoints"); } #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */ @@ -944,14 +942,14 @@ static void add_source(const struct bt_conn *conn, struct bt_bap_ep *ep) for (size_t i = 0U; i < ARRAY_SIZE(srcs[conn_index]); i++) { if (srcs[conn_index][i] == NULL) { - shell_print(ctx_shell, "Conn: %p, Source #%zu: ep %p", conn, i, ep); + bt_shell_print("Conn: %p, Source #%zu: ep %p", conn, i, ep); srcs[conn_index][i] = ep; return; } } - shell_error(ctx_shell, "Could not add more sink endpoints"); + bt_shell_error("Could not add more sink endpoints"); } #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */ @@ -978,7 +976,7 @@ static void endpoint_cb(struct bt_conn *conn, enum bt_audio_dir dir, struct bt_b static void discover_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir) { - shell_print(ctx_shell, "Discover complete: err %d", err); + bt_shell_print("Discover complete: err %d", err); } static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir) @@ -990,30 +988,30 @@ static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir) err = bt_bap_unicast_client_discover(default_conn, dir); if (err) { - shell_error(ctx_shell, "bt_bap_unicast_client_discover err %d", err); + bt_shell_error("bt_bap_unicast_client_discover err %d", err); } } } static void unicast_client_location_cb(struct bt_conn *conn, - enum bt_audio_dir dir, - enum bt_audio_location loc) + enum bt_audio_dir dir, + enum bt_audio_location loc) { - shell_print(ctx_shell, "dir %u loc %X\n", dir, loc); + bt_shell_print("dir %u loc %X\n", dir, loc); } static void available_contexts_cb(struct bt_conn *conn, enum bt_audio_context snk_ctx, enum bt_audio_context src_ctx) { - shell_print(ctx_shell, "snk ctx %u src ctx %u\n", snk_ctx, src_ctx); + bt_shell_print("snk ctx %u src ctx %u\n", snk_ctx, src_ctx); } static void config_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code, enum bt_bap_ascs_reason reason) { - shell_print(ctx_shell, "stream %p config operation rsp_code %u reason %u", - stream, rsp_code, reason); + bt_shell_print("stream %p config operation rsp_code %u reason %u", + stream, rsp_code, reason); if (default_stream == NULL) { default_stream = stream; @@ -1023,50 +1021,50 @@ static void config_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rs static void qos_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code, enum bt_bap_ascs_reason reason) { - shell_print(ctx_shell, "stream %p qos operation rsp_code %u reason %u", - stream, rsp_code, reason); + bt_shell_print("stream %p qos operation rsp_code %u reason %u", + stream, rsp_code, reason); } static void enable_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code, enum bt_bap_ascs_reason reason) { - shell_print(ctx_shell, "stream %p enable operation rsp_code %u reason %u", - stream, rsp_code, reason); + bt_shell_print("stream %p enable operation rsp_code %u reason %u", + stream, rsp_code, reason); } static void start_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code, enum bt_bap_ascs_reason reason) { - shell_print(ctx_shell, "stream %p start operation rsp_code %u reason %u", - stream, rsp_code, reason); + bt_shell_print("stream %p start operation rsp_code %u reason %u", + stream, rsp_code, reason); } static void stop_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code, enum bt_bap_ascs_reason reason) { - shell_print(ctx_shell, "stream %p stop operation rsp_code %u reason %u", - stream, rsp_code, reason); + bt_shell_print("stream %p stop operation rsp_code %u reason %u", + stream, rsp_code, reason); } static void disable_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code, enum bt_bap_ascs_reason reason) { - shell_print(ctx_shell, "stream %p disable operation rsp_code %u reason %u", - stream, rsp_code, reason); + bt_shell_print("stream %p disable operation rsp_code %u reason %u", + stream, rsp_code, reason); } static void metadata_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code, enum bt_bap_ascs_reason reason) { - shell_print(ctx_shell, "stream %p metadata operation rsp_code %u reason %u", - stream, rsp_code, reason); + bt_shell_print("stream %p metadata operation rsp_code %u reason %u", + stream, rsp_code, reason); } static void release_cb(struct bt_bap_stream *stream, enum bt_bap_ascs_rsp_code rsp_code, enum bt_bap_ascs_reason reason) { - shell_print(ctx_shell, "stream %p release operation rsp_code %u reason %u", - stream, rsp_code, reason); + bt_shell_print("stream %p release operation rsp_code %u reason %u", + stream, rsp_code, reason); } static struct bt_bap_unicast_client_cb unicast_client_cbs = { @@ -2337,8 +2335,8 @@ static int cmd_preset(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "%s", named_preset->name); - print_codec_cfg(ctx_shell, 0, &named_preset->preset.codec_cfg); - print_qos(ctx_shell, &named_preset->preset.qos); + print_codec_cfg(0, &named_preset->preset.codec_cfg); + print_qos(&named_preset->preset.qos); return 0; } @@ -2454,8 +2452,8 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct auto_scan.broadcast_info.broadcast_id = sr_info.broadcast_id; identified_broadcast = true; - shell_print(ctx_shell, "Found matched broadcast name '%s' with address %s", - sr_info.broadcast_name, addr_str); + bt_shell_print("Found matched broadcast name '%s' with address %s", + sr_info.broadcast_name, addr_str); } if (identified_broadcast && (auto_scan.broadcast_sink != NULL) && @@ -2463,13 +2461,13 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct struct bt_le_per_adv_sync_param create_params = {0}; int err; - shell_print(ctx_shell, - "Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X ", - sr_info.broadcast_id, addr_str, info->sid); + bt_shell_print( + "Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X ", + sr_info.broadcast_id, addr_str, info->sid); err = bt_le_scan_stop(); if (err != 0) { - shell_error(ctx_shell, "Could not stop scan: %d", err); + bt_shell_error("Could not stop scan: %d", err); } bt_addr_le_copy(&create_params.addr, info->addr); @@ -2478,10 +2476,10 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct create_params.skip = PA_SYNC_SKIP; create_params.timeout = interval_to_sync_timeout(info->interval); - shell_print(ctx_shell, "Attempting to PA sync to the broadcaster"); + bt_shell_print("Attempting to PA sync to the broadcaster"); err = bt_le_per_adv_sync_create(&create_params, auto_scan.out_sync); if (err != 0) { - shell_error(ctx_shell, "Could not create Broadcast PA sync: %d", err); + bt_shell_error("Could not create Broadcast PA sync: %d", err); } else { auto_scan.broadcast_sink->pa_sync = *auto_scan.out_sync; } @@ -2494,7 +2492,7 @@ static void base_recv(struct bt_bap_broadcast_sink *sink, const struct bt_bap_ba /* Don't print duplicates */ if (base_size != default_broadcast_sink.base_size || memcmp(base, &default_broadcast_sink.received_base, base_size) != 0) { - shell_print(ctx_shell, "Received BASE from sink %p:", sink); + bt_shell_print("Received BASE from sink %p:", sink); (void)memcpy(&default_broadcast_sink.received_base, base, base_size); default_broadcast_sink.base_size = base_size; @@ -2509,8 +2507,8 @@ static void syncable(struct bt_bap_broadcast_sink *sink, const struct bt_iso_big return; } - shell_print(ctx_shell, "Sink %p is ready to sync %s encryption", sink, - biginfo->encryption ? "with" : "without"); + bt_shell_print("Sink %p is ready to sync %s encryption", sink, + biginfo->encryption ? "with" : "without"); default_broadcast_sink.syncable = true; } } @@ -2520,21 +2518,21 @@ static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync, { if (auto_scan.broadcast_sink != NULL && auto_scan.out_sync != NULL && sync == *auto_scan.out_sync) { - shell_print(ctx_shell, "PA synced to broadcast with broadcast ID 0x%06x", - auto_scan.broadcast_info.broadcast_id); + bt_shell_print("PA synced to broadcast with broadcast ID 0x%06x", + auto_scan.broadcast_info.broadcast_id); if (auto_scan.broadcast_sink->bap_sink == NULL) { - shell_print(ctx_shell, "Attempting to create the sink"); + bt_shell_print("Attempting to create the sink"); int err; err = bt_bap_broadcast_sink_create(sync, auto_scan.broadcast_info.broadcast_id, &auto_scan.broadcast_sink->bap_sink); if (err != 0) { - shell_error(ctx_shell, "Could not create broadcast sink: %d", err); + bt_shell_error("Could not create broadcast sink: %d", err); } } else { - shell_print(ctx_shell, "Sink is already created"); + bt_shell_print("Sink is already created"); } } @@ -2555,7 +2553,7 @@ static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync, static void broadcast_scan_timeout_cb(void) { - shell_print(ctx_shell, "Scan timeout"); + bt_shell_print("Scan timeout"); clear_auto_scan(); } @@ -2609,37 +2607,36 @@ static struct shell_stream *usb_right_stream; static int init_lc3_decoder(struct shell_stream *sh_stream) { if (sh_stream == NULL) { - shell_error(ctx_shell, "NULL stream to init LC3 decoder"); + bt_shell_error("NULL stream to init LC3 decoder"); return -EINVAL; } if (!sh_stream->is_rx) { - shell_error(ctx_shell, "Invalid stream to init LC3 decoder"); + bt_shell_error("Invalid stream to init LC3 decoder"); return -EINVAL; } if (sh_stream->rx.lc3_decoder != NULL) { - shell_error(ctx_shell, "Already initialized"); + bt_shell_error("Already initialized"); return -EALREADY; } if (sh_stream->lc3_freq_hz == 0 || sh_stream->lc3_frame_duration_us == 0) { - shell_error(ctx_shell, "Invalid freq (%u) or frame duration (%u)", - sh_stream->lc3_freq_hz, sh_stream->lc3_frame_duration_us); + bt_shell_error("Invalid freq (%u) or frame duration (%u)", + sh_stream->lc3_freq_hz, sh_stream->lc3_frame_duration_us); return -EINVAL; } - shell_print(ctx_shell, - "Initializing the LC3 decoder with %u us duration and %u Hz frequency", - sh_stream->lc3_frame_duration_us, sh_stream->lc3_freq_hz); + bt_shell_print("Initializing the LC3 decoder with %u us duration and %u Hz frequency", + sh_stream->lc3_frame_duration_us, sh_stream->lc3_freq_hz); /* Create the decoder instance. This shall complete before stream_started() is called. */ sh_stream->rx.lc3_decoder = lc3_setup_decoder(sh_stream->lc3_frame_duration_us, sh_stream->lc3_freq_hz, IS_ENABLED(CONFIG_USB_DEVICE_AUDIO) ? USB_SAMPLE_RATE : 0, &sh_stream->rx.lc3_decoder_mem); if (sh_stream->rx.lc3_decoder == NULL) { - shell_error(ctx_shell, "Failed to setup LC3 decoder - wrong parameters?\n"); + bt_shell_error("Failed to setup LC3 decoder - wrong parameters?\n"); return -EINVAL; } @@ -2659,7 +2656,7 @@ static bool decode_frame(struct lc3_data *data, size_t frame_cnt) iso_data = NULL; /* perform PLC */ if ((sh_stream->rx.decoded_cnt % bap_stats_interval) == 0) { - shell_print(ctx_shell, "[%zu]: Performing PLC", sh_stream->rx.decoded_cnt); + bt_shell_print("[%zu]: Performing PLC", sh_stream->rx.decoded_cnt); } data->do_plc = false; /* clear flag */ @@ -2667,17 +2664,17 @@ static bool decode_frame(struct lc3_data *data, size_t frame_cnt) iso_data = net_buf_pull_mem(data->buf, octets_per_frame); if ((sh_stream->rx.decoded_cnt % bap_stats_interval) == 0) { - shell_print(ctx_shell, "[%zu]: Decoding frame of size %u (%u/%u)", - sh_stream->rx.decoded_cnt, octets_per_frame, frame_cnt + 1, - total_frames); + bt_shell_print("[%zu]: Decoding frame of size %u (%u/%u)", + sh_stream->rx.decoded_cnt, octets_per_frame, frame_cnt + 1, + total_frames); } } err = lc3_decode(sh_stream->rx.lc3_decoder, iso_data, octets_per_frame, LC3_PCM_FORMAT_S16, lc3_rx_buf, 1); if (err < 0) { - shell_error(ctx_shell, "Failed to decode LC3 data (%u/%u - %u/%u)", frame_cnt + 1, - total_frames, octets_per_frame * frame_cnt, buf->len); + bt_shell_error("Failed to decode LC3 data (%u/%u - %u/%u)", frame_cnt + 1, + total_frames, octets_per_frame * frame_cnt, buf->len); return false; } @@ -2768,7 +2765,7 @@ static void lc3_decoder_thread_func(void *arg1, void *arg2, void *arg3) struct shell_stream *sh_stream = data->sh_stream; if (sh_stream->is_rx && sh_stream->rx.lc3_decoder == NULL) { - shell_warn(ctx_shell, "Decoder is NULL, discarding data from FIFO"); + bt_shell_warn("Decoder is NULL, discarding data from FIFO"); k_mem_slab_free(&lc3_data_slab, (void *)data); continue; /* Wait for new data */ } @@ -2818,14 +2815,14 @@ static void audio_recv(struct bt_bap_stream *stream, } if ((sh_stream->rx.rx_cnt % bap_stats_interval) == 0) { - shell_print(ctx_shell, - "[%zu]: Incoming audio on stream %p len %u ts %u seq_num %u flags %u " - "(valid %zu, dup ts %zu, dup psn %zu, err_pkts %zu, lost_pkts %zu, " - "empty SDUs %zu)", - sh_stream->rx.rx_cnt, stream, buf->len, info->ts, info->seq_num, - info->flags, sh_stream->rx.valid_sdu_pkts, sh_stream->rx.dup_ts, - sh_stream->rx.dup_psn, sh_stream->rx.err_pkts, sh_stream->rx.lost_pkts, - sh_stream->rx.empty_sdu_pkts); + bt_shell_print( + "[%zu]: Incoming audio on stream %p len %u ts %u seq_num %u flags %u " + "(valid %zu, dup ts %zu, dup psn %zu, err_pkts %zu, lost_pkts %zu, " + "empty SDUs %zu)", + sh_stream->rx.rx_cnt, stream, buf->len, info->ts, info->seq_num, + info->flags, sh_stream->rx.valid_sdu_pkts, sh_stream->rx.dup_ts, + sh_stream->rx.dup_psn, sh_stream->rx.err_pkts, sh_stream->rx.lost_pkts, + sh_stream->rx.empty_sdu_pkts); } (void)memcpy(&sh_stream->rx.last_info, info, sizeof(sh_stream->rx.last_info)); @@ -2842,7 +2839,7 @@ static void audio_recv(struct bt_bap_stream *stream, * in a FIFO */ if (k_mem_slab_alloc(&lc3_data_slab, (void **)&data, K_NO_WAIT)) { - shell_warn(ctx_shell, "Could not allocate LC3 data item"); + bt_shell_warn("Could not allocate LC3 data item"); return; } @@ -2851,8 +2848,7 @@ static void audio_recv(struct bt_bap_stream *stream, data->do_plc = true; } else if (buf->len != (octets_per_frame * chan_cnt * frame_blocks_per_sdu)) { if (buf->len != 0U) { - shell_error( - ctx_shell, + bt_shell_error( "Expected %u frame blocks with %u channels of size %u, but " "length is %u", frame_blocks_per_sdu, chan_cnt, octets_per_frame, buf->len); @@ -2878,7 +2874,7 @@ static void audio_recv(struct bt_bap_stream *stream, #if defined(CONFIG_BT_BAP_UNICAST) static void stream_enabled_cb(struct bt_bap_stream *stream) { - shell_print(ctx_shell, "Stream %p enabled", stream); + bt_shell_print("Stream %p enabled", stream); if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER)) { struct bt_bap_ep_info ep_info; @@ -2887,7 +2883,7 @@ static void stream_enabled_cb(struct bt_bap_stream *stream) err = bt_conn_get_info(stream->conn, &conn_info); if (err != 0) { - shell_error(ctx_shell, "Failed to get conn info: %d", err); + bt_shell_error("Failed to get conn info: %d", err); return; } @@ -2897,7 +2893,7 @@ static void stream_enabled_cb(struct bt_bap_stream *stream) err = bt_bap_ep_get_info(stream->ep, &ep_info); if (err != 0) { - shell_error(ctx_shell, "Failed to get ep info: %d", err); + bt_shell_error("Failed to get ep info: %d", err); return; } @@ -2906,7 +2902,7 @@ static void stream_enabled_cb(struct bt_bap_stream *stream) err = bt_bap_stream_start(stream); if (err != 0) { - shell_error(ctx_shell, "Failed to start stream: %d", err); + bt_shell_error("Failed to start stream: %d", err); return; } } @@ -2924,7 +2920,7 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) ret = bt_bap_ep_get_info(bap_stream->ep, &info); if (ret != 0) { - shell_error(ctx_shell, "Failed to get EP info: %d", ret); + bt_shell_error("Failed to get EP info: %d", ret); return; } @@ -2949,16 +2945,15 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) ret == 48000) { sh_stream->lc3_freq_hz = (uint32_t)ret; } else { - shell_error(ctx_shell, "Unsupported frequency for LC3: %d", - ret); + bt_shell_error("Unsupported frequency for LC3: %d", ret); sh_stream->lc3_freq_hz = 0U; } } else { - shell_error(ctx_shell, "Invalid frequency: %d", ret); + bt_shell_error("Invalid frequency: %d", ret); sh_stream->lc3_freq_hz = 0U; } } else { - shell_error(ctx_shell, "Could not get frequency: %d", ret); + bt_shell_error("Could not get frequency: %d", ret); sh_stream->lc3_freq_hz = 0U; } @@ -2968,11 +2963,11 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) if (ret > 0) { sh_stream->lc3_frame_duration_us = (uint32_t)ret; } else { - shell_error(ctx_shell, "Invalid frame duration: %d", ret); + bt_shell_error("Invalid frame duration: %d", ret); sh_stream->lc3_frame_duration_us = 0U; } } else { - shell_error(ctx_shell, "Could not get frame duration: %d", ret); + bt_shell_error("Could not get frame duration: %d", ret); sh_stream->lc3_frame_duration_us = 0U; } @@ -2982,7 +2977,7 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) sh_stream->lc3_chan_cnt = bt_audio_get_chan_count(sh_stream->lc3_chan_allocation); } else { - shell_error(ctx_shell, "Could not get channel allocation: %d", ret); + bt_shell_error("Could not get channel allocation: %d", ret); sh_stream->lc3_chan_allocation = BT_AUDIO_LOCATION_MONO_AUDIO; sh_stream->lc3_chan_cnt = 1U; } @@ -2991,7 +2986,7 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) if (ret >= 0) { sh_stream->lc3_frame_blocks_per_sdu = (uint8_t)ret; } else { - shell_error(ctx_shell, "Could not get frame blocks per SDU: %d", ret); + bt_shell_error("Could not get frame blocks per SDU: %d", ret); sh_stream->lc3_frame_blocks_per_sdu = 0U; } @@ -2999,7 +2994,7 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) if (ret >= 0) { sh_stream->lc3_octets_per_frame = (uint16_t)ret; } else { - shell_error(ctx_shell, "Could not get octets per frame: %d", ret); + bt_shell_error("Could not get octets per frame: %d", ret); sh_stream->lc3_octets_per_frame = 0U; } @@ -3008,7 +3003,7 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) const int err = init_lc3_encoder(sh_stream); if (err != 0) { - shell_error(ctx_shell, "Failed to init LC3 encoder: %d", err); + bt_shell_error("Failed to init LC3 encoder: %d", err); return; } @@ -3026,8 +3021,7 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) const int err = init_lc3_decoder(sh_stream); if (err != 0) { - shell_error(ctx_shell, "Failed to init LC3 decoder: %d", - err); + bt_shell_error("Failed to init LC3 decoder: %d", err); return; } @@ -3039,26 +3033,22 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream) if ((sh_stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0) { if (usb_left_stream == NULL) { - shell_info(ctx_shell, - "Setting USB left stream to %p", - sh_stream); + bt_shell_info("Setting USB left stream to %p", + sh_stream); usb_left_stream = sh_stream; } else { - shell_warn(ctx_shell, - "Multiple left streams started"); + bt_shell_warn("Multiple left streams started"); } } if ((sh_stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0) { if (usb_right_stream == NULL) { - shell_info(ctx_shell, - "Setting USB right stream to %p", - sh_stream); + bt_shell_info("Setting USB right stream to %p", + sh_stream); usb_right_stream = sh_stream; } else { - shell_warn(ctx_shell, - "Multiple right streams started"); + bt_shell_warn("Multiple right streams started"); } } } @@ -3094,13 +3084,13 @@ static void update_usb_streams_cb(struct shell_stream *sh_stream, void *user_dat if (sh_stream->is_rx) { if (usb_left_stream == NULL && (sh_stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0) { - shell_info(ctx_shell, "Setting new USB left stream to %p", sh_stream); + bt_shell_info("Setting new USB left stream to %p", sh_stream); usb_left_stream = sh_stream; } if (usb_right_stream == NULL && (sh_stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0) { - shell_info(ctx_shell, "Setting new USB right stream to %p", sh_stream); + bt_shell_info("Setting new USB right stream to %p", sh_stream); usb_right_stream = sh_stream; } } @@ -3110,12 +3100,12 @@ static void update_usb_streams(struct shell_stream *sh_stream) { if (sh_stream->is_rx) { if (sh_stream == usb_left_stream) { - shell_info(ctx_shell, "Clearing USB left stream (%p)", usb_left_stream); + bt_shell_info("Clearing USB left stream (%p)", usb_left_stream); usb_left_stream = NULL; } if (sh_stream == usb_right_stream) { - shell_info(ctx_shell, "Clearing USB right stream (%p)", usb_right_stream); + bt_shell_info("Clearing USB right stream (%p)", usb_right_stream); usb_right_stream = NULL; } @@ -3177,14 +3167,14 @@ static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason) static void stream_configured_cb(struct bt_bap_stream *stream, const struct bt_bap_qos_cfg_pref *pref) { - shell_print(ctx_shell, "Stream %p configured\n", stream); + bt_shell_print("Stream %p configured\n", stream); } static void stream_released_cb(struct bt_bap_stream *stream) { struct shell_stream *sh_stream = shell_stream_from_bap_stream(stream); - shell_print(ctx_shell, "Stream %p released\n", stream); + bt_shell_print("Stream %p released\n", stream); #if defined(CONFIG_BT_BAP_UNICAST_CLIENT) if (default_unicast_group != NULL) { @@ -3210,12 +3200,12 @@ static void stream_released_cb(struct bt_bap_stream *stream) if (group_can_be_deleted) { int err; - shell_print(ctx_shell, "All streams released, deleting group\n"); + bt_shell_print("All streams released, deleting group\n"); err = bt_bap_unicast_group_delete(default_unicast_group); if (err != 0) { - shell_error(ctx_shell, "Failed to delete unicast group: %d", err); + bt_shell_error("Failed to delete unicast group: %d", err); } else { default_unicast_group = NULL; } @@ -3694,7 +3684,7 @@ static int cmd_set_loc(const struct shell *sh, size_t argc, char *argv[]) err = bt_pacs_set_location(dir, loc); if (err) { - shell_error(ctx_shell, "Set available contexts err %d", err); + shell_error(sh, "Set available contexts err %d", err); return -ENOEXEC; } @@ -3741,13 +3731,13 @@ static int cmd_context(const struct shell *sh, size_t argc, char *argv[]) err = bt_pacs_set_supported_contexts(dir, ctx); if (err) { - shell_error(ctx_shell, "Set supported contexts err %d", err); + shell_error(sh, "Set supported contexts err %d", err); return err; } } else if (!strcmp(argv[3], "available")) { err = bt_pacs_set_available_contexts(dir, ctx); if (err) { - shell_error(ctx_shell, "Set available contexts err %d", err); + shell_error(sh, "Set available contexts err %d", err); return err; } } else { @@ -3762,8 +3752,6 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[]) { int err, i; - ctx_shell = sh; - if (initialized) { shell_print(sh, "Already initialized"); return -ENOEXEC; @@ -3782,7 +3770,20 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[]) CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT }; - + const struct bt_pacs_register_param pacs_param = { +#if defined(CONFIG_BT_PAC_SNK) + .snk_pac = true, +#endif /* CONFIG_BT_PAC_SNK */ +#if defined(CONFIG_BT_PAC_SNK_LOC) + .snk_loc = true, +#endif /* CONFIG_BT_PAC_SNK_LOC */ +#if defined(CONFIG_BT_PAC_SRC) + .src_pac = true, +#endif /* CONFIG_BT_PAC_SRC */ +#if defined(CONFIG_BT_PAC_SRC_LOC) + .src_loc = true, +#endif /* CONFIG_BT_PAC_SRC_LOC */ + }; if (argc == 3) { snk_cnt = shell_strtoul(argv[1], 0, &err); @@ -3809,8 +3810,14 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[]) src_cnt = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT; } - bt_bap_unicast_server_register(&unicast_server_param); - bt_bap_unicast_server_register_cb(&unicast_server_cb); + err = bt_pacs_register(&pacs_param); + __ASSERT(err == 0, "Failed to register PACS: %d", err); + + err = bt_bap_unicast_server_register(&unicast_server_param); + __ASSERT(err == 0, "Failed to register Unicast Server: %d", err); + + err = bt_bap_unicast_server_register_cb(&unicast_server_cb); + __ASSERT(err == 0, "Failed to register Unicast Server Callbacks: %d", err); #endif /* CONFIG_BT_BAP_UNICAST_SERVER */ #if defined(CONFIG_BT_PAC_SNK) @@ -4124,7 +4131,7 @@ static int cmd_print_ase_info(const struct shell *sh, size_t argc, char *argv[]) #define HELP_CFG_META \ "\n[meta" HELP_SEP "[pref_ctx ]" HELP_SEP "[stream_ctx ]" HELP_SEP \ - "[program_info ]" HELP_SEP "[lang ]" HELP_SEP \ + "[program_info ]" HELP_SEP "[lang ]" HELP_SEP \ "[ccid_list ]" HELP_SEP "[parental_rating ]" HELP_SEP \ "[program_info_uri ]" HELP_SEP "[audio_active_state ]" HELP_SEP \ "[bcast_flag]" HELP_SEP "[extended ]" HELP_SEP "[vendor ]]" @@ -4217,8 +4224,7 @@ static int cmd_bap(const struct shell *sh, size_t argc, char **argv) SHELL_CMD_ARG_REGISTER(bap, &bap_cmds, "Bluetooth BAP shell commands", cmd_bap, 1, 1); -static ssize_t connectable_ad_data_add(struct bt_data *data_array, - size_t data_array_size) +static size_t connectable_ad_data_add(struct bt_data *data_array, size_t data_array_size) { static const uint8_t ad_ext_uuid16[] = { IF_ENABLED(CONFIG_BT_MICP_MIC_DEV, (BT_UUID_16_ENCODE(BT_UUID_MICS_VAL),)) @@ -4273,7 +4279,7 @@ static ssize_t connectable_ad_data_add(struct bt_data *data_array, size_t uuid16_size; if (data_array_size <= ad_len) { - shell_warn(ctx_shell, "No space for AD_UUID16"); + bt_shell_warn("No space for AD_UUID16"); return ad_len; } @@ -4300,8 +4306,7 @@ static ssize_t connectable_ad_data_add(struct bt_data *data_array, return ad_len; } -static ssize_t nonconnectable_ad_data_add(struct bt_data *data_array, - const size_t data_array_size) +static size_t nonconnectable_ad_data_add(struct bt_data *data_array, const size_t data_array_size) { static const uint8_t ad_ext_uuid16[] = { IF_ENABLED(CONFIG_BT_PACS, (BT_UUID_16_ENCODE(BT_UUID_PACS_VAL),)) @@ -4332,9 +4337,9 @@ static ssize_t nonconnectable_ad_data_add(struct bt_data *data_array, err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE); if (err != 0) { - printk("Unable to generate broadcast ID: %d\n", err); + bt_shell_error("Unable to generate broadcast ID: %d\n", err); - return -1; + return 0; } sys_put_le24(broadcast_id, &ad_bap_broadcast_announcement[2]); @@ -4347,7 +4352,7 @@ static ssize_t nonconnectable_ad_data_add(struct bt_data *data_array, if (ARRAY_SIZE(ad_ext_uuid16) > 0) { if (data_array_size <= ad_len) { - shell_warn(ctx_shell, "No space for AD_UUID16"); + bt_shell_warn("No space for AD_UUID16"); return ad_len; } @@ -4360,10 +4365,10 @@ static ssize_t nonconnectable_ad_data_add(struct bt_data *data_array, return ad_len; } -ssize_t audio_ad_data_add(struct bt_data *data_array, const size_t data_array_size, - const bool discoverable, const bool connectable) +size_t audio_ad_data_add(struct bt_data *data_array, const size_t data_array_size, + const bool discoverable, const bool connectable) { - ssize_t ad_len = 0; + size_t ad_len = 0; if (!discoverable) { return 0; @@ -4383,8 +4388,7 @@ ssize_t audio_ad_data_add(struct bt_data *data_array, const size_t data_array_si return ad_len; } -ssize_t audio_pa_data_add(struct bt_data *data_array, - const size_t data_array_size) +size_t audio_pa_data_add(struct bt_data *data_array, const size_t data_array_size) { size_t ad_len = 0; @@ -4400,9 +4404,9 @@ ssize_t audio_pa_data_add(struct bt_data *data_array, err = bt_bap_broadcast_source_get_base(default_source.bap_source, &base_buf); if (err != 0) { - printk("Unable to get BASE: %d\n", err); + bt_shell_error("Unable to get BASE: %d\n", err); - return -1; + return 0; } data_array[ad_len].type = BT_DATA_SVC_DATA16; diff --git a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c index d492330b5ead8..716d2d9bc8dbc 100644 --- a/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c +++ b/subsys/bluetooth/audio/shell/bap_broadcast_assistant.c @@ -32,8 +32,9 @@ #include #include +#include "common/bt_shell_private.h" #include "host/shell/bt.h" -#include "../../host/hci_core.h" +#include "host/hci_core.h" #include "audio.h" static uint8_t received_base[UINT8_MAX]; @@ -65,7 +66,7 @@ static bool pa_decode_base(struct bt_data *data, void *user_data) base_size = bt_bap_base_get_size(base); if (base_size < 0) { - shell_error(ctx_shell, "BASE get size failed (%d)", base_size); + bt_shell_error("BASE get size failed (%d)", base_size); return true; } @@ -93,12 +94,10 @@ static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err, uint8_t recv_state_count) { if (err != 0) { - shell_error(ctx_shell, "BASS discover failed (%d)", err); + bt_shell_error("BASS discover failed (%d)", err); } else { - shell_print(ctx_shell, "BASS discover done with %u recv states", - recv_state_count); + bt_shell_print("BASS discover done with %u recv states", recv_state_count); } - } static void bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info *info, @@ -107,8 +106,7 @@ static void bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info *i char le_addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); - shell_print( - ctx_shell, + bt_shell_print( "[DEVICE]: %s, broadcast_id 0x%06X, interval (ms) %u (0x%04x)), SID 0x%x, RSSI %i", le_addr, broadcast_id, BT_GAP_PER_ADV_INTERVAL_TO_MS(info->interval), info->interval, info->sid, info->rssi); @@ -120,8 +118,8 @@ static bool metadata_entry(struct bt_data *data, void *user_data) bin2hex(data->data, data->data_len, metadata, sizeof(metadata)); - shell_print(ctx_shell, "\t\tMetadata length %u, type %u, data: %s", - data->data_len, data->type, metadata); + bt_shell_print("\t\tMetadata length %u, type %u, data: %s", + data->data_len, data->type, metadata); return true; } @@ -135,7 +133,7 @@ static void bap_broadcast_assistant_recv_state_cb( bool is_bad_code; if (err != 0) { - shell_error(ctx_shell, "BASS recv state read failed (%d)", err); + bt_shell_error("BASS recv state read failed (%d)", err); return; } @@ -143,26 +141,25 @@ static void bap_broadcast_assistant_recv_state_cb( bin2hex(state->bad_code, BT_ISO_BROADCAST_CODE_SIZE, bad_code, sizeof(bad_code)); is_bad_code = state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE; - shell_print(ctx_shell, - "BASS recv state: src_id %u, addr %s, sid %u, broadcast_id 0x%06X, sync_state " - "%u, encrypt_state %u%s%s", - state->src_id, le_addr, state->adv_sid, state->broadcast_id, - state->pa_sync_state, state->encrypt_state, is_bad_code ? ", bad code" : "", - is_bad_code ? bad_code : ""); + bt_shell_print( + "BASS recv state: src_id %u, addr %s, sid %u, broadcast_id 0x%06X, sync_state " + "%u, encrypt_state %u%s%s", + state->src_id, le_addr, state->adv_sid, state->broadcast_id, + state->pa_sync_state, state->encrypt_state, is_bad_code ? ", bad code" : "", + is_bad_code ? bad_code : ""); for (int i = 0; i < state->num_subgroups; i++) { const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i]; struct net_buf_simple buf; - shell_print(ctx_shell, "\t[%d]: BIS sync 0x%04X, metadata_len %zu", i, - subgroup->bis_sync, subgroup->metadata_len); + bt_shell_print("\t[%d]: BIS sync 0x%04X, metadata_len %zu", i, + subgroup->bis_sync, subgroup->metadata_len); net_buf_simple_init_with_data(&buf, (void *)subgroup->metadata, subgroup->metadata_len); bt_data_parse(&buf, metadata_entry, NULL); } - if (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) { struct bt_le_per_adv_sync *per_adv_sync = NULL; struct bt_le_ext_adv *ext_adv = NULL; @@ -172,21 +169,20 @@ static void bap_broadcast_assistant_recv_state_cb( if (per_adv_syncs[i] != NULL && bt_addr_le_eq(&per_adv_syncs[i]->addr, &state->addr)) { per_adv_sync = per_adv_syncs[i]; - shell_print(ctx_shell, "Found matching PA sync [%zu]", i); + bt_shell_print("Found matching PA sync [%zu]", i); break; } } if (per_adv_sync && IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)) { - shell_print(ctx_shell, "Sending PAST"); + bt_shell_print("Sending PAST"); err = bt_le_per_adv_sync_transfer(per_adv_sync, conn, BT_UUID_BASS_VAL); if (err != 0) { - shell_error(ctx_shell, "Could not transfer periodic adv sync: %d", - err); + bt_shell_error("Could not transfer periodic adv sync: %d", err); } return; @@ -204,9 +200,7 @@ static void bap_broadcast_assistant_recv_state_cb( &oob_local); if (err != 0) { - shell_error(ctx_shell, - "Could not get local OOB %d", - err); + bt_shell_error("Could not get local OOB %d", err); return; } @@ -218,61 +212,58 @@ static void bap_broadcast_assistant_recv_state_cb( if (ext_adv != NULL && IS_ENABLED(CONFIG_BT_PER_ADV) && IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)) { - shell_print(ctx_shell, "Sending local PAST"); + bt_shell_print("Sending local PAST"); err = bt_le_per_adv_set_info_transfer(ext_adv, conn, BT_UUID_BASS_VAL); if (err != 0) { - shell_error(ctx_shell, - "Could not transfer per adv set info: %d", - err); + bt_shell_error("Could not transfer per adv set info: %d", err); } } else { - shell_error(ctx_shell, - "Could not send PA to Scan Delegator"); + bt_shell_error("Could not send PA to Scan Delegator"); } } } static void bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn *conn, uint8_t src_id) { - shell_print(ctx_shell, "BASS recv state %u removed", src_id); + bt_shell_print("BASS recv state %u removed", src_id); } static void bap_broadcast_assistant_scan_start_cb(struct bt_conn *conn, int err) { if (err != 0) { - shell_error(ctx_shell, "BASS scan start failed (%d)", err); + bt_shell_error("BASS scan start failed (%d)", err); } else { - shell_print(ctx_shell, "BASS scan start successful"); + bt_shell_print("BASS scan start successful"); } } static void bap_broadcast_assistant_scan_stop_cb(struct bt_conn *conn, int err) { if (err != 0) { - shell_error(ctx_shell, "BASS scan stop failed (%d)", err); + bt_shell_error("BASS scan stop failed (%d)", err); } else { - shell_print(ctx_shell, "BASS scan stop successful"); + bt_shell_print("BASS scan stop successful"); } } static void bap_broadcast_assistant_add_src_cb(struct bt_conn *conn, int err) { if (err != 0) { - shell_error(ctx_shell, "BASS add source failed (%d)", err); + bt_shell_error("BASS add source failed (%d)", err); } else { - shell_print(ctx_shell, "BASS add source successful"); + bt_shell_print("BASS add source successful"); } } static void bap_broadcast_assistant_mod_src_cb(struct bt_conn *conn, int err) { if (err != 0) { - shell_error(ctx_shell, "BASS modify source failed (%d)", err); + bt_shell_error("BASS modify source failed (%d)", err); } else { - shell_print(ctx_shell, "BASS modify source successful"); + bt_shell_print("BASS modify source successful"); } } @@ -280,18 +271,18 @@ static void bap_broadcast_assistant_broadcast_code_cb(struct bt_conn *conn, int err) { if (err != 0) { - shell_error(ctx_shell, "BASS broadcast code failed (%d)", err); + bt_shell_error("BASS broadcast code failed (%d)", err); } else { - shell_print(ctx_shell, "BASS broadcast code successful"); + bt_shell_print("BASS broadcast code successful"); } } static void bap_broadcast_assistant_rem_src_cb(struct bt_conn *conn, int err) { if (err != 0) { - shell_error(ctx_shell, "BASS remove source failed (%d)", err); + bt_shell_error("BASS remove source failed (%d)", err); } else { - shell_print(ctx_shell, "BASS remove source successful"); + bt_shell_print("BASS remove source successful"); } } @@ -551,18 +542,18 @@ static void scan_recv_cb(const struct bt_le_scan_recv_info *info, is_substring(auto_scan.broadcast_name, sr_info.broadcast_name)) { identified_broadcast = true; - shell_print(ctx_shell, "Found matched broadcast name '%s' with address %s", - sr_info.broadcast_name, addr_str); + bt_shell_print("Found matched broadcast name '%s' with address %s", + sr_info.broadcast_name, addr_str); } if (identified_broadcast) { - shell_print(ctx_shell, - "Found BAP broadcast source with address %s and ID 0x%06X\n", - addr_str, sr_info.broadcast_id); + bt_shell_print( + "Found BAP broadcast source with address %s and ID 0x%06X\n", + addr_str, sr_info.broadcast_id); err = bt_le_scan_stop(); if (err) { - shell_error(ctx_shell, "Failed to stop scan: %d", err); + bt_shell_error("Failed to stop scan: %d", err); } bt_addr_le_copy(¶m.addr, info->addr); @@ -575,7 +566,7 @@ static void scan_recv_cb(const struct bt_le_scan_recv_info *info, err = bt_bap_broadcast_assistant_add_src(default_conn, ¶m); if (err) { - shell_print(ctx_shell, "Failed to add source: %d", err); + bt_shell_print("Failed to add source: %d", err); } memset(&auto_scan, 0, sizeof(auto_scan)); @@ -586,7 +577,7 @@ static void scan_recv_cb(const struct bt_le_scan_recv_info *info, static void scan_timeout_cb(void) { - shell_print(ctx_shell, "Scan timeout"); + bt_shell_print("Scan timeout"); memset(&auto_scan, 0, sizeof(auto_scan)); auto_scan.broadcast_id = BT_BAP_INVALID_BROADCAST_ID; @@ -891,8 +882,8 @@ static inline bool add_pa_sync_base_subgroup_cb(const struct bt_bap_base_subgrou int ret; if (param->num_subgroups == CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) { - shell_warn(ctx_shell, "Cannot fit all subgroups param with size %d", - CONFIG_BT_BAP_BASS_MAX_SUBGROUPS); + bt_shell_warn("Cannot fit all subgroups param with size %d", + CONFIG_BT_BAP_BASS_MAX_SUBGROUPS); return true; /* return true to avoid returning -ECANCELED as this is OK */ } @@ -905,8 +896,8 @@ static inline bool add_pa_sync_base_subgroup_cb(const struct bt_bap_base_subgrou subgroup_param = ¶m->subgroups[param->num_subgroups]; if (ret > ARRAY_SIZE(subgroup_param->metadata)) { - shell_info(ctx_shell, "Cannot fit %d octets into subgroup param with size %zu", ret, - ARRAY_SIZE(subgroup_param->metadata)); + bt_shell_info("Cannot fit %d octets into subgroup param with size %zu", ret, + ARRAY_SIZE(subgroup_param->metadata)); return false; } @@ -1001,7 +992,7 @@ static int cmd_bap_broadcast_assistant_add_pa_sync(const struct shell *sh, err = bt_bap_base_foreach_subgroup((const struct bt_bap_base *)received_base, add_pa_sync_base_subgroup_cb, ¶m); if (err < 0) { - shell_error(ctx_shell, "Could not add BASE to params %d", err); + shell_error(sh, "Could not add BASE to params %d", err); return -ENOEXEC; } @@ -1023,7 +1014,7 @@ static int cmd_bap_broadcast_assistant_add_pa_sync(const struct shell *sh, if ((subgroups_bis_sync & bis_bitfield_req) != bis_bitfield_req) { /* bis_sync of all subgroups should contain at least all the bits in request */ /* Otherwise Command will be rejected */ - shell_error(ctx_shell, "Cannot set BIS index 0x%06X when BASE subgroups only " + shell_error(sh, "Cannot set BIS index 0x%06X when BASE subgroups only " "supports %d", bis_bitfield_req, subgroups_bis_sync); return -ENOEXEC; } diff --git a/subsys/bluetooth/audio/shell/bap_scan_delegator.c b/subsys/bluetooth/audio/shell/bap_scan_delegator.c index a4a515a0db508..e88b153c332fb 100644 --- a/subsys/bluetooth/audio/shell/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/shell/bap_scan_delegator.c @@ -33,6 +33,7 @@ #include